From e271c974adf19adc50bc88d6f5d67c55f5f63a6a Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Thu, 7 Oct 2021 22:14:53 +0200 Subject: [PATCH 001/629] init --- .gitignore | 249 + build.gradle.kts | 137 + ...ompilerOptions.module_typescript-to-lua.kt | 74 + externals/LuaAST.module_typescript-to-lua.kt | 485 + externals/LuaLib.module_typescript-to-lua.kt | 111 + .../LuaPrinter.module_typescript-to-lua.kt | 101 + externals/context.module_typescript-to-lua.kt | 79 + externals/index.module_typescript-to-lua.kt | 38 + externals/lib.es2015.collection.kt | 49 + externals/lib.es2015.iterable.kt | 54 + externals/lib.es5.Intl.module_dukat.kt | 220 + externals/lib.es5.kt | 69 + externals/lib.scripthost.kt | 20 + externals/nonDeclarations.ts.kt | 114 + ...tput-collector.module_typescript-to-lua.kt | 33 + externals/parse.module_typescript-to-lua.kt | 25 + externals/plugins.module_typescript-to-lua.kt | 24 + externals/report.module_typescript-to-lua.kt | 48 + externals/source-map.module_source-map.kt | 192 + .../transpile.module_typescript-to-lua.kt | 40 + .../transpiler.module_typescript-to-lua.kt | 55 + .../tsconfig.module_typescript-to-lua.kt | 18 + externals/typescript.module_typescript.kt | 19 + ...ipt.ts.ScriptSnapshot.module_typescript.kt | 20 + externals/typescript.ts.module_typescript.kt | 8236 +++++++++++++++++ .../typescript.ts.server.module_typescript.kt | 101 + externals/utils.module_typescript-to-lua.kt | 46 + .../visitors.module_typescript-to-lua.kt | 38 + ...ompilerOptions.module_typescript-to-lua.kt | 74 + .../LuaAST.module_typescript-to-lua.kt | 473 + .../LuaLib.module_typescript-to-lua.kt | 111 + .../LuaPrinter.module_typescript-to-lua.kt | 101 + .../context.module_typescript-to-lua.kt | 79 + externals02/index.module_typescript-to-lua.kt | 38 + externals02/lib.es2015.collection.kt | 49 + externals02/lib.es2015.iterable.kt | 54 + externals02/lib.es5.Intl.module_dukat.kt | 220 + externals02/lib.es5.kt | 69 + externals02/lib.scripthost.kt | 20 + externals02/nonDeclarations.ts.kt | 122 + ...tput-collector.module_typescript-to-lua.kt | 33 + externals02/parse.module_typescript-to-lua.kt | 25 + .../plugins.module_typescript-to-lua.kt | 24 + .../report.module_typescript-to-lua.kt | 48 + externals02/source-map.module_source-map.kt | 192 + .../transpile.module_typescript-to-lua.kt | 40 + .../transpiler.module_typescript-to-lua.kt | 55 + .../tsconfig.module_typescript-to-lua.kt | 18 + externals02/typescript.module_typescript.kt | 19 + ...ipt.ts.ScriptSnapshot.module_typescript.kt | 20 + .../typescript.ts.module_typescript.kt | 8129 ++++++++++++++++ .../typescript.ts.server.module_typescript.kt | 101 + externals02/utils.module_typescript-to-lua.kt | 46 + .../visitors.module_typescript-to-lua.kt | 38 + ...ompilerOptions.module_typescript-to-lua.kt | 74 + .../LuaAST.module_typescript-to-lua.kt | 485 + .../LuaLib.module_typescript-to-lua.kt | 111 + .../LuaPrinter.module_typescript-to-lua.kt | 101 + .../context.module_typescript-to-lua.kt | 79 + externals03/index.module_typescript-to-lua.kt | 38 + externals03/lib.es2015.collection.kt | 49 + externals03/lib.es2015.iterable.kt | 54 + externals03/lib.es5.Intl.module_dukat.kt | 220 + externals03/lib.es5.kt | 69 + externals03/lib.scripthost.kt | 20 + externals03/nonDeclarations.ts.kt | 114 + ...tput-collector.module_typescript-to-lua.kt | 33 + externals03/parse.module_typescript-to-lua.kt | 25 + .../plugins.module_typescript-to-lua.kt | 24 + .../report.module_typescript-to-lua.kt | 48 + externals03/source-map.module_source-map.kt | 192 + .../transpile.module_typescript-to-lua.kt | 40 + .../transpiler.module_typescript-to-lua.kt | 55 + .../tsconfig.module_typescript-to-lua.kt | 18 + ...ipt.ts.ScriptSnapshot.module_typescript.kt | 20 + .../typescript.ts.module_typescript.kt | 5914 ++++++++++++ externals03/utils.module_typescript-to-lua.kt | 46 + .../visitors.module_typescript-to-lua.kt | 38 + gradle.properties | 4 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59536 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 234 + gradlew.bat | 89 + settings.gradle.kts | 31 + src/jsMain/kotlin/main.kt | 8 + src/nativeMain/kotlin/Main.kt | 3 + src/nativeMain/kotlin/example/hello.kt | 27 + 87 files changed, 29161 insertions(+) create mode 100644 .gitignore create mode 100644 build.gradle.kts create mode 100644 externals/CompilerOptions.module_typescript-to-lua.kt create mode 100644 externals/LuaAST.module_typescript-to-lua.kt create mode 100644 externals/LuaLib.module_typescript-to-lua.kt create mode 100644 externals/LuaPrinter.module_typescript-to-lua.kt create mode 100644 externals/context.module_typescript-to-lua.kt create mode 100644 externals/index.module_typescript-to-lua.kt create mode 100644 externals/lib.es2015.collection.kt create mode 100644 externals/lib.es2015.iterable.kt create mode 100644 externals/lib.es5.Intl.module_dukat.kt create mode 100644 externals/lib.es5.kt create mode 100644 externals/lib.scripthost.kt create mode 100644 externals/nonDeclarations.ts.kt create mode 100644 externals/output-collector.module_typescript-to-lua.kt create mode 100644 externals/parse.module_typescript-to-lua.kt create mode 100644 externals/plugins.module_typescript-to-lua.kt create mode 100644 externals/report.module_typescript-to-lua.kt create mode 100644 externals/source-map.module_source-map.kt create mode 100644 externals/transpile.module_typescript-to-lua.kt create mode 100644 externals/transpiler.module_typescript-to-lua.kt create mode 100644 externals/tsconfig.module_typescript-to-lua.kt create mode 100644 externals/typescript.module_typescript.kt create mode 100644 externals/typescript.ts.ScriptSnapshot.module_typescript.kt create mode 100644 externals/typescript.ts.module_typescript.kt create mode 100644 externals/typescript.ts.server.module_typescript.kt create mode 100644 externals/utils.module_typescript-to-lua.kt create mode 100644 externals/visitors.module_typescript-to-lua.kt create mode 100644 externals02/CompilerOptions.module_typescript-to-lua.kt create mode 100644 externals02/LuaAST.module_typescript-to-lua.kt create mode 100644 externals02/LuaLib.module_typescript-to-lua.kt create mode 100644 externals02/LuaPrinter.module_typescript-to-lua.kt create mode 100644 externals02/context.module_typescript-to-lua.kt create mode 100644 externals02/index.module_typescript-to-lua.kt create mode 100644 externals02/lib.es2015.collection.kt create mode 100644 externals02/lib.es2015.iterable.kt create mode 100644 externals02/lib.es5.Intl.module_dukat.kt create mode 100644 externals02/lib.es5.kt create mode 100644 externals02/lib.scripthost.kt create mode 100644 externals02/nonDeclarations.ts.kt create mode 100644 externals02/output-collector.module_typescript-to-lua.kt create mode 100644 externals02/parse.module_typescript-to-lua.kt create mode 100644 externals02/plugins.module_typescript-to-lua.kt create mode 100644 externals02/report.module_typescript-to-lua.kt create mode 100644 externals02/source-map.module_source-map.kt create mode 100644 externals02/transpile.module_typescript-to-lua.kt create mode 100644 externals02/transpiler.module_typescript-to-lua.kt create mode 100644 externals02/tsconfig.module_typescript-to-lua.kt create mode 100644 externals02/typescript.module_typescript.kt create mode 100644 externals02/typescript.ts.ScriptSnapshot.module_typescript.kt create mode 100644 externals02/typescript.ts.module_typescript.kt create mode 100644 externals02/typescript.ts.server.module_typescript.kt create mode 100644 externals02/utils.module_typescript-to-lua.kt create mode 100644 externals02/visitors.module_typescript-to-lua.kt create mode 100644 externals03/CompilerOptions.module_typescript-to-lua.kt create mode 100644 externals03/LuaAST.module_typescript-to-lua.kt create mode 100644 externals03/LuaLib.module_typescript-to-lua.kt create mode 100644 externals03/LuaPrinter.module_typescript-to-lua.kt create mode 100644 externals03/context.module_typescript-to-lua.kt create mode 100644 externals03/index.module_typescript-to-lua.kt create mode 100644 externals03/lib.es2015.collection.kt create mode 100644 externals03/lib.es2015.iterable.kt create mode 100644 externals03/lib.es5.Intl.module_dukat.kt create mode 100644 externals03/lib.es5.kt create mode 100644 externals03/lib.scripthost.kt create mode 100644 externals03/nonDeclarations.ts.kt create mode 100644 externals03/output-collector.module_typescript-to-lua.kt create mode 100644 externals03/parse.module_typescript-to-lua.kt create mode 100644 externals03/plugins.module_typescript-to-lua.kt create mode 100644 externals03/report.module_typescript-to-lua.kt create mode 100644 externals03/source-map.module_source-map.kt create mode 100644 externals03/transpile.module_typescript-to-lua.kt create mode 100644 externals03/transpiler.module_typescript-to-lua.kt create mode 100644 externals03/tsconfig.module_typescript-to-lua.kt create mode 100644 externals03/typescript.ts.ScriptSnapshot.module_typescript.kt create mode 100644 externals03/typescript.ts.module_typescript.kt create mode 100644 externals03/utils.module_typescript-to-lua.kt create mode 100644 externals03/visitors.module_typescript-to-lua.kt create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle.kts create mode 100644 src/jsMain/kotlin/main.kt create mode 100644 src/nativeMain/kotlin/Main.kt create mode 100644 src/nativeMain/kotlin/example/hello.kt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ff3921f --- /dev/null +++ b/.gitignore @@ -0,0 +1,249 @@ + +.idea + +# Created by https://www.toptal.com/developers/gitignore/api/windows,macos,linux,gradle,intellij,visualstudiocode,kotlin +# Edit at https://www.toptal.com/developers/gitignore?templates=windows,macos,linux,gradle,intellij,visualstudiocode,kotlin + +### Intellij ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +.idea/artifacts +.idea/compiler.xml +.idea/jarRepositories.xml +.idea/modules.xml +.idea/*.iml +.idea/modules +*.iml +*.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Intellij Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +# https://plugins.jetbrains.com/plugin/7973-sonarlint +.idea/**/sonarlint/ + +# SonarQube Plugin +# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin +.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator-enh.xml +.idea/**/markdown-navigator/ + +# Cache file creation bug +# See https://youtrack.jetbrains.com/issue/JBR-2257 +.idea/$CACHE_FILE$ + +# CodeStream plugin +# https://plugins.jetbrains.com/plugin/12206-codestream +.idea/codestream.xml + +### Kotlin ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### Gradle ### +.gradle +build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +### Gradle Patch ### +**/build/ + +# Eclipse Gradle plugin generated files +# Eclipse Core +.project +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# End of https://www.toptal.com/developers/gitignore/api/windows,macos,linux,gradle,intellij,visualstudiocode,kotlin diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..90efe8e --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,137 @@ +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension + +plugins { + kotlin("multiplatform") version "1.5.31" +} + +group = "dev.adamko.factoriowebmap" +version = "1.0-SNAPSHOT" + +//repositories { +// mavenCentral() +// maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") +//} + + +kotlin { + + // + val hostOs = System.getProperty("os.name") + val isMingwX64 = hostOs.startsWith("Windows") + val nativeTarget = when { + hostOs == "Mac OS X" -> macosX64("native") + hostOs == "Linux" -> linuxX64("native") + isMingwX64 -> mingwX64("native") + else -> throw GradleException( + "Host OS '$hostOs' is not supported in Kotlin/Native.") + } + + nativeTarget.apply { + binaries { + executable { + entryPoint = "main" + } + sharedLib { + baseName = if (isMingwX64) "libnative" else "native" + } + } + } + sourceSets { + val nativeMain by getting { + dependencies { + implementation("com.soywiz.korlibs.luak:luak:2.4.3") + } + } + val nativeTest by getting { + dependencies { + implementation(kotlin("test")) + + } + } + } + // + + // + js(IR) { + binaries.executable() + browser { + commonWebpackConfig { + cssSupport.enabled = true + } + } + + useCommonJs() + nodejs() + + compilations.all { + packageJson { + customField( + "scripts", mapOf( + "build" to "tstl", + "dev" to "tstl --watch", + ) + ) + } + } +// compilations["main"] +// .packageJson { +// customField( +// "scripts", mapOf( +// "build" to "tstl", +// "dev" to "tstl --watch", +// ) +// ) +// } + } + + sourceSets { + + val jsMain by getting { + kotlin.srcDir("externals02") +// kotlin.srcDir("externals") + + dependencies { + + val kotlinWrappersVersion = "0.0.1-pre.254-kotlin-1.5.31" + implementation( + project.dependencies.enforcedPlatform( + "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" + ) + ) + + implementation("org.jetbrains.kotlin-wrappers:kotlin-react") + implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom") + implementation(npm("react", "17.0.2")) + implementation(npm("react-dom", "17.0.2")) + +// implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7") { +// because("https://github.com/Kotlin/kotlinx-nodejs") +// } + + val generateExternals = false + implementation(npm("typescript-to-lua", "1.0.1", generateExternals = generateExternals)) + implementation(npm("typed-factorio", "0.7.1", generateExternals = generateExternals)) + implementation(npm("lua-types", "2.11.0", generateExternals = generateExternals)) + implementation(npm("typescript", "4.4.3", generateExternals = generateExternals)) + } + } + + val jsTest by getting { + dependencies { + implementation(kotlin("test-js")) + } + } + } + // + +} + +configure { + versions.dukat.version = "0.5.8-rc.4-dev.20211001" +// versions.dukat.version = "0.5.8-rc.4" +} + +tasks.wrapper { + gradleVersion = "7.2" + distributionType = Wrapper.DistributionType.ALL +} diff --git a/externals/CompilerOptions.module_typescript-to-lua.kt b/externals/CompilerOptions.module_typescript-to-lua.kt new file mode 100644 index 0000000..aa83510 --- /dev/null +++ b/externals/CompilerOptions.module_typescript-to-lua.kt @@ -0,0 +1,74 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.Diagnostic + +typealias OmitIndexSignature = Any + +external interface TransformerImport { + var transform: String + var import: String? + get() = definedExternally + set(value) = definedExternally + var after: Boolean? + get() = definedExternally + set(value) = definedExternally + var afterDeclarations: Boolean? + get() = definedExternally + set(value) = definedExternally + var type: String? /* "program" | "config" | "checker" | "raw" | "compilerOptions" */ + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): Any? + @nativeSetter + operator fun set(option: String, value: Any) +} + +external interface LuaPluginImport { + var name: String + var import: String? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): Any? + @nativeSetter + operator fun set(option: String, value: Any) +} + +external enum class LuaLibImportKind { + None /* = "none" */, + Always /* = "always" */, + Inline /* = "inline" */, + Require /* = "require" */ +} + +external enum class LuaTarget { + Universal /* = "universal" */, + Lua51 /* = "5.1" */, + Lua52 /* = "5.2" */, + Lua53 /* = "5.3" */, + Lua54 /* = "5.4" */, + LuaJIT /* = "JIT" */ +} + +external enum class BuildMode { + Default /* = "default" */, + Library /* = "library" */ +} + +external var isBundleEnabled: (options: dynamic /* typealias OmitIndexSignature = dynamic */) -> Boolean + +external fun validateOptions(options: dynamic /* typealias OmitIndexSignature = dynamic */): Array \ No newline at end of file diff --git a/externals/LuaAST.module_typescript-to-lua.kt b/externals/LuaAST.module_typescript-to-lua.kt new file mode 100644 index 0000000..079e37f --- /dev/null +++ b/externals/LuaAST.module_typescript-to-lua.kt @@ -0,0 +1,485 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import tsstdlib.Set + +external enum class SyntaxKind { + File /* = 0 */, + Block /* = 1 */, + DoStatement /* = 2 */, + VariableDeclarationStatement /* = 3 */, + AssignmentStatement /* = 4 */, + IfStatement /* = 5 */, + WhileStatement /* = 6 */, + RepeatStatement /* = 7 */, + ForStatement /* = 8 */, + ForInStatement /* = 9 */, + GotoStatement /* = 10 */, + LabelStatement /* = 11 */, + ReturnStatement /* = 12 */, + BreakStatement /* = 13 */, + ExpressionStatement /* = 14 */, + StringLiteral /* = 15 */, + NumericLiteral /* = 16 */, + NilKeyword /* = 17 */, + DotsKeyword /* = 18 */, + TrueKeyword /* = 19 */, + FalseKeyword /* = 20 */, + FunctionExpression /* = 21 */, + TableFieldExpression /* = 22 */, + TableExpression /* = 23 */, + UnaryExpression /* = 24 */, + BinaryExpression /* = 25 */, + CallExpression /* = 26 */, + MethodCallExpression /* = 27 */, + Identifier /* = 28 */, + TableIndexExpression /* = 29 */, + AdditionOperator /* = 30 */, + SubtractionOperator /* = 31 */, + MultiplicationOperator /* = 32 */, + DivisionOperator /* = 33 */, + FloorDivisionOperator /* = 34 */, + ModuloOperator /* = 35 */, + PowerOperator /* = 36 */, + NegationOperator /* = 37 */, + ConcatOperator /* = 38 */, + LengthOperator /* = 39 */, + EqualityOperator /* = 40 */, + InequalityOperator /* = 41 */, + LessThanOperator /* = 42 */, + LessEqualOperator /* = 43 */, + GreaterThanOperator /* = 44 */, + GreaterEqualOperator /* = 45 */, + AndOperator /* = 46 */, + OrOperator /* = 47 */, + NotOperator /* = 48 */, + BitwiseAndOperator /* = 49 */, + BitwiseOrOperator /* = 50 */, + BitwiseExclusiveOrOperator /* = 51 */, + BitwiseRightShiftOperator /* = 52 */, + BitwiseLeftShiftOperator /* = 53 */, + BitwiseNotOperator /* = 54 */ +} + +typealias UnaryBitwiseOperator = SyntaxKind.BitwiseNotOperator + +external interface TextRange { + var line: Number? + get() = definedExternally + set(value) = definedExternally + var column: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface Node : TextRange { + var kind: SyntaxKind +} + +external fun createNode(kind: SyntaxKind, tsOriginal: ts.Node = definedExternally): Node + +external fun cloneNode(node: T): T + +external fun setNodePosition(node: T, position: TextRange): T + +external fun setNodeOriginal(node: T, tsOriginal: ts.Node): T + +external fun setNodeOriginal(node: T?, tsOriginal: ts.Node): T? + +external fun getOriginalPos(node: Node): TextRange + +external interface File : Node { + var statements: Array + var luaLibFeatures: Set + var trivia: String +} + +external fun isFile(node: Node): Boolean + +external fun createFile(statements: Array, luaLibFeatures: Set, trivia: String, tsOriginal: ts.Node = definedExternally): File + +external interface Block : Node { + var statements: Array +} + +external fun isBlock(node: Node): Boolean + +external fun createBlock(statements: Array, tsOriginal: ts.Node = definedExternally): Block + +external interface Statement : Node { + var _statementBrand: Any + var leadingComments: Array */>? + get() = definedExternally + set(value) = definedExternally + var trailingComments: Array */>? + get() = definedExternally + set(value) = definedExternally +} + +external interface DoStatement : Statement { + var statements: Array +} + +external fun isDoStatement(node: Node): Boolean + +external fun createDoStatement(statements: Array, tsOriginal: ts.Node = definedExternally): DoStatement + +external interface VariableDeclarationStatement : Statement { + var left: Array + var right: Array? + get() = definedExternally + set(value) = definedExternally +} + +external fun isVariableDeclarationStatement(node: Node): Boolean + +external fun createVariableDeclarationStatement(left: Identifier, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Identifier): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Identifier, right: Expression = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Identifier, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Identifier, right: Array = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array, right: Expression = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array, right: Array = definedExternally): VariableDeclarationStatement + +external interface AssignmentStatement : Statement { + var left: Array + var right: Array +} + +external fun isAssignmentStatement(node: Node): Boolean + +external fun createAssignmentStatement(left: Identifier, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Identifier): AssignmentStatement + +external fun createAssignmentStatement(left: Identifier, right: Expression = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Identifier, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Identifier, right: Array = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression, right: Expression = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression, right: Array = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Array, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Array): AssignmentStatement + +external fun createAssignmentStatement(left: Array, right: Expression = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Array, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Array, right: Array = definedExternally): AssignmentStatement + +external interface IfStatement : Statement { + var condition: Expression + var ifBlock: Block + var elseBlock: dynamic /* Block? | IfStatement? */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isIfStatement(node: Node): Boolean + +external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: Block = definedExternally, tsOriginal: ts.Node = definedExternally): IfStatement + +external fun createIfStatement(condition: Expression, ifBlock: Block): IfStatement + +external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: Block = definedExternally): IfStatement + +external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: IfStatement = definedExternally, tsOriginal: ts.Node = definedExternally): IfStatement + +external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: IfStatement = definedExternally): IfStatement + +external interface IterationStatement : Statement { + var body: Block +} + +external fun isIterationStatement(node: Node): Boolean + +external interface WhileStatement : IterationStatement { + var condition: Expression +} + +external fun isWhileStatement(node: Node): Boolean + +external fun createWhileStatement(body: Block, condition: Expression, tsOriginal: ts.Node = definedExternally): WhileStatement + +external interface RepeatStatement : IterationStatement { + var condition: Expression +} + +external fun isRepeatStatement(node: Node): Boolean + +external fun createRepeatStatement(body: Block, condition: Expression, tsOriginal: ts.Node = definedExternally): RepeatStatement + +external interface ForStatement : IterationStatement { + var controlVariable: Identifier + var controlVariableInitializer: Expression + var limitExpression: Expression + var stepExpression: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external fun isForStatement(node: Node): Boolean + +external fun createForStatement(body: Block, controlVariable: Identifier, controlVariableInitializer: Expression, limitExpression: Expression, stepExpression: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): ForStatement + +external interface ForInStatement : IterationStatement { + var names: Array + var expressions: Array +} + +external fun isForInStatement(node: Node): Boolean + +external fun createForInStatement(body: Block, names: Array, expressions: Array, tsOriginal: ts.Node = definedExternally): ForInStatement + +external interface GotoStatement : Statement { + var label: String +} + +external fun isGotoStatement(node: Node): Boolean + +external fun createGotoStatement(label: String, tsOriginal: ts.Node = definedExternally): GotoStatement + +external interface LabelStatement : Statement { + var name: String +} + +external fun isLabelStatement(node: Node): Boolean + +external fun createLabelStatement(name: String, tsOriginal: ts.Node = definedExternally): LabelStatement + +external interface ReturnStatement : Statement { + var expressions: Array +} + +external fun isReturnStatement(node: Node): Boolean + +external fun createReturnStatement(expressions: Array, tsOriginal: ts.Node = definedExternally): ReturnStatement + +external interface BreakStatement : Statement + +external fun isBreakStatement(node: Node): Boolean + +external fun createBreakStatement(tsOriginal: ts.Node = definedExternally): BreakStatement + +external interface ExpressionStatement : Statement { + var expression: Expression +} + +external fun isExpressionStatement(node: Node): Boolean + +external fun createExpressionStatement(expressions: Expression, tsOriginal: ts.Node = definedExternally): ExpressionStatement + +external interface Expression : Node { + var _expressionBrand: Any +} + +external interface NilLiteral : Expression + +external fun isNilLiteral(node: Node): Boolean + +external fun createNilLiteral(tsOriginal: ts.Node = definedExternally): NilLiteral + +external interface BooleanLiteral : Expression { + override var kind: dynamic /* SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isBooleanLiteral(node: Node): Boolean + +external fun createBooleanLiteral(value: Boolean, tsOriginal: ts.Node = definedExternally): BooleanLiteral + +external interface DotsLiteral : Expression + +external fun isDotsLiteral(node: Node): Boolean + +external fun createDotsLiteral(tsOriginal: ts.Node = definedExternally): DotsLiteral + +external interface NumericLiteral : Expression { + var value: Number +} + +external fun isNumericLiteral(node: Node): Boolean + +external fun createNumericLiteral(value: Number, tsOriginal: ts.Node = definedExternally): NumericLiteral + +external interface StringLiteral : Expression { + var value: String +} + +external fun isStringLiteral(node: Node): Boolean + +external fun createStringLiteral(value: String, tsOriginal: ts.Node = definedExternally): StringLiteral + +external enum class FunctionExpressionFlags { + None /* = 1 */, + Inline /* = 2 */, + Declaration /* = 4 */ +} + +external interface FunctionExpression : Expression { + var params: Array? + get() = definedExternally + set(value) = definedExternally + var dots: DotsLiteral? + get() = definedExternally + set(value) = definedExternally + var body: Block + var flags: FunctionExpressionFlags +} + +external fun isFunctionExpression(node: Node): Boolean + +external fun createFunctionExpression(body: Block, params: Array = definedExternally, dots: DotsLiteral = definedExternally, flags: FunctionExpressionFlags = definedExternally, tsOriginal: ts.Node = definedExternally): FunctionExpression + +external interface TableFieldExpression : Expression { + var value: Expression + var key: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external fun isTableFieldExpression(node: Node): Boolean + +external fun createTableFieldExpression(value: Expression, key: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): TableFieldExpression + +external interface TableExpression : Expression { + var fields: Array +} + +external fun isTableExpression(node: Node): Boolean + +external fun createTableExpression(fields: Array = definedExternally, tsOriginal: ts.Node = definedExternally): TableExpression + +external interface UnaryExpression : Expression { + var operand: Expression + var operator: dynamic /* SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isUnaryExpression(node: Node): Boolean + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NegationOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NegationOperator): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.LengthOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.LengthOperator): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NotOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NotOperator): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: UnaryBitwiseOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: UnaryBitwiseOperator): UnaryExpression + +external interface BinaryExpression : Expression { + var operator: dynamic /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */ + get() = definedExternally + set(value) = definedExternally + var left: Expression + var right: Expression +} + +external fun isBinaryExpression(node: Node): Boolean + +external fun createBinaryExpression(left: Expression, right: Expression, operator: Any /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */, tsOriginal: ts.Node = definedExternally): BinaryExpression + +external interface CallExpression : Expression { + var expression: Expression + var params: Array +} + +external fun isCallExpression(node: Node): Boolean + +external fun createCallExpression(expression: Expression, params: Array, tsOriginal: ts.Node = definedExternally): CallExpression + +external interface MethodCallExpression : Expression { + var prefixExpression: Expression + var name: Identifier + var params: Array +} + +external fun isMethodCallExpression(node: Node): Boolean + +external fun createMethodCallExpression(prefixExpression: Expression, name: Identifier, params: Array, tsOriginal: ts.Node = definedExternally): MethodCallExpression + +external interface Identifier : Expression { + var exportable: Boolean + var text: String + var originalName: String? + get() = definedExternally + set(value) = definedExternally + var symbolId: Number? /* Number? & `T$14`? */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isIdentifier(node: Node): Boolean + +external fun createIdentifier(text: String, tsOriginal: ts.Node = definedExternally, symbolId: Number /* Number & `T$14` */ = definedExternally, originalName: String = definedExternally): Identifier + +external fun cloneIdentifier(identifier: Identifier, tsOriginal: ts.Node = definedExternally): Identifier + +external fun createAnonymousIdentifier(tsOriginal: ts.Node = definedExternally): Identifier + +external interface TableIndexExpression : Expression { + var table: Expression + var index: Expression +} + +external fun isTableIndexExpression(node: Node): Boolean + +external fun createTableIndexExpression(table: Expression, index: Expression, tsOriginal: ts.Node = definedExternally): TableIndexExpression + +external fun isAssignmentLeftHandSideExpression(node: Node): Boolean + +external fun isFunctionDefinition(statement: VariableDeclarationStatement): Boolean + +external fun isFunctionDefinition(statement: AssignmentStatement): Boolean + +external interface `T$17` { + var statements: dynamic /* JsTuple */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isInlineFunctionExpression(expression: FunctionExpression): Boolean \ No newline at end of file diff --git a/externals/LuaLib.module_typescript-to-lua.kt b/externals/LuaLib.module_typescript-to-lua.kt new file mode 100644 index 0000000..f00c242 --- /dev/null +++ b/externals/LuaLib.module_typescript-to-lua.kt @@ -0,0 +1,111 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external enum class LuaLibFeature { + ArrayConcat /* = "ArrayConcat" */, + ArrayEntries /* = "ArrayEntries" */, + ArrayEvery /* = "ArrayEvery" */, + ArrayFilter /* = "ArrayFilter" */, + ArrayForEach /* = "ArrayForEach" */, + ArrayFind /* = "ArrayFind" */, + ArrayFindIndex /* = "ArrayFindIndex" */, + ArrayIncludes /* = "ArrayIncludes" */, + ArrayIndexOf /* = "ArrayIndexOf" */, + ArrayIsArray /* = "ArrayIsArray" */, + ArrayJoin /* = "ArrayJoin" */, + ArrayMap /* = "ArrayMap" */, + ArrayPush /* = "ArrayPush" */, + ArrayReduce /* = "ArrayReduce" */, + ArrayReduceRight /* = "ArrayReduceRight" */, + ArrayReverse /* = "ArrayReverse" */, + ArrayShift /* = "ArrayShift" */, + ArrayUnshift /* = "ArrayUnshift" */, + ArraySort /* = "ArraySort" */, + ArraySlice /* = "ArraySlice" */, + ArraySome /* = "ArraySome" */, + ArraySplice /* = "ArraySplice" */, + ArrayToObject /* = "ArrayToObject" */, + ArrayFlat /* = "ArrayFlat" */, + ArrayFlatMap /* = "ArrayFlatMap" */, + ArraySetLength /* = "ArraySetLength" */, + Await /* = "Await" */, + Class /* = "Class" */, + ClassExtends /* = "ClassExtends" */, + CloneDescriptor /* = "CloneDescriptor" */, + Decorate /* = "Decorate" */, + DecorateParam /* = "DecorateParam" */, + Delete /* = "Delete" */, + DelegatedYield /* = "DelegatedYield" */, + Error /* = "Error" */, + FunctionBind /* = "FunctionBind" */, + Generator /* = "Generator" */, + InstanceOf /* = "InstanceOf" */, + InstanceOfObject /* = "InstanceOfObject" */, + Iterator /* = "Iterator" */, + Map /* = "Map" */, + MathAtan2 /* = "MathAtan2" */, + New /* = "New" */, + Number /* = "Number" */, + NumberIsFinite /* = "NumberIsFinite" */, + NumberIsNaN /* = "NumberIsNaN" */, + NumberToString /* = "NumberToString" */, + ObjectAssign /* = "ObjectAssign" */, + ObjectDefineProperty /* = "ObjectDefineProperty" */, + ObjectEntries /* = "ObjectEntries" */, + ObjectFromEntries /* = "ObjectFromEntries" */, + ObjectGetOwnPropertyDescriptor /* = "ObjectGetOwnPropertyDescriptor" */, + ObjectGetOwnPropertyDescriptors /* = "ObjectGetOwnPropertyDescriptors" */, + ObjectKeys /* = "ObjectKeys" */, + ObjectRest /* = "ObjectRest" */, + ObjectValues /* = "ObjectValues" */, + OptionalChainAccess /* = "OptionalChainAccess" */, + OptionalFunctionCall /* = "OptionalFunctionCall" */, + OptionalMethodCall /* = "OptionalMethodCall" */, + ParseFloat /* = "ParseFloat" */, + ParseInt /* = "ParseInt" */, + Promise /* = "Promise" */, + PromiseAll /* = "PromiseAll" */, + PromiseAllSettled /* = "PromiseAllSettled" */, + PromiseAny /* = "PromiseAny" */, + PromiseRace /* = "PromiseRace" */, + Set /* = "Set" */, + SetDescriptor /* = "SetDescriptor" */, + WeakMap /* = "WeakMap" */, + WeakSet /* = "WeakSet" */, + SourceMapTraceBack /* = "SourceMapTraceBack" */, + Spread /* = "Spread" */, + StringAccess /* = "StringAccess" */, + StringCharAt /* = "StringCharAt" */, + StringCharCodeAt /* = "StringCharCodeAt" */, + StringConcat /* = "StringConcat" */, + StringEndsWith /* = "StringEndsWith" */, + StringIncludes /* = "StringIncludes" */, + StringPadEnd /* = "StringPadEnd" */, + StringPadStart /* = "StringPadStart" */, + StringReplace /* = "StringReplace" */, + StringSlice /* = "StringSlice" */, + StringSplit /* = "StringSplit" */, + StringStartsWith /* = "StringStartsWith" */, + StringSubstr /* = "StringSubstr" */, + StringSubstring /* = "StringSubstring" */, + StringTrim /* = "StringTrim" */, + StringTrimEnd /* = "StringTrimEnd" */, + StringTrimStart /* = "StringTrimStart" */, + Symbol /* = "Symbol" */, + SymbolRegistry /* = "SymbolRegistry" */, + TypeOf /* = "TypeOf" */, + Unpack /* = "Unpack" */ +} \ No newline at end of file diff --git a/externals/LuaPrinter.module_typescript-to-lua.kt b/externals/LuaPrinter.module_typescript-to-lua.kt new file mode 100644 index 0000000..6428653 --- /dev/null +++ b/externals/LuaPrinter.module_typescript-to-lua.kt @@ -0,0 +1,101 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.Program + +external var escapeString: (value: String) -> String + +external var tstlHeader: Any + +typealias Printer = (program: Program, emitHost: EmitHost, fileName: String, file: File) -> PrintResult + +external interface PrintResult { + var code: String + var sourceMap: String + var sourceMapNode: SourceNode +} + +external fun createPrinter(printers: Array): Printer + +external open class LuaPrinter(emitHost: EmitHost, program: Program, fileName: String) { + open var emitHost: Any + open var currentIndent: Any + open var sourceFile: Any + open var options: Any + open fun print(file: File): PrintResult + open var printInlineSourceMap: Any + open var printStackTraceOverride: Any + open var printFile: Any + open fun pushIndent() + open fun popIndent() + open fun indent(input: String = definedExternally): dynamic /* String | SourceNode */ + open fun indent(): dynamic /* String | SourceNode */ + open fun indent(input: SourceNode = definedExternally): dynamic /* String | SourceNode */ + open fun createSourceNode(node: Node, chunks: String, name: String = definedExternally): SourceNode + open fun createSourceNode(node: Node, chunks: String): SourceNode + open fun createSourceNode(node: Node, chunks: SourceNode, name: String = definedExternally): SourceNode + open fun createSourceNode(node: Node, chunks: SourceNode): SourceNode + open fun createSourceNode(node: Node, chunks: Array, name: String = definedExternally): SourceNode + open fun createSourceNode(node: Node, chunks: Array): SourceNode + open fun concatNodes(vararg chunks: Any /* String | SourceNode */): SourceNode + open fun printBlock(block: Block): SourceNode + open var statementMayRequireSemiColon: Any + open var nodeStartsWithParenthesis: Any + open fun printStatementArray(statements: Array): Array + open fun printStatement(statement: Statement): SourceNode + open fun printComment(comment: String): dynamic /* String | SourceNode */ + open fun printComment(comment: Array): dynamic /* String | SourceNode */ + open fun printStatementExcludingComments(statement: Statement): SourceNode + open fun printDoStatement(statement: DoStatement): SourceNode + open fun printVariableDeclarationStatement(statement: VariableDeclarationStatement): SourceNode + open fun printVariableAssignmentStatement(statement: AssignmentStatement): SourceNode + open fun printIfStatement(statement: IfStatement, isElseIf: Boolean = definedExternally): SourceNode + open fun printWhileStatement(statement: WhileStatement): SourceNode + open fun printRepeatStatement(statement: RepeatStatement): SourceNode + open fun printForStatement(statement: ForStatement): SourceNode + open fun printForInStatement(statement: ForInStatement): SourceNode + open fun printGotoStatement(statement: GotoStatement): SourceNode + open fun printLabelStatement(statement: LabelStatement): SourceNode + open fun printReturnStatement(statement: ReturnStatement): SourceNode + open fun printBreakStatement(statement: BreakStatement): SourceNode + open fun printExpressionStatement(statement: ExpressionStatement): SourceNode + open fun printExpression(expression: Expression): SourceNode + open fun printStringLiteral(expression: StringLiteral): SourceNode + open fun printNumericLiteral(expression: NumericLiteral): SourceNode + open fun printNilLiteral(expression: NilLiteral): SourceNode + open fun printDotsLiteral(expression: DotsLiteral): SourceNode + open fun printBooleanLiteral(expression: BooleanLiteral): SourceNode + open var printFunctionParameters: Any + open fun printFunctionExpression(expression: FunctionExpression): SourceNode + open fun printFunctionDefinition(statement: Any /* VariableDeclarationStatement | AssignmentStatement */): SourceNode + open fun printTableFieldExpression(expression: TableFieldExpression): SourceNode + open fun printTableExpression(expression: TableExpression): SourceNode + open fun printUnaryExpression(expression: UnaryExpression): SourceNode + open fun printBinaryExpression(expression: BinaryExpression): SourceNode + open var printExpressionInParenthesesIfNeeded: Any + open var needsParenthesis: Any + open fun printCallExpression(expression: CallExpression): SourceNode + open fun printMethodCallExpression(expression: MethodCallExpression): SourceNode + open fun printIdentifier(expression: Identifier): SourceNode + open fun printTableIndexExpression(expression: TableIndexExpression): SourceNode + open fun printOperator(kind: Any /* SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator | SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */): SourceNode + open fun joinChunksWithComma(chunks: Array): Array + open fun printExpressionList(expressions: Array): Array + open var buildSourceMap: Any + + companion object { + var operatorMap: Any + } +} \ No newline at end of file diff --git a/externals/context.module_typescript-to-lua.kt b/externals/context.module_typescript-to-lua.kt new file mode 100644 index 0000000..696e339 --- /dev/null +++ b/externals/context.module_typescript-to-lua.kt @@ -0,0 +1,79 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.GetAccessorDeclaration +import ts.SetAccessorDeclaration +import ts.Node +import ts.ImportEqualsDeclaration +import ts.Expression +import ts.SourceFile +import ts.CancellationToken +import ts.TypeChecker +import ts.Program +import ts.Diagnostic +import Node as _Node +import Expression as _Expression +import ts.QualifiedName +import ts.ExternalModuleReference + +external interface AllAccessorDeclarations { + var firstAccessor: dynamic /* GetAccessorDeclaration | SetAccessorDeclaration */ + get() = definedExternally + set(value) = definedExternally + var secondAccessor: dynamic /* GetAccessorDeclaration? | SetAccessorDeclaration? */ + get() = definedExternally + set(value) = definedExternally + var getAccessor: GetAccessorDeclaration? + var setAccessor: SetAccessorDeclaration? +} + +external interface EmitResolver { + fun isValueAliasDeclaration(node: Node): Boolean + fun isReferencedAliasDeclaration(node: Node, checkChildren: Boolean = definedExternally): Boolean + fun isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): Boolean + fun moduleExportsSomeValue(moduleReferenceExpression: Expression): Boolean + fun getAllAccessorDeclarations(declaration: GetAccessorDeclaration): AllAccessorDeclarations + fun getAllAccessorDeclarations(declaration: SetAccessorDeclaration): AllAccessorDeclarations +} + +external interface DiagnosticsProducingTypeChecker : TypeChecker { + fun getEmitResolver(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): EmitResolver +} + +external open class TransformationContext(program: Program, sourceFile: SourceFile, visitorMap: VisitorMap) { + open var program: Program + open var sourceFile: SourceFile + open var visitorMap: Any + open val diagnostics: Array + open val checker: DiagnosticsProducingTypeChecker + open val resolver: EmitResolver + open val options: dynamic /* typealias OmitIndexSignature = dynamic */ + open val luaTarget: LuaTarget + open val isModule: Boolean + open val isStrict: Boolean + open var currentNodeVisitors: Any + open fun transformNode(node: Node): Array<_Node> + open fun superTransformNode(node: Node): Array<_Node> + open fun transformExpression(node: Expression): _Expression + open fun transformExpression(node: QualifiedName): _Expression + open fun transformExpression(node: ExternalModuleReference): _Expression + open fun superTransformExpression(node: Expression): _Expression + open fun superTransformExpression(node: QualifiedName): _Expression + open fun superTransformExpression(node: ExternalModuleReference): _Expression + open fun transformStatements(node: StatementLikeNode): Array + open fun transformStatements(node: Array): Array + open fun superTransformStatements(node: StatementLikeNode): Array + open fun superTransformStatements(node: Array): Array +} \ No newline at end of file diff --git a/externals/index.module_typescript-to-lua.kt b/externals/index.module_typescript-to-lua.kt new file mode 100644 index 0000000..2016698 --- /dev/null +++ b/externals/index.module_typescript-to-lua.kt @@ -0,0 +1,38 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.WriteFileCallback +import ts.Diagnostic +import tsstdlib.Record + +external fun transpileFiles(rootNames: Array, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, writeFile: WriteFileCallback = definedExternally): EmitResult + +external fun transpileProject(configFileName: String, optionsToExtend: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, writeFile: WriteFileCallback = definedExternally): EmitResult + +external interface TranspileVirtualProjectResult { + var diagnostics: Array + var transpiledFiles: Array +} + +external fun transpileVirtualProject(files: Record, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally): TranspileVirtualProjectResult + +external interface TranspileStringResult { + var diagnostics: Array + var file: TranspiledFile? + get() = definedExternally + set(value) = definedExternally +} + +external fun transpileString(main: String, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally): TranspileStringResult \ No newline at end of file diff --git a/externals/lib.es2015.collection.kt b/externals/lib.es2015.collection.kt new file mode 100644 index 0000000..affffa8 --- /dev/null +++ b/externals/lib.es2015.collection.kt @@ -0,0 +1,49 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface Map { + fun entries(): IterableIterator */> + fun keys(): IterableIterator + fun values(): IterableIterator + fun clear() + fun delete(key: K): Boolean + fun forEach(callbackfn: (value: V, key: K, map: Map) -> Unit, thisArg: Any = definedExternally) + fun get(key: K): V? + fun has(key: K): Boolean + fun set(key: K, value: V): Map /* this */ + val size: Number +} + +external interface MapConstructor { + val prototype: Map +} + +external interface Set { + fun entries(): IterableIterator */> + fun keys(): IterableIterator + fun values(): IterableIterator + fun add(value: T): Set /* this */ + fun clear() + fun delete(value: T): Boolean + fun forEach(callbackfn: (value: T, value2: T, set: Set) -> Unit, thisArg: Any = definedExternally) + fun has(value: T): Boolean + val size: Number +} + +external interface SetConstructor { + val prototype: Set +} \ No newline at end of file diff --git a/externals/lib.es2015.iterable.kt b/externals/lib.es2015.iterable.kt new file mode 100644 index 0000000..1528efa --- /dev/null +++ b/externals/lib.es2015.iterable.kt @@ -0,0 +1,54 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface IteratorYieldResult { + var done: Boolean? + get() = definedExternally + set(value) = definedExternally + var value: TYield +} + +external interface IteratorReturnResult { + var done: Boolean + var value: TReturn +} + +external interface Iterator { + fun next(vararg args: Any /* JsTuple<> | JsTuple */): dynamic /* IteratorYieldResult | IteratorReturnResult */ + val `return`: ((value: TReturn) -> dynamic)? + val `throw`: ((e: Any) -> dynamic)? +} + +typealias Iterator__1 = Iterator + +external interface Iterable + +external interface IterableIterator : Iterator__1 + +external interface PromiseConstructor { + val prototype: Promise + fun all(values: Any /* JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple */): Promise | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple */> + fun all(values: Array */>): Promise> + fun race(values: Array): Promise + fun reject(reason: Any = definedExternally): Promise + fun resolve(value: T): Promise + fun resolve(value: PromiseLike): Promise + fun resolve(): Promise + fun all(values: Iterable */>): Promise> + fun race(values: Iterable): Promise + fun race(values: Iterable */>): Promise +} \ No newline at end of file diff --git a/externals/lib.es5.Intl.module_dukat.kt b/externals/lib.es5.Intl.module_dukat.kt new file mode 100644 index 0000000..62cbcc7 --- /dev/null +++ b/externals/lib.es5.Intl.module_dukat.kt @@ -0,0 +1,220 @@ +@file:JsQualifier("tsstdlib.Intl") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib.Intl + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface CollatorOptions { + var usage: String? + get() = definedExternally + set(value) = definedExternally + var localeMatcher: String? + get() = definedExternally + set(value) = definedExternally + var numeric: Boolean? + get() = definedExternally + set(value) = definedExternally + var caseFirst: String? + get() = definedExternally + set(value) = definedExternally + var sensitivity: String? + get() = definedExternally + set(value) = definedExternally + var ignorePunctuation: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedCollatorOptions { + var locale: String + var usage: String + var sensitivity: String + var ignorePunctuation: Boolean + var collation: String + var caseFirst: String + var numeric: Boolean +} + +@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface Collator { + fun compare(x: String, y: String): Number + fun resolvedOptions(): ResolvedCollatorOptions + + companion object { + @nativeInvoke + operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: CollatorOptions = definedExternally): Collator + fun supportedLocalesOf(locales: Any /* String | Array */, options: CollatorOptions = definedExternally): Array + } +} + +external interface NumberFormatOptions { + var localeMatcher: String? + get() = definedExternally + set(value) = definedExternally + var style: String? + get() = definedExternally + set(value) = definedExternally + var currency: String? + get() = definedExternally + set(value) = definedExternally + var currencyDisplay: String? + get() = definedExternally + set(value) = definedExternally + var useGrouping: Boolean? + get() = definedExternally + set(value) = definedExternally + var minimumIntegerDigits: Number? + get() = definedExternally + set(value) = definedExternally + var minimumFractionDigits: Number? + get() = definedExternally + set(value) = definedExternally + var maximumFractionDigits: Number? + get() = definedExternally + set(value) = definedExternally + var minimumSignificantDigits: Number? + get() = definedExternally + set(value) = definedExternally + var maximumSignificantDigits: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedNumberFormatOptions { + var locale: String + var numberingSystem: String + var style: String + var currency: String? + get() = definedExternally + set(value) = definedExternally + var currencyDisplay: String? + get() = definedExternally + set(value) = definedExternally + var minimumIntegerDigits: Number + var minimumFractionDigits: Number + var maximumFractionDigits: Number + var minimumSignificantDigits: Number? + get() = definedExternally + set(value) = definedExternally + var maximumSignificantDigits: Number? + get() = definedExternally + set(value) = definedExternally + var useGrouping: Boolean +} + +@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface NumberFormat { + fun format(value: Number): String + fun resolvedOptions(): ResolvedNumberFormatOptions + + companion object { + @nativeInvoke + operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: NumberFormatOptions = definedExternally): NumberFormat + fun supportedLocalesOf(locales: Any /* String | Array */, options: NumberFormatOptions = definedExternally): Array + } +} + +external interface DateTimeFormatOptions { + var localeMatcher: String? + get() = definedExternally + set(value) = definedExternally + var weekday: String? + get() = definedExternally + set(value) = definedExternally + var era: String? + get() = definedExternally + set(value) = definedExternally + var year: String? + get() = definedExternally + set(value) = definedExternally + var month: String? + get() = definedExternally + set(value) = definedExternally + var day: String? + get() = definedExternally + set(value) = definedExternally + var hour: String? + get() = definedExternally + set(value) = definedExternally + var minute: String? + get() = definedExternally + set(value) = definedExternally + var second: String? + get() = definedExternally + set(value) = definedExternally + var timeZoneName: String? + get() = definedExternally + set(value) = definedExternally + var formatMatcher: String? + get() = definedExternally + set(value) = definedExternally + var hour12: Boolean? + get() = definedExternally + set(value) = definedExternally + var timeZone: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedDateTimeFormatOptions { + var locale: String + var calendar: String + var numberingSystem: String + var timeZone: String + var hour12: Boolean? + get() = definedExternally + set(value) = definedExternally + var weekday: String? + get() = definedExternally + set(value) = definedExternally + var era: String? + get() = definedExternally + set(value) = definedExternally + var year: String? + get() = definedExternally + set(value) = definedExternally + var month: String? + get() = definedExternally + set(value) = definedExternally + var day: String? + get() = definedExternally + set(value) = definedExternally + var hour: String? + get() = definedExternally + set(value) = definedExternally + var minute: String? + get() = definedExternally + set(value) = definedExternally + var second: String? + get() = definedExternally + set(value) = definedExternally + var timeZoneName: String? + get() = definedExternally + set(value) = definedExternally +} + +@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface DateTimeFormat { + fun format(date: Date = definedExternally): String + fun format(): String + fun format(date: Number = definedExternally): String + fun resolvedOptions(): ResolvedDateTimeFormatOptions + + companion object { + @nativeInvoke + operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: DateTimeFormatOptions = definedExternally): DateTimeFormat + fun supportedLocalesOf(locales: Any /* String | Array */, options: DateTimeFormatOptions = definedExternally): Array + } +} \ No newline at end of file diff --git a/externals/lib.es5.kt b/externals/lib.es5.kt new file mode 100644 index 0000000..c9b2102 --- /dev/null +++ b/externals/lib.es5.kt @@ -0,0 +1,69 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface DateConstructor { + @nativeInvoke + operator fun invoke(): String + val prototype: Date + fun parse(s: String): Number + fun UTC(year: Number, month: Number, date: Number = definedExternally, hours: Number = definedExternally, minutes: Number = definedExternally, seconds: Number = definedExternally, ms: Number = definedExternally): Number + fun now(): Number +} + +external interface ConcatArray { + val length: Number + @nativeGetter + operator fun get(n: Number): T? + @nativeSetter + operator fun set(n: Number, value: T) + fun join(separator: String = definedExternally): String + fun slice(start: Number = definedExternally, end: Number = definedExternally): Array +} + +external interface ArrayConstructor { + fun from(iterable: Iterable): Array + fun from(iterable: ArrayLike): Array + fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array + fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U): Array + fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array + fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U): Array + fun of(vararg items: T): Array + @nativeInvoke + operator fun invoke(arrayLength: Number = definedExternally): Array + @nativeInvoke + operator fun invoke(): Array + @nativeInvoke + operator fun invoke(arrayLength: Number): Array + @nativeInvoke + operator fun invoke(vararg items: T): Array + fun isArray(arg: Any): Boolean + val prototype: Array +} + +external interface PromiseLike { + fun then(onfulfilled: ((value: T) -> Any?)? = definedExternally, onrejected: ((reason: Any) -> Any?)? = definedExternally): PromiseLike +} + +external interface ArrayLike { + val length: Number + @nativeGetter + operator fun get(n: Number): T? + @nativeSetter + operator fun set(n: Number, value: T) +} + +typealias Record = Any \ No newline at end of file diff --git a/externals/lib.scripthost.kt b/externals/lib.scripthost.kt new file mode 100644 index 0000000..809347e --- /dev/null +++ b/externals/lib.scripthost.kt @@ -0,0 +1,20 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external open class VarDate { + open var VarDate_typekey: VarDate +} \ No newline at end of file diff --git a/externals/nonDeclarations.ts.kt b/externals/nonDeclarations.ts.kt new file mode 100644 index 0000000..3650dca --- /dev/null +++ b/externals/nonDeclarations.ts.kt @@ -0,0 +1,114 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package ts + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +typealias SortedReadonlyArray = Array + +typealias SortedArray = Array + +typealias NodeArray = Array + +typealias DotToken = PunctuationToken + +typealias DotDotDotToken = PunctuationToken + +typealias QuestionToken = PunctuationToken + +typealias ExclamationToken = PunctuationToken + +typealias ColonToken = PunctuationToken + +typealias EqualsToken = PunctuationToken + +typealias AsteriskToken = PunctuationToken + +typealias EqualsGreaterThanToken = PunctuationToken + +typealias PlusToken = PunctuationToken + +typealias MinusToken = PunctuationToken + +typealias QuestionDotToken = PunctuationToken + +typealias AssertsKeyword = KeywordToken + +typealias AwaitKeyword = KeywordToken + +typealias AwaitKeywordToken = AwaitKeyword + +typealias AssertsToken = AssertsKeyword + +typealias AbstractKeyword = ModifierToken + +typealias AsyncKeyword = ModifierToken + +typealias ConstKeyword = ModifierToken + +typealias DeclareKeyword = ModifierToken + +typealias DefaultKeyword = ModifierToken + +typealias ExportKeyword = ModifierToken + +typealias PrivateKeyword = ModifierToken + +typealias ProtectedKeyword = ModifierToken + +typealias PublicKeyword = ModifierToken + +typealias ReadonlyKeyword = ModifierToken + +typealias OverrideKeyword = ModifierToken + +typealias StaticKeyword = ModifierToken + +typealias ReadonlyToken = ReadonlyKeyword + +typealias ModifiersArray = NodeArray + +typealias IncrementExpression = UpdateExpression + +typealias ExponentiationOperator = SyntaxKind.AsteriskAsteriskToken + +typealias BinaryOperatorToken = Token + +typealias AssignmentOperatorToken = Token + +typealias FunctionBody = Block + +typealias WriteFileCallback = (fileName: String, data: String, writeByteOrderMark: Boolean, onError: (message: String) -> Unit, sourceFiles: Array) -> Unit + +typealias CustomTransformerFactory = (context: TransformationContext) -> CustomTransformer + +typealias SymbolTable = UnderscoreEscapedMap + +typealias JsFileExtensionInfo = FileExtensionInfo + +typealias EmitHelperUniqueNameCallback = (name: String) -> String + +typealias TransformerFactory = (context: TransformationContext) -> Transformer + +typealias Transformer = (node: T) -> T + +typealias Visitor = (node: Node) -> dynamic + +typealias FileWatcherCallback = (fileName: String, eventKind: FileWatcherEventKind) -> Unit + +typealias DirectoryWatcherCallback = (fileName: String) -> Unit + +typealias DiagnosticReporter = (diagnostic: Diagnostic) -> Unit + +typealias CodeActionCommand = InstallPackageAction \ No newline at end of file diff --git a/externals/output-collector.module_typescript-to-lua.kt b/externals/output-collector.module_typescript-to-lua.kt new file mode 100644 index 0000000..0c57eac --- /dev/null +++ b/externals/output-collector.module_typescript-to-lua.kt @@ -0,0 +1,33 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.SourceFile + +external interface TranspiledFile { + var outPath: String + var sourceFiles: Array + var lua: String? + get() = definedExternally + set(value) = definedExternally + var luaSourceMap: String? + get() = definedExternally + set(value) = definedExternally + var declaration: String? + get() = definedExternally + set(value) = definedExternally + var declarationMap: String? + get() = definedExternally + set(value) = definedExternally +} \ No newline at end of file diff --git a/externals/parse.module_typescript-to-lua.kt b/externals/parse.module_typescript-to-lua.kt new file mode 100644 index 0000000..ff6e944 --- /dev/null +++ b/externals/parse.module_typescript-to-lua.kt @@ -0,0 +1,25 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface ParsedCommandLine : ts.ParsedCommandLine { + override var options: dynamic /* typealias OmitIndexSignature = dynamic */ + get() = definedExternally + set(value) = definedExternally +} + +external fun updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine + +external fun parseCommandLine(args: Array): ParsedCommandLine \ No newline at end of file diff --git a/externals/plugins.module_typescript-to-lua.kt b/externals/plugins.module_typescript-to-lua.kt new file mode 100644 index 0000000..24d3ea4 --- /dev/null +++ b/externals/plugins.module_typescript-to-lua.kt @@ -0,0 +1,24 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface Plugin { + var visitors: Visitors? + get() = definedExternally + set(value) = definedExternally + var printer: Printer? + get() = definedExternally + set(value) = definedExternally +} \ No newline at end of file diff --git a/externals/report.module_typescript-to-lua.kt b/externals/report.module_typescript-to-lua.kt new file mode 100644 index 0000000..f1582a6 --- /dev/null +++ b/externals/report.module_typescript-to-lua.kt @@ -0,0 +1,48 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.DiagnosticRelatedInformation +import ts.DiagnosticCategory +import ts.SourceFile +import ts.Diagnostic +import ts.System +import ts.DiagnosticReporter + +external interface `T$13` { + var code: Any + var reportsUnnecessary: Any? + get() = definedExternally + set(value) = definedExternally + var reportsDeprecated: Any? + get() = definedExternally + set(value) = definedExternally + var source: String? + get() = definedExternally + set(value) = definedExternally + var relatedInformation: Array? + get() = definedExternally + set(value) = definedExternally + var category: DiagnosticCategory + var file: SourceFile? + var start: Number? + var length: Number? + var messageText: dynamic /* String | ts.DiagnosticMessageChain */ + get() = definedExternally + set(value) = definedExternally +} + +external var prepareDiagnosticForFormatting: (diagnostic: Diagnostic) -> `T$13` + +external fun createDiagnosticReporter(pretty: Boolean, system: System = definedExternally): DiagnosticReporter \ No newline at end of file diff --git a/externals/source-map.module_source-map.kt b/externals/source-map.module_source-map.kt new file mode 100644 index 0000000..6880a36 --- /dev/null +++ b/externals/source-map.module_source-map.kt @@ -0,0 +1,192 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +typealias SourceMapUrl = String + +external interface StartOfSourceMap { + var file: String? + get() = definedExternally + set(value) = definedExternally + var sourceRoot: String? + get() = definedExternally + set(value) = definedExternally + var skipValidation: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface RawSourceMap { + var version: Number + var sources: Array + var names: Array + var sourceRoot: String? + get() = definedExternally + set(value) = definedExternally + var sourcesContent: Array? + get() = definedExternally + set(value) = definedExternally + var mappings: String + var file: String +} + +external interface RawIndexMap : StartOfSourceMap { + var version: Number + var sections: Array +} + +external interface RawSection { + var offset: Position + var map: RawSourceMap +} + +external interface Position { + var line: Number + var column: Number +} + +external interface NullablePosition { + var line: Number? + var column: Number? + var lastColumn: Number? +} + +external interface MappedPosition { + var source: String + var line: Number + var column: Number + var name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface NullableMappedPosition { + var source: String? + var line: Number? + var column: Number? + var name: String? +} + +external interface MappingItem { + var source: String + var generatedLine: Number + var generatedColumn: Number + var originalLine: Number + var originalColumn: Number + var name: String +} + +external interface Mapping { + var generated: Position + var original: Position + var source: String + var name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface CodeWithSourceMap { + var code: String + var map: SourceMapGenerator +} + +external interface SourceMapConsumer { + fun computeColumnSpans() + fun originalPositionFor(generatedPosition: Position /* Position & `T$19` */): NullableMappedPosition + fun generatedPositionFor(originalPosition: MappedPosition /* MappedPosition & `T$19` */): NullablePosition + fun allGeneratedPositionsFor(originalPosition: MappedPosition): Array + fun hasContentsOfAllSources(): Boolean + fun sourceContentFor(source: String, returnNullOnMissing: Boolean = definedExternally): String? + fun eachMapping(callback: (mapping: MappingItem) -> Unit, context: Any = definedExternally, order: Number = definedExternally) + fun destroy() +} + +external interface SourceMapConsumerConstructor { + var prototype: SourceMapConsumer + var GENERATED_ORDER: Number + var ORIGINAL_ORDER: Number + var GREATEST_LOWER_BOUND: Number + var LEAST_UPPER_BOUND: Number + fun fromSourceMap(sourceMap: SourceMapGenerator, sourceMapUrl: SourceMapUrl = definedExternally): Promise + fun with(rawSourceMap: RawSourceMap, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise + fun with(rawSourceMap: RawIndexMap, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise + fun with(rawSourceMap: String, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise +} + +external interface BasicSourceMapConsumer : SourceMapConsumer { + var file: String + var sourceRoot: String + var sources: Array + var sourcesContent: Array +} + +external interface BasicSourceMapConsumerConstructor { + var prototype: BasicSourceMapConsumer + fun fromSourceMap(sourceMap: SourceMapGenerator): Promise +} + +external interface IndexedSourceMapConsumer : SourceMapConsumer { + var sources: Array +} + +external interface IndexedSourceMapConsumerConstructor { + var prototype: IndexedSourceMapConsumer +} + +external open class SourceMapGenerator(startOfSourceMap: StartOfSourceMap = definedExternally) { + open fun addMapping(mapping: Mapping) + open fun setSourceContent(sourceFile: String, sourceContent: String) + open fun applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile: String = definedExternally, sourceMapPath: String = definedExternally) + override fun toString(): String + open fun toJSON(): RawSourceMap + + companion object { + fun fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator + } +} + +external open class SourceNode { + open var children: Array + open var sourceContents: Any + open var line: Number + open var column: Number + open var source: String + open var name: String + constructor() + constructor(line: Number?, column: Number?, source: String?, chunks: Array = definedExternally, name: String = definedExternally) + constructor(line: Number?, column: Number?, source: String?) + constructor(line: Number?, column: Number?, source: String?, chunks: Array = definedExternally) + constructor(line: Number?, column: Number?, source: String?, chunks: SourceNode = definedExternally, name: String = definedExternally) + constructor(line: Number?, column: Number?, source: String?, chunks: SourceNode = definedExternally) + constructor(line: Number?, column: Number?, source: String?, chunks: String = definedExternally, name: String = definedExternally) + constructor(line: Number?, column: Number?, source: String?, chunks: String = definedExternally) + open fun add(chunk: Array): SourceNode + open fun add(chunk: SourceNode): SourceNode + open fun add(chunk: String): SourceNode + open fun prepend(chunk: Array): SourceNode + open fun prepend(chunk: SourceNode): SourceNode + open fun prepend(chunk: String): SourceNode + open fun setSourceContent(sourceFile: String, sourceContent: String) + open fun walk(fn: (chunk: String, mapping: MappedPosition) -> Unit) + open fun walkSourceContents(fn: (file: String, content: String) -> Unit) + open fun join(sep: String): SourceNode + open fun replaceRight(pattern: String, replacement: String): SourceNode + override fun toString(): String + open fun toStringWithSourceMap(startOfSourceMap: StartOfSourceMap = definedExternally): CodeWithSourceMap + + companion object { + fun fromStringWithSourceMap(code: String, sourceMapConsumer: SourceMapConsumer, relativePath: String = definedExternally): SourceNode + } +} \ No newline at end of file diff --git a/externals/transpile.module_typescript-to-lua.kt b/externals/transpile.module_typescript-to-lua.kt new file mode 100644 index 0000000..8681706 --- /dev/null +++ b/externals/transpile.module_typescript-to-lua.kt @@ -0,0 +1,40 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.Program +import ts.SourceFile +import ts.CustomTransformers +import ts.Diagnostic +import ts.WriteFileCallback + +external interface TranspileOptions { + var program: Program + var sourceFiles: Array? + get() = definedExternally + set(value) = definedExternally + var customTransformers: CustomTransformers? + get() = definedExternally + set(value) = definedExternally + var plugins: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface TranspileResult { + var diagnostics: Array + var transpiledFiles: Array +} + +external fun getProgramTranspileResult(emitHost: EmitHost, writeFileResult: WriteFileCallback, __2: TranspileOptions): TranspileResult \ No newline at end of file diff --git a/externals/transpiler.module_typescript-to-lua.kt b/externals/transpiler.module_typescript-to-lua.kt new file mode 100644 index 0000000..16b18b0 --- /dev/null +++ b/externals/transpiler.module_typescript-to-lua.kt @@ -0,0 +1,55 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.WriteFileCallback +import ts.Diagnostic +import ts.Program + +external interface TranspilerOptions { + var emitHost: EmitHost? + get() = definedExternally + set(value) = definedExternally +} + +external interface EmitOptions : TranspileOptions { + var writeFile: WriteFileCallback? + get() = definedExternally + set(value) = definedExternally +} + +external interface EmitResult { + var emitSkipped: Boolean + var diagnostics: Array +} + +external interface `T$20` { + var emitPlan: Array +} + +external open class Transpiler(__0: TranspilerOptions = definedExternally) { + open var emitHost: EmitHost + open fun emit(emitOptions: EmitOptions): EmitResult + open fun getEmitPlan(program: Program, diagnostics: Array, files: Array): `T$20` +} + +external fun getEmitPath(file: String, program: Program): String + +external fun getEmitPathRelativeToOutDir(fileName: String, program: Program): String + +external fun getSourceDir(program: Program): String + +external fun getEmitOutDir(program: Program): String + +external fun getProjectRoot(program: Program): String \ No newline at end of file diff --git a/externals/tsconfig.module_typescript-to-lua.kt b/externals/tsconfig.module_typescript-to-lua.kt new file mode 100644 index 0000000..865bc70 --- /dev/null +++ b/externals/tsconfig.module_typescript-to-lua.kt @@ -0,0 +1,18 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.System + +external fun parseConfigFileWithSystem(configFileName: String, commandLineOptions: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, system: System = definedExternally): ParsedCommandLine \ No newline at end of file diff --git a/externals/typescript.module_typescript.kt b/externals/typescript.module_typescript.kt new file mode 100644 index 0000000..83261af --- /dev/null +++ b/externals/typescript.module_typescript.kt @@ -0,0 +1,19 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun setTimeout(handler: (args: Any) -> Unit, timeout: Number): Any + +external fun clearTimeout(handle: Any) \ No newline at end of file diff --git a/externals/typescript.ts.ScriptSnapshot.module_typescript.kt b/externals/typescript.ts.ScriptSnapshot.module_typescript.kt new file mode 100644 index 0000000..acab3da --- /dev/null +++ b/externals/typescript.ts.ScriptSnapshot.module_typescript.kt @@ -0,0 +1,20 @@ +@file:JsQualifier("ts.ScriptSnapshot") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package ts.ScriptSnapshot + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.IScriptSnapshot + +external fun fromString(text: String): IScriptSnapshot \ No newline at end of file diff --git a/externals/typescript.ts.module_typescript.kt b/externals/typescript.ts.module_typescript.kt new file mode 100644 index 0000000..841356c --- /dev/null +++ b/externals/typescript.ts.module_typescript.kt @@ -0,0 +1,8236 @@ +@file:JsModule("typescript") +@file:JsNonModule +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package ts + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external var versionMajorMinor: Any + +external var version: String + +external interface MapLike { + @nativeGetter + operator fun get(index: String): T? + @nativeSetter + operator fun set(index: String, value: T) +} + +external interface ReadonlyCollection { + val size: Number + fun has(key: K): Boolean + fun keys(): Iterator +} + +external interface Collection : ReadonlyCollection { + fun delete(key: K): Boolean + fun clear() +} + +external interface ReadonlyESMap : ReadonlyCollection { + fun get(key: K): V? + fun values(): Iterator + fun entries(): Iterator */> + fun forEach(action: (value: V, key: K) -> Unit) +} + +external interface ReadonlyMap : ReadonlyESMap + +external interface ESMap : ReadonlyESMap, Collection { + fun set(key: K, value: V): ESMap /* this */ +} + +external interface Map : ESMap + +external interface ReadonlySet : ReadonlyCollection { + override fun has(value: T): Boolean + fun values(): Iterator + fun entries(): Iterator */> + fun forEach(action: (value: T, key: T) -> Unit) +} + +external interface Set : ReadonlySet, Collection { + fun add(value: T): Set /* this */ + override fun delete(value: T): Boolean +} + +external interface Iterator { + fun next(): dynamic /* `T$1` | `T$2` */ +} + +external interface Push { + fun push(vararg values: T) +} + +external interface TextRange { + var pos: Number + var end: Number +} + +external interface ReadonlyTextRange { + val pos: Number + val end: Number +} + +external enum class SyntaxKind { + Unknown /* = 0 */, + EndOfFileToken /* = 1 */, + SingleLineCommentTrivia /* = 2 */, + MultiLineCommentTrivia /* = 3 */, + NewLineTrivia /* = 4 */, + WhitespaceTrivia /* = 5 */, + ShebangTrivia /* = 6 */, + ConflictMarkerTrivia /* = 7 */, + NumericLiteral /* = 8 */, + BigIntLiteral /* = 9 */, + StringLiteral /* = 10 */, + JsxText /* = 11 */, + JsxTextAllWhiteSpaces /* = 12 */, + RegularExpressionLiteral /* = 13 */, + NoSubstitutionTemplateLiteral /* = 14 */, + TemplateHead /* = 15 */, + TemplateMiddle /* = 16 */, + TemplateTail /* = 17 */, + OpenBraceToken /* = 18 */, + CloseBraceToken /* = 19 */, + OpenParenToken /* = 20 */, + CloseParenToken /* = 21 */, + OpenBracketToken /* = 22 */, + CloseBracketToken /* = 23 */, + DotToken /* = 24 */, + DotDotDotToken /* = 25 */, + SemicolonToken /* = 26 */, + CommaToken /* = 27 */, + QuestionDotToken /* = 28 */, + LessThanToken /* = 29 */, + LessThanSlashToken /* = 30 */, + GreaterThanToken /* = 31 */, + LessThanEqualsToken /* = 32 */, + GreaterThanEqualsToken /* = 33 */, + EqualsEqualsToken /* = 34 */, + ExclamationEqualsToken /* = 35 */, + EqualsEqualsEqualsToken /* = 36 */, + ExclamationEqualsEqualsToken /* = 37 */, + EqualsGreaterThanToken /* = 38 */, + PlusToken /* = 39 */, + MinusToken /* = 40 */, + AsteriskToken /* = 41 */, + AsteriskAsteriskToken /* = 42 */, + SlashToken /* = 43 */, + PercentToken /* = 44 */, + PlusPlusToken /* = 45 */, + MinusMinusToken /* = 46 */, + LessThanLessThanToken /* = 47 */, + GreaterThanGreaterThanToken /* = 48 */, + GreaterThanGreaterThanGreaterThanToken /* = 49 */, + AmpersandToken /* = 50 */, + BarToken /* = 51 */, + CaretToken /* = 52 */, + ExclamationToken /* = 53 */, + TildeToken /* = 54 */, + AmpersandAmpersandToken /* = 55 */, + BarBarToken /* = 56 */, + QuestionToken /* = 57 */, + ColonToken /* = 58 */, + AtToken /* = 59 */, + QuestionQuestionToken /* = 60 */, + BacktickToken /* = 61 */, + HashToken /* = 62 */, + EqualsToken /* = 63 */, + PlusEqualsToken /* = 64 */, + MinusEqualsToken /* = 65 */, + AsteriskEqualsToken /* = 66 */, + AsteriskAsteriskEqualsToken /* = 67 */, + SlashEqualsToken /* = 68 */, + PercentEqualsToken /* = 69 */, + LessThanLessThanEqualsToken /* = 70 */, + GreaterThanGreaterThanEqualsToken /* = 71 */, + GreaterThanGreaterThanGreaterThanEqualsToken /* = 72 */, + AmpersandEqualsToken /* = 73 */, + BarEqualsToken /* = 74 */, + BarBarEqualsToken /* = 75 */, + AmpersandAmpersandEqualsToken /* = 76 */, + QuestionQuestionEqualsToken /* = 77 */, + CaretEqualsToken /* = 78 */, + Identifier /* = 79 */, + PrivateIdentifier /* = 80 */, + BreakKeyword /* = 81 */, + CaseKeyword /* = 82 */, + CatchKeyword /* = 83 */, + ClassKeyword /* = 84 */, + ConstKeyword /* = 85 */, + ContinueKeyword /* = 86 */, + DebuggerKeyword /* = 87 */, + DefaultKeyword /* = 88 */, + DeleteKeyword /* = 89 */, + DoKeyword /* = 90 */, + ElseKeyword /* = 91 */, + EnumKeyword /* = 92 */, + ExportKeyword /* = 93 */, + ExtendsKeyword /* = 94 */, + FalseKeyword /* = 95 */, + FinallyKeyword /* = 96 */, + ForKeyword /* = 97 */, + FunctionKeyword /* = 98 */, + IfKeyword /* = 99 */, + ImportKeyword /* = 100 */, + InKeyword /* = 101 */, + InstanceOfKeyword /* = 102 */, + NewKeyword /* = 103 */, + NullKeyword /* = 104 */, + ReturnKeyword /* = 105 */, + SuperKeyword /* = 106 */, + SwitchKeyword /* = 107 */, + ThisKeyword /* = 108 */, + ThrowKeyword /* = 109 */, + TrueKeyword /* = 110 */, + TryKeyword /* = 111 */, + TypeOfKeyword /* = 112 */, + VarKeyword /* = 113 */, + VoidKeyword /* = 114 */, + WhileKeyword /* = 115 */, + WithKeyword /* = 116 */, + ImplementsKeyword /* = 117 */, + InterfaceKeyword /* = 118 */, + LetKeyword /* = 119 */, + PackageKeyword /* = 120 */, + PrivateKeyword /* = 121 */, + ProtectedKeyword /* = 122 */, + PublicKeyword /* = 123 */, + StaticKeyword /* = 124 */, + YieldKeyword /* = 125 */, + AbstractKeyword /* = 126 */, + AsKeyword /* = 127 */, + AssertsKeyword /* = 128 */, + AnyKeyword /* = 129 */, + AsyncKeyword /* = 130 */, + AwaitKeyword /* = 131 */, + BooleanKeyword /* = 132 */, + ConstructorKeyword /* = 133 */, + DeclareKeyword /* = 134 */, + GetKeyword /* = 135 */, + InferKeyword /* = 136 */, + IntrinsicKeyword /* = 137 */, + IsKeyword /* = 138 */, + KeyOfKeyword /* = 139 */, + ModuleKeyword /* = 140 */, + NamespaceKeyword /* = 141 */, + NeverKeyword /* = 142 */, + ReadonlyKeyword /* = 143 */, + RequireKeyword /* = 144 */, + NumberKeyword /* = 145 */, + ObjectKeyword /* = 146 */, + SetKeyword /* = 147 */, + StringKeyword /* = 148 */, + SymbolKeyword /* = 149 */, + TypeKeyword /* = 150 */, + UndefinedKeyword /* = 151 */, + UniqueKeyword /* = 152 */, + UnknownKeyword /* = 153 */, + FromKeyword /* = 154 */, + GlobalKeyword /* = 155 */, + BigIntKeyword /* = 156 */, + OverrideKeyword /* = 157 */, + OfKeyword /* = 158 */, + QualifiedName /* = 159 */, + ComputedPropertyName /* = 160 */, + TypeParameter /* = 161 */, + Parameter /* = 162 */, + Decorator /* = 163 */, + PropertySignature /* = 164 */, + PropertyDeclaration /* = 165 */, + MethodSignature /* = 166 */, + MethodDeclaration /* = 167 */, + ClassStaticBlockDeclaration /* = 168 */, + Constructor /* = 169 */, + GetAccessor /* = 170 */, + SetAccessor /* = 171 */, + CallSignature /* = 172 */, + ConstructSignature /* = 173 */, + IndexSignature /* = 174 */, + TypePredicate /* = 175 */, + TypeReference /* = 176 */, + FunctionType /* = 177 */, + ConstructorType /* = 178 */, + TypeQuery /* = 179 */, + TypeLiteral /* = 180 */, + ArrayType /* = 181 */, + TupleType /* = 182 */, + OptionalType /* = 183 */, + RestType /* = 184 */, + UnionType /* = 185 */, + IntersectionType /* = 186 */, + ConditionalType /* = 187 */, + InferType /* = 188 */, + ParenthesizedType /* = 189 */, + ThisType /* = 190 */, + TypeOperator /* = 191 */, + IndexedAccessType /* = 192 */, + MappedType /* = 193 */, + LiteralType /* = 194 */, + NamedTupleMember /* = 195 */, + TemplateLiteralType /* = 196 */, + TemplateLiteralTypeSpan /* = 197 */, + ImportType /* = 198 */, + ObjectBindingPattern /* = 199 */, + ArrayBindingPattern /* = 200 */, + BindingElement /* = 201 */, + ArrayLiteralExpression /* = 202 */, + ObjectLiteralExpression /* = 203 */, + PropertyAccessExpression /* = 204 */, + ElementAccessExpression /* = 205 */, + CallExpression /* = 206 */, + NewExpression /* = 207 */, + TaggedTemplateExpression /* = 208 */, + TypeAssertionExpression /* = 209 */, + ParenthesizedExpression /* = 210 */, + FunctionExpression /* = 211 */, + ArrowFunction /* = 212 */, + DeleteExpression /* = 213 */, + TypeOfExpression /* = 214 */, + VoidExpression /* = 215 */, + AwaitExpression /* = 216 */, + PrefixUnaryExpression /* = 217 */, + PostfixUnaryExpression /* = 218 */, + BinaryExpression /* = 219 */, + ConditionalExpression /* = 220 */, + TemplateExpression /* = 221 */, + YieldExpression /* = 222 */, + SpreadElement /* = 223 */, + ClassExpression /* = 224 */, + OmittedExpression /* = 225 */, + ExpressionWithTypeArguments /* = 226 */, + AsExpression /* = 227 */, + NonNullExpression /* = 228 */, + MetaProperty /* = 229 */, + SyntheticExpression /* = 230 */, + TemplateSpan /* = 231 */, + SemicolonClassElement /* = 232 */, + Block /* = 233 */, + EmptyStatement /* = 234 */, + VariableStatement /* = 235 */, + ExpressionStatement /* = 236 */, + IfStatement /* = 237 */, + DoStatement /* = 238 */, + WhileStatement /* = 239 */, + ForStatement /* = 240 */, + ForInStatement /* = 241 */, + ForOfStatement /* = 242 */, + ContinueStatement /* = 243 */, + BreakStatement /* = 244 */, + ReturnStatement /* = 245 */, + WithStatement /* = 246 */, + SwitchStatement /* = 247 */, + LabeledStatement /* = 248 */, + ThrowStatement /* = 249 */, + TryStatement /* = 250 */, + DebuggerStatement /* = 251 */, + VariableDeclaration /* = 252 */, + VariableDeclarationList /* = 253 */, + FunctionDeclaration /* = 254 */, + ClassDeclaration /* = 255 */, + InterfaceDeclaration /* = 256 */, + TypeAliasDeclaration /* = 257 */, + EnumDeclaration /* = 258 */, + ModuleDeclaration /* = 259 */, + ModuleBlock /* = 260 */, + CaseBlock /* = 261 */, + NamespaceExportDeclaration /* = 262 */, + ImportEqualsDeclaration /* = 263 */, + ImportDeclaration /* = 264 */, + ImportClause /* = 265 */, + NamespaceImport /* = 266 */, + NamedImports /* = 267 */, + ImportSpecifier /* = 268 */, + ExportAssignment /* = 269 */, + ExportDeclaration /* = 270 */, + NamedExports /* = 271 */, + NamespaceExport /* = 272 */, + ExportSpecifier /* = 273 */, + MissingDeclaration /* = 274 */, + ExternalModuleReference /* = 275 */, + JsxElement /* = 276 */, + JsxSelfClosingElement /* = 277 */, + JsxOpeningElement /* = 278 */, + JsxClosingElement /* = 279 */, + JsxFragment /* = 280 */, + JsxOpeningFragment /* = 281 */, + JsxClosingFragment /* = 282 */, + JsxAttribute /* = 283 */, + JsxAttributes /* = 284 */, + JsxSpreadAttribute /* = 285 */, + JsxExpression /* = 286 */, + CaseClause /* = 287 */, + DefaultClause /* = 288 */, + HeritageClause /* = 289 */, + CatchClause /* = 290 */, + PropertyAssignment /* = 291 */, + ShorthandPropertyAssignment /* = 292 */, + SpreadAssignment /* = 293 */, + EnumMember /* = 294 */, + UnparsedPrologue /* = 295 */, + UnparsedPrepend /* = 296 */, + UnparsedText /* = 297 */, + UnparsedInternalText /* = 298 */, + UnparsedSyntheticReference /* = 299 */, + SourceFile /* = 300 */, + Bundle /* = 301 */, + UnparsedSource /* = 302 */, + InputFiles /* = 303 */, + JSDocTypeExpression /* = 304 */, + JSDocNameReference /* = 305 */, + JSDocMemberName /* = 306 */, + JSDocAllType /* = 307 */, + JSDocUnknownType /* = 308 */, + JSDocNullableType /* = 309 */, + JSDocNonNullableType /* = 310 */, + JSDocOptionalType /* = 311 */, + JSDocFunctionType /* = 312 */, + JSDocVariadicType /* = 313 */, + JSDocNamepathType /* = 314 */, + JSDocComment /* = 315 */, + JSDocText /* = 316 */, + JSDocTypeLiteral /* = 317 */, + JSDocSignature /* = 318 */, + JSDocLink /* = 319 */, + JSDocLinkCode /* = 320 */, + JSDocLinkPlain /* = 321 */, + JSDocTag /* = 322 */, + JSDocAugmentsTag /* = 323 */, + JSDocImplementsTag /* = 324 */, + JSDocAuthorTag /* = 325 */, + JSDocDeprecatedTag /* = 326 */, + JSDocClassTag /* = 327 */, + JSDocPublicTag /* = 328 */, + JSDocPrivateTag /* = 329 */, + JSDocProtectedTag /* = 330 */, + JSDocReadonlyTag /* = 331 */, + JSDocOverrideTag /* = 332 */, + JSDocCallbackTag /* = 333 */, + JSDocEnumTag /* = 334 */, + JSDocParameterTag /* = 335 */, + JSDocReturnTag /* = 336 */, + JSDocThisTag /* = 337 */, + JSDocTypeTag /* = 338 */, + JSDocTemplateTag /* = 339 */, + JSDocTypedefTag /* = 340 */, + JSDocSeeTag /* = 341 */, + JSDocPropertyTag /* = 342 */, + SyntaxList /* = 343 */, + NotEmittedStatement /* = 344 */, + PartiallyEmittedExpression /* = 345 */, + CommaListExpression /* = 346 */, + MergeDeclarationMarker /* = 347 */, + EndOfDeclarationMarker /* = 348 */, + SyntheticReferenceExpression /* = 349 */, + Count /* = 350 */, + FirstAssignment /* = 63 */, + LastAssignment /* = 78 */, + FirstCompoundAssignment /* = 64 */, + LastCompoundAssignment /* = 78 */, + FirstReservedWord /* = 81 */, + LastReservedWord /* = 116 */, + FirstKeyword /* = 81 */, + LastKeyword /* = 158 */, + FirstFutureReservedWord /* = 117 */, + LastFutureReservedWord /* = 125 */, + FirstTypeNode /* = 175 */, + LastTypeNode /* = 198 */, + FirstPunctuation /* = 18 */, + LastPunctuation /* = 78 */, + FirstToken /* = 0 */, + LastToken /* = 158 */, + FirstTriviaToken /* = 2 */, + LastTriviaToken /* = 7 */, + FirstLiteralToken /* = 8 */, + LastLiteralToken /* = 14 */, + FirstTemplateToken /* = 14 */, + LastTemplateToken /* = 17 */, + FirstBinaryOperator /* = 29 */, + LastBinaryOperator /* = 78 */, + FirstStatement /* = 235 */, + LastStatement /* = 251 */, + FirstNode /* = 159 */, + FirstJSDocNode /* = 304 */, + LastJSDocNode /* = 342 */, + FirstJSDocTagNode /* = 322 */, + LastJSDocTagNode /* = 342 */ +} + +external enum class NodeFlags { + None /* = 0 */, + Let /* = 1 */, + Const /* = 2 */, + NestedNamespace /* = 4 */, + Synthesized /* = 8 */, + Namespace /* = 16 */, + OptionalChain /* = 32 */, + ExportContext /* = 64 */, + ContainsThis /* = 128 */, + HasImplicitReturn /* = 256 */, + HasExplicitReturn /* = 512 */, + GlobalAugmentation /* = 1024 */, + HasAsyncFunctions /* = 2048 */, + DisallowInContext /* = 4096 */, + YieldContext /* = 8192 */, + DecoratorContext /* = 16384 */, + AwaitContext /* = 32768 */, + ThisNodeHasError /* = 65536 */, + JavaScriptFile /* = 131072 */, + ThisNodeOrAnySubNodesHasError /* = 262144 */, + HasAggregatedChildData /* = 524288 */, + JSDoc /* = 4194304 */, + JsonFile /* = 33554432 */, + BlockScoped /* = 3 */, + ReachabilityCheckFlags /* = 768 */, + ReachabilityAndEmitFlags /* = 2816 */, + ContextFlags /* = 25358336 */, + TypeExcludesFlags /* = 40960 */ +} + +external enum class ModifierFlags { + None /* = 0 */, + Export /* = 1 */, + Ambient /* = 2 */, + Public /* = 4 */, + Private /* = 8 */, + Protected /* = 16 */, + Static /* = 32 */, + Readonly /* = 64 */, + Abstract /* = 128 */, + Async /* = 256 */, + Default /* = 512 */, + Const /* = 2048 */, + HasComputedJSDocModifiers /* = 4096 */, + Deprecated /* = 8192 */, + Override /* = 16384 */, + HasComputedFlags /* = 536870912 */, + AccessibilityModifier /* = 28 */, + ParameterPropertyModifier /* = 16476 */, + NonPublicAccessibilityModifier /* = 24 */, + TypeScriptModifier /* = 18654 */, + ExportDefault /* = 513 */, + All /* = 27647 */ +} + +external enum class JsxFlags { + None /* = 0 */, + IntrinsicNamedElement /* = 1 */, + IntrinsicIndexedElement /* = 2 */, + IntrinsicElement /* = 3 */ +} + +external interface Node : ReadonlyTextRange { + fun getSourceFile(): SourceFile + fun getChildCount(sourceFile: SourceFile = definedExternally): Number + fun getChildAt(index: Number, sourceFile: SourceFile = definedExternally): Node + fun getChildren(sourceFile: SourceFile = definedExternally): Array + fun getStart(sourceFile: SourceFile = definedExternally, includeJsDocComment: Boolean = definedExternally): Number + fun getFullStart(): Number + fun getEnd(): Number + fun getWidth(sourceFile: SourceFileLike = definedExternally): Number + fun getFullWidth(): Number + fun getLeadingTriviaWidth(sourceFile: SourceFile = definedExternally): Number + fun getFullText(sourceFile: SourceFile = definedExternally): String + fun getText(sourceFile: SourceFile = definedExternally): String + fun getFirstToken(sourceFile: SourceFile = definedExternally): Node? + fun getLastToken(sourceFile: SourceFile = definedExternally): Node? + fun forEachChild(cbNode: (node: Node) -> T?, cbNodeArray: (nodes: NodeArray) -> T? = definedExternally): T? + val kind: SyntaxKind + val flags: NodeFlags + val decorators: NodeArray? + get() = definedExternally + val modifiers: ModifiersArray? + get() = definedExternally + val parent: Node +} + +external interface JSDocContainer + +external interface Token : Node { + override val kind: TKind +} + +external interface PunctuationToken : Token + +external interface KeywordToken : Token + +external interface ModifierToken : KeywordToken + +external enum class GeneratedIdentifierFlags { + None /* = 0 */, + ReservedInNestedScopes /* = 8 */, + Optimistic /* = 16 */, + FileLevel /* = 32 */, + AllowNameSubstitution /* = 64 */ +} + +external interface Identifier : PrimaryExpression, Declaration { + val text: String + val escapedText: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + get() = definedExternally + val originalKeywordKind: SyntaxKind? + get() = definedExternally + var isInJSDocNamespace: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TransientIdentifier : Identifier { + var resolvedSymbol: Symbol +} + +external interface QualifiedName : Node { + val left: dynamic /* Identifier | QualifiedName */ + get() = definedExternally + val right: Identifier +} + +external interface Declaration : Node { + var _declarationBrand: Any +} + +external interface NamedDeclaration : Declaration { + val name: dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ + get() = definedExternally +} + +external interface DeclarationStatement : NamedDeclaration, Statement { + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? */ + get() = definedExternally +} + +external interface ComputedPropertyName : Node { + override val parent: Declaration + val expression: Expression +} + +external interface PrivateIdentifier : Node { + val text: String + val escapedText: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + get() = definedExternally +} + +external interface Decorator : Node { + override val parent: NamedDeclaration + val expression: LeftHandSideExpression +} + +external interface TypeParameterDeclaration : NamedDeclaration { + override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | InferTypeNode */ + get() = definedExternally + override val name: Identifier + val constraint: TypeNode? + get() = definedExternally + val default: TypeNode? + get() = definedExternally + var expression: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureDeclarationBase : NamedDeclaration, JSDocContainer { + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + val typeParameters: NodeArray? + get() = definedExternally + val parameters: NodeArray + val type: TypeNode? + get() = definedExternally +} + +external interface CallSignatureDeclaration : SignatureDeclarationBase, TypeElement { + override val kind: Any + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally +} + +external interface ConstructSignatureDeclaration : SignatureDeclarationBase, TypeElement { + override val kind: Any + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally +} + +external interface VariableDeclaration : NamedDeclaration, JSDocContainer { + override val parent: dynamic /* VariableDeclarationList | CatchClause */ + get() = definedExternally + override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ + get() = definedExternally + val exclamationToken: ExclamationToken? + get() = definedExternally + val type: TypeNode? + get() = definedExternally + val initializer: Expression? + get() = definedExternally +} + +external interface VariableDeclarationList : Node { + override val parent: dynamic /* VariableStatement | ForStatement | ForOfStatement | ForInStatement */ + get() = definedExternally + val declarations: NodeArray +} + +external interface ParameterDeclaration : NamedDeclaration, JSDocContainer { + override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ + get() = definedExternally + val dotDotDotToken: DotDotDotToken? + get() = definedExternally + override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ + get() = definedExternally + val questionToken: QuestionToken? + get() = definedExternally + val type: TypeNode? + get() = definedExternally + val initializer: Expression? + get() = definedExternally +} + +external interface BindingElement : NamedDeclaration { + override val parent: dynamic /* ObjectBindingPattern | ArrayBindingPattern */ + get() = definedExternally + val propertyName: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + val dotDotDotToken: DotDotDotToken? + get() = definedExternally + override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ + get() = definedExternally + val initializer: Expression? + get() = definedExternally +} + +external interface PropertySignature : TypeElement, JSDocContainer { + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + override val questionToken: QuestionToken? + get() = definedExternally + val type: TypeNode? + get() = definedExternally + var initializer: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface PropertyDeclaration : ClassElement, JSDocContainer { + override val parent: dynamic /* ClassDeclaration | ClassExpression */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + val questionToken: QuestionToken? + get() = definedExternally + val exclamationToken: ExclamationToken? + get() = definedExternally + val type: TypeNode? + get() = definedExternally + val initializer: Expression? + get() = definedExternally +} + +external interface ObjectLiteralElement : NamedDeclaration { + var _objectLiteralBrand: Any + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally +} + +external interface PropertyAssignment : ObjectLiteralElement, JSDocContainer { + override val parent: ObjectLiteralExpression + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + val questionToken: QuestionToken? + get() = definedExternally + val exclamationToken: ExclamationToken? + get() = definedExternally + val initializer: Expression +} + +external interface ShorthandPropertyAssignment : ObjectLiteralElement, JSDocContainer { + override val parent: ObjectLiteralExpression + override val name: Identifier + val questionToken: QuestionToken? + get() = definedExternally + val exclamationToken: ExclamationToken? + get() = definedExternally + val equalsToken: EqualsToken? + get() = definedExternally + val objectAssignmentInitializer: Expression? + get() = definedExternally +} + +external interface SpreadAssignment : ObjectLiteralElement, JSDocContainer { + override val parent: ObjectLiteralExpression + val expression: Expression +} + +external interface PropertyLikeDeclaration : NamedDeclaration { + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally +} + +external interface ObjectBindingPattern : Node { + override val parent: dynamic /* VariableDeclaration | ParameterDeclaration | BindingElement */ + get() = definedExternally + val elements: NodeArray +} + +external interface ArrayBindingPattern : Node { + override val parent: dynamic /* VariableDeclaration | ParameterDeclaration | BindingElement */ + get() = definedExternally + val elements: NodeArray +} + +external interface FunctionLikeDeclarationBase : SignatureDeclarationBase { + var _functionLikeDeclarationBrand: Any + val asteriskToken: AsteriskToken? + get() = definedExternally + val questionToken: QuestionToken? + get() = definedExternally + val exclamationToken: ExclamationToken? + get() = definedExternally + val body: dynamic /* Block? | Expression? */ + get() = definedExternally +} + +external interface FunctionDeclaration : FunctionLikeDeclarationBase, DeclarationStatement { + override val kind: Any + override val name: Identifier? + get() = definedExternally + override val body: FunctionBody? + get() = definedExternally +} + +external interface MethodSignature : SignatureDeclarationBase, TypeElement { + override val kind: Any + override val parent: dynamic /* ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally +} + +external interface MethodDeclaration : FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { + override val kind: Any + override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + override val body: FunctionBody? + get() = definedExternally +} + +external interface ConstructorDeclaration : FunctionLikeDeclarationBase, ClassElement, JSDocContainer { + override val kind: Any + override val parent: dynamic /* ClassDeclaration | ClassExpression */ + get() = definedExternally + override val body: FunctionBody? + get() = definedExternally +} + +external interface SemicolonClassElement : ClassElement { + override val parent: dynamic /* ClassDeclaration | ClassExpression */ + get() = definedExternally +} + +external interface GetAccessorDeclaration : FunctionLikeDeclarationBase, ClassElement, TypeElement, ObjectLiteralElement, JSDocContainer { + override val kind: Any + override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression | TypeLiteralNode | InterfaceDeclaration */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + override val body: FunctionBody? + get() = definedExternally + override val questionToken: QuestionToken? + get() = definedExternally +} + +external interface SetAccessorDeclaration : FunctionLikeDeclarationBase, ClassElement, TypeElement, ObjectLiteralElement, JSDocContainer { + override val kind: Any + override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression | TypeLiteralNode | InterfaceDeclaration */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + override val body: FunctionBody? + get() = definedExternally + override val questionToken: QuestionToken? + get() = definedExternally +} + +external interface IndexSignatureDeclaration : SignatureDeclarationBase, ClassElement, TypeElement { + override val kind: Any + override val parent: dynamic /* ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode */ + get() = definedExternally + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally +} + +external interface ClassStaticBlockDeclaration : ClassElement, JSDocContainer { + override val parent: dynamic /* ClassDeclaration | ClassExpression */ + get() = definedExternally + val body: Block +} + +external interface TypeNode : Node { + var _typeNodeBrand: Any +} + +external interface KeywordTypeNode : KeywordToken, TypeNode { + override val kind: TKind +} + +external interface ImportTypeNode : NodeWithTypeArguments { + val isTypeOf: Boolean + val argument: TypeNode + val qualifier: dynamic /* Identifier? | QualifiedName? */ + get() = definedExternally +} + +external interface ThisTypeNode : TypeNode + +external interface FunctionOrConstructorTypeNodeBase : TypeNode, SignatureDeclarationBase { + override val kind: dynamic /* SyntaxKind.FunctionType | SyntaxKind.ConstructorType */ + get() = definedExternally +} + +external interface FunctionTypeNode : FunctionOrConstructorTypeNodeBase { + override val kind: Any +} + +external interface ConstructorTypeNode : FunctionOrConstructorTypeNodeBase { + override val kind: Any +} + +external interface NodeWithTypeArguments : TypeNode { + val typeArguments: NodeArray? + get() = definedExternally +} + +external interface TypeReferenceNode : NodeWithTypeArguments { + val typeName: dynamic /* Identifier | QualifiedName */ + get() = definedExternally +} + +external interface TypePredicateNode : TypeNode { + override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | JSDocTypeExpression */ + get() = definedExternally + val assertsModifier: AssertsToken? + get() = definedExternally + val parameterName: dynamic /* Identifier | ThisTypeNode */ + get() = definedExternally + val type: TypeNode? + get() = definedExternally +} + +external interface TypeQueryNode : TypeNode { + val exprName: dynamic /* Identifier | QualifiedName */ + get() = definedExternally +} + +external interface TypeLiteralNode : TypeNode, Declaration { + val members: NodeArray +} + +external interface ArrayTypeNode : TypeNode { + val elementType: TypeNode +} + +external interface TupleTypeNode : TypeNode { + val elements: NodeArray +} + +external interface NamedTupleMember : TypeNode, JSDocContainer, Declaration { + val dotDotDotToken: Token? + get() = definedExternally + val name: Identifier + val questionToken: Token? + get() = definedExternally + val type: TypeNode +} + +external interface OptionalTypeNode : TypeNode { + val type: TypeNode +} + +external interface RestTypeNode : TypeNode { + val type: TypeNode +} + +external interface UnionTypeNode : TypeNode { + val types: NodeArray +} + +external interface IntersectionTypeNode : TypeNode { + val types: NodeArray +} + +external interface ConditionalTypeNode : TypeNode { + val checkType: TypeNode + val extendsType: TypeNode + val trueType: TypeNode + val falseType: TypeNode +} + +external interface InferTypeNode : TypeNode { + val typeParameter: TypeParameterDeclaration +} + +external interface ParenthesizedTypeNode : TypeNode { + val type: TypeNode +} + +external interface TypeOperatorNode : TypeNode { + val operator: dynamic /* SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword */ + get() = definedExternally + val type: TypeNode +} + +external interface IndexedAccessTypeNode : TypeNode { + val objectType: TypeNode + val indexType: TypeNode +} + +external interface MappedTypeNode : TypeNode, Declaration { + val readonlyToken: dynamic /* ReadonlyToken? | PlusToken? | MinusToken? */ + get() = definedExternally + val typeParameter: TypeParameterDeclaration + val nameType: TypeNode? + get() = definedExternally + val questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */ + get() = definedExternally + val type: TypeNode? + get() = definedExternally +} + +external interface LiteralTypeNode : TypeNode { + val literal: dynamic /* NullLiteral | TrueLiteral | FalseLiteral | LiteralExpression | PrefixUnaryExpression */ + get() = definedExternally +} + +external interface StringLiteral : LiteralExpression, Declaration + +external interface TemplateLiteralTypeNode : TypeNode { + val head: TemplateHead + val templateSpans: NodeArray +} + +external interface TemplateLiteralTypeSpan : TypeNode { + override val parent: TemplateLiteralTypeNode + val type: TypeNode + val literal: dynamic /* TemplateMiddle | TemplateTail */ + get() = definedExternally +} + +external interface Expression : Node { + var _expressionBrand: Any +} + +external interface OmittedExpression : Expression + +external interface PartiallyEmittedExpression : LeftHandSideExpression { + val expression: Expression +} + +external interface UnaryExpression : Expression { + var _unaryExpressionBrand: Any +} + +external interface UpdateExpression : UnaryExpression { + var _updateExpressionBrand: Any +} + +external interface PrefixUnaryExpression : UpdateExpression { + val operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken | SyntaxKind.ExclamationToken */ + get() = definedExternally + val operand: UnaryExpression +} + +external interface PostfixUnaryExpression : UpdateExpression { + val operand: LeftHandSideExpression + val operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken */ + get() = definedExternally +} + +external interface LeftHandSideExpression : UpdateExpression { + var _leftHandSideExpressionBrand: Any +} + +external interface MemberExpression : LeftHandSideExpression { + var _memberExpressionBrand: Any +} + +external interface PrimaryExpression : MemberExpression { + var _primaryExpressionBrand: Any +} + +external interface NullLiteral : PrimaryExpression + +external interface TrueLiteral : PrimaryExpression + +external interface FalseLiteral : PrimaryExpression + +external interface ThisExpression : PrimaryExpression + +external interface SuperExpression : PrimaryExpression + +external interface ImportExpression : PrimaryExpression + +external interface DeleteExpression : UnaryExpression { + val expression: UnaryExpression +} + +external interface TypeOfExpression : UnaryExpression { + val expression: UnaryExpression +} + +external interface VoidExpression : UnaryExpression { + val expression: UnaryExpression +} + +external interface AwaitExpression : UnaryExpression { + val expression: UnaryExpression +} + +external interface YieldExpression : Expression { + val asteriskToken: AsteriskToken? + get() = definedExternally + val expression: Expression? + get() = definedExternally +} + +external interface SyntheticExpression : Expression { + val isSpread: Boolean + val type: Type + val tupleNameSource: dynamic /* ParameterDeclaration? | NamedTupleMember? */ + get() = definedExternally +} + +external interface BinaryExpression : Expression, Declaration { + val left: Expression + val operatorToken: BinaryOperatorToken + val right: Expression +} + +external interface AssignmentExpression : BinaryExpression { + override val left: LeftHandSideExpression + override val operatorToken: TOperator +} + +external interface ObjectDestructuringAssignment : AssignmentExpression { + override val left: ObjectLiteralExpression +} + +external interface ArrayDestructuringAssignment : AssignmentExpression { + override val left: ArrayLiteralExpression +} + +external interface ConditionalExpression : Expression { + val condition: Expression + val questionToken: QuestionToken + val whenTrue: Expression + val colonToken: ColonToken + val whenFalse: Expression +} + +external interface FunctionExpression : PrimaryExpression, FunctionLikeDeclarationBase, JSDocContainer { + override val kind: Any + override val name: Identifier? + get() = definedExternally + override val body: FunctionBody +} + +external interface ArrowFunction : Expression, FunctionLikeDeclarationBase, JSDocContainer { + override val kind: Any + val equalsGreaterThanToken: EqualsGreaterThanToken + override val body: dynamic /* FunctionBody | Expression */ + get() = definedExternally + override val name: Any +} + +external interface LiteralLikeNode : Node { + var text: String + var isUnterminated: Boolean? + get() = definedExternally + set(value) = definedExternally + var hasExtendedUnicodeEscape: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TemplateLiteralLikeNode : LiteralLikeNode { + var rawText: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface LiteralExpression : LiteralLikeNode, PrimaryExpression { + var _literalExpressionBrand: Any +} + +external interface RegularExpressionLiteral : LiteralExpression + +external interface NoSubstitutionTemplateLiteral : LiteralExpression, TemplateLiteralLikeNode, Declaration + +external enum class TokenFlags { + None /* = 0 */, + Scientific /* = 16 */, + Octal /* = 32 */, + HexSpecifier /* = 64 */, + BinarySpecifier /* = 128 */, + OctalSpecifier /* = 256 */ +} + +external interface NumericLiteral : LiteralExpression, Declaration + +external interface BigIntLiteral : LiteralExpression + +external interface TemplateHead : TemplateLiteralLikeNode { + override val parent: dynamic /* TemplateExpression | TemplateLiteralTypeNode */ + get() = definedExternally +} + +external interface TemplateMiddle : TemplateLiteralLikeNode { + override val parent: dynamic /* TemplateSpan | TemplateLiteralTypeSpan */ + get() = definedExternally +} + +external interface TemplateTail : TemplateLiteralLikeNode { + override val parent: dynamic /* TemplateSpan | TemplateLiteralTypeSpan */ + get() = definedExternally +} + +external interface TemplateExpression : PrimaryExpression { + val head: TemplateHead + val templateSpans: NodeArray +} + +external interface TemplateSpan : Node { + override val parent: TemplateExpression + val expression: Expression + val literal: dynamic /* TemplateMiddle | TemplateTail */ + get() = definedExternally +} + +external interface ParenthesizedExpression : PrimaryExpression, JSDocContainer { + val expression: Expression +} + +external interface ArrayLiteralExpression : PrimaryExpression { + val elements: NodeArray +} + +external interface SpreadElement : Expression { + override val parent: dynamic /* ArrayLiteralExpression | CallExpression | NewExpression */ + get() = definedExternally + val expression: Expression +} + +external interface ObjectLiteralExpressionBase : PrimaryExpression, Declaration { + val properties: NodeArray +} + +external interface ObjectLiteralExpression : ObjectLiteralExpressionBase + +external interface PropertyAccessExpression : MemberExpression, NamedDeclaration { + val expression: LeftHandSideExpression + val questionDotToken: QuestionDotToken? + get() = definedExternally + override val name: dynamic /* Identifier | PrivateIdentifier */ + get() = definedExternally +} + +external interface PropertyAccessChain : PropertyAccessExpression { + var _optionalChainBrand: Any + override val name: dynamic /* Identifier | PrivateIdentifier */ + get() = definedExternally +} + +external interface SuperPropertyAccessExpression : PropertyAccessExpression { + override val expression: SuperExpression +} + +external interface PropertyAccessEntityNameExpression : PropertyAccessExpression { + var _propertyAccessExpressionLikeQualifiedNameBrand: Any? + get() = definedExternally + set(value) = definedExternally + override val expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ + get() = definedExternally + override val name: Identifier +} + +external interface ElementAccessExpression : MemberExpression { + val expression: LeftHandSideExpression + val questionDotToken: QuestionDotToken? + get() = definedExternally + val argumentExpression: Expression +} + +external interface ElementAccessChain : ElementAccessExpression { + var _optionalChainBrand: Any +} + +external interface SuperElementAccessExpression : ElementAccessExpression { + override val expression: SuperExpression +} + +external interface CallExpression : LeftHandSideExpression, Declaration { + val expression: LeftHandSideExpression + val questionDotToken: QuestionDotToken? + get() = definedExternally + val typeArguments: NodeArray? + get() = definedExternally + val arguments: NodeArray +} + +external interface CallChain : CallExpression { + var _optionalChainBrand: Any +} + +external interface SuperCall : CallExpression { + override val expression: SuperExpression +} + +external interface ImportCall : CallExpression { + override val expression: ImportExpression +} + +external interface ExpressionWithTypeArguments : NodeWithTypeArguments { + override val parent: dynamic /* HeritageClause | JSDocAugmentsTag | JSDocImplementsTag */ + get() = definedExternally + val expression: LeftHandSideExpression +} + +external interface NewExpression : PrimaryExpression, Declaration { + val expression: LeftHandSideExpression + val typeArguments: NodeArray? + get() = definedExternally + val arguments: NodeArray? + get() = definedExternally +} + +external interface TaggedTemplateExpression : MemberExpression { + val tag: LeftHandSideExpression + val typeArguments: NodeArray? + get() = definedExternally + val template: dynamic /* TemplateExpression | NoSubstitutionTemplateLiteral */ + get() = definedExternally +} + +external interface AsExpression : Expression { + val expression: Expression + val type: TypeNode +} + +external interface TypeAssertion : UnaryExpression { + val type: TypeNode + val expression: UnaryExpression +} + +external interface NonNullExpression : LeftHandSideExpression { + val expression: Expression +} + +external interface NonNullChain : NonNullExpression { + var _optionalChainBrand: Any +} + +external interface MetaProperty : PrimaryExpression { + val keywordToken: dynamic /* SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword */ + get() = definedExternally + val name: Identifier +} + +external interface JsxElement : PrimaryExpression { + val openingElement: JsxOpeningElement + val children: NodeArray + val closingElement: JsxClosingElement +} + +external interface JsxTagNamePropertyAccess : PropertyAccessExpression { + override val expression: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ + get() = definedExternally +} + +external interface JsxAttributes : ObjectLiteralExpressionBase { + override val parent: dynamic /* JsxSelfClosingElement | JsxOpeningElement */ + get() = definedExternally +} + +external interface JsxOpeningElement : Expression { + override val parent: JsxElement + val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ + get() = definedExternally + val typeArguments: NodeArray? + get() = definedExternally + val attributes: JsxAttributes +} + +external interface JsxSelfClosingElement : PrimaryExpression { + val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ + get() = definedExternally + val typeArguments: NodeArray? + get() = definedExternally + val attributes: JsxAttributes +} + +external interface JsxFragment : PrimaryExpression { + val openingFragment: JsxOpeningFragment + val children: NodeArray + val closingFragment: JsxClosingFragment +} + +external interface JsxOpeningFragment : Expression { + override val parent: JsxFragment +} + +external interface JsxClosingFragment : Expression { + override val parent: JsxFragment +} + +external interface JsxAttribute : ObjectLiteralElement { + override val parent: JsxAttributes + override val name: Identifier + val initializer: dynamic /* StringLiteral? | JsxExpression? */ + get() = definedExternally +} + +external interface JsxSpreadAttribute : ObjectLiteralElement { + override val parent: JsxAttributes + val expression: Expression +} + +external interface JsxClosingElement : Node { + override val parent: JsxElement + val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ + get() = definedExternally +} + +external interface JsxExpression : Expression { + override val parent: dynamic /* JsxElement | JsxAttribute | JsxSpreadAttribute */ + get() = definedExternally + val dotDotDotToken: Token? + get() = definedExternally + val expression: Expression? + get() = definedExternally +} + +external interface JsxText : LiteralLikeNode { + override val parent: JsxElement + val containsOnlyTriviaWhiteSpaces: Boolean +} + +external interface Statement : Node, JSDocContainer { + var _statementBrand: Any +} + +external interface NotEmittedStatement : Statement + +external interface CommaListExpression : Expression { + val elements: NodeArray +} + +external interface EmptyStatement : Statement + +external interface DebuggerStatement : Statement + +external interface MissingDeclaration : DeclarationStatement { + override val name: Identifier? + get() = definedExternally +} + +external interface Block : Statement { + val statements: NodeArray +} + +external interface VariableStatement : Statement { + val declarationList: VariableDeclarationList +} + +external interface ExpressionStatement : Statement { + val expression: Expression +} + +external interface IfStatement : Statement { + val expression: Expression + val thenStatement: Statement + val elseStatement: Statement? + get() = definedExternally +} + +external interface IterationStatement : Statement { + val statement: Statement +} + +external interface DoStatement : IterationStatement { + val expression: Expression +} + +external interface WhileStatement : IterationStatement { + val expression: Expression +} + +external interface ForStatement : IterationStatement { + val initializer: dynamic /* VariableDeclarationList? | Expression? */ + get() = definedExternally + val condition: Expression? + get() = definedExternally + val incrementor: Expression? + get() = definedExternally +} + +external interface ForInStatement : IterationStatement { + val initializer: dynamic /* VariableDeclarationList | Expression */ + get() = definedExternally + val expression: Expression +} + +external interface ForOfStatement : IterationStatement { + val awaitModifier: AwaitKeywordToken? + get() = definedExternally + val initializer: dynamic /* VariableDeclarationList | Expression */ + get() = definedExternally + val expression: Expression +} + +external interface BreakStatement : Statement { + val label: Identifier? + get() = definedExternally +} + +external interface ContinueStatement : Statement { + val label: Identifier? + get() = definedExternally +} + +external interface ReturnStatement : Statement { + val expression: Expression? + get() = definedExternally +} + +external interface WithStatement : Statement { + val expression: Expression + val statement: Statement +} + +external interface SwitchStatement : Statement { + val expression: Expression + val caseBlock: CaseBlock + var possiblyExhaustive: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface CaseBlock : Node { + override val parent: SwitchStatement + val clauses: NodeArray +} + +external interface CaseClause : Node { + override val parent: CaseBlock + val expression: Expression + val statements: NodeArray +} + +external interface DefaultClause : Node { + override val parent: CaseBlock + val statements: NodeArray +} + +external interface LabeledStatement : Statement { + val label: Identifier + val statement: Statement +} + +external interface ThrowStatement : Statement { + val expression: Expression +} + +external interface TryStatement : Statement { + val tryBlock: Block + val catchClause: CatchClause? + get() = definedExternally + val finallyBlock: Block? + get() = definedExternally +} + +external interface CatchClause : Node { + override val parent: TryStatement + val variableDeclaration: VariableDeclaration? + get() = definedExternally + val block: Block +} + +external interface ClassLikeDeclarationBase : NamedDeclaration, JSDocContainer { + override val kind: dynamic /* SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression */ + get() = definedExternally + override val name: Identifier? + get() = definedExternally + val typeParameters: NodeArray? + get() = definedExternally + val heritageClauses: NodeArray? + get() = definedExternally + val members: NodeArray +} + +external interface ClassDeclaration : ClassLikeDeclarationBase, DeclarationStatement { + override val kind: Any + override val name: Identifier? + get() = definedExternally +} + +external interface ClassExpression : ClassLikeDeclarationBase, PrimaryExpression { + override val kind: Any +} + +external interface ClassElement : NamedDeclaration { + var _classElementBrand: Any + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally +} + +external interface TypeElement : NamedDeclaration { + var _typeElementBrand: Any + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + val questionToken: QuestionToken? + get() = definedExternally +} + +external interface InterfaceDeclaration : DeclarationStatement, JSDocContainer { + override val name: Identifier + val typeParameters: NodeArray? + get() = definedExternally + val heritageClauses: NodeArray? + get() = definedExternally + val members: NodeArray +} + +external interface HeritageClause : Node { + override val parent: dynamic /* InterfaceDeclaration | ClassDeclaration | ClassExpression */ + get() = definedExternally + val token: dynamic /* SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword */ + get() = definedExternally + val types: NodeArray +} + +external interface TypeAliasDeclaration : DeclarationStatement, JSDocContainer { + override val name: Identifier + val typeParameters: NodeArray? + get() = definedExternally + val type: TypeNode +} + +external interface EnumMember : NamedDeclaration, JSDocContainer { + override val parent: EnumDeclaration + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + val initializer: Expression? + get() = definedExternally +} + +external interface EnumDeclaration : DeclarationStatement, JSDocContainer { + override val name: Identifier + val members: NodeArray +} + +external interface ModuleDeclaration : DeclarationStatement, JSDocContainer { + override val parent: dynamic /* ModuleBlock | NamespaceDeclaration | Identifier | JSDocNamespaceDeclaration | SourceFile */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral */ + get() = definedExternally + val body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */ + get() = definedExternally +} + +external interface NamespaceDeclaration : ModuleDeclaration { + override val name: Identifier + override val body: dynamic /* ModuleBlock | NamespaceDeclaration */ + get() = definedExternally +} + +external interface JSDocNamespaceDeclaration : ModuleDeclaration { + override val name: Identifier + override val body: dynamic /* Identifier? | JSDocNamespaceDeclaration? */ + get() = definedExternally +} + +external interface ModuleBlock : Node, Statement { + override val parent: ModuleDeclaration + val statements: NodeArray +} + +external interface ImportEqualsDeclaration : DeclarationStatement, JSDocContainer { + override val parent: dynamic /* SourceFile | ModuleBlock */ + get() = definedExternally + override val name: Identifier + val isTypeOnly: Boolean + val moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */ + get() = definedExternally +} + +external interface ExternalModuleReference : Node { + override val parent: ImportEqualsDeclaration + val expression: Expression +} + +external interface ImportDeclaration : Statement { + override val parent: dynamic /* SourceFile | ModuleBlock */ + get() = definedExternally + val importClause: ImportClause? + get() = definedExternally + val moduleSpecifier: Expression +} + +external interface ImportClause : NamedDeclaration { + override val parent: ImportDeclaration + val isTypeOnly: Boolean + override val name: Identifier? + get() = definedExternally + val namedBindings: dynamic /* NamespaceImport? | NamedImports? */ + get() = definedExternally +} + +external interface NamespaceImport : NamedDeclaration { + override val parent: ImportClause + override val name: Identifier +} + +external interface NamespaceExport : NamedDeclaration { + override val parent: ExportDeclaration + override val name: Identifier +} + +external interface NamespaceExportDeclaration : DeclarationStatement, JSDocContainer { + override val name: Identifier +} + +external interface ExportDeclaration : DeclarationStatement, JSDocContainer { + override val parent: dynamic /* SourceFile | ModuleBlock */ + get() = definedExternally + val isTypeOnly: Boolean + val exportClause: dynamic /* NamespaceExport? | NamedExports? */ + get() = definedExternally + val moduleSpecifier: Expression? + get() = definedExternally +} + +external interface NamedImports : Node { + override val parent: ImportClause + val elements: NodeArray +} + +external interface NamedExports : Node { + override val parent: ExportDeclaration + val elements: NodeArray +} + +external interface ImportSpecifier : NamedDeclaration { + override val parent: NamedImports + val propertyName: Identifier? + get() = definedExternally + override val name: Identifier +} + +external interface ExportSpecifier : NamedDeclaration { + override val parent: NamedExports + val propertyName: Identifier? + get() = definedExternally + override val name: Identifier +} + +external interface ExportAssignment : DeclarationStatement, JSDocContainer { + override val parent: SourceFile + val isExportEquals: Boolean? + get() = definedExternally + val expression: Expression +} + +external interface FileReference : TextRange { + var fileName: String +} + +external interface CheckJsDirective : TextRange { + var enabled: Boolean +} + +external interface CommentRange : TextRange { + var hasTrailingNewLine: Boolean? + get() = definedExternally + set(value) = definedExternally + var kind: dynamic /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */ + get() = definedExternally + set(value) = definedExternally +} + +external interface SynthesizedComment : CommentRange { + var text: String + var hasLeadingNewline: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface JSDocTypeExpression : TypeNode { + val type: TypeNode +} + +external interface JSDocNameReference : Node { + val name: dynamic /* Identifier | QualifiedName | JSDocMemberName */ + get() = definedExternally +} + +external interface JSDocMemberName : Node { + val left: dynamic /* Identifier | QualifiedName | JSDocMemberName */ + get() = definedExternally + val right: Identifier +} + +external interface JSDocType : TypeNode { + var _jsDocTypeBrand: Any +} + +external interface JSDocAllType : JSDocType + +external interface JSDocUnknownType : JSDocType + +external interface JSDocNonNullableType : JSDocType { + val type: TypeNode +} + +external interface JSDocNullableType : JSDocType { + val type: TypeNode +} + +external interface JSDocOptionalType : JSDocType { + val type: TypeNode +} + +external interface JSDocFunctionType : JSDocType, SignatureDeclarationBase { + override val kind: Any +} + +external interface JSDocVariadicType : JSDocType { + val type: TypeNode +} + +external interface JSDocNamepathType : JSDocType { + val type: TypeNode +} + +external interface JSDoc : Node { + override val parent: dynamic /* ParameterDeclaration | CallSignatureDeclaration | ClassStaticBlockDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | EmptyStatement | DebuggerStatement | Block | VariableStatement | ExpressionStatement | IfStatement | DoStatement | WhileStatement | ForStatement | ForInStatement | ForOfStatement | BreakStatement | ContinueStatement | ReturnStatement | WithStatement | SwitchStatement | LabeledStatement | ThrowStatement | TryStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | VariableDeclaration | PropertyDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | NamespaceExportDeclaration | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | Token & JSDocContainer */ + get() = definedExternally + val tags: NodeArray? + get() = definedExternally + val comment: dynamic /* String? | NodeArray? */ + get() = definedExternally +} + +external interface JSDocTag : Node { + override val parent: dynamic /* JSDoc | JSDocTypeLiteral */ + get() = definedExternally + val tagName: Identifier + val comment: dynamic /* String? | NodeArray? */ + get() = definedExternally +} + +external interface JSDocLink : Node { + val name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ + get() = definedExternally + var text: String +} + +external interface JSDocLinkCode : Node { + val name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ + get() = definedExternally + var text: String +} + +external interface JSDocLinkPlain : Node { + val name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ + get() = definedExternally + var text: String +} + +external interface JSDocText : Node { + var text: String +} + +external interface JSDocUnknownTag : JSDocTag + +external interface `T$21` { + val expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ + get() = definedExternally +} + +external interface JSDocAugmentsTag : JSDocTag { + val `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */ +} + +external interface JSDocImplementsTag : JSDocTag { + val `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */ +} + +external interface JSDocAuthorTag : JSDocTag + +external interface JSDocDeprecatedTag : JSDocTag + +external interface JSDocClassTag : JSDocTag + +external interface JSDocPublicTag : JSDocTag + +external interface JSDocPrivateTag : JSDocTag + +external interface JSDocProtectedTag : JSDocTag + +external interface JSDocReadonlyTag : JSDocTag + +external interface JSDocOverrideTag : JSDocTag + +external interface JSDocEnumTag : JSDocTag, Declaration { + override val parent: JSDoc + val typeExpression: JSDocTypeExpression +} + +external interface JSDocThisTag : JSDocTag { + val typeExpression: JSDocTypeExpression +} + +external interface JSDocTemplateTag : JSDocTag { + val constraint: JSDocTypeExpression? + val typeParameters: NodeArray +} + +external interface JSDocSeeTag : JSDocTag { + val name: JSDocNameReference? + get() = definedExternally +} + +external interface JSDocReturnTag : JSDocTag { + val typeExpression: JSDocTypeExpression? + get() = definedExternally +} + +external interface JSDocTypeTag : JSDocTag { + val typeExpression: JSDocTypeExpression +} + +external interface JSDocTypedefTag : JSDocTag, NamedDeclaration { + override val parent: JSDoc + val fullName: dynamic /* JSDocNamespaceDeclaration? | Identifier? */ + get() = definedExternally + override val name: Identifier? + get() = definedExternally + val typeExpression: dynamic /* JSDocTypeExpression? | JSDocTypeLiteral? */ + get() = definedExternally +} + +external interface JSDocCallbackTag : JSDocTag, NamedDeclaration { + override val parent: JSDoc + val fullName: dynamic /* JSDocNamespaceDeclaration? | Identifier? */ + get() = definedExternally + override val name: Identifier? + get() = definedExternally + val typeExpression: JSDocSignature +} + +external interface JSDocSignature : JSDocType, Declaration { + val typeParameters: Array? + get() = definedExternally + val parameters: Array + val type: JSDocReturnTag? +} + +external interface JSDocPropertyLikeTag : JSDocTag, Declaration { + override val parent: JSDoc + val name: dynamic /* Identifier | QualifiedName */ + get() = definedExternally + val typeExpression: JSDocTypeExpression? + get() = definedExternally + val isNameFirst: Boolean + val isBracketed: Boolean +} + +external interface JSDocPropertyTag : JSDocPropertyLikeTag + +external interface JSDocParameterTag : JSDocPropertyLikeTag + +external interface JSDocTypeLiteral : JSDocType { + val jsDocPropertyTags: Array? + get() = definedExternally + val isArrayType: Boolean +} + +external enum class FlowFlags { + Unreachable /* = 1 */, + Start /* = 2 */, + BranchLabel /* = 4 */, + LoopLabel /* = 8 */, + Assignment /* = 16 */, + TrueCondition /* = 32 */, + FalseCondition /* = 64 */, + SwitchClause /* = 128 */, + ArrayMutation /* = 256 */, + Call /* = 512 */, + ReduceLabel /* = 1024 */, + Referenced /* = 2048 */, + Shared /* = 4096 */, + Label /* = 12 */, + Condition /* = 96 */ +} + +external interface FlowNodeBase { + var flags: FlowFlags + var id: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowStart : FlowNodeBase { + var node: dynamic /* FunctionExpression? | ArrowFunction? | MethodDeclaration? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowLabel : FlowNodeBase { + var antecedents: Array? +} + +external interface FlowAssignment : FlowNodeBase { + var node: dynamic /* Expression | VariableDeclaration | BindingElement */ + get() = definedExternally + set(value) = definedExternally + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowCall : FlowNodeBase { + var node: CallExpression + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowCondition : FlowNodeBase { + var node: Expression + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowSwitchClause : FlowNodeBase { + var switchStatement: SwitchStatement + var clauseStart: Number + var clauseEnd: Number + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowArrayMutation : FlowNodeBase { + var node: dynamic /* CallExpression | BinaryExpression */ + get() = definedExternally + set(value) = definedExternally + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowReduceLabel : FlowNodeBase { + var target: FlowLabel + var antecedents: Array + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface IncompleteType { + var flags: TypeFlags + var type: Type +} + +external interface AmdDependency { + var path: String + var name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface SourceFile : Declaration { + fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter + fun getLineEndOfPosition(pos: Number): Number + fun getLineStarts(): Array + fun getPositionOfLineAndCharacter(line: Number, character: Number): Number + fun update(newText: String, textChangeRange: TextChangeRange): SourceFile + val statements: NodeArray + val endOfFileToken: Token + var fileName: String + var text: String + var amdDependencies: Array + var moduleName: String? + get() = definedExternally + set(value) = definedExternally + var referencedFiles: Array + var typeReferenceDirectives: Array + var libReferenceDirectives: Array + var languageVariant: LanguageVariant + var isDeclarationFile: Boolean + var hasNoDefaultLib: Boolean + var languageVersion: ScriptTarget +} + +external interface Bundle : Node { + val prepends: Array + val sourceFiles: Array +} + +external interface InputFiles : Node { + var javascriptPath: String? + get() = definedExternally + set(value) = definedExternally + var javascriptText: String + var javascriptMapPath: String? + get() = definedExternally + set(value) = definedExternally + var javascriptMapText: String? + get() = definedExternally + set(value) = definedExternally + var declarationPath: String? + get() = definedExternally + set(value) = definedExternally + var declarationText: String + var declarationMapPath: String? + get() = definedExternally + set(value) = definedExternally + var declarationMapText: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface UnparsedSource : Node { + var fileName: String + var text: String + val prologues: Array + var helpers: Array? + var referencedFiles: Array + var typeReferenceDirectives: Array? + var libReferenceDirectives: Array + var hasNoDefaultLib: Boolean? + get() = definedExternally + set(value) = definedExternally + var sourceMapPath: String? + get() = definedExternally + set(value) = definedExternally + var sourceMapText: String? + get() = definedExternally + set(value) = definedExternally + val syntheticReferences: Array? + get() = definedExternally + val texts: Array +} + +external interface UnparsedSection : Node { + override val kind: SyntaxKind + override val parent: UnparsedSource + val data: String? + get() = definedExternally +} + +external interface UnparsedPrologue : UnparsedSection { + override val parent: UnparsedSource +} + +external interface UnparsedPrepend : UnparsedSection { + override val parent: UnparsedSource + val texts: Array +} + +external interface UnparsedTextLike : UnparsedSection { + override val kind: dynamic /* SyntaxKind.UnparsedText | SyntaxKind.UnparsedInternalText */ + get() = definedExternally + override val parent: UnparsedSource +} + +external interface UnparsedSyntheticReference : UnparsedSection { + override val parent: UnparsedSource +} + +external interface JsonSourceFile : SourceFile { + override val statements: NodeArray +} + +external interface TsConfigSourceFile : JsonSourceFile { + var extendedSourceFiles: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface JsonMinusNumericLiteral : PrefixUnaryExpression { + override val kind: Any + override val operator: Any + override val operand: NumericLiteral +} + +external interface JsonObjectExpressionStatement : ExpressionStatement { + override val expression: dynamic /* ObjectLiteralExpression | ArrayLiteralExpression | JsonMinusNumericLiteral | NumericLiteral | StringLiteral | TrueLiteral | FalseLiteral | NullLiteral */ + get() = definedExternally +} + +external interface ScriptReferenceHost { + fun getCompilerOptions(): CompilerOptions + fun getSourceFile(fileName: String): SourceFile? + fun getSourceFileByPath(path: String /* String & `T$3` */): SourceFile? + fun getCurrentDirectory(): String +} + +external interface ParseConfigHost { + var useCaseSensitiveFileNames: Boolean + fun readDirectory(rootDir: String, extensions: Array, excludes: Array?, includes: Array, depth: Number = definedExternally): Array + fun fileExists(path: String): Boolean + fun readFile(path: String): String? + val trace: ((s: String) -> Unit)? +} + +external open class OperationCanceledException + +external interface CancellationToken { + fun isCancellationRequested(): Boolean + fun throwIfCancellationRequested() +} + +external interface Program : ScriptReferenceHost { + override fun getCurrentDirectory(): String + fun getRootFileNames(): Array + fun getSourceFiles(): Array + fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult + fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getDeclarationDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getConfigFileParsingDiagnostics(): Array + fun getTypeChecker(): TypeChecker + fun getNodeCount(): Number + fun getIdentifierCount(): Number + fun getSymbolCount(): Number + fun getTypeCount(): Number + fun getInstantiationCount(): Number + fun getRelationCacheSizes(): `T$6` + fun isSourceFileFromExternalLibrary(file: SourceFile): Boolean + fun isSourceFileDefaultLibrary(file: SourceFile): Boolean + fun getProjectReferences(): Array? + fun getResolvedProjectReferences(): Array? +} + +external interface ResolvedProjectReference { + var commandLine: ParsedCommandLine + var sourceFile: SourceFile + var references: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface CustomTransformer { + fun transformSourceFile(node: SourceFile): SourceFile + fun transformBundle(node: Bundle): Bundle +} + +external interface CustomTransformers { + var before: Array | CustomTransformerFactory */>? + get() = definedExternally + set(value) = definedExternally + var after: Array | CustomTransformerFactory */>? + get() = definedExternally + set(value) = definedExternally + var afterDeclarations: Array | CustomTransformerFactory */>? + get() = definedExternally + set(value) = definedExternally +} + +external interface SourceMapSpan { + var emittedLine: Number + var emittedColumn: Number + var sourceLine: Number + var sourceColumn: Number + var nameIndex: Number? + get() = definedExternally + set(value) = definedExternally + var sourceIndex: Number +} + +external enum class ExitStatus { + Success /* = 0 */, + DiagnosticsPresent_OutputsSkipped /* = 1 */, + DiagnosticsPresent_OutputsGenerated /* = 2 */, + InvalidProject_OutputsSkipped /* = 3 */, + ProjectReferenceCycle_OutputsSkipped /* = 4 */, + ProjectReferenceCycle_OutputsSkupped /* = 4 */ +} + +external interface EmitResult { + var emitSkipped: Boolean + var diagnostics: Array + var emittedFiles: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$22` { + var typeArguments: NodeArray? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeChecker { + fun getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type + fun getDeclaredTypeOfSymbol(symbol: Symbol): Type + fun getPropertiesOfType(type: Type): Array + fun getPropertyOfType(type: Type, propertyName: String): Symbol? + fun getPrivateIdentifierPropertyOfType(leftType: Type, name: String, location: Node): Symbol? + fun getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo? + fun getIndexInfosOfType(type: Type): Array + fun getSignaturesOfType(type: Type, kind: SignatureKind): Array + fun getIndexTypeOfType(type: Type, kind: IndexKind): Type? + fun getBaseTypes(type: InterfaceType): Array + fun getBaseTypeOfLiteralType(type: Type): Type + fun getWidenedType(type: Type): Type + fun getReturnTypeOfSignature(signature: Signature): Type + fun getNullableType(type: Type, flags: TypeFlags): Type + fun getNonNullableType(type: Type): Type + fun getTypeArguments(type: TypeReference): Array + fun typeToTypeNode(type: Type, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeNode? + fun signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ + fun indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): IndexSignatureDeclaration? + fun symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* Identifier? | QualifiedName? */ + fun symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): Expression? + fun symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): NodeArray? + fun symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): ParameterDeclaration? + fun typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeParameterDeclaration? + fun getSymbolsInScope(location: Node, meaning: SymbolFlags): Array + fun getSymbolAtLocation(node: Node): Symbol? + fun getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: String): Array + fun getShorthandAssignmentValueSymbol(location: Node?): Symbol? + fun getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol? + fun getExportSpecifierLocalTargetSymbol(location: Identifier): Symbol? + fun getExportSymbolOfSymbol(symbol: Symbol): Symbol + fun getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol? + fun getTypeOfAssignmentPattern(pattern: ObjectLiteralExpression): Type + fun getTypeOfAssignmentPattern(pattern: ArrayLiteralExpression): Type + fun getTypeAtLocation(node: Node): Type + fun getTypeFromTypeNode(node: TypeNode): Type + fun signatureToString(signature: Signature, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally, kind: SignatureKind = definedExternally): String + fun typeToString(type: Type, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun symbolToString(symbol: Symbol, enclosingDeclaration: Node = definedExternally, meaning: SymbolFlags = definedExternally, flags: SymbolFormatFlags = definedExternally): String + fun typePredicateToString(predicate: ThisTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun typePredicateToString(predicate: ThisTypePredicate): String + fun typePredicateToString(predicate: ThisTypePredicate, enclosingDeclaration: Node = definedExternally): String + fun typePredicateToString(predicate: IdentifierTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun typePredicateToString(predicate: IdentifierTypePredicate): String + fun typePredicateToString(predicate: IdentifierTypePredicate, enclosingDeclaration: Node = definedExternally): String + fun typePredicateToString(predicate: AssertsThisTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun typePredicateToString(predicate: AssertsThisTypePredicate): String + fun typePredicateToString(predicate: AssertsThisTypePredicate, enclosingDeclaration: Node = definedExternally): String + fun typePredicateToString(predicate: AssertsIdentifierTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun typePredicateToString(predicate: AssertsIdentifierTypePredicate): String + fun typePredicateToString(predicate: AssertsIdentifierTypePredicate, enclosingDeclaration: Node = definedExternally): String + fun getFullyQualifiedName(symbol: Symbol): String + fun getAugmentedPropertiesOfType(type: Type): Array + fun getRootSymbols(symbol: Symbol): Array + fun getSymbolOfExpando(node: Node, allowDeclaration: Boolean): Symbol? + fun getContextualType(node: Expression): Type? + fun getResolvedSignature(node: CallExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: CallExpression): Signature? + fun getResolvedSignature(node: CallExpression, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: NewExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: NewExpression): Signature? + fun getResolvedSignature(node: NewExpression, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: TaggedTemplateExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: TaggedTemplateExpression): Signature? + fun getResolvedSignature(node: TaggedTemplateExpression, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: Decorator, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: Decorator): Signature? + fun getResolvedSignature(node: Decorator, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: JsxSelfClosingElement, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: JsxSelfClosingElement): Signature? + fun getResolvedSignature(node: JsxSelfClosingElement, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: JsxOpeningElement, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: JsxOpeningElement): Signature? + fun getResolvedSignature(node: JsxOpeningElement, candidatesOutArray: Array = definedExternally): Signature? + fun getSignatureFromDeclaration(declaration: CallSignatureDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: ConstructSignatureDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: MethodSignature): Signature? + fun getSignatureFromDeclaration(declaration: IndexSignatureDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: FunctionTypeNode): Signature? + fun getSignatureFromDeclaration(declaration: ConstructorTypeNode): Signature? + fun getSignatureFromDeclaration(declaration: JSDocFunctionType): Signature? + fun getSignatureFromDeclaration(declaration: FunctionDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: MethodDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: ConstructorDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: GetAccessorDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: SetAccessorDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: FunctionExpression): Signature? + fun getSignatureFromDeclaration(declaration: ArrowFunction): Signature? + fun isImplementationOfOverload(node: CallSignatureDeclaration): Boolean? + fun isImplementationOfOverload(node: ConstructSignatureDeclaration): Boolean? + fun isImplementationOfOverload(node: MethodSignature): Boolean? + fun isImplementationOfOverload(node: IndexSignatureDeclaration): Boolean? + fun isImplementationOfOverload(node: FunctionTypeNode): Boolean? + fun isImplementationOfOverload(node: ConstructorTypeNode): Boolean? + fun isImplementationOfOverload(node: JSDocFunctionType): Boolean? + fun isImplementationOfOverload(node: FunctionDeclaration): Boolean? + fun isImplementationOfOverload(node: MethodDeclaration): Boolean? + fun isImplementationOfOverload(node: ConstructorDeclaration): Boolean? + fun isImplementationOfOverload(node: GetAccessorDeclaration): Boolean? + fun isImplementationOfOverload(node: SetAccessorDeclaration): Boolean? + fun isImplementationOfOverload(node: FunctionExpression): Boolean? + fun isImplementationOfOverload(node: ArrowFunction): Boolean? + fun isUndefinedSymbol(symbol: Symbol): Boolean + fun isArgumentsSymbol(symbol: Symbol): Boolean + fun isUnknownSymbol(symbol: Symbol): Boolean + fun getConstantValue(node: EnumMember): dynamic /* String? | Number? */ + fun getConstantValue(node: PropertyAccessExpression): dynamic /* String? | Number? */ + fun getConstantValue(node: ElementAccessExpression): dynamic /* String? | Number? */ + fun isValidPropertyAccess(node: PropertyAccessExpression, propertyName: String): Boolean + fun isValidPropertyAccess(node: QualifiedName, propertyName: String): Boolean + fun isValidPropertyAccess(node: ImportTypeNode, propertyName: String): Boolean + fun getAliasedSymbol(symbol: Symbol): Symbol + fun getImmediateAliasedSymbol(symbol: Symbol): Symbol? + fun getExportsOfModule(moduleSymbol: Symbol): Array + fun getJsxIntrinsicTagNamesAt(location: Node): Array + fun isOptionalParameter(node: ParameterDeclaration): Boolean + fun getAmbientModules(): Array + fun tryGetMemberInModuleExports(memberName: String, moduleSymbol: Symbol): Symbol? + fun getApparentType(type: Type): Type + fun getBaseConstraintOfType(type: Type): Type? + fun getDefaultFromTypeParameter(type: Type): Type? + fun runWithCancellationToken(token: CancellationToken, cb: (checker: TypeChecker) -> T): T +} + +external enum class NodeBuilderFlags { + None /* = 0 */, + NoTruncation /* = 1 */, + WriteArrayAsGenericType /* = 2 */, + GenerateNamesForShadowedTypeParams /* = 4 */, + UseStructuralFallback /* = 8 */, + ForbidIndexedAccessSymbolReferences /* = 16 */, + WriteTypeArgumentsOfSignature /* = 32 */, + UseFullyQualifiedType /* = 64 */, + UseOnlyExternalAliasing /* = 128 */, + SuppressAnyReturnType /* = 256 */, + WriteTypeParametersInQualifiedName /* = 512 */, + MultilineObjectLiterals /* = 1024 */, + WriteClassExpressionAsTypeLiteral /* = 2048 */, + UseTypeOfFunction /* = 4096 */, + OmitParameterModifiers /* = 8192 */, + UseAliasDefinedOutsideCurrentScope /* = 16384 */, + UseSingleQuotesForStringLiteralType /* = 268435456 */, + NoTypeReduction /* = 536870912 */, + NoUndefinedOptionalParameterType /* = 1073741824 */, + AllowThisInObjectLiteral /* = 32768 */, + AllowQualifiedNameInPlaceOfIdentifier /* = 65536 */, + AllowQualifedNameInPlaceOfIdentifier /* = 65536 */, + AllowAnonymousIdentifier /* = 131072 */, + AllowEmptyUnionOrIntersection /* = 262144 */, + AllowEmptyTuple /* = 524288 */, + AllowUniqueESSymbolType /* = 1048576 */, + AllowEmptyIndexInfoType /* = 2097152 */, + AllowNodeModulesRelativePaths /* = 67108864 */, + IgnoreErrors /* = 70221824 */, + InObjectTypeLiteral /* = 4194304 */, + InTypeAlias /* = 8388608 */, + InInitialEntityName /* = 16777216 */ +} + +external enum class TypeFormatFlags { + None /* = 0 */, + NoTruncation /* = 1 */, + WriteArrayAsGenericType /* = 2 */, + UseStructuralFallback /* = 8 */, + WriteTypeArgumentsOfSignature /* = 32 */, + UseFullyQualifiedType /* = 64 */, + SuppressAnyReturnType /* = 256 */, + MultilineObjectLiterals /* = 1024 */, + WriteClassExpressionAsTypeLiteral /* = 2048 */, + UseTypeOfFunction /* = 4096 */, + OmitParameterModifiers /* = 8192 */, + UseAliasDefinedOutsideCurrentScope /* = 16384 */, + UseSingleQuotesForStringLiteralType /* = 268435456 */, + NoTypeReduction /* = 536870912 */, + AllowUniqueESSymbolType /* = 1048576 */, + AddUndefined /* = 131072 */, + WriteArrowStyleSignature /* = 262144 */, + InArrayType /* = 524288 */, + InElementType /* = 2097152 */, + InFirstTypeArgument /* = 4194304 */, + InTypeAlias /* = 8388608 */, + WriteOwnNameForAnyLike /* = 0 */, + NodeBuilderFlagsMask /* = 814775659 */ +} + +external enum class SymbolFormatFlags { + None /* = 0 */, + WriteTypeParametersOrArguments /* = 1 */, + UseOnlyExternalAliasing /* = 2 */, + AllowAnyNodeKind /* = 4 */, + UseAliasDefinedOutsideCurrentScope /* = 8 */ +} + +external enum class TypePredicateKind { + This /* = 0 */, + Identifier /* = 1 */, + AssertsThis /* = 2 */, + AssertsIdentifier /* = 3 */ +} + +external interface TypePredicateBase { + var kind: TypePredicateKind + var type: Type? +} + +external interface ThisTypePredicate : TypePredicateBase { + var parameterName: Any? + var parameterIndex: Any? +} + +external interface IdentifierTypePredicate : TypePredicateBase { + var parameterName: String + var parameterIndex: Number +} + +external interface AssertsThisTypePredicate : TypePredicateBase { + var parameterName: Any? + var parameterIndex: Any? + override var type: Type? +} + +external interface AssertsIdentifierTypePredicate : TypePredicateBase { + var parameterName: String + var parameterIndex: Number + override var type: Type? +} + +external enum class SymbolFlags { + None /* = 0 */, + FunctionScopedVariable /* = 1 */, + BlockScopedVariable /* = 2 */, + Property /* = 4 */, + EnumMember /* = 8 */, + Function /* = 16 */, + Class /* = 32 */, + Interface /* = 64 */, + ConstEnum /* = 128 */, + RegularEnum /* = 256 */, + ValueModule /* = 512 */, + NamespaceModule /* = 1024 */, + TypeLiteral /* = 2048 */, + ObjectLiteral /* = 4096 */, + Method /* = 8192 */, + Constructor /* = 16384 */, + GetAccessor /* = 32768 */, + SetAccessor /* = 65536 */, + Signature /* = 131072 */, + TypeParameter /* = 262144 */, + TypeAlias /* = 524288 */, + ExportValue /* = 1048576 */, + Alias /* = 2097152 */, + Prototype /* = 4194304 */, + ExportStar /* = 8388608 */, + Optional /* = 16777216 */, + Transient /* = 33554432 */, + Assignment /* = 67108864 */, + ModuleExports /* = 134217728 */, + Enum /* = 384 */, + Variable /* = 3 */, + Value /* = 111551 */, + Type /* = 788968 */, + Namespace /* = 1920 */, + Module /* = 1536 */, + Accessor /* = 98304 */, + FunctionScopedVariableExcludes /* = 111550 */, + BlockScopedVariableExcludes /* = 111551 */, + ParameterExcludes /* = 111551 */, + PropertyExcludes /* = 0 */, + EnumMemberExcludes /* = 900095 */, + FunctionExcludes /* = 110991 */, + ClassExcludes /* = 899503 */, + InterfaceExcludes /* = 788872 */, + RegularEnumExcludes /* = 899327 */, + ConstEnumExcludes /* = 899967 */, + ValueModuleExcludes /* = 110735 */, + NamespaceModuleExcludes /* = 0 */, + MethodExcludes /* = 103359 */, + GetAccessorExcludes /* = 46015 */, + SetAccessorExcludes /* = 78783 */, + TypeParameterExcludes /* = 526824 */, + TypeAliasExcludes /* = 788968 */, + AliasExcludes /* = 2097152 */, + ModuleMember /* = 2623475 */, + ExportHasLocal /* = 944 */, + BlockScoped /* = 418 */, + PropertyOrAccessor /* = 98308 */, + ClassMember /* = 106500 */ +} + +external interface Symbol { + val name: String + fun getFlags(): SymbolFlags + fun getEscapedName(): dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + fun getName(): String + fun getDeclarations(): Array? + fun getDocumentationComment(typeChecker: TypeChecker?): Array + fun getJsDocTags(checker: TypeChecker = definedExternally): Array + var flags: SymbolFlags + var escapedName: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + get() = definedExternally + set(value) = definedExternally + var declarations: Array? + get() = definedExternally + set(value) = definedExternally + var valueDeclaration: Declaration? + get() = definedExternally + set(value) = definedExternally + var members: SymbolTable? + get() = definedExternally + set(value) = definedExternally + var exports: SymbolTable? + get() = definedExternally + set(value) = definedExternally + var globalExports: SymbolTable? + get() = definedExternally + set(value) = definedExternally +} + +external enum class InternalSymbolName { + Call /* = "__call" */, + Constructor /* = "__constructor" */, + New /* = "__new" */, + Index /* = "__index" */, + ExportStar /* = "__export" */, + Global /* = "__global" */, + Missing /* = "__missing" */, + Type /* = "__type" */, + Object /* = "__object" */, + JSXAttributes /* = "__jsxAttributes" */, + Class /* = "__class" */, + Function /* = "__function" */, + Computed /* = "__computed" */, + Resolving /* = "__resolving__" */, + ExportEquals /* = "export=" */, + Default /* = "default" */, + This /* = "this" */ +} + +external interface ReadonlyUnderscoreEscapedMap : ReadonlyESMap + +external interface UnderscoreEscapedMap : ESMap, ReadonlyUnderscoreEscapedMap + +external enum class TypeFlags { + Any /* = 1 */, + Unknown /* = 2 */, + String /* = 4 */, + Number /* = 8 */, + Boolean /* = 16 */, + Enum /* = 32 */, + BigInt /* = 64 */, + StringLiteral /* = 128 */, + NumberLiteral /* = 256 */, + BooleanLiteral /* = 512 */, + EnumLiteral /* = 1024 */, + BigIntLiteral /* = 2048 */, + ESSymbol /* = 4096 */, + UniqueESSymbol /* = 8192 */, + Void /* = 16384 */, + Undefined /* = 32768 */, + Null /* = 65536 */, + Never /* = 131072 */, + TypeParameter /* = 262144 */, + Object /* = 524288 */, + Union /* = 1048576 */, + Intersection /* = 2097152 */, + Index /* = 4194304 */, + IndexedAccess /* = 8388608 */, + Conditional /* = 16777216 */, + Substitution /* = 33554432 */, + NonPrimitive /* = 67108864 */, + TemplateLiteral /* = 134217728 */, + StringMapping /* = 268435456 */, + Literal /* = 2944 */, + Unit /* = 109440 */, + StringOrNumberLiteral /* = 384 */, + PossiblyFalsy /* = 117724 */, + StringLike /* = 402653316 */, + NumberLike /* = 296 */, + BigIntLike /* = 2112 */, + BooleanLike /* = 528 */, + EnumLike /* = 1056 */, + ESSymbolLike /* = 12288 */, + VoidLike /* = 49152 */, + UnionOrIntersection /* = 3145728 */, + StructuredType /* = 3670016 */, + TypeVariable /* = 8650752 */, + InstantiableNonPrimitive /* = 58982400 */, + InstantiablePrimitive /* = 406847488 */, + Instantiable /* = 465829888 */, + StructuredOrInstantiable /* = 469499904 */, + Narrowable /* = 536624127 */ +} + +external interface Type { + fun getFlags(): TypeFlags + fun getSymbol(): Symbol? + fun getProperties(): Array + fun getProperty(propertyName: String): Symbol? + fun getApparentProperties(): Array + fun getCallSignatures(): Array + fun getConstructSignatures(): Array + fun getStringIndexType(): Type? + fun getNumberIndexType(): Type? + fun getBaseTypes(): Array? + fun getNonNullableType(): Type + fun getConstraint(): Type? + fun getDefault(): Type? + fun isUnion(): Boolean + fun isIntersection(): Boolean + fun isUnionOrIntersection(): Boolean + fun isLiteral(): Boolean + fun isStringLiteral(): Boolean + fun isNumberLiteral(): Boolean + fun isTypeParameter(): Boolean + fun isClassOrInterface(): Boolean + fun isClass(): Boolean + var flags: TypeFlags + var symbol: Symbol + var pattern: dynamic /* ObjectBindingPattern? | ArrayBindingPattern? | ObjectLiteralExpression? | ArrayLiteralExpression? */ + get() = definedExternally + set(value) = definedExternally + var aliasSymbol: Symbol? + get() = definedExternally + set(value) = definedExternally + var aliasTypeArguments: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface LiteralType : Type { + var value: dynamic /* String | Number | PseudoBigInt */ + get() = definedExternally + set(value) = definedExternally + var freshType: LiteralType + var regularType: LiteralType +} + +external interface UniqueESSymbolType : Type { + override var symbol: Symbol + var escapedName: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + get() = definedExternally + set(value) = definedExternally +} + +external interface StringLiteralType : LiteralType { + override var value: String +} + +external interface NumberLiteralType : LiteralType { + override var value: Number +} + +external interface BigIntLiteralType : LiteralType { + override var value: PseudoBigInt +} + +external interface EnumType : Type + +external enum class ObjectFlags { + Class /* = 1 */, + Interface /* = 2 */, + Reference /* = 4 */, + Tuple /* = 8 */, + Anonymous /* = 16 */, + Mapped /* = 32 */, + Instantiated /* = 64 */, + ObjectLiteral /* = 128 */, + EvolvingArray /* = 256 */, + ObjectLiteralPatternWithComputedProperties /* = 512 */, + ReverseMapped /* = 1024 */, + JsxAttributes /* = 2048 */, + MarkerType /* = 4096 */, + JSLiteral /* = 8192 */, + FreshLiteral /* = 16384 */, + ArrayLiteral /* = 32768 */, + ClassOrInterface /* = 3 */, + ContainsSpread /* = 4194304 */, + ObjectRestType /* = 8388608 */ +} + +external interface ObjectType : Type { + var objectFlags: ObjectFlags +} + +external interface InterfaceType : ObjectType { + var typeParameters: Array? + var outerTypeParameters: Array? + var localTypeParameters: Array? + var thisType: TypeParameter? +} + +external interface InterfaceTypeWithDeclaredMembers : InterfaceType { + var declaredProperties: Array + var declaredCallSignatures: Array + var declaredConstructSignatures: Array + var declaredIndexInfos: Array +} + +external interface TypeReference : ObjectType { + var typeArguments: Array? + get() = definedExternally + set(value) = definedExternally + var target: GenericType + var node: dynamic /* TypeReferenceNode? | ArrayTypeNode? | TupleTypeNode? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface DeferredTypeReference : TypeReference + +external interface GenericType : InterfaceType, TypeReference + +external enum class ElementFlags { + Required /* = 1 */, + Optional /* = 2 */, + Rest /* = 4 */, + Variadic /* = 8 */, + Fixed /* = 3 */, + Variable /* = 12 */, + NonRequired /* = 14 */, + NonRest /* = 11 */ +} + +external interface TupleType : GenericType { + var elementFlags: Array + var minLength: Number + var fixedLength: Number + var hasRestElement: Boolean + var combinedFlags: ElementFlags + var readonly: Boolean + var labeledElementDeclarations: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface TupleTypeReference : TypeReference { + override var target: TupleType +} + +external interface UnionOrIntersectionType : Type { + var types: Array +} + +external interface UnionType : UnionOrIntersectionType + +external interface IntersectionType : UnionOrIntersectionType + +external interface EvolvingArrayType : ObjectType { + var elementType: Type + var finalArrayType: Type? + get() = definedExternally + set(value) = definedExternally +} + +external interface InstantiableType : Type + +external interface TypeParameter : InstantiableType + +external interface IndexedAccessType : InstantiableType { + var objectType: Type + var indexType: Type + var constraint: Type? + get() = definedExternally + set(value) = definedExternally + var simplifiedForReading: Type? + get() = definedExternally + set(value) = definedExternally + var simplifiedForWriting: Type? + get() = definedExternally + set(value) = definedExternally +} + +external interface IndexType : InstantiableType { + var type: dynamic /* InstantiableType | UnionOrIntersectionType */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ConditionalRoot { + var node: ConditionalTypeNode + var checkType: Type + var extendsType: Type + var isDistributive: Boolean + var inferTypeParameters: Array? + get() = definedExternally + set(value) = definedExternally + var outerTypeParameters: Array? + get() = definedExternally + set(value) = definedExternally + var instantiations: Map? + get() = definedExternally + set(value) = definedExternally + var aliasSymbol: Symbol? + get() = definedExternally + set(value) = definedExternally + var aliasTypeArguments: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface ConditionalType : InstantiableType { + var root: ConditionalRoot + var checkType: Type + var extendsType: Type + var resolvedTrueType: Type + var resolvedFalseType: Type +} + +external interface TemplateLiteralType : InstantiableType { + var texts: Array + var types: Array +} + +external interface StringMappingType : InstantiableType { + override var symbol: Symbol + var type: Type +} + +external interface SubstitutionType : InstantiableType { + var objectFlags: ObjectFlags + var baseType: Type + var substitute: Type +} + +external enum class SignatureKind { + Call /* = 0 */, + Construct /* = 1 */ +} + +external interface Signature { + fun getDeclaration(): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ + fun getTypeParameters(): Array? + fun getParameters(): Array + fun getReturnType(): Type + fun getDocumentationComment(typeChecker: TypeChecker?): Array + fun getJsDocTags(): Array + var declaration: dynamic /* CallSignatureDeclaration? | ConstructSignatureDeclaration? | MethodSignature? | IndexSignatureDeclaration? | FunctionTypeNode? | ConstructorTypeNode? | JSDocFunctionType? | FunctionDeclaration? | MethodDeclaration? | ConstructorDeclaration? | GetAccessorDeclaration? | SetAccessorDeclaration? | FunctionExpression? | ArrowFunction? | JSDocSignature? */ + get() = definedExternally + set(value) = definedExternally + var typeParameters: Array? + get() = definedExternally + set(value) = definedExternally + var parameters: Array +} + +external enum class IndexKind { + String /* = 0 */, + Number /* = 1 */ +} + +external interface IndexInfo { + var keyType: Type + var type: Type + var isReadonly: Boolean + var declaration: IndexSignatureDeclaration? + get() = definedExternally + set(value) = definedExternally +} + +external enum class InferencePriority { + NakedTypeVariable /* = 1 */, + SpeculativeTuple /* = 2 */, + SubstituteSource /* = 4 */, + HomomorphicMappedType /* = 8 */, + PartialHomomorphicMappedType /* = 16 */, + MappedTypeConstraint /* = 32 */, + ContravariantConditional /* = 64 */, + ReturnType /* = 128 */, + LiteralKeyof /* = 256 */, + NoConstraints /* = 512 */, + AlwaysStrict /* = 1024 */, + MaxValue /* = 2048 */, + PriorityImpliesCombination /* = 416 */, + Circularity /* = -1 */ +} + +external interface FileExtensionInfo { + var extension: String + var isMixedContent: Boolean + var scriptKind: ScriptKind? + get() = definedExternally + set(value) = definedExternally +} + +external interface DiagnosticMessage { + var key: String + var category: DiagnosticCategory + var code: Number + var message: String + var reportsUnnecessary: Any? + get() = definedExternally + set(value) = definedExternally + var reportsDeprecated: Any? + get() = definedExternally + set(value) = definedExternally +} + +external interface DiagnosticMessageChain { + var messageText: String + var category: DiagnosticCategory + var code: Number + var next: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface Diagnostic : DiagnosticRelatedInformation { + var reportsUnnecessary: Any? + get() = definedExternally + set(value) = definedExternally + var reportsDeprecated: Any? + get() = definedExternally + set(value) = definedExternally + var source: String? + get() = definedExternally + set(value) = definedExternally + var relatedInformation: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface DiagnosticRelatedInformation { + var category: DiagnosticCategory + var code: Number + var file: SourceFile? + var start: Number? + var length: Number? + var messageText: dynamic /* String | DiagnosticMessageChain */ + get() = definedExternally + set(value) = definedExternally +} + +external interface DiagnosticWithLocation : Diagnostic + +external enum class DiagnosticCategory { + Warning /* = 0 */, + Error /* = 1 */, + Suggestion /* = 2 */, + Message /* = 3 */ +} + +external enum class ModuleResolutionKind { + Classic /* = 1 */, + NodeJs /* = 2 */ +} + +external interface PluginImport { + var name: String +} + +external interface ProjectReference { + var path: String + var originalPath: String? + get() = definedExternally + set(value) = definedExternally + var prepend: Boolean? + get() = definedExternally + set(value) = definedExternally + var circular: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external enum class WatchFileKind { + FixedPollingInterval /* = 0 */, + PriorityPollingInterval /* = 1 */, + DynamicPriorityPolling /* = 2 */, + FixedChunkSizePolling /* = 3 */, + UseFsEvents /* = 4 */, + UseFsEventsOnParentDirectory /* = 5 */ +} + +external enum class WatchDirectoryKind { + UseFsEvents /* = 0 */, + FixedPollingInterval /* = 1 */, + DynamicPriorityPolling /* = 2 */, + FixedChunkSizePolling /* = 3 */ +} + +external enum class PollingWatchKind { + FixedInterval /* = 0 */, + PriorityInterval /* = 1 */, + DynamicPriority /* = 2 */, + FixedChunkSize /* = 3 */ +} + +external interface CompilerOptions { + var allowJs: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowSyntheticDefaultImports: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowUmdGlobalAccess: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowUnreachableCode: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowUnusedLabels: Boolean? + get() = definedExternally + set(value) = definedExternally + var alwaysStrict: Boolean? + get() = definedExternally + set(value) = definedExternally + var baseUrl: String? + get() = definedExternally + set(value) = definedExternally + var charset: String? + get() = definedExternally + set(value) = definedExternally + var checkJs: Boolean? + get() = definedExternally + set(value) = definedExternally + var declaration: Boolean? + get() = definedExternally + set(value) = definedExternally + var declarationMap: Boolean? + get() = definedExternally + set(value) = definedExternally + var emitDeclarationOnly: Boolean? + get() = definedExternally + set(value) = definedExternally + var declarationDir: String? + get() = definedExternally + set(value) = definedExternally + var disableSizeLimit: Boolean? + get() = definedExternally + set(value) = definedExternally + var disableSourceOfProjectReferenceRedirect: Boolean? + get() = definedExternally + set(value) = definedExternally + var disableSolutionSearching: Boolean? + get() = definedExternally + set(value) = definedExternally + var disableReferencedProjectLoad: Boolean? + get() = definedExternally + set(value) = definedExternally + var downlevelIteration: Boolean? + get() = definedExternally + set(value) = definedExternally + var emitBOM: Boolean? + get() = definedExternally + set(value) = definedExternally + var emitDecoratorMetadata: Boolean? + get() = definedExternally + set(value) = definedExternally + var exactOptionalPropertyTypes: Boolean? + get() = definedExternally + set(value) = definedExternally + var experimentalDecorators: Boolean? + get() = definedExternally + set(value) = definedExternally + var forceConsistentCasingInFileNames: Boolean? + get() = definedExternally + set(value) = definedExternally + var importHelpers: Boolean? + get() = definedExternally + set(value) = definedExternally + var importsNotUsedAsValues: ImportsNotUsedAsValues? + get() = definedExternally + set(value) = definedExternally + var inlineSourceMap: Boolean? + get() = definedExternally + set(value) = definedExternally + var inlineSources: Boolean? + get() = definedExternally + set(value) = definedExternally + var isolatedModules: Boolean? + get() = definedExternally + set(value) = definedExternally + var jsx: JsxEmit? + get() = definedExternally + set(value) = definedExternally + var keyofStringsOnly: Boolean? + get() = definedExternally + set(value) = definedExternally + var lib: Array? + get() = definedExternally + set(value) = definedExternally + var locale: String? + get() = definedExternally + set(value) = definedExternally + var mapRoot: String? + get() = definedExternally + set(value) = definedExternally + var maxNodeModuleJsDepth: Number? + get() = definedExternally + set(value) = definedExternally + var module: ModuleKind? + get() = definedExternally + set(value) = definedExternally + var moduleResolution: ModuleResolutionKind? + get() = definedExternally + set(value) = definedExternally + var newLine: NewLineKind? + get() = definedExternally + set(value) = definedExternally + var noEmit: Boolean? + get() = definedExternally + set(value) = definedExternally + var noEmitHelpers: Boolean? + get() = definedExternally + set(value) = definedExternally + var noEmitOnError: Boolean? + get() = definedExternally + set(value) = definedExternally + var noErrorTruncation: Boolean? + get() = definedExternally + set(value) = definedExternally + var noFallthroughCasesInSwitch: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitAny: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitReturns: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitThis: Boolean? + get() = definedExternally + set(value) = definedExternally + var noStrictGenericChecks: Boolean? + get() = definedExternally + set(value) = definedExternally + var noUnusedLocals: Boolean? + get() = definedExternally + set(value) = definedExternally + var noUnusedParameters: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitUseStrict: Boolean? + get() = definedExternally + set(value) = definedExternally + var noPropertyAccessFromIndexSignature: Boolean? + get() = definedExternally + set(value) = definedExternally + var assumeChangesOnlyAffectDirectDependencies: Boolean? + get() = definedExternally + set(value) = definedExternally + var noLib: Boolean? + get() = definedExternally + set(value) = definedExternally + var noResolve: Boolean? + get() = definedExternally + set(value) = definedExternally + var noUncheckedIndexedAccess: Boolean? + get() = definedExternally + set(value) = definedExternally + var out: String? + get() = definedExternally + set(value) = definedExternally + var outDir: String? + get() = definedExternally + set(value) = definedExternally + var outFile: String? + get() = definedExternally + set(value) = definedExternally + var paths: MapLike>? + get() = definedExternally + set(value) = definedExternally + var preserveConstEnums: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitOverride: Boolean? + get() = definedExternally + set(value) = definedExternally + var preserveSymlinks: Boolean? + get() = definedExternally + set(value) = definedExternally + var project: String? + get() = definedExternally + set(value) = definedExternally + var reactNamespace: String? + get() = definedExternally + set(value) = definedExternally + var jsxFactory: String? + get() = definedExternally + set(value) = definedExternally + var jsxFragmentFactory: String? + get() = definedExternally + set(value) = definedExternally + var jsxImportSource: String? + get() = definedExternally + set(value) = definedExternally + var composite: Boolean? + get() = definedExternally + set(value) = definedExternally + var incremental: Boolean? + get() = definedExternally + set(value) = definedExternally + var tsBuildInfoFile: String? + get() = definedExternally + set(value) = definedExternally + var removeComments: Boolean? + get() = definedExternally + set(value) = definedExternally + var rootDir: String? + get() = definedExternally + set(value) = definedExternally + var rootDirs: Array? + get() = definedExternally + set(value) = definedExternally + var skipLibCheck: Boolean? + get() = definedExternally + set(value) = definedExternally + var skipDefaultLibCheck: Boolean? + get() = definedExternally + set(value) = definedExternally + var sourceMap: Boolean? + get() = definedExternally + set(value) = definedExternally + var sourceRoot: String? + get() = definedExternally + set(value) = definedExternally + var strict: Boolean? + get() = definedExternally + set(value) = definedExternally + var strictFunctionTypes: Boolean? + get() = definedExternally + set(value) = definedExternally + var strictBindCallApply: Boolean? + get() = definedExternally + set(value) = definedExternally + var strictNullChecks: Boolean? + get() = definedExternally + set(value) = definedExternally + var strictPropertyInitialization: Boolean? + get() = definedExternally + set(value) = definedExternally + var stripInternal: Boolean? + get() = definedExternally + set(value) = definedExternally + var suppressExcessPropertyErrors: Boolean? + get() = definedExternally + set(value) = definedExternally + var suppressImplicitAnyIndexErrors: Boolean? + get() = definedExternally + set(value) = definedExternally + var target: ScriptTarget? + get() = definedExternally + set(value) = definedExternally + var traceResolution: Boolean? + get() = definedExternally + set(value) = definedExternally + var useUnknownInCatchVariables: Boolean? + get() = definedExternally + set(value) = definedExternally + var resolveJsonModule: Boolean? + get() = definedExternally + set(value) = definedExternally + var types: Array? + get() = definedExternally + set(value) = definedExternally + var typeRoots: Array? + get() = definedExternally + set(value) = definedExternally + var esModuleInterop: Boolean? + get() = definedExternally + set(value) = definedExternally + var useDefineForClassFields: Boolean? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? | TsConfigSourceFile? */ + @nativeSetter + operator fun set(option: String, value: String?) + @nativeSetter + operator fun set(option: String, value: Number?) + @nativeSetter + operator fun set(option: String, value: Boolean?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: MapLike>?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: TsConfigSourceFile?) +} + +external interface WatchOptions { + var watchFile: WatchFileKind? + get() = definedExternally + set(value) = definedExternally + var watchDirectory: WatchDirectoryKind? + get() = definedExternally + set(value) = definedExternally + var fallbackPolling: PollingWatchKind? + get() = definedExternally + set(value) = definedExternally + var synchronousWatchDirectory: Boolean? + get() = definedExternally + set(value) = definedExternally + var excludeDirectories: Array? + get() = definedExternally + set(value) = definedExternally + var excludeFiles: Array? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ + @nativeSetter + operator fun set(option: String, value: String?) + @nativeSetter + operator fun set(option: String, value: Number?) + @nativeSetter + operator fun set(option: String, value: Boolean?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: MapLike>?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) +} + +external interface TypeAcquisition { + var enableAutoDiscovery: Boolean? + get() = definedExternally + set(value) = definedExternally + var enable: Boolean? + get() = definedExternally + set(value) = definedExternally + var include: Array? + get() = definedExternally + set(value) = definedExternally + var exclude: Array? + get() = definedExternally + set(value) = definedExternally + var disableFilenameBasedTypeAcquisition: Boolean? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ + @nativeSetter + operator fun set(option: String, value: String?) + @nativeSetter + operator fun set(option: String, value: Number?) + @nativeSetter + operator fun set(option: String, value: Boolean?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: MapLike>?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) +} + +external enum class ModuleKind { + None /* = 0 */, + CommonJS /* = 1 */, + AMD /* = 2 */, + UMD /* = 3 */, + System /* = 4 */, + ES2015 /* = 5 */, + ES2020 /* = 6 */, + ESNext /* = 99 */ +} + +external enum class JsxEmit { + None /* = 0 */, + Preserve /* = 1 */, + React /* = 2 */, + ReactNative /* = 3 */, + ReactJSX /* = 4 */, + ReactJSXDev /* = 5 */ +} + +external enum class ImportsNotUsedAsValues { + Remove /* = 0 */, + Preserve /* = 1 */, + Error /* = 2 */ +} + +external enum class NewLineKind { + CarriageReturnLineFeed /* = 0 */, + LineFeed /* = 1 */ +} + +external interface LineAndCharacter { + var line: Number + var character: Number +} + +external enum class ScriptKind { + Unknown /* = 0 */, + JS /* = 1 */, + JSX /* = 2 */, + TS /* = 3 */, + TSX /* = 4 */, + External /* = 5 */, + JSON /* = 6 */, + Deferred /* = 7 */ +} + +external enum class ScriptTarget { + ES3 /* = 0 */, + ES5 /* = 1 */, + ES2015 /* = 2 */, + ES2016 /* = 3 */, + ES2017 /* = 4 */, + ES2018 /* = 5 */, + ES2019 /* = 6 */, + ES2020 /* = 7 */, + ES2021 /* = 8 */, + ESNext /* = 99 */, + JSON /* = 100 */, + Latest /* = 99 */ +} + +external enum class LanguageVariant { + Standard /* = 0 */, + JSX /* = 1 */ +} + +external interface ParsedCommandLine { + var options: CompilerOptions + var typeAcquisition: TypeAcquisition? + get() = definedExternally + set(value) = definedExternally + var fileNames: Array + var projectReferences: Array? + get() = definedExternally + set(value) = definedExternally + var watchOptions: WatchOptions? + get() = definedExternally + set(value) = definedExternally + var raw: Any? + get() = definedExternally + set(value) = definedExternally + var errors: Array + var wildcardDirectories: MapLike? + get() = definedExternally + set(value) = definedExternally + var compileOnSave: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external enum class WatchDirectoryFlags { + None /* = 0 */, + Recursive /* = 1 */ +} + +external interface CreateProgramOptions { + var rootNames: Array + var options: CompilerOptions + var projectReferences: Array? + get() = definedExternally + set(value) = definedExternally + var host: CompilerHost? + get() = definedExternally + set(value) = definedExternally + var oldProgram: Program? + get() = definedExternally + set(value) = definedExternally + var configFileParsingDiagnostics: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface ModuleResolutionHost { + fun fileExists(fileName: String): Boolean + fun readFile(fileName: String): String? + val trace: ((s: String) -> Unit)? + val directoryExists: ((directoryName: String) -> Boolean)? + val realpath: ((path: String) -> String)? + val getCurrentDirectory: (() -> String)? + val getDirectories: ((path: String) -> Array)? +} + +external interface ResolvedModule { + var resolvedFileName: String + var isExternalLibraryImport: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedModuleFull : ResolvedModule { + var extension: Extension + var packageId: PackageId? + get() = definedExternally + set(value) = definedExternally +} + +external interface PackageId { + var name: String + var subModuleName: String + var version: String +} + +external enum class Extension { + Ts /* = ".ts" */, + Tsx /* = ".tsx" */, + Dts /* = ".d.ts" */, + Js /* = ".js" */, + Jsx /* = ".jsx" */, + Json /* = ".json" */, + TsBuildInfo /* = ".tsbuildinfo" */ +} + +external interface ResolvedModuleWithFailedLookupLocations { + val resolvedModule: ResolvedModuleFull? +} + +external interface ResolvedTypeReferenceDirective { + var primary: Boolean + var resolvedFileName: String? + var packageId: PackageId? + get() = definedExternally + set(value) = definedExternally + var isExternalLibraryImport: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations { + val resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective? + val failedLookupLocations: Array +} + +external interface CompilerHost : ModuleResolutionHost { + fun getSourceFile(fileName: String, languageVersion: ScriptTarget, onError: (message: String) -> Unit = definedExternally, shouldCreateNewSourceFile: Boolean = definedExternally): SourceFile? + val getSourceFileByPath: ((fileName: String, path: String /* String & `T$3` */, languageVersion: ScriptTarget, onError: (message: String) -> Unit, shouldCreateNewSourceFile: Boolean) -> SourceFile?)? + val getCancellationToken: (() -> CancellationToken)? + fun getDefaultLibFileName(options: CompilerOptions): String + val getDefaultLibLocation: (() -> String)? + var writeFile: WriteFileCallback + override var getCurrentDirectory: () -> String + fun getCanonicalFileName(fileName: String): String + fun useCaseSensitiveFileNames(): Boolean + fun getNewLine(): String + val readDirectory: ((rootDir: String, extensions: Array, excludes: Array?, includes: Array, depth: Number) -> Array)? + val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val getEnvironmentVariable: ((name: String) -> String?)? + val createHash: ((data: String) -> String)? + val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? +} + +external interface SourceMapRange : TextRange { + var source: SourceMapSource? + get() = definedExternally + set(value) = definedExternally +} + +external interface SourceMapSource { + fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter + var fileName: String + var text: String + var skipTrivia: ((pos: Number) -> Number)? + get() = definedExternally + set(value) = definedExternally +} + +external enum class EmitFlags { + None /* = 0 */, + SingleLine /* = 1 */, + AdviseOnEmitNode /* = 2 */, + NoSubstitution /* = 4 */, + CapturesThis /* = 8 */, + NoLeadingSourceMap /* = 16 */, + NoTrailingSourceMap /* = 32 */, + NoSourceMap /* = 48 */, + NoNestedSourceMaps /* = 64 */, + NoTokenLeadingSourceMaps /* = 128 */, + NoTokenTrailingSourceMaps /* = 256 */, + NoTokenSourceMaps /* = 384 */, + NoLeadingComments /* = 512 */, + NoTrailingComments /* = 1024 */, + NoComments /* = 1536 */, + NoNestedComments /* = 2048 */, + HelperName /* = 4096 */, + ExportName /* = 8192 */, + LocalName /* = 16384 */, + InternalName /* = 32768 */, + Indented /* = 65536 */, + NoIndentation /* = 131072 */, + AsyncFunctionBody /* = 262144 */, + ReuseTempVariableScope /* = 524288 */, + CustomPrologue /* = 1048576 */, + NoHoisting /* = 2097152 */, + HasEndOfDeclarationMarker /* = 4194304 */, + Iterator /* = 8388608 */, + NoAsciiEscaping /* = 16777216 */ +} + +external interface EmitHelperBase { + val name: String + val scoped: Boolean + val text: dynamic /* String | (node: EmitHelperUniqueNameCallback) -> String */ + get() = definedExternally + val priority: Number? + get() = definedExternally + val dependencies: Array? + get() = definedExternally +} + +external interface ScopedEmitHelper : EmitHelperBase { + override val scoped: Boolean +} + +external interface UnscopedEmitHelper : EmitHelperBase { + override val scoped: Boolean + override val text: String +} + +external enum class EmitHint { + SourceFile /* = 0 */, + Expression /* = 1 */, + IdentifierName /* = 2 */, + MappedTypeParameter /* = 3 */, + Unspecified /* = 4 */, + EmbeddedStatement /* = 5 */, + JsxAttributeValue /* = 6 */ +} + +external enum class OuterExpressionKinds { + Parentheses /* = 1 */, + TypeAssertions /* = 2 */, + NonNullAssertions /* = 4 */, + PartiallyEmittedExpressions /* = 8 */, + Assertions /* = 6 */, + All /* = 15 */ +} + +external interface NodeFactory { + fun createNodeArray(elements: Array = definedExternally, hasTrailingComma: Boolean = definedExternally): NodeArray + fun createNumericLiteral(value: String, numericLiteralFlags: TokenFlags = definedExternally): NumericLiteral + fun createNumericLiteral(value: String): NumericLiteral + fun createNumericLiteral(value: Number, numericLiteralFlags: TokenFlags = definedExternally): NumericLiteral + fun createNumericLiteral(value: Number): NumericLiteral + fun createBigIntLiteral(value: String): BigIntLiteral + fun createBigIntLiteral(value: PseudoBigInt): BigIntLiteral + fun createStringLiteral(text: String, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: Identifier, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: Identifier): StringLiteral + fun createStringLiteralFromNode(sourceNode: StringLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: StringLiteral): StringLiteral + fun createStringLiteralFromNode(sourceNode: NoSubstitutionTemplateLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: NoSubstitutionTemplateLiteral): StringLiteral + fun createStringLiteralFromNode(sourceNode: NumericLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: NumericLiteral): StringLiteral + fun createRegularExpressionLiteral(text: String): RegularExpressionLiteral + fun createIdentifier(text: String): Identifier + fun createTempVariable(recordTempVariable: ((node: Identifier) -> Unit)?, reservedInNestedScopes: Boolean = definedExternally): Identifier + fun createLoopVariable(reservedInNestedScopes: Boolean = definedExternally): Identifier + fun createUniqueName(text: String, flags: GeneratedIdentifierFlags = definedExternally): Identifier + fun getGeneratedNameForNode(node: Node?, flags: GeneratedIdentifierFlags = definedExternally): Identifier + fun createPrivateIdentifier(text: String): PrivateIdentifier + fun createToken(token: SyntaxKind.SuperKeyword): SuperExpression + fun createToken(token: SyntaxKind.ThisKeyword): ThisExpression + fun createToken(token: SyntaxKind.NullKeyword): NullLiteral + fun createToken(token: SyntaxKind.TrueKeyword): TrueLiteral + fun createToken(token: SyntaxKind.FalseKeyword): FalseLiteral + fun createToken(token: TKind): dynamic /* Token */ + fun createSuper(): SuperExpression + fun createThis(): ThisExpression + fun createNull(): NullLiteral + fun createTrue(): TrueLiteral + fun createFalse(): FalseLiteral + fun createModifier(kind: T): ModifierToken + fun createModifiersFromModifierFlags(flags: ModifierFlags): Array + fun createQualifiedName(left: Identifier, right: String): QualifiedName + fun createQualifiedName(left: Identifier, right: Identifier): QualifiedName + fun createQualifiedName(left: QualifiedName, right: String): QualifiedName + fun createQualifiedName(left: QualifiedName, right: Identifier): QualifiedName + fun updateQualifiedName(node: QualifiedName, left: Identifier, right: Identifier): QualifiedName + fun updateQualifiedName(node: QualifiedName, left: QualifiedName, right: Identifier): QualifiedName + fun createComputedPropertyName(expression: Expression): ComputedPropertyName + fun updateComputedPropertyName(node: ComputedPropertyName, expression: Expression): ComputedPropertyName + fun createTypeParameterDeclaration(name: String, constraint: TypeNode = definedExternally, defaultType: TypeNode = definedExternally): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: String): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: String, constraint: TypeNode = definedExternally): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: Identifier, constraint: TypeNode = definedExternally, defaultType: TypeNode = definedExternally): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: Identifier): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: Identifier, constraint: TypeNode = definedExternally): TypeParameterDeclaration + fun updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode?, defaultType: TypeNode?): TypeParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration + fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration + fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration + fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration + fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration + fun createDecorator(expression: Expression): Decorator + fun updateDecorator(node: Decorator, expression: Expression): Decorator + fun createPropertySignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: String, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createMethodSignature(modifiers: Array?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createConstructorDeclaration(decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration + fun updateConstructorDeclaration(node: ConstructorDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration + fun createCallSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): CallSignatureDeclaration + fun updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): CallSignatureDeclaration + fun createConstructSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): ConstructSignatureDeclaration + fun updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): ConstructSignatureDeclaration + fun createIndexSignature(decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration + fun updateIndexSignature(node: IndexSignatureDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration + fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan + fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan + fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan + fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan + fun createClassStaticBlockDeclaration(decorators: Array?, modifiers: Array?, body: Block): ClassStaticBlockDeclaration + fun updateClassStaticBlockDeclaration(node: ClassStaticBlockDeclaration, decorators: Array?, modifiers: Array?, body: Block): ClassStaticBlockDeclaration + fun createKeywordTypeNode(kind: TKind): KeywordTypeNode + fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode + fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode + fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: String, type: TypeNode?): TypePredicateNode + fun updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode + fun updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode + fun createTypeReferenceNode(typeName: String, typeArguments: Array = definedExternally): TypeReferenceNode + fun createTypeReferenceNode(typeName: String): TypeReferenceNode + fun createTypeReferenceNode(typeName: Identifier, typeArguments: Array = definedExternally): TypeReferenceNode + fun createTypeReferenceNode(typeName: Identifier): TypeReferenceNode + fun createTypeReferenceNode(typeName: QualifiedName, typeArguments: Array = definedExternally): TypeReferenceNode + fun createTypeReferenceNode(typeName: QualifiedName): TypeReferenceNode + fun updateTypeReferenceNode(node: TypeReferenceNode, typeName: Identifier, typeArguments: NodeArray?): TypeReferenceNode + fun updateTypeReferenceNode(node: TypeReferenceNode, typeName: QualifiedName, typeArguments: NodeArray?): TypeReferenceNode + fun createFunctionTypeNode(typeParameters: Array?, parameters: Array, type: TypeNode): FunctionTypeNode + fun updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): FunctionTypeNode + fun createConstructorTypeNode(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode): ConstructorTypeNode + fun createConstructorTypeNode(typeParameters: Array?, parameters: Array, type: TypeNode): ConstructorTypeNode + fun updateConstructorTypeNode(node: ConstructorTypeNode, modifiers: Array?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): ConstructorTypeNode + fun updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): ConstructorTypeNode + fun createTypeQueryNode(exprName: Identifier): TypeQueryNode + fun createTypeQueryNode(exprName: QualifiedName): TypeQueryNode + fun updateTypeQueryNode(node: TypeQueryNode, exprName: Identifier): TypeQueryNode + fun updateTypeQueryNode(node: TypeQueryNode, exprName: QualifiedName): TypeQueryNode + fun createTypeLiteralNode(members: Array?): TypeLiteralNode + fun updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray): TypeLiteralNode + fun createArrayTypeNode(elementType: TypeNode): ArrayTypeNode + fun updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode + fun createTupleTypeNode(elements: Array): TupleTypeNode + fun updateTupleTypeNode(node: TupleTypeNode, elements: Array): TupleTypeNode + fun createNamedTupleMember(dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode): NamedTupleMember + fun updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode): NamedTupleMember + fun createOptionalTypeNode(type: TypeNode): OptionalTypeNode + fun updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode + fun createRestTypeNode(type: TypeNode): RestTypeNode + fun updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode + fun createUnionTypeNode(types: Array): UnionTypeNode + fun updateUnionTypeNode(node: UnionTypeNode, types: NodeArray): UnionTypeNode + fun createIntersectionTypeNode(types: Array): IntersectionTypeNode + fun updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray): IntersectionTypeNode + fun createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode + fun updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode + fun createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode + fun updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally, typeArguments: Array = definedExternally, isTypeOf: Boolean = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally, typeArguments: Array = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally, typeArguments: Array = definedExternally, isTypeOf: Boolean = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally, typeArguments: Array = definedExternally): ImportTypeNode + fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: Identifier?, typeArguments: Array?, isTypeOf: Boolean = definedExternally): ImportTypeNode + fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: Identifier?, typeArguments: Array?): ImportTypeNode + fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: QualifiedName?, typeArguments: Array?, isTypeOf: Boolean = definedExternally): ImportTypeNode + fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: QualifiedName?, typeArguments: Array?): ImportTypeNode + fun createParenthesizedType(type: TypeNode): ParenthesizedTypeNode + fun updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode + fun createThisTypeNode(): ThisTypeNode + fun createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword, type: TypeNode): TypeOperatorNode + fun createTypeOperatorNode(operator: SyntaxKind.UniqueKeyword, type: TypeNode): TypeOperatorNode + fun createTypeOperatorNode(operator: SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode + fun updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode + fun createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode + fun updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode + fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun createLiteralTypeNode(literal: NullLiteral): LiteralTypeNode + fun createLiteralTypeNode(literal: TrueLiteral): LiteralTypeNode + fun createLiteralTypeNode(literal: FalseLiteral): LiteralTypeNode + fun createLiteralTypeNode(literal: LiteralExpression): LiteralTypeNode + fun createLiteralTypeNode(literal: PrefixUnaryExpression): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: NullLiteral): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: TrueLiteral): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: FalseLiteral): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralExpression): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: PrefixUnaryExpression): LiteralTypeNode + fun createTemplateLiteralType(head: TemplateHead, templateSpans: Array): TemplateLiteralTypeNode + fun updateTemplateLiteralType(node: TemplateLiteralTypeNode, head: TemplateHead, templateSpans: Array): TemplateLiteralTypeNode + fun createObjectBindingPattern(elements: Array): ObjectBindingPattern + fun updateObjectBindingPattern(node: ObjectBindingPattern, elements: Array): ObjectBindingPattern + fun createArrayBindingPattern(elements: Array): ArrayBindingPattern + fun updateArrayBindingPattern(node: ArrayBindingPattern, elements: Array): ArrayBindingPattern + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: String?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: String?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun createArrayLiteralExpression(elements: Array = definedExternally, multiLine: Boolean = definedExternally): ArrayLiteralExpression + fun updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: Array): ArrayLiteralExpression + fun createObjectLiteralExpression(properties: Array = definedExternally, multiLine: Boolean = definedExternally): ObjectLiteralExpression + fun updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: Array): ObjectLiteralExpression + fun createPropertyAccessExpression(expression: Expression, name: String): PropertyAccessExpression + fun createPropertyAccessExpression(expression: Expression, name: Identifier): PropertyAccessExpression + fun createPropertyAccessExpression(expression: Expression, name: PrivateIdentifier): PropertyAccessExpression + fun updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier): PropertyAccessExpression + fun updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: PrivateIdentifier): PropertyAccessExpression + fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: String): PropertyAccessChain + fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: Identifier): PropertyAccessChain + fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: PrivateIdentifier): PropertyAccessChain + fun updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: Identifier): PropertyAccessChain + fun updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: PrivateIdentifier): PropertyAccessChain + fun createElementAccessExpression(expression: Expression, index: Number): ElementAccessExpression + fun createElementAccessExpression(expression: Expression, index: Expression): ElementAccessExpression + fun updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression + fun createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, index: Number): ElementAccessChain + fun createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, index: Expression): ElementAccessChain + fun updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, argumentExpression: Expression): ElementAccessChain + fun createCallExpression(expression: Expression, typeArguments: Array?, argumentsArray: Array?): CallExpression + fun updateCallExpression(node: CallExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array): CallExpression + fun createCallChain(expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array?): CallChain + fun updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array): CallChain + fun createNewExpression(expression: Expression, typeArguments: Array?, argumentsArray: Array?): NewExpression + fun updateNewExpression(node: NewExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array?): NewExpression + fun createTaggedTemplateExpression(tag: Expression, typeArguments: Array?, template: TemplateExpression): TaggedTemplateExpression + fun createTaggedTemplateExpression(tag: Expression, typeArguments: Array?, template: NoSubstitutionTemplateLiteral): TaggedTemplateExpression + fun updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: TemplateExpression): TaggedTemplateExpression + fun updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: NoSubstitutionTemplateLiteral): TaggedTemplateExpression + fun createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion + fun updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion + fun createParenthesizedExpression(expression: Expression): ParenthesizedExpression + fun updateParenthesizedExpression(node: ParenthesizedExpression, expression: Expression): ParenthesizedExpression + fun createFunctionExpression(modifiers: Array?, asteriskToken: AsteriskToken?, name: String?, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block): FunctionExpression + fun createFunctionExpression(modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block): FunctionExpression + fun updateFunctionExpression(node: FunctionExpression, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block): FunctionExpression + fun createArrowFunction(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: FunctionBody): ArrowFunction + fun createArrowFunction(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: Expression): ArrowFunction + fun updateArrowFunction(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: FunctionBody): ArrowFunction + fun updateArrowFunction(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: Expression): ArrowFunction + fun createDeleteExpression(expression: Expression): DeleteExpression + fun updateDeleteExpression(node: DeleteExpression, expression: Expression): DeleteExpression + fun createTypeOfExpression(expression: Expression): TypeOfExpression + fun updateTypeOfExpression(node: TypeOfExpression, expression: Expression): TypeOfExpression + fun createVoidExpression(expression: Expression): VoidExpression + fun updateVoidExpression(node: VoidExpression, expression: Expression): VoidExpression + fun createAwaitExpression(expression: Expression): AwaitExpression + fun updateAwaitExpression(node: AwaitExpression, expression: Expression): AwaitExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.PlusPlusToken, operand: Expression): PrefixUnaryExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.MinusMinusToken, operand: Expression): PrefixUnaryExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.PlusToken, operand: Expression): PrefixUnaryExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.MinusToken, operand: Expression): PrefixUnaryExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.TildeToken, operand: Expression): PrefixUnaryExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.ExclamationToken, operand: Expression): PrefixUnaryExpression + fun updatePrefixUnaryExpression(node: PrefixUnaryExpression, operand: Expression): PrefixUnaryExpression + fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind.PlusPlusToken): PostfixUnaryExpression + fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind.MinusMinusToken): PostfixUnaryExpression + fun updatePostfixUnaryExpression(node: PostfixUnaryExpression, operand: Expression): PostfixUnaryExpression + fun createBinaryExpression(left: Expression, operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression): BinaryExpression + fun updateBinaryExpression(node: BinaryExpression, left: Expression, operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression): BinaryExpression + fun createConditionalExpression(condition: Expression, questionToken: QuestionToken?, whenTrue: Expression, colonToken: ColonToken?, whenFalse: Expression): ConditionalExpression + fun updateConditionalExpression(node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression + fun createTemplateExpression(head: TemplateHead, templateSpans: Array): TemplateExpression + fun updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: Array): TemplateExpression + fun createTemplateHead(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateHead + fun createTemplateHead(text: String): TemplateHead + fun createTemplateHead(text: String, rawText: String = definedExternally): TemplateHead + fun createTemplateHead(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateHead + fun createTemplateHead(text: String?, rawText: String): TemplateHead + fun createTemplateMiddle(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateMiddle + fun createTemplateMiddle(text: String): TemplateMiddle + fun createTemplateMiddle(text: String, rawText: String = definedExternally): TemplateMiddle + fun createTemplateMiddle(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateMiddle + fun createTemplateMiddle(text: String?, rawText: String): TemplateMiddle + fun createTemplateTail(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateTail + fun createTemplateTail(text: String): TemplateTail + fun createTemplateTail(text: String, rawText: String = definedExternally): TemplateTail + fun createTemplateTail(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateTail + fun createTemplateTail(text: String?, rawText: String): TemplateTail + fun createNoSubstitutionTemplateLiteral(text: String, rawText: String = definedExternally): NoSubstitutionTemplateLiteral + fun createNoSubstitutionTemplateLiteral(text: String): NoSubstitutionTemplateLiteral + fun createNoSubstitutionTemplateLiteral(text: String?, rawText: String): NoSubstitutionTemplateLiteral + fun createYieldExpression(asteriskToken: AsteriskToken, expression: Expression): YieldExpression + fun createYieldExpression(asteriskToken: Nothing?, expression: Expression?): YieldExpression + fun updateYieldExpression(node: YieldExpression, asteriskToken: AsteriskToken?, expression: Expression?): YieldExpression + fun createSpreadElement(expression: Expression): SpreadElement + fun updateSpreadElement(node: SpreadElement, expression: Expression): SpreadElement + fun createClassExpression(decorators: Array?, modifiers: Array?, name: String?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression + fun createClassExpression(decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression + fun updateClassExpression(node: ClassExpression, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression + fun createOmittedExpression(): OmittedExpression + fun createExpressionWithTypeArguments(expression: Expression, typeArguments: Array?): ExpressionWithTypeArguments + fun updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, expression: Expression, typeArguments: Array?): ExpressionWithTypeArguments + fun createAsExpression(expression: Expression, type: TypeNode): AsExpression + fun updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode): AsExpression + fun createNonNullExpression(expression: Expression): NonNullExpression + fun updateNonNullExpression(node: NonNullExpression, expression: Expression): NonNullExpression + fun createNonNullChain(expression: Expression): NonNullChain + fun updateNonNullChain(node: NonNullChain, expression: Expression): NonNullChain + fun createMetaProperty(keywordToken: SyntaxKind.NewKeyword, name: Identifier): MetaProperty + fun createMetaProperty(keywordToken: SyntaxKind.ImportKeyword, name: Identifier): MetaProperty + fun updateMetaProperty(node: MetaProperty, name: Identifier): MetaProperty + fun createTemplateSpan(expression: Expression, literal: TemplateMiddle): TemplateSpan + fun createTemplateSpan(expression: Expression, literal: TemplateTail): TemplateSpan + fun updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle): TemplateSpan + fun updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateTail): TemplateSpan + fun createSemicolonClassElement(): SemicolonClassElement + fun createBlock(statements: Array, multiLine: Boolean = definedExternally): Block + fun updateBlock(node: Block, statements: Array): Block + fun createVariableStatement(modifiers: Array?, declarationList: VariableDeclarationList): VariableStatement + fun createVariableStatement(modifiers: Array?, declarationList: Array): VariableStatement + fun updateVariableStatement(node: VariableStatement, modifiers: Array?, declarationList: VariableDeclarationList): VariableStatement + fun createEmptyStatement(): EmptyStatement + fun createExpressionStatement(expression: Expression): ExpressionStatement + fun updateExpressionStatement(node: ExpressionStatement, expression: Expression): ExpressionStatement + fun createIfStatement(expression: Expression, thenStatement: Statement, elseStatement: Statement = definedExternally): IfStatement + fun updateIfStatement(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement?): IfStatement + fun createDoStatement(statement: Statement, expression: Expression): DoStatement + fun updateDoStatement(node: DoStatement, statement: Statement, expression: Expression): DoStatement + fun createWhileStatement(expression: Expression, statement: Statement): WhileStatement + fun updateWhileStatement(node: WhileStatement, expression: Expression, statement: Statement): WhileStatement + fun createForStatement(initializer: VariableDeclarationList?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement + fun createForStatement(initializer: Expression?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement + fun updateForStatement(node: ForStatement, initializer: VariableDeclarationList?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement + fun updateForStatement(node: ForStatement, initializer: Expression?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement + fun createForInStatement(initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForInStatement + fun createForInStatement(initializer: Expression, expression: Expression, statement: Statement): ForInStatement + fun updateForInStatement(node: ForInStatement, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForInStatement + fun updateForInStatement(node: ForInStatement, initializer: Expression, expression: Expression, statement: Statement): ForInStatement + fun createForOfStatement(awaitModifier: AwaitKeyword?, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForOfStatement + fun createForOfStatement(awaitModifier: AwaitKeyword?, initializer: Expression, expression: Expression, statement: Statement): ForOfStatement + fun updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForOfStatement + fun updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: Expression, expression: Expression, statement: Statement): ForOfStatement + fun createContinueStatement(label: String = definedExternally): ContinueStatement + fun createContinueStatement(): ContinueStatement + fun createContinueStatement(label: Identifier = definedExternally): ContinueStatement + fun updateContinueStatement(node: ContinueStatement, label: Identifier?): ContinueStatement + fun createBreakStatement(label: String = definedExternally): BreakStatement + fun createBreakStatement(): BreakStatement + fun createBreakStatement(label: Identifier = definedExternally): BreakStatement + fun updateBreakStatement(node: BreakStatement, label: Identifier?): BreakStatement + fun createReturnStatement(expression: Expression = definedExternally): ReturnStatement + fun updateReturnStatement(node: ReturnStatement, expression: Expression?): ReturnStatement + fun createWithStatement(expression: Expression, statement: Statement): WithStatement + fun updateWithStatement(node: WithStatement, expression: Expression, statement: Statement): WithStatement + fun createSwitchStatement(expression: Expression, caseBlock: CaseBlock): SwitchStatement + fun updateSwitchStatement(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock): SwitchStatement + fun createLabeledStatement(label: String, statement: Statement): LabeledStatement + fun createLabeledStatement(label: Identifier, statement: Statement): LabeledStatement + fun updateLabeledStatement(node: LabeledStatement, label: Identifier, statement: Statement): LabeledStatement + fun createThrowStatement(expression: Expression): ThrowStatement + fun updateThrowStatement(node: ThrowStatement, expression: Expression): ThrowStatement + fun createTryStatement(tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?): TryStatement + fun updateTryStatement(node: TryStatement, tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?): TryStatement + fun createDebuggerStatement(): DebuggerStatement + fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: String): VariableDeclaration + fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: Identifier): VariableDeclaration + fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ObjectBindingPattern): VariableDeclaration + fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ArrayBindingPattern): VariableDeclaration + fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration + fun updateVariableDeclaration(node: VariableDeclaration, name: Identifier, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration + fun updateVariableDeclaration(node: VariableDeclaration, name: ObjectBindingPattern, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration + fun updateVariableDeclaration(node: VariableDeclaration, name: ArrayBindingPattern, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration + fun createVariableDeclarationList(declarations: Array, flags: NodeFlags = definedExternally): VariableDeclarationList + fun updateVariableDeclarationList(node: VariableDeclarationList, declarations: Array): VariableDeclarationList + fun createFunctionDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration + fun createFunctionDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration + fun updateFunctionDeclaration(node: FunctionDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration + fun createClassDeclaration(decorators: Array?, modifiers: Array?, name: String?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration + fun createClassDeclaration(decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration + fun updateClassDeclaration(node: ClassDeclaration, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration + fun createInterfaceDeclaration(decorators: Array?, modifiers: Array?, name: String, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration + fun createInterfaceDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration + fun updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration + fun createTypeAliasDeclaration(decorators: Array?, modifiers: Array?, name: String, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration + fun createTypeAliasDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration + fun updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration + fun createEnumDeclaration(decorators: Array?, modifiers: Array?, name: String, members: Array): EnumDeclaration + fun createEnumDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, members: Array): EnumDeclaration + fun updateEnumDeclaration(node: EnumDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, members: Array): EnumDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?): ModuleDeclaration + fun createModuleBlock(statements: Array): ModuleBlock + fun updateModuleBlock(node: ModuleBlock, statements: Array): ModuleBlock + fun createCaseBlock(clauses: Array): CaseBlock + fun updateCaseBlock(node: CaseBlock, clauses: Array): CaseBlock + fun createNamespaceExportDeclaration(name: String): NamespaceExportDeclaration + fun createNamespaceExportDeclaration(name: Identifier): NamespaceExportDeclaration + fun updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier): NamespaceExportDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: Identifier): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: QualifiedName): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: ExternalModuleReference): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: Identifier): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: QualifiedName): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: ExternalModuleReference): ImportEqualsDeclaration + fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: Identifier): ImportEqualsDeclaration + fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: QualifiedName): ImportEqualsDeclaration + fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: ExternalModuleReference): ImportEqualsDeclaration + fun createImportDeclaration(decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression): ImportDeclaration + fun updateImportDeclaration(node: ImportDeclaration, decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression): ImportDeclaration + fun createImportClause(isTypeOnly: Boolean, name: Identifier?, namedBindings: NamespaceImport?): ImportClause + fun createImportClause(isTypeOnly: Boolean, name: Identifier?, namedBindings: NamedImports?): ImportClause + fun updateImportClause(node: ImportClause, isTypeOnly: Boolean, name: Identifier?, namedBindings: NamespaceImport?): ImportClause + fun updateImportClause(node: ImportClause, isTypeOnly: Boolean, name: Identifier?, namedBindings: NamedImports?): ImportClause + fun createNamespaceImport(name: Identifier): NamespaceImport + fun updateNamespaceImport(node: NamespaceImport, name: Identifier): NamespaceImport + fun createNamespaceExport(name: Identifier): NamespaceExport + fun updateNamespaceExport(node: NamespaceExport, name: Identifier): NamespaceExport + fun createNamedImports(elements: Array): NamedImports + fun updateNamedImports(node: NamedImports, elements: Array): NamedImports + fun createImportSpecifier(propertyName: Identifier?, name: Identifier): ImportSpecifier + fun updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier?, name: Identifier): ImportSpecifier + fun createExportAssignment(decorators: Array?, modifiers: Array?, isExportEquals: Boolean?, expression: Expression): ExportAssignment + fun updateExportAssignment(node: ExportAssignment, decorators: Array?, modifiers: Array?, expression: Expression): ExportAssignment + fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?, moduleSpecifier: Expression = definedExternally): ExportDeclaration + fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?): ExportDeclaration + fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?, moduleSpecifier: Expression = definedExternally): ExportDeclaration + fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?): ExportDeclaration + fun updateExportDeclaration(node: ExportDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?, moduleSpecifier: Expression?): ExportDeclaration + fun updateExportDeclaration(node: ExportDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?, moduleSpecifier: Expression?): ExportDeclaration + fun createNamedExports(elements: Array): NamedExports + fun updateNamedExports(node: NamedExports, elements: Array): NamedExports + fun createExportSpecifier(propertyName: String?, name: String): ExportSpecifier + fun createExportSpecifier(propertyName: String?, name: Identifier): ExportSpecifier + fun createExportSpecifier(propertyName: Identifier?, name: String): ExportSpecifier + fun createExportSpecifier(propertyName: Identifier?, name: Identifier): ExportSpecifier + fun updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier?, name: Identifier): ExportSpecifier + fun createExternalModuleReference(expression: Expression): ExternalModuleReference + fun updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference + fun createJSDocAllType(): JSDocAllType + fun createJSDocUnknownType(): JSDocUnknownType + fun createJSDocNonNullableType(type: TypeNode): JSDocNonNullableType + fun updateJSDocNonNullableType(node: JSDocNonNullableType, type: TypeNode): JSDocNonNullableType + fun createJSDocNullableType(type: TypeNode): JSDocNullableType + fun updateJSDocNullableType(node: JSDocNullableType, type: TypeNode): JSDocNullableType + fun createJSDocOptionalType(type: TypeNode): JSDocOptionalType + fun updateJSDocOptionalType(node: JSDocOptionalType, type: TypeNode): JSDocOptionalType + fun createJSDocFunctionType(parameters: Array, type: TypeNode?): JSDocFunctionType + fun updateJSDocFunctionType(node: JSDocFunctionType, parameters: Array, type: TypeNode?): JSDocFunctionType + fun createJSDocVariadicType(type: TypeNode): JSDocVariadicType + fun updateJSDocVariadicType(node: JSDocVariadicType, type: TypeNode): JSDocVariadicType + fun createJSDocNamepathType(type: TypeNode): JSDocNamepathType + fun updateJSDocNamepathType(node: JSDocNamepathType, type: TypeNode): JSDocNamepathType + fun createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression + fun updateJSDocTypeExpression(node: JSDocTypeExpression, type: TypeNode): JSDocTypeExpression + fun createJSDocNameReference(name: Identifier): JSDocNameReference + fun createJSDocNameReference(name: QualifiedName): JSDocNameReference + fun createJSDocNameReference(name: JSDocMemberName): JSDocNameReference + fun updateJSDocNameReference(node: JSDocNameReference, name: Identifier): JSDocNameReference + fun updateJSDocNameReference(node: JSDocNameReference, name: QualifiedName): JSDocNameReference + fun updateJSDocNameReference(node: JSDocNameReference, name: JSDocMemberName): JSDocNameReference + fun createJSDocMemberName(left: Identifier, right: Identifier): JSDocMemberName + fun createJSDocMemberName(left: QualifiedName, right: Identifier): JSDocMemberName + fun createJSDocMemberName(left: JSDocMemberName, right: Identifier): JSDocMemberName + fun updateJSDocMemberName(node: JSDocMemberName, left: Identifier, right: Identifier): JSDocMemberName + fun updateJSDocMemberName(node: JSDocMemberName, left: QualifiedName, right: Identifier): JSDocMemberName + fun updateJSDocMemberName(node: JSDocMemberName, left: JSDocMemberName, right: Identifier): JSDocMemberName + fun createJSDocLink(name: Identifier?, text: String): JSDocLink + fun createJSDocLink(name: QualifiedName?, text: String): JSDocLink + fun createJSDocLink(name: JSDocMemberName?, text: String): JSDocLink + fun updateJSDocLink(node: JSDocLink, name: Identifier?, text: String): JSDocLink + fun updateJSDocLink(node: JSDocLink, name: QualifiedName?, text: String): JSDocLink + fun updateJSDocLink(node: JSDocLink, name: JSDocMemberName?, text: String): JSDocLink + fun createJSDocLinkCode(name: Identifier?, text: String): JSDocLinkCode + fun createJSDocLinkCode(name: QualifiedName?, text: String): JSDocLinkCode + fun createJSDocLinkCode(name: JSDocMemberName?, text: String): JSDocLinkCode + fun updateJSDocLinkCode(node: JSDocLinkCode, name: Identifier?, text: String): JSDocLinkCode + fun updateJSDocLinkCode(node: JSDocLinkCode, name: QualifiedName?, text: String): JSDocLinkCode + fun updateJSDocLinkCode(node: JSDocLinkCode, name: JSDocMemberName?, text: String): JSDocLinkCode + fun createJSDocLinkPlain(name: Identifier?, text: String): JSDocLinkPlain + fun createJSDocLinkPlain(name: QualifiedName?, text: String): JSDocLinkPlain + fun createJSDocLinkPlain(name: JSDocMemberName?, text: String): JSDocLinkPlain + fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: Identifier?, text: String): JSDocLinkPlain + fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: QualifiedName?, text: String): JSDocLinkPlain + fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: JSDocMemberName?, text: String): JSDocLinkPlain + fun createJSDocTypeLiteral(jsDocPropertyTags: Array = definedExternally, isArrayType: Boolean = definedExternally): JSDocTypeLiteral + fun updateJSDocTypeLiteral(node: JSDocTypeLiteral, jsDocPropertyTags: Array?, isArrayType: Boolean?): JSDocTypeLiteral + fun createJSDocSignature(typeParameters: Array?, parameters: Array, type: JSDocReturnTag = definedExternally): JSDocSignature + fun updateJSDocSignature(node: JSDocSignature, typeParameters: Array?, parameters: Array, type: JSDocReturnTag?): JSDocSignature + fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String = definedExternally): JSDocTemplateTag + fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array): JSDocTemplateTag + fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray = definedExternally): JSDocTemplateTag + fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String?): JSDocTemplateTag + fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray?): JSDocTemplateTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: String?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: String?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag + fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocTypeTag + fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocTypeTag + fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocTypeTag + fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocTypeTag + fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocTypeTag + fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag + fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag + fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag + fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag + fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag + fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag + fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: String = definedExternally): JSDocReturnTag + fun createJSDocReturnTag(tagName: Identifier?): JSDocReturnTag + fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocReturnTag + fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: NodeArray = definedExternally): JSDocReturnTag + fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocReturnTag + fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocReturnTag + fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocThisTag + fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocThisTag + fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocThisTag + fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocThisTag + fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocThisTag + fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocEnumTag + fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocEnumTag + fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocEnumTag + fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocEnumTag + fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocEnumTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: String?): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: NodeArray?): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocCallbackTag + fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String = definedExternally): JSDocAugmentsTag + fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */): JSDocAugmentsTag + fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray = definedExternally): JSDocAugmentsTag + fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String?): JSDocAugmentsTag + fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray?): JSDocAugmentsTag + fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String = definedExternally): JSDocImplementsTag + fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */): JSDocImplementsTag + fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray = definedExternally): JSDocImplementsTag + fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String?): JSDocImplementsTag + fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray?): JSDocImplementsTag + fun createJSDocAuthorTag(tagName: Identifier?, comment: String = definedExternally): JSDocAuthorTag + fun createJSDocAuthorTag(tagName: Identifier?): JSDocAuthorTag + fun createJSDocAuthorTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocAuthorTag + fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: String?): JSDocAuthorTag + fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: NodeArray?): JSDocAuthorTag + fun createJSDocClassTag(tagName: Identifier?, comment: String = definedExternally): JSDocClassTag + fun createJSDocClassTag(tagName: Identifier?): JSDocClassTag + fun createJSDocClassTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocClassTag + fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: String?): JSDocClassTag + fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: NodeArray?): JSDocClassTag + fun createJSDocPublicTag(tagName: Identifier?, comment: String = definedExternally): JSDocPublicTag + fun createJSDocPublicTag(tagName: Identifier?): JSDocPublicTag + fun createJSDocPublicTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPublicTag + fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: String?): JSDocPublicTag + fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: NodeArray?): JSDocPublicTag + fun createJSDocPrivateTag(tagName: Identifier?, comment: String = definedExternally): JSDocPrivateTag + fun createJSDocPrivateTag(tagName: Identifier?): JSDocPrivateTag + fun createJSDocPrivateTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPrivateTag + fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: String?): JSDocPrivateTag + fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: NodeArray?): JSDocPrivateTag + fun createJSDocProtectedTag(tagName: Identifier?, comment: String = definedExternally): JSDocProtectedTag + fun createJSDocProtectedTag(tagName: Identifier?): JSDocProtectedTag + fun createJSDocProtectedTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocProtectedTag + fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: String?): JSDocProtectedTag + fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: NodeArray?): JSDocProtectedTag + fun createJSDocReadonlyTag(tagName: Identifier?, comment: String = definedExternally): JSDocReadonlyTag + fun createJSDocReadonlyTag(tagName: Identifier?): JSDocReadonlyTag + fun createJSDocReadonlyTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocReadonlyTag + fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: String?): JSDocReadonlyTag + fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: NodeArray?): JSDocReadonlyTag + fun createJSDocUnknownTag(tagName: Identifier, comment: String = definedExternally): JSDocUnknownTag + fun createJSDocUnknownTag(tagName: Identifier): JSDocUnknownTag + fun createJSDocUnknownTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocUnknownTag + fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: String?): JSDocUnknownTag + fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: NodeArray?): JSDocUnknownTag + fun createJSDocDeprecatedTag(tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag + fun createJSDocDeprecatedTag(tagName: Identifier): JSDocDeprecatedTag + fun createJSDocDeprecatedTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag + fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag + fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier): JSDocDeprecatedTag + fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag + fun createJSDocOverrideTag(tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag + fun createJSDocOverrideTag(tagName: Identifier): JSDocOverrideTag + fun createJSDocOverrideTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag + fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag + fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier): JSDocOverrideTag + fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag + fun createJSDocText(text: String): JSDocText + fun updateJSDocText(node: JSDocText, text: String): JSDocText + fun createJSDocComment(comment: String? = definedExternally, tags: Array? = definedExternally): JSDoc + fun createJSDocComment(): JSDoc + fun createJSDocComment(comment: String? = definedExternally): JSDoc + fun createJSDocComment(comment: NodeArray? = definedExternally, tags: Array? = definedExternally): JSDoc + fun createJSDocComment(comment: NodeArray? = definedExternally): JSDoc + fun updateJSDocComment(node: JSDoc, comment: String?, tags: Array?): JSDoc + fun updateJSDocComment(node: JSDoc, comment: NodeArray?, tags: Array?): JSDoc + fun createJsxElement(openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement + fun updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement + fun createJsxSelfClosingElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun createJsxSelfClosingElement(tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun createJsxSelfClosingElement(tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun createJsxOpeningElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun createJsxOpeningElement(tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun createJsxOpeningElement(tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun createJsxClosingElement(tagName: Identifier): JsxClosingElement + fun createJsxClosingElement(tagName: ThisExpression): JsxClosingElement + fun createJsxClosingElement(tagName: JsxTagNamePropertyAccess): JsxClosingElement + fun updateJsxClosingElement(node: JsxClosingElement, tagName: Identifier): JsxClosingElement + fun updateJsxClosingElement(node: JsxClosingElement, tagName: ThisExpression): JsxClosingElement + fun updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNamePropertyAccess): JsxClosingElement + fun createJsxFragment(openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment): JsxFragment + fun createJsxText(text: String, containsOnlyTriviaWhiteSpaces: Boolean = definedExternally): JsxText + fun updateJsxText(node: JsxText, text: String, containsOnlyTriviaWhiteSpaces: Boolean = definedExternally): JsxText + fun createJsxOpeningFragment(): JsxOpeningFragment + fun createJsxJsxClosingFragment(): JsxClosingFragment + fun updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment): JsxFragment + fun createJsxAttribute(name: Identifier, initializer: StringLiteral?): JsxAttribute + fun createJsxAttribute(name: Identifier, initializer: JsxExpression?): JsxAttribute + fun updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral?): JsxAttribute + fun updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: JsxExpression?): JsxAttribute + fun createJsxAttributes(properties: Array): JsxAttributes + fun updateJsxAttributes(node: JsxAttributes, properties: Array): JsxAttributes + fun createJsxSpreadAttribute(expression: Expression): JsxSpreadAttribute + fun updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression): JsxSpreadAttribute + fun createJsxExpression(dotDotDotToken: DotDotDotToken?, expression: Expression?): JsxExpression + fun updateJsxExpression(node: JsxExpression, expression: Expression?): JsxExpression + fun createCaseClause(expression: Expression, statements: Array): CaseClause + fun updateCaseClause(node: CaseClause, expression: Expression, statements: Array): CaseClause + fun createDefaultClause(statements: Array): DefaultClause + fun updateDefaultClause(node: DefaultClause, statements: Array): DefaultClause + fun createHeritageClause(token: SyntaxKind.ExtendsKeyword, types: Array): HeritageClause + fun createHeritageClause(token: SyntaxKind.ImplementsKeyword, types: Array): HeritageClause + fun updateHeritageClause(node: HeritageClause, types: Array): HeritageClause + fun createCatchClause(variableDeclaration: String?, block: Block): CatchClause + fun createCatchClause(variableDeclaration: VariableDeclaration?, block: Block): CatchClause + fun updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration?, block: Block): CatchClause + fun createPropertyAssignment(name: String, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: Identifier, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: StringLiteral, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: NumericLiteral, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: ComputedPropertyName, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: PrivateIdentifier, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: Identifier, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: StringLiteral, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: NumericLiteral, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: ComputedPropertyName, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: PrivateIdentifier, initializer: Expression): PropertyAssignment + fun createShorthandPropertyAssignment(name: String, objectAssignmentInitializer: Expression = definedExternally): ShorthandPropertyAssignment + fun createShorthandPropertyAssignment(name: String): ShorthandPropertyAssignment + fun createShorthandPropertyAssignment(name: Identifier, objectAssignmentInitializer: Expression = definedExternally): ShorthandPropertyAssignment + fun createShorthandPropertyAssignment(name: Identifier): ShorthandPropertyAssignment + fun updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression?): ShorthandPropertyAssignment + fun createSpreadAssignment(expression: Expression): SpreadAssignment + fun updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment + fun createEnumMember(name: String, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: String): EnumMember + fun createEnumMember(name: Identifier, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: Identifier): EnumMember + fun createEnumMember(name: StringLiteral, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: StringLiteral): EnumMember + fun createEnumMember(name: NumericLiteral, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: NumericLiteral): EnumMember + fun createEnumMember(name: ComputedPropertyName, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: ComputedPropertyName): EnumMember + fun createEnumMember(name: PrivateIdentifier, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: PrivateIdentifier): EnumMember + fun updateEnumMember(node: EnumMember, name: Identifier, initializer: Expression?): EnumMember + fun updateEnumMember(node: EnumMember, name: StringLiteral, initializer: Expression?): EnumMember + fun updateEnumMember(node: EnumMember, name: NumericLiteral, initializer: Expression?): EnumMember + fun updateEnumMember(node: EnumMember, name: ComputedPropertyName, initializer: Expression?): EnumMember + fun updateEnumMember(node: EnumMember, name: PrivateIdentifier, initializer: Expression?): EnumMember + fun createSourceFile(statements: Array, endOfFileToken: Token /* Token & JSDocContainer */, flags: NodeFlags): SourceFile + fun updateSourceFile(node: SourceFile, statements: Array, isDeclarationFile: Boolean = definedExternally, referencedFiles: Array = definedExternally, typeReferences: Array = definedExternally, hasNoDefaultLib: Boolean = definedExternally, libReferences: Array = definedExternally): SourceFile + fun createNotEmittedStatement(original: Node): NotEmittedStatement + fun createPartiallyEmittedExpression(expression: Expression, original: Node = definedExternally): PartiallyEmittedExpression + fun updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression): PartiallyEmittedExpression + fun createCommaListExpression(elements: Array): CommaListExpression + fun updateCommaListExpression(node: CommaListExpression, elements: Array): CommaListExpression + fun createBundle(sourceFiles: Array, prepends: Array = definedExternally): Bundle + fun updateBundle(node: Bundle, sourceFiles: Array, prepends: Array = definedExternally): Bundle + fun createComma(left: Expression, right: Expression): BinaryExpression + fun createAssignment(left: ObjectLiteralExpression, right: Expression): dynamic /* ObjectDestructuringAssignment | ArrayDestructuringAssignment */ + fun createAssignment(left: ArrayLiteralExpression, right: Expression): dynamic /* ObjectDestructuringAssignment | ArrayDestructuringAssignment */ + fun createAssignment(left: Expression, right: Expression): AssignmentExpression + fun createLogicalOr(left: Expression, right: Expression): BinaryExpression + fun createLogicalAnd(left: Expression, right: Expression): BinaryExpression + fun createBitwiseOr(left: Expression, right: Expression): BinaryExpression + fun createBitwiseXor(left: Expression, right: Expression): BinaryExpression + fun createBitwiseAnd(left: Expression, right: Expression): BinaryExpression + fun createStrictEquality(left: Expression, right: Expression): BinaryExpression + fun createStrictInequality(left: Expression, right: Expression): BinaryExpression + fun createEquality(left: Expression, right: Expression): BinaryExpression + fun createInequality(left: Expression, right: Expression): BinaryExpression + fun createLessThan(left: Expression, right: Expression): BinaryExpression + fun createLessThanEquals(left: Expression, right: Expression): BinaryExpression + fun createGreaterThan(left: Expression, right: Expression): BinaryExpression + fun createGreaterThanEquals(left: Expression, right: Expression): BinaryExpression + fun createLeftShift(left: Expression, right: Expression): BinaryExpression + fun createRightShift(left: Expression, right: Expression): BinaryExpression + fun createUnsignedRightShift(left: Expression, right: Expression): BinaryExpression + fun createAdd(left: Expression, right: Expression): BinaryExpression + fun createSubtract(left: Expression, right: Expression): BinaryExpression + fun createMultiply(left: Expression, right: Expression): BinaryExpression + fun createDivide(left: Expression, right: Expression): BinaryExpression + fun createModulo(left: Expression, right: Expression): BinaryExpression + fun createExponent(left: Expression, right: Expression): BinaryExpression + fun createPrefixPlus(operand: Expression): PrefixUnaryExpression + fun createPrefixMinus(operand: Expression): PrefixUnaryExpression + fun createPrefixIncrement(operand: Expression): PrefixUnaryExpression + fun createPrefixDecrement(operand: Expression): PrefixUnaryExpression + fun createBitwiseNot(operand: Expression): PrefixUnaryExpression + fun createLogicalNot(operand: Expression): PrefixUnaryExpression + fun createPostfixIncrement(operand: Expression): PostfixUnaryExpression + fun createPostfixDecrement(operand: Expression): PostfixUnaryExpression + fun createImmediatelyInvokedFunctionExpression(statements: Array): CallExpression + fun createImmediatelyInvokedFunctionExpression(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression + fun createImmediatelyInvokedArrowFunction(statements: Array): CallExpression + fun createImmediatelyInvokedArrowFunction(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression + fun createVoidZero(): VoidExpression + fun createExportDefault(expression: Expression): ExportAssignment + fun createExternalModuleExport(exportName: Identifier): ExportDeclaration + fun restoreOuterExpressions(outerExpression: Expression?, innerExpression: Expression, kinds: OuterExpressionKinds = definedExternally): Expression +} + +external interface CoreTransformationContext { + val factory: NodeFactory + fun getCompilerOptions(): CompilerOptions + fun startLexicalEnvironment() + fun suspendLexicalEnvironment() + fun resumeLexicalEnvironment() + fun endLexicalEnvironment(): Array? + fun hoistFunctionDeclaration(node: FunctionDeclaration) + fun hoistVariableDeclaration(node: Identifier) +} + +external interface TransformationContext : CoreTransformationContext { + fun requestEmitHelper(helper: ScopedEmitHelper) + fun requestEmitHelper(helper: UnscopedEmitHelper) + fun readEmitHelpers(): Array? + fun enableSubstitution(kind: SyntaxKind) + fun isSubstitutionEnabled(node: Node): Boolean + var onSubstituteNode: (hint: EmitHint, node: Node) -> Node + fun enableEmitNotification(kind: SyntaxKind) + fun isEmitNotificationEnabled(node: Node): Boolean + var onEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) -> Unit +} + +external interface TransformationResult { + var transformed: Array + var diagnostics: Array? + get() = definedExternally + set(value) = definedExternally + fun substituteNode(hint: EmitHint, node: Node): Node + fun emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) + val isEmitNotificationEnabled: ((node: Node) -> Boolean)? + fun dispose() +} + +external interface NodeVisitor { + @nativeInvoke + operator fun invoke(nodes: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T + @nativeInvoke + operator fun invoke(nodes: T, visitor: Visitor?): T + @nativeInvoke + operator fun invoke(nodes: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T + @nativeInvoke + operator fun invoke(nodes: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T? + @nativeInvoke + operator fun invoke(nodes: T?, visitor: Visitor?): T? + @nativeInvoke + operator fun invoke(nodes: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T? +} + +external interface NodesVisitor { + @nativeInvoke + operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray + @nativeInvoke + operator fun invoke(nodes: NodeArray, visitor: Visitor?): NodeArray + @nativeInvoke + operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray + @nativeInvoke + operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray + @nativeInvoke + operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray? + @nativeInvoke + operator fun invoke(nodes: NodeArray?, visitor: Visitor?): NodeArray? + @nativeInvoke + operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray? + @nativeInvoke + operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray? +} + +external interface Printer { + fun printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): String + fun printList(format: ListFormat, list: NodeArray, sourceFile: SourceFile): String + fun printFile(sourceFile: SourceFile): String + fun printBundle(bundle: Bundle): String +} + +external interface PrintHandlers { + val hasGlobalName: ((name: String) -> Boolean)? + val onEmitNode: ((hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) -> Unit)? + val isEmitNotificationEnabled: ((node: Node) -> Boolean)? + val substituteNode: ((hint: EmitHint, node: Node) -> Node)? +} + +external interface PrinterOptions { + var removeComments: Boolean? + get() = definedExternally + set(value) = definedExternally + var newLine: NewLineKind? + get() = definedExternally + set(value) = definedExternally + var omitTrailingSemicolon: Boolean? + get() = definedExternally + set(value) = definedExternally + var noEmitHelpers: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface GetEffectiveTypeRootsHost { + val directoryExists: ((directoryName: String) -> Boolean)? + val getCurrentDirectory: (() -> String)? +} + +external interface TextSpan { + var start: Number + var length: Number +} + +external interface TextChangeRange { + var span: TextSpan + var newLength: Number +} + +external interface SyntaxList : Node { + var _children: Array +} + +external enum class ListFormat { + None /* = 0 */, + SingleLine /* = 0 */, + MultiLine /* = 1 */, + PreserveLines /* = 2 */, + LinesMask /* = 3 */, + NotDelimited /* = 0 */, + BarDelimited /* = 4 */, + AmpersandDelimited /* = 8 */, + CommaDelimited /* = 16 */, + AsteriskDelimited /* = 32 */, + DelimitersMask /* = 60 */, + AllowTrailingComma /* = 64 */, + Indented /* = 128 */, + SpaceBetweenBraces /* = 256 */, + SpaceBetweenSiblings /* = 512 */, + Braces /* = 1024 */, + Parenthesis /* = 2048 */, + AngleBrackets /* = 4096 */, + SquareBrackets /* = 8192 */, + BracketsMask /* = 15360 */, + OptionalIfUndefined /* = 16384 */, + OptionalIfEmpty /* = 32768 */, + Optional /* = 49152 */, + PreferNewLine /* = 65536 */, + NoTrailingNewLine /* = 131072 */, + NoInterveningComments /* = 262144 */, + NoSpaceIfEmpty /* = 524288 */, + SingleElement /* = 1048576 */, + SpaceAfterList /* = 2097152 */, + Modifiers /* = 262656 */, + HeritageClauses /* = 512 */, + SingleLineTypeLiteralMembers /* = 768 */, + MultiLineTypeLiteralMembers /* = 32897 */, + SingleLineTupleTypeElements /* = 528 */, + MultiLineTupleTypeElements /* = 657 */, + UnionTypeConstituents /* = 516 */, + IntersectionTypeConstituents /* = 520 */, + ObjectBindingPatternElements /* = 525136 */, + ArrayBindingPatternElements /* = 524880 */, + ObjectLiteralExpressionProperties /* = 526226 */, + ArrayLiteralExpressionElements /* = 8914 */, + CommaListElements /* = 528 */, + CallExpressionArguments /* = 2576 */, + NewExpressionArguments /* = 18960 */, + TemplateExpressionSpans /* = 262144 */, + SingleLineBlockStatements /* = 768 */, + MultiLineBlockStatements /* = 129 */, + VariableDeclarationList /* = 528 */, + SingleLineFunctionBodyStatements /* = 768 */, + MultiLineFunctionBodyStatements /* = 1 */, + ClassHeritageClauses /* = 0 */, + ClassMembers /* = 129 */, + InterfaceMembers /* = 129 */, + EnumMembers /* = 145 */, + CaseBlockClauses /* = 129 */, + NamedImportsOrExportsElements /* = 525136 */, + JsxElementOrFragmentChildren /* = 262144 */, + JsxElementAttributes /* = 262656 */, + CaseOrDefaultClauseStatements /* = 163969 */, + HeritageClauseTypes /* = 528 */, + SourceFileStatements /* = 131073 */, + Decorators /* = 2146305 */, + TypeArguments /* = 53776 */, + TypeParameters /* = 53776 */, + Parameters /* = 2576 */, + IndexSignatureParameters /* = 8848 */, + JSDocComment /* = 33 */ +} + +external interface UserPreferences { + val disableSuggestions: Boolean? + get() = definedExternally + val quotePreference: String? /* "auto" | "double" | "single" */ + get() = definedExternally + val includeCompletionsForModuleExports: Boolean? + get() = definedExternally + val includeCompletionsForImportStatements: Boolean? + get() = definedExternally + val includeCompletionsWithSnippetText: Boolean? + get() = definedExternally + val includeAutomaticOptionalChainCompletions: Boolean? + get() = definedExternally + val includeCompletionsWithInsertText: Boolean? + get() = definedExternally + val allowIncompleteCompletions: Boolean? + get() = definedExternally + val importModuleSpecifierPreference: String? /* "shortest" | "project-relative" | "relative" | "non-relative" */ + get() = definedExternally + val importModuleSpecifierEnding: String? /* "auto" | "minimal" | "index" | "js" */ + get() = definedExternally + val allowTextChangesInNewFiles: Boolean? + get() = definedExternally + val providePrefixAndSuffixTextForRename: Boolean? + get() = definedExternally + val includePackageJsonAutoImports: String? /* "auto" | "on" | "off" */ + get() = definedExternally + val provideRefactorNotApplicableReason: Boolean? + get() = definedExternally +} + +external interface PseudoBigInt { + var negative: Boolean + var base10Value: String +} + +external enum class FileWatcherEventKind { + Created /* = 0 */, + Changed /* = 1 */, + Deleted /* = 2 */ +} + +external interface System { + var args: Array + var newLine: String + var useCaseSensitiveFileNames: Boolean + fun write(s: String) + val writeOutputIsTTY: (() -> Boolean)? + val getWidthOfTerminal: (() -> Number)? + fun readFile(path: String, encoding: String = definedExternally): String? + val getFileSize: ((path: String) -> Number)? + fun writeFile(path: String, data: String, writeByteOrderMark: Boolean = definedExternally) + val watchFile: ((path: String, callback: FileWatcherCallback, pollingInterval: Number, options: WatchOptions) -> FileWatcher)? + val watchDirectory: ((path: String, callback: DirectoryWatcherCallback, recursive: Boolean, options: WatchOptions) -> FileWatcher)? + fun resolvePath(path: String): String + fun fileExists(path: String): Boolean + fun directoryExists(path: String): Boolean + fun createDirectory(path: String) + fun getExecutingFilePath(): String + fun getCurrentDirectory(): String + fun getDirectories(path: String): Array + fun readDirectory(path: String, extensions: Array = definedExternally, exclude: Array = definedExternally, include: Array = definedExternally, depth: Number = definedExternally): Array + val getModifiedTime: ((path: String) -> Date?)? + val setModifiedTime: ((path: String, time: Date) -> Unit)? + val deleteFile: ((path: String) -> Unit)? + val createHash: ((data: String) -> String)? + val createSHA256Hash: ((data: String) -> String)? + val getMemoryUsage: (() -> Number)? + fun exit(exitCode: Number = definedExternally) + val realpath: ((path: String) -> String)? + val setTimeout: ((callback: (args: Any) -> Unit, ms: Number, args: Any) -> Any)? + val clearTimeout: ((timeoutId: Any) -> Unit)? + val clearScreen: (() -> Unit)? + val base64decode: ((input: String) -> String)? + val base64encode: ((input: String) -> String)? +} + +external interface FileWatcher { + fun close() +} + +external fun getNodeMajorVersion(): Number? + +external var sys: System + +external interface Scanner { + fun getStartPos(): Number + fun getToken(): SyntaxKind + fun getTextPos(): Number + fun getTokenPos(): Number + fun getTokenText(): String + fun getTokenValue(): String + fun hasUnicodeEscape(): Boolean + fun hasExtendedUnicodeEscape(): Boolean + fun hasPrecedingLineBreak(): Boolean + fun isIdentifier(): Boolean + fun isReservedWord(): Boolean + fun isUnterminated(): Boolean + fun reScanGreaterToken(): SyntaxKind + fun reScanSlashToken(): SyntaxKind + fun reScanAsteriskEqualsToken(): SyntaxKind + fun reScanTemplateToken(isTaggedTemplate: Boolean): SyntaxKind + fun reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind + fun scanJsxIdentifier(): SyntaxKind + fun scanJsxAttributeValue(): SyntaxKind + fun reScanJsxAttributeValue(): SyntaxKind + fun reScanJsxToken(allowMultilineJsxText: Boolean = definedExternally): dynamic /* SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken */ + fun reScanLessThanToken(): SyntaxKind + fun reScanHashToken(): SyntaxKind + fun reScanQuestionToken(): SyntaxKind + fun reScanInvalidIdentifier(): SyntaxKind + fun scanJsxToken(): dynamic /* SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken */ + fun scanJsDocToken(): dynamic /* SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.HashToken | SyntaxKind.Unknown | SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IntrinsicKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.OverrideKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword */ + fun scan(): SyntaxKind + fun getText(): String + fun setText(text: String?, start: Number = definedExternally, length: Number = definedExternally) + fun setOnError(onError: ErrorCallback?) + fun setScriptTarget(scriptTarget: ScriptTarget) + fun setLanguageVariant(variant: LanguageVariant) + fun setTextPos(textPos: Number) + fun lookAhead(callback: () -> T): T + fun scanRange(start: Number, length: Number, callback: () -> T): T + fun tryScan(callback: () -> T): T +} + +external fun tokenToString(t: SyntaxKind): String? + +external fun getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: Number, character: Number): Number + +external fun getLineAndCharacterOfPosition(sourceFile: SourceFileLike, position: Number): LineAndCharacter + +external fun isWhiteSpaceLike(ch: Number): Boolean + +external fun isWhiteSpaceSingleLine(ch: Number): Boolean + +external fun isLineBreak(ch: Number): Boolean + +external fun couldStartTrivia(text: String, pos: Number): Boolean + +external fun forEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean) -> U): U? + +external fun forEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T) -> U, state: T): U? + +external fun forEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean) -> U): U? + +external fun forEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T) -> U, state: T): U? + +external fun reduceEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T, memo: U) -> U, state: T, initial: U): U? + +external fun reduceEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T, memo: U) -> U, state: T, initial: U): U? + +external fun getLeadingCommentRanges(text: String, pos: Number): Array? + +external fun getTrailingCommentRanges(text: String, pos: Number): Array? + +external fun getShebang(text: String): String? + +external fun isIdentifierStart(ch: Number, languageVersion: ScriptTarget?): Boolean + +external fun isIdentifierPart(ch: Number, languageVersion: ScriptTarget?, identifierVariant: LanguageVariant = definedExternally): Boolean + +external fun createScanner(languageVersion: ScriptTarget, skipTrivia: Boolean, languageVariant: LanguageVariant = definedExternally, textInitial: String = definedExternally, onError: ErrorCallback = definedExternally, start: Number = definedExternally, length: Number = definedExternally): Scanner + +external fun isExternalModuleNameRelative(moduleName: String): Boolean + +external fun sortAndDeduplicateDiagnostics(diagnostics: Array): SortedReadonlyArray + +external fun getDefaultLibFileName(options: CompilerOptions): String + +external fun textSpanEnd(span: TextSpan): Number + +external fun textSpanIsEmpty(span: TextSpan): Boolean + +external fun textSpanContainsPosition(span: TextSpan, position: Number): Boolean + +external fun textSpanContainsTextSpan(span: TextSpan, other: TextSpan): Boolean + +external fun textSpanOverlapsWith(span: TextSpan, other: TextSpan): Boolean + +external fun textSpanOverlap(span1: TextSpan, span2: TextSpan): TextSpan? + +external fun textSpanIntersectsWithTextSpan(span: TextSpan, other: TextSpan): Boolean + +external fun textSpanIntersectsWith(span: TextSpan, start: Number, length: Number): Boolean + +external fun decodedTextSpanIntersectsWith(start1: Number, length1: Number, start2: Number, length2: Number): Boolean + +external fun textSpanIntersectsWithPosition(span: TextSpan, position: Number): Boolean + +external fun textSpanIntersection(span1: TextSpan, span2: TextSpan): TextSpan? + +external fun createTextSpan(start: Number, length: Number): TextSpan + +external fun createTextSpanFromBounds(start: Number, end: Number): TextSpan + +external fun textChangeRangeNewSpan(range: TextChangeRange): TextSpan + +external fun textChangeRangeIsUnchanged(range: TextChangeRange): Boolean + +external fun createTextChangeRange(span: TextSpan, newLength: Number): TextChangeRange + +external var unchangedTextChangeRange: TextChangeRange + +external fun collapseTextChangeRangesAcrossMultipleVersions(changes: Array): TextChangeRange + +external fun getTypeParameterOwner(d: Declaration): Declaration? + +external interface `T$23` { + var parent: ConstructorDeclaration + var name: Identifier +} + +external fun isParameterPropertyDeclaration(node: Node, parent: Node): Boolean + +external fun isEmptyBindingPattern(node: Identifier): Boolean + +external fun isEmptyBindingPattern(node: ObjectBindingPattern): Boolean + +external fun isEmptyBindingPattern(node: ArrayBindingPattern): Boolean + +external fun isEmptyBindingElement(node: BindingElement): Boolean + +external fun walkUpBindingElementsAndPatterns(binding: BindingElement): dynamic /* VariableDeclaration | ParameterDeclaration */ + +external fun getCombinedModifierFlags(node: Declaration): ModifierFlags + +external fun getCombinedNodeFlags(node: Node): NodeFlags + +external interface `T$24` { + fun getExecutingFilePath(): String + fun resolvePath(path: String): String + fun fileExists(fileName: String): Boolean + fun readFile(fileName: String): String? +} + +external fun validateLocaleAndSetLanguage(locale: String, sys: `T$24`, errors: Push = definedExternally) + +external fun getOriginalNode(node: Node): Node + +external fun getOriginalNode(node: Node, nodeTest: (node: Node) -> Boolean): T + +external fun getOriginalNode(node: Node?): Node? + +external fun getOriginalNode(node: Node?, nodeTest: (node: Node?) -> Boolean): T? + +external fun findAncestor(node: Node?, callback: (element: Node) -> Boolean): T? + +external fun findAncestor(node: Node?, callback: (element: Node) -> Any): Node? + +external fun isParseTreeNode(node: Node): Boolean + +external fun getParseTreeNode(node: Node?): Node? + +external fun getParseTreeNode(node: T?, nodeTest: (node: Node) -> Boolean = definedExternally): T? + +external fun getParseTreeNode(node: T?): T? + +external fun escapeLeadingUnderscores(identifier: String): dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + +external fun unescapeLeadingUnderscores(identifier: String /* String & `T$8` */): String + +external fun unescapeLeadingUnderscores(identifier: Unit /* Unit & `T$8` */): String + +external fun unescapeLeadingUnderscores(identifier: InternalSymbolName): String + +external fun idText(identifierOrPrivateName: Identifier): String + +external fun idText(identifierOrPrivateName: PrivateIdentifier): String + +external fun symbolName(symbol: Symbol): String + +external fun getNameOfJSDocTypedef(declaration: JSDocTypedefTag): dynamic /* Identifier? | PrivateIdentifier? */ + +external fun getNameOfDeclaration(declaration: Declaration?): dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ + +external fun getNameOfDeclaration(declaration: Expression?): dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ + +external fun getJSDocParameterTags(param: ParameterDeclaration): Array + +external fun getJSDocTypeParameterTags(param: TypeParameterDeclaration): Array + +external fun hasJSDocParameterTags(node: FunctionDeclaration): Boolean + +external fun hasJSDocParameterTags(node: MethodDeclaration): Boolean + +external fun hasJSDocParameterTags(node: GetAccessorDeclaration): Boolean + +external fun hasJSDocParameterTags(node: SetAccessorDeclaration): Boolean + +external fun hasJSDocParameterTags(node: ConstructorDeclaration): Boolean + +external fun hasJSDocParameterTags(node: FunctionExpression): Boolean + +external fun hasJSDocParameterTags(node: ArrowFunction): Boolean + +external fun hasJSDocParameterTags(node: CallSignatureDeclaration): Boolean + +external fun hasJSDocParameterTags(node: ConstructSignatureDeclaration): Boolean + +external fun hasJSDocParameterTags(node: MethodSignature): Boolean + +external fun hasJSDocParameterTags(node: IndexSignatureDeclaration): Boolean + +external fun hasJSDocParameterTags(node: FunctionTypeNode): Boolean + +external fun hasJSDocParameterTags(node: ConstructorTypeNode): Boolean + +external fun hasJSDocParameterTags(node: JSDocFunctionType): Boolean + +external fun getJSDocAugmentsTag(node: Node): JSDocAugmentsTag? + +external fun getJSDocImplementsTags(node: Node): Array + +external fun getJSDocClassTag(node: Node): JSDocClassTag? + +external fun getJSDocPublicTag(node: Node): JSDocPublicTag? + +external fun getJSDocPrivateTag(node: Node): JSDocPrivateTag? + +external fun getJSDocProtectedTag(node: Node): JSDocProtectedTag? + +external fun getJSDocReadonlyTag(node: Node): JSDocReadonlyTag? + +external fun getJSDocOverrideTagNoCache(node: Node): JSDocOverrideTag? + +external fun getJSDocDeprecatedTag(node: Node): JSDocDeprecatedTag? + +external fun getJSDocEnumTag(node: Node): JSDocEnumTag? + +external fun getJSDocThisTag(node: Node): JSDocThisTag? + +external fun getJSDocReturnTag(node: Node): JSDocReturnTag? + +external fun getJSDocTemplateTag(node: Node): JSDocTemplateTag? + +external fun getJSDocTypeTag(node: Node): JSDocTypeTag? + +external fun getJSDocType(node: Node): TypeNode? + +external fun getJSDocReturnType(node: Node): TypeNode? + +external fun getJSDocTags(node: Node): Array + +external fun getAllJSDocTags(node: Node, predicate: (tag: JSDocTag) -> Boolean): Array + +external fun getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): Array + +external fun getTextOfJSDocComment(comment: String = definedExternally): String? + +external fun getTextOfJSDocComment(): String? + +external fun getTextOfJSDocComment(comment: NodeArray = definedExternally): String? + +external fun getEffectiveTypeParameterDeclarations(node: Any /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature */): Array + +external fun getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode? + +external fun isMemberName(node: Node): Boolean + +external fun isPropertyAccessChain(node: Node): Boolean + +external fun isElementAccessChain(node: Node): Boolean + +external fun isCallChain(node: Node): Boolean + +external fun isOptionalChain(node: Node): Boolean + +external fun isNullishCoalesce(node: Node): Boolean + +external fun isConstTypeReference(node: Node): Boolean + +external fun skipPartiallyEmittedExpressions(node: Expression): Expression + +external fun skipPartiallyEmittedExpressions(node: Node): Node + +external fun isNonNullChain(node: Node): Boolean + +external fun isBreakOrContinueStatement(node: Node): Boolean + +external fun isNamedExportBindings(node: Node): Boolean + +external fun isUnparsedTextLike(node: Node): Boolean + +external fun isUnparsedNode(node: Node): Boolean + +external fun isJSDocPropertyLikeTag(node: Node): Boolean + +external fun isTokenKind(kind: SyntaxKind): Boolean + +external fun isToken(n: Node): Boolean + +external fun isLiteralExpression(node: Node): Boolean + +external fun isTemplateLiteralToken(node: Node): Boolean + +external fun isTemplateMiddleOrTemplateTail(node: Node): Boolean + +external fun isImportOrExportSpecifier(node: Node): Boolean + +external fun isTypeOnlyImportOrExportDeclaration(node: Node): Boolean + +external fun isStringTextContainingNode(node: Node): Boolean + +external fun isModifier(node: Node): Boolean + +external fun isEntityName(node: Node): Boolean + +external fun isPropertyName(node: Node): Boolean + +external fun isBindingName(node: Node): Boolean + +external fun isFunctionLike(node: Node?): Boolean + +external fun isClassElement(node: Node): Boolean + +external fun isClassLike(node: Node): Boolean + +external fun isAccessor(node: Node): Boolean + +external fun isTypeElement(node: Node): Boolean + +external fun isClassOrTypeElement(node: Node): Boolean + +external fun isObjectLiteralElementLike(node: Node): Boolean + +external fun isTypeNode(node: Node): Boolean + +external fun isFunctionOrConstructorTypeNode(node: Node): Boolean + +external fun isPropertyAccessOrQualifiedName(node: Node): Boolean + +external fun isCallLikeExpression(node: Node): Boolean + +external fun isCallOrNewExpression(node: Node): Boolean + +external fun isTemplateLiteral(node: Node): Boolean + +external fun isAssertionExpression(node: Node): Boolean + +external fun isIterationStatement(node: Node, lookInLabeledStatements: Boolean): Boolean + +external fun isJsxOpeningLikeElement(node: Node): Boolean + +external fun isCaseOrDefaultClause(node: Node): Boolean + +external fun isJSDocCommentContainingNode(node: Node): Boolean + +external fun isSetAccessor(node: Node): Boolean + +external fun isGetAccessor(node: Node): Boolean + +external fun hasOnlyExpressionInitializer(node: Node): Boolean + +external fun isObjectLiteralElement(node: Node): Boolean + +external fun isStringLiteralLike(node: Node): Boolean + +external fun isJSDocLinkLike(node: Node): Boolean + +external var factory: NodeFactory + +external fun createUnparsedSourceFile(text: String): UnparsedSource + +external fun createUnparsedSourceFile(inputFile: InputFiles, type: String /* "js" | "dts" */, stripInternal: Boolean = definedExternally): UnparsedSource + +external fun createUnparsedSourceFile(inputFile: InputFiles, type: String /* "js" | "dts" */): UnparsedSource + +external fun createUnparsedSourceFile(text: String, mapPath: String?, map: String?): UnparsedSource + +external fun createInputFiles(javascriptText: String, declarationText: String): InputFiles + +external fun createInputFiles(readFileText: (path: String) -> String?, javascriptPath: String, javascriptMapPath: String?, declarationPath: String, declarationMapPath: String?, buildInfoPath: String?): InputFiles + +external fun createInputFiles(javascriptText: String, declarationText: String, javascriptMapPath: String?, javascriptMapText: String?, declarationMapPath: String?, declarationMapText: String?): InputFiles + +external fun createSourceMapSource(fileName: String, text: String, skipTrivia: (pos: Number) -> Number = definedExternally): SourceMapSource + +external fun setOriginalNode(node: T, original: Node?): T + +external fun disposeEmitNodes(sourceFile: SourceFile?) + +external fun setEmitFlags(node: T, emitFlags: EmitFlags): T + +external fun getSourceMapRange(node: Node): SourceMapRange + +external fun setSourceMapRange(node: T, range: SourceMapRange?): T + +external fun getTokenSourceMapRange(node: Node, token: SyntaxKind): SourceMapRange? + +external fun setTokenSourceMapRange(node: T, token: SyntaxKind, range: SourceMapRange?): T + +external fun getCommentRange(node: Node): TextRange + +external fun setCommentRange(node: T, range: TextRange): T + +external fun getSyntheticLeadingComments(node: Node): Array? + +external fun setSyntheticLeadingComments(node: T, comments: Array?): T + +external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T + +external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String): T + +external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T + +external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String): T + +external fun getSyntheticTrailingComments(node: Node): Array? + +external fun setSyntheticTrailingComments(node: T, comments: Array?): T + +external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T + +external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String): T + +external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T + +external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String): T + +external fun moveSyntheticComments(node: T, original: Node): T + +external fun getConstantValue(node: PropertyAccessExpression): dynamic /* String? | Number? */ + +external fun getConstantValue(node: ElementAccessExpression): dynamic /* String? | Number? */ + +external fun setConstantValue(node: PropertyAccessExpression, value: String): dynamic /* PropertyAccessExpression | ElementAccessExpression */ + +external fun setConstantValue(node: PropertyAccessExpression, value: Number): dynamic /* PropertyAccessExpression | ElementAccessExpression */ + +external fun setConstantValue(node: ElementAccessExpression, value: String): dynamic /* PropertyAccessExpression | ElementAccessExpression */ + +external fun setConstantValue(node: ElementAccessExpression, value: Number): dynamic /* PropertyAccessExpression | ElementAccessExpression */ + +external fun addEmitHelper(node: T, helper: ScopedEmitHelper): T + +external fun addEmitHelper(node: T, helper: UnscopedEmitHelper): T + +external fun addEmitHelpers(node: T, helpers: Array?): T + +external fun removeEmitHelper(node: Node, helper: ScopedEmitHelper): Boolean + +external fun removeEmitHelper(node: Node, helper: UnscopedEmitHelper): Boolean + +external fun getEmitHelpers(node: Node): Array? + +external fun moveEmitHelpers(source: Node, target: Node, predicate: (helper: Any /* ScopedEmitHelper | UnscopedEmitHelper */) -> Boolean) + +external fun isNumericLiteral(node: Node): Boolean + +external fun isBigIntLiteral(node: Node): Boolean + +external fun isStringLiteral(node: Node): Boolean + +external fun isJsxText(node: Node): Boolean + +external fun isRegularExpressionLiteral(node: Node): Boolean + +external fun isNoSubstitutionTemplateLiteral(node: Node): Boolean + +external fun isTemplateHead(node: Node): Boolean + +external fun isTemplateMiddle(node: Node): Boolean + +external fun isTemplateTail(node: Node): Boolean + +external fun isDotDotDotToken(node: Node): Boolean + +external fun isPlusToken(node: Node): Boolean + +external fun isMinusToken(node: Node): Boolean + +external fun isAsteriskToken(node: Node): Boolean + +external fun isIdentifier(node: Node): Boolean + +external fun isPrivateIdentifier(node: Node): Boolean + +external fun isQualifiedName(node: Node): Boolean + +external fun isComputedPropertyName(node: Node): Boolean + +external fun isTypeParameterDeclaration(node: Node): Boolean + +external fun isParameter(node: Node): Boolean + +external fun isDecorator(node: Node): Boolean + +external fun isPropertySignature(node: Node): Boolean + +external fun isPropertyDeclaration(node: Node): Boolean + +external fun isMethodSignature(node: Node): Boolean + +external fun isMethodDeclaration(node: Node): Boolean + +external fun isClassStaticBlockDeclaration(node: Node): Boolean + +external fun isConstructorDeclaration(node: Node): Boolean + +external fun isGetAccessorDeclaration(node: Node): Boolean + +external fun isSetAccessorDeclaration(node: Node): Boolean + +external fun isCallSignatureDeclaration(node: Node): Boolean + +external fun isConstructSignatureDeclaration(node: Node): Boolean + +external fun isIndexSignatureDeclaration(node: Node): Boolean + +external fun isTypePredicateNode(node: Node): Boolean + +external fun isTypeReferenceNode(node: Node): Boolean + +external fun isFunctionTypeNode(node: Node): Boolean + +external fun isConstructorTypeNode(node: Node): Boolean + +external fun isTypeQueryNode(node: Node): Boolean + +external fun isTypeLiteralNode(node: Node): Boolean + +external fun isArrayTypeNode(node: Node): Boolean + +external fun isTupleTypeNode(node: Node): Boolean + +external fun isNamedTupleMember(node: Node): Boolean + +external fun isOptionalTypeNode(node: Node): Boolean + +external fun isRestTypeNode(node: Node): Boolean + +external fun isUnionTypeNode(node: Node): Boolean + +external fun isIntersectionTypeNode(node: Node): Boolean + +external fun isConditionalTypeNode(node: Node): Boolean + +external fun isInferTypeNode(node: Node): Boolean + +external fun isParenthesizedTypeNode(node: Node): Boolean + +external fun isThisTypeNode(node: Node): Boolean + +external fun isTypeOperatorNode(node: Node): Boolean + +external fun isIndexedAccessTypeNode(node: Node): Boolean + +external fun isMappedTypeNode(node: Node): Boolean + +external fun isLiteralTypeNode(node: Node): Boolean + +external fun isImportTypeNode(node: Node): Boolean + +external fun isTemplateLiteralTypeSpan(node: Node): Boolean + +external fun isTemplateLiteralTypeNode(node: Node): Boolean + +external fun isObjectBindingPattern(node: Node): Boolean + +external fun isArrayBindingPattern(node: Node): Boolean + +external fun isBindingElement(node: Node): Boolean + +external fun isArrayLiteralExpression(node: Node): Boolean + +external fun isObjectLiteralExpression(node: Node): Boolean + +external fun isPropertyAccessExpression(node: Node): Boolean + +external fun isElementAccessExpression(node: Node): Boolean + +external fun isCallExpression(node: Node): Boolean + +external fun isNewExpression(node: Node): Boolean + +external fun isTaggedTemplateExpression(node: Node): Boolean + +external fun isTypeAssertionExpression(node: Node): Boolean + +external fun isParenthesizedExpression(node: Node): Boolean + +external fun isFunctionExpression(node: Node): Boolean + +external fun isArrowFunction(node: Node): Boolean + +external fun isDeleteExpression(node: Node): Boolean + +external fun isTypeOfExpression(node: Node): Boolean + +external fun isVoidExpression(node: Node): Boolean + +external fun isAwaitExpression(node: Node): Boolean + +external fun isPrefixUnaryExpression(node: Node): Boolean + +external fun isPostfixUnaryExpression(node: Node): Boolean + +external fun isBinaryExpression(node: Node): Boolean + +external fun isConditionalExpression(node: Node): Boolean + +external fun isTemplateExpression(node: Node): Boolean + +external fun isYieldExpression(node: Node): Boolean + +external fun isSpreadElement(node: Node): Boolean + +external fun isClassExpression(node: Node): Boolean + +external fun isOmittedExpression(node: Node): Boolean + +external fun isExpressionWithTypeArguments(node: Node): Boolean + +external fun isAsExpression(node: Node): Boolean + +external fun isNonNullExpression(node: Node): Boolean + +external fun isMetaProperty(node: Node): Boolean + +external fun isSyntheticExpression(node: Node): Boolean + +external fun isPartiallyEmittedExpression(node: Node): Boolean + +external fun isCommaListExpression(node: Node): Boolean + +external fun isTemplateSpan(node: Node): Boolean + +external fun isSemicolonClassElement(node: Node): Boolean + +external fun isBlock(node: Node): Boolean + +external fun isVariableStatement(node: Node): Boolean + +external fun isEmptyStatement(node: Node): Boolean + +external fun isExpressionStatement(node: Node): Boolean + +external fun isIfStatement(node: Node): Boolean + +external fun isDoStatement(node: Node): Boolean + +external fun isWhileStatement(node: Node): Boolean + +external fun isForStatement(node: Node): Boolean + +external fun isForInStatement(node: Node): Boolean + +external fun isForOfStatement(node: Node): Boolean + +external fun isContinueStatement(node: Node): Boolean + +external fun isBreakStatement(node: Node): Boolean + +external fun isReturnStatement(node: Node): Boolean + +external fun isWithStatement(node: Node): Boolean + +external fun isSwitchStatement(node: Node): Boolean + +external fun isLabeledStatement(node: Node): Boolean + +external fun isThrowStatement(node: Node): Boolean + +external fun isTryStatement(node: Node): Boolean + +external fun isDebuggerStatement(node: Node): Boolean + +external fun isVariableDeclaration(node: Node): Boolean + +external fun isVariableDeclarationList(node: Node): Boolean + +external fun isFunctionDeclaration(node: Node): Boolean + +external fun isClassDeclaration(node: Node): Boolean + +external fun isInterfaceDeclaration(node: Node): Boolean + +external fun isTypeAliasDeclaration(node: Node): Boolean + +external fun isEnumDeclaration(node: Node): Boolean + +external fun isModuleDeclaration(node: Node): Boolean + +external fun isModuleBlock(node: Node): Boolean + +external fun isCaseBlock(node: Node): Boolean + +external fun isNamespaceExportDeclaration(node: Node): Boolean + +external fun isImportEqualsDeclaration(node: Node): Boolean + +external fun isImportDeclaration(node: Node): Boolean + +external fun isImportClause(node: Node): Boolean + +external fun isNamespaceImport(node: Node): Boolean + +external fun isNamespaceExport(node: Node): Boolean + +external fun isNamedImports(node: Node): Boolean + +external fun isImportSpecifier(node: Node): Boolean + +external fun isExportAssignment(node: Node): Boolean + +external fun isExportDeclaration(node: Node): Boolean + +external fun isNamedExports(node: Node): Boolean + +external fun isExportSpecifier(node: Node): Boolean + +external fun isMissingDeclaration(node: Node): Boolean + +external fun isNotEmittedStatement(node: Node): Boolean + +external fun isExternalModuleReference(node: Node): Boolean + +external fun isJsxElement(node: Node): Boolean + +external fun isJsxSelfClosingElement(node: Node): Boolean + +external fun isJsxOpeningElement(node: Node): Boolean + +external fun isJsxClosingElement(node: Node): Boolean + +external fun isJsxFragment(node: Node): Boolean + +external fun isJsxOpeningFragment(node: Node): Boolean + +external fun isJsxClosingFragment(node: Node): Boolean + +external fun isJsxAttribute(node: Node): Boolean + +external fun isJsxAttributes(node: Node): Boolean + +external fun isJsxSpreadAttribute(node: Node): Boolean + +external fun isJsxExpression(node: Node): Boolean + +external fun isCaseClause(node: Node): Boolean + +external fun isDefaultClause(node: Node): Boolean + +external fun isHeritageClause(node: Node): Boolean + +external fun isCatchClause(node: Node): Boolean + +external fun isPropertyAssignment(node: Node): Boolean + +external fun isShorthandPropertyAssignment(node: Node): Boolean + +external fun isSpreadAssignment(node: Node): Boolean + +external fun isEnumMember(node: Node): Boolean + +external fun isUnparsedPrepend(node: Node): Boolean + +external fun isSourceFile(node: Node): Boolean + +external fun isBundle(node: Node): Boolean + +external fun isUnparsedSource(node: Node): Boolean + +external fun isJSDocTypeExpression(node: Node): Boolean + +external fun isJSDocNameReference(node: Node): Boolean + +external fun isJSDocMemberName(node: Node): Boolean + +external fun isJSDocLink(node: Node): Boolean + +external fun isJSDocLinkCode(node: Node): Boolean + +external fun isJSDocLinkPlain(node: Node): Boolean + +external fun isJSDocAllType(node: Node): Boolean + +external fun isJSDocUnknownType(node: Node): Boolean + +external fun isJSDocNullableType(node: Node): Boolean + +external fun isJSDocNonNullableType(node: Node): Boolean + +external fun isJSDocOptionalType(node: Node): Boolean + +external fun isJSDocFunctionType(node: Node): Boolean + +external fun isJSDocVariadicType(node: Node): Boolean + +external fun isJSDocNamepathType(node: Node): Boolean + +external fun isJSDoc(node: Node): Boolean + +external fun isJSDocTypeLiteral(node: Node): Boolean + +external fun isJSDocSignature(node: Node): Boolean + +external fun isJSDocAugmentsTag(node: Node): Boolean + +external fun isJSDocAuthorTag(node: Node): Boolean + +external fun isJSDocClassTag(node: Node): Boolean + +external fun isJSDocCallbackTag(node: Node): Boolean + +external fun isJSDocPublicTag(node: Node): Boolean + +external fun isJSDocPrivateTag(node: Node): Boolean + +external fun isJSDocProtectedTag(node: Node): Boolean + +external fun isJSDocReadonlyTag(node: Node): Boolean + +external fun isJSDocOverrideTag(node: Node): Boolean + +external fun isJSDocDeprecatedTag(node: Node): Boolean + +external fun isJSDocSeeTag(node: Node): Boolean + +external fun isJSDocEnumTag(node: Node): Boolean + +external fun isJSDocParameterTag(node: Node): Boolean + +external fun isJSDocReturnTag(node: Node): Boolean + +external fun isJSDocThisTag(node: Node): Boolean + +external fun isJSDocTypeTag(node: Node): Boolean + +external fun isJSDocTemplateTag(node: Node): Boolean + +external fun isJSDocTypedefTag(node: Node): Boolean + +external fun isJSDocUnknownTag(node: Node): Boolean + +external fun isJSDocPropertyTag(node: Node): Boolean + +external fun isJSDocImplementsTag(node: Node): Boolean + +external fun setTextRange(range: T, location: TextRange?): T + +external fun forEachChild(node: Node, cbNode: (node: Node) -> T?, cbNodes: (nodes: NodeArray) -> T? = definedExternally): T? + +external fun createSourceFile(fileName: String, sourceText: String, languageVersion: ScriptTarget, setParentNodes: Boolean = definedExternally, scriptKind: ScriptKind = definedExternally): SourceFile + +external fun parseIsolatedEntityName(text: String, languageVersion: ScriptTarget): dynamic /* Identifier? | QualifiedName? */ + +external fun parseJsonText(fileName: String, sourceText: String): JsonSourceFile + +external fun isExternalModule(file: SourceFile): Boolean + +external fun updateSourceFile(sourceFile: SourceFile, newText: String, textChangeRange: TextChangeRange, aggressiveChecks: Boolean = definedExternally): SourceFile + +external fun parseCommandLine(commandLine: Array, readFile: (path: String) -> String? = definedExternally): ParsedCommandLine + +external interface ConfigFileDiagnosticsReporter { + var onUnRecoverableConfigFileDiagnostic: DiagnosticReporter +} + +external interface ParseConfigFileHost : ParseConfigHost, ConfigFileDiagnosticsReporter { + fun getCurrentDirectory(): String +} + +external fun getParsedCommandLineOfConfigFile(configFileName: String, optionsToExtend: CompilerOptions?, host: ParseConfigFileHost, extendedConfigCache: Map = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): ParsedCommandLine? + +external interface `T$25` { + var config: Any? + get() = definedExternally + set(value) = definedExternally + var error: Diagnostic? + get() = definedExternally + set(value) = definedExternally +} + +external fun readConfigFile(fileName: String, readFile: (path: String) -> String?): `T$25` + +external fun parseConfigFileTextToJson(fileName: String, jsonText: String): `T$25` + +external fun readJsonConfigFile(fileName: String, readFile: (path: String) -> String?): TsConfigSourceFile + +external fun convertToObject(sourceFile: JsonSourceFile, errors: Push): Any + +external fun parseJsonConfigFileContent(json: Any, host: ParseConfigHost, basePath: String, existingOptions: CompilerOptions = definedExternally, configFileName: String = definedExternally, resolutionStack: Array = definedExternally, extraFileExtensions: Array = definedExternally, extendedConfigCache: Map = definedExternally, existingWatchOptions: WatchOptions = definedExternally): ParsedCommandLine + +external fun parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: String, existingOptions: CompilerOptions = definedExternally, configFileName: String = definedExternally, resolutionStack: Array = definedExternally, extraFileExtensions: Array = definedExternally, extendedConfigCache: Map = definedExternally, existingWatchOptions: WatchOptions = definedExternally): ParsedCommandLine + +external interface ParsedTsconfig { + var raw: Any + var options: CompilerOptions? + get() = definedExternally + set(value) = definedExternally + var watchOptions: WatchOptions? + get() = definedExternally + set(value) = definedExternally + var typeAcquisition: TypeAcquisition? + get() = definedExternally + set(value) = definedExternally + var extendedConfigPath: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface ExtendedConfigCacheEntry { + var extendedResult: TsConfigSourceFile + var extendedConfig: ParsedTsconfig? +} + +external interface `T$26` { + var options: CompilerOptions + var errors: Array +} + +external fun convertCompilerOptionsFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$26` + +external interface `T$27` { + var options: TypeAcquisition + var errors: Array +} + +external fun convertTypeAcquisitionFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$27` + +external fun getEffectiveTypeRoots(options: CompilerOptions, host: GetEffectiveTypeRootsHost): Array? + +external fun resolveTypeReferenceDirective(typeReferenceDirectiveName: String, containingFile: String?, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference: ResolvedProjectReference = definedExternally, cache: TypeReferenceDirectiveResolutionCache = definedExternally): ResolvedTypeReferenceDirectiveWithFailedLookupLocations + +external fun getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): Array + +external interface TypeReferenceDirectiveResolutionCache : PerDirectoryResolutionCache, PackageJsonInfoCache + +external interface PerDirectoryResolutionCache { + fun getOrCreateCacheForDirectory(directoryName: String, redirectedReference: ResolvedProjectReference = definedExternally): Map + fun clear() + fun update(options: CompilerOptions) +} + +external interface ModuleResolutionCache : PerDirectoryResolutionCache, NonRelativeModuleNameResolutionCache, PackageJsonInfoCache { + fun getPackageJsonInfoCache(): PackageJsonInfoCache +} + +external interface NonRelativeModuleNameResolutionCache : PackageJsonInfoCache { + fun getOrCreateCacheForModuleName(nonRelativeModuleName: String, redirectedReference: ResolvedProjectReference = definedExternally): PerModuleNameCache +} + +external interface PackageJsonInfoCache { + fun clear() +} + +external interface PerModuleNameCache { + fun get(directory: String): ResolvedModuleWithFailedLookupLocations? + fun set(directory: String, result: ResolvedModuleWithFailedLookupLocations) +} + +external fun createModuleResolutionCache(currentDirectory: String, getCanonicalFileName: (s: String) -> String, options: CompilerOptions = definedExternally): ModuleResolutionCache + +external fun createTypeReferenceDirectiveResolutionCache(currentDirectory: String, getCanonicalFileName: (s: String) -> String, options: CompilerOptions = definedExternally, packageJsonInfoCache: PackageJsonInfoCache = definedExternally): TypeReferenceDirectiveResolutionCache + +external fun resolveModuleNameFromCache(moduleName: String, containingFile: String, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations? + +external fun resolveModuleName(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations + +external fun nodeModuleNameResolver(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations + +external fun classicNameResolver(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: NonRelativeModuleNameResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations + +external fun visitNode(node: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T + +external fun visitNode(node: T, visitor: Visitor?): T + +external fun visitNode(node: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T + +external fun visitNode(node: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T? + +external fun visitNode(node: T?, visitor: Visitor?): T? + +external fun visitNode(node: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T? + +external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray + +external fun visitNodes(nodes: NodeArray, visitor: Visitor?): NodeArray + +external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray + +external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray + +external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray? + +external fun visitNodes(nodes: NodeArray?, visitor: Visitor?): NodeArray? + +external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray? + +external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray? + +external fun visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start: Number = definedExternally, ensureUseStrict: Boolean = definedExternally, nodesVisitor: NodesVisitor = definedExternally): NodeArray + +external fun visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor = definedExternally): NodeArray + +external fun visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext): NodeArray + +external fun visitParameterList(nodes: NodeArray?, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor = definedExternally): NodeArray? + +external fun visitParameterList(nodes: NodeArray?, visitor: Visitor, context: TransformationContext): NodeArray? + +external fun visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): dynamic /* FunctionBody */ + +external fun visitFunctionBody(node: Expression, visitor: Visitor, context: TransformationContext): dynamic /* FunctionBody | Expression */ + +external fun visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement + +external fun visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T + +external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext, nodesVisitor: Any = definedExternally, tokenVisitor: Visitor = definedExternally): T? + +external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext): T? + +external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext, nodesVisitor: Any = definedExternally): T? + +external fun getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): String? + +external fun getOutputFileNames(commandLine: ParsedCommandLine, inputFileName: String, ignoreCase: Boolean): Array + +external fun createPrinter(printerOptions: PrinterOptions = definedExternally, handlers: PrintHandlers = definedExternally): Printer + +external fun findConfigFile(searchPath: String, fileExists: (fileName: String) -> Boolean, configName: String = definedExternally): String? + +external fun resolveTripleslashReference(moduleName: String, containingFile: String): String + +external fun createCompilerHost(options: CompilerOptions, setParentNodes: Boolean = definedExternally): CompilerHost + +external fun getPreEmitDiagnostics(program: Program, sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + +external interface FormatDiagnosticsHost { + fun getCurrentDirectory(): String + fun getCanonicalFileName(fileName: String): String + fun getNewLine(): String +} + +external fun formatDiagnostics(diagnostics: Array, host: FormatDiagnosticsHost): String + +external fun formatDiagnostic(diagnostic: Diagnostic, host: FormatDiagnosticsHost): String + +external fun formatDiagnosticsWithColorAndContext(diagnostics: Array, host: FormatDiagnosticsHost): String + +external fun flattenDiagnosticMessageText(diag: String?, newLine: String, indent: Number = definedExternally): String + +external fun flattenDiagnosticMessageText(diag: String?, newLine: String): String + +external fun flattenDiagnosticMessageText(diag: DiagnosticMessageChain?, newLine: String, indent: Number = definedExternally): String + +external fun flattenDiagnosticMessageText(diag: DiagnosticMessageChain?, newLine: String): String + +external fun getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): Array + +external fun createProgram(createProgramOptions: CreateProgramOptions): Program + +external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally, oldProgram: Program = definedExternally, configFileParsingDiagnostics: Array = definedExternally): Program + +external fun createProgram(rootNames: Array, options: CompilerOptions): Program + +external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally): Program + +external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally, oldProgram: Program = definedExternally): Program + +external interface ResolveProjectReferencePathHost { + fun fileExists(fileName: String): Boolean +} + +external fun resolveProjectReferencePath(ref: ProjectReference): String /* String & `T$5` */ + +external fun resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): String /* String & `T$5` */ + +external interface EmitOutput { + var outputFiles: Array + var emitSkipped: Boolean +} + +external interface OutputFile { + var name: String + var writeByteOrderMark: Boolean + var text: String +} + +external interface `T$28` { + var result: T + var affected: dynamic /* SourceFile | Program */ + get() = definedExternally + set(value) = definedExternally +} + +external interface BuilderProgramHost { + fun useCaseSensitiveFileNames(): Boolean + var createHash: ((data: String) -> String)? + get() = definedExternally + set(value) = definedExternally + var writeFile: WriteFileCallback? + get() = definedExternally + set(value) = definedExternally +} + +external interface BuilderProgram { + fun getProgram(): Program + fun getCompilerOptions(): CompilerOptions + fun getSourceFile(fileName: String): SourceFile? + fun getSourceFiles(): Array + fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getConfigFileParsingDiagnostics(): Array + fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getDeclarationDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getAllDependencies(sourceFile: SourceFile): Array + fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult + fun getCurrentDirectory(): String +} + +external interface SemanticDiagnosticsBuilderProgram : BuilderProgram { + fun getSemanticDiagnosticsOfNextAffectedFile(cancellationToken: CancellationToken = definedExternally, ignoreSourceFile: (sourceFile: SourceFile) -> Boolean = definedExternally): `T$28`>? +} + +external interface EmitAndSemanticDiagnosticsBuilderProgram : SemanticDiagnosticsBuilderProgram { + fun emitNextAffectedFile(writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): `T$28`? +} + +external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): BuilderProgram + +external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost): BuilderProgram + +external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram: BuilderProgram = definedExternally): BuilderProgram + +external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): BuilderProgram + +external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?): BuilderProgram + +external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): BuilderProgram + +external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally): BuilderProgram + +external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): BuilderProgram + +external interface ReadBuildProgramHost { + fun useCaseSensitiveFileNames(): Boolean + fun getCurrentDirectory(): String + fun readFile(fileName: String): String? +} + +external fun readBuilderProgram(compilerOptions: CompilerOptions, host: ReadBuildProgramHost): EmitAndSemanticDiagnosticsBuilderProgram? + +external fun createIncrementalCompilerHost(options: CompilerOptions, system: System = definedExternally): CompilerHost + +external interface IncrementalProgramOptions { + var rootNames: Array + var options: CompilerOptions + var configFileParsingDiagnostics: Array? + get() = definedExternally + set(value) = definedExternally + var projectReferences: Array? + get() = definedExternally + set(value) = definedExternally + var host: CompilerHost? + get() = definedExternally + set(value) = definedExternally + var createProgram: CreateProgram? + get() = definedExternally + set(value) = definedExternally +} + +external fun createIncrementalProgram(__0: IncrementalProgramOptions): T + +external interface WatchHost { + val onWatchStatusChange: ((diagnostic: Diagnostic, newLine: String, options: CompilerOptions, errorCount: Number) -> Unit)? + fun watchFile(path: String, callback: FileWatcherCallback, pollingInterval: Number = definedExternally, options: CompilerOptions = definedExternally): FileWatcher + fun watchDirectory(path: String, callback: DirectoryWatcherCallback, recursive: Boolean = definedExternally, options: CompilerOptions = definedExternally): FileWatcher + val setTimeout: ((callback: (args: Any) -> Unit, ms: Number, args: Any) -> Any)? + val clearTimeout: ((timeoutId: Any) -> Unit)? +} + +external interface ProgramHost { + var createProgram: CreateProgram + fun useCaseSensitiveFileNames(): Boolean + fun getNewLine(): String + fun getCurrentDirectory(): String + fun getDefaultLibFileName(options: CompilerOptions): String + val getDefaultLibLocation: (() -> String)? + val createHash: ((data: String) -> String)? + fun fileExists(path: String): Boolean + fun readFile(path: String, encoding: String = definedExternally): String? + val directoryExists: ((path: String) -> Boolean)? + val getDirectories: ((path: String) -> Array)? + val readDirectory: ((path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array)? + val realpath: ((path: String) -> String)? + val trace: ((s: String) -> Unit)? + val getEnvironmentVariable: ((name: String) -> String?)? + val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? +} + +external interface WatchCompilerHost : ProgramHost, WatchHost { + val useSourceOfProjectReferenceRedirect: (() -> Boolean)? + val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? + val afterProgramCreate: ((program: T) -> Unit)? +} + +external interface WatchCompilerHostOfFilesAndCompilerOptions : WatchCompilerHost { + var rootFiles: Array + var options: CompilerOptions + var watchOptions: WatchOptions? + get() = definedExternally + set(value) = definedExternally + var projectReferences: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface WatchCompilerHostOfConfigFile : WatchCompilerHost, ConfigFileDiagnosticsReporter { + var configFileName: String + var optionsToExtend: CompilerOptions? + get() = definedExternally + set(value) = definedExternally + var watchOptionsToExtend: WatchOptions? + get() = definedExternally + set(value) = definedExternally + var extraFileExtensions: Array? + get() = definedExternally + set(value) = definedExternally + override var readDirectory: (path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array +} + +external interface Watch { + fun getProgram(): T + fun close() +} + +external interface WatchOfConfigFile : Watch + +external interface WatchOfFilesAndCompilerOptions : Watch { + fun updateRootFileNames(fileNames: Array) +} + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, projectReferences: Array = definedExternally, watchOptions: WatchOptions = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, projectReferences: Array = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchProgram(host: WatchCompilerHostOfFilesAndCompilerOptions): WatchOfFilesAndCompilerOptions + +external fun createWatchProgram(host: WatchCompilerHostOfConfigFile): WatchOfConfigFile + +external interface BuildOptions { + var dry: Boolean? + get() = definedExternally + set(value) = definedExternally + var force: Boolean? + get() = definedExternally + set(value) = definedExternally + var verbose: Boolean? + get() = definedExternally + set(value) = definedExternally + var incremental: Boolean? + get() = definedExternally + set(value) = definedExternally + var assumeChangesOnlyAffectDirectDependencies: Boolean? + get() = definedExternally + set(value) = definedExternally + var traceResolution: Boolean? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ + @nativeSetter + operator fun set(option: String, value: String?) + @nativeSetter + operator fun set(option: String, value: Number?) + @nativeSetter + operator fun set(option: String, value: Boolean?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: MapLike>?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) +} + +external interface SolutionBuilderHostBase : ProgramHost { + val createDirectory: ((path: String) -> Unit)? + val writeFile: ((path: String, data: String, writeByteOrderMark: Boolean) -> Unit)? + var getCustomTransformers: ((project: String) -> CustomTransformers?)? + get() = definedExternally + set(value) = definedExternally + fun getModifiedTime(fileName: String): Date? + fun setModifiedTime(fileName: String, date: Date) + fun deleteFile(fileName: String) + val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? + var reportDiagnostic: DiagnosticReporter + var reportSolutionBuilderStatus: DiagnosticReporter + val afterProgramEmitAndDiagnostics: ((program: T) -> Unit)? +} + +external interface SolutionBuilderHost : SolutionBuilderHostBase { + var reportErrorSummary: ReportEmitErrorSummary? + get() = definedExternally + set(value) = definedExternally +} + +external interface SolutionBuilderWithWatchHost : SolutionBuilderHostBase, WatchHost + +external interface SolutionBuilder { + fun build(project: String = definedExternally, cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, getCustomTransformers: (project: String) -> CustomTransformers = definedExternally): ExitStatus + fun clean(project: String = definedExternally): ExitStatus + fun buildReferences(project: String, cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, getCustomTransformers: (project: String) -> CustomTransformers = definedExternally): ExitStatus + fun cleanReferences(project: String = definedExternally): ExitStatus + fun getNextInvalidatedProject(cancellationToken: CancellationToken = definedExternally): dynamic /* UpdateOutputFileStampsProject? | BuildInvalidedProject? | UpdateBundleProject? */ +} + +external fun createBuilderStatusReporter(system: System, pretty: Boolean = definedExternally): DiagnosticReporter + +external fun createSolutionBuilderHost(system: System = definedExternally, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportSolutionBuilderStatus: DiagnosticReporter = definedExternally, reportErrorSummary: ReportEmitErrorSummary = definedExternally): SolutionBuilderHost + +external fun createSolutionBuilderWithWatchHost(system: System = definedExternally, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportSolutionBuilderStatus: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): SolutionBuilderWithWatchHost + +external fun createSolutionBuilder(host: SolutionBuilderHost, rootNames: Array, defaultOptions: BuildOptions): SolutionBuilder + +external fun createSolutionBuilderWithWatch(host: SolutionBuilderWithWatchHost, rootNames: Array, defaultOptions: BuildOptions, baseWatchOptions: WatchOptions = definedExternally): SolutionBuilder + +external enum class InvalidatedProjectKind { + Build /* = 0 */, + UpdateBundle /* = 1 */, + UpdateOutputFileStamps /* = 2 */ +} + +external interface InvalidatedProjectBase { + val kind: InvalidatedProjectKind + val project: String /* String & `T$5` */ + fun done(cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, customTransformers: CustomTransformers = definedExternally): ExitStatus + fun getCompilerOptions(): CompilerOptions + fun getCurrentDirectory(): String +} + +external interface UpdateOutputFileStampsProject : InvalidatedProjectBase { + fun updateOutputFileStatmps() +} + +external interface BuildInvalidedProject : InvalidatedProjectBase { + fun getBuilderProgram(): T? + fun getProgram(): Program? + fun getSourceFile(fileName: String): SourceFile? + fun getSourceFiles(): Array + fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getConfigFileParsingDiagnostics(): Array + fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getAllDependencies(sourceFile: SourceFile): Array + fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getSemanticDiagnosticsOfNextAffectedFile(cancellationToken: CancellationToken = definedExternally, ignoreSourceFile: (sourceFile: SourceFile) -> Boolean = definedExternally): `T$28`>? + fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult? +} + +external interface UpdateBundleProject : InvalidatedProjectBase { + fun emit(writeFile: WriteFileCallback = definedExternally, customTransformers: CustomTransformers = definedExternally): dynamic /* EmitResult? | BuildInvalidedProject? */ +} + +external interface SourceFileLike { + fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter +} + +external interface IScriptSnapshot { + fun getText(start: Number, end: Number): String + fun getLength(): Number + fun getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange? + val dispose: (() -> Unit)? +} + +external interface PreProcessedFileInfo { + var referencedFiles: Array + var typeReferenceDirectives: Array + var libReferenceDirectives: Array + var importedFiles: Array + var ambientExternalModules: Array? + get() = definedExternally + set(value) = definedExternally + var isLibFile: Boolean +} + +external interface HostCancellationToken { + fun isCancellationRequested(): Boolean +} + +external interface InstallPackageOptions { + var fileName: String /* String & `T$3` */ + var packageName: String +} + +external interface PerformanceEvent { + var kind: String /* "UpdateGraph" | "CreatePackageJsonAutoImportProvider" */ + var durationMs: Number +} + +external enum class LanguageServiceMode { + Semantic /* = 0 */, + PartialSemantic /* = 1 */, + Syntactic /* = 2 */ +} + +external interface IncompleteCompletionsCache { + fun get(): CompletionInfo? + fun set(response: CompletionInfo) + fun clear() +} + +external interface LanguageServiceHost : GetEffectiveTypeRootsHost { + fun getCompilationSettings(): CompilerOptions + val getNewLine: (() -> String)? + val getProjectVersion: (() -> String)? + fun getScriptFileNames(): Array + val getScriptKind: ((fileName: String) -> ScriptKind)? + fun getScriptVersion(fileName: String): String + fun getScriptSnapshot(fileName: String): IScriptSnapshot? + val getProjectReferences: (() -> Array?)? + val getLocalizedDiagnosticMessages: (() -> Any)? + val getCancellationToken: (() -> HostCancellationToken)? + override var getCurrentDirectory: () -> String + fun getDefaultLibFileName(options: CompilerOptions): String + val log: ((s: String) -> Unit)? + val trace: ((s: String) -> Unit)? + val error: ((s: String) -> Unit)? + val useCaseSensitiveFileNames: (() -> Boolean)? + val readDirectory: ((path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array)? + val readFile: ((path: String, encoding: String) -> String?)? + val realpath: ((path: String) -> String)? + val fileExists: ((path: String) -> Boolean)? + val getTypeRootsVersion: (() -> Number)? + val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val getResolvedModuleWithFailedLookupLocationsFromCache: ((modulename: String, containingFile: String) -> ResolvedModuleWithFailedLookupLocations?)? + val resolveTypeReferenceDirectives: ((typeDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val getDirectories: ((directoryName: String) -> Array)? + val getCustomTransformers: (() -> CustomTransformers?)? + val isKnownTypesPackageName: ((name: String) -> Boolean)? + val installPackage: ((options: InstallPackageOptions) -> Promise)? + val writeFile: ((fileName: String, content: String) -> Unit)? + val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? +} + +external enum class SemanticClassificationFormat { + Original /* = "original" */, + TwentyTwenty /* = "2020" */ +} + +external interface LanguageService { + fun cleanupSemanticCache() + fun getSyntacticDiagnostics(fileName: String): Array + fun getSemanticDiagnostics(fileName: String): Array + fun getSuggestionDiagnostics(fileName: String): Array + fun getCompilerOptionsDiagnostics(): Array + fun getSyntacticClassifications(fileName: String, span: TextSpan): Array + fun getSyntacticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ + fun getSemanticClassifications(fileName: String, span: TextSpan): Array + fun getSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ + fun getEncodedSyntacticClassifications(fileName: String, span: TextSpan): Classifications + fun getEncodedSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat = definedExternally): Classifications + fun getCompletionsAtPosition(fileName: String, position: Number, options: GetCompletionsAtPositionOptions?): CompletionInfo /* CompletionInfo & `T$12` */ + fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeOptions?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? + fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeSettings?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? + fun getCompletionEntrySymbol(fileName: String, position: Number, name: String, source: String?): Symbol? + fun getQuickInfoAtPosition(fileName: String, position: Number): QuickInfo? + fun getNameOrDottedNameSpan(fileName: String, startPos: Number, endPos: Number): TextSpan? + fun getBreakpointStatementAtPosition(fileName: String, position: Number): TextSpan? + fun getSignatureHelpItems(fileName: String, position: Number, options: SignatureHelpItemsOptions?): SignatureHelpItems? + fun getRenameInfo(fileName: String, position: Number, options: RenameInfoOptions = definedExternally): dynamic /* RenameInfoSuccess | RenameInfoFailure */ + fun findRenameLocations(fileName: String, position: Number, findInStrings: Boolean, findInComments: Boolean, providePrefixAndSuffixTextForRename: Boolean = definedExternally): Array? + fun getSmartSelectionRange(fileName: String, position: Number): SelectionRange + fun getDefinitionAtPosition(fileName: String, position: Number): Array? + fun getDefinitionAndBoundSpan(fileName: String, position: Number): DefinitionInfoAndBoundSpan? + fun getTypeDefinitionAtPosition(fileName: String, position: Number): Array? + fun getImplementationAtPosition(fileName: String, position: Number): Array? + fun getReferencesAtPosition(fileName: String, position: Number): Array? + fun findReferences(fileName: String, position: Number): Array? + fun getDocumentHighlights(fileName: String, position: Number, filesToSearch: Array): Array? + fun getFileReferences(fileName: String): Array + fun getOccurrencesAtPosition(fileName: String, position: Number): Array? + fun getNavigateToItems(searchValue: String, maxResultCount: Number = definedExternally, fileName: String = definedExternally, excludeDtsFiles: Boolean = definedExternally): Array + fun getNavigationBarItems(fileName: String): Array + fun getNavigationTree(fileName: String): NavigationTree + fun prepareCallHierarchy(fileName: String, position: Number): dynamic /* CallHierarchyItem? | Array? */ + fun provideCallHierarchyIncomingCalls(fileName: String, position: Number): Array + fun provideCallHierarchyOutgoingCalls(fileName: String, position: Number): Array + fun provideInlayHints(fileName: String, span: TextSpan, preferences: UserPreferences?): Array + fun getOutliningSpans(fileName: String): Array + fun getTodoComments(fileName: String, descriptors: Array): Array + fun getBraceMatchingAtPosition(fileName: String, position: Number): Array + fun getIndentationAtPosition(fileName: String, position: Number, options: EditorOptions): Number + fun getIndentationAtPosition(fileName: String, position: Number, options: EditorSettings): Number + fun getFormattingEditsForRange(fileName: String, start: Number, end: Number, options: FormatCodeOptions): Array + fun getFormattingEditsForRange(fileName: String, start: Number, end: Number, options: FormatCodeSettings): Array + fun getFormattingEditsForDocument(fileName: String, options: FormatCodeOptions): Array + fun getFormattingEditsForDocument(fileName: String, options: FormatCodeSettings): Array + fun getFormattingEditsAfterKeystroke(fileName: String, position: Number, key: String, options: FormatCodeOptions): Array + fun getFormattingEditsAfterKeystroke(fileName: String, position: Number, key: String, options: FormatCodeSettings): Array + fun getDocCommentTemplateAtPosition(fileName: String, position: Number, options: DocCommentTemplateOptions = definedExternally): TextInsertion? + fun isValidBraceCompletionAtPosition(fileName: String, position: Number, openingBrace: Number): Boolean + fun getJsxClosingTagAtPosition(fileName: String, position: Number): JsxClosingTagInfo? + fun getSpanOfEnclosingComment(fileName: String, position: Number, onlyMultiLine: Boolean): TextSpan? + val toLineColumnOffset: ((fileName: String, position: Number) -> LineAndCharacter)? + fun getCodeFixesAtPosition(fileName: String, start: Number, end: Number, errorCodes: Array, formatOptions: FormatCodeSettings, preferences: UserPreferences): Array + fun getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: Any, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions + fun applyCodeActionCommand(action: CodeActionCommand, formatSettings: FormatCodeSettings = definedExternally): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(action: CodeActionCommand): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(action: Array, formatSettings: FormatCodeSettings = definedExternally): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(action: Array): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(fileName: String, action: CodeActionCommand): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(fileName: String, action: Array): dynamic /* Promise | Promise */ + fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally, kind: String = definedExternally): Array + fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?): Array + fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally): Array + fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally, kind: String = definedExternally): Array + fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?): Array + fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally): Array + fun getEditsForRefactor(fileName: String, formatOptions: FormatCodeSettings, positionOrRange: Number, refactorName: String, actionName: String, preferences: UserPreferences?): RefactorEditInfo? + fun getEditsForRefactor(fileName: String, formatOptions: FormatCodeSettings, positionOrRange: TextRange, refactorName: String, actionName: String, preferences: UserPreferences?): RefactorEditInfo? + fun organizeImports(args: OrganizeImportsArgs, formatOptions: FormatCodeSettings, preferences: UserPreferences?): Array + fun getEditsForFileRename(oldFilePath: String, newFilePath: String, formatOptions: FormatCodeSettings, preferences: UserPreferences?): Array + fun getEmitOutput(fileName: String, emitOnlyDtsFiles: Boolean = definedExternally, forceDtsEmit: Boolean = definedExternally): EmitOutput + fun getProgram(): Program? + fun toggleLineComment(fileName: String, textRange: TextRange): Array + fun toggleMultilineComment(fileName: String, textRange: TextRange): Array + fun commentSelection(fileName: String, textRange: TextRange): Array + fun uncommentSelection(fileName: String, textRange: TextRange): Array + fun dispose() +} + +external interface JsxClosingTagInfo { + val newText: String +} + +external interface CombinedCodeFixScope { + var type: String /* "file" */ + var fileName: String +} + +external interface OrganizeImportsArgs : CombinedCodeFixScope { + var skipDestructiveCodeActions: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external enum class CompletionTriggerKind { + Invoked /* = 1 */, + TriggerCharacter /* = 2 */, + TriggerForIncompleteCompletions /* = 3 */ +} + +external interface GetCompletionsAtPositionOptions : UserPreferences { + var triggerCharacter: String? /* "." | """ | "'" | "`" | "/" | "@" | "<" | "#" | " " */ + get() = definedExternally + set(value) = definedExternally + var triggerKind: CompletionTriggerKind? + get() = definedExternally + set(value) = definedExternally + var includeExternalModuleExports: Boolean? + get() = definedExternally + set(value) = definedExternally + var includeInsertTextCompletions: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface InlayHintsOptions : UserPreferences { + val includeInlayParameterNameHints: String? /* "none" | "literals" | "all" */ + get() = definedExternally + val includeInlayParameterNameHintsWhenArgumentMatchesName: Boolean? + get() = definedExternally + val includeInlayFunctionParameterTypeHints: Boolean? + get() = definedExternally + val includeInlayVariableTypeHints: Boolean? + get() = definedExternally + val includeInlayPropertyDeclarationTypeHints: Boolean? + get() = definedExternally + val includeInlayFunctionLikeReturnTypeHints: Boolean? + get() = definedExternally + val includeInlayEnumMemberValueHints: Boolean? + get() = definedExternally +} + +external interface SignatureHelpItemsOptions { + var triggerReason: dynamic /* SignatureHelpInvokedReason? | SignatureHelpCharacterTypedReason? | SignatureHelpRetriggeredReason? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureHelpInvokedReason { + var kind: String /* "invoked" */ + var triggerCharacter: Any? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureHelpCharacterTypedReason { + var kind: String /* "characterTyped" */ + var triggerCharacter: String /* "," | "(" | "<" */ +} + +external interface SignatureHelpRetriggeredReason { + var kind: String /* "retrigger" */ + var triggerCharacter: String? /* "," | "(" | "<" | ")" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ApplyCodeActionCommandResult { + var successMessage: String +} + +external interface Classifications { + var spans: Array + var endOfLineState: EndOfLineState +} + +external interface ClassifiedSpan { + var textSpan: TextSpan + var classificationType: ClassificationTypeNames +} + +external interface ClassifiedSpan2020 { + var textSpan: TextSpan + var classificationType: Number +} + +external interface NavigationBarItem { + var text: String + var kind: ScriptElementKind + var kindModifiers: String + var spans: Array + var childItems: Array + var indent: Number + var bolded: Boolean + var grayed: Boolean +} + +external interface NavigationTree { + var text: String + var kind: ScriptElementKind + var kindModifiers: String + var spans: Array + var nameSpan: TextSpan? + var childItems: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface CallHierarchyItem { + var name: String + var kind: ScriptElementKind + var kindModifiers: String? + get() = definedExternally + set(value) = definedExternally + var file: String + var span: TextSpan + var selectionSpan: TextSpan + var containerName: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface CallHierarchyIncomingCall { + var from: CallHierarchyItem + var fromSpans: Array +} + +external interface CallHierarchyOutgoingCall { + var to: CallHierarchyItem + var fromSpans: Array +} + +external enum class InlayHintKind { + Type /* = "Type" */, + Parameter /* = "Parameter" */, + Enum /* = "Enum" */ +} + +external interface InlayHint { + var text: String + var position: Number + var kind: InlayHintKind + var whitespaceBefore: Boolean? + get() = definedExternally + set(value) = definedExternally + var whitespaceAfter: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TodoCommentDescriptor { + var text: String + var priority: Number +} + +external interface TodoComment { + var descriptor: TodoCommentDescriptor + var message: String + var position: Number +} + +external interface TextChange { + var span: TextSpan + var newText: String +} + +external interface FileTextChanges { + var fileName: String + var textChanges: Array + var isNewFile: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface CodeAction { + var description: String + var changes: Array + var commands: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface CodeFixAction : CodeAction { + var fixName: String + var fixId: Any? + get() = definedExternally + set(value) = definedExternally + var fixAllDescription: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface CombinedCodeActions { + var changes: Array + var commands: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface InstallPackageAction + +external interface ApplicableRefactorInfo { + var name: String + var description: String + var inlineable: Boolean? + get() = definedExternally + set(value) = definedExternally + var actions: Array +} + +external interface RefactorActionInfo { + var name: String + var description: String + var notApplicableReason: String? + get() = definedExternally + set(value) = definedExternally + var kind: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface RefactorEditInfo { + var edits: Array + var renameFilename: String? + get() = definedExternally + set(value) = definedExternally + var renameLocation: Number? + get() = definedExternally + set(value) = definedExternally + var commands: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface TextInsertion { + var newText: String + var caretOffset: Number +} + +external interface DocumentSpan { + var textSpan: TextSpan + var fileName: String + var originalTextSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var originalFileName: String? + get() = definedExternally + set(value) = definedExternally + var contextSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var originalContextSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally +} + +external interface RenameLocation : DocumentSpan { + val prefixText: String? + get() = definedExternally + val suffixText: String? + get() = definedExternally +} + +external interface ReferenceEntry : DocumentSpan { + var isWriteAccess: Boolean + var isDefinition: Boolean + var isInString: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ImplementationLocation : DocumentSpan { + var kind: ScriptElementKind + var displayParts: Array +} + +external enum class HighlightSpanKind { + none /* = "none" */, + definition /* = "definition" */, + reference /* = "reference" */, + writtenReference /* = "writtenReference" */ +} + +external interface HighlightSpan { + var fileName: String? + get() = definedExternally + set(value) = definedExternally + var isInString: Boolean? + get() = definedExternally + set(value) = definedExternally + var textSpan: TextSpan + var contextSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var kind: HighlightSpanKind +} + +external interface NavigateToItem { + var name: String + var kind: ScriptElementKind + var kindModifiers: String + var matchKind: String /* "exact" | "prefix" | "substring" | "camelCase" */ + var isCaseSensitive: Boolean + var fileName: String + var textSpan: TextSpan + var containerName: String + var containerKind: ScriptElementKind +} + +external enum class IndentStyle { + None /* = 0 */, + Block /* = 1 */, + Smart /* = 2 */ +} + +external enum class SemicolonPreference { + Ignore /* = "ignore" */, + Insert /* = "insert" */, + Remove /* = "remove" */ +} + +external interface EditorOptions { + var BaseIndentSize: Number? + get() = definedExternally + set(value) = definedExternally + var IndentSize: Number + var TabSize: Number + var NewLineCharacter: String + var ConvertTabsToSpaces: Boolean + var IndentStyle: IndentStyle +} + +external interface EditorSettings { + var baseIndentSize: Number? + get() = definedExternally + set(value) = definedExternally + var indentSize: Number? + get() = definedExternally + set(value) = definedExternally + var tabSize: Number? + get() = definedExternally + set(value) = definedExternally + var newLineCharacter: String? + get() = definedExternally + set(value) = definedExternally + var convertTabsToSpaces: Boolean? + get() = definedExternally + set(value) = definedExternally + var indentStyle: IndentStyle? + get() = definedExternally + set(value) = definedExternally + var trimTrailingWhitespace: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface FormatCodeOptions : EditorOptions { + var InsertSpaceAfterCommaDelimiter: Boolean + var InsertSpaceAfterSemicolonInForStatements: Boolean + var InsertSpaceBeforeAndAfterBinaryOperators: Boolean + var InsertSpaceAfterConstructor: Boolean? + get() = definedExternally + set(value) = definedExternally + var InsertSpaceAfterKeywordsInControlFlowStatements: Boolean + var InsertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean + var InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean + var InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean + var InsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: Boolean? + get() = definedExternally + set(value) = definedExternally + var InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean + var InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: Boolean? + get() = definedExternally + set(value) = definedExternally + var InsertSpaceAfterTypeAssertion: Boolean? + get() = definedExternally + set(value) = definedExternally + var InsertSpaceBeforeFunctionParenthesis: Boolean? + get() = definedExternally + set(value) = definedExternally + var PlaceOpenBraceOnNewLineForFunctions: Boolean + var PlaceOpenBraceOnNewLineForControlBlocks: Boolean + var insertSpaceBeforeTypeAnnotation: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface FormatCodeSettings : EditorSettings { + val insertSpaceAfterCommaDelimiter: Boolean? + get() = definedExternally + val insertSpaceAfterSemicolonInForStatements: Boolean? + get() = definedExternally + val insertSpaceBeforeAndAfterBinaryOperators: Boolean? + get() = definedExternally + val insertSpaceAfterConstructor: Boolean? + get() = definedExternally + val insertSpaceAfterKeywordsInControlFlowStatements: Boolean? + get() = definedExternally + val insertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingEmptyBraces: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: Boolean? + get() = definedExternally + val insertSpaceAfterTypeAssertion: Boolean? + get() = definedExternally + val insertSpaceBeforeFunctionParenthesis: Boolean? + get() = definedExternally + val placeOpenBraceOnNewLineForFunctions: Boolean? + get() = definedExternally + val placeOpenBraceOnNewLineForControlBlocks: Boolean? + get() = definedExternally + val insertSpaceBeforeTypeAnnotation: Boolean? + get() = definedExternally + val indentMultiLineObjectLiteralBeginningOnBlankLine: Boolean? + get() = definedExternally + val semicolons: SemicolonPreference? + get() = definedExternally +} + +external fun getDefaultFormatCodeSettings(newLineCharacter: String = definedExternally): FormatCodeSettings + +external interface DefinitionInfo : DocumentSpan { + var kind: ScriptElementKind + var name: String + var containerKind: ScriptElementKind + var containerName: String + var unverified: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface DefinitionInfoAndBoundSpan { + var definitions: Array? + get() = definedExternally + set(value) = definedExternally + var textSpan: TextSpan +} + +external interface ReferencedSymbolDefinitionInfo : DefinitionInfo { + var displayParts: Array +} + +external interface ReferencedSymbol { + var definition: ReferencedSymbolDefinitionInfo + var references: Array +} + +external enum class SymbolDisplayPartKind { + aliasName /* = 0 */, + className /* = 1 */, + enumName /* = 2 */, + fieldName /* = 3 */, + interfaceName /* = 4 */, + keyword /* = 5 */, + lineBreak /* = 6 */, + numericLiteral /* = 7 */, + stringLiteral /* = 8 */, + localName /* = 9 */, + methodName /* = 10 */, + moduleName /* = 11 */, + operator /* = 12 */, + parameterName /* = 13 */, + propertyName /* = 14 */, + punctuation /* = 15 */, + space /* = 16 */, + text /* = 17 */, + typeParameterName /* = 18 */, + enumMemberName /* = 19 */, + functionName /* = 20 */, + regularExpressionLiteral /* = 21 */, + link /* = 22 */, + linkName /* = 23 */, + linkText /* = 24 */ +} + +external interface SymbolDisplayPart { + var text: String + var kind: String +} + +external interface JSDocLinkDisplayPart : SymbolDisplayPart { + var target: DocumentSpan +} + +external interface JSDocTagInfo { + var name: String + var text: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface QuickInfo { + var kind: ScriptElementKind + var kindModifiers: String + var textSpan: TextSpan + var displayParts: Array? + get() = definedExternally + set(value) = definedExternally + var documentation: Array? + get() = definedExternally + set(value) = definedExternally + var tags: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface RenameInfoSuccess { + var canRename: Boolean + var fileToRename: String? + get() = definedExternally + set(value) = definedExternally + var displayName: String + var fullDisplayName: String + var kind: ScriptElementKind + var kindModifiers: String + var triggerSpan: TextSpan +} + +external interface RenameInfoFailure { + var canRename: Boolean + var localizedErrorMessage: String +} + +external interface RenameInfoOptions { + val allowRenameOfImportPath: Boolean? + get() = definedExternally +} + +external interface DocCommentTemplateOptions { + val generateReturnInDocTemplate: Boolean? + get() = definedExternally +} + +external interface SignatureHelpParameter { + var name: String + var documentation: Array + var displayParts: Array + var isOptional: Boolean + var isRest: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface SelectionRange { + var textSpan: TextSpan + var parent: SelectionRange? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureHelpItem { + var isVariadic: Boolean + var prefixDisplayParts: Array + var suffixDisplayParts: Array + var separatorDisplayParts: Array + var parameters: Array + var documentation: Array + var tags: Array +} + +external interface SignatureHelpItems { + var items: Array + var applicableSpan: TextSpan + var selectedItemIndex: Number + var argumentIndex: Number + var argumentCount: Number +} + +external interface CompletionInfo { + var isGlobalCompletion: Boolean + var isMemberCompletion: Boolean + var optionalReplacementSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var isNewIdentifierLocation: Boolean + var isIncomplete: Boolean? + get() = definedExternally + set(value) = definedExternally + var entries: Array +} + +external interface CompletionEntryData { + var fileName: String? + get() = definedExternally + set(value) = definedExternally + var ambientModuleName: String? + get() = definedExternally + set(value) = definedExternally + var isPackageJsonImport: Boolean? + get() = definedExternally + set(value) = definedExternally + var exportName: String + var moduleSpecifier: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface CompletionEntry { + var name: String + var kind: ScriptElementKind + var kindModifiers: String? + get() = definedExternally + set(value) = definedExternally + var sortText: String + var insertText: String? + get() = definedExternally + set(value) = definedExternally + var isSnippet: Boolean? + get() = definedExternally + set(value) = definedExternally + var replacementSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var hasAction: Boolean? + get() = definedExternally + set(value) = definedExternally + var source: String? + get() = definedExternally + set(value) = definedExternally + var sourceDisplay: Array? + get() = definedExternally + set(value) = definedExternally + var isRecommended: Boolean? + get() = definedExternally + set(value) = definedExternally + var isFromUncheckedFile: Boolean? + get() = definedExternally + set(value) = definedExternally + var isPackageJsonImport: Boolean? + get() = definedExternally + set(value) = definedExternally + var isImportStatementCompletion: Boolean? + get() = definedExternally + set(value) = definedExternally + var data: CompletionEntryData? + get() = definedExternally + set(value) = definedExternally +} + +external interface CompletionEntryDetails { + var name: String + var kind: ScriptElementKind + var kindModifiers: String + var displayParts: Array + var documentation: Array? + get() = definedExternally + set(value) = definedExternally + var tags: Array? + get() = definedExternally + set(value) = definedExternally + var codeActions: Array? + get() = definedExternally + set(value) = definedExternally + var source: Array? + get() = definedExternally + set(value) = definedExternally + var sourceDisplay: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface OutliningSpan { + var textSpan: TextSpan + var hintSpan: TextSpan + var bannerText: String + var autoCollapse: Boolean + var kind: OutliningSpanKind +} + +external enum class OutliningSpanKind { + Comment /* = "comment" */, + Region /* = "region" */, + Code /* = "code" */, + Imports /* = "imports" */ +} + +external enum class OutputFileType { + JavaScript /* = 0 */, + SourceMap /* = 1 */, + Declaration /* = 2 */ +} + +external enum class EndOfLineState { + None /* = 0 */, + InMultiLineCommentTrivia /* = 1 */, + InSingleQuoteStringLiteral /* = 2 */, + InDoubleQuoteStringLiteral /* = 3 */, + InTemplateHeadOrNoSubstitutionTemplate /* = 4 */, + InTemplateMiddleOrTail /* = 5 */, + InTemplateSubstitutionPosition /* = 6 */ +} + +external enum class TokenClass { + Punctuation /* = 0 */, + Keyword /* = 1 */, + Operator /* = 2 */, + Comment /* = 3 */, + Whitespace /* = 4 */, + Identifier /* = 5 */, + NumberLiteral /* = 6 */, + BigIntLiteral /* = 7 */, + StringLiteral /* = 8 */, + RegExpLiteral /* = 9 */ +} + +external interface ClassificationResult { + var finalLexState: EndOfLineState + var entries: Array +} + +external interface ClassificationInfo { + var length: Number + var classification: TokenClass +} + +external interface Classifier { + fun getClassificationsForLine(text: String, lexState: EndOfLineState, syntacticClassifierAbsent: Boolean): ClassificationResult + fun getEncodedLexicalClassifications(text: String, endOfLineState: EndOfLineState, syntacticClassifierAbsent: Boolean): Classifications +} + +external enum class ScriptElementKind { + unknown /* = "" */, + warning /* = "warning" */, + keyword /* = "keyword" */, + scriptElement /* = "script" */, + moduleElement /* = "module" */, + classElement /* = "class" */, + localClassElement /* = "local class" */, + interfaceElement /* = "interface" */, + typeElement /* = "type" */, + enumElement /* = "enum" */, + enumMemberElement /* = "enum member" */, + variableElement /* = "var" */, + localVariableElement /* = "local var" */, + functionElement /* = "function" */, + localFunctionElement /* = "local function" */, + memberFunctionElement /* = "method" */, + memberGetAccessorElement /* = "getter" */, + memberSetAccessorElement /* = "setter" */, + memberVariableElement /* = "property" */, + constructorImplementationElement /* = "constructor" */, + callSignatureElement /* = "call" */, + indexSignatureElement /* = "index" */, + constructSignatureElement /* = "construct" */, + parameterElement /* = "parameter" */, + typeParameterElement /* = "type parameter" */, + primitiveType /* = "primitive type" */, + label /* = "label" */, + alias /* = "alias" */, + constElement /* = "const" */, + letElement /* = "let" */, + directory /* = "directory" */, + externalModuleName /* = "external module name" */, + jsxAttribute /* = "JSX attribute" */, + string /* = "string" */, + link /* = "link" */, + linkName /* = "link name" */, + linkText /* = "link text" */ +} + +external enum class ScriptElementKindModifier { + none /* = "" */, + publicMemberModifier /* = "public" */, + privateMemberModifier /* = "private" */, + protectedMemberModifier /* = "protected" */, + exportedModifier /* = "export" */, + ambientModifier /* = "declare" */, + staticModifier /* = "static" */, + abstractModifier /* = "abstract" */, + optionalModifier /* = "optional" */, + deprecatedModifier /* = "deprecated" */, + dtsModifier /* = ".d.ts" */, + tsModifier /* = ".ts" */, + tsxModifier /* = ".tsx" */, + jsModifier /* = ".js" */, + jsxModifier /* = ".jsx" */, + jsonModifier /* = ".json" */ +} + +external enum class ClassificationTypeNames { + comment /* = "comment" */, + identifier /* = "identifier" */, + keyword /* = "keyword" */, + numericLiteral /* = "number" */, + bigintLiteral /* = "bigint" */, + operator /* = "operator" */, + stringLiteral /* = "string" */, + whiteSpace /* = "whitespace" */, + text /* = "text" */, + punctuation /* = "punctuation" */, + className /* = "class name" */, + enumName /* = "enum name" */, + interfaceName /* = "interface name" */, + moduleName /* = "module name" */, + typeParameterName /* = "type parameter name" */, + typeAliasName /* = "type alias name" */, + parameterName /* = "parameter name" */, + docCommentTagName /* = "doc comment tag name" */, + jsxOpenTagName /* = "jsx open tag name" */, + jsxCloseTagName /* = "jsx close tag name" */, + jsxSelfClosingTagName /* = "jsx self closing tag name" */, + jsxAttribute /* = "jsx attribute" */, + jsxText /* = "jsx text" */, + jsxAttributeStringLiteralValue /* = "jsx attribute string literal value" */ +} + +external enum class ClassificationType { + comment /* = 1 */, + identifier /* = 2 */, + keyword /* = 3 */, + numericLiteral /* = 4 */, + operator /* = 5 */, + stringLiteral /* = 6 */, + regularExpressionLiteral /* = 7 */, + whiteSpace /* = 8 */, + text /* = 9 */, + punctuation /* = 10 */, + className /* = 11 */, + enumName /* = 12 */, + interfaceName /* = 13 */, + moduleName /* = 14 */, + typeParameterName /* = 15 */, + typeAliasName /* = 16 */, + parameterName /* = 17 */, + docCommentTagName /* = 18 */, + jsxOpenTagName /* = 19 */, + jsxCloseTagName /* = 20 */, + jsxSelfClosingTagName /* = 21 */, + jsxAttribute /* = 22 */, + jsxText /* = 23 */, + jsxAttributeStringLiteralValue /* = 24 */, + bigintLiteral /* = 25 */ +} + +external interface InlayHintsContext { + var file: SourceFile + var program: Program + var cancellationToken: CancellationToken + var host: LanguageServiceHost + var span: TextSpan + var preferences: InlayHintsOptions +} + +external fun createClassifier(): Classifier + +external interface DocumentHighlights { + var fileName: String + var highlightSpans: Array +} + +external interface DocumentRegistry { + fun acquireDocument(fileName: String, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile + fun acquireDocumentWithKey(fileName: String, path: String /* String & `T$3` */, compilationSettings: CompilerOptions, key: String /* String & `T$29` */, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile + fun updateDocument(fileName: String, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile + fun updateDocumentWithKey(fileName: String, path: String /* String & `T$3` */, compilationSettings: CompilerOptions, key: String /* String & `T$29` */, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile + fun getKeyForCompilationSettings(settings: CompilerOptions): String /* String & `T$29` */ + fun releaseDocument(fileName: String, compilationSettings: CompilerOptions) + fun releaseDocument(fileName: String, compilationSettings: CompilerOptions, scriptKind: ScriptKind) + fun releaseDocumentWithKey(path: String /* String & `T$3` */, key: String /* String & `T$29` */) + fun releaseDocumentWithKey(path: String /* String & `T$3` */, key: String /* String & `T$29` */, scriptKind: ScriptKind) + fun reportStats(): String +} + +external interface `T$29` { + var __bucketKey: Any +} + +external fun createDocumentRegistry(useCaseSensitiveFileNames: Boolean = definedExternally, currentDirectory: String = definedExternally): DocumentRegistry + +external fun preProcessFile(sourceText: String, readImportFiles: Boolean = definedExternally, detectJavaScriptImports: Boolean = definedExternally): PreProcessedFileInfo + +external interface TranspileOptions { + var compilerOptions: CompilerOptions? + get() = definedExternally + set(value) = definedExternally + var fileName: String? + get() = definedExternally + set(value) = definedExternally + var reportDiagnostics: Boolean? + get() = definedExternally + set(value) = definedExternally + var moduleName: String? + get() = definedExternally + set(value) = definedExternally + var renamedDependencies: MapLike? + get() = definedExternally + set(value) = definedExternally + var transformers: CustomTransformers? + get() = definedExternally + set(value) = definedExternally +} + +external interface TranspileOutput { + var outputText: String + var diagnostics: Array? + get() = definedExternally + set(value) = definedExternally + var sourceMapText: String? + get() = definedExternally + set(value) = definedExternally +} + +external fun transpileModule(input: String, transpileOptions: TranspileOptions): TranspileOutput + +external fun transpile(input: String, compilerOptions: CompilerOptions = definedExternally, fileName: String = definedExternally, diagnostics: Array = definedExternally, moduleName: String = definedExternally): String + +external var servicesVersion: Any + +external fun toEditorSettings(options: EditorOptions): EditorSettings + +external fun toEditorSettings(options: EditorSettings): EditorSettings + +external fun displayPartsToString(displayParts: Array?): String + +external fun getDefaultCompilerOptions(): CompilerOptions + +external fun getSupportedCodeFixes(): Array + +external fun createLanguageServiceSourceFile(fileName: String, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: String, setNodeParents: Boolean, scriptKind: ScriptKind = definedExternally): SourceFile + +external fun updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: String, textChangeRange: TextChangeRange?, aggressiveChecks: Boolean = definedExternally): SourceFile + +external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally, syntaxOnlyOrLanguageServiceMode: Boolean = definedExternally): LanguageService + +external fun createLanguageService(host: LanguageServiceHost): LanguageService + +external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally): LanguageService + +external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally, syntaxOnlyOrLanguageServiceMode: LanguageServiceMode = definedExternally): LanguageService + +external fun getDefaultLibFilePath(options: CompilerOptions): String + +external fun transform(source: T, transformers: Array>, compilerOptions: CompilerOptions = definedExternally): TransformationResult + +external fun transform(source: T, transformers: Array>): TransformationResult + +external fun transform(source: Array, transformers: Array>, compilerOptions: CompilerOptions = definedExternally): TransformationResult + +external fun transform(source: Array, transformers: Array>): TransformationResult + +external var createNodeArray: (elements: Array?, hasTrailingComma: Boolean?) -> NodeArray + +external var createNumericLiteral: (value: dynamic /* String | Number */, numericLiteralFlags: TokenFlags?) -> NumericLiteral + +external var createBigIntLiteral: (value: dynamic /* String | PseudoBigInt */) -> BigIntLiteral + +external object createStringLiteral { + @nativeInvoke + operator fun invoke(text: String, isSingleQuote: Boolean? = definedExternally): StringLiteral + @nativeInvoke + operator fun invoke(text: String, isSingleQuote: Boolean? = definedExternally, hasExtendedUnicodeEscape: Boolean? = definedExternally): StringLiteral +} + +external var createStringLiteralFromNode: (sourceNode: dynamic /* Identifier | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral */, isSingleQuote: Boolean?) -> StringLiteral + +external var createRegularExpressionLiteral: (text: String) -> RegularExpressionLiteral + +external var createLoopVariable: (reservedInNestedScopes: Boolean?) -> Identifier + +external var createUniqueName: (text: String, flags: GeneratedIdentifierFlags?) -> Identifier + +external var createPrivateIdentifier: (text: String) -> PrivateIdentifier + +external var createSuper: () -> SuperExpression + +external var createThis: () -> ThisExpression + +external var createNull: () -> NullLiteral + +external var createTrue: () -> TrueLiteral + +external var createFalse: () -> FalseLiteral + +external var createModifier: (kind: T) -> ModifierToken + +external var createModifiersFromModifierFlags: (flags: ModifierFlags) -> Array + +external var createQualifiedName: (left: dynamic /* Identifier | QualifiedName */, right: dynamic /* String | Identifier */) -> QualifiedName + +external var updateQualifiedName: (node: QualifiedName, left: dynamic /* Identifier | QualifiedName */, right: Identifier) -> QualifiedName + +external var createComputedPropertyName: (expression: Expression) -> ComputedPropertyName + +external var updateComputedPropertyName: (node: ComputedPropertyName, expression: Expression) -> ComputedPropertyName + +external var createTypeParameterDeclaration: (name: dynamic /* String | Identifier */, constraint: TypeNode?, defaultType: TypeNode?) -> TypeParameterDeclaration + +external var updateTypeParameterDeclaration: (node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode?, defaultType: TypeNode?) -> TypeParameterDeclaration + +external var createParameter: (decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> ParameterDeclaration + +external var updateParameter: (node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> ParameterDeclaration + +external var createDecorator: (expression: Expression) -> Decorator + +external var updateDecorator: (node: Decorator, expression: Expression) -> Decorator + +external var createProperty: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionOrExclamationToken: dynamic /* QuestionToken? | ExclamationToken? */, type: TypeNode?, initializer: Expression?) -> PropertyDeclaration + +external var updateProperty: (node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionOrExclamationToken: dynamic /* QuestionToken? | ExclamationToken? */, type: TypeNode?, initializer: Expression?) -> PropertyDeclaration + +external var createMethod: (decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> MethodDeclaration + +external var updateMethod: (node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> MethodDeclaration + +external var createConstructor: (decorators: Array?, modifiers: Array?, parameters: Array, body: Block?) -> ConstructorDeclaration + +external var updateConstructor: (node: ConstructorDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, body: Block?) -> ConstructorDeclaration + +external var createGetAccessor: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, type: TypeNode?, body: Block?) -> GetAccessorDeclaration + +external var updateGetAccessor: (node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, type: TypeNode?, body: Block?) -> GetAccessorDeclaration + +external var createSetAccessor: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, body: Block?) -> SetAccessorDeclaration + +external var updateSetAccessor: (node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, body: Block?) -> SetAccessorDeclaration + +external var createCallSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?) -> CallSignatureDeclaration + +external var updateCallSignature: (node: CallSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?) -> CallSignatureDeclaration + +external var createConstructSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?) -> ConstructSignatureDeclaration + +external var updateConstructSignature: (node: ConstructSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?) -> ConstructSignatureDeclaration + +external var updateIndexSignature: (node: IndexSignatureDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode) -> IndexSignatureDeclaration + +external var createKeywordTypeNode: (kind: TKind) -> KeywordTypeNode + +external var createTypePredicateNodeWithModifier: (assertsModifier: AssertsKeyword?, parameterName: dynamic /* String | Identifier | ThisTypeNode */, type: TypeNode?) -> TypePredicateNode + +external var updateTypePredicateNodeWithModifier: (node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: dynamic /* Identifier | ThisTypeNode */, type: TypeNode?) -> TypePredicateNode + +external var createTypeReferenceNode: (typeName: dynamic /* String | Identifier | QualifiedName */, typeArguments: Array?) -> TypeReferenceNode + +external var updateTypeReferenceNode: (node: TypeReferenceNode, typeName: dynamic /* Identifier | QualifiedName */, typeArguments: NodeArray?) -> TypeReferenceNode + +external var createFunctionTypeNode: (typeParameters: Array?, parameters: Array, type: TypeNode) -> FunctionTypeNode + +external var updateFunctionTypeNode: (node: FunctionTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode) -> FunctionTypeNode + +external var createConstructorTypeNode: (typeParameters: Array?, parameters: Array, type: TypeNode) -> ConstructorTypeNode + +external var updateConstructorTypeNode: (node: ConstructorTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode) -> ConstructorTypeNode + +external var createTypeQueryNode: (exprName: dynamic /* Identifier | QualifiedName */) -> TypeQueryNode + +external var updateTypeQueryNode: (node: TypeQueryNode, exprName: dynamic /* Identifier | QualifiedName */) -> TypeQueryNode + +external var createTypeLiteralNode: (members: Array?) -> TypeLiteralNode + +external var updateTypeLiteralNode: (node: TypeLiteralNode, members: NodeArray) -> TypeLiteralNode + +external var createArrayTypeNode: (elementType: TypeNode) -> ArrayTypeNode + +external var updateArrayTypeNode: (node: ArrayTypeNode, elementType: TypeNode) -> ArrayTypeNode + +external var createTupleTypeNode: (elements: Array) -> TupleTypeNode + +external var updateTupleTypeNode: (node: TupleTypeNode, elements: Array) -> TupleTypeNode + +external var createOptionalTypeNode: (type: TypeNode) -> OptionalTypeNode + +external var updateOptionalTypeNode: (node: OptionalTypeNode, type: TypeNode) -> OptionalTypeNode + +external var createRestTypeNode: (type: TypeNode) -> RestTypeNode + +external var updateRestTypeNode: (node: RestTypeNode, type: TypeNode) -> RestTypeNode + +external var createUnionTypeNode: (types: Array) -> UnionTypeNode + +external var updateUnionTypeNode: (node: UnionTypeNode, types: NodeArray) -> UnionTypeNode + +external var createIntersectionTypeNode: (types: Array) -> IntersectionTypeNode + +external var updateIntersectionTypeNode: (node: IntersectionTypeNode, types: NodeArray) -> IntersectionTypeNode + +external var createConditionalTypeNode: (checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) -> ConditionalTypeNode + +external var updateConditionalTypeNode: (node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) -> ConditionalTypeNode + +external var createInferTypeNode: (typeParameter: TypeParameterDeclaration) -> InferTypeNode + +external var updateInferTypeNode: (node: InferTypeNode, typeParameter: TypeParameterDeclaration) -> InferTypeNode + +external var createImportTypeNode: (argument: TypeNode, qualifier: dynamic /* Identifier? | QualifiedName? */, typeArguments: Array?, isTypeOf: Boolean?) -> ImportTypeNode + +external var updateImportTypeNode: (node: ImportTypeNode, argument: TypeNode, qualifier: dynamic /* Identifier? | QualifiedName? */, typeArguments: Array?, isTypeOf: Boolean?) -> ImportTypeNode + +external var createParenthesizedType: (type: TypeNode) -> ParenthesizedTypeNode + +external var updateParenthesizedType: (node: ParenthesizedTypeNode, type: TypeNode) -> ParenthesizedTypeNode + +external var createThisTypeNode: () -> ThisTypeNode + +external var updateTypeOperatorNode: (node: TypeOperatorNode, type: TypeNode) -> TypeOperatorNode + +external var createIndexedAccessTypeNode: (objectType: TypeNode, indexType: TypeNode) -> IndexedAccessTypeNode + +external var updateIndexedAccessTypeNode: (node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) -> IndexedAccessTypeNode + +external var createMappedTypeNode: (readonlyToken: dynamic /* ReadonlyKeyword? | PlusToken? | MinusToken? */, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */, type: TypeNode?) -> MappedTypeNode + +external var updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: dynamic /* ReadonlyKeyword? | PlusToken? | MinusToken? */, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */, type: TypeNode?) -> MappedTypeNode + +external var createLiteralTypeNode: (literal: dynamic /* LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral */) -> LiteralTypeNode + +external var updateLiteralTypeNode: (node: LiteralTypeNode, literal: dynamic /* LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral */) -> LiteralTypeNode + +external var createObjectBindingPattern: (elements: Array) -> ObjectBindingPattern + +external var updateObjectBindingPattern: (node: ObjectBindingPattern, elements: Array) -> ObjectBindingPattern + +external var createArrayBindingPattern: (elements: Array) -> ArrayBindingPattern + +external var updateArrayBindingPattern: (node: ArrayBindingPattern, elements: Array) -> ArrayBindingPattern + +external var createBindingElement: (dotDotDotToken: DotDotDotToken?, propertyName: dynamic /* String? | Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression?) -> BindingElement + +external var updateBindingElement: (node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */, name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression?) -> BindingElement + +external var createArrayLiteral: (elements: Array?, multiLine: Boolean?) -> ArrayLiteralExpression + +external var updateArrayLiteral: (node: ArrayLiteralExpression, elements: Array) -> ArrayLiteralExpression + +external var createObjectLiteral: (properties: Array?, multiLine: Boolean?) -> ObjectLiteralExpression + +external var updateObjectLiteral: (node: ObjectLiteralExpression, properties: Array) -> ObjectLiteralExpression + +external var createPropertyAccess: (expression: Expression, name: dynamic /* String | Identifier | PrivateIdentifier */) -> PropertyAccessExpression + +external var updatePropertyAccess: (node: PropertyAccessExpression, expression: Expression, name: dynamic /* Identifier | PrivateIdentifier */) -> PropertyAccessExpression + +external var createPropertyAccessChain: (expression: Expression, questionDotToken: QuestionDotToken?, name: dynamic /* String | Identifier | PrivateIdentifier */) -> PropertyAccessChain + +external var updatePropertyAccessChain: (node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: dynamic /* Identifier | PrivateIdentifier */) -> PropertyAccessChain + +external var createElementAccess: (expression: Expression, index: dynamic /* Number | Expression */) -> ElementAccessExpression + +external var updateElementAccess: (node: ElementAccessExpression, expression: Expression, argumentExpression: Expression) -> ElementAccessExpression + +external var createElementAccessChain: (expression: Expression, questionDotToken: QuestionDotToken?, index: dynamic /* Number | Expression */) -> ElementAccessChain + +external var updateElementAccessChain: (node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, argumentExpression: Expression) -> ElementAccessChain + +external var createCall: (expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> CallExpression + +external var updateCall: (node: CallExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array) -> CallExpression + +external var createCallChain: (expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array?) -> CallChain + +external var updateCallChain: (node: CallChain, expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array) -> CallChain + +external var createNew: (expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> NewExpression + +external var updateNew: (node: NewExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> NewExpression + +external var createTypeAssertion: (type: TypeNode, expression: Expression) -> TypeAssertion + +external var updateTypeAssertion: (node: TypeAssertion, type: TypeNode, expression: Expression) -> TypeAssertion + +external var createParen: (expression: Expression) -> ParenthesizedExpression + +external var updateParen: (node: ParenthesizedExpression, expression: Expression) -> ParenthesizedExpression + +external var createFunctionExpression: (modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block) -> FunctionExpression + +external var updateFunctionExpression: (node: FunctionExpression, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block) -> FunctionExpression + +external var createDelete: (expression: Expression) -> DeleteExpression + +external var updateDelete: (node: DeleteExpression, expression: Expression) -> DeleteExpression + +external var createTypeOf: (expression: Expression) -> TypeOfExpression + +external var updateTypeOf: (node: TypeOfExpression, expression: Expression) -> TypeOfExpression + +external var createVoid: (expression: Expression) -> VoidExpression + +external var updateVoid: (node: VoidExpression, expression: Expression) -> VoidExpression + +external var createAwait: (expression: Expression) -> AwaitExpression + +external var updateAwait: (node: AwaitExpression, expression: Expression) -> AwaitExpression + +external var createPrefix: (operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken | SyntaxKind.ExclamationToken */, operand: Expression) -> PrefixUnaryExpression + +external var updatePrefix: (node: PrefixUnaryExpression, operand: Expression) -> PrefixUnaryExpression + +external var createPostfix: (operand: Expression, operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken */) -> PostfixUnaryExpression + +external var updatePostfix: (node: PostfixUnaryExpression, operand: Expression) -> PostfixUnaryExpression + +external var createBinary: (left: Expression, operator: dynamic /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression) -> BinaryExpression + +external var updateConditional: (node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression) -> ConditionalExpression + +external var createTemplateExpression: (head: TemplateHead, templateSpans: Array) -> TemplateExpression + +external var updateTemplateExpression: (node: TemplateExpression, head: TemplateHead, templateSpans: Array) -> TemplateExpression + +external object createTemplateHead { + @nativeInvoke + operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateHead + @nativeInvoke + operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateHead +} + +external object createTemplateMiddle { + @nativeInvoke + operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateMiddle + @nativeInvoke + operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateMiddle +} + +external object createTemplateTail { + @nativeInvoke + operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateTail + @nativeInvoke + operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateTail +} + +external object createNoSubstitutionTemplateLiteral { + @nativeInvoke + operator fun invoke(text: String, rawText: String? = definedExternally): NoSubstitutionTemplateLiteral + @nativeInvoke + operator fun invoke(text: String?, rawText: String): NoSubstitutionTemplateLiteral +} + +external var updateYield: (node: YieldExpression, asteriskToken: AsteriskToken?, expression: Expression?) -> YieldExpression + +external var createSpread: (expression: Expression) -> SpreadElement + +external var updateSpread: (node: SpreadElement, expression: Expression) -> SpreadElement + +external var createOmittedExpression: () -> OmittedExpression + +external var createAsExpression: (expression: Expression, type: TypeNode) -> AsExpression + +external var updateAsExpression: (node: AsExpression, expression: Expression, type: TypeNode) -> AsExpression + +external var createNonNullExpression: (expression: Expression) -> NonNullExpression + +external var updateNonNullExpression: (node: NonNullExpression, expression: Expression) -> NonNullExpression + +external var createNonNullChain: (expression: Expression) -> NonNullChain + +external var updateNonNullChain: (node: NonNullChain, expression: Expression) -> NonNullChain + +external var createMetaProperty: (keywordToken: dynamic /* SyntaxKind.ImportKeyword | SyntaxKind.NewKeyword */, name: Identifier) -> MetaProperty + +external var updateMetaProperty: (node: MetaProperty, name: Identifier) -> MetaProperty + +external var createTemplateSpan: (expression: Expression, literal: dynamic /* TemplateMiddle | TemplateTail */) -> TemplateSpan + +external var updateTemplateSpan: (node: TemplateSpan, expression: Expression, literal: dynamic /* TemplateMiddle | TemplateTail */) -> TemplateSpan + +external var createSemicolonClassElement: () -> SemicolonClassElement + +external var createBlock: (statements: Array, multiLine: Boolean?) -> Block + +external var updateBlock: (node: Block, statements: Array) -> Block + +external var createVariableStatement: (modifiers: Array?, declarationList: dynamic /* VariableDeclarationList | Array */) -> VariableStatement + +external var updateVariableStatement: (node: VariableStatement, modifiers: Array?, declarationList: VariableDeclarationList) -> VariableStatement + +external var createEmptyStatement: () -> EmptyStatement + +external var createExpressionStatement: (expression: Expression) -> ExpressionStatement + +external var updateExpressionStatement: (node: ExpressionStatement, expression: Expression) -> ExpressionStatement + +external var createStatement: (expression: Expression) -> ExpressionStatement + +external var updateStatement: (node: ExpressionStatement, expression: Expression) -> ExpressionStatement + +external var createIf: (expression: Expression, thenStatement: Statement, elseStatement: Statement?) -> IfStatement + +external var updateIf: (node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement?) -> IfStatement + +external var createDo: (statement: Statement, expression: Expression) -> DoStatement + +external var updateDo: (node: DoStatement, statement: Statement, expression: Expression) -> DoStatement + +external var createWhile: (expression: Expression, statement: Statement) -> WhileStatement + +external var updateWhile: (node: WhileStatement, expression: Expression, statement: Statement) -> WhileStatement + +external var createFor: (initializer: dynamic /* VariableDeclarationList? | Expression? */, condition: Expression?, incrementor: Expression?, statement: Statement) -> ForStatement + +external var updateFor: (node: ForStatement, initializer: dynamic /* VariableDeclarationList? | Expression? */, condition: Expression?, incrementor: Expression?, statement: Statement) -> ForStatement + +external var createForIn: (initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForInStatement + +external var updateForIn: (node: ForInStatement, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForInStatement + +external var createForOf: (awaitModifier: AwaitKeyword?, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForOfStatement + +external var updateForOf: (node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForOfStatement + +external var createContinue: (label: dynamic /* String? | Identifier? */) -> ContinueStatement + +external var updateContinue: (node: ContinueStatement, label: Identifier?) -> ContinueStatement + +external var createBreak: (label: dynamic /* String? | Identifier? */) -> BreakStatement + +external var updateBreak: (node: BreakStatement, label: Identifier?) -> BreakStatement + +external var createReturn: (expression: Expression?) -> ReturnStatement + +external var updateReturn: (node: ReturnStatement, expression: Expression?) -> ReturnStatement + +external var createWith: (expression: Expression, statement: Statement) -> WithStatement + +external var updateWith: (node: WithStatement, expression: Expression, statement: Statement) -> WithStatement + +external var createSwitch: (expression: Expression, caseBlock: CaseBlock) -> SwitchStatement + +external var updateSwitch: (node: SwitchStatement, expression: Expression, caseBlock: CaseBlock) -> SwitchStatement + +external var createLabel: (label: dynamic /* String | Identifier */, statement: Statement) -> LabeledStatement + +external var updateLabel: (node: LabeledStatement, label: Identifier, statement: Statement) -> LabeledStatement + +external var createThrow: (expression: Expression) -> ThrowStatement + +external var updateThrow: (node: ThrowStatement, expression: Expression) -> ThrowStatement + +external var createTry: (tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?) -> TryStatement + +external var updateTry: (node: TryStatement, tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?) -> TryStatement + +external var createDebuggerStatement: () -> DebuggerStatement + +external var createVariableDeclarationList: (declarations: Array, flags: NodeFlags?) -> VariableDeclarationList + +external var updateVariableDeclarationList: (node: VariableDeclarationList, declarations: Array) -> VariableDeclarationList + +external var createFunctionDeclaration: (decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> FunctionDeclaration + +external var updateFunctionDeclaration: (node: FunctionDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> FunctionDeclaration + +external var createClassDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassDeclaration + +external var updateClassDeclaration: (node: ClassDeclaration, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassDeclaration + +external var createInterfaceDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> InterfaceDeclaration + +external var updateInterfaceDeclaration: (node: InterfaceDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array) -> InterfaceDeclaration + +external var createTypeAliasDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, typeParameters: Array?, type: TypeNode) -> TypeAliasDeclaration + +external var updateTypeAliasDeclaration: (node: TypeAliasDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode) -> TypeAliasDeclaration + +external var createEnumDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, members: Array) -> EnumDeclaration + +external var updateEnumDeclaration: (node: EnumDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, members: Array) -> EnumDeclaration + +external var createModuleDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral */, body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */, flags: NodeFlags?) -> ModuleDeclaration + +external var updateModuleDeclaration: (node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral */, body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */) -> ModuleDeclaration + +external var createModuleBlock: (statements: Array) -> ModuleBlock + +external var updateModuleBlock: (node: ModuleBlock, statements: Array) -> ModuleBlock + +external var createCaseBlock: (clauses: Array) -> CaseBlock + +external var updateCaseBlock: (node: CaseBlock, clauses: Array) -> CaseBlock + +external var createNamespaceExportDeclaration: (name: dynamic /* String | Identifier */) -> NamespaceExportDeclaration + +external var updateNamespaceExportDeclaration: (node: NamespaceExportDeclaration, name: Identifier) -> NamespaceExportDeclaration + +external var createImportEqualsDeclaration: (decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: dynamic /* String | Identifier */, moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */) -> ImportEqualsDeclaration + +external var updateImportEqualsDeclaration: (node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */) -> ImportEqualsDeclaration + +external var createImportDeclaration: (decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression) -> ImportDeclaration + +external var updateImportDeclaration: (node: ImportDeclaration, decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression) -> ImportDeclaration + +external var createNamespaceImport: (name: Identifier) -> NamespaceImport + +external var updateNamespaceImport: (node: NamespaceImport, name: Identifier) -> NamespaceImport + +external var createNamedImports: (elements: Array) -> NamedImports + +external var updateNamedImports: (node: NamedImports, elements: Array) -> NamedImports + +external var createImportSpecifier: (propertyName: Identifier?, name: Identifier) -> ImportSpecifier + +external var updateImportSpecifier: (node: ImportSpecifier, propertyName: Identifier?, name: Identifier) -> ImportSpecifier + +external var createExportAssignment: (decorators: Array?, modifiers: Array?, isExportEquals: Boolean?, expression: Expression) -> ExportAssignment + +external var updateExportAssignment: (node: ExportAssignment, decorators: Array?, modifiers: Array?, expression: Expression) -> ExportAssignment + +external var createNamedExports: (elements: Array) -> NamedExports + +external var updateNamedExports: (node: NamedExports, elements: Array) -> NamedExports + +external var createExportSpecifier: (propertyName: dynamic /* String? | Identifier? */, name: dynamic /* String | Identifier */) -> ExportSpecifier + +external var updateExportSpecifier: (node: ExportSpecifier, propertyName: Identifier?, name: Identifier) -> ExportSpecifier + +external var createExternalModuleReference: (expression: Expression) -> ExternalModuleReference + +external var updateExternalModuleReference: (node: ExternalModuleReference, expression: Expression) -> ExternalModuleReference + +external var createJSDocTypeExpression: (type: TypeNode) -> JSDocTypeExpression + +external var createJSDocTypeTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocTypeTag + +external var createJSDocReturnTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: dynamic /* String? | NodeArray? */) -> JSDocReturnTag + +external var createJSDocThisTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocThisTag + +external var createJSDocComment: (comment: dynamic /* String? | NodeArray? */, tags: Array?) -> JSDoc + +external var createJSDocParameterTag: (tagName: Identifier?, name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean?, comment: dynamic /* String? | NodeArray? */) -> JSDocParameterTag + +external var createJSDocClassTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocClassTag + +external var createJSDocAugmentsTag: (tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: dynamic /* String? | NodeArray? */) -> JSDocAugmentsTag + +external var createJSDocEnumTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocEnumTag + +external var createJSDocTemplateTag: (tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: dynamic /* String? | NodeArray? */) -> JSDocTemplateTag + +external var createJSDocTypedefTag: (tagName: Identifier?, typeExpression: dynamic /* JSDocTypeLiteral? | JSDocTypeExpression? */, fullName: dynamic /* Identifier? | JSDocNamespaceDeclaration? */, comment: dynamic /* String? | NodeArray? */) -> JSDocTypedefTag + +external var createJSDocCallbackTag: (tagName: Identifier?, typeExpression: JSDocSignature, fullName: dynamic /* Identifier? | JSDocNamespaceDeclaration? */, comment: dynamic /* String? | NodeArray? */) -> JSDocCallbackTag + +external var createJSDocSignature: (typeParameters: Array?, parameters: Array, type: JSDocReturnTag?) -> JSDocSignature + +external var createJSDocPropertyTag: (tagName: Identifier?, name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean?, comment: dynamic /* String? | NodeArray? */) -> JSDocPropertyTag + +external var createJSDocTypeLiteral: (jsDocPropertyTags: Array?, isArrayType: Boolean?) -> JSDocTypeLiteral + +external var createJSDocImplementsTag: (tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: dynamic /* String? | NodeArray? */) -> JSDocImplementsTag + +external var createJSDocAuthorTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocAuthorTag + +external var createJSDocPublicTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocPublicTag + +external var createJSDocPrivateTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocPrivateTag + +external var createJSDocProtectedTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocProtectedTag + +external var createJSDocReadonlyTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocReadonlyTag + +external var createJSDocTag: (tagName: Identifier, comment: dynamic /* String? | NodeArray? */) -> JSDocUnknownTag + +external var createJsxElement: (openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement) -> JsxElement + +external var updateJsxElement: (node: JsxElement, openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement) -> JsxElement + +external var createJsxSelfClosingElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxSelfClosingElement + +external var updateJsxSelfClosingElement: (node: JsxSelfClosingElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxSelfClosingElement + +external var createJsxOpeningElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxOpeningElement + +external var updateJsxOpeningElement: (node: JsxOpeningElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxOpeningElement + +external var createJsxClosingElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */) -> JsxClosingElement + +external var updateJsxClosingElement: (node: JsxClosingElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */) -> JsxClosingElement + +external var createJsxFragment: (openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment) -> JsxFragment + +external var createJsxText: (text: String, containsOnlyTriviaWhiteSpaces: Boolean?) -> JsxText + +external var updateJsxText: (node: JsxText, text: String, containsOnlyTriviaWhiteSpaces: Boolean?) -> JsxText + +external var createJsxOpeningFragment: () -> JsxOpeningFragment + +external var createJsxJsxClosingFragment: () -> JsxClosingFragment + +external var updateJsxFragment: (node: JsxFragment, openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment) -> JsxFragment + +external var createJsxAttribute: (name: Identifier, initializer: dynamic /* StringLiteral? | JsxExpression? */) -> JsxAttribute + +external var updateJsxAttribute: (node: JsxAttribute, name: Identifier, initializer: dynamic /* StringLiteral? | JsxExpression? */) -> JsxAttribute + +external var createJsxAttributes: (properties: Array) -> JsxAttributes + +external var updateJsxAttributes: (node: JsxAttributes, properties: Array) -> JsxAttributes + +external var createJsxSpreadAttribute: (expression: Expression) -> JsxSpreadAttribute + +external var updateJsxSpreadAttribute: (node: JsxSpreadAttribute, expression: Expression) -> JsxSpreadAttribute + +external var createJsxExpression: (dotDotDotToken: DotDotDotToken?, expression: Expression?) -> JsxExpression + +external var updateJsxExpression: (node: JsxExpression, expression: Expression?) -> JsxExpression + +external var createCaseClause: (expression: Expression, statements: Array) -> CaseClause + +external var updateCaseClause: (node: CaseClause, expression: Expression, statements: Array) -> CaseClause + +external var createDefaultClause: (statements: Array) -> DefaultClause + +external var updateDefaultClause: (node: DefaultClause, statements: Array) -> DefaultClause + +external var createHeritageClause: (token: dynamic /* SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword */, types: Array) -> HeritageClause + +external var updateHeritageClause: (node: HeritageClause, types: Array) -> HeritageClause + +external var createCatchClause: (variableDeclaration: dynamic /* String? | VariableDeclaration? */, block: Block) -> CatchClause + +external var updateCatchClause: (node: CatchClause, variableDeclaration: VariableDeclaration?, block: Block) -> CatchClause + +external var createPropertyAssignment: (name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression) -> PropertyAssignment + +external var updatePropertyAssignment: (node: PropertyAssignment, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression) -> PropertyAssignment + +external var createShorthandPropertyAssignment: (name: dynamic /* String | Identifier */, objectAssignmentInitializer: Expression?) -> ShorthandPropertyAssignment + +external var updateShorthandPropertyAssignment: (node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression?) -> ShorthandPropertyAssignment + +external var createSpreadAssignment: (expression: Expression) -> SpreadAssignment + +external var updateSpreadAssignment: (node: SpreadAssignment, expression: Expression) -> SpreadAssignment + +external var createEnumMember: (name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression?) -> EnumMember + +external var updateEnumMember: (node: EnumMember, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression?) -> EnumMember + +external var updateSourceFileNode: (node: SourceFile, statements: Array, isDeclarationFile: Boolean?, referencedFiles: Array?, typeReferences: Array?, hasNoDefaultLib: Boolean?, libReferences: Array?) -> SourceFile + +external var createNotEmittedStatement: (original: Node) -> NotEmittedStatement + +external var createPartiallyEmittedExpression: (expression: Expression, original: Node?) -> PartiallyEmittedExpression + +external var updatePartiallyEmittedExpression: (node: PartiallyEmittedExpression, expression: Expression) -> PartiallyEmittedExpression + +external var createCommaList: (elements: Array) -> CommaListExpression + +external var updateCommaList: (node: CommaListExpression, elements: Array) -> CommaListExpression + +external var createBundle: (sourceFiles: Array, prepends: Array?) -> Bundle + +external var updateBundle: (node: Bundle, sourceFiles: Array, prepends: Array?) -> Bundle + +external object createImmediatelyInvokedFunctionExpression { + @nativeInvoke + operator fun invoke(statements: Array): CallExpression + @nativeInvoke + operator fun invoke(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression +} + +external object createImmediatelyInvokedArrowFunction { + @nativeInvoke + operator fun invoke(statements: Array): CallExpression + @nativeInvoke + operator fun invoke(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression +} + +external var createVoidZero: () -> VoidExpression + +external var createExportDefault: (expression: Expression) -> ExportAssignment + +external var createExternalModuleExport: (exportName: Identifier) -> ExportDeclaration + +external var createNamespaceExport: (name: Identifier) -> NamespaceExport + +external var updateNamespaceExport: (node: NamespaceExport, name: Identifier) -> NamespaceExport + +external var createToken: (kind: TKind) -> Token + +external var createIdentifier: (text: String) -> Identifier + +external var createTempVariable: (recordTempVariable: ((node: Identifier) -> Unit)?) -> Identifier + +external var getGeneratedNameForNode: (node: Node?) -> Identifier + +external var createOptimisticUniqueName: (text: String) -> Identifier + +external var createFileLevelUniqueName: (text: String) -> Identifier + +external var createIndexSignature: (decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode) -> IndexSignatureDeclaration + +external var createTypePredicateNode: (parameterName: dynamic /* Identifier | ThisTypeNode | String */, type: TypeNode) -> TypePredicateNode + +external var updateTypePredicateNode: (node: TypePredicateNode, parameterName: dynamic /* Identifier | ThisTypeNode */, type: TypeNode) -> TypePredicateNode + +external object createLiteral { + @nativeInvoke + operator fun invoke(value: Any /* String | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier */): StringLiteral + @nativeInvoke + operator fun invoke(value: Any /* Number | PseudoBigInt */): NumericLiteral + @nativeInvoke + operator fun invoke(value: Boolean): dynamic /* TrueLiteral | FalseLiteral */ + @nativeInvoke + operator fun invoke(value: Any /* String | Number | PseudoBigInt | Boolean */): PrimaryExpression +} + +external var createMethodSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?) -> MethodSignature + +external var updateMethodSignature: (node: MethodSignature, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?) -> MethodSignature + +external object createTypeOperatorNode { + @nativeInvoke + operator fun invoke(type: TypeNode): TypeOperatorNode + @nativeInvoke + operator fun invoke(operator: Any /* SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword */, type: TypeNode): TypeOperatorNode +} + +external object createTaggedTemplate { + @nativeInvoke + operator fun invoke(tag: Expression, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression + @nativeInvoke + operator fun invoke(tag: Expression, typeArguments: Array?, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression +} + +external object updateTaggedTemplate { + @nativeInvoke + operator fun invoke(node: TaggedTemplateExpression, tag: Expression, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression + @nativeInvoke + operator fun invoke(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression +} + +external var updateBinary: (node: BinaryExpression, left: Expression, right: Expression, operator: dynamic /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */) -> BinaryExpression + +external object createConditional { + @nativeInvoke + operator fun invoke(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression + @nativeInvoke + operator fun invoke(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression +} + +external object createYield { + @nativeInvoke + operator fun invoke(expression: Expression? = definedExternally): YieldExpression + @nativeInvoke + operator fun invoke(asteriskToken: AsteriskToken?, expression: Expression): YieldExpression +} + +external var createClassExpression: (modifiers: Array?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassExpression + +external var updateClassExpression: (node: ClassExpression, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassExpression + +external var createPropertySignature: (modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | String */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> PropertySignature + +external var updatePropertySignature: (node: PropertySignature, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> PropertySignature + +external var createExpressionWithTypeArguments: (typeArguments: Array?, expression: Expression) -> ExpressionWithTypeArguments + +external var updateExpressionWithTypeArguments: (node: ExpressionWithTypeArguments, typeArguments: Array?, expression: Expression) -> ExpressionWithTypeArguments + +external object createArrowFunction { + @nativeInvoke + operator fun invoke(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: Any /* FunctionBody | Expression */): ArrowFunction + @nativeInvoke + operator fun invoke(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Any /* FunctionBody | Expression */): ArrowFunction +} + +external object updateArrowFunction { + @nativeInvoke + operator fun invoke(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: Any /* FunctionBody | Expression */): ArrowFunction + @nativeInvoke + operator fun invoke(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Any /* FunctionBody | Expression */): ArrowFunction +} + +external object createVariableDeclaration { + @nativeInvoke + operator fun invoke(name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, type: TypeNode? = definedExternally, initializer: Expression? = definedExternally): VariableDeclaration + @nativeInvoke + operator fun invoke(name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration +} + +external object updateVariableDeclaration { + @nativeInvoke + operator fun invoke(node: VariableDeclaration, name: Any /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, type: TypeNode?, initializer: Expression?): VariableDeclaration + @nativeInvoke + operator fun invoke(node: VariableDeclaration, name: Any /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration +} + +external var createImportClause: (name: Identifier?, namedBindings: dynamic /* NamespaceImport? | NamedImports? */, isTypeOnly: Any) -> ImportClause + +external var updateImportClause: (node: ImportClause, name: Identifier?, namedBindings: dynamic /* NamespaceImport? | NamedImports? */, isTypeOnly: Boolean) -> ImportClause + +external var createExportDeclaration: (decorators: Array?, modifiers: Array?, exportClause: dynamic /* NamespaceExport? | NamedExports? */, moduleSpecifier: Expression?, isTypeOnly: Any) -> ExportDeclaration + +external var updateExportDeclaration: (node: ExportDeclaration, decorators: Array?, modifiers: Array?, exportClause: dynamic /* NamespaceExport? | NamedExports? */, moduleSpecifier: Expression?, isTypeOnly: Boolean) -> ExportDeclaration + +external var createJSDocParamTag: (name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, comment: String?) -> JSDocParameterTag + +external var createComma: (left: Expression, right: Expression) -> Expression + +external var createLessThan: (left: Expression, right: Expression) -> Expression + +external var createAssignment: (left: Expression, right: Expression) -> BinaryExpression + +external var createStrictEquality: (left: Expression, right: Expression) -> BinaryExpression + +external var createStrictInequality: (left: Expression, right: Expression) -> BinaryExpression + +external var createAdd: (left: Expression, right: Expression) -> BinaryExpression + +external var createSubtract: (left: Expression, right: Expression) -> BinaryExpression + +external var createLogicalAnd: (left: Expression, right: Expression) -> BinaryExpression + +external var createLogicalOr: (left: Expression, right: Expression) -> BinaryExpression + +external var createPostfixIncrement: (operand: Expression) -> PostfixUnaryExpression + +external var createLogicalNot: (operand: Expression) -> PrefixUnaryExpression + +external var createNode: (kind: SyntaxKind, pos: Any, end: Any) -> Node + +external var getMutableClone: (node: T) -> T + +external var isTypeAssertion: (node: Node) -> Boolean + +external var isIdentifierOrPrivateIdentifier: (node: Node) -> Boolean \ No newline at end of file diff --git a/externals/typescript.ts.server.module_typescript.kt b/externals/typescript.ts.server.module_typescript.kt new file mode 100644 index 0000000..5a84cb3 --- /dev/null +++ b/externals/typescript.ts.server.module_typescript.kt @@ -0,0 +1,101 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package ts.server + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.CompilerOptions +import ts.WatchOptions +import ts.TypeAcquisition +import ts.SortedReadonlyArray + +external interface TypingInstallerResponse { + val kind: String /* "action::set" | "action::invalidate" | "event::typesRegistry" | "action::packageInstalled" | "event::beginInstallTypes" | "event::endInstallTypes" | "event::initializationFailed" */ +} + +external interface TypingInstallerRequestWithProjectName { + val projectName: String +} + +external interface DiscoverTypings : TypingInstallerRequestWithProjectName { + val fileNames: Array + val projectRootPath: String /* String & `T$3` */ + val compilerOptions: CompilerOptions + val watchOptions: WatchOptions? + get() = definedExternally + val typeAcquisition: TypeAcquisition + val unresolvedImports: SortedReadonlyArray + val cachePath: String? + get() = definedExternally + val kind: String /* "discover" */ +} + +external interface CloseProject : TypingInstallerRequestWithProjectName { + val kind: String /* "closeProject" */ +} + +external interface TypesRegistryRequest { + val kind: String /* "typesRegistry" */ +} + +external interface InstallPackageRequest : TypingInstallerRequestWithProjectName { + val kind: String /* "installPackage" */ + val fileName: String /* String & `T$3` */ + val packageName: String + val projectRootPath: String /* String & `T$3` */ +} + +external interface PackageInstalledResponse : ProjectResponse { + override val kind: String /* "action::packageInstalled" */ + val success: Boolean + val message: String +} + +external interface InitializationFailedResponse : TypingInstallerResponse { + override val kind: String /* "event::initializationFailed" */ + val message: String + val stack: String? + get() = definedExternally +} + +external interface ProjectResponse : TypingInstallerResponse { + val projectName: String +} + +external interface InvalidateCachedTypings : ProjectResponse { + override val kind: String /* "action::invalidate" */ +} + +external interface InstallTypes : ProjectResponse { + override val kind: String /* "event::beginInstallTypes" | "event::endInstallTypes" */ + val eventId: Number + val typingsInstallerVersion: String + val packagesToInstall: Array +} + +external interface BeginInstallTypes : InstallTypes { + override val kind: String /* "event::beginInstallTypes" */ +} + +external interface EndInstallTypes : InstallTypes { + override val kind: String /* "event::endInstallTypes" */ + val installSuccess: Boolean +} + +external interface SetTypings : ProjectResponse { + val typeAcquisition: TypeAcquisition + val compilerOptions: CompilerOptions + val typings: Array + val unresolvedImports: SortedReadonlyArray + override val kind: String /* "action::set" */ +} \ No newline at end of file diff --git a/externals/utils.module_typescript-to-lua.kt b/externals/utils.module_typescript-to-lua.kt new file mode 100644 index 0000000..08363d8 --- /dev/null +++ b/externals/utils.module_typescript-to-lua.kt @@ -0,0 +1,46 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.WriteFileCallback +import ts.SourceFile + +external interface EmitHost { + fun directoryExists(path: String): Boolean + fun fileExists(path: String): Boolean + fun getCurrentDirectory(): String + fun readFile(path: String): String? + var writeFile: WriteFileCallback +} + +external interface BaseFile { + var code: String + var sourceMap: String? + get() = definedExternally + set(value) = definedExternally + var sourceFiles: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface ProcessedFile : BaseFile { + var fileName: String + var luaAst: File? + get() = definedExternally + set(value) = definedExternally +} + +external interface EmitFile : BaseFile { + var outputPath: String +} \ No newline at end of file diff --git a/externals/visitors.module_typescript-to-lua.kt b/externals/visitors.module_typescript-to-lua.kt new file mode 100644 index 0000000..69513ac --- /dev/null +++ b/externals/visitors.module_typescript-to-lua.kt @@ -0,0 +1,38 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.Statement +import ts.Node +import tsstdlib.Map +import ts.SyntaxKind + +external interface NodesBySyntaxKind + +typealias StatementLikeNode = Statement + +typealias VisitorResult = Any + +typealias FunctionVisitor = (node: T, context: TransformationContext) -> VisitorResult + +external interface ObjectVisitor { + var transform: FunctionVisitor + var priority: Number? + get() = definedExternally + set(value) = definedExternally +} + +typealias Visitors = Any + +typealias VisitorMap = Map>> \ No newline at end of file diff --git a/externals02/CompilerOptions.module_typescript-to-lua.kt b/externals02/CompilerOptions.module_typescript-to-lua.kt new file mode 100644 index 0000000..aa83510 --- /dev/null +++ b/externals02/CompilerOptions.module_typescript-to-lua.kt @@ -0,0 +1,74 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.Diagnostic + +typealias OmitIndexSignature = Any + +external interface TransformerImport { + var transform: String + var import: String? + get() = definedExternally + set(value) = definedExternally + var after: Boolean? + get() = definedExternally + set(value) = definedExternally + var afterDeclarations: Boolean? + get() = definedExternally + set(value) = definedExternally + var type: String? /* "program" | "config" | "checker" | "raw" | "compilerOptions" */ + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): Any? + @nativeSetter + operator fun set(option: String, value: Any) +} + +external interface LuaPluginImport { + var name: String + var import: String? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): Any? + @nativeSetter + operator fun set(option: String, value: Any) +} + +external enum class LuaLibImportKind { + None /* = "none" */, + Always /* = "always" */, + Inline /* = "inline" */, + Require /* = "require" */ +} + +external enum class LuaTarget { + Universal /* = "universal" */, + Lua51 /* = "5.1" */, + Lua52 /* = "5.2" */, + Lua53 /* = "5.3" */, + Lua54 /* = "5.4" */, + LuaJIT /* = "JIT" */ +} + +external enum class BuildMode { + Default /* = "default" */, + Library /* = "library" */ +} + +external var isBundleEnabled: (options: dynamic /* typealias OmitIndexSignature = dynamic */) -> Boolean + +external fun validateOptions(options: dynamic /* typealias OmitIndexSignature = dynamic */): Array \ No newline at end of file diff --git a/externals02/LuaAST.module_typescript-to-lua.kt b/externals02/LuaAST.module_typescript-to-lua.kt new file mode 100644 index 0000000..ee5baa7 --- /dev/null +++ b/externals02/LuaAST.module_typescript-to-lua.kt @@ -0,0 +1,473 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import tsstdlib.Set + +external enum class SyntaxKind { + File /* = 0 */, + Block /* = 1 */, + DoStatement /* = 2 */, + VariableDeclarationStatement /* = 3 */, + AssignmentStatement /* = 4 */, + IfStatement /* = 5 */, + WhileStatement /* = 6 */, + RepeatStatement /* = 7 */, + ForStatement /* = 8 */, + ForInStatement /* = 9 */, + GotoStatement /* = 10 */, + LabelStatement /* = 11 */, + ReturnStatement /* = 12 */, + BreakStatement /* = 13 */, + ExpressionStatement /* = 14 */, + StringLiteral /* = 15 */, + NumericLiteral /* = 16 */, + NilKeyword /* = 17 */, + DotsKeyword /* = 18 */, + TrueKeyword /* = 19 */, + FalseKeyword /* = 20 */, + FunctionExpression /* = 21 */, + TableFieldExpression /* = 22 */, + TableExpression /* = 23 */, + UnaryExpression /* = 24 */, + BinaryExpression /* = 25 */, + CallExpression /* = 26 */, + MethodCallExpression /* = 27 */, + Identifier /* = 28 */, + TableIndexExpression /* = 29 */, + AdditionOperator /* = 30 */, + SubtractionOperator /* = 31 */, + MultiplicationOperator /* = 32 */, + DivisionOperator /* = 33 */, + FloorDivisionOperator /* = 34 */, + ModuloOperator /* = 35 */, + PowerOperator /* = 36 */, + NegationOperator /* = 37 */, + ConcatOperator /* = 38 */, + LengthOperator /* = 39 */, + EqualityOperator /* = 40 */, + InequalityOperator /* = 41 */, + LessThanOperator /* = 42 */, + LessEqualOperator /* = 43 */, + GreaterThanOperator /* = 44 */, + GreaterEqualOperator /* = 45 */, + AndOperator /* = 46 */, + OrOperator /* = 47 */, + NotOperator /* = 48 */, + BitwiseAndOperator /* = 49 */, + BitwiseOrOperator /* = 50 */, + BitwiseExclusiveOrOperator /* = 51 */, + BitwiseRightShiftOperator /* = 52 */, + BitwiseLeftShiftOperator /* = 53 */, + BitwiseNotOperator /* = 54 */ +} + +//typealias UnaryBitwiseOperator = SyntaxKind.BitwiseNotOperator + +external interface TextRange { + var line: Number? + get() = definedExternally + set(value) = definedExternally + var column: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface Node : TextRange { + var kind: SyntaxKind +} + +external fun createNode(kind: SyntaxKind, tsOriginal: ts.Node = definedExternally): Node + +external fun cloneNode(node: T): T + +external fun setNodePosition(node: T, position: TextRange): T + +external fun setNodeOriginal(node: T, tsOriginal: ts.Node): T + +external fun setNodeOriginal(node: T?, tsOriginal: ts.Node): T? + +external fun getOriginalPos(node: Node): TextRange + +external interface File : Node { + var statements: Array + var luaLibFeatures: Set + var trivia: String +} + +external fun isFile(node: Node): Boolean + +external fun createFile(statements: Array, luaLibFeatures: Set, trivia: String, tsOriginal: ts.Node = definedExternally): File + +external interface Block : Node { + var statements: Array +} + +external fun isBlock(node: Node): Boolean + +external fun createBlock(statements: Array, tsOriginal: ts.Node = definedExternally): Block + +external interface Statement : Node { + var _statementBrand: Any + var leadingComments: Array */>? + get() = definedExternally + set(value) = definedExternally + var trailingComments: Array */>? + get() = definedExternally + set(value) = definedExternally +} + +external interface DoStatement : Statement { + var statements: Array +} + +external fun isDoStatement(node: Node): Boolean + +external fun createDoStatement(statements: Array, tsOriginal: ts.Node = definedExternally): DoStatement + +external interface VariableDeclarationStatement : Statement { + var left: Array + var right: Array? + get() = definedExternally + set(value) = definedExternally +} + +external fun isVariableDeclarationStatement(node: Node): Boolean + +external fun createVariableDeclarationStatement(left: Identifier, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Identifier): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Identifier, right: Expression = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Identifier, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Identifier, right: Array = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array, right: Expression = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array, right: Array = definedExternally): VariableDeclarationStatement + +external interface AssignmentStatement : Statement { + var left: Array + var right: Array +} + +external fun isAssignmentStatement(node: Node): Boolean + +external fun createAssignmentStatement(left: Identifier, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Identifier): AssignmentStatement + +external fun createAssignmentStatement(left: Identifier, right: Expression = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Identifier, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Identifier, right: Array = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression, right: Expression = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression, right: Array = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Array, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Array): AssignmentStatement + +external fun createAssignmentStatement(left: Array, right: Expression = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Array, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Array, right: Array = definedExternally): AssignmentStatement + +external interface IfStatement : Statement { + var condition: Expression + var ifBlock: Block + var elseBlock: dynamic /* Block? | IfStatement? */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isIfStatement(node: Node): Boolean + +external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: Block = definedExternally, tsOriginal: ts.Node = definedExternally): IfStatement + +external fun createIfStatement(condition: Expression, ifBlock: Block): IfStatement + +external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: Block = definedExternally): IfStatement + +external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: IfStatement = definedExternally, tsOriginal: ts.Node = definedExternally): IfStatement + +external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: IfStatement = definedExternally): IfStatement + +external interface IterationStatement : Statement { + var body: Block +} + +external fun isIterationStatement(node: Node): Boolean + +external interface WhileStatement : IterationStatement { + var condition: Expression +} + +external fun isWhileStatement(node: Node): Boolean + +external fun createWhileStatement(body: Block, condition: Expression, tsOriginal: ts.Node = definedExternally): WhileStatement + +external interface RepeatStatement : IterationStatement { + var condition: Expression +} + +external fun isRepeatStatement(node: Node): Boolean + +external fun createRepeatStatement(body: Block, condition: Expression, tsOriginal: ts.Node = definedExternally): RepeatStatement + +external interface ForStatement : IterationStatement { + var controlVariable: Identifier + var controlVariableInitializer: Expression + var limitExpression: Expression + var stepExpression: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external fun isForStatement(node: Node): Boolean + +external fun createForStatement(body: Block, controlVariable: Identifier, controlVariableInitializer: Expression, limitExpression: Expression, stepExpression: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): ForStatement + +external interface ForInStatement : IterationStatement { + var names: Array + var expressions: Array +} + +external fun isForInStatement(node: Node): Boolean + +external fun createForInStatement(body: Block, names: Array, expressions: Array, tsOriginal: ts.Node = definedExternally): ForInStatement + +external interface GotoStatement : Statement { + var label: String +} + +external fun isGotoStatement(node: Node): Boolean + +external fun createGotoStatement(label: String, tsOriginal: ts.Node = definedExternally): GotoStatement + +external interface LabelStatement : Statement { + var name: String +} + +external fun isLabelStatement(node: Node): Boolean + +external fun createLabelStatement(name: String, tsOriginal: ts.Node = definedExternally): LabelStatement + +external interface ReturnStatement : Statement { + var expressions: Array +} + +external fun isReturnStatement(node: Node): Boolean + +external fun createReturnStatement(expressions: Array, tsOriginal: ts.Node = definedExternally): ReturnStatement + +external interface BreakStatement : Statement + +external fun isBreakStatement(node: Node): Boolean + +external fun createBreakStatement(tsOriginal: ts.Node = definedExternally): BreakStatement + +external interface ExpressionStatement : Statement { + var expression: Expression +} + +external fun isExpressionStatement(node: Node): Boolean + +external fun createExpressionStatement(expressions: Expression, tsOriginal: ts.Node = definedExternally): ExpressionStatement + +external interface Expression : Node { + var _expressionBrand: Any +} + +external interface NilLiteral : Expression + +external fun isNilLiteral(node: Node): Boolean + +external fun createNilLiteral(tsOriginal: ts.Node = definedExternally): NilLiteral + +external interface BooleanLiteral : Expression { + override var kind: dynamic /* SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isBooleanLiteral(node: Node): Boolean + +external fun createBooleanLiteral(value: Boolean, tsOriginal: ts.Node = definedExternally): BooleanLiteral + +external interface DotsLiteral : Expression + +external fun isDotsLiteral(node: Node): Boolean + +external fun createDotsLiteral(tsOriginal: ts.Node = definedExternally): DotsLiteral + +external interface NumericLiteral : Expression { + var value: Number +} + +external fun isNumericLiteral(node: Node): Boolean + +external fun createNumericLiteral(value: Number, tsOriginal: ts.Node = definedExternally): NumericLiteral + +external interface StringLiteral : Expression { + var value: String +} + +external fun isStringLiteral(node: Node): Boolean + +external fun createStringLiteral(value: String, tsOriginal: ts.Node = definedExternally): StringLiteral + +external enum class FunctionExpressionFlags { + None /* = 1 */, + Inline /* = 2 */, + Declaration /* = 4 */ +} + +external interface FunctionExpression : Expression { + var params: Array? + get() = definedExternally + set(value) = definedExternally + var dots: DotsLiteral? + get() = definedExternally + set(value) = definedExternally + var body: Block + var flags: FunctionExpressionFlags +} + +external fun isFunctionExpression(node: Node): Boolean + +external fun createFunctionExpression(body: Block, params: Array = definedExternally, dots: DotsLiteral = definedExternally, flags: FunctionExpressionFlags = definedExternally, tsOriginal: ts.Node = definedExternally): FunctionExpression + +external interface TableFieldExpression : Expression { + var value: Expression + var key: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external fun isTableFieldExpression(node: Node): Boolean + +external fun createTableFieldExpression(value: Expression, key: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): TableFieldExpression + +external interface TableExpression : Expression { + var fields: Array +} + +external fun isTableExpression(node: Node): Boolean + +external fun createTableExpression(fields: Array = definedExternally, tsOriginal: ts.Node = definedExternally): TableExpression + +external interface UnaryExpression : Expression { + var operand: Expression + var operator: dynamic /* SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isUnaryExpression(node: Node): Boolean + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind = definedExternally, tsOriginal: ts.Node = definedExternally): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind = definedExternally): UnaryExpression + +external interface BinaryExpression : Expression { + var operator: dynamic /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */ + get() = definedExternally + set(value) = definedExternally + var left: Expression + var right: Expression +} + +external fun isBinaryExpression(node: Node): Boolean + +external fun createBinaryExpression(left: Expression, right: Expression, operator: Any /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */, tsOriginal: ts.Node = definedExternally): BinaryExpression + +external interface CallExpression : Expression { + var expression: Expression + var params: Array +} + +external fun isCallExpression(node: Node): Boolean + +external fun createCallExpression(expression: Expression, params: Array, tsOriginal: ts.Node = definedExternally): CallExpression + +external interface MethodCallExpression : Expression { + var prefixExpression: Expression + var name: Identifier + var params: Array +} + +external fun isMethodCallExpression(node: Node): Boolean + +external fun createMethodCallExpression(prefixExpression: Expression, name: Identifier, params: Array, tsOriginal: ts.Node = definedExternally): MethodCallExpression + +external interface Identifier : Expression { + var exportable: Boolean + var text: String + var originalName: String? + get() = definedExternally + set(value) = definedExternally + var symbolId: Number? /* Number? & `T$18`? */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isIdentifier(node: Node): Boolean + +external fun createIdentifier(text: String, tsOriginal: ts.Node = definedExternally, symbolId: Number /* Number & `T$18` */ = definedExternally, originalName: String = definedExternally): Identifier + +external fun cloneIdentifier(identifier: Identifier, tsOriginal: ts.Node = definedExternally): Identifier + +external fun createAnonymousIdentifier(tsOriginal: ts.Node = definedExternally): Identifier + +external interface TableIndexExpression : Expression { + var table: Expression + var index: Expression +} + +external fun isTableIndexExpression(node: Node): Boolean + +external fun createTableIndexExpression(table: Expression, index: Expression, tsOriginal: ts.Node = definedExternally): TableIndexExpression + +external fun isAssignmentLeftHandSideExpression(node: Node): Boolean + +external fun isFunctionDefinition(statement: VariableDeclarationStatement): Boolean + +external fun isFunctionDefinition(statement: AssignmentStatement): Boolean + +external interface `T$21` { + var statements: dynamic /* JsTuple */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isInlineFunctionExpression(expression: FunctionExpression): Boolean diff --git a/externals02/LuaLib.module_typescript-to-lua.kt b/externals02/LuaLib.module_typescript-to-lua.kt new file mode 100644 index 0000000..f00c242 --- /dev/null +++ b/externals02/LuaLib.module_typescript-to-lua.kt @@ -0,0 +1,111 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external enum class LuaLibFeature { + ArrayConcat /* = "ArrayConcat" */, + ArrayEntries /* = "ArrayEntries" */, + ArrayEvery /* = "ArrayEvery" */, + ArrayFilter /* = "ArrayFilter" */, + ArrayForEach /* = "ArrayForEach" */, + ArrayFind /* = "ArrayFind" */, + ArrayFindIndex /* = "ArrayFindIndex" */, + ArrayIncludes /* = "ArrayIncludes" */, + ArrayIndexOf /* = "ArrayIndexOf" */, + ArrayIsArray /* = "ArrayIsArray" */, + ArrayJoin /* = "ArrayJoin" */, + ArrayMap /* = "ArrayMap" */, + ArrayPush /* = "ArrayPush" */, + ArrayReduce /* = "ArrayReduce" */, + ArrayReduceRight /* = "ArrayReduceRight" */, + ArrayReverse /* = "ArrayReverse" */, + ArrayShift /* = "ArrayShift" */, + ArrayUnshift /* = "ArrayUnshift" */, + ArraySort /* = "ArraySort" */, + ArraySlice /* = "ArraySlice" */, + ArraySome /* = "ArraySome" */, + ArraySplice /* = "ArraySplice" */, + ArrayToObject /* = "ArrayToObject" */, + ArrayFlat /* = "ArrayFlat" */, + ArrayFlatMap /* = "ArrayFlatMap" */, + ArraySetLength /* = "ArraySetLength" */, + Await /* = "Await" */, + Class /* = "Class" */, + ClassExtends /* = "ClassExtends" */, + CloneDescriptor /* = "CloneDescriptor" */, + Decorate /* = "Decorate" */, + DecorateParam /* = "DecorateParam" */, + Delete /* = "Delete" */, + DelegatedYield /* = "DelegatedYield" */, + Error /* = "Error" */, + FunctionBind /* = "FunctionBind" */, + Generator /* = "Generator" */, + InstanceOf /* = "InstanceOf" */, + InstanceOfObject /* = "InstanceOfObject" */, + Iterator /* = "Iterator" */, + Map /* = "Map" */, + MathAtan2 /* = "MathAtan2" */, + New /* = "New" */, + Number /* = "Number" */, + NumberIsFinite /* = "NumberIsFinite" */, + NumberIsNaN /* = "NumberIsNaN" */, + NumberToString /* = "NumberToString" */, + ObjectAssign /* = "ObjectAssign" */, + ObjectDefineProperty /* = "ObjectDefineProperty" */, + ObjectEntries /* = "ObjectEntries" */, + ObjectFromEntries /* = "ObjectFromEntries" */, + ObjectGetOwnPropertyDescriptor /* = "ObjectGetOwnPropertyDescriptor" */, + ObjectGetOwnPropertyDescriptors /* = "ObjectGetOwnPropertyDescriptors" */, + ObjectKeys /* = "ObjectKeys" */, + ObjectRest /* = "ObjectRest" */, + ObjectValues /* = "ObjectValues" */, + OptionalChainAccess /* = "OptionalChainAccess" */, + OptionalFunctionCall /* = "OptionalFunctionCall" */, + OptionalMethodCall /* = "OptionalMethodCall" */, + ParseFloat /* = "ParseFloat" */, + ParseInt /* = "ParseInt" */, + Promise /* = "Promise" */, + PromiseAll /* = "PromiseAll" */, + PromiseAllSettled /* = "PromiseAllSettled" */, + PromiseAny /* = "PromiseAny" */, + PromiseRace /* = "PromiseRace" */, + Set /* = "Set" */, + SetDescriptor /* = "SetDescriptor" */, + WeakMap /* = "WeakMap" */, + WeakSet /* = "WeakSet" */, + SourceMapTraceBack /* = "SourceMapTraceBack" */, + Spread /* = "Spread" */, + StringAccess /* = "StringAccess" */, + StringCharAt /* = "StringCharAt" */, + StringCharCodeAt /* = "StringCharCodeAt" */, + StringConcat /* = "StringConcat" */, + StringEndsWith /* = "StringEndsWith" */, + StringIncludes /* = "StringIncludes" */, + StringPadEnd /* = "StringPadEnd" */, + StringPadStart /* = "StringPadStart" */, + StringReplace /* = "StringReplace" */, + StringSlice /* = "StringSlice" */, + StringSplit /* = "StringSplit" */, + StringStartsWith /* = "StringStartsWith" */, + StringSubstr /* = "StringSubstr" */, + StringSubstring /* = "StringSubstring" */, + StringTrim /* = "StringTrim" */, + StringTrimEnd /* = "StringTrimEnd" */, + StringTrimStart /* = "StringTrimStart" */, + Symbol /* = "Symbol" */, + SymbolRegistry /* = "SymbolRegistry" */, + TypeOf /* = "TypeOf" */, + Unpack /* = "Unpack" */ +} \ No newline at end of file diff --git a/externals02/LuaPrinter.module_typescript-to-lua.kt b/externals02/LuaPrinter.module_typescript-to-lua.kt new file mode 100644 index 0000000..6428653 --- /dev/null +++ b/externals02/LuaPrinter.module_typescript-to-lua.kt @@ -0,0 +1,101 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.Program + +external var escapeString: (value: String) -> String + +external var tstlHeader: Any + +typealias Printer = (program: Program, emitHost: EmitHost, fileName: String, file: File) -> PrintResult + +external interface PrintResult { + var code: String + var sourceMap: String + var sourceMapNode: SourceNode +} + +external fun createPrinter(printers: Array): Printer + +external open class LuaPrinter(emitHost: EmitHost, program: Program, fileName: String) { + open var emitHost: Any + open var currentIndent: Any + open var sourceFile: Any + open var options: Any + open fun print(file: File): PrintResult + open var printInlineSourceMap: Any + open var printStackTraceOverride: Any + open var printFile: Any + open fun pushIndent() + open fun popIndent() + open fun indent(input: String = definedExternally): dynamic /* String | SourceNode */ + open fun indent(): dynamic /* String | SourceNode */ + open fun indent(input: SourceNode = definedExternally): dynamic /* String | SourceNode */ + open fun createSourceNode(node: Node, chunks: String, name: String = definedExternally): SourceNode + open fun createSourceNode(node: Node, chunks: String): SourceNode + open fun createSourceNode(node: Node, chunks: SourceNode, name: String = definedExternally): SourceNode + open fun createSourceNode(node: Node, chunks: SourceNode): SourceNode + open fun createSourceNode(node: Node, chunks: Array, name: String = definedExternally): SourceNode + open fun createSourceNode(node: Node, chunks: Array): SourceNode + open fun concatNodes(vararg chunks: Any /* String | SourceNode */): SourceNode + open fun printBlock(block: Block): SourceNode + open var statementMayRequireSemiColon: Any + open var nodeStartsWithParenthesis: Any + open fun printStatementArray(statements: Array): Array + open fun printStatement(statement: Statement): SourceNode + open fun printComment(comment: String): dynamic /* String | SourceNode */ + open fun printComment(comment: Array): dynamic /* String | SourceNode */ + open fun printStatementExcludingComments(statement: Statement): SourceNode + open fun printDoStatement(statement: DoStatement): SourceNode + open fun printVariableDeclarationStatement(statement: VariableDeclarationStatement): SourceNode + open fun printVariableAssignmentStatement(statement: AssignmentStatement): SourceNode + open fun printIfStatement(statement: IfStatement, isElseIf: Boolean = definedExternally): SourceNode + open fun printWhileStatement(statement: WhileStatement): SourceNode + open fun printRepeatStatement(statement: RepeatStatement): SourceNode + open fun printForStatement(statement: ForStatement): SourceNode + open fun printForInStatement(statement: ForInStatement): SourceNode + open fun printGotoStatement(statement: GotoStatement): SourceNode + open fun printLabelStatement(statement: LabelStatement): SourceNode + open fun printReturnStatement(statement: ReturnStatement): SourceNode + open fun printBreakStatement(statement: BreakStatement): SourceNode + open fun printExpressionStatement(statement: ExpressionStatement): SourceNode + open fun printExpression(expression: Expression): SourceNode + open fun printStringLiteral(expression: StringLiteral): SourceNode + open fun printNumericLiteral(expression: NumericLiteral): SourceNode + open fun printNilLiteral(expression: NilLiteral): SourceNode + open fun printDotsLiteral(expression: DotsLiteral): SourceNode + open fun printBooleanLiteral(expression: BooleanLiteral): SourceNode + open var printFunctionParameters: Any + open fun printFunctionExpression(expression: FunctionExpression): SourceNode + open fun printFunctionDefinition(statement: Any /* VariableDeclarationStatement | AssignmentStatement */): SourceNode + open fun printTableFieldExpression(expression: TableFieldExpression): SourceNode + open fun printTableExpression(expression: TableExpression): SourceNode + open fun printUnaryExpression(expression: UnaryExpression): SourceNode + open fun printBinaryExpression(expression: BinaryExpression): SourceNode + open var printExpressionInParenthesesIfNeeded: Any + open var needsParenthesis: Any + open fun printCallExpression(expression: CallExpression): SourceNode + open fun printMethodCallExpression(expression: MethodCallExpression): SourceNode + open fun printIdentifier(expression: Identifier): SourceNode + open fun printTableIndexExpression(expression: TableIndexExpression): SourceNode + open fun printOperator(kind: Any /* SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator | SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */): SourceNode + open fun joinChunksWithComma(chunks: Array): Array + open fun printExpressionList(expressions: Array): Array + open var buildSourceMap: Any + + companion object { + var operatorMap: Any + } +} \ No newline at end of file diff --git a/externals02/context.module_typescript-to-lua.kt b/externals02/context.module_typescript-to-lua.kt new file mode 100644 index 0000000..696e339 --- /dev/null +++ b/externals02/context.module_typescript-to-lua.kt @@ -0,0 +1,79 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.GetAccessorDeclaration +import ts.SetAccessorDeclaration +import ts.Node +import ts.ImportEqualsDeclaration +import ts.Expression +import ts.SourceFile +import ts.CancellationToken +import ts.TypeChecker +import ts.Program +import ts.Diagnostic +import Node as _Node +import Expression as _Expression +import ts.QualifiedName +import ts.ExternalModuleReference + +external interface AllAccessorDeclarations { + var firstAccessor: dynamic /* GetAccessorDeclaration | SetAccessorDeclaration */ + get() = definedExternally + set(value) = definedExternally + var secondAccessor: dynamic /* GetAccessorDeclaration? | SetAccessorDeclaration? */ + get() = definedExternally + set(value) = definedExternally + var getAccessor: GetAccessorDeclaration? + var setAccessor: SetAccessorDeclaration? +} + +external interface EmitResolver { + fun isValueAliasDeclaration(node: Node): Boolean + fun isReferencedAliasDeclaration(node: Node, checkChildren: Boolean = definedExternally): Boolean + fun isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): Boolean + fun moduleExportsSomeValue(moduleReferenceExpression: Expression): Boolean + fun getAllAccessorDeclarations(declaration: GetAccessorDeclaration): AllAccessorDeclarations + fun getAllAccessorDeclarations(declaration: SetAccessorDeclaration): AllAccessorDeclarations +} + +external interface DiagnosticsProducingTypeChecker : TypeChecker { + fun getEmitResolver(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): EmitResolver +} + +external open class TransformationContext(program: Program, sourceFile: SourceFile, visitorMap: VisitorMap) { + open var program: Program + open var sourceFile: SourceFile + open var visitorMap: Any + open val diagnostics: Array + open val checker: DiagnosticsProducingTypeChecker + open val resolver: EmitResolver + open val options: dynamic /* typealias OmitIndexSignature = dynamic */ + open val luaTarget: LuaTarget + open val isModule: Boolean + open val isStrict: Boolean + open var currentNodeVisitors: Any + open fun transformNode(node: Node): Array<_Node> + open fun superTransformNode(node: Node): Array<_Node> + open fun transformExpression(node: Expression): _Expression + open fun transformExpression(node: QualifiedName): _Expression + open fun transformExpression(node: ExternalModuleReference): _Expression + open fun superTransformExpression(node: Expression): _Expression + open fun superTransformExpression(node: QualifiedName): _Expression + open fun superTransformExpression(node: ExternalModuleReference): _Expression + open fun transformStatements(node: StatementLikeNode): Array + open fun transformStatements(node: Array): Array + open fun superTransformStatements(node: StatementLikeNode): Array + open fun superTransformStatements(node: Array): Array +} \ No newline at end of file diff --git a/externals02/index.module_typescript-to-lua.kt b/externals02/index.module_typescript-to-lua.kt new file mode 100644 index 0000000..2016698 --- /dev/null +++ b/externals02/index.module_typescript-to-lua.kt @@ -0,0 +1,38 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.WriteFileCallback +import ts.Diagnostic +import tsstdlib.Record + +external fun transpileFiles(rootNames: Array, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, writeFile: WriteFileCallback = definedExternally): EmitResult + +external fun transpileProject(configFileName: String, optionsToExtend: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, writeFile: WriteFileCallback = definedExternally): EmitResult + +external interface TranspileVirtualProjectResult { + var diagnostics: Array + var transpiledFiles: Array +} + +external fun transpileVirtualProject(files: Record, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally): TranspileVirtualProjectResult + +external interface TranspileStringResult { + var diagnostics: Array + var file: TranspiledFile? + get() = definedExternally + set(value) = definedExternally +} + +external fun transpileString(main: String, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally): TranspileStringResult \ No newline at end of file diff --git a/externals02/lib.es2015.collection.kt b/externals02/lib.es2015.collection.kt new file mode 100644 index 0000000..affffa8 --- /dev/null +++ b/externals02/lib.es2015.collection.kt @@ -0,0 +1,49 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface Map { + fun entries(): IterableIterator */> + fun keys(): IterableIterator + fun values(): IterableIterator + fun clear() + fun delete(key: K): Boolean + fun forEach(callbackfn: (value: V, key: K, map: Map) -> Unit, thisArg: Any = definedExternally) + fun get(key: K): V? + fun has(key: K): Boolean + fun set(key: K, value: V): Map /* this */ + val size: Number +} + +external interface MapConstructor { + val prototype: Map +} + +external interface Set { + fun entries(): IterableIterator */> + fun keys(): IterableIterator + fun values(): IterableIterator + fun add(value: T): Set /* this */ + fun clear() + fun delete(value: T): Boolean + fun forEach(callbackfn: (value: T, value2: T, set: Set) -> Unit, thisArg: Any = definedExternally) + fun has(value: T): Boolean + val size: Number +} + +external interface SetConstructor { + val prototype: Set +} \ No newline at end of file diff --git a/externals02/lib.es2015.iterable.kt b/externals02/lib.es2015.iterable.kt new file mode 100644 index 0000000..039ac84 --- /dev/null +++ b/externals02/lib.es2015.iterable.kt @@ -0,0 +1,54 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface IteratorYieldResult { + var done: Boolean? + get() = definedExternally + set(value) = definedExternally + var value: TYield +} + +external interface IteratorReturnResult { + var done: Boolean? + var value: TReturn +} + +external interface Iterator { + fun next(vararg args: Any /* JsTuple<> | JsTuple */): dynamic /* IteratorYieldResult | IteratorReturnResult */ + val `return`: ((value: TReturn) -> dynamic)? + val `throw`: ((e: Any) -> dynamic)? +} + +typealias Iterator__1 = Iterator + +external interface Iterable + +external interface IterableIterator : Iterator__1 + +external interface PromiseConstructor { + val prototype: Promise + fun all(values: Any /* JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple */): Promise | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple */> + fun all(values: Array */>): Promise> + fun race(values: Array): Promise + fun reject(reason: Any = definedExternally): Promise + fun resolve(value: T): Promise + fun resolve(value: PromiseLike): Promise + fun resolve(): Promise + fun all(values: Iterable */>): Promise> + fun race(values: Iterable): Promise + fun race(values: Iterable */>): Promise +} diff --git a/externals02/lib.es5.Intl.module_dukat.kt b/externals02/lib.es5.Intl.module_dukat.kt new file mode 100644 index 0000000..62cbcc7 --- /dev/null +++ b/externals02/lib.es5.Intl.module_dukat.kt @@ -0,0 +1,220 @@ +@file:JsQualifier("tsstdlib.Intl") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib.Intl + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface CollatorOptions { + var usage: String? + get() = definedExternally + set(value) = definedExternally + var localeMatcher: String? + get() = definedExternally + set(value) = definedExternally + var numeric: Boolean? + get() = definedExternally + set(value) = definedExternally + var caseFirst: String? + get() = definedExternally + set(value) = definedExternally + var sensitivity: String? + get() = definedExternally + set(value) = definedExternally + var ignorePunctuation: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedCollatorOptions { + var locale: String + var usage: String + var sensitivity: String + var ignorePunctuation: Boolean + var collation: String + var caseFirst: String + var numeric: Boolean +} + +@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface Collator { + fun compare(x: String, y: String): Number + fun resolvedOptions(): ResolvedCollatorOptions + + companion object { + @nativeInvoke + operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: CollatorOptions = definedExternally): Collator + fun supportedLocalesOf(locales: Any /* String | Array */, options: CollatorOptions = definedExternally): Array + } +} + +external interface NumberFormatOptions { + var localeMatcher: String? + get() = definedExternally + set(value) = definedExternally + var style: String? + get() = definedExternally + set(value) = definedExternally + var currency: String? + get() = definedExternally + set(value) = definedExternally + var currencyDisplay: String? + get() = definedExternally + set(value) = definedExternally + var useGrouping: Boolean? + get() = definedExternally + set(value) = definedExternally + var minimumIntegerDigits: Number? + get() = definedExternally + set(value) = definedExternally + var minimumFractionDigits: Number? + get() = definedExternally + set(value) = definedExternally + var maximumFractionDigits: Number? + get() = definedExternally + set(value) = definedExternally + var minimumSignificantDigits: Number? + get() = definedExternally + set(value) = definedExternally + var maximumSignificantDigits: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedNumberFormatOptions { + var locale: String + var numberingSystem: String + var style: String + var currency: String? + get() = definedExternally + set(value) = definedExternally + var currencyDisplay: String? + get() = definedExternally + set(value) = definedExternally + var minimumIntegerDigits: Number + var minimumFractionDigits: Number + var maximumFractionDigits: Number + var minimumSignificantDigits: Number? + get() = definedExternally + set(value) = definedExternally + var maximumSignificantDigits: Number? + get() = definedExternally + set(value) = definedExternally + var useGrouping: Boolean +} + +@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface NumberFormat { + fun format(value: Number): String + fun resolvedOptions(): ResolvedNumberFormatOptions + + companion object { + @nativeInvoke + operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: NumberFormatOptions = definedExternally): NumberFormat + fun supportedLocalesOf(locales: Any /* String | Array */, options: NumberFormatOptions = definedExternally): Array + } +} + +external interface DateTimeFormatOptions { + var localeMatcher: String? + get() = definedExternally + set(value) = definedExternally + var weekday: String? + get() = definedExternally + set(value) = definedExternally + var era: String? + get() = definedExternally + set(value) = definedExternally + var year: String? + get() = definedExternally + set(value) = definedExternally + var month: String? + get() = definedExternally + set(value) = definedExternally + var day: String? + get() = definedExternally + set(value) = definedExternally + var hour: String? + get() = definedExternally + set(value) = definedExternally + var minute: String? + get() = definedExternally + set(value) = definedExternally + var second: String? + get() = definedExternally + set(value) = definedExternally + var timeZoneName: String? + get() = definedExternally + set(value) = definedExternally + var formatMatcher: String? + get() = definedExternally + set(value) = definedExternally + var hour12: Boolean? + get() = definedExternally + set(value) = definedExternally + var timeZone: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedDateTimeFormatOptions { + var locale: String + var calendar: String + var numberingSystem: String + var timeZone: String + var hour12: Boolean? + get() = definedExternally + set(value) = definedExternally + var weekday: String? + get() = definedExternally + set(value) = definedExternally + var era: String? + get() = definedExternally + set(value) = definedExternally + var year: String? + get() = definedExternally + set(value) = definedExternally + var month: String? + get() = definedExternally + set(value) = definedExternally + var day: String? + get() = definedExternally + set(value) = definedExternally + var hour: String? + get() = definedExternally + set(value) = definedExternally + var minute: String? + get() = definedExternally + set(value) = definedExternally + var second: String? + get() = definedExternally + set(value) = definedExternally + var timeZoneName: String? + get() = definedExternally + set(value) = definedExternally +} + +@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface DateTimeFormat { + fun format(date: Date = definedExternally): String + fun format(): String + fun format(date: Number = definedExternally): String + fun resolvedOptions(): ResolvedDateTimeFormatOptions + + companion object { + @nativeInvoke + operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: DateTimeFormatOptions = definedExternally): DateTimeFormat + fun supportedLocalesOf(locales: Any /* String | Array */, options: DateTimeFormatOptions = definedExternally): Array + } +} \ No newline at end of file diff --git a/externals02/lib.es5.kt b/externals02/lib.es5.kt new file mode 100644 index 0000000..c9b2102 --- /dev/null +++ b/externals02/lib.es5.kt @@ -0,0 +1,69 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface DateConstructor { + @nativeInvoke + operator fun invoke(): String + val prototype: Date + fun parse(s: String): Number + fun UTC(year: Number, month: Number, date: Number = definedExternally, hours: Number = definedExternally, minutes: Number = definedExternally, seconds: Number = definedExternally, ms: Number = definedExternally): Number + fun now(): Number +} + +external interface ConcatArray { + val length: Number + @nativeGetter + operator fun get(n: Number): T? + @nativeSetter + operator fun set(n: Number, value: T) + fun join(separator: String = definedExternally): String + fun slice(start: Number = definedExternally, end: Number = definedExternally): Array +} + +external interface ArrayConstructor { + fun from(iterable: Iterable): Array + fun from(iterable: ArrayLike): Array + fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array + fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U): Array + fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array + fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U): Array + fun of(vararg items: T): Array + @nativeInvoke + operator fun invoke(arrayLength: Number = definedExternally): Array + @nativeInvoke + operator fun invoke(): Array + @nativeInvoke + operator fun invoke(arrayLength: Number): Array + @nativeInvoke + operator fun invoke(vararg items: T): Array + fun isArray(arg: Any): Boolean + val prototype: Array +} + +external interface PromiseLike { + fun then(onfulfilled: ((value: T) -> Any?)? = definedExternally, onrejected: ((reason: Any) -> Any?)? = definedExternally): PromiseLike +} + +external interface ArrayLike { + val length: Number + @nativeGetter + operator fun get(n: Number): T? + @nativeSetter + operator fun set(n: Number, value: T) +} + +typealias Record = Any \ No newline at end of file diff --git a/externals02/lib.scripthost.kt b/externals02/lib.scripthost.kt new file mode 100644 index 0000000..809347e --- /dev/null +++ b/externals02/lib.scripthost.kt @@ -0,0 +1,20 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external open class VarDate { + open var VarDate_typekey: VarDate +} \ No newline at end of file diff --git a/externals02/nonDeclarations.ts.kt b/externals02/nonDeclarations.ts.kt new file mode 100644 index 0000000..dbd777b --- /dev/null +++ b/externals02/nonDeclarations.ts.kt @@ -0,0 +1,122 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package ts + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +typealias SortedReadonlyArray = Array + +typealias SortedArray = Array + +typealias NodeArray = Array + +typealias DotToken = PunctuationToken + +typealias DotDotDotToken = PunctuationToken + +typealias QuestionToken = PunctuationToken + +typealias ExclamationToken = PunctuationToken + +typealias ColonToken = PunctuationToken + +typealias EqualsToken = PunctuationToken + +typealias AsteriskToken = PunctuationToken + +typealias EqualsGreaterThanToken = PunctuationToken + +typealias PlusToken = PunctuationToken + +typealias MinusToken = PunctuationToken + +typealias QuestionDotToken = PunctuationToken + +typealias AssertsKeyword = KeywordToken + +typealias AwaitKeyword = KeywordToken + +typealias AwaitKeywordToken = AwaitKeyword + +typealias AssertsToken = AssertsKeyword + +typealias AbstractKeyword = ModifierToken + +typealias AsyncKeyword = ModifierToken + +typealias ConstKeyword = ModifierToken + +typealias DeclareKeyword = ModifierToken + +typealias DefaultKeyword = ModifierToken + +typealias ExportKeyword = ModifierToken + +typealias PrivateKeyword = ModifierToken + +typealias ProtectedKeyword = ModifierToken + +typealias PublicKeyword = ModifierToken + +typealias ReadonlyKeyword = ModifierToken + +typealias OverrideKeyword = ModifierToken + +typealias StaticKeyword = ModifierToken + +typealias ReadonlyToken = ReadonlyKeyword + +typealias ModifiersArray = NodeArray + +typealias IncrementExpression = UpdateExpression + +//typealias ExponentiationOperator = SyntaxKind.AsteriskAsteriskToken + +typealias BinaryOperatorToken = Token + +typealias AssignmentOperatorToken = Token + +typealias FunctionBody = Block + +typealias WriteFileCallback = (fileName: String, data: String, writeByteOrderMark: Boolean, onError: (message: String) -> Unit, sourceFiles: Array) -> Unit + +typealias CustomTransformerFactory = (context: TransformationContext) -> CustomTransformer + +typealias SymbolTable = UnderscoreEscapedMap + +typealias JsFileExtensionInfo = FileExtensionInfo + +typealias EmitHelperUniqueNameCallback = (name: String) -> String + +typealias TransformerFactory = (context: TransformationContext) -> Transformer + +typealias Transformer = (node: T) -> T + +typealias Visitor = (node: Node) -> dynamic + +typealias FileWatcherCallback = (fileName: String, eventKind: FileWatcherEventKind) -> Unit + +typealias DirectoryWatcherCallback = (fileName: String) -> Unit + +typealias ErrorCallback = (message: DiagnosticMessage, length: Number) -> Unit + +typealias DiagnosticReporter = (diagnostic: Diagnostic) -> Unit + +typealias WatchStatusReporter = (diagnostic: Diagnostic, newLine: String, options: CompilerOptions, errorCount: Number) -> Unit + +typealias CreateProgram = (rootNames: Array?, options: CompilerOptions?, host: CompilerHost, oldProgram: T, configFileParsingDiagnostics: Array, projectReferences: Array?) -> T + +typealias ReportEmitErrorSummary = (errorCount: Number) -> Unit + +typealias CodeActionCommand = InstallPackageAction diff --git a/externals02/output-collector.module_typescript-to-lua.kt b/externals02/output-collector.module_typescript-to-lua.kt new file mode 100644 index 0000000..0c57eac --- /dev/null +++ b/externals02/output-collector.module_typescript-to-lua.kt @@ -0,0 +1,33 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.SourceFile + +external interface TranspiledFile { + var outPath: String + var sourceFiles: Array + var lua: String? + get() = definedExternally + set(value) = definedExternally + var luaSourceMap: String? + get() = definedExternally + set(value) = definedExternally + var declaration: String? + get() = definedExternally + set(value) = definedExternally + var declarationMap: String? + get() = definedExternally + set(value) = definedExternally +} \ No newline at end of file diff --git a/externals02/parse.module_typescript-to-lua.kt b/externals02/parse.module_typescript-to-lua.kt new file mode 100644 index 0000000..ff6e944 --- /dev/null +++ b/externals02/parse.module_typescript-to-lua.kt @@ -0,0 +1,25 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface ParsedCommandLine : ts.ParsedCommandLine { + override var options: dynamic /* typealias OmitIndexSignature = dynamic */ + get() = definedExternally + set(value) = definedExternally +} + +external fun updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine + +external fun parseCommandLine(args: Array): ParsedCommandLine \ No newline at end of file diff --git a/externals02/plugins.module_typescript-to-lua.kt b/externals02/plugins.module_typescript-to-lua.kt new file mode 100644 index 0000000..24d3ea4 --- /dev/null +++ b/externals02/plugins.module_typescript-to-lua.kt @@ -0,0 +1,24 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface Plugin { + var visitors: Visitors? + get() = definedExternally + set(value) = definedExternally + var printer: Printer? + get() = definedExternally + set(value) = definedExternally +} \ No newline at end of file diff --git a/externals02/report.module_typescript-to-lua.kt b/externals02/report.module_typescript-to-lua.kt new file mode 100644 index 0000000..3d2ed5e --- /dev/null +++ b/externals02/report.module_typescript-to-lua.kt @@ -0,0 +1,48 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.DiagnosticRelatedInformation +import ts.DiagnosticCategory +import ts.SourceFile +import ts.Diagnostic +import ts.System +import ts.DiagnosticReporter + +external interface `T$17` { + var code: Any + var reportsUnnecessary: Any? + get() = definedExternally + set(value) = definedExternally + var reportsDeprecated: Any? + get() = definedExternally + set(value) = definedExternally + var source: String? + get() = definedExternally + set(value) = definedExternally + var relatedInformation: Array? + get() = definedExternally + set(value) = definedExternally + var category: DiagnosticCategory + var file: SourceFile? + var start: Number? + var length: Number? + var messageText: dynamic /* String | ts.DiagnosticMessageChain */ + get() = definedExternally + set(value) = definedExternally +} + +external var prepareDiagnosticForFormatting: (diagnostic: Diagnostic) -> `T$17` + +external fun createDiagnosticReporter(pretty: Boolean, system: System = definedExternally): DiagnosticReporter \ No newline at end of file diff --git a/externals02/source-map.module_source-map.kt b/externals02/source-map.module_source-map.kt new file mode 100644 index 0000000..5961ecc --- /dev/null +++ b/externals02/source-map.module_source-map.kt @@ -0,0 +1,192 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +typealias SourceMapUrl = String + +external interface StartOfSourceMap { + var file: String? + get() = definedExternally + set(value) = definedExternally + var sourceRoot: String? + get() = definedExternally + set(value) = definedExternally + var skipValidation: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface RawSourceMap { + var version: Number + var sources: Array + var names: Array + var sourceRoot: String? + get() = definedExternally + set(value) = definedExternally + var sourcesContent: Array? + get() = definedExternally + set(value) = definedExternally + var mappings: String + var file: String +} + +external interface RawIndexMap : StartOfSourceMap { + var version: Number + var sections: Array +} + +external interface RawSection { + var offset: Position + var map: RawSourceMap +} + +external interface Position { + var line: Number + var column: Number +} + +external interface NullablePosition { + var line: Number? + var column: Number? + var lastColumn: Number? +} + +external interface MappedPosition { + var source: String + var line: Number + var column: Number + var name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface NullableMappedPosition { + var source: String? + var line: Number? + var column: Number? + var name: String? +} + +external interface MappingItem { + var source: String + var generatedLine: Number + var generatedColumn: Number + var originalLine: Number + var originalColumn: Number + var name: String +} + +external interface Mapping { + var generated: Position + var original: Position + var source: String + var name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface CodeWithSourceMap { + var code: String + var map: SourceMapGenerator +} + +external interface SourceMapConsumer { + fun computeColumnSpans() + fun originalPositionFor(generatedPosition: Position /* Position & `T$23` */): NullableMappedPosition + fun generatedPositionFor(originalPosition: MappedPosition /* MappedPosition & `T$23` */): NullablePosition + fun allGeneratedPositionsFor(originalPosition: MappedPosition): Array + fun hasContentsOfAllSources(): Boolean + fun sourceContentFor(source: String, returnNullOnMissing: Boolean = definedExternally): String? + fun eachMapping(callback: (mapping: MappingItem) -> Unit, context: Any = definedExternally, order: Number = definedExternally) + fun destroy() +} + +external interface SourceMapConsumerConstructor { + var prototype: SourceMapConsumer + var GENERATED_ORDER: Number + var ORIGINAL_ORDER: Number + var GREATEST_LOWER_BOUND: Number + var LEAST_UPPER_BOUND: Number + fun fromSourceMap(sourceMap: SourceMapGenerator, sourceMapUrl: SourceMapUrl = definedExternally): Promise + fun with(rawSourceMap: RawSourceMap, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise + fun with(rawSourceMap: RawIndexMap, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise + fun with(rawSourceMap: String, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise +} + +external interface BasicSourceMapConsumer : SourceMapConsumer { + var file: String + var sourceRoot: String + var sources: Array + var sourcesContent: Array +} + +external interface BasicSourceMapConsumerConstructor { + var prototype: BasicSourceMapConsumer + fun fromSourceMap(sourceMap: SourceMapGenerator): Promise +} + +external interface IndexedSourceMapConsumer : SourceMapConsumer { + var sources: Array +} + +external interface IndexedSourceMapConsumerConstructor { + var prototype: IndexedSourceMapConsumer +} + +external open class SourceMapGenerator(startOfSourceMap: StartOfSourceMap = definedExternally) { + open fun addMapping(mapping: Mapping) + open fun setSourceContent(sourceFile: String, sourceContent: String) + open fun applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile: String = definedExternally, sourceMapPath: String = definedExternally) + override fun toString(): String + open fun toJSON(): RawSourceMap + + companion object { + fun fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator + } +} + +external open class SourceNode { + open var children: Array + open var sourceContents: Any + open var line: Number + open var column: Number + open var source: String + open var name: String + constructor() + constructor(line: Number?, column: Number?, source: String?, chunks: Array = definedExternally, name: String = definedExternally) + constructor(line: Number?, column: Number?, source: String?) + constructor(line: Number?, column: Number?, source: String?, chunks: Array = definedExternally) + constructor(line: Number?, column: Number?, source: String?, chunks: SourceNode = definedExternally, name: String = definedExternally) + constructor(line: Number?, column: Number?, source: String?, chunks: SourceNode = definedExternally) + constructor(line: Number?, column: Number?, source: String?, chunks: String = definedExternally, name: String = definedExternally) + constructor(line: Number?, column: Number?, source: String?, chunks: String = definedExternally) + open fun add(chunk: Array): SourceNode + open fun add(chunk: SourceNode): SourceNode + open fun add(chunk: String): SourceNode + open fun prepend(chunk: Array): SourceNode + open fun prepend(chunk: SourceNode): SourceNode + open fun prepend(chunk: String): SourceNode + open fun setSourceContent(sourceFile: String, sourceContent: String) + open fun walk(fn: (chunk: String, mapping: MappedPosition) -> Unit) + open fun walkSourceContents(fn: (file: String, content: String) -> Unit) + open fun join(sep: String): SourceNode + open fun replaceRight(pattern: String, replacement: String): SourceNode + override fun toString(): String + open fun toStringWithSourceMap(startOfSourceMap: StartOfSourceMap = definedExternally): CodeWithSourceMap + + companion object { + fun fromStringWithSourceMap(code: String, sourceMapConsumer: SourceMapConsumer, relativePath: String = definedExternally): SourceNode + } +} \ No newline at end of file diff --git a/externals02/transpile.module_typescript-to-lua.kt b/externals02/transpile.module_typescript-to-lua.kt new file mode 100644 index 0000000..8681706 --- /dev/null +++ b/externals02/transpile.module_typescript-to-lua.kt @@ -0,0 +1,40 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.Program +import ts.SourceFile +import ts.CustomTransformers +import ts.Diagnostic +import ts.WriteFileCallback + +external interface TranspileOptions { + var program: Program + var sourceFiles: Array? + get() = definedExternally + set(value) = definedExternally + var customTransformers: CustomTransformers? + get() = definedExternally + set(value) = definedExternally + var plugins: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface TranspileResult { + var diagnostics: Array + var transpiledFiles: Array +} + +external fun getProgramTranspileResult(emitHost: EmitHost, writeFileResult: WriteFileCallback, __2: TranspileOptions): TranspileResult \ No newline at end of file diff --git a/externals02/transpiler.module_typescript-to-lua.kt b/externals02/transpiler.module_typescript-to-lua.kt new file mode 100644 index 0000000..227fec5 --- /dev/null +++ b/externals02/transpiler.module_typescript-to-lua.kt @@ -0,0 +1,55 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.WriteFileCallback +import ts.Diagnostic +import ts.Program + +external interface TranspilerOptions { + var emitHost: EmitHost? + get() = definedExternally + set(value) = definedExternally +} + +external interface EmitOptions : TranspileOptions { + var writeFile: WriteFileCallback? + get() = definedExternally + set(value) = definedExternally +} + +external interface EmitResult { + var emitSkipped: Boolean + var diagnostics: Array +} + +external interface `T$24` { + var emitPlan: Array +} + +external open class Transpiler(__0: TranspilerOptions = definedExternally) { + open var emitHost: EmitHost + open fun emit(emitOptions: EmitOptions): EmitResult + open fun getEmitPlan(program: Program, diagnostics: Array, files: Array): `T$24` +} + +external fun getEmitPath(file: String, program: Program): String + +external fun getEmitPathRelativeToOutDir(fileName: String, program: Program): String + +external fun getSourceDir(program: Program): String + +external fun getEmitOutDir(program: Program): String + +external fun getProjectRoot(program: Program): String \ No newline at end of file diff --git a/externals02/tsconfig.module_typescript-to-lua.kt b/externals02/tsconfig.module_typescript-to-lua.kt new file mode 100644 index 0000000..865bc70 --- /dev/null +++ b/externals02/tsconfig.module_typescript-to-lua.kt @@ -0,0 +1,18 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.System + +external fun parseConfigFileWithSystem(configFileName: String, commandLineOptions: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, system: System = definedExternally): ParsedCommandLine \ No newline at end of file diff --git a/externals02/typescript.module_typescript.kt b/externals02/typescript.module_typescript.kt new file mode 100644 index 0000000..83261af --- /dev/null +++ b/externals02/typescript.module_typescript.kt @@ -0,0 +1,19 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun setTimeout(handler: (args: Any) -> Unit, timeout: Number): Any + +external fun clearTimeout(handle: Any) \ No newline at end of file diff --git a/externals02/typescript.ts.ScriptSnapshot.module_typescript.kt b/externals02/typescript.ts.ScriptSnapshot.module_typescript.kt new file mode 100644 index 0000000..acab3da --- /dev/null +++ b/externals02/typescript.ts.ScriptSnapshot.module_typescript.kt @@ -0,0 +1,20 @@ +@file:JsQualifier("ts.ScriptSnapshot") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package ts.ScriptSnapshot + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.IScriptSnapshot + +external fun fromString(text: String): IScriptSnapshot \ No newline at end of file diff --git a/externals02/typescript.ts.module_typescript.kt b/externals02/typescript.ts.module_typescript.kt new file mode 100644 index 0000000..6fd58a3 --- /dev/null +++ b/externals02/typescript.ts.module_typescript.kt @@ -0,0 +1,8129 @@ +@file:JsModule("typescript") +@file:JsNonModule +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +package ts + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external var versionMajorMinor: Any + +external var version: String + +external interface MapLike { + @nativeGetter + operator fun get(index: String): T? + @nativeSetter + operator fun set(index: String, value: T) +} + +external interface ReadonlyCollection { + val size: Number + fun has(key: K): Boolean + fun keys(): Iterator +} + +external interface Collection : ReadonlyCollection { + fun delete(key: K): Boolean + fun clear() +} + +external interface ReadonlyESMap : ReadonlyCollection { + fun get(key: K): V? + fun values(): Iterator + fun entries(): Iterator */> + fun forEach(action: (value: V, key: K) -> Unit) +} + +external interface ReadonlyMap : ReadonlyESMap + +external interface ESMap : ReadonlyESMap, Collection { + fun set(key: K, value: V): ESMap /* this */ +} + +external interface Map : ESMap + +external interface ReadonlySet : ReadonlyCollection { + override fun has(key: T): Boolean + fun values(): Iterator + fun entries(): Iterator */> + fun forEach(action: (value: T, key: T) -> Unit) +} + +external interface Set : ReadonlySet, Collection { + fun add(value: T): Set /* this */ + override fun delete(key: T): Boolean +} + +external interface `T$1` { + var value: T + var done: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$2` { + var value: Unit + var done: Boolean? +} + +external interface Iterator { + fun next(): dynamic /* `T$1` | `T$2` */ +} + +external interface Push { + fun push(vararg values: T) +} + +external interface `T$3` { + var __pathBrand: Any +} + +external interface TextRange { + var pos: Number + var end: Number +} + +external interface ReadonlyTextRange { + val pos: Number + val end: Number +} + +external enum class SyntaxKind { + Unknown /* = 0 */, + EndOfFileToken /* = 1 */, + SingleLineCommentTrivia /* = 2 */, + MultiLineCommentTrivia /* = 3 */, + NewLineTrivia /* = 4 */, + WhitespaceTrivia /* = 5 */, + ShebangTrivia /* = 6 */, + ConflictMarkerTrivia /* = 7 */, + NumericLiteral /* = 8 */, + BigIntLiteral /* = 9 */, + StringLiteral /* = 10 */, + JsxText /* = 11 */, + JsxTextAllWhiteSpaces /* = 12 */, + RegularExpressionLiteral /* = 13 */, + NoSubstitutionTemplateLiteral /* = 14 */, + TemplateHead /* = 15 */, + TemplateMiddle /* = 16 */, + TemplateTail /* = 17 */, + OpenBraceToken /* = 18 */, + CloseBraceToken /* = 19 */, + OpenParenToken /* = 20 */, + CloseParenToken /* = 21 */, + OpenBracketToken /* = 22 */, + CloseBracketToken /* = 23 */, + DotToken /* = 24 */, + DotDotDotToken /* = 25 */, + SemicolonToken /* = 26 */, + CommaToken /* = 27 */, + QuestionDotToken /* = 28 */, + LessThanToken /* = 29 */, + LessThanSlashToken /* = 30 */, + GreaterThanToken /* = 31 */, + LessThanEqualsToken /* = 32 */, + GreaterThanEqualsToken /* = 33 */, + EqualsEqualsToken /* = 34 */, + ExclamationEqualsToken /* = 35 */, + EqualsEqualsEqualsToken /* = 36 */, + ExclamationEqualsEqualsToken /* = 37 */, + EqualsGreaterThanToken /* = 38 */, + PlusToken /* = 39 */, + MinusToken /* = 40 */, + AsteriskToken /* = 41 */, + AsteriskAsteriskToken /* = 42 */, + SlashToken /* = 43 */, + PercentToken /* = 44 */, + PlusPlusToken /* = 45 */, + MinusMinusToken /* = 46 */, + LessThanLessThanToken /* = 47 */, + GreaterThanGreaterThanToken /* = 48 */, + GreaterThanGreaterThanGreaterThanToken /* = 49 */, + AmpersandToken /* = 50 */, + BarToken /* = 51 */, + CaretToken /* = 52 */, + ExclamationToken /* = 53 */, + TildeToken /* = 54 */, + AmpersandAmpersandToken /* = 55 */, + BarBarToken /* = 56 */, + QuestionToken /* = 57 */, + ColonToken /* = 58 */, + AtToken /* = 59 */, + QuestionQuestionToken /* = 60 */, + BacktickToken /* = 61 */, + EqualsToken /* = 62 */, + PlusEqualsToken /* = 63 */, + MinusEqualsToken /* = 64 */, + AsteriskEqualsToken /* = 65 */, + AsteriskAsteriskEqualsToken /* = 66 */, + SlashEqualsToken /* = 67 */, + PercentEqualsToken /* = 68 */, + LessThanLessThanEqualsToken /* = 69 */, + GreaterThanGreaterThanEqualsToken /* = 70 */, + GreaterThanGreaterThanGreaterThanEqualsToken /* = 71 */, + AmpersandEqualsToken /* = 72 */, + BarEqualsToken /* = 73 */, + BarBarEqualsToken /* = 74 */, + AmpersandAmpersandEqualsToken /* = 75 */, + QuestionQuestionEqualsToken /* = 76 */, + CaretEqualsToken /* = 77 */, + Identifier /* = 78 */, + PrivateIdentifier /* = 79 */, + BreakKeyword /* = 80 */, + CaseKeyword /* = 81 */, + CatchKeyword /* = 82 */, + ClassKeyword /* = 83 */, + ConstKeyword /* = 84 */, + ContinueKeyword /* = 85 */, + DebuggerKeyword /* = 86 */, + DefaultKeyword /* = 87 */, + DeleteKeyword /* = 88 */, + DoKeyword /* = 89 */, + ElseKeyword /* = 90 */, + EnumKeyword /* = 91 */, + ExportKeyword /* = 92 */, + ExtendsKeyword /* = 93 */, + FalseKeyword /* = 94 */, + FinallyKeyword /* = 95 */, + ForKeyword /* = 96 */, + FunctionKeyword /* = 97 */, + IfKeyword /* = 98 */, + ImportKeyword /* = 99 */, + InKeyword /* = 100 */, + InstanceOfKeyword /* = 101 */, + NewKeyword /* = 102 */, + NullKeyword /* = 103 */, + ReturnKeyword /* = 104 */, + SuperKeyword /* = 105 */, + SwitchKeyword /* = 106 */, + ThisKeyword /* = 107 */, + ThrowKeyword /* = 108 */, + TrueKeyword /* = 109 */, + TryKeyword /* = 110 */, + TypeOfKeyword /* = 111 */, + VarKeyword /* = 112 */, + VoidKeyword /* = 113 */, + WhileKeyword /* = 114 */, + WithKeyword /* = 115 */, + ImplementsKeyword /* = 116 */, + InterfaceKeyword /* = 117 */, + LetKeyword /* = 118 */, + PackageKeyword /* = 119 */, + PrivateKeyword /* = 120 */, + ProtectedKeyword /* = 121 */, + PublicKeyword /* = 122 */, + StaticKeyword /* = 123 */, + YieldKeyword /* = 124 */, + AbstractKeyword /* = 125 */, + AsKeyword /* = 126 */, + AssertsKeyword /* = 127 */, + AnyKeyword /* = 128 */, + AsyncKeyword /* = 129 */, + AwaitKeyword /* = 130 */, + BooleanKeyword /* = 131 */, + ConstructorKeyword /* = 132 */, + DeclareKeyword /* = 133 */, + GetKeyword /* = 134 */, + InferKeyword /* = 135 */, + IntrinsicKeyword /* = 136 */, + IsKeyword /* = 137 */, + KeyOfKeyword /* = 138 */, + ModuleKeyword /* = 139 */, + NamespaceKeyword /* = 140 */, + NeverKeyword /* = 141 */, + ReadonlyKeyword /* = 142 */, + RequireKeyword /* = 143 */, + NumberKeyword /* = 144 */, + ObjectKeyword /* = 145 */, + SetKeyword /* = 146 */, + StringKeyword /* = 147 */, + SymbolKeyword /* = 148 */, + TypeKeyword /* = 149 */, + UndefinedKeyword /* = 150 */, + UniqueKeyword /* = 151 */, + UnknownKeyword /* = 152 */, + FromKeyword /* = 153 */, + GlobalKeyword /* = 154 */, + BigIntKeyword /* = 155 */, + OverrideKeyword /* = 156 */, + OfKeyword /* = 157 */, + QualifiedName /* = 158 */, + ComputedPropertyName /* = 159 */, + TypeParameter /* = 160 */, + Parameter /* = 161 */, + Decorator /* = 162 */, + PropertySignature /* = 163 */, + PropertyDeclaration /* = 164 */, + MethodSignature /* = 165 */, + MethodDeclaration /* = 166 */, + Constructor /* = 167 */, + GetAccessor /* = 168 */, + SetAccessor /* = 169 */, + CallSignature /* = 170 */, + ConstructSignature /* = 171 */, + IndexSignature /* = 172 */, + TypePredicate /* = 173 */, + TypeReference /* = 174 */, + FunctionType /* = 175 */, + ConstructorType /* = 176 */, + TypeQuery /* = 177 */, + TypeLiteral /* = 178 */, + ArrayType /* = 179 */, + TupleType /* = 180 */, + OptionalType /* = 181 */, + RestType /* = 182 */, + UnionType /* = 183 */, + IntersectionType /* = 184 */, + ConditionalType /* = 185 */, + InferType /* = 186 */, + ParenthesizedType /* = 187 */, + ThisType /* = 188 */, + TypeOperator /* = 189 */, + IndexedAccessType /* = 190 */, + MappedType /* = 191 */, + LiteralType /* = 192 */, + NamedTupleMember /* = 193 */, + TemplateLiteralType /* = 194 */, + TemplateLiteralTypeSpan /* = 195 */, + ImportType /* = 196 */, + ObjectBindingPattern /* = 197 */, + ArrayBindingPattern /* = 198 */, + BindingElement /* = 199 */, + ArrayLiteralExpression /* = 200 */, + ObjectLiteralExpression /* = 201 */, + PropertyAccessExpression /* = 202 */, + ElementAccessExpression /* = 203 */, + CallExpression /* = 204 */, + NewExpression /* = 205 */, + TaggedTemplateExpression /* = 206 */, + TypeAssertionExpression /* = 207 */, + ParenthesizedExpression /* = 208 */, + FunctionExpression /* = 209 */, + ArrowFunction /* = 210 */, + DeleteExpression /* = 211 */, + TypeOfExpression /* = 212 */, + VoidExpression /* = 213 */, + AwaitExpression /* = 214 */, + PrefixUnaryExpression /* = 215 */, + PostfixUnaryExpression /* = 216 */, + BinaryExpression /* = 217 */, + ConditionalExpression /* = 218 */, + TemplateExpression /* = 219 */, + YieldExpression /* = 220 */, + SpreadElement /* = 221 */, + ClassExpression /* = 222 */, + OmittedExpression /* = 223 */, + ExpressionWithTypeArguments /* = 224 */, + AsExpression /* = 225 */, + NonNullExpression /* = 226 */, + MetaProperty /* = 227 */, + SyntheticExpression /* = 228 */, + TemplateSpan /* = 229 */, + SemicolonClassElement /* = 230 */, + Block /* = 231 */, + EmptyStatement /* = 232 */, + VariableStatement /* = 233 */, + ExpressionStatement /* = 234 */, + IfStatement /* = 235 */, + DoStatement /* = 236 */, + WhileStatement /* = 237 */, + ForStatement /* = 238 */, + ForInStatement /* = 239 */, + ForOfStatement /* = 240 */, + ContinueStatement /* = 241 */, + BreakStatement /* = 242 */, + ReturnStatement /* = 243 */, + WithStatement /* = 244 */, + SwitchStatement /* = 245 */, + LabeledStatement /* = 246 */, + ThrowStatement /* = 247 */, + TryStatement /* = 248 */, + DebuggerStatement /* = 249 */, + VariableDeclaration /* = 250 */, + VariableDeclarationList /* = 251 */, + FunctionDeclaration /* = 252 */, + ClassDeclaration /* = 253 */, + InterfaceDeclaration /* = 254 */, + TypeAliasDeclaration /* = 255 */, + EnumDeclaration /* = 256 */, + ModuleDeclaration /* = 257 */, + ModuleBlock /* = 258 */, + CaseBlock /* = 259 */, + NamespaceExportDeclaration /* = 260 */, + ImportEqualsDeclaration /* = 261 */, + ImportDeclaration /* = 262 */, + ImportClause /* = 263 */, + NamespaceImport /* = 264 */, + NamedImports /* = 265 */, + ImportSpecifier /* = 266 */, + ExportAssignment /* = 267 */, + ExportDeclaration /* = 268 */, + NamedExports /* = 269 */, + NamespaceExport /* = 270 */, + ExportSpecifier /* = 271 */, + MissingDeclaration /* = 272 */, + ExternalModuleReference /* = 273 */, + JsxElement /* = 274 */, + JsxSelfClosingElement /* = 275 */, + JsxOpeningElement /* = 276 */, + JsxClosingElement /* = 277 */, + JsxFragment /* = 278 */, + JsxOpeningFragment /* = 279 */, + JsxClosingFragment /* = 280 */, + JsxAttribute /* = 281 */, + JsxAttributes /* = 282 */, + JsxSpreadAttribute /* = 283 */, + JsxExpression /* = 284 */, + CaseClause /* = 285 */, + DefaultClause /* = 286 */, + HeritageClause /* = 287 */, + CatchClause /* = 288 */, + PropertyAssignment /* = 289 */, + ShorthandPropertyAssignment /* = 290 */, + SpreadAssignment /* = 291 */, + EnumMember /* = 292 */, + UnparsedPrologue /* = 293 */, + UnparsedPrepend /* = 294 */, + UnparsedText /* = 295 */, + UnparsedInternalText /* = 296 */, + UnparsedSyntheticReference /* = 297 */, + SourceFile /* = 298 */, + Bundle /* = 299 */, + UnparsedSource /* = 300 */, + InputFiles /* = 301 */, + JSDocTypeExpression /* = 302 */, + JSDocNameReference /* = 303 */, + JSDocAllType /* = 304 */, + JSDocUnknownType /* = 305 */, + JSDocNullableType /* = 306 */, + JSDocNonNullableType /* = 307 */, + JSDocOptionalType /* = 308 */, + JSDocFunctionType /* = 309 */, + JSDocVariadicType /* = 310 */, + JSDocNamepathType /* = 311 */, + JSDocComment /* = 312 */, + JSDocText /* = 313 */, + JSDocTypeLiteral /* = 314 */, + JSDocSignature /* = 315 */, + JSDocLink /* = 316 */, + JSDocTag /* = 317 */, + JSDocAugmentsTag /* = 318 */, + JSDocImplementsTag /* = 319 */, + JSDocAuthorTag /* = 320 */, + JSDocDeprecatedTag /* = 321 */, + JSDocClassTag /* = 322 */, + JSDocPublicTag /* = 323 */, + JSDocPrivateTag /* = 324 */, + JSDocProtectedTag /* = 325 */, + JSDocReadonlyTag /* = 326 */, + JSDocOverrideTag /* = 327 */, + JSDocCallbackTag /* = 328 */, + JSDocEnumTag /* = 329 */, + JSDocParameterTag /* = 330 */, + JSDocReturnTag /* = 331 */, + JSDocThisTag /* = 332 */, + JSDocTypeTag /* = 333 */, + JSDocTemplateTag /* = 334 */, + JSDocTypedefTag /* = 335 */, + JSDocSeeTag /* = 336 */, + JSDocPropertyTag /* = 337 */, + SyntaxList /* = 338 */, + NotEmittedStatement /* = 339 */, + PartiallyEmittedExpression /* = 340 */, + CommaListExpression /* = 341 */, + MergeDeclarationMarker /* = 342 */, + EndOfDeclarationMarker /* = 343 */, + SyntheticReferenceExpression /* = 344 */, + Count /* = 345 */, + FirstAssignment /* = 62 */, + LastAssignment /* = 77 */, + FirstCompoundAssignment /* = 63 */, + LastCompoundAssignment /* = 77 */, + FirstReservedWord /* = 80 */, + LastReservedWord /* = 115 */, + FirstKeyword /* = 80 */, + LastKeyword /* = 157 */, + FirstFutureReservedWord /* = 116 */, + LastFutureReservedWord /* = 124 */, + FirstTypeNode /* = 173 */, + LastTypeNode /* = 196 */, + FirstPunctuation /* = 18 */, + LastPunctuation /* = 77 */, + FirstToken /* = 0 */, + LastToken /* = 157 */, + FirstTriviaToken /* = 2 */, + LastTriviaToken /* = 7 */, + FirstLiteralToken /* = 8 */, + LastLiteralToken /* = 14 */, + FirstTemplateToken /* = 14 */, + LastTemplateToken /* = 17 */, + FirstBinaryOperator /* = 29 */, + LastBinaryOperator /* = 77 */, + FirstStatement /* = 233 */, + LastStatement /* = 249 */, + FirstNode /* = 158 */, + FirstJSDocNode /* = 302 */, + LastJSDocNode /* = 337 */, + FirstJSDocTagNode /* = 317 */, + LastJSDocTagNode /* = 337 */ +} + +external enum class NodeFlags { + None /* = 0 */, + Let /* = 1 */, + Const /* = 2 */, + NestedNamespace /* = 4 */, + Synthesized /* = 8 */, + Namespace /* = 16 */, + OptionalChain /* = 32 */, + ExportContext /* = 64 */, + ContainsThis /* = 128 */, + HasImplicitReturn /* = 256 */, + HasExplicitReturn /* = 512 */, + GlobalAugmentation /* = 1024 */, + HasAsyncFunctions /* = 2048 */, + DisallowInContext /* = 4096 */, + YieldContext /* = 8192 */, + DecoratorContext /* = 16384 */, + AwaitContext /* = 32768 */, + ThisNodeHasError /* = 65536 */, + JavaScriptFile /* = 131072 */, + ThisNodeOrAnySubNodesHasError /* = 262144 */, + HasAggregatedChildData /* = 524288 */, + JSDoc /* = 4194304 */, + JsonFile /* = 33554432 */, + BlockScoped /* = 3 */, + ReachabilityCheckFlags /* = 768 */, + ReachabilityAndEmitFlags /* = 2816 */, + ContextFlags /* = 25358336 */, + TypeExcludesFlags /* = 40960 */ +} + +external enum class ModifierFlags { + None /* = 0 */, + Export /* = 1 */, + Ambient /* = 2 */, + Public /* = 4 */, + Private /* = 8 */, + Protected /* = 16 */, + Static /* = 32 */, + Readonly /* = 64 */, + Abstract /* = 128 */, + Async /* = 256 */, + Default /* = 512 */, + Const /* = 2048 */, + HasComputedJSDocModifiers /* = 4096 */, + Deprecated /* = 8192 */, + Override /* = 16384 */, + HasComputedFlags /* = 536870912 */, + AccessibilityModifier /* = 28 */, + ParameterPropertyModifier /* = 16476 */, + NonPublicAccessibilityModifier /* = 24 */, + TypeScriptModifier /* = 18654 */, + ExportDefault /* = 513 */, + All /* = 27647 */ +} + +external enum class JsxFlags { + None /* = 0 */, + IntrinsicNamedElement /* = 1 */, + IntrinsicIndexedElement /* = 2 */, + IntrinsicElement /* = 3 */ +} + +external interface Node : ReadonlyTextRange { + fun getSourceFile(): SourceFile + fun getChildCount(sourceFile: SourceFile = definedExternally): Number + fun getChildAt(index: Number, sourceFile: SourceFile = definedExternally): Node + fun getChildren(sourceFile: SourceFile = definedExternally): Array + fun getStart(sourceFile: SourceFile = definedExternally, includeJsDocComment: Boolean = definedExternally): Number + fun getFullStart(): Number + fun getEnd(): Number + fun getWidth(sourceFile: SourceFileLike = definedExternally): Number + fun getFullWidth(): Number + fun getLeadingTriviaWidth(sourceFile: SourceFile = definedExternally): Number + fun getFullText(sourceFile: SourceFile = definedExternally): String + fun getText(sourceFile: SourceFile = definedExternally): String + fun getFirstToken(sourceFile: SourceFile = definedExternally): Node? + fun getLastToken(sourceFile: SourceFile = definedExternally): Node? + fun forEachChild(cbNode: (node: Node) -> T?, cbNodeArray: (nodes: NodeArray) -> T? = definedExternally): T? + val kind: SyntaxKind + val flags: NodeFlags + val decorators: NodeArray? + get() = definedExternally + val modifiers: ModifiersArray? + get() = definedExternally + val parent: Node +} + +external interface JSDocContainer + +external interface Token : Node { + override val kind: TKind +} + +external interface PunctuationToken : Token + +external interface KeywordToken : Token + +external interface ModifierToken : KeywordToken + +external enum class GeneratedIdentifierFlags { + None /* = 0 */, + ReservedInNestedScopes /* = 8 */, + Optimistic /* = 16 */, + FileLevel /* = 32 */, + AllowNameSubstitution /* = 64 */ +} + +external interface Identifier : PrimaryExpression, Declaration { + val text: String + val escapedText: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + get() = definedExternally + val originalKeywordKind: SyntaxKind? + get() = definedExternally + var isInJSDocNamespace: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TransientIdentifier : Identifier { + var resolvedSymbol: Symbol +} + +external interface QualifiedName : Node { + val left: dynamic /* Identifier | QualifiedName */ + get() = definedExternally + val right: Identifier +} + +external interface Declaration : Node { + var _declarationBrand: Any +} + +external interface NamedDeclaration : Declaration { + val name: dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ + get() = definedExternally +} + +external interface DeclarationStatement : NamedDeclaration, Statement { + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? */ + get() = definedExternally +} + +external interface ComputedPropertyName : Node { + override val parent: Declaration + val expression: Expression +} + +external interface PrivateIdentifier : Node { + val text: String + val escapedText: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + get() = definedExternally +} + +external interface Decorator : Node { + override val parent: NamedDeclaration + val expression: LeftHandSideExpression +} + +external interface TypeParameterDeclaration : NamedDeclaration { + override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | InferTypeNode */ + get() = definedExternally + override val name: Identifier + val constraint: TypeNode? + get() = definedExternally + val default: TypeNode? + get() = definedExternally + var expression: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureDeclarationBase : NamedDeclaration, JSDocContainer { + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + val typeParameters: NodeArray? + get() = definedExternally + val parameters: NodeArray + val type: TypeNode? + get() = definedExternally +} + +external interface CallSignatureDeclaration : SignatureDeclarationBase, TypeElement { + override val kind: SyntaxKind + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally +} + +external interface ConstructSignatureDeclaration : SignatureDeclarationBase, TypeElement { + override val kind: SyntaxKind + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally +} + +external interface VariableDeclaration : NamedDeclaration, JSDocContainer { + override val parent: dynamic /* VariableDeclarationList | CatchClause */ + get() = definedExternally + override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ + get() = definedExternally + val exclamationToken: ExclamationToken? + get() = definedExternally + val type: TypeNode? + get() = definedExternally + val initializer: Expression? + get() = definedExternally +} + +external interface VariableDeclarationList : Node { + override val parent: dynamic /* VariableStatement | ForStatement | ForOfStatement | ForInStatement */ + get() = definedExternally + val declarations: NodeArray +} + +external interface ParameterDeclaration : NamedDeclaration, JSDocContainer { + override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ + get() = definedExternally + val dotDotDotToken: DotDotDotToken? + get() = definedExternally + override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ + get() = definedExternally + val questionToken: QuestionToken? + get() = definedExternally + val type: TypeNode? + get() = definedExternally + val initializer: Expression? + get() = definedExternally +} + +external interface BindingElement : NamedDeclaration { + override val parent: dynamic /* ObjectBindingPattern | ArrayBindingPattern */ + get() = definedExternally + val propertyName: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + val dotDotDotToken: DotDotDotToken? + get() = definedExternally + override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ + get() = definedExternally + val initializer: Expression? + get() = definedExternally +} + +external interface PropertySignature : TypeElement, JSDocContainer { + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + override val questionToken: QuestionToken? + get() = definedExternally + val type: TypeNode? + get() = definedExternally + var initializer: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface PropertyDeclaration : ClassElement, JSDocContainer { + override val parent: dynamic /* ClassDeclaration | ClassExpression */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + val questionToken: QuestionToken? + get() = definedExternally + val exclamationToken: ExclamationToken? + get() = definedExternally + val type: TypeNode? + get() = definedExternally + val initializer: Expression? + get() = definedExternally +} + +external interface ObjectLiteralElement : NamedDeclaration { + var _objectLiteralBrand: Any + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally +} + +external interface PropertyAssignment : ObjectLiteralElement, JSDocContainer { + override val parent: ObjectLiteralExpression + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + val questionToken: QuestionToken? + get() = definedExternally + val exclamationToken: ExclamationToken? + get() = definedExternally + val initializer: Expression +} + +external interface ShorthandPropertyAssignment : ObjectLiteralElement, JSDocContainer { + override val parent: ObjectLiteralExpression + override val name: Identifier + val questionToken: QuestionToken? + get() = definedExternally + val exclamationToken: ExclamationToken? + get() = definedExternally + val equalsToken: EqualsToken? + get() = definedExternally + val objectAssignmentInitializer: Expression? + get() = definedExternally +} + +external interface SpreadAssignment : ObjectLiteralElement, JSDocContainer { + override val parent: ObjectLiteralExpression + val expression: Expression +} + +external interface PropertyLikeDeclaration : NamedDeclaration { + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally +} + +external interface ObjectBindingPattern : Node { + override val parent: dynamic /* VariableDeclaration | ParameterDeclaration | BindingElement */ + get() = definedExternally + val elements: NodeArray +} + +external interface ArrayBindingPattern : Node { + override val parent: dynamic /* VariableDeclaration | ParameterDeclaration | BindingElement */ + get() = definedExternally + val elements: NodeArray +} + +external interface FunctionLikeDeclarationBase : SignatureDeclarationBase { + var _functionLikeDeclarationBrand: Any + val asteriskToken: AsteriskToken? + get() = definedExternally + val questionToken: QuestionToken? + get() = definedExternally + val exclamationToken: ExclamationToken? + get() = definedExternally + val body: dynamic /* Block? | Expression? */ + get() = definedExternally +} + +external interface FunctionDeclaration : FunctionLikeDeclarationBase, DeclarationStatement { + override val kind: SyntaxKind + override val name: Identifier? + get() = definedExternally + override val body: FunctionBody? + get() = definedExternally +} + +external interface MethodSignature : SignatureDeclarationBase, TypeElement { + override val kind: SyntaxKind + override val parent: dynamic /* ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally +} + +external interface MethodDeclaration : FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { + override val kind: SyntaxKind + override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + override val body: FunctionBody? + get() = definedExternally +} + +external interface ConstructorDeclaration : FunctionLikeDeclarationBase, ClassElement, JSDocContainer { + override val kind: SyntaxKind + override val parent: dynamic /* ClassDeclaration | ClassExpression */ + get() = definedExternally + override val body: FunctionBody? + get() = definedExternally + override val name: dynamic + get() = definedExternally +} + +external interface SemicolonClassElement : ClassElement { + override val parent: dynamic /* ClassDeclaration | ClassExpression */ + get() = definedExternally +} + +external interface GetAccessorDeclaration : FunctionLikeDeclarationBase, ClassElement, TypeElement, ObjectLiteralElement, JSDocContainer { + override val kind: SyntaxKind + override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression | TypeLiteralNode | InterfaceDeclaration */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + override val body: FunctionBody? + get() = definedExternally + override val questionToken: QuestionToken? + get() = definedExternally +} + +external interface SetAccessorDeclaration : FunctionLikeDeclarationBase, ClassElement, TypeElement, ObjectLiteralElement, JSDocContainer { + override val kind: SyntaxKind + override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression | TypeLiteralNode | InterfaceDeclaration */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + override val body: FunctionBody? + get() = definedExternally + override val questionToken: QuestionToken? + get() = definedExternally +} + +external interface IndexSignatureDeclaration : SignatureDeclarationBase, ClassElement, TypeElement { + override val kind: SyntaxKind + override val parent: dynamic /* ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode */ + get() = definedExternally + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally +} + +external interface TypeNode : Node { + var _typeNodeBrand: Any +} + +external interface KeywordTypeNode : KeywordToken, TypeNode { + override val kind: TKind +} + +external interface ImportTypeNode : NodeWithTypeArguments { + val isTypeOf: Boolean? + val argument: TypeNode + val qualifier: dynamic /* Identifier? | QualifiedName? */ + get() = definedExternally +} + +external interface ThisTypeNode : TypeNode + +external interface FunctionOrConstructorTypeNodeBase : TypeNode, SignatureDeclarationBase { + override val kind: dynamic /* SyntaxKind.FunctionType | SyntaxKind.ConstructorType */ + get() = definedExternally +} + +external interface FunctionTypeNode : FunctionOrConstructorTypeNodeBase { + override val kind: Any +} + +external interface ConstructorTypeNode : FunctionOrConstructorTypeNodeBase { + override val kind: Any +} + +external interface NodeWithTypeArguments : TypeNode { + val typeArguments: NodeArray? + get() = definedExternally +} + +external interface TypeReferenceNode : NodeWithTypeArguments { + val typeName: dynamic /* Identifier | QualifiedName */ + get() = definedExternally +} + +external interface TypePredicateNode : TypeNode { + override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | JSDocTypeExpression */ + get() = definedExternally + val assertsModifier: AssertsToken? + get() = definedExternally + val parameterName: dynamic /* Identifier | ThisTypeNode */ + get() = definedExternally + val type: TypeNode? + get() = definedExternally +} + +external interface TypeQueryNode : TypeNode { + val exprName: dynamic /* Identifier | QualifiedName */ + get() = definedExternally +} + +external interface TypeLiteralNode : TypeNode, Declaration { + val members: NodeArray +} + +external interface ArrayTypeNode : TypeNode { + val elementType: TypeNode +} + +external interface TupleTypeNode : TypeNode { + val elements: NodeArray +} + +external interface NamedTupleMember : TypeNode, JSDocContainer, Declaration { + val dotDotDotToken: Token? + get() = definedExternally + val name: Identifier + val questionToken: Token? + get() = definedExternally + val type: TypeNode +} + +external interface OptionalTypeNode : TypeNode { + val type: TypeNode +} + +external interface RestTypeNode : TypeNode { + val type: TypeNode +} + +external interface UnionTypeNode : TypeNode { + val types: NodeArray +} + +external interface IntersectionTypeNode : TypeNode { + val types: NodeArray +} + +external interface ConditionalTypeNode : TypeNode { + val checkType: TypeNode + val extendsType: TypeNode + val trueType: TypeNode + val falseType: TypeNode +} + +external interface InferTypeNode : TypeNode { + val typeParameter: TypeParameterDeclaration +} + +external interface ParenthesizedTypeNode : TypeNode { + val type: TypeNode +} + +external interface TypeOperatorNode : TypeNode { + val operator: dynamic /* SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword */ + get() = definedExternally + val type: TypeNode +} + +external interface IndexedAccessTypeNode : TypeNode { + val objectType: TypeNode + val indexType: TypeNode +} + +external interface MappedTypeNode : TypeNode, Declaration { + val readonlyToken: dynamic /* ReadonlyToken? | PlusToken? | MinusToken? */ + get() = definedExternally + val typeParameter: TypeParameterDeclaration + val nameType: TypeNode? + get() = definedExternally + val questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */ + get() = definedExternally + val type: TypeNode? + get() = definedExternally +} + +external interface LiteralTypeNode : TypeNode { + val literal: dynamic /* NullLiteral | TrueLiteral | FalseLiteral | LiteralExpression | PrefixUnaryExpression */ + get() = definedExternally +} + +external interface StringLiteral : LiteralExpression, Declaration + +external interface TemplateLiteralTypeNode : TypeNode { + val head: TemplateHead + val templateSpans: NodeArray +} + +external interface TemplateLiteralTypeSpan : TypeNode { + override val parent: TemplateLiteralTypeNode + val type: TypeNode + val literal: dynamic /* TemplateMiddle | TemplateTail */ + get() = definedExternally +} + +external interface Expression : Node { + var _expressionBrand: Any +} + +external interface OmittedExpression : Expression + +external interface PartiallyEmittedExpression : LeftHandSideExpression { + val expression: Expression +} + +external interface UnaryExpression : Expression { + var _unaryExpressionBrand: Any +} + +external interface UpdateExpression : UnaryExpression { + var _updateExpressionBrand: Any +} + +external interface PrefixUnaryExpression : UpdateExpression { + val operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken | SyntaxKind.ExclamationToken */ + get() = definedExternally + val operand: UnaryExpression +} + +external interface PostfixUnaryExpression : UpdateExpression { + val operand: LeftHandSideExpression + val operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken */ + get() = definedExternally +} + +external interface LeftHandSideExpression : UpdateExpression { + var _leftHandSideExpressionBrand: Any +} + +external interface MemberExpression : LeftHandSideExpression { + var _memberExpressionBrand: Any +} + +external interface PrimaryExpression : MemberExpression { + var _primaryExpressionBrand: Any +} + +external interface NullLiteral : PrimaryExpression + +external interface TrueLiteral : PrimaryExpression + +external interface FalseLiteral : PrimaryExpression + +external interface ThisExpression : PrimaryExpression + +external interface SuperExpression : PrimaryExpression + +external interface ImportExpression : PrimaryExpression + +external interface DeleteExpression : UnaryExpression { + val expression: UnaryExpression +} + +external interface TypeOfExpression : UnaryExpression { + val expression: UnaryExpression +} + +external interface VoidExpression : UnaryExpression { + val expression: UnaryExpression +} + +external interface AwaitExpression : UnaryExpression { + val expression: UnaryExpression +} + +external interface YieldExpression : Expression { + val asteriskToken: AsteriskToken? + get() = definedExternally + val expression: Expression? + get() = definedExternally +} + +external interface SyntheticExpression : Expression { + val isSpread: Boolean? + val type: Type + val tupleNameSource: dynamic /* ParameterDeclaration? | NamedTupleMember? */ + get() = definedExternally +} + +external interface BinaryExpression : Expression, Declaration { + val left: Expression + val operatorToken: BinaryOperatorToken + val right: Expression +} + +external interface AssignmentExpression : BinaryExpression { + override val left: LeftHandSideExpression + override val operatorToken: TOperator +} + +external interface ObjectDestructuringAssignment : AssignmentExpression { + override val left: ObjectLiteralExpression +} + +external interface ArrayDestructuringAssignment : AssignmentExpression { + override val left: ArrayLiteralExpression +} + +external interface ConditionalExpression : Expression { + val condition: Expression + val questionToken: QuestionToken + val whenTrue: Expression + val colonToken: ColonToken + val whenFalse: Expression +} + +external interface FunctionExpression : PrimaryExpression, FunctionLikeDeclarationBase, JSDocContainer { + override val kind: SyntaxKind + override val name: Identifier? + get() = definedExternally + override val body: FunctionBody +} + +external interface ArrowFunction : Expression, FunctionLikeDeclarationBase, JSDocContainer { + override val kind: SyntaxKind + val equalsGreaterThanToken: EqualsGreaterThanToken + override val body: dynamic /* FunctionBody | Expression */ + get() = definedExternally + override val name: Any +} + +external interface LiteralLikeNode : Node { + var text: String + var isUnterminated: Boolean? + get() = definedExternally + set(value) = definedExternally + var hasExtendedUnicodeEscape: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TemplateLiteralLikeNode : LiteralLikeNode { + var rawText: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface LiteralExpression : LiteralLikeNode, PrimaryExpression { + var _literalExpressionBrand: Any +} + +external interface RegularExpressionLiteral : LiteralExpression + +external interface NoSubstitutionTemplateLiteral : LiteralExpression, TemplateLiteralLikeNode, Declaration + +external enum class TokenFlags { + None /* = 0 */, + Scientific /* = 16 */, + Octal /* = 32 */, + HexSpecifier /* = 64 */, + BinarySpecifier /* = 128 */, + OctalSpecifier /* = 256 */ +} + +external interface NumericLiteral : LiteralExpression, Declaration + +external interface BigIntLiteral : LiteralExpression + +external interface TemplateHead : TemplateLiteralLikeNode { + override val parent: dynamic /* TemplateExpression | TemplateLiteralTypeNode */ + get() = definedExternally +} + +external interface TemplateMiddle : TemplateLiteralLikeNode { + override val parent: dynamic /* TemplateSpan | TemplateLiteralTypeSpan */ + get() = definedExternally +} + +external interface TemplateTail : TemplateLiteralLikeNode { + override val parent: dynamic /* TemplateSpan | TemplateLiteralTypeSpan */ + get() = definedExternally +} + +external interface TemplateExpression : PrimaryExpression { + val head: TemplateHead + val templateSpans: NodeArray +} + +external interface TemplateSpan : Node { + override val parent: TemplateExpression + val expression: Expression + val literal: dynamic /* TemplateMiddle | TemplateTail */ + get() = definedExternally +} + +external interface ParenthesizedExpression : PrimaryExpression, JSDocContainer { + val expression: Expression +} + +external interface ArrayLiteralExpression : PrimaryExpression { + val elements: NodeArray +} + +external interface SpreadElement : Expression { + override val parent: dynamic /* ArrayLiteralExpression | CallExpression | NewExpression */ + get() = definedExternally + val expression: Expression +} + +external interface ObjectLiteralExpressionBase : PrimaryExpression, Declaration { + val properties: NodeArray +} + +external interface ObjectLiteralExpression : ObjectLiteralExpressionBase + +external interface PropertyAccessExpression : MemberExpression, NamedDeclaration { + val expression: LeftHandSideExpression + val questionDotToken: QuestionDotToken? + get() = definedExternally + override val name: dynamic /* Identifier | PrivateIdentifier */ + get() = definedExternally +} + +external interface PropertyAccessChain : PropertyAccessExpression { + var _optionalChainBrand: Any + override val name: dynamic /* Identifier | PrivateIdentifier */ + get() = definedExternally +} + +external interface SuperPropertyAccessExpression : PropertyAccessExpression { + override val expression: SuperExpression +} + +external interface PropertyAccessEntityNameExpression : PropertyAccessExpression { + var _propertyAccessExpressionLikeQualifiedNameBrand: Any? + get() = definedExternally + set(value) = definedExternally + override val expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ + get() = definedExternally + override val name: Identifier +} + +external interface ElementAccessExpression : MemberExpression { + val expression: LeftHandSideExpression + val questionDotToken: QuestionDotToken? + get() = definedExternally + val argumentExpression: Expression +} + +external interface ElementAccessChain : ElementAccessExpression { + var _optionalChainBrand: Any +} + +external interface SuperElementAccessExpression : ElementAccessExpression { + override val expression: SuperExpression +} + +external interface CallExpression : LeftHandSideExpression, Declaration { + val expression: LeftHandSideExpression + val questionDotToken: QuestionDotToken? + get() = definedExternally + val typeArguments: NodeArray? + get() = definedExternally + val arguments: NodeArray +} + +external interface CallChain : CallExpression { + var _optionalChainBrand: Any +} + +external interface SuperCall : CallExpression { + override val expression: SuperExpression +} + +external interface ImportCall : CallExpression { + override val expression: ImportExpression +} + +external interface ExpressionWithTypeArguments : NodeWithTypeArguments { + override val parent: dynamic /* HeritageClause | JSDocAugmentsTag | JSDocImplementsTag */ + get() = definedExternally + val expression: LeftHandSideExpression +} + +external interface NewExpression : PrimaryExpression, Declaration { + val expression: LeftHandSideExpression + val typeArguments: NodeArray? + get() = definedExternally + val arguments: NodeArray? + get() = definedExternally +} + +external interface TaggedTemplateExpression : MemberExpression { + val tag: LeftHandSideExpression + val typeArguments: NodeArray? + get() = definedExternally + val template: dynamic /* TemplateExpression | NoSubstitutionTemplateLiteral */ + get() = definedExternally +} + +external interface AsExpression : Expression { + val expression: Expression + val type: TypeNode +} + +external interface TypeAssertion : UnaryExpression { + val type: TypeNode + val expression: UnaryExpression +} + +external interface NonNullExpression : LeftHandSideExpression { + val expression: Expression +} + +external interface NonNullChain : NonNullExpression { + var _optionalChainBrand: Any +} + +external interface MetaProperty : PrimaryExpression { + val keywordToken: dynamic /* SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword */ + get() = definedExternally + val name: Identifier +} + +external interface JsxElement : PrimaryExpression { + val openingElement: JsxOpeningElement + val children: NodeArray + val closingElement: JsxClosingElement +} + +external interface JsxTagNamePropertyAccess : PropertyAccessExpression { + override val expression: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ + get() = definedExternally +} + +external interface JsxAttributes : ObjectLiteralExpressionBase { + override val parent: dynamic /* JsxSelfClosingElement | JsxOpeningElement */ + get() = definedExternally +} + +external interface JsxOpeningElement : Expression { + override val parent: JsxElement + val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ + get() = definedExternally + val typeArguments: NodeArray? + get() = definedExternally + val attributes: JsxAttributes +} + +external interface JsxSelfClosingElement : PrimaryExpression { + val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ + get() = definedExternally + val typeArguments: NodeArray? + get() = definedExternally + val attributes: JsxAttributes +} + +external interface JsxFragment : PrimaryExpression { + val openingFragment: JsxOpeningFragment + val children: NodeArray + val closingFragment: JsxClosingFragment +} + +external interface JsxOpeningFragment : Expression { + override val parent: JsxFragment +} + +external interface JsxClosingFragment : Expression { + override val parent: JsxFragment +} + +external interface JsxAttribute : ObjectLiteralElement { + override val parent: JsxAttributes + override val name: Identifier + val initializer: dynamic /* StringLiteral? | JsxExpression? */ + get() = definedExternally +} + +external interface JsxSpreadAttribute : ObjectLiteralElement { + override val parent: JsxAttributes + val expression: Expression +} + +external interface JsxClosingElement : Node { + override val parent: JsxElement + val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ + get() = definedExternally +} + +external interface JsxExpression : Expression { + override val parent: dynamic /* JsxElement | JsxAttribute | JsxSpreadAttribute */ + get() = definedExternally + val dotDotDotToken: Token? + get() = definedExternally + val expression: Expression? + get() = definedExternally +} + +external interface JsxText : LiteralLikeNode { + override val parent: JsxElement + val containsOnlyTriviaWhiteSpaces: Boolean? +} + +external interface Statement : Node, JSDocContainer { + var _statementBrand: Any +} + +external interface NotEmittedStatement : Statement + +external interface CommaListExpression : Expression { + val elements: NodeArray +} + +external interface EmptyStatement : Statement + +external interface DebuggerStatement : Statement + +external interface MissingDeclaration : DeclarationStatement { + override val name: Identifier? + get() = definedExternally +} + +external interface Block : Statement { + val statements: NodeArray +} + +external interface VariableStatement : Statement { + val declarationList: VariableDeclarationList +} + +external interface ExpressionStatement : Statement { + val expression: Expression +} + +external interface IfStatement : Statement { + val expression: Expression + val thenStatement: Statement + val elseStatement: Statement? + get() = definedExternally +} + +external interface IterationStatement : Statement { + val statement: Statement +} + +external interface DoStatement : IterationStatement { + val expression: Expression +} + +external interface WhileStatement : IterationStatement { + val expression: Expression +} + +external interface ForStatement : IterationStatement { + val initializer: dynamic /* VariableDeclarationList? | Expression? */ + get() = definedExternally + val condition: Expression? + get() = definedExternally + val incrementor: Expression? + get() = definedExternally +} + +external interface ForInStatement : IterationStatement { + val initializer: dynamic /* VariableDeclarationList | Expression */ + get() = definedExternally + val expression: Expression +} + +external interface ForOfStatement : IterationStatement { + val awaitModifier: AwaitKeywordToken? + get() = definedExternally + val initializer: dynamic /* VariableDeclarationList | Expression */ + get() = definedExternally + val expression: Expression +} + +external interface BreakStatement : Statement { + val label: Identifier? + get() = definedExternally +} + +external interface ContinueStatement : Statement { + val label: Identifier? + get() = definedExternally +} + +external interface ReturnStatement : Statement { + val expression: Expression? + get() = definedExternally +} + +external interface WithStatement : Statement { + val expression: Expression + val statement: Statement +} + +external interface SwitchStatement : Statement { + val expression: Expression + val caseBlock: CaseBlock + var possiblyExhaustive: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface CaseBlock : Node { + override val parent: SwitchStatement + val clauses: NodeArray +} + +external interface CaseClause : Node { + override val parent: CaseBlock + val expression: Expression + val statements: NodeArray +} + +external interface DefaultClause : Node { + override val parent: CaseBlock + val statements: NodeArray +} + +external interface LabeledStatement : Statement { + val label: Identifier + val statement: Statement +} + +external interface ThrowStatement : Statement { + val expression: Expression +} + +external interface TryStatement : Statement { + val tryBlock: Block + val catchClause: CatchClause? + get() = definedExternally + val finallyBlock: Block? + get() = definedExternally +} + +external interface CatchClause : Node { + override val parent: TryStatement + val variableDeclaration: VariableDeclaration? + get() = definedExternally + val block: Block +} + +external interface ClassLikeDeclarationBase : NamedDeclaration, JSDocContainer { + override val kind: dynamic /* SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression */ + get() = definedExternally + override val name: Identifier? + get() = definedExternally + val typeParameters: NodeArray? + get() = definedExternally + val heritageClauses: NodeArray? + get() = definedExternally + val members: NodeArray +} + +external interface ClassDeclaration : ClassLikeDeclarationBase, DeclarationStatement { + override val kind: SyntaxKind + override val name: Identifier? + get() = definedExternally +} + +external interface ClassExpression : ClassLikeDeclarationBase, PrimaryExpression { + override val kind: SyntaxKind +} + +external interface ClassElement : NamedDeclaration { + var _classElementBrand: Any + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally +} + +external interface TypeElement : NamedDeclaration { + var _typeElementBrand: Any + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + val questionToken: QuestionToken? + get() = definedExternally +} + +external interface InterfaceDeclaration : DeclarationStatement, JSDocContainer { + override val name: Identifier + val typeParameters: NodeArray? + get() = definedExternally + val heritageClauses: NodeArray? + get() = definedExternally + val members: NodeArray +} + +external interface HeritageClause : Node { + override val parent: dynamic /* InterfaceDeclaration | ClassDeclaration | ClassExpression */ + get() = definedExternally + val token: dynamic /* SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword */ + get() = definedExternally + val types: NodeArray +} + +external interface TypeAliasDeclaration : DeclarationStatement, JSDocContainer { + override val name: Identifier + val typeParameters: NodeArray? + get() = definedExternally + val type: TypeNode +} + +external interface EnumMember : NamedDeclaration, JSDocContainer { + override val parent: EnumDeclaration + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + val initializer: Expression? + get() = definedExternally +} + +external interface EnumDeclaration : DeclarationStatement, JSDocContainer { + override val name: Identifier + val members: NodeArray +} + +external interface ModuleDeclaration : DeclarationStatement, JSDocContainer { + override val parent: dynamic /* ModuleBlock | NamespaceDeclaration | Identifier | JSDocNamespaceDeclaration | SourceFile */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral */ + get() = definedExternally + val body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */ + get() = definedExternally +} + +external interface NamespaceDeclaration : ModuleDeclaration { + override val name: Identifier + override val body: dynamic /* ModuleBlock | NamespaceDeclaration */ + get() = definedExternally +} + +external interface JSDocNamespaceDeclaration : ModuleDeclaration { + override val name: Identifier + override val body: dynamic /* Identifier? | JSDocNamespaceDeclaration? */ + get() = definedExternally +} + +external interface ModuleBlock : Node, Statement { + override val parent: ModuleDeclaration + val statements: NodeArray +} + +external interface ImportEqualsDeclaration : DeclarationStatement, JSDocContainer { + override val parent: dynamic /* SourceFile | ModuleBlock */ + get() = definedExternally + override val name: Identifier + val isTypeOnly: Boolean? + val moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */ + get() = definedExternally +} + +external interface ExternalModuleReference : Node { + override val parent: ImportEqualsDeclaration + val expression: Expression +} + +external interface ImportDeclaration : Statement { + override val parent: dynamic /* SourceFile | ModuleBlock */ + get() = definedExternally + val importClause: ImportClause? + get() = definedExternally + val moduleSpecifier: Expression +} + +external interface ImportClause : NamedDeclaration { + override val parent: ImportDeclaration + val isTypeOnly: Boolean? + override val name: Identifier? + get() = definedExternally + val namedBindings: dynamic /* NamespaceImport? | NamedImports? */ + get() = definedExternally +} + +external interface NamespaceImport : NamedDeclaration { + override val parent: ImportClause + override val name: Identifier +} + +external interface NamespaceExport : NamedDeclaration { + override val parent: ExportDeclaration + override val name: Identifier +} + +external interface NamespaceExportDeclaration : DeclarationStatement, JSDocContainer { + override val name: Identifier +} + +external interface ExportDeclaration : DeclarationStatement, JSDocContainer { + override val parent: dynamic /* SourceFile | ModuleBlock */ + get() = definedExternally + val isTypeOnly: Boolean? + val exportClause: dynamic /* NamespaceExport? | NamedExports? */ + get() = definedExternally + val moduleSpecifier: Expression? + get() = definedExternally +} + +external interface NamedImports : Node { + override val parent: ImportClause + val elements: NodeArray +} + +external interface NamedExports : Node { + override val parent: ExportDeclaration + val elements: NodeArray +} + +external interface ImportSpecifier : NamedDeclaration { + override val parent: NamedImports + val propertyName: Identifier? + get() = definedExternally + override val name: Identifier +} + +external interface ExportSpecifier : NamedDeclaration { + override val parent: NamedExports + val propertyName: Identifier? + get() = definedExternally + override val name: Identifier +} + +external interface ExportAssignment : DeclarationStatement, JSDocContainer { + override val parent: SourceFile + val isExportEquals: Boolean? + get() = definedExternally + val expression: Expression +} + +external interface FileReference : TextRange { + var fileName: String +} + +external interface CheckJsDirective : TextRange { + var enabled: Boolean? +} + +external interface CommentRange : TextRange { + var hasTrailingNewLine: Boolean? + get() = definedExternally + set(value) = definedExternally + var kind: dynamic /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */ + get() = definedExternally + set(value) = definedExternally +} + +external interface SynthesizedComment : CommentRange { + var text: String + var hasLeadingNewline: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface JSDocTypeExpression : TypeNode { + val type: TypeNode +} + +external interface JSDocNameReference : Node { + val name: dynamic /* Identifier | QualifiedName */ + get() = definedExternally +} + +external interface JSDocType : TypeNode { + var _jsDocTypeBrand: Any +} + +external interface JSDocAllType : JSDocType + +external interface JSDocUnknownType : JSDocType + +external interface JSDocNonNullableType : JSDocType { + val type: TypeNode +} + +external interface JSDocNullableType : JSDocType { + val type: TypeNode +} + +external interface JSDocOptionalType : JSDocType { + val type: TypeNode +} + +external interface JSDocFunctionType : JSDocType, SignatureDeclarationBase { + override val kind: SyntaxKind +} + +external interface JSDocVariadicType : JSDocType { + val type: TypeNode +} + +external interface JSDocNamepathType : JSDocType { + val type: TypeNode +} + +external interface JSDoc : Node { + override val parent: dynamic /* ParameterDeclaration | CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | EmptyStatement | DebuggerStatement | Block | VariableStatement | ExpressionStatement | IfStatement | DoStatement | WhileStatement | ForStatement | ForInStatement | ForOfStatement | BreakStatement | ContinueStatement | ReturnStatement | WithStatement | SwitchStatement | LabeledStatement | ThrowStatement | TryStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | VariableDeclaration | PropertyDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | NamespaceExportDeclaration | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | Token & JSDocContainer */ + get() = definedExternally + val tags: NodeArray? + get() = definedExternally + val comment: dynamic /* String? | NodeArray? */ + get() = definedExternally +} + +external interface JSDocTag : Node { + override val parent: dynamic /* JSDoc | JSDocTypeLiteral */ + get() = definedExternally + val tagName: Identifier + val comment: dynamic /* String? | NodeArray? */ + get() = definedExternally +} + +external interface JSDocLink : Node { + val name: dynamic /* Identifier? | QualifiedName? */ + get() = definedExternally + var text: String +} + +external interface JSDocText : Node { + var text: String +} + +external interface JSDocUnknownTag : JSDocTag + +external interface `T$4` { + val expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ + get() = definedExternally +} + +external interface JSDocAugmentsTag : JSDocTag { + val `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */ +} + +external interface JSDocImplementsTag : JSDocTag { + val `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */ +} + +external interface JSDocAuthorTag : JSDocTag + +external interface JSDocDeprecatedTag : JSDocTag + +external interface JSDocClassTag : JSDocTag + +external interface JSDocPublicTag : JSDocTag + +external interface JSDocPrivateTag : JSDocTag + +external interface JSDocProtectedTag : JSDocTag + +external interface JSDocReadonlyTag : JSDocTag + +external interface JSDocOverrideTag : JSDocTag + +external interface JSDocEnumTag : JSDocTag, Declaration { + override val parent: JSDoc + val typeExpression: JSDocTypeExpression +} + +external interface JSDocThisTag : JSDocTag { + val typeExpression: JSDocTypeExpression +} + +external interface JSDocTemplateTag : JSDocTag { + val constraint: JSDocTypeExpression? + val typeParameters: NodeArray +} + +external interface JSDocSeeTag : JSDocTag { + val name: JSDocNameReference? + get() = definedExternally +} + +external interface JSDocReturnTag : JSDocTag { + val typeExpression: JSDocTypeExpression? + get() = definedExternally +} + +external interface JSDocTypeTag : JSDocTag { + val typeExpression: JSDocTypeExpression +} + +external interface JSDocTypedefTag : JSDocTag, NamedDeclaration { + override val parent: JSDoc + val fullName: dynamic /* JSDocNamespaceDeclaration? | Identifier? */ + get() = definedExternally + override val name: Identifier? + get() = definedExternally + val typeExpression: dynamic /* JSDocTypeExpression? | JSDocTypeLiteral? */ + get() = definedExternally +} + +external interface JSDocCallbackTag : JSDocTag, NamedDeclaration { + override val parent: JSDoc + val fullName: dynamic /* JSDocNamespaceDeclaration? | Identifier? */ + get() = definedExternally + override val name: Identifier? + get() = definedExternally + val typeExpression: JSDocSignature +} + +external interface JSDocSignature : JSDocType, Declaration { + val typeParameters: Array? + get() = definedExternally + val parameters: Array + val type: JSDocReturnTag? +} + +external interface JSDocPropertyLikeTag : JSDocTag, Declaration { + override val parent: JSDoc + val name: dynamic /* Identifier | QualifiedName */ + get() = definedExternally + val typeExpression: JSDocTypeExpression? + get() = definedExternally + val isNameFirst: Boolean? + val isBracketed: Boolean? +} + +external interface JSDocPropertyTag : JSDocPropertyLikeTag + +external interface JSDocParameterTag : JSDocPropertyLikeTag + +external interface JSDocTypeLiteral : JSDocType { + val jsDocPropertyTags: Array? + get() = definedExternally + val isArrayType: Boolean? +} + +external enum class FlowFlags { + Unreachable /* = 1 */, + Start /* = 2 */, + BranchLabel /* = 4 */, + LoopLabel /* = 8 */, + Assignment /* = 16 */, + TrueCondition /* = 32 */, + FalseCondition /* = 64 */, + SwitchClause /* = 128 */, + ArrayMutation /* = 256 */, + Call /* = 512 */, + ReduceLabel /* = 1024 */, + Referenced /* = 2048 */, + Shared /* = 4096 */, + Label /* = 12 */, + Condition /* = 96 */ +} + +external interface FlowNodeBase { + var flags: FlowFlags + var id: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowStart : FlowNodeBase { + var node: dynamic /* FunctionExpression? | ArrowFunction? | MethodDeclaration? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowLabel : FlowNodeBase { + var antecedents: Array? +} + +external interface FlowAssignment : FlowNodeBase { + var node: dynamic /* Expression | VariableDeclaration | BindingElement */ + get() = definedExternally + set(value) = definedExternally + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowCall : FlowNodeBase { + var node: CallExpression + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowCondition : FlowNodeBase { + var node: Expression + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowSwitchClause : FlowNodeBase { + var switchStatement: SwitchStatement + var clauseStart: Number + var clauseEnd: Number + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowArrayMutation : FlowNodeBase { + var node: dynamic /* CallExpression | BinaryExpression */ + get() = definedExternally + set(value) = definedExternally + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowReduceLabel : FlowNodeBase { + var target: FlowLabel + var antecedents: Array + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface IncompleteType { + var flags: TypeFlags + var type: Type +} + +external interface AmdDependency { + var path: String + var name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface SourceFile : Declaration { + fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter + fun getLineEndOfPosition(pos: Number): Number + fun getLineStarts(): Array + fun getPositionOfLineAndCharacter(line: Number, character: Number): Number + fun update(newText: String, textChangeRange: TextChangeRange): SourceFile + val statements: NodeArray + val endOfFileToken: Token + var fileName: String + var text: String + var amdDependencies: Array + var moduleName: String? + get() = definedExternally + set(value) = definedExternally + var referencedFiles: Array + var typeReferenceDirectives: Array + var libReferenceDirectives: Array + var languageVariant: LanguageVariant + var isDeclarationFile: Boolean? + var hasNoDefaultLib: Boolean? + var languageVersion: ScriptTarget +} + +external interface Bundle : Node { + val prepends: Array + val sourceFiles: Array +} + +external interface InputFiles : Node { + var javascriptPath: String? + get() = definedExternally + set(value) = definedExternally + var javascriptText: String + var javascriptMapPath: String? + get() = definedExternally + set(value) = definedExternally + var javascriptMapText: String? + get() = definedExternally + set(value) = definedExternally + var declarationPath: String? + get() = definedExternally + set(value) = definedExternally + var declarationText: String + var declarationMapPath: String? + get() = definedExternally + set(value) = definedExternally + var declarationMapText: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface UnparsedSource : Node { + var fileName: String + var text: String + val prologues: Array + var helpers: Array? + var referencedFiles: Array + var typeReferenceDirectives: Array? + var libReferenceDirectives: Array + var hasNoDefaultLib: Boolean? + get() = definedExternally + set(value) = definedExternally + var sourceMapPath: String? + get() = definedExternally + set(value) = definedExternally + var sourceMapText: String? + get() = definedExternally + set(value) = definedExternally + val syntheticReferences: Array? + get() = definedExternally + val texts: Array +} + +external interface UnparsedSection : Node { + override val kind: SyntaxKind + override val parent: UnparsedSource + val data: String? + get() = definedExternally +} + +external interface UnparsedPrologue : UnparsedSection { + override val parent: UnparsedSource +} + +external interface UnparsedPrepend : UnparsedSection { + override val parent: UnparsedSource + val texts: Array +} + +external interface UnparsedTextLike : UnparsedSection { + override val kind: dynamic /* SyntaxKind.UnparsedText | SyntaxKind.UnparsedInternalText */ + get() = definedExternally + override val parent: UnparsedSource +} + +external interface UnparsedSyntheticReference : UnparsedSection { + override val parent: UnparsedSource +} + +external interface JsonSourceFile : SourceFile { + override val statements: NodeArray +} + +external interface TsConfigSourceFile : JsonSourceFile { + var extendedSourceFiles: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface JsonMinusNumericLiteral : PrefixUnaryExpression { + override val kind: SyntaxKind + override val operator: Any + override val operand: NumericLiteral +} + +external interface JsonObjectExpressionStatement : ExpressionStatement { + override val expression: dynamic /* ObjectLiteralExpression | ArrayLiteralExpression | JsonMinusNumericLiteral | NumericLiteral | StringLiteral | TrueLiteral | FalseLiteral | NullLiteral */ + get() = definedExternally +} + +external interface ScriptReferenceHost { + fun getCompilerOptions(): CompilerOptions + fun getSourceFile(fileName: String): SourceFile? + fun getSourceFileByPath(path: String /* String & `T$3` */): SourceFile? + fun getCurrentDirectory(): String +} + +external interface ParseConfigHost { + var useCaseSensitiveFileNames: Boolean? + fun readDirectory(rootDir: String, extensions: Array, excludes: Array?, includes: Array, depth: Number = definedExternally): Array + fun fileExists(path: String): Boolean + fun readFile(path: String): String? + val trace: ((s: String) -> Unit)? +} + +external interface `T$5` { + var _isResolvedConfigFileName: Any +} + +external open class OperationCanceledException + +external interface CancellationToken { + fun isCancellationRequested(): Boolean + fun throwIfCancellationRequested() +} + +external interface `T$6` { + var assignable: Number + var identity: Number + var subtype: Number + var strictSubtype: Number +} + +external interface Program : ScriptReferenceHost { + override fun getCurrentDirectory(): String + fun getRootFileNames(): Array + fun getSourceFiles(): Array + fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult + fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getDeclarationDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getConfigFileParsingDiagnostics(): Array + fun getTypeChecker(): TypeChecker + fun getNodeCount(): Number + fun getIdentifierCount(): Number + fun getSymbolCount(): Number + fun getTypeCount(): Number + fun getInstantiationCount(): Number + fun getRelationCacheSizes(): `T$6` + fun isSourceFileFromExternalLibrary(file: SourceFile): Boolean + fun isSourceFileDefaultLibrary(file: SourceFile): Boolean + fun getProjectReferences(): Array? + fun getResolvedProjectReferences(): Array? +} + +external interface ResolvedProjectReference { + var commandLine: ParsedCommandLine + var sourceFile: SourceFile + var references: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface CustomTransformer { + fun transformSourceFile(node: SourceFile): SourceFile + fun transformBundle(node: Bundle): Bundle +} + +external interface CustomTransformers { + var before: Array | CustomTransformerFactory */>? + get() = definedExternally + set(value) = definedExternally + var after: Array | CustomTransformerFactory */>? + get() = definedExternally + set(value) = definedExternally + var afterDeclarations: Array | CustomTransformerFactory */>? + get() = definedExternally + set(value) = definedExternally +} + +external interface SourceMapSpan { + var emittedLine: Number + var emittedColumn: Number + var sourceLine: Number + var sourceColumn: Number + var nameIndex: Number? + get() = definedExternally + set(value) = definedExternally + var sourceIndex: Number +} + +external enum class ExitStatus { + Success /* = 0 */, + DiagnosticsPresent_OutputsSkipped /* = 1 */, + DiagnosticsPresent_OutputsGenerated /* = 2 */, + InvalidProject_OutputsSkipped /* = 3 */, + ProjectReferenceCycle_OutputsSkipped /* = 4 */, + ProjectReferenceCycle_OutputsSkupped /* = 4 */ +} + +external interface EmitResult { + var emitSkipped: Boolean? + var diagnostics: Array + var emittedFiles: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$7` { + var typeArguments: NodeArray? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeChecker { + fun getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type + fun getDeclaredTypeOfSymbol(symbol: Symbol): Type + fun getPropertiesOfType(type: Type): Array + fun getPropertyOfType(type: Type, propertyName: String): Symbol? + fun getPrivateIdentifierPropertyOfType(leftType: Type, name: String, location: Node): Symbol? + fun getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo? + fun getSignaturesOfType(type: Type, kind: SignatureKind): Array + fun getIndexTypeOfType(type: Type, kind: IndexKind): Type? + fun getBaseTypes(type: InterfaceType): Array + fun getBaseTypeOfLiteralType(type: Type): Type + fun getWidenedType(type: Type): Type + fun getReturnTypeOfSignature(signature: Signature): Type + fun getNullableType(type: Type, flags: TypeFlags): Type + fun getNonNullableType(type: Type): Type + fun getTypeArguments(type: TypeReference): Array + fun typeToTypeNode(type: Type, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeNode? + fun signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ + fun indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): IndexSignatureDeclaration? + fun symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* Identifier? | QualifiedName? */ + fun symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): Expression? + fun symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): NodeArray? + fun symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): ParameterDeclaration? + fun typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeParameterDeclaration? + fun getSymbolsInScope(location: Node, meaning: SymbolFlags): Array + fun getSymbolAtLocation(node: Node): Symbol? + fun getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: String): Array + fun getShorthandAssignmentValueSymbol(location: Node?): Symbol? + fun getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol? + fun getExportSpecifierLocalTargetSymbol(location: Identifier): Symbol? + fun getExportSymbolOfSymbol(symbol: Symbol): Symbol + fun getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol? + fun getTypeOfAssignmentPattern(pattern: ObjectLiteralExpression): Type + fun getTypeOfAssignmentPattern(pattern: ArrayLiteralExpression): Type + fun getTypeAtLocation(node: Node): Type + fun getTypeFromTypeNode(node: TypeNode): Type + fun signatureToString(signature: Signature, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally, kind: SignatureKind = definedExternally): String + fun typeToString(type: Type, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun symbolToString(symbol: Symbol, enclosingDeclaration: Node = definedExternally, meaning: SymbolFlags = definedExternally, flags: SymbolFormatFlags = definedExternally): String + fun typePredicateToString(predicate: ThisTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun typePredicateToString(predicate: ThisTypePredicate): String + fun typePredicateToString(predicate: ThisTypePredicate, enclosingDeclaration: Node = definedExternally): String + fun typePredicateToString(predicate: IdentifierTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun typePredicateToString(predicate: IdentifierTypePredicate): String + fun typePredicateToString(predicate: IdentifierTypePredicate, enclosingDeclaration: Node = definedExternally): String + fun typePredicateToString(predicate: AssertsThisTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun typePredicateToString(predicate: AssertsThisTypePredicate): String + fun typePredicateToString(predicate: AssertsThisTypePredicate, enclosingDeclaration: Node = definedExternally): String + fun typePredicateToString(predicate: AssertsIdentifierTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun typePredicateToString(predicate: AssertsIdentifierTypePredicate): String + fun typePredicateToString(predicate: AssertsIdentifierTypePredicate, enclosingDeclaration: Node = definedExternally): String + fun getFullyQualifiedName(symbol: Symbol): String + fun getAugmentedPropertiesOfType(type: Type): Array + fun getRootSymbols(symbol: Symbol): Array + fun getSymbolOfExpando(node: Node, allowDeclaration: Boolean): Symbol? + fun getContextualType(node: Expression): Type? + fun getResolvedSignature(node: CallExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: CallExpression): Signature? + fun getResolvedSignature(node: CallExpression, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: NewExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: NewExpression): Signature? + fun getResolvedSignature(node: NewExpression, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: TaggedTemplateExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: TaggedTemplateExpression): Signature? + fun getResolvedSignature(node: TaggedTemplateExpression, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: Decorator, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: Decorator): Signature? + fun getResolvedSignature(node: Decorator, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: JsxSelfClosingElement, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: JsxSelfClosingElement): Signature? + fun getResolvedSignature(node: JsxSelfClosingElement, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: JsxOpeningElement, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: JsxOpeningElement): Signature? + fun getResolvedSignature(node: JsxOpeningElement, candidatesOutArray: Array = definedExternally): Signature? + fun getSignatureFromDeclaration(declaration: CallSignatureDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: ConstructSignatureDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: MethodSignature): Signature? + fun getSignatureFromDeclaration(declaration: IndexSignatureDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: FunctionTypeNode): Signature? + fun getSignatureFromDeclaration(declaration: ConstructorTypeNode): Signature? + fun getSignatureFromDeclaration(declaration: JSDocFunctionType): Signature? + fun getSignatureFromDeclaration(declaration: FunctionDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: MethodDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: ConstructorDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: GetAccessorDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: SetAccessorDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: FunctionExpression): Signature? + fun getSignatureFromDeclaration(declaration: ArrowFunction): Signature? + fun isImplementationOfOverload(node: CallSignatureDeclaration): Boolean? + fun isImplementationOfOverload(node: ConstructSignatureDeclaration): Boolean? + fun isImplementationOfOverload(node: MethodSignature): Boolean? + fun isImplementationOfOverload(node: IndexSignatureDeclaration): Boolean? + fun isImplementationOfOverload(node: FunctionTypeNode): Boolean? + fun isImplementationOfOverload(node: ConstructorTypeNode): Boolean? + fun isImplementationOfOverload(node: JSDocFunctionType): Boolean? + fun isImplementationOfOverload(node: FunctionDeclaration): Boolean? + fun isImplementationOfOverload(node: MethodDeclaration): Boolean? + fun isImplementationOfOverload(node: ConstructorDeclaration): Boolean? + fun isImplementationOfOverload(node: GetAccessorDeclaration): Boolean? + fun isImplementationOfOverload(node: SetAccessorDeclaration): Boolean? + fun isImplementationOfOverload(node: FunctionExpression): Boolean? + fun isImplementationOfOverload(node: ArrowFunction): Boolean? + fun isUndefinedSymbol(symbol: Symbol): Boolean + fun isArgumentsSymbol(symbol: Symbol): Boolean + fun isUnknownSymbol(symbol: Symbol): Boolean + fun getConstantValue(node: EnumMember): dynamic /* String? | Number? */ + fun getConstantValue(node: PropertyAccessExpression): dynamic /* String? | Number? */ + fun getConstantValue(node: ElementAccessExpression): dynamic /* String? | Number? */ + fun isValidPropertyAccess(node: PropertyAccessExpression, propertyName: String): Boolean + fun isValidPropertyAccess(node: QualifiedName, propertyName: String): Boolean + fun isValidPropertyAccess(node: ImportTypeNode, propertyName: String): Boolean + fun getAliasedSymbol(symbol: Symbol): Symbol + fun getExportsOfModule(moduleSymbol: Symbol): Array + fun getJsxIntrinsicTagNamesAt(location: Node): Array + fun isOptionalParameter(node: ParameterDeclaration): Boolean + fun getAmbientModules(): Array + fun tryGetMemberInModuleExports(memberName: String, moduleSymbol: Symbol): Symbol? + fun getApparentType(type: Type): Type + fun getBaseConstraintOfType(type: Type): Type? + fun getDefaultFromTypeParameter(type: Type): Type? + fun runWithCancellationToken(token: CancellationToken, cb: (checker: TypeChecker) -> T): T +} + +external enum class NodeBuilderFlags { + None /* = 0 */, + NoTruncation /* = 1 */, + WriteArrayAsGenericType /* = 2 */, + GenerateNamesForShadowedTypeParams /* = 4 */, + UseStructuralFallback /* = 8 */, + ForbidIndexedAccessSymbolReferences /* = 16 */, + WriteTypeArgumentsOfSignature /* = 32 */, + UseFullyQualifiedType /* = 64 */, + UseOnlyExternalAliasing /* = 128 */, + SuppressAnyReturnType /* = 256 */, + WriteTypeParametersInQualifiedName /* = 512 */, + MultilineObjectLiterals /* = 1024 */, + WriteClassExpressionAsTypeLiteral /* = 2048 */, + UseTypeOfFunction /* = 4096 */, + OmitParameterModifiers /* = 8192 */, + UseAliasDefinedOutsideCurrentScope /* = 16384 */, + UseSingleQuotesForStringLiteralType /* = 268435456 */, + NoTypeReduction /* = 536870912 */, + NoUndefinedOptionalParameterType /* = 1073741824 */, + AllowThisInObjectLiteral /* = 32768 */, + AllowQualifiedNameInPlaceOfIdentifier /* = 65536 */, + AllowQualifedNameInPlaceOfIdentifier /* = 65536 */, + AllowAnonymousIdentifier /* = 131072 */, + AllowEmptyUnionOrIntersection /* = 262144 */, + AllowEmptyTuple /* = 524288 */, + AllowUniqueESSymbolType /* = 1048576 */, + AllowEmptyIndexInfoType /* = 2097152 */, + AllowNodeModulesRelativePaths /* = 67108864 */, + IgnoreErrors /* = 70221824 */, + InObjectTypeLiteral /* = 4194304 */, + InTypeAlias /* = 8388608 */, + InInitialEntityName /* = 16777216 */ +} + +external enum class TypeFormatFlags { + None /* = 0 */, + NoTruncation /* = 1 */, + WriteArrayAsGenericType /* = 2 */, + UseStructuralFallback /* = 8 */, + WriteTypeArgumentsOfSignature /* = 32 */, + UseFullyQualifiedType /* = 64 */, + SuppressAnyReturnType /* = 256 */, + MultilineObjectLiterals /* = 1024 */, + WriteClassExpressionAsTypeLiteral /* = 2048 */, + UseTypeOfFunction /* = 4096 */, + OmitParameterModifiers /* = 8192 */, + UseAliasDefinedOutsideCurrentScope /* = 16384 */, + UseSingleQuotesForStringLiteralType /* = 268435456 */, + NoTypeReduction /* = 536870912 */, + AllowUniqueESSymbolType /* = 1048576 */, + AddUndefined /* = 131072 */, + WriteArrowStyleSignature /* = 262144 */, + InArrayType /* = 524288 */, + InElementType /* = 2097152 */, + InFirstTypeArgument /* = 4194304 */, + InTypeAlias /* = 8388608 */, + WriteOwnNameForAnyLike /* = 0 */, + NodeBuilderFlagsMask /* = 814775659 */ +} + +external enum class SymbolFormatFlags { + None /* = 0 */, + WriteTypeParametersOrArguments /* = 1 */, + UseOnlyExternalAliasing /* = 2 */, + AllowAnyNodeKind /* = 4 */, + UseAliasDefinedOutsideCurrentScope /* = 8 */ +} + +external enum class TypePredicateKind { + This /* = 0 */, + Identifier /* = 1 */, + AssertsThis /* = 2 */, + AssertsIdentifier /* = 3 */ +} + +external interface TypePredicateBase { + var kind: TypePredicateKind + var type: Type? +} + +external interface ThisTypePredicate : TypePredicateBase { + var parameterName: Any? + var parameterIndex: Any? +} + +external interface IdentifierTypePredicate : TypePredicateBase { + var parameterName: String + var parameterIndex: Number +} + +external interface AssertsThisTypePredicate : TypePredicateBase { + var parameterName: Any? + var parameterIndex: Any? + override var type: Type? +} + +external interface AssertsIdentifierTypePredicate : TypePredicateBase { + var parameterName: String + var parameterIndex: Number + override var type: Type? +} + +external enum class SymbolFlags { + None /* = 0 */, + FunctionScopedVariable /* = 1 */, + BlockScopedVariable /* = 2 */, + Property /* = 4 */, + EnumMember /* = 8 */, + Function /* = 16 */, + Class /* = 32 */, + Interface /* = 64 */, + ConstEnum /* = 128 */, + RegularEnum /* = 256 */, + ValueModule /* = 512 */, + NamespaceModule /* = 1024 */, + TypeLiteral /* = 2048 */, + ObjectLiteral /* = 4096 */, + Method /* = 8192 */, + Constructor /* = 16384 */, + GetAccessor /* = 32768 */, + SetAccessor /* = 65536 */, + Signature /* = 131072 */, + TypeParameter /* = 262144 */, + TypeAlias /* = 524288 */, + ExportValue /* = 1048576 */, + Alias /* = 2097152 */, + Prototype /* = 4194304 */, + ExportStar /* = 8388608 */, + Optional /* = 16777216 */, + Transient /* = 33554432 */, + Assignment /* = 67108864 */, + ModuleExports /* = 134217728 */, + Enum /* = 384 */, + Variable /* = 3 */, + Value /* = 111551 */, + Type /* = 788968 */, + Namespace /* = 1920 */, + Module /* = 1536 */, + Accessor /* = 98304 */, + FunctionScopedVariableExcludes /* = 111550 */, + BlockScopedVariableExcludes /* = 111551 */, + ParameterExcludes /* = 111551 */, + PropertyExcludes /* = 0 */, + EnumMemberExcludes /* = 900095 */, + FunctionExcludes /* = 110991 */, + ClassExcludes /* = 899503 */, + InterfaceExcludes /* = 788872 */, + RegularEnumExcludes /* = 899327 */, + ConstEnumExcludes /* = 899967 */, + ValueModuleExcludes /* = 110735 */, + NamespaceModuleExcludes /* = 0 */, + MethodExcludes /* = 103359 */, + GetAccessorExcludes /* = 46015 */, + SetAccessorExcludes /* = 78783 */, + TypeParameterExcludes /* = 526824 */, + TypeAliasExcludes /* = 788968 */, + AliasExcludes /* = 2097152 */, + ModuleMember /* = 2623475 */, + ExportHasLocal /* = 944 */, + BlockScoped /* = 418 */, + PropertyOrAccessor /* = 98308 */, + ClassMember /* = 106500 */ +} + +external interface Symbol { + val name: String + fun getFlags(): SymbolFlags + fun getEscapedName(): dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + fun getName(): String + fun getDeclarations(): Array? + fun getDocumentationComment(typeChecker: TypeChecker?): Array + fun getJsDocTags(checker: TypeChecker = definedExternally): Array + var flags: SymbolFlags + var escapedName: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + get() = definedExternally + set(value) = definedExternally + var declarations: Array? + get() = definedExternally + set(value) = definedExternally + var valueDeclaration: Declaration? + get() = definedExternally + set(value) = definedExternally + var members: SymbolTable? + get() = definedExternally + set(value) = definedExternally + var exports: SymbolTable? + get() = definedExternally + set(value) = definedExternally + var globalExports: SymbolTable? + get() = definedExternally + set(value) = definedExternally +} + +external enum class InternalSymbolName { + Call /* = "__call" */, + Constructor /* = "__constructor" */, + New /* = "__new" */, + Index /* = "__index" */, + ExportStar /* = "__export" */, + Global /* = "__global" */, + Missing /* = "__missing" */, + Type /* = "__type" */, + Object /* = "__object" */, + JSXAttributes /* = "__jsxAttributes" */, + Class /* = "__class" */, + Function /* = "__function" */, + Computed /* = "__computed" */, + Resolving /* = "__resolving__" */, + ExportEquals /* = "export=" */, + Default /* = "default" */, + This /* = "this" */ +} + +external interface `T$8` { + var __escapedIdentifier: Unit +} + +external interface ReadonlyUnderscoreEscapedMap : ReadonlyESMap + +external interface UnderscoreEscapedMap : ESMap, ReadonlyUnderscoreEscapedMap + +external enum class TypeFlags { + Any /* = 1 */, + Unknown /* = 2 */, + String /* = 4 */, + Number /* = 8 */, + Boolean /* = 16 */, + Enum /* = 32 */, + BigInt /* = 64 */, + StringLiteral /* = 128 */, + NumberLiteral /* = 256 */, + BooleanLiteral /* = 512 */, + EnumLiteral /* = 1024 */, + BigIntLiteral /* = 2048 */, + ESSymbol /* = 4096 */, + UniqueESSymbol /* = 8192 */, + Void /* = 16384 */, + Undefined /* = 32768 */, + Null /* = 65536 */, + Never /* = 131072 */, + TypeParameter /* = 262144 */, + Object /* = 524288 */, + Union /* = 1048576 */, + Intersection /* = 2097152 */, + Index /* = 4194304 */, + IndexedAccess /* = 8388608 */, + Conditional /* = 16777216 */, + Substitution /* = 33554432 */, + NonPrimitive /* = 67108864 */, + TemplateLiteral /* = 134217728 */, + StringMapping /* = 268435456 */, + Literal /* = 2944 */, + Unit /* = 109440 */, + StringOrNumberLiteral /* = 384 */, + PossiblyFalsy /* = 117724 */, + StringLike /* = 402653316 */, + NumberLike /* = 296 */, + BigIntLike /* = 2112 */, + BooleanLike /* = 528 */, + EnumLike /* = 1056 */, + ESSymbolLike /* = 12288 */, + VoidLike /* = 49152 */, + UnionOrIntersection /* = 3145728 */, + StructuredType /* = 3670016 */, + TypeVariable /* = 8650752 */, + InstantiableNonPrimitive /* = 58982400 */, + InstantiablePrimitive /* = 406847488 */, + Instantiable /* = 465829888 */, + StructuredOrInstantiable /* = 469499904 */, + Narrowable /* = 536624127 */ +} + +external interface Type { + fun getFlags(): TypeFlags + fun getSymbol(): Symbol? + fun getProperties(): Array + fun getProperty(propertyName: String): Symbol? + fun getApparentProperties(): Array + fun getCallSignatures(): Array + fun getConstructSignatures(): Array + fun getStringIndexType(): Type? + fun getNumberIndexType(): Type? + fun getBaseTypes(): Array? + fun getNonNullableType(): Type + fun getConstraint(): Type? + fun getDefault(): Type? + fun isUnion(): Boolean + fun isIntersection(): Boolean + fun isUnionOrIntersection(): Boolean + fun isLiteral(): Boolean + fun isStringLiteral(): Boolean + fun isNumberLiteral(): Boolean + fun isTypeParameter(): Boolean + fun isClassOrInterface(): Boolean + fun isClass(): Boolean + var flags: TypeFlags + var symbol: Symbol + var pattern: dynamic /* ObjectBindingPattern? | ArrayBindingPattern? | ObjectLiteralExpression? | ArrayLiteralExpression? */ + get() = definedExternally + set(value) = definedExternally + var aliasSymbol: Symbol? + get() = definedExternally + set(value) = definedExternally + var aliasTypeArguments: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface LiteralType : Type { + var value: dynamic /* String | Number | PseudoBigInt */ + get() = definedExternally + set(value) = definedExternally + var freshType: LiteralType + var regularType: LiteralType +} + +external interface UniqueESSymbolType : Type { + override var symbol: Symbol + var escapedName: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + get() = definedExternally + set(value) = definedExternally +} + +external interface StringLiteralType : LiteralType { + override var value: String +} + +external interface NumberLiteralType : LiteralType { + override var value: Number +} + +external interface BigIntLiteralType : LiteralType { + override var value: PseudoBigInt +} + +external interface EnumType : Type + +external enum class ObjectFlags { + Class /* = 1 */, + Interface /* = 2 */, + Reference /* = 4 */, + Tuple /* = 8 */, + Anonymous /* = 16 */, + Mapped /* = 32 */, + Instantiated /* = 64 */, + ObjectLiteral /* = 128 */, + EvolvingArray /* = 256 */, + ObjectLiteralPatternWithComputedProperties /* = 512 */, + ReverseMapped /* = 1024 */, + JsxAttributes /* = 2048 */, + MarkerType /* = 4096 */, + JSLiteral /* = 8192 */, + FreshLiteral /* = 16384 */, + ArrayLiteral /* = 32768 */, + ClassOrInterface /* = 3 */, + ContainsSpread /* = 4194304 */, + ObjectRestType /* = 8388608 */ +} + +external interface ObjectType : Type { + var objectFlags: ObjectFlags +} + +external interface InterfaceType : ObjectType { + var typeParameters: Array? + var outerTypeParameters: Array? + var localTypeParameters: Array? + var thisType: TypeParameter? +} + +external interface InterfaceTypeWithDeclaredMembers : InterfaceType { + var declaredProperties: Array + var declaredCallSignatures: Array + var declaredConstructSignatures: Array + var declaredStringIndexInfo: IndexInfo? + get() = definedExternally + set(value) = definedExternally + var declaredNumberIndexInfo: IndexInfo? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeReference : ObjectType { + var typeArguments: Array? + get() = definedExternally + set(value) = definedExternally + var target: GenericType + var node: dynamic /* TypeReferenceNode? | ArrayTypeNode? | TupleTypeNode? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface DeferredTypeReference : TypeReference + +external interface GenericType : InterfaceType, TypeReference + +external enum class ElementFlags { + Required /* = 1 */, + Optional /* = 2 */, + Rest /* = 4 */, + Variadic /* = 8 */, + Fixed /* = 3 */, + Variable /* = 12 */, + NonRequired /* = 14 */, + NonRest /* = 11 */ +} + +external interface TupleType : GenericType { + var elementFlags: Array + var minLength: Number + var fixedLength: Number + var hasRestElement: Boolean? + var combinedFlags: ElementFlags + var readonly: Boolean? + var labeledElementDeclarations: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface TupleTypeReference : TypeReference { + override var target: GenericType +} + +external interface UnionOrIntersectionType : Type { + var types: Array +} + +external interface UnionType : UnionOrIntersectionType + +external interface IntersectionType : UnionOrIntersectionType + +external interface EvolvingArrayType : ObjectType { + var elementType: Type + var finalArrayType: Type? + get() = definedExternally + set(value) = definedExternally +} + +external interface InstantiableType : Type + +external interface TypeParameter : InstantiableType + +external interface IndexedAccessType : InstantiableType { + var objectType: Type + var indexType: Type + var constraint: Type? + get() = definedExternally + set(value) = definedExternally + var simplifiedForReading: Type? + get() = definedExternally + set(value) = definedExternally + var simplifiedForWriting: Type? + get() = definedExternally + set(value) = definedExternally +} + +external interface IndexType : InstantiableType { + var type: dynamic /* InstantiableType | UnionOrIntersectionType */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ConditionalRoot { + var node: ConditionalTypeNode + var checkType: Type + var extendsType: Type + var isDistributive: Boolean? + var inferTypeParameters: Array? + get() = definedExternally + set(value) = definedExternally + var outerTypeParameters: Array? + get() = definedExternally + set(value) = definedExternally + var instantiations: Map? + get() = definedExternally + set(value) = definedExternally + var aliasSymbol: Symbol? + get() = definedExternally + set(value) = definedExternally + var aliasTypeArguments: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface ConditionalType : InstantiableType { + var root: ConditionalRoot + var checkType: Type + var extendsType: Type + var resolvedTrueType: Type + var resolvedFalseType: Type +} + +external interface TemplateLiteralType : InstantiableType { + var texts: Array + var types: Array +} + +external interface StringMappingType : InstantiableType { + override var symbol: Symbol + var type: Type +} + +external interface SubstitutionType : InstantiableType { + var objectFlags: ObjectFlags + var baseType: Type + var substitute: Type +} + +external enum class SignatureKind { + Call /* = 0 */, + Construct /* = 1 */ +} + +external interface Signature { + fun getDeclaration(): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ + fun getTypeParameters(): Array? + fun getParameters(): Array + fun getReturnType(): Type + fun getDocumentationComment(typeChecker: TypeChecker?): Array + fun getJsDocTags(): Array + var declaration: dynamic /* CallSignatureDeclaration? | ConstructSignatureDeclaration? | MethodSignature? | IndexSignatureDeclaration? | FunctionTypeNode? | ConstructorTypeNode? | JSDocFunctionType? | FunctionDeclaration? | MethodDeclaration? | ConstructorDeclaration? | GetAccessorDeclaration? | SetAccessorDeclaration? | FunctionExpression? | ArrowFunction? | JSDocSignature? */ + get() = definedExternally + set(value) = definedExternally + var typeParameters: Array? + get() = definedExternally + set(value) = definedExternally + var parameters: Array +} + +external enum class IndexKind { + String /* = 0 */, + Number /* = 1 */ +} + +external interface IndexInfo { + var type: Type + var isReadonly: Boolean? + var declaration: IndexSignatureDeclaration? + get() = definedExternally + set(value) = definedExternally +} + +external enum class InferencePriority { + NakedTypeVariable /* = 1 */, + SpeculativeTuple /* = 2 */, + SubstituteSource /* = 4 */, + HomomorphicMappedType /* = 8 */, + PartialHomomorphicMappedType /* = 16 */, + MappedTypeConstraint /* = 32 */, + ContravariantConditional /* = 64 */, + ReturnType /* = 128 */, + LiteralKeyof /* = 256 */, + NoConstraints /* = 512 */, + AlwaysStrict /* = 1024 */, + MaxValue /* = 2048 */, + PriorityImpliesCombination /* = 416 */, + Circularity /* = -1 */ +} + +external interface FileExtensionInfo { + var extension: String + var isMixedContent: Boolean? + var scriptKind: ScriptKind? + get() = definedExternally + set(value) = definedExternally +} + +external interface DiagnosticMessage { + var key: String + var category: DiagnosticCategory + var code: Number + var message: String + var reportsUnnecessary: Any? + get() = definedExternally + set(value) = definedExternally + var reportsDeprecated: Any? + get() = definedExternally + set(value) = definedExternally +} + +external interface DiagnosticMessageChain { + var messageText: String + var category: DiagnosticCategory + var code: Number + var next: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface Diagnostic : DiagnosticRelatedInformation { + var reportsUnnecessary: Any? + get() = definedExternally + set(value) = definedExternally + var reportsDeprecated: Any? + get() = definedExternally + set(value) = definedExternally + var source: String? + get() = definedExternally + set(value) = definedExternally + var relatedInformation: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface DiagnosticRelatedInformation { + var category: DiagnosticCategory + var code: Number + var file: SourceFile? + var start: Number? + var length: Number? + var messageText: dynamic /* String | DiagnosticMessageChain */ + get() = definedExternally + set(value) = definedExternally +} + +external interface DiagnosticWithLocation : Diagnostic + +external enum class DiagnosticCategory { + Warning /* = 0 */, + Error /* = 1 */, + Suggestion /* = 2 */, + Message /* = 3 */ +} + +external enum class ModuleResolutionKind { + Classic /* = 1 */, + NodeJs /* = 2 */ +} + +external interface PluginImport { + var name: String +} + +external interface ProjectReference { + var path: String + var originalPath: String? + get() = definedExternally + set(value) = definedExternally + var prepend: Boolean? + get() = definedExternally + set(value) = definedExternally + var circular: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external enum class WatchFileKind { + FixedPollingInterval /* = 0 */, + PriorityPollingInterval /* = 1 */, + DynamicPriorityPolling /* = 2 */, + FixedChunkSizePolling /* = 3 */, + UseFsEvents /* = 4 */, + UseFsEventsOnParentDirectory /* = 5 */ +} + +external enum class WatchDirectoryKind { + UseFsEvents /* = 0 */, + FixedPollingInterval /* = 1 */, + DynamicPriorityPolling /* = 2 */, + FixedChunkSizePolling /* = 3 */ +} + +external enum class PollingWatchKind { + FixedInterval /* = 0 */, + PriorityInterval /* = 1 */, + DynamicPriority /* = 2 */, + FixedChunkSize /* = 3 */ +} + +external interface CompilerOptions { + var allowJs: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowSyntheticDefaultImports: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowUmdGlobalAccess: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowUnreachableCode: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowUnusedLabels: Boolean? + get() = definedExternally + set(value) = definedExternally + var alwaysStrict: Boolean? + get() = definedExternally + set(value) = definedExternally + var baseUrl: String? + get() = definedExternally + set(value) = definedExternally + var charset: String? + get() = definedExternally + set(value) = definedExternally + var checkJs: Boolean? + get() = definedExternally + set(value) = definedExternally + var declaration: Boolean? + get() = definedExternally + set(value) = definedExternally + var declarationMap: Boolean? + get() = definedExternally + set(value) = definedExternally + var emitDeclarationOnly: Boolean? + get() = definedExternally + set(value) = definedExternally + var declarationDir: String? + get() = definedExternally + set(value) = definedExternally + var disableSizeLimit: Boolean? + get() = definedExternally + set(value) = definedExternally + var disableSourceOfProjectReferenceRedirect: Boolean? + get() = definedExternally + set(value) = definedExternally + var disableSolutionSearching: Boolean? + get() = definedExternally + set(value) = definedExternally + var disableReferencedProjectLoad: Boolean? + get() = definedExternally + set(value) = definedExternally + var downlevelIteration: Boolean? + get() = definedExternally + set(value) = definedExternally + var emitBOM: Boolean? + get() = definedExternally + set(value) = definedExternally + var emitDecoratorMetadata: Boolean? + get() = definedExternally + set(value) = definedExternally + var experimentalDecorators: Boolean? + get() = definedExternally + set(value) = definedExternally + var forceConsistentCasingInFileNames: Boolean? + get() = definedExternally + set(value) = definedExternally + var importHelpers: Boolean? + get() = definedExternally + set(value) = definedExternally + var importsNotUsedAsValues: ImportsNotUsedAsValues? + get() = definedExternally + set(value) = definedExternally + var inlineSourceMap: Boolean? + get() = definedExternally + set(value) = definedExternally + var inlineSources: Boolean? + get() = definedExternally + set(value) = definedExternally + var isolatedModules: Boolean? + get() = definedExternally + set(value) = definedExternally + var jsx: JsxEmit? + get() = definedExternally + set(value) = definedExternally + var keyofStringsOnly: Boolean? + get() = definedExternally + set(value) = definedExternally + var lib: Array? + get() = definedExternally + set(value) = definedExternally + var locale: String? + get() = definedExternally + set(value) = definedExternally + var mapRoot: String? + get() = definedExternally + set(value) = definedExternally + var maxNodeModuleJsDepth: Number? + get() = definedExternally + set(value) = definedExternally + var module: ModuleKind? + get() = definedExternally + set(value) = definedExternally + var moduleResolution: ModuleResolutionKind? + get() = definedExternally + set(value) = definedExternally + var newLine: NewLineKind? + get() = definedExternally + set(value) = definedExternally + var noEmit: Boolean? + get() = definedExternally + set(value) = definedExternally + var noEmitHelpers: Boolean? + get() = definedExternally + set(value) = definedExternally + var noEmitOnError: Boolean? + get() = definedExternally + set(value) = definedExternally + var noErrorTruncation: Boolean? + get() = definedExternally + set(value) = definedExternally + var noFallthroughCasesInSwitch: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitAny: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitReturns: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitThis: Boolean? + get() = definedExternally + set(value) = definedExternally + var noStrictGenericChecks: Boolean? + get() = definedExternally + set(value) = definedExternally + var noUnusedLocals: Boolean? + get() = definedExternally + set(value) = definedExternally + var noUnusedParameters: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitUseStrict: Boolean? + get() = definedExternally + set(value) = definedExternally + var noPropertyAccessFromIndexSignature: Boolean? + get() = definedExternally + set(value) = definedExternally + var assumeChangesOnlyAffectDirectDependencies: Boolean? + get() = definedExternally + set(value) = definedExternally + var noLib: Boolean? + get() = definedExternally + set(value) = definedExternally + var noResolve: Boolean? + get() = definedExternally + set(value) = definedExternally + var noUncheckedIndexedAccess: Boolean? + get() = definedExternally + set(value) = definedExternally + var out: String? + get() = definedExternally + set(value) = definedExternally + var outDir: String? + get() = definedExternally + set(value) = definedExternally + var outFile: String? + get() = definedExternally + set(value) = definedExternally + var paths: MapLike>? + get() = definedExternally + set(value) = definedExternally + var preserveConstEnums: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitOverride: Boolean? + get() = definedExternally + set(value) = definedExternally + var preserveSymlinks: Boolean? + get() = definedExternally + set(value) = definedExternally + var project: String? + get() = definedExternally + set(value) = definedExternally + var reactNamespace: String? + get() = definedExternally + set(value) = definedExternally + var jsxFactory: String? + get() = definedExternally + set(value) = definedExternally + var jsxFragmentFactory: String? + get() = definedExternally + set(value) = definedExternally + var jsxImportSource: String? + get() = definedExternally + set(value) = definedExternally + var composite: Boolean? + get() = definedExternally + set(value) = definedExternally + var incremental: Boolean? + get() = definedExternally + set(value) = definedExternally + var tsBuildInfoFile: String? + get() = definedExternally + set(value) = definedExternally + var removeComments: Boolean? + get() = definedExternally + set(value) = definedExternally + var rootDir: String? + get() = definedExternally + set(value) = definedExternally + var rootDirs: Array? + get() = definedExternally + set(value) = definedExternally + var skipLibCheck: Boolean? + get() = definedExternally + set(value) = definedExternally + var skipDefaultLibCheck: Boolean? + get() = definedExternally + set(value) = definedExternally + var sourceMap: Boolean? + get() = definedExternally + set(value) = definedExternally + var sourceRoot: String? + get() = definedExternally + set(value) = definedExternally + var strict: Boolean? + get() = definedExternally + set(value) = definedExternally + var strictFunctionTypes: Boolean? + get() = definedExternally + set(value) = definedExternally + var strictBindCallApply: Boolean? + get() = definedExternally + set(value) = definedExternally + var strictNullChecks: Boolean? + get() = definedExternally + set(value) = definedExternally + var strictPropertyInitialization: Boolean? + get() = definedExternally + set(value) = definedExternally + var stripInternal: Boolean? + get() = definedExternally + set(value) = definedExternally + var suppressExcessPropertyErrors: Boolean? + get() = definedExternally + set(value) = definedExternally + var suppressImplicitAnyIndexErrors: Boolean? + get() = definedExternally + set(value) = definedExternally + var target: ScriptTarget? + get() = definedExternally + set(value) = definedExternally + var traceResolution: Boolean? + get() = definedExternally + set(value) = definedExternally + var resolveJsonModule: Boolean? + get() = definedExternally + set(value) = definedExternally + var types: Array? + get() = definedExternally + set(value) = definedExternally + var typeRoots: Array? + get() = definedExternally + set(value) = definedExternally + var esModuleInterop: Boolean? + get() = definedExternally + set(value) = definedExternally + var useDefineForClassFields: Boolean? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? | TsConfigSourceFile? */ + @nativeSetter + operator fun set(option: String, value: String?) + @nativeSetter + operator fun set(option: String, value: Number?) + @nativeSetter + operator fun set(option: String, value: Boolean?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: MapLike>?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: TsConfigSourceFile?) +} + +external interface WatchOptions { + var watchFile: WatchFileKind? + get() = definedExternally + set(value) = definedExternally + var watchDirectory: WatchDirectoryKind? + get() = definedExternally + set(value) = definedExternally + var fallbackPolling: PollingWatchKind? + get() = definedExternally + set(value) = definedExternally + var synchronousWatchDirectory: Boolean? + get() = definedExternally + set(value) = definedExternally + var excludeDirectories: Array? + get() = definedExternally + set(value) = definedExternally + var excludeFiles: Array? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ + @nativeSetter + operator fun set(option: String, value: String?) + @nativeSetter + operator fun set(option: String, value: Number?) + @nativeSetter + operator fun set(option: String, value: Boolean?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: MapLike>?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) +} + +external interface TypeAcquisition { + var enableAutoDiscovery: Boolean? + get() = definedExternally + set(value) = definedExternally + var enable: Boolean? + get() = definedExternally + set(value) = definedExternally + var include: Array? + get() = definedExternally + set(value) = definedExternally + var exclude: Array? + get() = definedExternally + set(value) = definedExternally + var disableFilenameBasedTypeAcquisition: Boolean? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ + @nativeSetter + operator fun set(option: String, value: String?) + @nativeSetter + operator fun set(option: String, value: Number?) + @nativeSetter + operator fun set(option: String, value: Boolean?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: MapLike>?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) +} + +external enum class ModuleKind { + None /* = 0 */, + CommonJS /* = 1 */, + AMD /* = 2 */, + UMD /* = 3 */, + System /* = 4 */, + ES2015 /* = 5 */, + ES2020 /* = 6 */, + ESNext /* = 99 */ +} + +external enum class JsxEmit { + None /* = 0 */, + Preserve /* = 1 */, + React /* = 2 */, + ReactNative /* = 3 */, + ReactJSX /* = 4 */, + ReactJSXDev /* = 5 */ +} + +external enum class ImportsNotUsedAsValues { + Remove /* = 0 */, + Preserve /* = 1 */, + Error /* = 2 */ +} + +external enum class NewLineKind { + CarriageReturnLineFeed /* = 0 */, + LineFeed /* = 1 */ +} + +external interface LineAndCharacter { + var line: Number + var character: Number +} + +external enum class ScriptKind { + Unknown /* = 0 */, + JS /* = 1 */, + JSX /* = 2 */, + TS /* = 3 */, + TSX /* = 4 */, + External /* = 5 */, + JSON /* = 6 */, + Deferred /* = 7 */ +} + +external enum class ScriptTarget { + ES3 /* = 0 */, + ES5 /* = 1 */, + ES2015 /* = 2 */, + ES2016 /* = 3 */, + ES2017 /* = 4 */, + ES2018 /* = 5 */, + ES2019 /* = 6 */, + ES2020 /* = 7 */, + ES2021 /* = 8 */, + ESNext /* = 99 */, + JSON /* = 100 */, + Latest /* = 99 */ +} + +external enum class LanguageVariant { + Standard /* = 0 */, + JSX /* = 1 */ +} + +external interface ParsedCommandLine { + var options: CompilerOptions + var typeAcquisition: TypeAcquisition? + get() = definedExternally + set(value) = definedExternally + var fileNames: Array + var projectReferences: Array? + get() = definedExternally + set(value) = definedExternally + var watchOptions: WatchOptions? + get() = definedExternally + set(value) = definedExternally + var raw: Any? + get() = definedExternally + set(value) = definedExternally + var errors: Array + var wildcardDirectories: MapLike? + get() = definedExternally + set(value) = definedExternally + var compileOnSave: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external enum class WatchDirectoryFlags { + None /* = 0 */, + Recursive /* = 1 */ +} + +external interface CreateProgramOptions { + var rootNames: Array + var options: CompilerOptions + var projectReferences: Array? + get() = definedExternally + set(value) = definedExternally + var host: CompilerHost? + get() = definedExternally + set(value) = definedExternally + var oldProgram: Program? + get() = definedExternally + set(value) = definedExternally + var configFileParsingDiagnostics: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface ModuleResolutionHost { + fun fileExists(fileName: String): Boolean + fun readFile(fileName: String): String? + val trace: ((s: String) -> Unit)? + val directoryExists: ((directoryName: String) -> Boolean)? + val realpath: ((path: String) -> String)? + val getCurrentDirectory: (() -> String)? + val getDirectories: ((path: String) -> Array)? +} + +external interface ResolvedModule { + var resolvedFileName: String + var isExternalLibraryImport: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedModuleFull : ResolvedModule { + var extension: Extension + var packageId: PackageId? + get() = definedExternally + set(value) = definedExternally +} + +external interface PackageId { + var name: String + var subModuleName: String + var version: String +} + +external enum class Extension { + Ts /* = ".ts" */, + Tsx /* = ".tsx" */, + Dts /* = ".d.ts" */, + Js /* = ".js" */, + Jsx /* = ".jsx" */, + Json /* = ".json" */, + TsBuildInfo /* = ".tsbuildinfo" */ +} + +external interface ResolvedModuleWithFailedLookupLocations { + val resolvedModule: ResolvedModuleFull? +} + +external interface ResolvedTypeReferenceDirective { + var primary: Boolean? + var resolvedFileName: String? + var packageId: PackageId? + get() = definedExternally + set(value) = definedExternally + var isExternalLibraryImport: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations { + val resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective? + val failedLookupLocations: Array +} + +external interface CompilerHost : ModuleResolutionHost { + fun getSourceFile(fileName: String, languageVersion: ScriptTarget, onError: (message: String) -> Unit = definedExternally, shouldCreateNewSourceFile: Boolean = definedExternally): SourceFile? + val getSourceFileByPath: ((fileName: String, path: String /* String & `T$3` */, languageVersion: ScriptTarget, onError: (message: String) -> Unit, shouldCreateNewSourceFile: Boolean) -> SourceFile?)? + val getCancellationToken: (() -> CancellationToken)? + fun getDefaultLibFileName(options: CompilerOptions): String + val getDefaultLibLocation: (() -> String)? + var writeFile: WriteFileCallback + override var getCurrentDirectory: () -> String + fun getCanonicalFileName(fileName: String): String + fun useCaseSensitiveFileNames(): Boolean + fun getNewLine(): String + val readDirectory: ((rootDir: String, extensions: Array, excludes: Array?, includes: Array, depth: Number) -> Array)? + val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val getEnvironmentVariable: ((name: String) -> String?)? + val createHash: ((data: String) -> String)? + val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? +} + +external interface SourceMapRange : TextRange { + var source: SourceMapSource? + get() = definedExternally + set(value) = definedExternally +} + +external interface SourceMapSource { + fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter + var fileName: String + var text: String + var skipTrivia: ((pos: Number) -> Number)? + get() = definedExternally + set(value) = definedExternally +} + +external enum class EmitFlags { + None /* = 0 */, + SingleLine /* = 1 */, + AdviseOnEmitNode /* = 2 */, + NoSubstitution /* = 4 */, + CapturesThis /* = 8 */, + NoLeadingSourceMap /* = 16 */, + NoTrailingSourceMap /* = 32 */, + NoSourceMap /* = 48 */, + NoNestedSourceMaps /* = 64 */, + NoTokenLeadingSourceMaps /* = 128 */, + NoTokenTrailingSourceMaps /* = 256 */, + NoTokenSourceMaps /* = 384 */, + NoLeadingComments /* = 512 */, + NoTrailingComments /* = 1024 */, + NoComments /* = 1536 */, + NoNestedComments /* = 2048 */, + HelperName /* = 4096 */, + ExportName /* = 8192 */, + LocalName /* = 16384 */, + InternalName /* = 32768 */, + Indented /* = 65536 */, + NoIndentation /* = 131072 */, + AsyncFunctionBody /* = 262144 */, + ReuseTempVariableScope /* = 524288 */, + CustomPrologue /* = 1048576 */, + NoHoisting /* = 2097152 */, + HasEndOfDeclarationMarker /* = 4194304 */, + Iterator /* = 8388608 */, + NoAsciiEscaping /* = 16777216 */ +} + +external interface EmitHelperBase { + val name: String + val scoped: Boolean? + val text: dynamic /* String | (node: EmitHelperUniqueNameCallback) -> String */ + get() = definedExternally + val priority: Number? + get() = definedExternally + val dependencies: Array? + get() = definedExternally +} + +external interface ScopedEmitHelper : EmitHelperBase { + override val scoped: Boolean? +} + +external interface UnscopedEmitHelper : EmitHelperBase { + override val scoped: Boolean? + override val text: String +} + +external enum class EmitHint { + SourceFile /* = 0 */, + Expression /* = 1 */, + IdentifierName /* = 2 */, + MappedTypeParameter /* = 3 */, + Unspecified /* = 4 */, + EmbeddedStatement /* = 5 */, + JsxAttributeValue /* = 6 */ +} + +external enum class OuterExpressionKinds { + Parentheses /* = 1 */, + TypeAssertions /* = 2 */, + NonNullAssertions /* = 4 */, + PartiallyEmittedExpressions /* = 8 */, + Assertions /* = 6 */, + All /* = 15 */ +} + +external interface NodeFactory { + fun createNodeArray(elements: Array = definedExternally, hasTrailingComma: Boolean = definedExternally): NodeArray + fun createNumericLiteral(value: String, numericLiteralFlags: TokenFlags = definedExternally): NumericLiteral + fun createNumericLiteral(value: String): NumericLiteral + fun createNumericLiteral(value: Number, numericLiteralFlags: TokenFlags = definedExternally): NumericLiteral + fun createNumericLiteral(value: Number): NumericLiteral + fun createBigIntLiteral(value: String): BigIntLiteral + fun createBigIntLiteral(value: PseudoBigInt): BigIntLiteral + fun createStringLiteral(text: String, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: Identifier, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: Identifier): StringLiteral + fun createStringLiteralFromNode(sourceNode: StringLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: StringLiteral): StringLiteral + fun createStringLiteralFromNode(sourceNode: NoSubstitutionTemplateLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: NoSubstitutionTemplateLiteral): StringLiteral + fun createStringLiteralFromNode(sourceNode: NumericLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: NumericLiteral): StringLiteral + fun createRegularExpressionLiteral(text: String): RegularExpressionLiteral + fun createIdentifier(text: String): Identifier + fun createTempVariable(recordTempVariable: ((node: Identifier) -> Unit)?, reservedInNestedScopes: Boolean = definedExternally): Identifier + fun createLoopVariable(reservedInNestedScopes: Boolean = definedExternally): Identifier + fun createUniqueName(text: String, flags: GeneratedIdentifierFlags = definedExternally): Identifier + fun getGeneratedNameForNode(node: Node?, flags: GeneratedIdentifierFlags = definedExternally): Identifier + fun createPrivateIdentifier(text: String): PrivateIdentifier +// fun createToken(token: SyntaxKind = definedExternally): SuperExpression +// fun createToken(token: SyntaxKind = definedExternally): ThisExpression +// fun createToken(token: SyntaxKind = definedExternally): NullLiteral +// fun createToken(token: SyntaxKind = definedExternally): TrueLiteral +// fun createToken(token: SyntaxKind = definedExternally): FalseLiteral + fun createToken(token: TKind): dynamic /* Token */ + fun createSuper(): SuperExpression + fun createThis(): ThisExpression + fun createNull(): NullLiteral + fun createTrue(): TrueLiteral + fun createFalse(): FalseLiteral + fun createModifier(kind: T): ModifierToken + fun createModifiersFromModifierFlags(flags: ModifierFlags): Array + fun createQualifiedName(left: Identifier, right: String): QualifiedName + fun createQualifiedName(left: Identifier, right: Identifier): QualifiedName + fun createQualifiedName(left: QualifiedName, right: String): QualifiedName + fun createQualifiedName(left: QualifiedName, right: Identifier): QualifiedName + fun updateQualifiedName(node: QualifiedName, left: Identifier, right: Identifier): QualifiedName + fun updateQualifiedName(node: QualifiedName, left: QualifiedName, right: Identifier): QualifiedName + fun createComputedPropertyName(expression: Expression): ComputedPropertyName + fun updateComputedPropertyName(node: ComputedPropertyName, expression: Expression): ComputedPropertyName + fun createTypeParameterDeclaration(name: String, constraint: TypeNode = definedExternally, defaultType: TypeNode = definedExternally): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: String): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: String, constraint: TypeNode = definedExternally): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: Identifier, constraint: TypeNode = definedExternally, defaultType: TypeNode = definedExternally): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: Identifier): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: Identifier, constraint: TypeNode = definedExternally): TypeParameterDeclaration + fun updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode?, defaultType: TypeNode?): TypeParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration + fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration + fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration + fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration + fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration + fun createDecorator(expression: Expression): Decorator + fun updateDecorator(node: Decorator, expression: Expression): Decorator + fun createPropertySignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: String, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration + + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration + + fun createMethodSignature(modifiers: Array?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + + fun createConstructorDeclaration(decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration + fun updateConstructorDeclaration(node: ConstructorDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration + + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration + + fun createCallSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): CallSignatureDeclaration + fun updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): CallSignatureDeclaration + + fun createConstructSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): ConstructSignatureDeclaration + fun updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): ConstructSignatureDeclaration + + fun createIndexSignature(decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration + fun updateIndexSignature(node: IndexSignatureDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration + + fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan + fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan + + fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan + fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan + fun createKeywordTypeNode(kind: TKind): KeywordTypeNode + fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode + fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode + fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: String, type: TypeNode?): TypePredicateNode + fun updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode + fun updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode + fun createTypeReferenceNode(typeName: String, typeArguments: Array = definedExternally): TypeReferenceNode + fun createTypeReferenceNode(typeName: String): TypeReferenceNode + fun createTypeReferenceNode(typeName: Identifier, typeArguments: Array = definedExternally): TypeReferenceNode + fun createTypeReferenceNode(typeName: Identifier): TypeReferenceNode + fun createTypeReferenceNode(typeName: QualifiedName, typeArguments: Array = definedExternally): TypeReferenceNode + fun createTypeReferenceNode(typeName: QualifiedName): TypeReferenceNode + fun updateTypeReferenceNode(node: TypeReferenceNode, typeName: Identifier, typeArguments: NodeArray?): TypeReferenceNode + fun updateTypeReferenceNode(node: TypeReferenceNode, typeName: QualifiedName, typeArguments: NodeArray?): TypeReferenceNode + fun createFunctionTypeNode(typeParameters: Array?, parameters: Array, type: TypeNode): FunctionTypeNode + fun updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): FunctionTypeNode + fun createConstructorTypeNode(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode): ConstructorTypeNode + fun createConstructorTypeNode(typeParameters: Array?, parameters: Array, type: TypeNode): ConstructorTypeNode + fun updateConstructorTypeNode(node: ConstructorTypeNode, modifiers: Array?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): ConstructorTypeNode + fun updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): ConstructorTypeNode + fun createTypeQueryNode(exprName: Identifier): TypeQueryNode + fun createTypeQueryNode(exprName: QualifiedName): TypeQueryNode + fun updateTypeQueryNode(node: TypeQueryNode, exprName: Identifier): TypeQueryNode + fun updateTypeQueryNode(node: TypeQueryNode, exprName: QualifiedName): TypeQueryNode + fun createTypeLiteralNode(members: Array?): TypeLiteralNode + fun updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray): TypeLiteralNode + fun createArrayTypeNode(elementType: TypeNode): ArrayTypeNode + fun updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode + fun createTupleTypeNode(elements: Array): TupleTypeNode + fun updateTupleTypeNode(node: TupleTypeNode, elements: Array): TupleTypeNode + fun createNamedTupleMember(dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode): NamedTupleMember + fun updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode): NamedTupleMember + fun createOptionalTypeNode(type: TypeNode): OptionalTypeNode + fun updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode + fun createRestTypeNode(type: TypeNode): RestTypeNode + fun updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode + fun createUnionTypeNode(types: Array): UnionTypeNode + fun updateUnionTypeNode(node: UnionTypeNode, types: NodeArray): UnionTypeNode + fun createIntersectionTypeNode(types: Array): IntersectionTypeNode + fun updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray): IntersectionTypeNode + fun createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode + fun updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode + fun createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode + fun updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally, typeArguments: Array = definedExternally, isTypeOf: Boolean = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally, typeArguments: Array = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally, typeArguments: Array = definedExternally, isTypeOf: Boolean = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally, typeArguments: Array = definedExternally): ImportTypeNode + fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: Identifier?, typeArguments: Array?, isTypeOf: Boolean = definedExternally): ImportTypeNode + fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: Identifier?, typeArguments: Array?): ImportTypeNode + fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: QualifiedName?, typeArguments: Array?, isTypeOf: Boolean = definedExternally): ImportTypeNode + fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: QualifiedName?, typeArguments: Array?): ImportTypeNode + fun createParenthesizedType(type: TypeNode): ParenthesizedTypeNode + fun updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode + fun createThisTypeNode(): ThisTypeNode + fun createTypeOperatorNode(operator: SyntaxKind = definedExternally, type: TypeNode): TypeOperatorNode + fun updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode + fun createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode + fun updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode + + fun createMappedTypeNode(readonlyToken: SyntaxKind? = definedExternally, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: SyntaxKind? = definedExternally, type: TypeNode?): MappedTypeNode + + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: SyntaxKind? = definedExternally, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: SyntaxKind? = definedExternally, type: TypeNode?): MappedTypeNode + + fun createLiteralTypeNode(literal: NullLiteral): LiteralTypeNode + fun createLiteralTypeNode(literal: TrueLiteral): LiteralTypeNode + fun createLiteralTypeNode(literal: FalseLiteral): LiteralTypeNode + fun createLiteralTypeNode(literal: LiteralExpression): LiteralTypeNode + fun createLiteralTypeNode(literal: PrefixUnaryExpression): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: NullLiteral): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: TrueLiteral): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: FalseLiteral): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralExpression): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: PrefixUnaryExpression): LiteralTypeNode + fun createTemplateLiteralType(head: TemplateHead, templateSpans: Array): TemplateLiteralTypeNode + fun updateTemplateLiteralType(node: TemplateLiteralTypeNode, head: TemplateHead, templateSpans: Array): TemplateLiteralTypeNode + fun createObjectBindingPattern(elements: Array): ObjectBindingPattern + fun updateObjectBindingPattern(node: ObjectBindingPattern, elements: Array): ObjectBindingPattern + fun createArrayBindingPattern(elements: Array): ArrayBindingPattern + fun updateArrayBindingPattern(node: ArrayBindingPattern, elements: Array): ArrayBindingPattern + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: String?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: String?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun createArrayLiteralExpression(elements: Array = definedExternally, multiLine: Boolean = definedExternally): ArrayLiteralExpression + fun updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: Array): ArrayLiteralExpression + fun createObjectLiteralExpression(properties: Array = definedExternally, multiLine: Boolean = definedExternally): ObjectLiteralExpression + fun updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: Array): ObjectLiteralExpression + fun createPropertyAccessExpression(expression: Expression, name: String): PropertyAccessExpression + fun createPropertyAccessExpression(expression: Expression, name: Identifier): PropertyAccessExpression + fun createPropertyAccessExpression(expression: Expression, name: PrivateIdentifier): PropertyAccessExpression + fun updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier): PropertyAccessExpression + fun updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: PrivateIdentifier): PropertyAccessExpression + fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: String): PropertyAccessChain + fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: Identifier): PropertyAccessChain + fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: PrivateIdentifier): PropertyAccessChain + fun updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: Identifier): PropertyAccessChain + fun updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: PrivateIdentifier): PropertyAccessChain + fun createElementAccessExpression(expression: Expression, index: Number): ElementAccessExpression + fun createElementAccessExpression(expression: Expression, index: Expression): ElementAccessExpression + fun updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression + fun createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, index: Number): ElementAccessChain + fun createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, index: Expression): ElementAccessChain + fun updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, argumentExpression: Expression): ElementAccessChain + fun createCallExpression(expression: Expression, typeArguments: Array?, argumentsArray: Array?): CallExpression + fun updateCallExpression(node: CallExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array): CallExpression + fun createCallChain(expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array?): CallChain + fun updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array): CallChain + fun createNewExpression(expression: Expression, typeArguments: Array?, argumentsArray: Array?): NewExpression + fun updateNewExpression(node: NewExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array?): NewExpression + fun createTaggedTemplateExpression(tag: Expression, typeArguments: Array?, template: TemplateExpression): TaggedTemplateExpression + fun createTaggedTemplateExpression(tag: Expression, typeArguments: Array?, template: NoSubstitutionTemplateLiteral): TaggedTemplateExpression + fun updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: TemplateExpression): TaggedTemplateExpression + fun updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: NoSubstitutionTemplateLiteral): TaggedTemplateExpression + fun createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion + fun updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion + fun createParenthesizedExpression(expression: Expression): ParenthesizedExpression + fun updateParenthesizedExpression(node: ParenthesizedExpression, expression: Expression): ParenthesizedExpression + fun createFunctionExpression(modifiers: Array?, asteriskToken: AsteriskToken?, name: String?, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block): FunctionExpression + fun createFunctionExpression(modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block): FunctionExpression + fun updateFunctionExpression(node: FunctionExpression, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block): FunctionExpression + fun createArrowFunction(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: FunctionBody): ArrowFunction + fun createArrowFunction(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: Expression): ArrowFunction + fun updateArrowFunction(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: FunctionBody): ArrowFunction + fun updateArrowFunction(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: Expression): ArrowFunction + fun createDeleteExpression(expression: Expression): DeleteExpression + fun updateDeleteExpression(node: DeleteExpression, expression: Expression): DeleteExpression + fun createTypeOfExpression(expression: Expression): TypeOfExpression + fun updateTypeOfExpression(node: TypeOfExpression, expression: Expression): TypeOfExpression + fun createVoidExpression(expression: Expression): VoidExpression + fun updateVoidExpression(node: VoidExpression, expression: Expression): VoidExpression + fun createAwaitExpression(expression: Expression): AwaitExpression + fun updateAwaitExpression(node: AwaitExpression, expression: Expression): AwaitExpression + fun createPrefixUnaryExpression(operator: SyntaxKind = definedExternally, operand: Expression): PrefixUnaryExpression + fun updatePrefixUnaryExpression(node: PrefixUnaryExpression, operand: Expression): PrefixUnaryExpression + fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind = definedExternally): PostfixUnaryExpression + fun updatePostfixUnaryExpression(node: PostfixUnaryExpression, operand: Expression): PostfixUnaryExpression + fun createBinaryExpression( + left: Expression, + operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, + right: Expression + ): BinaryExpression + + fun updateBinaryExpression( + node: BinaryExpression, + left: Expression, + operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, + right: Expression + ): BinaryExpression + + fun createConditionalExpression(condition: Expression, questionToken: QuestionToken?, whenTrue: Expression, colonToken: ColonToken?, whenFalse: Expression): ConditionalExpression + fun updateConditionalExpression(node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression + fun createTemplateExpression(head: TemplateHead, templateSpans: Array): TemplateExpression + fun updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: Array): TemplateExpression + fun createTemplateHead(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateHead + fun createTemplateHead(text: String): TemplateHead + fun createTemplateHead(text: String, rawText: String = definedExternally): TemplateHead + fun createTemplateHead(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateHead + fun createTemplateHead(text: String?, rawText: String): TemplateHead + fun createTemplateMiddle(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateMiddle + fun createTemplateMiddle(text: String): TemplateMiddle + fun createTemplateMiddle(text: String, rawText: String = definedExternally): TemplateMiddle + fun createTemplateMiddle(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateMiddle + fun createTemplateMiddle(text: String?, rawText: String): TemplateMiddle + fun createTemplateTail(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateTail + fun createTemplateTail(text: String): TemplateTail + fun createTemplateTail(text: String, rawText: String = definedExternally): TemplateTail + fun createTemplateTail(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateTail + fun createTemplateTail(text: String?, rawText: String): TemplateTail + fun createNoSubstitutionTemplateLiteral(text: String, rawText: String = definedExternally): NoSubstitutionTemplateLiteral + fun createNoSubstitutionTemplateLiteral(text: String): NoSubstitutionTemplateLiteral + fun createNoSubstitutionTemplateLiteral(text: String?, rawText: String): NoSubstitutionTemplateLiteral + fun createYieldExpression(asteriskToken: AsteriskToken, expression: Expression): YieldExpression + fun createYieldExpression(asteriskToken: Nothing?, expression: Expression?): YieldExpression + fun updateYieldExpression(node: YieldExpression, asteriskToken: AsteriskToken?, expression: Expression?): YieldExpression + fun createSpreadElement(expression: Expression): SpreadElement + fun updateSpreadElement(node: SpreadElement, expression: Expression): SpreadElement + fun createClassExpression(decorators: Array?, modifiers: Array?, name: String?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression + fun createClassExpression(decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression + fun updateClassExpression(node: ClassExpression, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression + fun createOmittedExpression(): OmittedExpression + fun createExpressionWithTypeArguments(expression: Expression, typeArguments: Array?): ExpressionWithTypeArguments + fun updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, expression: Expression, typeArguments: Array?): ExpressionWithTypeArguments + fun createAsExpression(expression: Expression, type: TypeNode): AsExpression + fun updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode): AsExpression + fun createNonNullExpression(expression: Expression): NonNullExpression + fun updateNonNullExpression(node: NonNullExpression, expression: Expression): NonNullExpression + fun createNonNullChain(expression: Expression): NonNullChain + fun updateNonNullChain(node: NonNullChain, expression: Expression): NonNullChain + fun createMetaProperty(keywordToken: SyntaxKind = definedExternally, name: Identifier): MetaProperty + fun updateMetaProperty(node: MetaProperty, name: Identifier): MetaProperty + fun createTemplateSpan(expression: Expression, literal: TemplateMiddle): TemplateSpan + fun createTemplateSpan(expression: Expression, literal: TemplateTail): TemplateSpan + fun updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle): TemplateSpan + fun updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateTail): TemplateSpan + fun createSemicolonClassElement(): SemicolonClassElement + fun createBlock(statements: Array, multiLine: Boolean = definedExternally): Block + fun updateBlock(node: Block, statements: Array): Block + fun createVariableStatement(modifiers: Array?, declarationList: VariableDeclarationList): VariableStatement + fun createVariableStatement(modifiers: Array?, declarationList: Array): VariableStatement + fun updateVariableStatement(node: VariableStatement, modifiers: Array?, declarationList: VariableDeclarationList): VariableStatement + fun createEmptyStatement(): EmptyStatement + fun createExpressionStatement(expression: Expression): ExpressionStatement + fun updateExpressionStatement(node: ExpressionStatement, expression: Expression): ExpressionStatement + fun createIfStatement(expression: Expression, thenStatement: Statement, elseStatement: Statement = definedExternally): IfStatement + fun updateIfStatement(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement?): IfStatement + fun createDoStatement(statement: Statement, expression: Expression): DoStatement + fun updateDoStatement(node: DoStatement, statement: Statement, expression: Expression): DoStatement + fun createWhileStatement(expression: Expression, statement: Statement): WhileStatement + fun updateWhileStatement(node: WhileStatement, expression: Expression, statement: Statement): WhileStatement + fun createForStatement(initializer: VariableDeclarationList?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement + fun createForStatement(initializer: Expression?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement + fun updateForStatement(node: ForStatement, initializer: VariableDeclarationList?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement + fun updateForStatement(node: ForStatement, initializer: Expression?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement + fun createForInStatement(initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForInStatement + fun createForInStatement(initializer: Expression, expression: Expression, statement: Statement): ForInStatement + fun updateForInStatement(node: ForInStatement, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForInStatement + fun updateForInStatement(node: ForInStatement, initializer: Expression, expression: Expression, statement: Statement): ForInStatement + fun createForOfStatement(awaitModifier: AwaitKeyword?, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForOfStatement + fun createForOfStatement(awaitModifier: AwaitKeyword?, initializer: Expression, expression: Expression, statement: Statement): ForOfStatement + fun updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForOfStatement + fun updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: Expression, expression: Expression, statement: Statement): ForOfStatement + fun createContinueStatement(label: String = definedExternally): ContinueStatement + fun createContinueStatement(): ContinueStatement + fun createContinueStatement(label: Identifier = definedExternally): ContinueStatement + fun updateContinueStatement(node: ContinueStatement, label: Identifier?): ContinueStatement + fun createBreakStatement(label: String = definedExternally): BreakStatement + fun createBreakStatement(): BreakStatement + fun createBreakStatement(label: Identifier = definedExternally): BreakStatement + fun updateBreakStatement(node: BreakStatement, label: Identifier?): BreakStatement + fun createReturnStatement(expression: Expression = definedExternally): ReturnStatement + fun updateReturnStatement(node: ReturnStatement, expression: Expression?): ReturnStatement + fun createWithStatement(expression: Expression, statement: Statement): WithStatement + fun updateWithStatement(node: WithStatement, expression: Expression, statement: Statement): WithStatement + fun createSwitchStatement(expression: Expression, caseBlock: CaseBlock): SwitchStatement + fun updateSwitchStatement(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock): SwitchStatement + fun createLabeledStatement(label: String, statement: Statement): LabeledStatement + fun createLabeledStatement(label: Identifier, statement: Statement): LabeledStatement + fun updateLabeledStatement(node: LabeledStatement, label: Identifier, statement: Statement): LabeledStatement + fun createThrowStatement(expression: Expression): ThrowStatement + fun updateThrowStatement(node: ThrowStatement, expression: Expression): ThrowStatement + fun createTryStatement(tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?): TryStatement + fun updateTryStatement(node: TryStatement, tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?): TryStatement + fun createDebuggerStatement(): DebuggerStatement + fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: String): VariableDeclaration + fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: Identifier): VariableDeclaration + fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ObjectBindingPattern): VariableDeclaration + fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ArrayBindingPattern): VariableDeclaration + fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration + fun updateVariableDeclaration(node: VariableDeclaration, name: Identifier, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration + fun updateVariableDeclaration(node: VariableDeclaration, name: ObjectBindingPattern, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration + fun updateVariableDeclaration(node: VariableDeclaration, name: ArrayBindingPattern, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration + fun createVariableDeclarationList(declarations: Array, flags: NodeFlags = definedExternally): VariableDeclarationList + fun updateVariableDeclarationList(node: VariableDeclarationList, declarations: Array): VariableDeclarationList + fun createFunctionDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration + fun createFunctionDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration + fun updateFunctionDeclaration(node: FunctionDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration + fun createClassDeclaration(decorators: Array?, modifiers: Array?, name: String?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration + fun createClassDeclaration(decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration + fun updateClassDeclaration(node: ClassDeclaration, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration + fun createInterfaceDeclaration(decorators: Array?, modifiers: Array?, name: String, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration + fun createInterfaceDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration + fun updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration + fun createTypeAliasDeclaration(decorators: Array?, modifiers: Array?, name: String, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration + fun createTypeAliasDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration + fun updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration + fun createEnumDeclaration(decorators: Array?, modifiers: Array?, name: String, members: Array): EnumDeclaration + fun createEnumDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, members: Array): EnumDeclaration + fun updateEnumDeclaration(node: EnumDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, members: Array): EnumDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?): ModuleDeclaration + fun createModuleBlock(statements: Array): ModuleBlock + fun updateModuleBlock(node: ModuleBlock, statements: Array): ModuleBlock + fun createCaseBlock(clauses: Array): CaseBlock + fun updateCaseBlock(node: CaseBlock, clauses: Array): CaseBlock + fun createNamespaceExportDeclaration(name: String): NamespaceExportDeclaration + fun createNamespaceExportDeclaration(name: Identifier): NamespaceExportDeclaration + fun updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier): NamespaceExportDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: Identifier): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: QualifiedName): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: ExternalModuleReference): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: Identifier): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: QualifiedName): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: ExternalModuleReference): ImportEqualsDeclaration + fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: Identifier): ImportEqualsDeclaration + fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: QualifiedName): ImportEqualsDeclaration + fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: ExternalModuleReference): ImportEqualsDeclaration + fun createImportDeclaration(decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression): ImportDeclaration + fun updateImportDeclaration(node: ImportDeclaration, decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression): ImportDeclaration + fun createImportClause(isTypeOnly: Boolean, name: Identifier?, namedBindings: NamespaceImport?): ImportClause + fun createImportClause(isTypeOnly: Boolean, name: Identifier?, namedBindings: NamedImports?): ImportClause + fun updateImportClause(node: ImportClause, isTypeOnly: Boolean, name: Identifier?, namedBindings: NamespaceImport?): ImportClause + fun updateImportClause(node: ImportClause, isTypeOnly: Boolean, name: Identifier?, namedBindings: NamedImports?): ImportClause + fun createNamespaceImport(name: Identifier): NamespaceImport + fun updateNamespaceImport(node: NamespaceImport, name: Identifier): NamespaceImport + fun createNamespaceExport(name: Identifier): NamespaceExport + fun updateNamespaceExport(node: NamespaceExport, name: Identifier): NamespaceExport + fun createNamedImports(elements: Array): NamedImports + fun updateNamedImports(node: NamedImports, elements: Array): NamedImports + fun createImportSpecifier(propertyName: Identifier?, name: Identifier): ImportSpecifier + fun updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier?, name: Identifier): ImportSpecifier + fun createExportAssignment(decorators: Array?, modifiers: Array?, isExportEquals: Boolean?, expression: Expression): ExportAssignment + fun updateExportAssignment(node: ExportAssignment, decorators: Array?, modifiers: Array?, expression: Expression): ExportAssignment + fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?, moduleSpecifier: Expression = definedExternally): ExportDeclaration + fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?): ExportDeclaration + fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?, moduleSpecifier: Expression = definedExternally): ExportDeclaration + fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?): ExportDeclaration + fun updateExportDeclaration(node: ExportDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?, moduleSpecifier: Expression?): ExportDeclaration + fun updateExportDeclaration(node: ExportDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?, moduleSpecifier: Expression?): ExportDeclaration + fun createNamedExports(elements: Array): NamedExports + fun updateNamedExports(node: NamedExports, elements: Array): NamedExports + fun createExportSpecifier(propertyName: String?, name: String): ExportSpecifier + fun createExportSpecifier(propertyName: String?, name: Identifier): ExportSpecifier + fun createExportSpecifier(propertyName: Identifier?, name: String): ExportSpecifier + fun createExportSpecifier(propertyName: Identifier?, name: Identifier): ExportSpecifier + fun updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier?, name: Identifier): ExportSpecifier + fun createExternalModuleReference(expression: Expression): ExternalModuleReference + fun updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference + fun createJSDocAllType(): JSDocAllType + fun createJSDocUnknownType(): JSDocUnknownType + fun createJSDocNonNullableType(type: TypeNode): JSDocNonNullableType + fun updateJSDocNonNullableType(node: JSDocNonNullableType, type: TypeNode): JSDocNonNullableType + fun createJSDocNullableType(type: TypeNode): JSDocNullableType + fun updateJSDocNullableType(node: JSDocNullableType, type: TypeNode): JSDocNullableType + fun createJSDocOptionalType(type: TypeNode): JSDocOptionalType + fun updateJSDocOptionalType(node: JSDocOptionalType, type: TypeNode): JSDocOptionalType + fun createJSDocFunctionType(parameters: Array, type: TypeNode?): JSDocFunctionType + fun updateJSDocFunctionType(node: JSDocFunctionType, parameters: Array, type: TypeNode?): JSDocFunctionType + fun createJSDocVariadicType(type: TypeNode): JSDocVariadicType + fun updateJSDocVariadicType(node: JSDocVariadicType, type: TypeNode): JSDocVariadicType + fun createJSDocNamepathType(type: TypeNode): JSDocNamepathType + fun updateJSDocNamepathType(node: JSDocNamepathType, type: TypeNode): JSDocNamepathType + fun createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression + fun updateJSDocTypeExpression(node: JSDocTypeExpression, type: TypeNode): JSDocTypeExpression + fun createJSDocNameReference(name: Identifier): JSDocNameReference + fun createJSDocNameReference(name: QualifiedName): JSDocNameReference + fun updateJSDocNameReference(node: JSDocNameReference, name: Identifier): JSDocNameReference + fun updateJSDocNameReference(node: JSDocNameReference, name: QualifiedName): JSDocNameReference + fun createJSDocLink(name: Identifier?, text: String): JSDocLink + fun createJSDocLink(name: QualifiedName?, text: String): JSDocLink + fun updateJSDocLink(node: JSDocLink, name: Identifier?, text: String): JSDocLink + fun updateJSDocLink(node: JSDocLink, name: QualifiedName?, text: String): JSDocLink + fun createJSDocTypeLiteral(jsDocPropertyTags: Array = definedExternally, isArrayType: Boolean = definedExternally): JSDocTypeLiteral + fun updateJSDocTypeLiteral(node: JSDocTypeLiteral, jsDocPropertyTags: Array?, isArrayType: Boolean?): JSDocTypeLiteral + fun createJSDocSignature(typeParameters: Array?, parameters: Array, type: JSDocReturnTag = definedExternally): JSDocSignature + fun updateJSDocSignature(node: JSDocSignature, typeParameters: Array?, parameters: Array, type: JSDocReturnTag?): JSDocSignature + fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String = definedExternally): JSDocTemplateTag + fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array): JSDocTemplateTag + fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray = definedExternally): JSDocTemplateTag + fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String?): JSDocTemplateTag + fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray?): JSDocTemplateTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: String?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: String?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag + fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocTypeTag + fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocTypeTag + fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocTypeTag + fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocTypeTag + fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocTypeTag + fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag + fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag + fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag + fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag + fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag + fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag + fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: String = definedExternally): JSDocReturnTag + fun createJSDocReturnTag(tagName: Identifier?): JSDocReturnTag + fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocReturnTag + fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: NodeArray = definedExternally): JSDocReturnTag + fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocReturnTag + fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocReturnTag + fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocThisTag + fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocThisTag + fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocThisTag + fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocThisTag + fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocThisTag + fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocEnumTag + fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocEnumTag + fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocEnumTag + fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocEnumTag + fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocEnumTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: String?): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: NodeArray?): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocCallbackTag + fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: String = definedExternally): JSDocAugmentsTag + fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */): JSDocAugmentsTag + fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: NodeArray = definedExternally): JSDocAugmentsTag + fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: String?): JSDocAugmentsTag + fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: NodeArray?): JSDocAugmentsTag + fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: String = definedExternally): JSDocImplementsTag + fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */): JSDocImplementsTag + fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: NodeArray = definedExternally): JSDocImplementsTag + fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: String?): JSDocImplementsTag + fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: NodeArray?): JSDocImplementsTag + fun createJSDocAuthorTag(tagName: Identifier?, comment: String = definedExternally): JSDocAuthorTag + fun createJSDocAuthorTag(tagName: Identifier?): JSDocAuthorTag + fun createJSDocAuthorTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocAuthorTag + fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: String?): JSDocAuthorTag + fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: NodeArray?): JSDocAuthorTag + fun createJSDocClassTag(tagName: Identifier?, comment: String = definedExternally): JSDocClassTag + fun createJSDocClassTag(tagName: Identifier?): JSDocClassTag + fun createJSDocClassTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocClassTag + fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: String?): JSDocClassTag + fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: NodeArray?): JSDocClassTag + fun createJSDocPublicTag(tagName: Identifier?, comment: String = definedExternally): JSDocPublicTag + fun createJSDocPublicTag(tagName: Identifier?): JSDocPublicTag + fun createJSDocPublicTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPublicTag + fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: String?): JSDocPublicTag + fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: NodeArray?): JSDocPublicTag + fun createJSDocPrivateTag(tagName: Identifier?, comment: String = definedExternally): JSDocPrivateTag + fun createJSDocPrivateTag(tagName: Identifier?): JSDocPrivateTag + fun createJSDocPrivateTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPrivateTag + fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: String?): JSDocPrivateTag + fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: NodeArray?): JSDocPrivateTag + fun createJSDocProtectedTag(tagName: Identifier?, comment: String = definedExternally): JSDocProtectedTag + fun createJSDocProtectedTag(tagName: Identifier?): JSDocProtectedTag + fun createJSDocProtectedTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocProtectedTag + fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: String?): JSDocProtectedTag + fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: NodeArray?): JSDocProtectedTag + fun createJSDocReadonlyTag(tagName: Identifier?, comment: String = definedExternally): JSDocReadonlyTag + fun createJSDocReadonlyTag(tagName: Identifier?): JSDocReadonlyTag + fun createJSDocReadonlyTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocReadonlyTag + fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: String?): JSDocReadonlyTag + fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: NodeArray?): JSDocReadonlyTag + fun createJSDocUnknownTag(tagName: Identifier, comment: String = definedExternally): JSDocUnknownTag + fun createJSDocUnknownTag(tagName: Identifier): JSDocUnknownTag + fun createJSDocUnknownTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocUnknownTag + fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: String?): JSDocUnknownTag + fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: NodeArray?): JSDocUnknownTag + fun createJSDocDeprecatedTag(tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag + fun createJSDocDeprecatedTag(tagName: Identifier): JSDocDeprecatedTag + fun createJSDocDeprecatedTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag + fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag + fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier): JSDocDeprecatedTag + fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag + fun createJSDocOverrideTag(tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag + fun createJSDocOverrideTag(tagName: Identifier): JSDocOverrideTag + fun createJSDocOverrideTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag + fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag + fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier): JSDocOverrideTag + fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag + fun createJSDocText(text: String): JSDocText + fun updateJSDocText(node: JSDocText, text: String): JSDocText + fun createJSDocComment(comment: String? = definedExternally, tags: Array? = definedExternally): JSDoc + fun createJSDocComment(): JSDoc + fun createJSDocComment(comment: String? = definedExternally): JSDoc + fun createJSDocComment(comment: NodeArray? = definedExternally, tags: Array? = definedExternally): JSDoc + fun createJSDocComment(comment: NodeArray? = definedExternally): JSDoc + fun updateJSDocComment(node: JSDoc, comment: String?, tags: Array?): JSDoc + fun updateJSDocComment(node: JSDoc, comment: NodeArray?, tags: Array?): JSDoc + fun createJsxElement(openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement + fun updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement + fun createJsxSelfClosingElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun createJsxSelfClosingElement(tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun createJsxSelfClosingElement(tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun createJsxOpeningElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun createJsxOpeningElement(tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun createJsxOpeningElement(tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun createJsxClosingElement(tagName: Identifier): JsxClosingElement + fun createJsxClosingElement(tagName: ThisExpression): JsxClosingElement + fun createJsxClosingElement(tagName: JsxTagNamePropertyAccess): JsxClosingElement + fun updateJsxClosingElement(node: JsxClosingElement, tagName: Identifier): JsxClosingElement + fun updateJsxClosingElement(node: JsxClosingElement, tagName: ThisExpression): JsxClosingElement + fun updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNamePropertyAccess): JsxClosingElement + fun createJsxFragment(openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment): JsxFragment + fun createJsxText(text: String, containsOnlyTriviaWhiteSpaces: Boolean = definedExternally): JsxText + fun updateJsxText(node: JsxText, text: String, containsOnlyTriviaWhiteSpaces: Boolean = definedExternally): JsxText + fun createJsxOpeningFragment(): JsxOpeningFragment + fun createJsxJsxClosingFragment(): JsxClosingFragment + fun updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment): JsxFragment + fun createJsxAttribute(name: Identifier, initializer: StringLiteral?): JsxAttribute + fun createJsxAttribute(name: Identifier, initializer: JsxExpression?): JsxAttribute + fun updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral?): JsxAttribute + fun updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: JsxExpression?): JsxAttribute + fun createJsxAttributes(properties: Array): JsxAttributes + fun updateJsxAttributes(node: JsxAttributes, properties: Array): JsxAttributes + fun createJsxSpreadAttribute(expression: Expression): JsxSpreadAttribute + fun updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression): JsxSpreadAttribute + fun createJsxExpression(dotDotDotToken: DotDotDotToken?, expression: Expression?): JsxExpression + fun updateJsxExpression(node: JsxExpression, expression: Expression?): JsxExpression + fun createCaseClause(expression: Expression, statements: Array): CaseClause + fun updateCaseClause(node: CaseClause, expression: Expression, statements: Array): CaseClause + fun createDefaultClause(statements: Array): DefaultClause + fun updateDefaultClause(node: DefaultClause, statements: Array): DefaultClause + fun createHeritageClause(token: SyntaxKind = definedExternally, types: Array): HeritageClause + fun updateHeritageClause(node: HeritageClause, types: Array): HeritageClause + fun createCatchClause(variableDeclaration: String?, block: Block): CatchClause + fun createCatchClause(variableDeclaration: VariableDeclaration?, block: Block): CatchClause + fun updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration?, block: Block): CatchClause + fun createPropertyAssignment(name: String, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: Identifier, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: StringLiteral, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: NumericLiteral, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: ComputedPropertyName, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: PrivateIdentifier, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: Identifier, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: StringLiteral, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: NumericLiteral, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: ComputedPropertyName, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: PrivateIdentifier, initializer: Expression): PropertyAssignment + fun createShorthandPropertyAssignment(name: String, objectAssignmentInitializer: Expression = definedExternally): ShorthandPropertyAssignment + fun createShorthandPropertyAssignment(name: String): ShorthandPropertyAssignment + fun createShorthandPropertyAssignment(name: Identifier, objectAssignmentInitializer: Expression = definedExternally): ShorthandPropertyAssignment + fun createShorthandPropertyAssignment(name: Identifier): ShorthandPropertyAssignment + fun updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression?): ShorthandPropertyAssignment + fun createSpreadAssignment(expression: Expression): SpreadAssignment + fun updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment + fun createEnumMember(name: String, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: String): EnumMember + fun createEnumMember(name: Identifier, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: Identifier): EnumMember + fun createEnumMember(name: StringLiteral, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: StringLiteral): EnumMember + fun createEnumMember(name: NumericLiteral, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: NumericLiteral): EnumMember + fun createEnumMember(name: ComputedPropertyName, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: ComputedPropertyName): EnumMember + fun createEnumMember(name: PrivateIdentifier, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: PrivateIdentifier): EnumMember + fun updateEnumMember(node: EnumMember, name: Identifier, initializer: Expression?): EnumMember + fun updateEnumMember(node: EnumMember, name: StringLiteral, initializer: Expression?): EnumMember + fun updateEnumMember(node: EnumMember, name: NumericLiteral, initializer: Expression?): EnumMember + fun updateEnumMember(node: EnumMember, name: ComputedPropertyName, initializer: Expression?): EnumMember + fun updateEnumMember(node: EnumMember, name: PrivateIdentifier, initializer: Expression?): EnumMember + fun createSourceFile(statements: Array, endOfFileToken: Token /* Token & JSDocContainer */, flags: NodeFlags): SourceFile + fun updateSourceFile(node: SourceFile, statements: Array, isDeclarationFile: Boolean = definedExternally, referencedFiles: Array = definedExternally, typeReferences: Array = definedExternally, hasNoDefaultLib: Boolean = definedExternally, libReferences: Array = definedExternally): SourceFile + fun createNotEmittedStatement(original: Node): NotEmittedStatement + fun createPartiallyEmittedExpression(expression: Expression, original: Node = definedExternally): PartiallyEmittedExpression + fun updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression): PartiallyEmittedExpression + fun createCommaListExpression(elements: Array): CommaListExpression + fun updateCommaListExpression(node: CommaListExpression, elements: Array): CommaListExpression + fun createBundle(sourceFiles: Array, prepends: Array = definedExternally): Bundle + fun updateBundle(node: Bundle, sourceFiles: Array, prepends: Array = definedExternally): Bundle + fun createComma(left: Expression, right: Expression): BinaryExpression + fun createAssignment(left: ObjectLiteralExpression, right: Expression): dynamic /* ObjectDestructuringAssignment | ArrayDestructuringAssignment */ + fun createAssignment(left: ArrayLiteralExpression, right: Expression): dynamic /* ObjectDestructuringAssignment | ArrayDestructuringAssignment */ + fun createAssignment(left: Expression, right: Expression): AssignmentExpression + fun createLogicalOr(left: Expression, right: Expression): BinaryExpression + fun createLogicalAnd(left: Expression, right: Expression): BinaryExpression + fun createBitwiseOr(left: Expression, right: Expression): BinaryExpression + fun createBitwiseXor(left: Expression, right: Expression): BinaryExpression + fun createBitwiseAnd(left: Expression, right: Expression): BinaryExpression + fun createStrictEquality(left: Expression, right: Expression): BinaryExpression + fun createStrictInequality(left: Expression, right: Expression): BinaryExpression + fun createEquality(left: Expression, right: Expression): BinaryExpression + fun createInequality(left: Expression, right: Expression): BinaryExpression + fun createLessThan(left: Expression, right: Expression): BinaryExpression + fun createLessThanEquals(left: Expression, right: Expression): BinaryExpression + fun createGreaterThan(left: Expression, right: Expression): BinaryExpression + fun createGreaterThanEquals(left: Expression, right: Expression): BinaryExpression + fun createLeftShift(left: Expression, right: Expression): BinaryExpression + fun createRightShift(left: Expression, right: Expression): BinaryExpression + fun createUnsignedRightShift(left: Expression, right: Expression): BinaryExpression + fun createAdd(left: Expression, right: Expression): BinaryExpression + fun createSubtract(left: Expression, right: Expression): BinaryExpression + fun createMultiply(left: Expression, right: Expression): BinaryExpression + fun createDivide(left: Expression, right: Expression): BinaryExpression + fun createModulo(left: Expression, right: Expression): BinaryExpression + fun createExponent(left: Expression, right: Expression): BinaryExpression + fun createPrefixPlus(operand: Expression): PrefixUnaryExpression + fun createPrefixMinus(operand: Expression): PrefixUnaryExpression + fun createPrefixIncrement(operand: Expression): PrefixUnaryExpression + fun createPrefixDecrement(operand: Expression): PrefixUnaryExpression + fun createBitwiseNot(operand: Expression): PrefixUnaryExpression + fun createLogicalNot(operand: Expression): PrefixUnaryExpression + fun createPostfixIncrement(operand: Expression): PostfixUnaryExpression + fun createPostfixDecrement(operand: Expression): PostfixUnaryExpression + fun createImmediatelyInvokedFunctionExpression(statements: Array): CallExpression + fun createImmediatelyInvokedFunctionExpression(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression + fun createImmediatelyInvokedArrowFunction(statements: Array): CallExpression + fun createImmediatelyInvokedArrowFunction(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression + fun createVoidZero(): VoidExpression + fun createExportDefault(expression: Expression): ExportAssignment + fun createExternalModuleExport(exportName: Identifier): ExportDeclaration + fun restoreOuterExpressions(outerExpression: Expression?, innerExpression: Expression, kinds: OuterExpressionKinds = definedExternally): Expression +} + +external interface CoreTransformationContext { + val factory: NodeFactory + fun getCompilerOptions(): CompilerOptions + fun startLexicalEnvironment() + fun suspendLexicalEnvironment() + fun resumeLexicalEnvironment() + fun endLexicalEnvironment(): Array? + fun hoistFunctionDeclaration(node: FunctionDeclaration) + fun hoistVariableDeclaration(node: Identifier) +} + +external interface TransformationContext : CoreTransformationContext { + fun requestEmitHelper(helper: ScopedEmitHelper) + fun requestEmitHelper(helper: UnscopedEmitHelper) + fun readEmitHelpers(): Array? + fun enableSubstitution(kind: SyntaxKind) + fun isSubstitutionEnabled(node: Node): Boolean + var onSubstituteNode: (hint: EmitHint, node: Node) -> Node + fun enableEmitNotification(kind: SyntaxKind) + fun isEmitNotificationEnabled(node: Node): Boolean + var onEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) -> Unit +} + +external interface TransformationResult { + var transformed: Array + var diagnostics: Array? + get() = definedExternally + set(value) = definedExternally + + fun substituteNode(hint: EmitHint, node: Node): Node + fun emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) + val isEmitNotificationEnabled: ((node: Node) -> Boolean)? + fun dispose() +} + +external interface NodeVisitor { + @nativeInvoke + operator fun invoke(nodes: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T + @nativeInvoke + operator fun invoke(nodes: T, visitor: Visitor?): T + @nativeInvoke + operator fun invoke(nodes: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T + @nativeInvoke + operator fun invoke(nodes: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T? + @nativeInvoke + operator fun invoke(nodes: T?, visitor: Visitor?): T? + @nativeInvoke + operator fun invoke(nodes: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T? +} + +external interface NodesVisitor { + @nativeInvoke + operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray + @nativeInvoke + operator fun invoke(nodes: NodeArray, visitor: Visitor?): NodeArray + @nativeInvoke + operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray + @nativeInvoke + operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray + @nativeInvoke + operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray? + @nativeInvoke + operator fun invoke(nodes: NodeArray?, visitor: Visitor?): NodeArray? + @nativeInvoke + operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray? + @nativeInvoke + operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray? +} + +external interface Printer { + fun printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): String + fun printList(format: ListFormat, list: NodeArray, sourceFile: SourceFile): String + fun printFile(sourceFile: SourceFile): String + fun printBundle(bundle: Bundle): String +} + +external interface PrintHandlers { + val hasGlobalName: ((name: String) -> Boolean)? + val onEmitNode: ((hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) -> Unit)? + val isEmitNotificationEnabled: ((node: Node) -> Boolean)? + val substituteNode: ((hint: EmitHint, node: Node) -> Node)? +} + +external interface PrinterOptions { + var removeComments: Boolean? + get() = definedExternally + set(value) = definedExternally + var newLine: NewLineKind? + get() = definedExternally + set(value) = definedExternally + var omitTrailingSemicolon: Boolean? + get() = definedExternally + set(value) = definedExternally + var noEmitHelpers: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface GetEffectiveTypeRootsHost { + val directoryExists: ((directoryName: String) -> Boolean)? + val getCurrentDirectory: (() -> String)? +} + +external interface TextSpan { + var start: Number + var length: Number +} + +external interface TextChangeRange { + var span: TextSpan + var newLength: Number +} + +external interface SyntaxList : Node { + var _children: Array +} + +external enum class ListFormat { + None /* = 0 */, + SingleLine /* = 0 */, + MultiLine /* = 1 */, + PreserveLines /* = 2 */, + LinesMask /* = 3 */, + NotDelimited /* = 0 */, + BarDelimited /* = 4 */, + AmpersandDelimited /* = 8 */, + CommaDelimited /* = 16 */, + AsteriskDelimited /* = 32 */, + DelimitersMask /* = 60 */, + AllowTrailingComma /* = 64 */, + Indented /* = 128 */, + SpaceBetweenBraces /* = 256 */, + SpaceBetweenSiblings /* = 512 */, + Braces /* = 1024 */, + Parenthesis /* = 2048 */, + AngleBrackets /* = 4096 */, + SquareBrackets /* = 8192 */, + BracketsMask /* = 15360 */, + OptionalIfUndefined /* = 16384 */, + OptionalIfEmpty /* = 32768 */, + Optional /* = 49152 */, + PreferNewLine /* = 65536 */, + NoTrailingNewLine /* = 131072 */, + NoInterveningComments /* = 262144 */, + NoSpaceIfEmpty /* = 524288 */, + SingleElement /* = 1048576 */, + SpaceAfterList /* = 2097152 */, + Modifiers /* = 262656 */, + HeritageClauses /* = 512 */, + SingleLineTypeLiteralMembers /* = 768 */, + MultiLineTypeLiteralMembers /* = 32897 */, + SingleLineTupleTypeElements /* = 528 */, + MultiLineTupleTypeElements /* = 657 */, + UnionTypeConstituents /* = 516 */, + IntersectionTypeConstituents /* = 520 */, + ObjectBindingPatternElements /* = 525136 */, + ArrayBindingPatternElements /* = 524880 */, + ObjectLiteralExpressionProperties /* = 526226 */, + ArrayLiteralExpressionElements /* = 8914 */, + CommaListElements /* = 528 */, + CallExpressionArguments /* = 2576 */, + NewExpressionArguments /* = 18960 */, + TemplateExpressionSpans /* = 262144 */, + SingleLineBlockStatements /* = 768 */, + MultiLineBlockStatements /* = 129 */, + VariableDeclarationList /* = 528 */, + SingleLineFunctionBodyStatements /* = 768 */, + MultiLineFunctionBodyStatements /* = 1 */, + ClassHeritageClauses /* = 0 */, + ClassMembers /* = 129 */, + InterfaceMembers /* = 129 */, + EnumMembers /* = 145 */, + CaseBlockClauses /* = 129 */, + NamedImportsOrExportsElements /* = 525136 */, + JsxElementOrFragmentChildren /* = 262144 */, + JsxElementAttributes /* = 262656 */, + CaseOrDefaultClauseStatements /* = 163969 */, + HeritageClauseTypes /* = 528 */, + SourceFileStatements /* = 131073 */, + Decorators /* = 2146305 */, + TypeArguments /* = 53776 */, + TypeParameters /* = 53776 */, + Parameters /* = 2576 */, + IndexSignatureParameters /* = 8848 */, + JSDocComment /* = 33 */ +} + +external interface UserPreferences { + val disableSuggestions: Boolean? + get() = definedExternally + val quotePreference: String? /* "auto" | "double" | "single" */ + get() = definedExternally + val includeCompletionsForModuleExports: Boolean? + get() = definedExternally + val includeCompletionsForImportStatements: Boolean? + get() = definedExternally + val includeCompletionsWithSnippetText: Boolean? + get() = definedExternally + val includeAutomaticOptionalChainCompletions: Boolean? + get() = definedExternally + val includeCompletionsWithInsertText: Boolean? + get() = definedExternally + val importModuleSpecifierPreference: String? /* "shortest" | "project-relative" | "relative" | "non-relative" */ + get() = definedExternally + val importModuleSpecifierEnding: String? /* "auto" | "minimal" | "index" | "js" */ + get() = definedExternally + val allowTextChangesInNewFiles: Boolean? + get() = definedExternally + val providePrefixAndSuffixTextForRename: Boolean? + get() = definedExternally + val includePackageJsonAutoImports: String? /* "auto" | "on" | "off" */ + get() = definedExternally + val provideRefactorNotApplicableReason: Boolean? + get() = definedExternally +} + +external interface PseudoBigInt { + var negative: Boolean? + var base10Value: String +} + +external enum class FileWatcherEventKind { + Created /* = 0 */, + Changed /* = 1 */, + Deleted /* = 2 */ +} + +external interface System { + var args: Array + var newLine: String + var useCaseSensitiveFileNames: Boolean? + fun write(s: String) + val writeOutputIsTTY: (() -> Boolean)? + fun readFile(path: String, encoding: String = definedExternally): String? + val getFileSize: ((path: String) -> Number)? + fun writeFile(path: String, data: String, writeByteOrderMark: Boolean = definedExternally) + val watchFile: ((path: String, callback: FileWatcherCallback, pollingInterval: Number, options: WatchOptions) -> FileWatcher)? + val watchDirectory: ((path: String, callback: DirectoryWatcherCallback, recursive: Boolean, options: WatchOptions) -> FileWatcher)? + fun resolvePath(path: String): String + fun fileExists(path: String): Boolean + fun directoryExists(path: String): Boolean + fun createDirectory(path: String) + fun getExecutingFilePath(): String + fun getCurrentDirectory(): String + fun getDirectories(path: String): Array + fun readDirectory(path: String, extensions: Array = definedExternally, exclude: Array = definedExternally, include: Array = definedExternally, depth: Number = definedExternally): Array + val getModifiedTime: ((path: String) -> Date?)? + val setModifiedTime: ((path: String, time: Date) -> Unit)? + val deleteFile: ((path: String) -> Unit)? + val createHash: ((data: String) -> String)? + val createSHA256Hash: ((data: String) -> String)? + val getMemoryUsage: (() -> Number)? + fun exit(exitCode: Number = definedExternally) + val realpath: ((path: String) -> String)? + val setTimeout: ((callback: (args: Any) -> Unit, ms: Number, args: Any) -> Any)? + val clearTimeout: ((timeoutId: Any) -> Unit)? + val clearScreen: (() -> Unit)? + val base64decode: ((input: String) -> String)? + val base64encode: ((input: String) -> String)? +} + +external interface FileWatcher { + fun close() +} + +external fun getNodeMajorVersion(): Number? + +external var sys: System + +external interface Scanner { + fun getStartPos(): Number + fun getToken(): SyntaxKind + fun getTextPos(): Number + fun getTokenPos(): Number + fun getTokenText(): String + fun getTokenValue(): String + fun hasUnicodeEscape(): Boolean + fun hasExtendedUnicodeEscape(): Boolean + fun hasPrecedingLineBreak(): Boolean + fun isIdentifier(): Boolean + fun isReservedWord(): Boolean + fun isUnterminated(): Boolean + fun reScanGreaterToken(): SyntaxKind + fun reScanSlashToken(): SyntaxKind + fun reScanAsteriskEqualsToken(): SyntaxKind + fun reScanTemplateToken(isTaggedTemplate: Boolean): SyntaxKind + fun reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind + fun scanJsxIdentifier(): SyntaxKind + fun scanJsxAttributeValue(): SyntaxKind + fun reScanJsxAttributeValue(): SyntaxKind + fun reScanJsxToken(allowMultilineJsxText: Boolean = definedExternally): dynamic /* SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken */ + fun reScanLessThanToken(): SyntaxKind + fun reScanQuestionToken(): SyntaxKind + fun reScanInvalidIdentifier(): SyntaxKind + fun scanJsxToken(): dynamic /* SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken */ + fun scanJsDocToken(): dynamic /* SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.Unknown | SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IntrinsicKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.OverrideKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword */ + fun scan(): SyntaxKind + fun getText(): String + fun setText(text: String?, start: Number = definedExternally, length: Number = definedExternally) + fun setOnError(onError: ErrorCallback?) + fun setScriptTarget(scriptTarget: ScriptTarget) + fun setLanguageVariant(variant: LanguageVariant) + fun setTextPos(textPos: Number) + fun lookAhead(callback: () -> T): T + fun scanRange(start: Number, length: Number, callback: () -> T): T + fun tryScan(callback: () -> T): T +} + +external fun tokenToString(t: SyntaxKind): String? + +external fun getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: Number, character: Number): Number + +external fun getLineAndCharacterOfPosition(sourceFile: SourceFileLike, position: Number): LineAndCharacter + +external fun isWhiteSpaceLike(ch: Number): Boolean + +external fun isWhiteSpaceSingleLine(ch: Number): Boolean + +external fun isLineBreak(ch: Number): Boolean + +external fun couldStartTrivia(text: String, pos: Number): Boolean + +external fun forEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean) -> U): U? + +external fun forEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T) -> U, state: T): U? + +external fun forEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean) -> U): U? + +external fun forEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T) -> U, state: T): U? + +external fun reduceEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T, memo: U) -> U, state: T, initial: U): U? + +external fun reduceEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T, memo: U) -> U, state: T, initial: U): U? + +external fun getLeadingCommentRanges(text: String, pos: Number): Array? + +external fun getTrailingCommentRanges(text: String, pos: Number): Array? + +external fun getShebang(text: String): String? + +external fun isIdentifierStart(ch: Number, languageVersion: ScriptTarget?): Boolean + +external fun isIdentifierPart(ch: Number, languageVersion: ScriptTarget?, identifierVariant: LanguageVariant = definedExternally): Boolean + +external fun createScanner(languageVersion: ScriptTarget, skipTrivia: Boolean, languageVariant: LanguageVariant = definedExternally, textInitial: String = definedExternally, onError: ErrorCallback = definedExternally, start: Number = definedExternally, length: Number = definedExternally): Scanner + +external fun isExternalModuleNameRelative(moduleName: String): Boolean + +external fun sortAndDeduplicateDiagnostics(diagnostics: Array): SortedReadonlyArray + +external fun getDefaultLibFileName(options: CompilerOptions): String + +external fun textSpanEnd(span: TextSpan): Number + +external fun textSpanIsEmpty(span: TextSpan): Boolean + +external fun textSpanContainsPosition(span: TextSpan, position: Number): Boolean + +external fun textSpanContainsTextSpan(span: TextSpan, other: TextSpan): Boolean + +external fun textSpanOverlapsWith(span: TextSpan, other: TextSpan): Boolean + +external fun textSpanOverlap(span1: TextSpan, span2: TextSpan): TextSpan? + +external fun textSpanIntersectsWithTextSpan(span: TextSpan, other: TextSpan): Boolean + +external fun textSpanIntersectsWith(span: TextSpan, start: Number, length: Number): Boolean + +external fun decodedTextSpanIntersectsWith(start1: Number, length1: Number, start2: Number, length2: Number): Boolean + +external fun textSpanIntersectsWithPosition(span: TextSpan, position: Number): Boolean + +external fun textSpanIntersection(span1: TextSpan, span2: TextSpan): TextSpan? + +external fun createTextSpan(start: Number, length: Number): TextSpan + +external fun createTextSpanFromBounds(start: Number, end: Number): TextSpan + +external fun textChangeRangeNewSpan(range: TextChangeRange): TextSpan + +external fun textChangeRangeIsUnchanged(range: TextChangeRange): Boolean + +external fun createTextChangeRange(span: TextSpan, newLength: Number): TextChangeRange + +external var unchangedTextChangeRange: TextChangeRange + +external fun collapseTextChangeRangesAcrossMultipleVersions(changes: Array): TextChangeRange + +external fun getTypeParameterOwner(d: Declaration): Declaration? + +external interface `T$9` { + var parent: ConstructorDeclaration + var name: Identifier +} + +external fun isParameterPropertyDeclaration(node: Node, parent: Node): Boolean + +external fun isEmptyBindingPattern(node: Identifier): Boolean + +external fun isEmptyBindingPattern(node: ObjectBindingPattern): Boolean + +external fun isEmptyBindingPattern(node: ArrayBindingPattern): Boolean + +external fun isEmptyBindingElement(node: BindingElement): Boolean + +external fun walkUpBindingElementsAndPatterns(binding: BindingElement): dynamic /* VariableDeclaration | ParameterDeclaration */ + +external fun getCombinedModifierFlags(node: Declaration): ModifierFlags + +external fun getCombinedNodeFlags(node: Node): NodeFlags + +external interface `T$10` { + fun getExecutingFilePath(): String + fun resolvePath(path: String): String + fun fileExists(fileName: String): Boolean + fun readFile(fileName: String): String? +} + +external fun validateLocaleAndSetLanguage(locale: String, sys: `T$10`, errors: Push = definedExternally) + +external fun getOriginalNode(node: Node): Node + +external fun getOriginalNode(node: Node, nodeTest: (node: Node) -> Boolean): T + +external fun getOriginalNode(node: Node?): Node? + +external fun getOriginalNode(node: Node?, nodeTest: (node: Node?) -> Boolean): T? + +external fun findAncestor(node: Node?, callback: (element: Node) -> Boolean): T? + +external fun findAncestor(node: Node?, callback: (element: Node) -> Any): Node? + +external fun isParseTreeNode(node: Node): Boolean + +external fun getParseTreeNode(node: Node?): Node? + +external fun getParseTreeNode(node: T?, nodeTest: (node: Node) -> Boolean = definedExternally): T? + +external fun getParseTreeNode(node: T?): T? + +external fun escapeLeadingUnderscores(identifier: String): dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + +external fun unescapeLeadingUnderscores(identifier: String /* String & `T$8` */): String + +external fun unescapeLeadingUnderscores(identifier: Unit /* Unit & `T$8` */): String + +external fun unescapeLeadingUnderscores(identifier: InternalSymbolName): String + +external fun idText(identifierOrPrivateName: Identifier): String + +external fun idText(identifierOrPrivateName: PrivateIdentifier): String + +external fun symbolName(symbol: Symbol): String + +external fun getNameOfJSDocTypedef(declaration: JSDocTypedefTag): dynamic /* Identifier? | PrivateIdentifier? */ + +external fun getNameOfDeclaration(declaration: Declaration?): dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ + +external fun getNameOfDeclaration(declaration: Expression?): dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ + +external fun getJSDocParameterTags(param: ParameterDeclaration): Array + +external fun getJSDocTypeParameterTags(param: TypeParameterDeclaration): Array + +external fun hasJSDocParameterTags(node: FunctionDeclaration): Boolean + +external fun hasJSDocParameterTags(node: MethodDeclaration): Boolean + +external fun hasJSDocParameterTags(node: GetAccessorDeclaration): Boolean + +external fun hasJSDocParameterTags(node: SetAccessorDeclaration): Boolean + +external fun hasJSDocParameterTags(node: ConstructorDeclaration): Boolean + +external fun hasJSDocParameterTags(node: FunctionExpression): Boolean + +external fun hasJSDocParameterTags(node: ArrowFunction): Boolean + +external fun hasJSDocParameterTags(node: CallSignatureDeclaration): Boolean + +external fun hasJSDocParameterTags(node: ConstructSignatureDeclaration): Boolean + +external fun hasJSDocParameterTags(node: MethodSignature): Boolean + +external fun hasJSDocParameterTags(node: IndexSignatureDeclaration): Boolean + +external fun hasJSDocParameterTags(node: FunctionTypeNode): Boolean + +external fun hasJSDocParameterTags(node: ConstructorTypeNode): Boolean + +external fun hasJSDocParameterTags(node: JSDocFunctionType): Boolean + +external fun getJSDocAugmentsTag(node: Node): JSDocAugmentsTag? + +external fun getJSDocImplementsTags(node: Node): Array + +external fun getJSDocClassTag(node: Node): JSDocClassTag? + +external fun getJSDocPublicTag(node: Node): JSDocPublicTag? + +external fun getJSDocPrivateTag(node: Node): JSDocPrivateTag? + +external fun getJSDocProtectedTag(node: Node): JSDocProtectedTag? + +external fun getJSDocReadonlyTag(node: Node): JSDocReadonlyTag? + +external fun getJSDocOverrideTagNoCache(node: Node): JSDocOverrideTag? + +external fun getJSDocDeprecatedTag(node: Node): JSDocDeprecatedTag? + +external fun getJSDocEnumTag(node: Node): JSDocEnumTag? + +external fun getJSDocThisTag(node: Node): JSDocThisTag? + +external fun getJSDocReturnTag(node: Node): JSDocReturnTag? + +external fun getJSDocTemplateTag(node: Node): JSDocTemplateTag? + +external fun getJSDocTypeTag(node: Node): JSDocTypeTag? + +external fun getJSDocType(node: Node): TypeNode? + +external fun getJSDocReturnType(node: Node): TypeNode? + +external fun getJSDocTags(node: Node): Array + +external fun getAllJSDocTags(node: Node, predicate: (tag: JSDocTag) -> Boolean): Array + +external fun getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): Array + +external fun getTextOfJSDocComment(comment: String = definedExternally): String? + +external fun getTextOfJSDocComment(): String? + +external fun getTextOfJSDocComment(comment: NodeArray = definedExternally): String? + +external fun getEffectiveTypeParameterDeclarations(node: Any /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature */): Array + +external fun getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode? + +external fun isMemberName(node: Node): Boolean + +external fun isPropertyAccessChain(node: Node): Boolean + +external fun isElementAccessChain(node: Node): Boolean + +external fun isCallChain(node: Node): Boolean + +external fun isOptionalChain(node: Node): Boolean + +external fun isNullishCoalesce(node: Node): Boolean + +external fun isConstTypeReference(node: Node): Boolean + +external fun skipPartiallyEmittedExpressions(node: Expression): Expression + +external fun skipPartiallyEmittedExpressions(node: Node): Node + +external fun isNonNullChain(node: Node): Boolean + +external fun isBreakOrContinueStatement(node: Node): Boolean + +external fun isNamedExportBindings(node: Node): Boolean + +external fun isUnparsedTextLike(node: Node): Boolean + +external fun isUnparsedNode(node: Node): Boolean + +external fun isJSDocPropertyLikeTag(node: Node): Boolean + +external fun isTokenKind(kind: SyntaxKind): Boolean + +external fun isToken(n: Node): Boolean + +external fun isLiteralExpression(node: Node): Boolean + +external fun isTemplateLiteralToken(node: Node): Boolean + +external fun isTemplateMiddleOrTemplateTail(node: Node): Boolean + +external fun isImportOrExportSpecifier(node: Node): Boolean + +external fun isTypeOnlyImportOrExportDeclaration(node: Node): Boolean + +external fun isStringTextContainingNode(node: Node): Boolean + +external fun isModifier(node: Node): Boolean + +external fun isEntityName(node: Node): Boolean + +external fun isPropertyName(node: Node): Boolean + +external fun isBindingName(node: Node): Boolean + +external fun isFunctionLike(node: Node?): Boolean + +external fun isClassElement(node: Node): Boolean + +external fun isClassLike(node: Node): Boolean + +external fun isAccessor(node: Node): Boolean + +external fun isTypeElement(node: Node): Boolean + +external fun isClassOrTypeElement(node: Node): Boolean + +external fun isObjectLiteralElementLike(node: Node): Boolean + +external fun isTypeNode(node: Node): Boolean + +external fun isFunctionOrConstructorTypeNode(node: Node): Boolean + +external fun isPropertyAccessOrQualifiedName(node: Node): Boolean + +external fun isCallLikeExpression(node: Node): Boolean + +external fun isCallOrNewExpression(node: Node): Boolean + +external fun isTemplateLiteral(node: Node): Boolean + +external fun isAssertionExpression(node: Node): Boolean + +external fun isIterationStatement(node: Node, lookInLabeledStatements: Boolean): Boolean + +external fun isJsxOpeningLikeElement(node: Node): Boolean + +external fun isCaseOrDefaultClause(node: Node): Boolean + +external fun isJSDocCommentContainingNode(node: Node): Boolean + +external fun isSetAccessor(node: Node): Boolean + +external fun isGetAccessor(node: Node): Boolean + +external fun hasOnlyExpressionInitializer(node: Node): Boolean + +external fun isObjectLiteralElement(node: Node): Boolean + +external fun isStringLiteralLike(node: Node): Boolean + +external var factory: NodeFactory + +external fun createUnparsedSourceFile(text: String): UnparsedSource + +external fun createUnparsedSourceFile(inputFile: InputFiles, type: String /* "js" | "dts" */, stripInternal: Boolean = definedExternally): UnparsedSource + +external fun createUnparsedSourceFile(inputFile: InputFiles, type: String /* "js" | "dts" */): UnparsedSource + +external fun createUnparsedSourceFile(text: String, mapPath: String?, map: String?): UnparsedSource + +external fun createInputFiles(javascriptText: String, declarationText: String): InputFiles + +external fun createInputFiles(readFileText: (path: String) -> String?, javascriptPath: String, javascriptMapPath: String?, declarationPath: String, declarationMapPath: String?, buildInfoPath: String?): InputFiles + +external fun createInputFiles(javascriptText: String, declarationText: String, javascriptMapPath: String?, javascriptMapText: String?, declarationMapPath: String?, declarationMapText: String?): InputFiles + +external fun createSourceMapSource(fileName: String, text: String, skipTrivia: (pos: Number) -> Number = definedExternally): SourceMapSource + +external fun setOriginalNode(node: T, original: Node?): T + +external fun disposeEmitNodes(sourceFile: SourceFile?) + +external fun setEmitFlags(node: T, emitFlags: EmitFlags): T + +external fun getSourceMapRange(node: Node): SourceMapRange + +external fun setSourceMapRange(node: T, range: SourceMapRange?): T + +external fun getTokenSourceMapRange(node: Node, token: SyntaxKind): SourceMapRange? + +external fun setTokenSourceMapRange(node: T, token: SyntaxKind, range: SourceMapRange?): T + +external fun getCommentRange(node: Node): TextRange + +external fun setCommentRange(node: T, range: TextRange): T + +external fun getSyntheticLeadingComments(node: Node): Array? + +external fun setSyntheticLeadingComments(node: T, comments: Array?): T + +external fun getSyntheticTrailingComments(node: Node): Array? + +external fun setSyntheticTrailingComments(node: T, comments: Array?): T + +external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind = definedExternally, text: String, hasTrailingNewLine: Boolean = definedExternally): T + +external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind = definedExternally, text: String): T + +external fun moveSyntheticComments(node: T, original: Node): T + +external fun getConstantValue(node: PropertyAccessExpression): dynamic /* String? | Number? */ + +external fun getConstantValue(node: ElementAccessExpression): dynamic /* String? | Number? */ + +external fun setConstantValue(node: PropertyAccessExpression, value: String): dynamic /* PropertyAccessExpression | ElementAccessExpression */ + +external fun setConstantValue(node: PropertyAccessExpression, value: Number): dynamic /* PropertyAccessExpression | ElementAccessExpression */ + +external fun setConstantValue(node: ElementAccessExpression, value: String): dynamic /* PropertyAccessExpression | ElementAccessExpression */ + +external fun setConstantValue(node: ElementAccessExpression, value: Number): dynamic /* PropertyAccessExpression | ElementAccessExpression */ + +external fun addEmitHelper(node: T, helper: ScopedEmitHelper): T + +external fun addEmitHelper(node: T, helper: UnscopedEmitHelper): T + +external fun addEmitHelpers(node: T, helpers: Array?): T + +external fun removeEmitHelper(node: Node, helper: ScopedEmitHelper): Boolean + +external fun removeEmitHelper(node: Node, helper: UnscopedEmitHelper): Boolean + +external fun getEmitHelpers(node: Node): Array? + +external fun moveEmitHelpers(source: Node, target: Node, predicate: (helper: Any /* ScopedEmitHelper | UnscopedEmitHelper */) -> Boolean) + +external fun isNumericLiteral(node: Node): Boolean + +external fun isBigIntLiteral(node: Node): Boolean + +external fun isStringLiteral(node: Node): Boolean + +external fun isJsxText(node: Node): Boolean + +external fun isRegularExpressionLiteral(node: Node): Boolean + +external fun isNoSubstitutionTemplateLiteral(node: Node): Boolean + +external fun isTemplateHead(node: Node): Boolean + +external fun isTemplateMiddle(node: Node): Boolean + +external fun isTemplateTail(node: Node): Boolean + +external fun isDotDotDotToken(node: Node): Boolean + +external fun isPlusToken(node: Node): Boolean + +external fun isMinusToken(node: Node): Boolean + +external fun isAsteriskToken(node: Node): Boolean + +external fun isIdentifier(node: Node): Boolean + +external fun isPrivateIdentifier(node: Node): Boolean + +external fun isQualifiedName(node: Node): Boolean + +external fun isComputedPropertyName(node: Node): Boolean + +external fun isTypeParameterDeclaration(node: Node): Boolean + +external fun isParameter(node: Node): Boolean + +external fun isDecorator(node: Node): Boolean + +external fun isPropertySignature(node: Node): Boolean + +external fun isPropertyDeclaration(node: Node): Boolean + +external fun isMethodSignature(node: Node): Boolean + +external fun isMethodDeclaration(node: Node): Boolean + +external fun isConstructorDeclaration(node: Node): Boolean + +external fun isGetAccessorDeclaration(node: Node): Boolean + +external fun isSetAccessorDeclaration(node: Node): Boolean + +external fun isCallSignatureDeclaration(node: Node): Boolean + +external fun isConstructSignatureDeclaration(node: Node): Boolean + +external fun isIndexSignatureDeclaration(node: Node): Boolean + +external fun isTypePredicateNode(node: Node): Boolean + +external fun isTypeReferenceNode(node: Node): Boolean + +external fun isFunctionTypeNode(node: Node): Boolean + +external fun isConstructorTypeNode(node: Node): Boolean + +external fun isTypeQueryNode(node: Node): Boolean + +external fun isTypeLiteralNode(node: Node): Boolean + +external fun isArrayTypeNode(node: Node): Boolean + +external fun isTupleTypeNode(node: Node): Boolean + +external fun isNamedTupleMember(node: Node): Boolean + +external fun isOptionalTypeNode(node: Node): Boolean + +external fun isRestTypeNode(node: Node): Boolean + +external fun isUnionTypeNode(node: Node): Boolean + +external fun isIntersectionTypeNode(node: Node): Boolean + +external fun isConditionalTypeNode(node: Node): Boolean + +external fun isInferTypeNode(node: Node): Boolean + +external fun isParenthesizedTypeNode(node: Node): Boolean + +external fun isThisTypeNode(node: Node): Boolean + +external fun isTypeOperatorNode(node: Node): Boolean + +external fun isIndexedAccessTypeNode(node: Node): Boolean + +external fun isMappedTypeNode(node: Node): Boolean + +external fun isLiteralTypeNode(node: Node): Boolean + +external fun isImportTypeNode(node: Node): Boolean + +external fun isTemplateLiteralTypeSpan(node: Node): Boolean + +external fun isTemplateLiteralTypeNode(node: Node): Boolean + +external fun isObjectBindingPattern(node: Node): Boolean + +external fun isArrayBindingPattern(node: Node): Boolean + +external fun isBindingElement(node: Node): Boolean + +external fun isArrayLiteralExpression(node: Node): Boolean + +external fun isObjectLiteralExpression(node: Node): Boolean + +external fun isPropertyAccessExpression(node: Node): Boolean + +external fun isElementAccessExpression(node: Node): Boolean + +external fun isCallExpression(node: Node): Boolean + +external fun isNewExpression(node: Node): Boolean + +external fun isTaggedTemplateExpression(node: Node): Boolean + +external fun isTypeAssertionExpression(node: Node): Boolean + +external fun isParenthesizedExpression(node: Node): Boolean + +external fun isFunctionExpression(node: Node): Boolean + +external fun isArrowFunction(node: Node): Boolean + +external fun isDeleteExpression(node: Node): Boolean + +external fun isTypeOfExpression(node: Node): Boolean + +external fun isVoidExpression(node: Node): Boolean + +external fun isAwaitExpression(node: Node): Boolean + +external fun isPrefixUnaryExpression(node: Node): Boolean + +external fun isPostfixUnaryExpression(node: Node): Boolean + +external fun isBinaryExpression(node: Node): Boolean + +external fun isConditionalExpression(node: Node): Boolean + +external fun isTemplateExpression(node: Node): Boolean + +external fun isYieldExpression(node: Node): Boolean + +external fun isSpreadElement(node: Node): Boolean + +external fun isClassExpression(node: Node): Boolean + +external fun isOmittedExpression(node: Node): Boolean + +external fun isExpressionWithTypeArguments(node: Node): Boolean + +external fun isAsExpression(node: Node): Boolean + +external fun isNonNullExpression(node: Node): Boolean + +external fun isMetaProperty(node: Node): Boolean + +external fun isSyntheticExpression(node: Node): Boolean + +external fun isPartiallyEmittedExpression(node: Node): Boolean + +external fun isCommaListExpression(node: Node): Boolean + +external fun isTemplateSpan(node: Node): Boolean + +external fun isSemicolonClassElement(node: Node): Boolean + +external fun isBlock(node: Node): Boolean + +external fun isVariableStatement(node: Node): Boolean + +external fun isEmptyStatement(node: Node): Boolean + +external fun isExpressionStatement(node: Node): Boolean + +external fun isIfStatement(node: Node): Boolean + +external fun isDoStatement(node: Node): Boolean + +external fun isWhileStatement(node: Node): Boolean + +external fun isForStatement(node: Node): Boolean + +external fun isForInStatement(node: Node): Boolean + +external fun isForOfStatement(node: Node): Boolean + +external fun isContinueStatement(node: Node): Boolean + +external fun isBreakStatement(node: Node): Boolean + +external fun isReturnStatement(node: Node): Boolean + +external fun isWithStatement(node: Node): Boolean + +external fun isSwitchStatement(node: Node): Boolean + +external fun isLabeledStatement(node: Node): Boolean + +external fun isThrowStatement(node: Node): Boolean + +external fun isTryStatement(node: Node): Boolean + +external fun isDebuggerStatement(node: Node): Boolean + +external fun isVariableDeclaration(node: Node): Boolean + +external fun isVariableDeclarationList(node: Node): Boolean + +external fun isFunctionDeclaration(node: Node): Boolean + +external fun isClassDeclaration(node: Node): Boolean + +external fun isInterfaceDeclaration(node: Node): Boolean + +external fun isTypeAliasDeclaration(node: Node): Boolean + +external fun isEnumDeclaration(node: Node): Boolean + +external fun isModuleDeclaration(node: Node): Boolean + +external fun isModuleBlock(node: Node): Boolean + +external fun isCaseBlock(node: Node): Boolean + +external fun isNamespaceExportDeclaration(node: Node): Boolean + +external fun isImportEqualsDeclaration(node: Node): Boolean + +external fun isImportDeclaration(node: Node): Boolean + +external fun isImportClause(node: Node): Boolean + +external fun isNamespaceImport(node: Node): Boolean + +external fun isNamespaceExport(node: Node): Boolean + +external fun isNamedImports(node: Node): Boolean + +external fun isImportSpecifier(node: Node): Boolean + +external fun isExportAssignment(node: Node): Boolean + +external fun isExportDeclaration(node: Node): Boolean + +external fun isNamedExports(node: Node): Boolean + +external fun isExportSpecifier(node: Node): Boolean + +external fun isMissingDeclaration(node: Node): Boolean + +external fun isNotEmittedStatement(node: Node): Boolean + +external fun isExternalModuleReference(node: Node): Boolean + +external fun isJsxElement(node: Node): Boolean + +external fun isJsxSelfClosingElement(node: Node): Boolean + +external fun isJsxOpeningElement(node: Node): Boolean + +external fun isJsxClosingElement(node: Node): Boolean + +external fun isJsxFragment(node: Node): Boolean + +external fun isJsxOpeningFragment(node: Node): Boolean + +external fun isJsxClosingFragment(node: Node): Boolean + +external fun isJsxAttribute(node: Node): Boolean + +external fun isJsxAttributes(node: Node): Boolean + +external fun isJsxSpreadAttribute(node: Node): Boolean + +external fun isJsxExpression(node: Node): Boolean + +external fun isCaseClause(node: Node): Boolean + +external fun isDefaultClause(node: Node): Boolean + +external fun isHeritageClause(node: Node): Boolean + +external fun isCatchClause(node: Node): Boolean + +external fun isPropertyAssignment(node: Node): Boolean + +external fun isShorthandPropertyAssignment(node: Node): Boolean + +external fun isSpreadAssignment(node: Node): Boolean + +external fun isEnumMember(node: Node): Boolean + +external fun isUnparsedPrepend(node: Node): Boolean + +external fun isSourceFile(node: Node): Boolean + +external fun isBundle(node: Node): Boolean + +external fun isUnparsedSource(node: Node): Boolean + +external fun isJSDocTypeExpression(node: Node): Boolean + +external fun isJSDocNameReference(node: Node): Boolean + +external fun isJSDocLink(node: Node): Boolean + +external fun isJSDocAllType(node: Node): Boolean + +external fun isJSDocUnknownType(node: Node): Boolean + +external fun isJSDocNullableType(node: Node): Boolean + +external fun isJSDocNonNullableType(node: Node): Boolean + +external fun isJSDocOptionalType(node: Node): Boolean + +external fun isJSDocFunctionType(node: Node): Boolean + +external fun isJSDocVariadicType(node: Node): Boolean + +external fun isJSDocNamepathType(node: Node): Boolean + +external fun isJSDoc(node: Node): Boolean + +external fun isJSDocTypeLiteral(node: Node): Boolean + +external fun isJSDocSignature(node: Node): Boolean + +external fun isJSDocAugmentsTag(node: Node): Boolean + +external fun isJSDocAuthorTag(node: Node): Boolean + +external fun isJSDocClassTag(node: Node): Boolean + +external fun isJSDocCallbackTag(node: Node): Boolean + +external fun isJSDocPublicTag(node: Node): Boolean + +external fun isJSDocPrivateTag(node: Node): Boolean + +external fun isJSDocProtectedTag(node: Node): Boolean + +external fun isJSDocReadonlyTag(node: Node): Boolean + +external fun isJSDocOverrideTag(node: Node): Boolean + +external fun isJSDocDeprecatedTag(node: Node): Boolean + +external fun isJSDocSeeTag(node: Node): Boolean + +external fun isJSDocEnumTag(node: Node): Boolean + +external fun isJSDocParameterTag(node: Node): Boolean + +external fun isJSDocReturnTag(node: Node): Boolean + +external fun isJSDocThisTag(node: Node): Boolean + +external fun isJSDocTypeTag(node: Node): Boolean + +external fun isJSDocTemplateTag(node: Node): Boolean + +external fun isJSDocTypedefTag(node: Node): Boolean + +external fun isJSDocUnknownTag(node: Node): Boolean + +external fun isJSDocPropertyTag(node: Node): Boolean + +external fun isJSDocImplementsTag(node: Node): Boolean + +external fun setTextRange(range: T, location: TextRange?): T + +external fun forEachChild(node: Node, cbNode: (node: Node) -> T?, cbNodes: (nodes: NodeArray) -> T? = definedExternally): T? + +external fun createSourceFile(fileName: String, sourceText: String, languageVersion: ScriptTarget, setParentNodes: Boolean = definedExternally, scriptKind: ScriptKind = definedExternally): SourceFile + +external fun parseIsolatedEntityName(text: String, languageVersion: ScriptTarget): dynamic /* Identifier? | QualifiedName? */ + +external fun parseJsonText(fileName: String, sourceText: String): JsonSourceFile + +external fun isExternalModule(file: SourceFile): Boolean + +external fun updateSourceFile(sourceFile: SourceFile, newText: String, textChangeRange: TextChangeRange, aggressiveChecks: Boolean = definedExternally): SourceFile + +external fun parseCommandLine(commandLine: Array, readFile: (path: String) -> String? = definedExternally): ParsedCommandLine + +external interface ConfigFileDiagnosticsReporter { + var onUnRecoverableConfigFileDiagnostic: DiagnosticReporter +} + +external interface ParseConfigFileHost : ParseConfigHost, ConfigFileDiagnosticsReporter { + fun getCurrentDirectory(): String +} + +external fun getParsedCommandLineOfConfigFile(configFileName: String, optionsToExtend: CompilerOptions?, host: ParseConfigFileHost, extendedConfigCache: Map = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): ParsedCommandLine? + +external interface `T$11` { + var config: Any? + get() = definedExternally + set(value) = definedExternally + var error: Diagnostic? + get() = definedExternally + set(value) = definedExternally +} + +external fun readConfigFile(fileName: String, readFile: (path: String) -> String?): `T$11` + +external fun parseConfigFileTextToJson(fileName: String, jsonText: String): `T$11` + +external fun readJsonConfigFile(fileName: String, readFile: (path: String) -> String?): TsConfigSourceFile + +external fun convertToObject(sourceFile: JsonSourceFile, errors: Push): Any + +external fun parseJsonConfigFileContent(json: Any, host: ParseConfigHost, basePath: String, existingOptions: CompilerOptions = definedExternally, configFileName: String = definedExternally, resolutionStack: Array = definedExternally, extraFileExtensions: Array = definedExternally, extendedConfigCache: Map = definedExternally, existingWatchOptions: WatchOptions = definedExternally): ParsedCommandLine + +external fun parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: String, existingOptions: CompilerOptions = definedExternally, configFileName: String = definedExternally, resolutionStack: Array = definedExternally, extraFileExtensions: Array = definedExternally, extendedConfigCache: Map = definedExternally, existingWatchOptions: WatchOptions = definedExternally): ParsedCommandLine + +external interface ParsedTsconfig { + var raw: Any + var options: CompilerOptions? + get() = definedExternally + set(value) = definedExternally + var watchOptions: WatchOptions? + get() = definedExternally + set(value) = definedExternally + var typeAcquisition: TypeAcquisition? + get() = definedExternally + set(value) = definedExternally + var extendedConfigPath: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface ExtendedConfigCacheEntry { + var extendedResult: TsConfigSourceFile + var extendedConfig: ParsedTsconfig? +} + +external interface `T$12` { + var options: CompilerOptions + var errors: Array +} + +external fun convertCompilerOptionsFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$12` + +external interface `T$13` { + var options: TypeAcquisition + var errors: Array +} + +external fun convertTypeAcquisitionFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$13` + +external fun getEffectiveTypeRoots(options: CompilerOptions, host: GetEffectiveTypeRootsHost): Array? + +external fun resolveTypeReferenceDirective(typeReferenceDirectiveName: String, containingFile: String?, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference: ResolvedProjectReference = definedExternally, cache: TypeReferenceDirectiveResolutionCache = definedExternally): ResolvedTypeReferenceDirectiveWithFailedLookupLocations + +external fun getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): Array + +external interface TypeReferenceDirectiveResolutionCache : PerDirectoryResolutionCache, PackageJsonInfoCache + +external interface PerDirectoryResolutionCache { + fun getOrCreateCacheForDirectory(directoryName: String, redirectedReference: ResolvedProjectReference = definedExternally): Map + fun clear() + fun update(options: CompilerOptions) +} + +external interface ModuleResolutionCache : PerDirectoryResolutionCache, NonRelativeModuleNameResolutionCache, PackageJsonInfoCache { + fun getPackageJsonInfoCache(): PackageJsonInfoCache +} + +external interface NonRelativeModuleNameResolutionCache : PackageJsonInfoCache { + fun getOrCreateCacheForModuleName(nonRelativeModuleName: String, redirectedReference: ResolvedProjectReference = definedExternally): PerModuleNameCache +} + +external interface PackageJsonInfoCache { + fun clear() +} + +external interface PerModuleNameCache { + fun get(directory: String): ResolvedModuleWithFailedLookupLocations? + fun set(directory: String, result: ResolvedModuleWithFailedLookupLocations) +} + +external fun createModuleResolutionCache(currentDirectory: String, getCanonicalFileName: (s: String) -> String, options: CompilerOptions = definedExternally): ModuleResolutionCache + +external fun createTypeReferenceDirectiveResolutionCache(currentDirectory: String, getCanonicalFileName: (s: String) -> String, options: CompilerOptions = definedExternally, packageJsonInfoCache: PackageJsonInfoCache = definedExternally): TypeReferenceDirectiveResolutionCache + +external fun resolveModuleNameFromCache(moduleName: String, containingFile: String, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations? + +external fun resolveModuleName(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations + +external fun nodeModuleNameResolver(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations + +external fun classicNameResolver(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: NonRelativeModuleNameResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations + +external fun visitNode(node: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T + +external fun visitNode(node: T, visitor: Visitor?): T + +external fun visitNode(node: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T + +external fun visitNode(node: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T? + +external fun visitNode(node: T?, visitor: Visitor?): T? + +external fun visitNode(node: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T? + +external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray + +external fun visitNodes(nodes: NodeArray, visitor: Visitor?): NodeArray + +external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray + +external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray + +external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray? + +external fun visitNodes(nodes: NodeArray?, visitor: Visitor?): NodeArray? + +external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray? + +external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray? + +external fun visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start: Number = definedExternally, ensureUseStrict: Boolean = definedExternally, nodesVisitor: NodesVisitor = definedExternally): NodeArray + +external fun visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor = definedExternally): NodeArray + +external fun visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext): NodeArray + +external fun visitParameterList(nodes: NodeArray?, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor = definedExternally): NodeArray? + +external fun visitParameterList(nodes: NodeArray?, visitor: Visitor, context: TransformationContext): NodeArray? + +external fun visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): dynamic /* FunctionBody */ + +external fun visitFunctionBody(node: Expression, visitor: Visitor, context: TransformationContext): dynamic /* FunctionBody | Expression */ + +external fun visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement + +external fun visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T + +external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext, nodesVisitor: Any = definedExternally, tokenVisitor: Visitor = definedExternally): T? + +external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext): T? + +external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext, nodesVisitor: Any = definedExternally): T? + +external fun getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): String? + +external fun getOutputFileNames(commandLine: ParsedCommandLine, inputFileName: String, ignoreCase: Boolean): Array + +external fun createPrinter(printerOptions: PrinterOptions = definedExternally, handlers: PrintHandlers = definedExternally): Printer + +external fun findConfigFile(searchPath: String, fileExists: (fileName: String) -> Boolean, configName: String = definedExternally): String? + +external fun resolveTripleslashReference(moduleName: String, containingFile: String): String + +external fun createCompilerHost(options: CompilerOptions, setParentNodes: Boolean = definedExternally): CompilerHost + +external fun getPreEmitDiagnostics(program: Program, sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + +external interface FormatDiagnosticsHost { + fun getCurrentDirectory(): String + fun getCanonicalFileName(fileName: String): String + fun getNewLine(): String +} + +external fun formatDiagnostics(diagnostics: Array, host: FormatDiagnosticsHost): String + +external fun formatDiagnostic(diagnostic: Diagnostic, host: FormatDiagnosticsHost): String + +external fun formatDiagnosticsWithColorAndContext(diagnostics: Array, host: FormatDiagnosticsHost): String + +external fun flattenDiagnosticMessageText(diag: String?, newLine: String, indent: Number = definedExternally): String + +external fun flattenDiagnosticMessageText(diag: String?, newLine: String): String + +external fun flattenDiagnosticMessageText(diag: DiagnosticMessageChain?, newLine: String, indent: Number = definedExternally): String + +external fun flattenDiagnosticMessageText(diag: DiagnosticMessageChain?, newLine: String): String + +external fun getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): Array + +external fun createProgram(createProgramOptions: CreateProgramOptions): Program + +external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally, oldProgram: Program = definedExternally, configFileParsingDiagnostics: Array = definedExternally): Program + +external fun createProgram(rootNames: Array, options: CompilerOptions): Program + +external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally): Program + +external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally, oldProgram: Program = definedExternally): Program + +external interface ResolveProjectReferencePathHost { + fun fileExists(fileName: String): Boolean +} + +external fun resolveProjectReferencePath(ref: ProjectReference): String /* String & `T$5` */ + +external fun resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): String /* String & `T$5` */ + +external interface EmitOutput { + var outputFiles: Array + var emitSkipped: Boolean? +} + +external interface OutputFile { + var name: String + var writeByteOrderMark: Boolean? + var text: String +} + +external interface `T$14` { + var result: T + var affected: dynamic /* SourceFile | Program */ + get() = definedExternally + set(value) = definedExternally +} + +external interface BuilderProgramHost { + fun useCaseSensitiveFileNames(): Boolean + var createHash: ((data: String) -> String)? + get() = definedExternally + set(value) = definedExternally + var writeFile: WriteFileCallback? + get() = definedExternally + set(value) = definedExternally +} + +external interface BuilderProgram { + fun getProgram(): Program + fun getCompilerOptions(): CompilerOptions + fun getSourceFile(fileName: String): SourceFile? + fun getSourceFiles(): Array + fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getConfigFileParsingDiagnostics(): Array + fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getDeclarationDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getAllDependencies(sourceFile: SourceFile): Array + fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult + fun getCurrentDirectory(): String +} + +external interface SemanticDiagnosticsBuilderProgram : BuilderProgram { + fun getSemanticDiagnosticsOfNextAffectedFile(cancellationToken: CancellationToken = definedExternally, ignoreSourceFile: (sourceFile: SourceFile) -> Boolean = definedExternally): `T$14`>? +} + +external interface EmitAndSemanticDiagnosticsBuilderProgram : SemanticDiagnosticsBuilderProgram { + fun emitNextAffectedFile(writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): `T$14`? +} + +external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): BuilderProgram + +external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost): BuilderProgram + +external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram: BuilderProgram = definedExternally): BuilderProgram + +external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): BuilderProgram + +external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?): BuilderProgram + +external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): BuilderProgram + +external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally): BuilderProgram + +external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): BuilderProgram + +external interface ReadBuildProgramHost { + fun useCaseSensitiveFileNames(): Boolean + fun getCurrentDirectory(): String + fun readFile(fileName: String): String? +} + +external fun readBuilderProgram(compilerOptions: CompilerOptions, host: ReadBuildProgramHost): EmitAndSemanticDiagnosticsBuilderProgram? + +external fun createIncrementalCompilerHost(options: CompilerOptions, system: System = definedExternally): CompilerHost + +external interface IncrementalProgramOptions { + var rootNames: Array + var options: CompilerOptions + var configFileParsingDiagnostics: Array? + get() = definedExternally + set(value) = definedExternally + var projectReferences: Array? + get() = definedExternally + set(value) = definedExternally + var host: CompilerHost? + get() = definedExternally + set(value) = definedExternally + var createProgram: CreateProgram? + get() = definedExternally + set(value) = definedExternally +} + +external fun createIncrementalProgram(__0: IncrementalProgramOptions): T + +external interface WatchHost { + val onWatchStatusChange: ((diagnostic: Diagnostic, newLine: String, options: CompilerOptions, errorCount: Number) -> Unit)? + fun watchFile(path: String, callback: FileWatcherCallback, pollingInterval: Number = definedExternally, options: CompilerOptions = definedExternally): FileWatcher + fun watchDirectory(path: String, callback: DirectoryWatcherCallback, recursive: Boolean = definedExternally, options: CompilerOptions = definedExternally): FileWatcher + val setTimeout: ((callback: (args: Any) -> Unit, ms: Number, args: Any) -> Any)? + val clearTimeout: ((timeoutId: Any) -> Unit)? +} + +external interface ProgramHost { + var createProgram: CreateProgram + fun useCaseSensitiveFileNames(): Boolean + fun getNewLine(): String + fun getCurrentDirectory(): String + fun getDefaultLibFileName(options: CompilerOptions): String + val getDefaultLibLocation: (() -> String)? + val createHash: ((data: String) -> String)? + fun fileExists(path: String): Boolean + fun readFile(path: String, encoding: String = definedExternally): String? + val directoryExists: ((path: String) -> Boolean)? + val getDirectories: ((path: String) -> Array)? + val readDirectory: ((path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array)? + val realpath: ((path: String) -> String)? + val trace: ((s: String) -> Unit)? + val getEnvironmentVariable: ((name: String) -> String?)? + val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? +} + +external interface WatchCompilerHost : ProgramHost, WatchHost { + val useSourceOfProjectReferenceRedirect: (() -> Boolean)? + val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? + val afterProgramCreate: ((program: T) -> Unit)? +} + +external interface WatchCompilerHostOfFilesAndCompilerOptions : WatchCompilerHost { + var rootFiles: Array + var options: CompilerOptions + var watchOptions: WatchOptions? + get() = definedExternally + set(value) = definedExternally + var projectReferences: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface WatchCompilerHostOfConfigFile : WatchCompilerHost, ConfigFileDiagnosticsReporter { + var configFileName: String + var optionsToExtend: CompilerOptions? + get() = definedExternally + set(value) = definedExternally + var watchOptionsToExtend: WatchOptions? + get() = definedExternally + set(value) = definedExternally + var extraFileExtensions: Array? + get() = definedExternally + set(value) = definedExternally + override var readDirectory: (path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array +} + +external interface Watch { + fun getProgram(): T + fun close() +} + +external interface WatchOfConfigFile : Watch + +external interface WatchOfFilesAndCompilerOptions : Watch { + fun updateRootFileNames(fileNames: Array) +} + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, projectReferences: Array = definedExternally, watchOptions: WatchOptions = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, projectReferences: Array = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchProgram(host: WatchCompilerHostOfFilesAndCompilerOptions): WatchOfFilesAndCompilerOptions + +external fun createWatchProgram(host: WatchCompilerHostOfConfigFile): WatchOfConfigFile + +external interface BuildOptions { + var dry: Boolean? + get() = definedExternally + set(value) = definedExternally + var force: Boolean? + get() = definedExternally + set(value) = definedExternally + var verbose: Boolean? + get() = definedExternally + set(value) = definedExternally + var incremental: Boolean? + get() = definedExternally + set(value) = definedExternally + var assumeChangesOnlyAffectDirectDependencies: Boolean? + get() = definedExternally + set(value) = definedExternally + var traceResolution: Boolean? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ + @nativeSetter + operator fun set(option: String, value: String?) + @nativeSetter + operator fun set(option: String, value: Number?) + @nativeSetter + operator fun set(option: String, value: Boolean?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: MapLike>?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) +} + +external interface SolutionBuilderHostBase : ProgramHost { + val createDirectory: ((path: String) -> Unit)? + val writeFile: ((path: String, data: String, writeByteOrderMark: Boolean) -> Unit)? + var getCustomTransformers: ((project: String) -> CustomTransformers?)? + get() = definedExternally + set(value) = definedExternally + + fun getModifiedTime(fileName: String): Date? + fun setModifiedTime(fileName: String, date: Date) + fun deleteFile(fileName: String) + val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? + var reportDiagnostic: DiagnosticReporter + var reportSolutionBuilderStatus: DiagnosticReporter + val afterProgramEmitAndDiagnostics: ((program: T) -> Unit)? +} + +external interface SolutionBuilderHost : SolutionBuilderHostBase { + var reportErrorSummary: ReportEmitErrorSummary? + get() = definedExternally + set(value) = definedExternally +} + +external interface SolutionBuilderWithWatchHost : SolutionBuilderHostBase, WatchHost + +external interface SolutionBuilder { + fun build(project: String = definedExternally, cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, getCustomTransformers: (project: String) -> CustomTransformers = definedExternally): ExitStatus + fun clean(project: String = definedExternally): ExitStatus + fun buildReferences(project: String, cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, getCustomTransformers: (project: String) -> CustomTransformers = definedExternally): ExitStatus + fun cleanReferences(project: String = definedExternally): ExitStatus + fun getNextInvalidatedProject(cancellationToken: CancellationToken = definedExternally): dynamic /* UpdateOutputFileStampsProject? | BuildInvalidedProject? | UpdateBundleProject? */ +} + +external fun createBuilderStatusReporter(system: System, pretty: Boolean = definedExternally): DiagnosticReporter + +external fun createSolutionBuilderHost(system: System = definedExternally, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportSolutionBuilderStatus: DiagnosticReporter = definedExternally, reportErrorSummary: ReportEmitErrorSummary = definedExternally): SolutionBuilderHost + +external fun createSolutionBuilderWithWatchHost(system: System = definedExternally, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportSolutionBuilderStatus: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): SolutionBuilderWithWatchHost + +external fun createSolutionBuilder(host: SolutionBuilderHost, rootNames: Array, defaultOptions: BuildOptions): SolutionBuilder + +external fun createSolutionBuilderWithWatch(host: SolutionBuilderWithWatchHost, rootNames: Array, defaultOptions: BuildOptions, baseWatchOptions: WatchOptions = definedExternally): SolutionBuilder + +external enum class InvalidatedProjectKind { + Build /* = 0 */, + UpdateBundle /* = 1 */, + UpdateOutputFileStamps /* = 2 */ +} + +external interface InvalidatedProjectBase { + val kind: InvalidatedProjectKind + val project: String /* String & `T$5` */ + fun done(cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, customTransformers: CustomTransformers = definedExternally): ExitStatus + fun getCompilerOptions(): CompilerOptions + fun getCurrentDirectory(): String +} + +external interface UpdateOutputFileStampsProject : InvalidatedProjectBase { + fun updateOutputFileStatmps() +} + +external interface BuildInvalidedProject : InvalidatedProjectBase { + fun getBuilderProgram(): T? + fun getProgram(): Program? + fun getSourceFile(fileName: String): SourceFile? + fun getSourceFiles(): Array + fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getConfigFileParsingDiagnostics(): Array + fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getAllDependencies(sourceFile: SourceFile): Array + fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getSemanticDiagnosticsOfNextAffectedFile(cancellationToken: CancellationToken = definedExternally, ignoreSourceFile: (sourceFile: SourceFile) -> Boolean = definedExternally): `T$14`>? + fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult? +} + +external interface UpdateBundleProject : InvalidatedProjectBase { + fun emit(writeFile: WriteFileCallback = definedExternally, customTransformers: CustomTransformers = definedExternally): dynamic /* EmitResult? | BuildInvalidedProject? */ +} + +external interface SourceFileLike { + fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter +} + +external interface IScriptSnapshot { + fun getText(start: Number, end: Number): String + fun getLength(): Number + fun getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange? + val dispose: (() -> Unit)? +} + +external interface PreProcessedFileInfo { + var referencedFiles: Array + var typeReferenceDirectives: Array + var libReferenceDirectives: Array + var importedFiles: Array + var ambientExternalModules: Array? + get() = definedExternally + set(value) = definedExternally + var isLibFile: Boolean? +} + +external interface HostCancellationToken { + fun isCancellationRequested(): Boolean +} + +external interface InstallPackageOptions { + var fileName: String /* String & `T$3` */ + var packageName: String +} + +external interface PerformanceEvent { + var kind: String /* "UpdateGraph" | "CreatePackageJsonAutoImportProvider" */ + var durationMs: Number +} + +external enum class LanguageServiceMode { + Semantic /* = 0 */, + PartialSemantic /* = 1 */, + Syntactic /* = 2 */ +} + +external interface LanguageServiceHost : GetEffectiveTypeRootsHost { + fun getCompilationSettings(): CompilerOptions + val getNewLine: (() -> String)? + val getProjectVersion: (() -> String)? + fun getScriptFileNames(): Array + val getScriptKind: ((fileName: String) -> ScriptKind)? + fun getScriptVersion(fileName: String): String + fun getScriptSnapshot(fileName: String): IScriptSnapshot? + val getProjectReferences: (() -> Array?)? + val getLocalizedDiagnosticMessages: (() -> Any)? + val getCancellationToken: (() -> HostCancellationToken)? + override var getCurrentDirectory: () -> String + fun getDefaultLibFileName(options: CompilerOptions): String + val log: ((s: String) -> Unit)? + val trace: ((s: String) -> Unit)? + val error: ((s: String) -> Unit)? + val useCaseSensitiveFileNames: (() -> Boolean)? + val readDirectory: ((path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array)? + val readFile: ((path: String, encoding: String) -> String?)? + val realpath: ((path: String) -> String)? + val fileExists: ((path: String) -> Boolean)? + val getTypeRootsVersion: (() -> Number)? + val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val getResolvedModuleWithFailedLookupLocationsFromCache: ((modulename: String, containingFile: String) -> ResolvedModuleWithFailedLookupLocations?)? + val resolveTypeReferenceDirectives: ((typeDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val getDirectories: ((directoryName: String) -> Array)? + val getCustomTransformers: (() -> CustomTransformers?)? + val isKnownTypesPackageName: ((name: String) -> Boolean)? + val installPackage: ((options: InstallPackageOptions) -> Promise)? + val writeFile: ((fileName: String, content: String) -> Unit)? + val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? +} + +external interface `T$15` { + var metadata: Any? + get() = definedExternally + set(value) = definedExternally +} + +external enum class SemanticClassificationFormat { + Original /* = "original" */, + TwentyTwenty /* = "2020" */ +} + +external interface LanguageService { + fun cleanupSemanticCache() + fun getSyntacticDiagnostics(fileName: String): Array + fun getSemanticDiagnostics(fileName: String): Array + fun getSuggestionDiagnostics(fileName: String): Array + fun getCompilerOptionsDiagnostics(): Array + fun getSyntacticClassifications(fileName: String, span: TextSpan): Array + fun getSyntacticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ + fun getSemanticClassifications(fileName: String, span: TextSpan): Array + fun getSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ + fun getEncodedSyntacticClassifications(fileName: String, span: TextSpan): Classifications + fun getEncodedSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat = definedExternally): Classifications + fun getCompletionsAtPosition(fileName: String, position: Number, options: GetCompletionsAtPositionOptions?): CompletionInfo /* CompletionInfo & `T$15` */ + fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeOptions?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? + fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeSettings?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? + fun getCompletionEntrySymbol(fileName: String, position: Number, name: String, source: String?): Symbol? + fun getQuickInfoAtPosition(fileName: String, position: Number): QuickInfo? + fun getNameOrDottedNameSpan(fileName: String, startPos: Number, endPos: Number): TextSpan? + fun getBreakpointStatementAtPosition(fileName: String, position: Number): TextSpan? + fun getSignatureHelpItems(fileName: String, position: Number, options: SignatureHelpItemsOptions?): SignatureHelpItems? + fun getRenameInfo(fileName: String, position: Number, options: RenameInfoOptions = definedExternally): dynamic /* RenameInfoSuccess | RenameInfoFailure */ + fun findRenameLocations(fileName: String, position: Number, findInStrings: Boolean, findInComments: Boolean, providePrefixAndSuffixTextForRename: Boolean = definedExternally): Array? + fun getSmartSelectionRange(fileName: String, position: Number): SelectionRange + fun getDefinitionAtPosition(fileName: String, position: Number): Array? + fun getDefinitionAndBoundSpan(fileName: String, position: Number): DefinitionInfoAndBoundSpan? + fun getTypeDefinitionAtPosition(fileName: String, position: Number): Array? + fun getImplementationAtPosition(fileName: String, position: Number): Array? + fun getReferencesAtPosition(fileName: String, position: Number): Array? + fun findReferences(fileName: String, position: Number): Array? + fun getDocumentHighlights(fileName: String, position: Number, filesToSearch: Array): Array? + fun getFileReferences(fileName: String): Array + fun getOccurrencesAtPosition(fileName: String, position: Number): Array? + fun getNavigateToItems(searchValue: String, maxResultCount: Number = definedExternally, fileName: String = definedExternally, excludeDtsFiles: Boolean = definedExternally): Array + fun getNavigationBarItems(fileName: String): Array + fun getNavigationTree(fileName: String): NavigationTree + fun prepareCallHierarchy(fileName: String, position: Number): dynamic /* CallHierarchyItem? | Array? */ + fun provideCallHierarchyIncomingCalls(fileName: String, position: Number): Array + fun provideCallHierarchyOutgoingCalls(fileName: String, position: Number): Array + fun getOutliningSpans(fileName: String): Array + fun getTodoComments(fileName: String, descriptors: Array): Array + fun getBraceMatchingAtPosition(fileName: String, position: Number): Array + fun getIndentationAtPosition(fileName: String, position: Number, options: EditorOptions): Number + fun getIndentationAtPosition(fileName: String, position: Number, options: EditorSettings): Number + fun getFormattingEditsForRange(fileName: String, start: Number, end: Number, options: FormatCodeOptions): Array + fun getFormattingEditsForRange(fileName: String, start: Number, end: Number, options: FormatCodeSettings): Array + fun getFormattingEditsForDocument(fileName: String, options: FormatCodeOptions): Array + fun getFormattingEditsForDocument(fileName: String, options: FormatCodeSettings): Array + fun getFormattingEditsAfterKeystroke(fileName: String, position: Number, key: String, options: FormatCodeOptions): Array + fun getFormattingEditsAfterKeystroke(fileName: String, position: Number, key: String, options: FormatCodeSettings): Array + fun getDocCommentTemplateAtPosition(fileName: String, position: Number, options: DocCommentTemplateOptions = definedExternally): TextInsertion? + fun isValidBraceCompletionAtPosition(fileName: String, position: Number, openingBrace: Number): Boolean + fun getJsxClosingTagAtPosition(fileName: String, position: Number): JsxClosingTagInfo? + fun getSpanOfEnclosingComment(fileName: String, position: Number, onlyMultiLine: Boolean): TextSpan? + val toLineColumnOffset: ((fileName: String, position: Number) -> LineAndCharacter)? + fun getCodeFixesAtPosition(fileName: String, start: Number, end: Number, errorCodes: Array, formatOptions: FormatCodeSettings, preferences: UserPreferences): Array + fun getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: Any, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions + fun applyCodeActionCommand(action: CodeActionCommand, formatSettings: FormatCodeSettings = definedExternally): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(action: CodeActionCommand): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(action: Array, formatSettings: FormatCodeSettings = definedExternally): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(action: Array): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(fileName: String, action: CodeActionCommand): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(fileName: String, action: Array): dynamic /* Promise | Promise */ + fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally, kind: String = definedExternally): Array + fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?): Array + fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally): Array + fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally, kind: String = definedExternally): Array + fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?): Array + fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally): Array + fun getEditsForRefactor(fileName: String, formatOptions: FormatCodeSettings, positionOrRange: Number, refactorName: String, actionName: String, preferences: UserPreferences?): RefactorEditInfo? + fun getEditsForRefactor(fileName: String, formatOptions: FormatCodeSettings, positionOrRange: TextRange, refactorName: String, actionName: String, preferences: UserPreferences?): RefactorEditInfo? + fun organizeImports(args: OrganizeImportsArgs, formatOptions: FormatCodeSettings, preferences: UserPreferences?): Array + fun getEditsForFileRename(oldFilePath: String, newFilePath: String, formatOptions: FormatCodeSettings, preferences: UserPreferences?): Array + fun getEmitOutput(fileName: String, emitOnlyDtsFiles: Boolean = definedExternally, forceDtsEmit: Boolean = definedExternally): EmitOutput + fun getProgram(): Program? + fun toggleLineComment(fileName: String, textRange: TextRange): Array + fun toggleMultilineComment(fileName: String, textRange: TextRange): Array + fun commentSelection(fileName: String, textRange: TextRange): Array + fun uncommentSelection(fileName: String, textRange: TextRange): Array + fun dispose() +} + +external interface JsxClosingTagInfo { + val newText: String +} + +external interface CombinedCodeFixScope { + var type: String /* "file" */ + var fileName: String +} + +external interface OrganizeImportsArgs : CombinedCodeFixScope { + var skipDestructiveCodeActions: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface GetCompletionsAtPositionOptions : UserPreferences { + var triggerCharacter: String? /* "." | """ | "'" | "`" | "/" | "@" | "<" | "#" | " " */ + get() = definedExternally + set(value) = definedExternally + var includeExternalModuleExports: Boolean? + get() = definedExternally + set(value) = definedExternally + var includeInsertTextCompletions: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureHelpItemsOptions { + var triggerReason: dynamic /* SignatureHelpInvokedReason? | SignatureHelpCharacterTypedReason? | SignatureHelpRetriggeredReason? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureHelpInvokedReason { + var kind: String /* "invoked" */ + var triggerCharacter: Any? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureHelpCharacterTypedReason { + var kind: String /* "characterTyped" */ + var triggerCharacter: String /* "," | "(" | "<" */ +} + +external interface SignatureHelpRetriggeredReason { + var kind: String /* "retrigger" */ + var triggerCharacter: String? /* "," | "(" | "<" | ")" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ApplyCodeActionCommandResult { + var successMessage: String +} + +external interface Classifications { + var spans: Array + var endOfLineState: EndOfLineState +} + +external interface ClassifiedSpan { + var textSpan: TextSpan + var classificationType: ClassificationTypeNames +} + +external interface ClassifiedSpan2020 { + var textSpan: TextSpan + var classificationType: Number +} + +external interface NavigationBarItem { + var text: String + var kind: ScriptElementKind + var kindModifiers: String + var spans: Array + var childItems: Array + var indent: Number + var bolded: Boolean? + var grayed: Boolean? +} + +external interface NavigationTree { + var text: String + var kind: ScriptElementKind + var kindModifiers: String + var spans: Array + var nameSpan: TextSpan? + var childItems: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface CallHierarchyItem { + var name: String + var kind: ScriptElementKind + var kindModifiers: String? + get() = definedExternally + set(value) = definedExternally + var file: String + var span: TextSpan + var selectionSpan: TextSpan + var containerName: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface CallHierarchyIncomingCall { + var from: CallHierarchyItem + var fromSpans: Array +} + +external interface CallHierarchyOutgoingCall { + var to: CallHierarchyItem + var fromSpans: Array +} + +external interface TodoCommentDescriptor { + var text: String + var priority: Number +} + +external interface TodoComment { + var descriptor: TodoCommentDescriptor + var message: String + var position: Number +} + +external interface TextChange { + var span: TextSpan + var newText: String +} + +external interface FileTextChanges { + var fileName: String + var textChanges: Array + var isNewFile: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface CodeAction { + var description: String + var changes: Array + var commands: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface CodeFixAction : CodeAction { + var fixName: String + var fixId: Any? + get() = definedExternally + set(value) = definedExternally + var fixAllDescription: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface CombinedCodeActions { + var changes: Array + var commands: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface InstallPackageAction + +external interface ApplicableRefactorInfo { + var name: String + var description: String + var inlineable: Boolean? + get() = definedExternally + set(value) = definedExternally + var actions: Array +} + +external interface RefactorActionInfo { + var name: String + var description: String + var notApplicableReason: String? + get() = definedExternally + set(value) = definedExternally + var kind: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface RefactorEditInfo { + var edits: Array + var renameFilename: String? + get() = definedExternally + set(value) = definedExternally + var renameLocation: Number? + get() = definedExternally + set(value) = definedExternally + var commands: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface TextInsertion { + var newText: String + var caretOffset: Number +} + +external interface DocumentSpan { + var textSpan: TextSpan + var fileName: String + var originalTextSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var originalFileName: String? + get() = definedExternally + set(value) = definedExternally + var contextSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var originalContextSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally +} + +external interface RenameLocation : DocumentSpan { + val prefixText: String? + get() = definedExternally + val suffixText: String? + get() = definedExternally +} + +external interface ReferenceEntry : DocumentSpan { + var isWriteAccess: Boolean? + var isDefinition: Boolean? + var isInString: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ImplementationLocation : DocumentSpan { + var kind: ScriptElementKind + var displayParts: Array +} + +external enum class HighlightSpanKind { + none /* = "none" */, + definition /* = "definition" */, + reference /* = "reference" */, + writtenReference /* = "writtenReference" */ +} + +external interface HighlightSpan { + var fileName: String? + get() = definedExternally + set(value) = definedExternally + var isInString: Boolean? + get() = definedExternally + set(value) = definedExternally + var textSpan: TextSpan + var contextSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var kind: HighlightSpanKind +} + +external interface NavigateToItem { + var name: String + var kind: ScriptElementKind + var kindModifiers: String + var matchKind: String /* "exact" | "prefix" | "substring" | "camelCase" */ + var isCaseSensitive: Boolean? + var fileName: String + var textSpan: TextSpan + var containerName: String + var containerKind: ScriptElementKind +} + +external enum class IndentStyle { + None /* = 0 */, + Block /* = 1 */, + Smart /* = 2 */ +} + +external enum class SemicolonPreference { + Ignore /* = "ignore" */, + Insert /* = "insert" */, + Remove /* = "remove" */ +} + +external interface EditorOptions { + var BaseIndentSize: Number? + get() = definedExternally + set(value) = definedExternally + var IndentSize: Number + var TabSize: Number + var NewLineCharacter: String + var ConvertTabsToSpaces: Boolean? + var IndentStyle: IndentStyle +} + +external interface EditorSettings { + var baseIndentSize: Number? + get() = definedExternally + set(value) = definedExternally + var indentSize: Number? + get() = definedExternally + set(value) = definedExternally + var tabSize: Number? + get() = definedExternally + set(value) = definedExternally + var newLineCharacter: String? + get() = definedExternally + set(value) = definedExternally + var convertTabsToSpaces: Boolean? + get() = definedExternally + set(value) = definedExternally + var indentStyle: IndentStyle? + get() = definedExternally + set(value) = definedExternally + var trimTrailingWhitespace: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface FormatCodeOptions : EditorOptions { + var InsertSpaceAfterCommaDelimiter: Boolean? + var InsertSpaceAfterSemicolonInForStatements: Boolean? + var InsertSpaceBeforeAndAfterBinaryOperators: Boolean? + var InsertSpaceAfterConstructor: Boolean? + get() = definedExternally + set(value) = definedExternally + var InsertSpaceAfterKeywordsInControlFlowStatements: Boolean? + var InsertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean? + var InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean? + var InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean? + var InsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: Boolean? + get() = definedExternally + set(value) = definedExternally + var InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean? + var InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: Boolean? + get() = definedExternally + set(value) = definedExternally + var InsertSpaceAfterTypeAssertion: Boolean? + get() = definedExternally + set(value) = definedExternally + var InsertSpaceBeforeFunctionParenthesis: Boolean? + get() = definedExternally + set(value) = definedExternally + var PlaceOpenBraceOnNewLineForFunctions: Boolean? + var PlaceOpenBraceOnNewLineForControlBlocks: Boolean? + var insertSpaceBeforeTypeAnnotation: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface FormatCodeSettings : EditorSettings { + val insertSpaceAfterCommaDelimiter: Boolean? + get() = definedExternally + val insertSpaceAfterSemicolonInForStatements: Boolean? + get() = definedExternally + val insertSpaceBeforeAndAfterBinaryOperators: Boolean? + get() = definedExternally + val insertSpaceAfterConstructor: Boolean? + get() = definedExternally + val insertSpaceAfterKeywordsInControlFlowStatements: Boolean? + get() = definedExternally + val insertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingEmptyBraces: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: Boolean? + get() = definedExternally + val insertSpaceAfterTypeAssertion: Boolean? + get() = definedExternally + val insertSpaceBeforeFunctionParenthesis: Boolean? + get() = definedExternally + val placeOpenBraceOnNewLineForFunctions: Boolean? + get() = definedExternally + val placeOpenBraceOnNewLineForControlBlocks: Boolean? + get() = definedExternally + val insertSpaceBeforeTypeAnnotation: Boolean? + get() = definedExternally + val indentMultiLineObjectLiteralBeginningOnBlankLine: Boolean? + get() = definedExternally + val semicolons: SemicolonPreference? + get() = definedExternally +} + +external fun getDefaultFormatCodeSettings(newLineCharacter: String = definedExternally): FormatCodeSettings + +external interface DefinitionInfo : DocumentSpan { + var kind: ScriptElementKind + var name: String + var containerKind: ScriptElementKind + var containerName: String + var unverified: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface DefinitionInfoAndBoundSpan { + var definitions: Array? + get() = definedExternally + set(value) = definedExternally + var textSpan: TextSpan +} + +external interface ReferencedSymbolDefinitionInfo : DefinitionInfo { + var displayParts: Array +} + +external interface ReferencedSymbol { + var definition: ReferencedSymbolDefinitionInfo + var references: Array +} + +external enum class SymbolDisplayPartKind { + aliasName /* = 0 */, + className /* = 1 */, + enumName /* = 2 */, + fieldName /* = 3 */, + interfaceName /* = 4 */, + keyword /* = 5 */, + lineBreak /* = 6 */, + numericLiteral /* = 7 */, + stringLiteral /* = 8 */, + localName /* = 9 */, + methodName /* = 10 */, + moduleName /* = 11 */, + operator /* = 12 */, + parameterName /* = 13 */, + propertyName /* = 14 */, + punctuation /* = 15 */, + space /* = 16 */, + text /* = 17 */, + typeParameterName /* = 18 */, + enumMemberName /* = 19 */, + functionName /* = 20 */, + regularExpressionLiteral /* = 21 */, + link /* = 22 */, + linkName /* = 23 */, + linkText /* = 24 */ +} + +external interface SymbolDisplayPart { + var text: String + var kind: String +} + +external interface JSDocLinkDisplayPart : SymbolDisplayPart { + var target: DocumentSpan +} + +external interface JSDocTagInfo { + var name: String + var text: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface QuickInfo { + var kind: ScriptElementKind + var kindModifiers: String + var textSpan: TextSpan + var displayParts: Array? + get() = definedExternally + set(value) = definedExternally + var documentation: Array? + get() = definedExternally + set(value) = definedExternally + var tags: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface RenameInfoSuccess { + var canRename: Boolean? + var fileToRename: String? + get() = definedExternally + set(value) = definedExternally + var displayName: String + var fullDisplayName: String + var kind: ScriptElementKind + var kindModifiers: String + var triggerSpan: TextSpan +} + +external interface RenameInfoFailure { + var canRename: Boolean? + var localizedErrorMessage: String +} + +external interface RenameInfoOptions { + val allowRenameOfImportPath: Boolean? + get() = definedExternally +} + +external interface DocCommentTemplateOptions { + val generateReturnInDocTemplate: Boolean? + get() = definedExternally +} + +external interface SignatureHelpParameter { + var name: String + var documentation: Array + var displayParts: Array + var isOptional: Boolean? + var isRest: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface SelectionRange { + var textSpan: TextSpan + var parent: SelectionRange? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureHelpItem { + var isVariadic: Boolean? + var prefixDisplayParts: Array + var suffixDisplayParts: Array + var separatorDisplayParts: Array + var parameters: Array + var documentation: Array + var tags: Array +} + +external interface SignatureHelpItems { + var items: Array + var applicableSpan: TextSpan + var selectedItemIndex: Number + var argumentIndex: Number + var argumentCount: Number +} + +external interface CompletionInfo { + var isGlobalCompletion: Boolean? + var isMemberCompletion: Boolean? + var optionalReplacementSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var isNewIdentifierLocation: Boolean? + var isIncomplete: Boolean? + get() = definedExternally + set(value) = definedExternally + var entries: Array +} + +external interface CompletionEntryData { + var fileName: String? + get() = definedExternally + set(value) = definedExternally + var ambientModuleName: String? + get() = definedExternally + set(value) = definedExternally + var isPackageJsonImport: Boolean? + get() = definedExternally + set(value) = definedExternally + var exportName: String + var moduleSpecifier: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface CompletionEntry { + var name: String + var kind: ScriptElementKind + var kindModifiers: String? + get() = definedExternally + set(value) = definedExternally + var sortText: String + var insertText: String? + get() = definedExternally + set(value) = definedExternally + var isSnippet: Boolean? + get() = definedExternally + set(value) = definedExternally + var replacementSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var hasAction: Boolean? + get() = definedExternally + set(value) = definedExternally + var source: String? + get() = definedExternally + set(value) = definedExternally + var sourceDisplay: Array? + get() = definedExternally + set(value) = definedExternally + var isRecommended: Boolean? + get() = definedExternally + set(value) = definedExternally + var isFromUncheckedFile: Boolean? + get() = definedExternally + set(value) = definedExternally + var isPackageJsonImport: Boolean? + get() = definedExternally + set(value) = definedExternally + var isImportStatementCompletion: Boolean? + get() = definedExternally + set(value) = definedExternally + var data: CompletionEntryData? + get() = definedExternally + set(value) = definedExternally +} + +external interface CompletionEntryDetails { + var name: String + var kind: ScriptElementKind + var kindModifiers: String + var displayParts: Array + var documentation: Array? + get() = definedExternally + set(value) = definedExternally + var tags: Array? + get() = definedExternally + set(value) = definedExternally + var codeActions: Array? + get() = definedExternally + set(value) = definedExternally + var source: Array? + get() = definedExternally + set(value) = definedExternally + var sourceDisplay: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface OutliningSpan { + var textSpan: TextSpan + var hintSpan: TextSpan + var bannerText: String + var autoCollapse: Boolean? + var kind: OutliningSpanKind +} + +external enum class OutliningSpanKind { + Comment /* = "comment" */, + Region /* = "region" */, + Code /* = "code" */, + Imports /* = "imports" */ +} + +external enum class OutputFileType { + JavaScript /* = 0 */, + SourceMap /* = 1 */, + Declaration /* = 2 */ +} + +external enum class EndOfLineState { + None /* = 0 */, + InMultiLineCommentTrivia /* = 1 */, + InSingleQuoteStringLiteral /* = 2 */, + InDoubleQuoteStringLiteral /* = 3 */, + InTemplateHeadOrNoSubstitutionTemplate /* = 4 */, + InTemplateMiddleOrTail /* = 5 */, + InTemplateSubstitutionPosition /* = 6 */ +} + +external enum class TokenClass { + Punctuation /* = 0 */, + Keyword /* = 1 */, + Operator /* = 2 */, + Comment /* = 3 */, + Whitespace /* = 4 */, + Identifier /* = 5 */, + NumberLiteral /* = 6 */, + BigIntLiteral /* = 7 */, + StringLiteral /* = 8 */, + RegExpLiteral /* = 9 */ +} + +external interface ClassificationResult { + var finalLexState: EndOfLineState + var entries: Array +} + +external interface ClassificationInfo { + var length: Number + var classification: TokenClass +} + +external interface Classifier { + fun getClassificationsForLine(text: String, lexState: EndOfLineState, syntacticClassifierAbsent: Boolean): ClassificationResult + fun getEncodedLexicalClassifications(text: String, endOfLineState: EndOfLineState, syntacticClassifierAbsent: Boolean): Classifications +} + +external enum class ScriptElementKind { + unknown /* = "" */, + warning /* = "warning" */, + keyword /* = "keyword" */, + scriptElement /* = "script" */, + moduleElement /* = "module" */, + classElement /* = "class" */, + localClassElement /* = "local class" */, + interfaceElement /* = "interface" */, + typeElement /* = "type" */, + enumElement /* = "enum" */, + enumMemberElement /* = "enum member" */, + variableElement /* = "var" */, + localVariableElement /* = "local var" */, + functionElement /* = "function" */, + localFunctionElement /* = "local function" */, + memberFunctionElement /* = "method" */, + memberGetAccessorElement /* = "getter" */, + memberSetAccessorElement /* = "setter" */, + memberVariableElement /* = "property" */, + constructorImplementationElement /* = "constructor" */, + callSignatureElement /* = "call" */, + indexSignatureElement /* = "index" */, + constructSignatureElement /* = "construct" */, + parameterElement /* = "parameter" */, + typeParameterElement /* = "type parameter" */, + primitiveType /* = "primitive type" */, + label /* = "label" */, + alias /* = "alias" */, + constElement /* = "const" */, + letElement /* = "let" */, + directory /* = "directory" */, + externalModuleName /* = "external module name" */, + jsxAttribute /* = "JSX attribute" */, + string /* = "string" */, + link /* = "link" */, + linkName /* = "link name" */, + linkText /* = "link text" */ +} + +external enum class ScriptElementKindModifier { + none /* = "" */, + publicMemberModifier /* = "public" */, + privateMemberModifier /* = "private" */, + protectedMemberModifier /* = "protected" */, + exportedModifier /* = "export" */, + ambientModifier /* = "declare" */, + staticModifier /* = "static" */, + abstractModifier /* = "abstract" */, + optionalModifier /* = "optional" */, + deprecatedModifier /* = "deprecated" */, + dtsModifier /* = ".d.ts" */, + tsModifier /* = ".ts" */, + tsxModifier /* = ".tsx" */, + jsModifier /* = ".js" */, + jsxModifier /* = ".jsx" */, + jsonModifier /* = ".json" */ +} + +external enum class ClassificationTypeNames { + comment /* = "comment" */, + identifier /* = "identifier" */, + keyword /* = "keyword" */, + numericLiteral /* = "number" */, + bigintLiteral /* = "bigint" */, + operator /* = "operator" */, + stringLiteral /* = "string" */, + whiteSpace /* = "whitespace" */, + text /* = "text" */, + punctuation /* = "punctuation" */, + className /* = "class name" */, + enumName /* = "enum name" */, + interfaceName /* = "interface name" */, + moduleName /* = "module name" */, + typeParameterName /* = "type parameter name" */, + typeAliasName /* = "type alias name" */, + parameterName /* = "parameter name" */, + docCommentTagName /* = "doc comment tag name" */, + jsxOpenTagName /* = "jsx open tag name" */, + jsxCloseTagName /* = "jsx close tag name" */, + jsxSelfClosingTagName /* = "jsx self closing tag name" */, + jsxAttribute /* = "jsx attribute" */, + jsxText /* = "jsx text" */, + jsxAttributeStringLiteralValue /* = "jsx attribute string literal value" */ +} + +external enum class ClassificationType { + comment /* = 1 */, + identifier /* = 2 */, + keyword /* = 3 */, + numericLiteral /* = 4 */, + operator /* = 5 */, + stringLiteral /* = 6 */, + regularExpressionLiteral /* = 7 */, + whiteSpace /* = 8 */, + text /* = 9 */, + punctuation /* = 10 */, + className /* = 11 */, + enumName /* = 12 */, + interfaceName /* = 13 */, + moduleName /* = 14 */, + typeParameterName /* = 15 */, + typeAliasName /* = 16 */, + parameterName /* = 17 */, + docCommentTagName /* = 18 */, + jsxOpenTagName /* = 19 */, + jsxCloseTagName /* = 20 */, + jsxSelfClosingTagName /* = 21 */, + jsxAttribute /* = 22 */, + jsxText /* = 23 */, + jsxAttributeStringLiteralValue /* = 24 */, + bigintLiteral /* = 25 */ +} + +external fun createClassifier(): Classifier + +external interface DocumentHighlights { + var fileName: String + var highlightSpans: Array +} + +external interface DocumentRegistry { + fun acquireDocument(fileName: String, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile + fun acquireDocumentWithKey(fileName: String, path: String /* String & `T$3` */, compilationSettings: CompilerOptions, key: String /* String & `T$16` */, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile + fun updateDocument(fileName: String, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile + fun updateDocumentWithKey(fileName: String, path: String /* String & `T$3` */, compilationSettings: CompilerOptions, key: String /* String & `T$16` */, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile + fun getKeyForCompilationSettings(settings: CompilerOptions): String /* String & `T$16` */ + fun releaseDocument(fileName: String, compilationSettings: CompilerOptions) + fun releaseDocument(fileName: String, compilationSettings: CompilerOptions, scriptKind: ScriptKind) + fun releaseDocumentWithKey(path: String /* String & `T$3` */, key: String /* String & `T$16` */) + fun releaseDocumentWithKey(path: String /* String & `T$3` */, key: String /* String & `T$16` */, scriptKind: ScriptKind) + fun reportStats(): String +} + +external interface `T$16` { + var __bucketKey: Any +} + +external fun createDocumentRegistry(useCaseSensitiveFileNames: Boolean = definedExternally, currentDirectory: String = definedExternally): DocumentRegistry + +external fun preProcessFile(sourceText: String, readImportFiles: Boolean = definedExternally, detectJavaScriptImports: Boolean = definedExternally): PreProcessedFileInfo + +external interface TranspileOptions { + var compilerOptions: CompilerOptions? + get() = definedExternally + set(value) = definedExternally + var fileName: String? + get() = definedExternally + set(value) = definedExternally + var reportDiagnostics: Boolean? + get() = definedExternally + set(value) = definedExternally + var moduleName: String? + get() = definedExternally + set(value) = definedExternally + var renamedDependencies: MapLike? + get() = definedExternally + set(value) = definedExternally + var transformers: CustomTransformers? + get() = definedExternally + set(value) = definedExternally +} + +external interface TranspileOutput { + var outputText: String + var diagnostics: Array? + get() = definedExternally + set(value) = definedExternally + var sourceMapText: String? + get() = definedExternally + set(value) = definedExternally +} + +external fun transpileModule(input: String, transpileOptions: TranspileOptions): TranspileOutput + +external fun transpile(input: String, compilerOptions: CompilerOptions = definedExternally, fileName: String = definedExternally, diagnostics: Array = definedExternally, moduleName: String = definedExternally): String + +external var servicesVersion: Any + +external fun toEditorSettings(options: EditorOptions): EditorSettings + +external fun toEditorSettings(options: EditorSettings): EditorSettings + +external fun displayPartsToString(displayParts: Array?): String + +external fun getDefaultCompilerOptions(): CompilerOptions + +external fun getSupportedCodeFixes(): Array + +external fun createLanguageServiceSourceFile(fileName: String, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: String, setNodeParents: Boolean, scriptKind: ScriptKind = definedExternally): SourceFile + +external fun updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: String, textChangeRange: TextChangeRange?, aggressiveChecks: Boolean = definedExternally): SourceFile + +external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally, syntaxOnlyOrLanguageServiceMode: Boolean = definedExternally): LanguageService + +external fun createLanguageService(host: LanguageServiceHost): LanguageService + +external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally): LanguageService + +external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally, syntaxOnlyOrLanguageServiceMode: LanguageServiceMode = definedExternally): LanguageService + +external fun getDefaultLibFilePath(options: CompilerOptions): String + +external fun transform(source: T, transformers: Array>, compilerOptions: CompilerOptions = definedExternally): TransformationResult + +external fun transform(source: T, transformers: Array>): TransformationResult + +external fun transform(source: Array, transformers: Array>, compilerOptions: CompilerOptions = definedExternally): TransformationResult + +external fun transform(source: Array, transformers: Array>): TransformationResult + +external fun createNodeArray(elements: Array?, hasTrailingComma: Boolean?): NodeArray + +external var createNumericLiteral: (value: dynamic /* String | Number */, numericLiteralFlags: TokenFlags?) -> NumericLiteral + +external var createBigIntLiteral: (value: dynamic /* String | PseudoBigInt */) -> BigIntLiteral + +external object createStringLiteral { + @nativeInvoke + operator fun invoke(text: String, isSingleQuote: Boolean? = definedExternally): StringLiteral + @nativeInvoke + operator fun invoke(text: String, isSingleQuote: Boolean? = definedExternally, hasExtendedUnicodeEscape: Boolean? = definedExternally): StringLiteral +} + +external var createStringLiteralFromNode: (sourceNode: dynamic /* Identifier | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral */, isSingleQuote: Boolean?) -> StringLiteral + +external var createRegularExpressionLiteral: (text: String) -> RegularExpressionLiteral + +external var createLoopVariable: (reservedInNestedScopes: Boolean?) -> Identifier + +external var createUniqueName: (text: String, flags: GeneratedIdentifierFlags?) -> Identifier + +external var createPrivateIdentifier: (text: String) -> PrivateIdentifier + +external var createSuper: () -> SuperExpression + +external var createThis: () -> ThisExpression + +external var createNull: () -> NullLiteral + +external var createTrue: () -> TrueLiteral + +external var createFalse: () -> FalseLiteral + +//external var createModifier: (kind: T) -> ModifierToken +external fun createModifier(kind: T): ModifierToken + +external var createModifiersFromModifierFlags: (flags: ModifierFlags) -> Array + +external var createQualifiedName: (left: dynamic /* Identifier | QualifiedName */, right: dynamic /* String | Identifier */) -> QualifiedName + +external var updateQualifiedName: (node: QualifiedName, left: dynamic /* Identifier | QualifiedName */, right: Identifier) -> QualifiedName + +external var createComputedPropertyName: (expression: Expression) -> ComputedPropertyName + +external var updateComputedPropertyName: (node: ComputedPropertyName, expression: Expression) -> ComputedPropertyName + +external var createTypeParameterDeclaration: (name: dynamic /* String | Identifier */, constraint: TypeNode?, defaultType: TypeNode?) -> TypeParameterDeclaration + +external var updateTypeParameterDeclaration: (node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode?, defaultType: TypeNode?) -> TypeParameterDeclaration + +external var createParameter: (decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> ParameterDeclaration + +external var updateParameter: (node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> ParameterDeclaration + +external var createDecorator: (expression: Expression) -> Decorator + +external var updateDecorator: (node: Decorator, expression: Expression) -> Decorator + +external var createProperty: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionOrExclamationToken: dynamic /* QuestionToken? | ExclamationToken? */, type: TypeNode?, initializer: Expression?) -> PropertyDeclaration + +external var updateProperty: (node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionOrExclamationToken: dynamic /* QuestionToken? | ExclamationToken? */, type: TypeNode?, initializer: Expression?) -> PropertyDeclaration + +external var createMethod: (decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> MethodDeclaration + +external var updateMethod: (node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> MethodDeclaration + +external var createConstructor: (decorators: Array?, modifiers: Array?, parameters: Array, body: Block?) -> ConstructorDeclaration + +external var updateConstructor: (node: ConstructorDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, body: Block?) -> ConstructorDeclaration + +external var createGetAccessor: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, type: TypeNode?, body: Block?) -> GetAccessorDeclaration + +external var updateGetAccessor: (node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, type: TypeNode?, body: Block?) -> GetAccessorDeclaration + +external var createSetAccessor: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, body: Block?) -> SetAccessorDeclaration + +external var updateSetAccessor: (node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, body: Block?) -> SetAccessorDeclaration + +external var createCallSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?) -> CallSignatureDeclaration + +external var updateCallSignature: (node: CallSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?) -> CallSignatureDeclaration + +external var createConstructSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?) -> ConstructSignatureDeclaration + +external var updateConstructSignature: (node: ConstructSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?) -> ConstructSignatureDeclaration + +external var updateIndexSignature: (node: IndexSignatureDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode) -> IndexSignatureDeclaration + +//external var createKeywordTypeNode: (kind: TKind) -> KeywordTypeNode +external fun createKeywordTypeNode(kind: TKind): KeywordTypeNode + +external var createTypePredicateNodeWithModifier: (assertsModifier: AssertsKeyword?, parameterName: dynamic /* String | Identifier | ThisTypeNode */, type: TypeNode?) -> TypePredicateNode + +external var updateTypePredicateNodeWithModifier: (node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: dynamic /* Identifier | ThisTypeNode */, type: TypeNode?) -> TypePredicateNode + +external var createTypeReferenceNode: (typeName: dynamic /* String | Identifier | QualifiedName */, typeArguments: Array?) -> TypeReferenceNode + +external var updateTypeReferenceNode: (node: TypeReferenceNode, typeName: dynamic /* Identifier | QualifiedName */, typeArguments: NodeArray?) -> TypeReferenceNode + +external var createFunctionTypeNode: (typeParameters: Array?, parameters: Array, type: TypeNode) -> FunctionTypeNode + +external var updateFunctionTypeNode: (node: FunctionTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode) -> FunctionTypeNode + +external var createConstructorTypeNode: (typeParameters: Array?, parameters: Array, type: TypeNode) -> ConstructorTypeNode + +external var updateConstructorTypeNode: (node: ConstructorTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode) -> ConstructorTypeNode + +external var createTypeQueryNode: (exprName: dynamic /* Identifier | QualifiedName */) -> TypeQueryNode + +external var updateTypeQueryNode: (node: TypeQueryNode, exprName: dynamic /* Identifier | QualifiedName */) -> TypeQueryNode + +external var createTypeLiteralNode: (members: Array?) -> TypeLiteralNode + +external var updateTypeLiteralNode: (node: TypeLiteralNode, members: NodeArray) -> TypeLiteralNode + +external var createArrayTypeNode: (elementType: TypeNode) -> ArrayTypeNode + +external var updateArrayTypeNode: (node: ArrayTypeNode, elementType: TypeNode) -> ArrayTypeNode + +external var createTupleTypeNode: (elements: Array) -> TupleTypeNode + +external var updateTupleTypeNode: (node: TupleTypeNode, elements: Array) -> TupleTypeNode + +external var createOptionalTypeNode: (type: TypeNode) -> OptionalTypeNode + +external var updateOptionalTypeNode: (node: OptionalTypeNode, type: TypeNode) -> OptionalTypeNode + +external var createRestTypeNode: (type: TypeNode) -> RestTypeNode + +external var updateRestTypeNode: (node: RestTypeNode, type: TypeNode) -> RestTypeNode + +external var createUnionTypeNode: (types: Array) -> UnionTypeNode + +external var updateUnionTypeNode: (node: UnionTypeNode, types: NodeArray) -> UnionTypeNode + +external var createIntersectionTypeNode: (types: Array) -> IntersectionTypeNode + +external var updateIntersectionTypeNode: (node: IntersectionTypeNode, types: NodeArray) -> IntersectionTypeNode + +external var createConditionalTypeNode: (checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) -> ConditionalTypeNode + +external var updateConditionalTypeNode: (node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) -> ConditionalTypeNode + +external var createInferTypeNode: (typeParameter: TypeParameterDeclaration) -> InferTypeNode + +external var updateInferTypeNode: (node: InferTypeNode, typeParameter: TypeParameterDeclaration) -> InferTypeNode + +external var createImportTypeNode: (argument: TypeNode, qualifier: dynamic /* Identifier? | QualifiedName? */, typeArguments: Array?, isTypeOf: Boolean?) -> ImportTypeNode + +external var updateImportTypeNode: (node: ImportTypeNode, argument: TypeNode, qualifier: dynamic /* Identifier? | QualifiedName? */, typeArguments: Array?, isTypeOf: Boolean?) -> ImportTypeNode + +external var createParenthesizedType: (type: TypeNode) -> ParenthesizedTypeNode + +external var updateParenthesizedType: (node: ParenthesizedTypeNode, type: TypeNode) -> ParenthesizedTypeNode + +external var createThisTypeNode: () -> ThisTypeNode + +external var updateTypeOperatorNode: (node: TypeOperatorNode, type: TypeNode) -> TypeOperatorNode + +external var createIndexedAccessTypeNode: (objectType: TypeNode, indexType: TypeNode) -> IndexedAccessTypeNode + +external var updateIndexedAccessTypeNode: (node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) -> IndexedAccessTypeNode + +//external var createMappedTypeNode: (readonlyToken: dynamic /* ReadonlyKeyword? | PlusToken? | MinusToken? */, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */, type: TypeNode?) -> MappedTypeNode + +external var updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: dynamic /* ReadonlyKeyword? | PlusToken? | MinusToken? */, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */, type: TypeNode?) -> MappedTypeNode + +external var createLiteralTypeNode: (literal: dynamic /* LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral */) -> LiteralTypeNode + +external var updateLiteralTypeNode: (node: LiteralTypeNode, literal: dynamic /* LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral */) -> LiteralTypeNode + +external var createObjectBindingPattern: (elements: Array) -> ObjectBindingPattern + +external var updateObjectBindingPattern: (node: ObjectBindingPattern, elements: Array) -> ObjectBindingPattern + +external var createArrayBindingPattern: (elements: Array) -> ArrayBindingPattern + +external var updateArrayBindingPattern: (node: ArrayBindingPattern, elements: Array) -> ArrayBindingPattern + +external var createBindingElement: (dotDotDotToken: DotDotDotToken?, propertyName: dynamic /* String? | Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression?) -> BindingElement + +external var updateBindingElement: (node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */, name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression?) -> BindingElement + +external var createArrayLiteral: (elements: Array?, multiLine: Boolean?) -> ArrayLiteralExpression + +external var updateArrayLiteral: (node: ArrayLiteralExpression, elements: Array) -> ArrayLiteralExpression + +external var createObjectLiteral: (properties: Array?, multiLine: Boolean?) -> ObjectLiteralExpression + +external var updateObjectLiteral: (node: ObjectLiteralExpression, properties: Array) -> ObjectLiteralExpression + +external var createPropertyAccess: (expression: Expression, name: dynamic /* String | Identifier | PrivateIdentifier */) -> PropertyAccessExpression + +external var updatePropertyAccess: (node: PropertyAccessExpression, expression: Expression, name: dynamic /* Identifier | PrivateIdentifier */) -> PropertyAccessExpression + +external var createPropertyAccessChain: (expression: Expression, questionDotToken: QuestionDotToken?, name: dynamic /* String | Identifier | PrivateIdentifier */) -> PropertyAccessChain + +external var updatePropertyAccessChain: (node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: dynamic /* Identifier | PrivateIdentifier */) -> PropertyAccessChain + +external var createElementAccess: (expression: Expression, index: dynamic /* Number | Expression */) -> ElementAccessExpression + +external var updateElementAccess: (node: ElementAccessExpression, expression: Expression, argumentExpression: Expression) -> ElementAccessExpression + +external var createElementAccessChain: (expression: Expression, questionDotToken: QuestionDotToken?, index: dynamic /* Number | Expression */) -> ElementAccessChain + +external var updateElementAccessChain: (node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, argumentExpression: Expression) -> ElementAccessChain + +external var createCall: (expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> CallExpression + +external var updateCall: (node: CallExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array) -> CallExpression + +external var createCallChain: (expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array?) -> CallChain + +external var updateCallChain: (node: CallChain, expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array) -> CallChain + +external var createNew: (expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> NewExpression + +external var updateNew: (node: NewExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> NewExpression + +external var createTypeAssertion: (type: TypeNode, expression: Expression) -> TypeAssertion + +external var updateTypeAssertion: (node: TypeAssertion, type: TypeNode, expression: Expression) -> TypeAssertion + +external var createParen: (expression: Expression) -> ParenthesizedExpression + +external var updateParen: (node: ParenthesizedExpression, expression: Expression) -> ParenthesizedExpression + +external var createFunctionExpression: (modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block) -> FunctionExpression + +external var updateFunctionExpression: (node: FunctionExpression, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block) -> FunctionExpression + +external var createDelete: (expression: Expression) -> DeleteExpression + +external var updateDelete: (node: DeleteExpression, expression: Expression) -> DeleteExpression + +external var createTypeOf: (expression: Expression) -> TypeOfExpression + +external var updateTypeOf: (node: TypeOfExpression, expression: Expression) -> TypeOfExpression + +external var createVoid: (expression: Expression) -> VoidExpression + +external var updateVoid: (node: VoidExpression, expression: Expression) -> VoidExpression + +external var createAwait: (expression: Expression) -> AwaitExpression + +external var updateAwait: (node: AwaitExpression, expression: Expression) -> AwaitExpression + +external var createPrefix: (operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken | SyntaxKind.ExclamationToken */, operand: Expression) -> PrefixUnaryExpression + +external var updatePrefix: (node: PrefixUnaryExpression, operand: Expression) -> PrefixUnaryExpression + +external var createPostfix: (operand: Expression, operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken */) -> PostfixUnaryExpression + +external var updatePostfix: (node: PostfixUnaryExpression, operand: Expression) -> PostfixUnaryExpression + +external var createBinary: ( + left: Expression, operator: dynamic /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression +) -> BinaryExpression + +external var updateConditional: (node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression) -> ConditionalExpression + +external var createTemplateExpression: (head: TemplateHead, templateSpans: Array) -> TemplateExpression + +external var updateTemplateExpression: (node: TemplateExpression, head: TemplateHead, templateSpans: Array) -> TemplateExpression + +external object createTemplateHead { + @nativeInvoke + operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateHead + @nativeInvoke + operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateHead +} + +external object createTemplateMiddle { + @nativeInvoke + operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateMiddle + @nativeInvoke + operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateMiddle +} + +external object createTemplateTail { + @nativeInvoke + operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateTail + @nativeInvoke + operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateTail +} + +external object createNoSubstitutionTemplateLiteral { + @nativeInvoke + operator fun invoke(text: String, rawText: String? = definedExternally): NoSubstitutionTemplateLiteral + @nativeInvoke + operator fun invoke(text: String?, rawText: String): NoSubstitutionTemplateLiteral +} + +external var updateYield: (node: YieldExpression, asteriskToken: AsteriskToken?, expression: Expression?) -> YieldExpression + +external var createSpread: (expression: Expression) -> SpreadElement + +external var updateSpread: (node: SpreadElement, expression: Expression) -> SpreadElement + +external var createOmittedExpression: () -> OmittedExpression + +external var createAsExpression: (expression: Expression, type: TypeNode) -> AsExpression + +external var updateAsExpression: (node: AsExpression, expression: Expression, type: TypeNode) -> AsExpression + +external var createNonNullExpression: (expression: Expression) -> NonNullExpression + +external var updateNonNullExpression: (node: NonNullExpression, expression: Expression) -> NonNullExpression + +external var createNonNullChain: (expression: Expression) -> NonNullChain + +external var updateNonNullChain: (node: NonNullChain, expression: Expression) -> NonNullChain + +external var createMetaProperty: (keywordToken: dynamic /* SyntaxKind.ImportKeyword | SyntaxKind.NewKeyword */, name: Identifier) -> MetaProperty + +external var updateMetaProperty: (node: MetaProperty, name: Identifier) -> MetaProperty + +external var createTemplateSpan: (expression: Expression, literal: dynamic /* TemplateMiddle | TemplateTail */) -> TemplateSpan + +external var updateTemplateSpan: (node: TemplateSpan, expression: Expression, literal: dynamic /* TemplateMiddle | TemplateTail */) -> TemplateSpan + +external var createSemicolonClassElement: () -> SemicolonClassElement + +external var createBlock: (statements: Array, multiLine: Boolean?) -> Block + +external var updateBlock: (node: Block, statements: Array) -> Block + +external var createVariableStatement: (modifiers: Array?, declarationList: dynamic /* VariableDeclarationList | Array */) -> VariableStatement + +external var updateVariableStatement: (node: VariableStatement, modifiers: Array?, declarationList: VariableDeclarationList) -> VariableStatement + +external var createEmptyStatement: () -> EmptyStatement + +external var createExpressionStatement: (expression: Expression) -> ExpressionStatement + +external var updateExpressionStatement: (node: ExpressionStatement, expression: Expression) -> ExpressionStatement + +external var createStatement: (expression: Expression) -> ExpressionStatement + +external var updateStatement: (node: ExpressionStatement, expression: Expression) -> ExpressionStatement + +external var createIf: (expression: Expression, thenStatement: Statement, elseStatement: Statement?) -> IfStatement + +external var updateIf: (node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement?) -> IfStatement + +external var createDo: (statement: Statement, expression: Expression) -> DoStatement + +external var updateDo: (node: DoStatement, statement: Statement, expression: Expression) -> DoStatement + +external var createWhile: (expression: Expression, statement: Statement) -> WhileStatement + +external var updateWhile: (node: WhileStatement, expression: Expression, statement: Statement) -> WhileStatement + +external var createFor: (initializer: dynamic /* VariableDeclarationList? | Expression? */, condition: Expression?, incrementor: Expression?, statement: Statement) -> ForStatement + +external var updateFor: (node: ForStatement, initializer: dynamic /* VariableDeclarationList? | Expression? */, condition: Expression?, incrementor: Expression?, statement: Statement) -> ForStatement + +external var createForIn: (initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForInStatement + +external var updateForIn: (node: ForInStatement, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForInStatement + +external var createForOf: (awaitModifier: AwaitKeyword?, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForOfStatement + +external var updateForOf: (node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForOfStatement + +external var createContinue: (label: dynamic /* String? | Identifier? */) -> ContinueStatement + +external var updateContinue: (node: ContinueStatement, label: Identifier?) -> ContinueStatement + +external var createBreak: (label: dynamic /* String? | Identifier? */) -> BreakStatement + +external var updateBreak: (node: BreakStatement, label: Identifier?) -> BreakStatement + +external var createReturn: (expression: Expression?) -> ReturnStatement + +external var updateReturn: (node: ReturnStatement, expression: Expression?) -> ReturnStatement + +external var createWith: (expression: Expression, statement: Statement) -> WithStatement + +external var updateWith: (node: WithStatement, expression: Expression, statement: Statement) -> WithStatement + +external var createSwitch: (expression: Expression, caseBlock: CaseBlock) -> SwitchStatement + +external var updateSwitch: (node: SwitchStatement, expression: Expression, caseBlock: CaseBlock) -> SwitchStatement + +external var createLabel: (label: dynamic /* String | Identifier */, statement: Statement) -> LabeledStatement + +external var updateLabel: (node: LabeledStatement, label: Identifier, statement: Statement) -> LabeledStatement + +external var createThrow: (expression: Expression) -> ThrowStatement + +external var updateThrow: (node: ThrowStatement, expression: Expression) -> ThrowStatement + +external var createTry: (tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?) -> TryStatement + +external var updateTry: (node: TryStatement, tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?) -> TryStatement + +external var createDebuggerStatement: () -> DebuggerStatement + +external var createVariableDeclarationList: (declarations: Array, flags: NodeFlags?) -> VariableDeclarationList + +external var updateVariableDeclarationList: (node: VariableDeclarationList, declarations: Array) -> VariableDeclarationList + +external var createFunctionDeclaration: (decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> FunctionDeclaration + +external var updateFunctionDeclaration: (node: FunctionDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> FunctionDeclaration + +external var createClassDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassDeclaration + +external var updateClassDeclaration: (node: ClassDeclaration, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassDeclaration + +external var createInterfaceDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> InterfaceDeclaration + +external var updateInterfaceDeclaration: (node: InterfaceDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array) -> InterfaceDeclaration + +external var createTypeAliasDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, typeParameters: Array?, type: TypeNode) -> TypeAliasDeclaration + +external var updateTypeAliasDeclaration: (node: TypeAliasDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode) -> TypeAliasDeclaration + +external var createEnumDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, members: Array) -> EnumDeclaration + +external var updateEnumDeclaration: (node: EnumDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, members: Array) -> EnumDeclaration + +external var createModuleDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral */, body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */, flags: NodeFlags?) -> ModuleDeclaration + +external var updateModuleDeclaration: (node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral */, body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */) -> ModuleDeclaration + +external var createModuleBlock: (statements: Array) -> ModuleBlock + +external var updateModuleBlock: (node: ModuleBlock, statements: Array) -> ModuleBlock + +external var createCaseBlock: (clauses: Array) -> CaseBlock + +external var updateCaseBlock: (node: CaseBlock, clauses: Array) -> CaseBlock + +external var createNamespaceExportDeclaration: (name: dynamic /* String | Identifier */) -> NamespaceExportDeclaration + +external var updateNamespaceExportDeclaration: (node: NamespaceExportDeclaration, name: Identifier) -> NamespaceExportDeclaration + +external var createImportEqualsDeclaration: (decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: dynamic /* String | Identifier */, moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */) -> ImportEqualsDeclaration + +external var updateImportEqualsDeclaration: (node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */) -> ImportEqualsDeclaration + +external var createImportDeclaration: (decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression) -> ImportDeclaration + +external var updateImportDeclaration: (node: ImportDeclaration, decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression) -> ImportDeclaration + +external var createNamespaceImport: (name: Identifier) -> NamespaceImport + +external var updateNamespaceImport: (node: NamespaceImport, name: Identifier) -> NamespaceImport + +external var createNamedImports: (elements: Array) -> NamedImports + +external var updateNamedImports: (node: NamedImports, elements: Array) -> NamedImports + +external var createImportSpecifier: (propertyName: Identifier?, name: Identifier) -> ImportSpecifier + +external var updateImportSpecifier: (node: ImportSpecifier, propertyName: Identifier?, name: Identifier) -> ImportSpecifier + +external var createExportAssignment: (decorators: Array?, modifiers: Array?, isExportEquals: Boolean?, expression: Expression) -> ExportAssignment + +external var updateExportAssignment: (node: ExportAssignment, decorators: Array?, modifiers: Array?, expression: Expression) -> ExportAssignment + +external var createNamedExports: (elements: Array) -> NamedExports + +external var updateNamedExports: (node: NamedExports, elements: Array) -> NamedExports + +external var createExportSpecifier: (propertyName: dynamic /* String? | Identifier? */, name: dynamic /* String | Identifier */) -> ExportSpecifier + +external var updateExportSpecifier: (node: ExportSpecifier, propertyName: Identifier?, name: Identifier) -> ExportSpecifier + +external var createExternalModuleReference: (expression: Expression) -> ExternalModuleReference + +external var updateExternalModuleReference: (node: ExternalModuleReference, expression: Expression) -> ExternalModuleReference + +external var createJSDocTypeExpression: (type: TypeNode) -> JSDocTypeExpression + +external var createJSDocTypeTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocTypeTag + +external var createJSDocReturnTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: dynamic /* String? | NodeArray? */) -> JSDocReturnTag + +external var createJSDocThisTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocThisTag + +external var createJSDocComment: (comment: dynamic /* String? | NodeArray? */, tags: Array?) -> JSDoc + +external var createJSDocParameterTag: (tagName: Identifier?, name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean?, comment: dynamic /* String? | NodeArray? */) -> JSDocParameterTag + +external var createJSDocClassTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocClassTag + +external var createJSDocAugmentsTag: (tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: dynamic /* String? | NodeArray? */) -> JSDocAugmentsTag + +external var createJSDocEnumTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocEnumTag + +external var createJSDocTemplateTag: (tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: dynamic /* String? | NodeArray? */) -> JSDocTemplateTag + +external var createJSDocTypedefTag: (tagName: Identifier?, typeExpression: dynamic /* JSDocTypeLiteral? | JSDocTypeExpression? */, fullName: dynamic /* Identifier? | JSDocNamespaceDeclaration? */, comment: dynamic /* String? | NodeArray? */) -> JSDocTypedefTag + +external var createJSDocCallbackTag: (tagName: Identifier?, typeExpression: JSDocSignature, fullName: dynamic /* Identifier? | JSDocNamespaceDeclaration? */, comment: dynamic /* String? | NodeArray? */) -> JSDocCallbackTag + +external var createJSDocSignature: (typeParameters: Array?, parameters: Array, type: JSDocReturnTag?) -> JSDocSignature + +external var createJSDocPropertyTag: (tagName: Identifier?, name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean?, comment: dynamic /* String? | NodeArray? */) -> JSDocPropertyTag + +external var createJSDocTypeLiteral: (jsDocPropertyTags: Array?, isArrayType: Boolean?) -> JSDocTypeLiteral + +external var createJSDocImplementsTag: (tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: dynamic /* String? | NodeArray? */) -> JSDocImplementsTag + +external var createJSDocAuthorTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocAuthorTag + +external var createJSDocPublicTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocPublicTag + +external var createJSDocPrivateTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocPrivateTag + +external var createJSDocProtectedTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocProtectedTag + +external var createJSDocReadonlyTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocReadonlyTag + +external var createJSDocTag: (tagName: Identifier, comment: dynamic /* String? | NodeArray? */) -> JSDocUnknownTag + +external var createJsxElement: (openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement) -> JsxElement + +external var updateJsxElement: (node: JsxElement, openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement) -> JsxElement + +external var createJsxSelfClosingElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxSelfClosingElement + +external var updateJsxSelfClosingElement: (node: JsxSelfClosingElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxSelfClosingElement + +external var createJsxOpeningElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxOpeningElement + +external var updateJsxOpeningElement: (node: JsxOpeningElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxOpeningElement + +external var createJsxClosingElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */) -> JsxClosingElement + +external var updateJsxClosingElement: (node: JsxClosingElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */) -> JsxClosingElement + +external var createJsxFragment: (openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment) -> JsxFragment + +external var createJsxText: (text: String, containsOnlyTriviaWhiteSpaces: Boolean?) -> JsxText + +external var updateJsxText: (node: JsxText, text: String, containsOnlyTriviaWhiteSpaces: Boolean?) -> JsxText + +external var createJsxOpeningFragment: () -> JsxOpeningFragment + +external var createJsxJsxClosingFragment: () -> JsxClosingFragment + +external var updateJsxFragment: (node: JsxFragment, openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment) -> JsxFragment + +external var createJsxAttribute: (name: Identifier, initializer: dynamic /* StringLiteral? | JsxExpression? */) -> JsxAttribute + +external var updateJsxAttribute: (node: JsxAttribute, name: Identifier, initializer: dynamic /* StringLiteral? | JsxExpression? */) -> JsxAttribute + +external var createJsxAttributes: (properties: Array) -> JsxAttributes + +external var updateJsxAttributes: (node: JsxAttributes, properties: Array) -> JsxAttributes + +external var createJsxSpreadAttribute: (expression: Expression) -> JsxSpreadAttribute + +external var updateJsxSpreadAttribute: (node: JsxSpreadAttribute, expression: Expression) -> JsxSpreadAttribute + +external var createJsxExpression: (dotDotDotToken: DotDotDotToken?, expression: Expression?) -> JsxExpression + +external var updateJsxExpression: (node: JsxExpression, expression: Expression?) -> JsxExpression + +external var createCaseClause: (expression: Expression, statements: Array) -> CaseClause + +external var updateCaseClause: (node: CaseClause, expression: Expression, statements: Array) -> CaseClause + +external var createDefaultClause: (statements: Array) -> DefaultClause + +external var updateDefaultClause: (node: DefaultClause, statements: Array) -> DefaultClause + +external var createHeritageClause: (token: dynamic /* SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword */, types: Array) -> HeritageClause + +external var updateHeritageClause: (node: HeritageClause, types: Array) -> HeritageClause + +external var createCatchClause: (variableDeclaration: dynamic /* String? | VariableDeclaration? */, block: Block) -> CatchClause + +external var updateCatchClause: (node: CatchClause, variableDeclaration: VariableDeclaration?, block: Block) -> CatchClause + +external var createPropertyAssignment: (name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression) -> PropertyAssignment + +external var updatePropertyAssignment: (node: PropertyAssignment, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression) -> PropertyAssignment + +external var createShorthandPropertyAssignment: (name: dynamic /* String | Identifier */, objectAssignmentInitializer: Expression?) -> ShorthandPropertyAssignment + +external var updateShorthandPropertyAssignment: (node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression?) -> ShorthandPropertyAssignment + +external var createSpreadAssignment: (expression: Expression) -> SpreadAssignment + +external var updateSpreadAssignment: (node: SpreadAssignment, expression: Expression) -> SpreadAssignment + +external var createEnumMember: (name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression?) -> EnumMember + +external var updateEnumMember: (node: EnumMember, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression?) -> EnumMember + +external var updateSourceFileNode: (node: SourceFile, statements: Array, isDeclarationFile: Boolean?, referencedFiles: Array?, typeReferences: Array?, hasNoDefaultLib: Boolean?, libReferences: Array?) -> SourceFile + +external var createNotEmittedStatement: (original: Node) -> NotEmittedStatement + +external var createPartiallyEmittedExpression: (expression: Expression, original: Node?) -> PartiallyEmittedExpression + +external var updatePartiallyEmittedExpression: (node: PartiallyEmittedExpression, expression: Expression) -> PartiallyEmittedExpression + +external var createCommaList: (elements: Array) -> CommaListExpression + +external var updateCommaList: (node: CommaListExpression, elements: Array) -> CommaListExpression + +external var createBundle: (sourceFiles: Array, prepends: Array?) -> Bundle + +external var updateBundle: (node: Bundle, sourceFiles: Array, prepends: Array?) -> Bundle + +external object createImmediatelyInvokedFunctionExpression { + @nativeInvoke + operator fun invoke(statements: Array): CallExpression + @nativeInvoke + operator fun invoke(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression +} + +external object createImmediatelyInvokedArrowFunction { + @nativeInvoke + operator fun invoke(statements: Array): CallExpression + @nativeInvoke + operator fun invoke(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression +} + +external var createVoidZero: () -> VoidExpression + +external var createExportDefault: (expression: Expression) -> ExportAssignment + +external var createExternalModuleExport: (exportName: Identifier) -> ExportDeclaration + +external var createNamespaceExport: (name: Identifier) -> NamespaceExport + +external var updateNamespaceExport: (node: NamespaceExport, name: Identifier) -> NamespaceExport + +external fun createToken(kind: TKind): Token + +external var createIdentifier: (text: String) -> Identifier + +external var createTempVariable: (recordTempVariable: ((node: Identifier) -> Unit)?) -> Identifier + +external var getGeneratedNameForNode: (node: Node?) -> Identifier + +external var createOptimisticUniqueName: (text: String) -> Identifier + +external var createFileLevelUniqueName: (text: String) -> Identifier + +external var createIndexSignature: (decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode) -> IndexSignatureDeclaration + +external var createTypePredicateNode: (parameterName: dynamic /* Identifier | ThisTypeNode | String */, type: TypeNode) -> TypePredicateNode + +external var updateTypePredicateNode: (node: TypePredicateNode, parameterName: dynamic /* Identifier | ThisTypeNode */, type: TypeNode) -> TypePredicateNode + +external object createLiteral { + @nativeInvoke + operator fun invoke(value: Any /* String | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier */): StringLiteral + @nativeInvoke + operator fun invoke(value: Any /* Number | PseudoBigInt */): NumericLiteral + @nativeInvoke + operator fun invoke(value: Boolean): dynamic /* TrueLiteral | FalseLiteral */ + @nativeInvoke + operator fun invoke(value: Any /* String | Number | PseudoBigInt | Boolean */): PrimaryExpression +} + +external var createMethodSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?) -> MethodSignature + +external var updateMethodSignature: (node: MethodSignature, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?) -> MethodSignature + +external object createTypeOperatorNode { + @nativeInvoke + operator fun invoke(type: TypeNode): TypeOperatorNode + @nativeInvoke + operator fun invoke(operator: Any /* SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword */, type: TypeNode): TypeOperatorNode +} + +external object createTaggedTemplate { + @nativeInvoke + operator fun invoke(tag: Expression, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression + @nativeInvoke + operator fun invoke(tag: Expression, typeArguments: Array?, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression +} + +external object updateTaggedTemplate { + @nativeInvoke + operator fun invoke(node: TaggedTemplateExpression, tag: Expression, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression + @nativeInvoke + operator fun invoke(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression +} + +external var updateBinary: (node: BinaryExpression, left: Expression, right: Expression, operator: dynamic /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */) -> BinaryExpression + +external object createConditional { + @nativeInvoke + operator fun invoke(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression + @nativeInvoke + operator fun invoke(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression +} + +external object createYield { + @nativeInvoke + operator fun invoke(expression: Expression? = definedExternally): YieldExpression + @nativeInvoke + operator fun invoke(asteriskToken: AsteriskToken?, expression: Expression): YieldExpression +} + +external var createClassExpression: (modifiers: Array?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassExpression + +external var updateClassExpression: (node: ClassExpression, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassExpression + +external var createPropertySignature: (modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | String */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> PropertySignature + +external var updatePropertySignature: (node: PropertySignature, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> PropertySignature + +external var createExpressionWithTypeArguments: (typeArguments: Array?, expression: Expression) -> ExpressionWithTypeArguments + +external var updateExpressionWithTypeArguments: (node: ExpressionWithTypeArguments, typeArguments: Array?, expression: Expression) -> ExpressionWithTypeArguments + +external object createArrowFunction { + @nativeInvoke + operator fun invoke(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: Any /* FunctionBody | Expression */): ArrowFunction + @nativeInvoke + operator fun invoke(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Any /* FunctionBody | Expression */): ArrowFunction +} + +external object updateArrowFunction { + @nativeInvoke + operator fun invoke(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: Any /* FunctionBody | Expression */): ArrowFunction + @nativeInvoke + operator fun invoke(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Any /* FunctionBody | Expression */): ArrowFunction +} + +external object createVariableDeclaration { + @nativeInvoke + operator fun invoke(name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, type: TypeNode? = definedExternally, initializer: Expression? = definedExternally): VariableDeclaration + @nativeInvoke + operator fun invoke(name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration +} + +external object updateVariableDeclaration { + @nativeInvoke + operator fun invoke(node: VariableDeclaration, name: Any /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, type: TypeNode?, initializer: Expression?): VariableDeclaration + @nativeInvoke + operator fun invoke(node: VariableDeclaration, name: Any /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration +} + +external var createImportClause: (name: Identifier?, namedBindings: dynamic /* NamespaceImport? | NamedImports? */, isTypeOnly: Any) -> ImportClause + +external var updateImportClause: (node: ImportClause, name: Identifier?, namedBindings: dynamic /* NamespaceImport? | NamedImports? */, isTypeOnly: Boolean) -> ImportClause + +external var createExportDeclaration: (decorators: Array?, modifiers: Array?, exportClause: dynamic /* NamespaceExport? | NamedExports? */, moduleSpecifier: Expression?, isTypeOnly: Any) -> ExportDeclaration + +external var updateExportDeclaration: (node: ExportDeclaration, decorators: Array?, modifiers: Array?, exportClause: dynamic /* NamespaceExport? | NamedExports? */, moduleSpecifier: Expression?, isTypeOnly: Boolean) -> ExportDeclaration + +external var createJSDocParamTag: (name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, comment: String?) -> JSDocParameterTag + +external var createComma: (left: Expression, right: Expression) -> Expression + +external var createLessThan: (left: Expression, right: Expression) -> Expression + +external var createAssignment: (left: Expression, right: Expression) -> BinaryExpression + +external var createStrictEquality: (left: Expression, right: Expression) -> BinaryExpression + +external var createStrictInequality: (left: Expression, right: Expression) -> BinaryExpression + +external var createAdd: (left: Expression, right: Expression) -> BinaryExpression + +external var createSubtract: (left: Expression, right: Expression) -> BinaryExpression + +external var createLogicalAnd: (left: Expression, right: Expression) -> BinaryExpression + +external var createLogicalOr: (left: Expression, right: Expression) -> BinaryExpression + +external var createPostfixIncrement: (operand: Expression) -> PostfixUnaryExpression + +external var createLogicalNot: (operand: Expression) -> PrefixUnaryExpression + +external var createNode: (kind: SyntaxKind, pos: Any, end: Any) -> Node + +external fun getMutableClone(node: T): T + +external var isTypeAssertion: (node: Node) -> Boolean + +external var isIdentifierOrPrivateIdentifier: (node: Node) -> Boolean diff --git a/externals02/typescript.ts.server.module_typescript.kt b/externals02/typescript.ts.server.module_typescript.kt new file mode 100644 index 0000000..5a84cb3 --- /dev/null +++ b/externals02/typescript.ts.server.module_typescript.kt @@ -0,0 +1,101 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package ts.server + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.CompilerOptions +import ts.WatchOptions +import ts.TypeAcquisition +import ts.SortedReadonlyArray + +external interface TypingInstallerResponse { + val kind: String /* "action::set" | "action::invalidate" | "event::typesRegistry" | "action::packageInstalled" | "event::beginInstallTypes" | "event::endInstallTypes" | "event::initializationFailed" */ +} + +external interface TypingInstallerRequestWithProjectName { + val projectName: String +} + +external interface DiscoverTypings : TypingInstallerRequestWithProjectName { + val fileNames: Array + val projectRootPath: String /* String & `T$3` */ + val compilerOptions: CompilerOptions + val watchOptions: WatchOptions? + get() = definedExternally + val typeAcquisition: TypeAcquisition + val unresolvedImports: SortedReadonlyArray + val cachePath: String? + get() = definedExternally + val kind: String /* "discover" */ +} + +external interface CloseProject : TypingInstallerRequestWithProjectName { + val kind: String /* "closeProject" */ +} + +external interface TypesRegistryRequest { + val kind: String /* "typesRegistry" */ +} + +external interface InstallPackageRequest : TypingInstallerRequestWithProjectName { + val kind: String /* "installPackage" */ + val fileName: String /* String & `T$3` */ + val packageName: String + val projectRootPath: String /* String & `T$3` */ +} + +external interface PackageInstalledResponse : ProjectResponse { + override val kind: String /* "action::packageInstalled" */ + val success: Boolean + val message: String +} + +external interface InitializationFailedResponse : TypingInstallerResponse { + override val kind: String /* "event::initializationFailed" */ + val message: String + val stack: String? + get() = definedExternally +} + +external interface ProjectResponse : TypingInstallerResponse { + val projectName: String +} + +external interface InvalidateCachedTypings : ProjectResponse { + override val kind: String /* "action::invalidate" */ +} + +external interface InstallTypes : ProjectResponse { + override val kind: String /* "event::beginInstallTypes" | "event::endInstallTypes" */ + val eventId: Number + val typingsInstallerVersion: String + val packagesToInstall: Array +} + +external interface BeginInstallTypes : InstallTypes { + override val kind: String /* "event::beginInstallTypes" */ +} + +external interface EndInstallTypes : InstallTypes { + override val kind: String /* "event::endInstallTypes" */ + val installSuccess: Boolean +} + +external interface SetTypings : ProjectResponse { + val typeAcquisition: TypeAcquisition + val compilerOptions: CompilerOptions + val typings: Array + val unresolvedImports: SortedReadonlyArray + override val kind: String /* "action::set" */ +} \ No newline at end of file diff --git a/externals02/utils.module_typescript-to-lua.kt b/externals02/utils.module_typescript-to-lua.kt new file mode 100644 index 0000000..08363d8 --- /dev/null +++ b/externals02/utils.module_typescript-to-lua.kt @@ -0,0 +1,46 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.WriteFileCallback +import ts.SourceFile + +external interface EmitHost { + fun directoryExists(path: String): Boolean + fun fileExists(path: String): Boolean + fun getCurrentDirectory(): String + fun readFile(path: String): String? + var writeFile: WriteFileCallback +} + +external interface BaseFile { + var code: String + var sourceMap: String? + get() = definedExternally + set(value) = definedExternally + var sourceFiles: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface ProcessedFile : BaseFile { + var fileName: String + var luaAst: File? + get() = definedExternally + set(value) = definedExternally +} + +external interface EmitFile : BaseFile { + var outputPath: String +} \ No newline at end of file diff --git a/externals02/visitors.module_typescript-to-lua.kt b/externals02/visitors.module_typescript-to-lua.kt new file mode 100644 index 0000000..69513ac --- /dev/null +++ b/externals02/visitors.module_typescript-to-lua.kt @@ -0,0 +1,38 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.Statement +import ts.Node +import tsstdlib.Map +import ts.SyntaxKind + +external interface NodesBySyntaxKind + +typealias StatementLikeNode = Statement + +typealias VisitorResult = Any + +typealias FunctionVisitor = (node: T, context: TransformationContext) -> VisitorResult + +external interface ObjectVisitor { + var transform: FunctionVisitor + var priority: Number? + get() = definedExternally + set(value) = definedExternally +} + +typealias Visitors = Any + +typealias VisitorMap = Map>> \ No newline at end of file diff --git a/externals03/CompilerOptions.module_typescript-to-lua.kt b/externals03/CompilerOptions.module_typescript-to-lua.kt new file mode 100644 index 0000000..aa83510 --- /dev/null +++ b/externals03/CompilerOptions.module_typescript-to-lua.kt @@ -0,0 +1,74 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.Diagnostic + +typealias OmitIndexSignature = Any + +external interface TransformerImport { + var transform: String + var import: String? + get() = definedExternally + set(value) = definedExternally + var after: Boolean? + get() = definedExternally + set(value) = definedExternally + var afterDeclarations: Boolean? + get() = definedExternally + set(value) = definedExternally + var type: String? /* "program" | "config" | "checker" | "raw" | "compilerOptions" */ + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): Any? + @nativeSetter + operator fun set(option: String, value: Any) +} + +external interface LuaPluginImport { + var name: String + var import: String? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): Any? + @nativeSetter + operator fun set(option: String, value: Any) +} + +external enum class LuaLibImportKind { + None /* = "none" */, + Always /* = "always" */, + Inline /* = "inline" */, + Require /* = "require" */ +} + +external enum class LuaTarget { + Universal /* = "universal" */, + Lua51 /* = "5.1" */, + Lua52 /* = "5.2" */, + Lua53 /* = "5.3" */, + Lua54 /* = "5.4" */, + LuaJIT /* = "JIT" */ +} + +external enum class BuildMode { + Default /* = "default" */, + Library /* = "library" */ +} + +external var isBundleEnabled: (options: dynamic /* typealias OmitIndexSignature = dynamic */) -> Boolean + +external fun validateOptions(options: dynamic /* typealias OmitIndexSignature = dynamic */): Array \ No newline at end of file diff --git a/externals03/LuaAST.module_typescript-to-lua.kt b/externals03/LuaAST.module_typescript-to-lua.kt new file mode 100644 index 0000000..079e37f --- /dev/null +++ b/externals03/LuaAST.module_typescript-to-lua.kt @@ -0,0 +1,485 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import tsstdlib.Set + +external enum class SyntaxKind { + File /* = 0 */, + Block /* = 1 */, + DoStatement /* = 2 */, + VariableDeclarationStatement /* = 3 */, + AssignmentStatement /* = 4 */, + IfStatement /* = 5 */, + WhileStatement /* = 6 */, + RepeatStatement /* = 7 */, + ForStatement /* = 8 */, + ForInStatement /* = 9 */, + GotoStatement /* = 10 */, + LabelStatement /* = 11 */, + ReturnStatement /* = 12 */, + BreakStatement /* = 13 */, + ExpressionStatement /* = 14 */, + StringLiteral /* = 15 */, + NumericLiteral /* = 16 */, + NilKeyword /* = 17 */, + DotsKeyword /* = 18 */, + TrueKeyword /* = 19 */, + FalseKeyword /* = 20 */, + FunctionExpression /* = 21 */, + TableFieldExpression /* = 22 */, + TableExpression /* = 23 */, + UnaryExpression /* = 24 */, + BinaryExpression /* = 25 */, + CallExpression /* = 26 */, + MethodCallExpression /* = 27 */, + Identifier /* = 28 */, + TableIndexExpression /* = 29 */, + AdditionOperator /* = 30 */, + SubtractionOperator /* = 31 */, + MultiplicationOperator /* = 32 */, + DivisionOperator /* = 33 */, + FloorDivisionOperator /* = 34 */, + ModuloOperator /* = 35 */, + PowerOperator /* = 36 */, + NegationOperator /* = 37 */, + ConcatOperator /* = 38 */, + LengthOperator /* = 39 */, + EqualityOperator /* = 40 */, + InequalityOperator /* = 41 */, + LessThanOperator /* = 42 */, + LessEqualOperator /* = 43 */, + GreaterThanOperator /* = 44 */, + GreaterEqualOperator /* = 45 */, + AndOperator /* = 46 */, + OrOperator /* = 47 */, + NotOperator /* = 48 */, + BitwiseAndOperator /* = 49 */, + BitwiseOrOperator /* = 50 */, + BitwiseExclusiveOrOperator /* = 51 */, + BitwiseRightShiftOperator /* = 52 */, + BitwiseLeftShiftOperator /* = 53 */, + BitwiseNotOperator /* = 54 */ +} + +typealias UnaryBitwiseOperator = SyntaxKind.BitwiseNotOperator + +external interface TextRange { + var line: Number? + get() = definedExternally + set(value) = definedExternally + var column: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface Node : TextRange { + var kind: SyntaxKind +} + +external fun createNode(kind: SyntaxKind, tsOriginal: ts.Node = definedExternally): Node + +external fun cloneNode(node: T): T + +external fun setNodePosition(node: T, position: TextRange): T + +external fun setNodeOriginal(node: T, tsOriginal: ts.Node): T + +external fun setNodeOriginal(node: T?, tsOriginal: ts.Node): T? + +external fun getOriginalPos(node: Node): TextRange + +external interface File : Node { + var statements: Array + var luaLibFeatures: Set + var trivia: String +} + +external fun isFile(node: Node): Boolean + +external fun createFile(statements: Array, luaLibFeatures: Set, trivia: String, tsOriginal: ts.Node = definedExternally): File + +external interface Block : Node { + var statements: Array +} + +external fun isBlock(node: Node): Boolean + +external fun createBlock(statements: Array, tsOriginal: ts.Node = definedExternally): Block + +external interface Statement : Node { + var _statementBrand: Any + var leadingComments: Array */>? + get() = definedExternally + set(value) = definedExternally + var trailingComments: Array */>? + get() = definedExternally + set(value) = definedExternally +} + +external interface DoStatement : Statement { + var statements: Array +} + +external fun isDoStatement(node: Node): Boolean + +external fun createDoStatement(statements: Array, tsOriginal: ts.Node = definedExternally): DoStatement + +external interface VariableDeclarationStatement : Statement { + var left: Array + var right: Array? + get() = definedExternally + set(value) = definedExternally +} + +external fun isVariableDeclarationStatement(node: Node): Boolean + +external fun createVariableDeclarationStatement(left: Identifier, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Identifier): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Identifier, right: Expression = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Identifier, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Identifier, right: Array = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array, right: Expression = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array, right: Array = definedExternally): VariableDeclarationStatement + +external interface AssignmentStatement : Statement { + var left: Array + var right: Array +} + +external fun isAssignmentStatement(node: Node): Boolean + +external fun createAssignmentStatement(left: Identifier, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Identifier): AssignmentStatement + +external fun createAssignmentStatement(left: Identifier, right: Expression = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Identifier, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Identifier, right: Array = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression, right: Expression = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression, right: Array = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Array, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Array): AssignmentStatement + +external fun createAssignmentStatement(left: Array, right: Expression = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Array, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Array, right: Array = definedExternally): AssignmentStatement + +external interface IfStatement : Statement { + var condition: Expression + var ifBlock: Block + var elseBlock: dynamic /* Block? | IfStatement? */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isIfStatement(node: Node): Boolean + +external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: Block = definedExternally, tsOriginal: ts.Node = definedExternally): IfStatement + +external fun createIfStatement(condition: Expression, ifBlock: Block): IfStatement + +external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: Block = definedExternally): IfStatement + +external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: IfStatement = definedExternally, tsOriginal: ts.Node = definedExternally): IfStatement + +external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: IfStatement = definedExternally): IfStatement + +external interface IterationStatement : Statement { + var body: Block +} + +external fun isIterationStatement(node: Node): Boolean + +external interface WhileStatement : IterationStatement { + var condition: Expression +} + +external fun isWhileStatement(node: Node): Boolean + +external fun createWhileStatement(body: Block, condition: Expression, tsOriginal: ts.Node = definedExternally): WhileStatement + +external interface RepeatStatement : IterationStatement { + var condition: Expression +} + +external fun isRepeatStatement(node: Node): Boolean + +external fun createRepeatStatement(body: Block, condition: Expression, tsOriginal: ts.Node = definedExternally): RepeatStatement + +external interface ForStatement : IterationStatement { + var controlVariable: Identifier + var controlVariableInitializer: Expression + var limitExpression: Expression + var stepExpression: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external fun isForStatement(node: Node): Boolean + +external fun createForStatement(body: Block, controlVariable: Identifier, controlVariableInitializer: Expression, limitExpression: Expression, stepExpression: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): ForStatement + +external interface ForInStatement : IterationStatement { + var names: Array + var expressions: Array +} + +external fun isForInStatement(node: Node): Boolean + +external fun createForInStatement(body: Block, names: Array, expressions: Array, tsOriginal: ts.Node = definedExternally): ForInStatement + +external interface GotoStatement : Statement { + var label: String +} + +external fun isGotoStatement(node: Node): Boolean + +external fun createGotoStatement(label: String, tsOriginal: ts.Node = definedExternally): GotoStatement + +external interface LabelStatement : Statement { + var name: String +} + +external fun isLabelStatement(node: Node): Boolean + +external fun createLabelStatement(name: String, tsOriginal: ts.Node = definedExternally): LabelStatement + +external interface ReturnStatement : Statement { + var expressions: Array +} + +external fun isReturnStatement(node: Node): Boolean + +external fun createReturnStatement(expressions: Array, tsOriginal: ts.Node = definedExternally): ReturnStatement + +external interface BreakStatement : Statement + +external fun isBreakStatement(node: Node): Boolean + +external fun createBreakStatement(tsOriginal: ts.Node = definedExternally): BreakStatement + +external interface ExpressionStatement : Statement { + var expression: Expression +} + +external fun isExpressionStatement(node: Node): Boolean + +external fun createExpressionStatement(expressions: Expression, tsOriginal: ts.Node = definedExternally): ExpressionStatement + +external interface Expression : Node { + var _expressionBrand: Any +} + +external interface NilLiteral : Expression + +external fun isNilLiteral(node: Node): Boolean + +external fun createNilLiteral(tsOriginal: ts.Node = definedExternally): NilLiteral + +external interface BooleanLiteral : Expression { + override var kind: dynamic /* SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isBooleanLiteral(node: Node): Boolean + +external fun createBooleanLiteral(value: Boolean, tsOriginal: ts.Node = definedExternally): BooleanLiteral + +external interface DotsLiteral : Expression + +external fun isDotsLiteral(node: Node): Boolean + +external fun createDotsLiteral(tsOriginal: ts.Node = definedExternally): DotsLiteral + +external interface NumericLiteral : Expression { + var value: Number +} + +external fun isNumericLiteral(node: Node): Boolean + +external fun createNumericLiteral(value: Number, tsOriginal: ts.Node = definedExternally): NumericLiteral + +external interface StringLiteral : Expression { + var value: String +} + +external fun isStringLiteral(node: Node): Boolean + +external fun createStringLiteral(value: String, tsOriginal: ts.Node = definedExternally): StringLiteral + +external enum class FunctionExpressionFlags { + None /* = 1 */, + Inline /* = 2 */, + Declaration /* = 4 */ +} + +external interface FunctionExpression : Expression { + var params: Array? + get() = definedExternally + set(value) = definedExternally + var dots: DotsLiteral? + get() = definedExternally + set(value) = definedExternally + var body: Block + var flags: FunctionExpressionFlags +} + +external fun isFunctionExpression(node: Node): Boolean + +external fun createFunctionExpression(body: Block, params: Array = definedExternally, dots: DotsLiteral = definedExternally, flags: FunctionExpressionFlags = definedExternally, tsOriginal: ts.Node = definedExternally): FunctionExpression + +external interface TableFieldExpression : Expression { + var value: Expression + var key: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external fun isTableFieldExpression(node: Node): Boolean + +external fun createTableFieldExpression(value: Expression, key: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): TableFieldExpression + +external interface TableExpression : Expression { + var fields: Array +} + +external fun isTableExpression(node: Node): Boolean + +external fun createTableExpression(fields: Array = definedExternally, tsOriginal: ts.Node = definedExternally): TableExpression + +external interface UnaryExpression : Expression { + var operand: Expression + var operator: dynamic /* SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isUnaryExpression(node: Node): Boolean + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NegationOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NegationOperator): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.LengthOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.LengthOperator): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NotOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NotOperator): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: UnaryBitwiseOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: UnaryBitwiseOperator): UnaryExpression + +external interface BinaryExpression : Expression { + var operator: dynamic /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */ + get() = definedExternally + set(value) = definedExternally + var left: Expression + var right: Expression +} + +external fun isBinaryExpression(node: Node): Boolean + +external fun createBinaryExpression(left: Expression, right: Expression, operator: Any /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */, tsOriginal: ts.Node = definedExternally): BinaryExpression + +external interface CallExpression : Expression { + var expression: Expression + var params: Array +} + +external fun isCallExpression(node: Node): Boolean + +external fun createCallExpression(expression: Expression, params: Array, tsOriginal: ts.Node = definedExternally): CallExpression + +external interface MethodCallExpression : Expression { + var prefixExpression: Expression + var name: Identifier + var params: Array +} + +external fun isMethodCallExpression(node: Node): Boolean + +external fun createMethodCallExpression(prefixExpression: Expression, name: Identifier, params: Array, tsOriginal: ts.Node = definedExternally): MethodCallExpression + +external interface Identifier : Expression { + var exportable: Boolean + var text: String + var originalName: String? + get() = definedExternally + set(value) = definedExternally + var symbolId: Number? /* Number? & `T$14`? */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isIdentifier(node: Node): Boolean + +external fun createIdentifier(text: String, tsOriginal: ts.Node = definedExternally, symbolId: Number /* Number & `T$14` */ = definedExternally, originalName: String = definedExternally): Identifier + +external fun cloneIdentifier(identifier: Identifier, tsOriginal: ts.Node = definedExternally): Identifier + +external fun createAnonymousIdentifier(tsOriginal: ts.Node = definedExternally): Identifier + +external interface TableIndexExpression : Expression { + var table: Expression + var index: Expression +} + +external fun isTableIndexExpression(node: Node): Boolean + +external fun createTableIndexExpression(table: Expression, index: Expression, tsOriginal: ts.Node = definedExternally): TableIndexExpression + +external fun isAssignmentLeftHandSideExpression(node: Node): Boolean + +external fun isFunctionDefinition(statement: VariableDeclarationStatement): Boolean + +external fun isFunctionDefinition(statement: AssignmentStatement): Boolean + +external interface `T$17` { + var statements: dynamic /* JsTuple */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isInlineFunctionExpression(expression: FunctionExpression): Boolean \ No newline at end of file diff --git a/externals03/LuaLib.module_typescript-to-lua.kt b/externals03/LuaLib.module_typescript-to-lua.kt new file mode 100644 index 0000000..f00c242 --- /dev/null +++ b/externals03/LuaLib.module_typescript-to-lua.kt @@ -0,0 +1,111 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external enum class LuaLibFeature { + ArrayConcat /* = "ArrayConcat" */, + ArrayEntries /* = "ArrayEntries" */, + ArrayEvery /* = "ArrayEvery" */, + ArrayFilter /* = "ArrayFilter" */, + ArrayForEach /* = "ArrayForEach" */, + ArrayFind /* = "ArrayFind" */, + ArrayFindIndex /* = "ArrayFindIndex" */, + ArrayIncludes /* = "ArrayIncludes" */, + ArrayIndexOf /* = "ArrayIndexOf" */, + ArrayIsArray /* = "ArrayIsArray" */, + ArrayJoin /* = "ArrayJoin" */, + ArrayMap /* = "ArrayMap" */, + ArrayPush /* = "ArrayPush" */, + ArrayReduce /* = "ArrayReduce" */, + ArrayReduceRight /* = "ArrayReduceRight" */, + ArrayReverse /* = "ArrayReverse" */, + ArrayShift /* = "ArrayShift" */, + ArrayUnshift /* = "ArrayUnshift" */, + ArraySort /* = "ArraySort" */, + ArraySlice /* = "ArraySlice" */, + ArraySome /* = "ArraySome" */, + ArraySplice /* = "ArraySplice" */, + ArrayToObject /* = "ArrayToObject" */, + ArrayFlat /* = "ArrayFlat" */, + ArrayFlatMap /* = "ArrayFlatMap" */, + ArraySetLength /* = "ArraySetLength" */, + Await /* = "Await" */, + Class /* = "Class" */, + ClassExtends /* = "ClassExtends" */, + CloneDescriptor /* = "CloneDescriptor" */, + Decorate /* = "Decorate" */, + DecorateParam /* = "DecorateParam" */, + Delete /* = "Delete" */, + DelegatedYield /* = "DelegatedYield" */, + Error /* = "Error" */, + FunctionBind /* = "FunctionBind" */, + Generator /* = "Generator" */, + InstanceOf /* = "InstanceOf" */, + InstanceOfObject /* = "InstanceOfObject" */, + Iterator /* = "Iterator" */, + Map /* = "Map" */, + MathAtan2 /* = "MathAtan2" */, + New /* = "New" */, + Number /* = "Number" */, + NumberIsFinite /* = "NumberIsFinite" */, + NumberIsNaN /* = "NumberIsNaN" */, + NumberToString /* = "NumberToString" */, + ObjectAssign /* = "ObjectAssign" */, + ObjectDefineProperty /* = "ObjectDefineProperty" */, + ObjectEntries /* = "ObjectEntries" */, + ObjectFromEntries /* = "ObjectFromEntries" */, + ObjectGetOwnPropertyDescriptor /* = "ObjectGetOwnPropertyDescriptor" */, + ObjectGetOwnPropertyDescriptors /* = "ObjectGetOwnPropertyDescriptors" */, + ObjectKeys /* = "ObjectKeys" */, + ObjectRest /* = "ObjectRest" */, + ObjectValues /* = "ObjectValues" */, + OptionalChainAccess /* = "OptionalChainAccess" */, + OptionalFunctionCall /* = "OptionalFunctionCall" */, + OptionalMethodCall /* = "OptionalMethodCall" */, + ParseFloat /* = "ParseFloat" */, + ParseInt /* = "ParseInt" */, + Promise /* = "Promise" */, + PromiseAll /* = "PromiseAll" */, + PromiseAllSettled /* = "PromiseAllSettled" */, + PromiseAny /* = "PromiseAny" */, + PromiseRace /* = "PromiseRace" */, + Set /* = "Set" */, + SetDescriptor /* = "SetDescriptor" */, + WeakMap /* = "WeakMap" */, + WeakSet /* = "WeakSet" */, + SourceMapTraceBack /* = "SourceMapTraceBack" */, + Spread /* = "Spread" */, + StringAccess /* = "StringAccess" */, + StringCharAt /* = "StringCharAt" */, + StringCharCodeAt /* = "StringCharCodeAt" */, + StringConcat /* = "StringConcat" */, + StringEndsWith /* = "StringEndsWith" */, + StringIncludes /* = "StringIncludes" */, + StringPadEnd /* = "StringPadEnd" */, + StringPadStart /* = "StringPadStart" */, + StringReplace /* = "StringReplace" */, + StringSlice /* = "StringSlice" */, + StringSplit /* = "StringSplit" */, + StringStartsWith /* = "StringStartsWith" */, + StringSubstr /* = "StringSubstr" */, + StringSubstring /* = "StringSubstring" */, + StringTrim /* = "StringTrim" */, + StringTrimEnd /* = "StringTrimEnd" */, + StringTrimStart /* = "StringTrimStart" */, + Symbol /* = "Symbol" */, + SymbolRegistry /* = "SymbolRegistry" */, + TypeOf /* = "TypeOf" */, + Unpack /* = "Unpack" */ +} \ No newline at end of file diff --git a/externals03/LuaPrinter.module_typescript-to-lua.kt b/externals03/LuaPrinter.module_typescript-to-lua.kt new file mode 100644 index 0000000..6428653 --- /dev/null +++ b/externals03/LuaPrinter.module_typescript-to-lua.kt @@ -0,0 +1,101 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.Program + +external var escapeString: (value: String) -> String + +external var tstlHeader: Any + +typealias Printer = (program: Program, emitHost: EmitHost, fileName: String, file: File) -> PrintResult + +external interface PrintResult { + var code: String + var sourceMap: String + var sourceMapNode: SourceNode +} + +external fun createPrinter(printers: Array): Printer + +external open class LuaPrinter(emitHost: EmitHost, program: Program, fileName: String) { + open var emitHost: Any + open var currentIndent: Any + open var sourceFile: Any + open var options: Any + open fun print(file: File): PrintResult + open var printInlineSourceMap: Any + open var printStackTraceOverride: Any + open var printFile: Any + open fun pushIndent() + open fun popIndent() + open fun indent(input: String = definedExternally): dynamic /* String | SourceNode */ + open fun indent(): dynamic /* String | SourceNode */ + open fun indent(input: SourceNode = definedExternally): dynamic /* String | SourceNode */ + open fun createSourceNode(node: Node, chunks: String, name: String = definedExternally): SourceNode + open fun createSourceNode(node: Node, chunks: String): SourceNode + open fun createSourceNode(node: Node, chunks: SourceNode, name: String = definedExternally): SourceNode + open fun createSourceNode(node: Node, chunks: SourceNode): SourceNode + open fun createSourceNode(node: Node, chunks: Array, name: String = definedExternally): SourceNode + open fun createSourceNode(node: Node, chunks: Array): SourceNode + open fun concatNodes(vararg chunks: Any /* String | SourceNode */): SourceNode + open fun printBlock(block: Block): SourceNode + open var statementMayRequireSemiColon: Any + open var nodeStartsWithParenthesis: Any + open fun printStatementArray(statements: Array): Array + open fun printStatement(statement: Statement): SourceNode + open fun printComment(comment: String): dynamic /* String | SourceNode */ + open fun printComment(comment: Array): dynamic /* String | SourceNode */ + open fun printStatementExcludingComments(statement: Statement): SourceNode + open fun printDoStatement(statement: DoStatement): SourceNode + open fun printVariableDeclarationStatement(statement: VariableDeclarationStatement): SourceNode + open fun printVariableAssignmentStatement(statement: AssignmentStatement): SourceNode + open fun printIfStatement(statement: IfStatement, isElseIf: Boolean = definedExternally): SourceNode + open fun printWhileStatement(statement: WhileStatement): SourceNode + open fun printRepeatStatement(statement: RepeatStatement): SourceNode + open fun printForStatement(statement: ForStatement): SourceNode + open fun printForInStatement(statement: ForInStatement): SourceNode + open fun printGotoStatement(statement: GotoStatement): SourceNode + open fun printLabelStatement(statement: LabelStatement): SourceNode + open fun printReturnStatement(statement: ReturnStatement): SourceNode + open fun printBreakStatement(statement: BreakStatement): SourceNode + open fun printExpressionStatement(statement: ExpressionStatement): SourceNode + open fun printExpression(expression: Expression): SourceNode + open fun printStringLiteral(expression: StringLiteral): SourceNode + open fun printNumericLiteral(expression: NumericLiteral): SourceNode + open fun printNilLiteral(expression: NilLiteral): SourceNode + open fun printDotsLiteral(expression: DotsLiteral): SourceNode + open fun printBooleanLiteral(expression: BooleanLiteral): SourceNode + open var printFunctionParameters: Any + open fun printFunctionExpression(expression: FunctionExpression): SourceNode + open fun printFunctionDefinition(statement: Any /* VariableDeclarationStatement | AssignmentStatement */): SourceNode + open fun printTableFieldExpression(expression: TableFieldExpression): SourceNode + open fun printTableExpression(expression: TableExpression): SourceNode + open fun printUnaryExpression(expression: UnaryExpression): SourceNode + open fun printBinaryExpression(expression: BinaryExpression): SourceNode + open var printExpressionInParenthesesIfNeeded: Any + open var needsParenthesis: Any + open fun printCallExpression(expression: CallExpression): SourceNode + open fun printMethodCallExpression(expression: MethodCallExpression): SourceNode + open fun printIdentifier(expression: Identifier): SourceNode + open fun printTableIndexExpression(expression: TableIndexExpression): SourceNode + open fun printOperator(kind: Any /* SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator | SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */): SourceNode + open fun joinChunksWithComma(chunks: Array): Array + open fun printExpressionList(expressions: Array): Array + open var buildSourceMap: Any + + companion object { + var operatorMap: Any + } +} \ No newline at end of file diff --git a/externals03/context.module_typescript-to-lua.kt b/externals03/context.module_typescript-to-lua.kt new file mode 100644 index 0000000..696e339 --- /dev/null +++ b/externals03/context.module_typescript-to-lua.kt @@ -0,0 +1,79 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.GetAccessorDeclaration +import ts.SetAccessorDeclaration +import ts.Node +import ts.ImportEqualsDeclaration +import ts.Expression +import ts.SourceFile +import ts.CancellationToken +import ts.TypeChecker +import ts.Program +import ts.Diagnostic +import Node as _Node +import Expression as _Expression +import ts.QualifiedName +import ts.ExternalModuleReference + +external interface AllAccessorDeclarations { + var firstAccessor: dynamic /* GetAccessorDeclaration | SetAccessorDeclaration */ + get() = definedExternally + set(value) = definedExternally + var secondAccessor: dynamic /* GetAccessorDeclaration? | SetAccessorDeclaration? */ + get() = definedExternally + set(value) = definedExternally + var getAccessor: GetAccessorDeclaration? + var setAccessor: SetAccessorDeclaration? +} + +external interface EmitResolver { + fun isValueAliasDeclaration(node: Node): Boolean + fun isReferencedAliasDeclaration(node: Node, checkChildren: Boolean = definedExternally): Boolean + fun isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): Boolean + fun moduleExportsSomeValue(moduleReferenceExpression: Expression): Boolean + fun getAllAccessorDeclarations(declaration: GetAccessorDeclaration): AllAccessorDeclarations + fun getAllAccessorDeclarations(declaration: SetAccessorDeclaration): AllAccessorDeclarations +} + +external interface DiagnosticsProducingTypeChecker : TypeChecker { + fun getEmitResolver(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): EmitResolver +} + +external open class TransformationContext(program: Program, sourceFile: SourceFile, visitorMap: VisitorMap) { + open var program: Program + open var sourceFile: SourceFile + open var visitorMap: Any + open val diagnostics: Array + open val checker: DiagnosticsProducingTypeChecker + open val resolver: EmitResolver + open val options: dynamic /* typealias OmitIndexSignature = dynamic */ + open val luaTarget: LuaTarget + open val isModule: Boolean + open val isStrict: Boolean + open var currentNodeVisitors: Any + open fun transformNode(node: Node): Array<_Node> + open fun superTransformNode(node: Node): Array<_Node> + open fun transformExpression(node: Expression): _Expression + open fun transformExpression(node: QualifiedName): _Expression + open fun transformExpression(node: ExternalModuleReference): _Expression + open fun superTransformExpression(node: Expression): _Expression + open fun superTransformExpression(node: QualifiedName): _Expression + open fun superTransformExpression(node: ExternalModuleReference): _Expression + open fun transformStatements(node: StatementLikeNode): Array + open fun transformStatements(node: Array): Array + open fun superTransformStatements(node: StatementLikeNode): Array + open fun superTransformStatements(node: Array): Array +} \ No newline at end of file diff --git a/externals03/index.module_typescript-to-lua.kt b/externals03/index.module_typescript-to-lua.kt new file mode 100644 index 0000000..2016698 --- /dev/null +++ b/externals03/index.module_typescript-to-lua.kt @@ -0,0 +1,38 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.WriteFileCallback +import ts.Diagnostic +import tsstdlib.Record + +external fun transpileFiles(rootNames: Array, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, writeFile: WriteFileCallback = definedExternally): EmitResult + +external fun transpileProject(configFileName: String, optionsToExtend: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, writeFile: WriteFileCallback = definedExternally): EmitResult + +external interface TranspileVirtualProjectResult { + var diagnostics: Array + var transpiledFiles: Array +} + +external fun transpileVirtualProject(files: Record, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally): TranspileVirtualProjectResult + +external interface TranspileStringResult { + var diagnostics: Array + var file: TranspiledFile? + get() = definedExternally + set(value) = definedExternally +} + +external fun transpileString(main: String, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally): TranspileStringResult \ No newline at end of file diff --git a/externals03/lib.es2015.collection.kt b/externals03/lib.es2015.collection.kt new file mode 100644 index 0000000..affffa8 --- /dev/null +++ b/externals03/lib.es2015.collection.kt @@ -0,0 +1,49 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface Map { + fun entries(): IterableIterator */> + fun keys(): IterableIterator + fun values(): IterableIterator + fun clear() + fun delete(key: K): Boolean + fun forEach(callbackfn: (value: V, key: K, map: Map) -> Unit, thisArg: Any = definedExternally) + fun get(key: K): V? + fun has(key: K): Boolean + fun set(key: K, value: V): Map /* this */ + val size: Number +} + +external interface MapConstructor { + val prototype: Map +} + +external interface Set { + fun entries(): IterableIterator */> + fun keys(): IterableIterator + fun values(): IterableIterator + fun add(value: T): Set /* this */ + fun clear() + fun delete(value: T): Boolean + fun forEach(callbackfn: (value: T, value2: T, set: Set) -> Unit, thisArg: Any = definedExternally) + fun has(value: T): Boolean + val size: Number +} + +external interface SetConstructor { + val prototype: Set +} \ No newline at end of file diff --git a/externals03/lib.es2015.iterable.kt b/externals03/lib.es2015.iterable.kt new file mode 100644 index 0000000..1528efa --- /dev/null +++ b/externals03/lib.es2015.iterable.kt @@ -0,0 +1,54 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface IteratorYieldResult { + var done: Boolean? + get() = definedExternally + set(value) = definedExternally + var value: TYield +} + +external interface IteratorReturnResult { + var done: Boolean + var value: TReturn +} + +external interface Iterator { + fun next(vararg args: Any /* JsTuple<> | JsTuple */): dynamic /* IteratorYieldResult | IteratorReturnResult */ + val `return`: ((value: TReturn) -> dynamic)? + val `throw`: ((e: Any) -> dynamic)? +} + +typealias Iterator__1 = Iterator + +external interface Iterable + +external interface IterableIterator : Iterator__1 + +external interface PromiseConstructor { + val prototype: Promise + fun all(values: Any /* JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple */): Promise | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple */> + fun all(values: Array */>): Promise> + fun race(values: Array): Promise + fun reject(reason: Any = definedExternally): Promise + fun resolve(value: T): Promise + fun resolve(value: PromiseLike): Promise + fun resolve(): Promise + fun all(values: Iterable */>): Promise> + fun race(values: Iterable): Promise + fun race(values: Iterable */>): Promise +} \ No newline at end of file diff --git a/externals03/lib.es5.Intl.module_dukat.kt b/externals03/lib.es5.Intl.module_dukat.kt new file mode 100644 index 0000000..62cbcc7 --- /dev/null +++ b/externals03/lib.es5.Intl.module_dukat.kt @@ -0,0 +1,220 @@ +@file:JsQualifier("tsstdlib.Intl") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib.Intl + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface CollatorOptions { + var usage: String? + get() = definedExternally + set(value) = definedExternally + var localeMatcher: String? + get() = definedExternally + set(value) = definedExternally + var numeric: Boolean? + get() = definedExternally + set(value) = definedExternally + var caseFirst: String? + get() = definedExternally + set(value) = definedExternally + var sensitivity: String? + get() = definedExternally + set(value) = definedExternally + var ignorePunctuation: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedCollatorOptions { + var locale: String + var usage: String + var sensitivity: String + var ignorePunctuation: Boolean + var collation: String + var caseFirst: String + var numeric: Boolean +} + +@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface Collator { + fun compare(x: String, y: String): Number + fun resolvedOptions(): ResolvedCollatorOptions + + companion object { + @nativeInvoke + operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: CollatorOptions = definedExternally): Collator + fun supportedLocalesOf(locales: Any /* String | Array */, options: CollatorOptions = definedExternally): Array + } +} + +external interface NumberFormatOptions { + var localeMatcher: String? + get() = definedExternally + set(value) = definedExternally + var style: String? + get() = definedExternally + set(value) = definedExternally + var currency: String? + get() = definedExternally + set(value) = definedExternally + var currencyDisplay: String? + get() = definedExternally + set(value) = definedExternally + var useGrouping: Boolean? + get() = definedExternally + set(value) = definedExternally + var minimumIntegerDigits: Number? + get() = definedExternally + set(value) = definedExternally + var minimumFractionDigits: Number? + get() = definedExternally + set(value) = definedExternally + var maximumFractionDigits: Number? + get() = definedExternally + set(value) = definedExternally + var minimumSignificantDigits: Number? + get() = definedExternally + set(value) = definedExternally + var maximumSignificantDigits: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedNumberFormatOptions { + var locale: String + var numberingSystem: String + var style: String + var currency: String? + get() = definedExternally + set(value) = definedExternally + var currencyDisplay: String? + get() = definedExternally + set(value) = definedExternally + var minimumIntegerDigits: Number + var minimumFractionDigits: Number + var maximumFractionDigits: Number + var minimumSignificantDigits: Number? + get() = definedExternally + set(value) = definedExternally + var maximumSignificantDigits: Number? + get() = definedExternally + set(value) = definedExternally + var useGrouping: Boolean +} + +@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface NumberFormat { + fun format(value: Number): String + fun resolvedOptions(): ResolvedNumberFormatOptions + + companion object { + @nativeInvoke + operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: NumberFormatOptions = definedExternally): NumberFormat + fun supportedLocalesOf(locales: Any /* String | Array */, options: NumberFormatOptions = definedExternally): Array + } +} + +external interface DateTimeFormatOptions { + var localeMatcher: String? + get() = definedExternally + set(value) = definedExternally + var weekday: String? + get() = definedExternally + set(value) = definedExternally + var era: String? + get() = definedExternally + set(value) = definedExternally + var year: String? + get() = definedExternally + set(value) = definedExternally + var month: String? + get() = definedExternally + set(value) = definedExternally + var day: String? + get() = definedExternally + set(value) = definedExternally + var hour: String? + get() = definedExternally + set(value) = definedExternally + var minute: String? + get() = definedExternally + set(value) = definedExternally + var second: String? + get() = definedExternally + set(value) = definedExternally + var timeZoneName: String? + get() = definedExternally + set(value) = definedExternally + var formatMatcher: String? + get() = definedExternally + set(value) = definedExternally + var hour12: Boolean? + get() = definedExternally + set(value) = definedExternally + var timeZone: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedDateTimeFormatOptions { + var locale: String + var calendar: String + var numberingSystem: String + var timeZone: String + var hour12: Boolean? + get() = definedExternally + set(value) = definedExternally + var weekday: String? + get() = definedExternally + set(value) = definedExternally + var era: String? + get() = definedExternally + set(value) = definedExternally + var year: String? + get() = definedExternally + set(value) = definedExternally + var month: String? + get() = definedExternally + set(value) = definedExternally + var day: String? + get() = definedExternally + set(value) = definedExternally + var hour: String? + get() = definedExternally + set(value) = definedExternally + var minute: String? + get() = definedExternally + set(value) = definedExternally + var second: String? + get() = definedExternally + set(value) = definedExternally + var timeZoneName: String? + get() = definedExternally + set(value) = definedExternally +} + +@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface DateTimeFormat { + fun format(date: Date = definedExternally): String + fun format(): String + fun format(date: Number = definedExternally): String + fun resolvedOptions(): ResolvedDateTimeFormatOptions + + companion object { + @nativeInvoke + operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: DateTimeFormatOptions = definedExternally): DateTimeFormat + fun supportedLocalesOf(locales: Any /* String | Array */, options: DateTimeFormatOptions = definedExternally): Array + } +} \ No newline at end of file diff --git a/externals03/lib.es5.kt b/externals03/lib.es5.kt new file mode 100644 index 0000000..c9b2102 --- /dev/null +++ b/externals03/lib.es5.kt @@ -0,0 +1,69 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface DateConstructor { + @nativeInvoke + operator fun invoke(): String + val prototype: Date + fun parse(s: String): Number + fun UTC(year: Number, month: Number, date: Number = definedExternally, hours: Number = definedExternally, minutes: Number = definedExternally, seconds: Number = definedExternally, ms: Number = definedExternally): Number + fun now(): Number +} + +external interface ConcatArray { + val length: Number + @nativeGetter + operator fun get(n: Number): T? + @nativeSetter + operator fun set(n: Number, value: T) + fun join(separator: String = definedExternally): String + fun slice(start: Number = definedExternally, end: Number = definedExternally): Array +} + +external interface ArrayConstructor { + fun from(iterable: Iterable): Array + fun from(iterable: ArrayLike): Array + fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array + fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U): Array + fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array + fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U): Array + fun of(vararg items: T): Array + @nativeInvoke + operator fun invoke(arrayLength: Number = definedExternally): Array + @nativeInvoke + operator fun invoke(): Array + @nativeInvoke + operator fun invoke(arrayLength: Number): Array + @nativeInvoke + operator fun invoke(vararg items: T): Array + fun isArray(arg: Any): Boolean + val prototype: Array +} + +external interface PromiseLike { + fun then(onfulfilled: ((value: T) -> Any?)? = definedExternally, onrejected: ((reason: Any) -> Any?)? = definedExternally): PromiseLike +} + +external interface ArrayLike { + val length: Number + @nativeGetter + operator fun get(n: Number): T? + @nativeSetter + operator fun set(n: Number, value: T) +} + +typealias Record = Any \ No newline at end of file diff --git a/externals03/lib.scripthost.kt b/externals03/lib.scripthost.kt new file mode 100644 index 0000000..809347e --- /dev/null +++ b/externals03/lib.scripthost.kt @@ -0,0 +1,20 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external open class VarDate { + open var VarDate_typekey: VarDate +} \ No newline at end of file diff --git a/externals03/nonDeclarations.ts.kt b/externals03/nonDeclarations.ts.kt new file mode 100644 index 0000000..3650dca --- /dev/null +++ b/externals03/nonDeclarations.ts.kt @@ -0,0 +1,114 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package ts + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +typealias SortedReadonlyArray = Array + +typealias SortedArray = Array + +typealias NodeArray = Array + +typealias DotToken = PunctuationToken + +typealias DotDotDotToken = PunctuationToken + +typealias QuestionToken = PunctuationToken + +typealias ExclamationToken = PunctuationToken + +typealias ColonToken = PunctuationToken + +typealias EqualsToken = PunctuationToken + +typealias AsteriskToken = PunctuationToken + +typealias EqualsGreaterThanToken = PunctuationToken + +typealias PlusToken = PunctuationToken + +typealias MinusToken = PunctuationToken + +typealias QuestionDotToken = PunctuationToken + +typealias AssertsKeyword = KeywordToken + +typealias AwaitKeyword = KeywordToken + +typealias AwaitKeywordToken = AwaitKeyword + +typealias AssertsToken = AssertsKeyword + +typealias AbstractKeyword = ModifierToken + +typealias AsyncKeyword = ModifierToken + +typealias ConstKeyword = ModifierToken + +typealias DeclareKeyword = ModifierToken + +typealias DefaultKeyword = ModifierToken + +typealias ExportKeyword = ModifierToken + +typealias PrivateKeyword = ModifierToken + +typealias ProtectedKeyword = ModifierToken + +typealias PublicKeyword = ModifierToken + +typealias ReadonlyKeyword = ModifierToken + +typealias OverrideKeyword = ModifierToken + +typealias StaticKeyword = ModifierToken + +typealias ReadonlyToken = ReadonlyKeyword + +typealias ModifiersArray = NodeArray + +typealias IncrementExpression = UpdateExpression + +typealias ExponentiationOperator = SyntaxKind.AsteriskAsteriskToken + +typealias BinaryOperatorToken = Token + +typealias AssignmentOperatorToken = Token + +typealias FunctionBody = Block + +typealias WriteFileCallback = (fileName: String, data: String, writeByteOrderMark: Boolean, onError: (message: String) -> Unit, sourceFiles: Array) -> Unit + +typealias CustomTransformerFactory = (context: TransformationContext) -> CustomTransformer + +typealias SymbolTable = UnderscoreEscapedMap + +typealias JsFileExtensionInfo = FileExtensionInfo + +typealias EmitHelperUniqueNameCallback = (name: String) -> String + +typealias TransformerFactory = (context: TransformationContext) -> Transformer + +typealias Transformer = (node: T) -> T + +typealias Visitor = (node: Node) -> dynamic + +typealias FileWatcherCallback = (fileName: String, eventKind: FileWatcherEventKind) -> Unit + +typealias DirectoryWatcherCallback = (fileName: String) -> Unit + +typealias DiagnosticReporter = (diagnostic: Diagnostic) -> Unit + +typealias CodeActionCommand = InstallPackageAction \ No newline at end of file diff --git a/externals03/output-collector.module_typescript-to-lua.kt b/externals03/output-collector.module_typescript-to-lua.kt new file mode 100644 index 0000000..0c57eac --- /dev/null +++ b/externals03/output-collector.module_typescript-to-lua.kt @@ -0,0 +1,33 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.SourceFile + +external interface TranspiledFile { + var outPath: String + var sourceFiles: Array + var lua: String? + get() = definedExternally + set(value) = definedExternally + var luaSourceMap: String? + get() = definedExternally + set(value) = definedExternally + var declaration: String? + get() = definedExternally + set(value) = definedExternally + var declarationMap: String? + get() = definedExternally + set(value) = definedExternally +} \ No newline at end of file diff --git a/externals03/parse.module_typescript-to-lua.kt b/externals03/parse.module_typescript-to-lua.kt new file mode 100644 index 0000000..ff6e944 --- /dev/null +++ b/externals03/parse.module_typescript-to-lua.kt @@ -0,0 +1,25 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface ParsedCommandLine : ts.ParsedCommandLine { + override var options: dynamic /* typealias OmitIndexSignature = dynamic */ + get() = definedExternally + set(value) = definedExternally +} + +external fun updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine + +external fun parseCommandLine(args: Array): ParsedCommandLine \ No newline at end of file diff --git a/externals03/plugins.module_typescript-to-lua.kt b/externals03/plugins.module_typescript-to-lua.kt new file mode 100644 index 0000000..24d3ea4 --- /dev/null +++ b/externals03/plugins.module_typescript-to-lua.kt @@ -0,0 +1,24 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface Plugin { + var visitors: Visitors? + get() = definedExternally + set(value) = definedExternally + var printer: Printer? + get() = definedExternally + set(value) = definedExternally +} \ No newline at end of file diff --git a/externals03/report.module_typescript-to-lua.kt b/externals03/report.module_typescript-to-lua.kt new file mode 100644 index 0000000..f1582a6 --- /dev/null +++ b/externals03/report.module_typescript-to-lua.kt @@ -0,0 +1,48 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.DiagnosticRelatedInformation +import ts.DiagnosticCategory +import ts.SourceFile +import ts.Diagnostic +import ts.System +import ts.DiagnosticReporter + +external interface `T$13` { + var code: Any + var reportsUnnecessary: Any? + get() = definedExternally + set(value) = definedExternally + var reportsDeprecated: Any? + get() = definedExternally + set(value) = definedExternally + var source: String? + get() = definedExternally + set(value) = definedExternally + var relatedInformation: Array? + get() = definedExternally + set(value) = definedExternally + var category: DiagnosticCategory + var file: SourceFile? + var start: Number? + var length: Number? + var messageText: dynamic /* String | ts.DiagnosticMessageChain */ + get() = definedExternally + set(value) = definedExternally +} + +external var prepareDiagnosticForFormatting: (diagnostic: Diagnostic) -> `T$13` + +external fun createDiagnosticReporter(pretty: Boolean, system: System = definedExternally): DiagnosticReporter \ No newline at end of file diff --git a/externals03/source-map.module_source-map.kt b/externals03/source-map.module_source-map.kt new file mode 100644 index 0000000..6880a36 --- /dev/null +++ b/externals03/source-map.module_source-map.kt @@ -0,0 +1,192 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +typealias SourceMapUrl = String + +external interface StartOfSourceMap { + var file: String? + get() = definedExternally + set(value) = definedExternally + var sourceRoot: String? + get() = definedExternally + set(value) = definedExternally + var skipValidation: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface RawSourceMap { + var version: Number + var sources: Array + var names: Array + var sourceRoot: String? + get() = definedExternally + set(value) = definedExternally + var sourcesContent: Array? + get() = definedExternally + set(value) = definedExternally + var mappings: String + var file: String +} + +external interface RawIndexMap : StartOfSourceMap { + var version: Number + var sections: Array +} + +external interface RawSection { + var offset: Position + var map: RawSourceMap +} + +external interface Position { + var line: Number + var column: Number +} + +external interface NullablePosition { + var line: Number? + var column: Number? + var lastColumn: Number? +} + +external interface MappedPosition { + var source: String + var line: Number + var column: Number + var name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface NullableMappedPosition { + var source: String? + var line: Number? + var column: Number? + var name: String? +} + +external interface MappingItem { + var source: String + var generatedLine: Number + var generatedColumn: Number + var originalLine: Number + var originalColumn: Number + var name: String +} + +external interface Mapping { + var generated: Position + var original: Position + var source: String + var name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface CodeWithSourceMap { + var code: String + var map: SourceMapGenerator +} + +external interface SourceMapConsumer { + fun computeColumnSpans() + fun originalPositionFor(generatedPosition: Position /* Position & `T$19` */): NullableMappedPosition + fun generatedPositionFor(originalPosition: MappedPosition /* MappedPosition & `T$19` */): NullablePosition + fun allGeneratedPositionsFor(originalPosition: MappedPosition): Array + fun hasContentsOfAllSources(): Boolean + fun sourceContentFor(source: String, returnNullOnMissing: Boolean = definedExternally): String? + fun eachMapping(callback: (mapping: MappingItem) -> Unit, context: Any = definedExternally, order: Number = definedExternally) + fun destroy() +} + +external interface SourceMapConsumerConstructor { + var prototype: SourceMapConsumer + var GENERATED_ORDER: Number + var ORIGINAL_ORDER: Number + var GREATEST_LOWER_BOUND: Number + var LEAST_UPPER_BOUND: Number + fun fromSourceMap(sourceMap: SourceMapGenerator, sourceMapUrl: SourceMapUrl = definedExternally): Promise + fun with(rawSourceMap: RawSourceMap, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise + fun with(rawSourceMap: RawIndexMap, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise + fun with(rawSourceMap: String, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise +} + +external interface BasicSourceMapConsumer : SourceMapConsumer { + var file: String + var sourceRoot: String + var sources: Array + var sourcesContent: Array +} + +external interface BasicSourceMapConsumerConstructor { + var prototype: BasicSourceMapConsumer + fun fromSourceMap(sourceMap: SourceMapGenerator): Promise +} + +external interface IndexedSourceMapConsumer : SourceMapConsumer { + var sources: Array +} + +external interface IndexedSourceMapConsumerConstructor { + var prototype: IndexedSourceMapConsumer +} + +external open class SourceMapGenerator(startOfSourceMap: StartOfSourceMap = definedExternally) { + open fun addMapping(mapping: Mapping) + open fun setSourceContent(sourceFile: String, sourceContent: String) + open fun applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile: String = definedExternally, sourceMapPath: String = definedExternally) + override fun toString(): String + open fun toJSON(): RawSourceMap + + companion object { + fun fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator + } +} + +external open class SourceNode { + open var children: Array + open var sourceContents: Any + open var line: Number + open var column: Number + open var source: String + open var name: String + constructor() + constructor(line: Number?, column: Number?, source: String?, chunks: Array = definedExternally, name: String = definedExternally) + constructor(line: Number?, column: Number?, source: String?) + constructor(line: Number?, column: Number?, source: String?, chunks: Array = definedExternally) + constructor(line: Number?, column: Number?, source: String?, chunks: SourceNode = definedExternally, name: String = definedExternally) + constructor(line: Number?, column: Number?, source: String?, chunks: SourceNode = definedExternally) + constructor(line: Number?, column: Number?, source: String?, chunks: String = definedExternally, name: String = definedExternally) + constructor(line: Number?, column: Number?, source: String?, chunks: String = definedExternally) + open fun add(chunk: Array): SourceNode + open fun add(chunk: SourceNode): SourceNode + open fun add(chunk: String): SourceNode + open fun prepend(chunk: Array): SourceNode + open fun prepend(chunk: SourceNode): SourceNode + open fun prepend(chunk: String): SourceNode + open fun setSourceContent(sourceFile: String, sourceContent: String) + open fun walk(fn: (chunk: String, mapping: MappedPosition) -> Unit) + open fun walkSourceContents(fn: (file: String, content: String) -> Unit) + open fun join(sep: String): SourceNode + open fun replaceRight(pattern: String, replacement: String): SourceNode + override fun toString(): String + open fun toStringWithSourceMap(startOfSourceMap: StartOfSourceMap = definedExternally): CodeWithSourceMap + + companion object { + fun fromStringWithSourceMap(code: String, sourceMapConsumer: SourceMapConsumer, relativePath: String = definedExternally): SourceNode + } +} \ No newline at end of file diff --git a/externals03/transpile.module_typescript-to-lua.kt b/externals03/transpile.module_typescript-to-lua.kt new file mode 100644 index 0000000..8681706 --- /dev/null +++ b/externals03/transpile.module_typescript-to-lua.kt @@ -0,0 +1,40 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.Program +import ts.SourceFile +import ts.CustomTransformers +import ts.Diagnostic +import ts.WriteFileCallback + +external interface TranspileOptions { + var program: Program + var sourceFiles: Array? + get() = definedExternally + set(value) = definedExternally + var customTransformers: CustomTransformers? + get() = definedExternally + set(value) = definedExternally + var plugins: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface TranspileResult { + var diagnostics: Array + var transpiledFiles: Array +} + +external fun getProgramTranspileResult(emitHost: EmitHost, writeFileResult: WriteFileCallback, __2: TranspileOptions): TranspileResult \ No newline at end of file diff --git a/externals03/transpiler.module_typescript-to-lua.kt b/externals03/transpiler.module_typescript-to-lua.kt new file mode 100644 index 0000000..16b18b0 --- /dev/null +++ b/externals03/transpiler.module_typescript-to-lua.kt @@ -0,0 +1,55 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.WriteFileCallback +import ts.Diagnostic +import ts.Program + +external interface TranspilerOptions { + var emitHost: EmitHost? + get() = definedExternally + set(value) = definedExternally +} + +external interface EmitOptions : TranspileOptions { + var writeFile: WriteFileCallback? + get() = definedExternally + set(value) = definedExternally +} + +external interface EmitResult { + var emitSkipped: Boolean + var diagnostics: Array +} + +external interface `T$20` { + var emitPlan: Array +} + +external open class Transpiler(__0: TranspilerOptions = definedExternally) { + open var emitHost: EmitHost + open fun emit(emitOptions: EmitOptions): EmitResult + open fun getEmitPlan(program: Program, diagnostics: Array, files: Array): `T$20` +} + +external fun getEmitPath(file: String, program: Program): String + +external fun getEmitPathRelativeToOutDir(fileName: String, program: Program): String + +external fun getSourceDir(program: Program): String + +external fun getEmitOutDir(program: Program): String + +external fun getProjectRoot(program: Program): String \ No newline at end of file diff --git a/externals03/tsconfig.module_typescript-to-lua.kt b/externals03/tsconfig.module_typescript-to-lua.kt new file mode 100644 index 0000000..865bc70 --- /dev/null +++ b/externals03/tsconfig.module_typescript-to-lua.kt @@ -0,0 +1,18 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.System + +external fun parseConfigFileWithSystem(configFileName: String, commandLineOptions: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, system: System = definedExternally): ParsedCommandLine \ No newline at end of file diff --git a/externals03/typescript.ts.ScriptSnapshot.module_typescript.kt b/externals03/typescript.ts.ScriptSnapshot.module_typescript.kt new file mode 100644 index 0000000..acab3da --- /dev/null +++ b/externals03/typescript.ts.ScriptSnapshot.module_typescript.kt @@ -0,0 +1,20 @@ +@file:JsQualifier("ts.ScriptSnapshot") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package ts.ScriptSnapshot + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.IScriptSnapshot + +external fun fromString(text: String): IScriptSnapshot \ No newline at end of file diff --git a/externals03/typescript.ts.module_typescript.kt b/externals03/typescript.ts.module_typescript.kt new file mode 100644 index 0000000..a552747 --- /dev/null +++ b/externals03/typescript.ts.module_typescript.kt @@ -0,0 +1,5914 @@ +@file:JsModule("typescript") +@file:JsNonModule +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package ts + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external var versionMajorMinor: Any + +external var version: String + +external interface MapLike { + @nativeGetter + operator fun get(index: String): T? + @nativeSetter + operator fun set(index: String, value: T) +} + +external interface ReadonlyCollection { + val size: Number + fun has(key: K): Boolean + fun keys(): Iterator +} + +external interface Collection : ReadonlyCollection { + fun delete(key: K): Boolean + fun clear() +} + +external interface ReadonlyESMap : ReadonlyCollection { + fun get(key: K): V? + fun values(): Iterator + fun entries(): Iterator */> + fun forEach(action: (value: V, key: K) -> Unit) +} + +external interface ReadonlyMap : ReadonlyESMap + +external interface ESMap : ReadonlyESMap, Collection { + fun set(key: K, value: V): ESMap /* this */ +} + +external interface Map : ESMap + +external interface ReadonlySet : ReadonlyCollection { + override fun has(value: T): Boolean + fun values(): Iterator + fun entries(): Iterator */> + fun forEach(action: (value: T, key: T) -> Unit) +} + +external interface Set : ReadonlySet, Collection { + fun add(value: T): Set /* this */ + override fun delete(value: T): Boolean +} + +external interface `T$1` { + var value: T + var done: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$2` { + var value: Unit + var done: Boolean +} + +external interface Iterator { + fun next(): dynamic /* `T$1` | `T$2` */ +} + +external interface Push { + fun push(vararg values: T) +} + +external interface `T$3` { + var __pathBrand: Any +} + +external interface TextRange { + var pos: Number + var end: Number +} + +external interface ReadonlyTextRange { + val pos: Number + val end: Number +} + +external enum class SyntaxKind { + Unknown /* = 0 */, + EndOfFileToken /* = 1 */, + SingleLineCommentTrivia /* = 2 */, + MultiLineCommentTrivia /* = 3 */, + NewLineTrivia /* = 4 */, + WhitespaceTrivia /* = 5 */, + ShebangTrivia /* = 6 */, + ConflictMarkerTrivia /* = 7 */, + NumericLiteral /* = 8 */, + BigIntLiteral /* = 9 */, + StringLiteral /* = 10 */, + JsxText /* = 11 */, + JsxTextAllWhiteSpaces /* = 12 */, + RegularExpressionLiteral /* = 13 */, + NoSubstitutionTemplateLiteral /* = 14 */, + TemplateHead /* = 15 */, + TemplateMiddle /* = 16 */, + TemplateTail /* = 17 */, + OpenBraceToken /* = 18 */, + CloseBraceToken /* = 19 */, + OpenParenToken /* = 20 */, + CloseParenToken /* = 21 */, + OpenBracketToken /* = 22 */, + CloseBracketToken /* = 23 */, + DotToken /* = 24 */, + DotDotDotToken /* = 25 */, + SemicolonToken /* = 26 */, + CommaToken /* = 27 */, + QuestionDotToken /* = 28 */, + LessThanToken /* = 29 */, + LessThanSlashToken /* = 30 */, + GreaterThanToken /* = 31 */, + LessThanEqualsToken /* = 32 */, + GreaterThanEqualsToken /* = 33 */, + EqualsEqualsToken /* = 34 */, + ExclamationEqualsToken /* = 35 */, + EqualsEqualsEqualsToken /* = 36 */, + ExclamationEqualsEqualsToken /* = 37 */, + EqualsGreaterThanToken /* = 38 */, + PlusToken /* = 39 */, + MinusToken /* = 40 */, + AsteriskToken /* = 41 */, + AsteriskAsteriskToken /* = 42 */, + SlashToken /* = 43 */, + PercentToken /* = 44 */, + PlusPlusToken /* = 45 */, + MinusMinusToken /* = 46 */, + LessThanLessThanToken /* = 47 */, + GreaterThanGreaterThanToken /* = 48 */, + GreaterThanGreaterThanGreaterThanToken /* = 49 */, + AmpersandToken /* = 50 */, + BarToken /* = 51 */, + CaretToken /* = 52 */, + ExclamationToken /* = 53 */, + TildeToken /* = 54 */, + AmpersandAmpersandToken /* = 55 */, + BarBarToken /* = 56 */, + QuestionToken /* = 57 */, + ColonToken /* = 58 */, + AtToken /* = 59 */, + QuestionQuestionToken /* = 60 */, + BacktickToken /* = 61 */, + EqualsToken /* = 62 */, + PlusEqualsToken /* = 63 */, + MinusEqualsToken /* = 64 */, + AsteriskEqualsToken /* = 65 */, + AsteriskAsteriskEqualsToken /* = 66 */, + SlashEqualsToken /* = 67 */, + PercentEqualsToken /* = 68 */, + LessThanLessThanEqualsToken /* = 69 */, + GreaterThanGreaterThanEqualsToken /* = 70 */, + GreaterThanGreaterThanGreaterThanEqualsToken /* = 71 */, + AmpersandEqualsToken /* = 72 */, + BarEqualsToken /* = 73 */, + BarBarEqualsToken /* = 74 */, + AmpersandAmpersandEqualsToken /* = 75 */, + QuestionQuestionEqualsToken /* = 76 */, + CaretEqualsToken /* = 77 */, + Identifier /* = 78 */, + PrivateIdentifier /* = 79 */, + BreakKeyword /* = 80 */, + CaseKeyword /* = 81 */, + CatchKeyword /* = 82 */, + ClassKeyword /* = 83 */, + ConstKeyword /* = 84 */, + ContinueKeyword /* = 85 */, + DebuggerKeyword /* = 86 */, + DefaultKeyword /* = 87 */, + DeleteKeyword /* = 88 */, + DoKeyword /* = 89 */, + ElseKeyword /* = 90 */, + EnumKeyword /* = 91 */, + ExportKeyword /* = 92 */, + ExtendsKeyword /* = 93 */, + FalseKeyword /* = 94 */, + FinallyKeyword /* = 95 */, + ForKeyword /* = 96 */, + FunctionKeyword /* = 97 */, + IfKeyword /* = 98 */, + ImportKeyword /* = 99 */, + InKeyword /* = 100 */, + InstanceOfKeyword /* = 101 */, + NewKeyword /* = 102 */, + NullKeyword /* = 103 */, + ReturnKeyword /* = 104 */, + SuperKeyword /* = 105 */, + SwitchKeyword /* = 106 */, + ThisKeyword /* = 107 */, + ThrowKeyword /* = 108 */, + TrueKeyword /* = 109 */, + TryKeyword /* = 110 */, + TypeOfKeyword /* = 111 */, + VarKeyword /* = 112 */, + VoidKeyword /* = 113 */, + WhileKeyword /* = 114 */, + WithKeyword /* = 115 */, + ImplementsKeyword /* = 116 */, + InterfaceKeyword /* = 117 */, + LetKeyword /* = 118 */, + PackageKeyword /* = 119 */, + PrivateKeyword /* = 120 */, + ProtectedKeyword /* = 121 */, + PublicKeyword /* = 122 */, + StaticKeyword /* = 123 */, + YieldKeyword /* = 124 */, + AbstractKeyword /* = 125 */, + AsKeyword /* = 126 */, + AssertsKeyword /* = 127 */, + AnyKeyword /* = 128 */, + AsyncKeyword /* = 129 */, + AwaitKeyword /* = 130 */, + BooleanKeyword /* = 131 */, + ConstructorKeyword /* = 132 */, + DeclareKeyword /* = 133 */, + GetKeyword /* = 134 */, + InferKeyword /* = 135 */, + IntrinsicKeyword /* = 136 */, + IsKeyword /* = 137 */, + KeyOfKeyword /* = 138 */, + ModuleKeyword /* = 139 */, + NamespaceKeyword /* = 140 */, + NeverKeyword /* = 141 */, + ReadonlyKeyword /* = 142 */, + RequireKeyword /* = 143 */, + NumberKeyword /* = 144 */, + ObjectKeyword /* = 145 */, + SetKeyword /* = 146 */, + StringKeyword /* = 147 */, + SymbolKeyword /* = 148 */, + TypeKeyword /* = 149 */, + UndefinedKeyword /* = 150 */, + UniqueKeyword /* = 151 */, + UnknownKeyword /* = 152 */, + FromKeyword /* = 153 */, + GlobalKeyword /* = 154 */, + BigIntKeyword /* = 155 */, + OverrideKeyword /* = 156 */, + OfKeyword /* = 157 */, + QualifiedName /* = 158 */, + ComputedPropertyName /* = 159 */, + TypeParameter /* = 160 */, + Parameter /* = 161 */, + Decorator /* = 162 */, + PropertySignature /* = 163 */, + PropertyDeclaration /* = 164 */, + MethodSignature /* = 165 */, + MethodDeclaration /* = 166 */, + Constructor /* = 167 */, + GetAccessor /* = 168 */, + SetAccessor /* = 169 */, + CallSignature /* = 170 */, + ConstructSignature /* = 171 */, + IndexSignature /* = 172 */, + TypePredicate /* = 173 */, + TypeReference /* = 174 */, + FunctionType /* = 175 */, + ConstructorType /* = 176 */, + TypeQuery /* = 177 */, + TypeLiteral /* = 178 */, + ArrayType /* = 179 */, + TupleType /* = 180 */, + OptionalType /* = 181 */, + RestType /* = 182 */, + UnionType /* = 183 */, + IntersectionType /* = 184 */, + ConditionalType /* = 185 */, + InferType /* = 186 */, + ParenthesizedType /* = 187 */, + ThisType /* = 188 */, + TypeOperator /* = 189 */, + IndexedAccessType /* = 190 */, + MappedType /* = 191 */, + LiteralType /* = 192 */, + NamedTupleMember /* = 193 */, + TemplateLiteralType /* = 194 */, + TemplateLiteralTypeSpan /* = 195 */, + ImportType /* = 196 */, + ObjectBindingPattern /* = 197 */, + ArrayBindingPattern /* = 198 */, + BindingElement /* = 199 */, + ArrayLiteralExpression /* = 200 */, + ObjectLiteralExpression /* = 201 */, + PropertyAccessExpression /* = 202 */, + ElementAccessExpression /* = 203 */, + CallExpression /* = 204 */, + NewExpression /* = 205 */, + TaggedTemplateExpression /* = 206 */, + TypeAssertionExpression /* = 207 */, + ParenthesizedExpression /* = 208 */, + FunctionExpression /* = 209 */, + ArrowFunction /* = 210 */, + DeleteExpression /* = 211 */, + TypeOfExpression /* = 212 */, + VoidExpression /* = 213 */, + AwaitExpression /* = 214 */, + PrefixUnaryExpression /* = 215 */, + PostfixUnaryExpression /* = 216 */, + BinaryExpression /* = 217 */, + ConditionalExpression /* = 218 */, + TemplateExpression /* = 219 */, + YieldExpression /* = 220 */, + SpreadElement /* = 221 */, + ClassExpression /* = 222 */, + OmittedExpression /* = 223 */, + ExpressionWithTypeArguments /* = 224 */, + AsExpression /* = 225 */, + NonNullExpression /* = 226 */, + MetaProperty /* = 227 */, + SyntheticExpression /* = 228 */, + TemplateSpan /* = 229 */, + SemicolonClassElement /* = 230 */, + Block /* = 231 */, + EmptyStatement /* = 232 */, + VariableStatement /* = 233 */, + ExpressionStatement /* = 234 */, + IfStatement /* = 235 */, + DoStatement /* = 236 */, + WhileStatement /* = 237 */, + ForStatement /* = 238 */, + ForInStatement /* = 239 */, + ForOfStatement /* = 240 */, + ContinueStatement /* = 241 */, + BreakStatement /* = 242 */, + ReturnStatement /* = 243 */, + WithStatement /* = 244 */, + SwitchStatement /* = 245 */, + LabeledStatement /* = 246 */, + ThrowStatement /* = 247 */, + TryStatement /* = 248 */, + DebuggerStatement /* = 249 */, + VariableDeclaration /* = 250 */, + VariableDeclarationList /* = 251 */, + FunctionDeclaration /* = 252 */, + ClassDeclaration /* = 253 */, + InterfaceDeclaration /* = 254 */, + TypeAliasDeclaration /* = 255 */, + EnumDeclaration /* = 256 */, + ModuleDeclaration /* = 257 */, + ModuleBlock /* = 258 */, + CaseBlock /* = 259 */, + NamespaceExportDeclaration /* = 260 */, + ImportEqualsDeclaration /* = 261 */, + ImportDeclaration /* = 262 */, + ImportClause /* = 263 */, + NamespaceImport /* = 264 */, + NamedImports /* = 265 */, + ImportSpecifier /* = 266 */, + ExportAssignment /* = 267 */, + ExportDeclaration /* = 268 */, + NamedExports /* = 269 */, + NamespaceExport /* = 270 */, + ExportSpecifier /* = 271 */, + MissingDeclaration /* = 272 */, + ExternalModuleReference /* = 273 */, + JsxElement /* = 274 */, + JsxSelfClosingElement /* = 275 */, + JsxOpeningElement /* = 276 */, + JsxClosingElement /* = 277 */, + JsxFragment /* = 278 */, + JsxOpeningFragment /* = 279 */, + JsxClosingFragment /* = 280 */, + JsxAttribute /* = 281 */, + JsxAttributes /* = 282 */, + JsxSpreadAttribute /* = 283 */, + JsxExpression /* = 284 */, + CaseClause /* = 285 */, + DefaultClause /* = 286 */, + HeritageClause /* = 287 */, + CatchClause /* = 288 */, + PropertyAssignment /* = 289 */, + ShorthandPropertyAssignment /* = 290 */, + SpreadAssignment /* = 291 */, + EnumMember /* = 292 */, + UnparsedPrologue /* = 293 */, + UnparsedPrepend /* = 294 */, + UnparsedText /* = 295 */, + UnparsedInternalText /* = 296 */, + UnparsedSyntheticReference /* = 297 */, + SourceFile /* = 298 */, + Bundle /* = 299 */, + UnparsedSource /* = 300 */, + InputFiles /* = 301 */, + JSDocTypeExpression /* = 302 */, + JSDocNameReference /* = 303 */, + JSDocAllType /* = 304 */, + JSDocUnknownType /* = 305 */, + JSDocNullableType /* = 306 */, + JSDocNonNullableType /* = 307 */, + JSDocOptionalType /* = 308 */, + JSDocFunctionType /* = 309 */, + JSDocVariadicType /* = 310 */, + JSDocNamepathType /* = 311 */, + JSDocComment /* = 312 */, + JSDocText /* = 313 */, + JSDocTypeLiteral /* = 314 */, + JSDocSignature /* = 315 */, + JSDocLink /* = 316 */, + JSDocTag /* = 317 */, + JSDocAugmentsTag /* = 318 */, + JSDocImplementsTag /* = 319 */, + JSDocAuthorTag /* = 320 */, + JSDocDeprecatedTag /* = 321 */, + JSDocClassTag /* = 322 */, + JSDocPublicTag /* = 323 */, + JSDocPrivateTag /* = 324 */, + JSDocProtectedTag /* = 325 */, + JSDocReadonlyTag /* = 326 */, + JSDocOverrideTag /* = 327 */, + JSDocCallbackTag /* = 328 */, + JSDocEnumTag /* = 329 */, + JSDocParameterTag /* = 330 */, + JSDocReturnTag /* = 331 */, + JSDocThisTag /* = 332 */, + JSDocTypeTag /* = 333 */, + JSDocTemplateTag /* = 334 */, + JSDocTypedefTag /* = 335 */, + JSDocSeeTag /* = 336 */, + JSDocPropertyTag /* = 337 */, + SyntaxList /* = 338 */, + NotEmittedStatement /* = 339 */, + PartiallyEmittedExpression /* = 340 */, + CommaListExpression /* = 341 */, + MergeDeclarationMarker /* = 342 */, + EndOfDeclarationMarker /* = 343 */, + SyntheticReferenceExpression /* = 344 */, + Count /* = 345 */, + FirstAssignment /* = 62 */, + LastAssignment /* = 77 */, + FirstCompoundAssignment /* = 63 */, + LastCompoundAssignment /* = 77 */, + FirstReservedWord /* = 80 */, + LastReservedWord /* = 115 */, + FirstKeyword /* = 80 */, + LastKeyword /* = 157 */, + FirstFutureReservedWord /* = 116 */, + LastFutureReservedWord /* = 124 */, + FirstTypeNode /* = 173 */, + LastTypeNode /* = 196 */, + FirstPunctuation /* = 18 */, + LastPunctuation /* = 77 */, + FirstToken /* = 0 */, + LastToken /* = 157 */, + FirstTriviaToken /* = 2 */, + LastTriviaToken /* = 7 */, + FirstLiteralToken /* = 8 */, + LastLiteralToken /* = 14 */, + FirstTemplateToken /* = 14 */, + LastTemplateToken /* = 17 */, + FirstBinaryOperator /* = 29 */, + LastBinaryOperator /* = 77 */, + FirstStatement /* = 233 */, + LastStatement /* = 249 */, + FirstNode /* = 158 */, + FirstJSDocNode /* = 302 */, + LastJSDocNode /* = 337 */, + FirstJSDocTagNode /* = 317 */, + LastJSDocTagNode /* = 337 */ +} + +external enum class NodeFlags { + None /* = 0 */, + Let /* = 1 */, + Const /* = 2 */, + NestedNamespace /* = 4 */, + Synthesized /* = 8 */, + Namespace /* = 16 */, + OptionalChain /* = 32 */, + ExportContext /* = 64 */, + ContainsThis /* = 128 */, + HasImplicitReturn /* = 256 */, + HasExplicitReturn /* = 512 */, + GlobalAugmentation /* = 1024 */, + HasAsyncFunctions /* = 2048 */, + DisallowInContext /* = 4096 */, + YieldContext /* = 8192 */, + DecoratorContext /* = 16384 */, + AwaitContext /* = 32768 */, + ThisNodeHasError /* = 65536 */, + JavaScriptFile /* = 131072 */, + ThisNodeOrAnySubNodesHasError /* = 262144 */, + HasAggregatedChildData /* = 524288 */, + JSDoc /* = 4194304 */, + JsonFile /* = 33554432 */, + BlockScoped /* = 3 */, + ReachabilityCheckFlags /* = 768 */, + ReachabilityAndEmitFlags /* = 2816 */, + ContextFlags /* = 25358336 */, + TypeExcludesFlags /* = 40960 */ +} + +external enum class ModifierFlags { + None /* = 0 */, + Export /* = 1 */, + Ambient /* = 2 */, + Public /* = 4 */, + Private /* = 8 */, + Protected /* = 16 */, + Static /* = 32 */, + Readonly /* = 64 */, + Abstract /* = 128 */, + Async /* = 256 */, + Default /* = 512 */, + Const /* = 2048 */, + HasComputedJSDocModifiers /* = 4096 */, + Deprecated /* = 8192 */, + Override /* = 16384 */, + HasComputedFlags /* = 536870912 */, + AccessibilityModifier /* = 28 */, + ParameterPropertyModifier /* = 16476 */, + NonPublicAccessibilityModifier /* = 24 */, + TypeScriptModifier /* = 18654 */, + ExportDefault /* = 513 */, + All /* = 27647 */ +} + +external enum class JsxFlags { + None /* = 0 */, + IntrinsicNamedElement /* = 1 */, + IntrinsicIndexedElement /* = 2 */, + IntrinsicElement /* = 3 */ +} + +external interface Node : ReadonlyTextRange { + fun getSourceFile(): SourceFile + fun getChildCount(sourceFile: SourceFile = definedExternally): Number + fun getChildAt(index: Number, sourceFile: SourceFile = definedExternally): Node + fun getChildren(sourceFile: SourceFile = definedExternally): Array + fun getStart(sourceFile: SourceFile = definedExternally, includeJsDocComment: Boolean = definedExternally): Number + fun getFullStart(): Number + fun getEnd(): Number + fun getWidth(sourceFile: SourceFileLike = definedExternally): Number + fun getFullWidth(): Number + fun getLeadingTriviaWidth(sourceFile: SourceFile = definedExternally): Number + fun getFullText(sourceFile: SourceFile = definedExternally): String + fun getText(sourceFile: SourceFile = definedExternally): String + fun getFirstToken(sourceFile: SourceFile = definedExternally): Node? + fun getLastToken(sourceFile: SourceFile = definedExternally): Node? + fun forEachChild(cbNode: (node: Node) -> T?, cbNodeArray: (nodes: NodeArray) -> T? = definedExternally): T? + val kind: SyntaxKind + val flags: NodeFlags + val decorators: NodeArray? + get() = definedExternally + val modifiers: ModifiersArray? + get() = definedExternally + val parent: Node +} + +external interface JSDocContainer + +external interface Token : Node { + override val kind: TKind +} + +external interface PunctuationToken : Token + +external interface KeywordToken : Token + +external interface ModifierToken : KeywordToken + +external enum class GeneratedIdentifierFlags { + None /* = 0 */, + ReservedInNestedScopes /* = 8 */, + Optimistic /* = 16 */, + FileLevel /* = 32 */, + AllowNameSubstitution /* = 64 */ +} + +external interface Identifier : PrimaryExpression, Declaration { + val text: String + val escapedText: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + get() = definedExternally + val originalKeywordKind: SyntaxKind? + get() = definedExternally + var isInJSDocNamespace: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TransientIdentifier : Identifier { + var resolvedSymbol: Symbol +} + +external interface QualifiedName : Node { + val left: dynamic /* Identifier | QualifiedName */ + get() = definedExternally + val right: Identifier +} + +external interface Declaration : Node { + var _declarationBrand: Any +} + +external interface NamedDeclaration : Declaration { + val name: dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ + get() = definedExternally +} + +external interface DeclarationStatement : NamedDeclaration, Statement { + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? */ + get() = definedExternally +} + +external interface ComputedPropertyName : Node { + override val parent: Declaration + val expression: Expression +} + +external interface PrivateIdentifier : Node { + val text: String + val escapedText: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + get() = definedExternally +} + +external interface Decorator : Node { + override val parent: NamedDeclaration + val expression: LeftHandSideExpression +} + +external interface TypeParameterDeclaration : NamedDeclaration { + override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | InferTypeNode */ + get() = definedExternally + override val name: Identifier + val constraint: TypeNode? + get() = definedExternally + val default: TypeNode? + get() = definedExternally + var expression: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureDeclarationBase : NamedDeclaration, JSDocContainer { + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + val typeParameters: NodeArray? + get() = definedExternally + val parameters: NodeArray + val type: TypeNode? + get() = definedExternally +} + +external interface CallSignatureDeclaration : SignatureDeclarationBase, TypeElement { + override val kind: Any + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally +} + +external interface ConstructSignatureDeclaration : SignatureDeclarationBase, TypeElement { + override val kind: Any + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally +} + +external interface VariableDeclaration : NamedDeclaration, JSDocContainer { + override val parent: dynamic /* VariableDeclarationList | CatchClause */ + get() = definedExternally + override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ + get() = definedExternally + val exclamationToken: ExclamationToken? + get() = definedExternally + val type: TypeNode? + get() = definedExternally + val initializer: Expression? + get() = definedExternally +} + +external interface VariableDeclarationList : Node { + override val parent: dynamic /* VariableStatement | ForStatement | ForOfStatement | ForInStatement */ + get() = definedExternally + val declarations: NodeArray +} + +external interface ParameterDeclaration : NamedDeclaration, JSDocContainer { + override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ + get() = definedExternally + val dotDotDotToken: DotDotDotToken? + get() = definedExternally + override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ + get() = definedExternally + val questionToken: QuestionToken? + get() = definedExternally + val type: TypeNode? + get() = definedExternally + val initializer: Expression? + get() = definedExternally +} + +external interface BindingElement : NamedDeclaration { + override val parent: dynamic /* ObjectBindingPattern | ArrayBindingPattern */ + get() = definedExternally + val propertyName: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + val dotDotDotToken: DotDotDotToken? + get() = definedExternally + override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ + get() = definedExternally + val initializer: Expression? + get() = definedExternally +} + +external interface PropertySignature : TypeElement, JSDocContainer { + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + override val questionToken: QuestionToken? + get() = definedExternally + val type: TypeNode? + get() = definedExternally + var initializer: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface PropertyDeclaration : ClassElement, JSDocContainer { + override val parent: dynamic /* ClassDeclaration | ClassExpression */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + val questionToken: QuestionToken? + get() = definedExternally + val exclamationToken: ExclamationToken? + get() = definedExternally + val type: TypeNode? + get() = definedExternally + val initializer: Expression? + get() = definedExternally +} + +external interface ObjectLiteralElement : NamedDeclaration { + var _objectLiteralBrand: Any + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally +} + +external interface PropertyAssignment : ObjectLiteralElement, JSDocContainer { + override val parent: ObjectLiteralExpression + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + val questionToken: QuestionToken? + get() = definedExternally + val exclamationToken: ExclamationToken? + get() = definedExternally + val initializer: Expression +} + +external interface ShorthandPropertyAssignment : ObjectLiteralElement, JSDocContainer { + override val parent: ObjectLiteralExpression + override val name: Identifier + val questionToken: QuestionToken? + get() = definedExternally + val exclamationToken: ExclamationToken? + get() = definedExternally + val equalsToken: EqualsToken? + get() = definedExternally + val objectAssignmentInitializer: Expression? + get() = definedExternally +} + +external interface SpreadAssignment : ObjectLiteralElement, JSDocContainer { + override val parent: ObjectLiteralExpression + val expression: Expression +} + +external interface PropertyLikeDeclaration : NamedDeclaration { + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally +} + +external interface ObjectBindingPattern : Node { + override val parent: dynamic /* VariableDeclaration | ParameterDeclaration | BindingElement */ + get() = definedExternally + val elements: NodeArray +} + +external interface ArrayBindingPattern : Node { + override val parent: dynamic /* VariableDeclaration | ParameterDeclaration | BindingElement */ + get() = definedExternally + val elements: NodeArray +} + +external interface FunctionLikeDeclarationBase : SignatureDeclarationBase { + var _functionLikeDeclarationBrand: Any + val asteriskToken: AsteriskToken? + get() = definedExternally + val questionToken: QuestionToken? + get() = definedExternally + val exclamationToken: ExclamationToken? + get() = definedExternally + val body: dynamic /* Block? | Expression? */ + get() = definedExternally +} + +external interface FunctionDeclaration : FunctionLikeDeclarationBase, DeclarationStatement { + override val kind: Any + override val name: Identifier? + get() = definedExternally + override val body: FunctionBody? + get() = definedExternally +} + +external interface MethodSignature : SignatureDeclarationBase, TypeElement { + override val kind: Any + override val parent: dynamic /* ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally +} + +external interface MethodDeclaration : FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { + override val kind: Any + override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + override val body: FunctionBody? + get() = definedExternally +} + +external interface ConstructorDeclaration : FunctionLikeDeclarationBase, ClassElement, JSDocContainer { + override val kind: Any + override val parent: dynamic /* ClassDeclaration | ClassExpression */ + get() = definedExternally + override val body: FunctionBody? + get() = definedExternally +} + +external interface SemicolonClassElement : ClassElement { + override val parent: dynamic /* ClassDeclaration | ClassExpression */ + get() = definedExternally +} + +external interface GetAccessorDeclaration : FunctionLikeDeclarationBase, ClassElement, TypeElement, ObjectLiteralElement, JSDocContainer { + override val kind: Any + override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression | TypeLiteralNode | InterfaceDeclaration */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + override val body: FunctionBody? + get() = definedExternally + override val questionToken: QuestionToken? + get() = definedExternally +} + +external interface SetAccessorDeclaration : FunctionLikeDeclarationBase, ClassElement, TypeElement, ObjectLiteralElement, JSDocContainer { + override val kind: Any + override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression | TypeLiteralNode | InterfaceDeclaration */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + override val body: FunctionBody? + get() = definedExternally + override val questionToken: QuestionToken? + get() = definedExternally +} + +external interface IndexSignatureDeclaration : SignatureDeclarationBase, ClassElement, TypeElement { + override val kind: Any + override val parent: dynamic /* ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode */ + get() = definedExternally + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally +} + +external interface TypeNode : Node { + var _typeNodeBrand: Any +} + +external interface KeywordTypeNode : KeywordToken, TypeNode { + override val kind: TKind +} + +external interface ImportTypeNode : NodeWithTypeArguments { + val isTypeOf: Boolean + val argument: TypeNode + val qualifier: dynamic /* Identifier? | QualifiedName? */ + get() = definedExternally +} + +external interface ThisTypeNode : TypeNode + +external interface FunctionOrConstructorTypeNodeBase : TypeNode, SignatureDeclarationBase { + override val kind: dynamic /* SyntaxKind.FunctionType | SyntaxKind.ConstructorType */ + get() = definedExternally +} + +external interface FunctionTypeNode : FunctionOrConstructorTypeNodeBase { + override val kind: Any +} + +external interface ConstructorTypeNode : FunctionOrConstructorTypeNodeBase { + override val kind: Any +} + +external interface NodeWithTypeArguments : TypeNode { + val typeArguments: NodeArray? + get() = definedExternally +} + +external interface TypeReferenceNode : NodeWithTypeArguments { + val typeName: dynamic /* Identifier | QualifiedName */ + get() = definedExternally +} + +external interface TypePredicateNode : TypeNode { + override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | JSDocTypeExpression */ + get() = definedExternally + val assertsModifier: AssertsToken? + get() = definedExternally + val parameterName: dynamic /* Identifier | ThisTypeNode */ + get() = definedExternally + val type: TypeNode? + get() = definedExternally +} + +external interface TypeQueryNode : TypeNode { + val exprName: dynamic /* Identifier | QualifiedName */ + get() = definedExternally +} + +external interface TypeLiteralNode : TypeNode, Declaration { + val members: NodeArray +} + +external interface ArrayTypeNode : TypeNode { + val elementType: TypeNode +} + +external interface TupleTypeNode : TypeNode { + val elements: NodeArray +} + +external interface NamedTupleMember : TypeNode, JSDocContainer, Declaration { + val dotDotDotToken: Token? + get() = definedExternally + val name: Identifier + val questionToken: Token? + get() = definedExternally + val type: TypeNode +} + +external interface OptionalTypeNode : TypeNode { + val type: TypeNode +} + +external interface RestTypeNode : TypeNode { + val type: TypeNode +} + +external interface UnionTypeNode : TypeNode { + val types: NodeArray +} + +external interface IntersectionTypeNode : TypeNode { + val types: NodeArray +} + +external interface ConditionalTypeNode : TypeNode { + val checkType: TypeNode + val extendsType: TypeNode + val trueType: TypeNode + val falseType: TypeNode +} + +external interface InferTypeNode : TypeNode { + val typeParameter: TypeParameterDeclaration +} + +external interface ParenthesizedTypeNode : TypeNode { + val type: TypeNode +} + +external interface TypeOperatorNode : TypeNode { + val operator: dynamic /* SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword */ + get() = definedExternally + val type: TypeNode +} + +external interface IndexedAccessTypeNode : TypeNode { + val objectType: TypeNode + val indexType: TypeNode +} + +external interface MappedTypeNode : TypeNode, Declaration { + val readonlyToken: dynamic /* ReadonlyToken? | PlusToken? | MinusToken? */ + get() = definedExternally + val typeParameter: TypeParameterDeclaration + val nameType: TypeNode? + get() = definedExternally + val questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */ + get() = definedExternally + val type: TypeNode? + get() = definedExternally +} + +external interface LiteralTypeNode : TypeNode { + val literal: dynamic /* NullLiteral | TrueLiteral | FalseLiteral | LiteralExpression | PrefixUnaryExpression */ + get() = definedExternally +} + +external interface StringLiteral : LiteralExpression, Declaration + +external interface TemplateLiteralTypeNode : TypeNode { + val head: TemplateHead + val templateSpans: NodeArray +} + +external interface TemplateLiteralTypeSpan : TypeNode { + override val parent: TemplateLiteralTypeNode + val type: TypeNode + val literal: dynamic /* TemplateMiddle | TemplateTail */ + get() = definedExternally +} + +external interface Expression : Node { + var _expressionBrand: Any +} + +external interface OmittedExpression : Expression + +external interface PartiallyEmittedExpression : LeftHandSideExpression { + val expression: Expression +} + +external interface UnaryExpression : Expression { + var _unaryExpressionBrand: Any +} + +external interface UpdateExpression : UnaryExpression { + var _updateExpressionBrand: Any +} + +external interface PrefixUnaryExpression : UpdateExpression { + val operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken | SyntaxKind.ExclamationToken */ + get() = definedExternally + val operand: UnaryExpression +} + +external interface PostfixUnaryExpression : UpdateExpression { + val operand: LeftHandSideExpression + val operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken */ + get() = definedExternally +} + +external interface LeftHandSideExpression : UpdateExpression { + var _leftHandSideExpressionBrand: Any +} + +external interface MemberExpression : LeftHandSideExpression { + var _memberExpressionBrand: Any +} + +external interface PrimaryExpression : MemberExpression { + var _primaryExpressionBrand: Any +} + +external interface NullLiteral : PrimaryExpression + +external interface TrueLiteral : PrimaryExpression + +external interface FalseLiteral : PrimaryExpression + +external interface ThisExpression : PrimaryExpression + +external interface SuperExpression : PrimaryExpression + +external interface ImportExpression : PrimaryExpression + +external interface DeleteExpression : UnaryExpression { + val expression: UnaryExpression +} + +external interface TypeOfExpression : UnaryExpression { + val expression: UnaryExpression +} + +external interface VoidExpression : UnaryExpression { + val expression: UnaryExpression +} + +external interface AwaitExpression : UnaryExpression { + val expression: UnaryExpression +} + +external interface YieldExpression : Expression { + val asteriskToken: AsteriskToken? + get() = definedExternally + val expression: Expression? + get() = definedExternally +} + +external interface SyntheticExpression : Expression { + val isSpread: Boolean + val type: Type + val tupleNameSource: dynamic /* ParameterDeclaration? | NamedTupleMember? */ + get() = definedExternally +} + +external interface BinaryExpression : Expression, Declaration { + val left: Expression + val operatorToken: BinaryOperatorToken + val right: Expression +} + +external interface AssignmentExpression : BinaryExpression { + override val left: LeftHandSideExpression + override val operatorToken: TOperator +} + +external interface ObjectDestructuringAssignment : AssignmentExpression { + override val left: ObjectLiteralExpression +} + +external interface ArrayDestructuringAssignment : AssignmentExpression { + override val left: ArrayLiteralExpression +} + +external interface ConditionalExpression : Expression { + val condition: Expression + val questionToken: QuestionToken + val whenTrue: Expression + val colonToken: ColonToken + val whenFalse: Expression +} + +external interface FunctionExpression : PrimaryExpression, FunctionLikeDeclarationBase, JSDocContainer { + override val kind: Any + override val name: Identifier? + get() = definedExternally + override val body: FunctionBody +} + +external interface ArrowFunction : Expression, FunctionLikeDeclarationBase, JSDocContainer { + override val kind: Any + val equalsGreaterThanToken: EqualsGreaterThanToken + override val body: dynamic /* FunctionBody | Expression */ + get() = definedExternally + override val name: Any +} + +external interface LiteralLikeNode : Node { + var text: String + var isUnterminated: Boolean? + get() = definedExternally + set(value) = definedExternally + var hasExtendedUnicodeEscape: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TemplateLiteralLikeNode : LiteralLikeNode { + var rawText: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface LiteralExpression : LiteralLikeNode, PrimaryExpression { + var _literalExpressionBrand: Any +} + +external interface RegularExpressionLiteral : LiteralExpression + +external interface NoSubstitutionTemplateLiteral : LiteralExpression, TemplateLiteralLikeNode, Declaration + +external enum class TokenFlags { + None /* = 0 */, + Scientific /* = 16 */, + Octal /* = 32 */, + HexSpecifier /* = 64 */, + BinarySpecifier /* = 128 */, + OctalSpecifier /* = 256 */ +} + +external interface NumericLiteral : LiteralExpression, Declaration + +external interface BigIntLiteral : LiteralExpression + +external interface TemplateHead : TemplateLiteralLikeNode { + override val parent: dynamic /* TemplateExpression | TemplateLiteralTypeNode */ + get() = definedExternally +} + +external interface TemplateMiddle : TemplateLiteralLikeNode { + override val parent: dynamic /* TemplateSpan | TemplateLiteralTypeSpan */ + get() = definedExternally +} + +external interface TemplateTail : TemplateLiteralLikeNode { + override val parent: dynamic /* TemplateSpan | TemplateLiteralTypeSpan */ + get() = definedExternally +} + +external interface TemplateExpression : PrimaryExpression { + val head: TemplateHead + val templateSpans: NodeArray +} + +external interface TemplateSpan : Node { + override val parent: TemplateExpression + val expression: Expression + val literal: dynamic /* TemplateMiddle | TemplateTail */ + get() = definedExternally +} + +external interface ParenthesizedExpression : PrimaryExpression, JSDocContainer { + val expression: Expression +} + +external interface ArrayLiteralExpression : PrimaryExpression { + val elements: NodeArray +} + +external interface SpreadElement : Expression { + override val parent: dynamic /* ArrayLiteralExpression | CallExpression | NewExpression */ + get() = definedExternally + val expression: Expression +} + +external interface ObjectLiteralExpressionBase : PrimaryExpression, Declaration { + val properties: NodeArray +} + +external interface ObjectLiteralExpression : ObjectLiteralExpressionBase + +external interface PropertyAccessExpression : MemberExpression, NamedDeclaration { + val expression: LeftHandSideExpression + val questionDotToken: QuestionDotToken? + get() = definedExternally + override val name: dynamic /* Identifier | PrivateIdentifier */ + get() = definedExternally +} + +external interface PropertyAccessChain : PropertyAccessExpression { + var _optionalChainBrand: Any + override val name: dynamic /* Identifier | PrivateIdentifier */ + get() = definedExternally +} + +external interface SuperPropertyAccessExpression : PropertyAccessExpression { + override val expression: SuperExpression +} + +external interface PropertyAccessEntityNameExpression : PropertyAccessExpression { + var _propertyAccessExpressionLikeQualifiedNameBrand: Any? + get() = definedExternally + set(value) = definedExternally + override val expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ + get() = definedExternally + override val name: Identifier +} + +external interface ElementAccessExpression : MemberExpression { + val expression: LeftHandSideExpression + val questionDotToken: QuestionDotToken? + get() = definedExternally + val argumentExpression: Expression +} + +external interface ElementAccessChain : ElementAccessExpression { + var _optionalChainBrand: Any +} + +external interface SuperElementAccessExpression : ElementAccessExpression { + override val expression: SuperExpression +} + +external interface CallExpression : LeftHandSideExpression, Declaration { + val expression: LeftHandSideExpression + val questionDotToken: QuestionDotToken? + get() = definedExternally + val typeArguments: NodeArray? + get() = definedExternally + val arguments: NodeArray +} + +external interface CallChain : CallExpression { + var _optionalChainBrand: Any +} + +external interface SuperCall : CallExpression { + override val expression: SuperExpression +} + +external interface ImportCall : CallExpression { + override val expression: ImportExpression +} + +external interface ExpressionWithTypeArguments : NodeWithTypeArguments { + override val parent: dynamic /* HeritageClause | JSDocAugmentsTag | JSDocImplementsTag */ + get() = definedExternally + val expression: LeftHandSideExpression +} + +external interface NewExpression : PrimaryExpression, Declaration { + val expression: LeftHandSideExpression + val typeArguments: NodeArray? + get() = definedExternally + val arguments: NodeArray? + get() = definedExternally +} + +external interface TaggedTemplateExpression : MemberExpression { + val tag: LeftHandSideExpression + val typeArguments: NodeArray? + get() = definedExternally + val template: dynamic /* TemplateExpression | NoSubstitutionTemplateLiteral */ + get() = definedExternally +} + +external interface AsExpression : Expression { + val expression: Expression + val type: TypeNode +} + +external interface TypeAssertion : UnaryExpression { + val type: TypeNode + val expression: UnaryExpression +} + +external interface NonNullExpression : LeftHandSideExpression { + val expression: Expression +} + +external interface NonNullChain : NonNullExpression { + var _optionalChainBrand: Any +} + +external interface MetaProperty : PrimaryExpression { + val keywordToken: dynamic /* SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword */ + get() = definedExternally + val name: Identifier +} + +external interface JsxElement : PrimaryExpression { + val openingElement: JsxOpeningElement + val children: NodeArray + val closingElement: JsxClosingElement +} + +external interface JsxTagNamePropertyAccess : PropertyAccessExpression { + override val expression: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ + get() = definedExternally +} + +external interface JsxAttributes : ObjectLiteralExpressionBase { + override val parent: dynamic /* JsxSelfClosingElement | JsxOpeningElement */ + get() = definedExternally +} + +external interface JsxOpeningElement : Expression { + override val parent: JsxElement + val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ + get() = definedExternally + val typeArguments: NodeArray? + get() = definedExternally + val attributes: JsxAttributes +} + +external interface JsxSelfClosingElement : PrimaryExpression { + val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ + get() = definedExternally + val typeArguments: NodeArray? + get() = definedExternally + val attributes: JsxAttributes +} + +external interface JsxFragment : PrimaryExpression { + val openingFragment: JsxOpeningFragment + val children: NodeArray + val closingFragment: JsxClosingFragment +} + +external interface JsxOpeningFragment : Expression { + override val parent: JsxFragment +} + +external interface JsxClosingFragment : Expression { + override val parent: JsxFragment +} + +external interface JsxAttribute : ObjectLiteralElement { + override val parent: JsxAttributes + override val name: Identifier + val initializer: dynamic /* StringLiteral? | JsxExpression? */ + get() = definedExternally +} + +external interface JsxSpreadAttribute : ObjectLiteralElement { + override val parent: JsxAttributes + val expression: Expression +} + +external interface JsxClosingElement : Node { + override val parent: JsxElement + val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ + get() = definedExternally +} + +external interface JsxExpression : Expression { + override val parent: dynamic /* JsxElement | JsxAttribute | JsxSpreadAttribute */ + get() = definedExternally + val dotDotDotToken: Token? + get() = definedExternally + val expression: Expression? + get() = definedExternally +} + +external interface JsxText : LiteralLikeNode { + override val parent: JsxElement + val containsOnlyTriviaWhiteSpaces: Boolean +} + +external interface Statement : Node, JSDocContainer { + var _statementBrand: Any +} + +external interface NotEmittedStatement : Statement + +external interface CommaListExpression : Expression { + val elements: NodeArray +} + +external interface EmptyStatement : Statement + +external interface DebuggerStatement : Statement + +external interface MissingDeclaration : DeclarationStatement { + override val name: Identifier? + get() = definedExternally +} + +external interface Block : Statement { + val statements: NodeArray +} + +external interface VariableStatement : Statement { + val declarationList: VariableDeclarationList +} + +external interface ExpressionStatement : Statement { + val expression: Expression +} + +external interface IfStatement : Statement { + val expression: Expression + val thenStatement: Statement + val elseStatement: Statement? + get() = definedExternally +} + +external interface IterationStatement : Statement { + val statement: Statement +} + +external interface DoStatement : IterationStatement { + val expression: Expression +} + +external interface WhileStatement : IterationStatement { + val expression: Expression +} + +external interface ForStatement : IterationStatement { + val initializer: dynamic /* VariableDeclarationList? | Expression? */ + get() = definedExternally + val condition: Expression? + get() = definedExternally + val incrementor: Expression? + get() = definedExternally +} + +external interface ForInStatement : IterationStatement { + val initializer: dynamic /* VariableDeclarationList | Expression */ + get() = definedExternally + val expression: Expression +} + +external interface ForOfStatement : IterationStatement { + val awaitModifier: AwaitKeywordToken? + get() = definedExternally + val initializer: dynamic /* VariableDeclarationList | Expression */ + get() = definedExternally + val expression: Expression +} + +external interface BreakStatement : Statement { + val label: Identifier? + get() = definedExternally +} + +external interface ContinueStatement : Statement { + val label: Identifier? + get() = definedExternally +} + +external interface ReturnStatement : Statement { + val expression: Expression? + get() = definedExternally +} + +external interface WithStatement : Statement { + val expression: Expression + val statement: Statement +} + +external interface SwitchStatement : Statement { + val expression: Expression + val caseBlock: CaseBlock + var possiblyExhaustive: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface CaseBlock : Node { + override val parent: SwitchStatement + val clauses: NodeArray +} + +external interface CaseClause : Node { + override val parent: CaseBlock + val expression: Expression + val statements: NodeArray +} + +external interface DefaultClause : Node { + override val parent: CaseBlock + val statements: NodeArray +} + +external interface LabeledStatement : Statement { + val label: Identifier + val statement: Statement +} + +external interface ThrowStatement : Statement { + val expression: Expression +} + +external interface TryStatement : Statement { + val tryBlock: Block + val catchClause: CatchClause? + get() = definedExternally + val finallyBlock: Block? + get() = definedExternally +} + +external interface CatchClause : Node { + override val parent: TryStatement + val variableDeclaration: VariableDeclaration? + get() = definedExternally + val block: Block +} + +external interface ClassLikeDeclarationBase : NamedDeclaration, JSDocContainer { + override val kind: dynamic /* SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression */ + get() = definedExternally + override val name: Identifier? + get() = definedExternally + val typeParameters: NodeArray? + get() = definedExternally + val heritageClauses: NodeArray? + get() = definedExternally + val members: NodeArray +} + +external interface ClassDeclaration : ClassLikeDeclarationBase, DeclarationStatement { + override val kind: Any + override val name: Identifier? + get() = definedExternally +} + +external interface ClassExpression : ClassLikeDeclarationBase, PrimaryExpression { + override val kind: Any +} + +external interface ClassElement : NamedDeclaration { + var _classElementBrand: Any + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally +} + +external interface TypeElement : NamedDeclaration { + var _typeElementBrand: Any + override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + val questionToken: QuestionToken? + get() = definedExternally +} + +external interface InterfaceDeclaration : DeclarationStatement, JSDocContainer { + override val name: Identifier + val typeParameters: NodeArray? + get() = definedExternally + val heritageClauses: NodeArray? + get() = definedExternally + val members: NodeArray +} + +external interface HeritageClause : Node { + override val parent: dynamic /* InterfaceDeclaration | ClassDeclaration | ClassExpression */ + get() = definedExternally + val token: dynamic /* SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword */ + get() = definedExternally + val types: NodeArray +} + +external interface TypeAliasDeclaration : DeclarationStatement, JSDocContainer { + override val name: Identifier + val typeParameters: NodeArray? + get() = definedExternally + val type: TypeNode +} + +external interface EnumMember : NamedDeclaration, JSDocContainer { + override val parent: EnumDeclaration + override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + val initializer: Expression? + get() = definedExternally +} + +external interface EnumDeclaration : DeclarationStatement, JSDocContainer { + override val name: Identifier + val members: NodeArray +} + +external interface ModuleDeclaration : DeclarationStatement, JSDocContainer { + override val parent: dynamic /* ModuleBlock | NamespaceDeclaration | Identifier | JSDocNamespaceDeclaration | SourceFile */ + get() = definedExternally + override val name: dynamic /* Identifier | StringLiteral */ + get() = definedExternally + val body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */ + get() = definedExternally +} + +external interface NamespaceDeclaration : ModuleDeclaration { + override val name: Identifier + override val body: dynamic /* ModuleBlock | NamespaceDeclaration */ + get() = definedExternally +} + +external interface JSDocNamespaceDeclaration : ModuleDeclaration { + override val name: Identifier + override val body: dynamic /* Identifier? | JSDocNamespaceDeclaration? */ + get() = definedExternally +} + +external interface ModuleBlock : Node, Statement { + override val parent: ModuleDeclaration + val statements: NodeArray +} + +external interface ImportEqualsDeclaration : DeclarationStatement, JSDocContainer { + override val parent: dynamic /* SourceFile | ModuleBlock */ + get() = definedExternally + override val name: Identifier + val isTypeOnly: Boolean + val moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */ + get() = definedExternally +} + +external interface ExternalModuleReference : Node { + override val parent: ImportEqualsDeclaration + val expression: Expression +} + +external interface ImportDeclaration : Statement { + override val parent: dynamic /* SourceFile | ModuleBlock */ + get() = definedExternally + val importClause: ImportClause? + get() = definedExternally + val moduleSpecifier: Expression +} + +external interface ImportClause : NamedDeclaration { + override val parent: ImportDeclaration + val isTypeOnly: Boolean + override val name: Identifier? + get() = definedExternally + val namedBindings: dynamic /* NamespaceImport? | NamedImports? */ + get() = definedExternally +} + +external interface NamespaceImport : NamedDeclaration { + override val parent: ImportClause + override val name: Identifier +} + +external interface NamespaceExport : NamedDeclaration { + override val parent: ExportDeclaration + override val name: Identifier +} + +external interface NamespaceExportDeclaration : DeclarationStatement, JSDocContainer { + override val name: Identifier +} + +external interface ExportDeclaration : DeclarationStatement, JSDocContainer { + override val parent: dynamic /* SourceFile | ModuleBlock */ + get() = definedExternally + val isTypeOnly: Boolean + val exportClause: dynamic /* NamespaceExport? | NamedExports? */ + get() = definedExternally + val moduleSpecifier: Expression? + get() = definedExternally +} + +external interface NamedImports : Node { + override val parent: ImportClause + val elements: NodeArray +} + +external interface NamedExports : Node { + override val parent: ExportDeclaration + val elements: NodeArray +} + +external interface ImportSpecifier : NamedDeclaration { + override val parent: NamedImports + val propertyName: Identifier? + get() = definedExternally + override val name: Identifier +} + +external interface ExportSpecifier : NamedDeclaration { + override val parent: NamedExports + val propertyName: Identifier? + get() = definedExternally + override val name: Identifier +} + +external interface ExportAssignment : DeclarationStatement, JSDocContainer { + override val parent: SourceFile + val isExportEquals: Boolean? + get() = definedExternally + val expression: Expression +} + +external interface FileReference : TextRange { + var fileName: String +} + +external interface CheckJsDirective : TextRange { + var enabled: Boolean +} + +external interface CommentRange : TextRange { + var hasTrailingNewLine: Boolean? + get() = definedExternally + set(value) = definedExternally + var kind: dynamic /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */ + get() = definedExternally + set(value) = definedExternally +} + +external interface SynthesizedComment : CommentRange { + var text: String + var hasLeadingNewline: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface JSDocTypeExpression : TypeNode { + val type: TypeNode +} + +external interface JSDocNameReference : Node { + val name: dynamic /* Identifier | QualifiedName */ + get() = definedExternally +} + +external interface JSDocType : TypeNode { + var _jsDocTypeBrand: Any +} + +external interface JSDocAllType : JSDocType + +external interface JSDocUnknownType : JSDocType + +external interface JSDocNonNullableType : JSDocType { + val type: TypeNode +} + +external interface JSDocNullableType : JSDocType { + val type: TypeNode +} + +external interface JSDocOptionalType : JSDocType { + val type: TypeNode +} + +external interface JSDocFunctionType : JSDocType, SignatureDeclarationBase { + override val kind: Any +} + +external interface JSDocVariadicType : JSDocType { + val type: TypeNode +} + +external interface JSDocNamepathType : JSDocType { + val type: TypeNode +} + +external interface JSDoc : Node { + override val parent: dynamic /* ParameterDeclaration | CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | EmptyStatement | DebuggerStatement | Block | VariableStatement | ExpressionStatement | IfStatement | DoStatement | WhileStatement | ForStatement | ForInStatement | ForOfStatement | BreakStatement | ContinueStatement | ReturnStatement | WithStatement | SwitchStatement | LabeledStatement | ThrowStatement | TryStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | VariableDeclaration | PropertyDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | NamespaceExportDeclaration | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | Token & JSDocContainer */ + get() = definedExternally + val tags: NodeArray? + get() = definedExternally + val comment: dynamic /* String? | NodeArray? */ + get() = definedExternally +} + +external interface JSDocTag : Node { + override val parent: dynamic /* JSDoc | JSDocTypeLiteral */ + get() = definedExternally + val tagName: Identifier + val comment: dynamic /* String? | NodeArray? */ + get() = definedExternally +} + +external interface JSDocLink : Node { + val name: dynamic /* Identifier? | QualifiedName? */ + get() = definedExternally + var text: String +} + +external interface JSDocText : Node { + var text: String +} + +external interface JSDocUnknownTag : JSDocTag + +external interface `T$4` { + val expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ + get() = definedExternally +} + +external interface JSDocAugmentsTag : JSDocTag { + val `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */ +} + +external interface JSDocImplementsTag : JSDocTag { + val `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */ +} + +external interface JSDocAuthorTag : JSDocTag + +external interface JSDocDeprecatedTag : JSDocTag + +external interface JSDocClassTag : JSDocTag + +external interface JSDocPublicTag : JSDocTag + +external interface JSDocPrivateTag : JSDocTag + +external interface JSDocProtectedTag : JSDocTag + +external interface JSDocReadonlyTag : JSDocTag + +external interface JSDocOverrideTag : JSDocTag + +external interface JSDocEnumTag : JSDocTag, Declaration { + override val parent: JSDoc + val typeExpression: JSDocTypeExpression +} + +external interface JSDocThisTag : JSDocTag { + val typeExpression: JSDocTypeExpression +} + +external interface JSDocTemplateTag : JSDocTag { + val constraint: JSDocTypeExpression? + val typeParameters: NodeArray +} + +external interface JSDocSeeTag : JSDocTag { + val name: JSDocNameReference? + get() = definedExternally +} + +external interface JSDocReturnTag : JSDocTag { + val typeExpression: JSDocTypeExpression? + get() = definedExternally +} + +external interface JSDocTypeTag : JSDocTag { + val typeExpression: JSDocTypeExpression +} + +external interface JSDocTypedefTag : JSDocTag, NamedDeclaration { + override val parent: JSDoc + val fullName: dynamic /* JSDocNamespaceDeclaration? | Identifier? */ + get() = definedExternally + override val name: Identifier? + get() = definedExternally + val typeExpression: dynamic /* JSDocTypeExpression? | JSDocTypeLiteral? */ + get() = definedExternally +} + +external interface JSDocCallbackTag : JSDocTag, NamedDeclaration { + override val parent: JSDoc + val fullName: dynamic /* JSDocNamespaceDeclaration? | Identifier? */ + get() = definedExternally + override val name: Identifier? + get() = definedExternally + val typeExpression: JSDocSignature +} + +external interface JSDocSignature : JSDocType, Declaration { + val typeParameters: Array? + get() = definedExternally + val parameters: Array + val type: JSDocReturnTag? +} + +external interface JSDocPropertyLikeTag : JSDocTag, Declaration { + override val parent: JSDoc + val name: dynamic /* Identifier | QualifiedName */ + get() = definedExternally + val typeExpression: JSDocTypeExpression? + get() = definedExternally + val isNameFirst: Boolean + val isBracketed: Boolean +} + +external interface JSDocPropertyTag : JSDocPropertyLikeTag + +external interface JSDocParameterTag : JSDocPropertyLikeTag + +external interface JSDocTypeLiteral : JSDocType { + val jsDocPropertyTags: Array? + get() = definedExternally + val isArrayType: Boolean +} + +external enum class FlowFlags { + Unreachable /* = 1 */, + Start /* = 2 */, + BranchLabel /* = 4 */, + LoopLabel /* = 8 */, + Assignment /* = 16 */, + TrueCondition /* = 32 */, + FalseCondition /* = 64 */, + SwitchClause /* = 128 */, + ArrayMutation /* = 256 */, + Call /* = 512 */, + ReduceLabel /* = 1024 */, + Referenced /* = 2048 */, + Shared /* = 4096 */, + Label /* = 12 */, + Condition /* = 96 */ +} + +external interface FlowNodeBase { + var flags: FlowFlags + var id: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowStart : FlowNodeBase { + var node: dynamic /* FunctionExpression? | ArrowFunction? | MethodDeclaration? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowLabel : FlowNodeBase { + var antecedents: Array? +} + +external interface FlowAssignment : FlowNodeBase { + var node: dynamic /* Expression | VariableDeclaration | BindingElement */ + get() = definedExternally + set(value) = definedExternally + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowCall : FlowNodeBase { + var node: CallExpression + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowCondition : FlowNodeBase { + var node: Expression + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowSwitchClause : FlowNodeBase { + var switchStatement: SwitchStatement + var clauseStart: Number + var clauseEnd: Number + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowArrayMutation : FlowNodeBase { + var node: dynamic /* CallExpression | BinaryExpression */ + get() = definedExternally + set(value) = definedExternally + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowReduceLabel : FlowNodeBase { + var target: FlowLabel + var antecedents: Array + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface IncompleteType { + var flags: TypeFlags + var type: Type +} + +external interface AmdDependency { + var path: String + var name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface SourceFile : Declaration { + fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter + fun getLineEndOfPosition(pos: Number): Number + fun getLineStarts(): Array + fun getPositionOfLineAndCharacter(line: Number, character: Number): Number + fun update(newText: String, textChangeRange: TextChangeRange): SourceFile + val statements: NodeArray + val endOfFileToken: Token + var fileName: String + var text: String + var amdDependencies: Array + var moduleName: String? + get() = definedExternally + set(value) = definedExternally + var referencedFiles: Array + var typeReferenceDirectives: Array + var libReferenceDirectives: Array + var languageVariant: LanguageVariant + var isDeclarationFile: Boolean + var hasNoDefaultLib: Boolean + var languageVersion: ScriptTarget +} + +external interface Bundle : Node { + val prepends: Array + val sourceFiles: Array +} + +external interface InputFiles : Node { + var javascriptPath: String? + get() = definedExternally + set(value) = definedExternally + var javascriptText: String + var javascriptMapPath: String? + get() = definedExternally + set(value) = definedExternally + var javascriptMapText: String? + get() = definedExternally + set(value) = definedExternally + var declarationPath: String? + get() = definedExternally + set(value) = definedExternally + var declarationText: String + var declarationMapPath: String? + get() = definedExternally + set(value) = definedExternally + var declarationMapText: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface UnparsedSource : Node { + var fileName: String + var text: String + val prologues: Array + var helpers: Array? + var referencedFiles: Array + var typeReferenceDirectives: Array? + var libReferenceDirectives: Array + var hasNoDefaultLib: Boolean? + get() = definedExternally + set(value) = definedExternally + var sourceMapPath: String? + get() = definedExternally + set(value) = definedExternally + var sourceMapText: String? + get() = definedExternally + set(value) = definedExternally + val syntheticReferences: Array? + get() = definedExternally + val texts: Array +} + +external interface UnparsedSection : Node { + override val kind: SyntaxKind + override val parent: UnparsedSource + val data: String? + get() = definedExternally +} + +external interface UnparsedPrologue : UnparsedSection { + override val parent: UnparsedSource +} + +external interface UnparsedPrepend : UnparsedSection { + override val parent: UnparsedSource + val texts: Array +} + +external interface UnparsedTextLike : UnparsedSection { + override val kind: dynamic /* SyntaxKind.UnparsedText | SyntaxKind.UnparsedInternalText */ + get() = definedExternally + override val parent: UnparsedSource +} + +external interface UnparsedSyntheticReference : UnparsedSection { + override val parent: UnparsedSource +} + +external interface JsonSourceFile : SourceFile { + override val statements: NodeArray +} + +external interface TsConfigSourceFile : JsonSourceFile { + var extendedSourceFiles: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface JsonMinusNumericLiteral : PrefixUnaryExpression { + override val kind: Any + override val operator: Any + override val operand: NumericLiteral +} + +external interface JsonObjectExpressionStatement : ExpressionStatement { + override val expression: dynamic /* ObjectLiteralExpression | ArrayLiteralExpression | JsonMinusNumericLiteral | NumericLiteral | StringLiteral | TrueLiteral | FalseLiteral | NullLiteral */ + get() = definedExternally +} + +external interface ScriptReferenceHost { + fun getCompilerOptions(): CompilerOptions + fun getSourceFile(fileName: String): SourceFile? + fun getSourceFileByPath(path: String /* String & `T$3` */): SourceFile? + fun getCurrentDirectory(): String +} + +external interface ParseConfigHost { + var useCaseSensitiveFileNames: Boolean + fun readDirectory(rootDir: String, extensions: Array, excludes: Array?, includes: Array, depth: Number = definedExternally): Array + fun fileExists(path: String): Boolean + fun readFile(path: String): String? + val trace: ((s: String) -> Unit)? +} + +external interface `T$5` { + var _isResolvedConfigFileName: Any +} + +external open class OperationCanceledException + +external interface CancellationToken { + fun isCancellationRequested(): Boolean + fun throwIfCancellationRequested() +} + +external interface `T$6` { + var assignable: Number + var identity: Number + var subtype: Number + var strictSubtype: Number +} + +external interface Program : ScriptReferenceHost { + override fun getCurrentDirectory(): String + fun getRootFileNames(): Array + fun getSourceFiles(): Array + fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult + fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getDeclarationDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getConfigFileParsingDiagnostics(): Array + fun getTypeChecker(): TypeChecker + fun getNodeCount(): Number + fun getIdentifierCount(): Number + fun getSymbolCount(): Number + fun getTypeCount(): Number + fun getInstantiationCount(): Number + fun getRelationCacheSizes(): `T$6` + fun isSourceFileFromExternalLibrary(file: SourceFile): Boolean + fun isSourceFileDefaultLibrary(file: SourceFile): Boolean + fun getProjectReferences(): Array? + fun getResolvedProjectReferences(): Array? +} + +external interface ResolvedProjectReference { + var commandLine: ParsedCommandLine + var sourceFile: SourceFile + var references: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface CustomTransformer { + fun transformSourceFile(node: SourceFile): SourceFile + fun transformBundle(node: Bundle): Bundle +} + +external interface CustomTransformers { + var before: Array | CustomTransformerFactory */>? + get() = definedExternally + set(value) = definedExternally + var after: Array | CustomTransformerFactory */>? + get() = definedExternally + set(value) = definedExternally + var afterDeclarations: Array | CustomTransformerFactory */>? + get() = definedExternally + set(value) = definedExternally +} + +external interface SourceMapSpan { + var emittedLine: Number + var emittedColumn: Number + var sourceLine: Number + var sourceColumn: Number + var nameIndex: Number? + get() = definedExternally + set(value) = definedExternally + var sourceIndex: Number +} + +external enum class ExitStatus { + Success /* = 0 */, + DiagnosticsPresent_OutputsSkipped /* = 1 */, + DiagnosticsPresent_OutputsGenerated /* = 2 */, + InvalidProject_OutputsSkipped /* = 3 */, + ProjectReferenceCycle_OutputsSkipped /* = 4 */, + ProjectReferenceCycle_OutputsSkupped /* = 4 */ +} + +external interface EmitResult { + var emitSkipped: Boolean + var diagnostics: Array + var emittedFiles: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$7` { + var typeArguments: NodeArray? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeChecker { + fun getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type + fun getDeclaredTypeOfSymbol(symbol: Symbol): Type + fun getPropertiesOfType(type: Type): Array + fun getPropertyOfType(type: Type, propertyName: String): Symbol? + fun getPrivateIdentifierPropertyOfType(leftType: Type, name: String, location: Node): Symbol? + fun getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo? + fun getSignaturesOfType(type: Type, kind: SignatureKind): Array + fun getIndexTypeOfType(type: Type, kind: IndexKind): Type? + fun getBaseTypes(type: InterfaceType): Array + fun getBaseTypeOfLiteralType(type: Type): Type + fun getWidenedType(type: Type): Type + fun getReturnTypeOfSignature(signature: Signature): Type + fun getNullableType(type: Type, flags: TypeFlags): Type + fun getNonNullableType(type: Type): Type + fun getTypeArguments(type: TypeReference): Array + fun typeToTypeNode(type: Type, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeNode? + fun signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ + fun indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): IndexSignatureDeclaration? + fun symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* Identifier? | QualifiedName? */ + fun symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): Expression? + fun symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): NodeArray? + fun symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): ParameterDeclaration? + fun typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeParameterDeclaration? + fun getSymbolsInScope(location: Node, meaning: SymbolFlags): Array + fun getSymbolAtLocation(node: Node): Symbol? + fun getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: String): Array + fun getShorthandAssignmentValueSymbol(location: Node?): Symbol? + fun getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol? + fun getExportSpecifierLocalTargetSymbol(location: Identifier): Symbol? + fun getExportSymbolOfSymbol(symbol: Symbol): Symbol + fun getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol? + fun getTypeOfAssignmentPattern(pattern: ObjectLiteralExpression): Type + fun getTypeOfAssignmentPattern(pattern: ArrayLiteralExpression): Type + fun getTypeAtLocation(node: Node): Type + fun getTypeFromTypeNode(node: TypeNode): Type + fun signatureToString(signature: Signature, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally, kind: SignatureKind = definedExternally): String + fun typeToString(type: Type, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun symbolToString(symbol: Symbol, enclosingDeclaration: Node = definedExternally, meaning: SymbolFlags = definedExternally, flags: SymbolFormatFlags = definedExternally): String + fun typePredicateToString(predicate: ThisTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun typePredicateToString(predicate: ThisTypePredicate): String + fun typePredicateToString(predicate: ThisTypePredicate, enclosingDeclaration: Node = definedExternally): String + fun typePredicateToString(predicate: IdentifierTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun typePredicateToString(predicate: IdentifierTypePredicate): String + fun typePredicateToString(predicate: IdentifierTypePredicate, enclosingDeclaration: Node = definedExternally): String + fun typePredicateToString(predicate: AssertsThisTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun typePredicateToString(predicate: AssertsThisTypePredicate): String + fun typePredicateToString(predicate: AssertsThisTypePredicate, enclosingDeclaration: Node = definedExternally): String + fun typePredicateToString(predicate: AssertsIdentifierTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun typePredicateToString(predicate: AssertsIdentifierTypePredicate): String + fun typePredicateToString(predicate: AssertsIdentifierTypePredicate, enclosingDeclaration: Node = definedExternally): String + fun getFullyQualifiedName(symbol: Symbol): String + fun getAugmentedPropertiesOfType(type: Type): Array + fun getRootSymbols(symbol: Symbol): Array + fun getSymbolOfExpando(node: Node, allowDeclaration: Boolean): Symbol? + fun getContextualType(node: Expression): Type? + fun getResolvedSignature(node: CallExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: CallExpression): Signature? + fun getResolvedSignature(node: CallExpression, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: NewExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: NewExpression): Signature? + fun getResolvedSignature(node: NewExpression, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: TaggedTemplateExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: TaggedTemplateExpression): Signature? + fun getResolvedSignature(node: TaggedTemplateExpression, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: Decorator, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: Decorator): Signature? + fun getResolvedSignature(node: Decorator, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: JsxSelfClosingElement, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: JsxSelfClosingElement): Signature? + fun getResolvedSignature(node: JsxSelfClosingElement, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: JsxOpeningElement, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: JsxOpeningElement): Signature? + fun getResolvedSignature(node: JsxOpeningElement, candidatesOutArray: Array = definedExternally): Signature? + fun getSignatureFromDeclaration(declaration: CallSignatureDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: ConstructSignatureDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: MethodSignature): Signature? + fun getSignatureFromDeclaration(declaration: IndexSignatureDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: FunctionTypeNode): Signature? + fun getSignatureFromDeclaration(declaration: ConstructorTypeNode): Signature? + fun getSignatureFromDeclaration(declaration: JSDocFunctionType): Signature? + fun getSignatureFromDeclaration(declaration: FunctionDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: MethodDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: ConstructorDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: GetAccessorDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: SetAccessorDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: FunctionExpression): Signature? + fun getSignatureFromDeclaration(declaration: ArrowFunction): Signature? + fun isImplementationOfOverload(node: CallSignatureDeclaration): Boolean? + fun isImplementationOfOverload(node: ConstructSignatureDeclaration): Boolean? + fun isImplementationOfOverload(node: MethodSignature): Boolean? + fun isImplementationOfOverload(node: IndexSignatureDeclaration): Boolean? + fun isImplementationOfOverload(node: FunctionTypeNode): Boolean? + fun isImplementationOfOverload(node: ConstructorTypeNode): Boolean? + fun isImplementationOfOverload(node: JSDocFunctionType): Boolean? + fun isImplementationOfOverload(node: FunctionDeclaration): Boolean? + fun isImplementationOfOverload(node: MethodDeclaration): Boolean? + fun isImplementationOfOverload(node: ConstructorDeclaration): Boolean? + fun isImplementationOfOverload(node: GetAccessorDeclaration): Boolean? + fun isImplementationOfOverload(node: SetAccessorDeclaration): Boolean? + fun isImplementationOfOverload(node: FunctionExpression): Boolean? + fun isImplementationOfOverload(node: ArrowFunction): Boolean? + fun isUndefinedSymbol(symbol: Symbol): Boolean + fun isArgumentsSymbol(symbol: Symbol): Boolean + fun isUnknownSymbol(symbol: Symbol): Boolean + fun getConstantValue(node: EnumMember): dynamic /* String? | Number? */ + fun getConstantValue(node: PropertyAccessExpression): dynamic /* String? | Number? */ + fun getConstantValue(node: ElementAccessExpression): dynamic /* String? | Number? */ + fun isValidPropertyAccess(node: PropertyAccessExpression, propertyName: String): Boolean + fun isValidPropertyAccess(node: QualifiedName, propertyName: String): Boolean + fun isValidPropertyAccess(node: ImportTypeNode, propertyName: String): Boolean + fun getAliasedSymbol(symbol: Symbol): Symbol + fun getExportsOfModule(moduleSymbol: Symbol): Array + fun getJsxIntrinsicTagNamesAt(location: Node): Array + fun isOptionalParameter(node: ParameterDeclaration): Boolean + fun getAmbientModules(): Array + fun tryGetMemberInModuleExports(memberName: String, moduleSymbol: Symbol): Symbol? + fun getApparentType(type: Type): Type + fun getBaseConstraintOfType(type: Type): Type? + fun getDefaultFromTypeParameter(type: Type): Type? + fun runWithCancellationToken(token: CancellationToken, cb: (checker: TypeChecker) -> T): T +} + +external enum class NodeBuilderFlags { + None /* = 0 */, + NoTruncation /* = 1 */, + WriteArrayAsGenericType /* = 2 */, + GenerateNamesForShadowedTypeParams /* = 4 */, + UseStructuralFallback /* = 8 */, + ForbidIndexedAccessSymbolReferences /* = 16 */, + WriteTypeArgumentsOfSignature /* = 32 */, + UseFullyQualifiedType /* = 64 */, + UseOnlyExternalAliasing /* = 128 */, + SuppressAnyReturnType /* = 256 */, + WriteTypeParametersInQualifiedName /* = 512 */, + MultilineObjectLiterals /* = 1024 */, + WriteClassExpressionAsTypeLiteral /* = 2048 */, + UseTypeOfFunction /* = 4096 */, + OmitParameterModifiers /* = 8192 */, + UseAliasDefinedOutsideCurrentScope /* = 16384 */, + UseSingleQuotesForStringLiteralType /* = 268435456 */, + NoTypeReduction /* = 536870912 */, + NoUndefinedOptionalParameterType /* = 1073741824 */, + AllowThisInObjectLiteral /* = 32768 */, + AllowQualifiedNameInPlaceOfIdentifier /* = 65536 */, + AllowQualifedNameInPlaceOfIdentifier /* = 65536 */, + AllowAnonymousIdentifier /* = 131072 */, + AllowEmptyUnionOrIntersection /* = 262144 */, + AllowEmptyTuple /* = 524288 */, + AllowUniqueESSymbolType /* = 1048576 */, + AllowEmptyIndexInfoType /* = 2097152 */, + AllowNodeModulesRelativePaths /* = 67108864 */, + IgnoreErrors /* = 70221824 */, + InObjectTypeLiteral /* = 4194304 */, + InTypeAlias /* = 8388608 */, + InInitialEntityName /* = 16777216 */ +} + +external enum class TypeFormatFlags { + None /* = 0 */, + NoTruncation /* = 1 */, + WriteArrayAsGenericType /* = 2 */, + UseStructuralFallback /* = 8 */, + WriteTypeArgumentsOfSignature /* = 32 */, + UseFullyQualifiedType /* = 64 */, + SuppressAnyReturnType /* = 256 */, + MultilineObjectLiterals /* = 1024 */, + WriteClassExpressionAsTypeLiteral /* = 2048 */, + UseTypeOfFunction /* = 4096 */, + OmitParameterModifiers /* = 8192 */, + UseAliasDefinedOutsideCurrentScope /* = 16384 */, + UseSingleQuotesForStringLiteralType /* = 268435456 */, + NoTypeReduction /* = 536870912 */, + AllowUniqueESSymbolType /* = 1048576 */, + AddUndefined /* = 131072 */, + WriteArrowStyleSignature /* = 262144 */, + InArrayType /* = 524288 */, + InElementType /* = 2097152 */, + InFirstTypeArgument /* = 4194304 */, + InTypeAlias /* = 8388608 */, + WriteOwnNameForAnyLike /* = 0 */, + NodeBuilderFlagsMask /* = 814775659 */ +} + +external enum class SymbolFormatFlags { + None /* = 0 */, + WriteTypeParametersOrArguments /* = 1 */, + UseOnlyExternalAliasing /* = 2 */, + AllowAnyNodeKind /* = 4 */, + UseAliasDefinedOutsideCurrentScope /* = 8 */ +} + +external enum class TypePredicateKind { + This /* = 0 */, + Identifier /* = 1 */, + AssertsThis /* = 2 */, + AssertsIdentifier /* = 3 */ +} + +external interface TypePredicateBase { + var kind: TypePredicateKind + var type: Type? +} + +external interface ThisTypePredicate : TypePredicateBase { + var parameterName: Any? + var parameterIndex: Any? +} + +external interface IdentifierTypePredicate : TypePredicateBase { + var parameterName: String + var parameterIndex: Number +} + +external interface AssertsThisTypePredicate : TypePredicateBase { + var parameterName: Any? + var parameterIndex: Any? + override var type: Type? +} + +external interface AssertsIdentifierTypePredicate : TypePredicateBase { + var parameterName: String + var parameterIndex: Number + override var type: Type? +} + +external enum class SymbolFlags { + None /* = 0 */, + FunctionScopedVariable /* = 1 */, + BlockScopedVariable /* = 2 */, + Property /* = 4 */, + EnumMember /* = 8 */, + Function /* = 16 */, + Class /* = 32 */, + Interface /* = 64 */, + ConstEnum /* = 128 */, + RegularEnum /* = 256 */, + ValueModule /* = 512 */, + NamespaceModule /* = 1024 */, + TypeLiteral /* = 2048 */, + ObjectLiteral /* = 4096 */, + Method /* = 8192 */, + Constructor /* = 16384 */, + GetAccessor /* = 32768 */, + SetAccessor /* = 65536 */, + Signature /* = 131072 */, + TypeParameter /* = 262144 */, + TypeAlias /* = 524288 */, + ExportValue /* = 1048576 */, + Alias /* = 2097152 */, + Prototype /* = 4194304 */, + ExportStar /* = 8388608 */, + Optional /* = 16777216 */, + Transient /* = 33554432 */, + Assignment /* = 67108864 */, + ModuleExports /* = 134217728 */, + Enum /* = 384 */, + Variable /* = 3 */, + Value /* = 111551 */, + Type /* = 788968 */, + Namespace /* = 1920 */, + Module /* = 1536 */, + Accessor /* = 98304 */, + FunctionScopedVariableExcludes /* = 111550 */, + BlockScopedVariableExcludes /* = 111551 */, + ParameterExcludes /* = 111551 */, + PropertyExcludes /* = 0 */, + EnumMemberExcludes /* = 900095 */, + FunctionExcludes /* = 110991 */, + ClassExcludes /* = 899503 */, + InterfaceExcludes /* = 788872 */, + RegularEnumExcludes /* = 899327 */, + ConstEnumExcludes /* = 899967 */, + ValueModuleExcludes /* = 110735 */, + NamespaceModuleExcludes /* = 0 */, + MethodExcludes /* = 103359 */, + GetAccessorExcludes /* = 46015 */, + SetAccessorExcludes /* = 78783 */, + TypeParameterExcludes /* = 526824 */, + TypeAliasExcludes /* = 788968 */, + AliasExcludes /* = 2097152 */, + ModuleMember /* = 2623475 */, + ExportHasLocal /* = 944 */, + BlockScoped /* = 418 */, + PropertyOrAccessor /* = 98308 */, + ClassMember /* = 106500 */ +} + +external interface Symbol { + val name: String + fun getFlags(): SymbolFlags + fun getEscapedName(): dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + fun getName(): String + fun getDeclarations(): Array? + fun getDocumentationComment(typeChecker: TypeChecker?): Array + fun getJsDocTags(checker: TypeChecker = definedExternally): Array + var flags: SymbolFlags + var escapedName: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + get() = definedExternally + set(value) = definedExternally + var declarations: Array? + get() = definedExternally + set(value) = definedExternally + var valueDeclaration: Declaration? + get() = definedExternally + set(value) = definedExternally + var members: SymbolTable? + get() = definedExternally + set(value) = definedExternally + var exports: SymbolTable? + get() = definedExternally + set(value) = definedExternally + var globalExports: SymbolTable? + get() = definedExternally + set(value) = definedExternally +} + +external enum class InternalSymbolName { + Call /* = "__call" */, + Constructor /* = "__constructor" */, + New /* = "__new" */, + Index /* = "__index" */, + ExportStar /* = "__export" */, + Global /* = "__global" */, + Missing /* = "__missing" */, + Type /* = "__type" */, + Object /* = "__object" */, + JSXAttributes /* = "__jsxAttributes" */, + Class /* = "__class" */, + Function /* = "__function" */, + Computed /* = "__computed" */, + Resolving /* = "__resolving__" */, + ExportEquals /* = "export=" */, + Default /* = "default" */, + This /* = "this" */ +} + +external interface `T$8` { + var __escapedIdentifier: Unit +} + +external interface ReadonlyUnderscoreEscapedMap : ReadonlyESMap + +external interface UnderscoreEscapedMap : ESMap, ReadonlyUnderscoreEscapedMap + +external enum class TypeFlags { + Any /* = 1 */, + Unknown /* = 2 */, + String /* = 4 */, + Number /* = 8 */, + Boolean /* = 16 */, + Enum /* = 32 */, + BigInt /* = 64 */, + StringLiteral /* = 128 */, + NumberLiteral /* = 256 */, + BooleanLiteral /* = 512 */, + EnumLiteral /* = 1024 */, + BigIntLiteral /* = 2048 */, + ESSymbol /* = 4096 */, + UniqueESSymbol /* = 8192 */, + Void /* = 16384 */, + Undefined /* = 32768 */, + Null /* = 65536 */, + Never /* = 131072 */, + TypeParameter /* = 262144 */, + Object /* = 524288 */, + Union /* = 1048576 */, + Intersection /* = 2097152 */, + Index /* = 4194304 */, + IndexedAccess /* = 8388608 */, + Conditional /* = 16777216 */, + Substitution /* = 33554432 */, + NonPrimitive /* = 67108864 */, + TemplateLiteral /* = 134217728 */, + StringMapping /* = 268435456 */, + Literal /* = 2944 */, + Unit /* = 109440 */, + StringOrNumberLiteral /* = 384 */, + PossiblyFalsy /* = 117724 */, + StringLike /* = 402653316 */, + NumberLike /* = 296 */, + BigIntLike /* = 2112 */, + BooleanLike /* = 528 */, + EnumLike /* = 1056 */, + ESSymbolLike /* = 12288 */, + VoidLike /* = 49152 */, + UnionOrIntersection /* = 3145728 */, + StructuredType /* = 3670016 */, + TypeVariable /* = 8650752 */, + InstantiableNonPrimitive /* = 58982400 */, + InstantiablePrimitive /* = 406847488 */, + Instantiable /* = 465829888 */, + StructuredOrInstantiable /* = 469499904 */, + Narrowable /* = 536624127 */ +} + +external interface Type { + fun getFlags(): TypeFlags + fun getSymbol(): Symbol? + fun getProperties(): Array + fun getProperty(propertyName: String): Symbol? + fun getApparentProperties(): Array + fun getCallSignatures(): Array + fun getConstructSignatures(): Array + fun getStringIndexType(): Type? + fun getNumberIndexType(): Type? + fun getBaseTypes(): Array? + fun getNonNullableType(): Type + fun getConstraint(): Type? + fun getDefault(): Type? + fun isUnion(): Boolean + fun isIntersection(): Boolean + fun isUnionOrIntersection(): Boolean + fun isLiteral(): Boolean + fun isStringLiteral(): Boolean + fun isNumberLiteral(): Boolean + fun isTypeParameter(): Boolean + fun isClassOrInterface(): Boolean + fun isClass(): Boolean + var flags: TypeFlags + var symbol: Symbol + var pattern: dynamic /* ObjectBindingPattern? | ArrayBindingPattern? | ObjectLiteralExpression? | ArrayLiteralExpression? */ + get() = definedExternally + set(value) = definedExternally + var aliasSymbol: Symbol? + get() = definedExternally + set(value) = definedExternally + var aliasTypeArguments: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface LiteralType : Type { + var value: dynamic /* String | Number | PseudoBigInt */ + get() = definedExternally + set(value) = definedExternally + var freshType: LiteralType + var regularType: LiteralType +} + +external interface UniqueESSymbolType : Type { + override var symbol: Symbol + var escapedName: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + get() = definedExternally + set(value) = definedExternally +} + +external interface StringLiteralType : LiteralType { + override var value: String +} + +external interface NumberLiteralType : LiteralType { + override var value: Number +} + +external interface BigIntLiteralType : LiteralType { + override var value: PseudoBigInt +} + +external interface EnumType : Type + +external enum class ObjectFlags { + Class /* = 1 */, + Interface /* = 2 */, + Reference /* = 4 */, + Tuple /* = 8 */, + Anonymous /* = 16 */, + Mapped /* = 32 */, + Instantiated /* = 64 */, + ObjectLiteral /* = 128 */, + EvolvingArray /* = 256 */, + ObjectLiteralPatternWithComputedProperties /* = 512 */, + ReverseMapped /* = 1024 */, + JsxAttributes /* = 2048 */, + MarkerType /* = 4096 */, + JSLiteral /* = 8192 */, + FreshLiteral /* = 16384 */, + ArrayLiteral /* = 32768 */, + ClassOrInterface /* = 3 */, + ContainsSpread /* = 4194304 */, + ObjectRestType /* = 8388608 */ +} + +external interface ObjectType : Type { + var objectFlags: ObjectFlags +} + +external interface InterfaceType : ObjectType { + var typeParameters: Array? + var outerTypeParameters: Array? + var localTypeParameters: Array? + var thisType: TypeParameter? +} + +external interface InterfaceTypeWithDeclaredMembers : InterfaceType { + var declaredProperties: Array + var declaredCallSignatures: Array + var declaredConstructSignatures: Array + var declaredStringIndexInfo: IndexInfo? + get() = definedExternally + set(value) = definedExternally + var declaredNumberIndexInfo: IndexInfo? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeReference : ObjectType { + var typeArguments: Array? + get() = definedExternally + set(value) = definedExternally + var target: GenericType + var node: dynamic /* TypeReferenceNode? | ArrayTypeNode? | TupleTypeNode? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface DeferredTypeReference : TypeReference + +external interface GenericType : InterfaceType, TypeReference + +external enum class ElementFlags { + Required /* = 1 */, + Optional /* = 2 */, + Rest /* = 4 */, + Variadic /* = 8 */, + Fixed /* = 3 */, + Variable /* = 12 */, + NonRequired /* = 14 */, + NonRest /* = 11 */ +} + +external interface TupleType : GenericType { + var elementFlags: Array + var minLength: Number + var fixedLength: Number + var hasRestElement: Boolean + var combinedFlags: ElementFlags + var readonly: Boolean + var labeledElementDeclarations: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface TupleTypeReference : TypeReference { + override var target: TupleType +} + +external interface UnionOrIntersectionType : Type { + var types: Array +} + +external interface UnionType : UnionOrIntersectionType + +external interface IntersectionType : UnionOrIntersectionType + +external interface EvolvingArrayType : ObjectType { + var elementType: Type + var finalArrayType: Type? + get() = definedExternally + set(value) = definedExternally +} + +external interface InstantiableType : Type + +external interface TypeParameter : InstantiableType + +external interface IndexedAccessType : InstantiableType { + var objectType: Type + var indexType: Type + var constraint: Type? + get() = definedExternally + set(value) = definedExternally + var simplifiedForReading: Type? + get() = definedExternally + set(value) = definedExternally + var simplifiedForWriting: Type? + get() = definedExternally + set(value) = definedExternally +} + +external interface IndexType : InstantiableType { + var type: dynamic /* InstantiableType | UnionOrIntersectionType */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ConditionalRoot { + var node: ConditionalTypeNode + var checkType: Type + var extendsType: Type + var isDistributive: Boolean + var inferTypeParameters: Array? + get() = definedExternally + set(value) = definedExternally + var outerTypeParameters: Array? + get() = definedExternally + set(value) = definedExternally + var instantiations: Map? + get() = definedExternally + set(value) = definedExternally + var aliasSymbol: Symbol? + get() = definedExternally + set(value) = definedExternally + var aliasTypeArguments: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface ConditionalType : InstantiableType { + var root: ConditionalRoot + var checkType: Type + var extendsType: Type + var resolvedTrueType: Type + var resolvedFalseType: Type +} + +external interface TemplateLiteralType : InstantiableType { + var texts: Array + var types: Array +} + +external interface StringMappingType : InstantiableType { + override var symbol: Symbol + var type: Type +} + +external interface SubstitutionType : InstantiableType { + var objectFlags: ObjectFlags + var baseType: Type + var substitute: Type +} + +external enum class SignatureKind { + Call /* = 0 */, + Construct /* = 1 */ +} + +external interface Signature { + fun getDeclaration(): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ + fun getTypeParameters(): Array? + fun getParameters(): Array + fun getReturnType(): Type + fun getDocumentationComment(typeChecker: TypeChecker?): Array + fun getJsDocTags(): Array + var declaration: dynamic /* CallSignatureDeclaration? | ConstructSignatureDeclaration? | MethodSignature? | IndexSignatureDeclaration? | FunctionTypeNode? | ConstructorTypeNode? | JSDocFunctionType? | FunctionDeclaration? | MethodDeclaration? | ConstructorDeclaration? | GetAccessorDeclaration? | SetAccessorDeclaration? | FunctionExpression? | ArrowFunction? | JSDocSignature? */ + get() = definedExternally + set(value) = definedExternally + var typeParameters: Array? + get() = definedExternally + set(value) = definedExternally + var parameters: Array +} + +external enum class IndexKind { + String /* = 0 */, + Number /* = 1 */ +} + +external interface IndexInfo { + var type: Type + var isReadonly: Boolean + var declaration: IndexSignatureDeclaration? + get() = definedExternally + set(value) = definedExternally +} + +external enum class InferencePriority { + NakedTypeVariable /* = 1 */, + SpeculativeTuple /* = 2 */, + SubstituteSource /* = 4 */, + HomomorphicMappedType /* = 8 */, + PartialHomomorphicMappedType /* = 16 */, + MappedTypeConstraint /* = 32 */, + ContravariantConditional /* = 64 */, + ReturnType /* = 128 */, + LiteralKeyof /* = 256 */, + NoConstraints /* = 512 */, + AlwaysStrict /* = 1024 */, + MaxValue /* = 2048 */, + PriorityImpliesCombination /* = 416 */, + Circularity /* = -1 */ +} + +external interface FileExtensionInfo { + var extension: String + var isMixedContent: Boolean + var scriptKind: ScriptKind? + get() = definedExternally + set(value) = definedExternally +} + +external interface DiagnosticMessage { + var key: String + var category: DiagnosticCategory + var code: Number + var message: String + var reportsUnnecessary: Any? + get() = definedExternally + set(value) = definedExternally + var reportsDeprecated: Any? + get() = definedExternally + set(value) = definedExternally +} + +external interface DiagnosticMessageChain { + var messageText: String + var category: DiagnosticCategory + var code: Number + var next: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface Diagnostic : DiagnosticRelatedInformation { + var reportsUnnecessary: Any? + get() = definedExternally + set(value) = definedExternally + var reportsDeprecated: Any? + get() = definedExternally + set(value) = definedExternally + var source: String? + get() = definedExternally + set(value) = definedExternally + var relatedInformation: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface DiagnosticRelatedInformation { + var category: DiagnosticCategory + var code: Number + var file: SourceFile? + var start: Number? + var length: Number? + var messageText: dynamic /* String | DiagnosticMessageChain */ + get() = definedExternally + set(value) = definedExternally +} + +external interface DiagnosticWithLocation : Diagnostic + +external enum class DiagnosticCategory { + Warning /* = 0 */, + Error /* = 1 */, + Suggestion /* = 2 */, + Message /* = 3 */ +} + +external enum class ModuleResolutionKind { + Classic /* = 1 */, + NodeJs /* = 2 */ +} + +external interface PluginImport { + var name: String +} + +external interface ProjectReference { + var path: String + var originalPath: String? + get() = definedExternally + set(value) = definedExternally + var prepend: Boolean? + get() = definedExternally + set(value) = definedExternally + var circular: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external enum class WatchFileKind { + FixedPollingInterval /* = 0 */, + PriorityPollingInterval /* = 1 */, + DynamicPriorityPolling /* = 2 */, + FixedChunkSizePolling /* = 3 */, + UseFsEvents /* = 4 */, + UseFsEventsOnParentDirectory /* = 5 */ +} + +external enum class WatchDirectoryKind { + UseFsEvents /* = 0 */, + FixedPollingInterval /* = 1 */, + DynamicPriorityPolling /* = 2 */, + FixedChunkSizePolling /* = 3 */ +} + +external enum class PollingWatchKind { + FixedInterval /* = 0 */, + PriorityInterval /* = 1 */, + DynamicPriority /* = 2 */, + FixedChunkSize /* = 3 */ +} + +external interface CompilerOptions { + var allowJs: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowSyntheticDefaultImports: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowUmdGlobalAccess: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowUnreachableCode: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowUnusedLabels: Boolean? + get() = definedExternally + set(value) = definedExternally + var alwaysStrict: Boolean? + get() = definedExternally + set(value) = definedExternally + var baseUrl: String? + get() = definedExternally + set(value) = definedExternally + var charset: String? + get() = definedExternally + set(value) = definedExternally + var checkJs: Boolean? + get() = definedExternally + set(value) = definedExternally + var declaration: Boolean? + get() = definedExternally + set(value) = definedExternally + var declarationMap: Boolean? + get() = definedExternally + set(value) = definedExternally + var emitDeclarationOnly: Boolean? + get() = definedExternally + set(value) = definedExternally + var declarationDir: String? + get() = definedExternally + set(value) = definedExternally + var disableSizeLimit: Boolean? + get() = definedExternally + set(value) = definedExternally + var disableSourceOfProjectReferenceRedirect: Boolean? + get() = definedExternally + set(value) = definedExternally + var disableSolutionSearching: Boolean? + get() = definedExternally + set(value) = definedExternally + var disableReferencedProjectLoad: Boolean? + get() = definedExternally + set(value) = definedExternally + var downlevelIteration: Boolean? + get() = definedExternally + set(value) = definedExternally + var emitBOM: Boolean? + get() = definedExternally + set(value) = definedExternally + var emitDecoratorMetadata: Boolean? + get() = definedExternally + set(value) = definedExternally + var experimentalDecorators: Boolean? + get() = definedExternally + set(value) = definedExternally + var forceConsistentCasingInFileNames: Boolean? + get() = definedExternally + set(value) = definedExternally + var importHelpers: Boolean? + get() = definedExternally + set(value) = definedExternally + var importsNotUsedAsValues: ImportsNotUsedAsValues? + get() = definedExternally + set(value) = definedExternally + var inlineSourceMap: Boolean? + get() = definedExternally + set(value) = definedExternally + var inlineSources: Boolean? + get() = definedExternally + set(value) = definedExternally + var isolatedModules: Boolean? + get() = definedExternally + set(value) = definedExternally + var jsx: JsxEmit? + get() = definedExternally + set(value) = definedExternally + var keyofStringsOnly: Boolean? + get() = definedExternally + set(value) = definedExternally + var lib: Array? + get() = definedExternally + set(value) = definedExternally + var locale: String? + get() = definedExternally + set(value) = definedExternally + var mapRoot: String? + get() = definedExternally + set(value) = definedExternally + var maxNodeModuleJsDepth: Number? + get() = definedExternally + set(value) = definedExternally + var module: ModuleKind? + get() = definedExternally + set(value) = definedExternally + var moduleResolution: ModuleResolutionKind? + get() = definedExternally + set(value) = definedExternally + var newLine: NewLineKind? + get() = definedExternally + set(value) = definedExternally + var noEmit: Boolean? + get() = definedExternally + set(value) = definedExternally + var noEmitHelpers: Boolean? + get() = definedExternally + set(value) = definedExternally + var noEmitOnError: Boolean? + get() = definedExternally + set(value) = definedExternally + var noErrorTruncation: Boolean? + get() = definedExternally + set(value) = definedExternally + var noFallthroughCasesInSwitch: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitAny: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitReturns: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitThis: Boolean? + get() = definedExternally + set(value) = definedExternally + var noStrictGenericChecks: Boolean? + get() = definedExternally + set(value) = definedExternally + var noUnusedLocals: Boolean? + get() = definedExternally + set(value) = definedExternally + var noUnusedParameters: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitUseStrict: Boolean? + get() = definedExternally + set(value) = definedExternally + var noPropertyAccessFromIndexSignature: Boolean? + get() = definedExternally + set(value) = definedExternally + var assumeChangesOnlyAffectDirectDependencies: Boolean? + get() = definedExternally + set(value) = definedExternally + var noLib: Boolean? + get() = definedExternally + set(value) = definedExternally + var noResolve: Boolean? + get() = definedExternally + set(value) = definedExternally + var noUncheckedIndexedAccess: Boolean? + get() = definedExternally + set(value) = definedExternally + var out: String? + get() = definedExternally + set(value) = definedExternally + var outDir: String? + get() = definedExternally + set(value) = definedExternally + var outFile: String? + get() = definedExternally + set(value) = definedExternally + var paths: MapLike>? + get() = definedExternally + set(value) = definedExternally + var preserveConstEnums: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitOverride: Boolean? + get() = definedExternally + set(value) = definedExternally + var preserveSymlinks: Boolean? + get() = definedExternally + set(value) = definedExternally + var project: String? + get() = definedExternally + set(value) = definedExternally + var reactNamespace: String? + get() = definedExternally + set(value) = definedExternally + var jsxFactory: String? + get() = definedExternally + set(value) = definedExternally + var jsxFragmentFactory: String? + get() = definedExternally + set(value) = definedExternally + var jsxImportSource: String? + get() = definedExternally + set(value) = definedExternally + var composite: Boolean? + get() = definedExternally + set(value) = definedExternally + var incremental: Boolean? + get() = definedExternally + set(value) = definedExternally + var tsBuildInfoFile: String? + get() = definedExternally + set(value) = definedExternally + var removeComments: Boolean? + get() = definedExternally + set(value) = definedExternally + var rootDir: String? + get() = definedExternally + set(value) = definedExternally + var rootDirs: Array? + get() = definedExternally + set(value) = definedExternally + var skipLibCheck: Boolean? + get() = definedExternally + set(value) = definedExternally + var skipDefaultLibCheck: Boolean? + get() = definedExternally + set(value) = definedExternally + var sourceMap: Boolean? + get() = definedExternally + set(value) = definedExternally + var sourceRoot: String? + get() = definedExternally + set(value) = definedExternally + var strict: Boolean? + get() = definedExternally + set(value) = definedExternally + var strictFunctionTypes: Boolean? + get() = definedExternally + set(value) = definedExternally + var strictBindCallApply: Boolean? + get() = definedExternally + set(value) = definedExternally + var strictNullChecks: Boolean? + get() = definedExternally + set(value) = definedExternally + var strictPropertyInitialization: Boolean? + get() = definedExternally + set(value) = definedExternally + var stripInternal: Boolean? + get() = definedExternally + set(value) = definedExternally + var suppressExcessPropertyErrors: Boolean? + get() = definedExternally + set(value) = definedExternally + var suppressImplicitAnyIndexErrors: Boolean? + get() = definedExternally + set(value) = definedExternally + var target: ScriptTarget? + get() = definedExternally + set(value) = definedExternally + var traceResolution: Boolean? + get() = definedExternally + set(value) = definedExternally + var resolveJsonModule: Boolean? + get() = definedExternally + set(value) = definedExternally + var types: Array? + get() = definedExternally + set(value) = definedExternally + var typeRoots: Array? + get() = definedExternally + set(value) = definedExternally + var esModuleInterop: Boolean? + get() = definedExternally + set(value) = definedExternally + var useDefineForClassFields: Boolean? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? | TsConfigSourceFile? */ + @nativeSetter + operator fun set(option: String, value: String?) + @nativeSetter + operator fun set(option: String, value: Number?) + @nativeSetter + operator fun set(option: String, value: Boolean?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: MapLike>?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: TsConfigSourceFile?) +} + +external interface WatchOptions { + var watchFile: WatchFileKind? + get() = definedExternally + set(value) = definedExternally + var watchDirectory: WatchDirectoryKind? + get() = definedExternally + set(value) = definedExternally + var fallbackPolling: PollingWatchKind? + get() = definedExternally + set(value) = definedExternally + var synchronousWatchDirectory: Boolean? + get() = definedExternally + set(value) = definedExternally + var excludeDirectories: Array? + get() = definedExternally + set(value) = definedExternally + var excludeFiles: Array? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ + @nativeSetter + operator fun set(option: String, value: String?) + @nativeSetter + operator fun set(option: String, value: Number?) + @nativeSetter + operator fun set(option: String, value: Boolean?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: MapLike>?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) +} + +external interface TypeAcquisition { + var enableAutoDiscovery: Boolean? + get() = definedExternally + set(value) = definedExternally + var enable: Boolean? + get() = definedExternally + set(value) = definedExternally + var include: Array? + get() = definedExternally + set(value) = definedExternally + var exclude: Array? + get() = definedExternally + set(value) = definedExternally + var disableFilenameBasedTypeAcquisition: Boolean? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ + @nativeSetter + operator fun set(option: String, value: String?) + @nativeSetter + operator fun set(option: String, value: Number?) + @nativeSetter + operator fun set(option: String, value: Boolean?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: MapLike>?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) +} + +external enum class ModuleKind { + None /* = 0 */, + CommonJS /* = 1 */, + AMD /* = 2 */, + UMD /* = 3 */, + System /* = 4 */, + ES2015 /* = 5 */, + ES2020 /* = 6 */, + ESNext /* = 99 */ +} + +external enum class JsxEmit { + None /* = 0 */, + Preserve /* = 1 */, + React /* = 2 */, + ReactNative /* = 3 */, + ReactJSX /* = 4 */, + ReactJSXDev /* = 5 */ +} + +external enum class ImportsNotUsedAsValues { + Remove /* = 0 */, + Preserve /* = 1 */, + Error /* = 2 */ +} + +external enum class NewLineKind { + CarriageReturnLineFeed /* = 0 */, + LineFeed /* = 1 */ +} + +external interface LineAndCharacter { + var line: Number + var character: Number +} + +external enum class ScriptKind { + Unknown /* = 0 */, + JS /* = 1 */, + JSX /* = 2 */, + TS /* = 3 */, + TSX /* = 4 */, + External /* = 5 */, + JSON /* = 6 */, + Deferred /* = 7 */ +} + +external enum class ScriptTarget { + ES3 /* = 0 */, + ES5 /* = 1 */, + ES2015 /* = 2 */, + ES2016 /* = 3 */, + ES2017 /* = 4 */, + ES2018 /* = 5 */, + ES2019 /* = 6 */, + ES2020 /* = 7 */, + ES2021 /* = 8 */, + ESNext /* = 99 */, + JSON /* = 100 */, + Latest /* = 99 */ +} + +external enum class LanguageVariant { + Standard /* = 0 */, + JSX /* = 1 */ +} + +external interface ParsedCommandLine { + var options: CompilerOptions + var typeAcquisition: TypeAcquisition? + get() = definedExternally + set(value) = definedExternally + var fileNames: Array + var projectReferences: Array? + get() = definedExternally + set(value) = definedExternally + var watchOptions: WatchOptions? + get() = definedExternally + set(value) = definedExternally + var raw: Any? + get() = definedExternally + set(value) = definedExternally + var errors: Array + var wildcardDirectories: MapLike? + get() = definedExternally + set(value) = definedExternally + var compileOnSave: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external enum class WatchDirectoryFlags { + None /* = 0 */, + Recursive /* = 1 */ +} + +external interface CreateProgramOptions { + var rootNames: Array + var options: CompilerOptions + var projectReferences: Array? + get() = definedExternally + set(value) = definedExternally + var host: CompilerHost? + get() = definedExternally + set(value) = definedExternally + var oldProgram: Program? + get() = definedExternally + set(value) = definedExternally + var configFileParsingDiagnostics: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface ModuleResolutionHost { + fun fileExists(fileName: String): Boolean + fun readFile(fileName: String): String? + val trace: ((s: String) -> Unit)? + val directoryExists: ((directoryName: String) -> Boolean)? + val realpath: ((path: String) -> String)? + val getCurrentDirectory: (() -> String)? + val getDirectories: ((path: String) -> Array)? +} + +external interface ResolvedModule { + var resolvedFileName: String + var isExternalLibraryImport: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedModuleFull : ResolvedModule { + var extension: Extension + var packageId: PackageId? + get() = definedExternally + set(value) = definedExternally +} + +external interface PackageId { + var name: String + var subModuleName: String + var version: String +} + +external enum class Extension { + Ts /* = ".ts" */, + Tsx /* = ".tsx" */, + Dts /* = ".d.ts" */, + Js /* = ".js" */, + Jsx /* = ".jsx" */, + Json /* = ".json" */, + TsBuildInfo /* = ".tsbuildinfo" */ +} + +external interface ResolvedModuleWithFailedLookupLocations { + val resolvedModule: ResolvedModuleFull? +} + +external interface ResolvedTypeReferenceDirective { + var primary: Boolean + var resolvedFileName: String? + var packageId: PackageId? + get() = definedExternally + set(value) = definedExternally + var isExternalLibraryImport: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations { + val resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective? + val failedLookupLocations: Array +} + +external interface CompilerHost : ModuleResolutionHost { + fun getSourceFile(fileName: String, languageVersion: ScriptTarget, onError: (message: String) -> Unit = definedExternally, shouldCreateNewSourceFile: Boolean = definedExternally): SourceFile? + val getSourceFileByPath: ((fileName: String, path: String /* String & `T$3` */, languageVersion: ScriptTarget, onError: (message: String) -> Unit, shouldCreateNewSourceFile: Boolean) -> SourceFile?)? + val getCancellationToken: (() -> CancellationToken)? + fun getDefaultLibFileName(options: CompilerOptions): String + val getDefaultLibLocation: (() -> String)? + var writeFile: WriteFileCallback + override var getCurrentDirectory: () -> String + fun getCanonicalFileName(fileName: String): String + fun useCaseSensitiveFileNames(): Boolean + fun getNewLine(): String + val readDirectory: ((rootDir: String, extensions: Array, excludes: Array?, includes: Array, depth: Number) -> Array)? + val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val getEnvironmentVariable: ((name: String) -> String?)? + val createHash: ((data: String) -> String)? + val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? +} + +external interface SourceMapRange : TextRange { + var source: SourceMapSource? + get() = definedExternally + set(value) = definedExternally +} + +external interface SourceMapSource { + fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter + var fileName: String + var text: String + var skipTrivia: ((pos: Number) -> Number)? + get() = definedExternally + set(value) = definedExternally +} + +external enum class EmitFlags { + None /* = 0 */, + SingleLine /* = 1 */, + AdviseOnEmitNode /* = 2 */, + NoSubstitution /* = 4 */, + CapturesThis /* = 8 */, + NoLeadingSourceMap /* = 16 */, + NoTrailingSourceMap /* = 32 */, + NoSourceMap /* = 48 */, + NoNestedSourceMaps /* = 64 */, + NoTokenLeadingSourceMaps /* = 128 */, + NoTokenTrailingSourceMaps /* = 256 */, + NoTokenSourceMaps /* = 384 */, + NoLeadingComments /* = 512 */, + NoTrailingComments /* = 1024 */, + NoComments /* = 1536 */, + NoNestedComments /* = 2048 */, + HelperName /* = 4096 */, + ExportName /* = 8192 */, + LocalName /* = 16384 */, + InternalName /* = 32768 */, + Indented /* = 65536 */, + NoIndentation /* = 131072 */, + AsyncFunctionBody /* = 262144 */, + ReuseTempVariableScope /* = 524288 */, + CustomPrologue /* = 1048576 */, + NoHoisting /* = 2097152 */, + HasEndOfDeclarationMarker /* = 4194304 */, + Iterator /* = 8388608 */, + NoAsciiEscaping /* = 16777216 */ +} + +external interface EmitHelperBase { + val name: String + val scoped: Boolean + val text: dynamic /* String | (node: EmitHelperUniqueNameCallback) -> String */ + get() = definedExternally + val priority: Number? + get() = definedExternally + val dependencies: Array? + get() = definedExternally +} + +external interface ScopedEmitHelper : EmitHelperBase { + override val scoped: Boolean +} + +external interface UnscopedEmitHelper : EmitHelperBase { + override val scoped: Boolean + override val text: String +} + +external enum class EmitHint { + SourceFile /* = 0 */, + Expression /* = 1 */, + IdentifierName /* = 2 */, + MappedTypeParameter /* = 3 */, + Unspecified /* = 4 */, + EmbeddedStatement /* = 5 */, + JsxAttributeValue /* = 6 */ +} + +external enum class OuterExpressionKinds { + Parentheses /* = 1 */, + TypeAssertions /* = 2 */, + NonNullAssertions /* = 4 */, + PartiallyEmittedExpressions /* = 8 */, + Assertions /* = 6 */, + All /* = 15 */ +} + +external interface NodeFactory { + fun createNodeArray(elements: Array = definedExternally, hasTrailingComma: Boolean = definedExternally): NodeArray + fun createNumericLiteral(value: String, numericLiteralFlags: TokenFlags = definedExternally): NumericLiteral + fun createNumericLiteral(value: String): NumericLiteral + fun createNumericLiteral(value: Number, numericLiteralFlags: TokenFlags = definedExternally): NumericLiteral + fun createNumericLiteral(value: Number): NumericLiteral + fun createBigIntLiteral(value: String): BigIntLiteral + fun createBigIntLiteral(value: PseudoBigInt): BigIntLiteral + fun createStringLiteral(text: String, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: Identifier, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: Identifier): StringLiteral + fun createStringLiteralFromNode(sourceNode: StringLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: StringLiteral): StringLiteral + fun createStringLiteralFromNode(sourceNode: NoSubstitutionTemplateLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: NoSubstitutionTemplateLiteral): StringLiteral + fun createStringLiteralFromNode(sourceNode: NumericLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: NumericLiteral): StringLiteral + fun createRegularExpressionLiteral(text: String): RegularExpressionLiteral + fun createIdentifier(text: String): Identifier + fun createTempVariable(recordTempVariable: ((node: Identifier) -> Unit)?, reservedInNestedScopes: Boolean = definedExternally): Identifier + fun createLoopVariable(reservedInNestedScopes: Boolean = definedExternally): Identifier + fun createUniqueName(text: String, flags: GeneratedIdentifierFlags = definedExternally): Identifier + fun getGeneratedNameForNode(node: Node?, flags: GeneratedIdentifierFlags = definedExternally): Identifier + fun createPrivateIdentifier(text: String): PrivateIdentifier + fun createToken(token: SyntaxKind.SuperKeyword): SuperExpression + fun createToken(token: SyntaxKind.ThisKeyword): ThisExpression + fun createToken(token: SyntaxKind.NullKeyword): NullLiteral + fun createToken(token: SyntaxKind.TrueKeyword): TrueLiteral + fun createToken(token: SyntaxKind.FalseKeyword): FalseLiteral + fun createToken(token: TKind): dynamic /* Token */ + fun createSuper(): SuperExpression + fun createThis(): ThisExpression + fun createNull(): NullLiteral + fun createTrue(): TrueLiteral + fun createFalse(): FalseLiteral + fun createModifier(kind: T): ModifierToken + fun createModifiersFromModifierFlags(flags: ModifierFlags): Array + fun createQualifiedName(left: Identifier, right: String): QualifiedName + fun createQualifiedName(left: Identifier, right: Identifier): QualifiedName + fun createQualifiedName(left: QualifiedName, right: String): QualifiedName + fun createQualifiedName(left: QualifiedName, right: Identifier): QualifiedName + fun updateQualifiedName(node: QualifiedName, left: Identifier, right: Identifier): QualifiedName + fun updateQualifiedName(node: QualifiedName, left: QualifiedName, right: Identifier): QualifiedName + fun createComputedPropertyName(expression: Expression): ComputedPropertyName + fun updateComputedPropertyName(node: ComputedPropertyName, expression: Expression): ComputedPropertyName + fun createTypeParameterDeclaration(name: String, constraint: TypeNode = definedExternally, defaultType: TypeNode = definedExternally): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: String): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: String, constraint: TypeNode = definedExternally): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: Identifier, constraint: TypeNode = definedExternally, defaultType: TypeNode = definedExternally): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: Identifier): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: Identifier, constraint: TypeNode = definedExternally): TypeParameterDeclaration + fun updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode?, defaultType: TypeNode?): TypeParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration + fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration + fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration + fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration + fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration + fun createDecorator(expression: Expression): Decorator + fun updateDecorator(node: Decorator, expression: Expression): Decorator + fun createPropertySignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: String, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createMethodSignature(modifiers: Array?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createConstructorDeclaration(decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration + fun updateConstructorDeclaration(node: ConstructorDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration + fun createCallSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): CallSignatureDeclaration + fun updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): CallSignatureDeclaration + fun createConstructSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): ConstructSignatureDeclaration + fun updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): ConstructSignatureDeclaration + fun createIndexSignature(decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration + fun updateIndexSignature(node: IndexSignatureDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration + fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan + fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan + fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan + fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan + fun createKeywordTypeNode(kind: TKind): KeywordTypeNode + fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode + fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode + fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: String, type: TypeNode?): TypePredicateNode + fun updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode + fun updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode + fun createTypeReferenceNode(typeName: String, typeArguments: Array = definedExternally): TypeReferenceNode + fun createTypeReferenceNode(typeName: String): TypeReferenceNode + fun createTypeReferenceNode(typeName: Identifier, typeArguments: Array = definedExternally): TypeReferenceNode + fun createTypeReferenceNode(typeName: Identifier): TypeReferenceNode + fun createTypeReferenceNode(typeName: QualifiedName, typeArguments: Array = definedExternally): TypeReferenceNode + fun createTypeReferenceNode(typeName: QualifiedName): TypeReferenceNode + fun updateTypeReferenceNode(node: TypeReferenceNode, typeName: Identifier, typeArguments: NodeArray?): TypeReferenceNode + fun updateTypeReferenceNode(node: TypeReferenceNode, typeName: QualifiedName, typeArguments: NodeArray?): TypeReferenceNode + fun createFunctionTypeNode(typeParameters: Array?, parameters: Array, type: TypeNode): FunctionTypeNode + fun updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): FunctionTypeNode + fun createConstructorTypeNode(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode): ConstructorTypeNode + fun createConstructorTypeNode(typeParameters: Array?, parameters: Array, type: TypeNode): ConstructorTypeNode + fun updateConstructorTypeNode(node: ConstructorTypeNode, modifiers: Array?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): ConstructorTypeNode + fun updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): ConstructorTypeNode + fun createTypeQueryNode(exprName: Identifier): TypeQueryNode + fun createTypeQueryNode(exprName: QualifiedName): TypeQueryNode + fun updateTypeQueryNode(node: TypeQueryNode, exprName: Identifier): TypeQueryNode + fun updateTypeQueryNode(node: TypeQueryNode, exprName: QualifiedName): TypeQueryNode + fun createTypeLiteralNode(members: Array?): TypeLiteralNode + fun updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray): TypeLiteralNode + fun createArrayTypeNode(elementType: TypeNode): ArrayTypeNode + fun updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode + fun createTupleTypeNode(elements: Array): TupleTypeNode + fun updateTupleTypeNode(node: TupleTypeNode, elements: Array): TupleTypeNode + fun createNamedTupleMember(dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode): NamedTupleMember + fun updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode): NamedTupleMember + fun createOptionalTypeNode(type: TypeNode): OptionalTypeNode + fun updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode + fun createRestTypeNode(type: TypeNode): RestTypeNode + fun updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode + fun createUnionTypeNode(types: Array): UnionTypeNode + fun updateUnionTypeNode(node: UnionTypeNode, types: NodeArray): UnionTypeNode + fun createIntersectionTypeNode(types: Array): IntersectionTypeNode + fun updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray): IntersectionTypeNode + fun createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode + fun updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode + fun createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode + fun updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally, typeArguments: Array = definedExternally, isTypeOf: Boolean = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally, typeArguments: Array = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally, typeArguments: Array = definedExternally, isTypeOf: Boolean = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally, typeArguments: Array = definedExternally): ImportTypeNode + fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: Identifier?, typeArguments: Array?, isTypeOf: Boolean = definedExternally): ImportTypeNode + fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: Identifier?, typeArguments: Array?): ImportTypeNode + fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: QualifiedName?, typeArguments: Array?, isTypeOf: Boolean = definedExternally): ImportTypeNode + fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: QualifiedName?, typeArguments: Array?): ImportTypeNode + fun createParenthesizedType(type: TypeNode): ParenthesizedTypeNode + fun updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode + fun createThisTypeNode(): ThisTypeNode + fun createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword, type: TypeNode): TypeOperatorNode + fun createTypeOperatorNode(operator: SyntaxKind.UniqueKeyword, type: TypeNode): TypeOperatorNode + fun createTypeOperatorNode(operator: SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode + fun updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode + fun createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode + fun updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode + fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun createLiteralTypeNode(literal: NullLiteral): LiteralTypeNode + fun createLiteralTypeNode(literal: TrueLiteral): LiteralTypeNode + fun createLiteralTypeNode(literal: FalseLiteral): LiteralTypeNode + fun createLiteralTypeNode(literal: LiteralExpression): LiteralTypeNode + fun createLiteralTypeNode(literal: PrefixUnaryExpression): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: NullLiteral): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: TrueLiteral): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: FalseLiteral): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralExpression): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: PrefixUnaryExpression): LiteralTypeNode + fun createTemplateLiteralType(head: TemplateHead, templateSpans: Array): TemplateLiteralTypeNode + fun updateTemplateLiteralType(node: TemplateLiteralTypeNode, head: TemplateHead, templateSpans: Array): TemplateLiteralTypeNode + fun createObjectBindingPattern(elements: Array): ObjectBindingPattern + fun updateObjectBindingPattern(node: ObjectBindingPattern, elements: Array): ObjectBindingPattern + fun createArrayBindingPattern(elements: Array): ArrayBindingPattern + fun updateArrayBindingPattern(node: ArrayBindingPattern, elements: Array): ArrayBindingPattern + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: String?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: String?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun createArrayLiteralExpression(elements: Array = definedExternally, multiLine: Boolean = definedExternally): ArrayLiteralExpression + fun updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: Array): ArrayLiteralExpression + fun createObjectLiteralExpression(properties: Array = definedExternally, multiLine: Boolean = definedExternally): ObjectLiteralExpression + fun updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: Array): ObjectLiteralExpression + fun createPropertyAccessExpression(expression: Expression, name: String): PropertyAccessExpression + fun createPropertyAccessExpression(expression: Expression, name: Identifier): PropertyAccessExpression + fun createPropertyAccessExpression(expression: Expression, name: PrivateIdentifier): PropertyAccessExpression + fun updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier): PropertyAccessExpression + fun updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: PrivateIdentifier): PropertyAccessExpression + fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: String): PropertyAccessChain + fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: Identifier): PropertyAccessChain + fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: PrivateIdentifier): PropertyAccessChain + fun updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: Identifier): PropertyAccessChain + fun updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: PrivateIdentifier): PropertyAccessChain + fun createElementAccessExpression(expression: Expression, index: Number): ElementAccessExpression + fun createElementAccessExpression(expression: Expression, index: Expression): ElementAccessExpression + fun updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression + fun createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, index: Number): ElementAccessChain + fun createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, index: Expression): ElementAccessChain + fun updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, argumentExpression: Expression): ElementAccessChain + fun createCallExpression(expression: Expression, typeArguments: Array?, argumentsArray: Array?): CallExpression + fun updateCallExpression(node: CallExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array): CallExpression + fun createCallChain(expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array?): CallChain + fun updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array): CallChain + fun createNewExpression(expression: Expression, typeArguments: Array?, argumentsArray: Array?): NewExpression + fun updateNewExpression(node: NewExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array?): NewExpression + fun createTaggedTemplateExpression(tag: Expression, typeArguments: Array?, template: TemplateExpression): TaggedTemplateExpression + fun createTaggedTemplateExpression(tag: Expression, typeArguments: Array?, template: NoSubstitutionTemplateLiteral): TaggedTemplateExpression + fun updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: TemplateExpression): TaggedTemplateExpression + fun updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: NoSubstitutionTemplateLiteral): TaggedTemplateExpression + fun createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion + fun updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion + fun createParenthesizedExpression(expression: Expression): ParenthesizedExpression + fun updateParenthesizedExpression(node: ParenthesizedExpression, expression: Expression): ParenthesizedExpression + fun createFunctionExpression(modifiers: Array?, asteriskToken: AsteriskToken?, name: String?, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block): FunctionExpression + fun createFunctionExpression(modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block): FunctionExpression + fun updateFunctionExpression(node: FunctionExpression, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block): FunctionExpression + fun createArrowFunction(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: FunctionBody): ArrowFunction + fun createArrowFunction(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: Expression): ArrowFunction + fun updateArrowFunction(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: FunctionBody): ArrowFunction + fun updateArrowFunction(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: Expression): ArrowFunction + fun createDeleteExpression(expression: Expression): DeleteExpression + fun updateDeleteExpression(node: DeleteExpression, expression: Expression): DeleteExpression + fun createTypeOfExpression(expression: Expression): TypeOfExpression + fun updateTypeOfExpression(node: TypeOfExpression, expression: Expression): TypeOfExpression + fun createVoidExpression(expression: Expression): VoidExpression + fun updateVoidExpression(node: VoidExpression, expression: Expression): VoidExpression + fun createAwaitExpression(expression: Expression): AwaitExpression + fun updateAwaitExpression(node: AwaitExpression, expression: Expression): AwaitExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.PlusPlusToken, operand: Expression): PrefixUnaryExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.MinusMinusToken, operand: Expression): PrefixUnaryExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.PlusToken, operand: Expression): PrefixUnaryExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.MinusToken, operand: Expression): PrefixUnaryExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.TildeToken, operand: Expression): PrefixUnaryExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.ExclamationToken, operand: Expression): PrefixUnaryExpression + fun updatePrefixUnaryExpression(node: PrefixUnaryExpression, operand: Expression): PrefixUnaryExpression + fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind.PlusPlusToken): PostfixUnaryExpression + fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind.MinusMinusToken): PostfixUnaryExpression + fun updatePostfixUnaryExpression(node: PostfixUnaryExpression, operand: Expression): PostfixUnaryExpression + fun createBinaryExpression(left: Expression, operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression): BinaryExpression + fun updateBinaryExpression(node: BinaryExpression, left: Expression, operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression): BinaryExpression + fun createConditionalExpression(condition: Expression, questionToken: QuestionToken?, whenTrue: Expression, colonToken: ColonToken?, whenFalse: Expression): ConditionalExpression + fun updateConditionalExpression(node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression + fun createTemplateExpression(head: TemplateHead, templateSpans: Array): TemplateExpression + fun updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: Array): TemplateExpression + fun createTemplateHead(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateHead + fun createTemplateHead(text: String): TemplateHead + fun createTemplateHead(text: String, rawText: String = definedExternally): TemplateHead + fun createTemplateHead(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateHead + fun createTemplateHead(text: String?, rawText: String): TemplateHead + fun createTemplateMiddle(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateMiddle + fun createTemplateMiddle(text: String): TemplateMiddle + fun createTemplateMiddle(text: String, rawText: String = definedExternally): TemplateMiddle + fun createTemplateMiddle(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateMiddle + fun createTemplateMiddle(text: String?, rawText: String): TemplateMiddle + fun createTemplateTail(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateTail + fun createTemplateTail(text: String): TemplateTail + fun createTemplateTail(text: String, rawText: String = definedExternally): TemplateTail + fun createTemplateTail(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateTail + fun createTemplateTail(text: String?, rawText: String): TemplateTail + fun createNoSubstitutionTemplateLiteral(text: String, rawText: String = definedExternally): NoSubstitutionTemplateLiteral + fun createNoSubstitutionTemplateLiteral(text: String): NoSubstitutionTemplateLiteral + fun createNoSubstitutionTemplateLiteral(text: String?, rawText: String): NoSubstitutionTemplateLiteral + fun createYieldExpression(asteriskToken: AsteriskToken, expression: Expression): YieldExpression + fun createYieldExpression(asteriskToken: Nothing?, expression: Expression?): YieldExpression + fun updateYieldExpression(node: YieldExpression, asteriskToken: AsteriskToken?, expression: Expression?): YieldExpression + fun createSpreadElement(expression: Expression): SpreadElement + fun updateSpreadElement(node: SpreadElement, expression: Expression): SpreadElement + fun createClassExpression(decorators: Array?, modifiers: Array?, name: String?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression + fun createClassExpression(decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression + fun updateClassExpression(node: ClassExpression, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression + fun createOmittedExpression(): OmittedExpression + fun createExpressionWithTypeArguments(expression: Expression, typeArguments: Array?): ExpressionWithTypeArguments + fun updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, expression: Expression, typeArguments: Array?): ExpressionWithTypeArguments + fun createAsExpression(expression: Expression, type: TypeNode): AsExpression + fun updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode): AsExpression + fun createNonNullExpression(expression: Expression): NonNullExpression + fun updateNonNullExpression(node: NonNullExpression, expression: Expression): NonNullExpression + fun createNonNullChain(expression: Expression): NonNullChain + fun updateNonNullChain(node: NonNullChain, expression: Expression): NonNullChain + fun createMetaProperty(keywordToken: SyntaxKind.NewKeyword, name: Identifier): MetaProperty + fun createMetaProperty(keywordToken: SyntaxKind.ImportKeyword, name: Identifier): MetaProperty + fun updateMetaProperty(node: MetaProperty, name: Identifier): MetaProperty + fun createTemplateSpan(expression: Expression, literal: TemplateMiddle): TemplateSpan + fun createTemplateSpan(expression: Expression, literal: TemplateTail): TemplateSpan + fun updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle): TemplateSpan + fun updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateTail): TemplateSpan + fun createSemicolonClassElement(): SemicolonClassElement + fun createBlock(statements: Array, multiLine: Boolean = definedExternally): Block + fun updateBlock(node: Block, statements: Array): Block + fun createVariableStatement(modifiers: Array?, declarationList: VariableDeclarationList): VariableStatement + fun createVariableStatement(modifiers: Array?, declarationList: Array): VariableStatement + fun updateVariableStatement(node: VariableStatement, modifiers: Array?, declarationList: VariableDeclarationList): VariableStatement + fun createEmptyStatement(): EmptyStatement + fun createExpressionStatement(expression: Expression): ExpressionStatement + fun updateExpressionStatement(node: ExpressionStatement, expression: Expression): ExpressionStatement + fun createIfStatement(expression: Expression, thenStatement: Statement, elseStatement: Statement = definedExternally): IfStatement + fun updateIfStatement(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement?): IfStatement + fun createDoStatement(statement: Statement, expression: Expression): DoStatement + fun updateDoStatement(node: DoStatement, statement: Statement, expression: Expression): DoStatement + fun createWhileStatement(expression: Expression, statement: Statement): WhileStatement + fun updateWhileStatement(node: WhileStatement, expression: Expression, statement: Statement): WhileStatement + fun createForStatement(initializer: VariableDeclarationList?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement + fun createForStatement(initializer: Expression?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement + fun updateForStatement(node: ForStatement, initializer: VariableDeclarationList?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement + fun updateForStatement(node: ForStatement, initializer: Expression?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement + fun createForInStatement(initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForInStatement + fun createForInStatement(initializer: Expression, expression: Expression, statement: Statement): ForInStatement + fun updateForInStatement(node: ForInStatement, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForInStatement + fun updateForInStatement(node: ForInStatement, initializer: Expression, expression: Expression, statement: Statement): ForInStatement + fun createForOfStatement(awaitModifier: AwaitKeyword?, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForOfStatement + fun createForOfStatement(awaitModifier: AwaitKeyword?, initializer: Expression, expression: Expression, statement: Statement): ForOfStatement + fun updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForOfStatement + fun updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: Expression, expression: Expression, statement: Statement): ForOfStatement + fun createContinueStatement(label: String = definedExternally): ContinueStatement + fun createContinueStatement(): ContinueStatement + fun createContinueStatement(label: Identifier = definedExternally): ContinueStatement + fun updateContinueStatement(node: ContinueStatement, label: Identifier?): ContinueStatement + fun createBreakStatement(label: String = definedExternally): BreakStatement + fun createBreakStatement(): BreakStatement + fun createBreakStatement(label: Identifier = definedExternally): BreakStatement + fun updateBreakStatement(node: BreakStatement, label: Identifier?): BreakStatement + fun createReturnStatement(expression: Expression = definedExternally): ReturnStatement + fun updateReturnStatement(node: ReturnStatement, expression: Expression?): ReturnStatement + fun createWithStatement(expression: Expression, statement: Statement): WithStatement + fun updateWithStatement(node: WithStatement, expression: Expression, statement: Statement): WithStatement + fun createSwitchStatement(expression: Expression, caseBlock: CaseBlock): SwitchStatement + fun updateSwitchStatement(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock): SwitchStatement + fun createLabeledStatement(label: String, statement: Statement): LabeledStatement + fun createLabeledStatement(label: Identifier, statement: Statement): LabeledStatement + fun updateLabeledStatement(node: LabeledStatement, label: Identifier, statement: Statement): LabeledStatement + fun createThrowStatement(expression: Expression): ThrowStatement + fun updateThrowStatement(node: ThrowStatement, expression: Expression): ThrowStatement + fun createTryStatement(tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?): TryStatement + fun updateTryStatement(node: TryStatement, tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?): TryStatement + fun createDebuggerStatement(): DebuggerStatement + fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: String): VariableDeclaration + fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: Identifier): VariableDeclaration + fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ObjectBindingPattern): VariableDeclaration + fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ArrayBindingPattern): VariableDeclaration + fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration + fun updateVariableDeclaration(node: VariableDeclaration, name: Identifier, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration + fun updateVariableDeclaration(node: VariableDeclaration, name: ObjectBindingPattern, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration + fun updateVariableDeclaration(node: VariableDeclaration, name: ArrayBindingPattern, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration + fun createVariableDeclarationList(declarations: Array, flags: NodeFlags = definedExternally): VariableDeclarationList + fun updateVariableDeclarationList(node: VariableDeclarationList, declarations: Array): VariableDeclarationList + fun createFunctionDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration + fun createFunctionDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration + fun updateFunctionDeclaration(node: FunctionDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration + fun createClassDeclaration(decorators: Array?, modifiers: Array?, name: String?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration + fun createClassDeclaration(decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration + fun updateClassDeclaration(node: ClassDeclaration, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration + fun createInterfaceDeclaration(decorators: Array?, modifiers: Array?, name: String, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration + fun createInterfaceDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration + fun updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration + fun createTypeAliasDeclaration(decorators: Array?, modifiers: Array?, name: String, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration + fun createTypeAliasDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration + fun updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration + fun createEnumDeclaration(decorators: Array?, modifiers: Array?, name: String, members: Array): EnumDeclaration + fun createEnumDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, members: Array): EnumDeclaration + fun updateEnumDeclaration(node: EnumDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, members: Array): EnumDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?): ModuleDeclaration + fun createModuleBlock(statements: Array): ModuleBlock + fun updateModuleBlock(node: ModuleBlock, statements: Array): ModuleBlock + fun createCaseBlock(clauses: Array): CaseBlock + fun updateCaseBlock(node: CaseBlock, clauses: Array): CaseBlock + fun createNamespaceExportDeclaration(name: String): NamespaceExportDeclaration + fun createNamespaceExportDeclaration(name: Identifier): NamespaceExportDeclaration + fun updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier): NamespaceExportDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: Identifier): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: QualifiedName): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: ExternalModuleReference): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: Identifier): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: QualifiedName): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: ExternalModuleReference): ImportEqualsDeclaration + fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: Identifier): ImportEqualsDeclaration + fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: QualifiedName): ImportEqualsDeclaration + fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: ExternalModuleReference): ImportEqualsDeclaration + fun createImportDeclaration(decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression): ImportDeclaration + fun updateImportDeclaration(node: ImportDeclaration, decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression): ImportDeclaration + fun createImportClause(isTypeOnly: Boolean, name: Identifier?, namedBindings: NamespaceImport?): ImportClause + fun createImportClause(isTypeOnly: Boolean, name: Identifier?, namedBindings: NamedImports?): ImportClause + fun updateImportClause(node: ImportClause, isTypeOnly: Boolean, name: Identifier?, namedBindings: NamespaceImport?): ImportClause + fun updateImportClause(node: ImportClause, isTypeOnly: Boolean, name: Identifier?, namedBindings: NamedImports?): ImportClause + fun createNamespaceImport(name: Identifier): NamespaceImport + fun updateNamespaceImport(node: NamespaceImport, name: Identifier): NamespaceImport + fun createNamespaceExport(name: Identifier): NamespaceExport + fun updateNamespaceExport(node: NamespaceExport, name: Identifier): NamespaceExport + fun createNamedImports(elements: Array): NamedImports + fun updateNamedImports(node: NamedImports, elements: Array): NamedImports + fun createImportSpecifier(propertyName: Identifier?, name: Identifier): ImportSpecifier + fun updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier?, name: Identifier): ImportSpecifier + fun createExportAssignment(decorators: Array?, modifiers: Array?, isExportEquals: Boolean?, expression: Expression): ExportAssignment + fun updateExportAssignment(node: ExportAssignment, decorators: Array?, modifiers: Array?, expression: Expression): ExportAssignment + fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?, moduleSpecifier: Expression = definedExternally): ExportDeclaration + fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?): ExportDeclaration + fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?, moduleSpecifier: Expression = definedExternally): ExportDeclaration + fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?): ExportDeclaration + fun updateExportDeclaration(node: ExportDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?, moduleSpecifier: Expression?): ExportDeclaration + fun updateExportDeclaration(node: ExportDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?, moduleSpecifier: Expression?): ExportDeclaration + fun createNamedExports(elements: Array): NamedExports + fun updateNamedExports(node: NamedExports, elements: Array): NamedExports + fun createExportSpecifier(propertyName: String?, name: String): ExportSpecifier + fun createExportSpecifier(propertyName: String?, name: Identifier): ExportSpecifier + fun createExportSpecifier(propertyName: Identifier?, name: String): ExportSpecifier + fun createExportSpecifier(propertyName: Identifier?, name: Identifier): ExportSpecifier + fun updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier?, name: Identifier): ExportSpecifier + fun createExternalModuleReference(expression: Expression): ExternalModuleReference + fun updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference + fun createJSDocAllType(): JSDocAllType + fun createJSDocUnknownType(): JSDocUnknownType + fun createJSDocNonNullableType(type: TypeNode): JSDocNonNullableType + fun updateJSDocNonNullableType(node: JSDocNonNullableType, type: TypeNode): JSDocNonNullableType + fun createJSDocNullableType(type: TypeNode): JSDocNullableType + fun updateJSDocNullableType(node: JSDocNullableType, type: TypeNode): JSDocNullableType + fun createJSDocOptionalType(type: TypeNode): JSDocOptionalType + fun updateJSDocOptionalType(node: JSDocOptionalType, type: TypeNode): JSDocOptionalType + fun createJSDocFunctionType(parameters: Array, type: TypeNode?): JSDocFunctionType + fun updateJSDocFunctionType(node: JSDocFunctionType, parameters: Array, type: TypeNode?): JSDocFunctionType + fun createJSDocVariadicType(type: TypeNode): JSDocVariadicType + fun updateJSDocVariadicType(node: JSDocVariadicType, type: TypeNode): JSDocVariadicType + fun createJSDocNamepathType(type: TypeNode): JSDocNamepathType + fun updateJSDocNamepathType(node: JSDocNamepathType, type: TypeNode): JSDocNamepathType + fun createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression + fun updateJSDocTypeExpression(node: JSDocTypeExpression, type: TypeNode): JSDocTypeExpression + fun createJSDocNameReference(name: Identifier): JSDocNameReference + fun createJSDocNameReference(name: QualifiedName): JSDocNameReference + fun updateJSDocNameReference(node: JSDocNameReference, name: Identifier): JSDocNameReference + fun updateJSDocNameReference(node: JSDocNameReference, name: QualifiedName): JSDocNameReference + fun createJSDocLink(name: Identifier?, text: String): JSDocLink + fun createJSDocLink(name: QualifiedName?, text: String): JSDocLink + fun updateJSDocLink(node: JSDocLink, name: Identifier?, text: String): JSDocLink + fun updateJSDocLink(node: JSDocLink, name: QualifiedName?, text: String): JSDocLink + fun createJSDocTypeLiteral(jsDocPropertyTags: Array = definedExternally, isArrayType: Boolean = definedExternally): JSDocTypeLiteral + fun updateJSDocTypeLiteral(node: JSDocTypeLiteral, jsDocPropertyTags: Array?, isArrayType: Boolean?): JSDocTypeLiteral + fun createJSDocSignature(typeParameters: Array?, parameters: Array, type: JSDocReturnTag = definedExternally): JSDocSignature + fun updateJSDocSignature(node: JSDocSignature, typeParameters: Array?, parameters: Array, type: JSDocReturnTag?): JSDocSignature + fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String = definedExternally): JSDocTemplateTag + fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array): JSDocTemplateTag + fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray = definedExternally): JSDocTemplateTag + fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String?): JSDocTemplateTag + fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray?): JSDocTemplateTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: String?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: String?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag + fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocTypeTag + fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocTypeTag + fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocTypeTag + fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocTypeTag + fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocTypeTag + fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag + fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag + fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag + fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag + fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag + fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag + fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: String = definedExternally): JSDocReturnTag + fun createJSDocReturnTag(tagName: Identifier?): JSDocReturnTag + fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocReturnTag + fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: NodeArray = definedExternally): JSDocReturnTag + fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocReturnTag + fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocReturnTag + fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocThisTag + fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocThisTag + fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocThisTag + fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocThisTag + fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocThisTag + fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocEnumTag + fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocEnumTag + fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocEnumTag + fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocEnumTag + fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocEnumTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: String?): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: NodeArray?): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocCallbackTag + fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: String = definedExternally): JSDocAugmentsTag + fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */): JSDocAugmentsTag + fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: NodeArray = definedExternally): JSDocAugmentsTag + fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: String?): JSDocAugmentsTag + fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: NodeArray?): JSDocAugmentsTag + fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: String = definedExternally): JSDocImplementsTag + fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */): JSDocImplementsTag + fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: NodeArray = definedExternally): JSDocImplementsTag + fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: String?): JSDocImplementsTag + fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: NodeArray?): JSDocImplementsTag + fun createJSDocAuthorTag(tagName: Identifier?, comment: String = definedExternally): JSDocAuthorTag + fun createJSDocAuthorTag(tagName: Identifier?): JSDocAuthorTag + fun createJSDocAuthorTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocAuthorTag + fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: String?): JSDocAuthorTag + fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: NodeArray?): JSDocAuthorTag + fun createJSDocClassTag(tagName: Identifier?, comment: String = definedExternally): JSDocClassTag + fun createJSDocClassTag(tagName: Identifier?): JSDocClassTag + fun createJSDocClassTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocClassTag + fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: String?): JSDocClassTag + fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: NodeArray?): JSDocClassTag + fun createJSDocPublicTag(tagName: Identifier?, comment: String = definedExternally): JSDocPublicTag + fun createJSDocPublicTag(tagName: Identifier?): JSDocPublicTag + fun createJSDocPublicTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPublicTag + fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: String?): JSDocPublicTag + fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: NodeArray?): JSDocPublicTag + fun createJSDocPrivateTag(tagName: Identifier?, comment: String = definedExternally): JSDocPrivateTag + fun createJSDocPrivateTag(tagName: Identifier?): JSDocPrivateTag + fun createJSDocPrivateTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPrivateTag + fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: String?): JSDocPrivateTag + fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: NodeArray?): JSDocPrivateTag + fun createJSDocProtectedTag(tagName: Identifier?, comment: String = definedExternally): JSDocProtectedTag + fun createJSDocProtectedTag(tagName: Identifier?): JSDocProtectedTag + fun createJSDocProtectedTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocProtectedTag + fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: String?): JSDocProtectedTag + fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: NodeArray?): JSDocProtectedTag + fun createJSDocReadonlyTag(tagName: Identifier?, comment: String = definedExternally): JSDocReadonlyTag + fun createJSDocReadonlyTag(tagName: Identifier?): JSDocReadonlyTag + fun createJSDocReadonlyTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocReadonlyTag + fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: String?): JSDocReadonlyTag + fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: NodeArray?): JSDocReadonlyTag + fun createJSDocUnknownTag(tagName: Identifier, comment: String = definedExternally): JSDocUnknownTag + fun createJSDocUnknownTag(tagName: Identifier): JSDocUnknownTag + fun createJSDocUnknownTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocUnknownTag + fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: String?): JSDocUnknownTag + fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: NodeArray?): JSDocUnknownTag + fun createJSDocDeprecatedTag(tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag + fun createJSDocDeprecatedTag(tagName: Identifier): JSDocDeprecatedTag + fun createJSDocDeprecatedTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag + fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag + fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier): JSDocDeprecatedTag + fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag + fun createJSDocOverrideTag(tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag + fun createJSDocOverrideTag(tagName: Identifier): JSDocOverrideTag + fun createJSDocOverrideTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag + fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag + fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier): JSDocOverrideTag + fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag + fun createJSDocText(text: String): JSDocText + fun updateJSDocText(node: JSDocText, text: String): JSDocText + fun createJSDocComment(comment: String? = definedExternally, tags: Array? = definedExternally): JSDoc + fun createJSDocComment(): JSDoc + fun createJSDocComment(comment: String? = definedExternally): JSDoc + fun createJSDocComment(comment: NodeArray? = definedExternally, tags: Array? = definedExternally): JSDoc + fun createJSDocComment(comment: NodeArray? = definedExternally): JSDoc + fun updateJSDocComment(node: JSDoc, comment: String?, tags: Array?): JSDoc + fun updateJSDocComment(node: JSDoc, comment: NodeArray?, tags: Array?): JSDoc + fun createJsxElement(openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement + fun updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement + fun createJsxSelfClosingElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun createJsxSelfClosingElement(tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun createJsxSelfClosingElement(tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun createJsxOpeningElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun createJsxOpeningElement(tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun createJsxOpeningElement(tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun createJsxClosingElement(tagName: Identifier): JsxClosingElement + fun createJsxClosingElement(tagName: ThisExpression): JsxClosingElement + fun createJsxClosingElement(tagName: JsxTagNamePropertyAccess): JsxClosingElement + fun updateJsxClosingElement(node: JsxClosingElement, tagName: Identifier): JsxClosingElement + fun updateJsxClosingElement(node: JsxClosingElement, tagName: ThisExpression): JsxClosingElement + fun updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNamePropertyAccess): JsxClosingElement + fun createJsxFragment(openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment): JsxFragment + fun createJsxText(text: String, containsOnlyTriviaWhiteSpaces: Boolean = definedExternally): JsxText + fun updateJsxText(node: JsxText, text: String, containsOnlyTriviaWhiteSpaces: Boolean = definedExternally): JsxText + fun createJsxOpeningFragment(): JsxOpeningFragment + fun createJsxJsxClosingFragment(): JsxClosingFragment + fun updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment): JsxFragment + fun createJsxAttribute(name: Identifier, initializer: StringLiteral?): JsxAttribute + fun createJsxAttribute(name: Identifier, initializer: JsxExpression?): JsxAttribute + fun updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral?): JsxAttribute + fun updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: JsxExpression?): JsxAttribute + fun createJsxAttributes(properties: Array): JsxAttributes + fun updateJsxAttributes(node: JsxAttributes, properties: Array): JsxAttributes + fun createJsxSpreadAttribute(expression: Expression): JsxSpreadAttribute + fun updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression): JsxSpreadAttribute + fun createJsxExpression(dotDotDotToken: DotDotDotToken?, expression: Expression?): JsxExpression + fun updateJsxExpression(node: JsxExpression, expression: Expression?): JsxExpression + fun createCaseClause(expression: Expression, statements: Array): CaseClause + fun updateCaseClause(node: CaseClause, expression: Expression, statements: Array): CaseClause + fun createDefaultClause(statements: Array): DefaultClause + fun updateDefaultClause(node: DefaultClause, statements: Array): DefaultClause + fun createHeritageClause(token: SyntaxKind.ExtendsKeyword, types: Array): HeritageClause + fun createHeritageClause(token: SyntaxKind.ImplementsKeyword, types: Array): HeritageClause + fun updateHeritageClause(node: HeritageClause, types: Array): HeritageClause + fun createCatchClause(variableDeclaration: String?, block: Block): CatchClause + fun createCatchClause(variableDeclaration: VariableDeclaration?, block: Block): CatchClause + fun updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration?, block: Block): CatchClause + fun createPropertyAssignment(name: String, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: Identifier, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: StringLiteral, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: NumericLiteral, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: ComputedPropertyName, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: PrivateIdentifier, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: Identifier, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: StringLiteral, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: NumericLiteral, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: ComputedPropertyName, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: PrivateIdentifier, initializer: Expression): PropertyAssignment + fun createShorthandPropertyAssignment(name: String, objectAssignmentInitializer: Expression = definedExternally): ShorthandPropertyAssignment + fun createShorthandPropertyAssignment(name: String): ShorthandPropertyAssignment + fun createShorthandPropertyAssignment(name: Identifier, objectAssignmentInitializer: Expression = definedExternally): ShorthandPropertyAssignment + fun createShorthandPropertyAssignment(name: Identifier): ShorthandPropertyAssignment + fun updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression?): ShorthandPropertyAssignment + fun createSpreadAssignment(expression: Expression): SpreadAssignment + fun updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment + fun createEnumMember(name: String, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: String): EnumMember + fun createEnumMember(name: Identifier, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: Identifier): EnumMember + fun createEnumMember(name: StringLiteral, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: StringLiteral): EnumMember + fun createEnumMember(name: NumericLiteral, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: NumericLiteral): EnumMember + fun createEnumMember(name: ComputedPropertyName, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: ComputedPropertyName): EnumMember + fun createEnumMember(name: PrivateIdentifier, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: PrivateIdentifier): EnumMember + fun updateEnumMember(node: EnumMember, name: Identifier, initializer: Expression?): EnumMember + fun updateEnumMember(node: EnumMember, name: StringLiteral, initializer: Expression?): EnumMember + fun updateEnumMember(node: EnumMember, name: NumericLiteral, initializer: Expression?): EnumMember + fun updateEnumMember(node: EnumMember, name: ComputedPropertyName, initializer: Expression?): EnumMember + fun updateEnumMember(node: EnumMember, name: PrivateIdentifier, initializer: Expression?): EnumMember + fun createSourceFile(statements: Array, endOfFileToken: Token /* Token & JSDocContainer */, flags: NodeFlags): SourceFile + fun updateSourceFile(node: SourceFile, statements: Array, isDeclarationFile: Boolean = definedExternally, referencedFiles: Array = definedExternally, typeReferences: Array = definedExternally, hasNoDefaultLib: Boolean = definedExternally, libReferences: Array = definedExternally): SourceFile + fun createNotEmittedStatement(original: Node): NotEmittedStatement + fun createPartiallyEmittedExpression(expression: Expression, original: Node = definedExternally): PartiallyEmittedExpression + fun updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression): PartiallyEmittedExpression + fun createCommaListExpression(elements: Array): CommaListExpression + fun updateCommaListExpression(node: CommaListExpression, elements: Array): CommaListExpression + fun createBundle(sourceFiles: Array, prepends: Array = definedExternally): Bundle + fun updateBundle(node: Bundle, sourceFiles: Array, prepends: Array = definedExternally): Bundle + fun createComma(left: Expression, right: Expression): BinaryExpression + fun createAssignment(left: ObjectLiteralExpression, right: Expression): dynamic /* ObjectDestructuringAssignment | ArrayDestructuringAssignment */ + fun createAssignment(left: ArrayLiteralExpression, right: Expression): dynamic /* ObjectDestructuringAssignment | ArrayDestructuringAssignment */ + fun createAssignment(left: Expression, right: Expression): AssignmentExpression + fun createLogicalOr(left: Expression, right: Expression): BinaryExpression + fun createLogicalAnd(left: Expression, right: Expression): BinaryExpression + fun createBitwiseOr(left: Expression, right: Expression): BinaryExpression + fun createBitwiseXor(left: Expression, right: Expression): BinaryExpression + fun createBitwiseAnd(left: Expression, right: Expression): BinaryExpression + fun createStrictEquality(left: Expression, right: Expression): BinaryExpression + fun createStrictInequality(left: Expression, right: Expression): BinaryExpression + fun createEquality(left: Expression, right: Expression): BinaryExpression + fun createInequality(left: Expression, right: Expression): BinaryExpression + fun createLessThan(left: Expression, right: Expression): BinaryExpression + fun createLessThanEquals(left: Expression, right: Expression): BinaryExpression + fun createGreaterThan(left: Expression, right: Expression): BinaryExpression + fun createGreaterThanEquals(left: Expression, right: Expression): BinaryExpression + fun createLeftShift(left: Expression, right: Expression): BinaryExpression + fun createRightShift(left: Expression, right: Expression): BinaryExpression + fun createUnsignedRightShift(left: Expression, right: Expression): BinaryExpression + fun createAdd(left: Expression, right: Expression): BinaryExpression + fun createSubtract(left: Expression, right: Expression): BinaryExpression + fun createMultiply(left: Expression, right: Expression): BinaryExpression + fun createDivide(left: Expression, right: Expression): BinaryExpression + fun createModulo(left: Expression, right: Expression): BinaryExpression + fun createExponent(left: Expression, right: Expression): BinaryExpression + fun createPrefixPlus(operand: Expression): PrefixUnaryExpression + fun createPrefixMinus(operand: Expression): PrefixUnaryExpression + fun createPrefixIncrement(operand: Expression): PrefixUnaryExpression + fun createPrefixDecrement(operand: Expression): PrefixUnaryExpression + fun createBitwiseNot(operand: Expression): PrefixUnaryExpression + fun createLogicalNot(operand: Expression): PrefixUnaryExpression + fun createPostfixIncrement(operand: Expression): PostfixUnaryExpression + fun createPostfixDecrement(operand: Expression): PostfixUnaryExpression + fun createImmediatelyInvokedFunctionExpression(statements: Array): CallExpression + fun createImmediatelyInvokedFunctionExpression(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression + fun createImmediatelyInvokedArrowFunction(statements: Array): CallExpression + fun createImmediatelyInvokedArrowFunction(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression + fun createVoidZero(): VoidExpression + fun createExportDefault(expression: Expression): ExportAssignment + fun createExternalModuleExport(exportName: Identifier): ExportDeclaration + fun restoreOuterExpressions(outerExpression: Expression?, innerExpression: Expression, kinds: OuterExpressionKinds = definedExternally): Expression +} + +external interface CoreTransformationContext { + val factory: NodeFactory + fun getCompilerOptions(): CompilerOptions + fun startLexicalEnvironment() + fun suspendLexicalEnvironment() + fun resumeLexicalEnvironment() + fun endLexicalEnvironment(): Array? + fun hoistFunctionDeclaration(node: FunctionDeclaration) + fun hoistVariableDeclaration(node: Identifier) +} + +external interface TransformationContext : CoreTransformationContext { + fun requestEmitHelper(helper: ScopedEmitHelper) + fun requestEmitHelper(helper: UnscopedEmitHelper) + fun readEmitHelpers(): Array? + fun enableSubstitution(kind: SyntaxKind) + fun isSubstitutionEnabled(node: Node): Boolean + var onSubstituteNode: (hint: EmitHint, node: Node) -> Node + fun enableEmitNotification(kind: SyntaxKind) + fun isEmitNotificationEnabled(node: Node): Boolean + var onEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) -> Unit +} + +external interface TransformationResult { + var transformed: Array + var diagnostics: Array? + get() = definedExternally + set(value) = definedExternally + fun substituteNode(hint: EmitHint, node: Node): Node + fun emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) + val isEmitNotificationEnabled: ((node: Node) -> Boolean)? + fun dispose() +} + +external interface NodeVisitor { + @nativeInvoke + operator fun invoke(nodes: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T + @nativeInvoke + operator fun invoke(nodes: T, visitor: Visitor?): T + @nativeInvoke + operator fun invoke(nodes: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T + @nativeInvoke + operator fun invoke(nodes: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T? + @nativeInvoke + operator fun invoke(nodes: T?, visitor: Visitor?): T? + @nativeInvoke + operator fun invoke(nodes: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T? +} + +external interface NodesVisitor { + @nativeInvoke + operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray + @nativeInvoke + operator fun invoke(nodes: NodeArray, visitor: Visitor?): NodeArray + @nativeInvoke + operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray + @nativeInvoke + operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray + @nativeInvoke + operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray? + @nativeInvoke + operator fun invoke(nodes: NodeArray?, visitor: Visitor?): NodeArray? + @nativeInvoke + operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray? + @nativeInvoke + operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray? +} + +external interface Printer { + fun printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): String + fun printList(format: ListFormat, list: NodeArray, sourceFile: SourceFile): String + fun printFile(sourceFile: SourceFile): String + fun printBundle(bundle: Bundle): String +} + +external interface PrintHandlers { + val hasGlobalName: ((name: String) -> Boolean)? + val onEmitNode: ((hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) -> Unit)? + val isEmitNotificationEnabled: ((node: Node) -> Boolean)? + val substituteNode: ((hint: EmitHint, node: Node) -> Node)? +} + +external interface PrinterOptions { + var removeComments: Boolean? + get() = definedExternally + set(value) = definedExternally + var newLine: NewLineKind? + get() = definedExternally + set(value) = definedExternally + var omitTrailingSemicolon: Boolean? + get() = definedExternally + set(value) = definedExternally + var noEmitHelpers: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface GetEffectiveTypeRootsHost { + val directoryExists: ((directoryName: String) -> Boolean)? + val getCurrentDirectory: (() -> String)? +} + +external interface TextSpan { + var start: Number + var length: Number +} + +external interface TextChangeRange { + var span: TextSpan + var newLength: Number +} + +external interface SyntaxList : Node { + var _children: Array +} + +external enum class ListFormat { + None /* = 0 */, + SingleLine /* = 0 */, + MultiLine /* = 1 */, + PreserveLines /* = 2 */, + LinesMask /* = 3 */, + NotDelimited /* = 0 */, + BarDelimited /* = 4 */, + AmpersandDelimited /* = 8 */, + CommaDelimited /* = 16 */, + AsteriskDelimited /* = 32 */, + DelimitersMask /* = 60 */, + AllowTrailingComma /* = 64 */, + Indented /* = 128 */, + SpaceBetweenBraces /* = 256 */, + SpaceBetweenSiblings /* = 512 */, + Braces /* = 1024 */, + Parenthesis /* = 2048 */, + AngleBrackets /* = 4096 */, + SquareBrackets /* = 8192 */, + BracketsMask /* = 15360 */, + OptionalIfUndefined /* = 16384 */, + OptionalIfEmpty /* = 32768 */, + Optional /* = 49152 */, + PreferNewLine /* = 65536 */, + NoTrailingNewLine /* = 131072 */, + NoInterveningComments /* = 262144 */, + NoSpaceIfEmpty /* = 524288 */, + SingleElement /* = 1048576 */, + SpaceAfterList /* = 2097152 */, + Modifiers /* = 262656 */, + HeritageClauses /* = 512 */, + SingleLineTypeLiteralMembers /* = 768 */, + MultiLineTypeLiteralMembers /* = 32897 */, + SingleLineTupleTypeElements /* = 528 */, + MultiLineTupleTypeElements /* = 657 */, + UnionTypeConstituents /* = 516 */, + IntersectionTypeConstituents /* = 520 */, + ObjectBindingPatternElements /* = 525136 */, + ArrayBindingPatternElements /* = 524880 */, + ObjectLiteralExpressionProperties /* = 526226 */, + ArrayLiteralExpressionElements /* = 8914 */, + CommaListElements /* = 528 */, + CallExpressionArguments /* = 2576 */, + NewExpressionArguments /* = 18960 */, + TemplateExpressionSpans /* = 262144 */, + SingleLineBlockStatements /* = 768 */, + MultiLineBlockStatements /* = 129 */, + VariableDeclarationList /* = 528 */, + SingleLineFunctionBodyStatements /* = 768 */, + MultiLineFunctionBodyStatements /* = 1 */, + ClassHeritageClauses /* = 0 */, + ClassMembers /* = 129 */, + InterfaceMembers /* = 129 */, + EnumMembers /* = 145 */, + CaseBlockClauses /* = 129 */, + NamedImportsOrExportsElements /* = 525136 */, + JsxElementOrFragmentChildren /* = 262144 */, + JsxElementAttributes /* = 262656 */, + CaseOrDefaultClauseStatements /* = 163969 */, + HeritageClauseTypes /* = 528 */, + SourceFileStatements /* = 131073 */, + Decorators /* = 2146305 */, + TypeArguments /* = 53776 */, + TypeParameters /* = 53776 */, + Parameters /* = 2576 */, + IndexSignatureParameters /* = 8848 */, + JSDocComment /* = 33 */ +} + +external interface UserPreferences { + val disableSuggestions: Boolean? + get() = definedExternally + val quotePreference: String? /* "auto" | "double" | "single" */ + get() = definedExternally + val includeCompletionsForModuleExports: Boolean? + get() = definedExternally + val includeCompletionsForImportStatements: Boolean? + get() = definedExternally + val includeCompletionsWithSnippetText: Boolean? + get() = definedExternally + val includeAutomaticOptionalChainCompletions: Boolean? + get() = definedExternally + val includeCompletionsWithInsertText: Boolean? + get() = definedExternally + val importModuleSpecifierPreference: String? /* "shortest" | "project-relative" | "relative" | "non-relative" */ + get() = definedExternally + val importModuleSpecifierEnding: String? /* "auto" | "minimal" | "index" | "js" */ + get() = definedExternally + val allowTextChangesInNewFiles: Boolean? + get() = definedExternally + val providePrefixAndSuffixTextForRename: Boolean? + get() = definedExternally + val includePackageJsonAutoImports: String? /* "auto" | "on" | "off" */ + get() = definedExternally + val provideRefactorNotApplicableReason: Boolean? + get() = definedExternally +} + +external interface PseudoBigInt { + var negative: Boolean + var base10Value: String +} + +external enum class FileWatcherEventKind { + Created /* = 0 */, + Changed /* = 1 */, + Deleted /* = 2 */ +} + +external interface System { + var args: Array + var newLine: String + var useCaseSensitiveFileNames: Boolean + fun write(s: String) + val writeOutputIsTTY: (() -> Boolean)? + fun readFile(path: String, encoding: String = definedExternally): String? + val getFileSize: ((path: String) -> Number)? + fun writeFile(path: String, data: String, writeByteOrderMark: Boolean = definedExternally) + val watchFile: ((path: String, callback: FileWatcherCallback, pollingInterval: Number, options: WatchOptions) -> FileWatcher)? + val watchDirectory: ((path: String, callback: DirectoryWatcherCallback, recursive: Boolean, options: WatchOptions) -> FileWatcher)? + fun resolvePath(path: String): String + fun fileExists(path: String): Boolean + fun directoryExists(path: String): Boolean + fun createDirectory(path: String) + fun getExecutingFilePath(): String + fun getCurrentDirectory(): String + fun getDirectories(path: String): Array + fun readDirectory(path: String, extensions: Array = definedExternally, exclude: Array = definedExternally, include: Array = definedExternally, depth: Number = definedExternally): Array + val getModifiedTime: ((path: String) -> Date?)? + val setModifiedTime: ((path: String, time: Date) -> Unit)? + val deleteFile: ((path: String) -> Unit)? + val createHash: ((data: String) -> String)? + val createSHA256Hash: ((data: String) -> String)? + val getMemoryUsage: (() -> Number)? + fun exit(exitCode: Number = definedExternally) + val realpath: ((path: String) -> String)? + val setTimeout: ((callback: (args: Any) -> Unit, ms: Number, args: Any) -> Any)? + val clearTimeout: ((timeoutId: Any) -> Unit)? + val clearScreen: (() -> Unit)? + val base64decode: ((input: String) -> String)? + val base64encode: ((input: String) -> String)? +} + +external interface FileWatcher { + fun close() +} + +external fun getNodeMajorVersion(): Number? + +external var sys: System + +external fun parseCommandLine(commandLine: Array, readFile: (path: String) -> String? = definedExternally): ParsedCommandLine + +external interface ConfigFileDiagnosticsReporter { + var onUnRecoverableConfigFileDiagnostic: DiagnosticReporter +} + +external interface ParseConfigFileHost : ParseConfigHost, ConfigFileDiagnosticsReporter { + fun getCurrentDirectory(): String +} + +external fun getParsedCommandLineOfConfigFile(configFileName: String, optionsToExtend: CompilerOptions?, host: ParseConfigFileHost, extendedConfigCache: Map = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): ParsedCommandLine? + +external interface `T$9` { + var config: Any? + get() = definedExternally + set(value) = definedExternally + var error: Diagnostic? + get() = definedExternally + set(value) = definedExternally +} + +external fun readConfigFile(fileName: String, readFile: (path: String) -> String?): `T$9` + +external fun parseConfigFileTextToJson(fileName: String, jsonText: String): `T$9` + +external fun readJsonConfigFile(fileName: String, readFile: (path: String) -> String?): TsConfigSourceFile + +external fun convertToObject(sourceFile: JsonSourceFile, errors: Push): Any + +external fun parseJsonConfigFileContent(json: Any, host: ParseConfigHost, basePath: String, existingOptions: CompilerOptions = definedExternally, configFileName: String = definedExternally, resolutionStack: Array = definedExternally, extraFileExtensions: Array = definedExternally, extendedConfigCache: Map = definedExternally, existingWatchOptions: WatchOptions = definedExternally): ParsedCommandLine + +external fun parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: String, existingOptions: CompilerOptions = definedExternally, configFileName: String = definedExternally, resolutionStack: Array = definedExternally, extraFileExtensions: Array = definedExternally, extendedConfigCache: Map = definedExternally, existingWatchOptions: WatchOptions = definedExternally): ParsedCommandLine + +external interface ParsedTsconfig { + var raw: Any + var options: CompilerOptions? + get() = definedExternally + set(value) = definedExternally + var watchOptions: WatchOptions? + get() = definedExternally + set(value) = definedExternally + var typeAcquisition: TypeAcquisition? + get() = definedExternally + set(value) = definedExternally + var extendedConfigPath: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface ExtendedConfigCacheEntry { + var extendedResult: TsConfigSourceFile + var extendedConfig: ParsedTsconfig? +} + +external interface `T$10` { + var options: CompilerOptions + var errors: Array +} + +external fun convertCompilerOptionsFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$10` + +external interface `T$11` { + var options: TypeAcquisition + var errors: Array +} + +external fun convertTypeAcquisitionFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$11` + +external interface SourceFileLike { + fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter +} + +external interface IScriptSnapshot { + fun getText(start: Number, end: Number): String + fun getLength(): Number + fun getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange? + val dispose: (() -> Unit)? +} + +external interface PreProcessedFileInfo { + var referencedFiles: Array + var typeReferenceDirectives: Array + var libReferenceDirectives: Array + var importedFiles: Array + var ambientExternalModules: Array? + get() = definedExternally + set(value) = definedExternally + var isLibFile: Boolean +} + +external interface HostCancellationToken { + fun isCancellationRequested(): Boolean +} + +external interface InstallPackageOptions { + var fileName: String /* String & `T$3` */ + var packageName: String +} + +external interface PerformanceEvent { + var kind: String /* "UpdateGraph" | "CreatePackageJsonAutoImportProvider" */ + var durationMs: Number +} + +external enum class LanguageServiceMode { + Semantic /* = 0 */, + PartialSemantic /* = 1 */, + Syntactic /* = 2 */ +} + +external interface LanguageServiceHost : GetEffectiveTypeRootsHost { + fun getCompilationSettings(): CompilerOptions + val getNewLine: (() -> String)? + val getProjectVersion: (() -> String)? + fun getScriptFileNames(): Array + val getScriptKind: ((fileName: String) -> ScriptKind)? + fun getScriptVersion(fileName: String): String + fun getScriptSnapshot(fileName: String): IScriptSnapshot? + val getProjectReferences: (() -> Array?)? + val getLocalizedDiagnosticMessages: (() -> Any)? + val getCancellationToken: (() -> HostCancellationToken)? + override var getCurrentDirectory: () -> String + fun getDefaultLibFileName(options: CompilerOptions): String + val log: ((s: String) -> Unit)? + val trace: ((s: String) -> Unit)? + val error: ((s: String) -> Unit)? + val useCaseSensitiveFileNames: (() -> Boolean)? + val readDirectory: ((path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array)? + val readFile: ((path: String, encoding: String) -> String?)? + val realpath: ((path: String) -> String)? + val fileExists: ((path: String) -> Boolean)? + val getTypeRootsVersion: (() -> Number)? + val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val getResolvedModuleWithFailedLookupLocationsFromCache: ((modulename: String, containingFile: String) -> ResolvedModuleWithFailedLookupLocations?)? + val resolveTypeReferenceDirectives: ((typeDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val getDirectories: ((directoryName: String) -> Array)? + val getCustomTransformers: (() -> CustomTransformers?)? + val isKnownTypesPackageName: ((name: String) -> Boolean)? + val installPackage: ((options: InstallPackageOptions) -> Promise)? + val writeFile: ((fileName: String, content: String) -> Unit)? + val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? +} + +external interface `T$12` { + var metadata: Any? + get() = definedExternally + set(value) = definedExternally +} + +external enum class SemanticClassificationFormat { + Original /* = "original" */, + TwentyTwenty /* = "2020" */ +} + +external interface LanguageService { + fun cleanupSemanticCache() + fun getSyntacticDiagnostics(fileName: String): Array + fun getSemanticDiagnostics(fileName: String): Array + fun getSuggestionDiagnostics(fileName: String): Array + fun getCompilerOptionsDiagnostics(): Array + fun getSyntacticClassifications(fileName: String, span: TextSpan): Array + fun getSyntacticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ + fun getSemanticClassifications(fileName: String, span: TextSpan): Array + fun getSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ + fun getEncodedSyntacticClassifications(fileName: String, span: TextSpan): Classifications + fun getEncodedSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat = definedExternally): Classifications + fun getCompletionsAtPosition(fileName: String, position: Number, options: GetCompletionsAtPositionOptions?): CompletionInfo /* CompletionInfo & `T$12` */ + fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeOptions?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? + fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeSettings?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? + fun getCompletionEntrySymbol(fileName: String, position: Number, name: String, source: String?): Symbol? + fun getQuickInfoAtPosition(fileName: String, position: Number): QuickInfo? + fun getNameOrDottedNameSpan(fileName: String, startPos: Number, endPos: Number): TextSpan? + fun getBreakpointStatementAtPosition(fileName: String, position: Number): TextSpan? + fun getSignatureHelpItems(fileName: String, position: Number, options: SignatureHelpItemsOptions?): SignatureHelpItems? + fun getRenameInfo(fileName: String, position: Number, options: RenameInfoOptions = definedExternally): dynamic /* RenameInfoSuccess | RenameInfoFailure */ + fun findRenameLocations(fileName: String, position: Number, findInStrings: Boolean, findInComments: Boolean, providePrefixAndSuffixTextForRename: Boolean = definedExternally): Array? + fun getSmartSelectionRange(fileName: String, position: Number): SelectionRange + fun getDefinitionAtPosition(fileName: String, position: Number): Array? + fun getDefinitionAndBoundSpan(fileName: String, position: Number): DefinitionInfoAndBoundSpan? + fun getTypeDefinitionAtPosition(fileName: String, position: Number): Array? + fun getImplementationAtPosition(fileName: String, position: Number): Array? + fun getReferencesAtPosition(fileName: String, position: Number): Array? + fun findReferences(fileName: String, position: Number): Array? + fun getDocumentHighlights(fileName: String, position: Number, filesToSearch: Array): Array? + fun getFileReferences(fileName: String): Array + fun getOccurrencesAtPosition(fileName: String, position: Number): Array? + fun getNavigateToItems(searchValue: String, maxResultCount: Number = definedExternally, fileName: String = definedExternally, excludeDtsFiles: Boolean = definedExternally): Array + fun getNavigationBarItems(fileName: String): Array + fun getNavigationTree(fileName: String): NavigationTree + fun prepareCallHierarchy(fileName: String, position: Number): dynamic /* CallHierarchyItem? | Array? */ + fun provideCallHierarchyIncomingCalls(fileName: String, position: Number): Array + fun provideCallHierarchyOutgoingCalls(fileName: String, position: Number): Array + fun getOutliningSpans(fileName: String): Array + fun getTodoComments(fileName: String, descriptors: Array): Array + fun getBraceMatchingAtPosition(fileName: String, position: Number): Array + fun getIndentationAtPosition(fileName: String, position: Number, options: EditorOptions): Number + fun getIndentationAtPosition(fileName: String, position: Number, options: EditorSettings): Number + fun getFormattingEditsForRange(fileName: String, start: Number, end: Number, options: FormatCodeOptions): Array + fun getFormattingEditsForRange(fileName: String, start: Number, end: Number, options: FormatCodeSettings): Array + fun getFormattingEditsForDocument(fileName: String, options: FormatCodeOptions): Array + fun getFormattingEditsForDocument(fileName: String, options: FormatCodeSettings): Array + fun getFormattingEditsAfterKeystroke(fileName: String, position: Number, key: String, options: FormatCodeOptions): Array + fun getFormattingEditsAfterKeystroke(fileName: String, position: Number, key: String, options: FormatCodeSettings): Array + fun getDocCommentTemplateAtPosition(fileName: String, position: Number, options: DocCommentTemplateOptions = definedExternally): TextInsertion? + fun isValidBraceCompletionAtPosition(fileName: String, position: Number, openingBrace: Number): Boolean + fun getJsxClosingTagAtPosition(fileName: String, position: Number): JsxClosingTagInfo? + fun getSpanOfEnclosingComment(fileName: String, position: Number, onlyMultiLine: Boolean): TextSpan? + val toLineColumnOffset: ((fileName: String, position: Number) -> LineAndCharacter)? + fun getCodeFixesAtPosition(fileName: String, start: Number, end: Number, errorCodes: Array, formatOptions: FormatCodeSettings, preferences: UserPreferences): Array + fun getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: Any, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions + fun applyCodeActionCommand(action: CodeActionCommand, formatSettings: FormatCodeSettings = definedExternally): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(action: CodeActionCommand): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(action: Array, formatSettings: FormatCodeSettings = definedExternally): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(action: Array): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(fileName: String, action: CodeActionCommand): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(fileName: String, action: Array): dynamic /* Promise | Promise */ + fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally, kind: String = definedExternally): Array + fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?): Array + fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally): Array + fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally, kind: String = definedExternally): Array + fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?): Array + fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally): Array + fun getEditsForRefactor(fileName: String, formatOptions: FormatCodeSettings, positionOrRange: Number, refactorName: String, actionName: String, preferences: UserPreferences?): RefactorEditInfo? + fun getEditsForRefactor(fileName: String, formatOptions: FormatCodeSettings, positionOrRange: TextRange, refactorName: String, actionName: String, preferences: UserPreferences?): RefactorEditInfo? + fun organizeImports(args: OrganizeImportsArgs, formatOptions: FormatCodeSettings, preferences: UserPreferences?): Array + fun getEditsForFileRename(oldFilePath: String, newFilePath: String, formatOptions: FormatCodeSettings, preferences: UserPreferences?): Array + fun getEmitOutput(fileName: String, emitOnlyDtsFiles: Boolean = definedExternally, forceDtsEmit: Boolean = definedExternally): EmitOutput + fun getProgram(): Program? + fun toggleLineComment(fileName: String, textRange: TextRange): Array + fun toggleMultilineComment(fileName: String, textRange: TextRange): Array + fun commentSelection(fileName: String, textRange: TextRange): Array + fun uncommentSelection(fileName: String, textRange: TextRange): Array + fun dispose() +} + +external interface JsxClosingTagInfo { + val newText: String +} + +external interface CombinedCodeFixScope { + var type: String /* "file" */ + var fileName: String +} + +external interface OrganizeImportsArgs : CombinedCodeFixScope { + var skipDestructiveCodeActions: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface GetCompletionsAtPositionOptions : UserPreferences { + var triggerCharacter: String? /* "." | """ | "'" | "`" | "/" | "@" | "<" | "#" | " " */ + get() = definedExternally + set(value) = definedExternally + var includeExternalModuleExports: Boolean? + get() = definedExternally + set(value) = definedExternally + var includeInsertTextCompletions: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureHelpItemsOptions { + var triggerReason: dynamic /* SignatureHelpInvokedReason? | SignatureHelpCharacterTypedReason? | SignatureHelpRetriggeredReason? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureHelpInvokedReason { + var kind: String /* "invoked" */ + var triggerCharacter: Any? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureHelpCharacterTypedReason { + var kind: String /* "characterTyped" */ + var triggerCharacter: String /* "," | "(" | "<" */ +} + +external interface SignatureHelpRetriggeredReason { + var kind: String /* "retrigger" */ + var triggerCharacter: String? /* "," | "(" | "<" | ")" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ApplyCodeActionCommandResult { + var successMessage: String +} + +external interface Classifications { + var spans: Array + var endOfLineState: EndOfLineState +} + +external interface ClassifiedSpan { + var textSpan: TextSpan + var classificationType: ClassificationTypeNames +} + +external interface ClassifiedSpan2020 { + var textSpan: TextSpan + var classificationType: Number +} + +external interface NavigationBarItem { + var text: String + var kind: ScriptElementKind + var kindModifiers: String + var spans: Array + var childItems: Array + var indent: Number + var bolded: Boolean + var grayed: Boolean +} + +external interface NavigationTree { + var text: String + var kind: ScriptElementKind + var kindModifiers: String + var spans: Array + var nameSpan: TextSpan? + var childItems: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface CallHierarchyItem { + var name: String + var kind: ScriptElementKind + var kindModifiers: String? + get() = definedExternally + set(value) = definedExternally + var file: String + var span: TextSpan + var selectionSpan: TextSpan + var containerName: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface CallHierarchyIncomingCall { + var from: CallHierarchyItem + var fromSpans: Array +} + +external interface CallHierarchyOutgoingCall { + var to: CallHierarchyItem + var fromSpans: Array +} + +external interface TodoCommentDescriptor { + var text: String + var priority: Number +} + +external interface TodoComment { + var descriptor: TodoCommentDescriptor + var message: String + var position: Number +} + +external interface TextChange { + var span: TextSpan + var newText: String +} + +external interface FileTextChanges { + var fileName: String + var textChanges: Array + var isNewFile: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface CodeAction { + var description: String + var changes: Array + var commands: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface CodeFixAction : CodeAction { + var fixName: String + var fixId: Any? + get() = definedExternally + set(value) = definedExternally + var fixAllDescription: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface CombinedCodeActions { + var changes: Array + var commands: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface InstallPackageAction + +external interface ApplicableRefactorInfo { + var name: String + var description: String + var inlineable: Boolean? + get() = definedExternally + set(value) = definedExternally + var actions: Array +} + +external interface RefactorActionInfo { + var name: String + var description: String + var notApplicableReason: String? + get() = definedExternally + set(value) = definedExternally + var kind: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface RefactorEditInfo { + var edits: Array + var renameFilename: String? + get() = definedExternally + set(value) = definedExternally + var renameLocation: Number? + get() = definedExternally + set(value) = definedExternally + var commands: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface TextInsertion { + var newText: String + var caretOffset: Number +} + +external interface DocumentSpan { + var textSpan: TextSpan + var fileName: String + var originalTextSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var originalFileName: String? + get() = definedExternally + set(value) = definedExternally + var contextSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var originalContextSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally +} + +external interface RenameLocation : DocumentSpan { + val prefixText: String? + get() = definedExternally + val suffixText: String? + get() = definedExternally +} + +external interface ReferenceEntry : DocumentSpan { + var isWriteAccess: Boolean + var isDefinition: Boolean + var isInString: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ImplementationLocation : DocumentSpan { + var kind: ScriptElementKind + var displayParts: Array +} + +external enum class HighlightSpanKind { + none /* = "none" */, + definition /* = "definition" */, + reference /* = "reference" */, + writtenReference /* = "writtenReference" */ +} + +external interface HighlightSpan { + var fileName: String? + get() = definedExternally + set(value) = definedExternally + var isInString: Boolean? + get() = definedExternally + set(value) = definedExternally + var textSpan: TextSpan + var contextSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var kind: HighlightSpanKind +} + +external interface NavigateToItem { + var name: String + var kind: ScriptElementKind + var kindModifiers: String + var matchKind: String /* "exact" | "prefix" | "substring" | "camelCase" */ + var isCaseSensitive: Boolean + var fileName: String + var textSpan: TextSpan + var containerName: String + var containerKind: ScriptElementKind +} + +external enum class IndentStyle { + None /* = 0 */, + Block /* = 1 */, + Smart /* = 2 */ +} + +external enum class SemicolonPreference { + Ignore /* = "ignore" */, + Insert /* = "insert" */, + Remove /* = "remove" */ +} + +external interface EditorOptions { + var BaseIndentSize: Number? + get() = definedExternally + set(value) = definedExternally + var IndentSize: Number + var TabSize: Number + var NewLineCharacter: String + var ConvertTabsToSpaces: Boolean + var IndentStyle: IndentStyle +} + +external interface EditorSettings { + var baseIndentSize: Number? + get() = definedExternally + set(value) = definedExternally + var indentSize: Number? + get() = definedExternally + set(value) = definedExternally + var tabSize: Number? + get() = definedExternally + set(value) = definedExternally + var newLineCharacter: String? + get() = definedExternally + set(value) = definedExternally + var convertTabsToSpaces: Boolean? + get() = definedExternally + set(value) = definedExternally + var indentStyle: IndentStyle? + get() = definedExternally + set(value) = definedExternally + var trimTrailingWhitespace: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface FormatCodeOptions : EditorOptions { + var InsertSpaceAfterCommaDelimiter: Boolean + var InsertSpaceAfterSemicolonInForStatements: Boolean + var InsertSpaceBeforeAndAfterBinaryOperators: Boolean + var InsertSpaceAfterConstructor: Boolean? + get() = definedExternally + set(value) = definedExternally + var InsertSpaceAfterKeywordsInControlFlowStatements: Boolean + var InsertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean + var InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean + var InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean + var InsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: Boolean? + get() = definedExternally + set(value) = definedExternally + var InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean + var InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: Boolean? + get() = definedExternally + set(value) = definedExternally + var InsertSpaceAfterTypeAssertion: Boolean? + get() = definedExternally + set(value) = definedExternally + var InsertSpaceBeforeFunctionParenthesis: Boolean? + get() = definedExternally + set(value) = definedExternally + var PlaceOpenBraceOnNewLineForFunctions: Boolean + var PlaceOpenBraceOnNewLineForControlBlocks: Boolean + var insertSpaceBeforeTypeAnnotation: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface FormatCodeSettings : EditorSettings { + val insertSpaceAfterCommaDelimiter: Boolean? + get() = definedExternally + val insertSpaceAfterSemicolonInForStatements: Boolean? + get() = definedExternally + val insertSpaceBeforeAndAfterBinaryOperators: Boolean? + get() = definedExternally + val insertSpaceAfterConstructor: Boolean? + get() = definedExternally + val insertSpaceAfterKeywordsInControlFlowStatements: Boolean? + get() = definedExternally + val insertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingEmptyBraces: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean? + get() = definedExternally + val insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: Boolean? + get() = definedExternally + val insertSpaceAfterTypeAssertion: Boolean? + get() = definedExternally + val insertSpaceBeforeFunctionParenthesis: Boolean? + get() = definedExternally + val placeOpenBraceOnNewLineForFunctions: Boolean? + get() = definedExternally + val placeOpenBraceOnNewLineForControlBlocks: Boolean? + get() = definedExternally + val insertSpaceBeforeTypeAnnotation: Boolean? + get() = definedExternally + val indentMultiLineObjectLiteralBeginningOnBlankLine: Boolean? + get() = definedExternally + val semicolons: SemicolonPreference? + get() = definedExternally +} + +external fun getDefaultFormatCodeSettings(newLineCharacter: String = definedExternally): FormatCodeSettings + +external interface DefinitionInfo : DocumentSpan { + var kind: ScriptElementKind + var name: String + var containerKind: ScriptElementKind + var containerName: String + var unverified: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface DefinitionInfoAndBoundSpan { + var definitions: Array? + get() = definedExternally + set(value) = definedExternally + var textSpan: TextSpan +} + +external interface ReferencedSymbolDefinitionInfo : DefinitionInfo { + var displayParts: Array +} + +external interface ReferencedSymbol { + var definition: ReferencedSymbolDefinitionInfo + var references: Array +} + +external enum class SymbolDisplayPartKind { + aliasName /* = 0 */, + className /* = 1 */, + enumName /* = 2 */, + fieldName /* = 3 */, + interfaceName /* = 4 */, + keyword /* = 5 */, + lineBreak /* = 6 */, + numericLiteral /* = 7 */, + stringLiteral /* = 8 */, + localName /* = 9 */, + methodName /* = 10 */, + moduleName /* = 11 */, + operator /* = 12 */, + parameterName /* = 13 */, + propertyName /* = 14 */, + punctuation /* = 15 */, + space /* = 16 */, + text /* = 17 */, + typeParameterName /* = 18 */, + enumMemberName /* = 19 */, + functionName /* = 20 */, + regularExpressionLiteral /* = 21 */, + link /* = 22 */, + linkName /* = 23 */, + linkText /* = 24 */ +} + +external interface SymbolDisplayPart { + var text: String + var kind: String +} + +external interface JSDocLinkDisplayPart : SymbolDisplayPart { + var target: DocumentSpan +} + +external interface JSDocTagInfo { + var name: String + var text: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface QuickInfo { + var kind: ScriptElementKind + var kindModifiers: String + var textSpan: TextSpan + var displayParts: Array? + get() = definedExternally + set(value) = definedExternally + var documentation: Array? + get() = definedExternally + set(value) = definedExternally + var tags: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface RenameInfoSuccess { + var canRename: Boolean + var fileToRename: String? + get() = definedExternally + set(value) = definedExternally + var displayName: String + var fullDisplayName: String + var kind: ScriptElementKind + var kindModifiers: String + var triggerSpan: TextSpan +} + +external interface RenameInfoFailure { + var canRename: Boolean + var localizedErrorMessage: String +} + +external interface RenameInfoOptions { + val allowRenameOfImportPath: Boolean? + get() = definedExternally +} + +external interface DocCommentTemplateOptions { + val generateReturnInDocTemplate: Boolean? + get() = definedExternally +} + +external interface SignatureHelpParameter { + var name: String + var documentation: Array + var displayParts: Array + var isOptional: Boolean + var isRest: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface SelectionRange { + var textSpan: TextSpan + var parent: SelectionRange? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureHelpItem { + var isVariadic: Boolean + var prefixDisplayParts: Array + var suffixDisplayParts: Array + var separatorDisplayParts: Array + var parameters: Array + var documentation: Array + var tags: Array +} + +external interface SignatureHelpItems { + var items: Array + var applicableSpan: TextSpan + var selectedItemIndex: Number + var argumentIndex: Number + var argumentCount: Number +} + +external interface CompletionInfo { + var isGlobalCompletion: Boolean + var isMemberCompletion: Boolean + var optionalReplacementSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var isNewIdentifierLocation: Boolean + var isIncomplete: Boolean? + get() = definedExternally + set(value) = definedExternally + var entries: Array +} + +external interface CompletionEntryData { + var fileName: String? + get() = definedExternally + set(value) = definedExternally + var ambientModuleName: String? + get() = definedExternally + set(value) = definedExternally + var isPackageJsonImport: Boolean? + get() = definedExternally + set(value) = definedExternally + var exportName: String + var moduleSpecifier: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface CompletionEntry { + var name: String + var kind: ScriptElementKind + var kindModifiers: String? + get() = definedExternally + set(value) = definedExternally + var sortText: String + var insertText: String? + get() = definedExternally + set(value) = definedExternally + var isSnippet: Boolean? + get() = definedExternally + set(value) = definedExternally + var replacementSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var hasAction: Boolean? + get() = definedExternally + set(value) = definedExternally + var source: String? + get() = definedExternally + set(value) = definedExternally + var sourceDisplay: Array? + get() = definedExternally + set(value) = definedExternally + var isRecommended: Boolean? + get() = definedExternally + set(value) = definedExternally + var isFromUncheckedFile: Boolean? + get() = definedExternally + set(value) = definedExternally + var isPackageJsonImport: Boolean? + get() = definedExternally + set(value) = definedExternally + var isImportStatementCompletion: Boolean? + get() = definedExternally + set(value) = definedExternally + var data: CompletionEntryData? + get() = definedExternally + set(value) = definedExternally +} + +external interface CompletionEntryDetails { + var name: String + var kind: ScriptElementKind + var kindModifiers: String + var displayParts: Array + var documentation: Array? + get() = definedExternally + set(value) = definedExternally + var tags: Array? + get() = definedExternally + set(value) = definedExternally + var codeActions: Array? + get() = definedExternally + set(value) = definedExternally + var source: Array? + get() = definedExternally + set(value) = definedExternally + var sourceDisplay: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface OutliningSpan { + var textSpan: TextSpan + var hintSpan: TextSpan + var bannerText: String + var autoCollapse: Boolean + var kind: OutliningSpanKind +} + +external enum class OutliningSpanKind { + Comment /* = "comment" */, + Region /* = "region" */, + Code /* = "code" */, + Imports /* = "imports" */ +} + +external enum class OutputFileType { + JavaScript /* = 0 */, + SourceMap /* = 1 */, + Declaration /* = 2 */ +} + +external enum class EndOfLineState { + None /* = 0 */, + InMultiLineCommentTrivia /* = 1 */, + InSingleQuoteStringLiteral /* = 2 */, + InDoubleQuoteStringLiteral /* = 3 */, + InTemplateHeadOrNoSubstitutionTemplate /* = 4 */, + InTemplateMiddleOrTail /* = 5 */, + InTemplateSubstitutionPosition /* = 6 */ +} + +external enum class TokenClass { + Punctuation /* = 0 */, + Keyword /* = 1 */, + Operator /* = 2 */, + Comment /* = 3 */, + Whitespace /* = 4 */, + Identifier /* = 5 */, + NumberLiteral /* = 6 */, + BigIntLiteral /* = 7 */, + StringLiteral /* = 8 */, + RegExpLiteral /* = 9 */ +} + +external interface ClassificationResult { + var finalLexState: EndOfLineState + var entries: Array +} + +external interface ClassificationInfo { + var length: Number + var classification: TokenClass +} + +external interface Classifier { + fun getClassificationsForLine(text: String, lexState: EndOfLineState, syntacticClassifierAbsent: Boolean): ClassificationResult + fun getEncodedLexicalClassifications(text: String, endOfLineState: EndOfLineState, syntacticClassifierAbsent: Boolean): Classifications +} + +external enum class ScriptElementKind { + unknown /* = "" */, + warning /* = "warning" */, + keyword /* = "keyword" */, + scriptElement /* = "script" */, + moduleElement /* = "module" */, + classElement /* = "class" */, + localClassElement /* = "local class" */, + interfaceElement /* = "interface" */, + typeElement /* = "type" */, + enumElement /* = "enum" */, + enumMemberElement /* = "enum member" */, + variableElement /* = "var" */, + localVariableElement /* = "local var" */, + functionElement /* = "function" */, + localFunctionElement /* = "local function" */, + memberFunctionElement /* = "method" */, + memberGetAccessorElement /* = "getter" */, + memberSetAccessorElement /* = "setter" */, + memberVariableElement /* = "property" */, + constructorImplementationElement /* = "constructor" */, + callSignatureElement /* = "call" */, + indexSignatureElement /* = "index" */, + constructSignatureElement /* = "construct" */, + parameterElement /* = "parameter" */, + typeParameterElement /* = "type parameter" */, + primitiveType /* = "primitive type" */, + label /* = "label" */, + alias /* = "alias" */, + constElement /* = "const" */, + letElement /* = "let" */, + directory /* = "directory" */, + externalModuleName /* = "external module name" */, + jsxAttribute /* = "JSX attribute" */, + string /* = "string" */, + link /* = "link" */, + linkName /* = "link name" */, + linkText /* = "link text" */ +} + +external enum class ScriptElementKindModifier { + none /* = "" */, + publicMemberModifier /* = "public" */, + privateMemberModifier /* = "private" */, + protectedMemberModifier /* = "protected" */, + exportedModifier /* = "export" */, + ambientModifier /* = "declare" */, + staticModifier /* = "static" */, + abstractModifier /* = "abstract" */, + optionalModifier /* = "optional" */, + deprecatedModifier /* = "deprecated" */, + dtsModifier /* = ".d.ts" */, + tsModifier /* = ".ts" */, + tsxModifier /* = ".tsx" */, + jsModifier /* = ".js" */, + jsxModifier /* = ".jsx" */, + jsonModifier /* = ".json" */ +} + +external enum class ClassificationTypeNames { + comment /* = "comment" */, + identifier /* = "identifier" */, + keyword /* = "keyword" */, + numericLiteral /* = "number" */, + bigintLiteral /* = "bigint" */, + operator /* = "operator" */, + stringLiteral /* = "string" */, + whiteSpace /* = "whitespace" */, + text /* = "text" */, + punctuation /* = "punctuation" */, + className /* = "class name" */, + enumName /* = "enum name" */, + interfaceName /* = "interface name" */, + moduleName /* = "module name" */, + typeParameterName /* = "type parameter name" */, + typeAliasName /* = "type alias name" */, + parameterName /* = "parameter name" */, + docCommentTagName /* = "doc comment tag name" */, + jsxOpenTagName /* = "jsx open tag name" */, + jsxCloseTagName /* = "jsx close tag name" */, + jsxSelfClosingTagName /* = "jsx self closing tag name" */, + jsxAttribute /* = "jsx attribute" */, + jsxText /* = "jsx text" */, + jsxAttributeStringLiteralValue /* = "jsx attribute string literal value" */ +} + +external enum class ClassificationType { + comment /* = 1 */, + identifier /* = 2 */, + keyword /* = 3 */, + numericLiteral /* = 4 */, + operator /* = 5 */, + stringLiteral /* = 6 */, + regularExpressionLiteral /* = 7 */, + whiteSpace /* = 8 */, + text /* = 9 */, + punctuation /* = 10 */, + className /* = 11 */, + enumName /* = 12 */, + interfaceName /* = 13 */, + moduleName /* = 14 */, + typeParameterName /* = 15 */, + typeAliasName /* = 16 */, + parameterName /* = 17 */, + docCommentTagName /* = 18 */, + jsxOpenTagName /* = 19 */, + jsxCloseTagName /* = 20 */, + jsxSelfClosingTagName /* = 21 */, + jsxAttribute /* = 22 */, + jsxText /* = 23 */, + jsxAttributeStringLiteralValue /* = 24 */, + bigintLiteral /* = 25 */ +} \ No newline at end of file diff --git a/externals03/utils.module_typescript-to-lua.kt b/externals03/utils.module_typescript-to-lua.kt new file mode 100644 index 0000000..08363d8 --- /dev/null +++ b/externals03/utils.module_typescript-to-lua.kt @@ -0,0 +1,46 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.WriteFileCallback +import ts.SourceFile + +external interface EmitHost { + fun directoryExists(path: String): Boolean + fun fileExists(path: String): Boolean + fun getCurrentDirectory(): String + fun readFile(path: String): String? + var writeFile: WriteFileCallback +} + +external interface BaseFile { + var code: String + var sourceMap: String? + get() = definedExternally + set(value) = definedExternally + var sourceFiles: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface ProcessedFile : BaseFile { + var fileName: String + var luaAst: File? + get() = definedExternally + set(value) = definedExternally +} + +external interface EmitFile : BaseFile { + var outputPath: String +} \ No newline at end of file diff --git a/externals03/visitors.module_typescript-to-lua.kt b/externals03/visitors.module_typescript-to-lua.kt new file mode 100644 index 0000000..69513ac --- /dev/null +++ b/externals03/visitors.module_typescript-to-lua.kt @@ -0,0 +1,38 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.Statement +import ts.Node +import tsstdlib.Map +import ts.SyntaxKind + +external interface NodesBySyntaxKind + +typealias StatementLikeNode = Statement + +typealias VisitorResult = Any + +typealias FunctionVisitor = (node: T, context: TransformationContext) -> VisitorResult + +external interface ObjectVisitor { + var transform: FunctionVisitor + var priority: Number? + get() = definedExternally + set(value) = definedExternally +} + +typealias Visitors = Any + +typealias VisitorMap = Map>> \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..d661f6c --- /dev/null +++ b/gradle.properties @@ -0,0 +1,4 @@ +kotlin.js.compiler=ir +kotlin.mpp.stability.nowarn=true +kotlin.mpp.enableGranularSourceSetsMetadata=true +kotlin.native.enableDependencyPropagation=false diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..7454180f2ae8848c63b8b4dea2cb829da983f2fa GIT binary patch literal 59536 zcma&NbC71ylI~qywr$(CZQJHswz}-9F59+k+g;UV+cs{`J?GrGXYR~=-ydruB3JCa zB64N^cILAcWk5iofq)<(fq;O7{th4@;QxID0)qN`mJ?GIqLY#rX8-|G{5M0pdVW5^ zzXk$-2kQTAC?_N@B`&6-N-rmVFE=$QD?>*=4<|!MJu@}isLc4AW#{m2if&A5T5g&~ ziuMQeS*U5sL6J698wOd)K@oK@1{peP5&Esut<#VH^u)gp`9H4)`uE!2$>RTctN+^u z=ASkePDZA-X8)rp%D;p*~P?*a_=*Kwc<^>QSH|^<0>o37lt^+Mj1;4YvJ(JR-Y+?%Nu}JAYj5 z_Qc5%Ao#F?q32i?ZaN2OSNhWL;2oDEw_({7ZbgUjna!Fqn3NzLM@-EWFPZVmc>(fZ z0&bF-Ch#p9C{YJT9Rcr3+Y_uR^At1^BxZ#eo>$PLJF3=;t_$2|t+_6gg5(j{TmjYU zK12c&lE?Eh+2u2&6Gf*IdKS&6?rYbSEKBN!rv{YCm|Rt=UlPcW9j`0o6{66#y5t9C zruFA2iKd=H%jHf%ypOkxLnO8#H}#Zt{8p!oi6)7#NqoF({t6|J^?1e*oxqng9Q2Cc zg%5Vu!em)}Yuj?kaP!D?b?(C*w!1;>R=j90+RTkyEXz+9CufZ$C^umX^+4|JYaO<5 zmIM3#dv`DGM;@F6;(t!WngZSYzHx?9&$xEF70D1BvfVj<%+b#)vz)2iLCrTeYzUcL z(OBnNoG6Le%M+@2oo)&jdOg=iCszzv59e zDRCeaX8l1hC=8LbBt|k5?CXgep=3r9BXx1uR8!p%Z|0+4Xro=xi0G!e{c4U~1j6!) zH6adq0}#l{%*1U(Cb%4AJ}VLWKBPi0MoKFaQH6x?^hQ!6em@993xdtS%_dmevzeNl z(o?YlOI=jl(`L9^ z0O+H9k$_@`6L13eTT8ci-V0ljDMD|0ifUw|Q-Hep$xYj0hTO@0%IS^TD4b4n6EKDG z??uM;MEx`s98KYN(K0>c!C3HZdZ{+_53DO%9k5W%pr6yJusQAv_;IA}925Y%;+!tY z%2k!YQmLLOr{rF~!s<3-WEUs)`ix_mSU|cNRBIWxOox_Yb7Z=~Q45ZNe*u|m^|)d* zog=i>`=bTe!|;8F+#H>EjIMcgWcG2ORD`w0WD;YZAy5#s{65~qfI6o$+Ty&-hyMyJ z3Ra~t>R!p=5ZpxA;QkDAoPi4sYOP6>LT+}{xp}tk+<0k^CKCFdNYG(Es>p0gqD)jP zWOeX5G;9(m@?GOG7g;e74i_|SmE?`B2i;sLYwRWKLy0RLW!Hx`=!LH3&k=FuCsM=9M4|GqzA)anEHfxkB z?2iK-u(DC_T1};KaUT@3nP~LEcENT^UgPvp!QC@Dw&PVAhaEYrPey{nkcn(ro|r7XUz z%#(=$7D8uP_uU-oPHhd>>^adbCSQetgSG`e$U|7mr!`|bU0aHl_cmL)na-5x1#OsVE#m*+k84Y^+UMeSAa zbrVZHU=mFwXEaGHtXQq`2ZtjfS!B2H{5A<3(nb-6ARVV8kEmOkx6D2x7~-6hl;*-*}2Xz;J#a8Wn;_B5=m zl3dY;%krf?i-Ok^Pal-}4F`{F@TYPTwTEhxpZK5WCpfD^UmM_iYPe}wpE!Djai6_{ z*pGO=WB47#Xjb7!n2Ma)s^yeR*1rTxp`Mt4sfA+`HwZf%!7ZqGosPkw69`Ix5Ku6G z@Pa;pjzV&dn{M=QDx89t?p?d9gna*}jBly*#1!6}5K<*xDPJ{wv4& zM$17DFd~L*Te3A%yD;Dp9UGWTjRxAvMu!j^Tbc}2v~q^59d4bz zvu#!IJCy(BcWTc`;v$9tH;J%oiSJ_i7s;2`JXZF+qd4C)vY!hyCtl)sJIC{ebI*0> z@x>;EzyBv>AI-~{D6l6{ST=em*U( z(r$nuXY-#CCi^8Z2#v#UXOt`dbYN1z5jzNF2 z411?w)whZrfA20;nl&C1Gi+gk<`JSm+{|*2o<< zqM#@z_D`Cn|0H^9$|Tah)0M_X4c37|KQ*PmoT@%xHc3L1ZY6(p(sNXHa&49Frzto& zR`c~ClHpE~4Z=uKa5S(-?M8EJ$zt0&fJk~p$M#fGN1-y$7!37hld`Uw>Urri(DxLa;=#rK0g4J)pXMC zxzraOVw1+kNWpi#P=6(qxf`zSdUC?D$i`8ZI@F>k6k zz21?d+dw7b&i*>Kv5L(LH-?J%@WnqT7j#qZ9B>|Zl+=> z^U-pV@1y_ptHo4hl^cPRWewbLQ#g6XYQ@EkiP z;(=SU!yhjHp%1&MsU`FV1Z_#K1&(|5n(7IHbx&gG28HNT)*~-BQi372@|->2Aw5It z0CBpUcMA*QvsPy)#lr!lIdCi@1k4V2m!NH)%Px(vu-r(Q)HYc!p zJ^$|)j^E#q#QOgcb^pd74^JUi7fUmMiNP_o*lvx*q%_odv49Dsv$NV;6J z9GOXKomA{2Pb{w}&+yHtH?IkJJu~}Z?{Uk++2mB8zyvh*xhHKE``99>y#TdD z&(MH^^JHf;g(Tbb^&8P*;_i*2&fS$7${3WJtV7K&&(MBV2~)2KB3%cWg#1!VE~k#C z!;A;?p$s{ihyojEZz+$I1)L}&G~ml=udD9qh>Tu(ylv)?YcJT3ihapi!zgPtWb*CP zlLLJSRCj-^w?@;RU9aL2zDZY1`I3d<&OMuW=c3$o0#STpv_p3b9Wtbql>w^bBi~u4 z3D8KyF?YE?=HcKk!xcp@Cigvzy=lnFgc^9c%(^F22BWYNAYRSho@~*~S)4%AhEttv zvq>7X!!EWKG?mOd9&n>vvH1p4VzE?HCuxT-u+F&mnsfDI^}*-d00-KAauEaXqg3k@ zy#)MGX!X;&3&0s}F3q40ZmVM$(H3CLfpdL?hB6nVqMxX)q=1b}o_PG%r~hZ4gUfSp zOH4qlEOW4OMUc)_m)fMR_rl^pCfXc{$fQbI*E&mV77}kRF z&{<06AJyJ!e863o-V>FA1a9Eemx6>^F$~9ppt()ZbPGfg_NdRXBWoZnDy2;#ODgf! zgl?iOcF7Meo|{AF>KDwTgYrJLb$L2%%BEtO>T$C?|9bAB&}s;gI?lY#^tttY&hfr# zKhC+&b-rpg_?~uVK%S@mQleU#_xCsvIPK*<`E0fHE1&!J7!xD#IB|SSPW6-PyuqGn3^M^Rz%WT{e?OI^svARX&SAdU77V(C~ zM$H{Kg59op{<|8ry9ecfP%=kFm(-!W&?U0@<%z*+!*<e0XesMxRFu9QnGqun6R_%T+B%&9Dtk?*d$Q zb~>84jEAPi@&F@3wAa^Lzc(AJz5gsfZ7J53;@D<;Klpl?sK&u@gie`~vTsbOE~Cd4 z%kr56mI|#b(Jk&;p6plVwmNB0H@0SmgdmjIn5Ne@)}7Vty(yb2t3ev@22AE^s!KaN zyQ>j+F3w=wnx7w@FVCRe+`vUH)3gW%_72fxzqX!S&!dchdkRiHbXW1FMrIIBwjsai8`CB2r4mAbwp%rrO>3B$Zw;9=%fXI9B{d(UzVap7u z6piC-FQ)>}VOEuPpuqznpY`hN4dGa_1Xz9rVg(;H$5Te^F0dDv*gz9JS<|>>U0J^# z6)(4ICh+N_Q`Ft0hF|3fSHs*?a=XC;e`sJaU9&d>X4l?1W=|fr!5ShD|nv$GK;j46@BV6+{oRbWfqOBRb!ir88XD*SbC(LF}I1h#6@dvK%Toe%@ zhDyG$93H8Eu&gCYddP58iF3oQH*zLbNI;rN@E{T9%A8!=v#JLxKyUe}e}BJpB{~uN zqgxRgo0*-@-iaHPV8bTOH(rS(huwK1Xg0u+e!`(Irzu@Bld&s5&bWgVc@m7;JgELd zimVs`>vQ}B_1(2#rv#N9O`fJpVfPc7V2nv34PC);Dzbb;p!6pqHzvy?2pD&1NE)?A zt(t-ucqy@wn9`^MN5apa7K|L=9>ISC>xoc#>{@e}m#YAAa1*8-RUMKwbm|;5p>T`Z zNf*ph@tnF{gmDa3uwwN(g=`Rh)4!&)^oOy@VJaK4lMT&5#YbXkl`q?<*XtsqD z9PRK6bqb)fJw0g-^a@nu`^?71k|m3RPRjt;pIkCo1{*pdqbVs-Yl>4E>3fZx3Sv44grW=*qdSoiZ9?X0wWyO4`yDHh2E!9I!ZFi zVL8|VtW38}BOJHW(Ax#KL_KQzarbuE{(%TA)AY)@tY4%A%P%SqIU~8~-Lp3qY;U-} z`h_Gel7;K1h}7$_5ZZT0&%$Lxxr-<89V&&TCsu}LL#!xpQ1O31jaa{U34~^le*Y%L za?7$>Jk^k^pS^_M&cDs}NgXlR>16AHkSK-4TRaJSh#h&p!-!vQY%f+bmn6x`4fwTp z$727L^y`~!exvmE^W&#@uY!NxJi`g!i#(++!)?iJ(1)2Wk;RN zFK&O4eTkP$Xn~4bB|q8y(btx$R#D`O@epi4ofcETrx!IM(kWNEe42Qh(8*KqfP(c0 zouBl6>Fc_zM+V;F3znbo{x#%!?mH3`_ANJ?y7ppxS@glg#S9^MXu|FM&ynpz3o&Qh z2ujAHLF3($pH}0jXQsa#?t--TnF1P73b?4`KeJ9^qK-USHE)4!IYgMn-7z|=ALF5SNGkrtPG@Y~niUQV2?g$vzJN3nZ{7;HZHzWAeQ;5P|@Tl3YHpyznGG4-f4=XflwSJY+58-+wf?~Fg@1p1wkzuu-RF3j2JX37SQUc? zQ4v%`V8z9ZVZVqS8h|@@RpD?n0W<=hk=3Cf8R?d^9YK&e9ZybFY%jdnA)PeHvtBe- zhMLD+SSteHBq*q)d6x{)s1UrsO!byyLS$58WK;sqip$Mk{l)Y(_6hEIBsIjCr5t>( z7CdKUrJTrW%qZ#1z^n*Lb8#VdfzPw~OIL76aC+Rhr<~;4Tl!sw?Rj6hXj4XWa#6Tp z@)kJ~qOV)^Rh*-?aG>ic2*NlC2M7&LUzc9RT6WM%Cpe78`iAowe!>(T0jo&ivn8-7 zs{Qa@cGy$rE-3AY0V(l8wjI^uB8Lchj@?L}fYal^>T9z;8juH@?rG&g-t+R2dVDBe zq!K%{e-rT5jX19`(bP23LUN4+_zh2KD~EAYzhpEO3MUG8@}uBHH@4J zd`>_(K4q&>*k82(dDuC)X6JuPrBBubOg7qZ{?x!r@{%0);*`h*^F|%o?&1wX?Wr4b z1~&cy#PUuES{C#xJ84!z<1tp9sfrR(i%Tu^jnXy;4`Xk;AQCdFC@?V%|; zySdC7qS|uQRcH}EFZH%mMB~7gi}a0utE}ZE_}8PQH8f;H%PN41Cb9R%w5Oi5el^fd z$n{3SqLCnrF##x?4sa^r!O$7NX!}&}V;0ZGQ&K&i%6$3C_dR%I7%gdQ;KT6YZiQrW zk%q<74oVBV>@}CvJ4Wj!d^?#Zwq(b$E1ze4$99DuNg?6t9H}k_|D7KWD7i0-g*EO7 z;5{hSIYE4DMOK3H%|f5Edx+S0VI0Yw!tsaRS2&Il2)ea^8R5TG72BrJue|f_{2UHa z@w;^c|K3da#$TB0P3;MPlF7RuQeXT$ zS<<|C0OF(k)>fr&wOB=gP8!Qm>F41u;3esv7_0l%QHt(~+n; zf!G6%hp;Gfa9L9=AceiZs~tK+Tf*Wof=4!u{nIO90jH@iS0l+#%8=~%ASzFv7zqSB^?!@N7)kp0t&tCGLmzXSRMRyxCmCYUD2!B`? zhs$4%KO~m=VFk3Buv9osha{v+mAEq=ik3RdK@;WWTV_g&-$U4IM{1IhGX{pAu%Z&H zFfwCpUsX%RKg);B@7OUzZ{Hn{q6Vv!3#8fAg!P$IEx<0vAx;GU%}0{VIsmFBPq_mb zpe^BChDK>sc-WLKl<6 zwbW|e&d&dv9Wu0goueyu>(JyPx1mz0v4E?cJjFuKF71Q1)AL8jHO$!fYT3(;U3Re* zPPOe%*O+@JYt1bW`!W_1!mN&=w3G9ru1XsmwfS~BJ))PhD(+_J_^N6j)sx5VwbWK| zwRyC?W<`pOCY)b#AS?rluxuuGf-AJ=D!M36l{ua?@SJ5>e!IBr3CXIxWw5xUZ@Xrw z_R@%?{>d%Ld4p}nEsiA@v*nc6Ah!MUs?GA7e5Q5lPpp0@`%5xY$C;{%rz24$;vR#* zBP=a{)K#CwIY%p} zXVdxTQ^HS@O&~eIftU+Qt^~(DGxrdi3k}DdT^I7Iy5SMOp$QuD8s;+93YQ!OY{eB24%xY7ml@|M7I(Nb@K_-?F;2?et|CKkuZK_>+>Lvg!>JE~wN`BI|_h6$qi!P)+K-1Hh(1;a`os z55)4Q{oJiA(lQM#;w#Ta%T0jDNXIPM_bgESMCDEg6rM33anEr}=|Fn6)|jBP6Y}u{ zv9@%7*#RI9;fv;Yii5CI+KrRdr0DKh=L>)eO4q$1zmcSmglsV`*N(x=&Wx`*v!!hn6X-l0 zP_m;X??O(skcj+oS$cIdKhfT%ABAzz3w^la-Ucw?yBPEC+=Pe_vU8nd-HV5YX6X8r zZih&j^eLU=%*;VzhUyoLF;#8QsEfmByk+Y~caBqSvQaaWf2a{JKB9B>V&r?l^rXaC z8)6AdR@Qy_BxQrE2Fk?ewD!SwLuMj@&d_n5RZFf7=>O>hzVE*seW3U?_p|R^CfoY`?|#x9)-*yjv#lo&zP=uI`M?J zbzC<^3x7GfXA4{FZ72{PE*-mNHyy59Q;kYG@BB~NhTd6pm2Oj=_ zizmD?MKVRkT^KmXuhsk?eRQllPo2Ubk=uCKiZ&u3Xjj~<(!M94c)Tez@9M1Gfs5JV z->@II)CDJOXTtPrQudNjE}Eltbjq>6KiwAwqvAKd^|g!exgLG3;wP+#mZYr`cy3#39e653d=jrR-ulW|h#ddHu(m9mFoW~2yE zz5?dB%6vF}+`-&-W8vy^OCxm3_{02royjvmwjlp+eQDzFVEUiyO#gLv%QdDSI#3W* z?3!lL8clTaNo-DVJw@ynq?q!%6hTQi35&^>P85G$TqNt78%9_sSJt2RThO|JzM$iL zg|wjxdMC2|Icc5rX*qPL(coL!u>-xxz-rFiC!6hD1IR%|HSRsV3>Kq~&vJ=s3M5y8SG%YBQ|{^l#LGlg!D?E>2yR*eV%9m$_J6VGQ~AIh&P$_aFbh zULr0Z$QE!QpkP=aAeR4ny<#3Fwyw@rZf4?Ewq`;mCVv}xaz+3ni+}a=k~P+yaWt^L z@w67!DqVf7D%7XtXX5xBW;Co|HvQ8WR1k?r2cZD%U;2$bsM%u8{JUJ5Z0k= zZJARv^vFkmWx15CB=rb=D4${+#DVqy5$C%bf`!T0+epLJLnh1jwCdb*zuCL}eEFvE z{rO1%gxg>1!W(I!owu*mJZ0@6FM(?C+d*CeceZRW_4id*D9p5nzMY&{mWqrJomjIZ z97ZNnZ3_%Hx8dn;H>p8m7F#^2;T%yZ3H;a&N7tm=Lvs&lgJLW{V1@h&6Vy~!+Ffbb zv(n3+v)_D$}dqd!2>Y2B)#<+o}LH#%ogGi2-?xRIH)1!SD)u-L65B&bsJTC=LiaF+YOCif2dUX6uAA|#+vNR z>U+KQekVGon)Yi<93(d!(yw1h3&X0N(PxN2{%vn}cnV?rYw z$N^}_o!XUB!mckL`yO1rnUaI4wrOeQ(+&k?2mi47hzxSD`N#-byqd1IhEoh!PGq>t z_MRy{5B0eKY>;Ao3z$RUU7U+i?iX^&r739F)itdrTpAi-NN0=?^m%?{A9Ly2pVv>Lqs6moTP?T2-AHqFD-o_ znVr|7OAS#AEH}h8SRPQ@NGG47dO}l=t07__+iK8nHw^(AHx&Wb<%jPc$$jl6_p(b$ z)!pi(0fQodCHfM)KMEMUR&UID>}m^(!{C^U7sBDOA)$VThRCI0_+2=( zV8mMq0R(#z;C|7$m>$>`tX+T|xGt(+Y48@ZYu#z;0pCgYgmMVbFb!$?%yhZqP_nhn zy4<#3P1oQ#2b51NU1mGnHP$cf0j-YOgAA}A$QoL6JVLcmExs(kU{4z;PBHJD%_=0F z>+sQV`mzijSIT7xn%PiDKHOujX;n|M&qr1T@rOxTdxtZ!&u&3HHFLYD5$RLQ=heur zb>+AFokUVQeJy-#LP*^)spt{mb@Mqe=A~-4p0b+Bt|pZ+@CY+%x}9f}izU5;4&QFE zO1bhg&A4uC1)Zb67kuowWY4xbo&J=%yoXlFB)&$d*-}kjBu|w!^zbD1YPc0-#XTJr z)pm2RDy%J3jlqSMq|o%xGS$bPwn4AqitC6&e?pqWcjWPt{3I{>CBy;hg0Umh#c;hU3RhCUX=8aR>rmd` z7Orw(5tcM{|-^J?ZAA9KP|)X6n9$-kvr#j5YDecTM6n z&07(nD^qb8hpF0B^z^pQ*%5ePYkv&FabrlI61ntiVp!!C8y^}|<2xgAd#FY=8b*y( zuQOuvy2`Ii^`VBNJB&R!0{hABYX55ooCAJSSevl4RPqEGb)iy_0H}v@vFwFzD%>#I>)3PsouQ+_Kkbqy*kKdHdfkN7NBcq%V{x^fSxgXpg7$bF& zj!6AQbDY(1u#1_A#1UO9AxiZaCVN2F0wGXdY*g@x$ByvUA?ePdide0dmr#}udE%K| z3*k}Vv2Ew2u1FXBaVA6aerI36R&rzEZeDDCl5!t0J=ug6kuNZzH>3i_VN`%BsaVB3 zQYw|Xub_SGf{)F{$ZX5`Jc!X!;eybjP+o$I{Z^Hsj@D=E{MnnL+TbC@HEU2DjG{3-LDGIbq()U87x4eS;JXnSh;lRlJ z>EL3D>wHt-+wTjQF$fGyDO$>d+(fq@bPpLBS~xA~R=3JPbS{tzN(u~m#Po!?H;IYv zE;?8%^vle|%#oux(Lj!YzBKv+Fd}*Ur-dCBoX*t{KeNM*n~ZPYJ4NNKkI^MFbz9!v z4(Bvm*Kc!-$%VFEewYJKz-CQN{`2}KX4*CeJEs+Q(!kI%hN1!1P6iOq?ovz}X0IOi z)YfWpwW@pK08^69#wSyCZkX9?uZD?C^@rw^Y?gLS_xmFKkooyx$*^5#cPqntNTtSG zlP>XLMj2!VF^0k#ole7`-c~*~+_T5ls?x4)ah(j8vo_ zwb%S8qoaZqY0-$ZI+ViIA_1~~rAH7K_+yFS{0rT@eQtTAdz#8E5VpwnW!zJ_^{Utv zlW5Iar3V5t&H4D6A=>?mq;G92;1cg9a2sf;gY9pJDVKn$DYdQlvfXq}zz8#LyPGq@ z+`YUMD;^-6w&r-82JL7mA8&M~Pj@aK!m{0+^v<|t%APYf7`}jGEhdYLqsHW-Le9TL z_hZZ1gbrz7$f9^fAzVIP30^KIz!!#+DRLL+qMszvI_BpOSmjtl$hh;&UeM{ER@INV zcI}VbiVTPoN|iSna@=7XkP&-4#06C};8ajbxJ4Gcq8(vWv4*&X8bM^T$mBk75Q92j z1v&%a;OSKc8EIrodmIiw$lOES2hzGDcjjB`kEDfJe{r}yE6`eZL zEB`9u>Cl0IsQ+t}`-cx}{6jqcANucqIB>Qmga_&<+80E2Q|VHHQ$YlAt{6`Qu`HA3 z03s0-sSlwbvgi&_R8s={6<~M^pGvBNjKOa>tWenzS8s zR>L7R5aZ=mSU{f?ib4Grx$AeFvtO5N|D>9#)ChH#Fny2maHWHOf2G=#<9Myot#+4u zWVa6d^Vseq_0=#AYS(-m$Lp;*8nC_6jXIjEM`omUmtH@QDs3|G)i4j*#_?#UYVZvJ z?YjT-?!4Q{BNun;dKBWLEw2C-VeAz`%?A>p;)PL}TAZn5j~HK>v1W&anteARlE+~+ zj>c(F;?qO3pXBb|#OZdQnm<4xWmn~;DR5SDMxt0UK_F^&eD|KZ=O;tO3vy4@4h^;2 zUL~-z`-P1aOe?|ZC1BgVsL)2^J-&vIFI%q@40w0{jjEfeVl)i9(~bt2z#2Vm)p`V_ z1;6$Ae7=YXk#=Qkd24Y23t&GvRxaOoad~NbJ+6pxqzJ>FY#Td7@`N5xp!n(c!=RE& z&<<@^a$_Ys8jqz4|5Nk#FY$~|FPC0`*a5HH!|Gssa9=~66&xG9)|=pOOJ2KE5|YrR zw!w6K2aC=J$t?L-;}5hn6mHd%hC;p8P|Dgh6D>hGnXPgi;6r+eA=?f72y9(Cf_ho{ zH6#)uD&R=73^$$NE;5piWX2bzR67fQ)`b=85o0eOLGI4c-Tb@-KNi2pz=Ke@SDcPn za$AxXib84`!Sf;Z3B@TSo`Dz7GM5Kf(@PR>Ghzi=BBxK8wRp>YQoXm+iL>H*Jo9M3 z6w&E?BC8AFTFT&Tv8zf+m9<&S&%dIaZ)Aoqkak_$r-2{$d~0g2oLETx9Y`eOAf14QXEQw3tJne;fdzl@wV#TFXSLXM2428F-Q}t+n2g%vPRMUzYPvzQ9f# zu(liiJem9P*?0%V@RwA7F53r~|I!Ty)<*AsMX3J{_4&}{6pT%Tpw>)^|DJ)>gpS~1rNEh z0$D?uO8mG?H;2BwM5a*26^7YO$XjUm40XmBsb63MoR;bJh63J;OngS5sSI+o2HA;W zdZV#8pDpC9Oez&L8loZO)MClRz!_!WD&QRtQxnazhT%Vj6Wl4G11nUk8*vSeVab@N#oJ}`KyJv+8Mo@T1-pqZ1t|?cnaVOd;1(h9 z!$DrN=jcGsVYE-0-n?oCJ^4x)F}E;UaD-LZUIzcD?W^ficqJWM%QLy6QikrM1aKZC zi{?;oKwq^Vsr|&`i{jIphA8S6G4)$KGvpULjH%9u(Dq247;R#l&I0{IhcC|oBF*Al zvLo7Xte=C{aIt*otJD}BUq)|_pdR>{zBMT< z(^1RpZv*l*m*OV^8>9&asGBo8h*_4q*)-eCv*|Pq=XNGrZE)^(SF7^{QE_~4VDB(o zVcPA_!G+2CAtLbl+`=Q~9iW`4ZRLku!uB?;tWqVjB0lEOf}2RD7dJ=BExy=<9wkb- z9&7{XFA%n#JsHYN8t5d~=T~5DcW4$B%3M+nNvC2`0!#@sckqlzo5;hhGi(D9=*A4` z5ynobawSPRtWn&CDLEs3Xf`(8^zDP=NdF~F^s&={l7(aw&EG}KWpMjtmz7j_VLO;@ zM2NVLDxZ@GIv7*gzl1 zjq78tv*8#WSY`}Su0&C;2F$Ze(q>F(@Wm^Gw!)(j;dk9Ad{STaxn)IV9FZhm*n+U} zi;4y*3v%A`_c7a__DJ8D1b@dl0Std3F||4Wtvi)fCcBRh!X9$1x!_VzUh>*S5s!oq z;qd{J_r79EL2wIeiGAqFstWtkfIJpjVh%zFo*=55B9Zq~y0=^iqHWfQl@O!Ak;(o*m!pZqe9 z%U2oDOhR)BvW8&F70L;2TpkzIutIvNQaTjjs5V#8mV4!NQ}zN=i`i@WI1z0eN-iCS z;vL-Wxc^Vc_qK<5RPh(}*8dLT{~GzE{w2o$2kMFaEl&q zP{V=>&3kW7tWaK-Exy{~`v4J0U#OZBk{a9{&)&QG18L@6=bsZ1zC_d{{pKZ-Ey>I> z;8H0t4bwyQqgu4hmO`3|4K{R*5>qnQ&gOfdy?z`XD%e5+pTDzUt3`k^u~SaL&XMe= z9*h#kT(*Q9jO#w2Hd|Mr-%DV8i_1{J1MU~XJ3!WUplhXDYBpJH><0OU`**nIvPIof z|N8@I=wA)sf45SAvx||f?Z5uB$kz1qL3Ky_{%RPdP5iN-D2!p5scq}buuC00C@jom zhfGKm3|f?Z0iQ|K$Z~!`8{nmAS1r+fp6r#YDOS8V*;K&Gs7Lc&f^$RC66O|)28oh`NHy&vq zJh+hAw8+ybTB0@VhWN^0iiTnLsCWbS_y`^gs!LX!Lw{yE``!UVzrV24tP8o;I6-65 z1MUiHw^{bB15tmrVT*7-#sj6cs~z`wk52YQJ*TG{SE;KTm#Hf#a~|<(|ImHH17nNM z`Ub{+J3dMD!)mzC8b(2tZtokKW5pAwHa?NFiso~# z1*iaNh4lQ4TS)|@G)H4dZV@l*Vd;Rw;-;odDhW2&lJ%m@jz+Panv7LQm~2Js6rOW3 z0_&2cW^b^MYW3)@o;neZ<{B4c#m48dAl$GCc=$>ErDe|?y@z`$uq3xd(%aAsX)D%l z>y*SQ%My`yDP*zof|3@_w#cjaW_YW4BdA;#Glg1RQcJGY*CJ9`H{@|D+*e~*457kd z73p<%fB^PV!Ybw@)Dr%(ZJbX}xmCStCYv#K3O32ej{$9IzM^I{6FJ8!(=azt7RWf4 z7ib0UOPqN40X!wOnFOoddd8`!_IN~9O)#HRTyjfc#&MCZ zZAMzOVB=;qwt8gV?{Y2?b=iSZG~RF~uyx18K)IDFLl})G1v@$(s{O4@RJ%OTJyF+Cpcx4jmy|F3euCnMK!P2WTDu5j z{{gD$=M*pH!GGzL%P)V2*ROm>!$Y=z|D`!_yY6e7SU$~a5q8?hZGgaYqaiLnkK%?0 zs#oI%;zOxF@g*@(V4p!$7dS1rOr6GVs6uYCTt2h)eB4?(&w8{#o)s#%gN@BBosRUe z)@P@8_Zm89pr~)b>e{tbPC~&_MR--iB{=)y;INU5#)@Gix-YpgP<-c2Ms{9zuCX|3 z!p(?VaXww&(w&uBHzoT%!A2=3HAP>SDxcljrego7rY|%hxy3XlODWffO_%g|l+7Y_ zqV(xbu)s4lV=l7M;f>vJl{`6qBm>#ZeMA}kXb97Z)?R97EkoI?x6Lp0yu1Z>PS?2{ z0QQ(8D)|lc9CO3B~e(pQM&5(1y&y=e>C^X$`)_&XuaI!IgDTVqt31wX#n+@!a_A0ZQkA zCJ2@M_4Gb5MfCrm5UPggeyh)8 zO9?`B0J#rkoCx(R0I!ko_2?iO@|oRf1;3r+i)w-2&j?=;NVIdPFsB)`|IC0zk6r9c zRrkfxWsiJ(#8QndNJj@{@WP2Ackr|r1VxV{7S&rSU(^)-M8gV>@UzOLXu9K<{6e{T zXJ6b92r$!|lwjhmgqkdswY&}c)KW4A)-ac%sU;2^fvq7gfUW4Bw$b!i@duy1CAxSn z(pyh$^Z=&O-q<{bZUP+$U}=*#M9uVc>CQVgDs4swy5&8RAHZ~$)hrTF4W zPsSa~qYv_0mJnF89RnnJTH`3}w4?~epFl=D(35$ zWa07ON$`OMBOHgCmfO(9RFc<)?$x)N}Jd2A(<*Ll7+4jrRt9w zwGxExUXd9VB#I|DwfxvJ;HZ8Q{37^wDhaZ%O!oO(HpcqfLH%#a#!~;Jl7F5>EX_=8 z{()l2NqPz>La3qJR;_v+wlK>GsHl;uRA8%j`A|yH@k5r%55S9{*Cp%uw6t`qc1!*T za2OeqtQj7sAp#Q~=5Fs&aCR9v>5V+s&RdNvo&H~6FJOjvaj--2sYYBvMq;55%z8^o z|BJDA4vzfow#DO#ZQHh;Oq_{r+qP{R9ox2TOgwQiv7Ow!zjN+A@BN;0tA2lUb#+zO z(^b89eV)D7UVE+h{mcNc6&GtpOqDn_?VAQ)Vob$hlFwW%xh>D#wml{t&Ofmm_d_+; zKDxzdr}`n2Rw`DtyIjrG)eD0vut$}dJAZ0AohZ+ZQdWXn_Z@dI_y=7t3q8x#pDI-K z2VVc&EGq445Rq-j0=U=Zx`oBaBjsefY;%)Co>J3v4l8V(T8H?49_@;K6q#r~Wwppc z4XW0(4k}cP=5ex>-Xt3oATZ~bBWKv)aw|I|Lx=9C1s~&b77idz({&q3T(Y(KbWO?+ zmcZ6?WeUsGk6>km*~234YC+2e6Zxdl~<_g2J|IE`GH%n<%PRv-50; zH{tnVts*S5*_RxFT9eM0z-pksIb^drUq4>QSww=u;UFCv2AhOuXE*V4z?MM`|ABOC4P;OfhS(M{1|c%QZ=!%rQTDFx`+}?Kdx$&FU?Y<$x;j7z=(;Lyz+?EE>ov!8vvMtSzG!nMie zsBa9t8as#2nH}n8xzN%W%U$#MHNXmDUVr@GX{?(=yI=4vks|V)!-W5jHsU|h_&+kY zS_8^kd3jlYqOoiI`ZqBVY!(UfnAGny!FowZWY_@YR0z!nG7m{{)4OS$q&YDyw6vC$ zm4!$h>*|!2LbMbxS+VM6&DIrL*X4DeMO!@#EzMVfr)e4Tagn~AQHIU8?e61TuhcKD zr!F4(kEebk(Wdk-?4oXM(rJwanS>Jc%<>R(siF+>+5*CqJLecP_we33iTFTXr6W^G z7M?LPC-qFHK;E!fxCP)`8rkxZyFk{EV;G-|kwf4b$c1k0atD?85+|4V%YATWMG|?K zLyLrws36p%Qz6{}>7b>)$pe>mR+=IWuGrX{3ZPZXF3plvuv5Huax86}KX*lbPVr}L z{C#lDjdDeHr~?l|)Vp_}T|%$qF&q#U;ClHEPVuS+Jg~NjC1RP=17=aQKGOcJ6B3mp z8?4*-fAD~}sX*=E6!}^u8)+m2j<&FSW%pYr_d|p_{28DZ#Cz0@NF=gC-o$MY?8Ca8 zr5Y8DSR^*urS~rhpX^05r30Ik#2>*dIOGxRm0#0YX@YQ%Mg5b6dXlS!4{7O_kdaW8PFSdj1=ryI-=5$fiieGK{LZ+SX(1b=MNL!q#lN zv98?fqqTUH8r8C7v(cx#BQ5P9W>- zmW93;eH6T`vuJ~rqtIBg%A6>q>gnWb3X!r0wh_q;211+Om&?nvYzL1hhtjB zK_7G3!n7PL>d!kj){HQE zE8(%J%dWLh1_k%gVXTZt zEdT09XSKAx27Ncaq|(vzL3gm83q>6CAw<$fTnMU05*xAe&rDfCiu`u^1)CD<>sx0i z*hr^N_TeN89G(nunZoLBf^81#pmM}>JgD@Nn1l*lN#a=B=9pN%tmvYFjFIoKe_(GF z-26x{(KXdfsQL7Uv6UtDuYwV`;8V3w>oT_I<`Ccz3QqK9tYT5ZQzbop{=I=!pMOCb zCU68`n?^DT%^&m>A%+-~#lvF!7`L7a{z<3JqIlk1$<||_J}vW1U9Y&eX<}l8##6i( zZcTT@2`9(Mecptm@{3A_Y(X`w9K0EwtPq~O!16bq{7c0f7#(3wn-^)h zxV&M~iiF!{-6A@>o;$RzQ5A50kxXYj!tcgme=Qjrbje~;5X2xryU;vH|6bE(8z^<7 zQ>BG7_c*JG8~K7Oe68i#0~C$v?-t@~@r3t2inUnLT(c=URpA9kA8uq9PKU(Ps(LVH zqgcqW>Gm?6oV#AldDPKVRcEyQIdTT`Qa1j~vS{<;SwyTdr&3*t?J)y=M7q*CzucZ&B0M=joT zBbj@*SY;o2^_h*>R0e({!QHF0=)0hOj^B^d*m>SnRrwq>MolNSgl^~r8GR#mDWGYEIJA8B<|{{j?-7p zVnV$zancW3&JVDtVpIlI|5djKq0(w$KxEFzEiiL=h5Jw~4Le23@s(mYyXWL9SX6Ot zmb)sZaly_P%BeX_9 zw&{yBef8tFm+%=--m*J|o~+Xg3N+$IH)t)=fqD+|fEk4AAZ&!wcN5=mi~Vvo^i`}> z#_3ahR}Ju)(Px7kev#JGcSwPXJ2id9%Qd2A#Uc@t8~egZ8;iC{e! z%=CGJOD1}j!HW_sgbi_8suYnn4#Ou}%9u)dXd3huFIb!ytlX>Denx@pCS-Nj$`VO&j@(z!kKSP0hE4;YIP#w9ta=3DO$7f*x zc9M4&NK%IrVmZAe=r@skWD`AEWH=g+r|*13Ss$+{c_R!b?>?UaGXlw*8qDmY#xlR= z<0XFbs2t?8i^G~m?b|!Hal^ZjRjt<@a? z%({Gn14b4-a|#uY^=@iiKH+k?~~wTj5K1A&hU z2^9-HTC)7zpoWK|$JXaBL6C z#qSNYtY>65T@Zs&-0cHeu|RX(Pxz6vTITdzJdYippF zC-EB+n4}#lM7`2Ry~SO>FxhKboIAF#Z{1wqxaCb{#yEFhLuX;Rx(Lz%T`Xo1+a2M}7D+@wol2)OJs$TwtRNJ={( zD@#zTUEE}#Fz#&(EoD|SV#bayvr&E0vzmb%H?o~46|FAcx?r4$N z&67W3mdip-T1RIxwSm_&(%U|+WvtGBj*}t69XVd&ebn>KOuL(7Y8cV?THd-(+9>G7*Nt%T zcH;`p={`SOjaf7hNd(=37Lz3-51;58JffzIPgGs_7xIOsB5p2t&@v1mKS$2D$*GQ6 zM(IR*j4{nri7NMK9xlDy-hJW6sW|ZiDRaFiayj%;(%51DN!ZCCCXz+0Vm#};70nOx zJ#yA0P3p^1DED;jGdPbQWo0WATN=&2(QybbVdhd=Vq*liDk`c7iZ?*AKEYC#SY&2g z&Q(Ci)MJ{mEat$ZdSwTjf6h~roanYh2?9j$CF@4hjj_f35kTKuGHvIs9}Re@iKMxS-OI*`0S z6s)fOtz}O$T?PLFVSeOjSO26$@u`e<>k(OSP!&YstH3ANh>)mzmKGNOwOawq-MPXe zy4xbeUAl6tamnx))-`Gi2uV5>9n(73yS)Ukma4*7fI8PaEwa)dWHs6QA6>$}7?(L8 ztN8M}?{Tf!Zu22J5?2@95&rQ|F7=FK-hihT-vDp!5JCcWrVogEnp;CHenAZ)+E+K5 z$Cffk5sNwD_?4+ymgcHR(5xgt20Z8M`2*;MzOM#>yhk{r3x=EyM226wb&!+j`W<%* zSc&|`8!>dn9D@!pYow~(DsY_naSx7(Z4i>cu#hA5=;IuI88}7f%)bRkuY2B;+9Uep zpXcvFWkJ!mQai63BgNXG26$5kyhZ2&*3Q_tk)Ii4M>@p~_~q_cE!|^A;_MHB;7s#9 zKzMzK{lIxotjc};k67^Xsl-gS!^*m*m6kn|sbdun`O?dUkJ{0cmI0-_2y=lTAfn*Y zKg*A-2sJq)CCJgY0LF-VQvl&6HIXZyxo2#!O&6fOhbHXC?%1cMc6y^*dOS{f$=137Ds1m01qs`>iUQ49JijsaQ( zksqV9@&?il$|4Ua%4!O15>Zy&%gBY&wgqB>XA3!EldQ%1CRSM(pp#k~-pkcCg4LAT zXE=puHbgsw)!xtc@P4r~Z}nTF=D2~j(6D%gTBw$(`Fc=OOQ0kiW$_RDd=hcO0t97h zb86S5r=>(@VGy1&#S$Kg_H@7G^;8Ue)X5Y+IWUi`o;mpvoV)`fcVk4FpcT|;EG!;? zHG^zrVVZOm>1KFaHlaogcWj(v!S)O(Aa|Vo?S|P z5|6b{qkH(USa*Z7-y_Uvty_Z1|B{rTS^qmEMLEYUSk03_Fg&!O3BMo{b^*`3SHvl0 zhnLTe^_vVIdcSHe)SQE}r~2dq)VZJ!aSKR?RS<(9lzkYo&dQ?mubnWmgMM37Nudwo z3Vz@R{=m2gENUE3V4NbIzAA$H1z0pagz94-PTJyX{b$yndsdKptmlKQKaaHj@3=ED zc7L?p@%ui|RegVYutK$64q4pe9+5sv34QUpo)u{1ci?)_7gXQd{PL>b0l(LI#rJmN zGuO+%GO`xneFOOr4EU(Wg}_%bhzUf;d@TU+V*2#}!2OLwg~%D;1FAu=Un>OgjPb3S z7l(riiCwgghC=Lm5hWGf5NdGp#01xQ59`HJcLXbUR3&n%P(+W2q$h2Qd z*6+-QXJ*&Kvk9ht0f0*rO_|FMBALen{j7T1l%=Q>gf#kma zQlg#I9+HB+z*5BMxdesMND`_W;q5|FaEURFk|~&{@qY32N$G$2B=&Po{=!)x5b!#n zxLzblkq{yj05#O7(GRuT39(06FJlalyv<#K4m}+vs>9@q-&31@1(QBv82{}Zkns~K ze{eHC_RDX0#^A*JQTwF`a=IkE6Ze@j#-8Q`tTT?k9`^ZhA~3eCZJ-Jr{~7Cx;H4A3 zcZ+Zj{mzFZbVvQ6U~n>$U2ZotGsERZ@}VKrgGh0xM;Jzt29%TX6_&CWzg+YYMozrM z`nutuS)_0dCM8UVaKRj804J4i%z2BA_8A4OJRQ$N(P9Mfn-gF;4#q788C@9XR0O3< zsoS4wIoyt046d+LnSCJOy@B@Uz*#GGd#+Ln1ek5Dv>(ZtD@tgZlPnZZJGBLr^JK+!$$?A_fA3LOrkoDRH&l7 zcMcD$Hsjko3`-{bn)jPL6E9Ds{WskMrivsUu5apD z?grQO@W7i5+%X&E&p|RBaEZ(sGLR@~(y^BI@lDMot^Ll?!`90KT!JXUhYS`ZgX3jnu@Ja^seA*M5R@f`=`ynQV4rc$uT1mvE?@tz)TN<=&H1%Z?5yjxcpO+6y_R z6EPuPKM5uxKpmZfT(WKjRRNHs@ib)F5WAP7QCADvmCSD#hPz$V10wiD&{NXyEwx5S z6NE`3z!IS^$s7m}PCwQutVQ#~w+V z=+~->DI*bR2j0^@dMr9`p>q^Ny~NrAVxrJtX2DUveic5vM%#N*XO|?YAWwNI$Q)_) zvE|L(L1jP@F%gOGtnlXtIv2&1i8q<)Xfz8O3G^Ea~e*HJsQgBxWL(yuLY+jqUK zRE~`-zklrGog(X}$9@ZVUw!8*=l`6mzYLtsg`AvBYz(cxmAhr^j0~(rzXdiOEeu_p zE$sf2(w(BPAvO5DlaN&uQ$4@p-b?fRs}d7&2UQ4Fh?1Hzu*YVjcndqJLw0#q@fR4u zJCJ}>_7-|QbvOfylj+e^_L`5Ep9gqd>XI3-O?Wp z-gt*P29f$Tx(mtS`0d05nHH=gm~Po_^OxxUwV294BDKT>PHVlC5bndncxGR!n(OOm znsNt@Q&N{TLrmsoKFw0&_M9$&+C24`sIXGWgQaz=kY;S{?w`z^Q0JXXBKFLj0w0U6P*+jPKyZHX9F#b0D1$&(- zrm8PJd?+SrVf^JlfTM^qGDK&-p2Kdfg?f>^%>1n8bu&byH(huaocL>l@f%c*QkX2i znl}VZ4R1en4S&Bcqw?$=Zi7ohqB$Jw9x`aM#>pHc0x z0$!q7iFu zZ`tryM70qBI6JWWTF9EjgG@>6SRzsd}3h+4D8d~@CR07P$LJ}MFsYi-*O%XVvD@yT|rJ+Mk zDllJ7$n0V&A!0flbOf)HE6P_afPWZmbhpliqJuw=-h+r;WGk|ntkWN(8tKlYpq5Ow z(@%s>IN8nHRaYb*^d;M(D$zGCv5C|uqmsDjwy4g=Lz>*OhO3z=)VD}C<65;`89Ye} zSCxrv#ILzIpEx1KdLPlM&%Cctf@FqTKvNPXC&`*H9=l=D3r!GLM?UV zOxa(8ZsB`&+76S-_xuj?G#wXBfDY@Z_tMpXJS7^mp z@YX&u0jYw2A+Z+bD#6sgVK5ZgdPSJV3>{K^4~%HV?rn~4D)*2H!67Y>0aOmzup`{D zzDp3c9yEbGCY$U<8biJ_gB*`jluz1ShUd!QUIQJ$*1;MXCMApJ^m*Fiv88RZ zFopLViw}{$Tyhh_{MLGIE2~sZ)t0VvoW%=8qKZ>h=adTe3QM$&$PO2lfqH@brt!9j ziePM8$!CgE9iz6B<6_wyTQj?qYa;eC^{x_0wuwV~W+^fZmFco-o%wsKSnjXFEx02V zF5C2t)T6Gw$Kf^_c;Ei3G~uC8SM-xyycmXyC2hAVi-IfXqhu$$-C=*|X?R0~hu z8`J6TdgflslhrmDZq1f?GXF7*ALeMmOEpRDg(s*H`4>_NAr`2uqF;k;JQ+8>A|_6ZNsNLECC%NNEb1Y1dP zbIEmNpK)#XagtL4R6BC{C5T(+=yA-(Z|Ap}U-AfZM#gwVpus3(gPn}Q$CExObJ5AC z)ff9Yk?wZ}dZ-^)?cbb9Fw#EjqQ8jxF4G3=L?Ra zg_)0QDMV1y^A^>HRI$x?Op@t;oj&H@1xt4SZ9(kifQ zb59B*`M99Td7@aZ3UWvj1rD0sE)d=BsBuW*KwkCds7ay(7*01_+L}b~7)VHI>F_!{ zyxg-&nCO?v#KOUec0{OOKy+sjWA;8rTE|Lv6I9H?CI?H(mUm8VXGwU$49LGpz&{nQp2}dinE1@lZ1iox6{ghN&v^GZv9J${7WaXj)<0S4g_uiJ&JCZ zr8-hsu`U%N;+9N^@&Q0^kVPB3)wY(rr}p7{p0qFHb3NUUHJb672+wRZs`gd1UjKPX z4o6zljKKA+Kkj?H>Ew63o%QjyBk&1!P22;MkD>sM0=z_s-G{mTixJCT9@_|*(p^bz zJ8?ZZ&;pzV+7#6Mn`_U-)k8Pjg?a;|Oe^us^PoPY$Va~yi8|?+&=y$f+lABT<*pZr zP}D{~Pq1Qyni+@|aP;ixO~mbEW9#c0OU#YbDZIaw=_&$K%Ep2f%hO^&P67hApZe`x zv8b`Mz@?M_7-)b!lkQKk)JXXUuT|B8kJlvqRmRpxtQDgvrHMXC1B$M@Y%Me!BSx3P z#2Eawl$HleZhhTS6Txm>lN_+I`>eV$&v9fOg)%zVn3O5mI*lAl>QcHuW6!Kixmq`X zBCZ*Ck6OYtDiK!N47>jxI&O2a9x7M|i^IagRr-fmrmikEQGgw%J7bO|)*$2FW95O4 zeBs>KR)izRG1gRVL;F*sr8A}aRHO0gc$$j&ds8CIO1=Gwq1%_~E)CWNn9pCtBE}+`Jelk4{>S)M)`Ll=!~gnn1yq^EX(+y*ik@3Ou0qU`IgYi3*doM+5&dU!cho$pZ zn%lhKeZkS72P?Cf68<#kll_6OAO26bIbueZx**j6o;I0cS^XiL`y+>{cD}gd%lux} z)3N>MaE24WBZ}s0ApfdM;5J_Ny}rfUyxfkC``Awo2#sgLnGPewK};dORuT?@I6(5~ z?kE)Qh$L&fwJXzK){iYx!l5$Tt|^D~MkGZPA}(o6f7w~O2G6Vvzdo*a;iXzk$B66$ zwF#;wM7A+(;uFG4+UAY(2`*3XXx|V$K8AYu#ECJYSl@S=uZW$ksfC$~qrrbQj4??z-)uz0QL}>k^?fPnJTPw% zGz)~?B4}u0CzOf@l^um}HZzbaIwPmb<)< zi_3@E9lc)Qe2_`*Z^HH;1CXOceL=CHpHS{HySy3T%<^NrWQ}G0i4e1xm_K3(+~oi$ zoHl9wzb?Z4j#90DtURtjtgvi7uw8DzHYmtPb;?%8vb9n@bszT=1qr)V_>R%s!92_` zfnHQPANx z<#hIjIMm#*(v*!OXtF+w8kLu`o?VZ5k7{`vw{Yc^qYclpUGIM_PBN1+c{#Vxv&E*@ zxg=W2W~JuV{IuRYw3>LSI1)a!thID@R=bU+cU@DbR^_SXY`MC7HOsCN z!dO4OKV7(E_Z8T#8MA1H`99?Z!r0)qKW_#|29X3#Jb+5+>qUidbeP1NJ@)(qi2S-X zao|f0_tl(O+$R|Qwd$H{_ig|~I1fbp_$NkI!0E;Y z6JrnU{1Ra6^on{9gUUB0mwzP3S%B#h0fjo>JvV~#+X0P~JV=IG=yHG$O+p5O3NUgG zEQ}z6BTp^Fie)Sg<){Z&I8NwPR(=mO4joTLHkJ>|Tnk23E(Bo`FSbPc05lF2-+)X? z6vV3*m~IBHTy*^E!<0nA(tCOJW2G4DsH7)BxLV8kICn5lu6@U*R`w)o9;Ro$i8=Q^V%uH8n3q=+Yf;SFRZu z!+F&PKcH#8cG?aSK_Tl@K9P#8o+jry@gdexz&d(Q=47<7nw@e@FFfIRNL9^)1i@;A z28+$Z#rjv-wj#heI|<&J_DiJ*s}xd-f!{J8jfqOHE`TiHHZVIA8CjkNQ_u;Ery^^t zl1I75&u^`1_q)crO+JT4rx|z2ToSC>)Or@-D zy3S>jW*sNIZR-EBsfyaJ+Jq4BQE4?SePtD2+jY8*%FsSLZ9MY>+wk?}}}AFAw)vr{ml)8LUG-y9>^t!{~|sgpxYc0Gnkg`&~R z-pilJZjr@y5$>B=VMdZ73svct%##v%wdX~9fz6i3Q-zOKJ9wso+h?VME7}SjL=!NUG{J?M&i!>ma`eoEa@IX`5G>B1(7;%}M*%-# zfhJ(W{y;>MRz!Ic8=S}VaBKqh;~7KdnGEHxcL$kA-6E~=!hrN*zw9N+_=odt<$_H_8dbo;0=42wcAETPCVGUr~v(`Uai zb{=D!Qc!dOEU6v)2eHSZq%5iqK?B(JlCq%T6av$Cb4Rko6onlG&?CqaX7Y_C_cOC3 zYZ;_oI(}=>_07}Oep&Ws7x7-R)cc8zfe!SYxJYP``pi$FDS)4Fvw5HH=FiU6xfVqIM!hJ;Rx8c0cB7~aPtNH(Nmm5Vh{ibAoU#J6 zImRCr?(iyu_4W_6AWo3*vxTPUw@vPwy@E0`(>1Qi=%>5eSIrp^`` zK*Y?fK_6F1W>-7UsB)RPC4>>Ps9)f+^MqM}8AUm@tZ->j%&h1M8s*s!LX5&WxQcAh z8mciQej@RPm?660%>{_D+7er>%zX_{s|$Z+;G7_sfNfBgY(zLB4Ey}J9F>zX#K0f6 z?dVNIeEh?EIShmP6>M+d|0wMM85Sa4diw1hrg|ITJ}JDg@o8y>(rF9mXk5M z2@D|NA)-7>wD&wF;S_$KS=eE84`BGw3g0?6wGxu8ys4rwI?9U=*^VF22t3%mbGeOh z`!O-OpF7#Vceu~F`${bW0nYVU9ecmk31V{tF%iv&5hWofC>I~cqAt@u6|R+|HLMMX zVxuSlMFOK_EQ86#E8&KwxIr8S9tj_goWtLv4f@!&h8;Ov41{J~496vp9vX=(LK#j! zAwi*21RAV-LD>9Cw3bV_9X(X3)Kr0-UaB*7Y>t82EQ%!)(&(XuAYtTsYy-dz+w=$ir)VJpe!_$ z6SGpX^i(af3{o=VlFPC);|J8#(=_8#vdxDe|Cok+ANhYwbE*FO`Su2m1~w+&9<_9~ z-|tTU_ACGN`~CNW5WYYBn^B#SwZ(t4%3aPp z;o)|L6Rk569KGxFLUPx@!6OOa+5OjQLK5w&nAmwxkC5rZ|m&HT8G%GVZxB_@ME z>>{rnXUqyiJrT(8GMj_ap#yN_!9-lO5e8mR3cJiK3NE{_UM&=*vIU`YkiL$1%kf+1 z4=jk@7EEj`u(jy$HnzE33ZVW_J4bj}K;vT?T91YlO(|Y0FU4r+VdbmQ97%(J5 zkK*Bed8+C}FcZ@HIgdCMioV%A<*4pw_n}l*{Cr4}a(lq|injK#O?$tyvyE`S%(1`H z_wwRvk#13ElkZvij2MFGOj`fhy?nC^8`Zyo%yVcUAfEr8x&J#A{|moUBAV_^f$hpaUuyQeY3da^ zS9iRgf87YBwfe}>BO+T&Fl%rfpZh#+AM?Dq-k$Bq`vG6G_b4z%Kbd&v>qFjow*mBl z-OylnqOpLg}or7_VNwRg2za3VBK6FUfFX{|TD z`Wt0Vm2H$vdlRWYQJqDmM?JUbVqL*ZQY|5&sY*?!&%P8qhA~5+Af<{MaGo(dl&C5t zE%t!J0 zh6jqANt4ABdPxSTrVV}fLsRQal*)l&_*rFq(Ez}ClEH6LHv{J#v?+H-BZ2)Wy{K@9 z+ovXHq~DiDvm>O~r$LJo!cOuwL+Oa--6;UFE2q@g3N8Qkw5E>ytz^(&($!O47+i~$ zKM+tkAd-RbmP{s_rh+ugTD;lriL~`Xwkad#;_aM?nQ7L_muEFI}U_4$phjvYgleK~`Fo`;GiC07&Hq1F<%p;9Q;tv5b?*QnR%8DYJH3P>Svmv47Y>*LPZJy8_{9H`g6kQpyZU{oJ`m%&p~D=K#KpfoJ@ zn-3cqmHsdtN!f?~w+(t+I`*7GQA#EQC^lUA9(i6=i1PqSAc|ha91I%X&nXzjYaM{8$s&wEx@aVkQ6M{E2 zfzId#&r(XwUNtPcq4Ngze^+XaJA1EK-%&C9j>^9(secqe{}z>hR5CFNveMsVA)m#S zk)_%SidkY-XmMWlVnQ(mNJ>)ooszQ#vaK;!rPmGKXV7am^_F!Lz>;~{VrIO$;!#30XRhE1QqO_~#+Ux;B_D{Nk=grn z8Y0oR^4RqtcYM)7a%@B(XdbZCOqnX#fD{BQTeLvRHd(irHKq=4*jq34`6@VAQR8WG z^%)@5CXnD_T#f%@-l${>y$tfb>2LPmc{~5A82|16mH)R?&r#KKLs7xpN-D`=&Cm^R zvMA6#Ahr<3X>Q7|-qfTY)}32HkAz$_mibYV!I)u>bmjK`qwBe(>za^0Kt*HnFbSdO z1>+ryKCNxmm^)*$XfiDOF2|{-v3KKB?&!(S_Y=Ht@|ir^hLd978xuI&N{k>?(*f8H z=ClxVJK_%_z1TH0eUwm2J+2To7FK4o+n_na)&#VLn1m;!+CX+~WC+qg1?PA~KdOlC zW)C@pw75_xoe=w7i|r9KGIvQ$+3K?L{7TGHwrQM{dCp=Z*D}3kX7E-@sZnup!BImw z*T#a=+WcTwL78exTgBn|iNE3#EsOorO z*kt)gDzHiPt07fmisA2LWN?AymkdqTgr?=loT7z@d`wnlr6oN}@o|&JX!yPzC*Y8d zu6kWlTzE1)ckyBn+0Y^HMN+GA$wUO_LN6W>mxCo!0?oiQvT`z$jbSEu&{UHRU0E8# z%B^wOc@S!yhMT49Y)ww(Xta^8pmPCe@eI5C*ed96)AX9<>))nKx0(sci8gwob_1}4 z0DIL&vsJ1_s%<@y%U*-eX z5rN&(zef-5G~?@r79oZGW1d!WaTqQn0F6RIOa9tJ=0(kdd{d1{<*tHT#cCvl*i>YY zH+L7jq8xZNcTUBqj(S)ztTU!TM!RQ}In*n&Gn<>(60G7}4%WQL!o>hbJqNDSGwl#H z`4k+twp0cj%PsS+NKaxslAEu9!#U3xT1|_KB6`h=PI0SW`P9GTa7caD1}vKEglV8# zjKZR`pluCW19c2fM&ZG)c3T3Um;ir3y(tSCJ7Agl6|b524dy5El{^EQBG?E61H0XY z`bqg!;zhGhyMFl&(o=JWEJ8n~z)xI}A@C0d2hQGvw7nGv)?POU@(kS1m=%`|+^ika zXl8zjS?xqW$WlO?Ewa;vF~XbybHBor$f<%I&*t$F5fynwZlTGj|IjZtVfGa7l&tK} zW>I<69w(cZLu)QIVG|M2xzW@S+70NinQzk&Y0+3WT*cC)rx~04O-^<{JohU_&HL5XdUKW!uFy|i$FB|EMu0eUyW;gsf`XfIc!Z0V zeK&*hPL}f_cX=@iv>K%S5kL;cl_$v?n(Q9f_cChk8Lq$glT|=e+T*8O4H2n<=NGmn z+2*h+v;kBvF>}&0RDS>)B{1!_*XuE8A$Y=G8w^qGMtfudDBsD5>T5SB;Qo}fSkkiV ze^K^M(UthkwrD!&*tTsu>Dacdj_q`~V%r_twr$(Ct&_dKeeXE?fA&4&yASJWJ*}~- zel=@W)tusynfC_YqH4ll>4Eg`Xjs5F7Tj>tTLz<0N3)X<1px_d2yUY>X~y>>93*$) z5PuNMQLf9Bu?AAGO~a_|J2akO1M*@VYN^VxvP0F$2>;Zb9;d5Yfd8P%oFCCoZE$ z4#N$^J8rxYjUE_6{T%Y>MmWfHgScpuGv59#4u6fpTF%~KB^Ae`t1TD_^Ud#DhL+Dm zbY^VAM#MrAmFj{3-BpVSWph2b_Y6gCnCAombVa|1S@DU)2r9W<> zT5L8BB^er3zxKt1v(y&OYk!^aoQisqU zH(g@_o)D~BufUXcPt!Ydom)e|aW{XiMnes2z&rE?og>7|G+tp7&^;q?Qz5S5^yd$i z8lWr4g5nctBHtigX%0%XzIAB8U|T6&JsC4&^hZBw^*aIcuNO47de?|pGXJ4t}BB`L^d8tD`H`i zqrP8?#J@8T#;{^B!KO6J=@OWKhAerih(phML`(Rg7N1XWf1TN>=Z3Do{l_!d~DND&)O)D>ta20}@Lt77qSnVsA7>)uZAaT9bsB>u&aUQl+7GiY2|dAEg@%Al3i316y;&IhQL^8fw_nwS>f60M_-m+!5)S_6EPM7Y)(Nq^8gL7(3 zOiot`6Wy6%vw~a_H?1hLVzIT^i1;HedHgW9-P#)}Y6vF%C=P70X0Tk^z9Te@kPILI z_(gk!k+0%CG)%!WnBjjw*kAKs_lf#=5HXC00s-}oM-Q1aXYLj)(1d!_a7 z*Gg4Fe6F$*ujVjI|79Z5+Pr`us%zW@ln++2l+0hsngv<{mJ%?OfSo_3HJXOCys{Ug z00*YR-(fv<=&%Q!j%b-_ppA$JsTm^_L4x`$k{VpfLI(FMCap%LFAyq;#ns5bR7V+x zO!o;c5y~DyBPqdVQX)8G^G&jWkBy2|oWTw>)?5u}SAsI$RjT#)lTV&Rf8;>u*qXnb z8F%Xb=7#$m)83z%`E;49)t3fHInhtc#kx4wSLLms!*~Z$V?bTyUGiS&m>1P(952(H zuHdv=;o*{;5#X-uAyon`hP}d#U{uDlV?W?_5UjJvf%11hKwe&(&9_~{W)*y1nR5f_ z!N(R74nNK`y8>B!0Bt_Vr!;nc3W>~RiKtGSBkNlsR#-t^&;$W#)f9tTlZz>n*+Fjz z3zXZ;jf(sTM(oDzJt4FJS*8c&;PLTW(IQDFs_5QPy+7yhi1syPCarvqrHFcf&yTy)^O<1EBx;Ir`5W{TIM>{8w&PB>ro4;YD<5LF^TjTb0!zAP|QijA+1Vg>{Afv^% zmrkc4o6rvBI;Q8rj4*=AZacy*n8B{&G3VJc)so4$XUoie0)vr;qzPZVbb<#Fc=j+8CGBWe$n|3K& z_@%?{l|TzKSlUEO{U{{%Fz_pVDxs7i9H#bnbCw7@4DR=}r_qV!Zo~CvD4ZI*+j3kO zW6_=|S`)(*gM0Z;;}nj`73OigF4p6_NPZQ-Od~e$c_);;4-7sR>+2u$6m$Gf%T{aq zle>e3(*Rt(TPD}03n5)!Ca8Pu!V}m6v0o1;5<1h$*|7z|^(3$Y&;KHKTT}hV056wuF0Xo@mK-52~r=6^SI1NC%c~CC?n>yX6wPTgiWYVz!Sx^atLby9YNn1Rk{g?|pJaxD4|9cUf|V1_I*w zzxK)hRh9%zOl=*$?XUjly5z8?jPMy%vEN)f%T*|WO|bp5NWv@B(K3D6LMl!-6dQg0 zXNE&O>Oyf%K@`ngCvbGPR>HRg5!1IV$_}m@3dWB7x3t&KFyOJn9pxRXCAzFr&%37wXG;z^xaO$ekR=LJG ztIHpY8F5xBP{mtQidqNRoz= z@){+N3(VO5bD+VrmS^YjG@+JO{EOIW)9=F4v_$Ed8rZtHvjpiEp{r^c4F6Ic#ChlC zJX^DtSK+v(YdCW)^EFcs=XP7S>Y!4=xgmv>{S$~@h=xW-G4FF9?I@zYN$e5oF9g$# zb!eVU#J+NjLyX;yb)%SY)xJdvGhsnE*JEkuOVo^k5PyS=o#vq!KD46UTW_%R=Y&0G zFj6bV{`Y6)YoKgqnir2&+sl+i6foAn-**Zd1{_;Zb7Ki=u394C5J{l^H@XN`_6XTKY%X1AgQM6KycJ+= zYO=&t#5oSKB^pYhNdzPgH~aEGW2=ec1O#s-KG z71}LOg@4UEFtp3GY1PBemXpNs6UK-ax*)#$J^pC_me;Z$Je(OqLoh|ZrW*mAMBFn< zHttjwC&fkVfMnQeen8`Rvy^$pNRFVaiEN4Pih*Y3@jo!T0nsClN)pdrr9AYLcZxZ| zJ5Wlj+4q~($hbtuY zVQ7hl>4-+@6g1i`1a)rvtp-;b0>^`Dloy(#{z~ytgv=j4q^Kl}wD>K_Y!l~ zp(_&7sh`vfO(1*MO!B%<6E_bx1)&s+Ae`O)a|X=J9y~XDa@UB`m)`tSG4AUhoM=5& znWoHlA-(z@3n0=l{E)R-p8sB9XkV zZ#D8wietfHL?J5X0%&fGg@MH~(rNS2`GHS4xTo7L$>TPme+Is~!|79=^}QbPF>m%J zFMkGzSndiPO|E~hrhCeo@&Ea{M(ieIgRWMf)E}qeTxT8Q#g-!Lu*x$v8W^M^>?-g= zwMJ$dThI|~M06rG$Sv@C@tWR>_YgaG&!BAbkGggVQa#KdtDB)lMLNVLN|51C@F^y8 zCRvMB^{GO@j=cHfmy}_pCGbP%xb{pNN>? z?7tBz$1^zVaP|uaatYaIN+#xEN4jBzwZ|YI_)p(4CUAz1ZEbDk>J~Y|63SZaak~#0 zoYKruYsWHoOlC1(MhTnsdUOwQfz5p6-D0}4;DO$B;7#M{3lSE^jnTT;ns`>!G%i*F?@pR1JO{QTuD0U+~SlZxcc8~>IB{)@8p`P&+nDxNj`*gh|u?yrv$phpQcW)Us)bi`kT%qLj(fi{dWRZ%Es2!=3mI~UxiW0$-v3vUl?#g{p6eF zMEUAqo5-L0Ar(s{VlR9g=j7+lt!gP!UN2ICMokAZ5(Agd>})#gkA2w|5+<%-CuEP# zqgcM}u@3(QIC^Gx<2dbLj?cFSws_f3e%f4jeR?4M^M3cx1f+Qr6ydQ>n)kz1s##2w zk}UyQc+Z5G-d-1}{WzjkLXgS-2P7auWSJ%pSnD|Uivj5u!xk0 z_^-N9r9o;(rFDt~q1PvE#iJZ_f>J3gcP$)SOqhE~pD2|$=GvpL^d!r z6u=sp-CrMoF7;)}Zd7XO4XihC4ji?>V&(t^?@3Q&t9Mx=qex6C9d%{FE6dvU6%d94 zIE;hJ1J)cCqjv?F``7I*6bc#X)JW2b4f$L^>j{*$R`%5VHFi*+Q$2;nyieduE}qdS{L8y8F08yLs?w}{>8>$3236T-VMh@B zq-nujsb_1aUv_7g#)*rf9h%sFj*^mIcImRV*k~Vmw;%;YH(&ylYpy!&UjUVqqtfG` zox3esju?`unJJA_zKXRJP)rA3nXc$m^{S&-p|v|-0x9LHJm;XIww7C#R$?00l&Yyj z=e}gKUOpsImwW?N)+E(awoF@HyP^EhL+GlNB#k?R<2>95hz!h9sF@U20DHSB3~WMa zk90+858r@-+vWwkawJ)8ougd(i#1m3GLN{iSTylYz$brAsP%=&m$mQQrH$g%3-^VR zE%B`Vi&m8f3T~&myTEK28BDWCVzfWir1I?03;pX))|kY5ClO^+bae z*7E?g=3g7EiisYOrE+lA)2?Ln6q2*HLNpZEWMB|O-JI_oaHZB%CvYB(%=tU= zE*OY%QY58fW#RG5=gm0NR#iMB=EuNF@)%oZJ}nmm=tsJ?eGjia{e{yuU0l3{d^D@)kVDt=1PE)&tf_hHC%0MB znL|CRCPC}SeuVTdf>-QV70`0(EHizc21s^sU>y%hW0t!0&y<7}Wi-wGy>m%(-jsDj zP?mF|>p_K>liZ6ZP(w5(|9Ga%>tLgb$|doDDfkdW>Z z`)>V2XC?NJT26mL^@ zf+IKr27TfM!UbZ@?zRddC7#6ss1sw%CXJ4FWC+t3lHZupzM77m^=9 z&(a?-LxIq}*nvv)y?27lZ{j zifdl9hyJudyP2LpU$-kXctshbJDKS{WfulP5Dk~xU4Le4c#h^(YjJit4#R8_khheS z|8(>2ibaHES4+J|DBM7I#QF5u-*EdN{n=Kt@4Zt?@Tv{JZA{`4 zU#kYOv{#A&gGPwT+$Ud}AXlK3K7hYzo$(fBSFjrP{QQ zeaKg--L&jh$9N}`pu{Bs>?eDFPaWY4|9|foN%}i;3%;@4{dc+iw>m}{3rELqH21G! z`8@;w-zsJ1H(N3%|1B@#ioLOjib)j`EiJqPQVSbPSPVHCj6t5J&(NcWzBrzCiDt{4 zdlPAUKldz%6x5II1H_+jv)(xVL+a;P+-1hv_pM>gMRr%04@k;DTokASSKKhU1Qms| zrWh3a!b(J3n0>-tipg{a?UaKsP7?+|@A+1WPDiQIW1Sf@qDU~M_P65_s}7(gjTn0X zucyEm)o;f8UyshMy&>^SC3I|C6jR*R_GFwGranWZe*I>K+0k}pBuET&M~ z;Odo*ZcT?ZpduHyrf8E%IBFtv;JQ!N_m>!sV6ly$_1D{(&nO~w)G~Y`7sD3#hQk%^ zp}ucDF_$!6DAz*PM8yE(&~;%|=+h(Rn-=1Wykas_-@d&z#=S}rDf`4w(rVlcF&lF! z=1)M3YVz7orwk^BXhslJ8jR);sh^knJW(Qmm(QdSgIAIdlN4Te5KJisifjr?eB{FjAX1a0AB>d?qY4Wx>BZ8&}5K0fA+d{l8 z?^s&l8#j7pR&ijD?0b%;lL9l$P_mi2^*_OL+b}4kuLR$GAf85sOo02?Y#90}CCDiS zZ%rbCw>=H~CBO=C_JVV=xgDe%b4FaEFtuS7Q1##y686r%F6I)s-~2(}PWK|Z8M+Gu zl$y~5@#0Ka%$M<&Cv%L`a8X^@tY&T7<0|(6dNT=EsRe0%kp1Qyq!^43VAKYnr*A5~ zsI%lK1ewqO;0TpLrT9v}!@vJK{QoVa_+N4FYT#h?Y8rS1S&-G+m$FNMP?(8N`MZP zels(*?kK{{^g9DOzkuZXJ2;SrOQsp9T$hwRB1(phw1c7`!Q!by?Q#YsSM#I12RhU{$Q+{xj83axHcftEc$mNJ8_T7A-BQc*k(sZ+~NsO~xAA zxnbb%dam_fZlHvW7fKXrB~F&jS<4FD2FqY?VG?ix*r~MDXCE^WQ|W|WM;gsIA4lQP zJ2hAK@CF*3*VqPr2eeg6GzWFlICi8S>nO>5HvWzyZTE)hlkdC_>pBej*>o0EOHR|) z$?};&I4+_?wvL*g#PJ9)!bc#9BJu1(*RdNEn>#Oxta(VWeM40ola<0aOe2kSS~{^P zDJBd}0L-P#O-CzX*%+$#v;(x%<*SPgAje=F{Zh-@ucd2DA(yC|N_|ocs*|-!H%wEw z@Q!>siv2W;C^^j^59OAX03&}&D*W4EjCvfi(ygcL#~t8XGa#|NPO+*M@Y-)ctFA@I z-p7npT1#5zOLo>7q?aZpCZ=iecn3QYklP;gF0bq@>oyBq94f6C=;Csw3PkZ|5q=(c zfs`aw?II0e(h=|7o&T+hq&m$; zBrE09Twxd9BJ2P+QPN}*OdZ-JZV7%av@OM7v!!NL8R;%WFq*?{9T3{ct@2EKgc8h) zMxoM$SaF#p<`65BwIDfmXG6+OiK0e)`I=!A3E`+K@61f}0e z!2a*FOaDrOe>U`q%K!QN`&=&0C~)CaL3R4VY(NDt{Xz(Xpqru5=r#uQN1L$Je1*dkdqQ*=lofQaN%lO!<5z9ZlHgxt|`THd>2 zsWfU$9=p;yLyJyM^t zS2w9w?Bpto`@H^xJpZDKR1@~^30Il6oFGfk5%g6w*C+VM)+%R@gfIwNprOV5{F^M2 zO?n3DEzpT+EoSV-%OdvZvNF+pDd-ZVZ&d8 zKeIyrrfPN=EcFRCPEDCVflX#3-)Ik_HCkL(ejmY8vzcf-MTA{oHk!R2*36`O68$7J zf}zJC+bbQk--9Xm!u#lgLvx8TXx2J258E5^*IZ(FXMpq$2LUUvhWQPs((z1+2{Op% z?J}9k5^N=z;7ja~zi8a_-exIqWUBJwohe#4QJ`|FF*$C{lM18z^#hX6!5B8KAkLUX ziP=oti-gpV(BsLD{0(3*dw}4JxK23Y7M{BeFPucw!sHpY&l%Ws4pSm`+~V7;bZ%Dx zeI)MK=4vC&5#;2MT7fS?^ch9?2;%<8Jlu-IB&N~gg8t;6S-#C@!NU{`p7M8@2iGc& zg|JPg%@gCoCQ&s6JvDU&`X2S<57f(k8nJ1wvBu{8r?;q3_kpZZ${?|( z+^)UvR33sjSd)aT!UPkA;ylO6{aE3MQa{g%Mcf$1KONcjO@&g5zPHWtzM1rYC{_K> zgQNcs<{&X{OA=cEWw5JGqpr0O>x*Tfak2PE9?FuWtz^DDNI}rwAaT0(bdo-<+SJ6A z&}S%boGMWIS0L}=S>|-#kRX;e^sUsotry(MjE|3_9duvfc|nwF#NHuM-w7ZU!5ei8 z6Mkf>2)WunY2eU@C-Uj-A zG(z0Tz2YoBk>zCz_9-)4a>T46$(~kF+Y{#sA9MWH%5z#zNoz)sdXq7ZR_+`RZ%0(q zC7&GyS_|BGHNFl8Xa%@>iWh%Gr?=J5<(!OEjauj5jyrA-QXBjn0OAhJJ9+v=!LK`` z@g(`^*84Q4jcDL`OA&ZV60djgwG`|bcD*i50O}Q{9_noRg|~?dj%VtKOnyRs$Uzqg z191aWoR^rDX#@iSq0n z?9Sg$WSRPqSeI<}&n1T3!6%Wj@5iw5`*`Btni~G=&;J+4`7g#OQTa>u`{4ZZ(c@s$ zK0y;ySOGD-UTjREKbru{QaS>HjN<2)R%Nn-TZiQ(Twe4p@-saNa3~p{?^V9Nixz@a zykPv~<@lu6-Ng9i$Lrk(xi2Tri3q=RW`BJYOPC;S0Yly%77c727Yj-d1vF!Fuk{Xh z)lMbA69y7*5ufET>P*gXQrxsW+ zz)*MbHZv*eJPEXYE<6g6_M7N%#%mR{#awV3i^PafNv(zyI)&bH?F}2s8_rR(6%!V4SOWlup`TKAb@ee>!9JKPM=&8g#BeYRH9FpFybxBXQI2|g}FGJfJ+ zY-*2hB?o{TVL;Wt_ek;AP5PBqfDR4@Z->_182W z{P@Mc27j6jE*9xG{R$>6_;i=y{qf(c`5w9fa*`rEzX6t!KJ(p1H|>J1pC-2zqWENF zmm=Z5B4u{cY2XYl(PfrInB*~WGWik3@1oRhiMOS|D;acnf-Bs(QCm#wR;@Vf!hOPJ zgjhDCfDj$HcyVLJ=AaTbQ{@vIv14LWWF$=i-BDoC11}V;2V8A`S>_x)vIq44-VB-v z*w-d}$G+Ql?En8j!~ZkCpQ$|cA0|+rrY>tiCeWxkRGPoarxlGU2?7%k#F693RHT24 z-?JsiXlT2PTqZqNb&sSc>$d;O4V@|b6VKSWQb~bUaWn1Cf0+K%`Q&Wc<>mQ>*iEGB zbZ;aYOotBZ{vH3y<0A*L0QVM|#rf*LIsGx(O*-7)r@yyBIzJnBFSKBUSl1e|8lxU* zzFL+YDVVkIuzFWeJ8AbgN&w(4-7zbiaMn{5!JQXu)SELk*CNL+Fro|2v|YO)1l15t zs(0^&EB6DPMyaqvY>=KL>)tEpsn;N5Q#yJj<9}ImL((SqErWN3Q=;tBO~ExTCs9hB z2E$7eN#5wX4<3m^5pdjm#5o>s#eS_Q^P)tm$@SawTqF*1dj_i#)3};JslbLKHXl_N z)Fxzf>FN)EK&Rz&*|6&%Hs-^f{V|+_vL1S;-1K-l$5xiC@}%uDuwHYhmsV?YcOUlk zOYkG5v2+`+UWqpn0aaaqrD3lYdh0*!L`3FAsNKu=Q!vJu?Yc8n|CoYyDo_`r0mPoo z8>XCo$W4>l(==h?2~PoRR*kEe)&IH{1sM41mO#-36`02m#nTX{r*r`Q5rZ2-sE|nA zhnn5T#s#v`52T5|?GNS`%HgS2;R(*|^egNPDzzH_z^W)-Q98~$#YAe)cEZ%vge965AS_am#DK#pjPRr-!^za8>`kksCAUj(Xr*1NW5~e zpypt_eJpD&4_bl_y?G%>^L}=>xAaV>KR6;^aBytqpiHe%!j;&MzI_>Sx7O%F%D*8s zSN}cS^<{iiK)=Ji`FpO#^zY!_|D)qeRNAtgmH)m;qC|mq^j(|hL`7uBz+ULUj37gj zksdbnU+LSVo35riSX_4z{UX=%n&}7s0{WuZYoSfwAP`8aKN9P@%e=~1`~1ASL-z%# zw>DO&ixr}c9%4InGc*_y42bdEk)ZdG7-mTu0bD@_vGAr*NcFoMW;@r?@LUhRI zCUJgHb`O?M3!w)|CPu~ej%fddw20lod?Ufp8Dmt0PbnA0J%KE^2~AIcnKP()025V> zG>noSM3$5Btmc$GZoyP^v1@Poz0FD(6YSTH@aD0}BXva?LphAiSz9f&Y(aDAzBnUh z?d2m``~{z;{}kZJ>a^wYI?ry(V9hIoh;|EFc0*-#*`$T0DRQ1;WsqInG;YPS+I4{g zJGpKk%%Sdc5xBa$Q^_I~(F97eqDO7AN3EN0u)PNBAb+n+ zWBTxQx^;O9o0`=g+Zrt_{lP!sgWZHW?8bLYS$;1a@&7w9rD9|Ge;Gb?sEjFoF9-6v z#!2)t{DMHZ2@0W*fCx;62d#;jouz`R5Y(t{BT=$N4yr^^o$ON8d{PQ=!O zX17^CrdM~7D-;ZrC!||<+FEOxI_WI3CA<35va%4v>gc zEX-@h8esj=a4szW7x{0g$hwoWRQG$yK{@3mqd-jYiVofJE!Wok1* znV7Gm&Ssq#hFuvj1sRyHg(6PFA5U*Q8Rx>-blOs=lb`qa{zFy&n4xY;sd$fE+<3EI z##W$P9M{B3c3Si9gw^jlPU-JqD~Cye;wr=XkV7BSv#6}DrsXWFJ3eUNrc%7{=^sP> zrp)BWKA9<}^R9g!0q7yWlh;gr_TEOD|#BmGq<@IV;ueg+D2}cjpp+dPf&Q(36sFU&K8}hA85U61faW&{ zlB`9HUl-WWCG|<1XANN3JVAkRYvr5U4q6;!G*MTdSUt*Mi=z_y3B1A9j-@aK{lNvx zK%p23>M&=KTCgR!Ee8c?DAO2_R?B zkaqr6^BSP!8dHXxj%N1l+V$_%vzHjqvu7p@%Nl6;>y*S}M!B=pz=aqUV#`;h%M0rU zHfcog>kv3UZAEB*g7Er@t6CF8kHDmKTjO@rejA^ULqn!`LwrEwOVmHx^;g|5PHm#B zZ+jjWgjJ!043F+&#_;D*mz%Q60=L9Ove|$gU&~As5^uz@2-BfQ!bW)Khn}G+Wyjw- z19qI#oB(RSNydn0t~;tAmK!P-d{b-@@E5|cdgOS#!>%#Rj6ynkMvaW@37E>@hJP^8 z2zk8VXx|>#R^JCcWdBCy{0nPmYFOxN55#^-rlqobe0#L6)bi?E?SPymF*a5oDDeSd zO0gx?#KMoOd&G(2O@*W)HgX6y_aa6iMCl^~`{@UR`nMQE`>n_{_aY5nA}vqU8mt8H z`oa=g0SyiLd~BxAj2~l$zRSDHxvDs;I4>+M$W`HbJ|g&P+$!U7-PHX4RAcR0szJ*( ze-417=bO2q{492SWrqDK+L3#ChUHtz*@MP)e^%@>_&#Yk^1|tv@j4%3T)diEX zATx4K*hcO`sY$jk#jN5WD<=C3nvuVsRh||qDHnc~;Kf59zr0;c7VkVSUPD%NnnJC_ zl3F^#f_rDu8l}l8qcAz0FFa)EAt32IUy_JLIhU_J^l~FRH&6-ivSpG2PRqzDdMWft>Zc(c)#tb%wgmWN%>IOPm zZi-noqS!^Ftb81pRcQi`X#UhWK70hy4tGW1mz|+vI8c*h@ zfFGJtW3r>qV>1Z0r|L>7I3un^gcep$AAWfZHRvB|E*kktY$qQP_$YG60C@X~tTQjB3%@`uz!qxtxF+LE!+=nrS^07hn` zEgAp!h|r03h7B!$#OZW#ACD+M;-5J!W+{h|6I;5cNnE(Y863%1(oH}_FTW})8zYb$7czP zg~Szk1+_NTm6SJ0MS_|oSz%e(S~P-&SFp;!k?uFayytV$8HPwuyELSXOs^27XvK-D zOx-Dl!P|28DK6iX>p#Yb%3`A&CG0X2S43FjN%IB}q(!hC$fG}yl1y9W&W&I@KTg6@ zK^kpH8=yFuP+vI^+59|3%Zqnb5lTDAykf z9S#X`3N(X^SpdMyWQGOQRjhiwlj!0W-yD<3aEj^&X%=?`6lCy~?`&WSWt z?U~EKFcCG_RJ(Qp7j=$I%H8t)Z@6VjA#>1f@EYiS8MRHZphp zMA_5`znM=pzUpBPO)pXGYpQ6gkine{6u_o!P@Q+NKJ}k!_X7u|qfpAyIJb$_#3@wJ z<1SE2Edkfk9C!0t%}8Yio09^F`YGzpaJHGk*-ffsn85@)%4@`;Fv^8q(-Wk7r=Q8p zT&hD`5(f?M{gfzGbbwh8(}G#|#fDuk7v1W)5H9wkorE0ZZjL0Q1=NRGY>zwgfm81DdoaVwNH;or{{eSyybt)m<=zXoA^RALYG-2t zouH|L*BLvmm9cdMmn+KGopyR@4*=&0&4g|FLoreZOhRmh=)R0bg~ zT2(8V_q7~42-zvb)+y959OAv!V$u(O3)%Es0M@CRFmG{5sovIq4%8Ahjk#*5w{+)+ zMWQoJI_r$HxL5km1#6(e@{lK3Udc~n0@g`g$s?VrnQJ$!oPnb?IHh-1qA`Rz$)Ai< z6w$-MJW-gKNvOhL+XMbE7&mFt`x1KY>k4(!KbbpZ`>`K@1J<(#vVbjx@Z@(6Q}MF# zMnbr-f55(cTa^q4+#)=s+ThMaV~E`B8V=|W_fZWDwiso8tNMTNse)RNBGi=gVwgg% zbOg8>mbRN%7^Um-7oj4=6`$|(K7!+t^90a{$18Z>}<#!bm%ZEFQ{X(yBZMc>lCz0f1I2w9Sq zuGh<9<=AO&g6BZte6hn>Qmvv;Rt)*cJfTr2=~EnGD8P$v3R|&1RCl&7)b+`=QGapi zPbLg_pxm`+HZurtFZ;wZ=`Vk*do~$wB zxoW&=j0OTbQ=Q%S8XJ%~qoa3Ea|au5o}_(P;=!y-AjFrERh%8la!z6Fn@lR?^E~H12D?8#ht=1F;7@o4$Q8GDj;sSC%Jfn01xgL&%F2 zwG1|5ikb^qHv&9hT8w83+yv&BQXOQyMVJSBL(Ky~p)gU3#%|blG?IR9rP^zUbs7rOA0X52Ao=GRt@C&zlyjNLv-} z9?*x{y(`509qhCV*B47f2hLrGl^<@SuRGR!KwHei?!CM10Tq*YDIoBNyRuO*>3FU? zHjipIE#B~y3FSfOsMfj~F9PNr*H?0oHyYB^G(YyNh{SxcE(Y-`x5jFMKb~HO*m+R% zrq|ic4fzJ#USpTm;X7K+E%xsT_3VHKe?*uc4-FsILUH;kL>_okY(w`VU*8+l>o>Jm ziU#?2^`>arnsl#)*R&nf_%>A+qwl%o{l(u)M?DK1^mf260_oteV3#E_>6Y4!_hhVD zM8AI6MM2V*^_M^sQ0dmHu11fy^kOqXqzpr?K$`}BKWG`=Es(9&S@K@)ZjA{lj3ea7_MBP zk(|hBFRjHVMN!sNUkrB;(cTP)T97M$0Dtc&UXSec<+q?y>5=)}S~{Z@ua;1xt@=T5 zI7{`Z=z_X*no8s>mY;>BvEXK%b`a6(DTS6t&b!vf_z#HM{Uoy_5fiB(zpkF{})ruka$iX*~pq1ZxD?q68dIo zIZSVls9kFGsTwvr4{T_LidcWtt$u{kJlW7moRaH6+A5hW&;;2O#$oKyEN8kx`LmG)Wfq4ykh+q{I3|RfVpkR&QH_x;t41Uw z`P+tft^E2B$domKT@|nNW`EHwyj>&}K;eDpe z1bNOh=fvIfk`&B61+S8ND<(KC%>y&?>opCnY*r5M+!UrWKxv0_QvTlJc>X#AaI^xo zaRXL}t5Ej_Z$y*|w*$6D+A?Lw-CO-$itm^{2Ct82-<0IW)0KMNvJHgBrdsIR0v~=H z?n6^}l{D``Me90`^o|q!olsF?UX3YSq^6Vu>Ijm>>PaZI8G@<^NGw{Cx&%|PwYrfw zR!gX_%AR=L3BFsf8LxI|K^J}deh0ZdV?$3r--FEX`#INxsOG6_=!v)DI>0q|BxT)z z-G6kzA01M?rba+G_mwNMQD1mbVbNTWmBi*{s_v_Ft9m2Avg!^78(QFu&n6mbRJ2bA zv!b;%yo{g*9l2)>tsZJOOp}U~8VUH`}$ z8p_}t*XIOehezolNa-a2x0BS})Y9}&*TPgua{Ewn-=wVrmJUeU39EKx+%w%=ixQWK zDLpwaNJs65#6o7Ln7~~X+p_o2BR1g~VCfxLzxA{HlWAI6^H;`juI=&r1jQrUv_q0Z z1Ja-tjdktrrP>GOC*#p?*xfQU5MqjMsBe!9lh(u8)w$e@Z|>aUHI5o;MGw*|Myiz3 z-f0;pHg~Q#%*Kx8MxH%AluVXjG2C$)WL-K63@Q`#y9_k_+}eR(x4~dp7oV-ek0H>I zgy8p#i4GN{>#v=pFYUQT(g&b$OeTy-X_#FDgNF8XyfGY6R!>inYn8IR2RDa&O!(6< znXs{W!bkP|s_YI*Yx%4stI`=ZO45IK6rBs`g7sP40ic}GZ58s?Mc$&i`kq_tfci>N zIHrC0H+Qpam1bNa=(`SRKjixBTtm&e`j9porEci!zdlg1RI0Jw#b(_Tb@RQK1Zxr_ z%7SUeH6=TrXt3J@js`4iDD0=IoHhK~I7^W8^Rcp~Yaf>2wVe|Hh1bUpX9ATD#moByY57-f2Ef1TP^lBi&p5_s7WGG9|0T}dlfxOx zXvScJO1Cnq`c`~{Dp;{;l<-KkCDE+pmexJkd}zCgE{eF=)K``-qC~IT6GcRog_)!X z?fK^F8UDz$(zFUrwuR$qro5>qqn>+Z%<5>;_*3pZ8QM|yv9CAtrAx;($>4l^_$_-L z*&?(77!-=zvnCVW&kUcZMb6;2!83si518Y%R*A3JZ8Is|kUCMu`!vxDgaWjs7^0j( ziTaS4HhQ)ldR=r)_7vYFUr%THE}cPF{0H45FJ5MQW^+W>P+eEX2kLp3zzFe*-pFVA zdDZRybv?H|>`9f$AKVjFWJ=wegO7hOOIYCtd?Vj{EYLT*^gl35|HQ`R=ti+ADm{jyQE7K@kdjuqJhWVSks>b^ zxha88-h3s;%3_5b1TqFCPTxVjvuB5U>v=HyZ$?JSk+&I%)M7KE*wOg<)1-Iy)8-K! z^XpIt|0ibmk9RtMmlUd7#Ap3Q!q9N4atQy)TmrhrFhfx1DAN`^vq@Q_SRl|V z#lU<~n67$mT)NvHh`%als+G-)x1`Y%4Bp*6Un5Ri9h=_Db zA-AdP!f>f0m@~>7X#uBM?diI@)Egjuz@jXKvm zJo+==juc9_<;CqeRaU9_Mz@;3e=E4=6TK+c`|uu#pIqhSyNm`G(X)&)B`8q0RBv#> z`gGlw(Q=1Xmf55VHj%C#^1lpc>LY8kfA@|rlC1EA<1#`iuyNO z(=;irt{_&K=i4)^x%;U(Xv<)+o=dczC5H3W~+e|f~{*ucxj@{Yi-cw^MqYr3fN zF5D+~!wd$#al?UfMnz(@K#wn`_5na@rRr8XqN@&M&FGEC@`+OEv}sI1hw>Up0qAWf zL#e4~&oM;TVfjRE+10B_gFlLEP9?Q-dARr3xi6nQqnw>k-S;~b z;!0s2VS4}W8b&pGuK=7im+t(`nz@FnT#VD|!)eQNp-W6)@>aA+j~K*H{$G`y2|QHY z|Hmy+CR@#jWY4~)lr1qBJB_RfHJFfP<}pK5(#ZZGSqcpyS&}01LnTWk5fzmXMGHkJ zTP6L^B+uj;lmB_W<~4=${+v0>z31M!-_O@o-O9GyW)j_mjx}!0@br_LE-7SIuPP84 z;5=O(U*g_um0tyG|61N@d9lEuOeiRd+#NY^{nd5;-CVlw&Ap7J?qwM^?E29wvS}2d zbzar4Fz&RSR(-|s!Z6+za&Z zY#D<5q_JUktIzvL0)yq_kLWG6DO{ri=?c!y!f(Dk%G{8)k`Gym%j#!OgXVDD3;$&v@qy#ISJfp=Vm>pls@9-mapVQChAHHd-x+OGx)(*Yr zC1qDUTZ6mM(b_hi!TuFF2k#8uI2;kD70AQ&di$L*4P*Y-@p`jdm%_c3f)XhYD^6M8&#Y$ZpzQMcR|6nsH>b=*R_Von!$BTRj7yGCXokoAQ z&ANvx0-Epw`QIEPgI(^cS2f(Y85yV@ygI{ewyv5Frng)e}KCZF7JbR(&W618_dcEh(#+^zZFY;o<815<5sOHQdeax9_!PyM&;{P zkBa5xymca0#)c#tke@3KNEM8a_mT&1gm;p&&JlMGH(cL(b)BckgMQ^9&vRwj!~3@l zY?L5}=Jzr080OGKb|y`ee(+`flQg|!lo6>=H)X4`$Gz~hLmu2a%kYW_Uu8x09Pa0J zKZ`E$BKJ=2GPj_3l*TEcZ*uYRr<*J^#5pILTT;k_cgto1ZL-%slyc16J~OH-(RgDA z%;EjEnoUkZ&acS{Q8`{i6T5^nywgqQI5bDIymoa7CSZG|WWVk>GM9)zy*bNih|QIm z%0+(Nnc*a_xo;$=!HQYaapLms>J1ToyjtFByY`C2H1wT#178#4+|{H0BBqtCdd$L% z_3Hc60j@{t9~MjM@LBalR&6@>B;9?r<7J~F+WXyYu*y3?px*=8MAK@EA+jRX8{CG?GI-< z54?Dc9CAh>QTAvyOEm0^+x;r2BWX|{3$Y7)L5l*qVE*y0`7J>l2wCmW zL1?|a`pJ-l{fb_N;R(Z9UMiSj6pQjOvQ^%DvhIJF!+Th7jO2~1f1N+(-TyCFYQZYw z4)>7caf^Ki_KJ^Zx2JUb z&$3zJy!*+rCV4%jqwyuNY3j1ZEiltS0xTzd+=itTb;IPYpaf?8Y+RSdVdpacB(bVQ zC(JupLfFp8y43%PMj2}T|VS@%LVp>hv4Y!RPMF?pp8U_$xCJ)S zQx!69>bphNTIb9yn*_yfj{N%bY)t{L1cs8<8|!f$;UQ*}IN=2<6lA;x^(`8t?;+ST zh)z4qeYYgZkIy{$4x28O-pugO&gauRh3;lti9)9Pvw+^)0!h~%m&8Q!AKX%urEMnl z?yEz?g#ODn$UM`+Q#$Q!6|zsq_`dLO5YK-6bJM6ya>}H+vnW^h?o$z;V&wvuM$dR& zeEq;uUUh$XR`TWeC$$c&Jjau2it3#%J-y}Qm>nW*s?En?R&6w@sDXMEr#8~$=b(gk zwDC3)NtAP;M2BW_lL^5ShpK$D%@|BnD{=!Tq)o(5@z3i7Z){} zGr}Exom_qDO{kAVkZ*MbLNHE666Kina#D{&>Jy%~w7yX$oj;cYCd^p9zy z8*+wgSEcj$4{WxKmCF(5o7U4jqwEvO&dm1H#7z}%VXAbW&W24v-tS6N3}qrm1OnE)fUkoE8yMMn9S$?IswS88tQWm4#Oid#ckgr6 zRtHm!mfNl-`d>O*1~d7%;~n+{Rph6BBy^95zqI{K((E!iFQ+h*C3EsbxNo_aRm5gj zKYug($r*Q#W9`p%Bf{bi6;IY0v`pB^^qu)gbg9QHQ7 zWBj(a1YSu)~2RK8Pi#C>{DMlrqFb9e_RehEHyI{n?e3vL_}L>kYJC z_ly$$)zFi*SFyNrnOt(B*7E$??s67EO%DgoZL2XNk8iVx~X_)o++4oaK1M|ou73vA0K^503j@uuVmLcHH4ya-kOIDfM%5%(E z+Xpt~#7y2!KB&)PoyCA+$~DXqxPxxALy!g-O?<9+9KTk4Pgq4AIdUkl`1<1#j^cJg zgU3`0hkHj_jxV>`Y~%LAZl^3o0}`Sm@iw7kwff{M%VwtN)|~!p{AsfA6vB5UolF~d zHWS%*uBDt<9y!9v2Xe|au&1j&iR1HXCdyCjxSgG*L{wmTD4(NQ=mFjpa~xooc6kju z`~+d{j7$h-;HAB04H!Zscu^hZffL#9!p$)9>sRI|Yovm)g@F>ZnosF2EgkU3ln0bR zTA}|+E(tt)!SG)-bEJi_0m{l+(cAz^pi}`9=~n?y&;2eG;d9{M6nj>BHGn(KA2n|O zt}$=FPq!j`p&kQ8>cirSzkU0c08%8{^Qyqi-w2LoO8)^E7;;I1;HQ6B$u0nNaX2CY zSmfi)F`m94zL8>#zu;8|{aBui@RzRKBlP1&mfFxEC@%cjl?NBs`cr^nm){>;$g?rhKr$AO&6qV_Wbn^}5tfFBry^e1`%du2~o zs$~dN;S_#%iwwA_QvmMjh%Qo?0?rR~6liyN5Xmej8(*V9ym*T`xAhHih-v$7U}8=dfXi2i*aAB!xM(Xekg*ix@r|ymDw*{*s0?dlVys2e)z62u1 z+k3esbJE=-P5S$&KdFp+2H7_2e=}OKDrf( z9-207?6$@f4m4B+9E*e((Y89!q?zH|mz_vM>kp*HGXldO0Hg#!EtFhRuOm$u8e~a9 z5(roy7m$Kh+zjW6@zw{&20u?1f2uP&boD}$#Zy)4o&T;vyBoqFiF2t;*g=|1=)PxB z8eM3Mp=l_obbc?I^xyLz?4Y1YDWPa+nm;O<$Cn;@ane616`J9OO2r=rZr{I_Kizyc zP#^^WCdIEp*()rRT+*YZK>V@^Zs=ht32x>Kwe zab)@ZEffz;VM4{XA6e421^h~`ji5r%)B{wZu#hD}f3$y@L0JV9f3g{-RK!A?vBUA}${YF(vO4)@`6f1 z-A|}e#LN{)(eXloDnX4Vs7eH|<@{r#LodP@Nz--$Dg_Par%DCpu2>2jUnqy~|J?eZ zBG4FVsz_A+ibdwv>mLp>P!(t}E>$JGaK$R~;fb{O3($y1ssQQo|5M;^JqC?7qe|hg zu0ZOqeFcp?qVn&Qu7FQJ4hcFi&|nR!*j)MF#b}QO^lN%5)4p*D^H+B){n8%VPUzi! zDihoGcP71a6!ab`l^hK&*dYrVYzJ0)#}xVrp!e;lI!+x+bfCN0KXwUAPU9@#l7@0& QuEJmfE|#`Dqx|px0L@K;Y5)KL literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..a0f7639 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..c53aefa --- /dev/null +++ b/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..8ae1bcb --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,31 @@ + +rootProject.name = "factorio-web-map" + + +enableFeaturePreview("VERSION_CATALOGS") +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + +// repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + + repositories { + mavenCentral() + maven ("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") + maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") + } + + pluginManagement { + + repositories { + mavenCentral() + gradlePluginPortal() + maven { + url = uri("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") + } + } + + } + +} diff --git a/src/jsMain/kotlin/main.kt b/src/jsMain/kotlin/main.kt new file mode 100644 index 0000000..60460bd --- /dev/null +++ b/src/jsMain/kotlin/main.kt @@ -0,0 +1,8 @@ +fun main() { + println("Hello, Kotlin/JS!") +} + +//@JsModule("typed-factorio") +//@JsNonModule +////@JsModule +//external fun diff --git a/src/nativeMain/kotlin/Main.kt b/src/nativeMain/kotlin/Main.kt new file mode 100644 index 0000000..96a3690 --- /dev/null +++ b/src/nativeMain/kotlin/Main.kt @@ -0,0 +1,3 @@ +fun main() { + println("Hello, Kotlin/Native!") +} \ No newline at end of file diff --git a/src/nativeMain/kotlin/example/hello.kt b/src/nativeMain/kotlin/example/hello.kt new file mode 100644 index 0000000..73e1b99 --- /dev/null +++ b/src/nativeMain/kotlin/example/hello.kt @@ -0,0 +1,27 @@ +package example + +import org.luaj.vm2.LuaBoolean +import org.luaj.vm2.LuaValue + + +object Object { + val field = "A" +} + +class Clazz { + fun memberFunction(p: Int): ULong = 42UL +} + +fun forIntegers(b: Byte, s: Short, i: UInt, l: Long) {} +fun forFloats(f: Float, d: Double) {} + +fun strings(str: String): String { + return "That is '$str' from C" +} + +val globalString = "A global String" + +fun testingLuaBooleanElephant() { + val b: LuaBoolean = LuaValue.TRUE + println(b) +} From bf1b09bfa8ac5c0ba0a74b508709fbf1c2717182 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Thu, 7 Oct 2021 23:06:27 +0200 Subject: [PATCH 002/629] ts-> kotlin generated code compiles --- ...ompilerOptions.module_typescript-to-lua.kt | 26 +- .../LuaAST.module_typescript-to-lua.kt | 14 +- .../LuaPrinter.module_typescript-to-lua.kt | 2 +- externals02/lib.es2015.iterable.kt | 2 +- externals02/lib.es5.Intl.module_dukat.kt | 7 +- externals02/lib.scripthost.kt | 3 +- externals02/nonDeclarations.ts.kt | 61 +- .../report.module_typescript-to-lua.kt | 4 +- externals02/source-map.module_source-map.kt | 8 +- .../transpiler.module_typescript-to-lua.kt | 8 +- .../typescript.ts.module_typescript.kt | 1472 +++++++++-------- .../typescript.ts.server.module_typescript.kt | 4 +- 12 files changed, 863 insertions(+), 748 deletions(-) diff --git a/externals02/CompilerOptions.module_typescript-to-lua.kt b/externals02/CompilerOptions.module_typescript-to-lua.kt index aa83510..2c781b3 100644 --- a/externals02/CompilerOptions.module_typescript-to-lua.kt +++ b/externals02/CompilerOptions.module_typescript-to-lua.kt @@ -15,7 +15,7 @@ import org.w3c.workers.* import org.w3c.xhr.* import ts.Diagnostic -typealias OmitIndexSignature = Any +//typealias OmitIndexSignature = Any external interface TransformerImport { var transform: String @@ -31,10 +31,14 @@ external interface TransformerImport { var type: String? /* "program" | "config" | "checker" | "raw" | "compilerOptions" */ get() = definedExternally set(value) = definedExternally - @nativeGetter - operator fun get(option: String): Any? - @nativeSetter - operator fun set(option: String, value: Any) +} + +@Suppress("NOTHING_TO_INLINE") +inline operator fun TransformerImport.get(option: String): Any? = asDynamic()[option] + +@Suppress("NOTHING_TO_INLINE") +inline operator fun TransformerImport.set(option: String, value: Any) { + asDynamic()[option] = value } external interface LuaPluginImport { @@ -42,10 +46,14 @@ external interface LuaPluginImport { var import: String? get() = definedExternally set(value) = definedExternally - @nativeGetter - operator fun get(option: String): Any? - @nativeSetter - operator fun set(option: String, value: Any) +} + +@Suppress("NOTHING_TO_INLINE") +inline operator fun LuaPluginImport.get(option: String): Any? = asDynamic()[option] + +@Suppress("NOTHING_TO_INLINE") +inline operator fun LuaPluginImport.set(option: String, value: Any) { + asDynamic()[option] = value } external enum class LuaLibImportKind { diff --git a/externals02/LuaAST.module_typescript-to-lua.kt b/externals02/LuaAST.module_typescript-to-lua.kt index ee5baa7..35d07fb 100644 --- a/externals02/LuaAST.module_typescript-to-lua.kt +++ b/externals02/LuaAST.module_typescript-to-lua.kt @@ -395,9 +395,9 @@ external interface UnaryExpression : Expression { external fun isUnaryExpression(node: Node): Boolean -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind = definedExternally, tsOriginal: ts.Node = definedExternally): UnaryExpression +external fun createUnaryExpression(operand: Expression, operator: dynamic, tsOriginal: ts.Node = definedExternally): UnaryExpression -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind = definedExternally): UnaryExpression +external fun createUnaryExpression(operand: Expression, operator: dynamic): UnaryExpression external interface BinaryExpression : Expression { var operator: dynamic /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */ @@ -431,19 +431,19 @@ external fun isMethodCallExpression(node: Node): Boolean external fun createMethodCallExpression(prefixExpression: Expression, name: Identifier, params: Array, tsOriginal: ts.Node = definedExternally): MethodCallExpression external interface Identifier : Expression { - var exportable: Boolean + var exportable: Boolean? var text: String var originalName: String? get() = definedExternally set(value) = definedExternally - var symbolId: Number? /* Number? & `T$18`? */ + var symbolId: Number? /* Number? & `T$14`? */ get() = definedExternally set(value) = definedExternally } external fun isIdentifier(node: Node): Boolean -external fun createIdentifier(text: String, tsOriginal: ts.Node = definedExternally, symbolId: Number /* Number & `T$18` */ = definedExternally, originalName: String = definedExternally): Identifier +external fun createIdentifier(text: String, tsOriginal: ts.Node = definedExternally, symbolId: Number /* Number & `T$14` */ = definedExternally, originalName: String = definedExternally): Identifier external fun cloneIdentifier(identifier: Identifier, tsOriginal: ts.Node = definedExternally): Identifier @@ -464,10 +464,10 @@ external fun isFunctionDefinition(statement: VariableDeclarationStatement): Bool external fun isFunctionDefinition(statement: AssignmentStatement): Boolean -external interface `T$21` { +external interface `T$17` { var statements: dynamic /* JsTuple */ get() = definedExternally set(value) = definedExternally } -external fun isInlineFunctionExpression(expression: FunctionExpression): Boolean +external fun isInlineFunctionExpression(expression: FunctionExpression): Boolean \ No newline at end of file diff --git a/externals02/LuaPrinter.module_typescript-to-lua.kt b/externals02/LuaPrinter.module_typescript-to-lua.kt index 6428653..3a97a7d 100644 --- a/externals02/LuaPrinter.module_typescript-to-lua.kt +++ b/externals02/LuaPrinter.module_typescript-to-lua.kt @@ -29,7 +29,7 @@ external interface PrintResult { external fun createPrinter(printers: Array): Printer -external open class LuaPrinter(emitHost: EmitHost, program: Program, fileName: String) { +open external class LuaPrinter(emitHost: EmitHost, program: Program, fileName: String) { open var emitHost: Any open var currentIndent: Any open var sourceFile: Any diff --git a/externals02/lib.es2015.iterable.kt b/externals02/lib.es2015.iterable.kt index 039ac84..458df31 100644 --- a/externals02/lib.es2015.iterable.kt +++ b/externals02/lib.es2015.iterable.kt @@ -51,4 +51,4 @@ external interface PromiseConstructor { fun all(values: Iterable */>): Promise> fun race(values: Iterable): Promise fun race(values: Iterable */>): Promise -} +} \ No newline at end of file diff --git a/externals02/lib.es5.Intl.module_dukat.kt b/externals02/lib.es5.Intl.module_dukat.kt index 62cbcc7..456d347 100644 --- a/externals02/lib.es5.Intl.module_dukat.kt +++ b/externals02/lib.es5.Intl.module_dukat.kt @@ -1,6 +1,5 @@ @file:JsQualifier("tsstdlib.Intl") @file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib.Intl import kotlin.js.* import org.khronos.webgl.* @@ -41,10 +40,10 @@ external interface ResolvedCollatorOptions { var locale: String var usage: String var sensitivity: String - var ignorePunctuation: Boolean + var ignorePunctuation: Boolean? var collation: String var caseFirst: String - var numeric: Boolean + var numeric: Boolean? } @Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") @@ -111,7 +110,7 @@ external interface ResolvedNumberFormatOptions { var maximumSignificantDigits: Number? get() = definedExternally set(value) = definedExternally - var useGrouping: Boolean + var useGrouping: Boolean? } @Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") diff --git a/externals02/lib.scripthost.kt b/externals02/lib.scripthost.kt index 809347e..cd57d24 100644 --- a/externals02/lib.scripthost.kt +++ b/externals02/lib.scripthost.kt @@ -1,5 +1,4 @@ @file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib import kotlin.js.* import org.khronos.webgl.* @@ -15,6 +14,6 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external open class VarDate { +open external class VarDate { open var VarDate_typekey: VarDate } \ No newline at end of file diff --git a/externals02/nonDeclarations.ts.kt b/externals02/nonDeclarations.ts.kt index dbd777b..033a9db 100644 --- a/externals02/nonDeclarations.ts.kt +++ b/externals02/nonDeclarations.ts.kt @@ -14,6 +14,7 @@ import org.w3c.notifications.* import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* +import ts.* typealias SortedReadonlyArray = Array @@ -21,59 +22,59 @@ typealias SortedArray = Array typealias NodeArray = Array -typealias DotToken = PunctuationToken +typealias DotToken = PunctuationToken // SyntaxKind.DotToken -typealias DotDotDotToken = PunctuationToken +typealias DotDotDotToken = PunctuationToken // SyntaxKind.DotDotDotToken -typealias QuestionToken = PunctuationToken +typealias QuestionToken = PunctuationToken // SyntaxKind.QuestionToken -typealias ExclamationToken = PunctuationToken +typealias ExclamationToken = PunctuationToken // SyntaxKind.ExclamationToken -typealias ColonToken = PunctuationToken +typealias ColonToken = PunctuationToken // SyntaxKind.ColonToken -typealias EqualsToken = PunctuationToken +typealias EqualsToken = PunctuationToken // SyntaxKind.EqualsToken -typealias AsteriskToken = PunctuationToken +typealias AsteriskToken = PunctuationToken // SyntaxKind.AsteriskToken -typealias EqualsGreaterThanToken = PunctuationToken +typealias EqualsGreaterThanToken = PunctuationToken // SyntaxKind.EqualsGreaterThanToken -typealias PlusToken = PunctuationToken +typealias PlusToken = PunctuationToken // SyntaxKind.PlusToken -typealias MinusToken = PunctuationToken +typealias MinusToken = PunctuationToken // SyntaxKind.MinusToken -typealias QuestionDotToken = PunctuationToken +typealias QuestionDotToken = PunctuationToken // SyntaxKind.QuestionDotToken -typealias AssertsKeyword = KeywordToken +typealias AssertsKeyword = KeywordToken // SyntaxKind.AssertsKeyword -typealias AwaitKeyword = KeywordToken +typealias AwaitKeyword = KeywordToken // SyntaxKind.AwaitKeyword typealias AwaitKeywordToken = AwaitKeyword typealias AssertsToken = AssertsKeyword -typealias AbstractKeyword = ModifierToken +typealias AbstractKeyword = ModifierToken // SyntaxKind.AbstractKeyword -typealias AsyncKeyword = ModifierToken +typealias AsyncKeyword = ModifierToken // SyntaxKind.AsyncKeyword -typealias ConstKeyword = ModifierToken +typealias ConstKeyword = ModifierToken // SyntaxKind.ConstKeyword -typealias DeclareKeyword = ModifierToken +typealias DeclareKeyword = ModifierToken // SyntaxKind.DeclareKeyword -typealias DefaultKeyword = ModifierToken +typealias DefaultKeyword = ModifierToken // SyntaxKind.DefaultKeyword -typealias ExportKeyword = ModifierToken +typealias ExportKeyword = ModifierToken // SyntaxKind.ExportKeyword -typealias PrivateKeyword = ModifierToken +typealias PrivateKeyword = ModifierToken // SyntaxKind.PrivateKeyword -typealias ProtectedKeyword = ModifierToken +typealias ProtectedKeyword = ModifierToken // SyntaxKind.ProtectedKeyword -typealias PublicKeyword = ModifierToken +typealias PublicKeyword = ModifierToken // SyntaxKind.PublicKeyword -typealias ReadonlyKeyword = ModifierToken +typealias ReadonlyKeyword = ModifierToken // SyntaxKind.ReadonlyKeyword -typealias OverrideKeyword = ModifierToken +typealias OverrideKeyword = ModifierToken // SyntaxKind.OverrideKeyword -typealias StaticKeyword = ModifierToken +typealias StaticKeyword = ModifierToken // SyntaxKind.StaticKeyword typealias ReadonlyToken = ReadonlyKeyword @@ -109,14 +110,6 @@ typealias FileWatcherCallback = (fileName: String, eventKind: FileWatcherEventKi typealias DirectoryWatcherCallback = (fileName: String) -> Unit -typealias ErrorCallback = (message: DiagnosticMessage, length: Number) -> Unit - typealias DiagnosticReporter = (diagnostic: Diagnostic) -> Unit -typealias WatchStatusReporter = (diagnostic: Diagnostic, newLine: String, options: CompilerOptions, errorCount: Number) -> Unit - -typealias CreateProgram = (rootNames: Array?, options: CompilerOptions?, host: CompilerHost, oldProgram: T, configFileParsingDiagnostics: Array, projectReferences: Array?) -> T - -typealias ReportEmitErrorSummary = (errorCount: Number) -> Unit - -typealias CodeActionCommand = InstallPackageAction +typealias CodeActionCommand = InstallPackageAction \ No newline at end of file diff --git a/externals02/report.module_typescript-to-lua.kt b/externals02/report.module_typescript-to-lua.kt index 3d2ed5e..f1582a6 100644 --- a/externals02/report.module_typescript-to-lua.kt +++ b/externals02/report.module_typescript-to-lua.kt @@ -20,7 +20,7 @@ import ts.Diagnostic import ts.System import ts.DiagnosticReporter -external interface `T$17` { +external interface `T$13` { var code: Any var reportsUnnecessary: Any? get() = definedExternally @@ -43,6 +43,6 @@ external interface `T$17` { set(value) = definedExternally } -external var prepareDiagnosticForFormatting: (diagnostic: Diagnostic) -> `T$17` +external var prepareDiagnosticForFormatting: (diagnostic: Diagnostic) -> `T$13` external fun createDiagnosticReporter(pretty: Boolean, system: System = definedExternally): DiagnosticReporter \ No newline at end of file diff --git a/externals02/source-map.module_source-map.kt b/externals02/source-map.module_source-map.kt index 5961ecc..66b214e 100644 --- a/externals02/source-map.module_source-map.kt +++ b/externals02/source-map.module_source-map.kt @@ -104,8 +104,8 @@ external interface CodeWithSourceMap { external interface SourceMapConsumer { fun computeColumnSpans() - fun originalPositionFor(generatedPosition: Position /* Position & `T$23` */): NullableMappedPosition - fun generatedPositionFor(originalPosition: MappedPosition /* MappedPosition & `T$23` */): NullablePosition + fun originalPositionFor(generatedPosition: Position /* Position & `T$19` */): NullableMappedPosition + fun generatedPositionFor(originalPosition: MappedPosition /* MappedPosition & `T$19` */): NullablePosition fun allGeneratedPositionsFor(originalPosition: MappedPosition): Array fun hasContentsOfAllSources(): Boolean fun sourceContentFor(source: String, returnNullOnMissing: Boolean = definedExternally): String? @@ -145,7 +145,7 @@ external interface IndexedSourceMapConsumerConstructor { var prototype: IndexedSourceMapConsumer } -external open class SourceMapGenerator(startOfSourceMap: StartOfSourceMap = definedExternally) { +open external class SourceMapGenerator(startOfSourceMap: StartOfSourceMap = definedExternally) { open fun addMapping(mapping: Mapping) open fun setSourceContent(sourceFile: String, sourceContent: String) open fun applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile: String = definedExternally, sourceMapPath: String = definedExternally) @@ -157,7 +157,7 @@ external open class SourceMapGenerator(startOfSourceMap: StartOfSourceMap = defi } } -external open class SourceNode { +open external class SourceNode { open var children: Array open var sourceContents: Any open var line: Number diff --git a/externals02/transpiler.module_typescript-to-lua.kt b/externals02/transpiler.module_typescript-to-lua.kt index 227fec5..5edaf7c 100644 --- a/externals02/transpiler.module_typescript-to-lua.kt +++ b/externals02/transpiler.module_typescript-to-lua.kt @@ -30,18 +30,18 @@ external interface EmitOptions : TranspileOptions { } external interface EmitResult { - var emitSkipped: Boolean + var emitSkipped: Boolean? var diagnostics: Array } -external interface `T$24` { +external interface `T$20` { var emitPlan: Array } -external open class Transpiler(__0: TranspilerOptions = definedExternally) { +open external class Transpiler(__0: TranspilerOptions = definedExternally) { open var emitHost: EmitHost open fun emit(emitOptions: EmitOptions): EmitResult - open fun getEmitPlan(program: Program, diagnostics: Array, files: Array): `T$24` + open fun getEmitPlan(program: Program, diagnostics: Array, files: Array): `T$20` } external fun getEmitPath(file: String, program: Program): String diff --git a/externals02/typescript.ts.module_typescript.kt b/externals02/typescript.ts.module_typescript.kt index 6fd58a3..661aa23 100644 --- a/externals02/typescript.ts.module_typescript.kt +++ b/externals02/typescript.ts.module_typescript.kt @@ -1,7 +1,6 @@ @file:JsModule("typescript") @file:JsNonModule @file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - package ts import kotlin.js.* @@ -18,6 +17,8 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* +//@formatter:off + external var versionMajorMinor: Any external var version: String @@ -67,18 +68,6 @@ external interface Set : ReadonlySet, Collection { override fun delete(key: T): Boolean } -external interface `T$1` { - var value: T - var done: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$2` { - var value: Unit - var done: Boolean? -} - external interface Iterator { fun next(): dynamic /* `T$1` | `T$2` */ } @@ -87,10 +76,6 @@ external interface Push { fun push(vararg values: T) } -external interface `T$3` { - var __pathBrand: Any -} - external interface TextRange { var pos: Number var end: Number @@ -164,306 +149,311 @@ external enum class SyntaxKind { AtToken /* = 59 */, QuestionQuestionToken /* = 60 */, BacktickToken /* = 61 */, - EqualsToken /* = 62 */, - PlusEqualsToken /* = 63 */, - MinusEqualsToken /* = 64 */, - AsteriskEqualsToken /* = 65 */, - AsteriskAsteriskEqualsToken /* = 66 */, - SlashEqualsToken /* = 67 */, - PercentEqualsToken /* = 68 */, - LessThanLessThanEqualsToken /* = 69 */, - GreaterThanGreaterThanEqualsToken /* = 70 */, - GreaterThanGreaterThanGreaterThanEqualsToken /* = 71 */, - AmpersandEqualsToken /* = 72 */, - BarEqualsToken /* = 73 */, - BarBarEqualsToken /* = 74 */, - AmpersandAmpersandEqualsToken /* = 75 */, - QuestionQuestionEqualsToken /* = 76 */, - CaretEqualsToken /* = 77 */, - Identifier /* = 78 */, - PrivateIdentifier /* = 79 */, - BreakKeyword /* = 80 */, - CaseKeyword /* = 81 */, - CatchKeyword /* = 82 */, - ClassKeyword /* = 83 */, - ConstKeyword /* = 84 */, - ContinueKeyword /* = 85 */, - DebuggerKeyword /* = 86 */, - DefaultKeyword /* = 87 */, - DeleteKeyword /* = 88 */, - DoKeyword /* = 89 */, - ElseKeyword /* = 90 */, - EnumKeyword /* = 91 */, - ExportKeyword /* = 92 */, - ExtendsKeyword /* = 93 */, - FalseKeyword /* = 94 */, - FinallyKeyword /* = 95 */, - ForKeyword /* = 96 */, - FunctionKeyword /* = 97 */, - IfKeyword /* = 98 */, - ImportKeyword /* = 99 */, - InKeyword /* = 100 */, - InstanceOfKeyword /* = 101 */, - NewKeyword /* = 102 */, - NullKeyword /* = 103 */, - ReturnKeyword /* = 104 */, - SuperKeyword /* = 105 */, - SwitchKeyword /* = 106 */, - ThisKeyword /* = 107 */, - ThrowKeyword /* = 108 */, - TrueKeyword /* = 109 */, - TryKeyword /* = 110 */, - TypeOfKeyword /* = 111 */, - VarKeyword /* = 112 */, - VoidKeyword /* = 113 */, - WhileKeyword /* = 114 */, - WithKeyword /* = 115 */, - ImplementsKeyword /* = 116 */, - InterfaceKeyword /* = 117 */, - LetKeyword /* = 118 */, - PackageKeyword /* = 119 */, - PrivateKeyword /* = 120 */, - ProtectedKeyword /* = 121 */, - PublicKeyword /* = 122 */, - StaticKeyword /* = 123 */, - YieldKeyword /* = 124 */, - AbstractKeyword /* = 125 */, - AsKeyword /* = 126 */, - AssertsKeyword /* = 127 */, - AnyKeyword /* = 128 */, - AsyncKeyword /* = 129 */, - AwaitKeyword /* = 130 */, - BooleanKeyword /* = 131 */, - ConstructorKeyword /* = 132 */, - DeclareKeyword /* = 133 */, - GetKeyword /* = 134 */, - InferKeyword /* = 135 */, - IntrinsicKeyword /* = 136 */, - IsKeyword /* = 137 */, - KeyOfKeyword /* = 138 */, - ModuleKeyword /* = 139 */, - NamespaceKeyword /* = 140 */, - NeverKeyword /* = 141 */, - ReadonlyKeyword /* = 142 */, - RequireKeyword /* = 143 */, - NumberKeyword /* = 144 */, - ObjectKeyword /* = 145 */, - SetKeyword /* = 146 */, - StringKeyword /* = 147 */, - SymbolKeyword /* = 148 */, - TypeKeyword /* = 149 */, - UndefinedKeyword /* = 150 */, - UniqueKeyword /* = 151 */, - UnknownKeyword /* = 152 */, - FromKeyword /* = 153 */, - GlobalKeyword /* = 154 */, - BigIntKeyword /* = 155 */, - OverrideKeyword /* = 156 */, - OfKeyword /* = 157 */, - QualifiedName /* = 158 */, - ComputedPropertyName /* = 159 */, - TypeParameter /* = 160 */, - Parameter /* = 161 */, - Decorator /* = 162 */, - PropertySignature /* = 163 */, - PropertyDeclaration /* = 164 */, - MethodSignature /* = 165 */, - MethodDeclaration /* = 166 */, - Constructor /* = 167 */, - GetAccessor /* = 168 */, - SetAccessor /* = 169 */, - CallSignature /* = 170 */, - ConstructSignature /* = 171 */, - IndexSignature /* = 172 */, - TypePredicate /* = 173 */, - TypeReference /* = 174 */, - FunctionType /* = 175 */, - ConstructorType /* = 176 */, - TypeQuery /* = 177 */, - TypeLiteral /* = 178 */, - ArrayType /* = 179 */, - TupleType /* = 180 */, - OptionalType /* = 181 */, - RestType /* = 182 */, - UnionType /* = 183 */, - IntersectionType /* = 184 */, - ConditionalType /* = 185 */, - InferType /* = 186 */, - ParenthesizedType /* = 187 */, - ThisType /* = 188 */, - TypeOperator /* = 189 */, - IndexedAccessType /* = 190 */, - MappedType /* = 191 */, - LiteralType /* = 192 */, - NamedTupleMember /* = 193 */, - TemplateLiteralType /* = 194 */, - TemplateLiteralTypeSpan /* = 195 */, - ImportType /* = 196 */, - ObjectBindingPattern /* = 197 */, - ArrayBindingPattern /* = 198 */, - BindingElement /* = 199 */, - ArrayLiteralExpression /* = 200 */, - ObjectLiteralExpression /* = 201 */, - PropertyAccessExpression /* = 202 */, - ElementAccessExpression /* = 203 */, - CallExpression /* = 204 */, - NewExpression /* = 205 */, - TaggedTemplateExpression /* = 206 */, - TypeAssertionExpression /* = 207 */, - ParenthesizedExpression /* = 208 */, - FunctionExpression /* = 209 */, - ArrowFunction /* = 210 */, - DeleteExpression /* = 211 */, - TypeOfExpression /* = 212 */, - VoidExpression /* = 213 */, - AwaitExpression /* = 214 */, - PrefixUnaryExpression /* = 215 */, - PostfixUnaryExpression /* = 216 */, - BinaryExpression /* = 217 */, - ConditionalExpression /* = 218 */, - TemplateExpression /* = 219 */, - YieldExpression /* = 220 */, - SpreadElement /* = 221 */, - ClassExpression /* = 222 */, - OmittedExpression /* = 223 */, - ExpressionWithTypeArguments /* = 224 */, - AsExpression /* = 225 */, - NonNullExpression /* = 226 */, - MetaProperty /* = 227 */, - SyntheticExpression /* = 228 */, - TemplateSpan /* = 229 */, - SemicolonClassElement /* = 230 */, - Block /* = 231 */, - EmptyStatement /* = 232 */, - VariableStatement /* = 233 */, - ExpressionStatement /* = 234 */, - IfStatement /* = 235 */, - DoStatement /* = 236 */, - WhileStatement /* = 237 */, - ForStatement /* = 238 */, - ForInStatement /* = 239 */, - ForOfStatement /* = 240 */, - ContinueStatement /* = 241 */, - BreakStatement /* = 242 */, - ReturnStatement /* = 243 */, - WithStatement /* = 244 */, - SwitchStatement /* = 245 */, - LabeledStatement /* = 246 */, - ThrowStatement /* = 247 */, - TryStatement /* = 248 */, - DebuggerStatement /* = 249 */, - VariableDeclaration /* = 250 */, - VariableDeclarationList /* = 251 */, - FunctionDeclaration /* = 252 */, - ClassDeclaration /* = 253 */, - InterfaceDeclaration /* = 254 */, - TypeAliasDeclaration /* = 255 */, - EnumDeclaration /* = 256 */, - ModuleDeclaration /* = 257 */, - ModuleBlock /* = 258 */, - CaseBlock /* = 259 */, - NamespaceExportDeclaration /* = 260 */, - ImportEqualsDeclaration /* = 261 */, - ImportDeclaration /* = 262 */, - ImportClause /* = 263 */, - NamespaceImport /* = 264 */, - NamedImports /* = 265 */, - ImportSpecifier /* = 266 */, - ExportAssignment /* = 267 */, - ExportDeclaration /* = 268 */, - NamedExports /* = 269 */, - NamespaceExport /* = 270 */, - ExportSpecifier /* = 271 */, - MissingDeclaration /* = 272 */, - ExternalModuleReference /* = 273 */, - JsxElement /* = 274 */, - JsxSelfClosingElement /* = 275 */, - JsxOpeningElement /* = 276 */, - JsxClosingElement /* = 277 */, - JsxFragment /* = 278 */, - JsxOpeningFragment /* = 279 */, - JsxClosingFragment /* = 280 */, - JsxAttribute /* = 281 */, - JsxAttributes /* = 282 */, - JsxSpreadAttribute /* = 283 */, - JsxExpression /* = 284 */, - CaseClause /* = 285 */, - DefaultClause /* = 286 */, - HeritageClause /* = 287 */, - CatchClause /* = 288 */, - PropertyAssignment /* = 289 */, - ShorthandPropertyAssignment /* = 290 */, - SpreadAssignment /* = 291 */, - EnumMember /* = 292 */, - UnparsedPrologue /* = 293 */, - UnparsedPrepend /* = 294 */, - UnparsedText /* = 295 */, - UnparsedInternalText /* = 296 */, - UnparsedSyntheticReference /* = 297 */, - SourceFile /* = 298 */, - Bundle /* = 299 */, - UnparsedSource /* = 300 */, - InputFiles /* = 301 */, - JSDocTypeExpression /* = 302 */, - JSDocNameReference /* = 303 */, - JSDocAllType /* = 304 */, - JSDocUnknownType /* = 305 */, - JSDocNullableType /* = 306 */, - JSDocNonNullableType /* = 307 */, - JSDocOptionalType /* = 308 */, - JSDocFunctionType /* = 309 */, - JSDocVariadicType /* = 310 */, - JSDocNamepathType /* = 311 */, - JSDocComment /* = 312 */, - JSDocText /* = 313 */, - JSDocTypeLiteral /* = 314 */, - JSDocSignature /* = 315 */, - JSDocLink /* = 316 */, - JSDocTag /* = 317 */, - JSDocAugmentsTag /* = 318 */, - JSDocImplementsTag /* = 319 */, - JSDocAuthorTag /* = 320 */, - JSDocDeprecatedTag /* = 321 */, - JSDocClassTag /* = 322 */, - JSDocPublicTag /* = 323 */, - JSDocPrivateTag /* = 324 */, - JSDocProtectedTag /* = 325 */, - JSDocReadonlyTag /* = 326 */, - JSDocOverrideTag /* = 327 */, - JSDocCallbackTag /* = 328 */, - JSDocEnumTag /* = 329 */, - JSDocParameterTag /* = 330 */, - JSDocReturnTag /* = 331 */, - JSDocThisTag /* = 332 */, - JSDocTypeTag /* = 333 */, - JSDocTemplateTag /* = 334 */, - JSDocTypedefTag /* = 335 */, - JSDocSeeTag /* = 336 */, - JSDocPropertyTag /* = 337 */, - SyntaxList /* = 338 */, - NotEmittedStatement /* = 339 */, - PartiallyEmittedExpression /* = 340 */, - CommaListExpression /* = 341 */, - MergeDeclarationMarker /* = 342 */, - EndOfDeclarationMarker /* = 343 */, - SyntheticReferenceExpression /* = 344 */, - Count /* = 345 */, - FirstAssignment /* = 62 */, - LastAssignment /* = 77 */, - FirstCompoundAssignment /* = 63 */, - LastCompoundAssignment /* = 77 */, - FirstReservedWord /* = 80 */, - LastReservedWord /* = 115 */, - FirstKeyword /* = 80 */, - LastKeyword /* = 157 */, - FirstFutureReservedWord /* = 116 */, - LastFutureReservedWord /* = 124 */, - FirstTypeNode /* = 173 */, - LastTypeNode /* = 196 */, + HashToken /* = 62 */, + EqualsToken /* = 63 */, + PlusEqualsToken /* = 64 */, + MinusEqualsToken /* = 65 */, + AsteriskEqualsToken /* = 66 */, + AsteriskAsteriskEqualsToken /* = 67 */, + SlashEqualsToken /* = 68 */, + PercentEqualsToken /* = 69 */, + LessThanLessThanEqualsToken /* = 70 */, + GreaterThanGreaterThanEqualsToken /* = 71 */, + GreaterThanGreaterThanGreaterThanEqualsToken /* = 72 */, + AmpersandEqualsToken /* = 73 */, + BarEqualsToken /* = 74 */, + BarBarEqualsToken /* = 75 */, + AmpersandAmpersandEqualsToken /* = 76 */, + QuestionQuestionEqualsToken /* = 77 */, + CaretEqualsToken /* = 78 */, + Identifier /* = 79 */, + PrivateIdentifier /* = 80 */, + BreakKeyword /* = 81 */, + CaseKeyword /* = 82 */, + CatchKeyword /* = 83 */, + ClassKeyword /* = 84 */, + ConstKeyword /* = 85 */, + ContinueKeyword /* = 86 */, + DebuggerKeyword /* = 87 */, + DefaultKeyword /* = 88 */, + DeleteKeyword /* = 89 */, + DoKeyword /* = 90 */, + ElseKeyword /* = 91 */, + EnumKeyword /* = 92 */, + ExportKeyword /* = 93 */, + ExtendsKeyword /* = 94 */, + FalseKeyword /* = 95 */, + FinallyKeyword /* = 96 */, + ForKeyword /* = 97 */, + FunctionKeyword /* = 98 */, + IfKeyword /* = 99 */, + ImportKeyword /* = 100 */, + InKeyword /* = 101 */, + InstanceOfKeyword /* = 102 */, + NewKeyword /* = 103 */, + NullKeyword /* = 104 */, + ReturnKeyword /* = 105 */, + SuperKeyword /* = 106 */, + SwitchKeyword /* = 107 */, + ThisKeyword /* = 108 */, + ThrowKeyword /* = 109 */, + TrueKeyword /* = 110 */, + TryKeyword /* = 111 */, + TypeOfKeyword /* = 112 */, + VarKeyword /* = 113 */, + VoidKeyword /* = 114 */, + WhileKeyword /* = 115 */, + WithKeyword /* = 116 */, + ImplementsKeyword /* = 117 */, + InterfaceKeyword /* = 118 */, + LetKeyword /* = 119 */, + PackageKeyword /* = 120 */, + PrivateKeyword /* = 121 */, + ProtectedKeyword /* = 122 */, + PublicKeyword /* = 123 */, + StaticKeyword /* = 124 */, + YieldKeyword /* = 125 */, + AbstractKeyword /* = 126 */, + AsKeyword /* = 127 */, + AssertsKeyword /* = 128 */, + AnyKeyword /* = 129 */, + AsyncKeyword /* = 130 */, + AwaitKeyword /* = 131 */, + BooleanKeyword /* = 132 */, + ConstructorKeyword /* = 133 */, + DeclareKeyword /* = 134 */, + GetKeyword /* = 135 */, + InferKeyword /* = 136 */, + IntrinsicKeyword /* = 137 */, + IsKeyword /* = 138 */, + KeyOfKeyword /* = 139 */, + ModuleKeyword /* = 140 */, + NamespaceKeyword /* = 141 */, + NeverKeyword /* = 142 */, + ReadonlyKeyword /* = 143 */, + RequireKeyword /* = 144 */, + NumberKeyword /* = 145 */, + ObjectKeyword /* = 146 */, + SetKeyword /* = 147 */, + StringKeyword /* = 148 */, + SymbolKeyword /* = 149 */, + TypeKeyword /* = 150 */, + UndefinedKeyword /* = 151 */, + UniqueKeyword /* = 152 */, + UnknownKeyword /* = 153 */, + FromKeyword /* = 154 */, + GlobalKeyword /* = 155 */, + BigIntKeyword /* = 156 */, + OverrideKeyword /* = 157 */, + OfKeyword /* = 158 */, + QualifiedName /* = 159 */, + ComputedPropertyName /* = 160 */, + TypeParameter /* = 161 */, + Parameter /* = 162 */, + Decorator /* = 163 */, + PropertySignature /* = 164 */, + PropertyDeclaration /* = 165 */, + MethodSignature /* = 166 */, + MethodDeclaration /* = 167 */, + ClassStaticBlockDeclaration /* = 168 */, + Constructor /* = 169 */, + GetAccessor /* = 170 */, + SetAccessor /* = 171 */, + CallSignature /* = 172 */, + ConstructSignature /* = 173 */, + IndexSignature /* = 174 */, + TypePredicate /* = 175 */, + TypeReference /* = 176 */, + FunctionType /* = 177 */, + ConstructorType /* = 178 */, + TypeQuery /* = 179 */, + TypeLiteral /* = 180 */, + ArrayType /* = 181 */, + TupleType /* = 182 */, + OptionalType /* = 183 */, + RestType /* = 184 */, + UnionType /* = 185 */, + IntersectionType /* = 186 */, + ConditionalType /* = 187 */, + InferType /* = 188 */, + ParenthesizedType /* = 189 */, + ThisType /* = 190 */, + TypeOperator /* = 191 */, + IndexedAccessType /* = 192 */, + MappedType /* = 193 */, + LiteralType /* = 194 */, + NamedTupleMember /* = 195 */, + TemplateLiteralType /* = 196 */, + TemplateLiteralTypeSpan /* = 197 */, + ImportType /* = 198 */, + ObjectBindingPattern /* = 199 */, + ArrayBindingPattern /* = 200 */, + BindingElement /* = 201 */, + ArrayLiteralExpression /* = 202 */, + ObjectLiteralExpression /* = 203 */, + PropertyAccessExpression /* = 204 */, + ElementAccessExpression /* = 205 */, + CallExpression /* = 206 */, + NewExpression /* = 207 */, + TaggedTemplateExpression /* = 208 */, + TypeAssertionExpression /* = 209 */, + ParenthesizedExpression /* = 210 */, + FunctionExpression /* = 211 */, + ArrowFunction /* = 212 */, + DeleteExpression /* = 213 */, + TypeOfExpression /* = 214 */, + VoidExpression /* = 215 */, + AwaitExpression /* = 216 */, + PrefixUnaryExpression /* = 217 */, + PostfixUnaryExpression /* = 218 */, + BinaryExpression /* = 219 */, + ConditionalExpression /* = 220 */, + TemplateExpression /* = 221 */, + YieldExpression /* = 222 */, + SpreadElement /* = 223 */, + ClassExpression /* = 224 */, + OmittedExpression /* = 225 */, + ExpressionWithTypeArguments /* = 226 */, + AsExpression /* = 227 */, + NonNullExpression /* = 228 */, + MetaProperty /* = 229 */, + SyntheticExpression /* = 230 */, + TemplateSpan /* = 231 */, + SemicolonClassElement /* = 232 */, + Block /* = 233 */, + EmptyStatement /* = 234 */, + VariableStatement /* = 235 */, + ExpressionStatement /* = 236 */, + IfStatement /* = 237 */, + DoStatement /* = 238 */, + WhileStatement /* = 239 */, + ForStatement /* = 240 */, + ForInStatement /* = 241 */, + ForOfStatement /* = 242 */, + ContinueStatement /* = 243 */, + BreakStatement /* = 244 */, + ReturnStatement /* = 245 */, + WithStatement /* = 246 */, + SwitchStatement /* = 247 */, + LabeledStatement /* = 248 */, + ThrowStatement /* = 249 */, + TryStatement /* = 250 */, + DebuggerStatement /* = 251 */, + VariableDeclaration /* = 252 */, + VariableDeclarationList /* = 253 */, + FunctionDeclaration /* = 254 */, + ClassDeclaration /* = 255 */, + InterfaceDeclaration /* = 256 */, + TypeAliasDeclaration /* = 257 */, + EnumDeclaration /* = 258 */, + ModuleDeclaration /* = 259 */, + ModuleBlock /* = 260 */, + CaseBlock /* = 261 */, + NamespaceExportDeclaration /* = 262 */, + ImportEqualsDeclaration /* = 263 */, + ImportDeclaration /* = 264 */, + ImportClause /* = 265 */, + NamespaceImport /* = 266 */, + NamedImports /* = 267 */, + ImportSpecifier /* = 268 */, + ExportAssignment /* = 269 */, + ExportDeclaration /* = 270 */, + NamedExports /* = 271 */, + NamespaceExport /* = 272 */, + ExportSpecifier /* = 273 */, + MissingDeclaration /* = 274 */, + ExternalModuleReference /* = 275 */, + JsxElement /* = 276 */, + JsxSelfClosingElement /* = 277 */, + JsxOpeningElement /* = 278 */, + JsxClosingElement /* = 279 */, + JsxFragment /* = 280 */, + JsxOpeningFragment /* = 281 */, + JsxClosingFragment /* = 282 */, + JsxAttribute /* = 283 */, + JsxAttributes /* = 284 */, + JsxSpreadAttribute /* = 285 */, + JsxExpression /* = 286 */, + CaseClause /* = 287 */, + DefaultClause /* = 288 */, + HeritageClause /* = 289 */, + CatchClause /* = 290 */, + PropertyAssignment /* = 291 */, + ShorthandPropertyAssignment /* = 292 */, + SpreadAssignment /* = 293 */, + EnumMember /* = 294 */, + UnparsedPrologue /* = 295 */, + UnparsedPrepend /* = 296 */, + UnparsedText /* = 297 */, + UnparsedInternalText /* = 298 */, + UnparsedSyntheticReference /* = 299 */, + SourceFile /* = 300 */, + Bundle /* = 301 */, + UnparsedSource /* = 302 */, + InputFiles /* = 303 */, + JSDocTypeExpression /* = 304 */, + JSDocNameReference /* = 305 */, + JSDocMemberName /* = 306 */, + JSDocAllType /* = 307 */, + JSDocUnknownType /* = 308 */, + JSDocNullableType /* = 309 */, + JSDocNonNullableType /* = 310 */, + JSDocOptionalType /* = 311 */, + JSDocFunctionType /* = 312 */, + JSDocVariadicType /* = 313 */, + JSDocNamepathType /* = 314 */, + JSDocComment /* = 315 */, + JSDocText /* = 316 */, + JSDocTypeLiteral /* = 317 */, + JSDocSignature /* = 318 */, + JSDocLink /* = 319 */, + JSDocLinkCode /* = 320 */, + JSDocLinkPlain /* = 321 */, + JSDocTag /* = 322 */, + JSDocAugmentsTag /* = 323 */, + JSDocImplementsTag /* = 324 */, + JSDocAuthorTag /* = 325 */, + JSDocDeprecatedTag /* = 326 */, + JSDocClassTag /* = 327 */, + JSDocPublicTag /* = 328 */, + JSDocPrivateTag /* = 329 */, + JSDocProtectedTag /* = 330 */, + JSDocReadonlyTag /* = 331 */, + JSDocOverrideTag /* = 332 */, + JSDocCallbackTag /* = 333 */, + JSDocEnumTag /* = 334 */, + JSDocParameterTag /* = 335 */, + JSDocReturnTag /* = 336 */, + JSDocThisTag /* = 337 */, + JSDocTypeTag /* = 338 */, + JSDocTemplateTag /* = 339 */, + JSDocTypedefTag /* = 340 */, + JSDocSeeTag /* = 341 */, + JSDocPropertyTag /* = 342 */, + SyntaxList /* = 343 */, + NotEmittedStatement /* = 344 */, + PartiallyEmittedExpression /* = 345 */, + CommaListExpression /* = 346 */, + MergeDeclarationMarker /* = 347 */, + EndOfDeclarationMarker /* = 348 */, + SyntheticReferenceExpression /* = 349 */, + Count /* = 350 */, + FirstAssignment /* = 63 */, + LastAssignment /* = 78 */, + FirstCompoundAssignment /* = 64 */, + LastCompoundAssignment /* = 78 */, + FirstReservedWord /* = 81 */, + LastReservedWord /* = 116 */, + FirstKeyword /* = 81 */, + LastKeyword /* = 158 */, + FirstFutureReservedWord /* = 117 */, + LastFutureReservedWord /* = 125 */, + FirstTypeNode /* = 175 */, + LastTypeNode /* = 198 */, FirstPunctuation /* = 18 */, - LastPunctuation /* = 77 */, + LastPunctuation /* = 78 */, FirstToken /* = 0 */, - LastToken /* = 157 */, + LastToken /* = 158 */, FirstTriviaToken /* = 2 */, LastTriviaToken /* = 7 */, FirstLiteralToken /* = 8 */, @@ -471,14 +461,14 @@ external enum class SyntaxKind { FirstTemplateToken /* = 14 */, LastTemplateToken /* = 17 */, FirstBinaryOperator /* = 29 */, - LastBinaryOperator /* = 77 */, - FirstStatement /* = 233 */, - LastStatement /* = 249 */, - FirstNode /* = 158 */, - FirstJSDocNode /* = 302 */, - LastJSDocNode /* = 337 */, - FirstJSDocTagNode /* = 317 */, - LastJSDocTagNode /* = 337 */ + LastBinaryOperator /* = 78 */, + FirstStatement /* = 235 */, + LastStatement /* = 251 */, + FirstNode /* = 159 */, + FirstJSDocNode /* = 304 */, + LastJSDocNode /* = 342 */, + FirstJSDocTagNode /* = 322 */, + LastJSDocTagNode /* = 342 */ } external enum class NodeFlags { @@ -575,7 +565,7 @@ external interface Token : Node { override val kind: TKind } -external interface PunctuationToken : Token +external interface PunctuationToken : Token external interface KeywordToken : Token @@ -886,6 +876,12 @@ external interface IndexSignatureDeclaration : SignatureDeclarationBase, ClassEl get() = definedExternally } +external interface ClassStaticBlockDeclaration : ClassElement, JSDocContainer { + override val parent: dynamic /* ClassDeclaration | ClassExpression */ + get() = definedExternally + val body: Block +} + external interface TypeNode : Node { var _typeNodeBrand: Any } @@ -1789,10 +1785,16 @@ external interface JSDocTypeExpression : TypeNode { } external interface JSDocNameReference : Node { - val name: dynamic /* Identifier | QualifiedName */ + val name: dynamic /* Identifier | QualifiedName | JSDocMemberName */ get() = definedExternally } +external interface JSDocMemberName : Node { + val left: dynamic /* Identifier | QualifiedName | JSDocMemberName */ + get() = definedExternally + val right: Identifier +} + external interface JSDocType : TypeNode { var _jsDocTypeBrand: Any } @@ -1826,11 +1828,11 @@ external interface JSDocNamepathType : JSDocType { } external interface JSDoc : Node { - override val parent: dynamic /* ParameterDeclaration | CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | EmptyStatement | DebuggerStatement | Block | VariableStatement | ExpressionStatement | IfStatement | DoStatement | WhileStatement | ForStatement | ForInStatement | ForOfStatement | BreakStatement | ContinueStatement | ReturnStatement | WithStatement | SwitchStatement | LabeledStatement | ThrowStatement | TryStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | VariableDeclaration | PropertyDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | NamespaceExportDeclaration | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | Token & JSDocContainer */ + override val parent: dynamic /* ParameterDeclaration | CallSignatureDeclaration | ClassStaticBlockDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | EmptyStatement | DebuggerStatement | Block | VariableStatement | ExpressionStatement | IfStatement | DoStatement | WhileStatement | ForStatement | ForInStatement | ForOfStatement | BreakStatement | ContinueStatement | ReturnStatement | WithStatement | SwitchStatement | LabeledStatement | ThrowStatement | TryStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | VariableDeclaration | PropertyDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | NamespaceExportDeclaration | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | Token & JSDocContainer */ get() = definedExternally val tags: NodeArray? get() = definedExternally - val comment: dynamic /* String? | NodeArray? */ + val comment: dynamic /* String? | NodeArray? */ get() = definedExternally } @@ -1838,12 +1840,24 @@ external interface JSDocTag : Node { override val parent: dynamic /* JSDoc | JSDocTypeLiteral */ get() = definedExternally val tagName: Identifier - val comment: dynamic /* String? | NodeArray? */ + val comment: dynamic /* String? | NodeArray? */ get() = definedExternally } external interface JSDocLink : Node { - val name: dynamic /* Identifier? | QualifiedName? */ + val name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ + get() = definedExternally + var text: String +} + +external interface JSDocLinkCode : Node { + val name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ + get() = definedExternally + var text: String +} + +external interface JSDocLinkPlain : Node { + val name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ get() = definedExternally var text: String } @@ -1854,17 +1868,17 @@ external interface JSDocText : Node { external interface JSDocUnknownTag : JSDocTag -external interface `T$4` { +external interface `T$21` { val expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ get() = definedExternally } external interface JSDocAugmentsTag : JSDocTag { - val `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */ + val `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */ } external interface JSDocImplementsTag : JSDocTag { - val `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */ + val `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */ } external interface JSDocAuthorTag : JSDocTag @@ -2060,7 +2074,7 @@ external interface SourceFile : Declaration { fun getPositionOfLineAndCharacter(line: Number, character: Number): Number fun update(newText: String, textChangeRange: TextChangeRange): SourceFile val statements: NodeArray - val endOfFileToken: Token + val endOfFileToken: Token var fileName: String var text: String var amdDependencies: Array @@ -2188,24 +2202,13 @@ external interface ParseConfigHost { val trace: ((s: String) -> Unit)? } -external interface `T$5` { - var _isResolvedConfigFileName: Any -} - -external open class OperationCanceledException +open external class OperationCanceledException external interface CancellationToken { fun isCancellationRequested(): Boolean fun throwIfCancellationRequested() } -external interface `T$6` { - var assignable: Number - var identity: Number - var subtype: Number - var strictSubtype: Number -} - external interface Program : ScriptReferenceHost { override fun getCurrentDirectory(): String fun getRootFileNames(): Array @@ -2223,7 +2226,7 @@ external interface Program : ScriptReferenceHost { fun getSymbolCount(): Number fun getTypeCount(): Number fun getInstantiationCount(): Number - fun getRelationCacheSizes(): `T$6` +// fun getRelationCacheSizes(): `T$6` fun isSourceFileFromExternalLibrary(file: SourceFile): Boolean fun isSourceFileDefaultLibrary(file: SourceFile): Boolean fun getProjectReferences(): Array? @@ -2283,7 +2286,7 @@ external interface EmitResult { set(value) = definedExternally } -external interface `T$7` { +external interface `T$22` { var typeArguments: NodeArray? get() = definedExternally set(value) = definedExternally @@ -2296,6 +2299,7 @@ external interface TypeChecker { fun getPropertyOfType(type: Type, propertyName: String): Symbol? fun getPrivateIdentifierPropertyOfType(leftType: Type, name: String, location: Node): Symbol? fun getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo? + fun getIndexInfosOfType(type: Type): Array fun getSignaturesOfType(type: Type, kind: SignatureKind): Array fun getIndexTypeOfType(type: Type, kind: IndexKind): Type? fun getBaseTypes(type: InterfaceType): Array @@ -2307,7 +2311,7 @@ external interface TypeChecker { fun getTypeArguments(type: TypeReference): Array fun typeToTypeNode(type: Type, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeNode? fun signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ - fun indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): IndexSignatureDeclaration? + fun indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): IndexSignatureDeclaration? fun symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* Identifier? | QualifiedName? */ fun symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): Expression? fun symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): NodeArray? @@ -2401,6 +2405,7 @@ external interface TypeChecker { fun isValidPropertyAccess(node: QualifiedName, propertyName: String): Boolean fun isValidPropertyAccess(node: ImportTypeNode, propertyName: String): Boolean fun getAliasedSymbol(symbol: Symbol): Symbol + fun getImmediateAliasedSymbol(symbol: Symbol): Symbol? fun getExportsOfModule(moduleSymbol: Symbol): Array fun getJsxIntrinsicTagNamesAt(location: Node): Array fun isOptionalParameter(node: ParameterDeclaration): Boolean @@ -2626,10 +2631,6 @@ external enum class InternalSymbolName { This /* = "this" */ } -external interface `T$8` { - var __escapedIdentifier: Unit -} - external interface ReadonlyUnderscoreEscapedMap : ReadonlyESMap external interface UnderscoreEscapedMap : ESMap, ReadonlyUnderscoreEscapedMap @@ -2787,12 +2788,7 @@ external interface InterfaceTypeWithDeclaredMembers : InterfaceType { var declaredProperties: Array var declaredCallSignatures: Array var declaredConstructSignatures: Array - var declaredStringIndexInfo: IndexInfo? - get() = definedExternally - set(value) = definedExternally - var declaredNumberIndexInfo: IndexInfo? - get() = definedExternally - set(value) = definedExternally + var declaredIndexInfos: Array } external interface TypeReference : ObjectType { @@ -2948,6 +2944,7 @@ external enum class IndexKind { } external interface IndexInfo { + var keyType: Type var type: Type var isReadonly: Boolean? var declaration: IndexSignatureDeclaration? @@ -3143,6 +3140,9 @@ external interface CompilerOptions { var emitDecoratorMetadata: Boolean? get() = definedExternally set(value) = definedExternally + var exactOptionalPropertyTypes: Boolean? + get() = definedExternally + set(value) = definedExternally var experimentalDecorators: Boolean? get() = definedExternally set(value) = definedExternally @@ -3338,6 +3338,9 @@ external interface CompilerOptions { var traceResolution: Boolean? get() = definedExternally set(value) = definedExternally + var useUnknownInCatchVariables: Boolean? + get() = definedExternally + set(value) = definedExternally var resolveJsonModule: Boolean? get() = definedExternally set(value) = definedExternally @@ -3752,18 +3755,19 @@ external interface NodeFactory { fun createUniqueName(text: String, flags: GeneratedIdentifierFlags = definedExternally): Identifier fun getGeneratedNameForNode(node: Node?, flags: GeneratedIdentifierFlags = definedExternally): Identifier fun createPrivateIdentifier(text: String): PrivateIdentifier -// fun createToken(token: SyntaxKind = definedExternally): SuperExpression -// fun createToken(token: SyntaxKind = definedExternally): ThisExpression -// fun createToken(token: SyntaxKind = definedExternally): NullLiteral -// fun createToken(token: SyntaxKind = definedExternally): TrueLiteral -// fun createToken(token: SyntaxKind = definedExternally): FalseLiteral - fun createToken(token: TKind): dynamic /* Token */ + fun createToken(token: SyntaxKind): dynamic +// fun createToken(token: SyntaxKind.SuperKeyword): SuperExpression +// fun createToken(token: SyntaxKind.ThisKeyword): ThisExpression +// fun createToken(token: SyntaxKind.NullKeyword): NullLiteral +// fun createToken(token: SyntaxKind.TrueKeyword): TrueLiteral +// fun createToken(token: SyntaxKind.FalseKeyword): FalseLiteral + fun createToken(token: TKind): dynamic /* Token */ fun createSuper(): SuperExpression fun createThis(): ThisExpression fun createNull(): NullLiteral fun createTrue(): TrueLiteral fun createFalse(): FalseLiteral - fun createModifier(kind: T): ModifierToken + fun createModifier(kind: T): ModifierToken fun createModifiersFromModifierFlags(flags: ModifierFlags): Array fun createQualifiedName(left: Identifier, right: String): QualifiedName fun createQualifiedName(left: Identifier, right: Identifier): QualifiedName @@ -3813,50 +3817,60 @@ external interface NodeFactory { fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration - - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: SyntaxKind? = definedExternally, type: TypeNode?, initializer: Expression?): PropertyDeclaration - - fun createMethodSignature(modifiers: Array?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: dynamic, questionOrExclamationToken: dynamic?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: dynamic, questionOrExclamationToken: dynamic?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration +// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createMethodSignature(modifiers: Array?, name: dynamic, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature +// fun createMethodSignature(modifiers: Array?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature +// fun createMethodSignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature +// fun createMethodSignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature +// fun createMethodSignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature +// fun createMethodSignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature +// fun createMethodSignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: dynamic, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature +// fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature +// fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature +// fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature +// fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature +// fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration +// fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration +// fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration +// fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration +// fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration +// fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration +// fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration +// fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration +// fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration +// fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration +// fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration +// fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration fun createConstructorDeclaration(decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration fun updateConstructorDeclaration(node: ConstructorDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration @@ -3868,7 +3882,6 @@ external interface NodeFactory { fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, body: Block?): SetAccessorDeclaration fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration @@ -3880,22 +3893,19 @@ external interface NodeFactory { fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun createCallSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): CallSignatureDeclaration fun updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): CallSignatureDeclaration - fun createConstructSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): ConstructSignatureDeclaration fun updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): ConstructSignatureDeclaration - fun createIndexSignature(decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration fun updateIndexSignature(node: IndexSignatureDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration - fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan - fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan - fun createKeywordTypeNode(kind: TKind): KeywordTypeNode + fun createClassStaticBlockDeclaration(decorators: Array?, modifiers: Array?, body: Block): ClassStaticBlockDeclaration + fun updateClassStaticBlockDeclaration(node: ClassStaticBlockDeclaration, decorators: Array?, modifiers: Array?, body: Block): ClassStaticBlockDeclaration + fun createKeywordTypeNode(kind: TKind): KeywordTypeNode fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: String, type: TypeNode?): TypePredicateNode @@ -3953,15 +3963,33 @@ external interface NodeFactory { fun createParenthesizedType(type: TypeNode): ParenthesizedTypeNode fun updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode fun createThisTypeNode(): ThisTypeNode - fun createTypeOperatorNode(operator: SyntaxKind = definedExternally, type: TypeNode): TypeOperatorNode + fun createTypeOperatorNode(operator: SyntaxKind, type: TypeNode): dynamic +// fun createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword, type: TypeNode): TypeOperatorNode +// fun createTypeOperatorNode(operator: SyntaxKind.UniqueKeyword, type: TypeNode): TypeOperatorNode +// fun createTypeOperatorNode(operator: SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode fun updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode fun createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode fun updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode - - fun createMappedTypeNode(readonlyToken: SyntaxKind? = definedExternally, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: SyntaxKind? = definedExternally, type: TypeNode?): MappedTypeNode - - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: SyntaxKind? = definedExternally, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: SyntaxKind? = definedExternally, type: TypeNode?): MappedTypeNode - + fun createMappedTypeNode(readonlyToken: dynamic, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic, type: TypeNode?): MappedTypeNode +// fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode +// fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode +// fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode +// fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode +// fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode +// fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode +// fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode +// fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode +// fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: dynamic, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic, type: TypeNode?): MappedTypeNode +// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode +// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode +// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode +// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode +// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode +// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode +// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode +// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode +// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode fun createLiteralTypeNode(literal: NullLiteral): LiteralTypeNode fun createLiteralTypeNode(literal: TrueLiteral): LiteralTypeNode fun createLiteralTypeNode(literal: FalseLiteral): LiteralTypeNode @@ -4054,23 +4082,20 @@ external interface NodeFactory { fun updateVoidExpression(node: VoidExpression, expression: Expression): VoidExpression fun createAwaitExpression(expression: Expression): AwaitExpression fun updateAwaitExpression(node: AwaitExpression, expression: Expression): AwaitExpression - fun createPrefixUnaryExpression(operator: SyntaxKind = definedExternally, operand: Expression): PrefixUnaryExpression + fun createPrefixUnaryExpression(operator: SyntaxKind, operand: Expression): PrefixUnaryExpression +// fun createPrefixUnaryExpression(operator: SyntaxKind.PlusPlusToken, operand: Expression): PrefixUnaryExpression +// fun createPrefixUnaryExpression(operator: SyntaxKind.MinusMinusToken, operand: Expression): PrefixUnaryExpression +// fun createPrefixUnaryExpression(operator: SyntaxKind.PlusToken, operand: Expression): PrefixUnaryExpression +// fun createPrefixUnaryExpression(operator: SyntaxKind.MinusToken, operand: Expression): PrefixUnaryExpression +// fun createPrefixUnaryExpression(operator: SyntaxKind.TildeToken, operand: Expression): PrefixUnaryExpression +// fun createPrefixUnaryExpression(operator: SyntaxKind.ExclamationToken, operand: Expression): PrefixUnaryExpression fun updatePrefixUnaryExpression(node: PrefixUnaryExpression, operand: Expression): PrefixUnaryExpression - fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind = definedExternally): PostfixUnaryExpression + fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind): PostfixUnaryExpression +// fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind.PlusPlusToken): PostfixUnaryExpression +// fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind.MinusMinusToken): PostfixUnaryExpression fun updatePostfixUnaryExpression(node: PostfixUnaryExpression, operand: Expression): PostfixUnaryExpression - fun createBinaryExpression( - left: Expression, - operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, - right: Expression - ): BinaryExpression - - fun updateBinaryExpression( - node: BinaryExpression, - left: Expression, - operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, - right: Expression - ): BinaryExpression - + fun createBinaryExpression(left: Expression, operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression): BinaryExpression + fun updateBinaryExpression(node: BinaryExpression, left: Expression, operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression): BinaryExpression fun createConditionalExpression(condition: Expression, questionToken: QuestionToken?, whenTrue: Expression, colonToken: ColonToken?, whenFalse: Expression): ConditionalExpression fun updateConditionalExpression(node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression fun createTemplateExpression(head: TemplateHead, templateSpans: Array): TemplateExpression @@ -4110,7 +4135,9 @@ external interface NodeFactory { fun updateNonNullExpression(node: NonNullExpression, expression: Expression): NonNullExpression fun createNonNullChain(expression: Expression): NonNullChain fun updateNonNullChain(node: NonNullChain, expression: Expression): NonNullChain - fun createMetaProperty(keywordToken: SyntaxKind = definedExternally, name: Identifier): MetaProperty + fun createMetaProperty(keywordToken: SyntaxKind, name: Identifier): MetaProperty +// fun createMetaProperty(keywordToken: SyntaxKind.NewKeyword, name: Identifier): MetaProperty +// fun createMetaProperty(keywordToken: SyntaxKind.ImportKeyword, name: Identifier): MetaProperty fun updateMetaProperty(node: MetaProperty, name: Identifier): MetaProperty fun createTemplateSpan(expression: Expression, literal: TemplateMiddle): TemplateSpan fun createTemplateSpan(expression: Expression, literal: TemplateTail): TemplateSpan @@ -4290,176 +4317,198 @@ external interface NodeFactory { fun updateJSDocTypeExpression(node: JSDocTypeExpression, type: TypeNode): JSDocTypeExpression fun createJSDocNameReference(name: Identifier): JSDocNameReference fun createJSDocNameReference(name: QualifiedName): JSDocNameReference + fun createJSDocNameReference(name: JSDocMemberName): JSDocNameReference fun updateJSDocNameReference(node: JSDocNameReference, name: Identifier): JSDocNameReference fun updateJSDocNameReference(node: JSDocNameReference, name: QualifiedName): JSDocNameReference + fun updateJSDocNameReference(node: JSDocNameReference, name: JSDocMemberName): JSDocNameReference + fun createJSDocMemberName(left: Identifier, right: Identifier): JSDocMemberName + fun createJSDocMemberName(left: QualifiedName, right: Identifier): JSDocMemberName + fun createJSDocMemberName(left: JSDocMemberName, right: Identifier): JSDocMemberName + fun updateJSDocMemberName(node: JSDocMemberName, left: Identifier, right: Identifier): JSDocMemberName + fun updateJSDocMemberName(node: JSDocMemberName, left: QualifiedName, right: Identifier): JSDocMemberName + fun updateJSDocMemberName(node: JSDocMemberName, left: JSDocMemberName, right: Identifier): JSDocMemberName fun createJSDocLink(name: Identifier?, text: String): JSDocLink fun createJSDocLink(name: QualifiedName?, text: String): JSDocLink + fun createJSDocLink(name: JSDocMemberName?, text: String): JSDocLink fun updateJSDocLink(node: JSDocLink, name: Identifier?, text: String): JSDocLink fun updateJSDocLink(node: JSDocLink, name: QualifiedName?, text: String): JSDocLink + fun updateJSDocLink(node: JSDocLink, name: JSDocMemberName?, text: String): JSDocLink + fun createJSDocLinkCode(name: Identifier?, text: String): JSDocLinkCode + fun createJSDocLinkCode(name: QualifiedName?, text: String): JSDocLinkCode + fun createJSDocLinkCode(name: JSDocMemberName?, text: String): JSDocLinkCode + fun updateJSDocLinkCode(node: JSDocLinkCode, name: Identifier?, text: String): JSDocLinkCode + fun updateJSDocLinkCode(node: JSDocLinkCode, name: QualifiedName?, text: String): JSDocLinkCode + fun updateJSDocLinkCode(node: JSDocLinkCode, name: JSDocMemberName?, text: String): JSDocLinkCode + fun createJSDocLinkPlain(name: Identifier?, text: String): JSDocLinkPlain + fun createJSDocLinkPlain(name: QualifiedName?, text: String): JSDocLinkPlain + fun createJSDocLinkPlain(name: JSDocMemberName?, text: String): JSDocLinkPlain + fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: Identifier?, text: String): JSDocLinkPlain + fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: QualifiedName?, text: String): JSDocLinkPlain + fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: JSDocMemberName?, text: String): JSDocLinkPlain fun createJSDocTypeLiteral(jsDocPropertyTags: Array = definedExternally, isArrayType: Boolean = definedExternally): JSDocTypeLiteral fun updateJSDocTypeLiteral(node: JSDocTypeLiteral, jsDocPropertyTags: Array?, isArrayType: Boolean?): JSDocTypeLiteral fun createJSDocSignature(typeParameters: Array?, parameters: Array, type: JSDocReturnTag = definedExternally): JSDocSignature fun updateJSDocSignature(node: JSDocSignature, typeParameters: Array?, parameters: Array, type: JSDocReturnTag?): JSDocSignature fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String = definedExternally): JSDocTemplateTag fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array): JSDocTemplateTag - fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray = definedExternally): JSDocTemplateTag + fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray = definedExternally): JSDocTemplateTag fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String?): JSDocTemplateTag - fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray?): JSDocTemplateTag + fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray?): JSDocTemplateTag fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag fun createJSDocTypedefTag(tagName: Identifier?): JSDocTypedefTag fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocTypedefTag fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally): JSDocTypedefTag fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocParameterTag fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocParameterTag fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocPropertyTag fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocPropertyTag fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocTypeTag fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocTypeTag - fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocTypeTag + fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocTypeTag fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocTypeTag - fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocTypeTag + fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocTypeTag fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag - fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag + fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag - fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag + fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: String = definedExternally): JSDocReturnTag fun createJSDocReturnTag(tagName: Identifier?): JSDocReturnTag fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocReturnTag - fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: NodeArray = definedExternally): JSDocReturnTag + fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: NodeArray = definedExternally): JSDocReturnTag fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocReturnTag - fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocReturnTag + fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocReturnTag fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocThisTag fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocThisTag - fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocThisTag + fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocThisTag fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocThisTag - fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocThisTag + fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocThisTag fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocEnumTag fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocEnumTag - fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocEnumTag + fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocEnumTag fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocEnumTag - fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocEnumTag + fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocEnumTag fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocCallbackTag fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature): JSDocCallbackTag fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocCallbackTag fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: String?): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: NodeArray?): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: NodeArray?): JSDocCallbackTag fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocCallbackTag - fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: String = definedExternally): JSDocAugmentsTag - fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */): JSDocAugmentsTag - fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: NodeArray = definedExternally): JSDocAugmentsTag - fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: String?): JSDocAugmentsTag - fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: NodeArray?): JSDocAugmentsTag - fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: String = definedExternally): JSDocImplementsTag - fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */): JSDocImplementsTag - fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: NodeArray = definedExternally): JSDocImplementsTag - fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: String?): JSDocImplementsTag - fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: NodeArray?): JSDocImplementsTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocCallbackTag + fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String = definedExternally): JSDocAugmentsTag + fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */): JSDocAugmentsTag + fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray = definedExternally): JSDocAugmentsTag + fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String?): JSDocAugmentsTag + fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray?): JSDocAugmentsTag + fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String = definedExternally): JSDocImplementsTag + fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */): JSDocImplementsTag + fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray = definedExternally): JSDocImplementsTag + fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String?): JSDocImplementsTag + fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray?): JSDocImplementsTag fun createJSDocAuthorTag(tagName: Identifier?, comment: String = definedExternally): JSDocAuthorTag fun createJSDocAuthorTag(tagName: Identifier?): JSDocAuthorTag - fun createJSDocAuthorTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocAuthorTag + fun createJSDocAuthorTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocAuthorTag fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: String?): JSDocAuthorTag - fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: NodeArray?): JSDocAuthorTag + fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: NodeArray?): JSDocAuthorTag fun createJSDocClassTag(tagName: Identifier?, comment: String = definedExternally): JSDocClassTag fun createJSDocClassTag(tagName: Identifier?): JSDocClassTag - fun createJSDocClassTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocClassTag + fun createJSDocClassTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocClassTag fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: String?): JSDocClassTag - fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: NodeArray?): JSDocClassTag + fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: NodeArray?): JSDocClassTag fun createJSDocPublicTag(tagName: Identifier?, comment: String = definedExternally): JSDocPublicTag fun createJSDocPublicTag(tagName: Identifier?): JSDocPublicTag - fun createJSDocPublicTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPublicTag + fun createJSDocPublicTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPublicTag fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: String?): JSDocPublicTag - fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: NodeArray?): JSDocPublicTag + fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: NodeArray?): JSDocPublicTag fun createJSDocPrivateTag(tagName: Identifier?, comment: String = definedExternally): JSDocPrivateTag fun createJSDocPrivateTag(tagName: Identifier?): JSDocPrivateTag - fun createJSDocPrivateTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPrivateTag + fun createJSDocPrivateTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPrivateTag fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: String?): JSDocPrivateTag - fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: NodeArray?): JSDocPrivateTag + fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: NodeArray?): JSDocPrivateTag fun createJSDocProtectedTag(tagName: Identifier?, comment: String = definedExternally): JSDocProtectedTag fun createJSDocProtectedTag(tagName: Identifier?): JSDocProtectedTag - fun createJSDocProtectedTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocProtectedTag + fun createJSDocProtectedTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocProtectedTag fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: String?): JSDocProtectedTag - fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: NodeArray?): JSDocProtectedTag + fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: NodeArray?): JSDocProtectedTag fun createJSDocReadonlyTag(tagName: Identifier?, comment: String = definedExternally): JSDocReadonlyTag fun createJSDocReadonlyTag(tagName: Identifier?): JSDocReadonlyTag - fun createJSDocReadonlyTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocReadonlyTag + fun createJSDocReadonlyTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocReadonlyTag fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: String?): JSDocReadonlyTag - fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: NodeArray?): JSDocReadonlyTag + fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: NodeArray?): JSDocReadonlyTag fun createJSDocUnknownTag(tagName: Identifier, comment: String = definedExternally): JSDocUnknownTag fun createJSDocUnknownTag(tagName: Identifier): JSDocUnknownTag - fun createJSDocUnknownTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocUnknownTag + fun createJSDocUnknownTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocUnknownTag fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: String?): JSDocUnknownTag - fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: NodeArray?): JSDocUnknownTag + fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: NodeArray?): JSDocUnknownTag fun createJSDocDeprecatedTag(tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag fun createJSDocDeprecatedTag(tagName: Identifier): JSDocDeprecatedTag - fun createJSDocDeprecatedTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag + fun createJSDocDeprecatedTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier): JSDocDeprecatedTag - fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag + fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag fun createJSDocOverrideTag(tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag fun createJSDocOverrideTag(tagName: Identifier): JSDocOverrideTag - fun createJSDocOverrideTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag + fun createJSDocOverrideTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier): JSDocOverrideTag - fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag + fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag fun createJSDocText(text: String): JSDocText fun updateJSDocText(node: JSDocText, text: String): JSDocText fun createJSDocComment(comment: String? = definedExternally, tags: Array? = definedExternally): JSDoc fun createJSDocComment(): JSDoc fun createJSDocComment(comment: String? = definedExternally): JSDoc - fun createJSDocComment(comment: NodeArray? = definedExternally, tags: Array? = definedExternally): JSDoc - fun createJSDocComment(comment: NodeArray? = definedExternally): JSDoc + fun createJSDocComment(comment: NodeArray? = definedExternally, tags: Array? = definedExternally): JSDoc + fun createJSDocComment(comment: NodeArray? = definedExternally): JSDoc fun updateJSDocComment(node: JSDoc, comment: String?, tags: Array?): JSDoc - fun updateJSDocComment(node: JSDoc, comment: NodeArray?, tags: Array?): JSDoc + fun updateJSDocComment(node: JSDoc, comment: NodeArray?, tags: Array?): JSDoc fun createJsxElement(openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement fun updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement fun createJsxSelfClosingElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement @@ -4500,7 +4549,9 @@ external interface NodeFactory { fun updateCaseClause(node: CaseClause, expression: Expression, statements: Array): CaseClause fun createDefaultClause(statements: Array): DefaultClause fun updateDefaultClause(node: DefaultClause, statements: Array): DefaultClause - fun createHeritageClause(token: SyntaxKind = definedExternally, types: Array): HeritageClause + fun createHeritageClause(token: SyntaxKind, types: Array): HeritageClause +// fun createHeritageClause(token: SyntaxKind.ExtendsKeyword, types: Array): HeritageClause +// fun createHeritageClause(token: SyntaxKind.ImplementsKeyword, types: Array): HeritageClause fun updateHeritageClause(node: HeritageClause, types: Array): HeritageClause fun createCatchClause(variableDeclaration: String?, block: Block): CatchClause fun createCatchClause(variableDeclaration: VariableDeclaration?, block: Block): CatchClause @@ -4540,7 +4591,7 @@ external interface NodeFactory { fun updateEnumMember(node: EnumMember, name: NumericLiteral, initializer: Expression?): EnumMember fun updateEnumMember(node: EnumMember, name: ComputedPropertyName, initializer: Expression?): EnumMember fun updateEnumMember(node: EnumMember, name: PrivateIdentifier, initializer: Expression?): EnumMember - fun createSourceFile(statements: Array, endOfFileToken: Token /* Token & JSDocContainer */, flags: NodeFlags): SourceFile + fun createSourceFile(statements: Array, endOfFileToken: Token /* Token & JSDocContainer */, flags: NodeFlags): SourceFile fun updateSourceFile(node: SourceFile, statements: Array, isDeclarationFile: Boolean = definedExternally, referencedFiles: Array = definedExternally, typeReferences: Array = definedExternally, hasNoDefaultLib: Boolean = definedExternally, libReferences: Array = definedExternally): SourceFile fun createNotEmittedStatement(original: Node): NotEmittedStatement fun createPartiallyEmittedExpression(expression: Expression, original: Node = definedExternally): PartiallyEmittedExpression @@ -4621,7 +4672,6 @@ external interface TransformationResult { var diagnostics: Array? get() = definedExternally set(value) = definedExternally - fun substituteNode(hint: EmitHint, node: Node): Node fun emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) val isEmitNotificationEnabled: ((node: Node) -> Boolean)? @@ -4795,6 +4845,8 @@ external interface UserPreferences { get() = definedExternally val includeCompletionsWithInsertText: Boolean? get() = definedExternally + val allowIncompleteCompletions: Boolean? + get() = definedExternally val importModuleSpecifierPreference: String? /* "shortest" | "project-relative" | "relative" | "non-relative" */ get() = definedExternally val importModuleSpecifierEnding: String? /* "auto" | "minimal" | "index" | "js" */ @@ -4826,6 +4878,7 @@ external interface System { var useCaseSensitiveFileNames: Boolean? fun write(s: String) val writeOutputIsTTY: (() -> Boolean)? + val getWidthOfTerminal: (() -> Number)? fun readFile(path: String, encoding: String = definedExternally): String? val getFileSize: ((path: String) -> Number)? fun writeFile(path: String, data: String, writeByteOrderMark: Boolean = definedExternally) @@ -4885,14 +4938,16 @@ external interface Scanner { fun reScanJsxAttributeValue(): SyntaxKind fun reScanJsxToken(allowMultilineJsxText: Boolean = definedExternally): dynamic /* SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken */ fun reScanLessThanToken(): SyntaxKind + fun reScanHashToken(): SyntaxKind fun reScanQuestionToken(): SyntaxKind fun reScanInvalidIdentifier(): SyntaxKind fun scanJsxToken(): dynamic /* SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken */ - fun scanJsDocToken(): dynamic /* SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.Unknown | SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IntrinsicKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.OverrideKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword */ + fun scanJsDocToken(): dynamic /* SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.HashToken | SyntaxKind.Unknown | SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IntrinsicKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.OverrideKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword */ fun scan(): SyntaxKind fun getText(): String fun setText(text: String?, start: Number = definedExternally, length: Number = definedExternally) - fun setOnError(onError: ErrorCallback?) +// fun setOnError(onError: ErrorCallback?) // TODO why isn't ErrorCallback defined? + fun setOnError(onError: dynamic?) fun setScriptTarget(scriptTarget: ScriptTarget) fun setLanguageVariant(variant: LanguageVariant) fun setTextPos(textPos: Number) @@ -4937,7 +4992,7 @@ external fun isIdentifierStart(ch: Number, languageVersion: ScriptTarget?): Bool external fun isIdentifierPart(ch: Number, languageVersion: ScriptTarget?, identifierVariant: LanguageVariant = definedExternally): Boolean -external fun createScanner(languageVersion: ScriptTarget, skipTrivia: Boolean, languageVariant: LanguageVariant = definedExternally, textInitial: String = definedExternally, onError: ErrorCallback = definedExternally, start: Number = definedExternally, length: Number = definedExternally): Scanner +//external fun createScanner(languageVersion: ScriptTarget, skipTrivia: Boolean, languageVariant: LanguageVariant = definedExternally, textInitial: String = definedExternally, onError: ErrorCallback = definedExternally, start: Number = definedExternally, length: Number = definedExternally): Scanner external fun isExternalModuleNameRelative(moduleName: String): Boolean @@ -4983,7 +5038,7 @@ external fun collapseTextChangeRangesAcrossMultipleVersions(changes: Array = definedExternally) +external fun validateLocaleAndSetLanguage(locale: String, sys: `T$24`, errors: Push = definedExternally) external fun getOriginalNode(node: Node): Node @@ -5127,7 +5182,7 @@ external fun getTextOfJSDocComment(comment: String = definedExternally): String? external fun getTextOfJSDocComment(): String? -external fun getTextOfJSDocComment(comment: NodeArray = definedExternally): String? +external fun getTextOfJSDocComment(comment: NodeArray = definedExternally): String? external fun getEffectiveTypeParameterDeclarations(node: Any /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature */): Array @@ -5233,6 +5288,8 @@ external fun isObjectLiteralElement(node: Node): Boolean external fun isStringLiteralLike(node: Node): Boolean +external fun isJSDocLinkLike(node: Node): Boolean + external var factory: NodeFactory external fun createUnparsedSourceFile(text: String): UnparsedSource @@ -5273,13 +5330,23 @@ external fun getSyntheticLeadingComments(node: Node): Array? external fun setSyntheticLeadingComments(node: T, comments: Array?): T +external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind, text: String, hasTrailingNewLine: Boolean = definedExternally): T +external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind, text: String): T +//external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T +//external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String): T +//external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T +//external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String): T + external fun getSyntheticTrailingComments(node: Node): Array? external fun setSyntheticTrailingComments(node: T, comments: Array?): T -external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind = definedExternally, text: String, hasTrailingNewLine: Boolean = definedExternally): T - -external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind = definedExternally, text: String): T +external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind, text: String, hasTrailingNewLine: Boolean = definedExternally): T +external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind, text: String): T +//external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T +//external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String): T +//external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T +//external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String): T external fun moveSyntheticComments(node: T, original: Node): T @@ -5357,6 +5424,8 @@ external fun isMethodSignature(node: Node): Boolean external fun isMethodDeclaration(node: Node): Boolean +external fun isClassStaticBlockDeclaration(node: Node): Boolean + external fun isConstructorDeclaration(node: Node): Boolean external fun isGetAccessorDeclaration(node: Node): Boolean @@ -5627,8 +5696,14 @@ external fun isJSDocTypeExpression(node: Node): Boolean external fun isJSDocNameReference(node: Node): Boolean +external fun isJSDocMemberName(node: Node): Boolean + external fun isJSDocLink(node: Node): Boolean +external fun isJSDocLinkCode(node: Node): Boolean + +external fun isJSDocLinkPlain(node: Node): Boolean + external fun isJSDocAllType(node: Node): Boolean external fun isJSDocUnknownType(node: Node): Boolean @@ -5719,7 +5794,7 @@ external interface ParseConfigFileHost : ParseConfigHost, ConfigFileDiagnosticsR external fun getParsedCommandLineOfConfigFile(configFileName: String, optionsToExtend: CompilerOptions?, host: ParseConfigFileHost, extendedConfigCache: Map = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): ParsedCommandLine? -external interface `T$11` { +external interface `T$25` { var config: Any? get() = definedExternally set(value) = definedExternally @@ -5728,9 +5803,9 @@ external interface `T$11` { set(value) = definedExternally } -external fun readConfigFile(fileName: String, readFile: (path: String) -> String?): `T$11` +external fun readConfigFile(fileName: String, readFile: (path: String) -> String?): `T$25` -external fun parseConfigFileTextToJson(fileName: String, jsonText: String): `T$11` +external fun parseConfigFileTextToJson(fileName: String, jsonText: String): `T$25` external fun readJsonConfigFile(fileName: String, readFile: (path: String) -> String?): TsConfigSourceFile @@ -5761,19 +5836,19 @@ external interface ExtendedConfigCacheEntry { var extendedConfig: ParsedTsconfig? } -external interface `T$12` { +external interface `T$26` { var options: CompilerOptions var errors: Array } -external fun convertCompilerOptionsFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$12` +external fun convertCompilerOptionsFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$26` -external interface `T$13` { +external interface `T$27` { var options: TypeAcquisition var errors: Array } -external fun convertTypeAcquisitionFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$13` +external fun convertTypeAcquisitionFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$27` external fun getEffectiveTypeRoots(options: CompilerOptions, host: GetEffectiveTypeRootsHost): Array? @@ -5935,7 +6010,7 @@ external interface OutputFile { var text: String } -external interface `T$14` { +external interface `T$28` { var result: T var affected: dynamic /* SourceFile | Program */ get() = definedExternally @@ -5969,11 +6044,11 @@ external interface BuilderProgram { } external interface SemanticDiagnosticsBuilderProgram : BuilderProgram { - fun getSemanticDiagnosticsOfNextAffectedFile(cancellationToken: CancellationToken = definedExternally, ignoreSourceFile: (sourceFile: SourceFile) -> Boolean = definedExternally): `T$14`>? + fun getSemanticDiagnosticsOfNextAffectedFile(cancellationToken: CancellationToken = definedExternally, ignoreSourceFile: (sourceFile: SourceFile) -> Boolean = definedExternally): `T$28`>? } external interface EmitAndSemanticDiagnosticsBuilderProgram : SemanticDiagnosticsBuilderProgram { - fun emitNextAffectedFile(writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): `T$14`? + fun emitNextAffectedFile(writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): `T$28`? } external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): SemanticDiagnosticsBuilderProgram @@ -6046,9 +6121,9 @@ external interface IncrementalProgramOptions { var host: CompilerHost? get() = definedExternally set(value) = definedExternally - var createProgram: CreateProgram? - get() = definedExternally - set(value) = definedExternally +// var createProgram: CreateProgram? +// get() = definedExternally +// set(value) = definedExternally } external fun createIncrementalProgram(__0: IncrementalProgramOptions): T @@ -6061,56 +6136,56 @@ external interface WatchHost { val clearTimeout: ((timeoutId: Any) -> Unit)? } -external interface ProgramHost { - var createProgram: CreateProgram - fun useCaseSensitiveFileNames(): Boolean - fun getNewLine(): String - fun getCurrentDirectory(): String - fun getDefaultLibFileName(options: CompilerOptions): String - val getDefaultLibLocation: (() -> String)? - val createHash: ((data: String) -> String)? - fun fileExists(path: String): Boolean - fun readFile(path: String, encoding: String = definedExternally): String? - val directoryExists: ((path: String) -> Boolean)? - val getDirectories: ((path: String) -> Array)? - val readDirectory: ((path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array)? - val realpath: ((path: String) -> String)? - val trace: ((s: String) -> Unit)? - val getEnvironmentVariable: ((name: String) -> String?)? - val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? -} +//external interface ProgramHost { +// var createProgram: CreateProgram +// fun useCaseSensitiveFileNames(): Boolean +// fun getNewLine(): String +// fun getCurrentDirectory(): String +// fun getDefaultLibFileName(options: CompilerOptions): String +// val getDefaultLibLocation: (() -> String)? +// val createHash: ((data: String) -> String)? +// fun fileExists(path: String): Boolean +// fun readFile(path: String, encoding: String = definedExternally): String? +// val directoryExists: ((path: String) -> Boolean)? +// val getDirectories: ((path: String) -> Array)? +// val readDirectory: ((path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array)? +// val realpath: ((path: String) -> String)? +// val trace: ((s: String) -> Unit)? +// val getEnvironmentVariable: ((name: String) -> String?)? +// val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? +// val resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? +//} -external interface WatchCompilerHost : ProgramHost, WatchHost { - val useSourceOfProjectReferenceRedirect: (() -> Boolean)? - val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? - val afterProgramCreate: ((program: T) -> Unit)? -} +//external interface WatchCompilerHost : ProgramHost, WatchHost { +// val useSourceOfProjectReferenceRedirect: (() -> Boolean)? +// val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? +// val afterProgramCreate: ((program: T) -> Unit)? +//} -external interface WatchCompilerHostOfFilesAndCompilerOptions : WatchCompilerHost { - var rootFiles: Array - var options: CompilerOptions - var watchOptions: WatchOptions? - get() = definedExternally - set(value) = definedExternally - var projectReferences: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface WatchCompilerHostOfConfigFile : WatchCompilerHost, ConfigFileDiagnosticsReporter { - var configFileName: String - var optionsToExtend: CompilerOptions? - get() = definedExternally - set(value) = definedExternally - var watchOptionsToExtend: WatchOptions? - get() = definedExternally - set(value) = definedExternally - var extraFileExtensions: Array? - get() = definedExternally - set(value) = definedExternally - override var readDirectory: (path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array -} +//external interface WatchCompilerHostOfFilesAndCompilerOptions : WatchCompilerHost { +// var rootFiles: Array +// var options: CompilerOptions +// var watchOptions: WatchOptions? +// get() = definedExternally +// set(value) = definedExternally +// var projectReferences: Array? +// get() = definedExternally +// set(value) = definedExternally +//} +// +//external interface WatchCompilerHostOfConfigFile : WatchCompilerHost, ConfigFileDiagnosticsReporter { +// var configFileName: String +// var optionsToExtend: CompilerOptions? +// get() = definedExternally +// set(value) = definedExternally +// var watchOptionsToExtend: WatchOptions? +// get() = definedExternally +// set(value) = definedExternally +// var extraFileExtensions: Array? +// get() = definedExternally +// set(value) = definedExternally +// override var readDirectory: (path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array +//} external interface Watch { fun getProgram(): T @@ -6123,33 +6198,23 @@ external interface WatchOfFilesAndCompilerOptions : Watch { fun updateRootFileNames(fileNames: Array) } -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): WatchCompilerHostOfConfigFile +//external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): WatchCompilerHostOfConfigFile +//external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System): WatchCompilerHostOfConfigFile +//external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally): WatchCompilerHostOfConfigFile +//external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally): WatchCompilerHostOfConfigFile +//external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): WatchCompilerHostOfConfigFile +//external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally): WatchCompilerHostOfConfigFile +// +//external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, projectReferences: Array = definedExternally, watchOptions: WatchOptions = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions +//external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System): WatchCompilerHostOfFilesAndCompilerOptions +//external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions +//external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions +//external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions +//external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, projectReferences: Array = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, projectReferences: Array = definedExternally, watchOptions: WatchOptions = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, projectReferences: Array = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchProgram(host: WatchCompilerHostOfFilesAndCompilerOptions): WatchOfFilesAndCompilerOptions - -external fun createWatchProgram(host: WatchCompilerHostOfConfigFile): WatchOfConfigFile +//external fun createWatchProgram(host: WatchCompilerHostOfFilesAndCompilerOptions): WatchOfFilesAndCompilerOptions +// +//external fun createWatchProgram(host: WatchCompilerHostOfConfigFile): WatchOfConfigFile external interface BuildOptions { var dry: Boolean? @@ -6190,29 +6255,28 @@ external interface BuildOptions { operator fun set(option: String, value: Array?) } -external interface SolutionBuilderHostBase : ProgramHost { - val createDirectory: ((path: String) -> Unit)? - val writeFile: ((path: String, data: String, writeByteOrderMark: Boolean) -> Unit)? - var getCustomTransformers: ((project: String) -> CustomTransformers?)? - get() = definedExternally - set(value) = definedExternally +//external interface SolutionBuilderHostBase : ProgramHost { +// val createDirectory: ((path: String) -> Unit)? +// val writeFile: ((path: String, data: String, writeByteOrderMark: Boolean) -> Unit)? +// var getCustomTransformers: ((project: String) -> CustomTransformers?)? +// get() = definedExternally +// set(value) = definedExternally +// fun getModifiedTime(fileName: String): Date? +// fun setModifiedTime(fileName: String, date: Date) +// fun deleteFile(fileName: String) +// val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? +// var reportDiagnostic: DiagnosticReporter +// var reportSolutionBuilderStatus: DiagnosticReporter +// val afterProgramEmitAndDiagnostics: ((program: T) -> Unit)? +//} - fun getModifiedTime(fileName: String): Date? - fun setModifiedTime(fileName: String, date: Date) - fun deleteFile(fileName: String) - val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? - var reportDiagnostic: DiagnosticReporter - var reportSolutionBuilderStatus: DiagnosticReporter - val afterProgramEmitAndDiagnostics: ((program: T) -> Unit)? -} +//external interface SolutionBuilderHost : SolutionBuilderHostBase { +// var reportErrorSummary: ReportEmitErrorSummary? +// get() = definedExternally +// set(value) = definedExternally +//} -external interface SolutionBuilderHost : SolutionBuilderHostBase { - var reportErrorSummary: ReportEmitErrorSummary? - get() = definedExternally - set(value) = definedExternally -} - -external interface SolutionBuilderWithWatchHost : SolutionBuilderHostBase, WatchHost +//external interface SolutionBuilderWithWatchHost : SolutionBuilderHostBase, WatchHost external interface SolutionBuilder { fun build(project: String = definedExternally, cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, getCustomTransformers: (project: String) -> CustomTransformers = definedExternally): ExitStatus @@ -6224,13 +6288,13 @@ external interface SolutionBuilder { external fun createBuilderStatusReporter(system: System, pretty: Boolean = definedExternally): DiagnosticReporter -external fun createSolutionBuilderHost(system: System = definedExternally, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportSolutionBuilderStatus: DiagnosticReporter = definedExternally, reportErrorSummary: ReportEmitErrorSummary = definedExternally): SolutionBuilderHost +//external fun createSolutionBuilderHost(system: System = definedExternally, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportSolutionBuilderStatus: DiagnosticReporter = definedExternally, reportErrorSummary: ReportEmitErrorSummary = definedExternally): SolutionBuilderHost +// +//external fun createSolutionBuilderWithWatchHost(system: System = definedExternally, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportSolutionBuilderStatus: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): SolutionBuilderWithWatchHost +// +//external fun createSolutionBuilder(host: SolutionBuilderHost, rootNames: Array, defaultOptions: BuildOptions): SolutionBuilder -external fun createSolutionBuilderWithWatchHost(system: System = definedExternally, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportSolutionBuilderStatus: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): SolutionBuilderWithWatchHost - -external fun createSolutionBuilder(host: SolutionBuilderHost, rootNames: Array, defaultOptions: BuildOptions): SolutionBuilder - -external fun createSolutionBuilderWithWatch(host: SolutionBuilderWithWatchHost, rootNames: Array, defaultOptions: BuildOptions, baseWatchOptions: WatchOptions = definedExternally): SolutionBuilder +//external fun createSolutionBuilderWithWatch(host: SolutionBuilderWithWatchHost, rootNames: Array, defaultOptions: BuildOptions, baseWatchOptions: WatchOptions = definedExternally): SolutionBuilder external enum class InvalidatedProjectKind { Build /* = 0 */, @@ -6261,7 +6325,7 @@ external interface BuildInvalidedProject : InvalidatedProjec fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array fun getAllDependencies(sourceFile: SourceFile): Array fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getSemanticDiagnosticsOfNextAffectedFile(cancellationToken: CancellationToken = definedExternally, ignoreSourceFile: (sourceFile: SourceFile) -> Boolean = definedExternally): `T$14`>? + fun getSemanticDiagnosticsOfNextAffectedFile(cancellationToken: CancellationToken = definedExternally, ignoreSourceFile: (sourceFile: SourceFile) -> Boolean = definedExternally): `T$28`>? fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult? } @@ -6311,6 +6375,12 @@ external enum class LanguageServiceMode { Syntactic /* = 2 */ } +external interface IncompleteCompletionsCache { + fun get(): CompletionInfo? + fun set(response: CompletionInfo) + fun clear() +} + external interface LanguageServiceHost : GetEffectiveTypeRootsHost { fun getCompilationSettings(): CompilerOptions val getNewLine: (() -> String)? @@ -6344,12 +6414,6 @@ external interface LanguageServiceHost : GetEffectiveTypeRootsHost { val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? } -external interface `T$15` { - var metadata: Any? - get() = definedExternally - set(value) = definedExternally -} - external enum class SemanticClassificationFormat { Original /* = "original" */, TwentyTwenty /* = "2020" */ @@ -6367,7 +6431,7 @@ external interface LanguageService { fun getSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ fun getEncodedSyntacticClassifications(fileName: String, span: TextSpan): Classifications fun getEncodedSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat = definedExternally): Classifications - fun getCompletionsAtPosition(fileName: String, position: Number, options: GetCompletionsAtPositionOptions?): CompletionInfo /* CompletionInfo & `T$15` */ + fun getCompletionsAtPosition(fileName: String, position: Number, options: GetCompletionsAtPositionOptions?): CompletionInfo /* CompletionInfo & `T$12` */ fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeOptions?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeSettings?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? fun getCompletionEntrySymbol(fileName: String, position: Number, name: String, source: String?): Symbol? @@ -6393,6 +6457,7 @@ external interface LanguageService { fun prepareCallHierarchy(fileName: String, position: Number): dynamic /* CallHierarchyItem? | Array? */ fun provideCallHierarchyIncomingCalls(fileName: String, position: Number): Array fun provideCallHierarchyOutgoingCalls(fileName: String, position: Number): Array + fun provideInlayHints(fileName: String, span: TextSpan, preferences: UserPreferences?): Array fun getOutliningSpans(fileName: String): Array fun getTodoComments(fileName: String, descriptors: Array): Array fun getBraceMatchingAtPosition(fileName: String, position: Number): Array @@ -6451,10 +6516,19 @@ external interface OrganizeImportsArgs : CombinedCodeFixScope { set(value) = definedExternally } +external enum class CompletionTriggerKind { + Invoked /* = 1 */, + TriggerCharacter /* = 2 */, + TriggerForIncompleteCompletions /* = 3 */ +} + external interface GetCompletionsAtPositionOptions : UserPreferences { var triggerCharacter: String? /* "." | """ | "'" | "`" | "/" | "@" | "<" | "#" | " " */ get() = definedExternally set(value) = definedExternally + var triggerKind: CompletionTriggerKind? + get() = definedExternally + set(value) = definedExternally var includeExternalModuleExports: Boolean? get() = definedExternally set(value) = definedExternally @@ -6463,6 +6537,23 @@ external interface GetCompletionsAtPositionOptions : UserPreferences { set(value) = definedExternally } +external interface InlayHintsOptions : UserPreferences { + val includeInlayParameterNameHints: String? /* "none" | "literals" | "all" */ + get() = definedExternally + val includeInlayParameterNameHintsWhenArgumentMatchesName: Boolean? + get() = definedExternally + val includeInlayFunctionParameterTypeHints: Boolean? + get() = definedExternally + val includeInlayVariableTypeHints: Boolean? + get() = definedExternally + val includeInlayPropertyDeclarationTypeHints: Boolean? + get() = definedExternally + val includeInlayFunctionLikeReturnTypeHints: Boolean? + get() = definedExternally + val includeInlayEnumMemberValueHints: Boolean? + get() = definedExternally +} + external interface SignatureHelpItemsOptions { var triggerReason: dynamic /* SignatureHelpInvokedReason? | SignatureHelpCharacterTypedReason? | SignatureHelpRetriggeredReason? */ get() = definedExternally @@ -6553,6 +6644,24 @@ external interface CallHierarchyOutgoingCall { var fromSpans: Array } +external enum class InlayHintKind { + Type /* = "Type" */, + Parameter /* = "Parameter" */, + Enum /* = "Enum" */ +} + +external interface InlayHint { + var text: String + var position: Number + var kind: InlayHintKind + var whitespaceBefore: Boolean? + get() = definedExternally + set(value) = definedExternally + var whitespaceAfter: Boolean? + get() = definedExternally + set(value) = definedExternally +} + external interface TodoCommentDescriptor { var text: String var priority: Number @@ -7246,6 +7355,15 @@ external enum class ClassificationType { bigintLiteral /* = 25 */ } +external interface InlayHintsContext { + var file: SourceFile + var program: Program + var cancellationToken: CancellationToken + var host: LanguageServiceHost + var span: TextSpan + var preferences: InlayHintsOptions +} + external fun createClassifier(): Classifier external interface DocumentHighlights { @@ -7255,18 +7373,18 @@ external interface DocumentHighlights { external interface DocumentRegistry { fun acquireDocument(fileName: String, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile - fun acquireDocumentWithKey(fileName: String, path: String /* String & `T$3` */, compilationSettings: CompilerOptions, key: String /* String & `T$16` */, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile + fun acquireDocumentWithKey(fileName: String, path: String /* String & `T$3` */, compilationSettings: CompilerOptions, key: String /* String & `T$29` */, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile fun updateDocument(fileName: String, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile - fun updateDocumentWithKey(fileName: String, path: String /* String & `T$3` */, compilationSettings: CompilerOptions, key: String /* String & `T$16` */, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile - fun getKeyForCompilationSettings(settings: CompilerOptions): String /* String & `T$16` */ + fun updateDocumentWithKey(fileName: String, path: String /* String & `T$3` */, compilationSettings: CompilerOptions, key: String /* String & `T$29` */, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile + fun getKeyForCompilationSettings(settings: CompilerOptions): String /* String & `T$29` */ fun releaseDocument(fileName: String, compilationSettings: CompilerOptions) fun releaseDocument(fileName: String, compilationSettings: CompilerOptions, scriptKind: ScriptKind) - fun releaseDocumentWithKey(path: String /* String & `T$3` */, key: String /* String & `T$16` */) - fun releaseDocumentWithKey(path: String /* String & `T$3` */, key: String /* String & `T$16` */, scriptKind: ScriptKind) + fun releaseDocumentWithKey(path: String /* String & `T$3` */, key: String /* String & `T$29` */) + fun releaseDocumentWithKey(path: String /* String & `T$3` */, key: String /* String & `T$29` */, scriptKind: ScriptKind) fun reportStats(): String } -external interface `T$16` { +external interface `T$29` { var __bucketKey: Any } @@ -7506,7 +7624,7 @@ external var createIndexedAccessTypeNode: (objectType: TypeNode, indexType: Type external var updateIndexedAccessTypeNode: (node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) -> IndexedAccessTypeNode -//external var createMappedTypeNode: (readonlyToken: dynamic /* ReadonlyKeyword? | PlusToken? | MinusToken? */, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */, type: TypeNode?) -> MappedTypeNode +external var createMappedTypeNode: (readonlyToken: dynamic /* ReadonlyKeyword? | PlusToken? | MinusToken? */, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */, type: TypeNode?) -> MappedTypeNode external var updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: dynamic /* ReadonlyKeyword? | PlusToken? | MinusToken? */, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */, type: TypeNode?) -> MappedTypeNode @@ -7598,9 +7716,7 @@ external var createPostfix: (operand: Expression, operator: dynamic /* SyntaxKin external var updatePostfix: (node: PostfixUnaryExpression, operand: Expression) -> PostfixUnaryExpression -external var createBinary: ( - left: Expression, operator: dynamic /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression -) -> BinaryExpression +external var createBinary: (left: Expression, operator: dynamic /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression) -> BinaryExpression external var updateConditional: (node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression) -> ConditionalExpression @@ -7611,29 +7727,29 @@ external var updateTemplateExpression: (node: TemplateExpression, head: Template external object createTemplateHead { @nativeInvoke operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateHead - @nativeInvoke - operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateHead +// @nativeInvoke +// operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateHead } external object createTemplateMiddle { @nativeInvoke operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateMiddle - @nativeInvoke - operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateMiddle +// @nativeInvoke +// operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateMiddle } external object createTemplateTail { @nativeInvoke operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateTail - @nativeInvoke - operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateTail +// @nativeInvoke +// operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateTail } external object createNoSubstitutionTemplateLiteral { @nativeInvoke operator fun invoke(text: String, rawText: String? = definedExternally): NoSubstitutionTemplateLiteral - @nativeInvoke - operator fun invoke(text: String?, rawText: String): NoSubstitutionTemplateLiteral +// @nativeInvoke +// operator fun invoke(text: String?, rawText: String): NoSubstitutionTemplateLiteral } external var updateYield: (node: YieldExpression, asteriskToken: AsteriskToken?, expression: Expression?) -> YieldExpression @@ -7820,47 +7936,47 @@ external var updateExternalModuleReference: (node: ExternalModuleReference, expr external var createJSDocTypeExpression: (type: TypeNode) -> JSDocTypeExpression -external var createJSDocTypeTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocTypeTag +external var createJSDocTypeTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocTypeTag -external var createJSDocReturnTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: dynamic /* String? | NodeArray? */) -> JSDocReturnTag +external var createJSDocReturnTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: dynamic /* String? | NodeArray? */) -> JSDocReturnTag -external var createJSDocThisTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocThisTag +external var createJSDocThisTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocThisTag -external var createJSDocComment: (comment: dynamic /* String? | NodeArray? */, tags: Array?) -> JSDoc +external var createJSDocComment: (comment: dynamic /* String? | NodeArray? */, tags: Array?) -> JSDoc -external var createJSDocParameterTag: (tagName: Identifier?, name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean?, comment: dynamic /* String? | NodeArray? */) -> JSDocParameterTag +external var createJSDocParameterTag: (tagName: Identifier?, name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean?, comment: dynamic /* String? | NodeArray? */) -> JSDocParameterTag -external var createJSDocClassTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocClassTag +external var createJSDocClassTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocClassTag -external var createJSDocAugmentsTag: (tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: dynamic /* String? | NodeArray? */) -> JSDocAugmentsTag +external var createJSDocAugmentsTag: (tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: dynamic /* String? | NodeArray? */) -> JSDocAugmentsTag -external var createJSDocEnumTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocEnumTag +external var createJSDocEnumTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocEnumTag -external var createJSDocTemplateTag: (tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: dynamic /* String? | NodeArray? */) -> JSDocTemplateTag +external var createJSDocTemplateTag: (tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: dynamic /* String? | NodeArray? */) -> JSDocTemplateTag -external var createJSDocTypedefTag: (tagName: Identifier?, typeExpression: dynamic /* JSDocTypeLiteral? | JSDocTypeExpression? */, fullName: dynamic /* Identifier? | JSDocNamespaceDeclaration? */, comment: dynamic /* String? | NodeArray? */) -> JSDocTypedefTag +external var createJSDocTypedefTag: (tagName: Identifier?, typeExpression: dynamic /* JSDocTypeLiteral? | JSDocTypeExpression? */, fullName: dynamic /* Identifier? | JSDocNamespaceDeclaration? */, comment: dynamic /* String? | NodeArray? */) -> JSDocTypedefTag -external var createJSDocCallbackTag: (tagName: Identifier?, typeExpression: JSDocSignature, fullName: dynamic /* Identifier? | JSDocNamespaceDeclaration? */, comment: dynamic /* String? | NodeArray? */) -> JSDocCallbackTag +external var createJSDocCallbackTag: (tagName: Identifier?, typeExpression: JSDocSignature, fullName: dynamic /* Identifier? | JSDocNamespaceDeclaration? */, comment: dynamic /* String? | NodeArray? */) -> JSDocCallbackTag external var createJSDocSignature: (typeParameters: Array?, parameters: Array, type: JSDocReturnTag?) -> JSDocSignature -external var createJSDocPropertyTag: (tagName: Identifier?, name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean?, comment: dynamic /* String? | NodeArray? */) -> JSDocPropertyTag +external var createJSDocPropertyTag: (tagName: Identifier?, name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean?, comment: dynamic /* String? | NodeArray? */) -> JSDocPropertyTag external var createJSDocTypeLiteral: (jsDocPropertyTags: Array?, isArrayType: Boolean?) -> JSDocTypeLiteral -external var createJSDocImplementsTag: (tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: dynamic /* String? | NodeArray? */) -> JSDocImplementsTag +external var createJSDocImplementsTag: (tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: dynamic /* String? | NodeArray? */) -> JSDocImplementsTag -external var createJSDocAuthorTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocAuthorTag +external var createJSDocAuthorTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocAuthorTag -external var createJSDocPublicTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocPublicTag +external var createJSDocPublicTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocPublicTag -external var createJSDocPrivateTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocPrivateTag +external var createJSDocPrivateTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocPrivateTag -external var createJSDocProtectedTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocProtectedTag +external var createJSDocProtectedTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocProtectedTag -external var createJSDocReadonlyTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocReadonlyTag +external var createJSDocReadonlyTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocReadonlyTag -external var createJSDocTag: (tagName: Identifier, comment: dynamic /* String? | NodeArray? */) -> JSDocUnknownTag +external var createJSDocTag: (tagName: Identifier, comment: dynamic /* String? | NodeArray? */) -> JSDocUnknownTag external var createJsxElement: (openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement) -> JsxElement @@ -7997,14 +8113,14 @@ external var createTypePredicateNode: (parameterName: dynamic /* Identifier | Th external var updateTypePredicateNode: (node: TypePredicateNode, parameterName: dynamic /* Identifier | ThisTypeNode */, type: TypeNode) -> TypePredicateNode external object createLiteral { +// @nativeInvoke +// operator fun invoke(value: Any /* String | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier */): StringLiteral +// @nativeInvoke +// operator fun invoke(value: Any /* Number | PseudoBigInt */): NumericLiteral @nativeInvoke - operator fun invoke(value: Any /* String | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier */): StringLiteral - @nativeInvoke - operator fun invoke(value: Any /* Number | PseudoBigInt */): NumericLiteral - @nativeInvoke - operator fun invoke(value: Boolean): dynamic /* TrueLiteral | FalseLiteral */ - @nativeInvoke - operator fun invoke(value: Any /* String | Number | PseudoBigInt | Boolean */): PrimaryExpression + operator fun invoke(value: dynamic): dynamic /* TrueLiteral | FalseLiteral */ +// @nativeInvoke +// operator fun invoke(value: Any /* String | Number | PseudoBigInt | Boolean */): PrimaryExpression } external var createMethodSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?) -> MethodSignature diff --git a/externals02/typescript.ts.server.module_typescript.kt b/externals02/typescript.ts.server.module_typescript.kt index 5a84cb3..ae716a6 100644 --- a/externals02/typescript.ts.server.module_typescript.kt +++ b/externals02/typescript.ts.server.module_typescript.kt @@ -57,7 +57,7 @@ external interface InstallPackageRequest : TypingInstallerRequestWithProjectName external interface PackageInstalledResponse : ProjectResponse { override val kind: String /* "action::packageInstalled" */ - val success: Boolean + val success: Boolean? val message: String } @@ -89,7 +89,7 @@ external interface BeginInstallTypes : InstallTypes { external interface EndInstallTypes : InstallTypes { override val kind: String /* "event::endInstallTypes" */ - val installSuccess: Boolean + val installSuccess: Boolean? } external interface SetTypings : ProjectResponse { From cbae0aa1f66b789045862829517a63731844182e Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 9 Oct 2021 15:37:57 +0200 Subject: [PATCH 003/629] update git ignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index ff3921f..acd20e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ .idea +node_modules + # Created by https://www.toptal.com/developers/gitignore/api/windows,macos,linux,gradle,intellij,visualstudiocode,kotlin # Edit at https://www.toptal.com/developers/gitignore?templates=windows,macos,linux,gradle,intellij,visualstudiocode,kotlin From fea28b51beef2d25ff8383210ebfc9564b8675e8 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 9 Oct 2021 15:38:31 +0200 Subject: [PATCH 004/629] rm unused ts->kt generated files --- ...ompilerOptions.module_typescript-to-lua.kt | 74 - .../LuaAST.module_typescript-to-lua.kt | 485 -- .../LuaLib.module_typescript-to-lua.kt | 111 - .../LuaPrinter.module_typescript-to-lua.kt | 101 - .../context.module_typescript-to-lua.kt | 79 - externals03/index.module_typescript-to-lua.kt | 38 - externals03/lib.es2015.collection.kt | 49 - externals03/lib.es2015.iterable.kt | 54 - externals03/lib.es5.Intl.module_dukat.kt | 220 - externals03/lib.es5.kt | 69 - externals03/lib.scripthost.kt | 20 - externals03/nonDeclarations.ts.kt | 114 - ...tput-collector.module_typescript-to-lua.kt | 33 - externals03/parse.module_typescript-to-lua.kt | 25 - .../plugins.module_typescript-to-lua.kt | 24 - .../report.module_typescript-to-lua.kt | 48 - externals03/source-map.module_source-map.kt | 192 - .../transpile.module_typescript-to-lua.kt | 40 - .../transpiler.module_typescript-to-lua.kt | 55 - .../tsconfig.module_typescript-to-lua.kt | 18 - ...ipt.ts.ScriptSnapshot.module_typescript.kt | 20 - .../typescript.ts.module_typescript.kt | 5914 ----------------- externals03/utils.module_typescript-to-lua.kt | 46 - .../visitors.module_typescript-to-lua.kt | 38 - 24 files changed, 7867 deletions(-) delete mode 100644 externals03/CompilerOptions.module_typescript-to-lua.kt delete mode 100644 externals03/LuaAST.module_typescript-to-lua.kt delete mode 100644 externals03/LuaLib.module_typescript-to-lua.kt delete mode 100644 externals03/LuaPrinter.module_typescript-to-lua.kt delete mode 100644 externals03/context.module_typescript-to-lua.kt delete mode 100644 externals03/index.module_typescript-to-lua.kt delete mode 100644 externals03/lib.es2015.collection.kt delete mode 100644 externals03/lib.es2015.iterable.kt delete mode 100644 externals03/lib.es5.Intl.module_dukat.kt delete mode 100644 externals03/lib.es5.kt delete mode 100644 externals03/lib.scripthost.kt delete mode 100644 externals03/nonDeclarations.ts.kt delete mode 100644 externals03/output-collector.module_typescript-to-lua.kt delete mode 100644 externals03/parse.module_typescript-to-lua.kt delete mode 100644 externals03/plugins.module_typescript-to-lua.kt delete mode 100644 externals03/report.module_typescript-to-lua.kt delete mode 100644 externals03/source-map.module_source-map.kt delete mode 100644 externals03/transpile.module_typescript-to-lua.kt delete mode 100644 externals03/transpiler.module_typescript-to-lua.kt delete mode 100644 externals03/tsconfig.module_typescript-to-lua.kt delete mode 100644 externals03/typescript.ts.ScriptSnapshot.module_typescript.kt delete mode 100644 externals03/typescript.ts.module_typescript.kt delete mode 100644 externals03/utils.module_typescript-to-lua.kt delete mode 100644 externals03/visitors.module_typescript-to-lua.kt diff --git a/externals03/CompilerOptions.module_typescript-to-lua.kt b/externals03/CompilerOptions.module_typescript-to-lua.kt deleted file mode 100644 index aa83510..0000000 --- a/externals03/CompilerOptions.module_typescript-to-lua.kt +++ /dev/null @@ -1,74 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.Diagnostic - -typealias OmitIndexSignature = Any - -external interface TransformerImport { - var transform: String - var import: String? - get() = definedExternally - set(value) = definedExternally - var after: Boolean? - get() = definedExternally - set(value) = definedExternally - var afterDeclarations: Boolean? - get() = definedExternally - set(value) = definedExternally - var type: String? /* "program" | "config" | "checker" | "raw" | "compilerOptions" */ - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): Any? - @nativeSetter - operator fun set(option: String, value: Any) -} - -external interface LuaPluginImport { - var name: String - var import: String? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): Any? - @nativeSetter - operator fun set(option: String, value: Any) -} - -external enum class LuaLibImportKind { - None /* = "none" */, - Always /* = "always" */, - Inline /* = "inline" */, - Require /* = "require" */ -} - -external enum class LuaTarget { - Universal /* = "universal" */, - Lua51 /* = "5.1" */, - Lua52 /* = "5.2" */, - Lua53 /* = "5.3" */, - Lua54 /* = "5.4" */, - LuaJIT /* = "JIT" */ -} - -external enum class BuildMode { - Default /* = "default" */, - Library /* = "library" */ -} - -external var isBundleEnabled: (options: dynamic /* typealias OmitIndexSignature = dynamic */) -> Boolean - -external fun validateOptions(options: dynamic /* typealias OmitIndexSignature = dynamic */): Array \ No newline at end of file diff --git a/externals03/LuaAST.module_typescript-to-lua.kt b/externals03/LuaAST.module_typescript-to-lua.kt deleted file mode 100644 index 079e37f..0000000 --- a/externals03/LuaAST.module_typescript-to-lua.kt +++ /dev/null @@ -1,485 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import tsstdlib.Set - -external enum class SyntaxKind { - File /* = 0 */, - Block /* = 1 */, - DoStatement /* = 2 */, - VariableDeclarationStatement /* = 3 */, - AssignmentStatement /* = 4 */, - IfStatement /* = 5 */, - WhileStatement /* = 6 */, - RepeatStatement /* = 7 */, - ForStatement /* = 8 */, - ForInStatement /* = 9 */, - GotoStatement /* = 10 */, - LabelStatement /* = 11 */, - ReturnStatement /* = 12 */, - BreakStatement /* = 13 */, - ExpressionStatement /* = 14 */, - StringLiteral /* = 15 */, - NumericLiteral /* = 16 */, - NilKeyword /* = 17 */, - DotsKeyword /* = 18 */, - TrueKeyword /* = 19 */, - FalseKeyword /* = 20 */, - FunctionExpression /* = 21 */, - TableFieldExpression /* = 22 */, - TableExpression /* = 23 */, - UnaryExpression /* = 24 */, - BinaryExpression /* = 25 */, - CallExpression /* = 26 */, - MethodCallExpression /* = 27 */, - Identifier /* = 28 */, - TableIndexExpression /* = 29 */, - AdditionOperator /* = 30 */, - SubtractionOperator /* = 31 */, - MultiplicationOperator /* = 32 */, - DivisionOperator /* = 33 */, - FloorDivisionOperator /* = 34 */, - ModuloOperator /* = 35 */, - PowerOperator /* = 36 */, - NegationOperator /* = 37 */, - ConcatOperator /* = 38 */, - LengthOperator /* = 39 */, - EqualityOperator /* = 40 */, - InequalityOperator /* = 41 */, - LessThanOperator /* = 42 */, - LessEqualOperator /* = 43 */, - GreaterThanOperator /* = 44 */, - GreaterEqualOperator /* = 45 */, - AndOperator /* = 46 */, - OrOperator /* = 47 */, - NotOperator /* = 48 */, - BitwiseAndOperator /* = 49 */, - BitwiseOrOperator /* = 50 */, - BitwiseExclusiveOrOperator /* = 51 */, - BitwiseRightShiftOperator /* = 52 */, - BitwiseLeftShiftOperator /* = 53 */, - BitwiseNotOperator /* = 54 */ -} - -typealias UnaryBitwiseOperator = SyntaxKind.BitwiseNotOperator - -external interface TextRange { - var line: Number? - get() = definedExternally - set(value) = definedExternally - var column: Number? - get() = definedExternally - set(value) = definedExternally -} - -external interface Node : TextRange { - var kind: SyntaxKind -} - -external fun createNode(kind: SyntaxKind, tsOriginal: ts.Node = definedExternally): Node - -external fun cloneNode(node: T): T - -external fun setNodePosition(node: T, position: TextRange): T - -external fun setNodeOriginal(node: T, tsOriginal: ts.Node): T - -external fun setNodeOriginal(node: T?, tsOriginal: ts.Node): T? - -external fun getOriginalPos(node: Node): TextRange - -external interface File : Node { - var statements: Array - var luaLibFeatures: Set - var trivia: String -} - -external fun isFile(node: Node): Boolean - -external fun createFile(statements: Array, luaLibFeatures: Set, trivia: String, tsOriginal: ts.Node = definedExternally): File - -external interface Block : Node { - var statements: Array -} - -external fun isBlock(node: Node): Boolean - -external fun createBlock(statements: Array, tsOriginal: ts.Node = definedExternally): Block - -external interface Statement : Node { - var _statementBrand: Any - var leadingComments: Array */>? - get() = definedExternally - set(value) = definedExternally - var trailingComments: Array */>? - get() = definedExternally - set(value) = definedExternally -} - -external interface DoStatement : Statement { - var statements: Array -} - -external fun isDoStatement(node: Node): Boolean - -external fun createDoStatement(statements: Array, tsOriginal: ts.Node = definedExternally): DoStatement - -external interface VariableDeclarationStatement : Statement { - var left: Array - var right: Array? - get() = definedExternally - set(value) = definedExternally -} - -external fun isVariableDeclarationStatement(node: Node): Boolean - -external fun createVariableDeclarationStatement(left: Identifier, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Identifier): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Identifier, right: Expression = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Identifier, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Identifier, right: Array = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array, right: Expression = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array, right: Array = definedExternally): VariableDeclarationStatement - -external interface AssignmentStatement : Statement { - var left: Array - var right: Array -} - -external fun isAssignmentStatement(node: Node): Boolean - -external fun createAssignmentStatement(left: Identifier, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Identifier): AssignmentStatement - -external fun createAssignmentStatement(left: Identifier, right: Expression = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Identifier, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Identifier, right: Array = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression, right: Expression = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression, right: Array = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Array, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Array): AssignmentStatement - -external fun createAssignmentStatement(left: Array, right: Expression = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Array, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Array, right: Array = definedExternally): AssignmentStatement - -external interface IfStatement : Statement { - var condition: Expression - var ifBlock: Block - var elseBlock: dynamic /* Block? | IfStatement? */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isIfStatement(node: Node): Boolean - -external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: Block = definedExternally, tsOriginal: ts.Node = definedExternally): IfStatement - -external fun createIfStatement(condition: Expression, ifBlock: Block): IfStatement - -external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: Block = definedExternally): IfStatement - -external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: IfStatement = definedExternally, tsOriginal: ts.Node = definedExternally): IfStatement - -external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: IfStatement = definedExternally): IfStatement - -external interface IterationStatement : Statement { - var body: Block -} - -external fun isIterationStatement(node: Node): Boolean - -external interface WhileStatement : IterationStatement { - var condition: Expression -} - -external fun isWhileStatement(node: Node): Boolean - -external fun createWhileStatement(body: Block, condition: Expression, tsOriginal: ts.Node = definedExternally): WhileStatement - -external interface RepeatStatement : IterationStatement { - var condition: Expression -} - -external fun isRepeatStatement(node: Node): Boolean - -external fun createRepeatStatement(body: Block, condition: Expression, tsOriginal: ts.Node = definedExternally): RepeatStatement - -external interface ForStatement : IterationStatement { - var controlVariable: Identifier - var controlVariableInitializer: Expression - var limitExpression: Expression - var stepExpression: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external fun isForStatement(node: Node): Boolean - -external fun createForStatement(body: Block, controlVariable: Identifier, controlVariableInitializer: Expression, limitExpression: Expression, stepExpression: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): ForStatement - -external interface ForInStatement : IterationStatement { - var names: Array - var expressions: Array -} - -external fun isForInStatement(node: Node): Boolean - -external fun createForInStatement(body: Block, names: Array, expressions: Array, tsOriginal: ts.Node = definedExternally): ForInStatement - -external interface GotoStatement : Statement { - var label: String -} - -external fun isGotoStatement(node: Node): Boolean - -external fun createGotoStatement(label: String, tsOriginal: ts.Node = definedExternally): GotoStatement - -external interface LabelStatement : Statement { - var name: String -} - -external fun isLabelStatement(node: Node): Boolean - -external fun createLabelStatement(name: String, tsOriginal: ts.Node = definedExternally): LabelStatement - -external interface ReturnStatement : Statement { - var expressions: Array -} - -external fun isReturnStatement(node: Node): Boolean - -external fun createReturnStatement(expressions: Array, tsOriginal: ts.Node = definedExternally): ReturnStatement - -external interface BreakStatement : Statement - -external fun isBreakStatement(node: Node): Boolean - -external fun createBreakStatement(tsOriginal: ts.Node = definedExternally): BreakStatement - -external interface ExpressionStatement : Statement { - var expression: Expression -} - -external fun isExpressionStatement(node: Node): Boolean - -external fun createExpressionStatement(expressions: Expression, tsOriginal: ts.Node = definedExternally): ExpressionStatement - -external interface Expression : Node { - var _expressionBrand: Any -} - -external interface NilLiteral : Expression - -external fun isNilLiteral(node: Node): Boolean - -external fun createNilLiteral(tsOriginal: ts.Node = definedExternally): NilLiteral - -external interface BooleanLiteral : Expression { - override var kind: dynamic /* SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isBooleanLiteral(node: Node): Boolean - -external fun createBooleanLiteral(value: Boolean, tsOriginal: ts.Node = definedExternally): BooleanLiteral - -external interface DotsLiteral : Expression - -external fun isDotsLiteral(node: Node): Boolean - -external fun createDotsLiteral(tsOriginal: ts.Node = definedExternally): DotsLiteral - -external interface NumericLiteral : Expression { - var value: Number -} - -external fun isNumericLiteral(node: Node): Boolean - -external fun createNumericLiteral(value: Number, tsOriginal: ts.Node = definedExternally): NumericLiteral - -external interface StringLiteral : Expression { - var value: String -} - -external fun isStringLiteral(node: Node): Boolean - -external fun createStringLiteral(value: String, tsOriginal: ts.Node = definedExternally): StringLiteral - -external enum class FunctionExpressionFlags { - None /* = 1 */, - Inline /* = 2 */, - Declaration /* = 4 */ -} - -external interface FunctionExpression : Expression { - var params: Array? - get() = definedExternally - set(value) = definedExternally - var dots: DotsLiteral? - get() = definedExternally - set(value) = definedExternally - var body: Block - var flags: FunctionExpressionFlags -} - -external fun isFunctionExpression(node: Node): Boolean - -external fun createFunctionExpression(body: Block, params: Array = definedExternally, dots: DotsLiteral = definedExternally, flags: FunctionExpressionFlags = definedExternally, tsOriginal: ts.Node = definedExternally): FunctionExpression - -external interface TableFieldExpression : Expression { - var value: Expression - var key: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external fun isTableFieldExpression(node: Node): Boolean - -external fun createTableFieldExpression(value: Expression, key: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): TableFieldExpression - -external interface TableExpression : Expression { - var fields: Array -} - -external fun isTableExpression(node: Node): Boolean - -external fun createTableExpression(fields: Array = definedExternally, tsOriginal: ts.Node = definedExternally): TableExpression - -external interface UnaryExpression : Expression { - var operand: Expression - var operator: dynamic /* SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isUnaryExpression(node: Node): Boolean - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NegationOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NegationOperator): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.LengthOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.LengthOperator): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NotOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NotOperator): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: UnaryBitwiseOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: UnaryBitwiseOperator): UnaryExpression - -external interface BinaryExpression : Expression { - var operator: dynamic /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */ - get() = definedExternally - set(value) = definedExternally - var left: Expression - var right: Expression -} - -external fun isBinaryExpression(node: Node): Boolean - -external fun createBinaryExpression(left: Expression, right: Expression, operator: Any /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */, tsOriginal: ts.Node = definedExternally): BinaryExpression - -external interface CallExpression : Expression { - var expression: Expression - var params: Array -} - -external fun isCallExpression(node: Node): Boolean - -external fun createCallExpression(expression: Expression, params: Array, tsOriginal: ts.Node = definedExternally): CallExpression - -external interface MethodCallExpression : Expression { - var prefixExpression: Expression - var name: Identifier - var params: Array -} - -external fun isMethodCallExpression(node: Node): Boolean - -external fun createMethodCallExpression(prefixExpression: Expression, name: Identifier, params: Array, tsOriginal: ts.Node = definedExternally): MethodCallExpression - -external interface Identifier : Expression { - var exportable: Boolean - var text: String - var originalName: String? - get() = definedExternally - set(value) = definedExternally - var symbolId: Number? /* Number? & `T$14`? */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isIdentifier(node: Node): Boolean - -external fun createIdentifier(text: String, tsOriginal: ts.Node = definedExternally, symbolId: Number /* Number & `T$14` */ = definedExternally, originalName: String = definedExternally): Identifier - -external fun cloneIdentifier(identifier: Identifier, tsOriginal: ts.Node = definedExternally): Identifier - -external fun createAnonymousIdentifier(tsOriginal: ts.Node = definedExternally): Identifier - -external interface TableIndexExpression : Expression { - var table: Expression - var index: Expression -} - -external fun isTableIndexExpression(node: Node): Boolean - -external fun createTableIndexExpression(table: Expression, index: Expression, tsOriginal: ts.Node = definedExternally): TableIndexExpression - -external fun isAssignmentLeftHandSideExpression(node: Node): Boolean - -external fun isFunctionDefinition(statement: VariableDeclarationStatement): Boolean - -external fun isFunctionDefinition(statement: AssignmentStatement): Boolean - -external interface `T$17` { - var statements: dynamic /* JsTuple */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isInlineFunctionExpression(expression: FunctionExpression): Boolean \ No newline at end of file diff --git a/externals03/LuaLib.module_typescript-to-lua.kt b/externals03/LuaLib.module_typescript-to-lua.kt deleted file mode 100644 index f00c242..0000000 --- a/externals03/LuaLib.module_typescript-to-lua.kt +++ /dev/null @@ -1,111 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external enum class LuaLibFeature { - ArrayConcat /* = "ArrayConcat" */, - ArrayEntries /* = "ArrayEntries" */, - ArrayEvery /* = "ArrayEvery" */, - ArrayFilter /* = "ArrayFilter" */, - ArrayForEach /* = "ArrayForEach" */, - ArrayFind /* = "ArrayFind" */, - ArrayFindIndex /* = "ArrayFindIndex" */, - ArrayIncludes /* = "ArrayIncludes" */, - ArrayIndexOf /* = "ArrayIndexOf" */, - ArrayIsArray /* = "ArrayIsArray" */, - ArrayJoin /* = "ArrayJoin" */, - ArrayMap /* = "ArrayMap" */, - ArrayPush /* = "ArrayPush" */, - ArrayReduce /* = "ArrayReduce" */, - ArrayReduceRight /* = "ArrayReduceRight" */, - ArrayReverse /* = "ArrayReverse" */, - ArrayShift /* = "ArrayShift" */, - ArrayUnshift /* = "ArrayUnshift" */, - ArraySort /* = "ArraySort" */, - ArraySlice /* = "ArraySlice" */, - ArraySome /* = "ArraySome" */, - ArraySplice /* = "ArraySplice" */, - ArrayToObject /* = "ArrayToObject" */, - ArrayFlat /* = "ArrayFlat" */, - ArrayFlatMap /* = "ArrayFlatMap" */, - ArraySetLength /* = "ArraySetLength" */, - Await /* = "Await" */, - Class /* = "Class" */, - ClassExtends /* = "ClassExtends" */, - CloneDescriptor /* = "CloneDescriptor" */, - Decorate /* = "Decorate" */, - DecorateParam /* = "DecorateParam" */, - Delete /* = "Delete" */, - DelegatedYield /* = "DelegatedYield" */, - Error /* = "Error" */, - FunctionBind /* = "FunctionBind" */, - Generator /* = "Generator" */, - InstanceOf /* = "InstanceOf" */, - InstanceOfObject /* = "InstanceOfObject" */, - Iterator /* = "Iterator" */, - Map /* = "Map" */, - MathAtan2 /* = "MathAtan2" */, - New /* = "New" */, - Number /* = "Number" */, - NumberIsFinite /* = "NumberIsFinite" */, - NumberIsNaN /* = "NumberIsNaN" */, - NumberToString /* = "NumberToString" */, - ObjectAssign /* = "ObjectAssign" */, - ObjectDefineProperty /* = "ObjectDefineProperty" */, - ObjectEntries /* = "ObjectEntries" */, - ObjectFromEntries /* = "ObjectFromEntries" */, - ObjectGetOwnPropertyDescriptor /* = "ObjectGetOwnPropertyDescriptor" */, - ObjectGetOwnPropertyDescriptors /* = "ObjectGetOwnPropertyDescriptors" */, - ObjectKeys /* = "ObjectKeys" */, - ObjectRest /* = "ObjectRest" */, - ObjectValues /* = "ObjectValues" */, - OptionalChainAccess /* = "OptionalChainAccess" */, - OptionalFunctionCall /* = "OptionalFunctionCall" */, - OptionalMethodCall /* = "OptionalMethodCall" */, - ParseFloat /* = "ParseFloat" */, - ParseInt /* = "ParseInt" */, - Promise /* = "Promise" */, - PromiseAll /* = "PromiseAll" */, - PromiseAllSettled /* = "PromiseAllSettled" */, - PromiseAny /* = "PromiseAny" */, - PromiseRace /* = "PromiseRace" */, - Set /* = "Set" */, - SetDescriptor /* = "SetDescriptor" */, - WeakMap /* = "WeakMap" */, - WeakSet /* = "WeakSet" */, - SourceMapTraceBack /* = "SourceMapTraceBack" */, - Spread /* = "Spread" */, - StringAccess /* = "StringAccess" */, - StringCharAt /* = "StringCharAt" */, - StringCharCodeAt /* = "StringCharCodeAt" */, - StringConcat /* = "StringConcat" */, - StringEndsWith /* = "StringEndsWith" */, - StringIncludes /* = "StringIncludes" */, - StringPadEnd /* = "StringPadEnd" */, - StringPadStart /* = "StringPadStart" */, - StringReplace /* = "StringReplace" */, - StringSlice /* = "StringSlice" */, - StringSplit /* = "StringSplit" */, - StringStartsWith /* = "StringStartsWith" */, - StringSubstr /* = "StringSubstr" */, - StringSubstring /* = "StringSubstring" */, - StringTrim /* = "StringTrim" */, - StringTrimEnd /* = "StringTrimEnd" */, - StringTrimStart /* = "StringTrimStart" */, - Symbol /* = "Symbol" */, - SymbolRegistry /* = "SymbolRegistry" */, - TypeOf /* = "TypeOf" */, - Unpack /* = "Unpack" */ -} \ No newline at end of file diff --git a/externals03/LuaPrinter.module_typescript-to-lua.kt b/externals03/LuaPrinter.module_typescript-to-lua.kt deleted file mode 100644 index 6428653..0000000 --- a/externals03/LuaPrinter.module_typescript-to-lua.kt +++ /dev/null @@ -1,101 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.Program - -external var escapeString: (value: String) -> String - -external var tstlHeader: Any - -typealias Printer = (program: Program, emitHost: EmitHost, fileName: String, file: File) -> PrintResult - -external interface PrintResult { - var code: String - var sourceMap: String - var sourceMapNode: SourceNode -} - -external fun createPrinter(printers: Array): Printer - -external open class LuaPrinter(emitHost: EmitHost, program: Program, fileName: String) { - open var emitHost: Any - open var currentIndent: Any - open var sourceFile: Any - open var options: Any - open fun print(file: File): PrintResult - open var printInlineSourceMap: Any - open var printStackTraceOverride: Any - open var printFile: Any - open fun pushIndent() - open fun popIndent() - open fun indent(input: String = definedExternally): dynamic /* String | SourceNode */ - open fun indent(): dynamic /* String | SourceNode */ - open fun indent(input: SourceNode = definedExternally): dynamic /* String | SourceNode */ - open fun createSourceNode(node: Node, chunks: String, name: String = definedExternally): SourceNode - open fun createSourceNode(node: Node, chunks: String): SourceNode - open fun createSourceNode(node: Node, chunks: SourceNode, name: String = definedExternally): SourceNode - open fun createSourceNode(node: Node, chunks: SourceNode): SourceNode - open fun createSourceNode(node: Node, chunks: Array, name: String = definedExternally): SourceNode - open fun createSourceNode(node: Node, chunks: Array): SourceNode - open fun concatNodes(vararg chunks: Any /* String | SourceNode */): SourceNode - open fun printBlock(block: Block): SourceNode - open var statementMayRequireSemiColon: Any - open var nodeStartsWithParenthesis: Any - open fun printStatementArray(statements: Array): Array - open fun printStatement(statement: Statement): SourceNode - open fun printComment(comment: String): dynamic /* String | SourceNode */ - open fun printComment(comment: Array): dynamic /* String | SourceNode */ - open fun printStatementExcludingComments(statement: Statement): SourceNode - open fun printDoStatement(statement: DoStatement): SourceNode - open fun printVariableDeclarationStatement(statement: VariableDeclarationStatement): SourceNode - open fun printVariableAssignmentStatement(statement: AssignmentStatement): SourceNode - open fun printIfStatement(statement: IfStatement, isElseIf: Boolean = definedExternally): SourceNode - open fun printWhileStatement(statement: WhileStatement): SourceNode - open fun printRepeatStatement(statement: RepeatStatement): SourceNode - open fun printForStatement(statement: ForStatement): SourceNode - open fun printForInStatement(statement: ForInStatement): SourceNode - open fun printGotoStatement(statement: GotoStatement): SourceNode - open fun printLabelStatement(statement: LabelStatement): SourceNode - open fun printReturnStatement(statement: ReturnStatement): SourceNode - open fun printBreakStatement(statement: BreakStatement): SourceNode - open fun printExpressionStatement(statement: ExpressionStatement): SourceNode - open fun printExpression(expression: Expression): SourceNode - open fun printStringLiteral(expression: StringLiteral): SourceNode - open fun printNumericLiteral(expression: NumericLiteral): SourceNode - open fun printNilLiteral(expression: NilLiteral): SourceNode - open fun printDotsLiteral(expression: DotsLiteral): SourceNode - open fun printBooleanLiteral(expression: BooleanLiteral): SourceNode - open var printFunctionParameters: Any - open fun printFunctionExpression(expression: FunctionExpression): SourceNode - open fun printFunctionDefinition(statement: Any /* VariableDeclarationStatement | AssignmentStatement */): SourceNode - open fun printTableFieldExpression(expression: TableFieldExpression): SourceNode - open fun printTableExpression(expression: TableExpression): SourceNode - open fun printUnaryExpression(expression: UnaryExpression): SourceNode - open fun printBinaryExpression(expression: BinaryExpression): SourceNode - open var printExpressionInParenthesesIfNeeded: Any - open var needsParenthesis: Any - open fun printCallExpression(expression: CallExpression): SourceNode - open fun printMethodCallExpression(expression: MethodCallExpression): SourceNode - open fun printIdentifier(expression: Identifier): SourceNode - open fun printTableIndexExpression(expression: TableIndexExpression): SourceNode - open fun printOperator(kind: Any /* SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator | SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */): SourceNode - open fun joinChunksWithComma(chunks: Array): Array - open fun printExpressionList(expressions: Array): Array - open var buildSourceMap: Any - - companion object { - var operatorMap: Any - } -} \ No newline at end of file diff --git a/externals03/context.module_typescript-to-lua.kt b/externals03/context.module_typescript-to-lua.kt deleted file mode 100644 index 696e339..0000000 --- a/externals03/context.module_typescript-to-lua.kt +++ /dev/null @@ -1,79 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.GetAccessorDeclaration -import ts.SetAccessorDeclaration -import ts.Node -import ts.ImportEqualsDeclaration -import ts.Expression -import ts.SourceFile -import ts.CancellationToken -import ts.TypeChecker -import ts.Program -import ts.Diagnostic -import Node as _Node -import Expression as _Expression -import ts.QualifiedName -import ts.ExternalModuleReference - -external interface AllAccessorDeclarations { - var firstAccessor: dynamic /* GetAccessorDeclaration | SetAccessorDeclaration */ - get() = definedExternally - set(value) = definedExternally - var secondAccessor: dynamic /* GetAccessorDeclaration? | SetAccessorDeclaration? */ - get() = definedExternally - set(value) = definedExternally - var getAccessor: GetAccessorDeclaration? - var setAccessor: SetAccessorDeclaration? -} - -external interface EmitResolver { - fun isValueAliasDeclaration(node: Node): Boolean - fun isReferencedAliasDeclaration(node: Node, checkChildren: Boolean = definedExternally): Boolean - fun isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): Boolean - fun moduleExportsSomeValue(moduleReferenceExpression: Expression): Boolean - fun getAllAccessorDeclarations(declaration: GetAccessorDeclaration): AllAccessorDeclarations - fun getAllAccessorDeclarations(declaration: SetAccessorDeclaration): AllAccessorDeclarations -} - -external interface DiagnosticsProducingTypeChecker : TypeChecker { - fun getEmitResolver(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): EmitResolver -} - -external open class TransformationContext(program: Program, sourceFile: SourceFile, visitorMap: VisitorMap) { - open var program: Program - open var sourceFile: SourceFile - open var visitorMap: Any - open val diagnostics: Array - open val checker: DiagnosticsProducingTypeChecker - open val resolver: EmitResolver - open val options: dynamic /* typealias OmitIndexSignature = dynamic */ - open val luaTarget: LuaTarget - open val isModule: Boolean - open val isStrict: Boolean - open var currentNodeVisitors: Any - open fun transformNode(node: Node): Array<_Node> - open fun superTransformNode(node: Node): Array<_Node> - open fun transformExpression(node: Expression): _Expression - open fun transformExpression(node: QualifiedName): _Expression - open fun transformExpression(node: ExternalModuleReference): _Expression - open fun superTransformExpression(node: Expression): _Expression - open fun superTransformExpression(node: QualifiedName): _Expression - open fun superTransformExpression(node: ExternalModuleReference): _Expression - open fun transformStatements(node: StatementLikeNode): Array - open fun transformStatements(node: Array): Array - open fun superTransformStatements(node: StatementLikeNode): Array - open fun superTransformStatements(node: Array): Array -} \ No newline at end of file diff --git a/externals03/index.module_typescript-to-lua.kt b/externals03/index.module_typescript-to-lua.kt deleted file mode 100644 index 2016698..0000000 --- a/externals03/index.module_typescript-to-lua.kt +++ /dev/null @@ -1,38 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.WriteFileCallback -import ts.Diagnostic -import tsstdlib.Record - -external fun transpileFiles(rootNames: Array, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, writeFile: WriteFileCallback = definedExternally): EmitResult - -external fun transpileProject(configFileName: String, optionsToExtend: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, writeFile: WriteFileCallback = definedExternally): EmitResult - -external interface TranspileVirtualProjectResult { - var diagnostics: Array - var transpiledFiles: Array -} - -external fun transpileVirtualProject(files: Record, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally): TranspileVirtualProjectResult - -external interface TranspileStringResult { - var diagnostics: Array - var file: TranspiledFile? - get() = definedExternally - set(value) = definedExternally -} - -external fun transpileString(main: String, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally): TranspileStringResult \ No newline at end of file diff --git a/externals03/lib.es2015.collection.kt b/externals03/lib.es2015.collection.kt deleted file mode 100644 index affffa8..0000000 --- a/externals03/lib.es2015.collection.kt +++ /dev/null @@ -1,49 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface Map { - fun entries(): IterableIterator */> - fun keys(): IterableIterator - fun values(): IterableIterator - fun clear() - fun delete(key: K): Boolean - fun forEach(callbackfn: (value: V, key: K, map: Map) -> Unit, thisArg: Any = definedExternally) - fun get(key: K): V? - fun has(key: K): Boolean - fun set(key: K, value: V): Map /* this */ - val size: Number -} - -external interface MapConstructor { - val prototype: Map -} - -external interface Set { - fun entries(): IterableIterator */> - fun keys(): IterableIterator - fun values(): IterableIterator - fun add(value: T): Set /* this */ - fun clear() - fun delete(value: T): Boolean - fun forEach(callbackfn: (value: T, value2: T, set: Set) -> Unit, thisArg: Any = definedExternally) - fun has(value: T): Boolean - val size: Number -} - -external interface SetConstructor { - val prototype: Set -} \ No newline at end of file diff --git a/externals03/lib.es2015.iterable.kt b/externals03/lib.es2015.iterable.kt deleted file mode 100644 index 1528efa..0000000 --- a/externals03/lib.es2015.iterable.kt +++ /dev/null @@ -1,54 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface IteratorYieldResult { - var done: Boolean? - get() = definedExternally - set(value) = definedExternally - var value: TYield -} - -external interface IteratorReturnResult { - var done: Boolean - var value: TReturn -} - -external interface Iterator { - fun next(vararg args: Any /* JsTuple<> | JsTuple */): dynamic /* IteratorYieldResult | IteratorReturnResult */ - val `return`: ((value: TReturn) -> dynamic)? - val `throw`: ((e: Any) -> dynamic)? -} - -typealias Iterator__1 = Iterator - -external interface Iterable - -external interface IterableIterator : Iterator__1 - -external interface PromiseConstructor { - val prototype: Promise - fun all(values: Any /* JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple */): Promise | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple */> - fun all(values: Array */>): Promise> - fun race(values: Array): Promise - fun reject(reason: Any = definedExternally): Promise - fun resolve(value: T): Promise - fun resolve(value: PromiseLike): Promise - fun resolve(): Promise - fun all(values: Iterable */>): Promise> - fun race(values: Iterable): Promise - fun race(values: Iterable */>): Promise -} \ No newline at end of file diff --git a/externals03/lib.es5.Intl.module_dukat.kt b/externals03/lib.es5.Intl.module_dukat.kt deleted file mode 100644 index 62cbcc7..0000000 --- a/externals03/lib.es5.Intl.module_dukat.kt +++ /dev/null @@ -1,220 +0,0 @@ -@file:JsQualifier("tsstdlib.Intl") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib.Intl - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface CollatorOptions { - var usage: String? - get() = definedExternally - set(value) = definedExternally - var localeMatcher: String? - get() = definedExternally - set(value) = definedExternally - var numeric: Boolean? - get() = definedExternally - set(value) = definedExternally - var caseFirst: String? - get() = definedExternally - set(value) = definedExternally - var sensitivity: String? - get() = definedExternally - set(value) = definedExternally - var ignorePunctuation: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedCollatorOptions { - var locale: String - var usage: String - var sensitivity: String - var ignorePunctuation: Boolean - var collation: String - var caseFirst: String - var numeric: Boolean -} - -@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") -external interface Collator { - fun compare(x: String, y: String): Number - fun resolvedOptions(): ResolvedCollatorOptions - - companion object { - @nativeInvoke - operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: CollatorOptions = definedExternally): Collator - fun supportedLocalesOf(locales: Any /* String | Array */, options: CollatorOptions = definedExternally): Array - } -} - -external interface NumberFormatOptions { - var localeMatcher: String? - get() = definedExternally - set(value) = definedExternally - var style: String? - get() = definedExternally - set(value) = definedExternally - var currency: String? - get() = definedExternally - set(value) = definedExternally - var currencyDisplay: String? - get() = definedExternally - set(value) = definedExternally - var useGrouping: Boolean? - get() = definedExternally - set(value) = definedExternally - var minimumIntegerDigits: Number? - get() = definedExternally - set(value) = definedExternally - var minimumFractionDigits: Number? - get() = definedExternally - set(value) = definedExternally - var maximumFractionDigits: Number? - get() = definedExternally - set(value) = definedExternally - var minimumSignificantDigits: Number? - get() = definedExternally - set(value) = definedExternally - var maximumSignificantDigits: Number? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedNumberFormatOptions { - var locale: String - var numberingSystem: String - var style: String - var currency: String? - get() = definedExternally - set(value) = definedExternally - var currencyDisplay: String? - get() = definedExternally - set(value) = definedExternally - var minimumIntegerDigits: Number - var minimumFractionDigits: Number - var maximumFractionDigits: Number - var minimumSignificantDigits: Number? - get() = definedExternally - set(value) = definedExternally - var maximumSignificantDigits: Number? - get() = definedExternally - set(value) = definedExternally - var useGrouping: Boolean -} - -@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") -external interface NumberFormat { - fun format(value: Number): String - fun resolvedOptions(): ResolvedNumberFormatOptions - - companion object { - @nativeInvoke - operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: NumberFormatOptions = definedExternally): NumberFormat - fun supportedLocalesOf(locales: Any /* String | Array */, options: NumberFormatOptions = definedExternally): Array - } -} - -external interface DateTimeFormatOptions { - var localeMatcher: String? - get() = definedExternally - set(value) = definedExternally - var weekday: String? - get() = definedExternally - set(value) = definedExternally - var era: String? - get() = definedExternally - set(value) = definedExternally - var year: String? - get() = definedExternally - set(value) = definedExternally - var month: String? - get() = definedExternally - set(value) = definedExternally - var day: String? - get() = definedExternally - set(value) = definedExternally - var hour: String? - get() = definedExternally - set(value) = definedExternally - var minute: String? - get() = definedExternally - set(value) = definedExternally - var second: String? - get() = definedExternally - set(value) = definedExternally - var timeZoneName: String? - get() = definedExternally - set(value) = definedExternally - var formatMatcher: String? - get() = definedExternally - set(value) = definedExternally - var hour12: Boolean? - get() = definedExternally - set(value) = definedExternally - var timeZone: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedDateTimeFormatOptions { - var locale: String - var calendar: String - var numberingSystem: String - var timeZone: String - var hour12: Boolean? - get() = definedExternally - set(value) = definedExternally - var weekday: String? - get() = definedExternally - set(value) = definedExternally - var era: String? - get() = definedExternally - set(value) = definedExternally - var year: String? - get() = definedExternally - set(value) = definedExternally - var month: String? - get() = definedExternally - set(value) = definedExternally - var day: String? - get() = definedExternally - set(value) = definedExternally - var hour: String? - get() = definedExternally - set(value) = definedExternally - var minute: String? - get() = definedExternally - set(value) = definedExternally - var second: String? - get() = definedExternally - set(value) = definedExternally - var timeZoneName: String? - get() = definedExternally - set(value) = definedExternally -} - -@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") -external interface DateTimeFormat { - fun format(date: Date = definedExternally): String - fun format(): String - fun format(date: Number = definedExternally): String - fun resolvedOptions(): ResolvedDateTimeFormatOptions - - companion object { - @nativeInvoke - operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: DateTimeFormatOptions = definedExternally): DateTimeFormat - fun supportedLocalesOf(locales: Any /* String | Array */, options: DateTimeFormatOptions = definedExternally): Array - } -} \ No newline at end of file diff --git a/externals03/lib.es5.kt b/externals03/lib.es5.kt deleted file mode 100644 index c9b2102..0000000 --- a/externals03/lib.es5.kt +++ /dev/null @@ -1,69 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface DateConstructor { - @nativeInvoke - operator fun invoke(): String - val prototype: Date - fun parse(s: String): Number - fun UTC(year: Number, month: Number, date: Number = definedExternally, hours: Number = definedExternally, minutes: Number = definedExternally, seconds: Number = definedExternally, ms: Number = definedExternally): Number - fun now(): Number -} - -external interface ConcatArray { - val length: Number - @nativeGetter - operator fun get(n: Number): T? - @nativeSetter - operator fun set(n: Number, value: T) - fun join(separator: String = definedExternally): String - fun slice(start: Number = definedExternally, end: Number = definedExternally): Array -} - -external interface ArrayConstructor { - fun from(iterable: Iterable): Array - fun from(iterable: ArrayLike): Array - fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array - fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U): Array - fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array - fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U): Array - fun of(vararg items: T): Array - @nativeInvoke - operator fun invoke(arrayLength: Number = definedExternally): Array - @nativeInvoke - operator fun invoke(): Array - @nativeInvoke - operator fun invoke(arrayLength: Number): Array - @nativeInvoke - operator fun invoke(vararg items: T): Array - fun isArray(arg: Any): Boolean - val prototype: Array -} - -external interface PromiseLike { - fun then(onfulfilled: ((value: T) -> Any?)? = definedExternally, onrejected: ((reason: Any) -> Any?)? = definedExternally): PromiseLike -} - -external interface ArrayLike { - val length: Number - @nativeGetter - operator fun get(n: Number): T? - @nativeSetter - operator fun set(n: Number, value: T) -} - -typealias Record = Any \ No newline at end of file diff --git a/externals03/lib.scripthost.kt b/externals03/lib.scripthost.kt deleted file mode 100644 index 809347e..0000000 --- a/externals03/lib.scripthost.kt +++ /dev/null @@ -1,20 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external open class VarDate { - open var VarDate_typekey: VarDate -} \ No newline at end of file diff --git a/externals03/nonDeclarations.ts.kt b/externals03/nonDeclarations.ts.kt deleted file mode 100644 index 3650dca..0000000 --- a/externals03/nonDeclarations.ts.kt +++ /dev/null @@ -1,114 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package ts - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -typealias SortedReadonlyArray = Array - -typealias SortedArray = Array - -typealias NodeArray = Array - -typealias DotToken = PunctuationToken - -typealias DotDotDotToken = PunctuationToken - -typealias QuestionToken = PunctuationToken - -typealias ExclamationToken = PunctuationToken - -typealias ColonToken = PunctuationToken - -typealias EqualsToken = PunctuationToken - -typealias AsteriskToken = PunctuationToken - -typealias EqualsGreaterThanToken = PunctuationToken - -typealias PlusToken = PunctuationToken - -typealias MinusToken = PunctuationToken - -typealias QuestionDotToken = PunctuationToken - -typealias AssertsKeyword = KeywordToken - -typealias AwaitKeyword = KeywordToken - -typealias AwaitKeywordToken = AwaitKeyword - -typealias AssertsToken = AssertsKeyword - -typealias AbstractKeyword = ModifierToken - -typealias AsyncKeyword = ModifierToken - -typealias ConstKeyword = ModifierToken - -typealias DeclareKeyword = ModifierToken - -typealias DefaultKeyword = ModifierToken - -typealias ExportKeyword = ModifierToken - -typealias PrivateKeyword = ModifierToken - -typealias ProtectedKeyword = ModifierToken - -typealias PublicKeyword = ModifierToken - -typealias ReadonlyKeyword = ModifierToken - -typealias OverrideKeyword = ModifierToken - -typealias StaticKeyword = ModifierToken - -typealias ReadonlyToken = ReadonlyKeyword - -typealias ModifiersArray = NodeArray - -typealias IncrementExpression = UpdateExpression - -typealias ExponentiationOperator = SyntaxKind.AsteriskAsteriskToken - -typealias BinaryOperatorToken = Token - -typealias AssignmentOperatorToken = Token - -typealias FunctionBody = Block - -typealias WriteFileCallback = (fileName: String, data: String, writeByteOrderMark: Boolean, onError: (message: String) -> Unit, sourceFiles: Array) -> Unit - -typealias CustomTransformerFactory = (context: TransformationContext) -> CustomTransformer - -typealias SymbolTable = UnderscoreEscapedMap - -typealias JsFileExtensionInfo = FileExtensionInfo - -typealias EmitHelperUniqueNameCallback = (name: String) -> String - -typealias TransformerFactory = (context: TransformationContext) -> Transformer - -typealias Transformer = (node: T) -> T - -typealias Visitor = (node: Node) -> dynamic - -typealias FileWatcherCallback = (fileName: String, eventKind: FileWatcherEventKind) -> Unit - -typealias DirectoryWatcherCallback = (fileName: String) -> Unit - -typealias DiagnosticReporter = (diagnostic: Diagnostic) -> Unit - -typealias CodeActionCommand = InstallPackageAction \ No newline at end of file diff --git a/externals03/output-collector.module_typescript-to-lua.kt b/externals03/output-collector.module_typescript-to-lua.kt deleted file mode 100644 index 0c57eac..0000000 --- a/externals03/output-collector.module_typescript-to-lua.kt +++ /dev/null @@ -1,33 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.SourceFile - -external interface TranspiledFile { - var outPath: String - var sourceFiles: Array - var lua: String? - get() = definedExternally - set(value) = definedExternally - var luaSourceMap: String? - get() = definedExternally - set(value) = definedExternally - var declaration: String? - get() = definedExternally - set(value) = definedExternally - var declarationMap: String? - get() = definedExternally - set(value) = definedExternally -} \ No newline at end of file diff --git a/externals03/parse.module_typescript-to-lua.kt b/externals03/parse.module_typescript-to-lua.kt deleted file mode 100644 index ff6e944..0000000 --- a/externals03/parse.module_typescript-to-lua.kt +++ /dev/null @@ -1,25 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface ParsedCommandLine : ts.ParsedCommandLine { - override var options: dynamic /* typealias OmitIndexSignature = dynamic */ - get() = definedExternally - set(value) = definedExternally -} - -external fun updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine - -external fun parseCommandLine(args: Array): ParsedCommandLine \ No newline at end of file diff --git a/externals03/plugins.module_typescript-to-lua.kt b/externals03/plugins.module_typescript-to-lua.kt deleted file mode 100644 index 24d3ea4..0000000 --- a/externals03/plugins.module_typescript-to-lua.kt +++ /dev/null @@ -1,24 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface Plugin { - var visitors: Visitors? - get() = definedExternally - set(value) = definedExternally - var printer: Printer? - get() = definedExternally - set(value) = definedExternally -} \ No newline at end of file diff --git a/externals03/report.module_typescript-to-lua.kt b/externals03/report.module_typescript-to-lua.kt deleted file mode 100644 index f1582a6..0000000 --- a/externals03/report.module_typescript-to-lua.kt +++ /dev/null @@ -1,48 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.DiagnosticRelatedInformation -import ts.DiagnosticCategory -import ts.SourceFile -import ts.Diagnostic -import ts.System -import ts.DiagnosticReporter - -external interface `T$13` { - var code: Any - var reportsUnnecessary: Any? - get() = definedExternally - set(value) = definedExternally - var reportsDeprecated: Any? - get() = definedExternally - set(value) = definedExternally - var source: String? - get() = definedExternally - set(value) = definedExternally - var relatedInformation: Array? - get() = definedExternally - set(value) = definedExternally - var category: DiagnosticCategory - var file: SourceFile? - var start: Number? - var length: Number? - var messageText: dynamic /* String | ts.DiagnosticMessageChain */ - get() = definedExternally - set(value) = definedExternally -} - -external var prepareDiagnosticForFormatting: (diagnostic: Diagnostic) -> `T$13` - -external fun createDiagnosticReporter(pretty: Boolean, system: System = definedExternally): DiagnosticReporter \ No newline at end of file diff --git a/externals03/source-map.module_source-map.kt b/externals03/source-map.module_source-map.kt deleted file mode 100644 index 6880a36..0000000 --- a/externals03/source-map.module_source-map.kt +++ /dev/null @@ -1,192 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -typealias SourceMapUrl = String - -external interface StartOfSourceMap { - var file: String? - get() = definedExternally - set(value) = definedExternally - var sourceRoot: String? - get() = definedExternally - set(value) = definedExternally - var skipValidation: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface RawSourceMap { - var version: Number - var sources: Array - var names: Array - var sourceRoot: String? - get() = definedExternally - set(value) = definedExternally - var sourcesContent: Array? - get() = definedExternally - set(value) = definedExternally - var mappings: String - var file: String -} - -external interface RawIndexMap : StartOfSourceMap { - var version: Number - var sections: Array -} - -external interface RawSection { - var offset: Position - var map: RawSourceMap -} - -external interface Position { - var line: Number - var column: Number -} - -external interface NullablePosition { - var line: Number? - var column: Number? - var lastColumn: Number? -} - -external interface MappedPosition { - var source: String - var line: Number - var column: Number - var name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface NullableMappedPosition { - var source: String? - var line: Number? - var column: Number? - var name: String? -} - -external interface MappingItem { - var source: String - var generatedLine: Number - var generatedColumn: Number - var originalLine: Number - var originalColumn: Number - var name: String -} - -external interface Mapping { - var generated: Position - var original: Position - var source: String - var name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface CodeWithSourceMap { - var code: String - var map: SourceMapGenerator -} - -external interface SourceMapConsumer { - fun computeColumnSpans() - fun originalPositionFor(generatedPosition: Position /* Position & `T$19` */): NullableMappedPosition - fun generatedPositionFor(originalPosition: MappedPosition /* MappedPosition & `T$19` */): NullablePosition - fun allGeneratedPositionsFor(originalPosition: MappedPosition): Array - fun hasContentsOfAllSources(): Boolean - fun sourceContentFor(source: String, returnNullOnMissing: Boolean = definedExternally): String? - fun eachMapping(callback: (mapping: MappingItem) -> Unit, context: Any = definedExternally, order: Number = definedExternally) - fun destroy() -} - -external interface SourceMapConsumerConstructor { - var prototype: SourceMapConsumer - var GENERATED_ORDER: Number - var ORIGINAL_ORDER: Number - var GREATEST_LOWER_BOUND: Number - var LEAST_UPPER_BOUND: Number - fun fromSourceMap(sourceMap: SourceMapGenerator, sourceMapUrl: SourceMapUrl = definedExternally): Promise - fun with(rawSourceMap: RawSourceMap, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise - fun with(rawSourceMap: RawIndexMap, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise - fun with(rawSourceMap: String, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise -} - -external interface BasicSourceMapConsumer : SourceMapConsumer { - var file: String - var sourceRoot: String - var sources: Array - var sourcesContent: Array -} - -external interface BasicSourceMapConsumerConstructor { - var prototype: BasicSourceMapConsumer - fun fromSourceMap(sourceMap: SourceMapGenerator): Promise -} - -external interface IndexedSourceMapConsumer : SourceMapConsumer { - var sources: Array -} - -external interface IndexedSourceMapConsumerConstructor { - var prototype: IndexedSourceMapConsumer -} - -external open class SourceMapGenerator(startOfSourceMap: StartOfSourceMap = definedExternally) { - open fun addMapping(mapping: Mapping) - open fun setSourceContent(sourceFile: String, sourceContent: String) - open fun applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile: String = definedExternally, sourceMapPath: String = definedExternally) - override fun toString(): String - open fun toJSON(): RawSourceMap - - companion object { - fun fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator - } -} - -external open class SourceNode { - open var children: Array - open var sourceContents: Any - open var line: Number - open var column: Number - open var source: String - open var name: String - constructor() - constructor(line: Number?, column: Number?, source: String?, chunks: Array = definedExternally, name: String = definedExternally) - constructor(line: Number?, column: Number?, source: String?) - constructor(line: Number?, column: Number?, source: String?, chunks: Array = definedExternally) - constructor(line: Number?, column: Number?, source: String?, chunks: SourceNode = definedExternally, name: String = definedExternally) - constructor(line: Number?, column: Number?, source: String?, chunks: SourceNode = definedExternally) - constructor(line: Number?, column: Number?, source: String?, chunks: String = definedExternally, name: String = definedExternally) - constructor(line: Number?, column: Number?, source: String?, chunks: String = definedExternally) - open fun add(chunk: Array): SourceNode - open fun add(chunk: SourceNode): SourceNode - open fun add(chunk: String): SourceNode - open fun prepend(chunk: Array): SourceNode - open fun prepend(chunk: SourceNode): SourceNode - open fun prepend(chunk: String): SourceNode - open fun setSourceContent(sourceFile: String, sourceContent: String) - open fun walk(fn: (chunk: String, mapping: MappedPosition) -> Unit) - open fun walkSourceContents(fn: (file: String, content: String) -> Unit) - open fun join(sep: String): SourceNode - open fun replaceRight(pattern: String, replacement: String): SourceNode - override fun toString(): String - open fun toStringWithSourceMap(startOfSourceMap: StartOfSourceMap = definedExternally): CodeWithSourceMap - - companion object { - fun fromStringWithSourceMap(code: String, sourceMapConsumer: SourceMapConsumer, relativePath: String = definedExternally): SourceNode - } -} \ No newline at end of file diff --git a/externals03/transpile.module_typescript-to-lua.kt b/externals03/transpile.module_typescript-to-lua.kt deleted file mode 100644 index 8681706..0000000 --- a/externals03/transpile.module_typescript-to-lua.kt +++ /dev/null @@ -1,40 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.Program -import ts.SourceFile -import ts.CustomTransformers -import ts.Diagnostic -import ts.WriteFileCallback - -external interface TranspileOptions { - var program: Program - var sourceFiles: Array? - get() = definedExternally - set(value) = definedExternally - var customTransformers: CustomTransformers? - get() = definedExternally - set(value) = definedExternally - var plugins: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface TranspileResult { - var diagnostics: Array - var transpiledFiles: Array -} - -external fun getProgramTranspileResult(emitHost: EmitHost, writeFileResult: WriteFileCallback, __2: TranspileOptions): TranspileResult \ No newline at end of file diff --git a/externals03/transpiler.module_typescript-to-lua.kt b/externals03/transpiler.module_typescript-to-lua.kt deleted file mode 100644 index 16b18b0..0000000 --- a/externals03/transpiler.module_typescript-to-lua.kt +++ /dev/null @@ -1,55 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.WriteFileCallback -import ts.Diagnostic -import ts.Program - -external interface TranspilerOptions { - var emitHost: EmitHost? - get() = definedExternally - set(value) = definedExternally -} - -external interface EmitOptions : TranspileOptions { - var writeFile: WriteFileCallback? - get() = definedExternally - set(value) = definedExternally -} - -external interface EmitResult { - var emitSkipped: Boolean - var diagnostics: Array -} - -external interface `T$20` { - var emitPlan: Array -} - -external open class Transpiler(__0: TranspilerOptions = definedExternally) { - open var emitHost: EmitHost - open fun emit(emitOptions: EmitOptions): EmitResult - open fun getEmitPlan(program: Program, diagnostics: Array, files: Array): `T$20` -} - -external fun getEmitPath(file: String, program: Program): String - -external fun getEmitPathRelativeToOutDir(fileName: String, program: Program): String - -external fun getSourceDir(program: Program): String - -external fun getEmitOutDir(program: Program): String - -external fun getProjectRoot(program: Program): String \ No newline at end of file diff --git a/externals03/tsconfig.module_typescript-to-lua.kt b/externals03/tsconfig.module_typescript-to-lua.kt deleted file mode 100644 index 865bc70..0000000 --- a/externals03/tsconfig.module_typescript-to-lua.kt +++ /dev/null @@ -1,18 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.System - -external fun parseConfigFileWithSystem(configFileName: String, commandLineOptions: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, system: System = definedExternally): ParsedCommandLine \ No newline at end of file diff --git a/externals03/typescript.ts.ScriptSnapshot.module_typescript.kt b/externals03/typescript.ts.ScriptSnapshot.module_typescript.kt deleted file mode 100644 index acab3da..0000000 --- a/externals03/typescript.ts.ScriptSnapshot.module_typescript.kt +++ /dev/null @@ -1,20 +0,0 @@ -@file:JsQualifier("ts.ScriptSnapshot") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package ts.ScriptSnapshot - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.IScriptSnapshot - -external fun fromString(text: String): IScriptSnapshot \ No newline at end of file diff --git a/externals03/typescript.ts.module_typescript.kt b/externals03/typescript.ts.module_typescript.kt deleted file mode 100644 index a552747..0000000 --- a/externals03/typescript.ts.module_typescript.kt +++ /dev/null @@ -1,5914 +0,0 @@ -@file:JsModule("typescript") -@file:JsNonModule -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package ts - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external var versionMajorMinor: Any - -external var version: String - -external interface MapLike { - @nativeGetter - operator fun get(index: String): T? - @nativeSetter - operator fun set(index: String, value: T) -} - -external interface ReadonlyCollection { - val size: Number - fun has(key: K): Boolean - fun keys(): Iterator -} - -external interface Collection : ReadonlyCollection { - fun delete(key: K): Boolean - fun clear() -} - -external interface ReadonlyESMap : ReadonlyCollection { - fun get(key: K): V? - fun values(): Iterator - fun entries(): Iterator */> - fun forEach(action: (value: V, key: K) -> Unit) -} - -external interface ReadonlyMap : ReadonlyESMap - -external interface ESMap : ReadonlyESMap, Collection { - fun set(key: K, value: V): ESMap /* this */ -} - -external interface Map : ESMap - -external interface ReadonlySet : ReadonlyCollection { - override fun has(value: T): Boolean - fun values(): Iterator - fun entries(): Iterator */> - fun forEach(action: (value: T, key: T) -> Unit) -} - -external interface Set : ReadonlySet, Collection { - fun add(value: T): Set /* this */ - override fun delete(value: T): Boolean -} - -external interface `T$1` { - var value: T - var done: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$2` { - var value: Unit - var done: Boolean -} - -external interface Iterator { - fun next(): dynamic /* `T$1` | `T$2` */ -} - -external interface Push { - fun push(vararg values: T) -} - -external interface `T$3` { - var __pathBrand: Any -} - -external interface TextRange { - var pos: Number - var end: Number -} - -external interface ReadonlyTextRange { - val pos: Number - val end: Number -} - -external enum class SyntaxKind { - Unknown /* = 0 */, - EndOfFileToken /* = 1 */, - SingleLineCommentTrivia /* = 2 */, - MultiLineCommentTrivia /* = 3 */, - NewLineTrivia /* = 4 */, - WhitespaceTrivia /* = 5 */, - ShebangTrivia /* = 6 */, - ConflictMarkerTrivia /* = 7 */, - NumericLiteral /* = 8 */, - BigIntLiteral /* = 9 */, - StringLiteral /* = 10 */, - JsxText /* = 11 */, - JsxTextAllWhiteSpaces /* = 12 */, - RegularExpressionLiteral /* = 13 */, - NoSubstitutionTemplateLiteral /* = 14 */, - TemplateHead /* = 15 */, - TemplateMiddle /* = 16 */, - TemplateTail /* = 17 */, - OpenBraceToken /* = 18 */, - CloseBraceToken /* = 19 */, - OpenParenToken /* = 20 */, - CloseParenToken /* = 21 */, - OpenBracketToken /* = 22 */, - CloseBracketToken /* = 23 */, - DotToken /* = 24 */, - DotDotDotToken /* = 25 */, - SemicolonToken /* = 26 */, - CommaToken /* = 27 */, - QuestionDotToken /* = 28 */, - LessThanToken /* = 29 */, - LessThanSlashToken /* = 30 */, - GreaterThanToken /* = 31 */, - LessThanEqualsToken /* = 32 */, - GreaterThanEqualsToken /* = 33 */, - EqualsEqualsToken /* = 34 */, - ExclamationEqualsToken /* = 35 */, - EqualsEqualsEqualsToken /* = 36 */, - ExclamationEqualsEqualsToken /* = 37 */, - EqualsGreaterThanToken /* = 38 */, - PlusToken /* = 39 */, - MinusToken /* = 40 */, - AsteriskToken /* = 41 */, - AsteriskAsteriskToken /* = 42 */, - SlashToken /* = 43 */, - PercentToken /* = 44 */, - PlusPlusToken /* = 45 */, - MinusMinusToken /* = 46 */, - LessThanLessThanToken /* = 47 */, - GreaterThanGreaterThanToken /* = 48 */, - GreaterThanGreaterThanGreaterThanToken /* = 49 */, - AmpersandToken /* = 50 */, - BarToken /* = 51 */, - CaretToken /* = 52 */, - ExclamationToken /* = 53 */, - TildeToken /* = 54 */, - AmpersandAmpersandToken /* = 55 */, - BarBarToken /* = 56 */, - QuestionToken /* = 57 */, - ColonToken /* = 58 */, - AtToken /* = 59 */, - QuestionQuestionToken /* = 60 */, - BacktickToken /* = 61 */, - EqualsToken /* = 62 */, - PlusEqualsToken /* = 63 */, - MinusEqualsToken /* = 64 */, - AsteriskEqualsToken /* = 65 */, - AsteriskAsteriskEqualsToken /* = 66 */, - SlashEqualsToken /* = 67 */, - PercentEqualsToken /* = 68 */, - LessThanLessThanEqualsToken /* = 69 */, - GreaterThanGreaterThanEqualsToken /* = 70 */, - GreaterThanGreaterThanGreaterThanEqualsToken /* = 71 */, - AmpersandEqualsToken /* = 72 */, - BarEqualsToken /* = 73 */, - BarBarEqualsToken /* = 74 */, - AmpersandAmpersandEqualsToken /* = 75 */, - QuestionQuestionEqualsToken /* = 76 */, - CaretEqualsToken /* = 77 */, - Identifier /* = 78 */, - PrivateIdentifier /* = 79 */, - BreakKeyword /* = 80 */, - CaseKeyword /* = 81 */, - CatchKeyword /* = 82 */, - ClassKeyword /* = 83 */, - ConstKeyword /* = 84 */, - ContinueKeyword /* = 85 */, - DebuggerKeyword /* = 86 */, - DefaultKeyword /* = 87 */, - DeleteKeyword /* = 88 */, - DoKeyword /* = 89 */, - ElseKeyword /* = 90 */, - EnumKeyword /* = 91 */, - ExportKeyword /* = 92 */, - ExtendsKeyword /* = 93 */, - FalseKeyword /* = 94 */, - FinallyKeyword /* = 95 */, - ForKeyword /* = 96 */, - FunctionKeyword /* = 97 */, - IfKeyword /* = 98 */, - ImportKeyword /* = 99 */, - InKeyword /* = 100 */, - InstanceOfKeyword /* = 101 */, - NewKeyword /* = 102 */, - NullKeyword /* = 103 */, - ReturnKeyword /* = 104 */, - SuperKeyword /* = 105 */, - SwitchKeyword /* = 106 */, - ThisKeyword /* = 107 */, - ThrowKeyword /* = 108 */, - TrueKeyword /* = 109 */, - TryKeyword /* = 110 */, - TypeOfKeyword /* = 111 */, - VarKeyword /* = 112 */, - VoidKeyword /* = 113 */, - WhileKeyword /* = 114 */, - WithKeyword /* = 115 */, - ImplementsKeyword /* = 116 */, - InterfaceKeyword /* = 117 */, - LetKeyword /* = 118 */, - PackageKeyword /* = 119 */, - PrivateKeyword /* = 120 */, - ProtectedKeyword /* = 121 */, - PublicKeyword /* = 122 */, - StaticKeyword /* = 123 */, - YieldKeyword /* = 124 */, - AbstractKeyword /* = 125 */, - AsKeyword /* = 126 */, - AssertsKeyword /* = 127 */, - AnyKeyword /* = 128 */, - AsyncKeyword /* = 129 */, - AwaitKeyword /* = 130 */, - BooleanKeyword /* = 131 */, - ConstructorKeyword /* = 132 */, - DeclareKeyword /* = 133 */, - GetKeyword /* = 134 */, - InferKeyword /* = 135 */, - IntrinsicKeyword /* = 136 */, - IsKeyword /* = 137 */, - KeyOfKeyword /* = 138 */, - ModuleKeyword /* = 139 */, - NamespaceKeyword /* = 140 */, - NeverKeyword /* = 141 */, - ReadonlyKeyword /* = 142 */, - RequireKeyword /* = 143 */, - NumberKeyword /* = 144 */, - ObjectKeyword /* = 145 */, - SetKeyword /* = 146 */, - StringKeyword /* = 147 */, - SymbolKeyword /* = 148 */, - TypeKeyword /* = 149 */, - UndefinedKeyword /* = 150 */, - UniqueKeyword /* = 151 */, - UnknownKeyword /* = 152 */, - FromKeyword /* = 153 */, - GlobalKeyword /* = 154 */, - BigIntKeyword /* = 155 */, - OverrideKeyword /* = 156 */, - OfKeyword /* = 157 */, - QualifiedName /* = 158 */, - ComputedPropertyName /* = 159 */, - TypeParameter /* = 160 */, - Parameter /* = 161 */, - Decorator /* = 162 */, - PropertySignature /* = 163 */, - PropertyDeclaration /* = 164 */, - MethodSignature /* = 165 */, - MethodDeclaration /* = 166 */, - Constructor /* = 167 */, - GetAccessor /* = 168 */, - SetAccessor /* = 169 */, - CallSignature /* = 170 */, - ConstructSignature /* = 171 */, - IndexSignature /* = 172 */, - TypePredicate /* = 173 */, - TypeReference /* = 174 */, - FunctionType /* = 175 */, - ConstructorType /* = 176 */, - TypeQuery /* = 177 */, - TypeLiteral /* = 178 */, - ArrayType /* = 179 */, - TupleType /* = 180 */, - OptionalType /* = 181 */, - RestType /* = 182 */, - UnionType /* = 183 */, - IntersectionType /* = 184 */, - ConditionalType /* = 185 */, - InferType /* = 186 */, - ParenthesizedType /* = 187 */, - ThisType /* = 188 */, - TypeOperator /* = 189 */, - IndexedAccessType /* = 190 */, - MappedType /* = 191 */, - LiteralType /* = 192 */, - NamedTupleMember /* = 193 */, - TemplateLiteralType /* = 194 */, - TemplateLiteralTypeSpan /* = 195 */, - ImportType /* = 196 */, - ObjectBindingPattern /* = 197 */, - ArrayBindingPattern /* = 198 */, - BindingElement /* = 199 */, - ArrayLiteralExpression /* = 200 */, - ObjectLiteralExpression /* = 201 */, - PropertyAccessExpression /* = 202 */, - ElementAccessExpression /* = 203 */, - CallExpression /* = 204 */, - NewExpression /* = 205 */, - TaggedTemplateExpression /* = 206 */, - TypeAssertionExpression /* = 207 */, - ParenthesizedExpression /* = 208 */, - FunctionExpression /* = 209 */, - ArrowFunction /* = 210 */, - DeleteExpression /* = 211 */, - TypeOfExpression /* = 212 */, - VoidExpression /* = 213 */, - AwaitExpression /* = 214 */, - PrefixUnaryExpression /* = 215 */, - PostfixUnaryExpression /* = 216 */, - BinaryExpression /* = 217 */, - ConditionalExpression /* = 218 */, - TemplateExpression /* = 219 */, - YieldExpression /* = 220 */, - SpreadElement /* = 221 */, - ClassExpression /* = 222 */, - OmittedExpression /* = 223 */, - ExpressionWithTypeArguments /* = 224 */, - AsExpression /* = 225 */, - NonNullExpression /* = 226 */, - MetaProperty /* = 227 */, - SyntheticExpression /* = 228 */, - TemplateSpan /* = 229 */, - SemicolonClassElement /* = 230 */, - Block /* = 231 */, - EmptyStatement /* = 232 */, - VariableStatement /* = 233 */, - ExpressionStatement /* = 234 */, - IfStatement /* = 235 */, - DoStatement /* = 236 */, - WhileStatement /* = 237 */, - ForStatement /* = 238 */, - ForInStatement /* = 239 */, - ForOfStatement /* = 240 */, - ContinueStatement /* = 241 */, - BreakStatement /* = 242 */, - ReturnStatement /* = 243 */, - WithStatement /* = 244 */, - SwitchStatement /* = 245 */, - LabeledStatement /* = 246 */, - ThrowStatement /* = 247 */, - TryStatement /* = 248 */, - DebuggerStatement /* = 249 */, - VariableDeclaration /* = 250 */, - VariableDeclarationList /* = 251 */, - FunctionDeclaration /* = 252 */, - ClassDeclaration /* = 253 */, - InterfaceDeclaration /* = 254 */, - TypeAliasDeclaration /* = 255 */, - EnumDeclaration /* = 256 */, - ModuleDeclaration /* = 257 */, - ModuleBlock /* = 258 */, - CaseBlock /* = 259 */, - NamespaceExportDeclaration /* = 260 */, - ImportEqualsDeclaration /* = 261 */, - ImportDeclaration /* = 262 */, - ImportClause /* = 263 */, - NamespaceImport /* = 264 */, - NamedImports /* = 265 */, - ImportSpecifier /* = 266 */, - ExportAssignment /* = 267 */, - ExportDeclaration /* = 268 */, - NamedExports /* = 269 */, - NamespaceExport /* = 270 */, - ExportSpecifier /* = 271 */, - MissingDeclaration /* = 272 */, - ExternalModuleReference /* = 273 */, - JsxElement /* = 274 */, - JsxSelfClosingElement /* = 275 */, - JsxOpeningElement /* = 276 */, - JsxClosingElement /* = 277 */, - JsxFragment /* = 278 */, - JsxOpeningFragment /* = 279 */, - JsxClosingFragment /* = 280 */, - JsxAttribute /* = 281 */, - JsxAttributes /* = 282 */, - JsxSpreadAttribute /* = 283 */, - JsxExpression /* = 284 */, - CaseClause /* = 285 */, - DefaultClause /* = 286 */, - HeritageClause /* = 287 */, - CatchClause /* = 288 */, - PropertyAssignment /* = 289 */, - ShorthandPropertyAssignment /* = 290 */, - SpreadAssignment /* = 291 */, - EnumMember /* = 292 */, - UnparsedPrologue /* = 293 */, - UnparsedPrepend /* = 294 */, - UnparsedText /* = 295 */, - UnparsedInternalText /* = 296 */, - UnparsedSyntheticReference /* = 297 */, - SourceFile /* = 298 */, - Bundle /* = 299 */, - UnparsedSource /* = 300 */, - InputFiles /* = 301 */, - JSDocTypeExpression /* = 302 */, - JSDocNameReference /* = 303 */, - JSDocAllType /* = 304 */, - JSDocUnknownType /* = 305 */, - JSDocNullableType /* = 306 */, - JSDocNonNullableType /* = 307 */, - JSDocOptionalType /* = 308 */, - JSDocFunctionType /* = 309 */, - JSDocVariadicType /* = 310 */, - JSDocNamepathType /* = 311 */, - JSDocComment /* = 312 */, - JSDocText /* = 313 */, - JSDocTypeLiteral /* = 314 */, - JSDocSignature /* = 315 */, - JSDocLink /* = 316 */, - JSDocTag /* = 317 */, - JSDocAugmentsTag /* = 318 */, - JSDocImplementsTag /* = 319 */, - JSDocAuthorTag /* = 320 */, - JSDocDeprecatedTag /* = 321 */, - JSDocClassTag /* = 322 */, - JSDocPublicTag /* = 323 */, - JSDocPrivateTag /* = 324 */, - JSDocProtectedTag /* = 325 */, - JSDocReadonlyTag /* = 326 */, - JSDocOverrideTag /* = 327 */, - JSDocCallbackTag /* = 328 */, - JSDocEnumTag /* = 329 */, - JSDocParameterTag /* = 330 */, - JSDocReturnTag /* = 331 */, - JSDocThisTag /* = 332 */, - JSDocTypeTag /* = 333 */, - JSDocTemplateTag /* = 334 */, - JSDocTypedefTag /* = 335 */, - JSDocSeeTag /* = 336 */, - JSDocPropertyTag /* = 337 */, - SyntaxList /* = 338 */, - NotEmittedStatement /* = 339 */, - PartiallyEmittedExpression /* = 340 */, - CommaListExpression /* = 341 */, - MergeDeclarationMarker /* = 342 */, - EndOfDeclarationMarker /* = 343 */, - SyntheticReferenceExpression /* = 344 */, - Count /* = 345 */, - FirstAssignment /* = 62 */, - LastAssignment /* = 77 */, - FirstCompoundAssignment /* = 63 */, - LastCompoundAssignment /* = 77 */, - FirstReservedWord /* = 80 */, - LastReservedWord /* = 115 */, - FirstKeyword /* = 80 */, - LastKeyword /* = 157 */, - FirstFutureReservedWord /* = 116 */, - LastFutureReservedWord /* = 124 */, - FirstTypeNode /* = 173 */, - LastTypeNode /* = 196 */, - FirstPunctuation /* = 18 */, - LastPunctuation /* = 77 */, - FirstToken /* = 0 */, - LastToken /* = 157 */, - FirstTriviaToken /* = 2 */, - LastTriviaToken /* = 7 */, - FirstLiteralToken /* = 8 */, - LastLiteralToken /* = 14 */, - FirstTemplateToken /* = 14 */, - LastTemplateToken /* = 17 */, - FirstBinaryOperator /* = 29 */, - LastBinaryOperator /* = 77 */, - FirstStatement /* = 233 */, - LastStatement /* = 249 */, - FirstNode /* = 158 */, - FirstJSDocNode /* = 302 */, - LastJSDocNode /* = 337 */, - FirstJSDocTagNode /* = 317 */, - LastJSDocTagNode /* = 337 */ -} - -external enum class NodeFlags { - None /* = 0 */, - Let /* = 1 */, - Const /* = 2 */, - NestedNamespace /* = 4 */, - Synthesized /* = 8 */, - Namespace /* = 16 */, - OptionalChain /* = 32 */, - ExportContext /* = 64 */, - ContainsThis /* = 128 */, - HasImplicitReturn /* = 256 */, - HasExplicitReturn /* = 512 */, - GlobalAugmentation /* = 1024 */, - HasAsyncFunctions /* = 2048 */, - DisallowInContext /* = 4096 */, - YieldContext /* = 8192 */, - DecoratorContext /* = 16384 */, - AwaitContext /* = 32768 */, - ThisNodeHasError /* = 65536 */, - JavaScriptFile /* = 131072 */, - ThisNodeOrAnySubNodesHasError /* = 262144 */, - HasAggregatedChildData /* = 524288 */, - JSDoc /* = 4194304 */, - JsonFile /* = 33554432 */, - BlockScoped /* = 3 */, - ReachabilityCheckFlags /* = 768 */, - ReachabilityAndEmitFlags /* = 2816 */, - ContextFlags /* = 25358336 */, - TypeExcludesFlags /* = 40960 */ -} - -external enum class ModifierFlags { - None /* = 0 */, - Export /* = 1 */, - Ambient /* = 2 */, - Public /* = 4 */, - Private /* = 8 */, - Protected /* = 16 */, - Static /* = 32 */, - Readonly /* = 64 */, - Abstract /* = 128 */, - Async /* = 256 */, - Default /* = 512 */, - Const /* = 2048 */, - HasComputedJSDocModifiers /* = 4096 */, - Deprecated /* = 8192 */, - Override /* = 16384 */, - HasComputedFlags /* = 536870912 */, - AccessibilityModifier /* = 28 */, - ParameterPropertyModifier /* = 16476 */, - NonPublicAccessibilityModifier /* = 24 */, - TypeScriptModifier /* = 18654 */, - ExportDefault /* = 513 */, - All /* = 27647 */ -} - -external enum class JsxFlags { - None /* = 0 */, - IntrinsicNamedElement /* = 1 */, - IntrinsicIndexedElement /* = 2 */, - IntrinsicElement /* = 3 */ -} - -external interface Node : ReadonlyTextRange { - fun getSourceFile(): SourceFile - fun getChildCount(sourceFile: SourceFile = definedExternally): Number - fun getChildAt(index: Number, sourceFile: SourceFile = definedExternally): Node - fun getChildren(sourceFile: SourceFile = definedExternally): Array - fun getStart(sourceFile: SourceFile = definedExternally, includeJsDocComment: Boolean = definedExternally): Number - fun getFullStart(): Number - fun getEnd(): Number - fun getWidth(sourceFile: SourceFileLike = definedExternally): Number - fun getFullWidth(): Number - fun getLeadingTriviaWidth(sourceFile: SourceFile = definedExternally): Number - fun getFullText(sourceFile: SourceFile = definedExternally): String - fun getText(sourceFile: SourceFile = definedExternally): String - fun getFirstToken(sourceFile: SourceFile = definedExternally): Node? - fun getLastToken(sourceFile: SourceFile = definedExternally): Node? - fun forEachChild(cbNode: (node: Node) -> T?, cbNodeArray: (nodes: NodeArray) -> T? = definedExternally): T? - val kind: SyntaxKind - val flags: NodeFlags - val decorators: NodeArray? - get() = definedExternally - val modifiers: ModifiersArray? - get() = definedExternally - val parent: Node -} - -external interface JSDocContainer - -external interface Token : Node { - override val kind: TKind -} - -external interface PunctuationToken : Token - -external interface KeywordToken : Token - -external interface ModifierToken : KeywordToken - -external enum class GeneratedIdentifierFlags { - None /* = 0 */, - ReservedInNestedScopes /* = 8 */, - Optimistic /* = 16 */, - FileLevel /* = 32 */, - AllowNameSubstitution /* = 64 */ -} - -external interface Identifier : PrimaryExpression, Declaration { - val text: String - val escapedText: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - get() = definedExternally - val originalKeywordKind: SyntaxKind? - get() = definedExternally - var isInJSDocNamespace: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TransientIdentifier : Identifier { - var resolvedSymbol: Symbol -} - -external interface QualifiedName : Node { - val left: dynamic /* Identifier | QualifiedName */ - get() = definedExternally - val right: Identifier -} - -external interface Declaration : Node { - var _declarationBrand: Any -} - -external interface NamedDeclaration : Declaration { - val name: dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ - get() = definedExternally -} - -external interface DeclarationStatement : NamedDeclaration, Statement { - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? */ - get() = definedExternally -} - -external interface ComputedPropertyName : Node { - override val parent: Declaration - val expression: Expression -} - -external interface PrivateIdentifier : Node { - val text: String - val escapedText: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - get() = definedExternally -} - -external interface Decorator : Node { - override val parent: NamedDeclaration - val expression: LeftHandSideExpression -} - -external interface TypeParameterDeclaration : NamedDeclaration { - override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | InferTypeNode */ - get() = definedExternally - override val name: Identifier - val constraint: TypeNode? - get() = definedExternally - val default: TypeNode? - get() = definedExternally - var expression: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureDeclarationBase : NamedDeclaration, JSDocContainer { - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - val typeParameters: NodeArray? - get() = definedExternally - val parameters: NodeArray - val type: TypeNode? - get() = definedExternally -} - -external interface CallSignatureDeclaration : SignatureDeclarationBase, TypeElement { - override val kind: Any - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally -} - -external interface ConstructSignatureDeclaration : SignatureDeclarationBase, TypeElement { - override val kind: Any - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally -} - -external interface VariableDeclaration : NamedDeclaration, JSDocContainer { - override val parent: dynamic /* VariableDeclarationList | CatchClause */ - get() = definedExternally - override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ - get() = definedExternally - val exclamationToken: ExclamationToken? - get() = definedExternally - val type: TypeNode? - get() = definedExternally - val initializer: Expression? - get() = definedExternally -} - -external interface VariableDeclarationList : Node { - override val parent: dynamic /* VariableStatement | ForStatement | ForOfStatement | ForInStatement */ - get() = definedExternally - val declarations: NodeArray -} - -external interface ParameterDeclaration : NamedDeclaration, JSDocContainer { - override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ - get() = definedExternally - val dotDotDotToken: DotDotDotToken? - get() = definedExternally - override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ - get() = definedExternally - val questionToken: QuestionToken? - get() = definedExternally - val type: TypeNode? - get() = definedExternally - val initializer: Expression? - get() = definedExternally -} - -external interface BindingElement : NamedDeclaration { - override val parent: dynamic /* ObjectBindingPattern | ArrayBindingPattern */ - get() = definedExternally - val propertyName: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - val dotDotDotToken: DotDotDotToken? - get() = definedExternally - override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ - get() = definedExternally - val initializer: Expression? - get() = definedExternally -} - -external interface PropertySignature : TypeElement, JSDocContainer { - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - override val questionToken: QuestionToken? - get() = definedExternally - val type: TypeNode? - get() = definedExternally - var initializer: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface PropertyDeclaration : ClassElement, JSDocContainer { - override val parent: dynamic /* ClassDeclaration | ClassExpression */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - val questionToken: QuestionToken? - get() = definedExternally - val exclamationToken: ExclamationToken? - get() = definedExternally - val type: TypeNode? - get() = definedExternally - val initializer: Expression? - get() = definedExternally -} - -external interface ObjectLiteralElement : NamedDeclaration { - var _objectLiteralBrand: Any - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally -} - -external interface PropertyAssignment : ObjectLiteralElement, JSDocContainer { - override val parent: ObjectLiteralExpression - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - val questionToken: QuestionToken? - get() = definedExternally - val exclamationToken: ExclamationToken? - get() = definedExternally - val initializer: Expression -} - -external interface ShorthandPropertyAssignment : ObjectLiteralElement, JSDocContainer { - override val parent: ObjectLiteralExpression - override val name: Identifier - val questionToken: QuestionToken? - get() = definedExternally - val exclamationToken: ExclamationToken? - get() = definedExternally - val equalsToken: EqualsToken? - get() = definedExternally - val objectAssignmentInitializer: Expression? - get() = definedExternally -} - -external interface SpreadAssignment : ObjectLiteralElement, JSDocContainer { - override val parent: ObjectLiteralExpression - val expression: Expression -} - -external interface PropertyLikeDeclaration : NamedDeclaration { - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally -} - -external interface ObjectBindingPattern : Node { - override val parent: dynamic /* VariableDeclaration | ParameterDeclaration | BindingElement */ - get() = definedExternally - val elements: NodeArray -} - -external interface ArrayBindingPattern : Node { - override val parent: dynamic /* VariableDeclaration | ParameterDeclaration | BindingElement */ - get() = definedExternally - val elements: NodeArray -} - -external interface FunctionLikeDeclarationBase : SignatureDeclarationBase { - var _functionLikeDeclarationBrand: Any - val asteriskToken: AsteriskToken? - get() = definedExternally - val questionToken: QuestionToken? - get() = definedExternally - val exclamationToken: ExclamationToken? - get() = definedExternally - val body: dynamic /* Block? | Expression? */ - get() = definedExternally -} - -external interface FunctionDeclaration : FunctionLikeDeclarationBase, DeclarationStatement { - override val kind: Any - override val name: Identifier? - get() = definedExternally - override val body: FunctionBody? - get() = definedExternally -} - -external interface MethodSignature : SignatureDeclarationBase, TypeElement { - override val kind: Any - override val parent: dynamic /* ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally -} - -external interface MethodDeclaration : FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { - override val kind: Any - override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - override val body: FunctionBody? - get() = definedExternally -} - -external interface ConstructorDeclaration : FunctionLikeDeclarationBase, ClassElement, JSDocContainer { - override val kind: Any - override val parent: dynamic /* ClassDeclaration | ClassExpression */ - get() = definedExternally - override val body: FunctionBody? - get() = definedExternally -} - -external interface SemicolonClassElement : ClassElement { - override val parent: dynamic /* ClassDeclaration | ClassExpression */ - get() = definedExternally -} - -external interface GetAccessorDeclaration : FunctionLikeDeclarationBase, ClassElement, TypeElement, ObjectLiteralElement, JSDocContainer { - override val kind: Any - override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression | TypeLiteralNode | InterfaceDeclaration */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - override val body: FunctionBody? - get() = definedExternally - override val questionToken: QuestionToken? - get() = definedExternally -} - -external interface SetAccessorDeclaration : FunctionLikeDeclarationBase, ClassElement, TypeElement, ObjectLiteralElement, JSDocContainer { - override val kind: Any - override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression | TypeLiteralNode | InterfaceDeclaration */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - override val body: FunctionBody? - get() = definedExternally - override val questionToken: QuestionToken? - get() = definedExternally -} - -external interface IndexSignatureDeclaration : SignatureDeclarationBase, ClassElement, TypeElement { - override val kind: Any - override val parent: dynamic /* ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode */ - get() = definedExternally - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally -} - -external interface TypeNode : Node { - var _typeNodeBrand: Any -} - -external interface KeywordTypeNode : KeywordToken, TypeNode { - override val kind: TKind -} - -external interface ImportTypeNode : NodeWithTypeArguments { - val isTypeOf: Boolean - val argument: TypeNode - val qualifier: dynamic /* Identifier? | QualifiedName? */ - get() = definedExternally -} - -external interface ThisTypeNode : TypeNode - -external interface FunctionOrConstructorTypeNodeBase : TypeNode, SignatureDeclarationBase { - override val kind: dynamic /* SyntaxKind.FunctionType | SyntaxKind.ConstructorType */ - get() = definedExternally -} - -external interface FunctionTypeNode : FunctionOrConstructorTypeNodeBase { - override val kind: Any -} - -external interface ConstructorTypeNode : FunctionOrConstructorTypeNodeBase { - override val kind: Any -} - -external interface NodeWithTypeArguments : TypeNode { - val typeArguments: NodeArray? - get() = definedExternally -} - -external interface TypeReferenceNode : NodeWithTypeArguments { - val typeName: dynamic /* Identifier | QualifiedName */ - get() = definedExternally -} - -external interface TypePredicateNode : TypeNode { - override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | JSDocTypeExpression */ - get() = definedExternally - val assertsModifier: AssertsToken? - get() = definedExternally - val parameterName: dynamic /* Identifier | ThisTypeNode */ - get() = definedExternally - val type: TypeNode? - get() = definedExternally -} - -external interface TypeQueryNode : TypeNode { - val exprName: dynamic /* Identifier | QualifiedName */ - get() = definedExternally -} - -external interface TypeLiteralNode : TypeNode, Declaration { - val members: NodeArray -} - -external interface ArrayTypeNode : TypeNode { - val elementType: TypeNode -} - -external interface TupleTypeNode : TypeNode { - val elements: NodeArray -} - -external interface NamedTupleMember : TypeNode, JSDocContainer, Declaration { - val dotDotDotToken: Token? - get() = definedExternally - val name: Identifier - val questionToken: Token? - get() = definedExternally - val type: TypeNode -} - -external interface OptionalTypeNode : TypeNode { - val type: TypeNode -} - -external interface RestTypeNode : TypeNode { - val type: TypeNode -} - -external interface UnionTypeNode : TypeNode { - val types: NodeArray -} - -external interface IntersectionTypeNode : TypeNode { - val types: NodeArray -} - -external interface ConditionalTypeNode : TypeNode { - val checkType: TypeNode - val extendsType: TypeNode - val trueType: TypeNode - val falseType: TypeNode -} - -external interface InferTypeNode : TypeNode { - val typeParameter: TypeParameterDeclaration -} - -external interface ParenthesizedTypeNode : TypeNode { - val type: TypeNode -} - -external interface TypeOperatorNode : TypeNode { - val operator: dynamic /* SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword */ - get() = definedExternally - val type: TypeNode -} - -external interface IndexedAccessTypeNode : TypeNode { - val objectType: TypeNode - val indexType: TypeNode -} - -external interface MappedTypeNode : TypeNode, Declaration { - val readonlyToken: dynamic /* ReadonlyToken? | PlusToken? | MinusToken? */ - get() = definedExternally - val typeParameter: TypeParameterDeclaration - val nameType: TypeNode? - get() = definedExternally - val questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */ - get() = definedExternally - val type: TypeNode? - get() = definedExternally -} - -external interface LiteralTypeNode : TypeNode { - val literal: dynamic /* NullLiteral | TrueLiteral | FalseLiteral | LiteralExpression | PrefixUnaryExpression */ - get() = definedExternally -} - -external interface StringLiteral : LiteralExpression, Declaration - -external interface TemplateLiteralTypeNode : TypeNode { - val head: TemplateHead - val templateSpans: NodeArray -} - -external interface TemplateLiteralTypeSpan : TypeNode { - override val parent: TemplateLiteralTypeNode - val type: TypeNode - val literal: dynamic /* TemplateMiddle | TemplateTail */ - get() = definedExternally -} - -external interface Expression : Node { - var _expressionBrand: Any -} - -external interface OmittedExpression : Expression - -external interface PartiallyEmittedExpression : LeftHandSideExpression { - val expression: Expression -} - -external interface UnaryExpression : Expression { - var _unaryExpressionBrand: Any -} - -external interface UpdateExpression : UnaryExpression { - var _updateExpressionBrand: Any -} - -external interface PrefixUnaryExpression : UpdateExpression { - val operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken | SyntaxKind.ExclamationToken */ - get() = definedExternally - val operand: UnaryExpression -} - -external interface PostfixUnaryExpression : UpdateExpression { - val operand: LeftHandSideExpression - val operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken */ - get() = definedExternally -} - -external interface LeftHandSideExpression : UpdateExpression { - var _leftHandSideExpressionBrand: Any -} - -external interface MemberExpression : LeftHandSideExpression { - var _memberExpressionBrand: Any -} - -external interface PrimaryExpression : MemberExpression { - var _primaryExpressionBrand: Any -} - -external interface NullLiteral : PrimaryExpression - -external interface TrueLiteral : PrimaryExpression - -external interface FalseLiteral : PrimaryExpression - -external interface ThisExpression : PrimaryExpression - -external interface SuperExpression : PrimaryExpression - -external interface ImportExpression : PrimaryExpression - -external interface DeleteExpression : UnaryExpression { - val expression: UnaryExpression -} - -external interface TypeOfExpression : UnaryExpression { - val expression: UnaryExpression -} - -external interface VoidExpression : UnaryExpression { - val expression: UnaryExpression -} - -external interface AwaitExpression : UnaryExpression { - val expression: UnaryExpression -} - -external interface YieldExpression : Expression { - val asteriskToken: AsteriskToken? - get() = definedExternally - val expression: Expression? - get() = definedExternally -} - -external interface SyntheticExpression : Expression { - val isSpread: Boolean - val type: Type - val tupleNameSource: dynamic /* ParameterDeclaration? | NamedTupleMember? */ - get() = definedExternally -} - -external interface BinaryExpression : Expression, Declaration { - val left: Expression - val operatorToken: BinaryOperatorToken - val right: Expression -} - -external interface AssignmentExpression : BinaryExpression { - override val left: LeftHandSideExpression - override val operatorToken: TOperator -} - -external interface ObjectDestructuringAssignment : AssignmentExpression { - override val left: ObjectLiteralExpression -} - -external interface ArrayDestructuringAssignment : AssignmentExpression { - override val left: ArrayLiteralExpression -} - -external interface ConditionalExpression : Expression { - val condition: Expression - val questionToken: QuestionToken - val whenTrue: Expression - val colonToken: ColonToken - val whenFalse: Expression -} - -external interface FunctionExpression : PrimaryExpression, FunctionLikeDeclarationBase, JSDocContainer { - override val kind: Any - override val name: Identifier? - get() = definedExternally - override val body: FunctionBody -} - -external interface ArrowFunction : Expression, FunctionLikeDeclarationBase, JSDocContainer { - override val kind: Any - val equalsGreaterThanToken: EqualsGreaterThanToken - override val body: dynamic /* FunctionBody | Expression */ - get() = definedExternally - override val name: Any -} - -external interface LiteralLikeNode : Node { - var text: String - var isUnterminated: Boolean? - get() = definedExternally - set(value) = definedExternally - var hasExtendedUnicodeEscape: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TemplateLiteralLikeNode : LiteralLikeNode { - var rawText: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface LiteralExpression : LiteralLikeNode, PrimaryExpression { - var _literalExpressionBrand: Any -} - -external interface RegularExpressionLiteral : LiteralExpression - -external interface NoSubstitutionTemplateLiteral : LiteralExpression, TemplateLiteralLikeNode, Declaration - -external enum class TokenFlags { - None /* = 0 */, - Scientific /* = 16 */, - Octal /* = 32 */, - HexSpecifier /* = 64 */, - BinarySpecifier /* = 128 */, - OctalSpecifier /* = 256 */ -} - -external interface NumericLiteral : LiteralExpression, Declaration - -external interface BigIntLiteral : LiteralExpression - -external interface TemplateHead : TemplateLiteralLikeNode { - override val parent: dynamic /* TemplateExpression | TemplateLiteralTypeNode */ - get() = definedExternally -} - -external interface TemplateMiddle : TemplateLiteralLikeNode { - override val parent: dynamic /* TemplateSpan | TemplateLiteralTypeSpan */ - get() = definedExternally -} - -external interface TemplateTail : TemplateLiteralLikeNode { - override val parent: dynamic /* TemplateSpan | TemplateLiteralTypeSpan */ - get() = definedExternally -} - -external interface TemplateExpression : PrimaryExpression { - val head: TemplateHead - val templateSpans: NodeArray -} - -external interface TemplateSpan : Node { - override val parent: TemplateExpression - val expression: Expression - val literal: dynamic /* TemplateMiddle | TemplateTail */ - get() = definedExternally -} - -external interface ParenthesizedExpression : PrimaryExpression, JSDocContainer { - val expression: Expression -} - -external interface ArrayLiteralExpression : PrimaryExpression { - val elements: NodeArray -} - -external interface SpreadElement : Expression { - override val parent: dynamic /* ArrayLiteralExpression | CallExpression | NewExpression */ - get() = definedExternally - val expression: Expression -} - -external interface ObjectLiteralExpressionBase : PrimaryExpression, Declaration { - val properties: NodeArray -} - -external interface ObjectLiteralExpression : ObjectLiteralExpressionBase - -external interface PropertyAccessExpression : MemberExpression, NamedDeclaration { - val expression: LeftHandSideExpression - val questionDotToken: QuestionDotToken? - get() = definedExternally - override val name: dynamic /* Identifier | PrivateIdentifier */ - get() = definedExternally -} - -external interface PropertyAccessChain : PropertyAccessExpression { - var _optionalChainBrand: Any - override val name: dynamic /* Identifier | PrivateIdentifier */ - get() = definedExternally -} - -external interface SuperPropertyAccessExpression : PropertyAccessExpression { - override val expression: SuperExpression -} - -external interface PropertyAccessEntityNameExpression : PropertyAccessExpression { - var _propertyAccessExpressionLikeQualifiedNameBrand: Any? - get() = definedExternally - set(value) = definedExternally - override val expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ - get() = definedExternally - override val name: Identifier -} - -external interface ElementAccessExpression : MemberExpression { - val expression: LeftHandSideExpression - val questionDotToken: QuestionDotToken? - get() = definedExternally - val argumentExpression: Expression -} - -external interface ElementAccessChain : ElementAccessExpression { - var _optionalChainBrand: Any -} - -external interface SuperElementAccessExpression : ElementAccessExpression { - override val expression: SuperExpression -} - -external interface CallExpression : LeftHandSideExpression, Declaration { - val expression: LeftHandSideExpression - val questionDotToken: QuestionDotToken? - get() = definedExternally - val typeArguments: NodeArray? - get() = definedExternally - val arguments: NodeArray -} - -external interface CallChain : CallExpression { - var _optionalChainBrand: Any -} - -external interface SuperCall : CallExpression { - override val expression: SuperExpression -} - -external interface ImportCall : CallExpression { - override val expression: ImportExpression -} - -external interface ExpressionWithTypeArguments : NodeWithTypeArguments { - override val parent: dynamic /* HeritageClause | JSDocAugmentsTag | JSDocImplementsTag */ - get() = definedExternally - val expression: LeftHandSideExpression -} - -external interface NewExpression : PrimaryExpression, Declaration { - val expression: LeftHandSideExpression - val typeArguments: NodeArray? - get() = definedExternally - val arguments: NodeArray? - get() = definedExternally -} - -external interface TaggedTemplateExpression : MemberExpression { - val tag: LeftHandSideExpression - val typeArguments: NodeArray? - get() = definedExternally - val template: dynamic /* TemplateExpression | NoSubstitutionTemplateLiteral */ - get() = definedExternally -} - -external interface AsExpression : Expression { - val expression: Expression - val type: TypeNode -} - -external interface TypeAssertion : UnaryExpression { - val type: TypeNode - val expression: UnaryExpression -} - -external interface NonNullExpression : LeftHandSideExpression { - val expression: Expression -} - -external interface NonNullChain : NonNullExpression { - var _optionalChainBrand: Any -} - -external interface MetaProperty : PrimaryExpression { - val keywordToken: dynamic /* SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword */ - get() = definedExternally - val name: Identifier -} - -external interface JsxElement : PrimaryExpression { - val openingElement: JsxOpeningElement - val children: NodeArray - val closingElement: JsxClosingElement -} - -external interface JsxTagNamePropertyAccess : PropertyAccessExpression { - override val expression: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ - get() = definedExternally -} - -external interface JsxAttributes : ObjectLiteralExpressionBase { - override val parent: dynamic /* JsxSelfClosingElement | JsxOpeningElement */ - get() = definedExternally -} - -external interface JsxOpeningElement : Expression { - override val parent: JsxElement - val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ - get() = definedExternally - val typeArguments: NodeArray? - get() = definedExternally - val attributes: JsxAttributes -} - -external interface JsxSelfClosingElement : PrimaryExpression { - val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ - get() = definedExternally - val typeArguments: NodeArray? - get() = definedExternally - val attributes: JsxAttributes -} - -external interface JsxFragment : PrimaryExpression { - val openingFragment: JsxOpeningFragment - val children: NodeArray - val closingFragment: JsxClosingFragment -} - -external interface JsxOpeningFragment : Expression { - override val parent: JsxFragment -} - -external interface JsxClosingFragment : Expression { - override val parent: JsxFragment -} - -external interface JsxAttribute : ObjectLiteralElement { - override val parent: JsxAttributes - override val name: Identifier - val initializer: dynamic /* StringLiteral? | JsxExpression? */ - get() = definedExternally -} - -external interface JsxSpreadAttribute : ObjectLiteralElement { - override val parent: JsxAttributes - val expression: Expression -} - -external interface JsxClosingElement : Node { - override val parent: JsxElement - val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ - get() = definedExternally -} - -external interface JsxExpression : Expression { - override val parent: dynamic /* JsxElement | JsxAttribute | JsxSpreadAttribute */ - get() = definedExternally - val dotDotDotToken: Token? - get() = definedExternally - val expression: Expression? - get() = definedExternally -} - -external interface JsxText : LiteralLikeNode { - override val parent: JsxElement - val containsOnlyTriviaWhiteSpaces: Boolean -} - -external interface Statement : Node, JSDocContainer { - var _statementBrand: Any -} - -external interface NotEmittedStatement : Statement - -external interface CommaListExpression : Expression { - val elements: NodeArray -} - -external interface EmptyStatement : Statement - -external interface DebuggerStatement : Statement - -external interface MissingDeclaration : DeclarationStatement { - override val name: Identifier? - get() = definedExternally -} - -external interface Block : Statement { - val statements: NodeArray -} - -external interface VariableStatement : Statement { - val declarationList: VariableDeclarationList -} - -external interface ExpressionStatement : Statement { - val expression: Expression -} - -external interface IfStatement : Statement { - val expression: Expression - val thenStatement: Statement - val elseStatement: Statement? - get() = definedExternally -} - -external interface IterationStatement : Statement { - val statement: Statement -} - -external interface DoStatement : IterationStatement { - val expression: Expression -} - -external interface WhileStatement : IterationStatement { - val expression: Expression -} - -external interface ForStatement : IterationStatement { - val initializer: dynamic /* VariableDeclarationList? | Expression? */ - get() = definedExternally - val condition: Expression? - get() = definedExternally - val incrementor: Expression? - get() = definedExternally -} - -external interface ForInStatement : IterationStatement { - val initializer: dynamic /* VariableDeclarationList | Expression */ - get() = definedExternally - val expression: Expression -} - -external interface ForOfStatement : IterationStatement { - val awaitModifier: AwaitKeywordToken? - get() = definedExternally - val initializer: dynamic /* VariableDeclarationList | Expression */ - get() = definedExternally - val expression: Expression -} - -external interface BreakStatement : Statement { - val label: Identifier? - get() = definedExternally -} - -external interface ContinueStatement : Statement { - val label: Identifier? - get() = definedExternally -} - -external interface ReturnStatement : Statement { - val expression: Expression? - get() = definedExternally -} - -external interface WithStatement : Statement { - val expression: Expression - val statement: Statement -} - -external interface SwitchStatement : Statement { - val expression: Expression - val caseBlock: CaseBlock - var possiblyExhaustive: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface CaseBlock : Node { - override val parent: SwitchStatement - val clauses: NodeArray -} - -external interface CaseClause : Node { - override val parent: CaseBlock - val expression: Expression - val statements: NodeArray -} - -external interface DefaultClause : Node { - override val parent: CaseBlock - val statements: NodeArray -} - -external interface LabeledStatement : Statement { - val label: Identifier - val statement: Statement -} - -external interface ThrowStatement : Statement { - val expression: Expression -} - -external interface TryStatement : Statement { - val tryBlock: Block - val catchClause: CatchClause? - get() = definedExternally - val finallyBlock: Block? - get() = definedExternally -} - -external interface CatchClause : Node { - override val parent: TryStatement - val variableDeclaration: VariableDeclaration? - get() = definedExternally - val block: Block -} - -external interface ClassLikeDeclarationBase : NamedDeclaration, JSDocContainer { - override val kind: dynamic /* SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression */ - get() = definedExternally - override val name: Identifier? - get() = definedExternally - val typeParameters: NodeArray? - get() = definedExternally - val heritageClauses: NodeArray? - get() = definedExternally - val members: NodeArray -} - -external interface ClassDeclaration : ClassLikeDeclarationBase, DeclarationStatement { - override val kind: Any - override val name: Identifier? - get() = definedExternally -} - -external interface ClassExpression : ClassLikeDeclarationBase, PrimaryExpression { - override val kind: Any -} - -external interface ClassElement : NamedDeclaration { - var _classElementBrand: Any - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally -} - -external interface TypeElement : NamedDeclaration { - var _typeElementBrand: Any - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - val questionToken: QuestionToken? - get() = definedExternally -} - -external interface InterfaceDeclaration : DeclarationStatement, JSDocContainer { - override val name: Identifier - val typeParameters: NodeArray? - get() = definedExternally - val heritageClauses: NodeArray? - get() = definedExternally - val members: NodeArray -} - -external interface HeritageClause : Node { - override val parent: dynamic /* InterfaceDeclaration | ClassDeclaration | ClassExpression */ - get() = definedExternally - val token: dynamic /* SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword */ - get() = definedExternally - val types: NodeArray -} - -external interface TypeAliasDeclaration : DeclarationStatement, JSDocContainer { - override val name: Identifier - val typeParameters: NodeArray? - get() = definedExternally - val type: TypeNode -} - -external interface EnumMember : NamedDeclaration, JSDocContainer { - override val parent: EnumDeclaration - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - val initializer: Expression? - get() = definedExternally -} - -external interface EnumDeclaration : DeclarationStatement, JSDocContainer { - override val name: Identifier - val members: NodeArray -} - -external interface ModuleDeclaration : DeclarationStatement, JSDocContainer { - override val parent: dynamic /* ModuleBlock | NamespaceDeclaration | Identifier | JSDocNamespaceDeclaration | SourceFile */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral */ - get() = definedExternally - val body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */ - get() = definedExternally -} - -external interface NamespaceDeclaration : ModuleDeclaration { - override val name: Identifier - override val body: dynamic /* ModuleBlock | NamespaceDeclaration */ - get() = definedExternally -} - -external interface JSDocNamespaceDeclaration : ModuleDeclaration { - override val name: Identifier - override val body: dynamic /* Identifier? | JSDocNamespaceDeclaration? */ - get() = definedExternally -} - -external interface ModuleBlock : Node, Statement { - override val parent: ModuleDeclaration - val statements: NodeArray -} - -external interface ImportEqualsDeclaration : DeclarationStatement, JSDocContainer { - override val parent: dynamic /* SourceFile | ModuleBlock */ - get() = definedExternally - override val name: Identifier - val isTypeOnly: Boolean - val moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */ - get() = definedExternally -} - -external interface ExternalModuleReference : Node { - override val parent: ImportEqualsDeclaration - val expression: Expression -} - -external interface ImportDeclaration : Statement { - override val parent: dynamic /* SourceFile | ModuleBlock */ - get() = definedExternally - val importClause: ImportClause? - get() = definedExternally - val moduleSpecifier: Expression -} - -external interface ImportClause : NamedDeclaration { - override val parent: ImportDeclaration - val isTypeOnly: Boolean - override val name: Identifier? - get() = definedExternally - val namedBindings: dynamic /* NamespaceImport? | NamedImports? */ - get() = definedExternally -} - -external interface NamespaceImport : NamedDeclaration { - override val parent: ImportClause - override val name: Identifier -} - -external interface NamespaceExport : NamedDeclaration { - override val parent: ExportDeclaration - override val name: Identifier -} - -external interface NamespaceExportDeclaration : DeclarationStatement, JSDocContainer { - override val name: Identifier -} - -external interface ExportDeclaration : DeclarationStatement, JSDocContainer { - override val parent: dynamic /* SourceFile | ModuleBlock */ - get() = definedExternally - val isTypeOnly: Boolean - val exportClause: dynamic /* NamespaceExport? | NamedExports? */ - get() = definedExternally - val moduleSpecifier: Expression? - get() = definedExternally -} - -external interface NamedImports : Node { - override val parent: ImportClause - val elements: NodeArray -} - -external interface NamedExports : Node { - override val parent: ExportDeclaration - val elements: NodeArray -} - -external interface ImportSpecifier : NamedDeclaration { - override val parent: NamedImports - val propertyName: Identifier? - get() = definedExternally - override val name: Identifier -} - -external interface ExportSpecifier : NamedDeclaration { - override val parent: NamedExports - val propertyName: Identifier? - get() = definedExternally - override val name: Identifier -} - -external interface ExportAssignment : DeclarationStatement, JSDocContainer { - override val parent: SourceFile - val isExportEquals: Boolean? - get() = definedExternally - val expression: Expression -} - -external interface FileReference : TextRange { - var fileName: String -} - -external interface CheckJsDirective : TextRange { - var enabled: Boolean -} - -external interface CommentRange : TextRange { - var hasTrailingNewLine: Boolean? - get() = definedExternally - set(value) = definedExternally - var kind: dynamic /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */ - get() = definedExternally - set(value) = definedExternally -} - -external interface SynthesizedComment : CommentRange { - var text: String - var hasLeadingNewline: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface JSDocTypeExpression : TypeNode { - val type: TypeNode -} - -external interface JSDocNameReference : Node { - val name: dynamic /* Identifier | QualifiedName */ - get() = definedExternally -} - -external interface JSDocType : TypeNode { - var _jsDocTypeBrand: Any -} - -external interface JSDocAllType : JSDocType - -external interface JSDocUnknownType : JSDocType - -external interface JSDocNonNullableType : JSDocType { - val type: TypeNode -} - -external interface JSDocNullableType : JSDocType { - val type: TypeNode -} - -external interface JSDocOptionalType : JSDocType { - val type: TypeNode -} - -external interface JSDocFunctionType : JSDocType, SignatureDeclarationBase { - override val kind: Any -} - -external interface JSDocVariadicType : JSDocType { - val type: TypeNode -} - -external interface JSDocNamepathType : JSDocType { - val type: TypeNode -} - -external interface JSDoc : Node { - override val parent: dynamic /* ParameterDeclaration | CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | EmptyStatement | DebuggerStatement | Block | VariableStatement | ExpressionStatement | IfStatement | DoStatement | WhileStatement | ForStatement | ForInStatement | ForOfStatement | BreakStatement | ContinueStatement | ReturnStatement | WithStatement | SwitchStatement | LabeledStatement | ThrowStatement | TryStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | VariableDeclaration | PropertyDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | NamespaceExportDeclaration | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | Token & JSDocContainer */ - get() = definedExternally - val tags: NodeArray? - get() = definedExternally - val comment: dynamic /* String? | NodeArray? */ - get() = definedExternally -} - -external interface JSDocTag : Node { - override val parent: dynamic /* JSDoc | JSDocTypeLiteral */ - get() = definedExternally - val tagName: Identifier - val comment: dynamic /* String? | NodeArray? */ - get() = definedExternally -} - -external interface JSDocLink : Node { - val name: dynamic /* Identifier? | QualifiedName? */ - get() = definedExternally - var text: String -} - -external interface JSDocText : Node { - var text: String -} - -external interface JSDocUnknownTag : JSDocTag - -external interface `T$4` { - val expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ - get() = definedExternally -} - -external interface JSDocAugmentsTag : JSDocTag { - val `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */ -} - -external interface JSDocImplementsTag : JSDocTag { - val `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */ -} - -external interface JSDocAuthorTag : JSDocTag - -external interface JSDocDeprecatedTag : JSDocTag - -external interface JSDocClassTag : JSDocTag - -external interface JSDocPublicTag : JSDocTag - -external interface JSDocPrivateTag : JSDocTag - -external interface JSDocProtectedTag : JSDocTag - -external interface JSDocReadonlyTag : JSDocTag - -external interface JSDocOverrideTag : JSDocTag - -external interface JSDocEnumTag : JSDocTag, Declaration { - override val parent: JSDoc - val typeExpression: JSDocTypeExpression -} - -external interface JSDocThisTag : JSDocTag { - val typeExpression: JSDocTypeExpression -} - -external interface JSDocTemplateTag : JSDocTag { - val constraint: JSDocTypeExpression? - val typeParameters: NodeArray -} - -external interface JSDocSeeTag : JSDocTag { - val name: JSDocNameReference? - get() = definedExternally -} - -external interface JSDocReturnTag : JSDocTag { - val typeExpression: JSDocTypeExpression? - get() = definedExternally -} - -external interface JSDocTypeTag : JSDocTag { - val typeExpression: JSDocTypeExpression -} - -external interface JSDocTypedefTag : JSDocTag, NamedDeclaration { - override val parent: JSDoc - val fullName: dynamic /* JSDocNamespaceDeclaration? | Identifier? */ - get() = definedExternally - override val name: Identifier? - get() = definedExternally - val typeExpression: dynamic /* JSDocTypeExpression? | JSDocTypeLiteral? */ - get() = definedExternally -} - -external interface JSDocCallbackTag : JSDocTag, NamedDeclaration { - override val parent: JSDoc - val fullName: dynamic /* JSDocNamespaceDeclaration? | Identifier? */ - get() = definedExternally - override val name: Identifier? - get() = definedExternally - val typeExpression: JSDocSignature -} - -external interface JSDocSignature : JSDocType, Declaration { - val typeParameters: Array? - get() = definedExternally - val parameters: Array - val type: JSDocReturnTag? -} - -external interface JSDocPropertyLikeTag : JSDocTag, Declaration { - override val parent: JSDoc - val name: dynamic /* Identifier | QualifiedName */ - get() = definedExternally - val typeExpression: JSDocTypeExpression? - get() = definedExternally - val isNameFirst: Boolean - val isBracketed: Boolean -} - -external interface JSDocPropertyTag : JSDocPropertyLikeTag - -external interface JSDocParameterTag : JSDocPropertyLikeTag - -external interface JSDocTypeLiteral : JSDocType { - val jsDocPropertyTags: Array? - get() = definedExternally - val isArrayType: Boolean -} - -external enum class FlowFlags { - Unreachable /* = 1 */, - Start /* = 2 */, - BranchLabel /* = 4 */, - LoopLabel /* = 8 */, - Assignment /* = 16 */, - TrueCondition /* = 32 */, - FalseCondition /* = 64 */, - SwitchClause /* = 128 */, - ArrayMutation /* = 256 */, - Call /* = 512 */, - ReduceLabel /* = 1024 */, - Referenced /* = 2048 */, - Shared /* = 4096 */, - Label /* = 12 */, - Condition /* = 96 */ -} - -external interface FlowNodeBase { - var flags: FlowFlags - var id: Number? - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowStart : FlowNodeBase { - var node: dynamic /* FunctionExpression? | ArrowFunction? | MethodDeclaration? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowLabel : FlowNodeBase { - var antecedents: Array? -} - -external interface FlowAssignment : FlowNodeBase { - var node: dynamic /* Expression | VariableDeclaration | BindingElement */ - get() = definedExternally - set(value) = definedExternally - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowCall : FlowNodeBase { - var node: CallExpression - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowCondition : FlowNodeBase { - var node: Expression - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowSwitchClause : FlowNodeBase { - var switchStatement: SwitchStatement - var clauseStart: Number - var clauseEnd: Number - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowArrayMutation : FlowNodeBase { - var node: dynamic /* CallExpression | BinaryExpression */ - get() = definedExternally - set(value) = definedExternally - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowReduceLabel : FlowNodeBase { - var target: FlowLabel - var antecedents: Array - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface IncompleteType { - var flags: TypeFlags - var type: Type -} - -external interface AmdDependency { - var path: String - var name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface SourceFile : Declaration { - fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter - fun getLineEndOfPosition(pos: Number): Number - fun getLineStarts(): Array - fun getPositionOfLineAndCharacter(line: Number, character: Number): Number - fun update(newText: String, textChangeRange: TextChangeRange): SourceFile - val statements: NodeArray - val endOfFileToken: Token - var fileName: String - var text: String - var amdDependencies: Array - var moduleName: String? - get() = definedExternally - set(value) = definedExternally - var referencedFiles: Array - var typeReferenceDirectives: Array - var libReferenceDirectives: Array - var languageVariant: LanguageVariant - var isDeclarationFile: Boolean - var hasNoDefaultLib: Boolean - var languageVersion: ScriptTarget -} - -external interface Bundle : Node { - val prepends: Array - val sourceFiles: Array -} - -external interface InputFiles : Node { - var javascriptPath: String? - get() = definedExternally - set(value) = definedExternally - var javascriptText: String - var javascriptMapPath: String? - get() = definedExternally - set(value) = definedExternally - var javascriptMapText: String? - get() = definedExternally - set(value) = definedExternally - var declarationPath: String? - get() = definedExternally - set(value) = definedExternally - var declarationText: String - var declarationMapPath: String? - get() = definedExternally - set(value) = definedExternally - var declarationMapText: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface UnparsedSource : Node { - var fileName: String - var text: String - val prologues: Array - var helpers: Array? - var referencedFiles: Array - var typeReferenceDirectives: Array? - var libReferenceDirectives: Array - var hasNoDefaultLib: Boolean? - get() = definedExternally - set(value) = definedExternally - var sourceMapPath: String? - get() = definedExternally - set(value) = definedExternally - var sourceMapText: String? - get() = definedExternally - set(value) = definedExternally - val syntheticReferences: Array? - get() = definedExternally - val texts: Array -} - -external interface UnparsedSection : Node { - override val kind: SyntaxKind - override val parent: UnparsedSource - val data: String? - get() = definedExternally -} - -external interface UnparsedPrologue : UnparsedSection { - override val parent: UnparsedSource -} - -external interface UnparsedPrepend : UnparsedSection { - override val parent: UnparsedSource - val texts: Array -} - -external interface UnparsedTextLike : UnparsedSection { - override val kind: dynamic /* SyntaxKind.UnparsedText | SyntaxKind.UnparsedInternalText */ - get() = definedExternally - override val parent: UnparsedSource -} - -external interface UnparsedSyntheticReference : UnparsedSection { - override val parent: UnparsedSource -} - -external interface JsonSourceFile : SourceFile { - override val statements: NodeArray -} - -external interface TsConfigSourceFile : JsonSourceFile { - var extendedSourceFiles: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface JsonMinusNumericLiteral : PrefixUnaryExpression { - override val kind: Any - override val operator: Any - override val operand: NumericLiteral -} - -external interface JsonObjectExpressionStatement : ExpressionStatement { - override val expression: dynamic /* ObjectLiteralExpression | ArrayLiteralExpression | JsonMinusNumericLiteral | NumericLiteral | StringLiteral | TrueLiteral | FalseLiteral | NullLiteral */ - get() = definedExternally -} - -external interface ScriptReferenceHost { - fun getCompilerOptions(): CompilerOptions - fun getSourceFile(fileName: String): SourceFile? - fun getSourceFileByPath(path: String /* String & `T$3` */): SourceFile? - fun getCurrentDirectory(): String -} - -external interface ParseConfigHost { - var useCaseSensitiveFileNames: Boolean - fun readDirectory(rootDir: String, extensions: Array, excludes: Array?, includes: Array, depth: Number = definedExternally): Array - fun fileExists(path: String): Boolean - fun readFile(path: String): String? - val trace: ((s: String) -> Unit)? -} - -external interface `T$5` { - var _isResolvedConfigFileName: Any -} - -external open class OperationCanceledException - -external interface CancellationToken { - fun isCancellationRequested(): Boolean - fun throwIfCancellationRequested() -} - -external interface `T$6` { - var assignable: Number - var identity: Number - var subtype: Number - var strictSubtype: Number -} - -external interface Program : ScriptReferenceHost { - override fun getCurrentDirectory(): String - fun getRootFileNames(): Array - fun getSourceFiles(): Array - fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult - fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getDeclarationDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getConfigFileParsingDiagnostics(): Array - fun getTypeChecker(): TypeChecker - fun getNodeCount(): Number - fun getIdentifierCount(): Number - fun getSymbolCount(): Number - fun getTypeCount(): Number - fun getInstantiationCount(): Number - fun getRelationCacheSizes(): `T$6` - fun isSourceFileFromExternalLibrary(file: SourceFile): Boolean - fun isSourceFileDefaultLibrary(file: SourceFile): Boolean - fun getProjectReferences(): Array? - fun getResolvedProjectReferences(): Array? -} - -external interface ResolvedProjectReference { - var commandLine: ParsedCommandLine - var sourceFile: SourceFile - var references: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface CustomTransformer { - fun transformSourceFile(node: SourceFile): SourceFile - fun transformBundle(node: Bundle): Bundle -} - -external interface CustomTransformers { - var before: Array | CustomTransformerFactory */>? - get() = definedExternally - set(value) = definedExternally - var after: Array | CustomTransformerFactory */>? - get() = definedExternally - set(value) = definedExternally - var afterDeclarations: Array | CustomTransformerFactory */>? - get() = definedExternally - set(value) = definedExternally -} - -external interface SourceMapSpan { - var emittedLine: Number - var emittedColumn: Number - var sourceLine: Number - var sourceColumn: Number - var nameIndex: Number? - get() = definedExternally - set(value) = definedExternally - var sourceIndex: Number -} - -external enum class ExitStatus { - Success /* = 0 */, - DiagnosticsPresent_OutputsSkipped /* = 1 */, - DiagnosticsPresent_OutputsGenerated /* = 2 */, - InvalidProject_OutputsSkipped /* = 3 */, - ProjectReferenceCycle_OutputsSkipped /* = 4 */, - ProjectReferenceCycle_OutputsSkupped /* = 4 */ -} - -external interface EmitResult { - var emitSkipped: Boolean - var diagnostics: Array - var emittedFiles: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$7` { - var typeArguments: NodeArray? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeChecker { - fun getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type - fun getDeclaredTypeOfSymbol(symbol: Symbol): Type - fun getPropertiesOfType(type: Type): Array - fun getPropertyOfType(type: Type, propertyName: String): Symbol? - fun getPrivateIdentifierPropertyOfType(leftType: Type, name: String, location: Node): Symbol? - fun getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo? - fun getSignaturesOfType(type: Type, kind: SignatureKind): Array - fun getIndexTypeOfType(type: Type, kind: IndexKind): Type? - fun getBaseTypes(type: InterfaceType): Array - fun getBaseTypeOfLiteralType(type: Type): Type - fun getWidenedType(type: Type): Type - fun getReturnTypeOfSignature(signature: Signature): Type - fun getNullableType(type: Type, flags: TypeFlags): Type - fun getNonNullableType(type: Type): Type - fun getTypeArguments(type: TypeReference): Array - fun typeToTypeNode(type: Type, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeNode? - fun signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ - fun indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): IndexSignatureDeclaration? - fun symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* Identifier? | QualifiedName? */ - fun symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): Expression? - fun symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): NodeArray? - fun symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): ParameterDeclaration? - fun typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeParameterDeclaration? - fun getSymbolsInScope(location: Node, meaning: SymbolFlags): Array - fun getSymbolAtLocation(node: Node): Symbol? - fun getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: String): Array - fun getShorthandAssignmentValueSymbol(location: Node?): Symbol? - fun getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol? - fun getExportSpecifierLocalTargetSymbol(location: Identifier): Symbol? - fun getExportSymbolOfSymbol(symbol: Symbol): Symbol - fun getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol? - fun getTypeOfAssignmentPattern(pattern: ObjectLiteralExpression): Type - fun getTypeOfAssignmentPattern(pattern: ArrayLiteralExpression): Type - fun getTypeAtLocation(node: Node): Type - fun getTypeFromTypeNode(node: TypeNode): Type - fun signatureToString(signature: Signature, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally, kind: SignatureKind = definedExternally): String - fun typeToString(type: Type, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun symbolToString(symbol: Symbol, enclosingDeclaration: Node = definedExternally, meaning: SymbolFlags = definedExternally, flags: SymbolFormatFlags = definedExternally): String - fun typePredicateToString(predicate: ThisTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun typePredicateToString(predicate: ThisTypePredicate): String - fun typePredicateToString(predicate: ThisTypePredicate, enclosingDeclaration: Node = definedExternally): String - fun typePredicateToString(predicate: IdentifierTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun typePredicateToString(predicate: IdentifierTypePredicate): String - fun typePredicateToString(predicate: IdentifierTypePredicate, enclosingDeclaration: Node = definedExternally): String - fun typePredicateToString(predicate: AssertsThisTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun typePredicateToString(predicate: AssertsThisTypePredicate): String - fun typePredicateToString(predicate: AssertsThisTypePredicate, enclosingDeclaration: Node = definedExternally): String - fun typePredicateToString(predicate: AssertsIdentifierTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun typePredicateToString(predicate: AssertsIdentifierTypePredicate): String - fun typePredicateToString(predicate: AssertsIdentifierTypePredicate, enclosingDeclaration: Node = definedExternally): String - fun getFullyQualifiedName(symbol: Symbol): String - fun getAugmentedPropertiesOfType(type: Type): Array - fun getRootSymbols(symbol: Symbol): Array - fun getSymbolOfExpando(node: Node, allowDeclaration: Boolean): Symbol? - fun getContextualType(node: Expression): Type? - fun getResolvedSignature(node: CallExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: CallExpression): Signature? - fun getResolvedSignature(node: CallExpression, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: NewExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: NewExpression): Signature? - fun getResolvedSignature(node: NewExpression, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: TaggedTemplateExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: TaggedTemplateExpression): Signature? - fun getResolvedSignature(node: TaggedTemplateExpression, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: Decorator, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: Decorator): Signature? - fun getResolvedSignature(node: Decorator, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: JsxSelfClosingElement, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: JsxSelfClosingElement): Signature? - fun getResolvedSignature(node: JsxSelfClosingElement, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: JsxOpeningElement, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: JsxOpeningElement): Signature? - fun getResolvedSignature(node: JsxOpeningElement, candidatesOutArray: Array = definedExternally): Signature? - fun getSignatureFromDeclaration(declaration: CallSignatureDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: ConstructSignatureDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: MethodSignature): Signature? - fun getSignatureFromDeclaration(declaration: IndexSignatureDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: FunctionTypeNode): Signature? - fun getSignatureFromDeclaration(declaration: ConstructorTypeNode): Signature? - fun getSignatureFromDeclaration(declaration: JSDocFunctionType): Signature? - fun getSignatureFromDeclaration(declaration: FunctionDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: MethodDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: ConstructorDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: GetAccessorDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: SetAccessorDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: FunctionExpression): Signature? - fun getSignatureFromDeclaration(declaration: ArrowFunction): Signature? - fun isImplementationOfOverload(node: CallSignatureDeclaration): Boolean? - fun isImplementationOfOverload(node: ConstructSignatureDeclaration): Boolean? - fun isImplementationOfOverload(node: MethodSignature): Boolean? - fun isImplementationOfOverload(node: IndexSignatureDeclaration): Boolean? - fun isImplementationOfOverload(node: FunctionTypeNode): Boolean? - fun isImplementationOfOverload(node: ConstructorTypeNode): Boolean? - fun isImplementationOfOverload(node: JSDocFunctionType): Boolean? - fun isImplementationOfOverload(node: FunctionDeclaration): Boolean? - fun isImplementationOfOverload(node: MethodDeclaration): Boolean? - fun isImplementationOfOverload(node: ConstructorDeclaration): Boolean? - fun isImplementationOfOverload(node: GetAccessorDeclaration): Boolean? - fun isImplementationOfOverload(node: SetAccessorDeclaration): Boolean? - fun isImplementationOfOverload(node: FunctionExpression): Boolean? - fun isImplementationOfOverload(node: ArrowFunction): Boolean? - fun isUndefinedSymbol(symbol: Symbol): Boolean - fun isArgumentsSymbol(symbol: Symbol): Boolean - fun isUnknownSymbol(symbol: Symbol): Boolean - fun getConstantValue(node: EnumMember): dynamic /* String? | Number? */ - fun getConstantValue(node: PropertyAccessExpression): dynamic /* String? | Number? */ - fun getConstantValue(node: ElementAccessExpression): dynamic /* String? | Number? */ - fun isValidPropertyAccess(node: PropertyAccessExpression, propertyName: String): Boolean - fun isValidPropertyAccess(node: QualifiedName, propertyName: String): Boolean - fun isValidPropertyAccess(node: ImportTypeNode, propertyName: String): Boolean - fun getAliasedSymbol(symbol: Symbol): Symbol - fun getExportsOfModule(moduleSymbol: Symbol): Array - fun getJsxIntrinsicTagNamesAt(location: Node): Array - fun isOptionalParameter(node: ParameterDeclaration): Boolean - fun getAmbientModules(): Array - fun tryGetMemberInModuleExports(memberName: String, moduleSymbol: Symbol): Symbol? - fun getApparentType(type: Type): Type - fun getBaseConstraintOfType(type: Type): Type? - fun getDefaultFromTypeParameter(type: Type): Type? - fun runWithCancellationToken(token: CancellationToken, cb: (checker: TypeChecker) -> T): T -} - -external enum class NodeBuilderFlags { - None /* = 0 */, - NoTruncation /* = 1 */, - WriteArrayAsGenericType /* = 2 */, - GenerateNamesForShadowedTypeParams /* = 4 */, - UseStructuralFallback /* = 8 */, - ForbidIndexedAccessSymbolReferences /* = 16 */, - WriteTypeArgumentsOfSignature /* = 32 */, - UseFullyQualifiedType /* = 64 */, - UseOnlyExternalAliasing /* = 128 */, - SuppressAnyReturnType /* = 256 */, - WriteTypeParametersInQualifiedName /* = 512 */, - MultilineObjectLiterals /* = 1024 */, - WriteClassExpressionAsTypeLiteral /* = 2048 */, - UseTypeOfFunction /* = 4096 */, - OmitParameterModifiers /* = 8192 */, - UseAliasDefinedOutsideCurrentScope /* = 16384 */, - UseSingleQuotesForStringLiteralType /* = 268435456 */, - NoTypeReduction /* = 536870912 */, - NoUndefinedOptionalParameterType /* = 1073741824 */, - AllowThisInObjectLiteral /* = 32768 */, - AllowQualifiedNameInPlaceOfIdentifier /* = 65536 */, - AllowQualifedNameInPlaceOfIdentifier /* = 65536 */, - AllowAnonymousIdentifier /* = 131072 */, - AllowEmptyUnionOrIntersection /* = 262144 */, - AllowEmptyTuple /* = 524288 */, - AllowUniqueESSymbolType /* = 1048576 */, - AllowEmptyIndexInfoType /* = 2097152 */, - AllowNodeModulesRelativePaths /* = 67108864 */, - IgnoreErrors /* = 70221824 */, - InObjectTypeLiteral /* = 4194304 */, - InTypeAlias /* = 8388608 */, - InInitialEntityName /* = 16777216 */ -} - -external enum class TypeFormatFlags { - None /* = 0 */, - NoTruncation /* = 1 */, - WriteArrayAsGenericType /* = 2 */, - UseStructuralFallback /* = 8 */, - WriteTypeArgumentsOfSignature /* = 32 */, - UseFullyQualifiedType /* = 64 */, - SuppressAnyReturnType /* = 256 */, - MultilineObjectLiterals /* = 1024 */, - WriteClassExpressionAsTypeLiteral /* = 2048 */, - UseTypeOfFunction /* = 4096 */, - OmitParameterModifiers /* = 8192 */, - UseAliasDefinedOutsideCurrentScope /* = 16384 */, - UseSingleQuotesForStringLiteralType /* = 268435456 */, - NoTypeReduction /* = 536870912 */, - AllowUniqueESSymbolType /* = 1048576 */, - AddUndefined /* = 131072 */, - WriteArrowStyleSignature /* = 262144 */, - InArrayType /* = 524288 */, - InElementType /* = 2097152 */, - InFirstTypeArgument /* = 4194304 */, - InTypeAlias /* = 8388608 */, - WriteOwnNameForAnyLike /* = 0 */, - NodeBuilderFlagsMask /* = 814775659 */ -} - -external enum class SymbolFormatFlags { - None /* = 0 */, - WriteTypeParametersOrArguments /* = 1 */, - UseOnlyExternalAliasing /* = 2 */, - AllowAnyNodeKind /* = 4 */, - UseAliasDefinedOutsideCurrentScope /* = 8 */ -} - -external enum class TypePredicateKind { - This /* = 0 */, - Identifier /* = 1 */, - AssertsThis /* = 2 */, - AssertsIdentifier /* = 3 */ -} - -external interface TypePredicateBase { - var kind: TypePredicateKind - var type: Type? -} - -external interface ThisTypePredicate : TypePredicateBase { - var parameterName: Any? - var parameterIndex: Any? -} - -external interface IdentifierTypePredicate : TypePredicateBase { - var parameterName: String - var parameterIndex: Number -} - -external interface AssertsThisTypePredicate : TypePredicateBase { - var parameterName: Any? - var parameterIndex: Any? - override var type: Type? -} - -external interface AssertsIdentifierTypePredicate : TypePredicateBase { - var parameterName: String - var parameterIndex: Number - override var type: Type? -} - -external enum class SymbolFlags { - None /* = 0 */, - FunctionScopedVariable /* = 1 */, - BlockScopedVariable /* = 2 */, - Property /* = 4 */, - EnumMember /* = 8 */, - Function /* = 16 */, - Class /* = 32 */, - Interface /* = 64 */, - ConstEnum /* = 128 */, - RegularEnum /* = 256 */, - ValueModule /* = 512 */, - NamespaceModule /* = 1024 */, - TypeLiteral /* = 2048 */, - ObjectLiteral /* = 4096 */, - Method /* = 8192 */, - Constructor /* = 16384 */, - GetAccessor /* = 32768 */, - SetAccessor /* = 65536 */, - Signature /* = 131072 */, - TypeParameter /* = 262144 */, - TypeAlias /* = 524288 */, - ExportValue /* = 1048576 */, - Alias /* = 2097152 */, - Prototype /* = 4194304 */, - ExportStar /* = 8388608 */, - Optional /* = 16777216 */, - Transient /* = 33554432 */, - Assignment /* = 67108864 */, - ModuleExports /* = 134217728 */, - Enum /* = 384 */, - Variable /* = 3 */, - Value /* = 111551 */, - Type /* = 788968 */, - Namespace /* = 1920 */, - Module /* = 1536 */, - Accessor /* = 98304 */, - FunctionScopedVariableExcludes /* = 111550 */, - BlockScopedVariableExcludes /* = 111551 */, - ParameterExcludes /* = 111551 */, - PropertyExcludes /* = 0 */, - EnumMemberExcludes /* = 900095 */, - FunctionExcludes /* = 110991 */, - ClassExcludes /* = 899503 */, - InterfaceExcludes /* = 788872 */, - RegularEnumExcludes /* = 899327 */, - ConstEnumExcludes /* = 899967 */, - ValueModuleExcludes /* = 110735 */, - NamespaceModuleExcludes /* = 0 */, - MethodExcludes /* = 103359 */, - GetAccessorExcludes /* = 46015 */, - SetAccessorExcludes /* = 78783 */, - TypeParameterExcludes /* = 526824 */, - TypeAliasExcludes /* = 788968 */, - AliasExcludes /* = 2097152 */, - ModuleMember /* = 2623475 */, - ExportHasLocal /* = 944 */, - BlockScoped /* = 418 */, - PropertyOrAccessor /* = 98308 */, - ClassMember /* = 106500 */ -} - -external interface Symbol { - val name: String - fun getFlags(): SymbolFlags - fun getEscapedName(): dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - fun getName(): String - fun getDeclarations(): Array? - fun getDocumentationComment(typeChecker: TypeChecker?): Array - fun getJsDocTags(checker: TypeChecker = definedExternally): Array - var flags: SymbolFlags - var escapedName: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - get() = definedExternally - set(value) = definedExternally - var declarations: Array? - get() = definedExternally - set(value) = definedExternally - var valueDeclaration: Declaration? - get() = definedExternally - set(value) = definedExternally - var members: SymbolTable? - get() = definedExternally - set(value) = definedExternally - var exports: SymbolTable? - get() = definedExternally - set(value) = definedExternally - var globalExports: SymbolTable? - get() = definedExternally - set(value) = definedExternally -} - -external enum class InternalSymbolName { - Call /* = "__call" */, - Constructor /* = "__constructor" */, - New /* = "__new" */, - Index /* = "__index" */, - ExportStar /* = "__export" */, - Global /* = "__global" */, - Missing /* = "__missing" */, - Type /* = "__type" */, - Object /* = "__object" */, - JSXAttributes /* = "__jsxAttributes" */, - Class /* = "__class" */, - Function /* = "__function" */, - Computed /* = "__computed" */, - Resolving /* = "__resolving__" */, - ExportEquals /* = "export=" */, - Default /* = "default" */, - This /* = "this" */ -} - -external interface `T$8` { - var __escapedIdentifier: Unit -} - -external interface ReadonlyUnderscoreEscapedMap : ReadonlyESMap - -external interface UnderscoreEscapedMap : ESMap, ReadonlyUnderscoreEscapedMap - -external enum class TypeFlags { - Any /* = 1 */, - Unknown /* = 2 */, - String /* = 4 */, - Number /* = 8 */, - Boolean /* = 16 */, - Enum /* = 32 */, - BigInt /* = 64 */, - StringLiteral /* = 128 */, - NumberLiteral /* = 256 */, - BooleanLiteral /* = 512 */, - EnumLiteral /* = 1024 */, - BigIntLiteral /* = 2048 */, - ESSymbol /* = 4096 */, - UniqueESSymbol /* = 8192 */, - Void /* = 16384 */, - Undefined /* = 32768 */, - Null /* = 65536 */, - Never /* = 131072 */, - TypeParameter /* = 262144 */, - Object /* = 524288 */, - Union /* = 1048576 */, - Intersection /* = 2097152 */, - Index /* = 4194304 */, - IndexedAccess /* = 8388608 */, - Conditional /* = 16777216 */, - Substitution /* = 33554432 */, - NonPrimitive /* = 67108864 */, - TemplateLiteral /* = 134217728 */, - StringMapping /* = 268435456 */, - Literal /* = 2944 */, - Unit /* = 109440 */, - StringOrNumberLiteral /* = 384 */, - PossiblyFalsy /* = 117724 */, - StringLike /* = 402653316 */, - NumberLike /* = 296 */, - BigIntLike /* = 2112 */, - BooleanLike /* = 528 */, - EnumLike /* = 1056 */, - ESSymbolLike /* = 12288 */, - VoidLike /* = 49152 */, - UnionOrIntersection /* = 3145728 */, - StructuredType /* = 3670016 */, - TypeVariable /* = 8650752 */, - InstantiableNonPrimitive /* = 58982400 */, - InstantiablePrimitive /* = 406847488 */, - Instantiable /* = 465829888 */, - StructuredOrInstantiable /* = 469499904 */, - Narrowable /* = 536624127 */ -} - -external interface Type { - fun getFlags(): TypeFlags - fun getSymbol(): Symbol? - fun getProperties(): Array - fun getProperty(propertyName: String): Symbol? - fun getApparentProperties(): Array - fun getCallSignatures(): Array - fun getConstructSignatures(): Array - fun getStringIndexType(): Type? - fun getNumberIndexType(): Type? - fun getBaseTypes(): Array? - fun getNonNullableType(): Type - fun getConstraint(): Type? - fun getDefault(): Type? - fun isUnion(): Boolean - fun isIntersection(): Boolean - fun isUnionOrIntersection(): Boolean - fun isLiteral(): Boolean - fun isStringLiteral(): Boolean - fun isNumberLiteral(): Boolean - fun isTypeParameter(): Boolean - fun isClassOrInterface(): Boolean - fun isClass(): Boolean - var flags: TypeFlags - var symbol: Symbol - var pattern: dynamic /* ObjectBindingPattern? | ArrayBindingPattern? | ObjectLiteralExpression? | ArrayLiteralExpression? */ - get() = definedExternally - set(value) = definedExternally - var aliasSymbol: Symbol? - get() = definedExternally - set(value) = definedExternally - var aliasTypeArguments: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface LiteralType : Type { - var value: dynamic /* String | Number | PseudoBigInt */ - get() = definedExternally - set(value) = definedExternally - var freshType: LiteralType - var regularType: LiteralType -} - -external interface UniqueESSymbolType : Type { - override var symbol: Symbol - var escapedName: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - get() = definedExternally - set(value) = definedExternally -} - -external interface StringLiteralType : LiteralType { - override var value: String -} - -external interface NumberLiteralType : LiteralType { - override var value: Number -} - -external interface BigIntLiteralType : LiteralType { - override var value: PseudoBigInt -} - -external interface EnumType : Type - -external enum class ObjectFlags { - Class /* = 1 */, - Interface /* = 2 */, - Reference /* = 4 */, - Tuple /* = 8 */, - Anonymous /* = 16 */, - Mapped /* = 32 */, - Instantiated /* = 64 */, - ObjectLiteral /* = 128 */, - EvolvingArray /* = 256 */, - ObjectLiteralPatternWithComputedProperties /* = 512 */, - ReverseMapped /* = 1024 */, - JsxAttributes /* = 2048 */, - MarkerType /* = 4096 */, - JSLiteral /* = 8192 */, - FreshLiteral /* = 16384 */, - ArrayLiteral /* = 32768 */, - ClassOrInterface /* = 3 */, - ContainsSpread /* = 4194304 */, - ObjectRestType /* = 8388608 */ -} - -external interface ObjectType : Type { - var objectFlags: ObjectFlags -} - -external interface InterfaceType : ObjectType { - var typeParameters: Array? - var outerTypeParameters: Array? - var localTypeParameters: Array? - var thisType: TypeParameter? -} - -external interface InterfaceTypeWithDeclaredMembers : InterfaceType { - var declaredProperties: Array - var declaredCallSignatures: Array - var declaredConstructSignatures: Array - var declaredStringIndexInfo: IndexInfo? - get() = definedExternally - set(value) = definedExternally - var declaredNumberIndexInfo: IndexInfo? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeReference : ObjectType { - var typeArguments: Array? - get() = definedExternally - set(value) = definedExternally - var target: GenericType - var node: dynamic /* TypeReferenceNode? | ArrayTypeNode? | TupleTypeNode? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface DeferredTypeReference : TypeReference - -external interface GenericType : InterfaceType, TypeReference - -external enum class ElementFlags { - Required /* = 1 */, - Optional /* = 2 */, - Rest /* = 4 */, - Variadic /* = 8 */, - Fixed /* = 3 */, - Variable /* = 12 */, - NonRequired /* = 14 */, - NonRest /* = 11 */ -} - -external interface TupleType : GenericType { - var elementFlags: Array - var minLength: Number - var fixedLength: Number - var hasRestElement: Boolean - var combinedFlags: ElementFlags - var readonly: Boolean - var labeledElementDeclarations: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface TupleTypeReference : TypeReference { - override var target: TupleType -} - -external interface UnionOrIntersectionType : Type { - var types: Array -} - -external interface UnionType : UnionOrIntersectionType - -external interface IntersectionType : UnionOrIntersectionType - -external interface EvolvingArrayType : ObjectType { - var elementType: Type - var finalArrayType: Type? - get() = definedExternally - set(value) = definedExternally -} - -external interface InstantiableType : Type - -external interface TypeParameter : InstantiableType - -external interface IndexedAccessType : InstantiableType { - var objectType: Type - var indexType: Type - var constraint: Type? - get() = definedExternally - set(value) = definedExternally - var simplifiedForReading: Type? - get() = definedExternally - set(value) = definedExternally - var simplifiedForWriting: Type? - get() = definedExternally - set(value) = definedExternally -} - -external interface IndexType : InstantiableType { - var type: dynamic /* InstantiableType | UnionOrIntersectionType */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ConditionalRoot { - var node: ConditionalTypeNode - var checkType: Type - var extendsType: Type - var isDistributive: Boolean - var inferTypeParameters: Array? - get() = definedExternally - set(value) = definedExternally - var outerTypeParameters: Array? - get() = definedExternally - set(value) = definedExternally - var instantiations: Map? - get() = definedExternally - set(value) = definedExternally - var aliasSymbol: Symbol? - get() = definedExternally - set(value) = definedExternally - var aliasTypeArguments: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface ConditionalType : InstantiableType { - var root: ConditionalRoot - var checkType: Type - var extendsType: Type - var resolvedTrueType: Type - var resolvedFalseType: Type -} - -external interface TemplateLiteralType : InstantiableType { - var texts: Array - var types: Array -} - -external interface StringMappingType : InstantiableType { - override var symbol: Symbol - var type: Type -} - -external interface SubstitutionType : InstantiableType { - var objectFlags: ObjectFlags - var baseType: Type - var substitute: Type -} - -external enum class SignatureKind { - Call /* = 0 */, - Construct /* = 1 */ -} - -external interface Signature { - fun getDeclaration(): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ - fun getTypeParameters(): Array? - fun getParameters(): Array - fun getReturnType(): Type - fun getDocumentationComment(typeChecker: TypeChecker?): Array - fun getJsDocTags(): Array - var declaration: dynamic /* CallSignatureDeclaration? | ConstructSignatureDeclaration? | MethodSignature? | IndexSignatureDeclaration? | FunctionTypeNode? | ConstructorTypeNode? | JSDocFunctionType? | FunctionDeclaration? | MethodDeclaration? | ConstructorDeclaration? | GetAccessorDeclaration? | SetAccessorDeclaration? | FunctionExpression? | ArrowFunction? | JSDocSignature? */ - get() = definedExternally - set(value) = definedExternally - var typeParameters: Array? - get() = definedExternally - set(value) = definedExternally - var parameters: Array -} - -external enum class IndexKind { - String /* = 0 */, - Number /* = 1 */ -} - -external interface IndexInfo { - var type: Type - var isReadonly: Boolean - var declaration: IndexSignatureDeclaration? - get() = definedExternally - set(value) = definedExternally -} - -external enum class InferencePriority { - NakedTypeVariable /* = 1 */, - SpeculativeTuple /* = 2 */, - SubstituteSource /* = 4 */, - HomomorphicMappedType /* = 8 */, - PartialHomomorphicMappedType /* = 16 */, - MappedTypeConstraint /* = 32 */, - ContravariantConditional /* = 64 */, - ReturnType /* = 128 */, - LiteralKeyof /* = 256 */, - NoConstraints /* = 512 */, - AlwaysStrict /* = 1024 */, - MaxValue /* = 2048 */, - PriorityImpliesCombination /* = 416 */, - Circularity /* = -1 */ -} - -external interface FileExtensionInfo { - var extension: String - var isMixedContent: Boolean - var scriptKind: ScriptKind? - get() = definedExternally - set(value) = definedExternally -} - -external interface DiagnosticMessage { - var key: String - var category: DiagnosticCategory - var code: Number - var message: String - var reportsUnnecessary: Any? - get() = definedExternally - set(value) = definedExternally - var reportsDeprecated: Any? - get() = definedExternally - set(value) = definedExternally -} - -external interface DiagnosticMessageChain { - var messageText: String - var category: DiagnosticCategory - var code: Number - var next: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface Diagnostic : DiagnosticRelatedInformation { - var reportsUnnecessary: Any? - get() = definedExternally - set(value) = definedExternally - var reportsDeprecated: Any? - get() = definedExternally - set(value) = definedExternally - var source: String? - get() = definedExternally - set(value) = definedExternally - var relatedInformation: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface DiagnosticRelatedInformation { - var category: DiagnosticCategory - var code: Number - var file: SourceFile? - var start: Number? - var length: Number? - var messageText: dynamic /* String | DiagnosticMessageChain */ - get() = definedExternally - set(value) = definedExternally -} - -external interface DiagnosticWithLocation : Diagnostic - -external enum class DiagnosticCategory { - Warning /* = 0 */, - Error /* = 1 */, - Suggestion /* = 2 */, - Message /* = 3 */ -} - -external enum class ModuleResolutionKind { - Classic /* = 1 */, - NodeJs /* = 2 */ -} - -external interface PluginImport { - var name: String -} - -external interface ProjectReference { - var path: String - var originalPath: String? - get() = definedExternally - set(value) = definedExternally - var prepend: Boolean? - get() = definedExternally - set(value) = definedExternally - var circular: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external enum class WatchFileKind { - FixedPollingInterval /* = 0 */, - PriorityPollingInterval /* = 1 */, - DynamicPriorityPolling /* = 2 */, - FixedChunkSizePolling /* = 3 */, - UseFsEvents /* = 4 */, - UseFsEventsOnParentDirectory /* = 5 */ -} - -external enum class WatchDirectoryKind { - UseFsEvents /* = 0 */, - FixedPollingInterval /* = 1 */, - DynamicPriorityPolling /* = 2 */, - FixedChunkSizePolling /* = 3 */ -} - -external enum class PollingWatchKind { - FixedInterval /* = 0 */, - PriorityInterval /* = 1 */, - DynamicPriority /* = 2 */, - FixedChunkSize /* = 3 */ -} - -external interface CompilerOptions { - var allowJs: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowSyntheticDefaultImports: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowUmdGlobalAccess: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowUnreachableCode: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowUnusedLabels: Boolean? - get() = definedExternally - set(value) = definedExternally - var alwaysStrict: Boolean? - get() = definedExternally - set(value) = definedExternally - var baseUrl: String? - get() = definedExternally - set(value) = definedExternally - var charset: String? - get() = definedExternally - set(value) = definedExternally - var checkJs: Boolean? - get() = definedExternally - set(value) = definedExternally - var declaration: Boolean? - get() = definedExternally - set(value) = definedExternally - var declarationMap: Boolean? - get() = definedExternally - set(value) = definedExternally - var emitDeclarationOnly: Boolean? - get() = definedExternally - set(value) = definedExternally - var declarationDir: String? - get() = definedExternally - set(value) = definedExternally - var disableSizeLimit: Boolean? - get() = definedExternally - set(value) = definedExternally - var disableSourceOfProjectReferenceRedirect: Boolean? - get() = definedExternally - set(value) = definedExternally - var disableSolutionSearching: Boolean? - get() = definedExternally - set(value) = definedExternally - var disableReferencedProjectLoad: Boolean? - get() = definedExternally - set(value) = definedExternally - var downlevelIteration: Boolean? - get() = definedExternally - set(value) = definedExternally - var emitBOM: Boolean? - get() = definedExternally - set(value) = definedExternally - var emitDecoratorMetadata: Boolean? - get() = definedExternally - set(value) = definedExternally - var experimentalDecorators: Boolean? - get() = definedExternally - set(value) = definedExternally - var forceConsistentCasingInFileNames: Boolean? - get() = definedExternally - set(value) = definedExternally - var importHelpers: Boolean? - get() = definedExternally - set(value) = definedExternally - var importsNotUsedAsValues: ImportsNotUsedAsValues? - get() = definedExternally - set(value) = definedExternally - var inlineSourceMap: Boolean? - get() = definedExternally - set(value) = definedExternally - var inlineSources: Boolean? - get() = definedExternally - set(value) = definedExternally - var isolatedModules: Boolean? - get() = definedExternally - set(value) = definedExternally - var jsx: JsxEmit? - get() = definedExternally - set(value) = definedExternally - var keyofStringsOnly: Boolean? - get() = definedExternally - set(value) = definedExternally - var lib: Array? - get() = definedExternally - set(value) = definedExternally - var locale: String? - get() = definedExternally - set(value) = definedExternally - var mapRoot: String? - get() = definedExternally - set(value) = definedExternally - var maxNodeModuleJsDepth: Number? - get() = definedExternally - set(value) = definedExternally - var module: ModuleKind? - get() = definedExternally - set(value) = definedExternally - var moduleResolution: ModuleResolutionKind? - get() = definedExternally - set(value) = definedExternally - var newLine: NewLineKind? - get() = definedExternally - set(value) = definedExternally - var noEmit: Boolean? - get() = definedExternally - set(value) = definedExternally - var noEmitHelpers: Boolean? - get() = definedExternally - set(value) = definedExternally - var noEmitOnError: Boolean? - get() = definedExternally - set(value) = definedExternally - var noErrorTruncation: Boolean? - get() = definedExternally - set(value) = definedExternally - var noFallthroughCasesInSwitch: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitAny: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitReturns: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitThis: Boolean? - get() = definedExternally - set(value) = definedExternally - var noStrictGenericChecks: Boolean? - get() = definedExternally - set(value) = definedExternally - var noUnusedLocals: Boolean? - get() = definedExternally - set(value) = definedExternally - var noUnusedParameters: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitUseStrict: Boolean? - get() = definedExternally - set(value) = definedExternally - var noPropertyAccessFromIndexSignature: Boolean? - get() = definedExternally - set(value) = definedExternally - var assumeChangesOnlyAffectDirectDependencies: Boolean? - get() = definedExternally - set(value) = definedExternally - var noLib: Boolean? - get() = definedExternally - set(value) = definedExternally - var noResolve: Boolean? - get() = definedExternally - set(value) = definedExternally - var noUncheckedIndexedAccess: Boolean? - get() = definedExternally - set(value) = definedExternally - var out: String? - get() = definedExternally - set(value) = definedExternally - var outDir: String? - get() = definedExternally - set(value) = definedExternally - var outFile: String? - get() = definedExternally - set(value) = definedExternally - var paths: MapLike>? - get() = definedExternally - set(value) = definedExternally - var preserveConstEnums: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitOverride: Boolean? - get() = definedExternally - set(value) = definedExternally - var preserveSymlinks: Boolean? - get() = definedExternally - set(value) = definedExternally - var project: String? - get() = definedExternally - set(value) = definedExternally - var reactNamespace: String? - get() = definedExternally - set(value) = definedExternally - var jsxFactory: String? - get() = definedExternally - set(value) = definedExternally - var jsxFragmentFactory: String? - get() = definedExternally - set(value) = definedExternally - var jsxImportSource: String? - get() = definedExternally - set(value) = definedExternally - var composite: Boolean? - get() = definedExternally - set(value) = definedExternally - var incremental: Boolean? - get() = definedExternally - set(value) = definedExternally - var tsBuildInfoFile: String? - get() = definedExternally - set(value) = definedExternally - var removeComments: Boolean? - get() = definedExternally - set(value) = definedExternally - var rootDir: String? - get() = definedExternally - set(value) = definedExternally - var rootDirs: Array? - get() = definedExternally - set(value) = definedExternally - var skipLibCheck: Boolean? - get() = definedExternally - set(value) = definedExternally - var skipDefaultLibCheck: Boolean? - get() = definedExternally - set(value) = definedExternally - var sourceMap: Boolean? - get() = definedExternally - set(value) = definedExternally - var sourceRoot: String? - get() = definedExternally - set(value) = definedExternally - var strict: Boolean? - get() = definedExternally - set(value) = definedExternally - var strictFunctionTypes: Boolean? - get() = definedExternally - set(value) = definedExternally - var strictBindCallApply: Boolean? - get() = definedExternally - set(value) = definedExternally - var strictNullChecks: Boolean? - get() = definedExternally - set(value) = definedExternally - var strictPropertyInitialization: Boolean? - get() = definedExternally - set(value) = definedExternally - var stripInternal: Boolean? - get() = definedExternally - set(value) = definedExternally - var suppressExcessPropertyErrors: Boolean? - get() = definedExternally - set(value) = definedExternally - var suppressImplicitAnyIndexErrors: Boolean? - get() = definedExternally - set(value) = definedExternally - var target: ScriptTarget? - get() = definedExternally - set(value) = definedExternally - var traceResolution: Boolean? - get() = definedExternally - set(value) = definedExternally - var resolveJsonModule: Boolean? - get() = definedExternally - set(value) = definedExternally - var types: Array? - get() = definedExternally - set(value) = definedExternally - var typeRoots: Array? - get() = definedExternally - set(value) = definedExternally - var esModuleInterop: Boolean? - get() = definedExternally - set(value) = definedExternally - var useDefineForClassFields: Boolean? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? | TsConfigSourceFile? */ - @nativeSetter - operator fun set(option: String, value: String?) - @nativeSetter - operator fun set(option: String, value: Number?) - @nativeSetter - operator fun set(option: String, value: Boolean?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: MapLike>?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: TsConfigSourceFile?) -} - -external interface WatchOptions { - var watchFile: WatchFileKind? - get() = definedExternally - set(value) = definedExternally - var watchDirectory: WatchDirectoryKind? - get() = definedExternally - set(value) = definedExternally - var fallbackPolling: PollingWatchKind? - get() = definedExternally - set(value) = definedExternally - var synchronousWatchDirectory: Boolean? - get() = definedExternally - set(value) = definedExternally - var excludeDirectories: Array? - get() = definedExternally - set(value) = definedExternally - var excludeFiles: Array? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ - @nativeSetter - operator fun set(option: String, value: String?) - @nativeSetter - operator fun set(option: String, value: Number?) - @nativeSetter - operator fun set(option: String, value: Boolean?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: MapLike>?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) -} - -external interface TypeAcquisition { - var enableAutoDiscovery: Boolean? - get() = definedExternally - set(value) = definedExternally - var enable: Boolean? - get() = definedExternally - set(value) = definedExternally - var include: Array? - get() = definedExternally - set(value) = definedExternally - var exclude: Array? - get() = definedExternally - set(value) = definedExternally - var disableFilenameBasedTypeAcquisition: Boolean? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ - @nativeSetter - operator fun set(option: String, value: String?) - @nativeSetter - operator fun set(option: String, value: Number?) - @nativeSetter - operator fun set(option: String, value: Boolean?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: MapLike>?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) -} - -external enum class ModuleKind { - None /* = 0 */, - CommonJS /* = 1 */, - AMD /* = 2 */, - UMD /* = 3 */, - System /* = 4 */, - ES2015 /* = 5 */, - ES2020 /* = 6 */, - ESNext /* = 99 */ -} - -external enum class JsxEmit { - None /* = 0 */, - Preserve /* = 1 */, - React /* = 2 */, - ReactNative /* = 3 */, - ReactJSX /* = 4 */, - ReactJSXDev /* = 5 */ -} - -external enum class ImportsNotUsedAsValues { - Remove /* = 0 */, - Preserve /* = 1 */, - Error /* = 2 */ -} - -external enum class NewLineKind { - CarriageReturnLineFeed /* = 0 */, - LineFeed /* = 1 */ -} - -external interface LineAndCharacter { - var line: Number - var character: Number -} - -external enum class ScriptKind { - Unknown /* = 0 */, - JS /* = 1 */, - JSX /* = 2 */, - TS /* = 3 */, - TSX /* = 4 */, - External /* = 5 */, - JSON /* = 6 */, - Deferred /* = 7 */ -} - -external enum class ScriptTarget { - ES3 /* = 0 */, - ES5 /* = 1 */, - ES2015 /* = 2 */, - ES2016 /* = 3 */, - ES2017 /* = 4 */, - ES2018 /* = 5 */, - ES2019 /* = 6 */, - ES2020 /* = 7 */, - ES2021 /* = 8 */, - ESNext /* = 99 */, - JSON /* = 100 */, - Latest /* = 99 */ -} - -external enum class LanguageVariant { - Standard /* = 0 */, - JSX /* = 1 */ -} - -external interface ParsedCommandLine { - var options: CompilerOptions - var typeAcquisition: TypeAcquisition? - get() = definedExternally - set(value) = definedExternally - var fileNames: Array - var projectReferences: Array? - get() = definedExternally - set(value) = definedExternally - var watchOptions: WatchOptions? - get() = definedExternally - set(value) = definedExternally - var raw: Any? - get() = definedExternally - set(value) = definedExternally - var errors: Array - var wildcardDirectories: MapLike? - get() = definedExternally - set(value) = definedExternally - var compileOnSave: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external enum class WatchDirectoryFlags { - None /* = 0 */, - Recursive /* = 1 */ -} - -external interface CreateProgramOptions { - var rootNames: Array - var options: CompilerOptions - var projectReferences: Array? - get() = definedExternally - set(value) = definedExternally - var host: CompilerHost? - get() = definedExternally - set(value) = definedExternally - var oldProgram: Program? - get() = definedExternally - set(value) = definedExternally - var configFileParsingDiagnostics: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface ModuleResolutionHost { - fun fileExists(fileName: String): Boolean - fun readFile(fileName: String): String? - val trace: ((s: String) -> Unit)? - val directoryExists: ((directoryName: String) -> Boolean)? - val realpath: ((path: String) -> String)? - val getCurrentDirectory: (() -> String)? - val getDirectories: ((path: String) -> Array)? -} - -external interface ResolvedModule { - var resolvedFileName: String - var isExternalLibraryImport: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedModuleFull : ResolvedModule { - var extension: Extension - var packageId: PackageId? - get() = definedExternally - set(value) = definedExternally -} - -external interface PackageId { - var name: String - var subModuleName: String - var version: String -} - -external enum class Extension { - Ts /* = ".ts" */, - Tsx /* = ".tsx" */, - Dts /* = ".d.ts" */, - Js /* = ".js" */, - Jsx /* = ".jsx" */, - Json /* = ".json" */, - TsBuildInfo /* = ".tsbuildinfo" */ -} - -external interface ResolvedModuleWithFailedLookupLocations { - val resolvedModule: ResolvedModuleFull? -} - -external interface ResolvedTypeReferenceDirective { - var primary: Boolean - var resolvedFileName: String? - var packageId: PackageId? - get() = definedExternally - set(value) = definedExternally - var isExternalLibraryImport: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations { - val resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective? - val failedLookupLocations: Array -} - -external interface CompilerHost : ModuleResolutionHost { - fun getSourceFile(fileName: String, languageVersion: ScriptTarget, onError: (message: String) -> Unit = definedExternally, shouldCreateNewSourceFile: Boolean = definedExternally): SourceFile? - val getSourceFileByPath: ((fileName: String, path: String /* String & `T$3` */, languageVersion: ScriptTarget, onError: (message: String) -> Unit, shouldCreateNewSourceFile: Boolean) -> SourceFile?)? - val getCancellationToken: (() -> CancellationToken)? - fun getDefaultLibFileName(options: CompilerOptions): String - val getDefaultLibLocation: (() -> String)? - var writeFile: WriteFileCallback - override var getCurrentDirectory: () -> String - fun getCanonicalFileName(fileName: String): String - fun useCaseSensitiveFileNames(): Boolean - fun getNewLine(): String - val readDirectory: ((rootDir: String, extensions: Array, excludes: Array?, includes: Array, depth: Number) -> Array)? - val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val getEnvironmentVariable: ((name: String) -> String?)? - val createHash: ((data: String) -> String)? - val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? -} - -external interface SourceMapRange : TextRange { - var source: SourceMapSource? - get() = definedExternally - set(value) = definedExternally -} - -external interface SourceMapSource { - fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter - var fileName: String - var text: String - var skipTrivia: ((pos: Number) -> Number)? - get() = definedExternally - set(value) = definedExternally -} - -external enum class EmitFlags { - None /* = 0 */, - SingleLine /* = 1 */, - AdviseOnEmitNode /* = 2 */, - NoSubstitution /* = 4 */, - CapturesThis /* = 8 */, - NoLeadingSourceMap /* = 16 */, - NoTrailingSourceMap /* = 32 */, - NoSourceMap /* = 48 */, - NoNestedSourceMaps /* = 64 */, - NoTokenLeadingSourceMaps /* = 128 */, - NoTokenTrailingSourceMaps /* = 256 */, - NoTokenSourceMaps /* = 384 */, - NoLeadingComments /* = 512 */, - NoTrailingComments /* = 1024 */, - NoComments /* = 1536 */, - NoNestedComments /* = 2048 */, - HelperName /* = 4096 */, - ExportName /* = 8192 */, - LocalName /* = 16384 */, - InternalName /* = 32768 */, - Indented /* = 65536 */, - NoIndentation /* = 131072 */, - AsyncFunctionBody /* = 262144 */, - ReuseTempVariableScope /* = 524288 */, - CustomPrologue /* = 1048576 */, - NoHoisting /* = 2097152 */, - HasEndOfDeclarationMarker /* = 4194304 */, - Iterator /* = 8388608 */, - NoAsciiEscaping /* = 16777216 */ -} - -external interface EmitHelperBase { - val name: String - val scoped: Boolean - val text: dynamic /* String | (node: EmitHelperUniqueNameCallback) -> String */ - get() = definedExternally - val priority: Number? - get() = definedExternally - val dependencies: Array? - get() = definedExternally -} - -external interface ScopedEmitHelper : EmitHelperBase { - override val scoped: Boolean -} - -external interface UnscopedEmitHelper : EmitHelperBase { - override val scoped: Boolean - override val text: String -} - -external enum class EmitHint { - SourceFile /* = 0 */, - Expression /* = 1 */, - IdentifierName /* = 2 */, - MappedTypeParameter /* = 3 */, - Unspecified /* = 4 */, - EmbeddedStatement /* = 5 */, - JsxAttributeValue /* = 6 */ -} - -external enum class OuterExpressionKinds { - Parentheses /* = 1 */, - TypeAssertions /* = 2 */, - NonNullAssertions /* = 4 */, - PartiallyEmittedExpressions /* = 8 */, - Assertions /* = 6 */, - All /* = 15 */ -} - -external interface NodeFactory { - fun createNodeArray(elements: Array = definedExternally, hasTrailingComma: Boolean = definedExternally): NodeArray - fun createNumericLiteral(value: String, numericLiteralFlags: TokenFlags = definedExternally): NumericLiteral - fun createNumericLiteral(value: String): NumericLiteral - fun createNumericLiteral(value: Number, numericLiteralFlags: TokenFlags = definedExternally): NumericLiteral - fun createNumericLiteral(value: Number): NumericLiteral - fun createBigIntLiteral(value: String): BigIntLiteral - fun createBigIntLiteral(value: PseudoBigInt): BigIntLiteral - fun createStringLiteral(text: String, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: Identifier, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: Identifier): StringLiteral - fun createStringLiteralFromNode(sourceNode: StringLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: StringLiteral): StringLiteral - fun createStringLiteralFromNode(sourceNode: NoSubstitutionTemplateLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: NoSubstitutionTemplateLiteral): StringLiteral - fun createStringLiteralFromNode(sourceNode: NumericLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: NumericLiteral): StringLiteral - fun createRegularExpressionLiteral(text: String): RegularExpressionLiteral - fun createIdentifier(text: String): Identifier - fun createTempVariable(recordTempVariable: ((node: Identifier) -> Unit)?, reservedInNestedScopes: Boolean = definedExternally): Identifier - fun createLoopVariable(reservedInNestedScopes: Boolean = definedExternally): Identifier - fun createUniqueName(text: String, flags: GeneratedIdentifierFlags = definedExternally): Identifier - fun getGeneratedNameForNode(node: Node?, flags: GeneratedIdentifierFlags = definedExternally): Identifier - fun createPrivateIdentifier(text: String): PrivateIdentifier - fun createToken(token: SyntaxKind.SuperKeyword): SuperExpression - fun createToken(token: SyntaxKind.ThisKeyword): ThisExpression - fun createToken(token: SyntaxKind.NullKeyword): NullLiteral - fun createToken(token: SyntaxKind.TrueKeyword): TrueLiteral - fun createToken(token: SyntaxKind.FalseKeyword): FalseLiteral - fun createToken(token: TKind): dynamic /* Token */ - fun createSuper(): SuperExpression - fun createThis(): ThisExpression - fun createNull(): NullLiteral - fun createTrue(): TrueLiteral - fun createFalse(): FalseLiteral - fun createModifier(kind: T): ModifierToken - fun createModifiersFromModifierFlags(flags: ModifierFlags): Array - fun createQualifiedName(left: Identifier, right: String): QualifiedName - fun createQualifiedName(left: Identifier, right: Identifier): QualifiedName - fun createQualifiedName(left: QualifiedName, right: String): QualifiedName - fun createQualifiedName(left: QualifiedName, right: Identifier): QualifiedName - fun updateQualifiedName(node: QualifiedName, left: Identifier, right: Identifier): QualifiedName - fun updateQualifiedName(node: QualifiedName, left: QualifiedName, right: Identifier): QualifiedName - fun createComputedPropertyName(expression: Expression): ComputedPropertyName - fun updateComputedPropertyName(node: ComputedPropertyName, expression: Expression): ComputedPropertyName - fun createTypeParameterDeclaration(name: String, constraint: TypeNode = definedExternally, defaultType: TypeNode = definedExternally): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: String): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: String, constraint: TypeNode = definedExternally): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: Identifier, constraint: TypeNode = definedExternally, defaultType: TypeNode = definedExternally): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: Identifier): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: Identifier, constraint: TypeNode = definedExternally): TypeParameterDeclaration - fun updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode?, defaultType: TypeNode?): TypeParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration - fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration - fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration - fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration - fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration - fun createDecorator(expression: Expression): Decorator - fun updateDecorator(node: Decorator, expression: Expression): Decorator - fun createPropertySignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: String, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createMethodSignature(modifiers: Array?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createConstructorDeclaration(decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration - fun updateConstructorDeclaration(node: ConstructorDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun createCallSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): CallSignatureDeclaration - fun updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): CallSignatureDeclaration - fun createConstructSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): ConstructSignatureDeclaration - fun updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): ConstructSignatureDeclaration - fun createIndexSignature(decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration - fun updateIndexSignature(node: IndexSignatureDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration - fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan - fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan - fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan - fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan - fun createKeywordTypeNode(kind: TKind): KeywordTypeNode - fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode - fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode - fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: String, type: TypeNode?): TypePredicateNode - fun updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode - fun updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode - fun createTypeReferenceNode(typeName: String, typeArguments: Array = definedExternally): TypeReferenceNode - fun createTypeReferenceNode(typeName: String): TypeReferenceNode - fun createTypeReferenceNode(typeName: Identifier, typeArguments: Array = definedExternally): TypeReferenceNode - fun createTypeReferenceNode(typeName: Identifier): TypeReferenceNode - fun createTypeReferenceNode(typeName: QualifiedName, typeArguments: Array = definedExternally): TypeReferenceNode - fun createTypeReferenceNode(typeName: QualifiedName): TypeReferenceNode - fun updateTypeReferenceNode(node: TypeReferenceNode, typeName: Identifier, typeArguments: NodeArray?): TypeReferenceNode - fun updateTypeReferenceNode(node: TypeReferenceNode, typeName: QualifiedName, typeArguments: NodeArray?): TypeReferenceNode - fun createFunctionTypeNode(typeParameters: Array?, parameters: Array, type: TypeNode): FunctionTypeNode - fun updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): FunctionTypeNode - fun createConstructorTypeNode(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode): ConstructorTypeNode - fun createConstructorTypeNode(typeParameters: Array?, parameters: Array, type: TypeNode): ConstructorTypeNode - fun updateConstructorTypeNode(node: ConstructorTypeNode, modifiers: Array?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): ConstructorTypeNode - fun updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): ConstructorTypeNode - fun createTypeQueryNode(exprName: Identifier): TypeQueryNode - fun createTypeQueryNode(exprName: QualifiedName): TypeQueryNode - fun updateTypeQueryNode(node: TypeQueryNode, exprName: Identifier): TypeQueryNode - fun updateTypeQueryNode(node: TypeQueryNode, exprName: QualifiedName): TypeQueryNode - fun createTypeLiteralNode(members: Array?): TypeLiteralNode - fun updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray): TypeLiteralNode - fun createArrayTypeNode(elementType: TypeNode): ArrayTypeNode - fun updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode - fun createTupleTypeNode(elements: Array): TupleTypeNode - fun updateTupleTypeNode(node: TupleTypeNode, elements: Array): TupleTypeNode - fun createNamedTupleMember(dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode): NamedTupleMember - fun updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode): NamedTupleMember - fun createOptionalTypeNode(type: TypeNode): OptionalTypeNode - fun updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode - fun createRestTypeNode(type: TypeNode): RestTypeNode - fun updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode - fun createUnionTypeNode(types: Array): UnionTypeNode - fun updateUnionTypeNode(node: UnionTypeNode, types: NodeArray): UnionTypeNode - fun createIntersectionTypeNode(types: Array): IntersectionTypeNode - fun updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray): IntersectionTypeNode - fun createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode - fun updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode - fun createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode - fun updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally, typeArguments: Array = definedExternally, isTypeOf: Boolean = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally, typeArguments: Array = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally, typeArguments: Array = definedExternally, isTypeOf: Boolean = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally, typeArguments: Array = definedExternally): ImportTypeNode - fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: Identifier?, typeArguments: Array?, isTypeOf: Boolean = definedExternally): ImportTypeNode - fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: Identifier?, typeArguments: Array?): ImportTypeNode - fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: QualifiedName?, typeArguments: Array?, isTypeOf: Boolean = definedExternally): ImportTypeNode - fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: QualifiedName?, typeArguments: Array?): ImportTypeNode - fun createParenthesizedType(type: TypeNode): ParenthesizedTypeNode - fun updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode - fun createThisTypeNode(): ThisTypeNode - fun createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword, type: TypeNode): TypeOperatorNode - fun createTypeOperatorNode(operator: SyntaxKind.UniqueKeyword, type: TypeNode): TypeOperatorNode - fun createTypeOperatorNode(operator: SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode - fun updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode - fun createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode - fun updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode - fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun createLiteralTypeNode(literal: NullLiteral): LiteralTypeNode - fun createLiteralTypeNode(literal: TrueLiteral): LiteralTypeNode - fun createLiteralTypeNode(literal: FalseLiteral): LiteralTypeNode - fun createLiteralTypeNode(literal: LiteralExpression): LiteralTypeNode - fun createLiteralTypeNode(literal: PrefixUnaryExpression): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: NullLiteral): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: TrueLiteral): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: FalseLiteral): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralExpression): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: PrefixUnaryExpression): LiteralTypeNode - fun createTemplateLiteralType(head: TemplateHead, templateSpans: Array): TemplateLiteralTypeNode - fun updateTemplateLiteralType(node: TemplateLiteralTypeNode, head: TemplateHead, templateSpans: Array): TemplateLiteralTypeNode - fun createObjectBindingPattern(elements: Array): ObjectBindingPattern - fun updateObjectBindingPattern(node: ObjectBindingPattern, elements: Array): ObjectBindingPattern - fun createArrayBindingPattern(elements: Array): ArrayBindingPattern - fun updateArrayBindingPattern(node: ArrayBindingPattern, elements: Array): ArrayBindingPattern - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: String?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: String?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun createArrayLiteralExpression(elements: Array = definedExternally, multiLine: Boolean = definedExternally): ArrayLiteralExpression - fun updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: Array): ArrayLiteralExpression - fun createObjectLiteralExpression(properties: Array = definedExternally, multiLine: Boolean = definedExternally): ObjectLiteralExpression - fun updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: Array): ObjectLiteralExpression - fun createPropertyAccessExpression(expression: Expression, name: String): PropertyAccessExpression - fun createPropertyAccessExpression(expression: Expression, name: Identifier): PropertyAccessExpression - fun createPropertyAccessExpression(expression: Expression, name: PrivateIdentifier): PropertyAccessExpression - fun updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier): PropertyAccessExpression - fun updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: PrivateIdentifier): PropertyAccessExpression - fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: String): PropertyAccessChain - fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: Identifier): PropertyAccessChain - fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: PrivateIdentifier): PropertyAccessChain - fun updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: Identifier): PropertyAccessChain - fun updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: PrivateIdentifier): PropertyAccessChain - fun createElementAccessExpression(expression: Expression, index: Number): ElementAccessExpression - fun createElementAccessExpression(expression: Expression, index: Expression): ElementAccessExpression - fun updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression - fun createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, index: Number): ElementAccessChain - fun createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, index: Expression): ElementAccessChain - fun updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, argumentExpression: Expression): ElementAccessChain - fun createCallExpression(expression: Expression, typeArguments: Array?, argumentsArray: Array?): CallExpression - fun updateCallExpression(node: CallExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array): CallExpression - fun createCallChain(expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array?): CallChain - fun updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array): CallChain - fun createNewExpression(expression: Expression, typeArguments: Array?, argumentsArray: Array?): NewExpression - fun updateNewExpression(node: NewExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array?): NewExpression - fun createTaggedTemplateExpression(tag: Expression, typeArguments: Array?, template: TemplateExpression): TaggedTemplateExpression - fun createTaggedTemplateExpression(tag: Expression, typeArguments: Array?, template: NoSubstitutionTemplateLiteral): TaggedTemplateExpression - fun updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: TemplateExpression): TaggedTemplateExpression - fun updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: NoSubstitutionTemplateLiteral): TaggedTemplateExpression - fun createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion - fun updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion - fun createParenthesizedExpression(expression: Expression): ParenthesizedExpression - fun updateParenthesizedExpression(node: ParenthesizedExpression, expression: Expression): ParenthesizedExpression - fun createFunctionExpression(modifiers: Array?, asteriskToken: AsteriskToken?, name: String?, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block): FunctionExpression - fun createFunctionExpression(modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block): FunctionExpression - fun updateFunctionExpression(node: FunctionExpression, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block): FunctionExpression - fun createArrowFunction(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: FunctionBody): ArrowFunction - fun createArrowFunction(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: Expression): ArrowFunction - fun updateArrowFunction(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: FunctionBody): ArrowFunction - fun updateArrowFunction(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: Expression): ArrowFunction - fun createDeleteExpression(expression: Expression): DeleteExpression - fun updateDeleteExpression(node: DeleteExpression, expression: Expression): DeleteExpression - fun createTypeOfExpression(expression: Expression): TypeOfExpression - fun updateTypeOfExpression(node: TypeOfExpression, expression: Expression): TypeOfExpression - fun createVoidExpression(expression: Expression): VoidExpression - fun updateVoidExpression(node: VoidExpression, expression: Expression): VoidExpression - fun createAwaitExpression(expression: Expression): AwaitExpression - fun updateAwaitExpression(node: AwaitExpression, expression: Expression): AwaitExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.PlusPlusToken, operand: Expression): PrefixUnaryExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.MinusMinusToken, operand: Expression): PrefixUnaryExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.PlusToken, operand: Expression): PrefixUnaryExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.MinusToken, operand: Expression): PrefixUnaryExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.TildeToken, operand: Expression): PrefixUnaryExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.ExclamationToken, operand: Expression): PrefixUnaryExpression - fun updatePrefixUnaryExpression(node: PrefixUnaryExpression, operand: Expression): PrefixUnaryExpression - fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind.PlusPlusToken): PostfixUnaryExpression - fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind.MinusMinusToken): PostfixUnaryExpression - fun updatePostfixUnaryExpression(node: PostfixUnaryExpression, operand: Expression): PostfixUnaryExpression - fun createBinaryExpression(left: Expression, operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression): BinaryExpression - fun updateBinaryExpression(node: BinaryExpression, left: Expression, operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression): BinaryExpression - fun createConditionalExpression(condition: Expression, questionToken: QuestionToken?, whenTrue: Expression, colonToken: ColonToken?, whenFalse: Expression): ConditionalExpression - fun updateConditionalExpression(node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression - fun createTemplateExpression(head: TemplateHead, templateSpans: Array): TemplateExpression - fun updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: Array): TemplateExpression - fun createTemplateHead(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateHead - fun createTemplateHead(text: String): TemplateHead - fun createTemplateHead(text: String, rawText: String = definedExternally): TemplateHead - fun createTemplateHead(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateHead - fun createTemplateHead(text: String?, rawText: String): TemplateHead - fun createTemplateMiddle(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateMiddle - fun createTemplateMiddle(text: String): TemplateMiddle - fun createTemplateMiddle(text: String, rawText: String = definedExternally): TemplateMiddle - fun createTemplateMiddle(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateMiddle - fun createTemplateMiddle(text: String?, rawText: String): TemplateMiddle - fun createTemplateTail(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateTail - fun createTemplateTail(text: String): TemplateTail - fun createTemplateTail(text: String, rawText: String = definedExternally): TemplateTail - fun createTemplateTail(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateTail - fun createTemplateTail(text: String?, rawText: String): TemplateTail - fun createNoSubstitutionTemplateLiteral(text: String, rawText: String = definedExternally): NoSubstitutionTemplateLiteral - fun createNoSubstitutionTemplateLiteral(text: String): NoSubstitutionTemplateLiteral - fun createNoSubstitutionTemplateLiteral(text: String?, rawText: String): NoSubstitutionTemplateLiteral - fun createYieldExpression(asteriskToken: AsteriskToken, expression: Expression): YieldExpression - fun createYieldExpression(asteriskToken: Nothing?, expression: Expression?): YieldExpression - fun updateYieldExpression(node: YieldExpression, asteriskToken: AsteriskToken?, expression: Expression?): YieldExpression - fun createSpreadElement(expression: Expression): SpreadElement - fun updateSpreadElement(node: SpreadElement, expression: Expression): SpreadElement - fun createClassExpression(decorators: Array?, modifiers: Array?, name: String?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression - fun createClassExpression(decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression - fun updateClassExpression(node: ClassExpression, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression - fun createOmittedExpression(): OmittedExpression - fun createExpressionWithTypeArguments(expression: Expression, typeArguments: Array?): ExpressionWithTypeArguments - fun updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, expression: Expression, typeArguments: Array?): ExpressionWithTypeArguments - fun createAsExpression(expression: Expression, type: TypeNode): AsExpression - fun updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode): AsExpression - fun createNonNullExpression(expression: Expression): NonNullExpression - fun updateNonNullExpression(node: NonNullExpression, expression: Expression): NonNullExpression - fun createNonNullChain(expression: Expression): NonNullChain - fun updateNonNullChain(node: NonNullChain, expression: Expression): NonNullChain - fun createMetaProperty(keywordToken: SyntaxKind.NewKeyword, name: Identifier): MetaProperty - fun createMetaProperty(keywordToken: SyntaxKind.ImportKeyword, name: Identifier): MetaProperty - fun updateMetaProperty(node: MetaProperty, name: Identifier): MetaProperty - fun createTemplateSpan(expression: Expression, literal: TemplateMiddle): TemplateSpan - fun createTemplateSpan(expression: Expression, literal: TemplateTail): TemplateSpan - fun updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle): TemplateSpan - fun updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateTail): TemplateSpan - fun createSemicolonClassElement(): SemicolonClassElement - fun createBlock(statements: Array, multiLine: Boolean = definedExternally): Block - fun updateBlock(node: Block, statements: Array): Block - fun createVariableStatement(modifiers: Array?, declarationList: VariableDeclarationList): VariableStatement - fun createVariableStatement(modifiers: Array?, declarationList: Array): VariableStatement - fun updateVariableStatement(node: VariableStatement, modifiers: Array?, declarationList: VariableDeclarationList): VariableStatement - fun createEmptyStatement(): EmptyStatement - fun createExpressionStatement(expression: Expression): ExpressionStatement - fun updateExpressionStatement(node: ExpressionStatement, expression: Expression): ExpressionStatement - fun createIfStatement(expression: Expression, thenStatement: Statement, elseStatement: Statement = definedExternally): IfStatement - fun updateIfStatement(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement?): IfStatement - fun createDoStatement(statement: Statement, expression: Expression): DoStatement - fun updateDoStatement(node: DoStatement, statement: Statement, expression: Expression): DoStatement - fun createWhileStatement(expression: Expression, statement: Statement): WhileStatement - fun updateWhileStatement(node: WhileStatement, expression: Expression, statement: Statement): WhileStatement - fun createForStatement(initializer: VariableDeclarationList?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement - fun createForStatement(initializer: Expression?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement - fun updateForStatement(node: ForStatement, initializer: VariableDeclarationList?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement - fun updateForStatement(node: ForStatement, initializer: Expression?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement - fun createForInStatement(initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForInStatement - fun createForInStatement(initializer: Expression, expression: Expression, statement: Statement): ForInStatement - fun updateForInStatement(node: ForInStatement, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForInStatement - fun updateForInStatement(node: ForInStatement, initializer: Expression, expression: Expression, statement: Statement): ForInStatement - fun createForOfStatement(awaitModifier: AwaitKeyword?, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForOfStatement - fun createForOfStatement(awaitModifier: AwaitKeyword?, initializer: Expression, expression: Expression, statement: Statement): ForOfStatement - fun updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForOfStatement - fun updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: Expression, expression: Expression, statement: Statement): ForOfStatement - fun createContinueStatement(label: String = definedExternally): ContinueStatement - fun createContinueStatement(): ContinueStatement - fun createContinueStatement(label: Identifier = definedExternally): ContinueStatement - fun updateContinueStatement(node: ContinueStatement, label: Identifier?): ContinueStatement - fun createBreakStatement(label: String = definedExternally): BreakStatement - fun createBreakStatement(): BreakStatement - fun createBreakStatement(label: Identifier = definedExternally): BreakStatement - fun updateBreakStatement(node: BreakStatement, label: Identifier?): BreakStatement - fun createReturnStatement(expression: Expression = definedExternally): ReturnStatement - fun updateReturnStatement(node: ReturnStatement, expression: Expression?): ReturnStatement - fun createWithStatement(expression: Expression, statement: Statement): WithStatement - fun updateWithStatement(node: WithStatement, expression: Expression, statement: Statement): WithStatement - fun createSwitchStatement(expression: Expression, caseBlock: CaseBlock): SwitchStatement - fun updateSwitchStatement(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock): SwitchStatement - fun createLabeledStatement(label: String, statement: Statement): LabeledStatement - fun createLabeledStatement(label: Identifier, statement: Statement): LabeledStatement - fun updateLabeledStatement(node: LabeledStatement, label: Identifier, statement: Statement): LabeledStatement - fun createThrowStatement(expression: Expression): ThrowStatement - fun updateThrowStatement(node: ThrowStatement, expression: Expression): ThrowStatement - fun createTryStatement(tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?): TryStatement - fun updateTryStatement(node: TryStatement, tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?): TryStatement - fun createDebuggerStatement(): DebuggerStatement - fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: String): VariableDeclaration - fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: Identifier): VariableDeclaration - fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ObjectBindingPattern): VariableDeclaration - fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ArrayBindingPattern): VariableDeclaration - fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration - fun updateVariableDeclaration(node: VariableDeclaration, name: Identifier, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration - fun updateVariableDeclaration(node: VariableDeclaration, name: ObjectBindingPattern, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration - fun updateVariableDeclaration(node: VariableDeclaration, name: ArrayBindingPattern, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration - fun createVariableDeclarationList(declarations: Array, flags: NodeFlags = definedExternally): VariableDeclarationList - fun updateVariableDeclarationList(node: VariableDeclarationList, declarations: Array): VariableDeclarationList - fun createFunctionDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration - fun createFunctionDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration - fun updateFunctionDeclaration(node: FunctionDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration - fun createClassDeclaration(decorators: Array?, modifiers: Array?, name: String?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration - fun createClassDeclaration(decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration - fun updateClassDeclaration(node: ClassDeclaration, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration - fun createInterfaceDeclaration(decorators: Array?, modifiers: Array?, name: String, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration - fun createInterfaceDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration - fun updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration - fun createTypeAliasDeclaration(decorators: Array?, modifiers: Array?, name: String, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration - fun createTypeAliasDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration - fun updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration - fun createEnumDeclaration(decorators: Array?, modifiers: Array?, name: String, members: Array): EnumDeclaration - fun createEnumDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, members: Array): EnumDeclaration - fun updateEnumDeclaration(node: EnumDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, members: Array): EnumDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?): ModuleDeclaration - fun createModuleBlock(statements: Array): ModuleBlock - fun updateModuleBlock(node: ModuleBlock, statements: Array): ModuleBlock - fun createCaseBlock(clauses: Array): CaseBlock - fun updateCaseBlock(node: CaseBlock, clauses: Array): CaseBlock - fun createNamespaceExportDeclaration(name: String): NamespaceExportDeclaration - fun createNamespaceExportDeclaration(name: Identifier): NamespaceExportDeclaration - fun updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier): NamespaceExportDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: Identifier): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: QualifiedName): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: ExternalModuleReference): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: Identifier): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: QualifiedName): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: ExternalModuleReference): ImportEqualsDeclaration - fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: Identifier): ImportEqualsDeclaration - fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: QualifiedName): ImportEqualsDeclaration - fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: ExternalModuleReference): ImportEqualsDeclaration - fun createImportDeclaration(decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression): ImportDeclaration - fun updateImportDeclaration(node: ImportDeclaration, decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression): ImportDeclaration - fun createImportClause(isTypeOnly: Boolean, name: Identifier?, namedBindings: NamespaceImport?): ImportClause - fun createImportClause(isTypeOnly: Boolean, name: Identifier?, namedBindings: NamedImports?): ImportClause - fun updateImportClause(node: ImportClause, isTypeOnly: Boolean, name: Identifier?, namedBindings: NamespaceImport?): ImportClause - fun updateImportClause(node: ImportClause, isTypeOnly: Boolean, name: Identifier?, namedBindings: NamedImports?): ImportClause - fun createNamespaceImport(name: Identifier): NamespaceImport - fun updateNamespaceImport(node: NamespaceImport, name: Identifier): NamespaceImport - fun createNamespaceExport(name: Identifier): NamespaceExport - fun updateNamespaceExport(node: NamespaceExport, name: Identifier): NamespaceExport - fun createNamedImports(elements: Array): NamedImports - fun updateNamedImports(node: NamedImports, elements: Array): NamedImports - fun createImportSpecifier(propertyName: Identifier?, name: Identifier): ImportSpecifier - fun updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier?, name: Identifier): ImportSpecifier - fun createExportAssignment(decorators: Array?, modifiers: Array?, isExportEquals: Boolean?, expression: Expression): ExportAssignment - fun updateExportAssignment(node: ExportAssignment, decorators: Array?, modifiers: Array?, expression: Expression): ExportAssignment - fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?, moduleSpecifier: Expression = definedExternally): ExportDeclaration - fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?): ExportDeclaration - fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?, moduleSpecifier: Expression = definedExternally): ExportDeclaration - fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?): ExportDeclaration - fun updateExportDeclaration(node: ExportDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?, moduleSpecifier: Expression?): ExportDeclaration - fun updateExportDeclaration(node: ExportDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?, moduleSpecifier: Expression?): ExportDeclaration - fun createNamedExports(elements: Array): NamedExports - fun updateNamedExports(node: NamedExports, elements: Array): NamedExports - fun createExportSpecifier(propertyName: String?, name: String): ExportSpecifier - fun createExportSpecifier(propertyName: String?, name: Identifier): ExportSpecifier - fun createExportSpecifier(propertyName: Identifier?, name: String): ExportSpecifier - fun createExportSpecifier(propertyName: Identifier?, name: Identifier): ExportSpecifier - fun updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier?, name: Identifier): ExportSpecifier - fun createExternalModuleReference(expression: Expression): ExternalModuleReference - fun updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference - fun createJSDocAllType(): JSDocAllType - fun createJSDocUnknownType(): JSDocUnknownType - fun createJSDocNonNullableType(type: TypeNode): JSDocNonNullableType - fun updateJSDocNonNullableType(node: JSDocNonNullableType, type: TypeNode): JSDocNonNullableType - fun createJSDocNullableType(type: TypeNode): JSDocNullableType - fun updateJSDocNullableType(node: JSDocNullableType, type: TypeNode): JSDocNullableType - fun createJSDocOptionalType(type: TypeNode): JSDocOptionalType - fun updateJSDocOptionalType(node: JSDocOptionalType, type: TypeNode): JSDocOptionalType - fun createJSDocFunctionType(parameters: Array, type: TypeNode?): JSDocFunctionType - fun updateJSDocFunctionType(node: JSDocFunctionType, parameters: Array, type: TypeNode?): JSDocFunctionType - fun createJSDocVariadicType(type: TypeNode): JSDocVariadicType - fun updateJSDocVariadicType(node: JSDocVariadicType, type: TypeNode): JSDocVariadicType - fun createJSDocNamepathType(type: TypeNode): JSDocNamepathType - fun updateJSDocNamepathType(node: JSDocNamepathType, type: TypeNode): JSDocNamepathType - fun createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression - fun updateJSDocTypeExpression(node: JSDocTypeExpression, type: TypeNode): JSDocTypeExpression - fun createJSDocNameReference(name: Identifier): JSDocNameReference - fun createJSDocNameReference(name: QualifiedName): JSDocNameReference - fun updateJSDocNameReference(node: JSDocNameReference, name: Identifier): JSDocNameReference - fun updateJSDocNameReference(node: JSDocNameReference, name: QualifiedName): JSDocNameReference - fun createJSDocLink(name: Identifier?, text: String): JSDocLink - fun createJSDocLink(name: QualifiedName?, text: String): JSDocLink - fun updateJSDocLink(node: JSDocLink, name: Identifier?, text: String): JSDocLink - fun updateJSDocLink(node: JSDocLink, name: QualifiedName?, text: String): JSDocLink - fun createJSDocTypeLiteral(jsDocPropertyTags: Array = definedExternally, isArrayType: Boolean = definedExternally): JSDocTypeLiteral - fun updateJSDocTypeLiteral(node: JSDocTypeLiteral, jsDocPropertyTags: Array?, isArrayType: Boolean?): JSDocTypeLiteral - fun createJSDocSignature(typeParameters: Array?, parameters: Array, type: JSDocReturnTag = definedExternally): JSDocSignature - fun updateJSDocSignature(node: JSDocSignature, typeParameters: Array?, parameters: Array, type: JSDocReturnTag?): JSDocSignature - fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String = definedExternally): JSDocTemplateTag - fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array): JSDocTemplateTag - fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray = definedExternally): JSDocTemplateTag - fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String?): JSDocTemplateTag - fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray?): JSDocTemplateTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag - fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocTypeTag - fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocTypeTag - fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocTypeTag - fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocTypeTag - fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocTypeTag - fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag - fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag - fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag - fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag - fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag - fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag - fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: String = definedExternally): JSDocReturnTag - fun createJSDocReturnTag(tagName: Identifier?): JSDocReturnTag - fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocReturnTag - fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: NodeArray = definedExternally): JSDocReturnTag - fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocReturnTag - fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocReturnTag - fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocThisTag - fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocThisTag - fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocThisTag - fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocThisTag - fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocThisTag - fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocEnumTag - fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocEnumTag - fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocEnumTag - fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocEnumTag - fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocEnumTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: String?): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: NodeArray?): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocCallbackTag - fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: String = definedExternally): JSDocAugmentsTag - fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */): JSDocAugmentsTag - fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: NodeArray = definedExternally): JSDocAugmentsTag - fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: String?): JSDocAugmentsTag - fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: NodeArray?): JSDocAugmentsTag - fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: String = definedExternally): JSDocImplementsTag - fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */): JSDocImplementsTag - fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: NodeArray = definedExternally): JSDocImplementsTag - fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: String?): JSDocImplementsTag - fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$4` */, comment: NodeArray?): JSDocImplementsTag - fun createJSDocAuthorTag(tagName: Identifier?, comment: String = definedExternally): JSDocAuthorTag - fun createJSDocAuthorTag(tagName: Identifier?): JSDocAuthorTag - fun createJSDocAuthorTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocAuthorTag - fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: String?): JSDocAuthorTag - fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: NodeArray?): JSDocAuthorTag - fun createJSDocClassTag(tagName: Identifier?, comment: String = definedExternally): JSDocClassTag - fun createJSDocClassTag(tagName: Identifier?): JSDocClassTag - fun createJSDocClassTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocClassTag - fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: String?): JSDocClassTag - fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: NodeArray?): JSDocClassTag - fun createJSDocPublicTag(tagName: Identifier?, comment: String = definedExternally): JSDocPublicTag - fun createJSDocPublicTag(tagName: Identifier?): JSDocPublicTag - fun createJSDocPublicTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPublicTag - fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: String?): JSDocPublicTag - fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: NodeArray?): JSDocPublicTag - fun createJSDocPrivateTag(tagName: Identifier?, comment: String = definedExternally): JSDocPrivateTag - fun createJSDocPrivateTag(tagName: Identifier?): JSDocPrivateTag - fun createJSDocPrivateTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPrivateTag - fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: String?): JSDocPrivateTag - fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: NodeArray?): JSDocPrivateTag - fun createJSDocProtectedTag(tagName: Identifier?, comment: String = definedExternally): JSDocProtectedTag - fun createJSDocProtectedTag(tagName: Identifier?): JSDocProtectedTag - fun createJSDocProtectedTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocProtectedTag - fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: String?): JSDocProtectedTag - fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: NodeArray?): JSDocProtectedTag - fun createJSDocReadonlyTag(tagName: Identifier?, comment: String = definedExternally): JSDocReadonlyTag - fun createJSDocReadonlyTag(tagName: Identifier?): JSDocReadonlyTag - fun createJSDocReadonlyTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocReadonlyTag - fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: String?): JSDocReadonlyTag - fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: NodeArray?): JSDocReadonlyTag - fun createJSDocUnknownTag(tagName: Identifier, comment: String = definedExternally): JSDocUnknownTag - fun createJSDocUnknownTag(tagName: Identifier): JSDocUnknownTag - fun createJSDocUnknownTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocUnknownTag - fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: String?): JSDocUnknownTag - fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: NodeArray?): JSDocUnknownTag - fun createJSDocDeprecatedTag(tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag - fun createJSDocDeprecatedTag(tagName: Identifier): JSDocDeprecatedTag - fun createJSDocDeprecatedTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag - fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag - fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier): JSDocDeprecatedTag - fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag - fun createJSDocOverrideTag(tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag - fun createJSDocOverrideTag(tagName: Identifier): JSDocOverrideTag - fun createJSDocOverrideTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag - fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag - fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier): JSDocOverrideTag - fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag - fun createJSDocText(text: String): JSDocText - fun updateJSDocText(node: JSDocText, text: String): JSDocText - fun createJSDocComment(comment: String? = definedExternally, tags: Array? = definedExternally): JSDoc - fun createJSDocComment(): JSDoc - fun createJSDocComment(comment: String? = definedExternally): JSDoc - fun createJSDocComment(comment: NodeArray? = definedExternally, tags: Array? = definedExternally): JSDoc - fun createJSDocComment(comment: NodeArray? = definedExternally): JSDoc - fun updateJSDocComment(node: JSDoc, comment: String?, tags: Array?): JSDoc - fun updateJSDocComment(node: JSDoc, comment: NodeArray?, tags: Array?): JSDoc - fun createJsxElement(openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement - fun updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement - fun createJsxSelfClosingElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun createJsxSelfClosingElement(tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun createJsxSelfClosingElement(tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun createJsxOpeningElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun createJsxOpeningElement(tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun createJsxOpeningElement(tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun createJsxClosingElement(tagName: Identifier): JsxClosingElement - fun createJsxClosingElement(tagName: ThisExpression): JsxClosingElement - fun createJsxClosingElement(tagName: JsxTagNamePropertyAccess): JsxClosingElement - fun updateJsxClosingElement(node: JsxClosingElement, tagName: Identifier): JsxClosingElement - fun updateJsxClosingElement(node: JsxClosingElement, tagName: ThisExpression): JsxClosingElement - fun updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNamePropertyAccess): JsxClosingElement - fun createJsxFragment(openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment): JsxFragment - fun createJsxText(text: String, containsOnlyTriviaWhiteSpaces: Boolean = definedExternally): JsxText - fun updateJsxText(node: JsxText, text: String, containsOnlyTriviaWhiteSpaces: Boolean = definedExternally): JsxText - fun createJsxOpeningFragment(): JsxOpeningFragment - fun createJsxJsxClosingFragment(): JsxClosingFragment - fun updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment): JsxFragment - fun createJsxAttribute(name: Identifier, initializer: StringLiteral?): JsxAttribute - fun createJsxAttribute(name: Identifier, initializer: JsxExpression?): JsxAttribute - fun updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral?): JsxAttribute - fun updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: JsxExpression?): JsxAttribute - fun createJsxAttributes(properties: Array): JsxAttributes - fun updateJsxAttributes(node: JsxAttributes, properties: Array): JsxAttributes - fun createJsxSpreadAttribute(expression: Expression): JsxSpreadAttribute - fun updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression): JsxSpreadAttribute - fun createJsxExpression(dotDotDotToken: DotDotDotToken?, expression: Expression?): JsxExpression - fun updateJsxExpression(node: JsxExpression, expression: Expression?): JsxExpression - fun createCaseClause(expression: Expression, statements: Array): CaseClause - fun updateCaseClause(node: CaseClause, expression: Expression, statements: Array): CaseClause - fun createDefaultClause(statements: Array): DefaultClause - fun updateDefaultClause(node: DefaultClause, statements: Array): DefaultClause - fun createHeritageClause(token: SyntaxKind.ExtendsKeyword, types: Array): HeritageClause - fun createHeritageClause(token: SyntaxKind.ImplementsKeyword, types: Array): HeritageClause - fun updateHeritageClause(node: HeritageClause, types: Array): HeritageClause - fun createCatchClause(variableDeclaration: String?, block: Block): CatchClause - fun createCatchClause(variableDeclaration: VariableDeclaration?, block: Block): CatchClause - fun updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration?, block: Block): CatchClause - fun createPropertyAssignment(name: String, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: Identifier, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: StringLiteral, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: NumericLiteral, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: ComputedPropertyName, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: PrivateIdentifier, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: Identifier, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: StringLiteral, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: NumericLiteral, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: ComputedPropertyName, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: PrivateIdentifier, initializer: Expression): PropertyAssignment - fun createShorthandPropertyAssignment(name: String, objectAssignmentInitializer: Expression = definedExternally): ShorthandPropertyAssignment - fun createShorthandPropertyAssignment(name: String): ShorthandPropertyAssignment - fun createShorthandPropertyAssignment(name: Identifier, objectAssignmentInitializer: Expression = definedExternally): ShorthandPropertyAssignment - fun createShorthandPropertyAssignment(name: Identifier): ShorthandPropertyAssignment - fun updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression?): ShorthandPropertyAssignment - fun createSpreadAssignment(expression: Expression): SpreadAssignment - fun updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment - fun createEnumMember(name: String, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: String): EnumMember - fun createEnumMember(name: Identifier, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: Identifier): EnumMember - fun createEnumMember(name: StringLiteral, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: StringLiteral): EnumMember - fun createEnumMember(name: NumericLiteral, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: NumericLiteral): EnumMember - fun createEnumMember(name: ComputedPropertyName, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: ComputedPropertyName): EnumMember - fun createEnumMember(name: PrivateIdentifier, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: PrivateIdentifier): EnumMember - fun updateEnumMember(node: EnumMember, name: Identifier, initializer: Expression?): EnumMember - fun updateEnumMember(node: EnumMember, name: StringLiteral, initializer: Expression?): EnumMember - fun updateEnumMember(node: EnumMember, name: NumericLiteral, initializer: Expression?): EnumMember - fun updateEnumMember(node: EnumMember, name: ComputedPropertyName, initializer: Expression?): EnumMember - fun updateEnumMember(node: EnumMember, name: PrivateIdentifier, initializer: Expression?): EnumMember - fun createSourceFile(statements: Array, endOfFileToken: Token /* Token & JSDocContainer */, flags: NodeFlags): SourceFile - fun updateSourceFile(node: SourceFile, statements: Array, isDeclarationFile: Boolean = definedExternally, referencedFiles: Array = definedExternally, typeReferences: Array = definedExternally, hasNoDefaultLib: Boolean = definedExternally, libReferences: Array = definedExternally): SourceFile - fun createNotEmittedStatement(original: Node): NotEmittedStatement - fun createPartiallyEmittedExpression(expression: Expression, original: Node = definedExternally): PartiallyEmittedExpression - fun updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression): PartiallyEmittedExpression - fun createCommaListExpression(elements: Array): CommaListExpression - fun updateCommaListExpression(node: CommaListExpression, elements: Array): CommaListExpression - fun createBundle(sourceFiles: Array, prepends: Array = definedExternally): Bundle - fun updateBundle(node: Bundle, sourceFiles: Array, prepends: Array = definedExternally): Bundle - fun createComma(left: Expression, right: Expression): BinaryExpression - fun createAssignment(left: ObjectLiteralExpression, right: Expression): dynamic /* ObjectDestructuringAssignment | ArrayDestructuringAssignment */ - fun createAssignment(left: ArrayLiteralExpression, right: Expression): dynamic /* ObjectDestructuringAssignment | ArrayDestructuringAssignment */ - fun createAssignment(left: Expression, right: Expression): AssignmentExpression - fun createLogicalOr(left: Expression, right: Expression): BinaryExpression - fun createLogicalAnd(left: Expression, right: Expression): BinaryExpression - fun createBitwiseOr(left: Expression, right: Expression): BinaryExpression - fun createBitwiseXor(left: Expression, right: Expression): BinaryExpression - fun createBitwiseAnd(left: Expression, right: Expression): BinaryExpression - fun createStrictEquality(left: Expression, right: Expression): BinaryExpression - fun createStrictInequality(left: Expression, right: Expression): BinaryExpression - fun createEquality(left: Expression, right: Expression): BinaryExpression - fun createInequality(left: Expression, right: Expression): BinaryExpression - fun createLessThan(left: Expression, right: Expression): BinaryExpression - fun createLessThanEquals(left: Expression, right: Expression): BinaryExpression - fun createGreaterThan(left: Expression, right: Expression): BinaryExpression - fun createGreaterThanEquals(left: Expression, right: Expression): BinaryExpression - fun createLeftShift(left: Expression, right: Expression): BinaryExpression - fun createRightShift(left: Expression, right: Expression): BinaryExpression - fun createUnsignedRightShift(left: Expression, right: Expression): BinaryExpression - fun createAdd(left: Expression, right: Expression): BinaryExpression - fun createSubtract(left: Expression, right: Expression): BinaryExpression - fun createMultiply(left: Expression, right: Expression): BinaryExpression - fun createDivide(left: Expression, right: Expression): BinaryExpression - fun createModulo(left: Expression, right: Expression): BinaryExpression - fun createExponent(left: Expression, right: Expression): BinaryExpression - fun createPrefixPlus(operand: Expression): PrefixUnaryExpression - fun createPrefixMinus(operand: Expression): PrefixUnaryExpression - fun createPrefixIncrement(operand: Expression): PrefixUnaryExpression - fun createPrefixDecrement(operand: Expression): PrefixUnaryExpression - fun createBitwiseNot(operand: Expression): PrefixUnaryExpression - fun createLogicalNot(operand: Expression): PrefixUnaryExpression - fun createPostfixIncrement(operand: Expression): PostfixUnaryExpression - fun createPostfixDecrement(operand: Expression): PostfixUnaryExpression - fun createImmediatelyInvokedFunctionExpression(statements: Array): CallExpression - fun createImmediatelyInvokedFunctionExpression(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression - fun createImmediatelyInvokedArrowFunction(statements: Array): CallExpression - fun createImmediatelyInvokedArrowFunction(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression - fun createVoidZero(): VoidExpression - fun createExportDefault(expression: Expression): ExportAssignment - fun createExternalModuleExport(exportName: Identifier): ExportDeclaration - fun restoreOuterExpressions(outerExpression: Expression?, innerExpression: Expression, kinds: OuterExpressionKinds = definedExternally): Expression -} - -external interface CoreTransformationContext { - val factory: NodeFactory - fun getCompilerOptions(): CompilerOptions - fun startLexicalEnvironment() - fun suspendLexicalEnvironment() - fun resumeLexicalEnvironment() - fun endLexicalEnvironment(): Array? - fun hoistFunctionDeclaration(node: FunctionDeclaration) - fun hoistVariableDeclaration(node: Identifier) -} - -external interface TransformationContext : CoreTransformationContext { - fun requestEmitHelper(helper: ScopedEmitHelper) - fun requestEmitHelper(helper: UnscopedEmitHelper) - fun readEmitHelpers(): Array? - fun enableSubstitution(kind: SyntaxKind) - fun isSubstitutionEnabled(node: Node): Boolean - var onSubstituteNode: (hint: EmitHint, node: Node) -> Node - fun enableEmitNotification(kind: SyntaxKind) - fun isEmitNotificationEnabled(node: Node): Boolean - var onEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) -> Unit -} - -external interface TransformationResult { - var transformed: Array - var diagnostics: Array? - get() = definedExternally - set(value) = definedExternally - fun substituteNode(hint: EmitHint, node: Node): Node - fun emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) - val isEmitNotificationEnabled: ((node: Node) -> Boolean)? - fun dispose() -} - -external interface NodeVisitor { - @nativeInvoke - operator fun invoke(nodes: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T - @nativeInvoke - operator fun invoke(nodes: T, visitor: Visitor?): T - @nativeInvoke - operator fun invoke(nodes: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T - @nativeInvoke - operator fun invoke(nodes: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T? - @nativeInvoke - operator fun invoke(nodes: T?, visitor: Visitor?): T? - @nativeInvoke - operator fun invoke(nodes: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T? -} - -external interface NodesVisitor { - @nativeInvoke - operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray - @nativeInvoke - operator fun invoke(nodes: NodeArray, visitor: Visitor?): NodeArray - @nativeInvoke - operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray - @nativeInvoke - operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray - @nativeInvoke - operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray? - @nativeInvoke - operator fun invoke(nodes: NodeArray?, visitor: Visitor?): NodeArray? - @nativeInvoke - operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray? - @nativeInvoke - operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray? -} - -external interface Printer { - fun printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): String - fun printList(format: ListFormat, list: NodeArray, sourceFile: SourceFile): String - fun printFile(sourceFile: SourceFile): String - fun printBundle(bundle: Bundle): String -} - -external interface PrintHandlers { - val hasGlobalName: ((name: String) -> Boolean)? - val onEmitNode: ((hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) -> Unit)? - val isEmitNotificationEnabled: ((node: Node) -> Boolean)? - val substituteNode: ((hint: EmitHint, node: Node) -> Node)? -} - -external interface PrinterOptions { - var removeComments: Boolean? - get() = definedExternally - set(value) = definedExternally - var newLine: NewLineKind? - get() = definedExternally - set(value) = definedExternally - var omitTrailingSemicolon: Boolean? - get() = definedExternally - set(value) = definedExternally - var noEmitHelpers: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface GetEffectiveTypeRootsHost { - val directoryExists: ((directoryName: String) -> Boolean)? - val getCurrentDirectory: (() -> String)? -} - -external interface TextSpan { - var start: Number - var length: Number -} - -external interface TextChangeRange { - var span: TextSpan - var newLength: Number -} - -external interface SyntaxList : Node { - var _children: Array -} - -external enum class ListFormat { - None /* = 0 */, - SingleLine /* = 0 */, - MultiLine /* = 1 */, - PreserveLines /* = 2 */, - LinesMask /* = 3 */, - NotDelimited /* = 0 */, - BarDelimited /* = 4 */, - AmpersandDelimited /* = 8 */, - CommaDelimited /* = 16 */, - AsteriskDelimited /* = 32 */, - DelimitersMask /* = 60 */, - AllowTrailingComma /* = 64 */, - Indented /* = 128 */, - SpaceBetweenBraces /* = 256 */, - SpaceBetweenSiblings /* = 512 */, - Braces /* = 1024 */, - Parenthesis /* = 2048 */, - AngleBrackets /* = 4096 */, - SquareBrackets /* = 8192 */, - BracketsMask /* = 15360 */, - OptionalIfUndefined /* = 16384 */, - OptionalIfEmpty /* = 32768 */, - Optional /* = 49152 */, - PreferNewLine /* = 65536 */, - NoTrailingNewLine /* = 131072 */, - NoInterveningComments /* = 262144 */, - NoSpaceIfEmpty /* = 524288 */, - SingleElement /* = 1048576 */, - SpaceAfterList /* = 2097152 */, - Modifiers /* = 262656 */, - HeritageClauses /* = 512 */, - SingleLineTypeLiteralMembers /* = 768 */, - MultiLineTypeLiteralMembers /* = 32897 */, - SingleLineTupleTypeElements /* = 528 */, - MultiLineTupleTypeElements /* = 657 */, - UnionTypeConstituents /* = 516 */, - IntersectionTypeConstituents /* = 520 */, - ObjectBindingPatternElements /* = 525136 */, - ArrayBindingPatternElements /* = 524880 */, - ObjectLiteralExpressionProperties /* = 526226 */, - ArrayLiteralExpressionElements /* = 8914 */, - CommaListElements /* = 528 */, - CallExpressionArguments /* = 2576 */, - NewExpressionArguments /* = 18960 */, - TemplateExpressionSpans /* = 262144 */, - SingleLineBlockStatements /* = 768 */, - MultiLineBlockStatements /* = 129 */, - VariableDeclarationList /* = 528 */, - SingleLineFunctionBodyStatements /* = 768 */, - MultiLineFunctionBodyStatements /* = 1 */, - ClassHeritageClauses /* = 0 */, - ClassMembers /* = 129 */, - InterfaceMembers /* = 129 */, - EnumMembers /* = 145 */, - CaseBlockClauses /* = 129 */, - NamedImportsOrExportsElements /* = 525136 */, - JsxElementOrFragmentChildren /* = 262144 */, - JsxElementAttributes /* = 262656 */, - CaseOrDefaultClauseStatements /* = 163969 */, - HeritageClauseTypes /* = 528 */, - SourceFileStatements /* = 131073 */, - Decorators /* = 2146305 */, - TypeArguments /* = 53776 */, - TypeParameters /* = 53776 */, - Parameters /* = 2576 */, - IndexSignatureParameters /* = 8848 */, - JSDocComment /* = 33 */ -} - -external interface UserPreferences { - val disableSuggestions: Boolean? - get() = definedExternally - val quotePreference: String? /* "auto" | "double" | "single" */ - get() = definedExternally - val includeCompletionsForModuleExports: Boolean? - get() = definedExternally - val includeCompletionsForImportStatements: Boolean? - get() = definedExternally - val includeCompletionsWithSnippetText: Boolean? - get() = definedExternally - val includeAutomaticOptionalChainCompletions: Boolean? - get() = definedExternally - val includeCompletionsWithInsertText: Boolean? - get() = definedExternally - val importModuleSpecifierPreference: String? /* "shortest" | "project-relative" | "relative" | "non-relative" */ - get() = definedExternally - val importModuleSpecifierEnding: String? /* "auto" | "minimal" | "index" | "js" */ - get() = definedExternally - val allowTextChangesInNewFiles: Boolean? - get() = definedExternally - val providePrefixAndSuffixTextForRename: Boolean? - get() = definedExternally - val includePackageJsonAutoImports: String? /* "auto" | "on" | "off" */ - get() = definedExternally - val provideRefactorNotApplicableReason: Boolean? - get() = definedExternally -} - -external interface PseudoBigInt { - var negative: Boolean - var base10Value: String -} - -external enum class FileWatcherEventKind { - Created /* = 0 */, - Changed /* = 1 */, - Deleted /* = 2 */ -} - -external interface System { - var args: Array - var newLine: String - var useCaseSensitiveFileNames: Boolean - fun write(s: String) - val writeOutputIsTTY: (() -> Boolean)? - fun readFile(path: String, encoding: String = definedExternally): String? - val getFileSize: ((path: String) -> Number)? - fun writeFile(path: String, data: String, writeByteOrderMark: Boolean = definedExternally) - val watchFile: ((path: String, callback: FileWatcherCallback, pollingInterval: Number, options: WatchOptions) -> FileWatcher)? - val watchDirectory: ((path: String, callback: DirectoryWatcherCallback, recursive: Boolean, options: WatchOptions) -> FileWatcher)? - fun resolvePath(path: String): String - fun fileExists(path: String): Boolean - fun directoryExists(path: String): Boolean - fun createDirectory(path: String) - fun getExecutingFilePath(): String - fun getCurrentDirectory(): String - fun getDirectories(path: String): Array - fun readDirectory(path: String, extensions: Array = definedExternally, exclude: Array = definedExternally, include: Array = definedExternally, depth: Number = definedExternally): Array - val getModifiedTime: ((path: String) -> Date?)? - val setModifiedTime: ((path: String, time: Date) -> Unit)? - val deleteFile: ((path: String) -> Unit)? - val createHash: ((data: String) -> String)? - val createSHA256Hash: ((data: String) -> String)? - val getMemoryUsage: (() -> Number)? - fun exit(exitCode: Number = definedExternally) - val realpath: ((path: String) -> String)? - val setTimeout: ((callback: (args: Any) -> Unit, ms: Number, args: Any) -> Any)? - val clearTimeout: ((timeoutId: Any) -> Unit)? - val clearScreen: (() -> Unit)? - val base64decode: ((input: String) -> String)? - val base64encode: ((input: String) -> String)? -} - -external interface FileWatcher { - fun close() -} - -external fun getNodeMajorVersion(): Number? - -external var sys: System - -external fun parseCommandLine(commandLine: Array, readFile: (path: String) -> String? = definedExternally): ParsedCommandLine - -external interface ConfigFileDiagnosticsReporter { - var onUnRecoverableConfigFileDiagnostic: DiagnosticReporter -} - -external interface ParseConfigFileHost : ParseConfigHost, ConfigFileDiagnosticsReporter { - fun getCurrentDirectory(): String -} - -external fun getParsedCommandLineOfConfigFile(configFileName: String, optionsToExtend: CompilerOptions?, host: ParseConfigFileHost, extendedConfigCache: Map = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): ParsedCommandLine? - -external interface `T$9` { - var config: Any? - get() = definedExternally - set(value) = definedExternally - var error: Diagnostic? - get() = definedExternally - set(value) = definedExternally -} - -external fun readConfigFile(fileName: String, readFile: (path: String) -> String?): `T$9` - -external fun parseConfigFileTextToJson(fileName: String, jsonText: String): `T$9` - -external fun readJsonConfigFile(fileName: String, readFile: (path: String) -> String?): TsConfigSourceFile - -external fun convertToObject(sourceFile: JsonSourceFile, errors: Push): Any - -external fun parseJsonConfigFileContent(json: Any, host: ParseConfigHost, basePath: String, existingOptions: CompilerOptions = definedExternally, configFileName: String = definedExternally, resolutionStack: Array = definedExternally, extraFileExtensions: Array = definedExternally, extendedConfigCache: Map = definedExternally, existingWatchOptions: WatchOptions = definedExternally): ParsedCommandLine - -external fun parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: String, existingOptions: CompilerOptions = definedExternally, configFileName: String = definedExternally, resolutionStack: Array = definedExternally, extraFileExtensions: Array = definedExternally, extendedConfigCache: Map = definedExternally, existingWatchOptions: WatchOptions = definedExternally): ParsedCommandLine - -external interface ParsedTsconfig { - var raw: Any - var options: CompilerOptions? - get() = definedExternally - set(value) = definedExternally - var watchOptions: WatchOptions? - get() = definedExternally - set(value) = definedExternally - var typeAcquisition: TypeAcquisition? - get() = definedExternally - set(value) = definedExternally - var extendedConfigPath: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface ExtendedConfigCacheEntry { - var extendedResult: TsConfigSourceFile - var extendedConfig: ParsedTsconfig? -} - -external interface `T$10` { - var options: CompilerOptions - var errors: Array -} - -external fun convertCompilerOptionsFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$10` - -external interface `T$11` { - var options: TypeAcquisition - var errors: Array -} - -external fun convertTypeAcquisitionFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$11` - -external interface SourceFileLike { - fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter -} - -external interface IScriptSnapshot { - fun getText(start: Number, end: Number): String - fun getLength(): Number - fun getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange? - val dispose: (() -> Unit)? -} - -external interface PreProcessedFileInfo { - var referencedFiles: Array - var typeReferenceDirectives: Array - var libReferenceDirectives: Array - var importedFiles: Array - var ambientExternalModules: Array? - get() = definedExternally - set(value) = definedExternally - var isLibFile: Boolean -} - -external interface HostCancellationToken { - fun isCancellationRequested(): Boolean -} - -external interface InstallPackageOptions { - var fileName: String /* String & `T$3` */ - var packageName: String -} - -external interface PerformanceEvent { - var kind: String /* "UpdateGraph" | "CreatePackageJsonAutoImportProvider" */ - var durationMs: Number -} - -external enum class LanguageServiceMode { - Semantic /* = 0 */, - PartialSemantic /* = 1 */, - Syntactic /* = 2 */ -} - -external interface LanguageServiceHost : GetEffectiveTypeRootsHost { - fun getCompilationSettings(): CompilerOptions - val getNewLine: (() -> String)? - val getProjectVersion: (() -> String)? - fun getScriptFileNames(): Array - val getScriptKind: ((fileName: String) -> ScriptKind)? - fun getScriptVersion(fileName: String): String - fun getScriptSnapshot(fileName: String): IScriptSnapshot? - val getProjectReferences: (() -> Array?)? - val getLocalizedDiagnosticMessages: (() -> Any)? - val getCancellationToken: (() -> HostCancellationToken)? - override var getCurrentDirectory: () -> String - fun getDefaultLibFileName(options: CompilerOptions): String - val log: ((s: String) -> Unit)? - val trace: ((s: String) -> Unit)? - val error: ((s: String) -> Unit)? - val useCaseSensitiveFileNames: (() -> Boolean)? - val readDirectory: ((path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array)? - val readFile: ((path: String, encoding: String) -> String?)? - val realpath: ((path: String) -> String)? - val fileExists: ((path: String) -> Boolean)? - val getTypeRootsVersion: (() -> Number)? - val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val getResolvedModuleWithFailedLookupLocationsFromCache: ((modulename: String, containingFile: String) -> ResolvedModuleWithFailedLookupLocations?)? - val resolveTypeReferenceDirectives: ((typeDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val getDirectories: ((directoryName: String) -> Array)? - val getCustomTransformers: (() -> CustomTransformers?)? - val isKnownTypesPackageName: ((name: String) -> Boolean)? - val installPackage: ((options: InstallPackageOptions) -> Promise)? - val writeFile: ((fileName: String, content: String) -> Unit)? - val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? -} - -external interface `T$12` { - var metadata: Any? - get() = definedExternally - set(value) = definedExternally -} - -external enum class SemanticClassificationFormat { - Original /* = "original" */, - TwentyTwenty /* = "2020" */ -} - -external interface LanguageService { - fun cleanupSemanticCache() - fun getSyntacticDiagnostics(fileName: String): Array - fun getSemanticDiagnostics(fileName: String): Array - fun getSuggestionDiagnostics(fileName: String): Array - fun getCompilerOptionsDiagnostics(): Array - fun getSyntacticClassifications(fileName: String, span: TextSpan): Array - fun getSyntacticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ - fun getSemanticClassifications(fileName: String, span: TextSpan): Array - fun getSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ - fun getEncodedSyntacticClassifications(fileName: String, span: TextSpan): Classifications - fun getEncodedSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat = definedExternally): Classifications - fun getCompletionsAtPosition(fileName: String, position: Number, options: GetCompletionsAtPositionOptions?): CompletionInfo /* CompletionInfo & `T$12` */ - fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeOptions?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? - fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeSettings?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? - fun getCompletionEntrySymbol(fileName: String, position: Number, name: String, source: String?): Symbol? - fun getQuickInfoAtPosition(fileName: String, position: Number): QuickInfo? - fun getNameOrDottedNameSpan(fileName: String, startPos: Number, endPos: Number): TextSpan? - fun getBreakpointStatementAtPosition(fileName: String, position: Number): TextSpan? - fun getSignatureHelpItems(fileName: String, position: Number, options: SignatureHelpItemsOptions?): SignatureHelpItems? - fun getRenameInfo(fileName: String, position: Number, options: RenameInfoOptions = definedExternally): dynamic /* RenameInfoSuccess | RenameInfoFailure */ - fun findRenameLocations(fileName: String, position: Number, findInStrings: Boolean, findInComments: Boolean, providePrefixAndSuffixTextForRename: Boolean = definedExternally): Array? - fun getSmartSelectionRange(fileName: String, position: Number): SelectionRange - fun getDefinitionAtPosition(fileName: String, position: Number): Array? - fun getDefinitionAndBoundSpan(fileName: String, position: Number): DefinitionInfoAndBoundSpan? - fun getTypeDefinitionAtPosition(fileName: String, position: Number): Array? - fun getImplementationAtPosition(fileName: String, position: Number): Array? - fun getReferencesAtPosition(fileName: String, position: Number): Array? - fun findReferences(fileName: String, position: Number): Array? - fun getDocumentHighlights(fileName: String, position: Number, filesToSearch: Array): Array? - fun getFileReferences(fileName: String): Array - fun getOccurrencesAtPosition(fileName: String, position: Number): Array? - fun getNavigateToItems(searchValue: String, maxResultCount: Number = definedExternally, fileName: String = definedExternally, excludeDtsFiles: Boolean = definedExternally): Array - fun getNavigationBarItems(fileName: String): Array - fun getNavigationTree(fileName: String): NavigationTree - fun prepareCallHierarchy(fileName: String, position: Number): dynamic /* CallHierarchyItem? | Array? */ - fun provideCallHierarchyIncomingCalls(fileName: String, position: Number): Array - fun provideCallHierarchyOutgoingCalls(fileName: String, position: Number): Array - fun getOutliningSpans(fileName: String): Array - fun getTodoComments(fileName: String, descriptors: Array): Array - fun getBraceMatchingAtPosition(fileName: String, position: Number): Array - fun getIndentationAtPosition(fileName: String, position: Number, options: EditorOptions): Number - fun getIndentationAtPosition(fileName: String, position: Number, options: EditorSettings): Number - fun getFormattingEditsForRange(fileName: String, start: Number, end: Number, options: FormatCodeOptions): Array - fun getFormattingEditsForRange(fileName: String, start: Number, end: Number, options: FormatCodeSettings): Array - fun getFormattingEditsForDocument(fileName: String, options: FormatCodeOptions): Array - fun getFormattingEditsForDocument(fileName: String, options: FormatCodeSettings): Array - fun getFormattingEditsAfterKeystroke(fileName: String, position: Number, key: String, options: FormatCodeOptions): Array - fun getFormattingEditsAfterKeystroke(fileName: String, position: Number, key: String, options: FormatCodeSettings): Array - fun getDocCommentTemplateAtPosition(fileName: String, position: Number, options: DocCommentTemplateOptions = definedExternally): TextInsertion? - fun isValidBraceCompletionAtPosition(fileName: String, position: Number, openingBrace: Number): Boolean - fun getJsxClosingTagAtPosition(fileName: String, position: Number): JsxClosingTagInfo? - fun getSpanOfEnclosingComment(fileName: String, position: Number, onlyMultiLine: Boolean): TextSpan? - val toLineColumnOffset: ((fileName: String, position: Number) -> LineAndCharacter)? - fun getCodeFixesAtPosition(fileName: String, start: Number, end: Number, errorCodes: Array, formatOptions: FormatCodeSettings, preferences: UserPreferences): Array - fun getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: Any, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions - fun applyCodeActionCommand(action: CodeActionCommand, formatSettings: FormatCodeSettings = definedExternally): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(action: CodeActionCommand): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(action: Array, formatSettings: FormatCodeSettings = definedExternally): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(action: Array): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(fileName: String, action: CodeActionCommand): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(fileName: String, action: Array): dynamic /* Promise | Promise */ - fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally, kind: String = definedExternally): Array - fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?): Array - fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally): Array - fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally, kind: String = definedExternally): Array - fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?): Array - fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally): Array - fun getEditsForRefactor(fileName: String, formatOptions: FormatCodeSettings, positionOrRange: Number, refactorName: String, actionName: String, preferences: UserPreferences?): RefactorEditInfo? - fun getEditsForRefactor(fileName: String, formatOptions: FormatCodeSettings, positionOrRange: TextRange, refactorName: String, actionName: String, preferences: UserPreferences?): RefactorEditInfo? - fun organizeImports(args: OrganizeImportsArgs, formatOptions: FormatCodeSettings, preferences: UserPreferences?): Array - fun getEditsForFileRename(oldFilePath: String, newFilePath: String, formatOptions: FormatCodeSettings, preferences: UserPreferences?): Array - fun getEmitOutput(fileName: String, emitOnlyDtsFiles: Boolean = definedExternally, forceDtsEmit: Boolean = definedExternally): EmitOutput - fun getProgram(): Program? - fun toggleLineComment(fileName: String, textRange: TextRange): Array - fun toggleMultilineComment(fileName: String, textRange: TextRange): Array - fun commentSelection(fileName: String, textRange: TextRange): Array - fun uncommentSelection(fileName: String, textRange: TextRange): Array - fun dispose() -} - -external interface JsxClosingTagInfo { - val newText: String -} - -external interface CombinedCodeFixScope { - var type: String /* "file" */ - var fileName: String -} - -external interface OrganizeImportsArgs : CombinedCodeFixScope { - var skipDestructiveCodeActions: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface GetCompletionsAtPositionOptions : UserPreferences { - var triggerCharacter: String? /* "." | """ | "'" | "`" | "/" | "@" | "<" | "#" | " " */ - get() = definedExternally - set(value) = definedExternally - var includeExternalModuleExports: Boolean? - get() = definedExternally - set(value) = definedExternally - var includeInsertTextCompletions: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureHelpItemsOptions { - var triggerReason: dynamic /* SignatureHelpInvokedReason? | SignatureHelpCharacterTypedReason? | SignatureHelpRetriggeredReason? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureHelpInvokedReason { - var kind: String /* "invoked" */ - var triggerCharacter: Any? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureHelpCharacterTypedReason { - var kind: String /* "characterTyped" */ - var triggerCharacter: String /* "," | "(" | "<" */ -} - -external interface SignatureHelpRetriggeredReason { - var kind: String /* "retrigger" */ - var triggerCharacter: String? /* "," | "(" | "<" | ")" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ApplyCodeActionCommandResult { - var successMessage: String -} - -external interface Classifications { - var spans: Array - var endOfLineState: EndOfLineState -} - -external interface ClassifiedSpan { - var textSpan: TextSpan - var classificationType: ClassificationTypeNames -} - -external interface ClassifiedSpan2020 { - var textSpan: TextSpan - var classificationType: Number -} - -external interface NavigationBarItem { - var text: String - var kind: ScriptElementKind - var kindModifiers: String - var spans: Array - var childItems: Array - var indent: Number - var bolded: Boolean - var grayed: Boolean -} - -external interface NavigationTree { - var text: String - var kind: ScriptElementKind - var kindModifiers: String - var spans: Array - var nameSpan: TextSpan? - var childItems: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface CallHierarchyItem { - var name: String - var kind: ScriptElementKind - var kindModifiers: String? - get() = definedExternally - set(value) = definedExternally - var file: String - var span: TextSpan - var selectionSpan: TextSpan - var containerName: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface CallHierarchyIncomingCall { - var from: CallHierarchyItem - var fromSpans: Array -} - -external interface CallHierarchyOutgoingCall { - var to: CallHierarchyItem - var fromSpans: Array -} - -external interface TodoCommentDescriptor { - var text: String - var priority: Number -} - -external interface TodoComment { - var descriptor: TodoCommentDescriptor - var message: String - var position: Number -} - -external interface TextChange { - var span: TextSpan - var newText: String -} - -external interface FileTextChanges { - var fileName: String - var textChanges: Array - var isNewFile: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface CodeAction { - var description: String - var changes: Array - var commands: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface CodeFixAction : CodeAction { - var fixName: String - var fixId: Any? - get() = definedExternally - set(value) = definedExternally - var fixAllDescription: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface CombinedCodeActions { - var changes: Array - var commands: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface InstallPackageAction - -external interface ApplicableRefactorInfo { - var name: String - var description: String - var inlineable: Boolean? - get() = definedExternally - set(value) = definedExternally - var actions: Array -} - -external interface RefactorActionInfo { - var name: String - var description: String - var notApplicableReason: String? - get() = definedExternally - set(value) = definedExternally - var kind: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface RefactorEditInfo { - var edits: Array - var renameFilename: String? - get() = definedExternally - set(value) = definedExternally - var renameLocation: Number? - get() = definedExternally - set(value) = definedExternally - var commands: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface TextInsertion { - var newText: String - var caretOffset: Number -} - -external interface DocumentSpan { - var textSpan: TextSpan - var fileName: String - var originalTextSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var originalFileName: String? - get() = definedExternally - set(value) = definedExternally - var contextSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var originalContextSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally -} - -external interface RenameLocation : DocumentSpan { - val prefixText: String? - get() = definedExternally - val suffixText: String? - get() = definedExternally -} - -external interface ReferenceEntry : DocumentSpan { - var isWriteAccess: Boolean - var isDefinition: Boolean - var isInString: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ImplementationLocation : DocumentSpan { - var kind: ScriptElementKind - var displayParts: Array -} - -external enum class HighlightSpanKind { - none /* = "none" */, - definition /* = "definition" */, - reference /* = "reference" */, - writtenReference /* = "writtenReference" */ -} - -external interface HighlightSpan { - var fileName: String? - get() = definedExternally - set(value) = definedExternally - var isInString: Boolean? - get() = definedExternally - set(value) = definedExternally - var textSpan: TextSpan - var contextSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var kind: HighlightSpanKind -} - -external interface NavigateToItem { - var name: String - var kind: ScriptElementKind - var kindModifiers: String - var matchKind: String /* "exact" | "prefix" | "substring" | "camelCase" */ - var isCaseSensitive: Boolean - var fileName: String - var textSpan: TextSpan - var containerName: String - var containerKind: ScriptElementKind -} - -external enum class IndentStyle { - None /* = 0 */, - Block /* = 1 */, - Smart /* = 2 */ -} - -external enum class SemicolonPreference { - Ignore /* = "ignore" */, - Insert /* = "insert" */, - Remove /* = "remove" */ -} - -external interface EditorOptions { - var BaseIndentSize: Number? - get() = definedExternally - set(value) = definedExternally - var IndentSize: Number - var TabSize: Number - var NewLineCharacter: String - var ConvertTabsToSpaces: Boolean - var IndentStyle: IndentStyle -} - -external interface EditorSettings { - var baseIndentSize: Number? - get() = definedExternally - set(value) = definedExternally - var indentSize: Number? - get() = definedExternally - set(value) = definedExternally - var tabSize: Number? - get() = definedExternally - set(value) = definedExternally - var newLineCharacter: String? - get() = definedExternally - set(value) = definedExternally - var convertTabsToSpaces: Boolean? - get() = definedExternally - set(value) = definedExternally - var indentStyle: IndentStyle? - get() = definedExternally - set(value) = definedExternally - var trimTrailingWhitespace: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface FormatCodeOptions : EditorOptions { - var InsertSpaceAfterCommaDelimiter: Boolean - var InsertSpaceAfterSemicolonInForStatements: Boolean - var InsertSpaceBeforeAndAfterBinaryOperators: Boolean - var InsertSpaceAfterConstructor: Boolean? - get() = definedExternally - set(value) = definedExternally - var InsertSpaceAfterKeywordsInControlFlowStatements: Boolean - var InsertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean - var InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean - var InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean - var InsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: Boolean? - get() = definedExternally - set(value) = definedExternally - var InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean - var InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: Boolean? - get() = definedExternally - set(value) = definedExternally - var InsertSpaceAfterTypeAssertion: Boolean? - get() = definedExternally - set(value) = definedExternally - var InsertSpaceBeforeFunctionParenthesis: Boolean? - get() = definedExternally - set(value) = definedExternally - var PlaceOpenBraceOnNewLineForFunctions: Boolean - var PlaceOpenBraceOnNewLineForControlBlocks: Boolean - var insertSpaceBeforeTypeAnnotation: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface FormatCodeSettings : EditorSettings { - val insertSpaceAfterCommaDelimiter: Boolean? - get() = definedExternally - val insertSpaceAfterSemicolonInForStatements: Boolean? - get() = definedExternally - val insertSpaceBeforeAndAfterBinaryOperators: Boolean? - get() = definedExternally - val insertSpaceAfterConstructor: Boolean? - get() = definedExternally - val insertSpaceAfterKeywordsInControlFlowStatements: Boolean? - get() = definedExternally - val insertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingEmptyBraces: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: Boolean? - get() = definedExternally - val insertSpaceAfterTypeAssertion: Boolean? - get() = definedExternally - val insertSpaceBeforeFunctionParenthesis: Boolean? - get() = definedExternally - val placeOpenBraceOnNewLineForFunctions: Boolean? - get() = definedExternally - val placeOpenBraceOnNewLineForControlBlocks: Boolean? - get() = definedExternally - val insertSpaceBeforeTypeAnnotation: Boolean? - get() = definedExternally - val indentMultiLineObjectLiteralBeginningOnBlankLine: Boolean? - get() = definedExternally - val semicolons: SemicolonPreference? - get() = definedExternally -} - -external fun getDefaultFormatCodeSettings(newLineCharacter: String = definedExternally): FormatCodeSettings - -external interface DefinitionInfo : DocumentSpan { - var kind: ScriptElementKind - var name: String - var containerKind: ScriptElementKind - var containerName: String - var unverified: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface DefinitionInfoAndBoundSpan { - var definitions: Array? - get() = definedExternally - set(value) = definedExternally - var textSpan: TextSpan -} - -external interface ReferencedSymbolDefinitionInfo : DefinitionInfo { - var displayParts: Array -} - -external interface ReferencedSymbol { - var definition: ReferencedSymbolDefinitionInfo - var references: Array -} - -external enum class SymbolDisplayPartKind { - aliasName /* = 0 */, - className /* = 1 */, - enumName /* = 2 */, - fieldName /* = 3 */, - interfaceName /* = 4 */, - keyword /* = 5 */, - lineBreak /* = 6 */, - numericLiteral /* = 7 */, - stringLiteral /* = 8 */, - localName /* = 9 */, - methodName /* = 10 */, - moduleName /* = 11 */, - operator /* = 12 */, - parameterName /* = 13 */, - propertyName /* = 14 */, - punctuation /* = 15 */, - space /* = 16 */, - text /* = 17 */, - typeParameterName /* = 18 */, - enumMemberName /* = 19 */, - functionName /* = 20 */, - regularExpressionLiteral /* = 21 */, - link /* = 22 */, - linkName /* = 23 */, - linkText /* = 24 */ -} - -external interface SymbolDisplayPart { - var text: String - var kind: String -} - -external interface JSDocLinkDisplayPart : SymbolDisplayPart { - var target: DocumentSpan -} - -external interface JSDocTagInfo { - var name: String - var text: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface QuickInfo { - var kind: ScriptElementKind - var kindModifiers: String - var textSpan: TextSpan - var displayParts: Array? - get() = definedExternally - set(value) = definedExternally - var documentation: Array? - get() = definedExternally - set(value) = definedExternally - var tags: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface RenameInfoSuccess { - var canRename: Boolean - var fileToRename: String? - get() = definedExternally - set(value) = definedExternally - var displayName: String - var fullDisplayName: String - var kind: ScriptElementKind - var kindModifiers: String - var triggerSpan: TextSpan -} - -external interface RenameInfoFailure { - var canRename: Boolean - var localizedErrorMessage: String -} - -external interface RenameInfoOptions { - val allowRenameOfImportPath: Boolean? - get() = definedExternally -} - -external interface DocCommentTemplateOptions { - val generateReturnInDocTemplate: Boolean? - get() = definedExternally -} - -external interface SignatureHelpParameter { - var name: String - var documentation: Array - var displayParts: Array - var isOptional: Boolean - var isRest: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface SelectionRange { - var textSpan: TextSpan - var parent: SelectionRange? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureHelpItem { - var isVariadic: Boolean - var prefixDisplayParts: Array - var suffixDisplayParts: Array - var separatorDisplayParts: Array - var parameters: Array - var documentation: Array - var tags: Array -} - -external interface SignatureHelpItems { - var items: Array - var applicableSpan: TextSpan - var selectedItemIndex: Number - var argumentIndex: Number - var argumentCount: Number -} - -external interface CompletionInfo { - var isGlobalCompletion: Boolean - var isMemberCompletion: Boolean - var optionalReplacementSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var isNewIdentifierLocation: Boolean - var isIncomplete: Boolean? - get() = definedExternally - set(value) = definedExternally - var entries: Array -} - -external interface CompletionEntryData { - var fileName: String? - get() = definedExternally - set(value) = definedExternally - var ambientModuleName: String? - get() = definedExternally - set(value) = definedExternally - var isPackageJsonImport: Boolean? - get() = definedExternally - set(value) = definedExternally - var exportName: String - var moduleSpecifier: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface CompletionEntry { - var name: String - var kind: ScriptElementKind - var kindModifiers: String? - get() = definedExternally - set(value) = definedExternally - var sortText: String - var insertText: String? - get() = definedExternally - set(value) = definedExternally - var isSnippet: Boolean? - get() = definedExternally - set(value) = definedExternally - var replacementSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var hasAction: Boolean? - get() = definedExternally - set(value) = definedExternally - var source: String? - get() = definedExternally - set(value) = definedExternally - var sourceDisplay: Array? - get() = definedExternally - set(value) = definedExternally - var isRecommended: Boolean? - get() = definedExternally - set(value) = definedExternally - var isFromUncheckedFile: Boolean? - get() = definedExternally - set(value) = definedExternally - var isPackageJsonImport: Boolean? - get() = definedExternally - set(value) = definedExternally - var isImportStatementCompletion: Boolean? - get() = definedExternally - set(value) = definedExternally - var data: CompletionEntryData? - get() = definedExternally - set(value) = definedExternally -} - -external interface CompletionEntryDetails { - var name: String - var kind: ScriptElementKind - var kindModifiers: String - var displayParts: Array - var documentation: Array? - get() = definedExternally - set(value) = definedExternally - var tags: Array? - get() = definedExternally - set(value) = definedExternally - var codeActions: Array? - get() = definedExternally - set(value) = definedExternally - var source: Array? - get() = definedExternally - set(value) = definedExternally - var sourceDisplay: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface OutliningSpan { - var textSpan: TextSpan - var hintSpan: TextSpan - var bannerText: String - var autoCollapse: Boolean - var kind: OutliningSpanKind -} - -external enum class OutliningSpanKind { - Comment /* = "comment" */, - Region /* = "region" */, - Code /* = "code" */, - Imports /* = "imports" */ -} - -external enum class OutputFileType { - JavaScript /* = 0 */, - SourceMap /* = 1 */, - Declaration /* = 2 */ -} - -external enum class EndOfLineState { - None /* = 0 */, - InMultiLineCommentTrivia /* = 1 */, - InSingleQuoteStringLiteral /* = 2 */, - InDoubleQuoteStringLiteral /* = 3 */, - InTemplateHeadOrNoSubstitutionTemplate /* = 4 */, - InTemplateMiddleOrTail /* = 5 */, - InTemplateSubstitutionPosition /* = 6 */ -} - -external enum class TokenClass { - Punctuation /* = 0 */, - Keyword /* = 1 */, - Operator /* = 2 */, - Comment /* = 3 */, - Whitespace /* = 4 */, - Identifier /* = 5 */, - NumberLiteral /* = 6 */, - BigIntLiteral /* = 7 */, - StringLiteral /* = 8 */, - RegExpLiteral /* = 9 */ -} - -external interface ClassificationResult { - var finalLexState: EndOfLineState - var entries: Array -} - -external interface ClassificationInfo { - var length: Number - var classification: TokenClass -} - -external interface Classifier { - fun getClassificationsForLine(text: String, lexState: EndOfLineState, syntacticClassifierAbsent: Boolean): ClassificationResult - fun getEncodedLexicalClassifications(text: String, endOfLineState: EndOfLineState, syntacticClassifierAbsent: Boolean): Classifications -} - -external enum class ScriptElementKind { - unknown /* = "" */, - warning /* = "warning" */, - keyword /* = "keyword" */, - scriptElement /* = "script" */, - moduleElement /* = "module" */, - classElement /* = "class" */, - localClassElement /* = "local class" */, - interfaceElement /* = "interface" */, - typeElement /* = "type" */, - enumElement /* = "enum" */, - enumMemberElement /* = "enum member" */, - variableElement /* = "var" */, - localVariableElement /* = "local var" */, - functionElement /* = "function" */, - localFunctionElement /* = "local function" */, - memberFunctionElement /* = "method" */, - memberGetAccessorElement /* = "getter" */, - memberSetAccessorElement /* = "setter" */, - memberVariableElement /* = "property" */, - constructorImplementationElement /* = "constructor" */, - callSignatureElement /* = "call" */, - indexSignatureElement /* = "index" */, - constructSignatureElement /* = "construct" */, - parameterElement /* = "parameter" */, - typeParameterElement /* = "type parameter" */, - primitiveType /* = "primitive type" */, - label /* = "label" */, - alias /* = "alias" */, - constElement /* = "const" */, - letElement /* = "let" */, - directory /* = "directory" */, - externalModuleName /* = "external module name" */, - jsxAttribute /* = "JSX attribute" */, - string /* = "string" */, - link /* = "link" */, - linkName /* = "link name" */, - linkText /* = "link text" */ -} - -external enum class ScriptElementKindModifier { - none /* = "" */, - publicMemberModifier /* = "public" */, - privateMemberModifier /* = "private" */, - protectedMemberModifier /* = "protected" */, - exportedModifier /* = "export" */, - ambientModifier /* = "declare" */, - staticModifier /* = "static" */, - abstractModifier /* = "abstract" */, - optionalModifier /* = "optional" */, - deprecatedModifier /* = "deprecated" */, - dtsModifier /* = ".d.ts" */, - tsModifier /* = ".ts" */, - tsxModifier /* = ".tsx" */, - jsModifier /* = ".js" */, - jsxModifier /* = ".jsx" */, - jsonModifier /* = ".json" */ -} - -external enum class ClassificationTypeNames { - comment /* = "comment" */, - identifier /* = "identifier" */, - keyword /* = "keyword" */, - numericLiteral /* = "number" */, - bigintLiteral /* = "bigint" */, - operator /* = "operator" */, - stringLiteral /* = "string" */, - whiteSpace /* = "whitespace" */, - text /* = "text" */, - punctuation /* = "punctuation" */, - className /* = "class name" */, - enumName /* = "enum name" */, - interfaceName /* = "interface name" */, - moduleName /* = "module name" */, - typeParameterName /* = "type parameter name" */, - typeAliasName /* = "type alias name" */, - parameterName /* = "parameter name" */, - docCommentTagName /* = "doc comment tag name" */, - jsxOpenTagName /* = "jsx open tag name" */, - jsxCloseTagName /* = "jsx close tag name" */, - jsxSelfClosingTagName /* = "jsx self closing tag name" */, - jsxAttribute /* = "jsx attribute" */, - jsxText /* = "jsx text" */, - jsxAttributeStringLiteralValue /* = "jsx attribute string literal value" */ -} - -external enum class ClassificationType { - comment /* = 1 */, - identifier /* = 2 */, - keyword /* = 3 */, - numericLiteral /* = 4 */, - operator /* = 5 */, - stringLiteral /* = 6 */, - regularExpressionLiteral /* = 7 */, - whiteSpace /* = 8 */, - text /* = 9 */, - punctuation /* = 10 */, - className /* = 11 */, - enumName /* = 12 */, - interfaceName /* = 13 */, - moduleName /* = 14 */, - typeParameterName /* = 15 */, - typeAliasName /* = 16 */, - parameterName /* = 17 */, - docCommentTagName /* = 18 */, - jsxOpenTagName /* = 19 */, - jsxCloseTagName /* = 20 */, - jsxSelfClosingTagName /* = 21 */, - jsxAttribute /* = 22 */, - jsxText /* = 23 */, - jsxAttributeStringLiteralValue /* = 24 */, - bigintLiteral /* = 25 */ -} \ No newline at end of file diff --git a/externals03/utils.module_typescript-to-lua.kt b/externals03/utils.module_typescript-to-lua.kt deleted file mode 100644 index 08363d8..0000000 --- a/externals03/utils.module_typescript-to-lua.kt +++ /dev/null @@ -1,46 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.WriteFileCallback -import ts.SourceFile - -external interface EmitHost { - fun directoryExists(path: String): Boolean - fun fileExists(path: String): Boolean - fun getCurrentDirectory(): String - fun readFile(path: String): String? - var writeFile: WriteFileCallback -} - -external interface BaseFile { - var code: String - var sourceMap: String? - get() = definedExternally - set(value) = definedExternally - var sourceFiles: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface ProcessedFile : BaseFile { - var fileName: String - var luaAst: File? - get() = definedExternally - set(value) = definedExternally -} - -external interface EmitFile : BaseFile { - var outputPath: String -} \ No newline at end of file diff --git a/externals03/visitors.module_typescript-to-lua.kt b/externals03/visitors.module_typescript-to-lua.kt deleted file mode 100644 index 69513ac..0000000 --- a/externals03/visitors.module_typescript-to-lua.kt +++ /dev/null @@ -1,38 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.Statement -import ts.Node -import tsstdlib.Map -import ts.SyntaxKind - -external interface NodesBySyntaxKind - -typealias StatementLikeNode = Statement - -typealias VisitorResult = Any - -typealias FunctionVisitor = (node: T, context: TransformationContext) -> VisitorResult - -external interface ObjectVisitor { - var transform: FunctionVisitor - var priority: Number? - get() = definedExternally - set(value) = definedExternally -} - -typealias Visitors = Any - -typealias VisitorMap = Map>> \ No newline at end of file From 18dfc3ebdbc945ad4b9cb451d294c35ad8d2da15 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 9 Oct 2021 15:38:59 +0200 Subject: [PATCH 005/629] dynamic? to dynamic --- externals02/typescript.ts.module_typescript.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/externals02/typescript.ts.module_typescript.kt b/externals02/typescript.ts.module_typescript.kt index 661aa23..fb5f31b 100644 --- a/externals02/typescript.ts.module_typescript.kt +++ b/externals02/typescript.ts.module_typescript.kt @@ -3817,7 +3817,7 @@ external interface NodeFactory { fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: dynamic, questionOrExclamationToken: dynamic?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: dynamic, questionOrExclamationToken: dynamic, type: TypeNode?, initializer: Expression?): PropertyDeclaration // fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration // fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration // fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration @@ -3830,7 +3830,7 @@ external interface NodeFactory { // fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration // fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration // fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: dynamic, questionOrExclamationToken: dynamic?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: dynamic, questionOrExclamationToken: dynamic, type: TypeNode?, initializer: Expression?): PropertyDeclaration // fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration // fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration // fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration @@ -4947,7 +4947,7 @@ external interface Scanner { fun getText(): String fun setText(text: String?, start: Number = definedExternally, length: Number = definedExternally) // fun setOnError(onError: ErrorCallback?) // TODO why isn't ErrorCallback defined? - fun setOnError(onError: dynamic?) + fun setOnError(onError: dynamic) fun setScriptTarget(scriptTarget: ScriptTarget) fun setLanguageVariant(variant: LanguageVariant) fun setTextPos(textPos: Number) From ec94c681878b08c3de9ec23373c56d9cac97de81 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 9 Oct 2021 15:40:45 +0200 Subject: [PATCH 006/629] - change from Kotlin multi-platform to two subprojects. - set up ts->lua generation --- gradle/libs.versions.toml | 143 +++ modules/mod/build.gradle.kts | 151 +++ modules/mod/events.lua | 9 + modules/mod/package-lock.json | 1329 +++++++++++++++++++++ modules/mod/package.json | 28 + modules/mod/settings.gradle.kts | 3 + modules/mod/src/main/typescript/events.ts | 6 + modules/mod/tsconfig.json | 17 + modules/server/build.gradle.kts | 7 + modules/server/settings.gradle.kts | 3 + src/jsMain/kotlin/factorio.kt | 3 + 11 files changed, 1699 insertions(+) create mode 100644 gradle/libs.versions.toml create mode 100644 modules/mod/build.gradle.kts create mode 100644 modules/mod/events.lua create mode 100644 modules/mod/package-lock.json create mode 100644 modules/mod/package.json create mode 100644 modules/mod/settings.gradle.kts create mode 100644 modules/mod/src/main/typescript/events.ts create mode 100644 modules/mod/tsconfig.json create mode 100644 modules/server/build.gradle.kts create mode 100644 modules/server/settings.gradle.kts create mode 100644 src/jsMain/kotlin/factorio.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..b9724e7 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,143 @@ +# @formatter:off + +########## +[versions] +########## + +## compilation ## +jvm = "11" +kotlin = "1.5.31" + +## libs ## +http4k = "4.13.1.0" +slf4j = "1.7.30" +log4j2 = "2.14.1" +qosLogback = "1.2.5" + +## test ## +junit = "5.8.0" +kotest = "4.6.3" + + +######### +[plugins] +######### + +kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } +kotlinJs = { id = "org.jetbrains.kotlin.js", version.ref = "kotlin" } +kotlinSerialization = { id = "org.jetbrains.kotlin.kotlin-serialization", version.ref = "kotlin" } + +loggingCapabilities = { id = "dev.jacomet.logging-capabilities", version = "0.9.0" } +shadowJar = { id = "com.github.jengelman.gradle.plugins.shadow", version = "6.1.0" } +dependencyCheck = { id = "com.github.ben-manes.versions", version = "0.39.0" } +axionRelease = { id = "pl.allegro.tech.build.axion-release", version = "1.13.3" } + + +########### +[libraries] +########### + +twilio-sdk = { group = "com.twilio.sdk", name = "twilio", version = "8.19.1" } +faker = { group = "com.github.javafaker", name = "javafaker", version = "1.0.2" } +sendgrid = { group = "com.sendgrid", name = "sendgrid-java", version = "4.7.4" } + +## kotlin ## +kotlin-bom = { group = "org.jetbrains.kotlin", name = "kotlin-bom", version.ref = "kotlin" } + +kotlinx-serde = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version = "1.2.2" } +kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.5.2" } +kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.7.3" } + +## http4k ## +http4k-bom = { group = "org.http4k", name = "http4k-bom", version.ref = "http4k" } +http4k-core = { group = "org.http4k", name = "http4k-core" } +http4k-contract = { group = "org.http4k", name = "http4k-contract" } +http4k-client = { group = "org.http4k", name = "http4k-client-okhttp" } +http4k-server = { group = "org.http4k", name = "http4k-server-undertow" } +http4k-cloudnative = { group = "org.http4k", name = "http4k-cloudnative" } +#http4k-kotlinx = { group = "org.http4k", name = "http4k-format-kotlinx-serialization" } +http4k-format-json = { group = "org.http4k", name = "http4k-format-jackson" } +http4k-format-xml = { group = "org.http4k", name = "http4k-format-jackson-xml" } +http4k-format-yaml = { group = "org.http4k", name = "http4k-format-jackson-yaml" } + +## logging ## +slf4j-api = { group = "org.slf4j", name = "slf4j-api", version.ref = "slf4j" } +kotlin-logging = { group = "io.github.microutils", name = "kotlin-logging-jvm", version = "2.0.11" } +logback-core = { group = "ch.qos.logback", name = "logback-core", version.ref = "qosLogback" } +logback-classic = { group = "ch.qos.logback", name = "logback-classic", version.ref = "qosLogback" } +logback-encoder = { group = "net.logstash.logback", name = "logstash-logback-encoder", version = "6.6" } + +## gcp ## +gcp-bom = { group = "com.google.cloud", name = "libraries-bom", version = "23.1.0" } +gcp-pubsub = { group = "com.google.cloud", name = "google-cloud-pubsub" } +gcp-speech = { group = "com.google.cloud", name = "google-cloud-speech" } + + +############# +### test ### +############# + +mockk = { group = "io.mockk", name = "mockk", version = "1.12.0" } + +## junit ## +junit-bom = { group = "org.junit", name = "junit-bom", version.ref = "junit" } +junit-api = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junit" } +junit-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine", version.ref = "junit" } +junit-launcher = { group = "org.junit.platform", name = "junit-platform-launcher", version = "1.7.2" } + +## kotest ## +kotest-core = { group = "io.kotest", name = "kotest-assertions-core-jvm", version.ref = "kotest" } +kotest-datatest = { group = "io.kotest", name = "kotest-framework-datatest", version.ref = "kotest" } +kotest-runner = { group = "io.kotest", name = "kotest-runner-junit5-jvm", version.ref = "kotest" } +kotest-prop = { group = "io.kotest", name = "kotest-property-jvm", version.ref = "kotest" } +kotest-json = { group = "io.kotest", name = "kotest-assertions-json", version.ref = "kotest" } + +## http4k ## +http4k-test-chaos = { group = "org.http4k", name = "http4k-testing-chaos", version.ref = "http4k" } +http4k-test-approval = { group = "org.http4k", name = "http4k-testing-approval", version.ref = "http4k" } +http4k-test-kotest = { group = "org.http4k", name = "http4k-testing-kotest", version.ref = "http4k" } + + +######### +[bundles] +######### + +logging = [ + "slf4j-api", + "kotlin-logging", + "logback-core", + "logback-classic", + "logback-encoder", +] + +kt-testing = [ + "kotest-core", + "kotest-datatest", + "kotest-runner", + "kotest-prop", + "kotest-json", + "mockk", +] + +junit-runtime = [ + "junit-engine", + "junit-launcher", +] + +http4k = [ + "http4k-core", + "http4k-contract", + "http4k-client", + "http4k-server", + # "http4k-kotlinx", + "http4k-cloudnative", + "http4k-format-xml", + "http4k-format-json", + "http4k-format-yaml", +] + +http4k-test = [ + "http4k-test-chaos", + "http4k-test-approval", + "http4k-test-kotest", +] diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts new file mode 100644 index 0000000..2c1a95a --- /dev/null +++ b/modules/mod/build.gradle.kts @@ -0,0 +1,151 @@ +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + +plugins { +// kotlin("js") + id("com.github.node-gradle.node") +} + +group = "${rootProject.group}.mod" +version = rootProject.version + +node { + download.set(true) + version.set("14.18.0") +// version.set("16.10.0") +} +// "@types/node": "ts4.4", +// 16.10.3 = ts4.4, see https://www.npmjs.com/package/@types/node + + +//repositories { +// mavenCentral() +// maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") +// maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") +//} + +//kotlin { +// js(IR) { +// +// binaries.executable() +// +// browser { +// commonWebpackConfig { +// cssSupport.enabled = true +// } +// } +// +// useCommonJs() +// nodejs() +// +// compilations["main"].apply { +// packageJson { +// customField( +// "scripts", +// mapOf( +// "build" to "tstl", +// "dev" to "tstl --watch", +// ) +// ) +// } +// } +// } +// +// sourceSets { +// val main by getting { +//// kotlin.srcDir("externals02") +//// kotlin.srcDir("externals") +// +// dependencies { +// +// val kotlinWrappersVersion = "0.0.1-pre.254-kotlin-1.5.31" +// implementation( +// project.dependencies.enforcedPlatform( +// "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" +// ) +// ) +// +// implementation("org.jetbrains.kotlin-wrappers:kotlin-react") +// implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom") +// implementation(npm("react", "17.0.2")) +// implementation(npm("react-dom", "17.0.2")) +// +//// implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7") { +//// because("https://github.com/Kotlin/kotlinx-nodejs") +//// } +// +// val generateExternals = false +// implementation(npm("typescript-to-lua", "1.0.1", generateExternals = generateExternals)) +// implementation(npm("typed-factorio", "0.7.1", generateExternals = generateExternals)) +// implementation(npm("lua-types", "2.11.0", generateExternals = generateExternals)) +// implementation(npm("typescript", "4.4.3", generateExternals = generateExternals)) +// } +// } +// +// val test by getting { +// dependencies { +// implementation(kotlin("test-js")) +// } +// } +// } +// +//} + +val tstlTask = tasks.register("tstl") { + description = "Typescript To Lua" + group = "${rootProject.group}" + dependsOn(tasks.npmInstall) + + npmCommand.set(listOf("run", "build")) + args.set(listOf("--", "--outDir", "$buildDir/npm-output")) +// args.set(listOf("test")) + ignoreExitValue.set(false) +// environment.set(mapOf("MY_CUSTOM_VARIABLE" to "hello")) + workingDir.set(projectDir) + execOverrides { + standardOutput = System.out + } + inputs.dir("node_modules") + inputs.dir(fileTree("src/main/typescript")) + inputs.files( + "tsconfig.json", + "package.json", + ) + outputs.dir("$buildDir/factorio-web-map/") +// outputs.dir("$buildDir/npm-output") +// outputs.upToDateWhen { true } +} + +//sourceSets { +// val typescript by creating { +// setBuildDir("src/main/typescript") +// } +//} + + +//dependencies { +// val kotlinWrappersVersion = "0.0.1-pre.254-kotlin-1.5.31" +// implementation( +// project.dependencies.enforcedPlatform( +// "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" +// ) +// ) +// +// implementation("org.jetbrains.kotlin-wrappers:kotlin-react") +// implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom") +// implementation(npm("react", "17.0.2")) +// implementation(npm("react-dom", "17.0.2")) +// +// // @types/node + +//// implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7") { +//// because("https://github.com/Kotlin/kotlinx-nodejs") +//// } +// +// val generateExternals = false +// implementation(npm("typescript-to-lua", "1.0.1", generateExternals = generateExternals)) +// implementation(npm("typed-factorio", "0.7.1", generateExternals = generateExternals)) +// implementation(npm("lua-types", "2.11.0", generateExternals = generateExternals)) +// implementation(npm("typescript", "4.4.3", generateExternals = generateExternals)) +// +// testImplementation(kotlin("test-js")) +//} \ No newline at end of file diff --git a/modules/mod/events.lua b/modules/mod/events.lua new file mode 100644 index 0000000..ef8f222 --- /dev/null +++ b/modules/mod/events.lua @@ -0,0 +1,9 @@ +--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]] +script.on_event( + {defines.events.on_pre_build, defines.events.on_player_dropped_item}, + function(e) + log( + (("player " .. tostring(e.player_index)) .. " dropped item, tick:") .. tostring(e.tick) + ) + end +) diff --git a/modules/mod/package-lock.json b/modules/mod/package-lock.json new file mode 100644 index 0000000..403b9ef --- /dev/null +++ b/modules/mod/package-lock.json @@ -0,0 +1,1329 @@ +{ + "name": "factorio-web-map-mod", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@discoveryjs/json-ext": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz", + "integrity": "sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA==", + "dev": true + }, + "@types/eslint": { + "version": "7.28.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.1.tgz", + "integrity": "sha512-XhZKznR3i/W5dXqUhgU9fFdJekufbeBd5DALmkuXoeFcjbQcPk+2cL+WLHf6Q81HWAnM2vrslIHpGVyCAviRwg==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "0.0.47", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz", + "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "@types/node": { + "version": "16.10.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.3.tgz", + "integrity": "sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", + "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", + "dev": true, + "requires": { + "@webassemblyjs/helper-numbers": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", + "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", + "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", + "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==", + "dev": true + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", + "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", + "dev": true, + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.0", + "@webassemblyjs/helper-api-error": "1.11.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", + "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", + "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", + "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", + "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", + "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", + "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/helper-wasm-section": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/wasm-opt": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0", + "@webassemblyjs/wast-printer": "1.11.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", + "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/utf8": "1.11.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", + "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-buffer": "1.11.0", + "@webassemblyjs/wasm-gen": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", + "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/helper-api-error": "1.11.0", + "@webassemblyjs/helper-wasm-bytecode": "1.11.0", + "@webassemblyjs/ieee754": "1.11.0", + "@webassemblyjs/leb128": "1.11.0", + "@webassemblyjs/utf8": "1.11.0" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", + "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.0", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/configtest": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.0.tgz", + "integrity": "sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==", + "dev": true + }, + "@webpack-cli/info": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.0.tgz", + "integrity": "sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==", + "dev": true, + "requires": { + "envinfo": "^7.7.3" + } + }, + "@webpack-cli/serve": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.0.tgz", + "integrity": "sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==", + "dev": true + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "browserslist": { + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.3.tgz", + "integrity": "sha512-59IqHJV5VGdcJZ+GZ2hU5n4Kv3YiASzW6Xk5g9tf5a/MAzGeFwgGWU39fVzNIOVcgB3+Gp+kiQu0HEfTVU/3VQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001264", + "electron-to-chromium": "^1.3.857", + "escalade": "^3.1.1", + "node-releases": "^1.1.77", + "picocolors": "^0.2.1" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001265", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001265.tgz", + "integrity": "sha512-YzBnspggWV5hep1m9Z6sZVLOt7vrju8xWooFAgN6BA5qvy98qPAPb7vNUzypFaoh2pb3vlfzbDO8tB57UPGbtw==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "colorette": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "css-loader": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.6.tgz", + "integrity": "sha512-0wyN5vXMQZu6BvjbrPdUJvkCzGEO24HC7IS7nW4llc6BBFC+zwR9CKtYGv63Puzsg10L/o12inMY5/2ByzfD6w==", + "dev": true, + "requires": { + "icss-utils": "^5.1.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.15", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.1.0", + "schema-utils": "^3.0.0", + "semver": "^7.3.5" + } + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.864", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.864.tgz", + "integrity": "sha512-v4rbad8GO6/yVI92WOeU9Wgxc4NA0n4f6P1FvZTY+jyY7JHEhw3bduYu60v3Q1h81Cg6eo4ApZrFPuycwd5hGw==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "enhanced-resolve": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", + "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true + }, + "es-module-lexer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", + "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "format-util": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/format-util/-/format-util-1.0.5.tgz", + "integrity": "sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg==", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true + }, + "import-local": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", + "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "dev": true + }, + "is-core-module": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz", + "integrity": "sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==", + "requires": { + "has": "^1.0.3" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "jest-worker": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.2.5.tgz", + "integrity": "sha512-HTjEPZtcNKZ4LnhSp02NEH4vE+5OpJ0EsOWYvGQpHgUMLngydESAAMH5Wd/asPf29+XUDQZszxpLg1BkIIA2aw==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "loader-runner": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", + "dev": true + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "lua-types": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.11.0.tgz", + "integrity": "sha512-J/8qHrOjkZuPBDhnuAg0DWoaJEImqXNzgEnUigCTVrSVCcchM5Y5zpcI3aWAZPhuZlb0QKC/f3nc7VGmZmBg7w==" + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "mime-db": { + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", + "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", + "dev": true + }, + "mime-types": { + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", + "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", + "dev": true, + "requires": { + "mime-db": "1.50.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "nanoid": { + "version": "3.1.29", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.29.tgz", + "integrity": "sha512-dW2pUSGZ8ZnCFIlBIA31SV8huOGCHb6OwzVCc7A69rb/a+SgPBwfmLvK5TKQ3INPbRkcI8a/Owo0XbiTNH19wg==", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node-releases": { + "version": "1.1.77", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.77.tgz", + "integrity": "sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + }, + "dependencies": { + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + } + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "postcss": { + "version": "8.3.9", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.9.tgz", + "integrity": "sha512-f/ZFyAKh9Dnqytx5X62jgjhhzttjZS7hMsohcI7HEI5tjELX/HxCy3EFhsRxyzGvrzFF+82XPvCS8T9TFleVJw==", + "dev": true, + "requires": { + "nanoid": "^3.1.28", + "picocolors": "^0.2.1", + "source-map-js": "^0.6.2" + } + }, + "postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true + }, + "postcss-modules-local-by-default": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", + "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", + "dev": true, + "requires": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.4" + } + }, + "postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "requires": { + "icss-utils": "^5.0.0" + } + }, + "postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "react-dom": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" + } + }, + "rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "dev": true, + "requires": { + "resolve": "^1.9.0" + } + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", + "dev": true + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + }, + "source-map-js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", + "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==", + "dev": true + }, + "source-map-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.0.tgz", + "integrity": "sha512-GKGWqWvYr04M7tn8dryIWvb0s8YM41z82iQv01yBtIylgxax0CwvSy6gc2Y02iuXwEfGWRlMicH0nvms9UZphw==", + "dev": true, + "requires": { + "abab": "^2.0.5", + "iconv-lite": "^0.6.2", + "source-map-js": "^0.6.2" + } + }, + "source-map-support": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "style-loader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz", + "integrity": "sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" + }, + "terser": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.9.0.tgz", + "integrity": "sha512-h5hxa23sCdpzcye/7b8YqbE5OwKca/ni0RQz1uRX3tGh8haaGHqcuSqbGRybuAKNdntZ0mDgFNXPJ48xQ2RXKQ==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.20" + } + }, + "terser-webpack-plugin": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.2.4.tgz", + "integrity": "sha512-E2CkNMN+1cho04YpdANyRrn8CyN4yMy+WdFKZIySFZrGXZxJwJP6PMNGGc/Mcr6qygQHUUqRxnAPmi0M9f00XA==", + "dev": true, + "requires": { + "jest-worker": "^27.0.6", + "p-limit": "^3.1.0", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1", + "terser": "^5.7.2" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "typed-factorio": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.7.1.tgz", + "integrity": "sha512-2WdnkUuWnVk2SDV3TmabDsnfpw5kvKOkg/2br7bcJ1qzAXT4dgrMK/HwL5bUubKf67xTi1rKykaQ/qjhP3TqLw==", + "requires": { + "lua-types": "^2.10.1", + "typescript": "~4.3.5", + "typescript-to-lua": "^1.0.0" + }, + "dependencies": { + "typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==" + } + } + }, + "typescript": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", + "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==" + }, + "typescript-to-lua": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.0.1.tgz", + "integrity": "sha512-j5mb+8HgUUY8hhAKoNy6KUMeamEN1fsTtMvSbPaxmVkWw40pHdLi3umsQG+Qo7wM6IK+RQffFxbIWEjleF+xpw==", + "requires": { + "enhanced-resolve": "^5.8.2", + "resolve": "^1.15.1", + "source-map": "^0.7.3", + "typescript": "~4.3.5" + }, + "dependencies": { + "typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==" + } + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "watchpack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", + "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", + "dev": true, + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "webpack": { + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.38.1.tgz", + "integrity": "sha512-OqRmYD1OJbHZph6RUMD93GcCZy4Z4wC0ele4FXyYF0J6AxO1vOSuIlU1hkS/lDlR9CDYBz64MZRmdbdnFFoT2g==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.47", + "@webassemblyjs/ast": "1.11.0", + "@webassemblyjs/wasm-edit": "1.11.0", + "@webassemblyjs/wasm-parser": "1.11.0", + "acorn": "^8.2.1", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.0", + "es-module-lexer": "^0.4.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.0.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.1", + "watchpack": "^2.2.0", + "webpack-sources": "^2.3.0" + } + }, + "webpack-cli": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.7.1.tgz", + "integrity": "sha512-DJPd63AY53KXWOaD8cB8CaHR0epVP4O4GBIAk6wCPQHJugrAQ0B5kUkCg0c9vkIrD2kA6CXCmtWqKQsiVTo15A==", + "dev": true, + "requires": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.0.4", + "@webpack-cli/info": "^1.3.0", + "@webpack-cli/serve": "^1.5.0", + "colorette": "^1.2.1", + "commander": "^7.0.0", + "execa": "^5.0.0", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "v8-compile-cache": "^2.2.0", + "webpack-merge": "^5.7.3" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + } + } + }, + "webpack-merge": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + } + }, + "webpack-sources": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", + "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", + "dev": true, + "requires": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/modules/mod/package.json b/modules/mod/package.json new file mode 100644 index 0000000..dc0fc6b --- /dev/null +++ b/modules/mod/package.json @@ -0,0 +1,28 @@ +{ + "name": "factorio-web-map-mod", + "version": "0.0.1", + "private": true, + "scripts": { + "build": "tstl", + "dev": "tstl --watch" + }, + "devDependencies": { + "webpack": "5.38.1", + "webpack-cli": "4.7.1", + "format-util": "1.0.5", + "source-map-loader": "3.0.0", + "css-loader": "5.2.6", + "style-loader": "2.0.0" + }, + "dependencies": { + "react": "17.0.2", + "react-dom": "17.0.2", + "typescript-to-lua": "1.0.1", + "typed-factorio": "0.7.1", + "lua-types": "2.11.0", + "typescript": "4.4.3" + }, + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] +} diff --git a/modules/mod/settings.gradle.kts b/modules/mod/settings.gradle.kts new file mode 100644 index 0000000..90bb0a9 --- /dev/null +++ b/modules/mod/settings.gradle.kts @@ -0,0 +1,3 @@ +rootProject.name = "factorio-web-map-mod" + +rootProject.description = "Factorio Web Map mod" diff --git a/modules/mod/src/main/typescript/events.ts b/modules/mod/src/main/typescript/events.ts new file mode 100644 index 0000000..c8453b4 --- /dev/null +++ b/modules/mod/src/main/typescript/events.ts @@ -0,0 +1,6 @@ +script.on_event( + [defines.events.on_pre_build, defines.events.on_player_dropped_item], + (e: OnPreBuildEvent | OnPlayerDroppedItemEvent) => { + log("player " + e.player_index + " dropped item, tick:" + e.tick) + } +) \ No newline at end of file diff --git a/modules/mod/tsconfig.json b/modules/mod/tsconfig.json new file mode 100644 index 0000000..43cb2d2 --- /dev/null +++ b/modules/mod/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "esnext", + "lib": [ + "esnext" + ], + "moduleResolution": "node", + "types": [ + "typed-factorio/runtime" + ], + "strict": true + }, + "tstl": { + "luaTarget": "JIT", + "tstlVerbose": true + } +} diff --git a/modules/server/build.gradle.kts b/modules/server/build.gradle.kts new file mode 100644 index 0000000..0bbe330 --- /dev/null +++ b/modules/server/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + kotlin("jvm") +} + +group = "${rootProject.group}.server" +version = rootProject.version + diff --git a/modules/server/settings.gradle.kts b/modules/server/settings.gradle.kts new file mode 100644 index 0000000..36dc4be --- /dev/null +++ b/modules/server/settings.gradle.kts @@ -0,0 +1,3 @@ +rootProject.name = "factorio-web-map-server" + +rootProject.description = "Factorio Web Map server" diff --git a/src/jsMain/kotlin/factorio.kt b/src/jsMain/kotlin/factorio.kt new file mode 100644 index 0000000..b28b04f --- /dev/null +++ b/src/jsMain/kotlin/factorio.kt @@ -0,0 +1,3 @@ + + + From 877c1cdb98bb2e8ec905d8aa74c1350e31a9787b Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sun, 10 Oct 2021 20:20:01 +0200 Subject: [PATCH 007/629] - custom generate typed-factorio files - buildSrc archetype plugins --- build.gradle.kts | 137 +- buildSrc/build.gradle.kts | 15 + buildSrc/settings.gradle.kts | 43 + .../factoriowebmap/archetype/base.gradle.kts | 15 + .../archetype/kotlin-js.gradle.kts | 72 + .../archetype/kotlin-jvm.gradle.kts | 13 + modules/mod/build.gradle.kts | 172 +- modules/mod/data.ts | 1 + modules/mod/events.lua | 9 - modules/mod/item.ts | 12 + modules/mod/settings.gradle.kts | 3 - modules/mod/src/changelog.txt | 4 + modules/mod/src/control.ts | 1 + modules/mod/src/events.ts | 19 + modules/mod/src/info.json | 8 + modules/mod/src/main/typescript/events.ts | 6 - modules/mod/{ => src}/package-lock.json | 0 modules/mod/{ => src}/package.json | 6 +- modules/mod/src/thumbnail.png | Bin 0 -> 702 bytes modules/mod/{ => src}/tsconfig.json | 0 modules/mod/test/docker-compose.yml | 19 + modules/mod2/build.gradle.kts | 159 + .../5.2-only.bit32.module_lua-types.kt | 41 + .../dukat-custom/5.2-only.module_lua-types.kt | 17 + .../5.2-plus-or-jit.module_lua-types.kt | 37 + .../dukat-custom/5.2-plus.module_lua-types.kt | 22 + .../builtin-types.module_typed-factorio.kt | 33 + .../classes.module_typed-factorio.kt | 5723 +++++++++++ .../concepts.module_typed-factorio.kt | 2924 ++++++ .../coroutine.coroutine.module_lua-types.kt | 30 + .../debug.debug.module_lua-types.kt | 162 + ...behavior.inserter.module_typed-factorio.kt | 30 + ...rol_behavior.lamp.module_typed-factorio.kt | 21 + ...ogistic_container.module_typed-factorio.kt | 22 + ...vior.mining_drill.module_typed-factorio.kt | 22 + ....control_behavior.module_typed-factorio.kt | 38 + ...or.transport_belt.module_typed-factorio.kt | 22 + ...construction_item.module_typed-factorio.kt | 34 + ...fficulty_settings.module_typed-factorio.kt | 27 + ...es.defines.events.module_typed-factorio.kt | 364 + .../defines.defines.module_typed-factorio.kt | 668 ++ ...es.defines.riding.module_typed-factorio.kt | 30 + .../events.module_typed-factorio.kt | 1574 +++ .../global-objects.module_typed-factorio.kt | 29 + .../dukat-custom/global.module_lua-types.kt | 81 + .../index.module_typescript-to-lua.kt | 42 + .../dukat-custom/io.io.module_lua-types.kt | 57 + .../mod2/dukat-custom/io.module_lua-types.kt | 28 + modules/mod2/dukat-custom/lib.dom.kt | 31 + .../mod2/dukat-custom/lib.es2015.iterable.kt | 40 + modules/mod2/dukat-custom/lib.es5.kt | 74 + ...ariesAndFunctions.module_typed-factorio.kt | 135 + ...Functions.serpent.module_typed-factorio.kt | 32 + .../math.math.module_lua-types.kt | 75 + .../metatable.module_lua-types.kt | 49 + .../mod-gui.mod_gui.module_typed-factorio.kt | 29 + .../dukat-custom/modules.module_lua-types.kt | 17 + .../modules.package.module_lua-types.kt | 34 + .../mod2/dukat-custom/nonDeclarations.io.kt | 18 + .../mod2/dukat-custom/os.module_lua-types.kt | 45 + .../dukat-custom/os.os.module_lua-types.kt | 56 + .../pairs.module_typed-factorio.kt | 22 + .../string.string.module_lua-types.kt | 63 + .../table.table.module_lua-types.kt | 39 + .../types.module_typed-factorio.kt | 91 + .../util.util.module_typed-factorio.kt | 111 + .../util.util.table.module_typed-factorio.kt | 21 + ...ompilerOptions.module_typescript-to-lua.kt | 75 + .../LuaAST.module_typescript-to-lua.kt | 485 + .../LuaLib.module_typescript-to-lua.kt | 111 + .../LuaPrinter.module_typescript-to-lua.kt | 101 + .../context.module_typescript-to-lua.kt | 80 + .../index.module_typescript-to-lua.kt | 39 + .../mod2/externals/lib.es2015.collection.kt | 49 + modules/mod2/externals/lib.es2015.iterable.kt | 54 + .../externals/lib.es5.Intl.module_dukat.kt | 220 + modules/mod2/externals/lib.es5.kt | 69 + modules/mod2/externals/lib.scripthost.kt | 20 + modules/mod2/externals/nonDeclarations.ts.kt | 114 + ...tput-collector.module_typescript-to-lua.kt | 33 + .../parse.module_typescript-to-lua.kt | 21 + .../plugins.module_typescript-to-lua.kt | 24 + .../report.module_typescript-to-lua.kt | 48 + .../externals/source-map.module_source-map.kt | 192 + .../transpile.module_typescript-to-lua.kt | 40 + .../transpiler.module_typescript-to-lua.kt | 55 + .../tsconfig.module_typescript-to-lua.kt | 19 + .../externals/typescript.module_typescript.kt | 19 + ...ipt.ts.ScriptSnapshot.module_typescript.kt | 20 + .../typescript.ts.module_typescript.kt | 8487 +++++++++++++++++ .../typescript.ts.server.module_typescript.kt | 104 + .../utils.module_typescript-to-lua.kt | 46 + .../visitors.module_typescript-to-lua.kt | 38 + modules/server/settings.gradle.kts | 3 - settings.gradle.kts | 31 +- xbuild.gradle.kts | 124 + 96 files changed, 24216 insertions(+), 279 deletions(-) create mode 100644 buildSrc/build.gradle.kts create mode 100644 buildSrc/settings.gradle.kts create mode 100644 buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts create mode 100644 buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts create mode 100644 buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts create mode 100644 modules/mod/data.ts delete mode 100644 modules/mod/events.lua create mode 100644 modules/mod/item.ts delete mode 100644 modules/mod/settings.gradle.kts create mode 100644 modules/mod/src/changelog.txt create mode 100644 modules/mod/src/control.ts create mode 100644 modules/mod/src/events.ts create mode 100644 modules/mod/src/info.json delete mode 100644 modules/mod/src/main/typescript/events.ts rename modules/mod/{ => src}/package-lock.json (100%) rename modules/mod/{ => src}/package.json (89%) create mode 100644 modules/mod/src/thumbnail.png rename modules/mod/{ => src}/tsconfig.json (100%) create mode 100644 modules/mod/test/docker-compose.yml create mode 100644 modules/mod2/build.gradle.kts create mode 100644 modules/mod2/dukat-custom/5.2-only.bit32.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/5.2-only.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/5.2-plus-or-jit.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/5.2-plus.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/builtin-types.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/classes.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/concepts.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/coroutine.coroutine.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/debug.debug.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/defines.defines.control_behavior.inserter.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/defines.defines.control_behavior.lamp.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/defines.defines.control_behavior.logistic_container.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/defines.defines.control_behavior.mining_drill.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/defines.defines.control_behavior.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/defines.defines.control_behavior.transport_belt.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/defines.defines.deconstruction_item.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/defines.defines.difficulty_settings.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/defines.defines.events.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/defines.defines.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/defines.defines.riding.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/events.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/global-objects.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/global.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/index.module_typescript-to-lua.kt create mode 100644 modules/mod2/dukat-custom/io.io.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/io.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/lib.dom.kt create mode 100644 modules/mod2/dukat-custom/lib.es2015.iterable.kt create mode 100644 modules/mod2/dukat-custom/lib.es5.kt create mode 100644 modules/mod2/dukat-custom/librariesAndFunctions.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/librariesAndFunctions.serpent.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/math.math.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/metatable.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/mod-gui.mod_gui.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/modules.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/modules.package.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/nonDeclarations.io.kt create mode 100644 modules/mod2/dukat-custom/os.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/os.os.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/pairs.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/string.string.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/table.table.module_lua-types.kt create mode 100644 modules/mod2/dukat-custom/types.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/util.util.module_typed-factorio.kt create mode 100644 modules/mod2/dukat-custom/util.util.table.module_typed-factorio.kt create mode 100644 modules/mod2/externals/CompilerOptions.module_typescript-to-lua.kt create mode 100644 modules/mod2/externals/LuaAST.module_typescript-to-lua.kt create mode 100644 modules/mod2/externals/LuaLib.module_typescript-to-lua.kt create mode 100644 modules/mod2/externals/LuaPrinter.module_typescript-to-lua.kt create mode 100644 modules/mod2/externals/context.module_typescript-to-lua.kt create mode 100644 modules/mod2/externals/index.module_typescript-to-lua.kt create mode 100644 modules/mod2/externals/lib.es2015.collection.kt create mode 100644 modules/mod2/externals/lib.es2015.iterable.kt create mode 100644 modules/mod2/externals/lib.es5.Intl.module_dukat.kt create mode 100644 modules/mod2/externals/lib.es5.kt create mode 100644 modules/mod2/externals/lib.scripthost.kt create mode 100644 modules/mod2/externals/nonDeclarations.ts.kt create mode 100644 modules/mod2/externals/output-collector.module_typescript-to-lua.kt create mode 100644 modules/mod2/externals/parse.module_typescript-to-lua.kt create mode 100644 modules/mod2/externals/plugins.module_typescript-to-lua.kt create mode 100644 modules/mod2/externals/report.module_typescript-to-lua.kt create mode 100644 modules/mod2/externals/source-map.module_source-map.kt create mode 100644 modules/mod2/externals/transpile.module_typescript-to-lua.kt create mode 100644 modules/mod2/externals/transpiler.module_typescript-to-lua.kt create mode 100644 modules/mod2/externals/tsconfig.module_typescript-to-lua.kt create mode 100644 modules/mod2/externals/typescript.module_typescript.kt create mode 100644 modules/mod2/externals/typescript.ts.ScriptSnapshot.module_typescript.kt create mode 100644 modules/mod2/externals/typescript.ts.module_typescript.kt create mode 100644 modules/mod2/externals/typescript.ts.server.module_typescript.kt create mode 100644 modules/mod2/externals/utils.module_typescript-to-lua.kt create mode 100644 modules/mod2/externals/visitors.module_typescript-to-lua.kt delete mode 100644 modules/server/settings.gradle.kts create mode 100644 xbuild.gradle.kts diff --git a/build.gradle.kts b/build.gradle.kts index 90efe8e..c85d539 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,135 +1,16 @@ -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension - plugins { - kotlin("multiplatform") version "1.5.31" + base + +// val kotlinVersion = "1.5.31" +// kotlin("jvm") version kotlinVersion apply false +// kotlin("js") version kotlinVersion apply false +// kotlin("multiplatform") version kotlinVersion apply false + +// id("com.github.node-gradle.node") version "3.1.1" apply false } group = "dev.adamko.factoriowebmap" -version = "1.0-SNAPSHOT" - -//repositories { -// mavenCentral() -// maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") -//} - - -kotlin { - - // - val hostOs = System.getProperty("os.name") - val isMingwX64 = hostOs.startsWith("Windows") - val nativeTarget = when { - hostOs == "Mac OS X" -> macosX64("native") - hostOs == "Linux" -> linuxX64("native") - isMingwX64 -> mingwX64("native") - else -> throw GradleException( - "Host OS '$hostOs' is not supported in Kotlin/Native.") - } - - nativeTarget.apply { - binaries { - executable { - entryPoint = "main" - } - sharedLib { - baseName = if (isMingwX64) "libnative" else "native" - } - } - } - sourceSets { - val nativeMain by getting { - dependencies { - implementation("com.soywiz.korlibs.luak:luak:2.4.3") - } - } - val nativeTest by getting { - dependencies { - implementation(kotlin("test")) - - } - } - } - // - - // - js(IR) { - binaries.executable() - browser { - commonWebpackConfig { - cssSupport.enabled = true - } - } - - useCommonJs() - nodejs() - - compilations.all { - packageJson { - customField( - "scripts", mapOf( - "build" to "tstl", - "dev" to "tstl --watch", - ) - ) - } - } -// compilations["main"] -// .packageJson { -// customField( -// "scripts", mapOf( -// "build" to "tstl", -// "dev" to "tstl --watch", -// ) -// ) -// } - } - - sourceSets { - - val jsMain by getting { - kotlin.srcDir("externals02") -// kotlin.srcDir("externals") - - dependencies { - - val kotlinWrappersVersion = "0.0.1-pre.254-kotlin-1.5.31" - implementation( - project.dependencies.enforcedPlatform( - "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" - ) - ) - - implementation("org.jetbrains.kotlin-wrappers:kotlin-react") - implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom") - implementation(npm("react", "17.0.2")) - implementation(npm("react-dom", "17.0.2")) - -// implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7") { -// because("https://github.com/Kotlin/kotlinx-nodejs") -// } - - val generateExternals = false - implementation(npm("typescript-to-lua", "1.0.1", generateExternals = generateExternals)) - implementation(npm("typed-factorio", "0.7.1", generateExternals = generateExternals)) - implementation(npm("lua-types", "2.11.0", generateExternals = generateExternals)) - implementation(npm("typescript", "4.4.3", generateExternals = generateExternals)) - } - } - - val jsTest by getting { - dependencies { - implementation(kotlin("test-js")) - } - } - } - // - -} - -configure { - versions.dukat.version = "0.5.8-rc.4-dev.20211001" -// versions.dukat.version = "0.5.8-rc.4" -} +version = "0.0.2" tasks.wrapper { gradleVersion = "7.2" diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 0000000..4f2b743 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,15 @@ +plugins { + `kotlin-dsl` +} + +dependencies { + + val kotlinVersion = "1.5.31" + + implementation(platform("org.jetbrains.kotlin:kotlin-bom:$kotlinVersion")) + + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin") + + implementation("com.github.node-gradle:gradle-node-plugin:3.1.1") + +} diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts new file mode 100644 index 0000000..3080aa2 --- /dev/null +++ b/buildSrc/settings.gradle.kts @@ -0,0 +1,43 @@ +rootProject.name = "buildSrc" + +enableFeaturePreview("VERSION_CATALOGS") +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + + repositories { + mavenCentral() + gradlePluginPortal() + maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") + maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") + + // Declare the Node.js download repository + ivy { + name = "Node.js" + setUrl("https://nodejs.org/dist/") + patternLayout { + artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") + } + metadataSources { + artifact() + } + content { + includeModule("org.nodejs", "node") + } + } + } + + pluginManagement { + + repositories { + mavenCentral() + gradlePluginPortal() + maven { + url = uri("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") + } + } + + } + +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts new file mode 100644 index 0000000..02ed00f --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts @@ -0,0 +1,15 @@ +package dev.adamko.factoriowebmap.archetype + +plugins { + base +} + +group = rootProject.group.toString() + "." + project.name +version = rootProject.version + +val projectId by extra(rootProject.name + "-" + project.name) +val modBuildDir by extra(layout.buildDirectory.dir(projectId).get()) + +//group = "dev.adamko.factoriowebmap" +//version = "0.0.1" + diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts new file mode 100644 index 0000000..176bf65 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts @@ -0,0 +1,72 @@ +package dev.adamko.factoriowebmap.archetype + +import org.gradle.kotlin.dsl.kotlin +import com.github.gradle.node.npm.task.NpmTask +import com.github.gradle.node.task.NodeTask +import org.jetbrains.kotlin.gradle.targets.js.dukat.DtsResolver +import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask +import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs +import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject + + +plugins { + kotlin("js") + id("com.github.node-gradle.node") + id("dev.adamko.factoriowebmap.archetype.base") +} + +kotlin { + js(IR) { + + binaries.executable() + + useCommonJs() + nodejs() +// +//// compilations.all { +// compilations["main"].apply { +// packageJson { +// customField( +// "scripts", +// mapOf( +// "build" to "tstl", +// "dev" to "tstl --watch", +// ) +// ) +// } +// } + } +} + +val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) + +//fun NpmTask.setNodeModulesPath(path: String): Unit = +// environment.put("NODE_PATH", path) +// +//fun NpmTask.setNodeModulesPath(folder: File): Unit = +// setNodeModulesPath(folder.normalize().absolutePath) + + +val nodePath: Directory by extra { + val file = rootPackageJson.rootPackageJson.parentFile.normalize() + logger.lifecycle("Found root NODE_PATH: $file") + project.layout.dir(provider { file }).get() +} + +val nodeModulesDir: Directory by extra { + val file = nodePath.dir(NpmProject.NODE_MODULES) + logger.lifecycle("Found root NODE_MODULES: $file") + file +} + +node { + download.set(true) + version.set("14.18.0") + + distBaseUrl.set(null as String?) // set by dependencyResolutionManagement + + nodeProjectDir.set(nodePath) +// nodeProjectDir.set(packageJson.packageJson.parentFile.normalize()) +} + diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts new file mode 100644 index 0000000..4ad22ae --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts @@ -0,0 +1,13 @@ +package dev.adamko.factoriowebmap.archetype + +plugins { + id("dev.adamko.factoriowebmap.archetype.base") + kotlin("jvm") +} + +kotlin { +} + +dependencies { + implementation(platform("org.jetbrains.kotlin:kotlin-bom")) +} diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index 2c1a95a..742c8f3 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -1,7 +1,8 @@ +import com.github.gradle.node.npm.task.NpmTask import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { -// kotlin("js") + base id("com.github.node-gradle.node") } @@ -11,141 +12,62 @@ version = rootProject.version node { download.set(true) version.set("14.18.0") -// version.set("16.10.0") + + nodeProjectDir.set(layout.projectDirectory.dir("src")) + + distBaseUrl.set(null as String?) // set root dependencyResolutionManagement } -// "@types/node": "ts4.4", -// 16.10.3 = ts4.4, see https://www.npmjs.com/package/@types/node +val projectId = rootProject.name + "-" + project.name +val modBuildDir = layout.buildDirectory.dir(projectId).get() +//val tsSrcDir = layout.projectDirectory.dir("src") -//repositories { -// mavenCentral() -// maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") -// maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") -//} - -//kotlin { -// js(IR) { -// -// binaries.executable() -// -// browser { -// commonWebpackConfig { -// cssSupport.enabled = true -// } -// } -// -// useCommonJs() -// nodejs() -// -// compilations["main"].apply { -// packageJson { -// customField( -// "scripts", -// mapOf( -// "build" to "tstl", -// "dev" to "tstl --watch", -// ) -// ) -// } -// } -// } -// -// sourceSets { -// val main by getting { -//// kotlin.srcDir("externals02") -//// kotlin.srcDir("externals") -// -// dependencies { -// -// val kotlinWrappersVersion = "0.0.1-pre.254-kotlin-1.5.31" -// implementation( -// project.dependencies.enforcedPlatform( -// "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" -// ) -// ) -// -// implementation("org.jetbrains.kotlin-wrappers:kotlin-react") -// implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom") -// implementation(npm("react", "17.0.2")) -// implementation(npm("react-dom", "17.0.2")) -// -//// implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7") { -//// because("https://github.com/Kotlin/kotlinx-nodejs") -//// } -// -// val generateExternals = false -// implementation(npm("typescript-to-lua", "1.0.1", generateExternals = generateExternals)) -// implementation(npm("typed-factorio", "0.7.1", generateExternals = generateExternals)) -// implementation(npm("lua-types", "2.11.0", generateExternals = generateExternals)) -// implementation(npm("typescript", "4.4.3", generateExternals = generateExternals)) -// } -// } -// -// val test by getting { -// dependencies { -// implementation(kotlin("test-js")) -// } -// } -// } -// -//} - -val tstlTask = tasks.register("tstl") { +val tstlTask = tasks.register("tstl") { description = "Typescript To Lua" - group = "${rootProject.group}" + group = projectId + dependsOn(tasks.npmInstall) + execOverrides { standardOutput = System.out } + npmCommand.set(listOf("run", "build")) - args.set(listOf("--", "--outDir", "$buildDir/npm-output")) -// args.set(listOf("test")) + + val outputDir = modBuildDir.dir("tstl") + args.set(parseSpaceSeparatedArgs("-- --outDir $outputDir")) + outputs.dir(outputDir) + ignoreExitValue.set(false) -// environment.set(mapOf("MY_CUSTOM_VARIABLE" to "hello")) - workingDir.set(projectDir) - execOverrides { - standardOutput = System.out - } - inputs.dir("node_modules") - inputs.dir(fileTree("src/main/typescript")) - inputs.files( - "tsconfig.json", - "package.json", - ) - outputs.dir("$buildDir/factorio-web-map/") +// workingDir.set(tsSrcDir.asFile) + inputs.dir(node.nodeProjectDir) +// inputs.dir("node_modules") +// inputs.dir(fileTree("src")) +// inputs.files( +// "tsconfig.json", +// "package.json", +// ) +// outputs.dir("$buildDir/factorio-web-map/") // outputs.dir("$buildDir/npm-output") -// outputs.upToDateWhen { true } +// outputs.upToDateWhen { false } } -//sourceSets { -// val typescript by creating { -// setBuildDir("src/main/typescript") -// } -//} +val modPackageTask = tasks.register("package") { + description = "Package mod" + group = projectId + dependsOn(tstlTask) -//dependencies { -// val kotlinWrappersVersion = "0.0.1-pre.254-kotlin-1.5.31" -// implementation( -// project.dependencies.enforcedPlatform( -// "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" -// ) -// ) -// -// implementation("org.jetbrains.kotlin-wrappers:kotlin-react") -// implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom") -// implementation(npm("react", "17.0.2")) -// implementation(npm("react-dom", "17.0.2")) -// -// // @types/node + from(layout.projectDirectory.dir("src")) { + exclude("*.ts") + into(rootProject.name) + } + from(tstlTask) { + into(rootProject.name) + } + + archiveFileName.set("${rootProject.name}_${rootProject.version}.zip") + destinationDirectory.set(modBuildDir.dir("dist")) + +} + +tasks.build { dependsOn(tstlTask, modPackageTask) } -//// implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7") { -//// because("https://github.com/Kotlin/kotlinx-nodejs") -//// } -// -// val generateExternals = false -// implementation(npm("typescript-to-lua", "1.0.1", generateExternals = generateExternals)) -// implementation(npm("typed-factorio", "0.7.1", generateExternals = generateExternals)) -// implementation(npm("lua-types", "2.11.0", generateExternals = generateExternals)) -// implementation(npm("typescript", "4.4.3", generateExternals = generateExternals)) -// -// testImplementation(kotlin("test-js")) -//} \ No newline at end of file diff --git a/modules/mod/data.ts b/modules/mod/data.ts new file mode 100644 index 0000000..eef4c4c --- /dev/null +++ b/modules/mod/data.ts @@ -0,0 +1 @@ +// require("item") \ No newline at end of file diff --git a/modules/mod/events.lua b/modules/mod/events.lua deleted file mode 100644 index ef8f222..0000000 --- a/modules/mod/events.lua +++ /dev/null @@ -1,9 +0,0 @@ ---[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]] -script.on_event( - {defines.events.on_pre_build, defines.events.on_player_dropped_item}, - function(e) - log( - (("player " .. tostring(e.player_index)) .. " dropped item, tick:") .. tostring(e.tick) - ) - end -) diff --git a/modules/mod/item.ts b/modules/mod/item.ts new file mode 100644 index 0000000..d39f9dd --- /dev/null +++ b/modules/mod/item.ts @@ -0,0 +1,12 @@ +import * as util from "util"; +import { Data, Mods } from "typed-factorio/data/types" + + +declare const data: Data +declare const mods: Mods + +let fireArmour = util.table.deepcopy(data.raw["armor"]["heavy-armor"]) + +fireArmour.name = "fire-armour" +fireArmour.icon + diff --git a/modules/mod/settings.gradle.kts b/modules/mod/settings.gradle.kts deleted file mode 100644 index 90bb0a9..0000000 --- a/modules/mod/settings.gradle.kts +++ /dev/null @@ -1,3 +0,0 @@ -rootProject.name = "factorio-web-map-mod" - -rootProject.description = "Factorio Web Map mod" diff --git a/modules/mod/src/changelog.txt b/modules/mod/src/changelog.txt new file mode 100644 index 0000000..956eb6b --- /dev/null +++ b/modules/mod/src/changelog.txt @@ -0,0 +1,4 @@ +--------------------------------------------------------------------------------------------------- +Version: 0.0.1 + Features: + - Factorio Web Map diff --git a/modules/mod/src/control.ts b/modules/mod/src/control.ts new file mode 100644 index 0000000..544678b --- /dev/null +++ b/modules/mod/src/control.ts @@ -0,0 +1 @@ +require("events") \ No newline at end of file diff --git a/modules/mod/src/events.ts b/modules/mod/src/events.ts new file mode 100644 index 0000000..dc2b9b5 --- /dev/null +++ b/modules/mod/src/events.ts @@ -0,0 +1,19 @@ +script.on_event( + [defines.events.on_pre_build, defines.events.on_player_dropped_item], + (e: OnPreBuildEvent | OnPlayerDroppedItemEvent) => { + game.print("player " + e.player_index + " dropped item, tick:" + e.tick) + } +); + +script.on_event( + defines.events.on_tick, + (e: OnTickEvent) => { + if (e.tick % 60 == 0) { + game.print("test mod tick: " + e.tick) + } + } +); + +script.on_load(() => { + game.print("loaded Factorio Web Map!") +}); diff --git a/modules/mod/src/info.json b/modules/mod/src/info.json new file mode 100644 index 0000000..f24f7d0 --- /dev/null +++ b/modules/mod/src/info.json @@ -0,0 +1,8 @@ +{ + "name": "factorio-web-map", + "version": "0.0.1", + "title": "Factorio Web Map", + "author": "fredthedeadhead", + "factorio_version": "1.1", + "dependencies": [] +} diff --git a/modules/mod/src/main/typescript/events.ts b/modules/mod/src/main/typescript/events.ts deleted file mode 100644 index c8453b4..0000000 --- a/modules/mod/src/main/typescript/events.ts +++ /dev/null @@ -1,6 +0,0 @@ -script.on_event( - [defines.events.on_pre_build, defines.events.on_player_dropped_item], - (e: OnPreBuildEvent | OnPlayerDroppedItemEvent) => { - log("player " + e.player_index + " dropped item, tick:" + e.tick) - } -) \ No newline at end of file diff --git a/modules/mod/package-lock.json b/modules/mod/src/package-lock.json similarity index 100% rename from modules/mod/package-lock.json rename to modules/mod/src/package-lock.json diff --git a/modules/mod/package.json b/modules/mod/src/package.json similarity index 89% rename from modules/mod/package.json rename to modules/mod/src/package.json index dc0fc6b..8690038 100644 --- a/modules/mod/package.json +++ b/modules/mod/src/package.json @@ -16,7 +16,6 @@ }, "dependencies": { "react": "17.0.2", - "react-dom": "17.0.2", "typescript-to-lua": "1.0.1", "typed-factorio": "0.7.1", "lua-types": "2.11.0", @@ -24,5 +23,8 @@ }, "peerDependencies": {}, "optionalDependencies": {}, - "bundledDependencies": [] + "bundledDependencies": [], + "//": { + "react-dom": "17.0.2" + } } diff --git a/modules/mod/src/thumbnail.png b/modules/mod/src/thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..d44317855df14c54ce51f825241d5dd4a3c7df01 GIT binary patch literal 702 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q4M;wBd$a>cF%}28J29*~C-ahlfvLjN#WAEJ z?(HQ*-U9{#ERM5xZfps?pfXAE&$i;frmJthuiTf)#lxM`(Dw9B9%F-p2P=cu&pC`q z3Ze`ePm9?)8bcTsOgS&9z!t>V5M-C$ATg?7G#m)0ho9`b+t)huzBJGUCP)TPS3j3^ HP6(RootPackageJsonTask.NAME) + +//node { +// download.set(true) +// version.set("14.18.0") +// +// distBaseUrl.set(null as String?) // set by dependencyResolutionManagement +// +// nodeProjectDir.set(rootPackageJson.rootPackageJson.parentFile.normalize()) +//// nodeProjectDir.set(packageJson.packageJson.parentFile.normalize()) +//} + + +//fun NpmTask.setNodeModulesPath(path: String): Unit = +// environment.put("NODE_PATH", path) +// +//fun NpmTask.setNodeModulesPath(folder: File): Unit = +// setNodeModulesPath(folder.normalize().absolutePath) + +tasks { + register("tstl") { + description = "Typescript To Lua" + group = projectId + + dependsOn(build) + +// setNodeModulesPath(node.nodeProjectDir.dir("node_modules").get().asFile) +// setNodeModulesPath(node.nodeProjectDir.dir(NpmProject.NODE_MODULES).get().asFile) + val nodeModulesDir: Directory by project.extra + environment.put("NODE_PATH", nodeModulesDir.asFile.absolutePath) + + execOverrides { standardOutput = System.out } + + npmCommand.set(listOf("run", "build")) + + val outputDir = modBuildDir.dir("tstl") + args.set(parseSpaceSeparatedArgs("-- --outDir $outputDir")) + outputs.dir(outputDir) + + ignoreExitValue.set(false) + inputs.dir(rootProject.layout.buildDirectory.dir("js")) + } + + register("dukat-typed-factorio") { + group = projectId + + val npmProject = kotlin.js().compilations["main"].npmProject + + val files = nodeModulesDir.dir("typed-factorio") + .asFileTree + .filter { it.extension in setOf("ts", "d.ts") } + .files + + logger.lifecycle("Converting typed-factorio files: ${files.joinToString { it.name }}") + + val runner = DukatRunner( + npmProject, + files, + ExternalsOutputFormat.SOURCE, + project.layout.projectDirectory.dir("dukat-custom").asFile, + ) + val services = (project as ProjectInternal).services + doLast { + runner.execute(services) + } + } +} diff --git a/modules/mod2/dukat-custom/5.2-only.bit32.module_lua-types.kt b/modules/mod2/dukat-custom/5.2-only.bit32.module_lua-types.kt new file mode 100644 index 0000000..92589f5 --- /dev/null +++ b/modules/mod2/dukat-custom/5.2-only.bit32.module_lua-types.kt @@ -0,0 +1,41 @@ +@file:JsQualifier("bit32") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package bit32 + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun arshift(x: Number, disp: Number): Number + +external fun band(vararg operands: Number): Number + +external fun bnot(x: Number): Number + +external fun bor(vararg operands: Number): Number + +external fun btest(vararg operands: Number): Boolean + +external fun bxor(vararg operands: Number): Number + +external fun extract(n: Number, field: Number, width: Number = definedExternally): Number + +external fun replace(n: Number, v: Number, field: Number, width: Number = definedExternally): Number + +external fun lrotate(x: Number, disp: Number): Number + +external fun lshift(x: Number, disp: Number): Number + +external fun rrotate(x: Number, disp: Number): Number + +external fun rshift(x: Number, disp: Number): Number \ No newline at end of file diff --git a/modules/mod2/dukat-custom/5.2-only.module_lua-types.kt b/modules/mod2/dukat-custom/5.2-only.module_lua-types.kt new file mode 100644 index 0000000..85d3c1e --- /dev/null +++ b/modules/mod2/dukat-custom/5.2-only.module_lua-types.kt @@ -0,0 +1,17 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun collectgarbage(opt: String /* "count" | "generational" | "incremental" */): dynamic /* Unit */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/5.2-plus-or-jit.module_lua-types.kt b/modules/mod2/dukat-custom/5.2-plus-or-jit.module_lua-types.kt new file mode 100644 index 0000000..f68ae03 --- /dev/null +++ b/modules/mod2/dukat-custom/5.2-plus-or-jit.module_lua-types.kt @@ -0,0 +1,37 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun load(chunk: String, chunkname: String = definedExternally, mode: String /* "b" | "t" | "bt" */ = definedExternally, env: Any? = definedExternally): dynamic /* JsTuple<() -> Any> | JsTuple */ + +external fun load(chunk: String): dynamic /* JsTuple<() -> Any> | JsTuple */ + +external fun load(chunk: String, chunkname: String = definedExternally): dynamic /* JsTuple<() -> Any> | JsTuple */ + +external fun load(chunk: String, chunkname: String = definedExternally, mode: String /* "b" | "t" | "bt" */ = definedExternally): dynamic /* JsTuple<() -> Any> | JsTuple */ + +external fun load(chunk: () -> String?, chunkname: String = definedExternally, mode: String /* "b" | "t" | "bt" */ = definedExternally, env: Any? = definedExternally): dynamic /* JsTuple<() -> Any> | JsTuple */ + +external fun load(chunk: () -> String?): dynamic /* JsTuple<() -> Any> | JsTuple */ + +external fun load(chunk: () -> String?, chunkname: String = definedExternally): dynamic /* JsTuple<() -> Any> | JsTuple */ + +external fun load(chunk: () -> String?, chunkname: String = definedExternally, mode: String /* "b" | "t" | "bt" */ = definedExternally): dynamic /* JsTuple<() -> Any> | JsTuple */ + +external fun loadfile(filename: String = definedExternally, mode: String /* "b" | "t" | "bt" */ = definedExternally, env: Any? = definedExternally): dynamic /* JsTuple<() -> Any> | JsTuple */ + +external fun , R, E> xpcall(f: (self: This, args: Args) -> R, msgh: (self: Unit, err: Any) -> E, context: This, vararg args: Args): dynamic /* JsTuple | JsTuple */ + +external fun , R, E> xpcall(f: (self: Unit, args: Args) -> R, msgh: (err: Any) -> E, vararg args: Args): dynamic /* JsTuple | JsTuple */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/5.2-plus.module_lua-types.kt b/modules/mod2/dukat-custom/5.2-plus.module_lua-types.kt new file mode 100644 index 0000000..b7e567f --- /dev/null +++ b/modules/mod2/dukat-custom/5.2-plus.module_lua-types.kt @@ -0,0 +1,22 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import tsstdlib.Record + +external var _ENV: Record + +external fun collectgarbage(opt: String /* "isrunning" */): Boolean + +external fun module(name: String, vararg options: Function<*>) \ No newline at end of file diff --git a/modules/mod2/dukat-custom/builtin-types.module_typed-factorio.kt b/modules/mod2/dukat-custom/builtin-types.module_typed-factorio.kt new file mode 100644 index 0000000..f03d9c3 --- /dev/null +++ b/modules/mod2/dukat-custom/builtin-types.module_typed-factorio.kt @@ -0,0 +1,33 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +typealias float = Number + +typealias double = Number + +typealias int = Number + +typealias int8 = Number + +typealias uint = Number + +typealias uint8 = Number + +typealias uint16 = Number + +typealias uint64 = Number + +typealias table = Any? \ No newline at end of file diff --git a/modules/mod2/dukat-custom/classes.module_typed-factorio.kt b/modules/mod2/dukat-custom/classes.module_typed-factorio.kt new file mode 100644 index 0000000..1f051a8 --- /dev/null +++ b/modules/mod2/dukat-custom/classes.module_typed-factorio.kt @@ -0,0 +1,5723 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import tsstdlib.Omit +import tsstdlib.Record +import defines.wire_type +import defines.circuit_connector_id +import tsstdlib.Position +import defines.inventory +import defines.direction +import defines.shooting +import defines.gui_type +import defines.control_behavior.type +import defines.rail_direction +import defines.rail_connection_direction +import defines.logistic_member_index +import defines.signal_state +import defines.chain_signal_state +import defines.entity_status +import defines.flow_precision_index +import defines.difficulty +import tsstdlib.Extract +import defines.control_behavior.inserter.circuit_mode_of_operation +import defines.control_behavior.inserter.hand_read_mode +import defines.deconstruction_item.entity_filter_mode +import defines.deconstruction_item.tile_filter_mode +import defines.deconstruction_item.tile_selection_mode +import defines.control_behavior.logistic_container.circuit_mode_of_operation as _defines_control_behavior_logistic_container_circuit_mode_of_operation +import defines.logistic_mode +import defines.control_behavior.mining_drill.resource_read_mode +import defines.input_action +import defines.controllers +import defines.alert_type +import defines.render_mode +import defines.rich_text_setting +import defines.build_check_type +import defines.chunk_generated_status +import defines.train_state +import defines.control_behavior.transport_belt.content_read_mode +import defines.group_state + +external interface LuaAISettings { + var allow_destroy_when_commands_fail: Boolean + var allow_try_return_to_spawner: Boolean + var do_separation: Boolean + var path_resolution_modifier: int8 + var valid: Boolean + var object_name: String /* "LuaAISettings" */ + fun help(): String +} + +external interface LuaAccumulatorControlBehavior : LuaControlBehavior { + var output_signal: SignalID + var valid: Boolean + var object_name: String /* "LuaAccumulatorControlBehavior" */ + fun help(): String +} + +external interface LuaAchievementPrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var allowed_without_fight: Boolean + var hidden: Boolean + var valid: Boolean + var object_name: String /* "LuaAchievementPrototype" */ + fun help(): String +} + +external interface LuaAmmoCategoryPrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var bonus_gui_order: String + var valid: Boolean + var object_name: String /* "LuaAmmoCategoryPrototype" */ + fun help(): String +} + +external interface LuaArithmeticCombinatorControlBehavior : LuaCombinatorControlBehavior { + var parameters: ArithmeticCombinatorParameters + var valid: Boolean + var object_name: String /* "LuaArithmeticCombinatorControlBehavior" */ + fun help(): String +} + +external interface LuaAutoplaceControlPrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var richness: Boolean + var control_order: String + var category: String + var valid: Boolean + var object_name: String /* "LuaAutoplaceControlPrototype" */ + fun help(): String +} + +external interface `T$0` { + var player_index: uint + var message: String +} + +external interface `T$1` { + var item_stack: LuaItemStack + var player_index: uint + var recipe: LuaRecipe +} + +external interface `T$2` { + var player_index: uint + var entity: LuaEntity + var from_player: Boolean +} + +external interface `T$3` { + var entity: LuaEntity +} + +external interface `T$4` { + var player_index: uint + var market: LuaEntity + var offer_index: uint + var count: uint +} + +external interface `T$5` { + var entity: LuaEntity + var tags: Tags? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$6` { + var surface_index: uint + var tiles: Array +} + +external interface `T$7` { + var is_simulation: Boolean? + get() = definedExternally + set(value) = definedExternally + var is_tutorial: Boolean? + get() = definedExternally + set(value) = definedExternally + var campaign_name: String? + get() = definedExternally + set(value) = definedExternally + var level_name: String + var mod_name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface LuaBootstrap { + fun on_init(f: (() -> Unit)?) + fun on_load(f: (() -> Unit)?) + fun on_configuration_changed(f: ((param1: ConfigurationChangedData) -> Unit)?) + fun on_event(event: E, f: ((data: Any) -> Unit)?, filters: Array = definedExternally) + fun on_event(event: E, f: ((data: Any) -> Unit)?) + fun on_event(event: Array, f: ((data: Any) -> Unit)?) + fun on_event(event: String, f: ((data: CustomInputEvent) -> Unit)?) + fun on_nth_tick(tick: uint?, f: ((param1: NthTickEventData) -> Unit)?) + fun on_nth_tick(tick: Array?, f: ((param1: NthTickEventData) -> Unit)?) + fun register_on_entity_destroyed(entity: LuaEntity): uint64 + fun generate_event_name(): uint /* uint & `T$93` */ + fun get_event_handler(event: E): (data: Any) -> Unit + fun get_event_handler(event: String): (data: CustomInputEvent) -> Unit + fun get_event_order(): String + fun set_event_filter(event: E, filters: Array?) + fun get_event_filter(event: E): Array? + fun raise_event(event: E, data: Omit) + fun raise_console_chat(params: `T$0`) + fun raise_player_crafted_item(params: `T$1`) + fun raise_player_fast_transferred(params: `T$2`) + fun raise_biter_base_built(params: `T$3`) + fun raise_market_item_purchased(params: `T$4`) + fun raise_script_built(params: `T$3`) + fun raise_script_destroy(params: `T$3`) + fun raise_script_revive(params: `T$5`) + fun raise_script_set_tiles(params: `T$6`) + var mod_name: String + var level: `T$7` + var active_mods: Record + var object_name: String /* "LuaBootstrap" */ +} + +external interface LuaBurner { + var owner: dynamic /* LuaEntity | LuaEquipment */ + get() = definedExternally + set(value) = definedExternally + var inventory: LuaInventory + var burnt_result_inventory: LuaInventory + var heat: double + var heat_capacity: double + var remaining_burning_fuel: double + var currently_burning: LuaItemPrototype + var fuel_categories: Record + var valid: Boolean + var object_name: String /* "LuaBurner" */ + fun help(): String +} + +external interface `T$8` { + var minimum_intensity: float + var maximum_intensity: float + var derivation_change_frequency: float + var derivation_change_deviation: float + var border_fix_speed: float + var minimum_light_size: float + var light_intensity_to_size_coefficient: float + var color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally +} + +external interface LuaBurnerPrototype { + var emissions: double + var render_no_network_icon: Boolean + var render_no_power_icon: Boolean + var effectivity: double + var fuel_inventory_size: uint + var burnt_inventory_size: uint + var smoke: Array + var light_flicker: `T$8` + var fuel_categories: Record + var valid: Boolean + var object_name: String /* "LuaBurnerPrototype" */ + fun help(): String +} + +external interface LuaChunkIterator : LuaIterable { + @nativeInvoke + operator fun invoke(): ChunkPositionAndArea? + var valid: Boolean + var object_name: String /* "LuaChunkIterator" */ + fun help(): String +} + +external interface LuaCircuitNetwork { + fun get_signal(signal: SignalID): int + var entity: LuaEntity + var wire_type: wire_type + var circuit_connector_id: circuit_connector_id + var signals: Array? + var network_id: uint + var connected_circuit_count: uint + var valid: Boolean + var object_name: String /* "LuaCircuitNetwork" */ + fun help(): String +} + +external interface LuaCombinatorControlBehavior : LuaControlBehavior { + fun get_signal_last_tick(signal: SignalID): int? + var signals_last_tick: Array +} + +external interface LuaCommandProcessor { + fun add_command(name: String, help: Any /* JsTuple */, _function: (param1: CustomCommandData) -> Unit) + fun add_command(name: String, help: String, _function: (param1: CustomCommandData) -> Unit) + fun add_command(name: String, help: Number, _function: (param1: CustomCommandData) -> Unit) + fun remove_command(name: String): Boolean + var commands: Record | String | Number */> + var game_commands: Record | String | Number */> + var object_name: String /* "LuaCommandProcessor" */ +} + +external interface LuaConstantCombinatorControlBehavior : LuaControlBehavior { + fun set_signal(index: uint, signal: Signal) + fun get_signal(index: uint): Signal + var parameters: Array + var enabled: Boolean + var signals_count: uint + var valid: Boolean + var object_name: String /* "LuaConstantCombinatorControlBehavior" */ + fun help(): String +} + +external interface LuaContainerControlBehavior : LuaControlBehavior { + var valid: Boolean + var object_name: String /* "LuaContainerControlBehavior" */ + fun help(): String +} + +external interface BaseControlSetGuiArrow { + var type: String /* "nowhere" | "goal" | "entity_info" | "active_window" | "entity" | "position" | "crafting_queue" | "item_stack" */ +} + +external interface EntityControlSetGuiArrow : BaseControlSetGuiArrow { + override var type: String /* "entity" */ + var entity: LuaEntity +} + +external interface PositionControlSetGuiArrow : BaseControlSetGuiArrow { + override var type: String /* "position" */ + var position: Position +} + +external interface CraftingQueueControlSetGuiArrow : BaseControlSetGuiArrow { + override var type: String /* "crafting_queue" */ + var crafting_queueindex: uint +} + +external interface ItemStackControlSetGuiArrow : BaseControlSetGuiArrow { + override var type: String /* "item_stack" */ + var inventory_index: inventory + var item_stack_index: uint + var source: String /* "player" | "target" */ +} + +external interface OtherControlSetGuiArrow : BaseControlSetGuiArrow { + override var type: String /* "nowhere" | "goal" | "entity_info" | "active_window" */ +} + +external interface `T$9` { + var count: uint + var recipe: dynamic /* String | LuaRecipe */ + get() = definedExternally + set(value) = definedExternally + var silent: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$10` { + var index: uint + var count: uint +} + +external interface `T$11` { + var walking: Boolean + var direction: direction +} + +external interface `T$12` { + var mining: Boolean + var position: Position? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$13` { + var state: shooting + var position: Position +} + +external interface `T$14` { + var repairing: Boolean + var position: Position +} + +external interface LuaControl { + fun get_inventory(inventory: inventory): LuaInventory? + fun get_main_inventory(): LuaInventory? + fun can_insert(items: String): Boolean + fun can_insert(items: ItemStackDefinition): Boolean + fun can_insert(items: LuaItemStack): Boolean + fun insert(items: String): uint + fun insert(items: ItemStackDefinition): uint + fun insert(items: LuaItemStack): uint + fun set_gui_arrow(params: EntityControlSetGuiArrow) + fun set_gui_arrow(params: PositionControlSetGuiArrow) + fun set_gui_arrow(params: CraftingQueueControlSetGuiArrow) + fun set_gui_arrow(params: ItemStackControlSetGuiArrow) + fun set_gui_arrow(params: OtherControlSetGuiArrow) + fun clear_gui_arrow() + fun get_item_count(item: String = definedExternally): uint + fun has_items_inside(): Boolean + fun can_reach_entity(entity: LuaEntity): Boolean + fun clear_items_inside() + fun remove_item(items: String): uint + fun remove_item(items: ItemStackDefinition): uint + fun remove_item(items: LuaItemStack): uint + fun teleport(position: Position, surface: uint = definedExternally): Boolean + fun teleport(position: Position): Boolean + fun teleport(position: Position, surface: String = definedExternally): Boolean + fun teleport(position: Position, surface: LuaSurface = definedExternally): Boolean + fun update_selected_entity(position: Position) + fun clear_selected_entity() + fun disable_flashlight() + fun enable_flashlight() + fun is_flashlight_enabled() + fun get_craftable_count(recipe: String): uint + fun get_craftable_count(recipe: LuaRecipe): uint + fun begin_crafting(params: `T$9`): uint + fun cancel_crafting(params: `T$10`) + fun mine_entity(entity: LuaEntity, force: Boolean = definedExternally): Boolean + fun mine_tile(tile: LuaTile): Boolean + fun is_player(): Boolean + fun open_technology_gui(technology: String = definedExternally) + fun open_technology_gui() + fun open_technology_gui(technology: LuaTechnology = definedExternally) + fun open_technology_gui(technology: LuaTechnologyPrototype = definedExternally) + fun set_personal_logistic_slot(slot_index: uint, value: PersonalLogisticParameters): Boolean + fun set_vehicle_logistic_slot(slot_index: uint, value: PersonalLogisticParameters): Boolean + fun get_personal_logistic_slot(slot_index: uint): PersonalLogisticParameters + fun get_vehicle_logistic_slot(slot_index: uint): PersonalLogisticParameters + fun clear_personal_logistic_slot(slot_index: uint) + fun clear_vehicle_logistic_slot(slot_index: uint) + fun is_cursor_blueprint(): Boolean + fun get_blueprint_entities(): Array? + fun is_cursor_empty(): Boolean + var surface: LuaSurface + var position: PositionTable + var vehicle: LuaEntity? + var force: dynamic /* String | LuaForce */ + get() = definedExternally + set(value) = definedExternally + var selected: LuaEntity? + var opened: dynamic /* LuaEntity? | LuaItemStack? | LuaEquipment? | LuaEquipmentGrid? | LuaPlayer? | ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers | defines.gui_type? */ + get() = definedExternally + set(value) = definedExternally + var crafting_queue_size: uint + var crafting_queue_progress: double + var walking_state: `T$11` + var riding_state: RidingState + var mining_state: `T$12` + var shooting_state: `T$13` + var picking_state: Boolean + var repair_state: `T$14` + var cursor_stack: LuaItemStack? + var cursor_ghost: dynamic /* LuaItemStack | LuaItemPrototype | String */ + get() = definedExternally + set(value) = definedExternally + var driving: Boolean + var crafting_queue: Array + var following_robots: Array + var cheat_mode: Boolean + var character_crafting_speed_modifier: double + var character_mining_speed_modifier: double + var character_additional_mining_categories: Array + var character_running_speed_modifier: double + var character_build_distance_bonus: uint + var character_item_drop_distance_bonus: uint + var character_reach_distance_bonus: uint + var character_resource_reach_distance_bonus: uint + var character_item_pickup_distance_bonus: uint + var character_loot_pickup_distance_bonus: uint + var character_inventory_slots_bonus: uint + var character_trash_slot_count_bonus: uint + var character_maximum_following_robot_count_bonus: uint + var character_health_bonus: float + var character_personal_logistic_requests_enabled: Boolean + var vehicle_logistic_requests_enabled: Boolean + var opened_gui_type: gui_type? + var build_distance: uint + var drop_item_distance: uint + var reach_distance: uint + var item_pickup_distance: double + var loot_pickup_distance: double + var resource_reach_distance: double + var in_combat: Boolean + var character_running_speed: double + var character_mining_progress: double +} + +external interface LuaControlBehavior { + fun get_circuit_network(wire: wire_type, circuit_connector: circuit_connector_id = definedExternally): LuaCircuitNetwork? + var type: type + var entity: LuaEntity +} + +external interface LuaCustomChartTag { + fun destroy() + var icon: SignalID? + var last_user: LuaPlayer + var position: PositionTable + var text: String + var tag_number: uint + var force: LuaForce + var surface: LuaSurface + var valid: Boolean + var object_name: String /* "LuaCustomChartTag" */ + fun help(): String +} + +external interface LuaCustomInputPrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var key_sequence: String + var alternative_key_sequence: String? + var linked_game_control: String? + var consuming: String /* "none" | "game-only" */ + var action: String + var enabled: Boolean + var enabled_while_spectating: Boolean + var enabled_while_in_cutscene: Boolean + var include_selected_prototype: Boolean + var item_to_spawn: LuaItemPrototype? + var valid: Boolean + var object_name: String /* "LuaCustomInputPrototype" */ + fun help(): String +} + +typealias CustomTableIndex = Any + +external interface LuaCustomTableMembers { + var length: () -> uint /* () -> uint & LuaExtension */ + var valid: Boolean + var object_name: String /* "LuaCustomTable" */ + fun help(): String +} + +external interface LuaDamagePrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var hidden: Boolean + var valid: Boolean + var object_name: String /* "LuaDamagePrototype" */ + fun help(): String +} + +external interface LuaDeciderCombinatorControlBehavior : LuaCombinatorControlBehavior { + var parameters: DeciderCombinatorParameters + var valid: Boolean + var object_name: String /* "LuaDeciderCombinatorControlBehavior" */ + fun help(): String +} + +external interface LuaDecorativePrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var collision_box: BoundingBoxTable + var collision_mask: CollisionMask + var collision_mask_with_flags: CollisionMaskWithFlags + var autoplace_specification: AutoplaceSpecification? + var valid: Boolean + var object_name: String /* "LuaDecorativePrototype" */ + fun help(): String +} + +external interface LuaElectricEnergySourcePrototype { + var buffer_capacity: double + var usage_priority: String + var input_flow_limit: double + var output_flow_limit: double + var drain: double + var emissions: double + var render_no_network_icon: Boolean + var render_no_power_icon: Boolean + var valid: Boolean + var object_name: String /* "LuaElectricEnergySourcePrototype" */ + fun help(): String +} + +external interface `T$15` { + var do_cliff_correction: Boolean? + get() = definedExternally + set(value) = definedExternally + var raise_destroy: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$16` { + var force: dynamic /* String | LuaForce */ + get() = definedExternally + set(value) = definedExternally + var target: dynamic /* LuaEntity | LuaEntityPrototype | String */ + get() = definedExternally + set(value) = definedExternally + var player: dynamic /* uint? | String? | LuaPlayer? */ + get() = definedExternally + set(value) = definedExternally + var direction: direction? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$17` { + var return_item_request_proxy: Boolean? + get() = definedExternally + set(value) = definedExternally + var raise_revive: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$18` { + var rail_direction: rail_direction + var rail_connection_direction: rail_connection_direction +} + +external interface `T$19` { + var reverse: Boolean? + get() = definedExternally + set(value) = definedExternally + var by_player: dynamic /* uint? | String? | LuaPlayer? */ + get() = definedExternally + set(value) = definedExternally + var spill_items: Boolean? + get() = definedExternally + set(value) = definedExternally + var enable_looted: Boolean? + get() = definedExternally + set(value) = definedExternally + var force: dynamic /* LuaForce? | String? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$20` { + var position: Position + var surface: LuaSurface? + get() = definedExternally + set(value) = definedExternally + var force: dynamic /* String? | LuaForce? */ + get() = definedExternally + set(value) = definedExternally + var create_build_effect_smoke: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$21` { + var name: String + var amount: double + var minimum_temperature: double? + get() = definedExternally + set(value) = definedExternally + var maximum_temperature: double? + get() = definedExternally + set(value) = definedExternally + var temperature: double? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$22` { + var inventory: LuaInventory? + get() = definedExternally + set(value) = definedExternally + var force: Boolean? + get() = definedExternally + set(value) = definedExternally + var raise_destroyed: Boolean? + get() = definedExternally + set(value) = definedExternally + var ignore_minable: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$23` { + var red: Array + var green: Array +} + +external interface LuaEntity : LuaControl { + fun get_output_inventory(): LuaInventory + fun get_module_inventory(): LuaInventory? + fun get_fuel_inventory(): LuaInventory? + fun get_burnt_result_inventory(): LuaInventory? + fun damage(damage: float, force: String, type: String = definedExternally, dealer: LuaEntity = definedExternally): float + fun damage(damage: float, force: String): float + fun damage(damage: float, force: String, type: String = definedExternally): float + fun damage(damage: float, force: LuaForce, type: String = definedExternally, dealer: LuaEntity = definedExternally): float + fun damage(damage: float, force: LuaForce): float + fun damage(damage: float, force: LuaForce, type: String = definedExternally): float + fun can_be_destroyed(): Boolean + fun destroy(params: `T$15` = definedExternally): Boolean + fun set_command(command: AttackCommand) + fun set_command(command: GoToLocationCommand) + fun set_command(command: CompoundCommand) + fun set_command(command: GroupCommand) + fun set_command(command: AttackAreaCommand) + fun set_command(command: WanderCommand) + fun set_command(command: StopCommand) + fun set_command(command: FleeCommand) + fun set_command(command: BuildBaseCommand) + fun set_distraction_command(command: AttackCommand) + fun set_distraction_command(command: GoToLocationCommand) + fun set_distraction_command(command: CompoundCommand) + fun set_distraction_command(command: GroupCommand) + fun set_distraction_command(command: AttackAreaCommand) + fun set_distraction_command(command: WanderCommand) + fun set_distraction_command(command: StopCommand) + fun set_distraction_command(command: FleeCommand) + fun set_distraction_command(command: BuildBaseCommand) + fun has_command(): Boolean + fun die(force: String = definedExternally, cause: LuaEntity = definedExternally): Boolean + fun die(): Boolean + fun die(force: String = definedExternally): Boolean + fun die(force: LuaForce = definedExternally, cause: LuaEntity = definedExternally): Boolean + fun die(force: LuaForce = definedExternally): Boolean + fun has_flag(flag: String): Boolean + fun ghost_has_flag(flag: String): Boolean + fun add_market_item(offer: Offer) + fun remove_market_item(offer: uint): Boolean + fun get_market_items(): Array + fun clear_market_items() + fun connect_neighbour(target: LuaEntity): Boolean + fun connect_neighbour(target: WireConnectionDefinition): Boolean + fun disconnect_neighbour(target: wire_type = definedExternally) + fun disconnect_neighbour() + fun disconnect_neighbour(target: LuaEntity = definedExternally) + fun disconnect_neighbour(target: WireConnectionDefinition = definedExternally) + fun order_deconstruction(force: String, player: uint = definedExternally): Boolean + fun order_deconstruction(force: String): Boolean + fun order_deconstruction(force: String, player: String = definedExternally): Boolean + fun order_deconstruction(force: String, player: LuaPlayer = definedExternally): Boolean + fun order_deconstruction(force: LuaForce, player: uint = definedExternally): Boolean + fun order_deconstruction(force: LuaForce): Boolean + fun order_deconstruction(force: LuaForce, player: String = definedExternally): Boolean + fun order_deconstruction(force: LuaForce, player: LuaPlayer = definedExternally): Boolean + fun cancel_deconstruction(force: String, player: uint = definedExternally) + fun cancel_deconstruction(force: String) + fun cancel_deconstruction(force: String, player: String = definedExternally) + fun cancel_deconstruction(force: String, player: LuaPlayer = definedExternally) + fun cancel_deconstruction(force: LuaForce, player: uint = definedExternally) + fun cancel_deconstruction(force: LuaForce) + fun cancel_deconstruction(force: LuaForce, player: String = definedExternally) + fun cancel_deconstruction(force: LuaForce, player: LuaPlayer = definedExternally) + fun to_be_deconstructed(): Boolean + fun order_upgrade(params: `T$16`): Boolean + fun cancel_upgrade(force: String, player: uint = definedExternally): Boolean + fun cancel_upgrade(force: String): Boolean + fun cancel_upgrade(force: String, player: String = definedExternally): Boolean + fun cancel_upgrade(force: String, player: LuaPlayer = definedExternally): Boolean + fun cancel_upgrade(force: LuaForce, player: uint = definedExternally): Boolean + fun cancel_upgrade(force: LuaForce): Boolean + fun cancel_upgrade(force: LuaForce, player: String = definedExternally): Boolean + fun cancel_upgrade(force: LuaForce, player: LuaPlayer = definedExternally): Boolean + fun to_be_upgraded(): Boolean + fun get_request_slot(slot: uint): dynamic /* String? | ItemStackDefinition? */ + fun set_request_slot(request: String, slot: uint): Boolean + fun set_request_slot(request: ItemStackDefinition, slot: uint): Boolean + fun set_request_slot(request: LuaItemStack, slot: uint): Boolean + fun clear_request_slot(slot: uint) + fun is_crafting() + fun is_opened(): Boolean + fun is_opening(): Boolean + fun is_closed(): Boolean + fun is_closing(): Boolean + fun request_to_open(force: String, extra_time: uint = definedExternally) + fun request_to_open(force: String) + fun request_to_open(force: LuaForce, extra_time: uint = definedExternally) + fun request_to_open(force: LuaForce) + fun request_to_close(force: String) + fun request_to_close(force: LuaForce) + fun get_transport_line(index: uint): LuaTransportLine + fun get_max_transport_line_index(): uint + fun launch_rocket(): Boolean + fun revive(params: `T$17` = definedExternally): dynamic /* JsTuple | JsTuple, LuaEntity, LuaEntity?> */ + fun silent_revive(params: `T$17` = definedExternally): dynamic /* JsTuple | JsTuple, LuaEntity, LuaEntity?> */ + fun get_connected_rail(params: `T$18`): LuaEntity + fun get_connected_rails(): Array + fun get_rail_segment_entity(direction: rail_direction, in_else_out: Boolean): LuaEntity? + fun get_rail_segment_end(direction: rail_direction): dynamic /* JsTuple */ + fun get_rail_segment_length(): double + fun get_rail_segment_overlaps(): Array + fun get_filter(slot_index: uint): String? + fun set_filter(slot_index: uint, item: String) + fun get_infinity_container_filter(index: uint): InfinityInventoryFilter? + fun set_infinity_container_filter(index: uint, filter: InfinityInventoryFilter?) + fun get_infinity_pipe_filter(): InfinityPipeFilter? + fun set_infinity_pipe_filter(filter: InfinityPipeFilter?) + fun get_heat_setting(): HeatSetting + fun set_heat_setting(filter: HeatSetting) + fun get_control_behavior(): LuaControlBehavior? + fun get_or_create_control_behavior(): LuaControlBehavior? + fun get_circuit_network(wire: wire_type, circuit_connector: circuit_connector_id = definedExternally): LuaCircuitNetwork? + fun get_merged_signal(signal: SignalID, circuit_connector: circuit_connector_id = definedExternally): int + fun get_merged_signals(circuit_connector: circuit_connector_id = definedExternally): Array? + fun supports_backer_name(): Boolean + fun copy_settings(entity: LuaEntity, by_player: uint = definedExternally): Record + fun copy_settings(entity: LuaEntity): Record + fun copy_settings(entity: LuaEntity, by_player: String = definedExternally): Record + fun copy_settings(entity: LuaEntity, by_player: LuaPlayer = definedExternally): Record + fun get_logistic_point(index: logistic_member_index = definedExternally): dynamic /* LuaLogisticPoint | Array */ + fun play_note(instrument: uint, note: uint): Boolean + fun connect_rolling_stock(direction: rail_direction): Boolean + fun disconnect_rolling_stock(direction: rail_direction): Boolean + fun update_connections() + fun get_recipe(): LuaRecipe? + fun set_recipe(recipe: String?): Record + fun set_recipe(recipe: LuaRecipe?): Record + fun rotate(params: `T$19` = definedExternally): Boolean + fun get_driver(): dynamic /* LuaEntity? | LuaPlayer? */ + fun set_driver(driver: LuaEntity?) + fun set_driver(driver: uint?) + fun set_driver(driver: String?) + fun set_driver(driver: LuaPlayer?) + fun get_passenger(): dynamic /* LuaEntity? | LuaPlayer? */ + fun set_passenger(passenger: LuaEntity) + fun set_passenger(passenger: uint) + fun set_passenger(passenger: String) + fun set_passenger(passenger: LuaPlayer) + fun is_connected_to_electric_network(): Boolean + fun get_train_stop_trains(): Array + fun get_stopped_train(): LuaTrain? + fun clone(params: `T$20`): LuaEntity? + fun get_fluid_count(fluid: String = definedExternally): double + fun get_fluid_contents(): Record + fun remove_fluid(params: `T$21`): double + fun insert_fluid(fluid: Fluid): double + fun clear_fluid_inside() + fun get_beam_source(): BeamTarget + fun set_beam_source(source: LuaEntity) + fun set_beam_source(source: Position) + fun get_beam_target(): BeamTarget + fun set_beam_target(target: LuaEntity) + fun set_beam_target(target: Position) + fun get_radius(): double + fun get_health_ratio(): float + fun create_build_effect_smoke() + fun release_from_spawner() + fun toggle_equipment_movement_bonus() + fun can_shoot(target: LuaEntity, position: Position): Boolean + fun start_fading_out() + fun get_upgrade_target(): LuaEntityPrototype? + fun get_upgrade_direction(): direction? + fun get_damage_to_be_taken(): float + fun deplete() + fun mine(params: `T$22` = definedExternally): Boolean + fun spawn_decorations() + fun can_wires_reach(entity: LuaEntity): Boolean + fun get_connected_rolling_stock(direction: rail_direction): LuaEntity + fun is_registered_for_construction(): Boolean + fun is_registered_for_deconstruction(force: String): Boolean + fun is_registered_for_deconstruction(force: LuaForce): Boolean + fun is_registered_for_upgrade(): Boolean + fun is_registered_for_repair(): Boolean + fun add_autopilot_destination(position: Position) + fun connect_linked_belts(neighbour: LuaEntity?) + fun disconnect_linked_belts() + var name: String /* "inserter" | "filter-inserter" */ + var ghost_name: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var ghost_localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var ghost_localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var type: String + var ghost_type: String + var active: Boolean + var destructible: Boolean + var minable: Boolean + var rotatable: Boolean + var operable: Boolean + var health: float? + var direction: direction + var supports_direction: Boolean + var orientation: RealOrientation + var cliff_orientation: String /* "west-to-east" | "north-to-south" | "east-to-west" | "south-to-north" | "west-to-north" | "north-to-east" | "east-to-south" | "south-to-west" | "west-to-south" | "north-to-west" | "east-to-north" | "south-to-east" | "west-to-none" | "none-to-east" | "east-to-none" | "none-to-west" | "north-to-none" | "none-to-south" | "south-to-none" | "none-to-north" */ + var relative_turret_orientation: RealOrientation? + var torso_orientation: RealOrientation + var amount: uint + var initial_amount: uint? + var effectivity_modifier: float + var consumption_modifier: float + var friction_modifier: float + var driver_is_gunner: Boolean + var vehicle_automatic_targeting_parameters: VehicleAutomaticTargetingParameters + var speed: float + var effective_speed: float + var stack: LuaItemStack + var prototype: LuaEntityPrototype + var ghost_prototype: dynamic /* LuaEntityPrototype | LuaTilePrototype */ + get() = definedExternally + set(value) = definedExternally + var drop_position: Position + var pickup_position: Position + var drop_target: LuaEntity? + var pickup_target: LuaEntity + var selected_gun_index: uint? + var energy: double + var temperature: double? + var previous_recipe: LuaRecipe? + var held_stack: LuaItemStack + var held_stack_position: PositionTable + var train: LuaTrain? + var neighbours: dynamic /* Record>? | Array>? | LuaEntity? */ + get() = definedExternally + set(value) = definedExternally + var belt_neighbours: Record> + var fluidbox: LuaFluidBox + var backer_name: String? + var entity_label: String? + var time_to_live: uint + var color: dynamic /* ColorTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var text: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var signal_state: signal_state + var chain_signal_state: chain_signal_state + var to_be_looted: Boolean + var crafting_speed: double + var crafting_progress: float + var bonus_progress: double + var productivity_bonus: double + var pollution_bonus: double + var speed_bonus: double + var consumption_bonus: double + var belt_to_ground_type: String /* "input" | "output" */ + var loader_type: String /* "input" | "output" */ + var rocket_parts: uint + var logistic_network: LuaLogisticNetwork + var logistic_cell: LuaLogisticCell? + var item_requests: Record + var player: LuaPlayer? + var unit_group: LuaUnitGroup? + var damage_dealt: double + var kills: uint + var last_user: LuaPlayer? + var electric_buffer_size: double? + var electric_input_flow_limit: double? + var electric_output_flow_limit: double? + var electric_drain: double? + var electric_emissions: double? + var unit_number: uint? + var ghost_unit_number: uint? + var mining_progress: double? + var bonus_mining_progress: double? + var power_production: double + var power_usage: double + var bounding_box: BoundingBoxTable + var secondary_bounding_box: BoundingBoxTable? + var selection_box: BoundingBoxTable + var secondary_selection_box: BoundingBoxTable? + var mining_target: LuaEntity? + var circuit_connected_entities: `T$23` + var circuit_connection_definitions: Array + var request_slot_count: uint + var filter_slot_count: uint + var loader_container: LuaEntity + var grid: LuaEquipmentGrid? + var graphics_variation: uint8? + var tree_color_index: uint8 + var tree_color_index_max: uint8 + var tree_stage_index: uint8 + var tree_stage_index_max: uint8 + var tree_gray_stage_index: uint8 + var tree_gray_stage_index_max: uint8 + var burner: LuaBurner? + var shooting_target: LuaEntity? + var proxy_target: LuaEntity? + var stickers: Array? + var sticked_to: LuaEntity + var parameters: ProgrammableSpeakerParameters + var alert_parameters: ProgrammableSpeakerAlertParameters + var electric_network_statistics: LuaFlowStatistics + var inserter_stack_size_override: uint + var products_finished: uint + var spawner: LuaEntity? + var units: Array + var power_switch_state: Boolean + var effects: ModuleEffects? + var infinity_container_filters: Array + var remove_unfiltered_items: Boolean + var character_corpse_player_index: uint + var character_corpse_tick_of_death: uint + var character_corpse_death_cause: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var associated_player: LuaPlayer? + var tick_of_last_attack: uint + var tick_of_last_damage: uint + var splitter_filter: LuaItemPrototype? + var inserter_filter_mode: String /* "whitelist" | "blacklist" */ + var splitter_input_priority: String /* "left" | "none" | "right" */ + var splitter_output_priority: String /* "left" | "none" | "right" */ + var armed: Boolean + var recipe_locked: Boolean + var connected_rail: LuaEntity? + var trains_in_block: uint + var timeout: uint + var neighbour_bonus: double + var ai_settings: LuaAISettings + var highlight_box_type: String + var highlight_box_blink_interval: uint + var status: entity_status? + var enable_logistics_while_moving: Boolean + var render_player: LuaPlayer? + var render_to_forces: Array? + var pump_rail_target: LuaEntity? + var moving: Boolean + var electric_network_id: uint? + var allow_dispatching_robots: Boolean + var auto_launch: Boolean + var energy_generated_last_tick: double + var storage_filter: LuaItemPrototype + var request_from_buffers: Boolean + var corpse_expires: Boolean + var corpse_immune_to_entity_placement: Boolean + var tags: Tags? + var command: dynamic /* AttackCommand? | GoToLocationCommand? | CompoundCommand? | GroupCommand? | AttackAreaCommand? | WanderCommand? | StopCommand? | FleeCommand? | BuildBaseCommand? */ + get() = definedExternally + set(value) = definedExternally + var distraction_command: dynamic /* AttackCommand? | GoToLocationCommand? | CompoundCommand? | GroupCommand? | AttackAreaCommand? | WanderCommand? | StopCommand? | FleeCommand? | BuildBaseCommand? */ + get() = definedExternally + set(value) = definedExternally + var time_to_next_effect: uint + var autopilot_destination: Position? + var autopilot_destinations: Array + var trains_count: uint? + var trains_limit: uint + var is_entity_with_force: Boolean + var is_entity_with_owner: Boolean + var is_entity_with_health: Boolean + var combat_robot_owner: LuaEntity + var link_id: uint + var follow_target: LuaEntity + var follow_offset: Position? + var linked_belt_type: String /* "input" | "output" */ + var linked_belt_neighbour: LuaEntity? + var valid: Boolean + var object_name: String /* "LuaEntity" */ + fun help(): String +} + +external interface `T$24` { + var minable: Boolean + var mining_time: double + var mining_particle: String? + get() = definedExternally + set(value) = definedExternally + var products: Array? + get() = definedExternally + set(value) = definedExternally + var fluid_amount: double? + get() = definedExternally + set(value) = definedExternally + var required_fluid: String? + get() = definedExternally + set(value) = definedExternally + var mining_trigger: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$25` { + var min: double + var max: double +} + +external interface `T$26` { + var smoke_name: String + var offsets: Array + var offset_deviation: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var initial_height: float + var max_radius: float? + get() = definedExternally + set(value) = definedExternally + var speed: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var speed_multiplier: float + var speed_multiplier_deviation: float + var starting_frame: float + var starting_frame_deviation: float + var starting_frame_speed: float + var starting_frame_speed_deviation: float + var speed_from_center: float + var speed_from_center_deviation: float +} + +external interface LuaEntityPrototype { + fun has_flag(flag: String /* "not-rotatable" | "placeable-neutral" | "placeable-player" | "placeable-enemy" | "placeable-off-grid" | "player-creation" | "filter-directions" | "fast-replaceable-no-build-while-moving" | "breaths-air" | "not-repairable" | "not-on-map" | "not-deconstructable" | "not-blueprintable" | "hide-from-bonus-gui" | "hide-alt-info" | "fast-replaceable-no-cross-type-while-moving" | "no-gap-fill-while-building" | "not-flammable" | "no-automated-item-removal" | "no-automated-item-insertion" | "not-upgradable" */): Boolean + fun get_inventory_size(index: inventory): uint? + var type: String + var name: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var max_health: float + var infinite_resource: Boolean? + var minimum_resource_amount: uint? + var normal_resource_amount: uint? + var infinite_depletion_resource_amount: uint? + var resource_category: String? + var mineable_properties: `T$24` + var items_to_place_this: Array? + var collision_box: BoundingBoxTable + var secondary_collision_box: BoundingBoxTable? + var map_generator_bounding_box: BoundingBoxTable + var selection_box: BoundingBoxTable + var drawing_box: BoundingBoxTable + var sticker_box: BoundingBoxTable + var collision_mask: CollisionMask + var collision_mask_with_flags: CollisionMaskWithFlags + var default_collision_mask_with_flags: CollisionMaskWithFlags + var order: String + var group: LuaGroup + var subgroup: LuaGroup + var healing_per_tick: float + var emissions_per_second: double + var corpses: Record + var selectable_in_game: Boolean + var selection_priority: uint + var weight: double? + var resistances: Record + var fast_replaceable_group: String? + var next_upgrade: LuaEntityPrototype? + var loot: Array? + var repair_speed_modifier: uint? + var turret_range: uint? + var autoplace_specification: AutoplaceSpecification? + var belt_speed: double? + var result_units: Array + var attack_result: Array? + var final_attack_result: Array? + var attack_parameters: dynamic /* ProjectileAttackParameters? | StreamAttackParameters? | OtherAttackParameters? */ + get() = definedExternally + set(value) = definedExternally + var spawn_cooldown: `T$25`? + var mining_drill_radius: double? + var mining_speed: double? + var logistic_mode: String /* "requester" | "active-provider" | "passive-provider" | "buffer" | "storage" | "none" */ + var max_underground_distance: uint8? + var flags: EntityPrototypeFlags + var remains_when_mined: Array + var additional_pastable_entities: Array + var allow_copy_paste: Boolean + var shooting_cursor_size: double + var created_smoke: `T$26`? + var created_effect: Array? + var map_color: ColorTable? + var friendly_map_color: ColorTable + var enemy_map_color: ColorTable + var build_base_evolution_requirement: double + var instruments: Array? + var max_polyphony: uint? + var module_inventory_size: uint? + var ingredient_count: uint? + var crafting_speed: double? + var crafting_categories: Record + var resource_categories: Record? + var supply_area_distance: double? + var max_wire_distance: double + var max_circuit_wire_distance: double + var energy_usage: double? + var max_energy_usage: double + var max_energy_production: double + var effectivity: double? + var consumption: double? + var friction_force: double? + var braking_force: double? + var air_resistance: double? + var tank_driving: Boolean? + var rotation_speed: double? + var turret_rotation_speed: double? + var guns: Record? + var speed: double? + var speed_multiplier_when_out_of_energy: float? + var max_payload_size: uint? + var draw_cargo: Boolean? + var energy_per_move: double? + var energy_per_tick: double? + var max_energy: double? + var min_to_charge: float? + var max_to_charge: float? + var burner_prototype: LuaBurnerPrototype? + var electric_energy_source_prototype: LuaElectricEnergySourcePrototype? + var heat_energy_source_prototype: LuaHeatEnergySourcePrototype? + var fluid_energy_source_prototype: LuaFluidEnergySourcePrototype? + var void_energy_source_prototype: LuaVoidEnergySourcePrototype? + var building_grid_bit_shift: uint + var fluid_usage_per_tick: double? + var maximum_temperature: double? + var target_temperature: double? + var fluid: LuaFluidPrototype? + var fluid_capacity: double + var pumping_speed: double? + var stack: Boolean + var allow_custom_vectors: Boolean + var allow_burner_leech: Boolean + var inserter_extension_speed: double? + var inserter_rotation_speed: double? + var inserter_pickup_position: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var inserter_drop_position: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var inserter_chases_belt_items: Boolean? + var count_as_rock_for_filtered_deconstruction: Boolean + var filter_count: uint? + var time_to_live: uint + var distribution_effectivity: double? + var explosion_beam: double? + var explosion_rotate: double? + var tree_color_count: uint8? + var alert_when_damaged: Boolean? + var alert_when_attacking: Boolean? + var color: ColorTable? + var collision_mask_collides_with_self: Boolean + var collision_mask_collides_with_tiles_only: Boolean + var collision_mask_considers_tile_transitions: Boolean + var allowed_effects: Record? + var rocket_parts_required: uint? + var rocket_rising_delay: uint8? + var launch_wait_time: uint8? + var light_blinking_speed: double? + var door_opening_speed: double? + var rising_speed: double? + var engine_starting_speed: double? + var flying_speed: double? + var flying_acceleration: double? + var fixed_recipe: String? + var construction_radius: double? + var logistic_radius: double? + var energy_per_hit_point: double? + var create_ghost_on_death: Boolean + var timeout: uint + var fluidbox_prototypes: Array + var neighbour_bonus: double + var neighbour_collision_increase: double + var container_distance: double + var belt_distance: double + var belt_length: double + var is_building: Boolean + var automated_ammo_count: uint? + var max_speed: double? + var darkness_for_all_lamps_on: float? + var darkness_for_all_lamps_off: float? + var always_on: Boolean? + var min_darkness_to_spawn: float + var max_darkness_to_spawn: float + var call_for_help_radius: double + var max_count_of_owned_units: double + var max_friends_around_to_spawn: double + var spawning_radius: double + var spawning_spacing: double + var radius: double + var cliff_explosive_prototype: String? + var rocket_entity_prototype: LuaEntityPrototype? + var has_belt_immunity: Boolean? + var vision_distance: double? + var pollution_to_join_attack: float? + var min_pursue_time: uint? + var max_pursue_distance: double? + var radar_range: uint? + var move_while_shooting: Boolean? + var can_open_gates: Boolean? + var affected_by_tiles: Boolean? + var distraction_cooldown: uint? + var spawning_time_modifier: double? + var alert_icon_shift: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var lab_inputs: Array? + var researching_speed: double? + var item_slot_count: uint? + var base_productivity: double? + var allow_access_to_all_forces: Boolean + var supports_direction: Boolean + var terrain_friction_modifier: float + var allow_passengers: Boolean + var max_distance_of_sector_revealed: uint + var max_distance_of_nearby_sector_revealed: uint + var adjacent_tile_collision_box: BoundingBoxTable + var adjacent_tile_collision_mask: CollisionMask + var adjacent_tile_collision_test: CollisionMask + var center_collision_mask: CollisionMask + var grid_prototype: LuaEquipmentGridPrototype? + var remove_decoratives: String + var related_underground_belt: LuaEntityPrototype + var running_speed: double + var maximum_corner_sliding_distance: double + var build_distance: uint + var drop_item_distance: uint + var reach_distance: uint + var reach_resource_distance: double + var item_pickup_distance: double + var loot_pickup_distance: double + var enter_vehicle_distance: double + var ticks_to_keep_gun: uint + var ticks_to_keep_aiming_direction: uint + var ticks_to_stay_in_combat: uint + var respawn_time: uint + var damage_hit_tint: ColorTable + var character_corpse: LuaEntityPrototype + var valid: Boolean + var object_name: String /* "LuaEntityPrototype" */ + fun help(): String +} + +external interface `T$27` { + var width: uint + var height: uint +} + +external interface LuaEquipment { + var name: String + var type: String + var position: PositionTable + var shape: `T$27` + var shield: double + var max_shield: double + var max_solar_power: double + var movement_bonus: double + var generator_power: double + var energy: double + var max_energy: double + var prototype: LuaEquipmentPrototype + var burner: LuaBurner? + var valid: Boolean + var object_name: String /* "LuaEquipment" */ + fun help(): String +} + +external interface LuaEquipmentCategoryPrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var valid: Boolean + var object_name: String /* "LuaEquipmentCategoryPrototype" */ + fun help(): String +} + +external interface `T$28` { + var position: Position? + get() = definedExternally + set(value) = definedExternally + var equipment: LuaEquipment? + get() = definedExternally + set(value) = definedExternally + var by_player: dynamic /* uint? | String? | LuaPlayer? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$29` { + var name: String + var position: Position? + get() = definedExternally + set(value) = definedExternally + var by_player: dynamic /* uint? | String? | LuaPlayer? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$30` { + var equipment: LuaEquipment + var position: Position +} + +external interface LuaEquipmentGrid { + fun take(params: `T$28`): dynamic /* String? | ItemStackDefinition? */ + fun take_all(by_player: uint = definedExternally): Record + fun take_all(): Record + fun take_all(by_player: String = definedExternally): Record + fun take_all(by_player: LuaPlayer = definedExternally): Record + fun clear(by_player: uint = definedExternally) + fun clear() + fun clear(by_player: String = definedExternally) + fun clear(by_player: LuaPlayer = definedExternally) + fun put(params: `T$29`): LuaEquipment? + fun can_move(params: `T$30`): Boolean + fun move(params: `T$30`): Boolean + fun get(position: Position): LuaEquipment? + fun get_contents(): Record + var prototype: LuaEquipmentGridPrototype + var width: uint + var height: uint + var equipment: Array + var generator_energy: double + var max_solar_energy: double + var available_in_batteries: double + var battery_capacity: double + var shield: float + var max_shield: float + var inhibit_movement_bonus: Boolean + var valid: Boolean + var object_name: String /* "LuaEquipmentGrid" */ + fun help(): String +} + +external interface LuaEquipmentGridPrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var equipment_categories: Array + var width: uint + var height: uint + var locked: Boolean + var valid: Boolean + var object_name: String /* "LuaEquipmentGridPrototype" */ + fun help(): String +} + +external interface `T$31` { + var width: uint + var height: uint + var points: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$32` { + var spawn_and_station_height: float + var spawn_and_station_shadow_height_offset: float + var charge_approach_distance: float + var logistic_radius: float + var construction_radius: float + var charging_station_count: uint + var charging_distance: float + var charging_station_shift: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var charging_energy: double + var charging_threshold_distance: float + var robot_vertical_acceleration: float + var stationing_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var robot_limit: uint + var logistics_connection_distance: float + var robots_shrink_when_entering_and_exiting: Boolean +} + +external interface LuaEquipmentPrototype { + var name: String + var type: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var shape: `T$31` + var take_result: LuaItemPrototype? + var energy_production: double + var shield: float + var energy_per_shield: double + var logistic_parameters: `T$32` + var energy_consumption: double + var movement_bonus: float + var energy_source: LuaElectricEnergySourcePrototype + var equipment_categories: Array + var burner_prototype: LuaBurnerPrototype? + var electric_energy_source_prototype: LuaElectricEnergySourcePrototype? + var background_color: ColorTable + var attack_parameters: dynamic /* ProjectileAttackParameters? | StreamAttackParameters? | OtherAttackParameters? */ + get() = definedExternally + set(value) = definedExternally + var automatic: Boolean + var valid: Boolean + var object_name: String /* "LuaEquipmentPrototype" */ + fun help(): String +} + +external interface `T$33` { + var name: String + var input: Boolean + var precision_index: flow_precision_index + var count: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface LuaFlowStatistics { + fun get_input_count(name: String): dynamic /* uint64 | double */ + fun set_input_count(name: String, count: uint64) + fun get_output_count(name: String): dynamic /* uint64 | double */ + fun set_output_count(name: String, count: uint64) + fun get_flow_count(params: `T$33`): double + fun on_flow(name: String, count: float) + fun clear() + var input_counts: Record + var output_counts: Record + var force: LuaForce? + var valid: Boolean + var object_name: String /* "LuaFlowStatistics" */ + fun help(): String +} + +typealias LuaFluidBox = Array + +external interface LuaFluidBoxPrototype { + var entity: LuaEntityPrototype + var index: uint + var pipe_connections: Array + var production_type: String /* "input" | "output" | "input-output" | "none" */ + var base_area: double + var base_level: double + var height: double + var volume: double + var filter: LuaFluidPrototype? + var minimum_temperature: double? + var maximum_temperature: double? + var secondary_draw_orders: Array + var render_layer: String + var valid: Boolean + var object_name: String /* "LuaFluidBoxPrototype" */ + fun help(): String +} + +external interface LuaFluidEnergySourcePrototype { + var emissions: double + var render_no_network_icon: Boolean + var render_no_power_icon: Boolean + var effectivity: double + var burns_fluid: Boolean + var scale_fluid_usage: Boolean + var fluid_usage_per_tick: double + var smoke: Array + var maximum_temperature: double + var fluid_box: LuaFluidBoxPrototype + var valid: Boolean + var object_name: String /* "LuaFluidEnergySourcePrototype" */ + fun help(): String +} + +external interface LuaFluidPrototype { + var name: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var default_temperature: double + var max_temperature: double + var heat_capacity: double + var order: String + var group: LuaGroup + var subgroup: LuaGroup + var base_color: ColorTable + var flow_color: ColorTable + var gas_temperature: double + var emissions_multiplier: double + var fuel_value: double + var hidden: Boolean + var valid: Boolean + var object_name: String /* "LuaFluidPrototype" */ + fun help(): String +} + +external interface LuaFontPrototype { + var name: String + var from: String + var size: int + var spacing: float + var border: Boolean + var filtered: Boolean + var border_color: ColorTable? + var valid: Boolean + var object_name: String /* "LuaFontPrototype" */ + fun help(): String +} + +external interface `T$34` { + var path: dynamic /* String | */ + get() = definedExternally + set(value) = definedExternally + var position: Position? + get() = definedExternally + set(value) = definedExternally + var volume_modifier: double? + get() = definedExternally + set(value) = definedExternally + var override_sound_type: String? /* "game-effect" | "gui-effect" | "ambient" | "environment" | "walking" | "alert" | "wind" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$35` { + var name: dynamic /* String? | Array? */ + get() = definedExternally + set(value) = definedExternally + var surface: dynamic /* uint? | String? | LuaSurface? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface LuaForce { + fun get_entity_count(name: String): uint + fun disable_research() + fun enable_research() + fun disable_all_prototypes() + fun enable_all_prototypes() + fun reset_recipes() + fun enable_all_recipes() + fun enable_all_technologies() + fun research_all_technologies(include_disabled_prototypes: Boolean = definedExternally) + fun reset_technologies() + fun reset() + fun reset_technology_effects() + fun chart(surface: uint, area: BoundingBoxTable) + fun chart(surface: uint, area: Any /* JsTuple */) + fun chart(surface: String, area: BoundingBoxTable) + fun chart(surface: String, area: Any /* JsTuple */) + fun chart(surface: LuaSurface, area: BoundingBoxTable) + fun chart(surface: LuaSurface, area: Any /* JsTuple */) + fun clear_chart(surface: uint = definedExternally) + fun clear_chart() + fun clear_chart(surface: String = definedExternally) + fun clear_chart(surface: LuaSurface = definedExternally) + fun rechart() + fun chart_all(surface: uint = definedExternally) + fun chart_all() + fun chart_all(surface: String = definedExternally) + fun chart_all(surface: LuaSurface = definedExternally) + fun is_chunk_charted(surface: uint, position: ChunkPositionTable): Boolean + fun is_chunk_charted(surface: uint, position: Any /* JsTuple */): Boolean + fun is_chunk_charted(surface: String, position: ChunkPositionTable): Boolean + fun is_chunk_charted(surface: String, position: Any /* JsTuple */): Boolean + fun is_chunk_charted(surface: LuaSurface, position: ChunkPositionTable): Boolean + fun is_chunk_charted(surface: LuaSurface, position: Any /* JsTuple */): Boolean + fun is_chunk_visible(surface: uint, position: ChunkPositionTable): Boolean + fun is_chunk_visible(surface: uint, position: Any /* JsTuple */): Boolean + fun is_chunk_visible(surface: String, position: ChunkPositionTable): Boolean + fun is_chunk_visible(surface: String, position: Any /* JsTuple */): Boolean + fun is_chunk_visible(surface: LuaSurface, position: ChunkPositionTable): Boolean + fun is_chunk_visible(surface: LuaSurface, position: Any /* JsTuple */): Boolean + fun cancel_charting(surface: uint = definedExternally) + fun cancel_charting() + fun cancel_charting(surface: String = definedExternally) + fun cancel_charting(surface: LuaSurface = definedExternally) + fun get_ammo_damage_modifier(ammo: String): double + fun set_ammo_damage_modifier(ammo: String, modifier: double) + fun get_gun_speed_modifier(ammo: String): double + fun set_gun_speed_modifier(ammo: String, modifier: double) + fun get_turret_attack_modifier(turret: String): double + fun set_turret_attack_modifier(turret: String, modifier: double) + fun set_cease_fire(other: String, cease_fire: Boolean) + fun set_cease_fire(other: LuaForce, cease_fire: Boolean) + fun get_cease_fire(other: String): Boolean + fun get_cease_fire(other: LuaForce): Boolean + fun set_friend(other: String, friend: Boolean) + fun set_friend(other: LuaForce, friend: Boolean) + fun get_friend(other: String): Boolean + fun get_friend(other: LuaForce): Boolean + fun is_pathfinder_busy(): Boolean + fun kill_all_units() + fun find_logistic_network_by_position(position: Position, surface: uint): LuaLogisticNetwork? + fun find_logistic_network_by_position(position: Position, surface: String): LuaLogisticNetwork? + fun find_logistic_network_by_position(position: Position, surface: LuaSurface): LuaLogisticNetwork? + fun set_spawn_position(position: Position, surface: uint) + fun set_spawn_position(position: Position, surface: String) + fun set_spawn_position(position: Position, surface: LuaSurface) + fun get_spawn_position(surface: uint): PositionTable + fun get_spawn_position(surface: String): PositionTable + fun get_spawn_position(surface: LuaSurface): PositionTable + fun unchart_chunk(position: ChunkPositionTable, surface: uint) + fun unchart_chunk(position: ChunkPositionTable, surface: String) + fun unchart_chunk(position: ChunkPositionTable, surface: LuaSurface) + fun unchart_chunk(position: Any /* JsTuple */, surface: uint) + fun unchart_chunk(position: Any /* JsTuple */, surface: String) + fun unchart_chunk(position: Any /* JsTuple */, surface: LuaSurface) + fun get_item_launched(item: String): uint + fun set_item_launched(item: String, count: uint) + fun print(message: Any /* JsTuple */, color: ColorTable = definedExternally) + fun print(message: Any /* JsTuple */) + fun print(message: Any /* JsTuple */, color: Any /* JsTuple */ = definedExternally) + fun print(message: String, color: ColorTable = definedExternally) + fun print(message: String) + fun print(message: String, color: Any /* JsTuple */ = definedExternally) + fun print(message: Number, color: ColorTable = definedExternally) + fun print(message: Number) + fun print(message: Number, color: Any /* JsTuple */ = definedExternally) + fun get_trains(surface: uint = definedExternally): Array + fun get_trains(): Array + fun get_trains(surface: String = definedExternally): Array + fun get_trains(surface: LuaSurface = definedExternally): Array + fun add_chart_tag(surface: uint, tag: ChartTagSpec): LuaCustomChartTag? + fun add_chart_tag(surface: String, tag: ChartTagSpec): LuaCustomChartTag? + fun add_chart_tag(surface: LuaSurface, tag: ChartTagSpec): LuaCustomChartTag? + fun find_chart_tags(surface: uint, area: BoundingBoxTable = definedExternally): Array + fun find_chart_tags(surface: uint): Array + fun find_chart_tags(surface: uint, area: Any /* JsTuple */ = definedExternally): Array + fun find_chart_tags(surface: String, area: BoundingBoxTable = definedExternally): Array + fun find_chart_tags(surface: String): Array + fun find_chart_tags(surface: String, area: Any /* JsTuple */ = definedExternally): Array + fun find_chart_tags(surface: LuaSurface, area: BoundingBoxTable = definedExternally): Array + fun find_chart_tags(surface: LuaSurface): Array + fun find_chart_tags(surface: LuaSurface, area: Any /* JsTuple */ = definedExternally): Array + fun get_saved_technology_progress(technology: String): double? + fun get_saved_technology_progress(technology: LuaTechnology): double? + fun get_saved_technology_progress(technology: LuaTechnologyPrototype): double? + fun set_saved_technology_progress(technology: String, progress: double?) + fun set_saved_technology_progress(technology: LuaTechnology, progress: double?) + fun set_saved_technology_progress(technology: LuaTechnologyPrototype, progress: double?) + fun reset_evolution() + fun play_sound(params: `T$34`) + fun get_train_stops(params: `T$35` = definedExternally): Array + fun get_hand_crafting_disabled_for_recipe(recipe: String): Boolean + fun get_hand_crafting_disabled_for_recipe(recipe: LuaRecipe): Boolean + fun set_hand_crafting_disabled_for_recipe(recipe: String, hand_crafting_disabled: Boolean) + fun set_hand_crafting_disabled_for_recipe(recipe: LuaRecipe, hand_crafting_disabled: Boolean) + fun add_research(technology: String): Boolean + fun add_research(technology: LuaTechnology): Boolean + fun add_research(technology: LuaTechnologyPrototype): Boolean + fun cancel_current_research() + fun get_linked_inventory(prototype: LuaEntity, link_id: uint): LuaInventory? + fun get_linked_inventory(prototype: LuaEntityPrototype, link_id: uint): LuaInventory? + fun get_linked_inventory(prototype: String, link_id: uint): LuaInventory? + fun is_friend(other: String): Boolean + fun is_friend(other: LuaForce): Boolean + fun is_enemy(other: String): Boolean + fun is_enemy(other: LuaForce): Boolean + var name: String + var technologies: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var recipes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var manual_mining_speed_modifier: double + var manual_crafting_speed_modifier: double + var laboratory_speed_modifier: double + var laboratory_productivity_bonus: double + var worker_robots_speed_modifier: double + var worker_robots_battery_modifier: double + var worker_robots_storage_bonus: double + var current_research: LuaTechnology? + var research_progress: double + var previous_research: LuaTechnology + var inserter_stack_size_bonus: double + var stack_inserter_capacity_bonus: uint + var character_trash_slot_count: double + var maximum_following_robot_count: uint + var following_robots_lifetime_modifier: double + var ghost_time_to_live: uint + var players: Array + var ai_controllable: Boolean + var logistic_networks: Record> + var item_production_statistics: LuaFlowStatistics + var fluid_production_statistics: LuaFlowStatistics + var kill_count_statistics: LuaFlowStatistics + var entity_build_count_statistics: LuaFlowStatistics + var character_running_speed_modifier: double + var artillery_range_modifier: double + var character_build_distance_bonus: uint + var character_item_drop_distance_bonus: uint + var character_reach_distance_bonus: uint + var character_resource_reach_distance_bonus: double + var character_item_pickup_distance_bonus: double + var character_loot_pickup_distance_bonus: double + var character_inventory_slots_bonus: uint + var deconstruction_time_to_live: uint + var character_health_bonus: double + var max_successful_attempts_per_tick_per_construction_queue: uint + var max_failed_attempts_per_tick_per_construction_queue: uint + var zoom_to_world_enabled: Boolean + var zoom_to_world_ghost_building_enabled: Boolean + var zoom_to_world_blueprint_enabled: Boolean + var zoom_to_world_deconstruction_planner_enabled: Boolean + var zoom_to_world_selection_tool_enabled: Boolean + var character_logistic_requests: Boolean + var rockets_launched: uint + var items_launched: Record + var connected_players: Array + var mining_drill_productivity_bonus: double + var train_braking_force_bonus: double + var evolution_factor: double + var evolution_factor_by_pollution: double + var evolution_factor_by_time: double + var evolution_factor_by_killing_spawners: double + var friendly_fire: Boolean + var share_chart: Boolean + var research_queue_enabled: Boolean + var index: uint + var research_queue: Array? + var research_enabled: Boolean + var valid: Boolean + var object_name: String /* "LuaForce" */ + fun help(): String +} + +external interface LuaFuelCategoryPrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var valid: Boolean + var object_name: String /* "LuaFuelCategoryPrototype" */ + fun help(): String +} + +external interface `T$36` { + var game_finished: Boolean + var player_won: Boolean + var next_level: String + var can_continue: Boolean + var victorious_force: dynamic /* String | LuaForce */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$37` { + var text: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var image: String? + get() = definedExternally + set(value) = definedExternally + var point_to: dynamic /* EntityGuiArrowSpecification? | PositionGuiArrowSpecification? | CraftingQueueGuiArrowSpecification? | ItemStackGuiArrowSpecification? | OtherGuiArrowSpecification? */ + get() = definedExternally + set(value) = definedExternally + var style: String? + get() = definedExternally + set(value) = definedExternally + var wrapper_frame_style: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$38` { + var player: dynamic /* uint? | String? | LuaPlayer? */ + get() = definedExternally + set(value) = definedExternally + var by_player: dynamic /* uint? | String? | LuaPlayer? */ + get() = definedExternally + set(value) = definedExternally + var surface: dynamic /* uint? | String? | LuaSurface? */ + get() = definedExternally + set(value) = definedExternally + var position: Position? + get() = definedExternally + set(value) = definedExternally + var resolution: Position? + get() = definedExternally + set(value) = definedExternally + var zoom: double? + get() = definedExternally + set(value) = definedExternally + var path: String? + get() = definedExternally + set(value) = definedExternally + var show_gui: Boolean? + get() = definedExternally + set(value) = definedExternally + var show_entity_info: Boolean? + get() = definedExternally + set(value) = definedExternally + var show_cursor_building_preview: Boolean? + get() = definedExternally + set(value) = definedExternally + var anti_alias: Boolean? + get() = definedExternally + set(value) = definedExternally + var quality: int? + get() = definedExternally + set(value) = definedExternally + var allow_in_replay: Boolean? + get() = definedExternally + set(value) = definedExternally + var daytime: double? + get() = definedExternally + set(value) = definedExternally + var water_tick: uint? + get() = definedExternally + set(value) = definedExternally + var force_render: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$39` { + var force: dynamic /* String? | LuaForce? */ + get() = definedExternally + set(value) = definedExternally + var path: String? + get() = definedExternally + set(value) = definedExternally + var by_player: dynamic /* uint? | String? | LuaPlayer? */ + get() = definedExternally + set(value) = definedExternally + var selected_technology: dynamic /* String? | LuaTechnology? | LuaTechnologyPrototype? */ + get() = definedExternally + set(value) = definedExternally + var skip_disabled: Boolean? + get() = definedExternally + set(value) = definedExternally + var quality: int? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$40` { + var name: dynamic /* String? | Array? */ + get() = definedExternally + set(value) = definedExternally + var surface: dynamic /* uint? | String? | LuaSurface? */ + get() = definedExternally + set(value) = definedExternally + var force: dynamic /* String? | LuaForce? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface LuaGameScript { + fun set_game_state(params: `T$36`) + fun get_entity_by_tag(tag: String): LuaEntity + fun show_message_dialog(params: `T$37`) + fun is_demo(): Boolean + fun reload_script() + fun reload_mods() + fun save_atlas() + fun check_consistency() + fun regenerate_entity(entities: String) + fun regenerate_entity(entities: Array) + fun take_screenshot(params: `T$38`) + fun set_wait_for_screenshots_to_finish() + fun take_technology_screenshot(params: `T$39`) + fun table_to_json(data: table): String + fun json_to_table(json: String): dynamic /* String? | Number? | Boolean? | table? */ + fun write_file(filename: String, data: Any /* JsTuple */, append: Boolean = definedExternally, for_player: uint = definedExternally) + fun write_file(filename: String, data: Any /* JsTuple */) + fun write_file(filename: String, data: Any /* JsTuple */, append: Boolean = definedExternally) + fun write_file(filename: String, data: String, append: Boolean = definedExternally, for_player: uint = definedExternally) + fun write_file(filename: String, data: String) + fun write_file(filename: String, data: String, append: Boolean = definedExternally) + fun write_file(filename: String, data: Number, append: Boolean = definedExternally, for_player: uint = definedExternally) + fun write_file(filename: String, data: Number) + fun write_file(filename: String, data: Number, append: Boolean = definedExternally) + fun remove_path(path: String) + fun remove_offline_players(players: Array = definedExternally) + fun force_crc() + fun create_force(force: String): LuaForce + fun merge_forces(source: String, destination: String) + fun merge_forces(source: String, destination: LuaForce) + fun merge_forces(source: LuaForce, destination: String) + fun merge_forces(source: LuaForce, destination: LuaForce) + fun create_surface(name: String, settings: MapGenSettings = definedExternally): LuaSurface + fun server_save(name: String = definedExternally) + fun auto_save(name: String = definedExternally) + fun delete_surface(surface: String) + fun delete_surface(surface: LuaSurface) + fun disable_replay() + fun disable_tutorial_triggers() + fun direction_to_string(direction: direction) + fun print(message: Any /* JsTuple */, color: ColorTable = definedExternally) + fun print(message: Any /* JsTuple */) + fun print(message: Any /* JsTuple */, color: Any /* JsTuple */ = definedExternally) + fun print(message: String, color: ColorTable = definedExternally) + fun print(message: String) + fun print(message: String, color: Any /* JsTuple */ = definedExternally) + fun print(message: Number, color: ColorTable = definedExternally) + fun print(message: Number) + fun print(message: Number, color: Any /* JsTuple */ = definedExternally) + fun create_random_generator(seed: uint = definedExternally): LuaRandomGenerator + fun check_prototype_translations() + fun play_sound(params: `T$34`) + fun is_valid_sound_path(sound_path: String): Boolean + fun is_valid_sound_path(sound_path: ): Boolean + fun is_valid_sprite_path(sprite_path: String): Boolean + fun is_valid_sprite_path(sprite_path: ): Boolean + fun kick_player(player: uint, reason: Any /* JsTuple */ = definedExternally) + fun kick_player(player: uint) + fun kick_player(player: uint, reason: String = definedExternally) + fun kick_player(player: uint, reason: Number = definedExternally) + fun kick_player(player: String, reason: Any /* JsTuple */ = definedExternally) + fun kick_player(player: String) + fun kick_player(player: String, reason: String = definedExternally) + fun kick_player(player: String, reason: Number = definedExternally) + fun kick_player(player: LuaPlayer, reason: Any /* JsTuple */ = definedExternally) + fun kick_player(player: LuaPlayer) + fun kick_player(player: LuaPlayer, reason: String = definedExternally) + fun kick_player(player: LuaPlayer, reason: Number = definedExternally) + fun ban_player(player: uint, reason: Any /* JsTuple */ = definedExternally) + fun ban_player(player: uint) + fun ban_player(player: uint, reason: String = definedExternally) + fun ban_player(player: uint, reason: Number = definedExternally) + fun ban_player(player: String, reason: Any /* JsTuple */ = definedExternally) + fun ban_player(player: String) + fun ban_player(player: String, reason: String = definedExternally) + fun ban_player(player: String, reason: Number = definedExternally) + fun ban_player(player: LuaPlayer, reason: Any /* JsTuple */ = definedExternally) + fun ban_player(player: LuaPlayer) + fun ban_player(player: LuaPlayer, reason: String = definedExternally) + fun ban_player(player: LuaPlayer, reason: Number = definedExternally) + fun unban_player(player: uint) + fun unban_player(player: String) + fun unban_player(player: LuaPlayer) + fun purge_player(player: uint) + fun purge_player(player: String) + fun purge_player(player: LuaPlayer) + fun mute_player(player: uint) + fun mute_player(player: String) + fun mute_player(player: LuaPlayer) + fun unmute_player(player: uint) + fun unmute_player(player: String) + fun unmute_player(player: LuaPlayer) + fun count_pipe_groups() + fun is_multiplayer(): Boolean + fun get_active_entities_count(surface: uint = definedExternally): uint + fun get_active_entities_count(): uint + fun get_active_entities_count(surface: String = definedExternally): uint + fun get_active_entities_count(surface: LuaSurface = definedExternally): uint + fun get_map_exchange_string(): String + fun parse_map_exchange_string(map_exchange_string: String): MapExchangeStringData + fun get_train_stops(params: `T$40` = definedExternally): Array + fun get_player(player: uint): LuaPlayer? + fun get_player(player: String): LuaPlayer? + fun get_surface(surface: uint): LuaSurface? + fun get_surface(surface: String): LuaSurface? + fun create_profiler(stopped: Boolean = definedExternally): LuaProfiler + fun evaluate_expression(expression: String, variables: Record = definedExternally): double + fun get_filtered_entity_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + fun get_filtered_item_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + fun get_filtered_equipment_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + fun get_filtered_mod_setting_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + fun get_filtered_achievement_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + fun get_filtered_tile_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + fun get_filtered_decorative_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + fun get_filtered_fluid_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + fun get_filtered_recipe_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + fun get_filtered_technology_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + fun create_inventory(size: uint16): LuaInventory + fun get_script_inventories(mod: String = definedExternally): Record> + fun reset_time_played() + fun encode_string(string: String): String? + fun decode_string(string: String): String? + var player: LuaPlayer? + var players: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var map_settings: MapSettings + var difficulty_settings: DifficultySettings + var difficulty: difficulty + var forces: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var entity_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var item_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var fluid_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var tile_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var equipment_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var damage_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var virtual_signal_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var equipment_grid_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var recipe_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var technology_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var decorative_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var particle_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var autoplace_control_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var noise_layer_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var mod_setting_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var custom_input_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var ammo_category_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var named_noise_expressions: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var item_subgroup_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var item_group_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var fuel_category_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var resource_category_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var achievement_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var module_category_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var equipment_category_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var trivial_smoke_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var shortcut_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var recipe_category_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var font_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var map_gen_presets: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var styles: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var tick: uint + var ticks_played: uint + var tick_paused: Boolean + var ticks_to_run: uint + var finished: Boolean + var speed: float + var surfaces: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var active_mods: Record + var connected_players: Array + var permissions: LuaPermissionGroups + var backer_names: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var default_map_gen_settings: MapGenSettings + var enemy_has_vision_on_land_mines: Boolean + var autosave_enabled: Boolean + var draw_resource_selection: Boolean + var pollution_statistics: LuaFlowStatistics + var max_force_distraction_distance: double + var max_force_distraction_chunk_distance: uint + var max_electric_pole_supply_area_distance: float + var max_electric_pole_connection_distance: double + var max_beacon_supply_area_distance: double + var max_gate_activation_distance: double + var max_inserter_reach_distance: double + var max_pipe_to_ground_distance: uint8 + var max_underground_belt_distance: uint8 + var object_name: String /* "LuaGameScript" */ +} + +external interface LuaGenericOnOffControlBehavior : LuaControlBehavior { + var disabled: Boolean + var circuit_condition: CircuitConditionDefinition + var logistic_condition: CircuitConditionDefinition + var connect_to_logistic_network: Boolean + var valid: Boolean + var object_name: String + fun help(): String +} + +external interface LuaGroup { + var name: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var type: String + var group: LuaGroup? + var subgroups: Array + var order_in_recipe: String + var order: String + var valid: Boolean + var object_name: String /* "LuaGroup" */ + fun help(): String +} + +external interface LuaGui { + fun is_valid_sprite_path(sprite_path: String): Boolean + fun is_valid_sprite_path(sprite_path: ): Boolean + var player: LuaPlayer + var children: Record + var top: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var left: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var center: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var goal: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var screen: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var relative: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var valid: Boolean + var object_name: String /* "LuaGui" */ + fun help(): String +} + +external interface BaseGuiSpec { + var type: String /* "choose-elem-button" | "drop-down" | "empty-widget" | "entity-preview" | "list-box" | "scroll-pane" | "sprite-button" | "tabbed-pane" | "text-box" | "button" | "camera" | "checkbox" | "flow" | "frame" | "label" | "line" | "minimap" | "progressbar" | "radiobutton" | "slider" | "sprite" | "switch" | "tab" | "table" | "textfield" */ + var name: String? + get() = definedExternally + set(value) = definedExternally + var caption: dynamic /* JsTuple | String? | Number? */ + get() = definedExternally + set(value) = definedExternally + var tooltip: dynamic /* JsTuple | String? | Number? */ + get() = definedExternally + set(value) = definedExternally + var enabled: Boolean? + get() = definedExternally + set(value) = definedExternally + var visible: Boolean? + get() = definedExternally + set(value) = definedExternally + var ignored_by_interaction: Boolean? + get() = definedExternally + set(value) = definedExternally + var style: String? + get() = definedExternally + set(value) = definedExternally + var tags: Tags? + get() = definedExternally + set(value) = definedExternally + var index: uint? + get() = definedExternally + set(value) = definedExternally + var anchor: GuiAnchor? + get() = definedExternally + set(value) = definedExternally +} + +external interface ButtonGuiSpec : BaseGuiSpec { + override var type: String /* "button" */ + var mouse_button_filter: dynamic /* MouseButtonFlagsTable? | MouseButtonFlagsArray? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowGuiSpec : BaseGuiSpec { + override var type: String /* "flow" */ + var direction: String? /* "horizontal" | "vertical" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FrameGuiSpec : BaseGuiSpec { + override var type: String /* "frame" */ + var direction: String? /* "horizontal" | "vertical" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface TableGuiSpec : BaseGuiSpec { + override var type: String /* "table" */ + var column_count: uint + var draw_vertical_lines: Boolean? + get() = definedExternally + set(value) = definedExternally + var draw_horizontal_lines: Boolean? + get() = definedExternally + set(value) = definedExternally + var draw_horizontal_line_after_headers: Boolean? + get() = definedExternally + set(value) = definedExternally + var vertical_centering: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TextfieldGuiSpec : BaseGuiSpec { + override var type: String /* "textfield" */ + var text: String? + get() = definedExternally + set(value) = definedExternally + var numeric: Boolean? + get() = definedExternally + set(value) = definedExternally + var allow_decimal: Boolean? + get() = definedExternally + set(value) = definedExternally + var allow_negative: Boolean? + get() = definedExternally + set(value) = definedExternally + var is_password: Boolean? + get() = definedExternally + set(value) = definedExternally + var lose_focus_on_confirm: Boolean? + get() = definedExternally + set(value) = definedExternally + var clear_and_focus_on_right_click: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ProgressbarGuiSpec : BaseGuiSpec { + override var type: String /* "progressbar" */ + var value: double? + get() = definedExternally + set(value) = definedExternally +} + +external interface CheckboxGuiSpec : BaseGuiSpec { + override var type: String /* "checkbox" */ + var state: Boolean +} + +external interface RadiobuttonGuiSpec : BaseGuiSpec { + override var type: String /* "radiobutton" */ + var state: Boolean +} + +external interface SpriteButtonGuiSpec : BaseGuiSpec { + override var type: String /* "sprite-button" */ + var sprite: dynamic /* String? | ? */ + get() = definedExternally + set(value) = definedExternally + var hovered_sprite: dynamic /* String? | ? */ + get() = definedExternally + set(value) = definedExternally + var clicked_sprite: dynamic /* String? | ? */ + get() = definedExternally + set(value) = definedExternally + var number: double? + get() = definedExternally + set(value) = definedExternally + var show_percent_for_small_numbers: Boolean? + get() = definedExternally + set(value) = definedExternally + var mouse_button_filter: dynamic /* MouseButtonFlagsTable? | MouseButtonFlagsArray? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface SpriteGuiSpec : BaseGuiSpec { + override var type: String /* "sprite" */ + var sprite: dynamic /* String? | ? */ + get() = definedExternally + set(value) = definedExternally + var resize_to_sprite: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ScrollPaneGuiSpec : BaseGuiSpec { + override var type: String /* "scroll-pane" */ + var horizontal_scroll_policy: String? /* "auto" | "never" | "always" | "auto-and-reserve-space" | "dont-show-but-allow-scrolling" */ + get() = definedExternally + set(value) = definedExternally + var vertical_scroll_policy: String? /* "auto" | "never" | "always" | "auto-and-reserve-space" | "dont-show-but-allow-scrolling" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface DropDownGuiSpec : BaseGuiSpec { + override var type: String /* "drop-down" */ + var items: Array | String | Number */>? + get() = definedExternally + set(value) = definedExternally + var selected_index: uint? + get() = definedExternally + set(value) = definedExternally +} + +external interface LineGuiSpec : BaseGuiSpec { + override var type: String /* "line" */ + var direction: String? /* "horizontal" | "vertical" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ListBoxGuiSpec : BaseGuiSpec { + override var type: String /* "list-box" */ + var items: Array | String | Number */>? + get() = definedExternally + set(value) = definedExternally + var selected_index: uint? + get() = definedExternally + set(value) = definedExternally +} + +external interface CameraGuiSpec : BaseGuiSpec { + override var type: String /* "camera" */ + var position: Position + var surface_index: uint? + get() = definedExternally + set(value) = definedExternally + var zoom: double? + get() = definedExternally + set(value) = definedExternally +} + +external interface ChooseElemButtonFilters { + @nativeGetter + operator fun get(key: String): Any? + @nativeSetter + operator fun set(key: String, value: Any) + var item: Array + var tile: Array + var entity: Array + var signal: Any + var fluid: Array + var recipe: Array + var decorative: Array + var achievement: Array + var equipment: Array + var technology: Array +} + +external interface BaseChooseElemButtonSpec : BaseGuiSpec { + override var type: String /* "choose-elem-button" */ + var elem_type: String /* "item" | "tile" | "entity" | "signal" | "fluid" | "recipe" | "decorative" | "item-group" | "achievement" | "equipment" | "technology" */ + var filters: Any + get() = definedExternally + set(value) = definedExternally +} + +external interface ItemChooseElemButtonSpec : BaseChooseElemButtonSpec { + override var elem_type: String /* "item" */ + var item: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface TileChooseElemButtonSpec : BaseChooseElemButtonSpec { + override var elem_type: String /* "tile" */ + var tile: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface EntityChooseElemButtonSpec : BaseChooseElemButtonSpec { + override var elem_type: String /* "entity" */ + var entity: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignalChooseElemButtonSpec : BaseChooseElemButtonSpec { + override var elem_type: String /* "signal" */ + var signal: SignalID? + get() = definedExternally + set(value) = definedExternally +} + +external interface FluidChooseElemButtonSpec : BaseChooseElemButtonSpec { + override var elem_type: String /* "fluid" */ + var fluid: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface RecipeChooseElemButtonSpec : BaseChooseElemButtonSpec { + override var elem_type: String /* "recipe" */ + var recipe: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface DecorativeChooseElemButtonSpec : BaseChooseElemButtonSpec { + override var elem_type: String /* "decorative" */ + var decorative: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface ItemGroupChooseElemButtonSpec : BaseChooseElemButtonSpec { + @nativeGetter + operator fun get(key: String): String? + @nativeSetter + operator fun set(key: String, value: String?) + override var elem_type: String /* "item-group" */ +} + +external interface AchievementChooseElemButtonSpec : BaseChooseElemButtonSpec { + override var elem_type: String /* "achievement" */ + var achievement: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface EquipmentChooseElemButtonSpec : BaseChooseElemButtonSpec { + override var elem_type: String /* "equipment" */ + var equipment: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface TechnologyChooseElemButtonSpec : BaseChooseElemButtonSpec { + override var elem_type: String /* "technology" */ + var technology: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface TextBoxGuiSpec : BaseGuiSpec { + override var type: String /* "text-box" */ + var text: String? + get() = definedExternally + set(value) = definedExternally + var clear_and_focus_on_right_click: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface SliderGuiSpec : BaseGuiSpec { + override var type: String /* "slider" */ + var minimum_value: double? + get() = definedExternally + set(value) = definedExternally + var maximum_value: double? + get() = definedExternally + set(value) = definedExternally + var value: double? + get() = definedExternally + set(value) = definedExternally + var value_step: double? + get() = definedExternally + set(value) = definedExternally + var discrete_slider: Boolean? + get() = definedExternally + set(value) = definedExternally + var discrete_values: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface MinimapGuiSpec : BaseGuiSpec { + override var type: String /* "minimap" */ + var position: Position? + get() = definedExternally + set(value) = definedExternally + var surface_index: uint? + get() = definedExternally + set(value) = definedExternally + var chart_player_index: uint? + get() = definedExternally + set(value) = definedExternally + var force: String? + get() = definedExternally + set(value) = definedExternally + var zoom: double? + get() = definedExternally + set(value) = definedExternally +} + +external interface TabGuiSpec : BaseGuiSpec { + override var type: String /* "tab" */ + var badge_text: dynamic /* JsTuple | String? | Number? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface SwitchGuiSpec : BaseGuiSpec { + override var type: String /* "switch" */ + var switch_state: String? /* "left" | "right" | "none" */ + get() = definedExternally + set(value) = definedExternally + var allow_none_state: Boolean? + get() = definedExternally + set(value) = definedExternally + var left_label_caption: dynamic /* JsTuple | String? | Number? */ + get() = definedExternally + set(value) = definedExternally + var left_label_tooltip: dynamic /* JsTuple | String? | Number? */ + get() = definedExternally + set(value) = definedExternally + var right_label_caption: dynamic /* JsTuple | String? | Number? */ + get() = definedExternally + set(value) = definedExternally + var right_label_tooltip: dynamic /* JsTuple | String? | Number? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface OtherGuiSpec : BaseGuiSpec { + override var type: String /* "empty-widget" | "entity-preview" | "tabbed-pane" | "label" */ +} + +external interface GuiElementIndex { + @nativeGetter + operator fun get(name: String): dynamic /* ChooseElemButtonGuiElementMembers? | DropDownGuiElementMembers? | EmptyWidgetGuiElementMembers? | EntityPreviewGuiElementMembers? | ListBoxGuiElementMembers? | ScrollPaneGuiElementMembers? | SpriteButtonGuiElementMembers? | TabbedPaneGuiElementMembers? | TextBoxGuiElementMembers? | ButtonGuiElementMembers? | CameraGuiElementMembers? | CheckboxGuiElementMembers? | FlowGuiElementMembers? | FrameGuiElementMembers? | LabelGuiElementMembers? | LineGuiElementMembers? | MinimapGuiElementMembers? | ProgressbarGuiElementMembers? | RadiobuttonGuiElementMembers? | SliderGuiElementMembers? | SpriteGuiElementMembers? | SwitchGuiElementMembers? | TabGuiElementMembers? | TableGuiElementMembers? | TextfieldGuiElementMembers? */ + @nativeSetter + operator fun set(name: String, value: ChooseElemButtonGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: DropDownGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: EmptyWidgetGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: EntityPreviewGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: ListBoxGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: ScrollPaneGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: SpriteButtonGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: TabbedPaneGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: TextBoxGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: ButtonGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: CameraGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: CheckboxGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: FlowGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: FrameGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: LabelGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: LineGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: MinimapGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: ProgressbarGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: RadiobuttonGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: SliderGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: SpriteGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: SwitchGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: TabGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: TableGuiElementMembers) + @nativeSetter + operator fun set(name: String, value: TextfieldGuiElementMembers) +} + +external interface `T$41` { + var type: Type +} + +external interface BaseGuiElement { + fun add(element: Any /* ButtonGuiSpec | FlowGuiSpec | FrameGuiSpec | TableGuiSpec | TextfieldGuiSpec | ProgressbarGuiSpec | CheckboxGuiSpec | RadiobuttonGuiSpec | SpriteButtonGuiSpec | SpriteGuiSpec | ScrollPaneGuiSpec | DropDownGuiSpec | LineGuiSpec | ListBoxGuiSpec | CameraGuiSpec | ItemChooseElemButtonSpec | TileChooseElemButtonSpec | EntityChooseElemButtonSpec | SignalChooseElemButtonSpec | FluidChooseElemButtonSpec | RecipeChooseElemButtonSpec | DecorativeChooseElemButtonSpec | ItemGroupChooseElemButtonSpec | AchievementChooseElemButtonSpec | EquipmentChooseElemButtonSpec | TechnologyChooseElemButtonSpec | TextBoxGuiSpec | SliderGuiSpec | MinimapGuiSpec | TabGuiSpec | SwitchGuiSpec | OtherGuiSpec */): Extract> + fun clear() + fun destroy() + fun get_mod(): String? + fun get_index_in_parent(): uint + fun clear_items() + fun get_item(index: uint): dynamic /* JsTuple | String | Number */ + fun set_item(index: uint, string: Any /* JsTuple */) + fun set_item(index: uint, string: String) + fun set_item(index: uint, string: Number) + fun add_item(string: Any /* JsTuple */, index: uint = definedExternally) + fun add_item(string: Any /* JsTuple */) + fun add_item(string: String, index: uint = definedExternally) + fun add_item(string: String) + fun add_item(string: Number, index: uint = definedExternally) + fun add_item(string: Number) + fun remove_item(index: uint) + fun get_slider_minimum(): double + fun get_slider_maximum(): double + fun set_slider_minimum_maximum(minimum: double, maximum: double) + fun get_slider_value_step(): double + fun get_slider_discrete_slider(): Boolean + fun get_slider_discrete_values(): Boolean + fun set_slider_value_step(value: double) + fun set_slider_discrete_slider(value: Boolean) + fun set_slider_discrete_values(value: Boolean) + fun focus() + fun bring_to_front() + var index: uint + var gui: LuaGui + var parent: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var name: String + var caption: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var style: dynamic /* LuaStyle | String */ + get() = definedExternally + set(value) = definedExternally + var visible: Boolean + var children_names: Array + var player_index: uint + var sprite: dynamic /* String | */ + get() = definedExternally + set(value) = definedExternally + var resize_to_sprite: Boolean + var clicked_sprite: dynamic /* String | */ + get() = definedExternally + set(value) = definedExternally + var tooltip: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var type: String /* "choose-elem-button" | "drop-down" | "empty-widget" | "entity-preview" | "list-box" | "scroll-pane" | "sprite-button" | "tabbed-pane" | "text-box" | "button" | "camera" | "checkbox" | "flow" | "frame" | "label" | "line" | "minimap" | "progressbar" | "radiobutton" | "slider" | "sprite" | "switch" | "tab" | "table" | "textfield" */ + var children: Array + var items: Array | String | Number */> + var selected_index: uint + var number: double? + var show_percent_for_small_numbers: Boolean + var location: dynamic /* GuiLocationTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var position: Position + var surface_index: uint + var zoom: double + var force: String? + var enabled: Boolean + var ignored_by_interaction: Boolean + var mouse_button_filter: dynamic /* MouseButtonFlagsTable | MouseButtonFlagsArray */ + get() = definedExternally + set(value) = definedExternally + var drag_target: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var tabs: Array + var entity: LuaEntity? + var anchor: GuiAnchor? + var tags: Tags + var valid: Boolean + var object_name: String /* "LuaGuiElement" */ + fun help(): String +} + +external interface ChooseElemButtonGuiElementMembers : BaseGuiElement { + override var type: String /* "choose-elem-button" */ + var elem_type: String /* "item" | "tile" | "entity" | "signal" | "fluid" | "recipe" | "decorative" | "item-group" | "achievement" | "equipment" | "technology" */ + var elem_value: Any? + var elem_filters: Any + var locked: Boolean +} + +external interface DropDownGuiElementMembers : BaseGuiElement { + override var type: String /* "drop-down" */ +} + +external interface EmptyWidgetGuiElementMembers : BaseGuiElement { + override var type: String /* "empty-widget" */ +} + +external interface EntityPreviewGuiElementMembers : BaseGuiElement { + override var type: String /* "entity-preview" */ +} + +external interface ListBoxGuiElementMembers : BaseGuiElement { + override var type: String /* "list-box" */ + fun scroll_to_item(index: int, scroll_mode: String /* "in-view" | "top-third" */ = definedExternally) +} + +external interface ScrollPaneGuiElementMembers : BaseGuiElement { + override var type: String /* "scroll-pane" */ + fun scroll_to_top() + fun scroll_to_bottom() + fun scroll_to_left() + fun scroll_to_right() + fun scroll_to_element(element: Any /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */, scroll_mode: String /* "in-view" | "top-third" */ = definedExternally) + var horizontal_scroll_policy: String /* "auto" | "never" | "always" | "auto-and-reserve-space" | "dont-show-but-allow-scrolling" */ + var vertical_scroll_policy: String /* "auto" | "never" | "always" | "auto-and-reserve-space" | "dont-show-but-allow-scrolling" */ +} + +external interface SpriteButtonGuiElementMembers : BaseGuiElement { + override var type: String /* "sprite-button" */ + var hovered_sprite: dynamic /* String | */ + get() = definedExternally + set(value) = definedExternally +} + +external interface TabbedPaneGuiElementMembers : BaseGuiElement { + override var type: String /* "tabbed-pane" */ + fun add_tab(tab: Any /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */, content: Any /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */) + fun remove_tab(tab: Any /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */) + var selected_tab_index: uint? +} + +external interface TextBoxGuiElementMembers : BaseGuiElement { + override var type: String /* "text-box" */ + fun scroll_to_top() + fun scroll_to_bottom() + fun scroll_to_left() + fun scroll_to_right() + fun select_all() + fun select(start: int, end: int) + var text: String + var selectable: Boolean + var word_wrap: Boolean + var read_only: Boolean + var clear_and_focus_on_right_click: Boolean +} + +external interface ButtonGuiElementMembers : BaseGuiElement { + override var type: String /* "button" */ +} + +external interface CameraGuiElementMembers : BaseGuiElement { + override var type: String /* "camera" */ +} + +external interface CheckboxGuiElementMembers : BaseGuiElement { + override var type: String /* "checkbox" */ + var state: Boolean +} + +external interface FlowGuiElementMembers : BaseGuiElement { + override var type: String /* "flow" */ + var direction: String /* "horizontal" | "vertical" */ +} + +external interface FrameGuiElementMembers : BaseGuiElement { + override var type: String /* "frame" */ + fun force_auto_center() + var direction: String /* "horizontal" | "vertical" */ + var auto_center: Boolean +} + +external interface LabelGuiElementMembers : BaseGuiElement { + override var type: String /* "label" */ +} + +external interface LineGuiElementMembers : BaseGuiElement { + override var type: String /* "line" */ + var direction: String /* "horizontal" | "vertical" */ +} + +external interface MinimapGuiElementMembers : BaseGuiElement { + override var type: String /* "minimap" */ + var minimap_player_index: uint +} + +external interface ProgressbarGuiElementMembers : BaseGuiElement { + override var type: String /* "progressbar" */ + var value: double +} + +external interface RadiobuttonGuiElementMembers : BaseGuiElement { + override var type: String /* "radiobutton" */ + var state: Boolean +} + +external interface SliderGuiElementMembers : BaseGuiElement { + override var type: String /* "slider" */ + var slider_value: double +} + +external interface SpriteGuiElementMembers : BaseGuiElement { + override var type: String /* "sprite" */ +} + +external interface SwitchGuiElementMembers : BaseGuiElement { + override var type: String /* "switch" */ + var switch_state: String + var allow_none_state: Boolean + var left_label_caption: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var left_label_tooltip: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var right_label_caption: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var right_label_tooltip: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally +} + +external interface TabGuiElementMembers : BaseGuiElement { + override var type: String /* "tab" */ + var badge_text: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally +} + +external interface TableGuiElementMembers : BaseGuiElement { + override var type: String /* "table" */ + var draw_vertical_lines: Boolean + var draw_horizontal_lines: Boolean + var draw_horizontal_line_after_headers: Boolean + var column_count: uint + var vertical_centering: Boolean +} + +external interface TextfieldGuiElementMembers : BaseGuiElement { + override var type: String /* "textfield" */ + fun select_all() + fun select(start: int, end: int) + var text: String + var numeric: Boolean + var allow_decimal: Boolean + var allow_negative: Boolean + var is_password: Boolean + var lose_focus_on_confirm: Boolean + var clear_and_focus_on_right_click: Boolean +} + +external interface LuaHeatEnergySourcePrototype { + var emissions: double + var render_no_network_icon: Boolean + var render_no_power_icon: Boolean + var max_temperature: double + var default_temperature: double + var specific_heat: double + var max_transfer: double + var min_temperature_gradient: double + var min_working_temperature: double + var minimum_glow_temperature: double + var connections: Array + var valid: Boolean + var object_name: String /* "LuaHeatEnergySourcePrototype" */ + fun help(): String +} + +external interface LuaInserterControlBehavior : LuaGenericOnOffControlBehavior { + var circuit_read_hand_contents: Boolean + var circuit_mode_of_operation: circuit_mode_of_operation + var circuit_hand_read_mode: hand_read_mode + var circuit_set_stack_size: Boolean + var circuit_stack_control_signal: SignalID + override var valid: Boolean + override var object_name: String /* "LuaInserterControlBehavior" */ + override fun help(): String +} + +typealias LuaInventory = Array + +external interface LuaItemPrototype { + fun has_flag(flag: String): Boolean + fun get_ammo_type(ammo_source_type: String /* "default" | "player" | "turret" | "vehicle" */ = definedExternally): AmmoType? + var type: String /* "gun" | "mining-tool" */ + var name: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var order: String + var place_result: LuaEntityPrototype? + var place_as_equipment_result: LuaEquipmentPrototype? + var place_as_tile_result: PlaceAsTileResult? + var stackable: Boolean + var default_request_amount: uint + var stack_size: uint + var wire_count: uint + var fuel_category: String? + var burnt_result: LuaItemPrototype? + var fuel_value: float + var fuel_acceleration_multiplier: double + var fuel_top_speed_multiplier: double + var fuel_emissions_multiplier: double + var subgroup: LuaGroup + var group: LuaGroup + var flags: ItemPrototypeFlags + var rocket_launch_products: Array + var can_be_mod_opened: Boolean + var magazine_size: float? + var reload_time: float? + var equipment_grid: LuaEquipmentGridPrototype? + var resistances: Record? + var inventory_size_bonus: uint? + var capsule_action: CapsuleAction? + var attack_parameters: dynamic /* ProjectileAttackParameters? | StreamAttackParameters? | OtherAttackParameters? */ + get() = definedExternally + set(value) = definedExternally + var inventory_size: uint? + var item_filters: Record + var item_group_filters: Record + var item_subgroup_filters: Record + var filter_mode: String + var insertion_priority_mode: String + var localised_filter_message: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var extend_inventory_by_default: Boolean + var default_label_color: ColorTable? + var draw_label_for_cursor_render: Boolean + var speed: float? + var module_effects: ModuleEffects? + var category: String + var tier: uint + var limitations: Array + var limitation_message_key: String + var straight_rail: LuaEntityPrototype + var curved_rail: LuaEntityPrototype + var repair_result: Array? + var selection_border_color: ColorTable + var alt_selection_border_color: ColorTable + var selection_mode_flags: SelectionModeFlags + var alt_selection_mode_flags: SelectionModeFlags + var selection_cursor_box_type: String + var alt_selection_cursor_box_type: String + var always_include_tiles: Boolean + var entity_filter_mode: String + var alt_entity_filter_mode: String + var tile_filter_mode: String + var alt_tile_filter_mode: String + var entity_filters: Record + var alt_entity_filters: Record + var entity_type_filters: Record + var alt_entity_type_filters: Record + var tile_filters: Record + var alt_tile_filters: Record + var entity_filter_slots: uint? + var tile_filter_slots: uint? + var durability_description_key: String + var durability: double? + var infinite: Boolean? + var mapper_count: uint? + var valid: Boolean + var object_name: String /* "LuaItemPrototype" */ + fun help(): String +} + +external interface `T$42` { + var surface: dynamic /* uint | String | LuaSurface */ + get() = definedExternally + set(value) = definedExternally + var force: dynamic /* String | LuaForce */ + get() = definedExternally + set(value) = definedExternally + var position: Position + var force_build: Boolean? + get() = definedExternally + set(value) = definedExternally + var direction: direction? + get() = definedExternally + set(value) = definedExternally + var skip_fog_of_war: Boolean? + get() = definedExternally + set(value) = definedExternally + var by_player: dynamic /* uint? | String? | LuaPlayer? */ + get() = definedExternally + set(value) = definedExternally + var raise_built: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$43` { + var surface: dynamic /* uint | String | LuaSurface */ + get() = definedExternally + set(value) = definedExternally + var force: dynamic /* String | LuaForce */ + get() = definedExternally + set(value) = definedExternally + var area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var skip_fog_of_war: Boolean? + get() = definedExternally + set(value) = definedExternally + var by_player: dynamic /* uint? | String? | LuaPlayer? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$44` { + var surface: dynamic /* uint | String | LuaSurface */ + get() = definedExternally + set(value) = definedExternally + var force: dynamic /* String | LuaForce */ + get() = definedExternally + set(value) = definedExternally + var area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var always_include_tiles: Boolean? + get() = definedExternally + set(value) = definedExternally + var include_entities: Boolean? + get() = definedExternally + set(value) = definedExternally + var include_modules: Boolean? + get() = definedExternally + set(value) = definedExternally + var include_station_names: Boolean? + get() = definedExternally + set(value) = definedExternally + var include_trains: Boolean? + get() = definedExternally + set(value) = definedExternally + var include_fuel: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface LuaItemStack { + fun is_blueprint_setup(): Boolean + fun get_blueprint_entities(): Array + fun set_blueprint_entities(entities: Array) + fun add_ammo(amount: float) + fun drain_ammo(amount: float) + fun add_durability(amount: double) + fun drain_durability(amount: double) + fun can_set_stack(stack: String = definedExternally): Boolean + fun can_set_stack(): Boolean + fun can_set_stack(stack: ItemStackDefinition = definedExternally): Boolean + fun can_set_stack(stack: LuaItemStack = definedExternally): Boolean + fun set_stack(stack: String = definedExternally): Boolean + fun set_stack(): Boolean + fun set_stack(stack: ItemStackDefinition = definedExternally): Boolean + fun set_stack(stack: LuaItemStack = definedExternally): Boolean + fun transfer_stack(stack: String): Boolean + fun transfer_stack(stack: ItemStackDefinition): Boolean + fun transfer_stack(stack: LuaItemStack): Boolean + fun export_stack(): String + fun import_stack(data: String): int + fun swap_stack(stack: LuaItemStack): Boolean + fun clear() + fun get_blueprint_tiles(): Array + fun set_blueprint_tiles(tiles: Array) + fun get_inventory(inventory: inventory): LuaInventory? + fun build_blueprint(params: `T$42`): Array + fun deconstruct_area(params: `T$43`) + fun cancel_deconstruct_area(params: `T$43`) + fun create_blueprint(params: `T$44`): Record + fun get_tag(tag_name: String): dynamic /* String? | Number? | Boolean? | table? */ + fun set_tag(tag_name: String, tag: String): dynamic /* String | Number | Boolean | table */ + fun set_tag(tag_name: String, tag: Number): dynamic /* String | Number | Boolean | table */ + fun set_tag(tag_name: String, tag: Boolean): dynamic /* String | Number | Boolean | table */ + fun set_tag(tag_name: String, tag: table): dynamic /* String | Number | Boolean | table */ + fun remove_tag(tag: String): Boolean + fun clear_blueprint() + fun get_entity_filter(index: uint): String + fun set_entity_filter(index: uint, filter: String?): Boolean + fun set_entity_filter(index: uint, filter: LuaEntityPrototype?): Boolean + fun set_entity_filter(index: uint, filter: LuaEntity?): Boolean + fun get_tile_filter(index: uint): String + fun set_tile_filter(index: uint, filter: String?): Boolean + fun set_tile_filter(index: uint, filter: LuaTilePrototype?): Boolean + fun set_tile_filter(index: uint, filter: LuaTile?): Boolean + fun clear_deconstruction_item() + fun clear_upgrade_item() + fun get_mapper(index: uint, type: String /* "from" | "to" */): UpgradeFilter + fun set_mapper(index: uint, type: String, filter: UpgradeFilter?) + fun get_blueprint_entity_count(): uint + fun get_blueprint_entity_tags(index: uint): Tags + fun set_blueprint_entity_tags(index: uint, tags: Tags) + fun get_blueprint_entity_tag(index: uint, tag: String): dynamic /* String | Number | Boolean | table */ + fun set_blueprint_entity_tag(index: uint, tag: String, value: String?) + fun set_blueprint_entity_tag(index: uint, tag: String, value: Number?) + fun set_blueprint_entity_tag(index: uint, tag: String, value: Boolean?) + fun set_blueprint_entity_tag(index: uint, tag: String, value: table?) + fun create_grid(): LuaEquipmentGrid + var valid_for_read: Boolean + var prototype: LuaItemPrototype + var name: String + var type: String + var count: uint + var grid: LuaEquipmentGrid? + var health: float + var durability: double? + var ammo: uint + var blueprint_icons: Array? + var blueprint_snap_to_grid: Position? + var blueprint_position_relative_to_grid: Position? + var blueprint_absolute_snapping: Boolean + var label: String? + var label_color: dynamic /* ColorTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var allow_manual_label_change: Boolean + var cost_to_build: Record + var extends_inventory: Boolean + var prioritize_insertion_mode: String + var default_icons: Array + var tags: Tags + var custom_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var entity_filters: Array + var tile_filters: Array + var entity_filter_mode: entity_filter_mode + var tile_filter_mode: tile_filter_mode + var tile_selection_mode: tile_selection_mode + var trees_and_rocks_only: Boolean + var entity_filter_count: uint + var tile_filter_count: uint + var active_index: uint? + var item_number: uint? + var connected_entity: LuaEntity? + var is_blueprint: Boolean + var is_blueprint_book: Boolean + var is_module: Boolean + var is_tool: Boolean + var is_mining_tool: Boolean + var is_armor: Boolean + var is_repair_tool: Boolean + var is_item_with_label: Boolean + var is_item_with_inventory: Boolean + var is_item_with_entity_data: Boolean + var is_selection_tool: Boolean + var is_item_with_tags: Boolean + var is_deconstruction_item: Boolean + var is_upgrade_item: Boolean + var valid: Boolean + var object_name: String /* "LuaItemStack" */ + fun help(): String +} + +external interface LuaLampControlBehavior : LuaGenericOnOffControlBehavior { + var use_colors: Boolean + var color: ColorTable? + override var valid: Boolean + override var object_name: String /* "LuaLampControlBehavior" */ + override fun help(): String +} + +external interface LuaLazyLoadedValue { + fun get(): T + var valid: Boolean + var object_name: String /* "LuaLazyLoadedValue" */ + fun help(): String +} + +external interface LuaLogisticCell { + fun is_in_logistic_range(position: Position): Boolean + fun is_in_construction_range(position: Position): Boolean + fun is_neighbour_with(other: LuaLogisticCell): Boolean + var logistic_radius: float + var logistics_connection_distance: float + var construction_radius: float + var stationed_logistic_robot_count: uint + var stationed_construction_robot_count: uint + var mobile: Boolean + var transmitting: Boolean + var charge_approach_distance: float + var charging_robot_count: uint + var to_charge_robot_count: uint + var owner: LuaEntity + var logistic_network: LuaLogisticNetwork? + var neighbours: Array + var charging_robots: Array + var to_charge_robots: Array + var valid: Boolean + var object_name: String /* "LuaLogisticCell" */ + fun help(): String +} + +external interface LuaLogisticContainerControlBehavior : LuaControlBehavior { + var circuit_mode_of_operation: _defines_control_behavior_logistic_container_circuit_mode_of_operation + var valid: Boolean + var object_name: String /* "LuaLogisticContainerControlBehavior" */ + fun help(): String +} + +external interface `T$45` { + var name: String + var position: Position? + get() = definedExternally + set(value) = definedExternally + var include_buffers: Boolean? + get() = definedExternally + set(value) = definedExternally + var members: String? /* "storage" | "passive-provider" | "buffer" | "active-provider" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$46` { + var stack: dynamic /* String | ItemStackDefinition | LuaItemStack */ + get() = definedExternally + set(value) = definedExternally + var members: String? /* "storage" | "storage-empty" | "storage-empty-slot" | "requester" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface LuaLogisticNetwork { + fun get_item_count(item: String = definedExternally, member: String /* "storage" | "providers" */ = definedExternally): int + fun get_contents(): Record + fun remove_item(item: String, members: String /* "storage" | "passive-provider" | "buffer" | "active-provider" */ = definedExternally): uint + fun remove_item(item: String): uint + fun remove_item(item: ItemStackDefinition, members: String /* "storage" | "passive-provider" | "buffer" | "active-provider" */ = definedExternally): uint + fun remove_item(item: ItemStackDefinition): uint + fun remove_item(item: LuaItemStack, members: String /* "storage" | "passive-provider" | "buffer" | "active-provider" */ = definedExternally): uint + fun remove_item(item: LuaItemStack): uint + fun insert(item: String, members: String /* "storage" | "storage-empty" | "storage-empty-slot" | "requester" */ = definedExternally): uint + fun insert(item: String): uint + fun insert(item: ItemStackDefinition, members: String /* "storage" | "storage-empty" | "storage-empty-slot" | "requester" */ = definedExternally): uint + fun insert(item: ItemStackDefinition): uint + fun insert(item: LuaItemStack, members: String /* "storage" | "storage-empty" | "storage-empty-slot" | "requester" */ = definedExternally): uint + fun insert(item: LuaItemStack): uint + fun find_cell_closest_to(position: Position): LuaLogisticCell? + fun select_pickup_point(params: `T$45`): LuaLogisticPoint? + fun select_drop_point(params: `T$46`): LuaLogisticPoint? + var force: LuaForce + var available_logistic_robots: uint + var all_logistic_robots: uint + var available_construction_robots: uint + var all_construction_robots: uint + var robot_limit: uint + var cells: Array + var providers: Array + var empty_providers: Array + var requesters: Array + var storages: Array + var logistic_members: Array + var provider_points: Array + var passive_provider_points: Array + var active_provider_points: Array + var empty_provider_points: Array + var requester_points: Array + var storage_points: Array + var robots: Array + var construction_robots: Array + var logistic_robots: Array + var valid: Boolean + var object_name: String /* "LuaLogisticNetwork" */ + fun help(): String +} + +external interface LuaLogisticPoint { + var owner: LuaEntity + var logistic_network: LuaLogisticNetwork + var logistic_member_index: uint + var filters: Array? + var mode: logistic_mode + var force: LuaForce + var targeted_items_pickup: Record + var targeted_items_deliver: Record + var exact: Boolean + var valid: Boolean + var object_name: String /* "LuaLogisticPoint" */ + fun help(): String +} + +external interface LuaMiningDrillControlBehavior : LuaGenericOnOffControlBehavior { + var circuit_enable_disable: Boolean + var circuit_read_resources: Boolean + var resource_read_mode: resource_read_mode + var resource_read_targets: Array + override var valid: Boolean + override var object_name: String /* "LuaMiningDrillControlBehavior" */ + override fun help(): String +} + +external interface LuaModSettingPrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var mod: String + var setting_type: String + var default_value: dynamic /* Boolean | double | int | String */ + get() = definedExternally + set(value) = definedExternally + var minimum_value: dynamic /* double? | int? */ + get() = definedExternally + set(value) = definedExternally + var maximum_value: dynamic /* double? | int? */ + get() = definedExternally + set(value) = definedExternally + var allowed_values: dynamic /* Array? | Array? | Array? */ + get() = definedExternally + set(value) = definedExternally + var allow_blank: Boolean? + var auto_trim: Boolean? + var hidden: Boolean + var valid: Boolean + var object_name: String /* "LuaModSettingPrototype" */ + fun help(): String +} + +external interface LuaModuleCategoryPrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var valid: Boolean + var object_name: String /* "LuaModuleCategoryPrototype" */ + fun help(): String +} + +external interface LuaNamedNoiseExpression { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var intended_property: String + var expression: NoiseExpression + var valid: Boolean + var object_name: String /* "LuaNamedNoiseExpression" */ + fun help(): String +} + +external interface LuaNoiseLayerPrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var valid: Boolean + var object_name: String /* "LuaNoiseLayerPrototype" */ + fun help(): String +} + +external interface LuaParticlePrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var regular_trigger_effect: TriggerEffectItem + var ended_in_water_trigger_effect: TriggerEffectItem + var render_layer: dynamic /* Number | */ + get() = definedExternally + set(value) = definedExternally + var render_layer_when_on_ground: dynamic /* Number | */ + get() = definedExternally + set(value) = definedExternally + var life_time: uint + var regular_trigger_effect_frequency: uint + var movement_modifier_when_on_ground: float + var movement_modifier: float + var mining_particle_frame_speed: float + var valid: Boolean + var object_name: String /* "LuaParticlePrototype" */ + fun help(): String +} + +external interface LuaPermissionGroup { + fun add_player(player: uint): Boolean + fun add_player(player: String): Boolean + fun add_player(player: LuaPlayer): Boolean + fun remove_player(player: uint): Boolean + fun remove_player(player: String): Boolean + fun remove_player(player: LuaPlayer): Boolean + fun allows_action(action: input_action): Boolean + fun set_allows_action(action: input_action, allow_action: Boolean): Boolean + fun destroy(): Boolean + var name: String + var players: Array + var group_id: uint + var valid: Boolean + var object_name: String /* "LuaPermissionGroup" */ + fun help(): String +} + +external interface LuaPermissionGroups { + fun create_group(name: String = definedExternally): LuaPermissionGroup? + fun get_group(group: String): LuaPermissionGroup? + fun get_group(group: uint): LuaPermissionGroup? + var groups: Array + var valid: Boolean + var object_name: String /* "LuaPermissionGroups" */ + fun help(): String +} + +external interface `T$47` { + var type: controllers + var character: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var waypoints: CutsceneWaypoint? + get() = definedExternally + set(value) = definedExternally + var start_position: Position? + get() = definedExternally + set(value) = definedExternally + var start_zoom: double? + get() = definedExternally + set(value) = definedExternally + var final_transition_time: uint? + get() = definedExternally + set(value) = definedExternally + var chart_mode_cutoff: double? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$48` { + var position: Position +} + +external interface `T$49` { + var entity: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var prototype: LuaEntityPrototype? + get() = definedExternally + set(value) = definedExternally + var position: Position? + get() = definedExternally + set(value) = definedExternally + var type: alert_type? + get() = definedExternally + set(value) = definedExternally + var surface: dynamic /* uint? | String? | LuaSurface? */ + get() = definedExternally + set(value) = definedExternally + var icon: SignalID? + get() = definedExternally + set(value) = definedExternally + var message: dynamic /* JsTuple | String? | Number? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$50` { + var entity: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var prototype: LuaEntityPrototype? + get() = definedExternally + set(value) = definedExternally + var position: Position? + get() = definedExternally + set(value) = definedExternally + var type: alert_type? + get() = definedExternally + set(value) = definedExternally + var surface: dynamic /* uint? | String? | LuaSurface? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$51` { + var name: String + var position: Position + var direction: direction? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$52` { + var position: Position + var direction: direction? + get() = definedExternally + set(value) = definedExternally + var alt: Boolean? + get() = definedExternally + set(value) = definedExternally + var terrain_building_size: uint? + get() = definedExternally + set(value) = definedExternally + var skip_fog_of_war: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$53` { + var text: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var position: Position? + get() = definedExternally + set(value) = definedExternally + var create_at_cursor: Boolean? + get() = definedExternally + set(value) = definedExternally + var color: dynamic /* ColorTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var time_to_live: uint? + get() = definedExternally + set(value) = definedExternally + var speed: double? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$54` { + var address: String + var name: dynamic /* JsTuple | String? | Number? */ + get() = definedExternally + set(value) = definedExternally + var description: dynamic /* JsTuple | String? | Number? */ + get() = definedExternally + set(value) = definedExternally + var password: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface LuaPlayer : LuaControl { + fun set_ending_screen_data(message: Any /* JsTuple */, file: String = definedExternally) + fun set_ending_screen_data(message: Any /* JsTuple */) + fun set_ending_screen_data(message: String, file: String = definedExternally) + fun set_ending_screen_data(message: String) + fun set_ending_screen_data(message: Number, file: String = definedExternally) + fun set_ending_screen_data(message: Number) + fun print(message: Any /* JsTuple */, color: ColorTable = definedExternally) + fun print(message: Any /* JsTuple */) + fun print(message: Any /* JsTuple */, color: Any /* JsTuple */ = definedExternally) + fun print(message: String, color: ColorTable = definedExternally) + fun print(message: String) + fun print(message: String, color: Any /* JsTuple */ = definedExternally) + fun print(message: Number, color: ColorTable = definedExternally) + fun print(message: Number) + fun print(message: Number, color: Any /* JsTuple */ = definedExternally) + fun clear_console() + fun get_goal_description(): dynamic /* JsTuple | String | Number */ + fun set_goal_description(text: Any /* JsTuple */ = definedExternally, only_update: Boolean = definedExternally) + fun set_goal_description() + fun set_goal_description(text: Any /* JsTuple */ = definedExternally) + fun set_goal_description(text: String = definedExternally, only_update: Boolean = definedExternally) + fun set_goal_description(text: String = definedExternally) + fun set_goal_description(text: Number = definedExternally, only_update: Boolean = definedExternally) + fun set_goal_description(text: Number = definedExternally) + fun set_controller(params: `T$47`) + fun drag_wire(params: `T$48`): Boolean + fun disable_recipe_groups() + fun enable_recipe_groups() + fun disable_recipe_subgroups() + fun enable_recipe_subgroups() + fun print_entity_statistics(entities: Array = definedExternally) + fun print_robot_jobs() + fun print_lua_object_statistics() + fun log_active_entity_chunk_counts() + fun log_active_entity_counts() + fun unlock_achievement(name: String) + fun clear_cursor(): Boolean + fun create_character(character: String = definedExternally): Boolean + fun add_alert(entity: LuaEntity, type: alert_type) + fun add_custom_alert(entity: LuaEntity, icon: SignalID, message: Any /* JsTuple */, show_on_map: Boolean) + fun add_custom_alert(entity: LuaEntity, icon: SignalID, message: String, show_on_map: Boolean) + fun add_custom_alert(entity: LuaEntity, icon: SignalID, message: Number, show_on_map: Boolean) + fun remove_alert(params: `T$49`) + fun get_alerts(params: `T$50`): Record>> + fun mute_alert(alert_type: alert_type): Boolean + fun unmute_alert(alert_type: alert_type): Boolean + fun is_alert_muted(alert_type: alert_type): Boolean + fun enable_alert(alert_type: alert_type): Boolean + fun disable_alert(alert_type: alert_type): Boolean + fun is_alert_enabled(alert_type: alert_type): Boolean + fun pipette_entity(entity: String): Boolean + fun pipette_entity(entity: LuaEntity): Boolean + fun pipette_entity(entity: LuaEntityPrototype): Boolean + fun can_place_entity(params: `T$51`): Boolean + fun can_build_from_cursor(params: `T$52`): Boolean + fun build_from_cursor(params: `T$52`) + fun use_from_cursor(position: Position) + fun play_sound(params: `T$34`) + fun get_associated_characters(): Array + fun associate_character(character: LuaEntity) + fun disassociate_character(character: LuaEntity) + fun create_local_flying_text(params: `T$53`) + fun get_quick_bar_slot(index: uint): LuaItemPrototype? + fun set_quick_bar_slot(index: uint, filter: String?) + fun set_quick_bar_slot(index: uint, filter: LuaItemPrototype?) + fun set_quick_bar_slot(index: uint, filter: LuaItemStack?) + fun get_active_quick_bar_page(index: uint): uint8? + fun set_active_quick_bar_page(screen_index: uint, page_index: uint) + fun jump_to_cutscene_waypoint(waypoint_index: uint) + fun exit_cutscene() + fun open_map(position: Position, scale: double = definedExternally) + fun zoom_to_world(position: Position, scale: double = definedExternally) + fun close_map() + fun is_shortcut_toggled(prototype_name: String): Boolean + fun is_shortcut_available(prototype_name: String): Boolean + fun set_shortcut_toggled(prototype_name: String, toggled: Boolean) + fun set_shortcut_available(prototype_name: String, available: Boolean) + fun connect_to_server(params: `T$54`) + fun toggle_map_editor() + fun request_translation(localised_string: Any /* JsTuple */): Boolean + fun request_translation(localised_string: String): Boolean + fun request_translation(localised_string: Number): Boolean + fun get_infinity_inventory_filter(index: uint): InfinityInventoryFilter? + fun set_infinity_inventory_filter(index: uint, filter: InfinityInventoryFilter?) + fun clear_recipe_notifications() + fun add_recipe_notification(recipe: String) + fun add_to_clipboard(blueprint: LuaItemStack) + fun activate_paste() + fun start_selection(position: Position, selection_mode: String) + fun clear_selection() + var character: LuaEntity? + var cutscene_character: LuaEntity? + var index: uint + var gui: LuaGui + var opened_self: Boolean + var controller_type: controllers + var stashed_controller_type: controllers? + var game_view_settings: GameViewSettings + var minimap_enabled: Boolean + var color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var chat_color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var name: String + var tag: String + var connected: Boolean + var admin: Boolean + var entity_copy_source: LuaEntity? + var afk_time: uint + var online_time: uint + var last_online: uint + var permission_group: LuaPermissionGroup? + var mod_settings: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var ticks_to_respawn: uint? + var display_resolution: DisplayResolution + var display_scale: double + var blueprint_to_setup: LuaItemStack + var render_mode: render_mode + var spectator: Boolean + var remove_unfiltered_items: Boolean + var infinity_inventory_filters: Array + var auto_sort_main_inventory: Boolean + var hand_location: ItemStackLocation +} + +external interface LuaProfiler { + fun reset() + fun stop() + fun restart() + fun add(other: LuaProfiler) + fun divide(number: double) + var valid: Boolean + var object_name: String /* "LuaProfiler" */ + fun help(): String +} + +external interface LuaProgrammableSpeakerControlBehavior : LuaControlBehavior { + var circuit_parameters: ProgrammableSpeakerCircuitParameters + var circuit_condition: CircuitConditionDefinition + var valid: Boolean + var object_name: String /* "LuaProgrammableSpeakerControlBehavior" */ + fun help(): String +} + +external interface LuaRCON { + fun print(message: Any /* JsTuple */) + fun print(message: String) + fun print(message: Number) + var object_name: String /* "LuaRCON" */ +} + +external interface LuaRailChainSignalControlBehavior : LuaControlBehavior { + var red_signal: SignalID + var orange_signal: SignalID + var green_signal: SignalID + var blue_signal: SignalID + var valid: Boolean + var object_name: String /* "LuaRailChainSignalControlBehavior" */ + fun help(): String +} + +external interface LuaRailPath { + var size: uint + var current: uint + var total_distance: double + var travelled_distance: double + var rails: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var valid: Boolean + var object_name: String /* "LuaRailPath" */ + fun help(): String +} + +external interface LuaRailSignalControlBehavior : LuaControlBehavior { + var red_signal: SignalID + var orange_signal: SignalID + var green_signal: SignalID + var close_signal: Boolean + var read_signal: Boolean + var circuit_condition: CircuitConditionDefinition + var valid: Boolean + var object_name: String /* "LuaRailSignalControlBehavior" */ + fun help(): String +} + +external interface LuaRandomGenerator { + fun re_seed(seed: uint) + @nativeInvoke + operator fun invoke(lower: int = definedExternally, upper: int = definedExternally): double + var valid: Boolean + var object_name: String /* "LuaRandomGenerator" */ + fun help(): String +} + +external interface LuaRecipe { + fun reload() + var name: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var prototype: LuaRecipePrototype + var enabled: Boolean + var category: String + var ingredients: Array + var products: Array + var hidden: Boolean + var hidden_from_flow_stats: Boolean + var energy: double + var order: String + var group: LuaGroup + var subgroup: LuaGroup + var force: LuaForce + var valid: Boolean + var object_name: String /* "LuaRecipe" */ + fun help(): String +} + +external interface LuaRecipeCategoryPrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var valid: Boolean + var object_name: String /* "LuaRecipeCategoryPrototype" */ + fun help(): String +} + +external interface LuaRecipePrototype { + var enabled: Boolean + var name: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var category: String + var ingredients: Array + var products: Array + var main_product: dynamic /* FluidProduct? | OtherProduct? */ + get() = definedExternally + set(value) = definedExternally + var hidden: Boolean + var hidden_from_flow_stats: Boolean + var hidden_from_player_crafting: Boolean + var always_show_made_in: Boolean + var energy: double + var order: String + var group: LuaGroup + var subgroup: LuaGroup + var request_paste_multiplier: uint + var overload_multiplier: uint + var allow_inserter_overload: Boolean + var allow_as_intermediate: Boolean + var allow_intermediates: Boolean + var show_amount_in_title: Boolean + var always_show_products: Boolean + var emissions_multiplier: double + var allow_decomposition: Boolean + var unlock_results: Boolean + var valid: Boolean + var object_name: String /* "LuaRecipePrototype" */ + fun help(): String +} + +external interface LuaRemote { + fun add_interface(name: String, functions: Record Unit>) + fun remove_interface(name: String): Boolean + fun call(_interface: String, _function: String, vararg args: Any): Any + var interfaces: Record> + var object_name: String /* "LuaRemote" */ +} + +external interface `T$55` { + var color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var width: float + var gap_length: double? + get() = definedExternally + set(value) = definedExternally + var dash_length: double? + get() = definedExternally + set(value) = definedExternally + var from: dynamic /* Position | LuaEntity */ + get() = definedExternally + set(value) = definedExternally + var from_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var to: dynamic /* Position | LuaEntity */ + get() = definedExternally + set(value) = definedExternally + var to_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var surface: dynamic /* uint | String | LuaSurface */ + get() = definedExternally + set(value) = definedExternally + var time_to_live: uint? + get() = definedExternally + set(value) = definedExternally + var forces: Array? + get() = definedExternally + set(value) = definedExternally + var players: Array? + get() = definedExternally + set(value) = definedExternally + var visible: Boolean? + get() = definedExternally + set(value) = definedExternally + var draw_on_ground: Boolean? + get() = definedExternally + set(value) = definedExternally + var only_in_alt_mode: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$56` { + var text: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var surface: dynamic /* uint | String | LuaSurface */ + get() = definedExternally + set(value) = definedExternally + var target: dynamic /* Position | LuaEntity */ + get() = definedExternally + set(value) = definedExternally + var target_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var scale: double? + get() = definedExternally + set(value) = definedExternally + var font: String? + get() = definedExternally + set(value) = definedExternally + var time_to_live: uint? + get() = definedExternally + set(value) = definedExternally + var forces: Array? + get() = definedExternally + set(value) = definedExternally + var players: Array? + get() = definedExternally + set(value) = definedExternally + var visible: Boolean? + get() = definedExternally + set(value) = definedExternally + var draw_on_ground: Boolean? + get() = definedExternally + set(value) = definedExternally + var orientation: RealOrientation? + get() = definedExternally + set(value) = definedExternally + var alignment: String? /* "left" | "right" | "center" */ + get() = definedExternally + set(value) = definedExternally + var vertical_alignment: String? /* "top" | "middle" | "baseline" | "bottom" */ + get() = definedExternally + set(value) = definedExternally + var scale_with_zoom: Boolean? + get() = definedExternally + set(value) = definedExternally + var only_in_alt_mode: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$57` { + var color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var radius: double + var width: float? + get() = definedExternally + set(value) = definedExternally + var filled: Boolean + var target: dynamic /* Position | LuaEntity */ + get() = definedExternally + set(value) = definedExternally + var target_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var surface: dynamic /* uint | String | LuaSurface */ + get() = definedExternally + set(value) = definedExternally + var time_to_live: uint? + get() = definedExternally + set(value) = definedExternally + var forces: Array? + get() = definedExternally + set(value) = definedExternally + var players: Array? + get() = definedExternally + set(value) = definedExternally + var visible: Boolean? + get() = definedExternally + set(value) = definedExternally + var draw_on_ground: Boolean? + get() = definedExternally + set(value) = definedExternally + var only_in_alt_mode: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$58` { + var color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var width: float? + get() = definedExternally + set(value) = definedExternally + var filled: Boolean + var left_top: dynamic /* Position | LuaEntity */ + get() = definedExternally + set(value) = definedExternally + var left_top_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var right_bottom: dynamic /* Position | LuaEntity */ + get() = definedExternally + set(value) = definedExternally + var right_bottom_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var surface: dynamic /* uint | String | LuaSurface */ + get() = definedExternally + set(value) = definedExternally + var time_to_live: uint? + get() = definedExternally + set(value) = definedExternally + var forces: Array? + get() = definedExternally + set(value) = definedExternally + var players: Array? + get() = definedExternally + set(value) = definedExternally + var visible: Boolean? + get() = definedExternally + set(value) = definedExternally + var draw_on_ground: Boolean? + get() = definedExternally + set(value) = definedExternally + var only_in_alt_mode: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$59` { + var color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var max_radius: double + var min_radius: double + var start_angle: float + var angle: float + var target: dynamic /* Position | LuaEntity */ + get() = definedExternally + set(value) = definedExternally + var target_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var surface: dynamic /* uint | String | LuaSurface */ + get() = definedExternally + set(value) = definedExternally + var time_to_live: uint? + get() = definedExternally + set(value) = definedExternally + var forces: Array? + get() = definedExternally + set(value) = definedExternally + var players: Array? + get() = definedExternally + set(value) = definedExternally + var visible: Boolean? + get() = definedExternally + set(value) = definedExternally + var draw_on_ground: Boolean? + get() = definedExternally + set(value) = definedExternally + var only_in_alt_mode: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$60` { + var color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var vertices: Array + var target: dynamic /* Position? | LuaEntity? */ + get() = definedExternally + set(value) = definedExternally + var target_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var orientation: RealOrientation? + get() = definedExternally + set(value) = definedExternally + var orientation_target: dynamic /* Position? | LuaEntity? */ + get() = definedExternally + set(value) = definedExternally + var orientation_target_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var surface: dynamic /* uint | String | LuaSurface */ + get() = definedExternally + set(value) = definedExternally + var time_to_live: uint? + get() = definedExternally + set(value) = definedExternally + var forces: Array? + get() = definedExternally + set(value) = definedExternally + var players: Array? + get() = definedExternally + set(value) = definedExternally + var visible: Boolean? + get() = definedExternally + set(value) = definedExternally + var draw_on_ground: Boolean? + get() = definedExternally + set(value) = definedExternally + var only_in_alt_mode: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$61` { + var sprite: dynamic /* String | */ + get() = definedExternally + set(value) = definedExternally + var orientation: RealOrientation? + get() = definedExternally + set(value) = definedExternally + var x_scale: double? + get() = definedExternally + set(value) = definedExternally + var y_scale: double? + get() = definedExternally + set(value) = definedExternally + var tint: dynamic /* ColorTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var render_layer: dynamic /* Number? | ? */ + get() = definedExternally + set(value) = definedExternally + var orientation_target: dynamic /* Position? | LuaEntity? */ + get() = definedExternally + set(value) = definedExternally + var orientation_target_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var oriented_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var target: dynamic /* Position | LuaEntity */ + get() = definedExternally + set(value) = definedExternally + var target_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var surface: dynamic /* uint | String | LuaSurface */ + get() = definedExternally + set(value) = definedExternally + var time_to_live: uint? + get() = definedExternally + set(value) = definedExternally + var forces: Array? + get() = definedExternally + set(value) = definedExternally + var players: Array? + get() = definedExternally + set(value) = definedExternally + var visible: Boolean? + get() = definedExternally + set(value) = definedExternally + var only_in_alt_mode: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$62` { + var sprite: dynamic /* String | */ + get() = definedExternally + set(value) = definedExternally + var orientation: RealOrientation? + get() = definedExternally + set(value) = definedExternally + var scale: float? + get() = definedExternally + set(value) = definedExternally + var intensity: float? + get() = definedExternally + set(value) = definedExternally + var minimum_darkness: float? + get() = definedExternally + set(value) = definedExternally + var oriented: Boolean? + get() = definedExternally + set(value) = definedExternally + var color: dynamic /* ColorTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var target: dynamic /* Position | LuaEntity */ + get() = definedExternally + set(value) = definedExternally + var target_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var surface: dynamic /* uint | String | LuaSurface */ + get() = definedExternally + set(value) = definedExternally + var time_to_live: uint? + get() = definedExternally + set(value) = definedExternally + var forces: Array? + get() = definedExternally + set(value) = definedExternally + var players: Array? + get() = definedExternally + set(value) = definedExternally + var visible: Boolean? + get() = definedExternally + set(value) = definedExternally + var only_in_alt_mode: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$63` { + var animation: String + var orientation: RealOrientation? + get() = definedExternally + set(value) = definedExternally + var x_scale: double? + get() = definedExternally + set(value) = definedExternally + var y_scale: double? + get() = definedExternally + set(value) = definedExternally + var tint: dynamic /* ColorTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var render_layer: dynamic /* Number? | ? */ + get() = definedExternally + set(value) = definedExternally + var animation_speed: double? + get() = definedExternally + set(value) = definedExternally + var animation_offset: double? + get() = definedExternally + set(value) = definedExternally + var orientation_target: dynamic /* Position? | LuaEntity? */ + get() = definedExternally + set(value) = definedExternally + var orientation_target_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var oriented_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var target: dynamic /* Position | LuaEntity */ + get() = definedExternally + set(value) = definedExternally + var target_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var surface: dynamic /* uint | String | LuaSurface */ + get() = definedExternally + set(value) = definedExternally + var time_to_live: uint? + get() = definedExternally + set(value) = definedExternally + var forces: Array? + get() = definedExternally + set(value) = definedExternally + var players: Array? + get() = definedExternally + set(value) = definedExternally + var visible: Boolean? + get() = definedExternally + set(value) = definedExternally + var only_in_alt_mode: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface LuaRendering { + fun draw_line(params: `T$55`): uint64 + fun draw_text(params: `T$56`): uint64 + fun draw_circle(params: `T$57`): uint64 + fun draw_rectangle(params: `T$58`): uint64 + fun draw_arc(params: `T$59`): uint64 + fun draw_polygon(params: `T$60`): uint64 + fun draw_sprite(params: `T$61`): uint64 + fun draw_light(params: `T$62`): uint64 + fun draw_animation(params: `T$63`): uint64 + fun destroy(id: uint64) + fun is_font_valid(font_name: String): Boolean + fun is_valid(id: uint64): Boolean + fun get_all_ids(mod_name: String = definedExternally): Array + fun clear(mod_name: String = definedExternally) + fun get_type(id: uint64): String /* "text" | "line" | "circle" | "rectangle" | "arc" | "polygon" | "sprite" | "light" | "animation" */ + fun bring_to_front(id: uint64) + fun get_surface(id: uint64): LuaSurface + fun get_time_to_live(id: uint64): uint + fun set_time_to_live(id: uint64, time_to_live: uint) + fun get_forces(id: uint64): Array? + fun set_forces(id: uint64, forces: Array) + fun get_players(id: uint64): Array? + fun set_players(id: uint64, players: Array) + fun get_visible(id: uint64): Boolean + fun set_visible(id: uint64, visible: Boolean) + fun get_draw_on_ground(id: uint64): Boolean + fun set_draw_on_ground(id: uint64, draw_on_ground: Boolean) + fun get_only_in_alt_mode(id: uint64): Boolean + fun set_only_in_alt_mode(id: uint64, only_in_alt_mode: Boolean) + fun get_color(id: uint64): ColorTable? + fun set_color(id: uint64, color: ColorTable) + fun set_color(id: uint64, color: Any /* JsTuple */) + fun get_width(id: uint64): float? + fun set_width(id: uint64, width: float) + fun get_from(id: uint64): ScriptRenderTarget? + fun set_from(id: uint64, from: Position, from_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) + fun set_from(id: uint64, from: Position) + fun set_from(id: uint64, from: LuaEntity, from_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) + fun set_from(id: uint64, from: LuaEntity) + fun get_to(id: uint64): ScriptRenderTarget? + fun set_to(id: uint64, to: Position, to_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) + fun set_to(id: uint64, to: Position) + fun set_to(id: uint64, to: LuaEntity, to_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) + fun set_to(id: uint64, to: LuaEntity) + fun get_dash_length(id: uint64): double? + fun set_dash_length(id: uint64, dash_length: double) + fun get_gap_length(id: uint64): double? + fun set_gap_length(id: uint64, gap_length: double) + fun set_dashes(id: uint64, dash_length: double, gap_length: double) + fun get_target(id: uint64): ScriptRenderTarget? + fun set_target(id: uint64, target: Position, target_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) + fun set_target(id: uint64, target: Position) + fun set_target(id: uint64, target: LuaEntity, target_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) + fun set_target(id: uint64, target: LuaEntity) + fun get_orientation(id: uint64): RealOrientation? + fun set_orientation(id: uint64, orientation: RealOrientation) + fun get_scale(id: uint64): double? + fun set_scale(id: uint64, scale: double) + fun get_text(id: uint64): dynamic /* JsTuple | String? | Number? */ + fun set_text(id: uint64, text: Any /* JsTuple */) + fun set_text(id: uint64, text: String) + fun set_text(id: uint64, text: Number) + fun get_font(id: uint64): String? + fun set_font(id: uint64, font: String) + fun get_alignment(id: uint64): String? + fun set_alignment(id: uint64, alignment: String /* "left" | "right" | "center" */) + fun get_vertical_alignment(id: uint64): String? + fun set_vertical_alignment(id: uint64, alignment: String /* "top" | "middle" | "baseline" | "bottom" */) + fun get_scale_with_zoom(id: uint64): Boolean? + fun set_scale_with_zoom(id: uint64, scale_with_zoom: Boolean) + fun get_filled(id: uint64): Boolean? + fun set_filled(id: uint64, filled: Boolean) + fun get_radius(id: uint64): double? + fun set_radius(id: uint64, radius: double) + fun get_left_top(id: uint64): ScriptRenderTarget? + fun set_left_top(id: uint64, left_top: Position, left_top_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) + fun set_left_top(id: uint64, left_top: Position) + fun set_left_top(id: uint64, left_top: LuaEntity, left_top_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) + fun set_left_top(id: uint64, left_top: LuaEntity) + fun get_right_bottom(id: uint64): ScriptRenderTarget? + fun set_right_bottom(id: uint64, right_bottom: Position, right_bottom_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) + fun set_right_bottom(id: uint64, right_bottom: Position) + fun set_right_bottom(id: uint64, right_bottom: LuaEntity, right_bottom_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) + fun set_right_bottom(id: uint64, right_bottom: LuaEntity) + fun set_corners(id: uint64, left_top: Position, left_top_offset: dynamic /* typealias Vector = dynamic */, right_bottom: Position, right_bottom_offset: dynamic /* typealias Vector = dynamic */) + fun set_corners(id: uint64, left_top: Position, left_top_offset: dynamic /* typealias Vector = dynamic */, right_bottom: LuaEntity, right_bottom_offset: dynamic /* typealias Vector = dynamic */) + fun set_corners(id: uint64, left_top: LuaEntity, left_top_offset: dynamic /* typealias Vector = dynamic */, right_bottom: Position, right_bottom_offset: dynamic /* typealias Vector = dynamic */) + fun set_corners(id: uint64, left_top: LuaEntity, left_top_offset: dynamic /* typealias Vector = dynamic */, right_bottom: LuaEntity, right_bottom_offset: dynamic /* typealias Vector = dynamic */) + fun get_max_radius(id: uint64): double? + fun set_max_radius(id: uint64, max_radius: double) + fun get_min_radius(id: uint64): double? + fun set_min_radius(id: uint64, min_radius: double) + fun get_start_angle(id: uint64): float? + fun set_start_angle(id: uint64, start_angle: float) + fun get_angle(id: uint64): float? + fun set_angle(id: uint64, angle: float) + fun get_vertices(id: uint64): Array? + fun set_vertices(id: uint64, vertices: Array) + fun get_sprite(id: uint64): dynamic /* String? | ? */ + fun set_sprite(id: uint64, sprite: String) + fun set_sprite(id: uint64, sprite: ) + fun get_x_scale(id: uint64): double? + fun set_x_scale(id: uint64, x_scale: double) + fun get_y_scale(id: uint64): double? + fun set_y_scale(id: uint64, y_scale: double) + fun get_render_layer(id: uint64): dynamic /* Number? | ? */ + fun set_render_layer(id: uint64, render_layer: Number) + fun set_render_layer(id: uint64, render_layer: ) + fun get_orientation_target(id: uint64): ScriptRenderTarget? + fun set_orientation_target(id: uint64, orientation_target: Position, orientation_target_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) + fun set_orientation_target(id: uint64, orientation_target: Position) + fun set_orientation_target(id: uint64, orientation_target: LuaEntity, orientation_target_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) + fun set_orientation_target(id: uint64, orientation_target: LuaEntity) + fun get_oriented_offset(id: uint64): dynamic /* typealias Vector = dynamic */ + fun set_oriented_offset(id: uint64, oriented_offset: dynamic /* typealias Vector = dynamic */) + fun get_intensity(id: uint64): float? + fun set_intensity(id: uint64, intensity: float) + fun get_minimum_darkness(id: uint64): float? + fun set_minimum_darkness(id: uint64, minimum_darkness: float) + fun get_oriented(id: uint64): Boolean? + fun set_oriented(id: uint64, oriented: Boolean) + fun get_animation(id: uint64): String? + fun set_animation(id: uint64, animation: String) + fun get_animation_speed(id: uint64): double? + fun set_animation_speed(id: uint64, animation_speed: double) + fun get_animation_offset(id: uint64): double? + fun set_animation_offset(id: uint64, animation_offset: double) + var object_name: String /* "LuaRendering" */ +} + +external interface LuaResourceCategoryPrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var valid: Boolean + var object_name: String /* "LuaResourceCategoryPrototype" */ + fun help(): String +} + +external interface LuaRoboportControlBehavior : LuaControlBehavior { + var read_logistics: Boolean + var read_robot_stats: Boolean + var available_logistic_output_signal: SignalID + var total_logistic_output_signal: SignalID + var available_construction_output_signal: SignalID + var total_construction_output_signal: SignalID + var valid: Boolean + var object_name: String /* "LuaRoboportControlBehavior" */ + fun help(): String +} + +external interface LuaSettings { + fun get_player_settings(player: uint): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + fun get_player_settings(player: String): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + fun get_player_settings(player: LuaPlayer): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var startup: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var global: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var player: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var object_name: String /* "LuaSettings" */ +} + +external interface LuaShortcutPrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var action: String + var item_to_spawn: LuaItemPrototype + var technology_to_unlock: LuaTechnologyPrototype + var toggleable: Boolean + var associated_control_input: String + var valid: Boolean + var object_name: String /* "LuaShortcutPrototype" */ + fun help(): String +} + +external interface LuaStorageTankControlBehavior : LuaControlBehavior { + var valid: Boolean + var object_name: String /* "LuaStorageTankControlBehavior" */ + fun help(): String +} + +external interface LuaStyle { + var gui: LuaGui + var name: String + var minimal_width: int + var maximal_width: int + var minimal_height: int + var maximal_height: int + var natural_width: int + var natural_height: int + var top_padding: int + var right_padding: int + var bottom_padding: int + var left_padding: int + var top_margin: int + var right_margin: int + var bottom_margin: int + var left_margin: int + var horizontal_align: String /* "left" | "center" | "right" */ + var vertical_align: String /* "top" | "center" | "bottom" */ + var font_color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var font: String + var top_cell_padding: int + var right_cell_padding: int + var bottom_cell_padding: int + var left_cell_padding: int + var horizontally_stretchable: Boolean + var vertically_stretchable: Boolean + var horizontally_squashable: Boolean + var vertically_squashable: Boolean + var rich_text_setting: rich_text_setting + var hovered_font_color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var clicked_font_color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var disabled_font_color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var pie_progress_color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var clicked_vertical_offset: int + var selected_font_color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var selected_hovered_font_color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var selected_clicked_font_color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var strikethrough_color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var horizontal_spacing: int + var vertical_spacing: int + var use_header_filler: Boolean + var color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var column_alignments: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ + var single_line: Boolean + var extra_top_padding_when_activated: int + var extra_bottom_padding_when_activated: int + var extra_left_padding_when_activated: int + var extra_right_padding_when_activated: int + var extra_top_margin_when_activated: int + var extra_bottom_margin_when_activated: int + var extra_left_margin_when_activated: int + var extra_right_margin_when_activated: int + var stretch_image_to_widget_size: Boolean + var badge_font: String + var badge_horizontal_spacing: int + var default_badge_font_color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var selected_badge_font_color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var disabled_badge_font_color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally +} + +external interface BaseSurfaceCreateEntity { + var name: String + var position: Position + var direction: direction? + get() = definedExternally + set(value) = definedExternally + var force: dynamic /* String? | LuaForce? */ + get() = definedExternally + set(value) = definedExternally + var target: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var source: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var fast_replace: Boolean? + get() = definedExternally + set(value) = definedExternally + var player: dynamic /* uint? | String? | LuaPlayer? */ + get() = definedExternally + set(value) = definedExternally + var spill: Boolean? + get() = definedExternally + set(value) = definedExternally + var raise_built: Boolean? + get() = definedExternally + set(value) = definedExternally + var create_build_effect_smoke: Boolean? + get() = definedExternally + set(value) = definedExternally + var spawn_decorations: Boolean? + get() = definedExternally + set(value) = definedExternally + var move_stuck_players: Boolean? + get() = definedExternally + set(value) = definedExternally + var item: LuaItemStack? + get() = definedExternally + set(value) = definedExternally +} + +external interface AssemblingMachineSurfaceCreateEntity : BaseSurfaceCreateEntity { + var recipe: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface BeamSurfaceCreateEntity : BaseSurfaceCreateEntity { + var target_position: Position? + get() = definedExternally + set(value) = definedExternally + var source_position: Position? + get() = definedExternally + set(value) = definedExternally + var max_length: uint? + get() = definedExternally + set(value) = definedExternally + var duration: uint? + get() = definedExternally + set(value) = definedExternally + var source_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ContainerSurfaceCreateEntity : BaseSurfaceCreateEntity { + var bar: uint? + get() = definedExternally + set(value) = definedExternally +} + +external interface CliffSurfaceCreateEntity : BaseSurfaceCreateEntity { + var cliff_orientation: String? /* "west-to-east" | "north-to-south" | "east-to-west" | "south-to-north" | "west-to-north" | "north-to-east" | "east-to-south" | "south-to-west" | "west-to-south" | "north-to-west" | "east-to-north" | "south-to-east" | "west-to-none" | "none-to-east" | "east-to-none" | "none-to-west" | "north-to-none" | "none-to-south" | "south-to-none" | "none-to-north" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlyingTextSurfaceCreateEntity : BaseSurfaceCreateEntity { + var text: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var color: dynamic /* ColorTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var render_player_index: uint? + get() = definedExternally + set(value) = definedExternally +} + +external interface EntityGhostSurfaceCreateEntity : BaseSurfaceCreateEntity { + var inner_name: String + var expires: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface FireSurfaceCreateEntity : BaseSurfaceCreateEntity { + var initial_ground_flame_count: uint8? + get() = definedExternally + set(value) = definedExternally +} + +external interface InserterSurfaceCreateEntity : BaseSurfaceCreateEntity { + var conditions: InserterCircuitConditions + var filters: Array +} + +external interface ItemEntitySurfaceCreateEntity : BaseSurfaceCreateEntity { + var stack: dynamic /* String | ItemStackDefinition */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ItemRequestProxySurfaceCreateEntity : BaseSurfaceCreateEntity { + var modules: Record +} + +external interface RollingStockSurfaceCreateEntity : BaseSurfaceCreateEntity { + var orientation: RealOrientation? + get() = definedExternally + set(value) = definedExternally + var color: dynamic /* ColorTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally +} + +external interface LocomotiveSurfaceCreateEntity : BaseSurfaceCreateEntity { + var snap_to_train_stop: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface LogisticContainerSurfaceCreateEntity : BaseSurfaceCreateEntity { + var request_filters: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface ParticleSurfaceCreateEntity : BaseSurfaceCreateEntity { + var movement: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var height: float + var vertical_speed: float + var frame_speed: float +} + +external interface ArtilleryFlareSurfaceCreateEntity : BaseSurfaceCreateEntity { + var movement: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var height: float + var vertical_speed: float + var frame_speed: float +} + +external interface ProjectileSurfaceCreateEntity : BaseSurfaceCreateEntity { + var speed: double + var max_range: double +} + +external interface ResourceSurfaceCreateEntity : BaseSurfaceCreateEntity { + var amount: uint + var enable_tree_removal: Boolean? + get() = definedExternally + set(value) = definedExternally + var enable_cliff_removal: Boolean? + get() = definedExternally + set(value) = definedExternally + var snap_to_tile_center: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface UndergroundBeltSurfaceCreateEntity : BaseSurfaceCreateEntity { + var type: String? /* "output" | "input" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ProgrammableSpeakerSurfaceCreateEntity : BaseSurfaceCreateEntity { + var parameters: ProgrammableSpeakerParameters? + get() = definedExternally + set(value) = definedExternally + var alert_parameters: ProgrammableSpeakerAlertParameters? + get() = definedExternally + set(value) = definedExternally +} + +external interface CharacterCorpseSurfaceCreateEntity : BaseSurfaceCreateEntity { + var inventory_size: uint? + get() = definedExternally + set(value) = definedExternally + var player_index: uint? + get() = definedExternally + set(value) = definedExternally +} + +external interface HighlightBoxSurfaceCreateEntity : BaseSurfaceCreateEntity { + var bounding_box: dynamic /* BoundingBoxTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var box_type: String? /* "entity" | "not-allowed" | "electricity" | "pair" | "copy" | "train-visualization" | "logistics" | "blueprint-snap-rectangle" */ + get() = definedExternally + set(value) = definedExternally + var render_player_index: uint? + get() = definedExternally + set(value) = definedExternally + var blink_interval: uint? + get() = definedExternally + set(value) = definedExternally + var time_to_live: uint? + get() = definedExternally + set(value) = definedExternally +} + +external interface SpeechBubbleSurfaceCreateEntity : BaseSurfaceCreateEntity { + var text: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var lifetime: uint? + get() = definedExternally + set(value) = definedExternally +} + +external interface SimpleEntityWithOwnerSurfaceCreateEntity : BaseSurfaceCreateEntity { + var render_player_index: uint? + get() = definedExternally + set(value) = definedExternally +} + +external interface SimpleEntityWithForceSurfaceCreateEntity : BaseSurfaceCreateEntity { + var render_player_index: uint? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$64` { + var name: String + var position: Position + var direction: direction? + get() = definedExternally + set(value) = definedExternally + var force: dynamic /* String? | LuaForce? */ + get() = definedExternally + set(value) = definedExternally + var build_check_type: build_check_type? + get() = definedExternally + set(value) = definedExternally + var forced: Boolean? + get() = definedExternally + set(value) = definedExternally + var inner_name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$65` { + var name: String + var position: Position + var direction: direction? + get() = definedExternally + set(value) = definedExternally + var force: dynamic /* String? | LuaForce? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$66` { + var area: dynamic /* BoundingBoxTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var position: Position? + get() = definedExternally + set(value) = definedExternally + var radius: double? + get() = definedExternally + set(value) = definedExternally + var name: dynamic /* String? | Array? */ + get() = definedExternally + set(value) = definedExternally + var type: dynamic /* String? | Array? */ + get() = definedExternally + set(value) = definedExternally + var ghost_name: dynamic /* String? | Array? */ + get() = definedExternally + set(value) = definedExternally + var ghost_type: dynamic /* String? | Array? */ + get() = definedExternally + set(value) = definedExternally + var direction: dynamic /* defines.direction? | Array? */ + get() = definedExternally + set(value) = definedExternally + var collision_mask: dynamic /* "ground-tile" | "water-tile" | "resource-layer" | "doodad-layer" | "floor-layer" | "item-layer" | "ghost-layer" | "object-layer" | "player-layer" | "train-layer" | "rail-layer" | "transport-belt-layer" | "not-setup" | ? | Array? */ + get() = definedExternally + set(value) = definedExternally + var force: dynamic /* String? | LuaForce? | Array? */ + get() = definedExternally + set(value) = definedExternally + var to_be_deconstructed: Boolean? + get() = definedExternally + set(value) = definedExternally + var to_be_upgraded: Boolean? + get() = definedExternally + set(value) = definedExternally + var limit: uint? + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$67` { + var area: dynamic /* BoundingBoxTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var position: Position? + get() = definedExternally + set(value) = definedExternally + var radius: double? + get() = definedExternally + set(value) = definedExternally + var name: dynamic /* String? | Array? */ + get() = definedExternally + set(value) = definedExternally + var limit: uint? + get() = definedExternally + set(value) = definedExternally + var has_hidden_tile: Boolean? + get() = definedExternally + set(value) = definedExternally + var collision_mask: dynamic /* "ground-tile" | "water-tile" | "resource-layer" | "doodad-layer" | "floor-layer" | "item-layer" | "ghost-layer" | "object-layer" | "player-layer" | "train-layer" | "rail-layer" | "transport-belt-layer" | "not-setup" | ? | Array? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$68` { + var area: dynamic /* BoundingBoxTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var position: Position? + get() = definedExternally + set(value) = definedExternally + var radius: double? + get() = definedExternally + set(value) = definedExternally + var name: dynamic /* String? | Array? */ + get() = definedExternally + set(value) = definedExternally + var type: dynamic /* String? | Array? */ + get() = definedExternally + set(value) = definedExternally + var ghost_name: dynamic /* String? | Array? */ + get() = definedExternally + set(value) = definedExternally + var ghost_type: dynamic /* String? | Array? */ + get() = definedExternally + set(value) = definedExternally + var direction: dynamic /* defines.direction? | Array? */ + get() = definedExternally + set(value) = definedExternally + var collision_mask: dynamic /* "ground-tile" | "water-tile" | "resource-layer" | "doodad-layer" | "floor-layer" | "item-layer" | "ghost-layer" | "object-layer" | "player-layer" | "train-layer" | "rail-layer" | "transport-belt-layer" | "not-setup" | ? | Array? */ + get() = definedExternally + set(value) = definedExternally + var force: dynamic /* String? | LuaForce? | Array? */ + get() = definedExternally + set(value) = definedExternally + var to_be_deconstructed: Boolean? + get() = definedExternally + set(value) = definedExternally + var to_be_upgraded: Boolean? + get() = definedExternally + set(value) = definedExternally + var limit: uint? + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$69` { + var area: dynamic /* BoundingBoxTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var position: Position? + get() = definedExternally + set(value) = definedExternally + var radius: double? + get() = definedExternally + set(value) = definedExternally + var name: dynamic /* String? | Array? */ + get() = definedExternally + set(value) = definedExternally + var limit: uint? + get() = definedExternally + set(value) = definedExternally + var has_hidden_tile: Boolean? + get() = definedExternally + set(value) = definedExternally + var collision_mask: dynamic /* "ground-tile" | "water-tile" | "resource-layer" | "doodad-layer" | "floor-layer" | "item-layer" | "ghost-layer" | "object-layer" | "player-layer" | "train-layer" | "rail-layer" | "transport-belt-layer" | "not-setup" | ? | Array? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$70` { + var area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var force: dynamic /* LuaForce | String */ + get() = definedExternally + set(value) = definedExternally + var condition: String /* "all" | "enemy" | "ally" | "friend" | "not-friend" | "same" | "not-same" */ +} + +external interface `T$71` { + var position: Position + var max_distance: double + var force: dynamic /* String? | LuaForce? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$72` { + var command: dynamic /* AttackCommand | GoToLocationCommand | CompoundCommand | GroupCommand | AttackAreaCommand | WanderCommand | StopCommand | FleeCommand | BuildBaseCommand */ + get() = definedExternally + set(value) = definedExternally + var unit_count: uint + var force: dynamic /* String? | LuaForce? */ + get() = definedExternally + set(value) = definedExternally + var unit_search_distance: uint? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$73` { + var name: String + var position: Position +} + +external interface `T$74` { + var name: String + var position: Position + var movement: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var height: float + var vertical_speed: float + var frame_speed: float +} + +external interface `T$75` { + var position: Position + var force: dynamic /* String? | LuaForce? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$76` { + var area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var force: dynamic /* String | LuaForce */ + get() = definedExternally + set(value) = definedExternally + var player: dynamic /* uint? | String? | LuaPlayer? */ + get() = definedExternally + set(value) = definedExternally + var skip_fog_of_war: Boolean? + get() = definedExternally + set(value) = definedExternally + var item: LuaItemStack? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$77` { + var area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var force: dynamic /* String | LuaForce */ + get() = definedExternally + set(value) = definedExternally + var player: dynamic /* uint? | String? | LuaPlayer? */ + get() = definedExternally + set(value) = definedExternally + var skip_fog_of_war: Boolean? + get() = definedExternally + set(value) = definedExternally + var item: LuaItemStack +} + +external interface `T$78` { + var area: dynamic /* BoundingBoxTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var position: dynamic /* TilePositionTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var name: dynamic /* String? | Array? | LuaDecorativePrototype? | Array? */ + get() = definedExternally + set(value) = definedExternally + var limit: uint? + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$79` { + var check_collision: Boolean? + get() = definedExternally + set(value) = definedExternally + var decoratives: Array +} + +external interface `T$80` { + var area: dynamic /* BoundingBoxTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var position: dynamic /* TilePositionTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var name: dynamic /* String? | Array? | LuaDecorativePrototype? | Array? */ + get() = definedExternally + set(value) = definedExternally + var limit: uint? + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$81` { + var source_area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var destination_area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var destination_surface: dynamic /* uint? | String? | LuaSurface? */ + get() = definedExternally + set(value) = definedExternally + var destination_force: dynamic /* LuaForce? | String? */ + get() = definedExternally + set(value) = definedExternally + var clone_tiles: Boolean? + get() = definedExternally + set(value) = definedExternally + var clone_entities: Boolean? + get() = definedExternally + set(value) = definedExternally + var clone_decoratives: Boolean? + get() = definedExternally + set(value) = definedExternally + var clear_destination_entities: Boolean? + get() = definedExternally + set(value) = definedExternally + var clear_destination_decoratives: Boolean? + get() = definedExternally + set(value) = definedExternally + var expand_map: Boolean? + get() = definedExternally + set(value) = definedExternally + var create_build_effect_smoke: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$82` { + var source_offset: dynamic /* TilePositionTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var destination_offset: dynamic /* TilePositionTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var source_positions: Array */> + var destination_surface: dynamic /* uint? | String? | LuaSurface? */ + get() = definedExternally + set(value) = definedExternally + var destination_force: dynamic /* LuaForce? | String? */ + get() = definedExternally + set(value) = definedExternally + var clone_tiles: Boolean? + get() = definedExternally + set(value) = definedExternally + var clone_entities: Boolean? + get() = definedExternally + set(value) = definedExternally + var clone_decoratives: Boolean? + get() = definedExternally + set(value) = definedExternally + var clear_destination_entities: Boolean? + get() = definedExternally + set(value) = definedExternally + var clear_destination_decoratives: Boolean? + get() = definedExternally + set(value) = definedExternally + var expand_map: Boolean? + get() = definedExternally + set(value) = definedExternally + var manual_collision_mode: Boolean? + get() = definedExternally + set(value) = definedExternally + var create_build_effect_smoke: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$83` { + var entities: Array + var destination_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var destination_surface: dynamic /* uint? | String? | LuaSurface? */ + get() = definedExternally + set(value) = definedExternally + var destination_force: dynamic /* String? | LuaForce? */ + get() = definedExternally + set(value) = definedExternally + var snap_to_grid: Boolean? + get() = definedExternally + set(value) = definedExternally + var create_build_effect_smoke: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$84` { + var bounding_box: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var collision_mask: dynamic /* CollisionMask | Array */ + get() = definedExternally + set(value) = definedExternally + var start: Position + var goal: Position + var force: dynamic /* String | LuaForce */ + get() = definedExternally + set(value) = definedExternally + var radius: double? + get() = definedExternally + set(value) = definedExternally + var pathfind_flags: PathfinderFlags? + get() = definedExternally + set(value) = definedExternally + var can_open_gates: Boolean? + get() = definedExternally + set(value) = definedExternally + var path_resolution_modifier: int? + get() = definedExternally + set(value) = definedExternally + var entity_to_ignore: LuaEntity? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$85` { + var name: dynamic /* String? | Array? */ + get() = definedExternally + set(value) = definedExternally + var force: dynamic /* String? | LuaForce? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface LuaSurface { + fun get_pollution(position: Position): double + fun can_place_entity(params: `T$64`): Boolean + fun can_fast_replace(params: `T$65`): Boolean + fun find_entity(entity: String, position: Position): LuaEntity? + fun find_entities(area: BoundingBoxTable = definedExternally): Array + fun find_entities(): Array + fun find_entities(area: Any /* JsTuple */ = definedExternally): Array + fun find_entities_filtered(params: `T$66`): Array + fun find_tiles_filtered(params: `T$67`): Array + fun count_entities_filtered(params: `T$68`): uint + fun count_tiles_filtered(params: `T$69`): uint + fun find_non_colliding_position(name: String, center: Position, radius: double, precision: double, force_to_tile_center: Boolean = definedExternally): PositionTable? + fun find_non_colliding_position_in_box(name: String, search_space: BoundingBoxTable, precision: double, force_to_tile_center: Boolean = definedExternally): PositionTable? + fun find_non_colliding_position_in_box(name: String, search_space: BoundingBoxTable, precision: double): PositionTable? + fun find_non_colliding_position_in_box(name: String, search_space: Any /* JsTuple */, precision: double, force_to_tile_center: Boolean = definedExternally): PositionTable? + fun find_non_colliding_position_in_box(name: String, search_space: Any /* JsTuple */, precision: double): PositionTable? + fun spill_item_stack(position: Position, items: String, enable_looted: Boolean = definedExternally, force: LuaForce = definedExternally, allow_belts: Boolean = definedExternally): Array + fun spill_item_stack(position: Position, items: String): Array + fun spill_item_stack(position: Position, items: String, enable_looted: Boolean = definedExternally): Array + fun spill_item_stack(position: Position, items: String, enable_looted: Boolean = definedExternally, force: LuaForce = definedExternally): Array + fun spill_item_stack(position: Position, items: String, enable_looted: Boolean = definedExternally, force: String = definedExternally, allow_belts: Boolean = definedExternally): Array + fun spill_item_stack(position: Position, items: String, enable_looted: Boolean = definedExternally, force: String = definedExternally): Array + fun spill_item_stack(position: Position, items: ItemStackDefinition, enable_looted: Boolean = definedExternally, force: LuaForce = definedExternally, allow_belts: Boolean = definedExternally): Array + fun spill_item_stack(position: Position, items: ItemStackDefinition): Array + fun spill_item_stack(position: Position, items: ItemStackDefinition, enable_looted: Boolean = definedExternally): Array + fun spill_item_stack(position: Position, items: ItemStackDefinition, enable_looted: Boolean = definedExternally, force: LuaForce = definedExternally): Array + fun spill_item_stack(position: Position, items: ItemStackDefinition, enable_looted: Boolean = definedExternally, force: String = definedExternally, allow_belts: Boolean = definedExternally): Array + fun spill_item_stack(position: Position, items: ItemStackDefinition, enable_looted: Boolean = definedExternally, force: String = definedExternally): Array + fun spill_item_stack(position: Position, items: LuaItemStack, enable_looted: Boolean = definedExternally, force: LuaForce = definedExternally, allow_belts: Boolean = definedExternally): Array + fun spill_item_stack(position: Position, items: LuaItemStack): Array + fun spill_item_stack(position: Position, items: LuaItemStack, enable_looted: Boolean = definedExternally): Array + fun spill_item_stack(position: Position, items: LuaItemStack, enable_looted: Boolean = definedExternally, force: LuaForce = definedExternally): Array + fun spill_item_stack(position: Position, items: LuaItemStack, enable_looted: Boolean = definedExternally, force: String = definedExternally, allow_belts: Boolean = definedExternally): Array + fun spill_item_stack(position: Position, items: LuaItemStack, enable_looted: Boolean = definedExternally, force: String = definedExternally): Array + fun find_enemy_units(center: Position, radius: double, force: LuaForce = definedExternally): Array + fun find_enemy_units(center: Position, radius: double): Array + fun find_enemy_units(center: Position, radius: double, force: String = definedExternally): Array + fun find_units(params: `T$70`): Array + fun find_nearest_enemy(params: `T$71`): LuaEntity? + fun find_nearest_enemy_entity_with_owner(params: `T$71`): LuaEntity? + fun set_multi_command(params: `T$72`): uint + fun create_entity(params: Any /* AssemblingMachineSurfaceCreateEntity | BeamSurfaceCreateEntity | ContainerSurfaceCreateEntity | CliffSurfaceCreateEntity | FlyingTextSurfaceCreateEntity | EntityGhostSurfaceCreateEntity | FireSurfaceCreateEntity | InserterSurfaceCreateEntity | ItemEntitySurfaceCreateEntity | ItemRequestProxySurfaceCreateEntity | RollingStockSurfaceCreateEntity | LocomotiveSurfaceCreateEntity | LogisticContainerSurfaceCreateEntity | ParticleSurfaceCreateEntity | ArtilleryFlareSurfaceCreateEntity | ProjectileSurfaceCreateEntity | ResourceSurfaceCreateEntity | UndergroundBeltSurfaceCreateEntity | ProgrammableSpeakerSurfaceCreateEntity | CharacterCorpseSurfaceCreateEntity | HighlightBoxSurfaceCreateEntity | SpeechBubbleSurfaceCreateEntity | SimpleEntityWithOwnerSurfaceCreateEntity | SimpleEntityWithForceSurfaceCreateEntity */): LuaEntity? + fun create_trivial_smoke(params: `T$73`) + fun create_particle(params: `T$74`) + fun create_unit_group(params: `T$75`): LuaUnitGroup + fun build_enemy_base(position: Position, unit_count: uint, force: String = definedExternally) + fun build_enemy_base(position: Position, unit_count: uint) + fun build_enemy_base(position: Position, unit_count: uint, force: LuaForce = definedExternally) + fun get_tile(x: int, y: int): LuaTile + fun set_tiles(tiles: Array, correct_tiles: Boolean = definedExternally, remove_colliding_entities: Boolean = definedExternally, remove_colliding_decoratives: Boolean = definedExternally, raise_event: Boolean = definedExternally) + fun set_tiles(tiles: Array) + fun set_tiles(tiles: Array, correct_tiles: Boolean = definedExternally) + fun set_tiles(tiles: Array, correct_tiles: Boolean = definedExternally, remove_colliding_entities: Boolean = definedExternally) + fun set_tiles(tiles: Array, correct_tiles: Boolean = definedExternally, remove_colliding_entities: Boolean = definedExternally, remove_colliding_decoratives: Boolean = definedExternally) + fun set_tiles(tiles: Array, correct_tiles: Boolean = definedExternally, remove_colliding_entities: String = definedExternally, remove_colliding_decoratives: Boolean = definedExternally, raise_event: Boolean = definedExternally) + fun set_tiles(tiles: Array, correct_tiles: Boolean = definedExternally, remove_colliding_entities: String = definedExternally) + fun set_tiles(tiles: Array, correct_tiles: Boolean = definedExternally, remove_colliding_entities: String = definedExternally, remove_colliding_decoratives: Boolean = definedExternally) + fun pollute(source: Position, amount: double) + fun get_chunks(): LuaChunkIterator + fun is_chunk_generated(position: ChunkPositionTable): Boolean + fun is_chunk_generated(position: Any /* JsTuple */): Boolean + fun request_to_generate_chunks(position: Position, radius: uint) + fun force_generate_chunk_requests() + fun set_chunk_generated_status(position: ChunkPositionTable, status: chunk_generated_status) + fun set_chunk_generated_status(position: Any /* JsTuple */, status: chunk_generated_status) + fun find_logistic_network_by_position(position: Position, force: String): LuaLogisticNetwork? + fun find_logistic_network_by_position(position: Position, force: LuaForce): LuaLogisticNetwork? + fun find_logistic_networks_by_construction_area(position: Position, force: String): Array + fun find_logistic_networks_by_construction_area(position: Position, force: LuaForce): Array + fun deconstruct_area(params: `T$76`) + fun cancel_deconstruct_area(params: `T$76`) + fun upgrade_area(params: `T$77`) + fun cancel_upgrade_area(params: `T$76`) + fun get_hidden_tile(position: TilePositionTable): String? + fun get_hidden_tile(position: Any /* JsTuple */): String? + fun set_hidden_tile(position: TilePositionTable, tile: String?) + fun set_hidden_tile(position: TilePositionTable, tile: LuaTilePrototype?) + fun set_hidden_tile(position: Any /* JsTuple */, tile: String?) + fun set_hidden_tile(position: Any /* JsTuple */, tile: LuaTilePrototype?) + fun get_connected_tiles(position: Position, tiles: Array): Array + fun delete_chunk(position: ChunkPositionTable) + fun delete_chunk(position: Any /* JsTuple */) + fun regenerate_entity(entities: String = definedExternally, chunks: Array */> = definedExternally) + fun regenerate_entity() + fun regenerate_entity(entities: String = definedExternally) + fun regenerate_entity(entities: Array = definedExternally, chunks: Array */> = definedExternally) + fun regenerate_entity(entities: Array = definedExternally) + fun regenerate_decorative(decoratives: String = definedExternally, chunks: Array */> = definedExternally) + fun regenerate_decorative() + fun regenerate_decorative(decoratives: String = definedExternally) + fun regenerate_decorative(decoratives: Array = definedExternally, chunks: Array */> = definedExternally) + fun regenerate_decorative(decoratives: Array = definedExternally) + fun print(message: Any /* JsTuple */, color: ColorTable = definedExternally) + fun print(message: Any /* JsTuple */) + fun print(message: Any /* JsTuple */, color: Any /* JsTuple */ = definedExternally) + fun print(message: String, color: ColorTable = definedExternally) + fun print(message: String) + fun print(message: String, color: Any /* JsTuple */ = definedExternally) + fun print(message: Number, color: ColorTable = definedExternally) + fun print(message: Number) + fun print(message: Number, color: Any /* JsTuple */ = definedExternally) + fun destroy_decoratives(params: `T$78`) + fun create_decoratives(params: `T$79`) + fun find_decoratives_filtered(params: `T$80`): Array + fun get_trains(force: String = definedExternally): Array + fun get_trains(): Array + fun get_trains(force: LuaForce = definedExternally): Array + fun clear_pollution() + fun play_sound(params: `T$34`) + fun get_resource_counts(): Record + fun get_random_chunk(): ChunkPositionTable + fun clone_area(params: `T$81`) + fun clone_brush(params: `T$82`) + fun clone_entities(params: `T$83`) + fun clear(ignore_characters: Boolean = definedExternally) + fun request_path(params: `T$84`): uint + fun get_script_areas(name: String = definedExternally): Array + fun get_script_area(key: String = definedExternally): ScriptArea + fun get_script_area(): ScriptArea + fun get_script_area(key: uint = definedExternally): ScriptArea + fun edit_script_area(id: uint, area: ScriptArea) + fun add_script_area(area: ScriptArea): uint + fun remove_script_area(id: uint): Boolean + fun get_script_positions(name: String = definedExternally): Array + fun get_script_position(key: String = definedExternally): ScriptPosition + fun get_script_position(): ScriptPosition + fun get_script_position(key: uint = definedExternally): ScriptPosition + fun edit_script_position(id: uint, area: ScriptPosition) + fun add_script_position(area: ScriptPosition): uint + fun remove_script_position(id: uint): Boolean + fun get_map_exchange_string(): String + fun get_starting_area_radius(): double + fun get_closest(position: Position, entities: Array): LuaEntity + fun get_train_stops(params: `T$85` = definedExternally): Array + fun get_total_pollution(): double + fun entity_prototype_collides(prototype: LuaEntity, position: Position, use_map_generation_bounding_box: Boolean, direction: direction = definedExternally) + fun entity_prototype_collides(prototype: LuaEntity, position: Position, use_map_generation_bounding_box: Boolean) + fun entity_prototype_collides(prototype: LuaEntityPrototype, position: Position, use_map_generation_bounding_box: Boolean, direction: direction = definedExternally) + fun entity_prototype_collides(prototype: LuaEntityPrototype, position: Position, use_map_generation_bounding_box: Boolean) + fun entity_prototype_collides(prototype: String, position: Position, use_map_generation_bounding_box: Boolean, direction: direction = definedExternally) + fun entity_prototype_collides(prototype: String, position: Position, use_map_generation_bounding_box: Boolean) + fun decorative_prototype_collides(prototype: String, position: Position) + fun calculate_tile_properties(property_names: Array, positions: Array): Record> + fun get_entities_with_force(position: ChunkPositionTable, force: LuaForce): Array + fun get_entities_with_force(position: ChunkPositionTable, force: String): Array + fun get_entities_with_force(position: Any /* JsTuple */, force: LuaForce): Array + fun get_entities_with_force(position: Any /* JsTuple */, force: String): Array + fun build_checkerboard(area: BoundingBoxTable) + fun build_checkerboard(area: Any /* JsTuple */) + var name: String + var index: uint + var map_gen_settings: MapGenSettings + var generate_with_lab_tiles: Boolean + var always_day: Boolean + var daytime: float + var darkness: float + var wind_speed: double + var wind_orientation: RealOrientation + var wind_orientation_change: double + var peaceful_mode: Boolean + var freeze_daytime: Boolean + var ticks_per_day: uint + var dusk: double + var dawn: double + var evening: double + var morning: double + var solar_power_multiplier: double + var min_brightness: double + var brightness_visual_weights: dynamic /* ColorModifierTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var show_clouds: Boolean + var valid: Boolean + var object_name: String /* "LuaSurface" */ + fun help(): String +} + +external interface LuaTechnology { + fun reload() + var force: LuaForce + var name: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var prototype: LuaTechnologyPrototype + var enabled: Boolean + var visible_when_disabled: Boolean + var upgrade: Boolean + var researched: Boolean + var prerequisites: Record + var research_unit_ingredients: Array + var effects: Array + var research_unit_count: uint + var research_unit_energy: double + var order: String + var level: uint + var research_unit_count_formula: String? + var valid: Boolean + var object_name: String /* "LuaTechnology" */ + fun help(): String +} + +external interface LuaTechnologyPrototype { + var name: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var enabled: Boolean + var hidden: Boolean + var visible_when_disabled: Boolean + var ignore_tech_cost_multiplier: Boolean + var upgrade: Boolean + var prerequisites: Record + var research_unit_ingredients: Array + var effects: Array + var research_unit_count: uint + var research_unit_energy: double + var order: String + var level: uint + var max_level: uint + var research_unit_count_formula: String? + var valid: Boolean + var object_name: String /* "LuaTechnologyPrototype" */ + fun help(): String +} + +external interface LuaTile { + fun collides_with(layer: String /* "ground-tile" | "water-tile" | "resource-layer" | "doodad-layer" | "floor-layer" | "item-layer" | "ghost-layer" | "object-layer" | "player-layer" | "train-layer" | "rail-layer" | "transport-belt-layer" | "not-setup" */): Boolean + fun collides_with(layer: ): Boolean + fun to_be_deconstructed(): Boolean + fun order_deconstruction(force: String, player: uint = definedExternally): LuaEntity? + fun order_deconstruction(force: String): LuaEntity? + fun order_deconstruction(force: String, player: String = definedExternally): LuaEntity? + fun order_deconstruction(force: String, player: LuaPlayer = definedExternally): LuaEntity? + fun order_deconstruction(force: LuaForce, player: uint = definedExternally): LuaEntity? + fun order_deconstruction(force: LuaForce): LuaEntity? + fun order_deconstruction(force: LuaForce, player: String = definedExternally): LuaEntity? + fun order_deconstruction(force: LuaForce, player: LuaPlayer = definedExternally): LuaEntity? + fun cancel_deconstruction(force: String, player: uint = definedExternally) + fun cancel_deconstruction(force: String) + fun cancel_deconstruction(force: String, player: String = definedExternally) + fun cancel_deconstruction(force: String, player: LuaPlayer = definedExternally) + fun cancel_deconstruction(force: LuaForce, player: uint = definedExternally) + fun cancel_deconstruction(force: LuaForce) + fun cancel_deconstruction(force: LuaForce, player: String = definedExternally) + fun cancel_deconstruction(force: LuaForce, player: LuaPlayer = definedExternally) + var name: String + var prototype: LuaTilePrototype + var position: PositionTable + var hidden_tile: String? + var surface: LuaSurface + var valid: Boolean + var object_name: String /* "LuaTile" */ + fun help(): String +} + +external interface `T$86` { + var minable: Boolean + var miningtime: double + var miningparticle: String? + get() = definedExternally + set(value) = definedExternally + var products: Array +} + +external interface LuaTilePrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var collision_mask: CollisionMask + var collision_mask_with_flags: CollisionMaskWithFlags + var layer: uint + var autoplace_specification: AutoplaceSpecification? + var walking_speed_modifier: float + var vehicle_friction_modifier: float + var map_color: ColorTable + var decorative_removal_probability: float + var automatic_neighbors: Boolean + var allowed_neighbors: Record + var needs_correction: Boolean + var mineable_properties: `T$86` + var next_direction: LuaTilePrototype? + var items_to_place_this: Array + var can_be_part_of_blueprint: Boolean + var emissions_per_second: double + var valid: Boolean + var object_name: String /* "LuaTilePrototype" */ + fun help(): String +} + +external interface LuaTrain { + fun get_item_count(item: String = definedExternally): uint + fun get_contents(): Record + fun remove_item(stack: String): uint + fun remove_item(stack: ItemStackDefinition): uint + fun remove_item(stack: LuaItemStack): uint + fun insert(stack: String) + fun insert(stack: ItemStackDefinition) + fun insert(stack: LuaItemStack) + fun clear_items_inside() + fun recalculate_path(force: Boolean = definedExternally): Boolean + fun get_fluid_count(fluid: String = definedExternally): double + fun get_fluid_contents(): Record + fun remove_fluid(fluid: Fluid): double + fun insert_fluid(fluid: Fluid): double + fun clear_fluids_inside() + fun go_to_station(index: uint) + fun get_rails(): Array + var manual_mode: Boolean + var speed: double + var max_forward_speed: double + var max_backward_speed: double + var weight: double + var carriages: Array + var locomotives: Record> + var cargo_wagons: Array + var fluid_wagons: Array + var schedule: TrainSchedule? + var state: train_state + var front_rail: LuaEntity? + var back_rail: LuaEntity? + var rail_direction_from_front_rail: rail_direction + var rail_direction_from_back_rail: rail_direction + var front_stock: LuaEntity? + var back_stock: LuaEntity? + var station: LuaEntity? + var has_path: Boolean + var path_end_rail: LuaEntity? + var path_end_stop: LuaEntity? + var id: uint + var passengers: Array + var riding_state: RidingState + var killed_players: Record + var kill_count: uint + var path: LuaRailPath? + var signal: LuaEntity? + var valid: Boolean + var object_name: String /* "LuaTrain" */ + fun help(): String +} + +external interface LuaTrainStopControlBehavior : LuaGenericOnOffControlBehavior { + var send_to_train: Boolean + var read_from_train: Boolean + var read_stopped_train: Boolean + var set_trains_limit: Boolean + var read_trains_count: Boolean + var enable_disable: Boolean + var stopped_train_signal: SignalID + var trains_count_signal: SignalID + var trains_limit_signal: SignalID + override var valid: Boolean + override var object_name: String /* "LuaTrainStopControlBehavior" */ + override fun help(): String +} + +external interface LuaTransportBeltControlBehavior : LuaGenericOnOffControlBehavior { + var enable_disable: Boolean + var read_contents: Boolean + var read_contents_mode: content_read_mode + override var valid: Boolean + override var object_name: String /* "LuaTransportBeltControlBehavior" */ + override fun help(): String +} + +typealias LuaTransportLine = Array + +external interface LuaTrivialSmokePrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var color: ColorTable + var start_scale: double + var end_scale: double + var movement_slow_down_factor: double + var duration: uint + var spread_duration: uint + var fade_away_duration: uint + var fade_in_duration: uint + var glow_fade_away_duration: uint + var cyclic: Boolean + var affected_by_wind: Boolean + var show_when_smoke_off: Boolean + var glow_animation: Boolean + var render_layer: dynamic /* Number | */ + get() = definedExternally + set(value) = definedExternally + var valid: Boolean + var object_name: String /* "LuaTrivialSmokePrototype" */ + fun help(): String +} + +external interface LuaUnitGroup { + fun add_member(unit: LuaEntity) + fun set_command(command: AttackCommand) + fun set_command(command: GoToLocationCommand) + fun set_command(command: CompoundCommand) + fun set_command(command: GroupCommand) + fun set_command(command: AttackAreaCommand) + fun set_command(command: WanderCommand) + fun set_command(command: StopCommand) + fun set_command(command: FleeCommand) + fun set_command(command: BuildBaseCommand) + fun set_distraction_command(command: AttackCommand) + fun set_distraction_command(command: GoToLocationCommand) + fun set_distraction_command(command: CompoundCommand) + fun set_distraction_command(command: GroupCommand) + fun set_distraction_command(command: AttackAreaCommand) + fun set_distraction_command(command: WanderCommand) + fun set_distraction_command(command: StopCommand) + fun set_distraction_command(command: FleeCommand) + fun set_distraction_command(command: BuildBaseCommand) + fun set_autonomous() + fun start_moving() + fun destroy() + var members: Array + var position: PositionTable + var state: group_state + var force: LuaForce + var surface: LuaSurface + var group_number: uint + var is_script_driven: Boolean + var command: dynamic /* AttackCommand? | GoToLocationCommand? | CompoundCommand? | GroupCommand? | AttackAreaCommand? | WanderCommand? | StopCommand? | FleeCommand? | BuildBaseCommand? */ + get() = definedExternally + set(value) = definedExternally + var distraction_command: dynamic /* AttackCommand? | GoToLocationCommand? | CompoundCommand? | GroupCommand? | AttackAreaCommand? | WanderCommand? | StopCommand? | FleeCommand? | BuildBaseCommand? */ + get() = definedExternally + set(value) = definedExternally + var valid: Boolean + var object_name: String /* "LuaUnitGroup" */ + fun help(): String +} + +external interface LuaVirtualSignalPrototype { + var name: String + var order: String + var localised_name: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var localised_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var special: Boolean + var subgroup: LuaGroup + var valid: Boolean + var object_name: String /* "LuaVirtualSignalPrototype" */ + fun help(): String +} + +external interface LuaVoidEnergySourcePrototype { + var emissions: double + var render_no_network_icon: Boolean + var render_no_power_icon: Boolean + var valid: Boolean + var object_name: String /* "LuaVoidEnergySourcePrototype" */ + fun help(): String +} + +external interface LuaWallControlBehavior : LuaControlBehavior { + var circuit_condition: CircuitConditionDefinition + var open_gate: Boolean + var read_sensor: Boolean + var output_signal: SignalID + var valid: Boolean + var object_name: String /* "LuaWallControlBehavior" */ + fun help(): String +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/concepts.module_typed-factorio.kt b/modules/mod2/dukat-custom/concepts.module_typed-factorio.kt new file mode 100644 index 0000000..b30c7c9 --- /dev/null +++ b/modules/mod2/dukat-custom/concepts.module_typed-factorio.kt @@ -0,0 +1,2924 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import defines.relative_gui_type +import defines.relative_gui_position +import tsstdlib.Record +import tsstdlib.Position +import defines.difficulty_settings.recipe_difficulty +import defines.difficulty_settings.technology_difficulty +import defines.circuit_connector_id +import defines.direction +import defines.wire_type +import defines.command +import defines.distraction +import defines.compound_command +import defines.inventory +import defines.riding.acceleration +import defines.riding.direction as _defines_riding_direction +import defines.control_behavior.mining_drill.resource_read_mode +import defines.control_behavior.inserter.hand_read_mode +import defines.control_behavior.transport_belt.content_read_mode + +external interface DisplayResolution { + var width: uint + var height: uint +} + +external interface PersonalLogisticParameters { + var name: String? + get() = definedExternally + set(value) = definedExternally + var min: uint? + get() = definedExternally + set(value) = definedExternally + var max: uint? + get() = definedExternally + set(value) = definedExternally +} + +typealias RealOrientation = float + +external interface PositionTable { + var x: int + var y: int +} + +external interface ChunkPositionTable { + var x: int + var y: int +} + +external interface TilePositionTable { + var x: int + var y: int +} + +external interface GuiLocationTable { + var x: int + var y: int +} + +external interface ChunkPositionAndArea { + var x: int + var y: int + var area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally +} + +external interface EquipmentPoint { + var x: uint + var y: uint +} + +external interface GuiAnchor { + var gui: relative_gui_type + var position: relative_gui_position + var type: String? + get() = definedExternally + set(value) = definedExternally + var name: String? + get() = definedExternally + set(value) = definedExternally + var names: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface TabAndContent { + var tab: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var content: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally +} + +external interface OldTileAndPosition { + var old_tile: LuaTilePrototype + var position: dynamic /* TilePositionTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally +} + +typealias Tags = Record + +external interface SmokeSource { + var name: String + var frequency: double + var offset: double + var position: PositionTable? + get() = definedExternally + set(value) = definedExternally + var north_position: PositionTable? + get() = definedExternally + set(value) = definedExternally + var east_position: PositionTable? + get() = definedExternally + set(value) = definedExternally + var south_position: PositionTable? + get() = definedExternally + set(value) = definedExternally + var west_position: PositionTable? + get() = definedExternally + set(value) = definedExternally + var deviation: Position? + get() = definedExternally + set(value) = definedExternally + var starting_frame_speed: uint16 + var starting_frame_speed_deviation: double + var starting_frame: uint16 + var starting_frame_deviation: double + var slow_down_factor: uint8 + var height: float + var height_deviation: float + var starting_vertical_speed: float + var starting_vertical_speed_deviation: float + var vertical_speed_slowdown: float +} + +external interface BoundingBoxTable { + var left_top: Position + var right_bottom: Position + var orientation: RealOrientation? + get() = definedExternally + set(value) = definedExternally +} + +external interface ScriptArea { + var area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var name: String + var color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var id: uint +} + +external interface ScriptPosition { + var position: Position + var name: String + var color: dynamic /* ColorTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var id: uint +} + +external interface ColorTable { + var r: float? + get() = definedExternally + set(value) = definedExternally + var g: float? + get() = definedExternally + set(value) = definedExternally + var b: float? + get() = definedExternally + set(value) = definedExternally + var a: float? + get() = definedExternally + set(value) = definedExternally +} + +external interface ColorModifierTable { + var r: float? + get() = definedExternally + set(value) = definedExternally + var g: float? + get() = definedExternally + set(value) = definedExternally + var b: float? + get() = definedExternally + set(value) = definedExternally + var a: float? + get() = definedExternally + set(value) = definedExternally +} + +external interface CraftingQueueItem { + var index: uint + var recipe: String + var count: uint +} + +external interface Alert { + var tick: uint + var target: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var prototype: LuaEntityPrototype? + get() = definedExternally + set(value) = definedExternally + var position: Position? + get() = definedExternally + set(value) = definedExternally + var icon: SignalID? + get() = definedExternally + set(value) = definedExternally + var message: dynamic /* JsTuple | String? | Number? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ScriptRenderVertexTarget { + var target: dynamic /* Position | LuaEntity */ + get() = definedExternally + set(value) = definedExternally + var target_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally +} + +external interface PathfinderWaypoint { + var position: Position + var needs_destroy_to_reach: Boolean +} + +external interface CutsceneWaypoint { + var position: Position? + get() = definedExternally + set(value) = definedExternally + var target: dynamic /* LuaEntity? | LuaUnitGroup? */ + get() = definedExternally + set(value) = definedExternally + var transition_time: uint + var time_to_wait: uint + var zoom: double? + get() = definedExternally + set(value) = definedExternally +} + +external interface Decorative { + var name: String + var position: Position + var amount: uint8 +} + +external interface DecorativeResult { + var position: dynamic /* TilePositionTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var decorative: LuaDecorativePrototype + var amount: uint +} + +external interface ChartTagSpec { + var position: Position + var icon: SignalID? + get() = definedExternally + set(value) = definedExternally + var text: String? + get() = definedExternally + set(value) = definedExternally + var last_user: dynamic /* uint? | String? | LuaPlayer? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface GameViewSettings { + var show_controller_gui: Boolean + var show_minimap: Boolean + var show_research_info: Boolean + var show_entity_info: Boolean + var show_alert_gui: Boolean + var update_entity_selection: Boolean + var show_rail_block_visualisation: Boolean + var show_side_menu: Boolean + var show_map_view_options: Boolean + var show_quickbar: Boolean + var show_shortcut_bar: Boolean +} + +external interface MapViewSettings { + @nativeGetter + operator fun get(key: String): Boolean? + @nativeSetter + operator fun set(key: String, value: Boolean?) +} + +external interface PollutionMapSettings { + var enabled: Boolean + var diffusion_ratio: double + var min_to_diffuse: double + var aeging: double + var expected_max_per_chunk: double + var min_to_show_per_chunk: double + var min_pollution_to_damage_trees: double + var pollution_with_max_forest_damage: double + var pollution_per_tree_damage: double + var pollution_restored_per_tree_damage: double + var max_pollution_to_restore_trees: double + var enemy_attack_pollution_consumption_modifier: double +} + +external interface EnemyEvolutionMapSettings { + var enabled: Boolean + var time_factor: double + var destroy_factor: double + var pollution_factor: double +} + +external interface EnemyExpansionMapSettings { + var enabled: Boolean + var max_expansion_distance: uint + var friendly_base_influence_radius: uint + var enemy_building_influence_radius: uint + var building_coefficient: double + var other_base_coefficient: double + var neighbouring_chunk_coefficient: double + var neighbouring_base_chunk_coefficient: double + var max_colliding_tiles_coefficient: double + var settler_group_min_size: uint + var settler_group_max_size: uint + var min_expansion_cooldown: uint + var max_expansion_cooldown: uint +} + +external interface UnitGroupMapSettings { + var min_group_gathering_time: uint + var max_group_gathering_time: uint + var max_wait_time_for_late_members: uint + var min_group_radius: double + var max_group_radius: double + var max_member_speedup_when_behind: double + var max_member_slowdown_when_ahead: double + var max_group_slowdown_factor: double + var max_group_member_fallback_factor: double + var member_disown_distance: double + var tick_tolerance_when_member_arrives: uint + var max_gathering_unit_groups: uint + var max_unit_group_size: uint +} + +external interface SteeringMapSetting { + var radius: double + var separation_factor: double + var separation_force: double + var force_unit_fuzzy_goto_behavior: Boolean +} + +external interface SteeringMapSettings { + var default: SteeringMapSetting + var moving: SteeringMapSetting +} + +external interface PathFinderMapSettings { + var fwd2bwd_ratio: uint + var goal_pressure_ratio: double + var max_steps_worked_per_tick: double + var max_work_done_per_tick: uint + var use_path_cache: Boolean + var short_cache_size: uint + var long_cache_size: uint + var short_cache_min_cacheable_distance: double + var short_cache_min_algo_steps_to_cache: uint + var long_cache_min_cacheable_distance: double + var cache_max_connect_to_cache_steps_multiplier: uint + var cache_accept_path_start_distance_ratio: double + var cache_accept_path_end_distance_ratio: double + var negative_cache_accept_path_start_distance_ratio: double + var negative_cache_accept_path_end_distance_ratio: double + var cache_path_start_distance_rating_multiplier: double + var cache_path_end_distance_rating_multiplier: double + var stale_enemy_with_same_destination_collision_penalty: double + var ignore_moving_enemy_collision_distance: double + var enemy_with_different_destination_collision_penalty: double + var general_entity_collision_penalty: double + var general_entity_subsequent_collision_penalty: double + var extended_collision_penalty: double + var max_clients_to_accept_any_new_request: uint + var max_clients_to_accept_short_new_request: uint + var direct_distance_to_consider_short_request: uint + var short_request_max_steps: uint + var short_request_ratio: double + var min_steps_to_check_path_find_termination: uint + var start_to_goal_cost_multiplier_to_terminate_path_find: double + var overload_levels: Array + var overload_multipliers: Array + var negative_path_cache_delay_interval: uint +} + +external interface MapSettings { + var pollution: PollutionMapSettings + var enemy_evolution: EnemyEvolutionMapSettings + var enemy_expansion: EnemyExpansionMapSettings + var unit_group: UnitGroupMapSettings + var steering: SteeringMapSettings + var path_finder: PathFinderMapSettings + var max_failed_behavior_count: uint +} + +external interface DifficultySettings { + var recipe_difficulty: recipe_difficulty + var technology_difficulty: technology_difficulty + var technology_price_multiplier: double + var research_queue_setting: String /* "after-victory" | "always" | "never" */ +} + +external interface MapExchangeStringData { + var map_settings: MapSettings + var map_gen_settings: MapGenSettings +} + +external interface BlueprintItemIcon { + var name: String + var index: uint +} + +external interface BlueprintSignalIcon { + var signal: SignalID + var index: uint +} + +external interface BlueprintConnectionData { + var entity_id: uint + var circuit_id: circuit_connector_id? + get() = definedExternally + set(value) = definedExternally +} + +external interface BlueprintConnectionPoint { + var red: Array? + get() = definedExternally + set(value) = definedExternally + var green: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface BlueprintCircuitConnection { + @nativeGetter + operator fun get(key: String): BlueprintConnectionPoint? + @nativeSetter + operator fun set(key: String, value: BlueprintConnectionPoint?) +} + +external interface BlueprintEntity { + var entity_number: uint + var name: String + var position: Position + var direction: direction? + get() = definedExternally + set(value) = definedExternally + var tags: Tags? + get() = definedExternally + set(value) = definedExternally + var items: Record? + get() = definedExternally + set(value) = definedExternally + var connections: BlueprintCircuitConnection? + get() = definedExternally + set(value) = definedExternally + var control_behavior: BlueprintControlBehavior? + get() = definedExternally + set(value) = definedExternally + var schedule: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface Tile { + var position: Position + var name: String +} + +external interface Fluid { + var name: String + var amount: double + var temperature: double? + get() = definedExternally + set(value) = definedExternally +} + +external interface BaseIngredient { + var type: String /* "item" | "fluid" */ + var name: String + var amount: double + var catalyst_amount: dynamic /* uint? | double? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FluidIngredient : BaseIngredient { + override var type: String /* "fluid" */ + var minimum_temperature: double? + get() = definedExternally + set(value) = definedExternally + var maximum_temperature: double? + get() = definedExternally + set(value) = definedExternally +} + +external interface OtherIngredient : BaseIngredient { + override var type: String /* "item" */ +} + +external interface BaseProduct { + var type: String /* "item" | "fluid" */ + var name: String + var amount: double? + get() = definedExternally + set(value) = definedExternally + var amount_min: dynamic /* uint? | double? */ + get() = definedExternally + set(value) = definedExternally + var amount_max: dynamic /* uint? | double? */ + get() = definedExternally + set(value) = definedExternally + var probability: double? + get() = definedExternally + set(value) = definedExternally + var catalyst_amount: dynamic /* uint? | double? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FluidProduct : BaseProduct { + override var type: String /* "fluid" */ + var temperature: double? + get() = definedExternally + set(value) = definedExternally +} + +external interface OtherProduct : BaseProduct { + override var type: String /* "item" */ +} + +external interface Loot { + var item: String + var probability: double + var count_min: double + var count_max: double +} + +external interface BaseTechnologyModifier { + var type: String /* "inserter-stack-size-bonus" | "stack-inserter-capacity-bonus" | "laboratory-speed" | "character-logistic-trash-slots" | "maximum-following-robots-count" | "worker-robot-speed" | "worker-robot-storage" | "ghost-time-to-live" | "turret-attack" | "ammo-damage" | "give-item" | "gun-speed" | "unlock-recipe" | "character-crafting-speed" | "character-mining-speed" | "character-running-speed" | "character-build-distance" | "character-item-drop-distance" | "character-reach-distance" | "character-resource-reach-distance" | "character-item-pickup-distance" | "character-loot-pickup-distance" | "character-inventory-slots-bonus" | "deconstruction-time-to-live" | "max-failed-attempts-per-tick-per-construction-queue" | "max-successful-attempts-per-tick-per-construction-queue" | "character-health-bonus" | "mining-drill-productivity-bonus" | "train-braking-force-bonus" | "zoom-to-world-enabled" | "zoom-to-world-ghost-building-enabled" | "zoom-to-world-blueprint-enabled" | "zoom-to-world-deconstruction-planner-enabled" | "zoom-to-world-upgrade-planner-enabled" | "zoom-to-world-selection-tool-enabled" | "worker-robot-battery" | "laboratory-productivity" | "follower-robot-lifetime" | "artillery-range" | "nothing" | "character-additional-mining-categories" | "character-logistic-requests" */ +} + +external interface GunSpeedTechnologyModifier : BaseTechnologyModifier { + override var type: String /* "gun-speed" */ + var ammo_category: String + var modifier: double +} + +external interface AmmoDamageTechnologyModifier : BaseTechnologyModifier { + override var type: String /* "ammo-damage" */ + var ammo_category: String + var modifier: double +} + +external interface GiveItemTechnologyModifier : BaseTechnologyModifier { + override var type: String /* "give-item" */ + var item: String + var count: uint? + get() = definedExternally + set(value) = definedExternally +} + +external interface TurretAttackTechnologyModifier : BaseTechnologyModifier { + override var type: String /* "turret-attack" */ + var turret_id: String + var modifier: double +} + +external interface UnlockRecipeTechnologyModifier : BaseTechnologyModifier { + override var type: String /* "unlock-recipe" */ + var recipe: String +} + +external interface NothingTechnologyModifier : BaseTechnologyModifier { + override var type: String /* "nothing" */ + var effect_description: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally +} + +external interface OtherTechnologyModifier : BaseTechnologyModifier { + override var type: String /* "inserter-stack-size-bonus" | "stack-inserter-capacity-bonus" | "laboratory-speed" | "character-logistic-trash-slots" | "maximum-following-robots-count" | "worker-robot-speed" | "worker-robot-storage" | "ghost-time-to-live" | "character-crafting-speed" | "character-mining-speed" | "character-running-speed" | "character-build-distance" | "character-item-drop-distance" | "character-reach-distance" | "character-resource-reach-distance" | "character-item-pickup-distance" | "character-loot-pickup-distance" | "character-inventory-slots-bonus" | "deconstruction-time-to-live" | "max-failed-attempts-per-tick-per-construction-queue" | "max-successful-attempts-per-tick-per-construction-queue" | "character-health-bonus" | "mining-drill-productivity-bonus" | "train-braking-force-bonus" | "zoom-to-world-enabled" | "zoom-to-world-ghost-building-enabled" | "zoom-to-world-blueprint-enabled" | "zoom-to-world-deconstruction-planner-enabled" | "zoom-to-world-upgrade-planner-enabled" | "zoom-to-world-selection-tool-enabled" | "worker-robot-battery" | "laboratory-productivity" | "follower-robot-lifetime" | "artillery-range" | "character-additional-mining-categories" | "character-logistic-requests" */ + var modifier: double +} + +external interface Offer { + var price: Array + var offer: dynamic /* GunSpeedTechnologyModifier | AmmoDamageTechnologyModifier | GiveItemTechnologyModifier | TurretAttackTechnologyModifier | UnlockRecipeTechnologyModifier | NothingTechnologyModifier | OtherTechnologyModifier */ + get() = definedExternally + set(value) = definedExternally +} + +external interface AutoplaceSpecification { + var probability_expression: NoiseExpression + var richness_expression: NoiseExpression + var coverage: double + var sharpness: double + var max_probability: double + var placement_density: uint + var richness_base: double + var richness_multiplier: double + var richness_multiplier_distance_bonus: double + var starting_area_size: uint + var order: String + var default_enabled: Boolean + var peaks: Array? + get() = definedExternally + set(value) = definedExternally + var control: String? + get() = definedExternally + set(value) = definedExternally + var tile_restriction: Array? + get() = definedExternally + set(value) = definedExternally + var force: String + var random_probability_penalty: double +} + +external interface NoiseExpression { + var type: String +} + +external interface AutoplaceSpecificationPeak { + var influence: double + var max_influence: double + var min_influence: double + var richness_influence: double + var noisePersistence: double + var noise_layer: String? + get() = definedExternally + set(value) = definedExternally + var noise_octaves_difference: double + var water_optimal: double + var water_range: double + var water_max_range: double + var water_top_property_limit: double + var elevation_optimal: double + var elevation_range: double + var elevation_max_range: double + var elevation_top_property_limit: double + var temperature_optimal: double + var temperature_range: double + var temperature_max_range: double + var temperature_top_property_limit: double + var starting_area_weight_optimal: double + var starting_area_weight_range: double + var starting_area_weight_max_range: double + var starting_area_weight_top_property_limit: double + var tier_from_start_optimal: double + var tier_from_start_range: double + var tier_from_start_max_range: double + var tier_from_start_top_property_limit: double + var distance_optimal: double + var distance_range: double + var distance_max_range: double + var distance_top_property_limit: double + var aux_optimal: double + var aux_range: double + var aux_max_range: double + var aux_top_property_limit: double +} + +external interface AutoplaceSpecificationRestriction { + var first: String? + get() = definedExternally + set(value) = definedExternally + var second: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface Resistance { + var decrease: float + var percent: float +} + +external interface AutoplaceSetting { + var frequency: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ + get() = definedExternally + set(value) = definedExternally + var size: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ + get() = definedExternally + set(value) = definedExternally + var richness: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface AutoplaceSettings { + var treat_missing_as_default: Boolean + var settings: Record +} + +external interface AutoplaceControl { + var frequency: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ + get() = definedExternally + set(value) = definedExternally + var size: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ + get() = definedExternally + set(value) = definedExternally + var richness: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface CliffPlacementSettings { + var name: String + var cliff_elevation_0: float + var cliff_elevation_interval: float + var richness: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface MapGenSettings { + var terrain_segmentation: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ + get() = definedExternally + set(value) = definedExternally + var water: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ + get() = definedExternally + set(value) = definedExternally + var autoplace_controls: Record + var default_enable_all_autoplace_controls: Boolean + var autoplace_settings: Record + var cliff_settings: CliffPlacementSettings + var seed: uint + var width: uint + var height: uint + var starting_area: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ + get() = definedExternally + set(value) = definedExternally + var starting_points: Array + var peaceful_mode: Boolean + var property_expression_names: Record +} + +external interface MapGenSettingsPartial { + var terrain_segmentation: dynamic /* Number? | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ + get() = definedExternally + set(value) = definedExternally + var water: dynamic /* Number? | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ + get() = definedExternally + set(value) = definedExternally + var autoplace_controls: Record? + get() = definedExternally + set(value) = definedExternally + var default_enable_all_autoplace_controls: Boolean? + get() = definedExternally + set(value) = definedExternally + var autoplace_settings: Record? + get() = definedExternally + set(value) = definedExternally + var cliff_settings: CliffPlacementSettings? + get() = definedExternally + set(value) = definedExternally + var seed: uint? + get() = definedExternally + set(value) = definedExternally + var width: uint? + get() = definedExternally + set(value) = definedExternally + var height: uint? + get() = definedExternally + set(value) = definedExternally + var starting_area: dynamic /* Number? | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ + get() = definedExternally + set(value) = definedExternally + var starting_points: Array? + get() = definedExternally + set(value) = definedExternally + var peaceful_mode: Boolean? + get() = definedExternally + set(value) = definedExternally + var property_expression_names: Record? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignalID { + var type: String /* "item" | "fluid" | "virtual" */ + var name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface Signal { + var signal: SignalID + var count: int +} + +external interface UpgradeFilter { + var type: String /* "item" | "entity" */ + var name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface InfinityInventoryFilter { + var name: String + var count: uint? + get() = definedExternally + set(value) = definedExternally + var mode: String? /* "at-least" | "at-most" | "exactly" */ + get() = definedExternally + set(value) = definedExternally + var index: uint +} + +external interface InfinityPipeFilter { + var name: String + var percentage: double? + get() = definedExternally + set(value) = definedExternally + var temperature: double? + get() = definedExternally + set(value) = definedExternally + var mode: String? /* "at-least" | "at-most" | "exactly" | "add" | "remove" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FluidBoxFilter { + var name: String + var minimum_temperature: double + var maximum_temperature: double +} + +external interface FluidBoxFilterSpec { + var name: String + var minimum_temperature: double? + get() = definedExternally + set(value) = definedExternally + var maximum_temperature: double? + get() = definedExternally + set(value) = definedExternally + var force: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface HeatSetting { + var temperature: double? + get() = definedExternally + set(value) = definedExternally + var mode: String? /* "at-least" | "at-most" | "exactly" | "add" | "remove" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface HeatConnection { + var position: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var direction: direction +} + +external interface FluidBoxConnection { + var type: String /* "input" | "output" | "input-output" */ + var positions: Array + var max_underground_distance: uint? + get() = definedExternally + set(value) = definedExternally +} + +external interface ArithmeticCombinatorParameters { + var first_signal: SignalID? + get() = definedExternally + set(value) = definedExternally + var second_signal: SignalID? + get() = definedExternally + set(value) = definedExternally + var first_constant: int? + get() = definedExternally + set(value) = definedExternally + var second_constant: int? + get() = definedExternally + set(value) = definedExternally + var operation: String? /* "*" | "/" | "+" | "-" | "%" | "^" | "<<" | ">>" | "AND" | "OR" | "XOR" */ + get() = definedExternally + set(value) = definedExternally + var output_signal: SignalID? + get() = definedExternally + set(value) = definedExternally +} + +external interface ConstantCombinatorParameters { + var signal: SignalID + var count: int + var index: uint +} + +external interface DeciderCombinatorParameters { + var first_signal: SignalID? + get() = definedExternally + set(value) = definedExternally + var second_signal: SignalID? + get() = definedExternally + set(value) = definedExternally + var constant: uint? + get() = definedExternally + set(value) = definedExternally + var comparator: String? /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + get() = definedExternally + set(value) = definedExternally + var output_signal: SignalID? + get() = definedExternally + set(value) = definedExternally + var copy_count_from_input: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface InserterCircuitConditions { + var circuit: CircuitCondition? + get() = definedExternally + set(value) = definedExternally + var logistics: CircuitCondition? + get() = definedExternally + set(value) = definedExternally +} + +external interface CircuitCondition { + var comparator: String? /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + get() = definedExternally + set(value) = definedExternally + var first_signal: SignalID? + get() = definedExternally + set(value) = definedExternally + var second_signal: SignalID? + get() = definedExternally + set(value) = definedExternally + var constant: int? + get() = definedExternally + set(value) = definedExternally +} + +external interface CircuitConditionDefinition { + var condition: CircuitCondition + var fulfilled: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface CircuitConnectionDefinition { + var wire: wire_type + var target_entity: LuaEntity + var source_circuit_id: circuit_connector_id + var target_circuit_id: circuit_connector_id +} + +external interface WireConnectionDefinition { + var wire: wire_type + var target_entity: LuaEntity + var source_circuit_id: circuit_connector_id? + get() = definedExternally + set(value) = definedExternally + var target_circuit_id: circuit_connector_id? + get() = definedExternally + set(value) = definedExternally + var source_wire_id: circuit_connector_id? + get() = definedExternally + set(value) = definedExternally + var target_wire_id: circuit_connector_id? + get() = definedExternally + set(value) = definedExternally +} + +external interface InventoryFilter { + var index: uint + var name: String +} + +external interface PlaceAsTileResult { + var result: LuaTilePrototype + var condition_size: uint + var condition: CollisionMask +} + +external interface BaseCommand { + var type: command +} + +external interface AttackCommand : BaseCommand { + var target: LuaEntity + var distraction: distraction? + get() = definedExternally + set(value) = definedExternally +} + +external interface GoToLocationCommand : BaseCommand { + var destination: Position? + get() = definedExternally + set(value) = definedExternally + var destination_entity: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var distraction: distraction? + get() = definedExternally + set(value) = definedExternally + var pathfind_flags: PathfinderFlags? + get() = definedExternally + set(value) = definedExternally + var radius: double? + get() = definedExternally + set(value) = definedExternally +} + +external interface CompoundCommand : BaseCommand { + var structure_type: compound_command + var commands: Array +} + +external interface GroupCommand : BaseCommand { + var group: LuaUnitGroup + var distraction: distraction? + get() = definedExternally + set(value) = definedExternally + var use_group_distraction: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface AttackAreaCommand : BaseCommand { + var destination: Position + var radius: double + var distraction: distraction? + get() = definedExternally + set(value) = definedExternally +} + +external interface WanderCommand : BaseCommand { + var distraction: distraction? + get() = definedExternally + set(value) = definedExternally + var radius: double? + get() = definedExternally + set(value) = definedExternally + var wander_in_group: Boolean? + get() = definedExternally + set(value) = definedExternally + var ticks_to_wait: uint? + get() = definedExternally + set(value) = definedExternally +} + +external interface StopCommand : BaseCommand { + var distraction: distraction? + get() = definedExternally + set(value) = definedExternally + var ticks_to_wait: uint? + get() = definedExternally + set(value) = definedExternally +} + +external interface FleeCommand : BaseCommand { + var from: LuaEntity + var distraction: distraction? + get() = definedExternally + set(value) = definedExternally +} + +external interface BuildBaseCommand : BaseCommand { + var destination: Position + var distraction: distraction? + get() = definedExternally + set(value) = definedExternally + var ignore_planner: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface PathfinderFlags { + var allow_destroy_friendly_entities: Boolean? + get() = definedExternally + set(value) = definedExternally + var allow_paths_through_own_entities: Boolean? + get() = definedExternally + set(value) = definedExternally + var cache: Boolean? + get() = definedExternally + set(value) = definedExternally + var prefer_straight_paths: Boolean? + get() = definedExternally + set(value) = definedExternally + var low_priority: Boolean? + get() = definedExternally + set(value) = definedExternally + var no_break: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface UnitSpawnDefinition { + var unit: String + var spawn_points: Array +} + +external interface SpawnPointDefinition { + var evolution_factor: double + var weight: double +} + +external interface ItemStackDefinition { + var name: String + var count: uint? + get() = definedExternally + set(value) = definedExternally + var health: float? + get() = definedExternally + set(value) = definedExternally + var durability: double? + get() = definedExternally + set(value) = definedExternally + var ammo: double? + get() = definedExternally + set(value) = definedExternally + var tags: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface WaitCondition { + var type: String /* "time" | "inactivity" | "full" | "empty" | "item_count" | "circuit" | "robots_inactive" | "fluid_count" | "passenger_present" | "passenger_not_present" */ + var compare_type: String /* "and" | "or" */ + var ticks: uint? + get() = definedExternally + set(value) = definedExternally + var condition: CircuitCondition? + get() = definedExternally + set(value) = definedExternally +} + +external interface TrainScheduleRecord { + var station: String? + get() = definedExternally + set(value) = definedExternally + var rail: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var wait_conditions: Array? + get() = definedExternally + set(value) = definedExternally + var temporary: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TrainSchedule { + var current: uint + var records: Array +} + +external interface BaseGuiArrowSpecification { + var type: String /* "nowhere" | "goal" | "entity_info" | "active_window" | "entity" | "position" | "crafting_queue" | "item_stack" */ +} + +external interface EntityGuiArrowSpecification : BaseGuiArrowSpecification { + override var type: String /* "entity" */ + var entity: LuaEntity +} + +external interface PositionGuiArrowSpecification : BaseGuiArrowSpecification { + override var type: String /* "position" */ + var position: Position +} + +external interface CraftingQueueGuiArrowSpecification : BaseGuiArrowSpecification { + override var type: String /* "crafting_queue" */ + var crafting_queueindex: uint +} + +external interface ItemStackGuiArrowSpecification : BaseGuiArrowSpecification { + override var type: String /* "item_stack" */ + var inventory_index: inventory + var item_stack_index: uint + var source: String /* "player" | "target" | "player-quickbar" | "player-equipment-bar" */ +} + +external interface OtherGuiArrowSpecification : BaseGuiArrowSpecification { + override var type: String /* "nowhere" | "goal" | "entity_info" | "active_window" */ +} + +external interface AmmoType { + var action: Array? + get() = definedExternally + set(value) = definedExternally + var target_type: String /* "entity" | "position" | "direction" */ + var clamp_position: Boolean? + get() = definedExternally + set(value) = definedExternally + var category: String + var energy_consumption: double? + get() = definedExternally + set(value) = definedExternally +} + +external interface BeamTarget { + var entity: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var position: Position? + get() = definedExternally + set(value) = definedExternally +} + +external interface RidingState { + var acceleration: acceleration + var direction: _defines_riding_direction +} + +external interface ModuleEffectValue { + var bonus: float +} + +external interface ModuleEffects { + var consumption: ModuleEffectValue? + get() = definedExternally + set(value) = definedExternally + var speed: ModuleEffectValue? + get() = definedExternally + set(value) = definedExternally + var productivity: ModuleEffectValue? + get() = definedExternally + set(value) = definedExternally + var pollution: ModuleEffectValue? + get() = definedExternally + set(value) = definedExternally +} + +external interface EntityPrototypeFlags { + @nativeGetter + operator fun get(key: String): Boolean? + @nativeSetter + operator fun set(key: String, value: Boolean?) + var hidden: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ItemPrototypeFlags { + @nativeGetter + operator fun get(key: String): Boolean? + @nativeSetter + operator fun set(key: String, value: Boolean?) + var hidden: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +typealias CollisionMask = Any + +typealias CollisionMaskWithFlags = Any + +typealias TriggerTargetMask = Any + +external interface TriggerEffectItem { + var type: String /* "damage" | "create-entity" | "create-explosion" | "create-fire" | "create-smoke" | "create-trivial-smoke" | "create-particle" | "create-sticker" | "nested-result" | "play-sound" | "push-back" | "destroy-cliffs" | "show-explosion-on-chart" | "insert-item" | "script" */ + var repeat_count: uint + var affects_target: Boolean + var show_in_tooltip: Boolean +} + +external interface TriggerDelivery { + var type: String /* "instant" | "projectile" | "flame-thrower" | "beam" | "stream" | "artillery" */ + var source_effects: Array + var target_effects: Array +} + +external interface TriggerItem { + var type: String /* "direct" | "area" | "line" | "cluster" */ + var action_delivery: Array? + get() = definedExternally + set(value) = definedExternally + var entity_flags: EntityPrototypeFlags? + get() = definedExternally + set(value) = definedExternally + var ignore_collision_condition: Boolean + var collision_mask: CollisionMask + var trigger_target_mask: TriggerTargetMask + var force: String /* "all" | "enemy" | "ally" | "friend" | "not-friend" | "same" | "not-same" */ + var repeat_count: uint +} + +external interface CircularParticleCreationSpecification { + var name: String + var direction: float + var direction_deviation: float + var speed: float + var speed_deviation: float + var starting_frame_speed: float + var starting_frame_speed_deviation: float + var height: float + var height_deviation: float + var vertical_speed: float + var vertical_speed_deviation: float + var center: PositionTable + var creation_distance: double + var creation_distance_orientation: double + var use_source_position: Boolean +} + +external interface AttackParameterFluid { + var type: String + var damage_modifier: double +} + +external interface BaseAttackParameters { + var type: String /* "projectile" | "stream" | "beam" */ + var range: float + var min_range: float + var range_mode: String /* "center-to-center" | "bounding-box-to-bounding-box" */ + var fire_penalty: float + var rotate_penalty: float + var health_penalty: float + var min_attack_distance: float + var turn_range: float + var damage_modifier: float + var ammo_consumption_modifier: float + var cooldown: float + var warmup: uint + var movement_slow_down_factor: double + var movement_slow_down_cooldown: float + var ammo_type: AmmoType? + get() = definedExternally + set(value) = definedExternally + var ammo_categories: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface ProjectileAttackParameters : BaseAttackParameters { + override var type: String /* "projectile" */ + var projectile_center: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var projectile_creation_distance: float + var projectile_orientation_offset: float + var shell_particle: CircularParticleCreationSpecification? + get() = definedExternally + set(value) = definedExternally + var projectile_creation_parameters: Array */>? + get() = definedExternally + set(value) = definedExternally +} + +external interface StreamAttackParameters : BaseAttackParameters { + override var type: String /* "stream" */ + var gun_barrel_length: float + var gun_center_shift: Record + var fluid_consumption: float + var fluids: Array? + get() = definedExternally + set(value) = definedExternally + var projectile_creation_parameters: Array */>? + get() = definedExternally + set(value) = definedExternally +} + +external interface OtherAttackParameters : BaseAttackParameters { + override var type: String /* "beam" */ +} + +external interface CapsuleAction { + var type: String /* "throw" | "equipment-remote" | "use-on-self" */ + var attack_parameters: dynamic /* ProjectileAttackParameters? | StreamAttackParameters? | OtherAttackParameters? */ + get() = definedExternally + set(value) = definedExternally + var equipment: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface SelectionModeFlags { + @nativeGetter + operator fun get(key: String): Boolean? + @nativeSetter + operator fun set(key: String, value: Boolean?) + var blueprint: Boolean? + get() = definedExternally + set(value) = definedExternally + var deconstruct: Boolean? + get() = definedExternally + set(value) = definedExternally + var items: Boolean? + get() = definedExternally + set(value) = definedExternally + var trees: Boolean? + get() = definedExternally + set(value) = definedExternally + var nothing: Boolean? + get() = definedExternally + set(value) = definedExternally + var friend: Boolean? + get() = definedExternally + set(value) = definedExternally + var enemy: Boolean? + get() = definedExternally + set(value) = definedExternally + var upgrade: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface LogisticFilter { + var index: uint + var name: String + var count: uint +} + +external interface ModSetting { + var value: dynamic /* uint | double | Boolean | String */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ProgrammableSpeakerParameters { + var playback_volume: double + var playback_globally: Boolean + var allow_polyphony: Boolean +} + +external interface ProgrammableSpeakerAlertParameters { + var show_alert: Boolean + var show_on_map: Boolean + var icon_signal_id: SignalID + var alert_message: String +} + +external interface ProgrammableSpeakerCircuitParameters { + var signal_value_is_pitch: Boolean + var instrument_id: uint + var note_id: uint +} + +external interface ProgrammableSpeakerInstrument { + var name: String + var notes: Array +} + +external interface EventData { + var name: uint /* uint & `T$93` */ + var tick: uint + var mod_name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface NthTickEventData { + var tick: uint + var nth_tick: uint +} + +external interface ModChangeData { + var old_version: String? + var new_version: String? +} + +external interface ConfigurationChangedData { + var old_version: String? + get() = definedExternally + set(value) = definedExternally + var new_version: String? + get() = definedExternally + set(value) = definedExternally + var mod_changes: Record + var mod_startup_settings_changed: Boolean + var migration_applied: Boolean +} + +external interface CustomCommandData { + var name: String + var tick: uint + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var parameter: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface SelectedPrototypeData { + var base_type: String + var derived_type: String + var name: String +} + +external interface ScriptRenderTarget { + var entity: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var entity_offset: dynamic /* typealias Vector = dynamic */ + get() = definedExternally + set(value) = definedExternally + var position: Position? + get() = definedExternally + set(value) = definedExternally +} + +typealias MouseButtonFlagsTable = Any + +typealias MouseButtonFlagsArray = Array + +external interface ItemStackLocation { + var inventory: inventory + var slot: uint +} + +external interface VehicleAutomaticTargetingParameters { + var auto_target_without_gunner: Boolean + var auto_target_with_gunner: Boolean +} + +external interface BaseItemPrototypeFilter { + var filter: String /* "tool" | "mergeable" | "item-with-inventory" | "selection-tool" | "item-with-label" | "has-rocket-launch-products" | "fuel" | "place-result" | "burnt-result" | "place-as-tile" | "placed-as-equipment-result" | "name" | "type" | "flag" | "subgroup" | "fuel-category" | "stack-size" | "default-request-amount" | "wire-count" | "fuel-value" | "fuel-acceleration-multiplier" | "fuel-top-speed-multiplier" | "fuel-emissions-multiplier" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface PlaceResultItemPrototypeFilter : BaseItemPrototypeFilter { + override var filter: String /* "place-result" */ + var elem_filters: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface BurntResultItemPrototypeFilter : BaseItemPrototypeFilter { + override var filter: String /* "burnt-result" */ + var elem_filters: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface PlaceAsTileItemPrototypeFilter : BaseItemPrototypeFilter { + override var filter: String /* "place-as-tile" */ + var elem_filters: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface PlacedAsEquipmentResultItemPrototypeFilter : BaseItemPrototypeFilter { + override var filter: String /* "placed-as-equipment-result" */ + var elem_filters: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface NameItemPrototypeFilter : BaseItemPrototypeFilter { + override var filter: String /* "name" */ + var name: dynamic /* String | Array */ + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeItemPrototypeFilter : BaseItemPrototypeFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface FlagItemPrototypeFilter : BaseItemPrototypeFilter { + override var filter: String /* "flag" */ + var flag: String +} + +external interface SubgroupItemPrototypeFilter : BaseItemPrototypeFilter { + override var filter: String /* "subgroup" */ + var subgroup: String +} + +external interface FuelCategoryItemPrototypeFilter : BaseItemPrototypeFilter { + @nativeGetter + operator fun get(key: String): String? + @nativeSetter + operator fun set(key: String, value: String) + override var filter: String /* "fuel-category" */ +} + +external interface StackSizeItemPrototypeFilter : BaseItemPrototypeFilter { + override var filter: String /* "stack-size" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: uint +} + +external interface DefaultRequestAmountItemPrototypeFilter : BaseItemPrototypeFilter { + override var filter: String /* "default-request-amount" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: uint +} + +external interface WireCountItemPrototypeFilter : BaseItemPrototypeFilter { + override var filter: String /* "wire-count" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: uint +} + +external interface FuelValueItemPrototypeFilter : BaseItemPrototypeFilter { + override var filter: String /* "fuel-value" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface FuelAccelerationMultiplierItemPrototypeFilter : BaseItemPrototypeFilter { + override var filter: String /* "fuel-acceleration-multiplier" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface FuelTopSpeedMultiplierItemPrototypeFilter : BaseItemPrototypeFilter { + override var filter: String /* "fuel-top-speed-multiplier" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface FuelEmissionsMultiplierItemPrototypeFilter : BaseItemPrototypeFilter { + override var filter: String /* "fuel-emissions-multiplier" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface OtherItemPrototypeFilter : BaseItemPrototypeFilter { + override var filter: String /* "tool" | "mergeable" | "item-with-inventory" | "selection-tool" | "item-with-label" | "has-rocket-launch-products" | "fuel" */ +} + +external interface BaseModSettingPrototypeFilter { + var filter: String /* "type" | "mod" | "setting-type" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeModSettingPrototypeFilter : BaseModSettingPrototypeFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface ModModSettingPrototypeFilter : BaseModSettingPrototypeFilter { + override var filter: String /* "mod" */ + var mod: String +} + +external interface SettingTypeModSettingPrototypeFilter : BaseModSettingPrototypeFilter { + override var filter: String /* "setting-type" */ + var type: String +} + +external interface BaseTechnologyPrototypeFilter { + var filter: String /* "enabled" | "hidden" | "upgrade" | "visible-when-disabled" | "has-effects" | "has-prerequisites" | "research-unit-ingredient" | "level" | "max-level" | "time" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResearchUnitIngredientTechnologyPrototypeFilter : BaseTechnologyPrototypeFilter { + override var filter: String /* "research-unit-ingredient" */ + var ingredient: String +} + +external interface LevelTechnologyPrototypeFilter : BaseTechnologyPrototypeFilter { + override var filter: String /* "level" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: uint +} + +external interface MaxLevelTechnologyPrototypeFilter : BaseTechnologyPrototypeFilter { + override var filter: String /* "max-level" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: uint +} + +external interface TimeTechnologyPrototypeFilter : BaseTechnologyPrototypeFilter { + override var filter: String /* "time" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: uint +} + +external interface OtherTechnologyPrototypeFilter : BaseTechnologyPrototypeFilter { + override var filter: String /* "enabled" | "hidden" | "upgrade" | "visible-when-disabled" | "has-effects" | "has-prerequisites" */ +} + +external interface BaseDecorativePrototypeFilter { + var filter: String /* "decal" | "autoplace" | "collision-mask" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface CollisionMaskDecorativePrototypeFilter : BaseDecorativePrototypeFilter { + override var filter: String /* "collision-mask" */ + var mask: dynamic /* CollisionMask | CollisionMaskWithFlags */ + get() = definedExternally + set(value) = definedExternally + var mask_mode: String /* "collides" | "layers-equals" */ +} + +external interface OtherDecorativePrototypeFilter : BaseDecorativePrototypeFilter { + override var filter: String /* "decal" | "autoplace" */ +} + +external interface BaseAchievementPrototypeFilter { + var filter: String /* "allowed-without-fight" | "type" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeAchievementPrototypeFilter : BaseAchievementPrototypeFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface OtherAchievementPrototypeFilter : BaseAchievementPrototypeFilter { + override var filter: String /* "allowed-without-fight" */ +} + +external interface BaseFluidPrototypeFilter { + var filter: String /* "hidden" | "name" | "subgroup" | "default-temperature" | "max-temperature" | "heat-capacity" | "fuel-value" | "emissions-multiplier" | "gas-temperature" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface NameFluidPrototypeFilter : BaseFluidPrototypeFilter { + override var filter: String /* "name" */ + var name: dynamic /* String | Array */ + get() = definedExternally + set(value) = definedExternally +} + +external interface SubgroupFluidPrototypeFilter : BaseFluidPrototypeFilter { + override var filter: String /* "subgroup" */ + var subgroup: String +} + +external interface DefaultTemperatureFluidPrototypeFilter : BaseFluidPrototypeFilter { + override var filter: String /* "default-temperature" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface MaxTemperatureFluidPrototypeFilter : BaseFluidPrototypeFilter { + override var filter: String /* "max-temperature" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface HeatCapacityFluidPrototypeFilter : BaseFluidPrototypeFilter { + override var filter: String /* "heat-capacity" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface FuelValueFluidPrototypeFilter : BaseFluidPrototypeFilter { + override var filter: String /* "fuel-value" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface EmissionsMultiplierFluidPrototypeFilter : BaseFluidPrototypeFilter { + override var filter: String /* "emissions-multiplier" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface GasTemperatureFluidPrototypeFilter : BaseFluidPrototypeFilter { + override var filter: String /* "gas-temperature" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface OtherFluidPrototypeFilter : BaseFluidPrototypeFilter { + override var filter: String /* "hidden" */ +} + +external interface BaseEquipmentPrototypeFilter { + var filter: String /* "item-to-place" | "type" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeEquipmentPrototypeFilter : BaseEquipmentPrototypeFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface OtherEquipmentPrototypeFilter : BaseEquipmentPrototypeFilter { + override var filter: String /* "item-to-place" */ +} + +external interface BaseTilePrototypeFilter { + var filter: String /* "minable" | "autoplace" | "blueprintable" | "item-to-place" | "collision-mask" | "walking-speed-modifier" | "vehicle-friction-modifier" | "decorative-removal-probability" | "emissions" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface CollisionMaskTilePrototypeFilter : BaseTilePrototypeFilter { + override var filter: String /* "collision-mask" */ + var mask: dynamic /* CollisionMask | CollisionMaskWithFlags */ + get() = definedExternally + set(value) = definedExternally + var mask_mode: String /* "collides" | "layers-equals" */ +} + +external interface WalkingSpeedModifierTilePrototypeFilter : BaseTilePrototypeFilter { + override var filter: String /* "walking-speed-modifier" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface VehicleFrictionModifierTilePrototypeFilter : BaseTilePrototypeFilter { + override var filter: String /* "vehicle-friction-modifier" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface DecorativeRemovalProbabilityTilePrototypeFilter : BaseTilePrototypeFilter { + override var filter: String /* "decorative-removal-probability" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: float +} + +external interface EmissionsTilePrototypeFilter : BaseTilePrototypeFilter { + override var filter: String /* "emissions" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface OtherTilePrototypeFilter : BaseTilePrototypeFilter { + override var filter: String /* "minable" | "autoplace" | "blueprintable" | "item-to-place" */ +} + +external interface BaseRecipePrototypeFilter { + var filter: String /* "enabled" | "hidden" | "hidden-from-flow-stats" | "hidden-from-player-crafting" | "allow-as-intermediate" | "allow-intermediates" | "allow-decomposition" | "always-show-made-in" | "always-show-products" | "show-amount-in-title" | "has-ingredients" | "has-products" | "has-ingredient-item" | "has-ingredient-fluid" | "has-product-item" | "has-product-fluid" | "subgroup" | "category" | "energy" | "emissions-multiplier" | "request-paste-multiplier" | "overload-multiplier" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface HasIngredientItemRecipePrototypeFilter : BaseRecipePrototypeFilter { + override var filter: String /* "has-ingredient-item" */ + var elem_filters: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface HasIngredientFluidRecipePrototypeFilter : BaseRecipePrototypeFilter { + override var filter: String /* "has-ingredient-fluid" */ + var elem_filters: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface HasProductItemRecipePrototypeFilter : BaseRecipePrototypeFilter { + override var filter: String /* "has-product-item" */ + var elem_filters: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface HasProductFluidRecipePrototypeFilter : BaseRecipePrototypeFilter { + override var filter: String /* "has-product-fluid" */ + var elem_filters: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface SubgroupRecipePrototypeFilter : BaseRecipePrototypeFilter { + override var filter: String /* "subgroup" */ + var subgroup: String +} + +external interface CategoryRecipePrototypeFilter : BaseRecipePrototypeFilter { + override var filter: String /* "category" */ + var category: String +} + +external interface EnergyRecipePrototypeFilter : BaseRecipePrototypeFilter { + override var filter: String /* "energy" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface EmissionsMultiplierRecipePrototypeFilter : BaseRecipePrototypeFilter { + override var filter: String /* "emissions-multiplier" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface RequestPasteMultiplierRecipePrototypeFilter : BaseRecipePrototypeFilter { + override var filter: String /* "request-paste-multiplier" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: uint +} + +external interface OverloadMultiplierRecipePrototypeFilter : BaseRecipePrototypeFilter { + override var filter: String /* "overload-multiplier" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: uint +} + +external interface OtherRecipePrototypeFilter : BaseRecipePrototypeFilter { + override var filter: String /* "enabled" | "hidden" | "hidden-from-flow-stats" | "hidden-from-player-crafting" | "allow-as-intermediate" | "allow-intermediates" | "allow-decomposition" | "always-show-made-in" | "always-show-products" | "show-amount-in-title" | "has-ingredients" | "has-products" */ +} + +external interface BaseEntityPrototypeFilter { + var filter: String /* "flying-robot" | "robot-with-logistics-interface" | "rail" | "ghost" | "explosion" | "vehicle" | "crafting-machine" | "rolling-stock" | "turret" | "transport-belt-connectable" | "wall-connectable" | "buildable" | "placable-in-editor" | "clonable" | "selectable" | "hidden" | "entity-with-health" | "building" | "fast-replaceable" | "uses-direction" | "minable" | "circuit-connectable" | "autoplace" | "blueprintable" | "item-to-place" | "name" | "type" | "collision-mask" | "flag" | "build-base-evolution-requirement" | "selection-priority" | "emissions" | "crafting-category" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface NameEntityPrototypeFilter : BaseEntityPrototypeFilter { + override var filter: String /* "name" */ + var name: dynamic /* String | Array */ + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeEntityPrototypeFilter : BaseEntityPrototypeFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface CollisionMaskEntityPrototypeFilter : BaseEntityPrototypeFilter { + override var filter: String /* "collision-mask" */ + var mask: dynamic /* CollisionMask | CollisionMaskWithFlags */ + get() = definedExternally + set(value) = definedExternally + var mask_mode: String /* "collides" | "layers-equals" */ +} + +external interface FlagEntityPrototypeFilter : BaseEntityPrototypeFilter { + override var filter: String /* "flag" */ + var flag: String +} + +external interface BuildBaseEvolutionRequirementEntityPrototypeFilter : BaseEntityPrototypeFilter { + override var filter: String /* "build-base-evolution-requirement" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface SelectionPriorityEntityPrototypeFilter : BaseEntityPrototypeFilter { + override var filter: String /* "selection-priority" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: uint8 +} + +external interface EmissionsEntityPrototypeFilter : BaseEntityPrototypeFilter { + override var filter: String /* "emissions" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: double +} + +external interface CraftingCategoryEntityPrototypeFilter : BaseEntityPrototypeFilter { + override var filter: String /* "crafting-category" */ + var crafting_category: String +} + +external interface OtherEntityPrototypeFilter : BaseEntityPrototypeFilter { + override var filter: String /* "flying-robot" | "robot-with-logistics-interface" | "rail" | "ghost" | "explosion" | "vehicle" | "crafting-machine" | "rolling-stock" | "turret" | "transport-belt-connectable" | "wall-connectable" | "buildable" | "placable-in-editor" | "clonable" | "selectable" | "hidden" | "entity-with-health" | "building" | "fast-replaceable" | "uses-direction" | "minable" | "circuit-connectable" | "autoplace" | "blueprintable" | "item-to-place" */ +} + +external interface BaseScriptRaisedReviveEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeScriptRaisedReviveEventFilter : BaseScriptRaisedReviveEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NameScriptRaisedReviveEventFilter : BaseScriptRaisedReviveEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypeScriptRaisedReviveEventFilter : BaseScriptRaisedReviveEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNameScriptRaisedReviveEventFilter : BaseScriptRaisedReviveEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OtherScriptRaisedReviveEventFilter : BaseScriptRaisedReviveEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BaseEntityDiedEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeEntityDiedEventFilter : BaseEntityDiedEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NameEntityDiedEventFilter : BaseEntityDiedEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypeEntityDiedEventFilter : BaseEntityDiedEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNameEntityDiedEventFilter : BaseEntityDiedEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OtherEntityDiedEventFilter : BaseEntityDiedEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BaseEntityMarkedForDeconstructionEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeEntityMarkedForDeconstructionEventFilter : BaseEntityMarkedForDeconstructionEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NameEntityMarkedForDeconstructionEventFilter : BaseEntityMarkedForDeconstructionEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypeEntityMarkedForDeconstructionEventFilter : BaseEntityMarkedForDeconstructionEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNameEntityMarkedForDeconstructionEventFilter : BaseEntityMarkedForDeconstructionEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OtherEntityMarkedForDeconstructionEventFilter : BaseEntityMarkedForDeconstructionEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BasePreGhostDeconstructedEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypePreGhostDeconstructedEventFilter : BasePreGhostDeconstructedEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NamePreGhostDeconstructedEventFilter : BasePreGhostDeconstructedEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypePreGhostDeconstructedEventFilter : BasePreGhostDeconstructedEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNamePreGhostDeconstructedEventFilter : BasePreGhostDeconstructedEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OtherPreGhostDeconstructedEventFilter : BasePreGhostDeconstructedEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BaseScriptRaisedDestroyEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeScriptRaisedDestroyEventFilter : BaseScriptRaisedDestroyEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NameScriptRaisedDestroyEventFilter : BaseScriptRaisedDestroyEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypeScriptRaisedDestroyEventFilter : BaseScriptRaisedDestroyEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNameScriptRaisedDestroyEventFilter : BaseScriptRaisedDestroyEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OtherScriptRaisedDestroyEventFilter : BaseScriptRaisedDestroyEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BaseUpgradeCancelledEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeUpgradeCancelledEventFilter : BaseUpgradeCancelledEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NameUpgradeCancelledEventFilter : BaseUpgradeCancelledEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypeUpgradeCancelledEventFilter : BaseUpgradeCancelledEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNameUpgradeCancelledEventFilter : BaseUpgradeCancelledEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OtherUpgradeCancelledEventFilter : BaseUpgradeCancelledEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BasePlayerRepairedEntityEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypePlayerRepairedEntityEventFilter : BasePlayerRepairedEntityEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NamePlayerRepairedEntityEventFilter : BasePlayerRepairedEntityEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypePlayerRepairedEntityEventFilter : BasePlayerRepairedEntityEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNamePlayerRepairedEntityEventFilter : BasePlayerRepairedEntityEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OtherPlayerRepairedEntityEventFilter : BasePlayerRepairedEntityEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BaseEntityMarkedForUpgradeEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeEntityMarkedForUpgradeEventFilter : BaseEntityMarkedForUpgradeEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NameEntityMarkedForUpgradeEventFilter : BaseEntityMarkedForUpgradeEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypeEntityMarkedForUpgradeEventFilter : BaseEntityMarkedForUpgradeEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNameEntityMarkedForUpgradeEventFilter : BaseEntityMarkedForUpgradeEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OtherEntityMarkedForUpgradeEventFilter : BaseEntityMarkedForUpgradeEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BasePostEntityDiedEventFilter { + var filter: String /* "type" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypePostEntityDiedEventFilter : BasePostEntityDiedEventFilter { + override var filter: String /* "type" */ + var type: String +} + +typealias LuaPostEntityDiedEventFilter = TypePostEntityDiedEventFilter + +external interface BasePreRobotMinedEntityEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypePreRobotMinedEntityEventFilter : BasePreRobotMinedEntityEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NamePreRobotMinedEntityEventFilter : BasePreRobotMinedEntityEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypePreRobotMinedEntityEventFilter : BasePreRobotMinedEntityEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNamePreRobotMinedEntityEventFilter : BasePreRobotMinedEntityEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OtherPreRobotMinedEntityEventFilter : BasePreRobotMinedEntityEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BaseEntityClonedEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeEntityClonedEventFilter : BaseEntityClonedEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NameEntityClonedEventFilter : BaseEntityClonedEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypeEntityClonedEventFilter : BaseEntityClonedEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNameEntityClonedEventFilter : BaseEntityClonedEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OtherEntityClonedEventFilter : BaseEntityClonedEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BaseScriptRaisedBuiltEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeScriptRaisedBuiltEventFilter : BaseScriptRaisedBuiltEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NameScriptRaisedBuiltEventFilter : BaseScriptRaisedBuiltEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypeScriptRaisedBuiltEventFilter : BaseScriptRaisedBuiltEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNameScriptRaisedBuiltEventFilter : BaseScriptRaisedBuiltEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OtherScriptRaisedBuiltEventFilter : BaseScriptRaisedBuiltEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BaseRobotMinedEntityEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeRobotMinedEntityEventFilter : BaseRobotMinedEntityEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NameRobotMinedEntityEventFilter : BaseRobotMinedEntityEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypeRobotMinedEntityEventFilter : BaseRobotMinedEntityEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNameRobotMinedEntityEventFilter : BaseRobotMinedEntityEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OtherRobotMinedEntityEventFilter : BaseRobotMinedEntityEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BasePrePlayerMinedEntityEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypePrePlayerMinedEntityEventFilter : BasePrePlayerMinedEntityEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NamePrePlayerMinedEntityEventFilter : BasePrePlayerMinedEntityEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypePrePlayerMinedEntityEventFilter : BasePrePlayerMinedEntityEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNamePrePlayerMinedEntityEventFilter : BasePrePlayerMinedEntityEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OtherPrePlayerMinedEntityEventFilter : BasePrePlayerMinedEntityEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BaseRobotBuiltEntityEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" | "force" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeRobotBuiltEntityEventFilter : BaseRobotBuiltEntityEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NameRobotBuiltEntityEventFilter : BaseRobotBuiltEntityEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypeRobotBuiltEntityEventFilter : BaseRobotBuiltEntityEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNameRobotBuiltEntityEventFilter : BaseRobotBuiltEntityEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface ForceRobotBuiltEntityEventFilter : BaseRobotBuiltEntityEventFilter { + override var filter: String /* "force" */ + var force: String +} + +external interface OtherRobotBuiltEntityEventFilter : BaseRobotBuiltEntityEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BaseEntityDeconstructionCancelledEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeEntityDeconstructionCancelledEventFilter : BaseEntityDeconstructionCancelledEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NameEntityDeconstructionCancelledEventFilter : BaseEntityDeconstructionCancelledEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypeEntityDeconstructionCancelledEventFilter : BaseEntityDeconstructionCancelledEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNameEntityDeconstructionCancelledEventFilter : BaseEntityDeconstructionCancelledEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OtherEntityDeconstructionCancelledEventFilter : BaseEntityDeconstructionCancelledEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BasePlayerBuiltEntityEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" | "force" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypePlayerBuiltEntityEventFilter : BasePlayerBuiltEntityEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NamePlayerBuiltEntityEventFilter : BasePlayerBuiltEntityEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypePlayerBuiltEntityEventFilter : BasePlayerBuiltEntityEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNamePlayerBuiltEntityEventFilter : BasePlayerBuiltEntityEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface ForcePlayerBuiltEntityEventFilter : BasePlayerBuiltEntityEventFilter { + override var filter: String /* "force" */ + var force: String +} + +external interface OtherPlayerBuiltEntityEventFilter : BasePlayerBuiltEntityEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BasePlayerMinedEntityEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypePlayerMinedEntityEventFilter : BasePlayerMinedEntityEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NamePlayerMinedEntityEventFilter : BasePlayerMinedEntityEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypePlayerMinedEntityEventFilter : BasePlayerMinedEntityEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNamePlayerMinedEntityEventFilter : BasePlayerMinedEntityEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OtherPlayerMinedEntityEventFilter : BasePlayerMinedEntityEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BaseEntityDamagedEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" | "original-damage-amount" | "final-damage-amount" | "damage-type" | "final-health" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeEntityDamagedEventFilter : BaseEntityDamagedEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NameEntityDamagedEventFilter : BaseEntityDamagedEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypeEntityDamagedEventFilter : BaseEntityDamagedEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNameEntityDamagedEventFilter : BaseEntityDamagedEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OriginalDamageAmountEntityDamagedEventFilter : BaseEntityDamagedEventFilter { + override var filter: String /* "original-damage-amount" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: float +} + +external interface FinalDamageAmountEntityDamagedEventFilter : BaseEntityDamagedEventFilter { + override var filter: String /* "final-damage-amount" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: float +} + +external interface DamageTypeEntityDamagedEventFilter : BaseEntityDamagedEventFilter { + override var filter: String /* "damage-type" */ + var type: String +} + +external interface FinalHealthEntityDamagedEventFilter : BaseEntityDamagedEventFilter { + override var filter: String /* "final-health" */ + var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ + var value: float +} + +external interface OtherEntityDamagedEventFilter : BaseEntityDamagedEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface BaseSectorScannedEventFilter { + var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ + var mode: String? /* "or" | "and" */ + get() = definedExternally + set(value) = definedExternally + var invert: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeSectorScannedEventFilter : BaseSectorScannedEventFilter { + override var filter: String /* "type" */ + var type: String +} + +external interface NameSectorScannedEventFilter : BaseSectorScannedEventFilter { + override var filter: String /* "name" */ + var name: String +} + +external interface GhostTypeSectorScannedEventFilter : BaseSectorScannedEventFilter { + override var filter: String /* "ghost_type" */ + var type: String +} + +external interface GhostNameSectorScannedEventFilter : BaseSectorScannedEventFilter { + override var filter: String /* "ghost_name" */ + var name: String +} + +external interface OtherSectorScannedEventFilter : BaseSectorScannedEventFilter { + override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ +} + +external interface `T$87` { + var enabled: Boolean? + get() = definedExternally + set(value) = definedExternally + var diffusion_ratio: double? + get() = definedExternally + set(value) = definedExternally + var ageing: double? + get() = definedExternally + set(value) = definedExternally + var enemy_attack_pollution_consumption_modifier: double? + get() = definedExternally + set(value) = definedExternally + var min_pollution_to_damage_trees: double? + get() = definedExternally + set(value) = definedExternally + var pollution_restored_per_tree_damage: double? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$88` { + var enabled: Boolean? + get() = definedExternally + set(value) = definedExternally + var time_factor: double? + get() = definedExternally + set(value) = definedExternally + var destroy_factor: double? + get() = definedExternally + set(value) = definedExternally + var pollution_factor: double? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$89` { + var enabled: Boolean? + get() = definedExternally + set(value) = definedExternally + var max_expansion_distance: double? + get() = definedExternally + set(value) = definedExternally + var settler_group_min_size: double? + get() = definedExternally + set(value) = definedExternally + var settler_group_max_size: double? + get() = definedExternally + set(value) = definedExternally + var min_expansion_cooldown: double? + get() = definedExternally + set(value) = definedExternally + var max_expansion_cooldown: double? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$90` { + var recipe_difficulty: recipe_difficulty? + get() = definedExternally + set(value) = definedExternally + var technology_difficulty: technology_difficulty? + get() = definedExternally + set(value) = definedExternally + var technology_price_multiplier: double? + get() = definedExternally + set(value) = definedExternally + var research_queue_setting: String? /* "after-victory" | "always" | "never" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$91` { + var pollution: `T$87`? + get() = definedExternally + set(value) = definedExternally + var enemy_evolution: `T$88`? + get() = definedExternally + set(value) = definedExternally + var enemy_expansion: `T$89`? + get() = definedExternally + set(value) = definedExternally + var difficulty_settings: `T$90`? + get() = definedExternally + set(value) = definedExternally +} + +external interface MapGenPreset { + var order: String + var default: Boolean? + get() = definedExternally + set(value) = definedExternally + var basic_settings: MapGenSettingsPartial + var advanced_settings: `T$91` +} + +external interface BlueprintControlBehavior { + var condition: CircuitCondition? + get() = definedExternally + set(value) = definedExternally + var circuit_condition: CircuitCondition? + get() = definedExternally + set(value) = definedExternally + var filters: Array? + get() = definedExternally + set(value) = definedExternally + var is_on: Boolean? + get() = definedExternally + set(value) = definedExternally + var arithmetic_conditions: ArithmeticCombinatorParameters? + get() = definedExternally + set(value) = definedExternally + var decider_conditions: DeciderCombinatorParameters? + get() = definedExternally + set(value) = definedExternally + var circuit_enable_disable: Boolean? + get() = definedExternally + set(value) = definedExternally + var circuit_read_resources: Boolean? + get() = definedExternally + set(value) = definedExternally + var circuit_resource_read_mode: resource_read_mode? + get() = definedExternally + set(value) = definedExternally + var read_stopped_train: Boolean? + get() = definedExternally + set(value) = definedExternally + var train_stopped_signal: SignalID? + get() = definedExternally + set(value) = definedExternally + var read_from_train: Boolean? + get() = definedExternally + set(value) = definedExternally + var send_to_train: Boolean? + get() = definedExternally + set(value) = definedExternally + var circuit_mode_of_operation: Number? + get() = definedExternally + set(value) = definedExternally + var circuit_read_hand_contents: Boolean? + get() = definedExternally + set(value) = definedExternally + var circuit_hand_read_mode: hand_read_mode? + get() = definedExternally + set(value) = definedExternally + var circuit_set_stack_size: Boolean? + get() = definedExternally + set(value) = definedExternally + var stack_control_input_signal: SignalID? + get() = definedExternally + set(value) = definedExternally + var use_colors: Boolean? + get() = definedExternally + set(value) = definedExternally + var read_robot_stats: Boolean? + get() = definedExternally + set(value) = definedExternally + var read_logistics: Boolean? + get() = definedExternally + set(value) = definedExternally + var available_logistic_output_signal: Boolean? + get() = definedExternally + set(value) = definedExternally + var total_logistic_output_signal: Boolean? + get() = definedExternally + set(value) = definedExternally + var available_construction_output_signal: Boolean? + get() = definedExternally + set(value) = definedExternally + var total_construction_output_signal: Boolean? + get() = definedExternally + set(value) = definedExternally + var circuit_contents_read_mode: content_read_mode? + get() = definedExternally + set(value) = definedExternally + var output_signal: SignalID? + get() = definedExternally + set(value) = definedExternally + var circuit_close_signal: Boolean? + get() = definedExternally + set(value) = definedExternally + var circuit_read_signal: Boolean? + get() = definedExternally + set(value) = definedExternally + var red_output_signal: SignalID? + get() = definedExternally + set(value) = definedExternally + var orange_output_signal: SignalID? + get() = definedExternally + set(value) = definedExternally + var green_output_signal: SignalID? + get() = definedExternally + set(value) = definedExternally + var blue_output_signal: SignalID? + get() = definedExternally + set(value) = definedExternally + var circuit_open_gate: Boolean? + get() = definedExternally + set(value) = definedExternally + var circuit_read_sensor: Boolean? + get() = definedExternally + set(value) = definedExternally + var circuit_parameters: ProgrammableSpeakerCircuitParameters? + get() = definedExternally + set(value) = definedExternally +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/coroutine.coroutine.module_lua-types.kt b/modules/mod2/dukat-custom/coroutine.coroutine.module_lua-types.kt new file mode 100644 index 0000000..2228c85 --- /dev/null +++ b/modules/mod2/dukat-custom/coroutine.coroutine.module_lua-types.kt @@ -0,0 +1,30 @@ +@file:JsQualifier("coroutine") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package coroutine + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import LuaThread + +external fun create(f: (args: Any) -> Any): LuaThread + +external fun resume(co: LuaThread, vararg param_val: Any): dynamic /* JsTuple | JsTuple */ + +external fun status(co: LuaThread): String /* "running" | "suspended" | "normal" | "dead" */ + +external fun wrap(f: (args: Any) -> Any): (args: Any) -> Array + +external fun yield(vararg args: Any): Array /* Array & LuaExtension */ + +external fun running(): dynamic /* JsTuple */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/debug.debug.module_lua-types.kt b/modules/mod2/dukat-custom/debug.debug.module_lua-types.kt new file mode 100644 index 0000000..7068d82 --- /dev/null +++ b/modules/mod2/dukat-custom/debug.debug.module_lua-types.kt @@ -0,0 +1,162 @@ +@file:JsQualifier("debug") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package debug + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import LuaThread +import LuaMetatable__1 +import tsstdlib.Record +import LuaUserdata +import LuaMetatable + +external fun debug() + +external fun gethook(thread: LuaThread = definedExternally): dynamic /* JsTuple | JsTuple, Number, Any> */ + +external interface FunctionInfo> { + var nparams: Number + var isvararg: Boolean + var istailcall: Boolean + var func: T + var name: String? + get() = definedExternally + set(value) = definedExternally + var namewhat: String /* "global" | "local" | "method" | "field" | "" */ + var source: String + var short_src: String + var linedefined: Number + var lastlinedefined: Number + var what: String /* "Lua" | "C" | "main" */ + var currentline: Number + var nups: Number +} + +external interface FunctionInfoPartial> { + var nparams: Number? + get() = definedExternally + set(value) = definedExternally + var isvararg: Boolean? + get() = definedExternally + set(value) = definedExternally + var istailcall: Boolean? + get() = definedExternally + set(value) = definedExternally + var func: T? + get() = definedExternally + set(value) = definedExternally + var name: String? + get() = definedExternally + set(value) = definedExternally + var namewhat: String? /* "global" | "local" | "method" | "field" | "" */ + get() = definedExternally + set(value) = definedExternally + var source: String? + get() = definedExternally + set(value) = definedExternally + var short_src: String? + get() = definedExternally + set(value) = definedExternally + var linedefined: Number? + get() = definedExternally + set(value) = definedExternally + var lastlinedefined: Number? + get() = definedExternally + set(value) = definedExternally + var what: String? /* "Lua" | "C" | "main" */ + get() = definedExternally + set(value) = definedExternally + var currentline: Number? + get() = definedExternally + set(value) = definedExternally + var nups: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface FunctionInfo__0 : FunctionInfo> + +external interface FunctionInfo__0Partial : FunctionInfoPartial> + +external fun > getinfo(f: T): FunctionInfo + +external fun > getinfo(f: T, what: String): FunctionInfoPartial + +external fun > getinfo(thread: LuaThread, f: T): FunctionInfo + +external fun > getinfo(thread: LuaThread, f: T, what: String): FunctionInfoPartial + +external fun getinfo(f: Number): FunctionInfo__0? + +external fun getinfo(f: Number, what: String): FunctionInfo__0Partial? + +external fun getinfo(thread: LuaThread, f: Number): FunctionInfo__0? + +external fun getinfo(thread: LuaThread, f: Number, what: String): FunctionInfo__0Partial? + +external fun getmetatable(value: T): LuaMetatable__1? + +external fun getregistry(): Record + +external fun getupvalue(f: Function<*>, up: Number): dynamic /* JsTuple | JsTuple<> */ + +external fun getuservalue(u: LuaUserdata): Any + +external fun sethook() + +external fun sethook(hook: (event: String /* "call" | "return" | "line" | "count" */, line: Number) -> Any, mask: String, count: Number = definedExternally) + +external fun sethook(hook: (event: String /* "call" | "return" | "line" | "count" */, line: Number) -> Any, mask: String) + +external fun sethook(thread: LuaThread, hook: (event: String /* "call" | "return" | "line" | "count" */, line: Number) -> Any, mask: String, count: Number = definedExternally) + +external fun sethook(thread: LuaThread, hook: (event: String /* "call" | "return" | "line" | "count" */, line: Number) -> Any, mask: String) + +external fun setlocal(level: Number, local: Number, value: Any): String? + +external fun setlocal(thread: LuaThread, level: Number, local: Number, value: Any): String? + +external fun setmetatable(value: T, table: LuaMetatable? = definedExternally): Any + +external fun setupvalue(f: Function<*>, up: Number, value: Any): String? + +external fun setuservalue(udata: LuaUserdata, value: Any): LuaUserdata + +external fun traceback(message: String? = definedExternally, level: Number? = definedExternally): String + +external fun traceback(): String + +external fun traceback(message: String? = definedExternally): String + +external fun traceback(thread: LuaThread = definedExternally, message: String? = definedExternally, level: Number? = definedExternally): String + +external fun traceback(thread: LuaThread = definedExternally): String + +external fun traceback(thread: LuaThread = definedExternally, message: String? = definedExternally): String + +external fun traceback(message: T): T + +external fun traceback(thread: LuaThread, message: T): T + +external fun getlocal(f: Function<*>, local: Number): dynamic /* JsTuple */ + +external fun getlocal(f: Number, local: Number): dynamic /* JsTuple */ + +external fun getlocal(thread: LuaThread, f: Function<*>, local: Number): dynamic /* JsTuple */ + +external fun getlocal(thread: LuaThread, f: Number, local: Number): dynamic /* JsTuple */ + +external fun upvalueid(f: Function<*>, n: Number): LuaUserdata + +external fun upvaluejoin(f1: Function<*>, n1: Number, f2: Function<*>, n2: Number) \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines.defines.control_behavior.inserter.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines.defines.control_behavior.inserter.module_typed-factorio.kt new file mode 100644 index 0000000..9a91be8 --- /dev/null +++ b/modules/mod2/dukat-custom/defines.defines.control_behavior.inserter.module_typed-factorio.kt @@ -0,0 +1,30 @@ +@file:JsQualifier("defines.control_behavior.inserter") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package defines.control_behavior.inserter + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external enum class circuit_mode_of_operation { + none, + enable_disable, + set_filters, + read_hand_contents, + set_stack_size +} + +external enum class hand_read_mode { + hold, + pulse +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines.defines.control_behavior.lamp.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines.defines.control_behavior.lamp.module_typed-factorio.kt new file mode 100644 index 0000000..4688694 --- /dev/null +++ b/modules/mod2/dukat-custom/defines.defines.control_behavior.lamp.module_typed-factorio.kt @@ -0,0 +1,21 @@ +@file:JsQualifier("defines.control_behavior.lamp") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package defines.control_behavior.lamp + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external enum class circuit_mode_of_operation { + use_colors +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines.defines.control_behavior.logistic_container.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines.defines.control_behavior.logistic_container.module_typed-factorio.kt new file mode 100644 index 0000000..e9a2d7a --- /dev/null +++ b/modules/mod2/dukat-custom/defines.defines.control_behavior.logistic_container.module_typed-factorio.kt @@ -0,0 +1,22 @@ +@file:JsQualifier("defines.control_behavior.logistic_container") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package defines.control_behavior.logistic_container + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external enum class circuit_mode_of_operation { + send_contents, + set_requests +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines.defines.control_behavior.mining_drill.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines.defines.control_behavior.mining_drill.module_typed-factorio.kt new file mode 100644 index 0000000..86c2231 --- /dev/null +++ b/modules/mod2/dukat-custom/defines.defines.control_behavior.mining_drill.module_typed-factorio.kt @@ -0,0 +1,22 @@ +@file:JsQualifier("defines.control_behavior.mining_drill") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package defines.control_behavior.mining_drill + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external enum class resource_read_mode { + this_miner, + entire_patch +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines.defines.control_behavior.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines.defines.control_behavior.module_typed-factorio.kt new file mode 100644 index 0000000..4c0ec5b --- /dev/null +++ b/modules/mod2/dukat-custom/defines.defines.control_behavior.module_typed-factorio.kt @@ -0,0 +1,38 @@ +@file:JsQualifier("defines.control_behavior") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package defines.control_behavior + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external enum class type { + container, + generic_on_off, + inserter, + lamp, + logistic_container, + roboport, + storage_tank, + train_stop, + decider_combinator, + arithmetic_combinator, + constant_combinator, + transport_belt, + accumulator, + rail_signal, + rail_chain_signal, + wall, + mining_drill, + programmable_speaker +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines.defines.control_behavior.transport_belt.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines.defines.control_behavior.transport_belt.module_typed-factorio.kt new file mode 100644 index 0000000..c78e4e7 --- /dev/null +++ b/modules/mod2/dukat-custom/defines.defines.control_behavior.transport_belt.module_typed-factorio.kt @@ -0,0 +1,22 @@ +@file:JsQualifier("defines.control_behavior.transport_belt") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package defines.control_behavior.transport_belt + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external enum class content_read_mode { + pulse, + hold +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines.defines.deconstruction_item.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines.defines.deconstruction_item.module_typed-factorio.kt new file mode 100644 index 0000000..26ee0cc --- /dev/null +++ b/modules/mod2/dukat-custom/defines.defines.deconstruction_item.module_typed-factorio.kt @@ -0,0 +1,34 @@ +@file:JsQualifier("defines.deconstruction_item") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package defines.deconstruction_item + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external enum class entity_filter_mode { + whitelist, + blacklist +} + +external enum class tile_filter_mode { + whitelist, + blacklist +} + +external enum class tile_selection_mode { + normal, + always, + never, + only +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines.defines.difficulty_settings.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines.defines.difficulty_settings.module_typed-factorio.kt new file mode 100644 index 0000000..bc978a6 --- /dev/null +++ b/modules/mod2/dukat-custom/defines.defines.difficulty_settings.module_typed-factorio.kt @@ -0,0 +1,27 @@ +@file:JsQualifier("defines.difficulty_settings") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package defines.difficulty_settings + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external enum class recipe_difficulty { + normal, + expensive +} + +external enum class technology_difficulty { + normal, + expensive +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines.defines.events.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines.defines.events.module_typed-factorio.kt new file mode 100644 index 0000000..948e6bc --- /dev/null +++ b/modules/mod2/dukat-custom/defines.defines.events.module_typed-factorio.kt @@ -0,0 +1,364 @@ +@file:JsQualifier("defines.events") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package defines.events + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import uint + +external var on_tick: uint /* uint & `T$93` */ + +external var on_gui_click: uint /* uint & `T$93` */ + +external var on_gui_confirmed: uint /* uint & `T$93` */ + +external var on_gui_text_changed: uint /* uint & `T$93` */ + +external var on_gui_checked_state_changed: uint /* uint & `T$93` */ + +external var on_entity_died: uint /* uint & `T$93` */ + +external var on_post_entity_died: uint /* uint & `T$93` */ + +external var on_entity_damaged: uint /* uint & `T$93` */ + +external var on_picked_up_item: uint /* uint & `T$93` */ + +external var on_built_entity: uint /* uint & `T$93` */ + +external var on_sector_scanned: uint /* uint & `T$93` */ + +external var on_player_mined_item: uint /* uint & `T$93` */ + +external var on_pre_build: uint /* uint & `T$93` */ + +external var on_rocket_launched: uint /* uint & `T$93` */ + +external var on_pre_player_mined_item: uint /* uint & `T$93` */ + +external var on_chunk_generated: uint /* uint & `T$93` */ + +external var on_player_crafted_item: uint /* uint & `T$93` */ + +external var on_robot_built_entity: uint /* uint & `T$93` */ + +external var on_robot_pre_mined: uint /* uint & `T$93` */ + +external var on_robot_mined: uint /* uint & `T$93` */ + +external var on_research_started: uint /* uint & `T$93` */ + +external var on_research_finished: uint /* uint & `T$93` */ + +external var on_research_reversed: uint /* uint & `T$93` */ + +external var on_player_rotated_entity: uint /* uint & `T$93` */ + +external var on_marked_for_deconstruction: uint /* uint & `T$93` */ + +external var on_cancelled_deconstruction: uint /* uint & `T$93` */ + +external var on_trigger_created_entity: uint /* uint & `T$93` */ + +external var on_trigger_fired_artillery: uint /* uint & `T$93` */ + +external var on_train_changed_state: uint /* uint & `T$93` */ + +external var on_player_created: uint /* uint & `T$93` */ + +external var on_resource_depleted: uint /* uint & `T$93` */ + +external var on_player_driving_changed_state: uint /* uint & `T$93` */ + +external var on_force_created: uint /* uint & `T$93` */ + +external var on_forces_merging: uint /* uint & `T$93` */ + +external var on_player_cursor_stack_changed: uint /* uint & `T$93` */ + +external var on_pre_entity_settings_pasted: uint /* uint & `T$93` */ + +external var on_entity_settings_pasted: uint /* uint & `T$93` */ + +external var on_player_main_inventory_changed: uint /* uint & `T$93` */ + +external var on_player_armor_inventory_changed: uint /* uint & `T$93` */ + +external var on_player_ammo_inventory_changed: uint /* uint & `T$93` */ + +external var on_player_gun_inventory_changed: uint /* uint & `T$93` */ + +external var on_player_placed_equipment: uint /* uint & `T$93` */ + +external var on_player_removed_equipment: uint /* uint & `T$93` */ + +external var on_pre_player_died: uint /* uint & `T$93` */ + +external var on_player_died: uint /* uint & `T$93` */ + +external var on_player_respawned: uint /* uint & `T$93` */ + +external var on_player_joined_game: uint /* uint & `T$93` */ + +external var on_player_left_game: uint /* uint & `T$93` */ + +external var on_player_built_tile: uint /* uint & `T$93` */ + +external var on_player_mined_tile: uint /* uint & `T$93` */ + +external var on_robot_built_tile: uint /* uint & `T$93` */ + +external var on_robot_mined_tile: uint /* uint & `T$93` */ + +external var on_player_selected_area: uint /* uint & `T$93` */ + +external var on_player_alt_selected_area: uint /* uint & `T$93` */ + +external var on_player_changed_surface: uint /* uint & `T$93` */ + +external var on_selected_entity_changed: uint /* uint & `T$93` */ + +external var on_market_item_purchased: uint /* uint & `T$93` */ + +external var on_player_dropped_item: uint /* uint & `T$93` */ + +external var on_biter_base_built: uint /* uint & `T$93` */ + +external var on_player_changed_force: uint /* uint & `T$93` */ + +external var on_entity_renamed: uint /* uint & `T$93` */ + +external var on_gui_selection_state_changed: uint /* uint & `T$93` */ + +external var on_runtime_mod_setting_changed: uint /* uint & `T$93` */ + +external var on_difficulty_settings_changed: uint /* uint & `T$93` */ + +external var on_surface_created: uint /* uint & `T$93` */ + +external var on_surface_deleted: uint /* uint & `T$93` */ + +external var on_pre_surface_deleted: uint /* uint & `T$93` */ + +external var on_player_mined_entity: uint /* uint & `T$93` */ + +external var on_robot_mined_entity: uint /* uint & `T$93` */ + +external var on_train_created: uint /* uint & `T$93` */ + +external var on_gui_elem_changed: uint /* uint & `T$93` */ + +external var on_player_setup_blueprint: uint /* uint & `T$93` */ + +external var on_player_deconstructed_area: uint /* uint & `T$93` */ + +external var on_player_configured_blueprint: uint /* uint & `T$93` */ + +external var on_console_chat: uint /* uint & `T$93` */ + +external var on_console_command: uint /* uint & `T$93` */ + +external var on_player_removed: uint /* uint & `T$93` */ + +external var on_pre_player_removed: uint /* uint & `T$93` */ + +external var on_player_used_capsule: uint /* uint & `T$93` */ + +external var script_raised_built: uint /* uint & `T$93` */ + +external var script_raised_destroy: uint /* uint & `T$93` */ + +external var script_raised_revive: uint /* uint & `T$93` */ + +external var script_raised_set_tiles: uint /* uint & `T$93` */ + +external var on_player_promoted: uint /* uint & `T$93` */ + +external var on_player_demoted: uint /* uint & `T$93` */ + +external var on_combat_robot_expired: uint /* uint & `T$93` */ + +external var on_worker_robot_expired: uint /* uint & `T$93` */ + +external var on_player_changed_position: uint /* uint & `T$93` */ + +external var on_mod_item_opened: uint /* uint & `T$93` */ + +external var on_gui_opened: uint /* uint & `T$93` */ + +external var on_gui_closed: uint /* uint & `T$93` */ + +external var on_gui_value_changed: uint /* uint & `T$93` */ + +external var on_player_muted: uint /* uint & `T$93` */ + +external var on_player_unmuted: uint /* uint & `T$93` */ + +external var on_player_cheat_mode_enabled: uint /* uint & `T$93` */ + +external var on_player_cheat_mode_disabled: uint /* uint & `T$93` */ + +external var on_character_corpse_expired: uint /* uint & `T$93` */ + +external var on_pre_ghost_deconstructed: uint /* uint & `T$93` */ + +external var on_player_pipette: uint /* uint & `T$93` */ + +external var on_player_display_resolution_changed: uint /* uint & `T$93` */ + +external var on_player_display_scale_changed: uint /* uint & `T$93` */ + +external var on_pre_player_crafted_item: uint /* uint & `T$93` */ + +external var on_player_cancelled_crafting: uint /* uint & `T$93` */ + +external var on_chunk_charted: uint /* uint & `T$93` */ + +external var on_technology_effects_reset: uint /* uint & `T$93` */ + +external var on_force_reset: uint /* uint & `T$93` */ + +external var on_land_mine_armed: uint /* uint & `T$93` */ + +external var on_forces_merged: uint /* uint & `T$93` */ + +external var on_player_trash_inventory_changed: uint /* uint & `T$93` */ + +external var on_pre_player_left_game: uint /* uint & `T$93` */ + +external var on_pre_surface_cleared: uint /* uint & `T$93` */ + +external var on_surface_cleared: uint /* uint & `T$93` */ + +external var on_chunk_deleted: uint /* uint & `T$93` */ + +external var on_pre_chunk_deleted: uint /* uint & `T$93` */ + +external var on_train_schedule_changed: uint /* uint & `T$93` */ + +external var on_player_banned: uint /* uint & `T$93` */ + +external var on_player_kicked: uint /* uint & `T$93` */ + +external var on_player_unbanned: uint /* uint & `T$93` */ + +external var on_rocket_launch_ordered: uint /* uint & `T$93` */ + +external var on_script_path_request_finished: uint /* uint & `T$93` */ + +external var on_ai_command_completed: uint /* uint & `T$93` */ + +external var on_marked_for_upgrade: uint /* uint & `T$93` */ + +external var on_cancelled_upgrade: uint /* uint & `T$93` */ + +external var on_player_toggled_map_editor: uint /* uint & `T$93` */ + +external var on_entity_cloned: uint /* uint & `T$93` */ + +external var on_area_cloned: uint /* uint & `T$93` */ + +external var on_brush_cloned: uint /* uint & `T$93` */ + +external var on_game_created_from_scenario: uint /* uint & `T$93` */ + +external var on_surface_imported: uint /* uint & `T$93` */ + +external var on_surface_renamed: uint /* uint & `T$93` */ + +external var on_player_toggled_alt_mode: uint /* uint & `T$93` */ + +external var on_player_repaired_entity: uint /* uint & `T$93` */ + +external var on_player_fast_transferred: uint /* uint & `T$93` */ + +external var on_pre_robot_exploded_cliff: uint /* uint & `T$93` */ + +external var on_robot_exploded_cliff: uint /* uint & `T$93` */ + +external var on_entity_spawned: uint /* uint & `T$93` */ + +external var on_cutscene_waypoint_reached: uint /* uint & `T$93` */ + +external var on_unit_group_created: uint /* uint & `T$93` */ + +external var on_unit_added_to_group: uint /* uint & `T$93` */ + +external var on_unit_removed_from_group: uint /* uint & `T$93` */ + +external var on_unit_group_finished_gathering: uint /* uint & `T$93` */ + +external var on_build_base_arrived: uint /* uint & `T$93` */ + +external var on_chart_tag_added: uint /* uint & `T$93` */ + +external var on_chart_tag_modified: uint /* uint & `T$93` */ + +external var on_chart_tag_removed: uint /* uint & `T$93` */ + +external var on_lua_shortcut: uint /* uint & `T$93` */ + +external var on_gui_location_changed: uint /* uint & `T$93` */ + +external var on_gui_selected_tab_changed: uint /* uint & `T$93` */ + +external var on_gui_switch_state_changed: uint /* uint & `T$93` */ + +external var on_force_cease_fire_changed: uint /* uint & `T$93` */ + +external var on_force_friends_changed: uint /* uint & `T$93` */ + +external var on_string_translated: uint /* uint & `T$93` */ + +external var on_script_trigger_effect: uint /* uint & `T$93` */ + +external var on_player_set_quick_bar_slot: uint /* uint & `T$93` */ + +external var on_pre_player_toggled_map_editor: uint /* uint & `T$93` */ + +external var on_pre_script_inventory_resized: uint /* uint & `T$93` */ + +external var on_script_inventory_resized: uint /* uint & `T$93` */ + +external var on_entity_destroyed: uint /* uint & `T$93` */ + +external var on_player_clicked_gps_tag: uint /* uint & `T$93` */ + +external var on_player_flushed_fluid: uint /* uint & `T$93` */ + +external var on_permission_group_edited: uint /* uint & `T$93` */ + +external var on_pre_permission_string_imported: uint /* uint & `T$93` */ + +external var on_permission_string_imported: uint /* uint & `T$93` */ + +external var on_pre_permission_group_deleted: uint /* uint & `T$93` */ + +external var on_permission_group_deleted: uint /* uint & `T$93` */ + +external var on_permission_group_added: uint /* uint & `T$93` */ + +external var on_cutscene_cancelled: uint /* uint & `T$93` */ + +external var on_player_configured_spider_remote: uint /* uint & `T$93` */ + +external var on_player_used_spider_remote: uint /* uint & `T$93` */ + +external var on_spider_command_completed: uint /* uint & `T$93` */ + +external var on_entity_logistic_slot_changed: uint /* uint & `T$93` */ + +external var on_equipment_inserted: uint /* uint & `T$93` */ + +external var on_equipment_removed: uint /* uint & `T$93` */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines.defines.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines.defines.module_typed-factorio.kt new file mode 100644 index 0000000..0c4e085 --- /dev/null +++ b/modules/mod2/dukat-custom/defines.defines.module_typed-factorio.kt @@ -0,0 +1,668 @@ +@file:JsQualifier("defines") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package defines + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external enum class alert_type { + entity_destroyed, + entity_under_attack, + not_enough_construction_robots, + no_material_for_construction, + not_enough_repair_packs, + turret_fire, + custom, + no_storage, + train_out_of_fuel +} + +external enum class behavior_result { + in_progress, + fail, + success, + deleted +} + +external enum class build_check_type { + script, + manual, + manual_ghost, + script_ghost, + blueprint_ghost, + ghost_revive +} + +external enum class chain_signal_state { + none, + all_open, + partially_open, + none_open +} + +external enum class chunk_generated_status { + nothing, + custom_tiles, + basic_tiles, + corrected_tiles, + tiles, + entities +} + +external enum class circuit_condition_index { + inserter_circuit, + inserter_logistic, + lamp, + arithmetic_combinator, + decider_combinator, + constant_combinator, + offshore_pump, + pump +} + +external enum class circuit_connector_id { + accumulator, + constant_combinator, + container, + programmable_speaker, + rail_signal, + rail_chain_signal, + roboport, + storage_tank, + wall, + electric_pole, + inserter, + lamp, + combinator_input, + combinator_output, + offshore_pump, + pump +} + +external enum class command { + attack /* = 0 */, + go_to_location /* = 1 */, + compound /* = 2 */, + group /* = 3 */, + attack_area /* = 4 */, + wander /* = 5 */, + flee /* = 6 */, + stop /* = 7 */, + build_base /* = 8 */ +} + +external enum class compound_command { + logical_and, + logical_or, + return_last +} + +external enum class controllers { + ghost, + character, + god, + editor, + cutscene, + spectator +} + +external enum class difficulty { + easy, + normal, + hard +} + +external enum class direction { + north /* = 0 */, + northeast /* = 1 */, + east /* = 2 */, + southeast /* = 3 */, + south /* = 4 */, + southwest /* = 5 */, + west /* = 6 */, + northwest /* = 7 */ +} + +external enum class disconnect_reason { + quit, + dropped, + reconnect, + wrong_input, + desync_limit_reached, + cannot_keep_up, + afk, + kicked, + kicked_and_deleted, + banned, + switching_servers +} + +external enum class distraction { + none, + by_enemy, + by_anything, + by_damage +} + +external enum class entity_status { + working, + normal, + no_power, + low_power, + no_fuel, + disabled_by_control_behavior, + opened_by_circuit_network, + closed_by_circuit_network, + disabled_by_script, + marked_for_deconstruction, + not_plugged_in_electric_network, + networks_connected, + networks_disconnected, + charging, + discharging, + fully_charged, + out_of_logistic_network, + no_recipe, + no_ingredients, + no_input_fluid, + no_research_in_progress, + no_minable_resources, + low_input_fluid, + fluid_ingredient_shortage, + full_output, + item_ingredient_shortage, + missing_required_fluid, + missing_science_packs, + waiting_for_source_items, + waiting_for_space_in_destination, + preparing_rocket_for_launch, + waiting_to_launch_rocket, + launching_rocket, + no_modules_to_transmit, + recharging_after_power_outage, + waiting_for_target_to_be_built, + waiting_for_train, + no_ammo, + low_temperature, + disabled, + turned_off_during_daytime, + not_connected_to_rail, + cant_divide_segments +} + +external enum class flow_precision_index { + five_seconds, + one_minute, + ten_minutes, + one_hour, + ten_hours, + fifty_hours, + two_hundred_fifty_hours, + one_thousand_hours +} + +external enum class group_state { + gathering, + moving, + attacking_distraction, + attacking_target, + finished, + pathfinding, + wander_in_group +} + +external enum class gui_type { + none, + entity, + research, + controller, + production, + item, + bonus, + trains, + achievement, + blueprint_library, + equipment, + logistic, + other_player, + permissions, + tutorials, + custom, + server_management, + player_management, + tile +} + +external enum class input_action { + activate_copy, + activate_cut, + activate_paste, + add_permission_group, + add_train_station, + admin_action, + alt_select_area, + alt_select_blueprint_entities, + alternative_copy, + begin_mining, + begin_mining_terrain, + build, + build_rail, + build_terrain, + cancel_craft, + cancel_deconstruct, + cancel_new_blueprint, + cancel_research, + cancel_upgrade, + change_active_character_tab, + change_active_item_group_for_crafting, + change_active_item_group_for_filters, + change_active_quick_bar, + change_arithmetic_combinator_parameters, + change_decider_combinator_parameters, + change_entity_label, + change_item_description, + change_item_label, + change_multiplayer_config, + change_picking_state, + change_programmable_speaker_alert_parameters, + change_programmable_speaker_circuit_parameters, + change_programmable_speaker_parameters, + change_riding_state, + change_shooting_state, + change_train_stop_station, + change_train_wait_condition, + change_train_wait_condition_data, + clear_cursor, + connect_rolling_stock, + copy, + copy_entity_settings, + copy_opened_blueprint, + copy_opened_item, + craft, + cursor_split, + cursor_transfer, + custom_input, + cycle_blueprint_book_backwards, + cycle_blueprint_book_forwards, + deconstruct, + delete_blueprint_library, + delete_blueprint_record, + delete_custom_tag, + delete_permission_group, + destroy_item, + destroy_opened_item, + disconnect_rolling_stock, + drag_train_schedule, + drag_train_wait_condition, + drop_blueprint_record, + drop_item, + edit_blueprint_tool_preview, + edit_custom_tag, + edit_permission_group, + export_blueprint, + fast_entity_split, + fast_entity_transfer, + flush_opened_entity_fluid, + flush_opened_entity_specific_fluid, + go_to_train_station, + grab_blueprint_record, + gui_checked_state_changed, + gui_click, + gui_confirmed, + gui_elem_changed, + gui_location_changed, + gui_selected_tab_changed, + gui_selection_state_changed, + gui_switch_state_changed, + gui_text_changed, + gui_value_changed, + import_blueprint, + import_blueprint_string, + import_blueprints_filtered, + import_permissions_string, + inventory_split, + inventory_transfer, + launch_rocket, + lua_shortcut, + map_editor_action, + market_offer, + mod_settings_changed, + open_achievements_gui, + open_blueprint_library_gui, + open_blueprint_record, + open_bonus_gui, + open_character_gui, + open_current_vehicle_gui, + open_equipment, + open_gui, + open_item, + open_logistic_gui, + open_mod_item, + open_parent_of_opened_item, + open_production_gui, + open_technology_gui, + open_tips_and_tricks_gui, + open_train_gui, + open_train_station_gui, + open_trains_gui, + paste_entity_settings, + place_equipment, + quick_bar_pick_slot, + quick_bar_set_selected_page, + quick_bar_set_slot, + reassign_blueprint, + remove_cables, + remove_train_station, + reset_assembling_machine, + reset_item, + rotate_entity, + select_area, + select_blueprint_entities, + select_entity_slot, + select_item, + select_mapper_slot, + select_next_valid_gun, + select_tile_slot, + send_spidertron, + set_auto_launch_rocket, + set_autosort_inventory, + set_behavior_mode, + set_car_weapons_control, + set_circuit_condition, + set_circuit_mode_of_operation, + set_controller_logistic_trash_filter_item, + set_deconstruction_item_tile_selection_mode, + set_deconstruction_item_trees_and_rocks_only, + set_entity_color, + set_entity_energy_property, + set_entity_logistic_trash_filter_item, + set_filter, + set_flat_controller_gui, + set_heat_interface_mode, + set_heat_interface_temperature, + set_infinity_container_filter_item, + set_infinity_container_remove_unfiltered_items, + set_infinity_pipe_filter, + set_inserter_max_stack_size, + set_inventory_bar, + set_linked_container_link_i_d, + set_logistic_filter_item, + set_logistic_filter_signal, + set_player_color, + set_recipe_notifications, + set_request_from_buffers, + set_research_finished_stops_game, + set_signal, + set_splitter_priority, + set_train_stopped, + set_trains_limit, + set_vehicle_automatic_targeting_parameters, + setup_assembling_machine, + setup_blueprint, + setup_single_blueprint_record, + smart_pipette, + spawn_item, + stack_split, + stack_transfer, + start_repair, + start_research, + start_walking, + stop_building_by_moving, + switch_connect_to_logistic_network, + switch_constant_combinator_state, + switch_inserter_filter_mode_state, + switch_power_switch_state, + switch_to_rename_stop_gui, + take_equipment, + toggle_deconstruction_item_entity_filter_mode, + toggle_deconstruction_item_tile_filter_mode, + toggle_driving, + toggle_enable_vehicle_logistics_while_moving, + toggle_entity_logistic_requests, + toggle_equipment_movement_bonus, + toggle_map_editor, + toggle_personal_logistic_requests, + toggle_personal_roboport, + toggle_show_entity_info, + translate_string, + undo, + upgrade, + upgrade_opened_blueprint_by_item, + upgrade_opened_blueprint_by_record, + use_artillery_remote, + use_item, + wire_dragging, + write_to_console +} + +external enum class inventory { + fuel, + burnt_result, + chest, + furnace_source, + furnace_result, + furnace_modules, + character_main, + character_guns, + character_ammo, + character_armor, + character_vehicle, + character_trash, + god_main, + editor_main, + editor_guns, + editor_ammo, + editor_armor, + roboport_robot, + roboport_material, + robot_cargo, + robot_repair, + assembling_machine_input, + assembling_machine_output, + assembling_machine_modules, + lab_input, + lab_modules, + mining_drill_modules, + item_main, + rocket_silo_rocket, + rocket_silo_result, + rocket, + car_trunk, + car_ammo, + cargo_wagon, + turret_ammo, + beacon_modules, + character_corpse, + artillery_turret_ammo, + artillery_wagon_ammo, + spider_trunk, + spider_ammo, + spider_trash +} + +external enum class logistic_member_index { + logistic_container, + vehicle_storage, + character_requester, + character_storage, + character_provider, + generic_on_off_behavior +} + +external enum class logistic_mode { + none, + active_provider, + storage, + requester, + passive_provider, + buffer +} + +external enum class mouse_button_type { + none, + left, + right, + middle +} + +external var prototypes: Any + +external enum class rail_connection_direction { + left, + straight, + right, + none +} + +external enum class rail_direction { + front, + back +} + +external enum class relative_gui_position { + top, + bottom, + left, + right +} + +external enum class relative_gui_type { + accumulator_gui, + achievement_gui, + additional_entity_info_gui, + admin_gui, + arithmetic_combinator_gui, + armor_gui, + assembling_machine_gui, + assembling_machine_select_recipe_gui, + beacon_gui, + blueprint_book_gui, + blueprint_library_gui, + blueprint_setup_gui, + bonus_gui, + burner_equipment_gui, + car_gui, + constant_combinator_gui, + container_gui, + controller_gui, + decider_combinator_gui, + deconstruction_item_gui, + electric_energy_interface_gui, + electric_network_gui, + entity_variations_gui, + entity_with_energy_source_gui, + equipment_grid_gui, + furnace_gui, + generic_on_off_entity_gui, + heat_interface_gui, + infinity_pipe_gui, + inserter_gui, + item_with_inventory_gui, + lab_gui, + lamp_gui, + linked_container_gui, + loader_gui, + logistic_gui, + market_gui, + mining_drill_gui, + other_player_gui, + permissions_gui, + pipe_gui, + power_switch_gui, + production_gui, + programmable_speaker_gui, + rail_chain_signal_gui, + rail_signal_gui, + reactor_gui, + rename_stop_gui, + resource_entity_gui, + roboport_gui, + rocket_silo_gui, + server_config_gui, + spider_vehicle_gui, + splitter_gui, + standalone_character_gui, + storage_tank_gui, + tile_variations_gui, + train_gui, + train_stop_gui, + trains_gui, + transport_belt_gui, + upgrade_item_gui, + wall_gui +} + +external enum class render_mode { + game, + chart, + chart_zoomed_in +} + +external enum class rich_text_setting { + enabled, + disabled, + highlight +} + +external enum class shooting { + not_shooting, + shooting_enemies, + shooting_selected +} + +external enum class signal_state { + open, + closed, + reserved, + reserved_by_circuit_network +} + +external enum class train_state { + on_the_path, + path_lost, + no_schedule, + no_path, + arrive_signal, + wait_signal, + arrive_station, + wait_station, + manual_control_stop, + manual_control, + destination_full +} + +external enum class transport_line { + left_line, + right_line, + left_underground_line, + right_underground_line, + secondary_left_line, + secondary_right_line, + left_split_line, + right_split_line, + secondary_left_split_line, + secondary_right_split_line +} + +external enum class wire_connection_id { + electric_pole, + power_switch_left, + power_switch_right +} + +external enum class wire_type { + red, + green, + copper +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines.defines.riding.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines.defines.riding.module_typed-factorio.kt new file mode 100644 index 0000000..936be1e --- /dev/null +++ b/modules/mod2/dukat-custom/defines.defines.riding.module_typed-factorio.kt @@ -0,0 +1,30 @@ +@file:JsQualifier("defines.riding") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package defines.riding + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external enum class acceleration { + nothing, + accelerating, + braking, + reversing +} + +external enum class direction { + left, + straight, + right +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/events.module_typed-factorio.kt b/modules/mod2/dukat-custom/events.module_typed-factorio.kt new file mode 100644 index 0000000..11d3550 --- /dev/null +++ b/modules/mod2/dukat-custom/events.module_typed-factorio.kt @@ -0,0 +1,1574 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import tsstdlib.Position +import defines.behavior_result +import defines.mouse_button_type +import defines.gui_type +import defines.direction +import defines.input_action +import defines.disconnect_reason +import tsstdlib.Record +import defines.train_state + +external interface CustomInputEvent { + var player_index: uint + var input_name: String + var cursor_position: Position + var selected_prototype: SelectedPrototypeData? + get() = definedExternally + set(value) = definedExternally + var name: String + var tick: uint +} + +external interface OnAiCommandCompletedEvent { + var unit_number: uint + var result: behavior_result + var was_distracted: Boolean + var name: Any + var tick: uint +} + +external interface OnAreaClonedEvent { + var source_surface: LuaSurface + var source_area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var destination_surface: LuaSurface + var destination_area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var destination_force: LuaForce? + get() = definedExternally + set(value) = definedExternally + var clone_tiles: Boolean + var clone_entities: Boolean + var clone_decoratives: Boolean + var clear_destination_entities: Boolean + var clear_destination_decoratives: Boolean + var name: Any + var tick: uint +} + +external interface OnBiterBaseBuiltEvent { + var entity: LuaEntity + var name: Any + var tick: uint +} + +external interface OnBrushClonedEvent { + var source_offset: dynamic /* TilePositionTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var destination_offset: dynamic /* TilePositionTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var source_surface: LuaSurface + var source_positions: Array */> + var destination_surface: LuaSurface + var destination_force: LuaForce? + get() = definedExternally + set(value) = definedExternally + var clone_tiles: Boolean + var clone_entities: Boolean + var clone_decoratives: Boolean + var clear_destination_entities: Boolean + var clear_destination_decoratives: Boolean + var name: Any + var tick: uint +} + +external interface OnBuildBaseArrivedEvent { + var unit: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var group: LuaUnitGroup? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnBuiltEntityEvent { + var created_entity: LuaEntity + var player_index: uint + var stack: LuaItemStack + var item: LuaItemPrototype? + get() = definedExternally + set(value) = definedExternally + var tags: Tags? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnCancelledDeconstructionEvent { + var entity: LuaEntity + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnCancelledUpgradeEvent { + var entity: LuaEntity + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnCharacterCorpseExpiredEvent { + var corpse: LuaEntity + var name: Any + var tick: uint +} + +external interface OnChartTagAddedEvent { + var tag: LuaCustomChartTag + var force: LuaForce + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnChartTagModifiedEvent { + var tag: LuaCustomChartTag + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var force: LuaForce + var old_text: String + var old_icon: SignalID? + get() = definedExternally + set(value) = definedExternally + var old_player: uint? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnChartTagRemovedEvent { + var tag: LuaCustomChartTag + var force: LuaForce + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnChunkChartedEvent { + var surface_index: uint + var position: dynamic /* ChunkPositionTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var force: LuaForce + var name: Any + var tick: uint +} + +external interface OnChunkDeletedEvent { + var surface_index: uint + var positions: Array */> + var name: Any + var tick: uint +} + +external interface OnChunkGeneratedEvent { + var area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var position: dynamic /* ChunkPositionTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var surface: LuaSurface + var name: Any + var tick: uint +} + +external interface OnCombatRobotExpiredEvent { + var robot: LuaEntity + var owner: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnConsoleChatEvent { + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var message: String + var name: Any + var tick: uint +} + +external interface OnConsoleCommandEvent { + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var command: String + var parameters: String + var name: Any + var tick: uint +} + +external interface OnCutsceneCancelledEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnCutsceneWaypointReachedEvent { + var player_index: uint + var waypoint_index: uint + var name: Any + var tick: uint +} + +external interface OnDifficultySettingsChangedEvent { + var old_recipe_difficulty: uint + var old_technology_difficulty: uint + var name: Any + var tick: uint +} + +external interface OnEntityClonedEvent { + var source: LuaEntity + var destination: LuaEntity + var name: Any + var tick: uint +} + +external interface OnEntityDamagedEvent { + var entity: LuaEntity + var damage_type: LuaDamagePrototype + var original_damage_amount: float + var final_damage_amount: float + var final_health: float + var cause: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var force: LuaForce? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnEntityDestroyedEvent { + var registration_number: uint64 + var unit_number: uint? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnEntityDiedEvent { + var entity: LuaEntity + var cause: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var loot: LuaInventory + var force: LuaForce? + get() = definedExternally + set(value) = definedExternally + var damage_type: LuaDamagePrototype? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnEntityLogisticSlotChangedEvent { + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var entity: LuaEntity + var slot_index: uint + var name: Any + var tick: uint +} + +external interface OnEntityRenamedEvent { + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var by_script: Boolean + var entity: LuaEntity + var old_name: String + var name: Any + var tick: uint +} + +external interface OnEntitySettingsPastedEvent { + var player_index: uint + var source: LuaEntity + var destination: LuaEntity + var name: Any + var tick: uint +} + +external interface OnEntitySpawnedEvent { + var spawner: LuaEntity + var entity: LuaEntity + var name: Any + var tick: uint +} + +external interface OnEquipmentInsertedEvent { + var grid: LuaEquipmentGrid + var equipment: LuaEquipment + var name: Any + var tick: uint +} + +external interface OnEquipmentRemovedEvent { + var grid: LuaEquipmentGrid + var equipment: String + var count: uint + var name: Any + var tick: uint +} + +external interface OnForceCeaseFireChangedEvent { + var force: LuaForce + var other_force: LuaForce + var added: Boolean + var name: Any + var tick: uint +} + +external interface OnForceCreatedEvent { + var force: LuaForce + var name: Any + var tick: uint +} + +external interface OnForceFriendsChangedEvent { + var force: LuaForce + var other_force: LuaForce + var added: Boolean + var name: Any + var tick: uint +} + +external interface OnForceResetEvent { + var force: LuaForce + var name: Any + var tick: uint +} + +external interface OnForcesMergedEvent { + var source_name: String + var source_index: uint + var destination: LuaForce + var name: Any + var tick: uint +} + +external interface OnForcesMergingEvent { + var source: LuaForce + var destination: LuaForce + var name: Any + var tick: uint +} + +external interface OnGameCreatedFromScenarioEvent { + var name: Any + var tick: uint +} + +external interface OnGuiCheckedStateChangedEvent { + var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnGuiClickEvent { + var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var player_index: uint + var button: mouse_button_type + var alt: Boolean + var control: Boolean + var shift: Boolean + var name: Any + var tick: uint +} + +external interface OnGuiClosedEvent { + var player_index: uint + var gui_type: gui_type + var entity: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var item: LuaItemStack? + get() = definedExternally + set(value) = definedExternally + var equipment: LuaEquipment? + get() = definedExternally + set(value) = definedExternally + var other_player: LuaPlayer? + get() = definedExternally + set(value) = definedExternally + var element: dynamic /* ChooseElemButtonGuiElementMembers? | DropDownGuiElementMembers? | EmptyWidgetGuiElementMembers? | EntityPreviewGuiElementMembers? | ListBoxGuiElementMembers? | ScrollPaneGuiElementMembers? | SpriteButtonGuiElementMembers? | TabbedPaneGuiElementMembers? | TextBoxGuiElementMembers? | ButtonGuiElementMembers? | CameraGuiElementMembers? | CheckboxGuiElementMembers? | FlowGuiElementMembers? | FrameGuiElementMembers? | LabelGuiElementMembers? | LineGuiElementMembers? | MinimapGuiElementMembers? | ProgressbarGuiElementMembers? | RadiobuttonGuiElementMembers? | SliderGuiElementMembers? | SpriteGuiElementMembers? | SwitchGuiElementMembers? | TabGuiElementMembers? | TableGuiElementMembers? | TextfieldGuiElementMembers? */ + get() = definedExternally + set(value) = definedExternally + var technology: LuaTechnology? + get() = definedExternally + set(value) = definedExternally + var tile_position: dynamic /* TilePositionTable? | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnGuiConfirmedEvent { + var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var player_index: uint + var alt: Boolean + var control: Boolean + var shift: Boolean + var name: Any + var tick: uint +} + +external interface OnGuiElemChangedEvent { + var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnGuiLocationChangedEvent { + var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnGuiOpenedEvent { + var player_index: uint + var gui_type: gui_type + var entity: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var item: LuaItemStack? + get() = definedExternally + set(value) = definedExternally + var equipment: LuaEquipment? + get() = definedExternally + set(value) = definedExternally + var other_player: LuaPlayer? + get() = definedExternally + set(value) = definedExternally + var element: dynamic /* ChooseElemButtonGuiElementMembers? | DropDownGuiElementMembers? | EmptyWidgetGuiElementMembers? | EntityPreviewGuiElementMembers? | ListBoxGuiElementMembers? | ScrollPaneGuiElementMembers? | SpriteButtonGuiElementMembers? | TabbedPaneGuiElementMembers? | TextBoxGuiElementMembers? | ButtonGuiElementMembers? | CameraGuiElementMembers? | CheckboxGuiElementMembers? | FlowGuiElementMembers? | FrameGuiElementMembers? | LabelGuiElementMembers? | LineGuiElementMembers? | MinimapGuiElementMembers? | ProgressbarGuiElementMembers? | RadiobuttonGuiElementMembers? | SliderGuiElementMembers? | SpriteGuiElementMembers? | SwitchGuiElementMembers? | TabGuiElementMembers? | TableGuiElementMembers? | TextfieldGuiElementMembers? */ + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnGuiSelectedTabChangedEvent { + var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnGuiSelectionStateChangedEvent { + var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnGuiSwitchStateChangedEvent { + var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnGuiTextChangedEvent { + var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var player_index: uint + var text: String + var name: Any + var tick: uint +} + +external interface OnGuiValueChangedEvent { + var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ + get() = definedExternally + set(value) = definedExternally + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnLandMineArmedEvent { + var mine: LuaEntity + var name: Any + var tick: uint +} + +external interface OnLuaShortcutEvent { + var player_index: uint + var prototype_name: String + var name: Any + var tick: uint +} + +external interface OnMarkedForDeconstructionEvent { + var entity: LuaEntity + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnMarkedForUpgradeEvent { + var entity: LuaEntity + var target: LuaEntityPrototype + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var direction: direction? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnMarketItemPurchasedEvent { + var player_index: uint + var market: LuaEntity + var offer_index: uint + var count: uint + var name: Any + var tick: uint +} + +external interface OnModItemOpenedEvent { + var player_index: uint + var item: LuaItemPrototype + var name: Any + var tick: uint +} + +external interface OnPermissionGroupAddedEvent { + var player_index: uint + var group: LuaPermissionGroup + var name: Any + var tick: uint +} + +external interface OnPermissionGroupDeletedEvent { + var player_index: uint + var group_name: String + var id: uint + var name: Any + var tick: uint +} + +external interface OnPermissionGroupEditedEvent { + var player_index: uint + var group: LuaPermissionGroup + var type: String /* "add-permission" | "remove-permission" | "enable-all" | "disable-all" | "add-player" | "remove-player" | "rename" */ + var action: input_action + var other_player_index: uint + var old_name: String + var new_name: String + var name: Any + var tick: uint +} + +external interface OnPermissionStringImportedEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPickedUpItemEvent { + var item_stack: dynamic /* String | ItemStackDefinition */ + get() = definedExternally + set(value) = definedExternally + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerAltSelectedAreaEvent { + var player_index: uint + var surface: LuaSurface + var area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var item: String + var entities: Array + var tiles: Array + var name: Any + var tick: uint +} + +external interface OnPlayerAmmoInventoryChangedEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerArmorInventoryChangedEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerBannedEvent { + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var player_name: String + var by_player: uint? + get() = definedExternally + set(value) = definedExternally + var reason: String? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnPlayerBuiltTileEvent { + var player_index: uint + var surface_index: uint + var tiles: Array + var tile: LuaTilePrototype + var item: LuaItemPrototype? + get() = definedExternally + set(value) = definedExternally + var stack: LuaItemStack? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnPlayerCancelledCraftingEvent { + var player_index: uint + var items: LuaInventory + var recipe: LuaRecipe + var cancel_count: uint + var name: Any + var tick: uint +} + +external interface OnPlayerChangedForceEvent { + var player_index: uint + var force: LuaForce + var name: Any + var tick: uint +} + +external interface OnPlayerChangedPositionEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerChangedSurfaceEvent { + var player_index: uint + var surface_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerCheatModeDisabledEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerCheatModeEnabledEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerClickedGpsTagEvent { + var player_index: uint + var position: Position + var surface: String + var name: Any + var tick: uint +} + +external interface OnPlayerConfiguredBlueprintEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerConfiguredSpiderRemoteEvent { + var player_index: uint + var vehicle: LuaEntity + var name: Any + var tick: uint +} + +external interface OnPlayerCraftedItemEvent { + var item_stack: LuaItemStack + var player_index: uint + var recipe: LuaRecipe + var name: Any + var tick: uint +} + +external interface OnPlayerCreatedEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerCursorStackChangedEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerDeconstructedAreaEvent { + var player_index: uint + var surface: LuaSurface + var area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var item: String + var alt: Boolean + var name: Any + var tick: uint +} + +external interface OnPlayerDemotedEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerDiedEvent { + var player_index: uint + var cause: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnPlayerDisplayResolutionChangedEvent { + var player_index: uint + var old_resolution: DisplayResolution + var name: Any + var tick: uint +} + +external interface OnPlayerDisplayScaleChangedEvent { + var player_index: uint + var old_scale: double + var name: Any + var tick: uint +} + +external interface OnPlayerDrivingChangedStateEvent { + var player_index: uint + var entity: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnPlayerDroppedItemEvent { + var player_index: uint + var entity: LuaEntity + var name: Any + var tick: uint +} + +external interface OnPlayerFastTransferredEvent { + var player_index: uint + var entity: LuaEntity + var from_player: Boolean + var name: Any + var tick: uint +} + +external interface OnPlayerFlushedFluidEvent { + var player_index: uint + var fluid: String + var amount: double + var entity: LuaEntity + var only_this_entity: Boolean + var name: Any + var tick: uint +} + +external interface OnPlayerGunInventoryChangedEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerJoinedGameEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerKickedEvent { + var player_index: uint + var by_player: uint? + get() = definedExternally + set(value) = definedExternally + var reason: String? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnPlayerLeftGameEvent { + var player_index: uint + var reason: disconnect_reason + var name: Any + var tick: uint +} + +external interface OnPlayerMainInventoryChangedEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerMinedEntityEvent { + var player_index: uint + var entity: LuaEntity + var buffer: LuaInventory + var name: Any + var tick: uint +} + +external interface OnPlayerMinedItemEvent { + var item_stack: dynamic /* String | ItemStackDefinition */ + get() = definedExternally + set(value) = definedExternally + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerMinedTileEvent { + var player_index: uint + var surface_index: uint + var tiles: Array + var name: Any + var tick: uint +} + +external interface OnPlayerMutedEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerPipetteEvent { + var player_index: uint + var item: LuaItemPrototype + var used_cheat_mode: Boolean + var name: Any + var tick: uint +} + +external interface OnPlayerPlacedEquipmentEvent { + var player_index: uint + var equipment: LuaEquipment + var grid: LuaEquipmentGrid + var name: Any + var tick: uint +} + +external interface OnPlayerPromotedEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerRemovedEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerRemovedEquipmentEvent { + var player_index: uint + var grid: LuaEquipmentGrid + var equipment: String + var count: uint + var name: Any + var tick: uint +} + +external interface OnPlayerRepairedEntityEvent { + var player_index: uint + var entity: LuaEntity + var name: Any + var tick: uint +} + +external interface OnPlayerRespawnedEvent { + var player_index: uint + var player_port: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnPlayerRotatedEntityEvent { + var entity: LuaEntity + var previous_direction: direction + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerSelectedAreaEvent { + var player_index: uint + var surface: LuaSurface + var area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var item: String + var entities: Array + var tiles: Array + var name: Any + var tick: uint +} + +external interface OnPlayerSetQuickBarSlotEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerSetupBlueprintEvent { + var player_index: uint + var surface: LuaSurface + var area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var item: String + var alt: Boolean + var mapping: LuaLazyLoadedValue> + var name: Any + var tick: uint +} + +external interface OnPlayerToggledAltModeEvent { + var player_index: uint + var alt_mode: Boolean + var name: Any + var tick: uint +} + +external interface OnPlayerToggledMapEditorEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerTrashInventoryChangedEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerUnbannedEvent { + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var player_name: String + var by_player: uint? + get() = definedExternally + set(value) = definedExternally + var reason: String? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnPlayerUnmutedEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPlayerUsedCapsuleEvent { + var player_index: uint + var item: LuaItemPrototype + var position: Position + var name: Any + var tick: uint +} + +external interface OnPlayerUsedSpiderRemoteEvent { + var player_index: uint + var vehicle: LuaEntity + var position: Position + var success: Boolean + var name: Any + var tick: uint +} + +external interface OnPostEntityDiedEvent { + var ghost: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var force: LuaForce? + get() = definedExternally + set(value) = definedExternally + var position: Position + var prototype: LuaEntityPrototype + var damage_type: LuaDamagePrototype? + get() = definedExternally + set(value) = definedExternally + var corpses: Array + var surface_index: uint + var unit_number: uint? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnPreBuildEvent { + var player_index: uint + var position: Position + var shift_build: Boolean + var direction: direction + var flip_horizontal: Boolean + var flip_vertical: Boolean + var created_by_moving: Boolean + var name: Any + var tick: uint +} + +external interface OnPreChunkDeletedEvent { + var surface_index: uint + var positions: Array */> + var name: Any + var tick: uint +} + +external interface OnPreEntitySettingsPastedEvent { + var player_index: uint + var source: LuaEntity + var destination: LuaEntity + var name: Any + var tick: uint +} + +external interface OnPreGhostDeconstructedEvent { + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var ghost: LuaEntity + var name: Any + var tick: uint +} + +external interface OnPrePermissionGroupDeletedEvent { + var player_index: uint + var group: LuaPermissionGroup + var name: Any + var tick: uint +} + +external interface OnPrePermissionStringImportedEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPrePlayerCraftedItemEvent { + var player_index: uint + var recipe: LuaRecipe + var items: LuaInventory + var queued_count: uint + var name: Any + var tick: uint +} + +external interface OnPrePlayerDiedEvent { + var player_index: uint + var cause: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnPrePlayerLeftGameEvent { + var player_index: uint + var reason: disconnect_reason + var name: Any + var tick: uint +} + +external interface OnPrePlayerMinedItemEvent { + var entity: LuaEntity + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPrePlayerRemovedEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPrePlayerToggledMapEditorEvent { + var player_index: uint + var name: Any + var tick: uint +} + +external interface OnPreRobotExplodedCliffEvent { + var robot: LuaEntity + var cliff: LuaEntity + var item: LuaItemPrototype + var name: Any + var tick: uint +} + +external interface OnPreScriptInventoryResizedEvent { + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var mod: String + var inventory: LuaInventory + var old_size: uint + var new_size: uint + var name: Any + var tick: uint +} + +external interface OnPreSurfaceClearedEvent { + var surface_index: uint + var name: Any + var tick: uint +} + +external interface OnPreSurfaceDeletedEvent { + var surface_index: uint + var name: Any + var tick: uint +} + +external interface OnResearchFinishedEvent { + var research: LuaTechnology + var by_script: Boolean + var name: Any + var tick: uint +} + +external interface OnResearchReversedEvent { + var research: LuaTechnology + var by_script: Boolean + var name: Any + var tick: uint +} + +external interface OnResearchStartedEvent { + var research: LuaTechnology + var last_research: LuaTechnology? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnResourceDepletedEvent { + var entity: LuaEntity + var name: Any + var tick: uint +} + +external interface OnRobotBuiltEntityEvent { + var robot: LuaEntity + var created_entity: LuaEntity + var stack: LuaItemStack + var tags: Tags? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnRobotBuiltTileEvent { + var robot: LuaEntity + var tiles: Array + var tile: LuaTilePrototype + var item: LuaItemPrototype + var stack: LuaItemStack + var surface_index: uint + var name: Any + var tick: uint +} + +external interface OnRobotExplodedCliffEvent { + var robot: LuaEntity + var item: LuaItemPrototype + var name: Any + var tick: uint +} + +external interface OnRobotMinedEvent { + var robot: LuaEntity + var item_stack: dynamic /* String | ItemStackDefinition */ + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnRobotMinedEntityEvent { + var robot: LuaEntity + var entity: LuaEntity + var buffer: LuaInventory + var name: Any + var tick: uint +} + +external interface OnRobotMinedTileEvent { + var robot: LuaEntity + var tiles: Array + var surface_index: uint + var name: Any + var tick: uint +} + +external interface OnRobotPreMinedEvent { + var robot: LuaEntity + var entity: LuaEntity + var name: Any + var tick: uint +} + +external interface OnRocketLaunchOrderedEvent { + var rocket: LuaEntity + var rocket_silo: LuaEntity + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnRocketLaunchedEvent { + var rocket: LuaEntity + var rocket_silo: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnRuntimeModSettingChangedEvent { + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var setting: String + var setting_type: String /* "runtime-per-user" | "runtime-global" */ + var name: Any + var tick: uint +} + +external interface OnScriptInventoryResizedEvent { + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var mod: String + var inventory: LuaInventory + var old_size: uint + var new_size: uint + var overflow_inventory: LuaInventory + var name: Any + var tick: uint +} + +external interface OnScriptPathRequestFinishedEvent { + var path: Array? + get() = definedExternally + set(value) = definedExternally + var id: uint + var try_again_later: Boolean + var name: Any + var tick: uint +} + +external interface OnScriptTriggerEffectEvent { + var effect_id: String + var surface_index: uint + var source_position: Position? + get() = definedExternally + set(value) = definedExternally + var source_entity: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var target_position: Position? + get() = definedExternally + set(value) = definedExternally + var target_entity: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnSectorScannedEvent { + var radar: LuaEntity + var chunk_position: dynamic /* ChunkPositionTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var area: dynamic /* BoundingBoxTable | JsTuple */ + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnSelectedEntityChangedEvent { + var player_index: uint + var last_entity: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnSpiderCommandCompletedEvent { + var vehicle: LuaEntity + var name: Any + var tick: uint +} + +external interface OnStringTranslatedEvent { + var player_index: uint + var localised_string: dynamic /* JsTuple | String | Number */ + get() = definedExternally + set(value) = definedExternally + var result: String + var translated: Boolean + var name: Any + var tick: uint +} + +external interface OnSurfaceClearedEvent { + var surface_index: uint + var name: Any + var tick: uint +} + +external interface OnSurfaceCreatedEvent { + var surface_index: uint + var name: Any + var tick: uint +} + +external interface OnSurfaceDeletedEvent { + var surface_index: uint + var name: Any + var tick: uint +} + +external interface OnSurfaceImportedEvent { + var surface_index: uint + var original_name: String + var name: Any + var tick: uint +} + +external interface OnSurfaceRenamedEvent { + var surface_index: uint + var old_name: String + var new_name: String + var name: Any + var tick: uint +} + +external interface OnTechnologyEffectsResetEvent { + var force: LuaForce + var name: Any + var tick: uint +} + +external interface OnTickEvent { + var name: Any + var tick: uint +} + +external interface OnTrainChangedStateEvent { + var train: LuaTrain + var old_state: train_state + var name: Any + var tick: uint +} + +external interface OnTrainCreatedEvent { + var train: LuaTrain + var old_train_id_1: uint? + get() = definedExternally + set(value) = definedExternally + var old_train_id_2: uint? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnTrainScheduleChangedEvent { + var train: LuaTrain + var player_index: uint? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnTriggerCreatedEntityEvent { + var entity: LuaEntity + var source: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnTriggerFiredArtilleryEvent { + var entity: LuaEntity + var source: LuaEntity? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface OnUnitAddedToGroupEvent { + var unit: LuaEntity + var group: LuaUnitGroup + var name: Any + var tick: uint +} + +external interface OnUnitGroupCreatedEvent { + var group: LuaUnitGroup + var name: Any + var tick: uint +} + +external interface OnUnitGroupFinishedGatheringEvent { + var group: LuaUnitGroup + var name: Any + var tick: uint +} + +external interface OnUnitRemovedFromGroupEvent { + var unit: LuaEntity + var group: LuaUnitGroup + var name: Any + var tick: uint +} + +external interface OnWorkerRobotExpiredEvent { + var robot: LuaEntity + var name: Any + var tick: uint +} + +external interface ScriptRaisedBuiltEvent { + var entity: LuaEntity + var name: Any + var tick: uint +} + +external interface ScriptRaisedDestroyEvent { + var entity: LuaEntity + var name: Any + var tick: uint +} + +external interface ScriptRaisedReviveEvent { + var entity: LuaEntity + var tags: Tags? + get() = definedExternally + set(value) = definedExternally + var name: Any + var tick: uint +} + +external interface ScriptRaisedSetTilesEvent { + var surface_index: uint + var tiles: Array + var name: Any + var tick: uint +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/global-objects.module_typed-factorio.kt b/modules/mod2/dukat-custom/global-objects.module_typed-factorio.kt new file mode 100644 index 0000000..5eaab96 --- /dev/null +++ b/modules/mod2/dukat-custom/global-objects.module_typed-factorio.kt @@ -0,0 +1,29 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external var game: LuaGameScript + +external var script: LuaBootstrap + +external var remote: LuaRemote + +external var commands: LuaCommandProcessor + +external var settings: LuaSettings + +external var rcon: LuaRCON + +external var rendering: LuaRendering \ No newline at end of file diff --git a/modules/mod2/dukat-custom/global.module_lua-types.kt b/modules/mod2/dukat-custom/global.module_lua-types.kt new file mode 100644 index 0000000..e25a73e --- /dev/null +++ b/modules/mod2/dukat-custom/global.module_lua-types.kt @@ -0,0 +1,81 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import tsstdlib.Record +import tsstdlib.Iterable + +external interface LuaThread { + var __internal__: Any +} + +external interface LuaUserdata { + var __internal__: Any +} + +external var _VERSION: String /* "Lua 5.1" | "Lua 5.2" | "Lua 5.3" | "Lua 5.4" */ + +external var _G: Any + +external fun assert(v: V): Any + +external fun > assert(v: V, vararg args: A): dynamic /* JsTuple, Any> */ + +external fun collectgarbage(opt: String /* "collect" | "stop" | "restart" */ = definedExternally) + +external fun collectgarbage() + +external fun collectgarbage(opt: String /* "setpause" | "setstepmul" | "step" */, arg: Number): dynamic /* Number | Boolean */ + +external fun dofile(filename: String = definedExternally): Any + +external fun error(message: String, level: Number = definedExternally): Any + +external fun getmetatable(obj: T): LuaMetatable__1? + +external fun ipairs(t: Record): Iterable> */> /* Iterable> */> & LuaIterator> */, undefined> & LuaExtension */ + +external fun next(table: Any?, index: Any = definedExternally): dynamic /* JsTuple | JsTuple<> */ + +external fun pairs(t: LuaTable): Iterable> */> /* Iterable> */> & LuaIterator> */, undefined> & LuaExtension */ + +external fun pairs(t: T): Iterable> */> /* Iterable> */> & LuaIterator> */, undefined> & LuaExtension */ + +external fun , R> pcall(f: (self: This, args: Args) -> R, context: This, vararg args: Args): dynamic /* JsTuple | JsTuple */ + +external fun , R> pcall(f: (self: Unit, args: A) -> R, vararg args: A): dynamic /* JsTuple | JsTuple */ + +external fun print(vararg args: Any) + +external fun rawequal(v1: T, v2: T): Boolean + +external fun rawget(table: T, index: K): Any + +external fun rawlen(v: Any?): Number + +external fun rawlen(v: String?): Number + +external fun rawset(table: T, index: K, value: Any): T + +external fun select(index: Number, vararg args: T): Array /* Array & LuaExtension */ + +external fun select(index: String /* "#" */, vararg args: T): Number + +external fun setmetatable(table: T, metatable: LuaMetatable? = definedExternally): Any + +external fun tonumber(e: Any, base: Number = definedExternally): Number? + +external fun tostring(v: Any): String + +external fun type(v: Any): String /* "nil" | "number" | "string" | "boolean" | "table" | "function" | "thread" | "userdata" */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/index.module_typescript-to-lua.kt b/modules/mod2/dukat-custom/index.module_typescript-to-lua.kt new file mode 100644 index 0000000..25e92fc --- /dev/null +++ b/modules/mod2/dukat-custom/index.module_typescript-to-lua.kt @@ -0,0 +1,42 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import tsstdlib.Record +import tsstdlib.Iterable + +typealias AnyTable = Record + +external interface AnyNotNil + +typealias LuaExtension = Any + +external var `$multi`: (values: T) -> T /* (values: T) -> T & LuaExtension */ + +external var `$range`: (start: Number, limit: Number, step: Number) -> Iterable /* (start: Number, limit: Number, step: Number) -> Iterable & LuaExtension */ + +external var `$vararg`: Array /* Array & LuaExtension */ + +typealias LuaIterator = Any + +@Suppress("EXTERNAL_DELEGATION", "NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface LuaTable { + var length: () -> Number /* () -> Number & LuaExtension */ + var get: (key: TKey) -> TValue /* (key: TKey) -> TValue & LuaExtension */ + var set: (key: TKey, value: TValue) -> Unit /* (key: TKey, value: TValue) -> Unit & LuaExtension */ + var has: (key: TKey) -> Boolean /* (key: TKey) -> Boolean & LuaExtension */ + var delete: (key: TKey) -> Boolean /* (key: TKey) -> Boolean & LuaExtension */ + + companion object : Any by definedExternally +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/io.io.module_lua-types.kt b/modules/mod2/dukat-custom/io.io.module_lua-types.kt new file mode 100644 index 0000000..80cd0cd --- /dev/null +++ b/modules/mod2/dukat-custom/io.io.module_lua-types.kt @@ -0,0 +1,57 @@ +@file:JsQualifier("io") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package io + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import LuaFile +import tsstdlib.Iterable + +external fun close(file: LuaFile = definedExternally): Boolean + +external fun flush(): Boolean + +external fun input(file: String = definedExternally): LuaFile + +external fun input(): LuaFile + +external fun input(file: LuaFile = definedExternally): LuaFile + +external fun > lines(filename: String = definedExternally, vararg formats: T): Iterable */> /* Iterable */> & LuaIterator */, undefined> & LuaExtension */ + +external fun open(filename: String, mode: String = definedExternally): dynamic /* JsTuple | JsTuple */ + +external fun output(file: String = definedExternally): LuaFile + +external fun output(): LuaFile + +external fun output(file: LuaFile = definedExternally): LuaFile + +external fun popen(prog: String, mode: String /* "r" | "w" */ = definedExternally): dynamic /* JsTuple | JsTuple */ + +external fun read(): FileReadFormatToType? + +external fun read(format: T): FileReadFormatToType? /* Any & LuaExtension */ + +external var stderr: LuaFile + +external var stdin: LuaFile + +external var stdout: LuaFile + +external fun tmpfile(): LuaFile + +external fun type(obj: Any): String /* "file" | "closed file" */ + +external fun write(vararg args: Any /* String | Number */): dynamic /* JsTuple | JsTuple */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/io.module_lua-types.kt b/modules/mod2/dukat-custom/io.module_lua-types.kt new file mode 100644 index 0000000..abe679d --- /dev/null +++ b/modules/mod2/dukat-custom/io.module_lua-types.kt @@ -0,0 +1,28 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import tsstdlib.Iterable +import io.FileReadFormatToType + +external interface LuaFile { + fun close(): Boolean + fun flush(): Boolean + fun > lines(vararg formats: T): Iterable */> /* Iterable */> & LuaIterator */, undefined> & LuaExtension */ + fun read(): FileReadFormatToType? + fun read(format: T): FileReadFormatToType? /* Any & LuaExtension */ + fun seek(whence: String /* "set" | "cur" | "end" */ = definedExternally, offset: Number = definedExternally): dynamic /* JsTuple | JsTuple */ + fun setvbuf(mode: String /* "no" | "full" | "line" */, size: Number = definedExternally) + fun write(vararg args: Any /* String | Number */): dynamic /* JsTuple | JsTuple */ +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/lib.dom.kt b/modules/mod2/dukat-custom/lib.dom.kt new file mode 100644 index 0000000..09e0f80 --- /dev/null +++ b/modules/mod2/dukat-custom/lib.dom.kt @@ -0,0 +1,31 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface Coordinates { + var accuracy: Number + var altitude: Number? + var altitudeAccuracy: Number? + var heading: Number? + var latitude: Number + var longitude: Number + var speed: Number? +} + +external interface Position { + var coords: Coordinates + var timestamp: Number +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/lib.es2015.iterable.kt b/modules/mod2/dukat-custom/lib.es2015.iterable.kt new file mode 100644 index 0000000..fd548b7 --- /dev/null +++ b/modules/mod2/dukat-custom/lib.es2015.iterable.kt @@ -0,0 +1,40 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface IteratorYieldResult { + var done: Boolean? + get() = definedExternally + set(value) = definedExternally + var value: TYield +} + +external interface IteratorReturnResult { + var done: Boolean + var value: TReturn +} + +external interface Iterator { + fun next(vararg args: Any /* JsTuple<> | JsTuple */): dynamic /* IteratorYieldResult | IteratorReturnResult */ + val `return`: ((value: TReturn) -> dynamic)? + val `throw`: ((e: Any) -> dynamic)? +} + +typealias Iterator__1 = Iterator + +external interface Iterable + +external interface IterableIterator : Iterator__1 \ No newline at end of file diff --git a/modules/mod2/dukat-custom/lib.es5.kt b/modules/mod2/dukat-custom/lib.es5.kt new file mode 100644 index 0000000..8235e3b --- /dev/null +++ b/modules/mod2/dukat-custom/lib.es5.kt @@ -0,0 +1,74 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface FunctionConstructor { + @nativeInvoke + operator fun invoke(vararg args: String): Function<*> + var prototype: Function<*> +} + +external interface ConcatArray { + var length: Number + @nativeGetter + operator fun get(n: Number): T? + @nativeSetter + operator fun set(n: Number, value: T) + fun join(separator: String = definedExternally): String + fun slice(start: Number = definedExternally, end: Number = definedExternally): Array +} + +external interface ArrayConstructor { + fun from(iterable: Iterable): Array + fun from(iterable: ArrayLike): Array + fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array + fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U): Array + fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array + fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U): Array + fun of(vararg items: T): Array + @nativeInvoke + operator fun invoke(arrayLength: Number = definedExternally): Array + @nativeInvoke + operator fun invoke(): Array + @nativeInvoke + operator fun invoke(arrayLength: Number): Array + @nativeInvoke + operator fun invoke(vararg items: T): Array + fun isArray(arg: Any): Boolean + var prototype: Array +} + +external interface ArrayLike { + var length: Number + @nativeGetter + operator fun get(n: Number): T? + @nativeSetter + operator fun set(n: Number, value: T) +} + +typealias Partial = Any + +typealias Pick = Any + +typealias Record = Any + +typealias Exclude = Any + +typealias Extract = Any + +typealias Omit = Any + +typealias NonNullable = Any \ No newline at end of file diff --git a/modules/mod2/dukat-custom/librariesAndFunctions.module_typed-factorio.kt b/modules/mod2/dukat-custom/librariesAndFunctions.module_typed-factorio.kt new file mode 100644 index 0000000..547ceff --- /dev/null +++ b/modules/mod2/dukat-custom/librariesAndFunctions.module_typed-factorio.kt @@ -0,0 +1,135 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface `T$95` { + var tag: String + var head: String + var body: String + var tail: String + var level: Number +} + +external interface SerpentOptions { + var indent: String + var comment: dynamic /* Boolean | Number */ + get() = definedExternally + set(value) = definedExternally + var sortkeys: dynamic /* Boolean | (this: Unit, keys: Array, table: Any) -> Unit */ + get() = definedExternally + set(value) = definedExternally + var sparse: Boolean + var compact: Boolean + var fatal: Boolean + var nocode: Boolean + var nohuge: Boolean + var maxlevel: Number + var maxnum: Number + var maxlength: Number + var metatostring: Boolean + var numformat: String + var valignore: Array + var keyallow: Array + var keyignore: Array + var valtypeignore: Array + fun custom(opts: `T$95`): String + var name: String + var refcomment: dynamic /* Boolean | Number */ + get() = definedExternally + set(value) = definedExternally + var tablecomment: dynamic /* Boolean | Number */ + get() = definedExternally + set(value) = definedExternally +} + +external interface SerpentOptionsPartial { + var indent: String? + get() = definedExternally + set(value) = definedExternally + var comment: dynamic /* Boolean? | Number? */ + get() = definedExternally + set(value) = definedExternally + var sortkeys: dynamic /* Boolean? | ((this: Unit, keys: Array, table: Any) -> Unit)? */ + get() = definedExternally + set(value) = definedExternally + var sparse: Boolean? + get() = definedExternally + set(value) = definedExternally + var compact: Boolean? + get() = definedExternally + set(value) = definedExternally + var fatal: Boolean? + get() = definedExternally + set(value) = definedExternally + var nocode: Boolean? + get() = definedExternally + set(value) = definedExternally + var nohuge: Boolean? + get() = definedExternally + set(value) = definedExternally + var maxlevel: Number? + get() = definedExternally + set(value) = definedExternally + var maxnum: Number? + get() = definedExternally + set(value) = definedExternally + var maxlength: Number? + get() = definedExternally + set(value) = definedExternally + var metatostring: Boolean? + get() = definedExternally + set(value) = definedExternally + var numformat: String? + get() = definedExternally + set(value) = definedExternally + var valignore: Array? + get() = definedExternally + set(value) = definedExternally + var keyallow: Array? + get() = definedExternally + set(value) = definedExternally + var keyignore: Array? + get() = definedExternally + set(value) = definedExternally + var valtypeignore: Array? + get() = definedExternally + set(value) = definedExternally + var custom: ((opts: `T$95`) -> String)? + get() = definedExternally + set(value) = definedExternally + var name: String? + get() = definedExternally + set(value) = definedExternally + var refcomment: dynamic /* Boolean? | Number? */ + get() = definedExternally + set(value) = definedExternally + var tablecomment: dynamic /* Boolean? | Number? */ + get() = definedExternally + set(value) = definedExternally +} + +external fun log(ls: Any /* JsTuple */) + +external fun log(ls: String) + +external fun log(ls: Number) + +external fun localised_print(ls: Any /* JsTuple */) + +external fun localised_print(ls: String) + +external fun localised_print(ls: Number) + +external fun table_size(tbl: table): Number \ No newline at end of file diff --git a/modules/mod2/dukat-custom/librariesAndFunctions.serpent.module_typed-factorio.kt b/modules/mod2/dukat-custom/librariesAndFunctions.serpent.module_typed-factorio.kt new file mode 100644 index 0000000..223480e --- /dev/null +++ b/modules/mod2/dukat-custom/librariesAndFunctions.serpent.module_typed-factorio.kt @@ -0,0 +1,32 @@ +@file:JsQualifier("serpent") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package serpent + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import SerpentOptionsPartial + +external fun dump(tbl: Any, options: SerpentOptionsPartial = definedExternally): String + +external fun line(tbl: Any, options: SerpentOptionsPartial = definedExternally): String + +external fun block(tbl: Any, options: SerpentOptionsPartial = definedExternally): String + +external interface `T$96` { + var safe: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external fun load(str: String, options: `T$96` = definedExternally): dynamic /* JsTuple | JsTuple */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/math.math.module_lua-types.kt b/modules/mod2/dukat-custom/math.math.module_lua-types.kt new file mode 100644 index 0000000..8012ac2 --- /dev/null +++ b/modules/mod2/dukat-custom/math.math.module_lua-types.kt @@ -0,0 +1,75 @@ +@file:JsQualifier("math") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package math + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun abs(x: Number): Number + +external fun acos(x: Number): Number + +external fun asin(x: Number): Number + +external fun ceil(x: Number): Number + +external fun cos(x: Number): Number + +external fun deg(x: Number): Number + +external fun exp(x: Number): Number + +external fun floor(x: Number): Number + +external fun fmod(x: Number, y: Number): Number + +external var huge: Number + +external fun max(x: Number, vararg numbers: Number): Number + +external fun min(x: Number, vararg numbers: Number): Number + +external fun modf(x: Number): dynamic /* JsTuple */ + +external var pi: Number + +external fun rad(x: Number): Number + +external fun sin(x: Number): Number + +external fun sqrt(x: Number): Number + +external fun tan(x: Number): Number + +external fun log(x: Number, base: Number = definedExternally): Number + +external fun atan(x: Number): Number + +external fun atan2(y: Number, x: Number): Number + +external fun cosh(x: Number): Number + +external fun frexp(x: Number): Number + +external fun ldexp(m: Number, e: Number): Number + +external fun pow(x: Number, y: Number): Number + +external fun sinh(x: Number): Number + +external fun tanh(x: Number): Number + +external fun random(m: Number = definedExternally, n: Number = definedExternally): Number + +external fun randomseed(x: Number): Number \ No newline at end of file diff --git a/modules/mod2/dukat-custom/metatable.module_lua-types.kt b/modules/mod2/dukat-custom/metatable.module_lua-types.kt new file mode 100644 index 0000000..c538a64 --- /dev/null +++ b/modules/mod2/dukat-custom/metatable.module_lua-types.kt @@ -0,0 +1,49 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface LuaMetatable { + val __pairs: ((t: T) -> dynamic)? + val __ipairs: ((t: T) -> dynamic)? + val __add: ((operand: Any) -> Any)? + val __sub: ((operand: Any) -> Any)? + val __mul: ((operand: Any) -> Any)? + val __div: ((operand: Any) -> Any)? + val __mod: ((operand: Any) -> Any)? + val __pow: ((operand: Any) -> Any)? + val __unm: ((operand: Any) -> Any)? + val __concat: ((operand: Any) -> Any)? + val __len: (() -> Any)? + val __eq: ((operand: Any) -> Boolean)? + val __lt: ((operand: Any) -> Boolean)? + val __le: ((operand: Any) -> Boolean)? + var __index: TIndex? + get() = definedExternally + set(value) = definedExternally + var __newindex: dynamic /* Any? | ((this: T, key: Any, value: Any) -> Unit)? */ + get() = definedExternally + set(value) = definedExternally + val __call: ((args: Any) -> Any)? + val __tostring: (() -> String)? + var __mode: String? /* "k" | "v" | "kv" */ + get() = definedExternally + set(value) = definedExternally + var __metatable: Any? + get() = definedExternally + set(value) = definedExternally + val __gc: (() -> Unit)? +} + +external interface LuaMetatable__1 : LuaMetatable Any)? */> \ No newline at end of file diff --git a/modules/mod2/dukat-custom/mod-gui.mod_gui.module_typed-factorio.kt b/modules/mod2/dukat-custom/mod-gui.mod_gui.module_typed-factorio.kt new file mode 100644 index 0000000..64f0b7b --- /dev/null +++ b/modules/mod2/dukat-custom/mod-gui.mod_gui.module_typed-factorio.kt @@ -0,0 +1,29 @@ +@file:JsModule("mod-gui") +@file:JsNonModule +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package mod_gui + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import LuaPlayer +import FrameGuiElementMembers +import FlowGuiElementMembers + +external var button_style: String + +external var frame_style: String + +external fun get_button_flow(player: LuaPlayer): FrameGuiElementMembers /* FrameGuiElementMembers & GuiElementIndex */ + +external fun get_frame_flow(player: LuaPlayer): FlowGuiElementMembers /* FlowGuiElementMembers & GuiElementIndex */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/modules.module_lua-types.kt b/modules/mod2/dukat-custom/modules.module_lua-types.kt new file mode 100644 index 0000000..b4ffe28 --- /dev/null +++ b/modules/mod2/dukat-custom/modules.module_lua-types.kt @@ -0,0 +1,17 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun require(modname: String): Any \ No newline at end of file diff --git a/modules/mod2/dukat-custom/modules.package.module_lua-types.kt b/modules/mod2/dukat-custom/modules.package.module_lua-types.kt new file mode 100644 index 0000000..fefc008 --- /dev/null +++ b/modules/mod2/dukat-custom/modules.package.module_lua-types.kt @@ -0,0 +1,34 @@ +@file:JsQualifier("package") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package `package` + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import tsstdlib.Record + +external var config: String + +external var cpath: String + +external var loaded: Record + +external fun loadlib(libname: String, funcname: String): dynamic /* JsTuple> | JsTuple */ + +external var path: String + +external var preload: Record Any> + +external fun searchpath(name: String, path: String, sep: String = definedExternally, rep: String = definedExternally): String + +external var searchers: Array dynamic | (modname: String) -> dynamic | String */> \ No newline at end of file diff --git a/modules/mod2/dukat-custom/nonDeclarations.io.kt b/modules/mod2/dukat-custom/nonDeclarations.io.kt new file mode 100644 index 0000000..3fc06db --- /dev/null +++ b/modules/mod2/dukat-custom/nonDeclarations.io.kt @@ -0,0 +1,18 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package io + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +typealias FileReadFormatToType = Any \ No newline at end of file diff --git a/modules/mod2/dukat-custom/os.module_lua-types.kt b/modules/mod2/dukat-custom/os.module_lua-types.kt new file mode 100644 index 0000000..a6818b4 --- /dev/null +++ b/modules/mod2/dukat-custom/os.module_lua-types.kt @@ -0,0 +1,45 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface LuaDateInfo { + var year: Number + var month: Number + var day: Number + var hour: Number? + get() = definedExternally + set(value) = definedExternally + var min: Number? + get() = definedExternally + set(value) = definedExternally + var sec: Number? + get() = definedExternally + set(value) = definedExternally + var isdst: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface LuaDateInfoResult { + var year: Number + var month: Number + var day: Number + var hour: Number + var min: Number + var sec: Number + var isdst: Boolean + var yday: Number + var wday: Number +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/os.os.module_lua-types.kt b/modules/mod2/dukat-custom/os.os.module_lua-types.kt new file mode 100644 index 0000000..9fc56e1 --- /dev/null +++ b/modules/mod2/dukat-custom/os.os.module_lua-types.kt @@ -0,0 +1,56 @@ +@file:JsQualifier("os") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package os + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import LuaDateInfo + +external fun clock(): Number + +external fun date(format: String /* "*t" */ = definedExternally, time: Number = definedExternally): dynamic /* String | LuaDateInfoResult */ + +external fun date(): String + +external fun date(format: String /* "*t" */ = definedExternally): dynamic /* String | LuaDateInfoResult */ + +external fun difftime(t1: Number, t2: Number): Number + +external fun getenv(varname: String): String? + +external fun remove(filename: String): dynamic /* JsTuple | JsTuple */ + +external fun rename(oldname: String, newname: String): dynamic /* JsTuple | JsTuple */ + +external fun setlocale(locale: String = definedExternally, category: String /* "all" | "collate" | "ctype" | "monetary" | "numeric" | "time" */ = definedExternally): String? + +external fun time(): Number + +external fun time(table: LuaDateInfo): Number + +external fun tmpname(): String + +external fun execute(): Boolean + +external fun execute(command: String): dynamic /* JsTuple */ + +external fun exit(code: Boolean = definedExternally, close: Boolean = definedExternally): Any + +external fun exit(): Any + +external fun exit(code: Boolean = definedExternally): Any + +external fun exit(code: Number = definedExternally, close: Boolean = definedExternally): Any + +external fun exit(code: Number = definedExternally): Any \ No newline at end of file diff --git a/modules/mod2/dukat-custom/pairs.module_typed-factorio.kt b/modules/mod2/dukat-custom/pairs.module_typed-factorio.kt new file mode 100644 index 0000000..18d966d --- /dev/null +++ b/modules/mod2/dukat-custom/pairs.module_typed-factorio.kt @@ -0,0 +1,22 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import tsstdlib.Iterable + +external fun pairs(table: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */): Iterable */> /* Iterable */> & LuaIterator */, undefined> & LuaExtension */ + +external fun pairs(table: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */): Iterable */> /* Iterable */> & LuaIterator */, undefined> & LuaExtension */ + +external fun ipairs(table: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */): Any \ No newline at end of file diff --git a/modules/mod2/dukat-custom/string.string.module_lua-types.kt b/modules/mod2/dukat-custom/string.string.module_lua-types.kt new file mode 100644 index 0000000..8910e62 --- /dev/null +++ b/modules/mod2/dukat-custom/string.string.module_lua-types.kt @@ -0,0 +1,63 @@ +@file:JsQualifier("string") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package string + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import tsstdlib.Iterable +import tsstdlib.Record + +external fun byte(s: String, i: Number = definedExternally): dynamic /* Number | Array */ + +external fun byte(s: String): dynamic /* Number | Array */ + +external fun byte(s: String, i: Number = definedExternally, j: Number = definedExternally): Array /* Array & LuaExtension */ + +external fun char(vararg args: Number): String + +external fun dump(func: Function<*>): String + +external fun find(s: String, pattern: String, init: Number = definedExternally, plain: Boolean = definedExternally): dynamic /* JsTuple | JsTuple<> */ + +external fun format(formatstring: String, vararg args: Any): String + +external fun gmatch(s: String, pattern: String): Iterable /* Array & LuaExtension */> /* Iterable /* Array & LuaExtension */> & LuaIterator /* Array & LuaExtension */, undefined> & LuaExtension */ + +external fun gsub(s: String, pattern: String, repl: String, n: Number = definedExternally): dynamic /* JsTuple */ + +external fun gsub(s: String, pattern: String, repl: String): dynamic /* JsTuple */ + +external fun gsub(s: String, pattern: String, repl: Record, n: Number = definedExternally): dynamic /* JsTuple */ + +external fun gsub(s: String, pattern: String, repl: Record): dynamic /* JsTuple */ + +external fun gsub(s: String, pattern: String, repl: (matches: String) -> String, n: Number = definedExternally): dynamic /* JsTuple */ + +external fun gsub(s: String, pattern: String, repl: (matches: String) -> String): dynamic /* JsTuple */ + +external fun len(s: String): Number + +external fun lower(s: String): String + +external fun match(s: String, pattern: String, init: Number = definedExternally): Array /* Array & LuaExtension */ + +external fun rep(s: String, n: Number): String + +external fun reverse(s: String): String + +external fun sub(s: String, i: Number, j: Number = definedExternally): String + +external fun upper(s: String): String + +external fun rep(s: String, n: Number, sep: String = definedExternally): String \ No newline at end of file diff --git a/modules/mod2/dukat-custom/table.table.module_lua-types.kt b/modules/mod2/dukat-custom/table.table.module_lua-types.kt new file mode 100644 index 0000000..63cd957 --- /dev/null +++ b/modules/mod2/dukat-custom/table.table.module_lua-types.kt @@ -0,0 +1,39 @@ +@file:JsQualifier("table") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package table + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun concat(list: Array, sep: String = definedExternally, i: Number = definedExternally, j: Number = definedExternally): String + +external fun insert(list: Array, value: T) + +external fun insert(list: Array, pos: Number, value: T) + +external fun remove(list: Array, pos: Number = definedExternally): T? + +external fun sort(list: Array, comp: (a: T, b: T) -> Boolean = definedExternally) + +external fun > unpack(list: T): T /* T & LuaExtension */ + +external fun unpack(list: Array, i: Number, j: Number = definedExternally): Array /* Array & LuaExtension */ + +external fun unpack(list: Array, i: Number): Array /* Array & LuaExtension */ + +external interface `T$92` { + var n: Number +} + +external fun > pack(vararg args: T): T /* T & `T$92` */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/types.module_typed-factorio.kt b/modules/mod2/dukat-custom/types.module_typed-factorio.kt new file mode 100644 index 0000000..11d34eb --- /dev/null +++ b/modules/mod2/dukat-custom/types.module_typed-factorio.kt @@ -0,0 +1,91 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import tsstdlib.Record + +external interface BaseSettingDefinition { + var type: String /* "bool-setting" | "int-setting" | "double-setting" | "string-setting" */ + var name: String + var localized_name: dynamic /* JsTuple | String? | Number? */ + get() = definedExternally + set(value) = definedExternally + var localized_description: dynamic /* JsTuple | String? | Number? */ + get() = definedExternally + set(value) = definedExternally + var order: String? + get() = definedExternally + set(value) = definedExternally + var hidden: Boolean? + get() = definedExternally + set(value) = definedExternally + var setting_type: String /* "startup" | "runtime-global" | "runtime-per-user" */ +} + +external interface BoolSettingDefinition : BaseSettingDefinition { + override var type: String /* "bool-setting" */ + var default_value: Boolean + var forced_value: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface IntSettingDefinition : BaseSettingDefinition { + override var type: String /* "int-setting" */ + var default_value: Number + var minimum_value: Number? + get() = definedExternally + set(value) = definedExternally + var maximum_value: Number? + get() = definedExternally + set(value) = definedExternally + var allowed_values: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface DoubleSettingDefinition : BaseSettingDefinition { + override var type: String /* "double-setting" */ + var default_value: Number + var minimum_value: Number? + get() = definedExternally + set(value) = definedExternally + var maximum_value: Number? + get() = definedExternally + set(value) = definedExternally + var allowed_values: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface StringSettingDefinition : BaseSettingDefinition { + override var type: String /* "string-setting" */ + var default_value: String + var allow_blank: Boolean? + get() = definedExternally + set(value) = definedExternally + var auto_trim: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowed_values: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface Data { + var raw: Any + fun extend(prototypes: Array) +} + +typealias Mods = Record \ No newline at end of file diff --git a/modules/mod2/dukat-custom/util.util.module_typed-factorio.kt b/modules/mod2/dukat-custom/util.util.module_typed-factorio.kt new file mode 100644 index 0000000..843ae01 --- /dev/null +++ b/modules/mod2/dukat-custom/util.util.module_typed-factorio.kt @@ -0,0 +1,111 @@ +@file:JsModule("util") +@file:JsNonModule +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package util + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import tsstdlib.Position +import ColorTable +import defines.direction +import LuaEntity +import tsstdlib.Record +import LuaTable + +external fun copy(table: T): T + +external fun distance(position1: Position, position2: Position): Number + +external fun positiontostr(position: Position): String + +external fun formattime(ticks: Number): String + +external fun color(hex: String): ColorTable + +external fun premul_color(color: ColorTable): ColorTable + +external fun premul_color(color: Any /* JsTuple */): ColorTable + +external fun mix_color(c1: ColorTable, c2: ColorTable): dynamic /* JsTuple */ + +external fun mix_color(c1: ColorTable, c2: Any /* JsTuple */): dynamic /* JsTuple */ + +external fun mix_color(c1: Any /* JsTuple */, c2: ColorTable): dynamic /* JsTuple */ + +external fun mix_color(c1: Any /* JsTuple */, c2: Any /* JsTuple */): dynamic /* JsTuple */ + +external fun multiply_color(c1: ColorTable, n: Number): dynamic /* JsTuple */ + +external fun multiply_color(c1: Any /* JsTuple */, n: Number): dynamic /* JsTuple */ + +external fun moveposition(position: Position, direction: defines.direction.north, distance: Number): Position + +external fun moveposition(position: Position, direction: defines.direction.east, distance: Number): Position + +external fun moveposition(position: Position, direction: defines.direction.south, distance: Number): Position + +external fun moveposition(position: Position, direction: defines.direction.west, distance: Number): Position + +external fun moveposition(position: Position, direction: direction, distance: Number): Position? + +external fun oppositedirection(direction: direction): direction + +external fun multiplystripes(count: Number, stripes: Array): Array + +external fun by_pixel(x: Number, y: Number): Position + +external fun by_pixel_hr(x: Number, y: Number): Position + +external fun add_shift(a: Any /* JsTuple */, b: Any /* JsTuple */): dynamic /* JsTuple */ + +external fun mul_shift(shift: Any /* JsTuple */, scale: Number?): dynamic /* JsTuple */ + +external fun format_number(amount: Number, append_suffix: Boolean = definedExternally): String + +external fun increment(t: Array, index: Number, v: Number = definedExternally) + +external fun merge(tables: Array): T + +external fun insert_safe(entity: LuaEntity?, item_dict: Record?) + +external fun remove_safe(entity: LuaEntity?, item_dict: Record?) + +external fun split_whitespace(string: String): Array + +external fun clamp(x: Number, lower: Number, upper: Number): Number + +external fun parse_energy(energy: String): Number + +external interface `T$97` { + var probability: Number +} + +external interface `T$98` { + var amount: Number +} + +external interface `T$99` { + var amount_min: Number + var amount_max: Number +} + +external fun product_amount(product: `T$97` /* `T$97` & dynamic */): Number + +external fun empty_sprite(): Any? + +external fun remove_from_list(list: Array, value: T): Boolean + +external fun list_to_map(list: Array): dynamic /* Record | LuaTable */ + +external fun list_to_map(list: T): LuaTable \ No newline at end of file diff --git a/modules/mod2/dukat-custom/util.util.table.module_typed-factorio.kt b/modules/mod2/dukat-custom/util.util.table.module_typed-factorio.kt new file mode 100644 index 0000000..bd20fee --- /dev/null +++ b/modules/mod2/dukat-custom/util.util.table.module_typed-factorio.kt @@ -0,0 +1,21 @@ +@file:JsQualifier("util.table") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package util.table + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun deepcopy(table: T): T + +external fun compare(tb1: T, tb2: T): Boolean \ No newline at end of file diff --git a/modules/mod2/externals/CompilerOptions.module_typescript-to-lua.kt b/modules/mod2/externals/CompilerOptions.module_typescript-to-lua.kt new file mode 100644 index 0000000..a6740d0 --- /dev/null +++ b/modules/mod2/externals/CompilerOptions.module_typescript-to-lua.kt @@ -0,0 +1,75 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.CompilerOptions +import ts.Diagnostic + +typealias OmitIndexSignature = Any + +external interface TransformerImport { + var transform: String + var import: String? + get() = definedExternally + set(value) = definedExternally + var after: Boolean? + get() = definedExternally + set(value) = definedExternally + var afterDeclarations: Boolean? + get() = definedExternally + set(value) = definedExternally + var type: String? /* "program" | "config" | "checker" | "raw" | "compilerOptions" */ + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): Any? + @nativeSetter + operator fun set(option: String, value: Any) +} + +external interface LuaPluginImport { + var name: String + var import: String? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): Any? + @nativeSetter + operator fun set(option: String, value: Any) +} + +external enum class LuaLibImportKind { + None /* = "none" */, + Always /* = "always" */, + Inline /* = "inline" */, + Require /* = "require" */ +} + +external enum class LuaTarget { + Universal /* = "universal" */, + Lua51 /* = "5.1" */, + Lua52 /* = "5.2" */, + Lua53 /* = "5.3" */, + Lua54 /* = "5.4" */, + LuaJIT /* = "JIT" */ +} + +external enum class BuildMode { + Default /* = "default" */, + Library /* = "library" */ +} + +external var isBundleEnabled: (options: OmitIndexSignature /* OmitIndexSignature & `T$0` */) -> Boolean + +external fun validateOptions(options: OmitIndexSignature /* OmitIndexSignature & `T$0` */): Array \ No newline at end of file diff --git a/modules/mod2/externals/LuaAST.module_typescript-to-lua.kt b/modules/mod2/externals/LuaAST.module_typescript-to-lua.kt new file mode 100644 index 0000000..079e37f --- /dev/null +++ b/modules/mod2/externals/LuaAST.module_typescript-to-lua.kt @@ -0,0 +1,485 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import tsstdlib.Set + +external enum class SyntaxKind { + File /* = 0 */, + Block /* = 1 */, + DoStatement /* = 2 */, + VariableDeclarationStatement /* = 3 */, + AssignmentStatement /* = 4 */, + IfStatement /* = 5 */, + WhileStatement /* = 6 */, + RepeatStatement /* = 7 */, + ForStatement /* = 8 */, + ForInStatement /* = 9 */, + GotoStatement /* = 10 */, + LabelStatement /* = 11 */, + ReturnStatement /* = 12 */, + BreakStatement /* = 13 */, + ExpressionStatement /* = 14 */, + StringLiteral /* = 15 */, + NumericLiteral /* = 16 */, + NilKeyword /* = 17 */, + DotsKeyword /* = 18 */, + TrueKeyword /* = 19 */, + FalseKeyword /* = 20 */, + FunctionExpression /* = 21 */, + TableFieldExpression /* = 22 */, + TableExpression /* = 23 */, + UnaryExpression /* = 24 */, + BinaryExpression /* = 25 */, + CallExpression /* = 26 */, + MethodCallExpression /* = 27 */, + Identifier /* = 28 */, + TableIndexExpression /* = 29 */, + AdditionOperator /* = 30 */, + SubtractionOperator /* = 31 */, + MultiplicationOperator /* = 32 */, + DivisionOperator /* = 33 */, + FloorDivisionOperator /* = 34 */, + ModuloOperator /* = 35 */, + PowerOperator /* = 36 */, + NegationOperator /* = 37 */, + ConcatOperator /* = 38 */, + LengthOperator /* = 39 */, + EqualityOperator /* = 40 */, + InequalityOperator /* = 41 */, + LessThanOperator /* = 42 */, + LessEqualOperator /* = 43 */, + GreaterThanOperator /* = 44 */, + GreaterEqualOperator /* = 45 */, + AndOperator /* = 46 */, + OrOperator /* = 47 */, + NotOperator /* = 48 */, + BitwiseAndOperator /* = 49 */, + BitwiseOrOperator /* = 50 */, + BitwiseExclusiveOrOperator /* = 51 */, + BitwiseRightShiftOperator /* = 52 */, + BitwiseLeftShiftOperator /* = 53 */, + BitwiseNotOperator /* = 54 */ +} + +typealias UnaryBitwiseOperator = SyntaxKind.BitwiseNotOperator + +external interface TextRange { + var line: Number? + get() = definedExternally + set(value) = definedExternally + var column: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface Node : TextRange { + var kind: SyntaxKind +} + +external fun createNode(kind: SyntaxKind, tsOriginal: ts.Node = definedExternally): Node + +external fun cloneNode(node: T): T + +external fun setNodePosition(node: T, position: TextRange): T + +external fun setNodeOriginal(node: T, tsOriginal: ts.Node): T + +external fun setNodeOriginal(node: T?, tsOriginal: ts.Node): T? + +external fun getOriginalPos(node: Node): TextRange + +external interface File : Node { + var statements: Array + var luaLibFeatures: Set + var trivia: String +} + +external fun isFile(node: Node): Boolean + +external fun createFile(statements: Array, luaLibFeatures: Set, trivia: String, tsOriginal: ts.Node = definedExternally): File + +external interface Block : Node { + var statements: Array +} + +external fun isBlock(node: Node): Boolean + +external fun createBlock(statements: Array, tsOriginal: ts.Node = definedExternally): Block + +external interface Statement : Node { + var _statementBrand: Any + var leadingComments: Array */>? + get() = definedExternally + set(value) = definedExternally + var trailingComments: Array */>? + get() = definedExternally + set(value) = definedExternally +} + +external interface DoStatement : Statement { + var statements: Array +} + +external fun isDoStatement(node: Node): Boolean + +external fun createDoStatement(statements: Array, tsOriginal: ts.Node = definedExternally): DoStatement + +external interface VariableDeclarationStatement : Statement { + var left: Array + var right: Array? + get() = definedExternally + set(value) = definedExternally +} + +external fun isVariableDeclarationStatement(node: Node): Boolean + +external fun createVariableDeclarationStatement(left: Identifier, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Identifier): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Identifier, right: Expression = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Identifier, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Identifier, right: Array = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array, right: Expression = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement + +external fun createVariableDeclarationStatement(left: Array, right: Array = definedExternally): VariableDeclarationStatement + +external interface AssignmentStatement : Statement { + var left: Array + var right: Array +} + +external fun isAssignmentStatement(node: Node): Boolean + +external fun createAssignmentStatement(left: Identifier, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Identifier): AssignmentStatement + +external fun createAssignmentStatement(left: Identifier, right: Expression = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Identifier, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Identifier, right: Array = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression, right: Expression = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: TableIndexExpression, right: Array = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Array, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Array): AssignmentStatement + +external fun createAssignmentStatement(left: Array, right: Expression = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Array, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement + +external fun createAssignmentStatement(left: Array, right: Array = definedExternally): AssignmentStatement + +external interface IfStatement : Statement { + var condition: Expression + var ifBlock: Block + var elseBlock: dynamic /* Block? | IfStatement? */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isIfStatement(node: Node): Boolean + +external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: Block = definedExternally, tsOriginal: ts.Node = definedExternally): IfStatement + +external fun createIfStatement(condition: Expression, ifBlock: Block): IfStatement + +external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: Block = definedExternally): IfStatement + +external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: IfStatement = definedExternally, tsOriginal: ts.Node = definedExternally): IfStatement + +external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: IfStatement = definedExternally): IfStatement + +external interface IterationStatement : Statement { + var body: Block +} + +external fun isIterationStatement(node: Node): Boolean + +external interface WhileStatement : IterationStatement { + var condition: Expression +} + +external fun isWhileStatement(node: Node): Boolean + +external fun createWhileStatement(body: Block, condition: Expression, tsOriginal: ts.Node = definedExternally): WhileStatement + +external interface RepeatStatement : IterationStatement { + var condition: Expression +} + +external fun isRepeatStatement(node: Node): Boolean + +external fun createRepeatStatement(body: Block, condition: Expression, tsOriginal: ts.Node = definedExternally): RepeatStatement + +external interface ForStatement : IterationStatement { + var controlVariable: Identifier + var controlVariableInitializer: Expression + var limitExpression: Expression + var stepExpression: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external fun isForStatement(node: Node): Boolean + +external fun createForStatement(body: Block, controlVariable: Identifier, controlVariableInitializer: Expression, limitExpression: Expression, stepExpression: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): ForStatement + +external interface ForInStatement : IterationStatement { + var names: Array + var expressions: Array +} + +external fun isForInStatement(node: Node): Boolean + +external fun createForInStatement(body: Block, names: Array, expressions: Array, tsOriginal: ts.Node = definedExternally): ForInStatement + +external interface GotoStatement : Statement { + var label: String +} + +external fun isGotoStatement(node: Node): Boolean + +external fun createGotoStatement(label: String, tsOriginal: ts.Node = definedExternally): GotoStatement + +external interface LabelStatement : Statement { + var name: String +} + +external fun isLabelStatement(node: Node): Boolean + +external fun createLabelStatement(name: String, tsOriginal: ts.Node = definedExternally): LabelStatement + +external interface ReturnStatement : Statement { + var expressions: Array +} + +external fun isReturnStatement(node: Node): Boolean + +external fun createReturnStatement(expressions: Array, tsOriginal: ts.Node = definedExternally): ReturnStatement + +external interface BreakStatement : Statement + +external fun isBreakStatement(node: Node): Boolean + +external fun createBreakStatement(tsOriginal: ts.Node = definedExternally): BreakStatement + +external interface ExpressionStatement : Statement { + var expression: Expression +} + +external fun isExpressionStatement(node: Node): Boolean + +external fun createExpressionStatement(expressions: Expression, tsOriginal: ts.Node = definedExternally): ExpressionStatement + +external interface Expression : Node { + var _expressionBrand: Any +} + +external interface NilLiteral : Expression + +external fun isNilLiteral(node: Node): Boolean + +external fun createNilLiteral(tsOriginal: ts.Node = definedExternally): NilLiteral + +external interface BooleanLiteral : Expression { + override var kind: dynamic /* SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isBooleanLiteral(node: Node): Boolean + +external fun createBooleanLiteral(value: Boolean, tsOriginal: ts.Node = definedExternally): BooleanLiteral + +external interface DotsLiteral : Expression + +external fun isDotsLiteral(node: Node): Boolean + +external fun createDotsLiteral(tsOriginal: ts.Node = definedExternally): DotsLiteral + +external interface NumericLiteral : Expression { + var value: Number +} + +external fun isNumericLiteral(node: Node): Boolean + +external fun createNumericLiteral(value: Number, tsOriginal: ts.Node = definedExternally): NumericLiteral + +external interface StringLiteral : Expression { + var value: String +} + +external fun isStringLiteral(node: Node): Boolean + +external fun createStringLiteral(value: String, tsOriginal: ts.Node = definedExternally): StringLiteral + +external enum class FunctionExpressionFlags { + None /* = 1 */, + Inline /* = 2 */, + Declaration /* = 4 */ +} + +external interface FunctionExpression : Expression { + var params: Array? + get() = definedExternally + set(value) = definedExternally + var dots: DotsLiteral? + get() = definedExternally + set(value) = definedExternally + var body: Block + var flags: FunctionExpressionFlags +} + +external fun isFunctionExpression(node: Node): Boolean + +external fun createFunctionExpression(body: Block, params: Array = definedExternally, dots: DotsLiteral = definedExternally, flags: FunctionExpressionFlags = definedExternally, tsOriginal: ts.Node = definedExternally): FunctionExpression + +external interface TableFieldExpression : Expression { + var value: Expression + var key: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external fun isTableFieldExpression(node: Node): Boolean + +external fun createTableFieldExpression(value: Expression, key: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): TableFieldExpression + +external interface TableExpression : Expression { + var fields: Array +} + +external fun isTableExpression(node: Node): Boolean + +external fun createTableExpression(fields: Array = definedExternally, tsOriginal: ts.Node = definedExternally): TableExpression + +external interface UnaryExpression : Expression { + var operand: Expression + var operator: dynamic /* SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isUnaryExpression(node: Node): Boolean + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NegationOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NegationOperator): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.LengthOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.LengthOperator): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NotOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NotOperator): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: UnaryBitwiseOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression + +external fun createUnaryExpression(operand: Expression, operator: UnaryBitwiseOperator): UnaryExpression + +external interface BinaryExpression : Expression { + var operator: dynamic /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */ + get() = definedExternally + set(value) = definedExternally + var left: Expression + var right: Expression +} + +external fun isBinaryExpression(node: Node): Boolean + +external fun createBinaryExpression(left: Expression, right: Expression, operator: Any /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */, tsOriginal: ts.Node = definedExternally): BinaryExpression + +external interface CallExpression : Expression { + var expression: Expression + var params: Array +} + +external fun isCallExpression(node: Node): Boolean + +external fun createCallExpression(expression: Expression, params: Array, tsOriginal: ts.Node = definedExternally): CallExpression + +external interface MethodCallExpression : Expression { + var prefixExpression: Expression + var name: Identifier + var params: Array +} + +external fun isMethodCallExpression(node: Node): Boolean + +external fun createMethodCallExpression(prefixExpression: Expression, name: Identifier, params: Array, tsOriginal: ts.Node = definedExternally): MethodCallExpression + +external interface Identifier : Expression { + var exportable: Boolean + var text: String + var originalName: String? + get() = definedExternally + set(value) = definedExternally + var symbolId: Number? /* Number? & `T$14`? */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isIdentifier(node: Node): Boolean + +external fun createIdentifier(text: String, tsOriginal: ts.Node = definedExternally, symbolId: Number /* Number & `T$14` */ = definedExternally, originalName: String = definedExternally): Identifier + +external fun cloneIdentifier(identifier: Identifier, tsOriginal: ts.Node = definedExternally): Identifier + +external fun createAnonymousIdentifier(tsOriginal: ts.Node = definedExternally): Identifier + +external interface TableIndexExpression : Expression { + var table: Expression + var index: Expression +} + +external fun isTableIndexExpression(node: Node): Boolean + +external fun createTableIndexExpression(table: Expression, index: Expression, tsOriginal: ts.Node = definedExternally): TableIndexExpression + +external fun isAssignmentLeftHandSideExpression(node: Node): Boolean + +external fun isFunctionDefinition(statement: VariableDeclarationStatement): Boolean + +external fun isFunctionDefinition(statement: AssignmentStatement): Boolean + +external interface `T$17` { + var statements: dynamic /* JsTuple */ + get() = definedExternally + set(value) = definedExternally +} + +external fun isInlineFunctionExpression(expression: FunctionExpression): Boolean \ No newline at end of file diff --git a/modules/mod2/externals/LuaLib.module_typescript-to-lua.kt b/modules/mod2/externals/LuaLib.module_typescript-to-lua.kt new file mode 100644 index 0000000..f00c242 --- /dev/null +++ b/modules/mod2/externals/LuaLib.module_typescript-to-lua.kt @@ -0,0 +1,111 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external enum class LuaLibFeature { + ArrayConcat /* = "ArrayConcat" */, + ArrayEntries /* = "ArrayEntries" */, + ArrayEvery /* = "ArrayEvery" */, + ArrayFilter /* = "ArrayFilter" */, + ArrayForEach /* = "ArrayForEach" */, + ArrayFind /* = "ArrayFind" */, + ArrayFindIndex /* = "ArrayFindIndex" */, + ArrayIncludes /* = "ArrayIncludes" */, + ArrayIndexOf /* = "ArrayIndexOf" */, + ArrayIsArray /* = "ArrayIsArray" */, + ArrayJoin /* = "ArrayJoin" */, + ArrayMap /* = "ArrayMap" */, + ArrayPush /* = "ArrayPush" */, + ArrayReduce /* = "ArrayReduce" */, + ArrayReduceRight /* = "ArrayReduceRight" */, + ArrayReverse /* = "ArrayReverse" */, + ArrayShift /* = "ArrayShift" */, + ArrayUnshift /* = "ArrayUnshift" */, + ArraySort /* = "ArraySort" */, + ArraySlice /* = "ArraySlice" */, + ArraySome /* = "ArraySome" */, + ArraySplice /* = "ArraySplice" */, + ArrayToObject /* = "ArrayToObject" */, + ArrayFlat /* = "ArrayFlat" */, + ArrayFlatMap /* = "ArrayFlatMap" */, + ArraySetLength /* = "ArraySetLength" */, + Await /* = "Await" */, + Class /* = "Class" */, + ClassExtends /* = "ClassExtends" */, + CloneDescriptor /* = "CloneDescriptor" */, + Decorate /* = "Decorate" */, + DecorateParam /* = "DecorateParam" */, + Delete /* = "Delete" */, + DelegatedYield /* = "DelegatedYield" */, + Error /* = "Error" */, + FunctionBind /* = "FunctionBind" */, + Generator /* = "Generator" */, + InstanceOf /* = "InstanceOf" */, + InstanceOfObject /* = "InstanceOfObject" */, + Iterator /* = "Iterator" */, + Map /* = "Map" */, + MathAtan2 /* = "MathAtan2" */, + New /* = "New" */, + Number /* = "Number" */, + NumberIsFinite /* = "NumberIsFinite" */, + NumberIsNaN /* = "NumberIsNaN" */, + NumberToString /* = "NumberToString" */, + ObjectAssign /* = "ObjectAssign" */, + ObjectDefineProperty /* = "ObjectDefineProperty" */, + ObjectEntries /* = "ObjectEntries" */, + ObjectFromEntries /* = "ObjectFromEntries" */, + ObjectGetOwnPropertyDescriptor /* = "ObjectGetOwnPropertyDescriptor" */, + ObjectGetOwnPropertyDescriptors /* = "ObjectGetOwnPropertyDescriptors" */, + ObjectKeys /* = "ObjectKeys" */, + ObjectRest /* = "ObjectRest" */, + ObjectValues /* = "ObjectValues" */, + OptionalChainAccess /* = "OptionalChainAccess" */, + OptionalFunctionCall /* = "OptionalFunctionCall" */, + OptionalMethodCall /* = "OptionalMethodCall" */, + ParseFloat /* = "ParseFloat" */, + ParseInt /* = "ParseInt" */, + Promise /* = "Promise" */, + PromiseAll /* = "PromiseAll" */, + PromiseAllSettled /* = "PromiseAllSettled" */, + PromiseAny /* = "PromiseAny" */, + PromiseRace /* = "PromiseRace" */, + Set /* = "Set" */, + SetDescriptor /* = "SetDescriptor" */, + WeakMap /* = "WeakMap" */, + WeakSet /* = "WeakSet" */, + SourceMapTraceBack /* = "SourceMapTraceBack" */, + Spread /* = "Spread" */, + StringAccess /* = "StringAccess" */, + StringCharAt /* = "StringCharAt" */, + StringCharCodeAt /* = "StringCharCodeAt" */, + StringConcat /* = "StringConcat" */, + StringEndsWith /* = "StringEndsWith" */, + StringIncludes /* = "StringIncludes" */, + StringPadEnd /* = "StringPadEnd" */, + StringPadStart /* = "StringPadStart" */, + StringReplace /* = "StringReplace" */, + StringSlice /* = "StringSlice" */, + StringSplit /* = "StringSplit" */, + StringStartsWith /* = "StringStartsWith" */, + StringSubstr /* = "StringSubstr" */, + StringSubstring /* = "StringSubstring" */, + StringTrim /* = "StringTrim" */, + StringTrimEnd /* = "StringTrimEnd" */, + StringTrimStart /* = "StringTrimStart" */, + Symbol /* = "Symbol" */, + SymbolRegistry /* = "SymbolRegistry" */, + TypeOf /* = "TypeOf" */, + Unpack /* = "Unpack" */ +} \ No newline at end of file diff --git a/modules/mod2/externals/LuaPrinter.module_typescript-to-lua.kt b/modules/mod2/externals/LuaPrinter.module_typescript-to-lua.kt new file mode 100644 index 0000000..6428653 --- /dev/null +++ b/modules/mod2/externals/LuaPrinter.module_typescript-to-lua.kt @@ -0,0 +1,101 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.Program + +external var escapeString: (value: String) -> String + +external var tstlHeader: Any + +typealias Printer = (program: Program, emitHost: EmitHost, fileName: String, file: File) -> PrintResult + +external interface PrintResult { + var code: String + var sourceMap: String + var sourceMapNode: SourceNode +} + +external fun createPrinter(printers: Array): Printer + +external open class LuaPrinter(emitHost: EmitHost, program: Program, fileName: String) { + open var emitHost: Any + open var currentIndent: Any + open var sourceFile: Any + open var options: Any + open fun print(file: File): PrintResult + open var printInlineSourceMap: Any + open var printStackTraceOverride: Any + open var printFile: Any + open fun pushIndent() + open fun popIndent() + open fun indent(input: String = definedExternally): dynamic /* String | SourceNode */ + open fun indent(): dynamic /* String | SourceNode */ + open fun indent(input: SourceNode = definedExternally): dynamic /* String | SourceNode */ + open fun createSourceNode(node: Node, chunks: String, name: String = definedExternally): SourceNode + open fun createSourceNode(node: Node, chunks: String): SourceNode + open fun createSourceNode(node: Node, chunks: SourceNode, name: String = definedExternally): SourceNode + open fun createSourceNode(node: Node, chunks: SourceNode): SourceNode + open fun createSourceNode(node: Node, chunks: Array, name: String = definedExternally): SourceNode + open fun createSourceNode(node: Node, chunks: Array): SourceNode + open fun concatNodes(vararg chunks: Any /* String | SourceNode */): SourceNode + open fun printBlock(block: Block): SourceNode + open var statementMayRequireSemiColon: Any + open var nodeStartsWithParenthesis: Any + open fun printStatementArray(statements: Array): Array + open fun printStatement(statement: Statement): SourceNode + open fun printComment(comment: String): dynamic /* String | SourceNode */ + open fun printComment(comment: Array): dynamic /* String | SourceNode */ + open fun printStatementExcludingComments(statement: Statement): SourceNode + open fun printDoStatement(statement: DoStatement): SourceNode + open fun printVariableDeclarationStatement(statement: VariableDeclarationStatement): SourceNode + open fun printVariableAssignmentStatement(statement: AssignmentStatement): SourceNode + open fun printIfStatement(statement: IfStatement, isElseIf: Boolean = definedExternally): SourceNode + open fun printWhileStatement(statement: WhileStatement): SourceNode + open fun printRepeatStatement(statement: RepeatStatement): SourceNode + open fun printForStatement(statement: ForStatement): SourceNode + open fun printForInStatement(statement: ForInStatement): SourceNode + open fun printGotoStatement(statement: GotoStatement): SourceNode + open fun printLabelStatement(statement: LabelStatement): SourceNode + open fun printReturnStatement(statement: ReturnStatement): SourceNode + open fun printBreakStatement(statement: BreakStatement): SourceNode + open fun printExpressionStatement(statement: ExpressionStatement): SourceNode + open fun printExpression(expression: Expression): SourceNode + open fun printStringLiteral(expression: StringLiteral): SourceNode + open fun printNumericLiteral(expression: NumericLiteral): SourceNode + open fun printNilLiteral(expression: NilLiteral): SourceNode + open fun printDotsLiteral(expression: DotsLiteral): SourceNode + open fun printBooleanLiteral(expression: BooleanLiteral): SourceNode + open var printFunctionParameters: Any + open fun printFunctionExpression(expression: FunctionExpression): SourceNode + open fun printFunctionDefinition(statement: Any /* VariableDeclarationStatement | AssignmentStatement */): SourceNode + open fun printTableFieldExpression(expression: TableFieldExpression): SourceNode + open fun printTableExpression(expression: TableExpression): SourceNode + open fun printUnaryExpression(expression: UnaryExpression): SourceNode + open fun printBinaryExpression(expression: BinaryExpression): SourceNode + open var printExpressionInParenthesesIfNeeded: Any + open var needsParenthesis: Any + open fun printCallExpression(expression: CallExpression): SourceNode + open fun printMethodCallExpression(expression: MethodCallExpression): SourceNode + open fun printIdentifier(expression: Identifier): SourceNode + open fun printTableIndexExpression(expression: TableIndexExpression): SourceNode + open fun printOperator(kind: Any /* SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator | SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */): SourceNode + open fun joinChunksWithComma(chunks: Array): Array + open fun printExpressionList(expressions: Array): Array + open var buildSourceMap: Any + + companion object { + var operatorMap: Any + } +} \ No newline at end of file diff --git a/modules/mod2/externals/context.module_typescript-to-lua.kt b/modules/mod2/externals/context.module_typescript-to-lua.kt new file mode 100644 index 0000000..3c6d078 --- /dev/null +++ b/modules/mod2/externals/context.module_typescript-to-lua.kt @@ -0,0 +1,80 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.GetAccessorDeclaration +import ts.SetAccessorDeclaration +import ts.Node +import ts.ImportEqualsDeclaration +import ts.Expression +import ts.SourceFile +import ts.CancellationToken +import ts.TypeChecker +import ts.Program +import ts.Diagnostic +import ts.CompilerOptions +import Node as _Node +import Expression as _Expression +import ts.QualifiedName +import ts.ExternalModuleReference + +external interface AllAccessorDeclarations { + var firstAccessor: dynamic /* GetAccessorDeclaration | SetAccessorDeclaration */ + get() = definedExternally + set(value) = definedExternally + var secondAccessor: dynamic /* GetAccessorDeclaration? | SetAccessorDeclaration? */ + get() = definedExternally + set(value) = definedExternally + var getAccessor: GetAccessorDeclaration? + var setAccessor: SetAccessorDeclaration? +} + +external interface EmitResolver { + fun isValueAliasDeclaration(node: Node): Boolean + fun isReferencedAliasDeclaration(node: Node, checkChildren: Boolean = definedExternally): Boolean + fun isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): Boolean + fun moduleExportsSomeValue(moduleReferenceExpression: Expression): Boolean + fun getAllAccessorDeclarations(declaration: GetAccessorDeclaration): AllAccessorDeclarations + fun getAllAccessorDeclarations(declaration: SetAccessorDeclaration): AllAccessorDeclarations +} + +external interface DiagnosticsProducingTypeChecker : TypeChecker { + fun getEmitResolver(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): EmitResolver +} + +external open class TransformationContext(program: Program, sourceFile: SourceFile, visitorMap: VisitorMap) { + open var program: Program + open var sourceFile: SourceFile + open var visitorMap: Any + open var diagnostics: Array + open var checker: DiagnosticsProducingTypeChecker + open var resolver: EmitResolver + open var options: OmitIndexSignature /* OmitIndexSignature & `T$0` */ + open var luaTarget: LuaTarget + open var isModule: Boolean + open var isStrict: Boolean + open var currentNodeVisitors: Any + open fun transformNode(node: Node): Array<_Node> + open fun superTransformNode(node: Node): Array<_Node> + open fun transformExpression(node: Expression): _Expression + open fun transformExpression(node: QualifiedName): _Expression + open fun transformExpression(node: ExternalModuleReference): _Expression + open fun superTransformExpression(node: Expression): _Expression + open fun superTransformExpression(node: QualifiedName): _Expression + open fun superTransformExpression(node: ExternalModuleReference): _Expression + open fun transformStatements(node: StatementLikeNode): Array + open fun transformStatements(node: Array): Array + open fun superTransformStatements(node: StatementLikeNode): Array + open fun superTransformStatements(node: Array): Array +} \ No newline at end of file diff --git a/modules/mod2/externals/index.module_typescript-to-lua.kt b/modules/mod2/externals/index.module_typescript-to-lua.kt new file mode 100644 index 0000000..0de0447 --- /dev/null +++ b/modules/mod2/externals/index.module_typescript-to-lua.kt @@ -0,0 +1,39 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.CompilerOptions +import ts.WriteFileCallback +import ts.Diagnostic +import tsstdlib.Record + +external fun transpileFiles(rootNames: Array, options: OmitIndexSignature /* OmitIndexSignature & `T$0` */ = definedExternally, writeFile: WriteFileCallback = definedExternally): EmitResult + +external fun transpileProject(configFileName: String, optionsToExtend: OmitIndexSignature /* OmitIndexSignature & `T$0` */ = definedExternally, writeFile: WriteFileCallback = definedExternally): EmitResult + +external interface TranspileVirtualProjectResult { + var diagnostics: Array + var transpiledFiles: Array +} + +external fun transpileVirtualProject(files: Record, options: OmitIndexSignature /* OmitIndexSignature & `T$0` */ = definedExternally): TranspileVirtualProjectResult + +external interface TranspileStringResult { + var diagnostics: Array + var file: TranspiledFile? + get() = definedExternally + set(value) = definedExternally +} + +external fun transpileString(main: String, options: OmitIndexSignature /* OmitIndexSignature & `T$0` */ = definedExternally): TranspileStringResult \ No newline at end of file diff --git a/modules/mod2/externals/lib.es2015.collection.kt b/modules/mod2/externals/lib.es2015.collection.kt new file mode 100644 index 0000000..8d138d8 --- /dev/null +++ b/modules/mod2/externals/lib.es2015.collection.kt @@ -0,0 +1,49 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface Map { + fun entries(): IterableIterator */> + fun keys(): IterableIterator + fun values(): IterableIterator + fun clear() + fun delete(key: K): Boolean + fun forEach(callbackfn: (value: V, key: K, map: Map) -> Unit, thisArg: Any = definedExternally) + fun get(key: K): V? + fun has(key: K): Boolean + fun set(key: K, value: V): Map /* this */ + var size: Number +} + +external interface MapConstructor { + var prototype: Map +} + +external interface Set { + fun entries(): IterableIterator */> + fun keys(): IterableIterator + fun values(): IterableIterator + fun add(value: T): Set /* this */ + fun clear() + fun delete(value: T): Boolean + fun forEach(callbackfn: (value: T, value2: T, set: Set) -> Unit, thisArg: Any = definedExternally) + fun has(value: T): Boolean + var size: Number +} + +external interface SetConstructor { + var prototype: Set +} \ No newline at end of file diff --git a/modules/mod2/externals/lib.es2015.iterable.kt b/modules/mod2/externals/lib.es2015.iterable.kt new file mode 100644 index 0000000..57fb640 --- /dev/null +++ b/modules/mod2/externals/lib.es2015.iterable.kt @@ -0,0 +1,54 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface IteratorYieldResult { + var done: Boolean? + get() = definedExternally + set(value) = definedExternally + var value: TYield +} + +external interface IteratorReturnResult { + var done: Boolean + var value: TReturn +} + +external interface Iterator { + fun next(vararg args: Any /* JsTuple<> | JsTuple */): dynamic /* IteratorYieldResult | IteratorReturnResult */ + val `return`: ((value: TReturn) -> dynamic)? + val `throw`: ((e: Any) -> dynamic)? +} + +typealias Iterator__1 = Iterator + +external interface Iterable + +external interface IterableIterator : Iterator__1 + +external interface PromiseConstructor { + var prototype: Promise + fun all(values: Any /* JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple */): Promise | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple */> + fun all(values: Array */>): Promise> + fun race(values: Array): Promise + fun reject(reason: Any = definedExternally): Promise + fun resolve(value: T): Promise + fun resolve(value: PromiseLike): Promise + fun resolve(): Promise + fun all(values: Iterable */>): Promise> + fun race(values: Iterable): Promise + fun race(values: Iterable */>): Promise +} \ No newline at end of file diff --git a/modules/mod2/externals/lib.es5.Intl.module_dukat.kt b/modules/mod2/externals/lib.es5.Intl.module_dukat.kt new file mode 100644 index 0000000..62cbcc7 --- /dev/null +++ b/modules/mod2/externals/lib.es5.Intl.module_dukat.kt @@ -0,0 +1,220 @@ +@file:JsQualifier("tsstdlib.Intl") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib.Intl + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface CollatorOptions { + var usage: String? + get() = definedExternally + set(value) = definedExternally + var localeMatcher: String? + get() = definedExternally + set(value) = definedExternally + var numeric: Boolean? + get() = definedExternally + set(value) = definedExternally + var caseFirst: String? + get() = definedExternally + set(value) = definedExternally + var sensitivity: String? + get() = definedExternally + set(value) = definedExternally + var ignorePunctuation: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedCollatorOptions { + var locale: String + var usage: String + var sensitivity: String + var ignorePunctuation: Boolean + var collation: String + var caseFirst: String + var numeric: Boolean +} + +@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface Collator { + fun compare(x: String, y: String): Number + fun resolvedOptions(): ResolvedCollatorOptions + + companion object { + @nativeInvoke + operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: CollatorOptions = definedExternally): Collator + fun supportedLocalesOf(locales: Any /* String | Array */, options: CollatorOptions = definedExternally): Array + } +} + +external interface NumberFormatOptions { + var localeMatcher: String? + get() = definedExternally + set(value) = definedExternally + var style: String? + get() = definedExternally + set(value) = definedExternally + var currency: String? + get() = definedExternally + set(value) = definedExternally + var currencyDisplay: String? + get() = definedExternally + set(value) = definedExternally + var useGrouping: Boolean? + get() = definedExternally + set(value) = definedExternally + var minimumIntegerDigits: Number? + get() = definedExternally + set(value) = definedExternally + var minimumFractionDigits: Number? + get() = definedExternally + set(value) = definedExternally + var maximumFractionDigits: Number? + get() = definedExternally + set(value) = definedExternally + var minimumSignificantDigits: Number? + get() = definedExternally + set(value) = definedExternally + var maximumSignificantDigits: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedNumberFormatOptions { + var locale: String + var numberingSystem: String + var style: String + var currency: String? + get() = definedExternally + set(value) = definedExternally + var currencyDisplay: String? + get() = definedExternally + set(value) = definedExternally + var minimumIntegerDigits: Number + var minimumFractionDigits: Number + var maximumFractionDigits: Number + var minimumSignificantDigits: Number? + get() = definedExternally + set(value) = definedExternally + var maximumSignificantDigits: Number? + get() = definedExternally + set(value) = definedExternally + var useGrouping: Boolean +} + +@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface NumberFormat { + fun format(value: Number): String + fun resolvedOptions(): ResolvedNumberFormatOptions + + companion object { + @nativeInvoke + operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: NumberFormatOptions = definedExternally): NumberFormat + fun supportedLocalesOf(locales: Any /* String | Array */, options: NumberFormatOptions = definedExternally): Array + } +} + +external interface DateTimeFormatOptions { + var localeMatcher: String? + get() = definedExternally + set(value) = definedExternally + var weekday: String? + get() = definedExternally + set(value) = definedExternally + var era: String? + get() = definedExternally + set(value) = definedExternally + var year: String? + get() = definedExternally + set(value) = definedExternally + var month: String? + get() = definedExternally + set(value) = definedExternally + var day: String? + get() = definedExternally + set(value) = definedExternally + var hour: String? + get() = definedExternally + set(value) = definedExternally + var minute: String? + get() = definedExternally + set(value) = definedExternally + var second: String? + get() = definedExternally + set(value) = definedExternally + var timeZoneName: String? + get() = definedExternally + set(value) = definedExternally + var formatMatcher: String? + get() = definedExternally + set(value) = definedExternally + var hour12: Boolean? + get() = definedExternally + set(value) = definedExternally + var timeZone: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedDateTimeFormatOptions { + var locale: String + var calendar: String + var numberingSystem: String + var timeZone: String + var hour12: Boolean? + get() = definedExternally + set(value) = definedExternally + var weekday: String? + get() = definedExternally + set(value) = definedExternally + var era: String? + get() = definedExternally + set(value) = definedExternally + var year: String? + get() = definedExternally + set(value) = definedExternally + var month: String? + get() = definedExternally + set(value) = definedExternally + var day: String? + get() = definedExternally + set(value) = definedExternally + var hour: String? + get() = definedExternally + set(value) = definedExternally + var minute: String? + get() = definedExternally + set(value) = definedExternally + var second: String? + get() = definedExternally + set(value) = definedExternally + var timeZoneName: String? + get() = definedExternally + set(value) = definedExternally +} + +@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") +external interface DateTimeFormat { + fun format(date: Date = definedExternally): String + fun format(): String + fun format(date: Number = definedExternally): String + fun resolvedOptions(): ResolvedDateTimeFormatOptions + + companion object { + @nativeInvoke + operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: DateTimeFormatOptions = definedExternally): DateTimeFormat + fun supportedLocalesOf(locales: Any /* String | Array */, options: DateTimeFormatOptions = definedExternally): Array + } +} \ No newline at end of file diff --git a/modules/mod2/externals/lib.es5.kt b/modules/mod2/externals/lib.es5.kt new file mode 100644 index 0000000..a143da0 --- /dev/null +++ b/modules/mod2/externals/lib.es5.kt @@ -0,0 +1,69 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface DateConstructor { + @nativeInvoke + operator fun invoke(): String + var prototype: Date + fun parse(s: String): Number + fun UTC(year: Number, month: Number, date: Number = definedExternally, hours: Number = definedExternally, minutes: Number = definedExternally, seconds: Number = definedExternally, ms: Number = definedExternally): Number + fun now(): Number +} + +external interface ConcatArray { + var length: Number + @nativeGetter + operator fun get(n: Number): T? + @nativeSetter + operator fun set(n: Number, value: T) + fun join(separator: String = definedExternally): String + fun slice(start: Number = definedExternally, end: Number = definedExternally): Array +} + +external interface ArrayConstructor { + fun from(iterable: Iterable): Array + fun from(iterable: ArrayLike): Array + fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array + fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U): Array + fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array + fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U): Array + fun of(vararg items: T): Array + @nativeInvoke + operator fun invoke(arrayLength: Number = definedExternally): Array + @nativeInvoke + operator fun invoke(): Array + @nativeInvoke + operator fun invoke(arrayLength: Number): Array + @nativeInvoke + operator fun invoke(vararg items: T): Array + fun isArray(arg: Any): Boolean + var prototype: Array +} + +external interface PromiseLike { + fun then(onfulfilled: ((value: T) -> Any?)? = definedExternally, onrejected: ((reason: Any) -> Any?)? = definedExternally): PromiseLike +} + +external interface ArrayLike { + var length: Number + @nativeGetter + operator fun get(n: Number): T? + @nativeSetter + operator fun set(n: Number, value: T) +} + +typealias Record = Any \ No newline at end of file diff --git a/modules/mod2/externals/lib.scripthost.kt b/modules/mod2/externals/lib.scripthost.kt new file mode 100644 index 0000000..809347e --- /dev/null +++ b/modules/mod2/externals/lib.scripthost.kt @@ -0,0 +1,20 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package tsstdlib + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external open class VarDate { + open var VarDate_typekey: VarDate +} \ No newline at end of file diff --git a/modules/mod2/externals/nonDeclarations.ts.kt b/modules/mod2/externals/nonDeclarations.ts.kt new file mode 100644 index 0000000..3650dca --- /dev/null +++ b/modules/mod2/externals/nonDeclarations.ts.kt @@ -0,0 +1,114 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package ts + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +typealias SortedReadonlyArray = Array + +typealias SortedArray = Array + +typealias NodeArray = Array + +typealias DotToken = PunctuationToken + +typealias DotDotDotToken = PunctuationToken + +typealias QuestionToken = PunctuationToken + +typealias ExclamationToken = PunctuationToken + +typealias ColonToken = PunctuationToken + +typealias EqualsToken = PunctuationToken + +typealias AsteriskToken = PunctuationToken + +typealias EqualsGreaterThanToken = PunctuationToken + +typealias PlusToken = PunctuationToken + +typealias MinusToken = PunctuationToken + +typealias QuestionDotToken = PunctuationToken + +typealias AssertsKeyword = KeywordToken + +typealias AwaitKeyword = KeywordToken + +typealias AwaitKeywordToken = AwaitKeyword + +typealias AssertsToken = AssertsKeyword + +typealias AbstractKeyword = ModifierToken + +typealias AsyncKeyword = ModifierToken + +typealias ConstKeyword = ModifierToken + +typealias DeclareKeyword = ModifierToken + +typealias DefaultKeyword = ModifierToken + +typealias ExportKeyword = ModifierToken + +typealias PrivateKeyword = ModifierToken + +typealias ProtectedKeyword = ModifierToken + +typealias PublicKeyword = ModifierToken + +typealias ReadonlyKeyword = ModifierToken + +typealias OverrideKeyword = ModifierToken + +typealias StaticKeyword = ModifierToken + +typealias ReadonlyToken = ReadonlyKeyword + +typealias ModifiersArray = NodeArray + +typealias IncrementExpression = UpdateExpression + +typealias ExponentiationOperator = SyntaxKind.AsteriskAsteriskToken + +typealias BinaryOperatorToken = Token + +typealias AssignmentOperatorToken = Token + +typealias FunctionBody = Block + +typealias WriteFileCallback = (fileName: String, data: String, writeByteOrderMark: Boolean, onError: (message: String) -> Unit, sourceFiles: Array) -> Unit + +typealias CustomTransformerFactory = (context: TransformationContext) -> CustomTransformer + +typealias SymbolTable = UnderscoreEscapedMap + +typealias JsFileExtensionInfo = FileExtensionInfo + +typealias EmitHelperUniqueNameCallback = (name: String) -> String + +typealias TransformerFactory = (context: TransformationContext) -> Transformer + +typealias Transformer = (node: T) -> T + +typealias Visitor = (node: Node) -> dynamic + +typealias FileWatcherCallback = (fileName: String, eventKind: FileWatcherEventKind) -> Unit + +typealias DirectoryWatcherCallback = (fileName: String) -> Unit + +typealias DiagnosticReporter = (diagnostic: Diagnostic) -> Unit + +typealias CodeActionCommand = InstallPackageAction \ No newline at end of file diff --git a/modules/mod2/externals/output-collector.module_typescript-to-lua.kt b/modules/mod2/externals/output-collector.module_typescript-to-lua.kt new file mode 100644 index 0000000..0c57eac --- /dev/null +++ b/modules/mod2/externals/output-collector.module_typescript-to-lua.kt @@ -0,0 +1,33 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.SourceFile + +external interface TranspiledFile { + var outPath: String + var sourceFiles: Array + var lua: String? + get() = definedExternally + set(value) = definedExternally + var luaSourceMap: String? + get() = definedExternally + set(value) = definedExternally + var declaration: String? + get() = definedExternally + set(value) = definedExternally + var declarationMap: String? + get() = definedExternally + set(value) = definedExternally +} \ No newline at end of file diff --git a/modules/mod2/externals/parse.module_typescript-to-lua.kt b/modules/mod2/externals/parse.module_typescript-to-lua.kt new file mode 100644 index 0000000..052faf7 --- /dev/null +++ b/modules/mod2/externals/parse.module_typescript-to-lua.kt @@ -0,0 +1,21 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface ParsedCommandLine : ts.ParsedCommandLine + +external fun updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine + +external fun parseCommandLine(args: Array): ParsedCommandLine \ No newline at end of file diff --git a/modules/mod2/externals/plugins.module_typescript-to-lua.kt b/modules/mod2/externals/plugins.module_typescript-to-lua.kt new file mode 100644 index 0000000..24d3ea4 --- /dev/null +++ b/modules/mod2/externals/plugins.module_typescript-to-lua.kt @@ -0,0 +1,24 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external interface Plugin { + var visitors: Visitors? + get() = definedExternally + set(value) = definedExternally + var printer: Printer? + get() = definedExternally + set(value) = definedExternally +} \ No newline at end of file diff --git a/modules/mod2/externals/report.module_typescript-to-lua.kt b/modules/mod2/externals/report.module_typescript-to-lua.kt new file mode 100644 index 0000000..f1582a6 --- /dev/null +++ b/modules/mod2/externals/report.module_typescript-to-lua.kt @@ -0,0 +1,48 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.DiagnosticRelatedInformation +import ts.DiagnosticCategory +import ts.SourceFile +import ts.Diagnostic +import ts.System +import ts.DiagnosticReporter + +external interface `T$13` { + var code: Any + var reportsUnnecessary: Any? + get() = definedExternally + set(value) = definedExternally + var reportsDeprecated: Any? + get() = definedExternally + set(value) = definedExternally + var source: String? + get() = definedExternally + set(value) = definedExternally + var relatedInformation: Array? + get() = definedExternally + set(value) = definedExternally + var category: DiagnosticCategory + var file: SourceFile? + var start: Number? + var length: Number? + var messageText: dynamic /* String | ts.DiagnosticMessageChain */ + get() = definedExternally + set(value) = definedExternally +} + +external var prepareDiagnosticForFormatting: (diagnostic: Diagnostic) -> `T$13` + +external fun createDiagnosticReporter(pretty: Boolean, system: System = definedExternally): DiagnosticReporter \ No newline at end of file diff --git a/modules/mod2/externals/source-map.module_source-map.kt b/modules/mod2/externals/source-map.module_source-map.kt new file mode 100644 index 0000000..6880a36 --- /dev/null +++ b/modules/mod2/externals/source-map.module_source-map.kt @@ -0,0 +1,192 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +typealias SourceMapUrl = String + +external interface StartOfSourceMap { + var file: String? + get() = definedExternally + set(value) = definedExternally + var sourceRoot: String? + get() = definedExternally + set(value) = definedExternally + var skipValidation: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface RawSourceMap { + var version: Number + var sources: Array + var names: Array + var sourceRoot: String? + get() = definedExternally + set(value) = definedExternally + var sourcesContent: Array? + get() = definedExternally + set(value) = definedExternally + var mappings: String + var file: String +} + +external interface RawIndexMap : StartOfSourceMap { + var version: Number + var sections: Array +} + +external interface RawSection { + var offset: Position + var map: RawSourceMap +} + +external interface Position { + var line: Number + var column: Number +} + +external interface NullablePosition { + var line: Number? + var column: Number? + var lastColumn: Number? +} + +external interface MappedPosition { + var source: String + var line: Number + var column: Number + var name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface NullableMappedPosition { + var source: String? + var line: Number? + var column: Number? + var name: String? +} + +external interface MappingItem { + var source: String + var generatedLine: Number + var generatedColumn: Number + var originalLine: Number + var originalColumn: Number + var name: String +} + +external interface Mapping { + var generated: Position + var original: Position + var source: String + var name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface CodeWithSourceMap { + var code: String + var map: SourceMapGenerator +} + +external interface SourceMapConsumer { + fun computeColumnSpans() + fun originalPositionFor(generatedPosition: Position /* Position & `T$19` */): NullableMappedPosition + fun generatedPositionFor(originalPosition: MappedPosition /* MappedPosition & `T$19` */): NullablePosition + fun allGeneratedPositionsFor(originalPosition: MappedPosition): Array + fun hasContentsOfAllSources(): Boolean + fun sourceContentFor(source: String, returnNullOnMissing: Boolean = definedExternally): String? + fun eachMapping(callback: (mapping: MappingItem) -> Unit, context: Any = definedExternally, order: Number = definedExternally) + fun destroy() +} + +external interface SourceMapConsumerConstructor { + var prototype: SourceMapConsumer + var GENERATED_ORDER: Number + var ORIGINAL_ORDER: Number + var GREATEST_LOWER_BOUND: Number + var LEAST_UPPER_BOUND: Number + fun fromSourceMap(sourceMap: SourceMapGenerator, sourceMapUrl: SourceMapUrl = definedExternally): Promise + fun with(rawSourceMap: RawSourceMap, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise + fun with(rawSourceMap: RawIndexMap, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise + fun with(rawSourceMap: String, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise +} + +external interface BasicSourceMapConsumer : SourceMapConsumer { + var file: String + var sourceRoot: String + var sources: Array + var sourcesContent: Array +} + +external interface BasicSourceMapConsumerConstructor { + var prototype: BasicSourceMapConsumer + fun fromSourceMap(sourceMap: SourceMapGenerator): Promise +} + +external interface IndexedSourceMapConsumer : SourceMapConsumer { + var sources: Array +} + +external interface IndexedSourceMapConsumerConstructor { + var prototype: IndexedSourceMapConsumer +} + +external open class SourceMapGenerator(startOfSourceMap: StartOfSourceMap = definedExternally) { + open fun addMapping(mapping: Mapping) + open fun setSourceContent(sourceFile: String, sourceContent: String) + open fun applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile: String = definedExternally, sourceMapPath: String = definedExternally) + override fun toString(): String + open fun toJSON(): RawSourceMap + + companion object { + fun fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator + } +} + +external open class SourceNode { + open var children: Array + open var sourceContents: Any + open var line: Number + open var column: Number + open var source: String + open var name: String + constructor() + constructor(line: Number?, column: Number?, source: String?, chunks: Array = definedExternally, name: String = definedExternally) + constructor(line: Number?, column: Number?, source: String?) + constructor(line: Number?, column: Number?, source: String?, chunks: Array = definedExternally) + constructor(line: Number?, column: Number?, source: String?, chunks: SourceNode = definedExternally, name: String = definedExternally) + constructor(line: Number?, column: Number?, source: String?, chunks: SourceNode = definedExternally) + constructor(line: Number?, column: Number?, source: String?, chunks: String = definedExternally, name: String = definedExternally) + constructor(line: Number?, column: Number?, source: String?, chunks: String = definedExternally) + open fun add(chunk: Array): SourceNode + open fun add(chunk: SourceNode): SourceNode + open fun add(chunk: String): SourceNode + open fun prepend(chunk: Array): SourceNode + open fun prepend(chunk: SourceNode): SourceNode + open fun prepend(chunk: String): SourceNode + open fun setSourceContent(sourceFile: String, sourceContent: String) + open fun walk(fn: (chunk: String, mapping: MappedPosition) -> Unit) + open fun walkSourceContents(fn: (file: String, content: String) -> Unit) + open fun join(sep: String): SourceNode + open fun replaceRight(pattern: String, replacement: String): SourceNode + override fun toString(): String + open fun toStringWithSourceMap(startOfSourceMap: StartOfSourceMap = definedExternally): CodeWithSourceMap + + companion object { + fun fromStringWithSourceMap(code: String, sourceMapConsumer: SourceMapConsumer, relativePath: String = definedExternally): SourceNode + } +} \ No newline at end of file diff --git a/modules/mod2/externals/transpile.module_typescript-to-lua.kt b/modules/mod2/externals/transpile.module_typescript-to-lua.kt new file mode 100644 index 0000000..8681706 --- /dev/null +++ b/modules/mod2/externals/transpile.module_typescript-to-lua.kt @@ -0,0 +1,40 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.Program +import ts.SourceFile +import ts.CustomTransformers +import ts.Diagnostic +import ts.WriteFileCallback + +external interface TranspileOptions { + var program: Program + var sourceFiles: Array? + get() = definedExternally + set(value) = definedExternally + var customTransformers: CustomTransformers? + get() = definedExternally + set(value) = definedExternally + var plugins: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface TranspileResult { + var diagnostics: Array + var transpiledFiles: Array +} + +external fun getProgramTranspileResult(emitHost: EmitHost, writeFileResult: WriteFileCallback, __2: TranspileOptions): TranspileResult \ No newline at end of file diff --git a/modules/mod2/externals/transpiler.module_typescript-to-lua.kt b/modules/mod2/externals/transpiler.module_typescript-to-lua.kt new file mode 100644 index 0000000..16b18b0 --- /dev/null +++ b/modules/mod2/externals/transpiler.module_typescript-to-lua.kt @@ -0,0 +1,55 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.WriteFileCallback +import ts.Diagnostic +import ts.Program + +external interface TranspilerOptions { + var emitHost: EmitHost? + get() = definedExternally + set(value) = definedExternally +} + +external interface EmitOptions : TranspileOptions { + var writeFile: WriteFileCallback? + get() = definedExternally + set(value) = definedExternally +} + +external interface EmitResult { + var emitSkipped: Boolean + var diagnostics: Array +} + +external interface `T$20` { + var emitPlan: Array +} + +external open class Transpiler(__0: TranspilerOptions = definedExternally) { + open var emitHost: EmitHost + open fun emit(emitOptions: EmitOptions): EmitResult + open fun getEmitPlan(program: Program, diagnostics: Array, files: Array): `T$20` +} + +external fun getEmitPath(file: String, program: Program): String + +external fun getEmitPathRelativeToOutDir(fileName: String, program: Program): String + +external fun getSourceDir(program: Program): String + +external fun getEmitOutDir(program: Program): String + +external fun getProjectRoot(program: Program): String \ No newline at end of file diff --git a/modules/mod2/externals/tsconfig.module_typescript-to-lua.kt b/modules/mod2/externals/tsconfig.module_typescript-to-lua.kt new file mode 100644 index 0000000..8eadae2 --- /dev/null +++ b/modules/mod2/externals/tsconfig.module_typescript-to-lua.kt @@ -0,0 +1,19 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.CompilerOptions +import ts.System + +external fun parseConfigFileWithSystem(configFileName: String, commandLineOptions: OmitIndexSignature /* OmitIndexSignature & `T$0` */ = definedExternally, system: System = definedExternally): ParsedCommandLine \ No newline at end of file diff --git a/modules/mod2/externals/typescript.module_typescript.kt b/modules/mod2/externals/typescript.module_typescript.kt new file mode 100644 index 0000000..83261af --- /dev/null +++ b/modules/mod2/externals/typescript.module_typescript.kt @@ -0,0 +1,19 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external fun setTimeout(handler: (args: Any) -> Unit, timeout: Number): Any + +external fun clearTimeout(handle: Any) \ No newline at end of file diff --git a/modules/mod2/externals/typescript.ts.ScriptSnapshot.module_typescript.kt b/modules/mod2/externals/typescript.ts.ScriptSnapshot.module_typescript.kt new file mode 100644 index 0000000..acab3da --- /dev/null +++ b/modules/mod2/externals/typescript.ts.ScriptSnapshot.module_typescript.kt @@ -0,0 +1,20 @@ +@file:JsQualifier("ts.ScriptSnapshot") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package ts.ScriptSnapshot + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.IScriptSnapshot + +external fun fromString(text: String): IScriptSnapshot \ No newline at end of file diff --git a/modules/mod2/externals/typescript.ts.module_typescript.kt b/modules/mod2/externals/typescript.ts.module_typescript.kt new file mode 100644 index 0000000..73cc27f --- /dev/null +++ b/modules/mod2/externals/typescript.ts.module_typescript.kt @@ -0,0 +1,8487 @@ +@file:JsModule("typescript") +@file:JsNonModule +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package ts + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* + +external var versionMajorMinor: Any + +external var version: String + +external interface MapLike { + @nativeGetter + operator fun get(index: String): T? + @nativeSetter + operator fun set(index: String, value: T) +} + +external interface ReadonlyCollection { + var size: Number + fun has(key: K): Boolean + fun keys(): Iterator +} + +external interface Collection : ReadonlyCollection { + fun delete(key: K): Boolean + fun clear() +} + +external interface ReadonlyESMap : ReadonlyCollection { + fun get(key: K): V? + fun values(): Iterator + fun entries(): Iterator */> + fun forEach(action: (value: V, key: K) -> Unit) +} + +external interface ReadonlyMap : ReadonlyESMap + +external interface ESMap : ReadonlyESMap, Collection { + fun set(key: K, value: V): ESMap /* this */ +} + +external interface Map : ESMap + +external interface ReadonlySet : ReadonlyCollection { + override fun has(value: T): Boolean + fun values(): Iterator + fun entries(): Iterator */> + fun forEach(action: (value: T, key: T) -> Unit) +} + +external interface Set : ReadonlySet, Collection { + fun add(value: T): Set /* this */ + override fun delete(value: T): Boolean +} + +external interface Iterator { + fun next(): dynamic /* `T$1` | `T$2` */ +} + +external interface Push { + fun push(vararg values: T) +} + +external interface TextRange { + var pos: Number + var end: Number +} + +external interface ReadonlyTextRange { + var pos: Number + var end: Number +} + +external enum class SyntaxKind { + Unknown /* = 0 */, + EndOfFileToken /* = 1 */, + SingleLineCommentTrivia /* = 2 */, + MultiLineCommentTrivia /* = 3 */, + NewLineTrivia /* = 4 */, + WhitespaceTrivia /* = 5 */, + ShebangTrivia /* = 6 */, + ConflictMarkerTrivia /* = 7 */, + NumericLiteral /* = 8 */, + BigIntLiteral /* = 9 */, + StringLiteral /* = 10 */, + JsxText /* = 11 */, + JsxTextAllWhiteSpaces /* = 12 */, + RegularExpressionLiteral /* = 13 */, + NoSubstitutionTemplateLiteral /* = 14 */, + TemplateHead /* = 15 */, + TemplateMiddle /* = 16 */, + TemplateTail /* = 17 */, + OpenBraceToken /* = 18 */, + CloseBraceToken /* = 19 */, + OpenParenToken /* = 20 */, + CloseParenToken /* = 21 */, + OpenBracketToken /* = 22 */, + CloseBracketToken /* = 23 */, + DotToken /* = 24 */, + DotDotDotToken /* = 25 */, + SemicolonToken /* = 26 */, + CommaToken /* = 27 */, + QuestionDotToken /* = 28 */, + LessThanToken /* = 29 */, + LessThanSlashToken /* = 30 */, + GreaterThanToken /* = 31 */, + LessThanEqualsToken /* = 32 */, + GreaterThanEqualsToken /* = 33 */, + EqualsEqualsToken /* = 34 */, + ExclamationEqualsToken /* = 35 */, + EqualsEqualsEqualsToken /* = 36 */, + ExclamationEqualsEqualsToken /* = 37 */, + EqualsGreaterThanToken /* = 38 */, + PlusToken /* = 39 */, + MinusToken /* = 40 */, + AsteriskToken /* = 41 */, + AsteriskAsteriskToken /* = 42 */, + SlashToken /* = 43 */, + PercentToken /* = 44 */, + PlusPlusToken /* = 45 */, + MinusMinusToken /* = 46 */, + LessThanLessThanToken /* = 47 */, + GreaterThanGreaterThanToken /* = 48 */, + GreaterThanGreaterThanGreaterThanToken /* = 49 */, + AmpersandToken /* = 50 */, + BarToken /* = 51 */, + CaretToken /* = 52 */, + ExclamationToken /* = 53 */, + TildeToken /* = 54 */, + AmpersandAmpersandToken /* = 55 */, + BarBarToken /* = 56 */, + QuestionToken /* = 57 */, + ColonToken /* = 58 */, + AtToken /* = 59 */, + QuestionQuestionToken /* = 60 */, + BacktickToken /* = 61 */, + HashToken /* = 62 */, + EqualsToken /* = 63 */, + PlusEqualsToken /* = 64 */, + MinusEqualsToken /* = 65 */, + AsteriskEqualsToken /* = 66 */, + AsteriskAsteriskEqualsToken /* = 67 */, + SlashEqualsToken /* = 68 */, + PercentEqualsToken /* = 69 */, + LessThanLessThanEqualsToken /* = 70 */, + GreaterThanGreaterThanEqualsToken /* = 71 */, + GreaterThanGreaterThanGreaterThanEqualsToken /* = 72 */, + AmpersandEqualsToken /* = 73 */, + BarEqualsToken /* = 74 */, + BarBarEqualsToken /* = 75 */, + AmpersandAmpersandEqualsToken /* = 76 */, + QuestionQuestionEqualsToken /* = 77 */, + CaretEqualsToken /* = 78 */, + Identifier /* = 79 */, + PrivateIdentifier /* = 80 */, + BreakKeyword /* = 81 */, + CaseKeyword /* = 82 */, + CatchKeyword /* = 83 */, + ClassKeyword /* = 84 */, + ConstKeyword /* = 85 */, + ContinueKeyword /* = 86 */, + DebuggerKeyword /* = 87 */, + DefaultKeyword /* = 88 */, + DeleteKeyword /* = 89 */, + DoKeyword /* = 90 */, + ElseKeyword /* = 91 */, + EnumKeyword /* = 92 */, + ExportKeyword /* = 93 */, + ExtendsKeyword /* = 94 */, + FalseKeyword /* = 95 */, + FinallyKeyword /* = 96 */, + ForKeyword /* = 97 */, + FunctionKeyword /* = 98 */, + IfKeyword /* = 99 */, + ImportKeyword /* = 100 */, + InKeyword /* = 101 */, + InstanceOfKeyword /* = 102 */, + NewKeyword /* = 103 */, + NullKeyword /* = 104 */, + ReturnKeyword /* = 105 */, + SuperKeyword /* = 106 */, + SwitchKeyword /* = 107 */, + ThisKeyword /* = 108 */, + ThrowKeyword /* = 109 */, + TrueKeyword /* = 110 */, + TryKeyword /* = 111 */, + TypeOfKeyword /* = 112 */, + VarKeyword /* = 113 */, + VoidKeyword /* = 114 */, + WhileKeyword /* = 115 */, + WithKeyword /* = 116 */, + ImplementsKeyword /* = 117 */, + InterfaceKeyword /* = 118 */, + LetKeyword /* = 119 */, + PackageKeyword /* = 120 */, + PrivateKeyword /* = 121 */, + ProtectedKeyword /* = 122 */, + PublicKeyword /* = 123 */, + StaticKeyword /* = 124 */, + YieldKeyword /* = 125 */, + AbstractKeyword /* = 126 */, + AsKeyword /* = 127 */, + AssertsKeyword /* = 128 */, + AnyKeyword /* = 129 */, + AsyncKeyword /* = 130 */, + AwaitKeyword /* = 131 */, + BooleanKeyword /* = 132 */, + ConstructorKeyword /* = 133 */, + DeclareKeyword /* = 134 */, + GetKeyword /* = 135 */, + InferKeyword /* = 136 */, + IntrinsicKeyword /* = 137 */, + IsKeyword /* = 138 */, + KeyOfKeyword /* = 139 */, + ModuleKeyword /* = 140 */, + NamespaceKeyword /* = 141 */, + NeverKeyword /* = 142 */, + ReadonlyKeyword /* = 143 */, + RequireKeyword /* = 144 */, + NumberKeyword /* = 145 */, + ObjectKeyword /* = 146 */, + SetKeyword /* = 147 */, + StringKeyword /* = 148 */, + SymbolKeyword /* = 149 */, + TypeKeyword /* = 150 */, + UndefinedKeyword /* = 151 */, + UniqueKeyword /* = 152 */, + UnknownKeyword /* = 153 */, + FromKeyword /* = 154 */, + GlobalKeyword /* = 155 */, + BigIntKeyword /* = 156 */, + OverrideKeyword /* = 157 */, + OfKeyword /* = 158 */, + QualifiedName /* = 159 */, + ComputedPropertyName /* = 160 */, + TypeParameter /* = 161 */, + Parameter /* = 162 */, + Decorator /* = 163 */, + PropertySignature /* = 164 */, + PropertyDeclaration /* = 165 */, + MethodSignature /* = 166 */, + MethodDeclaration /* = 167 */, + ClassStaticBlockDeclaration /* = 168 */, + Constructor /* = 169 */, + GetAccessor /* = 170 */, + SetAccessor /* = 171 */, + CallSignature /* = 172 */, + ConstructSignature /* = 173 */, + IndexSignature /* = 174 */, + TypePredicate /* = 175 */, + TypeReference /* = 176 */, + FunctionType /* = 177 */, + ConstructorType /* = 178 */, + TypeQuery /* = 179 */, + TypeLiteral /* = 180 */, + ArrayType /* = 181 */, + TupleType /* = 182 */, + OptionalType /* = 183 */, + RestType /* = 184 */, + UnionType /* = 185 */, + IntersectionType /* = 186 */, + ConditionalType /* = 187 */, + InferType /* = 188 */, + ParenthesizedType /* = 189 */, + ThisType /* = 190 */, + TypeOperator /* = 191 */, + IndexedAccessType /* = 192 */, + MappedType /* = 193 */, + LiteralType /* = 194 */, + NamedTupleMember /* = 195 */, + TemplateLiteralType /* = 196 */, + TemplateLiteralTypeSpan /* = 197 */, + ImportType /* = 198 */, + ObjectBindingPattern /* = 199 */, + ArrayBindingPattern /* = 200 */, + BindingElement /* = 201 */, + ArrayLiteralExpression /* = 202 */, + ObjectLiteralExpression /* = 203 */, + PropertyAccessExpression /* = 204 */, + ElementAccessExpression /* = 205 */, + CallExpression /* = 206 */, + NewExpression /* = 207 */, + TaggedTemplateExpression /* = 208 */, + TypeAssertionExpression /* = 209 */, + ParenthesizedExpression /* = 210 */, + FunctionExpression /* = 211 */, + ArrowFunction /* = 212 */, + DeleteExpression /* = 213 */, + TypeOfExpression /* = 214 */, + VoidExpression /* = 215 */, + AwaitExpression /* = 216 */, + PrefixUnaryExpression /* = 217 */, + PostfixUnaryExpression /* = 218 */, + BinaryExpression /* = 219 */, + ConditionalExpression /* = 220 */, + TemplateExpression /* = 221 */, + YieldExpression /* = 222 */, + SpreadElement /* = 223 */, + ClassExpression /* = 224 */, + OmittedExpression /* = 225 */, + ExpressionWithTypeArguments /* = 226 */, + AsExpression /* = 227 */, + NonNullExpression /* = 228 */, + MetaProperty /* = 229 */, + SyntheticExpression /* = 230 */, + TemplateSpan /* = 231 */, + SemicolonClassElement /* = 232 */, + Block /* = 233 */, + EmptyStatement /* = 234 */, + VariableStatement /* = 235 */, + ExpressionStatement /* = 236 */, + IfStatement /* = 237 */, + DoStatement /* = 238 */, + WhileStatement /* = 239 */, + ForStatement /* = 240 */, + ForInStatement /* = 241 */, + ForOfStatement /* = 242 */, + ContinueStatement /* = 243 */, + BreakStatement /* = 244 */, + ReturnStatement /* = 245 */, + WithStatement /* = 246 */, + SwitchStatement /* = 247 */, + LabeledStatement /* = 248 */, + ThrowStatement /* = 249 */, + TryStatement /* = 250 */, + DebuggerStatement /* = 251 */, + VariableDeclaration /* = 252 */, + VariableDeclarationList /* = 253 */, + FunctionDeclaration /* = 254 */, + ClassDeclaration /* = 255 */, + InterfaceDeclaration /* = 256 */, + TypeAliasDeclaration /* = 257 */, + EnumDeclaration /* = 258 */, + ModuleDeclaration /* = 259 */, + ModuleBlock /* = 260 */, + CaseBlock /* = 261 */, + NamespaceExportDeclaration /* = 262 */, + ImportEqualsDeclaration /* = 263 */, + ImportDeclaration /* = 264 */, + ImportClause /* = 265 */, + NamespaceImport /* = 266 */, + NamedImports /* = 267 */, + ImportSpecifier /* = 268 */, + ExportAssignment /* = 269 */, + ExportDeclaration /* = 270 */, + NamedExports /* = 271 */, + NamespaceExport /* = 272 */, + ExportSpecifier /* = 273 */, + MissingDeclaration /* = 274 */, + ExternalModuleReference /* = 275 */, + JsxElement /* = 276 */, + JsxSelfClosingElement /* = 277 */, + JsxOpeningElement /* = 278 */, + JsxClosingElement /* = 279 */, + JsxFragment /* = 280 */, + JsxOpeningFragment /* = 281 */, + JsxClosingFragment /* = 282 */, + JsxAttribute /* = 283 */, + JsxAttributes /* = 284 */, + JsxSpreadAttribute /* = 285 */, + JsxExpression /* = 286 */, + CaseClause /* = 287 */, + DefaultClause /* = 288 */, + HeritageClause /* = 289 */, + CatchClause /* = 290 */, + PropertyAssignment /* = 291 */, + ShorthandPropertyAssignment /* = 292 */, + SpreadAssignment /* = 293 */, + EnumMember /* = 294 */, + UnparsedPrologue /* = 295 */, + UnparsedPrepend /* = 296 */, + UnparsedText /* = 297 */, + UnparsedInternalText /* = 298 */, + UnparsedSyntheticReference /* = 299 */, + SourceFile /* = 300 */, + Bundle /* = 301 */, + UnparsedSource /* = 302 */, + InputFiles /* = 303 */, + JSDocTypeExpression /* = 304 */, + JSDocNameReference /* = 305 */, + JSDocMemberName /* = 306 */, + JSDocAllType /* = 307 */, + JSDocUnknownType /* = 308 */, + JSDocNullableType /* = 309 */, + JSDocNonNullableType /* = 310 */, + JSDocOptionalType /* = 311 */, + JSDocFunctionType /* = 312 */, + JSDocVariadicType /* = 313 */, + JSDocNamepathType /* = 314 */, + JSDocComment /* = 315 */, + JSDocText /* = 316 */, + JSDocTypeLiteral /* = 317 */, + JSDocSignature /* = 318 */, + JSDocLink /* = 319 */, + JSDocLinkCode /* = 320 */, + JSDocLinkPlain /* = 321 */, + JSDocTag /* = 322 */, + JSDocAugmentsTag /* = 323 */, + JSDocImplementsTag /* = 324 */, + JSDocAuthorTag /* = 325 */, + JSDocDeprecatedTag /* = 326 */, + JSDocClassTag /* = 327 */, + JSDocPublicTag /* = 328 */, + JSDocPrivateTag /* = 329 */, + JSDocProtectedTag /* = 330 */, + JSDocReadonlyTag /* = 331 */, + JSDocOverrideTag /* = 332 */, + JSDocCallbackTag /* = 333 */, + JSDocEnumTag /* = 334 */, + JSDocParameterTag /* = 335 */, + JSDocReturnTag /* = 336 */, + JSDocThisTag /* = 337 */, + JSDocTypeTag /* = 338 */, + JSDocTemplateTag /* = 339 */, + JSDocTypedefTag /* = 340 */, + JSDocSeeTag /* = 341 */, + JSDocPropertyTag /* = 342 */, + SyntaxList /* = 343 */, + NotEmittedStatement /* = 344 */, + PartiallyEmittedExpression /* = 345 */, + CommaListExpression /* = 346 */, + MergeDeclarationMarker /* = 347 */, + EndOfDeclarationMarker /* = 348 */, + SyntheticReferenceExpression /* = 349 */, + Count /* = 350 */, + FirstAssignment /* = 63 */, + LastAssignment /* = 78 */, + FirstCompoundAssignment /* = 64 */, + LastCompoundAssignment /* = 78 */, + FirstReservedWord /* = 81 */, + LastReservedWord /* = 116 */, + FirstKeyword /* = 81 */, + LastKeyword /* = 158 */, + FirstFutureReservedWord /* = 117 */, + LastFutureReservedWord /* = 125 */, + FirstTypeNode /* = 175 */, + LastTypeNode /* = 198 */, + FirstPunctuation /* = 18 */, + LastPunctuation /* = 78 */, + FirstToken /* = 0 */, + LastToken /* = 158 */, + FirstTriviaToken /* = 2 */, + LastTriviaToken /* = 7 */, + FirstLiteralToken /* = 8 */, + LastLiteralToken /* = 14 */, + FirstTemplateToken /* = 14 */, + LastTemplateToken /* = 17 */, + FirstBinaryOperator /* = 29 */, + LastBinaryOperator /* = 78 */, + FirstStatement /* = 235 */, + LastStatement /* = 251 */, + FirstNode /* = 159 */, + FirstJSDocNode /* = 304 */, + LastJSDocNode /* = 342 */, + FirstJSDocTagNode /* = 322 */, + LastJSDocTagNode /* = 342 */ +} + +external enum class NodeFlags { + None /* = 0 */, + Let /* = 1 */, + Const /* = 2 */, + NestedNamespace /* = 4 */, + Synthesized /* = 8 */, + Namespace /* = 16 */, + OptionalChain /* = 32 */, + ExportContext /* = 64 */, + ContainsThis /* = 128 */, + HasImplicitReturn /* = 256 */, + HasExplicitReturn /* = 512 */, + GlobalAugmentation /* = 1024 */, + HasAsyncFunctions /* = 2048 */, + DisallowInContext /* = 4096 */, + YieldContext /* = 8192 */, + DecoratorContext /* = 16384 */, + AwaitContext /* = 32768 */, + ThisNodeHasError /* = 65536 */, + JavaScriptFile /* = 131072 */, + ThisNodeOrAnySubNodesHasError /* = 262144 */, + HasAggregatedChildData /* = 524288 */, + JSDoc /* = 4194304 */, + JsonFile /* = 33554432 */, + BlockScoped /* = 3 */, + ReachabilityCheckFlags /* = 768 */, + ReachabilityAndEmitFlags /* = 2816 */, + ContextFlags /* = 25358336 */, + TypeExcludesFlags /* = 40960 */ +} + +external enum class ModifierFlags { + None /* = 0 */, + Export /* = 1 */, + Ambient /* = 2 */, + Public /* = 4 */, + Private /* = 8 */, + Protected /* = 16 */, + Static /* = 32 */, + Readonly /* = 64 */, + Abstract /* = 128 */, + Async /* = 256 */, + Default /* = 512 */, + Const /* = 2048 */, + HasComputedJSDocModifiers /* = 4096 */, + Deprecated /* = 8192 */, + Override /* = 16384 */, + HasComputedFlags /* = 536870912 */, + AccessibilityModifier /* = 28 */, + ParameterPropertyModifier /* = 16476 */, + NonPublicAccessibilityModifier /* = 24 */, + TypeScriptModifier /* = 18654 */, + ExportDefault /* = 513 */, + All /* = 27647 */ +} + +external enum class JsxFlags { + None /* = 0 */, + IntrinsicNamedElement /* = 1 */, + IntrinsicIndexedElement /* = 2 */, + IntrinsicElement /* = 3 */ +} + +external interface Node : ReadonlyTextRange { + fun getSourceFile(): SourceFile + fun getChildCount(sourceFile: SourceFile = definedExternally): Number + fun getChildAt(index: Number, sourceFile: SourceFile = definedExternally): Node + fun getChildren(sourceFile: SourceFile = definedExternally): Array + fun getStart(sourceFile: SourceFile = definedExternally, includeJsDocComment: Boolean = definedExternally): Number + fun getFullStart(): Number + fun getEnd(): Number + fun getWidth(sourceFile: SourceFileLike = definedExternally): Number + fun getFullWidth(): Number + fun getLeadingTriviaWidth(sourceFile: SourceFile = definedExternally): Number + fun getFullText(sourceFile: SourceFile = definedExternally): String + fun getText(sourceFile: SourceFile = definedExternally): String + fun getFirstToken(sourceFile: SourceFile = definedExternally): Node? + fun getLastToken(sourceFile: SourceFile = definedExternally): Node? + fun forEachChild(cbNode: (node: Node) -> T?, cbNodeArray: (nodes: NodeArray) -> T? = definedExternally): T? + var kind: SyntaxKind + var flags: NodeFlags + var decorators: NodeArray? + get() = definedExternally + set(value) = definedExternally + var modifiers: ModifiersArray? + get() = definedExternally + set(value) = definedExternally + var parent: Node +} + +external interface JSDocContainer + +external interface Token : Node { + override var kind: TKind +} + +external interface PunctuationToken : Token + +external interface KeywordToken : Token + +external interface ModifierToken : KeywordToken + +external enum class GeneratedIdentifierFlags { + None /* = 0 */, + ReservedInNestedScopes /* = 8 */, + Optimistic /* = 16 */, + FileLevel /* = 32 */, + AllowNameSubstitution /* = 64 */ +} + +external interface Identifier : PrimaryExpression, Declaration { + var text: String + var escapedText: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + get() = definedExternally + set(value) = definedExternally + var originalKeywordKind: SyntaxKind? + get() = definedExternally + set(value) = definedExternally + var isInJSDocNamespace: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TransientIdentifier : Identifier { + var resolvedSymbol: Symbol +} + +external interface QualifiedName : Node { + var left: dynamic /* Identifier | QualifiedName */ + get() = definedExternally + set(value) = definedExternally + var right: Identifier +} + +external interface Declaration : Node { + var _declarationBrand: Any +} + +external interface NamedDeclaration : Declaration { + var name: dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface DeclarationStatement : NamedDeclaration, Statement { + override var name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ComputedPropertyName : Node { + override var parent: Declaration + var expression: Expression +} + +external interface PrivateIdentifier : Node { + var text: String + var escapedText: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + get() = definedExternally + set(value) = definedExternally +} + +external interface Decorator : Node { + override var parent: NamedDeclaration + var expression: LeftHandSideExpression +} + +external interface TypeParameterDeclaration : NamedDeclaration { + override var parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | InferTypeNode */ + get() = definedExternally + set(value) = definedExternally + override var name: Identifier + var constraint: TypeNode? + get() = definedExternally + set(value) = definedExternally + var default: TypeNode? + get() = definedExternally + set(value) = definedExternally + var expression: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureDeclarationBase : NamedDeclaration, JSDocContainer { + override var name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + set(value) = definedExternally + var typeParameters: NodeArray? + get() = definedExternally + set(value) = definedExternally + var parameters: NodeArray + var type: TypeNode? + get() = definedExternally + set(value) = definedExternally +} + +external interface CallSignatureDeclaration : SignatureDeclarationBase, TypeElement { + override var kind: Any + override var name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ConstructSignatureDeclaration : SignatureDeclarationBase, TypeElement { + override var kind: Any + override var name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface VariableDeclaration : NamedDeclaration, JSDocContainer { + override var parent: dynamic /* VariableDeclarationList | CatchClause */ + get() = definedExternally + set(value) = definedExternally + override var name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ + get() = definedExternally + set(value) = definedExternally + var exclamationToken: ExclamationToken? + get() = definedExternally + set(value) = definedExternally + var type: TypeNode? + get() = definedExternally + set(value) = definedExternally + var initializer: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface VariableDeclarationList : Node { + override var parent: dynamic /* VariableStatement | ForStatement | ForOfStatement | ForInStatement */ + get() = definedExternally + set(value) = definedExternally + var declarations: NodeArray +} + +external interface ParameterDeclaration : NamedDeclaration, JSDocContainer { + override var parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ + get() = definedExternally + set(value) = definedExternally + var dotDotDotToken: DotDotDotToken? + get() = definedExternally + set(value) = definedExternally + override var name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ + get() = definedExternally + set(value) = definedExternally + var questionToken: QuestionToken? + get() = definedExternally + set(value) = definedExternally + var type: TypeNode? + get() = definedExternally + set(value) = definedExternally + var initializer: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface BindingElement : NamedDeclaration { + override var parent: dynamic /* ObjectBindingPattern | ArrayBindingPattern */ + get() = definedExternally + set(value) = definedExternally + var propertyName: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + set(value) = definedExternally + var dotDotDotToken: DotDotDotToken? + get() = definedExternally + set(value) = definedExternally + override var name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ + get() = definedExternally + set(value) = definedExternally + var initializer: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface PropertySignature : TypeElement, JSDocContainer { + override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + set(value) = definedExternally + override var questionToken: QuestionToken? + get() = definedExternally + set(value) = definedExternally + var type: TypeNode? + get() = definedExternally + set(value) = definedExternally + var initializer: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface PropertyDeclaration : ClassElement, JSDocContainer { + override var parent: dynamic /* ClassDeclaration | ClassExpression */ + get() = definedExternally + set(value) = definedExternally + override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + set(value) = definedExternally + var questionToken: QuestionToken? + get() = definedExternally + set(value) = definedExternally + var exclamationToken: ExclamationToken? + get() = definedExternally + set(value) = definedExternally + var type: TypeNode? + get() = definedExternally + set(value) = definedExternally + var initializer: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface ObjectLiteralElement : NamedDeclaration { + var _objectLiteralBrand: Any + override var name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface PropertyAssignment : ObjectLiteralElement, JSDocContainer { + override var parent: ObjectLiteralExpression + override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + set(value) = definedExternally + var questionToken: QuestionToken? + get() = definedExternally + set(value) = definedExternally + var exclamationToken: ExclamationToken? + get() = definedExternally + set(value) = definedExternally + var initializer: Expression +} + +external interface ShorthandPropertyAssignment : ObjectLiteralElement, JSDocContainer { + override var parent: ObjectLiteralExpression + override var name: Identifier + var questionToken: QuestionToken? + get() = definedExternally + set(value) = definedExternally + var exclamationToken: ExclamationToken? + get() = definedExternally + set(value) = definedExternally + var equalsToken: EqualsToken? + get() = definedExternally + set(value) = definedExternally + var objectAssignmentInitializer: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface SpreadAssignment : ObjectLiteralElement, JSDocContainer { + override var parent: ObjectLiteralExpression + var expression: Expression +} + +external interface PropertyLikeDeclaration : NamedDeclaration { + override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ObjectBindingPattern : Node { + override var parent: dynamic /* VariableDeclaration | ParameterDeclaration | BindingElement */ + get() = definedExternally + set(value) = definedExternally + var elements: NodeArray +} + +external interface ArrayBindingPattern : Node { + override var parent: dynamic /* VariableDeclaration | ParameterDeclaration | BindingElement */ + get() = definedExternally + set(value) = definedExternally + var elements: NodeArray +} + +external interface FunctionLikeDeclarationBase : SignatureDeclarationBase { + var _functionLikeDeclarationBrand: Any + var asteriskToken: AsteriskToken? + get() = definedExternally + set(value) = definedExternally + var questionToken: QuestionToken? + get() = definedExternally + set(value) = definedExternally + var exclamationToken: ExclamationToken? + get() = definedExternally + set(value) = definedExternally + var body: dynamic /* Block? | Expression? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FunctionDeclaration : FunctionLikeDeclarationBase, DeclarationStatement { + override var kind: Any + override var name: Identifier? + get() = definedExternally + set(value) = definedExternally + override var body: FunctionBody? + get() = definedExternally + set(value) = definedExternally +} + +external interface MethodSignature : SignatureDeclarationBase, TypeElement { + override var kind: Any + override var parent: dynamic /* ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode */ + get() = definedExternally + set(value) = definedExternally + override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + set(value) = definedExternally +} + +external interface MethodDeclaration : FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { + override var kind: Any + override var parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression */ + get() = definedExternally + set(value) = definedExternally + override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + set(value) = definedExternally + override var body: FunctionBody? + get() = definedExternally + set(value) = definedExternally +} + +external interface ConstructorDeclaration : FunctionLikeDeclarationBase, ClassElement, JSDocContainer { + override var kind: Any + override var parent: dynamic /* ClassDeclaration | ClassExpression */ + get() = definedExternally + set(value) = definedExternally + override var body: FunctionBody? + get() = definedExternally + set(value) = definedExternally +} + +external interface SemicolonClassElement : ClassElement { + override var parent: dynamic /* ClassDeclaration | ClassExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface GetAccessorDeclaration : FunctionLikeDeclarationBase, ClassElement, TypeElement, ObjectLiteralElement, JSDocContainer { + override var kind: Any + override var parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression | TypeLiteralNode | InterfaceDeclaration */ + get() = definedExternally + set(value) = definedExternally + override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + set(value) = definedExternally + override var body: FunctionBody? + get() = definedExternally + set(value) = definedExternally + override var questionToken: QuestionToken? + get() = definedExternally + set(value) = definedExternally +} + +external interface SetAccessorDeclaration : FunctionLikeDeclarationBase, ClassElement, TypeElement, ObjectLiteralElement, JSDocContainer { + override var kind: Any + override var parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression | TypeLiteralNode | InterfaceDeclaration */ + get() = definedExternally + set(value) = definedExternally + override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + set(value) = definedExternally + override var body: FunctionBody? + get() = definedExternally + set(value) = definedExternally + override var questionToken: QuestionToken? + get() = definedExternally + set(value) = definedExternally +} + +external interface IndexSignatureDeclaration : SignatureDeclarationBase, ClassElement, TypeElement { + override var kind: Any + override var parent: dynamic /* ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode */ + get() = definedExternally + set(value) = definedExternally + override var name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ClassStaticBlockDeclaration : ClassElement, JSDocContainer { + override var parent: dynamic /* ClassDeclaration | ClassExpression */ + get() = definedExternally + set(value) = definedExternally + var body: Block +} + +external interface TypeNode : Node { + var _typeNodeBrand: Any +} + +external interface KeywordTypeNode : KeywordToken, TypeNode { + override var kind: TKind +} + +external interface ImportTypeNode : NodeWithTypeArguments { + var isTypeOf: Boolean + var argument: TypeNode + var qualifier: dynamic /* Identifier? | QualifiedName? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ThisTypeNode : TypeNode + +external interface FunctionOrConstructorTypeNodeBase : TypeNode, SignatureDeclarationBase { + override var kind: dynamic /* SyntaxKind.FunctionType | SyntaxKind.ConstructorType */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FunctionTypeNode : FunctionOrConstructorTypeNodeBase { + override var kind: Any +} + +external interface ConstructorTypeNode : FunctionOrConstructorTypeNodeBase { + override var kind: Any +} + +external interface NodeWithTypeArguments : TypeNode { + var typeArguments: NodeArray? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeReferenceNode : NodeWithTypeArguments { + var typeName: dynamic /* Identifier | QualifiedName */ + get() = definedExternally + set(value) = definedExternally +} + +external interface TypePredicateNode : TypeNode { + override var parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | JSDocTypeExpression */ + get() = definedExternally + set(value) = definedExternally + var assertsModifier: AssertsToken? + get() = definedExternally + set(value) = definedExternally + var parameterName: dynamic /* Identifier | ThisTypeNode */ + get() = definedExternally + set(value) = definedExternally + var type: TypeNode? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeQueryNode : TypeNode { + var exprName: dynamic /* Identifier | QualifiedName */ + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeLiteralNode : TypeNode, Declaration { + var members: NodeArray +} + +external interface ArrayTypeNode : TypeNode { + var elementType: TypeNode +} + +external interface TupleTypeNode : TypeNode { + var elements: NodeArray +} + +external interface NamedTupleMember : TypeNode, JSDocContainer, Declaration { + var dotDotDotToken: Token? + get() = definedExternally + set(value) = definedExternally + var name: Identifier + var questionToken: Token? + get() = definedExternally + set(value) = definedExternally + var type: TypeNode +} + +external interface OptionalTypeNode : TypeNode { + var type: TypeNode +} + +external interface RestTypeNode : TypeNode { + var type: TypeNode +} + +external interface UnionTypeNode : TypeNode { + var types: NodeArray +} + +external interface IntersectionTypeNode : TypeNode { + var types: NodeArray +} + +external interface ConditionalTypeNode : TypeNode { + var checkType: TypeNode + var extendsType: TypeNode + var trueType: TypeNode + var falseType: TypeNode +} + +external interface InferTypeNode : TypeNode { + var typeParameter: TypeParameterDeclaration +} + +external interface ParenthesizedTypeNode : TypeNode { + var type: TypeNode +} + +external interface TypeOperatorNode : TypeNode { + var operator: dynamic /* SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword */ + get() = definedExternally + set(value) = definedExternally + var type: TypeNode +} + +external interface IndexedAccessTypeNode : TypeNode { + var objectType: TypeNode + var indexType: TypeNode +} + +external interface MappedTypeNode : TypeNode, Declaration { + var readonlyToken: dynamic /* ReadonlyToken? | PlusToken? | MinusToken? */ + get() = definedExternally + set(value) = definedExternally + var typeParameter: TypeParameterDeclaration + var nameType: TypeNode? + get() = definedExternally + set(value) = definedExternally + var questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */ + get() = definedExternally + set(value) = definedExternally + var type: TypeNode? + get() = definedExternally + set(value) = definedExternally +} + +external interface LiteralTypeNode : TypeNode { + var literal: dynamic /* NullLiteral | TrueLiteral | FalseLiteral | LiteralExpression | PrefixUnaryExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface StringLiteral : LiteralExpression, Declaration + +external interface TemplateLiteralTypeNode : TypeNode { + var head: TemplateHead + var templateSpans: NodeArray +} + +external interface TemplateLiteralTypeSpan : TypeNode { + override var parent: TemplateLiteralTypeNode + var type: TypeNode + var literal: dynamic /* TemplateMiddle | TemplateTail */ + get() = definedExternally + set(value) = definedExternally +} + +external interface Expression : Node { + var _expressionBrand: Any +} + +external interface OmittedExpression : Expression + +external interface PartiallyEmittedExpression : LeftHandSideExpression { + var expression: Expression +} + +external interface UnaryExpression : Expression { + var _unaryExpressionBrand: Any +} + +external interface UpdateExpression : UnaryExpression { + var _updateExpressionBrand: Any +} + +external interface PrefixUnaryExpression : UpdateExpression { + var operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken | SyntaxKind.ExclamationToken */ + get() = definedExternally + set(value) = definedExternally + var operand: UnaryExpression +} + +external interface PostfixUnaryExpression : UpdateExpression { + var operand: LeftHandSideExpression + var operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken */ + get() = definedExternally + set(value) = definedExternally +} + +external interface LeftHandSideExpression : UpdateExpression { + var _leftHandSideExpressionBrand: Any +} + +external interface MemberExpression : LeftHandSideExpression { + var _memberExpressionBrand: Any +} + +external interface PrimaryExpression : MemberExpression { + var _primaryExpressionBrand: Any +} + +external interface NullLiteral : PrimaryExpression + +external interface TrueLiteral : PrimaryExpression + +external interface FalseLiteral : PrimaryExpression + +external interface ThisExpression : PrimaryExpression + +external interface SuperExpression : PrimaryExpression + +external interface ImportExpression : PrimaryExpression + +external interface DeleteExpression : UnaryExpression { + var expression: UnaryExpression +} + +external interface TypeOfExpression : UnaryExpression { + var expression: UnaryExpression +} + +external interface VoidExpression : UnaryExpression { + var expression: UnaryExpression +} + +external interface AwaitExpression : UnaryExpression { + var expression: UnaryExpression +} + +external interface YieldExpression : Expression { + var asteriskToken: AsteriskToken? + get() = definedExternally + set(value) = definedExternally + var expression: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface SyntheticExpression : Expression { + var isSpread: Boolean + var type: Type + var tupleNameSource: dynamic /* ParameterDeclaration? | NamedTupleMember? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface BinaryExpression : Expression, Declaration { + var left: Expression + var operatorToken: BinaryOperatorToken + var right: Expression +} + +external interface AssignmentExpression : BinaryExpression { + override var left: LeftHandSideExpression + override var operatorToken: TOperator +} + +external interface ObjectDestructuringAssignment : AssignmentExpression { + override var left: ObjectLiteralExpression +} + +external interface ArrayDestructuringAssignment : AssignmentExpression { + override var left: ArrayLiteralExpression +} + +external interface ConditionalExpression : Expression { + var condition: Expression + var questionToken: QuestionToken + var whenTrue: Expression + var colonToken: ColonToken + var whenFalse: Expression +} + +external interface FunctionExpression : PrimaryExpression, FunctionLikeDeclarationBase, JSDocContainer { + override var kind: Any + override var name: Identifier? + get() = definedExternally + set(value) = definedExternally + override var body: FunctionBody +} + +external interface ArrowFunction : Expression, FunctionLikeDeclarationBase, JSDocContainer { + override var kind: Any + var equalsGreaterThanToken: EqualsGreaterThanToken + override var body: dynamic /* FunctionBody | Expression */ + get() = definedExternally + set(value) = definedExternally + override var name: Any +} + +external interface LiteralLikeNode : Node { + var text: String + var isUnterminated: Boolean? + get() = definedExternally + set(value) = definedExternally + var hasExtendedUnicodeEscape: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TemplateLiteralLikeNode : LiteralLikeNode { + var rawText: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface LiteralExpression : LiteralLikeNode, PrimaryExpression { + var _literalExpressionBrand: Any +} + +external interface RegularExpressionLiteral : LiteralExpression + +external interface NoSubstitutionTemplateLiteral : LiteralExpression, TemplateLiteralLikeNode, Declaration + +external enum class TokenFlags { + None /* = 0 */, + Scientific /* = 16 */, + Octal /* = 32 */, + HexSpecifier /* = 64 */, + BinarySpecifier /* = 128 */, + OctalSpecifier /* = 256 */ +} + +external interface NumericLiteral : LiteralExpression, Declaration + +external interface BigIntLiteral : LiteralExpression + +external interface TemplateHead : TemplateLiteralLikeNode { + override var parent: dynamic /* TemplateExpression | TemplateLiteralTypeNode */ + get() = definedExternally + set(value) = definedExternally +} + +external interface TemplateMiddle : TemplateLiteralLikeNode { + override var parent: dynamic /* TemplateSpan | TemplateLiteralTypeSpan */ + get() = definedExternally + set(value) = definedExternally +} + +external interface TemplateTail : TemplateLiteralLikeNode { + override var parent: dynamic /* TemplateSpan | TemplateLiteralTypeSpan */ + get() = definedExternally + set(value) = definedExternally +} + +external interface TemplateExpression : PrimaryExpression { + var head: TemplateHead + var templateSpans: NodeArray +} + +external interface TemplateSpan : Node { + override var parent: TemplateExpression + var expression: Expression + var literal: dynamic /* TemplateMiddle | TemplateTail */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ParenthesizedExpression : PrimaryExpression, JSDocContainer { + var expression: Expression +} + +external interface ArrayLiteralExpression : PrimaryExpression { + var elements: NodeArray +} + +external interface SpreadElement : Expression { + override var parent: dynamic /* ArrayLiteralExpression | CallExpression | NewExpression */ + get() = definedExternally + set(value) = definedExternally + var expression: Expression +} + +external interface ObjectLiteralExpressionBase : PrimaryExpression, Declaration { + var properties: NodeArray +} + +external interface ObjectLiteralExpression : ObjectLiteralExpressionBase + +external interface PropertyAccessExpression : MemberExpression, NamedDeclaration { + var expression: LeftHandSideExpression + var questionDotToken: QuestionDotToken? + get() = definedExternally + set(value) = definedExternally + override var name: dynamic /* Identifier | PrivateIdentifier */ + get() = definedExternally + set(value) = definedExternally +} + +external interface PropertyAccessChain : PropertyAccessExpression { + var _optionalChainBrand: Any + override var name: dynamic /* Identifier | PrivateIdentifier */ + get() = definedExternally + set(value) = definedExternally +} + +external interface SuperPropertyAccessExpression : PropertyAccessExpression { + override var expression: SuperExpression +} + +external interface PropertyAccessEntityNameExpression : PropertyAccessExpression { + var _propertyAccessExpressionLikeQualifiedNameBrand: Any? + get() = definedExternally + set(value) = definedExternally + override var expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ + get() = definedExternally + set(value) = definedExternally + override var name: Identifier +} + +external interface ElementAccessExpression : MemberExpression { + var expression: LeftHandSideExpression + var questionDotToken: QuestionDotToken? + get() = definedExternally + set(value) = definedExternally + var argumentExpression: Expression +} + +external interface ElementAccessChain : ElementAccessExpression { + var _optionalChainBrand: Any +} + +external interface SuperElementAccessExpression : ElementAccessExpression { + override var expression: SuperExpression +} + +external interface CallExpression : LeftHandSideExpression, Declaration { + var expression: LeftHandSideExpression + var questionDotToken: QuestionDotToken? + get() = definedExternally + set(value) = definedExternally + var typeArguments: NodeArray? + get() = definedExternally + set(value) = definedExternally + var arguments: NodeArray +} + +external interface CallChain : CallExpression { + var _optionalChainBrand: Any +} + +external interface SuperCall : CallExpression { + override var expression: SuperExpression +} + +external interface ImportCall : CallExpression { + override var expression: ImportExpression +} + +external interface ExpressionWithTypeArguments : NodeWithTypeArguments { + override var parent: dynamic /* HeritageClause | JSDocAugmentsTag | JSDocImplementsTag */ + get() = definedExternally + set(value) = definedExternally + var expression: LeftHandSideExpression +} + +external interface NewExpression : PrimaryExpression, Declaration { + var expression: LeftHandSideExpression + var typeArguments: NodeArray? + get() = definedExternally + set(value) = definedExternally + var arguments: NodeArray? + get() = definedExternally + set(value) = definedExternally +} + +external interface TaggedTemplateExpression : MemberExpression { + var tag: LeftHandSideExpression + var typeArguments: NodeArray? + get() = definedExternally + set(value) = definedExternally + var template: dynamic /* TemplateExpression | NoSubstitutionTemplateLiteral */ + get() = definedExternally + set(value) = definedExternally +} + +external interface AsExpression : Expression { + var expression: Expression + var type: TypeNode +} + +external interface TypeAssertion : UnaryExpression { + var type: TypeNode + var expression: UnaryExpression +} + +external interface NonNullExpression : LeftHandSideExpression { + var expression: Expression +} + +external interface NonNullChain : NonNullExpression { + var _optionalChainBrand: Any +} + +external interface MetaProperty : PrimaryExpression { + var keywordToken: dynamic /* SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword */ + get() = definedExternally + set(value) = definedExternally + var name: Identifier +} + +external interface JsxElement : PrimaryExpression { + var openingElement: JsxOpeningElement + var children: NodeArray + var closingElement: JsxClosingElement +} + +external interface JsxTagNamePropertyAccess : PropertyAccessExpression { + override var expression: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ + get() = definedExternally + set(value) = definedExternally +} + +external interface JsxAttributes : ObjectLiteralExpressionBase { + override var parent: dynamic /* JsxSelfClosingElement | JsxOpeningElement */ + get() = definedExternally + set(value) = definedExternally +} + +external interface JsxOpeningElement : Expression { + override var parent: JsxElement + var tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ + get() = definedExternally + set(value) = definedExternally + var typeArguments: NodeArray? + get() = definedExternally + set(value) = definedExternally + var attributes: JsxAttributes +} + +external interface JsxSelfClosingElement : PrimaryExpression { + var tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ + get() = definedExternally + set(value) = definedExternally + var typeArguments: NodeArray? + get() = definedExternally + set(value) = definedExternally + var attributes: JsxAttributes +} + +external interface JsxFragment : PrimaryExpression { + var openingFragment: JsxOpeningFragment + var children: NodeArray + var closingFragment: JsxClosingFragment +} + +external interface JsxOpeningFragment : Expression { + override var parent: JsxFragment +} + +external interface JsxClosingFragment : Expression { + override var parent: JsxFragment +} + +external interface JsxAttribute : ObjectLiteralElement { + override var parent: JsxAttributes + override var name: Identifier + var initializer: dynamic /* StringLiteral? | JsxExpression? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface JsxSpreadAttribute : ObjectLiteralElement { + override var parent: JsxAttributes + var expression: Expression +} + +external interface JsxClosingElement : Node { + override var parent: JsxElement + var tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ + get() = definedExternally + set(value) = definedExternally +} + +external interface JsxExpression : Expression { + override var parent: dynamic /* JsxElement | JsxAttribute | JsxSpreadAttribute */ + get() = definedExternally + set(value) = definedExternally + var dotDotDotToken: Token? + get() = definedExternally + set(value) = definedExternally + var expression: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface JsxText : LiteralLikeNode { + override var parent: JsxElement + var containsOnlyTriviaWhiteSpaces: Boolean +} + +external interface Statement : Node, JSDocContainer { + var _statementBrand: Any +} + +external interface NotEmittedStatement : Statement + +external interface CommaListExpression : Expression { + var elements: NodeArray +} + +external interface EmptyStatement : Statement + +external interface DebuggerStatement : Statement + +external interface MissingDeclaration : DeclarationStatement { + override var name: Identifier? + get() = definedExternally + set(value) = definedExternally +} + +external interface Block : Statement { + var statements: NodeArray +} + +external interface VariableStatement : Statement { + var declarationList: VariableDeclarationList +} + +external interface ExpressionStatement : Statement { + var expression: Expression +} + +external interface IfStatement : Statement { + var expression: Expression + var thenStatement: Statement + var elseStatement: Statement? + get() = definedExternally + set(value) = definedExternally +} + +external interface IterationStatement : Statement { + var statement: Statement +} + +external interface DoStatement : IterationStatement { + var expression: Expression +} + +external interface WhileStatement : IterationStatement { + var expression: Expression +} + +external interface ForStatement : IterationStatement { + var initializer: dynamic /* VariableDeclarationList? | Expression? */ + get() = definedExternally + set(value) = definedExternally + var condition: Expression? + get() = definedExternally + set(value) = definedExternally + var incrementor: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface ForInStatement : IterationStatement { + var initializer: dynamic /* VariableDeclarationList | Expression */ + get() = definedExternally + set(value) = definedExternally + var expression: Expression +} + +external interface ForOfStatement : IterationStatement { + var awaitModifier: AwaitKeywordToken? + get() = definedExternally + set(value) = definedExternally + var initializer: dynamic /* VariableDeclarationList | Expression */ + get() = definedExternally + set(value) = definedExternally + var expression: Expression +} + +external interface BreakStatement : Statement { + var label: Identifier? + get() = definedExternally + set(value) = definedExternally +} + +external interface ContinueStatement : Statement { + var label: Identifier? + get() = definedExternally + set(value) = definedExternally +} + +external interface ReturnStatement : Statement { + var expression: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface WithStatement : Statement { + var expression: Expression + var statement: Statement +} + +external interface SwitchStatement : Statement { + var expression: Expression + var caseBlock: CaseBlock + var possiblyExhaustive: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface CaseBlock : Node { + override var parent: SwitchStatement + var clauses: NodeArray +} + +external interface CaseClause : Node { + override var parent: CaseBlock + var expression: Expression + var statements: NodeArray +} + +external interface DefaultClause : Node { + override var parent: CaseBlock + var statements: NodeArray +} + +external interface LabeledStatement : Statement { + var label: Identifier + var statement: Statement +} + +external interface ThrowStatement : Statement { + var expression: Expression +} + +external interface TryStatement : Statement { + var tryBlock: Block + var catchClause: CatchClause? + get() = definedExternally + set(value) = definedExternally + var finallyBlock: Block? + get() = definedExternally + set(value) = definedExternally +} + +external interface CatchClause : Node { + override var parent: TryStatement + var variableDeclaration: VariableDeclaration? + get() = definedExternally + set(value) = definedExternally + var block: Block +} + +external interface ClassLikeDeclarationBase : NamedDeclaration, JSDocContainer { + override var kind: dynamic /* SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression */ + get() = definedExternally + set(value) = definedExternally + override var name: Identifier? + get() = definedExternally + set(value) = definedExternally + var typeParameters: NodeArray? + get() = definedExternally + set(value) = definedExternally + var heritageClauses: NodeArray? + get() = definedExternally + set(value) = definedExternally + var members: NodeArray +} + +external interface ClassDeclaration : ClassLikeDeclarationBase, DeclarationStatement { + override var kind: Any + override var name: Identifier? + get() = definedExternally + set(value) = definedExternally +} + +external interface ClassExpression : ClassLikeDeclarationBase, PrimaryExpression { + override var kind: Any +} + +external interface ClassElement : NamedDeclaration { + var _classElementBrand: Any + override var name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeElement : NamedDeclaration { + var _typeElementBrand: Any + override var name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ + get() = definedExternally + set(value) = definedExternally + var questionToken: QuestionToken? + get() = definedExternally + set(value) = definedExternally +} + +external interface InterfaceDeclaration : DeclarationStatement, JSDocContainer { + override var name: Identifier + var typeParameters: NodeArray? + get() = definedExternally + set(value) = definedExternally + var heritageClauses: NodeArray? + get() = definedExternally + set(value) = definedExternally + var members: NodeArray +} + +external interface HeritageClause : Node { + override var parent: dynamic /* InterfaceDeclaration | ClassDeclaration | ClassExpression */ + get() = definedExternally + set(value) = definedExternally + var token: dynamic /* SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword */ + get() = definedExternally + set(value) = definedExternally + var types: NodeArray +} + +external interface TypeAliasDeclaration : DeclarationStatement, JSDocContainer { + override var name: Identifier + var typeParameters: NodeArray? + get() = definedExternally + set(value) = definedExternally + var type: TypeNode +} + +external interface EnumMember : NamedDeclaration, JSDocContainer { + override var parent: EnumDeclaration + override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ + get() = definedExternally + set(value) = definedExternally + var initializer: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface EnumDeclaration : DeclarationStatement, JSDocContainer { + override var name: Identifier + var members: NodeArray +} + +external interface ModuleDeclaration : DeclarationStatement, JSDocContainer { + override var parent: dynamic /* ModuleBlock | NamespaceDeclaration | Identifier | JSDocNamespaceDeclaration | SourceFile */ + get() = definedExternally + set(value) = definedExternally + override var name: dynamic /* Identifier | StringLiteral */ + get() = definedExternally + set(value) = definedExternally + var body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface NamespaceDeclaration : ModuleDeclaration { + override var name: Identifier + override var body: dynamic /* ModuleBlock | NamespaceDeclaration */ + get() = definedExternally + set(value) = definedExternally +} + +external interface JSDocNamespaceDeclaration : ModuleDeclaration { + override var name: Identifier + override var body: dynamic /* Identifier? | JSDocNamespaceDeclaration? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ModuleBlock : Node, Statement { + override var parent: ModuleDeclaration + var statements: NodeArray +} + +external interface ImportEqualsDeclaration : DeclarationStatement, JSDocContainer { + override var parent: dynamic /* SourceFile | ModuleBlock */ + get() = definedExternally + set(value) = definedExternally + override var name: Identifier + var isTypeOnly: Boolean + var moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ExternalModuleReference : Node { + override var parent: ImportEqualsDeclaration + var expression: Expression +} + +external interface ImportDeclaration : Statement { + override var parent: dynamic /* SourceFile | ModuleBlock */ + get() = definedExternally + set(value) = definedExternally + var importClause: ImportClause? + get() = definedExternally + set(value) = definedExternally + var moduleSpecifier: Expression +} + +external interface ImportClause : NamedDeclaration { + override var parent: ImportDeclaration + var isTypeOnly: Boolean + override var name: Identifier? + get() = definedExternally + set(value) = definedExternally + var namedBindings: dynamic /* NamespaceImport? | NamedImports? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface NamespaceImport : NamedDeclaration { + override var parent: ImportClause + override var name: Identifier +} + +external interface NamespaceExport : NamedDeclaration { + override var parent: ExportDeclaration + override var name: Identifier +} + +external interface NamespaceExportDeclaration : DeclarationStatement, JSDocContainer { + override var name: Identifier +} + +external interface ExportDeclaration : DeclarationStatement, JSDocContainer { + override var parent: dynamic /* SourceFile | ModuleBlock */ + get() = definedExternally + set(value) = definedExternally + var isTypeOnly: Boolean + var exportClause: dynamic /* NamespaceExport? | NamedExports? */ + get() = definedExternally + set(value) = definedExternally + var moduleSpecifier: Expression? + get() = definedExternally + set(value) = definedExternally +} + +external interface NamedImports : Node { + override var parent: ImportClause + var elements: NodeArray +} + +external interface NamedExports : Node { + override var parent: ExportDeclaration + var elements: NodeArray +} + +external interface ImportSpecifier : NamedDeclaration { + override var parent: NamedImports + var propertyName: Identifier? + get() = definedExternally + set(value) = definedExternally + override var name: Identifier +} + +external interface ExportSpecifier : NamedDeclaration { + override var parent: NamedExports + var propertyName: Identifier? + get() = definedExternally + set(value) = definedExternally + override var name: Identifier +} + +external interface ExportAssignment : DeclarationStatement, JSDocContainer { + override var parent: SourceFile + var isExportEquals: Boolean? + get() = definedExternally + set(value) = definedExternally + var expression: Expression +} + +external interface FileReference : TextRange { + var fileName: String +} + +external interface CheckJsDirective : TextRange { + var enabled: Boolean +} + +external interface CommentRange : TextRange { + var hasTrailingNewLine: Boolean? + get() = definedExternally + set(value) = definedExternally + var kind: dynamic /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */ + get() = definedExternally + set(value) = definedExternally +} + +external interface SynthesizedComment : CommentRange { + var text: String + var hasLeadingNewline: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface JSDocTypeExpression : TypeNode { + var type: TypeNode +} + +external interface JSDocNameReference : Node { + var name: dynamic /* Identifier | QualifiedName | JSDocMemberName */ + get() = definedExternally + set(value) = definedExternally +} + +external interface JSDocMemberName : Node { + var left: dynamic /* Identifier | QualifiedName | JSDocMemberName */ + get() = definedExternally + set(value) = definedExternally + var right: Identifier +} + +external interface JSDocType : TypeNode { + var _jsDocTypeBrand: Any +} + +external interface JSDocAllType : JSDocType + +external interface JSDocUnknownType : JSDocType + +external interface JSDocNonNullableType : JSDocType { + var type: TypeNode +} + +external interface JSDocNullableType : JSDocType { + var type: TypeNode +} + +external interface JSDocOptionalType : JSDocType { + var type: TypeNode +} + +external interface JSDocFunctionType : JSDocType, SignatureDeclarationBase { + override var kind: Any +} + +external interface JSDocVariadicType : JSDocType { + var type: TypeNode +} + +external interface JSDocNamepathType : JSDocType { + var type: TypeNode +} + +external interface JSDoc : Node { + override var parent: dynamic /* ParameterDeclaration | CallSignatureDeclaration | ClassStaticBlockDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | EmptyStatement | DebuggerStatement | Block | VariableStatement | ExpressionStatement | IfStatement | DoStatement | WhileStatement | ForStatement | ForInStatement | ForOfStatement | BreakStatement | ContinueStatement | ReturnStatement | WithStatement | SwitchStatement | LabeledStatement | ThrowStatement | TryStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | VariableDeclaration | PropertyDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | NamespaceExportDeclaration | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | Token & JSDocContainer */ + get() = definedExternally + set(value) = definedExternally + var tags: NodeArray? + get() = definedExternally + set(value) = definedExternally + var comment: dynamic /* String? | NodeArray? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface JSDocTag : Node { + override var parent: dynamic /* JSDoc | JSDocTypeLiteral */ + get() = definedExternally + set(value) = definedExternally + var tagName: Identifier + var comment: dynamic /* String? | NodeArray? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface JSDocLink : Node { + var name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ + get() = definedExternally + set(value) = definedExternally + var text: String +} + +external interface JSDocLinkCode : Node { + var name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ + get() = definedExternally + set(value) = definedExternally + var text: String +} + +external interface JSDocLinkPlain : Node { + var name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ + get() = definedExternally + set(value) = definedExternally + var text: String +} + +external interface JSDocText : Node { + var text: String +} + +external interface JSDocUnknownTag : JSDocTag + +external interface `T$21` { + var expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ + get() = definedExternally + set(value) = definedExternally +} + +external interface JSDocAugmentsTag : JSDocTag { + var `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */ +} + +external interface JSDocImplementsTag : JSDocTag { + var `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */ +} + +external interface JSDocAuthorTag : JSDocTag + +external interface JSDocDeprecatedTag : JSDocTag + +external interface JSDocClassTag : JSDocTag + +external interface JSDocPublicTag : JSDocTag + +external interface JSDocPrivateTag : JSDocTag + +external interface JSDocProtectedTag : JSDocTag + +external interface JSDocReadonlyTag : JSDocTag + +external interface JSDocOverrideTag : JSDocTag + +external interface JSDocEnumTag : JSDocTag, Declaration { + override var parent: JSDoc + var typeExpression: JSDocTypeExpression +} + +external interface JSDocThisTag : JSDocTag { + var typeExpression: JSDocTypeExpression +} + +external interface JSDocTemplateTag : JSDocTag { + var constraint: JSDocTypeExpression? + var typeParameters: NodeArray +} + +external interface JSDocSeeTag : JSDocTag { + var name: JSDocNameReference? + get() = definedExternally + set(value) = definedExternally +} + +external interface JSDocReturnTag : JSDocTag { + var typeExpression: JSDocTypeExpression? + get() = definedExternally + set(value) = definedExternally +} + +external interface JSDocTypeTag : JSDocTag { + var typeExpression: JSDocTypeExpression +} + +external interface JSDocTypedefTag : JSDocTag, NamedDeclaration { + override var parent: JSDoc + var fullName: dynamic /* JSDocNamespaceDeclaration? | Identifier? */ + get() = definedExternally + set(value) = definedExternally + override var name: Identifier? + get() = definedExternally + set(value) = definedExternally + var typeExpression: dynamic /* JSDocTypeExpression? | JSDocTypeLiteral? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface JSDocCallbackTag : JSDocTag, NamedDeclaration { + override var parent: JSDoc + var fullName: dynamic /* JSDocNamespaceDeclaration? | Identifier? */ + get() = definedExternally + set(value) = definedExternally + override var name: Identifier? + get() = definedExternally + set(value) = definedExternally + var typeExpression: JSDocSignature +} + +external interface JSDocSignature : JSDocType, Declaration { + var typeParameters: Array? + get() = definedExternally + set(value) = definedExternally + var parameters: Array + var type: JSDocReturnTag? +} + +external interface JSDocPropertyLikeTag : JSDocTag, Declaration { + override var parent: JSDoc + var name: dynamic /* Identifier | QualifiedName */ + get() = definedExternally + set(value) = definedExternally + var typeExpression: JSDocTypeExpression? + get() = definedExternally + set(value) = definedExternally + var isNameFirst: Boolean + var isBracketed: Boolean +} + +external interface JSDocPropertyTag : JSDocPropertyLikeTag + +external interface JSDocParameterTag : JSDocPropertyLikeTag + +external interface JSDocTypeLiteral : JSDocType { + var jsDocPropertyTags: Array? + get() = definedExternally + set(value) = definedExternally + var isArrayType: Boolean +} + +external enum class FlowFlags { + Unreachable /* = 1 */, + Start /* = 2 */, + BranchLabel /* = 4 */, + LoopLabel /* = 8 */, + Assignment /* = 16 */, + TrueCondition /* = 32 */, + FalseCondition /* = 64 */, + SwitchClause /* = 128 */, + ArrayMutation /* = 256 */, + Call /* = 512 */, + ReduceLabel /* = 1024 */, + Referenced /* = 2048 */, + Shared /* = 4096 */, + Label /* = 12 */, + Condition /* = 96 */ +} + +external interface FlowNodeBase { + var flags: FlowFlags + var id: Number? + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowStart : FlowNodeBase { + var node: dynamic /* FunctionExpression? | ArrowFunction? | MethodDeclaration? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowLabel : FlowNodeBase { + var antecedents: Array? +} + +external interface FlowAssignment : FlowNodeBase { + var node: dynamic /* Expression | VariableDeclaration | BindingElement */ + get() = definedExternally + set(value) = definedExternally + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowCall : FlowNodeBase { + var node: CallExpression + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowCondition : FlowNodeBase { + var node: Expression + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowSwitchClause : FlowNodeBase { + var switchStatement: SwitchStatement + var clauseStart: Number + var clauseEnd: Number + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowArrayMutation : FlowNodeBase { + var node: dynamic /* CallExpression | BinaryExpression */ + get() = definedExternally + set(value) = definedExternally + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface FlowReduceLabel : FlowNodeBase { + var target: FlowLabel + var antecedents: Array + var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ + get() = definedExternally + set(value) = definedExternally +} + +external interface IncompleteType { + var flags: TypeFlags + var type: Type +} + +external interface AmdDependency { + var path: String + var name: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface SourceFile : Declaration { + fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter + fun getLineEndOfPosition(pos: Number): Number + fun getLineStarts(): Array + fun getPositionOfLineAndCharacter(line: Number, character: Number): Number + fun update(newText: String, textChangeRange: TextChangeRange): SourceFile + var statements: NodeArray + var endOfFileToken: Token + var fileName: String + var text: String + var amdDependencies: Array + var moduleName: String? + get() = definedExternally + set(value) = definedExternally + var referencedFiles: Array + var typeReferenceDirectives: Array + var libReferenceDirectives: Array + var languageVariant: LanguageVariant + var isDeclarationFile: Boolean + var hasNoDefaultLib: Boolean + var languageVersion: ScriptTarget +} + +external interface Bundle : Node { + var prepends: Array + var sourceFiles: Array +} + +external interface InputFiles : Node { + var javascriptPath: String? + get() = definedExternally + set(value) = definedExternally + var javascriptText: String + var javascriptMapPath: String? + get() = definedExternally + set(value) = definedExternally + var javascriptMapText: String? + get() = definedExternally + set(value) = definedExternally + var declarationPath: String? + get() = definedExternally + set(value) = definedExternally + var declarationText: String + var declarationMapPath: String? + get() = definedExternally + set(value) = definedExternally + var declarationMapText: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface UnparsedSource : Node { + var fileName: String + var text: String + var prologues: Array + var helpers: Array? + var referencedFiles: Array + var typeReferenceDirectives: Array? + var libReferenceDirectives: Array + var hasNoDefaultLib: Boolean? + get() = definedExternally + set(value) = definedExternally + var sourceMapPath: String? + get() = definedExternally + set(value) = definedExternally + var sourceMapText: String? + get() = definedExternally + set(value) = definedExternally + var syntheticReferences: Array? + get() = definedExternally + set(value) = definedExternally + var texts: Array +} + +external interface UnparsedSection : Node { + override var kind: SyntaxKind + override var parent: UnparsedSource + var data: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface UnparsedPrologue : UnparsedSection { + override var parent: UnparsedSource +} + +external interface UnparsedPrepend : UnparsedSection { + override var parent: UnparsedSource + var texts: Array +} + +external interface UnparsedTextLike : UnparsedSection { + override var kind: dynamic /* SyntaxKind.UnparsedText | SyntaxKind.UnparsedInternalText */ + get() = definedExternally + set(value) = definedExternally + override var parent: UnparsedSource +} + +external interface UnparsedSyntheticReference : UnparsedSection { + override var parent: UnparsedSource +} + +external interface JsonSourceFile : SourceFile { + override var statements: NodeArray +} + +external interface TsConfigSourceFile : JsonSourceFile { + var extendedSourceFiles: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface JsonMinusNumericLiteral : PrefixUnaryExpression { + override var kind: Any + override var operator: Any + override var operand: NumericLiteral +} + +external interface JsonObjectExpressionStatement : ExpressionStatement { + override var expression: dynamic /* ObjectLiteralExpression | ArrayLiteralExpression | JsonMinusNumericLiteral | NumericLiteral | StringLiteral | TrueLiteral | FalseLiteral | NullLiteral */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ScriptReferenceHost { + fun getCompilerOptions(): CompilerOptions + fun getSourceFile(fileName: String): SourceFile? + fun getSourceFileByPath(path: String /* String & `T$3` */): SourceFile? + fun getCurrentDirectory(): String +} + +external interface ParseConfigHost { + var useCaseSensitiveFileNames: Boolean + fun readDirectory(rootDir: String, extensions: Array, excludes: Array?, includes: Array, depth: Number = definedExternally): Array + fun fileExists(path: String): Boolean + fun readFile(path: String): String? + val trace: ((s: String) -> Unit)? +} + +external open class OperationCanceledException + +external interface CancellationToken { + fun isCancellationRequested(): Boolean + fun throwIfCancellationRequested() +} + +external interface Program : ScriptReferenceHost { + override fun getCurrentDirectory(): String + fun getRootFileNames(): Array + fun getSourceFiles(): Array + fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult + fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getDeclarationDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getConfigFileParsingDiagnostics(): Array + fun getTypeChecker(): TypeChecker + fun getNodeCount(): Number + fun getIdentifierCount(): Number + fun getSymbolCount(): Number + fun getTypeCount(): Number + fun getInstantiationCount(): Number + fun getRelationCacheSizes(): `T$6` + fun isSourceFileFromExternalLibrary(file: SourceFile): Boolean + fun isSourceFileDefaultLibrary(file: SourceFile): Boolean + fun getProjectReferences(): Array? + fun getResolvedProjectReferences(): Array? +} + +external interface ResolvedProjectReference { + var commandLine: ParsedCommandLine + var sourceFile: SourceFile + var references: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface CustomTransformer { + fun transformSourceFile(node: SourceFile): SourceFile + fun transformBundle(node: Bundle): Bundle +} + +external interface CustomTransformers { + var before: Array | CustomTransformerFactory */>? + get() = definedExternally + set(value) = definedExternally + var after: Array | CustomTransformerFactory */>? + get() = definedExternally + set(value) = definedExternally + var afterDeclarations: Array | CustomTransformerFactory */>? + get() = definedExternally + set(value) = definedExternally +} + +external interface SourceMapSpan { + var emittedLine: Number + var emittedColumn: Number + var sourceLine: Number + var sourceColumn: Number + var nameIndex: Number? + get() = definedExternally + set(value) = definedExternally + var sourceIndex: Number +} + +external enum class ExitStatus { + Success /* = 0 */, + DiagnosticsPresent_OutputsSkipped /* = 1 */, + DiagnosticsPresent_OutputsGenerated /* = 2 */, + InvalidProject_OutputsSkipped /* = 3 */, + ProjectReferenceCycle_OutputsSkipped /* = 4 */, + ProjectReferenceCycle_OutputsSkupped /* = 4 */ +} + +external interface EmitResult { + var emitSkipped: Boolean + var diagnostics: Array + var emittedFiles: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface `T$22` { + var typeArguments: NodeArray? + get() = definedExternally + set(value) = definedExternally +} + +external interface TypeChecker { + fun getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type + fun getDeclaredTypeOfSymbol(symbol: Symbol): Type + fun getPropertiesOfType(type: Type): Array + fun getPropertyOfType(type: Type, propertyName: String): Symbol? + fun getPrivateIdentifierPropertyOfType(leftType: Type, name: String, location: Node): Symbol? + fun getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo? + fun getIndexInfosOfType(type: Type): Array + fun getSignaturesOfType(type: Type, kind: SignatureKind): Array + fun getIndexTypeOfType(type: Type, kind: IndexKind): Type? + fun getBaseTypes(type: InterfaceType): Array + fun getBaseTypeOfLiteralType(type: Type): Type + fun getWidenedType(type: Type): Type + fun getReturnTypeOfSignature(signature: Signature): Type + fun getNullableType(type: Type, flags: TypeFlags): Type + fun getNonNullableType(type: Type): Type + fun getTypeArguments(type: TypeReference): Array + fun typeToTypeNode(type: Type, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeNode? + fun signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ + fun indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): IndexSignatureDeclaration? + fun symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* Identifier? | QualifiedName? */ + fun symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): Expression? + fun symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): NodeArray? + fun symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): ParameterDeclaration? + fun typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeParameterDeclaration? + fun getSymbolsInScope(location: Node, meaning: SymbolFlags): Array + fun getSymbolAtLocation(node: Node): Symbol? + fun getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: String): Array + fun getShorthandAssignmentValueSymbol(location: Node?): Symbol? + fun getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol? + fun getExportSpecifierLocalTargetSymbol(location: Identifier): Symbol? + fun getExportSymbolOfSymbol(symbol: Symbol): Symbol + fun getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol? + fun getTypeOfAssignmentPattern(pattern: ObjectLiteralExpression): Type + fun getTypeOfAssignmentPattern(pattern: ArrayLiteralExpression): Type + fun getTypeAtLocation(node: Node): Type + fun getTypeFromTypeNode(node: TypeNode): Type + fun signatureToString(signature: Signature, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally, kind: SignatureKind = definedExternally): String + fun typeToString(type: Type, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun symbolToString(symbol: Symbol, enclosingDeclaration: Node = definedExternally, meaning: SymbolFlags = definedExternally, flags: SymbolFormatFlags = definedExternally): String + fun typePredicateToString(predicate: ThisTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun typePredicateToString(predicate: ThisTypePredicate): String + fun typePredicateToString(predicate: ThisTypePredicate, enclosingDeclaration: Node = definedExternally): String + fun typePredicateToString(predicate: IdentifierTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun typePredicateToString(predicate: IdentifierTypePredicate): String + fun typePredicateToString(predicate: IdentifierTypePredicate, enclosingDeclaration: Node = definedExternally): String + fun typePredicateToString(predicate: AssertsThisTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun typePredicateToString(predicate: AssertsThisTypePredicate): String + fun typePredicateToString(predicate: AssertsThisTypePredicate, enclosingDeclaration: Node = definedExternally): String + fun typePredicateToString(predicate: AssertsIdentifierTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String + fun typePredicateToString(predicate: AssertsIdentifierTypePredicate): String + fun typePredicateToString(predicate: AssertsIdentifierTypePredicate, enclosingDeclaration: Node = definedExternally): String + fun getFullyQualifiedName(symbol: Symbol): String + fun getAugmentedPropertiesOfType(type: Type): Array + fun getRootSymbols(symbol: Symbol): Array + fun getSymbolOfExpando(node: Node, allowDeclaration: Boolean): Symbol? + fun getContextualType(node: Expression): Type? + fun getResolvedSignature(node: CallExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: CallExpression): Signature? + fun getResolvedSignature(node: CallExpression, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: NewExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: NewExpression): Signature? + fun getResolvedSignature(node: NewExpression, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: TaggedTemplateExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: TaggedTemplateExpression): Signature? + fun getResolvedSignature(node: TaggedTemplateExpression, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: Decorator, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: Decorator): Signature? + fun getResolvedSignature(node: Decorator, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: JsxSelfClosingElement, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: JsxSelfClosingElement): Signature? + fun getResolvedSignature(node: JsxSelfClosingElement, candidatesOutArray: Array = definedExternally): Signature? + fun getResolvedSignature(node: JsxOpeningElement, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? + fun getResolvedSignature(node: JsxOpeningElement): Signature? + fun getResolvedSignature(node: JsxOpeningElement, candidatesOutArray: Array = definedExternally): Signature? + fun getSignatureFromDeclaration(declaration: CallSignatureDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: ConstructSignatureDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: MethodSignature): Signature? + fun getSignatureFromDeclaration(declaration: IndexSignatureDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: FunctionTypeNode): Signature? + fun getSignatureFromDeclaration(declaration: ConstructorTypeNode): Signature? + fun getSignatureFromDeclaration(declaration: JSDocFunctionType): Signature? + fun getSignatureFromDeclaration(declaration: FunctionDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: MethodDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: ConstructorDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: GetAccessorDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: SetAccessorDeclaration): Signature? + fun getSignatureFromDeclaration(declaration: FunctionExpression): Signature? + fun getSignatureFromDeclaration(declaration: ArrowFunction): Signature? + fun isImplementationOfOverload(node: CallSignatureDeclaration): Boolean? + fun isImplementationOfOverload(node: ConstructSignatureDeclaration): Boolean? + fun isImplementationOfOverload(node: MethodSignature): Boolean? + fun isImplementationOfOverload(node: IndexSignatureDeclaration): Boolean? + fun isImplementationOfOverload(node: FunctionTypeNode): Boolean? + fun isImplementationOfOverload(node: ConstructorTypeNode): Boolean? + fun isImplementationOfOverload(node: JSDocFunctionType): Boolean? + fun isImplementationOfOverload(node: FunctionDeclaration): Boolean? + fun isImplementationOfOverload(node: MethodDeclaration): Boolean? + fun isImplementationOfOverload(node: ConstructorDeclaration): Boolean? + fun isImplementationOfOverload(node: GetAccessorDeclaration): Boolean? + fun isImplementationOfOverload(node: SetAccessorDeclaration): Boolean? + fun isImplementationOfOverload(node: FunctionExpression): Boolean? + fun isImplementationOfOverload(node: ArrowFunction): Boolean? + fun isUndefinedSymbol(symbol: Symbol): Boolean + fun isArgumentsSymbol(symbol: Symbol): Boolean + fun isUnknownSymbol(symbol: Symbol): Boolean + fun getConstantValue(node: EnumMember): dynamic /* String? | Number? */ + fun getConstantValue(node: PropertyAccessExpression): dynamic /* String? | Number? */ + fun getConstantValue(node: ElementAccessExpression): dynamic /* String? | Number? */ + fun isValidPropertyAccess(node: PropertyAccessExpression, propertyName: String): Boolean + fun isValidPropertyAccess(node: QualifiedName, propertyName: String): Boolean + fun isValidPropertyAccess(node: ImportTypeNode, propertyName: String): Boolean + fun getAliasedSymbol(symbol: Symbol): Symbol + fun getImmediateAliasedSymbol(symbol: Symbol): Symbol? + fun getExportsOfModule(moduleSymbol: Symbol): Array + fun getJsxIntrinsicTagNamesAt(location: Node): Array + fun isOptionalParameter(node: ParameterDeclaration): Boolean + fun getAmbientModules(): Array + fun tryGetMemberInModuleExports(memberName: String, moduleSymbol: Symbol): Symbol? + fun getApparentType(type: Type): Type + fun getBaseConstraintOfType(type: Type): Type? + fun getDefaultFromTypeParameter(type: Type): Type? + fun runWithCancellationToken(token: CancellationToken, cb: (checker: TypeChecker) -> T): T +} + +external enum class NodeBuilderFlags { + None /* = 0 */, + NoTruncation /* = 1 */, + WriteArrayAsGenericType /* = 2 */, + GenerateNamesForShadowedTypeParams /* = 4 */, + UseStructuralFallback /* = 8 */, + ForbidIndexedAccessSymbolReferences /* = 16 */, + WriteTypeArgumentsOfSignature /* = 32 */, + UseFullyQualifiedType /* = 64 */, + UseOnlyExternalAliasing /* = 128 */, + SuppressAnyReturnType /* = 256 */, + WriteTypeParametersInQualifiedName /* = 512 */, + MultilineObjectLiterals /* = 1024 */, + WriteClassExpressionAsTypeLiteral /* = 2048 */, + UseTypeOfFunction /* = 4096 */, + OmitParameterModifiers /* = 8192 */, + UseAliasDefinedOutsideCurrentScope /* = 16384 */, + UseSingleQuotesForStringLiteralType /* = 268435456 */, + NoTypeReduction /* = 536870912 */, + NoUndefinedOptionalParameterType /* = 1073741824 */, + AllowThisInObjectLiteral /* = 32768 */, + AllowQualifiedNameInPlaceOfIdentifier /* = 65536 */, + AllowQualifedNameInPlaceOfIdentifier /* = 65536 */, + AllowAnonymousIdentifier /* = 131072 */, + AllowEmptyUnionOrIntersection /* = 262144 */, + AllowEmptyTuple /* = 524288 */, + AllowUniqueESSymbolType /* = 1048576 */, + AllowEmptyIndexInfoType /* = 2097152 */, + AllowNodeModulesRelativePaths /* = 67108864 */, + IgnoreErrors /* = 70221824 */, + InObjectTypeLiteral /* = 4194304 */, + InTypeAlias /* = 8388608 */, + InInitialEntityName /* = 16777216 */ +} + +external enum class TypeFormatFlags { + None /* = 0 */, + NoTruncation /* = 1 */, + WriteArrayAsGenericType /* = 2 */, + UseStructuralFallback /* = 8 */, + WriteTypeArgumentsOfSignature /* = 32 */, + UseFullyQualifiedType /* = 64 */, + SuppressAnyReturnType /* = 256 */, + MultilineObjectLiterals /* = 1024 */, + WriteClassExpressionAsTypeLiteral /* = 2048 */, + UseTypeOfFunction /* = 4096 */, + OmitParameterModifiers /* = 8192 */, + UseAliasDefinedOutsideCurrentScope /* = 16384 */, + UseSingleQuotesForStringLiteralType /* = 268435456 */, + NoTypeReduction /* = 536870912 */, + AllowUniqueESSymbolType /* = 1048576 */, + AddUndefined /* = 131072 */, + WriteArrowStyleSignature /* = 262144 */, + InArrayType /* = 524288 */, + InElementType /* = 2097152 */, + InFirstTypeArgument /* = 4194304 */, + InTypeAlias /* = 8388608 */, + WriteOwnNameForAnyLike /* = 0 */, + NodeBuilderFlagsMask /* = 814775659 */ +} + +external enum class SymbolFormatFlags { + None /* = 0 */, + WriteTypeParametersOrArguments /* = 1 */, + UseOnlyExternalAliasing /* = 2 */, + AllowAnyNodeKind /* = 4 */, + UseAliasDefinedOutsideCurrentScope /* = 8 */ +} + +external enum class TypePredicateKind { + This /* = 0 */, + Identifier /* = 1 */, + AssertsThis /* = 2 */, + AssertsIdentifier /* = 3 */ +} + +external interface TypePredicateBase { + var kind: TypePredicateKind + var type: Type? +} + +external interface ThisTypePredicate : TypePredicateBase { + var parameterName: Any? + var parameterIndex: Any? +} + +external interface IdentifierTypePredicate : TypePredicateBase { + var parameterName: String + var parameterIndex: Number +} + +external interface AssertsThisTypePredicate : TypePredicateBase { + var parameterName: Any? + var parameterIndex: Any? + override var type: Type? +} + +external interface AssertsIdentifierTypePredicate : TypePredicateBase { + var parameterName: String + var parameterIndex: Number + override var type: Type? +} + +external enum class SymbolFlags { + None /* = 0 */, + FunctionScopedVariable /* = 1 */, + BlockScopedVariable /* = 2 */, + Property /* = 4 */, + EnumMember /* = 8 */, + Function /* = 16 */, + Class /* = 32 */, + Interface /* = 64 */, + ConstEnum /* = 128 */, + RegularEnum /* = 256 */, + ValueModule /* = 512 */, + NamespaceModule /* = 1024 */, + TypeLiteral /* = 2048 */, + ObjectLiteral /* = 4096 */, + Method /* = 8192 */, + Constructor /* = 16384 */, + GetAccessor /* = 32768 */, + SetAccessor /* = 65536 */, + Signature /* = 131072 */, + TypeParameter /* = 262144 */, + TypeAlias /* = 524288 */, + ExportValue /* = 1048576 */, + Alias /* = 2097152 */, + Prototype /* = 4194304 */, + ExportStar /* = 8388608 */, + Optional /* = 16777216 */, + Transient /* = 33554432 */, + Assignment /* = 67108864 */, + ModuleExports /* = 134217728 */, + Enum /* = 384 */, + Variable /* = 3 */, + Value /* = 111551 */, + Type /* = 788968 */, + Namespace /* = 1920 */, + Module /* = 1536 */, + Accessor /* = 98304 */, + FunctionScopedVariableExcludes /* = 111550 */, + BlockScopedVariableExcludes /* = 111551 */, + ParameterExcludes /* = 111551 */, + PropertyExcludes /* = 0 */, + EnumMemberExcludes /* = 900095 */, + FunctionExcludes /* = 110991 */, + ClassExcludes /* = 899503 */, + InterfaceExcludes /* = 788872 */, + RegularEnumExcludes /* = 899327 */, + ConstEnumExcludes /* = 899967 */, + ValueModuleExcludes /* = 110735 */, + NamespaceModuleExcludes /* = 0 */, + MethodExcludes /* = 103359 */, + GetAccessorExcludes /* = 46015 */, + SetAccessorExcludes /* = 78783 */, + TypeParameterExcludes /* = 526824 */, + TypeAliasExcludes /* = 788968 */, + AliasExcludes /* = 2097152 */, + ModuleMember /* = 2623475 */, + ExportHasLocal /* = 944 */, + BlockScoped /* = 418 */, + PropertyOrAccessor /* = 98308 */, + ClassMember /* = 106500 */ +} + +external interface Symbol { + var name: String + fun getFlags(): SymbolFlags + fun getEscapedName(): dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + fun getName(): String + fun getDeclarations(): Array? + fun getDocumentationComment(typeChecker: TypeChecker?): Array + fun getJsDocTags(checker: TypeChecker = definedExternally): Array + var flags: SymbolFlags + var escapedName: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + get() = definedExternally + set(value) = definedExternally + var declarations: Array? + get() = definedExternally + set(value) = definedExternally + var valueDeclaration: Declaration? + get() = definedExternally + set(value) = definedExternally + var members: SymbolTable? + get() = definedExternally + set(value) = definedExternally + var exports: SymbolTable? + get() = definedExternally + set(value) = definedExternally + var globalExports: SymbolTable? + get() = definedExternally + set(value) = definedExternally +} + +external enum class InternalSymbolName { + Call /* = "__call" */, + Constructor /* = "__constructor" */, + New /* = "__new" */, + Index /* = "__index" */, + ExportStar /* = "__export" */, + Global /* = "__global" */, + Missing /* = "__missing" */, + Type /* = "__type" */, + Object /* = "__object" */, + JSXAttributes /* = "__jsxAttributes" */, + Class /* = "__class" */, + Function /* = "__function" */, + Computed /* = "__computed" */, + Resolving /* = "__resolving__" */, + ExportEquals /* = "export=" */, + Default /* = "default" */, + This /* = "this" */ +} + +external interface ReadonlyUnderscoreEscapedMap : ReadonlyESMap + +external interface UnderscoreEscapedMap : ESMap, ReadonlyUnderscoreEscapedMap + +external enum class TypeFlags { + Any /* = 1 */, + Unknown /* = 2 */, + String /* = 4 */, + Number /* = 8 */, + Boolean /* = 16 */, + Enum /* = 32 */, + BigInt /* = 64 */, + StringLiteral /* = 128 */, + NumberLiteral /* = 256 */, + BooleanLiteral /* = 512 */, + EnumLiteral /* = 1024 */, + BigIntLiteral /* = 2048 */, + ESSymbol /* = 4096 */, + UniqueESSymbol /* = 8192 */, + Void /* = 16384 */, + Undefined /* = 32768 */, + Null /* = 65536 */, + Never /* = 131072 */, + TypeParameter /* = 262144 */, + Object /* = 524288 */, + Union /* = 1048576 */, + Intersection /* = 2097152 */, + Index /* = 4194304 */, + IndexedAccess /* = 8388608 */, + Conditional /* = 16777216 */, + Substitution /* = 33554432 */, + NonPrimitive /* = 67108864 */, + TemplateLiteral /* = 134217728 */, + StringMapping /* = 268435456 */, + Literal /* = 2944 */, + Unit /* = 109440 */, + StringOrNumberLiteral /* = 384 */, + PossiblyFalsy /* = 117724 */, + StringLike /* = 402653316 */, + NumberLike /* = 296 */, + BigIntLike /* = 2112 */, + BooleanLike /* = 528 */, + EnumLike /* = 1056 */, + ESSymbolLike /* = 12288 */, + VoidLike /* = 49152 */, + UnionOrIntersection /* = 3145728 */, + StructuredType /* = 3670016 */, + TypeVariable /* = 8650752 */, + InstantiableNonPrimitive /* = 58982400 */, + InstantiablePrimitive /* = 406847488 */, + Instantiable /* = 465829888 */, + StructuredOrInstantiable /* = 469499904 */, + Narrowable /* = 536624127 */ +} + +external interface Type { + fun getFlags(): TypeFlags + fun getSymbol(): Symbol? + fun getProperties(): Array + fun getProperty(propertyName: String): Symbol? + fun getApparentProperties(): Array + fun getCallSignatures(): Array + fun getConstructSignatures(): Array + fun getStringIndexType(): Type? + fun getNumberIndexType(): Type? + fun getBaseTypes(): Array? + fun getNonNullableType(): Type + fun getConstraint(): Type? + fun getDefault(): Type? + fun isUnion(): Boolean + fun isIntersection(): Boolean + fun isUnionOrIntersection(): Boolean + fun isLiteral(): Boolean + fun isStringLiteral(): Boolean + fun isNumberLiteral(): Boolean + fun isTypeParameter(): Boolean + fun isClassOrInterface(): Boolean + fun isClass(): Boolean + var flags: TypeFlags + var symbol: Symbol + var pattern: dynamic /* ObjectBindingPattern? | ArrayBindingPattern? | ObjectLiteralExpression? | ArrayLiteralExpression? */ + get() = definedExternally + set(value) = definedExternally + var aliasSymbol: Symbol? + get() = definedExternally + set(value) = definedExternally + var aliasTypeArguments: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface LiteralType : Type { + var value: dynamic /* String | Number | PseudoBigInt */ + get() = definedExternally + set(value) = definedExternally + var freshType: LiteralType + var regularType: LiteralType +} + +external interface UniqueESSymbolType : Type { + override var symbol: Symbol + var escapedName: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + get() = definedExternally + set(value) = definedExternally +} + +external interface StringLiteralType : LiteralType { + override var value: String +} + +external interface NumberLiteralType : LiteralType { + override var value: Number +} + +external interface BigIntLiteralType : LiteralType { + override var value: PseudoBigInt +} + +external interface EnumType : Type + +external enum class ObjectFlags { + Class /* = 1 */, + Interface /* = 2 */, + Reference /* = 4 */, + Tuple /* = 8 */, + Anonymous /* = 16 */, + Mapped /* = 32 */, + Instantiated /* = 64 */, + ObjectLiteral /* = 128 */, + EvolvingArray /* = 256 */, + ObjectLiteralPatternWithComputedProperties /* = 512 */, + ReverseMapped /* = 1024 */, + JsxAttributes /* = 2048 */, + MarkerType /* = 4096 */, + JSLiteral /* = 8192 */, + FreshLiteral /* = 16384 */, + ArrayLiteral /* = 32768 */, + ClassOrInterface /* = 3 */, + ContainsSpread /* = 4194304 */, + ObjectRestType /* = 8388608 */ +} + +external interface ObjectType : Type { + var objectFlags: ObjectFlags +} + +external interface InterfaceType : ObjectType { + var typeParameters: Array? + var outerTypeParameters: Array? + var localTypeParameters: Array? + var thisType: TypeParameter? +} + +external interface InterfaceTypeWithDeclaredMembers : InterfaceType { + var declaredProperties: Array + var declaredCallSignatures: Array + var declaredConstructSignatures: Array + var declaredIndexInfos: Array +} + +external interface TypeReference : ObjectType { + var typeArguments: Array? + get() = definedExternally + set(value) = definedExternally + var target: GenericType + var node: dynamic /* TypeReferenceNode? | ArrayTypeNode? | TupleTypeNode? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface DeferredTypeReference : TypeReference + +external interface GenericType : InterfaceType, TypeReference + +external enum class ElementFlags { + Required /* = 1 */, + Optional /* = 2 */, + Rest /* = 4 */, + Variadic /* = 8 */, + Fixed /* = 3 */, + Variable /* = 12 */, + NonRequired /* = 14 */, + NonRest /* = 11 */ +} + +external interface TupleType : GenericType { + var elementFlags: Array + var minLength: Number + var fixedLength: Number + var hasRestElement: Boolean + var combinedFlags: ElementFlags + var readonly: Boolean + var labeledElementDeclarations: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface TupleTypeReference : TypeReference { + override var target: TupleType +} + +external interface UnionOrIntersectionType : Type { + var types: Array +} + +external interface UnionType : UnionOrIntersectionType + +external interface IntersectionType : UnionOrIntersectionType + +external interface EvolvingArrayType : ObjectType { + var elementType: Type + var finalArrayType: Type? + get() = definedExternally + set(value) = definedExternally +} + +external interface InstantiableType : Type + +external interface TypeParameter : InstantiableType + +external interface IndexedAccessType : InstantiableType { + var objectType: Type + var indexType: Type + var constraint: Type? + get() = definedExternally + set(value) = definedExternally + var simplifiedForReading: Type? + get() = definedExternally + set(value) = definedExternally + var simplifiedForWriting: Type? + get() = definedExternally + set(value) = definedExternally +} + +external interface IndexType : InstantiableType { + var type: dynamic /* InstantiableType | UnionOrIntersectionType */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ConditionalRoot { + var node: ConditionalTypeNode + var checkType: Type + var extendsType: Type + var isDistributive: Boolean + var inferTypeParameters: Array? + get() = definedExternally + set(value) = definedExternally + var outerTypeParameters: Array? + get() = definedExternally + set(value) = definedExternally + var instantiations: Map? + get() = definedExternally + set(value) = definedExternally + var aliasSymbol: Symbol? + get() = definedExternally + set(value) = definedExternally + var aliasTypeArguments: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface ConditionalType : InstantiableType { + var root: ConditionalRoot + var checkType: Type + var extendsType: Type + var resolvedTrueType: Type + var resolvedFalseType: Type +} + +external interface TemplateLiteralType : InstantiableType { + var texts: Array + var types: Array +} + +external interface StringMappingType : InstantiableType { + override var symbol: Symbol + var type: Type +} + +external interface SubstitutionType : InstantiableType { + var objectFlags: ObjectFlags + var baseType: Type + var substitute: Type +} + +external enum class SignatureKind { + Call /* = 0 */, + Construct /* = 1 */ +} + +external interface Signature { + fun getDeclaration(): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ + fun getTypeParameters(): Array? + fun getParameters(): Array + fun getReturnType(): Type + fun getDocumentationComment(typeChecker: TypeChecker?): Array + fun getJsDocTags(): Array + var declaration: dynamic /* CallSignatureDeclaration? | ConstructSignatureDeclaration? | MethodSignature? | IndexSignatureDeclaration? | FunctionTypeNode? | ConstructorTypeNode? | JSDocFunctionType? | FunctionDeclaration? | MethodDeclaration? | ConstructorDeclaration? | GetAccessorDeclaration? | SetAccessorDeclaration? | FunctionExpression? | ArrowFunction? | JSDocSignature? */ + get() = definedExternally + set(value) = definedExternally + var typeParameters: Array? + get() = definedExternally + set(value) = definedExternally + var parameters: Array +} + +external enum class IndexKind { + String /* = 0 */, + Number /* = 1 */ +} + +external interface IndexInfo { + var keyType: Type + var type: Type + var isReadonly: Boolean + var declaration: IndexSignatureDeclaration? + get() = definedExternally + set(value) = definedExternally +} + +external enum class InferencePriority { + NakedTypeVariable /* = 1 */, + SpeculativeTuple /* = 2 */, + SubstituteSource /* = 4 */, + HomomorphicMappedType /* = 8 */, + PartialHomomorphicMappedType /* = 16 */, + MappedTypeConstraint /* = 32 */, + ContravariantConditional /* = 64 */, + ReturnType /* = 128 */, + LiteralKeyof /* = 256 */, + NoConstraints /* = 512 */, + AlwaysStrict /* = 1024 */, + MaxValue /* = 2048 */, + PriorityImpliesCombination /* = 416 */, + Circularity /* = -1 */ +} + +external interface FileExtensionInfo { + var extension: String + var isMixedContent: Boolean + var scriptKind: ScriptKind? + get() = definedExternally + set(value) = definedExternally +} + +external interface DiagnosticMessage { + var key: String + var category: DiagnosticCategory + var code: Number + var message: String + var reportsUnnecessary: Any? + get() = definedExternally + set(value) = definedExternally + var reportsDeprecated: Any? + get() = definedExternally + set(value) = definedExternally +} + +external interface DiagnosticMessageChain { + var messageText: String + var category: DiagnosticCategory + var code: Number + var next: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface Diagnostic : DiagnosticRelatedInformation { + var reportsUnnecessary: Any? + get() = definedExternally + set(value) = definedExternally + var reportsDeprecated: Any? + get() = definedExternally + set(value) = definedExternally + var source: String? + get() = definedExternally + set(value) = definedExternally + var relatedInformation: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface DiagnosticRelatedInformation { + var category: DiagnosticCategory + var code: Number + var file: SourceFile? + var start: Number? + var length: Number? + var messageText: dynamic /* String | DiagnosticMessageChain */ + get() = definedExternally + set(value) = definedExternally +} + +external interface DiagnosticWithLocation : Diagnostic + +external enum class DiagnosticCategory { + Warning /* = 0 */, + Error /* = 1 */, + Suggestion /* = 2 */, + Message /* = 3 */ +} + +external enum class ModuleResolutionKind { + Classic /* = 1 */, + NodeJs /* = 2 */ +} + +external interface PluginImport { + var name: String +} + +external interface ProjectReference { + var path: String + var originalPath: String? + get() = definedExternally + set(value) = definedExternally + var prepend: Boolean? + get() = definedExternally + set(value) = definedExternally + var circular: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external enum class WatchFileKind { + FixedPollingInterval /* = 0 */, + PriorityPollingInterval /* = 1 */, + DynamicPriorityPolling /* = 2 */, + FixedChunkSizePolling /* = 3 */, + UseFsEvents /* = 4 */, + UseFsEventsOnParentDirectory /* = 5 */ +} + +external enum class WatchDirectoryKind { + UseFsEvents /* = 0 */, + FixedPollingInterval /* = 1 */, + DynamicPriorityPolling /* = 2 */, + FixedChunkSizePolling /* = 3 */ +} + +external enum class PollingWatchKind { + FixedInterval /* = 0 */, + PriorityInterval /* = 1 */, + DynamicPriority /* = 2 */, + FixedChunkSize /* = 3 */ +} + +external interface CompilerOptions { + var allowJs: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowSyntheticDefaultImports: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowUmdGlobalAccess: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowUnreachableCode: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowUnusedLabels: Boolean? + get() = definedExternally + set(value) = definedExternally + var alwaysStrict: Boolean? + get() = definedExternally + set(value) = definedExternally + var baseUrl: String? + get() = definedExternally + set(value) = definedExternally + var charset: String? + get() = definedExternally + set(value) = definedExternally + var checkJs: Boolean? + get() = definedExternally + set(value) = definedExternally + var declaration: Boolean? + get() = definedExternally + set(value) = definedExternally + var declarationMap: Boolean? + get() = definedExternally + set(value) = definedExternally + var emitDeclarationOnly: Boolean? + get() = definedExternally + set(value) = definedExternally + var declarationDir: String? + get() = definedExternally + set(value) = definedExternally + var disableSizeLimit: Boolean? + get() = definedExternally + set(value) = definedExternally + var disableSourceOfProjectReferenceRedirect: Boolean? + get() = definedExternally + set(value) = definedExternally + var disableSolutionSearching: Boolean? + get() = definedExternally + set(value) = definedExternally + var disableReferencedProjectLoad: Boolean? + get() = definedExternally + set(value) = definedExternally + var downlevelIteration: Boolean? + get() = definedExternally + set(value) = definedExternally + var emitBOM: Boolean? + get() = definedExternally + set(value) = definedExternally + var emitDecoratorMetadata: Boolean? + get() = definedExternally + set(value) = definedExternally + var exactOptionalPropertyTypes: Boolean? + get() = definedExternally + set(value) = definedExternally + var experimentalDecorators: Boolean? + get() = definedExternally + set(value) = definedExternally + var forceConsistentCasingInFileNames: Boolean? + get() = definedExternally + set(value) = definedExternally + var importHelpers: Boolean? + get() = definedExternally + set(value) = definedExternally + var importsNotUsedAsValues: ImportsNotUsedAsValues? + get() = definedExternally + set(value) = definedExternally + var inlineSourceMap: Boolean? + get() = definedExternally + set(value) = definedExternally + var inlineSources: Boolean? + get() = definedExternally + set(value) = definedExternally + var isolatedModules: Boolean? + get() = definedExternally + set(value) = definedExternally + var jsx: JsxEmit? + get() = definedExternally + set(value) = definedExternally + var keyofStringsOnly: Boolean? + get() = definedExternally + set(value) = definedExternally + var lib: Array? + get() = definedExternally + set(value) = definedExternally + var locale: String? + get() = definedExternally + set(value) = definedExternally + var mapRoot: String? + get() = definedExternally + set(value) = definedExternally + var maxNodeModuleJsDepth: Number? + get() = definedExternally + set(value) = definedExternally + var module: ModuleKind? + get() = definedExternally + set(value) = definedExternally + var moduleResolution: ModuleResolutionKind? + get() = definedExternally + set(value) = definedExternally + var newLine: NewLineKind? + get() = definedExternally + set(value) = definedExternally + var noEmit: Boolean? + get() = definedExternally + set(value) = definedExternally + var noEmitHelpers: Boolean? + get() = definedExternally + set(value) = definedExternally + var noEmitOnError: Boolean? + get() = definedExternally + set(value) = definedExternally + var noErrorTruncation: Boolean? + get() = definedExternally + set(value) = definedExternally + var noFallthroughCasesInSwitch: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitAny: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitReturns: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitThis: Boolean? + get() = definedExternally + set(value) = definedExternally + var noStrictGenericChecks: Boolean? + get() = definedExternally + set(value) = definedExternally + var noUnusedLocals: Boolean? + get() = definedExternally + set(value) = definedExternally + var noUnusedParameters: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitUseStrict: Boolean? + get() = definedExternally + set(value) = definedExternally + var noPropertyAccessFromIndexSignature: Boolean? + get() = definedExternally + set(value) = definedExternally + var assumeChangesOnlyAffectDirectDependencies: Boolean? + get() = definedExternally + set(value) = definedExternally + var noLib: Boolean? + get() = definedExternally + set(value) = definedExternally + var noResolve: Boolean? + get() = definedExternally + set(value) = definedExternally + var noUncheckedIndexedAccess: Boolean? + get() = definedExternally + set(value) = definedExternally + var out: String? + get() = definedExternally + set(value) = definedExternally + var outDir: String? + get() = definedExternally + set(value) = definedExternally + var outFile: String? + get() = definedExternally + set(value) = definedExternally + var paths: MapLike>? + get() = definedExternally + set(value) = definedExternally + var preserveConstEnums: Boolean? + get() = definedExternally + set(value) = definedExternally + var noImplicitOverride: Boolean? + get() = definedExternally + set(value) = definedExternally + var preserveSymlinks: Boolean? + get() = definedExternally + set(value) = definedExternally + var project: String? + get() = definedExternally + set(value) = definedExternally + var reactNamespace: String? + get() = definedExternally + set(value) = definedExternally + var jsxFactory: String? + get() = definedExternally + set(value) = definedExternally + var jsxFragmentFactory: String? + get() = definedExternally + set(value) = definedExternally + var jsxImportSource: String? + get() = definedExternally + set(value) = definedExternally + var composite: Boolean? + get() = definedExternally + set(value) = definedExternally + var incremental: Boolean? + get() = definedExternally + set(value) = definedExternally + var tsBuildInfoFile: String? + get() = definedExternally + set(value) = definedExternally + var removeComments: Boolean? + get() = definedExternally + set(value) = definedExternally + var rootDir: String? + get() = definedExternally + set(value) = definedExternally + var rootDirs: Array? + get() = definedExternally + set(value) = definedExternally + var skipLibCheck: Boolean? + get() = definedExternally + set(value) = definedExternally + var skipDefaultLibCheck: Boolean? + get() = definedExternally + set(value) = definedExternally + var sourceMap: Boolean? + get() = definedExternally + set(value) = definedExternally + var sourceRoot: String? + get() = definedExternally + set(value) = definedExternally + var strict: Boolean? + get() = definedExternally + set(value) = definedExternally + var strictFunctionTypes: Boolean? + get() = definedExternally + set(value) = definedExternally + var strictBindCallApply: Boolean? + get() = definedExternally + set(value) = definedExternally + var strictNullChecks: Boolean? + get() = definedExternally + set(value) = definedExternally + var strictPropertyInitialization: Boolean? + get() = definedExternally + set(value) = definedExternally + var stripInternal: Boolean? + get() = definedExternally + set(value) = definedExternally + var suppressExcessPropertyErrors: Boolean? + get() = definedExternally + set(value) = definedExternally + var suppressImplicitAnyIndexErrors: Boolean? + get() = definedExternally + set(value) = definedExternally + var target: ScriptTarget? + get() = definedExternally + set(value) = definedExternally + var traceResolution: Boolean? + get() = definedExternally + set(value) = definedExternally + var useUnknownInCatchVariables: Boolean? + get() = definedExternally + set(value) = definedExternally + var resolveJsonModule: Boolean? + get() = definedExternally + set(value) = definedExternally + var types: Array? + get() = definedExternally + set(value) = definedExternally + var typeRoots: Array? + get() = definedExternally + set(value) = definedExternally + var esModuleInterop: Boolean? + get() = definedExternally + set(value) = definedExternally + var useDefineForClassFields: Boolean? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? | TsConfigSourceFile? */ + @nativeSetter + operator fun set(option: String, value: String?) + @nativeSetter + operator fun set(option: String, value: Number?) + @nativeSetter + operator fun set(option: String, value: Boolean?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: MapLike>?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: TsConfigSourceFile?) +} + +external interface WatchOptions { + var watchFile: WatchFileKind? + get() = definedExternally + set(value) = definedExternally + var watchDirectory: WatchDirectoryKind? + get() = definedExternally + set(value) = definedExternally + var fallbackPolling: PollingWatchKind? + get() = definedExternally + set(value) = definedExternally + var synchronousWatchDirectory: Boolean? + get() = definedExternally + set(value) = definedExternally + var excludeDirectories: Array? + get() = definedExternally + set(value) = definedExternally + var excludeFiles: Array? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ + @nativeSetter + operator fun set(option: String, value: String?) + @nativeSetter + operator fun set(option: String, value: Number?) + @nativeSetter + operator fun set(option: String, value: Boolean?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: MapLike>?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) +} + +external interface TypeAcquisition { + var enableAutoDiscovery: Boolean? + get() = definedExternally + set(value) = definedExternally + var enable: Boolean? + get() = definedExternally + set(value) = definedExternally + var include: Array? + get() = definedExternally + set(value) = definedExternally + var exclude: Array? + get() = definedExternally + set(value) = definedExternally + var disableFilenameBasedTypeAcquisition: Boolean? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ + @nativeSetter + operator fun set(option: String, value: String?) + @nativeSetter + operator fun set(option: String, value: Number?) + @nativeSetter + operator fun set(option: String, value: Boolean?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: MapLike>?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) +} + +external enum class ModuleKind { + None /* = 0 */, + CommonJS /* = 1 */, + AMD /* = 2 */, + UMD /* = 3 */, + System /* = 4 */, + ES2015 /* = 5 */, + ES2020 /* = 6 */, + ESNext /* = 99 */ +} + +external enum class JsxEmit { + None /* = 0 */, + Preserve /* = 1 */, + React /* = 2 */, + ReactNative /* = 3 */, + ReactJSX /* = 4 */, + ReactJSXDev /* = 5 */ +} + +external enum class ImportsNotUsedAsValues { + Remove /* = 0 */, + Preserve /* = 1 */, + Error /* = 2 */ +} + +external enum class NewLineKind { + CarriageReturnLineFeed /* = 0 */, + LineFeed /* = 1 */ +} + +external interface LineAndCharacter { + var line: Number + var character: Number +} + +external enum class ScriptKind { + Unknown /* = 0 */, + JS /* = 1 */, + JSX /* = 2 */, + TS /* = 3 */, + TSX /* = 4 */, + External /* = 5 */, + JSON /* = 6 */, + Deferred /* = 7 */ +} + +external enum class ScriptTarget { + ES3 /* = 0 */, + ES5 /* = 1 */, + ES2015 /* = 2 */, + ES2016 /* = 3 */, + ES2017 /* = 4 */, + ES2018 /* = 5 */, + ES2019 /* = 6 */, + ES2020 /* = 7 */, + ES2021 /* = 8 */, + ESNext /* = 99 */, + JSON /* = 100 */, + Latest /* = 99 */ +} + +external enum class LanguageVariant { + Standard /* = 0 */, + JSX /* = 1 */ +} + +external interface ParsedCommandLine { + var options: CompilerOptions + var typeAcquisition: TypeAcquisition? + get() = definedExternally + set(value) = definedExternally + var fileNames: Array + var projectReferences: Array? + get() = definedExternally + set(value) = definedExternally + var watchOptions: WatchOptions? + get() = definedExternally + set(value) = definedExternally + var raw: Any? + get() = definedExternally + set(value) = definedExternally + var errors: Array + var wildcardDirectories: MapLike? + get() = definedExternally + set(value) = definedExternally + var compileOnSave: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external enum class WatchDirectoryFlags { + None /* = 0 */, + Recursive /* = 1 */ +} + +external interface CreateProgramOptions { + var rootNames: Array + var options: CompilerOptions + var projectReferences: Array? + get() = definedExternally + set(value) = definedExternally + var host: CompilerHost? + get() = definedExternally + set(value) = definedExternally + var oldProgram: Program? + get() = definedExternally + set(value) = definedExternally + var configFileParsingDiagnostics: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface ModuleResolutionHost { + fun fileExists(fileName: String): Boolean + fun readFile(fileName: String): String? + val trace: ((s: String) -> Unit)? + val directoryExists: ((directoryName: String) -> Boolean)? + val realpath: ((path: String) -> String)? + val getCurrentDirectory: (() -> String)? + val getDirectories: ((path: String) -> Array)? +} + +external interface ResolvedModule { + var resolvedFileName: String + var isExternalLibraryImport: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedModuleFull : ResolvedModule { + var extension: Extension + var packageId: PackageId? + get() = definedExternally + set(value) = definedExternally +} + +external interface PackageId { + var name: String + var subModuleName: String + var version: String +} + +external enum class Extension { + Ts /* = ".ts" */, + Tsx /* = ".tsx" */, + Dts /* = ".d.ts" */, + Js /* = ".js" */, + Jsx /* = ".jsx" */, + Json /* = ".json" */, + TsBuildInfo /* = ".tsbuildinfo" */ +} + +external interface ResolvedModuleWithFailedLookupLocations { + var resolvedModule: ResolvedModuleFull? +} + +external interface ResolvedTypeReferenceDirective { + var primary: Boolean + var resolvedFileName: String? + var packageId: PackageId? + get() = definedExternally + set(value) = definedExternally + var isExternalLibraryImport: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations { + var resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective? + var failedLookupLocations: Array +} + +external interface CompilerHost : ModuleResolutionHost { + fun getSourceFile(fileName: String, languageVersion: ScriptTarget, onError: (message: String) -> Unit = definedExternally, shouldCreateNewSourceFile: Boolean = definedExternally): SourceFile? + val getSourceFileByPath: ((fileName: String, path: String /* String & `T$3` */, languageVersion: ScriptTarget, onError: (message: String) -> Unit, shouldCreateNewSourceFile: Boolean) -> SourceFile?)? + val getCancellationToken: (() -> CancellationToken)? + fun getDefaultLibFileName(options: CompilerOptions): String + val getDefaultLibLocation: (() -> String)? + var writeFile: WriteFileCallback + override var getCurrentDirectory: () -> String + fun getCanonicalFileName(fileName: String): String + fun useCaseSensitiveFileNames(): Boolean + fun getNewLine(): String + val readDirectory: ((rootDir: String, extensions: Array, excludes: Array?, includes: Array, depth: Number) -> Array)? + val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val getEnvironmentVariable: ((name: String) -> String?)? + val createHash: ((data: String) -> String)? + val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? +} + +external interface SourceMapRange : TextRange { + var source: SourceMapSource? + get() = definedExternally + set(value) = definedExternally +} + +external interface SourceMapSource { + fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter + var fileName: String + var text: String + var skipTrivia: ((pos: Number) -> Number)? + get() = definedExternally + set(value) = definedExternally +} + +external enum class EmitFlags { + None /* = 0 */, + SingleLine /* = 1 */, + AdviseOnEmitNode /* = 2 */, + NoSubstitution /* = 4 */, + CapturesThis /* = 8 */, + NoLeadingSourceMap /* = 16 */, + NoTrailingSourceMap /* = 32 */, + NoSourceMap /* = 48 */, + NoNestedSourceMaps /* = 64 */, + NoTokenLeadingSourceMaps /* = 128 */, + NoTokenTrailingSourceMaps /* = 256 */, + NoTokenSourceMaps /* = 384 */, + NoLeadingComments /* = 512 */, + NoTrailingComments /* = 1024 */, + NoComments /* = 1536 */, + NoNestedComments /* = 2048 */, + HelperName /* = 4096 */, + ExportName /* = 8192 */, + LocalName /* = 16384 */, + InternalName /* = 32768 */, + Indented /* = 65536 */, + NoIndentation /* = 131072 */, + AsyncFunctionBody /* = 262144 */, + ReuseTempVariableScope /* = 524288 */, + CustomPrologue /* = 1048576 */, + NoHoisting /* = 2097152 */, + HasEndOfDeclarationMarker /* = 4194304 */, + Iterator /* = 8388608 */, + NoAsciiEscaping /* = 16777216 */ +} + +external interface EmitHelperBase { + var name: String + var scoped: Boolean + var text: dynamic /* String | (node: EmitHelperUniqueNameCallback) -> String */ + get() = definedExternally + set(value) = definedExternally + var priority: Number? + get() = definedExternally + set(value) = definedExternally + var dependencies: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface ScopedEmitHelper : EmitHelperBase { + override var scoped: Boolean +} + +external interface UnscopedEmitHelper : EmitHelperBase { + override var scoped: Boolean + override var text: String +} + +external enum class EmitHint { + SourceFile /* = 0 */, + Expression /* = 1 */, + IdentifierName /* = 2 */, + MappedTypeParameter /* = 3 */, + Unspecified /* = 4 */, + EmbeddedStatement /* = 5 */, + JsxAttributeValue /* = 6 */ +} + +external enum class OuterExpressionKinds { + Parentheses /* = 1 */, + TypeAssertions /* = 2 */, + NonNullAssertions /* = 4 */, + PartiallyEmittedExpressions /* = 8 */, + Assertions /* = 6 */, + All /* = 15 */ +} + +external interface NodeFactory { + fun createNodeArray(elements: Array = definedExternally, hasTrailingComma: Boolean = definedExternally): NodeArray + fun createNumericLiteral(value: String, numericLiteralFlags: TokenFlags = definedExternally): NumericLiteral + fun createNumericLiteral(value: String): NumericLiteral + fun createNumericLiteral(value: Number, numericLiteralFlags: TokenFlags = definedExternally): NumericLiteral + fun createNumericLiteral(value: Number): NumericLiteral + fun createBigIntLiteral(value: String): BigIntLiteral + fun createBigIntLiteral(value: PseudoBigInt): BigIntLiteral + fun createStringLiteral(text: String, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: Identifier, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: Identifier): StringLiteral + fun createStringLiteralFromNode(sourceNode: StringLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: StringLiteral): StringLiteral + fun createStringLiteralFromNode(sourceNode: NoSubstitutionTemplateLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: NoSubstitutionTemplateLiteral): StringLiteral + fun createStringLiteralFromNode(sourceNode: NumericLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral + fun createStringLiteralFromNode(sourceNode: NumericLiteral): StringLiteral + fun createRegularExpressionLiteral(text: String): RegularExpressionLiteral + fun createIdentifier(text: String): Identifier + fun createTempVariable(recordTempVariable: ((node: Identifier) -> Unit)?, reservedInNestedScopes: Boolean = definedExternally): Identifier + fun createLoopVariable(reservedInNestedScopes: Boolean = definedExternally): Identifier + fun createUniqueName(text: String, flags: GeneratedIdentifierFlags = definedExternally): Identifier + fun getGeneratedNameForNode(node: Node?, flags: GeneratedIdentifierFlags = definedExternally): Identifier + fun createPrivateIdentifier(text: String): PrivateIdentifier + fun createToken(token: SyntaxKind.SuperKeyword): SuperExpression + fun createToken(token: SyntaxKind.ThisKeyword): ThisExpression + fun createToken(token: SyntaxKind.NullKeyword): NullLiteral + fun createToken(token: SyntaxKind.TrueKeyword): TrueLiteral + fun createToken(token: SyntaxKind.FalseKeyword): FalseLiteral + fun createToken(token: TKind): dynamic /* Token */ + fun createSuper(): SuperExpression + fun createThis(): ThisExpression + fun createNull(): NullLiteral + fun createTrue(): TrueLiteral + fun createFalse(): FalseLiteral + fun createModifier(kind: T): ModifierToken + fun createModifiersFromModifierFlags(flags: ModifierFlags): Array + fun createQualifiedName(left: Identifier, right: String): QualifiedName + fun createQualifiedName(left: Identifier, right: Identifier): QualifiedName + fun createQualifiedName(left: QualifiedName, right: String): QualifiedName + fun createQualifiedName(left: QualifiedName, right: Identifier): QualifiedName + fun updateQualifiedName(node: QualifiedName, left: Identifier, right: Identifier): QualifiedName + fun updateQualifiedName(node: QualifiedName, left: QualifiedName, right: Identifier): QualifiedName + fun createComputedPropertyName(expression: Expression): ComputedPropertyName + fun updateComputedPropertyName(node: ComputedPropertyName, expression: Expression): ComputedPropertyName + fun createTypeParameterDeclaration(name: String, constraint: TypeNode = definedExternally, defaultType: TypeNode = definedExternally): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: String): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: String, constraint: TypeNode = definedExternally): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: Identifier, constraint: TypeNode = definedExternally, defaultType: TypeNode = definedExternally): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: Identifier): TypeParameterDeclaration + fun createTypeParameterDeclaration(name: Identifier, constraint: TypeNode = definedExternally): TypeParameterDeclaration + fun updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode?, defaultType: TypeNode?): TypeParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally): ParameterDeclaration + fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration + fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration + fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration + fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration + fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration + fun createDecorator(expression: Expression): Decorator + fun updateDecorator(node: Decorator, expression: Expression): Decorator + fun createPropertySignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertySignature(modifiers: Array?, name: String, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration + fun createMethodSignature(modifiers: Array?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun createMethodSignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration + fun createConstructorDeclaration(decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration + fun updateConstructorDeclaration(node: ConstructorDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration + fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration + fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration + fun createCallSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): CallSignatureDeclaration + fun updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): CallSignatureDeclaration + fun createConstructSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): ConstructSignatureDeclaration + fun updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): ConstructSignatureDeclaration + fun createIndexSignature(decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration + fun updateIndexSignature(node: IndexSignatureDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration + fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan + fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan + fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan + fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan + fun createClassStaticBlockDeclaration(decorators: Array?, modifiers: Array?, body: Block): ClassStaticBlockDeclaration + fun updateClassStaticBlockDeclaration(node: ClassStaticBlockDeclaration, decorators: Array?, modifiers: Array?, body: Block): ClassStaticBlockDeclaration + fun createKeywordTypeNode(kind: TKind): KeywordTypeNode + fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode + fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode + fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: String, type: TypeNode?): TypePredicateNode + fun updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode + fun updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode + fun createTypeReferenceNode(typeName: String, typeArguments: Array = definedExternally): TypeReferenceNode + fun createTypeReferenceNode(typeName: String): TypeReferenceNode + fun createTypeReferenceNode(typeName: Identifier, typeArguments: Array = definedExternally): TypeReferenceNode + fun createTypeReferenceNode(typeName: Identifier): TypeReferenceNode + fun createTypeReferenceNode(typeName: QualifiedName, typeArguments: Array = definedExternally): TypeReferenceNode + fun createTypeReferenceNode(typeName: QualifiedName): TypeReferenceNode + fun updateTypeReferenceNode(node: TypeReferenceNode, typeName: Identifier, typeArguments: NodeArray?): TypeReferenceNode + fun updateTypeReferenceNode(node: TypeReferenceNode, typeName: QualifiedName, typeArguments: NodeArray?): TypeReferenceNode + fun createFunctionTypeNode(typeParameters: Array?, parameters: Array, type: TypeNode): FunctionTypeNode + fun updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): FunctionTypeNode + fun createConstructorTypeNode(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode): ConstructorTypeNode + fun createConstructorTypeNode(typeParameters: Array?, parameters: Array, type: TypeNode): ConstructorTypeNode + fun updateConstructorTypeNode(node: ConstructorTypeNode, modifiers: Array?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): ConstructorTypeNode + fun updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): ConstructorTypeNode + fun createTypeQueryNode(exprName: Identifier): TypeQueryNode + fun createTypeQueryNode(exprName: QualifiedName): TypeQueryNode + fun updateTypeQueryNode(node: TypeQueryNode, exprName: Identifier): TypeQueryNode + fun updateTypeQueryNode(node: TypeQueryNode, exprName: QualifiedName): TypeQueryNode + fun createTypeLiteralNode(members: Array?): TypeLiteralNode + fun updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray): TypeLiteralNode + fun createArrayTypeNode(elementType: TypeNode): ArrayTypeNode + fun updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode + fun createTupleTypeNode(elements: Array): TupleTypeNode + fun updateTupleTypeNode(node: TupleTypeNode, elements: Array): TupleTypeNode + fun createNamedTupleMember(dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode): NamedTupleMember + fun updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode): NamedTupleMember + fun createOptionalTypeNode(type: TypeNode): OptionalTypeNode + fun updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode + fun createRestTypeNode(type: TypeNode): RestTypeNode + fun updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode + fun createUnionTypeNode(types: Array): UnionTypeNode + fun updateUnionTypeNode(node: UnionTypeNode, types: NodeArray): UnionTypeNode + fun createIntersectionTypeNode(types: Array): IntersectionTypeNode + fun updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray): IntersectionTypeNode + fun createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode + fun updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode + fun createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode + fun updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally, typeArguments: Array = definedExternally, isTypeOf: Boolean = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally, typeArguments: Array = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally, typeArguments: Array = definedExternally, isTypeOf: Boolean = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally): ImportTypeNode + fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally, typeArguments: Array = definedExternally): ImportTypeNode + fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: Identifier?, typeArguments: Array?, isTypeOf: Boolean = definedExternally): ImportTypeNode + fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: Identifier?, typeArguments: Array?): ImportTypeNode + fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: QualifiedName?, typeArguments: Array?, isTypeOf: Boolean = definedExternally): ImportTypeNode + fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: QualifiedName?, typeArguments: Array?): ImportTypeNode + fun createParenthesizedType(type: TypeNode): ParenthesizedTypeNode + fun updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode + fun createThisTypeNode(): ThisTypeNode + fun createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword, type: TypeNode): TypeOperatorNode + fun createTypeOperatorNode(operator: SyntaxKind.UniqueKeyword, type: TypeNode): TypeOperatorNode + fun createTypeOperatorNode(operator: SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode + fun updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode + fun createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode + fun updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode + fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode + fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode + fun createLiteralTypeNode(literal: NullLiteral): LiteralTypeNode + fun createLiteralTypeNode(literal: TrueLiteral): LiteralTypeNode + fun createLiteralTypeNode(literal: FalseLiteral): LiteralTypeNode + fun createLiteralTypeNode(literal: LiteralExpression): LiteralTypeNode + fun createLiteralTypeNode(literal: PrefixUnaryExpression): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: NullLiteral): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: TrueLiteral): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: FalseLiteral): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralExpression): LiteralTypeNode + fun updateLiteralTypeNode(node: LiteralTypeNode, literal: PrefixUnaryExpression): LiteralTypeNode + fun createTemplateLiteralType(head: TemplateHead, templateSpans: Array): TemplateLiteralTypeNode + fun updateTemplateLiteralType(node: TemplateLiteralTypeNode, head: TemplateHead, templateSpans: Array): TemplateLiteralTypeNode + fun createObjectBindingPattern(elements: Array): ObjectBindingPattern + fun updateObjectBindingPattern(node: ObjectBindingPattern, elements: Array): ObjectBindingPattern + fun createArrayBindingPattern(elements: Array): ArrayBindingPattern + fun updateArrayBindingPattern(node: ArrayBindingPattern, elements: Array): ArrayBindingPattern + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: String?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: String?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement + fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Identifier, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: ObjectBindingPattern, initializer: Expression?): BindingElement + fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: ArrayBindingPattern, initializer: Expression?): BindingElement + fun createArrayLiteralExpression(elements: Array = definedExternally, multiLine: Boolean = definedExternally): ArrayLiteralExpression + fun updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: Array): ArrayLiteralExpression + fun createObjectLiteralExpression(properties: Array = definedExternally, multiLine: Boolean = definedExternally): ObjectLiteralExpression + fun updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: Array): ObjectLiteralExpression + fun createPropertyAccessExpression(expression: Expression, name: String): PropertyAccessExpression + fun createPropertyAccessExpression(expression: Expression, name: Identifier): PropertyAccessExpression + fun createPropertyAccessExpression(expression: Expression, name: PrivateIdentifier): PropertyAccessExpression + fun updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier): PropertyAccessExpression + fun updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: PrivateIdentifier): PropertyAccessExpression + fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: String): PropertyAccessChain + fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: Identifier): PropertyAccessChain + fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: PrivateIdentifier): PropertyAccessChain + fun updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: Identifier): PropertyAccessChain + fun updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: PrivateIdentifier): PropertyAccessChain + fun createElementAccessExpression(expression: Expression, index: Number): ElementAccessExpression + fun createElementAccessExpression(expression: Expression, index: Expression): ElementAccessExpression + fun updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression + fun createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, index: Number): ElementAccessChain + fun createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, index: Expression): ElementAccessChain + fun updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, argumentExpression: Expression): ElementAccessChain + fun createCallExpression(expression: Expression, typeArguments: Array?, argumentsArray: Array?): CallExpression + fun updateCallExpression(node: CallExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array): CallExpression + fun createCallChain(expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array?): CallChain + fun updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array): CallChain + fun createNewExpression(expression: Expression, typeArguments: Array?, argumentsArray: Array?): NewExpression + fun updateNewExpression(node: NewExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array?): NewExpression + fun createTaggedTemplateExpression(tag: Expression, typeArguments: Array?, template: TemplateExpression): TaggedTemplateExpression + fun createTaggedTemplateExpression(tag: Expression, typeArguments: Array?, template: NoSubstitutionTemplateLiteral): TaggedTemplateExpression + fun updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: TemplateExpression): TaggedTemplateExpression + fun updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: NoSubstitutionTemplateLiteral): TaggedTemplateExpression + fun createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion + fun updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion + fun createParenthesizedExpression(expression: Expression): ParenthesizedExpression + fun updateParenthesizedExpression(node: ParenthesizedExpression, expression: Expression): ParenthesizedExpression + fun createFunctionExpression(modifiers: Array?, asteriskToken: AsteriskToken?, name: String?, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block): FunctionExpression + fun createFunctionExpression(modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block): FunctionExpression + fun updateFunctionExpression(node: FunctionExpression, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block): FunctionExpression + fun createArrowFunction(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: FunctionBody): ArrowFunction + fun createArrowFunction(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: Expression): ArrowFunction + fun updateArrowFunction(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: FunctionBody): ArrowFunction + fun updateArrowFunction(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: Expression): ArrowFunction + fun createDeleteExpression(expression: Expression): DeleteExpression + fun updateDeleteExpression(node: DeleteExpression, expression: Expression): DeleteExpression + fun createTypeOfExpression(expression: Expression): TypeOfExpression + fun updateTypeOfExpression(node: TypeOfExpression, expression: Expression): TypeOfExpression + fun createVoidExpression(expression: Expression): VoidExpression + fun updateVoidExpression(node: VoidExpression, expression: Expression): VoidExpression + fun createAwaitExpression(expression: Expression): AwaitExpression + fun updateAwaitExpression(node: AwaitExpression, expression: Expression): AwaitExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.PlusPlusToken, operand: Expression): PrefixUnaryExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.MinusMinusToken, operand: Expression): PrefixUnaryExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.PlusToken, operand: Expression): PrefixUnaryExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.MinusToken, operand: Expression): PrefixUnaryExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.TildeToken, operand: Expression): PrefixUnaryExpression + fun createPrefixUnaryExpression(operator: SyntaxKind.ExclamationToken, operand: Expression): PrefixUnaryExpression + fun updatePrefixUnaryExpression(node: PrefixUnaryExpression, operand: Expression): PrefixUnaryExpression + fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind.PlusPlusToken): PostfixUnaryExpression + fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind.MinusMinusToken): PostfixUnaryExpression + fun updatePostfixUnaryExpression(node: PostfixUnaryExpression, operand: Expression): PostfixUnaryExpression + fun createBinaryExpression(left: Expression, operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression): BinaryExpression + fun updateBinaryExpression(node: BinaryExpression, left: Expression, operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression): BinaryExpression + fun createConditionalExpression(condition: Expression, questionToken: QuestionToken?, whenTrue: Expression, colonToken: ColonToken?, whenFalse: Expression): ConditionalExpression + fun updateConditionalExpression(node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression + fun createTemplateExpression(head: TemplateHead, templateSpans: Array): TemplateExpression + fun updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: Array): TemplateExpression + fun createTemplateHead(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateHead + fun createTemplateHead(text: String): TemplateHead + fun createTemplateHead(text: String, rawText: String = definedExternally): TemplateHead + fun createTemplateHead(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateHead + fun createTemplateHead(text: String?, rawText: String): TemplateHead + fun createTemplateMiddle(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateMiddle + fun createTemplateMiddle(text: String): TemplateMiddle + fun createTemplateMiddle(text: String, rawText: String = definedExternally): TemplateMiddle + fun createTemplateMiddle(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateMiddle + fun createTemplateMiddle(text: String?, rawText: String): TemplateMiddle + fun createTemplateTail(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateTail + fun createTemplateTail(text: String): TemplateTail + fun createTemplateTail(text: String, rawText: String = definedExternally): TemplateTail + fun createTemplateTail(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateTail + fun createTemplateTail(text: String?, rawText: String): TemplateTail + fun createNoSubstitutionTemplateLiteral(text: String, rawText: String = definedExternally): NoSubstitutionTemplateLiteral + fun createNoSubstitutionTemplateLiteral(text: String): NoSubstitutionTemplateLiteral + fun createNoSubstitutionTemplateLiteral(text: String?, rawText: String): NoSubstitutionTemplateLiteral + fun createYieldExpression(asteriskToken: AsteriskToken, expression: Expression): YieldExpression + fun createYieldExpression(asteriskToken: Nothing?, expression: Expression?): YieldExpression + fun updateYieldExpression(node: YieldExpression, asteriskToken: AsteriskToken?, expression: Expression?): YieldExpression + fun createSpreadElement(expression: Expression): SpreadElement + fun updateSpreadElement(node: SpreadElement, expression: Expression): SpreadElement + fun createClassExpression(decorators: Array?, modifiers: Array?, name: String?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression + fun createClassExpression(decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression + fun updateClassExpression(node: ClassExpression, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression + fun createOmittedExpression(): OmittedExpression + fun createExpressionWithTypeArguments(expression: Expression, typeArguments: Array?): ExpressionWithTypeArguments + fun updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, expression: Expression, typeArguments: Array?): ExpressionWithTypeArguments + fun createAsExpression(expression: Expression, type: TypeNode): AsExpression + fun updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode): AsExpression + fun createNonNullExpression(expression: Expression): NonNullExpression + fun updateNonNullExpression(node: NonNullExpression, expression: Expression): NonNullExpression + fun createNonNullChain(expression: Expression): NonNullChain + fun updateNonNullChain(node: NonNullChain, expression: Expression): NonNullChain + fun createMetaProperty(keywordToken: SyntaxKind.NewKeyword, name: Identifier): MetaProperty + fun createMetaProperty(keywordToken: SyntaxKind.ImportKeyword, name: Identifier): MetaProperty + fun updateMetaProperty(node: MetaProperty, name: Identifier): MetaProperty + fun createTemplateSpan(expression: Expression, literal: TemplateMiddle): TemplateSpan + fun createTemplateSpan(expression: Expression, literal: TemplateTail): TemplateSpan + fun updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle): TemplateSpan + fun updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateTail): TemplateSpan + fun createSemicolonClassElement(): SemicolonClassElement + fun createBlock(statements: Array, multiLine: Boolean = definedExternally): Block + fun updateBlock(node: Block, statements: Array): Block + fun createVariableStatement(modifiers: Array?, declarationList: VariableDeclarationList): VariableStatement + fun createVariableStatement(modifiers: Array?, declarationList: Array): VariableStatement + fun updateVariableStatement(node: VariableStatement, modifiers: Array?, declarationList: VariableDeclarationList): VariableStatement + fun createEmptyStatement(): EmptyStatement + fun createExpressionStatement(expression: Expression): ExpressionStatement + fun updateExpressionStatement(node: ExpressionStatement, expression: Expression): ExpressionStatement + fun createIfStatement(expression: Expression, thenStatement: Statement, elseStatement: Statement = definedExternally): IfStatement + fun updateIfStatement(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement?): IfStatement + fun createDoStatement(statement: Statement, expression: Expression): DoStatement + fun updateDoStatement(node: DoStatement, statement: Statement, expression: Expression): DoStatement + fun createWhileStatement(expression: Expression, statement: Statement): WhileStatement + fun updateWhileStatement(node: WhileStatement, expression: Expression, statement: Statement): WhileStatement + fun createForStatement(initializer: VariableDeclarationList?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement + fun createForStatement(initializer: Expression?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement + fun updateForStatement(node: ForStatement, initializer: VariableDeclarationList?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement + fun updateForStatement(node: ForStatement, initializer: Expression?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement + fun createForInStatement(initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForInStatement + fun createForInStatement(initializer: Expression, expression: Expression, statement: Statement): ForInStatement + fun updateForInStatement(node: ForInStatement, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForInStatement + fun updateForInStatement(node: ForInStatement, initializer: Expression, expression: Expression, statement: Statement): ForInStatement + fun createForOfStatement(awaitModifier: AwaitKeyword?, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForOfStatement + fun createForOfStatement(awaitModifier: AwaitKeyword?, initializer: Expression, expression: Expression, statement: Statement): ForOfStatement + fun updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForOfStatement + fun updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: Expression, expression: Expression, statement: Statement): ForOfStatement + fun createContinueStatement(label: String = definedExternally): ContinueStatement + fun createContinueStatement(): ContinueStatement + fun createContinueStatement(label: Identifier = definedExternally): ContinueStatement + fun updateContinueStatement(node: ContinueStatement, label: Identifier?): ContinueStatement + fun createBreakStatement(label: String = definedExternally): BreakStatement + fun createBreakStatement(): BreakStatement + fun createBreakStatement(label: Identifier = definedExternally): BreakStatement + fun updateBreakStatement(node: BreakStatement, label: Identifier?): BreakStatement + fun createReturnStatement(expression: Expression = definedExternally): ReturnStatement + fun updateReturnStatement(node: ReturnStatement, expression: Expression?): ReturnStatement + fun createWithStatement(expression: Expression, statement: Statement): WithStatement + fun updateWithStatement(node: WithStatement, expression: Expression, statement: Statement): WithStatement + fun createSwitchStatement(expression: Expression, caseBlock: CaseBlock): SwitchStatement + fun updateSwitchStatement(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock): SwitchStatement + fun createLabeledStatement(label: String, statement: Statement): LabeledStatement + fun createLabeledStatement(label: Identifier, statement: Statement): LabeledStatement + fun updateLabeledStatement(node: LabeledStatement, label: Identifier, statement: Statement): LabeledStatement + fun createThrowStatement(expression: Expression): ThrowStatement + fun updateThrowStatement(node: ThrowStatement, expression: Expression): ThrowStatement + fun createTryStatement(tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?): TryStatement + fun updateTryStatement(node: TryStatement, tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?): TryStatement + fun createDebuggerStatement(): DebuggerStatement + fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: String): VariableDeclaration + fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: Identifier): VariableDeclaration + fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ObjectBindingPattern): VariableDeclaration + fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ArrayBindingPattern): VariableDeclaration + fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration + fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration + fun updateVariableDeclaration(node: VariableDeclaration, name: Identifier, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration + fun updateVariableDeclaration(node: VariableDeclaration, name: ObjectBindingPattern, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration + fun updateVariableDeclaration(node: VariableDeclaration, name: ArrayBindingPattern, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration + fun createVariableDeclarationList(declarations: Array, flags: NodeFlags = definedExternally): VariableDeclarationList + fun updateVariableDeclarationList(node: VariableDeclarationList, declarations: Array): VariableDeclarationList + fun createFunctionDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration + fun createFunctionDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration + fun updateFunctionDeclaration(node: FunctionDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration + fun createClassDeclaration(decorators: Array?, modifiers: Array?, name: String?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration + fun createClassDeclaration(decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration + fun updateClassDeclaration(node: ClassDeclaration, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration + fun createInterfaceDeclaration(decorators: Array?, modifiers: Array?, name: String, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration + fun createInterfaceDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration + fun updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration + fun createTypeAliasDeclaration(decorators: Array?, modifiers: Array?, name: String, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration + fun createTypeAliasDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration + fun updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration + fun createEnumDeclaration(decorators: Array?, modifiers: Array?, name: String, members: Array): EnumDeclaration + fun createEnumDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, members: Array): EnumDeclaration + fun updateEnumDeclaration(node: EnumDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, members: Array): EnumDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration + fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?): ModuleDeclaration + fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?): ModuleDeclaration + fun createModuleBlock(statements: Array): ModuleBlock + fun updateModuleBlock(node: ModuleBlock, statements: Array): ModuleBlock + fun createCaseBlock(clauses: Array): CaseBlock + fun updateCaseBlock(node: CaseBlock, clauses: Array): CaseBlock + fun createNamespaceExportDeclaration(name: String): NamespaceExportDeclaration + fun createNamespaceExportDeclaration(name: Identifier): NamespaceExportDeclaration + fun updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier): NamespaceExportDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: Identifier): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: QualifiedName): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: ExternalModuleReference): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: Identifier): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: QualifiedName): ImportEqualsDeclaration + fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: ExternalModuleReference): ImportEqualsDeclaration + fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: Identifier): ImportEqualsDeclaration + fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: QualifiedName): ImportEqualsDeclaration + fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: ExternalModuleReference): ImportEqualsDeclaration + fun createImportDeclaration(decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression): ImportDeclaration + fun updateImportDeclaration(node: ImportDeclaration, decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression): ImportDeclaration + fun createImportClause(isTypeOnly: Boolean, name: Identifier?, namedBindings: NamespaceImport?): ImportClause + fun createImportClause(isTypeOnly: Boolean, name: Identifier?, namedBindings: NamedImports?): ImportClause + fun updateImportClause(node: ImportClause, isTypeOnly: Boolean, name: Identifier?, namedBindings: NamespaceImport?): ImportClause + fun updateImportClause(node: ImportClause, isTypeOnly: Boolean, name: Identifier?, namedBindings: NamedImports?): ImportClause + fun createNamespaceImport(name: Identifier): NamespaceImport + fun updateNamespaceImport(node: NamespaceImport, name: Identifier): NamespaceImport + fun createNamespaceExport(name: Identifier): NamespaceExport + fun updateNamespaceExport(node: NamespaceExport, name: Identifier): NamespaceExport + fun createNamedImports(elements: Array): NamedImports + fun updateNamedImports(node: NamedImports, elements: Array): NamedImports + fun createImportSpecifier(propertyName: Identifier?, name: Identifier): ImportSpecifier + fun updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier?, name: Identifier): ImportSpecifier + fun createExportAssignment(decorators: Array?, modifiers: Array?, isExportEquals: Boolean?, expression: Expression): ExportAssignment + fun updateExportAssignment(node: ExportAssignment, decorators: Array?, modifiers: Array?, expression: Expression): ExportAssignment + fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?, moduleSpecifier: Expression = definedExternally): ExportDeclaration + fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?): ExportDeclaration + fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?, moduleSpecifier: Expression = definedExternally): ExportDeclaration + fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?): ExportDeclaration + fun updateExportDeclaration(node: ExportDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?, moduleSpecifier: Expression?): ExportDeclaration + fun updateExportDeclaration(node: ExportDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?, moduleSpecifier: Expression?): ExportDeclaration + fun createNamedExports(elements: Array): NamedExports + fun updateNamedExports(node: NamedExports, elements: Array): NamedExports + fun createExportSpecifier(propertyName: String?, name: String): ExportSpecifier + fun createExportSpecifier(propertyName: String?, name: Identifier): ExportSpecifier + fun createExportSpecifier(propertyName: Identifier?, name: String): ExportSpecifier + fun createExportSpecifier(propertyName: Identifier?, name: Identifier): ExportSpecifier + fun updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier?, name: Identifier): ExportSpecifier + fun createExternalModuleReference(expression: Expression): ExternalModuleReference + fun updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference + fun createJSDocAllType(): JSDocAllType + fun createJSDocUnknownType(): JSDocUnknownType + fun createJSDocNonNullableType(type: TypeNode): JSDocNonNullableType + fun updateJSDocNonNullableType(node: JSDocNonNullableType, type: TypeNode): JSDocNonNullableType + fun createJSDocNullableType(type: TypeNode): JSDocNullableType + fun updateJSDocNullableType(node: JSDocNullableType, type: TypeNode): JSDocNullableType + fun createJSDocOptionalType(type: TypeNode): JSDocOptionalType + fun updateJSDocOptionalType(node: JSDocOptionalType, type: TypeNode): JSDocOptionalType + fun createJSDocFunctionType(parameters: Array, type: TypeNode?): JSDocFunctionType + fun updateJSDocFunctionType(node: JSDocFunctionType, parameters: Array, type: TypeNode?): JSDocFunctionType + fun createJSDocVariadicType(type: TypeNode): JSDocVariadicType + fun updateJSDocVariadicType(node: JSDocVariadicType, type: TypeNode): JSDocVariadicType + fun createJSDocNamepathType(type: TypeNode): JSDocNamepathType + fun updateJSDocNamepathType(node: JSDocNamepathType, type: TypeNode): JSDocNamepathType + fun createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression + fun updateJSDocTypeExpression(node: JSDocTypeExpression, type: TypeNode): JSDocTypeExpression + fun createJSDocNameReference(name: Identifier): JSDocNameReference + fun createJSDocNameReference(name: QualifiedName): JSDocNameReference + fun createJSDocNameReference(name: JSDocMemberName): JSDocNameReference + fun updateJSDocNameReference(node: JSDocNameReference, name: Identifier): JSDocNameReference + fun updateJSDocNameReference(node: JSDocNameReference, name: QualifiedName): JSDocNameReference + fun updateJSDocNameReference(node: JSDocNameReference, name: JSDocMemberName): JSDocNameReference + fun createJSDocMemberName(left: Identifier, right: Identifier): JSDocMemberName + fun createJSDocMemberName(left: QualifiedName, right: Identifier): JSDocMemberName + fun createJSDocMemberName(left: JSDocMemberName, right: Identifier): JSDocMemberName + fun updateJSDocMemberName(node: JSDocMemberName, left: Identifier, right: Identifier): JSDocMemberName + fun updateJSDocMemberName(node: JSDocMemberName, left: QualifiedName, right: Identifier): JSDocMemberName + fun updateJSDocMemberName(node: JSDocMemberName, left: JSDocMemberName, right: Identifier): JSDocMemberName + fun createJSDocLink(name: Identifier?, text: String): JSDocLink + fun createJSDocLink(name: QualifiedName?, text: String): JSDocLink + fun createJSDocLink(name: JSDocMemberName?, text: String): JSDocLink + fun updateJSDocLink(node: JSDocLink, name: Identifier?, text: String): JSDocLink + fun updateJSDocLink(node: JSDocLink, name: QualifiedName?, text: String): JSDocLink + fun updateJSDocLink(node: JSDocLink, name: JSDocMemberName?, text: String): JSDocLink + fun createJSDocLinkCode(name: Identifier?, text: String): JSDocLinkCode + fun createJSDocLinkCode(name: QualifiedName?, text: String): JSDocLinkCode + fun createJSDocLinkCode(name: JSDocMemberName?, text: String): JSDocLinkCode + fun updateJSDocLinkCode(node: JSDocLinkCode, name: Identifier?, text: String): JSDocLinkCode + fun updateJSDocLinkCode(node: JSDocLinkCode, name: QualifiedName?, text: String): JSDocLinkCode + fun updateJSDocLinkCode(node: JSDocLinkCode, name: JSDocMemberName?, text: String): JSDocLinkCode + fun createJSDocLinkPlain(name: Identifier?, text: String): JSDocLinkPlain + fun createJSDocLinkPlain(name: QualifiedName?, text: String): JSDocLinkPlain + fun createJSDocLinkPlain(name: JSDocMemberName?, text: String): JSDocLinkPlain + fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: Identifier?, text: String): JSDocLinkPlain + fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: QualifiedName?, text: String): JSDocLinkPlain + fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: JSDocMemberName?, text: String): JSDocLinkPlain + fun createJSDocTypeLiteral(jsDocPropertyTags: Array = definedExternally, isArrayType: Boolean = definedExternally): JSDocTypeLiteral + fun updateJSDocTypeLiteral(node: JSDocTypeLiteral, jsDocPropertyTags: Array?, isArrayType: Boolean?): JSDocTypeLiteral + fun createJSDocSignature(typeParameters: Array?, parameters: Array, type: JSDocReturnTag = definedExternally): JSDocSignature + fun updateJSDocSignature(node: JSDocSignature, typeParameters: Array?, parameters: Array, type: JSDocReturnTag?): JSDocSignature + fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String = definedExternally): JSDocTemplateTag + fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array): JSDocTemplateTag + fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray = definedExternally): JSDocTemplateTag + fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String?): JSDocTemplateTag + fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray?): JSDocTemplateTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag + fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: String?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: String?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag + fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag + fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag + fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag + fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag + fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag + fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocTypeTag + fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocTypeTag + fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocTypeTag + fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocTypeTag + fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocTypeTag + fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag + fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag + fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag + fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag + fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag + fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag + fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: String = definedExternally): JSDocReturnTag + fun createJSDocReturnTag(tagName: Identifier?): JSDocReturnTag + fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocReturnTag + fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: NodeArray = definedExternally): JSDocReturnTag + fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocReturnTag + fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocReturnTag + fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocThisTag + fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocThisTag + fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocThisTag + fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocThisTag + fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocThisTag + fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocEnumTag + fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocEnumTag + fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocEnumTag + fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocEnumTag + fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocEnumTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocCallbackTag + fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: String?): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: NodeArray?): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocCallbackTag + fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocCallbackTag + fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String = definedExternally): JSDocAugmentsTag + fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */): JSDocAugmentsTag + fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray = definedExternally): JSDocAugmentsTag + fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String?): JSDocAugmentsTag + fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray?): JSDocAugmentsTag + fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String = definedExternally): JSDocImplementsTag + fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */): JSDocImplementsTag + fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray = definedExternally): JSDocImplementsTag + fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String?): JSDocImplementsTag + fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray?): JSDocImplementsTag + fun createJSDocAuthorTag(tagName: Identifier?, comment: String = definedExternally): JSDocAuthorTag + fun createJSDocAuthorTag(tagName: Identifier?): JSDocAuthorTag + fun createJSDocAuthorTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocAuthorTag + fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: String?): JSDocAuthorTag + fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: NodeArray?): JSDocAuthorTag + fun createJSDocClassTag(tagName: Identifier?, comment: String = definedExternally): JSDocClassTag + fun createJSDocClassTag(tagName: Identifier?): JSDocClassTag + fun createJSDocClassTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocClassTag + fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: String?): JSDocClassTag + fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: NodeArray?): JSDocClassTag + fun createJSDocPublicTag(tagName: Identifier?, comment: String = definedExternally): JSDocPublicTag + fun createJSDocPublicTag(tagName: Identifier?): JSDocPublicTag + fun createJSDocPublicTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPublicTag + fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: String?): JSDocPublicTag + fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: NodeArray?): JSDocPublicTag + fun createJSDocPrivateTag(tagName: Identifier?, comment: String = definedExternally): JSDocPrivateTag + fun createJSDocPrivateTag(tagName: Identifier?): JSDocPrivateTag + fun createJSDocPrivateTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPrivateTag + fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: String?): JSDocPrivateTag + fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: NodeArray?): JSDocPrivateTag + fun createJSDocProtectedTag(tagName: Identifier?, comment: String = definedExternally): JSDocProtectedTag + fun createJSDocProtectedTag(tagName: Identifier?): JSDocProtectedTag + fun createJSDocProtectedTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocProtectedTag + fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: String?): JSDocProtectedTag + fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: NodeArray?): JSDocProtectedTag + fun createJSDocReadonlyTag(tagName: Identifier?, comment: String = definedExternally): JSDocReadonlyTag + fun createJSDocReadonlyTag(tagName: Identifier?): JSDocReadonlyTag + fun createJSDocReadonlyTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocReadonlyTag + fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: String?): JSDocReadonlyTag + fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: NodeArray?): JSDocReadonlyTag + fun createJSDocUnknownTag(tagName: Identifier, comment: String = definedExternally): JSDocUnknownTag + fun createJSDocUnknownTag(tagName: Identifier): JSDocUnknownTag + fun createJSDocUnknownTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocUnknownTag + fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: String?): JSDocUnknownTag + fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: NodeArray?): JSDocUnknownTag + fun createJSDocDeprecatedTag(tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag + fun createJSDocDeprecatedTag(tagName: Identifier): JSDocDeprecatedTag + fun createJSDocDeprecatedTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag + fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag + fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier): JSDocDeprecatedTag + fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag + fun createJSDocOverrideTag(tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag + fun createJSDocOverrideTag(tagName: Identifier): JSDocOverrideTag + fun createJSDocOverrideTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag + fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag + fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier): JSDocOverrideTag + fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag + fun createJSDocText(text: String): JSDocText + fun updateJSDocText(node: JSDocText, text: String): JSDocText + fun createJSDocComment(comment: String? = definedExternally, tags: Array? = definedExternally): JSDoc + fun createJSDocComment(): JSDoc + fun createJSDocComment(comment: String? = definedExternally): JSDoc + fun createJSDocComment(comment: NodeArray? = definedExternally, tags: Array? = definedExternally): JSDoc + fun createJSDocComment(comment: NodeArray? = definedExternally): JSDoc + fun updateJSDocComment(node: JSDoc, comment: String?, tags: Array?): JSDoc + fun updateJSDocComment(node: JSDoc, comment: NodeArray?, tags: Array?): JSDoc + fun createJsxElement(openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement + fun updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement + fun createJsxSelfClosingElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun createJsxSelfClosingElement(tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun createJsxSelfClosingElement(tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement + fun createJsxOpeningElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun createJsxOpeningElement(tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun createJsxOpeningElement(tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement + fun createJsxClosingElement(tagName: Identifier): JsxClosingElement + fun createJsxClosingElement(tagName: ThisExpression): JsxClosingElement + fun createJsxClosingElement(tagName: JsxTagNamePropertyAccess): JsxClosingElement + fun updateJsxClosingElement(node: JsxClosingElement, tagName: Identifier): JsxClosingElement + fun updateJsxClosingElement(node: JsxClosingElement, tagName: ThisExpression): JsxClosingElement + fun updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNamePropertyAccess): JsxClosingElement + fun createJsxFragment(openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment): JsxFragment + fun createJsxText(text: String, containsOnlyTriviaWhiteSpaces: Boolean = definedExternally): JsxText + fun updateJsxText(node: JsxText, text: String, containsOnlyTriviaWhiteSpaces: Boolean = definedExternally): JsxText + fun createJsxOpeningFragment(): JsxOpeningFragment + fun createJsxJsxClosingFragment(): JsxClosingFragment + fun updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment): JsxFragment + fun createJsxAttribute(name: Identifier, initializer: StringLiteral?): JsxAttribute + fun createJsxAttribute(name: Identifier, initializer: JsxExpression?): JsxAttribute + fun updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral?): JsxAttribute + fun updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: JsxExpression?): JsxAttribute + fun createJsxAttributes(properties: Array): JsxAttributes + fun updateJsxAttributes(node: JsxAttributes, properties: Array): JsxAttributes + fun createJsxSpreadAttribute(expression: Expression): JsxSpreadAttribute + fun updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression): JsxSpreadAttribute + fun createJsxExpression(dotDotDotToken: DotDotDotToken?, expression: Expression?): JsxExpression + fun updateJsxExpression(node: JsxExpression, expression: Expression?): JsxExpression + fun createCaseClause(expression: Expression, statements: Array): CaseClause + fun updateCaseClause(node: CaseClause, expression: Expression, statements: Array): CaseClause + fun createDefaultClause(statements: Array): DefaultClause + fun updateDefaultClause(node: DefaultClause, statements: Array): DefaultClause + fun createHeritageClause(token: SyntaxKind.ExtendsKeyword, types: Array): HeritageClause + fun createHeritageClause(token: SyntaxKind.ImplementsKeyword, types: Array): HeritageClause + fun updateHeritageClause(node: HeritageClause, types: Array): HeritageClause + fun createCatchClause(variableDeclaration: String?, block: Block): CatchClause + fun createCatchClause(variableDeclaration: VariableDeclaration?, block: Block): CatchClause + fun updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration?, block: Block): CatchClause + fun createPropertyAssignment(name: String, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: Identifier, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: StringLiteral, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: NumericLiteral, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: ComputedPropertyName, initializer: Expression): PropertyAssignment + fun createPropertyAssignment(name: PrivateIdentifier, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: Identifier, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: StringLiteral, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: NumericLiteral, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: ComputedPropertyName, initializer: Expression): PropertyAssignment + fun updatePropertyAssignment(node: PropertyAssignment, name: PrivateIdentifier, initializer: Expression): PropertyAssignment + fun createShorthandPropertyAssignment(name: String, objectAssignmentInitializer: Expression = definedExternally): ShorthandPropertyAssignment + fun createShorthandPropertyAssignment(name: String): ShorthandPropertyAssignment + fun createShorthandPropertyAssignment(name: Identifier, objectAssignmentInitializer: Expression = definedExternally): ShorthandPropertyAssignment + fun createShorthandPropertyAssignment(name: Identifier): ShorthandPropertyAssignment + fun updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression?): ShorthandPropertyAssignment + fun createSpreadAssignment(expression: Expression): SpreadAssignment + fun updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment + fun createEnumMember(name: String, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: String): EnumMember + fun createEnumMember(name: Identifier, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: Identifier): EnumMember + fun createEnumMember(name: StringLiteral, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: StringLiteral): EnumMember + fun createEnumMember(name: NumericLiteral, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: NumericLiteral): EnumMember + fun createEnumMember(name: ComputedPropertyName, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: ComputedPropertyName): EnumMember + fun createEnumMember(name: PrivateIdentifier, initializer: Expression = definedExternally): EnumMember + fun createEnumMember(name: PrivateIdentifier): EnumMember + fun updateEnumMember(node: EnumMember, name: Identifier, initializer: Expression?): EnumMember + fun updateEnumMember(node: EnumMember, name: StringLiteral, initializer: Expression?): EnumMember + fun updateEnumMember(node: EnumMember, name: NumericLiteral, initializer: Expression?): EnumMember + fun updateEnumMember(node: EnumMember, name: ComputedPropertyName, initializer: Expression?): EnumMember + fun updateEnumMember(node: EnumMember, name: PrivateIdentifier, initializer: Expression?): EnumMember + fun createSourceFile(statements: Array, endOfFileToken: Token /* Token & JSDocContainer */, flags: NodeFlags): SourceFile + fun updateSourceFile(node: SourceFile, statements: Array, isDeclarationFile: Boolean = definedExternally, referencedFiles: Array = definedExternally, typeReferences: Array = definedExternally, hasNoDefaultLib: Boolean = definedExternally, libReferences: Array = definedExternally): SourceFile + fun createNotEmittedStatement(original: Node): NotEmittedStatement + fun createPartiallyEmittedExpression(expression: Expression, original: Node = definedExternally): PartiallyEmittedExpression + fun updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression): PartiallyEmittedExpression + fun createCommaListExpression(elements: Array): CommaListExpression + fun updateCommaListExpression(node: CommaListExpression, elements: Array): CommaListExpression + fun createBundle(sourceFiles: Array, prepends: Array = definedExternally): Bundle + fun updateBundle(node: Bundle, sourceFiles: Array, prepends: Array = definedExternally): Bundle + fun createComma(left: Expression, right: Expression): BinaryExpression + fun createAssignment(left: ObjectLiteralExpression, right: Expression): dynamic /* ObjectDestructuringAssignment | ArrayDestructuringAssignment */ + fun createAssignment(left: ArrayLiteralExpression, right: Expression): dynamic /* ObjectDestructuringAssignment | ArrayDestructuringAssignment */ + fun createAssignment(left: Expression, right: Expression): AssignmentExpression + fun createLogicalOr(left: Expression, right: Expression): BinaryExpression + fun createLogicalAnd(left: Expression, right: Expression): BinaryExpression + fun createBitwiseOr(left: Expression, right: Expression): BinaryExpression + fun createBitwiseXor(left: Expression, right: Expression): BinaryExpression + fun createBitwiseAnd(left: Expression, right: Expression): BinaryExpression + fun createStrictEquality(left: Expression, right: Expression): BinaryExpression + fun createStrictInequality(left: Expression, right: Expression): BinaryExpression + fun createEquality(left: Expression, right: Expression): BinaryExpression + fun createInequality(left: Expression, right: Expression): BinaryExpression + fun createLessThan(left: Expression, right: Expression): BinaryExpression + fun createLessThanEquals(left: Expression, right: Expression): BinaryExpression + fun createGreaterThan(left: Expression, right: Expression): BinaryExpression + fun createGreaterThanEquals(left: Expression, right: Expression): BinaryExpression + fun createLeftShift(left: Expression, right: Expression): BinaryExpression + fun createRightShift(left: Expression, right: Expression): BinaryExpression + fun createUnsignedRightShift(left: Expression, right: Expression): BinaryExpression + fun createAdd(left: Expression, right: Expression): BinaryExpression + fun createSubtract(left: Expression, right: Expression): BinaryExpression + fun createMultiply(left: Expression, right: Expression): BinaryExpression + fun createDivide(left: Expression, right: Expression): BinaryExpression + fun createModulo(left: Expression, right: Expression): BinaryExpression + fun createExponent(left: Expression, right: Expression): BinaryExpression + fun createPrefixPlus(operand: Expression): PrefixUnaryExpression + fun createPrefixMinus(operand: Expression): PrefixUnaryExpression + fun createPrefixIncrement(operand: Expression): PrefixUnaryExpression + fun createPrefixDecrement(operand: Expression): PrefixUnaryExpression + fun createBitwiseNot(operand: Expression): PrefixUnaryExpression + fun createLogicalNot(operand: Expression): PrefixUnaryExpression + fun createPostfixIncrement(operand: Expression): PostfixUnaryExpression + fun createPostfixDecrement(operand: Expression): PostfixUnaryExpression + fun createImmediatelyInvokedFunctionExpression(statements: Array): CallExpression + fun createImmediatelyInvokedFunctionExpression(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression + fun createImmediatelyInvokedArrowFunction(statements: Array): CallExpression + fun createImmediatelyInvokedArrowFunction(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression + fun createVoidZero(): VoidExpression + fun createExportDefault(expression: Expression): ExportAssignment + fun createExternalModuleExport(exportName: Identifier): ExportDeclaration + fun restoreOuterExpressions(outerExpression: Expression?, innerExpression: Expression, kinds: OuterExpressionKinds = definedExternally): Expression +} + +external interface CoreTransformationContext { + var factory: NodeFactory + fun getCompilerOptions(): CompilerOptions + fun startLexicalEnvironment() + fun suspendLexicalEnvironment() + fun resumeLexicalEnvironment() + fun endLexicalEnvironment(): Array? + fun hoistFunctionDeclaration(node: FunctionDeclaration) + fun hoistVariableDeclaration(node: Identifier) +} + +external interface TransformationContext : CoreTransformationContext { + fun requestEmitHelper(helper: ScopedEmitHelper) + fun requestEmitHelper(helper: UnscopedEmitHelper) + fun readEmitHelpers(): Array? + fun enableSubstitution(kind: SyntaxKind) + fun isSubstitutionEnabled(node: Node): Boolean + var onSubstituteNode: (hint: EmitHint, node: Node) -> Node + fun enableEmitNotification(kind: SyntaxKind) + fun isEmitNotificationEnabled(node: Node): Boolean + var onEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) -> Unit +} + +external interface TransformationResult { + var transformed: Array + var diagnostics: Array? + get() = definedExternally + set(value) = definedExternally + fun substituteNode(hint: EmitHint, node: Node): Node + fun emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) + val isEmitNotificationEnabled: ((node: Node) -> Boolean)? + fun dispose() +} + +external interface NodeVisitor { + @nativeInvoke + operator fun invoke(nodes: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T + @nativeInvoke + operator fun invoke(nodes: T, visitor: Visitor?): T + @nativeInvoke + operator fun invoke(nodes: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T + @nativeInvoke + operator fun invoke(nodes: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T? + @nativeInvoke + operator fun invoke(nodes: T?, visitor: Visitor?): T? + @nativeInvoke + operator fun invoke(nodes: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T? +} + +external interface NodesVisitor { + @nativeInvoke + operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray + @nativeInvoke + operator fun invoke(nodes: NodeArray, visitor: Visitor?): NodeArray + @nativeInvoke + operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray + @nativeInvoke + operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray + @nativeInvoke + operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray? + @nativeInvoke + operator fun invoke(nodes: NodeArray?, visitor: Visitor?): NodeArray? + @nativeInvoke + operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray? + @nativeInvoke + operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray? +} + +external interface Printer { + fun printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): String + fun printList(format: ListFormat, list: NodeArray, sourceFile: SourceFile): String + fun printFile(sourceFile: SourceFile): String + fun printBundle(bundle: Bundle): String +} + +external interface PrintHandlers { + val hasGlobalName: ((name: String) -> Boolean)? + val onEmitNode: ((hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) -> Unit)? + val isEmitNotificationEnabled: ((node: Node) -> Boolean)? + val substituteNode: ((hint: EmitHint, node: Node) -> Node)? +} + +external interface PrinterOptions { + var removeComments: Boolean? + get() = definedExternally + set(value) = definedExternally + var newLine: NewLineKind? + get() = definedExternally + set(value) = definedExternally + var omitTrailingSemicolon: Boolean? + get() = definedExternally + set(value) = definedExternally + var noEmitHelpers: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface GetEffectiveTypeRootsHost { + val directoryExists: ((directoryName: String) -> Boolean)? + val getCurrentDirectory: (() -> String)? +} + +external interface TextSpan { + var start: Number + var length: Number +} + +external interface TextChangeRange { + var span: TextSpan + var newLength: Number +} + +external interface SyntaxList : Node { + var _children: Array +} + +external enum class ListFormat { + None /* = 0 */, + SingleLine /* = 0 */, + MultiLine /* = 1 */, + PreserveLines /* = 2 */, + LinesMask /* = 3 */, + NotDelimited /* = 0 */, + BarDelimited /* = 4 */, + AmpersandDelimited /* = 8 */, + CommaDelimited /* = 16 */, + AsteriskDelimited /* = 32 */, + DelimitersMask /* = 60 */, + AllowTrailingComma /* = 64 */, + Indented /* = 128 */, + SpaceBetweenBraces /* = 256 */, + SpaceBetweenSiblings /* = 512 */, + Braces /* = 1024 */, + Parenthesis /* = 2048 */, + AngleBrackets /* = 4096 */, + SquareBrackets /* = 8192 */, + BracketsMask /* = 15360 */, + OptionalIfUndefined /* = 16384 */, + OptionalIfEmpty /* = 32768 */, + Optional /* = 49152 */, + PreferNewLine /* = 65536 */, + NoTrailingNewLine /* = 131072 */, + NoInterveningComments /* = 262144 */, + NoSpaceIfEmpty /* = 524288 */, + SingleElement /* = 1048576 */, + SpaceAfterList /* = 2097152 */, + Modifiers /* = 262656 */, + HeritageClauses /* = 512 */, + SingleLineTypeLiteralMembers /* = 768 */, + MultiLineTypeLiteralMembers /* = 32897 */, + SingleLineTupleTypeElements /* = 528 */, + MultiLineTupleTypeElements /* = 657 */, + UnionTypeConstituents /* = 516 */, + IntersectionTypeConstituents /* = 520 */, + ObjectBindingPatternElements /* = 525136 */, + ArrayBindingPatternElements /* = 524880 */, + ObjectLiteralExpressionProperties /* = 526226 */, + ArrayLiteralExpressionElements /* = 8914 */, + CommaListElements /* = 528 */, + CallExpressionArguments /* = 2576 */, + NewExpressionArguments /* = 18960 */, + TemplateExpressionSpans /* = 262144 */, + SingleLineBlockStatements /* = 768 */, + MultiLineBlockStatements /* = 129 */, + VariableDeclarationList /* = 528 */, + SingleLineFunctionBodyStatements /* = 768 */, + MultiLineFunctionBodyStatements /* = 1 */, + ClassHeritageClauses /* = 0 */, + ClassMembers /* = 129 */, + InterfaceMembers /* = 129 */, + EnumMembers /* = 145 */, + CaseBlockClauses /* = 129 */, + NamedImportsOrExportsElements /* = 525136 */, + JsxElementOrFragmentChildren /* = 262144 */, + JsxElementAttributes /* = 262656 */, + CaseOrDefaultClauseStatements /* = 163969 */, + HeritageClauseTypes /* = 528 */, + SourceFileStatements /* = 131073 */, + Decorators /* = 2146305 */, + TypeArguments /* = 53776 */, + TypeParameters /* = 53776 */, + Parameters /* = 2576 */, + IndexSignatureParameters /* = 8848 */, + JSDocComment /* = 33 */ +} + +external interface UserPreferences { + var disableSuggestions: Boolean? + get() = definedExternally + set(value) = definedExternally + var quotePreference: String? /* "auto" | "double" | "single" */ + get() = definedExternally + set(value) = definedExternally + var includeCompletionsForModuleExports: Boolean? + get() = definedExternally + set(value) = definedExternally + var includeCompletionsForImportStatements: Boolean? + get() = definedExternally + set(value) = definedExternally + var includeCompletionsWithSnippetText: Boolean? + get() = definedExternally + set(value) = definedExternally + var includeAutomaticOptionalChainCompletions: Boolean? + get() = definedExternally + set(value) = definedExternally + var includeCompletionsWithInsertText: Boolean? + get() = definedExternally + set(value) = definedExternally + var allowIncompleteCompletions: Boolean? + get() = definedExternally + set(value) = definedExternally + var importModuleSpecifierPreference: String? /* "shortest" | "project-relative" | "relative" | "non-relative" */ + get() = definedExternally + set(value) = definedExternally + var importModuleSpecifierEnding: String? /* "auto" | "minimal" | "index" | "js" */ + get() = definedExternally + set(value) = definedExternally + var allowTextChangesInNewFiles: Boolean? + get() = definedExternally + set(value) = definedExternally + var providePrefixAndSuffixTextForRename: Boolean? + get() = definedExternally + set(value) = definedExternally + var includePackageJsonAutoImports: String? /* "auto" | "on" | "off" */ + get() = definedExternally + set(value) = definedExternally + var provideRefactorNotApplicableReason: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface PseudoBigInt { + var negative: Boolean + var base10Value: String +} + +external enum class FileWatcherEventKind { + Created /* = 0 */, + Changed /* = 1 */, + Deleted /* = 2 */ +} + +external interface System { + var args: Array + var newLine: String + var useCaseSensitiveFileNames: Boolean + fun write(s: String) + val writeOutputIsTTY: (() -> Boolean)? + val getWidthOfTerminal: (() -> Number)? + fun readFile(path: String, encoding: String = definedExternally): String? + val getFileSize: ((path: String) -> Number)? + fun writeFile(path: String, data: String, writeByteOrderMark: Boolean = definedExternally) + val watchFile: ((path: String, callback: FileWatcherCallback, pollingInterval: Number, options: WatchOptions) -> FileWatcher)? + val watchDirectory: ((path: String, callback: DirectoryWatcherCallback, recursive: Boolean, options: WatchOptions) -> FileWatcher)? + fun resolvePath(path: String): String + fun fileExists(path: String): Boolean + fun directoryExists(path: String): Boolean + fun createDirectory(path: String) + fun getExecutingFilePath(): String + fun getCurrentDirectory(): String + fun getDirectories(path: String): Array + fun readDirectory(path: String, extensions: Array = definedExternally, exclude: Array = definedExternally, include: Array = definedExternally, depth: Number = definedExternally): Array + val getModifiedTime: ((path: String) -> Date?)? + val setModifiedTime: ((path: String, time: Date) -> Unit)? + val deleteFile: ((path: String) -> Unit)? + val createHash: ((data: String) -> String)? + val createSHA256Hash: ((data: String) -> String)? + val getMemoryUsage: (() -> Number)? + fun exit(exitCode: Number = definedExternally) + val realpath: ((path: String) -> String)? + val setTimeout: ((callback: (args: Any) -> Unit, ms: Number, args: Any) -> Any)? + val clearTimeout: ((timeoutId: Any) -> Unit)? + val clearScreen: (() -> Unit)? + val base64decode: ((input: String) -> String)? + val base64encode: ((input: String) -> String)? +} + +external interface FileWatcher { + fun close() +} + +external fun getNodeMajorVersion(): Number? + +external var sys: System + +external interface Scanner { + fun getStartPos(): Number + fun getToken(): SyntaxKind + fun getTextPos(): Number + fun getTokenPos(): Number + fun getTokenText(): String + fun getTokenValue(): String + fun hasUnicodeEscape(): Boolean + fun hasExtendedUnicodeEscape(): Boolean + fun hasPrecedingLineBreak(): Boolean + fun isIdentifier(): Boolean + fun isReservedWord(): Boolean + fun isUnterminated(): Boolean + fun reScanGreaterToken(): SyntaxKind + fun reScanSlashToken(): SyntaxKind + fun reScanAsteriskEqualsToken(): SyntaxKind + fun reScanTemplateToken(isTaggedTemplate: Boolean): SyntaxKind + fun reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind + fun scanJsxIdentifier(): SyntaxKind + fun scanJsxAttributeValue(): SyntaxKind + fun reScanJsxAttributeValue(): SyntaxKind + fun reScanJsxToken(allowMultilineJsxText: Boolean = definedExternally): dynamic /* SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken */ + fun reScanLessThanToken(): SyntaxKind + fun reScanHashToken(): SyntaxKind + fun reScanQuestionToken(): SyntaxKind + fun reScanInvalidIdentifier(): SyntaxKind + fun scanJsxToken(): dynamic /* SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken */ + fun scanJsDocToken(): dynamic /* SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.HashToken | SyntaxKind.Unknown | SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IntrinsicKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.OverrideKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword */ + fun scan(): SyntaxKind + fun getText(): String + fun setText(text: String?, start: Number = definedExternally, length: Number = definedExternally) + fun setOnError(onError: ErrorCallback?) + fun setScriptTarget(scriptTarget: ScriptTarget) + fun setLanguageVariant(variant: LanguageVariant) + fun setTextPos(textPos: Number) + fun lookAhead(callback: () -> T): T + fun scanRange(start: Number, length: Number, callback: () -> T): T + fun tryScan(callback: () -> T): T +} + +external fun tokenToString(t: SyntaxKind): String? + +external fun getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: Number, character: Number): Number + +external fun getLineAndCharacterOfPosition(sourceFile: SourceFileLike, position: Number): LineAndCharacter + +external fun isWhiteSpaceLike(ch: Number): Boolean + +external fun isWhiteSpaceSingleLine(ch: Number): Boolean + +external fun isLineBreak(ch: Number): Boolean + +external fun couldStartTrivia(text: String, pos: Number): Boolean + +external fun forEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean) -> U): U? + +external fun forEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T) -> U, state: T): U? + +external fun forEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean) -> U): U? + +external fun forEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T) -> U, state: T): U? + +external fun reduceEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T, memo: U) -> U, state: T, initial: U): U? + +external fun reduceEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T, memo: U) -> U, state: T, initial: U): U? + +external fun getLeadingCommentRanges(text: String, pos: Number): Array? + +external fun getTrailingCommentRanges(text: String, pos: Number): Array? + +external fun getShebang(text: String): String? + +external fun isIdentifierStart(ch: Number, languageVersion: ScriptTarget?): Boolean + +external fun isIdentifierPart(ch: Number, languageVersion: ScriptTarget?, identifierVariant: LanguageVariant = definedExternally): Boolean + +external fun createScanner(languageVersion: ScriptTarget, skipTrivia: Boolean, languageVariant: LanguageVariant = definedExternally, textInitial: String = definedExternally, onError: ErrorCallback = definedExternally, start: Number = definedExternally, length: Number = definedExternally): Scanner + +external fun isExternalModuleNameRelative(moduleName: String): Boolean + +external fun sortAndDeduplicateDiagnostics(diagnostics: Array): SortedReadonlyArray + +external fun getDefaultLibFileName(options: CompilerOptions): String + +external fun textSpanEnd(span: TextSpan): Number + +external fun textSpanIsEmpty(span: TextSpan): Boolean + +external fun textSpanContainsPosition(span: TextSpan, position: Number): Boolean + +external fun textSpanContainsTextSpan(span: TextSpan, other: TextSpan): Boolean + +external fun textSpanOverlapsWith(span: TextSpan, other: TextSpan): Boolean + +external fun textSpanOverlap(span1: TextSpan, span2: TextSpan): TextSpan? + +external fun textSpanIntersectsWithTextSpan(span: TextSpan, other: TextSpan): Boolean + +external fun textSpanIntersectsWith(span: TextSpan, start: Number, length: Number): Boolean + +external fun decodedTextSpanIntersectsWith(start1: Number, length1: Number, start2: Number, length2: Number): Boolean + +external fun textSpanIntersectsWithPosition(span: TextSpan, position: Number): Boolean + +external fun textSpanIntersection(span1: TextSpan, span2: TextSpan): TextSpan? + +external fun createTextSpan(start: Number, length: Number): TextSpan + +external fun createTextSpanFromBounds(start: Number, end: Number): TextSpan + +external fun textChangeRangeNewSpan(range: TextChangeRange): TextSpan + +external fun textChangeRangeIsUnchanged(range: TextChangeRange): Boolean + +external fun createTextChangeRange(span: TextSpan, newLength: Number): TextChangeRange + +external var unchangedTextChangeRange: TextChangeRange + +external fun collapseTextChangeRangesAcrossMultipleVersions(changes: Array): TextChangeRange + +external fun getTypeParameterOwner(d: Declaration): Declaration? + +external interface `T$23` { + var parent: ConstructorDeclaration + var name: Identifier +} + +external fun isParameterPropertyDeclaration(node: Node, parent: Node): Boolean + +external fun isEmptyBindingPattern(node: Identifier): Boolean + +external fun isEmptyBindingPattern(node: ObjectBindingPattern): Boolean + +external fun isEmptyBindingPattern(node: ArrayBindingPattern): Boolean + +external fun isEmptyBindingElement(node: BindingElement): Boolean + +external fun walkUpBindingElementsAndPatterns(binding: BindingElement): dynamic /* VariableDeclaration | ParameterDeclaration */ + +external fun getCombinedModifierFlags(node: Declaration): ModifierFlags + +external fun getCombinedNodeFlags(node: Node): NodeFlags + +external interface `T$24` { + fun getExecutingFilePath(): String + fun resolvePath(path: String): String + fun fileExists(fileName: String): Boolean + fun readFile(fileName: String): String? +} + +external fun validateLocaleAndSetLanguage(locale: String, sys: `T$24`, errors: Push = definedExternally) + +external fun getOriginalNode(node: Node): Node + +external fun getOriginalNode(node: Node, nodeTest: (node: Node) -> Boolean): T + +external fun getOriginalNode(node: Node?): Node? + +external fun getOriginalNode(node: Node?, nodeTest: (node: Node?) -> Boolean): T? + +external fun findAncestor(node: Node?, callback: (element: Node) -> Boolean): T? + +external fun findAncestor(node: Node?, callback: (element: Node) -> Any): Node? + +external fun isParseTreeNode(node: Node): Boolean + +external fun getParseTreeNode(node: Node?): Node? + +external fun getParseTreeNode(node: T?, nodeTest: (node: Node) -> Boolean = definedExternally): T? + +external fun getParseTreeNode(node: T?): T? + +external fun escapeLeadingUnderscores(identifier: String): dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ + +external fun unescapeLeadingUnderscores(identifier: String /* String & `T$8` */): String + +external fun unescapeLeadingUnderscores(identifier: Unit /* Unit & `T$8` */): String + +external fun unescapeLeadingUnderscores(identifier: InternalSymbolName): String + +external fun idText(identifierOrPrivateName: Identifier): String + +external fun idText(identifierOrPrivateName: PrivateIdentifier): String + +external fun symbolName(symbol: Symbol): String + +external fun getNameOfJSDocTypedef(declaration: JSDocTypedefTag): dynamic /* Identifier? | PrivateIdentifier? */ + +external fun getNameOfDeclaration(declaration: Declaration?): dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ + +external fun getNameOfDeclaration(declaration: Expression?): dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ + +external fun getJSDocParameterTags(param: ParameterDeclaration): Array + +external fun getJSDocTypeParameterTags(param: TypeParameterDeclaration): Array + +external fun hasJSDocParameterTags(node: FunctionDeclaration): Boolean + +external fun hasJSDocParameterTags(node: MethodDeclaration): Boolean + +external fun hasJSDocParameterTags(node: GetAccessorDeclaration): Boolean + +external fun hasJSDocParameterTags(node: SetAccessorDeclaration): Boolean + +external fun hasJSDocParameterTags(node: ConstructorDeclaration): Boolean + +external fun hasJSDocParameterTags(node: FunctionExpression): Boolean + +external fun hasJSDocParameterTags(node: ArrowFunction): Boolean + +external fun hasJSDocParameterTags(node: CallSignatureDeclaration): Boolean + +external fun hasJSDocParameterTags(node: ConstructSignatureDeclaration): Boolean + +external fun hasJSDocParameterTags(node: MethodSignature): Boolean + +external fun hasJSDocParameterTags(node: IndexSignatureDeclaration): Boolean + +external fun hasJSDocParameterTags(node: FunctionTypeNode): Boolean + +external fun hasJSDocParameterTags(node: ConstructorTypeNode): Boolean + +external fun hasJSDocParameterTags(node: JSDocFunctionType): Boolean + +external fun getJSDocAugmentsTag(node: Node): JSDocAugmentsTag? + +external fun getJSDocImplementsTags(node: Node): Array + +external fun getJSDocClassTag(node: Node): JSDocClassTag? + +external fun getJSDocPublicTag(node: Node): JSDocPublicTag? + +external fun getJSDocPrivateTag(node: Node): JSDocPrivateTag? + +external fun getJSDocProtectedTag(node: Node): JSDocProtectedTag? + +external fun getJSDocReadonlyTag(node: Node): JSDocReadonlyTag? + +external fun getJSDocOverrideTagNoCache(node: Node): JSDocOverrideTag? + +external fun getJSDocDeprecatedTag(node: Node): JSDocDeprecatedTag? + +external fun getJSDocEnumTag(node: Node): JSDocEnumTag? + +external fun getJSDocThisTag(node: Node): JSDocThisTag? + +external fun getJSDocReturnTag(node: Node): JSDocReturnTag? + +external fun getJSDocTemplateTag(node: Node): JSDocTemplateTag? + +external fun getJSDocTypeTag(node: Node): JSDocTypeTag? + +external fun getJSDocType(node: Node): TypeNode? + +external fun getJSDocReturnType(node: Node): TypeNode? + +external fun getJSDocTags(node: Node): Array + +external fun getAllJSDocTags(node: Node, predicate: (tag: JSDocTag) -> Boolean): Array + +external fun getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): Array + +external fun getTextOfJSDocComment(comment: String = definedExternally): String? + +external fun getTextOfJSDocComment(): String? + +external fun getTextOfJSDocComment(comment: NodeArray = definedExternally): String? + +external fun getEffectiveTypeParameterDeclarations(node: Any /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature */): Array + +external fun getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode? + +external fun isMemberName(node: Node): Boolean + +external fun isPropertyAccessChain(node: Node): Boolean + +external fun isElementAccessChain(node: Node): Boolean + +external fun isCallChain(node: Node): Boolean + +external fun isOptionalChain(node: Node): Boolean + +external fun isNullishCoalesce(node: Node): Boolean + +external fun isConstTypeReference(node: Node): Boolean + +external fun skipPartiallyEmittedExpressions(node: Expression): Expression + +external fun skipPartiallyEmittedExpressions(node: Node): Node + +external fun isNonNullChain(node: Node): Boolean + +external fun isBreakOrContinueStatement(node: Node): Boolean + +external fun isNamedExportBindings(node: Node): Boolean + +external fun isUnparsedTextLike(node: Node): Boolean + +external fun isUnparsedNode(node: Node): Boolean + +external fun isJSDocPropertyLikeTag(node: Node): Boolean + +external fun isTokenKind(kind: SyntaxKind): Boolean + +external fun isToken(n: Node): Boolean + +external fun isLiteralExpression(node: Node): Boolean + +external fun isTemplateLiteralToken(node: Node): Boolean + +external fun isTemplateMiddleOrTemplateTail(node: Node): Boolean + +external fun isImportOrExportSpecifier(node: Node): Boolean + +external fun isTypeOnlyImportOrExportDeclaration(node: Node): Boolean + +external fun isStringTextContainingNode(node: Node): Boolean + +external fun isModifier(node: Node): Boolean + +external fun isEntityName(node: Node): Boolean + +external fun isPropertyName(node: Node): Boolean + +external fun isBindingName(node: Node): Boolean + +external fun isFunctionLike(node: Node?): Boolean + +external fun isClassElement(node: Node): Boolean + +external fun isClassLike(node: Node): Boolean + +external fun isAccessor(node: Node): Boolean + +external fun isTypeElement(node: Node): Boolean + +external fun isClassOrTypeElement(node: Node): Boolean + +external fun isObjectLiteralElementLike(node: Node): Boolean + +external fun isTypeNode(node: Node): Boolean + +external fun isFunctionOrConstructorTypeNode(node: Node): Boolean + +external fun isPropertyAccessOrQualifiedName(node: Node): Boolean + +external fun isCallLikeExpression(node: Node): Boolean + +external fun isCallOrNewExpression(node: Node): Boolean + +external fun isTemplateLiteral(node: Node): Boolean + +external fun isAssertionExpression(node: Node): Boolean + +external fun isIterationStatement(node: Node, lookInLabeledStatements: Boolean): Boolean + +external fun isJsxOpeningLikeElement(node: Node): Boolean + +external fun isCaseOrDefaultClause(node: Node): Boolean + +external fun isJSDocCommentContainingNode(node: Node): Boolean + +external fun isSetAccessor(node: Node): Boolean + +external fun isGetAccessor(node: Node): Boolean + +external fun hasOnlyExpressionInitializer(node: Node): Boolean + +external fun isObjectLiteralElement(node: Node): Boolean + +external fun isStringLiteralLike(node: Node): Boolean + +external fun isJSDocLinkLike(node: Node): Boolean + +external var factory: NodeFactory + +external fun createUnparsedSourceFile(text: String): UnparsedSource + +external fun createUnparsedSourceFile(inputFile: InputFiles, type: String /* "js" | "dts" */, stripInternal: Boolean = definedExternally): UnparsedSource + +external fun createUnparsedSourceFile(inputFile: InputFiles, type: String /* "js" | "dts" */): UnparsedSource + +external fun createUnparsedSourceFile(text: String, mapPath: String?, map: String?): UnparsedSource + +external fun createInputFiles(javascriptText: String, declarationText: String): InputFiles + +external fun createInputFiles(readFileText: (path: String) -> String?, javascriptPath: String, javascriptMapPath: String?, declarationPath: String, declarationMapPath: String?, buildInfoPath: String?): InputFiles + +external fun createInputFiles(javascriptText: String, declarationText: String, javascriptMapPath: String?, javascriptMapText: String?, declarationMapPath: String?, declarationMapText: String?): InputFiles + +external fun createSourceMapSource(fileName: String, text: String, skipTrivia: (pos: Number) -> Number = definedExternally): SourceMapSource + +external fun setOriginalNode(node: T, original: Node?): T + +external fun disposeEmitNodes(sourceFile: SourceFile?) + +external fun setEmitFlags(node: T, emitFlags: EmitFlags): T + +external fun getSourceMapRange(node: Node): SourceMapRange + +external fun setSourceMapRange(node: T, range: SourceMapRange?): T + +external fun getTokenSourceMapRange(node: Node, token: SyntaxKind): SourceMapRange? + +external fun setTokenSourceMapRange(node: T, token: SyntaxKind, range: SourceMapRange?): T + +external fun getCommentRange(node: Node): TextRange + +external fun setCommentRange(node: T, range: TextRange): T + +external fun getSyntheticLeadingComments(node: Node): Array? + +external fun setSyntheticLeadingComments(node: T, comments: Array?): T + +external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T + +external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String): T + +external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T + +external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String): T + +external fun getSyntheticTrailingComments(node: Node): Array? + +external fun setSyntheticTrailingComments(node: T, comments: Array?): T + +external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T + +external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String): T + +external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T + +external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String): T + +external fun moveSyntheticComments(node: T, original: Node): T + +external fun getConstantValue(node: PropertyAccessExpression): dynamic /* String? | Number? */ + +external fun getConstantValue(node: ElementAccessExpression): dynamic /* String? | Number? */ + +external fun setConstantValue(node: PropertyAccessExpression, value: String): dynamic /* PropertyAccessExpression | ElementAccessExpression */ + +external fun setConstantValue(node: PropertyAccessExpression, value: Number): dynamic /* PropertyAccessExpression | ElementAccessExpression */ + +external fun setConstantValue(node: ElementAccessExpression, value: String): dynamic /* PropertyAccessExpression | ElementAccessExpression */ + +external fun setConstantValue(node: ElementAccessExpression, value: Number): dynamic /* PropertyAccessExpression | ElementAccessExpression */ + +external fun addEmitHelper(node: T, helper: ScopedEmitHelper): T + +external fun addEmitHelper(node: T, helper: UnscopedEmitHelper): T + +external fun addEmitHelpers(node: T, helpers: Array?): T + +external fun removeEmitHelper(node: Node, helper: ScopedEmitHelper): Boolean + +external fun removeEmitHelper(node: Node, helper: UnscopedEmitHelper): Boolean + +external fun getEmitHelpers(node: Node): Array? + +external fun moveEmitHelpers(source: Node, target: Node, predicate: (helper: Any /* ScopedEmitHelper | UnscopedEmitHelper */) -> Boolean) + +external fun isNumericLiteral(node: Node): Boolean + +external fun isBigIntLiteral(node: Node): Boolean + +external fun isStringLiteral(node: Node): Boolean + +external fun isJsxText(node: Node): Boolean + +external fun isRegularExpressionLiteral(node: Node): Boolean + +external fun isNoSubstitutionTemplateLiteral(node: Node): Boolean + +external fun isTemplateHead(node: Node): Boolean + +external fun isTemplateMiddle(node: Node): Boolean + +external fun isTemplateTail(node: Node): Boolean + +external fun isDotDotDotToken(node: Node): Boolean + +external fun isPlusToken(node: Node): Boolean + +external fun isMinusToken(node: Node): Boolean + +external fun isAsteriskToken(node: Node): Boolean + +external fun isIdentifier(node: Node): Boolean + +external fun isPrivateIdentifier(node: Node): Boolean + +external fun isQualifiedName(node: Node): Boolean + +external fun isComputedPropertyName(node: Node): Boolean + +external fun isTypeParameterDeclaration(node: Node): Boolean + +external fun isParameter(node: Node): Boolean + +external fun isDecorator(node: Node): Boolean + +external fun isPropertySignature(node: Node): Boolean + +external fun isPropertyDeclaration(node: Node): Boolean + +external fun isMethodSignature(node: Node): Boolean + +external fun isMethodDeclaration(node: Node): Boolean + +external fun isClassStaticBlockDeclaration(node: Node): Boolean + +external fun isConstructorDeclaration(node: Node): Boolean + +external fun isGetAccessorDeclaration(node: Node): Boolean + +external fun isSetAccessorDeclaration(node: Node): Boolean + +external fun isCallSignatureDeclaration(node: Node): Boolean + +external fun isConstructSignatureDeclaration(node: Node): Boolean + +external fun isIndexSignatureDeclaration(node: Node): Boolean + +external fun isTypePredicateNode(node: Node): Boolean + +external fun isTypeReferenceNode(node: Node): Boolean + +external fun isFunctionTypeNode(node: Node): Boolean + +external fun isConstructorTypeNode(node: Node): Boolean + +external fun isTypeQueryNode(node: Node): Boolean + +external fun isTypeLiteralNode(node: Node): Boolean + +external fun isArrayTypeNode(node: Node): Boolean + +external fun isTupleTypeNode(node: Node): Boolean + +external fun isNamedTupleMember(node: Node): Boolean + +external fun isOptionalTypeNode(node: Node): Boolean + +external fun isRestTypeNode(node: Node): Boolean + +external fun isUnionTypeNode(node: Node): Boolean + +external fun isIntersectionTypeNode(node: Node): Boolean + +external fun isConditionalTypeNode(node: Node): Boolean + +external fun isInferTypeNode(node: Node): Boolean + +external fun isParenthesizedTypeNode(node: Node): Boolean + +external fun isThisTypeNode(node: Node): Boolean + +external fun isTypeOperatorNode(node: Node): Boolean + +external fun isIndexedAccessTypeNode(node: Node): Boolean + +external fun isMappedTypeNode(node: Node): Boolean + +external fun isLiteralTypeNode(node: Node): Boolean + +external fun isImportTypeNode(node: Node): Boolean + +external fun isTemplateLiteralTypeSpan(node: Node): Boolean + +external fun isTemplateLiteralTypeNode(node: Node): Boolean + +external fun isObjectBindingPattern(node: Node): Boolean + +external fun isArrayBindingPattern(node: Node): Boolean + +external fun isBindingElement(node: Node): Boolean + +external fun isArrayLiteralExpression(node: Node): Boolean + +external fun isObjectLiteralExpression(node: Node): Boolean + +external fun isPropertyAccessExpression(node: Node): Boolean + +external fun isElementAccessExpression(node: Node): Boolean + +external fun isCallExpression(node: Node): Boolean + +external fun isNewExpression(node: Node): Boolean + +external fun isTaggedTemplateExpression(node: Node): Boolean + +external fun isTypeAssertionExpression(node: Node): Boolean + +external fun isParenthesizedExpression(node: Node): Boolean + +external fun isFunctionExpression(node: Node): Boolean + +external fun isArrowFunction(node: Node): Boolean + +external fun isDeleteExpression(node: Node): Boolean + +external fun isTypeOfExpression(node: Node): Boolean + +external fun isVoidExpression(node: Node): Boolean + +external fun isAwaitExpression(node: Node): Boolean + +external fun isPrefixUnaryExpression(node: Node): Boolean + +external fun isPostfixUnaryExpression(node: Node): Boolean + +external fun isBinaryExpression(node: Node): Boolean + +external fun isConditionalExpression(node: Node): Boolean + +external fun isTemplateExpression(node: Node): Boolean + +external fun isYieldExpression(node: Node): Boolean + +external fun isSpreadElement(node: Node): Boolean + +external fun isClassExpression(node: Node): Boolean + +external fun isOmittedExpression(node: Node): Boolean + +external fun isExpressionWithTypeArguments(node: Node): Boolean + +external fun isAsExpression(node: Node): Boolean + +external fun isNonNullExpression(node: Node): Boolean + +external fun isMetaProperty(node: Node): Boolean + +external fun isSyntheticExpression(node: Node): Boolean + +external fun isPartiallyEmittedExpression(node: Node): Boolean + +external fun isCommaListExpression(node: Node): Boolean + +external fun isTemplateSpan(node: Node): Boolean + +external fun isSemicolonClassElement(node: Node): Boolean + +external fun isBlock(node: Node): Boolean + +external fun isVariableStatement(node: Node): Boolean + +external fun isEmptyStatement(node: Node): Boolean + +external fun isExpressionStatement(node: Node): Boolean + +external fun isIfStatement(node: Node): Boolean + +external fun isDoStatement(node: Node): Boolean + +external fun isWhileStatement(node: Node): Boolean + +external fun isForStatement(node: Node): Boolean + +external fun isForInStatement(node: Node): Boolean + +external fun isForOfStatement(node: Node): Boolean + +external fun isContinueStatement(node: Node): Boolean + +external fun isBreakStatement(node: Node): Boolean + +external fun isReturnStatement(node: Node): Boolean + +external fun isWithStatement(node: Node): Boolean + +external fun isSwitchStatement(node: Node): Boolean + +external fun isLabeledStatement(node: Node): Boolean + +external fun isThrowStatement(node: Node): Boolean + +external fun isTryStatement(node: Node): Boolean + +external fun isDebuggerStatement(node: Node): Boolean + +external fun isVariableDeclaration(node: Node): Boolean + +external fun isVariableDeclarationList(node: Node): Boolean + +external fun isFunctionDeclaration(node: Node): Boolean + +external fun isClassDeclaration(node: Node): Boolean + +external fun isInterfaceDeclaration(node: Node): Boolean + +external fun isTypeAliasDeclaration(node: Node): Boolean + +external fun isEnumDeclaration(node: Node): Boolean + +external fun isModuleDeclaration(node: Node): Boolean + +external fun isModuleBlock(node: Node): Boolean + +external fun isCaseBlock(node: Node): Boolean + +external fun isNamespaceExportDeclaration(node: Node): Boolean + +external fun isImportEqualsDeclaration(node: Node): Boolean + +external fun isImportDeclaration(node: Node): Boolean + +external fun isImportClause(node: Node): Boolean + +external fun isNamespaceImport(node: Node): Boolean + +external fun isNamespaceExport(node: Node): Boolean + +external fun isNamedImports(node: Node): Boolean + +external fun isImportSpecifier(node: Node): Boolean + +external fun isExportAssignment(node: Node): Boolean + +external fun isExportDeclaration(node: Node): Boolean + +external fun isNamedExports(node: Node): Boolean + +external fun isExportSpecifier(node: Node): Boolean + +external fun isMissingDeclaration(node: Node): Boolean + +external fun isNotEmittedStatement(node: Node): Boolean + +external fun isExternalModuleReference(node: Node): Boolean + +external fun isJsxElement(node: Node): Boolean + +external fun isJsxSelfClosingElement(node: Node): Boolean + +external fun isJsxOpeningElement(node: Node): Boolean + +external fun isJsxClosingElement(node: Node): Boolean + +external fun isJsxFragment(node: Node): Boolean + +external fun isJsxOpeningFragment(node: Node): Boolean + +external fun isJsxClosingFragment(node: Node): Boolean + +external fun isJsxAttribute(node: Node): Boolean + +external fun isJsxAttributes(node: Node): Boolean + +external fun isJsxSpreadAttribute(node: Node): Boolean + +external fun isJsxExpression(node: Node): Boolean + +external fun isCaseClause(node: Node): Boolean + +external fun isDefaultClause(node: Node): Boolean + +external fun isHeritageClause(node: Node): Boolean + +external fun isCatchClause(node: Node): Boolean + +external fun isPropertyAssignment(node: Node): Boolean + +external fun isShorthandPropertyAssignment(node: Node): Boolean + +external fun isSpreadAssignment(node: Node): Boolean + +external fun isEnumMember(node: Node): Boolean + +external fun isUnparsedPrepend(node: Node): Boolean + +external fun isSourceFile(node: Node): Boolean + +external fun isBundle(node: Node): Boolean + +external fun isUnparsedSource(node: Node): Boolean + +external fun isJSDocTypeExpression(node: Node): Boolean + +external fun isJSDocNameReference(node: Node): Boolean + +external fun isJSDocMemberName(node: Node): Boolean + +external fun isJSDocLink(node: Node): Boolean + +external fun isJSDocLinkCode(node: Node): Boolean + +external fun isJSDocLinkPlain(node: Node): Boolean + +external fun isJSDocAllType(node: Node): Boolean + +external fun isJSDocUnknownType(node: Node): Boolean + +external fun isJSDocNullableType(node: Node): Boolean + +external fun isJSDocNonNullableType(node: Node): Boolean + +external fun isJSDocOptionalType(node: Node): Boolean + +external fun isJSDocFunctionType(node: Node): Boolean + +external fun isJSDocVariadicType(node: Node): Boolean + +external fun isJSDocNamepathType(node: Node): Boolean + +external fun isJSDoc(node: Node): Boolean + +external fun isJSDocTypeLiteral(node: Node): Boolean + +external fun isJSDocSignature(node: Node): Boolean + +external fun isJSDocAugmentsTag(node: Node): Boolean + +external fun isJSDocAuthorTag(node: Node): Boolean + +external fun isJSDocClassTag(node: Node): Boolean + +external fun isJSDocCallbackTag(node: Node): Boolean + +external fun isJSDocPublicTag(node: Node): Boolean + +external fun isJSDocPrivateTag(node: Node): Boolean + +external fun isJSDocProtectedTag(node: Node): Boolean + +external fun isJSDocReadonlyTag(node: Node): Boolean + +external fun isJSDocOverrideTag(node: Node): Boolean + +external fun isJSDocDeprecatedTag(node: Node): Boolean + +external fun isJSDocSeeTag(node: Node): Boolean + +external fun isJSDocEnumTag(node: Node): Boolean + +external fun isJSDocParameterTag(node: Node): Boolean + +external fun isJSDocReturnTag(node: Node): Boolean + +external fun isJSDocThisTag(node: Node): Boolean + +external fun isJSDocTypeTag(node: Node): Boolean + +external fun isJSDocTemplateTag(node: Node): Boolean + +external fun isJSDocTypedefTag(node: Node): Boolean + +external fun isJSDocUnknownTag(node: Node): Boolean + +external fun isJSDocPropertyTag(node: Node): Boolean + +external fun isJSDocImplementsTag(node: Node): Boolean + +external fun setTextRange(range: T, location: TextRange?): T + +external fun forEachChild(node: Node, cbNode: (node: Node) -> T?, cbNodes: (nodes: NodeArray) -> T? = definedExternally): T? + +external fun createSourceFile(fileName: String, sourceText: String, languageVersion: ScriptTarget, setParentNodes: Boolean = definedExternally, scriptKind: ScriptKind = definedExternally): SourceFile + +external fun parseIsolatedEntityName(text: String, languageVersion: ScriptTarget): dynamic /* Identifier? | QualifiedName? */ + +external fun parseJsonText(fileName: String, sourceText: String): JsonSourceFile + +external fun isExternalModule(file: SourceFile): Boolean + +external fun updateSourceFile(sourceFile: SourceFile, newText: String, textChangeRange: TextChangeRange, aggressiveChecks: Boolean = definedExternally): SourceFile + +external fun parseCommandLine(commandLine: Array, readFile: (path: String) -> String? = definedExternally): ParsedCommandLine + +external interface ConfigFileDiagnosticsReporter { + var onUnRecoverableConfigFileDiagnostic: DiagnosticReporter +} + +external interface ParseConfigFileHost : ParseConfigHost, ConfigFileDiagnosticsReporter { + fun getCurrentDirectory(): String +} + +external fun getParsedCommandLineOfConfigFile(configFileName: String, optionsToExtend: CompilerOptions?, host: ParseConfigFileHost, extendedConfigCache: Map = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): ParsedCommandLine? + +external interface `T$25` { + var config: Any? + get() = definedExternally + set(value) = definedExternally + var error: Diagnostic? + get() = definedExternally + set(value) = definedExternally +} + +external fun readConfigFile(fileName: String, readFile: (path: String) -> String?): `T$25` + +external fun parseConfigFileTextToJson(fileName: String, jsonText: String): `T$25` + +external fun readJsonConfigFile(fileName: String, readFile: (path: String) -> String?): TsConfigSourceFile + +external fun convertToObject(sourceFile: JsonSourceFile, errors: Push): Any + +external fun parseJsonConfigFileContent(json: Any, host: ParseConfigHost, basePath: String, existingOptions: CompilerOptions = definedExternally, configFileName: String = definedExternally, resolutionStack: Array = definedExternally, extraFileExtensions: Array = definedExternally, extendedConfigCache: Map = definedExternally, existingWatchOptions: WatchOptions = definedExternally): ParsedCommandLine + +external fun parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: String, existingOptions: CompilerOptions = definedExternally, configFileName: String = definedExternally, resolutionStack: Array = definedExternally, extraFileExtensions: Array = definedExternally, extendedConfigCache: Map = definedExternally, existingWatchOptions: WatchOptions = definedExternally): ParsedCommandLine + +external interface ParsedTsconfig { + var raw: Any + var options: CompilerOptions? + get() = definedExternally + set(value) = definedExternally + var watchOptions: WatchOptions? + get() = definedExternally + set(value) = definedExternally + var typeAcquisition: TypeAcquisition? + get() = definedExternally + set(value) = definedExternally + var extendedConfigPath: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface ExtendedConfigCacheEntry { + var extendedResult: TsConfigSourceFile + var extendedConfig: ParsedTsconfig? +} + +external interface `T$26` { + var options: CompilerOptions + var errors: Array +} + +external fun convertCompilerOptionsFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$26` + +external interface `T$27` { + var options: TypeAcquisition + var errors: Array +} + +external fun convertTypeAcquisitionFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$27` + +external fun getEffectiveTypeRoots(options: CompilerOptions, host: GetEffectiveTypeRootsHost): Array? + +external fun resolveTypeReferenceDirective(typeReferenceDirectiveName: String, containingFile: String?, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference: ResolvedProjectReference = definedExternally, cache: TypeReferenceDirectiveResolutionCache = definedExternally): ResolvedTypeReferenceDirectiveWithFailedLookupLocations + +external fun getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): Array + +external interface TypeReferenceDirectiveResolutionCache : PerDirectoryResolutionCache, PackageJsonInfoCache + +external interface PerDirectoryResolutionCache { + fun getOrCreateCacheForDirectory(directoryName: String, redirectedReference: ResolvedProjectReference = definedExternally): Map + fun clear() + fun update(options: CompilerOptions) +} + +external interface ModuleResolutionCache : PerDirectoryResolutionCache, NonRelativeModuleNameResolutionCache, PackageJsonInfoCache { + fun getPackageJsonInfoCache(): PackageJsonInfoCache +} + +external interface NonRelativeModuleNameResolutionCache : PackageJsonInfoCache { + fun getOrCreateCacheForModuleName(nonRelativeModuleName: String, redirectedReference: ResolvedProjectReference = definedExternally): PerModuleNameCache +} + +external interface PackageJsonInfoCache { + fun clear() +} + +external interface PerModuleNameCache { + fun get(directory: String): ResolvedModuleWithFailedLookupLocations? + fun set(directory: String, result: ResolvedModuleWithFailedLookupLocations) +} + +external fun createModuleResolutionCache(currentDirectory: String, getCanonicalFileName: (s: String) -> String, options: CompilerOptions = definedExternally): ModuleResolutionCache + +external fun createTypeReferenceDirectiveResolutionCache(currentDirectory: String, getCanonicalFileName: (s: String) -> String, options: CompilerOptions = definedExternally, packageJsonInfoCache: PackageJsonInfoCache = definedExternally): TypeReferenceDirectiveResolutionCache + +external fun resolveModuleNameFromCache(moduleName: String, containingFile: String, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations? + +external fun resolveModuleName(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations + +external fun nodeModuleNameResolver(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations + +external fun classicNameResolver(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: NonRelativeModuleNameResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations + +external fun visitNode(node: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T + +external fun visitNode(node: T, visitor: Visitor?): T + +external fun visitNode(node: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T + +external fun visitNode(node: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T? + +external fun visitNode(node: T?, visitor: Visitor?): T? + +external fun visitNode(node: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T? + +external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray + +external fun visitNodes(nodes: NodeArray, visitor: Visitor?): NodeArray + +external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray + +external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray + +external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray? + +external fun visitNodes(nodes: NodeArray?, visitor: Visitor?): NodeArray? + +external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray? + +external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray? + +external fun visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start: Number = definedExternally, ensureUseStrict: Boolean = definedExternally, nodesVisitor: NodesVisitor = definedExternally): NodeArray + +external fun visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor = definedExternally): NodeArray + +external fun visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext): NodeArray + +external fun visitParameterList(nodes: NodeArray?, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor = definedExternally): NodeArray? + +external fun visitParameterList(nodes: NodeArray?, visitor: Visitor, context: TransformationContext): NodeArray? + +external fun visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): dynamic /* FunctionBody */ + +external fun visitFunctionBody(node: Expression, visitor: Visitor, context: TransformationContext): dynamic /* FunctionBody | Expression */ + +external fun visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement + +external fun visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T + +external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext, nodesVisitor: Any = definedExternally, tokenVisitor: Visitor = definedExternally): T? + +external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext): T? + +external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext, nodesVisitor: Any = definedExternally): T? + +external fun getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): String? + +external fun getOutputFileNames(commandLine: ParsedCommandLine, inputFileName: String, ignoreCase: Boolean): Array + +external fun createPrinter(printerOptions: PrinterOptions = definedExternally, handlers: PrintHandlers = definedExternally): Printer + +external fun findConfigFile(searchPath: String, fileExists: (fileName: String) -> Boolean, configName: String = definedExternally): String? + +external fun resolveTripleslashReference(moduleName: String, containingFile: String): String + +external fun createCompilerHost(options: CompilerOptions, setParentNodes: Boolean = definedExternally): CompilerHost + +external fun getPreEmitDiagnostics(program: Program, sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + +external interface FormatDiagnosticsHost { + fun getCurrentDirectory(): String + fun getCanonicalFileName(fileName: String): String + fun getNewLine(): String +} + +external fun formatDiagnostics(diagnostics: Array, host: FormatDiagnosticsHost): String + +external fun formatDiagnostic(diagnostic: Diagnostic, host: FormatDiagnosticsHost): String + +external fun formatDiagnosticsWithColorAndContext(diagnostics: Array, host: FormatDiagnosticsHost): String + +external fun flattenDiagnosticMessageText(diag: String?, newLine: String, indent: Number = definedExternally): String + +external fun flattenDiagnosticMessageText(diag: String?, newLine: String): String + +external fun flattenDiagnosticMessageText(diag: DiagnosticMessageChain?, newLine: String, indent: Number = definedExternally): String + +external fun flattenDiagnosticMessageText(diag: DiagnosticMessageChain?, newLine: String): String + +external fun getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): Array + +external fun createProgram(createProgramOptions: CreateProgramOptions): Program + +external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally, oldProgram: Program = definedExternally, configFileParsingDiagnostics: Array = definedExternally): Program + +external fun createProgram(rootNames: Array, options: CompilerOptions): Program + +external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally): Program + +external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally, oldProgram: Program = definedExternally): Program + +external interface ResolveProjectReferencePathHost { + fun fileExists(fileName: String): Boolean +} + +external fun resolveProjectReferencePath(ref: ProjectReference): String /* String & `T$5` */ + +external fun resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): String /* String & `T$5` */ + +external interface EmitOutput { + var outputFiles: Array + var emitSkipped: Boolean +} + +external interface OutputFile { + var name: String + var writeByteOrderMark: Boolean + var text: String +} + +external interface `T$28` { + var result: T + var affected: dynamic /* SourceFile | Program */ + get() = definedExternally + set(value) = definedExternally +} + +external interface BuilderProgramHost { + fun useCaseSensitiveFileNames(): Boolean + var createHash: ((data: String) -> String)? + get() = definedExternally + set(value) = definedExternally + var writeFile: WriteFileCallback? + get() = definedExternally + set(value) = definedExternally +} + +external interface BuilderProgram { + fun getProgram(): Program + fun getCompilerOptions(): CompilerOptions + fun getSourceFile(fileName: String): SourceFile? + fun getSourceFiles(): Array + fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getConfigFileParsingDiagnostics(): Array + fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getDeclarationDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getAllDependencies(sourceFile: SourceFile): Array + fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult + fun getCurrentDirectory(): String +} + +external interface SemanticDiagnosticsBuilderProgram : BuilderProgram { + fun getSemanticDiagnosticsOfNextAffectedFile(cancellationToken: CancellationToken = definedExternally, ignoreSourceFile: (sourceFile: SourceFile) -> Boolean = definedExternally): `T$28`>? +} + +external interface EmitAndSemanticDiagnosticsBuilderProgram : SemanticDiagnosticsBuilderProgram { + fun emitNextAffectedFile(writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): `T$28`? +} + +external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): SemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram + +external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): BuilderProgram + +external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost): BuilderProgram + +external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram: BuilderProgram = definedExternally): BuilderProgram + +external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): BuilderProgram + +external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?): BuilderProgram + +external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): BuilderProgram + +external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally): BuilderProgram + +external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): BuilderProgram + +external interface ReadBuildProgramHost { + fun useCaseSensitiveFileNames(): Boolean + fun getCurrentDirectory(): String + fun readFile(fileName: String): String? +} + +external fun readBuilderProgram(compilerOptions: CompilerOptions, host: ReadBuildProgramHost): EmitAndSemanticDiagnosticsBuilderProgram? + +external fun createIncrementalCompilerHost(options: CompilerOptions, system: System = definedExternally): CompilerHost + +external interface IncrementalProgramOptions { + var rootNames: Array + var options: CompilerOptions + var configFileParsingDiagnostics: Array? + get() = definedExternally + set(value) = definedExternally + var projectReferences: Array? + get() = definedExternally + set(value) = definedExternally + var host: CompilerHost? + get() = definedExternally + set(value) = definedExternally + var createProgram: CreateProgram? + get() = definedExternally + set(value) = definedExternally +} + +external fun createIncrementalProgram(__0: IncrementalProgramOptions): T + +external interface WatchHost { + val onWatchStatusChange: ((diagnostic: Diagnostic, newLine: String, options: CompilerOptions, errorCount: Number) -> Unit)? + fun watchFile(path: String, callback: FileWatcherCallback, pollingInterval: Number = definedExternally, options: CompilerOptions = definedExternally): FileWatcher + fun watchDirectory(path: String, callback: DirectoryWatcherCallback, recursive: Boolean = definedExternally, options: CompilerOptions = definedExternally): FileWatcher + val setTimeout: ((callback: (args: Any) -> Unit, ms: Number, args: Any) -> Any)? + val clearTimeout: ((timeoutId: Any) -> Unit)? +} + +external interface ProgramHost { + var createProgram: CreateProgram + fun useCaseSensitiveFileNames(): Boolean + fun getNewLine(): String + fun getCurrentDirectory(): String + fun getDefaultLibFileName(options: CompilerOptions): String + val getDefaultLibLocation: (() -> String)? + val createHash: ((data: String) -> String)? + fun fileExists(path: String): Boolean + fun readFile(path: String, encoding: String = definedExternally): String? + val directoryExists: ((path: String) -> Boolean)? + val getDirectories: ((path: String) -> Array)? + val readDirectory: ((path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array)? + val realpath: ((path: String) -> String)? + val trace: ((s: String) -> Unit)? + val getEnvironmentVariable: ((name: String) -> String?)? + val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? +} + +external interface WatchCompilerHost : ProgramHost, WatchHost { + val useSourceOfProjectReferenceRedirect: (() -> Boolean)? + val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? + val afterProgramCreate: ((program: T) -> Unit)? +} + +external interface WatchCompilerHostOfFilesAndCompilerOptions : WatchCompilerHost { + var rootFiles: Array + var options: CompilerOptions + var watchOptions: WatchOptions? + get() = definedExternally + set(value) = definedExternally + var projectReferences: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface WatchCompilerHostOfConfigFile : WatchCompilerHost, ConfigFileDiagnosticsReporter { + var configFileName: String + var optionsToExtend: CompilerOptions? + get() = definedExternally + set(value) = definedExternally + var watchOptionsToExtend: WatchOptions? + get() = definedExternally + set(value) = definedExternally + var extraFileExtensions: Array? + get() = definedExternally + set(value) = definedExternally + override var readDirectory: (path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array +} + +external interface Watch { + fun getProgram(): T + fun close() +} + +external interface WatchOfConfigFile : Watch + +external interface WatchOfFilesAndCompilerOptions : Watch { + fun updateRootFileNames(fileNames: Array) +} + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally): WatchCompilerHostOfConfigFile + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, projectReferences: Array = definedExternally, watchOptions: WatchOptions = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, projectReferences: Array = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions + +external fun createWatchProgram(host: WatchCompilerHostOfFilesAndCompilerOptions): WatchOfFilesAndCompilerOptions + +external fun createWatchProgram(host: WatchCompilerHostOfConfigFile): WatchOfConfigFile + +external interface BuildOptions { + var dry: Boolean? + get() = definedExternally + set(value) = definedExternally + var force: Boolean? + get() = definedExternally + set(value) = definedExternally + var verbose: Boolean? + get() = definedExternally + set(value) = definedExternally + var incremental: Boolean? + get() = definedExternally + set(value) = definedExternally + var assumeChangesOnlyAffectDirectDependencies: Boolean? + get() = definedExternally + set(value) = definedExternally + var traceResolution: Boolean? + get() = definedExternally + set(value) = definedExternally + @nativeGetter + operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ + @nativeSetter + operator fun set(option: String, value: String?) + @nativeSetter + operator fun set(option: String, value: Number?) + @nativeSetter + operator fun set(option: String, value: Boolean?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: MapLike>?) + @nativeSetter + operator fun set(option: String, value: Array?) + @nativeSetter + operator fun set(option: String, value: Array?) +} + +external interface SolutionBuilderHostBase : ProgramHost { + val createDirectory: ((path: String) -> Unit)? + val writeFile: ((path: String, data: String, writeByteOrderMark: Boolean) -> Unit)? + var getCustomTransformers: ((project: String) -> CustomTransformers?)? + get() = definedExternally + set(value) = definedExternally + fun getModifiedTime(fileName: String): Date? + fun setModifiedTime(fileName: String, date: Date) + fun deleteFile(fileName: String) + val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? + var reportDiagnostic: DiagnosticReporter + var reportSolutionBuilderStatus: DiagnosticReporter + val afterProgramEmitAndDiagnostics: ((program: T) -> Unit)? +} + +external interface SolutionBuilderHost : SolutionBuilderHostBase { + var reportErrorSummary: ReportEmitErrorSummary? + get() = definedExternally + set(value) = definedExternally +} + +external interface SolutionBuilderWithWatchHost : SolutionBuilderHostBase, WatchHost + +external interface SolutionBuilder { + fun build(project: String = definedExternally, cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, getCustomTransformers: (project: String) -> CustomTransformers = definedExternally): ExitStatus + fun clean(project: String = definedExternally): ExitStatus + fun buildReferences(project: String, cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, getCustomTransformers: (project: String) -> CustomTransformers = definedExternally): ExitStatus + fun cleanReferences(project: String = definedExternally): ExitStatus + fun getNextInvalidatedProject(cancellationToken: CancellationToken = definedExternally): dynamic /* UpdateOutputFileStampsProject? | BuildInvalidedProject? | UpdateBundleProject? */ +} + +external fun createBuilderStatusReporter(system: System, pretty: Boolean = definedExternally): DiagnosticReporter + +external fun createSolutionBuilderHost(system: System = definedExternally, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportSolutionBuilderStatus: DiagnosticReporter = definedExternally, reportErrorSummary: ReportEmitErrorSummary = definedExternally): SolutionBuilderHost + +external fun createSolutionBuilderWithWatchHost(system: System = definedExternally, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportSolutionBuilderStatus: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): SolutionBuilderWithWatchHost + +external fun createSolutionBuilder(host: SolutionBuilderHost, rootNames: Array, defaultOptions: BuildOptions): SolutionBuilder + +external fun createSolutionBuilderWithWatch(host: SolutionBuilderWithWatchHost, rootNames: Array, defaultOptions: BuildOptions, baseWatchOptions: WatchOptions = definedExternally): SolutionBuilder + +external enum class InvalidatedProjectKind { + Build /* = 0 */, + UpdateBundle /* = 1 */, + UpdateOutputFileStamps /* = 2 */ +} + +external interface InvalidatedProjectBase { + var kind: InvalidatedProjectKind + var project: String /* String & `T$5` */ + fun done(cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, customTransformers: CustomTransformers = definedExternally): ExitStatus + fun getCompilerOptions(): CompilerOptions + fun getCurrentDirectory(): String +} + +external interface UpdateOutputFileStampsProject : InvalidatedProjectBase { + fun updateOutputFileStatmps() +} + +external interface BuildInvalidedProject : InvalidatedProjectBase { + fun getBuilderProgram(): T? + fun getProgram(): Program? + fun getSourceFile(fileName: String): SourceFile? + fun getSourceFiles(): Array + fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array + fun getConfigFileParsingDiagnostics(): Array + fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getAllDependencies(sourceFile: SourceFile): Array + fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array + fun getSemanticDiagnosticsOfNextAffectedFile(cancellationToken: CancellationToken = definedExternally, ignoreSourceFile: (sourceFile: SourceFile) -> Boolean = definedExternally): `T$28`>? + fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult? +} + +external interface UpdateBundleProject : InvalidatedProjectBase { + fun emit(writeFile: WriteFileCallback = definedExternally, customTransformers: CustomTransformers = definedExternally): dynamic /* EmitResult? | BuildInvalidedProject? */ +} + +external interface SourceFileLike { + fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter +} + +external interface IScriptSnapshot { + fun getText(start: Number, end: Number): String + fun getLength(): Number + fun getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange? + val dispose: (() -> Unit)? +} + +external interface PreProcessedFileInfo { + var referencedFiles: Array + var typeReferenceDirectives: Array + var libReferenceDirectives: Array + var importedFiles: Array + var ambientExternalModules: Array? + get() = definedExternally + set(value) = definedExternally + var isLibFile: Boolean +} + +external interface HostCancellationToken { + fun isCancellationRequested(): Boolean +} + +external interface InstallPackageOptions { + var fileName: String /* String & `T$3` */ + var packageName: String +} + +external interface PerformanceEvent { + var kind: String /* "UpdateGraph" | "CreatePackageJsonAutoImportProvider" */ + var durationMs: Number +} + +external enum class LanguageServiceMode { + Semantic /* = 0 */, + PartialSemantic /* = 1 */, + Syntactic /* = 2 */ +} + +external interface IncompleteCompletionsCache { + fun get(): CompletionInfo? + fun set(response: CompletionInfo) + fun clear() +} + +external interface LanguageServiceHost : GetEffectiveTypeRootsHost { + fun getCompilationSettings(): CompilerOptions + val getNewLine: (() -> String)? + val getProjectVersion: (() -> String)? + fun getScriptFileNames(): Array + val getScriptKind: ((fileName: String) -> ScriptKind)? + fun getScriptVersion(fileName: String): String + fun getScriptSnapshot(fileName: String): IScriptSnapshot? + val getProjectReferences: (() -> Array?)? + val getLocalizedDiagnosticMessages: (() -> Any)? + val getCancellationToken: (() -> HostCancellationToken)? + override var getCurrentDirectory: () -> String + fun getDefaultLibFileName(options: CompilerOptions): String + val log: ((s: String) -> Unit)? + val trace: ((s: String) -> Unit)? + val error: ((s: String) -> Unit)? + val useCaseSensitiveFileNames: (() -> Boolean)? + val readDirectory: ((path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array)? + val readFile: ((path: String, encoding: String) -> String?)? + val realpath: ((path: String) -> String)? + val fileExists: ((path: String) -> Boolean)? + val getTypeRootsVersion: (() -> Number)? + val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val getResolvedModuleWithFailedLookupLocationsFromCache: ((modulename: String, containingFile: String) -> ResolvedModuleWithFailedLookupLocations?)? + val resolveTypeReferenceDirectives: ((typeDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? + val getDirectories: ((directoryName: String) -> Array)? + val getCustomTransformers: (() -> CustomTransformers?)? + val isKnownTypesPackageName: ((name: String) -> Boolean)? + val installPackage: ((options: InstallPackageOptions) -> Promise)? + val writeFile: ((fileName: String, content: String) -> Unit)? + val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? +} + +external enum class SemanticClassificationFormat { + Original /* = "original" */, + TwentyTwenty /* = "2020" */ +} + +external interface LanguageService { + fun cleanupSemanticCache() + fun getSyntacticDiagnostics(fileName: String): Array + fun getSemanticDiagnostics(fileName: String): Array + fun getSuggestionDiagnostics(fileName: String): Array + fun getCompilerOptionsDiagnostics(): Array + fun getSyntacticClassifications(fileName: String, span: TextSpan): Array + fun getSyntacticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ + fun getSemanticClassifications(fileName: String, span: TextSpan): Array + fun getSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ + fun getEncodedSyntacticClassifications(fileName: String, span: TextSpan): Classifications + fun getEncodedSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat = definedExternally): Classifications + fun getCompletionsAtPosition(fileName: String, position: Number, options: GetCompletionsAtPositionOptions?): CompletionInfo /* CompletionInfo & `T$12` */ + fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeOptions?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? + fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeSettings?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? + fun getCompletionEntrySymbol(fileName: String, position: Number, name: String, source: String?): Symbol? + fun getQuickInfoAtPosition(fileName: String, position: Number): QuickInfo? + fun getNameOrDottedNameSpan(fileName: String, startPos: Number, endPos: Number): TextSpan? + fun getBreakpointStatementAtPosition(fileName: String, position: Number): TextSpan? + fun getSignatureHelpItems(fileName: String, position: Number, options: SignatureHelpItemsOptions?): SignatureHelpItems? + fun getRenameInfo(fileName: String, position: Number, options: RenameInfoOptions = definedExternally): dynamic /* RenameInfoSuccess | RenameInfoFailure */ + fun findRenameLocations(fileName: String, position: Number, findInStrings: Boolean, findInComments: Boolean, providePrefixAndSuffixTextForRename: Boolean = definedExternally): Array? + fun getSmartSelectionRange(fileName: String, position: Number): SelectionRange + fun getDefinitionAtPosition(fileName: String, position: Number): Array? + fun getDefinitionAndBoundSpan(fileName: String, position: Number): DefinitionInfoAndBoundSpan? + fun getTypeDefinitionAtPosition(fileName: String, position: Number): Array? + fun getImplementationAtPosition(fileName: String, position: Number): Array? + fun getReferencesAtPosition(fileName: String, position: Number): Array? + fun findReferences(fileName: String, position: Number): Array? + fun getDocumentHighlights(fileName: String, position: Number, filesToSearch: Array): Array? + fun getFileReferences(fileName: String): Array + fun getOccurrencesAtPosition(fileName: String, position: Number): Array? + fun getNavigateToItems(searchValue: String, maxResultCount: Number = definedExternally, fileName: String = definedExternally, excludeDtsFiles: Boolean = definedExternally): Array + fun getNavigationBarItems(fileName: String): Array + fun getNavigationTree(fileName: String): NavigationTree + fun prepareCallHierarchy(fileName: String, position: Number): dynamic /* CallHierarchyItem? | Array? */ + fun provideCallHierarchyIncomingCalls(fileName: String, position: Number): Array + fun provideCallHierarchyOutgoingCalls(fileName: String, position: Number): Array + fun provideInlayHints(fileName: String, span: TextSpan, preferences: UserPreferences?): Array + fun getOutliningSpans(fileName: String): Array + fun getTodoComments(fileName: String, descriptors: Array): Array + fun getBraceMatchingAtPosition(fileName: String, position: Number): Array + fun getIndentationAtPosition(fileName: String, position: Number, options: EditorOptions): Number + fun getIndentationAtPosition(fileName: String, position: Number, options: EditorSettings): Number + fun getFormattingEditsForRange(fileName: String, start: Number, end: Number, options: FormatCodeOptions): Array + fun getFormattingEditsForRange(fileName: String, start: Number, end: Number, options: FormatCodeSettings): Array + fun getFormattingEditsForDocument(fileName: String, options: FormatCodeOptions): Array + fun getFormattingEditsForDocument(fileName: String, options: FormatCodeSettings): Array + fun getFormattingEditsAfterKeystroke(fileName: String, position: Number, key: String, options: FormatCodeOptions): Array + fun getFormattingEditsAfterKeystroke(fileName: String, position: Number, key: String, options: FormatCodeSettings): Array + fun getDocCommentTemplateAtPosition(fileName: String, position: Number, options: DocCommentTemplateOptions = definedExternally): TextInsertion? + fun isValidBraceCompletionAtPosition(fileName: String, position: Number, openingBrace: Number): Boolean + fun getJsxClosingTagAtPosition(fileName: String, position: Number): JsxClosingTagInfo? + fun getSpanOfEnclosingComment(fileName: String, position: Number, onlyMultiLine: Boolean): TextSpan? + val toLineColumnOffset: ((fileName: String, position: Number) -> LineAndCharacter)? + fun getCodeFixesAtPosition(fileName: String, start: Number, end: Number, errorCodes: Array, formatOptions: FormatCodeSettings, preferences: UserPreferences): Array + fun getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: Any, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions + fun applyCodeActionCommand(action: CodeActionCommand, formatSettings: FormatCodeSettings = definedExternally): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(action: CodeActionCommand): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(action: Array, formatSettings: FormatCodeSettings = definedExternally): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(action: Array): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(fileName: String, action: CodeActionCommand): dynamic /* Promise | Promise */ + fun applyCodeActionCommand(fileName: String, action: Array): dynamic /* Promise | Promise */ + fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally, kind: String = definedExternally): Array + fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?): Array + fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally): Array + fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally, kind: String = definedExternally): Array + fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?): Array + fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally): Array + fun getEditsForRefactor(fileName: String, formatOptions: FormatCodeSettings, positionOrRange: Number, refactorName: String, actionName: String, preferences: UserPreferences?): RefactorEditInfo? + fun getEditsForRefactor(fileName: String, formatOptions: FormatCodeSettings, positionOrRange: TextRange, refactorName: String, actionName: String, preferences: UserPreferences?): RefactorEditInfo? + fun organizeImports(args: OrganizeImportsArgs, formatOptions: FormatCodeSettings, preferences: UserPreferences?): Array + fun getEditsForFileRename(oldFilePath: String, newFilePath: String, formatOptions: FormatCodeSettings, preferences: UserPreferences?): Array + fun getEmitOutput(fileName: String, emitOnlyDtsFiles: Boolean = definedExternally, forceDtsEmit: Boolean = definedExternally): EmitOutput + fun getProgram(): Program? + fun toggleLineComment(fileName: String, textRange: TextRange): Array + fun toggleMultilineComment(fileName: String, textRange: TextRange): Array + fun commentSelection(fileName: String, textRange: TextRange): Array + fun uncommentSelection(fileName: String, textRange: TextRange): Array + fun dispose() +} + +external interface JsxClosingTagInfo { + var newText: String +} + +external interface CombinedCodeFixScope { + var type: String /* "file" */ + var fileName: String +} + +external interface OrganizeImportsArgs : CombinedCodeFixScope { + var skipDestructiveCodeActions: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external enum class CompletionTriggerKind { + Invoked /* = 1 */, + TriggerCharacter /* = 2 */, + TriggerForIncompleteCompletions /* = 3 */ +} + +external interface GetCompletionsAtPositionOptions : UserPreferences { + var triggerCharacter: String? /* "." | """ | "'" | "`" | "/" | "@" | "<" | "#" | " " */ + get() = definedExternally + set(value) = definedExternally + var triggerKind: CompletionTriggerKind? + get() = definedExternally + set(value) = definedExternally + var includeExternalModuleExports: Boolean? + get() = definedExternally + set(value) = definedExternally + var includeInsertTextCompletions: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface InlayHintsOptions : UserPreferences { + var includeInlayParameterNameHints: String? /* "none" | "literals" | "all" */ + get() = definedExternally + set(value) = definedExternally + var includeInlayParameterNameHintsWhenArgumentMatchesName: Boolean? + get() = definedExternally + set(value) = definedExternally + var includeInlayFunctionParameterTypeHints: Boolean? + get() = definedExternally + set(value) = definedExternally + var includeInlayVariableTypeHints: Boolean? + get() = definedExternally + set(value) = definedExternally + var includeInlayPropertyDeclarationTypeHints: Boolean? + get() = definedExternally + set(value) = definedExternally + var includeInlayFunctionLikeReturnTypeHints: Boolean? + get() = definedExternally + set(value) = definedExternally + var includeInlayEnumMemberValueHints: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureHelpItemsOptions { + var triggerReason: dynamic /* SignatureHelpInvokedReason? | SignatureHelpCharacterTypedReason? | SignatureHelpRetriggeredReason? */ + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureHelpInvokedReason { + var kind: String /* "invoked" */ + var triggerCharacter: Any? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureHelpCharacterTypedReason { + var kind: String /* "characterTyped" */ + var triggerCharacter: String /* "," | "(" | "<" */ +} + +external interface SignatureHelpRetriggeredReason { + var kind: String /* "retrigger" */ + var triggerCharacter: String? /* "," | "(" | "<" | ")" */ + get() = definedExternally + set(value) = definedExternally +} + +external interface ApplyCodeActionCommandResult { + var successMessage: String +} + +external interface Classifications { + var spans: Array + var endOfLineState: EndOfLineState +} + +external interface ClassifiedSpan { + var textSpan: TextSpan + var classificationType: ClassificationTypeNames +} + +external interface ClassifiedSpan2020 { + var textSpan: TextSpan + var classificationType: Number +} + +external interface NavigationBarItem { + var text: String + var kind: ScriptElementKind + var kindModifiers: String + var spans: Array + var childItems: Array + var indent: Number + var bolded: Boolean + var grayed: Boolean +} + +external interface NavigationTree { + var text: String + var kind: ScriptElementKind + var kindModifiers: String + var spans: Array + var nameSpan: TextSpan? + var childItems: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface CallHierarchyItem { + var name: String + var kind: ScriptElementKind + var kindModifiers: String? + get() = definedExternally + set(value) = definedExternally + var file: String + var span: TextSpan + var selectionSpan: TextSpan + var containerName: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface CallHierarchyIncomingCall { + var from: CallHierarchyItem + var fromSpans: Array +} + +external interface CallHierarchyOutgoingCall { + var to: CallHierarchyItem + var fromSpans: Array +} + +external enum class InlayHintKind { + Type /* = "Type" */, + Parameter /* = "Parameter" */, + Enum /* = "Enum" */ +} + +external interface InlayHint { + var text: String + var position: Number + var kind: InlayHintKind + var whitespaceBefore: Boolean? + get() = definedExternally + set(value) = definedExternally + var whitespaceAfter: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface TodoCommentDescriptor { + var text: String + var priority: Number +} + +external interface TodoComment { + var descriptor: TodoCommentDescriptor + var message: String + var position: Number +} + +external interface TextChange { + var span: TextSpan + var newText: String +} + +external interface FileTextChanges { + var fileName: String + var textChanges: Array + var isNewFile: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface CodeAction { + var description: String + var changes: Array + var commands: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface CodeFixAction : CodeAction { + var fixName: String + var fixId: Any? + get() = definedExternally + set(value) = definedExternally + var fixAllDescription: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface CombinedCodeActions { + var changes: Array + var commands: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface InstallPackageAction + +external interface ApplicableRefactorInfo { + var name: String + var description: String + var inlineable: Boolean? + get() = definedExternally + set(value) = definedExternally + var actions: Array +} + +external interface RefactorActionInfo { + var name: String + var description: String + var notApplicableReason: String? + get() = definedExternally + set(value) = definedExternally + var kind: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface RefactorEditInfo { + var edits: Array + var renameFilename: String? + get() = definedExternally + set(value) = definedExternally + var renameLocation: Number? + get() = definedExternally + set(value) = definedExternally + var commands: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface TextInsertion { + var newText: String + var caretOffset: Number +} + +external interface DocumentSpan { + var textSpan: TextSpan + var fileName: String + var originalTextSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var originalFileName: String? + get() = definedExternally + set(value) = definedExternally + var contextSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var originalContextSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally +} + +external interface RenameLocation : DocumentSpan { + var prefixText: String? + get() = definedExternally + set(value) = definedExternally + var suffixText: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface ReferenceEntry : DocumentSpan { + var isWriteAccess: Boolean + var isDefinition: Boolean + var isInString: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface ImplementationLocation : DocumentSpan { + var kind: ScriptElementKind + var displayParts: Array +} + +external enum class HighlightSpanKind { + none /* = "none" */, + definition /* = "definition" */, + reference /* = "reference" */, + writtenReference /* = "writtenReference" */ +} + +external interface HighlightSpan { + var fileName: String? + get() = definedExternally + set(value) = definedExternally + var isInString: Boolean? + get() = definedExternally + set(value) = definedExternally + var textSpan: TextSpan + var contextSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var kind: HighlightSpanKind +} + +external interface NavigateToItem { + var name: String + var kind: ScriptElementKind + var kindModifiers: String + var matchKind: String /* "exact" | "prefix" | "substring" | "camelCase" */ + var isCaseSensitive: Boolean + var fileName: String + var textSpan: TextSpan + var containerName: String + var containerKind: ScriptElementKind +} + +external enum class IndentStyle { + None /* = 0 */, + Block /* = 1 */, + Smart /* = 2 */ +} + +external enum class SemicolonPreference { + Ignore /* = "ignore" */, + Insert /* = "insert" */, + Remove /* = "remove" */ +} + +external interface EditorOptions { + var BaseIndentSize: Number? + get() = definedExternally + set(value) = definedExternally + var IndentSize: Number + var TabSize: Number + var NewLineCharacter: String + var ConvertTabsToSpaces: Boolean + var IndentStyle: IndentStyle +} + +external interface EditorSettings { + var baseIndentSize: Number? + get() = definedExternally + set(value) = definedExternally + var indentSize: Number? + get() = definedExternally + set(value) = definedExternally + var tabSize: Number? + get() = definedExternally + set(value) = definedExternally + var newLineCharacter: String? + get() = definedExternally + set(value) = definedExternally + var convertTabsToSpaces: Boolean? + get() = definedExternally + set(value) = definedExternally + var indentStyle: IndentStyle? + get() = definedExternally + set(value) = definedExternally + var trimTrailingWhitespace: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface FormatCodeOptions : EditorOptions { + var InsertSpaceAfterCommaDelimiter: Boolean + var InsertSpaceAfterSemicolonInForStatements: Boolean + var InsertSpaceBeforeAndAfterBinaryOperators: Boolean + var InsertSpaceAfterConstructor: Boolean? + get() = definedExternally + set(value) = definedExternally + var InsertSpaceAfterKeywordsInControlFlowStatements: Boolean + var InsertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean + var InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean + var InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean + var InsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: Boolean? + get() = definedExternally + set(value) = definedExternally + var InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean + var InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: Boolean? + get() = definedExternally + set(value) = definedExternally + var InsertSpaceAfterTypeAssertion: Boolean? + get() = definedExternally + set(value) = definedExternally + var InsertSpaceBeforeFunctionParenthesis: Boolean? + get() = definedExternally + set(value) = definedExternally + var PlaceOpenBraceOnNewLineForFunctions: Boolean + var PlaceOpenBraceOnNewLineForControlBlocks: Boolean + var insertSpaceBeforeTypeAnnotation: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface FormatCodeSettings : EditorSettings { + var insertSpaceAfterCommaDelimiter: Boolean? + get() = definedExternally + set(value) = definedExternally + var insertSpaceAfterSemicolonInForStatements: Boolean? + get() = definedExternally + set(value) = definedExternally + var insertSpaceBeforeAndAfterBinaryOperators: Boolean? + get() = definedExternally + set(value) = definedExternally + var insertSpaceAfterConstructor: Boolean? + get() = definedExternally + set(value) = definedExternally + var insertSpaceAfterKeywordsInControlFlowStatements: Boolean? + get() = definedExternally + set(value) = definedExternally + var insertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean? + get() = definedExternally + set(value) = definedExternally + var insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean? + get() = definedExternally + set(value) = definedExternally + var insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean? + get() = definedExternally + set(value) = definedExternally + var insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: Boolean? + get() = definedExternally + set(value) = definedExternally + var insertSpaceAfterOpeningAndBeforeClosingEmptyBraces: Boolean? + get() = definedExternally + set(value) = definedExternally + var insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean? + get() = definedExternally + set(value) = definedExternally + var insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: Boolean? + get() = definedExternally + set(value) = definedExternally + var insertSpaceAfterTypeAssertion: Boolean? + get() = definedExternally + set(value) = definedExternally + var insertSpaceBeforeFunctionParenthesis: Boolean? + get() = definedExternally + set(value) = definedExternally + var placeOpenBraceOnNewLineForFunctions: Boolean? + get() = definedExternally + set(value) = definedExternally + var placeOpenBraceOnNewLineForControlBlocks: Boolean? + get() = definedExternally + set(value) = definedExternally + var insertSpaceBeforeTypeAnnotation: Boolean? + get() = definedExternally + set(value) = definedExternally + var indentMultiLineObjectLiteralBeginningOnBlankLine: Boolean? + get() = definedExternally + set(value) = definedExternally + var semicolons: SemicolonPreference? + get() = definedExternally + set(value) = definedExternally +} + +external fun getDefaultFormatCodeSettings(newLineCharacter: String = definedExternally): FormatCodeSettings + +external interface DefinitionInfo : DocumentSpan { + var kind: ScriptElementKind + var name: String + var containerKind: ScriptElementKind + var containerName: String + var unverified: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface DefinitionInfoAndBoundSpan { + var definitions: Array? + get() = definedExternally + set(value) = definedExternally + var textSpan: TextSpan +} + +external interface ReferencedSymbolDefinitionInfo : DefinitionInfo { + var displayParts: Array +} + +external interface ReferencedSymbol { + var definition: ReferencedSymbolDefinitionInfo + var references: Array +} + +external enum class SymbolDisplayPartKind { + aliasName /* = 0 */, + className /* = 1 */, + enumName /* = 2 */, + fieldName /* = 3 */, + interfaceName /* = 4 */, + keyword /* = 5 */, + lineBreak /* = 6 */, + numericLiteral /* = 7 */, + stringLiteral /* = 8 */, + localName /* = 9 */, + methodName /* = 10 */, + moduleName /* = 11 */, + operator /* = 12 */, + parameterName /* = 13 */, + propertyName /* = 14 */, + punctuation /* = 15 */, + space /* = 16 */, + text /* = 17 */, + typeParameterName /* = 18 */, + enumMemberName /* = 19 */, + functionName /* = 20 */, + regularExpressionLiteral /* = 21 */, + link /* = 22 */, + linkName /* = 23 */, + linkText /* = 24 */ +} + +external interface SymbolDisplayPart { + var text: String + var kind: String +} + +external interface JSDocLinkDisplayPart : SymbolDisplayPart { + var target: DocumentSpan +} + +external interface JSDocTagInfo { + var name: String + var text: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface QuickInfo { + var kind: ScriptElementKind + var kindModifiers: String + var textSpan: TextSpan + var displayParts: Array? + get() = definedExternally + set(value) = definedExternally + var documentation: Array? + get() = definedExternally + set(value) = definedExternally + var tags: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface RenameInfoSuccess { + var canRename: Boolean + var fileToRename: String? + get() = definedExternally + set(value) = definedExternally + var displayName: String + var fullDisplayName: String + var kind: ScriptElementKind + var kindModifiers: String + var triggerSpan: TextSpan +} + +external interface RenameInfoFailure { + var canRename: Boolean + var localizedErrorMessage: String +} + +external interface RenameInfoOptions { + var allowRenameOfImportPath: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface DocCommentTemplateOptions { + var generateReturnInDocTemplate: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureHelpParameter { + var name: String + var documentation: Array + var displayParts: Array + var isOptional: Boolean + var isRest: Boolean? + get() = definedExternally + set(value) = definedExternally +} + +external interface SelectionRange { + var textSpan: TextSpan + var parent: SelectionRange? + get() = definedExternally + set(value) = definedExternally +} + +external interface SignatureHelpItem { + var isVariadic: Boolean + var prefixDisplayParts: Array + var suffixDisplayParts: Array + var separatorDisplayParts: Array + var parameters: Array + var documentation: Array + var tags: Array +} + +external interface SignatureHelpItems { + var items: Array + var applicableSpan: TextSpan + var selectedItemIndex: Number + var argumentIndex: Number + var argumentCount: Number +} + +external interface CompletionInfo { + var isGlobalCompletion: Boolean + var isMemberCompletion: Boolean + var optionalReplacementSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var isNewIdentifierLocation: Boolean + var isIncomplete: Boolean? + get() = definedExternally + set(value) = definedExternally + var entries: Array +} + +external interface CompletionEntryData { + var fileName: String? + get() = definedExternally + set(value) = definedExternally + var ambientModuleName: String? + get() = definedExternally + set(value) = definedExternally + var isPackageJsonImport: Boolean? + get() = definedExternally + set(value) = definedExternally + var exportName: String + var moduleSpecifier: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface CompletionEntry { + var name: String + var kind: ScriptElementKind + var kindModifiers: String? + get() = definedExternally + set(value) = definedExternally + var sortText: String + var insertText: String? + get() = definedExternally + set(value) = definedExternally + var isSnippet: Boolean? + get() = definedExternally + set(value) = definedExternally + var replacementSpan: TextSpan? + get() = definedExternally + set(value) = definedExternally + var hasAction: Boolean? + get() = definedExternally + set(value) = definedExternally + var source: String? + get() = definedExternally + set(value) = definedExternally + var sourceDisplay: Array? + get() = definedExternally + set(value) = definedExternally + var isRecommended: Boolean? + get() = definedExternally + set(value) = definedExternally + var isFromUncheckedFile: Boolean? + get() = definedExternally + set(value) = definedExternally + var isPackageJsonImport: Boolean? + get() = definedExternally + set(value) = definedExternally + var isImportStatementCompletion: Boolean? + get() = definedExternally + set(value) = definedExternally + var data: CompletionEntryData? + get() = definedExternally + set(value) = definedExternally +} + +external interface CompletionEntryDetails { + var name: String + var kind: ScriptElementKind + var kindModifiers: String + var displayParts: Array + var documentation: Array? + get() = definedExternally + set(value) = definedExternally + var tags: Array? + get() = definedExternally + set(value) = definedExternally + var codeActions: Array? + get() = definedExternally + set(value) = definedExternally + var source: Array? + get() = definedExternally + set(value) = definedExternally + var sourceDisplay: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface OutliningSpan { + var textSpan: TextSpan + var hintSpan: TextSpan + var bannerText: String + var autoCollapse: Boolean + var kind: OutliningSpanKind +} + +external enum class OutliningSpanKind { + Comment /* = "comment" */, + Region /* = "region" */, + Code /* = "code" */, + Imports /* = "imports" */ +} + +external enum class OutputFileType { + JavaScript /* = 0 */, + SourceMap /* = 1 */, + Declaration /* = 2 */ +} + +external enum class EndOfLineState { + None /* = 0 */, + InMultiLineCommentTrivia /* = 1 */, + InSingleQuoteStringLiteral /* = 2 */, + InDoubleQuoteStringLiteral /* = 3 */, + InTemplateHeadOrNoSubstitutionTemplate /* = 4 */, + InTemplateMiddleOrTail /* = 5 */, + InTemplateSubstitutionPosition /* = 6 */ +} + +external enum class TokenClass { + Punctuation /* = 0 */, + Keyword /* = 1 */, + Operator /* = 2 */, + Comment /* = 3 */, + Whitespace /* = 4 */, + Identifier /* = 5 */, + NumberLiteral /* = 6 */, + BigIntLiteral /* = 7 */, + StringLiteral /* = 8 */, + RegExpLiteral /* = 9 */ +} + +external interface ClassificationResult { + var finalLexState: EndOfLineState + var entries: Array +} + +external interface ClassificationInfo { + var length: Number + var classification: TokenClass +} + +external interface Classifier { + fun getClassificationsForLine(text: String, lexState: EndOfLineState, syntacticClassifierAbsent: Boolean): ClassificationResult + fun getEncodedLexicalClassifications(text: String, endOfLineState: EndOfLineState, syntacticClassifierAbsent: Boolean): Classifications +} + +external enum class ScriptElementKind { + unknown /* = "" */, + warning /* = "warning" */, + keyword /* = "keyword" */, + scriptElement /* = "script" */, + moduleElement /* = "module" */, + classElement /* = "class" */, + localClassElement /* = "local class" */, + interfaceElement /* = "interface" */, + typeElement /* = "type" */, + enumElement /* = "enum" */, + enumMemberElement /* = "enum member" */, + variableElement /* = "var" */, + localVariableElement /* = "local var" */, + functionElement /* = "function" */, + localFunctionElement /* = "local function" */, + memberFunctionElement /* = "method" */, + memberGetAccessorElement /* = "getter" */, + memberSetAccessorElement /* = "setter" */, + memberVariableElement /* = "property" */, + constructorImplementationElement /* = "constructor" */, + callSignatureElement /* = "call" */, + indexSignatureElement /* = "index" */, + constructSignatureElement /* = "construct" */, + parameterElement /* = "parameter" */, + typeParameterElement /* = "type parameter" */, + primitiveType /* = "primitive type" */, + label /* = "label" */, + alias /* = "alias" */, + constElement /* = "const" */, + letElement /* = "let" */, + directory /* = "directory" */, + externalModuleName /* = "external module name" */, + jsxAttribute /* = "JSX attribute" */, + string /* = "string" */, + link /* = "link" */, + linkName /* = "link name" */, + linkText /* = "link text" */ +} + +external enum class ScriptElementKindModifier { + none /* = "" */, + publicMemberModifier /* = "public" */, + privateMemberModifier /* = "private" */, + protectedMemberModifier /* = "protected" */, + exportedModifier /* = "export" */, + ambientModifier /* = "declare" */, + staticModifier /* = "static" */, + abstractModifier /* = "abstract" */, + optionalModifier /* = "optional" */, + deprecatedModifier /* = "deprecated" */, + dtsModifier /* = ".d.ts" */, + tsModifier /* = ".ts" */, + tsxModifier /* = ".tsx" */, + jsModifier /* = ".js" */, + jsxModifier /* = ".jsx" */, + jsonModifier /* = ".json" */ +} + +external enum class ClassificationTypeNames { + comment /* = "comment" */, + identifier /* = "identifier" */, + keyword /* = "keyword" */, + numericLiteral /* = "number" */, + bigintLiteral /* = "bigint" */, + operator /* = "operator" */, + stringLiteral /* = "string" */, + whiteSpace /* = "whitespace" */, + text /* = "text" */, + punctuation /* = "punctuation" */, + className /* = "class name" */, + enumName /* = "enum name" */, + interfaceName /* = "interface name" */, + moduleName /* = "module name" */, + typeParameterName /* = "type parameter name" */, + typeAliasName /* = "type alias name" */, + parameterName /* = "parameter name" */, + docCommentTagName /* = "doc comment tag name" */, + jsxOpenTagName /* = "jsx open tag name" */, + jsxCloseTagName /* = "jsx close tag name" */, + jsxSelfClosingTagName /* = "jsx self closing tag name" */, + jsxAttribute /* = "jsx attribute" */, + jsxText /* = "jsx text" */, + jsxAttributeStringLiteralValue /* = "jsx attribute string literal value" */ +} + +external enum class ClassificationType { + comment /* = 1 */, + identifier /* = 2 */, + keyword /* = 3 */, + numericLiteral /* = 4 */, + operator /* = 5 */, + stringLiteral /* = 6 */, + regularExpressionLiteral /* = 7 */, + whiteSpace /* = 8 */, + text /* = 9 */, + punctuation /* = 10 */, + className /* = 11 */, + enumName /* = 12 */, + interfaceName /* = 13 */, + moduleName /* = 14 */, + typeParameterName /* = 15 */, + typeAliasName /* = 16 */, + parameterName /* = 17 */, + docCommentTagName /* = 18 */, + jsxOpenTagName /* = 19 */, + jsxCloseTagName /* = 20 */, + jsxSelfClosingTagName /* = 21 */, + jsxAttribute /* = 22 */, + jsxText /* = 23 */, + jsxAttributeStringLiteralValue /* = 24 */, + bigintLiteral /* = 25 */ +} + +external interface InlayHintsContext { + var file: SourceFile + var program: Program + var cancellationToken: CancellationToken + var host: LanguageServiceHost + var span: TextSpan + var preferences: InlayHintsOptions +} + +external fun createClassifier(): Classifier + +external interface DocumentHighlights { + var fileName: String + var highlightSpans: Array +} + +external interface DocumentRegistry { + fun acquireDocument(fileName: String, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile + fun acquireDocumentWithKey(fileName: String, path: String /* String & `T$3` */, compilationSettings: CompilerOptions, key: String /* String & `T$29` */, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile + fun updateDocument(fileName: String, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile + fun updateDocumentWithKey(fileName: String, path: String /* String & `T$3` */, compilationSettings: CompilerOptions, key: String /* String & `T$29` */, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile + fun getKeyForCompilationSettings(settings: CompilerOptions): String /* String & `T$29` */ + fun releaseDocument(fileName: String, compilationSettings: CompilerOptions) + fun releaseDocument(fileName: String, compilationSettings: CompilerOptions, scriptKind: ScriptKind) + fun releaseDocumentWithKey(path: String /* String & `T$3` */, key: String /* String & `T$29` */) + fun releaseDocumentWithKey(path: String /* String & `T$3` */, key: String /* String & `T$29` */, scriptKind: ScriptKind) + fun reportStats(): String +} + +external interface `T$29` { + var __bucketKey: Any +} + +external fun createDocumentRegistry(useCaseSensitiveFileNames: Boolean = definedExternally, currentDirectory: String = definedExternally): DocumentRegistry + +external fun preProcessFile(sourceText: String, readImportFiles: Boolean = definedExternally, detectJavaScriptImports: Boolean = definedExternally): PreProcessedFileInfo + +external interface TranspileOptions { + var compilerOptions: CompilerOptions? + get() = definedExternally + set(value) = definedExternally + var fileName: String? + get() = definedExternally + set(value) = definedExternally + var reportDiagnostics: Boolean? + get() = definedExternally + set(value) = definedExternally + var moduleName: String? + get() = definedExternally + set(value) = definedExternally + var renamedDependencies: MapLike? + get() = definedExternally + set(value) = definedExternally + var transformers: CustomTransformers? + get() = definedExternally + set(value) = definedExternally +} + +external interface TranspileOutput { + var outputText: String + var diagnostics: Array? + get() = definedExternally + set(value) = definedExternally + var sourceMapText: String? + get() = definedExternally + set(value) = definedExternally +} + +external fun transpileModule(input: String, transpileOptions: TranspileOptions): TranspileOutput + +external fun transpile(input: String, compilerOptions: CompilerOptions = definedExternally, fileName: String = definedExternally, diagnostics: Array = definedExternally, moduleName: String = definedExternally): String + +external var servicesVersion: Any + +external fun toEditorSettings(options: EditorOptions): EditorSettings + +external fun toEditorSettings(options: EditorSettings): EditorSettings + +external fun displayPartsToString(displayParts: Array?): String + +external fun getDefaultCompilerOptions(): CompilerOptions + +external fun getSupportedCodeFixes(): Array + +external fun createLanguageServiceSourceFile(fileName: String, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: String, setNodeParents: Boolean, scriptKind: ScriptKind = definedExternally): SourceFile + +external fun updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: String, textChangeRange: TextChangeRange?, aggressiveChecks: Boolean = definedExternally): SourceFile + +external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally, syntaxOnlyOrLanguageServiceMode: Boolean = definedExternally): LanguageService + +external fun createLanguageService(host: LanguageServiceHost): LanguageService + +external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally): LanguageService + +external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally, syntaxOnlyOrLanguageServiceMode: LanguageServiceMode = definedExternally): LanguageService + +external fun getDefaultLibFilePath(options: CompilerOptions): String + +external fun transform(source: T, transformers: Array>, compilerOptions: CompilerOptions = definedExternally): TransformationResult + +external fun transform(source: T, transformers: Array>): TransformationResult + +external fun transform(source: Array, transformers: Array>, compilerOptions: CompilerOptions = definedExternally): TransformationResult + +external fun transform(source: Array, transformers: Array>): TransformationResult + +external var createNodeArray: (elements: Array?, hasTrailingComma: Boolean?) -> NodeArray + +external var createNumericLiteral: (value: dynamic /* String | Number */, numericLiteralFlags: TokenFlags?) -> NumericLiteral + +external var createBigIntLiteral: (value: dynamic /* String | PseudoBigInt */) -> BigIntLiteral + +external object createStringLiteral { + @nativeInvoke + operator fun invoke(text: String, isSingleQuote: Boolean? = definedExternally): StringLiteral + @nativeInvoke + operator fun invoke(text: String, isSingleQuote: Boolean? = definedExternally, hasExtendedUnicodeEscape: Boolean? = definedExternally): StringLiteral +} + +external var createStringLiteralFromNode: (sourceNode: dynamic /* Identifier | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral */, isSingleQuote: Boolean?) -> StringLiteral + +external var createRegularExpressionLiteral: (text: String) -> RegularExpressionLiteral + +external var createLoopVariable: (reservedInNestedScopes: Boolean?) -> Identifier + +external var createUniqueName: (text: String, flags: GeneratedIdentifierFlags?) -> Identifier + +external var createPrivateIdentifier: (text: String) -> PrivateIdentifier + +external var createSuper: () -> SuperExpression + +external var createThis: () -> ThisExpression + +external var createNull: () -> NullLiteral + +external var createTrue: () -> TrueLiteral + +external var createFalse: () -> FalseLiteral + +external var createModifier: (kind: T) -> ModifierToken + +external var createModifiersFromModifierFlags: (flags: ModifierFlags) -> Array + +external var createQualifiedName: (left: dynamic /* Identifier | QualifiedName */, right: dynamic /* String | Identifier */) -> QualifiedName + +external var updateQualifiedName: (node: QualifiedName, left: dynamic /* Identifier | QualifiedName */, right: Identifier) -> QualifiedName + +external var createComputedPropertyName: (expression: Expression) -> ComputedPropertyName + +external var updateComputedPropertyName: (node: ComputedPropertyName, expression: Expression) -> ComputedPropertyName + +external var createTypeParameterDeclaration: (name: dynamic /* String | Identifier */, constraint: TypeNode?, defaultType: TypeNode?) -> TypeParameterDeclaration + +external var updateTypeParameterDeclaration: (node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode?, defaultType: TypeNode?) -> TypeParameterDeclaration + +external var createParameter: (decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> ParameterDeclaration + +external var updateParameter: (node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> ParameterDeclaration + +external var createDecorator: (expression: Expression) -> Decorator + +external var updateDecorator: (node: Decorator, expression: Expression) -> Decorator + +external var createProperty: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionOrExclamationToken: dynamic /* QuestionToken? | ExclamationToken? */, type: TypeNode?, initializer: Expression?) -> PropertyDeclaration + +external var updateProperty: (node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionOrExclamationToken: dynamic /* QuestionToken? | ExclamationToken? */, type: TypeNode?, initializer: Expression?) -> PropertyDeclaration + +external var createMethod: (decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> MethodDeclaration + +external var updateMethod: (node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> MethodDeclaration + +external var createConstructor: (decorators: Array?, modifiers: Array?, parameters: Array, body: Block?) -> ConstructorDeclaration + +external var updateConstructor: (node: ConstructorDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, body: Block?) -> ConstructorDeclaration + +external var createGetAccessor: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, type: TypeNode?, body: Block?) -> GetAccessorDeclaration + +external var updateGetAccessor: (node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, type: TypeNode?, body: Block?) -> GetAccessorDeclaration + +external var createSetAccessor: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, body: Block?) -> SetAccessorDeclaration + +external var updateSetAccessor: (node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, body: Block?) -> SetAccessorDeclaration + +external var createCallSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?) -> CallSignatureDeclaration + +external var updateCallSignature: (node: CallSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?) -> CallSignatureDeclaration + +external var createConstructSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?) -> ConstructSignatureDeclaration + +external var updateConstructSignature: (node: ConstructSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?) -> ConstructSignatureDeclaration + +external var updateIndexSignature: (node: IndexSignatureDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode) -> IndexSignatureDeclaration + +external var createKeywordTypeNode: (kind: TKind) -> KeywordTypeNode + +external var createTypePredicateNodeWithModifier: (assertsModifier: AssertsKeyword?, parameterName: dynamic /* String | Identifier | ThisTypeNode */, type: TypeNode?) -> TypePredicateNode + +external var updateTypePredicateNodeWithModifier: (node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: dynamic /* Identifier | ThisTypeNode */, type: TypeNode?) -> TypePredicateNode + +external var createTypeReferenceNode: (typeName: dynamic /* String | Identifier | QualifiedName */, typeArguments: Array?) -> TypeReferenceNode + +external var updateTypeReferenceNode: (node: TypeReferenceNode, typeName: dynamic /* Identifier | QualifiedName */, typeArguments: NodeArray?) -> TypeReferenceNode + +external var createFunctionTypeNode: (typeParameters: Array?, parameters: Array, type: TypeNode) -> FunctionTypeNode + +external var updateFunctionTypeNode: (node: FunctionTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode) -> FunctionTypeNode + +external var createConstructorTypeNode: (typeParameters: Array?, parameters: Array, type: TypeNode) -> ConstructorTypeNode + +external var updateConstructorTypeNode: (node: ConstructorTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode) -> ConstructorTypeNode + +external var createTypeQueryNode: (exprName: dynamic /* Identifier | QualifiedName */) -> TypeQueryNode + +external var updateTypeQueryNode: (node: TypeQueryNode, exprName: dynamic /* Identifier | QualifiedName */) -> TypeQueryNode + +external var createTypeLiteralNode: (members: Array?) -> TypeLiteralNode + +external var updateTypeLiteralNode: (node: TypeLiteralNode, members: NodeArray) -> TypeLiteralNode + +external var createArrayTypeNode: (elementType: TypeNode) -> ArrayTypeNode + +external var updateArrayTypeNode: (node: ArrayTypeNode, elementType: TypeNode) -> ArrayTypeNode + +external var createTupleTypeNode: (elements: Array) -> TupleTypeNode + +external var updateTupleTypeNode: (node: TupleTypeNode, elements: Array) -> TupleTypeNode + +external var createOptionalTypeNode: (type: TypeNode) -> OptionalTypeNode + +external var updateOptionalTypeNode: (node: OptionalTypeNode, type: TypeNode) -> OptionalTypeNode + +external var createRestTypeNode: (type: TypeNode) -> RestTypeNode + +external var updateRestTypeNode: (node: RestTypeNode, type: TypeNode) -> RestTypeNode + +external var createUnionTypeNode: (types: Array) -> UnionTypeNode + +external var updateUnionTypeNode: (node: UnionTypeNode, types: NodeArray) -> UnionTypeNode + +external var createIntersectionTypeNode: (types: Array) -> IntersectionTypeNode + +external var updateIntersectionTypeNode: (node: IntersectionTypeNode, types: NodeArray) -> IntersectionTypeNode + +external var createConditionalTypeNode: (checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) -> ConditionalTypeNode + +external var updateConditionalTypeNode: (node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) -> ConditionalTypeNode + +external var createInferTypeNode: (typeParameter: TypeParameterDeclaration) -> InferTypeNode + +external var updateInferTypeNode: (node: InferTypeNode, typeParameter: TypeParameterDeclaration) -> InferTypeNode + +external var createImportTypeNode: (argument: TypeNode, qualifier: dynamic /* Identifier? | QualifiedName? */, typeArguments: Array?, isTypeOf: Boolean?) -> ImportTypeNode + +external var updateImportTypeNode: (node: ImportTypeNode, argument: TypeNode, qualifier: dynamic /* Identifier? | QualifiedName? */, typeArguments: Array?, isTypeOf: Boolean?) -> ImportTypeNode + +external var createParenthesizedType: (type: TypeNode) -> ParenthesizedTypeNode + +external var updateParenthesizedType: (node: ParenthesizedTypeNode, type: TypeNode) -> ParenthesizedTypeNode + +external var createThisTypeNode: () -> ThisTypeNode + +external var updateTypeOperatorNode: (node: TypeOperatorNode, type: TypeNode) -> TypeOperatorNode + +external var createIndexedAccessTypeNode: (objectType: TypeNode, indexType: TypeNode) -> IndexedAccessTypeNode + +external var updateIndexedAccessTypeNode: (node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) -> IndexedAccessTypeNode + +external var createMappedTypeNode: (readonlyToken: dynamic /* ReadonlyKeyword? | PlusToken? | MinusToken? */, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */, type: TypeNode?) -> MappedTypeNode + +external var updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: dynamic /* ReadonlyKeyword? | PlusToken? | MinusToken? */, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */, type: TypeNode?) -> MappedTypeNode + +external var createLiteralTypeNode: (literal: dynamic /* LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral */) -> LiteralTypeNode + +external var updateLiteralTypeNode: (node: LiteralTypeNode, literal: dynamic /* LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral */) -> LiteralTypeNode + +external var createObjectBindingPattern: (elements: Array) -> ObjectBindingPattern + +external var updateObjectBindingPattern: (node: ObjectBindingPattern, elements: Array) -> ObjectBindingPattern + +external var createArrayBindingPattern: (elements: Array) -> ArrayBindingPattern + +external var updateArrayBindingPattern: (node: ArrayBindingPattern, elements: Array) -> ArrayBindingPattern + +external var createBindingElement: (dotDotDotToken: DotDotDotToken?, propertyName: dynamic /* String? | Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression?) -> BindingElement + +external var updateBindingElement: (node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */, name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression?) -> BindingElement + +external var createArrayLiteral: (elements: Array?, multiLine: Boolean?) -> ArrayLiteralExpression + +external var updateArrayLiteral: (node: ArrayLiteralExpression, elements: Array) -> ArrayLiteralExpression + +external var createObjectLiteral: (properties: Array?, multiLine: Boolean?) -> ObjectLiteralExpression + +external var updateObjectLiteral: (node: ObjectLiteralExpression, properties: Array) -> ObjectLiteralExpression + +external var createPropertyAccess: (expression: Expression, name: dynamic /* String | Identifier | PrivateIdentifier */) -> PropertyAccessExpression + +external var updatePropertyAccess: (node: PropertyAccessExpression, expression: Expression, name: dynamic /* Identifier | PrivateIdentifier */) -> PropertyAccessExpression + +external var createPropertyAccessChain: (expression: Expression, questionDotToken: QuestionDotToken?, name: dynamic /* String | Identifier | PrivateIdentifier */) -> PropertyAccessChain + +external var updatePropertyAccessChain: (node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: dynamic /* Identifier | PrivateIdentifier */) -> PropertyAccessChain + +external var createElementAccess: (expression: Expression, index: dynamic /* Number | Expression */) -> ElementAccessExpression + +external var updateElementAccess: (node: ElementAccessExpression, expression: Expression, argumentExpression: Expression) -> ElementAccessExpression + +external var createElementAccessChain: (expression: Expression, questionDotToken: QuestionDotToken?, index: dynamic /* Number | Expression */) -> ElementAccessChain + +external var updateElementAccessChain: (node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, argumentExpression: Expression) -> ElementAccessChain + +external var createCall: (expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> CallExpression + +external var updateCall: (node: CallExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array) -> CallExpression + +external var createCallChain: (expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array?) -> CallChain + +external var updateCallChain: (node: CallChain, expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array) -> CallChain + +external var createNew: (expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> NewExpression + +external var updateNew: (node: NewExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> NewExpression + +external var createTypeAssertion: (type: TypeNode, expression: Expression) -> TypeAssertion + +external var updateTypeAssertion: (node: TypeAssertion, type: TypeNode, expression: Expression) -> TypeAssertion + +external var createParen: (expression: Expression) -> ParenthesizedExpression + +external var updateParen: (node: ParenthesizedExpression, expression: Expression) -> ParenthesizedExpression + +external var createFunctionExpression: (modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block) -> FunctionExpression + +external var updateFunctionExpression: (node: FunctionExpression, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block) -> FunctionExpression + +external var createDelete: (expression: Expression) -> DeleteExpression + +external var updateDelete: (node: DeleteExpression, expression: Expression) -> DeleteExpression + +external var createTypeOf: (expression: Expression) -> TypeOfExpression + +external var updateTypeOf: (node: TypeOfExpression, expression: Expression) -> TypeOfExpression + +external var createVoid: (expression: Expression) -> VoidExpression + +external var updateVoid: (node: VoidExpression, expression: Expression) -> VoidExpression + +external var createAwait: (expression: Expression) -> AwaitExpression + +external var updateAwait: (node: AwaitExpression, expression: Expression) -> AwaitExpression + +external var createPrefix: (operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken | SyntaxKind.ExclamationToken */, operand: Expression) -> PrefixUnaryExpression + +external var updatePrefix: (node: PrefixUnaryExpression, operand: Expression) -> PrefixUnaryExpression + +external var createPostfix: (operand: Expression, operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken */) -> PostfixUnaryExpression + +external var updatePostfix: (node: PostfixUnaryExpression, operand: Expression) -> PostfixUnaryExpression + +external var createBinary: (left: Expression, operator: dynamic /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression) -> BinaryExpression + +external var updateConditional: (node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression) -> ConditionalExpression + +external var createTemplateExpression: (head: TemplateHead, templateSpans: Array) -> TemplateExpression + +external var updateTemplateExpression: (node: TemplateExpression, head: TemplateHead, templateSpans: Array) -> TemplateExpression + +external object createTemplateHead { + @nativeInvoke + operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateHead + @nativeInvoke + operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateHead +} + +external object createTemplateMiddle { + @nativeInvoke + operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateMiddle + @nativeInvoke + operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateMiddle +} + +external object createTemplateTail { + @nativeInvoke + operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateTail + @nativeInvoke + operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateTail +} + +external object createNoSubstitutionTemplateLiteral { + @nativeInvoke + operator fun invoke(text: String, rawText: String? = definedExternally): NoSubstitutionTemplateLiteral + @nativeInvoke + operator fun invoke(text: String?, rawText: String): NoSubstitutionTemplateLiteral +} + +external var updateYield: (node: YieldExpression, asteriskToken: AsteriskToken?, expression: Expression?) -> YieldExpression + +external var createSpread: (expression: Expression) -> SpreadElement + +external var updateSpread: (node: SpreadElement, expression: Expression) -> SpreadElement + +external var createOmittedExpression: () -> OmittedExpression + +external var createAsExpression: (expression: Expression, type: TypeNode) -> AsExpression + +external var updateAsExpression: (node: AsExpression, expression: Expression, type: TypeNode) -> AsExpression + +external var createNonNullExpression: (expression: Expression) -> NonNullExpression + +external var updateNonNullExpression: (node: NonNullExpression, expression: Expression) -> NonNullExpression + +external var createNonNullChain: (expression: Expression) -> NonNullChain + +external var updateNonNullChain: (node: NonNullChain, expression: Expression) -> NonNullChain + +external var createMetaProperty: (keywordToken: dynamic /* SyntaxKind.ImportKeyword | SyntaxKind.NewKeyword */, name: Identifier) -> MetaProperty + +external var updateMetaProperty: (node: MetaProperty, name: Identifier) -> MetaProperty + +external var createTemplateSpan: (expression: Expression, literal: dynamic /* TemplateMiddle | TemplateTail */) -> TemplateSpan + +external var updateTemplateSpan: (node: TemplateSpan, expression: Expression, literal: dynamic /* TemplateMiddle | TemplateTail */) -> TemplateSpan + +external var createSemicolonClassElement: () -> SemicolonClassElement + +external var createBlock: (statements: Array, multiLine: Boolean?) -> Block + +external var updateBlock: (node: Block, statements: Array) -> Block + +external var createVariableStatement: (modifiers: Array?, declarationList: dynamic /* VariableDeclarationList | Array */) -> VariableStatement + +external var updateVariableStatement: (node: VariableStatement, modifiers: Array?, declarationList: VariableDeclarationList) -> VariableStatement + +external var createEmptyStatement: () -> EmptyStatement + +external var createExpressionStatement: (expression: Expression) -> ExpressionStatement + +external var updateExpressionStatement: (node: ExpressionStatement, expression: Expression) -> ExpressionStatement + +external var createStatement: (expression: Expression) -> ExpressionStatement + +external var updateStatement: (node: ExpressionStatement, expression: Expression) -> ExpressionStatement + +external var createIf: (expression: Expression, thenStatement: Statement, elseStatement: Statement?) -> IfStatement + +external var updateIf: (node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement?) -> IfStatement + +external var createDo: (statement: Statement, expression: Expression) -> DoStatement + +external var updateDo: (node: DoStatement, statement: Statement, expression: Expression) -> DoStatement + +external var createWhile: (expression: Expression, statement: Statement) -> WhileStatement + +external var updateWhile: (node: WhileStatement, expression: Expression, statement: Statement) -> WhileStatement + +external var createFor: (initializer: dynamic /* VariableDeclarationList? | Expression? */, condition: Expression?, incrementor: Expression?, statement: Statement) -> ForStatement + +external var updateFor: (node: ForStatement, initializer: dynamic /* VariableDeclarationList? | Expression? */, condition: Expression?, incrementor: Expression?, statement: Statement) -> ForStatement + +external var createForIn: (initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForInStatement + +external var updateForIn: (node: ForInStatement, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForInStatement + +external var createForOf: (awaitModifier: AwaitKeyword?, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForOfStatement + +external var updateForOf: (node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForOfStatement + +external var createContinue: (label: dynamic /* String? | Identifier? */) -> ContinueStatement + +external var updateContinue: (node: ContinueStatement, label: Identifier?) -> ContinueStatement + +external var createBreak: (label: dynamic /* String? | Identifier? */) -> BreakStatement + +external var updateBreak: (node: BreakStatement, label: Identifier?) -> BreakStatement + +external var createReturn: (expression: Expression?) -> ReturnStatement + +external var updateReturn: (node: ReturnStatement, expression: Expression?) -> ReturnStatement + +external var createWith: (expression: Expression, statement: Statement) -> WithStatement + +external var updateWith: (node: WithStatement, expression: Expression, statement: Statement) -> WithStatement + +external var createSwitch: (expression: Expression, caseBlock: CaseBlock) -> SwitchStatement + +external var updateSwitch: (node: SwitchStatement, expression: Expression, caseBlock: CaseBlock) -> SwitchStatement + +external var createLabel: (label: dynamic /* String | Identifier */, statement: Statement) -> LabeledStatement + +external var updateLabel: (node: LabeledStatement, label: Identifier, statement: Statement) -> LabeledStatement + +external var createThrow: (expression: Expression) -> ThrowStatement + +external var updateThrow: (node: ThrowStatement, expression: Expression) -> ThrowStatement + +external var createTry: (tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?) -> TryStatement + +external var updateTry: (node: TryStatement, tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?) -> TryStatement + +external var createDebuggerStatement: () -> DebuggerStatement + +external var createVariableDeclarationList: (declarations: Array, flags: NodeFlags?) -> VariableDeclarationList + +external var updateVariableDeclarationList: (node: VariableDeclarationList, declarations: Array) -> VariableDeclarationList + +external var createFunctionDeclaration: (decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> FunctionDeclaration + +external var updateFunctionDeclaration: (node: FunctionDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> FunctionDeclaration + +external var createClassDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassDeclaration + +external var updateClassDeclaration: (node: ClassDeclaration, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassDeclaration + +external var createInterfaceDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> InterfaceDeclaration + +external var updateInterfaceDeclaration: (node: InterfaceDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array) -> InterfaceDeclaration + +external var createTypeAliasDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, typeParameters: Array?, type: TypeNode) -> TypeAliasDeclaration + +external var updateTypeAliasDeclaration: (node: TypeAliasDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode) -> TypeAliasDeclaration + +external var createEnumDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, members: Array) -> EnumDeclaration + +external var updateEnumDeclaration: (node: EnumDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, members: Array) -> EnumDeclaration + +external var createModuleDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral */, body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */, flags: NodeFlags?) -> ModuleDeclaration + +external var updateModuleDeclaration: (node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral */, body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */) -> ModuleDeclaration + +external var createModuleBlock: (statements: Array) -> ModuleBlock + +external var updateModuleBlock: (node: ModuleBlock, statements: Array) -> ModuleBlock + +external var createCaseBlock: (clauses: Array) -> CaseBlock + +external var updateCaseBlock: (node: CaseBlock, clauses: Array) -> CaseBlock + +external var createNamespaceExportDeclaration: (name: dynamic /* String | Identifier */) -> NamespaceExportDeclaration + +external var updateNamespaceExportDeclaration: (node: NamespaceExportDeclaration, name: Identifier) -> NamespaceExportDeclaration + +external var createImportEqualsDeclaration: (decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: dynamic /* String | Identifier */, moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */) -> ImportEqualsDeclaration + +external var updateImportEqualsDeclaration: (node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */) -> ImportEqualsDeclaration + +external var createImportDeclaration: (decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression) -> ImportDeclaration + +external var updateImportDeclaration: (node: ImportDeclaration, decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression) -> ImportDeclaration + +external var createNamespaceImport: (name: Identifier) -> NamespaceImport + +external var updateNamespaceImport: (node: NamespaceImport, name: Identifier) -> NamespaceImport + +external var createNamedImports: (elements: Array) -> NamedImports + +external var updateNamedImports: (node: NamedImports, elements: Array) -> NamedImports + +external var createImportSpecifier: (propertyName: Identifier?, name: Identifier) -> ImportSpecifier + +external var updateImportSpecifier: (node: ImportSpecifier, propertyName: Identifier?, name: Identifier) -> ImportSpecifier + +external var createExportAssignment: (decorators: Array?, modifiers: Array?, isExportEquals: Boolean?, expression: Expression) -> ExportAssignment + +external var updateExportAssignment: (node: ExportAssignment, decorators: Array?, modifiers: Array?, expression: Expression) -> ExportAssignment + +external var createNamedExports: (elements: Array) -> NamedExports + +external var updateNamedExports: (node: NamedExports, elements: Array) -> NamedExports + +external var createExportSpecifier: (propertyName: dynamic /* String? | Identifier? */, name: dynamic /* String | Identifier */) -> ExportSpecifier + +external var updateExportSpecifier: (node: ExportSpecifier, propertyName: Identifier?, name: Identifier) -> ExportSpecifier + +external var createExternalModuleReference: (expression: Expression) -> ExternalModuleReference + +external var updateExternalModuleReference: (node: ExternalModuleReference, expression: Expression) -> ExternalModuleReference + +external var createJSDocTypeExpression: (type: TypeNode) -> JSDocTypeExpression + +external var createJSDocTypeTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocTypeTag + +external var createJSDocReturnTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: dynamic /* String? | NodeArray? */) -> JSDocReturnTag + +external var createJSDocThisTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocThisTag + +external var createJSDocComment: (comment: dynamic /* String? | NodeArray? */, tags: Array?) -> JSDoc + +external var createJSDocParameterTag: (tagName: Identifier?, name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean?, comment: dynamic /* String? | NodeArray? */) -> JSDocParameterTag + +external var createJSDocClassTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocClassTag + +external var createJSDocAugmentsTag: (tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: dynamic /* String? | NodeArray? */) -> JSDocAugmentsTag + +external var createJSDocEnumTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocEnumTag + +external var createJSDocTemplateTag: (tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: dynamic /* String? | NodeArray? */) -> JSDocTemplateTag + +external var createJSDocTypedefTag: (tagName: Identifier?, typeExpression: dynamic /* JSDocTypeLiteral? | JSDocTypeExpression? */, fullName: dynamic /* Identifier? | JSDocNamespaceDeclaration? */, comment: dynamic /* String? | NodeArray? */) -> JSDocTypedefTag + +external var createJSDocCallbackTag: (tagName: Identifier?, typeExpression: JSDocSignature, fullName: dynamic /* Identifier? | JSDocNamespaceDeclaration? */, comment: dynamic /* String? | NodeArray? */) -> JSDocCallbackTag + +external var createJSDocSignature: (typeParameters: Array?, parameters: Array, type: JSDocReturnTag?) -> JSDocSignature + +external var createJSDocPropertyTag: (tagName: Identifier?, name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean?, comment: dynamic /* String? | NodeArray? */) -> JSDocPropertyTag + +external var createJSDocTypeLiteral: (jsDocPropertyTags: Array?, isArrayType: Boolean?) -> JSDocTypeLiteral + +external var createJSDocImplementsTag: (tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: dynamic /* String? | NodeArray? */) -> JSDocImplementsTag + +external var createJSDocAuthorTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocAuthorTag + +external var createJSDocPublicTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocPublicTag + +external var createJSDocPrivateTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocPrivateTag + +external var createJSDocProtectedTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocProtectedTag + +external var createJSDocReadonlyTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocReadonlyTag + +external var createJSDocTag: (tagName: Identifier, comment: dynamic /* String? | NodeArray? */) -> JSDocUnknownTag + +external var createJsxElement: (openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement) -> JsxElement + +external var updateJsxElement: (node: JsxElement, openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement) -> JsxElement + +external var createJsxSelfClosingElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxSelfClosingElement + +external var updateJsxSelfClosingElement: (node: JsxSelfClosingElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxSelfClosingElement + +external var createJsxOpeningElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxOpeningElement + +external var updateJsxOpeningElement: (node: JsxOpeningElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxOpeningElement + +external var createJsxClosingElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */) -> JsxClosingElement + +external var updateJsxClosingElement: (node: JsxClosingElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */) -> JsxClosingElement + +external var createJsxFragment: (openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment) -> JsxFragment + +external var createJsxText: (text: String, containsOnlyTriviaWhiteSpaces: Boolean?) -> JsxText + +external var updateJsxText: (node: JsxText, text: String, containsOnlyTriviaWhiteSpaces: Boolean?) -> JsxText + +external var createJsxOpeningFragment: () -> JsxOpeningFragment + +external var createJsxJsxClosingFragment: () -> JsxClosingFragment + +external var updateJsxFragment: (node: JsxFragment, openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment) -> JsxFragment + +external var createJsxAttribute: (name: Identifier, initializer: dynamic /* StringLiteral? | JsxExpression? */) -> JsxAttribute + +external var updateJsxAttribute: (node: JsxAttribute, name: Identifier, initializer: dynamic /* StringLiteral? | JsxExpression? */) -> JsxAttribute + +external var createJsxAttributes: (properties: Array) -> JsxAttributes + +external var updateJsxAttributes: (node: JsxAttributes, properties: Array) -> JsxAttributes + +external var createJsxSpreadAttribute: (expression: Expression) -> JsxSpreadAttribute + +external var updateJsxSpreadAttribute: (node: JsxSpreadAttribute, expression: Expression) -> JsxSpreadAttribute + +external var createJsxExpression: (dotDotDotToken: DotDotDotToken?, expression: Expression?) -> JsxExpression + +external var updateJsxExpression: (node: JsxExpression, expression: Expression?) -> JsxExpression + +external var createCaseClause: (expression: Expression, statements: Array) -> CaseClause + +external var updateCaseClause: (node: CaseClause, expression: Expression, statements: Array) -> CaseClause + +external var createDefaultClause: (statements: Array) -> DefaultClause + +external var updateDefaultClause: (node: DefaultClause, statements: Array) -> DefaultClause + +external var createHeritageClause: (token: dynamic /* SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword */, types: Array) -> HeritageClause + +external var updateHeritageClause: (node: HeritageClause, types: Array) -> HeritageClause + +external var createCatchClause: (variableDeclaration: dynamic /* String? | VariableDeclaration? */, block: Block) -> CatchClause + +external var updateCatchClause: (node: CatchClause, variableDeclaration: VariableDeclaration?, block: Block) -> CatchClause + +external var createPropertyAssignment: (name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression) -> PropertyAssignment + +external var updatePropertyAssignment: (node: PropertyAssignment, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression) -> PropertyAssignment + +external var createShorthandPropertyAssignment: (name: dynamic /* String | Identifier */, objectAssignmentInitializer: Expression?) -> ShorthandPropertyAssignment + +external var updateShorthandPropertyAssignment: (node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression?) -> ShorthandPropertyAssignment + +external var createSpreadAssignment: (expression: Expression) -> SpreadAssignment + +external var updateSpreadAssignment: (node: SpreadAssignment, expression: Expression) -> SpreadAssignment + +external var createEnumMember: (name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression?) -> EnumMember + +external var updateEnumMember: (node: EnumMember, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression?) -> EnumMember + +external var updateSourceFileNode: (node: SourceFile, statements: Array, isDeclarationFile: Boolean?, referencedFiles: Array?, typeReferences: Array?, hasNoDefaultLib: Boolean?, libReferences: Array?) -> SourceFile + +external var createNotEmittedStatement: (original: Node) -> NotEmittedStatement + +external var createPartiallyEmittedExpression: (expression: Expression, original: Node?) -> PartiallyEmittedExpression + +external var updatePartiallyEmittedExpression: (node: PartiallyEmittedExpression, expression: Expression) -> PartiallyEmittedExpression + +external var createCommaList: (elements: Array) -> CommaListExpression + +external var updateCommaList: (node: CommaListExpression, elements: Array) -> CommaListExpression + +external var createBundle: (sourceFiles: Array, prepends: Array?) -> Bundle + +external var updateBundle: (node: Bundle, sourceFiles: Array, prepends: Array?) -> Bundle + +external object createImmediatelyInvokedFunctionExpression { + @nativeInvoke + operator fun invoke(statements: Array): CallExpression + @nativeInvoke + operator fun invoke(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression +} + +external object createImmediatelyInvokedArrowFunction { + @nativeInvoke + operator fun invoke(statements: Array): CallExpression + @nativeInvoke + operator fun invoke(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression +} + +external var createVoidZero: () -> VoidExpression + +external var createExportDefault: (expression: Expression) -> ExportAssignment + +external var createExternalModuleExport: (exportName: Identifier) -> ExportDeclaration + +external var createNamespaceExport: (name: Identifier) -> NamespaceExport + +external var updateNamespaceExport: (node: NamespaceExport, name: Identifier) -> NamespaceExport + +external var createToken: (kind: TKind) -> Token + +external var createIdentifier: (text: String) -> Identifier + +external var createTempVariable: (recordTempVariable: ((node: Identifier) -> Unit)?) -> Identifier + +external var getGeneratedNameForNode: (node: Node?) -> Identifier + +external var createOptimisticUniqueName: (text: String) -> Identifier + +external var createFileLevelUniqueName: (text: String) -> Identifier + +external var createIndexSignature: (decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode) -> IndexSignatureDeclaration + +external var createTypePredicateNode: (parameterName: dynamic /* Identifier | ThisTypeNode | String */, type: TypeNode) -> TypePredicateNode + +external var updateTypePredicateNode: (node: TypePredicateNode, parameterName: dynamic /* Identifier | ThisTypeNode */, type: TypeNode) -> TypePredicateNode + +external object createLiteral { + @nativeInvoke + operator fun invoke(value: Any /* String | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier */): StringLiteral + @nativeInvoke + operator fun invoke(value: Any /* Number | PseudoBigInt */): NumericLiteral + @nativeInvoke + operator fun invoke(value: Boolean): dynamic /* TrueLiteral | FalseLiteral */ + @nativeInvoke + operator fun invoke(value: Any /* String | Number | PseudoBigInt | Boolean */): PrimaryExpression +} + +external var createMethodSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?) -> MethodSignature + +external var updateMethodSignature: (node: MethodSignature, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?) -> MethodSignature + +external object createTypeOperatorNode { + @nativeInvoke + operator fun invoke(type: TypeNode): TypeOperatorNode + @nativeInvoke + operator fun invoke(operator: Any /* SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword */, type: TypeNode): TypeOperatorNode +} + +external object createTaggedTemplate { + @nativeInvoke + operator fun invoke(tag: Expression, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression + @nativeInvoke + operator fun invoke(tag: Expression, typeArguments: Array?, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression +} + +external object updateTaggedTemplate { + @nativeInvoke + operator fun invoke(node: TaggedTemplateExpression, tag: Expression, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression + @nativeInvoke + operator fun invoke(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression +} + +external var updateBinary: (node: BinaryExpression, left: Expression, right: Expression, operator: dynamic /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */) -> BinaryExpression + +external object createConditional { + @nativeInvoke + operator fun invoke(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression + @nativeInvoke + operator fun invoke(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression +} + +external object createYield { + @nativeInvoke + operator fun invoke(expression: Expression? = definedExternally): YieldExpression + @nativeInvoke + operator fun invoke(asteriskToken: AsteriskToken?, expression: Expression): YieldExpression +} + +external var createClassExpression: (modifiers: Array?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassExpression + +external var updateClassExpression: (node: ClassExpression, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassExpression + +external var createPropertySignature: (modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | String */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> PropertySignature + +external var updatePropertySignature: (node: PropertySignature, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> PropertySignature + +external var createExpressionWithTypeArguments: (typeArguments: Array?, expression: Expression) -> ExpressionWithTypeArguments + +external var updateExpressionWithTypeArguments: (node: ExpressionWithTypeArguments, typeArguments: Array?, expression: Expression) -> ExpressionWithTypeArguments + +external object createArrowFunction { + @nativeInvoke + operator fun invoke(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: Any /* FunctionBody | Expression */): ArrowFunction + @nativeInvoke + operator fun invoke(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Any /* FunctionBody | Expression */): ArrowFunction +} + +external object updateArrowFunction { + @nativeInvoke + operator fun invoke(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: Any /* FunctionBody | Expression */): ArrowFunction + @nativeInvoke + operator fun invoke(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Any /* FunctionBody | Expression */): ArrowFunction +} + +external object createVariableDeclaration { + @nativeInvoke + operator fun invoke(name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, type: TypeNode? = definedExternally, initializer: Expression? = definedExternally): VariableDeclaration + @nativeInvoke + operator fun invoke(name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration +} + +external object updateVariableDeclaration { + @nativeInvoke + operator fun invoke(node: VariableDeclaration, name: Any /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, type: TypeNode?, initializer: Expression?): VariableDeclaration + @nativeInvoke + operator fun invoke(node: VariableDeclaration, name: Any /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration +} + +external var createImportClause: (name: Identifier?, namedBindings: dynamic /* NamespaceImport? | NamedImports? */, isTypeOnly: Any) -> ImportClause + +external var updateImportClause: (node: ImportClause, name: Identifier?, namedBindings: dynamic /* NamespaceImport? | NamedImports? */, isTypeOnly: Boolean) -> ImportClause + +external var createExportDeclaration: (decorators: Array?, modifiers: Array?, exportClause: dynamic /* NamespaceExport? | NamedExports? */, moduleSpecifier: Expression?, isTypeOnly: Any) -> ExportDeclaration + +external var updateExportDeclaration: (node: ExportDeclaration, decorators: Array?, modifiers: Array?, exportClause: dynamic /* NamespaceExport? | NamedExports? */, moduleSpecifier: Expression?, isTypeOnly: Boolean) -> ExportDeclaration + +external var createJSDocParamTag: (name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, comment: String?) -> JSDocParameterTag + +external var createComma: (left: Expression, right: Expression) -> Expression + +external var createLessThan: (left: Expression, right: Expression) -> Expression + +external var createAssignment: (left: Expression, right: Expression) -> BinaryExpression + +external var createStrictEquality: (left: Expression, right: Expression) -> BinaryExpression + +external var createStrictInequality: (left: Expression, right: Expression) -> BinaryExpression + +external var createAdd: (left: Expression, right: Expression) -> BinaryExpression + +external var createSubtract: (left: Expression, right: Expression) -> BinaryExpression + +external var createLogicalAnd: (left: Expression, right: Expression) -> BinaryExpression + +external var createLogicalOr: (left: Expression, right: Expression) -> BinaryExpression + +external var createPostfixIncrement: (operand: Expression) -> PostfixUnaryExpression + +external var createLogicalNot: (operand: Expression) -> PrefixUnaryExpression + +external var createNode: (kind: SyntaxKind, pos: Any, end: Any) -> Node + +external var getMutableClone: (node: T) -> T + +external var isTypeAssertion: (node: Node) -> Boolean + +external var isIdentifierOrPrivateIdentifier: (node: Node) -> Boolean \ No newline at end of file diff --git a/modules/mod2/externals/typescript.ts.server.module_typescript.kt b/modules/mod2/externals/typescript.ts.server.module_typescript.kt new file mode 100644 index 0000000..4ce5432 --- /dev/null +++ b/modules/mod2/externals/typescript.ts.server.module_typescript.kt @@ -0,0 +1,104 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +package ts.server + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.CompilerOptions +import ts.WatchOptions +import ts.TypeAcquisition +import ts.SortedReadonlyArray + +external interface TypingInstallerResponse { + var kind: String /* "action::set" | "action::invalidate" | "event::typesRegistry" | "action::packageInstalled" | "event::beginInstallTypes" | "event::endInstallTypes" | "event::initializationFailed" */ +} + +external interface TypingInstallerRequestWithProjectName { + var projectName: String +} + +external interface DiscoverTypings : TypingInstallerRequestWithProjectName { + var fileNames: Array + var projectRootPath: String /* String & `T$3` */ + var compilerOptions: CompilerOptions + var watchOptions: WatchOptions? + get() = definedExternally + set(value) = definedExternally + var typeAcquisition: TypeAcquisition + var unresolvedImports: SortedReadonlyArray + var cachePath: String? + get() = definedExternally + set(value) = definedExternally + var kind: String /* "discover" */ +} + +external interface CloseProject : TypingInstallerRequestWithProjectName { + var kind: String /* "closeProject" */ +} + +external interface TypesRegistryRequest { + var kind: String /* "typesRegistry" */ +} + +external interface InstallPackageRequest : TypingInstallerRequestWithProjectName { + var kind: String /* "installPackage" */ + var fileName: String /* String & `T$3` */ + var packageName: String + var projectRootPath: String /* String & `T$3` */ +} + +external interface PackageInstalledResponse : ProjectResponse { + override var kind: String /* "action::packageInstalled" */ + var success: Boolean + var message: String +} + +external interface InitializationFailedResponse : TypingInstallerResponse { + override var kind: String /* "event::initializationFailed" */ + var message: String + var stack: String? + get() = definedExternally + set(value) = definedExternally +} + +external interface ProjectResponse : TypingInstallerResponse { + var projectName: String +} + +external interface InvalidateCachedTypings : ProjectResponse { + override var kind: String /* "action::invalidate" */ +} + +external interface InstallTypes : ProjectResponse { + override var kind: String /* "event::beginInstallTypes" | "event::endInstallTypes" */ + var eventId: Number + var typingsInstallerVersion: String + var packagesToInstall: Array +} + +external interface BeginInstallTypes : InstallTypes { + override var kind: String /* "event::beginInstallTypes" */ +} + +external interface EndInstallTypes : InstallTypes { + override var kind: String /* "event::endInstallTypes" */ + var installSuccess: Boolean +} + +external interface SetTypings : ProjectResponse { + var typeAcquisition: TypeAcquisition + var compilerOptions: CompilerOptions + var typings: Array + var unresolvedImports: SortedReadonlyArray + override var kind: String /* "action::set" */ +} \ No newline at end of file diff --git a/modules/mod2/externals/utils.module_typescript-to-lua.kt b/modules/mod2/externals/utils.module_typescript-to-lua.kt new file mode 100644 index 0000000..08363d8 --- /dev/null +++ b/modules/mod2/externals/utils.module_typescript-to-lua.kt @@ -0,0 +1,46 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.WriteFileCallback +import ts.SourceFile + +external interface EmitHost { + fun directoryExists(path: String): Boolean + fun fileExists(path: String): Boolean + fun getCurrentDirectory(): String + fun readFile(path: String): String? + var writeFile: WriteFileCallback +} + +external interface BaseFile { + var code: String + var sourceMap: String? + get() = definedExternally + set(value) = definedExternally + var sourceFiles: Array? + get() = definedExternally + set(value) = definedExternally +} + +external interface ProcessedFile : BaseFile { + var fileName: String + var luaAst: File? + get() = definedExternally + set(value) = definedExternally +} + +external interface EmitFile : BaseFile { + var outputPath: String +} \ No newline at end of file diff --git a/modules/mod2/externals/visitors.module_typescript-to-lua.kt b/modules/mod2/externals/visitors.module_typescript-to-lua.kt new file mode 100644 index 0000000..69513ac --- /dev/null +++ b/modules/mod2/externals/visitors.module_typescript-to-lua.kt @@ -0,0 +1,38 @@ +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") + +import kotlin.js.* +import org.khronos.webgl.* +import org.w3c.dom.* +import org.w3c.dom.events.* +import org.w3c.dom.parsing.* +import org.w3c.dom.svg.* +import org.w3c.dom.url.* +import org.w3c.fetch.* +import org.w3c.files.* +import org.w3c.notifications.* +import org.w3c.performance.* +import org.w3c.workers.* +import org.w3c.xhr.* +import ts.Statement +import ts.Node +import tsstdlib.Map +import ts.SyntaxKind + +external interface NodesBySyntaxKind + +typealias StatementLikeNode = Statement + +typealias VisitorResult = Any + +typealias FunctionVisitor = (node: T, context: TransformationContext) -> VisitorResult + +external interface ObjectVisitor { + var transform: FunctionVisitor + var priority: Number? + get() = definedExternally + set(value) = definedExternally +} + +typealias Visitors = Any + +typealias VisitorMap = Map>> \ No newline at end of file diff --git a/modules/server/settings.gradle.kts b/modules/server/settings.gradle.kts deleted file mode 100644 index 36dc4be..0000000 --- a/modules/server/settings.gradle.kts +++ /dev/null @@ -1,3 +0,0 @@ -rootProject.name = "factorio-web-map-server" - -rootProject.description = "Factorio Web Map server" diff --git a/settings.gradle.kts b/settings.gradle.kts index 8ae1bcb..bc26244 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,10 @@ - rootProject.name = "factorio-web-map" +include( +// ":modules:mod", + ":modules:mod2", + ":modules:server", +) enableFeaturePreview("VERSION_CATALOGS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") @@ -8,12 +12,33 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") @Suppress("UnstableApiUsage") dependencyResolutionManagement { -// repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + // https://github.com/gradle/gradle/issues/15754#issuecomment-763614651 + // https://github.com/gradle/gradle/blob/09fcaacc9848f09aa584b4119be9271bee6916e6/build-logic/build-logic-base/settings-plugin/src/main/kotlin/gradlebuild.repositories.settings.gradle.kts#L68 + + // Cannot use 'FAIL_ON_PROJECT_REPOS' because + // - the 'gradle-guides-plugin' adds a repo (which it should not do) + // - the 'kotlin-gradle-plugin' adds a repo (and removes it afterwards) to download NodeJS + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) repositories { mavenCentral() - maven ("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") + maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") + + // Declare the Node.js download repository + ivy { + name = "Node.js" + setUrl("https://nodejs.org/dist/") + patternLayout { + artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") + } + metadataSources { + artifact() + } + content { + includeModule("org.nodejs", "node") + } + } } pluginManagement { diff --git a/xbuild.gradle.kts b/xbuild.gradle.kts new file mode 100644 index 0000000..de53fb0 --- /dev/null +++ b/xbuild.gradle.kts @@ -0,0 +1,124 @@ +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension + +plugins { + kotlin("multiplatform") version "1.5.31" +} + +group = "dev.adamko.factoriowebmap" +version = "1.0-SNAPSHOT" + +kotlin { + + // + val hostOs = System.getProperty("os.name") + val isMingwX64 = hostOs.startsWith("Windows") + val nativeTarget = when { + hostOs == "Mac OS X" -> macosX64("native") + hostOs == "Linux" -> linuxX64("native") + isMingwX64 -> mingwX64("native") + else -> throw GradleException( + "Host OS '$hostOs' is not supported in Kotlin/Native.") + } + + nativeTarget.apply { + binaries { + executable { + entryPoint = "main" + } + sharedLib { + baseName = if (isMingwX64) "libnative" else "native" + } + } + } + sourceSets { + val nativeMain by getting { + dependencies { + implementation("com.soywiz.korlibs.luak:luak:2.4.3") + } + } + val nativeTest by getting { + dependencies { + implementation(kotlin("test")) + + } + } + } + // + + // + js(IR) { + binaries.executable() + browser { + commonWebpackConfig { + cssSupport.enabled = true + } + } + + useCommonJs() + nodejs() + + compilations["main"].apply { + packageJson { + customField( + "scripts", + mapOf( + "build" to "tstl", + "dev" to "tstl --watch", + ) + ) + } + } + + } + + sourceSets { + + val jsMain by getting { + kotlin.srcDir("externals02") +// kotlin.srcDir("externals") + + dependencies { + + val kotlinWrappersVersion = "0.0.1-pre.254-kotlin-1.5.31" + implementation( + project.dependencies.enforcedPlatform( + "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" + ) + ) + + implementation("org.jetbrains.kotlin-wrappers:kotlin-react") + implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom") + implementation(npm("react", "17.0.2")) + implementation(npm("react-dom", "17.0.2")) + +// implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7") { +// because("https://github.com/Kotlin/kotlinx-nodejs") +// } + + val generateExternals = false + implementation(npm("typescript-to-lua", "1.0.1", generateExternals = generateExternals)) + implementation(npm("typed-factorio", "0.7.1", generateExternals = generateExternals)) + implementation(npm("lua-types", "2.11.0", generateExternals = generateExternals)) + implementation(npm("typescript", "4.4.3", generateExternals = generateExternals)) + } + } + + val jsTest by getting { + dependencies { + implementation(kotlin("test-js")) + } + } + } + // + +} + +configure { + versions.dukat.version = "0.5.8-rc.4-dev.20211001" +// versions.dukat.version = "0.5.8-rc.4" +} + +tasks.wrapper { + gradleVersion = "7.2" + distributionType = Wrapper.DistributionType.ALL +} From fb80ca3f79da38bb3df8c9a121b262efb2678a9d Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sun, 10 Oct 2021 21:26:11 +0200 Subject: [PATCH 008/629] fix compile errors --- buildSrc/build.gradle.kts | 6 + .../dukat-custom/5.2-only.module_lua-types.kt | 2 +- .../dukat-custom/5.2-plus.module_lua-types.kt | 6 +- .../5.2-only.bit32.module_lua-types.kt | 0 .../builtin-types.module_typed-factorio.kt | 32 +- .../classes.module_typed-factorio.kt | 994 +++++++++--------- .../coroutine.coroutine.module_lua-types.kt | 0 .../debug.debug.module_lua-types.kt | 4 +- ....control_behavior.module_typed-factorio.kt | 0 ...behavior.inserter.module_typed-factorio.kt | 0 ...rol_behavior.lamp.module_typed-factorio.kt | 0 ...ogistic_container.module_typed-factorio.kt | 0 ...vior.mining_drill.module_typed-factorio.kt | 0 ...or.transport_belt.module_typed-factorio.kt | 0 ...construction_item.module_typed-factorio.kt | 0 .../defines.defines.module_typed-factorio.kt | 0 ...fficulty_settings.module_typed-factorio.kt | 0 ...es.defines.events.module_typed-factorio.kt | 0 ...es.defines.riding.module_typed-factorio.kt | 0 .../events.module_typed-factorio.kt | 70 +- .../dukat-custom/global.module_lua-types.kt | 2 +- .../index.module_typescript-to-lua.kt | 5 +- .../mod2/dukat-custom/io.module_lua-types.kt | 2 +- .../{ => io}/io.io.module_lua-types.kt | 2 +- .../{ => io}/nonDeclarations.io.kt | 0 ...ariesAndFunctions.module_typed-factorio.kt | 12 +- .../{ => math}/math.math.module_lua-types.kt | 0 .../metatable.module_lua-types.kt | 6 +- .../mod-gui.mod_gui.module_typed-factorio.kt | 0 .../mod2/dukat-custom/os.module_lua-types.kt | 2 +- .../{ => os}/os.os.module_lua-types.kt | 0 .../modules.package.module_lua-types.kt | 0 ...Functions.serpent.module_typed-factorio.kt | 0 .../string.string.module_lua-types.kt | 0 .../table.table.module_lua-types.kt | 2 +- .../dukat-custom/{ => tsstdlib}/lib.dom.kt | 0 .../{ => tsstdlib}/lib.es2015.iterable.kt | 2 +- .../dukat-custom/{ => tsstdlib}/lib.es5.kt | 0 .../types.module_typed-factorio.kt | 2 +- .../util.util.table.module_typed-factorio.kt | 0 .../util.util.module_typed-factorio.kt | 17 +- 41 files changed, 606 insertions(+), 562 deletions(-) rename modules/mod2/dukat-custom/{ => bit32}/5.2-only.bit32.module_lua-types.kt (100%) rename modules/mod2/dukat-custom/{ => coroutine}/coroutine.coroutine.module_lua-types.kt (100%) rename modules/mod2/dukat-custom/{ => debug}/debug.debug.module_lua-types.kt (99%) rename modules/mod2/dukat-custom/{ => defines/control_behavior}/defines.defines.control_behavior.module_typed-factorio.kt (100%) rename modules/mod2/dukat-custom/{ => defines/control_behavior/inserter}/defines.defines.control_behavior.inserter.module_typed-factorio.kt (100%) rename modules/mod2/dukat-custom/{ => defines/control_behavior/lamp}/defines.defines.control_behavior.lamp.module_typed-factorio.kt (100%) rename modules/mod2/dukat-custom/{ => defines/control_behavior/logistic_container}/defines.defines.control_behavior.logistic_container.module_typed-factorio.kt (100%) rename modules/mod2/dukat-custom/{ => defines/control_behavior/mining_drill}/defines.defines.control_behavior.mining_drill.module_typed-factorio.kt (100%) rename modules/mod2/dukat-custom/{ => defines/control_behavior/transport_belt}/defines.defines.control_behavior.transport_belt.module_typed-factorio.kt (100%) rename modules/mod2/dukat-custom/{ => defines/deconstruction_item}/defines.defines.deconstruction_item.module_typed-factorio.kt (100%) rename modules/mod2/dukat-custom/{ => defines}/defines.defines.module_typed-factorio.kt (100%) rename modules/mod2/dukat-custom/{ => defines/difficulty_settings}/defines.defines.difficulty_settings.module_typed-factorio.kt (100%) rename modules/mod2/dukat-custom/{ => defines/events}/defines.defines.events.module_typed-factorio.kt (100%) rename modules/mod2/dukat-custom/{ => defines/riding}/defines.defines.riding.module_typed-factorio.kt (100%) rename modules/mod2/dukat-custom/{ => io}/io.io.module_lua-types.kt (94%) rename modules/mod2/dukat-custom/{ => io}/nonDeclarations.io.kt (100%) rename modules/mod2/dukat-custom/{ => math}/math.math.module_lua-types.kt (100%) rename modules/mod2/dukat-custom/{ => mod_gui}/mod-gui.mod_gui.module_typed-factorio.kt (100%) rename modules/mod2/dukat-custom/{ => os}/os.os.module_lua-types.kt (100%) rename modules/mod2/dukat-custom/{ => package}/modules.package.module_lua-types.kt (100%) rename modules/mod2/dukat-custom/{ => serpent}/librariesAndFunctions.serpent.module_typed-factorio.kt (100%) rename modules/mod2/dukat-custom/{ => string}/string.string.module_lua-types.kt (100%) rename modules/mod2/dukat-custom/{ => table}/table.table.module_lua-types.kt (98%) rename modules/mod2/dukat-custom/{ => tsstdlib}/lib.dom.kt (100%) rename modules/mod2/dukat-custom/{ => tsstdlib}/lib.es2015.iterable.kt (98%) rename modules/mod2/dukat-custom/{ => tsstdlib}/lib.es5.kt (100%) rename modules/mod2/dukat-custom/{ => util/table}/util.util.table.module_typed-factorio.kt (100%) rename modules/mod2/dukat-custom/{ => util}/util.util.module_typed-factorio.kt (84%) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 4f2b743..f337b75 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,11 +1,17 @@ plugins { `kotlin-dsl` + kotlin("jvm") version "1.5.31" } dependencies { val kotlinVersion = "1.5.31" +// implementation(gradleApi()) + +// implementation("org.gradle.kotlin:gradle-kotlin-dsl-plugins:${org.gradle.kotlin.dsl.support.expectedKotlinDslPluginsVersion}") +// implementation("org.gradle.kotlin:gradle-kotlin-dsl-plugins:${kotlinVersion}") + implementation(platform("org.jetbrains.kotlin:kotlin-bom:$kotlinVersion")) implementation("org.jetbrains.kotlin:kotlin-gradle-plugin") diff --git a/modules/mod2/dukat-custom/5.2-only.module_lua-types.kt b/modules/mod2/dukat-custom/5.2-only.module_lua-types.kt index 85d3c1e..d47462e 100644 --- a/modules/mod2/dukat-custom/5.2-only.module_lua-types.kt +++ b/modules/mod2/dukat-custom/5.2-only.module_lua-types.kt @@ -14,4 +14,4 @@ import org.w3c.performance.* import org.w3c.workers.* import org.w3c.xhr.* -external fun collectgarbage(opt: String /* "count" | "generational" | "incremental" */): dynamic /* Unit */ \ No newline at end of file +//external fun collectgarbage(opt: String /* "count" | "generational" | "incremental" */): dynamic /* Unit */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/5.2-plus.module_lua-types.kt b/modules/mod2/dukat-custom/5.2-plus.module_lua-types.kt index b7e567f..adcf485 100644 --- a/modules/mod2/dukat-custom/5.2-plus.module_lua-types.kt +++ b/modules/mod2/dukat-custom/5.2-plus.module_lua-types.kt @@ -15,8 +15,8 @@ import org.w3c.workers.* import org.w3c.xhr.* import tsstdlib.Record -external var _ENV: Record +//external var _ENV: Record -external fun collectgarbage(opt: String /* "isrunning" */): Boolean +//external fun collectgarbage(opt: String /* "isrunning" */): Boolean -external fun module(name: String, vararg options: Function<*>) \ No newline at end of file +//external fun module(name: String, vararg options: Function<*>) \ No newline at end of file diff --git a/modules/mod2/dukat-custom/5.2-only.bit32.module_lua-types.kt b/modules/mod2/dukat-custom/bit32/5.2-only.bit32.module_lua-types.kt similarity index 100% rename from modules/mod2/dukat-custom/5.2-only.bit32.module_lua-types.kt rename to modules/mod2/dukat-custom/bit32/5.2-only.bit32.module_lua-types.kt diff --git a/modules/mod2/dukat-custom/builtin-types.module_typed-factorio.kt b/modules/mod2/dukat-custom/builtin-types.module_typed-factorio.kt index f03d9c3..ecd4eab 100644 --- a/modules/mod2/dukat-custom/builtin-types.module_typed-factorio.kt +++ b/modules/mod2/dukat-custom/builtin-types.module_typed-factorio.kt @@ -1,6 +1,7 @@ @file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") import kotlin.js.* +import kotlinext.js.PropertyDescriptor import org.khronos.webgl.* import org.w3c.dom.* import org.w3c.dom.events.* @@ -30,4 +31,33 @@ typealias uint16 = Number typealias uint64 = Number -typealias table = Any? \ No newline at end of file +//typealias table = Any? +// TODO LuaTable? AnyTable? index.module_typescript-to-lua.kt +@JsName("table") +class table : Object2() + +/** https://github.com/JetBrains/kotlin-wrappers/blob/master/kotlin-extensions/src/main/kotlin/kotlinext/js/Object.kt */ +open external class Object2 { + fun toLocaleString(): String + fun valueOf(): dynamic + fun hasOwnProperty(v: String): Boolean + fun isPrototypeOf(v: Any): Boolean + fun propertyIsEnumerable(v: String): Boolean + + companion object { + fun

getPrototypeOf(o: T): P + fun getOwnPropertyDescriptor(o: Any, p: String): PropertyDescriptor + fun getOwnPropertyNames(o: Any): Array + fun create(o: T?, properties: dynamic = definedExternally): T + fun defineProperty(o: T, p: String, attributes: PropertyDescriptor

+ + diff --git a/modules/server/src/test/kotlin/test/com/example/AppSpec.kt b/modules/server/src/test/kotlin/test/com/example/AppSpec.kt new file mode 100644 index 0000000..33d8534 --- /dev/null +++ b/modules/server/src/test/kotlin/test/com/example/AppSpec.kt @@ -0,0 +1,15 @@ +package test.com.example + +import io.kvision.test.SimpleSpec +import kotlin.test.Test +import kotlin.test.assertTrue + +class AppSpec : SimpleSpec { + + @Test + fun render() { + run { + assertTrue(true, "Dummy test") + } + } +} diff --git a/modules/server/webpack.config.d/bootstrap.js b/modules/server/webpack.config.d/bootstrap.js new file mode 100644 index 0000000..c9ac06d --- /dev/null +++ b/modules/server/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, type: 'asset'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, type: 'asset'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, type: 'asset/resource'}); diff --git a/modules/server/webpack.config.d/css.js b/modules/server/webpack.config.d/css.js new file mode 100644 index 0000000..fd904af --- /dev/null +++ b/modules/server/webpack.config.d/css.js @@ -0,0 +1 @@ +config.module.rules.push({ test: /\.css$/, use: ["style-loader", { loader: "css-loader", options: {sourceMap: false} } ] }); diff --git a/modules/server/webpack.config.d/file.js b/modules/server/webpack.config.d/file.js new file mode 100644 index 0000000..aa64925 --- /dev/null +++ b/modules/server/webpack.config.d/file.js @@ -0,0 +1,6 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + type: 'asset/resource' + } +); diff --git a/modules/server/webpack.config.d/handlebars.js b/modules/server/webpack.config.d/handlebars.js new file mode 100644 index 0000000..3847b17 --- /dev/null +++ b/modules/server/webpack.config.d/handlebars.js @@ -0,0 +1,6 @@ +config.module.rules.push( + { + test: /\.hbs$/i, + loader: 'handlebars-loader' + } +); \ No newline at end of file diff --git a/modules/server/webpack.config.d/jquery.js b/modules/server/webpack.config.d/jquery.js new file mode 100644 index 0000000..e6c6b21 --- /dev/null +++ b/modules/server/webpack.config.d/jquery.js @@ -0,0 +1,9 @@ +;(function() { + const webpack = require('webpack') + + config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" + })); +})(); diff --git a/modules/server/webpack.config.d/moment.js b/modules/server/webpack.config.d/moment.js new file mode 100644 index 0000000..fb7c329 --- /dev/null +++ b/modules/server/webpack.config.d/moment.js @@ -0,0 +1,15 @@ +;(function() { + const webpack = require('webpack') + try { + const moment = require("moment"); + config.plugins.push(new webpack.IgnorePlugin({ + resourceRegExp: /^\.\/locale$/, + contextRegExp: /moment$/, + })); + config.plugins.push(new webpack.ProvidePlugin({ + moment: "moment", + "window.moment": "moment" + })); + } catch (e) { + } +})(); diff --git a/modules/server/webpack.config.d/webpack.js b/modules/server/webpack.config.d/webpack.js new file mode 100644 index 0000000..4ce4481 --- /dev/null +++ b/modules/server/webpack.config.d/webpack.js @@ -0,0 +1,15 @@ +config.resolve.modules.push("../../processedResources/js/main"); + +if (config.devServer) { + config.devServer.hot = true; + config.devtool = 'eval-cheap-source-map'; +} else { + config.devtool = undefined; +} + +// disable bundle size warning +config.performance = { + assetFilter: function (assetFilename) { + return !assetFilename.endsWith('.js'); + }, +}; From 8e94a20a792e9f4cedefbc7c32f502c0443ccc32 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 22 Oct 2021 18:17:48 +0200 Subject: [PATCH 026/629] rename data model, and experiment with K-mmp classes --- modules/data-model/build.gradle.kts | 8 --- .../build.gradle.kts | 46 ++++++++++++++ .../FactorioEvent.kt | 63 +++++++++++++++++++ .../JsonPrimitiveType.kt | 31 +++++++++ .../factorioevents/model/JsonPrimitiveType.kt | 27 ++++++++ .../src/main/kotlin/PlayerModel.kt | 0 6 files changed, 167 insertions(+), 8 deletions(-) delete mode 100644 modules/data-model/build.gradle.kts create mode 100644 modules/factorio-events-data-model/build.gradle.kts create mode 100644 modules/factorio-events-data-model/src/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt create mode 100644 modules/factorio-events-data-model/src/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt create mode 100644 modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/JsonPrimitiveType.kt rename modules/{data-model => factorio-events-data-model}/src/main/kotlin/PlayerModel.kt (100%) diff --git a/modules/data-model/build.gradle.kts b/modules/data-model/build.gradle.kts deleted file mode 100644 index 8a701aa..0000000 --- a/modules/data-model/build.gradle.kts +++ /dev/null @@ -1,8 +0,0 @@ -plugins { - id("dev.adamko.factoriowebmap.archetype.kotlin-js") -} - -val projectId: String by project.extra -val buildDir: Directory = layout.buildDirectory.dir(projectId).get() -val nodeModulesDir: Directory by project.extra - diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts new file mode 100644 index 0000000..26f24fc --- /dev/null +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -0,0 +1,46 @@ +plugins { + id("dev.adamko.factoriowebmap.archetype.base") + kotlin("multiplatform") +} + +val projectId: String by project.extra +val buildDir: Directory = layout.buildDirectory.dir(projectId).get() +val nodeModulesDir: Directory by project.extra + +kotlin { + + js(IR) { + binaries.executable() +// browser { +// commonWebpackConfig { +// cssSupport.enabled = true +// } +// } + + nodejs() + useCommonJs() + + compilations["main"].apply { + packageJson { + customField( + "scripts", + mapOf( + "build" to "tstl", + "dev" to "tstl --watch", + ) + ) + } + } + + } + + jvm { + compilations.all { + kotlinOptions.jvmTarget = "11" + } + testRuns["test"].executionTask.configure { + useJUnitPlatform() + } + } + +} diff --git a/modules/factorio-events-data-model/src/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt b/modules/factorio-events-data-model/src/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt new file mode 100644 index 0000000..058d02d --- /dev/null +++ b/modules/factorio-events-data-model/src/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt @@ -0,0 +1,63 @@ +package dev.adamko.factorioevents.model + +import kotlin.js.JsExport +import kotlin.jvm.JvmInline + +//expect sealed interface JsonPrimitive { +// value class JsonString(val string: String) : JsonPrimitive +// value class JsonNumber(val number: Number) : JsonPrimitive +// value class JsonBoolean(val boolean: Boolean) : JsonPrimitive +//} + +sealed interface JsonPrimitive { + @JvmInline + value class JsonString(val string: String) : JsonPrimitive + @JvmInline + value class JsonNumber(val number: Number) : JsonPrimitive + @JvmInline + value class JsonBoolean(val boolean: Boolean) : JsonPrimitive +} + +class JsonArray( + private val list: MutableList = mutableListOf() +) : MutableList by list + + +sealed interface JsonTableValue { + @JvmInline + value class JsonPrimitiveTV(val primitive: JsonPrimitive) : JsonTableValue + @JvmInline + value class JsonArrayTV(val array: JsonArray) : JsonTableValue + @JvmInline + value class JsonTableTV(val array: JsonTable) : JsonTableValue +} + +//expect class JsonNumber() : JsonPrimitiveType + +//expect class JsonArray + +//expect open class JsonTable + +open class JsonTable( + protected val map: MutableMap = mutableMapOf() +) : MutableMap by map { + + inline fun get2(key: String): T? { + + val jKey = JsonPrimitive.JsonString(key) + + return when { + T::class is Number -> ((get(jKey) as? JsonTableValue.JsonPrimitiveTV)?.primitive as? JsonPrimitive.JsonNumber)?.number as? T + else -> return get(jKey) as? T + } + + } + +} + +//@JsExport +class FactorioEvent : JsonTable() { + val tick: UInt? + get() = get2("tick") +// set(value) = map.put("tick", value) +} \ No newline at end of file diff --git a/modules/factorio-events-data-model/src/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt b/modules/factorio-events-data-model/src/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt new file mode 100644 index 0000000..06519b0 --- /dev/null +++ b/modules/factorio-events-data-model/src/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt @@ -0,0 +1,31 @@ +package dev.adamko.factorioevents.model + + +//actual sealed interface JsonPrimitive { +// actual value class JsonString(val string: String) : JsonPrimitive +// actual value class JsonNumber(val number: Number) : JsonPrimitive +// actual value class JsonBoolean(val boolean: Boolean) : JsonPrimitive +//} + +//actual class JsonArray( +// private val list: MutableList = mutableListOf() +//) : MutableList by list + +//actual sealed interface JsonTableValue { +// actual value class JsonPrimitiveTV(val primitive: JsonPrimitive) : JsonTableValue +// actual value class JsonArrayTV(val array: JsonArray) : JsonTableValue +//} + + +//actual open class JsonTable( +// private val map: MutableMap = mutableMapOf() +//) : MutableMap by map + + +fun printMap() { + val f = JsonPrimitive.JsonString("test") + + println(f.string) + println(f) + +} diff --git a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/JsonPrimitiveType.kt b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/JsonPrimitiveType.kt new file mode 100644 index 0000000..013584a --- /dev/null +++ b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/JsonPrimitiveType.kt @@ -0,0 +1,27 @@ +package dev.adamko.factorioevents.model + + +//actual sealed interface JsonPrimitive { +// @JvmInline +// actual value class JsonString(val string: String) : JsonPrimitive +// @JvmInline +// actual value class JsonNumber(val number: Number) : JsonPrimitive +// @JvmInline +// actual value class JsonBoolean(val boolean: Boolean) : JsonPrimitive +//} + +//actual class JsonArray( +// private val list: MutableList = mutableListOf() +//) : MutableList by list + +//actual sealed interface JsonTableValue { +// @JvmInline +// actual value class JsonPrimitiveTV(val primitive: JsonPrimitive) : JsonTableValue +// @JvmInline +// actual value class JsonArrayTV(val array: JsonArray) : JsonTableValue +//} + +//actual open class JsonTable( +// private val map: MutableMap = mutableMapOf() +//) : MutableMap by map + diff --git a/modules/data-model/src/main/kotlin/PlayerModel.kt b/modules/factorio-events-data-model/src/main/kotlin/PlayerModel.kt similarity index 100% rename from modules/data-model/src/main/kotlin/PlayerModel.kt rename to modules/factorio-events-data-model/src/main/kotlin/PlayerModel.kt From a1c0064b3dabc8f24ca1011eb7396604a74138d7 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 22 Oct 2021 18:19:53 +0200 Subject: [PATCH 027/629] start adding kafka processor... --- .../factorio-events-processor/build.gradle.kts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 modules/factorio-events-processor/build.gradle.kts diff --git a/modules/factorio-events-processor/build.gradle.kts b/modules/factorio-events-processor/build.gradle.kts new file mode 100644 index 0000000..924baaa --- /dev/null +++ b/modules/factorio-events-processor/build.gradle.kts @@ -0,0 +1,15 @@ +plugins { + id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") +} + +description = + """ + Receive raw Factorio Events from Kafka and process them into targeted topics or data formats. + + Factorio events -> Mod -> Kafka -> ***Factorio Events Processor*** -> processed events + """.trimIndent() + +val projectId: String by project.extra +val buildDir: Directory = layout.buildDirectory.dir(projectId).get() + + From 34c87ea5b8c32f40afdbec5c310858f61c118074 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 22 Oct 2021 18:20:23 +0200 Subject: [PATCH 028/629] include kafka processor & data model in gradle --- settings.gradle.kts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index b158369..c46dc6e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,7 +5,8 @@ include( // ":modules:mod2", ":modules:server", ":modules:kt-rcon", - ":modules:data-model", + ":modules:factorio-events-data-model", + ":modules:factorio-events-processor", ) From 1c9f415d016753ec6df5ff67d5eac1a7fc738dbd Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 22 Oct 2021 18:20:59 +0200 Subject: [PATCH 029/629] mod build improvements, add a separate model def --- modules/mod/src/main/typescript/events.ts | 10 ++------- .../mod/src/main/typescript/model/model.ts | 21 +++++++++++++++++++ .../mod/src/main/typescript/serdes/serdes.ts | 17 ++------------- 3 files changed, 25 insertions(+), 23 deletions(-) create mode 100644 modules/mod/src/main/typescript/model/model.ts diff --git a/modules/mod/src/main/typescript/events.ts b/modules/mod/src/main/typescript/events.ts index 50b08ad..98eb668 100644 --- a/modules/mod/src/main/typescript/events.ts +++ b/modules/mod/src/main/typescript/events.ts @@ -8,16 +8,10 @@ // thingType: Object.values(defines.events) // } -import {JsonTable, Serdes} from "./serdes/serdes" +import {Serdes} from "./serdes/serdes" +import {FactorioEvent, JsonTable} from "./model/model"; -interface FactorioEvent extends JsonTable { - tick: uint - object_name: string, - event_type: string, - data: JsonTable, -} - const FactorioEvent = ((tick: uint, objectName: string, eventType: string, data: JsonTable) => { return { tick: tick, diff --git a/modules/mod/src/main/typescript/model/model.ts b/modules/mod/src/main/typescript/model/model.ts new file mode 100644 index 0000000..b8e4152 --- /dev/null +++ b/modules/mod/src/main/typescript/model/model.ts @@ -0,0 +1,21 @@ +export type JsonPrimitiveType = number | string | boolean | undefined | null | void + +export type JsonArray = T[] + +export type JsonTableValueType = + JsonPrimitiveType + | JsonTable + | JsonArray + | undefined + | null + +export interface JsonTable { + [key: string]: JsonTableValueType +} + +export interface FactorioEvent extends JsonTable { + tick: uint + object_name: string, + event_type: string, + data: JsonTable, +} diff --git a/modules/mod/src/main/typescript/serdes/serdes.ts b/modules/mod/src/main/typescript/serdes/serdes.ts index d2fad48..5a9cfe3 100644 --- a/modules/mod/src/main/typescript/serdes/serdes.ts +++ b/modules/mod/src/main/typescript/serdes/serdes.ts @@ -1,18 +1,3 @@ -export type JsonPrimitiveType = number | string | boolean | undefined | null | void - -export type JsonArray = T[] - -export type JsonTableValueType = - JsonPrimitiveType - | JsonTable - | JsonArray - | undefined - | null - -export interface JsonTable { - [key: string]: JsonTableValueType -} - // export type JsonArray = TValue[] // export class JsonArray extends Array { // } @@ -29,6 +14,8 @@ export interface JsonTable { // declare const JsonTable: JsonTableConstructor +import {JsonTable, JsonArray} from "../model/model"; + export namespace Serdes { export namespace Player { From 26626263d3bea127f8df66f45650e3a8382e0f8f Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 23 Oct 2021 22:44:20 +0200 Subject: [PATCH 030/629] kafka pipe working!!!!!!!!!!!!!!!!! lots of experiments too - to be deleted --- .../archetype/kotlin-jvm.gradle.kts | 10 +- .../build.gradle.kts | 155 ++++++++++++++++++ .../docker-compose.yml | 54 ++++++ .../kafka-pipe-jar.Dockerfile | 12 ++ .../kafka-pipe.Dockerfile | 31 ++++ .../factorio-events-kafka-pipe/kafka-pipe.sh | 21 +++ .../pipe-logs-to-kafka.sh | 50 ++++++ .../src/main/kotlin/fekp.kt | 17 ++ .../build.gradle.kts | 1 - modules/mod/infra/docker-compose.yml | 22 ++- modules/mod/infra/kafka-server.properties | 135 +++++++++++++++ modules/mod/infra/kafka.Dockerfile | 4 +- settings.gradle.kts | 1 + 13 files changed, 506 insertions(+), 7 deletions(-) create mode 100644 modules/factorio-events-kafka-pipe/build.gradle.kts create mode 100644 modules/factorio-events-kafka-pipe/docker-compose.yml create mode 100644 modules/factorio-events-kafka-pipe/kafka-pipe-jar.Dockerfile create mode 100644 modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile create mode 100644 modules/factorio-events-kafka-pipe/kafka-pipe.sh create mode 100644 modules/factorio-events-kafka-pipe/pipe-logs-to-kafka.sh create mode 100644 modules/factorio-events-kafka-pipe/src/main/kotlin/fekp.kt create mode 100644 modules/mod/infra/kafka-server.properties diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts index 5f33e8a..ef894b0 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts @@ -8,6 +8,9 @@ plugins { } kotlin { + jvmToolchain { + (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(11)) // "8" + } } dependencies { @@ -16,8 +19,9 @@ dependencies { tasks.withType().configureEach { kotlinOptions.freeCompilerArgs += listOf( - "-Xopt-in=kotlin.OptIn", - "-Xopt-in=kotlin.ExperimentalStdlibApi", - "-Xopt-in=kotlin.time.ExperimentalTime", + "-Xopt-in=kotlin.OptIn", + "-Xopt-in=kotlin.ExperimentalStdlibApi", + "-Xopt-in=kotlin.time.ExperimentalTime", + "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", ) } \ No newline at end of file diff --git a/modules/factorio-events-kafka-pipe/build.gradle.kts b/modules/factorio-events-kafka-pipe/build.gradle.kts new file mode 100644 index 0000000..fc935c8 --- /dev/null +++ b/modules/factorio-events-kafka-pipe/build.gradle.kts @@ -0,0 +1,155 @@ +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + +plugins { + id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") + + application + +// id("com.github.johnrengelman.shadow") version "7.1.0" +} + +description = + """ + Send events from a Factorio server to a Kafka topic + """.trimIndent() + +val projectId: String by project.extra + +dependencies { + implementation(libs.bundles.logging) + implementation("eu.jrie.jetbrains:kotlin-shell-core:0.2.1") +} + +application { + mainClass.set("factorioEventsKafkaPipeKt") +} + +java { + withSourcesJar() +} + +tasks.jar { + manifest { + attributes( + "Implementation-Title" to project.name, + "Implementation-Version" to project.version, + "Main-Class" to application.mainClass, + ) + } + archiveBaseName.set(project.name) + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + + from( + configurations.runtimeClasspath.map { config -> + config.map { + logger.trace("Adding runtimeClasspath file to jar - $it") + when (it.isDirectory) { + true -> it + false -> zipTree(it) + } + } + } + ) + +} + +tasks.create("dockerBuildPdl2k") { + group = projectId + + dependsOn(tasks.jar) + + val jar = tasks.jar.get().archiveFile.get() + logger.lifecycle("building docker with jar $jar") + inputs.file(jar) + + commandLine( + parseSpaceSeparatedArgs( + "docker-compose build pdl2k --build-arg JAR_LOCATION=${jar.asFile.canonicalPath}" + ) + ) + +// inputs(tasks.jar.get().archiveFile.get()) + +// commandLine( +// "docker", +// "build", +// "--build-arg", +// "JAR_FILE=", +// "-t dev-adamko/pdl2k" +// ) +} + +//tasks.jar.get().archiveFile.get().asFile.canonicalPath + +tasks.create("runInDocker") { + group = projectId +// docker run -v `pwd`:/mnt java:8 java -jar /mnt/myapp.jar + + dependsOn(tasks.jar) + val jarFile = tasks.jar.get().archiveFile.get().asFile + inputs.file(jarFile) + + commandLine( + listOf( + "docker", + "run", + "--rm", + "--name", project.name, +// """--workdir="/app" """, + "-v", ".//${jarFile.toRelativeString(project.projectDir).replace("\\", "//")}:/mnt/", + "openjdk:11.0.6-jre-buster", + "ls", "-la", "/mnt/*", +// "java", "-jar", "/mnt/${jarFile.name}", + ) + ) + + doFirst { + logger.lifecycle("Executing [$commandLine]") + } +} + +//afterEvaluate { +// tasks { +// create("jar2", Jar::class).apply { +// dependsOn("jvmMainClasses", "jsJar") +// group = "jar" +// manifest { +// attributes( +// mapOf( +// "Implementation-Title" to rootProject.name, +// "Implementation-Version" to rootProject.version, +// "Timestamp" to System.currentTimeMillis(), +// "Main-Class" to application.mainClass +// ) +// ) +// } +// +// from( +// configurations +// ) +// +// val dependencies = +// configurations["jvmRuntimeClasspath"] +// .filter { it.name.endsWith(".jar") } + +// project.tasks["jvmJar"].outputs.files +// dependencies.forEach { from(zipTree(it)) } +// into("/lib") +// } +// } +//} +//val fatJar = task("fatJar", type = Jar::class) { +// baseName = "safescape-lib-${project.name}" +// // manifest Main-Class attribute is optional. +// // (Used only to provide default main class for executable jar) +// from(configurations.runtimeClasspath.map({ if (it.isDirectory) it else zipTree(it) })) +// with(tasks["jar"] as CopySpec) +//} +// +//tasks { +// "build" { +// dependsOn(fatJar) +// } +//} +//from(configurations.runtimeClasspath) { +// into("lib") +//} \ No newline at end of file diff --git a/modules/factorio-events-kafka-pipe/docker-compose.yml b/modules/factorio-events-kafka-pipe/docker-compose.yml new file mode 100644 index 0000000..4cc28cf --- /dev/null +++ b/modules/factorio-events-kafka-pipe/docker-compose.yml @@ -0,0 +1,54 @@ +version: "3.9" + +services: + kp2: + image: openjdk:11-jre-buster + container_name: "factorio-events-kafka-pipe" + build: + dockerfile: "kafka-pipe.Dockerfile" + networks: + - "factorio-events-nw" + environment: + FACTORIO_SERVER_CONTAINER_NAME: "factorio-server" + KAFKA_HOST: "kafka:29092" + volumes: + # Unix and Windows? + # - "//./pipe/docker_engine:/var/run/docker.sock" + # - "//./pipe/docker_engine:/pipe/docker_engine" + - "//var/run/docker.sock:/var/run/docker.sock" + # - "/var/run/docker.sock:/var/run/docker.sock" + # Windows? + # - "\\.\\pipe\\docker_engine:\\.\\pipe\\docker_engine" + # Windows? + # - "/usr/local/bin/docker:/usr/bin/docker" + + +# kp3: +# image: edenhill/kcat:1.7.0 +# container_name: kafka-pipe3 +# networks: +# - "factorio-events-nw" +# volumes: +# - "./kafka-pipe.sh:/kafka-pipe.sh" +# entrypoint: +# # - "ls" +# # - "-la" +# # - "&&" +# - "/bin/sh" +# - "./kafka-pipe.sh" +# - "factorio-server" +# - "kafka-kraft" + +### + +# volumes: +# - "./build/libs/:/app" +# command: +# - "java" +# - "-jar" +# - "/app/pipe-docker-logs-to-kafka-0.0.2.jar" + +networks: + factorio-events-nw: + name: "factorio-events-nw" + external: true diff --git a/modules/factorio-events-kafka-pipe/kafka-pipe-jar.Dockerfile b/modules/factorio-events-kafka-pipe/kafka-pipe-jar.Dockerfile new file mode 100644 index 0000000..16ded19 --- /dev/null +++ b/modules/factorio-events-kafka-pipe/kafka-pipe-jar.Dockerfile @@ -0,0 +1,12 @@ +ARG JAR_LOCATION + +FROM openjdk:11.0.6-jre-buster +ARG JAR_LOCATION + +RUN apt-get update && apt-get install -y \ + curl \ + && rm -rf /var/lib/apt/lists/* + +COPY JAR_LOCATION /app.jar + +ENTRYPOINT ["java","-jar","/app.jar"] diff --git a/modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile b/modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile new file mode 100644 index 0000000..9fc1c79 --- /dev/null +++ b/modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile @@ -0,0 +1,31 @@ + +#FROM debian:buster-slim +FROM docker:dind-rootless + +ENV FACTORIO_SERVER_CONTAINER_NAME="factorio-server" +ENV KAFKA_HOST="kafka-kraft" + +#RUN apt-get update && apt-get install -y --no-install-recommends \ +# curl \ +# docker \ +# kafkacat + +# root is required for following Docker logs +USER root + +RUN apk add --update \ + curl \ + kafkacat +#USER rootless + +# \ +# && rm -rf /var/lib/apt/lists/* + +COPY kafka-pipe.sh kafka-pipe.sh + +#RUN useradd --user-group --system --create-home --no-log-init the_engineer +#USER the_engineer + +ENTRYPOINT [ "/bin/sh", "/kafka-pipe.sh" ] +#ENTRYPOINT /bin/bash +#CMD exec /kafka-pipe.sh diff --git a/modules/factorio-events-kafka-pipe/kafka-pipe.sh b/modules/factorio-events-kafka-pipe/kafka-pipe.sh new file mode 100644 index 0000000..0c8fa68 --- /dev/null +++ b/modules/factorio-events-kafka-pipe/kafka-pipe.sh @@ -0,0 +1,21 @@ +#!/usr/bin/bash + +# Pipe Docker logs from a Factorio server to a Kafka topic + +echo "Piping logs from $FACTORIO_SERVER_CONTAINER_NAME to $KAFKA_HOST" + +trap endProcess SIGINT +endProcess() { + echo "Exiting Factorio Events Kafka Pipe" + exit +} + +while :; do + docker logs --tail 0 -f "$FACTORIO_SERVER_CONTAINER_NAME" | + sed -n -e 's/^FactorioEvent: //p' | + kafkacat -P -b "$KAFKA_HOST" -t factorio-server-log + + echo "Error - retrying in 10 seconds" + + sleep 10 +done diff --git a/modules/factorio-events-kafka-pipe/pipe-logs-to-kafka.sh b/modules/factorio-events-kafka-pipe/pipe-logs-to-kafka.sh new file mode 100644 index 0000000..d89e815 --- /dev/null +++ b/modules/factorio-events-kafka-pipe/pipe-logs-to-kafka.sh @@ -0,0 +1,50 @@ +#!/usr/bin/zsh + +# stream logs from 'factorio' container +# follow the logs, and +# combine stdout and stderr +# only match lines that start with 'FactorioEvent: ', +# and only return the stuff *after* 'FactorioEvent: ' +docker logs --tail 0 -f factorio-server 2>&1 | + sed -n -e 's/^FactorioEvent: //p' | + kafkacat -P -b localhost -t factorio-server-log + +# listen to events +# kafkacat -C -b localhost -t factorio-server-log | jq + +# curl -sS --unix-socket /var/run/docker.sock "http://localhost/v1.41/events?filters={"service":"factorio-server"}" --output - | jq + +curl --no-buffer -sS \ + --unix-socket /var/run/docker.sock \ + "http://localhost/v1.41/containers/factorio-server/logs?stdout=true&follow=true&tail=0" | + tail -c+9 +# --output - + +curl \ + -sS \ + --unix-socket /var/run/docker.sock \ + -X POST \ + --insecure "http://localhost/v1.41/containers/factorio-server/attach?logs=true&stream=true&stdout=true&follow=true" | + tail -c+9 + +# sed 's/^........//' + + +# https://stackoverflow.com/questions/42873285/curl-retry-mechanism +# --retry-all-errors + +# --header "Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==" \ +# --header "Sec-WebSocket-Version: 13" \ +# --header "Host: localhost:80" \ +# --header "Origin: http://localhost:80" \ + +curl --include \ + --unix-socket /var/run/docker.sock \ + --no-buffer \ + --header "Connection: Upgrade" \ + --header "Upgrade: websocket" \ + --header "Host: localhost:80" \ + --header "Origin: http://localhost:80" \ + --header "Sec-WebSocket-Version: 13" \ + --header "Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==" \ + "http://localhost/v1.41/containers/factorio-server/attach/ws?logs=true&stdout=true" diff --git a/modules/factorio-events-kafka-pipe/src/main/kotlin/fekp.kt b/modules/factorio-events-kafka-pipe/src/main/kotlin/fekp.kt new file mode 100644 index 0000000..be87043 --- /dev/null +++ b/modules/factorio-events-kafka-pipe/src/main/kotlin/fekp.kt @@ -0,0 +1,17 @@ +import eu.jrie.jetbrains.kotlinshell.shell.shell + +fun main() { + shell { + + "echo hello world"() + +// """ +// curl \ +// --no-buffer \ +// -sS \ +// --unix-socket /var/run/docker.sock \ +// "http://localhost/v1.41/containers/factorio-server/logs?stdout=true&follow=true&tail=0" +// """.trimIndent() + + } +} \ No newline at end of file diff --git a/modules/factorio-events-processor/build.gradle.kts b/modules/factorio-events-processor/build.gradle.kts index 924baaa..e5eff9b 100644 --- a/modules/factorio-events-processor/build.gradle.kts +++ b/modules/factorio-events-processor/build.gradle.kts @@ -12,4 +12,3 @@ description = val projectId: String by project.extra val buildDir: Directory = layout.buildDirectory.dir(projectId).get() - diff --git a/modules/mod/infra/docker-compose.yml b/modules/mod/infra/docker-compose.yml index 7ea4ccc..466e4cf 100644 --- a/modules/mod/infra/docker-compose.yml +++ b/modules/mod/infra/docker-compose.yml @@ -8,6 +8,8 @@ services: # driver: "json-file" container_name: "factorio-server" restart: "unless-stopped" + networks: + - "factorio-events-nw" ports: - "34197:34197/udp" # factorio - "27015:27015/tcp" # rcon @@ -29,18 +31,28 @@ services: # - USERNAME=FactorioUsername # - TOKEN=FactorioToken - kafka-kraft: + kafka: image: dev-adamko/kafka-kraft - container_name: "kafka-kraft" + container_name: "kafka" + restart: "unless-stopped" build: dockerfile: "kafka.Dockerfile" target: "kafka-kraft" args: KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/3.0.0/kafka_2.13-3.0.0.tgz" + networks: + - "factorio-events-nw" ports: - "9092:9092" - "9093:9093" +# environment: +# KAFKA_LISTENERS: "PLAINTEXT://kafka-kraft:29092,PLAINTEXT_HOST://localhost:9092,CONTROLLER_HOST://localhost:9093" # ,CONTROLLER://kafka-kraft:29093 +# KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT,CONTROLLER:PLAINTEXT" #,CONTROLLER_HOST:PLAINTEXT +# KAFKA_INTER_BROKER_LISTENER_NAME: "PLAINTEXT" +# KAFKA_ADVERTISED_LISTENERS: "PLAINTEXT://kafka-kraft:29092,PLAINTEXT_HOST://localhost:9092" +# KAKFA_CONTROLLER_LISTENER_NAMES: "CONTROLLER" #,CONTROLLER_HOST + # kafka-connect: # image: dev-adamko/kafka-connect # container_name: "kafka-connect" @@ -54,3 +66,9 @@ services: # ports: # - "8083:8083" # + + +networks: + factorio-events-nw: + name: "factorio-events-nw" + diff --git a/modules/mod/infra/kafka-server.properties b/modules/mod/infra/kafka-server.properties new file mode 100644 index 0000000..70ebc99 --- /dev/null +++ b/modules/mod/infra/kafka-server.properties @@ -0,0 +1,135 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# This configuration file is intended for use in KRaft mode, where +# Apache ZooKeeper is not present. See config/kraft/README.md for details. +# + +############################# Server Basics ############################# + +# The role of this server. Setting this puts us in KRaft mode +process.roles=broker,controller + +# The node id associated with this instance's roles +node.id=1 + +# The connect string for the controller quorum +controller.quorum.voters=1@localhost:9093 + +############################# Socket Server Settings ############################# + +# The address the socket server listens on. It will get the value returned from +# java.net.InetAddress.getCanonicalHostName() if not configured. +# FORMAT: +# listeners = listener_name://host_name:port +# EXAMPLE: +# listeners = PLAINTEXT://your.host.name:9092 +#listeners=PLAINTEXT://:9092,CONTROLLER://:9093 +#listeners=PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092,CONTROLLER://localhost:9093 +listeners=PLAINTEXT://:29092,PLAINTEXT_HOST://:9092,CONTROLLER://:9093 + +inter.broker.listener.name=PLAINTEXT +#KAFKA_INTER_BROKER_LISTENER_NAME: "PLAINTEXT" + +# Hostname and port the broker will advertise to producers and consumers. If not set, +# it uses the value for "listeners" if configured. Otherwise, it will use the value +# returned from java.net.InetAddress.getCanonicalHostName(). +#advertised.listeners=PLAINTEXT://localhost:9092 +advertised.listeners=PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092 + +# Listener, host name, and port for the controller to advertise to the brokers. If +# this server is a controller, this listener must be configured. +controller.listener.names=CONTROLLER + +# Maps listener names to security protocols, the default is for them to be the same. See the config documentation for more details +#listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,SSL:SSL,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSL +listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT +# ,SSL:SSL,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSL + +# The number of threads that the server uses for receiving requests from the network and sending responses to the network +num.network.threads=3 + +# The number of threads that the server uses for processing requests, which may include disk I/O +num.io.threads=8 + +# The send buffer (SO_SNDBUF) used by the socket server +socket.send.buffer.bytes=102400 + +# The receive buffer (SO_RCVBUF) used by the socket server +socket.receive.buffer.bytes=102400 + +# The maximum size of a request that the socket server will accept (protection against OOM) +socket.request.max.bytes=104857600 + + +############################# Log Basics ############################# + +# A comma separated list of directories under which to store log files +log.dirs=/tmp/kraft-combined-logs + +# The default number of log partitions per topic. More partitions allow greater +# parallelism for consumption, but this will also result in more files across +# the brokers. +num.partitions=1 + +# The number of threads per data directory to be used for log recovery at startup and flushing at shutdown. +# This value is recommended to be increased for installations with data dirs located in RAID array. +num.recovery.threads.per.data.dir=1 + +############################# Internal Topic Settings ############################# +# The replication factor for the group metadata internal topics "__consumer_offsets" and "__transaction_state" +# For anything other than development testing, a value greater than 1 is recommended to ensure availability such as 3. +offsets.topic.replication.factor=1 +transaction.state.log.replication.factor=1 +transaction.state.log.min.isr=1 + +############################# Log Flush Policy ############################# + +# Messages are immediately written to the filesystem but by default we only fsync() to sync +# the OS cache lazily. The following configurations control the flush of data to disk. +# There are a few important trade-offs here: +# 1. Durability: Unflushed data may be lost if you are not using replication. +# 2. Latency: Very large flush intervals may lead to latency spikes when the flush does occur as there will be a lot of data to flush. +# 3. Throughput: The flush is generally the most expensive operation, and a small flush interval may lead to excessive seeks. +# The settings below allow one to configure the flush policy to flush data after a period of time or +# every N messages (or both). This can be done globally and overridden on a per-topic basis. + +# The number of messages to accept before forcing a flush of data to disk +#log.flush.interval.messages=10000 + +# The maximum amount of time a message can sit in a log before we force a flush +#log.flush.interval.ms=1000 + +############################# Log Retention Policy ############################# + +# The following configurations control the disposal of log segments. The policy can +# be set to delete segments after a period of time, or after a given size has accumulated. +# A segment will be deleted whenever *either* of these criteria are met. Deletion always happens +# from the end of the log. + +# The minimum age of a log file to be eligible for deletion due to age +log.retention.hours=168 + +# A size-based retention policy for logs. Segments are pruned from the log unless the remaining +# segments drop below log.retention.bytes. Functions independently of log.retention.hours. +#log.retention.bytes=1073741824 + +# The maximum size of a log segment file. When this size is reached a new log segment will be created. +log.segment.bytes=1073741824 + +# The interval at which log segments are checked to see if they can be deleted according +# to the retention policies +log.retention.check.interval.ms=300000 diff --git a/modules/mod/infra/kafka.Dockerfile b/modules/mod/infra/kafka.Dockerfile index 48e4127..dca9f09 100644 --- a/modules/mod/infra/kafka.Dockerfile +++ b/modules/mod/infra/kafka.Dockerfile @@ -41,8 +41,10 @@ RUN ./bin/kafka-storage.sh format \ --config ./config/kraft/server.properties \ --cluster-id "$(cat cluster_id)" +COPY ./kafka-server.properties ./server.properties + # launch the broker in KRaft mode, which means that it runs without ZooKeeper -ENTRYPOINT ["./bin/kafka-server-start.sh", "./config/kraft/server.properties"] +ENTRYPOINT ["./bin/kafka-server-start.sh", "./server.properties"] ### Kafka Connect ## diff --git a/settings.gradle.kts b/settings.gradle.kts index c46dc6e..c15467c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,6 +7,7 @@ include( ":modules:kt-rcon", ":modules:factorio-events-data-model", ":modules:factorio-events-processor", + ":modules:factorio-events-kafka-pipe", ) From 70429d66be8cba9e022af566f46a9b59ba79890d Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 23 Oct 2021 22:46:17 +0200 Subject: [PATCH 031/629] rm old files, use sync to copy tstl'd files --- modules/mod/build.gradle.kts | 60 +++++++++++++++++++------------ modules/mod/data.ts | 1 - modules/mod/item.ts | 12 ------- modules/mod/pipe-logs-to-kafka.sh | 13 ------- 4 files changed, 38 insertions(+), 48 deletions(-) delete mode 100644 modules/mod/data.ts delete mode 100644 modules/mod/item.ts delete mode 100644 modules/mod/pipe-logs-to-kafka.sh diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index 46bf8fc..7a1002d 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -7,8 +7,8 @@ plugins { val projectId: String by project.extra -val tsSrcDir = layout.projectDirectory.dir("src/main/typescript") -val modBuildDir = layout.buildDirectory.dir(projectId).get() +val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") +val modBuildDir: Directory = layout.buildDirectory.dir(projectId).get() node { nodeProjectDir.set(tsSrcDir) @@ -25,19 +25,27 @@ val tstlTask = tasks.register("typescriptToLua") { npmCommand.set(listOf("run", "build")) inputs.dir(node.nodeProjectDir) - .skipWhenEmpty() - .withPropertyName("sourceFiles") - .withPathSensitivity(PathSensitivity.RELATIVE) + .skipWhenEmpty() + .withPropertyName("sourceFiles") + .withPathSensitivity(PathSensitivity.RELATIVE) + val intermediateOutputDir = temporaryDir + args.set(parseSpaceSeparatedArgs("-- --outDir $intermediateOutputDir")) val outputDir = modBuildDir.dir("typescriptToLua") - args.set(parseSpaceSeparatedArgs("-- --outDir $outputDir")) outputs.dir(outputDir) - .withPropertyName("outputDir") + .withPropertyName("outputDir") ignoreExitValue.set(false) doFirst("clean") { - delete(outputDir) + delete(intermediateOutputDir) + } + + doLast("syncTstlOutput") { + sync { + from(intermediateOutputDir) + into(outputDir) + } } } @@ -57,16 +65,16 @@ val tstlTask = tasks.register("typescriptToLua") { // } // } -val modPackageTask = tasks.register("package") { +val modPackageTask = tasks.register("packageMod") { description = "Package mod files into ZIP" group = projectId dependsOn(tstlTask) from( - layout.projectDirectory.dir("src/main/resources/mod-data"), - rootProject.layout.projectDirectory.file("LICENSE"), - tstlTask, + layout.projectDirectory.dir("src/main/resources/mod-data"), + rootProject.layout.projectDirectory.file("LICENSE"), + tstlTask, ) into(rootProject.name) @@ -80,8 +88,8 @@ val modPackageTask = tasks.register("package") { //tasks.build { dependsOn(tstlTask, modPackageTask) } -val modInfraDir = layout.projectDirectory.dir("infra") -val factorioServerDataDir = modInfraDir.dir("factorio-server") +val modInfraDir: Directory = layout.projectDirectory.dir("infra") +val factorioServerDataDir: Directory = modInfraDir.dir("factorio-server") val copyModToServerTask = tasks.register("copyModToServer") { description = "Copy the mod to the Factorio Docker server" @@ -97,7 +105,7 @@ val copyModToServerTask = tasks.register("copyModToServer") { } } -val serverStopTask = tasks.register("dockerStop") { +val factorioServerStop = tasks.register("factorioServerStop") { group = "$projectId.factorioServer" mustRunAfter(copyModToServerTask) @@ -106,16 +114,22 @@ val serverStopTask = tasks.register("dockerStop") { commandLine = parseSpaceSeparatedArgs("docker-compose stop factorio-server") } -val serverUpTask = tasks.register("dockerUp") { +val factorioServerUp = tasks.register("factorioServerUp") { group = "$projectId.factorioServer" mustRunAfter(copyModToServerTask) - dependsOn(serverStopTask) + dependsOn(factorioServerStop) workingDir(modInfraDir) commandLine = parseSpaceSeparatedArgs("docker-compose up -d factorio-server") } +val factorioServerRestart: Task by tasks.creating { + group = "$projectId.factorioServer" + + dependsOn(factorioServerStop, factorioServerUp) +} + //val serverRestartTask = tasks.register("dockerRestart") { // group = "$projectId.factorioServer" // @@ -156,9 +170,9 @@ val launch = tasks.register("modLauncher") { description = "Build the mod, upload to Server and Client, and start both" group = projectId dependsOn( - copyModToServerTask, - copyModToClientTask, - serverUpTask, + copyModToServerTask, + copyModToClientTask, + factorioServerRestart, // factorioClientLaunch, ) } @@ -175,11 +189,13 @@ tasks.register("downloadFactorioApiDocs") { doLast { - ant.invokeMethod("get", mapOf( + ant.invokeMethod( + "get", mapOf( "src" to target, "dest" to downloadedFile, "verbose" to true, - )) + ) + ) val json = downloadedFile.readText() val prettyJson = groovy.json.JsonOutput.prettyPrint(json) diff --git a/modules/mod/data.ts b/modules/mod/data.ts deleted file mode 100644 index eef4c4c..0000000 --- a/modules/mod/data.ts +++ /dev/null @@ -1 +0,0 @@ -// require("item") \ No newline at end of file diff --git a/modules/mod/item.ts b/modules/mod/item.ts deleted file mode 100644 index d39f9dd..0000000 --- a/modules/mod/item.ts +++ /dev/null @@ -1,12 +0,0 @@ -import * as util from "util"; -import { Data, Mods } from "typed-factorio/data/types" - - -declare const data: Data -declare const mods: Mods - -let fireArmour = util.table.deepcopy(data.raw["armor"]["heavy-armor"]) - -fireArmour.name = "fire-armour" -fireArmour.icon - diff --git a/modules/mod/pipe-logs-to-kafka.sh b/modules/mod/pipe-logs-to-kafka.sh deleted file mode 100644 index 96fbe5a..0000000 --- a/modules/mod/pipe-logs-to-kafka.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -# stream logs from 'factorio' container -# follow the logs, and -# combine stdout and stderr -# only match lines that start with 'FactorioEvent: ', -# and only return the stuff *after* 'FactorioEvent: ' -docker logs --tail 0 -f factorio 2>&1 | - sed -n -e 's/^FactorioEvent: //p' | - kafkacat -P -b localhost -t factorio-server-log - -# listen to events -# kafkacat -C -b localhost -t factorio-server-log | jq From 6245d614aab39701674c31a796d23e4fe4ef4109 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 23 Oct 2021 22:47:19 +0200 Subject: [PATCH 032/629] add mod version to messages, util method to get event name from event obj --- modules/mod/src/main/typescript/events.ts | 17 +++++--------- .../mod/src/main/typescript/model/model.ts | 22 +++++++++++++++++-- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/modules/mod/src/main/typescript/events.ts b/modules/mod/src/main/typescript/events.ts index 98eb668..223112c 100644 --- a/modules/mod/src/main/typescript/events.ts +++ b/modules/mod/src/main/typescript/events.ts @@ -11,16 +11,10 @@ import {Serdes} from "./serdes/serdes" import {FactorioEvent, JsonTable} from "./model/model"; - -const FactorioEvent = ((tick: uint, objectName: string, eventType: string, data: JsonTable) => { - return { - tick: tick, - object_name: objectName, - event_type: eventType, - data: data, - } as FactorioEvent - } -) +const mapEventIdToName = new LuaTable() +for (const [k, v] of pairs(defines.events)) { + mapEventIdToName.set(v, k) +} // function createFactorioEvent(tick: uint, object_name: string, eventType: string, data: // JsonTable): FactorioEvent { return { tick, object_name, eventType, data, } } @@ -105,7 +99,8 @@ script.on_event( for (const [index,] of pairs(game.surfaces)) { let surface = game.surfaces[index] - surfaceEvent(e.tick, surface, "on_tick") + surfaceEvent(e.tick, surface, mapEventIdToName.get(e.name)) + // surfaceEvent(e.tick, surface, "on_tick") } // let filename: string = table.concat([entity.unit_number, eventType, tick], "_") diff --git a/modules/mod/src/main/typescript/model/model.ts b/modules/mod/src/main/typescript/model/model.ts index b8e4152..dcd2615 100644 --- a/modules/mod/src/main/typescript/model/model.ts +++ b/modules/mod/src/main/typescript/model/model.ts @@ -13,9 +13,27 @@ export interface JsonTable { [key: string]: JsonTableValueType } +const MOD_VERSION = script.active_mods["factorio_web_map"] + export interface FactorioEvent extends JsonTable { - tick: uint - object_name: string, + /** Schema versioning */ + mod_version: string, + /** game time */ + tick: uint, + /** the initial Factorio event ({defines.events}) trigger */ event_type: string, + /** Defines the structure of {FactorioEvent.data} */ + object_name: string, data: JsonTable, } + +export const FactorioEvent = ((tick: uint, objectName: string, eventType: string, data: JsonTable) => { + return { + mod_version: MOD_VERSION, + tick: tick, + object_name: objectName, + event_type: eventType, + data: data, + } as FactorioEvent + } +) From 361ed8eef73003ef8dec14d58cd30040c6acd070 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 23 Oct 2021 22:59:36 +0200 Subject: [PATCH 033/629] make gradle project id shorter --- .../kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts index 555967c..35f58dc 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts @@ -7,7 +7,7 @@ plugins { group = "${rootProject.group}.${project.name}" version = rootProject.version -val projectId by extra("${rootProject.name}-${project.name}") +val projectId by extra("fwm-${project.name}") //val modBuildDir by extra(layout.buildDirectory.dir(projectId).get()) //group = "dev.adamko.factoriowebmap" From e52634529948243370c9e3ffbd4996313dfdde2b Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 23 Oct 2021 23:08:26 +0200 Subject: [PATCH 034/629] tidy up and some docs --- .../docker-compose.yml | 37 ++------------- modules/factorio-events-kafka-pipe/readme.md | 47 +++++++++++++++++++ 2 files changed, 50 insertions(+), 34 deletions(-) create mode 100644 modules/factorio-events-kafka-pipe/readme.md diff --git a/modules/factorio-events-kafka-pipe/docker-compose.yml b/modules/factorio-events-kafka-pipe/docker-compose.yml index 4cc28cf..b97d5e8 100644 --- a/modules/factorio-events-kafka-pipe/docker-compose.yml +++ b/modules/factorio-events-kafka-pipe/docker-compose.yml @@ -12,41 +12,10 @@ services: FACTORIO_SERVER_CONTAINER_NAME: "factorio-server" KAFKA_HOST: "kafka:29092" volumes: - # Unix and Windows? - # - "//./pipe/docker_engine:/var/run/docker.sock" - # - "//./pipe/docker_engine:/pipe/docker_engine" + # Windows (requires privileged/root) - "//var/run/docker.sock:/var/run/docker.sock" - # - "/var/run/docker.sock:/var/run/docker.sock" - # Windows? - # - "\\.\\pipe\\docker_engine:\\.\\pipe\\docker_engine" - # Windows? - # - "/usr/local/bin/docker:/usr/bin/docker" - - -# kp3: -# image: edenhill/kcat:1.7.0 -# container_name: kafka-pipe3 -# networks: -# - "factorio-events-nw" -# volumes: -# - "./kafka-pipe.sh:/kafka-pipe.sh" -# entrypoint: -# # - "ls" -# # - "-la" -# # - "&&" -# - "/bin/sh" -# - "./kafka-pipe.sh" -# - "factorio-server" -# - "kafka-kraft" - -### - -# volumes: -# - "./build/libs/:/app" -# command: -# - "java" -# - "-jar" -# - "/app/pipe-docker-logs-to-kafka-0.0.2.jar" + # Unix? + # - "/var/run/docker.sock:/var/run/docker.sock" networks: factorio-events-nw: diff --git a/modules/factorio-events-kafka-pipe/readme.md b/modules/factorio-events-kafka-pipe/readme.md new file mode 100644 index 0000000..5d9977d --- /dev/null +++ b/modules/factorio-events-kafka-pipe/readme.md @@ -0,0 +1,47 @@ + +### Setup notes + +Kafka must be connectable from both `localhost` (for cli) and `kafa` (the docker container name). + + +### Useful commands + +#### Powershell + +```shell +# might help with mounting the unix socket on Windows? +$Env:COMPOSE_CONVERT_WINDOWS_PATHS=1 + +# full rebuild +docker-compose down; docker-compose build; docker-compose up -d; docker-compose logs -f + +``` + +#### zsh + +```shell +# listen to events from factorio-server +docker logs --tail 0 -f factorio-server | sed -n -e 's/^FactorioEvent: //p' + +# tail logs with docker api (except it doesn't work) +curl -vvv \ + --unix-socket /var/run/docker.sock \ + --no-buffer \ + --header "Connection: Upgrade" \ + --header "Upgrade: websocket" \ + --header "Host: localhost:80" \ + --header "Origin: http://localhost:80" \ + --header "Sec-WebSocket-Version: 13" \ + --header "Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==" \ + "http://localhost:80/v1.41/containers/factorio-server/attach/ws?stream=true&logs=true&stdout=true" + +# tail logs +curl --no-buffer -sS --unix-socket /var/run/docker.sock \ + --get --data-urlencode 'filters={"container":["my-service"]}' \ + "http://localhost/v1.41/events" | jq --unbuffered + +# get logs from Kafka +kafkacat -u -C -b localhost -t factorio-server-log | jq --unbuffered + +``` + From 4c14cc2353c6748453a618617d398e46be3302e7 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 23 Oct 2021 23:10:38 +0200 Subject: [PATCH 035/629] tee produced records --- modules/factorio-events-kafka-pipe/kafka-pipe.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/factorio-events-kafka-pipe/kafka-pipe.sh b/modules/factorio-events-kafka-pipe/kafka-pipe.sh index 0c8fa68..e0f5b7b 100644 --- a/modules/factorio-events-kafka-pipe/kafka-pipe.sh +++ b/modules/factorio-events-kafka-pipe/kafka-pipe.sh @@ -13,7 +13,7 @@ endProcess() { while :; do docker logs --tail 0 -f "$FACTORIO_SERVER_CONTAINER_NAME" | sed -n -e 's/^FactorioEvent: //p' | - kafkacat -P -b "$KAFKA_HOST" -t factorio-server-log + kafkacat -P -T -b "$KAFKA_HOST" -t factorio-server-log echo "Error - retrying in 10 seconds" From 995ea750be076b6688048224ce7e78c3a3176e47 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 23 Oct 2021 23:21:31 +0200 Subject: [PATCH 036/629] rm old kafka-pipe experiments --- modules/factorio-events-kafka-pipe/.env | 1 + .../build.gradle.kts | 145 +----------------- .../docker-compose.yml | 1 + .../kafka-pipe-jar.Dockerfile | 12 -- .../kafka-pipe.Dockerfile | 22 +-- .../pipe-logs-to-kafka.sh | 50 ------ modules/factorio-events-kafka-pipe/readme.md | 13 +- .../src/main/kotlin/fekp.kt | 17 -- 8 files changed, 15 insertions(+), 246 deletions(-) create mode 100644 modules/factorio-events-kafka-pipe/.env delete mode 100644 modules/factorio-events-kafka-pipe/kafka-pipe-jar.Dockerfile delete mode 100644 modules/factorio-events-kafka-pipe/pipe-logs-to-kafka.sh delete mode 100644 modules/factorio-events-kafka-pipe/src/main/kotlin/fekp.kt diff --git a/modules/factorio-events-kafka-pipe/.env b/modules/factorio-events-kafka-pipe/.env new file mode 100644 index 0000000..d3d9e29 --- /dev/null +++ b/modules/factorio-events-kafka-pipe/.env @@ -0,0 +1 @@ +COMPOSE_PROJECT_NAME=factorio-events-kafka-pipe diff --git a/modules/factorio-events-kafka-pipe/build.gradle.kts b/modules/factorio-events-kafka-pipe/build.gradle.kts index fc935c8..e36b82f 100644 --- a/modules/factorio-events-kafka-pipe/build.gradle.kts +++ b/modules/factorio-events-kafka-pipe/build.gradle.kts @@ -1,11 +1,7 @@ import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { - id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") - - application - -// id("com.github.johnrengelman.shadow") version "7.1.0" + id("dev.adamko.factoriowebmap.archetype.base") } description = @@ -14,142 +10,3 @@ description = """.trimIndent() val projectId: String by project.extra - -dependencies { - implementation(libs.bundles.logging) - implementation("eu.jrie.jetbrains:kotlin-shell-core:0.2.1") -} - -application { - mainClass.set("factorioEventsKafkaPipeKt") -} - -java { - withSourcesJar() -} - -tasks.jar { - manifest { - attributes( - "Implementation-Title" to project.name, - "Implementation-Version" to project.version, - "Main-Class" to application.mainClass, - ) - } - archiveBaseName.set(project.name) - duplicatesStrategy = DuplicatesStrategy.EXCLUDE - - from( - configurations.runtimeClasspath.map { config -> - config.map { - logger.trace("Adding runtimeClasspath file to jar - $it") - when (it.isDirectory) { - true -> it - false -> zipTree(it) - } - } - } - ) - -} - -tasks.create("dockerBuildPdl2k") { - group = projectId - - dependsOn(tasks.jar) - - val jar = tasks.jar.get().archiveFile.get() - logger.lifecycle("building docker with jar $jar") - inputs.file(jar) - - commandLine( - parseSpaceSeparatedArgs( - "docker-compose build pdl2k --build-arg JAR_LOCATION=${jar.asFile.canonicalPath}" - ) - ) - -// inputs(tasks.jar.get().archiveFile.get()) - -// commandLine( -// "docker", -// "build", -// "--build-arg", -// "JAR_FILE=", -// "-t dev-adamko/pdl2k" -// ) -} - -//tasks.jar.get().archiveFile.get().asFile.canonicalPath - -tasks.create("runInDocker") { - group = projectId -// docker run -v `pwd`:/mnt java:8 java -jar /mnt/myapp.jar - - dependsOn(tasks.jar) - val jarFile = tasks.jar.get().archiveFile.get().asFile - inputs.file(jarFile) - - commandLine( - listOf( - "docker", - "run", - "--rm", - "--name", project.name, -// """--workdir="/app" """, - "-v", ".//${jarFile.toRelativeString(project.projectDir).replace("\\", "//")}:/mnt/", - "openjdk:11.0.6-jre-buster", - "ls", "-la", "/mnt/*", -// "java", "-jar", "/mnt/${jarFile.name}", - ) - ) - - doFirst { - logger.lifecycle("Executing [$commandLine]") - } -} - -//afterEvaluate { -// tasks { -// create("jar2", Jar::class).apply { -// dependsOn("jvmMainClasses", "jsJar") -// group = "jar" -// manifest { -// attributes( -// mapOf( -// "Implementation-Title" to rootProject.name, -// "Implementation-Version" to rootProject.version, -// "Timestamp" to System.currentTimeMillis(), -// "Main-Class" to application.mainClass -// ) -// ) -// } -// -// from( -// configurations -// ) -// -// val dependencies = -// configurations["jvmRuntimeClasspath"] -// .filter { it.name.endsWith(".jar") } + -// project.tasks["jvmJar"].outputs.files -// dependencies.forEach { from(zipTree(it)) } -// into("/lib") -// } -// } -//} -//val fatJar = task("fatJar", type = Jar::class) { -// baseName = "safescape-lib-${project.name}" -// // manifest Main-Class attribute is optional. -// // (Used only to provide default main class for executable jar) -// from(configurations.runtimeClasspath.map({ if (it.isDirectory) it else zipTree(it) })) -// with(tasks["jar"] as CopySpec) -//} -// -//tasks { -// "build" { -// dependsOn(fatJar) -// } -//} -//from(configurations.runtimeClasspath) { -// into("lib") -//} \ No newline at end of file diff --git a/modules/factorio-events-kafka-pipe/docker-compose.yml b/modules/factorio-events-kafka-pipe/docker-compose.yml index b97d5e8..4d42dbd 100644 --- a/modules/factorio-events-kafka-pipe/docker-compose.yml +++ b/modules/factorio-events-kafka-pipe/docker-compose.yml @@ -6,6 +6,7 @@ services: container_name: "factorio-events-kafka-pipe" build: dockerfile: "kafka-pipe.Dockerfile" + privileged: true networks: - "factorio-events-nw" environment: diff --git a/modules/factorio-events-kafka-pipe/kafka-pipe-jar.Dockerfile b/modules/factorio-events-kafka-pipe/kafka-pipe-jar.Dockerfile deleted file mode 100644 index 16ded19..0000000 --- a/modules/factorio-events-kafka-pipe/kafka-pipe-jar.Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -ARG JAR_LOCATION - -FROM openjdk:11.0.6-jre-buster -ARG JAR_LOCATION - -RUN apt-get update && apt-get install -y \ - curl \ - && rm -rf /var/lib/apt/lists/* - -COPY JAR_LOCATION /app.jar - -ENTRYPOINT ["java","-jar","/app.jar"] diff --git a/modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile b/modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile index 9fc1c79..ce5b414 100644 --- a/modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile +++ b/modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile @@ -1,31 +1,15 @@ - -#FROM debian:buster-slim FROM docker:dind-rootless ENV FACTORIO_SERVER_CONTAINER_NAME="factorio-server" -ENV KAFKA_HOST="kafka-kraft" +ENV KAFKA_HOST="kafka" -#RUN apt-get update && apt-get install -y --no-install-recommends \ -# curl \ -# docker \ -# kafkacat - -# root is required for following Docker logs +# root is required for installing dependencies USER root - RUN apk add --update \ curl \ kafkacat -#USER rootless - -# \ -# && rm -rf /var/lib/apt/lists/* +USER rootless COPY kafka-pipe.sh kafka-pipe.sh -#RUN useradd --user-group --system --create-home --no-log-init the_engineer -#USER the_engineer - ENTRYPOINT [ "/bin/sh", "/kafka-pipe.sh" ] -#ENTRYPOINT /bin/bash -#CMD exec /kafka-pipe.sh diff --git a/modules/factorio-events-kafka-pipe/pipe-logs-to-kafka.sh b/modules/factorio-events-kafka-pipe/pipe-logs-to-kafka.sh deleted file mode 100644 index d89e815..0000000 --- a/modules/factorio-events-kafka-pipe/pipe-logs-to-kafka.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/zsh - -# stream logs from 'factorio' container -# follow the logs, and -# combine stdout and stderr -# only match lines that start with 'FactorioEvent: ', -# and only return the stuff *after* 'FactorioEvent: ' -docker logs --tail 0 -f factorio-server 2>&1 | - sed -n -e 's/^FactorioEvent: //p' | - kafkacat -P -b localhost -t factorio-server-log - -# listen to events -# kafkacat -C -b localhost -t factorio-server-log | jq - -# curl -sS --unix-socket /var/run/docker.sock "http://localhost/v1.41/events?filters={"service":"factorio-server"}" --output - | jq - -curl --no-buffer -sS \ - --unix-socket /var/run/docker.sock \ - "http://localhost/v1.41/containers/factorio-server/logs?stdout=true&follow=true&tail=0" | - tail -c+9 -# --output - - -curl \ - -sS \ - --unix-socket /var/run/docker.sock \ - -X POST \ - --insecure "http://localhost/v1.41/containers/factorio-server/attach?logs=true&stream=true&stdout=true&follow=true" | - tail -c+9 - -# sed 's/^........//' - - -# https://stackoverflow.com/questions/42873285/curl-retry-mechanism -# --retry-all-errors - -# --header "Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==" \ -# --header "Sec-WebSocket-Version: 13" \ -# --header "Host: localhost:80" \ -# --header "Origin: http://localhost:80" \ - -curl --include \ - --unix-socket /var/run/docker.sock \ - --no-buffer \ - --header "Connection: Upgrade" \ - --header "Upgrade: websocket" \ - --header "Host: localhost:80" \ - --header "Origin: http://localhost:80" \ - --header "Sec-WebSocket-Version: 13" \ - --header "Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==" \ - "http://localhost/v1.41/containers/factorio-server/attach/ws?logs=true&stdout=true" diff --git a/modules/factorio-events-kafka-pipe/readme.md b/modules/factorio-events-kafka-pipe/readme.md index 5d9977d..2fc4129 100644 --- a/modules/factorio-events-kafka-pipe/readme.md +++ b/modules/factorio-events-kafka-pipe/readme.md @@ -1,8 +1,6 @@ - ### Setup notes -Kafka must be connectable from both `localhost` (for cli) and `kafa` (the docker container name). - +Kafka must be connectable from both `localhost` (for cli) and `kafa` (the docker container name). ### Useful commands @@ -43,5 +41,12 @@ curl --no-buffer -sS --unix-socket /var/run/docker.sock \ # get logs from Kafka kafkacat -u -C -b localhost -t factorio-server-log | jq --unbuffered -``` +# stream logs, and try trimming first 8 bytes (the header) but it doesn't work +curl \ + -sS \ + --unix-socket /var/run/docker.sock \ + -X POST \ + --insecure "http://localhost/v1.41/containers/factorio-server/attach?logs=true&stream=true&stdout=true&follow=true" | + tail -c+9 +``` \ No newline at end of file diff --git a/modules/factorio-events-kafka-pipe/src/main/kotlin/fekp.kt b/modules/factorio-events-kafka-pipe/src/main/kotlin/fekp.kt deleted file mode 100644 index be87043..0000000 --- a/modules/factorio-events-kafka-pipe/src/main/kotlin/fekp.kt +++ /dev/null @@ -1,17 +0,0 @@ -import eu.jrie.jetbrains.kotlinshell.shell.shell - -fun main() { - shell { - - "echo hello world"() - -// """ -// curl \ -// --no-buffer \ -// -sS \ -// --unix-socket /var/run/docker.sock \ -// "http://localhost/v1.41/containers/factorio-server/logs?stdout=true&follow=true&tail=0" -// """.trimIndent() - - } -} \ No newline at end of file From 416e3ff4fdba6ebb352df58deab87f9cc30fca71 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 23 Oct 2021 23:51:43 +0200 Subject: [PATCH 037/629] kafka pipe requires root --- modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile b/modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile index ce5b414..edcb96c 100644 --- a/modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile +++ b/modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile @@ -3,12 +3,13 @@ FROM docker:dind-rootless ENV FACTORIO_SERVER_CONTAINER_NAME="factorio-server" ENV KAFKA_HOST="kafka" -# root is required for installing dependencies +# root is required for installing dependencies and +# using the docker socket (listening to logs) USER root RUN apk add --update \ curl \ kafkacat -USER rootless +#USER rootless COPY kafka-pipe.sh kafka-pipe.sh From 2d9aaa4190233723111cd1ffa17d9cc4f8728820 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 23 Oct 2021 23:51:48 +0200 Subject: [PATCH 038/629] fix mod version --- modules/mod/src/main/typescript/model/model.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/mod/src/main/typescript/model/model.ts b/modules/mod/src/main/typescript/model/model.ts index dcd2615..eea1f76 100644 --- a/modules/mod/src/main/typescript/model/model.ts +++ b/modules/mod/src/main/typescript/model/model.ts @@ -13,7 +13,7 @@ export interface JsonTable { [key: string]: JsonTableValueType } -const MOD_VERSION = script.active_mods["factorio_web_map"] +const MOD_VERSION = script.active_mods["factorio-web-map"] export interface FactorioEvent extends JsonTable { /** Schema versioning */ From 9982336144a01f203fe0f520cb1793949dcf7591 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sun, 24 Oct 2021 12:28:12 +0200 Subject: [PATCH 039/629] setup kafka-ui --- .../docker-compose.yml | 1 + modules/mod/infra/docker-compose.yml | 33 ++++++++++++------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/modules/factorio-events-kafka-pipe/docker-compose.yml b/modules/factorio-events-kafka-pipe/docker-compose.yml index 4d42dbd..6f8a60e 100644 --- a/modules/factorio-events-kafka-pipe/docker-compose.yml +++ b/modules/factorio-events-kafka-pipe/docker-compose.yml @@ -6,6 +6,7 @@ services: container_name: "factorio-events-kafka-pipe" build: dockerfile: "kafka-pipe.Dockerfile" + restart: "unless-stopped" privileged: true networks: - "factorio-events-nw" diff --git a/modules/mod/infra/docker-compose.yml b/modules/mod/infra/docker-compose.yml index 466e4cf..180c22b 100644 --- a/modules/mod/infra/docker-compose.yml +++ b/modules/mod/infra/docker-compose.yml @@ -15,12 +15,12 @@ services: - "27015:27015/tcp" # rcon volumes: - "./factorio-server:/factorio" -# logging: -# driver: "mickyg/kafka-logdriver:latest" -# options: -# KAFKA_BROKER_ADDR: "kafka-kraft" -# LOG_TOPIC: "dockerlogs-factorio-server" -# LOG_TAG: "factorio-server" + # logging: + # driver: "mickyg/kafka-logdriver:latest" + # options: + # KAFKA_BROKER_ADDR: "kafka-kraft" + # LOG_TOPIC: "dockerlogs-factorio-server" + # LOG_TAG: "factorio-server" # environment: # RCON_PORT: 27715 @@ -41,17 +41,24 @@ services: args: KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/3.0.0/kafka_2.13-3.0.0.tgz" networks: + - "kafka-nw" - "factorio-events-nw" ports: - "9092:9092" - "9093:9093" -# environment: -# KAFKA_LISTENERS: "PLAINTEXT://kafka-kraft:29092,PLAINTEXT_HOST://localhost:9092,CONTROLLER_HOST://localhost:9093" # ,CONTROLLER://kafka-kraft:29093 -# KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT,CONTROLLER:PLAINTEXT" #,CONTROLLER_HOST:PLAINTEXT -# KAFKA_INTER_BROKER_LISTENER_NAME: "PLAINTEXT" -# KAFKA_ADVERTISED_LISTENERS: "PLAINTEXT://kafka-kraft:29092,PLAINTEXT_HOST://localhost:9092" -# KAKFA_CONTROLLER_LISTENER_NAMES: "CONTROLLER" #,CONTROLLER_HOST + kafka-ui: + image: provectuslabs/kafka-ui:0.2.1 + container_name: kafka-ui + restart: "unless-stopped" + networks: + - "kafka-nw" + ports: + - "8080:8080" + environment: + - KAFKA_CLUSTERS_0_NAME=factorio-events + - KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka:29092 +# - KAFKA_CLUSTERS_0_ZOOKEEPER=kafka:9093 # kafka-connect: # image: dev-adamko/kafka-connect @@ -69,6 +76,8 @@ services: networks: + kafka-nw: + name: "kafka-nw" factorio-events-nw: name: "factorio-events-nw" From cc1ca86b9cb883377d9fd8ddb060988144684391 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sun, 24 Oct 2021 12:40:00 +0200 Subject: [PATCH 040/629] set service name to factorio-events-kafka-pipe --- modules/factorio-events-kafka-pipe/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/factorio-events-kafka-pipe/docker-compose.yml b/modules/factorio-events-kafka-pipe/docker-compose.yml index 6f8a60e..3e77115 100644 --- a/modules/factorio-events-kafka-pipe/docker-compose.yml +++ b/modules/factorio-events-kafka-pipe/docker-compose.yml @@ -1,7 +1,7 @@ version: "3.9" services: - kp2: + factorio-events-kafka-pipe: image: openjdk:11-jre-buster container_name: "factorio-events-kafka-pipe" build: From 4329651c863f7e395c700dc0ae7b07478da6a657 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sun, 24 Oct 2021 14:55:04 +0200 Subject: [PATCH 041/629] tidy up shared config, start setting up kafka processor --- .gitignore | 3 + .../archetype/kotlin-jvm.gradle.kts | 30 +++++++- gradle/libs.versions.toml | 15 +++- .../build.gradle.kts | 20 +++++ .../processor/FactorioEventLogConsumer.kt | 7 ++ .../processor/FactorioEventsTopology.kt | 20 +++++ .../processor/StreamsExceptionHandler.kt | 11 +++ .../processor/config/ApplicationProperties.kt | 68 +++++++++++++++++ .../factorioevents/processor/config/Lenses.kt | 38 ++++++++++ .../processor/config/PortVal.kt | 30 ++++++++ .../processor/config/environmentExt.kt | 73 +++++++++++++++++++ .../adamko/factorioevents/processor/main.kt | 19 +++++ modules/kt-rcon/build.gradle.kts | 2 +- 13 files changed, 332 insertions(+), 4 deletions(-) create mode 100644 modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventLogConsumer.kt create mode 100644 modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventsTopology.kt create mode 100644 modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt create mode 100644 modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt create mode 100644 modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/Lenses.kt create mode 100644 modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/PortVal.kt create mode 100644 modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/environmentExt.kt create mode 100644 modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt diff --git a/.gitignore b/.gitignore index acd20e6..57dfac2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ +# ignore any files that start with '.secret' +.secret.* + .idea node_modules diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts index ef894b0..7e3553c 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts @@ -9,12 +9,36 @@ plugins { kotlin { jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(11)) // "8" + (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(11)) } } dependencies { + + // + implementation(platform("org.jetbrains.kotlin:kotlin-bom")) + implementation(kotlin("stdlib")) + + // + + // + + val junitVersion = "5.8.1" + testImplementation(enforcedPlatform("org.junit:junit-bom:$junitVersion")) + testImplementation("org.junit.jupiter:junit-jupiter-api") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") + + val kotestVersion = "4.6.3" + testImplementation(enforcedPlatform("io.kotest:kotest-bom:$kotestVersion")) + testImplementation("io.kotest:kotest-runner-junit5-jvm:$kotestVersion") + testImplementation("io.kotest:kotest-assertions-core-jvm:$kotestVersion") + testImplementation("io.kotest:kotest-property-jvm:$kotestVersion") + testImplementation("io.kotest:kotest-assertions-json:$kotestVersion") + testImplementation("io.mockk:mockk:1.12.0") + // + } tasks.withType().configureEach { @@ -24,4 +48,8 @@ tasks.withType().configureEach { "-Xopt-in=kotlin.time.ExperimentalTime", "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", ) +} + +tasks.compileTestKotlin { + kotlinOptions.freeCompilerArgs += "-Xopt-in=io.kotest.common.ExperimentalKotest" } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b9724e7..cadbdd3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,13 +9,14 @@ jvm = "11" kotlin = "1.5.31" ## libs ## -http4k = "4.13.1.0" +http4k = "4.16.1.0" slf4j = "1.7.30" log4j2 = "2.14.1" qosLogback = "1.2.5" +kafka = "3.0.0" ## test ## -junit = "5.8.0" +junit = "5.8.1" kotest = "4.6.3" @@ -59,6 +60,7 @@ http4k-cloudnative = { group = "org.http4k", name = "http4k-cloudnative" http4k-format-json = { group = "org.http4k", name = "http4k-format-jackson" } http4k-format-xml = { group = "org.http4k", name = "http4k-format-jackson-xml" } http4k-format-yaml = { group = "org.http4k", name = "http4k-format-jackson-yaml" } +http4k-graphql = { group = "org.http4k", name = "http4k-graphql" } ## logging ## slf4j-api = { group = "org.slf4j", name = "slf4j-api", version.ref = "slf4j" } @@ -73,6 +75,14 @@ gcp-pubsub = { group = "com.google.cloud", name = "google-cloud-pubsub" gcp-speech = { group = "com.google.cloud", name = "google-cloud-speech" } +## kafka ## + +kafka-streams = { group = "org.apache.kafka", name = "kafka-streams", version.ref = "kafka" } + +# kafka helpers +kotka = { group = "com.github.blueanvil", name = "kotka", version = "1.1.1" } + + ############# ### test ### ############# @@ -86,6 +96,7 @@ junit-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine", junit-launcher = { group = "org.junit.platform", name = "junit-platform-launcher", version = "1.7.2" } ## kotest ## +kotest-bom = { group = "io.kotest", name = "kotest-bom", version.ref = "kotest" } kotest-core = { group = "io.kotest", name = "kotest-assertions-core-jvm", version.ref = "kotest" } kotest-datatest = { group = "io.kotest", name = "kotest-framework-datatest", version.ref = "kotest" } kotest-runner = { group = "io.kotest", name = "kotest-runner-junit5-jvm", version.ref = "kotest" } diff --git a/modules/factorio-events-processor/build.gradle.kts b/modules/factorio-events-processor/build.gradle.kts index e5eff9b..9a44560 100644 --- a/modules/factorio-events-processor/build.gradle.kts +++ b/modules/factorio-events-processor/build.gradle.kts @@ -1,5 +1,7 @@ + plugins { id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") + application } description = @@ -12,3 +14,21 @@ description = val projectId: String by project.extra val buildDir: Directory = layout.buildDirectory.dir(projectId).get() +@Suppress("UnstableApiUsage") +dependencies { + + implementation("org.apache.kafka:kafka-streams:3.0.0") + + implementation(platform(libs.http4k.bom)) + implementation(libs.http4k.core) + implementation(libs.http4k.cloudnative) + implementation(libs.http4k.format.json) + implementation(libs.http4k.format.yaml) + + implementation(libs.bundles.logging) + +} + +application { + mainClass.set("dev.adamko.factorioevents.processor.mainKt") +} diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventLogConsumer.kt b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventLogConsumer.kt new file mode 100644 index 0000000..091f084 --- /dev/null +++ b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventLogConsumer.kt @@ -0,0 +1,7 @@ +package dev.adamko.factorioevents.processor + +/** + * Process the raw messages from a server. + */ +class FactorioEventLogConsumer { +} \ No newline at end of file diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventsTopology.kt b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventsTopology.kt new file mode 100644 index 0000000..83924d9 --- /dev/null +++ b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventsTopology.kt @@ -0,0 +1,20 @@ +package dev.adamko.factorioevents.processor + +import java.util.Properties +import org.apache.kafka.streams.KafkaStreams +import org.apache.kafka.streams.StreamsBuilder + +class FactorioEventsTopology { + + fun build() { + + val topology = StreamsBuilder().build() + + + val properties = Properties() + + val kafkaStreams = KafkaStreams(topology, properties) + + } + +} \ No newline at end of file diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt new file mode 100644 index 0000000..bf05679 --- /dev/null +++ b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt @@ -0,0 +1,11 @@ +package dev.adamko.factorioevents.processor + +import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler +import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler.StreamThreadExceptionResponse + +class StreamsExceptionHandler : StreamsUncaughtExceptionHandler { + override fun handle(exception: Throwable): StreamThreadExceptionResponse { + println("${exception.message} - ${exception.stackTrace}") + return StreamThreadExceptionResponse.REPLACE_THREAD + } +} diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt new file mode 100644 index 0000000..86232c8 --- /dev/null +++ b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt @@ -0,0 +1,68 @@ +package dev.adamko.factorioevents.processor.config + +import com.fasterxml.jackson.databind.JsonNode +import dev.adamko.factorioevents.processor.config.PortVal.Companion.portVal +import java.io.StringReader +import java.time.Clock +import java.util.Properties +import org.http4k.cloudnative.env.Environment +import org.http4k.cloudnative.env.EnvironmentKey +import org.http4k.core.Credentials +import org.http4k.core.Uri +import org.http4k.format.Jackson +import org.http4k.format.Json +import org.http4k.lens.boolean +import org.http4k.lens.map +import org.http4k.lens.nonEmptyString +import org.http4k.lens.uri + +/** + * Load properties, in descending priority order, from + * + * 1. Environment variables + * 2. This app's env file (as defined by the environment variable [Lenses.APPLICATION_PROPERTIES_FILE_PATH]) + * # 3. A resources-dir yaml file + * + */ +class ApplicationProperties( + vararg environments: Environment = arrayOf( + Environment.env(), + Environment.fromEnvVarPath(), + Environment.fromResourcesFile(".secret.config.yml") + ) +) { + private val appProps: Environment = + environments.reduce { acc, environment -> acc.overrides(environment) } + + fun clock(): Clock = Clock.systemUTC() + + // + + /** + * The port of the server + * + * Set by GCP ([docs](https://cloud.google.com/run/docs/reference/container-contract#env-vars)). + */ + val serverPort: PortVal + get() = EnvironmentKey.portVal().defaulted("PORT", PortVal.DEFAULT)[appProps] + + // + + + // + + val kafkaConfig: Properties + get() = EnvironmentKey + .nonEmptyString() + .map { + it.reader().use { sr -> + Properties().also { p -> + p.load(sr) + } + } + } + .required("kafka.config")[appProps] + + // + +} diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/Lenses.kt b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/Lenses.kt new file mode 100644 index 0000000..26e5109 --- /dev/null +++ b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/Lenses.kt @@ -0,0 +1,38 @@ +package dev.adamko.factorioevents.processor.config + +import java.io.File +import org.http4k.cloudnative.env.Environment +import org.http4k.cloudnative.env.EnvironmentKey +import org.http4k.core.Credentials +import org.http4k.lens.BiDiLens +import org.http4k.lens.BiDiMapping + + +internal object Lenses { + + /** The location of this app's env file. */ + val APPLICATION_PROPERTIES_FILE_PATH: BiDiLens = + EnvironmentKey + .map( + { path: String -> File(path) }, + { file: File -> file.canonicalPath }, + ) + .optional("APPLICATION_PROPERTIES_FILE_PATH") + + /** Bidirectional [String] and [Credentials] mapper. */ + val credentialsLens: BiDiMapping = run { + val separator = ":" + BiDiMapping( + // from String to Credentials + { property -> + property.split(separator, limit = 2) + .takeIf { it.size == 2 } + ?.let { (user, pass) -> Credentials(user, pass) } + ?: throw IllegalArgumentException("Credentials are invalid") + }, + // from Credentials to String + { it.user + separator + it.password } + ) + } + +} diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/PortVal.kt b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/PortVal.kt new file mode 100644 index 0000000..498dc77 --- /dev/null +++ b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/PortVal.kt @@ -0,0 +1,30 @@ +package dev.adamko.factorioevents.processor.config + +import org.http4k.cloudnative.env.Port +import org.http4k.lens.BiDiLensSpec +import org.http4k.lens.StringBiDiMappings.int +import org.http4k.lens.map + +/** + * Improved (slightly) version of http4k's [Port]. + */ +@JvmInline +value class PortVal(val value: Int) { + + init { + require(value in VALID_RANGE) { + "Out of range. Port: '$value', range: $VALID_RANGE" + } + } + + operator fun invoke(): Int = value + + companion object { + val DEFAULT = PortVal(8080) + val VALID_RANGE: IntRange + get() = (1..65535) + + fun BiDiLensSpec.portVal(): BiDiLensSpec = + map(int().map(::PortVal, PortVal::value)) + } +} diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/environmentExt.kt b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/environmentExt.kt new file mode 100644 index 0000000..d0a837f --- /dev/null +++ b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/environmentExt.kt @@ -0,0 +1,73 @@ +package dev.adamko.factorioevents.processor.config + +import java.io.File +import java.io.FileNotFoundException +import org.http4k.cloudnative.env.Environment +import org.http4k.cloudnative.env.MapEnvironment +import org.http4k.cloudnative.env.fromYaml +import org.http4k.lens.Lens + + +/** + * Load properties from either a `.yaml` or `.env` file. + * + * (An improved version of [Environment.fromResource]) + */ +internal fun Environment.Companion.fromResourcesFile( + resource: String, + default: Environment = EMPTY +) = + try { + val file = + this::class.java + .getResource("/${resource.removePrefix("/")}") + ?.file + ?.let { File(it) } + fromFile(file, default) + } catch (e: FileNotFoundException) { + default + } + +/** + * Try fetching a properties file the location provided by the + * [`JVM`][jvmProperties] or [`System`][env] environment variable + * [Lenses.APPLICATION_PROPERTIES_FILE_PATH], if it exists. + * + * If it does not exist, return [default]. + */ +internal fun Environment.Companion.fromEnvVarPath( + location: Lens = Lenses.APPLICATION_PROPERTIES_FILE_PATH, + default: Environment = EMPTY, +): Environment { + val file = (jvmProperties() overrides env())[location] + + return fromFile(file, default) +} + +/** + * Load properties from either a `.yaml` or `.env` file. + * + * (An improved version of [Environment.from]) + */ +internal fun Environment.Companion.fromFile( + file: File?, + default: Environment = EMPTY, +): Environment { + return file + ?.takeIf { it.isFile } + .let { + when (it?.extension) { + "yml", "yaml" -> fromYaml(it) + "env" -> from(it) + else -> default + } + } +} + +/** The same as [Environment.ENV], but refreshes on each invocation (which is useful for testing). */ +internal fun Environment.Companion.env(): Environment = + MapEnvironment.from(System.getenv().toProperties()) + +/** The same as [Environment.JVM_PROPERTIES], but refreshes on each invocation (which is useful for testing). */ +internal fun Environment.Companion.jvmProperties(): Environment = + MapEnvironment.from(System.getProperties()) diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt new file mode 100644 index 0000000..f0df841 --- /dev/null +++ b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt @@ -0,0 +1,19 @@ +package dev.adamko.factorioevents.processor + +import dev.adamko.factorioevents.processor.config.ApplicationProperties +import org.apache.kafka.streams.KafkaStreams +import org.apache.kafka.streams.StreamsBuilder + +fun main() { + + val appProps = ApplicationProperties() + + val topology = StreamsBuilder().build() + + val properties = appProps.kafkaConfig + + val streams = KafkaStreams(topology, properties) + + streams.setUncaughtExceptionHandler(StreamsExceptionHandler()) + +} \ No newline at end of file diff --git a/modules/kt-rcon/build.gradle.kts b/modules/kt-rcon/build.gradle.kts index dbd36d2..cab5d06 100644 --- a/modules/kt-rcon/build.gradle.kts +++ b/modules/kt-rcon/build.gradle.kts @@ -8,7 +8,7 @@ plugins { dependencies { - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2") + implementation(libs.kotlinx.coroutines) implementation("io.ktor:ktor-network:1.6.4") From 8b11670a692d97e141781311e3a7c544e7fc251a Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Mon, 25 Oct 2021 23:22:23 +0200 Subject: [PATCH 042/629] kafka-pipe - use a random key for messages --- modules/factorio-events-kafka-pipe/kafka-pipe.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/factorio-events-kafka-pipe/kafka-pipe.sh b/modules/factorio-events-kafka-pipe/kafka-pipe.sh index e0f5b7b..1c7aae1 100644 --- a/modules/factorio-events-kafka-pipe/kafka-pipe.sh +++ b/modules/factorio-events-kafka-pipe/kafka-pipe.sh @@ -10,12 +10,15 @@ endProcess() { exit } +# some random ID, to use as a message key +INSTANCE_ID=$(cat /proc/sys/kernel/random/uuid) + while :; do docker logs --tail 0 -f "$FACTORIO_SERVER_CONTAINER_NAME" | sed -n -e 's/^FactorioEvent: //p' | - kafkacat -P -T -b "$KAFKA_HOST" -t factorio-server-log + kafkacat -P -T -b "$KAFKA_HOST" -t factorio-server-log -k "$INSTANCE_ID" echo "Error - retrying in 10 seconds" - sleep 10 + done From 9447dce307f86d94445d4867f5861ce5bf10b9d3 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Mon, 25 Oct 2021 23:23:05 +0200 Subject: [PATCH 043/629] add some todo links to readme --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 9606faa..6a039de 100644 --- a/README.md +++ b/README.md @@ -19,4 +19,11 @@ to investigate: * https://github.com/starwing/lua-protobuf * https://github.com/grafi-tt/lunajson +* http://lua-users.org/wiki/CompressionAndArchiving +* https://luapower.com/zlib +* https://square.github.io/okio/#communicate-on-a-socket-javakotlin + +* https://github.com/cloudhut/kowl +* https://opensource.expediagroup.com/graphql-kotlin/docs/server/spring-server/spring-subscriptions +* https://github.com/YousefED/typescript-json-schema From 2de66a7406c5d2f307a42687bfa0789b96eced3a Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Mon, 25 Oct 2021 23:23:28 +0200 Subject: [PATCH 044/629] add serialization to buildsrc --- buildSrc/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index f337b75..8b7aba1 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -13,6 +13,7 @@ dependencies { // implementation("org.gradle.kotlin:gradle-kotlin-dsl-plugins:${kotlinVersion}") implementation(platform("org.jetbrains.kotlin:kotlin-bom:$kotlinVersion")) + implementation("org.jetbrains.kotlin:kotlin-serialization") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin") From aee68af5b396212122e154cb68edbb7157dec5c5 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Mon, 25 Oct 2021 23:23:55 +0200 Subject: [PATCH 045/629] start mucking about with a custom Factorio docker --- modules/mod/infra/factorioEvents.Dockerfile | 23 ++++++++++++++++++++ modules/mod/infra/kafka-pipe.sh | 24 +++++++++++++++++++++ modules/mod/infra/kcat.conf | 1 + 3 files changed, 48 insertions(+) create mode 100644 modules/mod/infra/factorioEvents.Dockerfile create mode 100644 modules/mod/infra/kafka-pipe.sh create mode 100644 modules/mod/infra/kcat.conf diff --git a/modules/mod/infra/factorioEvents.Dockerfile b/modules/mod/infra/factorioEvents.Dockerfile new file mode 100644 index 0000000..32676b8 --- /dev/null +++ b/modules/mod/infra/factorioEvents.Dockerfile @@ -0,0 +1,23 @@ +ARG factorioVersion=1.1.42 + + +FROM factoriotools/factorio:$factorioVersion + + + +#RUN apk add --update \ +# curl \ +# kafkacat \ +# ; + +ENV KCAT_CONFIG="/kcat.conf" + + +RUN apt-get update && apt-get install -y \ + kafkacat \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR / +COPY kafka-pipe.sh kafka-pipe.sh + + diff --git a/modules/mod/infra/kafka-pipe.sh b/modules/mod/infra/kafka-pipe.sh new file mode 100644 index 0000000..75dace3 --- /dev/null +++ b/modules/mod/infra/kafka-pipe.sh @@ -0,0 +1,24 @@ +#!/usr/bin/bash + +# Pipe Docker logs from a Factorio server to a Kafka topic + +echo "Piping logs from $FACTORIO_SERVER_CONTAINER_NAME to $KAFKA_HOST" + +# generate some distinctive key for messages from this server +SERVER_HASH=openssl dgst -sha3-512 "$CONFIG/server-settings.json" + +trap endProcess SIGINT +endProcess() { + echo "Exiting Factorio Events Kafka Pipe" + exit +} + +while :; do + + sed -n -e 's/^FactorioEvent: //p' | + kafkacat -F "$KCAT_PROP_FILE" + + echo "Error - retrying in 10 seconds" + + sleep 10 +done diff --git a/modules/mod/infra/kcat.conf b/modules/mod/infra/kcat.conf new file mode 100644 index 0000000..998c885 --- /dev/null +++ b/modules/mod/infra/kcat.conf @@ -0,0 +1 @@ +enable.idempotence=true From aa4b1f012dad5b742d52590413367d712f7daa47 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Mon, 25 Oct 2021 23:24:43 +0200 Subject: [PATCH 046/629] add serialization dep to buildsrc --- modules/server/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/server/build.gradle.kts b/modules/server/build.gradle.kts index 3f32130..2677c7f 100644 --- a/modules/server/build.gradle.kts +++ b/modules/server/build.gradle.kts @@ -5,7 +5,7 @@ plugins { // kotlin("jvm") id("io.kvision") version "5.4.1" kotlin("js") - kotlin("plugin.serialization") version "1.5.31" + kotlin("plugin.serialization") } group = "${rootProject.group}.server" From 2d72c619e89a054a46f78685f603c2ef3f097161 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Mon, 25 Oct 2021 23:32:08 +0200 Subject: [PATCH 047/629] version bump, adjust name --- gradle/libs.versions.toml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cadbdd3..b0981cc 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -45,9 +45,9 @@ sendgrid = { group = "com.sendgrid", name = "sendgrid-java", version ## kotlin ## kotlin-bom = { group = "org.jetbrains.kotlin", name = "kotlin-bom", version.ref = "kotlin" } -kotlinx-serde = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version = "1.2.2" } -kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.5.2" } -kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.7.3" } +kotlinx-serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version = "1.3.0" } +kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.5.2" } +kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.7.3" } ## http4k ## http4k-bom = { group = "org.http4k", name = "http4k-bom", version.ref = "http4k" } @@ -62,6 +62,10 @@ http4k-format-xml = { group = "org.http4k", name = "http4k-format-jackson-xml" http4k-format-yaml = { group = "org.http4k", name = "http4k-format-jackson-yaml" } http4k-graphql = { group = "org.http4k", name = "http4k-graphql" } +### jackson ## +#jackson-bom = { group = " com.fasterxml.jackson.module", name = ":jackson-module-kotlin", version = "2.13.+" } +#jackson-kotlin = { group = " com.fasterxml.jackson.module", name = ":jackson-module-kotlin", version = "2.13.+" } + ## logging ## slf4j-api = { group = "org.slf4j", name = "slf4j-api", version.ref = "slf4j" } kotlin-logging = { group = "io.github.microutils", name = "kotlin-logging-jvm", version = "2.0.11" } From 513107b56a2ce32665033960c89ae2aba15a4894 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Mon, 25 Oct 2021 23:34:38 +0200 Subject: [PATCH 048/629] whoa... version bump 0.0.3 (and automatically replace this in the mod.zip using tokens) --- build.gradle.kts | 2 +- .../factoriowebmap/archetype/base.gradle.kts | 9 +++++++++ modules/mod/build.gradle.kts | 17 +++++++++++++++-- .../mod/src/main/resources/mod-data/info.json | 2 +- modules/mod/src/main/typescript/package.json | 2 +- 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index c85d539..182dc1f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "dev.adamko.factoriowebmap" -version = "0.0.2" +version = "0.0.3" tasks.wrapper { gradleVersion = "7.2" diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts index 35f58dc..114b6a7 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts @@ -10,6 +10,15 @@ version = rootProject.version val projectId by extra("fwm-${project.name}") //val modBuildDir by extra(layout.buildDirectory.dir(projectId).get()) +val licenseFile: RegularFile by extra(rootProject.layout.projectDirectory.file("LICENSE")) + +val tokens: Map by extra( + mapOf( + "project.version" to "$version", + ) +) + + //group = "dev.adamko.factoriowebmap" //version = "0.0.1" diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index 7a1002d..16c5f5e 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -1,11 +1,13 @@ import com.github.gradle.node.npm.task.NpmTask import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs +import org.apache.tools.ant.filters.ReplaceTokens plugins { id("dev.adamko.factoriowebmap.archetype.node") } val projectId: String by project.extra +val tokens: Map by project.extra val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") val modBuildDir: Directory = layout.buildDirectory.dir(projectId).get() @@ -71,8 +73,13 @@ val modPackageTask = tasks.register("packageMod") { dependsOn(tstlTask) + inputs.properties(tokens) + + from(layout.projectDirectory.dir("src/main/resources/mod-data")) { + include("**/**") + filter("tokens" to tokens) + } from( - layout.projectDirectory.dir("src/main/resources/mod-data"), rootProject.layout.projectDirectory.file("LICENSE"), tstlTask, ) @@ -82,8 +89,14 @@ val modPackageTask = tasks.register("packageMod") { // Factorio required format is: // - filename: `mod-name_version.zip` // - zip contains one directory, `mod-name` - archiveFileName.set("${rootProject.name}_${rootProject.version}.zip") + archiveFileName.set("${rootProject.name}_${project.version}.zip") destinationDirectory.set(modBuildDir.dir("dist")) + + doLast { + val outDir = destinationDirectory.asFile.get().toRelativeString(layout.projectDirectory.asFile) + val outZip = "${archiveFileName.orNull}" + logger.lifecycle("Creating mod zip $outDir/$outZip") + } } //tasks.build { dependsOn(tstlTask, modPackageTask) } diff --git a/modules/mod/src/main/resources/mod-data/info.json b/modules/mod/src/main/resources/mod-data/info.json index edb1777..538c892 100644 --- a/modules/mod/src/main/resources/mod-data/info.json +++ b/modules/mod/src/main/resources/mod-data/info.json @@ -1,6 +1,6 @@ { "name": "factorio-web-map", - "version": "0.0.2", + "version": "@project.version@", "title": "Factorio Web Map", "author": "fredthedeadhead", "factorio_version": "1.1", diff --git a/modules/mod/src/main/typescript/package.json b/modules/mod/src/main/typescript/package.json index d6f6e1b..a663276 100644 --- a/modules/mod/src/main/typescript/package.json +++ b/modules/mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "factorio-web-map-mod", - "version": "0.0.1", + "version": "0.0.3", "private": true, "scripts": { "build": "tstl", From a63edb1c61343848f3b805d20230369e9576d3f5 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Mon, 25 Oct 2021 23:35:18 +0200 Subject: [PATCH 049/629] mucking about with the data-model --- .../build.gradle.kts | 80 ++++++++++--------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index 26f24fc..4481190 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -1,46 +1,52 @@ plugins { - id("dev.adamko.factoriowebmap.archetype.base") - kotlin("multiplatform") +// id("dev.adamko.factoriowebmap.archetype.base") +// kotlin("multiplatform") + + id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") + + id("com.google.protobuf") version "0.8.17" + + } val projectId: String by project.extra val buildDir: Directory = layout.buildDirectory.dir(projectId).get() val nodeModulesDir: Directory by project.extra -kotlin { - - js(IR) { - binaries.executable() -// browser { -// commonWebpackConfig { -// cssSupport.enabled = true +//kotlin { +// +// js(IR) { +// binaries.executable() +//// browser { +//// commonWebpackConfig { +//// cssSupport.enabled = true +//// } +//// } +// +// nodejs() +// useCommonJs() +// +// compilations["main"].apply { +// packageJson { +// customField( +// "scripts", +// mapOf( +// "build" to "tstl", +// "dev" to "tstl --watch", +// ) +// ) // } // } - - nodejs() - useCommonJs() - - compilations["main"].apply { - packageJson { - customField( - "scripts", - mapOf( - "build" to "tstl", - "dev" to "tstl --watch", - ) - ) - } - } - - } - - jvm { - compilations.all { - kotlinOptions.jvmTarget = "11" - } - testRuns["test"].executionTask.configure { - useJUnitPlatform() - } - } - -} +// +// } +// +// jvm { +// compilations.all { +// kotlinOptions.jvmTarget = "11" +// } +// testRuns["test"].executionTask.configure { +// useJUnitPlatform() +// } +// } +// +//} From da9cc6398fb0e93af7d458b1db6cc5f71536af98 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Mon, 25 Oct 2021 23:35:47 +0200 Subject: [PATCH 050/629] mucking about with the kafka processor --- .../build.gradle.kts | 4 +- .../adamko/factorioevents/processor/main.kt | 32 +++++++++- .../model/FactorioServerLogRecord.kt | 62 +++++++++++++++++++ 3 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecord.kt diff --git a/modules/factorio-events-processor/build.gradle.kts b/modules/factorio-events-processor/build.gradle.kts index 9a44560..9229e4d 100644 --- a/modules/factorio-events-processor/build.gradle.kts +++ b/modules/factorio-events-processor/build.gradle.kts @@ -1,6 +1,6 @@ - plugins { id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") + kotlin("plugin.serialization") application } @@ -19,6 +19,8 @@ dependencies { implementation("org.apache.kafka:kafka-streams:3.0.0") + implementation(libs.kotlinx.serialization) + implementation(platform(libs.http4k.bom)) implementation(libs.http4k.core) implementation(libs.http4k.cloudnative) diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt index f0df841..3336a95 100644 --- a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt +++ b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt @@ -1,19 +1,47 @@ package dev.adamko.factorioevents.processor import dev.adamko.factorioevents.processor.config.ApplicationProperties +import dev.adamko.factorioevents.processor.model.FactorioServerLogRecord +import dev.adamko.factorioevents.processor.model.LuaSurfaceData +import java.time.Duration +import org.apache.kafka.common.serialization.Serdes import org.apache.kafka.streams.KafkaStreams +import org.apache.kafka.streams.KeyValue import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.kstream.Branched +import org.apache.kafka.streams.kstream.Consumed +import org.apache.kafka.streams.kstream.Named +import org.apache.kafka.streams.processor.TopicNameExtractor +import org.http4k.format.Jackson fun main() { val appProps = ApplicationProperties() - val topology = StreamsBuilder().build() + val builder = StreamsBuilder() + + builder.stream( + "factorio-server-log", + Consumed.with(Serdes.String(), Serdes.String()) + ) + .mapValues { readOnlyKey, value -> + println("Mapping $readOnlyKey:$value") + Jackson.asA>(value) + } + .to(TopicNameExtractor { key, value, recordContext -> + value.data.objectName + }) + + val topology = builder.build() val properties = appProps.kafkaConfig val streams = KafkaStreams(topology, properties) streams.setUncaughtExceptionHandler(StreamsExceptionHandler()) -} \ No newline at end of file + Runtime.getRuntime().addShutdownHook(Thread { streams.close(Duration.ofSeconds(10)) }) + + streams.start() + +} diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecord.kt b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecord.kt new file mode 100644 index 0000000..c8a8182 --- /dev/null +++ b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecord.kt @@ -0,0 +1,62 @@ +package dev.adamko.factorioevents.processor.model + +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonTypeInfo +import com.fasterxml.jackson.annotation.JsonTypeName +import com.fasterxml.jackson.annotation.JsonValue +import java.math.BigDecimal +import java.math.BigInteger +import kotlin.reflect.KClass + + + + +data class FactorioServerLogRecord( + @JsonProperty("mod_version") + val modVersion: String, + @JsonProperty("tick") + val tick: BigInteger, + @JsonProperty("event_type") + val eventType: String, + @JsonProperty("data") + val data: DataType, +) + + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "object_name", + defaultImpl = Void::class, // equivalent to null + visible = true, +) +sealed class FactorioObjectData( + @JsonProperty("object_name") + val objectName: String +) + +@JsonTypeName("LuaSurface") +class LuaSurfaceData( + @JsonProperty("name") + val name: String, + @JsonProperty("index") + val index: Int, + @JsonProperty("daytime") + val daytime: BigDecimal, +) : FactorioObjectData("LuaSurface") + + +/* + +{ + "tick": 1144860, + "object_name": "LuaSurface", + "event_type": "on_tick", + "data": { + "name": "nauvis", + "index": 1, + "daytime": 0.4942800000457983 + } +} + + */ \ No newline at end of file From 02cda9c72a8fc1c7a840bfd69e7cd4930daa101d Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Mon, 25 Oct 2021 23:39:35 +0200 Subject: [PATCH 051/629] tidying up, making the data model a bit more structured, --- modules/mod/src/main/typescript/events.ts | 12 +--- .../mod/src/main/typescript/model/model.ts | 48 ++++++++++---- .../mod/src/main/typescript/serdes/serdes.ts | 64 +++++++++++++------ 3 files changed, 81 insertions(+), 43 deletions(-) diff --git a/modules/mod/src/main/typescript/events.ts b/modules/mod/src/main/typescript/events.ts index 223112c..4a5d20c 100644 --- a/modules/mod/src/main/typescript/events.ts +++ b/modules/mod/src/main/typescript/events.ts @@ -4,9 +4,6 @@ // declare const factorioData: Data // declare const factorioMods: Mods -// const eventEnum = { -// thingType: Object.values(defines.events) -// } import {Serdes} from "./serdes/serdes" import {FactorioEvent, JsonTable} from "./model/model"; @@ -16,13 +13,10 @@ for (const [k, v] of pairs(defines.events)) { mapEventIdToName.set(v, k) } -// function createFactorioEvent(tick: uint, object_name: string, eventType: string, data: -// JsonTable): FactorioEvent { return { tick, object_name, eventType, data, } } - function handlePlayerUpdate(tick: uint, playerIndex: uint, eventType: string) { let player: LuaPlayer = game.players[playerIndex] let table = Serdes.Player.playerToTable(player) - let event = FactorioEvent(tick, player.object_name, eventType, table) + let event = FactorioEvent(tick, eventType, table) emitEvent(event) handleCharactersEvent(tick, playerIndex, eventType) @@ -44,13 +38,13 @@ function handleCharactersEvent(tick: uint, playerIndex: uint, eventType: string) function handleEntityUpdate(tick: uint, entity: LuaEntity, eventType: string) { let table = Serdes.Entity.entityToTable(entity) - let event = FactorioEvent(tick, entity.object_name, eventType, table) + let event = FactorioEvent(tick, eventType, table) emitEvent(event) } function surfaceEvent(tick: uint, surface: LuaSurface, eventType: string) { let table = Serdes.Surface.surfaceToTable(surface) - let event = FactorioEvent(tick, surface.object_name, eventType, table) + let event = FactorioEvent(tick, eventType, table) emitEvent(event) } diff --git a/modules/mod/src/main/typescript/model/model.ts b/modules/mod/src/main/typescript/model/model.ts index eea1f76..125a27c 100644 --- a/modules/mod/src/main/typescript/model/model.ts +++ b/modules/mod/src/main/typescript/model/model.ts @@ -1,3 +1,6 @@ +import {Serdes} from "../serdes/serdes"; +import FactorioObjectData = Serdes.FactorioObjectData; + export type JsonPrimitiveType = number | string | boolean | undefined | null | void export type JsonArray = T[] @@ -22,18 +25,37 @@ export interface FactorioEvent extends JsonTable { tick: uint, /** the initial Factorio event ({defines.events}) trigger */ event_type: string, - /** Defines the structure of {FactorioEvent.data} */ - object_name: string, - data: JsonTable, + data: FactorioObjectData, } -export const FactorioEvent = ((tick: uint, objectName: string, eventType: string, data: JsonTable) => { - return { - mod_version: MOD_VERSION, - tick: tick, - object_name: objectName, - event_type: eventType, - data: data, - } as FactorioEvent - } -) +export const FactorioEvent = + (( + tick: uint, + eventType: string, + data: DataType + ) => { + return { + mod_version: MOD_VERSION, + tick: tick, + event_type: eventType, + data: data, + } as FactorioEvent + } + ) + + +// export type JsonArray = TValue[] +// export class JsonArray extends Array { +// } + +// export type JsonArray = Array +// declare type JsonArrayConstructor = (new () => JsonArray) +// declare const JsonArray: JsonArrayConstructor + +// export class JsonTable extends LuaTable { +// } +// export type JsonTable = LuaTable +// const JsonTable = () => new LuaTable() +// export type JsonTableConstructor = (new () => JsonTable) +// declare const JsonTable: JsonTableConstructor + diff --git a/modules/mod/src/main/typescript/serdes/serdes.ts b/modules/mod/src/main/typescript/serdes/serdes.ts index 5a9cfe3..b3de4be 100644 --- a/modules/mod/src/main/typescript/serdes/serdes.ts +++ b/modules/mod/src/main/typescript/serdes/serdes.ts @@ -1,28 +1,26 @@ -// export type JsonArray = TValue[] -// export class JsonArray extends Array { -// } - -// export type JsonArray = Array -// declare type JsonArrayConstructor = (new () => JsonArray) -// declare const JsonArray: JsonArrayConstructor - -// export class JsonTable extends LuaTable { -// } -// export type JsonTable = LuaTable -// const JsonTable = () => new LuaTable() -// export type JsonTableConstructor = (new () => JsonTable) -// declare const JsonTable: JsonTableConstructor - - import {JsonTable, JsonArray} from "../model/model"; +import PositionData = Serdes.DataClasses.PositionData; + export namespace Serdes { + export interface FactorioObjectData extends JsonTable { + object_name: string + } + export namespace Player { - export function playerToTable(player: LuaPlayer): JsonTable { + export interface PlayerData extends FactorioObjectData { + name: string + character_unit_number?: uint + associated_characters_unit_numbers: JsonArray + position: PositionData + } + + export function playerToTable(player: LuaPlayer): PlayerData { let charIds = Entity.entitiesToUnitNumbers(player.get_associated_characters()) return { + object_name: player.object_name, name: player.name, character_unit_number: player.character?.unit_number, associated_characters_unit_numbers: charIds, @@ -34,9 +32,21 @@ export namespace Serdes { export namespace Entity { - export function entityToTable(entity: LuaEntity): JsonTable { + interface EntityData extends FactorioObjectData { + name: string + type: string + active: boolean + health?: number + surface_index: int + unit_number?: number + position: PositionData + player_index?: number + } - let data: JsonTable = { + export function entityToTable(entity: LuaEntity): EntityData { + + let data: EntityData = { + object_name: entity.object_name, name: entity.name, type: entity.type, active: entity.active, @@ -68,8 +78,15 @@ export namespace Serdes { export namespace Surface { - export function surfaceToTable(surface: LuaSurface): JsonTable { + interface SurfaceData extends FactorioObjectData { + name: string + index: uint + daytime: number + } + + export function surfaceToTable(surface: LuaSurface): SurfaceData { return { + object_name: surface.object_name, name: surface.name, index: surface.index, daytime: surface.daytime, @@ -80,7 +97,12 @@ export namespace Serdes { export namespace DataClasses { - export function positionTableToTable(positionTable: PositionTable): JsonTable { + export interface PositionData extends JsonTable { + x: int + y: int + } + + export function positionTableToTable(positionTable: PositionTable): PositionData { return { x: positionTable.x, y: positionTable.y, From a0747c4564fd372c4ee72e8ac87bf72f95e69a59 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 29 Oct 2021 19:07:33 +0200 Subject: [PATCH 052/629] rm unused file --- .../factorioevents/model/JsonPrimitiveType.kt | 27 ------------------- 1 file changed, 27 deletions(-) delete mode 100644 modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/JsonPrimitiveType.kt diff --git a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/JsonPrimitiveType.kt b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/JsonPrimitiveType.kt deleted file mode 100644 index 013584a..0000000 --- a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/JsonPrimitiveType.kt +++ /dev/null @@ -1,27 +0,0 @@ -package dev.adamko.factorioevents.model - - -//actual sealed interface JsonPrimitive { -// @JvmInline -// actual value class JsonString(val string: String) : JsonPrimitive -// @JvmInline -// actual value class JsonNumber(val number: Number) : JsonPrimitive -// @JvmInline -// actual value class JsonBoolean(val boolean: Boolean) : JsonPrimitive -//} - -//actual class JsonArray( -// private val list: MutableList = mutableListOf() -//) : MutableList by list - -//actual sealed interface JsonTableValue { -// @JvmInline -// actual value class JsonPrimitiveTV(val primitive: JsonPrimitive) : JsonTableValue -// @JvmInline -// actual value class JsonArrayTV(val array: JsonArray) : JsonTableValue -//} - -//actual open class JsonTable( -// private val map: MutableMap = mutableMapOf() -//) : MutableMap by map - From ebba0bb767ded11ae6e912e89cad11e08e11c37f Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 29 Oct 2021 19:09:42 +0200 Subject: [PATCH 053/629] bump typed factorio version --- modules/mod/src/main/typescript/package-lock.json | 8 ++++---- modules/mod/src/main/typescript/package.json | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/mod/src/main/typescript/package-lock.json b/modules/mod/src/main/typescript/package-lock.json index 6aea416..b0ae77b 100644 --- a/modules/mod/src/main/typescript/package-lock.json +++ b/modules/mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "factorio-web-map-mod", - "version": "0.0.1", + "version": "0.0.3", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -74,9 +74,9 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.7.4.tgz", - "integrity": "sha512-IhvydBF1eNtlV8WRJWuu64ySOoMCbNujLX/kvqNMaWL+tcLmORghuQZggCbhuX2HI4wVL+UgGpTwG4xicOQM9A==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.8.0.tgz", + "integrity": "sha512-vuAJfkTBSQKD8mHCN7CAbwJJ73y+xfxLBPlFsYjjd015tMPv8Yrq1hBXxoUFZ1ZWGzNgcFL9RwZ6TspsIH7WJw==", "requires": { "lua-types": "^2.10.1", "typescript-to-lua": "^1.0.0" diff --git a/modules/mod/src/main/typescript/package.json b/modules/mod/src/main/typescript/package.json index a663276..4a2cd61 100644 --- a/modules/mod/src/main/typescript/package.json +++ b/modules/mod/src/main/typescript/package.json @@ -14,12 +14,13 @@ "lua-types": "^2.11.0", "@types/node": "^12.0.8", "typescript-to-lua": "1.0.1", - "typed-factorio": "0.7.4" + "typed-factorio": "0.8.0" }, "peerDependencies": {}, "optionalDependencies": {}, "bundledDependencies": [], "//": { + "typescript-json-schema": "0.51.0", "typescript": "4.4.3", "@types/node": "^13.7.7", "kafkajs": "1.15.0", From 106d7a7923e94b0c3298713fb6445090f7fe8dfe Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 29 Oct 2021 19:14:47 +0200 Subject: [PATCH 054/629] mucking around trying to get protoc working. I've finally got a task that downloads the exe... --- gradle.properties | 1 + .../build.gradle.kts | 263 +++++++++++++++--- .../main/proto/FactorioServerLogRecord.proto | 94 +++++++ .../build.gradle.kts | 95 +++++++ .../FactorioEvent.kt | 63 +++++ .../JsonPrimitiveType.kt | 31 +++ .../src/main/kotlin/PlayerModel.kt | 55 ++++ .../main/proto/FactorioServerLogRecord.proto | 94 +++++++ modules/protoc-gradle-plugin/build.gradle.kts | 159 +++++++++++ .../dev/adamko/gradle/pbandg/ProtocPlugin.kt | 148 ++++++++++ modules/server/build.gradle.kts | 16 +- settings.gradle.kts | 16 +- 12 files changed, 982 insertions(+), 53 deletions(-) create mode 100644 modules/factorio-events-data-model/src/main/proto/FactorioServerLogRecord.proto create mode 100644 modules/factorio-events-data-model2/build.gradle.kts create mode 100644 modules/factorio-events-data-model2/src/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt create mode 100644 modules/factorio-events-data-model2/src/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt create mode 100644 modules/factorio-events-data-model2/src/main/kotlin/PlayerModel.kt create mode 100644 modules/factorio-events-data-model2/src/main/proto/FactorioServerLogRecord.proto create mode 100644 modules/protoc-gradle-plugin/build.gradle.kts create mode 100644 modules/protoc-gradle-plugin/src/main/kotlin/dev/adamko/gradle/pbandg/ProtocPlugin.kt diff --git a/gradle.properties b/gradle.properties index d661f6c..d609dd0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,3 +2,4 @@ kotlin.js.compiler=ir kotlin.mpp.stability.nowarn=true kotlin.mpp.enableGranularSourceSetsMetadata=true kotlin.native.enableDependencyPropagation=false +org.gradle.dependency.verification.console=verbose diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index 4481190..6acd8ce 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -1,52 +1,237 @@ +import org.gradle.api.DefaultTask +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.artifacts.ExternalDependency +import org.gradle.api.plugins.ExtensionAware +import org.gradle.api.provider.Property +import org.gradle.api.tasks.TaskAction +import org.gradle.kotlin.dsl.domainObjectContainer +import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.withType +import org.gradle.kotlin.dsl.property +import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform + plugins { -// id("dev.adamko.factoriowebmap.archetype.base") -// kotlin("multiplatform") - - id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") - - id("com.google.protobuf") version "0.8.17" - - + id("dev.adamko.factoriowebmap.archetype.base") + `kotlin-dsl` } val projectId: String by project.extra val buildDir: Directory = layout.buildDirectory.dir(projectId).get() -val nodeModulesDir: Directory by project.extra -//kotlin { +dependencies { +} + + +class ProtocPlugin : Plugin { + + override fun apply(project: Project) { + + val protocConfig = + project.extensions.create("protocPluginConfig", ProtocPluginConfig::class, project) + +// val protocDep: Configuration = project.configurations.create("protoc") { +// isVisible = false +// isCanBeConsumed = false +// isCanBeResolved = true +// isTransitive = false // -// js(IR) { -// binaries.executable() -//// browser { -//// commonWebpackConfig { -//// cssSupport.enabled = true -//// } -//// } -// -// nodejs() -// useCommonJs() -// -// compilations["main"].apply { -// packageJson { -// customField( -// "scripts", -// mapOf( -// "build" to "tstl", -// "dev" to "tstl --watch", -// ) -// ) +// defaultDependencies { +// add(protocConfig.dependencyProvider()) // } // } + + project.tasks.register("protocPrepare") { + + } + // -// } +// val prepareTask = project.tasks.register("protocPrepare") { +// group = "protoc" // -// jvm { -// compilations.all { -// kotlinOptions.jvmTarget = "11" +// val outputDir = project.rootProject.layout.projectDirectory.dir(".gradle/protoc") +// +// outputs.dir(outputDir) +// +//// doLast { +// val protoc: File = protocDep.resolve().single() +// logger.lifecycle("protoc file $protoc") +// +// from(protoc) +// into(outputDir) +//// } // } -// testRuns["test"].executionTask.configure { -// useJUnitPlatform() -// } -// } // -//} +// project.tasks.build { dependsOn(prepareTask) } +// +// val generateTask = project.tasks.create("protocGenerate") { +// dependsOn(prepareTask) +// } + +// val protocDeps = project.configurations.create("pbAndG") { +// this.let { config -> +// +// config.isVisible = false +// config.isCanBeConsumed = false +// config.isCanBeResolved = true +// config.description = "protoc dependencies" +// +// config.defaultDependencies { +// add(protocConfig.dependencyProvider()) +// } +// } +// +// val generatorsContainer = +// project.objects.domainObjectContainer(ProtocGenerationTask::class) +// protocConfig.extensions.add("protocGenerate", generatorsContainer) +// +// +// project.extensions.add("testingExtensionThingy", project.provider { +// DefaultNativePlatform.getCurrentOperatingSystem().toFamilyName() +// }) +// +// project.tasks.withType { +// } +// +// } +// + } +} + +abstract class ProtocPluginConfig(private val project: Project) : java.io.Serializable { + + val protocVersion: Property = + project.objects.property(String::class).convention("3.9.2") + + val protocGroup: Property = + project.objects.property(String::class).convention("com.google.protobuf") + + val protocArtifactName: Property = + project.objects.property(String::class).convention("protoc") + + val protocArtifactExtension: Property = + project.objects.property(String::class).convention("exe") + + /** + * Should return one of + * + * * `linux` + * * `osx` + * * `windows` + */ + var osFamilyNameProvider: () -> String = { + DefaultNativePlatform.getCurrentOperatingSystem().toFamilyName() + } + + /** + * Should return one of + * + * * `aarch_64` + * * `ppcle_64` + * * `x86_32` + * * `x86_64` + */ + var architectureProvider: () -> String = { + DefaultNativePlatform.getCurrentArchitecture() + .name + .replace("-", "_") + } + + /** + * Default: concatenate [osFamilyNameProvider] and [architectureProvider] + * + * Should return one of: + * + * * `linux-aarch_64` + * * `linux-ppcle_64` + * * `linux-x86_64` + * * `osx-x86_32` + * * `osx-x86_64` + * * `windows-x86_32` + */ + var classifierProvider: () -> String = { + "${osFamilyNameProvider()}-${architectureProvider()}" + } + + var dependencyProvider: () -> ExternalModuleDependency = { + project.dependencies.create( + group = protocGroup.get(), + name = protocArtifactName.get(), + version = protocVersion.get(), + classifier = classifierProvider(), + ext = protocArtifactExtension.get(), + ) + } + +// val generators = project.objects.domainObjectContainer(ProtocGenerationConfig::class) +} + +abstract class ProtocGenerationConfig + +abstract class ProtocPrepareTask : DefaultTask() { + + @get:OutputDirectory + val outputDirectory: DirectoryProperty = project.objects.directoryProperty() + .convention(project.rootProject.layout.projectDirectory.dir(".gradle/protoc")) + + @get:OutputFile + val protocOutput: RegularFileProperty = project.objects.fileProperty() + .convention { outputDirectory.asFileTree.singleFile } + + @Internal + val protocPluginConfig: Provider = project.provider { + project.extensions.getByType() + } + + @Internal + val protocDependency: Provider = protocPluginConfig.map { + it.dependencyProvider() + } + + init { + super.setGroup("protoc") + } + + + @TaskAction + fun prepare() { + + val protocDep: Configuration = project.configurations.create("protoc") { + isVisible = false + isCanBeConsumed = false + isCanBeResolved = true + isTransitive = false + + defaultDependencies { + add(protocDependency.get()) + } + } + + val resolvedProtocDep = protocDep.resolve() + + require(resolvedProtocDep.singleOrNull() != null) { + "Expected to download a single protoc.exe, but got ${resolvedProtocDep.size}: ${resolvedProtocDep.joinToString()}" + } + + project.sync { + from(resolvedProtocDep) + into(outputDirectory) + } + } +} + +abstract class ProtocGenerationTask : DefaultTask() { + + @TaskAction + fun generate() { + logger.lifecycle("generating protoc...") + } + +} + + +apply() + +configure { +} + diff --git a/modules/factorio-events-data-model/src/main/proto/FactorioServerLogRecord.proto b/modules/factorio-events-data-model/src/main/proto/FactorioServerLogRecord.proto new file mode 100644 index 0000000..4c4f188 --- /dev/null +++ b/modules/factorio-events-data-model/src/main/proto/FactorioServerLogRecord.proto @@ -0,0 +1,94 @@ +syntax = "proto3"; + +option optimize_for = LITE_RUNTIME; +option java_multiple_files = true; + +package dev.adamko.factorioevents; + +import "google/protobuf/any.proto"; +import "google/protobuf/timestamp.proto"; + +message FactorioServerLogRecord { + string mod_version = 1; + uint32 tick = 2; + string event_type = 3; + FactorioLuaObject data = 4; + +} + +message FactorioLuaObject { + string object_name = 1; + oneof data { + LuaControl lua_control = 2; + } +} + +// https://lua-api.factorio.com/next/LuaControl.html +message LuaControl { + bool is_player = 2; + uint32 surface_index = 3; + Position position = 4; + uint32 force_index = 5; + + oneof subtype { + LuaPlayer player = 10; + LuaEntity entity = 11; + } +} + +// https://lua-api.factorio.com/next/LuaPlayer.html +message LuaPlayer { + uint32 index = 1; // unique ID + string name = 2; + repeated int32 data = 4 [packed = true]; + + Colour colour = 8; + + bool is_connected = 10; + bool is_admin = 11; + + uint32 afk_time_ticks = 100; + uint32 online_time_ticks = 101; + uint32 last_online_ticks = 102; +} + +// https://lua-api.factorio.com/next/LuaEntity.html +message LuaEntity { + uint32 unit_number = 1; // (optional) unique ID + string name = 2; + string type = 3; + string status = 4; // https://lua-api.factorio.com/next/defines.html#defines.entity_status + + bool is_active = 8; + bool is_moving = 9; + + uint32 player_index = 50; // (optional) The player connected to this character or nil if none. + uint32 last_user_index = 51; // (optional) The last player that changed any setting on this entity. + + Colour colour = 100; // (optional) +} + +message LuaSurface { + uint32 index = 1; // unique ID + string name = 2; + float daytime = 3; +} + +message LuaForce { + uint32 index = 1; // unique ID + string force_name = 2; + + repeated uint32 player_ids = 100 [packed = true]; +} + +message Position { + int32 x = 1; + int32 y = 2; +} + +message Colour { + float red = 1; + float green = 2; + float blue = 3; + float alpha = 4; +} diff --git a/modules/factorio-events-data-model2/build.gradle.kts b/modules/factorio-events-data-model2/build.gradle.kts new file mode 100644 index 0000000..11e86a4 --- /dev/null +++ b/modules/factorio-events-data-model2/build.gradle.kts @@ -0,0 +1,95 @@ +//import com.google.protobuf.gradle.builtins +//import com.google.protobuf.gradle.generateProtoTasks +//import com.google.protobuf.gradle.ofSourceSet +//import com.google.protobuf.gradle.plugins +//import com.google.protobuf.gradle.protobuf +//import com.google.protobuf.gradle.protoc + + +plugins { + id("dev.adamko.factoriowebmap.archetype.base") +// id("dev-adamko.pb-and-g") +// kotlin("multiplatform") + +// id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") +// java +// kotlin("js") + +// id("com.google.protobuf") version "0.8.17" + +} + +val projectId: String by project.extra +val buildDir: Directory = layout.buildDirectory.dir(projectId).get() +//val nodeModulesDir: Directory by project.extra + +val protobufVersion = "3.19.0" + +//kotlin { +//// js { +//// // To build distributions for and run tests on browser or Node.js use one or both of: +////// browser() +//// nodejs() +//// } +//} + + +dependencies { +// implementation(platform("com.google.protobuf:protobuf-bom:$protobufVersion")) +// +// implementation("com.google.protobuf:protobuf-java:$protobufVersion") +// implementation("com.google.protobuf:protobuf-javalite:$protobufVersion") +// implementation("com.google.protobuf:protobuf-kotlin-lite:$protobufVersion") +// implementation("com.google.protobuf:protobuf-kotlin:$protobufVersion") +// implementation("com.google.protobuf:protoc:$protobufVersion") +// +// implementation(platform("io.grpc:grpc-bom:1.41.0")) +// implementation("io.grpc:grpc-stub:1.41.0") +// implementation("io.grpc:grpc-protobuf:1.41.0") +// +// implementation("io.grpc:grpc-kotlin-stub:1.2.0") +// implementation("io.grpc:protoc-gen-grpc-kotlin:1.2.0") +// +// implementation("javax.annotation:javax.annotation-api:1.3.2") +// + +// implementation(npm("protoc-gen-ts", "0.15.0")) + +} + + +//protobuf { +// protoc { +// // The artifact spec for the Protobuf Compiler +// artifact = "com.google.protobuf:protoc:3.9.2" +// } +// +// plugins { +// +// this.id("ts") { +// +// } +// } +// +// this.plugins { +//// this.named("ts") { +//// +//// } +// } +// +// generateProtoTasks { +// ofSourceSet("main").forEach { task -> +// task.builtins { +// getByName("java") { +// option("lite") +// } +//// getByName("kotlin") { +//// option("lite") +//// } +//// getByName("ts") { +//// option("lite") +//// } +// } +// } +// } +//} diff --git a/modules/factorio-events-data-model2/src/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt b/modules/factorio-events-data-model2/src/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt new file mode 100644 index 0000000..058d02d --- /dev/null +++ b/modules/factorio-events-data-model2/src/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt @@ -0,0 +1,63 @@ +package dev.adamko.factorioevents.model + +import kotlin.js.JsExport +import kotlin.jvm.JvmInline + +//expect sealed interface JsonPrimitive { +// value class JsonString(val string: String) : JsonPrimitive +// value class JsonNumber(val number: Number) : JsonPrimitive +// value class JsonBoolean(val boolean: Boolean) : JsonPrimitive +//} + +sealed interface JsonPrimitive { + @JvmInline + value class JsonString(val string: String) : JsonPrimitive + @JvmInline + value class JsonNumber(val number: Number) : JsonPrimitive + @JvmInline + value class JsonBoolean(val boolean: Boolean) : JsonPrimitive +} + +class JsonArray( + private val list: MutableList = mutableListOf() +) : MutableList by list + + +sealed interface JsonTableValue { + @JvmInline + value class JsonPrimitiveTV(val primitive: JsonPrimitive) : JsonTableValue + @JvmInline + value class JsonArrayTV(val array: JsonArray) : JsonTableValue + @JvmInline + value class JsonTableTV(val array: JsonTable) : JsonTableValue +} + +//expect class JsonNumber() : JsonPrimitiveType + +//expect class JsonArray + +//expect open class JsonTable + +open class JsonTable( + protected val map: MutableMap = mutableMapOf() +) : MutableMap by map { + + inline fun get2(key: String): T? { + + val jKey = JsonPrimitive.JsonString(key) + + return when { + T::class is Number -> ((get(jKey) as? JsonTableValue.JsonPrimitiveTV)?.primitive as? JsonPrimitive.JsonNumber)?.number as? T + else -> return get(jKey) as? T + } + + } + +} + +//@JsExport +class FactorioEvent : JsonTable() { + val tick: UInt? + get() = get2("tick") +// set(value) = map.put("tick", value) +} \ No newline at end of file diff --git a/modules/factorio-events-data-model2/src/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt b/modules/factorio-events-data-model2/src/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt new file mode 100644 index 0000000..06519b0 --- /dev/null +++ b/modules/factorio-events-data-model2/src/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt @@ -0,0 +1,31 @@ +package dev.adamko.factorioevents.model + + +//actual sealed interface JsonPrimitive { +// actual value class JsonString(val string: String) : JsonPrimitive +// actual value class JsonNumber(val number: Number) : JsonPrimitive +// actual value class JsonBoolean(val boolean: Boolean) : JsonPrimitive +//} + +//actual class JsonArray( +// private val list: MutableList = mutableListOf() +//) : MutableList by list + +//actual sealed interface JsonTableValue { +// actual value class JsonPrimitiveTV(val primitive: JsonPrimitive) : JsonTableValue +// actual value class JsonArrayTV(val array: JsonArray) : JsonTableValue +//} + + +//actual open class JsonTable( +// private val map: MutableMap = mutableMapOf() +//) : MutableMap by map + + +fun printMap() { + val f = JsonPrimitive.JsonString("test") + + println(f.string) + println(f) + +} diff --git a/modules/factorio-events-data-model2/src/main/kotlin/PlayerModel.kt b/modules/factorio-events-data-model2/src/main/kotlin/PlayerModel.kt new file mode 100644 index 0000000..a745430 --- /dev/null +++ b/modules/factorio-events-data-model2/src/main/kotlin/PlayerModel.kt @@ -0,0 +1,55 @@ +interface Identifiable { + val id: T +} + + +interface IndexedModel { + val index: UInt +} + +interface NamedModel { + val name: String +} + + +data class SurfaceModel( + override val name: String, + override val index: UInt, + val daytime: Float, + val darkness: Float, + val wind_speed: Double, +) : IndexedModel, NamedModel + + +/** Player/Entity shared props */ +interface ControlModel { + val driving: Boolean + val forces: List +} + + +//data class PlayerModel( +// val index: UInt, +// val characters: List +//) : Identifiable { +// override val id: UInt = index +//} + +//data class EntityModel( +// val unit_number: Int, +// override val name: String, +// val type: String, +// val active: Boolean, +// val minable: Boolean, +// val health: Boolean, +// val speed: Float, override val driving: Boolean, +//) : ControlModel, NamedModel + + +data class ForceModel( + val index: UInt, + override val name: String, + val research_progress: Double, +) : Identifiable, NamedModel { + override val id: UInt = index +} diff --git a/modules/factorio-events-data-model2/src/main/proto/FactorioServerLogRecord.proto b/modules/factorio-events-data-model2/src/main/proto/FactorioServerLogRecord.proto new file mode 100644 index 0000000..4c4f188 --- /dev/null +++ b/modules/factorio-events-data-model2/src/main/proto/FactorioServerLogRecord.proto @@ -0,0 +1,94 @@ +syntax = "proto3"; + +option optimize_for = LITE_RUNTIME; +option java_multiple_files = true; + +package dev.adamko.factorioevents; + +import "google/protobuf/any.proto"; +import "google/protobuf/timestamp.proto"; + +message FactorioServerLogRecord { + string mod_version = 1; + uint32 tick = 2; + string event_type = 3; + FactorioLuaObject data = 4; + +} + +message FactorioLuaObject { + string object_name = 1; + oneof data { + LuaControl lua_control = 2; + } +} + +// https://lua-api.factorio.com/next/LuaControl.html +message LuaControl { + bool is_player = 2; + uint32 surface_index = 3; + Position position = 4; + uint32 force_index = 5; + + oneof subtype { + LuaPlayer player = 10; + LuaEntity entity = 11; + } +} + +// https://lua-api.factorio.com/next/LuaPlayer.html +message LuaPlayer { + uint32 index = 1; // unique ID + string name = 2; + repeated int32 data = 4 [packed = true]; + + Colour colour = 8; + + bool is_connected = 10; + bool is_admin = 11; + + uint32 afk_time_ticks = 100; + uint32 online_time_ticks = 101; + uint32 last_online_ticks = 102; +} + +// https://lua-api.factorio.com/next/LuaEntity.html +message LuaEntity { + uint32 unit_number = 1; // (optional) unique ID + string name = 2; + string type = 3; + string status = 4; // https://lua-api.factorio.com/next/defines.html#defines.entity_status + + bool is_active = 8; + bool is_moving = 9; + + uint32 player_index = 50; // (optional) The player connected to this character or nil if none. + uint32 last_user_index = 51; // (optional) The last player that changed any setting on this entity. + + Colour colour = 100; // (optional) +} + +message LuaSurface { + uint32 index = 1; // unique ID + string name = 2; + float daytime = 3; +} + +message LuaForce { + uint32 index = 1; // unique ID + string force_name = 2; + + repeated uint32 player_ids = 100 [packed = true]; +} + +message Position { + int32 x = 1; + int32 y = 2; +} + +message Colour { + float red = 1; + float green = 2; + float blue = 3; + float alpha = 4; +} diff --git a/modules/protoc-gradle-plugin/build.gradle.kts b/modules/protoc-gradle-plugin/build.gradle.kts new file mode 100644 index 0000000..ab9eb2b --- /dev/null +++ b/modules/protoc-gradle-plugin/build.gradle.kts @@ -0,0 +1,159 @@ +import org.gradle.nativeplatform.platform.internal.ArchitectureInternal +import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform + +plugins { + kotlin("jvm") version "1.5.31" + `kotlin-dsl` + `java-gradle-plugin` +} + +gradlePlugin { + plugins { + create("Protobuf & Gradle") { + id = "dev-adamko.pb-and-g" + implementationClass = "dev.adamko.gradle.pbandg.ProtocPluginKt" + description = + "Protobuf & Gradle. Wrapper for protoc to generate code from Proto Buffer files." + } + } +} + + +val protocConfiguration: Configuration by configurations.creating { + // A configuration meant for consumers that need the implementation of this component + isCanBeResolved = true + isCanBeConsumed = false +} + +val protobufVersion = "3.19.0" +val protocVersion = "3.9.2" + +dependencies { + implementation(platform("com.google.protobuf:protobuf-bom:$protobufVersion")) + + implementation("com.google.protobuf:protobuf-java:$protobufVersion") + implementation("com.google.protobuf:protobuf-javalite:$protobufVersion") + implementation("com.google.protobuf:protobuf-kotlin-lite:$protobufVersion") + implementation("com.google.protobuf:protobuf-kotlin:$protobufVersion") + implementation("com.google.protobuf:protoc:$protobufVersion") + + implementation(platform("io.grpc:grpc-bom:1.41.0")) + implementation("io.grpc:grpc-stub:1.41.0") + implementation("io.grpc:grpc-protobuf:1.41.0") + + implementation("io.grpc:grpc-kotlin-stub:1.2.0") + implementation("io.grpc:protoc-gen-grpc-kotlin:1.2.0") + + implementation("javax.annotation:javax.annotation-api:1.3.2") +// + +// implementation(npm("protoc-gen-ts", "0.15.0")) + + implementation( + group = "com.google.protobuf", + name = "protoc", + version = "3.9.2", +// configuration = "", + classifier = "windows-x86_64", + ext = "exe", + ) + + protocConfiguration( + group = "com.google.protobuf", + name = "protoc", + version = protocVersion, +// configuration = "", + classifier = "windows-x86_64", + ext = "exe", + ) + +// protocConfiguration("com.google.protobuf:protoc:3.9.2@exe") + + +} + + + +// https://github.com/protocolbuffers/protobuf/tree/master/protoc-artifacts +// The name of a published protoc artifact is in the format: +// protoc---.exe +// e.g., protoc-3.6.1-linux-x86_64.exe +// Note that artifacts for Linux/macOS also have the .exe suffix, but they are not windows binaries. +val os: OperatingSystem = DefaultNativePlatform.getCurrentOperatingSystem() +val arch: ArchitectureInternal = DefaultNativePlatform.getCurrentArchitecture() + +repositories { + mavenCentral() + +// ivy { +// url = project.repositories.mavenCentral().url +// +// patternLayout { +// +// // com/google/protobuf/protoc/3.9.2/protoc-3.9.2-linux-aarch_64.exe +// artifact("[organisation]/[module]/[revision]/[artifact]-[revision]-${os.name}-${arch.name}.[ext]") +// +//// artifact("3rd-party-artifacts/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]") +//// artifact("company-artifacts/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]") +//// ivy("ivy-files/[organisation]/[module]/[revision]/ivy.xml") +//// artifact("[organisation]/[module]/[revision]/[artifact]-[revision].[ext]") +// setM2compatible(true) +// metadataSources { +// artifact() +// } +// } +// } + +} + +tasks.register("protocExecCopy") { + group = project.name + +// from(protocConfiguration.artifacts) + + from(protocConfiguration.resolve()) + + into(project.layout.buildDirectory.dir("protocCopy")) +} + +//tasks.register("dlPc") { +// group = project.name +// +// val downloadDir = this.temporaryDir +// +// outputs.dir(downloadDir) +// +// doLast { +// +//// downloadDir.mkdirs() +// +// val protocArtifactFileExt = "exe" +// +// val osFamilyName = DefaultNativePlatform.host().operatingSystem.toFamilyName() +// +// val arch: String = +// DefaultNativePlatform.getCurrentArchitecture() +// .name +// .replace("-", "_") +// +// val artifact = "protoc-$protocVersion-${osFamilyName}-${arch}.$protocArtifactFileExt" +// +// val uri = uri( +// ArtifactRepositoryContainer.MAVEN_CENTRAL_URL +// + "com/google/protobuf/protoc/$protocVersion/$artifact" +// ) +// // actual: +// // https://repo.maven.apache.org/maven2/com/google/protobuf/protoc/3.9.2/protoc-3.9.2-windows-x86_64.exe +// // https://repo.maven.apache.org/maven2/com/google/protobuf/protoc/3.9.2/protoc-3.9.2-windows-x86-64.exe +// +// ant.invokeMethod( +// "get", mapOf( +// "src" to uri, +// "dest" to downloadDir.canonicalPath, +// "verbose" to true, +// ) +// ) +// } +// +//} +// diff --git a/modules/protoc-gradle-plugin/src/main/kotlin/dev/adamko/gradle/pbandg/ProtocPlugin.kt b/modules/protoc-gradle-plugin/src/main/kotlin/dev/adamko/gradle/pbandg/ProtocPlugin.kt new file mode 100644 index 0000000..a7c882f --- /dev/null +++ b/modules/protoc-gradle-plugin/src/main/kotlin/dev/adamko/gradle/pbandg/ProtocPlugin.kt @@ -0,0 +1,148 @@ +package dev.adamko.gradle.pbandg + +import org.gradle.api.DefaultTask +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.artifacts.ExternalDependency +import org.gradle.api.plugins.ExtensionAware +import org.gradle.api.provider.Property +import org.gradle.api.tasks.TaskAction +import org.gradle.kotlin.dsl.domainObjectContainer +import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.withType +import org.gradle.kotlin.dsl.property +import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform + + +class ProtocPlugin : Plugin { + + override fun apply(project: Project) { + + val protocConfig = + project.extensions.create("protocConfig", ProtocConfigExtension::class.java) + + val protocDeps = project.configurations.create("pbAndG") { + isVisible = false + isCanBeConsumed = false + isCanBeResolved = true + description = "protoc dependencies" + + defaultDependencies { +// deps += project.dependencies.create("com.google.protobuf:protoc:3.19.0") + add(protocConfig.dependencyProvider()) + } + } + + val generatorsContainer = + project.objects.domainObjectContainer(ProtocGenerationTask::class.java) + protocConfig.extensions.add("generate", generatorsContainer) + + + project.extensions.add("asd", project.provider { + DefaultNativePlatform.getCurrentOperatingSystem().toFamilyName() + }) + + project.tasks.withType { +// .getDataFiles()?.from(protocDeps) + } + +// project.getPlugins().withType(org.gradle.api.plugins.JavaPlugin::class) { javaPlugin -> +// val sourceSets: SourceSetContainer = +// project.getExtensions().getByType(SourceSetContainer::class.java) +// val main: SourceSet = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME) +// main.getJava().setSrcDirs(Arrays.asList("src")) +// } + + } + +} + + +abstract class ProtocConfigExtension(private val project: Project) : ExtensionAware { + + val protocVersion: Property = + project.objects.property(String::class).convention("3.9.2") + + val protocGroup: Property = + project.objects.property(String::class).convention("com.google.protobuf") + + val protocArtifactName: Property = + project.objects.property(String::class).convention("protoc") + + val protocArtifactExtension: Property = + project.objects.property(String::class).convention("exe") + + var osFamilyNameProvider: () -> String = { + DefaultNativePlatform.getCurrentOperatingSystem().toFamilyName() + } + + var architectureProviderMapper: (String) -> String = { + it.replace("-", "_") + } + + var architectureProvider: () -> String = { + DefaultNativePlatform.getCurrentArchitecture() + .name + .let(architectureProviderMapper) + } + + var classifierProvider: () -> String = { + "${osFamilyNameProvider()}-${architectureProvider()}" + } + + var dependencyProvider: () -> ExternalDependency = { + project.dependencies.create( + group = protocGroup.get(), + name = protocArtifactName.get(), + version = protocVersion.get(), + classifier = classifierProvider(), + ext = protocArtifactExtension.get(), + ) + } + + val generators = project.objects.domainObjectContainer(ProtocGenerationConfig::class) + + +} + +abstract class ProtocGenerationConfig + +abstract class ProtocGenerationTask : DefaultTask() { + + @TaskAction + fun generate() { + logger.lifecycle("generating protoc...") + } + +} + + +//class ProtocDownloadExe : DefaultTask() { +// +////@Input +//val protocVersion = "3.9.2" +//val protocArtifactFileExt = "exe" +// +// +// @TaskAction +// fun download() { +// +// val baseUri = project.repositories.mavenCentral().url +// +// val os: OperatingSystem = DefaultNativePlatform.getCurrentOperatingSystem() +// val arch: ArchitectureInternal = DefaultNativePlatform.getCurrentArchitecture() +// +// val artifact = "protoc-$protocVersion-${os.name}-${arch.name}.$protocArtifactFileExt" +// +// ant.invokeMethod( +// "get", mapOf( +// "src" to baseUri.resolve("/com/google/protobuf/protoc/3.9.2/protoc-3.9.2-linux-aarch_64.exe"), +// "dest" to project.layout.buildDirectory.dir("protoc-artifact"), +// "verbose" to true, +// ) +// ) +// +// +// } +// +//} diff --git a/modules/server/build.gradle.kts b/modules/server/build.gradle.kts index 2677c7f..f5bde61 100644 --- a/modules/server/build.gradle.kts +++ b/modules/server/build.gradle.kts @@ -3,7 +3,7 @@ import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig plugins { id("dev.adamko.factoriowebmap.archetype.base") // kotlin("jvm") - id("io.kvision") version "5.4.1" + id("io.kvision") version "5.4.1" kotlin("js") kotlin("plugin.serialization") } @@ -24,13 +24,13 @@ kotlin { outputFileName = "main.bundle.js" sourceMaps = false devServer = KotlinWebpackConfig.DevServer( - open = false, - port = 3000, - proxy = mutableMapOf( - "/kv/*" to "http://localhost:8080", - "/kvws/*" to mapOf("target" to "ws://localhost:8080", "ws" to true) - ), - static = mutableListOf("$buildDir/processedResources/js/main") + open = false, + port = 3000, + proxy = mutableMapOf( + "/kv/*" to "http://localhost:8080", + "/kvws/*" to mapOf("target" to "ws://localhost:8080", "ws" to true) + ), + static = mutableListOf("$buildDir/processedResources/js/main") ) } webpackTask { diff --git a/settings.gradle.kts b/settings.gradle.kts index c15467c..ea5f799 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,13 +1,17 @@ rootProject.name = "factorio-web-map" + +includeBuild("modules/protoc-gradle-plugin") + include( - ":modules:mod", + ":modules:mod", // ":modules:mod2", - ":modules:server", - ":modules:kt-rcon", - ":modules:factorio-events-data-model", - ":modules:factorio-events-processor", - ":modules:factorio-events-kafka-pipe", + ":modules:server", + ":modules:kt-rcon", + ":modules:factorio-events-data-model", +// ":modules:factorio-events-data-model2", + ":modules:factorio-events-processor", + ":modules:factorio-events-kafka-pipe", ) From 4ca40afa090660cc701d2e18cd8d968e0fd53e7c Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 29 Oct 2021 19:15:15 +0200 Subject: [PATCH 055/629] streams processor work. Stuck because of schema clashes. I want to get protoc working but it's a massive PIA. --- .../processor/StreamsExceptionHandler.kt | 2 +- .../adamko/factorioevents/processor/main.kt | 13 ++-- .../src/main/resources/logback.xml | 21 ++++++ .../model/FactorioServerLogRecordTest.kt | 68 +++++++++++++++++++ 4 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 modules/factorio-events-processor/src/main/resources/logback.xml create mode 100644 modules/factorio-events-processor/src/test/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecordTest.kt diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt index bf05679..107e6e5 100644 --- a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt +++ b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt @@ -6,6 +6,6 @@ import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler.StreamThr class StreamsExceptionHandler : StreamsUncaughtExceptionHandler { override fun handle(exception: Throwable): StreamThreadExceptionResponse { println("${exception.message} - ${exception.stackTrace}") - return StreamThreadExceptionResponse.REPLACE_THREAD + return StreamThreadExceptionResponse.SHUTDOWN_APPLICATION } } diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt index 3336a95..4932637 100644 --- a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt +++ b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt @@ -2,15 +2,12 @@ package dev.adamko.factorioevents.processor import dev.adamko.factorioevents.processor.config.ApplicationProperties import dev.adamko.factorioevents.processor.model.FactorioServerLogRecord -import dev.adamko.factorioevents.processor.model.LuaSurfaceData import java.time.Duration import org.apache.kafka.common.serialization.Serdes import org.apache.kafka.streams.KafkaStreams -import org.apache.kafka.streams.KeyValue import org.apache.kafka.streams.StreamsBuilder -import org.apache.kafka.streams.kstream.Branched +import org.apache.kafka.streams.TopologyDescription import org.apache.kafka.streams.kstream.Consumed -import org.apache.kafka.streams.kstream.Named import org.apache.kafka.streams.processor.TopicNameExtractor import org.http4k.format.Jackson @@ -20,7 +17,6 @@ fun main() { val builder = StreamsBuilder() - builder.stream( "factorio-server-log", Consumed.with(Serdes.String(), Serdes.String()) @@ -40,7 +36,12 @@ fun main() { streams.setUncaughtExceptionHandler(StreamsExceptionHandler()) - Runtime.getRuntime().addShutdownHook(Thread { streams.close(Duration.ofSeconds(10)) }) + Runtime.getRuntime().addShutdownHook(Thread { streams.close(Duration.ofSeconds(1)) }) + +// streams.cleanUp() + + val description: TopologyDescription = topology.describe() + println(description) streams.start() diff --git a/modules/factorio-events-processor/src/main/resources/logback.xml b/modules/factorio-events-processor/src/main/resources/logback.xml new file mode 100644 index 0000000..658a6ae --- /dev/null +++ b/modules/factorio-events-processor/src/main/resources/logback.xml @@ -0,0 +1,21 @@ + + + + true + + + %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/factorio-events-processor/src/test/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecordTest.kt b/modules/factorio-events-processor/src/test/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecordTest.kt new file mode 100644 index 0000000..d672635 --- /dev/null +++ b/modules/factorio-events-processor/src/test/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecordTest.kt @@ -0,0 +1,68 @@ +package dev.adamko.factorioevents.processor.model + +import io.kotest.assertions.json.shouldEqualJson +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.shouldBe +import io.kotest.matchers.shouldNotBe +import org.http4k.format.Jackson +import org.intellij.lang.annotations.Language + +class FactorioServerLogRecordTest : FunSpec({ + + test("player obj") { + @Language("JSON") + val example = """ + { + "mod_version":"0.0.3", + "tick":1256529, + "event_type":"on_player_joined_game", + "data":{ + "object_name":"LuaPlayer", + "name":"fredthedeadhead", + "character_unit_number":1, + "associated_characters_unit_numbers":{ + + }, + "position":{ + "x":3.48828125, + "y":23.43359375 + } + } + } + """.trimIndent() + val record: FactorioServerLogRecord<*> = Jackson.asA(example) + + record shouldBe null + } + + test("surface obj") { + @Language("JSON") + val example = """ + { + "mod_version":"0.0.3", + "tick":1256529, + "event_type":"on_player_joined_game", + "data":{ + "object_name":"LuaEntity", + "name":"character", + "type":"character", + "active":true, + "health":250, + "surface_index":1, + "unit_number":1, + "position":{ + "x":3.48828125, + "y":23.43359375 + } + } + } + """.trimIndent() + val record: FactorioServerLogRecord = Jackson.asA(example) + + record shouldNotBe null + + val str = Jackson.asFormatString(record) + str.shouldEqualJson(example) + } + +}) From 5cdc9e8dc72720db4f2e86b3e4e434e3640bf82e Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 30 Oct 2021 07:26:03 +0200 Subject: [PATCH 056/629] trying json polymorphism stuff... --- .../processor/model/FactorioServerLogRecord.kt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecord.kt b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecord.kt index c8a8182..7ec2a35 100644 --- a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecord.kt +++ b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecord.kt @@ -9,8 +9,6 @@ import java.math.BigInteger import kotlin.reflect.KClass - - data class FactorioServerLogRecord( @JsonProperty("mod_version") val modVersion: String, @@ -22,12 +20,11 @@ data class FactorioServerLogRecord( val data: DataType, ) - @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, - include = JsonTypeInfo.As.PROPERTY, + include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "object_name", - defaultImpl = Void::class, // equivalent to null + defaultImpl = UnknownFactorioObject::class, visible = true, ) sealed class FactorioObjectData( @@ -35,6 +32,8 @@ sealed class FactorioObjectData( val objectName: String ) +object UnknownFactorioObject : FactorioObjectData("unknown") + @JsonTypeName("LuaSurface") class LuaSurfaceData( @JsonProperty("name") From cbda9281417aa7e57d366b278f7e96b8c41ac084 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 30 Oct 2021 07:26:12 +0200 Subject: [PATCH 057/629] protoc download - working! --- .../build.gradle.kts | 187 ++++++++++-------- 1 file changed, 105 insertions(+), 82 deletions(-) diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index 6acd8ce..fcd58ea 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -1,15 +1,14 @@ +import java.util.function.Supplier import org.gradle.api.DefaultTask import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.artifacts.ExternalDependency -import org.gradle.api.plugins.ExtensionAware import org.gradle.api.provider.Property import org.gradle.api.tasks.TaskAction -import org.gradle.kotlin.dsl.domainObjectContainer import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.withType import org.gradle.kotlin.dsl.property import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform +import org.gradle.nativeplatform.platform.internal.DefaultOperatingSystem +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { id("dev.adamko.factoriowebmap.archetype.base") @@ -19,6 +18,7 @@ plugins { val projectId: String by project.extra val buildDir: Directory = layout.buildDirectory.dir(projectId).get() + dependencies { } @@ -41,65 +41,59 @@ class ProtocPlugin : Plugin { // } // } - project.tasks.register("protocPrepare") { +// project.dependencies.createArtifactResolutionQuery().forComponents() - } + val protocPrepare = project.tasks.register("protocPrepare") +// project.tasks.register("protobufCompile") { // -// val prepareTask = project.tasks.register("protocPrepare") { // group = "protoc" +// dependsOn(protocPrepare) // -// val outputDir = project.rootProject.layout.projectDirectory.dir(".gradle/protoc") +// workingDir(temporaryDir) // -// outputs.dir(outputDir) // -//// doLast { -// val protoc: File = protocDep.resolve().single() -// logger.lifecycle("protoc file $protoc") -// -// from(protoc) -// into(outputDir) -//// } -// } -// -// project.tasks.build { dependsOn(prepareTask) } -// -// val generateTask = project.tasks.create("protocGenerate") { -// dependsOn(prepareTask) -// } - -// val protocDeps = project.configurations.create("pbAndG") { -// this.let { config -> -// -// config.isVisible = false -// config.isCanBeConsumed = false -// config.isCanBeResolved = true -// config.description = "protoc dependencies" -// -// config.defaultDependencies { -// add(protocConfig.dependencyProvider()) -// } +// if (protocConfig.operatingSystemProvider.get().get().isWindows) { +// args("cmd", "/c") // } // -// val generatorsContainer = -// project.objects.domainObjectContainer(ProtocGenerationTask::class) -// protocConfig.extensions.add("protocGenerate", generatorsContainer) +// val srcDir = project.layout.projectDirectory.dir("src") +// val javaOut = project.layout.buildDirectory.dir("proto/java") +// val kotlinOut = project.layout.buildDirectory.dir("proto/kotlin") +// val protoFile = +// project.layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto") // +// args( +// parseSpaceSeparatedArgs( +// """ +// -I=${srcDir.asFile.canonicalPath} +// --java_out=${javaOut.get().asFile.canonicalPath} +// --kotlin_out=${kotlinOut.get().asFile.canonicalPath} +// ${protoFile.asFile.canonicalPath} // -// project.extensions.add("testingExtensionThingy", project.provider { -// DefaultNativePlatform.getCurrentOperatingSystem().toFamilyName() -// }) -// -// project.tasks.withType { +// """.trimIndent() +//// """ +//// -I=$SRC_DIR +//// --java_out=$DST_DIR +//// --kotlin_out=$DST_DIR +//// $SRC_DIR/addressbook.proto" +//// +//// """.trimIndent() +// ) +// ) +// doLast { +// executable = protocPrepare.flatMap { it.protocOutput }.get().asFile.canonicalPath // } -// // } -// } } abstract class ProtocPluginConfig(private val project: Project) : java.io.Serializable { + val protocWorkingDir: DirectoryProperty = + project.objects.directoryProperty() + .convention(project.rootProject.layout.projectDirectory.dir(".gradle/protoc")) + val protocVersion: Property = project.objects.property(String::class).convention("3.9.2") @@ -112,6 +106,10 @@ abstract class ProtocPluginConfig(private val project: Project) : java.io.Serial val protocArtifactExtension: Property = project.objects.property(String::class).convention("exe") + val operatingSystemProvider: Property> = + project.objects.property>() + .convention { DefaultNativePlatform.getCurrentOperatingSystem() } + /** * Should return one of * @@ -119,9 +117,13 @@ abstract class ProtocPluginConfig(private val project: Project) : java.io.Serial * * `osx` * * `windows` */ - var osFamilyNameProvider: () -> String = { - DefaultNativePlatform.getCurrentOperatingSystem().toFamilyName() - } + val operatingSystemName: Property = + project.objects + .property() + .convention(operatingSystemProvider.map { it.get().toFamilyName() }) + + private val architectureProvider: Provider = + project.provider { DefaultNativePlatform.getCurrentArchitecture() } /** * Should return one of @@ -131,11 +133,13 @@ abstract class ProtocPluginConfig(private val project: Project) : java.io.Serial * * `x86_32` * * `x86_64` */ - var architectureProvider: () -> String = { - DefaultNativePlatform.getCurrentArchitecture() - .name - .replace("-", "_") - } + val architectureName: Property = + project.objects + .property() + .convention(architectureProvider.map { it.name.replace("-", "_") }) + + private val classifierProvider: Provider = + project.provider { "${operatingSystemName.get()}-${architectureName.get()}" } /** * Default: concatenate [osFamilyNameProvider] and [architectureProvider] @@ -149,49 +153,63 @@ abstract class ProtocPluginConfig(private val project: Project) : java.io.Serial * * `osx-x86_64` * * `windows-x86_32` */ - var classifierProvider: () -> String = { - "${osFamilyNameProvider()}-${architectureProvider()}" - } + val classifier: Property = + project.objects + .property() + .convention(classifierProvider) - var dependencyProvider: () -> ExternalModuleDependency = { - project.dependencies.create( - group = protocGroup.get(), - name = protocArtifactName.get(), - version = protocVersion.get(), - classifier = classifierProvider(), - ext = protocArtifactExtension.get(), - ) - } -// val generators = project.objects.domainObjectContainer(ProtocGenerationConfig::class) + private val dependencyProvider: Provider = + project.provider { + project.dependencies.create( + group = protocGroup.get(), + name = protocArtifactName.get(), + version = protocVersion.get(), + classifier = classifierProvider.get(), + ext = protocArtifactExtension.get(), + ) + } + + val dependency: Property = + project.objects + .property() + .convention(dependencyProvider) + } abstract class ProtocGenerationConfig abstract class ProtocPrepareTask : DefaultTask() { - @get:OutputDirectory - val outputDirectory: DirectoryProperty = project.objects.directoryProperty() - .convention(project.rootProject.layout.projectDirectory.dir(".gradle/protoc")) - - @get:OutputFile - val protocOutput: RegularFileProperty = project.objects.fileProperty() - .convention { outputDirectory.asFileTree.singleFile } - @Internal val protocPluginConfig: Provider = project.provider { project.extensions.getByType() } + @get:OutputDirectory + val outputDirectory: DirectoryProperty = project.objects.directoryProperty() + .convention(protocPluginConfig.flatMap { it.protocWorkingDir }) + @Internal - val protocDependency: Provider = protocPluginConfig.map { - it.dependencyProvider() - } + val protocOutput: RegularFileProperty = project.objects.fileProperty() +// @get:OutputFile +// val protocOutput: RegularFileProperty = project.objects.fileProperty() +// .convention { outputDirectory.asFileTree.singleFile } +// .convention(outputDirectory.map { project it.asFileTree.singleFile }) + + @Internal + val protocDependency: Provider = + protocPluginConfig.flatMap { it.dependency } init { super.setGroup("protoc") - } +// project.dependencies { +// protocDep(protocDependency.get()) +// } +// +// super.dependsOn(protocDep) + } @TaskAction fun prepare() { @@ -207,15 +225,20 @@ abstract class ProtocPrepareTask : DefaultTask() { } } - val resolvedProtocDep = protocDep.resolve() + logger.lifecycle("Downloading protoc") + val resolvedProtocDep = protocDep.singleFile + logger.lifecycle("Downloaded $resolvedProtocDep") - require(resolvedProtocDep.singleOrNull() != null) { - "Expected to download a single protoc.exe, but got ${resolvedProtocDep.size}: ${resolvedProtocDep.joinToString()}" - } +// require(resolvedProtocDep.singleOrNull() != null) { +// "Expected to download a single protoc.exe, but got ${resolvedProtocDep.size}: ${resolvedProtocDep.joinToString()}" +// } project.sync { from(resolvedProtocDep) into(outputDirectory) +// doLast { +// logger.lifecycle("Syncing from $resolvedProtocDep to $outputDirectory") +// } } } } From 320bf854db49ec2a59a63ff2dc4044ac9ff68a5a Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 30 Oct 2021 11:29:07 +0200 Subject: [PATCH 058/629] downloading proto libs - working! --- .../build.gradle.kts | 160 ++++++++++-------- 1 file changed, 93 insertions(+), 67 deletions(-) diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index fcd58ea..bfc4af8 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -8,6 +8,7 @@ import org.gradle.kotlin.dsl.create import org.gradle.kotlin.dsl.property import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform import org.gradle.nativeplatform.platform.internal.DefaultOperatingSystem +import org.jetbrains.kotlin.incremental.isJavaFile import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { @@ -23,79 +24,119 @@ dependencies { } -class ProtocPlugin : Plugin { +open class ProtocPlugin : Plugin { override fun apply(project: Project) { val protocConfig = project.extensions.create("protocPluginConfig", ProtocPluginConfig::class, project) -// val protocDep: Configuration = project.configurations.create("protoc") { -// isVisible = false -// isCanBeConsumed = false -// isCanBeResolved = true -// isTransitive = false -// -// defaultDependencies { -// add(protocConfig.dependencyProvider()) -// } -// } + val protobufCompiler: Configuration = project.configurations.create("protobufCompiler") { + isVisible = false + isCanBeConsumed = false + isCanBeResolved = true + isTransitive = false -// project.dependencies.createArtifactResolutionQuery().forComponents() + defaultDependencies { + add(protocConfig.dependency.get()) + } + } - val protocPrepare = project.tasks.register("protocPrepare") + val protobufLibs: Configuration = project.configurations.create("protobufLib") { + isVisible = true + isCanBeConsumed = false + isCanBeResolved = true + isTransitive = false + } + +// val protocPrepare = project.tasks.register("protocPrepare") + + project.dependencies { + protobufLibs("com.google.protobuf:protobuf-javalite:3.19.1") + } + + val libsTask = project.tasks.register("protobufLibs") { + group = "protobuf" + + includeEmptyDirs = false + + dependsOn(protobufLibs) + + val outDir = project.layout.buildDirectory.dir("proto/libs") + + protobufLibs + .map { project.zipTree(it) } + .forEach { + logger.lifecycle("protoc lib - $it") + from(it) { + include("**/*.proto") + } + } + + into(outDir) + } + + + project.tasks.register("protobufCompile") { + group = "protobuf" + dependsOn(protobufCompiler, libsTask) + executable(protobufCompiler.singleFile) + + + val protoLibsDir = project.layout.buildDirectory.dir("proto/libs") + inputs.dir(protoLibsDir) + + standardOutput = System.out + + val outDir = project.layout.buildDirectory.dir("protoc") +// outDir.get().asFile.mkdirs() + workingDir(outDir) -// project.tasks.register("protobufCompile") { -// -// group = "protoc" -// dependsOn(protocPrepare) -// -// workingDir(temporaryDir) -// -// // if (protocConfig.operatingSystemProvider.get().get().isWindows) { // args("cmd", "/c") // } -// -// val srcDir = project.layout.projectDirectory.dir("src") -// val javaOut = project.layout.buildDirectory.dir("proto/java") -// val kotlinOut = project.layout.buildDirectory.dir("proto/kotlin") -// val protoFile = -// project.layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto") -// -// args( -// parseSpaceSeparatedArgs( + + val srcDir = project.layout.projectDirectory.dir("src") + val javaOut = project.layout.buildDirectory.dir("proto/java") + val kotlinOut = project.layout.buildDirectory.dir("proto/kotlin") + val protoFile = + project.layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto") + + + + args( + parseSpaceSeparatedArgs( + """ + -I=${srcDir.asFile.canonicalPath} + --java_out=${javaOut.get().asFile.canonicalPath} + --kotlin_out=${kotlinOut.get().asFile.canonicalPath} + ${protoFile.asFile.canonicalPath} + + """.trimIndent() // """ -// -I=${srcDir.asFile.canonicalPath} -// --java_out=${javaOut.get().asFile.canonicalPath} -// --kotlin_out=${kotlinOut.get().asFile.canonicalPath} -// ${protoFile.asFile.canonicalPath} +// -I=$SRC_DIR +// --java_out=$DST_DIR +// --kotlin_out=$DST_DIR +// $SRC_DIR/addressbook.proto" // // """.trimIndent() -//// """ -//// -I=$SRC_DIR -//// --java_out=$DST_DIR -//// --kotlin_out=$DST_DIR -//// $SRC_DIR/addressbook.proto" -//// -//// """.trimIndent() -// ) -// ) + ) + ) // doLast { // executable = protocPrepare.flatMap { it.protocOutput }.get().asFile.canonicalPath // } -// } + } } } -abstract class ProtocPluginConfig(private val project: Project) : java.io.Serializable { +abstract class ProtocPluginConfig(private val project: Project) : java.io.Serializable { // TODO remove serializable? val protocWorkingDir: DirectoryProperty = project.objects.directoryProperty() .convention(project.rootProject.layout.projectDirectory.dir(".gradle/protoc")) val protocVersion: Property = - project.objects.property(String::class).convention("3.9.2") + project.objects.property(String::class).convention("3.19.1") val protocGroup: Property = project.objects.property(String::class).convention("com.google.protobuf") @@ -177,10 +218,9 @@ abstract class ProtocPluginConfig(private val project: Project) : java.io.Serial } -abstract class ProtocGenerationConfig - abstract class ProtocPrepareTask : DefaultTask() { + @Internal val protocPluginConfig: Provider = project.provider { project.extensions.getByType() @@ -192,27 +232,18 @@ abstract class ProtocPrepareTask : DefaultTask() { @Internal val protocOutput: RegularFileProperty = project.objects.fileProperty() -// @get:OutputFile -// val protocOutput: RegularFileProperty = project.objects.fileProperty() -// .convention { outputDirectory.asFileTree.singleFile } -// .convention(outputDirectory.map { project it.asFileTree.singleFile }) @Internal val protocDependency: Provider = protocPluginConfig.flatMap { it.dependency } init { - super.setGroup("protoc") - -// project.dependencies { -// protocDep(protocDependency.get()) -// } -// -// super.dependsOn(protocDep) + super.setGroup("protobuf") + outputs.dir(outputDirectory) } @TaskAction - fun prepare() { + fun action() { val protocDep: Configuration = project.configurations.create("protoc") { isVisible = false @@ -229,16 +260,11 @@ abstract class ProtocPrepareTask : DefaultTask() { val resolvedProtocDep = protocDep.singleFile logger.lifecycle("Downloaded $resolvedProtocDep") -// require(resolvedProtocDep.singleOrNull() != null) { -// "Expected to download a single protoc.exe, but got ${resolvedProtocDep.size}: ${resolvedProtocDep.joinToString()}" -// } - project.sync { from(resolvedProtocDep) into(outputDirectory) -// doLast { -// logger.lifecycle("Syncing from $resolvedProtocDep to $outputDirectory") -// } + logger.lifecycle("Syncing from $resolvedProtocDep to ${outputDirectory.asFile.get().canonicalPath}") + protocOutput.set(outputDirectory.asFileTree.singleFile) } } } From 465cc2a7c304fb000787782e6d8e05075f24babc Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 30 Oct 2021 11:33:40 +0200 Subject: [PATCH 059/629] kotlin generation working --- modules/factorio-events-data-model/build.gradle.kts | 11 ++++++++--- .../src/main/proto/FactorioServerLogRecord.proto | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index bfc4af8..010baf6 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -102,11 +102,10 @@ open class ProtocPlugin : Plugin { val protoFile = project.layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto") - - args( parseSpaceSeparatedArgs( """ + -I=${protoLibsDir.map { it.asFile.canonicalPath }.get()} -I=${srcDir.asFile.canonicalPath} --java_out=${javaOut.get().asFile.canonicalPath} --kotlin_out=${kotlinOut.get().asFile.canonicalPath} @@ -122,6 +121,11 @@ open class ProtocPlugin : Plugin { // """.trimIndent() ) ) + doFirst { + javaOut.get().asFile.mkdirs() + kotlinOut.get().asFile.mkdirs() + } + // doLast { // executable = protocPrepare.flatMap { it.protocOutput }.get().asFile.canonicalPath // } @@ -129,7 +133,8 @@ open class ProtocPlugin : Plugin { } } -abstract class ProtocPluginConfig(private val project: Project) : java.io.Serializable { // TODO remove serializable? +abstract class ProtocPluginConfig(private val project: Project) : + java.io.Serializable { // TODO remove serializable? val protocWorkingDir: DirectoryProperty = project.objects.directoryProperty() diff --git a/modules/factorio-events-data-model/src/main/proto/FactorioServerLogRecord.proto b/modules/factorio-events-data-model/src/main/proto/FactorioServerLogRecord.proto index 4c4f188..906f31a 100644 --- a/modules/factorio-events-data-model/src/main/proto/FactorioServerLogRecord.proto +++ b/modules/factorio-events-data-model/src/main/proto/FactorioServerLogRecord.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option optimize_for = LITE_RUNTIME; +//option optimize_for = LITE_RUNTIME; option java_multiple_files = true; package dev.adamko.factorioevents; From cb205c558b4d5ceaf257c5718f1b002fe6127133 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 30 Oct 2021 11:54:46 +0200 Subject: [PATCH 060/629] kotlin generation working even better --- .../build.gradle.kts | 59 +++++++++---------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index 010baf6..ab92843 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -82,53 +82,50 @@ open class ProtocPlugin : Plugin { dependsOn(protobufCompiler, libsTask) executable(protobufCompiler.singleFile) - val protoLibsDir = project.layout.buildDirectory.dir("proto/libs") inputs.dir(protoLibsDir) standardOutput = System.out - val outDir = project.layout.buildDirectory.dir("protoc") -// outDir.get().asFile.mkdirs() - workingDir(outDir) + val outDir = project.layout.buildDirectory.dir("protoc/generated-sources") + outputs.dir(outDir) -// if (protocConfig.operatingSystemProvider.get().get().isWindows) { -// args("cmd", "/c") -// } + workingDir(temporaryDirFactory) - val srcDir = project.layout.projectDirectory.dir("src") - val javaOut = project.layout.buildDirectory.dir("proto/java") - val kotlinOut = project.layout.buildDirectory.dir("proto/kotlin") - val protoFile = - project.layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto") + val javaOut = workingDir.resolve("proto/java") + val kotlinOut = workingDir.resolve("proto/kotlin") + val protoFile by project.objects.fileProperty() + .convention(project.layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto")) + val protoFileParent = project.provider { protoFile.asFile.parentFile } + + inputs.file(protoFile) args( parseSpaceSeparatedArgs( """ - -I=${protoLibsDir.map { it.asFile.canonicalPath }.get()} - -I=${srcDir.asFile.canonicalPath} - --java_out=${javaOut.get().asFile.canonicalPath} - --kotlin_out=${kotlinOut.get().asFile.canonicalPath} - ${protoFile.asFile.canonicalPath} - - """.trimIndent() -// """ -// -I=$SRC_DIR -// --java_out=$DST_DIR -// --kotlin_out=$DST_DIR -// $SRC_DIR/addressbook.proto" -// -// """.trimIndent() + --proto_path=${protoFileParent.get()} + --proto_path=${protoLibsDir.get()} + --java_out=$javaOut + --kotlin_out=$kotlinOut + $protoFile + """ ) ) doFirst { - javaOut.get().asFile.mkdirs() - kotlinOut.get().asFile.mkdirs() + project.delete(workingDir) + + project.mkdir(javaOut) + project.mkdir(kotlinOut) + } + + doLast { + project.sync { + from(workingDir) + into(outDir) + } + project.delete(workingDir) } -// doLast { -// executable = protocPrepare.flatMap { it.protocOutput }.get().asFile.canonicalPath -// } } } } From 31ae0c9800b765318d986c0da2e4a60c29eabb15 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 30 Oct 2021 18:35:39 +0200 Subject: [PATCH 061/629] kotlin gen working (again!), and source sets working --- README.md | 2 + build.gradle.kts | 8 + .../factoriowebmap/archetype/base.gradle.kts | 7 + .../archetype/kotlin-js.gradle.kts | 1 + .../build.gradle.kts | 155 +++++++++++++----- 5 files changed, 132 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 6a039de..62bc90c 100644 --- a/README.md +++ b/README.md @@ -27,3 +27,5 @@ to investigate: * https://github.com/cloudhut/kowl * https://opensource.expediagroup.com/graphql-kotlin/docs/server/spring-server/spring-subscriptions * https://github.com/YousefED/typescript-json-schema + +* https://jbrandhorst.com/post/go-protobuf-tips/ \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 182dc1f..b632a30 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,5 @@ plugins { + idea base // val kotlinVersion = "1.5.31" @@ -16,3 +17,10 @@ tasks.wrapper { gradleVersion = "7.2" distributionType = Wrapper.DistributionType.ALL } + +idea { + module { + isDownloadSources = true + isDownloadJavadoc = true + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts index 114b6a7..46b5d8c 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts @@ -1,6 +1,7 @@ package dev.adamko.factoriowebmap.archetype plugins { + idea base } @@ -18,6 +19,12 @@ val tokens: Map by extra( ) ) +idea { + module { + isDownloadSources = true + isDownloadJavadoc = true + } +} //group = "dev.adamko.factoriowebmap" //version = "0.0.1" diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts index 879e2df..6f3e148 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject plugins { kotlin("js") + id("dev.adamko.factoriowebmap.archetype.base") id("dev.adamko.factoriowebmap.archetype.node") } diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index ab92843..4f2aa33 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -4,15 +4,18 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.provider.Property import org.gradle.api.tasks.TaskAction +import org.gradle.kotlin.dsl.provideDelegate +import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.create import org.gradle.kotlin.dsl.property import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform import org.gradle.nativeplatform.platform.internal.DefaultOperatingSystem -import org.jetbrains.kotlin.incremental.isJavaFile +import org.gradle.plugins.ide.idea.model.IdeaModel +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { - id("dev.adamko.factoriowebmap.archetype.base") + id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") `kotlin-dsl` } @@ -28,6 +31,8 @@ open class ProtocPlugin : Plugin { override fun apply(project: Project) { + configureIntelliJ(project) + val protocConfig = project.extensions.create("protocPluginConfig", ProtocPluginConfig::class, project) @@ -42,29 +47,29 @@ open class ProtocPlugin : Plugin { } } - val protobufLibs: Configuration = project.configurations.create("protobufLib") { + val protobufLib: Configuration = project.configurations.create("protobufLib") { isVisible = true isCanBeConsumed = false isCanBeResolved = true isTransitive = false } -// val protocPrepare = project.tasks.register("protocPrepare") - project.dependencies { - protobufLibs("com.google.protobuf:protobuf-javalite:3.19.1") + protobufLib("com.google.protobuf:protobuf-javalite:3.19.1") } - val libsTask = project.tasks.register("protobufLibs") { + /** Download protobuf libs */ + val protoLibsTask = project.tasks.register("protobufLibs") { group = "protobuf" - + description = "Download and extract protobuf libs" includeEmptyDirs = false + dependsOn(protobufLib) - dependsOn(protobufLibs) + val protoLibDir by project.objects.directoryProperty() + .convention(project.layout.buildDirectory.dir("protobuf/libs")) + into(protoLibDir) - val outDir = project.layout.buildDirectory.dir("proto/libs") - - protobufLibs + protobufLib .map { project.zipTree(it) } .forEach { logger.lifecycle("protoc lib - $it") @@ -72,50 +77,60 @@ open class ProtocPlugin : Plugin { include("**/*.proto") } } - - into(outDir) } + // TODO investigate builtBy and sourceDirectorySet? +// project.objects.fileCollection().builtBy() +// val pbSrcSet = project.objects.sourceDirectorySet("protobuf", "protobuf") - project.tasks.register("protobufCompile") { + + /** Convert `.proto` files to Kotlin */ + val pbCompileTask = project.tasks.register("protobufCompile") { group = "protobuf" - dependsOn(protobufCompiler, libsTask) - executable(protobufCompiler.singleFile) - - val protoLibsDir = project.layout.buildDirectory.dir("proto/libs") - inputs.dir(protoLibsDir) + dependsOn(protobufCompiler, protoLibsTask) standardOutput = System.out - val outDir = project.layout.buildDirectory.dir("protoc/generated-sources") - outputs.dir(outDir) - + executable(protobufCompiler.singleFile) workingDir(temporaryDirFactory) - val javaOut = workingDir.resolve("proto/java") - val kotlinOut = workingDir.resolve("proto/kotlin") + val outDir = project.layout.buildDirectory.dir("protobuf/generated-sources") + outputs.dir(outDir) + + val protoLibsDir: Provider = protoLibsTask.map { it.destinationDir } + + val javaOut = workingDir.resolve("java") + val kotlinOut = workingDir.resolve("kotlin") val protoFile by project.objects.fileProperty() .convention(project.layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto")) + val protoFileParent = project.provider { protoFile.asFile.parentFile } - inputs.file(protoFile) + val isLiteEnabled: Boolean by project.objects.property().convention(true) - args( - parseSpaceSeparatedArgs( - """ - --proto_path=${protoFileParent.get()} - --proto_path=${protoLibsDir.get()} - --java_out=$javaOut - --kotlin_out=$kotlinOut - $protoFile - """ - ) - ) doFirst { project.delete(workingDir) + project.mkdir(outDir) project.mkdir(javaOut) project.mkdir(kotlinOut) + + val liteOpt: String = when (isLiteEnabled) { + true -> "lite:" + false -> "" + } + + args( + parseSpaceSeparatedArgs( + """ + --proto_path=${protoLibsDir.get()} + --proto_path=${protoFileParent.get()} + --java_out=$liteOpt$javaOut + --kotlin_out=$liteOpt$kotlinOut + $protoFile + """ + ) + ) } doLast { @@ -125,13 +140,55 @@ open class ProtocPlugin : Plugin { } project.delete(workingDir) } + } + project.tasks.assemble { dependsOn(pbCompileTask) } + + } + + /** Setup source dirs */ + private fun configureIntelliJ(project: Project) { + + val genSrcDir = project.layout.buildDirectory.dir("protobuf/generated-sources") + val ktGenSrc = genSrcDir.map { it.dir("kotlin") } + + project.mkdir(ktGenSrc) + + project.extensions.findByType()?.apply { + project.logger.lifecycle("-------\nadding generated sources $ktGenSrc\n-------") + + project.sourceSets.named("main") { + this.java.srcDir(ktGenSrc) + } + +// sourceSets.main.get().kotlin.srcDir(ktGenSrc) + +// sourceSets.main.configure { +// this.kotlin.srcDir(ktGenSrc) +// } + } + + project.plugins.withType { + project.extensions.configure { + this.module.generatedSourceDirs.add(ktGenSrc.get().asFile) + } + } + + + /** + * IntelliJ requires source dirs are configured first. + * + * https://github.com/google/protobuf-gradle-plugin/blob/master/src/main/groovy/com/google/protobuf/gradle/Utils.groovy#L128 + */ + project.tasks.withType { + doFirst { + project.mkdir(ktGenSrc) + } } } } -abstract class ProtocPluginConfig(private val project: Project) : - java.io.Serializable { // TODO remove serializable? +abstract class ProtocPluginConfig(private val project: Project) { val protocWorkingDir: DirectoryProperty = project.objects.directoryProperty() @@ -222,7 +279,6 @@ abstract class ProtocPluginConfig(private val project: Project) : abstract class ProtocPrepareTask : DefaultTask() { - @Internal val protocPluginConfig: Provider = project.provider { project.extensions.getByType() @@ -280,9 +336,26 @@ abstract class ProtocGenerationTask : DefaultTask() { } - apply() configure { } + +val logSS = tasks.create("logSourceSets") { + group = "protobuf" + + doLast { + sourceSets.forEach { set -> + logger.lifecycle("SourceSet name: ${set.name}") + set.allSource.forEach { src -> + logger.lifecycle("location: ${src.toRelativeString(rootProject.projectDir)}") + } + } + + logger.lifecycle("-------\nIdeaModel generated source dirs: ${project.idea.module.generatedSourceDirs.joinToString()}\n-------") + } +} + +tasks.named("protobufCompile") { finalizedBy(logSS) } + From 978b515682f4b73fcc12fa8f855ef77e1ff46539 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 30 Oct 2021 18:49:52 +0200 Subject: [PATCH 062/629] get code compiling (add java as srcdir) --- modules/factorio-events-data-model/build.gradle.kts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index 4f2aa33..b82d1a5 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -56,6 +56,8 @@ open class ProtocPlugin : Plugin { project.dependencies { protobufLib("com.google.protobuf:protobuf-javalite:3.19.1") +// implementation("com.google.protobuf:protobuf-javalite:3.19.1") + implementation("com.google.protobuf:protobuf-kotlin-lite:3.19.1") } /** Download protobuf libs */ @@ -151,6 +153,7 @@ open class ProtocPlugin : Plugin { val genSrcDir = project.layout.buildDirectory.dir("protobuf/generated-sources") val ktGenSrc = genSrcDir.map { it.dir("kotlin") } + val jGenSrc = genSrcDir.map { it.dir("java") } project.mkdir(ktGenSrc) @@ -159,6 +162,7 @@ open class ProtocPlugin : Plugin { project.sourceSets.named("main") { this.java.srcDir(ktGenSrc) + this.java.srcDir(jGenSrc) } // sourceSets.main.get().kotlin.srcDir(ktGenSrc) @@ -171,6 +175,7 @@ open class ProtocPlugin : Plugin { project.plugins.withType { project.extensions.configure { this.module.generatedSourceDirs.add(ktGenSrc.get().asFile) + this.module.generatedSourceDirs.add(jGenSrc.get().asFile) } } From 59891678a52d7a7fdebf455819a9f4405f662f2d Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 30 Oct 2021 20:24:58 +0200 Subject: [PATCH 063/629] tried moving protobuf plugin to separate project, but IntelliJ doesn't like it --- buildSrc/build.gradle.kts | 11 + modules/protoc-gradle-plugin/build.gradle.kts | 102 +----- .../dev/adamko/gradle/pbandg/ProtocPlugin.kt | 330 +++++++++++++----- settings.gradle.kts | 2 +- 4 files changed, 260 insertions(+), 185 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 8b7aba1..dba2d23 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { `kotlin-dsl` kotlin("jvm") version "1.5.31" @@ -20,3 +22,12 @@ dependencies { implementation("com.github.node-gradle:gradle-node-plugin:3.1.1") } + +tasks.withType().configureEach { + kotlinOptions.freeCompilerArgs += listOf( + "-Xopt-in=kotlin.OptIn", + "-Xopt-in=kotlin.ExperimentalStdlibApi", + "-Xopt-in=kotlin.time.ExperimentalTime", + "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + ) +} \ No newline at end of file diff --git a/modules/protoc-gradle-plugin/build.gradle.kts b/modules/protoc-gradle-plugin/build.gradle.kts index ab9eb2b..47892e9 100644 --- a/modules/protoc-gradle-plugin/build.gradle.kts +++ b/modules/protoc-gradle-plugin/build.gradle.kts @@ -1,16 +1,14 @@ -import org.gradle.nativeplatform.platform.internal.ArchitectureInternal -import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform - plugins { kotlin("jvm") version "1.5.31" `kotlin-dsl` `java-gradle-plugin` + `maven-publish` } gradlePlugin { plugins { - create("Protobuf & Gradle") { - id = "dev-adamko.pb-and-g" + create("ProtobufAndGradle") { + id = "dev.adamko.pb-and-g" implementationClass = "dev.adamko.gradle.pbandg.ProtocPluginKt" description = "Protobuf & Gradle. Wrapper for protoc to generate code from Proto Buffer files." @@ -18,6 +16,9 @@ gradlePlugin { } } +group = "dev.adamko.gradle.pbandg" +version = "0.0.1-SNAPSHOT" + val protocConfiguration: Configuration by configurations.creating { // A configuration meant for consumers that need the implementation of this component @@ -25,10 +26,13 @@ val protocConfiguration: Configuration by configurations.creating { isCanBeConsumed = false } -val protobufVersion = "3.19.0" +val protobufVersion = "3.19.1" val protocVersion = "3.9.2" dependencies { + implementation(platform("org.jetbrains.kotlin:kotlin-bom")) + implementation(kotlin("stdlib")) + implementation(platform("com.google.protobuf:protobuf-bom:$protobufVersion")) implementation("com.google.protobuf:protobuf-java:$protobufVersion") @@ -45,9 +49,6 @@ dependencies { implementation("io.grpc:protoc-gen-grpc-kotlin:1.2.0") implementation("javax.annotation:javax.annotation-api:1.3.2") -// - -// implementation(npm("protoc-gen-ts", "0.15.0")) implementation( group = "com.google.protobuf", @@ -67,93 +68,10 @@ dependencies { ext = "exe", ) -// protocConfiguration("com.google.protobuf:protoc:3.9.2@exe") - } - - -// https://github.com/protocolbuffers/protobuf/tree/master/protoc-artifacts -// The name of a published protoc artifact is in the format: -// protoc---.exe -// e.g., protoc-3.6.1-linux-x86_64.exe -// Note that artifacts for Linux/macOS also have the .exe suffix, but they are not windows binaries. -val os: OperatingSystem = DefaultNativePlatform.getCurrentOperatingSystem() -val arch: ArchitectureInternal = DefaultNativePlatform.getCurrentArchitecture() - repositories { mavenCentral() - -// ivy { -// url = project.repositories.mavenCentral().url -// -// patternLayout { -// -// // com/google/protobuf/protoc/3.9.2/protoc-3.9.2-linux-aarch_64.exe -// artifact("[organisation]/[module]/[revision]/[artifact]-[revision]-${os.name}-${arch.name}.[ext]") -// -//// artifact("3rd-party-artifacts/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]") -//// artifact("company-artifacts/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]") -//// ivy("ivy-files/[organisation]/[module]/[revision]/ivy.xml") -//// artifact("[organisation]/[module]/[revision]/[artifact]-[revision].[ext]") -// setM2compatible(true) -// metadataSources { -// artifact() -// } -// } -// } - } -tasks.register("protocExecCopy") { - group = project.name - -// from(protocConfiguration.artifacts) - - from(protocConfiguration.resolve()) - - into(project.layout.buildDirectory.dir("protocCopy")) -} - -//tasks.register("dlPc") { -// group = project.name -// -// val downloadDir = this.temporaryDir -// -// outputs.dir(downloadDir) -// -// doLast { -// -//// downloadDir.mkdirs() -// -// val protocArtifactFileExt = "exe" -// -// val osFamilyName = DefaultNativePlatform.host().operatingSystem.toFamilyName() -// -// val arch: String = -// DefaultNativePlatform.getCurrentArchitecture() -// .name -// .replace("-", "_") -// -// val artifact = "protoc-$protocVersion-${osFamilyName}-${arch}.$protocArtifactFileExt" -// -// val uri = uri( -// ArtifactRepositoryContainer.MAVEN_CENTRAL_URL -// + "com/google/protobuf/protoc/$protocVersion/$artifact" -// ) -// // actual: -// // https://repo.maven.apache.org/maven2/com/google/protobuf/protoc/3.9.2/protoc-3.9.2-windows-x86_64.exe -// // https://repo.maven.apache.org/maven2/com/google/protobuf/protoc/3.9.2/protoc-3.9.2-windows-x86-64.exe -// -// ant.invokeMethod( -// "get", mapOf( -// "src" to uri, -// "dest" to downloadDir.canonicalPath, -// "verbose" to true, -// ) -// ) -// } -// -//} -// diff --git a/modules/protoc-gradle-plugin/src/main/kotlin/dev/adamko/gradle/pbandg/ProtocPlugin.kt b/modules/protoc-gradle-plugin/src/main/kotlin/dev/adamko/gradle/pbandg/ProtocPlugin.kt index a7c882f..70080a8 100644 --- a/modules/protoc-gradle-plugin/src/main/kotlin/dev/adamko/gradle/pbandg/ProtocPlugin.kt +++ b/modules/protoc-gradle-plugin/src/main/kotlin/dev/adamko/gradle/pbandg/ProtocPlugin.kt @@ -1,67 +1,217 @@ package dev.adamko.gradle.pbandg +import java.io.File +import java.util.function.Supplier import org.gradle.api.DefaultTask import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.ExternalDependency +import org.gradle.api.artifacts.ExternalModuleDependency +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty import org.gradle.api.plugins.ExtensionAware import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Exec +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.Sync import org.gradle.api.tasks.TaskAction +import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.domainObjectContainer import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.defaultDependencies +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.findByType +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.getValue import org.gradle.kotlin.dsl.withType import org.gradle.kotlin.dsl.property +import org.gradle.kotlin.dsl.provideDelegate +import org.gradle.kotlin.dsl.register +import org.gradle.nativeplatform.platform.Architecture import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform +import org.gradle.nativeplatform.platform.internal.DefaultOperatingSystem +import org.gradle.plugins.ide.idea.GenerateIdeaModule +import org.gradle.plugins.ide.idea.IdeaPlugin +import org.gradle.plugins.ide.idea.model.IdeaModel +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs -class ProtocPlugin : Plugin { +open class ProtocPlugin : Plugin { override fun apply(project: Project) { - val protocConfig = - project.extensions.create("protocConfig", ProtocConfigExtension::class.java) + configureIntelliJ(project) - val protocDeps = project.configurations.create("pbAndG") { + val protocConfig = + project.extensions.create("protocPluginConfig", ProtocPluginConfig::class, project) + + val protobufCompiler: Configuration = project.configurations.create("protobufCompiler") { isVisible = false isCanBeConsumed = false isCanBeResolved = true - description = "protoc dependencies" + isTransitive = false defaultDependencies { -// deps += project.dependencies.create("com.google.protobuf:protoc:3.19.0") - add(protocConfig.dependencyProvider()) + add(protocConfig.dependency.get()) } } - val generatorsContainer = - project.objects.domainObjectContainer(ProtocGenerationTask::class.java) - protocConfig.extensions.add("generate", generatorsContainer) - - - project.extensions.add("asd", project.provider { - DefaultNativePlatform.getCurrentOperatingSystem().toFamilyName() - }) - - project.tasks.withType { -// .getDataFiles()?.from(protocDeps) + val protobufLib: Configuration = project.configurations.create("protobufLib") { + isVisible = true + isCanBeConsumed = false + isCanBeResolved = true + isTransitive = false } -// project.getPlugins().withType(org.gradle.api.plugins.JavaPlugin::class) { javaPlugin -> -// val sourceSets: SourceSetContainer = -// project.getExtensions().getByType(SourceSetContainer::class.java) -// val main: SourceSet = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME) -// main.getJava().setSrcDirs(Arrays.asList("src")) -// } + project.dependencies { + protobufLib("com.google.protobuf:protobuf-javalite:3.19.1") +// implementation("com.google.protobuf:protobuf-javalite:3.19.1") +// implementation("com.google.protobuf:protobuf-kotlin-lite:3.19.1") + } + + /** Download protobuf libs */ + val protoLibsTask = project.tasks.register("protobufLibs") { + group = "protobuf" + description = "Download and extract protobuf libs" + includeEmptyDirs = false + dependsOn(protobufLib) + + val protoLibDir by project.objects.directoryProperty() + .convention(project.layout.buildDirectory.dir("protobuf/libs")) + into(protoLibDir) + + protobufLib + .map { project.zipTree(it) } + .forEach { + logger.lifecycle("protoc lib - $it") + from(it) { + include("**/*.proto") + } + } + } + + // TODO investigate builtBy and sourceDirectorySet? +// project.objects.fileCollection().builtBy() +// val pbSrcSet = project.objects.sourceDirectorySet("protobuf", "protobuf") + + + /** Convert `.proto` files to Kotlin */ + val pbCompileTask = project.tasks.register("protobufCompile") { + group = "protobuf" + dependsOn(protobufCompiler, protoLibsTask) + + standardOutput = System.out + + executable(protobufCompiler.singleFile) + workingDir(temporaryDirFactory) + + val outDir = project.layout.buildDirectory.dir("protobuf/generated-sources") + outputs.dir(outDir) + + val protoLibsDir: Provider = protoLibsTask.map { it.destinationDir } + + val javaOut = workingDir.resolve("java") + val kotlinOut = workingDir.resolve("kotlin") + val protoFile by project.objects.fileProperty() + .convention(project.layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto")) + + val protoFileParent = project.provider { protoFile.asFile.parentFile } + + val isLiteEnabled: Boolean by project.objects.property().convention(true) + + doFirst { + project.delete(workingDir) + + project.mkdir(outDir) + project.mkdir(javaOut) + project.mkdir(kotlinOut) + + val liteOpt: String = when (isLiteEnabled) { + true -> "lite:" + false -> "" + } + + args( + parseSpaceSeparatedArgs( + """ + --proto_path=${protoLibsDir.get()} + --proto_path=${protoFileParent.get()} + --java_out=$liteOpt$javaOut + --kotlin_out=$liteOpt$kotlinOut + $protoFile + """ + ) + ) + } + + doLast { + project.sync { + from(workingDir) + into(outDir) + } + project.delete(workingDir) + } + } + + project.tasks.assemble { dependsOn(pbCompileTask) } } + /** + * IntelliJ requires source dirs are configured first. + * + * https://github.com/google/protobuf-gradle-plugin/blob/master/src/main/groovy/com/google/protobuf/gradle/Utils.groovy#L128 + */ + private fun configureIntelliJ(project: Project) { + + val genSrcDir = project.layout.buildDirectory.dir("protobuf/generated-sources") + val ktGenSrc = genSrcDir.map { it.dir("kotlin") } + val jGenSrc = genSrcDir.map { it.dir("java") } + + project.mkdir(ktGenSrc) + + project.extensions.findByType()?.apply { + project.logger.lifecycle("-------\nadding generated sources $ktGenSrc\n-------") + + project.sourceSets.named("main") { + this.java.srcDir(ktGenSrc) + this.java.srcDir(jGenSrc) + } + +// sourceSets.main.get().kotlin.srcDir(ktGenSrc) + +// sourceSets.main.configure { +// this.kotlin.srcDir(ktGenSrc) +// } + } + + project.plugins.withType { + project.extensions.configure { + this.module.generatedSourceDirs.add(ktGenSrc.get().asFile) + this.module.generatedSourceDirs.add(jGenSrc.get().asFile) + } + } + + project.tasks.withType { + doFirst { + project.mkdir(ktGenSrc) + } + } + } } +abstract class ProtocPluginConfig(private val project: Project) { -abstract class ProtocConfigExtension(private val project: Project) : ExtensionAware { + val protocWorkingDir: DirectoryProperty = + project.objects.directoryProperty() + .convention(project.rootProject.layout.projectDirectory.dir(".gradle/protoc")) val protocVersion: Property = - project.objects.property(String::class).convention("3.9.2") + project.objects.property(String::class).convention("3.19.1") val protocGroup: Property = project.objects.property(String::class).convention("com.google.protobuf") @@ -72,77 +222,73 @@ abstract class ProtocConfigExtension(private val project: Project) : ExtensionAw val protocArtifactExtension: Property = project.objects.property(String::class).convention("exe") - var osFamilyNameProvider: () -> String = { - DefaultNativePlatform.getCurrentOperatingSystem().toFamilyName() - } + val operatingSystemProvider: Property> = + project.objects.property>() + .convention { DefaultNativePlatform.getCurrentOperatingSystem() } - var architectureProviderMapper: (String) -> String = { - it.replace("-", "_") - } + /** + * Should return one of + * + * * `linux` + * * `osx` + * * `windows` + */ + val operatingSystemName: Property = + project.objects + .property() + .convention(operatingSystemProvider.map { it.get().toFamilyName() }) - var architectureProvider: () -> String = { - DefaultNativePlatform.getCurrentArchitecture() - .name - .let(architectureProviderMapper) - } + private val architectureProvider: Provider = + project.provider { DefaultNativePlatform.getCurrentArchitecture() } - var classifierProvider: () -> String = { - "${osFamilyNameProvider()}-${architectureProvider()}" - } + /** + * Should return one of + * + * * `aarch_64` + * * `ppcle_64` + * * `x86_32` + * * `x86_64` + */ + val architectureName: Property = + project.objects + .property() + .convention(architectureProvider.map { it.name.replace("-", "_") }) - var dependencyProvider: () -> ExternalDependency = { - project.dependencies.create( - group = protocGroup.get(), - name = protocArtifactName.get(), - version = protocVersion.get(), - classifier = classifierProvider(), - ext = protocArtifactExtension.get(), - ) - } + private val classifierProvider: Provider = + project.provider { "${operatingSystemName.get()}-${architectureName.get()}" } - val generators = project.objects.domainObjectContainer(ProtocGenerationConfig::class) + /** + * Default: concatenate [osFamilyNameProvider] and [architectureProvider] + * + * Should return one of: + * + * * `linux-aarch_64` + * * `linux-ppcle_64` + * * `linux-x86_64` + * * `osx-x86_32` + * * `osx-x86_64` + * * `windows-x86_32` + */ + val classifier: Property = + project.objects + .property() + .convention(classifierProvider) + private val dependencyProvider: Provider = + project.provider { + project.dependencies.create( + group = protocGroup.get(), + name = protocArtifactName.get(), + version = protocVersion.get(), + classifier = classifierProvider.get(), + ext = protocArtifactExtension.get(), + ) + } + + val dependency: Property = + project.objects + .property() + .convention(dependencyProvider) + } - -abstract class ProtocGenerationConfig - -abstract class ProtocGenerationTask : DefaultTask() { - - @TaskAction - fun generate() { - logger.lifecycle("generating protoc...") - } - -} - - -//class ProtocDownloadExe : DefaultTask() { -// -////@Input -//val protocVersion = "3.9.2" -//val protocArtifactFileExt = "exe" -// -// -// @TaskAction -// fun download() { -// -// val baseUri = project.repositories.mavenCentral().url -// -// val os: OperatingSystem = DefaultNativePlatform.getCurrentOperatingSystem() -// val arch: ArchitectureInternal = DefaultNativePlatform.getCurrentArchitecture() -// -// val artifact = "protoc-$protocVersion-${os.name}-${arch.name}.$protocArtifactFileExt" -// -// ant.invokeMethod( -// "get", mapOf( -// "src" to baseUri.resolve("/com/google/protobuf/protoc/3.9.2/protoc-3.9.2-linux-aarch_64.exe"), -// "dest" to project.layout.buildDirectory.dir("protoc-artifact"), -// "verbose" to true, -// ) -// ) -// -// -// } -// -//} diff --git a/settings.gradle.kts b/settings.gradle.kts index ea5f799..30886cb 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ rootProject.name = "factorio-web-map" -includeBuild("modules/protoc-gradle-plugin") +//includeBuild("modules/protoc-gradle-plugin") include( ":modules:mod", From 0f6677e0b13d71e9122751e766ca11ad65ad440d Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sun, 31 Oct 2021 08:52:40 +0100 Subject: [PATCH 064/629] standalone pb plugin working! --- .../archetype/kotlin-jvm.gradle.kts | 1 + .../dev/adamko/gradle/pbandg/Constants.kt | 20 + .../pbandg/ProtobufCompilerDependency.kt | 22 ++ .../gradle/pbandg/pattern/IntelliJPattern.kt | 48 +++ .../pattern/KotlinProjectConfiguration.kt | 39 ++ .../pbandg/pattern/ProtocPrepareTask.kt | 65 ++++ .../adamko/gradle/pbandg/pb-and-g.gradle.kts | 86 +++++ .../gradle/pbandg/settings/PBAndGSettings.kt | 103 +++++ .../gradle/pbandg/task/ProtobufCompileTask.kt | 153 ++++++++ .../task/ProtobufPrepareLibrariesTask.kt | 39 ++ .../pbandg/task/options/ProtocOutput.kt | 33 ++ .../build.gradle.kts | 357 +----------------- 12 files changed, 613 insertions(+), 353 deletions(-) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/Constants.kt create mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/ProtobufCompilerDependency.kt create mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/IntelliJPattern.kt create mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinProjectConfiguration.kt create mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/ProtocPrepareTask.kt create mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts create mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/settings/PBAndGSettings.kt create mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufCompileTask.kt create mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufPrepareLibrariesTask.kt create mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/options/ProtocOutput.kt diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts index 7e3553c..f96fb0c 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts @@ -37,6 +37,7 @@ dependencies { testImplementation("io.kotest:kotest-property-jvm:$kotestVersion") testImplementation("io.kotest:kotest-assertions-json:$kotestVersion") testImplementation("io.mockk:mockk:1.12.0") + // } diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/Constants.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/Constants.kt new file mode 100644 index 0000000..95d8bbc --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/Constants.kt @@ -0,0 +1,20 @@ +package dev.adamko.gradle.pbandg + +import org.gradle.api.Project +import org.gradle.api.file.Directory +import org.gradle.api.file.ProjectLayout +import org.gradle.api.provider.Provider + +object Constants { + const val PBG_SETTINGS_NAME = "pbAndG" + const val PBG_TASK_GROUP = PBG_SETTINGS_NAME// "pb-and-g" + const val PBG_LIBS_CONF_NAME = "protobufLibrary" + const val PBG_TASK_COMPILE = "protobufCompile" + + val Project.pbAndGBuildDir: Provider + get() = layout.pbAndGBuildDir + + val ProjectLayout.pbAndGBuildDir: Provider + get() = buildDirectory.dir(PBG_TASK_GROUP) + +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/ProtobufCompilerDependency.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/ProtobufCompilerDependency.kt new file mode 100644 index 0000000..fb0edbb --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/ProtobufCompilerDependency.kt @@ -0,0 +1,22 @@ +package dev.adamko.gradle.pbandg + +import dev.adamko.gradle.pbandg.settings.PBAndGSettings +import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration + + +class ProtobufCompilerDependency( + project: Project, + pluginSettings: PBAndGSettings, + private val conf: Configuration = project.configurations.create("protobufCompiler") { + this.description = "Define a single dependency that provides the protoc.exe for this system" + isVisible = false + isCanBeConsumed = false + isCanBeResolved = true + isTransitive = false + + defaultDependencies { + add(pluginSettings.dependency.get()) + } + } +) : Configuration by conf diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/IntelliJPattern.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/IntelliJPattern.kt new file mode 100644 index 0000000..1624641 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/IntelliJPattern.kt @@ -0,0 +1,48 @@ +package dev.adamko.gradle.pbandg.pattern + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.hasPlugin +import org.gradle.kotlin.dsl.withType +import org.gradle.plugins.ide.idea.GenerateIdeaModule +import org.gradle.plugins.ide.idea.IdeaPlugin +import org.gradle.plugins.ide.idea.model.IdeaModel + +/** + * IntelliJ requires source dirs are configured first. + * + * https://github.com/google/protobuf-gradle-plugin/blob/master/src/main/groovy/com/google/protobuf/gradle/Utils.groovy#L128 + */ +class IntelliJPattern : Plugin { + + fun isIdeaPluginPresent(project: Project) = project.plugins.hasPlugin(IdeaPlugin::class) + + override fun apply(project: Project) { + + if (!isIdeaPluginPresent(project)) { + return + } + + val genSrcDir = project.layout.buildDirectory.dir("protobuf/generated-sources") + val ktGenSrc = genSrcDir.map { it.dir("kotlin") } + val jGenSrc = genSrcDir.map { it.dir("java") } + + project.mkdir(ktGenSrc) + project.mkdir(jGenSrc) + + project.plugins.withType { + project.extensions.configure { + this.module.generatedSourceDirs.add(ktGenSrc.get().asFile) + this.module.generatedSourceDirs.add(jGenSrc.get().asFile) + } + } + + project.tasks.withType { + doFirst { + project.mkdir(ktGenSrc) + } + } + + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinProjectConfiguration.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinProjectConfiguration.kt new file mode 100644 index 0000000..f30af8c --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinProjectConfiguration.kt @@ -0,0 +1,39 @@ +package dev.adamko.gradle.pbandg.pattern + +import dev.adamko.gradle.pbandg.task.ProtobufCompileTask +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.tasks.SourceSet +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.findByType +import org.gradle.kotlin.dsl.getByName +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension + +class KotlinProjectConfiguration : Plugin { + + override fun apply(project: Project) { + addSourceSets(project) + + } + + private fun addSourceSets(project: Project) { + + project.extensions.findByType()?.apply { + + val srcSet = project.extensions.getByName(SourceSet.MAIN_SOURCE_SET_NAME) + + project.tasks + .withType() + .map { it.generatedSources.get() } + .forEach { generatedSourcesDir -> + project.logger.lifecycle("-------\nadding generated sources $generatedSourcesDir\n-------") + + srcSet.java { + srcDir(generatedSourcesDir.dir("java")) + srcDir(generatedSourcesDir.dir("kotlin")) + } + } + } + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/ProtocPrepareTask.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/ProtocPrepareTask.kt new file mode 100644 index 0000000..63b7c9e --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/ProtocPrepareTask.kt @@ -0,0 +1,65 @@ +package dev.adamko.gradle.pbandg.pattern + + +import dev.adamko.gradle.pbandg.settings.PBAndGSettings +import org.gradle.api.DefaultTask +import org.gradle.api.artifacts.Configuration +import org.gradle.api.artifacts.ExternalModuleDependency +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction +import org.gradle.kotlin.dsl.getByType + + +abstract class ProtocPrepareTask : DefaultTask() { + + @Internal + val protocPluginConfig: Provider = project.provider { + project.extensions.getByType() + } + + @get:OutputDirectory + val outputDirectory: DirectoryProperty = project.objects.directoryProperty() + .convention(protocPluginConfig.flatMap { it.protocWorkingDir }) + + @Internal + val protocOutput: RegularFileProperty = project.objects.fileProperty() + + @Internal + val protocDependency: Provider = + protocPluginConfig.flatMap { it.dependency } + + init { + super.setGroup("protobuf") + outputs.dir(outputDirectory) + } + + @TaskAction + fun action() { + + val protocDep: Configuration = project.configurations.create("protoc") { + isVisible = false + isCanBeConsumed = false + isCanBeResolved = true + isTransitive = false + + defaultDependencies { + add(protocDependency.get()) + } + } + + logger.lifecycle("Downloading protoc") + val resolvedProtocDep = protocDep.singleFile + logger.lifecycle("Downloaded $resolvedProtocDep") + + project.sync { + from(resolvedProtocDep) + into(outputDirectory) + logger.lifecycle("Syncing from $resolvedProtocDep to ${outputDirectory.asFile.get().canonicalPath}") + protocOutput.set(outputDirectory.asFileTree.singleFile) + } + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts new file mode 100644 index 0000000..bfb6635 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts @@ -0,0 +1,86 @@ +package dev.adamko.gradle.pbandg + +import dev.adamko.gradle.pbandg.settings.PBAndGSettings +import dev.adamko.gradle.pbandg.task.ProtobufCompileTask +import dev.adamko.gradle.pbandg.task.ProtobufPrepareLibrariesTask +import dev.adamko.gradle.pbandg.task.options.ProtocOutput.JavaOutput +import dev.adamko.gradle.pbandg.task.options.ProtocOutput.KotlinOutput + +//plugins { +// `kotlin-dsl` +//} + +plugins { + base +} + + +// TODO investigate builtBy and sourceDirectorySet? +// project.objects.fileCollection().builtBy() +// val pbSrcSet = project.objects.sourceDirectorySet("protobuf", "protobuf") + +//if (plugins.hasPlugin(IdeaPlugin::class)) { +// apply(IntelliJPattern()) +//} +//if (plugins.hasPlugin("org.jetbrains.kotlin.jvm")) { +// apply(KotlinProjectConfiguration()) +//} + +val pbAndGSettings = + project.extensions.create(Constants.PBG_SETTINGS_NAME, PBAndGSettings::class, project) + +//val protocDep = ProtobufCompilerDependency(project, pbAndGSettings) +val protocDep = project.configurations.create("protobufCompiler") { + this.description = "Define a single dependency that provides the protoc.exe for this system" + isVisible = false + isCanBeConsumed = false + isCanBeResolved = true + isTransitive = false + + defaultDependencies { + add(pbAndGSettings.dependency.get()) + } +} + +val protobufLibraryDependencies: Configuration = + project.configurations.create(Constants.PBG_LIBS_CONF_NAME) { + isVisible = true + isCanBeConsumed = false + isCanBeResolved = true + isTransitive = false + } + + +project.dependencies { + protobufLibraryDependencies("com.google.protobuf:protobuf-javalite:3.19.1") +// implementation("com.google.protobuf:protobuf-javalite:3.19.1") +// implementation("com.google.protobuf:protobuf-kotlin-lite:3.19.1") +} + +val protobufPrepareLibrariesTask = + project.tasks.register("protobufPrepareLibraries") { + librarySources.set(protobufLibraryDependencies) + } + +//project.dependencies { +// protobufLibraryDependencies("com.google.protobuf:protobuf-javalite:3.19.1") +//// implementation("com.google.protobuf:protobuf-javalite:3.19.1") +//// implementation("com.google.protobuf:protobuf-kotlin-lite:3.19.1") +//} + + +/** Convert `.proto` files to Kotlin */ +val pbCompileTask = project.tasks.register(Constants.PBG_TASK_COMPILE) { + dependsOn(protocDep, protobufPrepareLibrariesTask) + + protobufLibraryDirectories.add(protobufPrepareLibrariesTask.flatMap { it.librariesDirectory }) + + protocOutputs += KotlinOutput() + protocOutputs += JavaOutput() + + val exe = protocDep.singleFile + logger.lifecycle("protoc.exe: $exe") + protocExecutable.set(exe) +} + +project.tasks.assemble { dependsOn(pbCompileTask) } \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/settings/PBAndGSettings.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/settings/PBAndGSettings.kt new file mode 100644 index 0000000..0023061 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/settings/PBAndGSettings.kt @@ -0,0 +1,103 @@ +package dev.adamko.gradle.pbandg.settings + + +import java.util.function.Supplier +import org.gradle.api.Project +import org.gradle.api.artifacts.ExternalModuleDependency +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider +import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.property +import org.gradle.nativeplatform.platform.Architecture +import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform +import org.gradle.nativeplatform.platform.internal.DefaultOperatingSystem + +abstract class PBAndGSettings(private val project: Project) { + + val protocWorkingDir: DirectoryProperty = + project.objects.directoryProperty() + .convention(project.rootProject.layout.projectDirectory.dir(".gradle/protoc")) + + val protocVersion: Property = + project.objects.property(String::class).convention("3.19.1") + + val protocGroup: Property = + project.objects.property(String::class).convention("com.google.protobuf") + + val protocArtifactName: Property = + project.objects.property(String::class).convention("protoc") + + val protocArtifactExtension: Property = + project.objects.property(String::class).convention("exe") + + val operatingSystemProvider: Property> = + project.objects.property>() + .convention { DefaultNativePlatform.getCurrentOperatingSystem() } + + /** + * Should return one of + * + * * `linux` + * * `osx` + * * `windows` + */ + val operatingSystemName: Property = + project.objects + .property() + .convention(operatingSystemProvider.map { it.get().toFamilyName() }) + + private val architectureProvider: Provider = + project.provider { DefaultNativePlatform.getCurrentArchitecture() } + + /** + * Should return one of + * + * * `aarch_64` + * * `ppcle_64` + * * `x86_32` + * * `x86_64` + */ + val architectureName: Property = + project.objects + .property() + .convention(architectureProvider.map { it.name.replace("-", "_") }) + + private val classifierProvider: Provider = + project.provider { "${operatingSystemName.get()}-${architectureName.get()}" } + + /** + * Default: concatenate [operatingSystemName] and [architectureName] + * + * Should return one of: + * + * * `linux-aarch_64` + * * `linux-ppcle_64` + * * `linux-x86_64` + * * `osx-x86_32` + * * `osx-x86_64` + * * `windows-x86_32` + */ + val classifier: Property = + project.objects + .property() + .convention(classifierProvider) + + + private val dependencyProvider: Provider = + project.provider { + project.dependencies.create( + group = protocGroup.get(), + name = protocArtifactName.get(), + version = protocVersion.get(), + classifier = classifierProvider.get(), + ext = protocArtifactExtension.get(), + ) + } + + val dependency: Property = + project.objects + .property() + .convention(dependencyProvider) + +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufCompileTask.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufCompileTask.kt new file mode 100644 index 0000000..5ff5ef4 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufCompileTask.kt @@ -0,0 +1,153 @@ +package dev.adamko.gradle.pbandg.task + +import dev.adamko.gradle.pbandg.Constants +import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir +import dev.adamko.gradle.pbandg.task.options.ProtocOutput +import org.gradle.api.DefaultTask +import org.gradle.api.DomainObjectSet +import org.gradle.api.file.Directory +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction +import org.gradle.kotlin.dsl.property + +abstract class ProtobufCompileTask : DefaultTask() { + + @get:InputFile + abstract val protocExecutable: RegularFileProperty + + @get:OutputDirectory + val generatedSources: DirectoryProperty = project.objects.directoryProperty() + .convention(project.pbAndGBuildDir.map { it.dir("generated-sources") }) + + @get:InputFiles + abstract val protobufLibraryDirectories: ListProperty + + @get:Input + abstract val protocOutputs: DomainObjectSet +// = project.objects.domainObjectSet(ProtocOutput::class.java) + + @get:InputFile + abstract val protoFile: RegularFileProperty + + @get:Input + val cliParamProtoPath: Property = + project.objects.property().convention("--proto_path=") + + init { + group = Constants.PBG_TASK_GROUP + } + + @TaskAction + fun compile() { + + val workDir = temporaryDir + project.delete(workDir) + + project.exec { + executable(protocExecutable.asFile.get()) + workingDir(workDir) + + // prepare directories + project.mkdir(workingDir) + project.mkdir(generatedSources) + + val mapOutputsToOutputDir = + protocOutputs.associateWith { workingDir.resolve(it.outputDirectoryName) } + mapOutputsToOutputDir.values.forEach { project.mkdir(it) } + + // set args + mapOutputsToOutputDir + .map { (opt, dir) -> + "${opt.cliParam}=${opt.protocOptions}:${dir}" + } + .also { args(it) } + + val protoPath = cliParamProtoPath.get() + val libArgs = protobufLibraryDirectories.get().map { "$protoPath${it.asFile}" } + args(libArgs) + + val targetProtoFile = protoFile.get().asFile + args("$protoPath${targetProtoFile.parentFile}") + args("$targetProtoFile") + } + + // sync compiled files + project.sync { + from(workDir) + into(generatedSources) + includeEmptyDirs = false + } + + // clean up temp-dir + project.delete(workDir) + } + +} + +/* + +{ + group = "protobuf" + dependsOn(protobufCompiler, protoLibsTask) + + standardOutput = System.out + + executable(protobufCompiler.singleFile) + workingDir(temporaryDirFactory) + + val outDir = project.layout.buildDirectory.dir("protobuf/generated-sources") + outputs.dir(outDir) + + val protoLibsDir: Provider = protoLibsTask.map { it.destinationDir } + + val javaOut = workingDir.resolve("java") + val kotlinOut = workingDir.resolve("kotlin") + val protoFile by project.objects.fileProperty() + .convention(project.layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto")) + + val protoFileParent = project.provider { protoFile.asFile.parentFile } + + val isLiteEnabled: Boolean by project.objects.property().convention(true) + + doFirst { + project.delete(workingDir) + + project.mkdir(outDir) + project.mkdir(javaOut) + project.mkdir(kotlinOut) + + val liteOpt: String = when (isLiteEnabled) { + true -> "lite:" + false -> "" + } + + args( + parseSpaceSeparatedArgs( + """ + --proto_path=${protoLibsDir.get()} + --proto_path=${protoFileParent.get()} + --java_out=$liteOpt$javaOut + --kotlin_out=$liteOpt$kotlinOut + $protoFile + """ + ) + ) + } + + doLast { + project.sync { + from(workingDir) + into(outDir) + } + project.delete(workingDir) + } +} + + */ \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufPrepareLibrariesTask.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufPrepareLibrariesTask.kt new file mode 100644 index 0000000..9f71c27 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufPrepareLibrariesTask.kt @@ -0,0 +1,39 @@ +package dev.adamko.gradle.pbandg.task + +import dev.adamko.gradle.pbandg.Constants +import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir +import org.gradle.api.DefaultTask +import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction +import org.gradle.kotlin.dsl.property + +/** Download protobuf libs */ +abstract class ProtobufPrepareLibrariesTask : DefaultTask() { + + @get:InputFiles + val librarySources: Property = project.objects.property() + + @OutputDirectory + val librariesDirectory: DirectoryProperty = project.objects.directoryProperty() + .convention(project.pbAndGBuildDir.map { it.dir("libs") }) + + init { + group = Constants.PBG_TASK_GROUP + description = "Download and extract protobuf libs" + } + + @TaskAction + fun doTask() { + project.sync { + includeEmptyDirs = false + from(librarySources.map { conf -> conf.map { project.zipTree(it) } }) + into(librariesDirectory) + include("**/*.proto") + } + } + +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/options/ProtocOutput.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/options/ProtocOutput.kt new file mode 100644 index 0000000..966fab2 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/options/ProtocOutput.kt @@ -0,0 +1,33 @@ +package dev.adamko.gradle.pbandg.task.options + +import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir +import java.io.Serializable +import org.gradle.api.file.Directory +import org.gradle.api.file.ProjectLayout +import org.gradle.api.provider.Provider + + +interface ProtocOutput : Serializable { + val cliParam: String + val protocOptions: String + val outputDirectoryName: String + + fun outputDirectory(layout: ProjectLayout): Provider { + return layout.pbAndGBuildDir.map { it.dir(outputDirectoryName) } + } + + data class KotlinOutput( + override val protocOptions: String = "lite", + override val outputDirectoryName: String = "kotlin", + ) : ProtocOutput { + override val cliParam: String = "--kotlin_out" + } + + data class JavaOutput( + override val protocOptions: String = "lite", + override val outputDirectoryName: String = "java", + ) : ProtocOutput { + override val cliParam: String = "--java_out" + } + +} \ No newline at end of file diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index b82d1a5..3dba8ca 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -1,21 +1,6 @@ -import java.util.function.Supplier -import org.gradle.api.DefaultTask -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.api.provider.Property -import org.gradle.api.tasks.TaskAction -import org.gradle.kotlin.dsl.provideDelegate -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.property -import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform -import org.gradle.nativeplatform.platform.internal.DefaultOperatingSystem -import org.gradle.plugins.ide.idea.model.IdeaModel -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs - plugins { id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") + id("dev.adamko.gradle.pbandg.pb-and-g") `kotlin-dsl` } @@ -24,343 +9,9 @@ val buildDir: Directory = layout.buildDirectory.dir(projectId).get() dependencies { + protobufLibrary("com.google.protobuf:protobuf-javalite:3.19.1") } - -open class ProtocPlugin : Plugin { - - override fun apply(project: Project) { - - configureIntelliJ(project) - - val protocConfig = - project.extensions.create("protocPluginConfig", ProtocPluginConfig::class, project) - - val protobufCompiler: Configuration = project.configurations.create("protobufCompiler") { - isVisible = false - isCanBeConsumed = false - isCanBeResolved = true - isTransitive = false - - defaultDependencies { - add(protocConfig.dependency.get()) - } - } - - val protobufLib: Configuration = project.configurations.create("protobufLib") { - isVisible = true - isCanBeConsumed = false - isCanBeResolved = true - isTransitive = false - } - - project.dependencies { - protobufLib("com.google.protobuf:protobuf-javalite:3.19.1") -// implementation("com.google.protobuf:protobuf-javalite:3.19.1") - implementation("com.google.protobuf:protobuf-kotlin-lite:3.19.1") - } - - /** Download protobuf libs */ - val protoLibsTask = project.tasks.register("protobufLibs") { - group = "protobuf" - description = "Download and extract protobuf libs" - includeEmptyDirs = false - dependsOn(protobufLib) - - val protoLibDir by project.objects.directoryProperty() - .convention(project.layout.buildDirectory.dir("protobuf/libs")) - into(protoLibDir) - - protobufLib - .map { project.zipTree(it) } - .forEach { - logger.lifecycle("protoc lib - $it") - from(it) { - include("**/*.proto") - } - } - } - - // TODO investigate builtBy and sourceDirectorySet? -// project.objects.fileCollection().builtBy() -// val pbSrcSet = project.objects.sourceDirectorySet("protobuf", "protobuf") - - - /** Convert `.proto` files to Kotlin */ - val pbCompileTask = project.tasks.register("protobufCompile") { - group = "protobuf" - dependsOn(protobufCompiler, protoLibsTask) - - standardOutput = System.out - - executable(protobufCompiler.singleFile) - workingDir(temporaryDirFactory) - - val outDir = project.layout.buildDirectory.dir("protobuf/generated-sources") - outputs.dir(outDir) - - val protoLibsDir: Provider = protoLibsTask.map { it.destinationDir } - - val javaOut = workingDir.resolve("java") - val kotlinOut = workingDir.resolve("kotlin") - val protoFile by project.objects.fileProperty() - .convention(project.layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto")) - - val protoFileParent = project.provider { protoFile.asFile.parentFile } - - val isLiteEnabled: Boolean by project.objects.property().convention(true) - - doFirst { - project.delete(workingDir) - - project.mkdir(outDir) - project.mkdir(javaOut) - project.mkdir(kotlinOut) - - val liteOpt: String = when (isLiteEnabled) { - true -> "lite:" - false -> "" - } - - args( - parseSpaceSeparatedArgs( - """ - --proto_path=${protoLibsDir.get()} - --proto_path=${protoFileParent.get()} - --java_out=$liteOpt$javaOut - --kotlin_out=$liteOpt$kotlinOut - $protoFile - """ - ) - ) - } - - doLast { - project.sync { - from(workingDir) - into(outDir) - } - project.delete(workingDir) - } - } - - project.tasks.assemble { dependsOn(pbCompileTask) } - - } - - /** Setup source dirs */ - private fun configureIntelliJ(project: Project) { - - val genSrcDir = project.layout.buildDirectory.dir("protobuf/generated-sources") - val ktGenSrc = genSrcDir.map { it.dir("kotlin") } - val jGenSrc = genSrcDir.map { it.dir("java") } - - project.mkdir(ktGenSrc) - - project.extensions.findByType()?.apply { - project.logger.lifecycle("-------\nadding generated sources $ktGenSrc\n-------") - - project.sourceSets.named("main") { - this.java.srcDir(ktGenSrc) - this.java.srcDir(jGenSrc) - } - -// sourceSets.main.get().kotlin.srcDir(ktGenSrc) - -// sourceSets.main.configure { -// this.kotlin.srcDir(ktGenSrc) -// } - } - - project.plugins.withType { - project.extensions.configure { - this.module.generatedSourceDirs.add(ktGenSrc.get().asFile) - this.module.generatedSourceDirs.add(jGenSrc.get().asFile) - } - } - - - /** - * IntelliJ requires source dirs are configured first. - * - * https://github.com/google/protobuf-gradle-plugin/blob/master/src/main/groovy/com/google/protobuf/gradle/Utils.groovy#L128 - */ - project.tasks.withType { - doFirst { - project.mkdir(ktGenSrc) - } - } - } +tasks.protobufCompile { + protoFile.set(layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto")) } - -abstract class ProtocPluginConfig(private val project: Project) { - - val protocWorkingDir: DirectoryProperty = - project.objects.directoryProperty() - .convention(project.rootProject.layout.projectDirectory.dir(".gradle/protoc")) - - val protocVersion: Property = - project.objects.property(String::class).convention("3.19.1") - - val protocGroup: Property = - project.objects.property(String::class).convention("com.google.protobuf") - - val protocArtifactName: Property = - project.objects.property(String::class).convention("protoc") - - val protocArtifactExtension: Property = - project.objects.property(String::class).convention("exe") - - val operatingSystemProvider: Property> = - project.objects.property>() - .convention { DefaultNativePlatform.getCurrentOperatingSystem() } - - /** - * Should return one of - * - * * `linux` - * * `osx` - * * `windows` - */ - val operatingSystemName: Property = - project.objects - .property() - .convention(operatingSystemProvider.map { it.get().toFamilyName() }) - - private val architectureProvider: Provider = - project.provider { DefaultNativePlatform.getCurrentArchitecture() } - - /** - * Should return one of - * - * * `aarch_64` - * * `ppcle_64` - * * `x86_32` - * * `x86_64` - */ - val architectureName: Property = - project.objects - .property() - .convention(architectureProvider.map { it.name.replace("-", "_") }) - - private val classifierProvider: Provider = - project.provider { "${operatingSystemName.get()}-${architectureName.get()}" } - - /** - * Default: concatenate [osFamilyNameProvider] and [architectureProvider] - * - * Should return one of: - * - * * `linux-aarch_64` - * * `linux-ppcle_64` - * * `linux-x86_64` - * * `osx-x86_32` - * * `osx-x86_64` - * * `windows-x86_32` - */ - val classifier: Property = - project.objects - .property() - .convention(classifierProvider) - - - private val dependencyProvider: Provider = - project.provider { - project.dependencies.create( - group = protocGroup.get(), - name = protocArtifactName.get(), - version = protocVersion.get(), - classifier = classifierProvider.get(), - ext = protocArtifactExtension.get(), - ) - } - - val dependency: Property = - project.objects - .property() - .convention(dependencyProvider) - -} - -abstract class ProtocPrepareTask : DefaultTask() { - - @Internal - val protocPluginConfig: Provider = project.provider { - project.extensions.getByType() - } - - @get:OutputDirectory - val outputDirectory: DirectoryProperty = project.objects.directoryProperty() - .convention(protocPluginConfig.flatMap { it.protocWorkingDir }) - - @Internal - val protocOutput: RegularFileProperty = project.objects.fileProperty() - - @Internal - val protocDependency: Provider = - protocPluginConfig.flatMap { it.dependency } - - init { - super.setGroup("protobuf") - outputs.dir(outputDirectory) - } - - @TaskAction - fun action() { - - val protocDep: Configuration = project.configurations.create("protoc") { - isVisible = false - isCanBeConsumed = false - isCanBeResolved = true - isTransitive = false - - defaultDependencies { - add(protocDependency.get()) - } - } - - logger.lifecycle("Downloading protoc") - val resolvedProtocDep = protocDep.singleFile - logger.lifecycle("Downloaded $resolvedProtocDep") - - project.sync { - from(resolvedProtocDep) - into(outputDirectory) - logger.lifecycle("Syncing from $resolvedProtocDep to ${outputDirectory.asFile.get().canonicalPath}") - protocOutput.set(outputDirectory.asFileTree.singleFile) - } - } -} - -abstract class ProtocGenerationTask : DefaultTask() { - - @TaskAction - fun generate() { - logger.lifecycle("generating protoc...") - } - -} - -apply() - -configure { -} - - -val logSS = tasks.create("logSourceSets") { - group = "protobuf" - - doLast { - sourceSets.forEach { set -> - logger.lifecycle("SourceSet name: ${set.name}") - set.allSource.forEach { src -> - logger.lifecycle("location: ${src.toRelativeString(rootProject.projectDir)}") - } - } - - logger.lifecycle("-------\nIdeaModel generated source dirs: ${project.idea.module.generatedSourceDirs.joinToString()}\n-------") - } -} - -tasks.named("protobufCompile") { finalizedBy(logSS) } - From 2920f2fcc2a4b9f6bf600faf082b8ba10b77d087 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sun, 31 Oct 2021 08:53:11 +0100 Subject: [PATCH 065/629] mucking about with idea plugin editing dirs --- modules/mod/build.gradle.kts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index 16c5f5e..70dd20c 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -52,6 +52,18 @@ val tstlTask = tasks.register("typescriptToLua") { } +idea { + module { + sourceDirs.add(layout.projectDirectory.dir("src/main/typescript").asFile) + excludeDirs.add(layout.projectDirectory.dir("src/main/typescript/node_modules").asFile) + resourceDirs.add(layout.projectDirectory.dir("src/main/resources").asFile) + + resourceDirs.add(layout.projectDirectory.dir("infra").asFile) + excludeDirs.add(layout.projectDirectory.dir("infra/factorio-server").asFile) + } +} + + //val typescriptSrc = // project.objects.sourceDirectorySet("typescript", "typescript").apply { // srcDir( From 5bb5f42af0937aff5008d467ecf50a9476ebee3b Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sun, 31 Oct 2021 09:13:41 +0100 Subject: [PATCH 066/629] pb plugin working really really well --- .../gradle/pbandg/pattern/IntelliJPattern.kt | 15 +++++--- .../pattern/KotlinProjectConfiguration.kt | 37 +++++++++++-------- .../adamko/gradle/pbandg/pb-and-g.gradle.kts | 10 +++-- .../{pattern => task}/ProtocPrepareTask.kt | 2 +- .../pbandg/task/options/ProtocOutput.kt | 8 ---- .../build.gradle.kts | 7 ++++ 6 files changed, 45 insertions(+), 34 deletions(-) rename buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/{pattern => task}/ProtocPrepareTask.kt (97%) diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/IntelliJPattern.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/IntelliJPattern.kt index 1624641..4adc9d2 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/IntelliJPattern.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/IntelliJPattern.kt @@ -24,17 +24,22 @@ class IntelliJPattern : Plugin { return } - val genSrcDir = project.layout.buildDirectory.dir("protobuf/generated-sources") - val ktGenSrc = genSrcDir.map { it.dir("kotlin") } - val jGenSrc = genSrcDir.map { it.dir("java") } + val genSrcDir = project.layout.buildDirectory.dir("pbAndG/generated-sources") + val ktGenSrc = genSrcDir.map { it.dir("kotlin").asFile } + val jGenSrc = genSrcDir.map { it.dir("java").asFile } + + val protoSrc = project.layout.projectDirectory.dir("src/main/proto").asFile project.mkdir(ktGenSrc) project.mkdir(jGenSrc) project.plugins.withType { project.extensions.configure { - this.module.generatedSourceDirs.add(ktGenSrc.get().asFile) - this.module.generatedSourceDirs.add(jGenSrc.get().asFile) + module { + generatedSourceDirs.add(ktGenSrc.get()) + generatedSourceDirs.add(jGenSrc.get()) + sourceDirs.add(protoSrc) + } } } diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinProjectConfiguration.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinProjectConfiguration.kt index f30af8c..cdcca3c 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinProjectConfiguration.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinProjectConfiguration.kt @@ -1,39 +1,44 @@ package dev.adamko.gradle.pbandg.pattern -import dev.adamko.gradle.pbandg.task.ProtobufCompileTask import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.tasks.SourceSet -import org.gradle.kotlin.dsl.dependencies +import org.gradle.api.tasks.SourceSetContainer import org.gradle.kotlin.dsl.findByType -import org.gradle.kotlin.dsl.getByName -import org.gradle.kotlin.dsl.withType import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension class KotlinProjectConfiguration : Plugin { override fun apply(project: Project) { addSourceSets(project) - } private fun addSourceSets(project: Project) { project.extensions.findByType()?.apply { - val srcSet = project.extensions.getByName(SourceSet.MAIN_SOURCE_SET_NAME) - - project.tasks - .withType() - .map { it.generatedSources.get() } - .forEach { generatedSourcesDir -> - project.logger.lifecycle("-------\nadding generated sources $generatedSourcesDir\n-------") - - srcSet.java { - srcDir(generatedSourcesDir.dir("java")) - srcDir(generatedSourcesDir.dir("kotlin")) + project.extensions.findByType() + ?.named(SourceSet.MAIN_SOURCE_SET_NAME) + ?.configure { + java { + srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/java")) + srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/kotlin")) } } + +// val srcSet = project.extensions.getByName(SourceSet.MAIN_SOURCE_SET_NAME) +// +// project.tasks +// .withType() +// .map { it.generatedSources.get() } +// .forEach { generatedSourcesDir -> +// project.logger.lifecycle("-------\nadding generated sources $generatedSourcesDir\n-------") +// +// srcSet.java { +// srcDir(generatedSourcesDir.dir("java")) +// srcDir(generatedSourcesDir.dir("kotlin")) +// } +// } } } } diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts index bfb6635..c015322 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts @@ -1,5 +1,7 @@ package dev.adamko.gradle.pbandg +import dev.adamko.gradle.pbandg.pattern.IntelliJPattern +import dev.adamko.gradle.pbandg.pattern.KotlinProjectConfiguration import dev.adamko.gradle.pbandg.settings.PBAndGSettings import dev.adamko.gradle.pbandg.task.ProtobufCompileTask import dev.adamko.gradle.pbandg.task.ProtobufPrepareLibrariesTask @@ -20,11 +22,11 @@ plugins { // val pbSrcSet = project.objects.sourceDirectorySet("protobuf", "protobuf") //if (plugins.hasPlugin(IdeaPlugin::class)) { -// apply(IntelliJPattern()) -//} -//if (plugins.hasPlugin("org.jetbrains.kotlin.jvm")) { -// apply(KotlinProjectConfiguration()) +// IntelliJPattern().apply(project) //} +if (plugins.hasPlugin("org.jetbrains.kotlin.jvm")) { + KotlinProjectConfiguration().apply(project) +} val pbAndGSettings = project.extensions.create(Constants.PBG_SETTINGS_NAME, PBAndGSettings::class, project) diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/ProtocPrepareTask.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtocPrepareTask.kt similarity index 97% rename from buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/ProtocPrepareTask.kt rename to buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtocPrepareTask.kt index 63b7c9e..75445b4 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/ProtocPrepareTask.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtocPrepareTask.kt @@ -1,4 +1,4 @@ -package dev.adamko.gradle.pbandg.pattern +package dev.adamko.gradle.pbandg.task import dev.adamko.gradle.pbandg.settings.PBAndGSettings diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/options/ProtocOutput.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/options/ProtocOutput.kt index 966fab2..a5b33c5 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/options/ProtocOutput.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/options/ProtocOutput.kt @@ -1,10 +1,6 @@ package dev.adamko.gradle.pbandg.task.options -import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir import java.io.Serializable -import org.gradle.api.file.Directory -import org.gradle.api.file.ProjectLayout -import org.gradle.api.provider.Provider interface ProtocOutput : Serializable { @@ -12,10 +8,6 @@ interface ProtocOutput : Serializable { val protocOptions: String val outputDirectoryName: String - fun outputDirectory(layout: ProjectLayout): Provider { - return layout.pbAndGBuildDir.map { it.dir(outputDirectoryName) } - } - data class KotlinOutput( override val protocOptions: String = "lite", override val outputDirectoryName: String = "kotlin", diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index 3dba8ca..4787ac5 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -10,8 +10,15 @@ val buildDir: Directory = layout.buildDirectory.dir(projectId).get() dependencies { protobufLibrary("com.google.protobuf:protobuf-javalite:3.19.1") + + api("com.google.protobuf:protobuf-javalite:3.19.1") + api("com.google.protobuf:protobuf-kotlin-lite:3.19.1") } tasks.protobufCompile { protoFile.set(layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto")) } + +sourceSets { + +} From 6dce641d6b20dcafcd8cd5b5cfe5f53fcfce09ff Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sun, 31 Oct 2021 11:32:27 +0100 Subject: [PATCH 067/629] kotlin multiplatform and proto kind of working? --- .../gradle/pbandg/pattern/IntelliJPattern.kt | 2 +- ...on.kt => KotlinJvmProjectConfiguration.kt} | 22 +-- ...KotlinMultiplatformProjectConfiguration.kt | 61 +++++++++ .../adamko/gradle/pbandg/pb-and-g.gradle.kts | 15 +- .../build.gradle.kts | 129 +++++++++++++++++- .../proto/FactorioServerLogRecord.proto | 0 .../FactorioEvent.kt | 0 .../JsonPrimitiveType.kt | 0 .../{src => xsrc}/main/kotlin/PlayerModel.kt | 0 9 files changed, 207 insertions(+), 22 deletions(-) rename buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/{KotlinProjectConfiguration.kt => KotlinJvmProjectConfiguration.kt} (66%) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt rename modules/factorio-events-data-model/src/{main => }/proto/FactorioServerLogRecord.proto (100%) rename modules/factorio-events-data-model/{src => xsrc}/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt (100%) rename modules/factorio-events-data-model/{src => xsrc}/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt (100%) rename modules/factorio-events-data-model/{src => xsrc}/main/kotlin/PlayerModel.kt (100%) diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/IntelliJPattern.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/IntelliJPattern.kt index 4adc9d2..8749884 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/IntelliJPattern.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/IntelliJPattern.kt @@ -50,4 +50,4 @@ class IntelliJPattern : Plugin { } } -} \ No newline at end of file +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinProjectConfiguration.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinJvmProjectConfiguration.kt similarity index 66% rename from buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinProjectConfiguration.kt rename to buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinJvmProjectConfiguration.kt index cdcca3c..4d0c429 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinProjectConfiguration.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinJvmProjectConfiguration.kt @@ -7,7 +7,7 @@ import org.gradle.api.tasks.SourceSetContainer import org.gradle.kotlin.dsl.findByType import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension -class KotlinProjectConfiguration : Plugin { +class KotlinJvmProjectConfiguration : Plugin { override fun apply(project: Project) { addSourceSets(project) @@ -15,16 +15,18 @@ class KotlinProjectConfiguration : Plugin { private fun addSourceSets(project: Project) { - project.extensions.findByType()?.apply { - - project.extensions.findByType() - ?.named(SourceSet.MAIN_SOURCE_SET_NAME) - ?.configure { - java { - srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/java")) - srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/kotlin")) + project.beforeEvaluate { + extensions.findByType()?.apply { + extensions.findByType() + ?.named(SourceSet.MAIN_SOURCE_SET_NAME) + ?.configure { + java { + srcDir(layout.buildDirectory.dir("pbAndG/generated-sources/java")) + srcDir(layout.buildDirectory.dir("pbAndG/generated-sources/kotlin")) + } } - } + + } // val srcSet = project.extensions.getByName(SourceSet.MAIN_SOURCE_SET_NAME) // diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt new file mode 100644 index 0000000..79845f4 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt @@ -0,0 +1,61 @@ +package dev.adamko.gradle.pbandg.pattern + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.findByType +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension + +class KotlinMultiplatformProjectConfiguration : Plugin { + + override fun apply(project: Project) { + project.afterEvaluate { + addSourceSets(this) + } + } + + private fun addSourceSets(project: Project) { + + project.extensions.findByType()?.apply { + project.logger.lifecycle("Kotlin Multiplatform source sets: ${sourceSets.joinToString { "${it.name} / ${it.kotlin.sourceDirectories.files.joinToString()}" }}") + + sourceSets.whenObjectAdded { + this.name + } +// +// val protoJvm = this.sourceSets.maybeCreate("protoJvm").apply { +// kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/java")) +// kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/kotlin")) +// } +// +// val protoTypescript = this.sourceSets.maybeCreate("protoJvm").apply { +// kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/typescript")) +// } + + this.sourceSets.named("jvmMain").configure { +// dependsOn(protoJvm) + kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/java")) + kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/kotlin")) + } + this.sourceSets.named("jsMain").configure { +// dependsOn(protoTypescript) + kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/typescript")) + } + + project.logger.lifecycle("Kotlin Multiplatform source sets: ${sourceSets.joinToString { "${it.name} / ${it.kotlin.sourceDirectories.files.joinToString()}" }}") + +// +// targets .forEach { +// when (it.platformType){ +// KotlinPlatformType.jvm -> TODO() +// KotlinPlatformType.js -> { +// it.defaultConfigurationName +// } +// KotlinPlatformType.androidJvm -> {} +// KotlinPlatformType.common -> {} +// KotlinPlatformType.native -> {} +// } +// } + + } + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts index c015322..232bbea 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts @@ -1,7 +1,7 @@ package dev.adamko.gradle.pbandg -import dev.adamko.gradle.pbandg.pattern.IntelliJPattern -import dev.adamko.gradle.pbandg.pattern.KotlinProjectConfiguration +import dev.adamko.gradle.pbandg.pattern.KotlinJvmProjectConfiguration +import dev.adamko.gradle.pbandg.pattern.KotlinMultiplatformProjectConfiguration import dev.adamko.gradle.pbandg.settings.PBAndGSettings import dev.adamko.gradle.pbandg.task.ProtobufCompileTask import dev.adamko.gradle.pbandg.task.ProtobufPrepareLibrariesTask @@ -24,8 +24,15 @@ plugins { //if (plugins.hasPlugin(IdeaPlugin::class)) { // IntelliJPattern().apply(project) //} -if (plugins.hasPlugin("org.jetbrains.kotlin.jvm")) { - KotlinProjectConfiguration().apply(project) + +plugins.withId("org.jetbrains.kotlin.jvm") { + logger.info("Configuring Kotlin JVM plugin for PB&G") + KotlinJvmProjectConfiguration().apply(project) +} + +plugins.withId("org.jetbrains.kotlin.multiplatform") { + logger.info("Configuring Kotlin Multiplatform plugin for PB&G") + KotlinMultiplatformProjectConfiguration().apply(project) } val pbAndGSettings = diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index 4787ac5..fac3999 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -1,7 +1,9 @@ plugins { - id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") + id("dev.adamko.factoriowebmap.archetype.base") + kotlin("multiplatform") + +// id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") id("dev.adamko.gradle.pbandg.pb-and-g") - `kotlin-dsl` } val projectId: String by project.extra @@ -10,15 +12,128 @@ val buildDir: Directory = layout.buildDirectory.dir(projectId).get() dependencies { protobufLibrary("com.google.protobuf:protobuf-javalite:3.19.1") - - api("com.google.protobuf:protobuf-javalite:3.19.1") - api("com.google.protobuf:protobuf-kotlin-lite:3.19.1") +// +// api("com.google.protobuf:protobuf-javalite:3.19.1") +// api("com.google.protobuf:protobuf-kotlin-lite:3.19.1") } tasks.protobufCompile { - protoFile.set(layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto")) + protoFile.set(layout.projectDirectory.file("src/proto/FactorioServerLogRecord.proto")) } -sourceSets { +idea { + workspace { + + } +} + +kotlin { + sourceSets.all { + languageSettings.apply { + languageVersion = "1.5" +// enableLanguageFeature("InlineClasses") // language feature name + optIn("kotlin.OptIn") + optIn("kotlin.ExperimentalStdlibApi") + optIn("kotlin.time.ExperimentalTime") + optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") +// progressiveMode = true // false by default + } + } + + // + sourceSets { + val proto by creating { + } + } + // + + // + jvm { + compilations.configureEach { + kotlinOptions { + jvmTarget = "11" + } + } + } + + sourceSets { + val jvmMain by getting { + dependencies { + api("com.google.protobuf:protobuf-javalite:3.19.1") + api("com.google.protobuf:protobuf-kotlin-lite:3.19.1") + } + } + val jvmTest by getting { + } + } + // + + // + js(IR) { + binaries.executable() + browser { + commonWebpackConfig { + cssSupport.enabled = true + } + } + + useCommonJs() + nodejs() + + compilations["main"].apply { + packageJson { + customField( + "scripts", + mapOf( + "build" to "tstl", + "dev" to "tstl --watch", + ) + ) + } + } + + } + + sourceSets { + + val jsMain by getting { + kotlin.srcDir("externals02") +// kotlin.srcDir("externals") + + dependencies { + + val kotlinWrappersVersion = "0.0.1-pre.254-kotlin-1.5.31" + implementation( + project.dependencies.enforcedPlatform( + "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" + ) + ) + +// implementation("org.jetbrains.kotlin-wrappers:kotlin-react") +// implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom") +// implementation(npm("react", "17.0.2")) +// implementation(npm("react-dom", "17.0.2")) + +// implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7") { +// because("https://github.com/Kotlin/kotlinx-nodejs") +// } + +// implementation(npm("typescript-to-lua", "1.0.1")) +// implementation(npm("typed-factorio", "0.7.1")) +// implementation(npm("lua-types", "2.11.0")) +// implementation(npm("typescript", "4.4.3")) + + + implementation(npm("ts-proto", "1.83.3")) + } + } + + val jsTest by getting { + dependencies { + implementation(kotlin("test-js")) + } + } + } + // } diff --git a/modules/factorio-events-data-model/src/main/proto/FactorioServerLogRecord.proto b/modules/factorio-events-data-model/src/proto/FactorioServerLogRecord.proto similarity index 100% rename from modules/factorio-events-data-model/src/main/proto/FactorioServerLogRecord.proto rename to modules/factorio-events-data-model/src/proto/FactorioServerLogRecord.proto diff --git a/modules/factorio-events-data-model/src/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt b/modules/factorio-events-data-model/xsrc/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt similarity index 100% rename from modules/factorio-events-data-model/src/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt rename to modules/factorio-events-data-model/xsrc/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt diff --git a/modules/factorio-events-data-model/src/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt b/modules/factorio-events-data-model/xsrc/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt similarity index 100% rename from modules/factorio-events-data-model/src/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt rename to modules/factorio-events-data-model/xsrc/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt diff --git a/modules/factorio-events-data-model/src/main/kotlin/PlayerModel.kt b/modules/factorio-events-data-model/xsrc/main/kotlin/PlayerModel.kt similarity index 100% rename from modules/factorio-events-data-model/src/main/kotlin/PlayerModel.kt rename to modules/factorio-events-data-model/xsrc/main/kotlin/PlayerModel.kt From 00b3dc35548f7c25a869427e8820632e596d58c3 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sun, 31 Oct 2021 13:57:49 +0100 Subject: [PATCH 068/629] proto2typescript working!!!!!!!!!!!!! --- .../archetype/kotlin-js.gradle.kts | 2 - ...KotlinMultiplatformProjectConfiguration.kt | 22 +++--- .../adamko/gradle/pbandg/pb-and-g.gradle.kts | 15 ++-- .../gradle/pbandg/task/ProtobufCompileTask.kt | 9 ++- .../build.gradle.kts | 68 +++++++++++++++++-- settings.gradle.kts | 2 +- 6 files changed, 91 insertions(+), 27 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts index 6f3e148..49c8445 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts @@ -16,8 +16,6 @@ plugins { id("dev.adamko.factoriowebmap.archetype.node") } - - kotlin { js(IR) { binaries.executable() diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt index 79845f4..3ec370f 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt @@ -22,21 +22,23 @@ class KotlinMultiplatformProjectConfiguration : Plugin { this.name } // -// val protoJvm = this.sourceSets.maybeCreate("protoJvm").apply { -// kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/java")) -// kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/kotlin")) -// } -// -// val protoTypescript = this.sourceSets.maybeCreate("protoJvm").apply { -// kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/typescript")) -// } + val protoJvm = this.sourceSets.maybeCreate("protoJvm").apply { + kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/java")) + kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/kotlin")) + } - this.sourceSets.named("jvmMain").configure { + val protoTypescript = this.sourceSets.maybeCreate("protoJvm").apply { + kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/typescript")) + } + + this.sourceSets.findByName("jvmMain")?.apply { +// protoJvm.dependsOn(this) // dependsOn(protoJvm) kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/java")) kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/kotlin")) } - this.sourceSets.named("jsMain").configure { + this.sourceSets.findByName("jsMain")?.apply { +// protoTypescript.dependsOn(this) // dependsOn(protoTypescript) kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/typescript")) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts index 232bbea..22dadf2 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts @@ -16,7 +16,6 @@ plugins { base } - // TODO investigate builtBy and sourceDirectorySet? // project.objects.fileCollection().builtBy() // val pbSrcSet = project.objects.sourceDirectorySet("protobuf", "protobuf") @@ -77,19 +76,19 @@ val protobufPrepareLibrariesTask = //// implementation("com.google.protobuf:protobuf-kotlin-lite:3.19.1") //} - -/** Convert `.proto` files to Kotlin */ -val pbCompileTask = project.tasks.register(Constants.PBG_TASK_COMPILE) { +project.tasks.withType { dependsOn(protocDep, protobufPrepareLibrariesTask) - protobufLibraryDirectories.add(protobufPrepareLibrariesTask.flatMap { it.librariesDirectory }) - protocOutputs += KotlinOutput() - protocOutputs += JavaOutput() - val exe = protocDep.singleFile logger.lifecycle("protoc.exe: $exe") protocExecutable.set(exe) } +/** Convert `.proto` files to Kotlin */ +val pbCompileTask = project.tasks.register(Constants.PBG_TASK_COMPILE) { + protocOutputs += KotlinOutput() + protocOutputs += JavaOutput() +} + project.tasks.assemble { dependsOn(pbCompileTask) } \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufCompileTask.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufCompileTask.kt index 5ff5ef4..de18e18 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufCompileTask.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufCompileTask.kt @@ -33,6 +33,9 @@ abstract class ProtobufCompileTask : DefaultTask() { abstract val protocOutputs: DomainObjectSet // = project.objects.domainObjectSet(ProtocOutput::class.java) + @get:Input + abstract val cliArgs: ListProperty + @get:InputFile abstract val protoFile: RegularFileProperty @@ -48,7 +51,7 @@ abstract class ProtobufCompileTask : DefaultTask() { fun compile() { val workDir = temporaryDir - project.delete(workDir) +// project.delete(workDir) project.exec { executable(protocExecutable.asFile.get()) @@ -65,9 +68,11 @@ abstract class ProtobufCompileTask : DefaultTask() { // set args mapOutputsToOutputDir .map { (opt, dir) -> - "${opt.cliParam}=${opt.protocOptions}:${dir}" + val optionsSuffix = if (opt.protocOptions.isBlank()) "" else ":" + "${opt.cliParam}=${opt.protocOptions}$optionsSuffix$dir" } .also { args(it) } + args(cliArgs.get()) val protoPath = cliParamProtoPath.get() val libArgs = protobufLibraryDirectories.get().map { "$protoPath${it.asFile}" } diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index fac3999..1c1372b 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -1,3 +1,7 @@ +import dev.adamko.gradle.pbandg.task.ProtobufCompileTask +import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject +import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask + plugins { id("dev.adamko.factoriowebmap.archetype.base") kotlin("multiplatform") @@ -17,10 +21,6 @@ dependencies { // api("com.google.protobuf:protobuf-kotlin-lite:3.19.1") } -tasks.protobufCompile { - protoFile.set(layout.projectDirectory.file("src/proto/FactorioServerLogRecord.proto")) -} - idea { workspace { @@ -36,6 +36,7 @@ kotlin { optIn("kotlin.ExperimentalStdlibApi") optIn("kotlin.time.ExperimentalTime") optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") + optIn("kotlin.js.ExperimentalJsExport") // progressiveMode = true // false by default } } @@ -137,3 +138,62 @@ kotlin { // } + +//rootProject.tasks.withType().configureEach { +//} + +val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) +val nodePath: Directory by extra { + val file = rootPackageJson.rootPackageJson.parentFile.normalize() + logger.lifecycle("Kotlin/JS NODE_PATH: $file") + project.layout.dir(provider { file }).get() +} + +val nodeModulesDir: Directory by extra { + val file = nodePath.dir(NpmProject.NODE_MODULES) + logger.lifecycle("Kotlin/JS NODE_MODULES: $file") + file +} + +// build/js/node_modules/ts-proto/node_modules/.bin + +tasks.protobufCompile { + description = "proto2java" + protoFile.set(layout.projectDirectory.file("src/proto/FactorioServerLogRecord.proto")) +} + + +tasks.create("protobufTypescript") { + description = "proto2typescript" + +// data class PluginTs( +// override val cliParam: String = "--plugin", +// override val protocOptions: String = "", +// override val outputDirectoryName: String = +// "${project.buildDir}/js/packages/factorio-web-map-factorio-events-data-model/node_modules/.bin/protoc-gen-ts_proto.cmd", +// ) : ProtocOutput +// +// +// data class OutputTs( +// override val cliParam: String = "--ts_proto_out", +// override val protocOptions: String = "", +// override val outputDirectoryName: String = "${project.buildDir}/pbAndG/generated-sources/typescript", +// ) : ProtocOutput +// +// protocOutputs.add(PluginTs()) +// protocOutputs.add(OutputTs()) + + +// cliArgs.add("--plugin=${rootProject.buildDir}/js/packages/factorio-web-map-factorio-events-data-model/node_modules/.bin/protoc-gen-ts_proto.cmd") + + cliArgs.add("--plugin=protoc-gen-ts_proto=${rootProject.buildDir}/js/packages/factorio-web-map-factorio-events-data-model/node_modules/.bin/protoc-gen-ts_proto.cmd") + + val outdir = temporaryDir.resolve("typescript") + val f: File = project.mkdir(outdir) + + cliArgs.add("--ts_proto_out=${outdir.canonicalPath}") + cliArgs.add("--ts_proto_opt=useOptionals=true") +// cliArgs.add("--proto_path=${rootProject.rootDir}") + + protoFile.set(layout.projectDirectory.file("src/proto/FactorioServerLogRecord.proto")) +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 30886cb..b1206d7 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -6,7 +6,7 @@ rootProject.name = "factorio-web-map" include( ":modules:mod", // ":modules:mod2", - ":modules:server", +// ":modules:server", ":modules:kt-rcon", ":modules:factorio-events-data-model", // ":modules:factorio-events-data-model2", From ac8428f36dabb41f0db0c55a23936960e611555b Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Tue, 2 Nov 2021 23:22:30 +0100 Subject: [PATCH 069/629] properly generate and collect and create source sets for jvm+kt+ts (but kotlin multiplatform js doesn't work????) todo: clean up this is really messy --- build.gradle.kts | 7 - ...KotlinMultiplatformProjectConfiguration.kt | 47 ++-- .../adamko/gradle/pbandg/pb-and-g.gradle.kts | 43 ++-- .../gradle/pbandg/task/ProtobufCompileTask.kt | 126 +++-------- .../build.gradle.kts | 214 +++++++----------- .../src/proto/FactorioServerLogRecord.proto | 10 +- 6 files changed, 167 insertions(+), 280 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index b632a30..7cdb0ce 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,13 +1,6 @@ plugins { idea base - -// val kotlinVersion = "1.5.31" -// kotlin("jvm") version kotlinVersion apply false -// kotlin("js") version kotlinVersion apply false -// kotlin("multiplatform") version kotlinVersion apply false - -// id("com.github.node-gradle.node") version "3.1.1" apply false } group = "dev.adamko.factoriowebmap" diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt index 3ec370f..a28809f 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt @@ -1,5 +1,6 @@ package dev.adamko.gradle.pbandg.pattern +import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.findByType @@ -18,30 +19,36 @@ class KotlinMultiplatformProjectConfiguration : Plugin { project.extensions.findByType()?.apply { project.logger.lifecycle("Kotlin Multiplatform source sets: ${sourceSets.joinToString { "${it.name} / ${it.kotlin.sourceDirectories.files.joinToString()}" }}") - sourceSets.whenObjectAdded { - this.name +// sourceSets.whenObjectAdded { +// this.name +// } +// + val jvmProto = this.sourceSets.maybeCreate("jvmProto").apply { + + kotlin.srcDir(project.layout.pbAndGBuildDir.get().dir("generated-sources/java")) + kotlin.srcDir(project.layout.pbAndGBuildDir.get().dir("generated-sources/kotlin")) + + dependsOn(sourceSets.maybeCreate("jvmMain")) } // - val protoJvm = this.sourceSets.maybeCreate("protoJvm").apply { - kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/java")) - kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/kotlin")) + val tsProto = this.sourceSets.maybeCreate("tsProto").apply { + + kotlin.srcDir(project.layout.pbAndGBuildDir.get().dir("generated-sources/typescript")) + + dependsOn(sourceSets.maybeCreate("jsMain")) } - val protoTypescript = this.sourceSets.maybeCreate("protoJvm").apply { - kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/typescript")) - } - - this.sourceSets.findByName("jvmMain")?.apply { -// protoJvm.dependsOn(this) -// dependsOn(protoJvm) - kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/java")) - kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/kotlin")) - } - this.sourceSets.findByName("jsMain")?.apply { -// protoTypescript.dependsOn(this) -// dependsOn(protoTypescript) - kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/typescript")) - } +// this.sourceSets.findByName("jvmMain")?.apply { +//// protoJvm.dependsOn(this) +//// dependsOn(protoJvm) +// kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/java")) +// kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/kotlin")) +// } +// this.sourceSets.findByName("jsMain")?.apply { +//// protoTypescript.dependsOn(this) +//// dependsOn(protoTypescript) +// kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/typescript")) +// } project.logger.lifecycle("Kotlin Multiplatform source sets: ${sourceSets.joinToString { "${it.name} / ${it.kotlin.sourceDirectories.files.joinToString()}" }}") diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts index 22dadf2..2c3132b 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts @@ -1,16 +1,11 @@ package dev.adamko.gradle.pbandg +import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir import dev.adamko.gradle.pbandg.pattern.KotlinJvmProjectConfiguration import dev.adamko.gradle.pbandg.pattern.KotlinMultiplatformProjectConfiguration import dev.adamko.gradle.pbandg.settings.PBAndGSettings import dev.adamko.gradle.pbandg.task.ProtobufCompileTask import dev.adamko.gradle.pbandg.task.ProtobufPrepareLibrariesTask -import dev.adamko.gradle.pbandg.task.options.ProtocOutput.JavaOutput -import dev.adamko.gradle.pbandg.task.options.ProtocOutput.KotlinOutput - -//plugins { -// `kotlin-dsl` -//} plugins { base @@ -63,6 +58,9 @@ project.dependencies { protobufLibraryDependencies("com.google.protobuf:protobuf-javalite:3.19.1") // implementation("com.google.protobuf:protobuf-javalite:3.19.1") // implementation("com.google.protobuf:protobuf-kotlin-lite:3.19.1") +// protobufLibraryDependencies("com.google.protobuf:protobuf-javalite:3.19.1") +//// implementation("com.google.protobuf:protobuf-javalite:3.19.1") +//// implementation("com.google.protobuf:protobuf-kotlin-lite:3.19.1") } val protobufPrepareLibrariesTask = @@ -70,12 +68,6 @@ val protobufPrepareLibrariesTask = librarySources.set(protobufLibraryDependencies) } -//project.dependencies { -// protobufLibraryDependencies("com.google.protobuf:protobuf-javalite:3.19.1") -//// implementation("com.google.protobuf:protobuf-javalite:3.19.1") -//// implementation("com.google.protobuf:protobuf-kotlin-lite:3.19.1") -//} - project.tasks.withType { dependsOn(protocDep, protobufPrepareLibrariesTask) protobufLibraryDirectories.add(protobufPrepareLibrariesTask.flatMap { it.librariesDirectory }) @@ -85,10 +77,25 @@ project.tasks.withType { protocExecutable.set(exe) } -/** Convert `.proto` files to Kotlin */ -val pbCompileTask = project.tasks.register(Constants.PBG_TASK_COMPILE) { - protocOutputs += KotlinOutput() - protocOutputs += JavaOutput() -} +val aggregateTask = project.tasks.register("protobufCompileAll") { + group = Constants.PBG_TASK_GROUP + + dependsOn(tasks.withType()) + + val genSrcDir = project.layout.pbAndGBuildDir.map { it.dir("generated-sources") } + + val pbCompileTasks = tasks.withType() + from(pbCompileTasks.map { it.temporaryDir }) + into(genSrcDir) + includeEmptyDirs = false + +} +//project.tasks.assemble { dependsOn(aggregateTask) } + + +///** Convert `.proto` files to Kotlin */ +//val pbCompileTask = project.tasks.create("protobufJava") { +// protocOutputs += KotlinOutput() +// protocOutputs += JavaOutput() +//} -project.tasks.assemble { dependsOn(pbCompileTask) } \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufCompileTask.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufCompileTask.kt index de18e18..bf9b84f 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufCompileTask.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufCompileTask.kt @@ -1,36 +1,32 @@ package dev.adamko.gradle.pbandg.task import dev.adamko.gradle.pbandg.Constants -import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir -import dev.adamko.gradle.pbandg.task.options.ProtocOutput import org.gradle.api.DefaultTask -import org.gradle.api.DomainObjectSet import org.gradle.api.file.Directory -import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFile import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.Internal import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction import org.gradle.kotlin.dsl.property +import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir + abstract class ProtobufCompileTask : DefaultTask() { @get:InputFile abstract val protocExecutable: RegularFileProperty - @get:OutputDirectory - val generatedSources: DirectoryProperty = project.objects.directoryProperty() - .convention(project.pbAndGBuildDir.map { it.dir("generated-sources") }) - @get:InputFiles abstract val protobufLibraryDirectories: ListProperty - @get:Input - abstract val protocOutputs: DomainObjectSet +// @get:Input +// abstract val protocOutputs: DomainObjectSet // = project.objects.domainObjectSet(ProtocOutput::class.java) @get:Input @@ -43,35 +39,37 @@ abstract class ProtobufCompileTask : DefaultTask() { val cliParamProtoPath: Property = project.objects.property().convention("--proto_path=") + @get:OutputDirectory + val outputDir: RegularFileProperty = + project.objects.fileProperty().convention { temporaryDir } + +// @get:Internal +// val outputPath: Provider = outputDir.map { it.asFile.canonicalPath } + init { group = Constants.PBG_TASK_GROUP } @TaskAction fun compile() { - - val workDir = temporaryDir -// project.delete(workDir) + // prepare directories + project.mkdir(outputDir) project.exec { executable(protocExecutable.asFile.get()) - workingDir(workDir) + workingDir(outputDir.asFile.get()) - // prepare directories - project.mkdir(workingDir) - project.mkdir(generatedSources) - - val mapOutputsToOutputDir = - protocOutputs.associateWith { workingDir.resolve(it.outputDirectoryName) } - mapOutputsToOutputDir.values.forEach { project.mkdir(it) } - - // set args - mapOutputsToOutputDir - .map { (opt, dir) -> - val optionsSuffix = if (opt.protocOptions.isBlank()) "" else ":" - "${opt.cliParam}=${opt.protocOptions}$optionsSuffix$dir" - } - .also { args(it) } +// val mapOutputsToOutputDir = +// protocOutputs.associateWith { outputDir.get().asFile.resolve(it.outputDirectoryName) } +// mapOutputsToOutputDir.values.forEach { project.mkdir(it) } +// +// // set args +// mapOutputsToOutputDir +// .map { (opt, dir) -> +// val optionsSuffix = if (opt.protocOptions.isBlank()) "" else ":" +// "${opt.cliParam}=${opt.protocOptions}$optionsSuffix$dir" +// } +// .also { args(it) } args(cliArgs.get()) val protoPath = cliParamProtoPath.get() @@ -83,76 +81,6 @@ abstract class ProtobufCompileTask : DefaultTask() { args("$targetProtoFile") } - // sync compiled files - project.sync { - from(workDir) - into(generatedSources) - includeEmptyDirs = false - } - - // clean up temp-dir - project.delete(workDir) } } - -/* - -{ - group = "protobuf" - dependsOn(protobufCompiler, protoLibsTask) - - standardOutput = System.out - - executable(protobufCompiler.singleFile) - workingDir(temporaryDirFactory) - - val outDir = project.layout.buildDirectory.dir("protobuf/generated-sources") - outputs.dir(outDir) - - val protoLibsDir: Provider = protoLibsTask.map { it.destinationDir } - - val javaOut = workingDir.resolve("java") - val kotlinOut = workingDir.resolve("kotlin") - val protoFile by project.objects.fileProperty() - .convention(project.layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto")) - - val protoFileParent = project.provider { protoFile.asFile.parentFile } - - val isLiteEnabled: Boolean by project.objects.property().convention(true) - - doFirst { - project.delete(workingDir) - - project.mkdir(outDir) - project.mkdir(javaOut) - project.mkdir(kotlinOut) - - val liteOpt: String = when (isLiteEnabled) { - true -> "lite:" - false -> "" - } - - args( - parseSpaceSeparatedArgs( - """ - --proto_path=${protoLibsDir.get()} - --proto_path=${protoFileParent.get()} - --java_out=$liteOpt$javaOut - --kotlin_out=$liteOpt$kotlinOut - $protoFile - """ - ) - ) - } - - doLast { - project.sync { - from(workingDir) - into(outDir) - } - project.delete(workingDir) - } -} - - */ \ No newline at end of file diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index 1c1372b..eefa406 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -1,6 +1,6 @@ import dev.adamko.gradle.pbandg.task.ProtobufCompileTask -import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject -import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask +//import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject +//import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask plugins { id("dev.adamko.factoriowebmap.archetype.base") @@ -21,31 +21,25 @@ dependencies { // api("com.google.protobuf:protobuf-kotlin-lite:3.19.1") } -idea { - workspace { - - } -} - kotlin { - sourceSets.all { - languageSettings.apply { - languageVersion = "1.5" -// enableLanguageFeature("InlineClasses") // language feature name - optIn("kotlin.OptIn") - optIn("kotlin.ExperimentalStdlibApi") - optIn("kotlin.time.ExperimentalTime") - optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") - optIn("kotlin.js.ExperimentalJsExport") -// progressiveMode = true // false by default - } - } +// sourceSets.all { +// languageSettings.apply { +// languageVersion = "1.5" +//// enableLanguageFeature("InlineClasses") // language feature name +// optIn("kotlin.OptIn") +// optIn("kotlin.ExperimentalStdlibApi") +// optIn("kotlin.time.ExperimentalTime") +// optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") +// optIn("kotlin.js.ExperimentalJsExport") +//// progressiveMode = true // false by default +// } +// } // - sourceSets { - val proto by creating { - } - } +// sourceSets { +// val proto by creating { +// } +// } // // @@ -57,6 +51,22 @@ kotlin { } } + // + + // +// js(IR) { +// binaries.executable() +//// browser { +////// commonWebpackConfig { +////// cssSupport.enabled = true +////// } +//// } +// +// useCommonJs() +// nodejs() +// +// } + sourceSets { val jvmMain by getting { dependencies { @@ -66,74 +76,18 @@ kotlin { } val jvmTest by getting { } - } - // - // - js(IR) { - binaries.executable() - browser { - commonWebpackConfig { - cssSupport.enabled = true - } - } - - useCommonJs() - nodejs() - - compilations["main"].apply { - packageJson { - customField( - "scripts", - mapOf( - "build" to "tstl", - "dev" to "tstl --watch", - ) - ) - } - } - - } - - sourceSets { - - val jsMain by getting { - kotlin.srcDir("externals02") -// kotlin.srcDir("externals") - - dependencies { - - val kotlinWrappersVersion = "0.0.1-pre.254-kotlin-1.5.31" - implementation( - project.dependencies.enforcedPlatform( - "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" - ) - ) - -// implementation("org.jetbrains.kotlin-wrappers:kotlin-react") -// implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom") -// implementation(npm("react", "17.0.2")) -// implementation(npm("react-dom", "17.0.2")) - -// implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7") { -// because("https://github.com/Kotlin/kotlinx-nodejs") -// } - -// implementation(npm("typescript-to-lua", "1.0.1")) -// implementation(npm("typed-factorio", "0.7.1")) -// implementation(npm("lua-types", "2.11.0")) -// implementation(npm("typescript", "4.4.3")) - - - implementation(npm("ts-proto", "1.83.3")) - } - } - - val jsTest by getting { - dependencies { - implementation(kotlin("test-js")) - } - } +// val jsMain by getting { +// dependencies { +// implementation(npm("ts-proto", "1.83.3")) +// } +// } +// +// val jsTest by getting { +// dependencies { +// implementation(kotlin("test-js")) +// } +// } } // @@ -142,58 +96,56 @@ kotlin { //rootProject.tasks.withType().configureEach { //} -val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) -val nodePath: Directory by extra { - val file = rootPackageJson.rootPackageJson.parentFile.normalize() - logger.lifecycle("Kotlin/JS NODE_PATH: $file") - project.layout.dir(provider { file }).get() -} - -val nodeModulesDir: Directory by extra { - val file = nodePath.dir(NpmProject.NODE_MODULES) - logger.lifecycle("Kotlin/JS NODE_MODULES: $file") - file -} +//val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) +//val nodePath: Directory by extra { +// val file = rootPackageJson.rootPackageJson.parentFile.normalize() +// logger.lifecycle("Kotlin/JS NODE_PATH: $file") +// project.layout.dir(provider { file }).get() +//} +// +//val nodeModulesDir: Directory by extra { +// val file = nodePath.dir(NpmProject.NODE_MODULES) +// logger.lifecycle("Kotlin/JS NODE_MODULES: $file") +// file +//} // build/js/node_modules/ts-proto/node_modules/.bin - -tasks.protobufCompile { +// +tasks.register("protobufJava") { description = "proto2java" - protoFile.set(layout.projectDirectory.file("src/proto/FactorioServerLogRecord.proto")) + protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto")) + + cliArgs.add("--java_out=lite:${project.mkdir("$temporaryDir/java").canonicalPath}") } +tasks.create("protobufKotlin") { + description = "proto2kotlin" + protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto")) + + cliArgs.add("--kotlin_out=lite:${project.mkdir("$temporaryDir/kotlin").canonicalPath}") +} tasks.create("protobufTypescript") { description = "proto2typescript" -// data class PluginTs( -// override val cliParam: String = "--plugin", -// override val protocOptions: String = "", -// override val outputDirectoryName: String = -// "${project.buildDir}/js/packages/factorio-web-map-factorio-events-data-model/node_modules/.bin/protoc-gen-ts_proto.cmd", -// ) : ProtocOutput -// -// -// data class OutputTs( -// override val cliParam: String = "--ts_proto_out", -// override val protocOptions: String = "", -// override val outputDirectoryName: String = "${project.buildDir}/pbAndG/generated-sources/typescript", -// ) : ProtocOutput -// -// protocOutputs.add(PluginTs()) -// protocOutputs.add(OutputTs()) - - + // linux: // cliArgs.add("--plugin=${rootProject.buildDir}/js/packages/factorio-web-map-factorio-events-data-model/node_modules/.bin/protoc-gen-ts_proto.cmd") - + // windows: cliArgs.add("--plugin=protoc-gen-ts_proto=${rootProject.buildDir}/js/packages/factorio-web-map-factorio-events-data-model/node_modules/.bin/protoc-gen-ts_proto.cmd") - val outdir = temporaryDir.resolve("typescript") - val f: File = project.mkdir(outdir) + cliArgs.add("--ts_proto_out=${project.mkdir("$temporaryDir/typescript").canonicalPath}") - cliArgs.add("--ts_proto_out=${outdir.canonicalPath}") - cliArgs.add("--ts_proto_opt=useOptionals=true") -// cliArgs.add("--proto_path=${rootProject.rootDir}") + cliArgs.addAll( + "--ts_proto_opt=useOptionals=true", + "--ts_proto_opt=outputServices=false", + "--ts_proto_opt=outputJsonMethods=false", + "--ts_proto_opt=outputEncodeMethods=false", + "--ts_proto_opt=forceLong=string", + "--ts_proto_opt=forceLong=number", + "--ts_proto_opt=esModuleInterop=true", + "--ts_proto_opt=exportCommonSymbols=false", +// "--proto_path=${rootProject.rootDir}", + ) - protoFile.set(layout.projectDirectory.file("src/proto/FactorioServerLogRecord.proto")) + protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto")) } diff --git a/modules/factorio-events-data-model/src/proto/FactorioServerLogRecord.proto b/modules/factorio-events-data-model/src/proto/FactorioServerLogRecord.proto index 906f31a..02d37ad 100644 --- a/modules/factorio-events-data-model/src/proto/FactorioServerLogRecord.proto +++ b/modules/factorio-events-data-model/src/proto/FactorioServerLogRecord.proto @@ -5,8 +5,8 @@ option java_multiple_files = true; package dev.adamko.factorioevents; -import "google/protobuf/any.proto"; -import "google/protobuf/timestamp.proto"; +//import "google/protobuf/any.proto"; +//import "google/protobuf/timestamp.proto"; message FactorioServerLogRecord { string mod_version = 1; @@ -54,7 +54,7 @@ message LuaPlayer { // https://lua-api.factorio.com/next/LuaEntity.html message LuaEntity { - uint32 unit_number = 1; // (optional) unique ID + optional uint32 unit_number = 1; // (optional) unique ID string name = 2; string type = 3; string status = 4; // https://lua-api.factorio.com/next/defines.html#defines.entity_status @@ -62,8 +62,8 @@ message LuaEntity { bool is_active = 8; bool is_moving = 9; - uint32 player_index = 50; // (optional) The player connected to this character or nil if none. - uint32 last_user_index = 51; // (optional) The last player that changed any setting on this entity. + optional uint32 player_index = 50; // (optional) The player connected to this character or nil if none. + optional uint32 last_user_index = 51; // (optional) The last player that changed any setting on this entity. Colour colour = 100; // (optional) } From 96d8ceda2c3dcdccaa030060862049ec81ece073 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 3 Nov 2021 09:48:30 +0100 Subject: [PATCH 070/629] jvm+kt+ts code gen working --- buildSrc/build.gradle.kts | 5 + ...KotlinMultiplatformProjectConfiguration.kt | 8 +- .../adamko/gradle/pbandg/pb-and-g.gradle.kts | 51 ++--- .../build.gradle.kts | 182 ++++++++---------- 4 files changed, 108 insertions(+), 138 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index dba2d23..1c9ab46 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -24,6 +24,11 @@ dependencies { } tasks.withType().configureEach { + + kotlinOptions { + jvmTarget = "11" + } + kotlinOptions.freeCompilerArgs += listOf( "-Xopt-in=kotlin.OptIn", "-Xopt-in=kotlin.ExperimentalStdlibApi", diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt index a28809f..99b5f4d 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt @@ -10,7 +10,7 @@ class KotlinMultiplatformProjectConfiguration : Plugin { override fun apply(project: Project) { project.afterEvaluate { - addSourceSets(this) + addSourceSets(project) } } @@ -19,10 +19,6 @@ class KotlinMultiplatformProjectConfiguration : Plugin { project.extensions.findByType()?.apply { project.logger.lifecycle("Kotlin Multiplatform source sets: ${sourceSets.joinToString { "${it.name} / ${it.kotlin.sourceDirectories.files.joinToString()}" }}") -// sourceSets.whenObjectAdded { -// this.name -// } -// val jvmProto = this.sourceSets.maybeCreate("jvmProto").apply { kotlin.srcDir(project.layout.pbAndGBuildDir.get().dir("generated-sources/java")) @@ -55,7 +51,7 @@ class KotlinMultiplatformProjectConfiguration : Plugin { // // targets .forEach { // when (it.platformType){ -// KotlinPlatformType.jvm -> TODO() +// KotlinPlatformType.jvm -> {} // KotlinPlatformType.js -> { // it.defaultConfigurationName // } diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts index 2c3132b..a19e654 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts @@ -1,8 +1,6 @@ package dev.adamko.gradle.pbandg import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir -import dev.adamko.gradle.pbandg.pattern.KotlinJvmProjectConfiguration -import dev.adamko.gradle.pbandg.pattern.KotlinMultiplatformProjectConfiguration import dev.adamko.gradle.pbandg.settings.PBAndGSettings import dev.adamko.gradle.pbandg.task.ProtobufCompileTask import dev.adamko.gradle.pbandg.task.ProtobufPrepareLibrariesTask @@ -19,21 +17,21 @@ plugins { // IntelliJPattern().apply(project) //} -plugins.withId("org.jetbrains.kotlin.jvm") { - logger.info("Configuring Kotlin JVM plugin for PB&G") - KotlinJvmProjectConfiguration().apply(project) -} - -plugins.withId("org.jetbrains.kotlin.multiplatform") { - logger.info("Configuring Kotlin Multiplatform plugin for PB&G") - KotlinMultiplatformProjectConfiguration().apply(project) -} +//plugins.withId("org.jetbrains.kotlin.jvm") { +// logger.info("Configuring Kotlin JVM plugin for PB&G") +// KotlinJvmProjectConfiguration().apply(project) +//} +// +//plugins.withId("org.jetbrains.kotlin.multiplatform") { +// logger.info("Configuring Kotlin Multiplatform plugin for PB&G") +// KotlinMultiplatformProjectConfiguration().apply(project) +//} val pbAndGSettings = project.extensions.create(Constants.PBG_SETTINGS_NAME, PBAndGSettings::class, project) //val protocDep = ProtobufCompilerDependency(project, pbAndGSettings) -val protocDep = project.configurations.create("protobufCompiler") { +val protocDep: Configuration = project.configurations.create("protobufCompiler") { this.description = "Define a single dependency that provides the protoc.exe for this system" isVisible = false isCanBeConsumed = false @@ -53,14 +51,10 @@ val protobufLibraryDependencies: Configuration = isTransitive = false } - project.dependencies { - protobufLibraryDependencies("com.google.protobuf:protobuf-javalite:3.19.1") -// implementation("com.google.protobuf:protobuf-javalite:3.19.1") -// implementation("com.google.protobuf:protobuf-kotlin-lite:3.19.1") -// protobufLibraryDependencies("com.google.protobuf:protobuf-javalite:3.19.1") -//// implementation("com.google.protobuf:protobuf-javalite:3.19.1") -//// implementation("com.google.protobuf:protobuf-kotlin-lite:3.19.1") + protobufLibraryDependencies("com.google.protobuf:protobuf-javalite:3.19.1") { + because("This dep contains common Google .proto files that will be extracted") + } } val protobufPrepareLibrariesTask = @@ -73,7 +67,7 @@ project.tasks.withType { protobufLibraryDirectories.add(protobufPrepareLibrariesTask.flatMap { it.librariesDirectory }) val exe = protocDep.singleFile - logger.lifecycle("protoc.exe: $exe") + logger.debug("Configuring Protobuf task with protoc.exe: $exe") protocExecutable.set(exe) } @@ -84,18 +78,11 @@ val aggregateTask = project.tasks.register("protobufCompileAll") { val genSrcDir = project.layout.pbAndGBuildDir.map { it.dir("generated-sources") } - val pbCompileTasks = tasks.withType() - from(pbCompileTasks.map { it.temporaryDir }) - into(genSrcDir) - includeEmptyDirs = false + val pbCompileTasks = tasks.withType() + from(pbCompileTasks.map { it.temporaryDir }) + into(genSrcDir) + includeEmptyDirs = false } -//project.tasks.assemble { dependsOn(aggregateTask) } - - -///** Convert `.proto` files to Kotlin */ -//val pbCompileTask = project.tasks.create("protobufJava") { -// protocOutputs += KotlinOutput() -// protocOutputs += JavaOutput() -//} +project.tasks.assemble { dependsOn(aggregateTask) } diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index eefa406..04727f0 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -1,46 +1,18 @@ import dev.adamko.gradle.pbandg.task.ProtobufCompileTask -//import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject -//import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask +import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject +import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask plugins { id("dev.adamko.factoriowebmap.archetype.base") kotlin("multiplatform") -// id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") id("dev.adamko.gradle.pbandg.pb-and-g") } val projectId: String by project.extra val buildDir: Directory = layout.buildDirectory.dir(projectId).get() - -dependencies { - protobufLibrary("com.google.protobuf:protobuf-javalite:3.19.1") -// -// api("com.google.protobuf:protobuf-javalite:3.19.1") -// api("com.google.protobuf:protobuf-kotlin-lite:3.19.1") -} - kotlin { -// sourceSets.all { -// languageSettings.apply { -// languageVersion = "1.5" -//// enableLanguageFeature("InlineClasses") // language feature name -// optIn("kotlin.OptIn") -// optIn("kotlin.ExperimentalStdlibApi") -// optIn("kotlin.time.ExperimentalTime") -// optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") -// optIn("kotlin.js.ExperimentalJsExport") -//// progressiveMode = true // false by default -// } -// } - - // -// sourceSets { -// val proto by creating { -// } -// } - // // jvm { @@ -51,21 +23,6 @@ kotlin { } } - // - - // -// js(IR) { -// binaries.executable() -//// browser { -////// commonWebpackConfig { -////// cssSupport.enabled = true -////// } -//// } -// -// useCommonJs() -// nodejs() -// -// } sourceSets { val jvmMain by getting { @@ -76,76 +33,101 @@ kotlin { } val jvmTest by getting { } + } -// val jsMain by getting { -// dependencies { -// implementation(npm("ts-proto", "1.83.3")) -// } -// } -// -// val jsTest by getting { -// dependencies { -// implementation(kotlin("test-js")) -// } -// } + // + + // + js(IR) { + browser() + } + + sourceSets { + val jsMain by getting { + dependencies { + implementation(npm("ts-proto", "1.83.3")) + } + } + + val jsTest by getting { + dependencies { + implementation(kotlin("test-js")) + } + } } // + sourceSets.all { + languageSettings.apply { + languageVersion = "1.5" +// enableLanguageFeature("InlineClasses") // language feature name + optIn("kotlin.OptIn") + optIn("kotlin.ExperimentalStdlibApi") + optIn("kotlin.time.ExperimentalTime") + optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") + optIn("kotlin.js.ExperimentalJsExport") +// progressiveMode = true // false by default + } + } } -//rootProject.tasks.withType().configureEach { -//} - -//val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) -//val nodePath: Directory by extra { -// val file = rootPackageJson.rootPackageJson.parentFile.normalize() -// logger.lifecycle("Kotlin/JS NODE_PATH: $file") -// project.layout.dir(provider { file }).get() -//} -// -//val nodeModulesDir: Directory by extra { -// val file = nodePath.dir(NpmProject.NODE_MODULES) -// logger.lifecycle("Kotlin/JS NODE_MODULES: $file") -// file -//} - -// build/js/node_modules/ts-proto/node_modules/.bin -// -tasks.register("protobufJava") { - description = "proto2java" - protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto")) - - cliArgs.add("--java_out=lite:${project.mkdir("$temporaryDir/java").canonicalPath}") +dependencies { + protobufLibrary("com.google.protobuf:protobuf-javalite:3.19.1") } -tasks.create("protobufKotlin") { - description = "proto2kotlin" - protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto")) - cliArgs.add("--kotlin_out=lite:${project.mkdir("$temporaryDir/kotlin").canonicalPath}") +val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) +val nodePath: Directory by extra { + val file = rootPackageJson.rootPackageJson.parentFile.normalize() + logger.lifecycle("Kotlin/JS NODE_PATH: $file") + project.layout.dir(provider { file }).get() } -tasks.create("protobufTypescript") { - description = "proto2typescript" +val nodeModulesDir: Directory by extra { + val file = nodePath.dir(NpmProject.NODE_MODULES) + logger.lifecycle("Kotlin/JS NODE_MODULES: $file") + file +} - // linux: +afterEvaluate { + tasks.register("protobufJava") { + description = "proto2java" + protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto")) + + cliArgs.add("--java_out=lite:${project.mkdir("$temporaryDir/java").canonicalPath}") + } + + tasks.register("protobufKotlin") { + description = "proto2kotlin" + protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto")) + + cliArgs.add("--kotlin_out=lite:${project.mkdir("$temporaryDir/kotlin").canonicalPath}") + } + + tasks.register("protobufTypescript") { + description = "proto2typescript" + + this.taskDependencies + + // linux: // cliArgs.add("--plugin=${rootProject.buildDir}/js/packages/factorio-web-map-factorio-events-data-model/node_modules/.bin/protoc-gen-ts_proto.cmd") - // windows: - cliArgs.add("--plugin=protoc-gen-ts_proto=${rootProject.buildDir}/js/packages/factorio-web-map-factorio-events-data-model/node_modules/.bin/protoc-gen-ts_proto.cmd") + // windows: + cliArgs.add("--plugin=protoc-gen-ts_proto=${rootProject.buildDir}/js/packages/factorio-web-map-factorio-events-data-model/node_modules/.bin/protoc-gen-ts_proto.cmd") - cliArgs.add("--ts_proto_out=${project.mkdir("$temporaryDir/typescript").canonicalPath}") + cliArgs.add("--ts_proto_out=${project.mkdir("$temporaryDir/typescript").canonicalPath}") - cliArgs.addAll( - "--ts_proto_opt=useOptionals=true", - "--ts_proto_opt=outputServices=false", - "--ts_proto_opt=outputJsonMethods=false", - "--ts_proto_opt=outputEncodeMethods=false", - "--ts_proto_opt=forceLong=string", - "--ts_proto_opt=forceLong=number", - "--ts_proto_opt=esModuleInterop=true", - "--ts_proto_opt=exportCommonSymbols=false", + cliArgs.addAll( + "--ts_proto_opt=useOptionals=true", + "--ts_proto_opt=outputServices=false", + "--ts_proto_opt=outputJsonMethods=false", + "--ts_proto_opt=outputEncodeMethods=false", + "--ts_proto_opt=forceLong=string", + "--ts_proto_opt=forceLong=number", + "--ts_proto_opt=esModuleInterop=true", + "--ts_proto_opt=exportCommonSymbols=false", // "--proto_path=${rootProject.rootDir}", - ) + ) - protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto")) + protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto")) + } } From e9e5b88aedd87e855926ab3cb0f4b94f52cf3c8b Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 3 Nov 2021 09:48:41 +0100 Subject: [PATCH 071/629] rm backup files --- .../build.gradle.kts | 95 ------------------- .../FactorioEvent.kt | 63 ------------ .../JsonPrimitiveType.kt | 31 ------ .../src/main/kotlin/PlayerModel.kt | 55 ----------- .../main/proto/FactorioServerLogRecord.proto | 94 ------------------ 5 files changed, 338 deletions(-) delete mode 100644 modules/factorio-events-data-model2/build.gradle.kts delete mode 100644 modules/factorio-events-data-model2/src/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt delete mode 100644 modules/factorio-events-data-model2/src/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt delete mode 100644 modules/factorio-events-data-model2/src/main/kotlin/PlayerModel.kt delete mode 100644 modules/factorio-events-data-model2/src/main/proto/FactorioServerLogRecord.proto diff --git a/modules/factorio-events-data-model2/build.gradle.kts b/modules/factorio-events-data-model2/build.gradle.kts deleted file mode 100644 index 11e86a4..0000000 --- a/modules/factorio-events-data-model2/build.gradle.kts +++ /dev/null @@ -1,95 +0,0 @@ -//import com.google.protobuf.gradle.builtins -//import com.google.protobuf.gradle.generateProtoTasks -//import com.google.protobuf.gradle.ofSourceSet -//import com.google.protobuf.gradle.plugins -//import com.google.protobuf.gradle.protobuf -//import com.google.protobuf.gradle.protoc - - -plugins { - id("dev.adamko.factoriowebmap.archetype.base") -// id("dev-adamko.pb-and-g") -// kotlin("multiplatform") - -// id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") -// java -// kotlin("js") - -// id("com.google.protobuf") version "0.8.17" - -} - -val projectId: String by project.extra -val buildDir: Directory = layout.buildDirectory.dir(projectId).get() -//val nodeModulesDir: Directory by project.extra - -val protobufVersion = "3.19.0" - -//kotlin { -//// js { -//// // To build distributions for and run tests on browser or Node.js use one or both of: -////// browser() -//// nodejs() -//// } -//} - - -dependencies { -// implementation(platform("com.google.protobuf:protobuf-bom:$protobufVersion")) -// -// implementation("com.google.protobuf:protobuf-java:$protobufVersion") -// implementation("com.google.protobuf:protobuf-javalite:$protobufVersion") -// implementation("com.google.protobuf:protobuf-kotlin-lite:$protobufVersion") -// implementation("com.google.protobuf:protobuf-kotlin:$protobufVersion") -// implementation("com.google.protobuf:protoc:$protobufVersion") -// -// implementation(platform("io.grpc:grpc-bom:1.41.0")) -// implementation("io.grpc:grpc-stub:1.41.0") -// implementation("io.grpc:grpc-protobuf:1.41.0") -// -// implementation("io.grpc:grpc-kotlin-stub:1.2.0") -// implementation("io.grpc:protoc-gen-grpc-kotlin:1.2.0") -// -// implementation("javax.annotation:javax.annotation-api:1.3.2") -// - -// implementation(npm("protoc-gen-ts", "0.15.0")) - -} - - -//protobuf { -// protoc { -// // The artifact spec for the Protobuf Compiler -// artifact = "com.google.protobuf:protoc:3.9.2" -// } -// -// plugins { -// -// this.id("ts") { -// -// } -// } -// -// this.plugins { -//// this.named("ts") { -//// -//// } -// } -// -// generateProtoTasks { -// ofSourceSet("main").forEach { task -> -// task.builtins { -// getByName("java") { -// option("lite") -// } -//// getByName("kotlin") { -//// option("lite") -//// } -//// getByName("ts") { -//// option("lite") -//// } -// } -// } -// } -//} diff --git a/modules/factorio-events-data-model2/src/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt b/modules/factorio-events-data-model2/src/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt deleted file mode 100644 index 058d02d..0000000 --- a/modules/factorio-events-data-model2/src/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt +++ /dev/null @@ -1,63 +0,0 @@ -package dev.adamko.factorioevents.model - -import kotlin.js.JsExport -import kotlin.jvm.JvmInline - -//expect sealed interface JsonPrimitive { -// value class JsonString(val string: String) : JsonPrimitive -// value class JsonNumber(val number: Number) : JsonPrimitive -// value class JsonBoolean(val boolean: Boolean) : JsonPrimitive -//} - -sealed interface JsonPrimitive { - @JvmInline - value class JsonString(val string: String) : JsonPrimitive - @JvmInline - value class JsonNumber(val number: Number) : JsonPrimitive - @JvmInline - value class JsonBoolean(val boolean: Boolean) : JsonPrimitive -} - -class JsonArray( - private val list: MutableList = mutableListOf() -) : MutableList by list - - -sealed interface JsonTableValue { - @JvmInline - value class JsonPrimitiveTV(val primitive: JsonPrimitive) : JsonTableValue - @JvmInline - value class JsonArrayTV(val array: JsonArray) : JsonTableValue - @JvmInline - value class JsonTableTV(val array: JsonTable) : JsonTableValue -} - -//expect class JsonNumber() : JsonPrimitiveType - -//expect class JsonArray - -//expect open class JsonTable - -open class JsonTable( - protected val map: MutableMap = mutableMapOf() -) : MutableMap by map { - - inline fun get2(key: String): T? { - - val jKey = JsonPrimitive.JsonString(key) - - return when { - T::class is Number -> ((get(jKey) as? JsonTableValue.JsonPrimitiveTV)?.primitive as? JsonPrimitive.JsonNumber)?.number as? T - else -> return get(jKey) as? T - } - - } - -} - -//@JsExport -class FactorioEvent : JsonTable() { - val tick: UInt? - get() = get2("tick") -// set(value) = map.put("tick", value) -} \ No newline at end of file diff --git a/modules/factorio-events-data-model2/src/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt b/modules/factorio-events-data-model2/src/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt deleted file mode 100644 index 06519b0..0000000 --- a/modules/factorio-events-data-model2/src/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt +++ /dev/null @@ -1,31 +0,0 @@ -package dev.adamko.factorioevents.model - - -//actual sealed interface JsonPrimitive { -// actual value class JsonString(val string: String) : JsonPrimitive -// actual value class JsonNumber(val number: Number) : JsonPrimitive -// actual value class JsonBoolean(val boolean: Boolean) : JsonPrimitive -//} - -//actual class JsonArray( -// private val list: MutableList = mutableListOf() -//) : MutableList by list - -//actual sealed interface JsonTableValue { -// actual value class JsonPrimitiveTV(val primitive: JsonPrimitive) : JsonTableValue -// actual value class JsonArrayTV(val array: JsonArray) : JsonTableValue -//} - - -//actual open class JsonTable( -// private val map: MutableMap = mutableMapOf() -//) : MutableMap by map - - -fun printMap() { - val f = JsonPrimitive.JsonString("test") - - println(f.string) - println(f) - -} diff --git a/modules/factorio-events-data-model2/src/main/kotlin/PlayerModel.kt b/modules/factorio-events-data-model2/src/main/kotlin/PlayerModel.kt deleted file mode 100644 index a745430..0000000 --- a/modules/factorio-events-data-model2/src/main/kotlin/PlayerModel.kt +++ /dev/null @@ -1,55 +0,0 @@ -interface Identifiable { - val id: T -} - - -interface IndexedModel { - val index: UInt -} - -interface NamedModel { - val name: String -} - - -data class SurfaceModel( - override val name: String, - override val index: UInt, - val daytime: Float, - val darkness: Float, - val wind_speed: Double, -) : IndexedModel, NamedModel - - -/** Player/Entity shared props */ -interface ControlModel { - val driving: Boolean - val forces: List -} - - -//data class PlayerModel( -// val index: UInt, -// val characters: List -//) : Identifiable { -// override val id: UInt = index -//} - -//data class EntityModel( -// val unit_number: Int, -// override val name: String, -// val type: String, -// val active: Boolean, -// val minable: Boolean, -// val health: Boolean, -// val speed: Float, override val driving: Boolean, -//) : ControlModel, NamedModel - - -data class ForceModel( - val index: UInt, - override val name: String, - val research_progress: Double, -) : Identifiable, NamedModel { - override val id: UInt = index -} diff --git a/modules/factorio-events-data-model2/src/main/proto/FactorioServerLogRecord.proto b/modules/factorio-events-data-model2/src/main/proto/FactorioServerLogRecord.proto deleted file mode 100644 index 4c4f188..0000000 --- a/modules/factorio-events-data-model2/src/main/proto/FactorioServerLogRecord.proto +++ /dev/null @@ -1,94 +0,0 @@ -syntax = "proto3"; - -option optimize_for = LITE_RUNTIME; -option java_multiple_files = true; - -package dev.adamko.factorioevents; - -import "google/protobuf/any.proto"; -import "google/protobuf/timestamp.proto"; - -message FactorioServerLogRecord { - string mod_version = 1; - uint32 tick = 2; - string event_type = 3; - FactorioLuaObject data = 4; - -} - -message FactorioLuaObject { - string object_name = 1; - oneof data { - LuaControl lua_control = 2; - } -} - -// https://lua-api.factorio.com/next/LuaControl.html -message LuaControl { - bool is_player = 2; - uint32 surface_index = 3; - Position position = 4; - uint32 force_index = 5; - - oneof subtype { - LuaPlayer player = 10; - LuaEntity entity = 11; - } -} - -// https://lua-api.factorio.com/next/LuaPlayer.html -message LuaPlayer { - uint32 index = 1; // unique ID - string name = 2; - repeated int32 data = 4 [packed = true]; - - Colour colour = 8; - - bool is_connected = 10; - bool is_admin = 11; - - uint32 afk_time_ticks = 100; - uint32 online_time_ticks = 101; - uint32 last_online_ticks = 102; -} - -// https://lua-api.factorio.com/next/LuaEntity.html -message LuaEntity { - uint32 unit_number = 1; // (optional) unique ID - string name = 2; - string type = 3; - string status = 4; // https://lua-api.factorio.com/next/defines.html#defines.entity_status - - bool is_active = 8; - bool is_moving = 9; - - uint32 player_index = 50; // (optional) The player connected to this character or nil if none. - uint32 last_user_index = 51; // (optional) The last player that changed any setting on this entity. - - Colour colour = 100; // (optional) -} - -message LuaSurface { - uint32 index = 1; // unique ID - string name = 2; - float daytime = 3; -} - -message LuaForce { - uint32 index = 1; // unique ID - string force_name = 2; - - repeated uint32 player_ids = 100 [packed = true]; -} - -message Position { - int32 x = 1; - int32 y = 2; -} - -message Colour { - float red = 1; - float green = 2; - float blue = 3; - float alpha = 4; -} From efaa85ca912c4c373b788de0ae274db0a429c7ba Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 3 Nov 2021 09:52:02 +0100 Subject: [PATCH 072/629] rm unused line --- modules/factorio-events-data-model/build.gradle.kts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index 04727f0..c1122f5 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -23,7 +23,6 @@ kotlin { } } - sourceSets { val jvmMain by getting { dependencies { @@ -75,7 +74,6 @@ dependencies { protobufLibrary("com.google.protobuf:protobuf-javalite:3.19.1") } - val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) val nodePath: Directory by extra { val file = rootPackageJson.rootPackageJson.parentFile.normalize() @@ -107,8 +105,6 @@ afterEvaluate { tasks.register("protobufTypescript") { description = "proto2typescript" - this.taskDependencies - // linux: // cliArgs.add("--plugin=${rootProject.buildDir}/js/packages/factorio-web-map-factorio-events-data-model/node_modules/.bin/protoc-gen-ts_proto.cmd") // windows: From 5ffd5010e4b59d26fc1ade174f153e01821a834d Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 3 Nov 2021 12:03:12 +0100 Subject: [PATCH 073/629] remove old externals file (generated from Dukat but never used) --- ...ompilerOptions.module_typescript-to-lua.kt | 74 - externals/LuaAST.module_typescript-to-lua.kt | 485 - externals/LuaLib.module_typescript-to-lua.kt | 111 - .../LuaPrinter.module_typescript-to-lua.kt | 101 - externals/context.module_typescript-to-lua.kt | 79 - externals/index.module_typescript-to-lua.kt | 38 - externals/lib.es2015.collection.kt | 49 - externals/lib.es2015.iterable.kt | 54 - externals/lib.es5.Intl.module_dukat.kt | 220 - externals/lib.es5.kt | 69 - externals/lib.scripthost.kt | 20 - externals/nonDeclarations.ts.kt | 114 - ...tput-collector.module_typescript-to-lua.kt | 33 - externals/parse.module_typescript-to-lua.kt | 25 - externals/plugins.module_typescript-to-lua.kt | 24 - externals/report.module_typescript-to-lua.kt | 48 - externals/source-map.module_source-map.kt | 192 - .../transpile.module_typescript-to-lua.kt | 40 - .../transpiler.module_typescript-to-lua.kt | 55 - .../tsconfig.module_typescript-to-lua.kt | 18 - externals/typescript.module_typescript.kt | 19 - ...ipt.ts.ScriptSnapshot.module_typescript.kt | 20 - externals/typescript.ts.module_typescript.kt | 8236 ---------------- .../typescript.ts.server.module_typescript.kt | 101 - externals/utils.module_typescript-to-lua.kt | 46 - .../visitors.module_typescript-to-lua.kt | 38 - ...ompilerOptions.module_typescript-to-lua.kt | 82 - .../LuaAST.module_typescript-to-lua.kt | 473 - .../LuaLib.module_typescript-to-lua.kt | 111 - .../LuaPrinter.module_typescript-to-lua.kt | 101 - .../context.module_typescript-to-lua.kt | 79 - externals02/index.module_typescript-to-lua.kt | 38 - externals02/lib.es2015.collection.kt | 49 - externals02/lib.es2015.iterable.kt | 54 - externals02/lib.es5.Intl.module_dukat.kt | 219 - externals02/lib.es5.kt | 69 - externals02/lib.scripthost.kt | 19 - externals02/nonDeclarations.ts.kt | 115 - ...tput-collector.module_typescript-to-lua.kt | 33 - externals02/parse.module_typescript-to-lua.kt | 25 - .../plugins.module_typescript-to-lua.kt | 24 - .../report.module_typescript-to-lua.kt | 48 - externals02/source-map.module_source-map.kt | 192 - .../transpile.module_typescript-to-lua.kt | 40 - .../transpiler.module_typescript-to-lua.kt | 55 - .../tsconfig.module_typescript-to-lua.kt | 18 - externals02/typescript.module_typescript.kt | 19 - ...ipt.ts.ScriptSnapshot.module_typescript.kt | 20 - .../typescript.ts.module_typescript.kt | 8245 ----------------- .../typescript.ts.server.module_typescript.kt | 101 - externals02/utils.module_typescript-to-lua.kt | 46 - .../visitors.module_typescript-to-lua.kt | 38 - 52 files changed, 20622 deletions(-) delete mode 100644 externals/CompilerOptions.module_typescript-to-lua.kt delete mode 100644 externals/LuaAST.module_typescript-to-lua.kt delete mode 100644 externals/LuaLib.module_typescript-to-lua.kt delete mode 100644 externals/LuaPrinter.module_typescript-to-lua.kt delete mode 100644 externals/context.module_typescript-to-lua.kt delete mode 100644 externals/index.module_typescript-to-lua.kt delete mode 100644 externals/lib.es2015.collection.kt delete mode 100644 externals/lib.es2015.iterable.kt delete mode 100644 externals/lib.es5.Intl.module_dukat.kt delete mode 100644 externals/lib.es5.kt delete mode 100644 externals/lib.scripthost.kt delete mode 100644 externals/nonDeclarations.ts.kt delete mode 100644 externals/output-collector.module_typescript-to-lua.kt delete mode 100644 externals/parse.module_typescript-to-lua.kt delete mode 100644 externals/plugins.module_typescript-to-lua.kt delete mode 100644 externals/report.module_typescript-to-lua.kt delete mode 100644 externals/source-map.module_source-map.kt delete mode 100644 externals/transpile.module_typescript-to-lua.kt delete mode 100644 externals/transpiler.module_typescript-to-lua.kt delete mode 100644 externals/tsconfig.module_typescript-to-lua.kt delete mode 100644 externals/typescript.module_typescript.kt delete mode 100644 externals/typescript.ts.ScriptSnapshot.module_typescript.kt delete mode 100644 externals/typescript.ts.module_typescript.kt delete mode 100644 externals/typescript.ts.server.module_typescript.kt delete mode 100644 externals/utils.module_typescript-to-lua.kt delete mode 100644 externals/visitors.module_typescript-to-lua.kt delete mode 100644 externals02/CompilerOptions.module_typescript-to-lua.kt delete mode 100644 externals02/LuaAST.module_typescript-to-lua.kt delete mode 100644 externals02/LuaLib.module_typescript-to-lua.kt delete mode 100644 externals02/LuaPrinter.module_typescript-to-lua.kt delete mode 100644 externals02/context.module_typescript-to-lua.kt delete mode 100644 externals02/index.module_typescript-to-lua.kt delete mode 100644 externals02/lib.es2015.collection.kt delete mode 100644 externals02/lib.es2015.iterable.kt delete mode 100644 externals02/lib.es5.Intl.module_dukat.kt delete mode 100644 externals02/lib.es5.kt delete mode 100644 externals02/lib.scripthost.kt delete mode 100644 externals02/nonDeclarations.ts.kt delete mode 100644 externals02/output-collector.module_typescript-to-lua.kt delete mode 100644 externals02/parse.module_typescript-to-lua.kt delete mode 100644 externals02/plugins.module_typescript-to-lua.kt delete mode 100644 externals02/report.module_typescript-to-lua.kt delete mode 100644 externals02/source-map.module_source-map.kt delete mode 100644 externals02/transpile.module_typescript-to-lua.kt delete mode 100644 externals02/transpiler.module_typescript-to-lua.kt delete mode 100644 externals02/tsconfig.module_typescript-to-lua.kt delete mode 100644 externals02/typescript.module_typescript.kt delete mode 100644 externals02/typescript.ts.ScriptSnapshot.module_typescript.kt delete mode 100644 externals02/typescript.ts.module_typescript.kt delete mode 100644 externals02/typescript.ts.server.module_typescript.kt delete mode 100644 externals02/utils.module_typescript-to-lua.kt delete mode 100644 externals02/visitors.module_typescript-to-lua.kt diff --git a/externals/CompilerOptions.module_typescript-to-lua.kt b/externals/CompilerOptions.module_typescript-to-lua.kt deleted file mode 100644 index aa83510..0000000 --- a/externals/CompilerOptions.module_typescript-to-lua.kt +++ /dev/null @@ -1,74 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.Diagnostic - -typealias OmitIndexSignature = Any - -external interface TransformerImport { - var transform: String - var import: String? - get() = definedExternally - set(value) = definedExternally - var after: Boolean? - get() = definedExternally - set(value) = definedExternally - var afterDeclarations: Boolean? - get() = definedExternally - set(value) = definedExternally - var type: String? /* "program" | "config" | "checker" | "raw" | "compilerOptions" */ - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): Any? - @nativeSetter - operator fun set(option: String, value: Any) -} - -external interface LuaPluginImport { - var name: String - var import: String? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): Any? - @nativeSetter - operator fun set(option: String, value: Any) -} - -external enum class LuaLibImportKind { - None /* = "none" */, - Always /* = "always" */, - Inline /* = "inline" */, - Require /* = "require" */ -} - -external enum class LuaTarget { - Universal /* = "universal" */, - Lua51 /* = "5.1" */, - Lua52 /* = "5.2" */, - Lua53 /* = "5.3" */, - Lua54 /* = "5.4" */, - LuaJIT /* = "JIT" */ -} - -external enum class BuildMode { - Default /* = "default" */, - Library /* = "library" */ -} - -external var isBundleEnabled: (options: dynamic /* typealias OmitIndexSignature = dynamic */) -> Boolean - -external fun validateOptions(options: dynamic /* typealias OmitIndexSignature = dynamic */): Array \ No newline at end of file diff --git a/externals/LuaAST.module_typescript-to-lua.kt b/externals/LuaAST.module_typescript-to-lua.kt deleted file mode 100644 index 079e37f..0000000 --- a/externals/LuaAST.module_typescript-to-lua.kt +++ /dev/null @@ -1,485 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import tsstdlib.Set - -external enum class SyntaxKind { - File /* = 0 */, - Block /* = 1 */, - DoStatement /* = 2 */, - VariableDeclarationStatement /* = 3 */, - AssignmentStatement /* = 4 */, - IfStatement /* = 5 */, - WhileStatement /* = 6 */, - RepeatStatement /* = 7 */, - ForStatement /* = 8 */, - ForInStatement /* = 9 */, - GotoStatement /* = 10 */, - LabelStatement /* = 11 */, - ReturnStatement /* = 12 */, - BreakStatement /* = 13 */, - ExpressionStatement /* = 14 */, - StringLiteral /* = 15 */, - NumericLiteral /* = 16 */, - NilKeyword /* = 17 */, - DotsKeyword /* = 18 */, - TrueKeyword /* = 19 */, - FalseKeyword /* = 20 */, - FunctionExpression /* = 21 */, - TableFieldExpression /* = 22 */, - TableExpression /* = 23 */, - UnaryExpression /* = 24 */, - BinaryExpression /* = 25 */, - CallExpression /* = 26 */, - MethodCallExpression /* = 27 */, - Identifier /* = 28 */, - TableIndexExpression /* = 29 */, - AdditionOperator /* = 30 */, - SubtractionOperator /* = 31 */, - MultiplicationOperator /* = 32 */, - DivisionOperator /* = 33 */, - FloorDivisionOperator /* = 34 */, - ModuloOperator /* = 35 */, - PowerOperator /* = 36 */, - NegationOperator /* = 37 */, - ConcatOperator /* = 38 */, - LengthOperator /* = 39 */, - EqualityOperator /* = 40 */, - InequalityOperator /* = 41 */, - LessThanOperator /* = 42 */, - LessEqualOperator /* = 43 */, - GreaterThanOperator /* = 44 */, - GreaterEqualOperator /* = 45 */, - AndOperator /* = 46 */, - OrOperator /* = 47 */, - NotOperator /* = 48 */, - BitwiseAndOperator /* = 49 */, - BitwiseOrOperator /* = 50 */, - BitwiseExclusiveOrOperator /* = 51 */, - BitwiseRightShiftOperator /* = 52 */, - BitwiseLeftShiftOperator /* = 53 */, - BitwiseNotOperator /* = 54 */ -} - -typealias UnaryBitwiseOperator = SyntaxKind.BitwiseNotOperator - -external interface TextRange { - var line: Number? - get() = definedExternally - set(value) = definedExternally - var column: Number? - get() = definedExternally - set(value) = definedExternally -} - -external interface Node : TextRange { - var kind: SyntaxKind -} - -external fun createNode(kind: SyntaxKind, tsOriginal: ts.Node = definedExternally): Node - -external fun cloneNode(node: T): T - -external fun setNodePosition(node: T, position: TextRange): T - -external fun setNodeOriginal(node: T, tsOriginal: ts.Node): T - -external fun setNodeOriginal(node: T?, tsOriginal: ts.Node): T? - -external fun getOriginalPos(node: Node): TextRange - -external interface File : Node { - var statements: Array - var luaLibFeatures: Set - var trivia: String -} - -external fun isFile(node: Node): Boolean - -external fun createFile(statements: Array, luaLibFeatures: Set, trivia: String, tsOriginal: ts.Node = definedExternally): File - -external interface Block : Node { - var statements: Array -} - -external fun isBlock(node: Node): Boolean - -external fun createBlock(statements: Array, tsOriginal: ts.Node = definedExternally): Block - -external interface Statement : Node { - var _statementBrand: Any - var leadingComments: Array */>? - get() = definedExternally - set(value) = definedExternally - var trailingComments: Array */>? - get() = definedExternally - set(value) = definedExternally -} - -external interface DoStatement : Statement { - var statements: Array -} - -external fun isDoStatement(node: Node): Boolean - -external fun createDoStatement(statements: Array, tsOriginal: ts.Node = definedExternally): DoStatement - -external interface VariableDeclarationStatement : Statement { - var left: Array - var right: Array? - get() = definedExternally - set(value) = definedExternally -} - -external fun isVariableDeclarationStatement(node: Node): Boolean - -external fun createVariableDeclarationStatement(left: Identifier, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Identifier): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Identifier, right: Expression = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Identifier, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Identifier, right: Array = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array, right: Expression = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array, right: Array = definedExternally): VariableDeclarationStatement - -external interface AssignmentStatement : Statement { - var left: Array - var right: Array -} - -external fun isAssignmentStatement(node: Node): Boolean - -external fun createAssignmentStatement(left: Identifier, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Identifier): AssignmentStatement - -external fun createAssignmentStatement(left: Identifier, right: Expression = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Identifier, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Identifier, right: Array = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression, right: Expression = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression, right: Array = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Array, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Array): AssignmentStatement - -external fun createAssignmentStatement(left: Array, right: Expression = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Array, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Array, right: Array = definedExternally): AssignmentStatement - -external interface IfStatement : Statement { - var condition: Expression - var ifBlock: Block - var elseBlock: dynamic /* Block? | IfStatement? */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isIfStatement(node: Node): Boolean - -external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: Block = definedExternally, tsOriginal: ts.Node = definedExternally): IfStatement - -external fun createIfStatement(condition: Expression, ifBlock: Block): IfStatement - -external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: Block = definedExternally): IfStatement - -external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: IfStatement = definedExternally, tsOriginal: ts.Node = definedExternally): IfStatement - -external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: IfStatement = definedExternally): IfStatement - -external interface IterationStatement : Statement { - var body: Block -} - -external fun isIterationStatement(node: Node): Boolean - -external interface WhileStatement : IterationStatement { - var condition: Expression -} - -external fun isWhileStatement(node: Node): Boolean - -external fun createWhileStatement(body: Block, condition: Expression, tsOriginal: ts.Node = definedExternally): WhileStatement - -external interface RepeatStatement : IterationStatement { - var condition: Expression -} - -external fun isRepeatStatement(node: Node): Boolean - -external fun createRepeatStatement(body: Block, condition: Expression, tsOriginal: ts.Node = definedExternally): RepeatStatement - -external interface ForStatement : IterationStatement { - var controlVariable: Identifier - var controlVariableInitializer: Expression - var limitExpression: Expression - var stepExpression: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external fun isForStatement(node: Node): Boolean - -external fun createForStatement(body: Block, controlVariable: Identifier, controlVariableInitializer: Expression, limitExpression: Expression, stepExpression: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): ForStatement - -external interface ForInStatement : IterationStatement { - var names: Array - var expressions: Array -} - -external fun isForInStatement(node: Node): Boolean - -external fun createForInStatement(body: Block, names: Array, expressions: Array, tsOriginal: ts.Node = definedExternally): ForInStatement - -external interface GotoStatement : Statement { - var label: String -} - -external fun isGotoStatement(node: Node): Boolean - -external fun createGotoStatement(label: String, tsOriginal: ts.Node = definedExternally): GotoStatement - -external interface LabelStatement : Statement { - var name: String -} - -external fun isLabelStatement(node: Node): Boolean - -external fun createLabelStatement(name: String, tsOriginal: ts.Node = definedExternally): LabelStatement - -external interface ReturnStatement : Statement { - var expressions: Array -} - -external fun isReturnStatement(node: Node): Boolean - -external fun createReturnStatement(expressions: Array, tsOriginal: ts.Node = definedExternally): ReturnStatement - -external interface BreakStatement : Statement - -external fun isBreakStatement(node: Node): Boolean - -external fun createBreakStatement(tsOriginal: ts.Node = definedExternally): BreakStatement - -external interface ExpressionStatement : Statement { - var expression: Expression -} - -external fun isExpressionStatement(node: Node): Boolean - -external fun createExpressionStatement(expressions: Expression, tsOriginal: ts.Node = definedExternally): ExpressionStatement - -external interface Expression : Node { - var _expressionBrand: Any -} - -external interface NilLiteral : Expression - -external fun isNilLiteral(node: Node): Boolean - -external fun createNilLiteral(tsOriginal: ts.Node = definedExternally): NilLiteral - -external interface BooleanLiteral : Expression { - override var kind: dynamic /* SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isBooleanLiteral(node: Node): Boolean - -external fun createBooleanLiteral(value: Boolean, tsOriginal: ts.Node = definedExternally): BooleanLiteral - -external interface DotsLiteral : Expression - -external fun isDotsLiteral(node: Node): Boolean - -external fun createDotsLiteral(tsOriginal: ts.Node = definedExternally): DotsLiteral - -external interface NumericLiteral : Expression { - var value: Number -} - -external fun isNumericLiteral(node: Node): Boolean - -external fun createNumericLiteral(value: Number, tsOriginal: ts.Node = definedExternally): NumericLiteral - -external interface StringLiteral : Expression { - var value: String -} - -external fun isStringLiteral(node: Node): Boolean - -external fun createStringLiteral(value: String, tsOriginal: ts.Node = definedExternally): StringLiteral - -external enum class FunctionExpressionFlags { - None /* = 1 */, - Inline /* = 2 */, - Declaration /* = 4 */ -} - -external interface FunctionExpression : Expression { - var params: Array? - get() = definedExternally - set(value) = definedExternally - var dots: DotsLiteral? - get() = definedExternally - set(value) = definedExternally - var body: Block - var flags: FunctionExpressionFlags -} - -external fun isFunctionExpression(node: Node): Boolean - -external fun createFunctionExpression(body: Block, params: Array = definedExternally, dots: DotsLiteral = definedExternally, flags: FunctionExpressionFlags = definedExternally, tsOriginal: ts.Node = definedExternally): FunctionExpression - -external interface TableFieldExpression : Expression { - var value: Expression - var key: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external fun isTableFieldExpression(node: Node): Boolean - -external fun createTableFieldExpression(value: Expression, key: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): TableFieldExpression - -external interface TableExpression : Expression { - var fields: Array -} - -external fun isTableExpression(node: Node): Boolean - -external fun createTableExpression(fields: Array = definedExternally, tsOriginal: ts.Node = definedExternally): TableExpression - -external interface UnaryExpression : Expression { - var operand: Expression - var operator: dynamic /* SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isUnaryExpression(node: Node): Boolean - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NegationOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NegationOperator): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.LengthOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.LengthOperator): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NotOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NotOperator): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: UnaryBitwiseOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: UnaryBitwiseOperator): UnaryExpression - -external interface BinaryExpression : Expression { - var operator: dynamic /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */ - get() = definedExternally - set(value) = definedExternally - var left: Expression - var right: Expression -} - -external fun isBinaryExpression(node: Node): Boolean - -external fun createBinaryExpression(left: Expression, right: Expression, operator: Any /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */, tsOriginal: ts.Node = definedExternally): BinaryExpression - -external interface CallExpression : Expression { - var expression: Expression - var params: Array -} - -external fun isCallExpression(node: Node): Boolean - -external fun createCallExpression(expression: Expression, params: Array, tsOriginal: ts.Node = definedExternally): CallExpression - -external interface MethodCallExpression : Expression { - var prefixExpression: Expression - var name: Identifier - var params: Array -} - -external fun isMethodCallExpression(node: Node): Boolean - -external fun createMethodCallExpression(prefixExpression: Expression, name: Identifier, params: Array, tsOriginal: ts.Node = definedExternally): MethodCallExpression - -external interface Identifier : Expression { - var exportable: Boolean - var text: String - var originalName: String? - get() = definedExternally - set(value) = definedExternally - var symbolId: Number? /* Number? & `T$14`? */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isIdentifier(node: Node): Boolean - -external fun createIdentifier(text: String, tsOriginal: ts.Node = definedExternally, symbolId: Number /* Number & `T$14` */ = definedExternally, originalName: String = definedExternally): Identifier - -external fun cloneIdentifier(identifier: Identifier, tsOriginal: ts.Node = definedExternally): Identifier - -external fun createAnonymousIdentifier(tsOriginal: ts.Node = definedExternally): Identifier - -external interface TableIndexExpression : Expression { - var table: Expression - var index: Expression -} - -external fun isTableIndexExpression(node: Node): Boolean - -external fun createTableIndexExpression(table: Expression, index: Expression, tsOriginal: ts.Node = definedExternally): TableIndexExpression - -external fun isAssignmentLeftHandSideExpression(node: Node): Boolean - -external fun isFunctionDefinition(statement: VariableDeclarationStatement): Boolean - -external fun isFunctionDefinition(statement: AssignmentStatement): Boolean - -external interface `T$17` { - var statements: dynamic /* JsTuple */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isInlineFunctionExpression(expression: FunctionExpression): Boolean \ No newline at end of file diff --git a/externals/LuaLib.module_typescript-to-lua.kt b/externals/LuaLib.module_typescript-to-lua.kt deleted file mode 100644 index f00c242..0000000 --- a/externals/LuaLib.module_typescript-to-lua.kt +++ /dev/null @@ -1,111 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external enum class LuaLibFeature { - ArrayConcat /* = "ArrayConcat" */, - ArrayEntries /* = "ArrayEntries" */, - ArrayEvery /* = "ArrayEvery" */, - ArrayFilter /* = "ArrayFilter" */, - ArrayForEach /* = "ArrayForEach" */, - ArrayFind /* = "ArrayFind" */, - ArrayFindIndex /* = "ArrayFindIndex" */, - ArrayIncludes /* = "ArrayIncludes" */, - ArrayIndexOf /* = "ArrayIndexOf" */, - ArrayIsArray /* = "ArrayIsArray" */, - ArrayJoin /* = "ArrayJoin" */, - ArrayMap /* = "ArrayMap" */, - ArrayPush /* = "ArrayPush" */, - ArrayReduce /* = "ArrayReduce" */, - ArrayReduceRight /* = "ArrayReduceRight" */, - ArrayReverse /* = "ArrayReverse" */, - ArrayShift /* = "ArrayShift" */, - ArrayUnshift /* = "ArrayUnshift" */, - ArraySort /* = "ArraySort" */, - ArraySlice /* = "ArraySlice" */, - ArraySome /* = "ArraySome" */, - ArraySplice /* = "ArraySplice" */, - ArrayToObject /* = "ArrayToObject" */, - ArrayFlat /* = "ArrayFlat" */, - ArrayFlatMap /* = "ArrayFlatMap" */, - ArraySetLength /* = "ArraySetLength" */, - Await /* = "Await" */, - Class /* = "Class" */, - ClassExtends /* = "ClassExtends" */, - CloneDescriptor /* = "CloneDescriptor" */, - Decorate /* = "Decorate" */, - DecorateParam /* = "DecorateParam" */, - Delete /* = "Delete" */, - DelegatedYield /* = "DelegatedYield" */, - Error /* = "Error" */, - FunctionBind /* = "FunctionBind" */, - Generator /* = "Generator" */, - InstanceOf /* = "InstanceOf" */, - InstanceOfObject /* = "InstanceOfObject" */, - Iterator /* = "Iterator" */, - Map /* = "Map" */, - MathAtan2 /* = "MathAtan2" */, - New /* = "New" */, - Number /* = "Number" */, - NumberIsFinite /* = "NumberIsFinite" */, - NumberIsNaN /* = "NumberIsNaN" */, - NumberToString /* = "NumberToString" */, - ObjectAssign /* = "ObjectAssign" */, - ObjectDefineProperty /* = "ObjectDefineProperty" */, - ObjectEntries /* = "ObjectEntries" */, - ObjectFromEntries /* = "ObjectFromEntries" */, - ObjectGetOwnPropertyDescriptor /* = "ObjectGetOwnPropertyDescriptor" */, - ObjectGetOwnPropertyDescriptors /* = "ObjectGetOwnPropertyDescriptors" */, - ObjectKeys /* = "ObjectKeys" */, - ObjectRest /* = "ObjectRest" */, - ObjectValues /* = "ObjectValues" */, - OptionalChainAccess /* = "OptionalChainAccess" */, - OptionalFunctionCall /* = "OptionalFunctionCall" */, - OptionalMethodCall /* = "OptionalMethodCall" */, - ParseFloat /* = "ParseFloat" */, - ParseInt /* = "ParseInt" */, - Promise /* = "Promise" */, - PromiseAll /* = "PromiseAll" */, - PromiseAllSettled /* = "PromiseAllSettled" */, - PromiseAny /* = "PromiseAny" */, - PromiseRace /* = "PromiseRace" */, - Set /* = "Set" */, - SetDescriptor /* = "SetDescriptor" */, - WeakMap /* = "WeakMap" */, - WeakSet /* = "WeakSet" */, - SourceMapTraceBack /* = "SourceMapTraceBack" */, - Spread /* = "Spread" */, - StringAccess /* = "StringAccess" */, - StringCharAt /* = "StringCharAt" */, - StringCharCodeAt /* = "StringCharCodeAt" */, - StringConcat /* = "StringConcat" */, - StringEndsWith /* = "StringEndsWith" */, - StringIncludes /* = "StringIncludes" */, - StringPadEnd /* = "StringPadEnd" */, - StringPadStart /* = "StringPadStart" */, - StringReplace /* = "StringReplace" */, - StringSlice /* = "StringSlice" */, - StringSplit /* = "StringSplit" */, - StringStartsWith /* = "StringStartsWith" */, - StringSubstr /* = "StringSubstr" */, - StringSubstring /* = "StringSubstring" */, - StringTrim /* = "StringTrim" */, - StringTrimEnd /* = "StringTrimEnd" */, - StringTrimStart /* = "StringTrimStart" */, - Symbol /* = "Symbol" */, - SymbolRegistry /* = "SymbolRegistry" */, - TypeOf /* = "TypeOf" */, - Unpack /* = "Unpack" */ -} \ No newline at end of file diff --git a/externals/LuaPrinter.module_typescript-to-lua.kt b/externals/LuaPrinter.module_typescript-to-lua.kt deleted file mode 100644 index 6428653..0000000 --- a/externals/LuaPrinter.module_typescript-to-lua.kt +++ /dev/null @@ -1,101 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.Program - -external var escapeString: (value: String) -> String - -external var tstlHeader: Any - -typealias Printer = (program: Program, emitHost: EmitHost, fileName: String, file: File) -> PrintResult - -external interface PrintResult { - var code: String - var sourceMap: String - var sourceMapNode: SourceNode -} - -external fun createPrinter(printers: Array): Printer - -external open class LuaPrinter(emitHost: EmitHost, program: Program, fileName: String) { - open var emitHost: Any - open var currentIndent: Any - open var sourceFile: Any - open var options: Any - open fun print(file: File): PrintResult - open var printInlineSourceMap: Any - open var printStackTraceOverride: Any - open var printFile: Any - open fun pushIndent() - open fun popIndent() - open fun indent(input: String = definedExternally): dynamic /* String | SourceNode */ - open fun indent(): dynamic /* String | SourceNode */ - open fun indent(input: SourceNode = definedExternally): dynamic /* String | SourceNode */ - open fun createSourceNode(node: Node, chunks: String, name: String = definedExternally): SourceNode - open fun createSourceNode(node: Node, chunks: String): SourceNode - open fun createSourceNode(node: Node, chunks: SourceNode, name: String = definedExternally): SourceNode - open fun createSourceNode(node: Node, chunks: SourceNode): SourceNode - open fun createSourceNode(node: Node, chunks: Array, name: String = definedExternally): SourceNode - open fun createSourceNode(node: Node, chunks: Array): SourceNode - open fun concatNodes(vararg chunks: Any /* String | SourceNode */): SourceNode - open fun printBlock(block: Block): SourceNode - open var statementMayRequireSemiColon: Any - open var nodeStartsWithParenthesis: Any - open fun printStatementArray(statements: Array): Array - open fun printStatement(statement: Statement): SourceNode - open fun printComment(comment: String): dynamic /* String | SourceNode */ - open fun printComment(comment: Array): dynamic /* String | SourceNode */ - open fun printStatementExcludingComments(statement: Statement): SourceNode - open fun printDoStatement(statement: DoStatement): SourceNode - open fun printVariableDeclarationStatement(statement: VariableDeclarationStatement): SourceNode - open fun printVariableAssignmentStatement(statement: AssignmentStatement): SourceNode - open fun printIfStatement(statement: IfStatement, isElseIf: Boolean = definedExternally): SourceNode - open fun printWhileStatement(statement: WhileStatement): SourceNode - open fun printRepeatStatement(statement: RepeatStatement): SourceNode - open fun printForStatement(statement: ForStatement): SourceNode - open fun printForInStatement(statement: ForInStatement): SourceNode - open fun printGotoStatement(statement: GotoStatement): SourceNode - open fun printLabelStatement(statement: LabelStatement): SourceNode - open fun printReturnStatement(statement: ReturnStatement): SourceNode - open fun printBreakStatement(statement: BreakStatement): SourceNode - open fun printExpressionStatement(statement: ExpressionStatement): SourceNode - open fun printExpression(expression: Expression): SourceNode - open fun printStringLiteral(expression: StringLiteral): SourceNode - open fun printNumericLiteral(expression: NumericLiteral): SourceNode - open fun printNilLiteral(expression: NilLiteral): SourceNode - open fun printDotsLiteral(expression: DotsLiteral): SourceNode - open fun printBooleanLiteral(expression: BooleanLiteral): SourceNode - open var printFunctionParameters: Any - open fun printFunctionExpression(expression: FunctionExpression): SourceNode - open fun printFunctionDefinition(statement: Any /* VariableDeclarationStatement | AssignmentStatement */): SourceNode - open fun printTableFieldExpression(expression: TableFieldExpression): SourceNode - open fun printTableExpression(expression: TableExpression): SourceNode - open fun printUnaryExpression(expression: UnaryExpression): SourceNode - open fun printBinaryExpression(expression: BinaryExpression): SourceNode - open var printExpressionInParenthesesIfNeeded: Any - open var needsParenthesis: Any - open fun printCallExpression(expression: CallExpression): SourceNode - open fun printMethodCallExpression(expression: MethodCallExpression): SourceNode - open fun printIdentifier(expression: Identifier): SourceNode - open fun printTableIndexExpression(expression: TableIndexExpression): SourceNode - open fun printOperator(kind: Any /* SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator | SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */): SourceNode - open fun joinChunksWithComma(chunks: Array): Array - open fun printExpressionList(expressions: Array): Array - open var buildSourceMap: Any - - companion object { - var operatorMap: Any - } -} \ No newline at end of file diff --git a/externals/context.module_typescript-to-lua.kt b/externals/context.module_typescript-to-lua.kt deleted file mode 100644 index 696e339..0000000 --- a/externals/context.module_typescript-to-lua.kt +++ /dev/null @@ -1,79 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.GetAccessorDeclaration -import ts.SetAccessorDeclaration -import ts.Node -import ts.ImportEqualsDeclaration -import ts.Expression -import ts.SourceFile -import ts.CancellationToken -import ts.TypeChecker -import ts.Program -import ts.Diagnostic -import Node as _Node -import Expression as _Expression -import ts.QualifiedName -import ts.ExternalModuleReference - -external interface AllAccessorDeclarations { - var firstAccessor: dynamic /* GetAccessorDeclaration | SetAccessorDeclaration */ - get() = definedExternally - set(value) = definedExternally - var secondAccessor: dynamic /* GetAccessorDeclaration? | SetAccessorDeclaration? */ - get() = definedExternally - set(value) = definedExternally - var getAccessor: GetAccessorDeclaration? - var setAccessor: SetAccessorDeclaration? -} - -external interface EmitResolver { - fun isValueAliasDeclaration(node: Node): Boolean - fun isReferencedAliasDeclaration(node: Node, checkChildren: Boolean = definedExternally): Boolean - fun isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): Boolean - fun moduleExportsSomeValue(moduleReferenceExpression: Expression): Boolean - fun getAllAccessorDeclarations(declaration: GetAccessorDeclaration): AllAccessorDeclarations - fun getAllAccessorDeclarations(declaration: SetAccessorDeclaration): AllAccessorDeclarations -} - -external interface DiagnosticsProducingTypeChecker : TypeChecker { - fun getEmitResolver(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): EmitResolver -} - -external open class TransformationContext(program: Program, sourceFile: SourceFile, visitorMap: VisitorMap) { - open var program: Program - open var sourceFile: SourceFile - open var visitorMap: Any - open val diagnostics: Array - open val checker: DiagnosticsProducingTypeChecker - open val resolver: EmitResolver - open val options: dynamic /* typealias OmitIndexSignature = dynamic */ - open val luaTarget: LuaTarget - open val isModule: Boolean - open val isStrict: Boolean - open var currentNodeVisitors: Any - open fun transformNode(node: Node): Array<_Node> - open fun superTransformNode(node: Node): Array<_Node> - open fun transformExpression(node: Expression): _Expression - open fun transformExpression(node: QualifiedName): _Expression - open fun transformExpression(node: ExternalModuleReference): _Expression - open fun superTransformExpression(node: Expression): _Expression - open fun superTransformExpression(node: QualifiedName): _Expression - open fun superTransformExpression(node: ExternalModuleReference): _Expression - open fun transformStatements(node: StatementLikeNode): Array - open fun transformStatements(node: Array): Array - open fun superTransformStatements(node: StatementLikeNode): Array - open fun superTransformStatements(node: Array): Array -} \ No newline at end of file diff --git a/externals/index.module_typescript-to-lua.kt b/externals/index.module_typescript-to-lua.kt deleted file mode 100644 index 2016698..0000000 --- a/externals/index.module_typescript-to-lua.kt +++ /dev/null @@ -1,38 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.WriteFileCallback -import ts.Diagnostic -import tsstdlib.Record - -external fun transpileFiles(rootNames: Array, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, writeFile: WriteFileCallback = definedExternally): EmitResult - -external fun transpileProject(configFileName: String, optionsToExtend: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, writeFile: WriteFileCallback = definedExternally): EmitResult - -external interface TranspileVirtualProjectResult { - var diagnostics: Array - var transpiledFiles: Array -} - -external fun transpileVirtualProject(files: Record, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally): TranspileVirtualProjectResult - -external interface TranspileStringResult { - var diagnostics: Array - var file: TranspiledFile? - get() = definedExternally - set(value) = definedExternally -} - -external fun transpileString(main: String, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally): TranspileStringResult \ No newline at end of file diff --git a/externals/lib.es2015.collection.kt b/externals/lib.es2015.collection.kt deleted file mode 100644 index affffa8..0000000 --- a/externals/lib.es2015.collection.kt +++ /dev/null @@ -1,49 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface Map { - fun entries(): IterableIterator */> - fun keys(): IterableIterator - fun values(): IterableIterator - fun clear() - fun delete(key: K): Boolean - fun forEach(callbackfn: (value: V, key: K, map: Map) -> Unit, thisArg: Any = definedExternally) - fun get(key: K): V? - fun has(key: K): Boolean - fun set(key: K, value: V): Map /* this */ - val size: Number -} - -external interface MapConstructor { - val prototype: Map -} - -external interface Set { - fun entries(): IterableIterator */> - fun keys(): IterableIterator - fun values(): IterableIterator - fun add(value: T): Set /* this */ - fun clear() - fun delete(value: T): Boolean - fun forEach(callbackfn: (value: T, value2: T, set: Set) -> Unit, thisArg: Any = definedExternally) - fun has(value: T): Boolean - val size: Number -} - -external interface SetConstructor { - val prototype: Set -} \ No newline at end of file diff --git a/externals/lib.es2015.iterable.kt b/externals/lib.es2015.iterable.kt deleted file mode 100644 index 1528efa..0000000 --- a/externals/lib.es2015.iterable.kt +++ /dev/null @@ -1,54 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface IteratorYieldResult { - var done: Boolean? - get() = definedExternally - set(value) = definedExternally - var value: TYield -} - -external interface IteratorReturnResult { - var done: Boolean - var value: TReturn -} - -external interface Iterator { - fun next(vararg args: Any /* JsTuple<> | JsTuple */): dynamic /* IteratorYieldResult | IteratorReturnResult */ - val `return`: ((value: TReturn) -> dynamic)? - val `throw`: ((e: Any) -> dynamic)? -} - -typealias Iterator__1 = Iterator - -external interface Iterable - -external interface IterableIterator : Iterator__1 - -external interface PromiseConstructor { - val prototype: Promise - fun all(values: Any /* JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple */): Promise | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple */> - fun all(values: Array */>): Promise> - fun race(values: Array): Promise - fun reject(reason: Any = definedExternally): Promise - fun resolve(value: T): Promise - fun resolve(value: PromiseLike): Promise - fun resolve(): Promise - fun all(values: Iterable */>): Promise> - fun race(values: Iterable): Promise - fun race(values: Iterable */>): Promise -} \ No newline at end of file diff --git a/externals/lib.es5.Intl.module_dukat.kt b/externals/lib.es5.Intl.module_dukat.kt deleted file mode 100644 index 62cbcc7..0000000 --- a/externals/lib.es5.Intl.module_dukat.kt +++ /dev/null @@ -1,220 +0,0 @@ -@file:JsQualifier("tsstdlib.Intl") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib.Intl - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface CollatorOptions { - var usage: String? - get() = definedExternally - set(value) = definedExternally - var localeMatcher: String? - get() = definedExternally - set(value) = definedExternally - var numeric: Boolean? - get() = definedExternally - set(value) = definedExternally - var caseFirst: String? - get() = definedExternally - set(value) = definedExternally - var sensitivity: String? - get() = definedExternally - set(value) = definedExternally - var ignorePunctuation: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedCollatorOptions { - var locale: String - var usage: String - var sensitivity: String - var ignorePunctuation: Boolean - var collation: String - var caseFirst: String - var numeric: Boolean -} - -@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") -external interface Collator { - fun compare(x: String, y: String): Number - fun resolvedOptions(): ResolvedCollatorOptions - - companion object { - @nativeInvoke - operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: CollatorOptions = definedExternally): Collator - fun supportedLocalesOf(locales: Any /* String | Array */, options: CollatorOptions = definedExternally): Array - } -} - -external interface NumberFormatOptions { - var localeMatcher: String? - get() = definedExternally - set(value) = definedExternally - var style: String? - get() = definedExternally - set(value) = definedExternally - var currency: String? - get() = definedExternally - set(value) = definedExternally - var currencyDisplay: String? - get() = definedExternally - set(value) = definedExternally - var useGrouping: Boolean? - get() = definedExternally - set(value) = definedExternally - var minimumIntegerDigits: Number? - get() = definedExternally - set(value) = definedExternally - var minimumFractionDigits: Number? - get() = definedExternally - set(value) = definedExternally - var maximumFractionDigits: Number? - get() = definedExternally - set(value) = definedExternally - var minimumSignificantDigits: Number? - get() = definedExternally - set(value) = definedExternally - var maximumSignificantDigits: Number? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedNumberFormatOptions { - var locale: String - var numberingSystem: String - var style: String - var currency: String? - get() = definedExternally - set(value) = definedExternally - var currencyDisplay: String? - get() = definedExternally - set(value) = definedExternally - var minimumIntegerDigits: Number - var minimumFractionDigits: Number - var maximumFractionDigits: Number - var minimumSignificantDigits: Number? - get() = definedExternally - set(value) = definedExternally - var maximumSignificantDigits: Number? - get() = definedExternally - set(value) = definedExternally - var useGrouping: Boolean -} - -@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") -external interface NumberFormat { - fun format(value: Number): String - fun resolvedOptions(): ResolvedNumberFormatOptions - - companion object { - @nativeInvoke - operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: NumberFormatOptions = definedExternally): NumberFormat - fun supportedLocalesOf(locales: Any /* String | Array */, options: NumberFormatOptions = definedExternally): Array - } -} - -external interface DateTimeFormatOptions { - var localeMatcher: String? - get() = definedExternally - set(value) = definedExternally - var weekday: String? - get() = definedExternally - set(value) = definedExternally - var era: String? - get() = definedExternally - set(value) = definedExternally - var year: String? - get() = definedExternally - set(value) = definedExternally - var month: String? - get() = definedExternally - set(value) = definedExternally - var day: String? - get() = definedExternally - set(value) = definedExternally - var hour: String? - get() = definedExternally - set(value) = definedExternally - var minute: String? - get() = definedExternally - set(value) = definedExternally - var second: String? - get() = definedExternally - set(value) = definedExternally - var timeZoneName: String? - get() = definedExternally - set(value) = definedExternally - var formatMatcher: String? - get() = definedExternally - set(value) = definedExternally - var hour12: Boolean? - get() = definedExternally - set(value) = definedExternally - var timeZone: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedDateTimeFormatOptions { - var locale: String - var calendar: String - var numberingSystem: String - var timeZone: String - var hour12: Boolean? - get() = definedExternally - set(value) = definedExternally - var weekday: String? - get() = definedExternally - set(value) = definedExternally - var era: String? - get() = definedExternally - set(value) = definedExternally - var year: String? - get() = definedExternally - set(value) = definedExternally - var month: String? - get() = definedExternally - set(value) = definedExternally - var day: String? - get() = definedExternally - set(value) = definedExternally - var hour: String? - get() = definedExternally - set(value) = definedExternally - var minute: String? - get() = definedExternally - set(value) = definedExternally - var second: String? - get() = definedExternally - set(value) = definedExternally - var timeZoneName: String? - get() = definedExternally - set(value) = definedExternally -} - -@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") -external interface DateTimeFormat { - fun format(date: Date = definedExternally): String - fun format(): String - fun format(date: Number = definedExternally): String - fun resolvedOptions(): ResolvedDateTimeFormatOptions - - companion object { - @nativeInvoke - operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: DateTimeFormatOptions = definedExternally): DateTimeFormat - fun supportedLocalesOf(locales: Any /* String | Array */, options: DateTimeFormatOptions = definedExternally): Array - } -} \ No newline at end of file diff --git a/externals/lib.es5.kt b/externals/lib.es5.kt deleted file mode 100644 index c9b2102..0000000 --- a/externals/lib.es5.kt +++ /dev/null @@ -1,69 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface DateConstructor { - @nativeInvoke - operator fun invoke(): String - val prototype: Date - fun parse(s: String): Number - fun UTC(year: Number, month: Number, date: Number = definedExternally, hours: Number = definedExternally, minutes: Number = definedExternally, seconds: Number = definedExternally, ms: Number = definedExternally): Number - fun now(): Number -} - -external interface ConcatArray { - val length: Number - @nativeGetter - operator fun get(n: Number): T? - @nativeSetter - operator fun set(n: Number, value: T) - fun join(separator: String = definedExternally): String - fun slice(start: Number = definedExternally, end: Number = definedExternally): Array -} - -external interface ArrayConstructor { - fun from(iterable: Iterable): Array - fun from(iterable: ArrayLike): Array - fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array - fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U): Array - fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array - fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U): Array - fun of(vararg items: T): Array - @nativeInvoke - operator fun invoke(arrayLength: Number = definedExternally): Array - @nativeInvoke - operator fun invoke(): Array - @nativeInvoke - operator fun invoke(arrayLength: Number): Array - @nativeInvoke - operator fun invoke(vararg items: T): Array - fun isArray(arg: Any): Boolean - val prototype: Array -} - -external interface PromiseLike { - fun then(onfulfilled: ((value: T) -> Any?)? = definedExternally, onrejected: ((reason: Any) -> Any?)? = definedExternally): PromiseLike -} - -external interface ArrayLike { - val length: Number - @nativeGetter - operator fun get(n: Number): T? - @nativeSetter - operator fun set(n: Number, value: T) -} - -typealias Record = Any \ No newline at end of file diff --git a/externals/lib.scripthost.kt b/externals/lib.scripthost.kt deleted file mode 100644 index 809347e..0000000 --- a/externals/lib.scripthost.kt +++ /dev/null @@ -1,20 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external open class VarDate { - open var VarDate_typekey: VarDate -} \ No newline at end of file diff --git a/externals/nonDeclarations.ts.kt b/externals/nonDeclarations.ts.kt deleted file mode 100644 index 3650dca..0000000 --- a/externals/nonDeclarations.ts.kt +++ /dev/null @@ -1,114 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package ts - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -typealias SortedReadonlyArray = Array - -typealias SortedArray = Array - -typealias NodeArray = Array - -typealias DotToken = PunctuationToken - -typealias DotDotDotToken = PunctuationToken - -typealias QuestionToken = PunctuationToken - -typealias ExclamationToken = PunctuationToken - -typealias ColonToken = PunctuationToken - -typealias EqualsToken = PunctuationToken - -typealias AsteriskToken = PunctuationToken - -typealias EqualsGreaterThanToken = PunctuationToken - -typealias PlusToken = PunctuationToken - -typealias MinusToken = PunctuationToken - -typealias QuestionDotToken = PunctuationToken - -typealias AssertsKeyword = KeywordToken - -typealias AwaitKeyword = KeywordToken - -typealias AwaitKeywordToken = AwaitKeyword - -typealias AssertsToken = AssertsKeyword - -typealias AbstractKeyword = ModifierToken - -typealias AsyncKeyword = ModifierToken - -typealias ConstKeyword = ModifierToken - -typealias DeclareKeyword = ModifierToken - -typealias DefaultKeyword = ModifierToken - -typealias ExportKeyword = ModifierToken - -typealias PrivateKeyword = ModifierToken - -typealias ProtectedKeyword = ModifierToken - -typealias PublicKeyword = ModifierToken - -typealias ReadonlyKeyword = ModifierToken - -typealias OverrideKeyword = ModifierToken - -typealias StaticKeyword = ModifierToken - -typealias ReadonlyToken = ReadonlyKeyword - -typealias ModifiersArray = NodeArray - -typealias IncrementExpression = UpdateExpression - -typealias ExponentiationOperator = SyntaxKind.AsteriskAsteriskToken - -typealias BinaryOperatorToken = Token - -typealias AssignmentOperatorToken = Token - -typealias FunctionBody = Block - -typealias WriteFileCallback = (fileName: String, data: String, writeByteOrderMark: Boolean, onError: (message: String) -> Unit, sourceFiles: Array) -> Unit - -typealias CustomTransformerFactory = (context: TransformationContext) -> CustomTransformer - -typealias SymbolTable = UnderscoreEscapedMap - -typealias JsFileExtensionInfo = FileExtensionInfo - -typealias EmitHelperUniqueNameCallback = (name: String) -> String - -typealias TransformerFactory = (context: TransformationContext) -> Transformer - -typealias Transformer = (node: T) -> T - -typealias Visitor = (node: Node) -> dynamic - -typealias FileWatcherCallback = (fileName: String, eventKind: FileWatcherEventKind) -> Unit - -typealias DirectoryWatcherCallback = (fileName: String) -> Unit - -typealias DiagnosticReporter = (diagnostic: Diagnostic) -> Unit - -typealias CodeActionCommand = InstallPackageAction \ No newline at end of file diff --git a/externals/output-collector.module_typescript-to-lua.kt b/externals/output-collector.module_typescript-to-lua.kt deleted file mode 100644 index 0c57eac..0000000 --- a/externals/output-collector.module_typescript-to-lua.kt +++ /dev/null @@ -1,33 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.SourceFile - -external interface TranspiledFile { - var outPath: String - var sourceFiles: Array - var lua: String? - get() = definedExternally - set(value) = definedExternally - var luaSourceMap: String? - get() = definedExternally - set(value) = definedExternally - var declaration: String? - get() = definedExternally - set(value) = definedExternally - var declarationMap: String? - get() = definedExternally - set(value) = definedExternally -} \ No newline at end of file diff --git a/externals/parse.module_typescript-to-lua.kt b/externals/parse.module_typescript-to-lua.kt deleted file mode 100644 index ff6e944..0000000 --- a/externals/parse.module_typescript-to-lua.kt +++ /dev/null @@ -1,25 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface ParsedCommandLine : ts.ParsedCommandLine { - override var options: dynamic /* typealias OmitIndexSignature = dynamic */ - get() = definedExternally - set(value) = definedExternally -} - -external fun updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine - -external fun parseCommandLine(args: Array): ParsedCommandLine \ No newline at end of file diff --git a/externals/plugins.module_typescript-to-lua.kt b/externals/plugins.module_typescript-to-lua.kt deleted file mode 100644 index 24d3ea4..0000000 --- a/externals/plugins.module_typescript-to-lua.kt +++ /dev/null @@ -1,24 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface Plugin { - var visitors: Visitors? - get() = definedExternally - set(value) = definedExternally - var printer: Printer? - get() = definedExternally - set(value) = definedExternally -} \ No newline at end of file diff --git a/externals/report.module_typescript-to-lua.kt b/externals/report.module_typescript-to-lua.kt deleted file mode 100644 index f1582a6..0000000 --- a/externals/report.module_typescript-to-lua.kt +++ /dev/null @@ -1,48 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.DiagnosticRelatedInformation -import ts.DiagnosticCategory -import ts.SourceFile -import ts.Diagnostic -import ts.System -import ts.DiagnosticReporter - -external interface `T$13` { - var code: Any - var reportsUnnecessary: Any? - get() = definedExternally - set(value) = definedExternally - var reportsDeprecated: Any? - get() = definedExternally - set(value) = definedExternally - var source: String? - get() = definedExternally - set(value) = definedExternally - var relatedInformation: Array? - get() = definedExternally - set(value) = definedExternally - var category: DiagnosticCategory - var file: SourceFile? - var start: Number? - var length: Number? - var messageText: dynamic /* String | ts.DiagnosticMessageChain */ - get() = definedExternally - set(value) = definedExternally -} - -external var prepareDiagnosticForFormatting: (diagnostic: Diagnostic) -> `T$13` - -external fun createDiagnosticReporter(pretty: Boolean, system: System = definedExternally): DiagnosticReporter \ No newline at end of file diff --git a/externals/source-map.module_source-map.kt b/externals/source-map.module_source-map.kt deleted file mode 100644 index 6880a36..0000000 --- a/externals/source-map.module_source-map.kt +++ /dev/null @@ -1,192 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -typealias SourceMapUrl = String - -external interface StartOfSourceMap { - var file: String? - get() = definedExternally - set(value) = definedExternally - var sourceRoot: String? - get() = definedExternally - set(value) = definedExternally - var skipValidation: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface RawSourceMap { - var version: Number - var sources: Array - var names: Array - var sourceRoot: String? - get() = definedExternally - set(value) = definedExternally - var sourcesContent: Array? - get() = definedExternally - set(value) = definedExternally - var mappings: String - var file: String -} - -external interface RawIndexMap : StartOfSourceMap { - var version: Number - var sections: Array -} - -external interface RawSection { - var offset: Position - var map: RawSourceMap -} - -external interface Position { - var line: Number - var column: Number -} - -external interface NullablePosition { - var line: Number? - var column: Number? - var lastColumn: Number? -} - -external interface MappedPosition { - var source: String - var line: Number - var column: Number - var name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface NullableMappedPosition { - var source: String? - var line: Number? - var column: Number? - var name: String? -} - -external interface MappingItem { - var source: String - var generatedLine: Number - var generatedColumn: Number - var originalLine: Number - var originalColumn: Number - var name: String -} - -external interface Mapping { - var generated: Position - var original: Position - var source: String - var name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface CodeWithSourceMap { - var code: String - var map: SourceMapGenerator -} - -external interface SourceMapConsumer { - fun computeColumnSpans() - fun originalPositionFor(generatedPosition: Position /* Position & `T$19` */): NullableMappedPosition - fun generatedPositionFor(originalPosition: MappedPosition /* MappedPosition & `T$19` */): NullablePosition - fun allGeneratedPositionsFor(originalPosition: MappedPosition): Array - fun hasContentsOfAllSources(): Boolean - fun sourceContentFor(source: String, returnNullOnMissing: Boolean = definedExternally): String? - fun eachMapping(callback: (mapping: MappingItem) -> Unit, context: Any = definedExternally, order: Number = definedExternally) - fun destroy() -} - -external interface SourceMapConsumerConstructor { - var prototype: SourceMapConsumer - var GENERATED_ORDER: Number - var ORIGINAL_ORDER: Number - var GREATEST_LOWER_BOUND: Number - var LEAST_UPPER_BOUND: Number - fun fromSourceMap(sourceMap: SourceMapGenerator, sourceMapUrl: SourceMapUrl = definedExternally): Promise - fun with(rawSourceMap: RawSourceMap, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise - fun with(rawSourceMap: RawIndexMap, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise - fun with(rawSourceMap: String, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise -} - -external interface BasicSourceMapConsumer : SourceMapConsumer { - var file: String - var sourceRoot: String - var sources: Array - var sourcesContent: Array -} - -external interface BasicSourceMapConsumerConstructor { - var prototype: BasicSourceMapConsumer - fun fromSourceMap(sourceMap: SourceMapGenerator): Promise -} - -external interface IndexedSourceMapConsumer : SourceMapConsumer { - var sources: Array -} - -external interface IndexedSourceMapConsumerConstructor { - var prototype: IndexedSourceMapConsumer -} - -external open class SourceMapGenerator(startOfSourceMap: StartOfSourceMap = definedExternally) { - open fun addMapping(mapping: Mapping) - open fun setSourceContent(sourceFile: String, sourceContent: String) - open fun applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile: String = definedExternally, sourceMapPath: String = definedExternally) - override fun toString(): String - open fun toJSON(): RawSourceMap - - companion object { - fun fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator - } -} - -external open class SourceNode { - open var children: Array - open var sourceContents: Any - open var line: Number - open var column: Number - open var source: String - open var name: String - constructor() - constructor(line: Number?, column: Number?, source: String?, chunks: Array = definedExternally, name: String = definedExternally) - constructor(line: Number?, column: Number?, source: String?) - constructor(line: Number?, column: Number?, source: String?, chunks: Array = definedExternally) - constructor(line: Number?, column: Number?, source: String?, chunks: SourceNode = definedExternally, name: String = definedExternally) - constructor(line: Number?, column: Number?, source: String?, chunks: SourceNode = definedExternally) - constructor(line: Number?, column: Number?, source: String?, chunks: String = definedExternally, name: String = definedExternally) - constructor(line: Number?, column: Number?, source: String?, chunks: String = definedExternally) - open fun add(chunk: Array): SourceNode - open fun add(chunk: SourceNode): SourceNode - open fun add(chunk: String): SourceNode - open fun prepend(chunk: Array): SourceNode - open fun prepend(chunk: SourceNode): SourceNode - open fun prepend(chunk: String): SourceNode - open fun setSourceContent(sourceFile: String, sourceContent: String) - open fun walk(fn: (chunk: String, mapping: MappedPosition) -> Unit) - open fun walkSourceContents(fn: (file: String, content: String) -> Unit) - open fun join(sep: String): SourceNode - open fun replaceRight(pattern: String, replacement: String): SourceNode - override fun toString(): String - open fun toStringWithSourceMap(startOfSourceMap: StartOfSourceMap = definedExternally): CodeWithSourceMap - - companion object { - fun fromStringWithSourceMap(code: String, sourceMapConsumer: SourceMapConsumer, relativePath: String = definedExternally): SourceNode - } -} \ No newline at end of file diff --git a/externals/transpile.module_typescript-to-lua.kt b/externals/transpile.module_typescript-to-lua.kt deleted file mode 100644 index 8681706..0000000 --- a/externals/transpile.module_typescript-to-lua.kt +++ /dev/null @@ -1,40 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.Program -import ts.SourceFile -import ts.CustomTransformers -import ts.Diagnostic -import ts.WriteFileCallback - -external interface TranspileOptions { - var program: Program - var sourceFiles: Array? - get() = definedExternally - set(value) = definedExternally - var customTransformers: CustomTransformers? - get() = definedExternally - set(value) = definedExternally - var plugins: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface TranspileResult { - var diagnostics: Array - var transpiledFiles: Array -} - -external fun getProgramTranspileResult(emitHost: EmitHost, writeFileResult: WriteFileCallback, __2: TranspileOptions): TranspileResult \ No newline at end of file diff --git a/externals/transpiler.module_typescript-to-lua.kt b/externals/transpiler.module_typescript-to-lua.kt deleted file mode 100644 index 16b18b0..0000000 --- a/externals/transpiler.module_typescript-to-lua.kt +++ /dev/null @@ -1,55 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.WriteFileCallback -import ts.Diagnostic -import ts.Program - -external interface TranspilerOptions { - var emitHost: EmitHost? - get() = definedExternally - set(value) = definedExternally -} - -external interface EmitOptions : TranspileOptions { - var writeFile: WriteFileCallback? - get() = definedExternally - set(value) = definedExternally -} - -external interface EmitResult { - var emitSkipped: Boolean - var diagnostics: Array -} - -external interface `T$20` { - var emitPlan: Array -} - -external open class Transpiler(__0: TranspilerOptions = definedExternally) { - open var emitHost: EmitHost - open fun emit(emitOptions: EmitOptions): EmitResult - open fun getEmitPlan(program: Program, diagnostics: Array, files: Array): `T$20` -} - -external fun getEmitPath(file: String, program: Program): String - -external fun getEmitPathRelativeToOutDir(fileName: String, program: Program): String - -external fun getSourceDir(program: Program): String - -external fun getEmitOutDir(program: Program): String - -external fun getProjectRoot(program: Program): String \ No newline at end of file diff --git a/externals/tsconfig.module_typescript-to-lua.kt b/externals/tsconfig.module_typescript-to-lua.kt deleted file mode 100644 index 865bc70..0000000 --- a/externals/tsconfig.module_typescript-to-lua.kt +++ /dev/null @@ -1,18 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.System - -external fun parseConfigFileWithSystem(configFileName: String, commandLineOptions: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, system: System = definedExternally): ParsedCommandLine \ No newline at end of file diff --git a/externals/typescript.module_typescript.kt b/externals/typescript.module_typescript.kt deleted file mode 100644 index 83261af..0000000 --- a/externals/typescript.module_typescript.kt +++ /dev/null @@ -1,19 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external fun setTimeout(handler: (args: Any) -> Unit, timeout: Number): Any - -external fun clearTimeout(handle: Any) \ No newline at end of file diff --git a/externals/typescript.ts.ScriptSnapshot.module_typescript.kt b/externals/typescript.ts.ScriptSnapshot.module_typescript.kt deleted file mode 100644 index acab3da..0000000 --- a/externals/typescript.ts.ScriptSnapshot.module_typescript.kt +++ /dev/null @@ -1,20 +0,0 @@ -@file:JsQualifier("ts.ScriptSnapshot") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package ts.ScriptSnapshot - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.IScriptSnapshot - -external fun fromString(text: String): IScriptSnapshot \ No newline at end of file diff --git a/externals/typescript.ts.module_typescript.kt b/externals/typescript.ts.module_typescript.kt deleted file mode 100644 index 841356c..0000000 --- a/externals/typescript.ts.module_typescript.kt +++ /dev/null @@ -1,8236 +0,0 @@ -@file:JsModule("typescript") -@file:JsNonModule -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package ts - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external var versionMajorMinor: Any - -external var version: String - -external interface MapLike { - @nativeGetter - operator fun get(index: String): T? - @nativeSetter - operator fun set(index: String, value: T) -} - -external interface ReadonlyCollection { - val size: Number - fun has(key: K): Boolean - fun keys(): Iterator -} - -external interface Collection : ReadonlyCollection { - fun delete(key: K): Boolean - fun clear() -} - -external interface ReadonlyESMap : ReadonlyCollection { - fun get(key: K): V? - fun values(): Iterator - fun entries(): Iterator */> - fun forEach(action: (value: V, key: K) -> Unit) -} - -external interface ReadonlyMap : ReadonlyESMap - -external interface ESMap : ReadonlyESMap, Collection { - fun set(key: K, value: V): ESMap /* this */ -} - -external interface Map : ESMap - -external interface ReadonlySet : ReadonlyCollection { - override fun has(value: T): Boolean - fun values(): Iterator - fun entries(): Iterator */> - fun forEach(action: (value: T, key: T) -> Unit) -} - -external interface Set : ReadonlySet, Collection { - fun add(value: T): Set /* this */ - override fun delete(value: T): Boolean -} - -external interface Iterator { - fun next(): dynamic /* `T$1` | `T$2` */ -} - -external interface Push { - fun push(vararg values: T) -} - -external interface TextRange { - var pos: Number - var end: Number -} - -external interface ReadonlyTextRange { - val pos: Number - val end: Number -} - -external enum class SyntaxKind { - Unknown /* = 0 */, - EndOfFileToken /* = 1 */, - SingleLineCommentTrivia /* = 2 */, - MultiLineCommentTrivia /* = 3 */, - NewLineTrivia /* = 4 */, - WhitespaceTrivia /* = 5 */, - ShebangTrivia /* = 6 */, - ConflictMarkerTrivia /* = 7 */, - NumericLiteral /* = 8 */, - BigIntLiteral /* = 9 */, - StringLiteral /* = 10 */, - JsxText /* = 11 */, - JsxTextAllWhiteSpaces /* = 12 */, - RegularExpressionLiteral /* = 13 */, - NoSubstitutionTemplateLiteral /* = 14 */, - TemplateHead /* = 15 */, - TemplateMiddle /* = 16 */, - TemplateTail /* = 17 */, - OpenBraceToken /* = 18 */, - CloseBraceToken /* = 19 */, - OpenParenToken /* = 20 */, - CloseParenToken /* = 21 */, - OpenBracketToken /* = 22 */, - CloseBracketToken /* = 23 */, - DotToken /* = 24 */, - DotDotDotToken /* = 25 */, - SemicolonToken /* = 26 */, - CommaToken /* = 27 */, - QuestionDotToken /* = 28 */, - LessThanToken /* = 29 */, - LessThanSlashToken /* = 30 */, - GreaterThanToken /* = 31 */, - LessThanEqualsToken /* = 32 */, - GreaterThanEqualsToken /* = 33 */, - EqualsEqualsToken /* = 34 */, - ExclamationEqualsToken /* = 35 */, - EqualsEqualsEqualsToken /* = 36 */, - ExclamationEqualsEqualsToken /* = 37 */, - EqualsGreaterThanToken /* = 38 */, - PlusToken /* = 39 */, - MinusToken /* = 40 */, - AsteriskToken /* = 41 */, - AsteriskAsteriskToken /* = 42 */, - SlashToken /* = 43 */, - PercentToken /* = 44 */, - PlusPlusToken /* = 45 */, - MinusMinusToken /* = 46 */, - LessThanLessThanToken /* = 47 */, - GreaterThanGreaterThanToken /* = 48 */, - GreaterThanGreaterThanGreaterThanToken /* = 49 */, - AmpersandToken /* = 50 */, - BarToken /* = 51 */, - CaretToken /* = 52 */, - ExclamationToken /* = 53 */, - TildeToken /* = 54 */, - AmpersandAmpersandToken /* = 55 */, - BarBarToken /* = 56 */, - QuestionToken /* = 57 */, - ColonToken /* = 58 */, - AtToken /* = 59 */, - QuestionQuestionToken /* = 60 */, - BacktickToken /* = 61 */, - HashToken /* = 62 */, - EqualsToken /* = 63 */, - PlusEqualsToken /* = 64 */, - MinusEqualsToken /* = 65 */, - AsteriskEqualsToken /* = 66 */, - AsteriskAsteriskEqualsToken /* = 67 */, - SlashEqualsToken /* = 68 */, - PercentEqualsToken /* = 69 */, - LessThanLessThanEqualsToken /* = 70 */, - GreaterThanGreaterThanEqualsToken /* = 71 */, - GreaterThanGreaterThanGreaterThanEqualsToken /* = 72 */, - AmpersandEqualsToken /* = 73 */, - BarEqualsToken /* = 74 */, - BarBarEqualsToken /* = 75 */, - AmpersandAmpersandEqualsToken /* = 76 */, - QuestionQuestionEqualsToken /* = 77 */, - CaretEqualsToken /* = 78 */, - Identifier /* = 79 */, - PrivateIdentifier /* = 80 */, - BreakKeyword /* = 81 */, - CaseKeyword /* = 82 */, - CatchKeyword /* = 83 */, - ClassKeyword /* = 84 */, - ConstKeyword /* = 85 */, - ContinueKeyword /* = 86 */, - DebuggerKeyword /* = 87 */, - DefaultKeyword /* = 88 */, - DeleteKeyword /* = 89 */, - DoKeyword /* = 90 */, - ElseKeyword /* = 91 */, - EnumKeyword /* = 92 */, - ExportKeyword /* = 93 */, - ExtendsKeyword /* = 94 */, - FalseKeyword /* = 95 */, - FinallyKeyword /* = 96 */, - ForKeyword /* = 97 */, - FunctionKeyword /* = 98 */, - IfKeyword /* = 99 */, - ImportKeyword /* = 100 */, - InKeyword /* = 101 */, - InstanceOfKeyword /* = 102 */, - NewKeyword /* = 103 */, - NullKeyword /* = 104 */, - ReturnKeyword /* = 105 */, - SuperKeyword /* = 106 */, - SwitchKeyword /* = 107 */, - ThisKeyword /* = 108 */, - ThrowKeyword /* = 109 */, - TrueKeyword /* = 110 */, - TryKeyword /* = 111 */, - TypeOfKeyword /* = 112 */, - VarKeyword /* = 113 */, - VoidKeyword /* = 114 */, - WhileKeyword /* = 115 */, - WithKeyword /* = 116 */, - ImplementsKeyword /* = 117 */, - InterfaceKeyword /* = 118 */, - LetKeyword /* = 119 */, - PackageKeyword /* = 120 */, - PrivateKeyword /* = 121 */, - ProtectedKeyword /* = 122 */, - PublicKeyword /* = 123 */, - StaticKeyword /* = 124 */, - YieldKeyword /* = 125 */, - AbstractKeyword /* = 126 */, - AsKeyword /* = 127 */, - AssertsKeyword /* = 128 */, - AnyKeyword /* = 129 */, - AsyncKeyword /* = 130 */, - AwaitKeyword /* = 131 */, - BooleanKeyword /* = 132 */, - ConstructorKeyword /* = 133 */, - DeclareKeyword /* = 134 */, - GetKeyword /* = 135 */, - InferKeyword /* = 136 */, - IntrinsicKeyword /* = 137 */, - IsKeyword /* = 138 */, - KeyOfKeyword /* = 139 */, - ModuleKeyword /* = 140 */, - NamespaceKeyword /* = 141 */, - NeverKeyword /* = 142 */, - ReadonlyKeyword /* = 143 */, - RequireKeyword /* = 144 */, - NumberKeyword /* = 145 */, - ObjectKeyword /* = 146 */, - SetKeyword /* = 147 */, - StringKeyword /* = 148 */, - SymbolKeyword /* = 149 */, - TypeKeyword /* = 150 */, - UndefinedKeyword /* = 151 */, - UniqueKeyword /* = 152 */, - UnknownKeyword /* = 153 */, - FromKeyword /* = 154 */, - GlobalKeyword /* = 155 */, - BigIntKeyword /* = 156 */, - OverrideKeyword /* = 157 */, - OfKeyword /* = 158 */, - QualifiedName /* = 159 */, - ComputedPropertyName /* = 160 */, - TypeParameter /* = 161 */, - Parameter /* = 162 */, - Decorator /* = 163 */, - PropertySignature /* = 164 */, - PropertyDeclaration /* = 165 */, - MethodSignature /* = 166 */, - MethodDeclaration /* = 167 */, - ClassStaticBlockDeclaration /* = 168 */, - Constructor /* = 169 */, - GetAccessor /* = 170 */, - SetAccessor /* = 171 */, - CallSignature /* = 172 */, - ConstructSignature /* = 173 */, - IndexSignature /* = 174 */, - TypePredicate /* = 175 */, - TypeReference /* = 176 */, - FunctionType /* = 177 */, - ConstructorType /* = 178 */, - TypeQuery /* = 179 */, - TypeLiteral /* = 180 */, - ArrayType /* = 181 */, - TupleType /* = 182 */, - OptionalType /* = 183 */, - RestType /* = 184 */, - UnionType /* = 185 */, - IntersectionType /* = 186 */, - ConditionalType /* = 187 */, - InferType /* = 188 */, - ParenthesizedType /* = 189 */, - ThisType /* = 190 */, - TypeOperator /* = 191 */, - IndexedAccessType /* = 192 */, - MappedType /* = 193 */, - LiteralType /* = 194 */, - NamedTupleMember /* = 195 */, - TemplateLiteralType /* = 196 */, - TemplateLiteralTypeSpan /* = 197 */, - ImportType /* = 198 */, - ObjectBindingPattern /* = 199 */, - ArrayBindingPattern /* = 200 */, - BindingElement /* = 201 */, - ArrayLiteralExpression /* = 202 */, - ObjectLiteralExpression /* = 203 */, - PropertyAccessExpression /* = 204 */, - ElementAccessExpression /* = 205 */, - CallExpression /* = 206 */, - NewExpression /* = 207 */, - TaggedTemplateExpression /* = 208 */, - TypeAssertionExpression /* = 209 */, - ParenthesizedExpression /* = 210 */, - FunctionExpression /* = 211 */, - ArrowFunction /* = 212 */, - DeleteExpression /* = 213 */, - TypeOfExpression /* = 214 */, - VoidExpression /* = 215 */, - AwaitExpression /* = 216 */, - PrefixUnaryExpression /* = 217 */, - PostfixUnaryExpression /* = 218 */, - BinaryExpression /* = 219 */, - ConditionalExpression /* = 220 */, - TemplateExpression /* = 221 */, - YieldExpression /* = 222 */, - SpreadElement /* = 223 */, - ClassExpression /* = 224 */, - OmittedExpression /* = 225 */, - ExpressionWithTypeArguments /* = 226 */, - AsExpression /* = 227 */, - NonNullExpression /* = 228 */, - MetaProperty /* = 229 */, - SyntheticExpression /* = 230 */, - TemplateSpan /* = 231 */, - SemicolonClassElement /* = 232 */, - Block /* = 233 */, - EmptyStatement /* = 234 */, - VariableStatement /* = 235 */, - ExpressionStatement /* = 236 */, - IfStatement /* = 237 */, - DoStatement /* = 238 */, - WhileStatement /* = 239 */, - ForStatement /* = 240 */, - ForInStatement /* = 241 */, - ForOfStatement /* = 242 */, - ContinueStatement /* = 243 */, - BreakStatement /* = 244 */, - ReturnStatement /* = 245 */, - WithStatement /* = 246 */, - SwitchStatement /* = 247 */, - LabeledStatement /* = 248 */, - ThrowStatement /* = 249 */, - TryStatement /* = 250 */, - DebuggerStatement /* = 251 */, - VariableDeclaration /* = 252 */, - VariableDeclarationList /* = 253 */, - FunctionDeclaration /* = 254 */, - ClassDeclaration /* = 255 */, - InterfaceDeclaration /* = 256 */, - TypeAliasDeclaration /* = 257 */, - EnumDeclaration /* = 258 */, - ModuleDeclaration /* = 259 */, - ModuleBlock /* = 260 */, - CaseBlock /* = 261 */, - NamespaceExportDeclaration /* = 262 */, - ImportEqualsDeclaration /* = 263 */, - ImportDeclaration /* = 264 */, - ImportClause /* = 265 */, - NamespaceImport /* = 266 */, - NamedImports /* = 267 */, - ImportSpecifier /* = 268 */, - ExportAssignment /* = 269 */, - ExportDeclaration /* = 270 */, - NamedExports /* = 271 */, - NamespaceExport /* = 272 */, - ExportSpecifier /* = 273 */, - MissingDeclaration /* = 274 */, - ExternalModuleReference /* = 275 */, - JsxElement /* = 276 */, - JsxSelfClosingElement /* = 277 */, - JsxOpeningElement /* = 278 */, - JsxClosingElement /* = 279 */, - JsxFragment /* = 280 */, - JsxOpeningFragment /* = 281 */, - JsxClosingFragment /* = 282 */, - JsxAttribute /* = 283 */, - JsxAttributes /* = 284 */, - JsxSpreadAttribute /* = 285 */, - JsxExpression /* = 286 */, - CaseClause /* = 287 */, - DefaultClause /* = 288 */, - HeritageClause /* = 289 */, - CatchClause /* = 290 */, - PropertyAssignment /* = 291 */, - ShorthandPropertyAssignment /* = 292 */, - SpreadAssignment /* = 293 */, - EnumMember /* = 294 */, - UnparsedPrologue /* = 295 */, - UnparsedPrepend /* = 296 */, - UnparsedText /* = 297 */, - UnparsedInternalText /* = 298 */, - UnparsedSyntheticReference /* = 299 */, - SourceFile /* = 300 */, - Bundle /* = 301 */, - UnparsedSource /* = 302 */, - InputFiles /* = 303 */, - JSDocTypeExpression /* = 304 */, - JSDocNameReference /* = 305 */, - JSDocMemberName /* = 306 */, - JSDocAllType /* = 307 */, - JSDocUnknownType /* = 308 */, - JSDocNullableType /* = 309 */, - JSDocNonNullableType /* = 310 */, - JSDocOptionalType /* = 311 */, - JSDocFunctionType /* = 312 */, - JSDocVariadicType /* = 313 */, - JSDocNamepathType /* = 314 */, - JSDocComment /* = 315 */, - JSDocText /* = 316 */, - JSDocTypeLiteral /* = 317 */, - JSDocSignature /* = 318 */, - JSDocLink /* = 319 */, - JSDocLinkCode /* = 320 */, - JSDocLinkPlain /* = 321 */, - JSDocTag /* = 322 */, - JSDocAugmentsTag /* = 323 */, - JSDocImplementsTag /* = 324 */, - JSDocAuthorTag /* = 325 */, - JSDocDeprecatedTag /* = 326 */, - JSDocClassTag /* = 327 */, - JSDocPublicTag /* = 328 */, - JSDocPrivateTag /* = 329 */, - JSDocProtectedTag /* = 330 */, - JSDocReadonlyTag /* = 331 */, - JSDocOverrideTag /* = 332 */, - JSDocCallbackTag /* = 333 */, - JSDocEnumTag /* = 334 */, - JSDocParameterTag /* = 335 */, - JSDocReturnTag /* = 336 */, - JSDocThisTag /* = 337 */, - JSDocTypeTag /* = 338 */, - JSDocTemplateTag /* = 339 */, - JSDocTypedefTag /* = 340 */, - JSDocSeeTag /* = 341 */, - JSDocPropertyTag /* = 342 */, - SyntaxList /* = 343 */, - NotEmittedStatement /* = 344 */, - PartiallyEmittedExpression /* = 345 */, - CommaListExpression /* = 346 */, - MergeDeclarationMarker /* = 347 */, - EndOfDeclarationMarker /* = 348 */, - SyntheticReferenceExpression /* = 349 */, - Count /* = 350 */, - FirstAssignment /* = 63 */, - LastAssignment /* = 78 */, - FirstCompoundAssignment /* = 64 */, - LastCompoundAssignment /* = 78 */, - FirstReservedWord /* = 81 */, - LastReservedWord /* = 116 */, - FirstKeyword /* = 81 */, - LastKeyword /* = 158 */, - FirstFutureReservedWord /* = 117 */, - LastFutureReservedWord /* = 125 */, - FirstTypeNode /* = 175 */, - LastTypeNode /* = 198 */, - FirstPunctuation /* = 18 */, - LastPunctuation /* = 78 */, - FirstToken /* = 0 */, - LastToken /* = 158 */, - FirstTriviaToken /* = 2 */, - LastTriviaToken /* = 7 */, - FirstLiteralToken /* = 8 */, - LastLiteralToken /* = 14 */, - FirstTemplateToken /* = 14 */, - LastTemplateToken /* = 17 */, - FirstBinaryOperator /* = 29 */, - LastBinaryOperator /* = 78 */, - FirstStatement /* = 235 */, - LastStatement /* = 251 */, - FirstNode /* = 159 */, - FirstJSDocNode /* = 304 */, - LastJSDocNode /* = 342 */, - FirstJSDocTagNode /* = 322 */, - LastJSDocTagNode /* = 342 */ -} - -external enum class NodeFlags { - None /* = 0 */, - Let /* = 1 */, - Const /* = 2 */, - NestedNamespace /* = 4 */, - Synthesized /* = 8 */, - Namespace /* = 16 */, - OptionalChain /* = 32 */, - ExportContext /* = 64 */, - ContainsThis /* = 128 */, - HasImplicitReturn /* = 256 */, - HasExplicitReturn /* = 512 */, - GlobalAugmentation /* = 1024 */, - HasAsyncFunctions /* = 2048 */, - DisallowInContext /* = 4096 */, - YieldContext /* = 8192 */, - DecoratorContext /* = 16384 */, - AwaitContext /* = 32768 */, - ThisNodeHasError /* = 65536 */, - JavaScriptFile /* = 131072 */, - ThisNodeOrAnySubNodesHasError /* = 262144 */, - HasAggregatedChildData /* = 524288 */, - JSDoc /* = 4194304 */, - JsonFile /* = 33554432 */, - BlockScoped /* = 3 */, - ReachabilityCheckFlags /* = 768 */, - ReachabilityAndEmitFlags /* = 2816 */, - ContextFlags /* = 25358336 */, - TypeExcludesFlags /* = 40960 */ -} - -external enum class ModifierFlags { - None /* = 0 */, - Export /* = 1 */, - Ambient /* = 2 */, - Public /* = 4 */, - Private /* = 8 */, - Protected /* = 16 */, - Static /* = 32 */, - Readonly /* = 64 */, - Abstract /* = 128 */, - Async /* = 256 */, - Default /* = 512 */, - Const /* = 2048 */, - HasComputedJSDocModifiers /* = 4096 */, - Deprecated /* = 8192 */, - Override /* = 16384 */, - HasComputedFlags /* = 536870912 */, - AccessibilityModifier /* = 28 */, - ParameterPropertyModifier /* = 16476 */, - NonPublicAccessibilityModifier /* = 24 */, - TypeScriptModifier /* = 18654 */, - ExportDefault /* = 513 */, - All /* = 27647 */ -} - -external enum class JsxFlags { - None /* = 0 */, - IntrinsicNamedElement /* = 1 */, - IntrinsicIndexedElement /* = 2 */, - IntrinsicElement /* = 3 */ -} - -external interface Node : ReadonlyTextRange { - fun getSourceFile(): SourceFile - fun getChildCount(sourceFile: SourceFile = definedExternally): Number - fun getChildAt(index: Number, sourceFile: SourceFile = definedExternally): Node - fun getChildren(sourceFile: SourceFile = definedExternally): Array - fun getStart(sourceFile: SourceFile = definedExternally, includeJsDocComment: Boolean = definedExternally): Number - fun getFullStart(): Number - fun getEnd(): Number - fun getWidth(sourceFile: SourceFileLike = definedExternally): Number - fun getFullWidth(): Number - fun getLeadingTriviaWidth(sourceFile: SourceFile = definedExternally): Number - fun getFullText(sourceFile: SourceFile = definedExternally): String - fun getText(sourceFile: SourceFile = definedExternally): String - fun getFirstToken(sourceFile: SourceFile = definedExternally): Node? - fun getLastToken(sourceFile: SourceFile = definedExternally): Node? - fun forEachChild(cbNode: (node: Node) -> T?, cbNodeArray: (nodes: NodeArray) -> T? = definedExternally): T? - val kind: SyntaxKind - val flags: NodeFlags - val decorators: NodeArray? - get() = definedExternally - val modifiers: ModifiersArray? - get() = definedExternally - val parent: Node -} - -external interface JSDocContainer - -external interface Token : Node { - override val kind: TKind -} - -external interface PunctuationToken : Token - -external interface KeywordToken : Token - -external interface ModifierToken : KeywordToken - -external enum class GeneratedIdentifierFlags { - None /* = 0 */, - ReservedInNestedScopes /* = 8 */, - Optimistic /* = 16 */, - FileLevel /* = 32 */, - AllowNameSubstitution /* = 64 */ -} - -external interface Identifier : PrimaryExpression, Declaration { - val text: String - val escapedText: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - get() = definedExternally - val originalKeywordKind: SyntaxKind? - get() = definedExternally - var isInJSDocNamespace: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TransientIdentifier : Identifier { - var resolvedSymbol: Symbol -} - -external interface QualifiedName : Node { - val left: dynamic /* Identifier | QualifiedName */ - get() = definedExternally - val right: Identifier -} - -external interface Declaration : Node { - var _declarationBrand: Any -} - -external interface NamedDeclaration : Declaration { - val name: dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ - get() = definedExternally -} - -external interface DeclarationStatement : NamedDeclaration, Statement { - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? */ - get() = definedExternally -} - -external interface ComputedPropertyName : Node { - override val parent: Declaration - val expression: Expression -} - -external interface PrivateIdentifier : Node { - val text: String - val escapedText: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - get() = definedExternally -} - -external interface Decorator : Node { - override val parent: NamedDeclaration - val expression: LeftHandSideExpression -} - -external interface TypeParameterDeclaration : NamedDeclaration { - override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | InferTypeNode */ - get() = definedExternally - override val name: Identifier - val constraint: TypeNode? - get() = definedExternally - val default: TypeNode? - get() = definedExternally - var expression: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureDeclarationBase : NamedDeclaration, JSDocContainer { - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - val typeParameters: NodeArray? - get() = definedExternally - val parameters: NodeArray - val type: TypeNode? - get() = definedExternally -} - -external interface CallSignatureDeclaration : SignatureDeclarationBase, TypeElement { - override val kind: Any - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally -} - -external interface ConstructSignatureDeclaration : SignatureDeclarationBase, TypeElement { - override val kind: Any - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally -} - -external interface VariableDeclaration : NamedDeclaration, JSDocContainer { - override val parent: dynamic /* VariableDeclarationList | CatchClause */ - get() = definedExternally - override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ - get() = definedExternally - val exclamationToken: ExclamationToken? - get() = definedExternally - val type: TypeNode? - get() = definedExternally - val initializer: Expression? - get() = definedExternally -} - -external interface VariableDeclarationList : Node { - override val parent: dynamic /* VariableStatement | ForStatement | ForOfStatement | ForInStatement */ - get() = definedExternally - val declarations: NodeArray -} - -external interface ParameterDeclaration : NamedDeclaration, JSDocContainer { - override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ - get() = definedExternally - val dotDotDotToken: DotDotDotToken? - get() = definedExternally - override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ - get() = definedExternally - val questionToken: QuestionToken? - get() = definedExternally - val type: TypeNode? - get() = definedExternally - val initializer: Expression? - get() = definedExternally -} - -external interface BindingElement : NamedDeclaration { - override val parent: dynamic /* ObjectBindingPattern | ArrayBindingPattern */ - get() = definedExternally - val propertyName: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - val dotDotDotToken: DotDotDotToken? - get() = definedExternally - override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ - get() = definedExternally - val initializer: Expression? - get() = definedExternally -} - -external interface PropertySignature : TypeElement, JSDocContainer { - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - override val questionToken: QuestionToken? - get() = definedExternally - val type: TypeNode? - get() = definedExternally - var initializer: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface PropertyDeclaration : ClassElement, JSDocContainer { - override val parent: dynamic /* ClassDeclaration | ClassExpression */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - val questionToken: QuestionToken? - get() = definedExternally - val exclamationToken: ExclamationToken? - get() = definedExternally - val type: TypeNode? - get() = definedExternally - val initializer: Expression? - get() = definedExternally -} - -external interface ObjectLiteralElement : NamedDeclaration { - var _objectLiteralBrand: Any - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally -} - -external interface PropertyAssignment : ObjectLiteralElement, JSDocContainer { - override val parent: ObjectLiteralExpression - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - val questionToken: QuestionToken? - get() = definedExternally - val exclamationToken: ExclamationToken? - get() = definedExternally - val initializer: Expression -} - -external interface ShorthandPropertyAssignment : ObjectLiteralElement, JSDocContainer { - override val parent: ObjectLiteralExpression - override val name: Identifier - val questionToken: QuestionToken? - get() = definedExternally - val exclamationToken: ExclamationToken? - get() = definedExternally - val equalsToken: EqualsToken? - get() = definedExternally - val objectAssignmentInitializer: Expression? - get() = definedExternally -} - -external interface SpreadAssignment : ObjectLiteralElement, JSDocContainer { - override val parent: ObjectLiteralExpression - val expression: Expression -} - -external interface PropertyLikeDeclaration : NamedDeclaration { - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally -} - -external interface ObjectBindingPattern : Node { - override val parent: dynamic /* VariableDeclaration | ParameterDeclaration | BindingElement */ - get() = definedExternally - val elements: NodeArray -} - -external interface ArrayBindingPattern : Node { - override val parent: dynamic /* VariableDeclaration | ParameterDeclaration | BindingElement */ - get() = definedExternally - val elements: NodeArray -} - -external interface FunctionLikeDeclarationBase : SignatureDeclarationBase { - var _functionLikeDeclarationBrand: Any - val asteriskToken: AsteriskToken? - get() = definedExternally - val questionToken: QuestionToken? - get() = definedExternally - val exclamationToken: ExclamationToken? - get() = definedExternally - val body: dynamic /* Block? | Expression? */ - get() = definedExternally -} - -external interface FunctionDeclaration : FunctionLikeDeclarationBase, DeclarationStatement { - override val kind: Any - override val name: Identifier? - get() = definedExternally - override val body: FunctionBody? - get() = definedExternally -} - -external interface MethodSignature : SignatureDeclarationBase, TypeElement { - override val kind: Any - override val parent: dynamic /* ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally -} - -external interface MethodDeclaration : FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { - override val kind: Any - override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - override val body: FunctionBody? - get() = definedExternally -} - -external interface ConstructorDeclaration : FunctionLikeDeclarationBase, ClassElement, JSDocContainer { - override val kind: Any - override val parent: dynamic /* ClassDeclaration | ClassExpression */ - get() = definedExternally - override val body: FunctionBody? - get() = definedExternally -} - -external interface SemicolonClassElement : ClassElement { - override val parent: dynamic /* ClassDeclaration | ClassExpression */ - get() = definedExternally -} - -external interface GetAccessorDeclaration : FunctionLikeDeclarationBase, ClassElement, TypeElement, ObjectLiteralElement, JSDocContainer { - override val kind: Any - override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression | TypeLiteralNode | InterfaceDeclaration */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - override val body: FunctionBody? - get() = definedExternally - override val questionToken: QuestionToken? - get() = definedExternally -} - -external interface SetAccessorDeclaration : FunctionLikeDeclarationBase, ClassElement, TypeElement, ObjectLiteralElement, JSDocContainer { - override val kind: Any - override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression | TypeLiteralNode | InterfaceDeclaration */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - override val body: FunctionBody? - get() = definedExternally - override val questionToken: QuestionToken? - get() = definedExternally -} - -external interface IndexSignatureDeclaration : SignatureDeclarationBase, ClassElement, TypeElement { - override val kind: Any - override val parent: dynamic /* ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode */ - get() = definedExternally - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally -} - -external interface ClassStaticBlockDeclaration : ClassElement, JSDocContainer { - override val parent: dynamic /* ClassDeclaration | ClassExpression */ - get() = definedExternally - val body: Block -} - -external interface TypeNode : Node { - var _typeNodeBrand: Any -} - -external interface KeywordTypeNode : KeywordToken, TypeNode { - override val kind: TKind -} - -external interface ImportTypeNode : NodeWithTypeArguments { - val isTypeOf: Boolean - val argument: TypeNode - val qualifier: dynamic /* Identifier? | QualifiedName? */ - get() = definedExternally -} - -external interface ThisTypeNode : TypeNode - -external interface FunctionOrConstructorTypeNodeBase : TypeNode, SignatureDeclarationBase { - override val kind: dynamic /* SyntaxKind.FunctionType | SyntaxKind.ConstructorType */ - get() = definedExternally -} - -external interface FunctionTypeNode : FunctionOrConstructorTypeNodeBase { - override val kind: Any -} - -external interface ConstructorTypeNode : FunctionOrConstructorTypeNodeBase { - override val kind: Any -} - -external interface NodeWithTypeArguments : TypeNode { - val typeArguments: NodeArray? - get() = definedExternally -} - -external interface TypeReferenceNode : NodeWithTypeArguments { - val typeName: dynamic /* Identifier | QualifiedName */ - get() = definedExternally -} - -external interface TypePredicateNode : TypeNode { - override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | JSDocTypeExpression */ - get() = definedExternally - val assertsModifier: AssertsToken? - get() = definedExternally - val parameterName: dynamic /* Identifier | ThisTypeNode */ - get() = definedExternally - val type: TypeNode? - get() = definedExternally -} - -external interface TypeQueryNode : TypeNode { - val exprName: dynamic /* Identifier | QualifiedName */ - get() = definedExternally -} - -external interface TypeLiteralNode : TypeNode, Declaration { - val members: NodeArray -} - -external interface ArrayTypeNode : TypeNode { - val elementType: TypeNode -} - -external interface TupleTypeNode : TypeNode { - val elements: NodeArray -} - -external interface NamedTupleMember : TypeNode, JSDocContainer, Declaration { - val dotDotDotToken: Token? - get() = definedExternally - val name: Identifier - val questionToken: Token? - get() = definedExternally - val type: TypeNode -} - -external interface OptionalTypeNode : TypeNode { - val type: TypeNode -} - -external interface RestTypeNode : TypeNode { - val type: TypeNode -} - -external interface UnionTypeNode : TypeNode { - val types: NodeArray -} - -external interface IntersectionTypeNode : TypeNode { - val types: NodeArray -} - -external interface ConditionalTypeNode : TypeNode { - val checkType: TypeNode - val extendsType: TypeNode - val trueType: TypeNode - val falseType: TypeNode -} - -external interface InferTypeNode : TypeNode { - val typeParameter: TypeParameterDeclaration -} - -external interface ParenthesizedTypeNode : TypeNode { - val type: TypeNode -} - -external interface TypeOperatorNode : TypeNode { - val operator: dynamic /* SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword */ - get() = definedExternally - val type: TypeNode -} - -external interface IndexedAccessTypeNode : TypeNode { - val objectType: TypeNode - val indexType: TypeNode -} - -external interface MappedTypeNode : TypeNode, Declaration { - val readonlyToken: dynamic /* ReadonlyToken? | PlusToken? | MinusToken? */ - get() = definedExternally - val typeParameter: TypeParameterDeclaration - val nameType: TypeNode? - get() = definedExternally - val questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */ - get() = definedExternally - val type: TypeNode? - get() = definedExternally -} - -external interface LiteralTypeNode : TypeNode { - val literal: dynamic /* NullLiteral | TrueLiteral | FalseLiteral | LiteralExpression | PrefixUnaryExpression */ - get() = definedExternally -} - -external interface StringLiteral : LiteralExpression, Declaration - -external interface TemplateLiteralTypeNode : TypeNode { - val head: TemplateHead - val templateSpans: NodeArray -} - -external interface TemplateLiteralTypeSpan : TypeNode { - override val parent: TemplateLiteralTypeNode - val type: TypeNode - val literal: dynamic /* TemplateMiddle | TemplateTail */ - get() = definedExternally -} - -external interface Expression : Node { - var _expressionBrand: Any -} - -external interface OmittedExpression : Expression - -external interface PartiallyEmittedExpression : LeftHandSideExpression { - val expression: Expression -} - -external interface UnaryExpression : Expression { - var _unaryExpressionBrand: Any -} - -external interface UpdateExpression : UnaryExpression { - var _updateExpressionBrand: Any -} - -external interface PrefixUnaryExpression : UpdateExpression { - val operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken | SyntaxKind.ExclamationToken */ - get() = definedExternally - val operand: UnaryExpression -} - -external interface PostfixUnaryExpression : UpdateExpression { - val operand: LeftHandSideExpression - val operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken */ - get() = definedExternally -} - -external interface LeftHandSideExpression : UpdateExpression { - var _leftHandSideExpressionBrand: Any -} - -external interface MemberExpression : LeftHandSideExpression { - var _memberExpressionBrand: Any -} - -external interface PrimaryExpression : MemberExpression { - var _primaryExpressionBrand: Any -} - -external interface NullLiteral : PrimaryExpression - -external interface TrueLiteral : PrimaryExpression - -external interface FalseLiteral : PrimaryExpression - -external interface ThisExpression : PrimaryExpression - -external interface SuperExpression : PrimaryExpression - -external interface ImportExpression : PrimaryExpression - -external interface DeleteExpression : UnaryExpression { - val expression: UnaryExpression -} - -external interface TypeOfExpression : UnaryExpression { - val expression: UnaryExpression -} - -external interface VoidExpression : UnaryExpression { - val expression: UnaryExpression -} - -external interface AwaitExpression : UnaryExpression { - val expression: UnaryExpression -} - -external interface YieldExpression : Expression { - val asteriskToken: AsteriskToken? - get() = definedExternally - val expression: Expression? - get() = definedExternally -} - -external interface SyntheticExpression : Expression { - val isSpread: Boolean - val type: Type - val tupleNameSource: dynamic /* ParameterDeclaration? | NamedTupleMember? */ - get() = definedExternally -} - -external interface BinaryExpression : Expression, Declaration { - val left: Expression - val operatorToken: BinaryOperatorToken - val right: Expression -} - -external interface AssignmentExpression : BinaryExpression { - override val left: LeftHandSideExpression - override val operatorToken: TOperator -} - -external interface ObjectDestructuringAssignment : AssignmentExpression { - override val left: ObjectLiteralExpression -} - -external interface ArrayDestructuringAssignment : AssignmentExpression { - override val left: ArrayLiteralExpression -} - -external interface ConditionalExpression : Expression { - val condition: Expression - val questionToken: QuestionToken - val whenTrue: Expression - val colonToken: ColonToken - val whenFalse: Expression -} - -external interface FunctionExpression : PrimaryExpression, FunctionLikeDeclarationBase, JSDocContainer { - override val kind: Any - override val name: Identifier? - get() = definedExternally - override val body: FunctionBody -} - -external interface ArrowFunction : Expression, FunctionLikeDeclarationBase, JSDocContainer { - override val kind: Any - val equalsGreaterThanToken: EqualsGreaterThanToken - override val body: dynamic /* FunctionBody | Expression */ - get() = definedExternally - override val name: Any -} - -external interface LiteralLikeNode : Node { - var text: String - var isUnterminated: Boolean? - get() = definedExternally - set(value) = definedExternally - var hasExtendedUnicodeEscape: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TemplateLiteralLikeNode : LiteralLikeNode { - var rawText: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface LiteralExpression : LiteralLikeNode, PrimaryExpression { - var _literalExpressionBrand: Any -} - -external interface RegularExpressionLiteral : LiteralExpression - -external interface NoSubstitutionTemplateLiteral : LiteralExpression, TemplateLiteralLikeNode, Declaration - -external enum class TokenFlags { - None /* = 0 */, - Scientific /* = 16 */, - Octal /* = 32 */, - HexSpecifier /* = 64 */, - BinarySpecifier /* = 128 */, - OctalSpecifier /* = 256 */ -} - -external interface NumericLiteral : LiteralExpression, Declaration - -external interface BigIntLiteral : LiteralExpression - -external interface TemplateHead : TemplateLiteralLikeNode { - override val parent: dynamic /* TemplateExpression | TemplateLiteralTypeNode */ - get() = definedExternally -} - -external interface TemplateMiddle : TemplateLiteralLikeNode { - override val parent: dynamic /* TemplateSpan | TemplateLiteralTypeSpan */ - get() = definedExternally -} - -external interface TemplateTail : TemplateLiteralLikeNode { - override val parent: dynamic /* TemplateSpan | TemplateLiteralTypeSpan */ - get() = definedExternally -} - -external interface TemplateExpression : PrimaryExpression { - val head: TemplateHead - val templateSpans: NodeArray -} - -external interface TemplateSpan : Node { - override val parent: TemplateExpression - val expression: Expression - val literal: dynamic /* TemplateMiddle | TemplateTail */ - get() = definedExternally -} - -external interface ParenthesizedExpression : PrimaryExpression, JSDocContainer { - val expression: Expression -} - -external interface ArrayLiteralExpression : PrimaryExpression { - val elements: NodeArray -} - -external interface SpreadElement : Expression { - override val parent: dynamic /* ArrayLiteralExpression | CallExpression | NewExpression */ - get() = definedExternally - val expression: Expression -} - -external interface ObjectLiteralExpressionBase : PrimaryExpression, Declaration { - val properties: NodeArray -} - -external interface ObjectLiteralExpression : ObjectLiteralExpressionBase - -external interface PropertyAccessExpression : MemberExpression, NamedDeclaration { - val expression: LeftHandSideExpression - val questionDotToken: QuestionDotToken? - get() = definedExternally - override val name: dynamic /* Identifier | PrivateIdentifier */ - get() = definedExternally -} - -external interface PropertyAccessChain : PropertyAccessExpression { - var _optionalChainBrand: Any - override val name: dynamic /* Identifier | PrivateIdentifier */ - get() = definedExternally -} - -external interface SuperPropertyAccessExpression : PropertyAccessExpression { - override val expression: SuperExpression -} - -external interface PropertyAccessEntityNameExpression : PropertyAccessExpression { - var _propertyAccessExpressionLikeQualifiedNameBrand: Any? - get() = definedExternally - set(value) = definedExternally - override val expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ - get() = definedExternally - override val name: Identifier -} - -external interface ElementAccessExpression : MemberExpression { - val expression: LeftHandSideExpression - val questionDotToken: QuestionDotToken? - get() = definedExternally - val argumentExpression: Expression -} - -external interface ElementAccessChain : ElementAccessExpression { - var _optionalChainBrand: Any -} - -external interface SuperElementAccessExpression : ElementAccessExpression { - override val expression: SuperExpression -} - -external interface CallExpression : LeftHandSideExpression, Declaration { - val expression: LeftHandSideExpression - val questionDotToken: QuestionDotToken? - get() = definedExternally - val typeArguments: NodeArray? - get() = definedExternally - val arguments: NodeArray -} - -external interface CallChain : CallExpression { - var _optionalChainBrand: Any -} - -external interface SuperCall : CallExpression { - override val expression: SuperExpression -} - -external interface ImportCall : CallExpression { - override val expression: ImportExpression -} - -external interface ExpressionWithTypeArguments : NodeWithTypeArguments { - override val parent: dynamic /* HeritageClause | JSDocAugmentsTag | JSDocImplementsTag */ - get() = definedExternally - val expression: LeftHandSideExpression -} - -external interface NewExpression : PrimaryExpression, Declaration { - val expression: LeftHandSideExpression - val typeArguments: NodeArray? - get() = definedExternally - val arguments: NodeArray? - get() = definedExternally -} - -external interface TaggedTemplateExpression : MemberExpression { - val tag: LeftHandSideExpression - val typeArguments: NodeArray? - get() = definedExternally - val template: dynamic /* TemplateExpression | NoSubstitutionTemplateLiteral */ - get() = definedExternally -} - -external interface AsExpression : Expression { - val expression: Expression - val type: TypeNode -} - -external interface TypeAssertion : UnaryExpression { - val type: TypeNode - val expression: UnaryExpression -} - -external interface NonNullExpression : LeftHandSideExpression { - val expression: Expression -} - -external interface NonNullChain : NonNullExpression { - var _optionalChainBrand: Any -} - -external interface MetaProperty : PrimaryExpression { - val keywordToken: dynamic /* SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword */ - get() = definedExternally - val name: Identifier -} - -external interface JsxElement : PrimaryExpression { - val openingElement: JsxOpeningElement - val children: NodeArray - val closingElement: JsxClosingElement -} - -external interface JsxTagNamePropertyAccess : PropertyAccessExpression { - override val expression: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ - get() = definedExternally -} - -external interface JsxAttributes : ObjectLiteralExpressionBase { - override val parent: dynamic /* JsxSelfClosingElement | JsxOpeningElement */ - get() = definedExternally -} - -external interface JsxOpeningElement : Expression { - override val parent: JsxElement - val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ - get() = definedExternally - val typeArguments: NodeArray? - get() = definedExternally - val attributes: JsxAttributes -} - -external interface JsxSelfClosingElement : PrimaryExpression { - val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ - get() = definedExternally - val typeArguments: NodeArray? - get() = definedExternally - val attributes: JsxAttributes -} - -external interface JsxFragment : PrimaryExpression { - val openingFragment: JsxOpeningFragment - val children: NodeArray - val closingFragment: JsxClosingFragment -} - -external interface JsxOpeningFragment : Expression { - override val parent: JsxFragment -} - -external interface JsxClosingFragment : Expression { - override val parent: JsxFragment -} - -external interface JsxAttribute : ObjectLiteralElement { - override val parent: JsxAttributes - override val name: Identifier - val initializer: dynamic /* StringLiteral? | JsxExpression? */ - get() = definedExternally -} - -external interface JsxSpreadAttribute : ObjectLiteralElement { - override val parent: JsxAttributes - val expression: Expression -} - -external interface JsxClosingElement : Node { - override val parent: JsxElement - val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ - get() = definedExternally -} - -external interface JsxExpression : Expression { - override val parent: dynamic /* JsxElement | JsxAttribute | JsxSpreadAttribute */ - get() = definedExternally - val dotDotDotToken: Token? - get() = definedExternally - val expression: Expression? - get() = definedExternally -} - -external interface JsxText : LiteralLikeNode { - override val parent: JsxElement - val containsOnlyTriviaWhiteSpaces: Boolean -} - -external interface Statement : Node, JSDocContainer { - var _statementBrand: Any -} - -external interface NotEmittedStatement : Statement - -external interface CommaListExpression : Expression { - val elements: NodeArray -} - -external interface EmptyStatement : Statement - -external interface DebuggerStatement : Statement - -external interface MissingDeclaration : DeclarationStatement { - override val name: Identifier? - get() = definedExternally -} - -external interface Block : Statement { - val statements: NodeArray -} - -external interface VariableStatement : Statement { - val declarationList: VariableDeclarationList -} - -external interface ExpressionStatement : Statement { - val expression: Expression -} - -external interface IfStatement : Statement { - val expression: Expression - val thenStatement: Statement - val elseStatement: Statement? - get() = definedExternally -} - -external interface IterationStatement : Statement { - val statement: Statement -} - -external interface DoStatement : IterationStatement { - val expression: Expression -} - -external interface WhileStatement : IterationStatement { - val expression: Expression -} - -external interface ForStatement : IterationStatement { - val initializer: dynamic /* VariableDeclarationList? | Expression? */ - get() = definedExternally - val condition: Expression? - get() = definedExternally - val incrementor: Expression? - get() = definedExternally -} - -external interface ForInStatement : IterationStatement { - val initializer: dynamic /* VariableDeclarationList | Expression */ - get() = definedExternally - val expression: Expression -} - -external interface ForOfStatement : IterationStatement { - val awaitModifier: AwaitKeywordToken? - get() = definedExternally - val initializer: dynamic /* VariableDeclarationList | Expression */ - get() = definedExternally - val expression: Expression -} - -external interface BreakStatement : Statement { - val label: Identifier? - get() = definedExternally -} - -external interface ContinueStatement : Statement { - val label: Identifier? - get() = definedExternally -} - -external interface ReturnStatement : Statement { - val expression: Expression? - get() = definedExternally -} - -external interface WithStatement : Statement { - val expression: Expression - val statement: Statement -} - -external interface SwitchStatement : Statement { - val expression: Expression - val caseBlock: CaseBlock - var possiblyExhaustive: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface CaseBlock : Node { - override val parent: SwitchStatement - val clauses: NodeArray -} - -external interface CaseClause : Node { - override val parent: CaseBlock - val expression: Expression - val statements: NodeArray -} - -external interface DefaultClause : Node { - override val parent: CaseBlock - val statements: NodeArray -} - -external interface LabeledStatement : Statement { - val label: Identifier - val statement: Statement -} - -external interface ThrowStatement : Statement { - val expression: Expression -} - -external interface TryStatement : Statement { - val tryBlock: Block - val catchClause: CatchClause? - get() = definedExternally - val finallyBlock: Block? - get() = definedExternally -} - -external interface CatchClause : Node { - override val parent: TryStatement - val variableDeclaration: VariableDeclaration? - get() = definedExternally - val block: Block -} - -external interface ClassLikeDeclarationBase : NamedDeclaration, JSDocContainer { - override val kind: dynamic /* SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression */ - get() = definedExternally - override val name: Identifier? - get() = definedExternally - val typeParameters: NodeArray? - get() = definedExternally - val heritageClauses: NodeArray? - get() = definedExternally - val members: NodeArray -} - -external interface ClassDeclaration : ClassLikeDeclarationBase, DeclarationStatement { - override val kind: Any - override val name: Identifier? - get() = definedExternally -} - -external interface ClassExpression : ClassLikeDeclarationBase, PrimaryExpression { - override val kind: Any -} - -external interface ClassElement : NamedDeclaration { - var _classElementBrand: Any - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally -} - -external interface TypeElement : NamedDeclaration { - var _typeElementBrand: Any - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - val questionToken: QuestionToken? - get() = definedExternally -} - -external interface InterfaceDeclaration : DeclarationStatement, JSDocContainer { - override val name: Identifier - val typeParameters: NodeArray? - get() = definedExternally - val heritageClauses: NodeArray? - get() = definedExternally - val members: NodeArray -} - -external interface HeritageClause : Node { - override val parent: dynamic /* InterfaceDeclaration | ClassDeclaration | ClassExpression */ - get() = definedExternally - val token: dynamic /* SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword */ - get() = definedExternally - val types: NodeArray -} - -external interface TypeAliasDeclaration : DeclarationStatement, JSDocContainer { - override val name: Identifier - val typeParameters: NodeArray? - get() = definedExternally - val type: TypeNode -} - -external interface EnumMember : NamedDeclaration, JSDocContainer { - override val parent: EnumDeclaration - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - val initializer: Expression? - get() = definedExternally -} - -external interface EnumDeclaration : DeclarationStatement, JSDocContainer { - override val name: Identifier - val members: NodeArray -} - -external interface ModuleDeclaration : DeclarationStatement, JSDocContainer { - override val parent: dynamic /* ModuleBlock | NamespaceDeclaration | Identifier | JSDocNamespaceDeclaration | SourceFile */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral */ - get() = definedExternally - val body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */ - get() = definedExternally -} - -external interface NamespaceDeclaration : ModuleDeclaration { - override val name: Identifier - override val body: dynamic /* ModuleBlock | NamespaceDeclaration */ - get() = definedExternally -} - -external interface JSDocNamespaceDeclaration : ModuleDeclaration { - override val name: Identifier - override val body: dynamic /* Identifier? | JSDocNamespaceDeclaration? */ - get() = definedExternally -} - -external interface ModuleBlock : Node, Statement { - override val parent: ModuleDeclaration - val statements: NodeArray -} - -external interface ImportEqualsDeclaration : DeclarationStatement, JSDocContainer { - override val parent: dynamic /* SourceFile | ModuleBlock */ - get() = definedExternally - override val name: Identifier - val isTypeOnly: Boolean - val moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */ - get() = definedExternally -} - -external interface ExternalModuleReference : Node { - override val parent: ImportEqualsDeclaration - val expression: Expression -} - -external interface ImportDeclaration : Statement { - override val parent: dynamic /* SourceFile | ModuleBlock */ - get() = definedExternally - val importClause: ImportClause? - get() = definedExternally - val moduleSpecifier: Expression -} - -external interface ImportClause : NamedDeclaration { - override val parent: ImportDeclaration - val isTypeOnly: Boolean - override val name: Identifier? - get() = definedExternally - val namedBindings: dynamic /* NamespaceImport? | NamedImports? */ - get() = definedExternally -} - -external interface NamespaceImport : NamedDeclaration { - override val parent: ImportClause - override val name: Identifier -} - -external interface NamespaceExport : NamedDeclaration { - override val parent: ExportDeclaration - override val name: Identifier -} - -external interface NamespaceExportDeclaration : DeclarationStatement, JSDocContainer { - override val name: Identifier -} - -external interface ExportDeclaration : DeclarationStatement, JSDocContainer { - override val parent: dynamic /* SourceFile | ModuleBlock */ - get() = definedExternally - val isTypeOnly: Boolean - val exportClause: dynamic /* NamespaceExport? | NamedExports? */ - get() = definedExternally - val moduleSpecifier: Expression? - get() = definedExternally -} - -external interface NamedImports : Node { - override val parent: ImportClause - val elements: NodeArray -} - -external interface NamedExports : Node { - override val parent: ExportDeclaration - val elements: NodeArray -} - -external interface ImportSpecifier : NamedDeclaration { - override val parent: NamedImports - val propertyName: Identifier? - get() = definedExternally - override val name: Identifier -} - -external interface ExportSpecifier : NamedDeclaration { - override val parent: NamedExports - val propertyName: Identifier? - get() = definedExternally - override val name: Identifier -} - -external interface ExportAssignment : DeclarationStatement, JSDocContainer { - override val parent: SourceFile - val isExportEquals: Boolean? - get() = definedExternally - val expression: Expression -} - -external interface FileReference : TextRange { - var fileName: String -} - -external interface CheckJsDirective : TextRange { - var enabled: Boolean -} - -external interface CommentRange : TextRange { - var hasTrailingNewLine: Boolean? - get() = definedExternally - set(value) = definedExternally - var kind: dynamic /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */ - get() = definedExternally - set(value) = definedExternally -} - -external interface SynthesizedComment : CommentRange { - var text: String - var hasLeadingNewline: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface JSDocTypeExpression : TypeNode { - val type: TypeNode -} - -external interface JSDocNameReference : Node { - val name: dynamic /* Identifier | QualifiedName | JSDocMemberName */ - get() = definedExternally -} - -external interface JSDocMemberName : Node { - val left: dynamic /* Identifier | QualifiedName | JSDocMemberName */ - get() = definedExternally - val right: Identifier -} - -external interface JSDocType : TypeNode { - var _jsDocTypeBrand: Any -} - -external interface JSDocAllType : JSDocType - -external interface JSDocUnknownType : JSDocType - -external interface JSDocNonNullableType : JSDocType { - val type: TypeNode -} - -external interface JSDocNullableType : JSDocType { - val type: TypeNode -} - -external interface JSDocOptionalType : JSDocType { - val type: TypeNode -} - -external interface JSDocFunctionType : JSDocType, SignatureDeclarationBase { - override val kind: Any -} - -external interface JSDocVariadicType : JSDocType { - val type: TypeNode -} - -external interface JSDocNamepathType : JSDocType { - val type: TypeNode -} - -external interface JSDoc : Node { - override val parent: dynamic /* ParameterDeclaration | CallSignatureDeclaration | ClassStaticBlockDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | EmptyStatement | DebuggerStatement | Block | VariableStatement | ExpressionStatement | IfStatement | DoStatement | WhileStatement | ForStatement | ForInStatement | ForOfStatement | BreakStatement | ContinueStatement | ReturnStatement | WithStatement | SwitchStatement | LabeledStatement | ThrowStatement | TryStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | VariableDeclaration | PropertyDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | NamespaceExportDeclaration | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | Token & JSDocContainer */ - get() = definedExternally - val tags: NodeArray? - get() = definedExternally - val comment: dynamic /* String? | NodeArray? */ - get() = definedExternally -} - -external interface JSDocTag : Node { - override val parent: dynamic /* JSDoc | JSDocTypeLiteral */ - get() = definedExternally - val tagName: Identifier - val comment: dynamic /* String? | NodeArray? */ - get() = definedExternally -} - -external interface JSDocLink : Node { - val name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ - get() = definedExternally - var text: String -} - -external interface JSDocLinkCode : Node { - val name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ - get() = definedExternally - var text: String -} - -external interface JSDocLinkPlain : Node { - val name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ - get() = definedExternally - var text: String -} - -external interface JSDocText : Node { - var text: String -} - -external interface JSDocUnknownTag : JSDocTag - -external interface `T$21` { - val expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ - get() = definedExternally -} - -external interface JSDocAugmentsTag : JSDocTag { - val `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */ -} - -external interface JSDocImplementsTag : JSDocTag { - val `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */ -} - -external interface JSDocAuthorTag : JSDocTag - -external interface JSDocDeprecatedTag : JSDocTag - -external interface JSDocClassTag : JSDocTag - -external interface JSDocPublicTag : JSDocTag - -external interface JSDocPrivateTag : JSDocTag - -external interface JSDocProtectedTag : JSDocTag - -external interface JSDocReadonlyTag : JSDocTag - -external interface JSDocOverrideTag : JSDocTag - -external interface JSDocEnumTag : JSDocTag, Declaration { - override val parent: JSDoc - val typeExpression: JSDocTypeExpression -} - -external interface JSDocThisTag : JSDocTag { - val typeExpression: JSDocTypeExpression -} - -external interface JSDocTemplateTag : JSDocTag { - val constraint: JSDocTypeExpression? - val typeParameters: NodeArray -} - -external interface JSDocSeeTag : JSDocTag { - val name: JSDocNameReference? - get() = definedExternally -} - -external interface JSDocReturnTag : JSDocTag { - val typeExpression: JSDocTypeExpression? - get() = definedExternally -} - -external interface JSDocTypeTag : JSDocTag { - val typeExpression: JSDocTypeExpression -} - -external interface JSDocTypedefTag : JSDocTag, NamedDeclaration { - override val parent: JSDoc - val fullName: dynamic /* JSDocNamespaceDeclaration? | Identifier? */ - get() = definedExternally - override val name: Identifier? - get() = definedExternally - val typeExpression: dynamic /* JSDocTypeExpression? | JSDocTypeLiteral? */ - get() = definedExternally -} - -external interface JSDocCallbackTag : JSDocTag, NamedDeclaration { - override val parent: JSDoc - val fullName: dynamic /* JSDocNamespaceDeclaration? | Identifier? */ - get() = definedExternally - override val name: Identifier? - get() = definedExternally - val typeExpression: JSDocSignature -} - -external interface JSDocSignature : JSDocType, Declaration { - val typeParameters: Array? - get() = definedExternally - val parameters: Array - val type: JSDocReturnTag? -} - -external interface JSDocPropertyLikeTag : JSDocTag, Declaration { - override val parent: JSDoc - val name: dynamic /* Identifier | QualifiedName */ - get() = definedExternally - val typeExpression: JSDocTypeExpression? - get() = definedExternally - val isNameFirst: Boolean - val isBracketed: Boolean -} - -external interface JSDocPropertyTag : JSDocPropertyLikeTag - -external interface JSDocParameterTag : JSDocPropertyLikeTag - -external interface JSDocTypeLiteral : JSDocType { - val jsDocPropertyTags: Array? - get() = definedExternally - val isArrayType: Boolean -} - -external enum class FlowFlags { - Unreachable /* = 1 */, - Start /* = 2 */, - BranchLabel /* = 4 */, - LoopLabel /* = 8 */, - Assignment /* = 16 */, - TrueCondition /* = 32 */, - FalseCondition /* = 64 */, - SwitchClause /* = 128 */, - ArrayMutation /* = 256 */, - Call /* = 512 */, - ReduceLabel /* = 1024 */, - Referenced /* = 2048 */, - Shared /* = 4096 */, - Label /* = 12 */, - Condition /* = 96 */ -} - -external interface FlowNodeBase { - var flags: FlowFlags - var id: Number? - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowStart : FlowNodeBase { - var node: dynamic /* FunctionExpression? | ArrowFunction? | MethodDeclaration? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowLabel : FlowNodeBase { - var antecedents: Array? -} - -external interface FlowAssignment : FlowNodeBase { - var node: dynamic /* Expression | VariableDeclaration | BindingElement */ - get() = definedExternally - set(value) = definedExternally - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowCall : FlowNodeBase { - var node: CallExpression - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowCondition : FlowNodeBase { - var node: Expression - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowSwitchClause : FlowNodeBase { - var switchStatement: SwitchStatement - var clauseStart: Number - var clauseEnd: Number - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowArrayMutation : FlowNodeBase { - var node: dynamic /* CallExpression | BinaryExpression */ - get() = definedExternally - set(value) = definedExternally - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowReduceLabel : FlowNodeBase { - var target: FlowLabel - var antecedents: Array - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface IncompleteType { - var flags: TypeFlags - var type: Type -} - -external interface AmdDependency { - var path: String - var name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface SourceFile : Declaration { - fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter - fun getLineEndOfPosition(pos: Number): Number - fun getLineStarts(): Array - fun getPositionOfLineAndCharacter(line: Number, character: Number): Number - fun update(newText: String, textChangeRange: TextChangeRange): SourceFile - val statements: NodeArray - val endOfFileToken: Token - var fileName: String - var text: String - var amdDependencies: Array - var moduleName: String? - get() = definedExternally - set(value) = definedExternally - var referencedFiles: Array - var typeReferenceDirectives: Array - var libReferenceDirectives: Array - var languageVariant: LanguageVariant - var isDeclarationFile: Boolean - var hasNoDefaultLib: Boolean - var languageVersion: ScriptTarget -} - -external interface Bundle : Node { - val prepends: Array - val sourceFiles: Array -} - -external interface InputFiles : Node { - var javascriptPath: String? - get() = definedExternally - set(value) = definedExternally - var javascriptText: String - var javascriptMapPath: String? - get() = definedExternally - set(value) = definedExternally - var javascriptMapText: String? - get() = definedExternally - set(value) = definedExternally - var declarationPath: String? - get() = definedExternally - set(value) = definedExternally - var declarationText: String - var declarationMapPath: String? - get() = definedExternally - set(value) = definedExternally - var declarationMapText: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface UnparsedSource : Node { - var fileName: String - var text: String - val prologues: Array - var helpers: Array? - var referencedFiles: Array - var typeReferenceDirectives: Array? - var libReferenceDirectives: Array - var hasNoDefaultLib: Boolean? - get() = definedExternally - set(value) = definedExternally - var sourceMapPath: String? - get() = definedExternally - set(value) = definedExternally - var sourceMapText: String? - get() = definedExternally - set(value) = definedExternally - val syntheticReferences: Array? - get() = definedExternally - val texts: Array -} - -external interface UnparsedSection : Node { - override val kind: SyntaxKind - override val parent: UnparsedSource - val data: String? - get() = definedExternally -} - -external interface UnparsedPrologue : UnparsedSection { - override val parent: UnparsedSource -} - -external interface UnparsedPrepend : UnparsedSection { - override val parent: UnparsedSource - val texts: Array -} - -external interface UnparsedTextLike : UnparsedSection { - override val kind: dynamic /* SyntaxKind.UnparsedText | SyntaxKind.UnparsedInternalText */ - get() = definedExternally - override val parent: UnparsedSource -} - -external interface UnparsedSyntheticReference : UnparsedSection { - override val parent: UnparsedSource -} - -external interface JsonSourceFile : SourceFile { - override val statements: NodeArray -} - -external interface TsConfigSourceFile : JsonSourceFile { - var extendedSourceFiles: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface JsonMinusNumericLiteral : PrefixUnaryExpression { - override val kind: Any - override val operator: Any - override val operand: NumericLiteral -} - -external interface JsonObjectExpressionStatement : ExpressionStatement { - override val expression: dynamic /* ObjectLiteralExpression | ArrayLiteralExpression | JsonMinusNumericLiteral | NumericLiteral | StringLiteral | TrueLiteral | FalseLiteral | NullLiteral */ - get() = definedExternally -} - -external interface ScriptReferenceHost { - fun getCompilerOptions(): CompilerOptions - fun getSourceFile(fileName: String): SourceFile? - fun getSourceFileByPath(path: String /* String & `T$3` */): SourceFile? - fun getCurrentDirectory(): String -} - -external interface ParseConfigHost { - var useCaseSensitiveFileNames: Boolean - fun readDirectory(rootDir: String, extensions: Array, excludes: Array?, includes: Array, depth: Number = definedExternally): Array - fun fileExists(path: String): Boolean - fun readFile(path: String): String? - val trace: ((s: String) -> Unit)? -} - -external open class OperationCanceledException - -external interface CancellationToken { - fun isCancellationRequested(): Boolean - fun throwIfCancellationRequested() -} - -external interface Program : ScriptReferenceHost { - override fun getCurrentDirectory(): String - fun getRootFileNames(): Array - fun getSourceFiles(): Array - fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult - fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getDeclarationDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getConfigFileParsingDiagnostics(): Array - fun getTypeChecker(): TypeChecker - fun getNodeCount(): Number - fun getIdentifierCount(): Number - fun getSymbolCount(): Number - fun getTypeCount(): Number - fun getInstantiationCount(): Number - fun getRelationCacheSizes(): `T$6` - fun isSourceFileFromExternalLibrary(file: SourceFile): Boolean - fun isSourceFileDefaultLibrary(file: SourceFile): Boolean - fun getProjectReferences(): Array? - fun getResolvedProjectReferences(): Array? -} - -external interface ResolvedProjectReference { - var commandLine: ParsedCommandLine - var sourceFile: SourceFile - var references: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface CustomTransformer { - fun transformSourceFile(node: SourceFile): SourceFile - fun transformBundle(node: Bundle): Bundle -} - -external interface CustomTransformers { - var before: Array | CustomTransformerFactory */>? - get() = definedExternally - set(value) = definedExternally - var after: Array | CustomTransformerFactory */>? - get() = definedExternally - set(value) = definedExternally - var afterDeclarations: Array | CustomTransformerFactory */>? - get() = definedExternally - set(value) = definedExternally -} - -external interface SourceMapSpan { - var emittedLine: Number - var emittedColumn: Number - var sourceLine: Number - var sourceColumn: Number - var nameIndex: Number? - get() = definedExternally - set(value) = definedExternally - var sourceIndex: Number -} - -external enum class ExitStatus { - Success /* = 0 */, - DiagnosticsPresent_OutputsSkipped /* = 1 */, - DiagnosticsPresent_OutputsGenerated /* = 2 */, - InvalidProject_OutputsSkipped /* = 3 */, - ProjectReferenceCycle_OutputsSkipped /* = 4 */, - ProjectReferenceCycle_OutputsSkupped /* = 4 */ -} - -external interface EmitResult { - var emitSkipped: Boolean - var diagnostics: Array - var emittedFiles: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$22` { - var typeArguments: NodeArray? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeChecker { - fun getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type - fun getDeclaredTypeOfSymbol(symbol: Symbol): Type - fun getPropertiesOfType(type: Type): Array - fun getPropertyOfType(type: Type, propertyName: String): Symbol? - fun getPrivateIdentifierPropertyOfType(leftType: Type, name: String, location: Node): Symbol? - fun getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo? - fun getIndexInfosOfType(type: Type): Array - fun getSignaturesOfType(type: Type, kind: SignatureKind): Array - fun getIndexTypeOfType(type: Type, kind: IndexKind): Type? - fun getBaseTypes(type: InterfaceType): Array - fun getBaseTypeOfLiteralType(type: Type): Type - fun getWidenedType(type: Type): Type - fun getReturnTypeOfSignature(signature: Signature): Type - fun getNullableType(type: Type, flags: TypeFlags): Type - fun getNonNullableType(type: Type): Type - fun getTypeArguments(type: TypeReference): Array - fun typeToTypeNode(type: Type, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeNode? - fun signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ - fun indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): IndexSignatureDeclaration? - fun symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* Identifier? | QualifiedName? */ - fun symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): Expression? - fun symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): NodeArray? - fun symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): ParameterDeclaration? - fun typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeParameterDeclaration? - fun getSymbolsInScope(location: Node, meaning: SymbolFlags): Array - fun getSymbolAtLocation(node: Node): Symbol? - fun getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: String): Array - fun getShorthandAssignmentValueSymbol(location: Node?): Symbol? - fun getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol? - fun getExportSpecifierLocalTargetSymbol(location: Identifier): Symbol? - fun getExportSymbolOfSymbol(symbol: Symbol): Symbol - fun getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol? - fun getTypeOfAssignmentPattern(pattern: ObjectLiteralExpression): Type - fun getTypeOfAssignmentPattern(pattern: ArrayLiteralExpression): Type - fun getTypeAtLocation(node: Node): Type - fun getTypeFromTypeNode(node: TypeNode): Type - fun signatureToString(signature: Signature, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally, kind: SignatureKind = definedExternally): String - fun typeToString(type: Type, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun symbolToString(symbol: Symbol, enclosingDeclaration: Node = definedExternally, meaning: SymbolFlags = definedExternally, flags: SymbolFormatFlags = definedExternally): String - fun typePredicateToString(predicate: ThisTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun typePredicateToString(predicate: ThisTypePredicate): String - fun typePredicateToString(predicate: ThisTypePredicate, enclosingDeclaration: Node = definedExternally): String - fun typePredicateToString(predicate: IdentifierTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun typePredicateToString(predicate: IdentifierTypePredicate): String - fun typePredicateToString(predicate: IdentifierTypePredicate, enclosingDeclaration: Node = definedExternally): String - fun typePredicateToString(predicate: AssertsThisTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun typePredicateToString(predicate: AssertsThisTypePredicate): String - fun typePredicateToString(predicate: AssertsThisTypePredicate, enclosingDeclaration: Node = definedExternally): String - fun typePredicateToString(predicate: AssertsIdentifierTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun typePredicateToString(predicate: AssertsIdentifierTypePredicate): String - fun typePredicateToString(predicate: AssertsIdentifierTypePredicate, enclosingDeclaration: Node = definedExternally): String - fun getFullyQualifiedName(symbol: Symbol): String - fun getAugmentedPropertiesOfType(type: Type): Array - fun getRootSymbols(symbol: Symbol): Array - fun getSymbolOfExpando(node: Node, allowDeclaration: Boolean): Symbol? - fun getContextualType(node: Expression): Type? - fun getResolvedSignature(node: CallExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: CallExpression): Signature? - fun getResolvedSignature(node: CallExpression, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: NewExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: NewExpression): Signature? - fun getResolvedSignature(node: NewExpression, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: TaggedTemplateExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: TaggedTemplateExpression): Signature? - fun getResolvedSignature(node: TaggedTemplateExpression, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: Decorator, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: Decorator): Signature? - fun getResolvedSignature(node: Decorator, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: JsxSelfClosingElement, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: JsxSelfClosingElement): Signature? - fun getResolvedSignature(node: JsxSelfClosingElement, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: JsxOpeningElement, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: JsxOpeningElement): Signature? - fun getResolvedSignature(node: JsxOpeningElement, candidatesOutArray: Array = definedExternally): Signature? - fun getSignatureFromDeclaration(declaration: CallSignatureDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: ConstructSignatureDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: MethodSignature): Signature? - fun getSignatureFromDeclaration(declaration: IndexSignatureDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: FunctionTypeNode): Signature? - fun getSignatureFromDeclaration(declaration: ConstructorTypeNode): Signature? - fun getSignatureFromDeclaration(declaration: JSDocFunctionType): Signature? - fun getSignatureFromDeclaration(declaration: FunctionDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: MethodDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: ConstructorDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: GetAccessorDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: SetAccessorDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: FunctionExpression): Signature? - fun getSignatureFromDeclaration(declaration: ArrowFunction): Signature? - fun isImplementationOfOverload(node: CallSignatureDeclaration): Boolean? - fun isImplementationOfOverload(node: ConstructSignatureDeclaration): Boolean? - fun isImplementationOfOverload(node: MethodSignature): Boolean? - fun isImplementationOfOverload(node: IndexSignatureDeclaration): Boolean? - fun isImplementationOfOverload(node: FunctionTypeNode): Boolean? - fun isImplementationOfOverload(node: ConstructorTypeNode): Boolean? - fun isImplementationOfOverload(node: JSDocFunctionType): Boolean? - fun isImplementationOfOverload(node: FunctionDeclaration): Boolean? - fun isImplementationOfOverload(node: MethodDeclaration): Boolean? - fun isImplementationOfOverload(node: ConstructorDeclaration): Boolean? - fun isImplementationOfOverload(node: GetAccessorDeclaration): Boolean? - fun isImplementationOfOverload(node: SetAccessorDeclaration): Boolean? - fun isImplementationOfOverload(node: FunctionExpression): Boolean? - fun isImplementationOfOverload(node: ArrowFunction): Boolean? - fun isUndefinedSymbol(symbol: Symbol): Boolean - fun isArgumentsSymbol(symbol: Symbol): Boolean - fun isUnknownSymbol(symbol: Symbol): Boolean - fun getConstantValue(node: EnumMember): dynamic /* String? | Number? */ - fun getConstantValue(node: PropertyAccessExpression): dynamic /* String? | Number? */ - fun getConstantValue(node: ElementAccessExpression): dynamic /* String? | Number? */ - fun isValidPropertyAccess(node: PropertyAccessExpression, propertyName: String): Boolean - fun isValidPropertyAccess(node: QualifiedName, propertyName: String): Boolean - fun isValidPropertyAccess(node: ImportTypeNode, propertyName: String): Boolean - fun getAliasedSymbol(symbol: Symbol): Symbol - fun getImmediateAliasedSymbol(symbol: Symbol): Symbol? - fun getExportsOfModule(moduleSymbol: Symbol): Array - fun getJsxIntrinsicTagNamesAt(location: Node): Array - fun isOptionalParameter(node: ParameterDeclaration): Boolean - fun getAmbientModules(): Array - fun tryGetMemberInModuleExports(memberName: String, moduleSymbol: Symbol): Symbol? - fun getApparentType(type: Type): Type - fun getBaseConstraintOfType(type: Type): Type? - fun getDefaultFromTypeParameter(type: Type): Type? - fun runWithCancellationToken(token: CancellationToken, cb: (checker: TypeChecker) -> T): T -} - -external enum class NodeBuilderFlags { - None /* = 0 */, - NoTruncation /* = 1 */, - WriteArrayAsGenericType /* = 2 */, - GenerateNamesForShadowedTypeParams /* = 4 */, - UseStructuralFallback /* = 8 */, - ForbidIndexedAccessSymbolReferences /* = 16 */, - WriteTypeArgumentsOfSignature /* = 32 */, - UseFullyQualifiedType /* = 64 */, - UseOnlyExternalAliasing /* = 128 */, - SuppressAnyReturnType /* = 256 */, - WriteTypeParametersInQualifiedName /* = 512 */, - MultilineObjectLiterals /* = 1024 */, - WriteClassExpressionAsTypeLiteral /* = 2048 */, - UseTypeOfFunction /* = 4096 */, - OmitParameterModifiers /* = 8192 */, - UseAliasDefinedOutsideCurrentScope /* = 16384 */, - UseSingleQuotesForStringLiteralType /* = 268435456 */, - NoTypeReduction /* = 536870912 */, - NoUndefinedOptionalParameterType /* = 1073741824 */, - AllowThisInObjectLiteral /* = 32768 */, - AllowQualifiedNameInPlaceOfIdentifier /* = 65536 */, - AllowQualifedNameInPlaceOfIdentifier /* = 65536 */, - AllowAnonymousIdentifier /* = 131072 */, - AllowEmptyUnionOrIntersection /* = 262144 */, - AllowEmptyTuple /* = 524288 */, - AllowUniqueESSymbolType /* = 1048576 */, - AllowEmptyIndexInfoType /* = 2097152 */, - AllowNodeModulesRelativePaths /* = 67108864 */, - IgnoreErrors /* = 70221824 */, - InObjectTypeLiteral /* = 4194304 */, - InTypeAlias /* = 8388608 */, - InInitialEntityName /* = 16777216 */ -} - -external enum class TypeFormatFlags { - None /* = 0 */, - NoTruncation /* = 1 */, - WriteArrayAsGenericType /* = 2 */, - UseStructuralFallback /* = 8 */, - WriteTypeArgumentsOfSignature /* = 32 */, - UseFullyQualifiedType /* = 64 */, - SuppressAnyReturnType /* = 256 */, - MultilineObjectLiterals /* = 1024 */, - WriteClassExpressionAsTypeLiteral /* = 2048 */, - UseTypeOfFunction /* = 4096 */, - OmitParameterModifiers /* = 8192 */, - UseAliasDefinedOutsideCurrentScope /* = 16384 */, - UseSingleQuotesForStringLiteralType /* = 268435456 */, - NoTypeReduction /* = 536870912 */, - AllowUniqueESSymbolType /* = 1048576 */, - AddUndefined /* = 131072 */, - WriteArrowStyleSignature /* = 262144 */, - InArrayType /* = 524288 */, - InElementType /* = 2097152 */, - InFirstTypeArgument /* = 4194304 */, - InTypeAlias /* = 8388608 */, - WriteOwnNameForAnyLike /* = 0 */, - NodeBuilderFlagsMask /* = 814775659 */ -} - -external enum class SymbolFormatFlags { - None /* = 0 */, - WriteTypeParametersOrArguments /* = 1 */, - UseOnlyExternalAliasing /* = 2 */, - AllowAnyNodeKind /* = 4 */, - UseAliasDefinedOutsideCurrentScope /* = 8 */ -} - -external enum class TypePredicateKind { - This /* = 0 */, - Identifier /* = 1 */, - AssertsThis /* = 2 */, - AssertsIdentifier /* = 3 */ -} - -external interface TypePredicateBase { - var kind: TypePredicateKind - var type: Type? -} - -external interface ThisTypePredicate : TypePredicateBase { - var parameterName: Any? - var parameterIndex: Any? -} - -external interface IdentifierTypePredicate : TypePredicateBase { - var parameterName: String - var parameterIndex: Number -} - -external interface AssertsThisTypePredicate : TypePredicateBase { - var parameterName: Any? - var parameterIndex: Any? - override var type: Type? -} - -external interface AssertsIdentifierTypePredicate : TypePredicateBase { - var parameterName: String - var parameterIndex: Number - override var type: Type? -} - -external enum class SymbolFlags { - None /* = 0 */, - FunctionScopedVariable /* = 1 */, - BlockScopedVariable /* = 2 */, - Property /* = 4 */, - EnumMember /* = 8 */, - Function /* = 16 */, - Class /* = 32 */, - Interface /* = 64 */, - ConstEnum /* = 128 */, - RegularEnum /* = 256 */, - ValueModule /* = 512 */, - NamespaceModule /* = 1024 */, - TypeLiteral /* = 2048 */, - ObjectLiteral /* = 4096 */, - Method /* = 8192 */, - Constructor /* = 16384 */, - GetAccessor /* = 32768 */, - SetAccessor /* = 65536 */, - Signature /* = 131072 */, - TypeParameter /* = 262144 */, - TypeAlias /* = 524288 */, - ExportValue /* = 1048576 */, - Alias /* = 2097152 */, - Prototype /* = 4194304 */, - ExportStar /* = 8388608 */, - Optional /* = 16777216 */, - Transient /* = 33554432 */, - Assignment /* = 67108864 */, - ModuleExports /* = 134217728 */, - Enum /* = 384 */, - Variable /* = 3 */, - Value /* = 111551 */, - Type /* = 788968 */, - Namespace /* = 1920 */, - Module /* = 1536 */, - Accessor /* = 98304 */, - FunctionScopedVariableExcludes /* = 111550 */, - BlockScopedVariableExcludes /* = 111551 */, - ParameterExcludes /* = 111551 */, - PropertyExcludes /* = 0 */, - EnumMemberExcludes /* = 900095 */, - FunctionExcludes /* = 110991 */, - ClassExcludes /* = 899503 */, - InterfaceExcludes /* = 788872 */, - RegularEnumExcludes /* = 899327 */, - ConstEnumExcludes /* = 899967 */, - ValueModuleExcludes /* = 110735 */, - NamespaceModuleExcludes /* = 0 */, - MethodExcludes /* = 103359 */, - GetAccessorExcludes /* = 46015 */, - SetAccessorExcludes /* = 78783 */, - TypeParameterExcludes /* = 526824 */, - TypeAliasExcludes /* = 788968 */, - AliasExcludes /* = 2097152 */, - ModuleMember /* = 2623475 */, - ExportHasLocal /* = 944 */, - BlockScoped /* = 418 */, - PropertyOrAccessor /* = 98308 */, - ClassMember /* = 106500 */ -} - -external interface Symbol { - val name: String - fun getFlags(): SymbolFlags - fun getEscapedName(): dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - fun getName(): String - fun getDeclarations(): Array? - fun getDocumentationComment(typeChecker: TypeChecker?): Array - fun getJsDocTags(checker: TypeChecker = definedExternally): Array - var flags: SymbolFlags - var escapedName: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - get() = definedExternally - set(value) = definedExternally - var declarations: Array? - get() = definedExternally - set(value) = definedExternally - var valueDeclaration: Declaration? - get() = definedExternally - set(value) = definedExternally - var members: SymbolTable? - get() = definedExternally - set(value) = definedExternally - var exports: SymbolTable? - get() = definedExternally - set(value) = definedExternally - var globalExports: SymbolTable? - get() = definedExternally - set(value) = definedExternally -} - -external enum class InternalSymbolName { - Call /* = "__call" */, - Constructor /* = "__constructor" */, - New /* = "__new" */, - Index /* = "__index" */, - ExportStar /* = "__export" */, - Global /* = "__global" */, - Missing /* = "__missing" */, - Type /* = "__type" */, - Object /* = "__object" */, - JSXAttributes /* = "__jsxAttributes" */, - Class /* = "__class" */, - Function /* = "__function" */, - Computed /* = "__computed" */, - Resolving /* = "__resolving__" */, - ExportEquals /* = "export=" */, - Default /* = "default" */, - This /* = "this" */ -} - -external interface ReadonlyUnderscoreEscapedMap : ReadonlyESMap - -external interface UnderscoreEscapedMap : ESMap, ReadonlyUnderscoreEscapedMap - -external enum class TypeFlags { - Any /* = 1 */, - Unknown /* = 2 */, - String /* = 4 */, - Number /* = 8 */, - Boolean /* = 16 */, - Enum /* = 32 */, - BigInt /* = 64 */, - StringLiteral /* = 128 */, - NumberLiteral /* = 256 */, - BooleanLiteral /* = 512 */, - EnumLiteral /* = 1024 */, - BigIntLiteral /* = 2048 */, - ESSymbol /* = 4096 */, - UniqueESSymbol /* = 8192 */, - Void /* = 16384 */, - Undefined /* = 32768 */, - Null /* = 65536 */, - Never /* = 131072 */, - TypeParameter /* = 262144 */, - Object /* = 524288 */, - Union /* = 1048576 */, - Intersection /* = 2097152 */, - Index /* = 4194304 */, - IndexedAccess /* = 8388608 */, - Conditional /* = 16777216 */, - Substitution /* = 33554432 */, - NonPrimitive /* = 67108864 */, - TemplateLiteral /* = 134217728 */, - StringMapping /* = 268435456 */, - Literal /* = 2944 */, - Unit /* = 109440 */, - StringOrNumberLiteral /* = 384 */, - PossiblyFalsy /* = 117724 */, - StringLike /* = 402653316 */, - NumberLike /* = 296 */, - BigIntLike /* = 2112 */, - BooleanLike /* = 528 */, - EnumLike /* = 1056 */, - ESSymbolLike /* = 12288 */, - VoidLike /* = 49152 */, - UnionOrIntersection /* = 3145728 */, - StructuredType /* = 3670016 */, - TypeVariable /* = 8650752 */, - InstantiableNonPrimitive /* = 58982400 */, - InstantiablePrimitive /* = 406847488 */, - Instantiable /* = 465829888 */, - StructuredOrInstantiable /* = 469499904 */, - Narrowable /* = 536624127 */ -} - -external interface Type { - fun getFlags(): TypeFlags - fun getSymbol(): Symbol? - fun getProperties(): Array - fun getProperty(propertyName: String): Symbol? - fun getApparentProperties(): Array - fun getCallSignatures(): Array - fun getConstructSignatures(): Array - fun getStringIndexType(): Type? - fun getNumberIndexType(): Type? - fun getBaseTypes(): Array? - fun getNonNullableType(): Type - fun getConstraint(): Type? - fun getDefault(): Type? - fun isUnion(): Boolean - fun isIntersection(): Boolean - fun isUnionOrIntersection(): Boolean - fun isLiteral(): Boolean - fun isStringLiteral(): Boolean - fun isNumberLiteral(): Boolean - fun isTypeParameter(): Boolean - fun isClassOrInterface(): Boolean - fun isClass(): Boolean - var flags: TypeFlags - var symbol: Symbol - var pattern: dynamic /* ObjectBindingPattern? | ArrayBindingPattern? | ObjectLiteralExpression? | ArrayLiteralExpression? */ - get() = definedExternally - set(value) = definedExternally - var aliasSymbol: Symbol? - get() = definedExternally - set(value) = definedExternally - var aliasTypeArguments: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface LiteralType : Type { - var value: dynamic /* String | Number | PseudoBigInt */ - get() = definedExternally - set(value) = definedExternally - var freshType: LiteralType - var regularType: LiteralType -} - -external interface UniqueESSymbolType : Type { - override var symbol: Symbol - var escapedName: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - get() = definedExternally - set(value) = definedExternally -} - -external interface StringLiteralType : LiteralType { - override var value: String -} - -external interface NumberLiteralType : LiteralType { - override var value: Number -} - -external interface BigIntLiteralType : LiteralType { - override var value: PseudoBigInt -} - -external interface EnumType : Type - -external enum class ObjectFlags { - Class /* = 1 */, - Interface /* = 2 */, - Reference /* = 4 */, - Tuple /* = 8 */, - Anonymous /* = 16 */, - Mapped /* = 32 */, - Instantiated /* = 64 */, - ObjectLiteral /* = 128 */, - EvolvingArray /* = 256 */, - ObjectLiteralPatternWithComputedProperties /* = 512 */, - ReverseMapped /* = 1024 */, - JsxAttributes /* = 2048 */, - MarkerType /* = 4096 */, - JSLiteral /* = 8192 */, - FreshLiteral /* = 16384 */, - ArrayLiteral /* = 32768 */, - ClassOrInterface /* = 3 */, - ContainsSpread /* = 4194304 */, - ObjectRestType /* = 8388608 */ -} - -external interface ObjectType : Type { - var objectFlags: ObjectFlags -} - -external interface InterfaceType : ObjectType { - var typeParameters: Array? - var outerTypeParameters: Array? - var localTypeParameters: Array? - var thisType: TypeParameter? -} - -external interface InterfaceTypeWithDeclaredMembers : InterfaceType { - var declaredProperties: Array - var declaredCallSignatures: Array - var declaredConstructSignatures: Array - var declaredIndexInfos: Array -} - -external interface TypeReference : ObjectType { - var typeArguments: Array? - get() = definedExternally - set(value) = definedExternally - var target: GenericType - var node: dynamic /* TypeReferenceNode? | ArrayTypeNode? | TupleTypeNode? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface DeferredTypeReference : TypeReference - -external interface GenericType : InterfaceType, TypeReference - -external enum class ElementFlags { - Required /* = 1 */, - Optional /* = 2 */, - Rest /* = 4 */, - Variadic /* = 8 */, - Fixed /* = 3 */, - Variable /* = 12 */, - NonRequired /* = 14 */, - NonRest /* = 11 */ -} - -external interface TupleType : GenericType { - var elementFlags: Array - var minLength: Number - var fixedLength: Number - var hasRestElement: Boolean - var combinedFlags: ElementFlags - var readonly: Boolean - var labeledElementDeclarations: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface TupleTypeReference : TypeReference { - override var target: TupleType -} - -external interface UnionOrIntersectionType : Type { - var types: Array -} - -external interface UnionType : UnionOrIntersectionType - -external interface IntersectionType : UnionOrIntersectionType - -external interface EvolvingArrayType : ObjectType { - var elementType: Type - var finalArrayType: Type? - get() = definedExternally - set(value) = definedExternally -} - -external interface InstantiableType : Type - -external interface TypeParameter : InstantiableType - -external interface IndexedAccessType : InstantiableType { - var objectType: Type - var indexType: Type - var constraint: Type? - get() = definedExternally - set(value) = definedExternally - var simplifiedForReading: Type? - get() = definedExternally - set(value) = definedExternally - var simplifiedForWriting: Type? - get() = definedExternally - set(value) = definedExternally -} - -external interface IndexType : InstantiableType { - var type: dynamic /* InstantiableType | UnionOrIntersectionType */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ConditionalRoot { - var node: ConditionalTypeNode - var checkType: Type - var extendsType: Type - var isDistributive: Boolean - var inferTypeParameters: Array? - get() = definedExternally - set(value) = definedExternally - var outerTypeParameters: Array? - get() = definedExternally - set(value) = definedExternally - var instantiations: Map? - get() = definedExternally - set(value) = definedExternally - var aliasSymbol: Symbol? - get() = definedExternally - set(value) = definedExternally - var aliasTypeArguments: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface ConditionalType : InstantiableType { - var root: ConditionalRoot - var checkType: Type - var extendsType: Type - var resolvedTrueType: Type - var resolvedFalseType: Type -} - -external interface TemplateLiteralType : InstantiableType { - var texts: Array - var types: Array -} - -external interface StringMappingType : InstantiableType { - override var symbol: Symbol - var type: Type -} - -external interface SubstitutionType : InstantiableType { - var objectFlags: ObjectFlags - var baseType: Type - var substitute: Type -} - -external enum class SignatureKind { - Call /* = 0 */, - Construct /* = 1 */ -} - -external interface Signature { - fun getDeclaration(): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ - fun getTypeParameters(): Array? - fun getParameters(): Array - fun getReturnType(): Type - fun getDocumentationComment(typeChecker: TypeChecker?): Array - fun getJsDocTags(): Array - var declaration: dynamic /* CallSignatureDeclaration? | ConstructSignatureDeclaration? | MethodSignature? | IndexSignatureDeclaration? | FunctionTypeNode? | ConstructorTypeNode? | JSDocFunctionType? | FunctionDeclaration? | MethodDeclaration? | ConstructorDeclaration? | GetAccessorDeclaration? | SetAccessorDeclaration? | FunctionExpression? | ArrowFunction? | JSDocSignature? */ - get() = definedExternally - set(value) = definedExternally - var typeParameters: Array? - get() = definedExternally - set(value) = definedExternally - var parameters: Array -} - -external enum class IndexKind { - String /* = 0 */, - Number /* = 1 */ -} - -external interface IndexInfo { - var keyType: Type - var type: Type - var isReadonly: Boolean - var declaration: IndexSignatureDeclaration? - get() = definedExternally - set(value) = definedExternally -} - -external enum class InferencePriority { - NakedTypeVariable /* = 1 */, - SpeculativeTuple /* = 2 */, - SubstituteSource /* = 4 */, - HomomorphicMappedType /* = 8 */, - PartialHomomorphicMappedType /* = 16 */, - MappedTypeConstraint /* = 32 */, - ContravariantConditional /* = 64 */, - ReturnType /* = 128 */, - LiteralKeyof /* = 256 */, - NoConstraints /* = 512 */, - AlwaysStrict /* = 1024 */, - MaxValue /* = 2048 */, - PriorityImpliesCombination /* = 416 */, - Circularity /* = -1 */ -} - -external interface FileExtensionInfo { - var extension: String - var isMixedContent: Boolean - var scriptKind: ScriptKind? - get() = definedExternally - set(value) = definedExternally -} - -external interface DiagnosticMessage { - var key: String - var category: DiagnosticCategory - var code: Number - var message: String - var reportsUnnecessary: Any? - get() = definedExternally - set(value) = definedExternally - var reportsDeprecated: Any? - get() = definedExternally - set(value) = definedExternally -} - -external interface DiagnosticMessageChain { - var messageText: String - var category: DiagnosticCategory - var code: Number - var next: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface Diagnostic : DiagnosticRelatedInformation { - var reportsUnnecessary: Any? - get() = definedExternally - set(value) = definedExternally - var reportsDeprecated: Any? - get() = definedExternally - set(value) = definedExternally - var source: String? - get() = definedExternally - set(value) = definedExternally - var relatedInformation: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface DiagnosticRelatedInformation { - var category: DiagnosticCategory - var code: Number - var file: SourceFile? - var start: Number? - var length: Number? - var messageText: dynamic /* String | DiagnosticMessageChain */ - get() = definedExternally - set(value) = definedExternally -} - -external interface DiagnosticWithLocation : Diagnostic - -external enum class DiagnosticCategory { - Warning /* = 0 */, - Error /* = 1 */, - Suggestion /* = 2 */, - Message /* = 3 */ -} - -external enum class ModuleResolutionKind { - Classic /* = 1 */, - NodeJs /* = 2 */ -} - -external interface PluginImport { - var name: String -} - -external interface ProjectReference { - var path: String - var originalPath: String? - get() = definedExternally - set(value) = definedExternally - var prepend: Boolean? - get() = definedExternally - set(value) = definedExternally - var circular: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external enum class WatchFileKind { - FixedPollingInterval /* = 0 */, - PriorityPollingInterval /* = 1 */, - DynamicPriorityPolling /* = 2 */, - FixedChunkSizePolling /* = 3 */, - UseFsEvents /* = 4 */, - UseFsEventsOnParentDirectory /* = 5 */ -} - -external enum class WatchDirectoryKind { - UseFsEvents /* = 0 */, - FixedPollingInterval /* = 1 */, - DynamicPriorityPolling /* = 2 */, - FixedChunkSizePolling /* = 3 */ -} - -external enum class PollingWatchKind { - FixedInterval /* = 0 */, - PriorityInterval /* = 1 */, - DynamicPriority /* = 2 */, - FixedChunkSize /* = 3 */ -} - -external interface CompilerOptions { - var allowJs: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowSyntheticDefaultImports: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowUmdGlobalAccess: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowUnreachableCode: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowUnusedLabels: Boolean? - get() = definedExternally - set(value) = definedExternally - var alwaysStrict: Boolean? - get() = definedExternally - set(value) = definedExternally - var baseUrl: String? - get() = definedExternally - set(value) = definedExternally - var charset: String? - get() = definedExternally - set(value) = definedExternally - var checkJs: Boolean? - get() = definedExternally - set(value) = definedExternally - var declaration: Boolean? - get() = definedExternally - set(value) = definedExternally - var declarationMap: Boolean? - get() = definedExternally - set(value) = definedExternally - var emitDeclarationOnly: Boolean? - get() = definedExternally - set(value) = definedExternally - var declarationDir: String? - get() = definedExternally - set(value) = definedExternally - var disableSizeLimit: Boolean? - get() = definedExternally - set(value) = definedExternally - var disableSourceOfProjectReferenceRedirect: Boolean? - get() = definedExternally - set(value) = definedExternally - var disableSolutionSearching: Boolean? - get() = definedExternally - set(value) = definedExternally - var disableReferencedProjectLoad: Boolean? - get() = definedExternally - set(value) = definedExternally - var downlevelIteration: Boolean? - get() = definedExternally - set(value) = definedExternally - var emitBOM: Boolean? - get() = definedExternally - set(value) = definedExternally - var emitDecoratorMetadata: Boolean? - get() = definedExternally - set(value) = definedExternally - var exactOptionalPropertyTypes: Boolean? - get() = definedExternally - set(value) = definedExternally - var experimentalDecorators: Boolean? - get() = definedExternally - set(value) = definedExternally - var forceConsistentCasingInFileNames: Boolean? - get() = definedExternally - set(value) = definedExternally - var importHelpers: Boolean? - get() = definedExternally - set(value) = definedExternally - var importsNotUsedAsValues: ImportsNotUsedAsValues? - get() = definedExternally - set(value) = definedExternally - var inlineSourceMap: Boolean? - get() = definedExternally - set(value) = definedExternally - var inlineSources: Boolean? - get() = definedExternally - set(value) = definedExternally - var isolatedModules: Boolean? - get() = definedExternally - set(value) = definedExternally - var jsx: JsxEmit? - get() = definedExternally - set(value) = definedExternally - var keyofStringsOnly: Boolean? - get() = definedExternally - set(value) = definedExternally - var lib: Array? - get() = definedExternally - set(value) = definedExternally - var locale: String? - get() = definedExternally - set(value) = definedExternally - var mapRoot: String? - get() = definedExternally - set(value) = definedExternally - var maxNodeModuleJsDepth: Number? - get() = definedExternally - set(value) = definedExternally - var module: ModuleKind? - get() = definedExternally - set(value) = definedExternally - var moduleResolution: ModuleResolutionKind? - get() = definedExternally - set(value) = definedExternally - var newLine: NewLineKind? - get() = definedExternally - set(value) = definedExternally - var noEmit: Boolean? - get() = definedExternally - set(value) = definedExternally - var noEmitHelpers: Boolean? - get() = definedExternally - set(value) = definedExternally - var noEmitOnError: Boolean? - get() = definedExternally - set(value) = definedExternally - var noErrorTruncation: Boolean? - get() = definedExternally - set(value) = definedExternally - var noFallthroughCasesInSwitch: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitAny: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitReturns: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitThis: Boolean? - get() = definedExternally - set(value) = definedExternally - var noStrictGenericChecks: Boolean? - get() = definedExternally - set(value) = definedExternally - var noUnusedLocals: Boolean? - get() = definedExternally - set(value) = definedExternally - var noUnusedParameters: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitUseStrict: Boolean? - get() = definedExternally - set(value) = definedExternally - var noPropertyAccessFromIndexSignature: Boolean? - get() = definedExternally - set(value) = definedExternally - var assumeChangesOnlyAffectDirectDependencies: Boolean? - get() = definedExternally - set(value) = definedExternally - var noLib: Boolean? - get() = definedExternally - set(value) = definedExternally - var noResolve: Boolean? - get() = definedExternally - set(value) = definedExternally - var noUncheckedIndexedAccess: Boolean? - get() = definedExternally - set(value) = definedExternally - var out: String? - get() = definedExternally - set(value) = definedExternally - var outDir: String? - get() = definedExternally - set(value) = definedExternally - var outFile: String? - get() = definedExternally - set(value) = definedExternally - var paths: MapLike>? - get() = definedExternally - set(value) = definedExternally - var preserveConstEnums: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitOverride: Boolean? - get() = definedExternally - set(value) = definedExternally - var preserveSymlinks: Boolean? - get() = definedExternally - set(value) = definedExternally - var project: String? - get() = definedExternally - set(value) = definedExternally - var reactNamespace: String? - get() = definedExternally - set(value) = definedExternally - var jsxFactory: String? - get() = definedExternally - set(value) = definedExternally - var jsxFragmentFactory: String? - get() = definedExternally - set(value) = definedExternally - var jsxImportSource: String? - get() = definedExternally - set(value) = definedExternally - var composite: Boolean? - get() = definedExternally - set(value) = definedExternally - var incremental: Boolean? - get() = definedExternally - set(value) = definedExternally - var tsBuildInfoFile: String? - get() = definedExternally - set(value) = definedExternally - var removeComments: Boolean? - get() = definedExternally - set(value) = definedExternally - var rootDir: String? - get() = definedExternally - set(value) = definedExternally - var rootDirs: Array? - get() = definedExternally - set(value) = definedExternally - var skipLibCheck: Boolean? - get() = definedExternally - set(value) = definedExternally - var skipDefaultLibCheck: Boolean? - get() = definedExternally - set(value) = definedExternally - var sourceMap: Boolean? - get() = definedExternally - set(value) = definedExternally - var sourceRoot: String? - get() = definedExternally - set(value) = definedExternally - var strict: Boolean? - get() = definedExternally - set(value) = definedExternally - var strictFunctionTypes: Boolean? - get() = definedExternally - set(value) = definedExternally - var strictBindCallApply: Boolean? - get() = definedExternally - set(value) = definedExternally - var strictNullChecks: Boolean? - get() = definedExternally - set(value) = definedExternally - var strictPropertyInitialization: Boolean? - get() = definedExternally - set(value) = definedExternally - var stripInternal: Boolean? - get() = definedExternally - set(value) = definedExternally - var suppressExcessPropertyErrors: Boolean? - get() = definedExternally - set(value) = definedExternally - var suppressImplicitAnyIndexErrors: Boolean? - get() = definedExternally - set(value) = definedExternally - var target: ScriptTarget? - get() = definedExternally - set(value) = definedExternally - var traceResolution: Boolean? - get() = definedExternally - set(value) = definedExternally - var useUnknownInCatchVariables: Boolean? - get() = definedExternally - set(value) = definedExternally - var resolveJsonModule: Boolean? - get() = definedExternally - set(value) = definedExternally - var types: Array? - get() = definedExternally - set(value) = definedExternally - var typeRoots: Array? - get() = definedExternally - set(value) = definedExternally - var esModuleInterop: Boolean? - get() = definedExternally - set(value) = definedExternally - var useDefineForClassFields: Boolean? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? | TsConfigSourceFile? */ - @nativeSetter - operator fun set(option: String, value: String?) - @nativeSetter - operator fun set(option: String, value: Number?) - @nativeSetter - operator fun set(option: String, value: Boolean?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: MapLike>?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: TsConfigSourceFile?) -} - -external interface WatchOptions { - var watchFile: WatchFileKind? - get() = definedExternally - set(value) = definedExternally - var watchDirectory: WatchDirectoryKind? - get() = definedExternally - set(value) = definedExternally - var fallbackPolling: PollingWatchKind? - get() = definedExternally - set(value) = definedExternally - var synchronousWatchDirectory: Boolean? - get() = definedExternally - set(value) = definedExternally - var excludeDirectories: Array? - get() = definedExternally - set(value) = definedExternally - var excludeFiles: Array? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ - @nativeSetter - operator fun set(option: String, value: String?) - @nativeSetter - operator fun set(option: String, value: Number?) - @nativeSetter - operator fun set(option: String, value: Boolean?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: MapLike>?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) -} - -external interface TypeAcquisition { - var enableAutoDiscovery: Boolean? - get() = definedExternally - set(value) = definedExternally - var enable: Boolean? - get() = definedExternally - set(value) = definedExternally - var include: Array? - get() = definedExternally - set(value) = definedExternally - var exclude: Array? - get() = definedExternally - set(value) = definedExternally - var disableFilenameBasedTypeAcquisition: Boolean? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ - @nativeSetter - operator fun set(option: String, value: String?) - @nativeSetter - operator fun set(option: String, value: Number?) - @nativeSetter - operator fun set(option: String, value: Boolean?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: MapLike>?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) -} - -external enum class ModuleKind { - None /* = 0 */, - CommonJS /* = 1 */, - AMD /* = 2 */, - UMD /* = 3 */, - System /* = 4 */, - ES2015 /* = 5 */, - ES2020 /* = 6 */, - ESNext /* = 99 */ -} - -external enum class JsxEmit { - None /* = 0 */, - Preserve /* = 1 */, - React /* = 2 */, - ReactNative /* = 3 */, - ReactJSX /* = 4 */, - ReactJSXDev /* = 5 */ -} - -external enum class ImportsNotUsedAsValues { - Remove /* = 0 */, - Preserve /* = 1 */, - Error /* = 2 */ -} - -external enum class NewLineKind { - CarriageReturnLineFeed /* = 0 */, - LineFeed /* = 1 */ -} - -external interface LineAndCharacter { - var line: Number - var character: Number -} - -external enum class ScriptKind { - Unknown /* = 0 */, - JS /* = 1 */, - JSX /* = 2 */, - TS /* = 3 */, - TSX /* = 4 */, - External /* = 5 */, - JSON /* = 6 */, - Deferred /* = 7 */ -} - -external enum class ScriptTarget { - ES3 /* = 0 */, - ES5 /* = 1 */, - ES2015 /* = 2 */, - ES2016 /* = 3 */, - ES2017 /* = 4 */, - ES2018 /* = 5 */, - ES2019 /* = 6 */, - ES2020 /* = 7 */, - ES2021 /* = 8 */, - ESNext /* = 99 */, - JSON /* = 100 */, - Latest /* = 99 */ -} - -external enum class LanguageVariant { - Standard /* = 0 */, - JSX /* = 1 */ -} - -external interface ParsedCommandLine { - var options: CompilerOptions - var typeAcquisition: TypeAcquisition? - get() = definedExternally - set(value) = definedExternally - var fileNames: Array - var projectReferences: Array? - get() = definedExternally - set(value) = definedExternally - var watchOptions: WatchOptions? - get() = definedExternally - set(value) = definedExternally - var raw: Any? - get() = definedExternally - set(value) = definedExternally - var errors: Array - var wildcardDirectories: MapLike? - get() = definedExternally - set(value) = definedExternally - var compileOnSave: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external enum class WatchDirectoryFlags { - None /* = 0 */, - Recursive /* = 1 */ -} - -external interface CreateProgramOptions { - var rootNames: Array - var options: CompilerOptions - var projectReferences: Array? - get() = definedExternally - set(value) = definedExternally - var host: CompilerHost? - get() = definedExternally - set(value) = definedExternally - var oldProgram: Program? - get() = definedExternally - set(value) = definedExternally - var configFileParsingDiagnostics: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface ModuleResolutionHost { - fun fileExists(fileName: String): Boolean - fun readFile(fileName: String): String? - val trace: ((s: String) -> Unit)? - val directoryExists: ((directoryName: String) -> Boolean)? - val realpath: ((path: String) -> String)? - val getCurrentDirectory: (() -> String)? - val getDirectories: ((path: String) -> Array)? -} - -external interface ResolvedModule { - var resolvedFileName: String - var isExternalLibraryImport: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedModuleFull : ResolvedModule { - var extension: Extension - var packageId: PackageId? - get() = definedExternally - set(value) = definedExternally -} - -external interface PackageId { - var name: String - var subModuleName: String - var version: String -} - -external enum class Extension { - Ts /* = ".ts" */, - Tsx /* = ".tsx" */, - Dts /* = ".d.ts" */, - Js /* = ".js" */, - Jsx /* = ".jsx" */, - Json /* = ".json" */, - TsBuildInfo /* = ".tsbuildinfo" */ -} - -external interface ResolvedModuleWithFailedLookupLocations { - val resolvedModule: ResolvedModuleFull? -} - -external interface ResolvedTypeReferenceDirective { - var primary: Boolean - var resolvedFileName: String? - var packageId: PackageId? - get() = definedExternally - set(value) = definedExternally - var isExternalLibraryImport: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations { - val resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective? - val failedLookupLocations: Array -} - -external interface CompilerHost : ModuleResolutionHost { - fun getSourceFile(fileName: String, languageVersion: ScriptTarget, onError: (message: String) -> Unit = definedExternally, shouldCreateNewSourceFile: Boolean = definedExternally): SourceFile? - val getSourceFileByPath: ((fileName: String, path: String /* String & `T$3` */, languageVersion: ScriptTarget, onError: (message: String) -> Unit, shouldCreateNewSourceFile: Boolean) -> SourceFile?)? - val getCancellationToken: (() -> CancellationToken)? - fun getDefaultLibFileName(options: CompilerOptions): String - val getDefaultLibLocation: (() -> String)? - var writeFile: WriteFileCallback - override var getCurrentDirectory: () -> String - fun getCanonicalFileName(fileName: String): String - fun useCaseSensitiveFileNames(): Boolean - fun getNewLine(): String - val readDirectory: ((rootDir: String, extensions: Array, excludes: Array?, includes: Array, depth: Number) -> Array)? - val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val getEnvironmentVariable: ((name: String) -> String?)? - val createHash: ((data: String) -> String)? - val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? -} - -external interface SourceMapRange : TextRange { - var source: SourceMapSource? - get() = definedExternally - set(value) = definedExternally -} - -external interface SourceMapSource { - fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter - var fileName: String - var text: String - var skipTrivia: ((pos: Number) -> Number)? - get() = definedExternally - set(value) = definedExternally -} - -external enum class EmitFlags { - None /* = 0 */, - SingleLine /* = 1 */, - AdviseOnEmitNode /* = 2 */, - NoSubstitution /* = 4 */, - CapturesThis /* = 8 */, - NoLeadingSourceMap /* = 16 */, - NoTrailingSourceMap /* = 32 */, - NoSourceMap /* = 48 */, - NoNestedSourceMaps /* = 64 */, - NoTokenLeadingSourceMaps /* = 128 */, - NoTokenTrailingSourceMaps /* = 256 */, - NoTokenSourceMaps /* = 384 */, - NoLeadingComments /* = 512 */, - NoTrailingComments /* = 1024 */, - NoComments /* = 1536 */, - NoNestedComments /* = 2048 */, - HelperName /* = 4096 */, - ExportName /* = 8192 */, - LocalName /* = 16384 */, - InternalName /* = 32768 */, - Indented /* = 65536 */, - NoIndentation /* = 131072 */, - AsyncFunctionBody /* = 262144 */, - ReuseTempVariableScope /* = 524288 */, - CustomPrologue /* = 1048576 */, - NoHoisting /* = 2097152 */, - HasEndOfDeclarationMarker /* = 4194304 */, - Iterator /* = 8388608 */, - NoAsciiEscaping /* = 16777216 */ -} - -external interface EmitHelperBase { - val name: String - val scoped: Boolean - val text: dynamic /* String | (node: EmitHelperUniqueNameCallback) -> String */ - get() = definedExternally - val priority: Number? - get() = definedExternally - val dependencies: Array? - get() = definedExternally -} - -external interface ScopedEmitHelper : EmitHelperBase { - override val scoped: Boolean -} - -external interface UnscopedEmitHelper : EmitHelperBase { - override val scoped: Boolean - override val text: String -} - -external enum class EmitHint { - SourceFile /* = 0 */, - Expression /* = 1 */, - IdentifierName /* = 2 */, - MappedTypeParameter /* = 3 */, - Unspecified /* = 4 */, - EmbeddedStatement /* = 5 */, - JsxAttributeValue /* = 6 */ -} - -external enum class OuterExpressionKinds { - Parentheses /* = 1 */, - TypeAssertions /* = 2 */, - NonNullAssertions /* = 4 */, - PartiallyEmittedExpressions /* = 8 */, - Assertions /* = 6 */, - All /* = 15 */ -} - -external interface NodeFactory { - fun createNodeArray(elements: Array = definedExternally, hasTrailingComma: Boolean = definedExternally): NodeArray - fun createNumericLiteral(value: String, numericLiteralFlags: TokenFlags = definedExternally): NumericLiteral - fun createNumericLiteral(value: String): NumericLiteral - fun createNumericLiteral(value: Number, numericLiteralFlags: TokenFlags = definedExternally): NumericLiteral - fun createNumericLiteral(value: Number): NumericLiteral - fun createBigIntLiteral(value: String): BigIntLiteral - fun createBigIntLiteral(value: PseudoBigInt): BigIntLiteral - fun createStringLiteral(text: String, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: Identifier, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: Identifier): StringLiteral - fun createStringLiteralFromNode(sourceNode: StringLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: StringLiteral): StringLiteral - fun createStringLiteralFromNode(sourceNode: NoSubstitutionTemplateLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: NoSubstitutionTemplateLiteral): StringLiteral - fun createStringLiteralFromNode(sourceNode: NumericLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: NumericLiteral): StringLiteral - fun createRegularExpressionLiteral(text: String): RegularExpressionLiteral - fun createIdentifier(text: String): Identifier - fun createTempVariable(recordTempVariable: ((node: Identifier) -> Unit)?, reservedInNestedScopes: Boolean = definedExternally): Identifier - fun createLoopVariable(reservedInNestedScopes: Boolean = definedExternally): Identifier - fun createUniqueName(text: String, flags: GeneratedIdentifierFlags = definedExternally): Identifier - fun getGeneratedNameForNode(node: Node?, flags: GeneratedIdentifierFlags = definedExternally): Identifier - fun createPrivateIdentifier(text: String): PrivateIdentifier - fun createToken(token: SyntaxKind.SuperKeyword): SuperExpression - fun createToken(token: SyntaxKind.ThisKeyword): ThisExpression - fun createToken(token: SyntaxKind.NullKeyword): NullLiteral - fun createToken(token: SyntaxKind.TrueKeyword): TrueLiteral - fun createToken(token: SyntaxKind.FalseKeyword): FalseLiteral - fun createToken(token: TKind): dynamic /* Token */ - fun createSuper(): SuperExpression - fun createThis(): ThisExpression - fun createNull(): NullLiteral - fun createTrue(): TrueLiteral - fun createFalse(): FalseLiteral - fun createModifier(kind: T): ModifierToken - fun createModifiersFromModifierFlags(flags: ModifierFlags): Array - fun createQualifiedName(left: Identifier, right: String): QualifiedName - fun createQualifiedName(left: Identifier, right: Identifier): QualifiedName - fun createQualifiedName(left: QualifiedName, right: String): QualifiedName - fun createQualifiedName(left: QualifiedName, right: Identifier): QualifiedName - fun updateQualifiedName(node: QualifiedName, left: Identifier, right: Identifier): QualifiedName - fun updateQualifiedName(node: QualifiedName, left: QualifiedName, right: Identifier): QualifiedName - fun createComputedPropertyName(expression: Expression): ComputedPropertyName - fun updateComputedPropertyName(node: ComputedPropertyName, expression: Expression): ComputedPropertyName - fun createTypeParameterDeclaration(name: String, constraint: TypeNode = definedExternally, defaultType: TypeNode = definedExternally): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: String): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: String, constraint: TypeNode = definedExternally): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: Identifier, constraint: TypeNode = definedExternally, defaultType: TypeNode = definedExternally): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: Identifier): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: Identifier, constraint: TypeNode = definedExternally): TypeParameterDeclaration - fun updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode?, defaultType: TypeNode?): TypeParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration - fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration - fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration - fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration - fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration - fun createDecorator(expression: Expression): Decorator - fun updateDecorator(node: Decorator, expression: Expression): Decorator - fun createPropertySignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: String, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createMethodSignature(modifiers: Array?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createConstructorDeclaration(decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration - fun updateConstructorDeclaration(node: ConstructorDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun createCallSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): CallSignatureDeclaration - fun updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): CallSignatureDeclaration - fun createConstructSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): ConstructSignatureDeclaration - fun updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): ConstructSignatureDeclaration - fun createIndexSignature(decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration - fun updateIndexSignature(node: IndexSignatureDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration - fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan - fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan - fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan - fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan - fun createClassStaticBlockDeclaration(decorators: Array?, modifiers: Array?, body: Block): ClassStaticBlockDeclaration - fun updateClassStaticBlockDeclaration(node: ClassStaticBlockDeclaration, decorators: Array?, modifiers: Array?, body: Block): ClassStaticBlockDeclaration - fun createKeywordTypeNode(kind: TKind): KeywordTypeNode - fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode - fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode - fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: String, type: TypeNode?): TypePredicateNode - fun updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode - fun updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode - fun createTypeReferenceNode(typeName: String, typeArguments: Array = definedExternally): TypeReferenceNode - fun createTypeReferenceNode(typeName: String): TypeReferenceNode - fun createTypeReferenceNode(typeName: Identifier, typeArguments: Array = definedExternally): TypeReferenceNode - fun createTypeReferenceNode(typeName: Identifier): TypeReferenceNode - fun createTypeReferenceNode(typeName: QualifiedName, typeArguments: Array = definedExternally): TypeReferenceNode - fun createTypeReferenceNode(typeName: QualifiedName): TypeReferenceNode - fun updateTypeReferenceNode(node: TypeReferenceNode, typeName: Identifier, typeArguments: NodeArray?): TypeReferenceNode - fun updateTypeReferenceNode(node: TypeReferenceNode, typeName: QualifiedName, typeArguments: NodeArray?): TypeReferenceNode - fun createFunctionTypeNode(typeParameters: Array?, parameters: Array, type: TypeNode): FunctionTypeNode - fun updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): FunctionTypeNode - fun createConstructorTypeNode(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode): ConstructorTypeNode - fun createConstructorTypeNode(typeParameters: Array?, parameters: Array, type: TypeNode): ConstructorTypeNode - fun updateConstructorTypeNode(node: ConstructorTypeNode, modifiers: Array?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): ConstructorTypeNode - fun updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): ConstructorTypeNode - fun createTypeQueryNode(exprName: Identifier): TypeQueryNode - fun createTypeQueryNode(exprName: QualifiedName): TypeQueryNode - fun updateTypeQueryNode(node: TypeQueryNode, exprName: Identifier): TypeQueryNode - fun updateTypeQueryNode(node: TypeQueryNode, exprName: QualifiedName): TypeQueryNode - fun createTypeLiteralNode(members: Array?): TypeLiteralNode - fun updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray): TypeLiteralNode - fun createArrayTypeNode(elementType: TypeNode): ArrayTypeNode - fun updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode - fun createTupleTypeNode(elements: Array): TupleTypeNode - fun updateTupleTypeNode(node: TupleTypeNode, elements: Array): TupleTypeNode - fun createNamedTupleMember(dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode): NamedTupleMember - fun updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode): NamedTupleMember - fun createOptionalTypeNode(type: TypeNode): OptionalTypeNode - fun updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode - fun createRestTypeNode(type: TypeNode): RestTypeNode - fun updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode - fun createUnionTypeNode(types: Array): UnionTypeNode - fun updateUnionTypeNode(node: UnionTypeNode, types: NodeArray): UnionTypeNode - fun createIntersectionTypeNode(types: Array): IntersectionTypeNode - fun updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray): IntersectionTypeNode - fun createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode - fun updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode - fun createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode - fun updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally, typeArguments: Array = definedExternally, isTypeOf: Boolean = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally, typeArguments: Array = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally, typeArguments: Array = definedExternally, isTypeOf: Boolean = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally, typeArguments: Array = definedExternally): ImportTypeNode - fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: Identifier?, typeArguments: Array?, isTypeOf: Boolean = definedExternally): ImportTypeNode - fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: Identifier?, typeArguments: Array?): ImportTypeNode - fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: QualifiedName?, typeArguments: Array?, isTypeOf: Boolean = definedExternally): ImportTypeNode - fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: QualifiedName?, typeArguments: Array?): ImportTypeNode - fun createParenthesizedType(type: TypeNode): ParenthesizedTypeNode - fun updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode - fun createThisTypeNode(): ThisTypeNode - fun createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword, type: TypeNode): TypeOperatorNode - fun createTypeOperatorNode(operator: SyntaxKind.UniqueKeyword, type: TypeNode): TypeOperatorNode - fun createTypeOperatorNode(operator: SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode - fun updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode - fun createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode - fun updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode - fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun createLiteralTypeNode(literal: NullLiteral): LiteralTypeNode - fun createLiteralTypeNode(literal: TrueLiteral): LiteralTypeNode - fun createLiteralTypeNode(literal: FalseLiteral): LiteralTypeNode - fun createLiteralTypeNode(literal: LiteralExpression): LiteralTypeNode - fun createLiteralTypeNode(literal: PrefixUnaryExpression): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: NullLiteral): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: TrueLiteral): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: FalseLiteral): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralExpression): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: PrefixUnaryExpression): LiteralTypeNode - fun createTemplateLiteralType(head: TemplateHead, templateSpans: Array): TemplateLiteralTypeNode - fun updateTemplateLiteralType(node: TemplateLiteralTypeNode, head: TemplateHead, templateSpans: Array): TemplateLiteralTypeNode - fun createObjectBindingPattern(elements: Array): ObjectBindingPattern - fun updateObjectBindingPattern(node: ObjectBindingPattern, elements: Array): ObjectBindingPattern - fun createArrayBindingPattern(elements: Array): ArrayBindingPattern - fun updateArrayBindingPattern(node: ArrayBindingPattern, elements: Array): ArrayBindingPattern - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: String?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: String?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun createArrayLiteralExpression(elements: Array = definedExternally, multiLine: Boolean = definedExternally): ArrayLiteralExpression - fun updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: Array): ArrayLiteralExpression - fun createObjectLiteralExpression(properties: Array = definedExternally, multiLine: Boolean = definedExternally): ObjectLiteralExpression - fun updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: Array): ObjectLiteralExpression - fun createPropertyAccessExpression(expression: Expression, name: String): PropertyAccessExpression - fun createPropertyAccessExpression(expression: Expression, name: Identifier): PropertyAccessExpression - fun createPropertyAccessExpression(expression: Expression, name: PrivateIdentifier): PropertyAccessExpression - fun updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier): PropertyAccessExpression - fun updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: PrivateIdentifier): PropertyAccessExpression - fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: String): PropertyAccessChain - fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: Identifier): PropertyAccessChain - fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: PrivateIdentifier): PropertyAccessChain - fun updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: Identifier): PropertyAccessChain - fun updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: PrivateIdentifier): PropertyAccessChain - fun createElementAccessExpression(expression: Expression, index: Number): ElementAccessExpression - fun createElementAccessExpression(expression: Expression, index: Expression): ElementAccessExpression - fun updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression - fun createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, index: Number): ElementAccessChain - fun createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, index: Expression): ElementAccessChain - fun updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, argumentExpression: Expression): ElementAccessChain - fun createCallExpression(expression: Expression, typeArguments: Array?, argumentsArray: Array?): CallExpression - fun updateCallExpression(node: CallExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array): CallExpression - fun createCallChain(expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array?): CallChain - fun updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array): CallChain - fun createNewExpression(expression: Expression, typeArguments: Array?, argumentsArray: Array?): NewExpression - fun updateNewExpression(node: NewExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array?): NewExpression - fun createTaggedTemplateExpression(tag: Expression, typeArguments: Array?, template: TemplateExpression): TaggedTemplateExpression - fun createTaggedTemplateExpression(tag: Expression, typeArguments: Array?, template: NoSubstitutionTemplateLiteral): TaggedTemplateExpression - fun updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: TemplateExpression): TaggedTemplateExpression - fun updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: NoSubstitutionTemplateLiteral): TaggedTemplateExpression - fun createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion - fun updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion - fun createParenthesizedExpression(expression: Expression): ParenthesizedExpression - fun updateParenthesizedExpression(node: ParenthesizedExpression, expression: Expression): ParenthesizedExpression - fun createFunctionExpression(modifiers: Array?, asteriskToken: AsteriskToken?, name: String?, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block): FunctionExpression - fun createFunctionExpression(modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block): FunctionExpression - fun updateFunctionExpression(node: FunctionExpression, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block): FunctionExpression - fun createArrowFunction(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: FunctionBody): ArrowFunction - fun createArrowFunction(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: Expression): ArrowFunction - fun updateArrowFunction(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: FunctionBody): ArrowFunction - fun updateArrowFunction(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: Expression): ArrowFunction - fun createDeleteExpression(expression: Expression): DeleteExpression - fun updateDeleteExpression(node: DeleteExpression, expression: Expression): DeleteExpression - fun createTypeOfExpression(expression: Expression): TypeOfExpression - fun updateTypeOfExpression(node: TypeOfExpression, expression: Expression): TypeOfExpression - fun createVoidExpression(expression: Expression): VoidExpression - fun updateVoidExpression(node: VoidExpression, expression: Expression): VoidExpression - fun createAwaitExpression(expression: Expression): AwaitExpression - fun updateAwaitExpression(node: AwaitExpression, expression: Expression): AwaitExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.PlusPlusToken, operand: Expression): PrefixUnaryExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.MinusMinusToken, operand: Expression): PrefixUnaryExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.PlusToken, operand: Expression): PrefixUnaryExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.MinusToken, operand: Expression): PrefixUnaryExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.TildeToken, operand: Expression): PrefixUnaryExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.ExclamationToken, operand: Expression): PrefixUnaryExpression - fun updatePrefixUnaryExpression(node: PrefixUnaryExpression, operand: Expression): PrefixUnaryExpression - fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind.PlusPlusToken): PostfixUnaryExpression - fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind.MinusMinusToken): PostfixUnaryExpression - fun updatePostfixUnaryExpression(node: PostfixUnaryExpression, operand: Expression): PostfixUnaryExpression - fun createBinaryExpression(left: Expression, operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression): BinaryExpression - fun updateBinaryExpression(node: BinaryExpression, left: Expression, operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression): BinaryExpression - fun createConditionalExpression(condition: Expression, questionToken: QuestionToken?, whenTrue: Expression, colonToken: ColonToken?, whenFalse: Expression): ConditionalExpression - fun updateConditionalExpression(node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression - fun createTemplateExpression(head: TemplateHead, templateSpans: Array): TemplateExpression - fun updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: Array): TemplateExpression - fun createTemplateHead(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateHead - fun createTemplateHead(text: String): TemplateHead - fun createTemplateHead(text: String, rawText: String = definedExternally): TemplateHead - fun createTemplateHead(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateHead - fun createTemplateHead(text: String?, rawText: String): TemplateHead - fun createTemplateMiddle(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateMiddle - fun createTemplateMiddle(text: String): TemplateMiddle - fun createTemplateMiddle(text: String, rawText: String = definedExternally): TemplateMiddle - fun createTemplateMiddle(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateMiddle - fun createTemplateMiddle(text: String?, rawText: String): TemplateMiddle - fun createTemplateTail(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateTail - fun createTemplateTail(text: String): TemplateTail - fun createTemplateTail(text: String, rawText: String = definedExternally): TemplateTail - fun createTemplateTail(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateTail - fun createTemplateTail(text: String?, rawText: String): TemplateTail - fun createNoSubstitutionTemplateLiteral(text: String, rawText: String = definedExternally): NoSubstitutionTemplateLiteral - fun createNoSubstitutionTemplateLiteral(text: String): NoSubstitutionTemplateLiteral - fun createNoSubstitutionTemplateLiteral(text: String?, rawText: String): NoSubstitutionTemplateLiteral - fun createYieldExpression(asteriskToken: AsteriskToken, expression: Expression): YieldExpression - fun createYieldExpression(asteriskToken: Nothing?, expression: Expression?): YieldExpression - fun updateYieldExpression(node: YieldExpression, asteriskToken: AsteriskToken?, expression: Expression?): YieldExpression - fun createSpreadElement(expression: Expression): SpreadElement - fun updateSpreadElement(node: SpreadElement, expression: Expression): SpreadElement - fun createClassExpression(decorators: Array?, modifiers: Array?, name: String?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression - fun createClassExpression(decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression - fun updateClassExpression(node: ClassExpression, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression - fun createOmittedExpression(): OmittedExpression - fun createExpressionWithTypeArguments(expression: Expression, typeArguments: Array?): ExpressionWithTypeArguments - fun updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, expression: Expression, typeArguments: Array?): ExpressionWithTypeArguments - fun createAsExpression(expression: Expression, type: TypeNode): AsExpression - fun updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode): AsExpression - fun createNonNullExpression(expression: Expression): NonNullExpression - fun updateNonNullExpression(node: NonNullExpression, expression: Expression): NonNullExpression - fun createNonNullChain(expression: Expression): NonNullChain - fun updateNonNullChain(node: NonNullChain, expression: Expression): NonNullChain - fun createMetaProperty(keywordToken: SyntaxKind.NewKeyword, name: Identifier): MetaProperty - fun createMetaProperty(keywordToken: SyntaxKind.ImportKeyword, name: Identifier): MetaProperty - fun updateMetaProperty(node: MetaProperty, name: Identifier): MetaProperty - fun createTemplateSpan(expression: Expression, literal: TemplateMiddle): TemplateSpan - fun createTemplateSpan(expression: Expression, literal: TemplateTail): TemplateSpan - fun updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle): TemplateSpan - fun updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateTail): TemplateSpan - fun createSemicolonClassElement(): SemicolonClassElement - fun createBlock(statements: Array, multiLine: Boolean = definedExternally): Block - fun updateBlock(node: Block, statements: Array): Block - fun createVariableStatement(modifiers: Array?, declarationList: VariableDeclarationList): VariableStatement - fun createVariableStatement(modifiers: Array?, declarationList: Array): VariableStatement - fun updateVariableStatement(node: VariableStatement, modifiers: Array?, declarationList: VariableDeclarationList): VariableStatement - fun createEmptyStatement(): EmptyStatement - fun createExpressionStatement(expression: Expression): ExpressionStatement - fun updateExpressionStatement(node: ExpressionStatement, expression: Expression): ExpressionStatement - fun createIfStatement(expression: Expression, thenStatement: Statement, elseStatement: Statement = definedExternally): IfStatement - fun updateIfStatement(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement?): IfStatement - fun createDoStatement(statement: Statement, expression: Expression): DoStatement - fun updateDoStatement(node: DoStatement, statement: Statement, expression: Expression): DoStatement - fun createWhileStatement(expression: Expression, statement: Statement): WhileStatement - fun updateWhileStatement(node: WhileStatement, expression: Expression, statement: Statement): WhileStatement - fun createForStatement(initializer: VariableDeclarationList?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement - fun createForStatement(initializer: Expression?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement - fun updateForStatement(node: ForStatement, initializer: VariableDeclarationList?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement - fun updateForStatement(node: ForStatement, initializer: Expression?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement - fun createForInStatement(initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForInStatement - fun createForInStatement(initializer: Expression, expression: Expression, statement: Statement): ForInStatement - fun updateForInStatement(node: ForInStatement, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForInStatement - fun updateForInStatement(node: ForInStatement, initializer: Expression, expression: Expression, statement: Statement): ForInStatement - fun createForOfStatement(awaitModifier: AwaitKeyword?, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForOfStatement - fun createForOfStatement(awaitModifier: AwaitKeyword?, initializer: Expression, expression: Expression, statement: Statement): ForOfStatement - fun updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForOfStatement - fun updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: Expression, expression: Expression, statement: Statement): ForOfStatement - fun createContinueStatement(label: String = definedExternally): ContinueStatement - fun createContinueStatement(): ContinueStatement - fun createContinueStatement(label: Identifier = definedExternally): ContinueStatement - fun updateContinueStatement(node: ContinueStatement, label: Identifier?): ContinueStatement - fun createBreakStatement(label: String = definedExternally): BreakStatement - fun createBreakStatement(): BreakStatement - fun createBreakStatement(label: Identifier = definedExternally): BreakStatement - fun updateBreakStatement(node: BreakStatement, label: Identifier?): BreakStatement - fun createReturnStatement(expression: Expression = definedExternally): ReturnStatement - fun updateReturnStatement(node: ReturnStatement, expression: Expression?): ReturnStatement - fun createWithStatement(expression: Expression, statement: Statement): WithStatement - fun updateWithStatement(node: WithStatement, expression: Expression, statement: Statement): WithStatement - fun createSwitchStatement(expression: Expression, caseBlock: CaseBlock): SwitchStatement - fun updateSwitchStatement(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock): SwitchStatement - fun createLabeledStatement(label: String, statement: Statement): LabeledStatement - fun createLabeledStatement(label: Identifier, statement: Statement): LabeledStatement - fun updateLabeledStatement(node: LabeledStatement, label: Identifier, statement: Statement): LabeledStatement - fun createThrowStatement(expression: Expression): ThrowStatement - fun updateThrowStatement(node: ThrowStatement, expression: Expression): ThrowStatement - fun createTryStatement(tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?): TryStatement - fun updateTryStatement(node: TryStatement, tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?): TryStatement - fun createDebuggerStatement(): DebuggerStatement - fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: String): VariableDeclaration - fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: Identifier): VariableDeclaration - fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ObjectBindingPattern): VariableDeclaration - fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ArrayBindingPattern): VariableDeclaration - fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration - fun updateVariableDeclaration(node: VariableDeclaration, name: Identifier, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration - fun updateVariableDeclaration(node: VariableDeclaration, name: ObjectBindingPattern, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration - fun updateVariableDeclaration(node: VariableDeclaration, name: ArrayBindingPattern, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration - fun createVariableDeclarationList(declarations: Array, flags: NodeFlags = definedExternally): VariableDeclarationList - fun updateVariableDeclarationList(node: VariableDeclarationList, declarations: Array): VariableDeclarationList - fun createFunctionDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration - fun createFunctionDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration - fun updateFunctionDeclaration(node: FunctionDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration - fun createClassDeclaration(decorators: Array?, modifiers: Array?, name: String?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration - fun createClassDeclaration(decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration - fun updateClassDeclaration(node: ClassDeclaration, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration - fun createInterfaceDeclaration(decorators: Array?, modifiers: Array?, name: String, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration - fun createInterfaceDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration - fun updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration - fun createTypeAliasDeclaration(decorators: Array?, modifiers: Array?, name: String, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration - fun createTypeAliasDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration - fun updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration - fun createEnumDeclaration(decorators: Array?, modifiers: Array?, name: String, members: Array): EnumDeclaration - fun createEnumDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, members: Array): EnumDeclaration - fun updateEnumDeclaration(node: EnumDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, members: Array): EnumDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?): ModuleDeclaration - fun createModuleBlock(statements: Array): ModuleBlock - fun updateModuleBlock(node: ModuleBlock, statements: Array): ModuleBlock - fun createCaseBlock(clauses: Array): CaseBlock - fun updateCaseBlock(node: CaseBlock, clauses: Array): CaseBlock - fun createNamespaceExportDeclaration(name: String): NamespaceExportDeclaration - fun createNamespaceExportDeclaration(name: Identifier): NamespaceExportDeclaration - fun updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier): NamespaceExportDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: Identifier): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: QualifiedName): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: ExternalModuleReference): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: Identifier): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: QualifiedName): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: ExternalModuleReference): ImportEqualsDeclaration - fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: Identifier): ImportEqualsDeclaration - fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: QualifiedName): ImportEqualsDeclaration - fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: ExternalModuleReference): ImportEqualsDeclaration - fun createImportDeclaration(decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression): ImportDeclaration - fun updateImportDeclaration(node: ImportDeclaration, decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression): ImportDeclaration - fun createImportClause(isTypeOnly: Boolean, name: Identifier?, namedBindings: NamespaceImport?): ImportClause - fun createImportClause(isTypeOnly: Boolean, name: Identifier?, namedBindings: NamedImports?): ImportClause - fun updateImportClause(node: ImportClause, isTypeOnly: Boolean, name: Identifier?, namedBindings: NamespaceImport?): ImportClause - fun updateImportClause(node: ImportClause, isTypeOnly: Boolean, name: Identifier?, namedBindings: NamedImports?): ImportClause - fun createNamespaceImport(name: Identifier): NamespaceImport - fun updateNamespaceImport(node: NamespaceImport, name: Identifier): NamespaceImport - fun createNamespaceExport(name: Identifier): NamespaceExport - fun updateNamespaceExport(node: NamespaceExport, name: Identifier): NamespaceExport - fun createNamedImports(elements: Array): NamedImports - fun updateNamedImports(node: NamedImports, elements: Array): NamedImports - fun createImportSpecifier(propertyName: Identifier?, name: Identifier): ImportSpecifier - fun updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier?, name: Identifier): ImportSpecifier - fun createExportAssignment(decorators: Array?, modifiers: Array?, isExportEquals: Boolean?, expression: Expression): ExportAssignment - fun updateExportAssignment(node: ExportAssignment, decorators: Array?, modifiers: Array?, expression: Expression): ExportAssignment - fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?, moduleSpecifier: Expression = definedExternally): ExportDeclaration - fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?): ExportDeclaration - fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?, moduleSpecifier: Expression = definedExternally): ExportDeclaration - fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?): ExportDeclaration - fun updateExportDeclaration(node: ExportDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?, moduleSpecifier: Expression?): ExportDeclaration - fun updateExportDeclaration(node: ExportDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?, moduleSpecifier: Expression?): ExportDeclaration - fun createNamedExports(elements: Array): NamedExports - fun updateNamedExports(node: NamedExports, elements: Array): NamedExports - fun createExportSpecifier(propertyName: String?, name: String): ExportSpecifier - fun createExportSpecifier(propertyName: String?, name: Identifier): ExportSpecifier - fun createExportSpecifier(propertyName: Identifier?, name: String): ExportSpecifier - fun createExportSpecifier(propertyName: Identifier?, name: Identifier): ExportSpecifier - fun updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier?, name: Identifier): ExportSpecifier - fun createExternalModuleReference(expression: Expression): ExternalModuleReference - fun updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference - fun createJSDocAllType(): JSDocAllType - fun createJSDocUnknownType(): JSDocUnknownType - fun createJSDocNonNullableType(type: TypeNode): JSDocNonNullableType - fun updateJSDocNonNullableType(node: JSDocNonNullableType, type: TypeNode): JSDocNonNullableType - fun createJSDocNullableType(type: TypeNode): JSDocNullableType - fun updateJSDocNullableType(node: JSDocNullableType, type: TypeNode): JSDocNullableType - fun createJSDocOptionalType(type: TypeNode): JSDocOptionalType - fun updateJSDocOptionalType(node: JSDocOptionalType, type: TypeNode): JSDocOptionalType - fun createJSDocFunctionType(parameters: Array, type: TypeNode?): JSDocFunctionType - fun updateJSDocFunctionType(node: JSDocFunctionType, parameters: Array, type: TypeNode?): JSDocFunctionType - fun createJSDocVariadicType(type: TypeNode): JSDocVariadicType - fun updateJSDocVariadicType(node: JSDocVariadicType, type: TypeNode): JSDocVariadicType - fun createJSDocNamepathType(type: TypeNode): JSDocNamepathType - fun updateJSDocNamepathType(node: JSDocNamepathType, type: TypeNode): JSDocNamepathType - fun createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression - fun updateJSDocTypeExpression(node: JSDocTypeExpression, type: TypeNode): JSDocTypeExpression - fun createJSDocNameReference(name: Identifier): JSDocNameReference - fun createJSDocNameReference(name: QualifiedName): JSDocNameReference - fun createJSDocNameReference(name: JSDocMemberName): JSDocNameReference - fun updateJSDocNameReference(node: JSDocNameReference, name: Identifier): JSDocNameReference - fun updateJSDocNameReference(node: JSDocNameReference, name: QualifiedName): JSDocNameReference - fun updateJSDocNameReference(node: JSDocNameReference, name: JSDocMemberName): JSDocNameReference - fun createJSDocMemberName(left: Identifier, right: Identifier): JSDocMemberName - fun createJSDocMemberName(left: QualifiedName, right: Identifier): JSDocMemberName - fun createJSDocMemberName(left: JSDocMemberName, right: Identifier): JSDocMemberName - fun updateJSDocMemberName(node: JSDocMemberName, left: Identifier, right: Identifier): JSDocMemberName - fun updateJSDocMemberName(node: JSDocMemberName, left: QualifiedName, right: Identifier): JSDocMemberName - fun updateJSDocMemberName(node: JSDocMemberName, left: JSDocMemberName, right: Identifier): JSDocMemberName - fun createJSDocLink(name: Identifier?, text: String): JSDocLink - fun createJSDocLink(name: QualifiedName?, text: String): JSDocLink - fun createJSDocLink(name: JSDocMemberName?, text: String): JSDocLink - fun updateJSDocLink(node: JSDocLink, name: Identifier?, text: String): JSDocLink - fun updateJSDocLink(node: JSDocLink, name: QualifiedName?, text: String): JSDocLink - fun updateJSDocLink(node: JSDocLink, name: JSDocMemberName?, text: String): JSDocLink - fun createJSDocLinkCode(name: Identifier?, text: String): JSDocLinkCode - fun createJSDocLinkCode(name: QualifiedName?, text: String): JSDocLinkCode - fun createJSDocLinkCode(name: JSDocMemberName?, text: String): JSDocLinkCode - fun updateJSDocLinkCode(node: JSDocLinkCode, name: Identifier?, text: String): JSDocLinkCode - fun updateJSDocLinkCode(node: JSDocLinkCode, name: QualifiedName?, text: String): JSDocLinkCode - fun updateJSDocLinkCode(node: JSDocLinkCode, name: JSDocMemberName?, text: String): JSDocLinkCode - fun createJSDocLinkPlain(name: Identifier?, text: String): JSDocLinkPlain - fun createJSDocLinkPlain(name: QualifiedName?, text: String): JSDocLinkPlain - fun createJSDocLinkPlain(name: JSDocMemberName?, text: String): JSDocLinkPlain - fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: Identifier?, text: String): JSDocLinkPlain - fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: QualifiedName?, text: String): JSDocLinkPlain - fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: JSDocMemberName?, text: String): JSDocLinkPlain - fun createJSDocTypeLiteral(jsDocPropertyTags: Array = definedExternally, isArrayType: Boolean = definedExternally): JSDocTypeLiteral - fun updateJSDocTypeLiteral(node: JSDocTypeLiteral, jsDocPropertyTags: Array?, isArrayType: Boolean?): JSDocTypeLiteral - fun createJSDocSignature(typeParameters: Array?, parameters: Array, type: JSDocReturnTag = definedExternally): JSDocSignature - fun updateJSDocSignature(node: JSDocSignature, typeParameters: Array?, parameters: Array, type: JSDocReturnTag?): JSDocSignature - fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String = definedExternally): JSDocTemplateTag - fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array): JSDocTemplateTag - fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray = definedExternally): JSDocTemplateTag - fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String?): JSDocTemplateTag - fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray?): JSDocTemplateTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag - fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocTypeTag - fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocTypeTag - fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocTypeTag - fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocTypeTag - fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocTypeTag - fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag - fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag - fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag - fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag - fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag - fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag - fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: String = definedExternally): JSDocReturnTag - fun createJSDocReturnTag(tagName: Identifier?): JSDocReturnTag - fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocReturnTag - fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: NodeArray = definedExternally): JSDocReturnTag - fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocReturnTag - fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocReturnTag - fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocThisTag - fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocThisTag - fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocThisTag - fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocThisTag - fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocThisTag - fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocEnumTag - fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocEnumTag - fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocEnumTag - fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocEnumTag - fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocEnumTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: String?): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: NodeArray?): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocCallbackTag - fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String = definedExternally): JSDocAugmentsTag - fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */): JSDocAugmentsTag - fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray = definedExternally): JSDocAugmentsTag - fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String?): JSDocAugmentsTag - fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray?): JSDocAugmentsTag - fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String = definedExternally): JSDocImplementsTag - fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */): JSDocImplementsTag - fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray = definedExternally): JSDocImplementsTag - fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String?): JSDocImplementsTag - fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray?): JSDocImplementsTag - fun createJSDocAuthorTag(tagName: Identifier?, comment: String = definedExternally): JSDocAuthorTag - fun createJSDocAuthorTag(tagName: Identifier?): JSDocAuthorTag - fun createJSDocAuthorTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocAuthorTag - fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: String?): JSDocAuthorTag - fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: NodeArray?): JSDocAuthorTag - fun createJSDocClassTag(tagName: Identifier?, comment: String = definedExternally): JSDocClassTag - fun createJSDocClassTag(tagName: Identifier?): JSDocClassTag - fun createJSDocClassTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocClassTag - fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: String?): JSDocClassTag - fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: NodeArray?): JSDocClassTag - fun createJSDocPublicTag(tagName: Identifier?, comment: String = definedExternally): JSDocPublicTag - fun createJSDocPublicTag(tagName: Identifier?): JSDocPublicTag - fun createJSDocPublicTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPublicTag - fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: String?): JSDocPublicTag - fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: NodeArray?): JSDocPublicTag - fun createJSDocPrivateTag(tagName: Identifier?, comment: String = definedExternally): JSDocPrivateTag - fun createJSDocPrivateTag(tagName: Identifier?): JSDocPrivateTag - fun createJSDocPrivateTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPrivateTag - fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: String?): JSDocPrivateTag - fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: NodeArray?): JSDocPrivateTag - fun createJSDocProtectedTag(tagName: Identifier?, comment: String = definedExternally): JSDocProtectedTag - fun createJSDocProtectedTag(tagName: Identifier?): JSDocProtectedTag - fun createJSDocProtectedTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocProtectedTag - fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: String?): JSDocProtectedTag - fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: NodeArray?): JSDocProtectedTag - fun createJSDocReadonlyTag(tagName: Identifier?, comment: String = definedExternally): JSDocReadonlyTag - fun createJSDocReadonlyTag(tagName: Identifier?): JSDocReadonlyTag - fun createJSDocReadonlyTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocReadonlyTag - fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: String?): JSDocReadonlyTag - fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: NodeArray?): JSDocReadonlyTag - fun createJSDocUnknownTag(tagName: Identifier, comment: String = definedExternally): JSDocUnknownTag - fun createJSDocUnknownTag(tagName: Identifier): JSDocUnknownTag - fun createJSDocUnknownTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocUnknownTag - fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: String?): JSDocUnknownTag - fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: NodeArray?): JSDocUnknownTag - fun createJSDocDeprecatedTag(tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag - fun createJSDocDeprecatedTag(tagName: Identifier): JSDocDeprecatedTag - fun createJSDocDeprecatedTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag - fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag - fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier): JSDocDeprecatedTag - fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag - fun createJSDocOverrideTag(tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag - fun createJSDocOverrideTag(tagName: Identifier): JSDocOverrideTag - fun createJSDocOverrideTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag - fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag - fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier): JSDocOverrideTag - fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag - fun createJSDocText(text: String): JSDocText - fun updateJSDocText(node: JSDocText, text: String): JSDocText - fun createJSDocComment(comment: String? = definedExternally, tags: Array? = definedExternally): JSDoc - fun createJSDocComment(): JSDoc - fun createJSDocComment(comment: String? = definedExternally): JSDoc - fun createJSDocComment(comment: NodeArray? = definedExternally, tags: Array? = definedExternally): JSDoc - fun createJSDocComment(comment: NodeArray? = definedExternally): JSDoc - fun updateJSDocComment(node: JSDoc, comment: String?, tags: Array?): JSDoc - fun updateJSDocComment(node: JSDoc, comment: NodeArray?, tags: Array?): JSDoc - fun createJsxElement(openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement - fun updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement - fun createJsxSelfClosingElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun createJsxSelfClosingElement(tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun createJsxSelfClosingElement(tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun createJsxOpeningElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun createJsxOpeningElement(tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun createJsxOpeningElement(tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun createJsxClosingElement(tagName: Identifier): JsxClosingElement - fun createJsxClosingElement(tagName: ThisExpression): JsxClosingElement - fun createJsxClosingElement(tagName: JsxTagNamePropertyAccess): JsxClosingElement - fun updateJsxClosingElement(node: JsxClosingElement, tagName: Identifier): JsxClosingElement - fun updateJsxClosingElement(node: JsxClosingElement, tagName: ThisExpression): JsxClosingElement - fun updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNamePropertyAccess): JsxClosingElement - fun createJsxFragment(openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment): JsxFragment - fun createJsxText(text: String, containsOnlyTriviaWhiteSpaces: Boolean = definedExternally): JsxText - fun updateJsxText(node: JsxText, text: String, containsOnlyTriviaWhiteSpaces: Boolean = definedExternally): JsxText - fun createJsxOpeningFragment(): JsxOpeningFragment - fun createJsxJsxClosingFragment(): JsxClosingFragment - fun updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment): JsxFragment - fun createJsxAttribute(name: Identifier, initializer: StringLiteral?): JsxAttribute - fun createJsxAttribute(name: Identifier, initializer: JsxExpression?): JsxAttribute - fun updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral?): JsxAttribute - fun updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: JsxExpression?): JsxAttribute - fun createJsxAttributes(properties: Array): JsxAttributes - fun updateJsxAttributes(node: JsxAttributes, properties: Array): JsxAttributes - fun createJsxSpreadAttribute(expression: Expression): JsxSpreadAttribute - fun updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression): JsxSpreadAttribute - fun createJsxExpression(dotDotDotToken: DotDotDotToken?, expression: Expression?): JsxExpression - fun updateJsxExpression(node: JsxExpression, expression: Expression?): JsxExpression - fun createCaseClause(expression: Expression, statements: Array): CaseClause - fun updateCaseClause(node: CaseClause, expression: Expression, statements: Array): CaseClause - fun createDefaultClause(statements: Array): DefaultClause - fun updateDefaultClause(node: DefaultClause, statements: Array): DefaultClause - fun createHeritageClause(token: SyntaxKind.ExtendsKeyword, types: Array): HeritageClause - fun createHeritageClause(token: SyntaxKind.ImplementsKeyword, types: Array): HeritageClause - fun updateHeritageClause(node: HeritageClause, types: Array): HeritageClause - fun createCatchClause(variableDeclaration: String?, block: Block): CatchClause - fun createCatchClause(variableDeclaration: VariableDeclaration?, block: Block): CatchClause - fun updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration?, block: Block): CatchClause - fun createPropertyAssignment(name: String, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: Identifier, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: StringLiteral, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: NumericLiteral, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: ComputedPropertyName, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: PrivateIdentifier, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: Identifier, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: StringLiteral, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: NumericLiteral, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: ComputedPropertyName, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: PrivateIdentifier, initializer: Expression): PropertyAssignment - fun createShorthandPropertyAssignment(name: String, objectAssignmentInitializer: Expression = definedExternally): ShorthandPropertyAssignment - fun createShorthandPropertyAssignment(name: String): ShorthandPropertyAssignment - fun createShorthandPropertyAssignment(name: Identifier, objectAssignmentInitializer: Expression = definedExternally): ShorthandPropertyAssignment - fun createShorthandPropertyAssignment(name: Identifier): ShorthandPropertyAssignment - fun updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression?): ShorthandPropertyAssignment - fun createSpreadAssignment(expression: Expression): SpreadAssignment - fun updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment - fun createEnumMember(name: String, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: String): EnumMember - fun createEnumMember(name: Identifier, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: Identifier): EnumMember - fun createEnumMember(name: StringLiteral, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: StringLiteral): EnumMember - fun createEnumMember(name: NumericLiteral, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: NumericLiteral): EnumMember - fun createEnumMember(name: ComputedPropertyName, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: ComputedPropertyName): EnumMember - fun createEnumMember(name: PrivateIdentifier, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: PrivateIdentifier): EnumMember - fun updateEnumMember(node: EnumMember, name: Identifier, initializer: Expression?): EnumMember - fun updateEnumMember(node: EnumMember, name: StringLiteral, initializer: Expression?): EnumMember - fun updateEnumMember(node: EnumMember, name: NumericLiteral, initializer: Expression?): EnumMember - fun updateEnumMember(node: EnumMember, name: ComputedPropertyName, initializer: Expression?): EnumMember - fun updateEnumMember(node: EnumMember, name: PrivateIdentifier, initializer: Expression?): EnumMember - fun createSourceFile(statements: Array, endOfFileToken: Token /* Token & JSDocContainer */, flags: NodeFlags): SourceFile - fun updateSourceFile(node: SourceFile, statements: Array, isDeclarationFile: Boolean = definedExternally, referencedFiles: Array = definedExternally, typeReferences: Array = definedExternally, hasNoDefaultLib: Boolean = definedExternally, libReferences: Array = definedExternally): SourceFile - fun createNotEmittedStatement(original: Node): NotEmittedStatement - fun createPartiallyEmittedExpression(expression: Expression, original: Node = definedExternally): PartiallyEmittedExpression - fun updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression): PartiallyEmittedExpression - fun createCommaListExpression(elements: Array): CommaListExpression - fun updateCommaListExpression(node: CommaListExpression, elements: Array): CommaListExpression - fun createBundle(sourceFiles: Array, prepends: Array = definedExternally): Bundle - fun updateBundle(node: Bundle, sourceFiles: Array, prepends: Array = definedExternally): Bundle - fun createComma(left: Expression, right: Expression): BinaryExpression - fun createAssignment(left: ObjectLiteralExpression, right: Expression): dynamic /* ObjectDestructuringAssignment | ArrayDestructuringAssignment */ - fun createAssignment(left: ArrayLiteralExpression, right: Expression): dynamic /* ObjectDestructuringAssignment | ArrayDestructuringAssignment */ - fun createAssignment(left: Expression, right: Expression): AssignmentExpression - fun createLogicalOr(left: Expression, right: Expression): BinaryExpression - fun createLogicalAnd(left: Expression, right: Expression): BinaryExpression - fun createBitwiseOr(left: Expression, right: Expression): BinaryExpression - fun createBitwiseXor(left: Expression, right: Expression): BinaryExpression - fun createBitwiseAnd(left: Expression, right: Expression): BinaryExpression - fun createStrictEquality(left: Expression, right: Expression): BinaryExpression - fun createStrictInequality(left: Expression, right: Expression): BinaryExpression - fun createEquality(left: Expression, right: Expression): BinaryExpression - fun createInequality(left: Expression, right: Expression): BinaryExpression - fun createLessThan(left: Expression, right: Expression): BinaryExpression - fun createLessThanEquals(left: Expression, right: Expression): BinaryExpression - fun createGreaterThan(left: Expression, right: Expression): BinaryExpression - fun createGreaterThanEquals(left: Expression, right: Expression): BinaryExpression - fun createLeftShift(left: Expression, right: Expression): BinaryExpression - fun createRightShift(left: Expression, right: Expression): BinaryExpression - fun createUnsignedRightShift(left: Expression, right: Expression): BinaryExpression - fun createAdd(left: Expression, right: Expression): BinaryExpression - fun createSubtract(left: Expression, right: Expression): BinaryExpression - fun createMultiply(left: Expression, right: Expression): BinaryExpression - fun createDivide(left: Expression, right: Expression): BinaryExpression - fun createModulo(left: Expression, right: Expression): BinaryExpression - fun createExponent(left: Expression, right: Expression): BinaryExpression - fun createPrefixPlus(operand: Expression): PrefixUnaryExpression - fun createPrefixMinus(operand: Expression): PrefixUnaryExpression - fun createPrefixIncrement(operand: Expression): PrefixUnaryExpression - fun createPrefixDecrement(operand: Expression): PrefixUnaryExpression - fun createBitwiseNot(operand: Expression): PrefixUnaryExpression - fun createLogicalNot(operand: Expression): PrefixUnaryExpression - fun createPostfixIncrement(operand: Expression): PostfixUnaryExpression - fun createPostfixDecrement(operand: Expression): PostfixUnaryExpression - fun createImmediatelyInvokedFunctionExpression(statements: Array): CallExpression - fun createImmediatelyInvokedFunctionExpression(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression - fun createImmediatelyInvokedArrowFunction(statements: Array): CallExpression - fun createImmediatelyInvokedArrowFunction(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression - fun createVoidZero(): VoidExpression - fun createExportDefault(expression: Expression): ExportAssignment - fun createExternalModuleExport(exportName: Identifier): ExportDeclaration - fun restoreOuterExpressions(outerExpression: Expression?, innerExpression: Expression, kinds: OuterExpressionKinds = definedExternally): Expression -} - -external interface CoreTransformationContext { - val factory: NodeFactory - fun getCompilerOptions(): CompilerOptions - fun startLexicalEnvironment() - fun suspendLexicalEnvironment() - fun resumeLexicalEnvironment() - fun endLexicalEnvironment(): Array? - fun hoistFunctionDeclaration(node: FunctionDeclaration) - fun hoistVariableDeclaration(node: Identifier) -} - -external interface TransformationContext : CoreTransformationContext { - fun requestEmitHelper(helper: ScopedEmitHelper) - fun requestEmitHelper(helper: UnscopedEmitHelper) - fun readEmitHelpers(): Array? - fun enableSubstitution(kind: SyntaxKind) - fun isSubstitutionEnabled(node: Node): Boolean - var onSubstituteNode: (hint: EmitHint, node: Node) -> Node - fun enableEmitNotification(kind: SyntaxKind) - fun isEmitNotificationEnabled(node: Node): Boolean - var onEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) -> Unit -} - -external interface TransformationResult { - var transformed: Array - var diagnostics: Array? - get() = definedExternally - set(value) = definedExternally - fun substituteNode(hint: EmitHint, node: Node): Node - fun emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) - val isEmitNotificationEnabled: ((node: Node) -> Boolean)? - fun dispose() -} - -external interface NodeVisitor { - @nativeInvoke - operator fun invoke(nodes: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T - @nativeInvoke - operator fun invoke(nodes: T, visitor: Visitor?): T - @nativeInvoke - operator fun invoke(nodes: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T - @nativeInvoke - operator fun invoke(nodes: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T? - @nativeInvoke - operator fun invoke(nodes: T?, visitor: Visitor?): T? - @nativeInvoke - operator fun invoke(nodes: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T? -} - -external interface NodesVisitor { - @nativeInvoke - operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray - @nativeInvoke - operator fun invoke(nodes: NodeArray, visitor: Visitor?): NodeArray - @nativeInvoke - operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray - @nativeInvoke - operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray - @nativeInvoke - operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray? - @nativeInvoke - operator fun invoke(nodes: NodeArray?, visitor: Visitor?): NodeArray? - @nativeInvoke - operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray? - @nativeInvoke - operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray? -} - -external interface Printer { - fun printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): String - fun printList(format: ListFormat, list: NodeArray, sourceFile: SourceFile): String - fun printFile(sourceFile: SourceFile): String - fun printBundle(bundle: Bundle): String -} - -external interface PrintHandlers { - val hasGlobalName: ((name: String) -> Boolean)? - val onEmitNode: ((hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) -> Unit)? - val isEmitNotificationEnabled: ((node: Node) -> Boolean)? - val substituteNode: ((hint: EmitHint, node: Node) -> Node)? -} - -external interface PrinterOptions { - var removeComments: Boolean? - get() = definedExternally - set(value) = definedExternally - var newLine: NewLineKind? - get() = definedExternally - set(value) = definedExternally - var omitTrailingSemicolon: Boolean? - get() = definedExternally - set(value) = definedExternally - var noEmitHelpers: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface GetEffectiveTypeRootsHost { - val directoryExists: ((directoryName: String) -> Boolean)? - val getCurrentDirectory: (() -> String)? -} - -external interface TextSpan { - var start: Number - var length: Number -} - -external interface TextChangeRange { - var span: TextSpan - var newLength: Number -} - -external interface SyntaxList : Node { - var _children: Array -} - -external enum class ListFormat { - None /* = 0 */, - SingleLine /* = 0 */, - MultiLine /* = 1 */, - PreserveLines /* = 2 */, - LinesMask /* = 3 */, - NotDelimited /* = 0 */, - BarDelimited /* = 4 */, - AmpersandDelimited /* = 8 */, - CommaDelimited /* = 16 */, - AsteriskDelimited /* = 32 */, - DelimitersMask /* = 60 */, - AllowTrailingComma /* = 64 */, - Indented /* = 128 */, - SpaceBetweenBraces /* = 256 */, - SpaceBetweenSiblings /* = 512 */, - Braces /* = 1024 */, - Parenthesis /* = 2048 */, - AngleBrackets /* = 4096 */, - SquareBrackets /* = 8192 */, - BracketsMask /* = 15360 */, - OptionalIfUndefined /* = 16384 */, - OptionalIfEmpty /* = 32768 */, - Optional /* = 49152 */, - PreferNewLine /* = 65536 */, - NoTrailingNewLine /* = 131072 */, - NoInterveningComments /* = 262144 */, - NoSpaceIfEmpty /* = 524288 */, - SingleElement /* = 1048576 */, - SpaceAfterList /* = 2097152 */, - Modifiers /* = 262656 */, - HeritageClauses /* = 512 */, - SingleLineTypeLiteralMembers /* = 768 */, - MultiLineTypeLiteralMembers /* = 32897 */, - SingleLineTupleTypeElements /* = 528 */, - MultiLineTupleTypeElements /* = 657 */, - UnionTypeConstituents /* = 516 */, - IntersectionTypeConstituents /* = 520 */, - ObjectBindingPatternElements /* = 525136 */, - ArrayBindingPatternElements /* = 524880 */, - ObjectLiteralExpressionProperties /* = 526226 */, - ArrayLiteralExpressionElements /* = 8914 */, - CommaListElements /* = 528 */, - CallExpressionArguments /* = 2576 */, - NewExpressionArguments /* = 18960 */, - TemplateExpressionSpans /* = 262144 */, - SingleLineBlockStatements /* = 768 */, - MultiLineBlockStatements /* = 129 */, - VariableDeclarationList /* = 528 */, - SingleLineFunctionBodyStatements /* = 768 */, - MultiLineFunctionBodyStatements /* = 1 */, - ClassHeritageClauses /* = 0 */, - ClassMembers /* = 129 */, - InterfaceMembers /* = 129 */, - EnumMembers /* = 145 */, - CaseBlockClauses /* = 129 */, - NamedImportsOrExportsElements /* = 525136 */, - JsxElementOrFragmentChildren /* = 262144 */, - JsxElementAttributes /* = 262656 */, - CaseOrDefaultClauseStatements /* = 163969 */, - HeritageClauseTypes /* = 528 */, - SourceFileStatements /* = 131073 */, - Decorators /* = 2146305 */, - TypeArguments /* = 53776 */, - TypeParameters /* = 53776 */, - Parameters /* = 2576 */, - IndexSignatureParameters /* = 8848 */, - JSDocComment /* = 33 */ -} - -external interface UserPreferences { - val disableSuggestions: Boolean? - get() = definedExternally - val quotePreference: String? /* "auto" | "double" | "single" */ - get() = definedExternally - val includeCompletionsForModuleExports: Boolean? - get() = definedExternally - val includeCompletionsForImportStatements: Boolean? - get() = definedExternally - val includeCompletionsWithSnippetText: Boolean? - get() = definedExternally - val includeAutomaticOptionalChainCompletions: Boolean? - get() = definedExternally - val includeCompletionsWithInsertText: Boolean? - get() = definedExternally - val allowIncompleteCompletions: Boolean? - get() = definedExternally - val importModuleSpecifierPreference: String? /* "shortest" | "project-relative" | "relative" | "non-relative" */ - get() = definedExternally - val importModuleSpecifierEnding: String? /* "auto" | "minimal" | "index" | "js" */ - get() = definedExternally - val allowTextChangesInNewFiles: Boolean? - get() = definedExternally - val providePrefixAndSuffixTextForRename: Boolean? - get() = definedExternally - val includePackageJsonAutoImports: String? /* "auto" | "on" | "off" */ - get() = definedExternally - val provideRefactorNotApplicableReason: Boolean? - get() = definedExternally -} - -external interface PseudoBigInt { - var negative: Boolean - var base10Value: String -} - -external enum class FileWatcherEventKind { - Created /* = 0 */, - Changed /* = 1 */, - Deleted /* = 2 */ -} - -external interface System { - var args: Array - var newLine: String - var useCaseSensitiveFileNames: Boolean - fun write(s: String) - val writeOutputIsTTY: (() -> Boolean)? - val getWidthOfTerminal: (() -> Number)? - fun readFile(path: String, encoding: String = definedExternally): String? - val getFileSize: ((path: String) -> Number)? - fun writeFile(path: String, data: String, writeByteOrderMark: Boolean = definedExternally) - val watchFile: ((path: String, callback: FileWatcherCallback, pollingInterval: Number, options: WatchOptions) -> FileWatcher)? - val watchDirectory: ((path: String, callback: DirectoryWatcherCallback, recursive: Boolean, options: WatchOptions) -> FileWatcher)? - fun resolvePath(path: String): String - fun fileExists(path: String): Boolean - fun directoryExists(path: String): Boolean - fun createDirectory(path: String) - fun getExecutingFilePath(): String - fun getCurrentDirectory(): String - fun getDirectories(path: String): Array - fun readDirectory(path: String, extensions: Array = definedExternally, exclude: Array = definedExternally, include: Array = definedExternally, depth: Number = definedExternally): Array - val getModifiedTime: ((path: String) -> Date?)? - val setModifiedTime: ((path: String, time: Date) -> Unit)? - val deleteFile: ((path: String) -> Unit)? - val createHash: ((data: String) -> String)? - val createSHA256Hash: ((data: String) -> String)? - val getMemoryUsage: (() -> Number)? - fun exit(exitCode: Number = definedExternally) - val realpath: ((path: String) -> String)? - val setTimeout: ((callback: (args: Any) -> Unit, ms: Number, args: Any) -> Any)? - val clearTimeout: ((timeoutId: Any) -> Unit)? - val clearScreen: (() -> Unit)? - val base64decode: ((input: String) -> String)? - val base64encode: ((input: String) -> String)? -} - -external interface FileWatcher { - fun close() -} - -external fun getNodeMajorVersion(): Number? - -external var sys: System - -external interface Scanner { - fun getStartPos(): Number - fun getToken(): SyntaxKind - fun getTextPos(): Number - fun getTokenPos(): Number - fun getTokenText(): String - fun getTokenValue(): String - fun hasUnicodeEscape(): Boolean - fun hasExtendedUnicodeEscape(): Boolean - fun hasPrecedingLineBreak(): Boolean - fun isIdentifier(): Boolean - fun isReservedWord(): Boolean - fun isUnterminated(): Boolean - fun reScanGreaterToken(): SyntaxKind - fun reScanSlashToken(): SyntaxKind - fun reScanAsteriskEqualsToken(): SyntaxKind - fun reScanTemplateToken(isTaggedTemplate: Boolean): SyntaxKind - fun reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind - fun scanJsxIdentifier(): SyntaxKind - fun scanJsxAttributeValue(): SyntaxKind - fun reScanJsxAttributeValue(): SyntaxKind - fun reScanJsxToken(allowMultilineJsxText: Boolean = definedExternally): dynamic /* SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken */ - fun reScanLessThanToken(): SyntaxKind - fun reScanHashToken(): SyntaxKind - fun reScanQuestionToken(): SyntaxKind - fun reScanInvalidIdentifier(): SyntaxKind - fun scanJsxToken(): dynamic /* SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken */ - fun scanJsDocToken(): dynamic /* SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.HashToken | SyntaxKind.Unknown | SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IntrinsicKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.OverrideKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword */ - fun scan(): SyntaxKind - fun getText(): String - fun setText(text: String?, start: Number = definedExternally, length: Number = definedExternally) - fun setOnError(onError: ErrorCallback?) - fun setScriptTarget(scriptTarget: ScriptTarget) - fun setLanguageVariant(variant: LanguageVariant) - fun setTextPos(textPos: Number) - fun lookAhead(callback: () -> T): T - fun scanRange(start: Number, length: Number, callback: () -> T): T - fun tryScan(callback: () -> T): T -} - -external fun tokenToString(t: SyntaxKind): String? - -external fun getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: Number, character: Number): Number - -external fun getLineAndCharacterOfPosition(sourceFile: SourceFileLike, position: Number): LineAndCharacter - -external fun isWhiteSpaceLike(ch: Number): Boolean - -external fun isWhiteSpaceSingleLine(ch: Number): Boolean - -external fun isLineBreak(ch: Number): Boolean - -external fun couldStartTrivia(text: String, pos: Number): Boolean - -external fun forEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean) -> U): U? - -external fun forEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T) -> U, state: T): U? - -external fun forEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean) -> U): U? - -external fun forEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T) -> U, state: T): U? - -external fun reduceEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T, memo: U) -> U, state: T, initial: U): U? - -external fun reduceEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T, memo: U) -> U, state: T, initial: U): U? - -external fun getLeadingCommentRanges(text: String, pos: Number): Array? - -external fun getTrailingCommentRanges(text: String, pos: Number): Array? - -external fun getShebang(text: String): String? - -external fun isIdentifierStart(ch: Number, languageVersion: ScriptTarget?): Boolean - -external fun isIdentifierPart(ch: Number, languageVersion: ScriptTarget?, identifierVariant: LanguageVariant = definedExternally): Boolean - -external fun createScanner(languageVersion: ScriptTarget, skipTrivia: Boolean, languageVariant: LanguageVariant = definedExternally, textInitial: String = definedExternally, onError: ErrorCallback = definedExternally, start: Number = definedExternally, length: Number = definedExternally): Scanner - -external fun isExternalModuleNameRelative(moduleName: String): Boolean - -external fun sortAndDeduplicateDiagnostics(diagnostics: Array): SortedReadonlyArray - -external fun getDefaultLibFileName(options: CompilerOptions): String - -external fun textSpanEnd(span: TextSpan): Number - -external fun textSpanIsEmpty(span: TextSpan): Boolean - -external fun textSpanContainsPosition(span: TextSpan, position: Number): Boolean - -external fun textSpanContainsTextSpan(span: TextSpan, other: TextSpan): Boolean - -external fun textSpanOverlapsWith(span: TextSpan, other: TextSpan): Boolean - -external fun textSpanOverlap(span1: TextSpan, span2: TextSpan): TextSpan? - -external fun textSpanIntersectsWithTextSpan(span: TextSpan, other: TextSpan): Boolean - -external fun textSpanIntersectsWith(span: TextSpan, start: Number, length: Number): Boolean - -external fun decodedTextSpanIntersectsWith(start1: Number, length1: Number, start2: Number, length2: Number): Boolean - -external fun textSpanIntersectsWithPosition(span: TextSpan, position: Number): Boolean - -external fun textSpanIntersection(span1: TextSpan, span2: TextSpan): TextSpan? - -external fun createTextSpan(start: Number, length: Number): TextSpan - -external fun createTextSpanFromBounds(start: Number, end: Number): TextSpan - -external fun textChangeRangeNewSpan(range: TextChangeRange): TextSpan - -external fun textChangeRangeIsUnchanged(range: TextChangeRange): Boolean - -external fun createTextChangeRange(span: TextSpan, newLength: Number): TextChangeRange - -external var unchangedTextChangeRange: TextChangeRange - -external fun collapseTextChangeRangesAcrossMultipleVersions(changes: Array): TextChangeRange - -external fun getTypeParameterOwner(d: Declaration): Declaration? - -external interface `T$23` { - var parent: ConstructorDeclaration - var name: Identifier -} - -external fun isParameterPropertyDeclaration(node: Node, parent: Node): Boolean - -external fun isEmptyBindingPattern(node: Identifier): Boolean - -external fun isEmptyBindingPattern(node: ObjectBindingPattern): Boolean - -external fun isEmptyBindingPattern(node: ArrayBindingPattern): Boolean - -external fun isEmptyBindingElement(node: BindingElement): Boolean - -external fun walkUpBindingElementsAndPatterns(binding: BindingElement): dynamic /* VariableDeclaration | ParameterDeclaration */ - -external fun getCombinedModifierFlags(node: Declaration): ModifierFlags - -external fun getCombinedNodeFlags(node: Node): NodeFlags - -external interface `T$24` { - fun getExecutingFilePath(): String - fun resolvePath(path: String): String - fun fileExists(fileName: String): Boolean - fun readFile(fileName: String): String? -} - -external fun validateLocaleAndSetLanguage(locale: String, sys: `T$24`, errors: Push = definedExternally) - -external fun getOriginalNode(node: Node): Node - -external fun getOriginalNode(node: Node, nodeTest: (node: Node) -> Boolean): T - -external fun getOriginalNode(node: Node?): Node? - -external fun getOriginalNode(node: Node?, nodeTest: (node: Node?) -> Boolean): T? - -external fun findAncestor(node: Node?, callback: (element: Node) -> Boolean): T? - -external fun findAncestor(node: Node?, callback: (element: Node) -> Any): Node? - -external fun isParseTreeNode(node: Node): Boolean - -external fun getParseTreeNode(node: Node?): Node? - -external fun getParseTreeNode(node: T?, nodeTest: (node: Node) -> Boolean = definedExternally): T? - -external fun getParseTreeNode(node: T?): T? - -external fun escapeLeadingUnderscores(identifier: String): dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - -external fun unescapeLeadingUnderscores(identifier: String /* String & `T$8` */): String - -external fun unescapeLeadingUnderscores(identifier: Unit /* Unit & `T$8` */): String - -external fun unescapeLeadingUnderscores(identifier: InternalSymbolName): String - -external fun idText(identifierOrPrivateName: Identifier): String - -external fun idText(identifierOrPrivateName: PrivateIdentifier): String - -external fun symbolName(symbol: Symbol): String - -external fun getNameOfJSDocTypedef(declaration: JSDocTypedefTag): dynamic /* Identifier? | PrivateIdentifier? */ - -external fun getNameOfDeclaration(declaration: Declaration?): dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ - -external fun getNameOfDeclaration(declaration: Expression?): dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ - -external fun getJSDocParameterTags(param: ParameterDeclaration): Array - -external fun getJSDocTypeParameterTags(param: TypeParameterDeclaration): Array - -external fun hasJSDocParameterTags(node: FunctionDeclaration): Boolean - -external fun hasJSDocParameterTags(node: MethodDeclaration): Boolean - -external fun hasJSDocParameterTags(node: GetAccessorDeclaration): Boolean - -external fun hasJSDocParameterTags(node: SetAccessorDeclaration): Boolean - -external fun hasJSDocParameterTags(node: ConstructorDeclaration): Boolean - -external fun hasJSDocParameterTags(node: FunctionExpression): Boolean - -external fun hasJSDocParameterTags(node: ArrowFunction): Boolean - -external fun hasJSDocParameterTags(node: CallSignatureDeclaration): Boolean - -external fun hasJSDocParameterTags(node: ConstructSignatureDeclaration): Boolean - -external fun hasJSDocParameterTags(node: MethodSignature): Boolean - -external fun hasJSDocParameterTags(node: IndexSignatureDeclaration): Boolean - -external fun hasJSDocParameterTags(node: FunctionTypeNode): Boolean - -external fun hasJSDocParameterTags(node: ConstructorTypeNode): Boolean - -external fun hasJSDocParameterTags(node: JSDocFunctionType): Boolean - -external fun getJSDocAugmentsTag(node: Node): JSDocAugmentsTag? - -external fun getJSDocImplementsTags(node: Node): Array - -external fun getJSDocClassTag(node: Node): JSDocClassTag? - -external fun getJSDocPublicTag(node: Node): JSDocPublicTag? - -external fun getJSDocPrivateTag(node: Node): JSDocPrivateTag? - -external fun getJSDocProtectedTag(node: Node): JSDocProtectedTag? - -external fun getJSDocReadonlyTag(node: Node): JSDocReadonlyTag? - -external fun getJSDocOverrideTagNoCache(node: Node): JSDocOverrideTag? - -external fun getJSDocDeprecatedTag(node: Node): JSDocDeprecatedTag? - -external fun getJSDocEnumTag(node: Node): JSDocEnumTag? - -external fun getJSDocThisTag(node: Node): JSDocThisTag? - -external fun getJSDocReturnTag(node: Node): JSDocReturnTag? - -external fun getJSDocTemplateTag(node: Node): JSDocTemplateTag? - -external fun getJSDocTypeTag(node: Node): JSDocTypeTag? - -external fun getJSDocType(node: Node): TypeNode? - -external fun getJSDocReturnType(node: Node): TypeNode? - -external fun getJSDocTags(node: Node): Array - -external fun getAllJSDocTags(node: Node, predicate: (tag: JSDocTag) -> Boolean): Array - -external fun getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): Array - -external fun getTextOfJSDocComment(comment: String = definedExternally): String? - -external fun getTextOfJSDocComment(): String? - -external fun getTextOfJSDocComment(comment: NodeArray = definedExternally): String? - -external fun getEffectiveTypeParameterDeclarations(node: Any /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature */): Array - -external fun getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode? - -external fun isMemberName(node: Node): Boolean - -external fun isPropertyAccessChain(node: Node): Boolean - -external fun isElementAccessChain(node: Node): Boolean - -external fun isCallChain(node: Node): Boolean - -external fun isOptionalChain(node: Node): Boolean - -external fun isNullishCoalesce(node: Node): Boolean - -external fun isConstTypeReference(node: Node): Boolean - -external fun skipPartiallyEmittedExpressions(node: Expression): Expression - -external fun skipPartiallyEmittedExpressions(node: Node): Node - -external fun isNonNullChain(node: Node): Boolean - -external fun isBreakOrContinueStatement(node: Node): Boolean - -external fun isNamedExportBindings(node: Node): Boolean - -external fun isUnparsedTextLike(node: Node): Boolean - -external fun isUnparsedNode(node: Node): Boolean - -external fun isJSDocPropertyLikeTag(node: Node): Boolean - -external fun isTokenKind(kind: SyntaxKind): Boolean - -external fun isToken(n: Node): Boolean - -external fun isLiteralExpression(node: Node): Boolean - -external fun isTemplateLiteralToken(node: Node): Boolean - -external fun isTemplateMiddleOrTemplateTail(node: Node): Boolean - -external fun isImportOrExportSpecifier(node: Node): Boolean - -external fun isTypeOnlyImportOrExportDeclaration(node: Node): Boolean - -external fun isStringTextContainingNode(node: Node): Boolean - -external fun isModifier(node: Node): Boolean - -external fun isEntityName(node: Node): Boolean - -external fun isPropertyName(node: Node): Boolean - -external fun isBindingName(node: Node): Boolean - -external fun isFunctionLike(node: Node?): Boolean - -external fun isClassElement(node: Node): Boolean - -external fun isClassLike(node: Node): Boolean - -external fun isAccessor(node: Node): Boolean - -external fun isTypeElement(node: Node): Boolean - -external fun isClassOrTypeElement(node: Node): Boolean - -external fun isObjectLiteralElementLike(node: Node): Boolean - -external fun isTypeNode(node: Node): Boolean - -external fun isFunctionOrConstructorTypeNode(node: Node): Boolean - -external fun isPropertyAccessOrQualifiedName(node: Node): Boolean - -external fun isCallLikeExpression(node: Node): Boolean - -external fun isCallOrNewExpression(node: Node): Boolean - -external fun isTemplateLiteral(node: Node): Boolean - -external fun isAssertionExpression(node: Node): Boolean - -external fun isIterationStatement(node: Node, lookInLabeledStatements: Boolean): Boolean - -external fun isJsxOpeningLikeElement(node: Node): Boolean - -external fun isCaseOrDefaultClause(node: Node): Boolean - -external fun isJSDocCommentContainingNode(node: Node): Boolean - -external fun isSetAccessor(node: Node): Boolean - -external fun isGetAccessor(node: Node): Boolean - -external fun hasOnlyExpressionInitializer(node: Node): Boolean - -external fun isObjectLiteralElement(node: Node): Boolean - -external fun isStringLiteralLike(node: Node): Boolean - -external fun isJSDocLinkLike(node: Node): Boolean - -external var factory: NodeFactory - -external fun createUnparsedSourceFile(text: String): UnparsedSource - -external fun createUnparsedSourceFile(inputFile: InputFiles, type: String /* "js" | "dts" */, stripInternal: Boolean = definedExternally): UnparsedSource - -external fun createUnparsedSourceFile(inputFile: InputFiles, type: String /* "js" | "dts" */): UnparsedSource - -external fun createUnparsedSourceFile(text: String, mapPath: String?, map: String?): UnparsedSource - -external fun createInputFiles(javascriptText: String, declarationText: String): InputFiles - -external fun createInputFiles(readFileText: (path: String) -> String?, javascriptPath: String, javascriptMapPath: String?, declarationPath: String, declarationMapPath: String?, buildInfoPath: String?): InputFiles - -external fun createInputFiles(javascriptText: String, declarationText: String, javascriptMapPath: String?, javascriptMapText: String?, declarationMapPath: String?, declarationMapText: String?): InputFiles - -external fun createSourceMapSource(fileName: String, text: String, skipTrivia: (pos: Number) -> Number = definedExternally): SourceMapSource - -external fun setOriginalNode(node: T, original: Node?): T - -external fun disposeEmitNodes(sourceFile: SourceFile?) - -external fun setEmitFlags(node: T, emitFlags: EmitFlags): T - -external fun getSourceMapRange(node: Node): SourceMapRange - -external fun setSourceMapRange(node: T, range: SourceMapRange?): T - -external fun getTokenSourceMapRange(node: Node, token: SyntaxKind): SourceMapRange? - -external fun setTokenSourceMapRange(node: T, token: SyntaxKind, range: SourceMapRange?): T - -external fun getCommentRange(node: Node): TextRange - -external fun setCommentRange(node: T, range: TextRange): T - -external fun getSyntheticLeadingComments(node: Node): Array? - -external fun setSyntheticLeadingComments(node: T, comments: Array?): T - -external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T - -external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String): T - -external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T - -external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String): T - -external fun getSyntheticTrailingComments(node: Node): Array? - -external fun setSyntheticTrailingComments(node: T, comments: Array?): T - -external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T - -external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String): T - -external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T - -external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String): T - -external fun moveSyntheticComments(node: T, original: Node): T - -external fun getConstantValue(node: PropertyAccessExpression): dynamic /* String? | Number? */ - -external fun getConstantValue(node: ElementAccessExpression): dynamic /* String? | Number? */ - -external fun setConstantValue(node: PropertyAccessExpression, value: String): dynamic /* PropertyAccessExpression | ElementAccessExpression */ - -external fun setConstantValue(node: PropertyAccessExpression, value: Number): dynamic /* PropertyAccessExpression | ElementAccessExpression */ - -external fun setConstantValue(node: ElementAccessExpression, value: String): dynamic /* PropertyAccessExpression | ElementAccessExpression */ - -external fun setConstantValue(node: ElementAccessExpression, value: Number): dynamic /* PropertyAccessExpression | ElementAccessExpression */ - -external fun addEmitHelper(node: T, helper: ScopedEmitHelper): T - -external fun addEmitHelper(node: T, helper: UnscopedEmitHelper): T - -external fun addEmitHelpers(node: T, helpers: Array?): T - -external fun removeEmitHelper(node: Node, helper: ScopedEmitHelper): Boolean - -external fun removeEmitHelper(node: Node, helper: UnscopedEmitHelper): Boolean - -external fun getEmitHelpers(node: Node): Array? - -external fun moveEmitHelpers(source: Node, target: Node, predicate: (helper: Any /* ScopedEmitHelper | UnscopedEmitHelper */) -> Boolean) - -external fun isNumericLiteral(node: Node): Boolean - -external fun isBigIntLiteral(node: Node): Boolean - -external fun isStringLiteral(node: Node): Boolean - -external fun isJsxText(node: Node): Boolean - -external fun isRegularExpressionLiteral(node: Node): Boolean - -external fun isNoSubstitutionTemplateLiteral(node: Node): Boolean - -external fun isTemplateHead(node: Node): Boolean - -external fun isTemplateMiddle(node: Node): Boolean - -external fun isTemplateTail(node: Node): Boolean - -external fun isDotDotDotToken(node: Node): Boolean - -external fun isPlusToken(node: Node): Boolean - -external fun isMinusToken(node: Node): Boolean - -external fun isAsteriskToken(node: Node): Boolean - -external fun isIdentifier(node: Node): Boolean - -external fun isPrivateIdentifier(node: Node): Boolean - -external fun isQualifiedName(node: Node): Boolean - -external fun isComputedPropertyName(node: Node): Boolean - -external fun isTypeParameterDeclaration(node: Node): Boolean - -external fun isParameter(node: Node): Boolean - -external fun isDecorator(node: Node): Boolean - -external fun isPropertySignature(node: Node): Boolean - -external fun isPropertyDeclaration(node: Node): Boolean - -external fun isMethodSignature(node: Node): Boolean - -external fun isMethodDeclaration(node: Node): Boolean - -external fun isClassStaticBlockDeclaration(node: Node): Boolean - -external fun isConstructorDeclaration(node: Node): Boolean - -external fun isGetAccessorDeclaration(node: Node): Boolean - -external fun isSetAccessorDeclaration(node: Node): Boolean - -external fun isCallSignatureDeclaration(node: Node): Boolean - -external fun isConstructSignatureDeclaration(node: Node): Boolean - -external fun isIndexSignatureDeclaration(node: Node): Boolean - -external fun isTypePredicateNode(node: Node): Boolean - -external fun isTypeReferenceNode(node: Node): Boolean - -external fun isFunctionTypeNode(node: Node): Boolean - -external fun isConstructorTypeNode(node: Node): Boolean - -external fun isTypeQueryNode(node: Node): Boolean - -external fun isTypeLiteralNode(node: Node): Boolean - -external fun isArrayTypeNode(node: Node): Boolean - -external fun isTupleTypeNode(node: Node): Boolean - -external fun isNamedTupleMember(node: Node): Boolean - -external fun isOptionalTypeNode(node: Node): Boolean - -external fun isRestTypeNode(node: Node): Boolean - -external fun isUnionTypeNode(node: Node): Boolean - -external fun isIntersectionTypeNode(node: Node): Boolean - -external fun isConditionalTypeNode(node: Node): Boolean - -external fun isInferTypeNode(node: Node): Boolean - -external fun isParenthesizedTypeNode(node: Node): Boolean - -external fun isThisTypeNode(node: Node): Boolean - -external fun isTypeOperatorNode(node: Node): Boolean - -external fun isIndexedAccessTypeNode(node: Node): Boolean - -external fun isMappedTypeNode(node: Node): Boolean - -external fun isLiteralTypeNode(node: Node): Boolean - -external fun isImportTypeNode(node: Node): Boolean - -external fun isTemplateLiteralTypeSpan(node: Node): Boolean - -external fun isTemplateLiteralTypeNode(node: Node): Boolean - -external fun isObjectBindingPattern(node: Node): Boolean - -external fun isArrayBindingPattern(node: Node): Boolean - -external fun isBindingElement(node: Node): Boolean - -external fun isArrayLiteralExpression(node: Node): Boolean - -external fun isObjectLiteralExpression(node: Node): Boolean - -external fun isPropertyAccessExpression(node: Node): Boolean - -external fun isElementAccessExpression(node: Node): Boolean - -external fun isCallExpression(node: Node): Boolean - -external fun isNewExpression(node: Node): Boolean - -external fun isTaggedTemplateExpression(node: Node): Boolean - -external fun isTypeAssertionExpression(node: Node): Boolean - -external fun isParenthesizedExpression(node: Node): Boolean - -external fun isFunctionExpression(node: Node): Boolean - -external fun isArrowFunction(node: Node): Boolean - -external fun isDeleteExpression(node: Node): Boolean - -external fun isTypeOfExpression(node: Node): Boolean - -external fun isVoidExpression(node: Node): Boolean - -external fun isAwaitExpression(node: Node): Boolean - -external fun isPrefixUnaryExpression(node: Node): Boolean - -external fun isPostfixUnaryExpression(node: Node): Boolean - -external fun isBinaryExpression(node: Node): Boolean - -external fun isConditionalExpression(node: Node): Boolean - -external fun isTemplateExpression(node: Node): Boolean - -external fun isYieldExpression(node: Node): Boolean - -external fun isSpreadElement(node: Node): Boolean - -external fun isClassExpression(node: Node): Boolean - -external fun isOmittedExpression(node: Node): Boolean - -external fun isExpressionWithTypeArguments(node: Node): Boolean - -external fun isAsExpression(node: Node): Boolean - -external fun isNonNullExpression(node: Node): Boolean - -external fun isMetaProperty(node: Node): Boolean - -external fun isSyntheticExpression(node: Node): Boolean - -external fun isPartiallyEmittedExpression(node: Node): Boolean - -external fun isCommaListExpression(node: Node): Boolean - -external fun isTemplateSpan(node: Node): Boolean - -external fun isSemicolonClassElement(node: Node): Boolean - -external fun isBlock(node: Node): Boolean - -external fun isVariableStatement(node: Node): Boolean - -external fun isEmptyStatement(node: Node): Boolean - -external fun isExpressionStatement(node: Node): Boolean - -external fun isIfStatement(node: Node): Boolean - -external fun isDoStatement(node: Node): Boolean - -external fun isWhileStatement(node: Node): Boolean - -external fun isForStatement(node: Node): Boolean - -external fun isForInStatement(node: Node): Boolean - -external fun isForOfStatement(node: Node): Boolean - -external fun isContinueStatement(node: Node): Boolean - -external fun isBreakStatement(node: Node): Boolean - -external fun isReturnStatement(node: Node): Boolean - -external fun isWithStatement(node: Node): Boolean - -external fun isSwitchStatement(node: Node): Boolean - -external fun isLabeledStatement(node: Node): Boolean - -external fun isThrowStatement(node: Node): Boolean - -external fun isTryStatement(node: Node): Boolean - -external fun isDebuggerStatement(node: Node): Boolean - -external fun isVariableDeclaration(node: Node): Boolean - -external fun isVariableDeclarationList(node: Node): Boolean - -external fun isFunctionDeclaration(node: Node): Boolean - -external fun isClassDeclaration(node: Node): Boolean - -external fun isInterfaceDeclaration(node: Node): Boolean - -external fun isTypeAliasDeclaration(node: Node): Boolean - -external fun isEnumDeclaration(node: Node): Boolean - -external fun isModuleDeclaration(node: Node): Boolean - -external fun isModuleBlock(node: Node): Boolean - -external fun isCaseBlock(node: Node): Boolean - -external fun isNamespaceExportDeclaration(node: Node): Boolean - -external fun isImportEqualsDeclaration(node: Node): Boolean - -external fun isImportDeclaration(node: Node): Boolean - -external fun isImportClause(node: Node): Boolean - -external fun isNamespaceImport(node: Node): Boolean - -external fun isNamespaceExport(node: Node): Boolean - -external fun isNamedImports(node: Node): Boolean - -external fun isImportSpecifier(node: Node): Boolean - -external fun isExportAssignment(node: Node): Boolean - -external fun isExportDeclaration(node: Node): Boolean - -external fun isNamedExports(node: Node): Boolean - -external fun isExportSpecifier(node: Node): Boolean - -external fun isMissingDeclaration(node: Node): Boolean - -external fun isNotEmittedStatement(node: Node): Boolean - -external fun isExternalModuleReference(node: Node): Boolean - -external fun isJsxElement(node: Node): Boolean - -external fun isJsxSelfClosingElement(node: Node): Boolean - -external fun isJsxOpeningElement(node: Node): Boolean - -external fun isJsxClosingElement(node: Node): Boolean - -external fun isJsxFragment(node: Node): Boolean - -external fun isJsxOpeningFragment(node: Node): Boolean - -external fun isJsxClosingFragment(node: Node): Boolean - -external fun isJsxAttribute(node: Node): Boolean - -external fun isJsxAttributes(node: Node): Boolean - -external fun isJsxSpreadAttribute(node: Node): Boolean - -external fun isJsxExpression(node: Node): Boolean - -external fun isCaseClause(node: Node): Boolean - -external fun isDefaultClause(node: Node): Boolean - -external fun isHeritageClause(node: Node): Boolean - -external fun isCatchClause(node: Node): Boolean - -external fun isPropertyAssignment(node: Node): Boolean - -external fun isShorthandPropertyAssignment(node: Node): Boolean - -external fun isSpreadAssignment(node: Node): Boolean - -external fun isEnumMember(node: Node): Boolean - -external fun isUnparsedPrepend(node: Node): Boolean - -external fun isSourceFile(node: Node): Boolean - -external fun isBundle(node: Node): Boolean - -external fun isUnparsedSource(node: Node): Boolean - -external fun isJSDocTypeExpression(node: Node): Boolean - -external fun isJSDocNameReference(node: Node): Boolean - -external fun isJSDocMemberName(node: Node): Boolean - -external fun isJSDocLink(node: Node): Boolean - -external fun isJSDocLinkCode(node: Node): Boolean - -external fun isJSDocLinkPlain(node: Node): Boolean - -external fun isJSDocAllType(node: Node): Boolean - -external fun isJSDocUnknownType(node: Node): Boolean - -external fun isJSDocNullableType(node: Node): Boolean - -external fun isJSDocNonNullableType(node: Node): Boolean - -external fun isJSDocOptionalType(node: Node): Boolean - -external fun isJSDocFunctionType(node: Node): Boolean - -external fun isJSDocVariadicType(node: Node): Boolean - -external fun isJSDocNamepathType(node: Node): Boolean - -external fun isJSDoc(node: Node): Boolean - -external fun isJSDocTypeLiteral(node: Node): Boolean - -external fun isJSDocSignature(node: Node): Boolean - -external fun isJSDocAugmentsTag(node: Node): Boolean - -external fun isJSDocAuthorTag(node: Node): Boolean - -external fun isJSDocClassTag(node: Node): Boolean - -external fun isJSDocCallbackTag(node: Node): Boolean - -external fun isJSDocPublicTag(node: Node): Boolean - -external fun isJSDocPrivateTag(node: Node): Boolean - -external fun isJSDocProtectedTag(node: Node): Boolean - -external fun isJSDocReadonlyTag(node: Node): Boolean - -external fun isJSDocOverrideTag(node: Node): Boolean - -external fun isJSDocDeprecatedTag(node: Node): Boolean - -external fun isJSDocSeeTag(node: Node): Boolean - -external fun isJSDocEnumTag(node: Node): Boolean - -external fun isJSDocParameterTag(node: Node): Boolean - -external fun isJSDocReturnTag(node: Node): Boolean - -external fun isJSDocThisTag(node: Node): Boolean - -external fun isJSDocTypeTag(node: Node): Boolean - -external fun isJSDocTemplateTag(node: Node): Boolean - -external fun isJSDocTypedefTag(node: Node): Boolean - -external fun isJSDocUnknownTag(node: Node): Boolean - -external fun isJSDocPropertyTag(node: Node): Boolean - -external fun isJSDocImplementsTag(node: Node): Boolean - -external fun setTextRange(range: T, location: TextRange?): T - -external fun forEachChild(node: Node, cbNode: (node: Node) -> T?, cbNodes: (nodes: NodeArray) -> T? = definedExternally): T? - -external fun createSourceFile(fileName: String, sourceText: String, languageVersion: ScriptTarget, setParentNodes: Boolean = definedExternally, scriptKind: ScriptKind = definedExternally): SourceFile - -external fun parseIsolatedEntityName(text: String, languageVersion: ScriptTarget): dynamic /* Identifier? | QualifiedName? */ - -external fun parseJsonText(fileName: String, sourceText: String): JsonSourceFile - -external fun isExternalModule(file: SourceFile): Boolean - -external fun updateSourceFile(sourceFile: SourceFile, newText: String, textChangeRange: TextChangeRange, aggressiveChecks: Boolean = definedExternally): SourceFile - -external fun parseCommandLine(commandLine: Array, readFile: (path: String) -> String? = definedExternally): ParsedCommandLine - -external interface ConfigFileDiagnosticsReporter { - var onUnRecoverableConfigFileDiagnostic: DiagnosticReporter -} - -external interface ParseConfigFileHost : ParseConfigHost, ConfigFileDiagnosticsReporter { - fun getCurrentDirectory(): String -} - -external fun getParsedCommandLineOfConfigFile(configFileName: String, optionsToExtend: CompilerOptions?, host: ParseConfigFileHost, extendedConfigCache: Map = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): ParsedCommandLine? - -external interface `T$25` { - var config: Any? - get() = definedExternally - set(value) = definedExternally - var error: Diagnostic? - get() = definedExternally - set(value) = definedExternally -} - -external fun readConfigFile(fileName: String, readFile: (path: String) -> String?): `T$25` - -external fun parseConfigFileTextToJson(fileName: String, jsonText: String): `T$25` - -external fun readJsonConfigFile(fileName: String, readFile: (path: String) -> String?): TsConfigSourceFile - -external fun convertToObject(sourceFile: JsonSourceFile, errors: Push): Any - -external fun parseJsonConfigFileContent(json: Any, host: ParseConfigHost, basePath: String, existingOptions: CompilerOptions = definedExternally, configFileName: String = definedExternally, resolutionStack: Array = definedExternally, extraFileExtensions: Array = definedExternally, extendedConfigCache: Map = definedExternally, existingWatchOptions: WatchOptions = definedExternally): ParsedCommandLine - -external fun parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: String, existingOptions: CompilerOptions = definedExternally, configFileName: String = definedExternally, resolutionStack: Array = definedExternally, extraFileExtensions: Array = definedExternally, extendedConfigCache: Map = definedExternally, existingWatchOptions: WatchOptions = definedExternally): ParsedCommandLine - -external interface ParsedTsconfig { - var raw: Any - var options: CompilerOptions? - get() = definedExternally - set(value) = definedExternally - var watchOptions: WatchOptions? - get() = definedExternally - set(value) = definedExternally - var typeAcquisition: TypeAcquisition? - get() = definedExternally - set(value) = definedExternally - var extendedConfigPath: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface ExtendedConfigCacheEntry { - var extendedResult: TsConfigSourceFile - var extendedConfig: ParsedTsconfig? -} - -external interface `T$26` { - var options: CompilerOptions - var errors: Array -} - -external fun convertCompilerOptionsFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$26` - -external interface `T$27` { - var options: TypeAcquisition - var errors: Array -} - -external fun convertTypeAcquisitionFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$27` - -external fun getEffectiveTypeRoots(options: CompilerOptions, host: GetEffectiveTypeRootsHost): Array? - -external fun resolveTypeReferenceDirective(typeReferenceDirectiveName: String, containingFile: String?, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference: ResolvedProjectReference = definedExternally, cache: TypeReferenceDirectiveResolutionCache = definedExternally): ResolvedTypeReferenceDirectiveWithFailedLookupLocations - -external fun getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): Array - -external interface TypeReferenceDirectiveResolutionCache : PerDirectoryResolutionCache, PackageJsonInfoCache - -external interface PerDirectoryResolutionCache { - fun getOrCreateCacheForDirectory(directoryName: String, redirectedReference: ResolvedProjectReference = definedExternally): Map - fun clear() - fun update(options: CompilerOptions) -} - -external interface ModuleResolutionCache : PerDirectoryResolutionCache, NonRelativeModuleNameResolutionCache, PackageJsonInfoCache { - fun getPackageJsonInfoCache(): PackageJsonInfoCache -} - -external interface NonRelativeModuleNameResolutionCache : PackageJsonInfoCache { - fun getOrCreateCacheForModuleName(nonRelativeModuleName: String, redirectedReference: ResolvedProjectReference = definedExternally): PerModuleNameCache -} - -external interface PackageJsonInfoCache { - fun clear() -} - -external interface PerModuleNameCache { - fun get(directory: String): ResolvedModuleWithFailedLookupLocations? - fun set(directory: String, result: ResolvedModuleWithFailedLookupLocations) -} - -external fun createModuleResolutionCache(currentDirectory: String, getCanonicalFileName: (s: String) -> String, options: CompilerOptions = definedExternally): ModuleResolutionCache - -external fun createTypeReferenceDirectiveResolutionCache(currentDirectory: String, getCanonicalFileName: (s: String) -> String, options: CompilerOptions = definedExternally, packageJsonInfoCache: PackageJsonInfoCache = definedExternally): TypeReferenceDirectiveResolutionCache - -external fun resolveModuleNameFromCache(moduleName: String, containingFile: String, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations? - -external fun resolveModuleName(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations - -external fun nodeModuleNameResolver(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations - -external fun classicNameResolver(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: NonRelativeModuleNameResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations - -external fun visitNode(node: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T - -external fun visitNode(node: T, visitor: Visitor?): T - -external fun visitNode(node: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T - -external fun visitNode(node: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T? - -external fun visitNode(node: T?, visitor: Visitor?): T? - -external fun visitNode(node: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T? - -external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray - -external fun visitNodes(nodes: NodeArray, visitor: Visitor?): NodeArray - -external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray - -external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray - -external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray? - -external fun visitNodes(nodes: NodeArray?, visitor: Visitor?): NodeArray? - -external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray? - -external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray? - -external fun visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start: Number = definedExternally, ensureUseStrict: Boolean = definedExternally, nodesVisitor: NodesVisitor = definedExternally): NodeArray - -external fun visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor = definedExternally): NodeArray - -external fun visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext): NodeArray - -external fun visitParameterList(nodes: NodeArray?, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor = definedExternally): NodeArray? - -external fun visitParameterList(nodes: NodeArray?, visitor: Visitor, context: TransformationContext): NodeArray? - -external fun visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): dynamic /* FunctionBody */ - -external fun visitFunctionBody(node: Expression, visitor: Visitor, context: TransformationContext): dynamic /* FunctionBody | Expression */ - -external fun visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement - -external fun visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T - -external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext, nodesVisitor: Any = definedExternally, tokenVisitor: Visitor = definedExternally): T? - -external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext): T? - -external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext, nodesVisitor: Any = definedExternally): T? - -external fun getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): String? - -external fun getOutputFileNames(commandLine: ParsedCommandLine, inputFileName: String, ignoreCase: Boolean): Array - -external fun createPrinter(printerOptions: PrinterOptions = definedExternally, handlers: PrintHandlers = definedExternally): Printer - -external fun findConfigFile(searchPath: String, fileExists: (fileName: String) -> Boolean, configName: String = definedExternally): String? - -external fun resolveTripleslashReference(moduleName: String, containingFile: String): String - -external fun createCompilerHost(options: CompilerOptions, setParentNodes: Boolean = definedExternally): CompilerHost - -external fun getPreEmitDiagnostics(program: Program, sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - -external interface FormatDiagnosticsHost { - fun getCurrentDirectory(): String - fun getCanonicalFileName(fileName: String): String - fun getNewLine(): String -} - -external fun formatDiagnostics(diagnostics: Array, host: FormatDiagnosticsHost): String - -external fun formatDiagnostic(diagnostic: Diagnostic, host: FormatDiagnosticsHost): String - -external fun formatDiagnosticsWithColorAndContext(diagnostics: Array, host: FormatDiagnosticsHost): String - -external fun flattenDiagnosticMessageText(diag: String?, newLine: String, indent: Number = definedExternally): String - -external fun flattenDiagnosticMessageText(diag: String?, newLine: String): String - -external fun flattenDiagnosticMessageText(diag: DiagnosticMessageChain?, newLine: String, indent: Number = definedExternally): String - -external fun flattenDiagnosticMessageText(diag: DiagnosticMessageChain?, newLine: String): String - -external fun getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): Array - -external fun createProgram(createProgramOptions: CreateProgramOptions): Program - -external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally, oldProgram: Program = definedExternally, configFileParsingDiagnostics: Array = definedExternally): Program - -external fun createProgram(rootNames: Array, options: CompilerOptions): Program - -external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally): Program - -external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally, oldProgram: Program = definedExternally): Program - -external interface ResolveProjectReferencePathHost { - fun fileExists(fileName: String): Boolean -} - -external fun resolveProjectReferencePath(ref: ProjectReference): String /* String & `T$5` */ - -external fun resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): String /* String & `T$5` */ - -external interface EmitOutput { - var outputFiles: Array - var emitSkipped: Boolean -} - -external interface OutputFile { - var name: String - var writeByteOrderMark: Boolean - var text: String -} - -external interface `T$28` { - var result: T - var affected: dynamic /* SourceFile | Program */ - get() = definedExternally - set(value) = definedExternally -} - -external interface BuilderProgramHost { - fun useCaseSensitiveFileNames(): Boolean - var createHash: ((data: String) -> String)? - get() = definedExternally - set(value) = definedExternally - var writeFile: WriteFileCallback? - get() = definedExternally - set(value) = definedExternally -} - -external interface BuilderProgram { - fun getProgram(): Program - fun getCompilerOptions(): CompilerOptions - fun getSourceFile(fileName: String): SourceFile? - fun getSourceFiles(): Array - fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getConfigFileParsingDiagnostics(): Array - fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getDeclarationDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getAllDependencies(sourceFile: SourceFile): Array - fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult - fun getCurrentDirectory(): String -} - -external interface SemanticDiagnosticsBuilderProgram : BuilderProgram { - fun getSemanticDiagnosticsOfNextAffectedFile(cancellationToken: CancellationToken = definedExternally, ignoreSourceFile: (sourceFile: SourceFile) -> Boolean = definedExternally): `T$28`>? -} - -external interface EmitAndSemanticDiagnosticsBuilderProgram : SemanticDiagnosticsBuilderProgram { - fun emitNextAffectedFile(writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): `T$28`? -} - -external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): BuilderProgram - -external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost): BuilderProgram - -external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram: BuilderProgram = definedExternally): BuilderProgram - -external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): BuilderProgram - -external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?): BuilderProgram - -external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): BuilderProgram - -external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally): BuilderProgram - -external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): BuilderProgram - -external interface ReadBuildProgramHost { - fun useCaseSensitiveFileNames(): Boolean - fun getCurrentDirectory(): String - fun readFile(fileName: String): String? -} - -external fun readBuilderProgram(compilerOptions: CompilerOptions, host: ReadBuildProgramHost): EmitAndSemanticDiagnosticsBuilderProgram? - -external fun createIncrementalCompilerHost(options: CompilerOptions, system: System = definedExternally): CompilerHost - -external interface IncrementalProgramOptions { - var rootNames: Array - var options: CompilerOptions - var configFileParsingDiagnostics: Array? - get() = definedExternally - set(value) = definedExternally - var projectReferences: Array? - get() = definedExternally - set(value) = definedExternally - var host: CompilerHost? - get() = definedExternally - set(value) = definedExternally - var createProgram: CreateProgram? - get() = definedExternally - set(value) = definedExternally -} - -external fun createIncrementalProgram(__0: IncrementalProgramOptions): T - -external interface WatchHost { - val onWatchStatusChange: ((diagnostic: Diagnostic, newLine: String, options: CompilerOptions, errorCount: Number) -> Unit)? - fun watchFile(path: String, callback: FileWatcherCallback, pollingInterval: Number = definedExternally, options: CompilerOptions = definedExternally): FileWatcher - fun watchDirectory(path: String, callback: DirectoryWatcherCallback, recursive: Boolean = definedExternally, options: CompilerOptions = definedExternally): FileWatcher - val setTimeout: ((callback: (args: Any) -> Unit, ms: Number, args: Any) -> Any)? - val clearTimeout: ((timeoutId: Any) -> Unit)? -} - -external interface ProgramHost { - var createProgram: CreateProgram - fun useCaseSensitiveFileNames(): Boolean - fun getNewLine(): String - fun getCurrentDirectory(): String - fun getDefaultLibFileName(options: CompilerOptions): String - val getDefaultLibLocation: (() -> String)? - val createHash: ((data: String) -> String)? - fun fileExists(path: String): Boolean - fun readFile(path: String, encoding: String = definedExternally): String? - val directoryExists: ((path: String) -> Boolean)? - val getDirectories: ((path: String) -> Array)? - val readDirectory: ((path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array)? - val realpath: ((path: String) -> String)? - val trace: ((s: String) -> Unit)? - val getEnvironmentVariable: ((name: String) -> String?)? - val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? -} - -external interface WatchCompilerHost : ProgramHost, WatchHost { - val useSourceOfProjectReferenceRedirect: (() -> Boolean)? - val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? - val afterProgramCreate: ((program: T) -> Unit)? -} - -external interface WatchCompilerHostOfFilesAndCompilerOptions : WatchCompilerHost { - var rootFiles: Array - var options: CompilerOptions - var watchOptions: WatchOptions? - get() = definedExternally - set(value) = definedExternally - var projectReferences: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface WatchCompilerHostOfConfigFile : WatchCompilerHost, ConfigFileDiagnosticsReporter { - var configFileName: String - var optionsToExtend: CompilerOptions? - get() = definedExternally - set(value) = definedExternally - var watchOptionsToExtend: WatchOptions? - get() = definedExternally - set(value) = definedExternally - var extraFileExtensions: Array? - get() = definedExternally - set(value) = definedExternally - override var readDirectory: (path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array -} - -external interface Watch { - fun getProgram(): T - fun close() -} - -external interface WatchOfConfigFile : Watch - -external interface WatchOfFilesAndCompilerOptions : Watch { - fun updateRootFileNames(fileNames: Array) -} - -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, projectReferences: Array = definedExternally, watchOptions: WatchOptions = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, projectReferences: Array = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchProgram(host: WatchCompilerHostOfFilesAndCompilerOptions): WatchOfFilesAndCompilerOptions - -external fun createWatchProgram(host: WatchCompilerHostOfConfigFile): WatchOfConfigFile - -external interface BuildOptions { - var dry: Boolean? - get() = definedExternally - set(value) = definedExternally - var force: Boolean? - get() = definedExternally - set(value) = definedExternally - var verbose: Boolean? - get() = definedExternally - set(value) = definedExternally - var incremental: Boolean? - get() = definedExternally - set(value) = definedExternally - var assumeChangesOnlyAffectDirectDependencies: Boolean? - get() = definedExternally - set(value) = definedExternally - var traceResolution: Boolean? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ - @nativeSetter - operator fun set(option: String, value: String?) - @nativeSetter - operator fun set(option: String, value: Number?) - @nativeSetter - operator fun set(option: String, value: Boolean?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: MapLike>?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) -} - -external interface SolutionBuilderHostBase : ProgramHost { - val createDirectory: ((path: String) -> Unit)? - val writeFile: ((path: String, data: String, writeByteOrderMark: Boolean) -> Unit)? - var getCustomTransformers: ((project: String) -> CustomTransformers?)? - get() = definedExternally - set(value) = definedExternally - fun getModifiedTime(fileName: String): Date? - fun setModifiedTime(fileName: String, date: Date) - fun deleteFile(fileName: String) - val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? - var reportDiagnostic: DiagnosticReporter - var reportSolutionBuilderStatus: DiagnosticReporter - val afterProgramEmitAndDiagnostics: ((program: T) -> Unit)? -} - -external interface SolutionBuilderHost : SolutionBuilderHostBase { - var reportErrorSummary: ReportEmitErrorSummary? - get() = definedExternally - set(value) = definedExternally -} - -external interface SolutionBuilderWithWatchHost : SolutionBuilderHostBase, WatchHost - -external interface SolutionBuilder { - fun build(project: String = definedExternally, cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, getCustomTransformers: (project: String) -> CustomTransformers = definedExternally): ExitStatus - fun clean(project: String = definedExternally): ExitStatus - fun buildReferences(project: String, cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, getCustomTransformers: (project: String) -> CustomTransformers = definedExternally): ExitStatus - fun cleanReferences(project: String = definedExternally): ExitStatus - fun getNextInvalidatedProject(cancellationToken: CancellationToken = definedExternally): dynamic /* UpdateOutputFileStampsProject? | BuildInvalidedProject? | UpdateBundleProject? */ -} - -external fun createBuilderStatusReporter(system: System, pretty: Boolean = definedExternally): DiagnosticReporter - -external fun createSolutionBuilderHost(system: System = definedExternally, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportSolutionBuilderStatus: DiagnosticReporter = definedExternally, reportErrorSummary: ReportEmitErrorSummary = definedExternally): SolutionBuilderHost - -external fun createSolutionBuilderWithWatchHost(system: System = definedExternally, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportSolutionBuilderStatus: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): SolutionBuilderWithWatchHost - -external fun createSolutionBuilder(host: SolutionBuilderHost, rootNames: Array, defaultOptions: BuildOptions): SolutionBuilder - -external fun createSolutionBuilderWithWatch(host: SolutionBuilderWithWatchHost, rootNames: Array, defaultOptions: BuildOptions, baseWatchOptions: WatchOptions = definedExternally): SolutionBuilder - -external enum class InvalidatedProjectKind { - Build /* = 0 */, - UpdateBundle /* = 1 */, - UpdateOutputFileStamps /* = 2 */ -} - -external interface InvalidatedProjectBase { - val kind: InvalidatedProjectKind - val project: String /* String & `T$5` */ - fun done(cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, customTransformers: CustomTransformers = definedExternally): ExitStatus - fun getCompilerOptions(): CompilerOptions - fun getCurrentDirectory(): String -} - -external interface UpdateOutputFileStampsProject : InvalidatedProjectBase { - fun updateOutputFileStatmps() -} - -external interface BuildInvalidedProject : InvalidatedProjectBase { - fun getBuilderProgram(): T? - fun getProgram(): Program? - fun getSourceFile(fileName: String): SourceFile? - fun getSourceFiles(): Array - fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getConfigFileParsingDiagnostics(): Array - fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getAllDependencies(sourceFile: SourceFile): Array - fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getSemanticDiagnosticsOfNextAffectedFile(cancellationToken: CancellationToken = definedExternally, ignoreSourceFile: (sourceFile: SourceFile) -> Boolean = definedExternally): `T$28`>? - fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult? -} - -external interface UpdateBundleProject : InvalidatedProjectBase { - fun emit(writeFile: WriteFileCallback = definedExternally, customTransformers: CustomTransformers = definedExternally): dynamic /* EmitResult? | BuildInvalidedProject? */ -} - -external interface SourceFileLike { - fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter -} - -external interface IScriptSnapshot { - fun getText(start: Number, end: Number): String - fun getLength(): Number - fun getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange? - val dispose: (() -> Unit)? -} - -external interface PreProcessedFileInfo { - var referencedFiles: Array - var typeReferenceDirectives: Array - var libReferenceDirectives: Array - var importedFiles: Array - var ambientExternalModules: Array? - get() = definedExternally - set(value) = definedExternally - var isLibFile: Boolean -} - -external interface HostCancellationToken { - fun isCancellationRequested(): Boolean -} - -external interface InstallPackageOptions { - var fileName: String /* String & `T$3` */ - var packageName: String -} - -external interface PerformanceEvent { - var kind: String /* "UpdateGraph" | "CreatePackageJsonAutoImportProvider" */ - var durationMs: Number -} - -external enum class LanguageServiceMode { - Semantic /* = 0 */, - PartialSemantic /* = 1 */, - Syntactic /* = 2 */ -} - -external interface IncompleteCompletionsCache { - fun get(): CompletionInfo? - fun set(response: CompletionInfo) - fun clear() -} - -external interface LanguageServiceHost : GetEffectiveTypeRootsHost { - fun getCompilationSettings(): CompilerOptions - val getNewLine: (() -> String)? - val getProjectVersion: (() -> String)? - fun getScriptFileNames(): Array - val getScriptKind: ((fileName: String) -> ScriptKind)? - fun getScriptVersion(fileName: String): String - fun getScriptSnapshot(fileName: String): IScriptSnapshot? - val getProjectReferences: (() -> Array?)? - val getLocalizedDiagnosticMessages: (() -> Any)? - val getCancellationToken: (() -> HostCancellationToken)? - override var getCurrentDirectory: () -> String - fun getDefaultLibFileName(options: CompilerOptions): String - val log: ((s: String) -> Unit)? - val trace: ((s: String) -> Unit)? - val error: ((s: String) -> Unit)? - val useCaseSensitiveFileNames: (() -> Boolean)? - val readDirectory: ((path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array)? - val readFile: ((path: String, encoding: String) -> String?)? - val realpath: ((path: String) -> String)? - val fileExists: ((path: String) -> Boolean)? - val getTypeRootsVersion: (() -> Number)? - val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val getResolvedModuleWithFailedLookupLocationsFromCache: ((modulename: String, containingFile: String) -> ResolvedModuleWithFailedLookupLocations?)? - val resolveTypeReferenceDirectives: ((typeDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val getDirectories: ((directoryName: String) -> Array)? - val getCustomTransformers: (() -> CustomTransformers?)? - val isKnownTypesPackageName: ((name: String) -> Boolean)? - val installPackage: ((options: InstallPackageOptions) -> Promise)? - val writeFile: ((fileName: String, content: String) -> Unit)? - val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? -} - -external enum class SemanticClassificationFormat { - Original /* = "original" */, - TwentyTwenty /* = "2020" */ -} - -external interface LanguageService { - fun cleanupSemanticCache() - fun getSyntacticDiagnostics(fileName: String): Array - fun getSemanticDiagnostics(fileName: String): Array - fun getSuggestionDiagnostics(fileName: String): Array - fun getCompilerOptionsDiagnostics(): Array - fun getSyntacticClassifications(fileName: String, span: TextSpan): Array - fun getSyntacticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ - fun getSemanticClassifications(fileName: String, span: TextSpan): Array - fun getSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ - fun getEncodedSyntacticClassifications(fileName: String, span: TextSpan): Classifications - fun getEncodedSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat = definedExternally): Classifications - fun getCompletionsAtPosition(fileName: String, position: Number, options: GetCompletionsAtPositionOptions?): CompletionInfo /* CompletionInfo & `T$12` */ - fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeOptions?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? - fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeSettings?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? - fun getCompletionEntrySymbol(fileName: String, position: Number, name: String, source: String?): Symbol? - fun getQuickInfoAtPosition(fileName: String, position: Number): QuickInfo? - fun getNameOrDottedNameSpan(fileName: String, startPos: Number, endPos: Number): TextSpan? - fun getBreakpointStatementAtPosition(fileName: String, position: Number): TextSpan? - fun getSignatureHelpItems(fileName: String, position: Number, options: SignatureHelpItemsOptions?): SignatureHelpItems? - fun getRenameInfo(fileName: String, position: Number, options: RenameInfoOptions = definedExternally): dynamic /* RenameInfoSuccess | RenameInfoFailure */ - fun findRenameLocations(fileName: String, position: Number, findInStrings: Boolean, findInComments: Boolean, providePrefixAndSuffixTextForRename: Boolean = definedExternally): Array? - fun getSmartSelectionRange(fileName: String, position: Number): SelectionRange - fun getDefinitionAtPosition(fileName: String, position: Number): Array? - fun getDefinitionAndBoundSpan(fileName: String, position: Number): DefinitionInfoAndBoundSpan? - fun getTypeDefinitionAtPosition(fileName: String, position: Number): Array? - fun getImplementationAtPosition(fileName: String, position: Number): Array? - fun getReferencesAtPosition(fileName: String, position: Number): Array? - fun findReferences(fileName: String, position: Number): Array? - fun getDocumentHighlights(fileName: String, position: Number, filesToSearch: Array): Array? - fun getFileReferences(fileName: String): Array - fun getOccurrencesAtPosition(fileName: String, position: Number): Array? - fun getNavigateToItems(searchValue: String, maxResultCount: Number = definedExternally, fileName: String = definedExternally, excludeDtsFiles: Boolean = definedExternally): Array - fun getNavigationBarItems(fileName: String): Array - fun getNavigationTree(fileName: String): NavigationTree - fun prepareCallHierarchy(fileName: String, position: Number): dynamic /* CallHierarchyItem? | Array? */ - fun provideCallHierarchyIncomingCalls(fileName: String, position: Number): Array - fun provideCallHierarchyOutgoingCalls(fileName: String, position: Number): Array - fun provideInlayHints(fileName: String, span: TextSpan, preferences: UserPreferences?): Array - fun getOutliningSpans(fileName: String): Array - fun getTodoComments(fileName: String, descriptors: Array): Array - fun getBraceMatchingAtPosition(fileName: String, position: Number): Array - fun getIndentationAtPosition(fileName: String, position: Number, options: EditorOptions): Number - fun getIndentationAtPosition(fileName: String, position: Number, options: EditorSettings): Number - fun getFormattingEditsForRange(fileName: String, start: Number, end: Number, options: FormatCodeOptions): Array - fun getFormattingEditsForRange(fileName: String, start: Number, end: Number, options: FormatCodeSettings): Array - fun getFormattingEditsForDocument(fileName: String, options: FormatCodeOptions): Array - fun getFormattingEditsForDocument(fileName: String, options: FormatCodeSettings): Array - fun getFormattingEditsAfterKeystroke(fileName: String, position: Number, key: String, options: FormatCodeOptions): Array - fun getFormattingEditsAfterKeystroke(fileName: String, position: Number, key: String, options: FormatCodeSettings): Array - fun getDocCommentTemplateAtPosition(fileName: String, position: Number, options: DocCommentTemplateOptions = definedExternally): TextInsertion? - fun isValidBraceCompletionAtPosition(fileName: String, position: Number, openingBrace: Number): Boolean - fun getJsxClosingTagAtPosition(fileName: String, position: Number): JsxClosingTagInfo? - fun getSpanOfEnclosingComment(fileName: String, position: Number, onlyMultiLine: Boolean): TextSpan? - val toLineColumnOffset: ((fileName: String, position: Number) -> LineAndCharacter)? - fun getCodeFixesAtPosition(fileName: String, start: Number, end: Number, errorCodes: Array, formatOptions: FormatCodeSettings, preferences: UserPreferences): Array - fun getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: Any, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions - fun applyCodeActionCommand(action: CodeActionCommand, formatSettings: FormatCodeSettings = definedExternally): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(action: CodeActionCommand): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(action: Array, formatSettings: FormatCodeSettings = definedExternally): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(action: Array): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(fileName: String, action: CodeActionCommand): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(fileName: String, action: Array): dynamic /* Promise | Promise */ - fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally, kind: String = definedExternally): Array - fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?): Array - fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally): Array - fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally, kind: String = definedExternally): Array - fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?): Array - fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally): Array - fun getEditsForRefactor(fileName: String, formatOptions: FormatCodeSettings, positionOrRange: Number, refactorName: String, actionName: String, preferences: UserPreferences?): RefactorEditInfo? - fun getEditsForRefactor(fileName: String, formatOptions: FormatCodeSettings, positionOrRange: TextRange, refactorName: String, actionName: String, preferences: UserPreferences?): RefactorEditInfo? - fun organizeImports(args: OrganizeImportsArgs, formatOptions: FormatCodeSettings, preferences: UserPreferences?): Array - fun getEditsForFileRename(oldFilePath: String, newFilePath: String, formatOptions: FormatCodeSettings, preferences: UserPreferences?): Array - fun getEmitOutput(fileName: String, emitOnlyDtsFiles: Boolean = definedExternally, forceDtsEmit: Boolean = definedExternally): EmitOutput - fun getProgram(): Program? - fun toggleLineComment(fileName: String, textRange: TextRange): Array - fun toggleMultilineComment(fileName: String, textRange: TextRange): Array - fun commentSelection(fileName: String, textRange: TextRange): Array - fun uncommentSelection(fileName: String, textRange: TextRange): Array - fun dispose() -} - -external interface JsxClosingTagInfo { - val newText: String -} - -external interface CombinedCodeFixScope { - var type: String /* "file" */ - var fileName: String -} - -external interface OrganizeImportsArgs : CombinedCodeFixScope { - var skipDestructiveCodeActions: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external enum class CompletionTriggerKind { - Invoked /* = 1 */, - TriggerCharacter /* = 2 */, - TriggerForIncompleteCompletions /* = 3 */ -} - -external interface GetCompletionsAtPositionOptions : UserPreferences { - var triggerCharacter: String? /* "." | """ | "'" | "`" | "/" | "@" | "<" | "#" | " " */ - get() = definedExternally - set(value) = definedExternally - var triggerKind: CompletionTriggerKind? - get() = definedExternally - set(value) = definedExternally - var includeExternalModuleExports: Boolean? - get() = definedExternally - set(value) = definedExternally - var includeInsertTextCompletions: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface InlayHintsOptions : UserPreferences { - val includeInlayParameterNameHints: String? /* "none" | "literals" | "all" */ - get() = definedExternally - val includeInlayParameterNameHintsWhenArgumentMatchesName: Boolean? - get() = definedExternally - val includeInlayFunctionParameterTypeHints: Boolean? - get() = definedExternally - val includeInlayVariableTypeHints: Boolean? - get() = definedExternally - val includeInlayPropertyDeclarationTypeHints: Boolean? - get() = definedExternally - val includeInlayFunctionLikeReturnTypeHints: Boolean? - get() = definedExternally - val includeInlayEnumMemberValueHints: Boolean? - get() = definedExternally -} - -external interface SignatureHelpItemsOptions { - var triggerReason: dynamic /* SignatureHelpInvokedReason? | SignatureHelpCharacterTypedReason? | SignatureHelpRetriggeredReason? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureHelpInvokedReason { - var kind: String /* "invoked" */ - var triggerCharacter: Any? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureHelpCharacterTypedReason { - var kind: String /* "characterTyped" */ - var triggerCharacter: String /* "," | "(" | "<" */ -} - -external interface SignatureHelpRetriggeredReason { - var kind: String /* "retrigger" */ - var triggerCharacter: String? /* "," | "(" | "<" | ")" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ApplyCodeActionCommandResult { - var successMessage: String -} - -external interface Classifications { - var spans: Array - var endOfLineState: EndOfLineState -} - -external interface ClassifiedSpan { - var textSpan: TextSpan - var classificationType: ClassificationTypeNames -} - -external interface ClassifiedSpan2020 { - var textSpan: TextSpan - var classificationType: Number -} - -external interface NavigationBarItem { - var text: String - var kind: ScriptElementKind - var kindModifiers: String - var spans: Array - var childItems: Array - var indent: Number - var bolded: Boolean - var grayed: Boolean -} - -external interface NavigationTree { - var text: String - var kind: ScriptElementKind - var kindModifiers: String - var spans: Array - var nameSpan: TextSpan? - var childItems: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface CallHierarchyItem { - var name: String - var kind: ScriptElementKind - var kindModifiers: String? - get() = definedExternally - set(value) = definedExternally - var file: String - var span: TextSpan - var selectionSpan: TextSpan - var containerName: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface CallHierarchyIncomingCall { - var from: CallHierarchyItem - var fromSpans: Array -} - -external interface CallHierarchyOutgoingCall { - var to: CallHierarchyItem - var fromSpans: Array -} - -external enum class InlayHintKind { - Type /* = "Type" */, - Parameter /* = "Parameter" */, - Enum /* = "Enum" */ -} - -external interface InlayHint { - var text: String - var position: Number - var kind: InlayHintKind - var whitespaceBefore: Boolean? - get() = definedExternally - set(value) = definedExternally - var whitespaceAfter: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TodoCommentDescriptor { - var text: String - var priority: Number -} - -external interface TodoComment { - var descriptor: TodoCommentDescriptor - var message: String - var position: Number -} - -external interface TextChange { - var span: TextSpan - var newText: String -} - -external interface FileTextChanges { - var fileName: String - var textChanges: Array - var isNewFile: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface CodeAction { - var description: String - var changes: Array - var commands: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface CodeFixAction : CodeAction { - var fixName: String - var fixId: Any? - get() = definedExternally - set(value) = definedExternally - var fixAllDescription: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface CombinedCodeActions { - var changes: Array - var commands: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface InstallPackageAction - -external interface ApplicableRefactorInfo { - var name: String - var description: String - var inlineable: Boolean? - get() = definedExternally - set(value) = definedExternally - var actions: Array -} - -external interface RefactorActionInfo { - var name: String - var description: String - var notApplicableReason: String? - get() = definedExternally - set(value) = definedExternally - var kind: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface RefactorEditInfo { - var edits: Array - var renameFilename: String? - get() = definedExternally - set(value) = definedExternally - var renameLocation: Number? - get() = definedExternally - set(value) = definedExternally - var commands: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface TextInsertion { - var newText: String - var caretOffset: Number -} - -external interface DocumentSpan { - var textSpan: TextSpan - var fileName: String - var originalTextSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var originalFileName: String? - get() = definedExternally - set(value) = definedExternally - var contextSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var originalContextSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally -} - -external interface RenameLocation : DocumentSpan { - val prefixText: String? - get() = definedExternally - val suffixText: String? - get() = definedExternally -} - -external interface ReferenceEntry : DocumentSpan { - var isWriteAccess: Boolean - var isDefinition: Boolean - var isInString: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ImplementationLocation : DocumentSpan { - var kind: ScriptElementKind - var displayParts: Array -} - -external enum class HighlightSpanKind { - none /* = "none" */, - definition /* = "definition" */, - reference /* = "reference" */, - writtenReference /* = "writtenReference" */ -} - -external interface HighlightSpan { - var fileName: String? - get() = definedExternally - set(value) = definedExternally - var isInString: Boolean? - get() = definedExternally - set(value) = definedExternally - var textSpan: TextSpan - var contextSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var kind: HighlightSpanKind -} - -external interface NavigateToItem { - var name: String - var kind: ScriptElementKind - var kindModifiers: String - var matchKind: String /* "exact" | "prefix" | "substring" | "camelCase" */ - var isCaseSensitive: Boolean - var fileName: String - var textSpan: TextSpan - var containerName: String - var containerKind: ScriptElementKind -} - -external enum class IndentStyle { - None /* = 0 */, - Block /* = 1 */, - Smart /* = 2 */ -} - -external enum class SemicolonPreference { - Ignore /* = "ignore" */, - Insert /* = "insert" */, - Remove /* = "remove" */ -} - -external interface EditorOptions { - var BaseIndentSize: Number? - get() = definedExternally - set(value) = definedExternally - var IndentSize: Number - var TabSize: Number - var NewLineCharacter: String - var ConvertTabsToSpaces: Boolean - var IndentStyle: IndentStyle -} - -external interface EditorSettings { - var baseIndentSize: Number? - get() = definedExternally - set(value) = definedExternally - var indentSize: Number? - get() = definedExternally - set(value) = definedExternally - var tabSize: Number? - get() = definedExternally - set(value) = definedExternally - var newLineCharacter: String? - get() = definedExternally - set(value) = definedExternally - var convertTabsToSpaces: Boolean? - get() = definedExternally - set(value) = definedExternally - var indentStyle: IndentStyle? - get() = definedExternally - set(value) = definedExternally - var trimTrailingWhitespace: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface FormatCodeOptions : EditorOptions { - var InsertSpaceAfterCommaDelimiter: Boolean - var InsertSpaceAfterSemicolonInForStatements: Boolean - var InsertSpaceBeforeAndAfterBinaryOperators: Boolean - var InsertSpaceAfterConstructor: Boolean? - get() = definedExternally - set(value) = definedExternally - var InsertSpaceAfterKeywordsInControlFlowStatements: Boolean - var InsertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean - var InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean - var InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean - var InsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: Boolean? - get() = definedExternally - set(value) = definedExternally - var InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean - var InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: Boolean? - get() = definedExternally - set(value) = definedExternally - var InsertSpaceAfterTypeAssertion: Boolean? - get() = definedExternally - set(value) = definedExternally - var InsertSpaceBeforeFunctionParenthesis: Boolean? - get() = definedExternally - set(value) = definedExternally - var PlaceOpenBraceOnNewLineForFunctions: Boolean - var PlaceOpenBraceOnNewLineForControlBlocks: Boolean - var insertSpaceBeforeTypeAnnotation: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface FormatCodeSettings : EditorSettings { - val insertSpaceAfterCommaDelimiter: Boolean? - get() = definedExternally - val insertSpaceAfterSemicolonInForStatements: Boolean? - get() = definedExternally - val insertSpaceBeforeAndAfterBinaryOperators: Boolean? - get() = definedExternally - val insertSpaceAfterConstructor: Boolean? - get() = definedExternally - val insertSpaceAfterKeywordsInControlFlowStatements: Boolean? - get() = definedExternally - val insertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingEmptyBraces: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: Boolean? - get() = definedExternally - val insertSpaceAfterTypeAssertion: Boolean? - get() = definedExternally - val insertSpaceBeforeFunctionParenthesis: Boolean? - get() = definedExternally - val placeOpenBraceOnNewLineForFunctions: Boolean? - get() = definedExternally - val placeOpenBraceOnNewLineForControlBlocks: Boolean? - get() = definedExternally - val insertSpaceBeforeTypeAnnotation: Boolean? - get() = definedExternally - val indentMultiLineObjectLiteralBeginningOnBlankLine: Boolean? - get() = definedExternally - val semicolons: SemicolonPreference? - get() = definedExternally -} - -external fun getDefaultFormatCodeSettings(newLineCharacter: String = definedExternally): FormatCodeSettings - -external interface DefinitionInfo : DocumentSpan { - var kind: ScriptElementKind - var name: String - var containerKind: ScriptElementKind - var containerName: String - var unverified: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface DefinitionInfoAndBoundSpan { - var definitions: Array? - get() = definedExternally - set(value) = definedExternally - var textSpan: TextSpan -} - -external interface ReferencedSymbolDefinitionInfo : DefinitionInfo { - var displayParts: Array -} - -external interface ReferencedSymbol { - var definition: ReferencedSymbolDefinitionInfo - var references: Array -} - -external enum class SymbolDisplayPartKind { - aliasName /* = 0 */, - className /* = 1 */, - enumName /* = 2 */, - fieldName /* = 3 */, - interfaceName /* = 4 */, - keyword /* = 5 */, - lineBreak /* = 6 */, - numericLiteral /* = 7 */, - stringLiteral /* = 8 */, - localName /* = 9 */, - methodName /* = 10 */, - moduleName /* = 11 */, - operator /* = 12 */, - parameterName /* = 13 */, - propertyName /* = 14 */, - punctuation /* = 15 */, - space /* = 16 */, - text /* = 17 */, - typeParameterName /* = 18 */, - enumMemberName /* = 19 */, - functionName /* = 20 */, - regularExpressionLiteral /* = 21 */, - link /* = 22 */, - linkName /* = 23 */, - linkText /* = 24 */ -} - -external interface SymbolDisplayPart { - var text: String - var kind: String -} - -external interface JSDocLinkDisplayPart : SymbolDisplayPart { - var target: DocumentSpan -} - -external interface JSDocTagInfo { - var name: String - var text: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface QuickInfo { - var kind: ScriptElementKind - var kindModifiers: String - var textSpan: TextSpan - var displayParts: Array? - get() = definedExternally - set(value) = definedExternally - var documentation: Array? - get() = definedExternally - set(value) = definedExternally - var tags: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface RenameInfoSuccess { - var canRename: Boolean - var fileToRename: String? - get() = definedExternally - set(value) = definedExternally - var displayName: String - var fullDisplayName: String - var kind: ScriptElementKind - var kindModifiers: String - var triggerSpan: TextSpan -} - -external interface RenameInfoFailure { - var canRename: Boolean - var localizedErrorMessage: String -} - -external interface RenameInfoOptions { - val allowRenameOfImportPath: Boolean? - get() = definedExternally -} - -external interface DocCommentTemplateOptions { - val generateReturnInDocTemplate: Boolean? - get() = definedExternally -} - -external interface SignatureHelpParameter { - var name: String - var documentation: Array - var displayParts: Array - var isOptional: Boolean - var isRest: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface SelectionRange { - var textSpan: TextSpan - var parent: SelectionRange? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureHelpItem { - var isVariadic: Boolean - var prefixDisplayParts: Array - var suffixDisplayParts: Array - var separatorDisplayParts: Array - var parameters: Array - var documentation: Array - var tags: Array -} - -external interface SignatureHelpItems { - var items: Array - var applicableSpan: TextSpan - var selectedItemIndex: Number - var argumentIndex: Number - var argumentCount: Number -} - -external interface CompletionInfo { - var isGlobalCompletion: Boolean - var isMemberCompletion: Boolean - var optionalReplacementSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var isNewIdentifierLocation: Boolean - var isIncomplete: Boolean? - get() = definedExternally - set(value) = definedExternally - var entries: Array -} - -external interface CompletionEntryData { - var fileName: String? - get() = definedExternally - set(value) = definedExternally - var ambientModuleName: String? - get() = definedExternally - set(value) = definedExternally - var isPackageJsonImport: Boolean? - get() = definedExternally - set(value) = definedExternally - var exportName: String - var moduleSpecifier: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface CompletionEntry { - var name: String - var kind: ScriptElementKind - var kindModifiers: String? - get() = definedExternally - set(value) = definedExternally - var sortText: String - var insertText: String? - get() = definedExternally - set(value) = definedExternally - var isSnippet: Boolean? - get() = definedExternally - set(value) = definedExternally - var replacementSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var hasAction: Boolean? - get() = definedExternally - set(value) = definedExternally - var source: String? - get() = definedExternally - set(value) = definedExternally - var sourceDisplay: Array? - get() = definedExternally - set(value) = definedExternally - var isRecommended: Boolean? - get() = definedExternally - set(value) = definedExternally - var isFromUncheckedFile: Boolean? - get() = definedExternally - set(value) = definedExternally - var isPackageJsonImport: Boolean? - get() = definedExternally - set(value) = definedExternally - var isImportStatementCompletion: Boolean? - get() = definedExternally - set(value) = definedExternally - var data: CompletionEntryData? - get() = definedExternally - set(value) = definedExternally -} - -external interface CompletionEntryDetails { - var name: String - var kind: ScriptElementKind - var kindModifiers: String - var displayParts: Array - var documentation: Array? - get() = definedExternally - set(value) = definedExternally - var tags: Array? - get() = definedExternally - set(value) = definedExternally - var codeActions: Array? - get() = definedExternally - set(value) = definedExternally - var source: Array? - get() = definedExternally - set(value) = definedExternally - var sourceDisplay: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface OutliningSpan { - var textSpan: TextSpan - var hintSpan: TextSpan - var bannerText: String - var autoCollapse: Boolean - var kind: OutliningSpanKind -} - -external enum class OutliningSpanKind { - Comment /* = "comment" */, - Region /* = "region" */, - Code /* = "code" */, - Imports /* = "imports" */ -} - -external enum class OutputFileType { - JavaScript /* = 0 */, - SourceMap /* = 1 */, - Declaration /* = 2 */ -} - -external enum class EndOfLineState { - None /* = 0 */, - InMultiLineCommentTrivia /* = 1 */, - InSingleQuoteStringLiteral /* = 2 */, - InDoubleQuoteStringLiteral /* = 3 */, - InTemplateHeadOrNoSubstitutionTemplate /* = 4 */, - InTemplateMiddleOrTail /* = 5 */, - InTemplateSubstitutionPosition /* = 6 */ -} - -external enum class TokenClass { - Punctuation /* = 0 */, - Keyword /* = 1 */, - Operator /* = 2 */, - Comment /* = 3 */, - Whitespace /* = 4 */, - Identifier /* = 5 */, - NumberLiteral /* = 6 */, - BigIntLiteral /* = 7 */, - StringLiteral /* = 8 */, - RegExpLiteral /* = 9 */ -} - -external interface ClassificationResult { - var finalLexState: EndOfLineState - var entries: Array -} - -external interface ClassificationInfo { - var length: Number - var classification: TokenClass -} - -external interface Classifier { - fun getClassificationsForLine(text: String, lexState: EndOfLineState, syntacticClassifierAbsent: Boolean): ClassificationResult - fun getEncodedLexicalClassifications(text: String, endOfLineState: EndOfLineState, syntacticClassifierAbsent: Boolean): Classifications -} - -external enum class ScriptElementKind { - unknown /* = "" */, - warning /* = "warning" */, - keyword /* = "keyword" */, - scriptElement /* = "script" */, - moduleElement /* = "module" */, - classElement /* = "class" */, - localClassElement /* = "local class" */, - interfaceElement /* = "interface" */, - typeElement /* = "type" */, - enumElement /* = "enum" */, - enumMemberElement /* = "enum member" */, - variableElement /* = "var" */, - localVariableElement /* = "local var" */, - functionElement /* = "function" */, - localFunctionElement /* = "local function" */, - memberFunctionElement /* = "method" */, - memberGetAccessorElement /* = "getter" */, - memberSetAccessorElement /* = "setter" */, - memberVariableElement /* = "property" */, - constructorImplementationElement /* = "constructor" */, - callSignatureElement /* = "call" */, - indexSignatureElement /* = "index" */, - constructSignatureElement /* = "construct" */, - parameterElement /* = "parameter" */, - typeParameterElement /* = "type parameter" */, - primitiveType /* = "primitive type" */, - label /* = "label" */, - alias /* = "alias" */, - constElement /* = "const" */, - letElement /* = "let" */, - directory /* = "directory" */, - externalModuleName /* = "external module name" */, - jsxAttribute /* = "JSX attribute" */, - string /* = "string" */, - link /* = "link" */, - linkName /* = "link name" */, - linkText /* = "link text" */ -} - -external enum class ScriptElementKindModifier { - none /* = "" */, - publicMemberModifier /* = "public" */, - privateMemberModifier /* = "private" */, - protectedMemberModifier /* = "protected" */, - exportedModifier /* = "export" */, - ambientModifier /* = "declare" */, - staticModifier /* = "static" */, - abstractModifier /* = "abstract" */, - optionalModifier /* = "optional" */, - deprecatedModifier /* = "deprecated" */, - dtsModifier /* = ".d.ts" */, - tsModifier /* = ".ts" */, - tsxModifier /* = ".tsx" */, - jsModifier /* = ".js" */, - jsxModifier /* = ".jsx" */, - jsonModifier /* = ".json" */ -} - -external enum class ClassificationTypeNames { - comment /* = "comment" */, - identifier /* = "identifier" */, - keyword /* = "keyword" */, - numericLiteral /* = "number" */, - bigintLiteral /* = "bigint" */, - operator /* = "operator" */, - stringLiteral /* = "string" */, - whiteSpace /* = "whitespace" */, - text /* = "text" */, - punctuation /* = "punctuation" */, - className /* = "class name" */, - enumName /* = "enum name" */, - interfaceName /* = "interface name" */, - moduleName /* = "module name" */, - typeParameterName /* = "type parameter name" */, - typeAliasName /* = "type alias name" */, - parameterName /* = "parameter name" */, - docCommentTagName /* = "doc comment tag name" */, - jsxOpenTagName /* = "jsx open tag name" */, - jsxCloseTagName /* = "jsx close tag name" */, - jsxSelfClosingTagName /* = "jsx self closing tag name" */, - jsxAttribute /* = "jsx attribute" */, - jsxText /* = "jsx text" */, - jsxAttributeStringLiteralValue /* = "jsx attribute string literal value" */ -} - -external enum class ClassificationType { - comment /* = 1 */, - identifier /* = 2 */, - keyword /* = 3 */, - numericLiteral /* = 4 */, - operator /* = 5 */, - stringLiteral /* = 6 */, - regularExpressionLiteral /* = 7 */, - whiteSpace /* = 8 */, - text /* = 9 */, - punctuation /* = 10 */, - className /* = 11 */, - enumName /* = 12 */, - interfaceName /* = 13 */, - moduleName /* = 14 */, - typeParameterName /* = 15 */, - typeAliasName /* = 16 */, - parameterName /* = 17 */, - docCommentTagName /* = 18 */, - jsxOpenTagName /* = 19 */, - jsxCloseTagName /* = 20 */, - jsxSelfClosingTagName /* = 21 */, - jsxAttribute /* = 22 */, - jsxText /* = 23 */, - jsxAttributeStringLiteralValue /* = 24 */, - bigintLiteral /* = 25 */ -} - -external interface InlayHintsContext { - var file: SourceFile - var program: Program - var cancellationToken: CancellationToken - var host: LanguageServiceHost - var span: TextSpan - var preferences: InlayHintsOptions -} - -external fun createClassifier(): Classifier - -external interface DocumentHighlights { - var fileName: String - var highlightSpans: Array -} - -external interface DocumentRegistry { - fun acquireDocument(fileName: String, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile - fun acquireDocumentWithKey(fileName: String, path: String /* String & `T$3` */, compilationSettings: CompilerOptions, key: String /* String & `T$29` */, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile - fun updateDocument(fileName: String, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile - fun updateDocumentWithKey(fileName: String, path: String /* String & `T$3` */, compilationSettings: CompilerOptions, key: String /* String & `T$29` */, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile - fun getKeyForCompilationSettings(settings: CompilerOptions): String /* String & `T$29` */ - fun releaseDocument(fileName: String, compilationSettings: CompilerOptions) - fun releaseDocument(fileName: String, compilationSettings: CompilerOptions, scriptKind: ScriptKind) - fun releaseDocumentWithKey(path: String /* String & `T$3` */, key: String /* String & `T$29` */) - fun releaseDocumentWithKey(path: String /* String & `T$3` */, key: String /* String & `T$29` */, scriptKind: ScriptKind) - fun reportStats(): String -} - -external interface `T$29` { - var __bucketKey: Any -} - -external fun createDocumentRegistry(useCaseSensitiveFileNames: Boolean = definedExternally, currentDirectory: String = definedExternally): DocumentRegistry - -external fun preProcessFile(sourceText: String, readImportFiles: Boolean = definedExternally, detectJavaScriptImports: Boolean = definedExternally): PreProcessedFileInfo - -external interface TranspileOptions { - var compilerOptions: CompilerOptions? - get() = definedExternally - set(value) = definedExternally - var fileName: String? - get() = definedExternally - set(value) = definedExternally - var reportDiagnostics: Boolean? - get() = definedExternally - set(value) = definedExternally - var moduleName: String? - get() = definedExternally - set(value) = definedExternally - var renamedDependencies: MapLike? - get() = definedExternally - set(value) = definedExternally - var transformers: CustomTransformers? - get() = definedExternally - set(value) = definedExternally -} - -external interface TranspileOutput { - var outputText: String - var diagnostics: Array? - get() = definedExternally - set(value) = definedExternally - var sourceMapText: String? - get() = definedExternally - set(value) = definedExternally -} - -external fun transpileModule(input: String, transpileOptions: TranspileOptions): TranspileOutput - -external fun transpile(input: String, compilerOptions: CompilerOptions = definedExternally, fileName: String = definedExternally, diagnostics: Array = definedExternally, moduleName: String = definedExternally): String - -external var servicesVersion: Any - -external fun toEditorSettings(options: EditorOptions): EditorSettings - -external fun toEditorSettings(options: EditorSettings): EditorSettings - -external fun displayPartsToString(displayParts: Array?): String - -external fun getDefaultCompilerOptions(): CompilerOptions - -external fun getSupportedCodeFixes(): Array - -external fun createLanguageServiceSourceFile(fileName: String, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: String, setNodeParents: Boolean, scriptKind: ScriptKind = definedExternally): SourceFile - -external fun updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: String, textChangeRange: TextChangeRange?, aggressiveChecks: Boolean = definedExternally): SourceFile - -external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally, syntaxOnlyOrLanguageServiceMode: Boolean = definedExternally): LanguageService - -external fun createLanguageService(host: LanguageServiceHost): LanguageService - -external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally): LanguageService - -external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally, syntaxOnlyOrLanguageServiceMode: LanguageServiceMode = definedExternally): LanguageService - -external fun getDefaultLibFilePath(options: CompilerOptions): String - -external fun transform(source: T, transformers: Array>, compilerOptions: CompilerOptions = definedExternally): TransformationResult - -external fun transform(source: T, transformers: Array>): TransformationResult - -external fun transform(source: Array, transformers: Array>, compilerOptions: CompilerOptions = definedExternally): TransformationResult - -external fun transform(source: Array, transformers: Array>): TransformationResult - -external var createNodeArray: (elements: Array?, hasTrailingComma: Boolean?) -> NodeArray - -external var createNumericLiteral: (value: dynamic /* String | Number */, numericLiteralFlags: TokenFlags?) -> NumericLiteral - -external var createBigIntLiteral: (value: dynamic /* String | PseudoBigInt */) -> BigIntLiteral - -external object createStringLiteral { - @nativeInvoke - operator fun invoke(text: String, isSingleQuote: Boolean? = definedExternally): StringLiteral - @nativeInvoke - operator fun invoke(text: String, isSingleQuote: Boolean? = definedExternally, hasExtendedUnicodeEscape: Boolean? = definedExternally): StringLiteral -} - -external var createStringLiteralFromNode: (sourceNode: dynamic /* Identifier | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral */, isSingleQuote: Boolean?) -> StringLiteral - -external var createRegularExpressionLiteral: (text: String) -> RegularExpressionLiteral - -external var createLoopVariable: (reservedInNestedScopes: Boolean?) -> Identifier - -external var createUniqueName: (text: String, flags: GeneratedIdentifierFlags?) -> Identifier - -external var createPrivateIdentifier: (text: String) -> PrivateIdentifier - -external var createSuper: () -> SuperExpression - -external var createThis: () -> ThisExpression - -external var createNull: () -> NullLiteral - -external var createTrue: () -> TrueLiteral - -external var createFalse: () -> FalseLiteral - -external var createModifier: (kind: T) -> ModifierToken - -external var createModifiersFromModifierFlags: (flags: ModifierFlags) -> Array - -external var createQualifiedName: (left: dynamic /* Identifier | QualifiedName */, right: dynamic /* String | Identifier */) -> QualifiedName - -external var updateQualifiedName: (node: QualifiedName, left: dynamic /* Identifier | QualifiedName */, right: Identifier) -> QualifiedName - -external var createComputedPropertyName: (expression: Expression) -> ComputedPropertyName - -external var updateComputedPropertyName: (node: ComputedPropertyName, expression: Expression) -> ComputedPropertyName - -external var createTypeParameterDeclaration: (name: dynamic /* String | Identifier */, constraint: TypeNode?, defaultType: TypeNode?) -> TypeParameterDeclaration - -external var updateTypeParameterDeclaration: (node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode?, defaultType: TypeNode?) -> TypeParameterDeclaration - -external var createParameter: (decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> ParameterDeclaration - -external var updateParameter: (node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> ParameterDeclaration - -external var createDecorator: (expression: Expression) -> Decorator - -external var updateDecorator: (node: Decorator, expression: Expression) -> Decorator - -external var createProperty: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionOrExclamationToken: dynamic /* QuestionToken? | ExclamationToken? */, type: TypeNode?, initializer: Expression?) -> PropertyDeclaration - -external var updateProperty: (node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionOrExclamationToken: dynamic /* QuestionToken? | ExclamationToken? */, type: TypeNode?, initializer: Expression?) -> PropertyDeclaration - -external var createMethod: (decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> MethodDeclaration - -external var updateMethod: (node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> MethodDeclaration - -external var createConstructor: (decorators: Array?, modifiers: Array?, parameters: Array, body: Block?) -> ConstructorDeclaration - -external var updateConstructor: (node: ConstructorDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, body: Block?) -> ConstructorDeclaration - -external var createGetAccessor: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, type: TypeNode?, body: Block?) -> GetAccessorDeclaration - -external var updateGetAccessor: (node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, type: TypeNode?, body: Block?) -> GetAccessorDeclaration - -external var createSetAccessor: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, body: Block?) -> SetAccessorDeclaration - -external var updateSetAccessor: (node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, body: Block?) -> SetAccessorDeclaration - -external var createCallSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?) -> CallSignatureDeclaration - -external var updateCallSignature: (node: CallSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?) -> CallSignatureDeclaration - -external var createConstructSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?) -> ConstructSignatureDeclaration - -external var updateConstructSignature: (node: ConstructSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?) -> ConstructSignatureDeclaration - -external var updateIndexSignature: (node: IndexSignatureDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode) -> IndexSignatureDeclaration - -external var createKeywordTypeNode: (kind: TKind) -> KeywordTypeNode - -external var createTypePredicateNodeWithModifier: (assertsModifier: AssertsKeyword?, parameterName: dynamic /* String | Identifier | ThisTypeNode */, type: TypeNode?) -> TypePredicateNode - -external var updateTypePredicateNodeWithModifier: (node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: dynamic /* Identifier | ThisTypeNode */, type: TypeNode?) -> TypePredicateNode - -external var createTypeReferenceNode: (typeName: dynamic /* String | Identifier | QualifiedName */, typeArguments: Array?) -> TypeReferenceNode - -external var updateTypeReferenceNode: (node: TypeReferenceNode, typeName: dynamic /* Identifier | QualifiedName */, typeArguments: NodeArray?) -> TypeReferenceNode - -external var createFunctionTypeNode: (typeParameters: Array?, parameters: Array, type: TypeNode) -> FunctionTypeNode - -external var updateFunctionTypeNode: (node: FunctionTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode) -> FunctionTypeNode - -external var createConstructorTypeNode: (typeParameters: Array?, parameters: Array, type: TypeNode) -> ConstructorTypeNode - -external var updateConstructorTypeNode: (node: ConstructorTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode) -> ConstructorTypeNode - -external var createTypeQueryNode: (exprName: dynamic /* Identifier | QualifiedName */) -> TypeQueryNode - -external var updateTypeQueryNode: (node: TypeQueryNode, exprName: dynamic /* Identifier | QualifiedName */) -> TypeQueryNode - -external var createTypeLiteralNode: (members: Array?) -> TypeLiteralNode - -external var updateTypeLiteralNode: (node: TypeLiteralNode, members: NodeArray) -> TypeLiteralNode - -external var createArrayTypeNode: (elementType: TypeNode) -> ArrayTypeNode - -external var updateArrayTypeNode: (node: ArrayTypeNode, elementType: TypeNode) -> ArrayTypeNode - -external var createTupleTypeNode: (elements: Array) -> TupleTypeNode - -external var updateTupleTypeNode: (node: TupleTypeNode, elements: Array) -> TupleTypeNode - -external var createOptionalTypeNode: (type: TypeNode) -> OptionalTypeNode - -external var updateOptionalTypeNode: (node: OptionalTypeNode, type: TypeNode) -> OptionalTypeNode - -external var createRestTypeNode: (type: TypeNode) -> RestTypeNode - -external var updateRestTypeNode: (node: RestTypeNode, type: TypeNode) -> RestTypeNode - -external var createUnionTypeNode: (types: Array) -> UnionTypeNode - -external var updateUnionTypeNode: (node: UnionTypeNode, types: NodeArray) -> UnionTypeNode - -external var createIntersectionTypeNode: (types: Array) -> IntersectionTypeNode - -external var updateIntersectionTypeNode: (node: IntersectionTypeNode, types: NodeArray) -> IntersectionTypeNode - -external var createConditionalTypeNode: (checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) -> ConditionalTypeNode - -external var updateConditionalTypeNode: (node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) -> ConditionalTypeNode - -external var createInferTypeNode: (typeParameter: TypeParameterDeclaration) -> InferTypeNode - -external var updateInferTypeNode: (node: InferTypeNode, typeParameter: TypeParameterDeclaration) -> InferTypeNode - -external var createImportTypeNode: (argument: TypeNode, qualifier: dynamic /* Identifier? | QualifiedName? */, typeArguments: Array?, isTypeOf: Boolean?) -> ImportTypeNode - -external var updateImportTypeNode: (node: ImportTypeNode, argument: TypeNode, qualifier: dynamic /* Identifier? | QualifiedName? */, typeArguments: Array?, isTypeOf: Boolean?) -> ImportTypeNode - -external var createParenthesizedType: (type: TypeNode) -> ParenthesizedTypeNode - -external var updateParenthesizedType: (node: ParenthesizedTypeNode, type: TypeNode) -> ParenthesizedTypeNode - -external var createThisTypeNode: () -> ThisTypeNode - -external var updateTypeOperatorNode: (node: TypeOperatorNode, type: TypeNode) -> TypeOperatorNode - -external var createIndexedAccessTypeNode: (objectType: TypeNode, indexType: TypeNode) -> IndexedAccessTypeNode - -external var updateIndexedAccessTypeNode: (node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) -> IndexedAccessTypeNode - -external var createMappedTypeNode: (readonlyToken: dynamic /* ReadonlyKeyword? | PlusToken? | MinusToken? */, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */, type: TypeNode?) -> MappedTypeNode - -external var updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: dynamic /* ReadonlyKeyword? | PlusToken? | MinusToken? */, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */, type: TypeNode?) -> MappedTypeNode - -external var createLiteralTypeNode: (literal: dynamic /* LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral */) -> LiteralTypeNode - -external var updateLiteralTypeNode: (node: LiteralTypeNode, literal: dynamic /* LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral */) -> LiteralTypeNode - -external var createObjectBindingPattern: (elements: Array) -> ObjectBindingPattern - -external var updateObjectBindingPattern: (node: ObjectBindingPattern, elements: Array) -> ObjectBindingPattern - -external var createArrayBindingPattern: (elements: Array) -> ArrayBindingPattern - -external var updateArrayBindingPattern: (node: ArrayBindingPattern, elements: Array) -> ArrayBindingPattern - -external var createBindingElement: (dotDotDotToken: DotDotDotToken?, propertyName: dynamic /* String? | Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression?) -> BindingElement - -external var updateBindingElement: (node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */, name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression?) -> BindingElement - -external var createArrayLiteral: (elements: Array?, multiLine: Boolean?) -> ArrayLiteralExpression - -external var updateArrayLiteral: (node: ArrayLiteralExpression, elements: Array) -> ArrayLiteralExpression - -external var createObjectLiteral: (properties: Array?, multiLine: Boolean?) -> ObjectLiteralExpression - -external var updateObjectLiteral: (node: ObjectLiteralExpression, properties: Array) -> ObjectLiteralExpression - -external var createPropertyAccess: (expression: Expression, name: dynamic /* String | Identifier | PrivateIdentifier */) -> PropertyAccessExpression - -external var updatePropertyAccess: (node: PropertyAccessExpression, expression: Expression, name: dynamic /* Identifier | PrivateIdentifier */) -> PropertyAccessExpression - -external var createPropertyAccessChain: (expression: Expression, questionDotToken: QuestionDotToken?, name: dynamic /* String | Identifier | PrivateIdentifier */) -> PropertyAccessChain - -external var updatePropertyAccessChain: (node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: dynamic /* Identifier | PrivateIdentifier */) -> PropertyAccessChain - -external var createElementAccess: (expression: Expression, index: dynamic /* Number | Expression */) -> ElementAccessExpression - -external var updateElementAccess: (node: ElementAccessExpression, expression: Expression, argumentExpression: Expression) -> ElementAccessExpression - -external var createElementAccessChain: (expression: Expression, questionDotToken: QuestionDotToken?, index: dynamic /* Number | Expression */) -> ElementAccessChain - -external var updateElementAccessChain: (node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, argumentExpression: Expression) -> ElementAccessChain - -external var createCall: (expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> CallExpression - -external var updateCall: (node: CallExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array) -> CallExpression - -external var createCallChain: (expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array?) -> CallChain - -external var updateCallChain: (node: CallChain, expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array) -> CallChain - -external var createNew: (expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> NewExpression - -external var updateNew: (node: NewExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> NewExpression - -external var createTypeAssertion: (type: TypeNode, expression: Expression) -> TypeAssertion - -external var updateTypeAssertion: (node: TypeAssertion, type: TypeNode, expression: Expression) -> TypeAssertion - -external var createParen: (expression: Expression) -> ParenthesizedExpression - -external var updateParen: (node: ParenthesizedExpression, expression: Expression) -> ParenthesizedExpression - -external var createFunctionExpression: (modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block) -> FunctionExpression - -external var updateFunctionExpression: (node: FunctionExpression, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block) -> FunctionExpression - -external var createDelete: (expression: Expression) -> DeleteExpression - -external var updateDelete: (node: DeleteExpression, expression: Expression) -> DeleteExpression - -external var createTypeOf: (expression: Expression) -> TypeOfExpression - -external var updateTypeOf: (node: TypeOfExpression, expression: Expression) -> TypeOfExpression - -external var createVoid: (expression: Expression) -> VoidExpression - -external var updateVoid: (node: VoidExpression, expression: Expression) -> VoidExpression - -external var createAwait: (expression: Expression) -> AwaitExpression - -external var updateAwait: (node: AwaitExpression, expression: Expression) -> AwaitExpression - -external var createPrefix: (operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken | SyntaxKind.ExclamationToken */, operand: Expression) -> PrefixUnaryExpression - -external var updatePrefix: (node: PrefixUnaryExpression, operand: Expression) -> PrefixUnaryExpression - -external var createPostfix: (operand: Expression, operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken */) -> PostfixUnaryExpression - -external var updatePostfix: (node: PostfixUnaryExpression, operand: Expression) -> PostfixUnaryExpression - -external var createBinary: (left: Expression, operator: dynamic /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression) -> BinaryExpression - -external var updateConditional: (node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression) -> ConditionalExpression - -external var createTemplateExpression: (head: TemplateHead, templateSpans: Array) -> TemplateExpression - -external var updateTemplateExpression: (node: TemplateExpression, head: TemplateHead, templateSpans: Array) -> TemplateExpression - -external object createTemplateHead { - @nativeInvoke - operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateHead - @nativeInvoke - operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateHead -} - -external object createTemplateMiddle { - @nativeInvoke - operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateMiddle - @nativeInvoke - operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateMiddle -} - -external object createTemplateTail { - @nativeInvoke - operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateTail - @nativeInvoke - operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateTail -} - -external object createNoSubstitutionTemplateLiteral { - @nativeInvoke - operator fun invoke(text: String, rawText: String? = definedExternally): NoSubstitutionTemplateLiteral - @nativeInvoke - operator fun invoke(text: String?, rawText: String): NoSubstitutionTemplateLiteral -} - -external var updateYield: (node: YieldExpression, asteriskToken: AsteriskToken?, expression: Expression?) -> YieldExpression - -external var createSpread: (expression: Expression) -> SpreadElement - -external var updateSpread: (node: SpreadElement, expression: Expression) -> SpreadElement - -external var createOmittedExpression: () -> OmittedExpression - -external var createAsExpression: (expression: Expression, type: TypeNode) -> AsExpression - -external var updateAsExpression: (node: AsExpression, expression: Expression, type: TypeNode) -> AsExpression - -external var createNonNullExpression: (expression: Expression) -> NonNullExpression - -external var updateNonNullExpression: (node: NonNullExpression, expression: Expression) -> NonNullExpression - -external var createNonNullChain: (expression: Expression) -> NonNullChain - -external var updateNonNullChain: (node: NonNullChain, expression: Expression) -> NonNullChain - -external var createMetaProperty: (keywordToken: dynamic /* SyntaxKind.ImportKeyword | SyntaxKind.NewKeyword */, name: Identifier) -> MetaProperty - -external var updateMetaProperty: (node: MetaProperty, name: Identifier) -> MetaProperty - -external var createTemplateSpan: (expression: Expression, literal: dynamic /* TemplateMiddle | TemplateTail */) -> TemplateSpan - -external var updateTemplateSpan: (node: TemplateSpan, expression: Expression, literal: dynamic /* TemplateMiddle | TemplateTail */) -> TemplateSpan - -external var createSemicolonClassElement: () -> SemicolonClassElement - -external var createBlock: (statements: Array, multiLine: Boolean?) -> Block - -external var updateBlock: (node: Block, statements: Array) -> Block - -external var createVariableStatement: (modifiers: Array?, declarationList: dynamic /* VariableDeclarationList | Array */) -> VariableStatement - -external var updateVariableStatement: (node: VariableStatement, modifiers: Array?, declarationList: VariableDeclarationList) -> VariableStatement - -external var createEmptyStatement: () -> EmptyStatement - -external var createExpressionStatement: (expression: Expression) -> ExpressionStatement - -external var updateExpressionStatement: (node: ExpressionStatement, expression: Expression) -> ExpressionStatement - -external var createStatement: (expression: Expression) -> ExpressionStatement - -external var updateStatement: (node: ExpressionStatement, expression: Expression) -> ExpressionStatement - -external var createIf: (expression: Expression, thenStatement: Statement, elseStatement: Statement?) -> IfStatement - -external var updateIf: (node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement?) -> IfStatement - -external var createDo: (statement: Statement, expression: Expression) -> DoStatement - -external var updateDo: (node: DoStatement, statement: Statement, expression: Expression) -> DoStatement - -external var createWhile: (expression: Expression, statement: Statement) -> WhileStatement - -external var updateWhile: (node: WhileStatement, expression: Expression, statement: Statement) -> WhileStatement - -external var createFor: (initializer: dynamic /* VariableDeclarationList? | Expression? */, condition: Expression?, incrementor: Expression?, statement: Statement) -> ForStatement - -external var updateFor: (node: ForStatement, initializer: dynamic /* VariableDeclarationList? | Expression? */, condition: Expression?, incrementor: Expression?, statement: Statement) -> ForStatement - -external var createForIn: (initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForInStatement - -external var updateForIn: (node: ForInStatement, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForInStatement - -external var createForOf: (awaitModifier: AwaitKeyword?, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForOfStatement - -external var updateForOf: (node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForOfStatement - -external var createContinue: (label: dynamic /* String? | Identifier? */) -> ContinueStatement - -external var updateContinue: (node: ContinueStatement, label: Identifier?) -> ContinueStatement - -external var createBreak: (label: dynamic /* String? | Identifier? */) -> BreakStatement - -external var updateBreak: (node: BreakStatement, label: Identifier?) -> BreakStatement - -external var createReturn: (expression: Expression?) -> ReturnStatement - -external var updateReturn: (node: ReturnStatement, expression: Expression?) -> ReturnStatement - -external var createWith: (expression: Expression, statement: Statement) -> WithStatement - -external var updateWith: (node: WithStatement, expression: Expression, statement: Statement) -> WithStatement - -external var createSwitch: (expression: Expression, caseBlock: CaseBlock) -> SwitchStatement - -external var updateSwitch: (node: SwitchStatement, expression: Expression, caseBlock: CaseBlock) -> SwitchStatement - -external var createLabel: (label: dynamic /* String | Identifier */, statement: Statement) -> LabeledStatement - -external var updateLabel: (node: LabeledStatement, label: Identifier, statement: Statement) -> LabeledStatement - -external var createThrow: (expression: Expression) -> ThrowStatement - -external var updateThrow: (node: ThrowStatement, expression: Expression) -> ThrowStatement - -external var createTry: (tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?) -> TryStatement - -external var updateTry: (node: TryStatement, tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?) -> TryStatement - -external var createDebuggerStatement: () -> DebuggerStatement - -external var createVariableDeclarationList: (declarations: Array, flags: NodeFlags?) -> VariableDeclarationList - -external var updateVariableDeclarationList: (node: VariableDeclarationList, declarations: Array) -> VariableDeclarationList - -external var createFunctionDeclaration: (decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> FunctionDeclaration - -external var updateFunctionDeclaration: (node: FunctionDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> FunctionDeclaration - -external var createClassDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassDeclaration - -external var updateClassDeclaration: (node: ClassDeclaration, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassDeclaration - -external var createInterfaceDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> InterfaceDeclaration - -external var updateInterfaceDeclaration: (node: InterfaceDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array) -> InterfaceDeclaration - -external var createTypeAliasDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, typeParameters: Array?, type: TypeNode) -> TypeAliasDeclaration - -external var updateTypeAliasDeclaration: (node: TypeAliasDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode) -> TypeAliasDeclaration - -external var createEnumDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, members: Array) -> EnumDeclaration - -external var updateEnumDeclaration: (node: EnumDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, members: Array) -> EnumDeclaration - -external var createModuleDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral */, body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */, flags: NodeFlags?) -> ModuleDeclaration - -external var updateModuleDeclaration: (node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral */, body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */) -> ModuleDeclaration - -external var createModuleBlock: (statements: Array) -> ModuleBlock - -external var updateModuleBlock: (node: ModuleBlock, statements: Array) -> ModuleBlock - -external var createCaseBlock: (clauses: Array) -> CaseBlock - -external var updateCaseBlock: (node: CaseBlock, clauses: Array) -> CaseBlock - -external var createNamespaceExportDeclaration: (name: dynamic /* String | Identifier */) -> NamespaceExportDeclaration - -external var updateNamespaceExportDeclaration: (node: NamespaceExportDeclaration, name: Identifier) -> NamespaceExportDeclaration - -external var createImportEqualsDeclaration: (decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: dynamic /* String | Identifier */, moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */) -> ImportEqualsDeclaration - -external var updateImportEqualsDeclaration: (node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */) -> ImportEqualsDeclaration - -external var createImportDeclaration: (decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression) -> ImportDeclaration - -external var updateImportDeclaration: (node: ImportDeclaration, decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression) -> ImportDeclaration - -external var createNamespaceImport: (name: Identifier) -> NamespaceImport - -external var updateNamespaceImport: (node: NamespaceImport, name: Identifier) -> NamespaceImport - -external var createNamedImports: (elements: Array) -> NamedImports - -external var updateNamedImports: (node: NamedImports, elements: Array) -> NamedImports - -external var createImportSpecifier: (propertyName: Identifier?, name: Identifier) -> ImportSpecifier - -external var updateImportSpecifier: (node: ImportSpecifier, propertyName: Identifier?, name: Identifier) -> ImportSpecifier - -external var createExportAssignment: (decorators: Array?, modifiers: Array?, isExportEquals: Boolean?, expression: Expression) -> ExportAssignment - -external var updateExportAssignment: (node: ExportAssignment, decorators: Array?, modifiers: Array?, expression: Expression) -> ExportAssignment - -external var createNamedExports: (elements: Array) -> NamedExports - -external var updateNamedExports: (node: NamedExports, elements: Array) -> NamedExports - -external var createExportSpecifier: (propertyName: dynamic /* String? | Identifier? */, name: dynamic /* String | Identifier */) -> ExportSpecifier - -external var updateExportSpecifier: (node: ExportSpecifier, propertyName: Identifier?, name: Identifier) -> ExportSpecifier - -external var createExternalModuleReference: (expression: Expression) -> ExternalModuleReference - -external var updateExternalModuleReference: (node: ExternalModuleReference, expression: Expression) -> ExternalModuleReference - -external var createJSDocTypeExpression: (type: TypeNode) -> JSDocTypeExpression - -external var createJSDocTypeTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocTypeTag - -external var createJSDocReturnTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: dynamic /* String? | NodeArray? */) -> JSDocReturnTag - -external var createJSDocThisTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocThisTag - -external var createJSDocComment: (comment: dynamic /* String? | NodeArray? */, tags: Array?) -> JSDoc - -external var createJSDocParameterTag: (tagName: Identifier?, name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean?, comment: dynamic /* String? | NodeArray? */) -> JSDocParameterTag - -external var createJSDocClassTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocClassTag - -external var createJSDocAugmentsTag: (tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: dynamic /* String? | NodeArray? */) -> JSDocAugmentsTag - -external var createJSDocEnumTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocEnumTag - -external var createJSDocTemplateTag: (tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: dynamic /* String? | NodeArray? */) -> JSDocTemplateTag - -external var createJSDocTypedefTag: (tagName: Identifier?, typeExpression: dynamic /* JSDocTypeLiteral? | JSDocTypeExpression? */, fullName: dynamic /* Identifier? | JSDocNamespaceDeclaration? */, comment: dynamic /* String? | NodeArray? */) -> JSDocTypedefTag - -external var createJSDocCallbackTag: (tagName: Identifier?, typeExpression: JSDocSignature, fullName: dynamic /* Identifier? | JSDocNamespaceDeclaration? */, comment: dynamic /* String? | NodeArray? */) -> JSDocCallbackTag - -external var createJSDocSignature: (typeParameters: Array?, parameters: Array, type: JSDocReturnTag?) -> JSDocSignature - -external var createJSDocPropertyTag: (tagName: Identifier?, name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean?, comment: dynamic /* String? | NodeArray? */) -> JSDocPropertyTag - -external var createJSDocTypeLiteral: (jsDocPropertyTags: Array?, isArrayType: Boolean?) -> JSDocTypeLiteral - -external var createJSDocImplementsTag: (tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: dynamic /* String? | NodeArray? */) -> JSDocImplementsTag - -external var createJSDocAuthorTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocAuthorTag - -external var createJSDocPublicTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocPublicTag - -external var createJSDocPrivateTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocPrivateTag - -external var createJSDocProtectedTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocProtectedTag - -external var createJSDocReadonlyTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocReadonlyTag - -external var createJSDocTag: (tagName: Identifier, comment: dynamic /* String? | NodeArray? */) -> JSDocUnknownTag - -external var createJsxElement: (openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement) -> JsxElement - -external var updateJsxElement: (node: JsxElement, openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement) -> JsxElement - -external var createJsxSelfClosingElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxSelfClosingElement - -external var updateJsxSelfClosingElement: (node: JsxSelfClosingElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxSelfClosingElement - -external var createJsxOpeningElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxOpeningElement - -external var updateJsxOpeningElement: (node: JsxOpeningElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxOpeningElement - -external var createJsxClosingElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */) -> JsxClosingElement - -external var updateJsxClosingElement: (node: JsxClosingElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */) -> JsxClosingElement - -external var createJsxFragment: (openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment) -> JsxFragment - -external var createJsxText: (text: String, containsOnlyTriviaWhiteSpaces: Boolean?) -> JsxText - -external var updateJsxText: (node: JsxText, text: String, containsOnlyTriviaWhiteSpaces: Boolean?) -> JsxText - -external var createJsxOpeningFragment: () -> JsxOpeningFragment - -external var createJsxJsxClosingFragment: () -> JsxClosingFragment - -external var updateJsxFragment: (node: JsxFragment, openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment) -> JsxFragment - -external var createJsxAttribute: (name: Identifier, initializer: dynamic /* StringLiteral? | JsxExpression? */) -> JsxAttribute - -external var updateJsxAttribute: (node: JsxAttribute, name: Identifier, initializer: dynamic /* StringLiteral? | JsxExpression? */) -> JsxAttribute - -external var createJsxAttributes: (properties: Array) -> JsxAttributes - -external var updateJsxAttributes: (node: JsxAttributes, properties: Array) -> JsxAttributes - -external var createJsxSpreadAttribute: (expression: Expression) -> JsxSpreadAttribute - -external var updateJsxSpreadAttribute: (node: JsxSpreadAttribute, expression: Expression) -> JsxSpreadAttribute - -external var createJsxExpression: (dotDotDotToken: DotDotDotToken?, expression: Expression?) -> JsxExpression - -external var updateJsxExpression: (node: JsxExpression, expression: Expression?) -> JsxExpression - -external var createCaseClause: (expression: Expression, statements: Array) -> CaseClause - -external var updateCaseClause: (node: CaseClause, expression: Expression, statements: Array) -> CaseClause - -external var createDefaultClause: (statements: Array) -> DefaultClause - -external var updateDefaultClause: (node: DefaultClause, statements: Array) -> DefaultClause - -external var createHeritageClause: (token: dynamic /* SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword */, types: Array) -> HeritageClause - -external var updateHeritageClause: (node: HeritageClause, types: Array) -> HeritageClause - -external var createCatchClause: (variableDeclaration: dynamic /* String? | VariableDeclaration? */, block: Block) -> CatchClause - -external var updateCatchClause: (node: CatchClause, variableDeclaration: VariableDeclaration?, block: Block) -> CatchClause - -external var createPropertyAssignment: (name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression) -> PropertyAssignment - -external var updatePropertyAssignment: (node: PropertyAssignment, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression) -> PropertyAssignment - -external var createShorthandPropertyAssignment: (name: dynamic /* String | Identifier */, objectAssignmentInitializer: Expression?) -> ShorthandPropertyAssignment - -external var updateShorthandPropertyAssignment: (node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression?) -> ShorthandPropertyAssignment - -external var createSpreadAssignment: (expression: Expression) -> SpreadAssignment - -external var updateSpreadAssignment: (node: SpreadAssignment, expression: Expression) -> SpreadAssignment - -external var createEnumMember: (name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression?) -> EnumMember - -external var updateEnumMember: (node: EnumMember, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression?) -> EnumMember - -external var updateSourceFileNode: (node: SourceFile, statements: Array, isDeclarationFile: Boolean?, referencedFiles: Array?, typeReferences: Array?, hasNoDefaultLib: Boolean?, libReferences: Array?) -> SourceFile - -external var createNotEmittedStatement: (original: Node) -> NotEmittedStatement - -external var createPartiallyEmittedExpression: (expression: Expression, original: Node?) -> PartiallyEmittedExpression - -external var updatePartiallyEmittedExpression: (node: PartiallyEmittedExpression, expression: Expression) -> PartiallyEmittedExpression - -external var createCommaList: (elements: Array) -> CommaListExpression - -external var updateCommaList: (node: CommaListExpression, elements: Array) -> CommaListExpression - -external var createBundle: (sourceFiles: Array, prepends: Array?) -> Bundle - -external var updateBundle: (node: Bundle, sourceFiles: Array, prepends: Array?) -> Bundle - -external object createImmediatelyInvokedFunctionExpression { - @nativeInvoke - operator fun invoke(statements: Array): CallExpression - @nativeInvoke - operator fun invoke(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression -} - -external object createImmediatelyInvokedArrowFunction { - @nativeInvoke - operator fun invoke(statements: Array): CallExpression - @nativeInvoke - operator fun invoke(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression -} - -external var createVoidZero: () -> VoidExpression - -external var createExportDefault: (expression: Expression) -> ExportAssignment - -external var createExternalModuleExport: (exportName: Identifier) -> ExportDeclaration - -external var createNamespaceExport: (name: Identifier) -> NamespaceExport - -external var updateNamespaceExport: (node: NamespaceExport, name: Identifier) -> NamespaceExport - -external var createToken: (kind: TKind) -> Token - -external var createIdentifier: (text: String) -> Identifier - -external var createTempVariable: (recordTempVariable: ((node: Identifier) -> Unit)?) -> Identifier - -external var getGeneratedNameForNode: (node: Node?) -> Identifier - -external var createOptimisticUniqueName: (text: String) -> Identifier - -external var createFileLevelUniqueName: (text: String) -> Identifier - -external var createIndexSignature: (decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode) -> IndexSignatureDeclaration - -external var createTypePredicateNode: (parameterName: dynamic /* Identifier | ThisTypeNode | String */, type: TypeNode) -> TypePredicateNode - -external var updateTypePredicateNode: (node: TypePredicateNode, parameterName: dynamic /* Identifier | ThisTypeNode */, type: TypeNode) -> TypePredicateNode - -external object createLiteral { - @nativeInvoke - operator fun invoke(value: Any /* String | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier */): StringLiteral - @nativeInvoke - operator fun invoke(value: Any /* Number | PseudoBigInt */): NumericLiteral - @nativeInvoke - operator fun invoke(value: Boolean): dynamic /* TrueLiteral | FalseLiteral */ - @nativeInvoke - operator fun invoke(value: Any /* String | Number | PseudoBigInt | Boolean */): PrimaryExpression -} - -external var createMethodSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?) -> MethodSignature - -external var updateMethodSignature: (node: MethodSignature, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?) -> MethodSignature - -external object createTypeOperatorNode { - @nativeInvoke - operator fun invoke(type: TypeNode): TypeOperatorNode - @nativeInvoke - operator fun invoke(operator: Any /* SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword */, type: TypeNode): TypeOperatorNode -} - -external object createTaggedTemplate { - @nativeInvoke - operator fun invoke(tag: Expression, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression - @nativeInvoke - operator fun invoke(tag: Expression, typeArguments: Array?, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression -} - -external object updateTaggedTemplate { - @nativeInvoke - operator fun invoke(node: TaggedTemplateExpression, tag: Expression, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression - @nativeInvoke - operator fun invoke(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression -} - -external var updateBinary: (node: BinaryExpression, left: Expression, right: Expression, operator: dynamic /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */) -> BinaryExpression - -external object createConditional { - @nativeInvoke - operator fun invoke(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression - @nativeInvoke - operator fun invoke(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression -} - -external object createYield { - @nativeInvoke - operator fun invoke(expression: Expression? = definedExternally): YieldExpression - @nativeInvoke - operator fun invoke(asteriskToken: AsteriskToken?, expression: Expression): YieldExpression -} - -external var createClassExpression: (modifiers: Array?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassExpression - -external var updateClassExpression: (node: ClassExpression, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassExpression - -external var createPropertySignature: (modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | String */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> PropertySignature - -external var updatePropertySignature: (node: PropertySignature, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> PropertySignature - -external var createExpressionWithTypeArguments: (typeArguments: Array?, expression: Expression) -> ExpressionWithTypeArguments - -external var updateExpressionWithTypeArguments: (node: ExpressionWithTypeArguments, typeArguments: Array?, expression: Expression) -> ExpressionWithTypeArguments - -external object createArrowFunction { - @nativeInvoke - operator fun invoke(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: Any /* FunctionBody | Expression */): ArrowFunction - @nativeInvoke - operator fun invoke(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Any /* FunctionBody | Expression */): ArrowFunction -} - -external object updateArrowFunction { - @nativeInvoke - operator fun invoke(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: Any /* FunctionBody | Expression */): ArrowFunction - @nativeInvoke - operator fun invoke(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Any /* FunctionBody | Expression */): ArrowFunction -} - -external object createVariableDeclaration { - @nativeInvoke - operator fun invoke(name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, type: TypeNode? = definedExternally, initializer: Expression? = definedExternally): VariableDeclaration - @nativeInvoke - operator fun invoke(name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration -} - -external object updateVariableDeclaration { - @nativeInvoke - operator fun invoke(node: VariableDeclaration, name: Any /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, type: TypeNode?, initializer: Expression?): VariableDeclaration - @nativeInvoke - operator fun invoke(node: VariableDeclaration, name: Any /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration -} - -external var createImportClause: (name: Identifier?, namedBindings: dynamic /* NamespaceImport? | NamedImports? */, isTypeOnly: Any) -> ImportClause - -external var updateImportClause: (node: ImportClause, name: Identifier?, namedBindings: dynamic /* NamespaceImport? | NamedImports? */, isTypeOnly: Boolean) -> ImportClause - -external var createExportDeclaration: (decorators: Array?, modifiers: Array?, exportClause: dynamic /* NamespaceExport? | NamedExports? */, moduleSpecifier: Expression?, isTypeOnly: Any) -> ExportDeclaration - -external var updateExportDeclaration: (node: ExportDeclaration, decorators: Array?, modifiers: Array?, exportClause: dynamic /* NamespaceExport? | NamedExports? */, moduleSpecifier: Expression?, isTypeOnly: Boolean) -> ExportDeclaration - -external var createJSDocParamTag: (name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, comment: String?) -> JSDocParameterTag - -external var createComma: (left: Expression, right: Expression) -> Expression - -external var createLessThan: (left: Expression, right: Expression) -> Expression - -external var createAssignment: (left: Expression, right: Expression) -> BinaryExpression - -external var createStrictEquality: (left: Expression, right: Expression) -> BinaryExpression - -external var createStrictInequality: (left: Expression, right: Expression) -> BinaryExpression - -external var createAdd: (left: Expression, right: Expression) -> BinaryExpression - -external var createSubtract: (left: Expression, right: Expression) -> BinaryExpression - -external var createLogicalAnd: (left: Expression, right: Expression) -> BinaryExpression - -external var createLogicalOr: (left: Expression, right: Expression) -> BinaryExpression - -external var createPostfixIncrement: (operand: Expression) -> PostfixUnaryExpression - -external var createLogicalNot: (operand: Expression) -> PrefixUnaryExpression - -external var createNode: (kind: SyntaxKind, pos: Any, end: Any) -> Node - -external var getMutableClone: (node: T) -> T - -external var isTypeAssertion: (node: Node) -> Boolean - -external var isIdentifierOrPrivateIdentifier: (node: Node) -> Boolean \ No newline at end of file diff --git a/externals/typescript.ts.server.module_typescript.kt b/externals/typescript.ts.server.module_typescript.kt deleted file mode 100644 index 5a84cb3..0000000 --- a/externals/typescript.ts.server.module_typescript.kt +++ /dev/null @@ -1,101 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package ts.server - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.CompilerOptions -import ts.WatchOptions -import ts.TypeAcquisition -import ts.SortedReadonlyArray - -external interface TypingInstallerResponse { - val kind: String /* "action::set" | "action::invalidate" | "event::typesRegistry" | "action::packageInstalled" | "event::beginInstallTypes" | "event::endInstallTypes" | "event::initializationFailed" */ -} - -external interface TypingInstallerRequestWithProjectName { - val projectName: String -} - -external interface DiscoverTypings : TypingInstallerRequestWithProjectName { - val fileNames: Array - val projectRootPath: String /* String & `T$3` */ - val compilerOptions: CompilerOptions - val watchOptions: WatchOptions? - get() = definedExternally - val typeAcquisition: TypeAcquisition - val unresolvedImports: SortedReadonlyArray - val cachePath: String? - get() = definedExternally - val kind: String /* "discover" */ -} - -external interface CloseProject : TypingInstallerRequestWithProjectName { - val kind: String /* "closeProject" */ -} - -external interface TypesRegistryRequest { - val kind: String /* "typesRegistry" */ -} - -external interface InstallPackageRequest : TypingInstallerRequestWithProjectName { - val kind: String /* "installPackage" */ - val fileName: String /* String & `T$3` */ - val packageName: String - val projectRootPath: String /* String & `T$3` */ -} - -external interface PackageInstalledResponse : ProjectResponse { - override val kind: String /* "action::packageInstalled" */ - val success: Boolean - val message: String -} - -external interface InitializationFailedResponse : TypingInstallerResponse { - override val kind: String /* "event::initializationFailed" */ - val message: String - val stack: String? - get() = definedExternally -} - -external interface ProjectResponse : TypingInstallerResponse { - val projectName: String -} - -external interface InvalidateCachedTypings : ProjectResponse { - override val kind: String /* "action::invalidate" */ -} - -external interface InstallTypes : ProjectResponse { - override val kind: String /* "event::beginInstallTypes" | "event::endInstallTypes" */ - val eventId: Number - val typingsInstallerVersion: String - val packagesToInstall: Array -} - -external interface BeginInstallTypes : InstallTypes { - override val kind: String /* "event::beginInstallTypes" */ -} - -external interface EndInstallTypes : InstallTypes { - override val kind: String /* "event::endInstallTypes" */ - val installSuccess: Boolean -} - -external interface SetTypings : ProjectResponse { - val typeAcquisition: TypeAcquisition - val compilerOptions: CompilerOptions - val typings: Array - val unresolvedImports: SortedReadonlyArray - override val kind: String /* "action::set" */ -} \ No newline at end of file diff --git a/externals/utils.module_typescript-to-lua.kt b/externals/utils.module_typescript-to-lua.kt deleted file mode 100644 index 08363d8..0000000 --- a/externals/utils.module_typescript-to-lua.kt +++ /dev/null @@ -1,46 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.WriteFileCallback -import ts.SourceFile - -external interface EmitHost { - fun directoryExists(path: String): Boolean - fun fileExists(path: String): Boolean - fun getCurrentDirectory(): String - fun readFile(path: String): String? - var writeFile: WriteFileCallback -} - -external interface BaseFile { - var code: String - var sourceMap: String? - get() = definedExternally - set(value) = definedExternally - var sourceFiles: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface ProcessedFile : BaseFile { - var fileName: String - var luaAst: File? - get() = definedExternally - set(value) = definedExternally -} - -external interface EmitFile : BaseFile { - var outputPath: String -} \ No newline at end of file diff --git a/externals/visitors.module_typescript-to-lua.kt b/externals/visitors.module_typescript-to-lua.kt deleted file mode 100644 index 69513ac..0000000 --- a/externals/visitors.module_typescript-to-lua.kt +++ /dev/null @@ -1,38 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.Statement -import ts.Node -import tsstdlib.Map -import ts.SyntaxKind - -external interface NodesBySyntaxKind - -typealias StatementLikeNode = Statement - -typealias VisitorResult = Any - -typealias FunctionVisitor = (node: T, context: TransformationContext) -> VisitorResult - -external interface ObjectVisitor { - var transform: FunctionVisitor - var priority: Number? - get() = definedExternally - set(value) = definedExternally -} - -typealias Visitors = Any - -typealias VisitorMap = Map>> \ No newline at end of file diff --git a/externals02/CompilerOptions.module_typescript-to-lua.kt b/externals02/CompilerOptions.module_typescript-to-lua.kt deleted file mode 100644 index 2c781b3..0000000 --- a/externals02/CompilerOptions.module_typescript-to-lua.kt +++ /dev/null @@ -1,82 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.Diagnostic - -//typealias OmitIndexSignature = Any - -external interface TransformerImport { - var transform: String - var import: String? - get() = definedExternally - set(value) = definedExternally - var after: Boolean? - get() = definedExternally - set(value) = definedExternally - var afterDeclarations: Boolean? - get() = definedExternally - set(value) = definedExternally - var type: String? /* "program" | "config" | "checker" | "raw" | "compilerOptions" */ - get() = definedExternally - set(value) = definedExternally -} - -@Suppress("NOTHING_TO_INLINE") -inline operator fun TransformerImport.get(option: String): Any? = asDynamic()[option] - -@Suppress("NOTHING_TO_INLINE") -inline operator fun TransformerImport.set(option: String, value: Any) { - asDynamic()[option] = value -} - -external interface LuaPluginImport { - var name: String - var import: String? - get() = definedExternally - set(value) = definedExternally -} - -@Suppress("NOTHING_TO_INLINE") -inline operator fun LuaPluginImport.get(option: String): Any? = asDynamic()[option] - -@Suppress("NOTHING_TO_INLINE") -inline operator fun LuaPluginImport.set(option: String, value: Any) { - asDynamic()[option] = value -} - -external enum class LuaLibImportKind { - None /* = "none" */, - Always /* = "always" */, - Inline /* = "inline" */, - Require /* = "require" */ -} - -external enum class LuaTarget { - Universal /* = "universal" */, - Lua51 /* = "5.1" */, - Lua52 /* = "5.2" */, - Lua53 /* = "5.3" */, - Lua54 /* = "5.4" */, - LuaJIT /* = "JIT" */ -} - -external enum class BuildMode { - Default /* = "default" */, - Library /* = "library" */ -} - -external var isBundleEnabled: (options: dynamic /* typealias OmitIndexSignature = dynamic */) -> Boolean - -external fun validateOptions(options: dynamic /* typealias OmitIndexSignature = dynamic */): Array \ No newline at end of file diff --git a/externals02/LuaAST.module_typescript-to-lua.kt b/externals02/LuaAST.module_typescript-to-lua.kt deleted file mode 100644 index 35d07fb..0000000 --- a/externals02/LuaAST.module_typescript-to-lua.kt +++ /dev/null @@ -1,473 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import tsstdlib.Set - -external enum class SyntaxKind { - File /* = 0 */, - Block /* = 1 */, - DoStatement /* = 2 */, - VariableDeclarationStatement /* = 3 */, - AssignmentStatement /* = 4 */, - IfStatement /* = 5 */, - WhileStatement /* = 6 */, - RepeatStatement /* = 7 */, - ForStatement /* = 8 */, - ForInStatement /* = 9 */, - GotoStatement /* = 10 */, - LabelStatement /* = 11 */, - ReturnStatement /* = 12 */, - BreakStatement /* = 13 */, - ExpressionStatement /* = 14 */, - StringLiteral /* = 15 */, - NumericLiteral /* = 16 */, - NilKeyword /* = 17 */, - DotsKeyword /* = 18 */, - TrueKeyword /* = 19 */, - FalseKeyword /* = 20 */, - FunctionExpression /* = 21 */, - TableFieldExpression /* = 22 */, - TableExpression /* = 23 */, - UnaryExpression /* = 24 */, - BinaryExpression /* = 25 */, - CallExpression /* = 26 */, - MethodCallExpression /* = 27 */, - Identifier /* = 28 */, - TableIndexExpression /* = 29 */, - AdditionOperator /* = 30 */, - SubtractionOperator /* = 31 */, - MultiplicationOperator /* = 32 */, - DivisionOperator /* = 33 */, - FloorDivisionOperator /* = 34 */, - ModuloOperator /* = 35 */, - PowerOperator /* = 36 */, - NegationOperator /* = 37 */, - ConcatOperator /* = 38 */, - LengthOperator /* = 39 */, - EqualityOperator /* = 40 */, - InequalityOperator /* = 41 */, - LessThanOperator /* = 42 */, - LessEqualOperator /* = 43 */, - GreaterThanOperator /* = 44 */, - GreaterEqualOperator /* = 45 */, - AndOperator /* = 46 */, - OrOperator /* = 47 */, - NotOperator /* = 48 */, - BitwiseAndOperator /* = 49 */, - BitwiseOrOperator /* = 50 */, - BitwiseExclusiveOrOperator /* = 51 */, - BitwiseRightShiftOperator /* = 52 */, - BitwiseLeftShiftOperator /* = 53 */, - BitwiseNotOperator /* = 54 */ -} - -//typealias UnaryBitwiseOperator = SyntaxKind.BitwiseNotOperator - -external interface TextRange { - var line: Number? - get() = definedExternally - set(value) = definedExternally - var column: Number? - get() = definedExternally - set(value) = definedExternally -} - -external interface Node : TextRange { - var kind: SyntaxKind -} - -external fun createNode(kind: SyntaxKind, tsOriginal: ts.Node = definedExternally): Node - -external fun cloneNode(node: T): T - -external fun setNodePosition(node: T, position: TextRange): T - -external fun setNodeOriginal(node: T, tsOriginal: ts.Node): T - -external fun setNodeOriginal(node: T?, tsOriginal: ts.Node): T? - -external fun getOriginalPos(node: Node): TextRange - -external interface File : Node { - var statements: Array - var luaLibFeatures: Set - var trivia: String -} - -external fun isFile(node: Node): Boolean - -external fun createFile(statements: Array, luaLibFeatures: Set, trivia: String, tsOriginal: ts.Node = definedExternally): File - -external interface Block : Node { - var statements: Array -} - -external fun isBlock(node: Node): Boolean - -external fun createBlock(statements: Array, tsOriginal: ts.Node = definedExternally): Block - -external interface Statement : Node { - var _statementBrand: Any - var leadingComments: Array */>? - get() = definedExternally - set(value) = definedExternally - var trailingComments: Array */>? - get() = definedExternally - set(value) = definedExternally -} - -external interface DoStatement : Statement { - var statements: Array -} - -external fun isDoStatement(node: Node): Boolean - -external fun createDoStatement(statements: Array, tsOriginal: ts.Node = definedExternally): DoStatement - -external interface VariableDeclarationStatement : Statement { - var left: Array - var right: Array? - get() = definedExternally - set(value) = definedExternally -} - -external fun isVariableDeclarationStatement(node: Node): Boolean - -external fun createVariableDeclarationStatement(left: Identifier, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Identifier): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Identifier, right: Expression = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Identifier, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Identifier, right: Array = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array, right: Expression = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array, right: Array = definedExternally): VariableDeclarationStatement - -external interface AssignmentStatement : Statement { - var left: Array - var right: Array -} - -external fun isAssignmentStatement(node: Node): Boolean - -external fun createAssignmentStatement(left: Identifier, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Identifier): AssignmentStatement - -external fun createAssignmentStatement(left: Identifier, right: Expression = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Identifier, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Identifier, right: Array = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression, right: Expression = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression, right: Array = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Array, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Array): AssignmentStatement - -external fun createAssignmentStatement(left: Array, right: Expression = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Array, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Array, right: Array = definedExternally): AssignmentStatement - -external interface IfStatement : Statement { - var condition: Expression - var ifBlock: Block - var elseBlock: dynamic /* Block? | IfStatement? */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isIfStatement(node: Node): Boolean - -external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: Block = definedExternally, tsOriginal: ts.Node = definedExternally): IfStatement - -external fun createIfStatement(condition: Expression, ifBlock: Block): IfStatement - -external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: Block = definedExternally): IfStatement - -external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: IfStatement = definedExternally, tsOriginal: ts.Node = definedExternally): IfStatement - -external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: IfStatement = definedExternally): IfStatement - -external interface IterationStatement : Statement { - var body: Block -} - -external fun isIterationStatement(node: Node): Boolean - -external interface WhileStatement : IterationStatement { - var condition: Expression -} - -external fun isWhileStatement(node: Node): Boolean - -external fun createWhileStatement(body: Block, condition: Expression, tsOriginal: ts.Node = definedExternally): WhileStatement - -external interface RepeatStatement : IterationStatement { - var condition: Expression -} - -external fun isRepeatStatement(node: Node): Boolean - -external fun createRepeatStatement(body: Block, condition: Expression, tsOriginal: ts.Node = definedExternally): RepeatStatement - -external interface ForStatement : IterationStatement { - var controlVariable: Identifier - var controlVariableInitializer: Expression - var limitExpression: Expression - var stepExpression: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external fun isForStatement(node: Node): Boolean - -external fun createForStatement(body: Block, controlVariable: Identifier, controlVariableInitializer: Expression, limitExpression: Expression, stepExpression: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): ForStatement - -external interface ForInStatement : IterationStatement { - var names: Array - var expressions: Array -} - -external fun isForInStatement(node: Node): Boolean - -external fun createForInStatement(body: Block, names: Array, expressions: Array, tsOriginal: ts.Node = definedExternally): ForInStatement - -external interface GotoStatement : Statement { - var label: String -} - -external fun isGotoStatement(node: Node): Boolean - -external fun createGotoStatement(label: String, tsOriginal: ts.Node = definedExternally): GotoStatement - -external interface LabelStatement : Statement { - var name: String -} - -external fun isLabelStatement(node: Node): Boolean - -external fun createLabelStatement(name: String, tsOriginal: ts.Node = definedExternally): LabelStatement - -external interface ReturnStatement : Statement { - var expressions: Array -} - -external fun isReturnStatement(node: Node): Boolean - -external fun createReturnStatement(expressions: Array, tsOriginal: ts.Node = definedExternally): ReturnStatement - -external interface BreakStatement : Statement - -external fun isBreakStatement(node: Node): Boolean - -external fun createBreakStatement(tsOriginal: ts.Node = definedExternally): BreakStatement - -external interface ExpressionStatement : Statement { - var expression: Expression -} - -external fun isExpressionStatement(node: Node): Boolean - -external fun createExpressionStatement(expressions: Expression, tsOriginal: ts.Node = definedExternally): ExpressionStatement - -external interface Expression : Node { - var _expressionBrand: Any -} - -external interface NilLiteral : Expression - -external fun isNilLiteral(node: Node): Boolean - -external fun createNilLiteral(tsOriginal: ts.Node = definedExternally): NilLiteral - -external interface BooleanLiteral : Expression { - override var kind: dynamic /* SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isBooleanLiteral(node: Node): Boolean - -external fun createBooleanLiteral(value: Boolean, tsOriginal: ts.Node = definedExternally): BooleanLiteral - -external interface DotsLiteral : Expression - -external fun isDotsLiteral(node: Node): Boolean - -external fun createDotsLiteral(tsOriginal: ts.Node = definedExternally): DotsLiteral - -external interface NumericLiteral : Expression { - var value: Number -} - -external fun isNumericLiteral(node: Node): Boolean - -external fun createNumericLiteral(value: Number, tsOriginal: ts.Node = definedExternally): NumericLiteral - -external interface StringLiteral : Expression { - var value: String -} - -external fun isStringLiteral(node: Node): Boolean - -external fun createStringLiteral(value: String, tsOriginal: ts.Node = definedExternally): StringLiteral - -external enum class FunctionExpressionFlags { - None /* = 1 */, - Inline /* = 2 */, - Declaration /* = 4 */ -} - -external interface FunctionExpression : Expression { - var params: Array? - get() = definedExternally - set(value) = definedExternally - var dots: DotsLiteral? - get() = definedExternally - set(value) = definedExternally - var body: Block - var flags: FunctionExpressionFlags -} - -external fun isFunctionExpression(node: Node): Boolean - -external fun createFunctionExpression(body: Block, params: Array = definedExternally, dots: DotsLiteral = definedExternally, flags: FunctionExpressionFlags = definedExternally, tsOriginal: ts.Node = definedExternally): FunctionExpression - -external interface TableFieldExpression : Expression { - var value: Expression - var key: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external fun isTableFieldExpression(node: Node): Boolean - -external fun createTableFieldExpression(value: Expression, key: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): TableFieldExpression - -external interface TableExpression : Expression { - var fields: Array -} - -external fun isTableExpression(node: Node): Boolean - -external fun createTableExpression(fields: Array = definedExternally, tsOriginal: ts.Node = definedExternally): TableExpression - -external interface UnaryExpression : Expression { - var operand: Expression - var operator: dynamic /* SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isUnaryExpression(node: Node): Boolean - -external fun createUnaryExpression(operand: Expression, operator: dynamic, tsOriginal: ts.Node = definedExternally): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: dynamic): UnaryExpression - -external interface BinaryExpression : Expression { - var operator: dynamic /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */ - get() = definedExternally - set(value) = definedExternally - var left: Expression - var right: Expression -} - -external fun isBinaryExpression(node: Node): Boolean - -external fun createBinaryExpression(left: Expression, right: Expression, operator: Any /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */, tsOriginal: ts.Node = definedExternally): BinaryExpression - -external interface CallExpression : Expression { - var expression: Expression - var params: Array -} - -external fun isCallExpression(node: Node): Boolean - -external fun createCallExpression(expression: Expression, params: Array, tsOriginal: ts.Node = definedExternally): CallExpression - -external interface MethodCallExpression : Expression { - var prefixExpression: Expression - var name: Identifier - var params: Array -} - -external fun isMethodCallExpression(node: Node): Boolean - -external fun createMethodCallExpression(prefixExpression: Expression, name: Identifier, params: Array, tsOriginal: ts.Node = definedExternally): MethodCallExpression - -external interface Identifier : Expression { - var exportable: Boolean? - var text: String - var originalName: String? - get() = definedExternally - set(value) = definedExternally - var symbolId: Number? /* Number? & `T$14`? */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isIdentifier(node: Node): Boolean - -external fun createIdentifier(text: String, tsOriginal: ts.Node = definedExternally, symbolId: Number /* Number & `T$14` */ = definedExternally, originalName: String = definedExternally): Identifier - -external fun cloneIdentifier(identifier: Identifier, tsOriginal: ts.Node = definedExternally): Identifier - -external fun createAnonymousIdentifier(tsOriginal: ts.Node = definedExternally): Identifier - -external interface TableIndexExpression : Expression { - var table: Expression - var index: Expression -} - -external fun isTableIndexExpression(node: Node): Boolean - -external fun createTableIndexExpression(table: Expression, index: Expression, tsOriginal: ts.Node = definedExternally): TableIndexExpression - -external fun isAssignmentLeftHandSideExpression(node: Node): Boolean - -external fun isFunctionDefinition(statement: VariableDeclarationStatement): Boolean - -external fun isFunctionDefinition(statement: AssignmentStatement): Boolean - -external interface `T$17` { - var statements: dynamic /* JsTuple */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isInlineFunctionExpression(expression: FunctionExpression): Boolean \ No newline at end of file diff --git a/externals02/LuaLib.module_typescript-to-lua.kt b/externals02/LuaLib.module_typescript-to-lua.kt deleted file mode 100644 index f00c242..0000000 --- a/externals02/LuaLib.module_typescript-to-lua.kt +++ /dev/null @@ -1,111 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external enum class LuaLibFeature { - ArrayConcat /* = "ArrayConcat" */, - ArrayEntries /* = "ArrayEntries" */, - ArrayEvery /* = "ArrayEvery" */, - ArrayFilter /* = "ArrayFilter" */, - ArrayForEach /* = "ArrayForEach" */, - ArrayFind /* = "ArrayFind" */, - ArrayFindIndex /* = "ArrayFindIndex" */, - ArrayIncludes /* = "ArrayIncludes" */, - ArrayIndexOf /* = "ArrayIndexOf" */, - ArrayIsArray /* = "ArrayIsArray" */, - ArrayJoin /* = "ArrayJoin" */, - ArrayMap /* = "ArrayMap" */, - ArrayPush /* = "ArrayPush" */, - ArrayReduce /* = "ArrayReduce" */, - ArrayReduceRight /* = "ArrayReduceRight" */, - ArrayReverse /* = "ArrayReverse" */, - ArrayShift /* = "ArrayShift" */, - ArrayUnshift /* = "ArrayUnshift" */, - ArraySort /* = "ArraySort" */, - ArraySlice /* = "ArraySlice" */, - ArraySome /* = "ArraySome" */, - ArraySplice /* = "ArraySplice" */, - ArrayToObject /* = "ArrayToObject" */, - ArrayFlat /* = "ArrayFlat" */, - ArrayFlatMap /* = "ArrayFlatMap" */, - ArraySetLength /* = "ArraySetLength" */, - Await /* = "Await" */, - Class /* = "Class" */, - ClassExtends /* = "ClassExtends" */, - CloneDescriptor /* = "CloneDescriptor" */, - Decorate /* = "Decorate" */, - DecorateParam /* = "DecorateParam" */, - Delete /* = "Delete" */, - DelegatedYield /* = "DelegatedYield" */, - Error /* = "Error" */, - FunctionBind /* = "FunctionBind" */, - Generator /* = "Generator" */, - InstanceOf /* = "InstanceOf" */, - InstanceOfObject /* = "InstanceOfObject" */, - Iterator /* = "Iterator" */, - Map /* = "Map" */, - MathAtan2 /* = "MathAtan2" */, - New /* = "New" */, - Number /* = "Number" */, - NumberIsFinite /* = "NumberIsFinite" */, - NumberIsNaN /* = "NumberIsNaN" */, - NumberToString /* = "NumberToString" */, - ObjectAssign /* = "ObjectAssign" */, - ObjectDefineProperty /* = "ObjectDefineProperty" */, - ObjectEntries /* = "ObjectEntries" */, - ObjectFromEntries /* = "ObjectFromEntries" */, - ObjectGetOwnPropertyDescriptor /* = "ObjectGetOwnPropertyDescriptor" */, - ObjectGetOwnPropertyDescriptors /* = "ObjectGetOwnPropertyDescriptors" */, - ObjectKeys /* = "ObjectKeys" */, - ObjectRest /* = "ObjectRest" */, - ObjectValues /* = "ObjectValues" */, - OptionalChainAccess /* = "OptionalChainAccess" */, - OptionalFunctionCall /* = "OptionalFunctionCall" */, - OptionalMethodCall /* = "OptionalMethodCall" */, - ParseFloat /* = "ParseFloat" */, - ParseInt /* = "ParseInt" */, - Promise /* = "Promise" */, - PromiseAll /* = "PromiseAll" */, - PromiseAllSettled /* = "PromiseAllSettled" */, - PromiseAny /* = "PromiseAny" */, - PromiseRace /* = "PromiseRace" */, - Set /* = "Set" */, - SetDescriptor /* = "SetDescriptor" */, - WeakMap /* = "WeakMap" */, - WeakSet /* = "WeakSet" */, - SourceMapTraceBack /* = "SourceMapTraceBack" */, - Spread /* = "Spread" */, - StringAccess /* = "StringAccess" */, - StringCharAt /* = "StringCharAt" */, - StringCharCodeAt /* = "StringCharCodeAt" */, - StringConcat /* = "StringConcat" */, - StringEndsWith /* = "StringEndsWith" */, - StringIncludes /* = "StringIncludes" */, - StringPadEnd /* = "StringPadEnd" */, - StringPadStart /* = "StringPadStart" */, - StringReplace /* = "StringReplace" */, - StringSlice /* = "StringSlice" */, - StringSplit /* = "StringSplit" */, - StringStartsWith /* = "StringStartsWith" */, - StringSubstr /* = "StringSubstr" */, - StringSubstring /* = "StringSubstring" */, - StringTrim /* = "StringTrim" */, - StringTrimEnd /* = "StringTrimEnd" */, - StringTrimStart /* = "StringTrimStart" */, - Symbol /* = "Symbol" */, - SymbolRegistry /* = "SymbolRegistry" */, - TypeOf /* = "TypeOf" */, - Unpack /* = "Unpack" */ -} \ No newline at end of file diff --git a/externals02/LuaPrinter.module_typescript-to-lua.kt b/externals02/LuaPrinter.module_typescript-to-lua.kt deleted file mode 100644 index 3a97a7d..0000000 --- a/externals02/LuaPrinter.module_typescript-to-lua.kt +++ /dev/null @@ -1,101 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.Program - -external var escapeString: (value: String) -> String - -external var tstlHeader: Any - -typealias Printer = (program: Program, emitHost: EmitHost, fileName: String, file: File) -> PrintResult - -external interface PrintResult { - var code: String - var sourceMap: String - var sourceMapNode: SourceNode -} - -external fun createPrinter(printers: Array): Printer - -open external class LuaPrinter(emitHost: EmitHost, program: Program, fileName: String) { - open var emitHost: Any - open var currentIndent: Any - open var sourceFile: Any - open var options: Any - open fun print(file: File): PrintResult - open var printInlineSourceMap: Any - open var printStackTraceOverride: Any - open var printFile: Any - open fun pushIndent() - open fun popIndent() - open fun indent(input: String = definedExternally): dynamic /* String | SourceNode */ - open fun indent(): dynamic /* String | SourceNode */ - open fun indent(input: SourceNode = definedExternally): dynamic /* String | SourceNode */ - open fun createSourceNode(node: Node, chunks: String, name: String = definedExternally): SourceNode - open fun createSourceNode(node: Node, chunks: String): SourceNode - open fun createSourceNode(node: Node, chunks: SourceNode, name: String = definedExternally): SourceNode - open fun createSourceNode(node: Node, chunks: SourceNode): SourceNode - open fun createSourceNode(node: Node, chunks: Array, name: String = definedExternally): SourceNode - open fun createSourceNode(node: Node, chunks: Array): SourceNode - open fun concatNodes(vararg chunks: Any /* String | SourceNode */): SourceNode - open fun printBlock(block: Block): SourceNode - open var statementMayRequireSemiColon: Any - open var nodeStartsWithParenthesis: Any - open fun printStatementArray(statements: Array): Array - open fun printStatement(statement: Statement): SourceNode - open fun printComment(comment: String): dynamic /* String | SourceNode */ - open fun printComment(comment: Array): dynamic /* String | SourceNode */ - open fun printStatementExcludingComments(statement: Statement): SourceNode - open fun printDoStatement(statement: DoStatement): SourceNode - open fun printVariableDeclarationStatement(statement: VariableDeclarationStatement): SourceNode - open fun printVariableAssignmentStatement(statement: AssignmentStatement): SourceNode - open fun printIfStatement(statement: IfStatement, isElseIf: Boolean = definedExternally): SourceNode - open fun printWhileStatement(statement: WhileStatement): SourceNode - open fun printRepeatStatement(statement: RepeatStatement): SourceNode - open fun printForStatement(statement: ForStatement): SourceNode - open fun printForInStatement(statement: ForInStatement): SourceNode - open fun printGotoStatement(statement: GotoStatement): SourceNode - open fun printLabelStatement(statement: LabelStatement): SourceNode - open fun printReturnStatement(statement: ReturnStatement): SourceNode - open fun printBreakStatement(statement: BreakStatement): SourceNode - open fun printExpressionStatement(statement: ExpressionStatement): SourceNode - open fun printExpression(expression: Expression): SourceNode - open fun printStringLiteral(expression: StringLiteral): SourceNode - open fun printNumericLiteral(expression: NumericLiteral): SourceNode - open fun printNilLiteral(expression: NilLiteral): SourceNode - open fun printDotsLiteral(expression: DotsLiteral): SourceNode - open fun printBooleanLiteral(expression: BooleanLiteral): SourceNode - open var printFunctionParameters: Any - open fun printFunctionExpression(expression: FunctionExpression): SourceNode - open fun printFunctionDefinition(statement: Any /* VariableDeclarationStatement | AssignmentStatement */): SourceNode - open fun printTableFieldExpression(expression: TableFieldExpression): SourceNode - open fun printTableExpression(expression: TableExpression): SourceNode - open fun printUnaryExpression(expression: UnaryExpression): SourceNode - open fun printBinaryExpression(expression: BinaryExpression): SourceNode - open var printExpressionInParenthesesIfNeeded: Any - open var needsParenthesis: Any - open fun printCallExpression(expression: CallExpression): SourceNode - open fun printMethodCallExpression(expression: MethodCallExpression): SourceNode - open fun printIdentifier(expression: Identifier): SourceNode - open fun printTableIndexExpression(expression: TableIndexExpression): SourceNode - open fun printOperator(kind: Any /* SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator | SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */): SourceNode - open fun joinChunksWithComma(chunks: Array): Array - open fun printExpressionList(expressions: Array): Array - open var buildSourceMap: Any - - companion object { - var operatorMap: Any - } -} \ No newline at end of file diff --git a/externals02/context.module_typescript-to-lua.kt b/externals02/context.module_typescript-to-lua.kt deleted file mode 100644 index 696e339..0000000 --- a/externals02/context.module_typescript-to-lua.kt +++ /dev/null @@ -1,79 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.GetAccessorDeclaration -import ts.SetAccessorDeclaration -import ts.Node -import ts.ImportEqualsDeclaration -import ts.Expression -import ts.SourceFile -import ts.CancellationToken -import ts.TypeChecker -import ts.Program -import ts.Diagnostic -import Node as _Node -import Expression as _Expression -import ts.QualifiedName -import ts.ExternalModuleReference - -external interface AllAccessorDeclarations { - var firstAccessor: dynamic /* GetAccessorDeclaration | SetAccessorDeclaration */ - get() = definedExternally - set(value) = definedExternally - var secondAccessor: dynamic /* GetAccessorDeclaration? | SetAccessorDeclaration? */ - get() = definedExternally - set(value) = definedExternally - var getAccessor: GetAccessorDeclaration? - var setAccessor: SetAccessorDeclaration? -} - -external interface EmitResolver { - fun isValueAliasDeclaration(node: Node): Boolean - fun isReferencedAliasDeclaration(node: Node, checkChildren: Boolean = definedExternally): Boolean - fun isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): Boolean - fun moduleExportsSomeValue(moduleReferenceExpression: Expression): Boolean - fun getAllAccessorDeclarations(declaration: GetAccessorDeclaration): AllAccessorDeclarations - fun getAllAccessorDeclarations(declaration: SetAccessorDeclaration): AllAccessorDeclarations -} - -external interface DiagnosticsProducingTypeChecker : TypeChecker { - fun getEmitResolver(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): EmitResolver -} - -external open class TransformationContext(program: Program, sourceFile: SourceFile, visitorMap: VisitorMap) { - open var program: Program - open var sourceFile: SourceFile - open var visitorMap: Any - open val diagnostics: Array - open val checker: DiagnosticsProducingTypeChecker - open val resolver: EmitResolver - open val options: dynamic /* typealias OmitIndexSignature = dynamic */ - open val luaTarget: LuaTarget - open val isModule: Boolean - open val isStrict: Boolean - open var currentNodeVisitors: Any - open fun transformNode(node: Node): Array<_Node> - open fun superTransformNode(node: Node): Array<_Node> - open fun transformExpression(node: Expression): _Expression - open fun transformExpression(node: QualifiedName): _Expression - open fun transformExpression(node: ExternalModuleReference): _Expression - open fun superTransformExpression(node: Expression): _Expression - open fun superTransformExpression(node: QualifiedName): _Expression - open fun superTransformExpression(node: ExternalModuleReference): _Expression - open fun transformStatements(node: StatementLikeNode): Array - open fun transformStatements(node: Array): Array - open fun superTransformStatements(node: StatementLikeNode): Array - open fun superTransformStatements(node: Array): Array -} \ No newline at end of file diff --git a/externals02/index.module_typescript-to-lua.kt b/externals02/index.module_typescript-to-lua.kt deleted file mode 100644 index 2016698..0000000 --- a/externals02/index.module_typescript-to-lua.kt +++ /dev/null @@ -1,38 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.WriteFileCallback -import ts.Diagnostic -import tsstdlib.Record - -external fun transpileFiles(rootNames: Array, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, writeFile: WriteFileCallback = definedExternally): EmitResult - -external fun transpileProject(configFileName: String, optionsToExtend: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, writeFile: WriteFileCallback = definedExternally): EmitResult - -external interface TranspileVirtualProjectResult { - var diagnostics: Array - var transpiledFiles: Array -} - -external fun transpileVirtualProject(files: Record, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally): TranspileVirtualProjectResult - -external interface TranspileStringResult { - var diagnostics: Array - var file: TranspiledFile? - get() = definedExternally - set(value) = definedExternally -} - -external fun transpileString(main: String, options: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally): TranspileStringResult \ No newline at end of file diff --git a/externals02/lib.es2015.collection.kt b/externals02/lib.es2015.collection.kt deleted file mode 100644 index affffa8..0000000 --- a/externals02/lib.es2015.collection.kt +++ /dev/null @@ -1,49 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface Map { - fun entries(): IterableIterator */> - fun keys(): IterableIterator - fun values(): IterableIterator - fun clear() - fun delete(key: K): Boolean - fun forEach(callbackfn: (value: V, key: K, map: Map) -> Unit, thisArg: Any = definedExternally) - fun get(key: K): V? - fun has(key: K): Boolean - fun set(key: K, value: V): Map /* this */ - val size: Number -} - -external interface MapConstructor { - val prototype: Map -} - -external interface Set { - fun entries(): IterableIterator */> - fun keys(): IterableIterator - fun values(): IterableIterator - fun add(value: T): Set /* this */ - fun clear() - fun delete(value: T): Boolean - fun forEach(callbackfn: (value: T, value2: T, set: Set) -> Unit, thisArg: Any = definedExternally) - fun has(value: T): Boolean - val size: Number -} - -external interface SetConstructor { - val prototype: Set -} \ No newline at end of file diff --git a/externals02/lib.es2015.iterable.kt b/externals02/lib.es2015.iterable.kt deleted file mode 100644 index 458df31..0000000 --- a/externals02/lib.es2015.iterable.kt +++ /dev/null @@ -1,54 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface IteratorYieldResult { - var done: Boolean? - get() = definedExternally - set(value) = definedExternally - var value: TYield -} - -external interface IteratorReturnResult { - var done: Boolean? - var value: TReturn -} - -external interface Iterator { - fun next(vararg args: Any /* JsTuple<> | JsTuple */): dynamic /* IteratorYieldResult | IteratorReturnResult */ - val `return`: ((value: TReturn) -> dynamic)? - val `throw`: ((e: Any) -> dynamic)? -} - -typealias Iterator__1 = Iterator - -external interface Iterable - -external interface IterableIterator : Iterator__1 - -external interface PromiseConstructor { - val prototype: Promise - fun all(values: Any /* JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple */): Promise | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple */> - fun all(values: Array */>): Promise> - fun race(values: Array): Promise - fun reject(reason: Any = definedExternally): Promise - fun resolve(value: T): Promise - fun resolve(value: PromiseLike): Promise - fun resolve(): Promise - fun all(values: Iterable */>): Promise> - fun race(values: Iterable): Promise - fun race(values: Iterable */>): Promise -} \ No newline at end of file diff --git a/externals02/lib.es5.Intl.module_dukat.kt b/externals02/lib.es5.Intl.module_dukat.kt deleted file mode 100644 index 456d347..0000000 --- a/externals02/lib.es5.Intl.module_dukat.kt +++ /dev/null @@ -1,219 +0,0 @@ -@file:JsQualifier("tsstdlib.Intl") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface CollatorOptions { - var usage: String? - get() = definedExternally - set(value) = definedExternally - var localeMatcher: String? - get() = definedExternally - set(value) = definedExternally - var numeric: Boolean? - get() = definedExternally - set(value) = definedExternally - var caseFirst: String? - get() = definedExternally - set(value) = definedExternally - var sensitivity: String? - get() = definedExternally - set(value) = definedExternally - var ignorePunctuation: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedCollatorOptions { - var locale: String - var usage: String - var sensitivity: String - var ignorePunctuation: Boolean? - var collation: String - var caseFirst: String - var numeric: Boolean? -} - -@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") -external interface Collator { - fun compare(x: String, y: String): Number - fun resolvedOptions(): ResolvedCollatorOptions - - companion object { - @nativeInvoke - operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: CollatorOptions = definedExternally): Collator - fun supportedLocalesOf(locales: Any /* String | Array */, options: CollatorOptions = definedExternally): Array - } -} - -external interface NumberFormatOptions { - var localeMatcher: String? - get() = definedExternally - set(value) = definedExternally - var style: String? - get() = definedExternally - set(value) = definedExternally - var currency: String? - get() = definedExternally - set(value) = definedExternally - var currencyDisplay: String? - get() = definedExternally - set(value) = definedExternally - var useGrouping: Boolean? - get() = definedExternally - set(value) = definedExternally - var minimumIntegerDigits: Number? - get() = definedExternally - set(value) = definedExternally - var minimumFractionDigits: Number? - get() = definedExternally - set(value) = definedExternally - var maximumFractionDigits: Number? - get() = definedExternally - set(value) = definedExternally - var minimumSignificantDigits: Number? - get() = definedExternally - set(value) = definedExternally - var maximumSignificantDigits: Number? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedNumberFormatOptions { - var locale: String - var numberingSystem: String - var style: String - var currency: String? - get() = definedExternally - set(value) = definedExternally - var currencyDisplay: String? - get() = definedExternally - set(value) = definedExternally - var minimumIntegerDigits: Number - var minimumFractionDigits: Number - var maximumFractionDigits: Number - var minimumSignificantDigits: Number? - get() = definedExternally - set(value) = definedExternally - var maximumSignificantDigits: Number? - get() = definedExternally - set(value) = definedExternally - var useGrouping: Boolean? -} - -@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") -external interface NumberFormat { - fun format(value: Number): String - fun resolvedOptions(): ResolvedNumberFormatOptions - - companion object { - @nativeInvoke - operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: NumberFormatOptions = definedExternally): NumberFormat - fun supportedLocalesOf(locales: Any /* String | Array */, options: NumberFormatOptions = definedExternally): Array - } -} - -external interface DateTimeFormatOptions { - var localeMatcher: String? - get() = definedExternally - set(value) = definedExternally - var weekday: String? - get() = definedExternally - set(value) = definedExternally - var era: String? - get() = definedExternally - set(value) = definedExternally - var year: String? - get() = definedExternally - set(value) = definedExternally - var month: String? - get() = definedExternally - set(value) = definedExternally - var day: String? - get() = definedExternally - set(value) = definedExternally - var hour: String? - get() = definedExternally - set(value) = definedExternally - var minute: String? - get() = definedExternally - set(value) = definedExternally - var second: String? - get() = definedExternally - set(value) = definedExternally - var timeZoneName: String? - get() = definedExternally - set(value) = definedExternally - var formatMatcher: String? - get() = definedExternally - set(value) = definedExternally - var hour12: Boolean? - get() = definedExternally - set(value) = definedExternally - var timeZone: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedDateTimeFormatOptions { - var locale: String - var calendar: String - var numberingSystem: String - var timeZone: String - var hour12: Boolean? - get() = definedExternally - set(value) = definedExternally - var weekday: String? - get() = definedExternally - set(value) = definedExternally - var era: String? - get() = definedExternally - set(value) = definedExternally - var year: String? - get() = definedExternally - set(value) = definedExternally - var month: String? - get() = definedExternally - set(value) = definedExternally - var day: String? - get() = definedExternally - set(value) = definedExternally - var hour: String? - get() = definedExternally - set(value) = definedExternally - var minute: String? - get() = definedExternally - set(value) = definedExternally - var second: String? - get() = definedExternally - set(value) = definedExternally - var timeZoneName: String? - get() = definedExternally - set(value) = definedExternally -} - -@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") -external interface DateTimeFormat { - fun format(date: Date = definedExternally): String - fun format(): String - fun format(date: Number = definedExternally): String - fun resolvedOptions(): ResolvedDateTimeFormatOptions - - companion object { - @nativeInvoke - operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: DateTimeFormatOptions = definedExternally): DateTimeFormat - fun supportedLocalesOf(locales: Any /* String | Array */, options: DateTimeFormatOptions = definedExternally): Array - } -} \ No newline at end of file diff --git a/externals02/lib.es5.kt b/externals02/lib.es5.kt deleted file mode 100644 index c9b2102..0000000 --- a/externals02/lib.es5.kt +++ /dev/null @@ -1,69 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface DateConstructor { - @nativeInvoke - operator fun invoke(): String - val prototype: Date - fun parse(s: String): Number - fun UTC(year: Number, month: Number, date: Number = definedExternally, hours: Number = definedExternally, minutes: Number = definedExternally, seconds: Number = definedExternally, ms: Number = definedExternally): Number - fun now(): Number -} - -external interface ConcatArray { - val length: Number - @nativeGetter - operator fun get(n: Number): T? - @nativeSetter - operator fun set(n: Number, value: T) - fun join(separator: String = definedExternally): String - fun slice(start: Number = definedExternally, end: Number = definedExternally): Array -} - -external interface ArrayConstructor { - fun from(iterable: Iterable): Array - fun from(iterable: ArrayLike): Array - fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array - fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U): Array - fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array - fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U): Array - fun of(vararg items: T): Array - @nativeInvoke - operator fun invoke(arrayLength: Number = definedExternally): Array - @nativeInvoke - operator fun invoke(): Array - @nativeInvoke - operator fun invoke(arrayLength: Number): Array - @nativeInvoke - operator fun invoke(vararg items: T): Array - fun isArray(arg: Any): Boolean - val prototype: Array -} - -external interface PromiseLike { - fun then(onfulfilled: ((value: T) -> Any?)? = definedExternally, onrejected: ((reason: Any) -> Any?)? = definedExternally): PromiseLike -} - -external interface ArrayLike { - val length: Number - @nativeGetter - operator fun get(n: Number): T? - @nativeSetter - operator fun set(n: Number, value: T) -} - -typealias Record = Any \ No newline at end of file diff --git a/externals02/lib.scripthost.kt b/externals02/lib.scripthost.kt deleted file mode 100644 index cd57d24..0000000 --- a/externals02/lib.scripthost.kt +++ /dev/null @@ -1,19 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -open external class VarDate { - open var VarDate_typekey: VarDate -} \ No newline at end of file diff --git a/externals02/nonDeclarations.ts.kt b/externals02/nonDeclarations.ts.kt deleted file mode 100644 index 033a9db..0000000 --- a/externals02/nonDeclarations.ts.kt +++ /dev/null @@ -1,115 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package ts - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.* - -typealias SortedReadonlyArray = Array - -typealias SortedArray = Array - -typealias NodeArray = Array - -typealias DotToken = PunctuationToken // SyntaxKind.DotToken - -typealias DotDotDotToken = PunctuationToken // SyntaxKind.DotDotDotToken - -typealias QuestionToken = PunctuationToken // SyntaxKind.QuestionToken - -typealias ExclamationToken = PunctuationToken // SyntaxKind.ExclamationToken - -typealias ColonToken = PunctuationToken // SyntaxKind.ColonToken - -typealias EqualsToken = PunctuationToken // SyntaxKind.EqualsToken - -typealias AsteriskToken = PunctuationToken // SyntaxKind.AsteriskToken - -typealias EqualsGreaterThanToken = PunctuationToken // SyntaxKind.EqualsGreaterThanToken - -typealias PlusToken = PunctuationToken // SyntaxKind.PlusToken - -typealias MinusToken = PunctuationToken // SyntaxKind.MinusToken - -typealias QuestionDotToken = PunctuationToken // SyntaxKind.QuestionDotToken - -typealias AssertsKeyword = KeywordToken // SyntaxKind.AssertsKeyword - -typealias AwaitKeyword = KeywordToken // SyntaxKind.AwaitKeyword - -typealias AwaitKeywordToken = AwaitKeyword - -typealias AssertsToken = AssertsKeyword - -typealias AbstractKeyword = ModifierToken // SyntaxKind.AbstractKeyword - -typealias AsyncKeyword = ModifierToken // SyntaxKind.AsyncKeyword - -typealias ConstKeyword = ModifierToken // SyntaxKind.ConstKeyword - -typealias DeclareKeyword = ModifierToken // SyntaxKind.DeclareKeyword - -typealias DefaultKeyword = ModifierToken // SyntaxKind.DefaultKeyword - -typealias ExportKeyword = ModifierToken // SyntaxKind.ExportKeyword - -typealias PrivateKeyword = ModifierToken // SyntaxKind.PrivateKeyword - -typealias ProtectedKeyword = ModifierToken // SyntaxKind.ProtectedKeyword - -typealias PublicKeyword = ModifierToken // SyntaxKind.PublicKeyword - -typealias ReadonlyKeyword = ModifierToken // SyntaxKind.ReadonlyKeyword - -typealias OverrideKeyword = ModifierToken // SyntaxKind.OverrideKeyword - -typealias StaticKeyword = ModifierToken // SyntaxKind.StaticKeyword - -typealias ReadonlyToken = ReadonlyKeyword - -typealias ModifiersArray = NodeArray - -typealias IncrementExpression = UpdateExpression - -//typealias ExponentiationOperator = SyntaxKind.AsteriskAsteriskToken - -typealias BinaryOperatorToken = Token - -typealias AssignmentOperatorToken = Token - -typealias FunctionBody = Block - -typealias WriteFileCallback = (fileName: String, data: String, writeByteOrderMark: Boolean, onError: (message: String) -> Unit, sourceFiles: Array) -> Unit - -typealias CustomTransformerFactory = (context: TransformationContext) -> CustomTransformer - -typealias SymbolTable = UnderscoreEscapedMap - -typealias JsFileExtensionInfo = FileExtensionInfo - -typealias EmitHelperUniqueNameCallback = (name: String) -> String - -typealias TransformerFactory = (context: TransformationContext) -> Transformer - -typealias Transformer = (node: T) -> T - -typealias Visitor = (node: Node) -> dynamic - -typealias FileWatcherCallback = (fileName: String, eventKind: FileWatcherEventKind) -> Unit - -typealias DirectoryWatcherCallback = (fileName: String) -> Unit - -typealias DiagnosticReporter = (diagnostic: Diagnostic) -> Unit - -typealias CodeActionCommand = InstallPackageAction \ No newline at end of file diff --git a/externals02/output-collector.module_typescript-to-lua.kt b/externals02/output-collector.module_typescript-to-lua.kt deleted file mode 100644 index 0c57eac..0000000 --- a/externals02/output-collector.module_typescript-to-lua.kt +++ /dev/null @@ -1,33 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.SourceFile - -external interface TranspiledFile { - var outPath: String - var sourceFiles: Array - var lua: String? - get() = definedExternally - set(value) = definedExternally - var luaSourceMap: String? - get() = definedExternally - set(value) = definedExternally - var declaration: String? - get() = definedExternally - set(value) = definedExternally - var declarationMap: String? - get() = definedExternally - set(value) = definedExternally -} \ No newline at end of file diff --git a/externals02/parse.module_typescript-to-lua.kt b/externals02/parse.module_typescript-to-lua.kt deleted file mode 100644 index ff6e944..0000000 --- a/externals02/parse.module_typescript-to-lua.kt +++ /dev/null @@ -1,25 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface ParsedCommandLine : ts.ParsedCommandLine { - override var options: dynamic /* typealias OmitIndexSignature = dynamic */ - get() = definedExternally - set(value) = definedExternally -} - -external fun updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine - -external fun parseCommandLine(args: Array): ParsedCommandLine \ No newline at end of file diff --git a/externals02/plugins.module_typescript-to-lua.kt b/externals02/plugins.module_typescript-to-lua.kt deleted file mode 100644 index 24d3ea4..0000000 --- a/externals02/plugins.module_typescript-to-lua.kt +++ /dev/null @@ -1,24 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface Plugin { - var visitors: Visitors? - get() = definedExternally - set(value) = definedExternally - var printer: Printer? - get() = definedExternally - set(value) = definedExternally -} \ No newline at end of file diff --git a/externals02/report.module_typescript-to-lua.kt b/externals02/report.module_typescript-to-lua.kt deleted file mode 100644 index f1582a6..0000000 --- a/externals02/report.module_typescript-to-lua.kt +++ /dev/null @@ -1,48 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.DiagnosticRelatedInformation -import ts.DiagnosticCategory -import ts.SourceFile -import ts.Diagnostic -import ts.System -import ts.DiagnosticReporter - -external interface `T$13` { - var code: Any - var reportsUnnecessary: Any? - get() = definedExternally - set(value) = definedExternally - var reportsDeprecated: Any? - get() = definedExternally - set(value) = definedExternally - var source: String? - get() = definedExternally - set(value) = definedExternally - var relatedInformation: Array? - get() = definedExternally - set(value) = definedExternally - var category: DiagnosticCategory - var file: SourceFile? - var start: Number? - var length: Number? - var messageText: dynamic /* String | ts.DiagnosticMessageChain */ - get() = definedExternally - set(value) = definedExternally -} - -external var prepareDiagnosticForFormatting: (diagnostic: Diagnostic) -> `T$13` - -external fun createDiagnosticReporter(pretty: Boolean, system: System = definedExternally): DiagnosticReporter \ No newline at end of file diff --git a/externals02/source-map.module_source-map.kt b/externals02/source-map.module_source-map.kt deleted file mode 100644 index 66b214e..0000000 --- a/externals02/source-map.module_source-map.kt +++ /dev/null @@ -1,192 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -typealias SourceMapUrl = String - -external interface StartOfSourceMap { - var file: String? - get() = definedExternally - set(value) = definedExternally - var sourceRoot: String? - get() = definedExternally - set(value) = definedExternally - var skipValidation: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface RawSourceMap { - var version: Number - var sources: Array - var names: Array - var sourceRoot: String? - get() = definedExternally - set(value) = definedExternally - var sourcesContent: Array? - get() = definedExternally - set(value) = definedExternally - var mappings: String - var file: String -} - -external interface RawIndexMap : StartOfSourceMap { - var version: Number - var sections: Array -} - -external interface RawSection { - var offset: Position - var map: RawSourceMap -} - -external interface Position { - var line: Number - var column: Number -} - -external interface NullablePosition { - var line: Number? - var column: Number? - var lastColumn: Number? -} - -external interface MappedPosition { - var source: String - var line: Number - var column: Number - var name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface NullableMappedPosition { - var source: String? - var line: Number? - var column: Number? - var name: String? -} - -external interface MappingItem { - var source: String - var generatedLine: Number - var generatedColumn: Number - var originalLine: Number - var originalColumn: Number - var name: String -} - -external interface Mapping { - var generated: Position - var original: Position - var source: String - var name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface CodeWithSourceMap { - var code: String - var map: SourceMapGenerator -} - -external interface SourceMapConsumer { - fun computeColumnSpans() - fun originalPositionFor(generatedPosition: Position /* Position & `T$19` */): NullableMappedPosition - fun generatedPositionFor(originalPosition: MappedPosition /* MappedPosition & `T$19` */): NullablePosition - fun allGeneratedPositionsFor(originalPosition: MappedPosition): Array - fun hasContentsOfAllSources(): Boolean - fun sourceContentFor(source: String, returnNullOnMissing: Boolean = definedExternally): String? - fun eachMapping(callback: (mapping: MappingItem) -> Unit, context: Any = definedExternally, order: Number = definedExternally) - fun destroy() -} - -external interface SourceMapConsumerConstructor { - var prototype: SourceMapConsumer - var GENERATED_ORDER: Number - var ORIGINAL_ORDER: Number - var GREATEST_LOWER_BOUND: Number - var LEAST_UPPER_BOUND: Number - fun fromSourceMap(sourceMap: SourceMapGenerator, sourceMapUrl: SourceMapUrl = definedExternally): Promise - fun with(rawSourceMap: RawSourceMap, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise - fun with(rawSourceMap: RawIndexMap, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise - fun with(rawSourceMap: String, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise -} - -external interface BasicSourceMapConsumer : SourceMapConsumer { - var file: String - var sourceRoot: String - var sources: Array - var sourcesContent: Array -} - -external interface BasicSourceMapConsumerConstructor { - var prototype: BasicSourceMapConsumer - fun fromSourceMap(sourceMap: SourceMapGenerator): Promise -} - -external interface IndexedSourceMapConsumer : SourceMapConsumer { - var sources: Array -} - -external interface IndexedSourceMapConsumerConstructor { - var prototype: IndexedSourceMapConsumer -} - -open external class SourceMapGenerator(startOfSourceMap: StartOfSourceMap = definedExternally) { - open fun addMapping(mapping: Mapping) - open fun setSourceContent(sourceFile: String, sourceContent: String) - open fun applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile: String = definedExternally, sourceMapPath: String = definedExternally) - override fun toString(): String - open fun toJSON(): RawSourceMap - - companion object { - fun fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator - } -} - -open external class SourceNode { - open var children: Array - open var sourceContents: Any - open var line: Number - open var column: Number - open var source: String - open var name: String - constructor() - constructor(line: Number?, column: Number?, source: String?, chunks: Array = definedExternally, name: String = definedExternally) - constructor(line: Number?, column: Number?, source: String?) - constructor(line: Number?, column: Number?, source: String?, chunks: Array = definedExternally) - constructor(line: Number?, column: Number?, source: String?, chunks: SourceNode = definedExternally, name: String = definedExternally) - constructor(line: Number?, column: Number?, source: String?, chunks: SourceNode = definedExternally) - constructor(line: Number?, column: Number?, source: String?, chunks: String = definedExternally, name: String = definedExternally) - constructor(line: Number?, column: Number?, source: String?, chunks: String = definedExternally) - open fun add(chunk: Array): SourceNode - open fun add(chunk: SourceNode): SourceNode - open fun add(chunk: String): SourceNode - open fun prepend(chunk: Array): SourceNode - open fun prepend(chunk: SourceNode): SourceNode - open fun prepend(chunk: String): SourceNode - open fun setSourceContent(sourceFile: String, sourceContent: String) - open fun walk(fn: (chunk: String, mapping: MappedPosition) -> Unit) - open fun walkSourceContents(fn: (file: String, content: String) -> Unit) - open fun join(sep: String): SourceNode - open fun replaceRight(pattern: String, replacement: String): SourceNode - override fun toString(): String - open fun toStringWithSourceMap(startOfSourceMap: StartOfSourceMap = definedExternally): CodeWithSourceMap - - companion object { - fun fromStringWithSourceMap(code: String, sourceMapConsumer: SourceMapConsumer, relativePath: String = definedExternally): SourceNode - } -} \ No newline at end of file diff --git a/externals02/transpile.module_typescript-to-lua.kt b/externals02/transpile.module_typescript-to-lua.kt deleted file mode 100644 index 8681706..0000000 --- a/externals02/transpile.module_typescript-to-lua.kt +++ /dev/null @@ -1,40 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.Program -import ts.SourceFile -import ts.CustomTransformers -import ts.Diagnostic -import ts.WriteFileCallback - -external interface TranspileOptions { - var program: Program - var sourceFiles: Array? - get() = definedExternally - set(value) = definedExternally - var customTransformers: CustomTransformers? - get() = definedExternally - set(value) = definedExternally - var plugins: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface TranspileResult { - var diagnostics: Array - var transpiledFiles: Array -} - -external fun getProgramTranspileResult(emitHost: EmitHost, writeFileResult: WriteFileCallback, __2: TranspileOptions): TranspileResult \ No newline at end of file diff --git a/externals02/transpiler.module_typescript-to-lua.kt b/externals02/transpiler.module_typescript-to-lua.kt deleted file mode 100644 index 5edaf7c..0000000 --- a/externals02/transpiler.module_typescript-to-lua.kt +++ /dev/null @@ -1,55 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.WriteFileCallback -import ts.Diagnostic -import ts.Program - -external interface TranspilerOptions { - var emitHost: EmitHost? - get() = definedExternally - set(value) = definedExternally -} - -external interface EmitOptions : TranspileOptions { - var writeFile: WriteFileCallback? - get() = definedExternally - set(value) = definedExternally -} - -external interface EmitResult { - var emitSkipped: Boolean? - var diagnostics: Array -} - -external interface `T$20` { - var emitPlan: Array -} - -open external class Transpiler(__0: TranspilerOptions = definedExternally) { - open var emitHost: EmitHost - open fun emit(emitOptions: EmitOptions): EmitResult - open fun getEmitPlan(program: Program, diagnostics: Array, files: Array): `T$20` -} - -external fun getEmitPath(file: String, program: Program): String - -external fun getEmitPathRelativeToOutDir(fileName: String, program: Program): String - -external fun getSourceDir(program: Program): String - -external fun getEmitOutDir(program: Program): String - -external fun getProjectRoot(program: Program): String \ No newline at end of file diff --git a/externals02/tsconfig.module_typescript-to-lua.kt b/externals02/tsconfig.module_typescript-to-lua.kt deleted file mode 100644 index 865bc70..0000000 --- a/externals02/tsconfig.module_typescript-to-lua.kt +++ /dev/null @@ -1,18 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.System - -external fun parseConfigFileWithSystem(configFileName: String, commandLineOptions: dynamic /* typealias OmitIndexSignature = dynamic */ = definedExternally, system: System = definedExternally): ParsedCommandLine \ No newline at end of file diff --git a/externals02/typescript.module_typescript.kt b/externals02/typescript.module_typescript.kt deleted file mode 100644 index 83261af..0000000 --- a/externals02/typescript.module_typescript.kt +++ /dev/null @@ -1,19 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external fun setTimeout(handler: (args: Any) -> Unit, timeout: Number): Any - -external fun clearTimeout(handle: Any) \ No newline at end of file diff --git a/externals02/typescript.ts.ScriptSnapshot.module_typescript.kt b/externals02/typescript.ts.ScriptSnapshot.module_typescript.kt deleted file mode 100644 index acab3da..0000000 --- a/externals02/typescript.ts.ScriptSnapshot.module_typescript.kt +++ /dev/null @@ -1,20 +0,0 @@ -@file:JsQualifier("ts.ScriptSnapshot") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package ts.ScriptSnapshot - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.IScriptSnapshot - -external fun fromString(text: String): IScriptSnapshot \ No newline at end of file diff --git a/externals02/typescript.ts.module_typescript.kt b/externals02/typescript.ts.module_typescript.kt deleted file mode 100644 index fb5f31b..0000000 --- a/externals02/typescript.ts.module_typescript.kt +++ /dev/null @@ -1,8245 +0,0 @@ -@file:JsModule("typescript") -@file:JsNonModule -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package ts - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -//@formatter:off - -external var versionMajorMinor: Any - -external var version: String - -external interface MapLike { - @nativeGetter - operator fun get(index: String): T? - @nativeSetter - operator fun set(index: String, value: T) -} - -external interface ReadonlyCollection { - val size: Number - fun has(key: K): Boolean - fun keys(): Iterator -} - -external interface Collection : ReadonlyCollection { - fun delete(key: K): Boolean - fun clear() -} - -external interface ReadonlyESMap : ReadonlyCollection { - fun get(key: K): V? - fun values(): Iterator - fun entries(): Iterator */> - fun forEach(action: (value: V, key: K) -> Unit) -} - -external interface ReadonlyMap : ReadonlyESMap - -external interface ESMap : ReadonlyESMap, Collection { - fun set(key: K, value: V): ESMap /* this */ -} - -external interface Map : ESMap - -external interface ReadonlySet : ReadonlyCollection { - override fun has(key: T): Boolean - fun values(): Iterator - fun entries(): Iterator */> - fun forEach(action: (value: T, key: T) -> Unit) -} - -external interface Set : ReadonlySet, Collection { - fun add(value: T): Set /* this */ - override fun delete(key: T): Boolean -} - -external interface Iterator { - fun next(): dynamic /* `T$1` | `T$2` */ -} - -external interface Push { - fun push(vararg values: T) -} - -external interface TextRange { - var pos: Number - var end: Number -} - -external interface ReadonlyTextRange { - val pos: Number - val end: Number -} - -external enum class SyntaxKind { - Unknown /* = 0 */, - EndOfFileToken /* = 1 */, - SingleLineCommentTrivia /* = 2 */, - MultiLineCommentTrivia /* = 3 */, - NewLineTrivia /* = 4 */, - WhitespaceTrivia /* = 5 */, - ShebangTrivia /* = 6 */, - ConflictMarkerTrivia /* = 7 */, - NumericLiteral /* = 8 */, - BigIntLiteral /* = 9 */, - StringLiteral /* = 10 */, - JsxText /* = 11 */, - JsxTextAllWhiteSpaces /* = 12 */, - RegularExpressionLiteral /* = 13 */, - NoSubstitutionTemplateLiteral /* = 14 */, - TemplateHead /* = 15 */, - TemplateMiddle /* = 16 */, - TemplateTail /* = 17 */, - OpenBraceToken /* = 18 */, - CloseBraceToken /* = 19 */, - OpenParenToken /* = 20 */, - CloseParenToken /* = 21 */, - OpenBracketToken /* = 22 */, - CloseBracketToken /* = 23 */, - DotToken /* = 24 */, - DotDotDotToken /* = 25 */, - SemicolonToken /* = 26 */, - CommaToken /* = 27 */, - QuestionDotToken /* = 28 */, - LessThanToken /* = 29 */, - LessThanSlashToken /* = 30 */, - GreaterThanToken /* = 31 */, - LessThanEqualsToken /* = 32 */, - GreaterThanEqualsToken /* = 33 */, - EqualsEqualsToken /* = 34 */, - ExclamationEqualsToken /* = 35 */, - EqualsEqualsEqualsToken /* = 36 */, - ExclamationEqualsEqualsToken /* = 37 */, - EqualsGreaterThanToken /* = 38 */, - PlusToken /* = 39 */, - MinusToken /* = 40 */, - AsteriskToken /* = 41 */, - AsteriskAsteriskToken /* = 42 */, - SlashToken /* = 43 */, - PercentToken /* = 44 */, - PlusPlusToken /* = 45 */, - MinusMinusToken /* = 46 */, - LessThanLessThanToken /* = 47 */, - GreaterThanGreaterThanToken /* = 48 */, - GreaterThanGreaterThanGreaterThanToken /* = 49 */, - AmpersandToken /* = 50 */, - BarToken /* = 51 */, - CaretToken /* = 52 */, - ExclamationToken /* = 53 */, - TildeToken /* = 54 */, - AmpersandAmpersandToken /* = 55 */, - BarBarToken /* = 56 */, - QuestionToken /* = 57 */, - ColonToken /* = 58 */, - AtToken /* = 59 */, - QuestionQuestionToken /* = 60 */, - BacktickToken /* = 61 */, - HashToken /* = 62 */, - EqualsToken /* = 63 */, - PlusEqualsToken /* = 64 */, - MinusEqualsToken /* = 65 */, - AsteriskEqualsToken /* = 66 */, - AsteriskAsteriskEqualsToken /* = 67 */, - SlashEqualsToken /* = 68 */, - PercentEqualsToken /* = 69 */, - LessThanLessThanEqualsToken /* = 70 */, - GreaterThanGreaterThanEqualsToken /* = 71 */, - GreaterThanGreaterThanGreaterThanEqualsToken /* = 72 */, - AmpersandEqualsToken /* = 73 */, - BarEqualsToken /* = 74 */, - BarBarEqualsToken /* = 75 */, - AmpersandAmpersandEqualsToken /* = 76 */, - QuestionQuestionEqualsToken /* = 77 */, - CaretEqualsToken /* = 78 */, - Identifier /* = 79 */, - PrivateIdentifier /* = 80 */, - BreakKeyword /* = 81 */, - CaseKeyword /* = 82 */, - CatchKeyword /* = 83 */, - ClassKeyword /* = 84 */, - ConstKeyword /* = 85 */, - ContinueKeyword /* = 86 */, - DebuggerKeyword /* = 87 */, - DefaultKeyword /* = 88 */, - DeleteKeyword /* = 89 */, - DoKeyword /* = 90 */, - ElseKeyword /* = 91 */, - EnumKeyword /* = 92 */, - ExportKeyword /* = 93 */, - ExtendsKeyword /* = 94 */, - FalseKeyword /* = 95 */, - FinallyKeyword /* = 96 */, - ForKeyword /* = 97 */, - FunctionKeyword /* = 98 */, - IfKeyword /* = 99 */, - ImportKeyword /* = 100 */, - InKeyword /* = 101 */, - InstanceOfKeyword /* = 102 */, - NewKeyword /* = 103 */, - NullKeyword /* = 104 */, - ReturnKeyword /* = 105 */, - SuperKeyword /* = 106 */, - SwitchKeyword /* = 107 */, - ThisKeyword /* = 108 */, - ThrowKeyword /* = 109 */, - TrueKeyword /* = 110 */, - TryKeyword /* = 111 */, - TypeOfKeyword /* = 112 */, - VarKeyword /* = 113 */, - VoidKeyword /* = 114 */, - WhileKeyword /* = 115 */, - WithKeyword /* = 116 */, - ImplementsKeyword /* = 117 */, - InterfaceKeyword /* = 118 */, - LetKeyword /* = 119 */, - PackageKeyword /* = 120 */, - PrivateKeyword /* = 121 */, - ProtectedKeyword /* = 122 */, - PublicKeyword /* = 123 */, - StaticKeyword /* = 124 */, - YieldKeyword /* = 125 */, - AbstractKeyword /* = 126 */, - AsKeyword /* = 127 */, - AssertsKeyword /* = 128 */, - AnyKeyword /* = 129 */, - AsyncKeyword /* = 130 */, - AwaitKeyword /* = 131 */, - BooleanKeyword /* = 132 */, - ConstructorKeyword /* = 133 */, - DeclareKeyword /* = 134 */, - GetKeyword /* = 135 */, - InferKeyword /* = 136 */, - IntrinsicKeyword /* = 137 */, - IsKeyword /* = 138 */, - KeyOfKeyword /* = 139 */, - ModuleKeyword /* = 140 */, - NamespaceKeyword /* = 141 */, - NeverKeyword /* = 142 */, - ReadonlyKeyword /* = 143 */, - RequireKeyword /* = 144 */, - NumberKeyword /* = 145 */, - ObjectKeyword /* = 146 */, - SetKeyword /* = 147 */, - StringKeyword /* = 148 */, - SymbolKeyword /* = 149 */, - TypeKeyword /* = 150 */, - UndefinedKeyword /* = 151 */, - UniqueKeyword /* = 152 */, - UnknownKeyword /* = 153 */, - FromKeyword /* = 154 */, - GlobalKeyword /* = 155 */, - BigIntKeyword /* = 156 */, - OverrideKeyword /* = 157 */, - OfKeyword /* = 158 */, - QualifiedName /* = 159 */, - ComputedPropertyName /* = 160 */, - TypeParameter /* = 161 */, - Parameter /* = 162 */, - Decorator /* = 163 */, - PropertySignature /* = 164 */, - PropertyDeclaration /* = 165 */, - MethodSignature /* = 166 */, - MethodDeclaration /* = 167 */, - ClassStaticBlockDeclaration /* = 168 */, - Constructor /* = 169 */, - GetAccessor /* = 170 */, - SetAccessor /* = 171 */, - CallSignature /* = 172 */, - ConstructSignature /* = 173 */, - IndexSignature /* = 174 */, - TypePredicate /* = 175 */, - TypeReference /* = 176 */, - FunctionType /* = 177 */, - ConstructorType /* = 178 */, - TypeQuery /* = 179 */, - TypeLiteral /* = 180 */, - ArrayType /* = 181 */, - TupleType /* = 182 */, - OptionalType /* = 183 */, - RestType /* = 184 */, - UnionType /* = 185 */, - IntersectionType /* = 186 */, - ConditionalType /* = 187 */, - InferType /* = 188 */, - ParenthesizedType /* = 189 */, - ThisType /* = 190 */, - TypeOperator /* = 191 */, - IndexedAccessType /* = 192 */, - MappedType /* = 193 */, - LiteralType /* = 194 */, - NamedTupleMember /* = 195 */, - TemplateLiteralType /* = 196 */, - TemplateLiteralTypeSpan /* = 197 */, - ImportType /* = 198 */, - ObjectBindingPattern /* = 199 */, - ArrayBindingPattern /* = 200 */, - BindingElement /* = 201 */, - ArrayLiteralExpression /* = 202 */, - ObjectLiteralExpression /* = 203 */, - PropertyAccessExpression /* = 204 */, - ElementAccessExpression /* = 205 */, - CallExpression /* = 206 */, - NewExpression /* = 207 */, - TaggedTemplateExpression /* = 208 */, - TypeAssertionExpression /* = 209 */, - ParenthesizedExpression /* = 210 */, - FunctionExpression /* = 211 */, - ArrowFunction /* = 212 */, - DeleteExpression /* = 213 */, - TypeOfExpression /* = 214 */, - VoidExpression /* = 215 */, - AwaitExpression /* = 216 */, - PrefixUnaryExpression /* = 217 */, - PostfixUnaryExpression /* = 218 */, - BinaryExpression /* = 219 */, - ConditionalExpression /* = 220 */, - TemplateExpression /* = 221 */, - YieldExpression /* = 222 */, - SpreadElement /* = 223 */, - ClassExpression /* = 224 */, - OmittedExpression /* = 225 */, - ExpressionWithTypeArguments /* = 226 */, - AsExpression /* = 227 */, - NonNullExpression /* = 228 */, - MetaProperty /* = 229 */, - SyntheticExpression /* = 230 */, - TemplateSpan /* = 231 */, - SemicolonClassElement /* = 232 */, - Block /* = 233 */, - EmptyStatement /* = 234 */, - VariableStatement /* = 235 */, - ExpressionStatement /* = 236 */, - IfStatement /* = 237 */, - DoStatement /* = 238 */, - WhileStatement /* = 239 */, - ForStatement /* = 240 */, - ForInStatement /* = 241 */, - ForOfStatement /* = 242 */, - ContinueStatement /* = 243 */, - BreakStatement /* = 244 */, - ReturnStatement /* = 245 */, - WithStatement /* = 246 */, - SwitchStatement /* = 247 */, - LabeledStatement /* = 248 */, - ThrowStatement /* = 249 */, - TryStatement /* = 250 */, - DebuggerStatement /* = 251 */, - VariableDeclaration /* = 252 */, - VariableDeclarationList /* = 253 */, - FunctionDeclaration /* = 254 */, - ClassDeclaration /* = 255 */, - InterfaceDeclaration /* = 256 */, - TypeAliasDeclaration /* = 257 */, - EnumDeclaration /* = 258 */, - ModuleDeclaration /* = 259 */, - ModuleBlock /* = 260 */, - CaseBlock /* = 261 */, - NamespaceExportDeclaration /* = 262 */, - ImportEqualsDeclaration /* = 263 */, - ImportDeclaration /* = 264 */, - ImportClause /* = 265 */, - NamespaceImport /* = 266 */, - NamedImports /* = 267 */, - ImportSpecifier /* = 268 */, - ExportAssignment /* = 269 */, - ExportDeclaration /* = 270 */, - NamedExports /* = 271 */, - NamespaceExport /* = 272 */, - ExportSpecifier /* = 273 */, - MissingDeclaration /* = 274 */, - ExternalModuleReference /* = 275 */, - JsxElement /* = 276 */, - JsxSelfClosingElement /* = 277 */, - JsxOpeningElement /* = 278 */, - JsxClosingElement /* = 279 */, - JsxFragment /* = 280 */, - JsxOpeningFragment /* = 281 */, - JsxClosingFragment /* = 282 */, - JsxAttribute /* = 283 */, - JsxAttributes /* = 284 */, - JsxSpreadAttribute /* = 285 */, - JsxExpression /* = 286 */, - CaseClause /* = 287 */, - DefaultClause /* = 288 */, - HeritageClause /* = 289 */, - CatchClause /* = 290 */, - PropertyAssignment /* = 291 */, - ShorthandPropertyAssignment /* = 292 */, - SpreadAssignment /* = 293 */, - EnumMember /* = 294 */, - UnparsedPrologue /* = 295 */, - UnparsedPrepend /* = 296 */, - UnparsedText /* = 297 */, - UnparsedInternalText /* = 298 */, - UnparsedSyntheticReference /* = 299 */, - SourceFile /* = 300 */, - Bundle /* = 301 */, - UnparsedSource /* = 302 */, - InputFiles /* = 303 */, - JSDocTypeExpression /* = 304 */, - JSDocNameReference /* = 305 */, - JSDocMemberName /* = 306 */, - JSDocAllType /* = 307 */, - JSDocUnknownType /* = 308 */, - JSDocNullableType /* = 309 */, - JSDocNonNullableType /* = 310 */, - JSDocOptionalType /* = 311 */, - JSDocFunctionType /* = 312 */, - JSDocVariadicType /* = 313 */, - JSDocNamepathType /* = 314 */, - JSDocComment /* = 315 */, - JSDocText /* = 316 */, - JSDocTypeLiteral /* = 317 */, - JSDocSignature /* = 318 */, - JSDocLink /* = 319 */, - JSDocLinkCode /* = 320 */, - JSDocLinkPlain /* = 321 */, - JSDocTag /* = 322 */, - JSDocAugmentsTag /* = 323 */, - JSDocImplementsTag /* = 324 */, - JSDocAuthorTag /* = 325 */, - JSDocDeprecatedTag /* = 326 */, - JSDocClassTag /* = 327 */, - JSDocPublicTag /* = 328 */, - JSDocPrivateTag /* = 329 */, - JSDocProtectedTag /* = 330 */, - JSDocReadonlyTag /* = 331 */, - JSDocOverrideTag /* = 332 */, - JSDocCallbackTag /* = 333 */, - JSDocEnumTag /* = 334 */, - JSDocParameterTag /* = 335 */, - JSDocReturnTag /* = 336 */, - JSDocThisTag /* = 337 */, - JSDocTypeTag /* = 338 */, - JSDocTemplateTag /* = 339 */, - JSDocTypedefTag /* = 340 */, - JSDocSeeTag /* = 341 */, - JSDocPropertyTag /* = 342 */, - SyntaxList /* = 343 */, - NotEmittedStatement /* = 344 */, - PartiallyEmittedExpression /* = 345 */, - CommaListExpression /* = 346 */, - MergeDeclarationMarker /* = 347 */, - EndOfDeclarationMarker /* = 348 */, - SyntheticReferenceExpression /* = 349 */, - Count /* = 350 */, - FirstAssignment /* = 63 */, - LastAssignment /* = 78 */, - FirstCompoundAssignment /* = 64 */, - LastCompoundAssignment /* = 78 */, - FirstReservedWord /* = 81 */, - LastReservedWord /* = 116 */, - FirstKeyword /* = 81 */, - LastKeyword /* = 158 */, - FirstFutureReservedWord /* = 117 */, - LastFutureReservedWord /* = 125 */, - FirstTypeNode /* = 175 */, - LastTypeNode /* = 198 */, - FirstPunctuation /* = 18 */, - LastPunctuation /* = 78 */, - FirstToken /* = 0 */, - LastToken /* = 158 */, - FirstTriviaToken /* = 2 */, - LastTriviaToken /* = 7 */, - FirstLiteralToken /* = 8 */, - LastLiteralToken /* = 14 */, - FirstTemplateToken /* = 14 */, - LastTemplateToken /* = 17 */, - FirstBinaryOperator /* = 29 */, - LastBinaryOperator /* = 78 */, - FirstStatement /* = 235 */, - LastStatement /* = 251 */, - FirstNode /* = 159 */, - FirstJSDocNode /* = 304 */, - LastJSDocNode /* = 342 */, - FirstJSDocTagNode /* = 322 */, - LastJSDocTagNode /* = 342 */ -} - -external enum class NodeFlags { - None /* = 0 */, - Let /* = 1 */, - Const /* = 2 */, - NestedNamespace /* = 4 */, - Synthesized /* = 8 */, - Namespace /* = 16 */, - OptionalChain /* = 32 */, - ExportContext /* = 64 */, - ContainsThis /* = 128 */, - HasImplicitReturn /* = 256 */, - HasExplicitReturn /* = 512 */, - GlobalAugmentation /* = 1024 */, - HasAsyncFunctions /* = 2048 */, - DisallowInContext /* = 4096 */, - YieldContext /* = 8192 */, - DecoratorContext /* = 16384 */, - AwaitContext /* = 32768 */, - ThisNodeHasError /* = 65536 */, - JavaScriptFile /* = 131072 */, - ThisNodeOrAnySubNodesHasError /* = 262144 */, - HasAggregatedChildData /* = 524288 */, - JSDoc /* = 4194304 */, - JsonFile /* = 33554432 */, - BlockScoped /* = 3 */, - ReachabilityCheckFlags /* = 768 */, - ReachabilityAndEmitFlags /* = 2816 */, - ContextFlags /* = 25358336 */, - TypeExcludesFlags /* = 40960 */ -} - -external enum class ModifierFlags { - None /* = 0 */, - Export /* = 1 */, - Ambient /* = 2 */, - Public /* = 4 */, - Private /* = 8 */, - Protected /* = 16 */, - Static /* = 32 */, - Readonly /* = 64 */, - Abstract /* = 128 */, - Async /* = 256 */, - Default /* = 512 */, - Const /* = 2048 */, - HasComputedJSDocModifiers /* = 4096 */, - Deprecated /* = 8192 */, - Override /* = 16384 */, - HasComputedFlags /* = 536870912 */, - AccessibilityModifier /* = 28 */, - ParameterPropertyModifier /* = 16476 */, - NonPublicAccessibilityModifier /* = 24 */, - TypeScriptModifier /* = 18654 */, - ExportDefault /* = 513 */, - All /* = 27647 */ -} - -external enum class JsxFlags { - None /* = 0 */, - IntrinsicNamedElement /* = 1 */, - IntrinsicIndexedElement /* = 2 */, - IntrinsicElement /* = 3 */ -} - -external interface Node : ReadonlyTextRange { - fun getSourceFile(): SourceFile - fun getChildCount(sourceFile: SourceFile = definedExternally): Number - fun getChildAt(index: Number, sourceFile: SourceFile = definedExternally): Node - fun getChildren(sourceFile: SourceFile = definedExternally): Array - fun getStart(sourceFile: SourceFile = definedExternally, includeJsDocComment: Boolean = definedExternally): Number - fun getFullStart(): Number - fun getEnd(): Number - fun getWidth(sourceFile: SourceFileLike = definedExternally): Number - fun getFullWidth(): Number - fun getLeadingTriviaWidth(sourceFile: SourceFile = definedExternally): Number - fun getFullText(sourceFile: SourceFile = definedExternally): String - fun getText(sourceFile: SourceFile = definedExternally): String - fun getFirstToken(sourceFile: SourceFile = definedExternally): Node? - fun getLastToken(sourceFile: SourceFile = definedExternally): Node? - fun forEachChild(cbNode: (node: Node) -> T?, cbNodeArray: (nodes: NodeArray) -> T? = definedExternally): T? - val kind: SyntaxKind - val flags: NodeFlags - val decorators: NodeArray? - get() = definedExternally - val modifiers: ModifiersArray? - get() = definedExternally - val parent: Node -} - -external interface JSDocContainer - -external interface Token : Node { - override val kind: TKind -} - -external interface PunctuationToken : Token - -external interface KeywordToken : Token - -external interface ModifierToken : KeywordToken - -external enum class GeneratedIdentifierFlags { - None /* = 0 */, - ReservedInNestedScopes /* = 8 */, - Optimistic /* = 16 */, - FileLevel /* = 32 */, - AllowNameSubstitution /* = 64 */ -} - -external interface Identifier : PrimaryExpression, Declaration { - val text: String - val escapedText: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - get() = definedExternally - val originalKeywordKind: SyntaxKind? - get() = definedExternally - var isInJSDocNamespace: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TransientIdentifier : Identifier { - var resolvedSymbol: Symbol -} - -external interface QualifiedName : Node { - val left: dynamic /* Identifier | QualifiedName */ - get() = definedExternally - val right: Identifier -} - -external interface Declaration : Node { - var _declarationBrand: Any -} - -external interface NamedDeclaration : Declaration { - val name: dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ - get() = definedExternally -} - -external interface DeclarationStatement : NamedDeclaration, Statement { - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? */ - get() = definedExternally -} - -external interface ComputedPropertyName : Node { - override val parent: Declaration - val expression: Expression -} - -external interface PrivateIdentifier : Node { - val text: String - val escapedText: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - get() = definedExternally -} - -external interface Decorator : Node { - override val parent: NamedDeclaration - val expression: LeftHandSideExpression -} - -external interface TypeParameterDeclaration : NamedDeclaration { - override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | InferTypeNode */ - get() = definedExternally - override val name: Identifier - val constraint: TypeNode? - get() = definedExternally - val default: TypeNode? - get() = definedExternally - var expression: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureDeclarationBase : NamedDeclaration, JSDocContainer { - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - val typeParameters: NodeArray? - get() = definedExternally - val parameters: NodeArray - val type: TypeNode? - get() = definedExternally -} - -external interface CallSignatureDeclaration : SignatureDeclarationBase, TypeElement { - override val kind: SyntaxKind - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally -} - -external interface ConstructSignatureDeclaration : SignatureDeclarationBase, TypeElement { - override val kind: SyntaxKind - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally -} - -external interface VariableDeclaration : NamedDeclaration, JSDocContainer { - override val parent: dynamic /* VariableDeclarationList | CatchClause */ - get() = definedExternally - override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ - get() = definedExternally - val exclamationToken: ExclamationToken? - get() = definedExternally - val type: TypeNode? - get() = definedExternally - val initializer: Expression? - get() = definedExternally -} - -external interface VariableDeclarationList : Node { - override val parent: dynamic /* VariableStatement | ForStatement | ForOfStatement | ForInStatement */ - get() = definedExternally - val declarations: NodeArray -} - -external interface ParameterDeclaration : NamedDeclaration, JSDocContainer { - override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ - get() = definedExternally - val dotDotDotToken: DotDotDotToken? - get() = definedExternally - override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ - get() = definedExternally - val questionToken: QuestionToken? - get() = definedExternally - val type: TypeNode? - get() = definedExternally - val initializer: Expression? - get() = definedExternally -} - -external interface BindingElement : NamedDeclaration { - override val parent: dynamic /* ObjectBindingPattern | ArrayBindingPattern */ - get() = definedExternally - val propertyName: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - val dotDotDotToken: DotDotDotToken? - get() = definedExternally - override val name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ - get() = definedExternally - val initializer: Expression? - get() = definedExternally -} - -external interface PropertySignature : TypeElement, JSDocContainer { - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - override val questionToken: QuestionToken? - get() = definedExternally - val type: TypeNode? - get() = definedExternally - var initializer: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface PropertyDeclaration : ClassElement, JSDocContainer { - override val parent: dynamic /* ClassDeclaration | ClassExpression */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - val questionToken: QuestionToken? - get() = definedExternally - val exclamationToken: ExclamationToken? - get() = definedExternally - val type: TypeNode? - get() = definedExternally - val initializer: Expression? - get() = definedExternally -} - -external interface ObjectLiteralElement : NamedDeclaration { - var _objectLiteralBrand: Any - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally -} - -external interface PropertyAssignment : ObjectLiteralElement, JSDocContainer { - override val parent: ObjectLiteralExpression - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - val questionToken: QuestionToken? - get() = definedExternally - val exclamationToken: ExclamationToken? - get() = definedExternally - val initializer: Expression -} - -external interface ShorthandPropertyAssignment : ObjectLiteralElement, JSDocContainer { - override val parent: ObjectLiteralExpression - override val name: Identifier - val questionToken: QuestionToken? - get() = definedExternally - val exclamationToken: ExclamationToken? - get() = definedExternally - val equalsToken: EqualsToken? - get() = definedExternally - val objectAssignmentInitializer: Expression? - get() = definedExternally -} - -external interface SpreadAssignment : ObjectLiteralElement, JSDocContainer { - override val parent: ObjectLiteralExpression - val expression: Expression -} - -external interface PropertyLikeDeclaration : NamedDeclaration { - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally -} - -external interface ObjectBindingPattern : Node { - override val parent: dynamic /* VariableDeclaration | ParameterDeclaration | BindingElement */ - get() = definedExternally - val elements: NodeArray -} - -external interface ArrayBindingPattern : Node { - override val parent: dynamic /* VariableDeclaration | ParameterDeclaration | BindingElement */ - get() = definedExternally - val elements: NodeArray -} - -external interface FunctionLikeDeclarationBase : SignatureDeclarationBase { - var _functionLikeDeclarationBrand: Any - val asteriskToken: AsteriskToken? - get() = definedExternally - val questionToken: QuestionToken? - get() = definedExternally - val exclamationToken: ExclamationToken? - get() = definedExternally - val body: dynamic /* Block? | Expression? */ - get() = definedExternally -} - -external interface FunctionDeclaration : FunctionLikeDeclarationBase, DeclarationStatement { - override val kind: SyntaxKind - override val name: Identifier? - get() = definedExternally - override val body: FunctionBody? - get() = definedExternally -} - -external interface MethodSignature : SignatureDeclarationBase, TypeElement { - override val kind: SyntaxKind - override val parent: dynamic /* ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally -} - -external interface MethodDeclaration : FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { - override val kind: SyntaxKind - override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - override val body: FunctionBody? - get() = definedExternally -} - -external interface ConstructorDeclaration : FunctionLikeDeclarationBase, ClassElement, JSDocContainer { - override val kind: SyntaxKind - override val parent: dynamic /* ClassDeclaration | ClassExpression */ - get() = definedExternally - override val body: FunctionBody? - get() = definedExternally - override val name: dynamic - get() = definedExternally -} - -external interface SemicolonClassElement : ClassElement { - override val parent: dynamic /* ClassDeclaration | ClassExpression */ - get() = definedExternally -} - -external interface GetAccessorDeclaration : FunctionLikeDeclarationBase, ClassElement, TypeElement, ObjectLiteralElement, JSDocContainer { - override val kind: SyntaxKind - override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression | TypeLiteralNode | InterfaceDeclaration */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - override val body: FunctionBody? - get() = definedExternally - override val questionToken: QuestionToken? - get() = definedExternally -} - -external interface SetAccessorDeclaration : FunctionLikeDeclarationBase, ClassElement, TypeElement, ObjectLiteralElement, JSDocContainer { - override val kind: SyntaxKind - override val parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression | TypeLiteralNode | InterfaceDeclaration */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - override val body: FunctionBody? - get() = definedExternally - override val questionToken: QuestionToken? - get() = definedExternally -} - -external interface IndexSignatureDeclaration : SignatureDeclarationBase, ClassElement, TypeElement { - override val kind: SyntaxKind - override val parent: dynamic /* ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode */ - get() = definedExternally - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally -} - -external interface ClassStaticBlockDeclaration : ClassElement, JSDocContainer { - override val parent: dynamic /* ClassDeclaration | ClassExpression */ - get() = definedExternally - val body: Block -} - -external interface TypeNode : Node { - var _typeNodeBrand: Any -} - -external interface KeywordTypeNode : KeywordToken, TypeNode { - override val kind: TKind -} - -external interface ImportTypeNode : NodeWithTypeArguments { - val isTypeOf: Boolean? - val argument: TypeNode - val qualifier: dynamic /* Identifier? | QualifiedName? */ - get() = definedExternally -} - -external interface ThisTypeNode : TypeNode - -external interface FunctionOrConstructorTypeNodeBase : TypeNode, SignatureDeclarationBase { - override val kind: dynamic /* SyntaxKind.FunctionType | SyntaxKind.ConstructorType */ - get() = definedExternally -} - -external interface FunctionTypeNode : FunctionOrConstructorTypeNodeBase { - override val kind: Any -} - -external interface ConstructorTypeNode : FunctionOrConstructorTypeNodeBase { - override val kind: Any -} - -external interface NodeWithTypeArguments : TypeNode { - val typeArguments: NodeArray? - get() = definedExternally -} - -external interface TypeReferenceNode : NodeWithTypeArguments { - val typeName: dynamic /* Identifier | QualifiedName */ - get() = definedExternally -} - -external interface TypePredicateNode : TypeNode { - override val parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | JSDocTypeExpression */ - get() = definedExternally - val assertsModifier: AssertsToken? - get() = definedExternally - val parameterName: dynamic /* Identifier | ThisTypeNode */ - get() = definedExternally - val type: TypeNode? - get() = definedExternally -} - -external interface TypeQueryNode : TypeNode { - val exprName: dynamic /* Identifier | QualifiedName */ - get() = definedExternally -} - -external interface TypeLiteralNode : TypeNode, Declaration { - val members: NodeArray -} - -external interface ArrayTypeNode : TypeNode { - val elementType: TypeNode -} - -external interface TupleTypeNode : TypeNode { - val elements: NodeArray -} - -external interface NamedTupleMember : TypeNode, JSDocContainer, Declaration { - val dotDotDotToken: Token? - get() = definedExternally - val name: Identifier - val questionToken: Token? - get() = definedExternally - val type: TypeNode -} - -external interface OptionalTypeNode : TypeNode { - val type: TypeNode -} - -external interface RestTypeNode : TypeNode { - val type: TypeNode -} - -external interface UnionTypeNode : TypeNode { - val types: NodeArray -} - -external interface IntersectionTypeNode : TypeNode { - val types: NodeArray -} - -external interface ConditionalTypeNode : TypeNode { - val checkType: TypeNode - val extendsType: TypeNode - val trueType: TypeNode - val falseType: TypeNode -} - -external interface InferTypeNode : TypeNode { - val typeParameter: TypeParameterDeclaration -} - -external interface ParenthesizedTypeNode : TypeNode { - val type: TypeNode -} - -external interface TypeOperatorNode : TypeNode { - val operator: dynamic /* SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword */ - get() = definedExternally - val type: TypeNode -} - -external interface IndexedAccessTypeNode : TypeNode { - val objectType: TypeNode - val indexType: TypeNode -} - -external interface MappedTypeNode : TypeNode, Declaration { - val readonlyToken: dynamic /* ReadonlyToken? | PlusToken? | MinusToken? */ - get() = definedExternally - val typeParameter: TypeParameterDeclaration - val nameType: TypeNode? - get() = definedExternally - val questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */ - get() = definedExternally - val type: TypeNode? - get() = definedExternally -} - -external interface LiteralTypeNode : TypeNode { - val literal: dynamic /* NullLiteral | TrueLiteral | FalseLiteral | LiteralExpression | PrefixUnaryExpression */ - get() = definedExternally -} - -external interface StringLiteral : LiteralExpression, Declaration - -external interface TemplateLiteralTypeNode : TypeNode { - val head: TemplateHead - val templateSpans: NodeArray -} - -external interface TemplateLiteralTypeSpan : TypeNode { - override val parent: TemplateLiteralTypeNode - val type: TypeNode - val literal: dynamic /* TemplateMiddle | TemplateTail */ - get() = definedExternally -} - -external interface Expression : Node { - var _expressionBrand: Any -} - -external interface OmittedExpression : Expression - -external interface PartiallyEmittedExpression : LeftHandSideExpression { - val expression: Expression -} - -external interface UnaryExpression : Expression { - var _unaryExpressionBrand: Any -} - -external interface UpdateExpression : UnaryExpression { - var _updateExpressionBrand: Any -} - -external interface PrefixUnaryExpression : UpdateExpression { - val operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken | SyntaxKind.ExclamationToken */ - get() = definedExternally - val operand: UnaryExpression -} - -external interface PostfixUnaryExpression : UpdateExpression { - val operand: LeftHandSideExpression - val operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken */ - get() = definedExternally -} - -external interface LeftHandSideExpression : UpdateExpression { - var _leftHandSideExpressionBrand: Any -} - -external interface MemberExpression : LeftHandSideExpression { - var _memberExpressionBrand: Any -} - -external interface PrimaryExpression : MemberExpression { - var _primaryExpressionBrand: Any -} - -external interface NullLiteral : PrimaryExpression - -external interface TrueLiteral : PrimaryExpression - -external interface FalseLiteral : PrimaryExpression - -external interface ThisExpression : PrimaryExpression - -external interface SuperExpression : PrimaryExpression - -external interface ImportExpression : PrimaryExpression - -external interface DeleteExpression : UnaryExpression { - val expression: UnaryExpression -} - -external interface TypeOfExpression : UnaryExpression { - val expression: UnaryExpression -} - -external interface VoidExpression : UnaryExpression { - val expression: UnaryExpression -} - -external interface AwaitExpression : UnaryExpression { - val expression: UnaryExpression -} - -external interface YieldExpression : Expression { - val asteriskToken: AsteriskToken? - get() = definedExternally - val expression: Expression? - get() = definedExternally -} - -external interface SyntheticExpression : Expression { - val isSpread: Boolean? - val type: Type - val tupleNameSource: dynamic /* ParameterDeclaration? | NamedTupleMember? */ - get() = definedExternally -} - -external interface BinaryExpression : Expression, Declaration { - val left: Expression - val operatorToken: BinaryOperatorToken - val right: Expression -} - -external interface AssignmentExpression : BinaryExpression { - override val left: LeftHandSideExpression - override val operatorToken: TOperator -} - -external interface ObjectDestructuringAssignment : AssignmentExpression { - override val left: ObjectLiteralExpression -} - -external interface ArrayDestructuringAssignment : AssignmentExpression { - override val left: ArrayLiteralExpression -} - -external interface ConditionalExpression : Expression { - val condition: Expression - val questionToken: QuestionToken - val whenTrue: Expression - val colonToken: ColonToken - val whenFalse: Expression -} - -external interface FunctionExpression : PrimaryExpression, FunctionLikeDeclarationBase, JSDocContainer { - override val kind: SyntaxKind - override val name: Identifier? - get() = definedExternally - override val body: FunctionBody -} - -external interface ArrowFunction : Expression, FunctionLikeDeclarationBase, JSDocContainer { - override val kind: SyntaxKind - val equalsGreaterThanToken: EqualsGreaterThanToken - override val body: dynamic /* FunctionBody | Expression */ - get() = definedExternally - override val name: Any -} - -external interface LiteralLikeNode : Node { - var text: String - var isUnterminated: Boolean? - get() = definedExternally - set(value) = definedExternally - var hasExtendedUnicodeEscape: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TemplateLiteralLikeNode : LiteralLikeNode { - var rawText: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface LiteralExpression : LiteralLikeNode, PrimaryExpression { - var _literalExpressionBrand: Any -} - -external interface RegularExpressionLiteral : LiteralExpression - -external interface NoSubstitutionTemplateLiteral : LiteralExpression, TemplateLiteralLikeNode, Declaration - -external enum class TokenFlags { - None /* = 0 */, - Scientific /* = 16 */, - Octal /* = 32 */, - HexSpecifier /* = 64 */, - BinarySpecifier /* = 128 */, - OctalSpecifier /* = 256 */ -} - -external interface NumericLiteral : LiteralExpression, Declaration - -external interface BigIntLiteral : LiteralExpression - -external interface TemplateHead : TemplateLiteralLikeNode { - override val parent: dynamic /* TemplateExpression | TemplateLiteralTypeNode */ - get() = definedExternally -} - -external interface TemplateMiddle : TemplateLiteralLikeNode { - override val parent: dynamic /* TemplateSpan | TemplateLiteralTypeSpan */ - get() = definedExternally -} - -external interface TemplateTail : TemplateLiteralLikeNode { - override val parent: dynamic /* TemplateSpan | TemplateLiteralTypeSpan */ - get() = definedExternally -} - -external interface TemplateExpression : PrimaryExpression { - val head: TemplateHead - val templateSpans: NodeArray -} - -external interface TemplateSpan : Node { - override val parent: TemplateExpression - val expression: Expression - val literal: dynamic /* TemplateMiddle | TemplateTail */ - get() = definedExternally -} - -external interface ParenthesizedExpression : PrimaryExpression, JSDocContainer { - val expression: Expression -} - -external interface ArrayLiteralExpression : PrimaryExpression { - val elements: NodeArray -} - -external interface SpreadElement : Expression { - override val parent: dynamic /* ArrayLiteralExpression | CallExpression | NewExpression */ - get() = definedExternally - val expression: Expression -} - -external interface ObjectLiteralExpressionBase : PrimaryExpression, Declaration { - val properties: NodeArray -} - -external interface ObjectLiteralExpression : ObjectLiteralExpressionBase - -external interface PropertyAccessExpression : MemberExpression, NamedDeclaration { - val expression: LeftHandSideExpression - val questionDotToken: QuestionDotToken? - get() = definedExternally - override val name: dynamic /* Identifier | PrivateIdentifier */ - get() = definedExternally -} - -external interface PropertyAccessChain : PropertyAccessExpression { - var _optionalChainBrand: Any - override val name: dynamic /* Identifier | PrivateIdentifier */ - get() = definedExternally -} - -external interface SuperPropertyAccessExpression : PropertyAccessExpression { - override val expression: SuperExpression -} - -external interface PropertyAccessEntityNameExpression : PropertyAccessExpression { - var _propertyAccessExpressionLikeQualifiedNameBrand: Any? - get() = definedExternally - set(value) = definedExternally - override val expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ - get() = definedExternally - override val name: Identifier -} - -external interface ElementAccessExpression : MemberExpression { - val expression: LeftHandSideExpression - val questionDotToken: QuestionDotToken? - get() = definedExternally - val argumentExpression: Expression -} - -external interface ElementAccessChain : ElementAccessExpression { - var _optionalChainBrand: Any -} - -external interface SuperElementAccessExpression : ElementAccessExpression { - override val expression: SuperExpression -} - -external interface CallExpression : LeftHandSideExpression, Declaration { - val expression: LeftHandSideExpression - val questionDotToken: QuestionDotToken? - get() = definedExternally - val typeArguments: NodeArray? - get() = definedExternally - val arguments: NodeArray -} - -external interface CallChain : CallExpression { - var _optionalChainBrand: Any -} - -external interface SuperCall : CallExpression { - override val expression: SuperExpression -} - -external interface ImportCall : CallExpression { - override val expression: ImportExpression -} - -external interface ExpressionWithTypeArguments : NodeWithTypeArguments { - override val parent: dynamic /* HeritageClause | JSDocAugmentsTag | JSDocImplementsTag */ - get() = definedExternally - val expression: LeftHandSideExpression -} - -external interface NewExpression : PrimaryExpression, Declaration { - val expression: LeftHandSideExpression - val typeArguments: NodeArray? - get() = definedExternally - val arguments: NodeArray? - get() = definedExternally -} - -external interface TaggedTemplateExpression : MemberExpression { - val tag: LeftHandSideExpression - val typeArguments: NodeArray? - get() = definedExternally - val template: dynamic /* TemplateExpression | NoSubstitutionTemplateLiteral */ - get() = definedExternally -} - -external interface AsExpression : Expression { - val expression: Expression - val type: TypeNode -} - -external interface TypeAssertion : UnaryExpression { - val type: TypeNode - val expression: UnaryExpression -} - -external interface NonNullExpression : LeftHandSideExpression { - val expression: Expression -} - -external interface NonNullChain : NonNullExpression { - var _optionalChainBrand: Any -} - -external interface MetaProperty : PrimaryExpression { - val keywordToken: dynamic /* SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword */ - get() = definedExternally - val name: Identifier -} - -external interface JsxElement : PrimaryExpression { - val openingElement: JsxOpeningElement - val children: NodeArray - val closingElement: JsxClosingElement -} - -external interface JsxTagNamePropertyAccess : PropertyAccessExpression { - override val expression: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ - get() = definedExternally -} - -external interface JsxAttributes : ObjectLiteralExpressionBase { - override val parent: dynamic /* JsxSelfClosingElement | JsxOpeningElement */ - get() = definedExternally -} - -external interface JsxOpeningElement : Expression { - override val parent: JsxElement - val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ - get() = definedExternally - val typeArguments: NodeArray? - get() = definedExternally - val attributes: JsxAttributes -} - -external interface JsxSelfClosingElement : PrimaryExpression { - val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ - get() = definedExternally - val typeArguments: NodeArray? - get() = definedExternally - val attributes: JsxAttributes -} - -external interface JsxFragment : PrimaryExpression { - val openingFragment: JsxOpeningFragment - val children: NodeArray - val closingFragment: JsxClosingFragment -} - -external interface JsxOpeningFragment : Expression { - override val parent: JsxFragment -} - -external interface JsxClosingFragment : Expression { - override val parent: JsxFragment -} - -external interface JsxAttribute : ObjectLiteralElement { - override val parent: JsxAttributes - override val name: Identifier - val initializer: dynamic /* StringLiteral? | JsxExpression? */ - get() = definedExternally -} - -external interface JsxSpreadAttribute : ObjectLiteralElement { - override val parent: JsxAttributes - val expression: Expression -} - -external interface JsxClosingElement : Node { - override val parent: JsxElement - val tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ - get() = definedExternally -} - -external interface JsxExpression : Expression { - override val parent: dynamic /* JsxElement | JsxAttribute | JsxSpreadAttribute */ - get() = definedExternally - val dotDotDotToken: Token? - get() = definedExternally - val expression: Expression? - get() = definedExternally -} - -external interface JsxText : LiteralLikeNode { - override val parent: JsxElement - val containsOnlyTriviaWhiteSpaces: Boolean? -} - -external interface Statement : Node, JSDocContainer { - var _statementBrand: Any -} - -external interface NotEmittedStatement : Statement - -external interface CommaListExpression : Expression { - val elements: NodeArray -} - -external interface EmptyStatement : Statement - -external interface DebuggerStatement : Statement - -external interface MissingDeclaration : DeclarationStatement { - override val name: Identifier? - get() = definedExternally -} - -external interface Block : Statement { - val statements: NodeArray -} - -external interface VariableStatement : Statement { - val declarationList: VariableDeclarationList -} - -external interface ExpressionStatement : Statement { - val expression: Expression -} - -external interface IfStatement : Statement { - val expression: Expression - val thenStatement: Statement - val elseStatement: Statement? - get() = definedExternally -} - -external interface IterationStatement : Statement { - val statement: Statement -} - -external interface DoStatement : IterationStatement { - val expression: Expression -} - -external interface WhileStatement : IterationStatement { - val expression: Expression -} - -external interface ForStatement : IterationStatement { - val initializer: dynamic /* VariableDeclarationList? | Expression? */ - get() = definedExternally - val condition: Expression? - get() = definedExternally - val incrementor: Expression? - get() = definedExternally -} - -external interface ForInStatement : IterationStatement { - val initializer: dynamic /* VariableDeclarationList | Expression */ - get() = definedExternally - val expression: Expression -} - -external interface ForOfStatement : IterationStatement { - val awaitModifier: AwaitKeywordToken? - get() = definedExternally - val initializer: dynamic /* VariableDeclarationList | Expression */ - get() = definedExternally - val expression: Expression -} - -external interface BreakStatement : Statement { - val label: Identifier? - get() = definedExternally -} - -external interface ContinueStatement : Statement { - val label: Identifier? - get() = definedExternally -} - -external interface ReturnStatement : Statement { - val expression: Expression? - get() = definedExternally -} - -external interface WithStatement : Statement { - val expression: Expression - val statement: Statement -} - -external interface SwitchStatement : Statement { - val expression: Expression - val caseBlock: CaseBlock - var possiblyExhaustive: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface CaseBlock : Node { - override val parent: SwitchStatement - val clauses: NodeArray -} - -external interface CaseClause : Node { - override val parent: CaseBlock - val expression: Expression - val statements: NodeArray -} - -external interface DefaultClause : Node { - override val parent: CaseBlock - val statements: NodeArray -} - -external interface LabeledStatement : Statement { - val label: Identifier - val statement: Statement -} - -external interface ThrowStatement : Statement { - val expression: Expression -} - -external interface TryStatement : Statement { - val tryBlock: Block - val catchClause: CatchClause? - get() = definedExternally - val finallyBlock: Block? - get() = definedExternally -} - -external interface CatchClause : Node { - override val parent: TryStatement - val variableDeclaration: VariableDeclaration? - get() = definedExternally - val block: Block -} - -external interface ClassLikeDeclarationBase : NamedDeclaration, JSDocContainer { - override val kind: dynamic /* SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression */ - get() = definedExternally - override val name: Identifier? - get() = definedExternally - val typeParameters: NodeArray? - get() = definedExternally - val heritageClauses: NodeArray? - get() = definedExternally - val members: NodeArray -} - -external interface ClassDeclaration : ClassLikeDeclarationBase, DeclarationStatement { - override val kind: SyntaxKind - override val name: Identifier? - get() = definedExternally -} - -external interface ClassExpression : ClassLikeDeclarationBase, PrimaryExpression { - override val kind: SyntaxKind -} - -external interface ClassElement : NamedDeclaration { - var _classElementBrand: Any - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally -} - -external interface TypeElement : NamedDeclaration { - var _typeElementBrand: Any - override val name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - val questionToken: QuestionToken? - get() = definedExternally -} - -external interface InterfaceDeclaration : DeclarationStatement, JSDocContainer { - override val name: Identifier - val typeParameters: NodeArray? - get() = definedExternally - val heritageClauses: NodeArray? - get() = definedExternally - val members: NodeArray -} - -external interface HeritageClause : Node { - override val parent: dynamic /* InterfaceDeclaration | ClassDeclaration | ClassExpression */ - get() = definedExternally - val token: dynamic /* SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword */ - get() = definedExternally - val types: NodeArray -} - -external interface TypeAliasDeclaration : DeclarationStatement, JSDocContainer { - override val name: Identifier - val typeParameters: NodeArray? - get() = definedExternally - val type: TypeNode -} - -external interface EnumMember : NamedDeclaration, JSDocContainer { - override val parent: EnumDeclaration - override val name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - val initializer: Expression? - get() = definedExternally -} - -external interface EnumDeclaration : DeclarationStatement, JSDocContainer { - override val name: Identifier - val members: NodeArray -} - -external interface ModuleDeclaration : DeclarationStatement, JSDocContainer { - override val parent: dynamic /* ModuleBlock | NamespaceDeclaration | Identifier | JSDocNamespaceDeclaration | SourceFile */ - get() = definedExternally - override val name: dynamic /* Identifier | StringLiteral */ - get() = definedExternally - val body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */ - get() = definedExternally -} - -external interface NamespaceDeclaration : ModuleDeclaration { - override val name: Identifier - override val body: dynamic /* ModuleBlock | NamespaceDeclaration */ - get() = definedExternally -} - -external interface JSDocNamespaceDeclaration : ModuleDeclaration { - override val name: Identifier - override val body: dynamic /* Identifier? | JSDocNamespaceDeclaration? */ - get() = definedExternally -} - -external interface ModuleBlock : Node, Statement { - override val parent: ModuleDeclaration - val statements: NodeArray -} - -external interface ImportEqualsDeclaration : DeclarationStatement, JSDocContainer { - override val parent: dynamic /* SourceFile | ModuleBlock */ - get() = definedExternally - override val name: Identifier - val isTypeOnly: Boolean? - val moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */ - get() = definedExternally -} - -external interface ExternalModuleReference : Node { - override val parent: ImportEqualsDeclaration - val expression: Expression -} - -external interface ImportDeclaration : Statement { - override val parent: dynamic /* SourceFile | ModuleBlock */ - get() = definedExternally - val importClause: ImportClause? - get() = definedExternally - val moduleSpecifier: Expression -} - -external interface ImportClause : NamedDeclaration { - override val parent: ImportDeclaration - val isTypeOnly: Boolean? - override val name: Identifier? - get() = definedExternally - val namedBindings: dynamic /* NamespaceImport? | NamedImports? */ - get() = definedExternally -} - -external interface NamespaceImport : NamedDeclaration { - override val parent: ImportClause - override val name: Identifier -} - -external interface NamespaceExport : NamedDeclaration { - override val parent: ExportDeclaration - override val name: Identifier -} - -external interface NamespaceExportDeclaration : DeclarationStatement, JSDocContainer { - override val name: Identifier -} - -external interface ExportDeclaration : DeclarationStatement, JSDocContainer { - override val parent: dynamic /* SourceFile | ModuleBlock */ - get() = definedExternally - val isTypeOnly: Boolean? - val exportClause: dynamic /* NamespaceExport? | NamedExports? */ - get() = definedExternally - val moduleSpecifier: Expression? - get() = definedExternally -} - -external interface NamedImports : Node { - override val parent: ImportClause - val elements: NodeArray -} - -external interface NamedExports : Node { - override val parent: ExportDeclaration - val elements: NodeArray -} - -external interface ImportSpecifier : NamedDeclaration { - override val parent: NamedImports - val propertyName: Identifier? - get() = definedExternally - override val name: Identifier -} - -external interface ExportSpecifier : NamedDeclaration { - override val parent: NamedExports - val propertyName: Identifier? - get() = definedExternally - override val name: Identifier -} - -external interface ExportAssignment : DeclarationStatement, JSDocContainer { - override val parent: SourceFile - val isExportEquals: Boolean? - get() = definedExternally - val expression: Expression -} - -external interface FileReference : TextRange { - var fileName: String -} - -external interface CheckJsDirective : TextRange { - var enabled: Boolean? -} - -external interface CommentRange : TextRange { - var hasTrailingNewLine: Boolean? - get() = definedExternally - set(value) = definedExternally - var kind: dynamic /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */ - get() = definedExternally - set(value) = definedExternally -} - -external interface SynthesizedComment : CommentRange { - var text: String - var hasLeadingNewline: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface JSDocTypeExpression : TypeNode { - val type: TypeNode -} - -external interface JSDocNameReference : Node { - val name: dynamic /* Identifier | QualifiedName | JSDocMemberName */ - get() = definedExternally -} - -external interface JSDocMemberName : Node { - val left: dynamic /* Identifier | QualifiedName | JSDocMemberName */ - get() = definedExternally - val right: Identifier -} - -external interface JSDocType : TypeNode { - var _jsDocTypeBrand: Any -} - -external interface JSDocAllType : JSDocType - -external interface JSDocUnknownType : JSDocType - -external interface JSDocNonNullableType : JSDocType { - val type: TypeNode -} - -external interface JSDocNullableType : JSDocType { - val type: TypeNode -} - -external interface JSDocOptionalType : JSDocType { - val type: TypeNode -} - -external interface JSDocFunctionType : JSDocType, SignatureDeclarationBase { - override val kind: SyntaxKind -} - -external interface JSDocVariadicType : JSDocType { - val type: TypeNode -} - -external interface JSDocNamepathType : JSDocType { - val type: TypeNode -} - -external interface JSDoc : Node { - override val parent: dynamic /* ParameterDeclaration | CallSignatureDeclaration | ClassStaticBlockDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | EmptyStatement | DebuggerStatement | Block | VariableStatement | ExpressionStatement | IfStatement | DoStatement | WhileStatement | ForStatement | ForInStatement | ForOfStatement | BreakStatement | ContinueStatement | ReturnStatement | WithStatement | SwitchStatement | LabeledStatement | ThrowStatement | TryStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | VariableDeclaration | PropertyDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | NamespaceExportDeclaration | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | Token & JSDocContainer */ - get() = definedExternally - val tags: NodeArray? - get() = definedExternally - val comment: dynamic /* String? | NodeArray? */ - get() = definedExternally -} - -external interface JSDocTag : Node { - override val parent: dynamic /* JSDoc | JSDocTypeLiteral */ - get() = definedExternally - val tagName: Identifier - val comment: dynamic /* String? | NodeArray? */ - get() = definedExternally -} - -external interface JSDocLink : Node { - val name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ - get() = definedExternally - var text: String -} - -external interface JSDocLinkCode : Node { - val name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ - get() = definedExternally - var text: String -} - -external interface JSDocLinkPlain : Node { - val name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ - get() = definedExternally - var text: String -} - -external interface JSDocText : Node { - var text: String -} - -external interface JSDocUnknownTag : JSDocTag - -external interface `T$21` { - val expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ - get() = definedExternally -} - -external interface JSDocAugmentsTag : JSDocTag { - val `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */ -} - -external interface JSDocImplementsTag : JSDocTag { - val `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */ -} - -external interface JSDocAuthorTag : JSDocTag - -external interface JSDocDeprecatedTag : JSDocTag - -external interface JSDocClassTag : JSDocTag - -external interface JSDocPublicTag : JSDocTag - -external interface JSDocPrivateTag : JSDocTag - -external interface JSDocProtectedTag : JSDocTag - -external interface JSDocReadonlyTag : JSDocTag - -external interface JSDocOverrideTag : JSDocTag - -external interface JSDocEnumTag : JSDocTag, Declaration { - override val parent: JSDoc - val typeExpression: JSDocTypeExpression -} - -external interface JSDocThisTag : JSDocTag { - val typeExpression: JSDocTypeExpression -} - -external interface JSDocTemplateTag : JSDocTag { - val constraint: JSDocTypeExpression? - val typeParameters: NodeArray -} - -external interface JSDocSeeTag : JSDocTag { - val name: JSDocNameReference? - get() = definedExternally -} - -external interface JSDocReturnTag : JSDocTag { - val typeExpression: JSDocTypeExpression? - get() = definedExternally -} - -external interface JSDocTypeTag : JSDocTag { - val typeExpression: JSDocTypeExpression -} - -external interface JSDocTypedefTag : JSDocTag, NamedDeclaration { - override val parent: JSDoc - val fullName: dynamic /* JSDocNamespaceDeclaration? | Identifier? */ - get() = definedExternally - override val name: Identifier? - get() = definedExternally - val typeExpression: dynamic /* JSDocTypeExpression? | JSDocTypeLiteral? */ - get() = definedExternally -} - -external interface JSDocCallbackTag : JSDocTag, NamedDeclaration { - override val parent: JSDoc - val fullName: dynamic /* JSDocNamespaceDeclaration? | Identifier? */ - get() = definedExternally - override val name: Identifier? - get() = definedExternally - val typeExpression: JSDocSignature -} - -external interface JSDocSignature : JSDocType, Declaration { - val typeParameters: Array? - get() = definedExternally - val parameters: Array - val type: JSDocReturnTag? -} - -external interface JSDocPropertyLikeTag : JSDocTag, Declaration { - override val parent: JSDoc - val name: dynamic /* Identifier | QualifiedName */ - get() = definedExternally - val typeExpression: JSDocTypeExpression? - get() = definedExternally - val isNameFirst: Boolean? - val isBracketed: Boolean? -} - -external interface JSDocPropertyTag : JSDocPropertyLikeTag - -external interface JSDocParameterTag : JSDocPropertyLikeTag - -external interface JSDocTypeLiteral : JSDocType { - val jsDocPropertyTags: Array? - get() = definedExternally - val isArrayType: Boolean? -} - -external enum class FlowFlags { - Unreachable /* = 1 */, - Start /* = 2 */, - BranchLabel /* = 4 */, - LoopLabel /* = 8 */, - Assignment /* = 16 */, - TrueCondition /* = 32 */, - FalseCondition /* = 64 */, - SwitchClause /* = 128 */, - ArrayMutation /* = 256 */, - Call /* = 512 */, - ReduceLabel /* = 1024 */, - Referenced /* = 2048 */, - Shared /* = 4096 */, - Label /* = 12 */, - Condition /* = 96 */ -} - -external interface FlowNodeBase { - var flags: FlowFlags - var id: Number? - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowStart : FlowNodeBase { - var node: dynamic /* FunctionExpression? | ArrowFunction? | MethodDeclaration? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowLabel : FlowNodeBase { - var antecedents: Array? -} - -external interface FlowAssignment : FlowNodeBase { - var node: dynamic /* Expression | VariableDeclaration | BindingElement */ - get() = definedExternally - set(value) = definedExternally - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowCall : FlowNodeBase { - var node: CallExpression - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowCondition : FlowNodeBase { - var node: Expression - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowSwitchClause : FlowNodeBase { - var switchStatement: SwitchStatement - var clauseStart: Number - var clauseEnd: Number - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowArrayMutation : FlowNodeBase { - var node: dynamic /* CallExpression | BinaryExpression */ - get() = definedExternally - set(value) = definedExternally - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowReduceLabel : FlowNodeBase { - var target: FlowLabel - var antecedents: Array - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface IncompleteType { - var flags: TypeFlags - var type: Type -} - -external interface AmdDependency { - var path: String - var name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface SourceFile : Declaration { - fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter - fun getLineEndOfPosition(pos: Number): Number - fun getLineStarts(): Array - fun getPositionOfLineAndCharacter(line: Number, character: Number): Number - fun update(newText: String, textChangeRange: TextChangeRange): SourceFile - val statements: NodeArray - val endOfFileToken: Token - var fileName: String - var text: String - var amdDependencies: Array - var moduleName: String? - get() = definedExternally - set(value) = definedExternally - var referencedFiles: Array - var typeReferenceDirectives: Array - var libReferenceDirectives: Array - var languageVariant: LanguageVariant - var isDeclarationFile: Boolean? - var hasNoDefaultLib: Boolean? - var languageVersion: ScriptTarget -} - -external interface Bundle : Node { - val prepends: Array - val sourceFiles: Array -} - -external interface InputFiles : Node { - var javascriptPath: String? - get() = definedExternally - set(value) = definedExternally - var javascriptText: String - var javascriptMapPath: String? - get() = definedExternally - set(value) = definedExternally - var javascriptMapText: String? - get() = definedExternally - set(value) = definedExternally - var declarationPath: String? - get() = definedExternally - set(value) = definedExternally - var declarationText: String - var declarationMapPath: String? - get() = definedExternally - set(value) = definedExternally - var declarationMapText: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface UnparsedSource : Node { - var fileName: String - var text: String - val prologues: Array - var helpers: Array? - var referencedFiles: Array - var typeReferenceDirectives: Array? - var libReferenceDirectives: Array - var hasNoDefaultLib: Boolean? - get() = definedExternally - set(value) = definedExternally - var sourceMapPath: String? - get() = definedExternally - set(value) = definedExternally - var sourceMapText: String? - get() = definedExternally - set(value) = definedExternally - val syntheticReferences: Array? - get() = definedExternally - val texts: Array -} - -external interface UnparsedSection : Node { - override val kind: SyntaxKind - override val parent: UnparsedSource - val data: String? - get() = definedExternally -} - -external interface UnparsedPrologue : UnparsedSection { - override val parent: UnparsedSource -} - -external interface UnparsedPrepend : UnparsedSection { - override val parent: UnparsedSource - val texts: Array -} - -external interface UnparsedTextLike : UnparsedSection { - override val kind: dynamic /* SyntaxKind.UnparsedText | SyntaxKind.UnparsedInternalText */ - get() = definedExternally - override val parent: UnparsedSource -} - -external interface UnparsedSyntheticReference : UnparsedSection { - override val parent: UnparsedSource -} - -external interface JsonSourceFile : SourceFile { - override val statements: NodeArray -} - -external interface TsConfigSourceFile : JsonSourceFile { - var extendedSourceFiles: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface JsonMinusNumericLiteral : PrefixUnaryExpression { - override val kind: SyntaxKind - override val operator: Any - override val operand: NumericLiteral -} - -external interface JsonObjectExpressionStatement : ExpressionStatement { - override val expression: dynamic /* ObjectLiteralExpression | ArrayLiteralExpression | JsonMinusNumericLiteral | NumericLiteral | StringLiteral | TrueLiteral | FalseLiteral | NullLiteral */ - get() = definedExternally -} - -external interface ScriptReferenceHost { - fun getCompilerOptions(): CompilerOptions - fun getSourceFile(fileName: String): SourceFile? - fun getSourceFileByPath(path: String /* String & `T$3` */): SourceFile? - fun getCurrentDirectory(): String -} - -external interface ParseConfigHost { - var useCaseSensitiveFileNames: Boolean? - fun readDirectory(rootDir: String, extensions: Array, excludes: Array?, includes: Array, depth: Number = definedExternally): Array - fun fileExists(path: String): Boolean - fun readFile(path: String): String? - val trace: ((s: String) -> Unit)? -} - -open external class OperationCanceledException - -external interface CancellationToken { - fun isCancellationRequested(): Boolean - fun throwIfCancellationRequested() -} - -external interface Program : ScriptReferenceHost { - override fun getCurrentDirectory(): String - fun getRootFileNames(): Array - fun getSourceFiles(): Array - fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult - fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getDeclarationDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getConfigFileParsingDiagnostics(): Array - fun getTypeChecker(): TypeChecker - fun getNodeCount(): Number - fun getIdentifierCount(): Number - fun getSymbolCount(): Number - fun getTypeCount(): Number - fun getInstantiationCount(): Number -// fun getRelationCacheSizes(): `T$6` - fun isSourceFileFromExternalLibrary(file: SourceFile): Boolean - fun isSourceFileDefaultLibrary(file: SourceFile): Boolean - fun getProjectReferences(): Array? - fun getResolvedProjectReferences(): Array? -} - -external interface ResolvedProjectReference { - var commandLine: ParsedCommandLine - var sourceFile: SourceFile - var references: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface CustomTransformer { - fun transformSourceFile(node: SourceFile): SourceFile - fun transformBundle(node: Bundle): Bundle -} - -external interface CustomTransformers { - var before: Array | CustomTransformerFactory */>? - get() = definedExternally - set(value) = definedExternally - var after: Array | CustomTransformerFactory */>? - get() = definedExternally - set(value) = definedExternally - var afterDeclarations: Array | CustomTransformerFactory */>? - get() = definedExternally - set(value) = definedExternally -} - -external interface SourceMapSpan { - var emittedLine: Number - var emittedColumn: Number - var sourceLine: Number - var sourceColumn: Number - var nameIndex: Number? - get() = definedExternally - set(value) = definedExternally - var sourceIndex: Number -} - -external enum class ExitStatus { - Success /* = 0 */, - DiagnosticsPresent_OutputsSkipped /* = 1 */, - DiagnosticsPresent_OutputsGenerated /* = 2 */, - InvalidProject_OutputsSkipped /* = 3 */, - ProjectReferenceCycle_OutputsSkipped /* = 4 */, - ProjectReferenceCycle_OutputsSkupped /* = 4 */ -} - -external interface EmitResult { - var emitSkipped: Boolean? - var diagnostics: Array - var emittedFiles: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$22` { - var typeArguments: NodeArray? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeChecker { - fun getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type - fun getDeclaredTypeOfSymbol(symbol: Symbol): Type - fun getPropertiesOfType(type: Type): Array - fun getPropertyOfType(type: Type, propertyName: String): Symbol? - fun getPrivateIdentifierPropertyOfType(leftType: Type, name: String, location: Node): Symbol? - fun getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo? - fun getIndexInfosOfType(type: Type): Array - fun getSignaturesOfType(type: Type, kind: SignatureKind): Array - fun getIndexTypeOfType(type: Type, kind: IndexKind): Type? - fun getBaseTypes(type: InterfaceType): Array - fun getBaseTypeOfLiteralType(type: Type): Type - fun getWidenedType(type: Type): Type - fun getReturnTypeOfSignature(signature: Signature): Type - fun getNullableType(type: Type, flags: TypeFlags): Type - fun getNonNullableType(type: Type): Type - fun getTypeArguments(type: TypeReference): Array - fun typeToTypeNode(type: Type, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeNode? - fun signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ - fun indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): IndexSignatureDeclaration? - fun symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* Identifier? | QualifiedName? */ - fun symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): Expression? - fun symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): NodeArray? - fun symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): ParameterDeclaration? - fun typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeParameterDeclaration? - fun getSymbolsInScope(location: Node, meaning: SymbolFlags): Array - fun getSymbolAtLocation(node: Node): Symbol? - fun getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: String): Array - fun getShorthandAssignmentValueSymbol(location: Node?): Symbol? - fun getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol? - fun getExportSpecifierLocalTargetSymbol(location: Identifier): Symbol? - fun getExportSymbolOfSymbol(symbol: Symbol): Symbol - fun getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol? - fun getTypeOfAssignmentPattern(pattern: ObjectLiteralExpression): Type - fun getTypeOfAssignmentPattern(pattern: ArrayLiteralExpression): Type - fun getTypeAtLocation(node: Node): Type - fun getTypeFromTypeNode(node: TypeNode): Type - fun signatureToString(signature: Signature, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally, kind: SignatureKind = definedExternally): String - fun typeToString(type: Type, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun symbolToString(symbol: Symbol, enclosingDeclaration: Node = definedExternally, meaning: SymbolFlags = definedExternally, flags: SymbolFormatFlags = definedExternally): String - fun typePredicateToString(predicate: ThisTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun typePredicateToString(predicate: ThisTypePredicate): String - fun typePredicateToString(predicate: ThisTypePredicate, enclosingDeclaration: Node = definedExternally): String - fun typePredicateToString(predicate: IdentifierTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun typePredicateToString(predicate: IdentifierTypePredicate): String - fun typePredicateToString(predicate: IdentifierTypePredicate, enclosingDeclaration: Node = definedExternally): String - fun typePredicateToString(predicate: AssertsThisTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun typePredicateToString(predicate: AssertsThisTypePredicate): String - fun typePredicateToString(predicate: AssertsThisTypePredicate, enclosingDeclaration: Node = definedExternally): String - fun typePredicateToString(predicate: AssertsIdentifierTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun typePredicateToString(predicate: AssertsIdentifierTypePredicate): String - fun typePredicateToString(predicate: AssertsIdentifierTypePredicate, enclosingDeclaration: Node = definedExternally): String - fun getFullyQualifiedName(symbol: Symbol): String - fun getAugmentedPropertiesOfType(type: Type): Array - fun getRootSymbols(symbol: Symbol): Array - fun getSymbolOfExpando(node: Node, allowDeclaration: Boolean): Symbol? - fun getContextualType(node: Expression): Type? - fun getResolvedSignature(node: CallExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: CallExpression): Signature? - fun getResolvedSignature(node: CallExpression, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: NewExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: NewExpression): Signature? - fun getResolvedSignature(node: NewExpression, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: TaggedTemplateExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: TaggedTemplateExpression): Signature? - fun getResolvedSignature(node: TaggedTemplateExpression, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: Decorator, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: Decorator): Signature? - fun getResolvedSignature(node: Decorator, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: JsxSelfClosingElement, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: JsxSelfClosingElement): Signature? - fun getResolvedSignature(node: JsxSelfClosingElement, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: JsxOpeningElement, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: JsxOpeningElement): Signature? - fun getResolvedSignature(node: JsxOpeningElement, candidatesOutArray: Array = definedExternally): Signature? - fun getSignatureFromDeclaration(declaration: CallSignatureDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: ConstructSignatureDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: MethodSignature): Signature? - fun getSignatureFromDeclaration(declaration: IndexSignatureDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: FunctionTypeNode): Signature? - fun getSignatureFromDeclaration(declaration: ConstructorTypeNode): Signature? - fun getSignatureFromDeclaration(declaration: JSDocFunctionType): Signature? - fun getSignatureFromDeclaration(declaration: FunctionDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: MethodDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: ConstructorDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: GetAccessorDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: SetAccessorDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: FunctionExpression): Signature? - fun getSignatureFromDeclaration(declaration: ArrowFunction): Signature? - fun isImplementationOfOverload(node: CallSignatureDeclaration): Boolean? - fun isImplementationOfOverload(node: ConstructSignatureDeclaration): Boolean? - fun isImplementationOfOverload(node: MethodSignature): Boolean? - fun isImplementationOfOverload(node: IndexSignatureDeclaration): Boolean? - fun isImplementationOfOverload(node: FunctionTypeNode): Boolean? - fun isImplementationOfOverload(node: ConstructorTypeNode): Boolean? - fun isImplementationOfOverload(node: JSDocFunctionType): Boolean? - fun isImplementationOfOverload(node: FunctionDeclaration): Boolean? - fun isImplementationOfOverload(node: MethodDeclaration): Boolean? - fun isImplementationOfOverload(node: ConstructorDeclaration): Boolean? - fun isImplementationOfOverload(node: GetAccessorDeclaration): Boolean? - fun isImplementationOfOverload(node: SetAccessorDeclaration): Boolean? - fun isImplementationOfOverload(node: FunctionExpression): Boolean? - fun isImplementationOfOverload(node: ArrowFunction): Boolean? - fun isUndefinedSymbol(symbol: Symbol): Boolean - fun isArgumentsSymbol(symbol: Symbol): Boolean - fun isUnknownSymbol(symbol: Symbol): Boolean - fun getConstantValue(node: EnumMember): dynamic /* String? | Number? */ - fun getConstantValue(node: PropertyAccessExpression): dynamic /* String? | Number? */ - fun getConstantValue(node: ElementAccessExpression): dynamic /* String? | Number? */ - fun isValidPropertyAccess(node: PropertyAccessExpression, propertyName: String): Boolean - fun isValidPropertyAccess(node: QualifiedName, propertyName: String): Boolean - fun isValidPropertyAccess(node: ImportTypeNode, propertyName: String): Boolean - fun getAliasedSymbol(symbol: Symbol): Symbol - fun getImmediateAliasedSymbol(symbol: Symbol): Symbol? - fun getExportsOfModule(moduleSymbol: Symbol): Array - fun getJsxIntrinsicTagNamesAt(location: Node): Array - fun isOptionalParameter(node: ParameterDeclaration): Boolean - fun getAmbientModules(): Array - fun tryGetMemberInModuleExports(memberName: String, moduleSymbol: Symbol): Symbol? - fun getApparentType(type: Type): Type - fun getBaseConstraintOfType(type: Type): Type? - fun getDefaultFromTypeParameter(type: Type): Type? - fun runWithCancellationToken(token: CancellationToken, cb: (checker: TypeChecker) -> T): T -} - -external enum class NodeBuilderFlags { - None /* = 0 */, - NoTruncation /* = 1 */, - WriteArrayAsGenericType /* = 2 */, - GenerateNamesForShadowedTypeParams /* = 4 */, - UseStructuralFallback /* = 8 */, - ForbidIndexedAccessSymbolReferences /* = 16 */, - WriteTypeArgumentsOfSignature /* = 32 */, - UseFullyQualifiedType /* = 64 */, - UseOnlyExternalAliasing /* = 128 */, - SuppressAnyReturnType /* = 256 */, - WriteTypeParametersInQualifiedName /* = 512 */, - MultilineObjectLiterals /* = 1024 */, - WriteClassExpressionAsTypeLiteral /* = 2048 */, - UseTypeOfFunction /* = 4096 */, - OmitParameterModifiers /* = 8192 */, - UseAliasDefinedOutsideCurrentScope /* = 16384 */, - UseSingleQuotesForStringLiteralType /* = 268435456 */, - NoTypeReduction /* = 536870912 */, - NoUndefinedOptionalParameterType /* = 1073741824 */, - AllowThisInObjectLiteral /* = 32768 */, - AllowQualifiedNameInPlaceOfIdentifier /* = 65536 */, - AllowQualifedNameInPlaceOfIdentifier /* = 65536 */, - AllowAnonymousIdentifier /* = 131072 */, - AllowEmptyUnionOrIntersection /* = 262144 */, - AllowEmptyTuple /* = 524288 */, - AllowUniqueESSymbolType /* = 1048576 */, - AllowEmptyIndexInfoType /* = 2097152 */, - AllowNodeModulesRelativePaths /* = 67108864 */, - IgnoreErrors /* = 70221824 */, - InObjectTypeLiteral /* = 4194304 */, - InTypeAlias /* = 8388608 */, - InInitialEntityName /* = 16777216 */ -} - -external enum class TypeFormatFlags { - None /* = 0 */, - NoTruncation /* = 1 */, - WriteArrayAsGenericType /* = 2 */, - UseStructuralFallback /* = 8 */, - WriteTypeArgumentsOfSignature /* = 32 */, - UseFullyQualifiedType /* = 64 */, - SuppressAnyReturnType /* = 256 */, - MultilineObjectLiterals /* = 1024 */, - WriteClassExpressionAsTypeLiteral /* = 2048 */, - UseTypeOfFunction /* = 4096 */, - OmitParameterModifiers /* = 8192 */, - UseAliasDefinedOutsideCurrentScope /* = 16384 */, - UseSingleQuotesForStringLiteralType /* = 268435456 */, - NoTypeReduction /* = 536870912 */, - AllowUniqueESSymbolType /* = 1048576 */, - AddUndefined /* = 131072 */, - WriteArrowStyleSignature /* = 262144 */, - InArrayType /* = 524288 */, - InElementType /* = 2097152 */, - InFirstTypeArgument /* = 4194304 */, - InTypeAlias /* = 8388608 */, - WriteOwnNameForAnyLike /* = 0 */, - NodeBuilderFlagsMask /* = 814775659 */ -} - -external enum class SymbolFormatFlags { - None /* = 0 */, - WriteTypeParametersOrArguments /* = 1 */, - UseOnlyExternalAliasing /* = 2 */, - AllowAnyNodeKind /* = 4 */, - UseAliasDefinedOutsideCurrentScope /* = 8 */ -} - -external enum class TypePredicateKind { - This /* = 0 */, - Identifier /* = 1 */, - AssertsThis /* = 2 */, - AssertsIdentifier /* = 3 */ -} - -external interface TypePredicateBase { - var kind: TypePredicateKind - var type: Type? -} - -external interface ThisTypePredicate : TypePredicateBase { - var parameterName: Any? - var parameterIndex: Any? -} - -external interface IdentifierTypePredicate : TypePredicateBase { - var parameterName: String - var parameterIndex: Number -} - -external interface AssertsThisTypePredicate : TypePredicateBase { - var parameterName: Any? - var parameterIndex: Any? - override var type: Type? -} - -external interface AssertsIdentifierTypePredicate : TypePredicateBase { - var parameterName: String - var parameterIndex: Number - override var type: Type? -} - -external enum class SymbolFlags { - None /* = 0 */, - FunctionScopedVariable /* = 1 */, - BlockScopedVariable /* = 2 */, - Property /* = 4 */, - EnumMember /* = 8 */, - Function /* = 16 */, - Class /* = 32 */, - Interface /* = 64 */, - ConstEnum /* = 128 */, - RegularEnum /* = 256 */, - ValueModule /* = 512 */, - NamespaceModule /* = 1024 */, - TypeLiteral /* = 2048 */, - ObjectLiteral /* = 4096 */, - Method /* = 8192 */, - Constructor /* = 16384 */, - GetAccessor /* = 32768 */, - SetAccessor /* = 65536 */, - Signature /* = 131072 */, - TypeParameter /* = 262144 */, - TypeAlias /* = 524288 */, - ExportValue /* = 1048576 */, - Alias /* = 2097152 */, - Prototype /* = 4194304 */, - ExportStar /* = 8388608 */, - Optional /* = 16777216 */, - Transient /* = 33554432 */, - Assignment /* = 67108864 */, - ModuleExports /* = 134217728 */, - Enum /* = 384 */, - Variable /* = 3 */, - Value /* = 111551 */, - Type /* = 788968 */, - Namespace /* = 1920 */, - Module /* = 1536 */, - Accessor /* = 98304 */, - FunctionScopedVariableExcludes /* = 111550 */, - BlockScopedVariableExcludes /* = 111551 */, - ParameterExcludes /* = 111551 */, - PropertyExcludes /* = 0 */, - EnumMemberExcludes /* = 900095 */, - FunctionExcludes /* = 110991 */, - ClassExcludes /* = 899503 */, - InterfaceExcludes /* = 788872 */, - RegularEnumExcludes /* = 899327 */, - ConstEnumExcludes /* = 899967 */, - ValueModuleExcludes /* = 110735 */, - NamespaceModuleExcludes /* = 0 */, - MethodExcludes /* = 103359 */, - GetAccessorExcludes /* = 46015 */, - SetAccessorExcludes /* = 78783 */, - TypeParameterExcludes /* = 526824 */, - TypeAliasExcludes /* = 788968 */, - AliasExcludes /* = 2097152 */, - ModuleMember /* = 2623475 */, - ExportHasLocal /* = 944 */, - BlockScoped /* = 418 */, - PropertyOrAccessor /* = 98308 */, - ClassMember /* = 106500 */ -} - -external interface Symbol { - val name: String - fun getFlags(): SymbolFlags - fun getEscapedName(): dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - fun getName(): String - fun getDeclarations(): Array? - fun getDocumentationComment(typeChecker: TypeChecker?): Array - fun getJsDocTags(checker: TypeChecker = definedExternally): Array - var flags: SymbolFlags - var escapedName: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - get() = definedExternally - set(value) = definedExternally - var declarations: Array? - get() = definedExternally - set(value) = definedExternally - var valueDeclaration: Declaration? - get() = definedExternally - set(value) = definedExternally - var members: SymbolTable? - get() = definedExternally - set(value) = definedExternally - var exports: SymbolTable? - get() = definedExternally - set(value) = definedExternally - var globalExports: SymbolTable? - get() = definedExternally - set(value) = definedExternally -} - -external enum class InternalSymbolName { - Call /* = "__call" */, - Constructor /* = "__constructor" */, - New /* = "__new" */, - Index /* = "__index" */, - ExportStar /* = "__export" */, - Global /* = "__global" */, - Missing /* = "__missing" */, - Type /* = "__type" */, - Object /* = "__object" */, - JSXAttributes /* = "__jsxAttributes" */, - Class /* = "__class" */, - Function /* = "__function" */, - Computed /* = "__computed" */, - Resolving /* = "__resolving__" */, - ExportEquals /* = "export=" */, - Default /* = "default" */, - This /* = "this" */ -} - -external interface ReadonlyUnderscoreEscapedMap : ReadonlyESMap - -external interface UnderscoreEscapedMap : ESMap, ReadonlyUnderscoreEscapedMap - -external enum class TypeFlags { - Any /* = 1 */, - Unknown /* = 2 */, - String /* = 4 */, - Number /* = 8 */, - Boolean /* = 16 */, - Enum /* = 32 */, - BigInt /* = 64 */, - StringLiteral /* = 128 */, - NumberLiteral /* = 256 */, - BooleanLiteral /* = 512 */, - EnumLiteral /* = 1024 */, - BigIntLiteral /* = 2048 */, - ESSymbol /* = 4096 */, - UniqueESSymbol /* = 8192 */, - Void /* = 16384 */, - Undefined /* = 32768 */, - Null /* = 65536 */, - Never /* = 131072 */, - TypeParameter /* = 262144 */, - Object /* = 524288 */, - Union /* = 1048576 */, - Intersection /* = 2097152 */, - Index /* = 4194304 */, - IndexedAccess /* = 8388608 */, - Conditional /* = 16777216 */, - Substitution /* = 33554432 */, - NonPrimitive /* = 67108864 */, - TemplateLiteral /* = 134217728 */, - StringMapping /* = 268435456 */, - Literal /* = 2944 */, - Unit /* = 109440 */, - StringOrNumberLiteral /* = 384 */, - PossiblyFalsy /* = 117724 */, - StringLike /* = 402653316 */, - NumberLike /* = 296 */, - BigIntLike /* = 2112 */, - BooleanLike /* = 528 */, - EnumLike /* = 1056 */, - ESSymbolLike /* = 12288 */, - VoidLike /* = 49152 */, - UnionOrIntersection /* = 3145728 */, - StructuredType /* = 3670016 */, - TypeVariable /* = 8650752 */, - InstantiableNonPrimitive /* = 58982400 */, - InstantiablePrimitive /* = 406847488 */, - Instantiable /* = 465829888 */, - StructuredOrInstantiable /* = 469499904 */, - Narrowable /* = 536624127 */ -} - -external interface Type { - fun getFlags(): TypeFlags - fun getSymbol(): Symbol? - fun getProperties(): Array - fun getProperty(propertyName: String): Symbol? - fun getApparentProperties(): Array - fun getCallSignatures(): Array - fun getConstructSignatures(): Array - fun getStringIndexType(): Type? - fun getNumberIndexType(): Type? - fun getBaseTypes(): Array? - fun getNonNullableType(): Type - fun getConstraint(): Type? - fun getDefault(): Type? - fun isUnion(): Boolean - fun isIntersection(): Boolean - fun isUnionOrIntersection(): Boolean - fun isLiteral(): Boolean - fun isStringLiteral(): Boolean - fun isNumberLiteral(): Boolean - fun isTypeParameter(): Boolean - fun isClassOrInterface(): Boolean - fun isClass(): Boolean - var flags: TypeFlags - var symbol: Symbol - var pattern: dynamic /* ObjectBindingPattern? | ArrayBindingPattern? | ObjectLiteralExpression? | ArrayLiteralExpression? */ - get() = definedExternally - set(value) = definedExternally - var aliasSymbol: Symbol? - get() = definedExternally - set(value) = definedExternally - var aliasTypeArguments: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface LiteralType : Type { - var value: dynamic /* String | Number | PseudoBigInt */ - get() = definedExternally - set(value) = definedExternally - var freshType: LiteralType - var regularType: LiteralType -} - -external interface UniqueESSymbolType : Type { - override var symbol: Symbol - var escapedName: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - get() = definedExternally - set(value) = definedExternally -} - -external interface StringLiteralType : LiteralType { - override var value: String -} - -external interface NumberLiteralType : LiteralType { - override var value: Number -} - -external interface BigIntLiteralType : LiteralType { - override var value: PseudoBigInt -} - -external interface EnumType : Type - -external enum class ObjectFlags { - Class /* = 1 */, - Interface /* = 2 */, - Reference /* = 4 */, - Tuple /* = 8 */, - Anonymous /* = 16 */, - Mapped /* = 32 */, - Instantiated /* = 64 */, - ObjectLiteral /* = 128 */, - EvolvingArray /* = 256 */, - ObjectLiteralPatternWithComputedProperties /* = 512 */, - ReverseMapped /* = 1024 */, - JsxAttributes /* = 2048 */, - MarkerType /* = 4096 */, - JSLiteral /* = 8192 */, - FreshLiteral /* = 16384 */, - ArrayLiteral /* = 32768 */, - ClassOrInterface /* = 3 */, - ContainsSpread /* = 4194304 */, - ObjectRestType /* = 8388608 */ -} - -external interface ObjectType : Type { - var objectFlags: ObjectFlags -} - -external interface InterfaceType : ObjectType { - var typeParameters: Array? - var outerTypeParameters: Array? - var localTypeParameters: Array? - var thisType: TypeParameter? -} - -external interface InterfaceTypeWithDeclaredMembers : InterfaceType { - var declaredProperties: Array - var declaredCallSignatures: Array - var declaredConstructSignatures: Array - var declaredIndexInfos: Array -} - -external interface TypeReference : ObjectType { - var typeArguments: Array? - get() = definedExternally - set(value) = definedExternally - var target: GenericType - var node: dynamic /* TypeReferenceNode? | ArrayTypeNode? | TupleTypeNode? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface DeferredTypeReference : TypeReference - -external interface GenericType : InterfaceType, TypeReference - -external enum class ElementFlags { - Required /* = 1 */, - Optional /* = 2 */, - Rest /* = 4 */, - Variadic /* = 8 */, - Fixed /* = 3 */, - Variable /* = 12 */, - NonRequired /* = 14 */, - NonRest /* = 11 */ -} - -external interface TupleType : GenericType { - var elementFlags: Array - var minLength: Number - var fixedLength: Number - var hasRestElement: Boolean? - var combinedFlags: ElementFlags - var readonly: Boolean? - var labeledElementDeclarations: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface TupleTypeReference : TypeReference { - override var target: GenericType -} - -external interface UnionOrIntersectionType : Type { - var types: Array -} - -external interface UnionType : UnionOrIntersectionType - -external interface IntersectionType : UnionOrIntersectionType - -external interface EvolvingArrayType : ObjectType { - var elementType: Type - var finalArrayType: Type? - get() = definedExternally - set(value) = definedExternally -} - -external interface InstantiableType : Type - -external interface TypeParameter : InstantiableType - -external interface IndexedAccessType : InstantiableType { - var objectType: Type - var indexType: Type - var constraint: Type? - get() = definedExternally - set(value) = definedExternally - var simplifiedForReading: Type? - get() = definedExternally - set(value) = definedExternally - var simplifiedForWriting: Type? - get() = definedExternally - set(value) = definedExternally -} - -external interface IndexType : InstantiableType { - var type: dynamic /* InstantiableType | UnionOrIntersectionType */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ConditionalRoot { - var node: ConditionalTypeNode - var checkType: Type - var extendsType: Type - var isDistributive: Boolean? - var inferTypeParameters: Array? - get() = definedExternally - set(value) = definedExternally - var outerTypeParameters: Array? - get() = definedExternally - set(value) = definedExternally - var instantiations: Map? - get() = definedExternally - set(value) = definedExternally - var aliasSymbol: Symbol? - get() = definedExternally - set(value) = definedExternally - var aliasTypeArguments: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface ConditionalType : InstantiableType { - var root: ConditionalRoot - var checkType: Type - var extendsType: Type - var resolvedTrueType: Type - var resolvedFalseType: Type -} - -external interface TemplateLiteralType : InstantiableType { - var texts: Array - var types: Array -} - -external interface StringMappingType : InstantiableType { - override var symbol: Symbol - var type: Type -} - -external interface SubstitutionType : InstantiableType { - var objectFlags: ObjectFlags - var baseType: Type - var substitute: Type -} - -external enum class SignatureKind { - Call /* = 0 */, - Construct /* = 1 */ -} - -external interface Signature { - fun getDeclaration(): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ - fun getTypeParameters(): Array? - fun getParameters(): Array - fun getReturnType(): Type - fun getDocumentationComment(typeChecker: TypeChecker?): Array - fun getJsDocTags(): Array - var declaration: dynamic /* CallSignatureDeclaration? | ConstructSignatureDeclaration? | MethodSignature? | IndexSignatureDeclaration? | FunctionTypeNode? | ConstructorTypeNode? | JSDocFunctionType? | FunctionDeclaration? | MethodDeclaration? | ConstructorDeclaration? | GetAccessorDeclaration? | SetAccessorDeclaration? | FunctionExpression? | ArrowFunction? | JSDocSignature? */ - get() = definedExternally - set(value) = definedExternally - var typeParameters: Array? - get() = definedExternally - set(value) = definedExternally - var parameters: Array -} - -external enum class IndexKind { - String /* = 0 */, - Number /* = 1 */ -} - -external interface IndexInfo { - var keyType: Type - var type: Type - var isReadonly: Boolean? - var declaration: IndexSignatureDeclaration? - get() = definedExternally - set(value) = definedExternally -} - -external enum class InferencePriority { - NakedTypeVariable /* = 1 */, - SpeculativeTuple /* = 2 */, - SubstituteSource /* = 4 */, - HomomorphicMappedType /* = 8 */, - PartialHomomorphicMappedType /* = 16 */, - MappedTypeConstraint /* = 32 */, - ContravariantConditional /* = 64 */, - ReturnType /* = 128 */, - LiteralKeyof /* = 256 */, - NoConstraints /* = 512 */, - AlwaysStrict /* = 1024 */, - MaxValue /* = 2048 */, - PriorityImpliesCombination /* = 416 */, - Circularity /* = -1 */ -} - -external interface FileExtensionInfo { - var extension: String - var isMixedContent: Boolean? - var scriptKind: ScriptKind? - get() = definedExternally - set(value) = definedExternally -} - -external interface DiagnosticMessage { - var key: String - var category: DiagnosticCategory - var code: Number - var message: String - var reportsUnnecessary: Any? - get() = definedExternally - set(value) = definedExternally - var reportsDeprecated: Any? - get() = definedExternally - set(value) = definedExternally -} - -external interface DiagnosticMessageChain { - var messageText: String - var category: DiagnosticCategory - var code: Number - var next: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface Diagnostic : DiagnosticRelatedInformation { - var reportsUnnecessary: Any? - get() = definedExternally - set(value) = definedExternally - var reportsDeprecated: Any? - get() = definedExternally - set(value) = definedExternally - var source: String? - get() = definedExternally - set(value) = definedExternally - var relatedInformation: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface DiagnosticRelatedInformation { - var category: DiagnosticCategory - var code: Number - var file: SourceFile? - var start: Number? - var length: Number? - var messageText: dynamic /* String | DiagnosticMessageChain */ - get() = definedExternally - set(value) = definedExternally -} - -external interface DiagnosticWithLocation : Diagnostic - -external enum class DiagnosticCategory { - Warning /* = 0 */, - Error /* = 1 */, - Suggestion /* = 2 */, - Message /* = 3 */ -} - -external enum class ModuleResolutionKind { - Classic /* = 1 */, - NodeJs /* = 2 */ -} - -external interface PluginImport { - var name: String -} - -external interface ProjectReference { - var path: String - var originalPath: String? - get() = definedExternally - set(value) = definedExternally - var prepend: Boolean? - get() = definedExternally - set(value) = definedExternally - var circular: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external enum class WatchFileKind { - FixedPollingInterval /* = 0 */, - PriorityPollingInterval /* = 1 */, - DynamicPriorityPolling /* = 2 */, - FixedChunkSizePolling /* = 3 */, - UseFsEvents /* = 4 */, - UseFsEventsOnParentDirectory /* = 5 */ -} - -external enum class WatchDirectoryKind { - UseFsEvents /* = 0 */, - FixedPollingInterval /* = 1 */, - DynamicPriorityPolling /* = 2 */, - FixedChunkSizePolling /* = 3 */ -} - -external enum class PollingWatchKind { - FixedInterval /* = 0 */, - PriorityInterval /* = 1 */, - DynamicPriority /* = 2 */, - FixedChunkSize /* = 3 */ -} - -external interface CompilerOptions { - var allowJs: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowSyntheticDefaultImports: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowUmdGlobalAccess: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowUnreachableCode: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowUnusedLabels: Boolean? - get() = definedExternally - set(value) = definedExternally - var alwaysStrict: Boolean? - get() = definedExternally - set(value) = definedExternally - var baseUrl: String? - get() = definedExternally - set(value) = definedExternally - var charset: String? - get() = definedExternally - set(value) = definedExternally - var checkJs: Boolean? - get() = definedExternally - set(value) = definedExternally - var declaration: Boolean? - get() = definedExternally - set(value) = definedExternally - var declarationMap: Boolean? - get() = definedExternally - set(value) = definedExternally - var emitDeclarationOnly: Boolean? - get() = definedExternally - set(value) = definedExternally - var declarationDir: String? - get() = definedExternally - set(value) = definedExternally - var disableSizeLimit: Boolean? - get() = definedExternally - set(value) = definedExternally - var disableSourceOfProjectReferenceRedirect: Boolean? - get() = definedExternally - set(value) = definedExternally - var disableSolutionSearching: Boolean? - get() = definedExternally - set(value) = definedExternally - var disableReferencedProjectLoad: Boolean? - get() = definedExternally - set(value) = definedExternally - var downlevelIteration: Boolean? - get() = definedExternally - set(value) = definedExternally - var emitBOM: Boolean? - get() = definedExternally - set(value) = definedExternally - var emitDecoratorMetadata: Boolean? - get() = definedExternally - set(value) = definedExternally - var exactOptionalPropertyTypes: Boolean? - get() = definedExternally - set(value) = definedExternally - var experimentalDecorators: Boolean? - get() = definedExternally - set(value) = definedExternally - var forceConsistentCasingInFileNames: Boolean? - get() = definedExternally - set(value) = definedExternally - var importHelpers: Boolean? - get() = definedExternally - set(value) = definedExternally - var importsNotUsedAsValues: ImportsNotUsedAsValues? - get() = definedExternally - set(value) = definedExternally - var inlineSourceMap: Boolean? - get() = definedExternally - set(value) = definedExternally - var inlineSources: Boolean? - get() = definedExternally - set(value) = definedExternally - var isolatedModules: Boolean? - get() = definedExternally - set(value) = definedExternally - var jsx: JsxEmit? - get() = definedExternally - set(value) = definedExternally - var keyofStringsOnly: Boolean? - get() = definedExternally - set(value) = definedExternally - var lib: Array? - get() = definedExternally - set(value) = definedExternally - var locale: String? - get() = definedExternally - set(value) = definedExternally - var mapRoot: String? - get() = definedExternally - set(value) = definedExternally - var maxNodeModuleJsDepth: Number? - get() = definedExternally - set(value) = definedExternally - var module: ModuleKind? - get() = definedExternally - set(value) = definedExternally - var moduleResolution: ModuleResolutionKind? - get() = definedExternally - set(value) = definedExternally - var newLine: NewLineKind? - get() = definedExternally - set(value) = definedExternally - var noEmit: Boolean? - get() = definedExternally - set(value) = definedExternally - var noEmitHelpers: Boolean? - get() = definedExternally - set(value) = definedExternally - var noEmitOnError: Boolean? - get() = definedExternally - set(value) = definedExternally - var noErrorTruncation: Boolean? - get() = definedExternally - set(value) = definedExternally - var noFallthroughCasesInSwitch: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitAny: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitReturns: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitThis: Boolean? - get() = definedExternally - set(value) = definedExternally - var noStrictGenericChecks: Boolean? - get() = definedExternally - set(value) = definedExternally - var noUnusedLocals: Boolean? - get() = definedExternally - set(value) = definedExternally - var noUnusedParameters: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitUseStrict: Boolean? - get() = definedExternally - set(value) = definedExternally - var noPropertyAccessFromIndexSignature: Boolean? - get() = definedExternally - set(value) = definedExternally - var assumeChangesOnlyAffectDirectDependencies: Boolean? - get() = definedExternally - set(value) = definedExternally - var noLib: Boolean? - get() = definedExternally - set(value) = definedExternally - var noResolve: Boolean? - get() = definedExternally - set(value) = definedExternally - var noUncheckedIndexedAccess: Boolean? - get() = definedExternally - set(value) = definedExternally - var out: String? - get() = definedExternally - set(value) = definedExternally - var outDir: String? - get() = definedExternally - set(value) = definedExternally - var outFile: String? - get() = definedExternally - set(value) = definedExternally - var paths: MapLike>? - get() = definedExternally - set(value) = definedExternally - var preserveConstEnums: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitOverride: Boolean? - get() = definedExternally - set(value) = definedExternally - var preserveSymlinks: Boolean? - get() = definedExternally - set(value) = definedExternally - var project: String? - get() = definedExternally - set(value) = definedExternally - var reactNamespace: String? - get() = definedExternally - set(value) = definedExternally - var jsxFactory: String? - get() = definedExternally - set(value) = definedExternally - var jsxFragmentFactory: String? - get() = definedExternally - set(value) = definedExternally - var jsxImportSource: String? - get() = definedExternally - set(value) = definedExternally - var composite: Boolean? - get() = definedExternally - set(value) = definedExternally - var incremental: Boolean? - get() = definedExternally - set(value) = definedExternally - var tsBuildInfoFile: String? - get() = definedExternally - set(value) = definedExternally - var removeComments: Boolean? - get() = definedExternally - set(value) = definedExternally - var rootDir: String? - get() = definedExternally - set(value) = definedExternally - var rootDirs: Array? - get() = definedExternally - set(value) = definedExternally - var skipLibCheck: Boolean? - get() = definedExternally - set(value) = definedExternally - var skipDefaultLibCheck: Boolean? - get() = definedExternally - set(value) = definedExternally - var sourceMap: Boolean? - get() = definedExternally - set(value) = definedExternally - var sourceRoot: String? - get() = definedExternally - set(value) = definedExternally - var strict: Boolean? - get() = definedExternally - set(value) = definedExternally - var strictFunctionTypes: Boolean? - get() = definedExternally - set(value) = definedExternally - var strictBindCallApply: Boolean? - get() = definedExternally - set(value) = definedExternally - var strictNullChecks: Boolean? - get() = definedExternally - set(value) = definedExternally - var strictPropertyInitialization: Boolean? - get() = definedExternally - set(value) = definedExternally - var stripInternal: Boolean? - get() = definedExternally - set(value) = definedExternally - var suppressExcessPropertyErrors: Boolean? - get() = definedExternally - set(value) = definedExternally - var suppressImplicitAnyIndexErrors: Boolean? - get() = definedExternally - set(value) = definedExternally - var target: ScriptTarget? - get() = definedExternally - set(value) = definedExternally - var traceResolution: Boolean? - get() = definedExternally - set(value) = definedExternally - var useUnknownInCatchVariables: Boolean? - get() = definedExternally - set(value) = definedExternally - var resolveJsonModule: Boolean? - get() = definedExternally - set(value) = definedExternally - var types: Array? - get() = definedExternally - set(value) = definedExternally - var typeRoots: Array? - get() = definedExternally - set(value) = definedExternally - var esModuleInterop: Boolean? - get() = definedExternally - set(value) = definedExternally - var useDefineForClassFields: Boolean? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? | TsConfigSourceFile? */ - @nativeSetter - operator fun set(option: String, value: String?) - @nativeSetter - operator fun set(option: String, value: Number?) - @nativeSetter - operator fun set(option: String, value: Boolean?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: MapLike>?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: TsConfigSourceFile?) -} - -external interface WatchOptions { - var watchFile: WatchFileKind? - get() = definedExternally - set(value) = definedExternally - var watchDirectory: WatchDirectoryKind? - get() = definedExternally - set(value) = definedExternally - var fallbackPolling: PollingWatchKind? - get() = definedExternally - set(value) = definedExternally - var synchronousWatchDirectory: Boolean? - get() = definedExternally - set(value) = definedExternally - var excludeDirectories: Array? - get() = definedExternally - set(value) = definedExternally - var excludeFiles: Array? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ - @nativeSetter - operator fun set(option: String, value: String?) - @nativeSetter - operator fun set(option: String, value: Number?) - @nativeSetter - operator fun set(option: String, value: Boolean?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: MapLike>?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) -} - -external interface TypeAcquisition { - var enableAutoDiscovery: Boolean? - get() = definedExternally - set(value) = definedExternally - var enable: Boolean? - get() = definedExternally - set(value) = definedExternally - var include: Array? - get() = definedExternally - set(value) = definedExternally - var exclude: Array? - get() = definedExternally - set(value) = definedExternally - var disableFilenameBasedTypeAcquisition: Boolean? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ - @nativeSetter - operator fun set(option: String, value: String?) - @nativeSetter - operator fun set(option: String, value: Number?) - @nativeSetter - operator fun set(option: String, value: Boolean?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: MapLike>?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) -} - -external enum class ModuleKind { - None /* = 0 */, - CommonJS /* = 1 */, - AMD /* = 2 */, - UMD /* = 3 */, - System /* = 4 */, - ES2015 /* = 5 */, - ES2020 /* = 6 */, - ESNext /* = 99 */ -} - -external enum class JsxEmit { - None /* = 0 */, - Preserve /* = 1 */, - React /* = 2 */, - ReactNative /* = 3 */, - ReactJSX /* = 4 */, - ReactJSXDev /* = 5 */ -} - -external enum class ImportsNotUsedAsValues { - Remove /* = 0 */, - Preserve /* = 1 */, - Error /* = 2 */ -} - -external enum class NewLineKind { - CarriageReturnLineFeed /* = 0 */, - LineFeed /* = 1 */ -} - -external interface LineAndCharacter { - var line: Number - var character: Number -} - -external enum class ScriptKind { - Unknown /* = 0 */, - JS /* = 1 */, - JSX /* = 2 */, - TS /* = 3 */, - TSX /* = 4 */, - External /* = 5 */, - JSON /* = 6 */, - Deferred /* = 7 */ -} - -external enum class ScriptTarget { - ES3 /* = 0 */, - ES5 /* = 1 */, - ES2015 /* = 2 */, - ES2016 /* = 3 */, - ES2017 /* = 4 */, - ES2018 /* = 5 */, - ES2019 /* = 6 */, - ES2020 /* = 7 */, - ES2021 /* = 8 */, - ESNext /* = 99 */, - JSON /* = 100 */, - Latest /* = 99 */ -} - -external enum class LanguageVariant { - Standard /* = 0 */, - JSX /* = 1 */ -} - -external interface ParsedCommandLine { - var options: CompilerOptions - var typeAcquisition: TypeAcquisition? - get() = definedExternally - set(value) = definedExternally - var fileNames: Array - var projectReferences: Array? - get() = definedExternally - set(value) = definedExternally - var watchOptions: WatchOptions? - get() = definedExternally - set(value) = definedExternally - var raw: Any? - get() = definedExternally - set(value) = definedExternally - var errors: Array - var wildcardDirectories: MapLike? - get() = definedExternally - set(value) = definedExternally - var compileOnSave: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external enum class WatchDirectoryFlags { - None /* = 0 */, - Recursive /* = 1 */ -} - -external interface CreateProgramOptions { - var rootNames: Array - var options: CompilerOptions - var projectReferences: Array? - get() = definedExternally - set(value) = definedExternally - var host: CompilerHost? - get() = definedExternally - set(value) = definedExternally - var oldProgram: Program? - get() = definedExternally - set(value) = definedExternally - var configFileParsingDiagnostics: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface ModuleResolutionHost { - fun fileExists(fileName: String): Boolean - fun readFile(fileName: String): String? - val trace: ((s: String) -> Unit)? - val directoryExists: ((directoryName: String) -> Boolean)? - val realpath: ((path: String) -> String)? - val getCurrentDirectory: (() -> String)? - val getDirectories: ((path: String) -> Array)? -} - -external interface ResolvedModule { - var resolvedFileName: String - var isExternalLibraryImport: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedModuleFull : ResolvedModule { - var extension: Extension - var packageId: PackageId? - get() = definedExternally - set(value) = definedExternally -} - -external interface PackageId { - var name: String - var subModuleName: String - var version: String -} - -external enum class Extension { - Ts /* = ".ts" */, - Tsx /* = ".tsx" */, - Dts /* = ".d.ts" */, - Js /* = ".js" */, - Jsx /* = ".jsx" */, - Json /* = ".json" */, - TsBuildInfo /* = ".tsbuildinfo" */ -} - -external interface ResolvedModuleWithFailedLookupLocations { - val resolvedModule: ResolvedModuleFull? -} - -external interface ResolvedTypeReferenceDirective { - var primary: Boolean? - var resolvedFileName: String? - var packageId: PackageId? - get() = definedExternally - set(value) = definedExternally - var isExternalLibraryImport: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations { - val resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective? - val failedLookupLocations: Array -} - -external interface CompilerHost : ModuleResolutionHost { - fun getSourceFile(fileName: String, languageVersion: ScriptTarget, onError: (message: String) -> Unit = definedExternally, shouldCreateNewSourceFile: Boolean = definedExternally): SourceFile? - val getSourceFileByPath: ((fileName: String, path: String /* String & `T$3` */, languageVersion: ScriptTarget, onError: (message: String) -> Unit, shouldCreateNewSourceFile: Boolean) -> SourceFile?)? - val getCancellationToken: (() -> CancellationToken)? - fun getDefaultLibFileName(options: CompilerOptions): String - val getDefaultLibLocation: (() -> String)? - var writeFile: WriteFileCallback - override var getCurrentDirectory: () -> String - fun getCanonicalFileName(fileName: String): String - fun useCaseSensitiveFileNames(): Boolean - fun getNewLine(): String - val readDirectory: ((rootDir: String, extensions: Array, excludes: Array?, includes: Array, depth: Number) -> Array)? - val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val getEnvironmentVariable: ((name: String) -> String?)? - val createHash: ((data: String) -> String)? - val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? -} - -external interface SourceMapRange : TextRange { - var source: SourceMapSource? - get() = definedExternally - set(value) = definedExternally -} - -external interface SourceMapSource { - fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter - var fileName: String - var text: String - var skipTrivia: ((pos: Number) -> Number)? - get() = definedExternally - set(value) = definedExternally -} - -external enum class EmitFlags { - None /* = 0 */, - SingleLine /* = 1 */, - AdviseOnEmitNode /* = 2 */, - NoSubstitution /* = 4 */, - CapturesThis /* = 8 */, - NoLeadingSourceMap /* = 16 */, - NoTrailingSourceMap /* = 32 */, - NoSourceMap /* = 48 */, - NoNestedSourceMaps /* = 64 */, - NoTokenLeadingSourceMaps /* = 128 */, - NoTokenTrailingSourceMaps /* = 256 */, - NoTokenSourceMaps /* = 384 */, - NoLeadingComments /* = 512 */, - NoTrailingComments /* = 1024 */, - NoComments /* = 1536 */, - NoNestedComments /* = 2048 */, - HelperName /* = 4096 */, - ExportName /* = 8192 */, - LocalName /* = 16384 */, - InternalName /* = 32768 */, - Indented /* = 65536 */, - NoIndentation /* = 131072 */, - AsyncFunctionBody /* = 262144 */, - ReuseTempVariableScope /* = 524288 */, - CustomPrologue /* = 1048576 */, - NoHoisting /* = 2097152 */, - HasEndOfDeclarationMarker /* = 4194304 */, - Iterator /* = 8388608 */, - NoAsciiEscaping /* = 16777216 */ -} - -external interface EmitHelperBase { - val name: String - val scoped: Boolean? - val text: dynamic /* String | (node: EmitHelperUniqueNameCallback) -> String */ - get() = definedExternally - val priority: Number? - get() = definedExternally - val dependencies: Array? - get() = definedExternally -} - -external interface ScopedEmitHelper : EmitHelperBase { - override val scoped: Boolean? -} - -external interface UnscopedEmitHelper : EmitHelperBase { - override val scoped: Boolean? - override val text: String -} - -external enum class EmitHint { - SourceFile /* = 0 */, - Expression /* = 1 */, - IdentifierName /* = 2 */, - MappedTypeParameter /* = 3 */, - Unspecified /* = 4 */, - EmbeddedStatement /* = 5 */, - JsxAttributeValue /* = 6 */ -} - -external enum class OuterExpressionKinds { - Parentheses /* = 1 */, - TypeAssertions /* = 2 */, - NonNullAssertions /* = 4 */, - PartiallyEmittedExpressions /* = 8 */, - Assertions /* = 6 */, - All /* = 15 */ -} - -external interface NodeFactory { - fun createNodeArray(elements: Array = definedExternally, hasTrailingComma: Boolean = definedExternally): NodeArray - fun createNumericLiteral(value: String, numericLiteralFlags: TokenFlags = definedExternally): NumericLiteral - fun createNumericLiteral(value: String): NumericLiteral - fun createNumericLiteral(value: Number, numericLiteralFlags: TokenFlags = definedExternally): NumericLiteral - fun createNumericLiteral(value: Number): NumericLiteral - fun createBigIntLiteral(value: String): BigIntLiteral - fun createBigIntLiteral(value: PseudoBigInt): BigIntLiteral - fun createStringLiteral(text: String, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: Identifier, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: Identifier): StringLiteral - fun createStringLiteralFromNode(sourceNode: StringLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: StringLiteral): StringLiteral - fun createStringLiteralFromNode(sourceNode: NoSubstitutionTemplateLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: NoSubstitutionTemplateLiteral): StringLiteral - fun createStringLiteralFromNode(sourceNode: NumericLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: NumericLiteral): StringLiteral - fun createRegularExpressionLiteral(text: String): RegularExpressionLiteral - fun createIdentifier(text: String): Identifier - fun createTempVariable(recordTempVariable: ((node: Identifier) -> Unit)?, reservedInNestedScopes: Boolean = definedExternally): Identifier - fun createLoopVariable(reservedInNestedScopes: Boolean = definedExternally): Identifier - fun createUniqueName(text: String, flags: GeneratedIdentifierFlags = definedExternally): Identifier - fun getGeneratedNameForNode(node: Node?, flags: GeneratedIdentifierFlags = definedExternally): Identifier - fun createPrivateIdentifier(text: String): PrivateIdentifier - fun createToken(token: SyntaxKind): dynamic -// fun createToken(token: SyntaxKind.SuperKeyword): SuperExpression -// fun createToken(token: SyntaxKind.ThisKeyword): ThisExpression -// fun createToken(token: SyntaxKind.NullKeyword): NullLiteral -// fun createToken(token: SyntaxKind.TrueKeyword): TrueLiteral -// fun createToken(token: SyntaxKind.FalseKeyword): FalseLiteral - fun createToken(token: TKind): dynamic /* Token */ - fun createSuper(): SuperExpression - fun createThis(): ThisExpression - fun createNull(): NullLiteral - fun createTrue(): TrueLiteral - fun createFalse(): FalseLiteral - fun createModifier(kind: T): ModifierToken - fun createModifiersFromModifierFlags(flags: ModifierFlags): Array - fun createQualifiedName(left: Identifier, right: String): QualifiedName - fun createQualifiedName(left: Identifier, right: Identifier): QualifiedName - fun createQualifiedName(left: QualifiedName, right: String): QualifiedName - fun createQualifiedName(left: QualifiedName, right: Identifier): QualifiedName - fun updateQualifiedName(node: QualifiedName, left: Identifier, right: Identifier): QualifiedName - fun updateQualifiedName(node: QualifiedName, left: QualifiedName, right: Identifier): QualifiedName - fun createComputedPropertyName(expression: Expression): ComputedPropertyName - fun updateComputedPropertyName(node: ComputedPropertyName, expression: Expression): ComputedPropertyName - fun createTypeParameterDeclaration(name: String, constraint: TypeNode = definedExternally, defaultType: TypeNode = definedExternally): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: String): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: String, constraint: TypeNode = definedExternally): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: Identifier, constraint: TypeNode = definedExternally, defaultType: TypeNode = definedExternally): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: Identifier): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: Identifier, constraint: TypeNode = definedExternally): TypeParameterDeclaration - fun updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode?, defaultType: TypeNode?): TypeParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration - fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration - fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration - fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration - fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration - fun createDecorator(expression: Expression): Decorator - fun updateDecorator(node: Decorator, expression: Expression): Decorator - fun createPropertySignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: String, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: dynamic, questionOrExclamationToken: dynamic, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: dynamic, questionOrExclamationToken: dynamic, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration -// fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createMethodSignature(modifiers: Array?, name: dynamic, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature -// fun createMethodSignature(modifiers: Array?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature -// fun createMethodSignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature -// fun createMethodSignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature -// fun createMethodSignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature -// fun createMethodSignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature -// fun createMethodSignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: dynamic, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature -// fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature -// fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature -// fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature -// fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature -// fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration -// fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration -// fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration -// fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration -// fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration -// fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration -// fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration -// fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration -// fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration -// fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration -// fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration -// fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createConstructorDeclaration(decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration - fun updateConstructorDeclaration(node: ConstructorDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun createCallSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): CallSignatureDeclaration - fun updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): CallSignatureDeclaration - fun createConstructSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): ConstructSignatureDeclaration - fun updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): ConstructSignatureDeclaration - fun createIndexSignature(decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration - fun updateIndexSignature(node: IndexSignatureDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration - fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan - fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan - fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan - fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan - fun createClassStaticBlockDeclaration(decorators: Array?, modifiers: Array?, body: Block): ClassStaticBlockDeclaration - fun updateClassStaticBlockDeclaration(node: ClassStaticBlockDeclaration, decorators: Array?, modifiers: Array?, body: Block): ClassStaticBlockDeclaration - fun createKeywordTypeNode(kind: TKind): KeywordTypeNode - fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode - fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode - fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: String, type: TypeNode?): TypePredicateNode - fun updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode - fun updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode - fun createTypeReferenceNode(typeName: String, typeArguments: Array = definedExternally): TypeReferenceNode - fun createTypeReferenceNode(typeName: String): TypeReferenceNode - fun createTypeReferenceNode(typeName: Identifier, typeArguments: Array = definedExternally): TypeReferenceNode - fun createTypeReferenceNode(typeName: Identifier): TypeReferenceNode - fun createTypeReferenceNode(typeName: QualifiedName, typeArguments: Array = definedExternally): TypeReferenceNode - fun createTypeReferenceNode(typeName: QualifiedName): TypeReferenceNode - fun updateTypeReferenceNode(node: TypeReferenceNode, typeName: Identifier, typeArguments: NodeArray?): TypeReferenceNode - fun updateTypeReferenceNode(node: TypeReferenceNode, typeName: QualifiedName, typeArguments: NodeArray?): TypeReferenceNode - fun createFunctionTypeNode(typeParameters: Array?, parameters: Array, type: TypeNode): FunctionTypeNode - fun updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): FunctionTypeNode - fun createConstructorTypeNode(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode): ConstructorTypeNode - fun createConstructorTypeNode(typeParameters: Array?, parameters: Array, type: TypeNode): ConstructorTypeNode - fun updateConstructorTypeNode(node: ConstructorTypeNode, modifiers: Array?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): ConstructorTypeNode - fun updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): ConstructorTypeNode - fun createTypeQueryNode(exprName: Identifier): TypeQueryNode - fun createTypeQueryNode(exprName: QualifiedName): TypeQueryNode - fun updateTypeQueryNode(node: TypeQueryNode, exprName: Identifier): TypeQueryNode - fun updateTypeQueryNode(node: TypeQueryNode, exprName: QualifiedName): TypeQueryNode - fun createTypeLiteralNode(members: Array?): TypeLiteralNode - fun updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray): TypeLiteralNode - fun createArrayTypeNode(elementType: TypeNode): ArrayTypeNode - fun updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode - fun createTupleTypeNode(elements: Array): TupleTypeNode - fun updateTupleTypeNode(node: TupleTypeNode, elements: Array): TupleTypeNode - fun createNamedTupleMember(dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode): NamedTupleMember - fun updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode): NamedTupleMember - fun createOptionalTypeNode(type: TypeNode): OptionalTypeNode - fun updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode - fun createRestTypeNode(type: TypeNode): RestTypeNode - fun updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode - fun createUnionTypeNode(types: Array): UnionTypeNode - fun updateUnionTypeNode(node: UnionTypeNode, types: NodeArray): UnionTypeNode - fun createIntersectionTypeNode(types: Array): IntersectionTypeNode - fun updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray): IntersectionTypeNode - fun createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode - fun updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode - fun createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode - fun updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally, typeArguments: Array = definedExternally, isTypeOf: Boolean = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally, typeArguments: Array = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally, typeArguments: Array = definedExternally, isTypeOf: Boolean = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally, typeArguments: Array = definedExternally): ImportTypeNode - fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: Identifier?, typeArguments: Array?, isTypeOf: Boolean = definedExternally): ImportTypeNode - fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: Identifier?, typeArguments: Array?): ImportTypeNode - fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: QualifiedName?, typeArguments: Array?, isTypeOf: Boolean = definedExternally): ImportTypeNode - fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: QualifiedName?, typeArguments: Array?): ImportTypeNode - fun createParenthesizedType(type: TypeNode): ParenthesizedTypeNode - fun updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode - fun createThisTypeNode(): ThisTypeNode - fun createTypeOperatorNode(operator: SyntaxKind, type: TypeNode): dynamic -// fun createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword, type: TypeNode): TypeOperatorNode -// fun createTypeOperatorNode(operator: SyntaxKind.UniqueKeyword, type: TypeNode): TypeOperatorNode -// fun createTypeOperatorNode(operator: SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode - fun updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode - fun createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode - fun updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode - fun createMappedTypeNode(readonlyToken: dynamic, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic, type: TypeNode?): MappedTypeNode -// fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode -// fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode -// fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode -// fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode -// fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode -// fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode -// fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode -// fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode -// fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: dynamic, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic, type: TypeNode?): MappedTypeNode -// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode -// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode -// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode -// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode -// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode -// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode -// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode -// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode -// fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun createLiteralTypeNode(literal: NullLiteral): LiteralTypeNode - fun createLiteralTypeNode(literal: TrueLiteral): LiteralTypeNode - fun createLiteralTypeNode(literal: FalseLiteral): LiteralTypeNode - fun createLiteralTypeNode(literal: LiteralExpression): LiteralTypeNode - fun createLiteralTypeNode(literal: PrefixUnaryExpression): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: NullLiteral): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: TrueLiteral): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: FalseLiteral): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralExpression): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: PrefixUnaryExpression): LiteralTypeNode - fun createTemplateLiteralType(head: TemplateHead, templateSpans: Array): TemplateLiteralTypeNode - fun updateTemplateLiteralType(node: TemplateLiteralTypeNode, head: TemplateHead, templateSpans: Array): TemplateLiteralTypeNode - fun createObjectBindingPattern(elements: Array): ObjectBindingPattern - fun updateObjectBindingPattern(node: ObjectBindingPattern, elements: Array): ObjectBindingPattern - fun createArrayBindingPattern(elements: Array): ArrayBindingPattern - fun updateArrayBindingPattern(node: ArrayBindingPattern, elements: Array): ArrayBindingPattern - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: String?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: String?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun createArrayLiteralExpression(elements: Array = definedExternally, multiLine: Boolean = definedExternally): ArrayLiteralExpression - fun updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: Array): ArrayLiteralExpression - fun createObjectLiteralExpression(properties: Array = definedExternally, multiLine: Boolean = definedExternally): ObjectLiteralExpression - fun updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: Array): ObjectLiteralExpression - fun createPropertyAccessExpression(expression: Expression, name: String): PropertyAccessExpression - fun createPropertyAccessExpression(expression: Expression, name: Identifier): PropertyAccessExpression - fun createPropertyAccessExpression(expression: Expression, name: PrivateIdentifier): PropertyAccessExpression - fun updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier): PropertyAccessExpression - fun updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: PrivateIdentifier): PropertyAccessExpression - fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: String): PropertyAccessChain - fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: Identifier): PropertyAccessChain - fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: PrivateIdentifier): PropertyAccessChain - fun updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: Identifier): PropertyAccessChain - fun updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: PrivateIdentifier): PropertyAccessChain - fun createElementAccessExpression(expression: Expression, index: Number): ElementAccessExpression - fun createElementAccessExpression(expression: Expression, index: Expression): ElementAccessExpression - fun updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression - fun createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, index: Number): ElementAccessChain - fun createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, index: Expression): ElementAccessChain - fun updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, argumentExpression: Expression): ElementAccessChain - fun createCallExpression(expression: Expression, typeArguments: Array?, argumentsArray: Array?): CallExpression - fun updateCallExpression(node: CallExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array): CallExpression - fun createCallChain(expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array?): CallChain - fun updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array): CallChain - fun createNewExpression(expression: Expression, typeArguments: Array?, argumentsArray: Array?): NewExpression - fun updateNewExpression(node: NewExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array?): NewExpression - fun createTaggedTemplateExpression(tag: Expression, typeArguments: Array?, template: TemplateExpression): TaggedTemplateExpression - fun createTaggedTemplateExpression(tag: Expression, typeArguments: Array?, template: NoSubstitutionTemplateLiteral): TaggedTemplateExpression - fun updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: TemplateExpression): TaggedTemplateExpression - fun updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: NoSubstitutionTemplateLiteral): TaggedTemplateExpression - fun createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion - fun updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion - fun createParenthesizedExpression(expression: Expression): ParenthesizedExpression - fun updateParenthesizedExpression(node: ParenthesizedExpression, expression: Expression): ParenthesizedExpression - fun createFunctionExpression(modifiers: Array?, asteriskToken: AsteriskToken?, name: String?, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block): FunctionExpression - fun createFunctionExpression(modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block): FunctionExpression - fun updateFunctionExpression(node: FunctionExpression, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block): FunctionExpression - fun createArrowFunction(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: FunctionBody): ArrowFunction - fun createArrowFunction(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: Expression): ArrowFunction - fun updateArrowFunction(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: FunctionBody): ArrowFunction - fun updateArrowFunction(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: Expression): ArrowFunction - fun createDeleteExpression(expression: Expression): DeleteExpression - fun updateDeleteExpression(node: DeleteExpression, expression: Expression): DeleteExpression - fun createTypeOfExpression(expression: Expression): TypeOfExpression - fun updateTypeOfExpression(node: TypeOfExpression, expression: Expression): TypeOfExpression - fun createVoidExpression(expression: Expression): VoidExpression - fun updateVoidExpression(node: VoidExpression, expression: Expression): VoidExpression - fun createAwaitExpression(expression: Expression): AwaitExpression - fun updateAwaitExpression(node: AwaitExpression, expression: Expression): AwaitExpression - fun createPrefixUnaryExpression(operator: SyntaxKind, operand: Expression): PrefixUnaryExpression -// fun createPrefixUnaryExpression(operator: SyntaxKind.PlusPlusToken, operand: Expression): PrefixUnaryExpression -// fun createPrefixUnaryExpression(operator: SyntaxKind.MinusMinusToken, operand: Expression): PrefixUnaryExpression -// fun createPrefixUnaryExpression(operator: SyntaxKind.PlusToken, operand: Expression): PrefixUnaryExpression -// fun createPrefixUnaryExpression(operator: SyntaxKind.MinusToken, operand: Expression): PrefixUnaryExpression -// fun createPrefixUnaryExpression(operator: SyntaxKind.TildeToken, operand: Expression): PrefixUnaryExpression -// fun createPrefixUnaryExpression(operator: SyntaxKind.ExclamationToken, operand: Expression): PrefixUnaryExpression - fun updatePrefixUnaryExpression(node: PrefixUnaryExpression, operand: Expression): PrefixUnaryExpression - fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind): PostfixUnaryExpression -// fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind.PlusPlusToken): PostfixUnaryExpression -// fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind.MinusMinusToken): PostfixUnaryExpression - fun updatePostfixUnaryExpression(node: PostfixUnaryExpression, operand: Expression): PostfixUnaryExpression - fun createBinaryExpression(left: Expression, operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression): BinaryExpression - fun updateBinaryExpression(node: BinaryExpression, left: Expression, operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression): BinaryExpression - fun createConditionalExpression(condition: Expression, questionToken: QuestionToken?, whenTrue: Expression, colonToken: ColonToken?, whenFalse: Expression): ConditionalExpression - fun updateConditionalExpression(node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression - fun createTemplateExpression(head: TemplateHead, templateSpans: Array): TemplateExpression - fun updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: Array): TemplateExpression - fun createTemplateHead(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateHead - fun createTemplateHead(text: String): TemplateHead - fun createTemplateHead(text: String, rawText: String = definedExternally): TemplateHead - fun createTemplateHead(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateHead - fun createTemplateHead(text: String?, rawText: String): TemplateHead - fun createTemplateMiddle(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateMiddle - fun createTemplateMiddle(text: String): TemplateMiddle - fun createTemplateMiddle(text: String, rawText: String = definedExternally): TemplateMiddle - fun createTemplateMiddle(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateMiddle - fun createTemplateMiddle(text: String?, rawText: String): TemplateMiddle - fun createTemplateTail(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateTail - fun createTemplateTail(text: String): TemplateTail - fun createTemplateTail(text: String, rawText: String = definedExternally): TemplateTail - fun createTemplateTail(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateTail - fun createTemplateTail(text: String?, rawText: String): TemplateTail - fun createNoSubstitutionTemplateLiteral(text: String, rawText: String = definedExternally): NoSubstitutionTemplateLiteral - fun createNoSubstitutionTemplateLiteral(text: String): NoSubstitutionTemplateLiteral - fun createNoSubstitutionTemplateLiteral(text: String?, rawText: String): NoSubstitutionTemplateLiteral - fun createYieldExpression(asteriskToken: AsteriskToken, expression: Expression): YieldExpression - fun createYieldExpression(asteriskToken: Nothing?, expression: Expression?): YieldExpression - fun updateYieldExpression(node: YieldExpression, asteriskToken: AsteriskToken?, expression: Expression?): YieldExpression - fun createSpreadElement(expression: Expression): SpreadElement - fun updateSpreadElement(node: SpreadElement, expression: Expression): SpreadElement - fun createClassExpression(decorators: Array?, modifiers: Array?, name: String?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression - fun createClassExpression(decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression - fun updateClassExpression(node: ClassExpression, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression - fun createOmittedExpression(): OmittedExpression - fun createExpressionWithTypeArguments(expression: Expression, typeArguments: Array?): ExpressionWithTypeArguments - fun updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, expression: Expression, typeArguments: Array?): ExpressionWithTypeArguments - fun createAsExpression(expression: Expression, type: TypeNode): AsExpression - fun updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode): AsExpression - fun createNonNullExpression(expression: Expression): NonNullExpression - fun updateNonNullExpression(node: NonNullExpression, expression: Expression): NonNullExpression - fun createNonNullChain(expression: Expression): NonNullChain - fun updateNonNullChain(node: NonNullChain, expression: Expression): NonNullChain - fun createMetaProperty(keywordToken: SyntaxKind, name: Identifier): MetaProperty -// fun createMetaProperty(keywordToken: SyntaxKind.NewKeyword, name: Identifier): MetaProperty -// fun createMetaProperty(keywordToken: SyntaxKind.ImportKeyword, name: Identifier): MetaProperty - fun updateMetaProperty(node: MetaProperty, name: Identifier): MetaProperty - fun createTemplateSpan(expression: Expression, literal: TemplateMiddle): TemplateSpan - fun createTemplateSpan(expression: Expression, literal: TemplateTail): TemplateSpan - fun updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle): TemplateSpan - fun updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateTail): TemplateSpan - fun createSemicolonClassElement(): SemicolonClassElement - fun createBlock(statements: Array, multiLine: Boolean = definedExternally): Block - fun updateBlock(node: Block, statements: Array): Block - fun createVariableStatement(modifiers: Array?, declarationList: VariableDeclarationList): VariableStatement - fun createVariableStatement(modifiers: Array?, declarationList: Array): VariableStatement - fun updateVariableStatement(node: VariableStatement, modifiers: Array?, declarationList: VariableDeclarationList): VariableStatement - fun createEmptyStatement(): EmptyStatement - fun createExpressionStatement(expression: Expression): ExpressionStatement - fun updateExpressionStatement(node: ExpressionStatement, expression: Expression): ExpressionStatement - fun createIfStatement(expression: Expression, thenStatement: Statement, elseStatement: Statement = definedExternally): IfStatement - fun updateIfStatement(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement?): IfStatement - fun createDoStatement(statement: Statement, expression: Expression): DoStatement - fun updateDoStatement(node: DoStatement, statement: Statement, expression: Expression): DoStatement - fun createWhileStatement(expression: Expression, statement: Statement): WhileStatement - fun updateWhileStatement(node: WhileStatement, expression: Expression, statement: Statement): WhileStatement - fun createForStatement(initializer: VariableDeclarationList?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement - fun createForStatement(initializer: Expression?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement - fun updateForStatement(node: ForStatement, initializer: VariableDeclarationList?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement - fun updateForStatement(node: ForStatement, initializer: Expression?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement - fun createForInStatement(initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForInStatement - fun createForInStatement(initializer: Expression, expression: Expression, statement: Statement): ForInStatement - fun updateForInStatement(node: ForInStatement, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForInStatement - fun updateForInStatement(node: ForInStatement, initializer: Expression, expression: Expression, statement: Statement): ForInStatement - fun createForOfStatement(awaitModifier: AwaitKeyword?, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForOfStatement - fun createForOfStatement(awaitModifier: AwaitKeyword?, initializer: Expression, expression: Expression, statement: Statement): ForOfStatement - fun updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForOfStatement - fun updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: Expression, expression: Expression, statement: Statement): ForOfStatement - fun createContinueStatement(label: String = definedExternally): ContinueStatement - fun createContinueStatement(): ContinueStatement - fun createContinueStatement(label: Identifier = definedExternally): ContinueStatement - fun updateContinueStatement(node: ContinueStatement, label: Identifier?): ContinueStatement - fun createBreakStatement(label: String = definedExternally): BreakStatement - fun createBreakStatement(): BreakStatement - fun createBreakStatement(label: Identifier = definedExternally): BreakStatement - fun updateBreakStatement(node: BreakStatement, label: Identifier?): BreakStatement - fun createReturnStatement(expression: Expression = definedExternally): ReturnStatement - fun updateReturnStatement(node: ReturnStatement, expression: Expression?): ReturnStatement - fun createWithStatement(expression: Expression, statement: Statement): WithStatement - fun updateWithStatement(node: WithStatement, expression: Expression, statement: Statement): WithStatement - fun createSwitchStatement(expression: Expression, caseBlock: CaseBlock): SwitchStatement - fun updateSwitchStatement(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock): SwitchStatement - fun createLabeledStatement(label: String, statement: Statement): LabeledStatement - fun createLabeledStatement(label: Identifier, statement: Statement): LabeledStatement - fun updateLabeledStatement(node: LabeledStatement, label: Identifier, statement: Statement): LabeledStatement - fun createThrowStatement(expression: Expression): ThrowStatement - fun updateThrowStatement(node: ThrowStatement, expression: Expression): ThrowStatement - fun createTryStatement(tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?): TryStatement - fun updateTryStatement(node: TryStatement, tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?): TryStatement - fun createDebuggerStatement(): DebuggerStatement - fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: String): VariableDeclaration - fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: Identifier): VariableDeclaration - fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ObjectBindingPattern): VariableDeclaration - fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ArrayBindingPattern): VariableDeclaration - fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration - fun updateVariableDeclaration(node: VariableDeclaration, name: Identifier, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration - fun updateVariableDeclaration(node: VariableDeclaration, name: ObjectBindingPattern, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration - fun updateVariableDeclaration(node: VariableDeclaration, name: ArrayBindingPattern, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration - fun createVariableDeclarationList(declarations: Array, flags: NodeFlags = definedExternally): VariableDeclarationList - fun updateVariableDeclarationList(node: VariableDeclarationList, declarations: Array): VariableDeclarationList - fun createFunctionDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration - fun createFunctionDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration - fun updateFunctionDeclaration(node: FunctionDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration - fun createClassDeclaration(decorators: Array?, modifiers: Array?, name: String?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration - fun createClassDeclaration(decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration - fun updateClassDeclaration(node: ClassDeclaration, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration - fun createInterfaceDeclaration(decorators: Array?, modifiers: Array?, name: String, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration - fun createInterfaceDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration - fun updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration - fun createTypeAliasDeclaration(decorators: Array?, modifiers: Array?, name: String, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration - fun createTypeAliasDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration - fun updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration - fun createEnumDeclaration(decorators: Array?, modifiers: Array?, name: String, members: Array): EnumDeclaration - fun createEnumDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, members: Array): EnumDeclaration - fun updateEnumDeclaration(node: EnumDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, members: Array): EnumDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?): ModuleDeclaration - fun createModuleBlock(statements: Array): ModuleBlock - fun updateModuleBlock(node: ModuleBlock, statements: Array): ModuleBlock - fun createCaseBlock(clauses: Array): CaseBlock - fun updateCaseBlock(node: CaseBlock, clauses: Array): CaseBlock - fun createNamespaceExportDeclaration(name: String): NamespaceExportDeclaration - fun createNamespaceExportDeclaration(name: Identifier): NamespaceExportDeclaration - fun updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier): NamespaceExportDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: Identifier): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: QualifiedName): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: ExternalModuleReference): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: Identifier): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: QualifiedName): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: ExternalModuleReference): ImportEqualsDeclaration - fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: Identifier): ImportEqualsDeclaration - fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: QualifiedName): ImportEqualsDeclaration - fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: ExternalModuleReference): ImportEqualsDeclaration - fun createImportDeclaration(decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression): ImportDeclaration - fun updateImportDeclaration(node: ImportDeclaration, decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression): ImportDeclaration - fun createImportClause(isTypeOnly: Boolean, name: Identifier?, namedBindings: NamespaceImport?): ImportClause - fun createImportClause(isTypeOnly: Boolean, name: Identifier?, namedBindings: NamedImports?): ImportClause - fun updateImportClause(node: ImportClause, isTypeOnly: Boolean, name: Identifier?, namedBindings: NamespaceImport?): ImportClause - fun updateImportClause(node: ImportClause, isTypeOnly: Boolean, name: Identifier?, namedBindings: NamedImports?): ImportClause - fun createNamespaceImport(name: Identifier): NamespaceImport - fun updateNamespaceImport(node: NamespaceImport, name: Identifier): NamespaceImport - fun createNamespaceExport(name: Identifier): NamespaceExport - fun updateNamespaceExport(node: NamespaceExport, name: Identifier): NamespaceExport - fun createNamedImports(elements: Array): NamedImports - fun updateNamedImports(node: NamedImports, elements: Array): NamedImports - fun createImportSpecifier(propertyName: Identifier?, name: Identifier): ImportSpecifier - fun updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier?, name: Identifier): ImportSpecifier - fun createExportAssignment(decorators: Array?, modifiers: Array?, isExportEquals: Boolean?, expression: Expression): ExportAssignment - fun updateExportAssignment(node: ExportAssignment, decorators: Array?, modifiers: Array?, expression: Expression): ExportAssignment - fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?, moduleSpecifier: Expression = definedExternally): ExportDeclaration - fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?): ExportDeclaration - fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?, moduleSpecifier: Expression = definedExternally): ExportDeclaration - fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?): ExportDeclaration - fun updateExportDeclaration(node: ExportDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?, moduleSpecifier: Expression?): ExportDeclaration - fun updateExportDeclaration(node: ExportDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?, moduleSpecifier: Expression?): ExportDeclaration - fun createNamedExports(elements: Array): NamedExports - fun updateNamedExports(node: NamedExports, elements: Array): NamedExports - fun createExportSpecifier(propertyName: String?, name: String): ExportSpecifier - fun createExportSpecifier(propertyName: String?, name: Identifier): ExportSpecifier - fun createExportSpecifier(propertyName: Identifier?, name: String): ExportSpecifier - fun createExportSpecifier(propertyName: Identifier?, name: Identifier): ExportSpecifier - fun updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier?, name: Identifier): ExportSpecifier - fun createExternalModuleReference(expression: Expression): ExternalModuleReference - fun updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference - fun createJSDocAllType(): JSDocAllType - fun createJSDocUnknownType(): JSDocUnknownType - fun createJSDocNonNullableType(type: TypeNode): JSDocNonNullableType - fun updateJSDocNonNullableType(node: JSDocNonNullableType, type: TypeNode): JSDocNonNullableType - fun createJSDocNullableType(type: TypeNode): JSDocNullableType - fun updateJSDocNullableType(node: JSDocNullableType, type: TypeNode): JSDocNullableType - fun createJSDocOptionalType(type: TypeNode): JSDocOptionalType - fun updateJSDocOptionalType(node: JSDocOptionalType, type: TypeNode): JSDocOptionalType - fun createJSDocFunctionType(parameters: Array, type: TypeNode?): JSDocFunctionType - fun updateJSDocFunctionType(node: JSDocFunctionType, parameters: Array, type: TypeNode?): JSDocFunctionType - fun createJSDocVariadicType(type: TypeNode): JSDocVariadicType - fun updateJSDocVariadicType(node: JSDocVariadicType, type: TypeNode): JSDocVariadicType - fun createJSDocNamepathType(type: TypeNode): JSDocNamepathType - fun updateJSDocNamepathType(node: JSDocNamepathType, type: TypeNode): JSDocNamepathType - fun createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression - fun updateJSDocTypeExpression(node: JSDocTypeExpression, type: TypeNode): JSDocTypeExpression - fun createJSDocNameReference(name: Identifier): JSDocNameReference - fun createJSDocNameReference(name: QualifiedName): JSDocNameReference - fun createJSDocNameReference(name: JSDocMemberName): JSDocNameReference - fun updateJSDocNameReference(node: JSDocNameReference, name: Identifier): JSDocNameReference - fun updateJSDocNameReference(node: JSDocNameReference, name: QualifiedName): JSDocNameReference - fun updateJSDocNameReference(node: JSDocNameReference, name: JSDocMemberName): JSDocNameReference - fun createJSDocMemberName(left: Identifier, right: Identifier): JSDocMemberName - fun createJSDocMemberName(left: QualifiedName, right: Identifier): JSDocMemberName - fun createJSDocMemberName(left: JSDocMemberName, right: Identifier): JSDocMemberName - fun updateJSDocMemberName(node: JSDocMemberName, left: Identifier, right: Identifier): JSDocMemberName - fun updateJSDocMemberName(node: JSDocMemberName, left: QualifiedName, right: Identifier): JSDocMemberName - fun updateJSDocMemberName(node: JSDocMemberName, left: JSDocMemberName, right: Identifier): JSDocMemberName - fun createJSDocLink(name: Identifier?, text: String): JSDocLink - fun createJSDocLink(name: QualifiedName?, text: String): JSDocLink - fun createJSDocLink(name: JSDocMemberName?, text: String): JSDocLink - fun updateJSDocLink(node: JSDocLink, name: Identifier?, text: String): JSDocLink - fun updateJSDocLink(node: JSDocLink, name: QualifiedName?, text: String): JSDocLink - fun updateJSDocLink(node: JSDocLink, name: JSDocMemberName?, text: String): JSDocLink - fun createJSDocLinkCode(name: Identifier?, text: String): JSDocLinkCode - fun createJSDocLinkCode(name: QualifiedName?, text: String): JSDocLinkCode - fun createJSDocLinkCode(name: JSDocMemberName?, text: String): JSDocLinkCode - fun updateJSDocLinkCode(node: JSDocLinkCode, name: Identifier?, text: String): JSDocLinkCode - fun updateJSDocLinkCode(node: JSDocLinkCode, name: QualifiedName?, text: String): JSDocLinkCode - fun updateJSDocLinkCode(node: JSDocLinkCode, name: JSDocMemberName?, text: String): JSDocLinkCode - fun createJSDocLinkPlain(name: Identifier?, text: String): JSDocLinkPlain - fun createJSDocLinkPlain(name: QualifiedName?, text: String): JSDocLinkPlain - fun createJSDocLinkPlain(name: JSDocMemberName?, text: String): JSDocLinkPlain - fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: Identifier?, text: String): JSDocLinkPlain - fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: QualifiedName?, text: String): JSDocLinkPlain - fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: JSDocMemberName?, text: String): JSDocLinkPlain - fun createJSDocTypeLiteral(jsDocPropertyTags: Array = definedExternally, isArrayType: Boolean = definedExternally): JSDocTypeLiteral - fun updateJSDocTypeLiteral(node: JSDocTypeLiteral, jsDocPropertyTags: Array?, isArrayType: Boolean?): JSDocTypeLiteral - fun createJSDocSignature(typeParameters: Array?, parameters: Array, type: JSDocReturnTag = definedExternally): JSDocSignature - fun updateJSDocSignature(node: JSDocSignature, typeParameters: Array?, parameters: Array, type: JSDocReturnTag?): JSDocSignature - fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String = definedExternally): JSDocTemplateTag - fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array): JSDocTemplateTag - fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray = definedExternally): JSDocTemplateTag - fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String?): JSDocTemplateTag - fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray?): JSDocTemplateTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag - fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocTypeTag - fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocTypeTag - fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocTypeTag - fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocTypeTag - fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocTypeTag - fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag - fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag - fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag - fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag - fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag - fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag - fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: String = definedExternally): JSDocReturnTag - fun createJSDocReturnTag(tagName: Identifier?): JSDocReturnTag - fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocReturnTag - fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: NodeArray = definedExternally): JSDocReturnTag - fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocReturnTag - fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocReturnTag - fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocThisTag - fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocThisTag - fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocThisTag - fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocThisTag - fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocThisTag - fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocEnumTag - fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocEnumTag - fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocEnumTag - fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocEnumTag - fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocEnumTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: String?): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: NodeArray?): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocCallbackTag - fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String = definedExternally): JSDocAugmentsTag - fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */): JSDocAugmentsTag - fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray = definedExternally): JSDocAugmentsTag - fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String?): JSDocAugmentsTag - fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray?): JSDocAugmentsTag - fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String = definedExternally): JSDocImplementsTag - fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */): JSDocImplementsTag - fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray = definedExternally): JSDocImplementsTag - fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String?): JSDocImplementsTag - fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray?): JSDocImplementsTag - fun createJSDocAuthorTag(tagName: Identifier?, comment: String = definedExternally): JSDocAuthorTag - fun createJSDocAuthorTag(tagName: Identifier?): JSDocAuthorTag - fun createJSDocAuthorTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocAuthorTag - fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: String?): JSDocAuthorTag - fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: NodeArray?): JSDocAuthorTag - fun createJSDocClassTag(tagName: Identifier?, comment: String = definedExternally): JSDocClassTag - fun createJSDocClassTag(tagName: Identifier?): JSDocClassTag - fun createJSDocClassTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocClassTag - fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: String?): JSDocClassTag - fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: NodeArray?): JSDocClassTag - fun createJSDocPublicTag(tagName: Identifier?, comment: String = definedExternally): JSDocPublicTag - fun createJSDocPublicTag(tagName: Identifier?): JSDocPublicTag - fun createJSDocPublicTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPublicTag - fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: String?): JSDocPublicTag - fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: NodeArray?): JSDocPublicTag - fun createJSDocPrivateTag(tagName: Identifier?, comment: String = definedExternally): JSDocPrivateTag - fun createJSDocPrivateTag(tagName: Identifier?): JSDocPrivateTag - fun createJSDocPrivateTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPrivateTag - fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: String?): JSDocPrivateTag - fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: NodeArray?): JSDocPrivateTag - fun createJSDocProtectedTag(tagName: Identifier?, comment: String = definedExternally): JSDocProtectedTag - fun createJSDocProtectedTag(tagName: Identifier?): JSDocProtectedTag - fun createJSDocProtectedTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocProtectedTag - fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: String?): JSDocProtectedTag - fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: NodeArray?): JSDocProtectedTag - fun createJSDocReadonlyTag(tagName: Identifier?, comment: String = definedExternally): JSDocReadonlyTag - fun createJSDocReadonlyTag(tagName: Identifier?): JSDocReadonlyTag - fun createJSDocReadonlyTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocReadonlyTag - fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: String?): JSDocReadonlyTag - fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: NodeArray?): JSDocReadonlyTag - fun createJSDocUnknownTag(tagName: Identifier, comment: String = definedExternally): JSDocUnknownTag - fun createJSDocUnknownTag(tagName: Identifier): JSDocUnknownTag - fun createJSDocUnknownTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocUnknownTag - fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: String?): JSDocUnknownTag - fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: NodeArray?): JSDocUnknownTag - fun createJSDocDeprecatedTag(tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag - fun createJSDocDeprecatedTag(tagName: Identifier): JSDocDeprecatedTag - fun createJSDocDeprecatedTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag - fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag - fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier): JSDocDeprecatedTag - fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag - fun createJSDocOverrideTag(tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag - fun createJSDocOverrideTag(tagName: Identifier): JSDocOverrideTag - fun createJSDocOverrideTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag - fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag - fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier): JSDocOverrideTag - fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag - fun createJSDocText(text: String): JSDocText - fun updateJSDocText(node: JSDocText, text: String): JSDocText - fun createJSDocComment(comment: String? = definedExternally, tags: Array? = definedExternally): JSDoc - fun createJSDocComment(): JSDoc - fun createJSDocComment(comment: String? = definedExternally): JSDoc - fun createJSDocComment(comment: NodeArray? = definedExternally, tags: Array? = definedExternally): JSDoc - fun createJSDocComment(comment: NodeArray? = definedExternally): JSDoc - fun updateJSDocComment(node: JSDoc, comment: String?, tags: Array?): JSDoc - fun updateJSDocComment(node: JSDoc, comment: NodeArray?, tags: Array?): JSDoc - fun createJsxElement(openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement - fun updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement - fun createJsxSelfClosingElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun createJsxSelfClosingElement(tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun createJsxSelfClosingElement(tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun createJsxOpeningElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun createJsxOpeningElement(tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun createJsxOpeningElement(tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun createJsxClosingElement(tagName: Identifier): JsxClosingElement - fun createJsxClosingElement(tagName: ThisExpression): JsxClosingElement - fun createJsxClosingElement(tagName: JsxTagNamePropertyAccess): JsxClosingElement - fun updateJsxClosingElement(node: JsxClosingElement, tagName: Identifier): JsxClosingElement - fun updateJsxClosingElement(node: JsxClosingElement, tagName: ThisExpression): JsxClosingElement - fun updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNamePropertyAccess): JsxClosingElement - fun createJsxFragment(openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment): JsxFragment - fun createJsxText(text: String, containsOnlyTriviaWhiteSpaces: Boolean = definedExternally): JsxText - fun updateJsxText(node: JsxText, text: String, containsOnlyTriviaWhiteSpaces: Boolean = definedExternally): JsxText - fun createJsxOpeningFragment(): JsxOpeningFragment - fun createJsxJsxClosingFragment(): JsxClosingFragment - fun updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment): JsxFragment - fun createJsxAttribute(name: Identifier, initializer: StringLiteral?): JsxAttribute - fun createJsxAttribute(name: Identifier, initializer: JsxExpression?): JsxAttribute - fun updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral?): JsxAttribute - fun updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: JsxExpression?): JsxAttribute - fun createJsxAttributes(properties: Array): JsxAttributes - fun updateJsxAttributes(node: JsxAttributes, properties: Array): JsxAttributes - fun createJsxSpreadAttribute(expression: Expression): JsxSpreadAttribute - fun updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression): JsxSpreadAttribute - fun createJsxExpression(dotDotDotToken: DotDotDotToken?, expression: Expression?): JsxExpression - fun updateJsxExpression(node: JsxExpression, expression: Expression?): JsxExpression - fun createCaseClause(expression: Expression, statements: Array): CaseClause - fun updateCaseClause(node: CaseClause, expression: Expression, statements: Array): CaseClause - fun createDefaultClause(statements: Array): DefaultClause - fun updateDefaultClause(node: DefaultClause, statements: Array): DefaultClause - fun createHeritageClause(token: SyntaxKind, types: Array): HeritageClause -// fun createHeritageClause(token: SyntaxKind.ExtendsKeyword, types: Array): HeritageClause -// fun createHeritageClause(token: SyntaxKind.ImplementsKeyword, types: Array): HeritageClause - fun updateHeritageClause(node: HeritageClause, types: Array): HeritageClause - fun createCatchClause(variableDeclaration: String?, block: Block): CatchClause - fun createCatchClause(variableDeclaration: VariableDeclaration?, block: Block): CatchClause - fun updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration?, block: Block): CatchClause - fun createPropertyAssignment(name: String, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: Identifier, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: StringLiteral, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: NumericLiteral, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: ComputedPropertyName, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: PrivateIdentifier, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: Identifier, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: StringLiteral, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: NumericLiteral, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: ComputedPropertyName, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: PrivateIdentifier, initializer: Expression): PropertyAssignment - fun createShorthandPropertyAssignment(name: String, objectAssignmentInitializer: Expression = definedExternally): ShorthandPropertyAssignment - fun createShorthandPropertyAssignment(name: String): ShorthandPropertyAssignment - fun createShorthandPropertyAssignment(name: Identifier, objectAssignmentInitializer: Expression = definedExternally): ShorthandPropertyAssignment - fun createShorthandPropertyAssignment(name: Identifier): ShorthandPropertyAssignment - fun updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression?): ShorthandPropertyAssignment - fun createSpreadAssignment(expression: Expression): SpreadAssignment - fun updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment - fun createEnumMember(name: String, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: String): EnumMember - fun createEnumMember(name: Identifier, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: Identifier): EnumMember - fun createEnumMember(name: StringLiteral, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: StringLiteral): EnumMember - fun createEnumMember(name: NumericLiteral, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: NumericLiteral): EnumMember - fun createEnumMember(name: ComputedPropertyName, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: ComputedPropertyName): EnumMember - fun createEnumMember(name: PrivateIdentifier, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: PrivateIdentifier): EnumMember - fun updateEnumMember(node: EnumMember, name: Identifier, initializer: Expression?): EnumMember - fun updateEnumMember(node: EnumMember, name: StringLiteral, initializer: Expression?): EnumMember - fun updateEnumMember(node: EnumMember, name: NumericLiteral, initializer: Expression?): EnumMember - fun updateEnumMember(node: EnumMember, name: ComputedPropertyName, initializer: Expression?): EnumMember - fun updateEnumMember(node: EnumMember, name: PrivateIdentifier, initializer: Expression?): EnumMember - fun createSourceFile(statements: Array, endOfFileToken: Token /* Token & JSDocContainer */, flags: NodeFlags): SourceFile - fun updateSourceFile(node: SourceFile, statements: Array, isDeclarationFile: Boolean = definedExternally, referencedFiles: Array = definedExternally, typeReferences: Array = definedExternally, hasNoDefaultLib: Boolean = definedExternally, libReferences: Array = definedExternally): SourceFile - fun createNotEmittedStatement(original: Node): NotEmittedStatement - fun createPartiallyEmittedExpression(expression: Expression, original: Node = definedExternally): PartiallyEmittedExpression - fun updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression): PartiallyEmittedExpression - fun createCommaListExpression(elements: Array): CommaListExpression - fun updateCommaListExpression(node: CommaListExpression, elements: Array): CommaListExpression - fun createBundle(sourceFiles: Array, prepends: Array = definedExternally): Bundle - fun updateBundle(node: Bundle, sourceFiles: Array, prepends: Array = definedExternally): Bundle - fun createComma(left: Expression, right: Expression): BinaryExpression - fun createAssignment(left: ObjectLiteralExpression, right: Expression): dynamic /* ObjectDestructuringAssignment | ArrayDestructuringAssignment */ - fun createAssignment(left: ArrayLiteralExpression, right: Expression): dynamic /* ObjectDestructuringAssignment | ArrayDestructuringAssignment */ - fun createAssignment(left: Expression, right: Expression): AssignmentExpression - fun createLogicalOr(left: Expression, right: Expression): BinaryExpression - fun createLogicalAnd(left: Expression, right: Expression): BinaryExpression - fun createBitwiseOr(left: Expression, right: Expression): BinaryExpression - fun createBitwiseXor(left: Expression, right: Expression): BinaryExpression - fun createBitwiseAnd(left: Expression, right: Expression): BinaryExpression - fun createStrictEquality(left: Expression, right: Expression): BinaryExpression - fun createStrictInequality(left: Expression, right: Expression): BinaryExpression - fun createEquality(left: Expression, right: Expression): BinaryExpression - fun createInequality(left: Expression, right: Expression): BinaryExpression - fun createLessThan(left: Expression, right: Expression): BinaryExpression - fun createLessThanEquals(left: Expression, right: Expression): BinaryExpression - fun createGreaterThan(left: Expression, right: Expression): BinaryExpression - fun createGreaterThanEquals(left: Expression, right: Expression): BinaryExpression - fun createLeftShift(left: Expression, right: Expression): BinaryExpression - fun createRightShift(left: Expression, right: Expression): BinaryExpression - fun createUnsignedRightShift(left: Expression, right: Expression): BinaryExpression - fun createAdd(left: Expression, right: Expression): BinaryExpression - fun createSubtract(left: Expression, right: Expression): BinaryExpression - fun createMultiply(left: Expression, right: Expression): BinaryExpression - fun createDivide(left: Expression, right: Expression): BinaryExpression - fun createModulo(left: Expression, right: Expression): BinaryExpression - fun createExponent(left: Expression, right: Expression): BinaryExpression - fun createPrefixPlus(operand: Expression): PrefixUnaryExpression - fun createPrefixMinus(operand: Expression): PrefixUnaryExpression - fun createPrefixIncrement(operand: Expression): PrefixUnaryExpression - fun createPrefixDecrement(operand: Expression): PrefixUnaryExpression - fun createBitwiseNot(operand: Expression): PrefixUnaryExpression - fun createLogicalNot(operand: Expression): PrefixUnaryExpression - fun createPostfixIncrement(operand: Expression): PostfixUnaryExpression - fun createPostfixDecrement(operand: Expression): PostfixUnaryExpression - fun createImmediatelyInvokedFunctionExpression(statements: Array): CallExpression - fun createImmediatelyInvokedFunctionExpression(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression - fun createImmediatelyInvokedArrowFunction(statements: Array): CallExpression - fun createImmediatelyInvokedArrowFunction(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression - fun createVoidZero(): VoidExpression - fun createExportDefault(expression: Expression): ExportAssignment - fun createExternalModuleExport(exportName: Identifier): ExportDeclaration - fun restoreOuterExpressions(outerExpression: Expression?, innerExpression: Expression, kinds: OuterExpressionKinds = definedExternally): Expression -} - -external interface CoreTransformationContext { - val factory: NodeFactory - fun getCompilerOptions(): CompilerOptions - fun startLexicalEnvironment() - fun suspendLexicalEnvironment() - fun resumeLexicalEnvironment() - fun endLexicalEnvironment(): Array? - fun hoistFunctionDeclaration(node: FunctionDeclaration) - fun hoistVariableDeclaration(node: Identifier) -} - -external interface TransformationContext : CoreTransformationContext { - fun requestEmitHelper(helper: ScopedEmitHelper) - fun requestEmitHelper(helper: UnscopedEmitHelper) - fun readEmitHelpers(): Array? - fun enableSubstitution(kind: SyntaxKind) - fun isSubstitutionEnabled(node: Node): Boolean - var onSubstituteNode: (hint: EmitHint, node: Node) -> Node - fun enableEmitNotification(kind: SyntaxKind) - fun isEmitNotificationEnabled(node: Node): Boolean - var onEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) -> Unit -} - -external interface TransformationResult { - var transformed: Array - var diagnostics: Array? - get() = definedExternally - set(value) = definedExternally - fun substituteNode(hint: EmitHint, node: Node): Node - fun emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) - val isEmitNotificationEnabled: ((node: Node) -> Boolean)? - fun dispose() -} - -external interface NodeVisitor { - @nativeInvoke - operator fun invoke(nodes: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T - @nativeInvoke - operator fun invoke(nodes: T, visitor: Visitor?): T - @nativeInvoke - operator fun invoke(nodes: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T - @nativeInvoke - operator fun invoke(nodes: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T? - @nativeInvoke - operator fun invoke(nodes: T?, visitor: Visitor?): T? - @nativeInvoke - operator fun invoke(nodes: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T? -} - -external interface NodesVisitor { - @nativeInvoke - operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray - @nativeInvoke - operator fun invoke(nodes: NodeArray, visitor: Visitor?): NodeArray - @nativeInvoke - operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray - @nativeInvoke - operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray - @nativeInvoke - operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray? - @nativeInvoke - operator fun invoke(nodes: NodeArray?, visitor: Visitor?): NodeArray? - @nativeInvoke - operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray? - @nativeInvoke - operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray? -} - -external interface Printer { - fun printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): String - fun printList(format: ListFormat, list: NodeArray, sourceFile: SourceFile): String - fun printFile(sourceFile: SourceFile): String - fun printBundle(bundle: Bundle): String -} - -external interface PrintHandlers { - val hasGlobalName: ((name: String) -> Boolean)? - val onEmitNode: ((hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) -> Unit)? - val isEmitNotificationEnabled: ((node: Node) -> Boolean)? - val substituteNode: ((hint: EmitHint, node: Node) -> Node)? -} - -external interface PrinterOptions { - var removeComments: Boolean? - get() = definedExternally - set(value) = definedExternally - var newLine: NewLineKind? - get() = definedExternally - set(value) = definedExternally - var omitTrailingSemicolon: Boolean? - get() = definedExternally - set(value) = definedExternally - var noEmitHelpers: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface GetEffectiveTypeRootsHost { - val directoryExists: ((directoryName: String) -> Boolean)? - val getCurrentDirectory: (() -> String)? -} - -external interface TextSpan { - var start: Number - var length: Number -} - -external interface TextChangeRange { - var span: TextSpan - var newLength: Number -} - -external interface SyntaxList : Node { - var _children: Array -} - -external enum class ListFormat { - None /* = 0 */, - SingleLine /* = 0 */, - MultiLine /* = 1 */, - PreserveLines /* = 2 */, - LinesMask /* = 3 */, - NotDelimited /* = 0 */, - BarDelimited /* = 4 */, - AmpersandDelimited /* = 8 */, - CommaDelimited /* = 16 */, - AsteriskDelimited /* = 32 */, - DelimitersMask /* = 60 */, - AllowTrailingComma /* = 64 */, - Indented /* = 128 */, - SpaceBetweenBraces /* = 256 */, - SpaceBetweenSiblings /* = 512 */, - Braces /* = 1024 */, - Parenthesis /* = 2048 */, - AngleBrackets /* = 4096 */, - SquareBrackets /* = 8192 */, - BracketsMask /* = 15360 */, - OptionalIfUndefined /* = 16384 */, - OptionalIfEmpty /* = 32768 */, - Optional /* = 49152 */, - PreferNewLine /* = 65536 */, - NoTrailingNewLine /* = 131072 */, - NoInterveningComments /* = 262144 */, - NoSpaceIfEmpty /* = 524288 */, - SingleElement /* = 1048576 */, - SpaceAfterList /* = 2097152 */, - Modifiers /* = 262656 */, - HeritageClauses /* = 512 */, - SingleLineTypeLiteralMembers /* = 768 */, - MultiLineTypeLiteralMembers /* = 32897 */, - SingleLineTupleTypeElements /* = 528 */, - MultiLineTupleTypeElements /* = 657 */, - UnionTypeConstituents /* = 516 */, - IntersectionTypeConstituents /* = 520 */, - ObjectBindingPatternElements /* = 525136 */, - ArrayBindingPatternElements /* = 524880 */, - ObjectLiteralExpressionProperties /* = 526226 */, - ArrayLiteralExpressionElements /* = 8914 */, - CommaListElements /* = 528 */, - CallExpressionArguments /* = 2576 */, - NewExpressionArguments /* = 18960 */, - TemplateExpressionSpans /* = 262144 */, - SingleLineBlockStatements /* = 768 */, - MultiLineBlockStatements /* = 129 */, - VariableDeclarationList /* = 528 */, - SingleLineFunctionBodyStatements /* = 768 */, - MultiLineFunctionBodyStatements /* = 1 */, - ClassHeritageClauses /* = 0 */, - ClassMembers /* = 129 */, - InterfaceMembers /* = 129 */, - EnumMembers /* = 145 */, - CaseBlockClauses /* = 129 */, - NamedImportsOrExportsElements /* = 525136 */, - JsxElementOrFragmentChildren /* = 262144 */, - JsxElementAttributes /* = 262656 */, - CaseOrDefaultClauseStatements /* = 163969 */, - HeritageClauseTypes /* = 528 */, - SourceFileStatements /* = 131073 */, - Decorators /* = 2146305 */, - TypeArguments /* = 53776 */, - TypeParameters /* = 53776 */, - Parameters /* = 2576 */, - IndexSignatureParameters /* = 8848 */, - JSDocComment /* = 33 */ -} - -external interface UserPreferences { - val disableSuggestions: Boolean? - get() = definedExternally - val quotePreference: String? /* "auto" | "double" | "single" */ - get() = definedExternally - val includeCompletionsForModuleExports: Boolean? - get() = definedExternally - val includeCompletionsForImportStatements: Boolean? - get() = definedExternally - val includeCompletionsWithSnippetText: Boolean? - get() = definedExternally - val includeAutomaticOptionalChainCompletions: Boolean? - get() = definedExternally - val includeCompletionsWithInsertText: Boolean? - get() = definedExternally - val allowIncompleteCompletions: Boolean? - get() = definedExternally - val importModuleSpecifierPreference: String? /* "shortest" | "project-relative" | "relative" | "non-relative" */ - get() = definedExternally - val importModuleSpecifierEnding: String? /* "auto" | "minimal" | "index" | "js" */ - get() = definedExternally - val allowTextChangesInNewFiles: Boolean? - get() = definedExternally - val providePrefixAndSuffixTextForRename: Boolean? - get() = definedExternally - val includePackageJsonAutoImports: String? /* "auto" | "on" | "off" */ - get() = definedExternally - val provideRefactorNotApplicableReason: Boolean? - get() = definedExternally -} - -external interface PseudoBigInt { - var negative: Boolean? - var base10Value: String -} - -external enum class FileWatcherEventKind { - Created /* = 0 */, - Changed /* = 1 */, - Deleted /* = 2 */ -} - -external interface System { - var args: Array - var newLine: String - var useCaseSensitiveFileNames: Boolean? - fun write(s: String) - val writeOutputIsTTY: (() -> Boolean)? - val getWidthOfTerminal: (() -> Number)? - fun readFile(path: String, encoding: String = definedExternally): String? - val getFileSize: ((path: String) -> Number)? - fun writeFile(path: String, data: String, writeByteOrderMark: Boolean = definedExternally) - val watchFile: ((path: String, callback: FileWatcherCallback, pollingInterval: Number, options: WatchOptions) -> FileWatcher)? - val watchDirectory: ((path: String, callback: DirectoryWatcherCallback, recursive: Boolean, options: WatchOptions) -> FileWatcher)? - fun resolvePath(path: String): String - fun fileExists(path: String): Boolean - fun directoryExists(path: String): Boolean - fun createDirectory(path: String) - fun getExecutingFilePath(): String - fun getCurrentDirectory(): String - fun getDirectories(path: String): Array - fun readDirectory(path: String, extensions: Array = definedExternally, exclude: Array = definedExternally, include: Array = definedExternally, depth: Number = definedExternally): Array - val getModifiedTime: ((path: String) -> Date?)? - val setModifiedTime: ((path: String, time: Date) -> Unit)? - val deleteFile: ((path: String) -> Unit)? - val createHash: ((data: String) -> String)? - val createSHA256Hash: ((data: String) -> String)? - val getMemoryUsage: (() -> Number)? - fun exit(exitCode: Number = definedExternally) - val realpath: ((path: String) -> String)? - val setTimeout: ((callback: (args: Any) -> Unit, ms: Number, args: Any) -> Any)? - val clearTimeout: ((timeoutId: Any) -> Unit)? - val clearScreen: (() -> Unit)? - val base64decode: ((input: String) -> String)? - val base64encode: ((input: String) -> String)? -} - -external interface FileWatcher { - fun close() -} - -external fun getNodeMajorVersion(): Number? - -external var sys: System - -external interface Scanner { - fun getStartPos(): Number - fun getToken(): SyntaxKind - fun getTextPos(): Number - fun getTokenPos(): Number - fun getTokenText(): String - fun getTokenValue(): String - fun hasUnicodeEscape(): Boolean - fun hasExtendedUnicodeEscape(): Boolean - fun hasPrecedingLineBreak(): Boolean - fun isIdentifier(): Boolean - fun isReservedWord(): Boolean - fun isUnterminated(): Boolean - fun reScanGreaterToken(): SyntaxKind - fun reScanSlashToken(): SyntaxKind - fun reScanAsteriskEqualsToken(): SyntaxKind - fun reScanTemplateToken(isTaggedTemplate: Boolean): SyntaxKind - fun reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind - fun scanJsxIdentifier(): SyntaxKind - fun scanJsxAttributeValue(): SyntaxKind - fun reScanJsxAttributeValue(): SyntaxKind - fun reScanJsxToken(allowMultilineJsxText: Boolean = definedExternally): dynamic /* SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken */ - fun reScanLessThanToken(): SyntaxKind - fun reScanHashToken(): SyntaxKind - fun reScanQuestionToken(): SyntaxKind - fun reScanInvalidIdentifier(): SyntaxKind - fun scanJsxToken(): dynamic /* SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken */ - fun scanJsDocToken(): dynamic /* SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.HashToken | SyntaxKind.Unknown | SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IntrinsicKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.OverrideKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword */ - fun scan(): SyntaxKind - fun getText(): String - fun setText(text: String?, start: Number = definedExternally, length: Number = definedExternally) -// fun setOnError(onError: ErrorCallback?) // TODO why isn't ErrorCallback defined? - fun setOnError(onError: dynamic) - fun setScriptTarget(scriptTarget: ScriptTarget) - fun setLanguageVariant(variant: LanguageVariant) - fun setTextPos(textPos: Number) - fun lookAhead(callback: () -> T): T - fun scanRange(start: Number, length: Number, callback: () -> T): T - fun tryScan(callback: () -> T): T -} - -external fun tokenToString(t: SyntaxKind): String? - -external fun getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: Number, character: Number): Number - -external fun getLineAndCharacterOfPosition(sourceFile: SourceFileLike, position: Number): LineAndCharacter - -external fun isWhiteSpaceLike(ch: Number): Boolean - -external fun isWhiteSpaceSingleLine(ch: Number): Boolean - -external fun isLineBreak(ch: Number): Boolean - -external fun couldStartTrivia(text: String, pos: Number): Boolean - -external fun forEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean) -> U): U? - -external fun forEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T) -> U, state: T): U? - -external fun forEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean) -> U): U? - -external fun forEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T) -> U, state: T): U? - -external fun reduceEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T, memo: U) -> U, state: T, initial: U): U? - -external fun reduceEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T, memo: U) -> U, state: T, initial: U): U? - -external fun getLeadingCommentRanges(text: String, pos: Number): Array? - -external fun getTrailingCommentRanges(text: String, pos: Number): Array? - -external fun getShebang(text: String): String? - -external fun isIdentifierStart(ch: Number, languageVersion: ScriptTarget?): Boolean - -external fun isIdentifierPart(ch: Number, languageVersion: ScriptTarget?, identifierVariant: LanguageVariant = definedExternally): Boolean - -//external fun createScanner(languageVersion: ScriptTarget, skipTrivia: Boolean, languageVariant: LanguageVariant = definedExternally, textInitial: String = definedExternally, onError: ErrorCallback = definedExternally, start: Number = definedExternally, length: Number = definedExternally): Scanner - -external fun isExternalModuleNameRelative(moduleName: String): Boolean - -external fun sortAndDeduplicateDiagnostics(diagnostics: Array): SortedReadonlyArray - -external fun getDefaultLibFileName(options: CompilerOptions): String - -external fun textSpanEnd(span: TextSpan): Number - -external fun textSpanIsEmpty(span: TextSpan): Boolean - -external fun textSpanContainsPosition(span: TextSpan, position: Number): Boolean - -external fun textSpanContainsTextSpan(span: TextSpan, other: TextSpan): Boolean - -external fun textSpanOverlapsWith(span: TextSpan, other: TextSpan): Boolean - -external fun textSpanOverlap(span1: TextSpan, span2: TextSpan): TextSpan? - -external fun textSpanIntersectsWithTextSpan(span: TextSpan, other: TextSpan): Boolean - -external fun textSpanIntersectsWith(span: TextSpan, start: Number, length: Number): Boolean - -external fun decodedTextSpanIntersectsWith(start1: Number, length1: Number, start2: Number, length2: Number): Boolean - -external fun textSpanIntersectsWithPosition(span: TextSpan, position: Number): Boolean - -external fun textSpanIntersection(span1: TextSpan, span2: TextSpan): TextSpan? - -external fun createTextSpan(start: Number, length: Number): TextSpan - -external fun createTextSpanFromBounds(start: Number, end: Number): TextSpan - -external fun textChangeRangeNewSpan(range: TextChangeRange): TextSpan - -external fun textChangeRangeIsUnchanged(range: TextChangeRange): Boolean - -external fun createTextChangeRange(span: TextSpan, newLength: Number): TextChangeRange - -external var unchangedTextChangeRange: TextChangeRange - -external fun collapseTextChangeRangesAcrossMultipleVersions(changes: Array): TextChangeRange - -external fun getTypeParameterOwner(d: Declaration): Declaration? - -external interface `T$23` { - var parent: ConstructorDeclaration - var name: Identifier -} - -external fun isParameterPropertyDeclaration(node: Node, parent: Node): Boolean - -external fun isEmptyBindingPattern(node: Identifier): Boolean - -external fun isEmptyBindingPattern(node: ObjectBindingPattern): Boolean - -external fun isEmptyBindingPattern(node: ArrayBindingPattern): Boolean - -external fun isEmptyBindingElement(node: BindingElement): Boolean - -external fun walkUpBindingElementsAndPatterns(binding: BindingElement): dynamic /* VariableDeclaration | ParameterDeclaration */ - -external fun getCombinedModifierFlags(node: Declaration): ModifierFlags - -external fun getCombinedNodeFlags(node: Node): NodeFlags - -external interface `T$24` { - fun getExecutingFilePath(): String - fun resolvePath(path: String): String - fun fileExists(fileName: String): Boolean - fun readFile(fileName: String): String? -} - -external fun validateLocaleAndSetLanguage(locale: String, sys: `T$24`, errors: Push = definedExternally) - -external fun getOriginalNode(node: Node): Node - -external fun getOriginalNode(node: Node, nodeTest: (node: Node) -> Boolean): T - -external fun getOriginalNode(node: Node?): Node? - -external fun getOriginalNode(node: Node?, nodeTest: (node: Node?) -> Boolean): T? - -external fun findAncestor(node: Node?, callback: (element: Node) -> Boolean): T? - -external fun findAncestor(node: Node?, callback: (element: Node) -> Any): Node? - -external fun isParseTreeNode(node: Node): Boolean - -external fun getParseTreeNode(node: Node?): Node? - -external fun getParseTreeNode(node: T?, nodeTest: (node: Node) -> Boolean = definedExternally): T? - -external fun getParseTreeNode(node: T?): T? - -external fun escapeLeadingUnderscores(identifier: String): dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - -external fun unescapeLeadingUnderscores(identifier: String /* String & `T$8` */): String - -external fun unescapeLeadingUnderscores(identifier: Unit /* Unit & `T$8` */): String - -external fun unescapeLeadingUnderscores(identifier: InternalSymbolName): String - -external fun idText(identifierOrPrivateName: Identifier): String - -external fun idText(identifierOrPrivateName: PrivateIdentifier): String - -external fun symbolName(symbol: Symbol): String - -external fun getNameOfJSDocTypedef(declaration: JSDocTypedefTag): dynamic /* Identifier? | PrivateIdentifier? */ - -external fun getNameOfDeclaration(declaration: Declaration?): dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ - -external fun getNameOfDeclaration(declaration: Expression?): dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ - -external fun getJSDocParameterTags(param: ParameterDeclaration): Array - -external fun getJSDocTypeParameterTags(param: TypeParameterDeclaration): Array - -external fun hasJSDocParameterTags(node: FunctionDeclaration): Boolean - -external fun hasJSDocParameterTags(node: MethodDeclaration): Boolean - -external fun hasJSDocParameterTags(node: GetAccessorDeclaration): Boolean - -external fun hasJSDocParameterTags(node: SetAccessorDeclaration): Boolean - -external fun hasJSDocParameterTags(node: ConstructorDeclaration): Boolean - -external fun hasJSDocParameterTags(node: FunctionExpression): Boolean - -external fun hasJSDocParameterTags(node: ArrowFunction): Boolean - -external fun hasJSDocParameterTags(node: CallSignatureDeclaration): Boolean - -external fun hasJSDocParameterTags(node: ConstructSignatureDeclaration): Boolean - -external fun hasJSDocParameterTags(node: MethodSignature): Boolean - -external fun hasJSDocParameterTags(node: IndexSignatureDeclaration): Boolean - -external fun hasJSDocParameterTags(node: FunctionTypeNode): Boolean - -external fun hasJSDocParameterTags(node: ConstructorTypeNode): Boolean - -external fun hasJSDocParameterTags(node: JSDocFunctionType): Boolean - -external fun getJSDocAugmentsTag(node: Node): JSDocAugmentsTag? - -external fun getJSDocImplementsTags(node: Node): Array - -external fun getJSDocClassTag(node: Node): JSDocClassTag? - -external fun getJSDocPublicTag(node: Node): JSDocPublicTag? - -external fun getJSDocPrivateTag(node: Node): JSDocPrivateTag? - -external fun getJSDocProtectedTag(node: Node): JSDocProtectedTag? - -external fun getJSDocReadonlyTag(node: Node): JSDocReadonlyTag? - -external fun getJSDocOverrideTagNoCache(node: Node): JSDocOverrideTag? - -external fun getJSDocDeprecatedTag(node: Node): JSDocDeprecatedTag? - -external fun getJSDocEnumTag(node: Node): JSDocEnumTag? - -external fun getJSDocThisTag(node: Node): JSDocThisTag? - -external fun getJSDocReturnTag(node: Node): JSDocReturnTag? - -external fun getJSDocTemplateTag(node: Node): JSDocTemplateTag? - -external fun getJSDocTypeTag(node: Node): JSDocTypeTag? - -external fun getJSDocType(node: Node): TypeNode? - -external fun getJSDocReturnType(node: Node): TypeNode? - -external fun getJSDocTags(node: Node): Array - -external fun getAllJSDocTags(node: Node, predicate: (tag: JSDocTag) -> Boolean): Array - -external fun getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): Array - -external fun getTextOfJSDocComment(comment: String = definedExternally): String? - -external fun getTextOfJSDocComment(): String? - -external fun getTextOfJSDocComment(comment: NodeArray = definedExternally): String? - -external fun getEffectiveTypeParameterDeclarations(node: Any /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature */): Array - -external fun getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode? - -external fun isMemberName(node: Node): Boolean - -external fun isPropertyAccessChain(node: Node): Boolean - -external fun isElementAccessChain(node: Node): Boolean - -external fun isCallChain(node: Node): Boolean - -external fun isOptionalChain(node: Node): Boolean - -external fun isNullishCoalesce(node: Node): Boolean - -external fun isConstTypeReference(node: Node): Boolean - -external fun skipPartiallyEmittedExpressions(node: Expression): Expression - -external fun skipPartiallyEmittedExpressions(node: Node): Node - -external fun isNonNullChain(node: Node): Boolean - -external fun isBreakOrContinueStatement(node: Node): Boolean - -external fun isNamedExportBindings(node: Node): Boolean - -external fun isUnparsedTextLike(node: Node): Boolean - -external fun isUnparsedNode(node: Node): Boolean - -external fun isJSDocPropertyLikeTag(node: Node): Boolean - -external fun isTokenKind(kind: SyntaxKind): Boolean - -external fun isToken(n: Node): Boolean - -external fun isLiteralExpression(node: Node): Boolean - -external fun isTemplateLiteralToken(node: Node): Boolean - -external fun isTemplateMiddleOrTemplateTail(node: Node): Boolean - -external fun isImportOrExportSpecifier(node: Node): Boolean - -external fun isTypeOnlyImportOrExportDeclaration(node: Node): Boolean - -external fun isStringTextContainingNode(node: Node): Boolean - -external fun isModifier(node: Node): Boolean - -external fun isEntityName(node: Node): Boolean - -external fun isPropertyName(node: Node): Boolean - -external fun isBindingName(node: Node): Boolean - -external fun isFunctionLike(node: Node?): Boolean - -external fun isClassElement(node: Node): Boolean - -external fun isClassLike(node: Node): Boolean - -external fun isAccessor(node: Node): Boolean - -external fun isTypeElement(node: Node): Boolean - -external fun isClassOrTypeElement(node: Node): Boolean - -external fun isObjectLiteralElementLike(node: Node): Boolean - -external fun isTypeNode(node: Node): Boolean - -external fun isFunctionOrConstructorTypeNode(node: Node): Boolean - -external fun isPropertyAccessOrQualifiedName(node: Node): Boolean - -external fun isCallLikeExpression(node: Node): Boolean - -external fun isCallOrNewExpression(node: Node): Boolean - -external fun isTemplateLiteral(node: Node): Boolean - -external fun isAssertionExpression(node: Node): Boolean - -external fun isIterationStatement(node: Node, lookInLabeledStatements: Boolean): Boolean - -external fun isJsxOpeningLikeElement(node: Node): Boolean - -external fun isCaseOrDefaultClause(node: Node): Boolean - -external fun isJSDocCommentContainingNode(node: Node): Boolean - -external fun isSetAccessor(node: Node): Boolean - -external fun isGetAccessor(node: Node): Boolean - -external fun hasOnlyExpressionInitializer(node: Node): Boolean - -external fun isObjectLiteralElement(node: Node): Boolean - -external fun isStringLiteralLike(node: Node): Boolean - -external fun isJSDocLinkLike(node: Node): Boolean - -external var factory: NodeFactory - -external fun createUnparsedSourceFile(text: String): UnparsedSource - -external fun createUnparsedSourceFile(inputFile: InputFiles, type: String /* "js" | "dts" */, stripInternal: Boolean = definedExternally): UnparsedSource - -external fun createUnparsedSourceFile(inputFile: InputFiles, type: String /* "js" | "dts" */): UnparsedSource - -external fun createUnparsedSourceFile(text: String, mapPath: String?, map: String?): UnparsedSource - -external fun createInputFiles(javascriptText: String, declarationText: String): InputFiles - -external fun createInputFiles(readFileText: (path: String) -> String?, javascriptPath: String, javascriptMapPath: String?, declarationPath: String, declarationMapPath: String?, buildInfoPath: String?): InputFiles - -external fun createInputFiles(javascriptText: String, declarationText: String, javascriptMapPath: String?, javascriptMapText: String?, declarationMapPath: String?, declarationMapText: String?): InputFiles - -external fun createSourceMapSource(fileName: String, text: String, skipTrivia: (pos: Number) -> Number = definedExternally): SourceMapSource - -external fun setOriginalNode(node: T, original: Node?): T - -external fun disposeEmitNodes(sourceFile: SourceFile?) - -external fun setEmitFlags(node: T, emitFlags: EmitFlags): T - -external fun getSourceMapRange(node: Node): SourceMapRange - -external fun setSourceMapRange(node: T, range: SourceMapRange?): T - -external fun getTokenSourceMapRange(node: Node, token: SyntaxKind): SourceMapRange? - -external fun setTokenSourceMapRange(node: T, token: SyntaxKind, range: SourceMapRange?): T - -external fun getCommentRange(node: Node): TextRange - -external fun setCommentRange(node: T, range: TextRange): T - -external fun getSyntheticLeadingComments(node: Node): Array? - -external fun setSyntheticLeadingComments(node: T, comments: Array?): T - -external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind, text: String, hasTrailingNewLine: Boolean = definedExternally): T -external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind, text: String): T -//external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T -//external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String): T -//external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T -//external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String): T - -external fun getSyntheticTrailingComments(node: Node): Array? - -external fun setSyntheticTrailingComments(node: T, comments: Array?): T - -external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind, text: String, hasTrailingNewLine: Boolean = definedExternally): T -external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind, text: String): T -//external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T -//external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String): T -//external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T -//external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String): T - -external fun moveSyntheticComments(node: T, original: Node): T - -external fun getConstantValue(node: PropertyAccessExpression): dynamic /* String? | Number? */ - -external fun getConstantValue(node: ElementAccessExpression): dynamic /* String? | Number? */ - -external fun setConstantValue(node: PropertyAccessExpression, value: String): dynamic /* PropertyAccessExpression | ElementAccessExpression */ - -external fun setConstantValue(node: PropertyAccessExpression, value: Number): dynamic /* PropertyAccessExpression | ElementAccessExpression */ - -external fun setConstantValue(node: ElementAccessExpression, value: String): dynamic /* PropertyAccessExpression | ElementAccessExpression */ - -external fun setConstantValue(node: ElementAccessExpression, value: Number): dynamic /* PropertyAccessExpression | ElementAccessExpression */ - -external fun addEmitHelper(node: T, helper: ScopedEmitHelper): T - -external fun addEmitHelper(node: T, helper: UnscopedEmitHelper): T - -external fun addEmitHelpers(node: T, helpers: Array?): T - -external fun removeEmitHelper(node: Node, helper: ScopedEmitHelper): Boolean - -external fun removeEmitHelper(node: Node, helper: UnscopedEmitHelper): Boolean - -external fun getEmitHelpers(node: Node): Array? - -external fun moveEmitHelpers(source: Node, target: Node, predicate: (helper: Any /* ScopedEmitHelper | UnscopedEmitHelper */) -> Boolean) - -external fun isNumericLiteral(node: Node): Boolean - -external fun isBigIntLiteral(node: Node): Boolean - -external fun isStringLiteral(node: Node): Boolean - -external fun isJsxText(node: Node): Boolean - -external fun isRegularExpressionLiteral(node: Node): Boolean - -external fun isNoSubstitutionTemplateLiteral(node: Node): Boolean - -external fun isTemplateHead(node: Node): Boolean - -external fun isTemplateMiddle(node: Node): Boolean - -external fun isTemplateTail(node: Node): Boolean - -external fun isDotDotDotToken(node: Node): Boolean - -external fun isPlusToken(node: Node): Boolean - -external fun isMinusToken(node: Node): Boolean - -external fun isAsteriskToken(node: Node): Boolean - -external fun isIdentifier(node: Node): Boolean - -external fun isPrivateIdentifier(node: Node): Boolean - -external fun isQualifiedName(node: Node): Boolean - -external fun isComputedPropertyName(node: Node): Boolean - -external fun isTypeParameterDeclaration(node: Node): Boolean - -external fun isParameter(node: Node): Boolean - -external fun isDecorator(node: Node): Boolean - -external fun isPropertySignature(node: Node): Boolean - -external fun isPropertyDeclaration(node: Node): Boolean - -external fun isMethodSignature(node: Node): Boolean - -external fun isMethodDeclaration(node: Node): Boolean - -external fun isClassStaticBlockDeclaration(node: Node): Boolean - -external fun isConstructorDeclaration(node: Node): Boolean - -external fun isGetAccessorDeclaration(node: Node): Boolean - -external fun isSetAccessorDeclaration(node: Node): Boolean - -external fun isCallSignatureDeclaration(node: Node): Boolean - -external fun isConstructSignatureDeclaration(node: Node): Boolean - -external fun isIndexSignatureDeclaration(node: Node): Boolean - -external fun isTypePredicateNode(node: Node): Boolean - -external fun isTypeReferenceNode(node: Node): Boolean - -external fun isFunctionTypeNode(node: Node): Boolean - -external fun isConstructorTypeNode(node: Node): Boolean - -external fun isTypeQueryNode(node: Node): Boolean - -external fun isTypeLiteralNode(node: Node): Boolean - -external fun isArrayTypeNode(node: Node): Boolean - -external fun isTupleTypeNode(node: Node): Boolean - -external fun isNamedTupleMember(node: Node): Boolean - -external fun isOptionalTypeNode(node: Node): Boolean - -external fun isRestTypeNode(node: Node): Boolean - -external fun isUnionTypeNode(node: Node): Boolean - -external fun isIntersectionTypeNode(node: Node): Boolean - -external fun isConditionalTypeNode(node: Node): Boolean - -external fun isInferTypeNode(node: Node): Boolean - -external fun isParenthesizedTypeNode(node: Node): Boolean - -external fun isThisTypeNode(node: Node): Boolean - -external fun isTypeOperatorNode(node: Node): Boolean - -external fun isIndexedAccessTypeNode(node: Node): Boolean - -external fun isMappedTypeNode(node: Node): Boolean - -external fun isLiteralTypeNode(node: Node): Boolean - -external fun isImportTypeNode(node: Node): Boolean - -external fun isTemplateLiteralTypeSpan(node: Node): Boolean - -external fun isTemplateLiteralTypeNode(node: Node): Boolean - -external fun isObjectBindingPattern(node: Node): Boolean - -external fun isArrayBindingPattern(node: Node): Boolean - -external fun isBindingElement(node: Node): Boolean - -external fun isArrayLiteralExpression(node: Node): Boolean - -external fun isObjectLiteralExpression(node: Node): Boolean - -external fun isPropertyAccessExpression(node: Node): Boolean - -external fun isElementAccessExpression(node: Node): Boolean - -external fun isCallExpression(node: Node): Boolean - -external fun isNewExpression(node: Node): Boolean - -external fun isTaggedTemplateExpression(node: Node): Boolean - -external fun isTypeAssertionExpression(node: Node): Boolean - -external fun isParenthesizedExpression(node: Node): Boolean - -external fun isFunctionExpression(node: Node): Boolean - -external fun isArrowFunction(node: Node): Boolean - -external fun isDeleteExpression(node: Node): Boolean - -external fun isTypeOfExpression(node: Node): Boolean - -external fun isVoidExpression(node: Node): Boolean - -external fun isAwaitExpression(node: Node): Boolean - -external fun isPrefixUnaryExpression(node: Node): Boolean - -external fun isPostfixUnaryExpression(node: Node): Boolean - -external fun isBinaryExpression(node: Node): Boolean - -external fun isConditionalExpression(node: Node): Boolean - -external fun isTemplateExpression(node: Node): Boolean - -external fun isYieldExpression(node: Node): Boolean - -external fun isSpreadElement(node: Node): Boolean - -external fun isClassExpression(node: Node): Boolean - -external fun isOmittedExpression(node: Node): Boolean - -external fun isExpressionWithTypeArguments(node: Node): Boolean - -external fun isAsExpression(node: Node): Boolean - -external fun isNonNullExpression(node: Node): Boolean - -external fun isMetaProperty(node: Node): Boolean - -external fun isSyntheticExpression(node: Node): Boolean - -external fun isPartiallyEmittedExpression(node: Node): Boolean - -external fun isCommaListExpression(node: Node): Boolean - -external fun isTemplateSpan(node: Node): Boolean - -external fun isSemicolonClassElement(node: Node): Boolean - -external fun isBlock(node: Node): Boolean - -external fun isVariableStatement(node: Node): Boolean - -external fun isEmptyStatement(node: Node): Boolean - -external fun isExpressionStatement(node: Node): Boolean - -external fun isIfStatement(node: Node): Boolean - -external fun isDoStatement(node: Node): Boolean - -external fun isWhileStatement(node: Node): Boolean - -external fun isForStatement(node: Node): Boolean - -external fun isForInStatement(node: Node): Boolean - -external fun isForOfStatement(node: Node): Boolean - -external fun isContinueStatement(node: Node): Boolean - -external fun isBreakStatement(node: Node): Boolean - -external fun isReturnStatement(node: Node): Boolean - -external fun isWithStatement(node: Node): Boolean - -external fun isSwitchStatement(node: Node): Boolean - -external fun isLabeledStatement(node: Node): Boolean - -external fun isThrowStatement(node: Node): Boolean - -external fun isTryStatement(node: Node): Boolean - -external fun isDebuggerStatement(node: Node): Boolean - -external fun isVariableDeclaration(node: Node): Boolean - -external fun isVariableDeclarationList(node: Node): Boolean - -external fun isFunctionDeclaration(node: Node): Boolean - -external fun isClassDeclaration(node: Node): Boolean - -external fun isInterfaceDeclaration(node: Node): Boolean - -external fun isTypeAliasDeclaration(node: Node): Boolean - -external fun isEnumDeclaration(node: Node): Boolean - -external fun isModuleDeclaration(node: Node): Boolean - -external fun isModuleBlock(node: Node): Boolean - -external fun isCaseBlock(node: Node): Boolean - -external fun isNamespaceExportDeclaration(node: Node): Boolean - -external fun isImportEqualsDeclaration(node: Node): Boolean - -external fun isImportDeclaration(node: Node): Boolean - -external fun isImportClause(node: Node): Boolean - -external fun isNamespaceImport(node: Node): Boolean - -external fun isNamespaceExport(node: Node): Boolean - -external fun isNamedImports(node: Node): Boolean - -external fun isImportSpecifier(node: Node): Boolean - -external fun isExportAssignment(node: Node): Boolean - -external fun isExportDeclaration(node: Node): Boolean - -external fun isNamedExports(node: Node): Boolean - -external fun isExportSpecifier(node: Node): Boolean - -external fun isMissingDeclaration(node: Node): Boolean - -external fun isNotEmittedStatement(node: Node): Boolean - -external fun isExternalModuleReference(node: Node): Boolean - -external fun isJsxElement(node: Node): Boolean - -external fun isJsxSelfClosingElement(node: Node): Boolean - -external fun isJsxOpeningElement(node: Node): Boolean - -external fun isJsxClosingElement(node: Node): Boolean - -external fun isJsxFragment(node: Node): Boolean - -external fun isJsxOpeningFragment(node: Node): Boolean - -external fun isJsxClosingFragment(node: Node): Boolean - -external fun isJsxAttribute(node: Node): Boolean - -external fun isJsxAttributes(node: Node): Boolean - -external fun isJsxSpreadAttribute(node: Node): Boolean - -external fun isJsxExpression(node: Node): Boolean - -external fun isCaseClause(node: Node): Boolean - -external fun isDefaultClause(node: Node): Boolean - -external fun isHeritageClause(node: Node): Boolean - -external fun isCatchClause(node: Node): Boolean - -external fun isPropertyAssignment(node: Node): Boolean - -external fun isShorthandPropertyAssignment(node: Node): Boolean - -external fun isSpreadAssignment(node: Node): Boolean - -external fun isEnumMember(node: Node): Boolean - -external fun isUnparsedPrepend(node: Node): Boolean - -external fun isSourceFile(node: Node): Boolean - -external fun isBundle(node: Node): Boolean - -external fun isUnparsedSource(node: Node): Boolean - -external fun isJSDocTypeExpression(node: Node): Boolean - -external fun isJSDocNameReference(node: Node): Boolean - -external fun isJSDocMemberName(node: Node): Boolean - -external fun isJSDocLink(node: Node): Boolean - -external fun isJSDocLinkCode(node: Node): Boolean - -external fun isJSDocLinkPlain(node: Node): Boolean - -external fun isJSDocAllType(node: Node): Boolean - -external fun isJSDocUnknownType(node: Node): Boolean - -external fun isJSDocNullableType(node: Node): Boolean - -external fun isJSDocNonNullableType(node: Node): Boolean - -external fun isJSDocOptionalType(node: Node): Boolean - -external fun isJSDocFunctionType(node: Node): Boolean - -external fun isJSDocVariadicType(node: Node): Boolean - -external fun isJSDocNamepathType(node: Node): Boolean - -external fun isJSDoc(node: Node): Boolean - -external fun isJSDocTypeLiteral(node: Node): Boolean - -external fun isJSDocSignature(node: Node): Boolean - -external fun isJSDocAugmentsTag(node: Node): Boolean - -external fun isJSDocAuthorTag(node: Node): Boolean - -external fun isJSDocClassTag(node: Node): Boolean - -external fun isJSDocCallbackTag(node: Node): Boolean - -external fun isJSDocPublicTag(node: Node): Boolean - -external fun isJSDocPrivateTag(node: Node): Boolean - -external fun isJSDocProtectedTag(node: Node): Boolean - -external fun isJSDocReadonlyTag(node: Node): Boolean - -external fun isJSDocOverrideTag(node: Node): Boolean - -external fun isJSDocDeprecatedTag(node: Node): Boolean - -external fun isJSDocSeeTag(node: Node): Boolean - -external fun isJSDocEnumTag(node: Node): Boolean - -external fun isJSDocParameterTag(node: Node): Boolean - -external fun isJSDocReturnTag(node: Node): Boolean - -external fun isJSDocThisTag(node: Node): Boolean - -external fun isJSDocTypeTag(node: Node): Boolean - -external fun isJSDocTemplateTag(node: Node): Boolean - -external fun isJSDocTypedefTag(node: Node): Boolean - -external fun isJSDocUnknownTag(node: Node): Boolean - -external fun isJSDocPropertyTag(node: Node): Boolean - -external fun isJSDocImplementsTag(node: Node): Boolean - -external fun setTextRange(range: T, location: TextRange?): T - -external fun forEachChild(node: Node, cbNode: (node: Node) -> T?, cbNodes: (nodes: NodeArray) -> T? = definedExternally): T? - -external fun createSourceFile(fileName: String, sourceText: String, languageVersion: ScriptTarget, setParentNodes: Boolean = definedExternally, scriptKind: ScriptKind = definedExternally): SourceFile - -external fun parseIsolatedEntityName(text: String, languageVersion: ScriptTarget): dynamic /* Identifier? | QualifiedName? */ - -external fun parseJsonText(fileName: String, sourceText: String): JsonSourceFile - -external fun isExternalModule(file: SourceFile): Boolean - -external fun updateSourceFile(sourceFile: SourceFile, newText: String, textChangeRange: TextChangeRange, aggressiveChecks: Boolean = definedExternally): SourceFile - -external fun parseCommandLine(commandLine: Array, readFile: (path: String) -> String? = definedExternally): ParsedCommandLine - -external interface ConfigFileDiagnosticsReporter { - var onUnRecoverableConfigFileDiagnostic: DiagnosticReporter -} - -external interface ParseConfigFileHost : ParseConfigHost, ConfigFileDiagnosticsReporter { - fun getCurrentDirectory(): String -} - -external fun getParsedCommandLineOfConfigFile(configFileName: String, optionsToExtend: CompilerOptions?, host: ParseConfigFileHost, extendedConfigCache: Map = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): ParsedCommandLine? - -external interface `T$25` { - var config: Any? - get() = definedExternally - set(value) = definedExternally - var error: Diagnostic? - get() = definedExternally - set(value) = definedExternally -} - -external fun readConfigFile(fileName: String, readFile: (path: String) -> String?): `T$25` - -external fun parseConfigFileTextToJson(fileName: String, jsonText: String): `T$25` - -external fun readJsonConfigFile(fileName: String, readFile: (path: String) -> String?): TsConfigSourceFile - -external fun convertToObject(sourceFile: JsonSourceFile, errors: Push): Any - -external fun parseJsonConfigFileContent(json: Any, host: ParseConfigHost, basePath: String, existingOptions: CompilerOptions = definedExternally, configFileName: String = definedExternally, resolutionStack: Array = definedExternally, extraFileExtensions: Array = definedExternally, extendedConfigCache: Map = definedExternally, existingWatchOptions: WatchOptions = definedExternally): ParsedCommandLine - -external fun parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: String, existingOptions: CompilerOptions = definedExternally, configFileName: String = definedExternally, resolutionStack: Array = definedExternally, extraFileExtensions: Array = definedExternally, extendedConfigCache: Map = definedExternally, existingWatchOptions: WatchOptions = definedExternally): ParsedCommandLine - -external interface ParsedTsconfig { - var raw: Any - var options: CompilerOptions? - get() = definedExternally - set(value) = definedExternally - var watchOptions: WatchOptions? - get() = definedExternally - set(value) = definedExternally - var typeAcquisition: TypeAcquisition? - get() = definedExternally - set(value) = definedExternally - var extendedConfigPath: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface ExtendedConfigCacheEntry { - var extendedResult: TsConfigSourceFile - var extendedConfig: ParsedTsconfig? -} - -external interface `T$26` { - var options: CompilerOptions - var errors: Array -} - -external fun convertCompilerOptionsFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$26` - -external interface `T$27` { - var options: TypeAcquisition - var errors: Array -} - -external fun convertTypeAcquisitionFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$27` - -external fun getEffectiveTypeRoots(options: CompilerOptions, host: GetEffectiveTypeRootsHost): Array? - -external fun resolveTypeReferenceDirective(typeReferenceDirectiveName: String, containingFile: String?, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference: ResolvedProjectReference = definedExternally, cache: TypeReferenceDirectiveResolutionCache = definedExternally): ResolvedTypeReferenceDirectiveWithFailedLookupLocations - -external fun getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): Array - -external interface TypeReferenceDirectiveResolutionCache : PerDirectoryResolutionCache, PackageJsonInfoCache - -external interface PerDirectoryResolutionCache { - fun getOrCreateCacheForDirectory(directoryName: String, redirectedReference: ResolvedProjectReference = definedExternally): Map - fun clear() - fun update(options: CompilerOptions) -} - -external interface ModuleResolutionCache : PerDirectoryResolutionCache, NonRelativeModuleNameResolutionCache, PackageJsonInfoCache { - fun getPackageJsonInfoCache(): PackageJsonInfoCache -} - -external interface NonRelativeModuleNameResolutionCache : PackageJsonInfoCache { - fun getOrCreateCacheForModuleName(nonRelativeModuleName: String, redirectedReference: ResolvedProjectReference = definedExternally): PerModuleNameCache -} - -external interface PackageJsonInfoCache { - fun clear() -} - -external interface PerModuleNameCache { - fun get(directory: String): ResolvedModuleWithFailedLookupLocations? - fun set(directory: String, result: ResolvedModuleWithFailedLookupLocations) -} - -external fun createModuleResolutionCache(currentDirectory: String, getCanonicalFileName: (s: String) -> String, options: CompilerOptions = definedExternally): ModuleResolutionCache - -external fun createTypeReferenceDirectiveResolutionCache(currentDirectory: String, getCanonicalFileName: (s: String) -> String, options: CompilerOptions = definedExternally, packageJsonInfoCache: PackageJsonInfoCache = definedExternally): TypeReferenceDirectiveResolutionCache - -external fun resolveModuleNameFromCache(moduleName: String, containingFile: String, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations? - -external fun resolveModuleName(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations - -external fun nodeModuleNameResolver(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations - -external fun classicNameResolver(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: NonRelativeModuleNameResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations - -external fun visitNode(node: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T - -external fun visitNode(node: T, visitor: Visitor?): T - -external fun visitNode(node: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T - -external fun visitNode(node: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T? - -external fun visitNode(node: T?, visitor: Visitor?): T? - -external fun visitNode(node: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T? - -external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray - -external fun visitNodes(nodes: NodeArray, visitor: Visitor?): NodeArray - -external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray - -external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray - -external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray? - -external fun visitNodes(nodes: NodeArray?, visitor: Visitor?): NodeArray? - -external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray? - -external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray? - -external fun visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start: Number = definedExternally, ensureUseStrict: Boolean = definedExternally, nodesVisitor: NodesVisitor = definedExternally): NodeArray - -external fun visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor = definedExternally): NodeArray - -external fun visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext): NodeArray - -external fun visitParameterList(nodes: NodeArray?, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor = definedExternally): NodeArray? - -external fun visitParameterList(nodes: NodeArray?, visitor: Visitor, context: TransformationContext): NodeArray? - -external fun visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): dynamic /* FunctionBody */ - -external fun visitFunctionBody(node: Expression, visitor: Visitor, context: TransformationContext): dynamic /* FunctionBody | Expression */ - -external fun visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement - -external fun visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T - -external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext, nodesVisitor: Any = definedExternally, tokenVisitor: Visitor = definedExternally): T? - -external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext): T? - -external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext, nodesVisitor: Any = definedExternally): T? - -external fun getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): String? - -external fun getOutputFileNames(commandLine: ParsedCommandLine, inputFileName: String, ignoreCase: Boolean): Array - -external fun createPrinter(printerOptions: PrinterOptions = definedExternally, handlers: PrintHandlers = definedExternally): Printer - -external fun findConfigFile(searchPath: String, fileExists: (fileName: String) -> Boolean, configName: String = definedExternally): String? - -external fun resolveTripleslashReference(moduleName: String, containingFile: String): String - -external fun createCompilerHost(options: CompilerOptions, setParentNodes: Boolean = definedExternally): CompilerHost - -external fun getPreEmitDiagnostics(program: Program, sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - -external interface FormatDiagnosticsHost { - fun getCurrentDirectory(): String - fun getCanonicalFileName(fileName: String): String - fun getNewLine(): String -} - -external fun formatDiagnostics(diagnostics: Array, host: FormatDiagnosticsHost): String - -external fun formatDiagnostic(diagnostic: Diagnostic, host: FormatDiagnosticsHost): String - -external fun formatDiagnosticsWithColorAndContext(diagnostics: Array, host: FormatDiagnosticsHost): String - -external fun flattenDiagnosticMessageText(diag: String?, newLine: String, indent: Number = definedExternally): String - -external fun flattenDiagnosticMessageText(diag: String?, newLine: String): String - -external fun flattenDiagnosticMessageText(diag: DiagnosticMessageChain?, newLine: String, indent: Number = definedExternally): String - -external fun flattenDiagnosticMessageText(diag: DiagnosticMessageChain?, newLine: String): String - -external fun getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): Array - -external fun createProgram(createProgramOptions: CreateProgramOptions): Program - -external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally, oldProgram: Program = definedExternally, configFileParsingDiagnostics: Array = definedExternally): Program - -external fun createProgram(rootNames: Array, options: CompilerOptions): Program - -external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally): Program - -external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally, oldProgram: Program = definedExternally): Program - -external interface ResolveProjectReferencePathHost { - fun fileExists(fileName: String): Boolean -} - -external fun resolveProjectReferencePath(ref: ProjectReference): String /* String & `T$5` */ - -external fun resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): String /* String & `T$5` */ - -external interface EmitOutput { - var outputFiles: Array - var emitSkipped: Boolean? -} - -external interface OutputFile { - var name: String - var writeByteOrderMark: Boolean? - var text: String -} - -external interface `T$28` { - var result: T - var affected: dynamic /* SourceFile | Program */ - get() = definedExternally - set(value) = definedExternally -} - -external interface BuilderProgramHost { - fun useCaseSensitiveFileNames(): Boolean - var createHash: ((data: String) -> String)? - get() = definedExternally - set(value) = definedExternally - var writeFile: WriteFileCallback? - get() = definedExternally - set(value) = definedExternally -} - -external interface BuilderProgram { - fun getProgram(): Program - fun getCompilerOptions(): CompilerOptions - fun getSourceFile(fileName: String): SourceFile? - fun getSourceFiles(): Array - fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getConfigFileParsingDiagnostics(): Array - fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getDeclarationDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getAllDependencies(sourceFile: SourceFile): Array - fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult - fun getCurrentDirectory(): String -} - -external interface SemanticDiagnosticsBuilderProgram : BuilderProgram { - fun getSemanticDiagnosticsOfNextAffectedFile(cancellationToken: CancellationToken = definedExternally, ignoreSourceFile: (sourceFile: SourceFile) -> Boolean = definedExternally): `T$28`>? -} - -external interface EmitAndSemanticDiagnosticsBuilderProgram : SemanticDiagnosticsBuilderProgram { - fun emitNextAffectedFile(writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): `T$28`? -} - -external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): BuilderProgram - -external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost): BuilderProgram - -external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram: BuilderProgram = definedExternally): BuilderProgram - -external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): BuilderProgram - -external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?): BuilderProgram - -external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): BuilderProgram - -external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally): BuilderProgram - -external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): BuilderProgram - -external interface ReadBuildProgramHost { - fun useCaseSensitiveFileNames(): Boolean - fun getCurrentDirectory(): String - fun readFile(fileName: String): String? -} - -external fun readBuilderProgram(compilerOptions: CompilerOptions, host: ReadBuildProgramHost): EmitAndSemanticDiagnosticsBuilderProgram? - -external fun createIncrementalCompilerHost(options: CompilerOptions, system: System = definedExternally): CompilerHost - -external interface IncrementalProgramOptions { - var rootNames: Array - var options: CompilerOptions - var configFileParsingDiagnostics: Array? - get() = definedExternally - set(value) = definedExternally - var projectReferences: Array? - get() = definedExternally - set(value) = definedExternally - var host: CompilerHost? - get() = definedExternally - set(value) = definedExternally -// var createProgram: CreateProgram? -// get() = definedExternally -// set(value) = definedExternally -} - -external fun createIncrementalProgram(__0: IncrementalProgramOptions): T - -external interface WatchHost { - val onWatchStatusChange: ((diagnostic: Diagnostic, newLine: String, options: CompilerOptions, errorCount: Number) -> Unit)? - fun watchFile(path: String, callback: FileWatcherCallback, pollingInterval: Number = definedExternally, options: CompilerOptions = definedExternally): FileWatcher - fun watchDirectory(path: String, callback: DirectoryWatcherCallback, recursive: Boolean = definedExternally, options: CompilerOptions = definedExternally): FileWatcher - val setTimeout: ((callback: (args: Any) -> Unit, ms: Number, args: Any) -> Any)? - val clearTimeout: ((timeoutId: Any) -> Unit)? -} - -//external interface ProgramHost { -// var createProgram: CreateProgram -// fun useCaseSensitiveFileNames(): Boolean -// fun getNewLine(): String -// fun getCurrentDirectory(): String -// fun getDefaultLibFileName(options: CompilerOptions): String -// val getDefaultLibLocation: (() -> String)? -// val createHash: ((data: String) -> String)? -// fun fileExists(path: String): Boolean -// fun readFile(path: String, encoding: String = definedExternally): String? -// val directoryExists: ((path: String) -> Boolean)? -// val getDirectories: ((path: String) -> Array)? -// val readDirectory: ((path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array)? -// val realpath: ((path: String) -> String)? -// val trace: ((s: String) -> Unit)? -// val getEnvironmentVariable: ((name: String) -> String?)? -// val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? -// val resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? -//} - -//external interface WatchCompilerHost : ProgramHost, WatchHost { -// val useSourceOfProjectReferenceRedirect: (() -> Boolean)? -// val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? -// val afterProgramCreate: ((program: T) -> Unit)? -//} - -//external interface WatchCompilerHostOfFilesAndCompilerOptions : WatchCompilerHost { -// var rootFiles: Array -// var options: CompilerOptions -// var watchOptions: WatchOptions? -// get() = definedExternally -// set(value) = definedExternally -// var projectReferences: Array? -// get() = definedExternally -// set(value) = definedExternally -//} -// -//external interface WatchCompilerHostOfConfigFile : WatchCompilerHost, ConfigFileDiagnosticsReporter { -// var configFileName: String -// var optionsToExtend: CompilerOptions? -// get() = definedExternally -// set(value) = definedExternally -// var watchOptionsToExtend: WatchOptions? -// get() = definedExternally -// set(value) = definedExternally -// var extraFileExtensions: Array? -// get() = definedExternally -// set(value) = definedExternally -// override var readDirectory: (path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array -//} - -external interface Watch { - fun getProgram(): T - fun close() -} - -external interface WatchOfConfigFile : Watch - -external interface WatchOfFilesAndCompilerOptions : Watch { - fun updateRootFileNames(fileNames: Array) -} - -//external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): WatchCompilerHostOfConfigFile -//external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System): WatchCompilerHostOfConfigFile -//external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally): WatchCompilerHostOfConfigFile -//external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally): WatchCompilerHostOfConfigFile -//external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): WatchCompilerHostOfConfigFile -//external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally): WatchCompilerHostOfConfigFile -// -//external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, projectReferences: Array = definedExternally, watchOptions: WatchOptions = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions -//external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System): WatchCompilerHostOfFilesAndCompilerOptions -//external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions -//external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions -//external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions -//external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, projectReferences: Array = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions - -//external fun createWatchProgram(host: WatchCompilerHostOfFilesAndCompilerOptions): WatchOfFilesAndCompilerOptions -// -//external fun createWatchProgram(host: WatchCompilerHostOfConfigFile): WatchOfConfigFile - -external interface BuildOptions { - var dry: Boolean? - get() = definedExternally - set(value) = definedExternally - var force: Boolean? - get() = definedExternally - set(value) = definedExternally - var verbose: Boolean? - get() = definedExternally - set(value) = definedExternally - var incremental: Boolean? - get() = definedExternally - set(value) = definedExternally - var assumeChangesOnlyAffectDirectDependencies: Boolean? - get() = definedExternally - set(value) = definedExternally - var traceResolution: Boolean? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ - @nativeSetter - operator fun set(option: String, value: String?) - @nativeSetter - operator fun set(option: String, value: Number?) - @nativeSetter - operator fun set(option: String, value: Boolean?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: MapLike>?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) -} - -//external interface SolutionBuilderHostBase : ProgramHost { -// val createDirectory: ((path: String) -> Unit)? -// val writeFile: ((path: String, data: String, writeByteOrderMark: Boolean) -> Unit)? -// var getCustomTransformers: ((project: String) -> CustomTransformers?)? -// get() = definedExternally -// set(value) = definedExternally -// fun getModifiedTime(fileName: String): Date? -// fun setModifiedTime(fileName: String, date: Date) -// fun deleteFile(fileName: String) -// val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? -// var reportDiagnostic: DiagnosticReporter -// var reportSolutionBuilderStatus: DiagnosticReporter -// val afterProgramEmitAndDiagnostics: ((program: T) -> Unit)? -//} - -//external interface SolutionBuilderHost : SolutionBuilderHostBase { -// var reportErrorSummary: ReportEmitErrorSummary? -// get() = definedExternally -// set(value) = definedExternally -//} - -//external interface SolutionBuilderWithWatchHost : SolutionBuilderHostBase, WatchHost - -external interface SolutionBuilder { - fun build(project: String = definedExternally, cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, getCustomTransformers: (project: String) -> CustomTransformers = definedExternally): ExitStatus - fun clean(project: String = definedExternally): ExitStatus - fun buildReferences(project: String, cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, getCustomTransformers: (project: String) -> CustomTransformers = definedExternally): ExitStatus - fun cleanReferences(project: String = definedExternally): ExitStatus - fun getNextInvalidatedProject(cancellationToken: CancellationToken = definedExternally): dynamic /* UpdateOutputFileStampsProject? | BuildInvalidedProject? | UpdateBundleProject? */ -} - -external fun createBuilderStatusReporter(system: System, pretty: Boolean = definedExternally): DiagnosticReporter - -//external fun createSolutionBuilderHost(system: System = definedExternally, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportSolutionBuilderStatus: DiagnosticReporter = definedExternally, reportErrorSummary: ReportEmitErrorSummary = definedExternally): SolutionBuilderHost -// -//external fun createSolutionBuilderWithWatchHost(system: System = definedExternally, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportSolutionBuilderStatus: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): SolutionBuilderWithWatchHost -// -//external fun createSolutionBuilder(host: SolutionBuilderHost, rootNames: Array, defaultOptions: BuildOptions): SolutionBuilder - -//external fun createSolutionBuilderWithWatch(host: SolutionBuilderWithWatchHost, rootNames: Array, defaultOptions: BuildOptions, baseWatchOptions: WatchOptions = definedExternally): SolutionBuilder - -external enum class InvalidatedProjectKind { - Build /* = 0 */, - UpdateBundle /* = 1 */, - UpdateOutputFileStamps /* = 2 */ -} - -external interface InvalidatedProjectBase { - val kind: InvalidatedProjectKind - val project: String /* String & `T$5` */ - fun done(cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, customTransformers: CustomTransformers = definedExternally): ExitStatus - fun getCompilerOptions(): CompilerOptions - fun getCurrentDirectory(): String -} - -external interface UpdateOutputFileStampsProject : InvalidatedProjectBase { - fun updateOutputFileStatmps() -} - -external interface BuildInvalidedProject : InvalidatedProjectBase { - fun getBuilderProgram(): T? - fun getProgram(): Program? - fun getSourceFile(fileName: String): SourceFile? - fun getSourceFiles(): Array - fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getConfigFileParsingDiagnostics(): Array - fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getAllDependencies(sourceFile: SourceFile): Array - fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getSemanticDiagnosticsOfNextAffectedFile(cancellationToken: CancellationToken = definedExternally, ignoreSourceFile: (sourceFile: SourceFile) -> Boolean = definedExternally): `T$28`>? - fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult? -} - -external interface UpdateBundleProject : InvalidatedProjectBase { - fun emit(writeFile: WriteFileCallback = definedExternally, customTransformers: CustomTransformers = definedExternally): dynamic /* EmitResult? | BuildInvalidedProject? */ -} - -external interface SourceFileLike { - fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter -} - -external interface IScriptSnapshot { - fun getText(start: Number, end: Number): String - fun getLength(): Number - fun getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange? - val dispose: (() -> Unit)? -} - -external interface PreProcessedFileInfo { - var referencedFiles: Array - var typeReferenceDirectives: Array - var libReferenceDirectives: Array - var importedFiles: Array - var ambientExternalModules: Array? - get() = definedExternally - set(value) = definedExternally - var isLibFile: Boolean? -} - -external interface HostCancellationToken { - fun isCancellationRequested(): Boolean -} - -external interface InstallPackageOptions { - var fileName: String /* String & `T$3` */ - var packageName: String -} - -external interface PerformanceEvent { - var kind: String /* "UpdateGraph" | "CreatePackageJsonAutoImportProvider" */ - var durationMs: Number -} - -external enum class LanguageServiceMode { - Semantic /* = 0 */, - PartialSemantic /* = 1 */, - Syntactic /* = 2 */ -} - -external interface IncompleteCompletionsCache { - fun get(): CompletionInfo? - fun set(response: CompletionInfo) - fun clear() -} - -external interface LanguageServiceHost : GetEffectiveTypeRootsHost { - fun getCompilationSettings(): CompilerOptions - val getNewLine: (() -> String)? - val getProjectVersion: (() -> String)? - fun getScriptFileNames(): Array - val getScriptKind: ((fileName: String) -> ScriptKind)? - fun getScriptVersion(fileName: String): String - fun getScriptSnapshot(fileName: String): IScriptSnapshot? - val getProjectReferences: (() -> Array?)? - val getLocalizedDiagnosticMessages: (() -> Any)? - val getCancellationToken: (() -> HostCancellationToken)? - override var getCurrentDirectory: () -> String - fun getDefaultLibFileName(options: CompilerOptions): String - val log: ((s: String) -> Unit)? - val trace: ((s: String) -> Unit)? - val error: ((s: String) -> Unit)? - val useCaseSensitiveFileNames: (() -> Boolean)? - val readDirectory: ((path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array)? - val readFile: ((path: String, encoding: String) -> String?)? - val realpath: ((path: String) -> String)? - val fileExists: ((path: String) -> Boolean)? - val getTypeRootsVersion: (() -> Number)? - val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val getResolvedModuleWithFailedLookupLocationsFromCache: ((modulename: String, containingFile: String) -> ResolvedModuleWithFailedLookupLocations?)? - val resolveTypeReferenceDirectives: ((typeDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val getDirectories: ((directoryName: String) -> Array)? - val getCustomTransformers: (() -> CustomTransformers?)? - val isKnownTypesPackageName: ((name: String) -> Boolean)? - val installPackage: ((options: InstallPackageOptions) -> Promise)? - val writeFile: ((fileName: String, content: String) -> Unit)? - val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? -} - -external enum class SemanticClassificationFormat { - Original /* = "original" */, - TwentyTwenty /* = "2020" */ -} - -external interface LanguageService { - fun cleanupSemanticCache() - fun getSyntacticDiagnostics(fileName: String): Array - fun getSemanticDiagnostics(fileName: String): Array - fun getSuggestionDiagnostics(fileName: String): Array - fun getCompilerOptionsDiagnostics(): Array - fun getSyntacticClassifications(fileName: String, span: TextSpan): Array - fun getSyntacticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ - fun getSemanticClassifications(fileName: String, span: TextSpan): Array - fun getSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ - fun getEncodedSyntacticClassifications(fileName: String, span: TextSpan): Classifications - fun getEncodedSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat = definedExternally): Classifications - fun getCompletionsAtPosition(fileName: String, position: Number, options: GetCompletionsAtPositionOptions?): CompletionInfo /* CompletionInfo & `T$12` */ - fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeOptions?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? - fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeSettings?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? - fun getCompletionEntrySymbol(fileName: String, position: Number, name: String, source: String?): Symbol? - fun getQuickInfoAtPosition(fileName: String, position: Number): QuickInfo? - fun getNameOrDottedNameSpan(fileName: String, startPos: Number, endPos: Number): TextSpan? - fun getBreakpointStatementAtPosition(fileName: String, position: Number): TextSpan? - fun getSignatureHelpItems(fileName: String, position: Number, options: SignatureHelpItemsOptions?): SignatureHelpItems? - fun getRenameInfo(fileName: String, position: Number, options: RenameInfoOptions = definedExternally): dynamic /* RenameInfoSuccess | RenameInfoFailure */ - fun findRenameLocations(fileName: String, position: Number, findInStrings: Boolean, findInComments: Boolean, providePrefixAndSuffixTextForRename: Boolean = definedExternally): Array? - fun getSmartSelectionRange(fileName: String, position: Number): SelectionRange - fun getDefinitionAtPosition(fileName: String, position: Number): Array? - fun getDefinitionAndBoundSpan(fileName: String, position: Number): DefinitionInfoAndBoundSpan? - fun getTypeDefinitionAtPosition(fileName: String, position: Number): Array? - fun getImplementationAtPosition(fileName: String, position: Number): Array? - fun getReferencesAtPosition(fileName: String, position: Number): Array? - fun findReferences(fileName: String, position: Number): Array? - fun getDocumentHighlights(fileName: String, position: Number, filesToSearch: Array): Array? - fun getFileReferences(fileName: String): Array - fun getOccurrencesAtPosition(fileName: String, position: Number): Array? - fun getNavigateToItems(searchValue: String, maxResultCount: Number = definedExternally, fileName: String = definedExternally, excludeDtsFiles: Boolean = definedExternally): Array - fun getNavigationBarItems(fileName: String): Array - fun getNavigationTree(fileName: String): NavigationTree - fun prepareCallHierarchy(fileName: String, position: Number): dynamic /* CallHierarchyItem? | Array? */ - fun provideCallHierarchyIncomingCalls(fileName: String, position: Number): Array - fun provideCallHierarchyOutgoingCalls(fileName: String, position: Number): Array - fun provideInlayHints(fileName: String, span: TextSpan, preferences: UserPreferences?): Array - fun getOutliningSpans(fileName: String): Array - fun getTodoComments(fileName: String, descriptors: Array): Array - fun getBraceMatchingAtPosition(fileName: String, position: Number): Array - fun getIndentationAtPosition(fileName: String, position: Number, options: EditorOptions): Number - fun getIndentationAtPosition(fileName: String, position: Number, options: EditorSettings): Number - fun getFormattingEditsForRange(fileName: String, start: Number, end: Number, options: FormatCodeOptions): Array - fun getFormattingEditsForRange(fileName: String, start: Number, end: Number, options: FormatCodeSettings): Array - fun getFormattingEditsForDocument(fileName: String, options: FormatCodeOptions): Array - fun getFormattingEditsForDocument(fileName: String, options: FormatCodeSettings): Array - fun getFormattingEditsAfterKeystroke(fileName: String, position: Number, key: String, options: FormatCodeOptions): Array - fun getFormattingEditsAfterKeystroke(fileName: String, position: Number, key: String, options: FormatCodeSettings): Array - fun getDocCommentTemplateAtPosition(fileName: String, position: Number, options: DocCommentTemplateOptions = definedExternally): TextInsertion? - fun isValidBraceCompletionAtPosition(fileName: String, position: Number, openingBrace: Number): Boolean - fun getJsxClosingTagAtPosition(fileName: String, position: Number): JsxClosingTagInfo? - fun getSpanOfEnclosingComment(fileName: String, position: Number, onlyMultiLine: Boolean): TextSpan? - val toLineColumnOffset: ((fileName: String, position: Number) -> LineAndCharacter)? - fun getCodeFixesAtPosition(fileName: String, start: Number, end: Number, errorCodes: Array, formatOptions: FormatCodeSettings, preferences: UserPreferences): Array - fun getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: Any, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions - fun applyCodeActionCommand(action: CodeActionCommand, formatSettings: FormatCodeSettings = definedExternally): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(action: CodeActionCommand): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(action: Array, formatSettings: FormatCodeSettings = definedExternally): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(action: Array): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(fileName: String, action: CodeActionCommand): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(fileName: String, action: Array): dynamic /* Promise | Promise */ - fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally, kind: String = definedExternally): Array - fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?): Array - fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally): Array - fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally, kind: String = definedExternally): Array - fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?): Array - fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally): Array - fun getEditsForRefactor(fileName: String, formatOptions: FormatCodeSettings, positionOrRange: Number, refactorName: String, actionName: String, preferences: UserPreferences?): RefactorEditInfo? - fun getEditsForRefactor(fileName: String, formatOptions: FormatCodeSettings, positionOrRange: TextRange, refactorName: String, actionName: String, preferences: UserPreferences?): RefactorEditInfo? - fun organizeImports(args: OrganizeImportsArgs, formatOptions: FormatCodeSettings, preferences: UserPreferences?): Array - fun getEditsForFileRename(oldFilePath: String, newFilePath: String, formatOptions: FormatCodeSettings, preferences: UserPreferences?): Array - fun getEmitOutput(fileName: String, emitOnlyDtsFiles: Boolean = definedExternally, forceDtsEmit: Boolean = definedExternally): EmitOutput - fun getProgram(): Program? - fun toggleLineComment(fileName: String, textRange: TextRange): Array - fun toggleMultilineComment(fileName: String, textRange: TextRange): Array - fun commentSelection(fileName: String, textRange: TextRange): Array - fun uncommentSelection(fileName: String, textRange: TextRange): Array - fun dispose() -} - -external interface JsxClosingTagInfo { - val newText: String -} - -external interface CombinedCodeFixScope { - var type: String /* "file" */ - var fileName: String -} - -external interface OrganizeImportsArgs : CombinedCodeFixScope { - var skipDestructiveCodeActions: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external enum class CompletionTriggerKind { - Invoked /* = 1 */, - TriggerCharacter /* = 2 */, - TriggerForIncompleteCompletions /* = 3 */ -} - -external interface GetCompletionsAtPositionOptions : UserPreferences { - var triggerCharacter: String? /* "." | """ | "'" | "`" | "/" | "@" | "<" | "#" | " " */ - get() = definedExternally - set(value) = definedExternally - var triggerKind: CompletionTriggerKind? - get() = definedExternally - set(value) = definedExternally - var includeExternalModuleExports: Boolean? - get() = definedExternally - set(value) = definedExternally - var includeInsertTextCompletions: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface InlayHintsOptions : UserPreferences { - val includeInlayParameterNameHints: String? /* "none" | "literals" | "all" */ - get() = definedExternally - val includeInlayParameterNameHintsWhenArgumentMatchesName: Boolean? - get() = definedExternally - val includeInlayFunctionParameterTypeHints: Boolean? - get() = definedExternally - val includeInlayVariableTypeHints: Boolean? - get() = definedExternally - val includeInlayPropertyDeclarationTypeHints: Boolean? - get() = definedExternally - val includeInlayFunctionLikeReturnTypeHints: Boolean? - get() = definedExternally - val includeInlayEnumMemberValueHints: Boolean? - get() = definedExternally -} - -external interface SignatureHelpItemsOptions { - var triggerReason: dynamic /* SignatureHelpInvokedReason? | SignatureHelpCharacterTypedReason? | SignatureHelpRetriggeredReason? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureHelpInvokedReason { - var kind: String /* "invoked" */ - var triggerCharacter: Any? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureHelpCharacterTypedReason { - var kind: String /* "characterTyped" */ - var triggerCharacter: String /* "," | "(" | "<" */ -} - -external interface SignatureHelpRetriggeredReason { - var kind: String /* "retrigger" */ - var triggerCharacter: String? /* "," | "(" | "<" | ")" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ApplyCodeActionCommandResult { - var successMessage: String -} - -external interface Classifications { - var spans: Array - var endOfLineState: EndOfLineState -} - -external interface ClassifiedSpan { - var textSpan: TextSpan - var classificationType: ClassificationTypeNames -} - -external interface ClassifiedSpan2020 { - var textSpan: TextSpan - var classificationType: Number -} - -external interface NavigationBarItem { - var text: String - var kind: ScriptElementKind - var kindModifiers: String - var spans: Array - var childItems: Array - var indent: Number - var bolded: Boolean? - var grayed: Boolean? -} - -external interface NavigationTree { - var text: String - var kind: ScriptElementKind - var kindModifiers: String - var spans: Array - var nameSpan: TextSpan? - var childItems: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface CallHierarchyItem { - var name: String - var kind: ScriptElementKind - var kindModifiers: String? - get() = definedExternally - set(value) = definedExternally - var file: String - var span: TextSpan - var selectionSpan: TextSpan - var containerName: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface CallHierarchyIncomingCall { - var from: CallHierarchyItem - var fromSpans: Array -} - -external interface CallHierarchyOutgoingCall { - var to: CallHierarchyItem - var fromSpans: Array -} - -external enum class InlayHintKind { - Type /* = "Type" */, - Parameter /* = "Parameter" */, - Enum /* = "Enum" */ -} - -external interface InlayHint { - var text: String - var position: Number - var kind: InlayHintKind - var whitespaceBefore: Boolean? - get() = definedExternally - set(value) = definedExternally - var whitespaceAfter: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TodoCommentDescriptor { - var text: String - var priority: Number -} - -external interface TodoComment { - var descriptor: TodoCommentDescriptor - var message: String - var position: Number -} - -external interface TextChange { - var span: TextSpan - var newText: String -} - -external interface FileTextChanges { - var fileName: String - var textChanges: Array - var isNewFile: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface CodeAction { - var description: String - var changes: Array - var commands: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface CodeFixAction : CodeAction { - var fixName: String - var fixId: Any? - get() = definedExternally - set(value) = definedExternally - var fixAllDescription: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface CombinedCodeActions { - var changes: Array - var commands: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface InstallPackageAction - -external interface ApplicableRefactorInfo { - var name: String - var description: String - var inlineable: Boolean? - get() = definedExternally - set(value) = definedExternally - var actions: Array -} - -external interface RefactorActionInfo { - var name: String - var description: String - var notApplicableReason: String? - get() = definedExternally - set(value) = definedExternally - var kind: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface RefactorEditInfo { - var edits: Array - var renameFilename: String? - get() = definedExternally - set(value) = definedExternally - var renameLocation: Number? - get() = definedExternally - set(value) = definedExternally - var commands: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface TextInsertion { - var newText: String - var caretOffset: Number -} - -external interface DocumentSpan { - var textSpan: TextSpan - var fileName: String - var originalTextSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var originalFileName: String? - get() = definedExternally - set(value) = definedExternally - var contextSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var originalContextSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally -} - -external interface RenameLocation : DocumentSpan { - val prefixText: String? - get() = definedExternally - val suffixText: String? - get() = definedExternally -} - -external interface ReferenceEntry : DocumentSpan { - var isWriteAccess: Boolean? - var isDefinition: Boolean? - var isInString: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ImplementationLocation : DocumentSpan { - var kind: ScriptElementKind - var displayParts: Array -} - -external enum class HighlightSpanKind { - none /* = "none" */, - definition /* = "definition" */, - reference /* = "reference" */, - writtenReference /* = "writtenReference" */ -} - -external interface HighlightSpan { - var fileName: String? - get() = definedExternally - set(value) = definedExternally - var isInString: Boolean? - get() = definedExternally - set(value) = definedExternally - var textSpan: TextSpan - var contextSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var kind: HighlightSpanKind -} - -external interface NavigateToItem { - var name: String - var kind: ScriptElementKind - var kindModifiers: String - var matchKind: String /* "exact" | "prefix" | "substring" | "camelCase" */ - var isCaseSensitive: Boolean? - var fileName: String - var textSpan: TextSpan - var containerName: String - var containerKind: ScriptElementKind -} - -external enum class IndentStyle { - None /* = 0 */, - Block /* = 1 */, - Smart /* = 2 */ -} - -external enum class SemicolonPreference { - Ignore /* = "ignore" */, - Insert /* = "insert" */, - Remove /* = "remove" */ -} - -external interface EditorOptions { - var BaseIndentSize: Number? - get() = definedExternally - set(value) = definedExternally - var IndentSize: Number - var TabSize: Number - var NewLineCharacter: String - var ConvertTabsToSpaces: Boolean? - var IndentStyle: IndentStyle -} - -external interface EditorSettings { - var baseIndentSize: Number? - get() = definedExternally - set(value) = definedExternally - var indentSize: Number? - get() = definedExternally - set(value) = definedExternally - var tabSize: Number? - get() = definedExternally - set(value) = definedExternally - var newLineCharacter: String? - get() = definedExternally - set(value) = definedExternally - var convertTabsToSpaces: Boolean? - get() = definedExternally - set(value) = definedExternally - var indentStyle: IndentStyle? - get() = definedExternally - set(value) = definedExternally - var trimTrailingWhitespace: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface FormatCodeOptions : EditorOptions { - var InsertSpaceAfterCommaDelimiter: Boolean? - var InsertSpaceAfterSemicolonInForStatements: Boolean? - var InsertSpaceBeforeAndAfterBinaryOperators: Boolean? - var InsertSpaceAfterConstructor: Boolean? - get() = definedExternally - set(value) = definedExternally - var InsertSpaceAfterKeywordsInControlFlowStatements: Boolean? - var InsertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean? - var InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean? - var InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean? - var InsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: Boolean? - get() = definedExternally - set(value) = definedExternally - var InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean? - var InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: Boolean? - get() = definedExternally - set(value) = definedExternally - var InsertSpaceAfterTypeAssertion: Boolean? - get() = definedExternally - set(value) = definedExternally - var InsertSpaceBeforeFunctionParenthesis: Boolean? - get() = definedExternally - set(value) = definedExternally - var PlaceOpenBraceOnNewLineForFunctions: Boolean? - var PlaceOpenBraceOnNewLineForControlBlocks: Boolean? - var insertSpaceBeforeTypeAnnotation: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface FormatCodeSettings : EditorSettings { - val insertSpaceAfterCommaDelimiter: Boolean? - get() = definedExternally - val insertSpaceAfterSemicolonInForStatements: Boolean? - get() = definedExternally - val insertSpaceBeforeAndAfterBinaryOperators: Boolean? - get() = definedExternally - val insertSpaceAfterConstructor: Boolean? - get() = definedExternally - val insertSpaceAfterKeywordsInControlFlowStatements: Boolean? - get() = definedExternally - val insertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingEmptyBraces: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean? - get() = definedExternally - val insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: Boolean? - get() = definedExternally - val insertSpaceAfterTypeAssertion: Boolean? - get() = definedExternally - val insertSpaceBeforeFunctionParenthesis: Boolean? - get() = definedExternally - val placeOpenBraceOnNewLineForFunctions: Boolean? - get() = definedExternally - val placeOpenBraceOnNewLineForControlBlocks: Boolean? - get() = definedExternally - val insertSpaceBeforeTypeAnnotation: Boolean? - get() = definedExternally - val indentMultiLineObjectLiteralBeginningOnBlankLine: Boolean? - get() = definedExternally - val semicolons: SemicolonPreference? - get() = definedExternally -} - -external fun getDefaultFormatCodeSettings(newLineCharacter: String = definedExternally): FormatCodeSettings - -external interface DefinitionInfo : DocumentSpan { - var kind: ScriptElementKind - var name: String - var containerKind: ScriptElementKind - var containerName: String - var unverified: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface DefinitionInfoAndBoundSpan { - var definitions: Array? - get() = definedExternally - set(value) = definedExternally - var textSpan: TextSpan -} - -external interface ReferencedSymbolDefinitionInfo : DefinitionInfo { - var displayParts: Array -} - -external interface ReferencedSymbol { - var definition: ReferencedSymbolDefinitionInfo - var references: Array -} - -external enum class SymbolDisplayPartKind { - aliasName /* = 0 */, - className /* = 1 */, - enumName /* = 2 */, - fieldName /* = 3 */, - interfaceName /* = 4 */, - keyword /* = 5 */, - lineBreak /* = 6 */, - numericLiteral /* = 7 */, - stringLiteral /* = 8 */, - localName /* = 9 */, - methodName /* = 10 */, - moduleName /* = 11 */, - operator /* = 12 */, - parameterName /* = 13 */, - propertyName /* = 14 */, - punctuation /* = 15 */, - space /* = 16 */, - text /* = 17 */, - typeParameterName /* = 18 */, - enumMemberName /* = 19 */, - functionName /* = 20 */, - regularExpressionLiteral /* = 21 */, - link /* = 22 */, - linkName /* = 23 */, - linkText /* = 24 */ -} - -external interface SymbolDisplayPart { - var text: String - var kind: String -} - -external interface JSDocLinkDisplayPart : SymbolDisplayPart { - var target: DocumentSpan -} - -external interface JSDocTagInfo { - var name: String - var text: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface QuickInfo { - var kind: ScriptElementKind - var kindModifiers: String - var textSpan: TextSpan - var displayParts: Array? - get() = definedExternally - set(value) = definedExternally - var documentation: Array? - get() = definedExternally - set(value) = definedExternally - var tags: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface RenameInfoSuccess { - var canRename: Boolean? - var fileToRename: String? - get() = definedExternally - set(value) = definedExternally - var displayName: String - var fullDisplayName: String - var kind: ScriptElementKind - var kindModifiers: String - var triggerSpan: TextSpan -} - -external interface RenameInfoFailure { - var canRename: Boolean? - var localizedErrorMessage: String -} - -external interface RenameInfoOptions { - val allowRenameOfImportPath: Boolean? - get() = definedExternally -} - -external interface DocCommentTemplateOptions { - val generateReturnInDocTemplate: Boolean? - get() = definedExternally -} - -external interface SignatureHelpParameter { - var name: String - var documentation: Array - var displayParts: Array - var isOptional: Boolean? - var isRest: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface SelectionRange { - var textSpan: TextSpan - var parent: SelectionRange? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureHelpItem { - var isVariadic: Boolean? - var prefixDisplayParts: Array - var suffixDisplayParts: Array - var separatorDisplayParts: Array - var parameters: Array - var documentation: Array - var tags: Array -} - -external interface SignatureHelpItems { - var items: Array - var applicableSpan: TextSpan - var selectedItemIndex: Number - var argumentIndex: Number - var argumentCount: Number -} - -external interface CompletionInfo { - var isGlobalCompletion: Boolean? - var isMemberCompletion: Boolean? - var optionalReplacementSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var isNewIdentifierLocation: Boolean? - var isIncomplete: Boolean? - get() = definedExternally - set(value) = definedExternally - var entries: Array -} - -external interface CompletionEntryData { - var fileName: String? - get() = definedExternally - set(value) = definedExternally - var ambientModuleName: String? - get() = definedExternally - set(value) = definedExternally - var isPackageJsonImport: Boolean? - get() = definedExternally - set(value) = definedExternally - var exportName: String - var moduleSpecifier: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface CompletionEntry { - var name: String - var kind: ScriptElementKind - var kindModifiers: String? - get() = definedExternally - set(value) = definedExternally - var sortText: String - var insertText: String? - get() = definedExternally - set(value) = definedExternally - var isSnippet: Boolean? - get() = definedExternally - set(value) = definedExternally - var replacementSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var hasAction: Boolean? - get() = definedExternally - set(value) = definedExternally - var source: String? - get() = definedExternally - set(value) = definedExternally - var sourceDisplay: Array? - get() = definedExternally - set(value) = definedExternally - var isRecommended: Boolean? - get() = definedExternally - set(value) = definedExternally - var isFromUncheckedFile: Boolean? - get() = definedExternally - set(value) = definedExternally - var isPackageJsonImport: Boolean? - get() = definedExternally - set(value) = definedExternally - var isImportStatementCompletion: Boolean? - get() = definedExternally - set(value) = definedExternally - var data: CompletionEntryData? - get() = definedExternally - set(value) = definedExternally -} - -external interface CompletionEntryDetails { - var name: String - var kind: ScriptElementKind - var kindModifiers: String - var displayParts: Array - var documentation: Array? - get() = definedExternally - set(value) = definedExternally - var tags: Array? - get() = definedExternally - set(value) = definedExternally - var codeActions: Array? - get() = definedExternally - set(value) = definedExternally - var source: Array? - get() = definedExternally - set(value) = definedExternally - var sourceDisplay: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface OutliningSpan { - var textSpan: TextSpan - var hintSpan: TextSpan - var bannerText: String - var autoCollapse: Boolean? - var kind: OutliningSpanKind -} - -external enum class OutliningSpanKind { - Comment /* = "comment" */, - Region /* = "region" */, - Code /* = "code" */, - Imports /* = "imports" */ -} - -external enum class OutputFileType { - JavaScript /* = 0 */, - SourceMap /* = 1 */, - Declaration /* = 2 */ -} - -external enum class EndOfLineState { - None /* = 0 */, - InMultiLineCommentTrivia /* = 1 */, - InSingleQuoteStringLiteral /* = 2 */, - InDoubleQuoteStringLiteral /* = 3 */, - InTemplateHeadOrNoSubstitutionTemplate /* = 4 */, - InTemplateMiddleOrTail /* = 5 */, - InTemplateSubstitutionPosition /* = 6 */ -} - -external enum class TokenClass { - Punctuation /* = 0 */, - Keyword /* = 1 */, - Operator /* = 2 */, - Comment /* = 3 */, - Whitespace /* = 4 */, - Identifier /* = 5 */, - NumberLiteral /* = 6 */, - BigIntLiteral /* = 7 */, - StringLiteral /* = 8 */, - RegExpLiteral /* = 9 */ -} - -external interface ClassificationResult { - var finalLexState: EndOfLineState - var entries: Array -} - -external interface ClassificationInfo { - var length: Number - var classification: TokenClass -} - -external interface Classifier { - fun getClassificationsForLine(text: String, lexState: EndOfLineState, syntacticClassifierAbsent: Boolean): ClassificationResult - fun getEncodedLexicalClassifications(text: String, endOfLineState: EndOfLineState, syntacticClassifierAbsent: Boolean): Classifications -} - -external enum class ScriptElementKind { - unknown /* = "" */, - warning /* = "warning" */, - keyword /* = "keyword" */, - scriptElement /* = "script" */, - moduleElement /* = "module" */, - classElement /* = "class" */, - localClassElement /* = "local class" */, - interfaceElement /* = "interface" */, - typeElement /* = "type" */, - enumElement /* = "enum" */, - enumMemberElement /* = "enum member" */, - variableElement /* = "var" */, - localVariableElement /* = "local var" */, - functionElement /* = "function" */, - localFunctionElement /* = "local function" */, - memberFunctionElement /* = "method" */, - memberGetAccessorElement /* = "getter" */, - memberSetAccessorElement /* = "setter" */, - memberVariableElement /* = "property" */, - constructorImplementationElement /* = "constructor" */, - callSignatureElement /* = "call" */, - indexSignatureElement /* = "index" */, - constructSignatureElement /* = "construct" */, - parameterElement /* = "parameter" */, - typeParameterElement /* = "type parameter" */, - primitiveType /* = "primitive type" */, - label /* = "label" */, - alias /* = "alias" */, - constElement /* = "const" */, - letElement /* = "let" */, - directory /* = "directory" */, - externalModuleName /* = "external module name" */, - jsxAttribute /* = "JSX attribute" */, - string /* = "string" */, - link /* = "link" */, - linkName /* = "link name" */, - linkText /* = "link text" */ -} - -external enum class ScriptElementKindModifier { - none /* = "" */, - publicMemberModifier /* = "public" */, - privateMemberModifier /* = "private" */, - protectedMemberModifier /* = "protected" */, - exportedModifier /* = "export" */, - ambientModifier /* = "declare" */, - staticModifier /* = "static" */, - abstractModifier /* = "abstract" */, - optionalModifier /* = "optional" */, - deprecatedModifier /* = "deprecated" */, - dtsModifier /* = ".d.ts" */, - tsModifier /* = ".ts" */, - tsxModifier /* = ".tsx" */, - jsModifier /* = ".js" */, - jsxModifier /* = ".jsx" */, - jsonModifier /* = ".json" */ -} - -external enum class ClassificationTypeNames { - comment /* = "comment" */, - identifier /* = "identifier" */, - keyword /* = "keyword" */, - numericLiteral /* = "number" */, - bigintLiteral /* = "bigint" */, - operator /* = "operator" */, - stringLiteral /* = "string" */, - whiteSpace /* = "whitespace" */, - text /* = "text" */, - punctuation /* = "punctuation" */, - className /* = "class name" */, - enumName /* = "enum name" */, - interfaceName /* = "interface name" */, - moduleName /* = "module name" */, - typeParameterName /* = "type parameter name" */, - typeAliasName /* = "type alias name" */, - parameterName /* = "parameter name" */, - docCommentTagName /* = "doc comment tag name" */, - jsxOpenTagName /* = "jsx open tag name" */, - jsxCloseTagName /* = "jsx close tag name" */, - jsxSelfClosingTagName /* = "jsx self closing tag name" */, - jsxAttribute /* = "jsx attribute" */, - jsxText /* = "jsx text" */, - jsxAttributeStringLiteralValue /* = "jsx attribute string literal value" */ -} - -external enum class ClassificationType { - comment /* = 1 */, - identifier /* = 2 */, - keyword /* = 3 */, - numericLiteral /* = 4 */, - operator /* = 5 */, - stringLiteral /* = 6 */, - regularExpressionLiteral /* = 7 */, - whiteSpace /* = 8 */, - text /* = 9 */, - punctuation /* = 10 */, - className /* = 11 */, - enumName /* = 12 */, - interfaceName /* = 13 */, - moduleName /* = 14 */, - typeParameterName /* = 15 */, - typeAliasName /* = 16 */, - parameterName /* = 17 */, - docCommentTagName /* = 18 */, - jsxOpenTagName /* = 19 */, - jsxCloseTagName /* = 20 */, - jsxSelfClosingTagName /* = 21 */, - jsxAttribute /* = 22 */, - jsxText /* = 23 */, - jsxAttributeStringLiteralValue /* = 24 */, - bigintLiteral /* = 25 */ -} - -external interface InlayHintsContext { - var file: SourceFile - var program: Program - var cancellationToken: CancellationToken - var host: LanguageServiceHost - var span: TextSpan - var preferences: InlayHintsOptions -} - -external fun createClassifier(): Classifier - -external interface DocumentHighlights { - var fileName: String - var highlightSpans: Array -} - -external interface DocumentRegistry { - fun acquireDocument(fileName: String, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile - fun acquireDocumentWithKey(fileName: String, path: String /* String & `T$3` */, compilationSettings: CompilerOptions, key: String /* String & `T$29` */, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile - fun updateDocument(fileName: String, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile - fun updateDocumentWithKey(fileName: String, path: String /* String & `T$3` */, compilationSettings: CompilerOptions, key: String /* String & `T$29` */, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile - fun getKeyForCompilationSettings(settings: CompilerOptions): String /* String & `T$29` */ - fun releaseDocument(fileName: String, compilationSettings: CompilerOptions) - fun releaseDocument(fileName: String, compilationSettings: CompilerOptions, scriptKind: ScriptKind) - fun releaseDocumentWithKey(path: String /* String & `T$3` */, key: String /* String & `T$29` */) - fun releaseDocumentWithKey(path: String /* String & `T$3` */, key: String /* String & `T$29` */, scriptKind: ScriptKind) - fun reportStats(): String -} - -external interface `T$29` { - var __bucketKey: Any -} - -external fun createDocumentRegistry(useCaseSensitiveFileNames: Boolean = definedExternally, currentDirectory: String = definedExternally): DocumentRegistry - -external fun preProcessFile(sourceText: String, readImportFiles: Boolean = definedExternally, detectJavaScriptImports: Boolean = definedExternally): PreProcessedFileInfo - -external interface TranspileOptions { - var compilerOptions: CompilerOptions? - get() = definedExternally - set(value) = definedExternally - var fileName: String? - get() = definedExternally - set(value) = definedExternally - var reportDiagnostics: Boolean? - get() = definedExternally - set(value) = definedExternally - var moduleName: String? - get() = definedExternally - set(value) = definedExternally - var renamedDependencies: MapLike? - get() = definedExternally - set(value) = definedExternally - var transformers: CustomTransformers? - get() = definedExternally - set(value) = definedExternally -} - -external interface TranspileOutput { - var outputText: String - var diagnostics: Array? - get() = definedExternally - set(value) = definedExternally - var sourceMapText: String? - get() = definedExternally - set(value) = definedExternally -} - -external fun transpileModule(input: String, transpileOptions: TranspileOptions): TranspileOutput - -external fun transpile(input: String, compilerOptions: CompilerOptions = definedExternally, fileName: String = definedExternally, diagnostics: Array = definedExternally, moduleName: String = definedExternally): String - -external var servicesVersion: Any - -external fun toEditorSettings(options: EditorOptions): EditorSettings - -external fun toEditorSettings(options: EditorSettings): EditorSettings - -external fun displayPartsToString(displayParts: Array?): String - -external fun getDefaultCompilerOptions(): CompilerOptions - -external fun getSupportedCodeFixes(): Array - -external fun createLanguageServiceSourceFile(fileName: String, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: String, setNodeParents: Boolean, scriptKind: ScriptKind = definedExternally): SourceFile - -external fun updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: String, textChangeRange: TextChangeRange?, aggressiveChecks: Boolean = definedExternally): SourceFile - -external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally, syntaxOnlyOrLanguageServiceMode: Boolean = definedExternally): LanguageService - -external fun createLanguageService(host: LanguageServiceHost): LanguageService - -external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally): LanguageService - -external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally, syntaxOnlyOrLanguageServiceMode: LanguageServiceMode = definedExternally): LanguageService - -external fun getDefaultLibFilePath(options: CompilerOptions): String - -external fun transform(source: T, transformers: Array>, compilerOptions: CompilerOptions = definedExternally): TransformationResult - -external fun transform(source: T, transformers: Array>): TransformationResult - -external fun transform(source: Array, transformers: Array>, compilerOptions: CompilerOptions = definedExternally): TransformationResult - -external fun transform(source: Array, transformers: Array>): TransformationResult - -external fun createNodeArray(elements: Array?, hasTrailingComma: Boolean?): NodeArray - -external var createNumericLiteral: (value: dynamic /* String | Number */, numericLiteralFlags: TokenFlags?) -> NumericLiteral - -external var createBigIntLiteral: (value: dynamic /* String | PseudoBigInt */) -> BigIntLiteral - -external object createStringLiteral { - @nativeInvoke - operator fun invoke(text: String, isSingleQuote: Boolean? = definedExternally): StringLiteral - @nativeInvoke - operator fun invoke(text: String, isSingleQuote: Boolean? = definedExternally, hasExtendedUnicodeEscape: Boolean? = definedExternally): StringLiteral -} - -external var createStringLiteralFromNode: (sourceNode: dynamic /* Identifier | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral */, isSingleQuote: Boolean?) -> StringLiteral - -external var createRegularExpressionLiteral: (text: String) -> RegularExpressionLiteral - -external var createLoopVariable: (reservedInNestedScopes: Boolean?) -> Identifier - -external var createUniqueName: (text: String, flags: GeneratedIdentifierFlags?) -> Identifier - -external var createPrivateIdentifier: (text: String) -> PrivateIdentifier - -external var createSuper: () -> SuperExpression - -external var createThis: () -> ThisExpression - -external var createNull: () -> NullLiteral - -external var createTrue: () -> TrueLiteral - -external var createFalse: () -> FalseLiteral - -//external var createModifier: (kind: T) -> ModifierToken -external fun createModifier(kind: T): ModifierToken - -external var createModifiersFromModifierFlags: (flags: ModifierFlags) -> Array - -external var createQualifiedName: (left: dynamic /* Identifier | QualifiedName */, right: dynamic /* String | Identifier */) -> QualifiedName - -external var updateQualifiedName: (node: QualifiedName, left: dynamic /* Identifier | QualifiedName */, right: Identifier) -> QualifiedName - -external var createComputedPropertyName: (expression: Expression) -> ComputedPropertyName - -external var updateComputedPropertyName: (node: ComputedPropertyName, expression: Expression) -> ComputedPropertyName - -external var createTypeParameterDeclaration: (name: dynamic /* String | Identifier */, constraint: TypeNode?, defaultType: TypeNode?) -> TypeParameterDeclaration - -external var updateTypeParameterDeclaration: (node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode?, defaultType: TypeNode?) -> TypeParameterDeclaration - -external var createParameter: (decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> ParameterDeclaration - -external var updateParameter: (node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> ParameterDeclaration - -external var createDecorator: (expression: Expression) -> Decorator - -external var updateDecorator: (node: Decorator, expression: Expression) -> Decorator - -external var createProperty: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionOrExclamationToken: dynamic /* QuestionToken? | ExclamationToken? */, type: TypeNode?, initializer: Expression?) -> PropertyDeclaration - -external var updateProperty: (node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionOrExclamationToken: dynamic /* QuestionToken? | ExclamationToken? */, type: TypeNode?, initializer: Expression?) -> PropertyDeclaration - -external var createMethod: (decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> MethodDeclaration - -external var updateMethod: (node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> MethodDeclaration - -external var createConstructor: (decorators: Array?, modifiers: Array?, parameters: Array, body: Block?) -> ConstructorDeclaration - -external var updateConstructor: (node: ConstructorDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, body: Block?) -> ConstructorDeclaration - -external var createGetAccessor: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, type: TypeNode?, body: Block?) -> GetAccessorDeclaration - -external var updateGetAccessor: (node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, type: TypeNode?, body: Block?) -> GetAccessorDeclaration - -external var createSetAccessor: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, body: Block?) -> SetAccessorDeclaration - -external var updateSetAccessor: (node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, body: Block?) -> SetAccessorDeclaration - -external var createCallSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?) -> CallSignatureDeclaration - -external var updateCallSignature: (node: CallSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?) -> CallSignatureDeclaration - -external var createConstructSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?) -> ConstructSignatureDeclaration - -external var updateConstructSignature: (node: ConstructSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?) -> ConstructSignatureDeclaration - -external var updateIndexSignature: (node: IndexSignatureDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode) -> IndexSignatureDeclaration - -//external var createKeywordTypeNode: (kind: TKind) -> KeywordTypeNode -external fun createKeywordTypeNode(kind: TKind): KeywordTypeNode - -external var createTypePredicateNodeWithModifier: (assertsModifier: AssertsKeyword?, parameterName: dynamic /* String | Identifier | ThisTypeNode */, type: TypeNode?) -> TypePredicateNode - -external var updateTypePredicateNodeWithModifier: (node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: dynamic /* Identifier | ThisTypeNode */, type: TypeNode?) -> TypePredicateNode - -external var createTypeReferenceNode: (typeName: dynamic /* String | Identifier | QualifiedName */, typeArguments: Array?) -> TypeReferenceNode - -external var updateTypeReferenceNode: (node: TypeReferenceNode, typeName: dynamic /* Identifier | QualifiedName */, typeArguments: NodeArray?) -> TypeReferenceNode - -external var createFunctionTypeNode: (typeParameters: Array?, parameters: Array, type: TypeNode) -> FunctionTypeNode - -external var updateFunctionTypeNode: (node: FunctionTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode) -> FunctionTypeNode - -external var createConstructorTypeNode: (typeParameters: Array?, parameters: Array, type: TypeNode) -> ConstructorTypeNode - -external var updateConstructorTypeNode: (node: ConstructorTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode) -> ConstructorTypeNode - -external var createTypeQueryNode: (exprName: dynamic /* Identifier | QualifiedName */) -> TypeQueryNode - -external var updateTypeQueryNode: (node: TypeQueryNode, exprName: dynamic /* Identifier | QualifiedName */) -> TypeQueryNode - -external var createTypeLiteralNode: (members: Array?) -> TypeLiteralNode - -external var updateTypeLiteralNode: (node: TypeLiteralNode, members: NodeArray) -> TypeLiteralNode - -external var createArrayTypeNode: (elementType: TypeNode) -> ArrayTypeNode - -external var updateArrayTypeNode: (node: ArrayTypeNode, elementType: TypeNode) -> ArrayTypeNode - -external var createTupleTypeNode: (elements: Array) -> TupleTypeNode - -external var updateTupleTypeNode: (node: TupleTypeNode, elements: Array) -> TupleTypeNode - -external var createOptionalTypeNode: (type: TypeNode) -> OptionalTypeNode - -external var updateOptionalTypeNode: (node: OptionalTypeNode, type: TypeNode) -> OptionalTypeNode - -external var createRestTypeNode: (type: TypeNode) -> RestTypeNode - -external var updateRestTypeNode: (node: RestTypeNode, type: TypeNode) -> RestTypeNode - -external var createUnionTypeNode: (types: Array) -> UnionTypeNode - -external var updateUnionTypeNode: (node: UnionTypeNode, types: NodeArray) -> UnionTypeNode - -external var createIntersectionTypeNode: (types: Array) -> IntersectionTypeNode - -external var updateIntersectionTypeNode: (node: IntersectionTypeNode, types: NodeArray) -> IntersectionTypeNode - -external var createConditionalTypeNode: (checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) -> ConditionalTypeNode - -external var updateConditionalTypeNode: (node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) -> ConditionalTypeNode - -external var createInferTypeNode: (typeParameter: TypeParameterDeclaration) -> InferTypeNode - -external var updateInferTypeNode: (node: InferTypeNode, typeParameter: TypeParameterDeclaration) -> InferTypeNode - -external var createImportTypeNode: (argument: TypeNode, qualifier: dynamic /* Identifier? | QualifiedName? */, typeArguments: Array?, isTypeOf: Boolean?) -> ImportTypeNode - -external var updateImportTypeNode: (node: ImportTypeNode, argument: TypeNode, qualifier: dynamic /* Identifier? | QualifiedName? */, typeArguments: Array?, isTypeOf: Boolean?) -> ImportTypeNode - -external var createParenthesizedType: (type: TypeNode) -> ParenthesizedTypeNode - -external var updateParenthesizedType: (node: ParenthesizedTypeNode, type: TypeNode) -> ParenthesizedTypeNode - -external var createThisTypeNode: () -> ThisTypeNode - -external var updateTypeOperatorNode: (node: TypeOperatorNode, type: TypeNode) -> TypeOperatorNode - -external var createIndexedAccessTypeNode: (objectType: TypeNode, indexType: TypeNode) -> IndexedAccessTypeNode - -external var updateIndexedAccessTypeNode: (node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) -> IndexedAccessTypeNode - -external var createMappedTypeNode: (readonlyToken: dynamic /* ReadonlyKeyword? | PlusToken? | MinusToken? */, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */, type: TypeNode?) -> MappedTypeNode - -external var updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: dynamic /* ReadonlyKeyword? | PlusToken? | MinusToken? */, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */, type: TypeNode?) -> MappedTypeNode - -external var createLiteralTypeNode: (literal: dynamic /* LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral */) -> LiteralTypeNode - -external var updateLiteralTypeNode: (node: LiteralTypeNode, literal: dynamic /* LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral */) -> LiteralTypeNode - -external var createObjectBindingPattern: (elements: Array) -> ObjectBindingPattern - -external var updateObjectBindingPattern: (node: ObjectBindingPattern, elements: Array) -> ObjectBindingPattern - -external var createArrayBindingPattern: (elements: Array) -> ArrayBindingPattern - -external var updateArrayBindingPattern: (node: ArrayBindingPattern, elements: Array) -> ArrayBindingPattern - -external var createBindingElement: (dotDotDotToken: DotDotDotToken?, propertyName: dynamic /* String? | Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression?) -> BindingElement - -external var updateBindingElement: (node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */, name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression?) -> BindingElement - -external var createArrayLiteral: (elements: Array?, multiLine: Boolean?) -> ArrayLiteralExpression - -external var updateArrayLiteral: (node: ArrayLiteralExpression, elements: Array) -> ArrayLiteralExpression - -external var createObjectLiteral: (properties: Array?, multiLine: Boolean?) -> ObjectLiteralExpression - -external var updateObjectLiteral: (node: ObjectLiteralExpression, properties: Array) -> ObjectLiteralExpression - -external var createPropertyAccess: (expression: Expression, name: dynamic /* String | Identifier | PrivateIdentifier */) -> PropertyAccessExpression - -external var updatePropertyAccess: (node: PropertyAccessExpression, expression: Expression, name: dynamic /* Identifier | PrivateIdentifier */) -> PropertyAccessExpression - -external var createPropertyAccessChain: (expression: Expression, questionDotToken: QuestionDotToken?, name: dynamic /* String | Identifier | PrivateIdentifier */) -> PropertyAccessChain - -external var updatePropertyAccessChain: (node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: dynamic /* Identifier | PrivateIdentifier */) -> PropertyAccessChain - -external var createElementAccess: (expression: Expression, index: dynamic /* Number | Expression */) -> ElementAccessExpression - -external var updateElementAccess: (node: ElementAccessExpression, expression: Expression, argumentExpression: Expression) -> ElementAccessExpression - -external var createElementAccessChain: (expression: Expression, questionDotToken: QuestionDotToken?, index: dynamic /* Number | Expression */) -> ElementAccessChain - -external var updateElementAccessChain: (node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, argumentExpression: Expression) -> ElementAccessChain - -external var createCall: (expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> CallExpression - -external var updateCall: (node: CallExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array) -> CallExpression - -external var createCallChain: (expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array?) -> CallChain - -external var updateCallChain: (node: CallChain, expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array) -> CallChain - -external var createNew: (expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> NewExpression - -external var updateNew: (node: NewExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> NewExpression - -external var createTypeAssertion: (type: TypeNode, expression: Expression) -> TypeAssertion - -external var updateTypeAssertion: (node: TypeAssertion, type: TypeNode, expression: Expression) -> TypeAssertion - -external var createParen: (expression: Expression) -> ParenthesizedExpression - -external var updateParen: (node: ParenthesizedExpression, expression: Expression) -> ParenthesizedExpression - -external var createFunctionExpression: (modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block) -> FunctionExpression - -external var updateFunctionExpression: (node: FunctionExpression, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block) -> FunctionExpression - -external var createDelete: (expression: Expression) -> DeleteExpression - -external var updateDelete: (node: DeleteExpression, expression: Expression) -> DeleteExpression - -external var createTypeOf: (expression: Expression) -> TypeOfExpression - -external var updateTypeOf: (node: TypeOfExpression, expression: Expression) -> TypeOfExpression - -external var createVoid: (expression: Expression) -> VoidExpression - -external var updateVoid: (node: VoidExpression, expression: Expression) -> VoidExpression - -external var createAwait: (expression: Expression) -> AwaitExpression - -external var updateAwait: (node: AwaitExpression, expression: Expression) -> AwaitExpression - -external var createPrefix: (operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken | SyntaxKind.ExclamationToken */, operand: Expression) -> PrefixUnaryExpression - -external var updatePrefix: (node: PrefixUnaryExpression, operand: Expression) -> PrefixUnaryExpression - -external var createPostfix: (operand: Expression, operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken */) -> PostfixUnaryExpression - -external var updatePostfix: (node: PostfixUnaryExpression, operand: Expression) -> PostfixUnaryExpression - -external var createBinary: (left: Expression, operator: dynamic /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression) -> BinaryExpression - -external var updateConditional: (node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression) -> ConditionalExpression - -external var createTemplateExpression: (head: TemplateHead, templateSpans: Array) -> TemplateExpression - -external var updateTemplateExpression: (node: TemplateExpression, head: TemplateHead, templateSpans: Array) -> TemplateExpression - -external object createTemplateHead { - @nativeInvoke - operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateHead -// @nativeInvoke -// operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateHead -} - -external object createTemplateMiddle { - @nativeInvoke - operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateMiddle -// @nativeInvoke -// operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateMiddle -} - -external object createTemplateTail { - @nativeInvoke - operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateTail -// @nativeInvoke -// operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateTail -} - -external object createNoSubstitutionTemplateLiteral { - @nativeInvoke - operator fun invoke(text: String, rawText: String? = definedExternally): NoSubstitutionTemplateLiteral -// @nativeInvoke -// operator fun invoke(text: String?, rawText: String): NoSubstitutionTemplateLiteral -} - -external var updateYield: (node: YieldExpression, asteriskToken: AsteriskToken?, expression: Expression?) -> YieldExpression - -external var createSpread: (expression: Expression) -> SpreadElement - -external var updateSpread: (node: SpreadElement, expression: Expression) -> SpreadElement - -external var createOmittedExpression: () -> OmittedExpression - -external var createAsExpression: (expression: Expression, type: TypeNode) -> AsExpression - -external var updateAsExpression: (node: AsExpression, expression: Expression, type: TypeNode) -> AsExpression - -external var createNonNullExpression: (expression: Expression) -> NonNullExpression - -external var updateNonNullExpression: (node: NonNullExpression, expression: Expression) -> NonNullExpression - -external var createNonNullChain: (expression: Expression) -> NonNullChain - -external var updateNonNullChain: (node: NonNullChain, expression: Expression) -> NonNullChain - -external var createMetaProperty: (keywordToken: dynamic /* SyntaxKind.ImportKeyword | SyntaxKind.NewKeyword */, name: Identifier) -> MetaProperty - -external var updateMetaProperty: (node: MetaProperty, name: Identifier) -> MetaProperty - -external var createTemplateSpan: (expression: Expression, literal: dynamic /* TemplateMiddle | TemplateTail */) -> TemplateSpan - -external var updateTemplateSpan: (node: TemplateSpan, expression: Expression, literal: dynamic /* TemplateMiddle | TemplateTail */) -> TemplateSpan - -external var createSemicolonClassElement: () -> SemicolonClassElement - -external var createBlock: (statements: Array, multiLine: Boolean?) -> Block - -external var updateBlock: (node: Block, statements: Array) -> Block - -external var createVariableStatement: (modifiers: Array?, declarationList: dynamic /* VariableDeclarationList | Array */) -> VariableStatement - -external var updateVariableStatement: (node: VariableStatement, modifiers: Array?, declarationList: VariableDeclarationList) -> VariableStatement - -external var createEmptyStatement: () -> EmptyStatement - -external var createExpressionStatement: (expression: Expression) -> ExpressionStatement - -external var updateExpressionStatement: (node: ExpressionStatement, expression: Expression) -> ExpressionStatement - -external var createStatement: (expression: Expression) -> ExpressionStatement - -external var updateStatement: (node: ExpressionStatement, expression: Expression) -> ExpressionStatement - -external var createIf: (expression: Expression, thenStatement: Statement, elseStatement: Statement?) -> IfStatement - -external var updateIf: (node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement?) -> IfStatement - -external var createDo: (statement: Statement, expression: Expression) -> DoStatement - -external var updateDo: (node: DoStatement, statement: Statement, expression: Expression) -> DoStatement - -external var createWhile: (expression: Expression, statement: Statement) -> WhileStatement - -external var updateWhile: (node: WhileStatement, expression: Expression, statement: Statement) -> WhileStatement - -external var createFor: (initializer: dynamic /* VariableDeclarationList? | Expression? */, condition: Expression?, incrementor: Expression?, statement: Statement) -> ForStatement - -external var updateFor: (node: ForStatement, initializer: dynamic /* VariableDeclarationList? | Expression? */, condition: Expression?, incrementor: Expression?, statement: Statement) -> ForStatement - -external var createForIn: (initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForInStatement - -external var updateForIn: (node: ForInStatement, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForInStatement - -external var createForOf: (awaitModifier: AwaitKeyword?, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForOfStatement - -external var updateForOf: (node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForOfStatement - -external var createContinue: (label: dynamic /* String? | Identifier? */) -> ContinueStatement - -external var updateContinue: (node: ContinueStatement, label: Identifier?) -> ContinueStatement - -external var createBreak: (label: dynamic /* String? | Identifier? */) -> BreakStatement - -external var updateBreak: (node: BreakStatement, label: Identifier?) -> BreakStatement - -external var createReturn: (expression: Expression?) -> ReturnStatement - -external var updateReturn: (node: ReturnStatement, expression: Expression?) -> ReturnStatement - -external var createWith: (expression: Expression, statement: Statement) -> WithStatement - -external var updateWith: (node: WithStatement, expression: Expression, statement: Statement) -> WithStatement - -external var createSwitch: (expression: Expression, caseBlock: CaseBlock) -> SwitchStatement - -external var updateSwitch: (node: SwitchStatement, expression: Expression, caseBlock: CaseBlock) -> SwitchStatement - -external var createLabel: (label: dynamic /* String | Identifier */, statement: Statement) -> LabeledStatement - -external var updateLabel: (node: LabeledStatement, label: Identifier, statement: Statement) -> LabeledStatement - -external var createThrow: (expression: Expression) -> ThrowStatement - -external var updateThrow: (node: ThrowStatement, expression: Expression) -> ThrowStatement - -external var createTry: (tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?) -> TryStatement - -external var updateTry: (node: TryStatement, tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?) -> TryStatement - -external var createDebuggerStatement: () -> DebuggerStatement - -external var createVariableDeclarationList: (declarations: Array, flags: NodeFlags?) -> VariableDeclarationList - -external var updateVariableDeclarationList: (node: VariableDeclarationList, declarations: Array) -> VariableDeclarationList - -external var createFunctionDeclaration: (decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> FunctionDeclaration - -external var updateFunctionDeclaration: (node: FunctionDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> FunctionDeclaration - -external var createClassDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassDeclaration - -external var updateClassDeclaration: (node: ClassDeclaration, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassDeclaration - -external var createInterfaceDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> InterfaceDeclaration - -external var updateInterfaceDeclaration: (node: InterfaceDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array) -> InterfaceDeclaration - -external var createTypeAliasDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, typeParameters: Array?, type: TypeNode) -> TypeAliasDeclaration - -external var updateTypeAliasDeclaration: (node: TypeAliasDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode) -> TypeAliasDeclaration - -external var createEnumDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, members: Array) -> EnumDeclaration - -external var updateEnumDeclaration: (node: EnumDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, members: Array) -> EnumDeclaration - -external var createModuleDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral */, body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */, flags: NodeFlags?) -> ModuleDeclaration - -external var updateModuleDeclaration: (node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral */, body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */) -> ModuleDeclaration - -external var createModuleBlock: (statements: Array) -> ModuleBlock - -external var updateModuleBlock: (node: ModuleBlock, statements: Array) -> ModuleBlock - -external var createCaseBlock: (clauses: Array) -> CaseBlock - -external var updateCaseBlock: (node: CaseBlock, clauses: Array) -> CaseBlock - -external var createNamespaceExportDeclaration: (name: dynamic /* String | Identifier */) -> NamespaceExportDeclaration - -external var updateNamespaceExportDeclaration: (node: NamespaceExportDeclaration, name: Identifier) -> NamespaceExportDeclaration - -external var createImportEqualsDeclaration: (decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: dynamic /* String | Identifier */, moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */) -> ImportEqualsDeclaration - -external var updateImportEqualsDeclaration: (node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */) -> ImportEqualsDeclaration - -external var createImportDeclaration: (decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression) -> ImportDeclaration - -external var updateImportDeclaration: (node: ImportDeclaration, decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression) -> ImportDeclaration - -external var createNamespaceImport: (name: Identifier) -> NamespaceImport - -external var updateNamespaceImport: (node: NamespaceImport, name: Identifier) -> NamespaceImport - -external var createNamedImports: (elements: Array) -> NamedImports - -external var updateNamedImports: (node: NamedImports, elements: Array) -> NamedImports - -external var createImportSpecifier: (propertyName: Identifier?, name: Identifier) -> ImportSpecifier - -external var updateImportSpecifier: (node: ImportSpecifier, propertyName: Identifier?, name: Identifier) -> ImportSpecifier - -external var createExportAssignment: (decorators: Array?, modifiers: Array?, isExportEquals: Boolean?, expression: Expression) -> ExportAssignment - -external var updateExportAssignment: (node: ExportAssignment, decorators: Array?, modifiers: Array?, expression: Expression) -> ExportAssignment - -external var createNamedExports: (elements: Array) -> NamedExports - -external var updateNamedExports: (node: NamedExports, elements: Array) -> NamedExports - -external var createExportSpecifier: (propertyName: dynamic /* String? | Identifier? */, name: dynamic /* String | Identifier */) -> ExportSpecifier - -external var updateExportSpecifier: (node: ExportSpecifier, propertyName: Identifier?, name: Identifier) -> ExportSpecifier - -external var createExternalModuleReference: (expression: Expression) -> ExternalModuleReference - -external var updateExternalModuleReference: (node: ExternalModuleReference, expression: Expression) -> ExternalModuleReference - -external var createJSDocTypeExpression: (type: TypeNode) -> JSDocTypeExpression - -external var createJSDocTypeTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocTypeTag - -external var createJSDocReturnTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: dynamic /* String? | NodeArray? */) -> JSDocReturnTag - -external var createJSDocThisTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocThisTag - -external var createJSDocComment: (comment: dynamic /* String? | NodeArray? */, tags: Array?) -> JSDoc - -external var createJSDocParameterTag: (tagName: Identifier?, name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean?, comment: dynamic /* String? | NodeArray? */) -> JSDocParameterTag - -external var createJSDocClassTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocClassTag - -external var createJSDocAugmentsTag: (tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: dynamic /* String? | NodeArray? */) -> JSDocAugmentsTag - -external var createJSDocEnumTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocEnumTag - -external var createJSDocTemplateTag: (tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: dynamic /* String? | NodeArray? */) -> JSDocTemplateTag - -external var createJSDocTypedefTag: (tagName: Identifier?, typeExpression: dynamic /* JSDocTypeLiteral? | JSDocTypeExpression? */, fullName: dynamic /* Identifier? | JSDocNamespaceDeclaration? */, comment: dynamic /* String? | NodeArray? */) -> JSDocTypedefTag - -external var createJSDocCallbackTag: (tagName: Identifier?, typeExpression: JSDocSignature, fullName: dynamic /* Identifier? | JSDocNamespaceDeclaration? */, comment: dynamic /* String? | NodeArray? */) -> JSDocCallbackTag - -external var createJSDocSignature: (typeParameters: Array?, parameters: Array, type: JSDocReturnTag?) -> JSDocSignature - -external var createJSDocPropertyTag: (tagName: Identifier?, name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean?, comment: dynamic /* String? | NodeArray? */) -> JSDocPropertyTag - -external var createJSDocTypeLiteral: (jsDocPropertyTags: Array?, isArrayType: Boolean?) -> JSDocTypeLiteral - -external var createJSDocImplementsTag: (tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: dynamic /* String? | NodeArray? */) -> JSDocImplementsTag - -external var createJSDocAuthorTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocAuthorTag - -external var createJSDocPublicTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocPublicTag - -external var createJSDocPrivateTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocPrivateTag - -external var createJSDocProtectedTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocProtectedTag - -external var createJSDocReadonlyTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocReadonlyTag - -external var createJSDocTag: (tagName: Identifier, comment: dynamic /* String? | NodeArray? */) -> JSDocUnknownTag - -external var createJsxElement: (openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement) -> JsxElement - -external var updateJsxElement: (node: JsxElement, openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement) -> JsxElement - -external var createJsxSelfClosingElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxSelfClosingElement - -external var updateJsxSelfClosingElement: (node: JsxSelfClosingElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxSelfClosingElement - -external var createJsxOpeningElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxOpeningElement - -external var updateJsxOpeningElement: (node: JsxOpeningElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxOpeningElement - -external var createJsxClosingElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */) -> JsxClosingElement - -external var updateJsxClosingElement: (node: JsxClosingElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */) -> JsxClosingElement - -external var createJsxFragment: (openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment) -> JsxFragment - -external var createJsxText: (text: String, containsOnlyTriviaWhiteSpaces: Boolean?) -> JsxText - -external var updateJsxText: (node: JsxText, text: String, containsOnlyTriviaWhiteSpaces: Boolean?) -> JsxText - -external var createJsxOpeningFragment: () -> JsxOpeningFragment - -external var createJsxJsxClosingFragment: () -> JsxClosingFragment - -external var updateJsxFragment: (node: JsxFragment, openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment) -> JsxFragment - -external var createJsxAttribute: (name: Identifier, initializer: dynamic /* StringLiteral? | JsxExpression? */) -> JsxAttribute - -external var updateJsxAttribute: (node: JsxAttribute, name: Identifier, initializer: dynamic /* StringLiteral? | JsxExpression? */) -> JsxAttribute - -external var createJsxAttributes: (properties: Array) -> JsxAttributes - -external var updateJsxAttributes: (node: JsxAttributes, properties: Array) -> JsxAttributes - -external var createJsxSpreadAttribute: (expression: Expression) -> JsxSpreadAttribute - -external var updateJsxSpreadAttribute: (node: JsxSpreadAttribute, expression: Expression) -> JsxSpreadAttribute - -external var createJsxExpression: (dotDotDotToken: DotDotDotToken?, expression: Expression?) -> JsxExpression - -external var updateJsxExpression: (node: JsxExpression, expression: Expression?) -> JsxExpression - -external var createCaseClause: (expression: Expression, statements: Array) -> CaseClause - -external var updateCaseClause: (node: CaseClause, expression: Expression, statements: Array) -> CaseClause - -external var createDefaultClause: (statements: Array) -> DefaultClause - -external var updateDefaultClause: (node: DefaultClause, statements: Array) -> DefaultClause - -external var createHeritageClause: (token: dynamic /* SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword */, types: Array) -> HeritageClause - -external var updateHeritageClause: (node: HeritageClause, types: Array) -> HeritageClause - -external var createCatchClause: (variableDeclaration: dynamic /* String? | VariableDeclaration? */, block: Block) -> CatchClause - -external var updateCatchClause: (node: CatchClause, variableDeclaration: VariableDeclaration?, block: Block) -> CatchClause - -external var createPropertyAssignment: (name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression) -> PropertyAssignment - -external var updatePropertyAssignment: (node: PropertyAssignment, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression) -> PropertyAssignment - -external var createShorthandPropertyAssignment: (name: dynamic /* String | Identifier */, objectAssignmentInitializer: Expression?) -> ShorthandPropertyAssignment - -external var updateShorthandPropertyAssignment: (node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression?) -> ShorthandPropertyAssignment - -external var createSpreadAssignment: (expression: Expression) -> SpreadAssignment - -external var updateSpreadAssignment: (node: SpreadAssignment, expression: Expression) -> SpreadAssignment - -external var createEnumMember: (name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression?) -> EnumMember - -external var updateEnumMember: (node: EnumMember, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression?) -> EnumMember - -external var updateSourceFileNode: (node: SourceFile, statements: Array, isDeclarationFile: Boolean?, referencedFiles: Array?, typeReferences: Array?, hasNoDefaultLib: Boolean?, libReferences: Array?) -> SourceFile - -external var createNotEmittedStatement: (original: Node) -> NotEmittedStatement - -external var createPartiallyEmittedExpression: (expression: Expression, original: Node?) -> PartiallyEmittedExpression - -external var updatePartiallyEmittedExpression: (node: PartiallyEmittedExpression, expression: Expression) -> PartiallyEmittedExpression - -external var createCommaList: (elements: Array) -> CommaListExpression - -external var updateCommaList: (node: CommaListExpression, elements: Array) -> CommaListExpression - -external var createBundle: (sourceFiles: Array, prepends: Array?) -> Bundle - -external var updateBundle: (node: Bundle, sourceFiles: Array, prepends: Array?) -> Bundle - -external object createImmediatelyInvokedFunctionExpression { - @nativeInvoke - operator fun invoke(statements: Array): CallExpression - @nativeInvoke - operator fun invoke(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression -} - -external object createImmediatelyInvokedArrowFunction { - @nativeInvoke - operator fun invoke(statements: Array): CallExpression - @nativeInvoke - operator fun invoke(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression -} - -external var createVoidZero: () -> VoidExpression - -external var createExportDefault: (expression: Expression) -> ExportAssignment - -external var createExternalModuleExport: (exportName: Identifier) -> ExportDeclaration - -external var createNamespaceExport: (name: Identifier) -> NamespaceExport - -external var updateNamespaceExport: (node: NamespaceExport, name: Identifier) -> NamespaceExport - -external fun createToken(kind: TKind): Token - -external var createIdentifier: (text: String) -> Identifier - -external var createTempVariable: (recordTempVariable: ((node: Identifier) -> Unit)?) -> Identifier - -external var getGeneratedNameForNode: (node: Node?) -> Identifier - -external var createOptimisticUniqueName: (text: String) -> Identifier - -external var createFileLevelUniqueName: (text: String) -> Identifier - -external var createIndexSignature: (decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode) -> IndexSignatureDeclaration - -external var createTypePredicateNode: (parameterName: dynamic /* Identifier | ThisTypeNode | String */, type: TypeNode) -> TypePredicateNode - -external var updateTypePredicateNode: (node: TypePredicateNode, parameterName: dynamic /* Identifier | ThisTypeNode */, type: TypeNode) -> TypePredicateNode - -external object createLiteral { -// @nativeInvoke -// operator fun invoke(value: Any /* String | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier */): StringLiteral -// @nativeInvoke -// operator fun invoke(value: Any /* Number | PseudoBigInt */): NumericLiteral - @nativeInvoke - operator fun invoke(value: dynamic): dynamic /* TrueLiteral | FalseLiteral */ -// @nativeInvoke -// operator fun invoke(value: Any /* String | Number | PseudoBigInt | Boolean */): PrimaryExpression -} - -external var createMethodSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?) -> MethodSignature - -external var updateMethodSignature: (node: MethodSignature, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?) -> MethodSignature - -external object createTypeOperatorNode { - @nativeInvoke - operator fun invoke(type: TypeNode): TypeOperatorNode - @nativeInvoke - operator fun invoke(operator: Any /* SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword */, type: TypeNode): TypeOperatorNode -} - -external object createTaggedTemplate { - @nativeInvoke - operator fun invoke(tag: Expression, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression - @nativeInvoke - operator fun invoke(tag: Expression, typeArguments: Array?, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression -} - -external object updateTaggedTemplate { - @nativeInvoke - operator fun invoke(node: TaggedTemplateExpression, tag: Expression, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression - @nativeInvoke - operator fun invoke(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression -} - -external var updateBinary: (node: BinaryExpression, left: Expression, right: Expression, operator: dynamic /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */) -> BinaryExpression - -external object createConditional { - @nativeInvoke - operator fun invoke(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression - @nativeInvoke - operator fun invoke(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression -} - -external object createYield { - @nativeInvoke - operator fun invoke(expression: Expression? = definedExternally): YieldExpression - @nativeInvoke - operator fun invoke(asteriskToken: AsteriskToken?, expression: Expression): YieldExpression -} - -external var createClassExpression: (modifiers: Array?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassExpression - -external var updateClassExpression: (node: ClassExpression, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassExpression - -external var createPropertySignature: (modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | String */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> PropertySignature - -external var updatePropertySignature: (node: PropertySignature, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> PropertySignature - -external var createExpressionWithTypeArguments: (typeArguments: Array?, expression: Expression) -> ExpressionWithTypeArguments - -external var updateExpressionWithTypeArguments: (node: ExpressionWithTypeArguments, typeArguments: Array?, expression: Expression) -> ExpressionWithTypeArguments - -external object createArrowFunction { - @nativeInvoke - operator fun invoke(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: Any /* FunctionBody | Expression */): ArrowFunction - @nativeInvoke - operator fun invoke(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Any /* FunctionBody | Expression */): ArrowFunction -} - -external object updateArrowFunction { - @nativeInvoke - operator fun invoke(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: Any /* FunctionBody | Expression */): ArrowFunction - @nativeInvoke - operator fun invoke(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Any /* FunctionBody | Expression */): ArrowFunction -} - -external object createVariableDeclaration { - @nativeInvoke - operator fun invoke(name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, type: TypeNode? = definedExternally, initializer: Expression? = definedExternally): VariableDeclaration - @nativeInvoke - operator fun invoke(name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration -} - -external object updateVariableDeclaration { - @nativeInvoke - operator fun invoke(node: VariableDeclaration, name: Any /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, type: TypeNode?, initializer: Expression?): VariableDeclaration - @nativeInvoke - operator fun invoke(node: VariableDeclaration, name: Any /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration -} - -external var createImportClause: (name: Identifier?, namedBindings: dynamic /* NamespaceImport? | NamedImports? */, isTypeOnly: Any) -> ImportClause - -external var updateImportClause: (node: ImportClause, name: Identifier?, namedBindings: dynamic /* NamespaceImport? | NamedImports? */, isTypeOnly: Boolean) -> ImportClause - -external var createExportDeclaration: (decorators: Array?, modifiers: Array?, exportClause: dynamic /* NamespaceExport? | NamedExports? */, moduleSpecifier: Expression?, isTypeOnly: Any) -> ExportDeclaration - -external var updateExportDeclaration: (node: ExportDeclaration, decorators: Array?, modifiers: Array?, exportClause: dynamic /* NamespaceExport? | NamedExports? */, moduleSpecifier: Expression?, isTypeOnly: Boolean) -> ExportDeclaration - -external var createJSDocParamTag: (name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, comment: String?) -> JSDocParameterTag - -external var createComma: (left: Expression, right: Expression) -> Expression - -external var createLessThan: (left: Expression, right: Expression) -> Expression - -external var createAssignment: (left: Expression, right: Expression) -> BinaryExpression - -external var createStrictEquality: (left: Expression, right: Expression) -> BinaryExpression - -external var createStrictInequality: (left: Expression, right: Expression) -> BinaryExpression - -external var createAdd: (left: Expression, right: Expression) -> BinaryExpression - -external var createSubtract: (left: Expression, right: Expression) -> BinaryExpression - -external var createLogicalAnd: (left: Expression, right: Expression) -> BinaryExpression - -external var createLogicalOr: (left: Expression, right: Expression) -> BinaryExpression - -external var createPostfixIncrement: (operand: Expression) -> PostfixUnaryExpression - -external var createLogicalNot: (operand: Expression) -> PrefixUnaryExpression - -external var createNode: (kind: SyntaxKind, pos: Any, end: Any) -> Node - -external fun getMutableClone(node: T): T - -external var isTypeAssertion: (node: Node) -> Boolean - -external var isIdentifierOrPrivateIdentifier: (node: Node) -> Boolean diff --git a/externals02/typescript.ts.server.module_typescript.kt b/externals02/typescript.ts.server.module_typescript.kt deleted file mode 100644 index ae716a6..0000000 --- a/externals02/typescript.ts.server.module_typescript.kt +++ /dev/null @@ -1,101 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package ts.server - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.CompilerOptions -import ts.WatchOptions -import ts.TypeAcquisition -import ts.SortedReadonlyArray - -external interface TypingInstallerResponse { - val kind: String /* "action::set" | "action::invalidate" | "event::typesRegistry" | "action::packageInstalled" | "event::beginInstallTypes" | "event::endInstallTypes" | "event::initializationFailed" */ -} - -external interface TypingInstallerRequestWithProjectName { - val projectName: String -} - -external interface DiscoverTypings : TypingInstallerRequestWithProjectName { - val fileNames: Array - val projectRootPath: String /* String & `T$3` */ - val compilerOptions: CompilerOptions - val watchOptions: WatchOptions? - get() = definedExternally - val typeAcquisition: TypeAcquisition - val unresolvedImports: SortedReadonlyArray - val cachePath: String? - get() = definedExternally - val kind: String /* "discover" */ -} - -external interface CloseProject : TypingInstallerRequestWithProjectName { - val kind: String /* "closeProject" */ -} - -external interface TypesRegistryRequest { - val kind: String /* "typesRegistry" */ -} - -external interface InstallPackageRequest : TypingInstallerRequestWithProjectName { - val kind: String /* "installPackage" */ - val fileName: String /* String & `T$3` */ - val packageName: String - val projectRootPath: String /* String & `T$3` */ -} - -external interface PackageInstalledResponse : ProjectResponse { - override val kind: String /* "action::packageInstalled" */ - val success: Boolean? - val message: String -} - -external interface InitializationFailedResponse : TypingInstallerResponse { - override val kind: String /* "event::initializationFailed" */ - val message: String - val stack: String? - get() = definedExternally -} - -external interface ProjectResponse : TypingInstallerResponse { - val projectName: String -} - -external interface InvalidateCachedTypings : ProjectResponse { - override val kind: String /* "action::invalidate" */ -} - -external interface InstallTypes : ProjectResponse { - override val kind: String /* "event::beginInstallTypes" | "event::endInstallTypes" */ - val eventId: Number - val typingsInstallerVersion: String - val packagesToInstall: Array -} - -external interface BeginInstallTypes : InstallTypes { - override val kind: String /* "event::beginInstallTypes" */ -} - -external interface EndInstallTypes : InstallTypes { - override val kind: String /* "event::endInstallTypes" */ - val installSuccess: Boolean? -} - -external interface SetTypings : ProjectResponse { - val typeAcquisition: TypeAcquisition - val compilerOptions: CompilerOptions - val typings: Array - val unresolvedImports: SortedReadonlyArray - override val kind: String /* "action::set" */ -} \ No newline at end of file diff --git a/externals02/utils.module_typescript-to-lua.kt b/externals02/utils.module_typescript-to-lua.kt deleted file mode 100644 index 08363d8..0000000 --- a/externals02/utils.module_typescript-to-lua.kt +++ /dev/null @@ -1,46 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.WriteFileCallback -import ts.SourceFile - -external interface EmitHost { - fun directoryExists(path: String): Boolean - fun fileExists(path: String): Boolean - fun getCurrentDirectory(): String - fun readFile(path: String): String? - var writeFile: WriteFileCallback -} - -external interface BaseFile { - var code: String - var sourceMap: String? - get() = definedExternally - set(value) = definedExternally - var sourceFiles: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface ProcessedFile : BaseFile { - var fileName: String - var luaAst: File? - get() = definedExternally - set(value) = definedExternally -} - -external interface EmitFile : BaseFile { - var outputPath: String -} \ No newline at end of file diff --git a/externals02/visitors.module_typescript-to-lua.kt b/externals02/visitors.module_typescript-to-lua.kt deleted file mode 100644 index 69513ac..0000000 --- a/externals02/visitors.module_typescript-to-lua.kt +++ /dev/null @@ -1,38 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.Statement -import ts.Node -import tsstdlib.Map -import ts.SyntaxKind - -external interface NodesBySyntaxKind - -typealias StatementLikeNode = Statement - -typealias VisitorResult = Any - -typealias FunctionVisitor = (node: T, context: TransformationContext) -> VisitorResult - -external interface ObjectVisitor { - var transform: FunctionVisitor - var priority: Number? - get() = definedExternally - set(value) = definedExternally -} - -typealias Visitors = Any - -typealias VisitorMap = Map>> \ No newline at end of file From 464d4c28fbb17aa7f5fb5536015e7602e7221d57 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 3 Nov 2021 12:08:07 +0100 Subject: [PATCH 074/629] tasks to move generated ts files to mod project --- .../adamko/gradle/pbandg/pb-and-g.gradle.kts | 4 +- .../build.gradle.kts | 33 ++++++- modules/mod/build.gradle.kts | 62 +++++++++++++- .../proto/FactorioServerLogRecord.ts | 85 +++++++++++++++++++ 4 files changed, 177 insertions(+), 7 deletions(-) create mode 100644 modules/mod/src/main/typescript/proto/FactorioServerLogRecord.ts diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts index a19e654..5735a4b 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts @@ -74,11 +74,11 @@ project.tasks.withType { val aggregateTask = project.tasks.register("protobufCompileAll") { group = Constants.PBG_TASK_GROUP - dependsOn(tasks.withType()) + val pbCompileTasks = tasks.withType() + dependsOn(pbCompileTasks) val genSrcDir = project.layout.pbAndGBuildDir.map { it.dir("generated-sources") } - val pbCompileTasks = tasks.withType() from(pbCompileTasks.map { it.temporaryDir }) into(genSrcDir) includeEmptyDirs = false diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index c1122f5..0b363db 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -88,21 +88,35 @@ val nodeModulesDir: Directory by extra { } afterEvaluate { - tasks.register("protobufJava") { + val protobufJava by tasks.creating(ProtobufCompileTask::class) { description = "proto2java" protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto")) cliArgs.add("--java_out=lite:${project.mkdir("$temporaryDir/java").canonicalPath}") } - - tasks.register("protobufKotlin") { + val protobufKotlin by tasks.creating(ProtobufCompileTask::class) { description = "proto2kotlin" protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto")) cliArgs.add("--kotlin_out=lite:${project.mkdir("$temporaryDir/kotlin").canonicalPath}") } - tasks.register("protobufTypescript") { + + val ktProto by configurations.creating { + isCanBeResolved = false + isCanBeConsumed = true + } + + artifacts { + add(ktProto.name, protobufJava.outputDir) { + builtBy(protobufJava) + } + add(ktProto.name, protobufKotlin.outputDir) { + builtBy(protobufKotlin) + } + } + + val protobufTypescript by tasks.creating(ProtobufCompileTask::class) { description = "proto2typescript" // linux: @@ -126,4 +140,15 @@ afterEvaluate { protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto")) } + + val tsProto by configurations.creating { + isCanBeResolved = false + isCanBeConsumed = true + } + artifacts { + add(tsProto.name, protobufTypescript.outputDir) { + builtBy(protobufTypescript) + } + } + } diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index 70dd20c..aa0a501 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -1,6 +1,6 @@ import com.github.gradle.node.npm.task.NpmTask -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs import org.apache.tools.ant.filters.ReplaceTokens +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { id("dev.adamko.factoriowebmap.archetype.node") @@ -16,6 +16,66 @@ node { nodeProjectDir.set(tsSrcDir) } +val tsProto: Configuration by configurations.creating { + isCanBeConsumed = false + isCanBeResolved = true +} + +dependencies { + tsProto(projects.modules.factorioEventsDataModel.dependencyProject.configurations.getByName("tsProto")) +} + +val tsProtoFetch by tasks.creating(Sync::class) { + group = project.name + + dependsOn(projects.modules.factorioEventsDataModel.dependencyProject.tasks.named("protobufTypescript")) + + val genSrcDir = projects + .modules + .factorioEventsDataModel + .dependencyProject + .layout + .buildDirectory + .dir("pbAndG/generated-sources/typescript") + + val targetDir = "$projectDir/src/main/typescript/proto" + + inputs.dir(genSrcDir) + + from(genSrcDir) + into(targetDir) + + doLast { + + fileTree(targetDir).forEach { + var text = it.readText() + + text = text.replace( + Regex( + """if \(_m0\.util\.Long !== Long\)\s*\{\s*_m0\.util\.Long = Long as any;\s*_m0\.configure\(\);\s*\}""" + ), + "" + ) + + text = text.replace( + Regex("""import Long from "long";"""), + "" + ) + + text = text.replace( + Regex("""import _m0 from "protobufjs\/minimal";"""), + "" + ) + + it.writeText(text) + } + } + +} + +tasks.assemble { dependsOn(tsProtoFetch) } + + val tstlTask = tasks.register("typescriptToLua") { description = "Convert Typescript To Lua" group = projectId diff --git a/modules/mod/src/main/typescript/proto/FactorioServerLogRecord.ts b/modules/mod/src/main/typescript/proto/FactorioServerLogRecord.ts new file mode 100644 index 0000000..c305e96 --- /dev/null +++ b/modules/mod/src/main/typescript/proto/FactorioServerLogRecord.ts @@ -0,0 +1,85 @@ +/* eslint-disable */ + + + +export interface FactorioServerLogRecord { + modVersion: string; + tick: number; + eventType: string; + data?: FactorioLuaObject; +} + +export interface FactorioLuaObject { + objectName: string; + luaControl?: LuaControl | undefined; +} + +/** https://lua-api.factorio.com/next/LuaControl.html */ +export interface LuaControl { + isPlayer: boolean; + surfaceIndex: number; + position?: Position; + forceIndex: number; + player?: LuaPlayer | undefined; + entity?: LuaEntity | undefined; +} + +/** https://lua-api.factorio.com/next/LuaPlayer.html */ +export interface LuaPlayer { + /** unique ID */ + index: number; + name: string; + data: number[]; + colour?: Colour; + isConnected: boolean; + isAdmin: boolean; + afkTimeTicks: number; + onlineTimeTicks: number; + lastOnlineTicks: number; +} + +/** https://lua-api.factorio.com/next/LuaEntity.html */ +export interface LuaEntity { + /** (optional) unique ID */ + unitNumber?: number | undefined; + name: string; + type: string; + /** https://lua-api.factorio.com/next/defines.html#defines.entity_status */ + status: string; + isActive: boolean; + isMoving: boolean; + /** (optional) The player connected to this character or nil if none. */ + playerIndex?: number | undefined; + /** (optional) The last player that changed any setting on this entity. */ + lastUserIndex?: number | undefined; + /** (optional) */ + colour?: Colour; +} + +export interface LuaSurface { + /** unique ID */ + index: number; + name: string; + daytime: number; +} + +export interface LuaForce { + /** unique ID */ + index: number; + forceName: string; + playerIds: number[]; +} + +export interface Position { + x: number; + y: number; +} + +export interface Colour { + red: number; + green: number; + blue: number; + alpha: number; +} + + From 16d382db11a384cfc95b7bdea06d2151b297f682 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 3 Nov 2021 15:59:24 +0100 Subject: [PATCH 075/629] giving up on protobuf arrggghhhhhhh --- .../build.gradle.kts | 2 +- modules/mod/build.gradle.kts | 82 +- .../mod/src/main/typescript/package-lock.json | 153 ++++ modules/mod/src/main/typescript/package.json | 3 +- .../proto/FactorioServerLogRecord.ts | 826 +++++++++++++++++- modules/mod/src/main/typescript/tsconfig.json | 8 +- 6 files changed, 1041 insertions(+), 33 deletions(-) diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index 0b363db..a3f5c6c 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -130,7 +130,7 @@ afterEvaluate { "--ts_proto_opt=useOptionals=true", "--ts_proto_opt=outputServices=false", "--ts_proto_opt=outputJsonMethods=false", - "--ts_proto_opt=outputEncodeMethods=false", +// "--ts_proto_opt=outputEncodeMethods=false", "--ts_proto_opt=forceLong=string", "--ts_proto_opt=forceLong=number", "--ts_proto_opt=esModuleInterop=true", diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index aa0a501..26e634f 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -45,31 +45,31 @@ val tsProtoFetch by tasks.creating(Sync::class) { from(genSrcDir) into(targetDir) - doLast { - - fileTree(targetDir).forEach { - var text = it.readText() - - text = text.replace( - Regex( - """if \(_m0\.util\.Long !== Long\)\s*\{\s*_m0\.util\.Long = Long as any;\s*_m0\.configure\(\);\s*\}""" - ), - "" - ) - - text = text.replace( - Regex("""import Long from "long";"""), - "" - ) - - text = text.replace( - Regex("""import _m0 from "protobufjs\/minimal";"""), - "" - ) - - it.writeText(text) - } - } +// doLast { +// +// fileTree(targetDir).forEach { +// var text = it.readText() +// +// text = text.replace( +// Regex( +// """if \(_m0\.util\.Long !== Long\)\s*\{\s*_m0\.util\.Long = Long as any;\s*_m0\.configure\(\);\s*\}""" +// ), +// "" +// ) +// +// text = text.replace( +// Regex("""import Long from "long";"""), +// "" +// ) +// +// text = text.replace( +// Regex("""import _m0 from "protobufjs\/minimal";"""), +// "" +// ) +// +// it.writeText(text) +// } +// } } @@ -267,7 +267,7 @@ tasks.register("downloadFactorioApiDocs") { val target = uri("https://lua-api.factorio.com/latest/runtime-api.json") val apiFilename = File(target.path).name - val downloadedFile = file(temporaryDir.path + "/" + apiFilename) + val downloadedFile = file("$temporaryDir/$apiFilename") val apiFile = modBuildDir.file(apiFilename) outputs.file(apiFile) @@ -290,3 +290,33 @@ tasks.register("downloadFactorioApiDocs") { logger.lifecycle("Downloaded Factorio API json: $apiFile") } } + +//tasks.register("downloadLuaProtobuf") { +// group = projectId +// +// val luaProtobufVersion = "0.3.3" +// +// val target = uri("https://github.com/starwing/lua-protobuf/archive/refs/tags/$luaProtobufVersion.zip") +// val downloadedFile = file("$temporaryDir/luaProtobuf-$luaProtobufVersion.zip") +// +// val luaProto = modBuildDir.file(apiFilename) +// outputs.file(apiFile) +// +// doLast { +// +// ant.invokeMethod( +// "get", mapOf( +// "src" to target, +// "dest" to downloadedFile, +// "verbose" to true, +// ) +// ) +// +// val json = downloadedFile.readText() +// val prettyJson = groovy.json.JsonOutput.prettyPrint(json) +// +// apiFile.asFile.writeText(prettyJson) +// +// logger.lifecycle("Downloaded Factorio API json: $apiFile") +// } +//} \ No newline at end of file diff --git a/modules/mod/src/main/typescript/package-lock.json b/modules/mod/src/main/typescript/package-lock.json index b0ae77b..621dcc5 100644 --- a/modules/mod/src/main/typescript/package-lock.json +++ b/modules/mod/src/main/typescript/package-lock.json @@ -4,11 +4,85 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, + "@types/long": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + }, "@types/node": { "version": "12.20.33", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz", "integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw==" }, + "@types/object-hash": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/object-hash/-/object-hash-1.3.4.tgz", + "integrity": "sha512-xFdpkAkikBgqBdG9vIlsqffDV8GpvnPEzs0IUtr1v3BEB97ijsFQ4RXVbUZwjFThhB4MDSTUfvmxUD5PGx0wXA==" + }, + "@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==" + }, + "dataloader": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz", + "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==" + }, "enhanced-resolve": { "version": "5.8.3", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", @@ -44,16 +118,63 @@ "has": "^1.0.3" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "lua-types": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.11.0.tgz", "integrity": "sha512-J/8qHrOjkZuPBDhnuAg0DWoaJEImqXNzgEnUigCTVrSVCcchM5Y5zpcI3aWAZPhuZlb0QKC/f3nc7VGmZmBg7w==" }, + "object-hash": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", + "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==" + }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, + "prettier": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==" + }, + "protobufjs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", + "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "16.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz", + "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==" + } + } + }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -73,6 +194,38 @@ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, + "ts-poet": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/ts-poet/-/ts-poet-4.6.1.tgz", + "integrity": "sha512-DXJ+mBJIDp+jiaUgB4N5I/sczHHDU2FWacdbDNVAVS4Mh4hb7ckpvUWVW7m7/nAOcjR0r4Wt+7AoO7FeJKExfA==", + "requires": { + "@types/prettier": "^1.19.0", + "lodash": "^4.17.15", + "prettier": "^2.0.2" + } + }, + "ts-proto": { + "version": "1.83.3", + "resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-1.83.3.tgz", + "integrity": "sha512-r6MKFjoc4Og2kB4cNJ/bddLebdIwhouG5plu0Rry1jJMEqp2GKA7AE4FrR/FnTCIGbNPYP4622lBqckZd7UHcQ==", + "requires": { + "@types/object-hash": "^1.3.0", + "dataloader": "^1.4.0", + "object-hash": "^1.3.1", + "protobufjs": "^6.8.8", + "ts-poet": "^4.5.0", + "ts-proto-descriptors": "^1.2.1" + } + }, + "ts-proto-descriptors": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/ts-proto-descriptors/-/ts-proto-descriptors-1.3.1.tgz", + "integrity": "sha512-Cybb3fqceMwA6JzHdC32dIo8eVGVmXrM6TWhdk1XQVVHT/6OQqk0ioyX1dIdu3rCIBhRmWUhUE4HsyK+olmgMw==", + "requires": { + "long": "^4.0.0", + "protobufjs": "^6.8.8" + } + }, "typed-factorio": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.8.0.tgz", diff --git a/modules/mod/src/main/typescript/package.json b/modules/mod/src/main/typescript/package.json index 4a2cd61..dd451c1 100644 --- a/modules/mod/src/main/typescript/package.json +++ b/modules/mod/src/main/typescript/package.json @@ -14,7 +14,8 @@ "lua-types": "^2.11.0", "@types/node": "^12.0.8", "typescript-to-lua": "1.0.1", - "typed-factorio": "0.8.0" + "typed-factorio": "0.8.0", + "ts-proto": "1.83.3" }, "peerDependencies": {}, "optionalDependencies": {}, diff --git a/modules/mod/src/main/typescript/proto/FactorioServerLogRecord.ts b/modules/mod/src/main/typescript/proto/FactorioServerLogRecord.ts index c305e96..009a229 100644 --- a/modules/mod/src/main/typescript/proto/FactorioServerLogRecord.ts +++ b/modules/mod/src/main/typescript/proto/FactorioServerLogRecord.ts @@ -1,6 +1,6 @@ /* eslint-disable */ - - +import Long from "long"; +import _m0 from "protobufjs/minimal"; export interface FactorioServerLogRecord { modVersion: string; @@ -82,4 +82,826 @@ export interface Colour { alpha: number; } +const baseFactorioServerLogRecord: object = { + modVersion: "", + tick: 0, + eventType: "", +}; +export const FactorioServerLogRecord = { + encode( + message: FactorioServerLogRecord, + writer: _m0.Writer = _m0.Writer.create() + ): _m0.Writer { + if (message.modVersion !== "") { + writer.uint32(10).string(message.modVersion); + } + if (message.tick !== 0) { + writer.uint32(16).uint32(message.tick); + } + if (message.eventType !== "") { + writer.uint32(26).string(message.eventType); + } + if (message.data !== undefined) { + FactorioLuaObject.encode(message.data, writer.uint32(34).fork()).ldelim(); + } + return writer; + }, + + decode( + input: _m0.Reader | Uint8Array, + length?: number + ): FactorioServerLogRecord { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = { + ...baseFactorioServerLogRecord, + } as FactorioServerLogRecord; + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.modVersion = reader.string(); + break; + case 2: + message.tick = reader.uint32(); + break; + case 3: + message.eventType = reader.string(); + break; + case 4: + message.data = FactorioLuaObject.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromPartial( + object: DeepPartial + ): FactorioServerLogRecord { + const message = { + ...baseFactorioServerLogRecord, + } as FactorioServerLogRecord; + if (object.modVersion !== undefined && object.modVersion !== null) { + message.modVersion = object.modVersion; + } else { + message.modVersion = ""; + } + if (object.tick !== undefined && object.tick !== null) { + message.tick = object.tick; + } else { + message.tick = 0; + } + if (object.eventType !== undefined && object.eventType !== null) { + message.eventType = object.eventType; + } else { + message.eventType = ""; + } + if (object.data !== undefined && object.data !== null) { + message.data = FactorioLuaObject.fromPartial(object.data); + } else { + message.data = undefined; + } + return message; + }, +}; + +const baseFactorioLuaObject: object = { objectName: "" }; + +export const FactorioLuaObject = { + encode( + message: FactorioLuaObject, + writer: _m0.Writer = _m0.Writer.create() + ): _m0.Writer { + if (message.objectName !== "") { + writer.uint32(10).string(message.objectName); + } + if (message.luaControl !== undefined) { + LuaControl.encode(message.luaControl, writer.uint32(18).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): FactorioLuaObject { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = { ...baseFactorioLuaObject } as FactorioLuaObject; + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.objectName = reader.string(); + break; + case 2: + message.luaControl = LuaControl.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromPartial(object: DeepPartial): FactorioLuaObject { + const message = { ...baseFactorioLuaObject } as FactorioLuaObject; + if (object.objectName !== undefined && object.objectName !== null) { + message.objectName = object.objectName; + } else { + message.objectName = ""; + } + if (object.luaControl !== undefined && object.luaControl !== null) { + message.luaControl = LuaControl.fromPartial(object.luaControl); + } else { + message.luaControl = undefined; + } + return message; + }, +}; + +const baseLuaControl: object = { + isPlayer: false, + surfaceIndex: 0, + forceIndex: 0, +}; + +export const LuaControl = { + encode( + message: LuaControl, + writer: _m0.Writer = _m0.Writer.create() + ): _m0.Writer { + if (message.isPlayer === true) { + writer.uint32(16).bool(message.isPlayer); + } + if (message.surfaceIndex !== 0) { + writer.uint32(24).uint32(message.surfaceIndex); + } + if (message.position !== undefined) { + Position.encode(message.position, writer.uint32(34).fork()).ldelim(); + } + if (message.forceIndex !== 0) { + writer.uint32(40).uint32(message.forceIndex); + } + if (message.player !== undefined) { + LuaPlayer.encode(message.player, writer.uint32(82).fork()).ldelim(); + } + if (message.entity !== undefined) { + LuaEntity.encode(message.entity, writer.uint32(90).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): LuaControl { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = { ...baseLuaControl } as LuaControl; + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 2: + message.isPlayer = reader.bool(); + break; + case 3: + message.surfaceIndex = reader.uint32(); + break; + case 4: + message.position = Position.decode(reader, reader.uint32()); + break; + case 5: + message.forceIndex = reader.uint32(); + break; + case 10: + message.player = LuaPlayer.decode(reader, reader.uint32()); + break; + case 11: + message.entity = LuaEntity.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromPartial(object: DeepPartial): LuaControl { + const message = { ...baseLuaControl } as LuaControl; + if (object.isPlayer !== undefined && object.isPlayer !== null) { + message.isPlayer = object.isPlayer; + } else { + message.isPlayer = false; + } + if (object.surfaceIndex !== undefined && object.surfaceIndex !== null) { + message.surfaceIndex = object.surfaceIndex; + } else { + message.surfaceIndex = 0; + } + if (object.position !== undefined && object.position !== null) { + message.position = Position.fromPartial(object.position); + } else { + message.position = undefined; + } + if (object.forceIndex !== undefined && object.forceIndex !== null) { + message.forceIndex = object.forceIndex; + } else { + message.forceIndex = 0; + } + if (object.player !== undefined && object.player !== null) { + message.player = LuaPlayer.fromPartial(object.player); + } else { + message.player = undefined; + } + if (object.entity !== undefined && object.entity !== null) { + message.entity = LuaEntity.fromPartial(object.entity); + } else { + message.entity = undefined; + } + return message; + }, +}; + +const baseLuaPlayer: object = { + index: 0, + name: "", + data: 0, + isConnected: false, + isAdmin: false, + afkTimeTicks: 0, + onlineTimeTicks: 0, + lastOnlineTicks: 0, +}; + +export const LuaPlayer = { + encode( + message: LuaPlayer, + writer: _m0.Writer = _m0.Writer.create() + ): _m0.Writer { + if (message.index !== 0) { + writer.uint32(8).uint32(message.index); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + writer.uint32(34).fork(); + for (const v of message.data) { + writer.int32(v); + } + writer.ldelim(); + if (message.colour !== undefined) { + Colour.encode(message.colour, writer.uint32(66).fork()).ldelim(); + } + if (message.isConnected === true) { + writer.uint32(80).bool(message.isConnected); + } + if (message.isAdmin === true) { + writer.uint32(88).bool(message.isAdmin); + } + if (message.afkTimeTicks !== 0) { + writer.uint32(800).uint32(message.afkTimeTicks); + } + if (message.onlineTimeTicks !== 0) { + writer.uint32(808).uint32(message.onlineTimeTicks); + } + if (message.lastOnlineTicks !== 0) { + writer.uint32(816).uint32(message.lastOnlineTicks); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): LuaPlayer { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = { ...baseLuaPlayer } as LuaPlayer; + message.data = []; + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.index = reader.uint32(); + break; + case 2: + message.name = reader.string(); + break; + case 4: + if ((tag & 7) === 2) { + const end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) { + message.data.push(reader.int32()); + } + } else { + message.data.push(reader.int32()); + } + break; + case 8: + message.colour = Colour.decode(reader, reader.uint32()); + break; + case 10: + message.isConnected = reader.bool(); + break; + case 11: + message.isAdmin = reader.bool(); + break; + case 100: + message.afkTimeTicks = reader.uint32(); + break; + case 101: + message.onlineTimeTicks = reader.uint32(); + break; + case 102: + message.lastOnlineTicks = reader.uint32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromPartial(object: DeepPartial): LuaPlayer { + const message = { ...baseLuaPlayer } as LuaPlayer; + message.data = []; + if (object.index !== undefined && object.index !== null) { + message.index = object.index; + } else { + message.index = 0; + } + if (object.name !== undefined && object.name !== null) { + message.name = object.name; + } else { + message.name = ""; + } + if (object.data !== undefined && object.data !== null) { + for (const e of object.data) { + message.data.push(e); + } + } + if (object.colour !== undefined && object.colour !== null) { + message.colour = Colour.fromPartial(object.colour); + } else { + message.colour = undefined; + } + if (object.isConnected !== undefined && object.isConnected !== null) { + message.isConnected = object.isConnected; + } else { + message.isConnected = false; + } + if (object.isAdmin !== undefined && object.isAdmin !== null) { + message.isAdmin = object.isAdmin; + } else { + message.isAdmin = false; + } + if (object.afkTimeTicks !== undefined && object.afkTimeTicks !== null) { + message.afkTimeTicks = object.afkTimeTicks; + } else { + message.afkTimeTicks = 0; + } + if ( + object.onlineTimeTicks !== undefined && + object.onlineTimeTicks !== null + ) { + message.onlineTimeTicks = object.onlineTimeTicks; + } else { + message.onlineTimeTicks = 0; + } + if ( + object.lastOnlineTicks !== undefined && + object.lastOnlineTicks !== null + ) { + message.lastOnlineTicks = object.lastOnlineTicks; + } else { + message.lastOnlineTicks = 0; + } + return message; + }, +}; + +const baseLuaEntity: object = { + name: "", + type: "", + status: "", + isActive: false, + isMoving: false, +}; + +export const LuaEntity = { + encode( + message: LuaEntity, + writer: _m0.Writer = _m0.Writer.create() + ): _m0.Writer { + if (message.unitNumber !== undefined) { + writer.uint32(8).uint32(message.unitNumber); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.type !== "") { + writer.uint32(26).string(message.type); + } + if (message.status !== "") { + writer.uint32(34).string(message.status); + } + if (message.isActive === true) { + writer.uint32(64).bool(message.isActive); + } + if (message.isMoving === true) { + writer.uint32(72).bool(message.isMoving); + } + if (message.playerIndex !== undefined) { + writer.uint32(400).uint32(message.playerIndex); + } + if (message.lastUserIndex !== undefined) { + writer.uint32(408).uint32(message.lastUserIndex); + } + if (message.colour !== undefined) { + Colour.encode(message.colour, writer.uint32(802).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): LuaEntity { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = { ...baseLuaEntity } as LuaEntity; + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.unitNumber = reader.uint32(); + break; + case 2: + message.name = reader.string(); + break; + case 3: + message.type = reader.string(); + break; + case 4: + message.status = reader.string(); + break; + case 8: + message.isActive = reader.bool(); + break; + case 9: + message.isMoving = reader.bool(); + break; + case 50: + message.playerIndex = reader.uint32(); + break; + case 51: + message.lastUserIndex = reader.uint32(); + break; + case 100: + message.colour = Colour.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromPartial(object: DeepPartial): LuaEntity { + const message = { ...baseLuaEntity } as LuaEntity; + if (object.unitNumber !== undefined && object.unitNumber !== null) { + message.unitNumber = object.unitNumber; + } else { + message.unitNumber = undefined; + } + if (object.name !== undefined && object.name !== null) { + message.name = object.name; + } else { + message.name = ""; + } + if (object.type !== undefined && object.type !== null) { + message.type = object.type; + } else { + message.type = ""; + } + if (object.status !== undefined && object.status !== null) { + message.status = object.status; + } else { + message.status = ""; + } + if (object.isActive !== undefined && object.isActive !== null) { + message.isActive = object.isActive; + } else { + message.isActive = false; + } + if (object.isMoving !== undefined && object.isMoving !== null) { + message.isMoving = object.isMoving; + } else { + message.isMoving = false; + } + if (object.playerIndex !== undefined && object.playerIndex !== null) { + message.playerIndex = object.playerIndex; + } else { + message.playerIndex = undefined; + } + if (object.lastUserIndex !== undefined && object.lastUserIndex !== null) { + message.lastUserIndex = object.lastUserIndex; + } else { + message.lastUserIndex = undefined; + } + if (object.colour !== undefined && object.colour !== null) { + message.colour = Colour.fromPartial(object.colour); + } else { + message.colour = undefined; + } + return message; + }, +}; + +const baseLuaSurface: object = { index: 0, name: "", daytime: 0 }; + +export const LuaSurface = { + encode( + message: LuaSurface, + writer: _m0.Writer = _m0.Writer.create() + ): _m0.Writer { + if (message.index !== 0) { + writer.uint32(8).uint32(message.index); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.daytime !== 0) { + writer.uint32(29).float(message.daytime); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): LuaSurface { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = { ...baseLuaSurface } as LuaSurface; + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.index = reader.uint32(); + break; + case 2: + message.name = reader.string(); + break; + case 3: + message.daytime = reader.float(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromPartial(object: DeepPartial): LuaSurface { + const message = { ...baseLuaSurface } as LuaSurface; + if (object.index !== undefined && object.index !== null) { + message.index = object.index; + } else { + message.index = 0; + } + if (object.name !== undefined && object.name !== null) { + message.name = object.name; + } else { + message.name = ""; + } + if (object.daytime !== undefined && object.daytime !== null) { + message.daytime = object.daytime; + } else { + message.daytime = 0; + } + return message; + }, +}; + +const baseLuaForce: object = { index: 0, forceName: "", playerIds: 0 }; + +export const LuaForce = { + encode( + message: LuaForce, + writer: _m0.Writer = _m0.Writer.create() + ): _m0.Writer { + if (message.index !== 0) { + writer.uint32(8).uint32(message.index); + } + if (message.forceName !== "") { + writer.uint32(18).string(message.forceName); + } + writer.uint32(802).fork(); + for (const v of message.playerIds) { + writer.uint32(v); + } + writer.ldelim(); + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): LuaForce { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = { ...baseLuaForce } as LuaForce; + message.playerIds = []; + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.index = reader.uint32(); + break; + case 2: + message.forceName = reader.string(); + break; + case 100: + if ((tag & 7) === 2) { + const end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) { + message.playerIds.push(reader.uint32()); + } + } else { + message.playerIds.push(reader.uint32()); + } + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromPartial(object: DeepPartial): LuaForce { + const message = { ...baseLuaForce } as LuaForce; + message.playerIds = []; + if (object.index !== undefined && object.index !== null) { + message.index = object.index; + } else { + message.index = 0; + } + if (object.forceName !== undefined && object.forceName !== null) { + message.forceName = object.forceName; + } else { + message.forceName = ""; + } + if (object.playerIds !== undefined && object.playerIds !== null) { + for (const e of object.playerIds) { + message.playerIds.push(e); + } + } + return message; + }, +}; + +const basePosition: object = { x: 0, y: 0 }; + +export const Position = { + encode( + message: Position, + writer: _m0.Writer = _m0.Writer.create() + ): _m0.Writer { + if (message.x !== 0) { + writer.uint32(8).int32(message.x); + } + if (message.y !== 0) { + writer.uint32(16).int32(message.y); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): Position { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = { ...basePosition } as Position; + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.x = reader.int32(); + break; + case 2: + message.y = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromPartial(object: DeepPartial): Position { + const message = { ...basePosition } as Position; + if (object.x !== undefined && object.x !== null) { + message.x = object.x; + } else { + message.x = 0; + } + if (object.y !== undefined && object.y !== null) { + message.y = object.y; + } else { + message.y = 0; + } + return message; + }, +}; + +const baseColour: object = { red: 0, green: 0, blue: 0, alpha: 0 }; + +export const Colour = { + encode( + message: Colour, + writer: _m0.Writer = _m0.Writer.create() + ): _m0.Writer { + if (message.red !== 0) { + writer.uint32(13).float(message.red); + } + if (message.green !== 0) { + writer.uint32(21).float(message.green); + } + if (message.blue !== 0) { + writer.uint32(29).float(message.blue); + } + if (message.alpha !== 0) { + writer.uint32(37).float(message.alpha); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): Colour { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = { ...baseColour } as Colour; + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.red = reader.float(); + break; + case 2: + message.green = reader.float(); + break; + case 3: + message.blue = reader.float(); + break; + case 4: + message.alpha = reader.float(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromPartial(object: DeepPartial): Colour { + const message = { ...baseColour } as Colour; + if (object.red !== undefined && object.red !== null) { + message.red = object.red; + } else { + message.red = 0; + } + if (object.green !== undefined && object.green !== null) { + message.green = object.green; + } else { + message.green = 0; + } + if (object.blue !== undefined && object.blue !== null) { + message.blue = object.blue; + } else { + message.blue = 0; + } + if (object.alpha !== undefined && object.alpha !== null) { + message.alpha = object.alpha; + } else { + message.alpha = 0; + } + return message; + }, +}; + +type Builtin = + | Date + | Function + | Uint8Array + | string + | number + | boolean + | undefined; +type DeepPartial = T extends Builtin + ? T + : T extends Array + ? Array> + : T extends ReadonlyArray + ? ReadonlyArray> + : T extends {} + ? { [K in keyof T]?: DeepPartial } + : Partial; + +if (_m0.util.Long !== Long) { + _m0.util.Long = Long as any; + _m0.configure(); +} diff --git a/modules/mod/src/main/typescript/tsconfig.json b/modules/mod/src/main/typescript/tsconfig.json index 4b05c31..989f0ae 100644 --- a/modules/mod/src/main/typescript/tsconfig.json +++ b/modules/mod/src/main/typescript/tsconfig.json @@ -10,7 +10,9 @@ "types": [ "typescript-to-lua/language-extensions", "lua-types/5.2", - "typed-factorio/runtime" + "typed-factorio/runtime", + "protobufjs/minimal.d.ts", + "@types/long" ], "explainFiles": true, "forceConsistentCasingInFileNames": true, @@ -22,7 +24,8 @@ "strict": true, "strictFunctionTypes": true, "strictNullChecks": true, - "traceResolution": true + "traceResolution": true, + "esModuleInterop": true }, "tstl": { "luaTarget": "5.2", @@ -38,7 +41,6 @@ "node_modules" ], "exactOptionalPropertyTypes": true, - "luaTarget": "5.2", "skipLibCheck": true, "skipDefaultLibCheck": true, "types": [ From 7dd7baef345c8bd910f74942e211494d73883b60 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 3 Nov 2021 17:07:59 +0100 Subject: [PATCH 076/629] delete protobuf stuff, and unused code --- .../dev/adamko/gradle/pbandg/Constants.kt | 20 - .../pbandg/ProtobufCompilerDependency.kt | 22 - .../gradle/pbandg/pattern/IntelliJPattern.kt | 53 - .../pattern/KotlinJvmProjectConfiguration.kt | 46 - ...KotlinMultiplatformProjectConfiguration.kt | 66 - .../adamko/gradle/pbandg/pb-and-g.gradle.kts | 88 - .../gradle/pbandg/settings/PBAndGSettings.kt | 103 - .../gradle/pbandg/task/ProtobufCompileTask.kt | 86 - .../task/ProtobufPrepareLibrariesTask.kt | 39 - .../gradle/pbandg/task/ProtocPrepareTask.kt | 65 - .../pbandg/task/options/ProtocOutput.kt | 25 - .../build.gradle.kts | 92 - .../src/proto/FactorioServerLogRecord.proto | 94 - .../FactorioEvent.kt | 63 - .../JsonPrimitiveType.kt | 31 - .../xsrc/main/kotlin/PlayerModel.kt | 55 - modules/mod/build.gradle.kts | 88 +- .../mod/src/main/typescript/package-lock.json | 153 - modules/mod/src/main/typescript/package.json | 20 +- .../proto/FactorioServerLogRecord.ts | 907 - modules/mod/src/main/typescript/tsconfig.json | 28 +- modules/mod2/build.gradle.kts | 162 - .../dukat-custom/5.2-only.module_lua-types.kt | 17 - .../5.2-plus-or-jit.module_lua-types.kt | 37 - .../dukat-custom/5.2-plus.module_lua-types.kt | 22 - .../bit32/5.2-only.bit32.module_lua-types.kt | 41 - .../builtin-types.module_typed-factorio.kt | 51 - .../classes.module_typed-factorio.kt | 5729 ----- .../concepts.module_typed-factorio.kt | 2924 --- .../coroutine.coroutine.module_lua-types.kt | 30 - .../debug/debug.debug.module_lua-types.kt | 162 - ....control_behavior.module_typed-factorio.kt | 38 - ...behavior.inserter.module_typed-factorio.kt | 30 - ...rol_behavior.lamp.module_typed-factorio.kt | 21 - ...ogistic_container.module_typed-factorio.kt | 22 - ...vior.mining_drill.module_typed-factorio.kt | 22 - ...or.transport_belt.module_typed-factorio.kt | 22 - ...construction_item.module_typed-factorio.kt | 34 - .../defines.defines.module_typed-factorio.kt | 668 - ...fficulty_settings.module_typed-factorio.kt | 27 - ...es.defines.events.module_typed-factorio.kt | 366 - ...es.defines.riding.module_typed-factorio.kt | 30 - modules/mod2/dukat-custom/eventId.kt | 11 - .../events.module_typed-factorio.kt | 1574 -- .../global-objects.module_typed-factorio.kt | 29 - .../dukat-custom/global.module_lua-types.kt | 95 - .../index.module_typescript-to-lua.kt | 43 - .../mod2/dukat-custom/io.module_lua-types.kt | 28 - .../dukat-custom/io/io.io.module_lua-types.kt | 57 - .../dukat-custom/io/nonDeclarations.io.kt | 18 - ...ariesAndFunctions.module_typed-factorio.kt | 135 - .../math/math.math.module_lua-types.kt | 75 - .../metatable.module_lua-types.kt | 51 - .../mod-gui.mod_gui.module_typed-factorio.kt | 29 - .../dukat-custom/modules.module_lua-types.kt | 17 - .../mod2/dukat-custom/os.module_lua-types.kt | 45 - .../dukat-custom/os/os.os.module_lua-types.kt | 56 - .../modules.package.module_lua-types.kt | 34 - .../pairs.module_typed-factorio.kt | 22 - ...Functions.serpent.module_typed-factorio.kt | 32 - .../string/string.string.module_lua-types.kt | 63 - .../table/table.table.module_lua-types.kt | 39 - modules/mod2/dukat-custom/tsstdlib/lib.dom.kt | 31 - .../tsstdlib/lib.es2015.iterable.kt | 40 - modules/mod2/dukat-custom/tsstdlib/lib.es5.kt | 76 - .../types.module_typed-factorio.kt | 91 - .../util.util.table.module_typed-factorio.kt | 21 - .../util/util.util.module_typed-factorio.kt | 110 - ...ompilerOptions.module_typescript-to-lua.kt | 75 - .../LuaAST.module_typescript-to-lua.kt | 485 - .../LuaLib.module_typescript-to-lua.kt | 111 - .../LuaPrinter.module_typescript-to-lua.kt | 101 - .../context.module_typescript-to-lua.kt | 80 - .../index.module_typescript-to-lua.kt | 39 - .../mod2/externals/lib.es2015.collection.kt | 49 - modules/mod2/externals/lib.es2015.iterable.kt | 54 - .../externals/lib.es5.Intl.module_dukat.kt | 220 - modules/mod2/externals/lib.es5.kt | 69 - modules/mod2/externals/lib.scripthost.kt | 20 - modules/mod2/externals/nonDeclarations.ts.kt | 114 - ...tput-collector.module_typescript-to-lua.kt | 33 - .../parse.module_typescript-to-lua.kt | 21 - .../plugins.module_typescript-to-lua.kt | 24 - .../report.module_typescript-to-lua.kt | 48 - .../externals/source-map.module_source-map.kt | 192 - .../transpile.module_typescript-to-lua.kt | 40 - .../transpiler.module_typescript-to-lua.kt | 55 - .../tsconfig.module_typescript-to-lua.kt | 19 - .../externals/typescript.module_typescript.kt | 19 - ...ipt.ts.ScriptSnapshot.module_typescript.kt | 20 - .../typescript.ts.module_typescript.kt | 8487 ------- .../typescript.ts.server.module_typescript.kt | 104 - .../utils.module_typescript-to-lua.kt | 46 - .../visitors.module_typescript-to-lua.kt | 38 - modules/mod2/src/main/kotlin/events.kt | 11 - modules/mod2/typed-factorio/README.md | 113 - modules/mod2/typed-factorio/data/types.d.ts | 13 - .../generated/builtin-types.d.ts | 66 - .../typed-factorio/generated/classes.d.ts | 20023 ---------------- .../typed-factorio/generated/concepts.d.ts | 5635 ----- .../typed-factorio/generated/defines.d.ts | 1642 -- .../mod2/typed-factorio/generated/events.d.ts | 2976 --- .../generated/global-objects.d.ts | 51 - .../mod2/typed-factorio/generated/index.d.ts | 7 - modules/mod2/typed-factorio/package.json | 39 - .../mod2/typed-factorio/runtime/index.d.ts | 10 - .../runtime/librariesAndFunctions.d.ts | 123 - .../mod2/typed-factorio/runtime/mod-gui.d.ts | 11 - .../mod2/typed-factorio/runtime/pairs.d.ts | 13 - modules/mod2/typed-factorio/runtime/util.d.ts | 120 - .../mod2/typed-factorio/settings/types.d.ts | 120 - modules/protoc-gradle-plugin/build.gradle.kts | 77 - .../dev/adamko/gradle/pbandg/ProtocPlugin.kt | 294 - modules/server/build.gradle.kts | 60 - .../server/src/main/kotlin/com/example/App.kt | 38 - .../server/src/main/resources/css/kvapp.css | 0 .../src/main/resources/i18n/messages-en.po | 23 - .../src/main/resources/i18n/messages-pl.po | 23 - .../src/main/resources/i18n/messages.pot | 8 - modules/server/src/main/web/index.html | 12 - .../test/kotlin/test/com/example/AppSpec.kt | 15 - modules/server/webpack.config.d/bootstrap.js | 3 - modules/server/webpack.config.d/css.js | 1 - modules/server/webpack.config.d/file.js | 6 - modules/server/webpack.config.d/handlebars.js | 6 - modules/server/webpack.config.d/jquery.js | 9 - modules/server/webpack.config.d/moment.js | 15 - modules/server/webpack.config.d/webpack.js | 15 - src/jsMain/kotlin/main.kt | 8 - src/nativeMain/kotlin/Main.kt | 3 - src/nativeMain/kotlin/example/hello.kt | 27 - xbuild.gradle.kts | 124 - 132 files changed, 16 insertions(+), 57708 deletions(-) delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/Constants.kt delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/ProtobufCompilerDependency.kt delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/IntelliJPattern.kt delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinJvmProjectConfiguration.kt delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/settings/PBAndGSettings.kt delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufCompileTask.kt delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufPrepareLibrariesTask.kt delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtocPrepareTask.kt delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/options/ProtocOutput.kt delete mode 100644 modules/factorio-events-data-model/src/proto/FactorioServerLogRecord.proto delete mode 100644 modules/factorio-events-data-model/xsrc/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt delete mode 100644 modules/factorio-events-data-model/xsrc/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt delete mode 100644 modules/factorio-events-data-model/xsrc/main/kotlin/PlayerModel.kt delete mode 100644 modules/mod/src/main/typescript/proto/FactorioServerLogRecord.ts delete mode 100644 modules/mod2/build.gradle.kts delete mode 100644 modules/mod2/dukat-custom/5.2-only.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/5.2-plus-or-jit.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/5.2-plus.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/bit32/5.2-only.bit32.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/builtin-types.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/classes.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/concepts.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/coroutine/coroutine.coroutine.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/debug/debug.debug.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/defines/control_behavior/defines.defines.control_behavior.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/defines/control_behavior/inserter/defines.defines.control_behavior.inserter.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/defines/control_behavior/lamp/defines.defines.control_behavior.lamp.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/defines/control_behavior/logistic_container/defines.defines.control_behavior.logistic_container.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/defines/control_behavior/mining_drill/defines.defines.control_behavior.mining_drill.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/defines/control_behavior/transport_belt/defines.defines.control_behavior.transport_belt.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/defines/deconstruction_item/defines.defines.deconstruction_item.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/defines/defines.defines.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/defines/difficulty_settings/defines.defines.difficulty_settings.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/defines/events/defines.defines.events.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/defines/riding/defines.defines.riding.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/eventId.kt delete mode 100644 modules/mod2/dukat-custom/events.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/global-objects.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/global.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/index.module_typescript-to-lua.kt delete mode 100644 modules/mod2/dukat-custom/io.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/io/io.io.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/io/nonDeclarations.io.kt delete mode 100644 modules/mod2/dukat-custom/librariesAndFunctions.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/math/math.math.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/metatable.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/mod_gui/mod-gui.mod_gui.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/modules.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/os.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/os/os.os.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/package/modules.package.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/pairs.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/serpent/librariesAndFunctions.serpent.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/string/string.string.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/table/table.table.module_lua-types.kt delete mode 100644 modules/mod2/dukat-custom/tsstdlib/lib.dom.kt delete mode 100644 modules/mod2/dukat-custom/tsstdlib/lib.es2015.iterable.kt delete mode 100644 modules/mod2/dukat-custom/tsstdlib/lib.es5.kt delete mode 100644 modules/mod2/dukat-custom/types.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/util/table/util.util.table.module_typed-factorio.kt delete mode 100644 modules/mod2/dukat-custom/util/util.util.module_typed-factorio.kt delete mode 100644 modules/mod2/externals/CompilerOptions.module_typescript-to-lua.kt delete mode 100644 modules/mod2/externals/LuaAST.module_typescript-to-lua.kt delete mode 100644 modules/mod2/externals/LuaLib.module_typescript-to-lua.kt delete mode 100644 modules/mod2/externals/LuaPrinter.module_typescript-to-lua.kt delete mode 100644 modules/mod2/externals/context.module_typescript-to-lua.kt delete mode 100644 modules/mod2/externals/index.module_typescript-to-lua.kt delete mode 100644 modules/mod2/externals/lib.es2015.collection.kt delete mode 100644 modules/mod2/externals/lib.es2015.iterable.kt delete mode 100644 modules/mod2/externals/lib.es5.Intl.module_dukat.kt delete mode 100644 modules/mod2/externals/lib.es5.kt delete mode 100644 modules/mod2/externals/lib.scripthost.kt delete mode 100644 modules/mod2/externals/nonDeclarations.ts.kt delete mode 100644 modules/mod2/externals/output-collector.module_typescript-to-lua.kt delete mode 100644 modules/mod2/externals/parse.module_typescript-to-lua.kt delete mode 100644 modules/mod2/externals/plugins.module_typescript-to-lua.kt delete mode 100644 modules/mod2/externals/report.module_typescript-to-lua.kt delete mode 100644 modules/mod2/externals/source-map.module_source-map.kt delete mode 100644 modules/mod2/externals/transpile.module_typescript-to-lua.kt delete mode 100644 modules/mod2/externals/transpiler.module_typescript-to-lua.kt delete mode 100644 modules/mod2/externals/tsconfig.module_typescript-to-lua.kt delete mode 100644 modules/mod2/externals/typescript.module_typescript.kt delete mode 100644 modules/mod2/externals/typescript.ts.ScriptSnapshot.module_typescript.kt delete mode 100644 modules/mod2/externals/typescript.ts.module_typescript.kt delete mode 100644 modules/mod2/externals/typescript.ts.server.module_typescript.kt delete mode 100644 modules/mod2/externals/utils.module_typescript-to-lua.kt delete mode 100644 modules/mod2/externals/visitors.module_typescript-to-lua.kt delete mode 100644 modules/mod2/src/main/kotlin/events.kt delete mode 100644 modules/mod2/typed-factorio/README.md delete mode 100644 modules/mod2/typed-factorio/data/types.d.ts delete mode 100644 modules/mod2/typed-factorio/generated/builtin-types.d.ts delete mode 100644 modules/mod2/typed-factorio/generated/classes.d.ts delete mode 100644 modules/mod2/typed-factorio/generated/concepts.d.ts delete mode 100644 modules/mod2/typed-factorio/generated/defines.d.ts delete mode 100644 modules/mod2/typed-factorio/generated/events.d.ts delete mode 100644 modules/mod2/typed-factorio/generated/global-objects.d.ts delete mode 100644 modules/mod2/typed-factorio/generated/index.d.ts delete mode 100644 modules/mod2/typed-factorio/package.json delete mode 100644 modules/mod2/typed-factorio/runtime/index.d.ts delete mode 100644 modules/mod2/typed-factorio/runtime/librariesAndFunctions.d.ts delete mode 100644 modules/mod2/typed-factorio/runtime/mod-gui.d.ts delete mode 100644 modules/mod2/typed-factorio/runtime/pairs.d.ts delete mode 100644 modules/mod2/typed-factorio/runtime/util.d.ts delete mode 100644 modules/mod2/typed-factorio/settings/types.d.ts delete mode 100644 modules/protoc-gradle-plugin/build.gradle.kts delete mode 100644 modules/protoc-gradle-plugin/src/main/kotlin/dev/adamko/gradle/pbandg/ProtocPlugin.kt delete mode 100644 modules/server/build.gradle.kts delete mode 100644 modules/server/src/main/kotlin/com/example/App.kt delete mode 100644 modules/server/src/main/resources/css/kvapp.css delete mode 100644 modules/server/src/main/resources/i18n/messages-en.po delete mode 100644 modules/server/src/main/resources/i18n/messages-pl.po delete mode 100644 modules/server/src/main/resources/i18n/messages.pot delete mode 100644 modules/server/src/main/web/index.html delete mode 100644 modules/server/src/test/kotlin/test/com/example/AppSpec.kt delete mode 100644 modules/server/webpack.config.d/bootstrap.js delete mode 100644 modules/server/webpack.config.d/css.js delete mode 100644 modules/server/webpack.config.d/file.js delete mode 100644 modules/server/webpack.config.d/handlebars.js delete mode 100644 modules/server/webpack.config.d/jquery.js delete mode 100644 modules/server/webpack.config.d/moment.js delete mode 100644 modules/server/webpack.config.d/webpack.js delete mode 100644 src/jsMain/kotlin/main.kt delete mode 100644 src/nativeMain/kotlin/Main.kt delete mode 100644 src/nativeMain/kotlin/example/hello.kt delete mode 100644 xbuild.gradle.kts diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/Constants.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/Constants.kt deleted file mode 100644 index 95d8bbc..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/Constants.kt +++ /dev/null @@ -1,20 +0,0 @@ -package dev.adamko.gradle.pbandg - -import org.gradle.api.Project -import org.gradle.api.file.Directory -import org.gradle.api.file.ProjectLayout -import org.gradle.api.provider.Provider - -object Constants { - const val PBG_SETTINGS_NAME = "pbAndG" - const val PBG_TASK_GROUP = PBG_SETTINGS_NAME// "pb-and-g" - const val PBG_LIBS_CONF_NAME = "protobufLibrary" - const val PBG_TASK_COMPILE = "protobufCompile" - - val Project.pbAndGBuildDir: Provider - get() = layout.pbAndGBuildDir - - val ProjectLayout.pbAndGBuildDir: Provider - get() = buildDirectory.dir(PBG_TASK_GROUP) - -} diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/ProtobufCompilerDependency.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/ProtobufCompilerDependency.kt deleted file mode 100644 index fb0edbb..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/ProtobufCompilerDependency.kt +++ /dev/null @@ -1,22 +0,0 @@ -package dev.adamko.gradle.pbandg - -import dev.adamko.gradle.pbandg.settings.PBAndGSettings -import org.gradle.api.Project -import org.gradle.api.artifacts.Configuration - - -class ProtobufCompilerDependency( - project: Project, - pluginSettings: PBAndGSettings, - private val conf: Configuration = project.configurations.create("protobufCompiler") { - this.description = "Define a single dependency that provides the protoc.exe for this system" - isVisible = false - isCanBeConsumed = false - isCanBeResolved = true - isTransitive = false - - defaultDependencies { - add(pluginSettings.dependency.get()) - } - } -) : Configuration by conf diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/IntelliJPattern.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/IntelliJPattern.kt deleted file mode 100644 index 8749884..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/IntelliJPattern.kt +++ /dev/null @@ -1,53 +0,0 @@ -package dev.adamko.gradle.pbandg.pattern - -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.hasPlugin -import org.gradle.kotlin.dsl.withType -import org.gradle.plugins.ide.idea.GenerateIdeaModule -import org.gradle.plugins.ide.idea.IdeaPlugin -import org.gradle.plugins.ide.idea.model.IdeaModel - -/** - * IntelliJ requires source dirs are configured first. - * - * https://github.com/google/protobuf-gradle-plugin/blob/master/src/main/groovy/com/google/protobuf/gradle/Utils.groovy#L128 - */ -class IntelliJPattern : Plugin { - - fun isIdeaPluginPresent(project: Project) = project.plugins.hasPlugin(IdeaPlugin::class) - - override fun apply(project: Project) { - - if (!isIdeaPluginPresent(project)) { - return - } - - val genSrcDir = project.layout.buildDirectory.dir("pbAndG/generated-sources") - val ktGenSrc = genSrcDir.map { it.dir("kotlin").asFile } - val jGenSrc = genSrcDir.map { it.dir("java").asFile } - - val protoSrc = project.layout.projectDirectory.dir("src/main/proto").asFile - - project.mkdir(ktGenSrc) - project.mkdir(jGenSrc) - - project.plugins.withType { - project.extensions.configure { - module { - generatedSourceDirs.add(ktGenSrc.get()) - generatedSourceDirs.add(jGenSrc.get()) - sourceDirs.add(protoSrc) - } - } - } - - project.tasks.withType { - doFirst { - project.mkdir(ktGenSrc) - } - } - - } -} diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinJvmProjectConfiguration.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinJvmProjectConfiguration.kt deleted file mode 100644 index 4d0c429..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinJvmProjectConfiguration.kt +++ /dev/null @@ -1,46 +0,0 @@ -package dev.adamko.gradle.pbandg.pattern - -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.api.tasks.SourceSet -import org.gradle.api.tasks.SourceSetContainer -import org.gradle.kotlin.dsl.findByType -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension - -class KotlinJvmProjectConfiguration : Plugin { - - override fun apply(project: Project) { - addSourceSets(project) - } - - private fun addSourceSets(project: Project) { - - project.beforeEvaluate { - extensions.findByType()?.apply { - extensions.findByType() - ?.named(SourceSet.MAIN_SOURCE_SET_NAME) - ?.configure { - java { - srcDir(layout.buildDirectory.dir("pbAndG/generated-sources/java")) - srcDir(layout.buildDirectory.dir("pbAndG/generated-sources/kotlin")) - } - } - - } - -// val srcSet = project.extensions.getByName(SourceSet.MAIN_SOURCE_SET_NAME) -// -// project.tasks -// .withType() -// .map { it.generatedSources.get() } -// .forEach { generatedSourcesDir -> -// project.logger.lifecycle("-------\nadding generated sources $generatedSourcesDir\n-------") -// -// srcSet.java { -// srcDir(generatedSourcesDir.dir("java")) -// srcDir(generatedSourcesDir.dir("kotlin")) -// } -// } - } - } -} diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt deleted file mode 100644 index 99b5f4d..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pattern/KotlinMultiplatformProjectConfiguration.kt +++ /dev/null @@ -1,66 +0,0 @@ -package dev.adamko.gradle.pbandg.pattern - -import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.kotlin.dsl.findByType -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension - -class KotlinMultiplatformProjectConfiguration : Plugin { - - override fun apply(project: Project) { - project.afterEvaluate { - addSourceSets(project) - } - } - - private fun addSourceSets(project: Project) { - - project.extensions.findByType()?.apply { - project.logger.lifecycle("Kotlin Multiplatform source sets: ${sourceSets.joinToString { "${it.name} / ${it.kotlin.sourceDirectories.files.joinToString()}" }}") - - val jvmProto = this.sourceSets.maybeCreate("jvmProto").apply { - - kotlin.srcDir(project.layout.pbAndGBuildDir.get().dir("generated-sources/java")) - kotlin.srcDir(project.layout.pbAndGBuildDir.get().dir("generated-sources/kotlin")) - - dependsOn(sourceSets.maybeCreate("jvmMain")) - } -// - val tsProto = this.sourceSets.maybeCreate("tsProto").apply { - - kotlin.srcDir(project.layout.pbAndGBuildDir.get().dir("generated-sources/typescript")) - - dependsOn(sourceSets.maybeCreate("jsMain")) - } - -// this.sourceSets.findByName("jvmMain")?.apply { -//// protoJvm.dependsOn(this) -//// dependsOn(protoJvm) -// kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/java")) -// kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/kotlin")) -// } -// this.sourceSets.findByName("jsMain")?.apply { -//// protoTypescript.dependsOn(this) -//// dependsOn(protoTypescript) -// kotlin.srcDir(project.layout.buildDirectory.dir("pbAndG/generated-sources/typescript")) -// } - - project.logger.lifecycle("Kotlin Multiplatform source sets: ${sourceSets.joinToString { "${it.name} / ${it.kotlin.sourceDirectories.files.joinToString()}" }}") - -// -// targets .forEach { -// when (it.platformType){ -// KotlinPlatformType.jvm -> {} -// KotlinPlatformType.js -> { -// it.defaultConfigurationName -// } -// KotlinPlatformType.androidJvm -> {} -// KotlinPlatformType.common -> {} -// KotlinPlatformType.native -> {} -// } -// } - - } - } -} diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts deleted file mode 100644 index 5735a4b..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/pb-and-g.gradle.kts +++ /dev/null @@ -1,88 +0,0 @@ -package dev.adamko.gradle.pbandg - -import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir -import dev.adamko.gradle.pbandg.settings.PBAndGSettings -import dev.adamko.gradle.pbandg.task.ProtobufCompileTask -import dev.adamko.gradle.pbandg.task.ProtobufPrepareLibrariesTask - -plugins { - base -} - -// TODO investigate builtBy and sourceDirectorySet? -// project.objects.fileCollection().builtBy() -// val pbSrcSet = project.objects.sourceDirectorySet("protobuf", "protobuf") - -//if (plugins.hasPlugin(IdeaPlugin::class)) { -// IntelliJPattern().apply(project) -//} - -//plugins.withId("org.jetbrains.kotlin.jvm") { -// logger.info("Configuring Kotlin JVM plugin for PB&G") -// KotlinJvmProjectConfiguration().apply(project) -//} -// -//plugins.withId("org.jetbrains.kotlin.multiplatform") { -// logger.info("Configuring Kotlin Multiplatform plugin for PB&G") -// KotlinMultiplatformProjectConfiguration().apply(project) -//} - -val pbAndGSettings = - project.extensions.create(Constants.PBG_SETTINGS_NAME, PBAndGSettings::class, project) - -//val protocDep = ProtobufCompilerDependency(project, pbAndGSettings) -val protocDep: Configuration = project.configurations.create("protobufCompiler") { - this.description = "Define a single dependency that provides the protoc.exe for this system" - isVisible = false - isCanBeConsumed = false - isCanBeResolved = true - isTransitive = false - - defaultDependencies { - add(pbAndGSettings.dependency.get()) - } -} - -val protobufLibraryDependencies: Configuration = - project.configurations.create(Constants.PBG_LIBS_CONF_NAME) { - isVisible = true - isCanBeConsumed = false - isCanBeResolved = true - isTransitive = false - } - -project.dependencies { - protobufLibraryDependencies("com.google.protobuf:protobuf-javalite:3.19.1") { - because("This dep contains common Google .proto files that will be extracted") - } -} - -val protobufPrepareLibrariesTask = - project.tasks.register("protobufPrepareLibraries") { - librarySources.set(protobufLibraryDependencies) - } - -project.tasks.withType { - dependsOn(protocDep, protobufPrepareLibrariesTask) - protobufLibraryDirectories.add(protobufPrepareLibrariesTask.flatMap { it.librariesDirectory }) - - val exe = protocDep.singleFile - logger.debug("Configuring Protobuf task with protoc.exe: $exe") - protocExecutable.set(exe) -} - -val aggregateTask = project.tasks.register("protobufCompileAll") { - group = Constants.PBG_TASK_GROUP - - val pbCompileTasks = tasks.withType() - dependsOn(pbCompileTasks) - - val genSrcDir = project.layout.pbAndGBuildDir.map { it.dir("generated-sources") } - - from(pbCompileTasks.map { it.temporaryDir }) - into(genSrcDir) - includeEmptyDirs = false - -} - -project.tasks.assemble { dependsOn(aggregateTask) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/settings/PBAndGSettings.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/settings/PBAndGSettings.kt deleted file mode 100644 index 0023061..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/settings/PBAndGSettings.kt +++ /dev/null @@ -1,103 +0,0 @@ -package dev.adamko.gradle.pbandg.settings - - -import java.util.function.Supplier -import org.gradle.api.Project -import org.gradle.api.artifacts.ExternalModuleDependency -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.provider.Property -import org.gradle.api.provider.Provider -import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.property -import org.gradle.nativeplatform.platform.Architecture -import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform -import org.gradle.nativeplatform.platform.internal.DefaultOperatingSystem - -abstract class PBAndGSettings(private val project: Project) { - - val protocWorkingDir: DirectoryProperty = - project.objects.directoryProperty() - .convention(project.rootProject.layout.projectDirectory.dir(".gradle/protoc")) - - val protocVersion: Property = - project.objects.property(String::class).convention("3.19.1") - - val protocGroup: Property = - project.objects.property(String::class).convention("com.google.protobuf") - - val protocArtifactName: Property = - project.objects.property(String::class).convention("protoc") - - val protocArtifactExtension: Property = - project.objects.property(String::class).convention("exe") - - val operatingSystemProvider: Property> = - project.objects.property>() - .convention { DefaultNativePlatform.getCurrentOperatingSystem() } - - /** - * Should return one of - * - * * `linux` - * * `osx` - * * `windows` - */ - val operatingSystemName: Property = - project.objects - .property() - .convention(operatingSystemProvider.map { it.get().toFamilyName() }) - - private val architectureProvider: Provider = - project.provider { DefaultNativePlatform.getCurrentArchitecture() } - - /** - * Should return one of - * - * * `aarch_64` - * * `ppcle_64` - * * `x86_32` - * * `x86_64` - */ - val architectureName: Property = - project.objects - .property() - .convention(architectureProvider.map { it.name.replace("-", "_") }) - - private val classifierProvider: Provider = - project.provider { "${operatingSystemName.get()}-${architectureName.get()}" } - - /** - * Default: concatenate [operatingSystemName] and [architectureName] - * - * Should return one of: - * - * * `linux-aarch_64` - * * `linux-ppcle_64` - * * `linux-x86_64` - * * `osx-x86_32` - * * `osx-x86_64` - * * `windows-x86_32` - */ - val classifier: Property = - project.objects - .property() - .convention(classifierProvider) - - - private val dependencyProvider: Provider = - project.provider { - project.dependencies.create( - group = protocGroup.get(), - name = protocArtifactName.get(), - version = protocVersion.get(), - classifier = classifierProvider.get(), - ext = protocArtifactExtension.get(), - ) - } - - val dependency: Property = - project.objects - .property() - .convention(dependencyProvider) - -} diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufCompileTask.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufCompileTask.kt deleted file mode 100644 index bf9b84f..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufCompileTask.kt +++ /dev/null @@ -1,86 +0,0 @@ -package dev.adamko.gradle.pbandg.task - -import dev.adamko.gradle.pbandg.Constants -import org.gradle.api.DefaultTask -import org.gradle.api.file.Directory -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.ListProperty -import org.gradle.api.provider.Property -import org.gradle.api.provider.Provider -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction -import org.gradle.kotlin.dsl.property - -import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir - -abstract class ProtobufCompileTask : DefaultTask() { - - @get:InputFile - abstract val protocExecutable: RegularFileProperty - - @get:InputFiles - abstract val protobufLibraryDirectories: ListProperty - -// @get:Input -// abstract val protocOutputs: DomainObjectSet -// = project.objects.domainObjectSet(ProtocOutput::class.java) - - @get:Input - abstract val cliArgs: ListProperty - - @get:InputFile - abstract val protoFile: RegularFileProperty - - @get:Input - val cliParamProtoPath: Property = - project.objects.property().convention("--proto_path=") - - @get:OutputDirectory - val outputDir: RegularFileProperty = - project.objects.fileProperty().convention { temporaryDir } - -// @get:Internal -// val outputPath: Provider = outputDir.map { it.asFile.canonicalPath } - - init { - group = Constants.PBG_TASK_GROUP - } - - @TaskAction - fun compile() { - // prepare directories - project.mkdir(outputDir) - - project.exec { - executable(protocExecutable.asFile.get()) - workingDir(outputDir.asFile.get()) - -// val mapOutputsToOutputDir = -// protocOutputs.associateWith { outputDir.get().asFile.resolve(it.outputDirectoryName) } -// mapOutputsToOutputDir.values.forEach { project.mkdir(it) } -// -// // set args -// mapOutputsToOutputDir -// .map { (opt, dir) -> -// val optionsSuffix = if (opt.protocOptions.isBlank()) "" else ":" -// "${opt.cliParam}=${opt.protocOptions}$optionsSuffix$dir" -// } -// .also { args(it) } - args(cliArgs.get()) - - val protoPath = cliParamProtoPath.get() - val libArgs = protobufLibraryDirectories.get().map { "$protoPath${it.asFile}" } - args(libArgs) - - val targetProtoFile = protoFile.get().asFile - args("$protoPath${targetProtoFile.parentFile}") - args("$targetProtoFile") - } - - } - -} diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufPrepareLibrariesTask.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufPrepareLibrariesTask.kt deleted file mode 100644 index 9f71c27..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtobufPrepareLibrariesTask.kt +++ /dev/null @@ -1,39 +0,0 @@ -package dev.adamko.gradle.pbandg.task - -import dev.adamko.gradle.pbandg.Constants -import dev.adamko.gradle.pbandg.Constants.pbAndGBuildDir -import org.gradle.api.DefaultTask -import org.gradle.api.artifacts.Configuration -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.provider.Property -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction -import org.gradle.kotlin.dsl.property - -/** Download protobuf libs */ -abstract class ProtobufPrepareLibrariesTask : DefaultTask() { - - @get:InputFiles - val librarySources: Property = project.objects.property() - - @OutputDirectory - val librariesDirectory: DirectoryProperty = project.objects.directoryProperty() - .convention(project.pbAndGBuildDir.map { it.dir("libs") }) - - init { - group = Constants.PBG_TASK_GROUP - description = "Download and extract protobuf libs" - } - - @TaskAction - fun doTask() { - project.sync { - includeEmptyDirs = false - from(librarySources.map { conf -> conf.map { project.zipTree(it) } }) - into(librariesDirectory) - include("**/*.proto") - } - } - -} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtocPrepareTask.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtocPrepareTask.kt deleted file mode 100644 index 75445b4..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/ProtocPrepareTask.kt +++ /dev/null @@ -1,65 +0,0 @@ -package dev.adamko.gradle.pbandg.task - - -import dev.adamko.gradle.pbandg.settings.PBAndGSettings -import org.gradle.api.DefaultTask -import org.gradle.api.artifacts.Configuration -import org.gradle.api.artifacts.ExternalModuleDependency -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.Provider -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction -import org.gradle.kotlin.dsl.getByType - - -abstract class ProtocPrepareTask : DefaultTask() { - - @Internal - val protocPluginConfig: Provider = project.provider { - project.extensions.getByType() - } - - @get:OutputDirectory - val outputDirectory: DirectoryProperty = project.objects.directoryProperty() - .convention(protocPluginConfig.flatMap { it.protocWorkingDir }) - - @Internal - val protocOutput: RegularFileProperty = project.objects.fileProperty() - - @Internal - val protocDependency: Provider = - protocPluginConfig.flatMap { it.dependency } - - init { - super.setGroup("protobuf") - outputs.dir(outputDirectory) - } - - @TaskAction - fun action() { - - val protocDep: Configuration = project.configurations.create("protoc") { - isVisible = false - isCanBeConsumed = false - isCanBeResolved = true - isTransitive = false - - defaultDependencies { - add(protocDependency.get()) - } - } - - logger.lifecycle("Downloading protoc") - val resolvedProtocDep = protocDep.singleFile - logger.lifecycle("Downloaded $resolvedProtocDep") - - project.sync { - from(resolvedProtocDep) - into(outputDirectory) - logger.lifecycle("Syncing from $resolvedProtocDep to ${outputDirectory.asFile.get().canonicalPath}") - protocOutput.set(outputDirectory.asFileTree.singleFile) - } - } -} diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/options/ProtocOutput.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/options/ProtocOutput.kt deleted file mode 100644 index a5b33c5..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/pbandg/task/options/ProtocOutput.kt +++ /dev/null @@ -1,25 +0,0 @@ -package dev.adamko.gradle.pbandg.task.options - -import java.io.Serializable - - -interface ProtocOutput : Serializable { - val cliParam: String - val protocOptions: String - val outputDirectoryName: String - - data class KotlinOutput( - override val protocOptions: String = "lite", - override val outputDirectoryName: String = "kotlin", - ) : ProtocOutput { - override val cliParam: String = "--kotlin_out" - } - - data class JavaOutput( - override val protocOptions: String = "lite", - override val outputDirectoryName: String = "java", - ) : ProtocOutput { - override val cliParam: String = "--java_out" - } - -} \ No newline at end of file diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index a3f5c6c..d592108 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -1,12 +1,6 @@ -import dev.adamko.gradle.pbandg.task.ProtobufCompileTask -import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject -import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask - plugins { id("dev.adamko.factoriowebmap.archetype.base") kotlin("multiplatform") - - id("dev.adamko.gradle.pbandg.pb-and-g") } val projectId: String by project.extra @@ -43,9 +37,6 @@ kotlin { sourceSets { val jsMain by getting { - dependencies { - implementation(npm("ts-proto", "1.83.3")) - } } val jsTest by getting { @@ -69,86 +60,3 @@ kotlin { } } } - -dependencies { - protobufLibrary("com.google.protobuf:protobuf-javalite:3.19.1") -} - -val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) -val nodePath: Directory by extra { - val file = rootPackageJson.rootPackageJson.parentFile.normalize() - logger.lifecycle("Kotlin/JS NODE_PATH: $file") - project.layout.dir(provider { file }).get() -} - -val nodeModulesDir: Directory by extra { - val file = nodePath.dir(NpmProject.NODE_MODULES) - logger.lifecycle("Kotlin/JS NODE_MODULES: $file") - file -} - -afterEvaluate { - val protobufJava by tasks.creating(ProtobufCompileTask::class) { - description = "proto2java" - protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto")) - - cliArgs.add("--java_out=lite:${project.mkdir("$temporaryDir/java").canonicalPath}") - } - val protobufKotlin by tasks.creating(ProtobufCompileTask::class) { - description = "proto2kotlin" - protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto")) - - cliArgs.add("--kotlin_out=lite:${project.mkdir("$temporaryDir/kotlin").canonicalPath}") - } - - - val ktProto by configurations.creating { - isCanBeResolved = false - isCanBeConsumed = true - } - - artifacts { - add(ktProto.name, protobufJava.outputDir) { - builtBy(protobufJava) - } - add(ktProto.name, protobufKotlin.outputDir) { - builtBy(protobufKotlin) - } - } - - val protobufTypescript by tasks.creating(ProtobufCompileTask::class) { - description = "proto2typescript" - - // linux: -// cliArgs.add("--plugin=${rootProject.buildDir}/js/packages/factorio-web-map-factorio-events-data-model/node_modules/.bin/protoc-gen-ts_proto.cmd") - // windows: - cliArgs.add("--plugin=protoc-gen-ts_proto=${rootProject.buildDir}/js/packages/factorio-web-map-factorio-events-data-model/node_modules/.bin/protoc-gen-ts_proto.cmd") - - cliArgs.add("--ts_proto_out=${project.mkdir("$temporaryDir/typescript").canonicalPath}") - - cliArgs.addAll( - "--ts_proto_opt=useOptionals=true", - "--ts_proto_opt=outputServices=false", - "--ts_proto_opt=outputJsonMethods=false", -// "--ts_proto_opt=outputEncodeMethods=false", - "--ts_proto_opt=forceLong=string", - "--ts_proto_opt=forceLong=number", - "--ts_proto_opt=esModuleInterop=true", - "--ts_proto_opt=exportCommonSymbols=false", -// "--proto_path=${rootProject.rootDir}", - ) - - protoFile.set(file("$projectDir/src/proto/FactorioServerLogRecord.proto")) - } - - val tsProto by configurations.creating { - isCanBeResolved = false - isCanBeConsumed = true - } - artifacts { - add(tsProto.name, protobufTypescript.outputDir) { - builtBy(protobufTypescript) - } - } - -} diff --git a/modules/factorio-events-data-model/src/proto/FactorioServerLogRecord.proto b/modules/factorio-events-data-model/src/proto/FactorioServerLogRecord.proto deleted file mode 100644 index 02d37ad..0000000 --- a/modules/factorio-events-data-model/src/proto/FactorioServerLogRecord.proto +++ /dev/null @@ -1,94 +0,0 @@ -syntax = "proto3"; - -//option optimize_for = LITE_RUNTIME; -option java_multiple_files = true; - -package dev.adamko.factorioevents; - -//import "google/protobuf/any.proto"; -//import "google/protobuf/timestamp.proto"; - -message FactorioServerLogRecord { - string mod_version = 1; - uint32 tick = 2; - string event_type = 3; - FactorioLuaObject data = 4; - -} - -message FactorioLuaObject { - string object_name = 1; - oneof data { - LuaControl lua_control = 2; - } -} - -// https://lua-api.factorio.com/next/LuaControl.html -message LuaControl { - bool is_player = 2; - uint32 surface_index = 3; - Position position = 4; - uint32 force_index = 5; - - oneof subtype { - LuaPlayer player = 10; - LuaEntity entity = 11; - } -} - -// https://lua-api.factorio.com/next/LuaPlayer.html -message LuaPlayer { - uint32 index = 1; // unique ID - string name = 2; - repeated int32 data = 4 [packed = true]; - - Colour colour = 8; - - bool is_connected = 10; - bool is_admin = 11; - - uint32 afk_time_ticks = 100; - uint32 online_time_ticks = 101; - uint32 last_online_ticks = 102; -} - -// https://lua-api.factorio.com/next/LuaEntity.html -message LuaEntity { - optional uint32 unit_number = 1; // (optional) unique ID - string name = 2; - string type = 3; - string status = 4; // https://lua-api.factorio.com/next/defines.html#defines.entity_status - - bool is_active = 8; - bool is_moving = 9; - - optional uint32 player_index = 50; // (optional) The player connected to this character or nil if none. - optional uint32 last_user_index = 51; // (optional) The last player that changed any setting on this entity. - - Colour colour = 100; // (optional) -} - -message LuaSurface { - uint32 index = 1; // unique ID - string name = 2; - float daytime = 3; -} - -message LuaForce { - uint32 index = 1; // unique ID - string force_name = 2; - - repeated uint32 player_ids = 100 [packed = true]; -} - -message Position { - int32 x = 1; - int32 y = 2; -} - -message Colour { - float red = 1; - float green = 2; - float blue = 3; - float alpha = 4; -} diff --git a/modules/factorio-events-data-model/xsrc/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt b/modules/factorio-events-data-model/xsrc/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt deleted file mode 100644 index 058d02d..0000000 --- a/modules/factorio-events-data-model/xsrc/commonMain/kotlin/dev.adamko.factorioevents.model/FactorioEvent.kt +++ /dev/null @@ -1,63 +0,0 @@ -package dev.adamko.factorioevents.model - -import kotlin.js.JsExport -import kotlin.jvm.JvmInline - -//expect sealed interface JsonPrimitive { -// value class JsonString(val string: String) : JsonPrimitive -// value class JsonNumber(val number: Number) : JsonPrimitive -// value class JsonBoolean(val boolean: Boolean) : JsonPrimitive -//} - -sealed interface JsonPrimitive { - @JvmInline - value class JsonString(val string: String) : JsonPrimitive - @JvmInline - value class JsonNumber(val number: Number) : JsonPrimitive - @JvmInline - value class JsonBoolean(val boolean: Boolean) : JsonPrimitive -} - -class JsonArray( - private val list: MutableList = mutableListOf() -) : MutableList by list - - -sealed interface JsonTableValue { - @JvmInline - value class JsonPrimitiveTV(val primitive: JsonPrimitive) : JsonTableValue - @JvmInline - value class JsonArrayTV(val array: JsonArray) : JsonTableValue - @JvmInline - value class JsonTableTV(val array: JsonTable) : JsonTableValue -} - -//expect class JsonNumber() : JsonPrimitiveType - -//expect class JsonArray - -//expect open class JsonTable - -open class JsonTable( - protected val map: MutableMap = mutableMapOf() -) : MutableMap by map { - - inline fun get2(key: String): T? { - - val jKey = JsonPrimitive.JsonString(key) - - return when { - T::class is Number -> ((get(jKey) as? JsonTableValue.JsonPrimitiveTV)?.primitive as? JsonPrimitive.JsonNumber)?.number as? T - else -> return get(jKey) as? T - } - - } - -} - -//@JsExport -class FactorioEvent : JsonTable() { - val tick: UInt? - get() = get2("tick") -// set(value) = map.put("tick", value) -} \ No newline at end of file diff --git a/modules/factorio-events-data-model/xsrc/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt b/modules/factorio-events-data-model/xsrc/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt deleted file mode 100644 index 06519b0..0000000 --- a/modules/factorio-events-data-model/xsrc/jsMain/kotlin/dev.adamko.factorioevents.model/JsonPrimitiveType.kt +++ /dev/null @@ -1,31 +0,0 @@ -package dev.adamko.factorioevents.model - - -//actual sealed interface JsonPrimitive { -// actual value class JsonString(val string: String) : JsonPrimitive -// actual value class JsonNumber(val number: Number) : JsonPrimitive -// actual value class JsonBoolean(val boolean: Boolean) : JsonPrimitive -//} - -//actual class JsonArray( -// private val list: MutableList = mutableListOf() -//) : MutableList by list - -//actual sealed interface JsonTableValue { -// actual value class JsonPrimitiveTV(val primitive: JsonPrimitive) : JsonTableValue -// actual value class JsonArrayTV(val array: JsonArray) : JsonTableValue -//} - - -//actual open class JsonTable( -// private val map: MutableMap = mutableMapOf() -//) : MutableMap by map - - -fun printMap() { - val f = JsonPrimitive.JsonString("test") - - println(f.string) - println(f) - -} diff --git a/modules/factorio-events-data-model/xsrc/main/kotlin/PlayerModel.kt b/modules/factorio-events-data-model/xsrc/main/kotlin/PlayerModel.kt deleted file mode 100644 index a745430..0000000 --- a/modules/factorio-events-data-model/xsrc/main/kotlin/PlayerModel.kt +++ /dev/null @@ -1,55 +0,0 @@ -interface Identifiable { - val id: T -} - - -interface IndexedModel { - val index: UInt -} - -interface NamedModel { - val name: String -} - - -data class SurfaceModel( - override val name: String, - override val index: UInt, - val daytime: Float, - val darkness: Float, - val wind_speed: Double, -) : IndexedModel, NamedModel - - -/** Player/Entity shared props */ -interface ControlModel { - val driving: Boolean - val forces: List -} - - -//data class PlayerModel( -// val index: UInt, -// val characters: List -//) : Identifiable { -// override val id: UInt = index -//} - -//data class EntityModel( -// val unit_number: Int, -// override val name: String, -// val type: String, -// val active: Boolean, -// val minable: Boolean, -// val health: Boolean, -// val speed: Float, override val driving: Boolean, -//) : ControlModel, NamedModel - - -data class ForceModel( - val index: UInt, - override val name: String, - val research_progress: Double, -) : Identifiable, NamedModel { - override val id: UInt = index -} diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index 26e634f..5868ba2 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -16,66 +16,6 @@ node { nodeProjectDir.set(tsSrcDir) } -val tsProto: Configuration by configurations.creating { - isCanBeConsumed = false - isCanBeResolved = true -} - -dependencies { - tsProto(projects.modules.factorioEventsDataModel.dependencyProject.configurations.getByName("tsProto")) -} - -val tsProtoFetch by tasks.creating(Sync::class) { - group = project.name - - dependsOn(projects.modules.factorioEventsDataModel.dependencyProject.tasks.named("protobufTypescript")) - - val genSrcDir = projects - .modules - .factorioEventsDataModel - .dependencyProject - .layout - .buildDirectory - .dir("pbAndG/generated-sources/typescript") - - val targetDir = "$projectDir/src/main/typescript/proto" - - inputs.dir(genSrcDir) - - from(genSrcDir) - into(targetDir) - -// doLast { -// -// fileTree(targetDir).forEach { -// var text = it.readText() -// -// text = text.replace( -// Regex( -// """if \(_m0\.util\.Long !== Long\)\s*\{\s*_m0\.util\.Long = Long as any;\s*_m0\.configure\(\);\s*\}""" -// ), -// "" -// ) -// -// text = text.replace( -// Regex("""import Long from "long";"""), -// "" -// ) -// -// text = text.replace( -// Regex("""import _m0 from "protobufjs\/minimal";"""), -// "" -// ) -// -// it.writeText(text) -// } -// } - -} - -tasks.assemble { dependsOn(tsProtoFetch) } - - val tstlTask = tasks.register("typescriptToLua") { description = "Convert Typescript To Lua" group = projectId @@ -86,7 +26,7 @@ val tstlTask = tasks.register("typescriptToLua") { npmCommand.set(listOf("run", "build")) - inputs.dir(node.nodeProjectDir) + inputs.dir(project.node.nodeProjectDir) .skipWhenEmpty() .withPropertyName("sourceFiles") .withPathSensitivity(PathSensitivity.RELATIVE) @@ -124,20 +64,18 @@ idea { } -//val typescriptSrc = -// project.objects.sourceDirectorySet("typescript", "typescript").apply { -// srcDir( -// layout.projectDirectory.dir("src/main/typescript") -// ) -// destinationDirectory.set( -// modBuildDir.dir("typescriptToLua") -// ) -// compiledBy(tstlTask) { -// project.objects.directoryProperty().apply { -// set( modBuildDir.dir("typescriptToLua")) -// } -// } -// } +val typescriptSrcSet = + project.objects.sourceDirectorySet("typescript", "typescript").apply { + srcDir(mkdir("$projectDir/src/main/typescript")) + + destinationDirectory.set(modBuildDir.dir("typescriptToLua").asFile) + compiledBy(tstlTask) { + + project.objects.directoryProperty().apply { + set(modBuildDir.dir("typescriptToLua")) + } + } + } val modPackageTask = tasks.register("packageMod") { description = "Package mod files into ZIP" diff --git a/modules/mod/src/main/typescript/package-lock.json b/modules/mod/src/main/typescript/package-lock.json index 621dcc5..b0ae77b 100644 --- a/modules/mod/src/main/typescript/package-lock.json +++ b/modules/mod/src/main/typescript/package-lock.json @@ -4,85 +4,11 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" - }, - "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" - }, "@types/node": { "version": "12.20.33", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz", "integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw==" }, - "@types/object-hash": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@types/object-hash/-/object-hash-1.3.4.tgz", - "integrity": "sha512-xFdpkAkikBgqBdG9vIlsqffDV8GpvnPEzs0IUtr1v3BEB97ijsFQ4RXVbUZwjFThhB4MDSTUfvmxUD5PGx0wXA==" - }, - "@types/prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==" - }, - "dataloader": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz", - "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==" - }, "enhanced-resolve": { "version": "5.8.3", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", @@ -118,63 +44,16 @@ "has": "^1.0.3" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, "lua-types": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.11.0.tgz", "integrity": "sha512-J/8qHrOjkZuPBDhnuAg0DWoaJEImqXNzgEnUigCTVrSVCcchM5Y5zpcI3aWAZPhuZlb0QKC/f3nc7VGmZmBg7w==" }, - "object-hash": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", - "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==" - }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, - "prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==" - }, - "protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "dependencies": { - "@types/node": { - "version": "16.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz", - "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==" - } - } - }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -194,38 +73,6 @@ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, - "ts-poet": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/ts-poet/-/ts-poet-4.6.1.tgz", - "integrity": "sha512-DXJ+mBJIDp+jiaUgB4N5I/sczHHDU2FWacdbDNVAVS4Mh4hb7ckpvUWVW7m7/nAOcjR0r4Wt+7AoO7FeJKExfA==", - "requires": { - "@types/prettier": "^1.19.0", - "lodash": "^4.17.15", - "prettier": "^2.0.2" - } - }, - "ts-proto": { - "version": "1.83.3", - "resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-1.83.3.tgz", - "integrity": "sha512-r6MKFjoc4Og2kB4cNJ/bddLebdIwhouG5plu0Rry1jJMEqp2GKA7AE4FrR/FnTCIGbNPYP4622lBqckZd7UHcQ==", - "requires": { - "@types/object-hash": "^1.3.0", - "dataloader": "^1.4.0", - "object-hash": "^1.3.1", - "protobufjs": "^6.8.8", - "ts-poet": "^4.5.0", - "ts-proto-descriptors": "^1.2.1" - } - }, - "ts-proto-descriptors": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/ts-proto-descriptors/-/ts-proto-descriptors-1.3.1.tgz", - "integrity": "sha512-Cybb3fqceMwA6JzHdC32dIo8eVGVmXrM6TWhdk1XQVVHT/6OQqk0ioyX1dIdu3rCIBhRmWUhUE4HsyK+olmgMw==", - "requires": { - "long": "^4.0.0", - "protobufjs": "^6.8.8" - } - }, "typed-factorio": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.8.0.tgz", diff --git a/modules/mod/src/main/typescript/package.json b/modules/mod/src/main/typescript/package.json index dd451c1..b25c3b9 100644 --- a/modules/mod/src/main/typescript/package.json +++ b/modules/mod/src/main/typescript/package.json @@ -14,25 +14,9 @@ "lua-types": "^2.11.0", "@types/node": "^12.0.8", "typescript-to-lua": "1.0.1", - "typed-factorio": "0.8.0", - "ts-proto": "1.83.3" + "typed-factorio": "0.8.0" }, "peerDependencies": {}, "optionalDependencies": {}, - "bundledDependencies": [], - "//": { - "typescript-json-schema": "0.51.0", - "typescript": "4.4.3", - "@types/node": "^13.7.7", - "kafkajs": "1.15.0", - "lua-types": "^2.11.0", - "react": "17.0.2", - "react-dom": "17.0.2", - "webpack": "5.38.1", - "webpack-cli": "4.7.1", - "format-util": "1.0.5", - "source-map-loader": "3.0.0", - "css-loader": "5.2.6", - "style-loader": "2.0.0" - } + "bundledDependencies": [] } diff --git a/modules/mod/src/main/typescript/proto/FactorioServerLogRecord.ts b/modules/mod/src/main/typescript/proto/FactorioServerLogRecord.ts deleted file mode 100644 index 009a229..0000000 --- a/modules/mod/src/main/typescript/proto/FactorioServerLogRecord.ts +++ /dev/null @@ -1,907 +0,0 @@ -/* eslint-disable */ -import Long from "long"; -import _m0 from "protobufjs/minimal"; - -export interface FactorioServerLogRecord { - modVersion: string; - tick: number; - eventType: string; - data?: FactorioLuaObject; -} - -export interface FactorioLuaObject { - objectName: string; - luaControl?: LuaControl | undefined; -} - -/** https://lua-api.factorio.com/next/LuaControl.html */ -export interface LuaControl { - isPlayer: boolean; - surfaceIndex: number; - position?: Position; - forceIndex: number; - player?: LuaPlayer | undefined; - entity?: LuaEntity | undefined; -} - -/** https://lua-api.factorio.com/next/LuaPlayer.html */ -export interface LuaPlayer { - /** unique ID */ - index: number; - name: string; - data: number[]; - colour?: Colour; - isConnected: boolean; - isAdmin: boolean; - afkTimeTicks: number; - onlineTimeTicks: number; - lastOnlineTicks: number; -} - -/** https://lua-api.factorio.com/next/LuaEntity.html */ -export interface LuaEntity { - /** (optional) unique ID */ - unitNumber?: number | undefined; - name: string; - type: string; - /** https://lua-api.factorio.com/next/defines.html#defines.entity_status */ - status: string; - isActive: boolean; - isMoving: boolean; - /** (optional) The player connected to this character or nil if none. */ - playerIndex?: number | undefined; - /** (optional) The last player that changed any setting on this entity. */ - lastUserIndex?: number | undefined; - /** (optional) */ - colour?: Colour; -} - -export interface LuaSurface { - /** unique ID */ - index: number; - name: string; - daytime: number; -} - -export interface LuaForce { - /** unique ID */ - index: number; - forceName: string; - playerIds: number[]; -} - -export interface Position { - x: number; - y: number; -} - -export interface Colour { - red: number; - green: number; - blue: number; - alpha: number; -} - -const baseFactorioServerLogRecord: object = { - modVersion: "", - tick: 0, - eventType: "", -}; - -export const FactorioServerLogRecord = { - encode( - message: FactorioServerLogRecord, - writer: _m0.Writer = _m0.Writer.create() - ): _m0.Writer { - if (message.modVersion !== "") { - writer.uint32(10).string(message.modVersion); - } - if (message.tick !== 0) { - writer.uint32(16).uint32(message.tick); - } - if (message.eventType !== "") { - writer.uint32(26).string(message.eventType); - } - if (message.data !== undefined) { - FactorioLuaObject.encode(message.data, writer.uint32(34).fork()).ldelim(); - } - return writer; - }, - - decode( - input: _m0.Reader | Uint8Array, - length?: number - ): FactorioServerLogRecord { - const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = { - ...baseFactorioServerLogRecord, - } as FactorioServerLogRecord; - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.modVersion = reader.string(); - break; - case 2: - message.tick = reader.uint32(); - break; - case 3: - message.eventType = reader.string(); - break; - case 4: - message.data = FactorioLuaObject.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }, - - fromPartial( - object: DeepPartial - ): FactorioServerLogRecord { - const message = { - ...baseFactorioServerLogRecord, - } as FactorioServerLogRecord; - if (object.modVersion !== undefined && object.modVersion !== null) { - message.modVersion = object.modVersion; - } else { - message.modVersion = ""; - } - if (object.tick !== undefined && object.tick !== null) { - message.tick = object.tick; - } else { - message.tick = 0; - } - if (object.eventType !== undefined && object.eventType !== null) { - message.eventType = object.eventType; - } else { - message.eventType = ""; - } - if (object.data !== undefined && object.data !== null) { - message.data = FactorioLuaObject.fromPartial(object.data); - } else { - message.data = undefined; - } - return message; - }, -}; - -const baseFactorioLuaObject: object = { objectName: "" }; - -export const FactorioLuaObject = { - encode( - message: FactorioLuaObject, - writer: _m0.Writer = _m0.Writer.create() - ): _m0.Writer { - if (message.objectName !== "") { - writer.uint32(10).string(message.objectName); - } - if (message.luaControl !== undefined) { - LuaControl.encode(message.luaControl, writer.uint32(18).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): FactorioLuaObject { - const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = { ...baseFactorioLuaObject } as FactorioLuaObject; - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.objectName = reader.string(); - break; - case 2: - message.luaControl = LuaControl.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }, - - fromPartial(object: DeepPartial): FactorioLuaObject { - const message = { ...baseFactorioLuaObject } as FactorioLuaObject; - if (object.objectName !== undefined && object.objectName !== null) { - message.objectName = object.objectName; - } else { - message.objectName = ""; - } - if (object.luaControl !== undefined && object.luaControl !== null) { - message.luaControl = LuaControl.fromPartial(object.luaControl); - } else { - message.luaControl = undefined; - } - return message; - }, -}; - -const baseLuaControl: object = { - isPlayer: false, - surfaceIndex: 0, - forceIndex: 0, -}; - -export const LuaControl = { - encode( - message: LuaControl, - writer: _m0.Writer = _m0.Writer.create() - ): _m0.Writer { - if (message.isPlayer === true) { - writer.uint32(16).bool(message.isPlayer); - } - if (message.surfaceIndex !== 0) { - writer.uint32(24).uint32(message.surfaceIndex); - } - if (message.position !== undefined) { - Position.encode(message.position, writer.uint32(34).fork()).ldelim(); - } - if (message.forceIndex !== 0) { - writer.uint32(40).uint32(message.forceIndex); - } - if (message.player !== undefined) { - LuaPlayer.encode(message.player, writer.uint32(82).fork()).ldelim(); - } - if (message.entity !== undefined) { - LuaEntity.encode(message.entity, writer.uint32(90).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): LuaControl { - const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = { ...baseLuaControl } as LuaControl; - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 2: - message.isPlayer = reader.bool(); - break; - case 3: - message.surfaceIndex = reader.uint32(); - break; - case 4: - message.position = Position.decode(reader, reader.uint32()); - break; - case 5: - message.forceIndex = reader.uint32(); - break; - case 10: - message.player = LuaPlayer.decode(reader, reader.uint32()); - break; - case 11: - message.entity = LuaEntity.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }, - - fromPartial(object: DeepPartial): LuaControl { - const message = { ...baseLuaControl } as LuaControl; - if (object.isPlayer !== undefined && object.isPlayer !== null) { - message.isPlayer = object.isPlayer; - } else { - message.isPlayer = false; - } - if (object.surfaceIndex !== undefined && object.surfaceIndex !== null) { - message.surfaceIndex = object.surfaceIndex; - } else { - message.surfaceIndex = 0; - } - if (object.position !== undefined && object.position !== null) { - message.position = Position.fromPartial(object.position); - } else { - message.position = undefined; - } - if (object.forceIndex !== undefined && object.forceIndex !== null) { - message.forceIndex = object.forceIndex; - } else { - message.forceIndex = 0; - } - if (object.player !== undefined && object.player !== null) { - message.player = LuaPlayer.fromPartial(object.player); - } else { - message.player = undefined; - } - if (object.entity !== undefined && object.entity !== null) { - message.entity = LuaEntity.fromPartial(object.entity); - } else { - message.entity = undefined; - } - return message; - }, -}; - -const baseLuaPlayer: object = { - index: 0, - name: "", - data: 0, - isConnected: false, - isAdmin: false, - afkTimeTicks: 0, - onlineTimeTicks: 0, - lastOnlineTicks: 0, -}; - -export const LuaPlayer = { - encode( - message: LuaPlayer, - writer: _m0.Writer = _m0.Writer.create() - ): _m0.Writer { - if (message.index !== 0) { - writer.uint32(8).uint32(message.index); - } - if (message.name !== "") { - writer.uint32(18).string(message.name); - } - writer.uint32(34).fork(); - for (const v of message.data) { - writer.int32(v); - } - writer.ldelim(); - if (message.colour !== undefined) { - Colour.encode(message.colour, writer.uint32(66).fork()).ldelim(); - } - if (message.isConnected === true) { - writer.uint32(80).bool(message.isConnected); - } - if (message.isAdmin === true) { - writer.uint32(88).bool(message.isAdmin); - } - if (message.afkTimeTicks !== 0) { - writer.uint32(800).uint32(message.afkTimeTicks); - } - if (message.onlineTimeTicks !== 0) { - writer.uint32(808).uint32(message.onlineTimeTicks); - } - if (message.lastOnlineTicks !== 0) { - writer.uint32(816).uint32(message.lastOnlineTicks); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): LuaPlayer { - const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = { ...baseLuaPlayer } as LuaPlayer; - message.data = []; - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.index = reader.uint32(); - break; - case 2: - message.name = reader.string(); - break; - case 4: - if ((tag & 7) === 2) { - const end2 = reader.uint32() + reader.pos; - while (reader.pos < end2) { - message.data.push(reader.int32()); - } - } else { - message.data.push(reader.int32()); - } - break; - case 8: - message.colour = Colour.decode(reader, reader.uint32()); - break; - case 10: - message.isConnected = reader.bool(); - break; - case 11: - message.isAdmin = reader.bool(); - break; - case 100: - message.afkTimeTicks = reader.uint32(); - break; - case 101: - message.onlineTimeTicks = reader.uint32(); - break; - case 102: - message.lastOnlineTicks = reader.uint32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }, - - fromPartial(object: DeepPartial): LuaPlayer { - const message = { ...baseLuaPlayer } as LuaPlayer; - message.data = []; - if (object.index !== undefined && object.index !== null) { - message.index = object.index; - } else { - message.index = 0; - } - if (object.name !== undefined && object.name !== null) { - message.name = object.name; - } else { - message.name = ""; - } - if (object.data !== undefined && object.data !== null) { - for (const e of object.data) { - message.data.push(e); - } - } - if (object.colour !== undefined && object.colour !== null) { - message.colour = Colour.fromPartial(object.colour); - } else { - message.colour = undefined; - } - if (object.isConnected !== undefined && object.isConnected !== null) { - message.isConnected = object.isConnected; - } else { - message.isConnected = false; - } - if (object.isAdmin !== undefined && object.isAdmin !== null) { - message.isAdmin = object.isAdmin; - } else { - message.isAdmin = false; - } - if (object.afkTimeTicks !== undefined && object.afkTimeTicks !== null) { - message.afkTimeTicks = object.afkTimeTicks; - } else { - message.afkTimeTicks = 0; - } - if ( - object.onlineTimeTicks !== undefined && - object.onlineTimeTicks !== null - ) { - message.onlineTimeTicks = object.onlineTimeTicks; - } else { - message.onlineTimeTicks = 0; - } - if ( - object.lastOnlineTicks !== undefined && - object.lastOnlineTicks !== null - ) { - message.lastOnlineTicks = object.lastOnlineTicks; - } else { - message.lastOnlineTicks = 0; - } - return message; - }, -}; - -const baseLuaEntity: object = { - name: "", - type: "", - status: "", - isActive: false, - isMoving: false, -}; - -export const LuaEntity = { - encode( - message: LuaEntity, - writer: _m0.Writer = _m0.Writer.create() - ): _m0.Writer { - if (message.unitNumber !== undefined) { - writer.uint32(8).uint32(message.unitNumber); - } - if (message.name !== "") { - writer.uint32(18).string(message.name); - } - if (message.type !== "") { - writer.uint32(26).string(message.type); - } - if (message.status !== "") { - writer.uint32(34).string(message.status); - } - if (message.isActive === true) { - writer.uint32(64).bool(message.isActive); - } - if (message.isMoving === true) { - writer.uint32(72).bool(message.isMoving); - } - if (message.playerIndex !== undefined) { - writer.uint32(400).uint32(message.playerIndex); - } - if (message.lastUserIndex !== undefined) { - writer.uint32(408).uint32(message.lastUserIndex); - } - if (message.colour !== undefined) { - Colour.encode(message.colour, writer.uint32(802).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): LuaEntity { - const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = { ...baseLuaEntity } as LuaEntity; - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.unitNumber = reader.uint32(); - break; - case 2: - message.name = reader.string(); - break; - case 3: - message.type = reader.string(); - break; - case 4: - message.status = reader.string(); - break; - case 8: - message.isActive = reader.bool(); - break; - case 9: - message.isMoving = reader.bool(); - break; - case 50: - message.playerIndex = reader.uint32(); - break; - case 51: - message.lastUserIndex = reader.uint32(); - break; - case 100: - message.colour = Colour.decode(reader, reader.uint32()); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }, - - fromPartial(object: DeepPartial): LuaEntity { - const message = { ...baseLuaEntity } as LuaEntity; - if (object.unitNumber !== undefined && object.unitNumber !== null) { - message.unitNumber = object.unitNumber; - } else { - message.unitNumber = undefined; - } - if (object.name !== undefined && object.name !== null) { - message.name = object.name; - } else { - message.name = ""; - } - if (object.type !== undefined && object.type !== null) { - message.type = object.type; - } else { - message.type = ""; - } - if (object.status !== undefined && object.status !== null) { - message.status = object.status; - } else { - message.status = ""; - } - if (object.isActive !== undefined && object.isActive !== null) { - message.isActive = object.isActive; - } else { - message.isActive = false; - } - if (object.isMoving !== undefined && object.isMoving !== null) { - message.isMoving = object.isMoving; - } else { - message.isMoving = false; - } - if (object.playerIndex !== undefined && object.playerIndex !== null) { - message.playerIndex = object.playerIndex; - } else { - message.playerIndex = undefined; - } - if (object.lastUserIndex !== undefined && object.lastUserIndex !== null) { - message.lastUserIndex = object.lastUserIndex; - } else { - message.lastUserIndex = undefined; - } - if (object.colour !== undefined && object.colour !== null) { - message.colour = Colour.fromPartial(object.colour); - } else { - message.colour = undefined; - } - return message; - }, -}; - -const baseLuaSurface: object = { index: 0, name: "", daytime: 0 }; - -export const LuaSurface = { - encode( - message: LuaSurface, - writer: _m0.Writer = _m0.Writer.create() - ): _m0.Writer { - if (message.index !== 0) { - writer.uint32(8).uint32(message.index); - } - if (message.name !== "") { - writer.uint32(18).string(message.name); - } - if (message.daytime !== 0) { - writer.uint32(29).float(message.daytime); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): LuaSurface { - const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = { ...baseLuaSurface } as LuaSurface; - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.index = reader.uint32(); - break; - case 2: - message.name = reader.string(); - break; - case 3: - message.daytime = reader.float(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }, - - fromPartial(object: DeepPartial): LuaSurface { - const message = { ...baseLuaSurface } as LuaSurface; - if (object.index !== undefined && object.index !== null) { - message.index = object.index; - } else { - message.index = 0; - } - if (object.name !== undefined && object.name !== null) { - message.name = object.name; - } else { - message.name = ""; - } - if (object.daytime !== undefined && object.daytime !== null) { - message.daytime = object.daytime; - } else { - message.daytime = 0; - } - return message; - }, -}; - -const baseLuaForce: object = { index: 0, forceName: "", playerIds: 0 }; - -export const LuaForce = { - encode( - message: LuaForce, - writer: _m0.Writer = _m0.Writer.create() - ): _m0.Writer { - if (message.index !== 0) { - writer.uint32(8).uint32(message.index); - } - if (message.forceName !== "") { - writer.uint32(18).string(message.forceName); - } - writer.uint32(802).fork(); - for (const v of message.playerIds) { - writer.uint32(v); - } - writer.ldelim(); - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): LuaForce { - const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = { ...baseLuaForce } as LuaForce; - message.playerIds = []; - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.index = reader.uint32(); - break; - case 2: - message.forceName = reader.string(); - break; - case 100: - if ((tag & 7) === 2) { - const end2 = reader.uint32() + reader.pos; - while (reader.pos < end2) { - message.playerIds.push(reader.uint32()); - } - } else { - message.playerIds.push(reader.uint32()); - } - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }, - - fromPartial(object: DeepPartial): LuaForce { - const message = { ...baseLuaForce } as LuaForce; - message.playerIds = []; - if (object.index !== undefined && object.index !== null) { - message.index = object.index; - } else { - message.index = 0; - } - if (object.forceName !== undefined && object.forceName !== null) { - message.forceName = object.forceName; - } else { - message.forceName = ""; - } - if (object.playerIds !== undefined && object.playerIds !== null) { - for (const e of object.playerIds) { - message.playerIds.push(e); - } - } - return message; - }, -}; - -const basePosition: object = { x: 0, y: 0 }; - -export const Position = { - encode( - message: Position, - writer: _m0.Writer = _m0.Writer.create() - ): _m0.Writer { - if (message.x !== 0) { - writer.uint32(8).int32(message.x); - } - if (message.y !== 0) { - writer.uint32(16).int32(message.y); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): Position { - const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = { ...basePosition } as Position; - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.x = reader.int32(); - break; - case 2: - message.y = reader.int32(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }, - - fromPartial(object: DeepPartial): Position { - const message = { ...basePosition } as Position; - if (object.x !== undefined && object.x !== null) { - message.x = object.x; - } else { - message.x = 0; - } - if (object.y !== undefined && object.y !== null) { - message.y = object.y; - } else { - message.y = 0; - } - return message; - }, -}; - -const baseColour: object = { red: 0, green: 0, blue: 0, alpha: 0 }; - -export const Colour = { - encode( - message: Colour, - writer: _m0.Writer = _m0.Writer.create() - ): _m0.Writer { - if (message.red !== 0) { - writer.uint32(13).float(message.red); - } - if (message.green !== 0) { - writer.uint32(21).float(message.green); - } - if (message.blue !== 0) { - writer.uint32(29).float(message.blue); - } - if (message.alpha !== 0) { - writer.uint32(37).float(message.alpha); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): Colour { - const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = { ...baseColour } as Colour; - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - message.red = reader.float(); - break; - case 2: - message.green = reader.float(); - break; - case 3: - message.blue = reader.float(); - break; - case 4: - message.alpha = reader.float(); - break; - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }, - - fromPartial(object: DeepPartial): Colour { - const message = { ...baseColour } as Colour; - if (object.red !== undefined && object.red !== null) { - message.red = object.red; - } else { - message.red = 0; - } - if (object.green !== undefined && object.green !== null) { - message.green = object.green; - } else { - message.green = 0; - } - if (object.blue !== undefined && object.blue !== null) { - message.blue = object.blue; - } else { - message.blue = 0; - } - if (object.alpha !== undefined && object.alpha !== null) { - message.alpha = object.alpha; - } else { - message.alpha = 0; - } - return message; - }, -}; - -type Builtin = - | Date - | Function - | Uint8Array - | string - | number - | boolean - | undefined; -type DeepPartial = T extends Builtin - ? T - : T extends Array - ? Array> - : T extends ReadonlyArray - ? ReadonlyArray> - : T extends {} - ? { [K in keyof T]?: DeepPartial } - : Partial; - -if (_m0.util.Long !== Long) { - _m0.util.Long = Long as any; - _m0.configure(); -} diff --git a/modules/mod/src/main/typescript/tsconfig.json b/modules/mod/src/main/typescript/tsconfig.json index 989f0ae..1e9e646 100644 --- a/modules/mod/src/main/typescript/tsconfig.json +++ b/modules/mod/src/main/typescript/tsconfig.json @@ -10,9 +10,7 @@ "types": [ "typescript-to-lua/language-extensions", "lua-types/5.2", - "typed-factorio/runtime", - "protobufjs/minimal.d.ts", - "@types/long" + "typed-factorio/runtime" ], "explainFiles": true, "forceConsistentCasingInFileNames": true, @@ -33,29 +31,5 @@ "noHeader": true, "noImplicitSelf": true, "luaLibImport": "inline" - }, - "//": { - "noResolve": true, - "newLine": "lf", - "exclude": [ - "node_modules" - ], - "exactOptionalPropertyTypes": true, - "skipLibCheck": true, - "skipDefaultLibCheck": true, - "types": [ - "node", - "typed-factorio/runtime", - "lua-types/5.2" - ], - "typeRoots": [ - "node_modules/@types" - ], - "//": "lua-types/5.2", - "luaLibImport": "inline", - "noImplicitSelf": true, - "sourceMapTraceback": true, - "luaBundle ": "bundle.lua", - "luaBundleEntry ": "bundleEntry.lua" } } diff --git a/modules/mod2/build.gradle.kts b/modules/mod2/build.gradle.kts deleted file mode 100644 index 586e5cb..0000000 --- a/modules/mod2/build.gradle.kts +++ /dev/null @@ -1,162 +0,0 @@ -import com.github.gradle.node.npm.task.NpmTask -import com.github.gradle.node.task.NodeTask -import org.gradle.api.internal.project.ProjectInternal -import org.jetbrains.kotlin.gradle.targets.js.dukat.DukatRunner -import org.jetbrains.kotlin.gradle.targets.js.dukat.ExternalsOutputFormat -import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask -import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs -import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject -import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject - -plugins { - id("dev.adamko.factoriowebmap.archetype.kotlin-js") -} - -//group = rootProject.group.toString() + "." + project.name -//version = rootProject.version -// -//val projectId = rootProject.name + "-" + project.name -val projectId: String by project.extra -val modBuildDir: Directory = layout.buildDirectory.dir(projectId).get() -val nodeModulesDir: Directory by project.extra - -kotlin { - - js(IR) { - - binaries.executable() - - useCommonJs() - nodejs() - -// compilations.all { - compilations["main"].apply { - packageJson { - customField( - "scripts", - mapOf( - "build" to "tstl", - "dev" to "tstl --watch", - ) - ) - } - } - - -// kotlin.srcDir("src/main/myKotlin") -// } - sourceSets["main"].apply { -// sourceSets.create("dukat").apply { - kotlin.srcDir(project.layout.projectDirectory.dir("dukat-custom")) - } - - -// sourceSets { -// all { -// languageSettings.optIn("kotlin.ExperimentalStdlibApi") -// languageSettings.optIn("kotlin.time.ExperimentalTime") -// } -// } - } -} - -dependencies { - - - // bom is defined in archetype.kotlin-js - - implementation("org.jetbrains.kotlin-wrappers:kotlin-react") -// implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom") - implementation(npm("react", "17.0.2")) -// implementation(npm("react-dom", "17.0.2")) - -// implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7") { -// because("https://github.com/Kotlin/kotlinx-nodejs") -// } - - val generateExternals = false - implementation(npm("typescript-to-lua", "1.0.1", generateExternals = generateExternals)) - implementation(npm("typed-factorio", "0.7.1", generateExternals = true)) - implementation(npm("lua-types", "2.11.0", generateExternals = generateExternals)) - implementation(npm("typescript", "4.4.3", generateExternals = generateExternals)) - - testImplementation(kotlin("test-js")) -} - -//val rootPackageJson: RootPackageJsonTask by tasks.getting(RootPackageJsonTask::class) -//val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) -//val packageJson by rootProject.tasks.getting(KotlinPackageJsonTask::class) -//val packageJson : RootPackageJsonTask by tasks.named(RootPackageJsonTask.NAME) - -//node { -// download.set(true) -// version.set("14.18.0") -// -// distBaseUrl.set(null as String?) // set by dependencyResolutionManagement -// -// nodeProjectDir.set(rootPackageJson.rootPackageJson.parentFile.normalize()) -//// nodeProjectDir.set(packageJson.packageJson.parentFile.normalize()) -//} - - -//fun NpmTask.setNodeModulesPath(path: String): Unit = -// environment.put("NODE_PATH", path) -// -//fun NpmTask.setNodeModulesPath(folder: File): Unit = -// setNodeModulesPath(folder.normalize().absolutePath) - -tasks { - register("tstl") { - description = "Typescript To Lua" - group = projectId - - dependsOn(build) - -// setNodeModulesPath(node.nodeProjectDir.dir("node_modules").get().asFile) -// setNodeModulesPath(node.nodeProjectDir.dir(NpmProject.NODE_MODULES).get().asFile) - val nodeModulesDir: Directory by project.extra - environment.put("NODE_PATH", nodeModulesDir.asFile.absolutePath) - - execOverrides { standardOutput = System.out } - - npmCommand.set(listOf("run", "build")) - - val outputDir = modBuildDir.dir("tstl") - args.set(parseSpaceSeparatedArgs("-- --outDir $outputDir")) - outputs.dir(outputDir) - - ignoreExitValue.set(false) - inputs.dir(rootProject.layout.buildDirectory.dir("js")) - } - - register("dukat-typed-factorio") { - group = projectId - - val npmProject = kotlin.js().compilations["main"].npmProject - - val files = nodeModulesDir.dir("typed-factorio") - .asFileTree - .filter { it.extension in setOf("ts", "d.ts") } - .files - - logger.lifecycle("Converting typed-factorio files: ${files.joinToString { it.name }}") - - val runner = DukatRunner( - npmProject, - files, - ExternalsOutputFormat.SOURCE, - project.layout.projectDirectory.dir("dukat-custom").asFile, - ) - val services = (project as ProjectInternal).services - doLast { - runner.execute(services) - } - } -} - - -configure { - versions.dukat.version = "0.5.8-rc.4-dev.20211001" -// versions.dukat.version = "0.5.8-rc.4" -} diff --git a/modules/mod2/dukat-custom/5.2-only.module_lua-types.kt b/modules/mod2/dukat-custom/5.2-only.module_lua-types.kt deleted file mode 100644 index d47462e..0000000 --- a/modules/mod2/dukat-custom/5.2-only.module_lua-types.kt +++ /dev/null @@ -1,17 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -//external fun collectgarbage(opt: String /* "count" | "generational" | "incremental" */): dynamic /* Unit */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/5.2-plus-or-jit.module_lua-types.kt b/modules/mod2/dukat-custom/5.2-plus-or-jit.module_lua-types.kt deleted file mode 100644 index f68ae03..0000000 --- a/modules/mod2/dukat-custom/5.2-plus-or-jit.module_lua-types.kt +++ /dev/null @@ -1,37 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external fun load(chunk: String, chunkname: String = definedExternally, mode: String /* "b" | "t" | "bt" */ = definedExternally, env: Any? = definedExternally): dynamic /* JsTuple<() -> Any> | JsTuple */ - -external fun load(chunk: String): dynamic /* JsTuple<() -> Any> | JsTuple */ - -external fun load(chunk: String, chunkname: String = definedExternally): dynamic /* JsTuple<() -> Any> | JsTuple */ - -external fun load(chunk: String, chunkname: String = definedExternally, mode: String /* "b" | "t" | "bt" */ = definedExternally): dynamic /* JsTuple<() -> Any> | JsTuple */ - -external fun load(chunk: () -> String?, chunkname: String = definedExternally, mode: String /* "b" | "t" | "bt" */ = definedExternally, env: Any? = definedExternally): dynamic /* JsTuple<() -> Any> | JsTuple */ - -external fun load(chunk: () -> String?): dynamic /* JsTuple<() -> Any> | JsTuple */ - -external fun load(chunk: () -> String?, chunkname: String = definedExternally): dynamic /* JsTuple<() -> Any> | JsTuple */ - -external fun load(chunk: () -> String?, chunkname: String = definedExternally, mode: String /* "b" | "t" | "bt" */ = definedExternally): dynamic /* JsTuple<() -> Any> | JsTuple */ - -external fun loadfile(filename: String = definedExternally, mode: String /* "b" | "t" | "bt" */ = definedExternally, env: Any? = definedExternally): dynamic /* JsTuple<() -> Any> | JsTuple */ - -external fun , R, E> xpcall(f: (self: This, args: Args) -> R, msgh: (self: Unit, err: Any) -> E, context: This, vararg args: Args): dynamic /* JsTuple | JsTuple */ - -external fun , R, E> xpcall(f: (self: Unit, args: Args) -> R, msgh: (err: Any) -> E, vararg args: Args): dynamic /* JsTuple | JsTuple */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/5.2-plus.module_lua-types.kt b/modules/mod2/dukat-custom/5.2-plus.module_lua-types.kt deleted file mode 100644 index adcf485..0000000 --- a/modules/mod2/dukat-custom/5.2-plus.module_lua-types.kt +++ /dev/null @@ -1,22 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import tsstdlib.Record - -//external var _ENV: Record - -//external fun collectgarbage(opt: String /* "isrunning" */): Boolean - -//external fun module(name: String, vararg options: Function<*>) \ No newline at end of file diff --git a/modules/mod2/dukat-custom/bit32/5.2-only.bit32.module_lua-types.kt b/modules/mod2/dukat-custom/bit32/5.2-only.bit32.module_lua-types.kt deleted file mode 100644 index 92589f5..0000000 --- a/modules/mod2/dukat-custom/bit32/5.2-only.bit32.module_lua-types.kt +++ /dev/null @@ -1,41 +0,0 @@ -@file:JsQualifier("bit32") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package bit32 - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external fun arshift(x: Number, disp: Number): Number - -external fun band(vararg operands: Number): Number - -external fun bnot(x: Number): Number - -external fun bor(vararg operands: Number): Number - -external fun btest(vararg operands: Number): Boolean - -external fun bxor(vararg operands: Number): Number - -external fun extract(n: Number, field: Number, width: Number = definedExternally): Number - -external fun replace(n: Number, v: Number, field: Number, width: Number = definedExternally): Number - -external fun lrotate(x: Number, disp: Number): Number - -external fun lshift(x: Number, disp: Number): Number - -external fun rrotate(x: Number, disp: Number): Number - -external fun rshift(x: Number, disp: Number): Number \ No newline at end of file diff --git a/modules/mod2/dukat-custom/builtin-types.module_typed-factorio.kt b/modules/mod2/dukat-custom/builtin-types.module_typed-factorio.kt deleted file mode 100644 index 28b7280..0000000 --- a/modules/mod2/dukat-custom/builtin-types.module_typed-factorio.kt +++ /dev/null @@ -1,51 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import kotlinext.js.PropertyDescriptor - -typealias float = Number - -typealias double = Number - -typealias int = Number - -typealias int8 = Number - -typealias uint = Number - -typealias uint8 = Number - -typealias uint16 = Number - -typealias uint64 = Number - -//typealias table = Any? -// TODO LuaTable? AnyTable? index.module_typescript-to-lua.kt -@JsName("table") -class table : Object2() - -/** https://github.com/JetBrains/kotlin-wrappers/blob/master/kotlin-extensions/src/main/kotlin/kotlinext/js/Object.kt */ -open external class Object2 { - fun toLocaleString(): String - fun valueOf(): dynamic - fun hasOwnProperty(v: String): Boolean - fun isPrototypeOf(v: Any): Boolean - fun propertyIsEnumerable(v: String): Boolean - - companion object { - fun

getPrototypeOf(o: T): P - fun getOwnPropertyDescriptor(o: Any, p: String): PropertyDescriptor - fun getOwnPropertyNames(o: Any): Array - fun create(o: T?, properties: dynamic = definedExternally): T - fun defineProperty(o: T, p: String, attributes: PropertyDescriptor

- - diff --git a/modules/server/src/test/kotlin/test/com/example/AppSpec.kt b/modules/server/src/test/kotlin/test/com/example/AppSpec.kt deleted file mode 100644 index 33d8534..0000000 --- a/modules/server/src/test/kotlin/test/com/example/AppSpec.kt +++ /dev/null @@ -1,15 +0,0 @@ -package test.com.example - -import io.kvision.test.SimpleSpec -import kotlin.test.Test -import kotlin.test.assertTrue - -class AppSpec : SimpleSpec { - - @Test - fun render() { - run { - assertTrue(true, "Dummy test") - } - } -} diff --git a/modules/server/webpack.config.d/bootstrap.js b/modules/server/webpack.config.d/bootstrap.js deleted file mode 100644 index c9ac06d..0000000 --- a/modules/server/webpack.config.d/bootstrap.js +++ /dev/null @@ -1,3 +0,0 @@ -config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, type: 'asset'}); -config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, type: 'asset'}); -config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, type: 'asset/resource'}); diff --git a/modules/server/webpack.config.d/css.js b/modules/server/webpack.config.d/css.js deleted file mode 100644 index fd904af..0000000 --- a/modules/server/webpack.config.d/css.js +++ /dev/null @@ -1 +0,0 @@ -config.module.rules.push({ test: /\.css$/, use: ["style-loader", { loader: "css-loader", options: {sourceMap: false} } ] }); diff --git a/modules/server/webpack.config.d/file.js b/modules/server/webpack.config.d/file.js deleted file mode 100644 index aa64925..0000000 --- a/modules/server/webpack.config.d/file.js +++ /dev/null @@ -1,6 +0,0 @@ -config.module.rules.push( - { - test: /\.(jpe?g|png|gif|svg)$/i, - type: 'asset/resource' - } -); diff --git a/modules/server/webpack.config.d/handlebars.js b/modules/server/webpack.config.d/handlebars.js deleted file mode 100644 index 3847b17..0000000 --- a/modules/server/webpack.config.d/handlebars.js +++ /dev/null @@ -1,6 +0,0 @@ -config.module.rules.push( - { - test: /\.hbs$/i, - loader: 'handlebars-loader' - } -); \ No newline at end of file diff --git a/modules/server/webpack.config.d/jquery.js b/modules/server/webpack.config.d/jquery.js deleted file mode 100644 index e6c6b21..0000000 --- a/modules/server/webpack.config.d/jquery.js +++ /dev/null @@ -1,9 +0,0 @@ -;(function() { - const webpack = require('webpack') - - config.plugins.push(new webpack.ProvidePlugin({ - $: "jquery", - jQuery: "jquery", - "window.jQuery": "jquery" - })); -})(); diff --git a/modules/server/webpack.config.d/moment.js b/modules/server/webpack.config.d/moment.js deleted file mode 100644 index fb7c329..0000000 --- a/modules/server/webpack.config.d/moment.js +++ /dev/null @@ -1,15 +0,0 @@ -;(function() { - const webpack = require('webpack') - try { - const moment = require("moment"); - config.plugins.push(new webpack.IgnorePlugin({ - resourceRegExp: /^\.\/locale$/, - contextRegExp: /moment$/, - })); - config.plugins.push(new webpack.ProvidePlugin({ - moment: "moment", - "window.moment": "moment" - })); - } catch (e) { - } -})(); diff --git a/modules/server/webpack.config.d/webpack.js b/modules/server/webpack.config.d/webpack.js deleted file mode 100644 index 4ce4481..0000000 --- a/modules/server/webpack.config.d/webpack.js +++ /dev/null @@ -1,15 +0,0 @@ -config.resolve.modules.push("../../processedResources/js/main"); - -if (config.devServer) { - config.devServer.hot = true; - config.devtool = 'eval-cheap-source-map'; -} else { - config.devtool = undefined; -} - -// disable bundle size warning -config.performance = { - assetFilter: function (assetFilename) { - return !assetFilename.endsWith('.js'); - }, -}; diff --git a/src/jsMain/kotlin/main.kt b/src/jsMain/kotlin/main.kt deleted file mode 100644 index 60460bd..0000000 --- a/src/jsMain/kotlin/main.kt +++ /dev/null @@ -1,8 +0,0 @@ -fun main() { - println("Hello, Kotlin/JS!") -} - -//@JsModule("typed-factorio") -//@JsNonModule -////@JsModule -//external fun diff --git a/src/nativeMain/kotlin/Main.kt b/src/nativeMain/kotlin/Main.kt deleted file mode 100644 index 96a3690..0000000 --- a/src/nativeMain/kotlin/Main.kt +++ /dev/null @@ -1,3 +0,0 @@ -fun main() { - println("Hello, Kotlin/Native!") -} \ No newline at end of file diff --git a/src/nativeMain/kotlin/example/hello.kt b/src/nativeMain/kotlin/example/hello.kt deleted file mode 100644 index 73e1b99..0000000 --- a/src/nativeMain/kotlin/example/hello.kt +++ /dev/null @@ -1,27 +0,0 @@ -package example - -import org.luaj.vm2.LuaBoolean -import org.luaj.vm2.LuaValue - - -object Object { - val field = "A" -} - -class Clazz { - fun memberFunction(p: Int): ULong = 42UL -} - -fun forIntegers(b: Byte, s: Short, i: UInt, l: Long) {} -fun forFloats(f: Float, d: Double) {} - -fun strings(str: String): String { - return "That is '$str' from C" -} - -val globalString = "A global String" - -fun testingLuaBooleanElephant() { - val b: LuaBoolean = LuaValue.TRUE - println(b) -} diff --git a/xbuild.gradle.kts b/xbuild.gradle.kts deleted file mode 100644 index de53fb0..0000000 --- a/xbuild.gradle.kts +++ /dev/null @@ -1,124 +0,0 @@ -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension - -plugins { - kotlin("multiplatform") version "1.5.31" -} - -group = "dev.adamko.factoriowebmap" -version = "1.0-SNAPSHOT" - -kotlin { - - // - val hostOs = System.getProperty("os.name") - val isMingwX64 = hostOs.startsWith("Windows") - val nativeTarget = when { - hostOs == "Mac OS X" -> macosX64("native") - hostOs == "Linux" -> linuxX64("native") - isMingwX64 -> mingwX64("native") - else -> throw GradleException( - "Host OS '$hostOs' is not supported in Kotlin/Native.") - } - - nativeTarget.apply { - binaries { - executable { - entryPoint = "main" - } - sharedLib { - baseName = if (isMingwX64) "libnative" else "native" - } - } - } - sourceSets { - val nativeMain by getting { - dependencies { - implementation("com.soywiz.korlibs.luak:luak:2.4.3") - } - } - val nativeTest by getting { - dependencies { - implementation(kotlin("test")) - - } - } - } - // - - // - js(IR) { - binaries.executable() - browser { - commonWebpackConfig { - cssSupport.enabled = true - } - } - - useCommonJs() - nodejs() - - compilations["main"].apply { - packageJson { - customField( - "scripts", - mapOf( - "build" to "tstl", - "dev" to "tstl --watch", - ) - ) - } - } - - } - - sourceSets { - - val jsMain by getting { - kotlin.srcDir("externals02") -// kotlin.srcDir("externals") - - dependencies { - - val kotlinWrappersVersion = "0.0.1-pre.254-kotlin-1.5.31" - implementation( - project.dependencies.enforcedPlatform( - "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" - ) - ) - - implementation("org.jetbrains.kotlin-wrappers:kotlin-react") - implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom") - implementation(npm("react", "17.0.2")) - implementation(npm("react-dom", "17.0.2")) - -// implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7") { -// because("https://github.com/Kotlin/kotlinx-nodejs") -// } - - val generateExternals = false - implementation(npm("typescript-to-lua", "1.0.1", generateExternals = generateExternals)) - implementation(npm("typed-factorio", "0.7.1", generateExternals = generateExternals)) - implementation(npm("lua-types", "2.11.0", generateExternals = generateExternals)) - implementation(npm("typescript", "4.4.3", generateExternals = generateExternals)) - } - } - - val jsTest by getting { - dependencies { - implementation(kotlin("test-js")) - } - } - } - // - -} - -configure { - versions.dukat.version = "0.5.8-rc.4-dev.20211001" -// versions.dukat.version = "0.5.8-rc.4" -} - -tasks.wrapper { - gradleVersion = "7.2" - distributionType = Wrapper.DistributionType.ALL -} From b3af697636c8ed9c092faaf5d70213217accd975 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 10 Nov 2021 17:34:01 +0100 Subject: [PATCH 077/629] backing up before finally deciding on how to sync Kotlin and Typescript data model --- asd.md | 63 ++++++++ build.gradle.kts | 2 +- buildSrc/build.gradle.kts | 48 +++++- .../archetype/kotlin-js.gradle.kts | 15 +- .../archetype/kotlin-jvm.gradle.kts | 9 ++ .../archetype/kotlin-multiplatform.gradle.kts | 22 +++ .../factoriowebmap/archetype/node.gradle.kts | 6 + .../gradle/json-kotlin-schema-gen.gradle.kts | 12 ++ .../dev/adamko/gradle/tstl/TstlPlugin.kt | 24 +++ .../gradle/tstl/tasks/TypescriptToLuaTask.kt | 50 +++++++ gradle/wrapper/gradle-wrapper.properties | 2 +- .../build.gradle.kts | 141 +++++++++++++++++- .../factorioevents/model/FactorioEvent.kt | 56 +++++++ .../factorioevents/model/FactorioEvent.kt | 13 ++ .../factorioevents/model/builtinTypes.kt | 97 ++++++++++++ .../factorioevents/model/factorioEvents.kt | 58 +++++++ .../dev/adamko/factorioevents/model/main.kt | 46 ++++++ modules/mod/build.gradle.kts | 48 ++---- modules/mod/infra/docker-compose.yml | 2 +- modules/mod/src/main/typescript/events.ts | 2 +- .../mod/src/main/typescript/package-lock.json | 33 ++-- modules/mod/src/main/typescript/package.json | 8 +- settings.gradle.kts | 19 +-- 23 files changed, 679 insertions(+), 97 deletions(-) create mode 100644 asd.md create mode 100644 buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-multiplatform.gradle.kts create mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/json-kotlin-schema-gen.gradle.kts create mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/TstlPlugin.kt create mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/tasks/TypescriptToLuaTask.kt create mode 100644 modules/factorio-events-data-model/src/commonMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt create mode 100644 modules/factorio-events-data-model/src/jsMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt create mode 100644 modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt create mode 100644 modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt create mode 100644 modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/main.kt diff --git a/asd.md b/asd.md new file mode 100644 index 0000000..669dfcc --- /dev/null +++ b/asd.md @@ -0,0 +1,63 @@ +How I can run a npx Gradle task with Kotlin/JS? + +I have a project that includes some dependencies downloaded from NPM and source code in Typescript. + +I want to use [TypeScriptToLua](https://typescripttolua.github.io/) to convert my Typescript files +into Lua. + +I see that Kotlin/JS has two + +https://github.com/JetBrains/kotlin/blob/b76cbdaa41c8cae04d8bd1bd857186d7835045b5/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmProject.kt#L86 + +```kotlin +fun useTool( + exec: ExecSpec, + tool: String, + nodeArgs: List = listOf(), + args: List +) { + exec.workingDir = dir + exec.executable = nodeExecutable + exec.args = nodeArgs + require(tool) + args +} +``` + +https://github.com/JetBrains/kotlin/blob/92d200e093c693b3c06e53a39e0b0973b84c7ec5/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/dukat/DukatRunner.kt#L47 + +```kotlin +npmProject.useTool( + exec, + "dukat/bin/dukat-cli.js", + listOf(), + args +) +``` + +https://github.com/JetBrains/kotlin/blob/711b882e7176060fc7fe2968773a393c7be73cb8/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsExec.kt + +In `build.gradle.kts` I've configured the Kotlin Multiplatform plugin to download +the `typescript-to-lua` dependency + +```kotlin +plugins { + kotlin("multiplatform") +} + +kotlin { + js(IR) { + browser() + } + + sourceSets { + val jsMain: KotlinSourceSet by getting { + dependencies { + implementation(npm("typescript-to-lua", "1.1.1")) + } + } + } +} +``` + +and this correctly downloads the NPM module binaries: +`build/js/packages/data-model/node_modules/.bin/tstl` + diff --git a/build.gradle.kts b/build.gradle.kts index 7cdb0ce..1d51ecb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ group = "dev.adamko.factoriowebmap" version = "0.0.3" tasks.wrapper { - gradleVersion = "7.2" + gradleVersion = "7.3" distributionType = Wrapper.DistributionType.ALL } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 1c9ab46..f07747a 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,8 +1,27 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { + idea `kotlin-dsl` kotlin("jvm") version "1.5.31" + `java-gradle-plugin` +} + +gradlePlugin { + plugins { + create("tstl") { + id = "dev.adamko.tstl" + description = + "Gradle plugin for TypescriptToLua. Requires plugin `com.github.node-gradle.node`." + implementationClass = "dev.adamko.gradle.tstl.TstlPlugin" + } + create("json-kotlin-schema-gen") { + id = "dev.adamko.json-kotlin-schema-gen" + description = + "Gradle plugin for 'json-kotlin-schema-codegen' - Code generation for JSON Schema (Draft 07) https://github.com/pwall567/json-kotlin-schema-codegen" + implementationClass = "dev.adamko.gradle.jsonkotlinschemagen.JsonKotlinSchemaGenPlugin" + } + } } dependencies { @@ -21,18 +40,43 @@ dependencies { implementation("com.github.node-gradle:gradle-node-plugin:3.1.1") + implementation("net.pwall.json:json-kotlin-schema-codegen:0.53") } +val projectJvmTarget = "11" + tasks.withType().configureEach { kotlinOptions { - jvmTarget = "11" + jvmTarget = projectJvmTarget + apiVersion = "1.5" + languageVersion = "1.5" } kotlinOptions.freeCompilerArgs += listOf( "-Xopt-in=kotlin.OptIn", + "-Xopt-in=kotlin.RequiresOptIn", "-Xopt-in=kotlin.ExperimentalStdlibApi", "-Xopt-in=kotlin.time.ExperimentalTime", "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi", ) -} \ No newline at end of file +} + + +kotlin { + jvmToolchain { + (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(projectJvmTarget)) + } + + kotlinDslPluginOptions { + jvmTarget.set(projectJvmTarget) + } +} + +idea { + module { + isDownloadSources = true + isDownloadJavadoc = true + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts index 49c8445..4d1d5e9 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts @@ -26,7 +26,7 @@ kotlin { } dependencies { - val kotlinWrappersVersion = "0.0.1-pre.259-kotlin-1.5.31" + val kotlinWrappersVersion = "0.0.1-pre.263-kotlin-1.5.31" implementation( project.dependencies.enforcedPlatform( "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" @@ -48,7 +48,7 @@ val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) val nodePath: Directory by extra { val file = rootPackageJson.rootPackageJson.parentFile.normalize() logger.lifecycle("Kotlin/JS NODE_PATH: $file") - project.layout.dir(provider { file }).get() + project.layout.dir(project.provider { file }).get() } val nodeModulesDir: Directory by extra { @@ -56,14 +56,3 @@ val nodeModulesDir: Directory by extra { logger.lifecycle("Kotlin/JS NODE_MODULES: $file") file } - -node { - download.set(true) - version.set("14.18.0") - - distBaseUrl.set(null as String?) // set by dependencyResolutionManagement - -// nodeProjectDir.set(nodePath) -// nodeProjectDir.set(packageJson.packageJson.parentFile.normalize()) -} - diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts index f96fb0c..913b1a8 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts @@ -43,11 +43,20 @@ dependencies { } tasks.withType().configureEach { + + kotlinOptions { + jvmTarget = "11" + apiVersion = "1.5" + languageVersion = "1.5" + } + kotlinOptions.freeCompilerArgs += listOf( "-Xopt-in=kotlin.OptIn", + "-Xopt-in=kotlin.RequiresOptIn", "-Xopt-in=kotlin.ExperimentalStdlibApi", "-Xopt-in=kotlin.time.ExperimentalTime", "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi", ) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-multiplatform.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-multiplatform.gradle.kts new file mode 100644 index 0000000..e110efb --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-multiplatform.gradle.kts @@ -0,0 +1,22 @@ +package dev.adamko.factoriowebmap.archetype + +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension + + +plugins { + id("dev.adamko.factoriowebmap.archetype.base") + id("dev.adamko.factoriowebmap.archetype.node") + kotlin("multiplatform") +} + + +afterEvaluate { + + rootProject.extensions.configure { + val projectNodeInstallDir = file("$rootDir/.gradle").resolve("nodejs") + if (installationDir != projectNodeInstallDir) { + installationDir = projectNodeInstallDir + } + } + +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts index cb83376..77788fc 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts @@ -2,7 +2,10 @@ package dev.adamko.factoriowebmap.archetype import org.gradle.kotlin.dsl.kotlin import com.github.gradle.node.npm.task.NpmTask +import com.github.gradle.node.npm.task.NpxTask import com.github.gradle.node.task.NodeTask +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin +import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlugin import org.jetbrains.kotlin.gradle.targets.js.dukat.DtsResolver import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask @@ -21,3 +24,6 @@ node { distBaseUrl.set(null as String?) // set by dependencyResolutionManagement } +project.plugins.withType() +project.plugins.withType() + diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/json-kotlin-schema-gen.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/gradle/json-kotlin-schema-gen.gradle.kts new file mode 100644 index 0000000..374f9f2 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/json-kotlin-schema-gen.gradle.kts @@ -0,0 +1,12 @@ +package dev.adamko.gradle + +import org.gradle.kotlin.dsl.`component-model-base` +import org.gradle.kotlin.dsl.kotlin + + +plugins { + base +} + + + diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/TstlPlugin.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/TstlPlugin.kt new file mode 100644 index 0000000..d506592 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/TstlPlugin.kt @@ -0,0 +1,24 @@ +package dev.adamko.gradle.tstl + +import com.github.gradle.node.NodePlugin +import dev.adamko.gradle.tstl.tasks.TypescriptToLuaTask +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.plugins.BasePlugin +import org.gradle.kotlin.dsl.withType +import org.gradle.language.base.plugins.LifecycleBasePlugin + + +class TstlPlugin : Plugin { + override fun apply(project: Project) { + + project.plugins.withType { + } + + project.plugins.withType { + project.tasks.named(LifecycleBasePlugin.ASSEMBLE_TASK_NAME) { + dependsOn(project.tasks.withType()) + } + } + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/tasks/TypescriptToLuaTask.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/tasks/TypescriptToLuaTask.kt new file mode 100644 index 0000000..4da82d3 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/tasks/TypescriptToLuaTask.kt @@ -0,0 +1,50 @@ +package dev.adamko.gradle.tstl.tasks + +import com.github.gradle.node.npm.task.* +import org.gradle.api.file.* +import org.gradle.api.provider.* +import org.gradle.api.tasks.* +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs +import org.gradle.kotlin.dsl.* + +abstract class TypescriptToLuaTask : NpmTask() { + + @get:Internal + val intermediateOutputDir: RegularFileProperty = project.objects.fileProperty() + .convention { temporaryDir } + + @get:Internal + val intermediateOutputCanonicalPath: Provider = + intermediateOutputDir.map { it.asFile.canonicalPath } + + @get:Input + val identifier: Property = project.objects.property().convention(name) + + @get:Internal + val luaOutputDirConvention: Provider = + project.layout.buildDirectory.map { it.dir("typescriptToLua/${identifier.get()}") } + + @get:OutputDirectory + val luaOutputDir: DirectoryProperty = project.objects.directoryProperty() + .convention(luaOutputDirConvention) + + init { + group = "typescriptToLua" + + execOverrides { standardOutput = System.out } + + super.dependsOn(project.tasks.withType()) + ignoreExitValue.set(false) + } + + @TaskAction + fun convert() { + args.set(parseSpaceSeparatedArgs("-- --outDir ${intermediateOutputCanonicalPath.get()}")) + + project.delete(intermediateOutputDir.get()) + + super.exec() + + } + +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a0f7639..fbce071 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index d592108..618df6e 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -1,6 +1,14 @@ +import org.gradle.process.internal.DefaultExecSpec +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation +import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + + plugins { - id("dev.adamko.factoriowebmap.archetype.base") - kotlin("multiplatform") + id("dev.adamko.factoriowebmap.archetype.kotlin-multiplatform") + kotlin("plugin.serialization") } val projectId: String by project.extra @@ -13,6 +21,8 @@ kotlin { compilations.configureEach { kotlinOptions { jvmTarget = "11" + apiVersion = "1.5" + languageVersion = "1.5" } } } @@ -20,8 +30,12 @@ kotlin { sourceSets { val jvmMain by getting { dependencies { - api("com.google.protobuf:protobuf-javalite:3.19.1") - api("com.google.protobuf:protobuf-kotlin-lite:3.19.1") + implementation("com.github.ntrrgc:ts-generator:1.1.1") + implementation("org.jetbrains.kotlin:kotlin-reflect") + + val kotlinXSerializationVersion = "1.3.0" + implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$kotlinXSerializationVersion") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinXSerializationVersion") } } val jvmTest by getting { @@ -32,11 +46,24 @@ kotlin { // js(IR) { - browser() + moduleName = "data-model" + browser { } + binaries.executable() } sourceSets { - val jsMain by getting { + val jsMain: KotlinSourceSet by getting { + + dependencies { + + implementation(npm("lua-types", "^2.11.0")) + implementation(npm("@types/node", "^12.0.8")) + implementation(npm("typescript-to-lua", "1.1.1")) + implementation(npm("typescript", "4.4.4")) + implementation(npm("typed-factorio", "0.11.0-packagetypes-1", false)) + + } + } val jsTest by getting { @@ -52,11 +79,113 @@ kotlin { languageVersion = "1.5" // enableLanguageFeature("InlineClasses") // language feature name optIn("kotlin.OptIn") + optIn("kotlin.RequiresOptIn") optIn("kotlin.ExperimentalStdlibApi") optIn("kotlin.time.ExperimentalTime") optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") optIn("kotlin.js.ExperimentalJsExport") + optIn("kotlinx.serialization.ExperimentalSerializationApi") // progressiveMode = true // false by default } } } + + + + +//kotlin.js() +// .compilations +// .getByName(KotlinCompilation.MAIN_COMPILATION_NAME) +// .npmProject +// .useTool() + + +afterEvaluate { + +// val nodeJsExecTstl by tasks.creating(NodeJsExec::class) { +// group = project.name +// +// nodeArgs += listOf( +// "tstl", +// ) +// } + + val kotlinJsCompilation: KotlinJsCompilation = + kotlin.targets + .flatMap { it.compilations } + .filterIsInstance() + .first { it.name == KotlinCompilation.MAIN_COMPILATION_NAME } + val npmProject = kotlinJsCompilation.npmProject + + tasks.create("tstl") { + group = project.name + + standardOutput = System.out + errorOutput = System.err + + workingDir = npmProject.dir + executable = + when (npmProject.nodeJs.requireConfigured().isWindows) { + true -> "npx.cmd" + false -> "npx" + } + + args(parseSpaceSeparatedArgs("tstl --out $temporaryDir")) + + } + + tasks.create("asd") { + group = project.name + + doLast { + + val execSpec = + project.objects.newInstance(DefaultExecSpec::class.java).apply { + isIgnoreExitValue = false + standardOutput = System.out + errorOutput = System.err + } + + kotlin.targets + .flatMap { it.compilations } + .filterIsInstance() + .filter { it.name == KotlinCompilation.MAIN_COMPILATION_NAME } + .forEach { + + org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsExec.create(it, "blahDeBlah") { + + } + + execSpec.workingDir = it.npmProject.dir + + execSpec.executable = + when (it.npmProject.nodeJs.requireConfigured().isWindows) { + true -> "npx.cmd" + false -> "npx" + } + + execSpec.args("tstl", "--version") + +// execSpec.commandLine + + +// it.npmProject.useTool( +// execSpec, +// "typescript-to-lua/dist/tstl.js", +// listOf(), +// listOf( "--outDir","$buildDir/testAsd"), +// listOf("--version"), +// listOf(), +// ) + } + + exec { + execSpec.copyTo(this) + } + + } + } + +} + + diff --git a/modules/factorio-events-data-model/src/commonMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt b/modules/factorio-events-data-model/src/commonMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt new file mode 100644 index 0000000..25ff622 --- /dev/null +++ b/modules/factorio-events-data-model/src/commonMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt @@ -0,0 +1,56 @@ +package dev.adamko.factorioevents.model + +import kotlin.js.ExperimentalJsExport +import kotlin.js.JsExport + +// +//@JsExport +//@ExperimentalJsExport +//data class FactorioEvent( +// val modVersion: String, +// val tick: F_uint, +// val eventType: String, +// val data: FactorioObjectData, +//) +// +//@JsExport +//abstract class FactorioObjectData { +// abstract val objectName: String +//} +// +//@JsExport +//data class PlayerData( +// override val objectName: String, +// val name: String, +// val characterUnitNumber: F_uint, +// val associatedCharactersUnitNumbers: List, +// val position: PositionData, +//) : FactorioObjectData() +// +// +//@JsExport +//data class PositionData( +// val x: F_int, +// val y: F_int, +//) +// +// +// +//typealias F_float = Float +//typealias F_double = Double +//typealias F_int = Int +//typealias F_int8 = Byte +// +// +////@JsExport +////@ExperimentalJsExport +//typealias F_uint = UInt +////expect class F_uint +// +////expect value class F_uint internal constructor(internal val data: Int) +//expect value class F_uint8 internal constructor(internal val data: Int) +//expect value class F_uint16 internal constructor(internal val data: Int) +//expect value class F_uint64 internal constructor(internal val data: Int) +// +//typealias F_table = Any? +// diff --git a/modules/factorio-events-data-model/src/jsMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt b/modules/factorio-events-data-model/src/jsMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt new file mode 100644 index 0000000..2e0cc08 --- /dev/null +++ b/modules/factorio-events-data-model/src/jsMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt @@ -0,0 +1,13 @@ +package dev.adamko.factorioevents.model + +import kotlin.js.* + +// +//@JsModule("typed-factorio") +//external class uint +// +//actual typealias F_uint = uint +//actual typealias F_uint8 = UByte +//actual typealias F_uint16 = UShort +//actual typealias F_uint64 = ULong +// diff --git a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt new file mode 100644 index 0000000..162eed3 --- /dev/null +++ b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt @@ -0,0 +1,97 @@ +@file:Suppress("ClassName") + +package dev.adamko.factorioevents.model + + +import kotlinx.serialization.Serializable + + +/* + * The basic types used in the Factorio API. While Lua only supports the `boolean`, `number`, + * `string`, and `table` types (as they relate to the types listed below), the API docs will + * specify what C++ types these are converted to or from internally. + */ + + +/** + * Tables are enclosed in curly brackets, like this `{}` + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#table) + */ +typealias F_table = MutableMap + +sealed interface FBuiltInType { + + sealed interface FNumber { + /** + * A floating-point number. This is a single-precision floating point number. Whilst Lua only uses double-precision + * numbers, when a function takes a float, the game engine will immediately convert the double-precision number to + * single-precision. + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#float) + */ + @Serializable + @JvmInline + value class F_float(val float: Float) : FNumber + /** + * A double-precision floating-point number. This is the same data type as all Lua numbers use. + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#double) + */ + @Serializable + @JvmInline + value class F_double(val double: Double) : FNumber + + /** + * 32-bit signed integer. Possible values are -2,147,483,648 to 2,147,483,647. + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#int) + */ + @Serializable + @JvmInline + value class F_int(val int: Int) : FNumber + /** + * 8-bit signed integer. Possible values are -128 to 127. + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#int8) + */ + @Serializable + @JvmInline + value class F_int8(val int8: Byte) : FNumber + + /** + * 32-bit unsigned integer. Possible values are 0 to 4,294,967,295. + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#uint) + */ + @Serializable + @JvmInline + value class F_uint(val uint: UInt) : FNumber + /** + * 8-bit unsigned integer. Possible values are 0 to 255. + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#uint8) + */ + @Serializable + @JvmInline + value class F_uint8(val uint8: UByte) : FNumber + /** + * 16-bit unsigned integer. Possible values are 0 to 65535. + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#uint16) + */ + @Serializable + @JvmInline + value class F_uint16(val uint16: UShort) : FNumber + /** + * 64-bit unsigned integer. Possible values are 0 to 18,446,744,073,709,551,615. + * + * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#uint64) + */ + @Serializable + @JvmInline + value class F_uint64(val uint64: ULong) : FNumber + } + + +} diff --git a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt new file mode 100644 index 0000000..1c6d81c --- /dev/null +++ b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt @@ -0,0 +1,58 @@ +package dev.adamko.factorioevents.model + +import dev.adamko.factorioevents.model.FBuiltInType.FNumber.F_float +import dev.adamko.factorioevents.model.FBuiltInType.FNumber.F_int +import dev.adamko.factorioevents.model.FBuiltInType.FNumber.F_uint + +import kotlinx.serialization.* +import kotlinx.serialization.builtins.* +import kotlinx.serialization.json.* +import kotlinx.serialization.modules.* + + +@Serializable +data class FactorioEvent( + val modVersion: String, + val tick: UInt, + val eventType: String, + val data: FactorioObjectData, +) + +@JsonClassDiscriminator("object_name") +sealed interface FactorioObjectData { + val objectName: String +} + +@SerialName("player") +data class PlayerData( + override val objectName: String, + val characterUnitNumber: UInt, + val associatedCharacterUnitNumbers: List, + val positionData: PositionData, +) : FactorioObjectData + +data class EntityData( + override val objectName: String, + val name: String, + val type: String, + val active: Boolean, + val healthRatio: Float, + val health: Float?, + val surface_index: Int, + val unit_number: UInt?, + val position: PositionData, + val player_index: UInt?, +) : FactorioObjectData + + +data class SurfaceData( + override val objectName: String, + val name: String, + val index: UInt, + val daytime: Float, +) : FactorioObjectData + +data class PositionData( + val x: Int, + val y: Int, +) \ No newline at end of file diff --git a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/main.kt b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/main.kt new file mode 100644 index 0000000..84248ae --- /dev/null +++ b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/main.kt @@ -0,0 +1,46 @@ +package dev.adamko.factorioevents.model + +import kotlin.reflect.KClass +import kotlin.reflect.KProperty +import me.ntrrgc.tsGenerator.ClassTransformer +import me.ntrrgc.tsGenerator.TypeScriptGenerator +import me.ntrrgc.tsGenerator.camelCaseToSnakeCase + + +fun main() { + + val gen = + TypeScriptGenerator( + rootClasses = + buildSet { + add(FactorioEvent::class) + addAll(FactorioObjectData::class.sealedSubclasses) + }, + mappings = mapOf( + // builtin Factorio numeric types > `typed-factorio/generated/builtin-types.d.ts` + Float::class to "float", + Double::class to "double", + Int::class to "int", + Byte::class to "int8", + UInt::class to "uint", + UByte::class to "uint8", + UShort::class to "uint16", + ULong::class to "uint64", + ), + classTransformers = listOf( + PropertyNameTransformer, + ) + ) + + println(gen.definitionsText) +} + +object PropertyNameTransformer : ClassTransformer { + override fun transformPropertyName( + propertyName: String, + property: KProperty<*>, + klass: KClass<*> + ): String { + return camelCaseToSnakeCase(propertyName) + } +} diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index 5868ba2..fa0274f 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -3,7 +3,9 @@ import org.apache.tools.ant.filters.ReplaceTokens import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { + idea id("dev.adamko.factoriowebmap.archetype.node") + id("dev.adamko.tstl") } val projectId: String by project.extra @@ -33,7 +35,7 @@ val tstlTask = tasks.register("typescriptToLua") { val intermediateOutputDir = temporaryDir args.set(parseSpaceSeparatedArgs("-- --outDir $intermediateOutputDir")) - val outputDir = modBuildDir.dir("typescriptToLua") + val outputDir: Directory = modBuildDir.dir("typescriptToLua") outputs.dir(outputDir) .withPropertyName("outputDir") @@ -54,19 +56,17 @@ val tstlTask = tasks.register("typescriptToLua") { idea { module { - sourceDirs.add(layout.projectDirectory.dir("src/main/typescript").asFile) - excludeDirs.add(layout.projectDirectory.dir("src/main/typescript/node_modules").asFile) - resourceDirs.add(layout.projectDirectory.dir("src/main/resources").asFile) - - resourceDirs.add(layout.projectDirectory.dir("infra").asFile) - excludeDirs.add(layout.projectDirectory.dir("infra/factorio-server").asFile) + sourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript").asFile)) + excludeDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript/node_modules").asFile)) + resourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/resources").asFile)) + resourceDirs.add(mkdir(layout.projectDirectory.dir("infra").asFile)) + excludeDirs.add(mkdir(layout.projectDirectory.dir("infra/factorio-server").asFile)) } } - val typescriptSrcSet = project.objects.sourceDirectorySet("typescript", "typescript").apply { - srcDir(mkdir("$projectDir/src/main/typescript")) + srcDir(layout.projectDirectory.dir("src/main/typescript")) destinationDirectory.set(modBuildDir.dir("typescriptToLua").asFile) compiledBy(tstlTask) { @@ -228,33 +228,3 @@ tasks.register("downloadFactorioApiDocs") { logger.lifecycle("Downloaded Factorio API json: $apiFile") } } - -//tasks.register("downloadLuaProtobuf") { -// group = projectId -// -// val luaProtobufVersion = "0.3.3" -// -// val target = uri("https://github.com/starwing/lua-protobuf/archive/refs/tags/$luaProtobufVersion.zip") -// val downloadedFile = file("$temporaryDir/luaProtobuf-$luaProtobufVersion.zip") -// -// val luaProto = modBuildDir.file(apiFilename) -// outputs.file(apiFile) -// -// doLast { -// -// ant.invokeMethod( -// "get", mapOf( -// "src" to target, -// "dest" to downloadedFile, -// "verbose" to true, -// ) -// ) -// -// val json = downloadedFile.readText() -// val prettyJson = groovy.json.JsonOutput.prettyPrint(json) -// -// apiFile.asFile.writeText(prettyJson) -// -// logger.lifecycle("Downloaded Factorio API json: $apiFile") -// } -//} \ No newline at end of file diff --git a/modules/mod/infra/docker-compose.yml b/modules/mod/infra/docker-compose.yml index 180c22b..3ee1c60 100644 --- a/modules/mod/infra/docker-compose.yml +++ b/modules/mod/infra/docker-compose.yml @@ -3,7 +3,7 @@ version: "3.9" services: factorio-server: - image: factoriotools/factorio:1.1.42 + image: factoriotools/factorio:1.1.46 # logging: # driver: "json-file" container_name: "factorio-server" diff --git a/modules/mod/src/main/typescript/events.ts b/modules/mod/src/main/typescript/events.ts index 4a5d20c..c7744a7 100644 --- a/modules/mod/src/main/typescript/events.ts +++ b/modules/mod/src/main/typescript/events.ts @@ -8,7 +8,7 @@ import {Serdes} from "./serdes/serdes" import {FactorioEvent, JsonTable} from "./model/model"; -const mapEventIdToName = new LuaTable() +const mapEventIdToName = new LuaTable() for (const [k, v] of pairs(defines.events)) { mapEventIdToName.set(v, k) } diff --git a/modules/mod/src/main/typescript/package-lock.json b/modules/mod/src/main/typescript/package-lock.json index b0ae77b..e7eaaf1 100644 --- a/modules/mod/src/main/typescript/package-lock.json +++ b/modules/mod/src/main/typescript/package-lock.json @@ -37,9 +37,9 @@ } }, "is-core-module": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz", - "integrity": "sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", "requires": { "has": "^1.0.3" } @@ -74,30 +74,27 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.8.0.tgz", - "integrity": "sha512-vuAJfkTBSQKD8mHCN7CAbwJJ73y+xfxLBPlFsYjjd015tMPv8Yrq1hBXxoUFZ1ZWGzNgcFL9RwZ6TspsIH7WJw==", + "version": "0.11.0-packagetypes-1", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.11.0-packagetypes-1.tgz", + "integrity": "sha512-oiN9XjODry434DPcgx3MNyC22/cOrbeU5/q0uM+Tj8BjJ7B42DYH+SR21tEtrHaWHNUJNX5iXD8h1Bk0N3Qvmw==", "requires": { "lua-types": "^2.10.1", "typescript-to-lua": "^1.0.0" } }, + "typescript": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", + "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==" + }, "typescript-to-lua": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.0.1.tgz", - "integrity": "sha512-j5mb+8HgUUY8hhAKoNy6KUMeamEN1fsTtMvSbPaxmVkWw40pHdLi3umsQG+Qo7wM6IK+RQffFxbIWEjleF+xpw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.1.1.tgz", + "integrity": "sha512-13vk/FSQyqbBkXNvg73LpT0tsPKdepJHPYR6TNtbc9l1ClSxAEUvkB3k49MAwSQ6LoN8Ui4Bgyu9dKFoDB315Q==", "requires": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", - "source-map": "^0.7.3", - "typescript": "~4.3.5" - }, - "dependencies": { - "typescript": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", - "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==" - } + "source-map": "^0.7.3" } } } diff --git a/modules/mod/src/main/typescript/package.json b/modules/mod/src/main/typescript/package.json index b25c3b9..076d3ae 100644 --- a/modules/mod/src/main/typescript/package.json +++ b/modules/mod/src/main/typescript/package.json @@ -13,8 +13,12 @@ "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", - "typescript-to-lua": "1.0.1", - "typed-factorio": "0.8.0" + "typescript-to-lua": "1.1.1", + "typed-factorio": "0.11.0-packagetypes-1", + "typescript": "4.4.4" + }, + "//": { + "typed-factorio": "0.10.0" }, "peerDependencies": {}, "optionalDependencies": {}, diff --git a/settings.gradle.kts b/settings.gradle.kts index b1206d7..b75fcf8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,7 +5,6 @@ rootProject.name = "factorio-web-map" include( ":modules:mod", -// ":modules:mod2", // ":modules:server", ":modules:kt-rcon", ":modules:factorio-events-data-model", @@ -31,22 +30,16 @@ dependencyResolutionManagement { repositories { mavenCentral() + maven("https://jitpack.io") maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") // Declare the Node.js download repository - ivy { - name = "Node.js" - setUrl("https://nodejs.org/dist/") - patternLayout { - artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") - } - metadataSources { - artifact() - } - content { - includeModule("org.nodejs", "node") - } + ivy("https://nodejs.org/dist/") { + name = "Node Distributions at $url" + patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") } + metadataSources { artifact() } + content { includeModule("org.nodejs", "node") } } } From d6a9a58dc9483aa83a8f21b9787b0592e7d670c8 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 26 Nov 2021 14:30:06 +0100 Subject: [PATCH 078/629] kotlin 1.6, gradle tidying --- README.md | 11 ++- buildSrc/build.gradle.kts | 32 +------- buildSrc/repositories.settings.gradle.kts | 45 +++++++++++ buildSrc/settings.gradle.kts | 42 +--------- .../archetype/kotlin-js.gradle.kts | 2 +- .../archetype/kotlin-jvm.gradle.kts | 5 +- .../gradle/json-kotlin-schema-gen.gradle.kts | 12 --- .../dev/adamko/gradle/tstl/TstlPlugin.kt | 24 ------ .../gradle/tstl/tasks/TypescriptToLuaTask.kt | 50 ------------ gradle/libs.versions.toml | 8 +- .../build.gradle.kts | 79 +------------------ .../factorioevents/model/factorioEvents.kt | 12 +-- modules/mod/build.gradle.kts | 1 - settings.gradle.kts | 46 +---------- 14 files changed, 74 insertions(+), 295 deletions(-) create mode 100644 buildSrc/repositories.settings.gradle.kts delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/json-kotlin-schema-gen.gradle.kts delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/TstlPlugin.kt delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/tasks/TypescriptToLuaTask.kt diff --git a/README.md b/README.md index 62bc90c..2a938cb 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ 1. converts data to images 2. hosts a web map -todo +## todo * add settings * is active - whether files are exported or not @@ -15,7 +15,7 @@ todo * requires on some sort of in-mod cache of map) * also divide by game-speed? to keep ratio the same -to investigate: +### to investigate: * https://github.com/starwing/lua-protobuf * https://github.com/grafi-tt/lunajson @@ -28,4 +28,9 @@ to investigate: * https://opensource.expediagroup.com/graphql-kotlin/docs/server/spring-server/spring-subscriptions * https://github.com/YousefED/typescript-json-schema -* https://jbrandhorst.com/post/go-protobuf-tips/ \ No newline at end of file +* https://jbrandhorst.com/post/go-protobuf-tips/ + +#### CBOR + +https://www.zash.se/lua-cbor.html +https://code.zash.se/lua-cbor/archive/68b3a36d0816.tar.gz \ No newline at end of file diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index f07747a..5e0c6e6 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -3,35 +3,13 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { idea `kotlin-dsl` - kotlin("jvm") version "1.5.31" + kotlin("jvm") version "1.6.0" `java-gradle-plugin` } -gradlePlugin { - plugins { - create("tstl") { - id = "dev.adamko.tstl" - description = - "Gradle plugin for TypescriptToLua. Requires plugin `com.github.node-gradle.node`." - implementationClass = "dev.adamko.gradle.tstl.TstlPlugin" - } - create("json-kotlin-schema-gen") { - id = "dev.adamko.json-kotlin-schema-gen" - description = - "Gradle plugin for 'json-kotlin-schema-codegen' - Code generation for JSON Schema (Draft 07) https://github.com/pwall567/json-kotlin-schema-codegen" - implementationClass = "dev.adamko.gradle.jsonkotlinschemagen.JsonKotlinSchemaGenPlugin" - } - } -} - dependencies { - val kotlinVersion = "1.5.31" - -// implementation(gradleApi()) - -// implementation("org.gradle.kotlin:gradle-kotlin-dsl-plugins:${org.gradle.kotlin.dsl.support.expectedKotlinDslPluginsVersion}") -// implementation("org.gradle.kotlin:gradle-kotlin-dsl-plugins:${kotlinVersion}") + val kotlinVersion = "1.6.0" implementation(platform("org.jetbrains.kotlin:kotlin-bom:$kotlinVersion")) implementation("org.jetbrains.kotlin:kotlin-serialization") @@ -39,8 +17,6 @@ dependencies { implementation("org.jetbrains.kotlin:kotlin-gradle-plugin") implementation("com.github.node-gradle:gradle-node-plugin:3.1.1") - - implementation("net.pwall.json:json-kotlin-schema-codegen:0.53") } val projectJvmTarget = "11" @@ -49,8 +25,8 @@ tasks.withType().configureEach { kotlinOptions { jvmTarget = projectJvmTarget - apiVersion = "1.5" - languageVersion = "1.5" + apiVersion = "1.6" + languageVersion = "1.6" } kotlinOptions.freeCompilerArgs += listOf( diff --git a/buildSrc/repositories.settings.gradle.kts b/buildSrc/repositories.settings.gradle.kts new file mode 100644 index 0000000..550a6d5 --- /dev/null +++ b/buildSrc/repositories.settings.gradle.kts @@ -0,0 +1,45 @@ + +@Suppress("UnstableApiUsage") +dependencyResolutionManagement { + + // https://github.com/gradle/gradle/issues/15754#issuecomment-763614651 + // https://github.com/gradle/gradle/blob/09fcaacc9848f09aa584b4119be9271bee6916e6/build-logic/build-logic-base/settings-plugin/src/main/kotlin/gradlebuild.repositories.settings.gradle.kts#L68 + + // Cannot use 'FAIL_ON_PROJECT_REPOS' because + // - the 'gradle-guides-plugin' adds a repo (which it should not do) + // - the 'kotlin-gradle-plugin' adds a repo (and removes it afterwards) to download NodeJS + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + + repositories { + mavenCentral() + gradlePluginPortal() + maven("https://jitpack.io") + maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") + maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") + + // Declare the Node.js download repository + ivy("https://nodejs.org/dist/") { + name = "Node Distributions at $url" + patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") } + metadataSources { artifact() } + content { includeModule("org.nodejs", "node") } + } + ivy("https://github.com/yarnpkg/yarn/releases/download") { + name = "Yarn Distributions at $url" + patternLayout { artifact("v[revision]/[artifact](-v[revision]).[ext]") } + metadataSources { artifact() } + content { includeModule("com.yarnpkg", "yarn") } + } + } + + pluginManagement { + + repositories { + mavenCentral() + gradlePluginPortal() + maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") + } + + } + +} diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts index 3080aa2..8065bb4 100644 --- a/buildSrc/settings.gradle.kts +++ b/buildSrc/settings.gradle.kts @@ -1,43 +1,3 @@ rootProject.name = "buildSrc" -enableFeaturePreview("VERSION_CATALOGS") -enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") - -@Suppress("UnstableApiUsage") -dependencyResolutionManagement { - - repositories { - mavenCentral() - gradlePluginPortal() - maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") - maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") - - // Declare the Node.js download repository - ivy { - name = "Node.js" - setUrl("https://nodejs.org/dist/") - patternLayout { - artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") - } - metadataSources { - artifact() - } - content { - includeModule("org.nodejs", "node") - } - } - } - - pluginManagement { - - repositories { - mavenCentral() - gradlePluginPortal() - maven { - url = uri("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") - } - } - - } - -} +apply(from = "./repositories.settings.gradle.kts") diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts index 4d1d5e9..26c4bc6 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts @@ -26,7 +26,7 @@ kotlin { } dependencies { - val kotlinWrappersVersion = "0.0.1-pre.263-kotlin-1.5.31" + val kotlinWrappersVersion = "0.0.1-pre.270-kotlin-1.6.0" implementation( project.dependencies.enforcedPlatform( "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts index 913b1a8..3065c31 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts @@ -36,6 +36,7 @@ dependencies { testImplementation("io.kotest:kotest-assertions-core-jvm:$kotestVersion") testImplementation("io.kotest:kotest-property-jvm:$kotestVersion") testImplementation("io.kotest:kotest-assertions-json:$kotestVersion") + testImplementation("io.mockk:mockk:1.12.0") // @@ -46,8 +47,8 @@ tasks.withType().configureEach { kotlinOptions { jvmTarget = "11" - apiVersion = "1.5" - languageVersion = "1.5" + apiVersion = "1.6" + languageVersion = "1.6" } kotlinOptions.freeCompilerArgs += listOf( diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/json-kotlin-schema-gen.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/gradle/json-kotlin-schema-gen.gradle.kts deleted file mode 100644 index 374f9f2..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/json-kotlin-schema-gen.gradle.kts +++ /dev/null @@ -1,12 +0,0 @@ -package dev.adamko.gradle - -import org.gradle.kotlin.dsl.`component-model-base` -import org.gradle.kotlin.dsl.kotlin - - -plugins { - base -} - - - diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/TstlPlugin.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/TstlPlugin.kt deleted file mode 100644 index d506592..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/TstlPlugin.kt +++ /dev/null @@ -1,24 +0,0 @@ -package dev.adamko.gradle.tstl - -import com.github.gradle.node.NodePlugin -import dev.adamko.gradle.tstl.tasks.TypescriptToLuaTask -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.api.plugins.BasePlugin -import org.gradle.kotlin.dsl.withType -import org.gradle.language.base.plugins.LifecycleBasePlugin - - -class TstlPlugin : Plugin { - override fun apply(project: Project) { - - project.plugins.withType { - } - - project.plugins.withType { - project.tasks.named(LifecycleBasePlugin.ASSEMBLE_TASK_NAME) { - dependsOn(project.tasks.withType()) - } - } - } -} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/tasks/TypescriptToLuaTask.kt b/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/tasks/TypescriptToLuaTask.kt deleted file mode 100644 index 4da82d3..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/gradle/tstl/tasks/TypescriptToLuaTask.kt +++ /dev/null @@ -1,50 +0,0 @@ -package dev.adamko.gradle.tstl.tasks - -import com.github.gradle.node.npm.task.* -import org.gradle.api.file.* -import org.gradle.api.provider.* -import org.gradle.api.tasks.* -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs -import org.gradle.kotlin.dsl.* - -abstract class TypescriptToLuaTask : NpmTask() { - - @get:Internal - val intermediateOutputDir: RegularFileProperty = project.objects.fileProperty() - .convention { temporaryDir } - - @get:Internal - val intermediateOutputCanonicalPath: Provider = - intermediateOutputDir.map { it.asFile.canonicalPath } - - @get:Input - val identifier: Property = project.objects.property().convention(name) - - @get:Internal - val luaOutputDirConvention: Provider = - project.layout.buildDirectory.map { it.dir("typescriptToLua/${identifier.get()}") } - - @get:OutputDirectory - val luaOutputDir: DirectoryProperty = project.objects.directoryProperty() - .convention(luaOutputDirConvention) - - init { - group = "typescriptToLua" - - execOverrides { standardOutput = System.out } - - super.dependsOn(project.tasks.withType()) - ignoreExitValue.set(false) - } - - @TaskAction - fun convert() { - args.set(parseSpaceSeparatedArgs("-- --outDir ${intermediateOutputCanonicalPath.get()}")) - - project.delete(intermediateOutputDir.get()) - - super.exec() - - } - -} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b0981cc..2751a37 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ ## compilation ## jvm = "11" -kotlin = "1.5.31" +kotlin = "1.6.0" ## libs ## http4k = "4.16.1.0" @@ -45,9 +45,9 @@ sendgrid = { group = "com.sendgrid", name = "sendgrid-java", version ## kotlin ## kotlin-bom = { group = "org.jetbrains.kotlin", name = "kotlin-bom", version.ref = "kotlin" } -kotlinx-serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version = "1.3.0" } -kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.5.2" } -kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.7.3" } +kotlinx-serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version = "1.3.0" } +kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.6.0-RC" } +kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.7.3" } ## http4k ## http4k-bom = { group = "org.http4k", name = "http4k-bom", version.ref = "http4k" } diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index 618df6e..48aae2d 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -1,4 +1,3 @@ -import org.gradle.process.internal.DefaultExecSpec import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation @@ -21,8 +20,8 @@ kotlin { compilations.configureEach { kotlinOptions { jvmTarget = "11" - apiVersion = "1.5" - languageVersion = "1.5" + apiVersion = "1.6" + languageVersion = "1.6" } } } @@ -76,7 +75,7 @@ kotlin { sourceSets.all { languageSettings.apply { - languageVersion = "1.5" + languageVersion = "1.6" // enableLanguageFeature("InlineClasses") // language feature name optIn("kotlin.OptIn") optIn("kotlin.RequiresOptIn") @@ -91,25 +90,8 @@ kotlin { } - - -//kotlin.js() -// .compilations -// .getByName(KotlinCompilation.MAIN_COMPILATION_NAME) -// .npmProject -// .useTool() - - afterEvaluate { -// val nodeJsExecTstl by tasks.creating(NodeJsExec::class) { -// group = project.name -// -// nodeArgs += listOf( -// "tstl", -// ) -// } - val kotlinJsCompilation: KotlinJsCompilation = kotlin.targets .flatMap { it.compilations } @@ -124,8 +106,7 @@ afterEvaluate { errorOutput = System.err workingDir = npmProject.dir - executable = - when (npmProject.nodeJs.requireConfigured().isWindows) { + executable = when (npmProject.nodeJs.requireConfigured().isWindows) { true -> "npx.cmd" false -> "npx" } @@ -134,58 +115,6 @@ afterEvaluate { } - tasks.create("asd") { - group = project.name - - doLast { - - val execSpec = - project.objects.newInstance(DefaultExecSpec::class.java).apply { - isIgnoreExitValue = false - standardOutput = System.out - errorOutput = System.err - } - - kotlin.targets - .flatMap { it.compilations } - .filterIsInstance() - .filter { it.name == KotlinCompilation.MAIN_COMPILATION_NAME } - .forEach { - - org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsExec.create(it, "blahDeBlah") { - - } - - execSpec.workingDir = it.npmProject.dir - - execSpec.executable = - when (it.npmProject.nodeJs.requireConfigured().isWindows) { - true -> "npx.cmd" - false -> "npx" - } - - execSpec.args("tstl", "--version") - -// execSpec.commandLine - - -// it.npmProject.useTool( -// execSpec, -// "typescript-to-lua/dist/tstl.js", -// listOf(), -// listOf( "--outDir","$buildDir/testAsd"), -// listOf("--version"), -// listOf(), -// ) - } - - exec { - execSpec.copyTo(this) - } - - } - } - } diff --git a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt index 1c6d81c..bb5d928 100644 --- a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt +++ b/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt @@ -1,13 +1,8 @@ package dev.adamko.factorioevents.model -import dev.adamko.factorioevents.model.FBuiltInType.FNumber.F_float -import dev.adamko.factorioevents.model.FBuiltInType.FNumber.F_int -import dev.adamko.factorioevents.model.FBuiltInType.FNumber.F_uint - -import kotlinx.serialization.* -import kotlinx.serialization.builtins.* -import kotlinx.serialization.json.* -import kotlinx.serialization.modules.* +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonClassDiscriminator @Serializable @@ -44,7 +39,6 @@ data class EntityData( val player_index: UInt?, ) : FactorioObjectData - data class SurfaceData( override val objectName: String, val name: String, diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index fa0274f..e120d00 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -5,7 +5,6 @@ import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { idea id("dev.adamko.factoriowebmap.archetype.node") - id("dev.adamko.tstl") } val projectId: String by project.extra diff --git a/settings.gradle.kts b/settings.gradle.kts index b75fcf8..c0e4e8b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,58 +1,14 @@ rootProject.name = "factorio-web-map" - -//includeBuild("modules/protoc-gradle-plugin") - include( ":modules:mod", -// ":modules:server", ":modules:kt-rcon", ":modules:factorio-events-data-model", -// ":modules:factorio-events-data-model2", ":modules:factorio-events-processor", ":modules:factorio-events-kafka-pipe", ) - enableFeaturePreview("VERSION_CATALOGS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") -@Suppress("UnstableApiUsage") -dependencyResolutionManagement { - - // https://github.com/gradle/gradle/issues/15754#issuecomment-763614651 - // https://github.com/gradle/gradle/blob/09fcaacc9848f09aa584b4119be9271bee6916e6/build-logic/build-logic-base/settings-plugin/src/main/kotlin/gradlebuild.repositories.settings.gradle.kts#L68 - - // Cannot use 'FAIL_ON_PROJECT_REPOS' because - // - the 'gradle-guides-plugin' adds a repo (which it should not do) - // - the 'kotlin-gradle-plugin' adds a repo (and removes it afterwards) to download NodeJS - repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) - - repositories { - mavenCentral() - maven("https://jitpack.io") - maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") - maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") - - // Declare the Node.js download repository - ivy("https://nodejs.org/dist/") { - name = "Node Distributions at $url" - patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") } - metadataSources { artifact() } - content { includeModule("org.nodejs", "node") } - } - } - - pluginManagement { - - repositories { - mavenCentral() - gradlePluginPortal() - maven { - url = uri("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") - } - } - - } - -} +apply(from = "./buildSrc/repositories.settings.gradle.kts") From 0d85bfca60c664e994e42d9bc7bdc078e40ea446 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 27 Nov 2021 17:57:50 +0100 Subject: [PATCH 079/629] get a shared kotlin-typescript data model working --- .../factoriowebmap/configurations/type.kt | 15 ++ .../configurations/typescript.kt | 20 +++ .../build.gradle.kts | 132 ++++-------------- .../factorioevents/model/FactorioEvent.kt | 56 -------- .../factorioevents/model/FactorioEvent.kt | 13 -- .../factorioevents/model/builtinTypes.kt | 0 .../factorioevents/model/factorioEvents.kt | 9 +- .../dev/adamko/factorioevents/model/kt2ts.kt} | 30 +++- modules/mod/build.gradle.kts | 31 ++++ .../main/typescript/generated/data-model.ts | 45 ++++++ 10 files changed, 173 insertions(+), 178 deletions(-) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/type.kt create mode 100644 buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/typescript.kt delete mode 100644 modules/factorio-events-data-model/src/commonMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt delete mode 100644 modules/factorio-events-data-model/src/jsMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt rename modules/factorio-events-data-model/src/{jvmMain => main}/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt (100%) rename modules/factorio-events-data-model/src/{jvmMain => main}/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt (85%) rename modules/factorio-events-data-model/src/{jvmMain/kotlin/dev/adamko/factorioevents/model/main.kt => main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt} (66%) create mode 100644 modules/mod/src/main/typescript/generated/data-model.ts diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/type.kt b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/type.kt new file mode 100644 index 0000000..272b7ce --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/type.kt @@ -0,0 +1,15 @@ +package dev.adamko.factoriowebmap.configurations + +import org.gradle.api.artifacts.Configuration + +fun Configuration.asProvider() { + isVisible = false + isCanBeResolved = false + isCanBeConsumed = true +} + +fun Configuration.asConsumer() { + isVisible = false + isCanBeResolved = true + isCanBeConsumed = false +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/typescript.kt b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/typescript.kt new file mode 100644 index 0000000..2020f16 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/typescript.kt @@ -0,0 +1,20 @@ +package dev.adamko.factoriowebmap.configurations + +import org.gradle.api.artifacts.Configuration +import org.gradle.api.attributes.AttributeContainer +import org.gradle.api.attributes.Bundling +import org.gradle.api.attributes.Category +import org.gradle.api.attributes.LibraryElements +import org.gradle.api.attributes.Usage +import org.gradle.api.model.ObjectFactory +import org.gradle.kotlin.dsl.named + +fun Configuration.typescriptAttributes(objects: ObjectFactory) = + attributes { typescript(objects) } + +fun AttributeContainer.typescript(objects: ObjectFactory) { + attribute(Usage.USAGE_ATTRIBUTE, objects.named("typescript")) + attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) + attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.OBJECTS)) + attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL)) +} diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index 48aae2d..f422934 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -1,120 +1,46 @@ -import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation -import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation -import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs - +import dev.adamko.factoriowebmap.configurations.asProvider +import dev.adamko.factoriowebmap.configurations.typescriptAttributes plugins { - id("dev.adamko.factoriowebmap.archetype.kotlin-multiplatform") + id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") kotlin("plugin.serialization") } val projectId: String by project.extra val buildDir: Directory = layout.buildDirectory.dir(projectId).get() -kotlin { +dependencies { + val kotlinXSerializationVersion = "1.3.0" + implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$kotlinXSerializationVersion") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinXSerializationVersion") - // - jvm { - compilations.configureEach { - kotlinOptions { - jvmTarget = "11" - apiVersion = "1.6" - languageVersion = "1.6" - } - } - } + implementation("com.github.ntrrgc:ts-generator:1.1.2") + implementation("org.jetbrains.kotlin:kotlin-reflect") +} - sourceSets { - val jvmMain by getting { - dependencies { - implementation("com.github.ntrrgc:ts-generator:1.1.1") - implementation("org.jetbrains.kotlin:kotlin-reflect") +val generateTypescript by tasks.registering(JavaExec::class) { + group = project.name - val kotlinXSerializationVersion = "1.3.0" - implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$kotlinXSerializationVersion") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinXSerializationVersion") - } - } - val jvmTest by getting { - } - } + val generatedFileName = "$temporaryDir/data-model.ts" + inputs.property("generatedFileName", generatedFileName) + outputs.file(generatedFileName) - // + classpath(sourceSets.main.map { it.runtimeClasspath }) + mainClass.set("dev.adamko.factorioevents.model.Kt2tsKt") + args(generatedFileName) - // - js(IR) { - moduleName = "data-model" - browser { } - binaries.executable() - } - - sourceSets { - val jsMain: KotlinSourceSet by getting { - - dependencies { - - implementation(npm("lua-types", "^2.11.0")) - implementation(npm("@types/node", "^12.0.8")) - implementation(npm("typescript-to-lua", "1.1.1")) - implementation(npm("typescript", "4.4.4")) - implementation(npm("typed-factorio", "0.11.0-packagetypes-1", false)) - - } - - } - - val jsTest by getting { - dependencies { - implementation(kotlin("test-js")) - } - } - } - // - - sourceSets.all { - languageSettings.apply { - languageVersion = "1.6" -// enableLanguageFeature("InlineClasses") // language feature name - optIn("kotlin.OptIn") - optIn("kotlin.RequiresOptIn") - optIn("kotlin.ExperimentalStdlibApi") - optIn("kotlin.time.ExperimentalTime") - optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") - optIn("kotlin.js.ExperimentalJsExport") - optIn("kotlinx.serialization.ExperimentalSerializationApi") -// progressiveMode = true // false by default - } + doFirst { + delete(temporaryDir) + mkdir(temporaryDir) } } - -afterEvaluate { - - val kotlinJsCompilation: KotlinJsCompilation = - kotlin.targets - .flatMap { it.compilations } - .filterIsInstance() - .first { it.name == KotlinCompilation.MAIN_COMPILATION_NAME } - val npmProject = kotlinJsCompilation.npmProject - - tasks.create("tstl") { - group = project.name - - standardOutput = System.out - errorOutput = System.err - - workingDir = npmProject.dir - executable = when (npmProject.nodeJs.requireConfigured().isWindows) { - true -> "npx.cmd" - false -> "npx" - } - - args(parseSpaceSeparatedArgs("tstl --out $temporaryDir")) - - } - +val typescriptModelGenerated by configurations.registering { + asProvider() + typescriptAttributes(objects) + outgoing.artifact( + generateTypescript.map { + it.outputs.files.singleFile + } + ) } - - diff --git a/modules/factorio-events-data-model/src/commonMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt b/modules/factorio-events-data-model/src/commonMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt deleted file mode 100644 index 25ff622..0000000 --- a/modules/factorio-events-data-model/src/commonMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt +++ /dev/null @@ -1,56 +0,0 @@ -package dev.adamko.factorioevents.model - -import kotlin.js.ExperimentalJsExport -import kotlin.js.JsExport - -// -//@JsExport -//@ExperimentalJsExport -//data class FactorioEvent( -// val modVersion: String, -// val tick: F_uint, -// val eventType: String, -// val data: FactorioObjectData, -//) -// -//@JsExport -//abstract class FactorioObjectData { -// abstract val objectName: String -//} -// -//@JsExport -//data class PlayerData( -// override val objectName: String, -// val name: String, -// val characterUnitNumber: F_uint, -// val associatedCharactersUnitNumbers: List, -// val position: PositionData, -//) : FactorioObjectData() -// -// -//@JsExport -//data class PositionData( -// val x: F_int, -// val y: F_int, -//) -// -// -// -//typealias F_float = Float -//typealias F_double = Double -//typealias F_int = Int -//typealias F_int8 = Byte -// -// -////@JsExport -////@ExperimentalJsExport -//typealias F_uint = UInt -////expect class F_uint -// -////expect value class F_uint internal constructor(internal val data: Int) -//expect value class F_uint8 internal constructor(internal val data: Int) -//expect value class F_uint16 internal constructor(internal val data: Int) -//expect value class F_uint64 internal constructor(internal val data: Int) -// -//typealias F_table = Any? -// diff --git a/modules/factorio-events-data-model/src/jsMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt b/modules/factorio-events-data-model/src/jsMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt deleted file mode 100644 index 2e0cc08..0000000 --- a/modules/factorio-events-data-model/src/jsMain/kotlin/dev/adamko/factorioevents/model/FactorioEvent.kt +++ /dev/null @@ -1,13 +0,0 @@ -package dev.adamko.factorioevents.model - -import kotlin.js.* - -// -//@JsModule("typed-factorio") -//external class uint -// -//actual typealias F_uint = uint -//actual typealias F_uint8 = UByte -//actual typealias F_uint16 = UShort -//actual typealias F_uint64 = ULong -// diff --git a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt b/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt similarity index 100% rename from modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt rename to modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt diff --git a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt b/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt similarity index 85% rename from modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt rename to modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt index bb5d928..4f7865e 100644 --- a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt +++ b/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt @@ -7,8 +7,11 @@ import kotlinx.serialization.json.JsonClassDiscriminator @Serializable data class FactorioEvent( + /** Schema versioning */ val modVersion: String, + /** game time */ val tick: UInt, + /** the initial Factorio event ({defines.events}) trigger */ val eventType: String, val data: FactorioObjectData, ) @@ -33,10 +36,10 @@ data class EntityData( val active: Boolean, val healthRatio: Float, val health: Float?, - val surface_index: Int, - val unit_number: UInt?, + val surfaceIndex: Int, + val unitNumber: UInt?, val position: PositionData, - val player_index: UInt?, + val playerIndex: UInt?, ) : FactorioObjectData data class SurfaceData( diff --git a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/main.kt b/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt similarity index 66% rename from modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/main.kt rename to modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt index 84248ae..e6fe4e9 100644 --- a/modules/factorio-events-data-model/src/jvmMain/kotlin/dev/adamko/factorioevents/model/main.kt +++ b/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt @@ -1,13 +1,14 @@ package dev.adamko.factorioevents.model +import java.io.File import kotlin.reflect.KClass import kotlin.reflect.KProperty import me.ntrrgc.tsGenerator.ClassTransformer import me.ntrrgc.tsGenerator.TypeScriptGenerator import me.ntrrgc.tsGenerator.camelCaseToSnakeCase +import org.intellij.lang.annotations.Language - -fun main() { +fun main(args: Array) { val gen = TypeScriptGenerator( @@ -32,9 +33,32 @@ fun main() { ) ) - println(gen.definitionsText) + val definitions = gen.definitionsText + + when (val filename = args.firstOrNull()) { + null -> { + println(definitions) + } + else -> { + val out = File(filename) + out.parentFile.mkdirs() + out.printWriter().use { + it.print(header) + it.print(definitions) + } + println("Generated file: $out") + } + } } +@Language("TypeScript") +val header = """ + + // Generated code - do edit this file manually + + +""".trimIndent() + object PropertyNameTransformer : ClassTransformer { override fun transformPropertyName( propertyName: String, diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index e120d00..3590ace 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -1,4 +1,6 @@ import com.github.gradle.node.npm.task.NpmTask +import dev.adamko.factoriowebmap.configurations.asConsumer +import dev.adamko.factoriowebmap.configurations.typescriptAttributes import org.apache.tools.ant.filters.ReplaceTokens import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs @@ -53,6 +55,35 @@ val tstlTask = tasks.register("typescriptToLua") { } +val dataModelTs: Configuration by configurations.creating { + asConsumer() + typescriptAttributes(objects) +} + +dependencies { + dataModelTs(projects.modules.factorioEventsDataModel) +} + +val updateDataModel by tasks.registering(Sync::class) { + group = project.name + + dependsOn(dataModelTs) + + from( + dataModelTs.incoming + .artifactView { lenient(true) } + .artifacts + .artifactFiles + .filter { it.exists() } + ) + + into(layout.projectDirectory.dir("src/main/typescript/generated")) +} + +tasks.assemble { dependsOn(updateDataModel) } + + + idea { module { sourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript").asFile)) diff --git a/modules/mod/src/main/typescript/generated/data-model.ts b/modules/mod/src/main/typescript/generated/data-model.ts new file mode 100644 index 0000000..cf85b17 --- /dev/null +++ b/modules/mod/src/main/typescript/generated/data-model.ts @@ -0,0 +1,45 @@ + +// Generated code - do edit this file manually + +interface FactorioObjectData { + object_name: string; +} + +interface FactorioEvent { + data: FactorioObjectData; + event_type: string; + mod_version: string; + tick: uint; +} + +interface PositionData { + x: int; + y: int; +} + +interface PlayerData extends FactorioObjectData { + associated_character_unit_numbers: uint[]; + character_unit_number: uint; + object_name: string; + position_data: PositionData; +} + +interface EntityData extends FactorioObjectData { + active: boolean; + health: float | null; + health_ratio: float; + name: string; + object_name: string; + player_index: uint | null; + position: PositionData; + surface_index: int; + type: string; + unit_number: uint | null; +} + +interface SurfaceData extends FactorioObjectData { + daytime: float; + index: uint; + name: string; + object_name: string; +} \ No newline at end of file From 51918a2fb2b2886a3f1651b6841f1c57e8ea9db8 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 27 Nov 2021 19:32:19 +0100 Subject: [PATCH 080/629] events are up and running again, and are produced to Kafka... next step is to consume the messages --- build.gradle.kts | 2 +- .../factorioevents/model/factorioEvents.kt | 36 ++++---- modules/mod/infra/docker-compose.yml | 2 +- modules/mod/src/main/typescript/events.ts | 26 ++++-- .../main/typescript/generated/data-model.ts | 11 +-- .../mod/src/main/typescript/model/model.ts | 83 +++++++++---------- .../mod/src/main/typescript/package-lock.json | 14 ++-- modules/mod/src/main/typescript/package.json | 6 +- .../mod/src/main/typescript/serdes/serdes.ts | 61 ++++---------- 9 files changed, 112 insertions(+), 129 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 1d51ecb..f3a3cac 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } group = "dev.adamko.factoriowebmap" -version = "0.0.3" +version = "0.0.4" tasks.wrapper { gradleVersion = "7.3" diff --git a/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt b/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt index 4f7865e..2648afc 100644 --- a/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt +++ b/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt @@ -6,14 +6,14 @@ import kotlinx.serialization.json.JsonClassDiscriminator @Serializable -data class FactorioEvent( +data class FactorioEvent( + /** the initial Factorio event ({defines.events}) trigger */ + val eventType: String, /** Schema versioning */ val modVersion: String, /** game time */ val tick: UInt, - /** the initial Factorio event ({defines.events}) trigger */ - val eventType: String, - val data: FactorioObjectData, + val data: T, ) @JsonClassDiscriminator("object_name") @@ -21,34 +21,40 @@ sealed interface FactorioObjectData { val objectName: String } -@SerialName("player") +@SerialName("LuaPlayer") data class PlayerData( override val objectName: String, - val characterUnitNumber: UInt, - val associatedCharacterUnitNumbers: List, - val positionData: PositionData, + val associatedCharactersUnitNumbers: List, + val characterUnitNumber: UInt?, + val name: String, + val position: PositionData, ) : FactorioObjectData +@SerialName("LuaEntity") data class EntityData( override val objectName: String, - val name: String, - val type: String, + val active: Boolean, - val healthRatio: Float, val health: Float?, - val surfaceIndex: Int, - val unitNumber: UInt?, + val healthRatio: Float, + val name: String, val position: PositionData, + val surfaceIndex: Int, + val type: String, + val unitNumber: UInt?, + val playerIndex: UInt?, ) : FactorioObjectData +@SerialName("LuaSurface") data class SurfaceData( override val objectName: String, - val name: String, - val index: UInt, val daytime: Float, + val index: UInt, + val name: String, ) : FactorioObjectData +@Serializable data class PositionData( val x: Int, val y: Int, diff --git a/modules/mod/infra/docker-compose.yml b/modules/mod/infra/docker-compose.yml index 3ee1c60..3b42704 100644 --- a/modules/mod/infra/docker-compose.yml +++ b/modules/mod/infra/docker-compose.yml @@ -3,7 +3,7 @@ version: "3.9" services: factorio-server: - image: factoriotools/factorio:1.1.46 + image: factoriotools/factorio:1.1.48 # logging: # driver: "json-file" container_name: "factorio-server" diff --git a/modules/mod/src/main/typescript/events.ts b/modules/mod/src/main/typescript/events.ts index c7744a7..e63cf1f 100644 --- a/modules/mod/src/main/typescript/events.ts +++ b/modules/mod/src/main/typescript/events.ts @@ -6,7 +6,10 @@ import {Serdes} from "./serdes/serdes" -import {FactorioEvent, JsonTable} from "./model/model"; +// import {FactorioEvent, JsonTable} from "./model/model"; + + +const MOD_VERSION = script.active_mods["factorio-web-map"] const mapEventIdToName = new LuaTable() for (const [k, v] of pairs(defines.events)) { @@ -16,8 +19,7 @@ for (const [k, v] of pairs(defines.events)) { function handlePlayerUpdate(tick: uint, playerIndex: uint, eventType: string) { let player: LuaPlayer = game.players[playerIndex] let table = Serdes.Player.playerToTable(player) - let event = FactorioEvent(tick, eventType, table) - emitEvent(event) + emitEvent(table, tick, eventType) handleCharactersEvent(tick, playerIndex, eventType) } @@ -38,22 +40,28 @@ function handleCharactersEvent(tick: uint, playerIndex: uint, eventType: string) function handleEntityUpdate(tick: uint, entity: LuaEntity, eventType: string) { let table = Serdes.Entity.entityToTable(entity) - let event = FactorioEvent(tick, eventType, table) - emitEvent(event) + emitEvent(table, tick, eventType) } function surfaceEvent(tick: uint, surface: LuaSurface, eventType: string) { let table = Serdes.Surface.surfaceToTable(surface) - let event = FactorioEvent(tick, eventType, table) - emitEvent(event) + emitEvent(table, tick, eventType) } // const SERVER_ID: uint = 0 // const EVENT_FILE_DIR: string = "events" /** Emit a serialised event */ -function emitEvent(event: JsonTable) { +function emitEvent(eventData: T, tick: uint, eventType: string) { + + let event: FactorioEvent = { + data: eventData, + event_type: eventType, + mod_version: MOD_VERSION, + tick: tick + } + let data = game.table_to_json(event) - // game.write_file(EVENT_FILE_DIR + "/" + filename, data, false, SERVER_ID) + localised_print(`FactorioEvent: ${data}`) } diff --git a/modules/mod/src/main/typescript/generated/data-model.ts b/modules/mod/src/main/typescript/generated/data-model.ts index cf85b17..f6b435d 100644 --- a/modules/mod/src/main/typescript/generated/data-model.ts +++ b/modules/mod/src/main/typescript/generated/data-model.ts @@ -5,8 +5,8 @@ interface FactorioObjectData { object_name: string; } -interface FactorioEvent { - data: FactorioObjectData; +interface FactorioEvent { + data: T; event_type: string; mod_version: string; tick: uint; @@ -18,10 +18,11 @@ interface PositionData { } interface PlayerData extends FactorioObjectData { - associated_character_unit_numbers: uint[]; - character_unit_number: uint; + associated_characters_unit_numbers: uint[]; + character_unit_number: uint | null; + name: string; object_name: string; - position_data: PositionData; + position: PositionData; } interface EntityData extends FactorioObjectData { diff --git a/modules/mod/src/main/typescript/model/model.ts b/modules/mod/src/main/typescript/model/model.ts index 125a27c..29909f4 100644 --- a/modules/mod/src/main/typescript/model/model.ts +++ b/modules/mod/src/main/typescript/model/model.ts @@ -1,47 +1,46 @@ -import {Serdes} from "../serdes/serdes"; -import FactorioObjectData = Serdes.FactorioObjectData; +// import {Serdes} from "../serdes/serdes"; +// import FactorioObjectData = Serdes.FactorioObjectData; +// +// export type JsonPrimitiveType = number | string | boolean | undefined | null | void +// +// export type JsonArray = T[] +// +// export type JsonTableValueType = +// JsonPrimitiveType +// | JsonTable +// | JsonArray +// | undefined +// | null +// +// export interface JsonTable { +// [key: string]: JsonTableValueType +// } -export type JsonPrimitiveType = number | string | boolean | undefined | null | void -export type JsonArray = T[] - -export type JsonTableValueType = - JsonPrimitiveType - | JsonTable - | JsonArray - | undefined - | null - -export interface JsonTable { - [key: string]: JsonTableValueType -} - -const MOD_VERSION = script.active_mods["factorio-web-map"] - -export interface FactorioEvent extends JsonTable { - /** Schema versioning */ - mod_version: string, - /** game time */ - tick: uint, - /** the initial Factorio event ({defines.events}) trigger */ - event_type: string, - data: FactorioObjectData, -} - -export const FactorioEvent = - (( - tick: uint, - eventType: string, - data: DataType - ) => { - return { - mod_version: MOD_VERSION, - tick: tick, - event_type: eventType, - data: data, - } as FactorioEvent - } - ) +// export interface FactorioEvent extends JsonTable { +// /** Schema versioning */ +// mod_version: string, +// /** game time */ +// tick: uint, +// /** the initial Factorio event ({defines.events}) trigger */ +// event_type: string, +// data: FactorioObjectData, +// } +// +// export const FactorioEvent = +// (( +// tick: uint, +// eventType: string, +// data: DataType +// ) => { +// return { +// mod_version: MOD_VERSION, +// tick: tick, +// event_type: eventType, +// data: data, +// } as FactorioEvent +// } +// ) // export type JsonArray = TValue[] diff --git a/modules/mod/src/main/typescript/package-lock.json b/modules/mod/src/main/typescript/package-lock.json index e7eaaf1..0a1276e 100644 --- a/modules/mod/src/main/typescript/package-lock.json +++ b/modules/mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "factorio-web-map-mod", - "version": "0.0.3", + "version": "0.0.4", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -74,18 +74,18 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "0.11.0-packagetypes-1", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.11.0-packagetypes-1.tgz", - "integrity": "sha512-oiN9XjODry434DPcgx3MNyC22/cOrbeU5/q0uM+Tj8BjJ7B42DYH+SR21tEtrHaWHNUJNX5iXD8h1Bk0N3Qvmw==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.12.0.tgz", + "integrity": "sha512-7SeZX7TvWjtO+V5buWEgHUbhi7tSNZsHGveh5uPQ6Vvr7BDEhHre9DP3OrdD+L7cpAtvJ2w9OwaMnDm2P5dvng==", "requires": { "lua-types": "^2.10.1", "typescript-to-lua": "^1.0.0" } }, "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==" + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", + "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==" }, "typescript-to-lua": { "version": "1.1.1", diff --git a/modules/mod/src/main/typescript/package.json b/modules/mod/src/main/typescript/package.json index 076d3ae..91aa84e 100644 --- a/modules/mod/src/main/typescript/package.json +++ b/modules/mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "factorio-web-map-mod", - "version": "0.0.3", + "version": "0.0.4", "private": true, "scripts": { "build": "tstl", @@ -14,8 +14,8 @@ "lua-types": "^2.11.0", "@types/node": "^12.0.8", "typescript-to-lua": "1.1.1", - "typed-factorio": "0.11.0-packagetypes-1", - "typescript": "4.4.4" + "typed-factorio": "0.12.0", + "typescript": "4.5.2" }, "//": { "typed-factorio": "0.10.0" diff --git a/modules/mod/src/main/typescript/serdes/serdes.ts b/modules/mod/src/main/typescript/serdes/serdes.ts index b3de4be..b33e595 100644 --- a/modules/mod/src/main/typescript/serdes/serdes.ts +++ b/modules/mod/src/main/typescript/serdes/serdes.ts @@ -1,28 +1,20 @@ -import {JsonTable, JsonArray} from "../model/model"; +// import {JsonTable, JsonArray} from "../model/model"; -import PositionData = Serdes.DataClasses.PositionData; export namespace Serdes { - export interface FactorioObjectData extends JsonTable { - object_name: string - } + // export interface FactorioObjectData extends JsonTable { + // object_name: string + // } export namespace Player { - export interface PlayerData extends FactorioObjectData { - name: string - character_unit_number?: uint - associated_characters_unit_numbers: JsonArray - position: PositionData - } - export function playerToTable(player: LuaPlayer): PlayerData { let charIds = Entity.entitiesToUnitNumbers(player.get_associated_characters()) return { object_name: player.object_name, name: player.name, - character_unit_number: player.character?.unit_number, + character_unit_number: player.character?.unit_number ?? null, associated_characters_unit_numbers: charIds, position: DataClasses.positionTableToTable(player.position), } @@ -32,40 +24,28 @@ export namespace Serdes { export namespace Entity { - interface EntityData extends FactorioObjectData { - name: string - type: string - active: boolean - health?: number - surface_index: int - unit_number?: number - position: PositionData - player_index?: number - } - export function entityToTable(entity: LuaEntity): EntityData { - let data: EntityData = { + let player: LuaPlayer | null = entity.is_player() ? entity.player!! : null + + return { object_name: entity.object_name, name: entity.name, type: entity.type, active: entity.active, - health: entity.health, + health: entity.health ?? null, + health_ratio: entity.get_health_ratio(), surface_index: entity.surface.index, - unit_number: entity.unit_number, + unit_number: entity.unit_number ?? null, position: DataClasses.positionTableToTable(entity.position), - } - if (entity.is_player()) { - let player = entity.player!! - data.player_index = player.index + // player data: + player_index: player?.index ?? null } - - return data } - export function entitiesToUnitNumbers(entities: LuaEntity[]): JsonArray { - let result: (number) [] = [] + export function entitiesToUnitNumbers(entities: LuaEntity[]): uint[] { + let result: (uint) [] = [] for (let entity of entities) { if (entity.unit_number != null) { result[result.length] = entity.unit_number @@ -78,12 +58,6 @@ export namespace Serdes { export namespace Surface { - interface SurfaceData extends FactorioObjectData { - name: string - index: uint - daytime: number - } - export function surfaceToTable(surface: LuaSurface): SurfaceData { return { object_name: surface.object_name, @@ -97,11 +71,6 @@ export namespace Serdes { export namespace DataClasses { - export interface PositionData extends JsonTable { - x: int - y: int - } - export function positionTableToTable(positionTable: PositionTable): PositionData { return { x: positionTable.x, From babe0161ae6fef6b1c31f4d6207bdf9464033a13 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sun, 28 Nov 2021 18:11:39 +0100 Subject: [PATCH 081/629] auto package.json version update --- buildSrc/build.gradle.kts | 9 ++- .../factoriowebmap/archetype/node.gradle.kts | 10 ---- modules/mod/build.gradle.kts | 58 +++++++++++++++++++ modules/mod/src/main/typescript/package.json | 14 +++-- 4 files changed, 73 insertions(+), 18 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 5e0c6e6..28abbf2 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -4,7 +4,6 @@ plugins { idea `kotlin-dsl` kotlin("jvm") version "1.6.0" - `java-gradle-plugin` } dependencies { @@ -13,9 +12,14 @@ dependencies { implementation(platform("org.jetbrains.kotlin:kotlin-bom:$kotlinVersion")) implementation("org.jetbrains.kotlin:kotlin-serialization") - + implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin") + val kotlinXSerializationVersion = "1.3.1" + implementation(platform("org.jetbrains.kotlinx:kotlinx-serialization-bom:$kotlinXSerializationVersion")) + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json") + + implementation("com.github.node-gradle:gradle-node-plugin:3.1.1") } @@ -39,7 +43,6 @@ tasks.withType().configureEach { ) } - kotlin { jvmToolchain { (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(projectJvmTarget)) diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts index 77788fc..0984035 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts @@ -1,16 +1,7 @@ package dev.adamko.factoriowebmap.archetype -import org.gradle.kotlin.dsl.kotlin -import com.github.gradle.node.npm.task.NpmTask -import com.github.gradle.node.npm.task.NpxTask -import com.github.gradle.node.task.NodeTask import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlugin -import org.jetbrains.kotlin.gradle.targets.js.dukat.DtsResolver -import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask -import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs -import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject plugins { id("com.github.node-gradle.node") @@ -26,4 +17,3 @@ node { project.plugins.withType() project.plugins.withType() - diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index 3590ace..677523f 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -1,8 +1,17 @@ import com.github.gradle.node.npm.task.NpmTask import dev.adamko.factoriowebmap.configurations.asConsumer import dev.adamko.factoriowebmap.configurations.typescriptAttributes +import groovy.json.JsonOutput +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive import org.apache.tools.ant.filters.ReplaceTokens +import org.gradle.kotlin.dsl.support.useToRun import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs +import org.jetbrains.kotlin.util.suffixIfNot plugins { idea @@ -55,6 +64,55 @@ val tstlTask = tasks.register("typescriptToLua") { } +val updatePackageJsonVersion by tasks.registering { + group = project.name + description = """ + Read the package.json file and set the version to be the project's version. + """.trimIndent() + + val projectVersion = "${project.version}" + inputs.properties( + "projectVersion" to projectVersion, + ) + + val packageJsonFile = layout.projectDirectory.file("src/main/typescript/package.json") + outputs.file(packageJsonFile) + + val jsonFormatter = Json { + prettyPrint = true + prettyPrintIndent = " " + } + + onlyIf { + val packageJsonContent = packageJsonFile.asFile.readText() + val packageJson = jsonFormatter.parseToJsonElement(packageJsonContent).jsonObject + packageJson["version"]?.jsonPrimitive?.content != projectVersion + } + + doFirst { + delete(temporaryDir) + mkdir(temporaryDir) + } + + doLast { + val packageJsonContent = packageJsonFile.asFile.readText() + val packageJson = jsonFormatter.parseToJsonElement(packageJsonContent).jsonObject + val packageJsonUpdate = JsonObject( + packageJson + ("version" to JsonPrimitive(projectVersion)) + ) + val packageJsonContentUpdated = + jsonFormatter + .encodeToString(packageJsonUpdate) + .suffixIfNot("\n") + packageJsonFile.asFile.writer().useToRun { + write(packageJsonContentUpdated) + } + } +} + +tasks.assemble { dependsOn(updatePackageJsonVersion) } + + val dataModelTs: Configuration by configurations.creating { asConsumer() typescriptAttributes(objects) diff --git a/modules/mod/src/main/typescript/package.json b/modules/mod/src/main/typescript/package.json index 91aa84e..f69dcfe 100644 --- a/modules/mod/src/main/typescript/package.json +++ b/modules/mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "factorio-web-map-mod", - "version": "0.0.4", + "version": "0.0.5", "private": true, "scripts": { "build": "tstl", @@ -9,7 +9,8 @@ "engines": { "node": ">=10.13.0" }, - "devDependencies": {}, + "devDependencies": { + }, "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", @@ -20,7 +21,10 @@ "//": { "typed-factorio": "0.10.0" }, - "peerDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": [] + "peerDependencies": { + }, + "optionalDependencies": { + }, + "bundledDependencies": [ + ] } From 53862ef1b5b59ca6330bb265fdbb43fee30fbc1e Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 1 Dec 2021 13:35:32 +0100 Subject: [PATCH 082/629] - serialization improvements (the tests work at least) - fixing some version mis-alignments --- build.gradle.kts | 7 +- buildSrc/build.gradle.kts | 9 +- gradle/libs.versions.toml | 34 +++-- .../build.gradle.kts | 6 +- .../factorioevents/model/factorioEvents.kt | 78 +++++++--- .../dev/adamko/factorioevents/model/json.kt | 34 +++++ .../factorioevents/model/FactorioEventTest.kt | 139 ++++++++++++++++++ .../build.gradle.kts | 21 ++- .../processor/config/ApplicationProperties.kt | 1 - .../adamko/factorioevents/processor/main.kt | 8 +- .../model/FactorioServerLogRecord.kt | 61 -------- .../model/FactorioServerLogRecordTest.kt | 68 --------- modules/kt-rcon/build.gradle.kts | 2 + modules/mod/build.gradle.kts | 2 +- .../main/typescript/generated/data-model.ts | 10 +- .../mod/src/main/typescript/model/model.ts | 60 -------- .../mod/src/main/typescript/package-lock.json | 8 +- modules/mod/src/main/typescript/package.json | 4 +- .../mod/src/main/typescript/serdes/serdes.ts | 13 +- 19 files changed, 305 insertions(+), 260 deletions(-) create mode 100644 modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/json.kt create mode 100644 modules/factorio-events-data-model/src/test/kotlin/dev/adamko/factorioevents/model/FactorioEventTest.kt delete mode 100644 modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecord.kt delete mode 100644 modules/factorio-events-processor/src/test/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecordTest.kt delete mode 100644 modules/mod/src/main/typescript/model/model.ts diff --git a/build.gradle.kts b/build.gradle.kts index f3a3cac..1e6369a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,10 +1,11 @@ plugins { idea base + `project-report` } group = "dev.adamko.factoriowebmap" -version = "0.0.4" +version = "0.0.7" tasks.wrapper { gradleVersion = "7.3" @@ -17,3 +18,7 @@ idea { isDownloadJavadoc = true } } + +tasks.withType(HtmlDependencyReportTask::class).configureEach { + projects = project.allprojects +} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 28abbf2..b11311b 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -4,19 +4,20 @@ plugins { idea `kotlin-dsl` kotlin("jvm") version "1.6.0" + `project-report` } dependencies { val kotlinVersion = "1.6.0" - - implementation(platform("org.jetbrains.kotlin:kotlin-bom:$kotlinVersion")) + implementation(enforcedPlatform("org.jetbrains.kotlin:kotlin-bom:$kotlinVersion")) implementation("org.jetbrains.kotlin:kotlin-serialization") implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin") val kotlinXSerializationVersion = "1.3.1" - implementation(platform("org.jetbrains.kotlinx:kotlinx-serialization-bom:$kotlinXSerializationVersion")) + implementation(enforcedPlatform("org.jetbrains.kotlinx:kotlinx-serialization-bom:$kotlinXSerializationVersion")) + implementation("org.jetbrains.kotlinx:kotlinx-serialization-core") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json") @@ -59,3 +60,5 @@ idea { isDownloadJavadoc = true } } + +tasks.assemble { dependsOn(tasks.htmlDependencyReport) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2751a37..4a19812 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,11 +9,12 @@ jvm = "11" kotlin = "1.6.0" ## libs ## -http4k = "4.16.1.0" +http4k = "4.17.2.0" slf4j = "1.7.30" log4j2 = "2.14.1" qosLogback = "1.2.5" kafka = "3.0.0" +kotlinx-serialization = "1.3.1" ## test ## junit = "5.8.1" @@ -45,22 +46,25 @@ sendgrid = { group = "com.sendgrid", name = "sendgrid-java", version ## kotlin ## kotlin-bom = { group = "org.jetbrains.kotlin", name = "kotlin-bom", version.ref = "kotlin" } -kotlinx-serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version = "1.3.0" } -kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.6.0-RC" } -kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.7.3" } +kotlinx-serialization-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-bom", version.ref = "kotlinx-serialization" } +kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core" } +kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json" } +kotlinx-serialization-yaml = { group = "com.charleskorn.kaml", name = "kaml", version = "0.37.0" } +kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.6.0-RC" } +kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.7.3" } ## http4k ## -http4k-bom = { group = "org.http4k", name = "http4k-bom", version.ref = "http4k" } -http4k-core = { group = "org.http4k", name = "http4k-core" } -http4k-contract = { group = "org.http4k", name = "http4k-contract" } -http4k-client = { group = "org.http4k", name = "http4k-client-okhttp" } -http4k-server = { group = "org.http4k", name = "http4k-server-undertow" } -http4k-cloudnative = { group = "org.http4k", name = "http4k-cloudnative" } -#http4k-kotlinx = { group = "org.http4k", name = "http4k-format-kotlinx-serialization" } -http4k-format-json = { group = "org.http4k", name = "http4k-format-jackson" } -http4k-format-xml = { group = "org.http4k", name = "http4k-format-jackson-xml" } -http4k-format-yaml = { group = "org.http4k", name = "http4k-format-jackson-yaml" } -http4k-graphql = { group = "org.http4k", name = "http4k-graphql" } +http4k-bom = { group = "org.http4k", name = "http4k-bom", version.ref = "http4k" } +http4k-core = { group = "org.http4k", name = "http4k-core" } +http4k-contract = { group = "org.http4k", name = "http4k-contract" } +http4k-client = { group = "org.http4k", name = "http4k-client-okhttp" } +http4k-server = { group = "org.http4k", name = "http4k-server-undertow" } +http4k-cloudnative = { group = "org.http4k", name = "http4k-cloudnative" } +http4k-format-json = { group = "org.http4k", name = "http4k-format-jackson" } +http4k-format-xml = { group = "org.http4k", name = "http4k-format-jackson-xml" } +http4k-format-yaml = { group = "org.http4k", name = "http4k-format-jackson-yaml" } +http4k-format-kotlinx = { group = "org.http4k", name = "http4k-format-kotlinx-serialization" } +http4k-graphql = { group = "org.http4k", name = "http4k-graphql" } ### jackson ## #jackson-bom = { group = " com.fasterxml.jackson.module", name = ":jackson-module-kotlin", version = "2.13.+" } diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/factorio-events-data-model/build.gradle.kts index f422934..a8ed8a2 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/factorio-events-data-model/build.gradle.kts @@ -10,9 +10,9 @@ val projectId: String by project.extra val buildDir: Directory = layout.buildDirectory.dir(projectId).get() dependencies { - val kotlinXSerializationVersion = "1.3.0" - implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$kotlinXSerializationVersion") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinXSerializationVersion") + implementation(platform(libs.kotlinx.serialization.bom)) + implementation(libs.kotlinx.serialization.core) + implementation(libs.kotlinx.serialization.json) implementation("com.github.ntrrgc:ts-generator:1.1.2") implementation("org.jetbrains.kotlin:kotlin-reflect") diff --git a/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt b/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt index 2648afc..0d30420 100644 --- a/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt +++ b/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt @@ -1,61 +1,101 @@ package dev.adamko.factorioevents.model + import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonClassDiscriminator +//@Serializable(with = FactorioEventSerializer::class) @Serializable -data class FactorioEvent( +data class FactorioEvent( /** the initial Factorio event ({defines.events}) trigger */ + @SerialName("event_type") val eventType: String, /** Schema versioning */ + @SerialName("mod_version") val modVersion: String, /** game time */ + @SerialName("tick") val tick: UInt, - val data: T, + @SerialName("data") + val data: T ) -@JsonClassDiscriminator("object_name") -sealed interface FactorioObjectData { - val objectName: String + +/** The [JsonClassDiscriminator] for [FactorioEvent] */ +const val FactorioObjectDataDiscriminatorKey: String = "object_name" + + +@Serializable +@JsonClassDiscriminator(FactorioObjectDataDiscriminatorKey) +sealed class FactorioObjectData { + @SerialName(FactorioObjectDataDiscriminatorKey) + abstract val objectName: String } +@Serializable @SerialName("LuaPlayer") data class PlayerData( + @SerialName(FactorioObjectDataDiscriminatorKey) override val objectName: String, - val associatedCharactersUnitNumbers: List, - val characterUnitNumber: UInt?, - val name: String, - val position: PositionData, -) : FactorioObjectData + @Serializable(with = ListAsObjectSerializer::class) + @SerialName("associated_characters_unit_numbers") + val associatedCharactersUnitNumbers: List, + @SerialName("character_unit_number") + val characterUnitNumber: UInt?, + @SerialName("name") + val name: String, + @SerialName("position") + val position: PositionData, +) : FactorioObjectData() + +@Serializable @SerialName("LuaEntity") data class EntityData( + @SerialName(FactorioObjectDataDiscriminatorKey) override val objectName: String, + @SerialName("active") val active: Boolean, - val health: Float?, - val healthRatio: Float, + @SerialName("health") + val health: Double?, + @SerialName("health_ratio") + val healthRatio: Double, + @SerialName("name") val name: String, + @SerialName("position") val position: PositionData, + @SerialName("surface_index") val surfaceIndex: Int, + @SerialName("type") val type: String, + @SerialName("unit_number") val unitNumber: UInt?, - val playerIndex: UInt?, -) : FactorioObjectData + @SerialName("player_index") + val playerIndex: UInt? = null, +) : FactorioObjectData() +@Serializable @SerialName("LuaSurface") data class SurfaceData( + @SerialName(FactorioObjectDataDiscriminatorKey) override val objectName: String, - val daytime: Float, + + @SerialName("daytime") + val daytime: Double, + @SerialName("index") val index: UInt, + @SerialName("name") val name: String, -) : FactorioObjectData +) : FactorioObjectData() @Serializable data class PositionData( - val x: Int, - val y: Int, -) \ No newline at end of file + @SerialName("x") + val x: Double, + @SerialName("y") + val y: Double, +) diff --git a/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/json.kt b/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/json.kt new file mode 100644 index 0000000..8e98573 --- /dev/null +++ b/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/json.kt @@ -0,0 +1,34 @@ +package dev.adamko.factorioevents.model + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonTransformingSerializer +import kotlinx.serialization.json.jsonArray +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.modules.SerializersModule + + +/** Factorio outputs lists as Json objects - this serializer converts an object back to a list. */ +class ListAsObjectSerializer(dataSerializer: KSerializer) : + JsonTransformingSerializer>(ListSerializer(dataSerializer)) { + + override fun transformDeserialize(element: JsonElement): JsonElement = + JsonArray( + element.jsonObject.values.toList() + ) + + override fun transformSerialize(element: JsonElement): JsonElement = + JsonObject( + element.jsonArray.mapIndexed { index, jsonElement -> "$index" to jsonElement }.toMap() + ) +} + +val jsonMapper = Json { + prettyPrint = true + prettyPrintIndent = " " + serializersModule = SerializersModule { } +} diff --git a/modules/factorio-events-data-model/src/test/kotlin/dev/adamko/factorioevents/model/FactorioEventTest.kt b/modules/factorio-events-data-model/src/test/kotlin/dev/adamko/factorioevents/model/FactorioEventTest.kt new file mode 100644 index 0000000..0f7386d --- /dev/null +++ b/modules/factorio-events-data-model/src/test/kotlin/dev/adamko/factorioevents/model/FactorioEventTest.kt @@ -0,0 +1,139 @@ +package dev.adamko.factorioevents.model + +import io.kotest.core.spec.style.BehaviorSpec +import io.kotest.matchers.equality.shouldBeEqualToComparingFields +import kotlinx.serialization.decodeFromString +import org.intellij.lang.annotations.Language + +class FactorioEventTest : BehaviorSpec({ + + Given("json on_player_joined_game") { + + @Language("JSON") + val json = """ + { + "data": { + "object_name": "LuaPlayer", + "name": "fredthedeadhead", + "character_unit_number": 1, + "associated_characters_unit_numbers": {}, + "position": { + "x": -3.5703125, + "y": 29.75 + } + }, + "event_type": "on_player_joined_game", + "mod_version": "0.0.4", + "tick": 1278458 + } + """.trimIndent() + + Then("parse") { + val actual: FactorioEvent = jsonMapper.decodeFromString(json) + + val expected = FactorioEvent( + data = PlayerData( + objectName = "LuaPlayer", + name = "fredthedeadhead", + characterUnitNumber = 1u, + associatedCharactersUnitNumbers = emptyList(), + position = PositionData( + x = -3.5703125, + y = 29.75 + ) + ), + eventType = "on_player_joined_game", + modVersion = "0.0.4", + tick = 1278458u + ) + + actual shouldBeEqualToComparingFields expected + } + } + + Given("json surface") { + @Language("JSON") + val json = """ + { + "data": { + "object_name": "LuaSurface", + "name": "nauvis", + "index": 1, + "daytime": 0.8390800000511436707029133685864508152008056640625 + }, + "event_type": "on_tick", + "mod_version": "0.0.4", + "tick": 1278480 + } + """.trimIndent() + Then("parse") { + val actual: FactorioEvent = jsonMapper.decodeFromString(json) + + val expected = FactorioEvent( + data = SurfaceData( + objectName = "LuaSurface", + name = "nauvis", + index = 1u, + daytime = 0.8390800000511436707029133685864508152008056640625 + ), + eventType = "on_tick", + modVersion = "0.0.4", + tick = 1278480u + ) + + actual shouldBeEqualToComparingFields expected + } + } + + Given("json entity") { + @Language("JSON") + val json = """ + { + "data": { + "object_name": "LuaEntity", + "name": "character", + "type": "character", + "active": true, + "health": 250, + "health_ratio": 1, + "surface_index": 1, + "unit_number": 1, + "position": { + "x": -0.25, + "y": 30.09375 + } + }, + "event_type": "on_player_changed_position", + "mod_version": "0.0.6", + "tick": 1384507 + } + """.trimIndent() + Then("parse") { + val actual: FactorioEvent = jsonMapper.decodeFromString(json) + + val expected = FactorioEvent( + data = EntityData( + objectName = "LuaEntity", + name = "character", + type = "character", + active = true, + health = 250.0, + healthRatio = 1.0, + surfaceIndex = 1, + unitNumber = 1u, + playerIndex = null, + position = PositionData( + x = -0.25, + y = 30.09375, + ) + ), + eventType = "on_player_changed_position", + modVersion = "0.0.6", + tick = 1384507u + ) + + actual shouldBeEqualToComparingFields expected + } + } + +}) diff --git a/modules/factorio-events-processor/build.gradle.kts b/modules/factorio-events-processor/build.gradle.kts index 9229e4d..216a19e 100644 --- a/modules/factorio-events-processor/build.gradle.kts +++ b/modules/factorio-events-processor/build.gradle.kts @@ -4,8 +4,7 @@ plugins { application } -description = - """ +description = """ Receive raw Factorio Events from Kafka and process them into targeted topics or data formats. Factorio events -> Mod -> Kafka -> ***Factorio Events Processor*** -> processed events @@ -19,13 +18,23 @@ dependencies { implementation("org.apache.kafka:kafka-streams:3.0.0") - implementation(libs.kotlinx.serialization) + implementation(projects.modules.factorioEventsDataModel) + +// implementation("com.ionspin.kotlin:bignum:0.3.3") + + implementation(enforcedPlatform(libs.kotlinx.serialization.bom)) + implementation(libs.kotlinx.serialization.core) + implementation(libs.kotlinx.serialization.json) implementation(platform(libs.http4k.bom)) - implementation(libs.http4k.core) +// implementation(libs.http4k.core) implementation(libs.http4k.cloudnative) - implementation(libs.http4k.format.json) - implementation(libs.http4k.format.yaml) +// implementation(libs.http4k.format.json) + implementation(libs.http4k.format.yaml) { + because("parsing yaml properties files") + } + + implementation(libs.http4k.format.kotlinx) implementation(libs.bundles.logging) diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt index 86232c8..51c5ed6 100644 --- a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt +++ b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt @@ -9,7 +9,6 @@ import org.http4k.cloudnative.env.Environment import org.http4k.cloudnative.env.EnvironmentKey import org.http4k.core.Credentials import org.http4k.core.Uri -import org.http4k.format.Jackson import org.http4k.format.Json import org.http4k.lens.boolean import org.http4k.lens.map diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt index 4932637..23bbdde 100644 --- a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt +++ b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt @@ -1,7 +1,8 @@ package dev.adamko.factorioevents.processor +import dev.adamko.factorioevents.model.FactorioEvent +import dev.adamko.factorioevents.model.jsonMapper import dev.adamko.factorioevents.processor.config.ApplicationProperties -import dev.adamko.factorioevents.processor.model.FactorioServerLogRecord import java.time.Duration import org.apache.kafka.common.serialization.Serdes import org.apache.kafka.streams.KafkaStreams @@ -9,7 +10,7 @@ import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.TopologyDescription import org.apache.kafka.streams.kstream.Consumed import org.apache.kafka.streams.processor.TopicNameExtractor -import org.http4k.format.Jackson +import org.http4k.format.KotlinxSerialization fun main() { @@ -23,7 +24,8 @@ fun main() { ) .mapValues { readOnlyKey, value -> println("Mapping $readOnlyKey:$value") - Jackson.asA>(value) +// jsonMapper.decodeFromString>(value) + KotlinxSerialization.asA>(value) } .to(TopicNameExtractor { key, value, recordContext -> value.data.objectName diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecord.kt b/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecord.kt deleted file mode 100644 index 7ec2a35..0000000 --- a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecord.kt +++ /dev/null @@ -1,61 +0,0 @@ -package dev.adamko.factorioevents.processor.model - -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.annotation.JsonTypeInfo -import com.fasterxml.jackson.annotation.JsonTypeName -import com.fasterxml.jackson.annotation.JsonValue -import java.math.BigDecimal -import java.math.BigInteger -import kotlin.reflect.KClass - - -data class FactorioServerLogRecord( - @JsonProperty("mod_version") - val modVersion: String, - @JsonProperty("tick") - val tick: BigInteger, - @JsonProperty("event_type") - val eventType: String, - @JsonProperty("data") - val data: DataType, -) - -@JsonTypeInfo( - use = JsonTypeInfo.Id.NAME, - include = JsonTypeInfo.As.EXISTING_PROPERTY, - property = "object_name", - defaultImpl = UnknownFactorioObject::class, - visible = true, -) -sealed class FactorioObjectData( - @JsonProperty("object_name") - val objectName: String -) - -object UnknownFactorioObject : FactorioObjectData("unknown") - -@JsonTypeName("LuaSurface") -class LuaSurfaceData( - @JsonProperty("name") - val name: String, - @JsonProperty("index") - val index: Int, - @JsonProperty("daytime") - val daytime: BigDecimal, -) : FactorioObjectData("LuaSurface") - - -/* - -{ - "tick": 1144860, - "object_name": "LuaSurface", - "event_type": "on_tick", - "data": { - "name": "nauvis", - "index": 1, - "daytime": 0.4942800000457983 - } -} - - */ \ No newline at end of file diff --git a/modules/factorio-events-processor/src/test/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecordTest.kt b/modules/factorio-events-processor/src/test/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecordTest.kt deleted file mode 100644 index d672635..0000000 --- a/modules/factorio-events-processor/src/test/kotlin/dev/adamko/factorioevents/processor/model/FactorioServerLogRecordTest.kt +++ /dev/null @@ -1,68 +0,0 @@ -package dev.adamko.factorioevents.processor.model - -import io.kotest.assertions.json.shouldEqualJson -import io.kotest.core.spec.style.FunSpec -import io.kotest.matchers.shouldBe -import io.kotest.matchers.shouldNotBe -import org.http4k.format.Jackson -import org.intellij.lang.annotations.Language - -class FactorioServerLogRecordTest : FunSpec({ - - test("player obj") { - @Language("JSON") - val example = """ - { - "mod_version":"0.0.3", - "tick":1256529, - "event_type":"on_player_joined_game", - "data":{ - "object_name":"LuaPlayer", - "name":"fredthedeadhead", - "character_unit_number":1, - "associated_characters_unit_numbers":{ - - }, - "position":{ - "x":3.48828125, - "y":23.43359375 - } - } - } - """.trimIndent() - val record: FactorioServerLogRecord<*> = Jackson.asA(example) - - record shouldBe null - } - - test("surface obj") { - @Language("JSON") - val example = """ - { - "mod_version":"0.0.3", - "tick":1256529, - "event_type":"on_player_joined_game", - "data":{ - "object_name":"LuaEntity", - "name":"character", - "type":"character", - "active":true, - "health":250, - "surface_index":1, - "unit_number":1, - "position":{ - "x":3.48828125, - "y":23.43359375 - } - } - } - """.trimIndent() - val record: FactorioServerLogRecord = Jackson.asA(example) - - record shouldNotBe null - - val str = Jackson.asFormatString(record) - str.shouldEqualJson(example) - } - -}) diff --git a/modules/kt-rcon/build.gradle.kts b/modules/kt-rcon/build.gradle.kts index cab5d06..6d1d75e 100644 --- a/modules/kt-rcon/build.gradle.kts +++ b/modules/kt-rcon/build.gradle.kts @@ -8,6 +8,8 @@ plugins { dependencies { + implementation(enforcedPlatform(libs.kotlinx.serialization.bom)) + implementation(libs.kotlinx.coroutines) implementation("io.ktor:ktor-network:1.6.4") diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index 677523f..e3004ed 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -309,7 +309,7 @@ tasks.register("downloadFactorioApiDocs") { ) val json = downloadedFile.readText() - val prettyJson = groovy.json.JsonOutput.prettyPrint(json) + val prettyJson = JsonOutput.prettyPrint(json) apiFile.asFile.writeText(prettyJson) diff --git a/modules/mod/src/main/typescript/generated/data-model.ts b/modules/mod/src/main/typescript/generated/data-model.ts index f6b435d..8950029 100644 --- a/modules/mod/src/main/typescript/generated/data-model.ts +++ b/modules/mod/src/main/typescript/generated/data-model.ts @@ -13,8 +13,8 @@ interface FactorioEvent { } interface PositionData { - x: int; - y: int; + x: double; + y: double; } interface PlayerData extends FactorioObjectData { @@ -27,8 +27,8 @@ interface PlayerData extends FactorioObjectData { interface EntityData extends FactorioObjectData { active: boolean; - health: float | null; - health_ratio: float; + health: double | null; + health_ratio: double; name: string; object_name: string; player_index: uint | null; @@ -39,7 +39,7 @@ interface EntityData extends FactorioObjectData { } interface SurfaceData extends FactorioObjectData { - daytime: float; + daytime: double; index: uint; name: string; object_name: string; diff --git a/modules/mod/src/main/typescript/model/model.ts b/modules/mod/src/main/typescript/model/model.ts deleted file mode 100644 index 29909f4..0000000 --- a/modules/mod/src/main/typescript/model/model.ts +++ /dev/null @@ -1,60 +0,0 @@ -// import {Serdes} from "../serdes/serdes"; -// import FactorioObjectData = Serdes.FactorioObjectData; -// -// export type JsonPrimitiveType = number | string | boolean | undefined | null | void -// -// export type JsonArray = T[] -// -// export type JsonTableValueType = -// JsonPrimitiveType -// | JsonTable -// | JsonArray -// | undefined -// | null -// -// export interface JsonTable { -// [key: string]: JsonTableValueType -// } - - -// export interface FactorioEvent extends JsonTable { -// /** Schema versioning */ -// mod_version: string, -// /** game time */ -// tick: uint, -// /** the initial Factorio event ({defines.events}) trigger */ -// event_type: string, -// data: FactorioObjectData, -// } -// -// export const FactorioEvent = -// (( -// tick: uint, -// eventType: string, -// data: DataType -// ) => { -// return { -// mod_version: MOD_VERSION, -// tick: tick, -// event_type: eventType, -// data: data, -// } as FactorioEvent -// } -// ) - - -// export type JsonArray = TValue[] -// export class JsonArray extends Array { -// } - -// export type JsonArray = Array -// declare type JsonArrayConstructor = (new () => JsonArray) -// declare const JsonArray: JsonArrayConstructor - -// export class JsonTable extends LuaTable { -// } -// export type JsonTable = LuaTable -// const JsonTable = () => new LuaTable() -// export type JsonTableConstructor = (new () => JsonTable) -// declare const JsonTable: JsonTableConstructor - diff --git a/modules/mod/src/main/typescript/package-lock.json b/modules/mod/src/main/typescript/package-lock.json index 0a1276e..f4d614b 100644 --- a/modules/mod/src/main/typescript/package-lock.json +++ b/modules/mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "factorio-web-map-mod", - "version": "0.0.4", + "version": "0.0.6", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -83,9 +83,9 @@ } }, "typescript": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", - "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==" + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", + "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==" }, "typescript-to-lua": { "version": "1.1.1", diff --git a/modules/mod/src/main/typescript/package.json b/modules/mod/src/main/typescript/package.json index f69dcfe..95396be 100644 --- a/modules/mod/src/main/typescript/package.json +++ b/modules/mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "factorio-web-map-mod", - "version": "0.0.5", + "version": "0.0.7", "private": true, "scripts": { "build": "tstl", @@ -16,7 +16,7 @@ "@types/node": "^12.0.8", "typescript-to-lua": "1.1.1", "typed-factorio": "0.12.0", - "typescript": "4.5.2" + "typescript": "4.4.4" }, "//": { "typed-factorio": "0.10.0" diff --git a/modules/mod/src/main/typescript/serdes/serdes.ts b/modules/mod/src/main/typescript/serdes/serdes.ts index b33e595..2a4a8e1 100644 --- a/modules/mod/src/main/typescript/serdes/serdes.ts +++ b/modules/mod/src/main/typescript/serdes/serdes.ts @@ -1,18 +1,12 @@ -// import {JsonTable, JsonArray} from "../model/model"; - - export namespace Serdes { - // export interface FactorioObjectData extends JsonTable { - // object_name: string - // } - export namespace Player { export function playerToTable(player: LuaPlayer): PlayerData { let charIds = Entity.entitiesToUnitNumbers(player.get_associated_characters()) return { object_name: player.object_name, + name: player.name, character_unit_number: player.character?.unit_number ?? null, associated_characters_unit_numbers: charIds, @@ -30,6 +24,8 @@ export namespace Serdes { return { object_name: entity.object_name, + + // entity data name: entity.name, type: entity.type, active: entity.active, @@ -39,7 +35,7 @@ export namespace Serdes { unit_number: entity.unit_number ?? null, position: DataClasses.positionTableToTable(entity.position), - // player data: + // player data player_index: player?.index ?? null } } @@ -61,6 +57,7 @@ export namespace Serdes { export function surfaceToTable(surface: LuaSurface): SurfaceData { return { object_name: surface.object_name, + name: surface.name, index: surface.index, daytime: surface.daytime, From 633e898f3ce0d01dd889ef934468707b59b6d959 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 1 Dec 2021 16:57:46 +0100 Subject: [PATCH 083/629] project re-organisation, and rename --- build.gradle.kts | 7 +- .../factoriowebmap/archetype/base.gradle.kts | 3 - .../archetype/process-runner.gradle.kts | 23 ++ .../configurations/factorioMod.kt | 20 ++ .../kotlin/dev/adamko/gradleExtensions.kt | 21 ++ modules/events-mod/build.gradle.kts | 235 +++++++++++++ .../src/main/resources/mod-data/changelog.txt | 0 .../src/main/resources/mod-data/info.json | 0 .../src/main/resources/mod-data/thumbnail.png | Bin .../src/main/typescript/control.ts | 0 .../src/main/typescript/events.ts | 0 .../src/main/typescript/model}/data-model.ts | 2 +- .../src/main/typescript/package-lock.json | 2 +- .../src/main/typescript/package.json | 12 +- .../src/main/typescript/serdes/serdes.ts | 0 .../src/main/typescript/tsconfig.json | 0 .../build.gradle.kts | 3 +- .../processor/FactorioEventLogConsumer.kt | 0 .../processor/FactorioEventsTopology.kt | 0 .../processor/StreamsExceptionHandler.kt | 0 .../processor/config/ApplicationProperties.kt | 0 .../factorioevents/processor/config/Lenses.kt | 0 .../processor/config/PortVal.kt | 0 .../processor/config/environmentExt.kt | 0 .../adamko/factorioevents/processor/main.kt | 0 .../src/main/resources/logback.xml | 0 .../build.gradle.kts | 3 - .../factorioevents/model/builtinTypes.kt | 0 .../factorioevents/model/factorioEvents.kt | 0 .../dev/adamko/factorioevents/model/json.kt | 0 .../dev/adamko/factorioevents/model/kt2ts.kt | 0 .../factorioevents/model/FactorioEventTest.kt | 0 .../build.gradle.kts | 12 - .../infra-factorio-client/build.gradle.kts | 81 +++++ .../infra-factorio-server/build.gradle.kts | 77 +++++ .../{mod => infra-factorio-server}/infra/.env | 0 .../infra/.gitignore | 0 .../infra/docker-compose.yml | 39 +++ .../infra/factorioEvents.Dockerfile | 0 .../infra/kafka-pipe.sh | 0 .../infra/kcat.conf | 0 .../docker-compose.yml | 32 +- .../kafka-server.properties | 0 .../kafka.Dockerfile | 0 modules/infra-kafka-pipe/build.gradle.kts | 6 + .../src}/.env | 0 .../src}/docker-compose.yml | 0 .../src}/kafka-pipe.Dockerfile | 0 .../src}/kafka-pipe.sh | 0 .../src}/readme.md | 0 modules/mod/build.gradle.kts | 318 ------------------ settings.gradle.kts | 16 +- 52 files changed, 525 insertions(+), 387 deletions(-) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/process-runner.gradle.kts create mode 100644 buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/factorioMod.kt create mode 100644 buildSrc/src/main/kotlin/dev/adamko/gradleExtensions.kt create mode 100644 modules/events-mod/build.gradle.kts rename modules/{mod => events-mod}/src/main/resources/mod-data/changelog.txt (100%) rename modules/{mod => events-mod}/src/main/resources/mod-data/info.json (100%) rename modules/{mod => events-mod}/src/main/resources/mod-data/thumbnail.png (100%) rename modules/{mod => events-mod}/src/main/typescript/control.ts (100%) rename modules/{mod => events-mod}/src/main/typescript/events.ts (100%) rename modules/{mod/src/main/typescript/generated => events-mod/src/main/typescript/model}/data-model.ts (99%) rename modules/{mod => events-mod}/src/main/typescript/package-lock.json (99%) rename modules/{mod => events-mod}/src/main/typescript/package.json (77%) rename modules/{mod => events-mod}/src/main/typescript/serdes/serdes.ts (100%) rename modules/{mod => events-mod}/src/main/typescript/tsconfig.json (100%) rename modules/{factorio-events-processor => events-processor}/build.gradle.kts (89%) rename modules/{factorio-events-processor => events-processor}/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventLogConsumer.kt (100%) rename modules/{factorio-events-processor => events-processor}/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventsTopology.kt (100%) rename modules/{factorio-events-processor => events-processor}/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt (100%) rename modules/{factorio-events-processor => events-processor}/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt (100%) rename modules/{factorio-events-processor => events-processor}/src/main/kotlin/dev/adamko/factorioevents/processor/config/Lenses.kt (100%) rename modules/{factorio-events-processor => events-processor}/src/main/kotlin/dev/adamko/factorioevents/processor/config/PortVal.kt (100%) rename modules/{factorio-events-processor => events-processor}/src/main/kotlin/dev/adamko/factorioevents/processor/config/environmentExt.kt (100%) rename modules/{factorio-events-processor => events-processor}/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt (100%) rename modules/{factorio-events-processor => events-processor}/src/main/resources/logback.xml (100%) rename modules/{factorio-events-data-model => events-schema}/build.gradle.kts (91%) rename modules/{factorio-events-data-model => events-schema}/src/main/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt (100%) rename modules/{factorio-events-data-model => events-schema}/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt (100%) rename modules/{factorio-events-data-model => events-schema}/src/main/kotlin/dev/adamko/factorioevents/model/json.kt (100%) rename modules/{factorio-events-data-model => events-schema}/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt (100%) rename modules/{factorio-events-data-model => events-schema}/src/test/kotlin/dev/adamko/factorioevents/model/FactorioEventTest.kt (100%) delete mode 100644 modules/factorio-events-kafka-pipe/build.gradle.kts create mode 100644 modules/infra-factorio-client/build.gradle.kts create mode 100644 modules/infra-factorio-server/build.gradle.kts rename modules/{mod => infra-factorio-server}/infra/.env (100%) rename modules/{mod => infra-factorio-server}/infra/.gitignore (100%) create mode 100644 modules/infra-factorio-server/infra/docker-compose.yml rename modules/{mod => infra-factorio-server}/infra/factorioEvents.Dockerfile (100%) rename modules/{mod => infra-factorio-server}/infra/kafka-pipe.sh (100%) rename modules/{mod => infra-factorio-server}/infra/kcat.conf (100%) rename modules/{mod/infra => infra-kafka-cluster}/docker-compose.yml (60%) rename modules/{mod/infra => infra-kafka-cluster}/kafka-server.properties (100%) rename modules/{mod/infra => infra-kafka-cluster}/kafka.Dockerfile (100%) create mode 100644 modules/infra-kafka-pipe/build.gradle.kts rename modules/{factorio-events-kafka-pipe => infra-kafka-pipe/src}/.env (100%) rename modules/{factorio-events-kafka-pipe => infra-kafka-pipe/src}/docker-compose.yml (100%) rename modules/{factorio-events-kafka-pipe => infra-kafka-pipe/src}/kafka-pipe.Dockerfile (100%) rename modules/{factorio-events-kafka-pipe => infra-kafka-pipe/src}/kafka-pipe.sh (100%) rename modules/{factorio-events-kafka-pipe => infra-kafka-pipe/src}/readme.md (100%) delete mode 100644 modules/mod/build.gradle.kts diff --git a/build.gradle.kts b/build.gradle.kts index 1e6369a..bfca669 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,6 +2,7 @@ plugins { idea base `project-report` + `build-dashboard` } group = "dev.adamko.factoriowebmap" @@ -19,6 +20,6 @@ idea { } } -tasks.withType(HtmlDependencyReportTask::class).configureEach { - projects = project.allprojects -} +//tasks.withType(HtmlDependencyReportTask::class).configureEach { +// projects = project.allprojects +//} diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts index 46b5d8c..999ef24 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts @@ -8,9 +8,6 @@ plugins { group = "${rootProject.group}.${project.name}" version = rootProject.version -val projectId by extra("fwm-${project.name}") -//val modBuildDir by extra(layout.buildDirectory.dir(projectId).get()) - val licenseFile: RegularFile by extra(rootProject.layout.projectDirectory.file("LICENSE")) val tokens: Map by extra( diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/process-runner.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/process-runner.gradle.kts new file mode 100644 index 0000000..c793c71 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/process-runner.gradle.kts @@ -0,0 +1,23 @@ +package dev.adamko.factoriowebmap.archetype + +plugins { + id("dev.adamko.factoriowebmap.archetype.base") +} + +val processRunnerTaskGroup: String by extra("processes") + +val processRun by tasks.registering { + group = processRunnerTaskGroup +} + +val processKill by tasks.registering { + group = processRunnerTaskGroup +} + +val processRestart by tasks.registering { + group = processRunnerTaskGroup + + processKill.get().state + dependsOn(processKill) + finalizedBy(processRun) +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/factorioMod.kt b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/factorioMod.kt new file mode 100644 index 0000000..e158817 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/factorioMod.kt @@ -0,0 +1,20 @@ +package dev.adamko.factoriowebmap.configurations + +import org.gradle.api.artifacts.Configuration +import org.gradle.api.attributes.AttributeContainer +import org.gradle.api.attributes.Bundling +import org.gradle.api.attributes.Category +import org.gradle.api.attributes.LibraryElements +import org.gradle.api.attributes.Usage +import org.gradle.api.model.ObjectFactory +import org.gradle.kotlin.dsl.named + +fun Configuration.factorioModAttributes(objects: ObjectFactory) = + attributes { factorioMod(objects) } + +fun AttributeContainer.factorioMod(objects: ObjectFactory) { + attribute(Usage.USAGE_ATTRIBUTE, objects.named("factorio")) + attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) + attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.CLASSES_AND_RESOURCES)) + attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EMBEDDED)) +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradleExtensions.kt b/buildSrc/src/main/kotlin/dev/adamko/gradleExtensions.kt new file mode 100644 index 0000000..0b00148 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/gradleExtensions.kt @@ -0,0 +1,21 @@ +package dev.adamko + +import java.io.ByteArrayOutputStream +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.specs.Spec +import org.gradle.kotlin.dsl.invoke + +operator fun Spec.not(): Spec = Spec { !this(it) } + +fun Project.isProcessRunning(process: String, ignoreCase: Boolean = true): Spec = + Spec { + ByteArrayOutputStream().use { outputStream -> + project.exec { + commandLine("tasklist") + standardOutput = outputStream + } + outputStream.toString() + .contains(process, ignoreCase) + } + } \ No newline at end of file diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts new file mode 100644 index 0000000..26413ae --- /dev/null +++ b/modules/events-mod/build.gradle.kts @@ -0,0 +1,235 @@ +import com.github.gradle.node.npm.task.NpmTask +import dev.adamko.factoriowebmap.configurations.asConsumer +import dev.adamko.factoriowebmap.configurations.asProvider +import dev.adamko.factoriowebmap.configurations.factorioModAttributes +import dev.adamko.factoriowebmap.configurations.typescriptAttributes +import groovy.json.JsonOutput +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive +import org.apache.tools.ant.filters.ReplaceTokens +import org.gradle.kotlin.dsl.support.useToRun +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs +import org.jetbrains.kotlin.util.suffixIfNot + +plugins { + idea + id("dev.adamko.factoriowebmap.archetype.node") +} + +val tokens: Map by project.extra +val licenseFile: RegularFile by project.extra + +val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") + +node { + nodeProjectDir.set(tsSrcDir) +} + + +val dataModelTs by configurations.registering { + asConsumer() + typescriptAttributes(objects) + defaultDependencies { + project.dependencies.create(projects.modules.eventsSchema) + } +} + + +val typescriptToLua by tasks.registering(NpmTask::class) { + description = "Convert Typescript To Lua" + group = project.name + + dependsOn(tasks.npmInstall) + + execOverrides { standardOutput = System.out } + + npmCommand.set(listOf("run", "build")) + + inputs.dir(project.node.nodeProjectDir) + .skipWhenEmpty() + .withPropertyName("sourceFiles") + .withPathSensitivity(PathSensitivity.RELATIVE) + + val intermediateOutputDir = temporaryDir + args.set(parseSpaceSeparatedArgs("-- --outDir $intermediateOutputDir")) + val outputDir = layout.buildDirectory.dir("typescriptToLua") + outputs.dir(outputDir) + .withPropertyName("outputDir") + + ignoreExitValue.set(false) + + doFirst("clean") { + delete(intermediateOutputDir) + } + + doLast("syncTstlOutput") { + sync { + from(intermediateOutputDir) + into(outputDir) + } + } + +} + +val updatePackageJsonVersion by tasks.registering { + group = project.name + description = """ + Read the package.json file and set the version to be the project's version. + """.trimIndent() + + val projectVersion = "${project.version}" + inputs.properties( + "projectVersion" to projectVersion, + ) + + val packageJsonFile = layout.projectDirectory.file("src/main/typescript/package.json") + outputs.file(packageJsonFile) + + val jsonFormatter = Json { + prettyPrint = true + prettyPrintIndent = " " + } + + onlyIf { + // check to see if the version is already up-to-date + val packageJsonContent = packageJsonFile.asFile.readText() + val packageJson = jsonFormatter.parseToJsonElement(packageJsonContent).jsonObject + packageJson["version"]?.jsonPrimitive?.content != projectVersion + } + + doLast { + val packageJsonContent = packageJsonFile.asFile.readText() + val packageJson = jsonFormatter.parseToJsonElement(packageJsonContent).jsonObject + val packageJsonUpdate = JsonObject( + packageJson + ("version" to JsonPrimitive(projectVersion)) + ) + val packageJsonContentUpdated = + jsonFormatter + .encodeToString(packageJsonUpdate) + .suffixIfNot("\n") + packageJsonFile.asFile.writer().useToRun { + write(packageJsonContentUpdated) + } + } +} + +val updateDataModel by tasks.registering(Sync::class) { + group = project.name + description = "Fetch the latest shared data-model" + + dependsOn(dataModelTs) + + from( + dataModelTs.map { c -> + c.incoming + .artifactView { lenient(true) } + .artifacts + .artifactFiles + .filter { file -> file.exists() } + } + ) + + into(layout.projectDirectory.dir("src/main/typescript/model")) +} + + +val packageMod by tasks.registering(Zip::class) { + description = "Package mod files into ZIP" + group = project.name + + dependsOn(typescriptToLua) + + inputs.properties(tokens) + + from(layout.projectDirectory.dir("src/main/resources/mod-data")) { + include("**/**") + filter("tokens" to tokens) + } + dependsOn(typescriptToLua) + from(licenseFile) + + into(rootProject.name) + + // Factorio required format is: + // - filename: `mod-name_version.zip` + // - zip contains one directory, `mod-name` + archiveFileName.set("${rootProject.name}_${project.version}.zip") + destinationDirectory.set(layout.buildDirectory.dir("dist")) + + doLast { + val outDir = destinationDirectory.asFile.get().toRelativeString(layout.projectDirectory.asFile) + val outZip = "${archiveFileName.orNull}" + logger.lifecycle("Packaged mod into $outDir/$outZip") + } +} + + +val downloadFactorioApiDocs by tasks.registering { + group = project.name + + val target = uri("https://lua-api.factorio.com/latest/runtime-api.json") + val apiFilename = File(target.path).name + val downloadedFile = file("$temporaryDir/$apiFilename") + + val apiFile = layout.buildDirectory.file(apiFilename) + outputs.file(apiFile) + + doLast { + + ant.invokeMethod( + "get", mapOf( + "src" to target, + "dest" to downloadedFile, + "verbose" to true, + ) + ) + + val json = downloadedFile.readText() + val prettyJson = JsonOutput.prettyPrint(json) + + apiFile.get().asFile.writeText(prettyJson) + + logger.lifecycle("Downloaded Factorio API json: $apiFile") + } +} + + +val factorioModProvider by configurations.registering { + asProvider() + factorioModAttributes(objects) + outgoing.artifact(packageMod) +} + + +tasks.assemble { dependsOn(updateDataModel, updatePackageJsonVersion) } +tasks.build { dependsOn(packageMod) } + + +// +//idea { +// // this doesn't work - no source sets? +// module { +// sourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript").asFile)) +// excludeDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript/node_modules").asFile)) +// resourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/resources").asFile)) +// resourceDirs.add(mkdir(layout.projectDirectory.dir("infra").asFile)) +// excludeDirs.add(mkdir(layout.projectDirectory.dir("infra/factorio-server").asFile)) +// } +//} +// +//val typescriptSrcSet = +// project.objects.sourceDirectorySet("typescript", "typescript").apply { +// srcDir(layout.projectDirectory.dir("src/main/typescript")) +// +// destinationDirectory.set(modBuildDir.dir("typescriptToLua").asFile) +// compiledBy(tstlTask) { +// +// project.objects.directoryProperty().apply { +// set(modBuildDir.dir("typescriptToLua")) +// } +// } +// } diff --git a/modules/mod/src/main/resources/mod-data/changelog.txt b/modules/events-mod/src/main/resources/mod-data/changelog.txt similarity index 100% rename from modules/mod/src/main/resources/mod-data/changelog.txt rename to modules/events-mod/src/main/resources/mod-data/changelog.txt diff --git a/modules/mod/src/main/resources/mod-data/info.json b/modules/events-mod/src/main/resources/mod-data/info.json similarity index 100% rename from modules/mod/src/main/resources/mod-data/info.json rename to modules/events-mod/src/main/resources/mod-data/info.json diff --git a/modules/mod/src/main/resources/mod-data/thumbnail.png b/modules/events-mod/src/main/resources/mod-data/thumbnail.png similarity index 100% rename from modules/mod/src/main/resources/mod-data/thumbnail.png rename to modules/events-mod/src/main/resources/mod-data/thumbnail.png diff --git a/modules/mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts similarity index 100% rename from modules/mod/src/main/typescript/control.ts rename to modules/events-mod/src/main/typescript/control.ts diff --git a/modules/mod/src/main/typescript/events.ts b/modules/events-mod/src/main/typescript/events.ts similarity index 100% rename from modules/mod/src/main/typescript/events.ts rename to modules/events-mod/src/main/typescript/events.ts diff --git a/modules/mod/src/main/typescript/generated/data-model.ts b/modules/events-mod/src/main/typescript/model/data-model.ts similarity index 99% rename from modules/mod/src/main/typescript/generated/data-model.ts rename to modules/events-mod/src/main/typescript/model/data-model.ts index 8950029..15f67d9 100644 --- a/modules/mod/src/main/typescript/generated/data-model.ts +++ b/modules/events-mod/src/main/typescript/model/data-model.ts @@ -43,4 +43,4 @@ interface SurfaceData extends FactorioObjectData { index: uint; name: string; object_name: string; -} \ No newline at end of file +} diff --git a/modules/mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json similarity index 99% rename from modules/mod/src/main/typescript/package-lock.json rename to modules/events-mod/src/main/typescript/package-lock.json index f4d614b..ab7b085 100644 --- a/modules/mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "factorio-web-map-mod", - "version": "0.0.6", + "version": "0.0.7", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json similarity index 77% rename from modules/mod/src/main/typescript/package.json rename to modules/events-mod/src/main/typescript/package.json index 95396be..4bc733a 100644 --- a/modules/mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -9,8 +9,7 @@ "engines": { "node": ">=10.13.0" }, - "devDependencies": { - }, + "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", @@ -21,10 +20,7 @@ "//": { "typed-factorio": "0.10.0" }, - "peerDependencies": { - }, - "optionalDependencies": { - }, - "bundledDependencies": [ - ] + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] } diff --git a/modules/mod/src/main/typescript/serdes/serdes.ts b/modules/events-mod/src/main/typescript/serdes/serdes.ts similarity index 100% rename from modules/mod/src/main/typescript/serdes/serdes.ts rename to modules/events-mod/src/main/typescript/serdes/serdes.ts diff --git a/modules/mod/src/main/typescript/tsconfig.json b/modules/events-mod/src/main/typescript/tsconfig.json similarity index 100% rename from modules/mod/src/main/typescript/tsconfig.json rename to modules/events-mod/src/main/typescript/tsconfig.json diff --git a/modules/factorio-events-processor/build.gradle.kts b/modules/events-processor/build.gradle.kts similarity index 89% rename from modules/factorio-events-processor/build.gradle.kts rename to modules/events-processor/build.gradle.kts index 216a19e..9b30683 100644 --- a/modules/factorio-events-processor/build.gradle.kts +++ b/modules/events-processor/build.gradle.kts @@ -11,14 +11,13 @@ description = """ """.trimIndent() val projectId: String by project.extra -val buildDir: Directory = layout.buildDirectory.dir(projectId).get() @Suppress("UnstableApiUsage") dependencies { implementation("org.apache.kafka:kafka-streams:3.0.0") - implementation(projects.modules.factorioEventsDataModel) + implementation(projects.modules.eventsSchema) // implementation("com.ionspin.kotlin:bignum:0.3.3") diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventLogConsumer.kt b/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventLogConsumer.kt similarity index 100% rename from modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventLogConsumer.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventLogConsumer.kt diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventsTopology.kt b/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventsTopology.kt similarity index 100% rename from modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventsTopology.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventsTopology.kt diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt b/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt similarity index 100% rename from modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt b/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt similarity index 100% rename from modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/Lenses.kt b/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/Lenses.kt similarity index 100% rename from modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/Lenses.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/Lenses.kt diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/PortVal.kt b/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/PortVal.kt similarity index 100% rename from modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/PortVal.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/PortVal.kt diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/environmentExt.kt b/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/environmentExt.kt similarity index 100% rename from modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/environmentExt.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/environmentExt.kt diff --git a/modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt b/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt similarity index 100% rename from modules/factorio-events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt diff --git a/modules/factorio-events-processor/src/main/resources/logback.xml b/modules/events-processor/src/main/resources/logback.xml similarity index 100% rename from modules/factorio-events-processor/src/main/resources/logback.xml rename to modules/events-processor/src/main/resources/logback.xml diff --git a/modules/factorio-events-data-model/build.gradle.kts b/modules/events-schema/build.gradle.kts similarity index 91% rename from modules/factorio-events-data-model/build.gradle.kts rename to modules/events-schema/build.gradle.kts index a8ed8a2..c2a9332 100644 --- a/modules/factorio-events-data-model/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -6,9 +6,6 @@ plugins { kotlin("plugin.serialization") } -val projectId: String by project.extra -val buildDir: Directory = layout.buildDirectory.dir(projectId).get() - dependencies { implementation(platform(libs.kotlinx.serialization.bom)) implementation(libs.kotlinx.serialization.core) diff --git a/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt b/modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt similarity index 100% rename from modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt rename to modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt diff --git a/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt b/modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt similarity index 100% rename from modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt rename to modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt diff --git a/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/json.kt b/modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/json.kt similarity index 100% rename from modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/json.kt rename to modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/json.kt diff --git a/modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt b/modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt similarity index 100% rename from modules/factorio-events-data-model/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt rename to modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt diff --git a/modules/factorio-events-data-model/src/test/kotlin/dev/adamko/factorioevents/model/FactorioEventTest.kt b/modules/events-schema/src/test/kotlin/dev/adamko/factorioevents/model/FactorioEventTest.kt similarity index 100% rename from modules/factorio-events-data-model/src/test/kotlin/dev/adamko/factorioevents/model/FactorioEventTest.kt rename to modules/events-schema/src/test/kotlin/dev/adamko/factorioevents/model/FactorioEventTest.kt diff --git a/modules/factorio-events-kafka-pipe/build.gradle.kts b/modules/factorio-events-kafka-pipe/build.gradle.kts deleted file mode 100644 index e36b82f..0000000 --- a/modules/factorio-events-kafka-pipe/build.gradle.kts +++ /dev/null @@ -1,12 +0,0 @@ -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs - -plugins { - id("dev.adamko.factoriowebmap.archetype.base") -} - -description = - """ - Send events from a Factorio server to a Kafka topic - """.trimIndent() - -val projectId: String by project.extra diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts new file mode 100644 index 0000000..a4415f5 --- /dev/null +++ b/modules/infra-factorio-client/build.gradle.kts @@ -0,0 +1,81 @@ +import dev.adamko.factoriowebmap.configurations.asConsumer +import dev.adamko.factoriowebmap.configurations.factorioModAttributes +import dev.adamko.isProcessRunning +import dev.adamko.not +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + +plugins { + id("dev.adamko.factoriowebmap.archetype.process-runner") +} + +val tokens: Map by project.extra + +val clientModsDirectory = file("""D:\Users\Adam\AppData\Roaming\Factorio\mods""") +val factorioGameId = "427520" +val steamExe = """C:\Program Files (x86)\Steam\steam.exe""" + +val factorioMod: Configuration by configurations.creating { + asConsumer() + factorioModAttributes(objects) +} + +dependencies { + factorioMod(projects.modules.eventsMod) +} + +// +val deployModToClient by tasks.registering(Copy::class) { + description = "Copy the mod to the Factorio client" + group = project.name + + from(factorioMod) + into(clientModsDirectory) + + doLast { + logger.lifecycle("Copying mod from ${source.files} to $destinationDir") + } +} +// + +// +fun isFactorioRunning(): Spec = isProcessRunning("factorio.exe") + +val clientLaunch by tasks.registering(Exec::class) { + description = "Run Factorio Steam game client" + group = project.name + + onlyIf(!isFactorioRunning()) + + dependsOn(deployModToClient) + mustRunAfter(clientKill) + + commandLine = parseSpaceSeparatedArgs( +// """explorer "steam://rungameid/$factorioGameId// --mp-connect localhost/" """ // not working +// """explorer "steam://run/$factorioGameId//--mp-connect localhost/" """ // works! But has annoying pop-up + """ $steamExe -applaunch $factorioGameId --mp-connect localhost """ + ) + doFirst { logger.lifecycle("Launching factorio.exe") } +} + +val clientKill by tasks.registering(Exec::class) { + description = "Run Factorio Steam game client" + group = project.name + onlyIf(isFactorioRunning()) + commandLine = parseSpaceSeparatedArgs(""" taskkill /im factorio.exe """) + doFirst { logger.lifecycle("Killing factorio.exe") } +} +// + +tasks.build { dependsOn(deployModToClient) } + +tasks.processRun { + dependsOn( + deployModToClient, + clientLaunch, + ) +} + +tasks.processKill { + dependsOn(clientKill) +} + diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts new file mode 100644 index 0000000..9489d07 --- /dev/null +++ b/modules/infra-factorio-server/build.gradle.kts @@ -0,0 +1,77 @@ +import dev.adamko.factoriowebmap.configurations.asConsumer +import dev.adamko.factoriowebmap.configurations.factorioModAttributes +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + +plugins { + id("dev.adamko.factoriowebmap.archetype.process-runner") +} + +val tokens: Map by project.extra + +val modInfraDir: Directory = layout.projectDirectory.dir("infra") +val factorioServerDataDir: Directory = modInfraDir.dir("factorio-server") + +val factorioMod: Configuration by configurations.creating { + asConsumer() + factorioModAttributes(objects) +} + +dependencies { + factorioMod(projects.modules.eventsMod) +} + +val deployModToServer by tasks.registering(Copy::class) { + description = "Copy the mod to the Factorio Docker server" + group = project.name + + from(factorioMod) + into(factorioServerDataDir.dir("mods")) + + doLast { + logger.lifecycle("Copying mods ${source.files} to $destinationDir") + } +} + +// +val factorioServerStop = tasks.register("factorioServerStop") { + group = project.name + + mustRunAfter(deployModToServer) + + workingDir(modInfraDir) + commandLine = parseSpaceSeparatedArgs("docker-compose stop factorio-server") +} + +val factorioServerUp = tasks.register("factorioServerUp") { + group = project.name + + mustRunAfter(deployModToServer) + dependsOn(factorioServerStop) + + workingDir(modInfraDir) + commandLine = parseSpaceSeparatedArgs("docker-compose up -d factorio-server") +} + +val factorioServerRestart: Task by tasks.creating { + group = project.name + + dependsOn(factorioServerStop, factorioServerUp) +} +// + +tasks.build { dependsOn(deployModToServer) } + +tasks.processRun { + description = "Build the mod, upload to Server and Client, and start both" + dependsOn( + deployModToServer, + factorioServerRestart, + ) +} + +tasks.processKill { + dependsOn( + factorioServerStop, + ) +} + diff --git a/modules/mod/infra/.env b/modules/infra-factorio-server/infra/.env similarity index 100% rename from modules/mod/infra/.env rename to modules/infra-factorio-server/infra/.env diff --git a/modules/mod/infra/.gitignore b/modules/infra-factorio-server/infra/.gitignore similarity index 100% rename from modules/mod/infra/.gitignore rename to modules/infra-factorio-server/infra/.gitignore diff --git a/modules/infra-factorio-server/infra/docker-compose.yml b/modules/infra-factorio-server/infra/docker-compose.yml new file mode 100644 index 0000000..12fe89d --- /dev/null +++ b/modules/infra-factorio-server/infra/docker-compose.yml @@ -0,0 +1,39 @@ +version: "3.9" + +services: + + factorio-server: + image: factoriotools/factorio:1.1.48 + # logging: + # driver: "json-file" + container_name: "factorio-server" + restart: "unless-stopped" + networks: + - "factorio-events-nw" + ports: + - "34197:34197/udp" # factorio + - "27015:27015/tcp" # rcon + volumes: + - "./factorio-server:/factorio" + # logging: + # driver: "mickyg/kafka-logdriver:latest" + # options: + # KAFKA_BROKER_ADDR: "kafka-kraft" + # LOG_TOPIC: "dockerlogs-factorio-server" + # LOG_TAG: "factorio-server" + + # environment: + # RCON_PORT: 27715 + # environment: + # - PUID=1000 + # - PGID=1000 + # - UPDATE_MODS_ON_START=true + # - USERNAME=FactorioUsername + # - TOKEN=FactorioToken + +networks: + kafka-nw: + name: "kafka-nw" + external: true + factorio-events-nw: + name: "factorio-events-nw" diff --git a/modules/mod/infra/factorioEvents.Dockerfile b/modules/infra-factorio-server/infra/factorioEvents.Dockerfile similarity index 100% rename from modules/mod/infra/factorioEvents.Dockerfile rename to modules/infra-factorio-server/infra/factorioEvents.Dockerfile diff --git a/modules/mod/infra/kafka-pipe.sh b/modules/infra-factorio-server/infra/kafka-pipe.sh similarity index 100% rename from modules/mod/infra/kafka-pipe.sh rename to modules/infra-factorio-server/infra/kafka-pipe.sh diff --git a/modules/mod/infra/kcat.conf b/modules/infra-factorio-server/infra/kcat.conf similarity index 100% rename from modules/mod/infra/kcat.conf rename to modules/infra-factorio-server/infra/kcat.conf diff --git a/modules/mod/infra/docker-compose.yml b/modules/infra-kafka-cluster/docker-compose.yml similarity index 60% rename from modules/mod/infra/docker-compose.yml rename to modules/infra-kafka-cluster/docker-compose.yml index 3b42704..75c7cc6 100644 --- a/modules/mod/infra/docker-compose.yml +++ b/modules/infra-kafka-cluster/docker-compose.yml @@ -2,35 +2,6 @@ version: "3.9" services: - factorio-server: - image: factoriotools/factorio:1.1.48 - # logging: - # driver: "json-file" - container_name: "factorio-server" - restart: "unless-stopped" - networks: - - "factorio-events-nw" - ports: - - "34197:34197/udp" # factorio - - "27015:27015/tcp" # rcon - volumes: - - "./factorio-server:/factorio" - # logging: - # driver: "mickyg/kafka-logdriver:latest" - # options: - # KAFKA_BROKER_ADDR: "kafka-kraft" - # LOG_TOPIC: "dockerlogs-factorio-server" - # LOG_TAG: "factorio-server" - - # environment: - # RCON_PORT: 27715 - # environment: - # - PUID=1000 - # - PGID=1000 - # - UPDATE_MODS_ON_START=true - # - USERNAME=FactorioUsername - # - TOKEN=FactorioToken - kafka: image: dev-adamko/kafka-kraft container_name: "kafka" @@ -74,10 +45,9 @@ services: # - "8083:8083" # - networks: kafka-nw: name: "kafka-nw" factorio-events-nw: name: "factorio-events-nw" - + external: true diff --git a/modules/mod/infra/kafka-server.properties b/modules/infra-kafka-cluster/kafka-server.properties similarity index 100% rename from modules/mod/infra/kafka-server.properties rename to modules/infra-kafka-cluster/kafka-server.properties diff --git a/modules/mod/infra/kafka.Dockerfile b/modules/infra-kafka-cluster/kafka.Dockerfile similarity index 100% rename from modules/mod/infra/kafka.Dockerfile rename to modules/infra-kafka-cluster/kafka.Dockerfile diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts new file mode 100644 index 0000000..2744f98 --- /dev/null +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -0,0 +1,6 @@ +plugins { + id("dev.adamko.factoriowebmap.archetype.process-runner") +} + +description = "Send events from a Factorio server to a Kafka topic " + diff --git a/modules/factorio-events-kafka-pipe/.env b/modules/infra-kafka-pipe/src/.env similarity index 100% rename from modules/factorio-events-kafka-pipe/.env rename to modules/infra-kafka-pipe/src/.env diff --git a/modules/factorio-events-kafka-pipe/docker-compose.yml b/modules/infra-kafka-pipe/src/docker-compose.yml similarity index 100% rename from modules/factorio-events-kafka-pipe/docker-compose.yml rename to modules/infra-kafka-pipe/src/docker-compose.yml diff --git a/modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile b/modules/infra-kafka-pipe/src/kafka-pipe.Dockerfile similarity index 100% rename from modules/factorio-events-kafka-pipe/kafka-pipe.Dockerfile rename to modules/infra-kafka-pipe/src/kafka-pipe.Dockerfile diff --git a/modules/factorio-events-kafka-pipe/kafka-pipe.sh b/modules/infra-kafka-pipe/src/kafka-pipe.sh similarity index 100% rename from modules/factorio-events-kafka-pipe/kafka-pipe.sh rename to modules/infra-kafka-pipe/src/kafka-pipe.sh diff --git a/modules/factorio-events-kafka-pipe/readme.md b/modules/infra-kafka-pipe/src/readme.md similarity index 100% rename from modules/factorio-events-kafka-pipe/readme.md rename to modules/infra-kafka-pipe/src/readme.md diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts deleted file mode 100644 index e3004ed..0000000 --- a/modules/mod/build.gradle.kts +++ /dev/null @@ -1,318 +0,0 @@ -import com.github.gradle.node.npm.task.NpmTask -import dev.adamko.factoriowebmap.configurations.asConsumer -import dev.adamko.factoriowebmap.configurations.typescriptAttributes -import groovy.json.JsonOutput -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.JsonPrimitive -import kotlinx.serialization.json.jsonObject -import kotlinx.serialization.json.jsonPrimitive -import org.apache.tools.ant.filters.ReplaceTokens -import org.gradle.kotlin.dsl.support.useToRun -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs -import org.jetbrains.kotlin.util.suffixIfNot - -plugins { - idea - id("dev.adamko.factoriowebmap.archetype.node") -} - -val projectId: String by project.extra -val tokens: Map by project.extra - -val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") -val modBuildDir: Directory = layout.buildDirectory.dir(projectId).get() - -node { - nodeProjectDir.set(tsSrcDir) -} - -val tstlTask = tasks.register("typescriptToLua") { - description = "Convert Typescript To Lua" - group = projectId - - dependsOn(tasks.npmInstall) - - execOverrides { standardOutput = System.out } - - npmCommand.set(listOf("run", "build")) - - inputs.dir(project.node.nodeProjectDir) - .skipWhenEmpty() - .withPropertyName("sourceFiles") - .withPathSensitivity(PathSensitivity.RELATIVE) - - val intermediateOutputDir = temporaryDir - args.set(parseSpaceSeparatedArgs("-- --outDir $intermediateOutputDir")) - val outputDir: Directory = modBuildDir.dir("typescriptToLua") - outputs.dir(outputDir) - .withPropertyName("outputDir") - - ignoreExitValue.set(false) - - doFirst("clean") { - delete(intermediateOutputDir) - } - - doLast("syncTstlOutput") { - sync { - from(intermediateOutputDir) - into(outputDir) - } - } - -} - -val updatePackageJsonVersion by tasks.registering { - group = project.name - description = """ - Read the package.json file and set the version to be the project's version. - """.trimIndent() - - val projectVersion = "${project.version}" - inputs.properties( - "projectVersion" to projectVersion, - ) - - val packageJsonFile = layout.projectDirectory.file("src/main/typescript/package.json") - outputs.file(packageJsonFile) - - val jsonFormatter = Json { - prettyPrint = true - prettyPrintIndent = " " - } - - onlyIf { - val packageJsonContent = packageJsonFile.asFile.readText() - val packageJson = jsonFormatter.parseToJsonElement(packageJsonContent).jsonObject - packageJson["version"]?.jsonPrimitive?.content != projectVersion - } - - doFirst { - delete(temporaryDir) - mkdir(temporaryDir) - } - - doLast { - val packageJsonContent = packageJsonFile.asFile.readText() - val packageJson = jsonFormatter.parseToJsonElement(packageJsonContent).jsonObject - val packageJsonUpdate = JsonObject( - packageJson + ("version" to JsonPrimitive(projectVersion)) - ) - val packageJsonContentUpdated = - jsonFormatter - .encodeToString(packageJsonUpdate) - .suffixIfNot("\n") - packageJsonFile.asFile.writer().useToRun { - write(packageJsonContentUpdated) - } - } -} - -tasks.assemble { dependsOn(updatePackageJsonVersion) } - - -val dataModelTs: Configuration by configurations.creating { - asConsumer() - typescriptAttributes(objects) -} - -dependencies { - dataModelTs(projects.modules.factorioEventsDataModel) -} - -val updateDataModel by tasks.registering(Sync::class) { - group = project.name - - dependsOn(dataModelTs) - - from( - dataModelTs.incoming - .artifactView { lenient(true) } - .artifacts - .artifactFiles - .filter { it.exists() } - ) - - into(layout.projectDirectory.dir("src/main/typescript/generated")) -} - -tasks.assemble { dependsOn(updateDataModel) } - - - -idea { - module { - sourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript").asFile)) - excludeDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript/node_modules").asFile)) - resourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/resources").asFile)) - resourceDirs.add(mkdir(layout.projectDirectory.dir("infra").asFile)) - excludeDirs.add(mkdir(layout.projectDirectory.dir("infra/factorio-server").asFile)) - } -} - -val typescriptSrcSet = - project.objects.sourceDirectorySet("typescript", "typescript").apply { - srcDir(layout.projectDirectory.dir("src/main/typescript")) - - destinationDirectory.set(modBuildDir.dir("typescriptToLua").asFile) - compiledBy(tstlTask) { - - project.objects.directoryProperty().apply { - set(modBuildDir.dir("typescriptToLua")) - } - } - } - -val modPackageTask = tasks.register("packageMod") { - description = "Package mod files into ZIP" - group = projectId - - dependsOn(tstlTask) - - inputs.properties(tokens) - - from(layout.projectDirectory.dir("src/main/resources/mod-data")) { - include("**/**") - filter("tokens" to tokens) - } - from( - rootProject.layout.projectDirectory.file("LICENSE"), - tstlTask, - ) - - into(rootProject.name) - - // Factorio required format is: - // - filename: `mod-name_version.zip` - // - zip contains one directory, `mod-name` - archiveFileName.set("${rootProject.name}_${project.version}.zip") - destinationDirectory.set(modBuildDir.dir("dist")) - - doLast { - val outDir = destinationDirectory.asFile.get().toRelativeString(layout.projectDirectory.asFile) - val outZip = "${archiveFileName.orNull}" - logger.lifecycle("Creating mod zip $outDir/$outZip") - } -} - -//tasks.build { dependsOn(tstlTask, modPackageTask) } - -val modInfraDir: Directory = layout.projectDirectory.dir("infra") -val factorioServerDataDir: Directory = modInfraDir.dir("factorio-server") - -val copyModToServerTask = tasks.register("copyModToServer") { - description = "Copy the mod to the Factorio Docker server" - group = "$projectId.factorioServer" - - dependsOn(modPackageTask) - - from(modPackageTask) - into(factorioServerDataDir.dir("mods")) - - doLast { - logger.lifecycle("Copying mod from ${source.files} to $destinationDir") - } -} - -val factorioServerStop = tasks.register("factorioServerStop") { - group = "$projectId.factorioServer" - - mustRunAfter(copyModToServerTask) - - workingDir(modInfraDir) - commandLine = parseSpaceSeparatedArgs("docker-compose stop factorio-server") -} - -val factorioServerUp = tasks.register("factorioServerUp") { - group = "$projectId.factorioServer" - - mustRunAfter(copyModToServerTask) - dependsOn(factorioServerStop) - - workingDir(modInfraDir) - commandLine = parseSpaceSeparatedArgs("docker-compose up -d factorio-server") -} - -val factorioServerRestart: Task by tasks.creating { - group = "$projectId.factorioServer" - - dependsOn(factorioServerStop, factorioServerUp) -} - -//val serverRestartTask = tasks.register("dockerRestart") { -// group = "$projectId.factorioServer" -// -// workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile -// commandLine = parseSpaceSeparatedArgs("docker-compose restart") -//} - -val copyModToClientTask = tasks.register("copyModToClient") { - description = "Copy the mod to the Factorio client" - group = "$projectId.factorioClient" - - dependsOn(modPackageTask) - - from(modPackageTask) - into("""D:\Users\Adam\AppData\Roaming\Factorio\mods""") - - doLast { - logger.lifecycle("Copying mod from ${source.files} to $destinationDir") - } -} - -//val factorioClientLaunch = tasks.register("launch") { -// description = "Run Factorio client" -// group = "$projectId.factorioClient" -// -// dependsOn( -// serverRestartTask, -// copyModToClientTask -// ) -// -//// workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile -// commandLine = parseSpaceSeparatedArgs( -// """explorer "steam://rungameid/427520 --mp-connect localhost" """ -// ) -//} - -val launch = tasks.register("modLauncher") { - description = "Build the mod, upload to Server and Client, and start both" - group = projectId - dependsOn( - copyModToServerTask, - copyModToClientTask, - factorioServerRestart, -// factorioClientLaunch, - ) -} - -tasks.register("downloadFactorioApiDocs") { - group = projectId - - val target = uri("https://lua-api.factorio.com/latest/runtime-api.json") - val apiFilename = File(target.path).name - val downloadedFile = file("$temporaryDir/$apiFilename") - - val apiFile = modBuildDir.file(apiFilename) - outputs.file(apiFile) - - doLast { - - ant.invokeMethod( - "get", mapOf( - "src" to target, - "dest" to downloadedFile, - "verbose" to true, - ) - ) - - val json = downloadedFile.readText() - val prettyJson = JsonOutput.prettyPrint(json) - - apiFile.asFile.writeText(prettyJson) - - logger.lifecycle("Downloaded Factorio API json: $apiFile") - } -} diff --git a/settings.gradle.kts b/settings.gradle.kts index c0e4e8b..5c78149 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,11 +1,17 @@ -rootProject.name = "factorio-web-map" +rootProject.name = "kafkatorio" include( - ":modules:mod", + + ":modules:events-mod", + ":modules:events-processor", + ":modules:events-schema", + + ":modules:infra-factorio-client", + ":modules:infra-factorio-server", + ":modules:infra-kafka-cluster", + ":modules:infra-kafka-pipe", + ":modules:kt-rcon", - ":modules:factorio-events-data-model", - ":modules:factorio-events-processor", - ":modules:factorio-events-kafka-pipe", ) enableFeaturePreview("VERSION_CATALOGS") From 8c75b47a96fa5d0222899974a90bb99b241e2ace Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 1 Dec 2021 18:12:34 +0100 Subject: [PATCH 084/629] more re-organisation to new name --- .../factoriowebmap/archetype/node.gradle.kts | 19 ---- .../configurations/factorioMod.kt | 20 ----- .../factoriowebmap/configurations/type.kt | 15 ---- .../configurations/typescript.kt | 20 ----- .../archetype => kafkatorio}/base.gradle.kts | 6 +- .../kafkatorio/gradle/artifactDistribution.kt | 41 +++++++++ .../gradle/extensions.kt} | 0 .../lang}/kotlin-js.gradle.kts | 9 +- .../lang}/kotlin-jvm.gradle.kts | 7 +- .../lang}/kotlin-multiplatform.gradle.kts | 8 +- .../adamko/kafkatorio/lang/node.gradle.kts | 87 +++++++++++++++++++ .../process-runner.gradle.kts | 7 +- .../kafkatorio/task/UpdatePackageJson.kt | 9 ++ modules/events-mod/build.gradle.kts | 76 +++------------- .../events-mod/src/main/typescript/events.ts | 9 -- .../src/main/typescript/package.json | 2 +- .../kafkatorio-events.ts} | 0 modules/events-processor/build.gradle.kts | 2 +- .../processor/FactorioEventLogConsumer.kt | 2 +- .../processor/FactorioEventsTopology.kt | 2 +- .../processor/StreamsExceptionHandler.kt | 2 +- .../processor/config/ApplicationProperties.kt | 4 +- .../processor/config/Lenses.kt | 2 +- .../processor/config/PortVal.kt | 2 +- .../processor/config/environmentExt.kt | 2 +- .../processor/main.kt | 8 +- modules/events-schema/build.gradle.kts | 6 +- .../events/schema}/builtinTypes.kt | 2 +- .../events/schema}/factorioEvents.kt | 2 +- .../events/schema}/json.kt | 2 +- .../events/schema}/kt2ts.kt | 2 +- .../events/schema}/FactorioEventTest.kt | 9 +- .../infra-factorio-client/build.gradle.kts | 7 +- .../infra-factorio-server/build.gradle.kts | 6 +- modules/infra-kafka-pipe/build.gradle.kts | 2 +- modules/kt-rcon/build.gradle.kts | 2 +- .../src/main/kotlin/dev/adamko/ktrcon/main.kt | 15 ++-- 37 files changed, 219 insertions(+), 197 deletions(-) delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/factorioMod.kt delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/type.kt delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/typescript.kt rename buildSrc/src/main/kotlin/dev/adamko/{factoriowebmap/archetype => kafkatorio}/base.gradle.kts (76%) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistribution.kt rename buildSrc/src/main/kotlin/dev/adamko/{gradleExtensions.kt => kafkatorio/gradle/extensions.kt} (100%) rename buildSrc/src/main/kotlin/dev/adamko/{factoriowebmap/archetype => kafkatorio/lang}/kotlin-js.gradle.kts (87%) rename buildSrc/src/main/kotlin/dev/adamko/{factoriowebmap/archetype => kafkatorio/lang}/kotlin-jvm.gradle.kts (90%) rename buildSrc/src/main/kotlin/dev/adamko/{factoriowebmap/archetype => kafkatorio/lang}/kotlin-multiplatform.gradle.kts (67%) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts rename buildSrc/src/main/kotlin/dev/adamko/{factoriowebmap/archetype => kafkatorio}/process-runner.gradle.kts (72%) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt rename modules/events-mod/src/main/typescript/{model/data-model.ts => schema/kafkatorio-events.ts} (100%) rename modules/events-processor/src/main/kotlin/dev/adamko/{factorioevents => kafkatorio}/processor/FactorioEventLogConsumer.kt (66%) rename modules/events-processor/src/main/kotlin/dev/adamko/{factorioevents => kafkatorio}/processor/FactorioEventsTopology.kt (87%) rename modules/events-processor/src/main/kotlin/dev/adamko/{factorioevents => kafkatorio}/processor/StreamsExceptionHandler.kt (91%) rename modules/events-processor/src/main/kotlin/dev/adamko/{factorioevents => kafkatorio}/processor/config/ApplicationProperties.kt (92%) rename modules/events-processor/src/main/kotlin/dev/adamko/{factorioevents => kafkatorio}/processor/config/Lenses.kt (95%) rename modules/events-processor/src/main/kotlin/dev/adamko/{factorioevents => kafkatorio}/processor/config/PortVal.kt (92%) rename modules/events-processor/src/main/kotlin/dev/adamko/{factorioevents => kafkatorio}/processor/config/environmentExt.kt (97%) rename modules/events-processor/src/main/kotlin/dev/adamko/{factorioevents => kafkatorio}/processor/main.kt (85%) rename modules/events-schema/src/main/kotlin/dev/adamko/{factorioevents/model => kafkatorio/events/schema}/builtinTypes.kt (98%) rename modules/events-schema/src/main/kotlin/dev/adamko/{factorioevents/model => kafkatorio/events/schema}/factorioEvents.kt (98%) rename modules/events-schema/src/main/kotlin/dev/adamko/{factorioevents/model => kafkatorio/events/schema}/json.kt (96%) rename modules/events-schema/src/main/kotlin/dev/adamko/{factorioevents/model => kafkatorio/events/schema}/kt2ts.kt (97%) rename modules/events-schema/src/test/kotlin/dev/adamko/{factorioevents/model => kafkatorio/events/schema}/FactorioEventTest.kt (89%) diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts deleted file mode 100644 index 0984035..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts +++ /dev/null @@ -1,19 +0,0 @@ -package dev.adamko.factoriowebmap.archetype - -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin -import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlugin - -plugins { - id("com.github.node-gradle.node") - id("dev.adamko.factoriowebmap.archetype.base") -} - -node { - download.set(true) - version.set("14.18.0") - - distBaseUrl.set(null as String?) // set by dependencyResolutionManagement -} - -project.plugins.withType() -project.plugins.withType() diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/factorioMod.kt b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/factorioMod.kt deleted file mode 100644 index e158817..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/factorioMod.kt +++ /dev/null @@ -1,20 +0,0 @@ -package dev.adamko.factoriowebmap.configurations - -import org.gradle.api.artifacts.Configuration -import org.gradle.api.attributes.AttributeContainer -import org.gradle.api.attributes.Bundling -import org.gradle.api.attributes.Category -import org.gradle.api.attributes.LibraryElements -import org.gradle.api.attributes.Usage -import org.gradle.api.model.ObjectFactory -import org.gradle.kotlin.dsl.named - -fun Configuration.factorioModAttributes(objects: ObjectFactory) = - attributes { factorioMod(objects) } - -fun AttributeContainer.factorioMod(objects: ObjectFactory) { - attribute(Usage.USAGE_ATTRIBUTE, objects.named("factorio")) - attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) - attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.CLASSES_AND_RESOURCES)) - attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EMBEDDED)) -} diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/type.kt b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/type.kt deleted file mode 100644 index 272b7ce..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/type.kt +++ /dev/null @@ -1,15 +0,0 @@ -package dev.adamko.factoriowebmap.configurations - -import org.gradle.api.artifacts.Configuration - -fun Configuration.asProvider() { - isVisible = false - isCanBeResolved = false - isCanBeConsumed = true -} - -fun Configuration.asConsumer() { - isVisible = false - isCanBeResolved = true - isCanBeConsumed = false -} diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/typescript.kt b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/typescript.kt deleted file mode 100644 index 2020f16..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/configurations/typescript.kt +++ /dev/null @@ -1,20 +0,0 @@ -package dev.adamko.factoriowebmap.configurations - -import org.gradle.api.artifacts.Configuration -import org.gradle.api.attributes.AttributeContainer -import org.gradle.api.attributes.Bundling -import org.gradle.api.attributes.Category -import org.gradle.api.attributes.LibraryElements -import org.gradle.api.attributes.Usage -import org.gradle.api.model.ObjectFactory -import org.gradle.kotlin.dsl.named - -fun Configuration.typescriptAttributes(objects: ObjectFactory) = - attributes { typescript(objects) } - -fun AttributeContainer.typescript(objects: ObjectFactory) { - attribute(Usage.USAGE_ATTRIBUTE, objects.named("typescript")) - attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) - attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.OBJECTS)) - attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL)) -} diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts similarity index 76% rename from buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts rename to buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts index 999ef24..cb48dee 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts @@ -1,4 +1,8 @@ -package dev.adamko.factoriowebmap.archetype +package dev.adamko.kafkatorio + +import org.gradle.kotlin.dsl.base +import org.gradle.kotlin.dsl.extra +import org.gradle.kotlin.dsl.idea plugins { idea diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistribution.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistribution.kt new file mode 100644 index 0000000..e4a9181 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistribution.kt @@ -0,0 +1,41 @@ +package dev.adamko.kafkatorio.gradle + +import org.gradle.api.artifacts.Configuration +import org.gradle.api.attributes.Bundling +import org.gradle.api.attributes.Bundling.BUNDLING_ATTRIBUTE +import org.gradle.api.attributes.Category +import org.gradle.api.attributes.Category.CATEGORY_ATTRIBUTE +import org.gradle.api.attributes.LibraryElements +import org.gradle.api.attributes.LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE +import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE +import org.gradle.api.model.ObjectFactory +import org.gradle.kotlin.dsl.named + + +fun Configuration.asProvider() { + isVisible = false + isCanBeResolved = false + isCanBeConsumed = true +} + +fun Configuration.asConsumer() { + isVisible = false + isCanBeResolved = true + isCanBeConsumed = false +} + +fun Configuration.factorioModAttributes(objects: ObjectFactory): Configuration = + attributes { + attribute(USAGE_ATTRIBUTE, objects.named("factorio")) + attribute(CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) + attribute(LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.CLASSES_AND_RESOURCES)) + attribute(BUNDLING_ATTRIBUTE, objects.named(Bundling.EMBEDDED)) + } + +fun Configuration.typescriptAttributes(objects: ObjectFactory) = + attributes { + attribute(USAGE_ATTRIBUTE, objects.named("typescript")) + attribute(CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) + attribute(LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.OBJECTS)) + attribute(BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL)) + } diff --git a/buildSrc/src/main/kotlin/dev/adamko/gradleExtensions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt similarity index 100% rename from buildSrc/src/main/kotlin/dev/adamko/gradleExtensions.kt rename to buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts similarity index 87% rename from buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts rename to buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts index 26c4bc6..a7ce394 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts @@ -1,8 +1,11 @@ -package dev.adamko.factoriowebmap.archetype +package dev.adamko.kafkatorio.lang import org.gradle.kotlin.dsl.kotlin import com.github.gradle.node.npm.task.NpmTask import com.github.gradle.node.task.NodeTask +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.extra +import org.gradle.kotlin.dsl.getting import org.jetbrains.kotlin.gradle.targets.js.dukat.DtsResolver import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask @@ -12,8 +15,8 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject plugins { kotlin("js") - id("dev.adamko.factoriowebmap.archetype.base") - id("dev.adamko.factoriowebmap.archetype.node") + id("dev.adamko.kafkatorio.base") + id("dev.adamko.kafkatorio.lang.node") } kotlin { diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts similarity index 90% rename from buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts rename to buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index 3065c31..88f15be 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -1,9 +1,12 @@ -package dev.adamko.factoriowebmap.archetype +package dev.adamko.kafkatorio.lang +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.kotlin +import org.gradle.kotlin.dsl.withType import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - id("dev.adamko.factoriowebmap.archetype.base") + id("dev.adamko.kafkatorio.base") kotlin("jvm") } diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-multiplatform.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts similarity index 67% rename from buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-multiplatform.gradle.kts rename to buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts index e110efb..28cd163 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-multiplatform.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts @@ -1,11 +1,13 @@ -package dev.adamko.factoriowebmap.archetype +package dev.adamko.kafkatorio.lang +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.kotlin import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension plugins { - id("dev.adamko.factoriowebmap.archetype.base") - id("dev.adamko.factoriowebmap.archetype.node") + id("dev.adamko.kafkatorio.base") + id("dev.adamko.kafkatorio.lang.node") kotlin("multiplatform") } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts new file mode 100644 index 0000000..6f30bb9 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts @@ -0,0 +1,87 @@ +package dev.adamko.kafkatorio.lang + +import com.github.gradle.node.NodePlugin +import dev.adamko.kafkatorio.task.UpdatePackageJson +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive +import org.gradle.kotlin.dsl.registering +import org.gradle.kotlin.dsl.support.useToRun +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin +import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlugin +import org.jetbrains.kotlin.util.suffixIfNot + +plugins { + id("com.github.node-gradle.node") + id("dev.adamko.kafkatorio.base") +} + +node { + download.set(true) + version.set("14.18.0") + + distBaseUrl.set(null as String?) // set by dependencyResolutionManagement +} + +project.plugins.withType() +project.plugins.withType() + + +val jsonMapper = Json { + prettyPrint = true + prettyPrintIndent = " " +} + + +val packageJsonFile: RegularFile = layout.projectDirectory.file("src/main/typescript/package.json") + +fun arePropertiesUpToDate(properties: () -> Map): Spec = + Spec { + val packageJsonContent = packageJsonFile.asFile.readText() + val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject + + properties().all { (key, expectedVal) -> + val actualVal = packageJson[key]?.jsonPrimitive?.content + val isUpToDate = expectedVal == actualVal + if (!isUpToDate) { + logger.lifecycle("package.json has outdated property $key=$actualVal (expected: $expectedVal)") + } + isUpToDate + } + } + +val updatePackageJson by tasks.registering(UpdatePackageJson::class) { + group = NodePlugin.NODE_GROUP + + group = project.name + description = "Read the package.json file and update the version and name, based on the project." + + propertiesToCheck["version"] = "${project.version}" + + outputs.file(packageJsonFile) + + // check to see if the properties are already up-to-date + onlyIf(arePropertiesUpToDate { propertiesToCheck }) + + doLast { + val packageJsonContent = packageJsonFile.asFile.readText() + val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject + + val newJsonProps = propertiesToCheck.mapValues { (_, newVal) -> JsonPrimitive(newVal) } + + val packageJsonUpdate = JsonObject(packageJson + newJsonProps) + val packageJsonContentUpdated = + jsonMapper + .encodeToString(packageJsonUpdate) + .suffixIfNot("\n") + + packageJsonFile.asFile.writer().useToRun { + write(packageJsonContentUpdated) + } + + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/process-runner.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/process-runner.gradle.kts similarity index 72% rename from buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/process-runner.gradle.kts rename to buildSrc/src/main/kotlin/dev/adamko/kafkatorio/process-runner.gradle.kts index c793c71..6ef0e30 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/process-runner.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/process-runner.gradle.kts @@ -1,7 +1,10 @@ -package dev.adamko.factoriowebmap.archetype +package dev.adamko.kafkatorio + +import org.gradle.kotlin.dsl.extra +import org.gradle.kotlin.dsl.registering plugins { - id("dev.adamko.factoriowebmap.archetype.base") + id("dev.adamko.kafkatorio.base") } val processRunnerTaskGroup: String by extra("processes") diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt new file mode 100644 index 0000000..e7b0ee5 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt @@ -0,0 +1,9 @@ +package dev.adamko.kafkatorio.task + +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.Input + +abstract class UpdatePackageJson : DefaultTask() { + @get:Input + val propertiesToCheck: MutableMap = mutableMapOf() +} diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 26413ae..772df6d 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -1,23 +1,15 @@ import com.github.gradle.node.npm.task.NpmTask -import dev.adamko.factoriowebmap.configurations.asConsumer -import dev.adamko.factoriowebmap.configurations.asProvider -import dev.adamko.factoriowebmap.configurations.factorioModAttributes -import dev.adamko.factoriowebmap.configurations.typescriptAttributes +import dev.adamko.kafkatorio.gradle.asConsumer +import dev.adamko.kafkatorio.gradle.asProvider +import dev.adamko.kafkatorio.gradle.factorioModAttributes +import dev.adamko.kafkatorio.gradle.typescriptAttributes import groovy.json.JsonOutput -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.JsonPrimitive -import kotlinx.serialization.json.jsonObject -import kotlinx.serialization.json.jsonPrimitive import org.apache.tools.ant.filters.ReplaceTokens -import org.gradle.kotlin.dsl.support.useToRun import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs -import org.jetbrains.kotlin.util.suffixIfNot plugins { idea - id("dev.adamko.factoriowebmap.archetype.node") + id("dev.adamko.kafkatorio.lang.node") } val tokens: Map by project.extra @@ -29,8 +21,7 @@ node { nodeProjectDir.set(tsSrcDir) } - -val dataModelTs by configurations.registering { +val typescriptEventsSchema by configurations.registering { asConsumer() typescriptAttributes(objects) defaultDependencies { @@ -38,7 +29,6 @@ val dataModelTs by configurations.registering { } } - val typescriptToLua by tasks.registering(NpmTask::class) { description = "Convert Typescript To Lua" group = project.name @@ -75,56 +65,14 @@ val typescriptToLua by tasks.registering(NpmTask::class) { } -val updatePackageJsonVersion by tasks.registering { - group = project.name - description = """ - Read the package.json file and set the version to be the project's version. - """.trimIndent() - - val projectVersion = "${project.version}" - inputs.properties( - "projectVersion" to projectVersion, - ) - - val packageJsonFile = layout.projectDirectory.file("src/main/typescript/package.json") - outputs.file(packageJsonFile) - - val jsonFormatter = Json { - prettyPrint = true - prettyPrintIndent = " " - } - - onlyIf { - // check to see if the version is already up-to-date - val packageJsonContent = packageJsonFile.asFile.readText() - val packageJson = jsonFormatter.parseToJsonElement(packageJsonContent).jsonObject - packageJson["version"]?.jsonPrimitive?.content != projectVersion - } - - doLast { - val packageJsonContent = packageJsonFile.asFile.readText() - val packageJson = jsonFormatter.parseToJsonElement(packageJsonContent).jsonObject - val packageJsonUpdate = JsonObject( - packageJson + ("version" to JsonPrimitive(projectVersion)) - ) - val packageJsonContentUpdated = - jsonFormatter - .encodeToString(packageJsonUpdate) - .suffixIfNot("\n") - packageJsonFile.asFile.writer().useToRun { - write(packageJsonContentUpdated) - } - } -} - -val updateDataModel by tasks.registering(Sync::class) { +val fetchEventsSchema by tasks.registering(Sync::class) { group = project.name description = "Fetch the latest shared data-model" - dependsOn(dataModelTs) + dependsOn(typescriptEventsSchema) from( - dataModelTs.map { c -> + typescriptEventsSchema.map { c -> c.incoming .artifactView { lenient(true) } .artifacts @@ -136,7 +84,6 @@ val updateDataModel by tasks.registering(Sync::class) { into(layout.projectDirectory.dir("src/main/typescript/model")) } - val packageMod by tasks.registering(Zip::class) { description = "Package mod files into ZIP" group = project.name @@ -204,8 +151,11 @@ val factorioModProvider by configurations.registering { outgoing.artifact(packageMod) } +tasks.updatePackageJson { + propertiesToCheck["name"] = "${rootProject.name}-${project.name}" +} -tasks.assemble { dependsOn(updateDataModel, updatePackageJsonVersion) } +tasks.assemble { dependsOn(fetchEventsSchema, tasks.updatePackageJson) } tasks.build { dependsOn(packageMod) } diff --git a/modules/events-mod/src/main/typescript/events.ts b/modules/events-mod/src/main/typescript/events.ts index e63cf1f..0fb6924 100644 --- a/modules/events-mod/src/main/typescript/events.ts +++ b/modules/events-mod/src/main/typescript/events.ts @@ -1,13 +1,4 @@ -// import {Data, Mods} from "typed-factorio/settings/types" -// import { events } from "typed-factorio/generated" - -// declare const factorioData: Data -// declare const factorioMods: Mods - - import {Serdes} from "./serdes/serdes" -// import {FactorioEvent, JsonTable} from "./model/model"; - const MOD_VERSION = script.active_mods["factorio-web-map"] diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 4bc733a..f0ebee7 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,5 +1,5 @@ { - "name": "factorio-web-map-mod", + "name": "kafkatorio-events", "version": "0.0.7", "private": true, "scripts": { diff --git a/modules/events-mod/src/main/typescript/model/data-model.ts b/modules/events-mod/src/main/typescript/schema/kafkatorio-events.ts similarity index 100% rename from modules/events-mod/src/main/typescript/model/data-model.ts rename to modules/events-mod/src/main/typescript/schema/kafkatorio-events.ts diff --git a/modules/events-processor/build.gradle.kts b/modules/events-processor/build.gradle.kts index 9b30683..2066d02 100644 --- a/modules/events-processor/build.gradle.kts +++ b/modules/events-processor/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") + id("dev.adamko.kafkatorio.lang.kotlin-jvm") kotlin("plugin.serialization") application } diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventLogConsumer.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventLogConsumer.kt similarity index 66% rename from modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventLogConsumer.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventLogConsumer.kt index 091f084..5ced240 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventLogConsumer.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventLogConsumer.kt @@ -1,4 +1,4 @@ -package dev.adamko.factorioevents.processor +package dev.adamko.kafkatorio.processor /** * Process the raw messages from a server. diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventsTopology.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt similarity index 87% rename from modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventsTopology.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt index 83924d9..4bd53cb 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/FactorioEventsTopology.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt @@ -1,4 +1,4 @@ -package dev.adamko.factorioevents.processor +package dev.adamko.kafkatorio.processor import java.util.Properties import org.apache.kafka.streams.KafkaStreams diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt similarity index 91% rename from modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt index 107e6e5..78009c3 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/StreamsExceptionHandler.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt @@ -1,4 +1,4 @@ -package dev.adamko.factorioevents.processor +package dev.adamko.kafkatorio.processor import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler.StreamThreadExceptionResponse diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt similarity index 92% rename from modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt index 51c5ed6..c3fe7ec 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/ApplicationProperties.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt @@ -1,7 +1,7 @@ -package dev.adamko.factorioevents.processor.config +package dev.adamko.kafkatorio.processor.config import com.fasterxml.jackson.databind.JsonNode -import dev.adamko.factorioevents.processor.config.PortVal.Companion.portVal +import dev.adamko.kafkatorio.processor.config.PortVal.Companion.portVal import java.io.StringReader import java.time.Clock import java.util.Properties diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/Lenses.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt similarity index 95% rename from modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/Lenses.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt index 26e5109..fec46a8 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/Lenses.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt @@ -1,4 +1,4 @@ -package dev.adamko.factorioevents.processor.config +package dev.adamko.kafkatorio.processor.config import java.io.File import org.http4k.cloudnative.env.Environment diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/PortVal.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt similarity index 92% rename from modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/PortVal.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt index 498dc77..de0f49a 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/PortVal.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt @@ -1,4 +1,4 @@ -package dev.adamko.factorioevents.processor.config +package dev.adamko.kafkatorio.processor.config import org.http4k.cloudnative.env.Port import org.http4k.lens.BiDiLensSpec diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/environmentExt.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt similarity index 97% rename from modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/environmentExt.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt index d0a837f..58d592e 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/config/environmentExt.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt @@ -1,4 +1,4 @@ -package dev.adamko.factorioevents.processor.config +package dev.adamko.kafkatorio.processor.config import java.io.File import java.io.FileNotFoundException diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt similarity index 85% rename from modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt rename to modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt index 23bbdde..ecc2789 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/factorioevents/processor/main.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt @@ -1,8 +1,8 @@ -package dev.adamko.factorioevents.processor +package dev.adamko.kafkatorio.processor -import dev.adamko.factorioevents.model.FactorioEvent -import dev.adamko.factorioevents.model.jsonMapper -import dev.adamko.factorioevents.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.jsonMapper +import dev.adamko.kafkatorio.processor.config.ApplicationProperties import java.time.Duration import org.apache.kafka.common.serialization.Serdes import org.apache.kafka.streams.KafkaStreams diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index c2a9332..0b83b2a 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -1,8 +1,8 @@ -import dev.adamko.factoriowebmap.configurations.asProvider -import dev.adamko.factoriowebmap.configurations.typescriptAttributes +import dev.adamko.kafkatorio.gradle.asProvider +import dev.adamko.kafkatorio.gradle.typescriptAttributes plugins { - id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") + id("dev.adamko.kafkatorio.lang.kotlin-jvm") kotlin("plugin.serialization") } diff --git a/modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt b/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/builtinTypes.kt similarity index 98% rename from modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt rename to modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/builtinTypes.kt index 162eed3..a4d3b7a 100644 --- a/modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/builtinTypes.kt +++ b/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/builtinTypes.kt @@ -1,6 +1,6 @@ @file:Suppress("ClassName") -package dev.adamko.factorioevents.model +package dev.adamko.kafkatorio.events.schema import kotlinx.serialization.Serializable diff --git a/modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt b/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt similarity index 98% rename from modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt rename to modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index 0d30420..b95e171 100644 --- a/modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/factorioEvents.kt +++ b/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -1,4 +1,4 @@ -package dev.adamko.factorioevents.model +package dev.adamko.kafkatorio.events.schema import kotlinx.serialization.SerialName diff --git a/modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/json.kt b/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/json.kt similarity index 96% rename from modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/json.kt rename to modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/json.kt index 8e98573..3723e74 100644 --- a/modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/json.kt +++ b/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/json.kt @@ -1,4 +1,4 @@ -package dev.adamko.factorioevents.model +package dev.adamko.kafkatorio.events.schema import kotlinx.serialization.KSerializer import kotlinx.serialization.builtins.ListSerializer diff --git a/modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt b/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt similarity index 97% rename from modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt rename to modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt index e6fe4e9..c650bf6 100644 --- a/modules/events-schema/src/main/kotlin/dev/adamko/factorioevents/model/kt2ts.kt +++ b/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt @@ -1,4 +1,4 @@ -package dev.adamko.factorioevents.model +package dev.adamko.kafkatorio.events.schema import java.io.File import kotlin.reflect.KClass diff --git a/modules/events-schema/src/test/kotlin/dev/adamko/factorioevents/model/FactorioEventTest.kt b/modules/events-schema/src/test/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt similarity index 89% rename from modules/events-schema/src/test/kotlin/dev/adamko/factorioevents/model/FactorioEventTest.kt rename to modules/events-schema/src/test/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt index 0f7386d..e41fb27 100644 --- a/modules/events-schema/src/test/kotlin/dev/adamko/factorioevents/model/FactorioEventTest.kt +++ b/modules/events-schema/src/test/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt @@ -1,5 +1,12 @@ -package dev.adamko.factorioevents.model +package dev.adamko.kafkatorio.events.schema +import dev.adamko.kafkatorio.events.schema.EntityData +import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.FactorioObjectData +import dev.adamko.kafkatorio.events.schema.PlayerData +import dev.adamko.kafkatorio.events.schema.PositionData +import dev.adamko.kafkatorio.events.schema.SurfaceData +import dev.adamko.kafkatorio.events.schema.jsonMapper import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.equality.shouldBeEqualToComparingFields import kotlinx.serialization.decodeFromString diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index a4415f5..011b29a 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -1,11 +1,11 @@ -import dev.adamko.factoriowebmap.configurations.asConsumer -import dev.adamko.factoriowebmap.configurations.factorioModAttributes +import dev.adamko.kafkatorio.gradle.asConsumer +import dev.adamko.kafkatorio.gradle.factorioModAttributes import dev.adamko.isProcessRunning import dev.adamko.not import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { - id("dev.adamko.factoriowebmap.archetype.process-runner") + id("dev.adamko.kafkatorio.process-runner") } val tokens: Map by project.extra @@ -78,4 +78,3 @@ tasks.processRun { tasks.processKill { dependsOn(clientKill) } - diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 9489d07..c41e6c9 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -1,9 +1,9 @@ -import dev.adamko.factoriowebmap.configurations.asConsumer -import dev.adamko.factoriowebmap.configurations.factorioModAttributes +import dev.adamko.kafkatorio.gradle.asConsumer +import dev.adamko.kafkatorio.gradle.factorioModAttributes import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { - id("dev.adamko.factoriowebmap.archetype.process-runner") + id("dev.adamko.kafkatorio.process-runner") } val tokens: Map by project.extra diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index 2744f98..96ba268 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("dev.adamko.factoriowebmap.archetype.process-runner") + id("dev.adamko.kafkatorio.process-runner") } description = "Send events from a Factorio server to a Kafka topic " diff --git a/modules/kt-rcon/build.gradle.kts b/modules/kt-rcon/build.gradle.kts index 6d1d75e..236d9f6 100644 --- a/modules/kt-rcon/build.gradle.kts +++ b/modules/kt-rcon/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") + id("dev.adamko.kafkatorio.lang.kotlin-jvm") } //group = "${rootProject.group}.server" diff --git a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/main.kt b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/main.kt index 946446c..5486877 100644 --- a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/main.kt +++ b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/main.kt @@ -1,25 +1,22 @@ package dev.adamko.ktrcon -import kotlin.time.Duration +import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking fun main(): Unit = runBlocking { KtRconClient3( - "localhost", - 27715, - Password("coh9oongoojahX4") + "localhost", + 27715, + Password("coh9oongoojahX4") ).use { client -> - // client.send(PacketType.AUTH_REQUEST, "passwrd") client.send(PacketType.AUTH_REQUEST, "coh9oongoojahX4") - delay(Duration.seconds(10)) + delay(10.seconds) client.send(PacketType.EXEC_COMMAND, "/help") - - delay(Duration.seconds(10)) - + delay(10.seconds) } } From afbfeda61621a4c45385e76e86f920049c9dd8ec Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 1 Dec 2021 18:31:18 +0100 Subject: [PATCH 085/629] tidying up after refactor, fix update-package-json task, try to fix factorio-client launcher --- .../adamko/kafkatorio/gradle/extensions.kt | 2 +- .../adamko/kafkatorio/lang/node.gradle.kts | 41 +++++++++---------- .../kafkatorio/task/UpdatePackageJson.kt | 4 ++ modules/events-mod/build.gradle.kts | 1 + .../src/main/typescript/package.json | 14 ++++--- .../infra-factorio-client/build.gradle.kts | 6 +-- modules/infra-kafka-pipe/{src => }/readme.md | 0 7 files changed, 37 insertions(+), 31 deletions(-) rename modules/infra-kafka-pipe/{src => }/readme.md (100%) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt index 0b00148..6b9b74b 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt @@ -1,4 +1,4 @@ -package dev.adamko +package dev.adamko.kafkatorio.gradle import java.io.ByteArrayOutputStream import org.gradle.api.Project diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts index 6f30bb9..9aa0c8f 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts @@ -2,19 +2,19 @@ package dev.adamko.kafkatorio.lang import com.github.gradle.node.NodePlugin import dev.adamko.kafkatorio.task.UpdatePackageJson +import dev.adamko.kafkatorio.gradle.not import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive -import org.gradle.kotlin.dsl.registering import org.gradle.kotlin.dsl.support.useToRun -import org.gradle.kotlin.dsl.withType import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlugin import org.jetbrains.kotlin.util.suffixIfNot + plugins { id("com.github.node-gradle.node") id("dev.adamko.kafkatorio.base") @@ -37,38 +37,33 @@ val jsonMapper = Json { } -val packageJsonFile: RegularFile = layout.projectDirectory.file("src/main/typescript/package.json") +fun arePropertiesUpToDate( + packageJsonFile: RegularFileProperty, + properties: () -> Map +): Spec = Spec { + val packageJsonContent = packageJsonFile.get().asFile.readText() + val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject -fun arePropertiesUpToDate(properties: () -> Map): Spec = - Spec { - val packageJsonContent = packageJsonFile.asFile.readText() - val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject - - properties().all { (key, expectedVal) -> - val actualVal = packageJson[key]?.jsonPrimitive?.content - val isUpToDate = expectedVal == actualVal - if (!isUpToDate) { - logger.lifecycle("package.json has outdated property $key=$actualVal (expected: $expectedVal)") - } - isUpToDate + properties().all { (key, expectedVal) -> + val actualVal = packageJson[key]?.jsonPrimitive?.content + (expectedVal == actualVal).also { + if (!it) + logger.lifecycle("package.json has outdated property '$key' (expected: $expectedVal, actual: $actualVal)") } } +} val updatePackageJson by tasks.registering(UpdatePackageJson::class) { group = NodePlugin.NODE_GROUP - - group = project.name description = "Read the package.json file and update the version and name, based on the project." propertiesToCheck["version"] = "${project.version}" - outputs.file(packageJsonFile) - // check to see if the properties are already up-to-date - onlyIf(arePropertiesUpToDate { propertiesToCheck }) + onlyIf(!arePropertiesUpToDate(packageJsonFile) { propertiesToCheck }) doLast { - val packageJsonContent = packageJsonFile.asFile.readText() + val packageJsonContent = packageJsonFile.get().asFile.readText() val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject val newJsonProps = propertiesToCheck.mapValues { (_, newVal) -> JsonPrimitive(newVal) } @@ -79,7 +74,9 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) { .encodeToString(packageJsonUpdate) .suffixIfNot("\n") - packageJsonFile.asFile.writer().useToRun { + logger.lifecycle(packageJsonContentUpdated) + + packageJsonFile.get().asFile.writer().useToRun { write(packageJsonContentUpdated) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt index e7b0ee5..2dc7b99 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt @@ -1,9 +1,13 @@ package dev.adamko.kafkatorio.task import org.gradle.api.DefaultTask +import org.gradle.api.file.RegularFileProperty import org.gradle.api.tasks.Input +import org.gradle.api.tasks.OutputFile abstract class UpdatePackageJson : DefaultTask() { @get:Input val propertiesToCheck: MutableMap = mutableMapOf() + @get:OutputFile + abstract val packageJsonFile: RegularFileProperty } diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 772df6d..8345a75 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -153,6 +153,7 @@ val factorioModProvider by configurations.registering { tasks.updatePackageJson { propertiesToCheck["name"] = "${rootProject.name}-${project.name}" + packageJsonFile.set(layout.projectDirectory.file("src/main/typescript/package.json")) } tasks.assemble { dependsOn(fetchEventsSchema, tasks.updatePackageJson) } diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index f0ebee7..727b80d 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,5 +1,5 @@ { - "name": "kafkatorio-events", + "name": "kafkatorio-events-mod", "version": "0.0.7", "private": true, "scripts": { @@ -9,7 +9,8 @@ "engines": { "node": ">=10.13.0" }, - "devDependencies": {}, + "devDependencies": { + }, "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", @@ -20,7 +21,10 @@ "//": { "typed-factorio": "0.10.0" }, - "peerDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": [] + "peerDependencies": { + }, + "optionalDependencies": { + }, + "bundledDependencies": [ + ] } diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index 011b29a..13bb477 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -1,7 +1,7 @@ import dev.adamko.kafkatorio.gradle.asConsumer import dev.adamko.kafkatorio.gradle.factorioModAttributes -import dev.adamko.isProcessRunning -import dev.adamko.not +import dev.adamko.kafkatorio.gradle.isProcessRunning +import dev.adamko.kafkatorio.gradle.not import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { @@ -52,7 +52,7 @@ val clientLaunch by tasks.registering(Exec::class) { commandLine = parseSpaceSeparatedArgs( // """explorer "steam://rungameid/$factorioGameId// --mp-connect localhost/" """ // not working // """explorer "steam://run/$factorioGameId//--mp-connect localhost/" """ // works! But has annoying pop-up - """ $steamExe -applaunch $factorioGameId --mp-connect localhost """ + """ $steamExe -applaunch $factorioGameId --mp-connect localhost --mod-directory $clientModsDirectory """ ) doFirst { logger.lifecycle("Launching factorio.exe") } } diff --git a/modules/infra-kafka-pipe/src/readme.md b/modules/infra-kafka-pipe/readme.md similarity index 100% rename from modules/infra-kafka-pipe/src/readme.md rename to modules/infra-kafka-pipe/readme.md From 7091f7648dfc823dec0bc331b79bb68ba270bf14 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Thu, 2 Dec 2021 00:54:15 +0100 Subject: [PATCH 086/629] - more tidying up - setting up distribution plugin - using more variables for mod config --- build.gradle.kts | 25 ++-- buildSrc/build.gradle.kts | 3 +- .../dev/adamko/kafkatorio/base.gradle.kts | 15 +- .../infra/docker-compose.gradle.kts | 41 +++++ .../{ => infra}/process-runner.gradle.kts | 10 +- .../kafkatorio/lang/kotlin-jvm.gradle.kts | 1 - gradle/libs.versions.toml | 2 + modules/events-mod/build.gradle.kts | 141 ++++++++++++------ .../src/main/resources/mod-data/changelog.txt | 2 +- .../src/main/resources/mod-data/info.json | 7 +- .../events-mod/src/main/typescript/events.ts | 10 +- .../src/main/typescript/package-lock.json | 2 +- .../src/main/typescript/package.json | 12 +- ...{kafkatorio-events.ts => events-schema.ts} | 2 +- .../dev/adamko/kafkatorio/processor/main.kt | 3 +- modules/events-schema/build.gradle.kts | 31 ++-- .../events/schema/factorioEvents.kt | 2 +- .../infra-factorio-client/build.gradle.kts | 4 +- .../infra-factorio-server/build.gradle.kts | 91 ++++++----- modules/infra-factorio-server/infra/.env | 1 - modules/infra-factorio-server/src/.env | 3 + .../{infra => src}/.gitignore | 0 .../{infra => src}/docker-compose.yml | 10 +- .../{infra => src}/factorioEvents.Dockerfile | 8 +- .../{infra => src}/kafka-pipe.sh | 0 .../{infra => src}/kcat.conf | 0 modules/infra-kafka-cluster/build.gradle.kts | 5 + modules/infra-kafka-cluster/src/.env | 2 + .../{ => src}/docker-compose.yml | 11 +- .../{ => src}/kafka-server.properties | 0 .../{ => src}/kafka.Dockerfile | 0 modules/infra-kafka-pipe/build.gradle.kts | 5 +- modules/infra-kafka-pipe/src/.env | 3 +- .../infra-kafka-pipe/src/docker-compose.yml | 10 +- 34 files changed, 293 insertions(+), 169 deletions(-) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts rename buildSrc/src/main/kotlin/dev/adamko/kafkatorio/{ => infra}/process-runner.gradle.kts (59%) rename modules/events-mod/src/main/typescript/schema/{kafkatorio-events.ts => events-schema.ts} (99%) delete mode 100644 modules/infra-factorio-server/infra/.env create mode 100644 modules/infra-factorio-server/src/.env rename modules/infra-factorio-server/{infra => src}/.gitignore (100%) rename modules/infra-factorio-server/{infra => src}/docker-compose.yml (83%) rename modules/infra-factorio-server/{infra => src}/factorioEvents.Dockerfile (62%) rename modules/infra-factorio-server/{infra => src}/kafka-pipe.sh (100%) rename modules/infra-factorio-server/{infra => src}/kcat.conf (100%) create mode 100644 modules/infra-kafka-cluster/build.gradle.kts create mode 100644 modules/infra-kafka-cluster/src/.env rename modules/infra-kafka-cluster/{ => src}/docker-compose.yml (85%) rename modules/infra-kafka-cluster/{ => src}/kafka-server.properties (100%) rename modules/infra-kafka-cluster/{ => src}/kafka.Dockerfile (100%) diff --git a/build.gradle.kts b/build.gradle.kts index bfca669..b2e9d6e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ plugins { `build-dashboard` } -group = "dev.adamko.factoriowebmap" +group = "dev.adamko" version = "0.0.7" tasks.wrapper { @@ -13,13 +13,20 @@ tasks.wrapper { distributionType = Wrapper.DistributionType.ALL } -idea { - module { - isDownloadSources = true - isDownloadJavadoc = true - } +val startInfra by tasks.registering { + group = project.name + + dependsOn( + ":modules:infra-kafka-pipe:processRun", + ":modules:infra-kafka-cluster:processRun", + ) } -//tasks.withType(HtmlDependencyReportTask::class).configureEach { -// projects = project.allprojects -//} +val runKafkatorio by tasks.registering { + group = project.name + + dependsOn( + ":modules:infra-factorio-client:processRun", + ":modules:infra-factorio-server:processRun", + ) +} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index b11311b..1b93bce 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -13,7 +13,7 @@ dependencies { implementation(enforcedPlatform("org.jetbrains.kotlin:kotlin-bom:$kotlinVersion")) implementation("org.jetbrains.kotlin:kotlin-serialization") implementation("org.jetbrains.kotlin:kotlin-reflect") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") val kotlinXSerializationVersion = "1.3.1" implementation(enforcedPlatform("org.jetbrains.kotlinx:kotlinx-serialization-bom:$kotlinXSerializationVersion")) @@ -35,7 +35,6 @@ tasks.withType().configureEach { } kotlinOptions.freeCompilerArgs += listOf( - "-Xopt-in=kotlin.OptIn", "-Xopt-in=kotlin.RequiresOptIn", "-Xopt-in=kotlin.ExperimentalStdlibApi", "-Xopt-in=kotlin.time.ExperimentalTime", diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts index cb48dee..a23eaa1 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts @@ -1,9 +1,5 @@ package dev.adamko.kafkatorio -import org.gradle.kotlin.dsl.base -import org.gradle.kotlin.dsl.extra -import org.gradle.kotlin.dsl.idea - plugins { idea base @@ -14,8 +10,8 @@ version = rootProject.version val licenseFile: RegularFile by extra(rootProject.layout.projectDirectory.file("LICENSE")) -val tokens: Map by extra( - mapOf( +val tokens: MutableMap by extra( + mutableMapOf( "project.version" to "$version", ) ) @@ -27,6 +23,7 @@ idea { } } -//group = "dev.adamko.factoriowebmap" -//version = "0.0.1" - +tasks.withType().configureEach { + encoding = Charsets.UTF_8.name() + comment = " Do not edit manually. This file was created with task '$name'" +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts new file mode 100644 index 0000000..770e0a4 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts @@ -0,0 +1,41 @@ +package dev.adamko.kafkatorio.infra + +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + +plugins { + id("dev.adamko.kafkatorio.infra.process-runner") +} + +val dockerComposeTaskGroup : String by extra("docker-compose") + +val composeProjectName: String by extra(rootProject.name) +val srcDir: Directory by extra(layout.projectDirectory.dir("src")) + + +val dockerUp by tasks.creating(Exec::class) { + group = dockerComposeTaskGroup + workingDir = srcDir.asFile + commandLine = parseSpaceSeparatedArgs(""" docker-compose up -d """) +} + +val dockerDown by tasks.creating(Exec::class) { + group = dockerComposeTaskGroup + workingDir = srcDir.asFile + commandLine = parseSpaceSeparatedArgs(""" docker-compose down """) +} + +afterEvaluate { + tasks.named("processRun") { dependsOn(dockerUp, updateEnv) } + tasks.named("processKill") { dependsOn(dockerDown) } +} + +val updateEnv by tasks.registering(WriteProperties::class) { + group = dockerComposeTaskGroup + + setOutputFile(srcDir.file(".env")) + properties( + "COMPOSE_PROJECT_NAME" to composeProjectName, + ) +} + +tasks.assemble { dependsOn(updateEnv) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/process-runner.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/process-runner.gradle.kts similarity index 59% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/process-runner.gradle.kts rename to buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/process-runner.gradle.kts index 6ef0e30..25d5231 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/process-runner.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/process-runner.gradle.kts @@ -1,7 +1,4 @@ -package dev.adamko.kafkatorio - -import org.gradle.kotlin.dsl.extra -import org.gradle.kotlin.dsl.registering +package dev.adamko.kafkatorio.infra plugins { id("dev.adamko.kafkatorio.base") @@ -9,18 +6,17 @@ plugins { val processRunnerTaskGroup: String by extra("processes") -val processRun by tasks.registering { +val processRun by tasks.registering(Task::class) { group = processRunnerTaskGroup } -val processKill by tasks.registering { +val processKill by tasks.registering(Task::class) { group = processRunnerTaskGroup } val processRestart by tasks.registering { group = processRunnerTaskGroup - processKill.get().state dependsOn(processKill) finalizedBy(processRun) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index 88f15be..12e2c81 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -55,7 +55,6 @@ tasks.withType().configureEach { } kotlinOptions.freeCompilerArgs += listOf( - "-Xopt-in=kotlin.OptIn", "-Xopt-in=kotlin.RequiresOptIn", "-Xopt-in=kotlin.ExperimentalStdlibApi", "-Xopt-in=kotlin.time.ExperimentalTime", diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4a19812..439b18d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,6 +20,8 @@ kotlinx-serialization = "1.3.1" junit = "5.8.1" kotest = "4.6.3" +## infra ## +factorio = "1.1.48" ######### [plugins] diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 8345a75..01acad9 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -10,23 +10,42 @@ import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { idea id("dev.adamko.kafkatorio.lang.node") + distribution } -val tokens: Map by project.extra -val licenseFile: RegularFile by project.extra +description = + "Sends in-game information to a server over the internet (requires Kafkatorio Kafka-Pipe)" + +// Factorio required format is: +// - filename: `mod-name_version.zip` +// - zip contains one directory, `mod-name` +val modName: String by extra("${rootProject.name}-events") +val distributionZipName: String by extra("${modName}_${project.version}.zip") + + +val tokens: MutableMap by project.extra +tokens += mapOf( + "mod.name" to modName, + "mod.title" to "Kafkatorio Events", + "mod.description" to (project.description ?: ""), + "factorio.version" to libs.versions.factorio.get().substringBeforeLast("."), +) + +val licenseFile: RegularFile by project.extra val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") node { nodeProjectDir.set(tsSrcDir) } -val typescriptEventsSchema by configurations.registering { +val typescriptEventsSchema: Configuration by configurations.creating { asConsumer() typescriptAttributes(objects) - defaultDependencies { - project.dependencies.create(projects.modules.eventsSchema) - } +} + +dependencies { + typescriptEventsSchema(projects.modules.eventsSchema) } val typescriptToLua by tasks.registering(NpmTask::class) { @@ -39,13 +58,12 @@ val typescriptToLua by tasks.registering(NpmTask::class) { npmCommand.set(listOf("run", "build")) - inputs.dir(project.node.nodeProjectDir) + inputs.dir(tsSrcDir) .skipWhenEmpty() .withPropertyName("sourceFiles") .withPathSensitivity(PathSensitivity.RELATIVE) - val intermediateOutputDir = temporaryDir - args.set(parseSpaceSeparatedArgs("-- --outDir $intermediateOutputDir")) + args.set(parseSpaceSeparatedArgs("-- --outDir $temporaryDir")) val outputDir = layout.buildDirectory.dir("typescriptToLua") outputs.dir(outputDir) .withPropertyName("outputDir") @@ -53,12 +71,13 @@ val typescriptToLua by tasks.registering(NpmTask::class) { ignoreExitValue.set(false) doFirst("clean") { - delete(intermediateOutputDir) + delete(temporaryDir) + mkdir(temporaryDir) } doLast("syncTstlOutput") { sync { - from(intermediateOutputDir) + from(temporaryDir) into(outputDir) } } @@ -66,54 +85,86 @@ val typescriptToLua by tasks.registering(NpmTask::class) { } val fetchEventsSchema by tasks.registering(Sync::class) { - group = project.name description = "Fetch the latest shared data-model" + group = project.name dependsOn(typescriptEventsSchema) from( - typescriptEventsSchema.map { c -> - c.incoming - .artifactView { lenient(true) } - .artifacts - .artifactFiles - .filter { file -> file.exists() } + typescriptEventsSchema.incoming + .artifactView { lenient(true) } + .artifacts + .artifactFiles + .filter { file -> file.exists() } + .files + .map { zipTree(it) } + ) { + // drop the first directory inside the zip + eachFile { + relativePath = RelativePath(true, *relativePath.segments.drop(1).toTypedArray()) } - ) + includeEmptyDirs = false + } - into(layout.projectDirectory.dir("src/main/typescript/model")) + into(layout.projectDirectory.dir("src/main/typescript/schema")) } -val packageMod by tasks.registering(Zip::class) { - description = "Package mod files into ZIP" - group = project.name +tasks.distZip { + archiveFileName.set(distributionZipName) +} - dependsOn(typescriptToLua) +distributions { + main { - inputs.properties(tokens) + distributionBaseName.set(modName) - from(layout.projectDirectory.dir("src/main/resources/mod-data")) { - include("**/**") - filter("tokens" to tokens) - } - dependsOn(typescriptToLua) - from(licenseFile) + contents { + from(layout.projectDirectory.dir("src/main/resources/mod-data")) { + include("**/**") + filter("tokens" to tokens) + } + from(licenseFile) + from(typescriptToLua.map { it.outputs }) + includeEmptyDirs = false + exclude { + it.file.run { + isFile && useLines { lines -> lines.all { line -> line.isBlank() } } + } + } + } - into(rootProject.name) - - // Factorio required format is: - // - filename: `mod-name_version.zip` - // - zip contains one directory, `mod-name` - archiveFileName.set("${rootProject.name}_${project.version}.zip") - destinationDirectory.set(layout.buildDirectory.dir("dist")) - - doLast { - val outDir = destinationDirectory.asFile.get().toRelativeString(layout.projectDirectory.asFile) - val outZip = "${archiveFileName.orNull}" - logger.lifecycle("Packaged mod into $outDir/$outZip") } } +//val packageMod by tasks.registering(Zip::class) { +// description = "Package mod files into ZIP" +// group = project.name +// +// dependsOn(typescriptToLua) +// +// inputs.properties(tokens) +// +// from(layout.projectDirectory.dir("src/main/resources/mod-data")) { +// include("**/**") +// filter("tokens" to tokens) +// } +// from(licenseFile) +// +// into(rootProject.name) +// +// // Factorio required format is: +// // - filename: `mod-name_version.zip` +// // - zip contains one directory, `mod-name` +// archiveFileName.set("${rootProject.name}_${project.version}.zip") +// destinationDirectory.set(layout.buildDirectory.dir("dist")) +// +// doLast { +// val outDir = destinationDirectory.asFile.get().toRelativeString(layout.projectDirectory.asFile) +// val outZip = "${archiveFileName.orNull}" +// logger.lifecycle("Packaged mod into $outDir/$outZip") +// } +//} + val downloadFactorioApiDocs by tasks.registering { group = project.name @@ -148,7 +199,7 @@ val downloadFactorioApiDocs by tasks.registering { val factorioModProvider by configurations.registering { asProvider() factorioModAttributes(objects) - outgoing.artifact(packageMod) + outgoing.artifact(tasks.distZip.flatMap { it.archiveFile }) } tasks.updatePackageJson { @@ -157,7 +208,7 @@ tasks.updatePackageJson { } tasks.assemble { dependsOn(fetchEventsSchema, tasks.updatePackageJson) } -tasks.build { dependsOn(packageMod) } +//tasks.build { dependsOn(packageMod) } // diff --git a/modules/events-mod/src/main/resources/mod-data/changelog.txt b/modules/events-mod/src/main/resources/mod-data/changelog.txt index 956eb6b..ae5a975 100644 --- a/modules/events-mod/src/main/resources/mod-data/changelog.txt +++ b/modules/events-mod/src/main/resources/mod-data/changelog.txt @@ -1,4 +1,4 @@ --------------------------------------------------------------------------------------------------- Version: 0.0.1 Features: - - Factorio Web Map + - Kafkatorio diff --git a/modules/events-mod/src/main/resources/mod-data/info.json b/modules/events-mod/src/main/resources/mod-data/info.json index 538c892..b9244ca 100644 --- a/modules/events-mod/src/main/resources/mod-data/info.json +++ b/modules/events-mod/src/main/resources/mod-data/info.json @@ -1,8 +1,9 @@ { - "name": "factorio-web-map", + "name": "@mod.name@", "version": "@project.version@", - "title": "Factorio Web Map", + "title": "@mod.title@", + "description": "@mod.description@", "author": "fredthedeadhead", - "factorio_version": "1.1", + "factorio_version": "@factorio.version@", "dependencies": [] } diff --git a/modules/events-mod/src/main/typescript/events.ts b/modules/events-mod/src/main/typescript/events.ts index 0fb6924..68835c5 100644 --- a/modules/events-mod/src/main/typescript/events.ts +++ b/modules/events-mod/src/main/typescript/events.ts @@ -90,9 +90,13 @@ script.on_event( (e: OnTickEvent) => { if (e.tick % 60 == 0) { - for (const [index,] of pairs(game.surfaces)) { - let surface = game.surfaces[index] - surfaceEvent(e.tick, surface, mapEventIdToName.get(e.name)) + + for (const [index, _] of pairs(game.surfaces)) { + let s = game.get_surface(index) // TODO fix / report can't iterate over surfaces + // let surface = game.surfaces[index] + if (s != undefined) { + surfaceEvent(e.tick, s, mapEventIdToName.get(e.name)) + } // surfaceEvent(e.tick, surface, "on_tick") } diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index ab7b085..58d0c36 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,5 +1,5 @@ { - "name": "factorio-web-map-mod", + "name": "kafkatorio-events-mod", "version": "0.0.7", "lockfileVersion": 1, "requires": true, diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 727b80d..19e4815 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -9,8 +9,7 @@ "engines": { "node": ">=10.13.0" }, - "devDependencies": { - }, + "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", @@ -21,10 +20,7 @@ "//": { "typed-factorio": "0.10.0" }, - "peerDependencies": { - }, - "optionalDependencies": { - }, - "bundledDependencies": [ - ] + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] } diff --git a/modules/events-mod/src/main/typescript/schema/kafkatorio-events.ts b/modules/events-mod/src/main/typescript/schema/events-schema.ts similarity index 99% rename from modules/events-mod/src/main/typescript/schema/kafkatorio-events.ts rename to modules/events-mod/src/main/typescript/schema/events-schema.ts index 15f67d9..8950029 100644 --- a/modules/events-mod/src/main/typescript/schema/kafkatorio-events.ts +++ b/modules/events-mod/src/main/typescript/schema/events-schema.ts @@ -43,4 +43,4 @@ interface SurfaceData extends FactorioObjectData { index: uint; name: string; object_name: string; -} +} \ No newline at end of file diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt index ecc2789..ffb938d 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt @@ -1,6 +1,7 @@ package dev.adamko.kafkatorio.processor import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.FactorioObjectData import dev.adamko.kafkatorio.events.schema.jsonMapper import dev.adamko.kafkatorio.processor.config.ApplicationProperties import java.time.Duration @@ -25,7 +26,7 @@ fun main() { .mapValues { readOnlyKey, value -> println("Mapping $readOnlyKey:$value") // jsonMapper.decodeFromString>(value) - KotlinxSerialization.asA>(value) + KotlinxSerialization.asA>(value) } .to(TopicNameExtractor { key, value, recordContext -> value.data.objectName diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index 0b83b2a..001e817 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -4,6 +4,7 @@ import dev.adamko.kafkatorio.gradle.typescriptAttributes plugins { id("dev.adamko.kafkatorio.lang.kotlin-jvm") kotlin("plugin.serialization") + distribution } dependencies { @@ -18,26 +19,36 @@ dependencies { val generateTypescript by tasks.registering(JavaExec::class) { group = project.name - val generatedFileName = "$temporaryDir/data-model.ts" - inputs.property("generatedFileName", generatedFileName) - outputs.file(generatedFileName) + val generatedFile = file("$temporaryDir/${project.name}.ts") classpath(sourceSets.main.map { it.runtimeClasspath }) - mainClass.set("dev.adamko.factorioevents.model.Kt2tsKt") - args(generatedFileName) + mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2tsKt") + args(generatedFile) + + val buildOutput = layout.buildDirectory.dir("generated/typescript") + outputs.dir(buildOutput) doFirst { delete(temporaryDir) mkdir(temporaryDir) } + + doLast { + sync { from(temporaryDir); into(buildOutput) } + } +} + +distributions { + main { + distributionBaseName.set("${rootProject.name}-${project.name}") + contents { + from(generateTypescript.map { it.outputs.files.asFileTree }) + } + } } val typescriptModelGenerated by configurations.registering { asProvider() typescriptAttributes(objects) - outgoing.artifact( - generateTypescript.map { - it.outputs.files.singleFile - } - ) + outgoing.artifact(tasks.distZip.flatMap { it.archiveFile }) } diff --git a/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index b95e171..38fa09e 100644 --- a/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -29,7 +29,7 @@ const val FactorioObjectDataDiscriminatorKey: String = "object_name" @Serializable @JsonClassDiscriminator(FactorioObjectDataDiscriminatorKey) -sealed class FactorioObjectData { +sealed class FactorioObjectData { @SerialName(FactorioObjectDataDiscriminatorKey) abstract val objectName: String } diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index 13bb477..fe34c63 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -5,11 +5,9 @@ import dev.adamko.kafkatorio.gradle.not import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { - id("dev.adamko.kafkatorio.process-runner") + id("dev.adamko.kafkatorio.infra.process-runner") } -val tokens: Map by project.extra - val clientModsDirectory = file("""D:\Users\Adam\AppData\Roaming\Factorio\mods""") val factorioGameId = "427520" val steamExe = """C:\Program Files (x86)\Steam\steam.exe""" diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index c41e6c9..5df52cf 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -1,15 +1,12 @@ import dev.adamko.kafkatorio.gradle.asConsumer import dev.adamko.kafkatorio.gradle.factorioModAttributes -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { - id("dev.adamko.kafkatorio.process-runner") + id("dev.adamko.kafkatorio.infra.docker-compose") } -val tokens: Map by project.extra - -val modInfraDir: Directory = layout.projectDirectory.dir("infra") -val factorioServerDataDir: Directory = modInfraDir.dir("factorio-server") +val srcDir: Directory by extra +val factorioServerDataDir: Directory = srcDir.dir("factorio-server") val factorioMod: Configuration by configurations.creating { asConsumer() @@ -32,46 +29,58 @@ val deployModToServer by tasks.registering(Copy::class) { } } -// -val factorioServerStop = tasks.register("factorioServerStop") { - group = project.name - - mustRunAfter(deployModToServer) - - workingDir(modInfraDir) - commandLine = parseSpaceSeparatedArgs("docker-compose stop factorio-server") +tasks.dockerUp { + dependsOn( + deployModToServer, + ":modules:infra-kafka-cluster:processRun", + ) } -val factorioServerUp = tasks.register("factorioServerUp") { - group = project.name - - mustRunAfter(deployModToServer) - dependsOn(factorioServerStop) - - workingDir(modInfraDir) - commandLine = parseSpaceSeparatedArgs("docker-compose up -d factorio-server") +tasks.updateEnv { + properties("FACTORIO_VERSION" to libs.versions.factorio.get()) } -val factorioServerRestart: Task by tasks.creating { - group = project.name - - dependsOn(factorioServerStop, factorioServerUp) -} -// - tasks.build { dependsOn(deployModToServer) } -tasks.processRun { - description = "Build the mod, upload to Server and Client, and start both" - dependsOn( - deployModToServer, - factorioServerRestart, - ) -} +// +//val factorioServerStop = tasks.register("factorioServerStop") { +// group = project.name +// +// mustRunAfter(deployModToServer) +// +// workingDir(modInfraDir) +// commandLine = parseSpaceSeparatedArgs("docker-compose stop factorio-server") +//} -tasks.processKill { - dependsOn( - factorioServerStop, - ) -} +//val factorioServerUp = tasks.register("factorioServerUp") { +// group = project.name +// +// mustRunAfter(deployModToServer) +// dependsOn(factorioServerStop) +// +// workingDir(modInfraDir) +// commandLine = parseSpaceSeparatedArgs("docker-compose up -d factorio-server") +//} +//val factorioServerRestart: Task by tasks.creating { +// group = project.name +// +// dependsOn(factorioServerStop, factorioServerUp) +//} +// + +// +//tasks.processRun { +// description = "Build the mod, upload to Server and Client, and start both" +// dependsOn( +// deployModToServer, +// factorioServerRestart, +// ) +//} +// +//tasks.processKill { +// dependsOn( +// factorioServerStop, +// ) +//} +// diff --git a/modules/infra-factorio-server/infra/.env b/modules/infra-factorio-server/infra/.env deleted file mode 100644 index 35ed112..0000000 --- a/modules/infra-factorio-server/infra/.env +++ /dev/null @@ -1 +0,0 @@ -COMPOSE_PROJECT_NAME=factorio-infra diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env new file mode 100644 index 0000000..0f0f4c6 --- /dev/null +++ b/modules/infra-factorio-server/src/.env @@ -0,0 +1,3 @@ +# Do not edit manually. This file was created with task 'updateEnv' +COMPOSE_PROJECT_NAME=kafkatorio +FACTORIO_VERSION=1.1.48 diff --git a/modules/infra-factorio-server/infra/.gitignore b/modules/infra-factorio-server/src/.gitignore similarity index 100% rename from modules/infra-factorio-server/infra/.gitignore rename to modules/infra-factorio-server/src/.gitignore diff --git a/modules/infra-factorio-server/infra/docker-compose.yml b/modules/infra-factorio-server/src/docker-compose.yml similarity index 83% rename from modules/infra-factorio-server/infra/docker-compose.yml rename to modules/infra-factorio-server/src/docker-compose.yml index 12fe89d..dc6a261 100644 --- a/modules/infra-factorio-server/infra/docker-compose.yml +++ b/modules/infra-factorio-server/src/docker-compose.yml @@ -3,13 +3,13 @@ version: "3.9" services: factorio-server: - image: factoriotools/factorio:1.1.48 + image: factoriotools/factorio:${FACTORIO_VERSION} # logging: # driver: "json-file" container_name: "factorio-server" restart: "unless-stopped" networks: - - "factorio-events-nw" + - "kafkatorio-nw" ports: - "34197:34197/udp" # factorio - "27015:27015/tcp" # rcon @@ -32,8 +32,6 @@ services: # - TOKEN=FactorioToken networks: - kafka-nw: - name: "kafka-nw" + kafkatorio-nw: + name: "kafkatorio-nw" external: true - factorio-events-nw: - name: "factorio-events-nw" diff --git a/modules/infra-factorio-server/infra/factorioEvents.Dockerfile b/modules/infra-factorio-server/src/factorioEvents.Dockerfile similarity index 62% rename from modules/infra-factorio-server/infra/factorioEvents.Dockerfile rename to modules/infra-factorio-server/src/factorioEvents.Dockerfile index 32676b8..7c24909 100644 --- a/modules/infra-factorio-server/infra/factorioEvents.Dockerfile +++ b/modules/infra-factorio-server/src/factorioEvents.Dockerfile @@ -3,7 +3,11 @@ ARG factorioVersion=1.1.42 FROM factoriotools/factorio:$factorioVersion - +# In progress +# The intention is to remove kafka-pipe and have a +# pre-preared Factorio Docker container than can +# just run, without needing an additional +# container with kcat. #RUN apk add --update \ # curl \ @@ -19,5 +23,3 @@ RUN apt-get update && apt-get install -y \ WORKDIR / COPY kafka-pipe.sh kafka-pipe.sh - - diff --git a/modules/infra-factorio-server/infra/kafka-pipe.sh b/modules/infra-factorio-server/src/kafka-pipe.sh similarity index 100% rename from modules/infra-factorio-server/infra/kafka-pipe.sh rename to modules/infra-factorio-server/src/kafka-pipe.sh diff --git a/modules/infra-factorio-server/infra/kcat.conf b/modules/infra-factorio-server/src/kcat.conf similarity index 100% rename from modules/infra-factorio-server/infra/kcat.conf rename to modules/infra-factorio-server/src/kcat.conf diff --git a/modules/infra-kafka-cluster/build.gradle.kts b/modules/infra-kafka-cluster/build.gradle.kts new file mode 100644 index 0000000..8cb355b --- /dev/null +++ b/modules/infra-kafka-cluster/build.gradle.kts @@ -0,0 +1,5 @@ +plugins { + id("dev.adamko.kafkatorio.infra.docker-compose") +} + +description = "Kafka cluster" diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env new file mode 100644 index 0000000..811559f --- /dev/null +++ b/modules/infra-kafka-cluster/src/.env @@ -0,0 +1,2 @@ +# Do not edit manually. This file was created with task 'updateEnv' +COMPOSE_PROJECT_NAME=kafkatorio diff --git a/modules/infra-kafka-cluster/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml similarity index 85% rename from modules/infra-kafka-cluster/docker-compose.yml rename to modules/infra-kafka-cluster/src/docker-compose.yml index 75c7cc6..c103f3b 100644 --- a/modules/infra-kafka-cluster/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -13,21 +13,21 @@ services: KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/3.0.0/kafka_2.13-3.0.0.tgz" networks: - "kafka-nw" - - "factorio-events-nw" + - "kafkatorio-nw" ports: - "9092:9092" - "9093:9093" kafka-ui: image: provectuslabs/kafka-ui:0.2.1 - container_name: kafka-ui + container_name: "kafka-ui" restart: "unless-stopped" networks: - "kafka-nw" ports: - "8080:8080" environment: - - KAFKA_CLUSTERS_0_NAME=factorio-events + - KAFKA_CLUSTERS_0_NAME=${COMPOSE_PROJECT_NAME} - KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka:29092 # - KAFKA_CLUSTERS_0_ZOOKEEPER=kafka:9093 @@ -48,6 +48,5 @@ services: networks: kafka-nw: name: "kafka-nw" - factorio-events-nw: - name: "factorio-events-nw" - external: true + kafkatorio-nw: + name: "kafkatorio-nw" diff --git a/modules/infra-kafka-cluster/kafka-server.properties b/modules/infra-kafka-cluster/src/kafka-server.properties similarity index 100% rename from modules/infra-kafka-cluster/kafka-server.properties rename to modules/infra-kafka-cluster/src/kafka-server.properties diff --git a/modules/infra-kafka-cluster/kafka.Dockerfile b/modules/infra-kafka-cluster/src/kafka.Dockerfile similarity index 100% rename from modules/infra-kafka-cluster/kafka.Dockerfile rename to modules/infra-kafka-cluster/src/kafka.Dockerfile diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index 96ba268..2991681 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -1,6 +1,9 @@ plugins { - id("dev.adamko.kafkatorio.process-runner") + id("dev.adamko.kafkatorio.infra.docker-compose") } description = "Send events from a Factorio server to a Kafka topic " +tasks.dockerUp { + dependsOn(":modules:infra-kafka-cluster:dockerUp") +} diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index d3d9e29..811559f 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1 +1,2 @@ -COMPOSE_PROJECT_NAME=factorio-events-kafka-pipe +# Do not edit manually. This file was created with task 'updateEnv' +COMPOSE_PROJECT_NAME=kafkatorio diff --git a/modules/infra-kafka-pipe/src/docker-compose.yml b/modules/infra-kafka-pipe/src/docker-compose.yml index 3e77115..c94fd64 100644 --- a/modules/infra-kafka-pipe/src/docker-compose.yml +++ b/modules/infra-kafka-pipe/src/docker-compose.yml @@ -1,15 +1,15 @@ version: "3.9" services: - factorio-events-kafka-pipe: + kafka-pipe: image: openjdk:11-jre-buster - container_name: "factorio-events-kafka-pipe" + container_name: "kafka-pipe" build: dockerfile: "kafka-pipe.Dockerfile" restart: "unless-stopped" privileged: true networks: - - "factorio-events-nw" + - "kafkatorio-nw" environment: FACTORIO_SERVER_CONTAINER_NAME: "factorio-server" KAFKA_HOST: "kafka:29092" @@ -20,6 +20,6 @@ services: # - "/var/run/docker.sock:/var/run/docker.sock" networks: - factorio-events-nw: - name: "factorio-events-nw" + kafkatorio-nw: + name: "kafkatorio-nw" external: true From 42b60ac0c3c2c2b1a63138714e46a6161b7693d3 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 3 Dec 2021 09:04:18 +0100 Subject: [PATCH 087/629] factorio -> event -> mod -> console -> kafka pipe -> kafka -> event processor working!!!!!!!!!!!!!!!!!! --- README.md | 25 ++++++++--- build.gradle.kts | 6 +-- .../kotlin/dev/adamko/kafkatorio/common.kt | 9 ++++ ...stribution.kt => artifactDistributions.kt} | 0 .../adamko/kafkatorio/gradle/extensions.kt | 27 +++++++++++- .../adamko/kafkatorio/lang/node.gradle.kts | 39 +++-------------- modules/events-mod/build.gradle.kts | 5 ++- .../events-mod/src/main/typescript/events.ts | 4 +- .../src/main/typescript/package-lock.json | 2 +- .../src/main/typescript/package.json | 14 +++--- .../main/typescript/schema/events-schema.ts | 4 +- .../dev/adamko/kafkatorio/processor/main.kt | 43 ++++++++++++++++--- modules/events-schema/build.gradle.kts | 2 + .../events/schema/factorioEvents.kt | 27 ++++++------ .../events/schema/FactorioEventTest.kt | 23 +++++----- .../infra-factorio-client/build.gradle.kts | 2 +- .../infra-factorio-server/build.gradle.kts | 5 +++ .../src/docker-compose.yml | 1 + .../infra-kafka-pipe/src/docker-compose.yml | 1 + 19 files changed, 152 insertions(+), 87 deletions(-) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt rename buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/{artifactDistribution.kt => artifactDistributions.kt} (100%) diff --git a/README.md b/README.md index 2a938cb..0c1acaa 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,11 @@ ## todo * add settings - * is active - whether files are exported or not - * delete files - clean up all files - * tick-rate - how often reports are generated ( - * requires on some sort of in-mod cache of map) - * also divide by game-speed? to keep ratio the same + * is active - whether files are exported or not + * delete files - clean up all files + * tick-rate - how often reports are generated ( + * requires on some sort of in-mod cache of map) + * also divide by game-speed? to keep ratio the same ### to investigate: @@ -21,6 +21,11 @@ * https://github.com/grafi-tt/lunajson * http://lua-users.org/wiki/CompressionAndArchiving * https://luapower.com/zlib +* https://github.com/appgurueu/modlib#bluon +* https://github.com/dingyi222666/lua-table-serialize +* https://github.com/uriid1/lua-serialize +* https://github.com/rxi/lume#lumeserializex +* https://github.com/SwadicalRag/bON * https://square.github.io/okio/#communicate-on-a-socket-javakotlin @@ -30,6 +35,16 @@ * https://jbrandhorst.com/post/go-protobuf-tips/ +##### flatbuffers + +https://github.com/dvidelabs/flatcc + + +##### z85 encoding + +* Kotlin https://gist.github.com/ischumacher/b4929f26341ebef62cbce35c65543eda +* Lua https://web-eworks.github.io/lZ85/ + #### CBOR https://www.zash.se/lua-cbor.html diff --git a/build.gradle.kts b/build.gradle.kts index b2e9d6e..a569d76 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "dev.adamko" -version = "0.0.7" +version = "0.1.1" tasks.wrapper { gradleVersion = "7.3" @@ -26,7 +26,7 @@ val runKafkatorio by tasks.registering { group = project.name dependsOn( - ":modules:infra-factorio-client:processRun", - ":modules:infra-factorio-server:processRun", + ":modules:infra-factorio-client:processRestart", + ":modules:infra-factorio-server:processRestart", ) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt new file mode 100644 index 0000000..856c07b --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt @@ -0,0 +1,9 @@ +package dev.adamko.kafkatorio + +import kotlinx.serialization.json.Json + + +val jsonMapper = Json { + prettyPrint = true + prettyPrintIndent = " " +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistribution.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistributions.kt similarity index 100% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistribution.kt rename to buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistributions.kt diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt index 6b9b74b..2dbf448 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt @@ -1,8 +1,13 @@ package dev.adamko.kafkatorio.gradle +import dev.adamko.kafkatorio.jsonMapper import java.io.ByteArrayOutputStream +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive import org.gradle.api.Project import org.gradle.api.Task +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.logging.LogLevel import org.gradle.api.specs.Spec import org.gradle.kotlin.dsl.invoke @@ -12,10 +17,28 @@ fun Project.isProcessRunning(process: String, ignoreCase: Boolean = true): Spec< Spec { ByteArrayOutputStream().use { outputStream -> project.exec { - commandLine("tasklist") + commandLine("tasklist") // Windows only for now... standardOutput = outputStream } outputStream.toString() .contains(process, ignoreCase) } - } \ No newline at end of file + } + +fun Project.areJsonPropertiesUpToDate( + packageJsonFile: RegularFileProperty, + properties: () -> Map +): Spec = Spec { + val packageJsonContent = packageJsonFile.get().asFile.readText() + val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject + + properties().all { (key, expectedVal) -> + val actualVal = packageJson[key]?.jsonPrimitive?.content + (expectedVal == actualVal).also { + logger.log( + if (it) LogLevel.LIFECYCLE else LogLevel.INFO, + "package.json has outdated property '$key' (expected: $expectedVal, actual: $actualVal)" + ) + } + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts index 9aa0c8f..7561bd9 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts @@ -1,20 +1,17 @@ package dev.adamko.kafkatorio.lang import com.github.gradle.node.NodePlugin -import dev.adamko.kafkatorio.task.UpdatePackageJson +import dev.adamko.kafkatorio.gradle.areJsonPropertiesUpToDate import dev.adamko.kafkatorio.gradle.not +import dev.adamko.kafkatorio.jsonMapper +import dev.adamko.kafkatorio.task.UpdatePackageJson import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.jsonObject -import kotlinx.serialization.json.jsonPrimitive import org.gradle.kotlin.dsl.support.useToRun -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin -import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlugin import org.jetbrains.kotlin.util.suffixIfNot - plugins { id("com.github.node-gradle.node") id("dev.adamko.kafkatorio.base") @@ -27,32 +24,6 @@ node { distBaseUrl.set(null as String?) // set by dependencyResolutionManagement } -project.plugins.withType() -project.plugins.withType() - - -val jsonMapper = Json { - prettyPrint = true - prettyPrintIndent = " " -} - - -fun arePropertiesUpToDate( - packageJsonFile: RegularFileProperty, - properties: () -> Map -): Spec = Spec { - val packageJsonContent = packageJsonFile.get().asFile.readText() - val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject - - properties().all { (key, expectedVal) -> - val actualVal = packageJson[key]?.jsonPrimitive?.content - (expectedVal == actualVal).also { - if (!it) - logger.lifecycle("package.json has outdated property '$key' (expected: $expectedVal, actual: $actualVal)") - } - } -} - val updatePackageJson by tasks.registering(UpdatePackageJson::class) { group = NodePlugin.NODE_GROUP description = "Read the package.json file and update the version and name, based on the project." @@ -60,7 +31,7 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) { propertiesToCheck["version"] = "${project.version}" // check to see if the properties are already up-to-date - onlyIf(!arePropertiesUpToDate(packageJsonFile) { propertiesToCheck }) + onlyIf(!areJsonPropertiesUpToDate(packageJsonFile) { propertiesToCheck }) doLast { val packageJsonContent = packageJsonFile.get().asFile.readText() @@ -74,7 +45,7 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) { .encodeToString(packageJsonUpdate) .suffixIfNot("\n") - logger.lifecycle(packageJsonContentUpdated) + logger.debug(packageJsonContentUpdated) packageJsonFile.get().asFile.writer().useToRun { write(packageJsonContentUpdated) diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 01acad9..e0f5ecc 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -52,7 +52,7 @@ val typescriptToLua by tasks.registering(NpmTask::class) { description = "Convert Typescript To Lua" group = project.name - dependsOn(tasks.npmInstall) + dependsOn(tasks.npmInstall, fetchEventsSchema) execOverrides { standardOutput = System.out } @@ -121,12 +121,13 @@ distributions { contents { from(layout.projectDirectory.dir("src/main/resources/mod-data")) { include("**/**") - filter("tokens" to tokens) } from(licenseFile) from(typescriptToLua.map { it.outputs }) + filter("tokens" to tokens) includeEmptyDirs = false exclude { + // exclude empty lines it.file.run { isFile && useLines { lines -> lines.all { line -> line.isBlank() } } } diff --git a/modules/events-mod/src/main/typescript/events.ts b/modules/events-mod/src/main/typescript/events.ts index 68835c5..f09773c 100644 --- a/modules/events-mod/src/main/typescript/events.ts +++ b/modules/events-mod/src/main/typescript/events.ts @@ -1,6 +1,7 @@ import {Serdes} from "./serdes/serdes" -const MOD_VERSION = script.active_mods["factorio-web-map"] +const MOD_VERSION = script.active_mods["@mod.name@"] ?? "UNKNOWN" +const FACTORIO_VERSION = script.active_mods["base"] ?? "UNKNOWN" const mapEventIdToName = new LuaTable() for (const [k, v] of pairs(defines.events)) { @@ -48,6 +49,7 @@ function emitEvent(eventData: T, tick: uint, event data: eventData, event_type: eventType, mod_version: MOD_VERSION, + factorio_version: FACTORIO_VERSION, tick: tick } diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index 58d0c36..800094c 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.0.7", + "version": "0.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 19e4815..bec800c 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.0.7", + "version": "0.1.1", "private": true, "scripts": { "build": "tstl", @@ -9,7 +9,8 @@ "engines": { "node": ">=10.13.0" }, - "devDependencies": {}, + "devDependencies": { + }, "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", @@ -20,7 +21,10 @@ "//": { "typed-factorio": "0.10.0" }, - "peerDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": [] + "peerDependencies": { + }, + "optionalDependencies": { + }, + "bundledDependencies": [ + ] } diff --git a/modules/events-mod/src/main/typescript/schema/events-schema.ts b/modules/events-mod/src/main/typescript/schema/events-schema.ts index 8950029..4443f16 100644 --- a/modules/events-mod/src/main/typescript/schema/events-schema.ts +++ b/modules/events-mod/src/main/typescript/schema/events-schema.ts @@ -8,6 +8,7 @@ interface FactorioObjectData { interface FactorioEvent { data: T; event_type: string; + factorio_version: string; mod_version: string; tick: uint; } @@ -21,7 +22,6 @@ interface PlayerData extends FactorioObjectData { associated_characters_unit_numbers: uint[]; character_unit_number: uint | null; name: string; - object_name: string; position: PositionData; } @@ -30,7 +30,6 @@ interface EntityData extends FactorioObjectData { health: double | null; health_ratio: double; name: string; - object_name: string; player_index: uint | null; position: PositionData; surface_index: int; @@ -42,5 +41,4 @@ interface SurfaceData extends FactorioObjectData { daytime: double; index: uint; name: string; - object_name: string; } \ No newline at end of file diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt index ffb938d..6aed9b3 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt @@ -5,13 +5,40 @@ import dev.adamko.kafkatorio.events.schema.FactorioObjectData import dev.adamko.kafkatorio.events.schema.jsonMapper import dev.adamko.kafkatorio.processor.config.ApplicationProperties import java.time.Duration +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString +import kotlinx.serialization.modules.SerializersModule +import org.apache.kafka.common.serialization.Deserializer +import org.apache.kafka.common.serialization.Serde import org.apache.kafka.common.serialization.Serdes +import org.apache.kafka.common.serialization.Serializer import org.apache.kafka.streams.KafkaStreams import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.TopologyDescription import org.apache.kafka.streams.kstream.Consumed -import org.apache.kafka.streams.processor.TopicNameExtractor -import org.http4k.format.KotlinxSerialization +import org.apache.kafka.streams.kstream.Produced +import org.http4k.format.ConfigurableKotlinxSerialization +import org.http4k.format.asConfigurable +import org.http4k.format.withStandardMappings + +object KSX : ConfigurableKotlinxSerialization({ + ignoreUnknownKeys = true + prettyPrint = true + prettyPrintIndent = " " + asConfigurable().withStandardMappings().done() + serializersModule = SerializersModule { } +}) + +object JsonSerdes : Serde> { + override fun serializer() = Serializer> { _, message -> + jsonMapper.encodeToString>(message).encodeToByteArray() + } + + override fun deserializer() = Deserializer> { _, bytes -> + jsonMapper.decodeFromString(bytes.decodeToString()) + } + +} fun main() { @@ -25,16 +52,18 @@ fun main() { ) .mapValues { readOnlyKey, value -> println("Mapping $readOnlyKey:$value") -// jsonMapper.decodeFromString>(value) - KotlinxSerialization.asA>(value) + jsonMapper.decodeFromString>(value) +// KSX.asA>(value) } - .to(TopicNameExtractor { key, value, recordContext -> - value.data.objectName - }) + .to( + { key, value, recordContext -> value.data.objectName }, + Produced.with(Serdes.String(), JsonSerdes) + ) val topology = builder.build() val properties = appProps.kafkaConfig + val streams = KafkaStreams(topology, properties) streams.setUncaughtExceptionHandler(StreamsExceptionHandler()) diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index 001e817..3a4c925 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -14,6 +14,8 @@ dependencies { implementation("com.github.ntrrgc:ts-generator:1.1.2") implementation("org.jetbrains.kotlin:kotlin-reflect") + + testImplementation(libs.kotest.datatest) } val generateTypescript by tasks.registering(JavaExec::class) { diff --git a/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index 38fa09e..609f90e 100644 --- a/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -1,8 +1,11 @@ package dev.adamko.kafkatorio.events.schema +import kotlin.reflect.full.findAnnotation +import kotlin.reflect.full.findAnnotations import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient import kotlinx.serialization.json.JsonClassDiscriminator @@ -15,6 +18,8 @@ data class FactorioEvent( /** Schema versioning */ @SerialName("mod_version") val modVersion: String, + @SerialName("factorio_version") + val factorioVersion: String, /** game time */ @SerialName("tick") val tick: UInt, @@ -29,17 +34,19 @@ const val FactorioObjectDataDiscriminatorKey: String = "object_name" @Serializable @JsonClassDiscriminator(FactorioObjectDataDiscriminatorKey) -sealed class FactorioObjectData { - @SerialName(FactorioObjectDataDiscriminatorKey) - abstract val objectName: String +sealed class FactorioObjectData private constructor() { + + // workaround - https://github.com/Kotlin/kotlinx.serialization/issues/1664 + val objectName : String by lazy { + requireNotNull(this::class.findAnnotation()?.value) { + "Couldn't find @SerialName for ${this::class}!" + } + } } @Serializable @SerialName("LuaPlayer") data class PlayerData( - @SerialName(FactorioObjectDataDiscriminatorKey) - override val objectName: String, - @Serializable(with = ListAsObjectSerializer::class) @SerialName("associated_characters_unit_numbers") val associatedCharactersUnitNumbers: List, @@ -54,9 +61,6 @@ data class PlayerData( @Serializable @SerialName("LuaEntity") data class EntityData( - @SerialName(FactorioObjectDataDiscriminatorKey) - override val objectName: String, - @SerialName("active") val active: Boolean, @SerialName("health") @@ -72,7 +76,7 @@ data class EntityData( @SerialName("type") val type: String, @SerialName("unit_number") - val unitNumber: UInt?, + val unitNumber: UInt? = null, @SerialName("player_index") val playerIndex: UInt? = null, @@ -81,9 +85,6 @@ data class EntityData( @Serializable @SerialName("LuaSurface") data class SurfaceData( - @SerialName(FactorioObjectDataDiscriminatorKey) - override val objectName: String, - @SerialName("daytime") val daytime: Double, @SerialName("index") diff --git a/modules/events-schema/src/test/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/test/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt index e41fb27..8bae62f 100644 --- a/modules/events-schema/src/test/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt +++ b/modules/events-schema/src/test/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt @@ -1,14 +1,8 @@ package dev.adamko.kafkatorio.events.schema -import dev.adamko.kafkatorio.events.schema.EntityData -import dev.adamko.kafkatorio.events.schema.FactorioEvent -import dev.adamko.kafkatorio.events.schema.FactorioObjectData -import dev.adamko.kafkatorio.events.schema.PlayerData -import dev.adamko.kafkatorio.events.schema.PositionData -import dev.adamko.kafkatorio.events.schema.SurfaceData -import dev.adamko.kafkatorio.events.schema.jsonMapper import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.equality.shouldBeEqualToComparingFields +import io.kotest.matchers.shouldBe import kotlinx.serialization.decodeFromString import org.intellij.lang.annotations.Language @@ -31,6 +25,7 @@ class FactorioEventTest : BehaviorSpec({ }, "event_type": "on_player_joined_game", "mod_version": "0.0.4", + "factorio_version": "1.1.48", "tick": 1278458 } """.trimIndent() @@ -40,7 +35,6 @@ class FactorioEventTest : BehaviorSpec({ val expected = FactorioEvent( data = PlayerData( - objectName = "LuaPlayer", name = "fredthedeadhead", characterUnitNumber = 1u, associatedCharactersUnitNumbers = emptyList(), @@ -51,10 +45,13 @@ class FactorioEventTest : BehaviorSpec({ ), eventType = "on_player_joined_game", modVersion = "0.0.4", + factorioVersion = "1.1.48", tick = 1278458u ) actual shouldBeEqualToComparingFields expected + + expected.data.objectName shouldBe "LuaPlayer" } } @@ -70,6 +67,7 @@ class FactorioEventTest : BehaviorSpec({ }, "event_type": "on_tick", "mod_version": "0.0.4", + "factorio_version": "1.1.48", "tick": 1278480 } """.trimIndent() @@ -78,17 +76,19 @@ class FactorioEventTest : BehaviorSpec({ val expected = FactorioEvent( data = SurfaceData( - objectName = "LuaSurface", name = "nauvis", index = 1u, daytime = 0.8390800000511436707029133685864508152008056640625 ), eventType = "on_tick", modVersion = "0.0.4", + factorioVersion = "1.1.48", tick = 1278480u ) actual shouldBeEqualToComparingFields expected + + expected.data.objectName shouldBe "LuaSurface" } } @@ -112,6 +112,7 @@ class FactorioEventTest : BehaviorSpec({ }, "event_type": "on_player_changed_position", "mod_version": "0.0.6", + "factorio_version": "1.1.48", "tick": 1384507 } """.trimIndent() @@ -120,7 +121,6 @@ class FactorioEventTest : BehaviorSpec({ val expected = FactorioEvent( data = EntityData( - objectName = "LuaEntity", name = "character", type = "character", active = true, @@ -136,10 +136,13 @@ class FactorioEventTest : BehaviorSpec({ ), eventType = "on_player_changed_position", modVersion = "0.0.6", + factorioVersion = "1.1.48", tick = 1384507u ) actual shouldBeEqualToComparingFields expected + + expected.data.objectName shouldBe "LuaEntity" } } diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index fe34c63..531ef55 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -45,7 +45,7 @@ val clientLaunch by tasks.registering(Exec::class) { onlyIf(!isFactorioRunning()) dependsOn(deployModToClient) - mustRunAfter(clientKill) + mustRunAfter(clientKill, ":modules:infra-factorio-server:processRun") commandLine = parseSpaceSeparatedArgs( // """explorer "steam://rungameid/$factorioGameId// --mp-connect localhost/" """ // not working diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 5df52cf..4715e8b 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -1,5 +1,6 @@ import dev.adamko.kafkatorio.gradle.asConsumer import dev.adamko.kafkatorio.gradle.factorioModAttributes +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { id("dev.adamko.kafkatorio.infra.docker-compose") @@ -29,6 +30,10 @@ val deployModToServer by tasks.registering(Copy::class) { } } +tasks.dockerDown { + commandLine = parseSpaceSeparatedArgs(""" docker-compose stop """) +} + tasks.dockerUp { dependsOn( deployModToServer, diff --git a/modules/infra-kafka-cluster/src/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml index c103f3b..8a4e714 100644 --- a/modules/infra-kafka-cluster/src/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -8,6 +8,7 @@ services: restart: "unless-stopped" build: dockerfile: "kafka.Dockerfile" + context: "." target: "kafka-kraft" args: KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/3.0.0/kafka_2.13-3.0.0.tgz" diff --git a/modules/infra-kafka-pipe/src/docker-compose.yml b/modules/infra-kafka-pipe/src/docker-compose.yml index c94fd64..976eb47 100644 --- a/modules/infra-kafka-pipe/src/docker-compose.yml +++ b/modules/infra-kafka-pipe/src/docker-compose.yml @@ -6,6 +6,7 @@ services: container_name: "kafka-pipe" build: dockerfile: "kafka-pipe.Dockerfile" + context: "." restart: "unless-stopped" privileged: true networks: From 29d190b8f4d000b2557be0fc2ef17be9e92c25d1 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 3 Dec 2021 22:18:17 +0100 Subject: [PATCH 088/629] fetch serialName with kxs, minor formatting/refactoring --- .../dev/adamko/kafkatorio/processor/main.kt | 7 +++---- .../events/schema/factorioEvents.kt | 20 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt index 6aed9b3..a6b5ff1 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt @@ -21,7 +21,8 @@ import org.http4k.format.ConfigurableKotlinxSerialization import org.http4k.format.asConfigurable import org.http4k.format.withStandardMappings -object KSX : ConfigurableKotlinxSerialization({ + +object KXS : ConfigurableKotlinxSerialization({ ignoreUnknownKeys = true prettyPrint = true prettyPrintIndent = " " @@ -37,7 +38,6 @@ object JsonSerdes : Serde> { override fun deserializer() = Deserializer> { _, bytes -> jsonMapper.decodeFromString(bytes.decodeToString()) } - } fun main() { @@ -53,7 +53,7 @@ fun main() { .mapValues { readOnlyKey, value -> println("Mapping $readOnlyKey:$value") jsonMapper.decodeFromString>(value) -// KSX.asA>(value) +// KXS.asA>(value) } .to( { key, value, recordContext -> value.data.objectName }, @@ -63,7 +63,6 @@ fun main() { val topology = builder.build() val properties = appProps.kafkaConfig - val streams = KafkaStreams(topology, properties) streams.setUncaughtExceptionHandler(StreamsExceptionHandler()) diff --git a/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index 609f90e..6e32078 100644 --- a/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -1,11 +1,9 @@ package dev.adamko.kafkatorio.events.schema -import kotlin.reflect.full.findAnnotation -import kotlin.reflect.full.findAnnotations +import kotlin.reflect.full.starProjectedType import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient import kotlinx.serialization.json.JsonClassDiscriminator @@ -34,14 +32,20 @@ const val FactorioObjectDataDiscriminatorKey: String = "object_name" @Serializable @JsonClassDiscriminator(FactorioObjectDataDiscriminatorKey) -sealed class FactorioObjectData private constructor() { +sealed class FactorioObjectData { // workaround - https://github.com/Kotlin/kotlinx.serialization/issues/1664 - val objectName : String by lazy { - requireNotNull(this::class.findAnnotation()?.value) { - "Couldn't find @SerialName for ${this::class}!" - } + val objectName: String by lazy { + kotlinx.serialization.serializer(this::class.starProjectedType).descriptor.serialName } + + // alternative: find the @SerialName annotation + // Again it must be delegated so there's no backing field and kxs ignores it +// val objectNameByAnnotation: String by lazy { +// requireNotNull(this::class.findAnnotation()?.value) { +// "Couldn't find @SerialName for ${this::class}!" +// } +// } } @Serializable From 6d60428ab9dbb03826571f0c1d37d3ceaa754a03 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Mon, 6 Dec 2021 22:15:26 +0100 Subject: [PATCH 089/629] added kvision web-map, cleaning up a few gradle things (tokens) --- LICENSE | 26 ++----- README.md | 16 ++++- build.gradle.kts | 25 ++++++- buildSrc/build.gradle.kts | 2 +- .../dev/adamko/kafkatorio/base.gradle.kts | 8 --- .../gradle/artifactDistributions.kt | 2 +- .../kafkatorio/lang/kotlin-js.gradle.kts | 18 ++--- .../adamko/kafkatorio/lang/node.gradle.kts | 6 +- .../kafkatorio/task/UpdatePackageJson.kt | 10 ++- gradle/libs.versions.toml | 1 + gradle/wrapper/gradle-wrapper.properties | 2 +- modules/events-mod/build.gradle.kts | 26 +++---- .../src/main/resources/mod-data/info.json | 2 +- .../src/main/typescript/package-lock.json | 2 +- .../src/main/typescript/package.json | 15 ++-- .../main/typescript/schema/events-schema.ts | 4 +- .../adamko/kafkatorio/events/schema/kt2ts.kt | 8 +-- modules/web-map/.gettext.json | 39 ++++++++++ modules/web-map/.gitignore | 8 +++ modules/web-map/build.gradle.kts | 72 +++++++++++++++++++ .../dev/adamko/kafkatorio/webmap/App.kt | 34 +++++++++ modules/web-map/src/main/web/index.html | 12 ++++ .../dev/adamko/kafkatorio/webmap/AppSpec.kt | 15 ++++ modules/web-map/webpack.config.d/bootstrap.js | 3 + modules/web-map/webpack.config.d/css.js | 2 + modules/web-map/webpack.config.d/file.js | 6 ++ .../web-map/webpack.config.d/handlebars.js | 6 ++ modules/web-map/webpack.config.d/jquery.js | 9 +++ modules/web-map/webpack.config.d/moment.js | 15 ++++ modules/web-map/webpack.config.d/webpack.js | 15 ++++ settings.gradle.kts | 1 + 31 files changed, 323 insertions(+), 87 deletions(-) create mode 100644 modules/web-map/.gettext.json create mode 100644 modules/web-map/.gitignore create mode 100644 modules/web-map/build.gradle.kts create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt create mode 100644 modules/web-map/src/main/web/index.html create mode 100644 modules/web-map/src/test/kotlin/test/dev/adamko/kafkatorio/webmap/AppSpec.kt create mode 100644 modules/web-map/webpack.config.d/bootstrap.js create mode 100644 modules/web-map/webpack.config.d/css.js create mode 100644 modules/web-map/webpack.config.d/file.js create mode 100644 modules/web-map/webpack.config.d/handlebars.js create mode 100644 modules/web-map/webpack.config.d/jquery.js create mode 100644 modules/web-map/webpack.config.d/moment.js create mode 100644 modules/web-map/webpack.config.d/webpack.js diff --git a/LICENSE b/LICENSE index 0804e5f..d867f51 100644 --- a/LICENSE +++ b/LICENSE @@ -1,24 +1,6 @@ -COPYRIGHT (C) LIMITED USE SOFTWARE LICENSE AGREEMENT +Copyright (C) 2021 adam@adamko.dev -All rights are reserved by the copyright holder. +This file is part of the Kafkatorio project. -Permission is granted to use this software as a Factorio mod. - -Permission is granted distribute this software under the -condition that the distribution is publicly accessible, -and no payment or registration is required. Additionally, -all distributions must include the full source code of the -software, without restrictions or limitations. - -Permission is granted to make modifications to this software -under the condition that any claim of ownership is -relinquished, and any modification becomes the property of -the original copyright holder of this software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -For more information contact fredthedeadhead@gmail.com +The Kafkatorio project cannot be copied and/or distributed +without the express permission of the author - adam@adamko.dev diff --git a/README.md b/README.md index 0c1acaa..b2ee244 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,20 @@ 1. converts data to images 2. hosts a web map + + +## License + +While this project is under development, [no license](https://choosealicense.com/no-permission/) +is provided. + ## todo * add settings * is active - whether files are exported or not * delete files - clean up all files - * tick-rate - how often reports are generated ( - * requires on some sort of in-mod cache of map) + * tick-rate - how often reports are generated + * requires on some sort of in-mod cache of map * also divide by game-speed? to keep ratio the same ### to investigate: @@ -48,4 +55,7 @@ https://github.com/dvidelabs/flatcc #### CBOR https://www.zash.se/lua-cbor.html -https://code.zash.se/lua-cbor/archive/68b3a36d0816.tar.gz \ No newline at end of file +https://code.zash.se/lua-cbor/archive/68b3a36d0816.tar.gz + + + diff --git a/build.gradle.kts b/build.gradle.kts index a569d76..582d59f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,13 +5,32 @@ plugins { `build-dashboard` } -group = "dev.adamko" -version = "0.1.1" +group = "dev.adamko.kafkatorio" +version = "0.1.2" + +val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) + +val projectTokens: MutableMap by extra( + mutableMapOf( + "project.version" to "$version", + "rootProject.name" to rootProject.name, + "date.year" to "${java.time.LocalDate.now().year}", + "author.email" to "adam@adamko.dev", + ) +) + +idea { + module { + isDownloadSources = true + isDownloadJavadoc = true + } +} tasks.wrapper { - gradleVersion = "7.3" + gradleVersion = "7.3.1" distributionType = Wrapper.DistributionType.ALL } +tasks.assemble { dependsOn(tasks.wrapper) } val startInfra by tasks.registering { group = project.name diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 1b93bce..c61dbe9 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -60,4 +60,4 @@ idea { } } -tasks.assemble { dependsOn(tasks.htmlDependencyReport) } +//tasks.assemble { dependsOn(tasks.htmlDependencyReport) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts index a23eaa1..732bd75 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts @@ -8,14 +8,6 @@ plugins { group = "${rootProject.group}.${project.name}" version = rootProject.version -val licenseFile: RegularFile by extra(rootProject.layout.projectDirectory.file("LICENSE")) - -val tokens: MutableMap by extra( - mutableMapOf( - "project.version" to "$version", - ) -) - idea { module { isDownloadSources = true diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistributions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistributions.kt index e4a9181..02bf554 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistributions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistributions.kt @@ -32,7 +32,7 @@ fun Configuration.factorioModAttributes(objects: ObjectFactory): Configuration = attribute(BUNDLING_ATTRIBUTE, objects.named(Bundling.EMBEDDED)) } -fun Configuration.typescriptAttributes(objects: ObjectFactory) = +fun Configuration.typescriptAttributes(objects: ObjectFactory): Configuration = attributes { attribute(USAGE_ATTRIBUTE, objects.named("typescript")) attribute(CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts index a7ce394..2304d8b 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts @@ -1,16 +1,8 @@ package dev.adamko.kafkatorio.lang import org.gradle.kotlin.dsl.kotlin -import com.github.gradle.node.npm.task.NpmTask -import com.github.gradle.node.task.NodeTask -import org.gradle.kotlin.dsl.dependencies -import org.gradle.kotlin.dsl.extra -import org.gradle.kotlin.dsl.getting -import org.jetbrains.kotlin.gradle.targets.js.dukat.DtsResolver -import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask -import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject +import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask plugins { @@ -19,6 +11,8 @@ plugins { id("dev.adamko.kafkatorio.lang.node") } +// not in use at the moment + kotlin { js(IR) { binaries.executable() @@ -31,9 +25,9 @@ kotlin { dependencies { val kotlinWrappersVersion = "0.0.1-pre.270-kotlin-1.6.0" implementation( - project.dependencies.enforcedPlatform( - "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" - ) + project.dependencies.enforcedPlatform( + "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" + ) ) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts index 7561bd9..53475e4 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts @@ -28,16 +28,16 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) { group = NodePlugin.NODE_GROUP description = "Read the package.json file and update the version and name, based on the project." - propertiesToCheck["version"] = "${project.version}" + propertiesToCheck.put("version", "${project.version}") // check to see if the properties are already up-to-date - onlyIf(!areJsonPropertiesUpToDate(packageJsonFile) { propertiesToCheck }) + onlyIf(!areJsonPropertiesUpToDate(packageJsonFile) { propertiesToCheck.get() }) doLast { val packageJsonContent = packageJsonFile.get().asFile.readText() val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject - val newJsonProps = propertiesToCheck.mapValues { (_, newVal) -> JsonPrimitive(newVal) } + val newJsonProps = propertiesToCheck.get().mapValues { (_, newVal) -> JsonPrimitive(newVal) } val packageJsonUpdate = JsonObject(packageJson + newJsonProps) val packageJsonContentUpdated = diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt index 2dc7b99..9017d20 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt @@ -2,12 +2,20 @@ package dev.adamko.kafkatorio.task import org.gradle.api.DefaultTask import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.MapProperty import org.gradle.api.tasks.Input import org.gradle.api.tasks.OutputFile abstract class UpdatePackageJson : DefaultTask() { @get:Input - val propertiesToCheck: MutableMap = mutableMapOf() + abstract val propertiesToCheck: MapProperty @get:OutputFile abstract val packageJsonFile: RegularFileProperty + + init { + super.doFirst { + propertiesToCheck.disallowChanges() + packageJsonFile.disallowChanges() + } + } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 439b18d..2107b2b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,6 +15,7 @@ log4j2 = "2.14.1" qosLogback = "1.2.5" kafka = "3.0.0" kotlinx-serialization = "1.3.1" +kvision = "5.6.1" ## test ## junit = "5.8.1" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fbce071..3cd8500 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index e0f5ecc..ff7582b 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -5,6 +5,7 @@ import dev.adamko.kafkatorio.gradle.factorioModAttributes import dev.adamko.kafkatorio.gradle.typescriptAttributes import groovy.json.JsonOutput import org.apache.tools.ant.filters.ReplaceTokens +import org.jetbrains.kotlin.gradle.targets.js.npm.SemVer import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { @@ -23,16 +24,18 @@ description = val modName: String by extra("${rootProject.name}-events") val distributionZipName: String by extra("${modName}_${project.version}.zip") +// version of Factorio that the mod is compatible with (must only be "major.minor" - patch causes error) +val modFactorioCompatibility = SemVer.from(libs.versions.factorio.get()).run { "$major.$minor" } -val tokens: MutableMap by project.extra -tokens += mapOf( +val licenseFile: RegularFile by rootProject.extra +val projectTokens: MutableMap by rootProject.extra +projectTokens += mapOf( "mod.name" to modName, "mod.title" to "Kafkatorio Events", "mod.description" to (project.description ?: ""), - "factorio.version" to libs.versions.factorio.get().substringBeforeLast("."), + "factorio.version" to modFactorioCompatibility, ) -val licenseFile: RegularFile by project.extra val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") node { @@ -52,7 +55,7 @@ val typescriptToLua by tasks.registering(NpmTask::class) { description = "Convert Typescript To Lua" group = project.name - dependsOn(tasks.npmInstall, fetchEventsSchema) + dependsOn(tasks.npmInstall, installEventsSchema) execOverrides { standardOutput = System.out } @@ -84,7 +87,7 @@ val typescriptToLua by tasks.registering(NpmTask::class) { } -val fetchEventsSchema by tasks.registering(Sync::class) { +val installEventsSchema by tasks.registering(Sync::class) { description = "Fetch the latest shared data-model" group = project.name @@ -124,10 +127,10 @@ distributions { } from(licenseFile) from(typescriptToLua.map { it.outputs }) - filter("tokens" to tokens) + filter("tokens" to projectTokens) includeEmptyDirs = false exclude { - // exclude empty lines + // exclude empty files it.file.run { isFile && useLines { lines -> lines.all { line -> line.isBlank() } } } @@ -196,7 +199,6 @@ val downloadFactorioApiDocs by tasks.registering { } } - val factorioModProvider by configurations.registering { asProvider() factorioModAttributes(objects) @@ -204,13 +206,11 @@ val factorioModProvider by configurations.registering { } tasks.updatePackageJson { - propertiesToCheck["name"] = "${rootProject.name}-${project.name}" + propertiesToCheck.put("name", "${rootProject.name}-${project.name}") packageJsonFile.set(layout.projectDirectory.file("src/main/typescript/package.json")) } -tasks.assemble { dependsOn(fetchEventsSchema, tasks.updatePackageJson) } -//tasks.build { dependsOn(packageMod) } - +tasks.assemble { dependsOn(installEventsSchema, tasks.updatePackageJson) } // //idea { diff --git a/modules/events-mod/src/main/resources/mod-data/info.json b/modules/events-mod/src/main/resources/mod-data/info.json index b9244ca..68f245b 100644 --- a/modules/events-mod/src/main/resources/mod-data/info.json +++ b/modules/events-mod/src/main/resources/mod-data/info.json @@ -3,7 +3,7 @@ "version": "@project.version@", "title": "@mod.title@", "description": "@mod.description@", - "author": "fredthedeadhead", + "author": "@author.email@", "factorio_version": "@factorio.version@", "dependencies": [] } diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index 800094c..c83bfc6 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.1.0", + "version": "0.1.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index bec800c..772d947 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.1.1", + "version": "0.1.2", "private": true, "scripts": { "build": "tstl", @@ -9,8 +9,7 @@ "engines": { "node": ">=10.13.0" }, - "devDependencies": { - }, + "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", @@ -21,10 +20,8 @@ "//": { "typed-factorio": "0.10.0" }, - "peerDependencies": { - }, - "optionalDependencies": { - }, - "bundledDependencies": [ - ] + "license": "UNLICENSED", + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] } diff --git a/modules/events-mod/src/main/typescript/schema/events-schema.ts b/modules/events-mod/src/main/typescript/schema/events-schema.ts index 4443f16..27a14dd 100644 --- a/modules/events-mod/src/main/typescript/schema/events-schema.ts +++ b/modules/events-mod/src/main/typescript/schema/events-schema.ts @@ -1,6 +1,4 @@ - -// Generated code - do edit this file manually - +// Generated by TypeScriptGenerator - do edit this file manually interface FactorioObjectData { object_name: string; } diff --git a/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt index c650bf6..d16ec4f 100644 --- a/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt +++ b/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt @@ -53,11 +53,9 @@ fun main(args: Array) { @Language("TypeScript") val header = """ - - // Generated code - do edit this file manually - - -""".trimIndent() + |// Generated by TypeScriptGenerator - do edit this file manually + | +""".trimMargin() object PropertyNameTransformer : ClassTransformer { override fun transformPropertyName( diff --git a/modules/web-map/.gettext.json b/modules/web-map/.gettext.json new file mode 100644 index 0000000..796d539 --- /dev/null +++ b/modules/web-map/.gettext.json @@ -0,0 +1,39 @@ +{ + "js": { + "parsers": [ + { + "expression": "tr", + "arguments": { + "text": 0 + } + }, + { + "expression": "ntr", + "arguments": { + "text": 0, + "textPlural": 1 + } + }, + { + "expression": "gettext", + "arguments": { + "text": 0 + } + }, + { + "expression": "ngettext", + "arguments": { + "text": 0, + "textPlural": 1 + } + } + ], + "glob": { + "pattern": "src/**/*.kt" + } + }, + "headers": { + "Language": "" + }, + "output": "src/main/resources/i18n/messages.pot" +} diff --git a/modules/web-map/.gitignore b/modules/web-map/.gitignore new file mode 100644 index 0000000..b1959ee --- /dev/null +++ b/modules/web-map/.gitignore @@ -0,0 +1,8 @@ +.*/ +build/ +out/ +/refresh.sh +*.imp +*.ipr +*.iws +*.idea diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts new file mode 100644 index 0000000..56e7897 --- /dev/null +++ b/modules/web-map/build.gradle.kts @@ -0,0 +1,72 @@ +import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig + +plugins { + id("dev.adamko.kafkatorio.base") + kotlin("plugin.serialization") + kotlin("js") // version kotlinVersion + id("io.kvision") version "5.6.1" +} + +kotlin { + js(IR) { + browser { + runTask { + outputFileName = "main.bundle.js" + sourceMaps = false + devServer = KotlinWebpackConfig.DevServer( + open = false, + port = 3000, + proxy = mutableMapOf( + "/kv/*" to "http://localhost:8080", + "/kvws/*" to mapOf("target" to "ws://localhost:8080", "ws" to true) + ), + static = mutableListOf("$buildDir/processedResources/js/main") + ) + } + webpackTask { + outputFileName = "main.bundle.js" + } + testTask { + useKarma { + useChromeHeadless() + } + } + } + binaries.executable() + } + + sourceSets { + val kvisionVersion: String = libs.versions.kvision.get() + + main { + dependencies { + + implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7") + + implementation("io.kvision:kvision:$kvisionVersion") + implementation("io.kvision:kvision-bootstrap:$kvisionVersion") + implementation("io.kvision:kvision-bootstrap-css:$kvisionVersion") + implementation("io.kvision:kvision-bootstrap-icons:$kvisionVersion") + implementation("io.kvision:kvision-fontawesome:$kvisionVersion") + implementation("io.kvision:kvision-state:$kvisionVersion") + implementation("io.kvision:kvision-chart:$kvisionVersion") + + val kotlinWrappersVersion = "0.0.1-pre.270-kotlin-1.6.0" + implementation( + project.dependencies.enforcedPlatform( + "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" + ) + ) + } + + val webDir = file("src/main/web") + resources.srcDir(webDir) + } + test { + dependencies { + implementation(kotlin("test-js")) + implementation("io.kvision:kvision-testutils:$kvisionVersion") + } + } + } +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt new file mode 100644 index 0000000..0e6bcce --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -0,0 +1,34 @@ +package dev.adamko.kafkatorio.webmap + +import io.kvision.Application +import io.kvision.CoreModule +import io.kvision.BootstrapModule +import io.kvision.BootstrapCssModule +import io.kvision.BootstrapIconsModule +import io.kvision.FontAwesomeModule +import io.kvision.ChartModule +import io.kvision.html.div +import io.kvision.module +import io.kvision.panel.root +import io.kvision.startApplication + +class App : Application() { + override fun start() { + root("kvapp") { + div("Hello world") + } + } +} + +fun main() { + startApplication( + ::App, + module.hot, + BootstrapModule, + BootstrapCssModule, + BootstrapIconsModule, + FontAwesomeModule, + ChartModule, + CoreModule + ) +} diff --git a/modules/web-map/src/main/web/index.html b/modules/web-map/src/main/web/index.html new file mode 100644 index 0000000..f7c610c --- /dev/null +++ b/modules/web-map/src/main/web/index.html @@ -0,0 +1,12 @@ + + + + + + KVision Template + + + +
+ + diff --git a/modules/web-map/src/test/kotlin/test/dev/adamko/kafkatorio/webmap/AppSpec.kt b/modules/web-map/src/test/kotlin/test/dev/adamko/kafkatorio/webmap/AppSpec.kt new file mode 100644 index 0000000..cce7cab --- /dev/null +++ b/modules/web-map/src/test/kotlin/test/dev/adamko/kafkatorio/webmap/AppSpec.kt @@ -0,0 +1,15 @@ +package test.dev.adamko.kafkatorio.webmap + +import io.kvision.test.SimpleSpec +import kotlin.test.Test +import kotlin.test.assertTrue + +class AppSpec : SimpleSpec { + + @Test + fun render() { + run { + assertTrue(true, "Dummy test") + } + } +} diff --git a/modules/web-map/webpack.config.d/bootstrap.js b/modules/web-map/webpack.config.d/bootstrap.js new file mode 100644 index 0000000..c9ac06d --- /dev/null +++ b/modules/web-map/webpack.config.d/bootstrap.js @@ -0,0 +1,3 @@ +config.module.rules.push({test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, type: 'asset'}); +config.module.rules.push({test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, type: 'asset'}); +config.module.rules.push({test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, type: 'asset/resource'}); diff --git a/modules/web-map/webpack.config.d/css.js b/modules/web-map/webpack.config.d/css.js new file mode 100644 index 0000000..3ed3ebc --- /dev/null +++ b/modules/web-map/webpack.config.d/css.js @@ -0,0 +1,2 @@ +config.module.rules.push({ test: /\.css$/, use: ["style-loader", { loader: "css-loader", options: {sourceMap: false} } ] }); + diff --git a/modules/web-map/webpack.config.d/file.js b/modules/web-map/webpack.config.d/file.js new file mode 100644 index 0000000..aa64925 --- /dev/null +++ b/modules/web-map/webpack.config.d/file.js @@ -0,0 +1,6 @@ +config.module.rules.push( + { + test: /\.(jpe?g|png|gif|svg)$/i, + type: 'asset/resource' + } +); diff --git a/modules/web-map/webpack.config.d/handlebars.js b/modules/web-map/webpack.config.d/handlebars.js new file mode 100644 index 0000000..d17c90e --- /dev/null +++ b/modules/web-map/webpack.config.d/handlebars.js @@ -0,0 +1,6 @@ +config.module.rules.push( + { + test: /\.hbs$/i, + loader: 'handlebars-loader' + } +); diff --git a/modules/web-map/webpack.config.d/jquery.js b/modules/web-map/webpack.config.d/jquery.js new file mode 100644 index 0000000..e6c6b21 --- /dev/null +++ b/modules/web-map/webpack.config.d/jquery.js @@ -0,0 +1,9 @@ +;(function() { + const webpack = require('webpack') + + config.plugins.push(new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery" + })); +})(); diff --git a/modules/web-map/webpack.config.d/moment.js b/modules/web-map/webpack.config.d/moment.js new file mode 100644 index 0000000..1dac35c --- /dev/null +++ b/modules/web-map/webpack.config.d/moment.js @@ -0,0 +1,15 @@ +;(function() { + const webpack = require('webpack') + try { + const moment = require("moment"); + config.plugins.push(new webpack.IgnorePlugin({ + resourceRegExp: /^\.\/locale$/, + contextRegExp: /moment$/, + })); + config.plugins.push(new webpack.ProvidePlugin({ + moment: "moment", + "window.moment": "moment" + })); + } catch (e) { + } +})(); diff --git a/modules/web-map/webpack.config.d/webpack.js b/modules/web-map/webpack.config.d/webpack.js new file mode 100644 index 0000000..4ce4481 --- /dev/null +++ b/modules/web-map/webpack.config.d/webpack.js @@ -0,0 +1,15 @@ +config.resolve.modules.push("../../processedResources/js/main"); + +if (config.devServer) { + config.devServer.hot = true; + config.devtool = 'eval-cheap-source-map'; +} else { + config.devtool = undefined; +} + +// disable bundle size warning +config.performance = { + assetFilter: function (assetFilename) { + return !assetFilename.endsWith('.js'); + }, +}; diff --git a/settings.gradle.kts b/settings.gradle.kts index 5c78149..22060ee 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -12,6 +12,7 @@ include( ":modules:infra-kafka-pipe", ":modules:kt-rcon", + ":modules:web-map", ) enableFeaturePreview("VERSION_CATALOGS") From 1f88d6f4644c8df88af8a85bba42eabe6a59c728 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 8 Dec 2021 17:43:08 +0100 Subject: [PATCH 090/629] move schema to kotlin-multiplatform --- .../adamko/kafkatorio/gradle/extensions.kt | 17 +-- .../adamko/kafkatorio/lang/node.gradle.kts | 2 +- gradle/libs.versions.toml | 4 +- modules/events-mod/build.gradle.kts | 31 +++--- modules/events-schema/build.gradle.kts | 100 ++++++++++++++---- .../kafkatorio/events/schema/builtinTypes.kt | 1 + .../events/schema/factorioEvents.kt | 8 +- .../adamko/kafkatorio/events/schema/json.kt | 0 .../adamko/kafkatorio/events/schema/kt2ts.kt | 0 .../events/schema/FactorioEventTest.kt | 0 modules/web-map/build.gradle.kts | 1 + 11 files changed, 118 insertions(+), 46 deletions(-) rename modules/events-schema/src/{main => commonMain}/kotlin/dev/adamko/kafkatorio/events/schema/builtinTypes.kt (99%) rename modules/events-schema/src/{main => commonMain}/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt (89%) rename modules/events-schema/src/{main => commonMain}/kotlin/dev/adamko/kafkatorio/events/schema/json.kt (100%) rename modules/events-schema/src/{main => jvmMain}/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt (100%) rename modules/events-schema/src/{test => jvmTest}/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt (100%) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt index 2dbf448..793ecef 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt @@ -7,7 +7,7 @@ import kotlinx.serialization.json.jsonPrimitive import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.file.RegularFileProperty -import org.gradle.api.logging.LogLevel +import org.gradle.api.provider.MapProperty import org.gradle.api.specs.Spec import org.gradle.kotlin.dsl.invoke @@ -27,18 +27,23 @@ fun Project.isProcessRunning(process: String, ignoreCase: Boolean = true): Spec< fun Project.areJsonPropertiesUpToDate( packageJsonFile: RegularFileProperty, - properties: () -> Map + properties: MapProperty ): Spec = Spec { val packageJsonContent = packageJsonFile.get().asFile.readText() val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject - properties().all { (key, expectedVal) -> + properties.get().all { (key, expectedVal) -> val actualVal = packageJson[key]?.jsonPrimitive?.content - (expectedVal == actualVal).also { - logger.log( - if (it) LogLevel.LIFECYCLE else LogLevel.INFO, + val isUpToDate = expectedVal == actualVal + + if (isUpToDate) { + logger.info("package.json property is up to date, '$key = $actualVal'") + } else { + logger.lifecycle( "package.json has outdated property '$key' (expected: $expectedVal, actual: $actualVal)" ) } + + isUpToDate } } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts index 53475e4..4210854 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts @@ -31,7 +31,7 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) { propertiesToCheck.put("version", "${project.version}") // check to see if the properties are already up-to-date - onlyIf(!areJsonPropertiesUpToDate(packageJsonFile) { propertiesToCheck.get() }) + onlyIf(!areJsonPropertiesUpToDate(packageJsonFile, propertiesToCheck)) doLast { val packageJsonContent = packageJsonFile.get().asFile.readText() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2107b2b..59d9e3f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -18,8 +18,8 @@ kotlinx-serialization = "1.3.1" kvision = "5.6.1" ## test ## -junit = "5.8.1" -kotest = "4.6.3" +junit = "5.8.2" +kotest = "5.0.1" ## infra ## factorio = "1.1.48" diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index ff7582b..bdb990c 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -55,7 +55,7 @@ val typescriptToLua by tasks.registering(NpmTask::class) { description = "Convert Typescript To Lua" group = project.name - dependsOn(tasks.npmInstall, installEventsSchema) + dependsOn(tasks.npmInstall, installEventsTsSchema) execOverrides { standardOutput = System.out } @@ -84,23 +84,27 @@ val typescriptToLua by tasks.registering(NpmTask::class) { into(outputDir) } } - } -val installEventsSchema by tasks.registering(Sync::class) { +val installEventsTsSchema by tasks.registering(Sync::class) { description = "Fetch the latest shared data-model" group = project.name dependsOn(typescriptEventsSchema) + val outputDir = layout.projectDirectory.dir("src/main/typescript/schema") + outputs.dir(outputDir) + from( - typescriptEventsSchema.incoming - .artifactView { lenient(true) } - .artifacts - .artifactFiles - .filter { file -> file.exists() } - .files - .map { zipTree(it) } + provider { typescriptEventsSchema } + .map { eventsSchema -> + eventsSchema.incoming + .artifactView { lenient(true) } + .artifacts + .artifactFiles + .filter { file -> file.exists() } + .map { zipTree(it) } + } ) { // drop the first directory inside the zip eachFile { @@ -108,8 +112,7 @@ val installEventsSchema by tasks.registering(Sync::class) { } includeEmptyDirs = false } - - into(layout.projectDirectory.dir("src/main/typescript/schema")) + into(outputDir) } tasks.distZip { @@ -130,7 +133,7 @@ distributions { filter("tokens" to projectTokens) includeEmptyDirs = false exclude { - // exclude empty files +// exclude empty files it.file.run { isFile && useLines { lines -> lines.all { line -> line.isBlank() } } } @@ -210,7 +213,7 @@ tasks.updatePackageJson { packageJsonFile.set(layout.projectDirectory.file("src/main/typescript/package.json")) } -tasks.assemble { dependsOn(installEventsSchema, tasks.updatePackageJson) } +tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) } // //idea { diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index 3a4c925..971aa8d 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -2,29 +2,83 @@ import dev.adamko.kafkatorio.gradle.asProvider import dev.adamko.kafkatorio.gradle.typescriptAttributes plugins { - id("dev.adamko.kafkatorio.lang.kotlin-jvm") + kotlin("multiplatform") kotlin("plugin.serialization") distribution } -dependencies { - implementation(platform(libs.kotlinx.serialization.bom)) - implementation(libs.kotlinx.serialization.core) - implementation(libs.kotlinx.serialization.json) +kotlin { + js(IR) { + binaries.executable() + nodejs() + } + jvm() - implementation("com.github.ntrrgc:ts-generator:1.1.2") - implementation("org.jetbrains.kotlin:kotlin-reflect") + @Suppress("UnstableApiUsage") // enforcedPlatform is incubating + sourceSets { - testImplementation(libs.kotest.datatest) + all { + languageSettings.apply { + optIn("kotlin.RequiresOptIn") + optIn("kotlin.ExperimentalStdlibApi") + optIn("kotlin.time.ExperimentalTime") + optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") + optIn("kotlinx.serialization.ExperimentalSerializationApi") + } + } + + val commonMain by getting { + dependencies { + implementation(project.dependencies.enforcedPlatform(libs.kotlin.bom)) + + implementation(project.dependencies.enforcedPlatform(libs.kotlinx.serialization.bom)) + implementation(libs.kotlinx.serialization.core) + implementation(libs.kotlinx.serialization.json) + + } + } + + val commonTest by getting { + dependencies { + + implementation(kotlin("test")) + + implementation(project.dependencies.enforcedPlatform(libs.kotest.bom)) + implementation("io.kotest:kotest-assertions-core") + implementation("io.kotest:kotest-property") + implementation("io.kotest:kotest-assertions-json") + } + } + + val jvmMain by getting { + dependencies { + implementation("com.github.ntrrgc:ts-generator:1.1.2") + implementation("org.jetbrains.kotlin:kotlin-reflect") + } + } + + val jvmTest by getting { + dependencies { + implementation("io.kotest:kotest-runner-junit5") + } + } + } } + val generateTypescript by tasks.registering(JavaExec::class) { group = project.name - val generatedFile = file("$temporaryDir/${project.name}.ts") + val jvmJar by tasks.getting(Jar::class) + val main by kotlin.jvm().compilations.getting + classpath( + jvmJar, + main.runtimeDependencyFiles + ) - classpath(sourceSets.main.map { it.runtimeClasspath }) mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2tsKt") + + val generatedFile = file("$temporaryDir/${project.name}.ts") args(generatedFile) val buildOutput = layout.buildDirectory.dir("generated/typescript") @@ -36,21 +90,25 @@ val generateTypescript by tasks.registering(JavaExec::class) { } doLast { - sync { from(temporaryDir); into(buildOutput) } - } -} - -distributions { - main { - distributionBaseName.set("${rootProject.name}-${project.name}") - contents { - from(generateTypescript.map { it.outputs.files.asFileTree }) + sync { + from(temporaryDir) + into(buildOutput) + include("**/*.ts") } } } -val typescriptModelGenerated by configurations.registering { +val schemaTs by distributions.registering { + distributionBaseName.set("${rootProject.name}-${project.name}") + contents { + from(generateTypescript.map { it.outputs.files.asFileTree }) + } +} + +val typescriptModelGenerated : Configuration by configurations.creating { asProvider() typescriptAttributes(objects) - outgoing.artifact(tasks.distZip.flatMap { it.archiveFile }) + + val schemaTsZipTask = tasks.named("${schemaTs.name}DistZip") + outgoing.artifact(schemaTsZipTask.flatMap { it.archiveFile }) } diff --git a/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/builtinTypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/builtinTypes.kt similarity index 99% rename from modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/builtinTypes.kt rename to modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/builtinTypes.kt index a4d3b7a..20d85e5 100644 --- a/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/builtinTypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/builtinTypes.kt @@ -3,6 +3,7 @@ package dev.adamko.kafkatorio.events.schema +import kotlin.jvm.JvmInline import kotlinx.serialization.Serializable diff --git a/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt similarity index 89% rename from modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt rename to modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index 6e32078..b4888b2 100644 --- a/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -1,7 +1,7 @@ package dev.adamko.kafkatorio.events.schema -import kotlin.reflect.full.starProjectedType +//import kotlin.reflect.full.starProjectedType import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonClassDiscriminator @@ -35,8 +35,12 @@ const val FactorioObjectDataDiscriminatorKey: String = "object_name" sealed class FactorioObjectData { // workaround - https://github.com/Kotlin/kotlinx.serialization/issues/1664 +// val objectName: String by lazy { +// kotlinx.serialization.serializer(this::class.starProjectedType).descriptor.serialName +// } val objectName: String by lazy { - kotlinx.serialization.serializer(this::class.starProjectedType).descriptor.serialName + serializer().descriptor.serialName +// kotlinx.serialization.serializer(this::class.starProjectedType).descriptor.serialName } // alternative: find the @SerialName annotation diff --git a/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/json.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt similarity index 100% rename from modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/json.kt rename to modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt diff --git a/modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt similarity index 100% rename from modules/events-schema/src/main/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt rename to modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt diff --git a/modules/events-schema/src/test/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt similarity index 100% rename from modules/events-schema/src/test/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt rename to modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 56e7897..855e89d 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -9,6 +9,7 @@ plugins { kotlin { js(IR) { +// nodejs() browser { runTask { outputFileName = "main.bundle.js" From 6b63f2ab97f2857d2d128db3364dd8700b930338 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 8 Dec 2021 17:57:28 +0100 Subject: [PATCH 091/629] fix server mod deploy --- modules/infra-factorio-server/build.gradle.kts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 4715e8b..8f113ec 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -22,7 +22,9 @@ val deployModToServer by tasks.registering(Copy::class) { description = "Copy the mod to the Factorio Docker server" group = project.name - from(factorioMod) + from( + provider { factorioMod.incoming.artifacts.artifactFiles.files } + ) into(factorioServerDataDir.dir("mods")) doLast { From 67685c7d571cf9c054b5470704f92af0188e8c97 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 8 Dec 2021 21:15:16 +0100 Subject: [PATCH 092/629] use kotlin SemVer lib for parsing Factorio version --- buildSrc/build.gradle.kts | 2 ++ modules/events-mod/build.gradle.kts | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index c61dbe9..3a8a465 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -22,6 +22,8 @@ dependencies { implementation("com.github.node-gradle:gradle-node-plugin:3.1.1") + + implementation("net.swiftzer.semver:semver:1.1.2") } val projectJvmTarget = "11" diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index bdb990c..57747f9 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -5,7 +5,7 @@ import dev.adamko.kafkatorio.gradle.factorioModAttributes import dev.adamko.kafkatorio.gradle.typescriptAttributes import groovy.json.JsonOutput import org.apache.tools.ant.filters.ReplaceTokens -import org.jetbrains.kotlin.gradle.targets.js.npm.SemVer +import net.swiftzer.semver.SemVer import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { @@ -25,7 +25,7 @@ val modName: String by extra("${rootProject.name}-events") val distributionZipName: String by extra("${modName}_${project.version}.zip") // version of Factorio that the mod is compatible with (must only be "major.minor" - patch causes error) -val modFactorioCompatibility = SemVer.from(libs.versions.factorio.get()).run { "$major.$minor" } +val modFactorioCompatibility = SemVer.parse(libs.versions.factorio.get()).run { "$major.$minor" } val licenseFile: RegularFile by rootProject.extra val projectTokens: MutableMap by rootProject.extra From 85763df8936b4d3f4efd0d4aaeb36525d99d0775 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 8 Dec 2021 21:15:26 +0100 Subject: [PATCH 093/629] refactor --- .../dev/adamko/kafkatorio/events/schema/factorioEvents.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index b4888b2..0371d19 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -35,13 +35,13 @@ const val FactorioObjectDataDiscriminatorKey: String = "object_name" sealed class FactorioObjectData { // workaround - https://github.com/Kotlin/kotlinx.serialization/issues/1664 + val objectName: String by lazy { + serializer().descriptor.serialName + } + // val objectName: String by lazy { // kotlinx.serialization.serializer(this::class.starProjectedType).descriptor.serialName // } - val objectName: String by lazy { - serializer().descriptor.serialName -// kotlinx.serialization.serializer(this::class.starProjectedType).descriptor.serialName - } // alternative: find the @SerialName annotation // Again it must be delegated so there's no backing field and kxs ignores it From 0736c7e24ce47471db42781786c73265394e2a3e Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 8 Dec 2021 21:15:37 +0100 Subject: [PATCH 094/629] js export optin compiler flag --- modules/events-schema/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index 971aa8d..ad6a372 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -24,6 +24,7 @@ kotlin { optIn("kotlin.time.ExperimentalTime") optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") optIn("kotlinx.serialization.ExperimentalSerializationApi") + optIn("kotlin.js.ExperimentalJsExport") } } From ca40d8bd3e1e0090c809732a2c2b3dedc1c1f099 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 8 Dec 2021 21:51:52 +0100 Subject: [PATCH 095/629] minor refactor --- modules/events-mod/build.gradle.kts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 57747f9..bb2c28e 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -4,8 +4,8 @@ import dev.adamko.kafkatorio.gradle.asProvider import dev.adamko.kafkatorio.gradle.factorioModAttributes import dev.adamko.kafkatorio.gradle.typescriptAttributes import groovy.json.JsonOutput -import org.apache.tools.ant.filters.ReplaceTokens import net.swiftzer.semver.SemVer +import org.apache.tools.ant.filters.ReplaceTokens import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { @@ -25,7 +25,12 @@ val modName: String by extra("${rootProject.name}-events") val distributionZipName: String by extra("${modName}_${project.version}.zip") // version of Factorio that the mod is compatible with (must only be "major.minor" - patch causes error) -val modFactorioCompatibility = SemVer.parse(libs.versions.factorio.get()).run { "$major.$minor" } +val modFactorioCompatibility: String by extra( + libs.versions.factorio + .map { SemVer.parse(it) } + .map { it.run { "$major.$minor" } } + .get() +) val licenseFile: RegularFile by rootProject.extra val projectTokens: MutableMap by rootProject.extra From adf55cb263e35367b9ce503105bafa1f4a7ada38 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 10 Dec 2021 20:38:52 +0100 Subject: [PATCH 096/629] some version bumps, and renaming --- build.gradle.kts | 2 +- .../infra/docker-compose.gradle.kts | 6 ++--- .../kafkatorio/lang/kotlin-jvm.gradle.kts | 12 +++++----- gradle/libs.versions.toml | 2 +- .../src/main/typescript/package-lock.json | 24 ++++++++----------- .../src/main/typescript/package.json | 11 ++++----- .../infra-factorio-server/build.gradle.kts | 2 +- modules/infra-factorio-server/src/.env | 4 ++-- modules/infra-kafka-cluster/src/.env | 2 +- modules/infra-kafka-pipe/src/.env | 2 +- modules/web-map/build.gradle.kts | 4 +++- 11 files changed, 33 insertions(+), 38 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 582d59f..d162c14 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.1.2" +version = "0.1.3" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts index 770e0a4..70a5fad 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts @@ -25,11 +25,11 @@ val dockerDown by tasks.creating(Exec::class) { } afterEvaluate { - tasks.named("processRun") { dependsOn(dockerUp, updateEnv) } + tasks.named("processRun") { dependsOn(dockerUp, dockerEnv) } tasks.named("processKill") { dependsOn(dockerDown) } } -val updateEnv by tasks.registering(WriteProperties::class) { +val dockerEnv by tasks.registering(WriteProperties::class) { group = dockerComposeTaskGroup setOutputFile(srcDir.file(".env")) @@ -38,4 +38,4 @@ val updateEnv by tasks.registering(WriteProperties::class) { ) } -tasks.assemble { dependsOn(updateEnv) } +tasks.assemble { dependsOn(dockerEnv) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index 12e2c81..0bea845 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -21,23 +21,23 @@ dependencies { // implementation(platform("org.jetbrains.kotlin:kotlin-bom")) - implementation(kotlin("stdlib")) +// implementation(kotlin("stdlib")) // // - val junitVersion = "5.8.1" + val junitVersion = "5.8.2" testImplementation(enforcedPlatform("org.junit:junit-bom:$junitVersion")) testImplementation("org.junit.jupiter:junit-jupiter-api") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") testRuntimeOnly("org.junit.platform:junit-platform-launcher") - val kotestVersion = "4.6.3" + val kotestVersion = "5.0.1" testImplementation(enforcedPlatform("io.kotest:kotest-bom:$kotestVersion")) - testImplementation("io.kotest:kotest-runner-junit5-jvm:$kotestVersion") - testImplementation("io.kotest:kotest-assertions-core-jvm:$kotestVersion") - testImplementation("io.kotest:kotest-property-jvm:$kotestVersion") + testImplementation("io.kotest:kotest-runner-junit5:$kotestVersion") + testImplementation("io.kotest:kotest-assertions-core:$kotestVersion") + testImplementation("io.kotest:kotest-property:$kotestVersion") testImplementation("io.kotest:kotest-assertions-json:$kotestVersion") testImplementation("io.mockk:mockk:1.12.0") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 59d9e3f..6f80bfc 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,7 @@ junit = "5.8.2" kotest = "5.0.1" ## infra ## -factorio = "1.1.48" +factorio = "1.1.49" ######### [plugins] diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index c83bfc6..14b1fa0 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.1.2", + "version": "0.1.3", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -74,23 +74,19 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.12.0.tgz", - "integrity": "sha512-7SeZX7TvWjtO+V5buWEgHUbhi7tSNZsHGveh5uPQ6Vvr7BDEhHre9DP3OrdD+L7cpAtvJ2w9OwaMnDm2P5dvng==", - "requires": { - "lua-types": "^2.10.1", - "typescript-to-lua": "^1.0.0" - } + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.13.0.tgz", + "integrity": "sha512-a6z8pciAtBQ+FXMJYUI1YqL/zhtFeEW2370rpuxZSaP6RdfWpZ98Vu8Hl19t98h+ULLXnmWsC/g6OW/TJcLbAQ==" }, "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==" + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", + "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==" }, "typescript-to-lua": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.1.1.tgz", - "integrity": "sha512-13vk/FSQyqbBkXNvg73LpT0tsPKdepJHPYR6TNtbc9l1ClSxAEUvkB3k49MAwSQ6LoN8Ui4Bgyu9dKFoDB315Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.2.0.tgz", + "integrity": "sha512-hbAagI6DgP4MjaPKqGlxtiD/rsZE5hO9ypIz96xukKIjzxp5c/TSItik0BMriX5yIIhRiYLfyAQBp+X1cO8MkQ==", "requires": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 772d947..a1150ee 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.1.2", + "version": "0.1.3", "private": true, "scripts": { "build": "tstl", @@ -13,12 +13,9 @@ "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", - "typescript-to-lua": "1.1.1", - "typed-factorio": "0.12.0", - "typescript": "4.4.4" - }, - "//": { - "typed-factorio": "0.10.0" + "typescript-to-lua": "1.2.0", + "typed-factorio": "0.13.0", + "typescript": "4.5.2" }, "license": "UNLICENSED", "peerDependencies": {}, diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 8f113ec..eee876e 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -43,7 +43,7 @@ tasks.dockerUp { ) } -tasks.updateEnv { +tasks.dockerEnv { properties("FACTORIO_VERSION" to libs.versions.factorio.get()) } diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index 0f0f4c6..69f81c6 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,3 +1,3 @@ -# Do not edit manually. This file was created with task 'updateEnv' +# Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -FACTORIO_VERSION=1.1.48 +FACTORIO_VERSION=1.1.49 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index 811559f..6f7d99f 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,2 +1,2 @@ -# Do not edit manually. This file was created with task 'updateEnv' +# Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index 811559f..6f7d99f 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,2 +1,2 @@ -# Do not edit manually. This file was created with task 'updateEnv' +# Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 855e89d..5fd09db 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -52,12 +52,14 @@ kotlin { implementation("io.kvision:kvision-state:$kvisionVersion") implementation("io.kvision:kvision-chart:$kvisionVersion") - val kotlinWrappersVersion = "0.0.1-pre.270-kotlin-1.6.0" + val kotlinWrappersVersion = "0.0.1-pre.276-kotlin-1.6.0" implementation( project.dependencies.enforcedPlatform( "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" ) ) + + implementation(npm("kafkajs", "1.15.0")) } val webDir = file("src/main/web") From f4bb22c1f86ed9d365eb26af7fd735474144283d Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 10 Dec 2021 21:27:19 +0100 Subject: [PATCH 097/629] kafka connect docker image setup --- .../infra/docker-compose.gradle.kts | 6 +- .../adamko/kafkatorio/lang/node.gradle.kts | 2 + gradle/libs.versions.toml | 16 ++- modules/infra-kafka-connect/build.gradle.kts | 127 ++++++++++++++++++ modules/infra-kafka-connect/src/.env | 4 + modules/infra-kafka-connect/src/.gitignore | 1 + .../src/docker-compose.yml | 50 +++++++ .../src/kafka-connect.Dockerfile | 19 +++ settings.gradle.kts | 2 + 9 files changed, 219 insertions(+), 8 deletions(-) create mode 100644 modules/infra-kafka-connect/build.gradle.kts create mode 100644 modules/infra-kafka-connect/src/.env create mode 100644 modules/infra-kafka-connect/src/.gitignore create mode 100644 modules/infra-kafka-connect/src/docker-compose.yml create mode 100644 modules/infra-kafka-connect/src/kafka-connect.Dockerfile diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts index 70a5fad..f00f353 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts @@ -6,7 +6,7 @@ plugins { id("dev.adamko.kafkatorio.infra.process-runner") } -val dockerComposeTaskGroup : String by extra("docker-compose") +val dockerComposeTaskGroup: String by extra("docker-compose") val composeProjectName: String by extra(rootProject.name) val srcDir: Directory by extra(layout.projectDirectory.dir("src")) @@ -14,12 +14,16 @@ val srcDir: Directory by extra(layout.projectDirectory.dir("src")) val dockerUp by tasks.creating(Exec::class) { group = dockerComposeTaskGroup + + dependsOn(tasks.assemble) + workingDir = srcDir.asFile commandLine = parseSpaceSeparatedArgs(""" docker-compose up -d """) } val dockerDown by tasks.creating(Exec::class) { group = dockerComposeTaskGroup + workingDir = srcDir.asFile commandLine = parseSpaceSeparatedArgs(""" docker-compose down """) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts index 4210854..17a4450 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts @@ -53,3 +53,5 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) { } } + +tasks.assemble { dependsOn(updatePackageJson) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6f80bfc..b51ab25 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,20 +9,22 @@ jvm = "11" kotlin = "1.6.0" ## libs ## -http4k = "4.17.2.0" -slf4j = "1.7.30" -log4j2 = "2.14.1" -qosLogback = "1.2.5" -kafka = "3.0.0" +camel-kafkaConnectors = "0.11.0" +http4k = "4.17.2.0" +kafka = "3.0.0" kotlinx-serialization = "1.3.1" -kvision = "5.6.1" +kvision = "5.6.1" +log4j2 = "2.14.1" +qosLogback = "1.2.5" +slf4j = "1.7.30" ## test ## junit = "5.8.2" kotest = "5.0.1" ## infra ## -factorio = "1.1.49" +factorio = "1.1.49" +confluent-kafkaConnect = "7.0.0" ######### [plugins] diff --git a/modules/infra-kafka-connect/build.gradle.kts b/modules/infra-kafka-connect/build.gradle.kts new file mode 100644 index 0000000..11a0ca9 --- /dev/null +++ b/modules/infra-kafka-connect/build.gradle.kts @@ -0,0 +1,127 @@ +import dev.adamko.kafkatorio.gradle.asConsumer +import dev.adamko.kafkatorio.jsonMapper +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.contentOrNull +import kotlinx.serialization.json.jsonArray +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive + +plugins { + id("dev.adamko.kafkatorio.infra.docker-compose") +} + +val camelConnectorDependencies: Configuration by configurations.creating { asConsumer() } + +fun DependencyHandlerScope.kafkaConnector( + name: String, + group: String = "org.apache.camel.kafkaconnector", + version: String = libs.versions.camel.kafkaConnectors.get(), +) { + camelConnectorDependencies(group, name, version) +} + +dependencies { + kafkaConnector("camel-websocket-kafka-connector") + kafkaConnector("camel-ahc-ws-kafka-connector") +} + + +val connectorJarDir: Directory = layout.projectDirectory.dir("src/camel-kafka-connectors") + +val downloadCamelConnectors by tasks.registering(Sync::class) { + group = project.name + description = "Retrieve Camel Kafka Connectors from Maven, in preparation for the Docker build" + + from( + provider { camelConnectorDependencies } + .map { eventsSchema -> + eventsSchema.incoming + .artifactView { lenient(true) } + .artifacts + .artifactFiles + } + ) + into(connectorJarDir) +} + + +tasks.dockerUp { + dependsOn(":modules:infra-kafka-cluster:dockerUp") + dependsOn(downloadCamelConnectors) +} + +tasks.dockerEnv { + properties( + "CONNECTOR_ID" to "kafkatorio-connect", + "KAFKA_CONNECT_VERSION" to libs.versions.confluent.kafkaConnect.get(), + ) +} + + +val availableCamelVersions by tasks.registering { + // dicking around with some sort of 'all camel connectors' docker image. + // it's unfinished. + + val camelGroup = "org.apache.camel.kafkaconnector" + val camelParent = "connectors" + + val requestUrl = """ + https://search.maven.org/solrsearch/select?q=g:"$camelGroup"+AND+a:"$camelParent"&core=gav&rows=20&wt=json + """.trimIndent() + .replace("\"", "%22") + + doLast { + + val connectorVersions = java.net.URL(requestUrl).readText() + logger.lifecycle("conn ==== $connectorVersions") + val versionsJson = jsonMapper.parseToJsonElement(connectorVersions).jsonObject + + logger.lifecycle("json ==== \n ${jsonMapper.encodeToString(versionsJson)}") + + val deps = versionsJson["response"] + ?.jsonObject + ?.get("docs") + ?.jsonArray + ?.map { it.jsonObject } + ?.mapNotNull { j -> + val group = j["g"]?.jsonPrimitive?.contentOrNull + val artifact = j["a"]?.jsonPrimitive?.contentOrNull + val version = j["v"]?.jsonPrimitive?.contentOrNull + val packaging = j["p"]?.jsonPrimitive?.contentOrNull?.toLowerCase() + + if (listOf(group, artifact, version, packaging).all { it != null }) { + val d = project.dependencies.create( + group = group!!, + name = artifact!!, + version = version!!, + ext = packaging, + ) + logger.lifecycle("dep = $d / $packaging") + d + } else { + null + } + } ?: emptyList() + + val c = configurations.detachedConfiguration() + c.dependencies.addAll(deps) + c.resolve() + .joinToString("\n\n---\n\n") { it.readLines().take(5).joinToString("\n") } + +// logger.lifecycle("ids: ${versions?.joinToString("\n", "\n\n", "\n\n")}") +// +// versions?.filterNotNull()?.forEach { id -> +// +// configurations.detachedConfiguration( +// project.dependencies.create(id) +// ) +// .resolve() +// .joinToString("\n\n---\n\n") { it.readLines().take(5).joinToString("\n") } +// +// } + + +// jsonMapper.parseToJsonElement() + + } +} diff --git a/modules/infra-kafka-connect/src/.env b/modules/infra-kafka-connect/src/.env new file mode 100644 index 0000000..a1fb7e3 --- /dev/null +++ b/modules/infra-kafka-connect/src/.env @@ -0,0 +1,4 @@ +# Do not edit manually. This file was created with task 'dockerEnv' +COMPOSE_PROJECT_NAME=kafkatorio +CONNECTOR_ID=kafkatorio-connect +KAFKA_CONNECT_VERSION=7.0.0 diff --git a/modules/infra-kafka-connect/src/.gitignore b/modules/infra-kafka-connect/src/.gitignore new file mode 100644 index 0000000..664df74 --- /dev/null +++ b/modules/infra-kafka-connect/src/.gitignore @@ -0,0 +1 @@ +camel-kafka-connectors/ diff --git a/modules/infra-kafka-connect/src/docker-compose.yml b/modules/infra-kafka-connect/src/docker-compose.yml new file mode 100644 index 0000000..7833ca4 --- /dev/null +++ b/modules/infra-kafka-connect/src/docker-compose.yml @@ -0,0 +1,50 @@ +version: "3.9" + +services: + + connect: + image: adamko-dev/kafkatorio-kafka-connect:${KAFKA_CONNECT_VERSION} + hostname: ${CONNECTOR_ID} + container_name: ${CONNECTOR_ID} + build: + context: "." + dockerfile: kafka-connect.Dockerfile + args: + KAFKA_CONNECT_VERSION: ${KAFKA_CONNECT_VERSION} +# FILE_PULSE_VERSION: ${CONNECTOR_FILE_PULSE_VERSION} +# CAMEL_KC_VERSION: ${CONNECTOR_CAMEL_KAFKA_VERSION} +# CAMEL_CONNECTOR: ${CAMEL_FILE_CONNECTOR} + ports: + - "28083:28083" +# volumes: +# - "./connect/input:/warehouse/input" +# - "./connect/components:/usr/share/confluent-hub-components" + +# volumes: +# - "./camel-kafka-connectors:/usr/share/java" + networks: + - "kafkatorio-nw" + environment: + CONNECT_BOOTSTRAP_SERVERS: "kafka:29092" + CONNECT_REST_ADVERTISED_HOST_NAME: ${CONNECTOR_ID} +# CONNECT_VALUE_CONVERTER_SCHEMA_REGISTRY_URL: "http://${SCHEMA_REGISTRY}:8081" + CONNECT_REST_PORT: 28083 + CONNECT_GROUP_ID: ${CONNECTOR_ID} + CONNECT_CONFIG_STORAGE_TOPIC: ${CONNECTOR_ID}-configs + CONNECT_CONFIG_STORAGE_REPLICATION_FACTOR: 1 + CONNECT_OFFSET_FLUSH_INTERVAL_MS: 10000 + CONNECT_OFFSET_STORAGE_TOPIC: ${CONNECTOR_ID}-offsets + CONNECT_OFFSET_STORAGE_REPLICATION_FACTOR: 1 + CONNECT_STATUS_STORAGE_TOPIC: ${CONNECTOR_ID}-status + CONNECT_STATUS_STORAGE_REPLICATION_FACTOR: 1 + CONNECT_KEY_CONVERTER: "org.apache.kafka.connect.storage.StringConverter" +# CONNECT_VALUE_CONVERTER: "io.confluent.connect.avro.AvroConverter" + CONNECT_VALUE_CONVERTER: "org.apache.kafka.connect.json.JsonConverter" + CONNECT_PLUGIN_PATH: "/usr/share/java,/usr/share/confluent-hub-components" + CONNECT_LOG4J_ROOT_LOGLEVEL: INFO + CONNECT_LOG4J_LOGGERS: "org.apache.zookeeper=INFO,org.I0Itec.zkclient=ERROR,org.reflections=ERROR" + +networks: + kafkatorio-nw: + name: "kafkatorio-nw" + external: true diff --git a/modules/infra-kafka-connect/src/kafka-connect.Dockerfile b/modules/infra-kafka-connect/src/kafka-connect.Dockerfile new file mode 100644 index 0000000..7659554 --- /dev/null +++ b/modules/infra-kafka-connect/src/kafka-connect.Dockerfile @@ -0,0 +1,19 @@ +ARG KAFKA_CONNECT_VERSION + + +FROM confluentinc/cp-kafka-connect-base:${KAFKA_CONNECT_VERSION} + +ENV CONNECT_VERSION=${KAFKA_CONNECT_VERSION} + +USER 0:0 + +COPY ./camel-kafka-connectors /usr/share/java/ + +#WORKDIR /usr/share/java/ +# +##ENV CAMEL_KC_VERSION=0.9.0 +##ENV CAMEL_CONNECTOR=camel-file-kafka-connector +# +#ENV URL=https://repo.maven.apache.org/maven2/org/apache/camel/kafkaconnector/camel-file-kafka-connector/0.9.0/camel-file-kafka-connector-0.9.0-package.tar.gz +# +#RUN curl -L $URL | tar -xzvf - --strip=0 $CAMEL_CONNECTOR diff --git a/settings.gradle.kts b/settings.gradle.kts index 22060ee..3af2206 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -8,8 +8,10 @@ include( ":modules:infra-factorio-client", ":modules:infra-factorio-server", + ":modules:infra-kafka-cluster", ":modules:infra-kafka-pipe", + ":modules:infra-kafka-connect", ":modules:kt-rcon", ":modules:web-map", From 7cd630500e646d59c1ec496ba23c6253726d2b63 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 10 Dec 2021 21:29:27 +0100 Subject: [PATCH 098/629] rm unused libs --- gradle/libs.versions.toml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b51ab25..9ec057c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -44,12 +44,8 @@ axionRelease = { id = "pl.allegro.tech.build.axion-release", vers [libraries] ########### -twilio-sdk = { group = "com.twilio.sdk", name = "twilio", version = "8.19.1" } -faker = { group = "com.github.javafaker", name = "javafaker", version = "1.0.2" } -sendgrid = { group = "com.sendgrid", name = "sendgrid-java", version = "4.7.4" } - ## kotlin ## -kotlin-bom = { group = "org.jetbrains.kotlin", name = "kotlin-bom", version.ref = "kotlin" } +kotlin-bom = { group = "org.jetbrains.kotlin", name = "kotlin-bom", version.ref = "kotlin" } kotlinx-serialization-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-bom", version.ref = "kotlinx-serialization" } kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core" } @@ -89,7 +85,6 @@ gcp-speech = { group = "com.google.cloud", name = "google-cloud-speech" ## kafka ## - kafka-streams = { group = "org.apache.kafka", name = "kafka-streams", version.ref = "kafka" } # kafka helpers From 45189dddc2872916303845b33ab7e705530b1620 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 22 Dec 2021 22:45:56 +0100 Subject: [PATCH 099/629] - version bumps for coroutines, gradle, kotlin - refactor kafka-connector project, prepping for the connector-admin --- build.gradle.kts | 3 +- buildSrc/build.gradle.kts | 8 +- buildSrc/repositories.settings.gradle.kts | 10 +- .../kotlin/dev/adamko/kafkatorio/common.kt | 1 - .../infra/docker-compose.gradle.kts | 21 +- .../kafkatorio/lang/kotlin-js.gradle.kts | 2 +- .../kafkatorio/lang/kotlin-jvm.gradle.kts | 19 +- gradle/libs.versions.toml | 30 +- gradle/wrapper/gradle-wrapper.properties | 2 +- kotlin-js-store/yarn.lock | 3219 +++++++++++++++++ modules/events-schema/build.gradle.kts | 2 +- .../infra-factorio-server/build.gradle.kts | 4 +- modules/infra-kafka-connect/build.gradle.kts | 94 +- .../src/{ => main/docker}/.env | 0 .../src/{ => main/docker}/.gitignore | 0 .../src/{ => main/docker}/docker-compose.yml | 0 .../docker}/kafka-connect.Dockerfile | 0 .../kafkaconnect/kafkaConnectAdmin.kt | 51 + .../configs/websocket-sink-lua-topics.json5 | 64 + modules/web-map/build.gradle.kts | 2 +- 20 files changed, 3408 insertions(+), 124 deletions(-) create mode 100644 kotlin-js-store/yarn.lock rename modules/infra-kafka-connect/src/{ => main/docker}/.env (100%) rename modules/infra-kafka-connect/src/{ => main/docker}/.gitignore (100%) rename modules/infra-kafka-connect/src/{ => main/docker}/docker-compose.yml (100%) rename modules/infra-kafka-connect/src/{ => main/docker}/kafka-connect.Dockerfile (100%) create mode 100644 modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/kafkaConnectAdmin.kt create mode 100644 modules/infra-kafka-connect/src/main/resources/configs/websocket-sink-lua-topics.json5 diff --git a/build.gradle.kts b/build.gradle.kts index d162c14..dac00c0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -27,7 +27,7 @@ idea { } tasks.wrapper { - gradleVersion = "7.3.1" + gradleVersion = "7.3.3" distributionType = Wrapper.DistributionType.ALL } tasks.assemble { dependsOn(tasks.wrapper) } @@ -38,6 +38,7 @@ val startInfra by tasks.registering { dependsOn( ":modules:infra-kafka-pipe:processRun", ":modules:infra-kafka-cluster:processRun", + ":modules:infra-kafka-connect:processRun", ) } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 3a8a465..2687fad 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -3,13 +3,13 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { idea `kotlin-dsl` - kotlin("jvm") version "1.6.0" + kotlin("jvm") version "1.6.10" `project-report` } dependencies { - val kotlinVersion = "1.6.0" + val kotlinVersion = "1.6.10" implementation(enforcedPlatform("org.jetbrains.kotlin:kotlin-bom:$kotlinVersion")) implementation("org.jetbrains.kotlin:kotlin-serialization") implementation("org.jetbrains.kotlin:kotlin-reflect") @@ -19,7 +19,7 @@ dependencies { implementation(enforcedPlatform("org.jetbrains.kotlinx:kotlinx-serialization-bom:$kotlinXSerializationVersion")) implementation("org.jetbrains.kotlinx:kotlinx-serialization-core") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json") - +// implementation("com.charleskorn.kaml:kaml:0.37.0") implementation("com.github.node-gradle:gradle-node-plugin:3.1.1") @@ -40,7 +40,7 @@ tasks.withType().configureEach { "-Xopt-in=kotlin.RequiresOptIn", "-Xopt-in=kotlin.ExperimentalStdlibApi", "-Xopt-in=kotlin.time.ExperimentalTime", - "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", +// "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", "-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi", ) } diff --git a/buildSrc/repositories.settings.gradle.kts b/buildSrc/repositories.settings.gradle.kts index 550a6d5..d4252d6 100644 --- a/buildSrc/repositories.settings.gradle.kts +++ b/buildSrc/repositories.settings.gradle.kts @@ -1,4 +1,3 @@ - @Suppress("UnstableApiUsage") dependencyResolutionManagement { @@ -13,7 +12,7 @@ dependencyResolutionManagement { repositories { mavenCentral() gradlePluginPortal() - maven("https://jitpack.io") + jitpack() maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") @@ -35,11 +34,16 @@ dependencyResolutionManagement { pluginManagement { repositories { - mavenCentral() gradlePluginPortal() + mavenCentral() + jitpack() maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") } } } + +fun RepositoryHandler.jitpack() { + maven("https://jitpack.io") +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt index 856c07b..73c7011 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt @@ -2,7 +2,6 @@ package dev.adamko.kafkatorio import kotlinx.serialization.json.Json - val jsonMapper = Json { prettyPrint = true prettyPrintIndent = " " diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts index f00f353..b15f05d 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts @@ -8,23 +8,26 @@ plugins { val dockerComposeTaskGroup: String by extra("docker-compose") -val composeProjectName: String by extra(rootProject.name) -val srcDir: Directory by extra(layout.projectDirectory.dir("src")) +val dockerComposeProjectName: String by extra(rootProject.name) +val dockerSrcDir: Directory by extra(layout.projectDirectory.dir("src")) -val dockerUp by tasks.creating(Exec::class) { +val dockerUp by tasks.registering(Exec::class) { group = dockerComposeTaskGroup dependsOn(tasks.assemble) + logging.captureStandardOutput(LogLevel.LIFECYCLE) - workingDir = srcDir.asFile + workingDir = dockerSrcDir.asFile commandLine = parseSpaceSeparatedArgs(""" docker-compose up -d """) } -val dockerDown by tasks.creating(Exec::class) { +val dockerDown by tasks.registering(Exec::class) { group = dockerComposeTaskGroup - workingDir = srcDir.asFile + logging.captureStandardOutput(LogLevel.LIFECYCLE) + + workingDir = dockerSrcDir.asFile commandLine = parseSpaceSeparatedArgs(""" docker-compose down """) } @@ -36,9 +39,11 @@ afterEvaluate { val dockerEnv by tasks.registering(WriteProperties::class) { group = dockerComposeTaskGroup - setOutputFile(srcDir.file(".env")) + logging.captureStandardOutput(LogLevel.LIFECYCLE) + + setOutputFile(dockerSrcDir.file(".env")) properties( - "COMPOSE_PROJECT_NAME" to composeProjectName, + "COMPOSE_PROJECT_NAME" to dockerComposeProjectName, ) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts index 2304d8b..fa6b191 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts @@ -23,7 +23,7 @@ kotlin { } dependencies { - val kotlinWrappersVersion = "0.0.1-pre.270-kotlin-1.6.0" + val kotlinWrappersVersion = "0.0.1-pre.276-kotlin-1.6.0" implementation( project.dependencies.enforcedPlatform( "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index 0bea845..a0fe076 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -1,8 +1,6 @@ package dev.adamko.kafkatorio.lang -import org.gradle.kotlin.dsl.dependencies import org.gradle.kotlin.dsl.kotlin -import org.gradle.kotlin.dsl.withType import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -29,11 +27,12 @@ dependencies { val junitVersion = "5.8.2" testImplementation(enforcedPlatform("org.junit:junit-bom:$junitVersion")) - testImplementation("org.junit.jupiter:junit-jupiter-api") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") - testRuntimeOnly("org.junit.platform:junit-platform-launcher") + testImplementation("org.junit.jupiter:junit-jupiter") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") { + because("Only needed to run tests in a version of IntelliJ IDEA that bundles older versions") + } - val kotestVersion = "5.0.1" + val kotestVersion = "5.0.3" testImplementation(enforcedPlatform("io.kotest:kotest-bom:$kotestVersion")) testImplementation("io.kotest:kotest-runner-junit5:$kotestVersion") testImplementation("io.kotest:kotest-assertions-core:$kotestVersion") @@ -58,11 +57,15 @@ tasks.withType().configureEach { "-Xopt-in=kotlin.RequiresOptIn", "-Xopt-in=kotlin.ExperimentalStdlibApi", "-Xopt-in=kotlin.time.ExperimentalTime", - "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", +// "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", "-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi", ) } tasks.compileTestKotlin { kotlinOptions.freeCompilerArgs += "-Xopt-in=io.kotest.common.ExperimentalKotest" -} \ No newline at end of file +} + +tasks.withType { + useJUnitPlatform() +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9ec057c..fe50e09 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,11 +6,11 @@ ## compilation ## jvm = "11" -kotlin = "1.6.0" +kotlin = "1.6.10" ## libs ## camel-kafkaConnectors = "0.11.0" -http4k = "4.17.2.0" +http4k = "4.17.4.0" kafka = "3.0.0" kotlinx-serialization = "1.3.1" kvision = "5.6.1" @@ -50,22 +50,22 @@ kotlin-bom = { group = "org.jetbrains.kotlin", name = "kotlin-bom", version.ref kotlinx-serialization-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-bom", version.ref = "kotlinx-serialization" } kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core" } kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json" } -kotlinx-serialization-yaml = { group = "com.charleskorn.kaml", name = "kaml", version = "0.37.0" } -kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.6.0-RC" } -kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.7.3" } +kotlinx-serialization-yaml = { group = "com.charleskorn.kaml", name = "kaml", version = "0.37.0" } +kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.6.0" } +kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.7.3" } ## http4k ## http4k-bom = { group = "org.http4k", name = "http4k-bom", version.ref = "http4k" } -http4k-core = { group = "org.http4k", name = "http4k-core" } -http4k-contract = { group = "org.http4k", name = "http4k-contract" } -http4k-client = { group = "org.http4k", name = "http4k-client-okhttp" } -http4k-server = { group = "org.http4k", name = "http4k-server-undertow" } -http4k-cloudnative = { group = "org.http4k", name = "http4k-cloudnative" } -http4k-format-json = { group = "org.http4k", name = "http4k-format-jackson" } -http4k-format-xml = { group = "org.http4k", name = "http4k-format-jackson-xml" } -http4k-format-yaml = { group = "org.http4k", name = "http4k-format-jackson-yaml" } -http4k-format-kotlinx = { group = "org.http4k", name = "http4k-format-kotlinx-serialization" } -http4k-graphql = { group = "org.http4k", name = "http4k-graphql" } +http4k-core = { group = "org.http4k", name = "http4k-core" } +http4k-contract = { group = "org.http4k", name = "http4k-contract" } +http4k-client = { group = "org.http4k", name = "http4k-client-okhttp" } +http4k-server = { group = "org.http4k", name = "http4k-server-undertow" } +http4k-cloudnative = { group = "org.http4k", name = "http4k-cloudnative" } +http4k-format-json = { group = "org.http4k", name = "http4k-format-jackson" } +http4k-format-xml = { group = "org.http4k", name = "http4k-format-jackson-xml" } +http4k-format-yaml = { group = "org.http4k", name = "http4k-format-jackson-yaml" } +http4k-format-kotlinx = { group = "org.http4k", name = "http4k-format-kotlinx-serialization" } +http4k-graphql = { group = "org.http4k", name = "http4k-graphql" } ### jackson ## #jackson-bom = { group = " com.fasterxml.jackson.module", name = ":jackson-module-kotlin", version = "2.13.+" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3cd8500..669386b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock new file mode 100644 index 0000000..18bda50 --- /dev/null +++ b/kotlin-js-store/yarn.lock @@ -0,0 +1,3219 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@discoveryjs/json-ext@^0.5.0": + version "0.5.6" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" + integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA== + +"@fortawesome/fontawesome-free@^5.15.4": + version "5.15.4" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5" + integrity sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@popperjs/core@^2.10.2": + version "2.11.0" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.0.tgz#6734f8ebc106a0860dff7f92bf90df193f0935d7" + integrity sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ== + +"@rjaros/snabbdom-virtualize@^1.0.0-beta.0": + version "1.0.0-beta.0" + resolved "https://registry.yarnpkg.com/@rjaros/snabbdom-virtualize/-/snabbdom-virtualize-1.0.0-beta.0.tgz#b35f143d8772b3bdf1222784450f3a05a4403e6f" + integrity sha512-aIx4z9BDoTW0Tn1gIhnmv/NU5dYvlTjSJOKYSQvY0TX1WYMX9fQNQT37t1M2GEwqbQyBEffyhlEEfF100JCNGQ== + dependencies: + html-parse-stringify2 "^2" + +"@types/component-emitter@^1.2.10": + version "1.2.11" + resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" + integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== + +"@types/cookie@^0.4.0": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" + integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== + +"@types/cors@^2.8.8": + version "2.8.12" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" + integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== + +"@types/eslint-scope@^3.7.0": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.2.tgz#11e96a868c67acf65bf6f11d10bb89ea71d5e473" + integrity sha512-TzgYCWoPiTeRg6RQYgtuW7iODtVoKu3RVL72k3WohqhjfaOLK5Mg2T4Tg1o2bSfu0vPkoI48wdQFv5b/Xe04wQ== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.2.1" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.2.1.tgz#13f3d69bac93c2ae008019c28783868d0a1d6605" + integrity sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^0.0.50": + version "0.0.50" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" + integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== + +"@types/glob@5 - 7": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/http-proxy@^1.17.5": + version "1.17.8" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.8.tgz#968c66903e7e42b483608030ee85800f22d03f55" + integrity sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA== + dependencies: + "@types/node" "*" + +"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== + +"@types/minimatch@*": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== + +"@types/node@*", "@types/node@>=10.0.0": + version "17.0.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.2.tgz#a4c07d47ff737e8ee7e586fe636ff0e1ddff070a" + integrity sha512-JepeIUPFDARgIs0zD/SKPgFsJEAF0X5/qO80llx59gOxFTboS9Amv3S+QfB7lqBId5sFXJ99BN0J6zFRvL9dDA== + +"@types/parse5@^5": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" + integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== + +"@types/retry@^0.12.0": + version "0.12.1" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" + integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== + +"@ungap/promise-all-settled@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== + +"@webassemblyjs/ast@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + +"@webassemblyjs/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== + +"@webassemblyjs/helper-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + +"@webassemblyjs/helper-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== + +"@webassemblyjs/helper-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== + +"@webassemblyjs/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + +"@webassemblyjs/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + +"@webassemblyjs/wasm-edit@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + +"@webassemblyjs/wasm-gen@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wasm-opt@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + +"@webassemblyjs/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webpack-cli/configtest@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.0.tgz#8342bef0badfb7dfd3b576f2574ab80c725be043" + integrity sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg== + +"@webpack-cli/info@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.0.tgz#b9179c3227ab09cbbb149aa733475fcf99430223" + integrity sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw== + dependencies: + envinfo "^7.7.3" + +"@webpack-cli/serve@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.0.tgz#2c275aa05c895eccebbfc34cfb223c6e8bd591a2" + integrity sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abab@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + +acorn@^8.4.1: + version "8.6.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" + integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.0, ajv@^8.8.0: + version "8.8.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.8.2.tgz#01b4fef2007a28bf75f0b7fc009f62679de4abbb" + integrity sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" + integrity sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg= + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +async@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +awesome-bootstrap-checkbox@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/awesome-bootstrap-checkbox/-/awesome-bootstrap-checkbox-1.0.1.tgz#dab10146b6001129ab0a0ec1e54bb77c6c30457a" + integrity sha1-2rEBRrYAESmrCg7B5Uu3fGwwRXo= + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-arraybuffer@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" + integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= + +base64id@2.0.0, base64id@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +body-parser@1.19.1, body-parser@^1.19.0: + version "1.19.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.1.tgz#1499abbaa9274af3ecc9f6f10396c995943e31d4" + integrity sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA== + dependencies: + bytes "3.1.1" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.9.6" + raw-body "2.4.2" + type-is "~1.6.18" + +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + +bootstrap-icons@^1.6.0: + version "1.7.2" + resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.7.2.tgz#4024e081e2c850602552e1fed6451e682d09322a" + integrity sha512-NiR2PqC73AQOPdVSu6GJfnk+hN2z6powcistXk1JgPnKuoV2FSdSl26w931Oz9HYbKCcKUSB6ncZTYJAYJl3QQ== + +bootstrap@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.1.3.tgz#ba081b0c130f810fa70900acbc1c6d3c28fa8f34" + integrity sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserslist@^4.14.5: + version "4.19.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" + integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== + dependencies: + caniuse-lite "^1.0.30001286" + electron-to-chromium "^1.4.17" + escalade "^3.1.1" + node-releases "^2.0.1" + picocolors "^1.0.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +bytes@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a" + integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg== + +call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +camelcase@^6.0.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.1.tgz#250fd350cfd555d0d2160b1d51510eaf8326e86e" + integrity sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA== + +caniuse-lite@^1.0.30001286: + version "1.0.30001292" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001292.tgz#4a55f61c06abc9595965cfd77897dc7bc1cdc456" + integrity sha512-jnT4Tq0Q4ma+6nncYQVe7d73kmDmE9C3OGTx3MvW7lBM/eY1S1DZTMBON7dqV481RhNiS5OxD7k9JQvmDOTirw== + +chalk@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" + integrity sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8= + dependencies: + ansi-styles "~1.0.0" + has-color "~0.1.0" + strip-ansi "~0.1.0" + +chart.js@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.6.2.tgz#47342c551f688ffdda2cd53b534cb7e461ecec33" + integrity sha512-Xz7f/fgtVltfQYWq0zL1Xbv7N2inpG+B54p3D5FSvpCdy3sM+oZhbqa42eNuYXltaVvajgX5UpKCU2GeeJIgxg== + +chokidar@3.5.2, chokidar@^3.5.1, chokidar@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^2.0.10, colorette@^2.0.14: + version "2.0.16" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" + integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== + +colors@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +component-emitter@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +connect@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== + dependencies: + debug "2.6.9" + finalhandler "1.1.2" + parseurl "~1.3.3" + utils-merge "1.0.1" + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.1, cookie@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cors@~2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-loader@^6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.5.1.tgz#0c43d4fbe0d97f699c91e9818cb585759091d1b1" + integrity sha512-gEy2w9AnJNnD9Kuo4XAP9VflW/ujKoS9c/syO+uWMlm5igc7LysKzPXaDoR2vroROkSwsTS2tGr1yGGEbZOYZQ== + dependencies: + icss-utils "^5.1.0" + postcss "^8.2.15" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.1.0" + semver "^7.3.5" + +css-selector-parser@^1.3: + version "1.4.1" + resolved "https://registry.yarnpkg.com/css-selector-parser/-/css-selector-parser-1.4.1.tgz#03f9cb8a81c3e5ab2c51684557d5aaf6d2569759" + integrity sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= + +date-format@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-2.1.0.tgz#31d5b5ea211cf5fd764cd38baf9d033df7e125cf" + integrity sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA== + +date-format@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-3.0.0.tgz#eb8780365c7d2b1511078fb491e6479780f3ad95" + integrity sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + +debug@^3.1.1: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.0, debug@^4.1.1, debug@~4.3.1: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +deep-equal@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +del@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/del/-/del-6.0.0.tgz#0b40d0332cea743f1614f818be4feb717714c952" + integrity sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ== + dependencies: + globby "^11.0.1" + graceful-fs "^4.2.4" + is-glob "^4.0.1" + is-path-cwd "^2.2.0" + is-path-inside "^3.0.2" + p-map "^4.0.0" + rimraf "^3.0.2" + slash "^3.0.0" + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw= + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + +dns-packet@^1.3.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" + integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + +dom-serialize@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + integrity sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs= + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + +dukat@0.5.8-rc.3: + version "0.5.8-rc.3" + resolved "https://registry.yarnpkg.com/dukat/-/dukat-0.5.8-rc.3.tgz#4a2b848b9d2978cb610af8d5cf24ff5e5a408743" + integrity sha512-wzl9A5alTT1Mag4y7bUVjPF4L/wkts7AiiWxe6/6tL5gSDowexUzlJX/pYVTbnHcOo48/bok3Ao1gzU4/cFFjw== + dependencies: + google-protobuf "3.12.2" + typescript "3.9.5" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +electron-to-chromium@^1.4.17: + version "1.4.27" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.27.tgz#bfc6e798d8a56a17d658312f4b7ae1a7ca87724f" + integrity sha512-uZ95szi3zUbzRDx1zx/xnsCG+2xgZyy57pDOeaeO4r8zx5Dqe8Jv1ti8cunvBwJHVI5LzPuw8umKwZb3WKYxSQ== + +element-resize-event@^3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/element-resize-event/-/element-resize-event-3.0.6.tgz#3a18efd4879ad615e979fd8bbf173b014987eb9a" + integrity sha512-sSeXY9rNDp86bJODW68pxLcy3A5FrPZfIgOrJHzqgYzX513Zq6/ytdBigp7KeJEpZZopBBSiO1cVuiRkZpNxLw== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +encoding@^0.1.11: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + +engine.io-parser@~4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-4.0.3.tgz#83d3a17acfd4226f19e721bb22a1ee8f7662d2f6" + integrity sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA== + dependencies: + base64-arraybuffer "0.1.4" + +engine.io@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-4.1.1.tgz#9a8f8a5ac5a5ea316183c489bf7f5b6cf91ace5b" + integrity sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w== + dependencies: + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~4.0.0" + ws "~7.4.2" + +enhanced-resolve@^5.8.3: + version "5.8.3" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" + integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0= + +envinfo@^7.7.3: + version "7.8.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" + integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +express@^4.17.1: + version "4.17.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.2.tgz#c18369f265297319beed4e5558753cc8c1364cb3" + integrity sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.4.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.9.6" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.17.2" + serve-static "1.14.2" + setprototypeof "1.2.0" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.1.1: + version "3.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" + integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fastest-levenshtein@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" + integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== + +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +fecha@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce" + integrity sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.1.2, finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatted@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" + integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== + +follow-redirects@^1.0.0: + version "1.14.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.6.tgz#8cfb281bbc035b3c067d6cd975b0f6ade6e855cd" + integrity sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A== + +format-util@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" + integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +fs-extra@^8.0.1, fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-monkey@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" + integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +gettext-extract@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/gettext-extract/-/gettext-extract-2.0.1.tgz#4ade7e3d7c1c247d95a81f28059ca1923c355886" + integrity sha512-k51R90txkCZeXQEDjK0e7gNHfBHJVCu8IQ3AbSVZoOL5nR3yl+C+7qpzp6hoZwOtiniaY+CKeLyvNulsEUM6MA== + dependencies: + chalk "^2.3.0" + find-up "^4.1.0" + fs-extra "^8.0.1" + gettext-extractor "^3.1.0" + minimist "^1.2.0" + +gettext-extractor@^3.1.0: + version "3.5.3" + resolved "https://registry.yarnpkg.com/gettext-extractor/-/gettext-extractor-3.5.3.tgz#6ed46931c154a7485a80fa8b91b835ff7b8d0411" + integrity sha512-9EgJ+hmbtAbATdMIvCj4WnrkeDWH6fv1z+IJJ1XCxdcUMGx6JQdVVFTdzJkSyIHh4td53ngoB5EQbavbKJU9Og== + dependencies: + "@types/glob" "5 - 7" + "@types/parse5" "^5" + css-selector-parser "^1.3" + glob "5 - 7" + parse5 "5 - 6" + pofile "1.0.x" + typescript "2 - 4" + +gettext-parser@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-1.1.0.tgz#2c5a6638d893934b9b55037d0ad82cb7004b2679" + integrity sha1-LFpmONiTk0ubVQN9CtgstwBLJnk= + dependencies: + encoding "^0.1.11" + +gettext.js@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/gettext.js/-/gettext.js-1.1.1.tgz#5644ee7a2cd687e7bbca0f508b75f08aa61eaf17" + integrity sha512-+GlPwSg/rGOVjRRU8kkgP4v6V6t+SulDZrT70D2YntUQVUN8q6TtfNMCa0F3h+QB5y7mvLY52V8MOSipdhrnow== + dependencies: + po2json "^0.4.0" + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +"glob@5 - 7", glob@^7.1.3, glob@^7.1.7: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@7.1.7: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globby@^11.0.1: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + +google-protobuf@3.12.2: + version "3.12.2" + resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.12.2.tgz#50ce9f9b6281235724eb243d6a83e969a2176e53" + integrity sha512-4CZhpuRr1d6HjlyrxoXoocoGFnRYgKULgMtikMddA9ztRyYR59Aondv2FioyxWVamRo0rF2XpYawkTCBEQOSkA== + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6: + version "4.2.8" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" + integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +has-color@~0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + integrity sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488" + integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ== + +html-parse-stringify2@^2: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz#dc5670b7292ca158b7bc916c9a6735ac8872834a" + integrity sha1-3FZwtyksoVi3vJFsmmc1rIhyg0o= + dependencies: + void-elements "^2.0.1" + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + +http-errors@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.5.tgz#d7c30d5d3c90d865b4a2e870181f9d6f22ac7ac5" + integrity sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA== + +http-proxy-middleware@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.1.tgz#7ef3417a479fb7666a571e09966c66a39bd2c15f" + integrity sha512-cfaXRVoZxSed/BmkA7SwBVNI9Kj7HFltaE5rqYOub5kWzWZ+gofV2koVN1j2rMW7pEfSSlCHGJ31xmuyFyfLOg== + dependencies: + "@types/http-proxy" "^1.17.5" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +ignore@^5.1.4: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + +import-local@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.3.tgz#4d51c2c495ca9393da259ec66b62e022920211e0" + integrity sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imports-loader@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-3.1.1.tgz#3e464d9aad1e303b1b34b658eb8f8aae22f96435" + integrity sha512-3QMyGU4RTgxLf0puWkUfT5+7zJvexvB00PI5skDIcxG8O20gZCbQsaRpNBv+cIO6yy/lmlOBwaxc3uH1CV+sww== + dependencies: + source-map "^0.6.1" + strip-comments "^2.0.1" + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + +ip@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-core-module@^2.2.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" + integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-cwd@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-regex@^1.0.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isbinaryfile@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.8.tgz#5d34b94865bd4946633ecc78a026fc76c5b11fcf" + integrity sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +jest-worker@^27.4.1: + version "27.4.5" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.5.tgz#d696e3e46ae0f24cff3fa7195ffba22889262242" + integrity sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jquery@^3.5.1: + version "3.6.0" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470" + integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw== + +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +karma-chrome-launcher@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz#805a586799a4d05f4e54f72a204979f3f3066738" + integrity sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg== + dependencies: + which "^1.2.1" + +karma-mocha@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-2.0.1.tgz#4b0254a18dfee71bdbe6188d9a6861bf86b0cd7d" + integrity sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ== + dependencies: + minimist "^1.2.3" + +karma-sourcemap-loader@0.3.8: + version "0.3.8" + resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.8.tgz#d4bae72fb7a8397328a62b75013d2df937bdcf9c" + integrity sha512-zorxyAakYZuBcHRJE+vbrK2o2JXLFWK8VVjiT/6P+ltLBUGUvqTEkUiQ119MGdOrK7mrmxXHZF1/pfT6GgIZ6g== + dependencies: + graceful-fs "^4.1.2" + +karma-webpack@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.0.tgz#2a2c7b80163fe7ffd1010f83f5507f95ef39f840" + integrity sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA== + dependencies: + glob "^7.1.3" + minimatch "^3.0.4" + webpack-merge "^4.1.5" + +karma@6.3.4: + version "6.3.4" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.4.tgz#359899d3aab3d6b918ea0f57046fd2a6b68565e6" + integrity sha512-hbhRogUYIulfkBTZT7xoPrCYhRBnBoqbbL4fszWD0ReFGUxU+LYBr3dwKdAluaDQ/ynT9/7C+Lf7pPNW4gSx4Q== + dependencies: + body-parser "^1.19.0" + braces "^3.0.2" + chokidar "^3.5.1" + colors "^1.4.0" + connect "^3.7.0" + di "^0.0.1" + dom-serialize "^2.2.1" + glob "^7.1.7" + graceful-fs "^4.2.6" + http-proxy "^1.18.1" + isbinaryfile "^4.0.8" + lodash "^4.17.21" + log4js "^6.3.0" + mime "^2.5.2" + minimatch "^3.0.4" + qjobs "^1.2.0" + range-parser "^1.2.1" + rimraf "^3.0.2" + socket.io "^3.1.0" + source-map "^0.6.1" + tmp "^0.2.1" + ua-parser-js "^0.7.28" + yargs "^16.1.1" + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +kvision-assets@^5.0.7: + version "5.0.7" + resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-5.0.7.tgz#e6dc3e28a2d244b4c89318b060d3e7e337c15495" + integrity sha512-szoL8ixFRTivLkbnmkWFjGJMk3bsUW/loUS5QfWThPwFnyFEw8ht3eBUrJ0V51Rn/WaJbVoPvY4SfIaiNu13bg== + +loader-runner@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" + integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log4js@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.3.0.tgz#10dfafbb434351a3e30277a00b9879446f715bcb" + integrity sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw== + dependencies: + date-format "^3.0.0" + debug "^4.1.1" + flatted "^2.0.1" + rfdc "^1.1.4" + streamroller "^2.2.4" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +memfs@^3.2.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.0.tgz#8bc12062b973be6b295d4340595736a656f0a257" + integrity sha512-o/RfP0J1d03YwsAxyHxAYs2kyJp55AFkMazlFAZFR2I2IXkxiUTXRabJ6RmNNCQ83LAD2jy52Khj0m3OffpNdA== + dependencies: + fs-monkey "1.0.3" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +mime-db@1.51.0, "mime-db@>= 1.43.0 < 2": + version "1.51.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" + integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== + +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24: + version "2.1.34" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" + integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== + dependencies: + mime-db "1.51.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.5.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@3.0.4, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mkdirp@^0.5.5: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mocha@9.1.2: + version "9.1.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.2.tgz#93f53175b0f0dc4014bd2d612218fccfcf3534d3" + integrity sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.2" + debug "4.3.2" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.1.7" + growl "1.10.5" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "3.0.4" + ms "2.1.3" + nanoid "3.1.25" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + workerpool "6.1.5" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + +nanoid@3.1.25: + version "3.1.25" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" + integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== + +nanoid@^3.1.30: + version "3.1.30" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362" + integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ== + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +node-forge@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" + integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== + +node-releases@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" + integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== + +nomnom@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" + integrity sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc= + dependencies: + chalk "~0.4.0" + underscore "~1.6.0" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +object-assign@^4: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@^8.0.9: + version "8.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" + integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-retry@^4.5.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c" + integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA== + dependencies: + "@types/retry" "^0.12.0" + retry "^0.13.1" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +"parse5@5 - 6": + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +po2json@^0.4.0: + version "0.4.5" + resolved "https://registry.yarnpkg.com/po2json/-/po2json-0.4.5.tgz#47bb2952da32d58a1be2f256a598eebc0b745118" + integrity sha1-R7spUtoy1Yob4vJWpZjuvAt0URg= + dependencies: + gettext-parser "1.1.0" + nomnom "1.8.1" + +pofile@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.0.11.tgz#35aff58c17491d127a07336d5522ebc9df57c954" + integrity sha512-Vy9eH1dRD9wHjYt/QqXcTz+RnX/zg53xK+KljFSX30PvdDMb2z+c6uDUeblUGqqJgz3QFsdlA0IJvHziPmWtQg== + +portfinder@^1.0.28: + version "1.0.28" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" + integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.5" + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.8" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.8.tgz#f023ed7a9ea736cd7ef70342996e8e78645a7914" + integrity sha512-D5PG53d209Z1Uhcc0qAZ5U3t5HagH3cxu+WLZ22jt3gLUpXM4eXXfiO14jiDWST3NNooX/E8wISfOhZ9eIjGTQ== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.2.15: + version "8.4.5" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95" + integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg== + dependencies: + nanoid "^3.1.30" + picocolors "^1.0.0" + source-map-js "^1.0.1" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qjobs@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + +qs@6.9.6: + version "6.9.6" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" + integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32" + integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ== + dependencies: + bytes "3.1.1" + http-errors "1.8.1" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readable-stream@^2.0.1: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" + integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== + dependencies: + resolve "^1.9.0" + +regexp.prototype.flags@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" + integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve@^1.9.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rfdc@^1.1.4: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +schema-utils@^3.1.0, schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" + integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.8.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.0.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + +selfsigned@^1.10.11: + version "1.10.11" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.11.tgz#24929cd906fe0f44b6d01fb23999a739537acbe9" + integrity sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA== + dependencies: + node-forge "^0.10.0" + +semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +send@0.17.2: + version "0.17.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" + integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "1.8.1" + mime "1.6.0" + ms "2.1.3" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serialize-javascript@6.0.0, serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.14.2: + version "1.14.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" + integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.2" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.3: + version "3.0.6" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" + integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +snabbdom@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.2.0.tgz#8ea6b2517739a7d9ca82df3f181d052adf1ca5ad" + integrity sha512-UWyfm8WbaFmbmYLC33pe5fawBfExhynkMDoZqQ8ehlHDwkxrgIOpWhKf5PaacLUW1n+Uwu5N5HND6mESU7cMlw== + +socket.io-adapter@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz#edc5dc36602f2985918d631c1399215e97a1b527" + integrity sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg== + +socket.io-parser@~4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0" + integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g== + dependencies: + "@types/component-emitter" "^1.2.10" + component-emitter "~1.3.0" + debug "~4.3.1" + +socket.io@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-3.1.2.tgz#06e27caa1c4fc9617547acfbb5da9bc1747da39a" + integrity sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw== + dependencies: + "@types/cookie" "^0.4.0" + "@types/cors" "^2.8.8" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.1" + engine.io "~4.1.0" + socket.io-adapter "~2.1.0" + socket.io-parser "~4.0.3" + +sockjs@^0.3.21: + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + +source-map-js@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" + integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== + +source-map-js@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf" + integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA== + +source-map-loader@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.0.tgz#f2a04ee2808ad01c774dea6b7d2639839f3b3049" + integrity sha512-GKGWqWvYr04M7tn8dryIWvb0s8YM41z82iQv01yBtIylgxax0CwvSy6gc2Y02iuXwEfGWRlMicH0nvms9UZphw== + dependencies: + abab "^2.0.5" + iconv-lite "^0.6.2" + source-map-js "^0.6.2" + +source-map-support@0.5.20: + version "0.5.20" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" + integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +split.js@^1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/split.js/-/split.js-1.6.4.tgz#13d47cba53382adef230a53294ce5dacb2a2f2e1" + integrity sha512-kYmQZprRJrF1IOjg/E+gdBEsKFv5kbgUE6RJVJZvrIzTOK/IHzKSqIeiJnWs7IP5D9TnpTQ2CbanuDuIWcyDUQ== + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +streamroller@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-2.2.4.tgz#c198ced42db94086a6193608187ce80a5f2b0e53" + integrity sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ== + dependencies: + date-format "^2.1.0" + debug "^4.1.1" + fs-extra "^8.1.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" + integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== + dependencies: + ansi-regex "^6.0.1" + +strip-ansi@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" + integrity sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE= + +strip-comments@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" + integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +style-loader@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" + integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== + +supports-color@8.1.1, supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +terser-webpack-plugin@^5.1.3: + version "5.3.0" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz#21641326486ecf91d8054161c816e464435bae9f" + integrity sha512-LPIisi3Ol4chwAaPP8toUJ3L4qCM1G0wao7L3qNv57Drezxj6+VEyySpPw4B1HSO2Eg/hDY/MNF5XihCAoqnsQ== + dependencies: + jest-worker "^27.4.1" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + source-map "^0.6.1" + terser "^5.7.2" + +terser@^5.7.2: + version "5.10.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc" + integrity sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA== + dependencies: + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.20" + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +"typescript@2 - 4": + version "4.5.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" + integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== + +typescript@3.9.5: + version "3.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" + integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== + +ua-parser-js@^0.7.28: + version "0.7.31" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" + integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== + +underscore@~1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" + integrity sha1-izixDKze9jM3uLJOT/htRa6lKag= + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +void-elements@^2.0.0, void-elements@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= + +watchpack@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25" + integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webpack-cli@4.9.1: + version "4.9.1" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3" + integrity sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.1.0" + "@webpack-cli/info" "^1.4.0" + "@webpack-cli/serve" "^1.6.0" + colorette "^2.0.14" + commander "^7.0.0" + execa "^5.0.0" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + webpack-merge "^5.7.3" + +webpack-dev-middleware@^5.2.1: + version "5.3.0" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.0.tgz#8fc02dba6e72e1d373eca361623d84610f27be7c" + integrity sha512-MouJz+rXAm9B1OTOYaJnn6rtD/lWZPy2ufQCH3BPs8Rloh/Du6Jze4p7AeLYHkVi0giJnYLaSGDC7S+GM9arhg== + dependencies: + colorette "^2.0.10" + memfs "^3.2.2" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.6.0.tgz#e8648601c440172d9b6f248d28db98bed335315a" + integrity sha512-oojcBIKvx3Ya7qs1/AVWHDgmP1Xml8rGsEBnSobxU/UJSX1xP1GPM3MwsAnDzvqcVmVki8tV7lbcsjEjk0PtYg== + dependencies: + ansi-html-community "^0.0.8" + bonjour "^3.5.0" + chokidar "^3.5.2" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + default-gateway "^6.0.3" + del "^6.0.0" + express "^4.17.1" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.0" + ipaddr.js "^2.0.1" + open "^8.0.9" + p-retry "^4.5.0" + portfinder "^1.0.28" + schema-utils "^4.0.0" + selfsigned "^1.10.11" + serve-index "^1.9.1" + sockjs "^0.3.21" + spdy "^4.0.2" + strip-ansi "^7.0.0" + url "^0.11.0" + webpack-dev-middleware "^5.2.1" + ws "^8.1.0" + +webpack-merge@^4.1.5: + version "4.2.2" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" + integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== + dependencies: + lodash "^4.17.15" + +webpack-merge@^5.7.3: + version "5.8.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" + integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + +webpack-sources@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.2.tgz#d88e3741833efec57c4c789b6010db9977545260" + integrity sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw== + +webpack@5.64.4: + version "5.64.4" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.64.4.tgz#e1454b6a13009f57cc2c78e08416cd674622937b" + integrity sha512-LWhqfKjCLoYJLKJY8wk2C3h77i8VyHowG3qYNZiIqD6D0ZS40439S/KVuc/PY48jp2yQmy0mhMknq8cys4jFMw== + dependencies: + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.50" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.4.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.8.3" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.4" + json-parse-better-errors "^1.0.2" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.3.0" + webpack-sources "^3.2.2" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +which@2.0.2, which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +which@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wildcard@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" + integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== + +workerpool@6.1.5: + version "6.1.5" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" + integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@^8.1.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.4.0.tgz#f05e982a0a88c604080e8581576e2a063802bed6" + integrity sha512-IHVsKe2pjajSUIl4KYMQOdlyliovpEPquKkqbwswulszzI7r0SfQrxnXdWAEqOlDCLrVSJzo+O1hAwdog2sKSQ== + +ws@~7.4.2: + version "7.4.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0, yargs@^16.1.1: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index ad6a372..729a5e1 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -22,7 +22,7 @@ kotlin { optIn("kotlin.RequiresOptIn") optIn("kotlin.ExperimentalStdlibApi") optIn("kotlin.time.ExperimentalTime") - optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") +// optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") optIn("kotlinx.serialization.ExperimentalSerializationApi") optIn("kotlin.js.ExperimentalJsExport") } diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index eee876e..36e61b7 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -6,8 +6,8 @@ plugins { id("dev.adamko.kafkatorio.infra.docker-compose") } -val srcDir: Directory by extra -val factorioServerDataDir: Directory = srcDir.dir("factorio-server") +val dockerSrcDir: Directory by extra +val factorioServerDataDir: Directory = dockerSrcDir.dir("factorio-server") val factorioMod: Configuration by configurations.creating { asConsumer() diff --git a/modules/infra-kafka-connect/build.gradle.kts b/modules/infra-kafka-connect/build.gradle.kts index 11a0ca9..2899214 100644 --- a/modules/infra-kafka-connect/build.gradle.kts +++ b/modules/infra-kafka-connect/build.gradle.kts @@ -1,15 +1,15 @@ +@file:Suppress("UnstableApiUsage") // VERSION_PLATFORM + platform(...) is unstable + import dev.adamko.kafkatorio.gradle.asConsumer -import dev.adamko.kafkatorio.jsonMapper -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.contentOrNull -import kotlinx.serialization.json.jsonArray -import kotlinx.serialization.json.jsonObject -import kotlinx.serialization.json.jsonPrimitive plugins { id("dev.adamko.kafkatorio.infra.docker-compose") + id("dev.adamko.kafkatorio.lang.kotlin-jvm") } +val dockerSrcDir: Directory by extra(layout.projectDirectory.dir("src/main/docker")) +val connectorJarDir: Directory = dockerSrcDir.dir("camel-kafka-connectors") + val camelConnectorDependencies: Configuration by configurations.creating { asConsumer() } fun DependencyHandlerScope.kafkaConnector( @@ -23,11 +23,19 @@ fun DependencyHandlerScope.kafkaConnector( dependencies { kafkaConnector("camel-websocket-kafka-connector") kafkaConnector("camel-ahc-ws-kafka-connector") + + implementation("com.github.adamko-dev:json5-kotlin:2.0.3") + + implementation(platform(libs.http4k.bom)) + implementation("org.http4k:http4k-core") + implementation("org.http4k:http4k-client-okhttp") + + implementation(platform(libs.kotlinx.serialization.bom)) + implementation("org.jetbrains.kotlinx:kotlinx-serialization-core") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json") } -val connectorJarDir: Directory = layout.projectDirectory.dir("src/camel-kafka-connectors") - val downloadCamelConnectors by tasks.registering(Sync::class) { group = project.name description = "Retrieve Camel Kafka Connectors from Maven, in preparation for the Docker build" @@ -44,7 +52,6 @@ val downloadCamelConnectors by tasks.registering(Sync::class) { into(connectorJarDir) } - tasks.dockerUp { dependsOn(":modules:infra-kafka-cluster:dockerUp") dependsOn(downloadCamelConnectors) @@ -56,72 +63,3 @@ tasks.dockerEnv { "KAFKA_CONNECT_VERSION" to libs.versions.confluent.kafkaConnect.get(), ) } - - -val availableCamelVersions by tasks.registering { - // dicking around with some sort of 'all camel connectors' docker image. - // it's unfinished. - - val camelGroup = "org.apache.camel.kafkaconnector" - val camelParent = "connectors" - - val requestUrl = """ - https://search.maven.org/solrsearch/select?q=g:"$camelGroup"+AND+a:"$camelParent"&core=gav&rows=20&wt=json - """.trimIndent() - .replace("\"", "%22") - - doLast { - - val connectorVersions = java.net.URL(requestUrl).readText() - logger.lifecycle("conn ==== $connectorVersions") - val versionsJson = jsonMapper.parseToJsonElement(connectorVersions).jsonObject - - logger.lifecycle("json ==== \n ${jsonMapper.encodeToString(versionsJson)}") - - val deps = versionsJson["response"] - ?.jsonObject - ?.get("docs") - ?.jsonArray - ?.map { it.jsonObject } - ?.mapNotNull { j -> - val group = j["g"]?.jsonPrimitive?.contentOrNull - val artifact = j["a"]?.jsonPrimitive?.contentOrNull - val version = j["v"]?.jsonPrimitive?.contentOrNull - val packaging = j["p"]?.jsonPrimitive?.contentOrNull?.toLowerCase() - - if (listOf(group, artifact, version, packaging).all { it != null }) { - val d = project.dependencies.create( - group = group!!, - name = artifact!!, - version = version!!, - ext = packaging, - ) - logger.lifecycle("dep = $d / $packaging") - d - } else { - null - } - } ?: emptyList() - - val c = configurations.detachedConfiguration() - c.dependencies.addAll(deps) - c.resolve() - .joinToString("\n\n---\n\n") { it.readLines().take(5).joinToString("\n") } - -// logger.lifecycle("ids: ${versions?.joinToString("\n", "\n\n", "\n\n")}") -// -// versions?.filterNotNull()?.forEach { id -> -// -// configurations.detachedConfiguration( -// project.dependencies.create(id) -// ) -// .resolve() -// .joinToString("\n\n---\n\n") { it.readLines().take(5).joinToString("\n") } -// -// } - - -// jsonMapper.parseToJsonElement() - - } -} diff --git a/modules/infra-kafka-connect/src/.env b/modules/infra-kafka-connect/src/main/docker/.env similarity index 100% rename from modules/infra-kafka-connect/src/.env rename to modules/infra-kafka-connect/src/main/docker/.env diff --git a/modules/infra-kafka-connect/src/.gitignore b/modules/infra-kafka-connect/src/main/docker/.gitignore similarity index 100% rename from modules/infra-kafka-connect/src/.gitignore rename to modules/infra-kafka-connect/src/main/docker/.gitignore diff --git a/modules/infra-kafka-connect/src/docker-compose.yml b/modules/infra-kafka-connect/src/main/docker/docker-compose.yml similarity index 100% rename from modules/infra-kafka-connect/src/docker-compose.yml rename to modules/infra-kafka-connect/src/main/docker/docker-compose.yml diff --git a/modules/infra-kafka-connect/src/kafka-connect.Dockerfile b/modules/infra-kafka-connect/src/main/docker/kafka-connect.Dockerfile similarity index 100% rename from modules/infra-kafka-connect/src/kafka-connect.Dockerfile rename to modules/infra-kafka-connect/src/main/docker/kafka-connect.Dockerfile diff --git a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/kafkaConnectAdmin.kt b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/kafkaConnectAdmin.kt new file mode 100644 index 0000000..a34e265 --- /dev/null +++ b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/kafkaConnectAdmin.kt @@ -0,0 +1,51 @@ +package dev.adamko.kafkatorio.kafkaconnect + +import at.syntaxerror.json5.Json5Module +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject + +import kotlinx.serialization.json.Json + +val jsonMapper = Json { + prettyPrint = true + prettyPrintIndent = " " +} + +val j5 = Json5Module() + +//val updateConnectors by tasks.registering { +// group = project.name +// +// val configFile = layout.projectDirectory.file("configs/websocket-sink-lua-topics.json5") +// inputs.file(configFile) +// +// doLast { +// val fileText = resources.text.fromFile(configFile) +// +// val jsonObject: JsonObject = j5.decodeObject(fileText.asString()) +// +// logger.lifecycle("out: $jsonObject") +// val configJson = jsonMapper.encodeToString(jsonObject) +// logger.lifecycle("configJson: $configJson") +// +// val request = Request( +// PUT, +// Uri.of("http://localhost:8083").path("/connectors/kafkatorio-ws-connector/config") +// ).header("Content-Type", "application/json") +// .body(configJson) +// +// +// val client = OkHttp() +// val response = client(request) +// +// println(response.toMessage()) +// println( +// jsonMapper.encodeToString( +// jsonMapper.decodeFromString(response.body.toString()) +// ) +// ) +// } +// +//} diff --git a/modules/infra-kafka-connect/src/main/resources/configs/websocket-sink-lua-topics.json5 b/modules/infra-kafka-connect/src/main/resources/configs/websocket-sink-lua-topics.json5 new file mode 100644 index 0000000..8fc8556 --- /dev/null +++ b/modules/infra-kafka-connect/src/main/resources/configs/websocket-sink-lua-topics.json5 @@ -0,0 +1,64 @@ +//Exchange data with external Websocket servers using Async Http Client +{ + name: "CKC-async-ws-lua-objects", + "connector.class": "org.apache.camel.kafkaconnector.ahcws.CamelAhcwsSinkConnector", + "tasks.max": 1, + //use the kafka converters that better suit your needs, these are just defaults: + "key.converter": "org.apache.kafka.connect.storage.StringConverter", + "value.converter": "org.apache.kafka.connect.storage.StringConverter", + //https://docs.confluent.io/platform/current/installation/configuration/connect/sink-connect-configs.html#sinkconnectorconfigs_topics + //List of topics to consume, separated by commas + // topics= + "topics.regex": "^Lua.*$", + + // mandatory properties (for a complete properties list see the connector documentation): + + // The URI to use such as http://hostname:port/path + "camel.sink.path.httpUri": "http://localhost:/ws", + // If the option is true, then the Exchange.HTTP_URI header is ignored, and use the endpoint's URI for request. You may also set the throwExceptionOnFailure to be false to let the AhcProducer send all the fault response back. + // camel.sink.endpoint.bridgeEndpoint= + // The initial in-memory buffer size used when transferring data between Camel and AHC Client. + // camel.sink.endpoint.bufferSize= + // To use a custom HeaderFilterStrategy to filter header to and from Camel message. + // camel.sink.endpoint.headerFilterStrategy= + // Option to disable throwing the AhcOperationFailedException in case of failed responses from the remote server. This allows you to get all responses regardless of the HTTP status code. + // camel.sink.endpoint.throwExceptionOnFailure= + // If enabled and an Exchange failed processing on the consumer side, and if the caused Exception was send back serialized in the response as a application\/x-java-serialized-object content type (for example using Jetty or Servlet Camel components). On the producer side the exception will be deserialized and thrown as is, instead of the AhcOperationFailedException. The caused exception is required to be serialized. This is by default turned off. If you enable this then be aware that Java will deserialize the incoming data from the request to Java and that can be a potential security risk. + // camel.sink.endpoint.transferException= + // Define if the Connection Close header has to be added to HTTP Request. This parameter is false by default + // camel.sink.endpoint.connectionClose= + // Configure a cookie handler to maintain a HTTP session + // camel.sink.endpoint.cookieHandler= + // Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and starting the producer may take a little time and prolong the total processing time of the processing. + // camel.sink.endpoint.lazyStartProducer= + // To enable streaming to send data as multiple text fragments. + // camel.sink.endpoint.useStreaming= + // To use a custom AhcBinding which allows to control how to bind between AHC and Camel. + // camel.sink.endpoint.binding= + // To configure the AsyncHttpClient to use a custom com.ning.http.client.AsyncHttpClientConfig instance. + // camel.sink.endpoint.clientConfig= + // To configure the AsyncHttpClientConfig using the key\/values from the Map. + // camel.sink.endpoint.clientConfigOptions= + // To configure the AsyncHttpClientConfig Realm using the key\/values from the Map. + // camel.sink.endpoint.clientConfigRealmOptions= + // Reference to a org.apache.camel.support.jsse.SSLContextParameters in the Registry. This reference overrides any configured SSLContextParameters at the component level. See Using the JSSE Configuration Utility. Note that configuring this option will override any SSL\/TLS configuration options provided through the clientConfig option at the endpoint or component level. + // camel.sink.endpoint.sslContextParameters= + // Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and starting the producer may take a little time and prolong the total processing time of the processing. + // camel.component.ahc-ws.lazyStartProducer= + // Whether to allow java serialization when a request uses context-type=application\/x-java-serialized-object This is by default turned off. If you enable this then be aware that Java will deserialize the incoming data from the request to Java and that can be a potential security risk. + // camel.component.ahc-ws.allowJavaSerializedObject= + // Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching type, which then gets configured on the component. This can be used for automatic configuring JDBC data sources, JMS connection factories, AWS Clients, etc. + // camel.component.ahc-ws.autowiredEnabled= + // To use a custom AhcBinding which allows to control how to bind between AHC and Camel. + // camel.component.ahc-ws.binding= + // To use a custom AsyncHttpClient + // camel.component.ahc-ws.client= + // To configure the AsyncHttpClient to use a custom com.ning.http.client.AsyncHttpClientConfig instance. + // camel.component.ahc-ws.clientConfig= + // To use a custom org.apache.camel.spi.HeaderFilterStrategy to filter header to and from Camel message. + // camel.component.ahc-ws.headerFilterStrategy= + // Reference to a org.apache.camel.support.jsse.SSLContextParameters in the Registry. Note that configuring this option will override any SSL\/TLS configuration options provided through the clientConfig option at the endpoint or component level. + // camel.component.ahc-ws.sslContextParameters= + // Enable usage of global SSL context parameters. + // camel.component.ahc-ws.useGlobalSslContextParameters= +} diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 5fd09db..bef04c4 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -59,7 +59,7 @@ kotlin { ) ) - implementation(npm("kafkajs", "1.15.0")) +// implementation(npm("kafkajs", "1.15.0")) } val webDir = file("src/main/web") From 7e134b535384a70f607a08cd3b6c5aede7e69e7a Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 22 Dec 2021 23:01:24 +0100 Subject: [PATCH 100/629] - use kotlin-js convention buildsrc plugin - move yarn-lock --- buildSrc/build.gradle.kts | 2 +- .../kafkatorio/lang/kotlin-js.gradle.kts | 23 ++++++++----------- .../kotlin-js-store}/yarn.lock | 0 modules/events-schema/build.gradle.kts | 2 +- modules/web-map/build.gradle.kts | 11 ++------- 5 files changed, 13 insertions(+), 25 deletions(-) rename {kotlin-js-store => gradle/kotlin-js-store}/yarn.lock (100%) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 2687fad..dc26678 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -40,7 +40,7 @@ tasks.withType().configureEach { "-Xopt-in=kotlin.RequiresOptIn", "-Xopt-in=kotlin.ExperimentalStdlibApi", "-Xopt-in=kotlin.time.ExperimentalTime", -// "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", "-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi", ) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts index fa6b191..62c6d7b 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts @@ -1,31 +1,19 @@ package dev.adamko.kafkatorio.lang -import org.gradle.kotlin.dsl.kotlin import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask +import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension plugins { kotlin("js") id("dev.adamko.kafkatorio.base") - id("dev.adamko.kafkatorio.lang.node") -} - -// not in use at the moment - -kotlin { - js(IR) { - binaries.executable() - - useCommonJs() - nodejs() - } } dependencies { val kotlinWrappersVersion = "0.0.1-pre.276-kotlin-1.6.0" implementation( - project.dependencies.enforcedPlatform( + project.dependencies.platform( "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" ) ) @@ -53,3 +41,10 @@ val nodeModulesDir: Directory by extra { logger.lifecycle("Kotlin/JS NODE_MODULES: $file") file } + +rootProject.extensions.configure { + // kotlin-js adds a directory in the root-dir for the Yarn lock. + // That's a bit annoying. It's a little neater if it's in the + // gradle dir, next to the version-catalog. + lockFileDirectory = rootProject.rootDir.resolve("gradle/kotlin-js-store") +} diff --git a/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock similarity index 100% rename from kotlin-js-store/yarn.lock rename to gradle/kotlin-js-store/yarn.lock diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index 729a5e1..ad6a372 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -22,7 +22,7 @@ kotlin { optIn("kotlin.RequiresOptIn") optIn("kotlin.ExperimentalStdlibApi") optIn("kotlin.time.ExperimentalTime") -// optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") + optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") optIn("kotlinx.serialization.ExperimentalSerializationApi") optIn("kotlin.js.ExperimentalJsExport") } diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index bef04c4..74c5e4b 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -1,9 +1,9 @@ import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig plugins { - id("dev.adamko.kafkatorio.base") + id("dev.adamko.kafkatorio.lang.kotlin-js") kotlin("plugin.serialization") - kotlin("js") // version kotlinVersion +// kotlin("js") // version kotlinVersion id("io.kvision") version "5.6.1" } @@ -52,13 +52,6 @@ kotlin { implementation("io.kvision:kvision-state:$kvisionVersion") implementation("io.kvision:kvision-chart:$kvisionVersion") - val kotlinWrappersVersion = "0.0.1-pre.276-kotlin-1.6.0" - implementation( - project.dependencies.enforcedPlatform( - "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" - ) - ) - // implementation(npm("kafkajs", "1.15.0")) } From 4732a66f874d2db6b00d0895bce1b377a9d53080 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 22 Dec 2021 23:25:16 +0100 Subject: [PATCH 101/629] - version bump to 0.1.4 - update some node deps versions - get Factorio event names programmatically --- build.gradle.kts | 2 +- .../events-mod/src/main/typescript/events.ts | 30 ++++++++----------- .../src/main/typescript/package-lock.json | 18 +++++------ .../src/main/typescript/package.json | 6 ++-- modules/web-map/build.gradle.kts | 1 - 5 files changed, 26 insertions(+), 31 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index dac00c0..9c4671e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.1.3" +version = "0.1.4" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/src/main/typescript/events.ts b/modules/events-mod/src/main/typescript/events.ts index f09773c..e9e071f 100644 --- a/modules/events-mod/src/main/typescript/events.ts +++ b/modules/events-mod/src/main/typescript/events.ts @@ -68,22 +68,25 @@ function emitEvent(eventData: T, tick: uint, event script.on_event( defines.events.on_player_mined_entity, (e: OnPlayerMinedEntityEvent) => { - handlePlayerUpdate(e.tick, e.player_index, "on_player_mined_entity") - handleEntityUpdate(e.tick, e.entity, "on_player_mined_entity") + let eventName = mapEventIdToName.get(e.name) + handlePlayerUpdate(e.tick, e.player_index, eventName) + handleEntityUpdate(e.tick, e.entity, eventName) } ) + script.on_event( defines.events.on_player_joined_game, (e: OnPlayerJoinedGameEvent) => { - handlePlayerUpdate(e.tick, e.player_index, "on_player_joined_game") + let eventName = mapEventIdToName.get(e.name) + handlePlayerUpdate(e.tick, e.player_index, eventName) } ) script.on_event( defines.events.on_player_changed_position, - // this is actually a character update, not a player update? (e: OnPlayerChangedPositionEvent) => { - handlePlayerUpdate(e.tick, e.player_index, "on_player_changed_position") + let eventName = mapEventIdToName.get(e.name) + handlePlayerUpdate(e.tick, e.player_index, eventName) } ) @@ -92,21 +95,14 @@ script.on_event( (e: OnTickEvent) => { if (e.tick % 60 == 0) { - for (const [index, _] of pairs(game.surfaces)) { - let s = game.get_surface(index) // TODO fix / report can't iterate over surfaces - // let surface = game.surfaces[index] - if (s != undefined) { - surfaceEvent(e.tick, s, mapEventIdToName.get(e.name)) + let surface = game.get_surface(index) // TODO fix / report can't iterate over surfaces + if (surface != undefined) { + surfaceEvent(e.tick, surface, mapEventIdToName.get(e.name)) } - // surfaceEvent(e.tick, surface, "on_tick") + // let surface = game.surfaces[index] + // surfaceEvent(e.tick, surface, mapEventIdToName.get(e.name)) } - - // let filename: string = table.concat([entity.unit_number, eventType, tick], "_") - // let msg = "test mod tick: " + e.tick + "\n" - // game.write_file("tick.log", msg, true, SERVER_ID) - // let filename: string = `OnTickEvent/${e.tick}` - // outputEvent(filename, e) } } ); diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index 14b1fa0..fddf787 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -74,19 +74,19 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.13.0.tgz", - "integrity": "sha512-a6z8pciAtBQ+FXMJYUI1YqL/zhtFeEW2370rpuxZSaP6RdfWpZ98Vu8Hl19t98h+ULLXnmWsC/g6OW/TJcLbAQ==" + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.14.0.tgz", + "integrity": "sha512-9T9z7S3vmFbl2EHIHzAUEmujxkuAMWGe+DXDNLgVXewIgR1gx6REh7iy+qHtivzzDLq0XOjHQGTUibhNSONAig==" }, "typescript": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", - "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==" + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", + "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==" }, "typescript-to-lua": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.2.0.tgz", - "integrity": "sha512-hbAagI6DgP4MjaPKqGlxtiD/rsZE5hO9ypIz96xukKIjzxp5c/TSItik0BMriX5yIIhRiYLfyAQBp+X1cO8MkQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.3.0.tgz", + "integrity": "sha512-hFjZ7+Cv08WUql2VJChOEb1JH2nqYspyjw+9Og0cDLkP0QaEmM+Eh/slO2exdngDyQye/rrQysLy3zVzJe+PVg==", "requires": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index a1150ee..11dd9b2 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -13,9 +13,9 @@ "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", - "typescript-to-lua": "1.2.0", - "typed-factorio": "0.13.0", - "typescript": "4.5.2" + "typescript-to-lua": "1.3.0", + "typed-factorio": "0.14.0", + "typescript": "4.5.4" }, "license": "UNLICENSED", "peerDependencies": {}, diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 74c5e4b..16522c2 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -52,7 +52,6 @@ kotlin { implementation("io.kvision:kvision-state:$kvisionVersion") implementation("io.kvision:kvision-chart:$kvisionVersion") -// implementation(npm("kafkajs", "1.15.0")) } val webDir = file("src/main/web") From 427b8951d321eb8b56fae2bcaba85449f9707426 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 23 Dec 2021 21:35:14 +0100 Subject: [PATCH 102/629] factorio version bump --- build.gradle.kts | 2 +- gradle/libs.versions.toml | 2 +- .../src/main/typescript/package-lock.json | 6 +++--- .../events-mod/src/main/typescript/package.json | 16 ++++++++++------ modules/infra-factorio-server/src/.env | 2 +- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9c4671e..a28bcdc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.1.4" +version = "0.1.5" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fe50e09..594f23d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,7 +23,7 @@ junit = "5.8.2" kotest = "5.0.1" ## infra ## -factorio = "1.1.49" +factorio = "1.1.50" confluent-kafkaConnect = "7.0.0" ######### diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index fddf787..fd6ba9b 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -74,9 +74,9 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.14.0.tgz", - "integrity": "sha512-9T9z7S3vmFbl2EHIHzAUEmujxkuAMWGe+DXDNLgVXewIgR1gx6REh7iy+qHtivzzDLq0XOjHQGTUibhNSONAig==" + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.14.1.tgz", + "integrity": "sha512-0ot54PB1/bvSz2dENYh2pdQSdGgBuxD4ZxRVBlp8R1AiurbU2yqRvn8JPX5oOMcJjRGHqnO8g0m4R3fRwI8qvQ==" }, "typescript": { "version": "4.5.4", diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 11dd9b2..7a9829d 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.1.3", + "version": "0.1.5", "private": true, "scripts": { "build": "tstl", @@ -9,16 +9,20 @@ "engines": { "node": ">=10.13.0" }, - "devDependencies": {}, + "devDependencies": { + }, "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", "typescript-to-lua": "1.3.0", - "typed-factorio": "0.14.0", + "typed-factorio": "0.14.1", "typescript": "4.5.4" }, "license": "UNLICENSED", - "peerDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": [] + "peerDependencies": { + }, + "optionalDependencies": { + }, + "bundledDependencies": [ + ] } diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index 69f81c6..9880131 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -FACTORIO_VERSION=1.1.49 +FACTORIO_VERSION=1.1.50 From 83c991842f16838bddc5bf534cd63246013a5771 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 26 Dec 2021 11:02:56 +0100 Subject: [PATCH 103/629] successfully create KC websocket connector (not sure if it works though...) --- gradle/libs.versions.toml | 4 +- modules/infra-kafka-connect/build.gradle.kts | 35 +++++++++++++-- .../src/main/docker/docker-compose.yml | 9 ++-- .../src/main/docker/kafka-connect.Dockerfile | 2 +- .../kafkatorio/kafkaconnect/Resources.kt | 10 +++++ .../kafkaconnect/kafkaConnectAdmin.kt | 45 ++++++++++++++++++- .../configs/websocket-sink-lua-topics.json5 | 2 +- 7 files changed, 94 insertions(+), 13 deletions(-) create mode 100644 modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/Resources.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 594f23d..4b09960 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,7 +10,7 @@ kotlin = "1.6.10" ## libs ## camel-kafkaConnectors = "0.11.0" -http4k = "4.17.4.0" +http4k = "4.17.6.0" kafka = "3.0.0" kotlinx-serialization = "1.3.1" kvision = "5.6.1" @@ -24,7 +24,7 @@ kotest = "5.0.1" ## infra ## factorio = "1.1.50" -confluent-kafkaConnect = "7.0.0" +confluent-kafkaConnect = "7.0.1" ######### [plugins] diff --git a/modules/infra-kafka-connect/build.gradle.kts b/modules/infra-kafka-connect/build.gradle.kts index 2899214..ff2da04 100644 --- a/modules/infra-kafka-connect/build.gradle.kts +++ b/modules/infra-kafka-connect/build.gradle.kts @@ -1,6 +1,7 @@ @file:Suppress("UnstableApiUsage") // VERSION_PLATFORM + platform(...) is unstable import dev.adamko.kafkatorio.gradle.asConsumer +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { id("dev.adamko.kafkatorio.infra.docker-compose") @@ -16,12 +17,13 @@ fun DependencyHandlerScope.kafkaConnector( name: String, group: String = "org.apache.camel.kafkaconnector", version: String = libs.versions.camel.kafkaConnectors.get(), + classifier: String = "package", + extension: String = "tar.gz", ) { - camelConnectorDependencies(group, name, version) + camelConnectorDependencies(group, name, version, ext = extension, classifier = classifier) } dependencies { - kafkaConnector("camel-websocket-kafka-connector") kafkaConnector("camel-ahc-ws-kafka-connector") implementation("com.github.adamko-dev:json5-kotlin:2.0.3") @@ -35,21 +37,46 @@ dependencies { implementation("org.jetbrains.kotlinx:kotlinx-serialization-json") } +val dockerBuildKafkaConnect by tasks.registering(Exec::class) { + group = "docker-compose" + dependsOn(downloadCamelConnectors, tasks.dockerEnv) + + logging.captureStandardOutput(LogLevel.LIFECYCLE) + + inputs.dir(dockerSrcDir) + + workingDir = dockerSrcDir.asFile + commandLine = parseSpaceSeparatedArgs(""" docker-compose build connect """) +} +tasks.assemble { dependsOn(dockerBuildKafkaConnect) } + val downloadCamelConnectors by tasks.registering(Sync::class) { group = project.name description = "Retrieve Camel Kafka Connectors from Maven, in preparation for the Docker build" + dependsOn(camelConnectorDependencies) + from( provider { camelConnectorDependencies } .map { eventsSchema -> eventsSchema.incoming - .artifactView { lenient(true) } .artifacts .artifactFiles } ) - into(connectorJarDir) + into(temporaryDir) + + doLast { + sync { + fileTree(temporaryDir) + .asFileTree + .forEach { zip -> + from(tarTree(zip)) + } + into(connectorJarDir) + } + } } tasks.dockerUp { diff --git a/modules/infra-kafka-connect/src/main/docker/docker-compose.yml b/modules/infra-kafka-connect/src/main/docker/docker-compose.yml index 7833ca4..f44f3af 100644 --- a/modules/infra-kafka-connect/src/main/docker/docker-compose.yml +++ b/modules/infra-kafka-connect/src/main/docker/docker-compose.yml @@ -15,7 +15,8 @@ services: # CAMEL_KC_VERSION: ${CONNECTOR_CAMEL_KAFKA_VERSION} # CAMEL_CONNECTOR: ${CAMEL_FILE_CONNECTOR} ports: - - "28083:28083" + - "8083:8083" + - "8095:8095" # volumes: # - "./connect/input:/warehouse/input" # - "./connect/components:/usr/share/confluent-hub-components" @@ -28,7 +29,8 @@ services: CONNECT_BOOTSTRAP_SERVERS: "kafka:29092" CONNECT_REST_ADVERTISED_HOST_NAME: ${CONNECTOR_ID} # CONNECT_VALUE_CONVERTER_SCHEMA_REGISTRY_URL: "http://${SCHEMA_REGISTRY}:8081" - CONNECT_REST_PORT: 28083 +# CONNECT_REST_PORT: 28083 + CONNECT_REST_PORT: 8083 CONNECT_GROUP_ID: ${CONNECTOR_ID} CONNECT_CONFIG_STORAGE_TOPIC: ${CONNECTOR_ID}-configs CONNECT_CONFIG_STORAGE_REPLICATION_FACTOR: 1 @@ -40,9 +42,10 @@ services: CONNECT_KEY_CONVERTER: "org.apache.kafka.connect.storage.StringConverter" # CONNECT_VALUE_CONVERTER: "io.confluent.connect.avro.AvroConverter" CONNECT_VALUE_CONVERTER: "org.apache.kafka.connect.json.JsonConverter" - CONNECT_PLUGIN_PATH: "/usr/share/java,/usr/share/confluent-hub-components" + CONNECT_PLUGIN_PATH: "/usr/share/java,/usr/share/camel-kafka-connectors" CONNECT_LOG4J_ROOT_LOGLEVEL: INFO CONNECT_LOG4J_LOGGERS: "org.apache.zookeeper=INFO,org.I0Itec.zkclient=ERROR,org.reflections=ERROR" +# CONNECT_LISTENERS: "http://localhost:28083" networks: kafkatorio-nw: diff --git a/modules/infra-kafka-connect/src/main/docker/kafka-connect.Dockerfile b/modules/infra-kafka-connect/src/main/docker/kafka-connect.Dockerfile index 7659554..885c292 100644 --- a/modules/infra-kafka-connect/src/main/docker/kafka-connect.Dockerfile +++ b/modules/infra-kafka-connect/src/main/docker/kafka-connect.Dockerfile @@ -7,7 +7,7 @@ ENV CONNECT_VERSION=${KAFKA_CONNECT_VERSION} USER 0:0 -COPY ./camel-kafka-connectors /usr/share/java/ +COPY ./camel-kafka-connectors /usr/share/camel-kafka-connectors #WORKDIR /usr/share/java/ # diff --git a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/Resources.kt b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/Resources.kt new file mode 100644 index 0000000..0e6406c --- /dev/null +++ b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/Resources.kt @@ -0,0 +1,10 @@ +package dev.adamko.kafkatorio.kafkaconnect + +import java.io.File + +object Resources { + fun loadResource(name: String): File = + File(requireNotNull(Resources::class.java.getResource(name)?.file) { + "could not load resource '$name'" + }) +} diff --git a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/kafkaConnectAdmin.kt b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/kafkaConnectAdmin.kt index a34e265..6a68965 100644 --- a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/kafkaConnectAdmin.kt +++ b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/kafkaConnectAdmin.kt @@ -3,10 +3,15 @@ package dev.adamko.kafkatorio.kafkaconnect import at.syntaxerror.json5.Json5Module import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonObject - -import kotlinx.serialization.json.Json +import kotlinx.serialization.json.jsonPrimitive +import org.http4k.client.OkHttp +import org.http4k.core.Method.GET +import org.http4k.core.Method.PUT +import org.http4k.core.Request +import org.http4k.core.Uri val jsonMapper = Json { prettyPrint = true @@ -15,6 +20,42 @@ val jsonMapper = Json { val j5 = Json5Module() +fun main() { + + val connectorHostUrl = Uri.of("http://localhost:8083") + + val configFile = Resources.loadResource("/configs/websocket-sink-lua-topics.json5") + + val jsonObject: JsonObject = j5.decodeObject(configFile.readText()) + println("json5 connector config: $jsonObject") + val configJson = jsonMapper.encodeToString(jsonObject) + println("json connector config: $configJson") + + val connectorName = jsonObject["name"]!!.jsonPrimitive.content + + val request: Request = + Request(PUT, connectorHostUrl.path("/connectors/$connectorName/config")) + .header("Content-Type", "application/json") + .header("Accept", "application/json") +// .header("Accept-Encoding", "identity") + .body(configJson) + + val client = OkHttp() + + // check the status of KC + val statusResponse = client(Request(GET, connectorHostUrl)) + println(statusResponse.toMessage()) + + val response = client(request) + + println(response.toMessage()) + println( + jsonMapper.encodeToString( + jsonMapper.decodeFromString(response.body.toString()) + ) + ) +} + //val updateConnectors by tasks.registering { // group = project.name // diff --git a/modules/infra-kafka-connect/src/main/resources/configs/websocket-sink-lua-topics.json5 b/modules/infra-kafka-connect/src/main/resources/configs/websocket-sink-lua-topics.json5 index 8fc8556..09963ad 100644 --- a/modules/infra-kafka-connect/src/main/resources/configs/websocket-sink-lua-topics.json5 +++ b/modules/infra-kafka-connect/src/main/resources/configs/websocket-sink-lua-topics.json5 @@ -14,7 +14,7 @@ // mandatory properties (for a complete properties list see the connector documentation): // The URI to use such as http://hostname:port/path - "camel.sink.path.httpUri": "http://localhost:/ws", + "camel.sink.path.httpUri": "http://localhost:8095/ws", // If the option is true, then the Exchange.HTTP_URI header is ignored, and use the endpoint's URI for request. You may also set the throwExceptionOnFailure to be false to let the AhcProducer send all the fault response back. // camel.sink.endpoint.bridgeEndpoint= // The initial in-memory buffer size used when transferring data between Camel and AHC Client. From abada0bf4bc69dd5fc8420355ee79d643566e456 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 26 Dec 2021 22:55:06 +0100 Subject: [PATCH 104/629] mucking about trying to get camel-kafka-connect websockets working --- gradle/libs.versions.toml | 6 ++- .../src/main/typescript/package-lock.json | 2 +- .../src/main/typescript/package.json | 12 ++--- .../main/typescript/schema/events-schema.ts | 3 ++ .../dev/adamko/kafkatorio/processor/main.kt | 5 +- .../events/schema/factorioEvents.kt | 27 +++++++---- .../src/docker-compose.yml | 7 ++- modules/infra-kafka-connect/build.gradle.kts | 5 +- .../src/main/docker/docker-compose.yml | 3 +- .../kafkaconnect/websocketClient.kt | 46 +++++++++++++++++++ .../configs/websocket-sink-lua-topics.json5 | 12 ++++- modules/infra-kafka-pipe/build.gradle.kts | 19 ++++++++ .../src/kafka-pipe.Dockerfile | 2 +- modules/infra-kafka-pipe/src/kafka-pipe.sh | 2 +- 14 files changed, 122 insertions(+), 29 deletions(-) create mode 100644 modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/websocketClient.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4b09960..877b863 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -58,7 +58,8 @@ kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx- http4k-bom = { group = "org.http4k", name = "http4k-bom", version.ref = "http4k" } http4k-core = { group = "org.http4k", name = "http4k-core" } http4k-contract = { group = "org.http4k", name = "http4k-contract" } -http4k-client = { group = "org.http4k", name = "http4k-client-okhttp" } +http4k-client-okhttp = { group = "org.http4k", name = "http4k-client-okhttp" } +http4k-client-ws = { group = "org.http4k", name = "http4k-client-websocket" } http4k-server = { group = "org.http4k", name = "http4k-server-undertow" } http4k-cloudnative = { group = "org.http4k", name = "http4k-cloudnative" } http4k-format-json = { group = "org.http4k", name = "http4k-format-jackson" } @@ -146,7 +147,8 @@ junit-runtime = [ http4k = [ "http4k-core", "http4k-contract", - "http4k-client", + "http4k-client-okhttp", + "http4k-client-ws", "http4k-server", # "http4k-kotlinx", "http4k-cloudnative", diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index fd6ba9b..32fb6ef 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.1.3", + "version": "0.1.5", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 7a9829d..966ac89 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -9,8 +9,7 @@ "engines": { "node": ">=10.13.0" }, - "devDependencies": { - }, + "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", @@ -19,10 +18,7 @@ "typescript": "4.5.4" }, "license": "UNLICENSED", - "peerDependencies": { - }, - "optionalDependencies": { - }, - "bundledDependencies": [ - ] + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] } diff --git a/modules/events-mod/src/main/typescript/schema/events-schema.ts b/modules/events-mod/src/main/typescript/schema/events-schema.ts index 27a14dd..fccd740 100644 --- a/modules/events-mod/src/main/typescript/schema/events-schema.ts +++ b/modules/events-mod/src/main/typescript/schema/events-schema.ts @@ -20,6 +20,7 @@ interface PlayerData extends FactorioObjectData { associated_characters_unit_numbers: uint[]; character_unit_number: uint | null; name: string; + object_name: string; position: PositionData; } @@ -28,6 +29,7 @@ interface EntityData extends FactorioObjectData { health: double | null; health_ratio: double; name: string; + object_name: string; player_index: uint | null; position: PositionData; surface_index: int; @@ -39,4 +41,5 @@ interface SurfaceData extends FactorioObjectData { daytime: double; index: uint; name: string; + object_name: string; } \ No newline at end of file diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt index a6b5ff1..2f899bf 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt @@ -56,7 +56,10 @@ fun main() { // KXS.asA>(value) } .to( - { key, value, recordContext -> value.data.objectName }, + { key, value, recordContext -> +// println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") + value.data.objectName + }, Produced.with(Serdes.String(), JsonSerdes) ) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index 0371d19..f1692b7 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -1,9 +1,9 @@ package dev.adamko.kafkatorio.events.schema -//import kotlin.reflect.full.starProjectedType import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient import kotlinx.serialization.json.JsonClassDiscriminator @@ -34,10 +34,12 @@ const val FactorioObjectDataDiscriminatorKey: String = "object_name" @JsonClassDiscriminator(FactorioObjectDataDiscriminatorKey) sealed class FactorioObjectData { + abstract val objectName: String + // workaround - https://github.com/Kotlin/kotlinx.serialization/issues/1664 - val objectName: String by lazy { - serializer().descriptor.serialName - } +// val objectName: String by lazy { +// serializer().descriptor.serialName +// } // val objectName: String by lazy { // kotlinx.serialization.serializer(this::class.starProjectedType).descriptor.serialName @@ -45,7 +47,7 @@ sealed class FactorioObjectData { // alternative: find the @SerialName annotation // Again it must be delegated so there's no backing field and kxs ignores it -// val objectNameByAnnotation: String by lazy { +// val objectName: String by lazy { // requireNotNull(this::class.findAnnotation()?.value) { // "Couldn't find @SerialName for ${this::class}!" // } @@ -64,7 +66,10 @@ data class PlayerData( val name: String, @SerialName("position") val position: PositionData, -) : FactorioObjectData() +) : FactorioObjectData() { + @Transient + override val objectName: String= "LuaPlayer" +} @Serializable @SerialName("LuaEntity") @@ -88,7 +93,10 @@ data class EntityData( @SerialName("player_index") val playerIndex: UInt? = null, -) : FactorioObjectData() +) : FactorioObjectData() { + @Transient + override val objectName: String= "LuaEntity" +} @Serializable @SerialName("LuaSurface") @@ -99,7 +107,10 @@ data class SurfaceData( val index: UInt, @SerialName("name") val name: String, -) : FactorioObjectData() +) : FactorioObjectData() { + @Transient + override val objectName: String="LuaSurface" +} @Serializable data class PositionData( diff --git a/modules/infra-kafka-cluster/src/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml index 8a4e714..600e071 100644 --- a/modules/infra-kafka-cluster/src/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -28,8 +28,11 @@ services: ports: - "8080:8080" environment: - - KAFKA_CLUSTERS_0_NAME=${COMPOSE_PROJECT_NAME} - - KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka:29092 + KAFKA_CLUSTERS_0_NAME: "${COMPOSE_PROJECT_NAME}" + KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: "kafka:29092" + + KAFKA_CLUSTERS_0_KAFKACONNECT_0_NAME: "kafkatorio-connect" + KAFKA_CLUSTERS_0_KAFKACONNECT_0_ADDRESS: "http://connect:8083" # - KAFKA_CLUSTERS_0_ZOOKEEPER=kafka:9093 # kafka-connect: diff --git a/modules/infra-kafka-connect/build.gradle.kts b/modules/infra-kafka-connect/build.gradle.kts index ff2da04..871f9c1 100644 --- a/modules/infra-kafka-connect/build.gradle.kts +++ b/modules/infra-kafka-connect/build.gradle.kts @@ -24,13 +24,14 @@ fun DependencyHandlerScope.kafkaConnector( } dependencies { + kotlin("reflect") + kafkaConnector("camel-ahc-ws-kafka-connector") implementation("com.github.adamko-dev:json5-kotlin:2.0.3") implementation(platform(libs.http4k.bom)) - implementation("org.http4k:http4k-core") - implementation("org.http4k:http4k-client-okhttp") + implementation(libs.bundles.http4k) implementation(platform(libs.kotlinx.serialization.bom)) implementation("org.jetbrains.kotlinx:kotlinx-serialization-core") diff --git a/modules/infra-kafka-connect/src/main/docker/docker-compose.yml b/modules/infra-kafka-connect/src/main/docker/docker-compose.yml index f44f3af..f152ae6 100644 --- a/modules/infra-kafka-connect/src/main/docker/docker-compose.yml +++ b/modules/infra-kafka-connect/src/main/docker/docker-compose.yml @@ -27,7 +27,8 @@ services: - "kafkatorio-nw" environment: CONNECT_BOOTSTRAP_SERVERS: "kafka:29092" - CONNECT_REST_ADVERTISED_HOST_NAME: ${CONNECTOR_ID} +# CONNECT_REST_ADVERTISED_HOST_NAME: ${CONNECTOR_ID} + CONNECT_REST_ADVERTISED_HOST_NAME: connect # CONNECT_VALUE_CONVERTER_SCHEMA_REGISTRY_URL: "http://${SCHEMA_REGISTRY}:8081" # CONNECT_REST_PORT: 28083 CONNECT_REST_PORT: 8083 diff --git a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/websocketClient.kt b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/websocketClient.kt new file mode 100644 index 0000000..a5f6609 --- /dev/null +++ b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/websocketClient.kt @@ -0,0 +1,46 @@ +package dev.adamko.kafkatorio.kafkaconnect + +import java.time.Duration +import org.http4k.client.WebsocketClient +import org.http4k.core.Uri +import org.http4k.websocket.WsMessage + +fun main() { + +// val client = WebsocketClient.blocking( +// uri = Uri.of("ws://localhost:8095/ws"), +//// autoReconnection = true, +//// timeout = Duration.ofSeconds(30) +// ) +//// client.send(WsMessage("server sent on connection")) +// +// client.received() +// .take(100) +// .forEachIndexed { index, wsMessage -> +// println("[$index] ${wsMessage.bodyString()}") +// } + + + val nonBlockingClient = WebsocketClient.nonBlocking( + uri = Uri.of("ws://localhost:8095/ws"), + onError = { it.printStackTrace() }, + onConnect = { ws -> + println("onConnect, ws.upgradeRequest ${ws.upgradeRequest}") + ws.send(WsMessage("client sent on connection")) + } + ) + + nonBlockingClient.onMessage { msg -> print(msg.bodyString()) } + + + nonBlockingClient.onClose { + println("non-blocking client closing") + } + + + nonBlockingClient.onError { it.printStackTrace() } + + + Thread.sleep(Duration.ofMinutes(1).toMillis()) + +} diff --git a/modules/infra-kafka-connect/src/main/resources/configs/websocket-sink-lua-topics.json5 b/modules/infra-kafka-connect/src/main/resources/configs/websocket-sink-lua-topics.json5 index 09963ad..d11fdcc 100644 --- a/modules/infra-kafka-connect/src/main/resources/configs/websocket-sink-lua-topics.json5 +++ b/modules/infra-kafka-connect/src/main/resources/configs/websocket-sink-lua-topics.json5 @@ -14,7 +14,7 @@ // mandatory properties (for a complete properties list see the connector documentation): // The URI to use such as http://hostname:port/path - "camel.sink.path.httpUri": "http://localhost:8095/ws", + "camel.sink.path.httpUri": "localhost:8095/ws", // If the option is true, then the Exchange.HTTP_URI header is ignored, and use the endpoint's URI for request. You may also set the throwExceptionOnFailure to be false to let the AhcProducer send all the fault response back. // camel.sink.endpoint.bridgeEndpoint= // The initial in-memory buffer size used when transferring data between Camel and AHC Client. @@ -29,8 +29,16 @@ // camel.sink.endpoint.connectionClose= // Configure a cookie handler to maintain a HTTP session // camel.sink.endpoint.cookieHandler= - // Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and starting the producer may take a little time and prolong the total processing time of the processing. + + // Whether the producer should be started lazy (on the first message). By starting lazy you can + // use this to allow CamelContext and routes to startup in situations where a producer + // may otherwise fail during starting and cause the route to fail being started. By deferring + // this startup to be lazy then the startup failure can be handled during routing messages via + // Camel's routing error handlers. Beware that when the first message is processed then creating + // and starting the producer may take a little time and prolong the total processing time of the + // processing. // camel.sink.endpoint.lazyStartProducer= + // To enable streaming to send data as multiple text fragments. // camel.sink.endpoint.useStreaming= // To use a custom AhcBinding which allows to control how to bind between AHC and Camel. diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index 2991681..d3d3fb0 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -1,9 +1,28 @@ +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + plugins { id("dev.adamko.kafkatorio.infra.docker-compose") } description = "Send events from a Factorio server to a Kafka topic " + +val dockerSrcDir: Directory by extra + tasks.dockerUp { dependsOn(":modules:infra-kafka-cluster:dockerUp") } + +val dockerBuildKafkaPipe by tasks.registering(Exec::class) { + group = "docker-compose" + + logging.captureStandardOutput(LogLevel.LIFECYCLE) + + dependsOn(tasks.dockerEnv) + + inputs.dir(dockerSrcDir) + + workingDir = dockerSrcDir.asFile + commandLine = parseSpaceSeparatedArgs(""" docker-compose build kafka-pipe """) +} +tasks.assemble { dependsOn(dockerBuildKafkaPipe) } diff --git a/modules/infra-kafka-pipe/src/kafka-pipe.Dockerfile b/modules/infra-kafka-pipe/src/kafka-pipe.Dockerfile index edcb96c..02f8881 100644 --- a/modules/infra-kafka-pipe/src/kafka-pipe.Dockerfile +++ b/modules/infra-kafka-pipe/src/kafka-pipe.Dockerfile @@ -8,7 +8,7 @@ ENV KAFKA_HOST="kafka" USER root RUN apk add --update \ curl \ - kafkacat + kcat #USER rootless COPY kafka-pipe.sh kafka-pipe.sh diff --git a/modules/infra-kafka-pipe/src/kafka-pipe.sh b/modules/infra-kafka-pipe/src/kafka-pipe.sh index 1c7aae1..b40a782 100644 --- a/modules/infra-kafka-pipe/src/kafka-pipe.sh +++ b/modules/infra-kafka-pipe/src/kafka-pipe.sh @@ -16,7 +16,7 @@ INSTANCE_ID=$(cat /proc/sys/kernel/random/uuid) while :; do docker logs --tail 0 -f "$FACTORIO_SERVER_CONTAINER_NAME" | sed -n -e 's/^FactorioEvent: //p' | - kafkacat -P -T -b "$KAFKA_HOST" -t factorio-server-log -k "$INSTANCE_ID" + kcat -P -T -b "$KAFKA_HOST" -t factorio-server-log -k "$INSTANCE_ID" echo "Error - retrying in 10 seconds" sleep 10 From 2ad0c2848c437f26b649f17e40c94d6b88324b0e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 27 Dec 2021 12:24:55 +0100 Subject: [PATCH 105/629] giving up on kafka connect websockets, it doesn't work and there's no error messages and the documentaiton sucks --- build.gradle.kts | 2 +- modules/infra-kafka-connect/build.gradle.kts | 3 +- .../infra-kafka-connect/src/main/docker/.env | 2 +- .../src/main/docker/docker-compose.yml | 3 +- .../kafkaconnect/kafkaConnectAdmin.kt | 4 +- .../kafkaconnect/websocketClient.kt | 4 +- .../configs/ckc-websocket-lua-objects.json5 | 130 ++++++++++++++++++ ...son5 => websocket-async-lua-objects.json5} | 22 ++- settings.gradle.kts | 2 +- 9 files changed, 158 insertions(+), 14 deletions(-) create mode 100644 modules/infra-kafka-connect/src/main/resources/configs/ckc-websocket-lua-objects.json5 rename modules/infra-kafka-connect/src/main/resources/configs/{websocket-sink-lua-topics.json5 => websocket-async-lua-objects.json5} (85%) diff --git a/build.gradle.kts b/build.gradle.kts index a28bcdc..94fee6c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -38,7 +38,7 @@ val startInfra by tasks.registering { dependsOn( ":modules:infra-kafka-pipe:processRun", ":modules:infra-kafka-cluster:processRun", - ":modules:infra-kafka-connect:processRun", +// ":modules:infra-kafka-connect:processRun", ) } diff --git a/modules/infra-kafka-connect/build.gradle.kts b/modules/infra-kafka-connect/build.gradle.kts index 871f9c1..a233462 100644 --- a/modules/infra-kafka-connect/build.gradle.kts +++ b/modules/infra-kafka-connect/build.gradle.kts @@ -27,6 +27,7 @@ dependencies { kotlin("reflect") kafkaConnector("camel-ahc-ws-kafka-connector") + kafkaConnector("camel-websocket-kafka-connector") implementation("com.github.adamko-dev:json5-kotlin:2.0.3") @@ -49,7 +50,7 @@ val dockerBuildKafkaConnect by tasks.registering(Exec::class) { workingDir = dockerSrcDir.asFile commandLine = parseSpaceSeparatedArgs(""" docker-compose build connect """) } -tasks.assemble { dependsOn(dockerBuildKafkaConnect) } +//tasks.assemble { dependsOn(dockerBuildKafkaConnect) } val downloadCamelConnectors by tasks.registering(Sync::class) { diff --git a/modules/infra-kafka-connect/src/main/docker/.env b/modules/infra-kafka-connect/src/main/docker/.env index a1fb7e3..3af8d5f 100644 --- a/modules/infra-kafka-connect/src/main/docker/.env +++ b/modules/infra-kafka-connect/src/main/docker/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio CONNECTOR_ID=kafkatorio-connect -KAFKA_CONNECT_VERSION=7.0.0 +KAFKA_CONNECT_VERSION=7.0.1 diff --git a/modules/infra-kafka-connect/src/main/docker/docker-compose.yml b/modules/infra-kafka-connect/src/main/docker/docker-compose.yml index f152ae6..278ba19 100644 --- a/modules/infra-kafka-connect/src/main/docker/docker-compose.yml +++ b/modules/infra-kafka-connect/src/main/docker/docker-compose.yml @@ -16,7 +16,8 @@ services: # CAMEL_CONNECTOR: ${CAMEL_FILE_CONNECTOR} ports: - "8083:8083" - - "8095:8095" + - "8095:8095" # ws-async (client?) + - "9292:9292" # websocket server(?) # volumes: # - "./connect/input:/warehouse/input" # - "./connect/components:/usr/share/confluent-hub-components" diff --git a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/kafkaConnectAdmin.kt b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/kafkaConnectAdmin.kt index 6a68965..e8eccfb 100644 --- a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/kafkaConnectAdmin.kt +++ b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/kafkaConnectAdmin.kt @@ -24,7 +24,7 @@ fun main() { val connectorHostUrl = Uri.of("http://localhost:8083") - val configFile = Resources.loadResource("/configs/websocket-sink-lua-topics.json5") + val configFile = Resources.loadResource("/configs/ckc-websocket-lua-objects.json5") val jsonObject: JsonObject = j5.decodeObject(configFile.readText()) println("json5 connector config: $jsonObject") @@ -59,7 +59,7 @@ fun main() { //val updateConnectors by tasks.registering { // group = project.name // -// val configFile = layout.projectDirectory.file("configs/websocket-sink-lua-topics.json5") +// val configFile = layout.projectDirectory.file("configs/websocket-async-lua-objects.json5") // inputs.file(configFile) // // doLast { diff --git a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/websocketClient.kt b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/websocketClient.kt index a5f6609..b7ee898 100644 --- a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/websocketClient.kt +++ b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/websocketClient.kt @@ -22,11 +22,11 @@ fun main() { val nonBlockingClient = WebsocketClient.nonBlocking( - uri = Uri.of("ws://localhost:8095/ws"), + uri = Uri.of("ws://localhost:9292/lua-objects"), onError = { it.printStackTrace() }, onConnect = { ws -> println("onConnect, ws.upgradeRequest ${ws.upgradeRequest}") - ws.send(WsMessage("client sent on connection")) +// ws.send(WsMessage("client sent on connection")) } ) diff --git a/modules/infra-kafka-connect/src/main/resources/configs/ckc-websocket-lua-objects.json5 b/modules/infra-kafka-connect/src/main/resources/configs/ckc-websocket-lua-objects.json5 new file mode 100644 index 0000000..c96e8c8 --- /dev/null +++ b/modules/infra-kafka-connect/src/main/resources/configs/ckc-websocket-lua-objects.json5 @@ -0,0 +1,130 @@ +{ + "name": "ckc-websocket-lua-objects", + "connector.class": "org.apache.camel.kafkaconnector.websocket.CamelWebsocketSinkConnector", + "topics.regex": "^Lua.*$", + "key.converter": "org.apache.kafka.connect.storage.StringConverter", + "value.converter": "org.apache.kafka.connect.storage.StringConverter", + // The hostname. The default value is 0.0.0.0. Setting this option on the component will use the + // component configured value as default. + "camel.sink.path.host": "0.0.0.0", +// "camel.sink.path.host": "host.docker.internal", + // The port number. The default value is 9292. Setting this option on the component will use the + // component configured value as default. + "camel.sink.path.port": "9292", + // Name of the websocket channel to use + "camel.sink.path.resourceUri": "lua-objects", + "camel.sink.endpoint.sendToAll": "true", + "camel.component.websocket.host":"0.0.0.0", + "camel.component.websocket.port": "8084", + // Can be used to set the size in bytes that the websocket created by the websocketServlet may + // be accept before closing. (Default is -1 - or unlimited) + // "camel.sink.endpoint.maxBinaryMessageSize": -1, + + // Whether the producer should be started lazy (on the first message). By starting lazy you can + // use this to allow CamelContext and routes to startup in situations where a producer may otherwise + // fail during starting and cause the route to fail being started. By deferring this startup to be + // lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. + // Beware that when the first message is processed then creating and starting the producer may take a little + // time and prolong the total processing time of the processing. + // "camel.sink.endpoint.lazyStartProducer": false, + + // Timeout in millis when sending to a websocket channel. The default timeout is 30000 (30 seconds). + // "camel.sink.endpoint.sendTimeout": 30000, + + // To send to all websocket subscribers. Can be used to configure on endpoint level, instead of + // having to use the WebsocketConstants.SEND_TO_ALL header on the message. + // "camel.sink.endpoint.sendToAll": , + + // Set the buffer size of the websocketServlet, which is also the max frame byte size (default + // 8192) + // "camel.sink.endpoint.bufferSize": 8192, + + // Set the time in ms that the websocket created by the websocketServlet may be idle before + // closing. (default is 300000) + // "camel.sink.endpoint.maxIdleTime": 300000, + + // Can be used to set the size in characters that the websocket created by the websocketServlet + // may be accept before closing. + // "camel.sink.endpoint.maxTextMessageSize": , + + // Can be used to set the minimum protocol version accepted for the websocketServlet. + // (Default 13 - the RFC6455 version) + // "camel.sink.endpoint.minVersion": 13, + + // The CORS allowed origins. Use to allow all. + // "camel.sink.endpoint.allowedOrigins": , + + // Whether to enable CORS + // "camel.sink.endpoint.crossOriginFilterOn": false, + + // Context path for filtering CORS + // "camel.sink.endpoint.filterPath": , + + // If this option is true, Jetty JMX support will be enabled for this endpoint. See Jetty JMX + // support for more details. + // "camel.sink.endpoint.enableJmx": false, + + // To configure security using SSLContextParameters + // "camel.sink.endpoint.sslContextParameters": , + + // The hostname. The default value is 0.0.0.0 + // "camel.component.websocket.host": "0.0.0.0", + + // The port number. The default value is 9292 + // "camel.component.websocket.port": 9292, + + // Whether the producer should be started lazy (on the first message). By starting lazy you can + // use this to allow CamelContext and routes to startup in situations where a producer may otherwise + // fail during starting and cause the route to fail being started. By deferring this startup to be + // lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. + // Beware that when the first message is processed then creating and starting the producer may take a little + // time and prolong the total processing time of the processing. + // "camel.component.websocket.lazyStartProducer": false, + + // Whether autowiring is enabled. This is used for automatic autowiring options (the option must + // be marked as autowired) by looking up in the registry to find if there is a single instance + // of matching type, which then gets configured on the component. This can be used for automatic + // configuring JDBC data sources, JMS connection factories, AWS Clients, etc. + // "camel.component.websocket.autowiredEnabled": true, + + // If this option is true, Jetty JMX support will be enabled for this endpoint. See Jetty JMX + // support for more details. + // "camel.component.websocket.enableJmx": false, + + // To set a value for maximum number of threads in server thread pool. MaxThreads\/minThreads + // or threadPool fields are required due to switch to Jetty9. The default values for maxThreads + // is 1 2 noCores. + // "camel.component.websocket.maxThreads": , + + // To set a value for minimum number of threads in server thread pool. MaxThreads\/minThreads + // or threadPool fields are required due to switch to Jetty9. The default values for minThreads + // is 1. + // "camel.component.websocket.minThreads": , + + // This is a comma-separated list of subprotocols that are supported by the application. The list + // is in priority order. The first subprotocol on this list that is proposed by the client is + // the one that will be accepted. If no subprotocol on this list is proposed by the client, then the + // websocket connection is refused. The special value 'any' means that any subprotocol is acceptable. 'any' + // can be used on its own, or as a failsafe at the end of a list of more specific protocols. 'any' will also + // match the case where no subprotocol is proposed by the client. + // "camel.component.websocket.subprotocol": "any", + + // To use a custom thread pool for the server. MaxThreads\/minThreads or threadPool fields are + // required due to switch to Jetty9. + // "camel.component.websocket.threadPool": , + + // To configure security using SSLContextParameters + // "camel.component.websocket.sslContextParameters": , + + // The password for the keystore when using SSL. + // "camel.component.websocket.sslKeyPassword": , + + // The path to the keystore. + // "camel.component.websocket.sslKeystore": , + + // The password when using SSL. + // "camel.component.websocket.sslPassword": , + + // Enable usage of global SSL context parameters. + // "camel.component.websocket.useGlobalSslContextParameters": false, +} diff --git a/modules/infra-kafka-connect/src/main/resources/configs/websocket-sink-lua-topics.json5 b/modules/infra-kafka-connect/src/main/resources/configs/websocket-async-lua-objects.json5 similarity index 85% rename from modules/infra-kafka-connect/src/main/resources/configs/websocket-sink-lua-topics.json5 rename to modules/infra-kafka-connect/src/main/resources/configs/websocket-async-lua-objects.json5 index d11fdcc..19837c3 100644 --- a/modules/infra-kafka-connect/src/main/resources/configs/websocket-sink-lua-topics.json5 +++ b/modules/infra-kafka-connect/src/main/resources/configs/websocket-async-lua-objects.json5 @@ -1,6 +1,6 @@ //Exchange data with external Websocket servers using Async Http Client { - name: "CKC-async-ws-lua-objects", + name: "websocket-async-lua-objects", "connector.class": "org.apache.camel.kafkaconnector.ahcws.CamelAhcwsSinkConnector", "tasks.max": 1, //use the kafka converters that better suit your needs, these are just defaults: @@ -14,17 +14,29 @@ // mandatory properties (for a complete properties list see the connector documentation): // The URI to use such as http://hostname:port/path - "camel.sink.path.httpUri": "localhost:8095/ws", - // If the option is true, then the Exchange.HTTP_URI header is ignored, and use the endpoint's URI for request. You may also set the throwExceptionOnFailure to be false to let the AhcProducer send all the fault response back. + "camel.sink.path.httpUri": "host.docker.internal:8095/ws/lua", + // If the option is true, then the Exchange.HTTP_URI header is ignored, and use the endpoint's + // URI for request. You may also set the throwExceptionOnFailure to be false to let the + // AhcProducer send all the fault response back. // camel.sink.endpoint.bridgeEndpoint= + // The initial in-memory buffer size used when transferring data between Camel and AHC Client. // camel.sink.endpoint.bufferSize= // To use a custom HeaderFilterStrategy to filter header to and from Camel message. // camel.sink.endpoint.headerFilterStrategy= - // Option to disable throwing the AhcOperationFailedException in case of failed responses from the remote server. This allows you to get all responses regardless of the HTTP status code. + // Option to disable throwing the AhcOperationFailedException in case of failed responses from + // the remote server. This allows you to get all responses regardless of the HTTP status code. // camel.sink.endpoint.throwExceptionOnFailure= - // If enabled and an Exchange failed processing on the consumer side, and if the caused Exception was send back serialized in the response as a application\/x-java-serialized-object content type (for example using Jetty or Servlet Camel components). On the producer side the exception will be deserialized and thrown as is, instead of the AhcOperationFailedException. The caused exception is required to be serialized. This is by default turned off. If you enable this then be aware that Java will deserialize the incoming data from the request to Java and that can be a potential security risk. + // If enabled and an Exchange failed processing on the consumer side, and if the caused + + // Exception was send back serialized in the response as a application\/x-java-serialized-object + // content type (for example using Jetty or Servlet Camel components). On the producer side the + // exception will be deserialized and thrown as is, instead of the AhcOperationFailedException. + // The caused exception is required to be serialized. This is by default turned off. + // If you enable this then be aware that Java will deserialize the incoming data from the + // request to Java and that can be a potential security risk. // camel.sink.endpoint.transferException= + // Define if the Connection Close header has to be added to HTTP Request. This parameter is false by default // camel.sink.endpoint.connectionClose= // Configure a cookie handler to maintain a HTTP session diff --git a/settings.gradle.kts b/settings.gradle.kts index 3af2206..a99134d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -11,7 +11,7 @@ include( ":modules:infra-kafka-cluster", ":modules:infra-kafka-pipe", - ":modules:infra-kafka-connect", +// ":modules:infra-kafka-connect", ":modules:kt-rcon", ":modules:web-map", From 55bea4aed47f70113d3d1219c0374c4cc262ba7e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 27 Dec 2021 12:44:37 +0100 Subject: [PATCH 106/629] giving up on kafka connect websockets, it doesn't work and there's no error messages and the documentaiton sucks --- gradle/libs.versions.toml | 5 ++--- modules/events-processor/build.gradle.kts | 7 ++++--- modules/infra-kafka-connect/build.gradle.kts | 11 +++++++++++ settings.gradle.kts | 2 +- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 877b863..edf618f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -37,7 +37,6 @@ kotlinSerialization = { id = "org.jetbrains.kotlin.kotlin-serialization", vers loggingCapabilities = { id = "dev.jacomet.logging-capabilities", version = "0.9.0" } shadowJar = { id = "com.github.jengelman.gradle.plugins.shadow", version = "6.1.0" } dependencyCheck = { id = "com.github.ben-manes.versions", version = "0.39.0" } -axionRelease = { id = "pl.allegro.tech.build.axion-release", version = "1.13.3" } ########### @@ -69,8 +68,8 @@ http4k-format-kotlinx = { group = "org.http4k", name = "http4k-format-kotlinx-s http4k-graphql = { group = "org.http4k", name = "http4k-graphql" } ### jackson ## -#jackson-bom = { group = " com.fasterxml.jackson.module", name = ":jackson-module-kotlin", version = "2.13.+" } -#jackson-kotlin = { group = " com.fasterxml.jackson.module", name = ":jackson-module-kotlin", version = "2.13.+" } +#jackson-bom = { group = " com.fasterxml.jackson.module", name = ":jackson-module-kotlin", version = "2.13.+" } +#jackson-kotlin = { group = " com.fasterxml.jackson.module", name = ":jackson-module-kotlin", version = "2.13.+" } ## logging ## slf4j-api = { group = "org.slf4j", name = "slf4j-api", version.ref = "slf4j" } diff --git a/modules/events-processor/build.gradle.kts b/modules/events-processor/build.gradle.kts index 2066d02..dd7b8f6 100644 --- a/modules/events-processor/build.gradle.kts +++ b/modules/events-processor/build.gradle.kts @@ -12,7 +12,7 @@ description = """ val projectId: String by project.extra -@Suppress("UnstableApiUsage") +@Suppress("UnstableApiUsage") // platform + version-catalog is incubating dependencies { implementation("org.apache.kafka:kafka-streams:3.0.0") @@ -21,10 +21,12 @@ dependencies { // implementation("com.ionspin.kotlin:bignum:0.3.3") - implementation(enforcedPlatform(libs.kotlinx.serialization.bom)) + implementation(platform(libs.kotlinx.serialization.bom)) implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.json) + implementation(libs.kotlinx.coroutines) + implementation(platform(libs.http4k.bom)) // implementation(libs.http4k.core) implementation(libs.http4k.cloudnative) @@ -36,7 +38,6 @@ dependencies { implementation(libs.http4k.format.kotlinx) implementation(libs.bundles.logging) - } application { diff --git a/modules/infra-kafka-connect/build.gradle.kts b/modules/infra-kafka-connect/build.gradle.kts index a233462..30c163a 100644 --- a/modules/infra-kafka-connect/build.gradle.kts +++ b/modules/infra-kafka-connect/build.gradle.kts @@ -39,7 +39,12 @@ dependencies { implementation("org.jetbrains.kotlinx:kotlinx-serialization-json") } +// disabled for now... +val projectEnabled = false + val dockerBuildKafkaConnect by tasks.registering(Exec::class) { + enabled = projectEnabled + group = "docker-compose" dependsOn(downloadCamelConnectors, tasks.dockerEnv) @@ -54,6 +59,8 @@ val dockerBuildKafkaConnect by tasks.registering(Exec::class) { val downloadCamelConnectors by tasks.registering(Sync::class) { + enabled = projectEnabled + group = project.name description = "Retrieve Camel Kafka Connectors from Maven, in preparation for the Docker build" @@ -82,11 +89,15 @@ val downloadCamelConnectors by tasks.registering(Sync::class) { } tasks.dockerUp { + enabled = projectEnabled + dependsOn(":modules:infra-kafka-cluster:dockerUp") dependsOn(downloadCamelConnectors) } tasks.dockerEnv { + enabled = projectEnabled + properties( "CONNECTOR_ID" to "kafkatorio-connect", "KAFKA_CONNECT_VERSION" to libs.versions.confluent.kafkaConnect.get(), diff --git a/settings.gradle.kts b/settings.gradle.kts index a99134d..3af2206 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -11,7 +11,7 @@ include( ":modules:infra-kafka-cluster", ":modules:infra-kafka-pipe", -// ":modules:infra-kafka-connect", + ":modules:infra-kafka-connect", ":modules:kt-rcon", ":modules:web-map", From 7813756c6967164440ec61e737b0319d7586b7f0 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 28 Dec 2021 16:26:23 +0100 Subject: [PATCH 107/629] kafka -> websockets working!! --- build.gradle.kts | 1 - buildSrc/build.gradle.kts | 10 +- .../kafkatorio/lang/kotlin-jvm.gradle.kts | 16 +-- gradle/libs.versions.toml | 2 +- modules/events-processor/build.gradle.kts | 15 +-- .../processor/FactorioEventsTopology.kt | 51 ++++++++-- .../kafkatorio/processor/WebsocketServer.kt | 98 +++++++++++++++++++ .../kafkatorio/processor/eventProcessor.kt | 32 ++++++ .../dev/adamko/kafkatorio/processor/main.kt | 82 ---------------- .../dev/adamko/kafkatorio/processor/serdes.kt | 39 ++++++++ .../adamko/kafkatorio/events/schema/json.kt | 4 +- .../kafkaconnect/websocketClient.kt | 57 +++++------ 12 files changed, 265 insertions(+), 142 deletions(-) create mode 100644 modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt create mode 100644 modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt delete mode 100644 modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt create mode 100644 modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt diff --git a/build.gradle.kts b/build.gradle.kts index 94fee6c..0ed4990 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -30,7 +30,6 @@ tasks.wrapper { gradleVersion = "7.3.3" distributionType = Wrapper.DistributionType.ALL } -tasks.assemble { dependsOn(tasks.wrapper) } val startInfra by tasks.registering { group = project.name diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index dc26678..2a694a2 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -37,11 +37,11 @@ tasks.withType().configureEach { } kotlinOptions.freeCompilerArgs += listOf( - "-Xopt-in=kotlin.RequiresOptIn", - "-Xopt-in=kotlin.ExperimentalStdlibApi", - "-Xopt-in=kotlin.time.ExperimentalTime", - "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi", + "-opt-in=kotlin.RequiresOptIn", + "-opt-in=kotlin.ExperimentalStdlibApi", + "-opt-in=kotlin.time.ExperimentalTime", + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", ) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index a0fe076..122d74a 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -26,14 +26,14 @@ dependencies { // val junitVersion = "5.8.2" - testImplementation(enforcedPlatform("org.junit:junit-bom:$junitVersion")) + testImplementation(platform("org.junit:junit-bom:$junitVersion")) testImplementation("org.junit.jupiter:junit-jupiter") testRuntimeOnly("org.junit.platform:junit-platform-launcher") { because("Only needed to run tests in a version of IntelliJ IDEA that bundles older versions") } val kotestVersion = "5.0.3" - testImplementation(enforcedPlatform("io.kotest:kotest-bom:$kotestVersion")) + testImplementation(platform("io.kotest:kotest-bom:$kotestVersion")) testImplementation("io.kotest:kotest-runner-junit5:$kotestVersion") testImplementation("io.kotest:kotest-assertions-core:$kotestVersion") testImplementation("io.kotest:kotest-property:$kotestVersion") @@ -54,16 +54,16 @@ tasks.withType().configureEach { } kotlinOptions.freeCompilerArgs += listOf( - "-Xopt-in=kotlin.RequiresOptIn", - "-Xopt-in=kotlin.ExperimentalStdlibApi", - "-Xopt-in=kotlin.time.ExperimentalTime", -// "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi", + "-opt-in=kotlin.RequiresOptIn", + "-opt-in=kotlin.ExperimentalStdlibApi", + "-opt-in=kotlin.time.ExperimentalTime", +// "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", ) } tasks.compileTestKotlin { - kotlinOptions.freeCompilerArgs += "-Xopt-in=io.kotest.common.ExperimentalKotest" + kotlinOptions.freeCompilerArgs += "-opt-in=io.kotest.common.ExperimentalKotest" } tasks.withType { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index edf618f..acfc587 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -149,11 +149,11 @@ http4k = [ "http4k-client-okhttp", "http4k-client-ws", "http4k-server", - # "http4k-kotlinx", "http4k-cloudnative", "http4k-format-xml", "http4k-format-json", "http4k-format-yaml", + "http4k-format-kotlinx", ] http4k-test = [ diff --git a/modules/events-processor/build.gradle.kts b/modules/events-processor/build.gradle.kts index dd7b8f6..ed4964e 100644 --- a/modules/events-processor/build.gradle.kts +++ b/modules/events-processor/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { id("dev.adamko.kafkatorio.lang.kotlin-jvm") kotlin("plugin.serialization") @@ -28,12 +30,7 @@ dependencies { implementation(libs.kotlinx.coroutines) implementation(platform(libs.http4k.bom)) -// implementation(libs.http4k.core) - implementation(libs.http4k.cloudnative) -// implementation(libs.http4k.format.json) - implementation(libs.http4k.format.yaml) { - because("parsing yaml properties files") - } + implementation(libs.bundles.http4k) implementation(libs.http4k.format.kotlinx) @@ -43,3 +40,9 @@ dependencies { application { mainClass.set("dev.adamko.factorioevents.processor.mainKt") } + +tasks.withType { + kotlinOptions.freeCompilerArgs += listOf( + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + ) +} diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt index 4bd53cb..d9e2359 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt @@ -1,20 +1,59 @@ package dev.adamko.kafkatorio.processor -import java.util.Properties +import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.FactorioObjectData +import java.time.Duration +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString +import org.apache.kafka.common.serialization.Serdes import org.apache.kafka.streams.KafkaStreams import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.TopologyDescription +import org.apache.kafka.streams.kstream.Consumed +import org.apache.kafka.streams.kstream.Produced -class FactorioEventsTopology { +class FactorioEventsTopology( + val websocketServer: WebsocketServer, + val builder: StreamsBuilder = StreamsBuilder(), +) { + + private val sourceTopic = "factorio-server-log" fun build() { - val topology = StreamsBuilder().build() + builder.stream( + sourceTopic, + Consumed.with(Serdes.String(), Serdes.String()) + ) + .mapValues { readOnlyKey, value -> + println("Mapping $readOnlyKey:$value") + jsonMapper.decodeFromString>(value) + } + .peek { _, value -> + websocketServer.sendMessage(jsonMapper.encodeToString(value)) + } + .to( + { _, value, _ -> +// println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") + value.data.objectName + }, + Produced.with(Serdes.String(), JsonSerdes) + ) + val topology = builder.build() - val properties = Properties() + val streams = KafkaStreams(topology, appProps.kafkaConfig) - val kafkaStreams = KafkaStreams(topology, properties) + streams.setUncaughtExceptionHandler(StreamsExceptionHandler()) + Runtime.getRuntime().addShutdownHook(Thread { streams.close(Duration.ofSeconds(1)) }) + +// streams.cleanUp() + + val description: TopologyDescription = topology.describe() + println(description) + + streams.start() } -} \ No newline at end of file +} diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt new file mode 100644 index 0000000..4789991 --- /dev/null +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt @@ -0,0 +1,98 @@ +package dev.adamko.kafkatorio.processor + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.withIndex +import kotlinx.coroutines.job +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.supervisorScope +import org.http4k.core.Request +import org.http4k.core.Response +import org.http4k.core.Status.Companion.OK +import org.http4k.routing.bind +import org.http4k.routing.websockets +import org.http4k.server.PolyHandler +import org.http4k.websocket.Websocket +import org.http4k.websocket.WsMessage +import org.http4k.websocket.WsStatus + + +class WebsocketServer { + + // create a scope+job for the server + private val serverJob = SupervisorJob() + private val serverScope = CoroutineScope(serverJob) + + private val clients: MutableSharedFlow = MutableSharedFlow( + replay = 100, + extraBufferCapacity = 100, + BufferOverflow.DROP_OLDEST, + ) + + private val messages: MutableSharedFlow = MutableSharedFlow( + replay = 100, + extraBufferCapacity = 100, + BufferOverflow.DROP_OLDEST, + ) + + private fun bindClient(ws: Websocket) = runBlocking(serverScope.coroutineContext) { + clients.emit(ws) + } + + fun sendMessage(msg: String) = runBlocking(serverScope.coroutineContext) { + messages.emit(msg) + } + + suspend fun start(): PolyHandler = supervisorScope builder@{ + + coroutineContext.job.invokeOnCompletion { e -> + e?.let { serverJob.completeExceptionally(it) } ?: serverJob.complete() + } + + clients + .withIndex() + .onEach { (id, ws) -> + // create a scope+job for each client + val clientJob = SupervisorJob(serverJob) + val clientScope = CoroutineScope(clientJob) + + clientJob.invokeOnCompletion { e -> + println("[clientJob.invokeOnCompletion] closing client ws $e") + when (e) { + null -> ws.close(WsStatus.NORMAL) + else -> ws.close(WsStatus.ABNORMAL_CLOSE) + } + } + + ws.onError { e -> + sendMessage("[ws.onError] client $id error [${e}]") + clientJob.completeExceptionally(e) + } + ws.onClose { status -> + sendMessage("[ws.onClose] client $id disconnected [${status}]") + clientJob.complete() + } + ws.onMessage { wsMsg -> + sendMessage("$id says: ${wsMsg.bodyString()}") + } + + sendMessage("new client $id!") + + messages + .onEach { msg -> ws.send(WsMessage(msg)) } + .launchIn(clientScope) + + } + .launchIn(serverScope) + + val http = { _: Request -> Response(OK) } + val ws = websockets("/ws" bind ::bindClient) + + return@builder PolyHandler(http, ws) + + } +} diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt new file mode 100644 index 0000000..75b47fb --- /dev/null +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -0,0 +1,32 @@ +package dev.adamko.kafkatorio.processor + + +import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import kotlinx.coroutines.runBlocking +import org.http4k.server.Undertow +import org.http4k.server.asServer + +val appProps = ApplicationProperties() + +fun main() = runBlocking { + + val wsServer = WebsocketServer() + + val topology = FactorioEventsTopology(wsServer) + topology.build() + + wsServer.start().asServer(Undertow(9073)).start().block() +} + +// +// +//// a standard websocket app +//val websocketServer = websockets( +// "/lua-objects" bind { ws: Websocket -> +// ws.send(WsMessage("bob")) +// ws.onMessage { +// println("server received: $it") +// ws.send(it) +// } +// } +//).asServer(Undertow(9097)).start() diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt deleted file mode 100644 index 2f899bf..0000000 --- a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/main.kt +++ /dev/null @@ -1,82 +0,0 @@ -package dev.adamko.kafkatorio.processor - -import dev.adamko.kafkatorio.events.schema.FactorioEvent -import dev.adamko.kafkatorio.events.schema.FactorioObjectData -import dev.adamko.kafkatorio.events.schema.jsonMapper -import dev.adamko.kafkatorio.processor.config.ApplicationProperties -import java.time.Duration -import kotlinx.serialization.decodeFromString -import kotlinx.serialization.encodeToString -import kotlinx.serialization.modules.SerializersModule -import org.apache.kafka.common.serialization.Deserializer -import org.apache.kafka.common.serialization.Serde -import org.apache.kafka.common.serialization.Serdes -import org.apache.kafka.common.serialization.Serializer -import org.apache.kafka.streams.KafkaStreams -import org.apache.kafka.streams.StreamsBuilder -import org.apache.kafka.streams.TopologyDescription -import org.apache.kafka.streams.kstream.Consumed -import org.apache.kafka.streams.kstream.Produced -import org.http4k.format.ConfigurableKotlinxSerialization -import org.http4k.format.asConfigurable -import org.http4k.format.withStandardMappings - - -object KXS : ConfigurableKotlinxSerialization({ - ignoreUnknownKeys = true - prettyPrint = true - prettyPrintIndent = " " - asConfigurable().withStandardMappings().done() - serializersModule = SerializersModule { } -}) - -object JsonSerdes : Serde> { - override fun serializer() = Serializer> { _, message -> - jsonMapper.encodeToString>(message).encodeToByteArray() - } - - override fun deserializer() = Deserializer> { _, bytes -> - jsonMapper.decodeFromString(bytes.decodeToString()) - } -} - -fun main() { - - val appProps = ApplicationProperties() - - val builder = StreamsBuilder() - - builder.stream( - "factorio-server-log", - Consumed.with(Serdes.String(), Serdes.String()) - ) - .mapValues { readOnlyKey, value -> - println("Mapping $readOnlyKey:$value") - jsonMapper.decodeFromString>(value) -// KXS.asA>(value) - } - .to( - { key, value, recordContext -> -// println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") - value.data.objectName - }, - Produced.with(Serdes.String(), JsonSerdes) - ) - - val topology = builder.build() - val properties = appProps.kafkaConfig - - val streams = KafkaStreams(topology, properties) - - streams.setUncaughtExceptionHandler(StreamsExceptionHandler()) - - Runtime.getRuntime().addShutdownHook(Thread { streams.close(Duration.ofSeconds(1)) }) - -// streams.cleanUp() - - val description: TopologyDescription = topology.describe() - println(description) - - streams.start() - -} diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt new file mode 100644 index 0000000..14c40bf --- /dev/null +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt @@ -0,0 +1,39 @@ +package dev.adamko.kafkatorio.processor + +import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.FactorioObjectData +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import kotlinx.serialization.modules.SerializersModule +import org.apache.kafka.common.serialization.Deserializer +import org.apache.kafka.common.serialization.Serde +import org.apache.kafka.common.serialization.Serializer +import org.http4k.format.ConfigurableKotlinxSerialization +import org.http4k.format.asConfigurable +import org.http4k.format.withStandardMappings + + +object JsonSerdes : Serde> { + override fun serializer() = Serializer> { _, message -> + jsonMapper.encodeToString>(message).encodeToByteArray() + } + + override fun deserializer() = Deserializer> { _, bytes -> + jsonMapper.decodeFromString(bytes.decodeToString()) + } +} + +val jsonMapper = Json { + prettyPrint = true + prettyPrintIndent = " " + serializersModule = SerializersModule { } +} + +object KXS : ConfigurableKotlinxSerialization({ + ignoreUnknownKeys = true + prettyPrint = true + prettyPrintIndent = " " + asConfigurable().withStandardMappings().done() + serializersModule = SerializersModule { } +}) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt index 3723e74..d99ec7e 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt @@ -13,7 +13,7 @@ import kotlinx.serialization.modules.SerializersModule /** Factorio outputs lists as Json objects - this serializer converts an object back to a list. */ -class ListAsObjectSerializer(dataSerializer: KSerializer) : +internal class ListAsObjectSerializer(dataSerializer: KSerializer) : JsonTransformingSerializer>(ListSerializer(dataSerializer)) { override fun transformDeserialize(element: JsonElement): JsonElement = @@ -27,7 +27,7 @@ class ListAsObjectSerializer(dataSerializer: KSerializer) : ) } -val jsonMapper = Json { +internal val jsonMapper = Json { prettyPrint = true prettyPrintIndent = " " serializersModule = SerializersModule { } diff --git a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/websocketClient.kt b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/websocketClient.kt index b7ee898..1763679 100644 --- a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/websocketClient.kt +++ b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/websocketClient.kt @@ -7,40 +7,35 @@ import org.http4k.websocket.WsMessage fun main() { -// val client = WebsocketClient.blocking( -// uri = Uri.of("ws://localhost:8095/ws"), -//// autoReconnection = true, -//// timeout = Duration.ofSeconds(30) -// ) -//// client.send(WsMessage("server sent on connection")) -// -// client.received() -// .take(100) -// .forEachIndexed { index, wsMessage -> -// println("[$index] ${wsMessage.bodyString()}") -// } - - - val nonBlockingClient = WebsocketClient.nonBlocking( - uri = Uri.of("ws://localhost:9292/lua-objects"), - onError = { it.printStackTrace() }, - onConnect = { ws -> - println("onConnect, ws.upgradeRequest ${ws.upgradeRequest}") -// ws.send(WsMessage("client sent on connection")) - } + val client = WebsocketClient.blocking( + uri = Uri.of("ws://localhost:9073/ws"), +// autoReconnection = true, +// timeout = Duration.ofSeconds(30) ) +// client.send(WsMessage("server sent on connection")) - nonBlockingClient.onMessage { msg -> print(msg.bodyString()) } + client.received() + .take(100) + .forEachIndexed { index, wsMessage -> + println("[$index] ${wsMessage.bodyString()}") + } - nonBlockingClient.onClose { - println("non-blocking client closing") - } - - - nonBlockingClient.onError { it.printStackTrace() } - - - Thread.sleep(Duration.ofMinutes(1).toMillis()) +// val nonBlockingClient = WebsocketClient.nonBlocking( +// uri = Uri.of("ws://localhost:9097/lua-objects"), +// onError = { it.printStackTrace() }, +// onConnect = { ws -> +// println("onConnect, ws.upgradeRequest ${ws.upgradeRequest}") +//// ws.send(WsMessage("client sent on connection")) +// } +// ) +// +// nonBlockingClient.onMessage { msg -> print(msg.bodyString()) } +// nonBlockingClient.onClose { +// println("non-blocking client closing") +// } +//// nonBlockingClient.onError { it.printStackTrace() } +// +// Thread.sleep(Duration.ofMinutes(1).toMillis()) } From 08ab1c582c100e31467510d2662720318066eb14 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 28 Dec 2021 17:05:52 +0100 Subject: [PATCH 108/629] tidying up --- build.gradle.kts | 2 +- buildSrc/build.gradle.kts | 5 +- .../kafkatorio/lang/kotlin-js.gradle.kts | 4 +- .../kafkatorio/lang/kotlin-jvm.gradle.kts | 1 - .../adamko/kafkatorio/lang/node.gradle.kts | 4 + ...w-to-run-npx-gradle-task-with-kotlin-js.md | 0 gradle/libs.versions.toml | 2 +- modules/events-mod/build.gradle.kts | 34 +----- .../events-mod/src/main/typescript/events.ts | 6 +- .../src/main/typescript/package.json | 14 ++- .../src/main/typescript/serdes/serdes.ts | 100 ++++++++---------- .../processor/FactorioEventLogConsumer.kt | 7 -- .../processor/FactorioEventsTopology.kt | 4 +- .../kafkatorio/processor/WebsocketServer.kt | 2 +- .../processor/config/ApplicationProperties.kt | 8 -- .../kafkatorio/processor/eventProcessor.kt | 15 +-- .../kafkatorio/events/schema/builtinTypes.kt | 98 ----------------- .../events/schema/factorioEvents.kt | 75 +++++-------- .../adamko/kafkatorio/events/schema/kt2ts.kt | 3 + .../infra-factorio-client/build.gradle.kts | 2 + .../infra-factorio-server/build.gradle.kts | 43 -------- .../factorioEvents.Dockerfile | 0 .../kafka-pipe.sh | 0 .../kcat.conf | 0 24 files changed, 105 insertions(+), 324 deletions(-) rename asd.md => docs/notes/question-how-to-run-npx-gradle-task-with-kotlin-js.md (100%) delete mode 100644 modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventLogConsumer.kt delete mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/builtinTypes.kt rename modules/infra-factorio-server/{src => factorio-and-kpipe-server}/factorioEvents.Dockerfile (100%) rename modules/infra-factorio-server/{src => factorio-and-kpipe-server}/kafka-pipe.sh (100%) rename modules/infra-factorio-server/{src => factorio-and-kpipe-server}/kcat.conf (100%) diff --git a/build.gradle.kts b/build.gradle.kts index 0ed4990..b67ca9a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.1.5" +version = "0.1.6" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 2a694a2..6566320 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -15,7 +15,7 @@ dependencies { implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") - val kotlinXSerializationVersion = "1.3.1" + val kotlinXSerializationVersion = "1.3.2" implementation(enforcedPlatform("org.jetbrains.kotlinx:kotlinx-serialization-bom:$kotlinXSerializationVersion")) implementation("org.jetbrains.kotlinx:kotlinx-serialization-core") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json") @@ -24,6 +24,9 @@ dependencies { implementation("com.github.node-gradle:gradle-node-plugin:3.1.1") implementation("net.swiftzer.semver:semver:1.1.2") + + // https://github.com/avast/gradle-docker-compose-plugin + implementation("com.avast.gradle:gradle-docker-compose-plugin:0.14.12") } val projectJvmTarget = "11" diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts index 62c6d7b..4c11e6d 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts @@ -32,13 +32,13 @@ val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) val nodePath: Directory by extra { val file = rootPackageJson.rootPackageJson.parentFile.normalize() - logger.lifecycle("Kotlin/JS NODE_PATH: $file") + logger.info("Kotlin/JS NODE_PATH: $file") project.layout.dir(project.provider { file }).get() } val nodeModulesDir: Directory by extra { val file = nodePath.dir(NpmProject.NODE_MODULES) - logger.lifecycle("Kotlin/JS NODE_MODULES: $file") + logger.info("Kotlin/JS NODE_MODULES: $file") file } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index 122d74a..f3aa96e 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -19,7 +19,6 @@ dependencies { // implementation(platform("org.jetbrains.kotlin:kotlin-bom")) -// implementation(kotlin("stdlib")) // diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts index 17a4450..f335393 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts @@ -1,6 +1,7 @@ package dev.adamko.kafkatorio.lang import com.github.gradle.node.NodePlugin +import com.github.gradle.node.npm.task.NpmTask import dev.adamko.kafkatorio.gradle.areJsonPropertiesUpToDate import dev.adamko.kafkatorio.gradle.not import dev.adamko.kafkatorio.jsonMapper @@ -55,3 +56,6 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) { } tasks.assemble { dependsOn(updatePackageJson) } +tasks.withType { + dependsOn(updatePackageJson) +} diff --git a/asd.md b/docs/notes/question-how-to-run-npx-gradle-task-with-kotlin-js.md similarity index 100% rename from asd.md rename to docs/notes/question-how-to-run-npx-gradle-task-with-kotlin-js.md diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index acfc587..cd4b7ac 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ kotlin = "1.6.10" camel-kafkaConnectors = "0.11.0" http4k = "4.17.6.0" kafka = "3.0.0" -kotlinx-serialization = "1.3.1" +kotlinx-serialization = "1.3.2" kvision = "5.6.1" log4j2 = "2.14.1" qosLogback = "1.2.5" diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index bb2c28e..12719aa 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -138,7 +138,7 @@ distributions { filter("tokens" to projectTokens) includeEmptyDirs = false exclude { -// exclude empty files + // exclude empty files it.file.run { isFile && useLines { lines -> lines.all { line -> line.isBlank() } } } @@ -148,36 +148,6 @@ distributions { } } -//val packageMod by tasks.registering(Zip::class) { -// description = "Package mod files into ZIP" -// group = project.name -// -// dependsOn(typescriptToLua) -// -// inputs.properties(tokens) -// -// from(layout.projectDirectory.dir("src/main/resources/mod-data")) { -// include("**/**") -// filter("tokens" to tokens) -// } -// from(licenseFile) -// -// into(rootProject.name) -// -// // Factorio required format is: -// // - filename: `mod-name_version.zip` -// // - zip contains one directory, `mod-name` -// archiveFileName.set("${rootProject.name}_${project.version}.zip") -// destinationDirectory.set(layout.buildDirectory.dir("dist")) -// -// doLast { -// val outDir = destinationDirectory.asFile.get().toRelativeString(layout.projectDirectory.asFile) -// val outZip = "${archiveFileName.orNull}" -// logger.lifecycle("Packaged mod into $outDir/$outZip") -// } -//} - - val downloadFactorioApiDocs by tasks.registering { group = project.name @@ -244,3 +214,5 @@ tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) } // } // } // } + +tasks.npmInstall diff --git a/modules/events-mod/src/main/typescript/events.ts b/modules/events-mod/src/main/typescript/events.ts index e9e071f..7ac5ec3 100644 --- a/modules/events-mod/src/main/typescript/events.ts +++ b/modules/events-mod/src/main/typescript/events.ts @@ -10,7 +10,7 @@ for (const [k, v] of pairs(defines.events)) { function handlePlayerUpdate(tick: uint, playerIndex: uint, eventType: string) { let player: LuaPlayer = game.players[playerIndex] - let table = Serdes.Player.playerToTable(player) + let table = Serdes.playerToTable(player) emitEvent(table, tick, eventType) handleCharactersEvent(tick, playerIndex, eventType) @@ -31,12 +31,12 @@ function handleCharactersEvent(tick: uint, playerIndex: uint, eventType: string) } function handleEntityUpdate(tick: uint, entity: LuaEntity, eventType: string) { - let table = Serdes.Entity.entityToTable(entity) + let table = Serdes.entityToTable(entity) emitEvent(table, tick, eventType) } function surfaceEvent(tick: uint, surface: LuaSurface, eventType: string) { - let table = Serdes.Surface.surfaceToTable(surface) + let table = Serdes.surfaceToTable(surface) emitEvent(table, tick, eventType) } diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 966ac89..033dca2 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.1.5", + "version": "0.1.6", "private": true, "scripts": { "build": "tstl", @@ -9,7 +9,8 @@ "engines": { "node": ">=10.13.0" }, - "devDependencies": {}, + "devDependencies": { + }, "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", @@ -18,7 +19,10 @@ "typescript": "4.5.4" }, "license": "UNLICENSED", - "peerDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": [] + "peerDependencies": { + }, + "optionalDependencies": { + }, + "bundledDependencies": [ + ] } diff --git a/modules/events-mod/src/main/typescript/serdes/serdes.ts b/modules/events-mod/src/main/typescript/serdes/serdes.ts index 2a4a8e1..76425c4 100644 --- a/modules/events-mod/src/main/typescript/serdes/serdes.ts +++ b/modules/events-mod/src/main/typescript/serdes/serdes.ts @@ -1,79 +1,65 @@ export namespace Serdes { - export namespace Player { - export function playerToTable(player: LuaPlayer): PlayerData { - let charIds = Entity.entitiesToUnitNumbers(player.get_associated_characters()) - return { - object_name: player.object_name, + export function playerToTable(player: LuaPlayer): PlayerData { + let charIds = entitiesToUnitNumbers(player.get_associated_characters()) + return { + object_name: player.object_name, - name: player.name, - character_unit_number: player.character?.unit_number ?? null, - associated_characters_unit_numbers: charIds, - position: DataClasses.positionTableToTable(player.position), - } + name: player.name, + character_unit_number: player.character?.unit_number ?? null, + associated_characters_unit_numbers: charIds, + position: positionTableToTable(player.position), } - } - export namespace Entity { + export function entityToTable(entity: LuaEntity): EntityData { - export function entityToTable(entity: LuaEntity): EntityData { + let player: LuaPlayer | null = entity.is_player() ? entity.player!! : null - let player: LuaPlayer | null = entity.is_player() ? entity.player!! : null + return { + object_name: entity.object_name, - return { - object_name: entity.object_name, + // entity data + name: entity.name, + type: entity.type, + active: entity.active, + health: entity.health ?? null, + health_ratio: entity.get_health_ratio(), + surface_index: entity.surface.index, + unit_number: entity.unit_number ?? null, + position: positionTableToTable(entity.position), - // entity data - name: entity.name, - type: entity.type, - active: entity.active, - health: entity.health ?? null, - health_ratio: entity.get_health_ratio(), - surface_index: entity.surface.index, - unit_number: entity.unit_number ?? null, - position: DataClasses.positionTableToTable(entity.position), - - // player data - player_index: player?.index ?? null - } + // player data + player_index: player?.index ?? null } - - export function entitiesToUnitNumbers(entities: LuaEntity[]): uint[] { - let result: (uint) [] = [] - for (let entity of entities) { - if (entity.unit_number != null) { - result[result.length] = entity.unit_number - } - } - return result - } - } - export namespace Surface { - - export function surfaceToTable(surface: LuaSurface): SurfaceData { - return { - object_name: surface.object_name, - - name: surface.name, - index: surface.index, - daytime: surface.daytime, + export function entitiesToUnitNumbers(entities: LuaEntity[]): uint[] { + let result: (uint) [] = [] + for (let entity of entities) { + if (entity.unit_number != null) { + result[result.length] = entity.unit_number } } - + return result } - export namespace DataClasses { + export function surfaceToTable(surface: LuaSurface): SurfaceData { + return { + object_name: surface.object_name, - export function positionTableToTable(positionTable: PositionTable): PositionData { - return { - x: positionTable.x, - y: positionTable.y, - } + name: surface.name, + index: surface.index, + daytime: surface.daytime, } - } + + export function positionTableToTable(positionTable: PositionTable): PositionData { + return { + x: positionTable.x, + y: positionTable.y, + } + } + } diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventLogConsumer.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventLogConsumer.kt deleted file mode 100644 index 5ced240..0000000 --- a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventLogConsumer.kt +++ /dev/null @@ -1,7 +0,0 @@ -package dev.adamko.kafkatorio.processor - -/** - * Process the raw messages from a server. - */ -class FactorioEventLogConsumer { -} \ No newline at end of file diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt index d9e2359..d87339d 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt @@ -13,8 +13,8 @@ import org.apache.kafka.streams.kstream.Consumed import org.apache.kafka.streams.kstream.Produced class FactorioEventsTopology( - val websocketServer: WebsocketServer, - val builder: StreamsBuilder = StreamsBuilder(), + private val websocketServer: WebsocketServer, + private val builder: StreamsBuilder = StreamsBuilder(), ) { private val sourceTopic = "factorio-server-log" diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt index 4789991..05efe69 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt @@ -47,7 +47,7 @@ class WebsocketServer { messages.emit(msg) } - suspend fun start(): PolyHandler = supervisorScope builder@{ + suspend fun build(): PolyHandler = supervisorScope builder@{ coroutineContext.job.invokeOnCompletion { e -> e?.let { serverJob.completeExceptionally(it) } ?: serverJob.complete() diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt index c3fe7ec..f462adb 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt @@ -1,19 +1,11 @@ package dev.adamko.kafkatorio.processor.config -import com.fasterxml.jackson.databind.JsonNode import dev.adamko.kafkatorio.processor.config.PortVal.Companion.portVal -import java.io.StringReader import java.time.Clock import java.util.Properties import org.http4k.cloudnative.env.Environment import org.http4k.cloudnative.env.EnvironmentKey -import org.http4k.core.Credentials -import org.http4k.core.Uri -import org.http4k.format.Json -import org.http4k.lens.boolean -import org.http4k.lens.map import org.http4k.lens.nonEmptyString -import org.http4k.lens.uri /** * Load properties, in descending priority order, from diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt index 75b47fb..ca3d7e2 100644 --- a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ b/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -15,18 +15,5 @@ fun main() = runBlocking { val topology = FactorioEventsTopology(wsServer) topology.build() - wsServer.start().asServer(Undertow(9073)).start().block() + wsServer.build().asServer(Undertow(9073)).start().block() } - -// -// -//// a standard websocket app -//val websocketServer = websockets( -// "/lua-objects" bind { ws: Websocket -> -// ws.send(WsMessage("bob")) -// ws.onMessage { -// println("server received: $it") -// ws.send(it) -// } -// } -//).asServer(Undertow(9097)).start() diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/builtinTypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/builtinTypes.kt deleted file mode 100644 index 20d85e5..0000000 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/builtinTypes.kt +++ /dev/null @@ -1,98 +0,0 @@ -@file:Suppress("ClassName") - -package dev.adamko.kafkatorio.events.schema - - -import kotlin.jvm.JvmInline -import kotlinx.serialization.Serializable - - -/* - * The basic types used in the Factorio API. While Lua only supports the `boolean`, `number`, - * `string`, and `table` types (as they relate to the types listed below), the API docs will - * specify what C++ types these are converted to or from internally. - */ - - -/** - * Tables are enclosed in curly brackets, like this `{}` - * - * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#table) - */ -typealias F_table = MutableMap - -sealed interface FBuiltInType { - - sealed interface FNumber { - /** - * A floating-point number. This is a single-precision floating point number. Whilst Lua only uses double-precision - * numbers, when a function takes a float, the game engine will immediately convert the double-precision number to - * single-precision. - * - * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#float) - */ - @Serializable - @JvmInline - value class F_float(val float: Float) : FNumber - /** - * A double-precision floating-point number. This is the same data type as all Lua numbers use. - * - * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#double) - */ - @Serializable - @JvmInline - value class F_double(val double: Double) : FNumber - - /** - * 32-bit signed integer. Possible values are -2,147,483,648 to 2,147,483,647. - * - * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#int) - */ - @Serializable - @JvmInline - value class F_int(val int: Int) : FNumber - /** - * 8-bit signed integer. Possible values are -128 to 127. - * - * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#int8) - */ - @Serializable - @JvmInline - value class F_int8(val int8: Byte) : FNumber - - /** - * 32-bit unsigned integer. Possible values are 0 to 4,294,967,295. - * - * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#uint) - */ - @Serializable - @JvmInline - value class F_uint(val uint: UInt) : FNumber - /** - * 8-bit unsigned integer. Possible values are 0 to 255. - * - * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#uint8) - */ - @Serializable - @JvmInline - value class F_uint8(val uint8: UByte) : FNumber - /** - * 16-bit unsigned integer. Possible values are 0 to 65535. - * - * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#uint16) - */ - @Serializable - @JvmInline - value class F_uint16(val uint16: UShort) : FNumber - /** - * 64-bit unsigned integer. Possible values are 0 to 18,446,744,073,709,551,615. - * - * [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#uint64) - */ - @Serializable - @JvmInline - value class F_uint64(val uint64: ULong) : FNumber - } - - -} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index f1692b7..81090ed 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -11,18 +11,13 @@ import kotlinx.serialization.json.JsonClassDiscriminator @Serializable data class FactorioEvent( /** the initial Factorio event ({defines.events}) trigger */ - @SerialName("event_type") - val eventType: String, + @SerialName("event_type") val eventType: String, /** Schema versioning */ - @SerialName("mod_version") - val modVersion: String, - @SerialName("factorio_version") - val factorioVersion: String, + @SerialName("mod_version") val modVersion: String, + @SerialName("factorio_version") val factorioVersion: String, /** game time */ - @SerialName("tick") - val tick: UInt, - @SerialName("data") - val data: T + @SerialName("tick") val tick: UInt, + @SerialName("data") val data: T ) @@ -58,64 +53,46 @@ sealed class FactorioObjectData { @SerialName("LuaPlayer") data class PlayerData( @Serializable(with = ListAsObjectSerializer::class) - @SerialName("associated_characters_unit_numbers") - val associatedCharactersUnitNumbers: List, - @SerialName("character_unit_number") - val characterUnitNumber: UInt?, - @SerialName("name") - val name: String, - @SerialName("position") - val position: PositionData, + @SerialName("associated_characters_unit_numbers") val associatedCharactersUnitNumbers: List, + @SerialName("character_unit_number") val characterUnitNumber: UInt?, + @SerialName("name") val name: String, + @SerialName("position") val position: PositionData, ) : FactorioObjectData() { @Transient - override val objectName: String= "LuaPlayer" + override val objectName: String = "LuaPlayer" } @Serializable @SerialName("LuaEntity") data class EntityData( - @SerialName("active") - val active: Boolean, - @SerialName("health") - val health: Double?, - @SerialName("health_ratio") - val healthRatio: Double, - @SerialName("name") - val name: String, - @SerialName("position") - val position: PositionData, - @SerialName("surface_index") - val surfaceIndex: Int, - @SerialName("type") - val type: String, - @SerialName("unit_number") - val unitNumber: UInt? = null, + @SerialName("active") val active: Boolean, + @SerialName("health") val health: Double?, + @SerialName("health_ratio") val healthRatio: Double, + @SerialName("name") val name: String, + @SerialName("position") val position: PositionData, + @SerialName("surface_index") val surfaceIndex: Int, + @SerialName("type") val type: String, + @SerialName("unit_number") val unitNumber: UInt? = null, - @SerialName("player_index") - val playerIndex: UInt? = null, + @SerialName("player_index") val playerIndex: UInt? = null, ) : FactorioObjectData() { @Transient - override val objectName: String= "LuaEntity" + override val objectName: String = "LuaEntity" } @Serializable @SerialName("LuaSurface") data class SurfaceData( - @SerialName("daytime") - val daytime: Double, - @SerialName("index") - val index: UInt, - @SerialName("name") - val name: String, + @SerialName("daytime") val daytime: Double, + @SerialName("index") val index: UInt, + @SerialName("name") val name: String, ) : FactorioObjectData() { @Transient - override val objectName: String="LuaSurface" + override val objectName: String = "LuaSurface" } @Serializable data class PositionData( - @SerialName("x") - val x: Double, - @SerialName("y") - val y: Double, + @SerialName("x") val x: Double, + @SerialName("y") val y: Double, ) diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt index d16ec4f..4a8af3f 100644 --- a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt @@ -8,6 +8,9 @@ import me.ntrrgc.tsGenerator.TypeScriptGenerator import me.ntrrgc.tsGenerator.camelCaseToSnakeCase import org.intellij.lang.annotations.Language +/** + * Convert Kotlin classes to Typescript classes, using [TypeScriptGenerator] + */ fun main(args: Array) { val gen = diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index 531ef55..c52e925 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -8,6 +8,8 @@ plugins { id("dev.adamko.kafkatorio.infra.process-runner") } +description = "Start the Factorio game client" + val clientModsDirectory = file("""D:\Users\Adam\AppData\Roaming\Factorio\mods""") val factorioGameId = "427520" val steamExe = """C:\Program Files (x86)\Steam\steam.exe""" diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 36e61b7..5951ca5 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -48,46 +48,3 @@ tasks.dockerEnv { } tasks.build { dependsOn(deployModToServer) } - -// -//val factorioServerStop = tasks.register("factorioServerStop") { -// group = project.name -// -// mustRunAfter(deployModToServer) -// -// workingDir(modInfraDir) -// commandLine = parseSpaceSeparatedArgs("docker-compose stop factorio-server") -//} - -//val factorioServerUp = tasks.register("factorioServerUp") { -// group = project.name -// -// mustRunAfter(deployModToServer) -// dependsOn(factorioServerStop) -// -// workingDir(modInfraDir) -// commandLine = parseSpaceSeparatedArgs("docker-compose up -d factorio-server") -//} - -//val factorioServerRestart: Task by tasks.creating { -// group = project.name -// -// dependsOn(factorioServerStop, factorioServerUp) -//} -// - -// -//tasks.processRun { -// description = "Build the mod, upload to Server and Client, and start both" -// dependsOn( -// deployModToServer, -// factorioServerRestart, -// ) -//} -// -//tasks.processKill { -// dependsOn( -// factorioServerStop, -// ) -//} -// diff --git a/modules/infra-factorio-server/src/factorioEvents.Dockerfile b/modules/infra-factorio-server/factorio-and-kpipe-server/factorioEvents.Dockerfile similarity index 100% rename from modules/infra-factorio-server/src/factorioEvents.Dockerfile rename to modules/infra-factorio-server/factorio-and-kpipe-server/factorioEvents.Dockerfile diff --git a/modules/infra-factorio-server/src/kafka-pipe.sh b/modules/infra-factorio-server/factorio-and-kpipe-server/kafka-pipe.sh similarity index 100% rename from modules/infra-factorio-server/src/kafka-pipe.sh rename to modules/infra-factorio-server/factorio-and-kpipe-server/kafka-pipe.sh diff --git a/modules/infra-factorio-server/src/kcat.conf b/modules/infra-factorio-server/factorio-and-kpipe-server/kcat.conf similarity index 100% rename from modules/infra-factorio-server/src/kcat.conf rename to modules/infra-factorio-server/factorio-and-kpipe-server/kcat.conf From de5f420621d46934fd922f1eb793e35b02d104e8 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 28 Dec 2021 17:13:11 +0100 Subject: [PATCH 109/629] rename events-processor to events-server --- modules/{events-processor => events-server}/build.gradle.kts | 0 .../dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt | 0 .../dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt | 0 .../kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt | 0 .../adamko/kafkatorio/processor/config/ApplicationProperties.kt | 0 .../kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt | 0 .../kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt | 0 .../dev/adamko/kafkatorio/processor/config/environmentExt.kt | 0 .../kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt | 0 .../src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt | 0 .../src/main/resources/logback.xml | 0 settings.gradle.kts | 2 +- 12 files changed, 1 insertion(+), 1 deletion(-) rename modules/{events-processor => events-server}/build.gradle.kts (100%) rename modules/{events-processor => events-server}/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt (100%) rename modules/{events-processor => events-server}/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt (100%) rename modules/{events-processor => events-server}/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt (100%) rename modules/{events-processor => events-server}/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt (100%) rename modules/{events-processor => events-server}/src/main/kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt (100%) rename modules/{events-processor => events-server}/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt (100%) rename modules/{events-processor => events-server}/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt (100%) rename modules/{events-processor => events-server}/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt (100%) rename modules/{events-processor => events-server}/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt (100%) rename modules/{events-processor => events-server}/src/main/resources/logback.xml (100%) diff --git a/modules/events-processor/build.gradle.kts b/modules/events-server/build.gradle.kts similarity index 100% rename from modules/events-processor/build.gradle.kts rename to modules/events-server/build.gradle.kts diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt similarity index 100% rename from modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt similarity index 100% rename from modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt similarity index 100% rename from modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt similarity index 100% rename from modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt similarity index 100% rename from modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt similarity index 100% rename from modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt similarity index 100% rename from modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt similarity index 100% rename from modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt diff --git a/modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt similarity index 100% rename from modules/events-processor/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt diff --git a/modules/events-processor/src/main/resources/logback.xml b/modules/events-server/src/main/resources/logback.xml similarity index 100% rename from modules/events-processor/src/main/resources/logback.xml rename to modules/events-server/src/main/resources/logback.xml diff --git a/settings.gradle.kts b/settings.gradle.kts index 3af2206..29bcb98 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -3,8 +3,8 @@ rootProject.name = "kafkatorio" include( ":modules:events-mod", - ":modules:events-processor", ":modules:events-schema", + ":modules:events-server", ":modules:infra-factorio-client", ":modules:infra-factorio-server", From 841f07c8472af14e72c3c89b46c9852b1460f763 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 28 Dec 2021 17:24:20 +0100 Subject: [PATCH 110/629] a bit more tidying up --- .../dev/adamko/kafkatorio/lang/node.gradle.kts | 4 ++-- .../events-mod/src/main/typescript/package-lock.json | 2 +- modules/events-mod/src/main/typescript/package.json | 12 ++++-------- modules/infra-factorio-server/build.gradle.kts | 2 ++ modules/infra-kafka-pipe/build.gradle.kts | 2 +- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts index f335393..642bf90 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts @@ -1,7 +1,7 @@ package dev.adamko.kafkatorio.lang import com.github.gradle.node.NodePlugin -import com.github.gradle.node.npm.task.NpmTask +import com.github.gradle.node.npm.task.NpmInstallTask import dev.adamko.kafkatorio.gradle.areJsonPropertiesUpToDate import dev.adamko.kafkatorio.gradle.not import dev.adamko.kafkatorio.jsonMapper @@ -56,6 +56,6 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) { } tasks.assemble { dependsOn(updatePackageJson) } -tasks.withType { +tasks.withType { dependsOn(updatePackageJson) } diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index 32fb6ef..a7c3550 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.1.5", + "version": "0.1.6", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 033dca2..603a2d4 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -9,8 +9,7 @@ "engines": { "node": ">=10.13.0" }, - "devDependencies": { - }, + "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", @@ -19,10 +18,7 @@ "typescript": "4.5.4" }, "license": "UNLICENSED", - "peerDependencies": { - }, - "optionalDependencies": { - }, - "bundledDependencies": [ - ] + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] } diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 5951ca5..392f15c 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -22,6 +22,8 @@ val deployModToServer by tasks.registering(Copy::class) { description = "Copy the mod to the Factorio Docker server" group = project.name + dependsOn(factorioMod) + from( provider { factorioMod.incoming.artifacts.artifactFiles.files } ) diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index d3d3fb0..89066a3 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -25,4 +25,4 @@ val dockerBuildKafkaPipe by tasks.registering(Exec::class) { workingDir = dockerSrcDir.asFile commandLine = parseSpaceSeparatedArgs(""" docker-compose build kafka-pipe """) } -tasks.assemble { dependsOn(dockerBuildKafkaPipe) } +//tasks.assemble { dependsOn(dockerBuildKafkaPipe) } From a0c330384a5e61cad2ddea75d5c43afb580bdefd Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 4 Jan 2022 15:09:50 +0100 Subject: [PATCH 111/629] it is literally working --- README.md | 11 ++- gradle/kotlin-js-store/yarn.lock | 54 ++++++++++ gradle/libs.versions.toml | 7 +- .../main/typescript/schema/events-schema.ts | 10 ++ .../src/main/typescript/serdes/serdes.ts | 13 +++ modules/events-schema/build.gradle.kts | 6 +- .../events/schema/factorioEvents.kt | 99 ++++++++++++++----- .../events/schema/FactorioEventTest.kt | 8 +- modules/web-map/build.gradle.kts | 45 ++++++--- .../dev/adamko/kafkatorio/webmap/App.kt | 75 ++++++++++---- .../adamko/kafkatorio/webmap/converters.kt | 36 +++++++ .../dev/adamko/kafkatorio/webmap/json.kt | 7 ++ .../dev/adamko/kafkatorio/webmap/map.kt | 37 +++++++ .../dev/adamko/kafkatorio/webmap/state.kt | 92 +++++++++++++++++ .../adamko/kafkatorio/webmap/websockets.kt | 46 +++++++++ modules/web-map/src/main/web/index.html | 5 +- settings.gradle.kts | 11 +++ 17 files changed, 499 insertions(+), 63 deletions(-) create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt diff --git a/README.md b/README.md index b2ee244..5fa1128 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,14 @@ is provided. * https://jbrandhorst.com/post/go-protobuf-tips/ + +##### wasm + +kt -> wasm -> lua? +kt-flatbuffers -> wasm -> lua? + +https://www.npmjs.com/package/wasm2lua?activeTab=readme + ##### flatbuffers https://github.com/dvidelabs/flatcc @@ -56,6 +64,3 @@ https://github.com/dvidelabs/flatcc https://www.zash.se/lua-cbor.html https://code.zash.se/lua-cbor/archive/68b3a36d0816.tar.gz - - - diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index 18bda50..09534e0 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -2,6 +2,13 @@ # yarn lockfile v1 +"@babel/runtime@^7.9.2": + version "7.16.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.5.tgz#7f3e34bf8bdbbadf03fbb7b1ea0d929569c9487a" + integrity sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA== + dependencies: + regenerator-runtime "^0.13.4" + "@discoveryjs/json-ext@^0.5.0": version "0.5.6" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" @@ -81,6 +88,11 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== +"@types/geojson@*", "@types/geojson@7946.0.8": + version "7946.0.8" + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" + integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA== + "@types/glob@5 - 7": version "7.2.0" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" @@ -101,6 +113,13 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== +"@types/leaflet@^1.7.7": + version "1.7.7" + resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.7.7.tgz#3c9f629126e03405ed68cc1aa395e32df3312376" + integrity sha512-5/nNqTviSqUwPxbS3PlHl8ODjfnlpOXSFtUAi7dexnisO8E3pfyotChRY/hlIYGvbBiBcKNd6V18xA8O4OpHiQ== + dependencies: + "@types/geojson" "*" + "@types/minimatch@*": version "3.0.5" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" @@ -949,6 +968,14 @@ dukat@0.5.8-rc.3: google-protobuf "3.12.2" typescript "3.9.5" +dukat@0.5.8-rc.4: + version "0.5.8-rc.4" + resolved "https://registry.yarnpkg.com/dukat/-/dukat-0.5.8-rc.4.tgz#90384dcb50b14c26f0e99dae92b2dea44f5fce21" + integrity sha512-ZnMt6DGBjlVgK2uQamXfd7uP/AxH7RqI0BL9GLrrJb2gKdDxvJChWy+M9AQEaL+7/6TmxzJxFOsRiInY9oGWTA== + dependencies: + google-protobuf "3.12.2" + typescript "3.9.5" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -1280,6 +1307,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +geojson@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/geojson/-/geojson-0.5.0.tgz#3cd6c96399be65b56ee55596116fe9191ce701c0" + integrity sha1-PNbJY5m+ZbVu5VWWEW/pGRznAcA= + get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -1845,6 +1877,11 @@ kvision-assets@^5.0.7: resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-5.0.7.tgz#e6dc3e28a2d244b4c89318b060d3e7e337c15495" integrity sha512-szoL8ixFRTivLkbnmkWFjGJMk3bsUW/loUS5QfWThPwFnyFEw8ht3eBUrJ0V51Rn/WaJbVoPvY4SfIaiNu13bg== +leaflet@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.7.1.tgz#10d684916edfe1bf41d688a3b97127c0322a2a19" + integrity sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw== + loader-runner@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" @@ -2430,6 +2467,23 @@ rechoir@^0.7.0: dependencies: resolve "^1.9.0" +redux-thunk@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.1.tgz#0dd8042cf47868f4b29699941de03c9301a75714" + integrity sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q== + +redux@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.2.tgz#140f35426d99bb4729af760afcf79eaaac407104" + integrity sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw== + dependencies: + "@babel/runtime" "^7.9.2" + +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + regexp.prototype.flags@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cd4b7ac..d544e8c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,8 @@ camel-kafkaConnectors = "0.11.0" http4k = "4.17.6.0" kafka = "3.0.0" kotlinx-serialization = "1.3.2" -kvision = "5.6.1" +#kvision = "5.6.1" +kvision = "5.6.2-SNAPSHOT" log4j2 = "2.14.1" qosLogback = "1.2.5" slf4j = "1.7.30" @@ -50,8 +51,12 @@ kotlinx-serialization-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx- kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core" } kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json" } kotlinx-serialization-yaml = { group = "com.charleskorn.kaml", name = "kaml", version = "0.37.0" } + kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.6.0" } + kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.7.3" } +kotlinx-nodejs = { group = "org.jetbrains.kotlinx", name = "kotlinx-nodejs", version = "0.0.7" } + ## http4k ## http4k-bom = { group = "org.http4k", name = "http4k-bom", version.ref = "http4k" } diff --git a/modules/events-mod/src/main/typescript/schema/events-schema.ts b/modules/events-mod/src/main/typescript/schema/events-schema.ts index fccd740..88aa0db 100644 --- a/modules/events-mod/src/main/typescript/schema/events-schema.ts +++ b/modules/events-mod/src/main/typescript/schema/events-schema.ts @@ -11,6 +11,13 @@ interface FactorioEvent { tick: uint; } +interface Colour { + alpha: float; + blue: float; + green: float; + red: float; +} + interface PositionData { x: double; y: double; @@ -19,6 +26,9 @@ interface PositionData { interface PlayerData extends FactorioObjectData { associated_characters_unit_numbers: uint[]; character_unit_number: uint | null; + chat_colour: Colour; + colour: Colour; + last_online: uint; name: string; object_name: string; position: PositionData; diff --git a/modules/events-mod/src/main/typescript/serdes/serdes.ts b/modules/events-mod/src/main/typescript/serdes/serdes.ts index 76425c4..128f219 100644 --- a/modules/events-mod/src/main/typescript/serdes/serdes.ts +++ b/modules/events-mod/src/main/typescript/serdes/serdes.ts @@ -10,6 +10,9 @@ export namespace Serdes { character_unit_number: player.character?.unit_number ?? null, associated_characters_unit_numbers: charIds, position: positionTableToTable(player.position), + colour: mapColour(player.color), + chat_colour: mapColour(player.chat_color), + last_online: player.last_online } } @@ -62,4 +65,14 @@ export namespace Serdes { } } + export function mapColour(color: Color): Colour { + color = (color as ColorTable) + return { + red: color.r ?? 0, + green: color.g ?? 0, + blue: color.b ?? 0, + alpha: color.a ?? 0, + } + } + } diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index ad6a372..94ce097 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -30,9 +30,9 @@ kotlin { val commonMain by getting { dependencies { - implementation(project.dependencies.enforcedPlatform(libs.kotlin.bom)) + implementation(project.dependencies.platform(libs.kotlin.bom)) - implementation(project.dependencies.enforcedPlatform(libs.kotlinx.serialization.bom)) + implementation(project.dependencies.platform(libs.kotlinx.serialization.bom)) implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.json) @@ -44,7 +44,7 @@ kotlin { implementation(kotlin("test")) - implementation(project.dependencies.enforcedPlatform(libs.kotest.bom)) + implementation(project.dependencies.platform(libs.kotest.bom)) implementation("io.kotest:kotest-assertions-core") implementation("io.kotest:kotest-property") implementation("io.kotest:kotest-assertions-json") diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index 81090ed..ebf5d33 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -11,13 +11,18 @@ import kotlinx.serialization.json.JsonClassDiscriminator @Serializable data class FactorioEvent( /** the initial Factorio event ({defines.events}) trigger */ - @SerialName("event_type") val eventType: String, + @SerialName("event_type") + val eventType: String, /** Schema versioning */ - @SerialName("mod_version") val modVersion: String, - @SerialName("factorio_version") val factorioVersion: String, + @SerialName("mod_version") + val modVersion: String, + @SerialName("factorio_version") + val factorioVersion: String, /** game time */ - @SerialName("tick") val tick: UInt, - @SerialName("data") val data: T + @SerialName("tick") + val tick: UInt, + @SerialName("data") + val data: T ) @@ -53,10 +58,20 @@ sealed class FactorioObjectData { @SerialName("LuaPlayer") data class PlayerData( @Serializable(with = ListAsObjectSerializer::class) - @SerialName("associated_characters_unit_numbers") val associatedCharactersUnitNumbers: List, - @SerialName("character_unit_number") val characterUnitNumber: UInt?, - @SerialName("name") val name: String, - @SerialName("position") val position: PositionData, + @SerialName("associated_characters_unit_numbers") + val associatedCharactersUnitNumbers: List, + @SerialName("character_unit_number") + val characterUnitNumber: UInt?, + @SerialName("name") + val name: String, + @SerialName("position") + val position: PositionData, + @SerialName("colour") + val colour: Colour, + @SerialName("chat_colour") + val chatColour: Colour, + @SerialName("last_online") + val lastOnline: UInt, ) : FactorioObjectData() { @Transient override val objectName: String = "LuaPlayer" @@ -65,16 +80,25 @@ data class PlayerData( @Serializable @SerialName("LuaEntity") data class EntityData( - @SerialName("active") val active: Boolean, - @SerialName("health") val health: Double?, - @SerialName("health_ratio") val healthRatio: Double, - @SerialName("name") val name: String, - @SerialName("position") val position: PositionData, - @SerialName("surface_index") val surfaceIndex: Int, - @SerialName("type") val type: String, - @SerialName("unit_number") val unitNumber: UInt? = null, + @SerialName("active") + val active: Boolean, + @SerialName("health") + val health: Double?, + @SerialName("health_ratio") + val healthRatio: Double, + @SerialName("name") + val name: String, + @SerialName("position") + val position: PositionData, + @SerialName("surface_index") + val surfaceIndex: Int, + @SerialName("type") + val type: String, + @SerialName("unit_number") + val unitNumber: UInt? = null, - @SerialName("player_index") val playerIndex: UInt? = null, + @SerialName("player_index") + val playerIndex: UInt? = null, ) : FactorioObjectData() { @Transient override val objectName: String = "LuaEntity" @@ -83,9 +107,12 @@ data class EntityData( @Serializable @SerialName("LuaSurface") data class SurfaceData( - @SerialName("daytime") val daytime: Double, - @SerialName("index") val index: UInt, - @SerialName("name") val name: String, + @SerialName("daytime") + val daytime: Double, + @SerialName("index") + val index: UInt, + @SerialName("name") + val name: String, ) : FactorioObjectData() { @Transient override val objectName: String = "LuaSurface" @@ -93,6 +120,32 @@ data class SurfaceData( @Serializable data class PositionData( - @SerialName("x") val x: Double, - @SerialName("y") val y: Double, + val x: Double, + val y: Double, ) + +/** + * Red, green, blue and alpha values, all in range `[0, 1]` or all in range `[0, 255]` if any + * value is > 1. + * + * All values here are optional. Color channels default to 0, the alpha channel defaults to 1. + */ +@Serializable +data class Colour( + val red: Float = 0f, + val green: Float = 0f, + val blue: Float = 0f, + val alpha: Float = 1f, +) { + /** True if any value is greater than 1, so the values are hexadecimal. */ + fun isDecimal(): Boolean { + return red > 1f + || green > 1f + || blue > 1f + || alpha > 1f + } + + /** True if all values are between `[0..1]`. */ + fun isPercentage(): Boolean = !isDecimal() + +} diff --git a/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt index 8bae62f..312eda6 100644 --- a/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt +++ b/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt @@ -21,7 +21,8 @@ class FactorioEventTest : BehaviorSpec({ "position": { "x": -3.5703125, "y": 29.75 - } + }, + "last_online": 123 }, "event_type": "on_player_joined_game", "mod_version": "0.0.4", @@ -41,7 +42,10 @@ class FactorioEventTest : BehaviorSpec({ position = PositionData( x = -3.5703125, y = 29.75 - ) + ), + colour = Colour(), + chatColour = Colour(), + lastOnline = 123u ), eventType = "on_player_joined_game", modVersion = "0.0.4", diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 16522c2..fb7a2e2 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -1,9 +1,9 @@ +import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig plugins { id("dev.adamko.kafkatorio.lang.kotlin-js") kotlin("plugin.serialization") -// kotlin("js") // version kotlinVersion id("io.kvision") version "5.6.1" } @@ -13,7 +13,7 @@ kotlin { browser { runTask { outputFileName = "main.bundle.js" - sourceMaps = false + sourceMaps = true devServer = KotlinWebpackConfig.DevServer( open = false, port = 3000, @@ -37,31 +37,54 @@ kotlin { } sourceSets { - val kvisionVersion: String = libs.versions.kvision.get() + + all { + languageSettings.optIn("kotlin.RequiresOptIn") + languageSettings.optIn("kotlinx.serialization.ExperimentalSerializationApi") + } main { dependencies { + implementation(projects.modules.eventsSchema) + implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7") + implementation("org.jetbrains.kotlinx:kotlinx-html:0.7.3") - implementation("io.kvision:kvision:$kvisionVersion") - implementation("io.kvision:kvision-bootstrap:$kvisionVersion") - implementation("io.kvision:kvision-bootstrap-css:$kvisionVersion") - implementation("io.kvision:kvision-bootstrap-icons:$kvisionVersion") - implementation("io.kvision:kvision-fontawesome:$kvisionVersion") - implementation("io.kvision:kvision-state:$kvisionVersion") - implementation("io.kvision:kvision-chart:$kvisionVersion") + kvision("kvision") + kvision("kvision-bootstrap") + kvision("kvision-bootstrap-css") + kvision("kvision-bootstrap-icons") + kvision("kvision-fontawesome") + kvision("kvision-state") + kvision("kvision-chart") + kvision("kvision-maps") + kvision("kvision-redux") + kvision("kvision-state-flow") + implementation(libs.kotlinx.coroutines) } val webDir = file("src/main/web") resources.srcDir(webDir) } + test { dependencies { implementation(kotlin("test-js")) - implementation("io.kvision:kvision-testutils:$kvisionVersion") + + kvision("kvision-testutils") } } } } + +fun KotlinDependencyHandler.kvision( + module: String, + version: Provider = libs.versions.kvision, + configure: ExternalModuleDependency.() -> Unit = { + isChanging = true + } +) { + implementation("io.kvision:$module:${version.get()}", configure) +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index 0e6bcce..762d111 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -1,34 +1,73 @@ package dev.adamko.kafkatorio.webmap import io.kvision.Application -import io.kvision.CoreModule -import io.kvision.BootstrapModule import io.kvision.BootstrapCssModule import io.kvision.BootstrapIconsModule -import io.kvision.FontAwesomeModule +import io.kvision.BootstrapModule import io.kvision.ChartModule +import io.kvision.CoreModule +import io.kvision.FontAwesomeModule import io.kvision.html.div +import io.kvision.maps.Maps import io.kvision.module import io.kvision.panel.root +import io.kvision.redux.ReduxStore import io.kvision.startApplication -class App : Application() { - override fun start() { - root("kvapp") { - div("Hello world") - } + +class App( + reduxStore: ReduxStore, + wsService: WebsocketService +) : Application() { + private var appState: MutableMap = mutableMapOf() + + var reduxStore: ReduxStore by appState + var wsService: WebsocketService by appState + + init { + this.reduxStore = reduxStore + this.wsService = wsService + } + + private val kvMaps: Maps + get() = reduxStore.getState().kvMaps + + override fun start(state: Map) { + this.appState = state.toMutableMap() + + root("kvapp") { + div("Kafkatorio Web Map") + add(kvMaps) } + } + + override fun dispose(): Map { + return appState + } + } + fun main() { - startApplication( - ::App, - module.hot, - BootstrapModule, - BootstrapCssModule, - BootstrapIconsModule, - FontAwesomeModule, - ChartModule, - CoreModule - ) + startApplication( + { + val reduxStore = createFactorioReduxStore() + val wsService = WebsocketService( + "ws://localhost:9073/ws", + reduxStore, + ) + + App( + reduxStore = reduxStore, + wsService = wsService + ) + }, + module.hot, + BootstrapModule, + BootstrapCssModule, + BootstrapIconsModule, + FontAwesomeModule, + ChartModule, + CoreModule + ) } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt new file mode 100644 index 0000000..bd83abe --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt @@ -0,0 +1,36 @@ +package dev.adamko.kafkatorio.webmap + +import dev.adamko.kafkatorio.events.schema.Colour +import dev.adamko.kafkatorio.events.schema.PlayerData +import externals.leaflet.geo.LatLng +import io.kvision.maps.Maps +import kotlin.math.roundToInt + + +fun Colour.toHexString(includeAlpha: Boolean = false): String { + + val hexConverter: Float.() -> String = if (isDecimal()) { + Float::decimalToHex + } else { + Float::percentageToHex + } + + val length = if (includeAlpha) 9 else 7 + return buildString(length) { + append('#') + append(red.hexConverter()) + append(green.hexConverter()) + append(blue.hexConverter()) + if (includeAlpha) { + append(alpha.hexConverter()) + } + } +} + +fun Float.decimalToHex(): String = + roundToInt().toString(16).padStart(2, ' ') + +fun Float.percentageToHex(): String = + times(255).roundToInt().toString(16).padStart(2, ' ') + +fun PlayerData.latLng(): LatLng = Maps.L.latLng((position.y * -1) to position.x) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt new file mode 100644 index 0000000..d1acf02 --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt @@ -0,0 +1,7 @@ +package dev.adamko.kafkatorio.webmap + +import kotlinx.serialization.json.Json + +val jsonMapper = Json { + prettyPrint = true +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt new file mode 100644 index 0000000..b4233f1 --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -0,0 +1,37 @@ +package dev.adamko.kafkatorio.webmap + +import externals.leaflet.geo.CRS +import externals.leaflet.geo.LatLng +import io.kvision.maps.DefaultTileLayers +import io.kvision.maps.Maps +import io.kvision.utils.px + +// +//val polyline = Maps.L.polyline( +// listOf( +// LatLng(55, 2), +// LatLng(65, 2), +// LatLng(65, 20), +// LatLng(55, 20), +// LatLng(55, 2), +// ) +//) { +// noClip = true +//} + +fun createFactorioMap() = Maps { + width = 800.px + height = 800.px + margin = 10.px + + configureLeafletMap { + setView(LatLng(0, 0), 13) + +// DefaultTileLayers.OpenStreetMap.addTo(this) + + with(options) { + crs = CRS.Simple + } + + } +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt new file mode 100644 index 0000000..ec1c63d --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt @@ -0,0 +1,92 @@ +package dev.adamko.kafkatorio.webmap + +import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.PlayerData +import externals.leaflet.geo.LatLng +import externals.leaflet.layer.overlay.Tooltip +import externals.leaflet.layer.vector.CircleMarker +import io.kvision.maps.Maps +import io.kvision.maps.Maps.Companion.L +import io.kvision.redux.ReduxStore +import io.kvision.redux.createReduxStore +import io.kvision.utils.obj +import redux.RAction + +fun createFactorioReduxStore(): ReduxStore = + createReduxStore( + ::factorioGameReducer, + FactorioGameState( + kvMaps = createFactorioMap(), + players = emptyMap() + ) + ) + +data class FactorioGameState( + val kvMaps: Maps, + val players: Map, +) + + +sealed class FactorioUpdate : RAction { + data class PlayerUpdate(val event: FactorioEvent<*>, val playerData: PlayerData) : + FactorioUpdate() +} + +fun factorioGameReducer(state: FactorioGameState, update: FactorioUpdate): FactorioGameState = + when (update) { + is FactorioUpdate.PlayerUpdate -> { + + val playerState = state.players.getOrElse(update.playerData.name) { + val newState = PlayerState(update.playerData) + state.kvMaps.leafletMap { + addLayer(newState.mapMarker) + newState.mapMarker.openPopup() +// setView(update.playerData.latLng()) + } + newState + } + + playerState.update(update.playerData) + + val updatedPlayersState = state.players + (update.playerData.name to playerState) + state.copy(players = updatedPlayersState) + } + } + + +data class PlayerState( + private var playerData: PlayerData, + val mapMarker: CircleMarker = createMapMarker(playerData) +) { + + fun update(playerData: PlayerData) { + this.playerData = playerData + mapMarker.setLatLng(playerData.latLng()) + println("updated player ${playerData.name}") + } + + companion object { + + fun createMapMarker(playerData: PlayerData): CircleMarker { + + val playerLatLng = playerData.latLng() + val playerMapTooltip = "${playerData.name} [$playerLatLng]" + + val circle = L.circleMarker(playerLatLng) { + color = playerData.colour.toHexString(false) + fillColor = color + fillOpacity = 1f + radius = 10 + className = playerData.objectName +// interactive = false + } + + circle.bindTooltip(playerMapTooltip, obj { +// interactive = false + }) + + return circle + } + } + +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt new file mode 100644 index 0000000..fdc7f95 --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -0,0 +1,46 @@ +package dev.adamko.kafkatorio.webmap + +import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.FactorioObjectData +import dev.adamko.kafkatorio.events.schema.PlayerData +import io.kvision.redux.ReduxStore +import kotlinx.serialization.decodeFromString +import org.w3c.dom.MessageEvent +import org.w3c.dom.WebSocket + +class WebsocketService( + private val wsUrl: String, + private val reduxStore: ReduxStore, +) { + private val ws = WebSocket(wsUrl) + + init { + ws.onmessage = ::handleMessageEvent + } + + private fun handleMessageEvent(msg: MessageEvent) { + + val data = msg.data as? String + + if ( + data != null + && data.trim().startsWith("{") + && data.trim().endsWith("}") + ) { + + println(data.replace('\n', ' ')) + val event: FactorioEvent = jsonMapper.decodeFromString(data) + + when (val eventData = event.data) { + is PlayerData -> { + reduxStore.dispatch(FactorioUpdate.PlayerUpdate(event, eventData)) + } + else -> {} + } + } else { + println(data) + + } + + } +} diff --git a/modules/web-map/src/main/web/index.html b/modules/web-map/src/main/web/index.html index f7c610c..53f5626 100644 --- a/modules/web-map/src/main/web/index.html +++ b/modules/web-map/src/main/web/index.html @@ -1,9 +1,10 @@ - + - KVision Template + Kafkatorio Web Map + diff --git a/settings.gradle.kts b/settings.gradle.kts index 29bcb98..d05230b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -21,3 +21,14 @@ enableFeaturePreview("VERSION_CATALOGS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") apply(from = "./buildSrc/repositories.settings.gradle.kts") + +@Suppress("UnstableApiUsage") // centralized repositories is incubating +dependencyResolutionManagement { + repositories { + mavenLocal { + content { + includeGroup("io.kvision") + } + } + } +} From 58233c9343aace8b971a2808daa1b26cfef8efd4 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 6 Jan 2022 09:16:44 +0100 Subject: [PATCH 112/629] - mod refactoring into separate files, specific dirs - start work on emitting prototypes - start preparing for generating map tiles for leaflet - start work on more events - console chat - chunk charted --- README.md | 21 ++-- build.gradle.kts | 2 +- .../events-mod/src/main/typescript/control.ts | 9 +- .../events-mod/src/main/typescript/events.ts | 97 ++++++------------- .../src/main/typescript/events/emitter.ts | 21 ++++ .../src/main/typescript/events/handlers.ts | 82 ++++++++++++++++ .../typescript/{serdes => events}/serdes.ts | 23 ++++- .../src/main/typescript/package-lock.json | 8 +- .../src/main/typescript/package.json | 4 +- .../typescript/prototypes/emitPrototypes.ts | 42 ++++++++ .../main/typescript/schema/events-schema.ts | 39 +++++++- .../src/main/typescript/tsconfig.json | 5 +- modules/events-schema/build.gradle.kts | 3 +- .../events/schema/factorioEvents.kt | 41 ++++++++ .../events/schema/factorioPrototypes.kt | 28 ++++++ .../adamko/kafkatorio/events/schema/kt2ts.kt | 3 +- 16 files changed, 334 insertions(+), 94 deletions(-) create mode 100644 modules/events-mod/src/main/typescript/events/emitter.ts create mode 100644 modules/events-mod/src/main/typescript/events/handlers.ts rename modules/events-mod/src/main/typescript/{serdes => events}/serdes.ts (78%) create mode 100644 modules/events-mod/src/main/typescript/prototypes/emitPrototypes.ts create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt diff --git a/README.md b/README.md index 5fa1128..507d532 100644 --- a/README.md +++ b/README.md @@ -50,17 +50,14 @@ kt-flatbuffers -> wasm -> lua? https://www.npmjs.com/package/wasm2lua?activeTab=readme -##### flatbuffers -https://github.com/dvidelabs/flatcc +##### Encodings - -##### z85 encoding - -* Kotlin https://gist.github.com/ischumacher/b4929f26341ebef62cbce35c65543eda -* Lua https://web-eworks.github.io/lZ85/ - -#### CBOR - -https://www.zash.se/lua-cbor.html -https://code.zash.se/lua-cbor/archive/68b3a36d0816.tar.gz +* flatbuffers https://github.com/dvidelabs/flatcc +* z85 encoding + * Kotlin https://gist.github.com/ischumacher/b4929f26341ebef62cbce35c65543eda + * Lua https://web-eworks.github.io/lZ85/ +* https://github.com/SafeteeWoW/LibDeflate +* CBOR + * https://www.zash.se/lua-cbor.html + * https://code.zash.se/lua-cbor/archive/68b3a36d0816.tar.gz diff --git a/build.gradle.kts b/build.gradle.kts index b67ca9a..42a664f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.1.6" +version = "0.1.7" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index 544678b..e0064ea 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -1 +1,8 @@ -require("events") \ No newline at end of file +import {emitTiles} from "./prototypes/emitPrototypes"; + +require("events") + +// on startup, push out prototypes +script.on_configuration_changed((e: ConfigurationChangedData) => { + emitTiles() +}) diff --git a/modules/events-mod/src/main/typescript/events.ts b/modules/events-mod/src/main/typescript/events.ts index 7ac5ec3..fd5d7d3 100644 --- a/modules/events-mod/src/main/typescript/events.ts +++ b/modules/events-mod/src/main/typescript/events.ts @@ -1,63 +1,16 @@ -import {Serdes} from "./serdes/serdes" - -const MOD_VERSION = script.active_mods["@mod.name@"] ?? "UNKNOWN" -const FACTORIO_VERSION = script.active_mods["base"] ?? "UNKNOWN" +import { + handleChunkUpdate, + handleConsoleChat, + handleEntityUpdate, + handlePlayerUpdate, + handleSurfaceUpdate +} from "./events/handlers"; const mapEventIdToName = new LuaTable() for (const [k, v] of pairs(defines.events)) { mapEventIdToName.set(v, k) } -function handlePlayerUpdate(tick: uint, playerIndex: uint, eventType: string) { - let player: LuaPlayer = game.players[playerIndex] - let table = Serdes.playerToTable(player) - emitEvent(table, tick, eventType) - - handleCharactersEvent(tick, playerIndex, eventType) -} - -function handleCharactersEvent(tick: uint, playerIndex: uint, eventType: string) { - - let player: LuaPlayer = game.players[playerIndex] - - if (player.character != undefined) { - handleEntityUpdate(tick, player.character, eventType) - } - for (const character of player.get_associated_characters()) { - if (character != undefined) { - handleEntityUpdate(tick, character, eventType) - } - } -} - -function handleEntityUpdate(tick: uint, entity: LuaEntity, eventType: string) { - let table = Serdes.entityToTable(entity) - emitEvent(table, tick, eventType) -} - -function surfaceEvent(tick: uint, surface: LuaSurface, eventType: string) { - let table = Serdes.surfaceToTable(surface) - emitEvent(table, tick, eventType) -} - -// const SERVER_ID: uint = 0 -// const EVENT_FILE_DIR: string = "events" -/** Emit a serialised event */ -function emitEvent(eventData: T, tick: uint, eventType: string) { - - let event: FactorioEvent = { - data: eventData, - event_type: eventType, - mod_version: MOD_VERSION, - factorio_version: FACTORIO_VERSION, - tick: tick - } - - let data = game.table_to_json(event) - - localised_print(`FactorioEvent: ${data}`) -} - // script.on_event( // [defines.events.on_pre_build, defines.events.on_player_dropped_item], // (e: OnPreBuildEvent | OnPlayerDroppedItemEvent) => { @@ -94,20 +47,32 @@ script.on_event( defines.events.on_tick, (e: OnTickEvent) => { if (e.tick % 60 == 0) { - - for (const [index, _] of pairs(game.surfaces)) { - let surface = game.get_surface(index) // TODO fix / report can't iterate over surfaces - if (surface != undefined) { - surfaceEvent(e.tick, surface, mapEventIdToName.get(e.name)) - } - // let surface = game.surfaces[index] - // surfaceEvent(e.tick, surface, mapEventIdToName.get(e.name)) + for (const [_, surface] of pairs(game.surfaces)) { + handleSurfaceUpdate(e.tick, surface, mapEventIdToName.get(e.name)) } + + // for (const [index, _] of pairs(game.surfaces)) { + // let surface = game.get_surface(index) // TODO fix / report can't iterate over surfaces + // if (surface != undefined) { + // handleSurfaceUpdate(e.tick, surface, mapEventIdToName.get(e.name)) + // } + //// let surface = game.surfaces[index] + //// surfaceEvent(e.tick, surface, mapEventIdToName.get(e.name)) + // } } } -); +) +script.on_event( + defines.events.on_console_chat, + (e: OnConsoleChatEvent) => { + handleConsoleChat(e.tick, e.player_index, e.message, mapEventIdToName.get(e.name)) + } +) -// script.on_load(() => { -// game.print("loaded Factorio Web Map!") -// }); +script.on_event( + defines.events.on_chunk_charted, + (e: OnChunkChartedEvent) => { + handleChunkUpdate(e.tick, mapEventIdToName.get(e.name), e.surface_index, e.position) + } +) diff --git a/modules/events-mod/src/main/typescript/events/emitter.ts b/modules/events-mod/src/main/typescript/events/emitter.ts new file mode 100644 index 0000000..8613fae --- /dev/null +++ b/modules/events-mod/src/main/typescript/events/emitter.ts @@ -0,0 +1,21 @@ +export const MOD_VERSION = script.active_mods["@mod.name@"] ?? "UNKNOWN" +export const FACTORIO_VERSION = script.active_mods["base"] ?? "UNKNOWN" + +// const SERVER_ID: uint = 0 +// const EVENT_FILE_DIR: string = "events" + +/** Emit a serialised event */ +export function emitEvent(eventData: T, tick: uint, eventType: string) { + + let event: FactorioEvent = { + data: eventData, + event_type: eventType, + mod_version: MOD_VERSION, + factorio_version: FACTORIO_VERSION, + tick: tick + } + + let data = game.table_to_json(event) + + localised_print(`FactorioEvent: ${data}`) +} diff --git a/modules/events-mod/src/main/typescript/events/handlers.ts b/modules/events-mod/src/main/typescript/events/handlers.ts new file mode 100644 index 0000000..e2ec935 --- /dev/null +++ b/modules/events-mod/src/main/typescript/events/handlers.ts @@ -0,0 +1,82 @@ +import {Serdes} from "./serdes" +import {emitEvent} from "./emitter"; + +export function handlePlayerUpdate(tick: uint, playerIndex: uint, eventType: string) { + let player: LuaPlayer = game.players[playerIndex] + let table = Serdes.playerToTable(player) + emitEvent(table, tick, eventType) + + handleCharactersEvent(tick, playerIndex, eventType) +} + +export function handleCharactersEvent(tick: uint, playerIndex: uint, eventType: string) { + + let player: LuaPlayer = game.players[playerIndex] + + if (player.character != undefined) { + handleEntityUpdate(tick, player.character, eventType) + } + for (const character of player.get_associated_characters()) { + if (character != undefined) { + handleEntityUpdate(tick, character, eventType) + } + } +} + +export function handleEntityUpdate(tick: uint, entity: LuaEntity, eventType: string) { + let table = Serdes.entityToTable(entity) + emitEvent(table, tick, eventType) +} + +export function handleSurfaceUpdate( + tick: uint, + surface: LuaSurface, + eventType: string +) { + let table = Serdes.surfaceToTable(surface) + emitEvent(table, tick, eventType) +} + + +export function handleConsoleChat( + tick: uint, + playerIndex: uint | undefined, + message: string, + eventType: string, +) { + let table = Serdes.consoleChat(message, playerIndex) + emitEvent(table, tick, eventType) +} + +const CHUNK_SIZE = 32 + +export function handleChunkUpdate(tick: uint, + eventType: string, + surfaceIndex: uint, + position: ChunkPosition) { + + let surface = game.get_surface(surfaceIndex) + + let x = (position as ChunkPositionTable).x * CHUNK_SIZE + let y = (position as ChunkPositionTable).y * CHUNK_SIZE + + let tiles = surface?.find_tiles_filtered({ + position: {x: x, y: y}, + radius: CHUNK_SIZE, + collision_mask: ["ground-tile", "water-tile"] + } + ) ?? [] + + let tilePositionMap = new Map(); + for (let tile of tiles) { + let position = Serdes.positionTableToTable(tile.position) + tilePositionMap.set(position, Serdes.convertTile(tile)) + } + let mapChunk: FactorioTilesMap = { + object_name: "FactorioTilesMap", + tiles: tilePositionMap, + } + + emitEvent(mapChunk, tick, eventType) + +} diff --git a/modules/events-mod/src/main/typescript/serdes/serdes.ts b/modules/events-mod/src/main/typescript/events/serdes.ts similarity index 78% rename from modules/events-mod/src/main/typescript/serdes/serdes.ts rename to modules/events-mod/src/main/typescript/events/serdes.ts index 128f219..3394ba6 100644 --- a/modules/events-mod/src/main/typescript/serdes/serdes.ts +++ b/modules/events-mod/src/main/typescript/events/serdes.ts @@ -1,6 +1,5 @@ export namespace Serdes { - export function playerToTable(player: LuaPlayer): PlayerData { let charIds = entitiesToUnitNumbers(player.get_associated_characters()) return { @@ -65,8 +64,7 @@ export namespace Serdes { } } - export function mapColour(color: Color): Colour { - color = (color as ColorTable) + export function mapColour(color: ColorTable): Colour { return { red: color.r ?? 0, green: color.g ?? 0, @@ -75,4 +73,23 @@ export namespace Serdes { } } + export function consoleChat(content: string, playerIndex?: uint): ConsoleChatMessage { + return { + object_name: "ConsoleChatMessage", + + author_player_index: playerIndex ?? null, + content: content + } + } + + export function convertTile(tile: LuaTile): FactorioTile { + return { + object_name: tile.object_name, + + position: tile.position, + prototype_name: tile.prototype.name, + surface_index: tile.surface.index + } + } + } diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index a7c3550..4fe36f3 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.1.6", + "version": "0.1.7", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -74,9 +74,9 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.14.1.tgz", - "integrity": "sha512-0ot54PB1/bvSz2dENYh2pdQSdGgBuxD4ZxRVBlp8R1AiurbU2yqRvn8JPX5oOMcJjRGHqnO8g0m4R3fRwI8qvQ==" + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.15.0.tgz", + "integrity": "sha512-hEpW+nRL3q5vg3aOxbNbYpwARxYzMTncihurAucwnpQ/IDc4w4PrO2/OWHI5R+PkZSEQUY5LSRxG7qrGqDeWHQ==" }, "typescript": { "version": "4.5.4", diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 603a2d4..5fd898c 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.1.6", + "version": "0.1.7", "private": true, "scripts": { "build": "tstl", @@ -14,7 +14,7 @@ "lua-types": "^2.11.0", "@types/node": "^12.0.8", "typescript-to-lua": "1.3.0", - "typed-factorio": "0.14.1", + "typed-factorio": "0.15.0", "typescript": "4.5.4" }, "license": "UNLICENSED", diff --git a/modules/events-mod/src/main/typescript/prototypes/emitPrototypes.ts b/modules/events-mod/src/main/typescript/prototypes/emitPrototypes.ts new file mode 100644 index 0000000..44aa893 --- /dev/null +++ b/modules/events-mod/src/main/typescript/prototypes/emitPrototypes.ts @@ -0,0 +1,42 @@ +import {Serdes} from "../events/serdes"; + +export function emitTiles() { + + let tilePrototypes = new LuaTable() + + for (const [_, tile] of pairs(game.tile_prototypes)) { + // let ttttt = game.tile_prototypes[tileName] + tilePrototypes.set(tile.name, mapTilePrototype(tile)) + } + + // for (let tileName in game.tile_prototypes) { + // const tile = game.tile_prototypes[tileName] + // tilePrototypes.set(tileName, mapTilePrototype(tile)) + // } + + // for (const [id, player] of pairs(game.players)) { + // const num: number = id + // const p: LuaPlayer = player + // } + emitPrototypes(tilePrototypes) +} + +function mapTilePrototype(tile: LuaTilePrototype): FactorioMapTilePrototype { + return { + object_name: tile.object_name, + + name: tile.name, + order: tile.order, + layer: tile.layer, + collision_masks: [], + map_color: Serdes.mapColour(tile.map_color), + can_be_mined: tile.mineable_properties.minable, + } +} + +function emitPrototypes(prototypes: LuaTable) { + + let data = game.table_to_json(prototypes) + + localised_print(`FactorioPrototype: ${data}`) +} diff --git a/modules/events-mod/src/main/typescript/schema/events-schema.ts b/modules/events-mod/src/main/typescript/schema/events-schema.ts index 88aa0db..24d67a3 100644 --- a/modules/events-mod/src/main/typescript/schema/events-schema.ts +++ b/modules/events-mod/src/main/typescript/schema/events-schema.ts @@ -1,4 +1,4 @@ -// Generated by TypeScriptGenerator - do edit this file manually +// Generated by TypeScriptGenerator - do not edit this file manually interface FactorioObjectData { object_name: string; } @@ -52,4 +52,41 @@ interface SurfaceData extends FactorioObjectData { index: uint; name: string; object_name: string; +} + +interface ConsoleChatMessage extends FactorioObjectData { + author_player_index: uint | null; + content: string; + object_name: string; +} + +interface FactorioTile extends FactorioObjectData { + object_name: string; + position: PositionData; + prototype_name: string; + surface_index: int; +} + +interface FactorioTilesMap extends FactorioObjectData { + object_name: string; + tiles: Map; +} + +interface FactorioTiles extends FactorioObjectData { + object_name: string; + tiles: FactorioTile[]; +} + +interface FactorioPrototype { + object_name: string; +} + +interface FactorioMapTilePrototype extends FactorioPrototype { + can_be_mined: boolean; + collision_masks: string[]; + layer: uint; + map_color: Colour; + name: string; + object_name: string; + order: string; } \ No newline at end of file diff --git a/modules/events-mod/src/main/typescript/tsconfig.json b/modules/events-mod/src/main/typescript/tsconfig.json index 1e9e646..70b9ed4 100644 --- a/modules/events-mod/src/main/typescript/tsconfig.json +++ b/modules/events-mod/src/main/typescript/tsconfig.json @@ -12,6 +12,8 @@ "lua-types/5.2", "typed-factorio/runtime" ], + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, "explainFiles": true, "forceConsistentCasingInFileNames": true, "listEmittedFiles": true, @@ -22,8 +24,7 @@ "strict": true, "strictFunctionTypes": true, "strictNullChecks": true, - "traceResolution": true, - "esModuleInterop": true + "traceResolution": true }, "tstl": { "luaTarget": "5.2", diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index 94ce097..efe3409 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -53,7 +53,8 @@ kotlin { val jvmMain by getting { dependencies { - implementation("com.github.ntrrgc:ts-generator:1.1.2") + implementation("com.github.aSemy:ts-generator:v1.2.1") +// implementation("com.github.ntrrgc:ts-generator:1.1.2") implementation("org.jetbrains.kotlin:kotlin-reflect") } } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index ebf5d33..746352d 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -149,3 +149,44 @@ data class Colour( fun isPercentage(): Boolean = !isDecimal() } + +@Serializable +data class ConsoleChatMessage( + @SerialName("author_player_index") + val authorPlayerIndex: UInt?, + val content: String, +) : FactorioObjectData() { + @Transient + override val objectName: String = "ConsoleChatMessage" +} + +@Serializable +@SerialName("FactorioTilesMap") +data class FactorioTilesMap( + val tiles: Map, +) : FactorioObjectData() { + @Transient + override val objectName: String = "FactorioTilesMap" +} + + +@Serializable +@SerialName("FactorioTiles") +data class FactorioTiles( + val tiles: List, +) : FactorioObjectData() { + @Transient + override val objectName: String = "FactorioTiles" +} + + +@Serializable +@SerialName("LuaTile") +data class FactorioTile( + val prototypeName: String, + val position: PositionData, + val surfaceIndex: Int, +) : FactorioObjectData() { + @Transient + override val objectName: String = "LuaTile" +} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt new file mode 100644 index 0000000..53aacb6 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt @@ -0,0 +1,28 @@ +package dev.adamko.kafkatorio.events.schema + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient +import kotlinx.serialization.json.JsonClassDiscriminator + +@Serializable +@JsonClassDiscriminator(FactorioObjectDataDiscriminatorKey) +sealed class FactorioPrototype { + abstract val objectName: String +} + +@Serializable +@SerialName("LuaTilePrototype") +data class FactorioMapTilePrototype( + val name: String, + val layer: UInt, + val mapColor: Colour, + val collisionMasks: List, + val order: String, + + /** Is this tile mineable at all? */ + val canBeMined: Boolean, +) : FactorioPrototype() { + @Transient + override val objectName: String = "LuaTilePrototype" +} diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt index 4a8af3f..8bbbabf 100644 --- a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt @@ -19,6 +19,7 @@ fun main(args: Array) { buildSet { add(FactorioEvent::class) addAll(FactorioObjectData::class.sealedSubclasses) + addAll(FactorioPrototype::class.sealedSubclasses) }, mappings = mapOf( // builtin Factorio numeric types > `typed-factorio/generated/builtin-types.d.ts` @@ -56,7 +57,7 @@ fun main(args: Array) { @Language("TypeScript") val header = """ - |// Generated by TypeScriptGenerator - do edit this file manually + |// Generated by TypeScriptGenerator - do not edit this file manually | """.trimMargin() From ed4d42a2ef59de9ba66cbd7e17d5895e1d7d4ce3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Jan 2022 13:11:51 +0100 Subject: [PATCH 113/629] make the data being output by the events-mod more generalised, to include more than just events (mod config, prototypes) --- build.gradle.kts | 2 +- modules/events-mod/build.gradle.kts | 6 +- .../events-mod/src/main/typescript/control.ts | 7 +- .../src/main/typescript/events/emitter.ts | 5 +- .../src/main/typescript/events/handlers.ts | 15 +- .../src/main/typescript/events/serdes.ts | 45 ++--- .../handleConfigurationUpdate.ts | 43 ++++ .../main/config-update/updateGlobal.ts | 4 + .../typescript/main/emitKafkatorioPacket.ts | 6 + .../src/main/typescript/main/global.d.ts | 4 + .../src/main/typescript/package-lock.json | 2 +- .../src/main/typescript/package.json | 2 +- .../typescript/prototypes/emitPrototypes.ts | 60 +++--- .../main/typescript/schema/config-update.d.ts | 19 ++ .../main/typescript/schema/events-schema.ts | 92 --------- .../main/typescript/schema/object-data.d.ts | 61 ++++++ .../src/main/typescript/schema/prototype.d.ts | 20 ++ .../src/main/typescript/schema/schema.d.ts | 20 ++ modules/events-schema/build.gradle.kts | 4 +- .../events/schema/factorioCommonData.kt | 50 +++++ .../events/schema/factorioConfiguration.kt | 25 +++ .../events/schema/factorioEvents.kt | 184 +----------------- .../events/schema/factorioLuaObjects.kt | 108 ++++++++++ .../events/schema/factorioPrototypes.kt | 14 +- .../events/schema/kafkatorioPacket.kt | 26 +++ .../adamko/kafkatorio/events/schema/kt2ts.kt | 79 +++++--- 26 files changed, 524 insertions(+), 379 deletions(-) create mode 100644 modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts create mode 100644 modules/events-mod/src/main/typescript/main/config-update/updateGlobal.ts create mode 100644 modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts create mode 100644 modules/events-mod/src/main/typescript/main/global.d.ts create mode 100644 modules/events-mod/src/main/typescript/schema/config-update.d.ts delete mode 100644 modules/events-mod/src/main/typescript/schema/events-schema.ts create mode 100644 modules/events-mod/src/main/typescript/schema/object-data.d.ts create mode 100644 modules/events-mod/src/main/typescript/schema/prototype.d.ts create mode 100644 modules/events-mod/src/main/typescript/schema/schema.d.ts create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt diff --git a/build.gradle.kts b/build.gradle.kts index 42a664f..2b60f01 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.1.7" +version = "0.2.0" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 12719aa..12fee4b 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -10,7 +10,7 @@ import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { idea - id("dev.adamko.kafkatorio.lang.node") + dev.adamko.kafkatorio.lang.node distribution } @@ -60,7 +60,7 @@ val typescriptToLua by tasks.registering(NpmTask::class) { description = "Convert Typescript To Lua" group = project.name - dependsOn(tasks.npmInstall, installEventsTsSchema) + dependsOn(tasks.npmInstall, installEventsTsSchema, tasks.updatePackageJson) execOverrides { standardOutput = System.out } @@ -214,5 +214,3 @@ tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) } // } // } // } - -tasks.npmInstall diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index e0064ea..5448f13 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -1,8 +1,5 @@ -import {emitTiles} from "./prototypes/emitPrototypes"; +import {handleConfigurationUpdate} from "./main/config-update/handleConfigurationUpdate"; require("events") -// on startup, push out prototypes -script.on_configuration_changed((e: ConfigurationChangedData) => { - emitTiles() -}) +script.on_configuration_changed(handleConfigurationUpdate) diff --git a/modules/events-mod/src/main/typescript/events/emitter.ts b/modules/events-mod/src/main/typescript/events/emitter.ts index 8613fae..28a8f8e 100644 --- a/modules/events-mod/src/main/typescript/events/emitter.ts +++ b/modules/events-mod/src/main/typescript/events/emitter.ts @@ -9,9 +9,8 @@ export function emitEvent(eventData: T, tick: uint let event: FactorioEvent = { data: eventData, - event_type: eventType, - mod_version: MOD_VERSION, - factorio_version: FACTORIO_VERSION, + eventType: eventType, + modVersion: MOD_VERSION, tick: tick } diff --git a/modules/events-mod/src/main/typescript/events/handlers.ts b/modules/events-mod/src/main/typescript/events/handlers.ts index e2ec935..0bcf505 100644 --- a/modules/events-mod/src/main/typescript/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/events/handlers.ts @@ -50,10 +50,12 @@ export function handleConsoleChat( const CHUNK_SIZE = 32 -export function handleChunkUpdate(tick: uint, - eventType: string, - surfaceIndex: uint, - position: ChunkPosition) { +export function handleChunkUpdate( + tick: uint, + eventType: string, + surfaceIndex: uint, + position: ChunkPosition +) { let surface = game.get_surface(surfaceIndex) @@ -69,14 +71,13 @@ export function handleChunkUpdate(tick: uint, let tilePositionMap = new Map(); for (let tile of tiles) { - let position = Serdes.positionTableToTable(tile.position) + let position = Serdes.convertMapPosition(tile.position) tilePositionMap.set(position, Serdes.convertTile(tile)) } let mapChunk: FactorioTilesMap = { - object_name: "FactorioTilesMap", + objectName: "FactorioTilesMap", tiles: tilePositionMap, } emitEvent(mapChunk, tick, eventType) - } diff --git a/modules/events-mod/src/main/typescript/events/serdes.ts b/modules/events-mod/src/main/typescript/events/serdes.ts index 3394ba6..4eb7e42 100644 --- a/modules/events-mod/src/main/typescript/events/serdes.ts +++ b/modules/events-mod/src/main/typescript/events/serdes.ts @@ -3,15 +3,15 @@ export namespace Serdes { export function playerToTable(player: LuaPlayer): PlayerData { let charIds = entitiesToUnitNumbers(player.get_associated_characters()) return { - object_name: player.object_name, + objectName: player.object_name, name: player.name, - character_unit_number: player.character?.unit_number ?? null, - associated_characters_unit_numbers: charIds, - position: positionTableToTable(player.position), + characterUnitNumber: player.character?.unit_number ?? null, + associatedCharactersUnitNumbers: charIds, + position: convertMapPosition(player.position), colour: mapColour(player.color), - chat_colour: mapColour(player.chat_color), - last_online: player.last_online + chatColour: mapColour(player.chat_color), + lastOnline: player.last_online } } @@ -20,20 +20,20 @@ export namespace Serdes { let player: LuaPlayer | null = entity.is_player() ? entity.player!! : null return { - object_name: entity.object_name, + objectName: entity.object_name, // entity data name: entity.name, type: entity.type, active: entity.active, health: entity.health ?? null, - health_ratio: entity.get_health_ratio(), - surface_index: entity.surface.index, - unit_number: entity.unit_number ?? null, - position: positionTableToTable(entity.position), + healthRatio: entity.get_health_ratio(), + surfaceIndex: entity.surface.index, + unitNumber: entity.unit_number ?? null, + position: convertMapPosition(entity.position), // player data - player_index: player?.index ?? null + playerIndex: player?.index ?? null } } @@ -49,7 +49,7 @@ export namespace Serdes { export function surfaceToTable(surface: LuaSurface): SurfaceData { return { - object_name: surface.object_name, + objectName: surface.object_name, name: surface.name, index: surface.index, @@ -57,10 +57,11 @@ export namespace Serdes { } } - export function positionTableToTable(positionTable: PositionTable): PositionData { + export function convertMapPosition(mapPos: MapPositionTable): PositionData { return { - x: positionTable.x, - y: positionTable.y, + type: "MAP", + x: mapPos.x, + y: mapPos.y, } } @@ -75,20 +76,20 @@ export namespace Serdes { export function consoleChat(content: string, playerIndex?: uint): ConsoleChatMessage { return { - object_name: "ConsoleChatMessage", + objectName: "ConsoleChatMessage", - author_player_index: playerIndex ?? null, + authorPlayerIndex: playerIndex ?? null, content: content } } export function convertTile(tile: LuaTile): FactorioTile { return { - object_name: tile.object_name, + objectName: tile.object_name, - position: tile.position, - prototype_name: tile.prototype.name, - surface_index: tile.surface.index + position: convertMapPosition(tile.position), + prototypeName: tile.prototype.name, + surfaceIndex: tile.surface.index } } diff --git a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts new file mode 100644 index 0000000..1ea1d0e --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts @@ -0,0 +1,43 @@ +import {emitPacket} from "../emitKafkatorioPacket"; +import {convertPrototypes} from "../../prototypes/emitPrototypes"; + +export function handleConfigurationUpdate(changeData: ConfigurationChangedData) { + + emitPacket({ + modVersion: global.MOD_VERSION, + allMods: allMods(changeData), + factorioData: factorioData(changeData), + prototypes: convertPrototypes() + }) + +} + +function factorioData(changeData: ConfigurationChangedData): FactorioGameDataUpdate { + return { + oldVersion: changeData.old_version ?? null, + newVersion: changeData.new_version ?? null, + } +} + +function allMods(e: ConfigurationChangedData): FactorioModInfo[] { + + let namesOfChangedMods: string[] = Object.keys(e.mod_changes) + let namesOfCurrentMods: string[] = Object.keys(script.active_mods) + + let modNames = [...new Set( + namesOfChangedMods.concat(namesOfCurrentMods) + )] + + return modNames.map((modName) => { + + let currentVer = script.active_mods[modName] ?? e.mod_changes[modName].new_version + let previousVer = e.mod_changes[modName].old_version + + return { + modName: modName, + currentVersion: currentVer, + previousVersion: previousVer, + } + }) + +} diff --git a/modules/events-mod/src/main/typescript/main/config-update/updateGlobal.ts b/modules/events-mod/src/main/typescript/main/config-update/updateGlobal.ts new file mode 100644 index 0000000..db1e621 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/config-update/updateGlobal.ts @@ -0,0 +1,4 @@ +export function updateGlobal() { + global.MOD_VERSION = script.active_mods[script.mod_name][1] + global.FACTORIO_VERSION = script.active_mods["base"][1] +} diff --git a/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts b/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts new file mode 100644 index 0000000..c86af5d --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts @@ -0,0 +1,6 @@ +/** Emit a serialised KafkatorioPacket */ +export function emitPacket(packet: T) { + let data = game.table_to_json(packet) + localised_print(`KafkatorioPacket: ${data}`) + // rcon.print(`KafkatorioPacket: ${data}`) +} diff --git a/modules/events-mod/src/main/typescript/main/global.d.ts b/modules/events-mod/src/main/typescript/main/global.d.ts new file mode 100644 index 0000000..7a73643 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/global.d.ts @@ -0,0 +1,4 @@ +declare const global: { + MOD_VERSION: string + FACTORIO_VERSION: string +} diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index 4fe36f3..e30a5b3 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.1.7", + "version": "0.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 5fd898c..e708d32 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.1.7", + "version": "0.2.0", "private": true, "scripts": { "build": "tstl", diff --git a/modules/events-mod/src/main/typescript/prototypes/emitPrototypes.ts b/modules/events-mod/src/main/typescript/prototypes/emitPrototypes.ts index 44aa893..2099e3e 100644 --- a/modules/events-mod/src/main/typescript/prototypes/emitPrototypes.ts +++ b/modules/events-mod/src/main/typescript/prototypes/emitPrototypes.ts @@ -1,42 +1,36 @@ import {Serdes} from "../events/serdes"; -export function emitTiles() { +export function convertPrototypes (): FactorioPrototype[] { + let prototypes = new Array() - let tilePrototypes = new LuaTable() + prototypes.push(...getMapTilePrototypes()) - for (const [_, tile] of pairs(game.tile_prototypes)) { - // let ttttt = game.tile_prototypes[tileName] - tilePrototypes.set(tile.name, mapTilePrototype(tile)) + return prototypes +} + +function getMapTilePrototypes(): FactorioMapTilePrototype[] { + let tiles: FactorioMapTilePrototype[] = [] + for (let [_, tile] of pairs(game.tile_prototypes)) { + tiles.push( + { + objectName: tile.object_name, + + name: tile.name, + order: tile.order, + layer: tile.layer, + collisionMasks: convertCollisionMaskToNames(tile.collision_mask), + mapColor: Serdes.mapColour(tile.map_color), + canBeMined: tile.mineable_properties.minable, + } + ) } - - // for (let tileName in game.tile_prototypes) { - // const tile = game.tile_prototypes[tileName] - // tilePrototypes.set(tileName, mapTilePrototype(tile)) - // } - - // for (const [id, player] of pairs(game.players)) { - // const num: number = id - // const p: LuaPlayer = player - // } - emitPrototypes(tilePrototypes) + return tiles } -function mapTilePrototype(tile: LuaTilePrototype): FactorioMapTilePrototype { - return { - object_name: tile.object_name, - - name: tile.name, - order: tile.order, - layer: tile.layer, - collision_masks: [], - map_color: Serdes.mapColour(tile.map_color), - can_be_mined: tile.mineable_properties.minable, +function convertCollisionMaskToNames(cm: CollisionMask): string[] { + let masks: string[] = [] + for (let [name, _] of pairs(cm)) { + masks.push(name) } -} - -function emitPrototypes(prototypes: LuaTable) { - - let data = game.table_to_json(prototypes) - - localised_print(`FactorioPrototype: ${data}`) + return masks } diff --git a/modules/events-mod/src/main/typescript/schema/config-update.d.ts b/modules/events-mod/src/main/typescript/schema/config-update.d.ts new file mode 100644 index 0000000..1f8e37a --- /dev/null +++ b/modules/events-mod/src/main/typescript/schema/config-update.d.ts @@ -0,0 +1,19 @@ +// Generated by TypeScriptGenerator - do not edit this file manually + +interface FactorioModInfo { + currentVersion: string | null; + modName: string; + previousVersion: string | null; +} + +interface FactorioGameDataUpdate { + newVersion: string | null; + oldVersion: string | null; +} + +interface FactorioConfigurationUpdate extends KafkatorioPacket { + allMods: FactorioModInfo[]; + factorioData: FactorioGameDataUpdate; + modVersion: string; + prototypes: FactorioPrototype[]; +} diff --git a/modules/events-mod/src/main/typescript/schema/events-schema.ts b/modules/events-mod/src/main/typescript/schema/events-schema.ts deleted file mode 100644 index 24d67a3..0000000 --- a/modules/events-mod/src/main/typescript/schema/events-schema.ts +++ /dev/null @@ -1,92 +0,0 @@ -// Generated by TypeScriptGenerator - do not edit this file manually -interface FactorioObjectData { - object_name: string; -} - -interface FactorioEvent { - data: T; - event_type: string; - factorio_version: string; - mod_version: string; - tick: uint; -} - -interface Colour { - alpha: float; - blue: float; - green: float; - red: float; -} - -interface PositionData { - x: double; - y: double; -} - -interface PlayerData extends FactorioObjectData { - associated_characters_unit_numbers: uint[]; - character_unit_number: uint | null; - chat_colour: Colour; - colour: Colour; - last_online: uint; - name: string; - object_name: string; - position: PositionData; -} - -interface EntityData extends FactorioObjectData { - active: boolean; - health: double | null; - health_ratio: double; - name: string; - object_name: string; - player_index: uint | null; - position: PositionData; - surface_index: int; - type: string; - unit_number: uint | null; -} - -interface SurfaceData extends FactorioObjectData { - daytime: double; - index: uint; - name: string; - object_name: string; -} - -interface ConsoleChatMessage extends FactorioObjectData { - author_player_index: uint | null; - content: string; - object_name: string; -} - -interface FactorioTile extends FactorioObjectData { - object_name: string; - position: PositionData; - prototype_name: string; - surface_index: int; -} - -interface FactorioTilesMap extends FactorioObjectData { - object_name: string; - tiles: Map; -} - -interface FactorioTiles extends FactorioObjectData { - object_name: string; - tiles: FactorioTile[]; -} - -interface FactorioPrototype { - object_name: string; -} - -interface FactorioMapTilePrototype extends FactorioPrototype { - can_be_mined: boolean; - collision_masks: string[]; - layer: uint; - map_color: Colour; - name: string; - object_name: string; - order: string; -} \ No newline at end of file diff --git a/modules/events-mod/src/main/typescript/schema/object-data.d.ts b/modules/events-mod/src/main/typescript/schema/object-data.d.ts new file mode 100644 index 0000000..612b721 --- /dev/null +++ b/modules/events-mod/src/main/typescript/schema/object-data.d.ts @@ -0,0 +1,61 @@ +// Generated by TypeScriptGenerator - do not edit this file manually + +interface FactorioObjectData { + objectName: string; +} + +interface FactorioEvent extends KafkatorioPacket { + data: T; + eventType: string; + modVersion: string; + tick: uint; +} + +interface PlayerData extends FactorioObjectData { + associatedCharactersUnitNumbers: uint[]; + characterUnitNumber: uint | null; + chatColour: Colour; + colour: Colour; + lastOnline: uint; + name: string; + objectName: string; + position: PositionData; +} + +interface EntityData extends FactorioObjectData { + active: boolean; + health: double | null; + healthRatio: double; + name: string; + objectName: string; + playerIndex: uint | null; + position: PositionData; + surfaceIndex: int; + type: string; + unitNumber: uint | null; +} + +interface SurfaceData extends FactorioObjectData { + daytime: double; + index: uint; + name: string; + objectName: string; +} + +interface FactorioTile extends FactorioObjectData { + objectName: string; + position: PositionData; + prototypeName: string; + surfaceIndex: int; +} + +interface FactorioTilesMap extends FactorioObjectData { + objectName: string; + tiles: Map; +} + +interface ConsoleChatMessage extends FactorioObjectData { + authorPlayerIndex: uint | null; + content: string; + objectName: string; +} diff --git a/modules/events-mod/src/main/typescript/schema/prototype.d.ts b/modules/events-mod/src/main/typescript/schema/prototype.d.ts new file mode 100644 index 0000000..f1d2052 --- /dev/null +++ b/modules/events-mod/src/main/typescript/schema/prototype.d.ts @@ -0,0 +1,20 @@ +// Generated by TypeScriptGenerator - do not edit this file manually + +interface FactorioPrototype { + objectName: string; +} + +interface FactorioPrototypes extends KafkatorioPacket { + modVersion: string; + prototypes: T[]; +} + +interface FactorioMapTilePrototype extends FactorioPrototype { + canBeMined: boolean; + collisionMasks: string[]; + layer: uint; + mapColor: Colour; + name: string; + objectName: string; + order: string; +} diff --git a/modules/events-mod/src/main/typescript/schema/schema.d.ts b/modules/events-mod/src/main/typescript/schema/schema.d.ts new file mode 100644 index 0000000..9738c8c --- /dev/null +++ b/modules/events-mod/src/main/typescript/schema/schema.d.ts @@ -0,0 +1,20 @@ +// Generated by TypeScriptGenerator - do not edit this file manually + +interface KafkatorioPacket { + modVersion: string; +} + +interface Colour { + alpha: float; + blue: float; + green: float; + red: float; +} + +type PositionType = "MAP" | "CHUNK" | "TILE"; + +interface PositionData { + type: PositionType | null; + x: double; + y: double; +} diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index efe3409..b19af7d 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -80,8 +80,8 @@ val generateTypescript by tasks.registering(JavaExec::class) { mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2tsKt") - val generatedFile = file("$temporaryDir/${project.name}.ts") - args(generatedFile) + val tempOutputDirectory = file("$temporaryDir") + args(tempOutputDirectory) val buildOutput = layout.buildDirectory.dir("generated/typescript") outputs.dir(buildOutput) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt new file mode 100644 index 0000000..191e215 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -0,0 +1,50 @@ +package dev.adamko.kafkatorio.events.schema + +import kotlinx.serialization.Serializable + +@Serializable +data class PositionData( + val x: Double, + val y: Double, + val type: PositionType?, +) + +@Serializable +enum class PositionType { + MAP, CHUNK, TILE, +} + +/** + * Red, green, blue and alpha values, all in range `[0, 1]` or all in range `[0, 255]` if any + * value is > 1. + * + * All values here are optional. Color channels default to 0, the alpha channel defaults to 1. + */ +@Serializable +data class Colour( + val red: Float = 0f, + val green: Float = 0f, + val blue: Float = 0f, + val alpha: Float = 1f, +) { + /** True if any value is greater than 1, so the values are hexadecimal. */ + fun isDecimal(): Boolean { + return red > 1f + || green > 1f + || blue > 1f + || alpha > 1f + } + + /** True if all values are between `[0..1]`. */ + fun isPercentage(): Boolean = !isDecimal() + +} + +//@Serializable +//@SerialName("FactorioTiles") +//data class FactorioTiles( +// val tiles: List, +//) : FactorioObjectData() { +// @Transient +// override val objectName: String = "FactorioTiles" +//} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt new file mode 100644 index 0000000..a3c829f --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt @@ -0,0 +1,25 @@ +package dev.adamko.kafkatorio.events.schema + +import kotlinx.serialization.Serializable + + +@Serializable +data class FactorioConfigurationUpdate( + override val modVersion: String, + val factorioData: FactorioGameDataUpdate, + val allMods: List, + val prototypes: List, +) : KafkatorioPacket + +@Serializable +data class FactorioGameDataUpdate( + val oldVersion: String?, + val newVersion: String?, +) + +@Serializable +data class FactorioModInfo( + val modName: String, + val currentVersion: String?, + val previousVersion: String?, +) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index 746352d..15eef33 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -1,192 +1,16 @@ package dev.adamko.kafkatorio.events.schema -import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient -import kotlinx.serialization.json.JsonClassDiscriminator -//@Serializable(with = FactorioEventSerializer::class) @Serializable data class FactorioEvent( + override val modVersion: String, + /** the initial Factorio event ({defines.events}) trigger */ - @SerialName("event_type") val eventType: String, - /** Schema versioning */ - @SerialName("mod_version") - val modVersion: String, - @SerialName("factorio_version") - val factorioVersion: String, /** game time */ - @SerialName("tick") val tick: UInt, - @SerialName("data") - val data: T -) - - -/** The [JsonClassDiscriminator] for [FactorioEvent] */ -const val FactorioObjectDataDiscriminatorKey: String = "object_name" - - -@Serializable -@JsonClassDiscriminator(FactorioObjectDataDiscriminatorKey) -sealed class FactorioObjectData { - - abstract val objectName: String - - // workaround - https://github.com/Kotlin/kotlinx.serialization/issues/1664 -// val objectName: String by lazy { -// serializer().descriptor.serialName -// } - -// val objectName: String by lazy { -// kotlinx.serialization.serializer(this::class.starProjectedType).descriptor.serialName -// } - - // alternative: find the @SerialName annotation - // Again it must be delegated so there's no backing field and kxs ignores it -// val objectName: String by lazy { -// requireNotNull(this::class.findAnnotation()?.value) { -// "Couldn't find @SerialName for ${this::class}!" -// } -// } -} - -@Serializable -@SerialName("LuaPlayer") -data class PlayerData( - @Serializable(with = ListAsObjectSerializer::class) - @SerialName("associated_characters_unit_numbers") - val associatedCharactersUnitNumbers: List, - @SerialName("character_unit_number") - val characterUnitNumber: UInt?, - @SerialName("name") - val name: String, - @SerialName("position") - val position: PositionData, - @SerialName("colour") - val colour: Colour, - @SerialName("chat_colour") - val chatColour: Colour, - @SerialName("last_online") - val lastOnline: UInt, -) : FactorioObjectData() { - @Transient - override val objectName: String = "LuaPlayer" -} - -@Serializable -@SerialName("LuaEntity") -data class EntityData( - @SerialName("active") - val active: Boolean, - @SerialName("health") - val health: Double?, - @SerialName("health_ratio") - val healthRatio: Double, - @SerialName("name") - val name: String, - @SerialName("position") - val position: PositionData, - @SerialName("surface_index") - val surfaceIndex: Int, - @SerialName("type") - val type: String, - @SerialName("unit_number") - val unitNumber: UInt? = null, - - @SerialName("player_index") - val playerIndex: UInt? = null, -) : FactorioObjectData() { - @Transient - override val objectName: String = "LuaEntity" -} - -@Serializable -@SerialName("LuaSurface") -data class SurfaceData( - @SerialName("daytime") - val daytime: Double, - @SerialName("index") - val index: UInt, - @SerialName("name") - val name: String, -) : FactorioObjectData() { - @Transient - override val objectName: String = "LuaSurface" -} - -@Serializable -data class PositionData( - val x: Double, - val y: Double, -) - -/** - * Red, green, blue and alpha values, all in range `[0, 1]` or all in range `[0, 255]` if any - * value is > 1. - * - * All values here are optional. Color channels default to 0, the alpha channel defaults to 1. - */ -@Serializable -data class Colour( - val red: Float = 0f, - val green: Float = 0f, - val blue: Float = 0f, - val alpha: Float = 1f, -) { - /** True if any value is greater than 1, so the values are hexadecimal. */ - fun isDecimal(): Boolean { - return red > 1f - || green > 1f - || blue > 1f - || alpha > 1f - } - - /** True if all values are between `[0..1]`. */ - fun isPercentage(): Boolean = !isDecimal() - -} - -@Serializable -data class ConsoleChatMessage( - @SerialName("author_player_index") - val authorPlayerIndex: UInt?, - val content: String, -) : FactorioObjectData() { - @Transient - override val objectName: String = "ConsoleChatMessage" -} - -@Serializable -@SerialName("FactorioTilesMap") -data class FactorioTilesMap( - val tiles: Map, -) : FactorioObjectData() { - @Transient - override val objectName: String = "FactorioTilesMap" -} - - -@Serializable -@SerialName("FactorioTiles") -data class FactorioTiles( - val tiles: List, -) : FactorioObjectData() { - @Transient - override val objectName: String = "FactorioTiles" -} - - -@Serializable -@SerialName("LuaTile") -data class FactorioTile( - val prototypeName: String, - val position: PositionData, - val surfaceIndex: Int, -) : FactorioObjectData() { - @Transient - override val objectName: String = "LuaTile" -} + val data: T, +) : KafkatorioPacket diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt new file mode 100644 index 0000000..0ab2686 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -0,0 +1,108 @@ +package dev.adamko.kafkatorio.events.schema + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient +import kotlinx.serialization.json.JsonClassDiscriminator + +@Serializable +@JsonClassDiscriminator(FactorioObjectData.discriminatorKey) +sealed class FactorioObjectData { + + abstract val objectName: String + + // workaround - https://github.com/Kotlin/kotlinx.serialization/issues/1664 +// val objectName: String by lazy { +// serializer().descriptor.serialName +// } + +// val objectName: String by lazy { +// kotlinx.serialization.serializer(this::class.starProjectedType).descriptor.serialName +// } + + // alternative: find the @SerialName annotation + // Again it must be delegated so there's no backing field and kxs ignores it +// val objectName: String by lazy { +// requireNotNull(this::class.findAnnotation()?.value) { +// "Couldn't find @SerialName for ${this::class}!" +// } +// } + + companion object { + /** The [JsonClassDiscriminator] for [FactorioEvent] */ + const val discriminatorKey: String = "objectName" + } +} + +@Serializable +@SerialName("LuaPlayer") +data class PlayerData( + @Serializable(with = ListAsObjectSerializer::class) + val associatedCharactersUnitNumbers: List, + val characterUnitNumber: UInt?, + val name: String, + val position: PositionData, + val colour: Colour, + val chatColour: Colour, + val lastOnline: UInt, +) : FactorioObjectData() { + @Transient + override val objectName: String = "LuaPlayer" +} + +@Serializable +@SerialName("LuaEntity") +data class EntityData( + val active: Boolean, + val health: Double?, + val healthRatio: Double, + val name: String, + val position: PositionData, + val surfaceIndex: Int, + val type: String, + val unitNumber: UInt? = null, + val playerIndex: UInt? = null, +) : FactorioObjectData() { + @Transient + override val objectName: String = "LuaEntity" +} + +@Serializable +@SerialName("LuaSurface") +data class SurfaceData( + val daytime: Double, + val index: UInt, + val name: String, +) : FactorioObjectData() { + @Transient + override val objectName: String = "LuaSurface" +} + +@Serializable +@SerialName("FactorioTilesMap") +data class FactorioTilesMap( + val tiles: Map, +) : FactorioObjectData() { + @Transient + override val objectName: String = "FactorioTilesMap" +} + +@Serializable +@SerialName("LuaTile") +data class FactorioTile( + val prototypeName: String, + val position: PositionData, + val surfaceIndex: Int, +) : FactorioObjectData() { + @Transient + override val objectName: String = "LuaTile" +} + +@Serializable +data class ConsoleChatMessage( + val authorPlayerIndex: UInt?, + val content: String, +) : FactorioObjectData() { + @Transient + override val objectName: String = "ConsoleChatMessage" +} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt index 53aacb6..70404b9 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt @@ -6,9 +6,19 @@ import kotlinx.serialization.Transient import kotlinx.serialization.json.JsonClassDiscriminator @Serializable -@JsonClassDiscriminator(FactorioObjectDataDiscriminatorKey) +class FactorioPrototypes( + override val modVersion: String, + val prototypes: List, +) : KafkatorioPacket + +@Serializable +@JsonClassDiscriminator(FactorioPrototype.discriminatorKey) sealed class FactorioPrototype { abstract val objectName: String + + companion object { + const val discriminatorKey: String = "objectName" + } } @Serializable @@ -20,7 +30,7 @@ data class FactorioMapTilePrototype( val collisionMasks: List, val order: String, - /** Is this tile mineable at all? */ + /** Can the tile be mined for resources? */ val canBeMined: Boolean, ) : FactorioPrototype() { @Transient diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt new file mode 100644 index 0000000..194f2c6 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt @@ -0,0 +1,26 @@ +package dev.adamko.kafkatorio.events.schema; + + +//@Serializable +sealed interface KafkatorioPacket { + /** Schema versioning */ + val modVersion: String +} + + +//enum class PacketDataType { +// EVENT, PROTOTYPE, CONFIG_DATA, +// ; +//} + + +//@Serializable +//@JsonClassDiscriminator(KafkatorioPacketData.discriminatorKey) +//sealed class KafkatorioPacketData( +// @SerialName(discriminatorKey) +// val dataType: PacketDataType +//) { +// companion object { +// const val discriminatorKey: String = "dataType" +// } +//} diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt index 8bbbabf..c1b48ab 100644 --- a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt @@ -1,11 +1,8 @@ package dev.adamko.kafkatorio.events.schema -import java.io.File -import kotlin.reflect.KClass -import kotlin.reflect.KProperty -import me.ntrrgc.tsGenerator.ClassTransformer +import kotlin.io.path.Path +import kotlin.io.path.createDirectories import me.ntrrgc.tsGenerator.TypeScriptGenerator -import me.ntrrgc.tsGenerator.camelCaseToSnakeCase import org.intellij.lang.annotations.Language /** @@ -15,9 +12,8 @@ fun main(args: Array) { val gen = TypeScriptGenerator( - rootClasses = - buildSet { - add(FactorioEvent::class) + rootClasses = buildSet { + addAll(KafkatorioPacket::class.sealedSubclasses) addAll(FactorioObjectData::class.sealedSubclasses) addAll(FactorioPrototype::class.sealedSubclasses) }, @@ -33,7 +29,7 @@ fun main(args: Array) { ULong::class to "uint64", ), classTransformers = listOf( - PropertyNameTransformer, +// PropertyNameTransformer, ) ) @@ -44,29 +40,60 @@ fun main(args: Array) { println(definitions) } else -> { - val out = File(filename) - out.parentFile.mkdirs() - out.printWriter().use { - it.print(header) - it.print(definitions) - } - println("Generated file: $out") + + val outPath = Path(filename) + outPath.createDirectories() + + splitDefinitions(definitions) + .forEach { (defFile, def) -> + val outFile = outPath.resolve(defFile).toFile() + outFile.printWriter().use { + it.print(header) + it.print(def) + } + println("Generated file: $outFile") + } + } } } +/** Split the TypeScript interfaces into different files */ +private fun splitDefinitions(definitions: String): Map { + return definitions + .split("\n\n") + .groupBy { def -> + when { + "extends FactorioObjectData" in def || + "interface FactorioObjectData" in def -> "object-data.d.ts" + "extends FactorioPrototype" in def || + "interface FactorioPrototype" in def -> "prototype.d.ts" + "extends FactorioConfigurationUpdate" in def || + "interface FactorioConfigurationUpdate" in def || + "FactorioGameDataUpdate" in def || + "FactorioModInfo" in def -> "config-update.d.ts" + else -> "schema.d.ts" + } + } + .mapValues { (_, def) -> + def + .joinToString("\n\n", postfix = "\n") + .replace(" ", " ") + } +} + @Language("TypeScript") val header = """ |// Generated by TypeScriptGenerator - do not edit this file manually | -""".trimMargin() +""".trimMargin() + "\n" -object PropertyNameTransformer : ClassTransformer { - override fun transformPropertyName( - propertyName: String, - property: KProperty<*>, - klass: KClass<*> - ): String { - return camelCaseToSnakeCase(propertyName) - } -} +//object PropertyNameTransformer : ClassTransformer { +// override fun transformPropertyName( +// propertyName: String, +// property: KProperty<*>, +// klass: KClass<*> +// ): String { +// return camelCaseToSnakeCase(propertyName) +// } +//} From baa6ffac139a5c7395dee0b5120cacc65ba5a0b0 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Jan 2022 13:14:32 +0100 Subject: [PATCH 114/629] reorganise mod package structure --- modules/events-mod/build.gradle.kts | 2 +- modules/events-mod/src/main/typescript/control.ts | 2 +- .../{schema => generated/kafkatorio-schema}/config-update.d.ts | 0 .../{schema => generated/kafkatorio-schema}/object-data.d.ts | 0 .../{schema => generated/kafkatorio-schema}/prototype.d.ts | 0 .../{schema => generated/kafkatorio-schema}/schema.d.ts | 0 modules/events-mod/src/main/typescript/{ => main}/events.ts | 0 .../events-mod/src/main/typescript/{ => main}/events/emitter.ts | 0 .../src/main/typescript/{ => main}/events/handlers.ts | 0 .../events-mod/src/main/typescript/{ => main}/events/serdes.ts | 0 .../src/main/typescript/{ => main}/prototypes/emitPrototypes.ts | 0 11 files changed, 2 insertions(+), 2 deletions(-) rename modules/events-mod/src/main/typescript/{schema => generated/kafkatorio-schema}/config-update.d.ts (100%) rename modules/events-mod/src/main/typescript/{schema => generated/kafkatorio-schema}/object-data.d.ts (100%) rename modules/events-mod/src/main/typescript/{schema => generated/kafkatorio-schema}/prototype.d.ts (100%) rename modules/events-mod/src/main/typescript/{schema => generated/kafkatorio-schema}/schema.d.ts (100%) rename modules/events-mod/src/main/typescript/{ => main}/events.ts (100%) rename modules/events-mod/src/main/typescript/{ => main}/events/emitter.ts (100%) rename modules/events-mod/src/main/typescript/{ => main}/events/handlers.ts (100%) rename modules/events-mod/src/main/typescript/{ => main}/events/serdes.ts (100%) rename modules/events-mod/src/main/typescript/{ => main}/prototypes/emitPrototypes.ts (100%) diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 12fee4b..c44ed62 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -97,7 +97,7 @@ val installEventsTsSchema by tasks.registering(Sync::class) { dependsOn(typescriptEventsSchema) - val outputDir = layout.projectDirectory.dir("src/main/typescript/schema") + val outputDir = layout.projectDirectory.dir("src/main/typescript/generated/kafkatorio-schema") outputs.dir(outputDir) from( diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index 5448f13..a195c76 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -1,5 +1,5 @@ import {handleConfigurationUpdate} from "./main/config-update/handleConfigurationUpdate"; -require("events") +require("./main/events") script.on_configuration_changed(handleConfigurationUpdate) diff --git a/modules/events-mod/src/main/typescript/schema/config-update.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts similarity index 100% rename from modules/events-mod/src/main/typescript/schema/config-update.d.ts rename to modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts diff --git a/modules/events-mod/src/main/typescript/schema/object-data.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts similarity index 100% rename from modules/events-mod/src/main/typescript/schema/object-data.d.ts rename to modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts diff --git a/modules/events-mod/src/main/typescript/schema/prototype.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts similarity index 100% rename from modules/events-mod/src/main/typescript/schema/prototype.d.ts rename to modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts diff --git a/modules/events-mod/src/main/typescript/schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts similarity index 100% rename from modules/events-mod/src/main/typescript/schema/schema.d.ts rename to modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts diff --git a/modules/events-mod/src/main/typescript/events.ts b/modules/events-mod/src/main/typescript/main/events.ts similarity index 100% rename from modules/events-mod/src/main/typescript/events.ts rename to modules/events-mod/src/main/typescript/main/events.ts diff --git a/modules/events-mod/src/main/typescript/events/emitter.ts b/modules/events-mod/src/main/typescript/main/events/emitter.ts similarity index 100% rename from modules/events-mod/src/main/typescript/events/emitter.ts rename to modules/events-mod/src/main/typescript/main/events/emitter.ts diff --git a/modules/events-mod/src/main/typescript/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts similarity index 100% rename from modules/events-mod/src/main/typescript/events/handlers.ts rename to modules/events-mod/src/main/typescript/main/events/handlers.ts diff --git a/modules/events-mod/src/main/typescript/events/serdes.ts b/modules/events-mod/src/main/typescript/main/events/serdes.ts similarity index 100% rename from modules/events-mod/src/main/typescript/events/serdes.ts rename to modules/events-mod/src/main/typescript/main/events/serdes.ts diff --git a/modules/events-mod/src/main/typescript/prototypes/emitPrototypes.ts b/modules/events-mod/src/main/typescript/main/prototypes/emitPrototypes.ts similarity index 100% rename from modules/events-mod/src/main/typescript/prototypes/emitPrototypes.ts rename to modules/events-mod/src/main/typescript/main/prototypes/emitPrototypes.ts From ae94151fb6bef4cf82416570ea8f62fe054dac52 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Jan 2022 13:14:42 +0100 Subject: [PATCH 115/629] tidy comments, versions --- .../kafkatorio/lang/kotlin-jvm.gradle.kts | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index f3aa96e..9e79a0e 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -1,6 +1,5 @@ package dev.adamko.kafkatorio.lang -import org.gradle.kotlin.dsl.kotlin import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -16,14 +15,8 @@ kotlin { dependencies { - // - implementation(platform("org.jetbrains.kotlin:kotlin-bom")) - // - - // - val junitVersion = "5.8.2" testImplementation(platform("org.junit:junit-bom:$junitVersion")) testImplementation("org.junit.jupiter:junit-jupiter") @@ -33,14 +26,12 @@ dependencies { val kotestVersion = "5.0.3" testImplementation(platform("io.kotest:kotest-bom:$kotestVersion")) - testImplementation("io.kotest:kotest-runner-junit5:$kotestVersion") - testImplementation("io.kotest:kotest-assertions-core:$kotestVersion") - testImplementation("io.kotest:kotest-property:$kotestVersion") - testImplementation("io.kotest:kotest-assertions-json:$kotestVersion") + testImplementation("io.kotest:kotest-runner-junit5") + testImplementation("io.kotest:kotest-assertions-core") + testImplementation("io.kotest:kotest-property") + testImplementation("io.kotest:kotest-assertions-json") - testImplementation("io.mockk:mockk:1.12.0") - - // + testImplementation("io.mockk:mockk:1.12.1") } From f97b0a65627ca1d013b3118f3b5f9be1176b0eb9 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Jan 2022 13:23:32 +0100 Subject: [PATCH 116/629] more mod restructuring --- .../convertPrototypes.ts} | 4 ++-- .../handleConfigurationUpdate.ts | 4 +++- .../main/events/{serdes.ts => converters.ts} | 4 ++-- .../main/typescript/main/events/emitEvent.ts | 14 +++++++++++++ .../main/typescript/main/events/emitter.ts | 20 ------------------- .../main/typescript/main/events/handlers.ts | 18 +++++++++-------- .../{events.ts => events/registerHandlers.ts} | 2 +- .../events/schema/factorioCommonData.kt | 1 + .../events/schema/factorioEvents.kt | 2 +- 9 files changed, 34 insertions(+), 35 deletions(-) rename modules/events-mod/src/main/typescript/main/{prototypes/emitPrototypes.ts => config-update/convertPrototypes.ts} (88%) rename modules/events-mod/src/main/typescript/main/events/{serdes.ts => converters.ts} (95%) create mode 100644 modules/events-mod/src/main/typescript/main/events/emitEvent.ts delete mode 100644 modules/events-mod/src/main/typescript/main/events/emitter.ts rename modules/events-mod/src/main/typescript/main/{events.ts => events/registerHandlers.ts} (98%) diff --git a/modules/events-mod/src/main/typescript/main/prototypes/emitPrototypes.ts b/modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts similarity index 88% rename from modules/events-mod/src/main/typescript/main/prototypes/emitPrototypes.ts rename to modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts index 2099e3e..b1e2c3f 100644 --- a/modules/events-mod/src/main/typescript/main/prototypes/emitPrototypes.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts @@ -1,4 +1,4 @@ -import {Serdes} from "../events/serdes"; +import {Converters} from "../events/converters"; export function convertPrototypes (): FactorioPrototype[] { let prototypes = new Array() @@ -19,7 +19,7 @@ function getMapTilePrototypes(): FactorioMapTilePrototype[] { order: tile.order, layer: tile.layer, collisionMasks: convertCollisionMaskToNames(tile.collision_mask), - mapColor: Serdes.mapColour(tile.map_color), + mapColor: Converters.mapColour(tile.map_color), canBeMined: tile.mineable_properties.minable, } ) diff --git a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts index 1ea1d0e..8ceb25b 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts @@ -1,7 +1,9 @@ import {emitPacket} from "../emitKafkatorioPacket"; -import {convertPrototypes} from "../../prototypes/emitPrototypes"; +import {convertPrototypes} from "./convertPrototypes"; +import {updateGlobal} from "./updateGlobal"; export function handleConfigurationUpdate(changeData: ConfigurationChangedData) { + updateGlobal() emitPacket({ modVersion: global.MOD_VERSION, diff --git a/modules/events-mod/src/main/typescript/main/events/serdes.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts similarity index 95% rename from modules/events-mod/src/main/typescript/main/events/serdes.ts rename to modules/events-mod/src/main/typescript/main/events/converters.ts index 4eb7e42..b8eebdf 100644 --- a/modules/events-mod/src/main/typescript/main/events/serdes.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -1,4 +1,4 @@ -export namespace Serdes { +export namespace Converters { export function playerToTable(player: LuaPlayer): PlayerData { let charIds = entitiesToUnitNumbers(player.get_associated_characters()) @@ -37,7 +37,7 @@ export namespace Serdes { } } - export function entitiesToUnitNumbers(entities: LuaEntity[]): uint[] { + function entitiesToUnitNumbers(entities: LuaEntity[]): uint[] { let result: (uint) [] = [] for (let entity of entities) { if (entity.unit_number != null) { diff --git a/modules/events-mod/src/main/typescript/main/events/emitEvent.ts b/modules/events-mod/src/main/typescript/main/events/emitEvent.ts new file mode 100644 index 0000000..4aad9ee --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/events/emitEvent.ts @@ -0,0 +1,14 @@ +// const SERVER_ID: uint = 0 +// const EVENT_FILE_DIR: string = "events" + +import {emitPacket} from "../emitKafkatorioPacket"; + +/** Emit a serialised event */ +export function emitEvent(eventData: T, tick: uint, eventType: string) { + emitPacket({ + data: eventData, + eventType: eventType, + modVersion: global.MOD_VERSION, + tick: tick + }) +} diff --git a/modules/events-mod/src/main/typescript/main/events/emitter.ts b/modules/events-mod/src/main/typescript/main/events/emitter.ts deleted file mode 100644 index 28a8f8e..0000000 --- a/modules/events-mod/src/main/typescript/main/events/emitter.ts +++ /dev/null @@ -1,20 +0,0 @@ -export const MOD_VERSION = script.active_mods["@mod.name@"] ?? "UNKNOWN" -export const FACTORIO_VERSION = script.active_mods["base"] ?? "UNKNOWN" - -// const SERVER_ID: uint = 0 -// const EVENT_FILE_DIR: string = "events" - -/** Emit a serialised event */ -export function emitEvent(eventData: T, tick: uint, eventType: string) { - - let event: FactorioEvent = { - data: eventData, - eventType: eventType, - modVersion: MOD_VERSION, - tick: tick - } - - let data = game.table_to_json(event) - - localised_print(`FactorioEvent: ${data}`) -} diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index 0bcf505..036080a 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -1,9 +1,11 @@ -import {Serdes} from "./serdes" -import {emitEvent} from "./emitter"; +import {Converters} from "./converters" +import {emitEvent} from "./emitEvent"; export function handlePlayerUpdate(tick: uint, playerIndex: uint, eventType: string) { let player: LuaPlayer = game.players[playerIndex] - let table = Serdes.playerToTable(player) + let table = Converters.playerToTable(player) + + emitEvent(table, tick, eventType) handleCharactersEvent(tick, playerIndex, eventType) @@ -24,7 +26,7 @@ export function handleCharactersEvent(tick: uint, playerIndex: uint, eventType: } export function handleEntityUpdate(tick: uint, entity: LuaEntity, eventType: string) { - let table = Serdes.entityToTable(entity) + let table = Converters.entityToTable(entity) emitEvent(table, tick, eventType) } @@ -33,7 +35,7 @@ export function handleSurfaceUpdate( surface: LuaSurface, eventType: string ) { - let table = Serdes.surfaceToTable(surface) + let table = Converters.surfaceToTable(surface) emitEvent(table, tick, eventType) } @@ -44,7 +46,7 @@ export function handleConsoleChat( message: string, eventType: string, ) { - let table = Serdes.consoleChat(message, playerIndex) + let table = Converters.consoleChat(message, playerIndex) emitEvent(table, tick, eventType) } @@ -71,8 +73,8 @@ export function handleChunkUpdate( let tilePositionMap = new Map(); for (let tile of tiles) { - let position = Serdes.convertMapPosition(tile.position) - tilePositionMap.set(position, Serdes.convertTile(tile)) + let position = Converters.convertMapPosition(tile.position) + tilePositionMap.set(position, Converters.convertTile(tile)) } let mapChunk: FactorioTilesMap = { objectName: "FactorioTilesMap", diff --git a/modules/events-mod/src/main/typescript/main/events.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts similarity index 98% rename from modules/events-mod/src/main/typescript/main/events.ts rename to modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index fd5d7d3..969d90d 100644 --- a/modules/events-mod/src/main/typescript/main/events.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -4,7 +4,7 @@ import { handleEntityUpdate, handlePlayerUpdate, handleSurfaceUpdate -} from "./events/handlers"; +} from "./handlers"; const mapEventIdToName = new LuaTable() for (const [k, v] of pairs(defines.events)) { diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index 191e215..6da45c7 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -27,6 +27,7 @@ data class Colour( val blue: Float = 0f, val alpha: Float = 1f, ) { + /** True if any value is greater than 1, so the values are hexadecimal. */ fun isDecimal(): Boolean { return red > 1f diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index 15eef33..12b0994 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -8,7 +8,7 @@ import kotlinx.serialization.Serializable data class FactorioEvent( override val modVersion: String, - /** the initial Factorio event ({defines.events}) trigger */ + /** the initial Factorio event (`defines.events`) trigger */ val eventType: String, /** game time */ val tick: UInt, From 56fa2cbf0087ecf62a796eb73f417a9d344bae72 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Jan 2022 14:02:30 +0100 Subject: [PATCH 117/629] fix bugs (mostly tstl limitations) and improve schema structure a bit --- .../events-mod/src/main/typescript/control.ts | 2 +- .../generated/kafkatorio-schema/object-data.d.ts | 6 +++--- .../main/config-update/convertPrototypes.ts | 4 ++-- .../config-update/handleConfigurationUpdate.ts | 4 ++-- .../main/typescript/main/events/converters.ts | 2 +- .../src/main/typescript/main/events/handlers.ts | 16 +++++++--------- .../events/schema/factorioLuaObjects.kt | 12 ++++++------ modules/infra-kafka-pipe/src/kafka-pipe.sh | 2 +- 8 files changed, 23 insertions(+), 25 deletions(-) diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index a195c76..43783ab 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -1,5 +1,5 @@ import {handleConfigurationUpdate} from "./main/config-update/handleConfigurationUpdate"; -require("./main/events") +require("./main/events/registerHandlers") script.on_configuration_changed(handleConfigurationUpdate) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts index 612b721..f9d50fe 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts @@ -42,16 +42,16 @@ interface SurfaceData extends FactorioObjectData { objectName: string; } -interface FactorioTile extends FactorioObjectData { +interface FactorioMapTile extends FactorioObjectData { objectName: string; position: PositionData; prototypeName: string; surfaceIndex: int; } -interface FactorioTilesMap extends FactorioObjectData { +interface FactorioMapChunk extends FactorioObjectData { objectName: string; - tiles: Map; + tiles: FactorioMapTile[]; } interface ConsoleChatMessage extends FactorioObjectData { diff --git a/modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts b/modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts index b1e2c3f..5234afb 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts @@ -1,7 +1,7 @@ import {Converters} from "../events/converters"; -export function convertPrototypes (): FactorioPrototype[] { - let prototypes = new Array() +export function convertPrototypes(): FactorioPrototype[] { + let prototypes: FactorioPrototype[] = [] prototypes.push(...getMapTilePrototypes()) diff --git a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts index 8ceb25b..89d5657 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts @@ -32,8 +32,8 @@ function allMods(e: ConfigurationChangedData): FactorioModInfo[] { return modNames.map((modName) => { - let currentVer = script.active_mods[modName] ?? e.mod_changes[modName].new_version - let previousVer = e.mod_changes[modName].old_version + let currentVer = script.active_mods[modName] ?? e.mod_changes[modName].new_version ?? null + let previousVer = e.mod_changes[modName]?.old_version ?? null return { modName: modName, diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index b8eebdf..104df2a 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -83,7 +83,7 @@ export namespace Converters { } } - export function convertTile(tile: LuaTile): FactorioTile { + export function convertTile(tile: LuaTile): FactorioMapTile { return { objectName: tile.object_name, diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index 036080a..ba0bed4 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -39,7 +39,6 @@ export function handleSurfaceUpdate( emitEvent(table, tick, eventType) } - export function handleConsoleChat( tick: uint, playerIndex: uint | undefined, @@ -64,21 +63,20 @@ export function handleChunkUpdate( let x = (position as ChunkPositionTable).x * CHUNK_SIZE let y = (position as ChunkPositionTable).y * CHUNK_SIZE - let tiles = surface?.find_tiles_filtered({ + let tiles: LuaTile[] = surface?.find_tiles_filtered({ position: {x: x, y: y}, radius: CHUNK_SIZE, collision_mask: ["ground-tile", "water-tile"] } ) ?? [] - let tilePositionMap = new Map(); - for (let tile of tiles) { - let position = Converters.convertMapPosition(tile.position) - tilePositionMap.set(position, Converters.convertTile(tile)) - } - let mapChunk: FactorioTilesMap = { + let convertedTiles: FactorioMapTile[] = tiles.map((tile: LuaTile) => { + return Converters.convertTile(tile) + }) + + let mapChunk: FactorioMapChunk = { objectName: "FactorioTilesMap", - tiles: tilePositionMap, + tiles: convertedTiles, } emitEvent(mapChunk, tick, eventType) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt index 0ab2686..a8e1504 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -79,17 +79,17 @@ data class SurfaceData( } @Serializable -@SerialName("FactorioTilesMap") -data class FactorioTilesMap( - val tiles: Map, +@SerialName("FactorioMapChunk") +data class FactorioMapChunk( + val tiles: List, ) : FactorioObjectData() { @Transient - override val objectName: String = "FactorioTilesMap" + override val objectName: String = "FactorioMapChunk" } @Serializable @SerialName("LuaTile") -data class FactorioTile( +data class FactorioMapTile( val prototypeName: String, val position: PositionData, val surfaceIndex: Int, @@ -102,7 +102,7 @@ data class FactorioTile( data class ConsoleChatMessage( val authorPlayerIndex: UInt?, val content: String, -) : FactorioObjectData() { +) : FactorioObjectData() { @Transient override val objectName: String = "ConsoleChatMessage" } diff --git a/modules/infra-kafka-pipe/src/kafka-pipe.sh b/modules/infra-kafka-pipe/src/kafka-pipe.sh index b40a782..a8a8ea9 100644 --- a/modules/infra-kafka-pipe/src/kafka-pipe.sh +++ b/modules/infra-kafka-pipe/src/kafka-pipe.sh @@ -15,7 +15,7 @@ INSTANCE_ID=$(cat /proc/sys/kernel/random/uuid) while :; do docker logs --tail 0 -f "$FACTORIO_SERVER_CONTAINER_NAME" | - sed -n -e 's/^FactorioEvent: //p' | + sed -n -e 's/^KafkatorioPacket: //p' | kcat -P -T -b "$KAFKA_HOST" -t factorio-server-log -k "$INSTANCE_ID" echo "Error - retrying in 10 seconds" From e6d424960e42f4b847084423dd103b0c775d5ae6 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Jan 2022 14:02:38 +0100 Subject: [PATCH 118/629] fix tests --- .../kafkatorio/events/schema/FactorioEventTest.kt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt index 312eda6..64b4add 100644 --- a/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt +++ b/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt @@ -20,7 +20,8 @@ class FactorioEventTest : BehaviorSpec({ "associated_characters_unit_numbers": {}, "position": { "x": -3.5703125, - "y": 29.75 + "y": 29.75, + "type": "MAP" }, "last_online": 123 }, @@ -41,7 +42,8 @@ class FactorioEventTest : BehaviorSpec({ associatedCharactersUnitNumbers = emptyList(), position = PositionData( x = -3.5703125, - y = 29.75 + y = 29.75, + type = PositionType.MAP, ), colour = Colour(), chatColour = Colour(), @@ -49,7 +51,6 @@ class FactorioEventTest : BehaviorSpec({ ), eventType = "on_player_joined_game", modVersion = "0.0.4", - factorioVersion = "1.1.48", tick = 1278458u ) @@ -86,7 +87,6 @@ class FactorioEventTest : BehaviorSpec({ ), eventType = "on_tick", modVersion = "0.0.4", - factorioVersion = "1.1.48", tick = 1278480u ) @@ -111,7 +111,8 @@ class FactorioEventTest : BehaviorSpec({ "unit_number": 1, "position": { "x": -0.25, - "y": 30.09375 + "y": 30.09375, + "type": "MAP" } }, "event_type": "on_player_changed_position", @@ -136,11 +137,11 @@ class FactorioEventTest : BehaviorSpec({ position = PositionData( x = -0.25, y = 30.09375, + type = PositionType.MAP, ) ), eventType = "on_player_changed_position", modVersion = "0.0.6", - factorioVersion = "1.1.48", tick = 1384507u ) From 92566c7ebe76c5788d6af6d23a1276afc6e6e7e3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Jan 2022 14:03:08 +0100 Subject: [PATCH 119/629] don't restart Factorio server if there's a problem (it's probably a mod bug, and I want to see what it is) --- modules/infra-factorio-server/src/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infra-factorio-server/src/docker-compose.yml b/modules/infra-factorio-server/src/docker-compose.yml index dc6a261..680960c 100644 --- a/modules/infra-factorio-server/src/docker-compose.yml +++ b/modules/infra-factorio-server/src/docker-compose.yml @@ -7,7 +7,7 @@ services: # logging: # driver: "json-file" container_name: "factorio-server" - restart: "unless-stopped" + restart: "no" networks: - "kafkatorio-nw" ports: From 3875b9c3098e854c353e23becc5794b61d56f0ab Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Jan 2022 14:03:16 +0100 Subject: [PATCH 120/629] bump kafka-ui version --- modules/infra-kafka-cluster/src/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infra-kafka-cluster/src/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml index 600e071..c95fa8e 100644 --- a/modules/infra-kafka-cluster/src/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -20,7 +20,7 @@ services: - "9093:9093" kafka-ui: - image: provectuslabs/kafka-ui:0.2.1 + image: provectuslabs/kafka-ui:0.3.1 container_name: "kafka-ui" restart: "unless-stopped" networks: From 51e0aff823f98ebfb4dba164b60eb9020a07c5e3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Jan 2022 23:09:27 +0100 Subject: [PATCH 121/629] improve event-schema polymorphism with enums --- .../kafkatorio-schema/config-update.d.ts | 1 + .../kafkatorio-schema/object-data.d.ts | 17 +++++----- .../kafkatorio-schema/prototype.d.ts | 11 +++---- .../generated/kafkatorio-schema/schema.d.ts | 3 ++ .../handleConfigurationUpdate.ts | 1 + .../main/typescript/main/events/emitEvent.ts | 1 + .../events/schema/factorioConfiguration.kt | 6 +++- .../events/schema/factorioEvents.kt | 7 +++-- .../events/schema/factorioLuaObjects.kt | 26 +++++++++++----- .../events/schema/factorioPrototypes.kt | 11 ++++--- .../events/schema/kafkatorioPacket.kt | 21 +++++++------ .../adamko/kafkatorio/events/schema/kt2ts.kt | 14 +++++---- .../processor/FactorioEventsTopology.kt | 14 ++++++--- .../kafkatorio/processor/eventProcessor.kt | 1 + .../dev/adamko/kafkatorio/processor/serdes.kt | 11 +++---- .../dev/adamko/kafkatorio/webmap/App.kt | 1 - .../dev/adamko/kafkatorio/webmap/state.kt | 10 +++--- .../adamko/kafkatorio/webmap/websockets.kt | 31 +++++++++++++------ 18 files changed, 120 insertions(+), 67 deletions(-) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts index 1f8e37a..3302903 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts @@ -15,5 +15,6 @@ interface FactorioConfigurationUpdate extends KafkatorioPacket { allMods: FactorioModInfo[]; factorioData: FactorioGameDataUpdate; modVersion: string; + packetType: PacketType; prototypes: FactorioPrototype[]; } diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts index f9d50fe..27d0907 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts @@ -1,13 +1,16 @@ // Generated by TypeScriptGenerator - do not edit this file manually +type ObjectName = "LuaPlayer" | "LuaEntity" | "LuaSurface" | "FactorioMapChunk" | "LuaTile" | "ConsoleChatMessage"; + interface FactorioObjectData { - objectName: string; + objectName: ObjectName; } interface FactorioEvent extends KafkatorioPacket { data: T; eventType: string; modVersion: string; + packetType: PacketType; tick: uint; } @@ -18,7 +21,7 @@ interface PlayerData extends FactorioObjectData { colour: Colour; lastOnline: uint; name: string; - objectName: string; + objectName: ObjectName; position: PositionData; } @@ -27,7 +30,7 @@ interface EntityData extends FactorioObjectData { health: double | null; healthRatio: double; name: string; - objectName: string; + objectName: ObjectName; playerIndex: uint | null; position: PositionData; surfaceIndex: int; @@ -39,23 +42,23 @@ interface SurfaceData extends FactorioObjectData { daytime: double; index: uint; name: string; - objectName: string; + objectName: ObjectName; } interface FactorioMapTile extends FactorioObjectData { - objectName: string; + objectName: ObjectName; position: PositionData; prototypeName: string; surfaceIndex: int; } interface FactorioMapChunk extends FactorioObjectData { - objectName: string; + objectName: ObjectName; tiles: FactorioMapTile[]; } interface ConsoleChatMessage extends FactorioObjectData { authorPlayerIndex: uint | null; content: string; - objectName: string; + objectName: ObjectName; } diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts index f1d2052..fdb93b9 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts @@ -1,12 +1,9 @@ // Generated by TypeScriptGenerator - do not edit this file manually -interface FactorioPrototype { - objectName: string; -} +type PrototypeObjectName = "LuaTilePrototype"; -interface FactorioPrototypes extends KafkatorioPacket { - modVersion: string; - prototypes: T[]; +interface FactorioPrototype { + objectName: PrototypeObjectName; } interface FactorioMapTilePrototype extends FactorioPrototype { @@ -15,6 +12,6 @@ interface FactorioMapTilePrototype extends FactorioPrototype { layer: uint; mapColor: Colour; name: string; - objectName: string; + objectName: PrototypeObjectName; order: string; } diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts index 9738c8c..18b91eb 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts @@ -1,7 +1,10 @@ // Generated by TypeScriptGenerator - do not edit this file manually +type PacketType = "EVENT" | "CONFIG"; + interface KafkatorioPacket { modVersion: string; + packetType: PacketType; } interface Colour { diff --git a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts index 89d5657..7298fb1 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts @@ -7,6 +7,7 @@ export function handleConfigurationUpdate(changeData: ConfigurationChangedData) emitPacket({ modVersion: global.MOD_VERSION, + packetType: "CONFIG", allMods: allMods(changeData), factorioData: factorioData(changeData), prototypes: convertPrototypes() diff --git a/modules/events-mod/src/main/typescript/main/events/emitEvent.ts b/modules/events-mod/src/main/typescript/main/events/emitEvent.ts index 4aad9ee..771b408 100644 --- a/modules/events-mod/src/main/typescript/main/events/emitEvent.ts +++ b/modules/events-mod/src/main/typescript/main/events/emitEvent.ts @@ -7,6 +7,7 @@ import {emitPacket} from "../emitKafkatorioPacket"; export function emitEvent(eventData: T, tick: uint, eventType: string) { emitPacket({ data: eventData, + packetType: "EVENT", eventType: eventType, modVersion: global.MOD_VERSION, tick: tick diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt index a3c829f..ad8844f 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt @@ -1,6 +1,7 @@ package dev.adamko.kafkatorio.events.schema import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient @Serializable @@ -9,7 +10,10 @@ data class FactorioConfigurationUpdate( val factorioData: FactorioGameDataUpdate, val allMods: List, val prototypes: List, -) : KafkatorioPacket +) : KafkatorioPacket() { + @Transient + override val packetType = PacketType.CONFIG +} @Serializable data class FactorioGameDataUpdate( diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index 12b0994..aaaf2a1 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -2,15 +2,18 @@ package dev.adamko.kafkatorio.events.schema import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient @Serializable data class FactorioEvent( override val modVersion: String, - /** the initial Factorio event (`defines.events`) trigger */ val eventType: String, /** game time */ val tick: UInt, val data: T, -) : KafkatorioPacket +) : KafkatorioPacket() { + @Transient + override val packetType: PacketType = PacketType.EVENT +} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt index a8e1504..7d5d749 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -9,7 +9,8 @@ import kotlinx.serialization.json.JsonClassDiscriminator @JsonClassDiscriminator(FactorioObjectData.discriminatorKey) sealed class FactorioObjectData { - abstract val objectName: String + /** @see FactorioObjectData.discriminatorKey */ + abstract val objectName: ObjectName // workaround - https://github.com/Kotlin/kotlinx.serialization/issues/1664 // val objectName: String by lazy { @@ -28,12 +29,22 @@ sealed class FactorioObjectData { // } // } + enum class ObjectName { + LuaPlayer, + LuaEntity, + LuaSurface, + FactorioMapChunk, + LuaTile, + ConsoleChatMessage, + } + companion object { /** The [JsonClassDiscriminator] for [FactorioEvent] */ const val discriminatorKey: String = "objectName" } } + @Serializable @SerialName("LuaPlayer") data class PlayerData( @@ -47,7 +58,7 @@ data class PlayerData( val lastOnline: UInt, ) : FactorioObjectData() { @Transient - override val objectName: String = "LuaPlayer" + override val objectName = ObjectName.LuaPlayer } @Serializable @@ -64,7 +75,7 @@ data class EntityData( val playerIndex: UInt? = null, ) : FactorioObjectData() { @Transient - override val objectName: String = "LuaEntity" + override val objectName = ObjectName.LuaEntity } @Serializable @@ -75,16 +86,17 @@ data class SurfaceData( val name: String, ) : FactorioObjectData() { @Transient - override val objectName: String = "LuaSurface" + override val objectName = ObjectName.LuaSurface } +/** Quasi-object. This isn't a Factorio Lua type, but a helpful collection of [FactorioMapTile]s */ @Serializable @SerialName("FactorioMapChunk") data class FactorioMapChunk( val tiles: List, ) : FactorioObjectData() { @Transient - override val objectName: String = "FactorioMapChunk" + override val objectName = ObjectName.FactorioMapChunk } @Serializable @@ -95,7 +107,7 @@ data class FactorioMapTile( val surfaceIndex: Int, ) : FactorioObjectData() { @Transient - override val objectName: String = "LuaTile" + override val objectName = ObjectName.LuaTile } @Serializable @@ -104,5 +116,5 @@ data class ConsoleChatMessage( val content: String, ) : FactorioObjectData() { @Transient - override val objectName: String = "ConsoleChatMessage" + override val objectName = ObjectName.ConsoleChatMessage } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt index 70404b9..82316f3 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt @@ -7,14 +7,17 @@ import kotlinx.serialization.json.JsonClassDiscriminator @Serializable class FactorioPrototypes( - override val modVersion: String, val prototypes: List, -) : KafkatorioPacket +) @Serializable @JsonClassDiscriminator(FactorioPrototype.discriminatorKey) sealed class FactorioPrototype { - abstract val objectName: String + abstract val objectName: PrototypeObjectName + + enum class PrototypeObjectName { + LuaTilePrototype + } companion object { const val discriminatorKey: String = "objectName" @@ -34,5 +37,5 @@ data class FactorioMapTilePrototype( val canBeMined: Boolean, ) : FactorioPrototype() { @Transient - override val objectName: String = "LuaTilePrototype" + override val objectName: PrototypeObjectName = PrototypeObjectName.LuaTilePrototype } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt index 194f2c6..fa6d789 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt @@ -1,19 +1,22 @@ package dev.adamko.kafkatorio.events.schema; +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonClassDiscriminator -//@Serializable -sealed interface KafkatorioPacket { + +@Serializable +@JsonClassDiscriminator("packetType") +sealed class KafkatorioPacket { /** Schema versioning */ - val modVersion: String + abstract val modVersion: String + abstract val packetType: PacketType + + enum class PacketType { + EVENT, CONFIG, + } } -//enum class PacketDataType { -// EVENT, PROTOTYPE, CONFIG_DATA, -// ; -//} - - //@Serializable //@JsonClassDiscriminator(KafkatorioPacketData.discriminatorKey) //sealed class KafkatorioPacketData( diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt index c1b48ab..3086333 100644 --- a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt @@ -48,7 +48,7 @@ fun main(args: Array) { .forEach { (defFile, def) -> val outFile = outPath.resolve(defFile).toFile() outFile.printWriter().use { - it.print(header) + it.println(header) it.print(def) } println("Generated file: $outFile") @@ -65,14 +65,16 @@ private fun splitDefinitions(definitions: String): Map { .groupBy { def -> when { "extends FactorioObjectData" in def || - "interface FactorioObjectData" in def -> "object-data.d.ts" + "interface FactorioObjectData" in def || + "type ObjectName" in def -> "object-data.d.ts" "extends FactorioPrototype" in def || - "interface FactorioPrototype" in def -> "prototype.d.ts" + "interface FactorioPrototype" in def || + "type PrototypeObjectName" in def -> "prototype.d.ts" "extends FactorioConfigurationUpdate" in def || "interface FactorioConfigurationUpdate" in def || "FactorioGameDataUpdate" in def || - "FactorioModInfo" in def -> "config-update.d.ts" - else -> "schema.d.ts" + "FactorioModInfo" in def -> "config-update.d.ts" + else -> "schema.d.ts" } } .mapValues { (_, def) -> @@ -86,7 +88,7 @@ private fun splitDefinitions(definitions: String): Map { val header = """ |// Generated by TypeScriptGenerator - do not edit this file manually | -""".trimMargin() + "\n" +""".trimMargin() //object PropertyNameTransformer : ClassTransformer { // override fun transformPropertyName( diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt index d87339d..139bf1b 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt @@ -1,7 +1,8 @@ package dev.adamko.kafkatorio.processor +import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate import dev.adamko.kafkatorio.events.schema.FactorioEvent -import dev.adamko.kafkatorio.events.schema.FactorioObjectData +import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import java.time.Duration import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString @@ -27,7 +28,7 @@ class FactorioEventsTopology( ) .mapValues { readOnlyKey, value -> println("Mapping $readOnlyKey:$value") - jsonMapper.decodeFromString>(value) + jsonMapper.decodeFromString(value) } .peek { _, value -> websocketServer.sendMessage(jsonMapper.encodeToString(value)) @@ -35,9 +36,14 @@ class FactorioEventsTopology( .to( { _, value, _ -> // println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") - value.data.objectName + when (value) { + is FactorioEvent<*> -> + "kafkatorio.${value.packetType.name}.${value.data.objectName.name}" + is FactorioConfigurationUpdate -> + "kafkatorio.${value.packetType.name}" + } }, - Produced.with(Serdes.String(), JsonSerdes) + Produced.with(Serdes.String(), KafkatorioPacketSerde) ) val topology = builder.build() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt index ca3d7e2..0011293 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -16,4 +16,5 @@ fun main() = runBlocking { topology.build() wsServer.build().asServer(Undertow(9073)).start().block() + } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt index 14c40bf..3138db1 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt @@ -1,7 +1,6 @@ package dev.adamko.kafkatorio.processor -import dev.adamko.kafkatorio.events.schema.FactorioEvent -import dev.adamko.kafkatorio.events.schema.FactorioObjectData +import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json @@ -14,12 +13,12 @@ import org.http4k.format.asConfigurable import org.http4k.format.withStandardMappings -object JsonSerdes : Serde> { - override fun serializer() = Serializer> { _, message -> - jsonMapper.encodeToString>(message).encodeToByteArray() +object KafkatorioPacketSerde : Serde { + override fun serializer() = Serializer { _, message -> + jsonMapper.encodeToString(message).encodeToByteArray() } - override fun deserializer() = Deserializer> { _, bytes -> + override fun deserializer() = Deserializer { _, bytes -> jsonMapper.decodeFromString(bytes.decodeToString()) } } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index 762d111..7615b19 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -56,7 +56,6 @@ fun main() { "ws://localhost:9073/ws", reduxStore, ) - App( reduxStore = reduxStore, wsService = wsService diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt index ec1c63d..8b1b823 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt @@ -2,9 +2,8 @@ package dev.adamko.kafkatorio.webmap import dev.adamko.kafkatorio.events.schema.FactorioEvent import dev.adamko.kafkatorio.events.schema.PlayerData -import externals.leaflet.geo.LatLng -import externals.leaflet.layer.overlay.Tooltip -import externals.leaflet.layer.vector.CircleMarker +import io.kvision.maps.externals.leaflet.layer.overlay.Tooltip +import io.kvision.maps.externals.leaflet.layer.vector.CircleMarker import io.kvision.maps.Maps import io.kvision.maps.Maps.Companion.L import io.kvision.redux.ReduxStore @@ -12,6 +11,7 @@ import io.kvision.redux.createReduxStore import io.kvision.utils.obj import redux.RAction + fun createFactorioReduxStore(): ReduxStore = createReduxStore( ::factorioGameReducer, @@ -21,6 +21,7 @@ fun createFactorioReduxStore(): ReduxStore = ) ) + data class FactorioGameState( val kvMaps: Maps, val players: Map, @@ -32,6 +33,7 @@ sealed class FactorioUpdate : RAction { FactorioUpdate() } + fun factorioGameReducer(state: FactorioGameState, update: FactorioUpdate): FactorioGameState = when (update) { is FactorioUpdate.PlayerUpdate -> { @@ -77,7 +79,7 @@ data class PlayerState( fillColor = color fillOpacity = 1f radius = 10 - className = playerData.objectName + className = playerData.objectName.name // interactive = false } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt index fdc7f95..0b05406 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -1,13 +1,20 @@ package dev.adamko.kafkatorio.webmap +import dev.adamko.kafkatorio.events.schema.ConsoleChatMessage +import dev.adamko.kafkatorio.events.schema.EntityData +import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate import dev.adamko.kafkatorio.events.schema.FactorioEvent -import dev.adamko.kafkatorio.events.schema.FactorioObjectData +import dev.adamko.kafkatorio.events.schema.FactorioMapChunk +import dev.adamko.kafkatorio.events.schema.FactorioMapTile +import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.events.schema.PlayerData +import dev.adamko.kafkatorio.events.schema.SurfaceData import io.kvision.redux.ReduxStore import kotlinx.serialization.decodeFromString import org.w3c.dom.MessageEvent import org.w3c.dom.WebSocket + class WebsocketService( private val wsUrl: String, private val reduxStore: ReduxStore, @@ -24,22 +31,28 @@ class WebsocketService( if ( data != null - && data.trim().startsWith("{") - && data.trim().endsWith("}") + && data.trim().run { startsWith("{") && endsWith("}") } ) { println(data.replace('\n', ' ')) - val event: FactorioEvent = jsonMapper.decodeFromString(data) - when (val eventData = event.data) { - is PlayerData -> { - reduxStore.dispatch(FactorioUpdate.PlayerUpdate(event, eventData)) + when (val event: KafkatorioPacket = jsonMapper.decodeFromString(data)) { + is FactorioEvent<*> -> { + when (val eventData = event.data) { + is PlayerData -> + reduxStore.dispatch(FactorioUpdate.PlayerUpdate(event, eventData)) + is ConsoleChatMessage -> {} + is EntityData -> {} + is FactorioMapChunk -> {} + is FactorioMapTile -> {} + is SurfaceData -> {} + } } - else -> {} + is FactorioConfigurationUpdate -> {} } + } else { println(data) - } } From ab858321267d36b11cfe2d4a76b37a532d3c4928 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Jan 2022 23:09:49 +0100 Subject: [PATCH 122/629] version bump kvision --- gradle/libs.versions.toml | 3 +-- modules/web-map/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d544e8c..a9e448b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,8 +13,7 @@ camel-kafkaConnectors = "0.11.0" http4k = "4.17.6.0" kafka = "3.0.0" kotlinx-serialization = "1.3.2" -#kvision = "5.6.1" -kvision = "5.6.2-SNAPSHOT" +kvision = "5.7.1" log4j2 = "2.14.1" qosLogback = "1.2.5" slf4j = "1.7.30" diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index fb7a2e2..502cedd 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -4,7 +4,7 @@ import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig plugins { id("dev.adamko.kafkatorio.lang.kotlin-js") kotlin("plugin.serialization") - id("io.kvision") version "5.6.1" + id("io.kvision") version "5.7.1" } kotlin { From 042ca9fb98070e97bd8e78ddc9e2846a9dfcf085 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Jan 2022 23:10:04 +0100 Subject: [PATCH 123/629] fix mod version and factorio version global def --- .../src/main/typescript/main/config-update/updateGlobal.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/config-update/updateGlobal.ts b/modules/events-mod/src/main/typescript/main/config-update/updateGlobal.ts index db1e621..c81be94 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/updateGlobal.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/updateGlobal.ts @@ -1,4 +1,4 @@ export function updateGlobal() { - global.MOD_VERSION = script.active_mods[script.mod_name][1] - global.FACTORIO_VERSION = script.active_mods["base"][1] + global.MOD_VERSION = script.active_mods[script.mod_name] + global.FACTORIO_VERSION = script.active_mods["base"] } From 4efd912f754acd91f3c2e2bd2dcd8b8675673fe6 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Jan 2022 23:10:27 +0100 Subject: [PATCH 124/629] binser for lua encode? --- README.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 507d532..022a03a 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,6 @@ 1. converts data to images 2. hosts a web map - - ## License While this project is under development, [no license](https://choosealicense.com/no-permission/) @@ -18,7 +16,7 @@ is provided. * add settings * is active - whether files are exported or not * delete files - clean up all files - * tick-rate - how often reports are generated + * tick-rate - how often reports are generated * requires on some sort of in-mod cache of map * also divide by game-speed? to keep ratio the same @@ -42,22 +40,21 @@ is provided. * https://jbrandhorst.com/post/go-protobuf-tips/ +* https://github.com/bakpakin/binser ##### wasm -kt -> wasm -> lua? -kt-flatbuffers -> wasm -> lua? +kt -> wasm -> lua? kt-flatbuffers -> wasm -> lua? https://www.npmjs.com/package/wasm2lua?activeTab=readme - ##### Encodings * flatbuffers https://github.com/dvidelabs/flatcc * z85 encoding - * Kotlin https://gist.github.com/ischumacher/b4929f26341ebef62cbce35c65543eda - * Lua https://web-eworks.github.io/lZ85/ + * Kotlin https://gist.github.com/ischumacher/b4929f26341ebef62cbce35c65543eda + * Lua https://web-eworks.github.io/lZ85/ * https://github.com/SafeteeWoW/LibDeflate -* CBOR - * https://www.zash.se/lua-cbor.html - * https://code.zash.se/lua-cbor/archive/68b3a36d0816.tar.gz +* CBOR + * https://www.zash.se/lua-cbor.html + * https://code.zash.se/lua-cbor/archive/68b3a36d0816.tar.gz From 3a7625c139f98a24a6da77c2ec71c9899510c914 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Jan 2022 23:14:27 +0100 Subject: [PATCH 125/629] fix wrong objectName --- modules/events-mod/src/main/typescript/main/events/handlers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index ba0bed4..2700139 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -75,7 +75,7 @@ export function handleChunkUpdate( }) let mapChunk: FactorioMapChunk = { - objectName: "FactorioTilesMap", + objectName: "FactorioMapChunk", tiles: convertedTiles, } From 11ffaedf14564c7aeab6fb99cf88e858d411a83c Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Jan 2022 23:18:50 +0100 Subject: [PATCH 126/629] version bump, and fix imports --- .kotlin-js-store/yarn.lock | 3342 +++++++++++++++++ build.gradle.kts | 2 +- .../src/main/typescript/package-lock.json | 2 +- .../src/main/typescript/package.json | 2 +- .../adamko/kafkatorio/webmap/converters.kt | 2 +- .../dev/adamko/kafkatorio/webmap/map.kt | 5 +- 6 files changed, 3348 insertions(+), 7 deletions(-) create mode 100644 .kotlin-js-store/yarn.lock diff --git a/.kotlin-js-store/yarn.lock b/.kotlin-js-store/yarn.lock new file mode 100644 index 0000000..7a7afaa --- /dev/null +++ b/.kotlin-js-store/yarn.lock @@ -0,0 +1,3342 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/runtime@^7.9.2": + version "7.16.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.5.tgz#7f3e34bf8bdbbadf03fbb7b1ea0d929569c9487a" + integrity sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA== + dependencies: + regenerator-runtime "^0.13.4" + +"@discoveryjs/json-ext@^0.5.0": + version "0.5.6" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" + integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA== + +"@fortawesome/fontawesome-free@^5.15.4": + version "5.15.4" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5" + integrity sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@popperjs/core@^2.10.2": + version "2.11.0" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.0.tgz#6734f8ebc106a0860dff7f92bf90df193f0935d7" + integrity sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ== + +"@rjaros/gettext.js@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@rjaros/gettext.js/-/gettext.js-1.1.3.tgz#8d1109f4a6f8e0c4dadba26281c7fe83de8ab18f" + integrity sha512-FgGWKCN88UE6nOmIjdv+gSnrE3AXjMx7f4uo3brLzKcC9dKzuNNDCzTIbuEDg38Pm1yYUTUH6QG4493T4sUnDg== + dependencies: + "@rjaros/po2json" "^1.0.0-beta-4" + +"@rjaros/po2json@^1.0.0-beta-4": + version "1.0.0-beta-4" + resolved "https://registry.yarnpkg.com/@rjaros/po2json/-/po2json-1.0.0-beta-4.tgz#0bd911af874afa39d868aeb88f6903cfabfbf5dd" + integrity sha512-VhNHrPJtX+caY99UnjCmMB0EWY4EgtZ/pj/Usyj4VUt3TtjHE5nV+fz4bVC0/OO641ncEFFfC3SJ2TurcwEWPw== + dependencies: + commander "^6.0.0" + gettext-parser "2.0.0" + gettext-to-messageformat "0.3.1" + +"@rjaros/snabbdom-virtualize@^1.0.0-beta.4": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@rjaros/snabbdom-virtualize/-/snabbdom-virtualize-1.0.0-beta.5.tgz#17f2586beee5e6c130e1b0ae2f589ff9162a86db" + integrity sha512-2rf1MI7wVSZLOgy+EXtOfYzqcwLtMjak4wzRBQUVJjO4qlCmlSo+bh890eKkILhRGxkp6aTQS9gMjH1fP9g8Nw== + dependencies: + html-parse-stringify "^3" + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.10" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" + integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== + dependencies: + "@types/node" "*" + +"@types/component-emitter@^1.2.10": + version "1.2.11" + resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" + integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== + +"@types/connect-history-api-fallback@^1.3.5": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" + integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/cookie@^0.4.0": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" + integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== + +"@types/cors@^2.8.8": + version "2.8.12" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" + integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== + +"@types/eslint-scope@^3.7.0": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.2.tgz#11e96a868c67acf65bf6f11d10bb89ea71d5e473" + integrity sha512-TzgYCWoPiTeRg6RQYgtuW7iODtVoKu3RVL72k3WohqhjfaOLK5Mg2T4Tg1o2bSfu0vPkoI48wdQFv5b/Xe04wQ== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.2.1" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.2.1.tgz#13f3d69bac93c2ae008019c28783868d0a1d6605" + integrity sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^0.0.50": + version "0.0.50" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" + integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== + +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": + version "4.17.27" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.27.tgz#7a776191e47295d2a05962ecbb3a4ce97e38b401" + integrity sha512-e/sVallzUTPdyOTiqi8O8pMdBBphscvI6E4JYaKlja4Lm+zh7UFSSdW5VMkRbhDtmrONqOUHOXRguPsDckzxNA== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/geojson@*", "@types/geojson@7946.0.8": + version "7946.0.8" + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" + integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA== + +"@types/glob@5 - 7": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/http-proxy@^1.17.5": + version "1.17.8" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.8.tgz#968c66903e7e42b483608030ee85800f22d03f55" + integrity sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA== + dependencies: + "@types/node" "*" + +"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== + +"@types/leaflet@^1.7.7": + version "1.7.7" + resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.7.7.tgz#3c9f629126e03405ed68cc1aa395e32df3312376" + integrity sha512-5/nNqTviSqUwPxbS3PlHl8ODjfnlpOXSFtUAi7dexnisO8E3pfyotChRY/hlIYGvbBiBcKNd6V18xA8O4OpHiQ== + dependencies: + "@types/geojson" "*" + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + +"@types/minimatch@*": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== + +"@types/node@*", "@types/node@>=10.0.0": + version "17.0.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.2.tgz#a4c07d47ff737e8ee7e586fe636ff0e1ddff070a" + integrity sha512-JepeIUPFDARgIs0zD/SKPgFsJEAF0X5/qO80llx59gOxFTboS9Amv3S+QfB7lqBId5sFXJ99BN0J6zFRvL9dDA== + +"@types/parse5@^5": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" + integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/retry@^0.12.0": + version "0.12.1" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" + integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== + +"@types/serve-index@^1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" + integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== + dependencies: + "@types/express" "*" + +"@types/serve-static@*": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.33" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" + integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== + dependencies: + "@types/node" "*" + +"@types/ws@^8.2.2": + version "8.2.2" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.2.2.tgz#7c5be4decb19500ae6b3d563043cd407bf366c21" + integrity sha512-NOn5eIcgWLOo6qW8AcuLZ7G8PycXu0xTxxkS6Q18VWFxgPUSOwV0pBj2a/4viNZVu25i7RIB7GttdkAIUUXOOg== + dependencies: + "@types/node" "*" + +"@ungap/promise-all-settled@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== + +"@webassemblyjs/ast@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + +"@webassemblyjs/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== + +"@webassemblyjs/helper-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + +"@webassemblyjs/helper-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== + +"@webassemblyjs/helper-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== + +"@webassemblyjs/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + +"@webassemblyjs/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + +"@webassemblyjs/wasm-edit@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + +"@webassemblyjs/wasm-gen@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wasm-opt@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + +"@webassemblyjs/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webpack-cli/configtest@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.0.tgz#8342bef0badfb7dfd3b576f2574ab80c725be043" + integrity sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg== + +"@webpack-cli/info@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.0.tgz#b9179c3227ab09cbbb149aa733475fcf99430223" + integrity sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw== + dependencies: + envinfo "^7.7.3" + +"@webpack-cli/serve@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.0.tgz#2c275aa05c895eccebbfc34cfb223c6e8bd591a2" + integrity sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abab@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + +acorn@^8.4.1: + version "8.6.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" + integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.0, ajv@^8.8.0: + version "8.8.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.8.2.tgz#01b4fef2007a28bf75f0b7fc009f62679de4abbb" + integrity sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +async@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +awesome-bootstrap-checkbox@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/awesome-bootstrap-checkbox/-/awesome-bootstrap-checkbox-1.0.1.tgz#dab10146b6001129ab0a0ec1e54bb77c6c30457a" + integrity sha1-2rEBRrYAESmrCg7B5Uu3fGwwRXo= + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-arraybuffer@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" + integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= + +base64id@2.0.0, base64id@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +body-parser@1.19.1, body-parser@^1.19.0: + version "1.19.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.1.tgz#1499abbaa9274af3ecc9f6f10396c995943e31d4" + integrity sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA== + dependencies: + bytes "3.1.1" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.9.6" + raw-body "2.4.2" + type-is "~1.6.18" + +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + +bootstrap-icons@^1.6.0: + version "1.7.2" + resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.7.2.tgz#4024e081e2c850602552e1fed6451e682d09322a" + integrity sha512-NiR2PqC73AQOPdVSu6GJfnk+hN2z6powcistXk1JgPnKuoV2FSdSl26w931Oz9HYbKCcKUSB6ncZTYJAYJl3QQ== + +bootstrap@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.1.3.tgz#ba081b0c130f810fa70900acbc1c6d3c28fa8f34" + integrity sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserslist@^4.14.5: + version "4.19.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" + integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== + dependencies: + caniuse-lite "^1.0.30001286" + electron-to-chromium "^1.4.17" + escalade "^3.1.1" + node-releases "^2.0.1" + picocolors "^1.0.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +bytes@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a" + integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg== + +call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +camelcase@^6.0.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.1.tgz#250fd350cfd555d0d2160b1d51510eaf8326e86e" + integrity sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA== + +caniuse-lite@^1.0.30001286: + version "1.0.30001292" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001292.tgz#4a55f61c06abc9595965cfd77897dc7bc1cdc456" + integrity sha512-jnT4Tq0Q4ma+6nncYQVe7d73kmDmE9C3OGTx3MvW7lBM/eY1S1DZTMBON7dqV481RhNiS5OxD7k9JQvmDOTirw== + +chalk@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chart.js@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.6.2.tgz#47342c551f688ffdda2cd53b534cb7e461ecec33" + integrity sha512-Xz7f/fgtVltfQYWq0zL1Xbv7N2inpG+B54p3D5FSvpCdy3sM+oZhbqa42eNuYXltaVvajgX5UpKCU2GeeJIgxg== + +chokidar@3.5.2, chokidar@^3.5.1, chokidar@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^2.0.10, colorette@^2.0.14: + version "2.0.16" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" + integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== + +colors@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^6.0.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + +commander@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +component-emitter@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +connect@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== + dependencies: + debug "2.6.9" + finalhandler "1.1.2" + parseurl "~1.3.3" + utils-merge "1.0.1" + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.1, cookie@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cors@~2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-loader@^6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.5.1.tgz#0c43d4fbe0d97f699c91e9818cb585759091d1b1" + integrity sha512-gEy2w9AnJNnD9Kuo4XAP9VflW/ujKoS9c/syO+uWMlm5igc7LysKzPXaDoR2vroROkSwsTS2tGr1yGGEbZOYZQ== + dependencies: + icss-utils "^5.1.0" + postcss "^8.2.15" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.1.0" + semver "^7.3.5" + +css-selector-parser@^1.3: + version "1.4.1" + resolved "https://registry.yarnpkg.com/css-selector-parser/-/css-selector-parser-1.4.1.tgz#03f9cb8a81c3e5ab2c51684557d5aaf6d2569759" + integrity sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= + +date-format@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-2.1.0.tgz#31d5b5ea211cf5fd764cd38baf9d033df7e125cf" + integrity sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA== + +date-format@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-3.0.0.tgz#eb8780365c7d2b1511078fb491e6479780f3ad95" + integrity sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + +debug@^3.1.1: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.0, debug@^4.1.1, debug@~4.3.1: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +deep-equal@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +del@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/del/-/del-6.0.0.tgz#0b40d0332cea743f1614f818be4feb717714c952" + integrity sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ== + dependencies: + globby "^11.0.1" + graceful-fs "^4.2.4" + is-glob "^4.0.1" + is-path-cwd "^2.2.0" + is-path-inside "^3.0.2" + p-map "^4.0.0" + rimraf "^3.0.2" + slash "^3.0.0" + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw= + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + +dns-packet@^1.3.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" + integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + +dom-serialize@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + integrity sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs= + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + +dukat@0.5.8-rc.3: + version "0.5.8-rc.3" + resolved "https://registry.yarnpkg.com/dukat/-/dukat-0.5.8-rc.3.tgz#4a2b848b9d2978cb610af8d5cf24ff5e5a408743" + integrity sha512-wzl9A5alTT1Mag4y7bUVjPF4L/wkts7AiiWxe6/6tL5gSDowexUzlJX/pYVTbnHcOo48/bok3Ao1gzU4/cFFjw== + dependencies: + google-protobuf "3.12.2" + typescript "3.9.5" + +dukat@0.5.8-rc.4: + version "0.5.8-rc.4" + resolved "https://registry.yarnpkg.com/dukat/-/dukat-0.5.8-rc.4.tgz#90384dcb50b14c26f0e99dae92b2dea44f5fce21" + integrity sha512-ZnMt6DGBjlVgK2uQamXfd7uP/AxH7RqI0BL9GLrrJb2gKdDxvJChWy+M9AQEaL+7/6TmxzJxFOsRiInY9oGWTA== + dependencies: + google-protobuf "3.12.2" + typescript "3.9.5" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +electron-to-chromium@^1.4.17: + version "1.4.27" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.27.tgz#bfc6e798d8a56a17d658312f4b7ae1a7ca87724f" + integrity sha512-uZ95szi3zUbzRDx1zx/xnsCG+2xgZyy57pDOeaeO4r8zx5Dqe8Jv1ti8cunvBwJHVI5LzPuw8umKwZb3WKYxSQ== + +element-resize-event@^3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/element-resize-event/-/element-resize-event-3.0.6.tgz#3a18efd4879ad615e979fd8bbf173b014987eb9a" + integrity sha512-sSeXY9rNDp86bJODW68pxLcy3A5FrPZfIgOrJHzqgYzX513Zq6/ytdBigp7KeJEpZZopBBSiO1cVuiRkZpNxLw== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +encoding@^0.1.12: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + +engine.io-parser@~4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-4.0.3.tgz#83d3a17acfd4226f19e721bb22a1ee8f7662d2f6" + integrity sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA== + dependencies: + base64-arraybuffer "0.1.4" + +engine.io@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-4.1.1.tgz#9a8f8a5ac5a5ea316183c489bf7f5b6cf91ace5b" + integrity sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w== + dependencies: + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~4.0.0" + ws "~7.4.2" + +enhanced-resolve@^5.8.3: + version "5.8.3" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" + integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0= + +envinfo@^7.7.3: + version "7.8.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" + integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +express@^4.17.1: + version "4.17.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.2.tgz#c18369f265297319beed4e5558753cc8c1364cb3" + integrity sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.4.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.9.6" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.17.2" + serve-static "1.14.2" + setprototypeof "1.2.0" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.1.1: + version "3.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" + integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fastest-levenshtein@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" + integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== + +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +fecha@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce" + integrity sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.1.2, finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatted@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" + integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== + +follow-redirects@^1.0.0: + version "1.14.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.6.tgz#8cfb281bbc035b3c067d6cd975b0f6ade6e855cd" + integrity sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A== + +format-util@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" + integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +fs-extra@^8.0.1, fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-monkey@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" + integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +geojson@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/geojson/-/geojson-0.5.0.tgz#3cd6c96399be65b56ee55596116fe9191ce701c0" + integrity sha1-PNbJY5m+ZbVu5VWWEW/pGRznAcA= + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +gettext-extract@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/gettext-extract/-/gettext-extract-2.0.1.tgz#4ade7e3d7c1c247d95a81f28059ca1923c355886" + integrity sha512-k51R90txkCZeXQEDjK0e7gNHfBHJVCu8IQ3AbSVZoOL5nR3yl+C+7qpzp6hoZwOtiniaY+CKeLyvNulsEUM6MA== + dependencies: + chalk "^2.3.0" + find-up "^4.1.0" + fs-extra "^8.0.1" + gettext-extractor "^3.1.0" + minimist "^1.2.0" + +gettext-extractor@^3.1.0: + version "3.5.3" + resolved "https://registry.yarnpkg.com/gettext-extractor/-/gettext-extractor-3.5.3.tgz#6ed46931c154a7485a80fa8b91b835ff7b8d0411" + integrity sha512-9EgJ+hmbtAbATdMIvCj4WnrkeDWH6fv1z+IJJ1XCxdcUMGx6JQdVVFTdzJkSyIHh4td53ngoB5EQbavbKJU9Og== + dependencies: + "@types/glob" "5 - 7" + "@types/parse5" "^5" + css-selector-parser "^1.3" + glob "5 - 7" + parse5 "5 - 6" + pofile "1.0.x" + typescript "2 - 4" + +gettext-parser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-2.0.0.tgz#c28bb31e61f76f14665dfafbb5c0518cdc1270ed" + integrity sha512-FDs/7XjNw58ToQwJFO7avZZbPecSYgw8PBYhd0An+4JtZSrSzKhEvTsVV2uqdO7VziWTOGSgLGD5YRPdsCjF7Q== + dependencies: + encoding "^0.1.12" + safe-buffer "^5.1.2" + +gettext-parser@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-1.4.0.tgz#f8baf34a292f03d5e42f02df099d301f167a7ace" + integrity sha512-sedZYLHlHeBop/gZ1jdg59hlUEcpcZJofLq2JFwJT1zTqAU3l2wFv6IsuwFHGqbiT9DWzMUW4/em2+hspnmMMA== + dependencies: + encoding "^0.1.12" + safe-buffer "^5.1.1" + +gettext-to-messageformat@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/gettext-to-messageformat/-/gettext-to-messageformat-0.3.1.tgz#c303ff9e31a5c781b14629b13bddb27b9ffca1f8" + integrity sha512-UyqIL3Ul4NryU95Wome/qtlcuVIqgEWVIFw0zi7Lv14ACLXfaVDCbrjZ7o+3BZ7u+4NS1mP/2O1eXZoHCoas8g== + dependencies: + gettext-parser "^1.4.0" + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +"glob@5 - 7", glob@^7.1.3, glob@^7.1.7: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@7.1.7: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globby@^11.0.1: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + +google-protobuf@3.12.2: + version "3.12.2" + resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.12.2.tgz#50ce9f9b6281235724eb243d6a83e969a2176e53" + integrity sha512-4CZhpuRr1d6HjlyrxoXoocoGFnRYgKULgMtikMddA9ztRyYR59Aondv2FioyxWVamRo0rF2XpYawkTCBEQOSkA== + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6: + version "4.2.8" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" + integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488" + integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ== + +html-parse-stringify@^3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2" + integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg== + dependencies: + void-elements "3.1.0" + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + +http-errors@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.5.tgz#d7c30d5d3c90d865b4a2e870181f9d6f22ac7ac5" + integrity sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA== + +http-proxy-middleware@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.1.tgz#7ef3417a479fb7666a571e09966c66a39bd2c15f" + integrity sha512-cfaXRVoZxSed/BmkA7SwBVNI9Kj7HFltaE5rqYOub5kWzWZ+gofV2koVN1j2rMW7pEfSSlCHGJ31xmuyFyfLOg== + dependencies: + "@types/http-proxy" "^1.17.5" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +ignore@^5.1.4: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + +import-local@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.3.tgz#4d51c2c495ca9393da259ec66b62e022920211e0" + integrity sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imports-loader@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-3.1.1.tgz#3e464d9aad1e303b1b34b658eb8f8aae22f96435" + integrity sha512-3QMyGU4RTgxLf0puWkUfT5+7zJvexvB00PI5skDIcxG8O20gZCbQsaRpNBv+cIO6yy/lmlOBwaxc3uH1CV+sww== + dependencies: + source-map "^0.6.1" + strip-comments "^2.0.1" + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + +ip@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-core-module@^2.2.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" + integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-cwd@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-regex@^1.0.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isbinaryfile@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.8.tgz#5d34b94865bd4946633ecc78a026fc76c5b11fcf" + integrity sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +jest-worker@^27.4.1: + version "27.4.5" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.5.tgz#d696e3e46ae0f24cff3fa7195ffba22889262242" + integrity sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jquery@^3.5.1: + version "3.6.0" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470" + integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw== + +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +karma-chrome-launcher@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz#805a586799a4d05f4e54f72a204979f3f3066738" + integrity sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg== + dependencies: + which "^1.2.1" + +karma-mocha@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-2.0.1.tgz#4b0254a18dfee71bdbe6188d9a6861bf86b0cd7d" + integrity sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ== + dependencies: + minimist "^1.2.3" + +karma-sourcemap-loader@0.3.8: + version "0.3.8" + resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.8.tgz#d4bae72fb7a8397328a62b75013d2df937bdcf9c" + integrity sha512-zorxyAakYZuBcHRJE+vbrK2o2JXLFWK8VVjiT/6P+ltLBUGUvqTEkUiQ119MGdOrK7mrmxXHZF1/pfT6GgIZ6g== + dependencies: + graceful-fs "^4.1.2" + +karma-webpack@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.0.tgz#2a2c7b80163fe7ffd1010f83f5507f95ef39f840" + integrity sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA== + dependencies: + glob "^7.1.3" + minimatch "^3.0.4" + webpack-merge "^4.1.5" + +karma@6.3.4: + version "6.3.4" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.4.tgz#359899d3aab3d6b918ea0f57046fd2a6b68565e6" + integrity sha512-hbhRogUYIulfkBTZT7xoPrCYhRBnBoqbbL4fszWD0ReFGUxU+LYBr3dwKdAluaDQ/ynT9/7C+Lf7pPNW4gSx4Q== + dependencies: + body-parser "^1.19.0" + braces "^3.0.2" + chokidar "^3.5.1" + colors "^1.4.0" + connect "^3.7.0" + di "^0.0.1" + dom-serialize "^2.2.1" + glob "^7.1.7" + graceful-fs "^4.2.6" + http-proxy "^1.18.1" + isbinaryfile "^4.0.8" + lodash "^4.17.21" + log4js "^6.3.0" + mime "^2.5.2" + minimatch "^3.0.4" + qjobs "^1.2.0" + range-parser "^1.2.1" + rimraf "^3.0.2" + socket.io "^3.1.0" + source-map "^0.6.1" + tmp "^0.2.1" + ua-parser-js "^0.7.28" + yargs "^16.1.1" + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +kvision-assets@^5.0.7: + version "5.0.7" + resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-5.0.7.tgz#e6dc3e28a2d244b4c89318b060d3e7e337c15495" + integrity sha512-szoL8ixFRTivLkbnmkWFjGJMk3bsUW/loUS5QfWThPwFnyFEw8ht3eBUrJ0V51Rn/WaJbVoPvY4SfIaiNu13bg== + +leaflet@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.7.1.tgz#10d684916edfe1bf41d688a3b97127c0322a2a19" + integrity sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw== + +loader-runner@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" + integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log4js@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.3.0.tgz#10dfafbb434351a3e30277a00b9879446f715bcb" + integrity sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw== + dependencies: + date-format "^3.0.0" + debug "^4.1.1" + flatted "^2.0.1" + rfdc "^1.1.4" + streamroller "^2.2.4" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +memfs@^3.2.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.0.tgz#8bc12062b973be6b295d4340595736a656f0a257" + integrity sha512-o/RfP0J1d03YwsAxyHxAYs2kyJp55AFkMazlFAZFR2I2IXkxiUTXRabJ6RmNNCQ83LAD2jy52Khj0m3OffpNdA== + dependencies: + fs-monkey "1.0.3" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +mime-db@1.51.0, "mime-db@>= 1.43.0 < 2": + version "1.51.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" + integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== + +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24: + version "2.1.34" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" + integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== + dependencies: + mime-db "1.51.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.5.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@3.0.4, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mkdirp@^0.5.5: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mocha@9.1.2: + version "9.1.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.2.tgz#93f53175b0f0dc4014bd2d612218fccfcf3534d3" + integrity sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.2" + debug "4.3.2" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.1.7" + growl "1.10.5" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "3.0.4" + ms "2.1.3" + nanoid "3.1.25" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + workerpool "6.1.5" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + +nanoid@3.1.25: + version "3.1.25" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" + integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== + +nanoid@^3.1.30: + version "3.1.30" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362" + integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ== + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +node-forge@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" + integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== + +node-releases@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" + integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +object-assign@^4: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@^8.0.9: + version "8.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" + integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-retry@^4.5.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c" + integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA== + dependencies: + "@types/retry" "^0.12.0" + retry "^0.13.1" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +"parse5@5 - 6": + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pofile@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.0.11.tgz#35aff58c17491d127a07336d5522ebc9df57c954" + integrity sha512-Vy9eH1dRD9wHjYt/QqXcTz+RnX/zg53xK+KljFSX30PvdDMb2z+c6uDUeblUGqqJgz3QFsdlA0IJvHziPmWtQg== + +portfinder@^1.0.28: + version "1.0.28" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" + integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.5" + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.8" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.8.tgz#f023ed7a9ea736cd7ef70342996e8e78645a7914" + integrity sha512-D5PG53d209Z1Uhcc0qAZ5U3t5HagH3cxu+WLZ22jt3gLUpXM4eXXfiO14jiDWST3NNooX/E8wISfOhZ9eIjGTQ== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.2.15: + version "8.4.5" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95" + integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg== + dependencies: + nanoid "^3.1.30" + picocolors "^1.0.0" + source-map-js "^1.0.1" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qjobs@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + +qs@6.9.6: + version "6.9.6" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" + integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32" + integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ== + dependencies: + bytes "3.1.1" + http-errors "1.8.1" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readable-stream@^2.0.1: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" + integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== + dependencies: + resolve "^1.9.0" + +redux-thunk@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.1.tgz#0dd8042cf47868f4b29699941de03c9301a75714" + integrity sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q== + +redux@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.2.tgz#140f35426d99bb4729af760afcf79eaaac407104" + integrity sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw== + dependencies: + "@babel/runtime" "^7.9.2" + +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + +regexp.prototype.flags@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" + integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve@^1.9.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rfdc@^1.1.4: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +schema-utils@^3.1.0, schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" + integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.8.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.0.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + +selfsigned@^1.10.11: + version "1.10.11" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.11.tgz#24929cd906fe0f44b6d01fb23999a739537acbe9" + integrity sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA== + dependencies: + node-forge "^0.10.0" + +semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +send@0.17.2: + version "0.17.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" + integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "1.8.1" + mime "1.6.0" + ms "2.1.3" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serialize-javascript@6.0.0, serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.14.2: + version "1.14.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" + integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.2" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.3: + version "3.0.6" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" + integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +snabbdom@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.2.0.tgz#8ea6b2517739a7d9ca82df3f181d052adf1ca5ad" + integrity sha512-UWyfm8WbaFmbmYLC33pe5fawBfExhynkMDoZqQ8ehlHDwkxrgIOpWhKf5PaacLUW1n+Uwu5N5HND6mESU7cMlw== + +socket.io-adapter@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz#edc5dc36602f2985918d631c1399215e97a1b527" + integrity sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg== + +socket.io-parser@~4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0" + integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g== + dependencies: + "@types/component-emitter" "^1.2.10" + component-emitter "~1.3.0" + debug "~4.3.1" + +socket.io@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-3.1.2.tgz#06e27caa1c4fc9617547acfbb5da9bc1747da39a" + integrity sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw== + dependencies: + "@types/cookie" "^0.4.0" + "@types/cors" "^2.8.8" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.1" + engine.io "~4.1.0" + socket.io-adapter "~2.1.0" + socket.io-parser "~4.0.3" + +sockjs@^0.3.21: + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + +source-map-js@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" + integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== + +source-map-js@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf" + integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA== + +source-map-loader@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.0.tgz#f2a04ee2808ad01c774dea6b7d2639839f3b3049" + integrity sha512-GKGWqWvYr04M7tn8dryIWvb0s8YM41z82iQv01yBtIylgxax0CwvSy6gc2Y02iuXwEfGWRlMicH0nvms9UZphw== + dependencies: + abab "^2.0.5" + iconv-lite "^0.6.2" + source-map-js "^0.6.2" + +source-map-support@0.5.20: + version "0.5.20" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" + integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +split.js@^1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/split.js/-/split.js-1.6.4.tgz#13d47cba53382adef230a53294ce5dacb2a2f2e1" + integrity sha512-kYmQZprRJrF1IOjg/E+gdBEsKFv5kbgUE6RJVJZvrIzTOK/IHzKSqIeiJnWs7IP5D9TnpTQ2CbanuDuIWcyDUQ== + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +streamroller@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-2.2.4.tgz#c198ced42db94086a6193608187ce80a5f2b0e53" + integrity sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ== + dependencies: + date-format "^2.1.0" + debug "^4.1.1" + fs-extra "^8.1.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" + integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== + dependencies: + ansi-regex "^6.0.1" + +strip-comments@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" + integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +style-loader@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" + integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== + +supports-color@8.1.1, supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +terser-webpack-plugin@^5.1.3: + version "5.3.0" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz#21641326486ecf91d8054161c816e464435bae9f" + integrity sha512-LPIisi3Ol4chwAaPP8toUJ3L4qCM1G0wao7L3qNv57Drezxj6+VEyySpPw4B1HSO2Eg/hDY/MNF5XihCAoqnsQ== + dependencies: + jest-worker "^27.4.1" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + source-map "^0.6.1" + terser "^5.7.2" + +terser@^5.7.2: + version "5.10.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc" + integrity sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA== + dependencies: + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.20" + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +"typescript@2 - 4": + version "4.5.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" + integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== + +typescript@3.9.5: + version "3.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" + integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== + +ua-parser-js@^0.7.28: + version "0.7.31" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" + integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +void-elements@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" + integrity sha1-YU9/v42AHwu18GYfWy9XhXUOTwk= + +void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= + +watchpack@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25" + integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webpack-cli@4.9.1: + version "4.9.1" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3" + integrity sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.1.0" + "@webpack-cli/info" "^1.4.0" + "@webpack-cli/serve" "^1.6.0" + colorette "^2.0.14" + commander "^7.0.0" + execa "^5.0.0" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + webpack-merge "^5.7.3" + +webpack-dev-middleware@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.0.tgz#8fc02dba6e72e1d373eca361623d84610f27be7c" + integrity sha512-MouJz+rXAm9B1OTOYaJnn6rtD/lWZPy2ufQCH3BPs8Rloh/Du6Jze4p7AeLYHkVi0giJnYLaSGDC7S+GM9arhg== + dependencies: + colorette "^2.0.10" + memfs "^3.2.2" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@4.7.2: + version "4.7.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.7.2.tgz#324b79046491f2cf0b9d9e275381198c8246b380" + integrity sha512-s6yEOSfPpB6g1T2+C5ZOUt5cQOMhjI98IVmmvMNb5cdiqHoxSUfACISHqU/wZy+q4ar/A9jW0pbNj7sa50XRVA== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/serve-index" "^1.9.1" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.2.2" + ansi-html-community "^0.0.8" + bonjour "^3.5.0" + chokidar "^3.5.2" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + default-gateway "^6.0.3" + del "^6.0.0" + express "^4.17.1" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.0" + ipaddr.js "^2.0.1" + open "^8.0.9" + p-retry "^4.5.0" + portfinder "^1.0.28" + schema-utils "^4.0.0" + selfsigned "^1.10.11" + serve-index "^1.9.1" + sockjs "^0.3.21" + spdy "^4.0.2" + strip-ansi "^7.0.0" + webpack-dev-middleware "^5.3.0" + ws "^8.1.0" + +webpack-merge@^4.1.5: + version "4.2.2" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" + integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== + dependencies: + lodash "^4.17.15" + +webpack-merge@^5.7.3: + version "5.8.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" + integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + +webpack-sources@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.2.tgz#d88e3741833efec57c4c789b6010db9977545260" + integrity sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw== + +webpack@5.65.0: + version "5.65.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.65.0.tgz#ed2891d9145ba1f0d318e4ea4f89c3fa18e6f9be" + integrity sha512-Q5or2o6EKs7+oKmJo7LaqZaMOlDWQse9Tm5l1WAfU/ujLGN5Pb0SqGeVkN/4bpPmEqEP5RnVhiqsOtWtUVwGRw== + dependencies: + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.50" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.4.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.8.3" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.4" + json-parse-better-errors "^1.0.2" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.3.1" + webpack-sources "^3.2.2" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +which@2.0.2, which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +which@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wildcard@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" + integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== + +workerpool@6.1.5: + version "6.1.5" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" + integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@^8.1.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.4.0.tgz#f05e982a0a88c604080e8581576e2a063802bed6" + integrity sha512-IHVsKe2pjajSUIl4KYMQOdlyliovpEPquKkqbwswulszzI7r0SfQrxnXdWAEqOlDCLrVSJzo+O1hAwdog2sKSQ== + +ws@~7.4.2: + version "7.4.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0, yargs@^16.1.1: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/build.gradle.kts b/build.gradle.kts index 2b60f01..dc3d0f9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.2.0" +version = "0.2.1" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index e30a5b3..64e6fc4 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.0", + "version": "0.2.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index e708d32..68acb70 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.0", + "version": "0.2.1", "private": true, "scripts": { "build": "tstl", diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt index bd83abe..b09d924 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt @@ -2,7 +2,7 @@ package dev.adamko.kafkatorio.webmap import dev.adamko.kafkatorio.events.schema.Colour import dev.adamko.kafkatorio.events.schema.PlayerData -import externals.leaflet.geo.LatLng +import io.kvision.maps.externals.leaflet.geo.LatLng import io.kvision.maps.Maps import kotlin.math.roundToInt diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index b4233f1..3bf8615 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -1,8 +1,7 @@ package dev.adamko.kafkatorio.webmap -import externals.leaflet.geo.CRS -import externals.leaflet.geo.LatLng -import io.kvision.maps.DefaultTileLayers +import io.kvision.maps.externals.leaflet.geo.CRS +import io.kvision.maps.externals.leaflet.geo.LatLng import io.kvision.maps.Maps import io.kvision.utils.px From 77429f35bf24793a104d5e58747bcbb53d9b5829 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 11:02:05 +0100 Subject: [PATCH 127/629] disable repo warning for buildSrc --- buildSrc/repositories.settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/repositories.settings.gradle.kts b/buildSrc/repositories.settings.gradle.kts index d4252d6..670ad93 100644 --- a/buildSrc/repositories.settings.gradle.kts +++ b/buildSrc/repositories.settings.gradle.kts @@ -7,7 +7,7 @@ dependencyResolutionManagement { // Cannot use 'FAIL_ON_PROJECT_REPOS' because // - the 'gradle-guides-plugin' adds a repo (which it should not do) // - the 'kotlin-gradle-plugin' adds a repo (and removes it afterwards) to download NodeJS - repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) +// repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) repositories { mavenCentral() From e20f51f44630df5fcd1b1515e70c231ab993d073 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 11:04:15 +0100 Subject: [PATCH 128/629] add project version to docker env --- .../kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts | 1 + modules/infra-factorio-server/src/.env | 1 + modules/infra-kafka-cluster/src/.env | 1 + modules/infra-kafka-pipe/src/.env | 1 + modules/infra-kafka-pipe/src/docker-compose.yml | 1 + modules/infra-kafka-pipe/src/kafka-pipe.sh | 1 + 6 files changed, 6 insertions(+) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts index b15f05d..a565841 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts @@ -44,6 +44,7 @@ val dockerEnv by tasks.registering(WriteProperties::class) { setOutputFile(dockerSrcDir.file(".env")) properties( "COMPOSE_PROJECT_NAME" to dockerComposeProjectName, + "KAFKATORIO_VERSION" to project.version, ) } diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index 9880131..97202e7 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,3 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio FACTORIO_VERSION=1.1.50 +KAFKATORIO_VERSION=0.2.1 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index 6f7d99f..cac708d 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,2 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio +KAFKATORIO_VERSION=0.2.1 diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index 6f7d99f..cac708d 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,2 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio +KAFKATORIO_VERSION=0.2.1 diff --git a/modules/infra-kafka-pipe/src/docker-compose.yml b/modules/infra-kafka-pipe/src/docker-compose.yml index 976eb47..33bfde1 100644 --- a/modules/infra-kafka-pipe/src/docker-compose.yml +++ b/modules/infra-kafka-pipe/src/docker-compose.yml @@ -13,6 +13,7 @@ services: - "kafkatorio-nw" environment: FACTORIO_SERVER_CONTAINER_NAME: "factorio-server" + KAFKATORIO_VERSION: $KAFKATORIO_VERSION KAFKA_HOST: "kafka:29092" volumes: # Windows (requires privileged/root) diff --git a/modules/infra-kafka-pipe/src/kafka-pipe.sh b/modules/infra-kafka-pipe/src/kafka-pipe.sh index a8a8ea9..b155266 100644 --- a/modules/infra-kafka-pipe/src/kafka-pipe.sh +++ b/modules/infra-kafka-pipe/src/kafka-pipe.sh @@ -2,6 +2,7 @@ # Pipe Docker logs from a Factorio server to a Kafka topic +echo "Kafkatorio-Pipe version $KAFKATORIO_VERSION" echo "Piping logs from $FACTORIO_SERVER_CONTAINER_NAME to $KAFKA_HOST" trap endProcess SIGINT From 101e48c59384cee6a3e7263fcaf25383ccc74133 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 11:04:42 +0100 Subject: [PATCH 129/629] hook build kafka-pipe task into 'assemble' --- modules/infra-kafka-pipe/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index 89066a3..d3d3fb0 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -25,4 +25,4 @@ val dockerBuildKafkaPipe by tasks.registering(Exec::class) { workingDir = dockerSrcDir.asFile commandLine = parseSpaceSeparatedArgs(""" docker-compose build kafka-pipe """) } -//tasks.assemble { dependsOn(dockerBuildKafkaPipe) } +tasks.assemble { dependsOn(dockerBuildKafkaPipe) } From 5a406358d850251aad6f7d996b52b71369d5dc99 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 11:05:30 +0100 Subject: [PATCH 130/629] renaming events server, to match project and so Gradle task.run works --- modules/events-server/build.gradle.kts | 2 +- .../{FactorioEventsTopology.kt => KafkatorioTopology.kt} | 2 +- .../kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/{FactorioEventsTopology.kt => KafkatorioTopology.kt} (98%) diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index ed4964e..f1e7b8c 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -38,7 +38,7 @@ dependencies { } application { - mainClass.set("dev.adamko.factorioevents.processor.mainKt") + mainClass.set("dev.adamko.kafkatorio.processor.EventProcessorKt") } tasks.withType { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt similarity index 98% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 139bf1b..523b291 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/FactorioEventsTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -13,7 +13,7 @@ import org.apache.kafka.streams.TopologyDescription import org.apache.kafka.streams.kstream.Consumed import org.apache.kafka.streams.kstream.Produced -class FactorioEventsTopology( +class KafkatorioTopology( private val websocketServer: WebsocketServer, private val builder: StreamsBuilder = StreamsBuilder(), ) { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt index 0011293..499cb63 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -12,7 +12,7 @@ fun main() = runBlocking { val wsServer = WebsocketServer() - val topology = FactorioEventsTopology(wsServer) + val topology = KafkatorioTopology(wsServer) topology.build() wsServer.build().asServer(Undertow(9073)).start().block() From f16e7405f637e09e1420a5e73a255ad278ae78a6 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 11:05:52 +0100 Subject: [PATCH 131/629] update json serde tests --- .../events/schema/FactorioEventTest.kt | 134 ++++++++++-------- 1 file changed, 78 insertions(+), 56 deletions(-) diff --git a/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt index 64b4add..f5db169 100644 --- a/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt +++ b/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt @@ -12,28 +12,40 @@ class FactorioEventTest : BehaviorSpec({ @Language("JSON") val json = """ - { - "data": { - "object_name": "LuaPlayer", - "name": "fredthedeadhead", - "character_unit_number": 1, - "associated_characters_unit_numbers": {}, - "position": { - "x": -3.5703125, - "y": 29.75, - "type": "MAP" - }, - "last_online": 123 - }, - "event_type": "on_player_joined_game", - "mod_version": "0.0.4", - "factorio_version": "1.1.48", - "tick": 1278458 - } + { + "data": { + "objectName": "LuaPlayer", + "name": "fredthedeadhead", + "characterUnitNumber": 1, + "associatedCharactersUnitNumbers": {}, + "position": { + "type": "MAP", + "x": 30.65625, + "y": 84.07421875 + }, + "colour": { + "red": 0.869000017642974853515625, + "green": 0.5, + "blue": 0.12999999523162841796875, + "alpha": 0.5 + }, + "chatColour": { + "red": 1, + "green": 0.62999999523162841796875, + "blue": 0.259000003337860107421875, + "alpha": 1 + }, + "lastOnline": 2287061 + }, + "packetType": "EVENT", + "eventType": "on_player_joined_game", + "modVersion": "0.2.1", + "tick": 2287072 + } """.trimIndent() Then("parse") { - val actual: FactorioEvent = jsonMapper.decodeFromString(json) + val actual: KafkatorioPacket = jsonMapper.decodeFromString(KafkatorioPacket.serializer(), json) val expected = FactorioEvent( data = PlayerData( @@ -41,22 +53,32 @@ class FactorioEventTest : BehaviorSpec({ characterUnitNumber = 1u, associatedCharactersUnitNumbers = emptyList(), position = PositionData( - x = -3.5703125, - y = 29.75, type = PositionType.MAP, + x = 30.65625, + y = 84.07421875, ), - colour = Colour(), - chatColour = Colour(), - lastOnline = 123u + colour = Colour( + red = 0.869000017642974853515625f, + green = 0.5f, + blue = 0.12999999523162841796875f, + alpha = 0.5f + ), + chatColour = Colour( + red = 1f, + green = 0.62999999523162841796875f, + blue = 0.259000003337860107421875f, + alpha = 1f + ), + lastOnline = 2287061u ), eventType = "on_player_joined_game", - modVersion = "0.0.4", - tick = 1278458u + modVersion = "0.2.1", + tick = 2287072u ) actual shouldBeEqualToComparingFields expected - expected.data.objectName shouldBe "LuaPlayer" + expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaPlayer } } @@ -65,64 +87,64 @@ class FactorioEventTest : BehaviorSpec({ val json = """ { "data": { - "object_name": "LuaSurface", + "objectName": "LuaSurface", "name": "nauvis", "index": 1, - "daytime": 0.8390800000511436707029133685864508152008056640625 + "daytime": 0.749480000092057618843455202295444905757904052734375 }, - "event_type": "on_tick", - "mod_version": "0.0.4", - "factorio_version": "1.1.48", - "tick": 1278480 + "packetType": "EVENT", + "eventType": "on_tick", + "modVersion": "0.2.1", + "tick": 2301240 } """.trimIndent() Then("parse") { - val actual: FactorioEvent = jsonMapper.decodeFromString(json) + val actual: KafkatorioPacket = jsonMapper.decodeFromString(json) val expected = FactorioEvent( data = SurfaceData( name = "nauvis", index = 1u, - daytime = 0.8390800000511436707029133685864508152008056640625 + daytime = 0.749480000092057618843455202295444905757904052734375 ), eventType = "on_tick", - modVersion = "0.0.4", - tick = 1278480u + modVersion = "0.2.1", + tick = 2301240u ) actual shouldBeEqualToComparingFields expected - expected.data.objectName shouldBe "LuaSurface" + expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaSurface } } - Given("json entity") { + Given("LuaEntity on_player_changed_position") { @Language("JSON") val json = """ { "data": { - "object_name": "LuaEntity", + "objectName": "LuaEntity", "name": "character", "type": "character", "active": true, "health": 250, - "health_ratio": 1, - "surface_index": 1, - "unit_number": 1, + "healthRatio": 1, + "surfaceIndex": 1, + "unitNumber": 1, "position": { - "x": -0.25, - "y": 30.09375, - "type": "MAP" + "type": "MAP", + "x": 37.859375, + "y": 81.14453125 } }, - "event_type": "on_player_changed_position", - "mod_version": "0.0.6", - "factorio_version": "1.1.48", - "tick": 1384507 + "packetType": "EVENT", + "eventType": "on_player_changed_position", + "modVersion": "0.2.1", + "tick": 2301231 } """.trimIndent() Then("parse") { - val actual: FactorioEvent = jsonMapper.decodeFromString(json) + val actual: KafkatorioPacket = jsonMapper.decodeFromString(json) val expected = FactorioEvent( data = EntityData( @@ -135,19 +157,19 @@ class FactorioEventTest : BehaviorSpec({ unitNumber = 1u, playerIndex = null, position = PositionData( - x = -0.25, - y = 30.09375, + x = 37.859375, + y = 81.14453125, type = PositionType.MAP, ) ), eventType = "on_player_changed_position", - modVersion = "0.0.6", - tick = 1384507u + modVersion = "0.2.1", + tick = 2301231u ) actual shouldBeEqualToComparingFields expected - expected.data.objectName shouldBe "LuaEntity" + expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaEntity } } From e5feabf7eba7acbfd7ce894d3dbf0cdde5e4e98c Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 11:06:15 +0100 Subject: [PATCH 132/629] make jvm schema tests run --- modules/events-schema/build.gradle.kts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index b19af7d..a22817b 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -4,6 +4,7 @@ import dev.adamko.kafkatorio.gradle.typescriptAttributes plugins { kotlin("multiplatform") kotlin("plugin.serialization") + id("io.kotest.multiplatform") version "5.0.2" distribution } @@ -12,7 +13,11 @@ kotlin { binaries.executable() nodejs() } - jvm() + jvm { + testRuns["test"].executionTask.configure { + useJUnitPlatform() + } + } @Suppress("UnstableApiUsage") // enforcedPlatform is incubating sourceSets { @@ -22,7 +27,6 @@ kotlin { optIn("kotlin.RequiresOptIn") optIn("kotlin.ExperimentalStdlibApi") optIn("kotlin.time.ExperimentalTime") - optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") optIn("kotlinx.serialization.ExperimentalSerializationApi") optIn("kotlin.js.ExperimentalJsExport") } @@ -35,7 +39,6 @@ kotlin { implementation(project.dependencies.platform(libs.kotlinx.serialization.bom)) implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.json) - } } From 2208c916528c091198d5eb4c5b7efeb92bcadbba Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 12:37:26 +0100 Subject: [PATCH 133/629] fix polymorphic serialization, and update the names of some schema objects --- .../kafkatorio-schema/object-data.d.ts | 8 ++-- .../main/typescript/main/events/converters.ts | 2 +- .../main/typescript/main/events/handlers.ts | 6 +-- .../events/schema/factorioConfiguration.kt | 4 +- .../events/schema/factorioEvents.kt | 47 ++++++++++++++++++- .../events/schema/factorioLuaObjects.kt | 22 ++++----- .../adamko/kafkatorio/events/schema/json.kt | 7 +-- .../events/schema/kafkatorioPacket.kt | 44 +++++++++++------ .../events/schema/FactorioEventTest.kt | 6 +-- .../dev/adamko/kafkatorio/processor/serdes.kt | 6 +-- .../adamko/kafkatorio/webmap/websockets.kt | 12 ++--- 11 files changed, 109 insertions(+), 55 deletions(-) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts index 27d0907..30d82f0 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts @@ -1,6 +1,6 @@ // Generated by TypeScriptGenerator - do not edit this file manually -type ObjectName = "LuaPlayer" | "LuaEntity" | "LuaSurface" | "FactorioMapChunk" | "LuaTile" | "ConsoleChatMessage"; +type ObjectName = "LuaPlayer" | "LuaEntity" | "LuaSurface" | "MapChunk" | "LuaTile" | "ConsoleChatMessage"; interface FactorioObjectData { objectName: ObjectName; @@ -45,16 +45,16 @@ interface SurfaceData extends FactorioObjectData { objectName: ObjectName; } -interface FactorioMapTile extends FactorioObjectData { +interface MapTile extends FactorioObjectData { objectName: ObjectName; position: PositionData; prototypeName: string; surfaceIndex: int; } -interface FactorioMapChunk extends FactorioObjectData { +interface MapChunk extends FactorioObjectData { objectName: ObjectName; - tiles: FactorioMapTile[]; + tiles: MapTile[]; } interface ConsoleChatMessage extends FactorioObjectData { diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index 104df2a..0bb3b53 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -83,7 +83,7 @@ export namespace Converters { } } - export function convertTile(tile: LuaTile): FactorioMapTile { + export function convertTile(tile: LuaTile): MapTile { return { objectName: tile.object_name, diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index 2700139..f8e085f 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -70,12 +70,12 @@ export function handleChunkUpdate( } ) ?? [] - let convertedTiles: FactorioMapTile[] = tiles.map((tile: LuaTile) => { + let convertedTiles: MapTile[] = tiles.map((tile: LuaTile) => { return Converters.convertTile(tile) }) - let mapChunk: FactorioMapChunk = { - objectName: "FactorioMapChunk", + let mapChunk: MapChunk = { + objectName: "MapChunk", tiles: convertedTiles, } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt index ad8844f..ee45182 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt @@ -1,17 +1,17 @@ package dev.adamko.kafkatorio.events.schema +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient @Serializable +@SerialName("CONFIG") data class FactorioConfigurationUpdate( override val modVersion: String, val factorioData: FactorioGameDataUpdate, val allMods: List, val prototypes: List, ) : KafkatorioPacket() { - @Transient override val packetType = PacketType.CONFIG } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index aaaf2a1..badb888 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -1,11 +1,20 @@ package dev.adamko.kafkatorio.events.schema +import dev.adamko.kafkatorio.events.schema.FactorioObjectData.ObjectName +import kotlinx.serialization.DeserializationStrategy +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient +import kotlinx.serialization.json.JsonContentPolymorphicSerializer +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.contentOrNull +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive +import kotlinx.serialization.modules.SerializersModule @Serializable +@SerialName("EVENT") data class FactorioEvent( override val modVersion: String, /** the initial Factorio event (`defines.events`) trigger */ @@ -14,6 +23,40 @@ data class FactorioEvent( val tick: UInt, val data: T, ) : KafkatorioPacket() { - @Transient override val packetType: PacketType = PacketType.EVENT + + companion object { + val kxsModule = SerializersModule { + contextual(FactorioEvent::class) { types -> serializer(types[0]) } + } + } + +} + + +object FactorioEventSerializer : JsonContentPolymorphicSerializer>( + FactorioEvent::class +) { + + override fun selectDeserializer(element: JsonElement): DeserializationStrategy> { + + val objectName: ObjectName? = element + .jsonObject[FactorioEvent<*>::data.name] + ?.jsonObject + ?.get(FactorioObjectData.discriminatorKey) + ?.jsonPrimitive + ?.contentOrNull + ?.let(ObjectName::valueOf) + + val sub = when (objectName) { + ObjectName.LuaPlayer -> PlayerData.serializer() + ObjectName.LuaEntity -> EntityData.serializer() + ObjectName.LuaSurface -> SurfaceData.serializer() + ObjectName.MapChunk -> MapChunk.serializer() + ObjectName.LuaTile -> MapTile.serializer() + ObjectName.ConsoleChatMessage -> ConsoleChatMessage.serializer() + null -> throw IllegalStateException("unknown type $objectName") + } + return FactorioEvent.serializer(sub) + } } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt index 7d5d749..f1ab819 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -2,7 +2,6 @@ package dev.adamko.kafkatorio.events.schema import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient import kotlinx.serialization.json.JsonClassDiscriminator @Serializable @@ -33,7 +32,7 @@ sealed class FactorioObjectData { LuaPlayer, LuaEntity, LuaSurface, - FactorioMapChunk, + MapChunk, LuaTile, ConsoleChatMessage, } @@ -57,7 +56,6 @@ data class PlayerData( val chatColour: Colour, val lastOnline: UInt, ) : FactorioObjectData() { - @Transient override val objectName = ObjectName.LuaPlayer } @@ -74,7 +72,6 @@ data class EntityData( val unitNumber: UInt? = null, val playerIndex: UInt? = null, ) : FactorioObjectData() { - @Transient override val objectName = ObjectName.LuaEntity } @@ -85,36 +82,33 @@ data class SurfaceData( val index: UInt, val name: String, ) : FactorioObjectData() { - @Transient override val objectName = ObjectName.LuaSurface } -/** Quasi-object. This isn't a Factorio Lua type, but a helpful collection of [FactorioMapTile]s */ +/** Quasi-object. This isn't a Factorio Lua type, but a helpful collection of [MapTile]s */ @Serializable -@SerialName("FactorioMapChunk") -data class FactorioMapChunk( - val tiles: List, +@SerialName("MapChunk") +data class MapChunk( + val tiles: List, ) : FactorioObjectData() { - @Transient - override val objectName = ObjectName.FactorioMapChunk + override val objectName = ObjectName.MapChunk } @Serializable @SerialName("LuaTile") -data class FactorioMapTile( +data class MapTile( val prototypeName: String, val position: PositionData, val surfaceIndex: Int, ) : FactorioObjectData() { - @Transient override val objectName = ObjectName.LuaTile } @Serializable +@SerialName("ConsoleChatMessage") data class ConsoleChatMessage( val authorPlayerIndex: UInt?, val content: String, ) : FactorioObjectData() { - @Transient override val objectName = ObjectName.ConsoleChatMessage } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt index d99ec7e..78f26d5 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt @@ -9,7 +9,6 @@ import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonTransformingSerializer import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonObject -import kotlinx.serialization.modules.SerializersModule /** Factorio outputs lists as Json objects - this serializer converts an object back to a list. */ @@ -27,8 +26,10 @@ internal class ListAsObjectSerializer(dataSerializer: KSerializer) : ) } -internal val jsonMapper = Json { +val jsonMapperKafkatorio = Json { prettyPrint = true prettyPrintIndent = " " - serializersModule = SerializersModule { } + serializersModule = FactorioEvent.kxsModule +// serializersModule = KafkatorioPacket.kxsModule + FactorioEvent.kxsModule +// serializersModule = SerializersModule { } } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt index fa6d789..702542f 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt @@ -1,29 +1,45 @@ package dev.adamko.kafkatorio.events.schema; +import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.Serializable -import kotlinx.serialization.json.JsonClassDiscriminator +import kotlinx.serialization.json.JsonContentPolymorphicSerializer +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.contentOrNull +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive -@Serializable -@JsonClassDiscriminator("packetType") +@Serializable(with = KafkatorioPacketSerializer::class) sealed class KafkatorioPacket { /** Schema versioning */ abstract val modVersion: String abstract val packetType: PacketType enum class PacketType { - EVENT, CONFIG, + EVENT, + CONFIG, } } -//@Serializable -//@JsonClassDiscriminator(KafkatorioPacketData.discriminatorKey) -//sealed class KafkatorioPacketData( -// @SerialName(discriminatorKey) -// val dataType: PacketDataType -//) { -// companion object { -// const val discriminatorKey: String = "dataType" -// } -//} +object KafkatorioPacketSerializer : JsonContentPolymorphicSerializer( + KafkatorioPacket::class +) { + private const val key = "packetType" + + override fun selectDeserializer(element: JsonElement): DeserializationStrategy { + + val type = element + .jsonObject[key] + ?.jsonPrimitive + ?.contentOrNull + ?.let(KafkatorioPacket.PacketType::valueOf) + + return when (type) { + KafkatorioPacket.PacketType.EVENT -> FactorioEventSerializer + KafkatorioPacket.PacketType.CONFIG -> FactorioConfigurationUpdate.serializer() + else -> + throw Exception("Unknown Packet: key '$key' ") + } + } +} diff --git a/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt index f5db169..04625ed 100644 --- a/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt +++ b/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt @@ -45,7 +45,7 @@ class FactorioEventTest : BehaviorSpec({ """.trimIndent() Then("parse") { - val actual: KafkatorioPacket = jsonMapper.decodeFromString(KafkatorioPacket.serializer(), json) + val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) val expected = FactorioEvent( data = PlayerData( @@ -99,7 +99,7 @@ class FactorioEventTest : BehaviorSpec({ } """.trimIndent() Then("parse") { - val actual: KafkatorioPacket = jsonMapper.decodeFromString(json) + val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) val expected = FactorioEvent( data = SurfaceData( @@ -144,7 +144,7 @@ class FactorioEventTest : BehaviorSpec({ } """.trimIndent() Then("parse") { - val actual: KafkatorioPacket = jsonMapper.decodeFromString(json) + val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) val expected = FactorioEvent( data = EntityData( diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt index 3138db1..88c3666 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt @@ -1,10 +1,10 @@ package dev.adamko.kafkatorio.processor import dev.adamko.kafkatorio.events.schema.KafkatorioPacket +import dev.adamko.kafkatorio.events.schema.jsonMapperKafkatorio import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json -import kotlinx.serialization.modules.SerializersModule import org.apache.kafka.common.serialization.Deserializer import org.apache.kafka.common.serialization.Serde import org.apache.kafka.common.serialization.Serializer @@ -26,7 +26,7 @@ object KafkatorioPacketSerde : Serde { val jsonMapper = Json { prettyPrint = true prettyPrintIndent = " " - serializersModule = SerializersModule { } + serializersModule = jsonMapperKafkatorio.serializersModule } object KXS : ConfigurableKotlinxSerialization({ @@ -34,5 +34,5 @@ object KXS : ConfigurableKotlinxSerialization({ prettyPrint = true prettyPrintIndent = " " asConfigurable().withStandardMappings().done() - serializersModule = SerializersModule { } + serializersModule = jsonMapperKafkatorio.serializersModule }) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt index 0b05406..ca59674 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -4,8 +4,8 @@ import dev.adamko.kafkatorio.events.schema.ConsoleChatMessage import dev.adamko.kafkatorio.events.schema.EntityData import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate import dev.adamko.kafkatorio.events.schema.FactorioEvent -import dev.adamko.kafkatorio.events.schema.FactorioMapChunk -import dev.adamko.kafkatorio.events.schema.FactorioMapTile +import dev.adamko.kafkatorio.events.schema.MapChunk +import dev.adamko.kafkatorio.events.schema.MapTile import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.events.schema.PlayerData import dev.adamko.kafkatorio.events.schema.SurfaceData @@ -42,10 +42,10 @@ class WebsocketService( is PlayerData -> reduxStore.dispatch(FactorioUpdate.PlayerUpdate(event, eventData)) is ConsoleChatMessage -> {} - is EntityData -> {} - is FactorioMapChunk -> {} - is FactorioMapTile -> {} - is SurfaceData -> {} + is EntityData -> {} + is MapChunk -> {} + is MapTile -> {} + is SurfaceData -> {} } } is FactorioConfigurationUpdate -> {} From 1be9841d8ba1a7fdc0510bad3731c22bb585e678 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 12:37:41 +0100 Subject: [PATCH 134/629] try fixing docker build so it doesn't run every time --- .../dev/adamko/kafkatorio/infra/docker-compose.gradle.kts | 2 +- modules/infra-kafka-pipe/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts index a565841..7e1152e 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts @@ -19,7 +19,7 @@ val dockerUp by tasks.registering(Exec::class) { logging.captureStandardOutput(LogLevel.LIFECYCLE) workingDir = dockerSrcDir.asFile - commandLine = parseSpaceSeparatedArgs(""" docker-compose up -d """) + commandLine = parseSpaceSeparatedArgs(""" docker-compose up --build -d """) } val dockerDown by tasks.registering(Exec::class) { diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index d3d3fb0..89066a3 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -25,4 +25,4 @@ val dockerBuildKafkaPipe by tasks.registering(Exec::class) { workingDir = dockerSrcDir.asFile commandLine = parseSpaceSeparatedArgs(""" docker-compose build kafka-pipe """) } -tasks.assemble { dependsOn(dockerBuildKafkaPipe) } +//tasks.assemble { dependsOn(dockerBuildKafkaPipe) } From beb73d158484534e9fae6a87a7fa8e96491d5d4a Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 14:01:48 +0100 Subject: [PATCH 135/629] - make tests multi-platform - fix polymorphism finally??? --- .kotlin-js-store/yarn.lock | 154 +++++++++++++- modules/events-schema/build.gradle.kts | 2 + .../events/schema/factorioConfiguration.kt | 8 +- .../events/schema/factorioEvents.kt | 82 ++++--- .../events/schema/factorioLuaObjects.kt | 62 +++++- .../adamko/kafkatorio/events/schema/json.kt | 2 +- .../events/schema/kafkatorioPacket.kt | 28 ++- .../events/schema/FactorioEventTest.kt | 200 ++++++++++++++++++ .../events/schema/FactorioEventTest.kt | 176 --------------- 9 files changed, 471 insertions(+), 243 deletions(-) create mode 100644 modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt delete mode 100644 modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt diff --git a/.kotlin-js-store/yarn.lock b/.kotlin-js-store/yarn.lock index 7a7afaa..8f53c73 100644 --- a/.kotlin-js-store/yarn.lock +++ b/.kotlin-js-store/yarn.lock @@ -965,7 +965,7 @@ deep-equal@^1.0.1: object-keys "^1.1.1" regexp.prototype.flags "^1.2.0" -default-gateway@^6.0.3: +default-gateway@^6.0.0, default-gateway@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== @@ -1721,17 +1721,32 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= +internal-ip@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-6.2.0.tgz#d5541e79716e406b74ac6b07b856ef18dc1621c1" + integrity sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg== + dependencies: + default-gateway "^6.0.0" + ipaddr.js "^1.9.1" + is-ip "^3.1.0" + p-event "^4.2.0" + interpret@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== +ip-regex@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" + integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== + ip@^1.1.0: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= -ipaddr.js@1.9.1: +ipaddr.js@1.9.1, ipaddr.js@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== @@ -1792,6 +1807,13 @@ is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-ip@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8" + integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q== + dependencies: + ip-regex "^4.0.0" + is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -2285,6 +2307,18 @@ open@^8.0.9: is-docker "^2.1.1" is-wsl "^2.2.0" +p-event@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" + integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== + dependencies: + p-timeout "^3.1.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -2328,6 +2362,13 @@ p-retry@^4.5.0: "@types/retry" "^0.12.0" retry "^0.13.1" +p-timeout@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -2467,6 +2508,11 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -2482,6 +2528,11 @@ qs@6.9.6: resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -3072,6 +3123,14 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -3087,6 +3146,11 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +v8-compile-cache@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -3102,7 +3166,7 @@ void-elements@^2.0.0: resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= -watchpack@^2.3.1: +watchpack@^2.2.0, watchpack@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25" integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== @@ -3117,6 +3181,25 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" +webpack-cli@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.0.tgz#dc43e6e0f80dd52e89cbf73d5294bcd7ad6eb343" + integrity sha512-n/jZZBMzVEl4PYIBs+auy2WI0WTQ74EnJDiyD98O2JZY6IVIHJNitkYp/uTXOviIOMfgzrNvC9foKv/8o8KSZw== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.1.0" + "@webpack-cli/info" "^1.4.0" + "@webpack-cli/serve" "^1.6.0" + colorette "^2.0.14" + commander "^7.0.0" + execa "^5.0.0" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + v8-compile-cache "^2.2.0" + webpack-merge "^5.7.3" + webpack-cli@4.9.1: version "4.9.1" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3" @@ -3135,7 +3218,7 @@ webpack-cli@4.9.1: rechoir "^0.7.0" webpack-merge "^5.7.3" -webpack-dev-middleware@^5.3.0: +webpack-dev-middleware@^5.2.1, webpack-dev-middleware@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.0.tgz#8fc02dba6e72e1d373eca361623d84610f27be7c" integrity sha512-MouJz+rXAm9B1OTOYaJnn6rtD/lWZPy2ufQCH3BPs8Rloh/Du6Jze4p7AeLYHkVi0giJnYLaSGDC7S+GM9arhg== @@ -3146,6 +3229,37 @@ webpack-dev-middleware@^5.3.0: range-parser "^1.2.1" schema-utils "^4.0.0" +webpack-dev-server@4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.3.1.tgz#759d3337f0fbea297fbd1e433ab04ccfc000076b" + integrity sha512-qNXQCVYo1kYhH9pgLtm8LRNkXX3XzTfHSj/zqzaqYzGPca+Qjr+81wj1jgPMCHhIhso9WEQ+kX9z23iG9PzQ7w== + dependencies: + ansi-html-community "^0.0.8" + bonjour "^3.5.0" + chokidar "^3.5.1" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + del "^6.0.0" + express "^4.17.1" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.0" + internal-ip "^6.2.0" + ipaddr.js "^2.0.1" + open "^8.0.9" + p-retry "^4.5.0" + portfinder "^1.0.28" + schema-utils "^3.1.0" + selfsigned "^1.10.11" + serve-index "^1.9.1" + sockjs "^0.3.21" + spdy "^4.0.2" + strip-ansi "^7.0.0" + url "^0.11.0" + webpack-dev-middleware "^5.2.1" + ws "^8.1.0" + webpack-dev-server@4.7.2: version "4.7.2" resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.7.2.tgz#324b79046491f2cf0b9d9e275381198c8246b380" @@ -3196,11 +3310,41 @@ webpack-merge@^5.7.3: clone-deep "^4.0.1" wildcard "^2.0.0" -webpack-sources@^3.2.2: +webpack-sources@^3.2.0, webpack-sources@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.2.tgz#d88e3741833efec57c4c789b6010db9977545260" integrity sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw== +webpack@5.57.1: + version "5.57.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.57.1.tgz#ead5ace2c17ecef2ae8126f143bfeaa7f55eab44" + integrity sha512-kHszukYjTPVfCOEyrUthA3jqJwduY/P3eO8I0gMNOZGIQWKAwZftxmp5hq6paophvwo9NoUrcZOecs9ulOyyTg== + dependencies: + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.50" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.4.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.8.3" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.4" + json-parse-better-errors "^1.0.2" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.2.0" + webpack-sources "^3.2.0" + webpack@5.65.0: version "5.65.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.65.0.tgz#ed2891d9145ba1f0d318e4ea4f89c3fa18e6f9be" diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index a22817b..f49820c 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -11,6 +11,7 @@ plugins { kotlin { js(IR) { binaries.executable() + browser() nodejs() } jvm { @@ -48,6 +49,7 @@ kotlin { implementation(kotlin("test")) implementation(project.dependencies.platform(libs.kotest.bom)) + implementation("io.kotest:kotest-framework-engine") implementation("io.kotest:kotest-assertions-core") implementation("io.kotest:kotest-property") implementation("io.kotest:kotest-assertions-json") diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt index ee45182..28787fa 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt @@ -1,17 +1,23 @@ package dev.adamko.kafkatorio.events.schema +import kotlinx.serialization.EncodeDefault +import kotlinx.serialization.Required import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient @Serializable -@SerialName("CONFIG") +//@SerialName("CONFIG") data class FactorioConfigurationUpdate( override val modVersion: String, val factorioData: FactorioGameDataUpdate, val allMods: List, val prototypes: List, ) : KafkatorioPacket() { +// @Transient + + @EncodeDefault override val packetType = PacketType.CONFIG } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index badb888..0228337 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -1,62 +1,56 @@ package dev.adamko.kafkatorio.events.schema -import dev.adamko.kafkatorio.events.schema.FactorioObjectData.ObjectName -import kotlinx.serialization.DeserializationStrategy -import kotlinx.serialization.SerialName +import kotlinx.serialization.EncodeDefault +import kotlinx.serialization.Required import kotlinx.serialization.Serializable -import kotlinx.serialization.json.JsonContentPolymorphicSerializer -import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.contentOrNull -import kotlinx.serialization.json.jsonObject -import kotlinx.serialization.json.jsonPrimitive -import kotlinx.serialization.modules.SerializersModule - @Serializable -@SerialName("EVENT") -data class FactorioEvent( +//@SerialName("EVENT") +data class FactorioEvent( override val modVersion: String, /** the initial Factorio event (`defines.events`) trigger */ val eventType: String, /** game time */ val tick: UInt, - val data: T, + val data: FactorioObjectData, ) : KafkatorioPacket() { + // @Transient + @EncodeDefault override val packetType: PacketType = PacketType.EVENT - companion object { - val kxsModule = SerializersModule { - contextual(FactorioEvent::class) { types -> serializer(types[0]) } - } - } +// companion object { +// val kxsModule = SerializersModule { +// contextual(FactorioEvent::class) { types -> serializer(types[0]) } +// } +// } } -object FactorioEventSerializer : JsonContentPolymorphicSerializer>( - FactorioEvent::class -) { - - override fun selectDeserializer(element: JsonElement): DeserializationStrategy> { - - val objectName: ObjectName? = element - .jsonObject[FactorioEvent<*>::data.name] - ?.jsonObject - ?.get(FactorioObjectData.discriminatorKey) - ?.jsonPrimitive - ?.contentOrNull - ?.let(ObjectName::valueOf) - - val sub = when (objectName) { - ObjectName.LuaPlayer -> PlayerData.serializer() - ObjectName.LuaEntity -> EntityData.serializer() - ObjectName.LuaSurface -> SurfaceData.serializer() - ObjectName.MapChunk -> MapChunk.serializer() - ObjectName.LuaTile -> MapTile.serializer() - ObjectName.ConsoleChatMessage -> ConsoleChatMessage.serializer() - null -> throw IllegalStateException("unknown type $objectName") - } - return FactorioEvent.serializer(sub) - } -} +//object FactorioEventSerializer : JsonContentPolymorphicSerializer>( +// FactorioEvent::class +//) { +// +// override fun selectDeserializer(element: JsonElement): DeserializationStrategy> { +// +// val objectName: ObjectName? = element +// .jsonObject[FactorioEvent<*>::data.name] +// ?.jsonObject +// ?.get(FactorioObjectData.discriminatorKey) +// ?.jsonPrimitive +// ?.contentOrNull +// ?.let(ObjectName::valueOf) +// +// val sub = when (objectName) { +// ObjectName.LuaPlayer -> PlayerData.serializer() +// ObjectName.LuaEntity -> EntityData.serializer() +// ObjectName.LuaSurface -> SurfaceData.serializer() +// ObjectName.MapChunk -> MapChunk.serializer() +// ObjectName.LuaTile -> MapTile.serializer() +// ObjectName.ConsoleChatMessage -> ConsoleChatMessage.serializer() +// null -> throw IllegalStateException("unknown type $objectName") +// } +// return FactorioEvent.serializer(sub) +// } +//} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt index f1ab819..d2df5b9 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -1,14 +1,22 @@ package dev.adamko.kafkatorio.events.schema -import kotlinx.serialization.SerialName +import kotlinx.serialization.DeserializationStrategy +import kotlinx.serialization.EncodeDefault import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonClassDiscriminator +import kotlinx.serialization.json.JsonContentPolymorphicSerializer +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.contentOrNull +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive -@Serializable -@JsonClassDiscriminator(FactorioObjectData.discriminatorKey) +//@Serializable +@Serializable(with = FactorioObjectDataSerializer::class) +//@JsonClassDiscriminator(FactorioObjectData.discriminatorKey) sealed class FactorioObjectData { /** @see FactorioObjectData.discriminatorKey */ + @EncodeDefault abstract val objectName: ObjectName // workaround - https://github.com/Kotlin/kotlinx.serialization/issues/1664 @@ -43,9 +51,39 @@ sealed class FactorioObjectData { } } +object FactorioObjectDataSerializer : JsonContentPolymorphicSerializer( + FactorioObjectData::class +) { + private val key = + FactorioObjectData::objectName.name +// "objectName" + + override fun selectDeserializer(element: JsonElement): DeserializationStrategy { + + val type = element + .jsonObject[key] + ?.jsonPrimitive + ?.contentOrNull + ?.let { json -> + FactorioObjectData.ObjectName.values().firstOrNull { it.name == json } + } + + return when (type) { + FactorioObjectData.ObjectName.LuaPlayer -> PlayerData.serializer() + FactorioObjectData.ObjectName.LuaEntity -> EntityData.serializer() + FactorioObjectData.ObjectName.LuaSurface -> SurfaceData.serializer() + FactorioObjectData.ObjectName.MapChunk -> MapChunk.serializer() + FactorioObjectData.ObjectName.LuaTile -> MapTile.serializer() + FactorioObjectData.ObjectName.ConsoleChatMessage -> ConsoleChatMessage.serializer() + null -> + throw Exception("Unknown FactorioObjectData $key: '$type' ") + } + } +} + @Serializable -@SerialName("LuaPlayer") +//@SerialName("LuaPlayer") data class PlayerData( @Serializable(with = ListAsObjectSerializer::class) val associatedCharactersUnitNumbers: List, @@ -56,11 +94,12 @@ data class PlayerData( val chatColour: Colour, val lastOnline: UInt, ) : FactorioObjectData() { + @EncodeDefault override val objectName = ObjectName.LuaPlayer } @Serializable -@SerialName("LuaEntity") +//@SerialName("LuaEntity") data class EntityData( val active: Boolean, val health: Double?, @@ -72,43 +111,48 @@ data class EntityData( val unitNumber: UInt? = null, val playerIndex: UInt? = null, ) : FactorioObjectData() { + @EncodeDefault override val objectName = ObjectName.LuaEntity } @Serializable -@SerialName("LuaSurface") +//@SerialName("LuaSurface") data class SurfaceData( val daytime: Double, val index: UInt, val name: String, ) : FactorioObjectData() { + @EncodeDefault override val objectName = ObjectName.LuaSurface } /** Quasi-object. This isn't a Factorio Lua type, but a helpful collection of [MapTile]s */ @Serializable -@SerialName("MapChunk") +//@SerialName("MapChunk") data class MapChunk( val tiles: List, ) : FactorioObjectData() { + @EncodeDefault override val objectName = ObjectName.MapChunk } @Serializable -@SerialName("LuaTile") +//@SerialName("LuaTile") data class MapTile( val prototypeName: String, val position: PositionData, val surfaceIndex: Int, ) : FactorioObjectData() { + @EncodeDefault override val objectName = ObjectName.LuaTile } @Serializable -@SerialName("ConsoleChatMessage") +//@SerialName("ConsoleChatMessage") data class ConsoleChatMessage( val authorPlayerIndex: UInt?, val content: String, ) : FactorioObjectData() { + @EncodeDefault override val objectName = ObjectName.ConsoleChatMessage } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt index 78f26d5..42551b0 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt @@ -29,7 +29,7 @@ internal class ListAsObjectSerializer(dataSerializer: KSerializer) : val jsonMapperKafkatorio = Json { prettyPrint = true prettyPrintIndent = " " - serializersModule = FactorioEvent.kxsModule +// serializersModule = FactorioEvent.kxsModule // serializersModule = KafkatorioPacket.kxsModule + FactorioEvent.kxsModule // serializersModule = SerializersModule { } } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt index 702542f..c99b231 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt @@ -1,6 +1,8 @@ package dev.adamko.kafkatorio.events.schema; import kotlinx.serialization.DeserializationStrategy +import kotlinx.serialization.EncodeDefault +import kotlinx.serialization.Required import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonContentPolymorphicSerializer import kotlinx.serialization.json.JsonElement @@ -8,24 +10,34 @@ import kotlinx.serialization.json.contentOrNull import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive - +//@Serializable @Serializable(with = KafkatorioPacketSerializer::class) +//@JsonClassDiscriminator("packetType") sealed class KafkatorioPacket { /** Schema versioning */ abstract val modVersion: String + @EncodeDefault abstract val packetType: PacketType enum class PacketType { EVENT, CONFIG, } -} + companion object { +// val kxsModule = SerializersModule { +// polym +// } + } + +} object KafkatorioPacketSerializer : JsonContentPolymorphicSerializer( KafkatorioPacket::class ) { - private const val key = "packetType" + private val key = + KafkatorioPacket::packetType.name +// "packetType" override fun selectDeserializer(element: JsonElement): DeserializationStrategy { @@ -33,13 +45,15 @@ object KafkatorioPacketSerializer : JsonContentPolymorphicSerializer + KafkatorioPacket.PacketType.values().firstOrNull { it.name == json } + } return when (type) { - KafkatorioPacket.PacketType.EVENT -> FactorioEventSerializer + KafkatorioPacket.PacketType.EVENT -> FactorioEvent.serializer() KafkatorioPacket.PacketType.CONFIG -> FactorioConfigurationUpdate.serializer() - else -> - throw Exception("Unknown Packet: key '$key' ") + null -> + throw Exception("Unknown KafkatorioPacket ${key}: '$type' ") } } } diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt new file mode 100644 index 0000000..aad3502 --- /dev/null +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt @@ -0,0 +1,200 @@ +package dev.adamko.kafkatorio.events.schema + +import io.kotest.assertions.json.shouldEqualJson +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.shouldBe +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString + +class FactorioEventTest : FunSpec({ + + context("Given: json on_player_joined_game") { + + // language=JSON + val json = """ + { + "data": { + "objectName": "LuaPlayer", + "name": "fredthedeadhead", + "characterUnitNumber": 1, + "associatedCharactersUnitNumbers": {}, + "position": { + "type": "MAP", + "x": 30.65625, + "y": 84.07421875 + }, + "colour": { + "red": 0.869000017642974853515625, + "green": 0.5, + "blue": 0.12999999523162841796875, + "alpha": 0.5 + }, + "chatColour": { + "red": 1, + "green": 0.62999999523162841796875, + "blue": 0.259000003337860107421875, + "alpha": 1 + }, + "lastOnline": 2287061 + }, + "packetType": "EVENT", + "eventType": "on_player_joined_game", + "modVersion": "0.2.1", + "tick": 2287072 + } + """.trimIndent() + context("When: decoded") { + val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) + + test("Then: parse") { + + val expected = FactorioEvent( + data = PlayerData( + name = "fredthedeadhead", + characterUnitNumber = 1u, + associatedCharactersUnitNumbers = emptyList(), + position = PositionData( + type = PositionType.MAP, + x = 30.65625, + y = 84.07421875, + ), + colour = Colour( + red = 0.869000017642974853515625f, + green = 0.5f, + blue = 0.12999999523162841796875f, + alpha = 0.5f + ), + chatColour = Colour( + red = 1f, + green = 0.62999999523162841796875f, + blue = 0.259000003337860107421875f, + alpha = 1f + ), + lastOnline = 2287061u + ), + eventType = "on_player_joined_game", + modVersion = "0.2.1", + tick = 2287072u + ) + + actual shouldBe expected + + expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaPlayer + } + + test("Then: expect encode equals json") { + val encoded = jsonMapperKafkatorio.encodeToString(actual) + encoded.shouldEqualJson(json) + } + } + } + + context("Given: json LuaSurface") { + // language=JSON + val json = """ + { + "data": { + "objectName": "LuaSurface", + "name": "nauvis", + "index": 1, + "daytime": 0.749480000092057618843455202295444905757904052734375 + }, + "packetType": "EVENT", + "eventType": "on_tick", + "modVersion": "0.2.1", + "tick": 2301240 + } + """.trimIndent() + + context("When: decoded") { + val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) + + test("should equal obj") { + + val expected = FactorioEvent( + data = SurfaceData( + name = "nauvis", + index = 1u, + daytime = 0.749480000092057618843455202295444905757904052734375 + ), + eventType = "on_tick", + modVersion = "0.2.1", + tick = 2301240u + ) + + actual shouldBe expected + + expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaSurface + } + + test("Then: expect encode equals json") { + val encoded = jsonMapperKafkatorio.encodeToString(actual) + encoded.shouldEqualJson(json) + } + } + } + + context("Given: LuaEntity on_player_changed_position") { + // language=JSON + val json = """ + { + "data": { + "objectName": "LuaEntity", + "name": "character", + "type": "character", + "active": true, + "health": 250, + "healthRatio": 1, + "surfaceIndex": 1, + "unitNumber": 1, + "position": { + "type": "MAP", + "x": 37.859375, + "y": 81.14453125 + } + }, + "packetType": "EVENT", + "eventType": "on_player_changed_position", + "modVersion": "0.2.1", + "tick": 2301231 + } + """.trimIndent() + context("When: decoded") { + val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) + + test("parse") { + + val expected = FactorioEvent( + data = EntityData( + name = "character", + type = "character", + active = true, + health = 250.0, + healthRatio = 1.0, + surfaceIndex = 1, + unitNumber = 1u, + playerIndex = null, + position = PositionData( + x = 37.859375, + y = 81.14453125, + type = PositionType.MAP, + ) + ), + eventType = "on_player_changed_position", + modVersion = "0.2.1", + tick = 2301231u + ) + + actual shouldBe expected + + expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaEntity + } + + test("Then: expect encode equals json") { + val encoded = jsonMapperKafkatorio.encodeToString(actual) + encoded.shouldEqualJson(json) + } + } + + } +}) diff --git a/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt deleted file mode 100644 index 04625ed..0000000 --- a/modules/events-schema/src/jvmTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt +++ /dev/null @@ -1,176 +0,0 @@ -package dev.adamko.kafkatorio.events.schema - -import io.kotest.core.spec.style.BehaviorSpec -import io.kotest.matchers.equality.shouldBeEqualToComparingFields -import io.kotest.matchers.shouldBe -import kotlinx.serialization.decodeFromString -import org.intellij.lang.annotations.Language - -class FactorioEventTest : BehaviorSpec({ - - Given("json on_player_joined_game") { - - @Language("JSON") - val json = """ - { - "data": { - "objectName": "LuaPlayer", - "name": "fredthedeadhead", - "characterUnitNumber": 1, - "associatedCharactersUnitNumbers": {}, - "position": { - "type": "MAP", - "x": 30.65625, - "y": 84.07421875 - }, - "colour": { - "red": 0.869000017642974853515625, - "green": 0.5, - "blue": 0.12999999523162841796875, - "alpha": 0.5 - }, - "chatColour": { - "red": 1, - "green": 0.62999999523162841796875, - "blue": 0.259000003337860107421875, - "alpha": 1 - }, - "lastOnline": 2287061 - }, - "packetType": "EVENT", - "eventType": "on_player_joined_game", - "modVersion": "0.2.1", - "tick": 2287072 - } - """.trimIndent() - - Then("parse") { - val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) - - val expected = FactorioEvent( - data = PlayerData( - name = "fredthedeadhead", - characterUnitNumber = 1u, - associatedCharactersUnitNumbers = emptyList(), - position = PositionData( - type = PositionType.MAP, - x = 30.65625, - y = 84.07421875, - ), - colour = Colour( - red = 0.869000017642974853515625f, - green = 0.5f, - blue = 0.12999999523162841796875f, - alpha = 0.5f - ), - chatColour = Colour( - red = 1f, - green = 0.62999999523162841796875f, - blue = 0.259000003337860107421875f, - alpha = 1f - ), - lastOnline = 2287061u - ), - eventType = "on_player_joined_game", - modVersion = "0.2.1", - tick = 2287072u - ) - - actual shouldBeEqualToComparingFields expected - - expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaPlayer - } - } - - Given("json surface") { - @Language("JSON") - val json = """ - { - "data": { - "objectName": "LuaSurface", - "name": "nauvis", - "index": 1, - "daytime": 0.749480000092057618843455202295444905757904052734375 - }, - "packetType": "EVENT", - "eventType": "on_tick", - "modVersion": "0.2.1", - "tick": 2301240 - } - """.trimIndent() - Then("parse") { - val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) - - val expected = FactorioEvent( - data = SurfaceData( - name = "nauvis", - index = 1u, - daytime = 0.749480000092057618843455202295444905757904052734375 - ), - eventType = "on_tick", - modVersion = "0.2.1", - tick = 2301240u - ) - - actual shouldBeEqualToComparingFields expected - - expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaSurface - } - } - - Given("LuaEntity on_player_changed_position") { - @Language("JSON") - val json = """ - { - "data": { - "objectName": "LuaEntity", - "name": "character", - "type": "character", - "active": true, - "health": 250, - "healthRatio": 1, - "surfaceIndex": 1, - "unitNumber": 1, - "position": { - "type": "MAP", - "x": 37.859375, - "y": 81.14453125 - } - }, - "packetType": "EVENT", - "eventType": "on_player_changed_position", - "modVersion": "0.2.1", - "tick": 2301231 - } - """.trimIndent() - Then("parse") { - val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) - - val expected = FactorioEvent( - data = EntityData( - name = "character", - type = "character", - active = true, - health = 250.0, - healthRatio = 1.0, - surfaceIndex = 1, - unitNumber = 1u, - playerIndex = null, - position = PositionData( - x = 37.859375, - y = 81.14453125, - type = PositionType.MAP, - ) - ), - eventType = "on_player_changed_position", - modVersion = "0.2.1", - tick = 2301231u - ) - - actual shouldBeEqualToComparingFields expected - - expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaEntity - } - } - -}) From d28088be2dd22973df2759bfb13f3aa3766a18b0 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 14:02:18 +0100 Subject: [PATCH 136/629] remove --build from docker-compose up (it builds every time - I only want it to build on changes) --- .../dev/adamko/kafkatorio/infra/docker-compose.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts index 7e1152e..a565841 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts @@ -19,7 +19,7 @@ val dockerUp by tasks.registering(Exec::class) { logging.captureStandardOutput(LogLevel.LIFECYCLE) workingDir = dockerSrcDir.asFile - commandLine = parseSpaceSeparatedArgs(""" docker-compose up --build -d """) + commandLine = parseSpaceSeparatedArgs(""" docker-compose up -d """) } val dockerDown by tasks.registering(Exec::class) { From 7486961fc201cbdb51cc96b6005bc46e1c62a481 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 14:07:19 +0100 Subject: [PATCH 137/629] cleaning up comments and old code --- .../events/schema/factorioCommonData.kt | 9 ----- .../events/schema/factorioConfiguration.kt | 3 -- .../events/schema/factorioEvents.kt | 38 ------------------- .../events/schema/factorioLuaObjects.kt | 18 +-------- .../events/schema/kafkatorioPacket.kt | 15 +------- 5 files changed, 3 insertions(+), 80 deletions(-) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index 6da45c7..282415e 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -40,12 +40,3 @@ data class Colour( fun isPercentage(): Boolean = !isDecimal() } - -//@Serializable -//@SerialName("FactorioTiles") -//data class FactorioTiles( -// val tiles: List, -//) : FactorioObjectData() { -// @Transient -// override val objectName: String = "FactorioTiles" -//} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt index 28787fa..8fd0333 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt @@ -8,15 +8,12 @@ import kotlinx.serialization.Transient @Serializable -//@SerialName("CONFIG") data class FactorioConfigurationUpdate( override val modVersion: String, val factorioData: FactorioGameDataUpdate, val allMods: List, val prototypes: List, ) : KafkatorioPacket() { -// @Transient - @EncodeDefault override val packetType = PacketType.CONFIG } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index 0228337..9477af1 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -2,11 +2,9 @@ package dev.adamko.kafkatorio.events.schema import kotlinx.serialization.EncodeDefault -import kotlinx.serialization.Required import kotlinx.serialization.Serializable @Serializable -//@SerialName("EVENT") data class FactorioEvent( override val modVersion: String, /** the initial Factorio event (`defines.events`) trigger */ @@ -15,42 +13,6 @@ data class FactorioEvent( val tick: UInt, val data: FactorioObjectData, ) : KafkatorioPacket() { - // @Transient @EncodeDefault override val packetType: PacketType = PacketType.EVENT - -// companion object { -// val kxsModule = SerializersModule { -// contextual(FactorioEvent::class) { types -> serializer(types[0]) } -// } -// } - } - - -//object FactorioEventSerializer : JsonContentPolymorphicSerializer>( -// FactorioEvent::class -//) { -// -// override fun selectDeserializer(element: JsonElement): DeserializationStrategy> { -// -// val objectName: ObjectName? = element -// .jsonObject[FactorioEvent<*>::data.name] -// ?.jsonObject -// ?.get(FactorioObjectData.discriminatorKey) -// ?.jsonPrimitive -// ?.contentOrNull -// ?.let(ObjectName::valueOf) -// -// val sub = when (objectName) { -// ObjectName.LuaPlayer -> PlayerData.serializer() -// ObjectName.LuaEntity -> EntityData.serializer() -// ObjectName.LuaSurface -> SurfaceData.serializer() -// ObjectName.MapChunk -> MapChunk.serializer() -// ObjectName.LuaTile -> MapTile.serializer() -// ObjectName.ConsoleChatMessage -> ConsoleChatMessage.serializer() -// null -> throw IllegalStateException("unknown type $objectName") -// } -// return FactorioEvent.serializer(sub) -// } -//} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt index d2df5b9..dcdce76 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -3,16 +3,13 @@ package dev.adamko.kafkatorio.events.schema import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.EncodeDefault import kotlinx.serialization.Serializable -import kotlinx.serialization.json.JsonClassDiscriminator import kotlinx.serialization.json.JsonContentPolymorphicSerializer import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.contentOrNull import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive -//@Serializable @Serializable(with = FactorioObjectDataSerializer::class) -//@JsonClassDiscriminator(FactorioObjectData.discriminatorKey) sealed class FactorioObjectData { /** @see FactorioObjectData.discriminatorKey */ @@ -44,19 +41,12 @@ sealed class FactorioObjectData { LuaTile, ConsoleChatMessage, } - - companion object { - /** The [JsonClassDiscriminator] for [FactorioEvent] */ - const val discriminatorKey: String = "objectName" - } } object FactorioObjectDataSerializer : JsonContentPolymorphicSerializer( FactorioObjectData::class ) { - private val key = - FactorioObjectData::objectName.name -// "objectName" + private val key = FactorioObjectData::objectName.name override fun selectDeserializer(element: JsonElement): DeserializationStrategy { @@ -83,7 +73,6 @@ object FactorioObjectDataSerializer : JsonContentPolymorphicSerializer, @@ -99,7 +88,6 @@ data class PlayerData( } @Serializable -//@SerialName("LuaEntity") data class EntityData( val active: Boolean, val health: Double?, @@ -116,7 +104,6 @@ data class EntityData( } @Serializable -//@SerialName("LuaSurface") data class SurfaceData( val daytime: Double, val index: UInt, @@ -128,7 +115,6 @@ data class SurfaceData( /** Quasi-object. This isn't a Factorio Lua type, but a helpful collection of [MapTile]s */ @Serializable -//@SerialName("MapChunk") data class MapChunk( val tiles: List, ) : FactorioObjectData() { @@ -137,7 +123,6 @@ data class MapChunk( } @Serializable -//@SerialName("LuaTile") data class MapTile( val prototypeName: String, val position: PositionData, @@ -148,7 +133,6 @@ data class MapTile( } @Serializable -//@SerialName("ConsoleChatMessage") data class ConsoleChatMessage( val authorPlayerIndex: UInt?, val content: String, diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt index c99b231..9248fb7 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt @@ -2,7 +2,6 @@ package dev.adamko.kafkatorio.events.schema; import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.EncodeDefault -import kotlinx.serialization.Required import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonContentPolymorphicSerializer import kotlinx.serialization.json.JsonElement @@ -10,9 +9,8 @@ import kotlinx.serialization.json.contentOrNull import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive -//@Serializable + @Serializable(with = KafkatorioPacketSerializer::class) -//@JsonClassDiscriminator("packetType") sealed class KafkatorioPacket { /** Schema versioning */ abstract val modVersion: String @@ -23,21 +21,12 @@ sealed class KafkatorioPacket { EVENT, CONFIG, } - - companion object { -// val kxsModule = SerializersModule { -// polym -// } - } - } object KafkatorioPacketSerializer : JsonContentPolymorphicSerializer( KafkatorioPacket::class ) { - private val key = - KafkatorioPacket::packetType.name -// "packetType" + private val key = KafkatorioPacket::packetType.name override fun selectDeserializer(element: JsonElement): DeserializationStrategy { From 524aa218fc8c648b4c2332a3fbd6c13ceaf1c3cf Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 14:08:02 +0100 Subject: [PATCH 138/629] pre-emptively fixing kxs generics on factorioPrototypes.kt --- .../events/schema/factorioLuaObjects.kt | 1 - .../events/schema/factorioPrototypes.kt | 55 +++++++++++++------ 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt index dcdce76..41d5441 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -12,7 +12,6 @@ import kotlinx.serialization.json.jsonPrimitive @Serializable(with = FactorioObjectDataSerializer::class) sealed class FactorioObjectData { - /** @see FactorioObjectData.discriminatorKey */ @EncodeDefault abstract val objectName: ObjectName diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt index 82316f3..1cc4dd0 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt @@ -1,31 +1,50 @@ package dev.adamko.kafkatorio.events.schema -import kotlinx.serialization.SerialName +import kotlinx.serialization.DeserializationStrategy +import kotlinx.serialization.EncodeDefault import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient -import kotlinx.serialization.json.JsonClassDiscriminator +import kotlinx.serialization.json.JsonContentPolymorphicSerializer +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.contentOrNull +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive -@Serializable -class FactorioPrototypes( - val prototypes: List, -) -@Serializable -@JsonClassDiscriminator(FactorioPrototype.discriminatorKey) +@Serializable(with = FactorioPrototypeSerializer::class) sealed class FactorioPrototype { - abstract val objectName: PrototypeObjectName + @EncodeDefault + abstract val objectName: ObjectName - enum class PrototypeObjectName { + enum class ObjectName { LuaTilePrototype } - - companion object { - const val discriminatorKey: String = "objectName" - } } +object FactorioPrototypeSerializer : JsonContentPolymorphicSerializer( + FactorioPrototype::class +) { + private val key = FactorioPrototype::objectName.name + + override fun selectDeserializer(element: JsonElement): DeserializationStrategy { + + val type = element + .jsonObject[key] + ?.jsonPrimitive + ?.contentOrNull + ?.let { json -> + FactorioPrototype.ObjectName.values().firstOrNull { it.name == json } + } + + return when (type) { + FactorioPrototype.ObjectName.LuaTilePrototype -> FactorioMapTilePrototype.serializer() + null -> + throw Exception("Unknown FactorioPrototype $key: '$type' ") + } + } +} + + @Serializable -@SerialName("LuaTilePrototype") data class FactorioMapTilePrototype( val name: String, val layer: UInt, @@ -36,6 +55,6 @@ data class FactorioMapTilePrototype( /** Can the tile be mined for resources? */ val canBeMined: Boolean, ) : FactorioPrototype() { - @Transient - override val objectName: PrototypeObjectName = PrototypeObjectName.LuaTilePrototype + @EncodeDefault + override val objectName: ObjectName = ObjectName.LuaTilePrototype } From 4d94e2f395a373e1064f74ccd7fe33d77dd34f61 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 15:07:36 +0100 Subject: [PATCH 139/629] finish fixing the schema --- .../events/schema/factorioCommonData.kt | 7 +++- .../events/schema/factorioPrototypes.kt | 1 - .../events/schema/FactorioEventTest.kt | 36 +++++++++---------- .../processor/KafkatorioTopology.kt | 2 +- .../dev/adamko/kafkatorio/webmap/state.kt | 2 +- .../adamko/kafkatorio/webmap/websockets.kt | 12 +++---- 6 files changed, 32 insertions(+), 28 deletions(-) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index 282415e..79b3f06 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.events.schema +import kotlinx.serialization.EncodeDefault import kotlinx.serialization.Serializable @Serializable @@ -22,12 +23,16 @@ enum class PositionType { */ @Serializable data class Colour( + @EncodeDefault val red: Float = 0f, + @EncodeDefault val green: Float = 0f, + @EncodeDefault val blue: Float = 0f, + @EncodeDefault val alpha: Float = 1f, ) { - + /** True if any value is greater than 1, so the values are hexadecimal. */ fun isDecimal(): Boolean { return red > 1f diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt index 1cc4dd0..2d8a4fe 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt @@ -51,7 +51,6 @@ data class FactorioMapTilePrototype( val mapColor: Colour, val collisionMasks: List, val order: String, - /** Can the tile be mined for resources? */ val canBeMined: Boolean, ) : FactorioPrototype() { diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt index aad3502..9b81385 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt @@ -20,19 +20,19 @@ class FactorioEventTest : FunSpec({ "associatedCharactersUnitNumbers": {}, "position": { "type": "MAP", - "x": 30.65625, - "y": 84.07421875 + "x": 30.6, + "y": 84.1 }, "colour": { - "red": 0.869000017642974853515625, + "red": 0.86, "green": 0.5, - "blue": 0.12999999523162841796875, + "blue": 0.12, "alpha": 0.5 }, "chatColour": { "red": 1, - "green": 0.62999999523162841796875, - "blue": 0.259000003337860107421875, + "green": 0.62, + "blue": 0.25, "alpha": 1 }, "lastOnline": 2287061 @@ -55,19 +55,19 @@ class FactorioEventTest : FunSpec({ associatedCharactersUnitNumbers = emptyList(), position = PositionData( type = PositionType.MAP, - x = 30.65625, - y = 84.07421875, + x = 30.6, + y = 84.1, ), colour = Colour( - red = 0.869000017642974853515625f, + red = 0.86f, green = 0.5f, - blue = 0.12999999523162841796875f, + blue = 0.12f, alpha = 0.5f ), chatColour = Colour( red = 1f, - green = 0.62999999523162841796875f, - blue = 0.259000003337860107421875f, + green = 0.62f, + blue = 0.25f, alpha = 1f ), lastOnline = 2287061u @@ -97,7 +97,7 @@ class FactorioEventTest : FunSpec({ "objectName": "LuaSurface", "name": "nauvis", "index": 1, - "daytime": 0.749480000092057618843455202295444905757904052734375 + "daytime": 0.745 }, "packetType": "EVENT", "eventType": "on_tick", @@ -115,7 +115,7 @@ class FactorioEventTest : FunSpec({ data = SurfaceData( name = "nauvis", index = 1u, - daytime = 0.749480000092057618843455202295444905757904052734375 + daytime = 0.745 ), eventType = "on_tick", modVersion = "0.2.1", @@ -149,8 +149,8 @@ class FactorioEventTest : FunSpec({ "unitNumber": 1, "position": { "type": "MAP", - "x": 37.859375, - "y": 81.14453125 + "x": 37.5, + "y": 81.1 } }, "packetType": "EVENT", @@ -175,8 +175,8 @@ class FactorioEventTest : FunSpec({ unitNumber = 1u, playerIndex = null, position = PositionData( - x = 37.859375, - y = 81.14453125, + x = 37.5, + y = 81.1, type = PositionType.MAP, ) ), diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 523b291..914a02b 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -37,7 +37,7 @@ class KafkatorioTopology( { _, value, _ -> // println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") when (value) { - is FactorioEvent<*> -> + is FactorioEvent -> "kafkatorio.${value.packetType.name}.${value.data.objectName.name}" is FactorioConfigurationUpdate -> "kafkatorio.${value.packetType.name}" diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt index 8b1b823..dad8b9a 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt @@ -29,7 +29,7 @@ data class FactorioGameState( sealed class FactorioUpdate : RAction { - data class PlayerUpdate(val event: FactorioEvent<*>, val playerData: PlayerData) : + data class PlayerUpdate(val event: FactorioEvent, val playerData: PlayerData) : FactorioUpdate() } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt index ca59674..36c8a7c 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -4,9 +4,9 @@ import dev.adamko.kafkatorio.events.schema.ConsoleChatMessage import dev.adamko.kafkatorio.events.schema.EntityData import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.events.schema.MapChunk import dev.adamko.kafkatorio.events.schema.MapTile -import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.events.schema.PlayerData import dev.adamko.kafkatorio.events.schema.SurfaceData import io.kvision.redux.ReduxStore @@ -37,15 +37,15 @@ class WebsocketService( println(data.replace('\n', ' ')) when (val event: KafkatorioPacket = jsonMapper.decodeFromString(data)) { - is FactorioEvent<*> -> { + is FactorioEvent -> { when (val eventData = event.data) { is PlayerData -> reduxStore.dispatch(FactorioUpdate.PlayerUpdate(event, eventData)) is ConsoleChatMessage -> {} - is EntityData -> {} - is MapChunk -> {} - is MapTile -> {} - is SurfaceData -> {} + is EntityData -> {} + is MapChunk -> {} + is MapTile -> {} + is SurfaceData -> {} } } is FactorioConfigurationUpdate -> {} From 4d2f57482775c6a2248f13f49fe6047c8b27d620 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 15:15:52 +0100 Subject: [PATCH 140/629] fix typescript after updates --- .../generated/kafkatorio-schema/object-data.d.ts | 8 -------- .../generated/kafkatorio-schema/prototype.d.ts | 4 ++-- .../generated/kafkatorio-schema/schema.d.ts | 8 ++++++++ .../main/config-update/convertPrototypes.ts | 6 +++--- .../kafkatorio/events/schema/factorioPrototypes.kt | 14 +++++++------- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts index 30d82f0..eb07c20 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts @@ -6,14 +6,6 @@ interface FactorioObjectData { objectName: ObjectName; } -interface FactorioEvent extends KafkatorioPacket { - data: T; - eventType: string; - modVersion: string; - packetType: PacketType; - tick: uint; -} - interface PlayerData extends FactorioObjectData { associatedCharactersUnitNumbers: uint[]; characterUnitNumber: uint | null; diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts index fdb93b9..e4d4067 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts @@ -3,7 +3,7 @@ type PrototypeObjectName = "LuaTilePrototype"; interface FactorioPrototype { - objectName: PrototypeObjectName; + prototypeObjectName: PrototypeObjectName; } interface FactorioMapTilePrototype extends FactorioPrototype { @@ -12,6 +12,6 @@ interface FactorioMapTilePrototype extends FactorioPrototype { layer: uint; mapColor: Colour; name: string; - objectName: PrototypeObjectName; order: string; + prototypeObjectName: PrototypeObjectName; } diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts index 18b91eb..712c4d6 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts @@ -7,6 +7,14 @@ interface KafkatorioPacket { packetType: PacketType; } +interface FactorioEvent extends KafkatorioPacket { + data: FactorioObjectData; + eventType: string; + modVersion: string; + packetType: PacketType; + tick: uint; +} + interface Colour { alpha: float; blue: float; diff --git a/modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts b/modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts index 5234afb..a3b803f 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts @@ -10,10 +10,10 @@ export function convertPrototypes(): FactorioPrototype[] { function getMapTilePrototypes(): FactorioMapTilePrototype[] { let tiles: FactorioMapTilePrototype[] = [] - for (let [_, tile] of pairs(game.tile_prototypes)) { + for (let [, tile] of pairs(game.tile_prototypes)) { tiles.push( { - objectName: tile.object_name, + prototypeObjectName: tile.object_name, name: tile.name, order: tile.order, @@ -29,7 +29,7 @@ function getMapTilePrototypes(): FactorioMapTilePrototype[] { function convertCollisionMaskToNames(cm: CollisionMask): string[] { let masks: string[] = [] - for (let [name, _] of pairs(cm)) { + for (let [name] of pairs(cm)) { masks.push(name) } return masks diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt index 2d8a4fe..8cedb60 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt @@ -13,9 +13,9 @@ import kotlinx.serialization.json.jsonPrimitive @Serializable(with = FactorioPrototypeSerializer::class) sealed class FactorioPrototype { @EncodeDefault - abstract val objectName: ObjectName + abstract val prototypeObjectName: PrototypeObjectName - enum class ObjectName { + enum class PrototypeObjectName { LuaTilePrototype } } @@ -23,7 +23,7 @@ sealed class FactorioPrototype { object FactorioPrototypeSerializer : JsonContentPolymorphicSerializer( FactorioPrototype::class ) { - private val key = FactorioPrototype::objectName.name + private val key = FactorioPrototype::prototypeObjectName.name override fun selectDeserializer(element: JsonElement): DeserializationStrategy { @@ -32,12 +32,12 @@ object FactorioPrototypeSerializer : JsonContentPolymorphicSerializer - FactorioPrototype.ObjectName.values().firstOrNull { it.name == json } + FactorioPrototype.PrototypeObjectName.values().firstOrNull { it.name == json } } return when (type) { - FactorioPrototype.ObjectName.LuaTilePrototype -> FactorioMapTilePrototype.serializer() - null -> + FactorioPrototype.PrototypeObjectName.LuaTilePrototype -> FactorioMapTilePrototype.serializer() + null -> throw Exception("Unknown FactorioPrototype $key: '$type' ") } } @@ -55,5 +55,5 @@ data class FactorioMapTilePrototype( val canBeMined: Boolean, ) : FactorioPrototype() { @EncodeDefault - override val objectName: ObjectName = ObjectName.LuaTilePrototype + override val prototypeObjectName: PrototypeObjectName = PrototypeObjectName.LuaTilePrototype } From 05a693720d277d345f71f26c32494e4aff495419 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 15:41:58 +0100 Subject: [PATCH 141/629] small refactor, make all event handlers have same parameter order --- .../src/main/typescript/main/events/handlers.ts | 16 ++++++++-------- .../typescript/main/events/registerHandlers.ts | 16 +++++++--------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index f8e085f..158e5d7 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -1,39 +1,39 @@ import {Converters} from "./converters" import {emitEvent} from "./emitEvent"; -export function handlePlayerUpdate(tick: uint, playerIndex: uint, eventType: string) { +export function handlePlayerUpdate(tick: uint, eventType: string, playerIndex: uint) { let player: LuaPlayer = game.players[playerIndex] let table = Converters.playerToTable(player) emitEvent(table, tick, eventType) - handleCharactersEvent(tick, playerIndex, eventType) + handleCharactersEvent(tick, eventType, playerIndex) } -export function handleCharactersEvent(tick: uint, playerIndex: uint, eventType: string) { +export function handleCharactersEvent(tick: uint, eventType: string, playerIndex: uint) { let player: LuaPlayer = game.players[playerIndex] if (player.character != undefined) { - handleEntityUpdate(tick, player.character, eventType) + handleEntityUpdate(tick, eventType, player.character) } for (const character of player.get_associated_characters()) { if (character != undefined) { - handleEntityUpdate(tick, character, eventType) + handleEntityUpdate(tick, eventType, character) } } } -export function handleEntityUpdate(tick: uint, entity: LuaEntity, eventType: string) { +export function handleEntityUpdate(tick: uint, eventType: string, entity: LuaEntity) { let table = Converters.entityToTable(entity) emitEvent(table, tick, eventType) } export function handleSurfaceUpdate( tick: uint, + eventType: string, surface: LuaSurface, - eventType: string ) { let table = Converters.surfaceToTable(surface) emitEvent(table, tick, eventType) @@ -41,9 +41,9 @@ export function handleSurfaceUpdate( export function handleConsoleChat( tick: uint, + eventType: string, playerIndex: uint | undefined, message: string, - eventType: string, ) { let table = Converters.consoleChat(message, playerIndex) emitEvent(table, tick, eventType) diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index 969d90d..67029ba 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -22,24 +22,22 @@ script.on_event( defines.events.on_player_mined_entity, (e: OnPlayerMinedEntityEvent) => { let eventName = mapEventIdToName.get(e.name) - handlePlayerUpdate(e.tick, e.player_index, eventName) - handleEntityUpdate(e.tick, e.entity, eventName) + handlePlayerUpdate(e.tick, eventName, e.player_index) + handleEntityUpdate(e.tick, eventName, e.entity) } ) script.on_event( defines.events.on_player_joined_game, (e: OnPlayerJoinedGameEvent) => { - let eventName = mapEventIdToName.get(e.name) - handlePlayerUpdate(e.tick, e.player_index, eventName) + handlePlayerUpdate(e.tick, mapEventIdToName.get(e.name), e.player_index) } ) script.on_event( defines.events.on_player_changed_position, (e: OnPlayerChangedPositionEvent) => { - let eventName = mapEventIdToName.get(e.name) - handlePlayerUpdate(e.tick, e.player_index, eventName) + handlePlayerUpdate(e.tick, mapEventIdToName.get(e.name), e.player_index) } ) @@ -47,8 +45,8 @@ script.on_event( defines.events.on_tick, (e: OnTickEvent) => { if (e.tick % 60 == 0) { - for (const [_, surface] of pairs(game.surfaces)) { - handleSurfaceUpdate(e.tick, surface, mapEventIdToName.get(e.name)) + for (const [, surface] of pairs(game.surfaces)) { + handleSurfaceUpdate(e.tick, mapEventIdToName.get(e.name), surface) } // for (const [index, _] of pairs(game.surfaces)) { @@ -66,7 +64,7 @@ script.on_event( script.on_event( defines.events.on_console_chat, (e: OnConsoleChatEvent) => { - handleConsoleChat(e.tick, e.player_index, e.message, mapEventIdToName.get(e.name)) + handleConsoleChat(e.tick, mapEventIdToName.get(e.name), e.player_index, e.message) } ) From f41def72e28e3bb9448b457476964e0576cd08ac Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 16:10:47 +0100 Subject: [PATCH 142/629] rm comment, only send chunks updates on chunk generation --- .../typescript/main/events/registerHandlers.ts | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index 67029ba..9ff6950 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -48,15 +48,6 @@ script.on_event( for (const [, surface] of pairs(game.surfaces)) { handleSurfaceUpdate(e.tick, mapEventIdToName.get(e.name), surface) } - - // for (const [index, _] of pairs(game.surfaces)) { - // let surface = game.get_surface(index) // TODO fix / report can't iterate over surfaces - // if (surface != undefined) { - // handleSurfaceUpdate(e.tick, surface, mapEventIdToName.get(e.name)) - // } - //// let surface = game.surfaces[index] - //// surfaceEvent(e.tick, surface, mapEventIdToName.get(e.name)) - // } } } ) @@ -69,8 +60,8 @@ script.on_event( ) script.on_event( - defines.events.on_chunk_charted, - (e: OnChunkChartedEvent) => { - handleChunkUpdate(e.tick, mapEventIdToName.get(e.name), e.surface_index, e.position) + defines.events.on_chunk_generated, + (e: OnChunkGeneratedEvent) => { + handleChunkUpdate(e.tick, mapEventIdToName.get(e.name), e.surface.index, e.position) } ) From b9190b19480d925205080afeafced000ce2f529d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 16:33:23 +0100 Subject: [PATCH 143/629] make the json a little less verbose by having separate position types instead of a discriminator --- .../kafkatorio-schema/object-data.d.ts | 7 +-- .../generated/kafkatorio-schema/schema.d.ts | 15 ++++-- .../main/typescript/main/events/converters.ts | 24 +++++++-- .../main/typescript/main/events/handlers.ts | 4 +- .../events/schema/factorioCommonData.kt | 51 +++++++++++++++++-- .../events/schema/factorioLuaObjects.kt | 7 +-- 6 files changed, 87 insertions(+), 21 deletions(-) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts index eb07c20..a0a9e7a 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts @@ -14,7 +14,7 @@ interface PlayerData extends FactorioObjectData { lastOnline: uint; name: string; objectName: ObjectName; - position: PositionData; + position: MapEntityPosition; } interface EntityData extends FactorioObjectData { @@ -24,7 +24,7 @@ interface EntityData extends FactorioObjectData { name: string; objectName: ObjectName; playerIndex: uint | null; - position: PositionData; + position: MapEntityPosition; surfaceIndex: int; type: string; unitNumber: uint | null; @@ -39,13 +39,14 @@ interface SurfaceData extends FactorioObjectData { interface MapTile extends FactorioObjectData { objectName: ObjectName; - position: PositionData; + position: MapTilePosition; prototypeName: string; surfaceIndex: int; } interface MapChunk extends FactorioObjectData { objectName: ObjectName; + position: MapChunkPosition; tiles: MapTile[]; } diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts index 712c4d6..7ac53c3 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts @@ -22,10 +22,17 @@ interface Colour { red: float; } -type PositionType = "MAP" | "CHUNK" | "TILE"; - -interface PositionData { - type: PositionType | null; +interface MapEntityPosition { x: double; y: double; } + +interface MapChunkPosition { + x: int; + y: int; +} + +interface MapTilePosition { + x: int; + y: int; +} diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index 0bb3b53..5956fa8 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -8,7 +8,7 @@ export namespace Converters { name: player.name, characterUnitNumber: player.character?.unit_number ?? null, associatedCharactersUnitNumbers: charIds, - position: convertMapPosition(player.position), + position: mapEntityPosition(player.position), colour: mapColour(player.color), chatColour: mapColour(player.chat_color), lastOnline: player.last_online @@ -30,7 +30,7 @@ export namespace Converters { healthRatio: entity.get_health_ratio(), surfaceIndex: entity.surface.index, unitNumber: entity.unit_number ?? null, - position: convertMapPosition(entity.position), + position: mapEntityPosition(entity.position), // player data playerIndex: player?.index ?? null @@ -57,9 +57,23 @@ export namespace Converters { } } - export function convertMapPosition(mapPos: MapPositionTable): PositionData { + export function mapEntityPosition(mapPos: MapPositionTable): MapEntityPosition { + return { + x: mapPos.x, + y: mapPos.y, + } + } + + export function mapTilePosition(mapPos: MapPositionTable): MapTilePosition { + return { + x: mapPos.x, + y: mapPos.y, + } + } + + + export function mapChunkPosition(mapPos: ChunkPositionTable): MapChunkPosition { return { - type: "MAP", x: mapPos.x, y: mapPos.y, } @@ -87,7 +101,7 @@ export namespace Converters { return { objectName: tile.object_name, - position: convertMapPosition(tile.position), + position: mapTilePosition(tile.position), prototypeName: tile.prototype.name, surfaceIndex: tile.surface.index } diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index 158e5d7..22a6f10 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -1,5 +1,6 @@ import {Converters} from "./converters" import {emitEvent} from "./emitEvent"; +import mapChunkPosition = Converters.mapChunkPosition; export function handlePlayerUpdate(tick: uint, eventType: string, playerIndex: uint) { let player: LuaPlayer = game.players[playerIndex] @@ -55,7 +56,7 @@ export function handleChunkUpdate( tick: uint, eventType: string, surfaceIndex: uint, - position: ChunkPosition + position: ChunkPositionTable ) { let surface = game.get_surface(surfaceIndex) @@ -77,6 +78,7 @@ export function handleChunkUpdate( let mapChunk: MapChunk = { objectName: "MapChunk", tiles: convertedTiles, + position: mapChunkPosition(position) } emitEvent(mapChunk, tick, eventType) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index 79b3f06..8633fc3 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -1,18 +1,59 @@ package dev.adamko.kafkatorio.events.schema +import kotlin.math.roundToInt import kotlinx.serialization.EncodeDefault import kotlinx.serialization.Serializable +const val MAP_CHUNK_SIZE = 32 + +/** + * Coordinates of a [EntityData] on a map. + * + * A [MapEntityPosition] can be translated to a [MapChunkPosition] by dividing the `x`/`y` values + * by [32][MAP_CHUNK_SIZE]. + */ @Serializable -data class PositionData( +data class MapEntityPosition( val x: Double, val y: Double, - val type: PositionType?, -) +) { + fun toMapChunkPosition() = MapChunkPosition( + (x / MAP_CHUNK_SIZE).roundToInt(), + (y / MAP_CHUNK_SIZE).roundToInt(), + ) + +} + +/** Coordinates of a chunk in a [SurfaceData] where each integer `x`/`y` represents a different + * chunk. + * + * A [MapChunkPosition] can be translated to a [MapEntityPosition] by multiplying the `x`/`y` + * values by [32][MAP_CHUNK_SIZE]. + */ @Serializable -enum class PositionType { - MAP, CHUNK, TILE, +data class MapChunkPosition( + val x: Int, + val y: Int, +) { + fun toMapEntityPosition() = MapEntityPosition( + x * MAP_CHUNK_SIZE.toDouble(), + y * MAP_CHUNK_SIZE.toDouble(), + ) +} + +/** + * Coordinates of a tile in a chunk on a [SurfaceData] where each integer `x`/`y` represents a + * different [MapTile]. + * + * It rounds any `x`/`y` down to whole numbers. + */ +@Serializable +data class MapTilePosition( + val x: Int, + val y: Int, +) { + constructor(x: Number, y: Number) : this(x.toInt(), y.toInt()) } /** diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt index 41d5441..0b8c3c6 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -77,7 +77,7 @@ data class PlayerData( val associatedCharactersUnitNumbers: List, val characterUnitNumber: UInt?, val name: String, - val position: PositionData, + val position: MapEntityPosition, val colour: Colour, val chatColour: Colour, val lastOnline: UInt, @@ -92,7 +92,7 @@ data class EntityData( val health: Double?, val healthRatio: Double, val name: String, - val position: PositionData, + val position: MapEntityPosition, val surfaceIndex: Int, val type: String, val unitNumber: UInt? = null, @@ -116,6 +116,7 @@ data class SurfaceData( @Serializable data class MapChunk( val tiles: List, + val position: MapChunkPosition, ) : FactorioObjectData() { @EncodeDefault override val objectName = ObjectName.MapChunk @@ -124,7 +125,7 @@ data class MapChunk( @Serializable data class MapTile( val prototypeName: String, - val position: PositionData, + val position: MapTilePosition, val surfaceIndex: Int, ) : FactorioObjectData() { @EncodeDefault From 4e8a0c4f69ad5671d6a2d5623a2d4b825593b1bb Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 17:39:24 +0100 Subject: [PATCH 144/629] fix build error, and disable SNAPSHOT kvision checking --- modules/web-map/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 502cedd..a7128f7 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -13,7 +13,7 @@ kotlin { browser { runTask { outputFileName = "main.bundle.js" - sourceMaps = true + sourceMaps = false devServer = KotlinWebpackConfig.DevServer( open = false, port = 3000, @@ -83,7 +83,7 @@ fun KotlinDependencyHandler.kvision( module: String, version: Provider = libs.versions.kvision, configure: ExternalModuleDependency.() -> Unit = { - isChanging = true +// isChanging = true } ) { implementation("io.kvision:$module:${version.get()}", configure) From 4d2926ebe2d5169fa27c29ffbd58b23f1e753916 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 17:40:28 +0100 Subject: [PATCH 145/629] try making map tiles better, listen to events for changed tiles --- .../kafkatorio-schema/object-data.d.ts | 9 +++- .../main/typescript/main/events/converters.ts | 11 +++- .../main/typescript/main/events/handlers.ts | 54 ++++++++++++++++--- .../main/events/registerHandlers.ts | 20 ++++++- .../events/schema/factorioLuaObjects.kt | 17 ++++-- .../events/schema/FactorioEventTest.kt | 8 +-- 6 files changed, 97 insertions(+), 22 deletions(-) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts index a0a9e7a..56b2136 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts @@ -1,6 +1,6 @@ // Generated by TypeScriptGenerator - do not edit this file manually -type ObjectName = "LuaPlayer" | "LuaEntity" | "LuaSurface" | "MapChunk" | "LuaTile" | "ConsoleChatMessage"; +type ObjectName = "LuaPlayer" | "LuaEntity" | "LuaSurface" | "MapChunk" | "LuaTile" | "LuaTiles" | "ConsoleChatMessage"; interface FactorioObjectData { objectName: ObjectName; @@ -41,13 +41,18 @@ interface MapTile extends FactorioObjectData { objectName: ObjectName; position: MapTilePosition; prototypeName: string; +} + +interface MapTiles extends FactorioObjectData { + objectName: ObjectName; surfaceIndex: int; + tiles: MapTile[]; } interface MapChunk extends FactorioObjectData { objectName: ObjectName; position: MapChunkPosition; - tiles: MapTile[]; + tiles: MapTiles; } interface ConsoleChatMessage extends FactorioObjectData { diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index 5956fa8..7e23e95 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -71,7 +71,6 @@ export namespace Converters { } } - export function mapChunkPosition(mapPos: ChunkPositionTable): MapChunkPosition { return { x: mapPos.x, @@ -103,8 +102,16 @@ export namespace Converters { position: mapTilePosition(tile.position), prototypeName: tile.prototype.name, - surfaceIndex: tile.surface.index } } + // export function convertMapTilePositionToMapChunkPosition( + // tilePosition: TilePositionTable + // ): ChunkPositionTable { + // return { + // x: tilePosition.x / 32, + // y: tilePosition.y / 32, + // } + // } + } diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index 22a6f10..ffebbf8 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -50,23 +50,25 @@ export function handleConsoleChat( emitEvent(table, tick, eventType) } -const CHUNK_SIZE = 32 +// const CHUNK_SIZE = 32 export function handleChunkUpdate( tick: uint, eventType: string, surfaceIndex: uint, - position: ChunkPositionTable + position: ChunkPositionTable, + area: BoundingBoxTable, ) { let surface = game.get_surface(surfaceIndex) - let x = (position as ChunkPositionTable).x * CHUNK_SIZE - let y = (position as ChunkPositionTable).y * CHUNK_SIZE + // let x = (position as ChunkPositionTable).x * CHUNK_SIZE + // let y = (position as ChunkPositionTable).y * CHUNK_SIZE let tiles: LuaTile[] = surface?.find_tiles_filtered({ - position: {x: x, y: y}, - radius: CHUNK_SIZE, + area: area, + // position: {x: x, y: y}, + // radius: CHUNK_SIZE, collision_mask: ["ground-tile", "water-tile"] } ) ?? [] @@ -77,9 +79,47 @@ export function handleChunkUpdate( let mapChunk: MapChunk = { objectName: "MapChunk", - tiles: convertedTiles, + tiles: createMapTiles(surfaceIndex, convertedTiles), position: mapChunkPosition(position) } emitEvent(mapChunk, tick, eventType) } + +export function handleTilesUpdate( + tick: uint, + eventType: string, + surfaceIndex: uint, + newTileType: LuaTilePrototype, + updatedTiles: OldTileAndPosition[], +) { + + if (!newTileType.collision_mask["ground-tile"] && !newTileType.collision_mask["water-tile"]) { + return + } else { + + let convertedTiles: MapTile[] = updatedTiles.map((it) => { + return { + objectName: "LuaTile", + position: it.position, + prototypeName: newTileType.name, + surfaceIndex: surfaceIndex + } + }) + + let mapTiles: MapTiles = createMapTiles(surfaceIndex, convertedTiles) + + emitEvent(mapTiles, tick, eventType) + } +} + +function createMapTiles( + surfaceIndex: uint, + tiles: MapTile[], +): MapTiles { + return { + objectName: "LuaTiles", + surfaceIndex: surfaceIndex, + tiles: tiles, + } +} diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index 9ff6950..faa7e2e 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -3,8 +3,11 @@ import { handleConsoleChat, handleEntityUpdate, handlePlayerUpdate, - handleSurfaceUpdate + handleSurfaceUpdate, + handleTilesUpdate } from "./handlers"; +import on_player_built_tile = defines.events.on_player_built_tile; +import on_robot_built_tile = defines.events.on_robot_built_tile; const mapEventIdToName = new LuaTable() for (const [k, v] of pairs(defines.events)) { @@ -62,6 +65,19 @@ script.on_event( script.on_event( defines.events.on_chunk_generated, (e: OnChunkGeneratedEvent) => { - handleChunkUpdate(e.tick, mapEventIdToName.get(e.name), e.surface.index, e.position) + handleChunkUpdate(e.tick, mapEventIdToName.get(e.name), e.surface.index, e.position, e.area) + } +) + +script.on_event( + [on_player_built_tile, on_robot_built_tile], + (builtTilesEvent) => { + handleTilesUpdate( + builtTilesEvent.tick, + mapEventIdToName.get(builtTilesEvent.name), + builtTilesEvent.surface_index, + builtTilesEvent.tile, + builtTilesEvent.tiles, + ) } ) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt index 0b8c3c6..2ab170a 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -38,6 +38,7 @@ sealed class FactorioObjectData { LuaSurface, MapChunk, LuaTile, + LuaTiles, ConsoleChatMessage, } } @@ -63,6 +64,7 @@ object FactorioObjectDataSerializer : JsonContentPolymorphicSerializer SurfaceData.serializer() FactorioObjectData.ObjectName.MapChunk -> MapChunk.serializer() FactorioObjectData.ObjectName.LuaTile -> MapTile.serializer() + FactorioObjectData.ObjectName.LuaTiles -> MapTiles.serializer() FactorioObjectData.ObjectName.ConsoleChatMessage -> ConsoleChatMessage.serializer() null -> throw Exception("Unknown FactorioObjectData $key: '$type' ") @@ -112,21 +114,30 @@ data class SurfaceData( override val objectName = ObjectName.LuaSurface } -/** Quasi-object. This isn't a Factorio Lua type, but a helpful collection of [MapTile]s */ +/** This isn't a Factorio Lua type, but a helpful collection of Chunk info */ @Serializable data class MapChunk( - val tiles: List, + val tiles: MapTiles, val position: MapChunkPosition, ) : FactorioObjectData() { @EncodeDefault override val objectName = ObjectName.MapChunk } +/** This isn't a Factorio Lua type, but a helpful collection of [MapTile]s */ +@Serializable +data class MapTiles( + val surfaceIndex: Int, + val tiles: List, +) : FactorioObjectData() { + @EncodeDefault + override val objectName = ObjectName.LuaTiles +} + @Serializable data class MapTile( val prototypeName: String, val position: MapTilePosition, - val surfaceIndex: Int, ) : FactorioObjectData() { @EncodeDefault override val objectName = ObjectName.LuaTile diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt index 9b81385..085559c 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt @@ -19,7 +19,6 @@ class FactorioEventTest : FunSpec({ "characterUnitNumber": 1, "associatedCharactersUnitNumbers": {}, "position": { - "type": "MAP", "x": 30.6, "y": 84.1 }, @@ -53,8 +52,7 @@ class FactorioEventTest : FunSpec({ name = "fredthedeadhead", characterUnitNumber = 1u, associatedCharactersUnitNumbers = emptyList(), - position = PositionData( - type = PositionType.MAP, + position = MapEntityPosition( x = 30.6, y = 84.1, ), @@ -148,7 +146,6 @@ class FactorioEventTest : FunSpec({ "surfaceIndex": 1, "unitNumber": 1, "position": { - "type": "MAP", "x": 37.5, "y": 81.1 } @@ -174,10 +171,9 @@ class FactorioEventTest : FunSpec({ surfaceIndex = 1, unitNumber = 1u, playerIndex = null, - position = PositionData( + position = MapEntityPosition( x = 37.5, y = 81.1, - type = PositionType.MAP, ) ), eventType = "on_player_changed_position", From b5de2132a1200a76389d17eb5a5d266b5af4dcf1 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 17:40:38 +0100 Subject: [PATCH 146/629] version bump --- build.gradle.kts | 2 +- modules/events-mod/src/main/typescript/package-lock.json | 2 +- modules/events-mod/src/main/typescript/package.json | 2 +- modules/infra-factorio-server/src/.env | 2 +- modules/infra-kafka-cluster/src/.env | 2 +- modules/infra-kafka-pipe/src/.env | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index dc3d0f9..fd005aa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.2.1" +version = "0.2.2" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index 64e6fc4..e164848 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.1", + "version": "0.2.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 68acb70..c769a23 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.1", + "version": "0.2.2", "private": true, "scripts": { "build": "tstl", diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index 97202e7..2b7d71e 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio FACTORIO_VERSION=1.1.50 -KAFKATORIO_VERSION=0.2.1 +KAFKATORIO_VERSION=0.2.2 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index cac708d..7425adc 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.2.1 +KAFKATORIO_VERSION=0.2.2 diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index cac708d..7425adc 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.2.1 +KAFKATORIO_VERSION=0.2.2 From d2aa961e1ae2b28cc670e6cacac66d101c83167a Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 17:46:17 +0100 Subject: [PATCH 147/629] add version header to kafka pipe messages --- modules/infra-kafka-pipe/src/kafka-pipe.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/infra-kafka-pipe/src/kafka-pipe.sh b/modules/infra-kafka-pipe/src/kafka-pipe.sh index b155266..f9fc1ce 100644 --- a/modules/infra-kafka-pipe/src/kafka-pipe.sh +++ b/modules/infra-kafka-pipe/src/kafka-pipe.sh @@ -17,7 +17,11 @@ INSTANCE_ID=$(cat /proc/sys/kernel/random/uuid) while :; do docker logs --tail 0 -f "$FACTORIO_SERVER_CONTAINER_NAME" | sed -n -e 's/^KafkatorioPacket: //p' | - kcat -P -T -b "$KAFKA_HOST" -t factorio-server-log -k "$INSTANCE_ID" + kcat -P -T \ + -b "$KAFKA_HOST" \ + -t factorio-server-log \ + -k "$INSTANCE_ID" \ + -H "KAFKA-PIPE-VERSION=$KAFKATORIO_VERSION" echo "Error - retrying in 10 seconds" sleep 10 From 27c8088f4136d9abe59663970677bdfa42f4bc42 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 18:05:28 +0100 Subject: [PATCH 148/629] maybe fix docker build for kafka pipe?? --- modules/infra-kafka-pipe/build.gradle.kts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index 89066a3..d183740 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -22,7 +22,20 @@ val dockerBuildKafkaPipe by tasks.registering(Exec::class) { inputs.dir(dockerSrcDir) + val imageIdFile = file("$temporaryDir/docker-image-id.txt") + outputs.file(imageIdFile) + workingDir = dockerSrcDir.asFile commandLine = parseSpaceSeparatedArgs(""" docker-compose build kafka-pipe """) + + doLast { + imageIdFile.outputStream().use { os -> + exec { + workingDir = dockerSrcDir.asFile + commandLine = parseSpaceSeparatedArgs(""" docker-compose images -q kafka-pipe """) + standardOutput = os + } + } + } } -//tasks.assemble { dependsOn(dockerBuildKafkaPipe) } +tasks.assemble { dependsOn(dockerBuildKafkaPipe) } From 1439e816282c94613d28df17e1936fcb1d9a0428 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 18:48:32 +0100 Subject: [PATCH 149/629] maybe fix docker build for kafka pipe?? again???? --- modules/infra-kafka-pipe/build.gradle.kts | 37 ++++++++++++++++------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index d183740..e2878bb 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -1,3 +1,4 @@ +import org.jetbrains.kotlin.incremental.md5 import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { @@ -8,6 +9,11 @@ description = "Send events from a Factorio server to a Kafka topic " val dockerSrcDir: Directory by extra +fun Directory.filesChecksum() = asFileTree + .files + .map { it.readBytes() + it.absolutePath.toByteArray() } + .fold(byteArrayOf()) { acc, bytes -> acc + bytes } + .md5() tasks.dockerUp { dependsOn(":modules:infra-kafka-cluster:dockerUp") @@ -21,21 +27,30 @@ val dockerBuildKafkaPipe by tasks.registering(Exec::class) { dependsOn(tasks.dockerEnv) inputs.dir(dockerSrcDir) + inputs.property("dockerSrcDirChecksum") { dockerSrcDir.filesChecksum() } - val imageIdFile = file("$temporaryDir/docker-image-id.txt") - outputs.file(imageIdFile) + outputs.upToDateWhen { + it.inputs.properties["dockerSrcDirChecksum"] as? Long? == dockerSrcDir.filesChecksum() + } + +// val imageIdFile = file("$temporaryDir/docker-image-id.txt") +// outputs.file(imageIdFile) workingDir = dockerSrcDir.asFile commandLine = parseSpaceSeparatedArgs(""" docker-compose build kafka-pipe """) - doLast { - imageIdFile.outputStream().use { os -> - exec { - workingDir = dockerSrcDir.asFile - commandLine = parseSpaceSeparatedArgs(""" docker-compose images -q kafka-pipe """) - standardOutput = os - } - } - } +// doLast { +// sync { +// from(dockerSrcDir) +// into(temporaryDir) +// } +// imageIdFile.outputStream().use { os -> +// exec { +// workingDir = dockerSrcDir.asFile +// commandLine = parseSpaceSeparatedArgs(""" docker-compose images -q kafka-pipe """) +// standardOutput = os +// } +// } +//} } tasks.assemble { dependsOn(dockerBuildKafkaPipe) } From 723c7ae6e8d06dabe1686f97e40932a29f212bcf Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 19:01:47 +0100 Subject: [PATCH 150/629] test LuaTiles --- .../events/schema/FactorioEventTest.kt | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt index 085559c..65c291c 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt @@ -193,4 +193,97 @@ class FactorioEventTest : FunSpec({ } } + + context("Given: LuaTiles on_player_built_tile") { + // language=JSON + val json = """ + { + "data": { + "objectName": "LuaTiles", + "surfaceIndex": 1, + "tiles": [ + { + "objectName": "LuaTile", + "position": { + "y": 10, + "x": -65 + }, + "prototypeName": "refined-concrete" + }, + { + "objectName": "LuaTile", + "position": { + "y": 11, + "x": -65 + }, + "prototypeName": "refined-concrete" + }, + { + "objectName": "LuaTile", + "position": { + "y": 10, + "x": -64 + }, + "prototypeName": "refined-concrete" + }, + { + "objectName": "LuaTile", + "position": { + "y": 11, + "x": -64 + }, + "prototypeName": "refined-concrete" + } + ] + }, + "packetType": "EVENT", + "eventType": "on_player_built_tile", + "modVersion": "0.2.2", + "tick": 2429929 + } + """.trimIndent() + context("When: decoded") { + val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) + + test("parse") { + + val expected = FactorioEvent( + data = MapTiles( + surfaceIndex = 1, + tiles = listOf( + MapTile( + prototypeName = "refined-concrete", + position = MapTilePosition(-65, 10) + ), + MapTile( + prototypeName = "refined-concrete", + position = MapTilePosition(-65, 11) + ), + MapTile( + prototypeName = "refined-concrete", + position = MapTilePosition(-64, 10) + ), + MapTile( + prototypeName = "refined-concrete", + position = MapTilePosition(-64, 11) + ), + ) + ), + eventType = "on_player_built_tile", + modVersion = "0.2.2", + tick = 2429929u + ) + + actual shouldBe expected + + expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaTiles + } + + test("Then: expect encode equals json") { + val encoded = jsonMapperKafkatorio.encodeToString(actual) + encoded.shouldEqualJson(json) + } + } + + } }) From a8b13be110f3ce50ce148c8323f773df392b0564 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 19:07:51 +0100 Subject: [PATCH 151/629] remove extra field (is there a better way to prevent this?) --- modules/events-mod/src/main/typescript/main/events/handlers.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index ffebbf8..9197f56 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -103,7 +103,6 @@ export function handleTilesUpdate( objectName: "LuaTile", position: it.position, prototypeName: newTileType.name, - surfaceIndex: surfaceIndex } }) From 9acce508ea91c22efdc945867df1f67f4efbbb08 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 9 Jan 2022 19:09:40 +0100 Subject: [PATCH 152/629] don't use Jansi --- modules/events-server/src/main/resources/logback.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/events-server/src/main/resources/logback.xml b/modules/events-server/src/main/resources/logback.xml index 658a6ae..4c3eb02 100644 --- a/modules/events-server/src/main/resources/logback.xml +++ b/modules/events-server/src/main/resources/logback.xml @@ -1,7 +1,7 @@ - true + false @@ -18,4 +18,4 @@ - \ No newline at end of file + From 49ad3654a34e4290bff884f6c9545a0d34464977 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 13 Jan 2022 00:00:59 +0100 Subject: [PATCH 153/629] tiles from kafka -> image tiles... maybe??? --- README.md | 4 + build.gradle.kts | 2 +- .../kafkatorio-schema/prototype.d.ts | 4 +- .../main/config-update/convertPrototypes.ts | 8 +- .../events/schema/factorioCommonData.kt | 30 +- .../events/schema/factorioPrototypes.kt | 6 +- modules/events-server/build.gradle.kts | 3 +- .../kafkastreams/GlobalKTableDefinition.kt | 31 ++ .../kafkastreams/KStreamExtensions.kt | 111 ++++++ .../kafkastreams/KStreamTransform.kt | 90 +++++ .../kafkastreams/KTableExtensions.kt | 19 + .../kafkastreams/KafkaStreamsExtensions.kt | 93 +++++ .../kafkastreams/KeyPairExtensions.kt | 35 ++ .../extensions/kafkastreams/KeyValueSerdes.kt | 40 +++ .../KotlinxSerializationExtensions.kt | 55 +++ .../extensions/kafkastreams/TopicData.kt | 17 + .../kafkastreams/TopicDefinition.kt | 42 +++ .../extensions/kafkastreams/aliases.kt | 7 + .../processor/KafkatorioTopology.kt | 330 ++++++++++++++++-- .../dev/adamko/kafkatorio/processor/serdes.kt | 3 +- .../processor/topology/FactorioGameState.kt | 68 ++++ 21 files changed, 961 insertions(+), 37 deletions(-) create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/GlobalKTableDefinition.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamExtensions.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamTransform.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KTableExtensions.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KafkaStreamsExtensions.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyPairExtensions.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyValueSerdes.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KotlinxSerializationExtensions.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicData.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicDefinition.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/aliases.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioGameState.kt diff --git a/README.md b/README.md index 022a03a..43670cc 100644 --- a/README.md +++ b/README.md @@ -58,3 +58,7 @@ https://www.npmjs.com/package/wasm2lua?activeTab=readme * CBOR * https://www.zash.se/lua-cbor.html * https://code.zash.se/lua-cbor/archive/68b3a36d0816.tar.gz + +* BSON + * https://github.com/mpaland/bsonfy + * https://github.com/tcoram/bson-lua diff --git a/build.gradle.kts b/build.gradle.kts index fd005aa..fcb9c04 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.2.2" +version = "0.2.3" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts index e4d4067..67464d8 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts @@ -6,11 +6,11 @@ interface FactorioPrototype { prototypeObjectName: PrototypeObjectName; } -interface FactorioMapTilePrototype extends FactorioPrototype { +interface MapTilePrototype extends FactorioPrototype { canBeMined: boolean; collisionMasks: string[]; layer: uint; - mapColor: Colour; + mapColour: Colour; name: string; order: string; prototypeObjectName: PrototypeObjectName; diff --git a/modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts b/modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts index a3b803f..b9c6203 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts @@ -8,18 +8,18 @@ export function convertPrototypes(): FactorioPrototype[] { return prototypes } -function getMapTilePrototypes(): FactorioMapTilePrototype[] { - let tiles: FactorioMapTilePrototype[] = [] +function getMapTilePrototypes(): MapTilePrototype[] { + let tiles: MapTilePrototype[] = [] for (let [, tile] of pairs(game.tile_prototypes)) { tiles.push( - { + { prototypeObjectName: tile.object_name, name: tile.name, order: tile.order, layer: tile.layer, collisionMasks: convertCollisionMaskToNames(tile.collision_mask), - mapColor: Converters.mapColour(tile.map_color), + mapColour: Converters.mapColour(tile.map_color), canBeMined: tile.mineable_properties.minable, } ) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index 8633fc3..1c4854b 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -54,13 +54,19 @@ data class MapTilePosition( val y: Int, ) { constructor(x: Number, y: Number) : this(x.toInt(), y.toInt()) + + fun toMapChunkPosition() = MapChunkPosition( + x / MAP_CHUNK_SIZE, + y / MAP_CHUNK_SIZE, + ) + } /** * Red, green, blue and alpha values, all in range `[0, 1]` or all in range `[0, 255]` if any * value is > 1. * - * All values here are optional. Color channels default to 0, the alpha channel defaults to 1. + * All values here are optional. Colour channels default to 0, the alpha channel defaults to 1. */ @Serializable data class Colour( @@ -85,4 +91,26 @@ data class Colour( /** True if all values are between `[0..1]`. */ fun isPercentage(): Boolean = !isDecimal() + fun asDecimal() = if (isPercentage()) { + Colour( + (red * 255).coerceIn(0f..255f), + (green * 255).coerceIn(0f..255f), + (blue * 255).coerceIn(0f..255f), + (alpha * 255).coerceIn(0f..255f), + ) + } else { + this + } + + fun asPercentage() = if (isPercentage()) { + this + } else { + Colour( + (red / 255).coerceIn(0f..1f), + (green / 255).coerceIn(0f..1f), + (blue / 255).coerceIn(0f..1f), + (alpha / 255).coerceIn(0f..1f), + ) + } + } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt index 8cedb60..ea820a4 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt @@ -36,7 +36,7 @@ object FactorioPrototypeSerializer : JsonContentPolymorphicSerializer FactorioMapTilePrototype.serializer() + FactorioPrototype.PrototypeObjectName.LuaTilePrototype -> MapTilePrototype.serializer() null -> throw Exception("Unknown FactorioPrototype $key: '$type' ") } @@ -45,10 +45,10 @@ object FactorioPrototypeSerializer : JsonContentPolymorphicSerializer, val order: String, /** Can the tile be mined for resources? */ diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index f1e7b8c..2495d2f 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -31,10 +31,11 @@ dependencies { implementation(platform(libs.http4k.bom)) implementation(libs.bundles.http4k) - implementation(libs.http4k.format.kotlinx) implementation(libs.bundles.logging) + + implementation("com.sksamuel.scrimage:scrimage-core:4.0.24") } application { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/GlobalKTableDefinition.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/GlobalKTableDefinition.kt new file mode 100644 index 0000000..d2b3fb7 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/GlobalKTableDefinition.kt @@ -0,0 +1,31 @@ +package dev.adamko.kafkatorio.extensions.kafkastreams + +import org.apache.kafka.streams.state.QueryableStoreTypes.timestampedKeyValueStore + +/** + * * update topic [topicName] + * * plus table-source topic [tableName] + * * plus state store [globalStoreName] + * + * equals a GlobalTableDefinition + */ +abstract class GlobalKTableDefinition( + val tableName: String, + override val serdes: KeyValueSerdes, + val globalStoreName: String = "$tableName-store", + /** + * The backing topic, from which this table will be filled. + * + * Updates to items can be sent or received with this topic. + */ + final override val topicName: String = "$tableName-topic", + val storeType: TimestampedQueryStoreType = timestampedKeyValueStore(), +) : TopicDefinition { + val topicNames: Set + + init { + require(tableName != topicName) + require(tableName != globalStoreName) + topicNames = setOf(tableName, topicName) + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamExtensions.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamExtensions.kt new file mode 100644 index 0000000..28d1541 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamExtensions.kt @@ -0,0 +1,111 @@ +package dev.adamko.kafkatorio.extensions.kafkastreams + +import dev.adamko.kafkatorio.extensions.kafkastreams.KStreamExtensions.flatMap +import dev.adamko.kafkatorio.extensions.kafkastreams.KStreamExtensions.groupBy +import dev.adamko.kafkatorio.extensions.kafkastreams.KStreamExtensions.map +import dev.adamko.kafkatorio.extensions.kafkastreams.KStreamExtensions.mapValues +import dev.adamko.kafkatorio.extensions.kafkastreams.KafkaStreamsExtensions.withName +import dev.adamko.kafkatorio.extensions.kafkastreams.KeyPairExtensions.kvPair +import dev.adamko.kafkatorio.extensions.kafkastreams.KeyPairExtensions.toKeyValue +import org.apache.kafka.streams.KeyValue +import org.apache.kafka.streams.kstream.Grouped +import org.apache.kafka.streams.kstream.KGroupedStream +import org.apache.kafka.streams.kstream.KStream +import org.apache.kafka.streams.kstream.Transformer +import org.apache.kafka.streams.processor.ProcessorContext + +object KStreamExtensions { + +// /** @see KStream.map */ +// inline fun > KStream.map( +// name: String, +// crossinline mapper: (key: inK, value: inV) -> outV +// ): KStream = +// map({ k, v -> mapper(k, v).asKeyValue() }, withName(name)) + + /** @see KStream.map */ + inline fun KStream.map( + name: String, + crossinline mapper: (key: inK, value: inV) -> Pair + ): KStream = + map({ k, v -> mapper(k, v).toKeyValue() }, withName(name)) + + /** Wrapper for [KStream.mapValues] */ + fun KStream.mapValues( + name: String, + mapper: (key: K, value: inV) -> outV + ): KStream = + mapValues({ k, v -> mapper(k, v) }, withName(name)) + +// /** @see KStream.flatMap */ +// inline fun > KStream.flatMap( +// name: String, +// crossinline mapper: (key: inK, value: inV) -> Iterable +// ): KStream = flatMap( +// { k, v -> mapper(k, v).map { a: outV -> a.asKeyValue() } }, +// withName(name) +// ) + + /** @see KStream.flatMap */ + inline fun KStream.flatMap( + name: String, + crossinline mapper: (key: inK, value: inV) -> Iterable> + ): KStream = flatMap( + { k, v -> mapper(k, v).map { it.toKeyValue() } }, + withName(name) + ) + + /** @see KStream.groupBy */ + inline fun KStream.groupBy( + grouped: Grouped, + crossinline keySelector: KeyValue.() -> outK + ): KGroupedStream = + groupBy( + { k, v -> (k kvPair v).keySelector() }, + grouped + ) + + + +// @JvmName("flatMapKeyValuePairs") +// inline fun KStream.flatMap( +// name: String, +// crossinline mapper: (key: inK, value: inV) -> Iterable> +// ): KStream = +// flatMap( +// { k, v -> mapper(k, v).map { it.asKeyPair() } }, +// withName(name) +// ) + +// inline fun KStream.mapValues( +// name: String, +// crossinline mapper: (readOnlyKey: K, value: inV) -> outV +// ): KStream = +// map({ k, v -> (k to mapper(v)).asKeyPair() }, KafkaStreamsExtensions.withName(name)) + +} + + +//open class TransformerKt( +//) : Transformer> { +// +// val onClose: TransformerKt.() -> Unit = {} +// val transformer: TransformerKt.(key: inK, value: inV) -> KeyValue? = +// {} +// +// private lateinit var _context: ProcessorContext +// val context: ProcessorContext? +// get() = if (this::_context.isInitialized) _context else null +// +// override fun init(context: ProcessorContext) { +// this._context = context +// } +// +// override fun close() { +// onClose() +// } +// +// override fun transform(key: inK, value: inV): KeyValue? { +// return transformer(key, value) +// } +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamTransform.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamTransform.kt new file mode 100644 index 0000000..b6cfd63 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamTransform.kt @@ -0,0 +1,90 @@ +package dev.adamko.kafkatorio.extensions.kafkastreams + +import dev.adamko.kafkatorio.extensions.kafkastreams.KeyPairExtensions.toKeyValue +import kotlin.experimental.ExperimentalTypeInference +import org.apache.kafka.streams.KeyValue +import org.apache.kafka.streams.kstream.KStream +import org.apache.kafka.streams.kstream.Transformer +import org.apache.kafka.streams.kstream.TransformerSupplier +import org.apache.kafka.streams.processor.ProcessorContext + +/** @see KStream.transform */ +inline fun KStream.transformKt( + crossinline block: BuildTransformer +): KStream { + + val transformer = object : Transformer> { + + private lateinit var scope: TransformerScope + + override fun init(procContext: ProcessorContext) { + scope = TransformerScope(procContext) + scope.block() + } + + override fun close() { + scope.close() + } + + override fun transform(key: inK, value: inV): KeyValue? { + return scope.mapper(key, value)?.toKeyValue() + } + } + + return transform({ transformer }) +} + +/** @see KStream.transform */ +@OptIn(ExperimentalTypeInference::class) +inline fun > KStream.transformKt2( + @BuilderInference block: Transformer.() -> Unit +): KStream { + + val transformer = object : Transformer> { + + private lateinit var scope: TransformerScope + + override fun init(procContext: ProcessorContext) { + scope = TransformerScope(procContext) + } + + override fun close() { + scope.close() + + sequence { + + } + } + + override fun transform(key: inK, value: inV): KeyValue? { + return scope.mapper(key, value)?.toKeyValue() + } + } + + return transform(TransformerSupplier { transformer }) +} + +typealias BuildTransformer = TransformerScope.() -> Unit + +typealias TransformerMapper = (key: inK, value: inV) -> Pair? +typealias TransformerCloseHandler = (ProcessorContext) -> Unit + +open class TransformerScope( + val processorContext: ProcessorContext, +) : AutoCloseable { + + private var closeHandler: TransformerCloseHandler = {} + lateinit var mapper: TransformerMapper + + fun handleClose(closeHandler: TransformerCloseHandler) { + this.closeHandler = closeHandler + } + + fun mapEach(mapper: TransformerMapper) { + this.mapper = mapper + } + + override fun close() { + closeHandler(processorContext) + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KTableExtensions.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KTableExtensions.kt new file mode 100644 index 0000000..c573dd3 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KTableExtensions.kt @@ -0,0 +1,19 @@ +package dev.adamko.kafkatorio.extensions.kafkastreams + +import dev.adamko.kafkatorio.extensions.kafkastreams.KTableExtensions.mapValues +import dev.adamko.kafkatorio.extensions.kafkastreams.KafkaStreamsExtensions.withName +import org.apache.kafka.streams.kstream.KTable + +object KTableExtensions { + + /** @see [KTable.mapValues] */ + fun KTable.mapValues( + name: String, + mapper: (readOnlyKey: K, value: inV) -> outV + ): KTable = + mapValues( + { k, v -> mapper(k, v) }, + withName(name) + ) + +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KafkaStreamsExtensions.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KafkaStreamsExtensions.kt new file mode 100644 index 0000000..1bea403 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KafkaStreamsExtensions.kt @@ -0,0 +1,93 @@ +package dev.adamko.kafkatorio.extensions.kafkastreams + +import org.apache.kafka.common.serialization.Serde +import org.apache.kafka.streams.kstream.Grouped +import org.apache.kafka.streams.kstream.Joined +import org.apache.kafka.streams.kstream.Materialized +import org.apache.kafka.streams.kstream.Named +import org.apache.kafka.streams.kstream.Produced +import org.apache.kafka.streams.kstream.Repartitioned +import org.apache.kafka.streams.processor.StateStore + +/** Helpful extensions & shortcuts for Kafka Streams */ +object KafkaStreamsExtensions { + + /** @see [Named] */ + fun withName(name: String): Named = Named.`as`(name) + +// @Suppress("FunctionName") +// inline fun MaterializedAs( +// tableDefinition: GlobalTableDefinition +// ) = MaterializedAs( +// tableDefinition.globalStoreName, +// tableDefinition.serdes.keySerde, +// tableDefinition.serdes.valueSerde +// ) + + /** @see Materialized */ + inline fun materializedAs( + name: String, + keySerde: Serde,//= kxsJsonSerde(), + valueSerde: Serde,//= kxsJsonSerde(), + ): Materialized = + Materialized.`as`(name) + .withKeySerde(keySerde) + .withValueSerde(valueSerde) + + /** @see Repartitioned */ + inline fun repartitionedAs( + name: String, + keySerde: Serde, + valueSerde: Serde, + ): Repartitioned = + Repartitioned.`as`(name) + .withKeySerde(keySerde) + .withValueSerde(valueSerde) + + /** @see Produced */ + fun producedAs(name: String): Produced = + Produced.`as`(name) + + /** @see Produced */ + inline fun producedAs( + name: String, + keySerde: Serde, + valueSerde: Serde, + ): Produced = + producedAs(name) + .withKeySerde(keySerde) + .withValueSerde(valueSerde) + +// @Suppress("FunctionName") +// fun JoinedAs(name: String): Joined = +// Joined.`as`(name) + + /** @see Joined */ + inline fun joinedAs( + name: String, + keySerde: Serde,// = kxsJsonSerde(), + valueSerde: Serde,//= kxsJsonSerde(), + otherValueSerde: Serde?,//= kxsJsonSerde(), + ): Joined = + Joined.`as`(name) + .withKeySerde(keySerde) + .withValueSerde(valueSerde) + .withOtherValueSerde(otherValueSerde) + + /** @see [Grouped.`as`] */ + inline fun groupedAs( + name: String, + keySerde: Serde?, //= kxsJsonSerde(), + valueSerde: Serde?,// = kxsJsonSerde(), + ): Grouped = + Grouped.`as`(name) + .withKeySerde(keySerde) + .withValueSerde(valueSerde) + +// fun InteractiveQueryService.getQueryableStore( +// tableDef: GlobalTableDefinition +// ): Optional>> { +// return getQueryableStore(tableDef.globalStoreName, tableDef.storeType) +// } + +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyPairExtensions.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyPairExtensions.kt new file mode 100644 index 0000000..0bb1d21 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyPairExtensions.kt @@ -0,0 +1,35 @@ +package dev.adamko.kafkatorio.extensions.kafkastreams + +import org.apache.kafka.streams.KeyValue +import org.apache.kafka.streams.state.ValueAndTimestamp + +object KeyPairExtensions { + + inline fun Pair.toKeyValue(): KeyValue = + KeyValue.pair(first, second) + + infix fun K.kvPair(value: V): KeyValue = KeyValue(this, value) + + infix fun V.timestamped(timestamp: Long): ValueAndTimestamp = + ValueAndTimestamp.make(this, timestamp) + + + @JvmName("keyValueGetKey") + operator fun KeyValue.component1(): K = key + @JvmName("keyValueGetValue") + operator fun KeyValue.component2(): V = value + + + @JvmName("keyValueTimestampGetKey") + operator fun KeyValue>.component1(): K = key + @JvmName("keyValueTimestampGetValue") + operator fun KeyValue>.component2(): V = value.value() + @JvmName("keyValueTimestampGetTimestamp") + operator fun KeyValue>.component3(): Long = value.timestamp() + + + @JvmName("valueTimestampGetValue") + operator fun ValueAndTimestamp.component1(): V = value() + @JvmName("valueTimestampGetTimestamp") + operator fun ValueAndTimestamp.component2(): Long = timestamp() +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyValueSerdes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyValueSerdes.kt new file mode 100644 index 0000000..431af7f --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyValueSerdes.kt @@ -0,0 +1,40 @@ +package dev.adamko.kafkatorio.extensions.kafkastreams + +import dev.adamko.kafkatorio.extensions.kafkastreams.KotlinxSerializationExtensions.kxsJsonSerde +import org.apache.kafka.common.serialization.Serde +import org.apache.kafka.common.serialization.Serdes +import org.apache.kafka.streams.kstream.Consumed +import org.apache.kafka.streams.kstream.Produced +import org.apache.kafka.streams.kstream.Repartitioned + +/** + * A wrapper for two [Serde]s - [one for the Key][keySerde], [another for the Value][valueSerde]. + */ +open class KeyValueSerdes( + val keySerde: Serde, + val valueSerde: Serde, +) { + + fun consumer(name: String): Consumed = + Consumed.with(keySerde, valueSerde).withName(name) + + fun producer(name: String): Produced = + Produced.with(keySerde, valueSerde).withName(name) + + fun repartitioned(name: String): Repartitioned = + Repartitioned.with(keySerde, valueSerde).withName(name) + + companion object { + inline fun kxsJson(): KeyValueSerdes = + KeyValueSerdes( + kxsJsonSerde(), + kxsJsonSerde(), + ) + + fun string(): KeyValueSerdes = + KeyValueSerdes( + Serdes.String(), + Serdes.String(), + ) + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KotlinxSerializationExtensions.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KotlinxSerializationExtensions.kt new file mode 100644 index 0000000..86acd86 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KotlinxSerializationExtensions.kt @@ -0,0 +1,55 @@ +package dev.adamko.kafkatorio.extensions.kafkastreams + +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import org.apache.kafka.common.serialization.Deserializer +import org.apache.kafka.common.serialization.Serde +import org.apache.kafka.common.serialization.Serializer + +object KotlinxSerializationExtensions { + + inline fun Json.kafkaSerializer() = Serializer { topic: String, data: T -> + runCatching { + encodeToString(data).encodeToByteArray() +// jsonMapper.encodeToString(data as T).encodeToByteArray() + }.getOrElse { e -> + println( + """ + Exception on encodeToString + Topic: $topic + topicData: $data + topicData as T: ${data as T} + """.trimIndent() + ) + e.printStackTrace() + throw e + } + } + + inline fun Json.kafkaDeserializer() = Deserializer { topic: String, data: ByteArray -> + runCatching { + decodeFromString(data.decodeToString()) + }.getOrElse { e -> + println( + """ + Exception on decodeFromString, + Topic: $topic + topicData: $data + topicData as T: ${data as T} + """.trimIndent() + ) + e.printStackTrace() + throw e + } + } + + + inline fun Json.serde() = object : Serde { + + override fun serializer(): Serializer = kafkaSerializer() + + override fun deserializer(): Deserializer = kafkaDeserializer() + } + +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicData.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicData.kt new file mode 100644 index 0000000..dd23620 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicData.kt @@ -0,0 +1,17 @@ +package dev.adamko.kafkatorio.extensions.kafkastreams + +import org.apache.kafka.streams.KeyValue + +interface TopicData { + + val topicKey: K + + companion object { + fun > T.toPair(): Pair = topicKey to this + fun > T.toKeyValue(): KeyValue = KeyValue.pair(topicKey, this) + + operator fun > T.component1(): K = topicKey + operator fun > T.component2(): T = this + + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicDefinition.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicDefinition.kt new file mode 100644 index 0000000..49ce40f --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicDefinition.kt @@ -0,0 +1,42 @@ +package dev.adamko.kafkatorio.extensions.kafkastreams; + +/** + * A definition for all topics that are created in Kafka. + * + * These can be used to create KTopics, KTables, or GlobalKTables. + */ +interface TopicDefinition { + + /** unique kafka processor id */ + val pid: String + get() = this::class.simpleName!! + + /** + * Unique name for each [TopicDefinition] + * + * https://devshawn.com/blog/apache-kafka-topic-naming-conventions/ + * + * https://www.xeotek.com/topic-naming-conventions-how-do-i-name-my-topics-5-recommendations-with-examples/ + * + * Domain: warehouse + * Operation: stock-management + * Data type: + * - cdc=all instances of a specific object/thing/item, + * - cmd=command (mutation), + * - fct=fact (information (complete or partial) + * about an event at specific point in time) + * - sys=internal system topic - not meant for external use + * - tbl=a global table store (must be paired with another topic) + * Description: the data type + * + * Version: stored in message header + * + * ``` + * warehouse.stock-management.sts/cdc/cmd.warehouse-item + * ``` + */ + val topicName: String + + val serdes: KeyValueSerdes + +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/aliases.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/aliases.kt new file mode 100644 index 0000000..8461387 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/aliases.kt @@ -0,0 +1,7 @@ +package dev.adamko.kafkatorio.extensions.kafkastreams + +import org.apache.kafka.streams.state.QueryableStoreType +import org.apache.kafka.streams.state.ReadOnlyKeyValueStore +import org.apache.kafka.streams.state.ValueAndTimestamp + +typealias TimestampedQueryStoreType = QueryableStoreType>> diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 914a02b..c80da00 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -1,17 +1,44 @@ package dev.adamko.kafkatorio.processor +import com.sksamuel.scrimage.ImmutableImage +import com.sksamuel.scrimage.nio.PngWriter +import com.sksamuel.scrimage.pixels.Pixel +import com.sksamuel.scrimage.pixels.PixelTools import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.FactorioObjectData import dev.adamko.kafkatorio.events.schema.KafkatorioPacket +import dev.adamko.kafkatorio.events.schema.MapChunk +import dev.adamko.kafkatorio.events.schema.MapChunkPosition +import dev.adamko.kafkatorio.events.schema.MapTile +import dev.adamko.kafkatorio.events.schema.MapTilePosition +import dev.adamko.kafkatorio.events.schema.MapTilePrototype +import dev.adamko.kafkatorio.events.schema.MapTiles +import dev.adamko.kafkatorio.extensions.kafkastreams.KafkaStreamsExtensions.materializedAs +import dev.adamko.kafkatorio.extensions.kafkastreams.KeyPairExtensions.toKeyValue +import dev.adamko.kafkatorio.extensions.kafkastreams.KotlinxSerializationExtensions.serde +import dev.adamko.kafkatorio.extensions.kafkastreams.TopicData +import dev.adamko.kafkatorio.extensions.kafkastreams.TopicData.Companion.toKeyValue +import java.awt.image.BufferedImage +import java.io.File import java.time.Duration +import kotlin.math.roundToInt +import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import org.apache.kafka.common.serialization.Serdes import org.apache.kafka.streams.KafkaStreams +import org.apache.kafka.streams.StoreQueryParameters import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.TopologyDescription import org.apache.kafka.streams.kstream.Consumed +import org.apache.kafka.streams.kstream.KStream +import org.apache.kafka.streams.kstream.KTable import org.apache.kafka.streams.kstream.Produced +import org.apache.kafka.streams.state.QueryableStoreTypes +import org.apache.kafka.streams.state.ReadOnlyKeyValueStore +import org.apache.kafka.streams.state.ValueAndTimestamp + class KafkatorioTopology( private val websocketServer: WebsocketServer, @@ -20,36 +47,25 @@ class KafkatorioTopology( private val sourceTopic = "factorio-server-log" + private lateinit var tilePrototypesStore: ReadOnlyKeyValueStore> fun build() { - builder.stream( - sourceTopic, - Consumed.with(Serdes.String(), Serdes.String()) - ) - .mapValues { readOnlyKey, value -> - println("Mapping $readOnlyKey:$value") - jsonMapper.decodeFromString(value) - } - .peek { _, value -> - websocketServer.sendMessage(jsonMapper.encodeToString(value)) - } - .to( - { _, value, _ -> -// println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") - when (value) { - is FactorioEvent -> - "kafkatorio.${value.packetType.name}.${value.data.objectName.name}" - is FactorioConfigurationUpdate -> - "kafkatorio.${value.packetType.name}" - } - }, - Produced.with(Serdes.String(), KafkatorioPacketSerde) - ) + parseAndSplitServerLog() + sendPlayerUpdatesToWebSocket() +// createMapTileImages() + val tilePrototypesTable: KTable = tilePrototypesTable() val topology = builder.build() val streams = KafkaStreams(topology, appProps.kafkaConfig) + tilePrototypesStore = streams.store( + StoreQueryParameters.fromNameAndType( + tilePrototypesTable.queryableStoreName(), + QueryableStoreTypes.timestampedKeyValueStore() + ) + ) + streams.setUncaughtExceptionHandler(StreamsExceptionHandler()) Runtime.getRuntime().addShutdownHook(Thread { streams.close(Duration.ofSeconds(1)) }) @@ -62,4 +78,272 @@ class KafkatorioTopology( streams.start() } + private fun parseAndSplitServerLog() { + + builder.stream( + sourceTopic, + Consumed.with(Serdes.String(), Serdes.String()) + ) + .mapValues { readOnlyKey, value -> + println("Mapping $readOnlyKey:$value") + jsonMapper.decodeFromString(value) + } + .to( + { _, value, _ -> +// println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") + when (value) { + is FactorioEvent -> + "kafkatorio.${value.packetType.name}.${value.data.objectName.name}" + is FactorioConfigurationUpdate -> + "kafkatorio.${value.packetType.name}.FactorioConfigurationUpdate" + } + }, + Produced.with(Serdes.String(), KafkatorioPacketSerde) + ) + } + + private fun sendPlayerUpdatesToWebSocket() { + builder.stream( + "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaPlayer}", + Consumed.with(Serdes.String(), KafkatorioPacketSerde) + ) + .foreach { _, value -> + websocketServer.sendMessage(jsonMapper.encodeToString(value)) + } + } + + private fun tilePrototypesTable(): KTable { + return builder.stream( + "kafkatorio.${KafkatorioPacket.PacketType.CONFIG}.FactorioConfigurationUpdate", + Consumed.with(Serdes.String(), jsonMapper.serde()) + ) + .flatMap { _, update: FactorioConfigurationUpdate -> + update + .prototypes + .filterIsInstance() + .map { proto -> proto.name to proto } + .map { it.toKeyValue() } + } + .toTable( + materializedAs( + "kafkatorio.prototypes.map-tiles", + jsonMapper.serde(), + jsonMapper.serde() + ) + ) + } + + private fun mapChunksStream() { + + val luaTilesUpdatesStream: KStream = builder.stream( + "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", + Consumed.with(Serdes.String(), jsonMapper.serde()) + ) + .filter { _, event: FactorioEvent -> event.data is MapTiles } + .mapValues { _, event: FactorioEvent -> (event.data as? MapTiles)!! } + + val chunkTilesUpdateStream: KStream = builder.stream( + "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", + Consumed.with(Serdes.String(), jsonMapper.serde()) + ) + .filter { _, event: FactorioEvent -> event.data is MapChunk } + .mapValues { _, event: FactorioEvent -> (event.data as? MapChunk)!!.tiles } + + @Serializable + data class TileUpdateRecordKey( + val surfaceIndex: Int, + val tilePosition: MapTilePosition, + ) + + @Serializable + data class TileUpdateRecord( + val surfaceIndex: Int, + val tilePosition: MapTilePosition, + val tile: MapTile + ) : TopicData { + override val topicKey: TileUpdateRecordKey = + TileUpdateRecordKey(surfaceIndex, tilePosition) + } + + val allTileUpdatesStream: KStream = + luaTilesUpdatesStream + .merge(chunkTilesUpdateStream) + .flatMap { _, mapTiles: MapTiles -> + mapTiles.tiles.map { tile -> + TileUpdateRecord( + mapTiles.surfaceIndex, + tile.position, + tile + ).toKeyValue() + } + } + + @Serializable + data class MapChunkDataPosition( + val position: MapChunkPosition, + val surfaceIndex: Int, + ) + + @Serializable + data class MapChunkData( + val position: MapChunkPosition, + val surfaceIndex: Int, + val tiles: Set, + ) : TopicData { + override val topicKey = MapChunkDataPosition(position, surfaceIndex) + + constructor(key: MapChunkDataPosition, tiles: Set) : + this(key.position, key.surfaceIndex, tiles) + } + + val chunksTable = + allTileUpdatesStream + .groupBy { _: TileUpdateRecordKey, value: TileUpdateRecord -> + MapChunkDataPosition( + value.tilePosition.toMapChunkPosition(), + value.surfaceIndex, + ) + } + .aggregate( + { setOf() }, + ) { _: MapChunkDataPosition, v: TileUpdateRecord, tiles: Set -> + tiles + v.tile + } + .mapValues { chunkPosition: MapChunkDataPosition, tiles: Set -> + MapChunkData(chunkPosition, tiles) + } + + chunksTable.toStream() + .foreach { key: MapChunkDataPosition, value: MapChunkData -> + + + value.tiles + .map { tile -> + + val colour = tilePrototypesStore.get(tile.prototypeName) + .value() + .mapColour + .asDecimal() + + + val pixelColour = PixelTools.argb( + colour.alpha.roundToInt(), + colour.red.roundToInt(), + colour.green.roundToInt(), + colour.blue.roundToInt(), + ) + + Pixel( + tile.position.x, + tile.position.y, + pixelColour + ) + } + + val chunkImg = ImmutableImage.create(32, 32, BufferedImage.TYPE_INT_ARGB) + + val zoom = 1u + chunkImg.output( + PngWriter.MaxCompression, + File("${key.surfaceIndex}/$zoom/${key.position.x}/${key.position.y}.png") + ) + } + } + +// +// private fun createMapTileImages() { +// +// val mapTilesByPrototypeName: KStream = +// builder.stream( +// "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", +// Consumed.with(Serdes.String(), KafkatorioPacketSerde) +// ) +// .filter { _, packet -> packet is FactorioEvent && packet.data is MapTiles } +// .mapValues { packet -> ((packet as? FactorioEvent)?.data as? MapTiles)!! } +// .flatMap { _, mapTiles -> +// mapTiles +// .tiles +// .map { tile -> tile.prototypeName to tile } +// .map { it.toKeyValue() } +// } +//// .groupByKey() +// +// @Serializable +// data class TileSurfaceCoord( +// val surfaceIndex: Int, +// val position: MapTilePosition, +// ) +// +// @Serializable +// data class TileSurfaceState( +// val surfaceIndex: Int, +// val position: MapTilePosition, +// val prototypeName: String, +// ) +// +// val mapTilesTable: KTable = +// builder.stream( +// "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", +// Consumed.with(Serdes.String(), KafkatorioPacketSerde) +// ) +// .filter { _, packet -> packet is FactorioEvent && packet.data is MapTiles } +// .mapValues { packet -> ((packet as? FactorioEvent)?.data as? MapTiles)!! } +// .flatMap({ _, mapTiles: MapTiles -> +// mapTiles.tiles.map { tile: MapTile -> +// val key = TileSurfaceCoord(mapTiles.surfaceIndex, tile.position) +// val value = TileSurfaceState(mapTiles.surfaceIndex, tile.position, tile.prototypeName) +// (key to value).toKeyValue() +// } +// } +// ) +// .toTable( +// materializedAs( +// "kafkatorio.table.map-tile-status", +// jsonMapper.serde(), +// jsonMapper.serde(), +// ) +// ) +// +// +// val tilePrototypesTable: KTable = +// builder.stream( +// "kafkatorio.${KafkatorioPacket.PacketType.CONFIG}.FactorioConfigurationUpdate", +// Consumed.with(Serdes.String(), KafkatorioPacketSerde) +// ) +// .flatMap(KeyValueMapper>> { _, packet -> +// when (packet) { +// is FactorioConfigurationUpdate -> +// packet.prototypes +// .filterIsInstance() +// .map { proto -> proto.name to proto } +// .map { it.toKeyValue() } +// is FactorioEvent -> +// emptyList() +// } +// }) +// .toTable( +// materializedAs("kafkatorio.table.tile-prototypes", Serdes.String(), jsonMapper.serde()) +// ) +// +// +// @Serializable +// data class TileSurfaceData( +// val surfaceIndex: Int, +// val position: MapTilePosition, +// val prototype: MapTilePrototype, +// ) +// +// val enrichedTiles: KTable = +// mapTilesTable.join( +// tilePrototypesTable, +// { tile: TileSurfaceState -> +// tile.prototypeName +// }, +// { tile: TileSurfaceState, proto: MapTilePrototype -> +// TileSurfaceData(tile.surfaceIndex, tile.position, proto) +// }, +// ) +// +// } + } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt index 88c3666..e178d78 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt @@ -12,7 +12,6 @@ import org.http4k.format.ConfigurableKotlinxSerialization import org.http4k.format.asConfigurable import org.http4k.format.withStandardMappings - object KafkatorioPacketSerde : Serde { override fun serializer() = Serializer { _, message -> jsonMapper.encodeToString(message).encodeToByteArray() @@ -23,7 +22,7 @@ object KafkatorioPacketSerde : Serde { } } -val jsonMapper = Json { +val jsonMapper: Json = Json { prettyPrint = true prettyPrintIndent = " " serializersModule = jsonMapperKafkatorio.serializersModule diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioGameState.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioGameState.kt new file mode 100644 index 0000000..d66e7d1 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioGameState.kt @@ -0,0 +1,68 @@ +package dev.adamko.kafkatorio.processor.topology + +import dev.adamko.kafkatorio.events.schema.KafkatorioPacket +import dev.adamko.kafkatorio.events.schema.MapChunkPosition +import dev.adamko.kafkatorio.events.schema.MapTilePosition +import dev.adamko.kafkatorio.events.schema.MapTilePrototype +import dev.adamko.kafkatorio.processor.jsonMapper +import kotlinx.serialization.Serializable +import kotlinx.serialization.decodeFromString +import org.apache.kafka.common.serialization.Serdes +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.kstream.Consumed +import org.apache.kafka.streams.kstream.KGroupedStream + +class FactorioGameState ( +private val builder: StreamsBuilder = StreamsBuilder(), +) { + private val sourceTopic = "factorio-server-log" + + + private fun gatherGameState() { + + val serverPackets: KGroupedStream = + builder.stream( + sourceTopic, + Consumed.with(Serdes.String(), Serdes.String()) + ) + .mapValues { readOnlyKey, value -> + println("Mapping $readOnlyKey:$value") + jsonMapper.decodeFromString(value) + } + .groupByKey() + + @Serializable + data class TileSurfaceData( + val surfaceIndex: Int, + val position: MapTilePosition, + val prototype: MapTilePrototype, + ) + + @Serializable + data class MapChunkData( + val position: MapChunkPosition, + val tiles: List, + ) + + @Serializable + data class FactorioSurfaceData( + val surfaceIndex: Int, + val chunks: List, + ) + + @Serializable + data class FactorioServerState( + val surfaces: Map, + val tilePrototypes: List, + ) + + + +// serverPackets +// .aggregate( +// Initializer { FactorioServerState("", emptyMap(), emptyList()) } +// ) + } + + +} From 8533be0af874d53ad628ff1425e201b9601042ee Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 16 Jan 2022 23:16:09 +0100 Subject: [PATCH 154/629] chunk pngs almost working... - rm yarn lock, it should be in ./gradle/kotlin-js-store - move kafka extensions to another project, kotka-streams - move prototypes to their own package - create a Factorio command for emitting prototypes - add bounding box to chunk updates - bump typed-factorio version - fix MapEntityPosition -> MapChunkPosition x/y rounding - lots of work on the Kafka Streams topology --- .kotlin-js-store/yarn.lock | 3486 ----------------- build.gradle.kts | 2 +- buildSrc/build.gradle.kts | 2 - buildSrc/repositories.settings.gradle.kts | 19 +- .../lang/kotlin-multiplatform.gradle.kts | 9 + .../events-mod/src/main/typescript/control.ts | 1 + .../kafkatorio-schema/config-update.d.ts | 1 - .../kafkatorio-schema/object-data.d.ts | 1 + .../kafkatorio-schema/prototype.d.ts | 6 + .../generated/kafkatorio-schema/schema.d.ts | 17 +- .../main/commands/kafkatorioCommands.ts | 12 + .../handleConfigurationUpdate.ts | 6 +- .../{convertPrototypes.ts => prototypes.ts} | 11 +- .../main/typescript/main/events/converters.ts | 7 + .../main/typescript/main/events/handlers.ts | 5 +- .../src/main/typescript/package-lock.json | 8 +- .../src/main/typescript/package.json | 4 +- modules/events-schema/build.gradle.kts | 2 +- .../events/schema/factorioCommonData.kt | 25 +- .../events/schema/factorioConfiguration.kt | 6 +- .../events/schema/factorioLuaObjects.kt | 1 + .../events/schema/factorioPrototypes.kt | 11 + .../adamko/kafkatorio/events/schema/json.kt | 29 +- .../events/schema/kafkatorioPacket.kt | 2 + .../events/schema/PrototypesTest.kt | 45 + .../adamko/kafkatorio/events/schema/kt2ts.kt | 26 +- modules/events-server/build.gradle.kts | 12 +- .../adamko/kafkatorio/admin/CreateTopics.kt | 78 + .../kafkastreams/GlobalKTableDefinition.kt | 54 +- .../extensions/kafkastreams/KGroupedStream.kt | 32 + .../kafkastreams/KStreamExtensions.kt | 251 +- .../kafkastreams/KStreamTransform.kt | 178 +- .../kafkastreams/KTableExtensions.kt | 65 +- .../kafkastreams/KafkaStreamsExtensions.kt | 182 +- .../kafkastreams/KeyPairExtensions.kt | 66 +- .../extensions/kafkastreams/KeyValueSerdes.kt | 77 +- .../KotlinxSerializationExtensions.kt | 55 - .../extensions/kafkastreams/TopicData.kt | 30 +- .../kafkastreams/TopicDefinition.kt | 80 +- .../extensions/kafkastreams/aliases.kt | 2 +- .../kxs/KotlinxSerializationExtensions.kt | 55 + .../processor/KafkatorioTopology.kt | 294 +- .../processor/StreamsExceptionHandler.kt | 2 +- modules/infra-factorio-server/src/.env | 2 +- modules/infra-kafka-cluster/src/.env | 2 +- modules/infra-kafka-pipe/src/.env | 2 +- settings.gradle.kts | 13 +- 47 files changed, 1097 insertions(+), 4179 deletions(-) delete mode 100644 .kotlin-js-store/yarn.lock create mode 100644 modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts rename modules/events-mod/src/main/typescript/main/config-update/{convertPrototypes.ts => prototypes.ts} (76%) create mode 100644 modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KGroupedStream.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KotlinxSerializationExtensions.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kxs/KotlinxSerializationExtensions.kt diff --git a/.kotlin-js-store/yarn.lock b/.kotlin-js-store/yarn.lock deleted file mode 100644 index 8f53c73..0000000 --- a/.kotlin-js-store/yarn.lock +++ /dev/null @@ -1,3486 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/runtime@^7.9.2": - version "7.16.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.5.tgz#7f3e34bf8bdbbadf03fbb7b1ea0d929569c9487a" - integrity sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA== - dependencies: - regenerator-runtime "^0.13.4" - -"@discoveryjs/json-ext@^0.5.0": - version "0.5.6" - resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" - integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA== - -"@fortawesome/fontawesome-free@^5.15.4": - version "5.15.4" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5" - integrity sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@popperjs/core@^2.10.2": - version "2.11.0" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.0.tgz#6734f8ebc106a0860dff7f92bf90df193f0935d7" - integrity sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ== - -"@rjaros/gettext.js@^1.1.2": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@rjaros/gettext.js/-/gettext.js-1.1.3.tgz#8d1109f4a6f8e0c4dadba26281c7fe83de8ab18f" - integrity sha512-FgGWKCN88UE6nOmIjdv+gSnrE3AXjMx7f4uo3brLzKcC9dKzuNNDCzTIbuEDg38Pm1yYUTUH6QG4493T4sUnDg== - dependencies: - "@rjaros/po2json" "^1.0.0-beta-4" - -"@rjaros/po2json@^1.0.0-beta-4": - version "1.0.0-beta-4" - resolved "https://registry.yarnpkg.com/@rjaros/po2json/-/po2json-1.0.0-beta-4.tgz#0bd911af874afa39d868aeb88f6903cfabfbf5dd" - integrity sha512-VhNHrPJtX+caY99UnjCmMB0EWY4EgtZ/pj/Usyj4VUt3TtjHE5nV+fz4bVC0/OO641ncEFFfC3SJ2TurcwEWPw== - dependencies: - commander "^6.0.0" - gettext-parser "2.0.0" - gettext-to-messageformat "0.3.1" - -"@rjaros/snabbdom-virtualize@^1.0.0-beta.4": - version "1.0.0-beta.5" - resolved "https://registry.yarnpkg.com/@rjaros/snabbdom-virtualize/-/snabbdom-virtualize-1.0.0-beta.5.tgz#17f2586beee5e6c130e1b0ae2f589ff9162a86db" - integrity sha512-2rf1MI7wVSZLOgy+EXtOfYzqcwLtMjak4wzRBQUVJjO4qlCmlSo+bh890eKkILhRGxkp6aTQS9gMjH1fP9g8Nw== - dependencies: - html-parse-stringify "^3" - -"@types/body-parser@*": - version "1.19.2" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" - integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/bonjour@^3.5.9": - version "3.5.10" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" - integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== - dependencies: - "@types/node" "*" - -"@types/component-emitter@^1.2.10": - version "1.2.11" - resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" - integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== - -"@types/connect-history-api-fallback@^1.3.5": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" - integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== - dependencies: - "@types/express-serve-static-core" "*" - "@types/node" "*" - -"@types/connect@*": - version "3.4.35" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" - integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== - dependencies: - "@types/node" "*" - -"@types/cookie@^0.4.0": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" - integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== - -"@types/cors@^2.8.8": - version "2.8.12" - resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" - integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== - -"@types/eslint-scope@^3.7.0": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.2.tgz#11e96a868c67acf65bf6f11d10bb89ea71d5e473" - integrity sha512-TzgYCWoPiTeRg6RQYgtuW7iODtVoKu3RVL72k3WohqhjfaOLK5Mg2T4Tg1o2bSfu0vPkoI48wdQFv5b/Xe04wQ== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "8.2.1" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.2.1.tgz#13f3d69bac93c2ae008019c28783868d0a1d6605" - integrity sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree@*", "@types/estree@^0.0.50": - version "0.0.50" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" - integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== - -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": - version "4.17.27" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.27.tgz#7a776191e47295d2a05962ecbb3a4ce97e38b401" - integrity sha512-e/sVallzUTPdyOTiqi8O8pMdBBphscvI6E4JYaKlja4Lm+zh7UFSSdW5VMkRbhDtmrONqOUHOXRguPsDckzxNA== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - -"@types/express@*": - version "4.17.13" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" - integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.18" - "@types/qs" "*" - "@types/serve-static" "*" - -"@types/geojson@*", "@types/geojson@7946.0.8": - version "7946.0.8" - resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" - integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA== - -"@types/glob@5 - 7": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - -"@types/http-proxy@^1.17.5": - version "1.17.8" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.8.tgz#968c66903e7e42b483608030ee85800f22d03f55" - integrity sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA== - dependencies: - "@types/node" "*" - -"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.9" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" - integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== - -"@types/leaflet@^1.7.7": - version "1.7.7" - resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.7.7.tgz#3c9f629126e03405ed68cc1aa395e32df3312376" - integrity sha512-5/nNqTviSqUwPxbS3PlHl8ODjfnlpOXSFtUAi7dexnisO8E3pfyotChRY/hlIYGvbBiBcKNd6V18xA8O4OpHiQ== - dependencies: - "@types/geojson" "*" - -"@types/mime@^1": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" - integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== - -"@types/minimatch@*": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" - integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== - -"@types/node@*", "@types/node@>=10.0.0": - version "17.0.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.2.tgz#a4c07d47ff737e8ee7e586fe636ff0e1ddff070a" - integrity sha512-JepeIUPFDARgIs0zD/SKPgFsJEAF0X5/qO80llx59gOxFTboS9Amv3S+QfB7lqBId5sFXJ99BN0J6zFRvL9dDA== - -"@types/parse5@^5": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" - integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== - -"@types/qs@*": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== - -"@types/range-parser@*": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" - integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== - -"@types/retry@^0.12.0": - version "0.12.1" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" - integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== - -"@types/serve-index@^1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" - integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== - dependencies: - "@types/express" "*" - -"@types/serve-static@*": - version "1.13.10" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" - integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== - dependencies: - "@types/mime" "^1" - "@types/node" "*" - -"@types/sockjs@^0.3.33": - version "0.3.33" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" - integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== - dependencies: - "@types/node" "*" - -"@types/ws@^8.2.2": - version "8.2.2" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.2.2.tgz#7c5be4decb19500ae6b3d563043cd407bf366c21" - integrity sha512-NOn5eIcgWLOo6qW8AcuLZ7G8PycXu0xTxxkS6Q18VWFxgPUSOwV0pBj2a/4viNZVu25i7RIB7GttdkAIUUXOOg== - dependencies: - "@types/node" "*" - -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== - dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== - -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== - -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== - -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== - -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== - -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" - -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@xtuc/long" "4.2.2" - -"@webpack-cli/configtest@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.0.tgz#8342bef0badfb7dfd3b576f2574ab80c725be043" - integrity sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg== - -"@webpack-cli/info@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.0.tgz#b9179c3227ab09cbbb149aa733475fcf99430223" - integrity sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw== - dependencies: - envinfo "^7.7.3" - -"@webpack-cli/serve@^1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.0.tgz#2c275aa05c895eccebbfc34cfb223c6e8bd591a2" - integrity sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA== - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - -abab@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" - integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== - -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== - -acorn@^8.4.1: - version "8.6.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" - integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv-formats@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" - integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== - dependencies: - ajv "^8.0.0" - -ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - -ajv-keywords@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" - integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== - dependencies: - fast-deep-equal "^3.1.3" - -ajv@^6.12.5: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^8.0.0, ajv@^8.8.0: - version "8.8.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.8.2.tgz#01b4fef2007a28bf75f0b7fc009f62679de4abbb" - integrity sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-html-community@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" - integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - -array-flatten@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -async@^2.6.2: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== - dependencies: - lodash "^4.17.14" - -awesome-bootstrap-checkbox@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/awesome-bootstrap-checkbox/-/awesome-bootstrap-checkbox-1.0.1.tgz#dab10146b6001129ab0a0ec1e54bb77c6c30457a" - integrity sha1-2rEBRrYAESmrCg7B5Uu3fGwwRXo= - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base64-arraybuffer@0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" - integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= - -base64id@2.0.0, base64id@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" - integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== - -batch@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -body-parser@1.19.1, body-parser@^1.19.0: - version "1.19.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.1.tgz#1499abbaa9274af3ecc9f6f10396c995943e31d4" - integrity sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA== - dependencies: - bytes "3.1.1" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.2" - http-errors "1.8.1" - iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.9.6" - raw-body "2.4.2" - type-is "~1.6.18" - -bonjour@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" - integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= - dependencies: - array-flatten "^2.1.0" - deep-equal "^1.0.1" - dns-equal "^1.0.0" - dns-txt "^2.0.2" - multicast-dns "^6.0.1" - multicast-dns-service-types "^1.1.0" - -bootstrap-icons@^1.6.0: - version "1.7.2" - resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.7.2.tgz#4024e081e2c850602552e1fed6451e682d09322a" - integrity sha512-NiR2PqC73AQOPdVSu6GJfnk+hN2z6powcistXk1JgPnKuoV2FSdSl26w931Oz9HYbKCcKUSB6ncZTYJAYJl3QQ== - -bootstrap@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.1.3.tgz#ba081b0c130f810fa70900acbc1c6d3c28fa8f34" - integrity sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -browserslist@^4.14.5: - version "4.19.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" - integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== - dependencies: - caniuse-lite "^1.0.30001286" - electron-to-chromium "^1.4.17" - escalade "^3.1.1" - node-releases "^2.0.1" - picocolors "^1.0.0" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer-indexof@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" - integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== - -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= - -bytes@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a" - integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg== - -call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -camelcase@^6.0.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.1.tgz#250fd350cfd555d0d2160b1d51510eaf8326e86e" - integrity sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA== - -caniuse-lite@^1.0.30001286: - version "1.0.30001292" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001292.tgz#4a55f61c06abc9595965cfd77897dc7bc1cdc456" - integrity sha512-jnT4Tq0Q4ma+6nncYQVe7d73kmDmE9C3OGTx3MvW7lBM/eY1S1DZTMBON7dqV481RhNiS5OxD7k9JQvmDOTirw== - -chalk@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chart.js@^3.6.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.6.2.tgz#47342c551f688ffdda2cd53b534cb7e461ecec33" - integrity sha512-Xz7f/fgtVltfQYWq0zL1Xbv7N2inpG+B54p3D5FSvpCdy3sM+oZhbqa42eNuYXltaVvajgX5UpKCU2GeeJIgxg== - -chokidar@3.5.2, chokidar@^3.5.1, chokidar@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" - integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chrome-trace-event@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" - integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -clone-deep@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== - dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -colorette@^2.0.10, colorette@^2.0.14: - version "2.0.16" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" - integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== - -colors@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@^6.0.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" - integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== - -commander@^7.0.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - -component-emitter@~1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -compressible@~2.0.16: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== - dependencies: - mime-db ">= 1.43.0 < 2" - -compression@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -connect-history-api-fallback@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" - integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== - -connect@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" - integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== - dependencies: - debug "2.6.9" - finalhandler "1.1.2" - parseurl "~1.3.3" - utils-merge "1.0.1" - -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - -cookie@0.4.1, cookie@~0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" - integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -cors@~2.8.5: - version "2.8.5" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" - integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== - dependencies: - object-assign "^4" - vary "^1" - -cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -css-loader@^6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.5.1.tgz#0c43d4fbe0d97f699c91e9818cb585759091d1b1" - integrity sha512-gEy2w9AnJNnD9Kuo4XAP9VflW/ujKoS9c/syO+uWMlm5igc7LysKzPXaDoR2vroROkSwsTS2tGr1yGGEbZOYZQ== - dependencies: - icss-utils "^5.1.0" - postcss "^8.2.15" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" - postcss-modules-scope "^3.0.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.1.0" - semver "^7.3.5" - -css-selector-parser@^1.3: - version "1.4.1" - resolved "https://registry.yarnpkg.com/css-selector-parser/-/css-selector-parser-1.4.1.tgz#03f9cb8a81c3e5ab2c51684557d5aaf6d2569759" - integrity sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g== - -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - -custom-event@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" - integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= - -date-format@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/date-format/-/date-format-2.1.0.tgz#31d5b5ea211cf5fd764cd38baf9d033df7e125cf" - integrity sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA== - -date-format@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/date-format/-/date-format-3.0.0.tgz#eb8780365c7d2b1511078fb491e6479780f3ad95" - integrity sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w== - -debug@2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - -debug@^3.1.1: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.1.0, debug@^4.1.1, debug@~4.3.1: - version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== - dependencies: - ms "2.1.2" - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -deep-equal@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - -default-gateway@^6.0.0, default-gateway@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" - integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== - dependencies: - execa "^5.0.0" - -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -del@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/del/-/del-6.0.0.tgz#0b40d0332cea743f1614f818be4feb717714c952" - integrity sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ== - dependencies: - globby "^11.0.1" - graceful-fs "^4.2.4" - is-glob "^4.0.1" - is-path-cwd "^2.2.0" - is-path-inside "^3.0.2" - p-map "^4.0.0" - rimraf "^3.0.2" - slash "^3.0.0" - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - -detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - -di@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" - integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw= - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= - -dns-packet@^1.3.1: - version "1.3.4" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" - integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== - dependencies: - ip "^1.1.0" - safe-buffer "^5.0.1" - -dns-txt@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" - integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= - dependencies: - buffer-indexof "^1.0.0" - -dom-serialize@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" - integrity sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs= - dependencies: - custom-event "~1.0.0" - ent "~2.2.0" - extend "^3.0.0" - void-elements "^2.0.0" - -dukat@0.5.8-rc.3: - version "0.5.8-rc.3" - resolved "https://registry.yarnpkg.com/dukat/-/dukat-0.5.8-rc.3.tgz#4a2b848b9d2978cb610af8d5cf24ff5e5a408743" - integrity sha512-wzl9A5alTT1Mag4y7bUVjPF4L/wkts7AiiWxe6/6tL5gSDowexUzlJX/pYVTbnHcOo48/bok3Ao1gzU4/cFFjw== - dependencies: - google-protobuf "3.12.2" - typescript "3.9.5" - -dukat@0.5.8-rc.4: - version "0.5.8-rc.4" - resolved "https://registry.yarnpkg.com/dukat/-/dukat-0.5.8-rc.4.tgz#90384dcb50b14c26f0e99dae92b2dea44f5fce21" - integrity sha512-ZnMt6DGBjlVgK2uQamXfd7uP/AxH7RqI0BL9GLrrJb2gKdDxvJChWy+M9AQEaL+7/6TmxzJxFOsRiInY9oGWTA== - dependencies: - google-protobuf "3.12.2" - typescript "3.9.5" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -electron-to-chromium@^1.4.17: - version "1.4.27" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.27.tgz#bfc6e798d8a56a17d658312f4b7ae1a7ca87724f" - integrity sha512-uZ95szi3zUbzRDx1zx/xnsCG+2xgZyy57pDOeaeO4r8zx5Dqe8Jv1ti8cunvBwJHVI5LzPuw8umKwZb3WKYxSQ== - -element-resize-event@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/element-resize-event/-/element-resize-event-3.0.6.tgz#3a18efd4879ad615e979fd8bbf173b014987eb9a" - integrity sha512-sSeXY9rNDp86bJODW68pxLcy3A5FrPZfIgOrJHzqgYzX513Zq6/ytdBigp7KeJEpZZopBBSiO1cVuiRkZpNxLw== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -encoding@^0.1.12: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - -engine.io-parser@~4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-4.0.3.tgz#83d3a17acfd4226f19e721bb22a1ee8f7662d2f6" - integrity sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA== - dependencies: - base64-arraybuffer "0.1.4" - -engine.io@~4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-4.1.1.tgz#9a8f8a5ac5a5ea316183c489bf7f5b6cf91ace5b" - integrity sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w== - dependencies: - accepts "~1.3.4" - base64id "2.0.0" - cookie "~0.4.1" - cors "~2.8.5" - debug "~4.3.1" - engine.io-parser "~4.0.0" - ws "~7.4.2" - -enhanced-resolve@^5.8.3: - version "5.8.3" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" - integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - -ent@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" - integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0= - -envinfo@^7.7.3: - version "7.8.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" - integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== - -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-string-regexp@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-scope@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -eventemitter3@^4.0.0: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -events@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -express@^4.17.1: - version "4.17.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.2.tgz#c18369f265297319beed4e5558753cc8c1364cb3" - integrity sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg== - dependencies: - accepts "~1.3.7" - array-flatten "1.1.1" - body-parser "1.19.1" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.4.1" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.1.2" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.7" - qs "6.9.6" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.17.2" - serve-static "1.14.2" - setprototypeof "1.2.0" - statuses "~1.5.0" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -extend@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@^3.1.1: - version "3.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" - integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fastest-levenshtein@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" - integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== - -fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== - dependencies: - reusify "^1.0.4" - -faye-websocket@^0.11.3: - version "0.11.4" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" - integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== - dependencies: - websocket-driver ">=0.5.1" - -fecha@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce" - integrity sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q== - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@1.1.2, finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - -find-up@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== - -follow-redirects@^1.0.0: - version "1.14.6" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.6.tgz#8cfb281bbc035b3c067d6cd975b0f6ade6e855cd" - integrity sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A== - -format-util@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" - integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -fs-extra@^8.0.1, fs-extra@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-monkey@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" - integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -geojson@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/geojson/-/geojson-0.5.0.tgz#3cd6c96399be65b56ee55596116fe9191ce701c0" - integrity sha1-PNbJY5m+ZbVu5VWWEW/pGRznAcA= - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.0.2: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -gettext-extract@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/gettext-extract/-/gettext-extract-2.0.1.tgz#4ade7e3d7c1c247d95a81f28059ca1923c355886" - integrity sha512-k51R90txkCZeXQEDjK0e7gNHfBHJVCu8IQ3AbSVZoOL5nR3yl+C+7qpzp6hoZwOtiniaY+CKeLyvNulsEUM6MA== - dependencies: - chalk "^2.3.0" - find-up "^4.1.0" - fs-extra "^8.0.1" - gettext-extractor "^3.1.0" - minimist "^1.2.0" - -gettext-extractor@^3.1.0: - version "3.5.3" - resolved "https://registry.yarnpkg.com/gettext-extractor/-/gettext-extractor-3.5.3.tgz#6ed46931c154a7485a80fa8b91b835ff7b8d0411" - integrity sha512-9EgJ+hmbtAbATdMIvCj4WnrkeDWH6fv1z+IJJ1XCxdcUMGx6JQdVVFTdzJkSyIHh4td53ngoB5EQbavbKJU9Og== - dependencies: - "@types/glob" "5 - 7" - "@types/parse5" "^5" - css-selector-parser "^1.3" - glob "5 - 7" - parse5 "5 - 6" - pofile "1.0.x" - typescript "2 - 4" - -gettext-parser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-2.0.0.tgz#c28bb31e61f76f14665dfafbb5c0518cdc1270ed" - integrity sha512-FDs/7XjNw58ToQwJFO7avZZbPecSYgw8PBYhd0An+4JtZSrSzKhEvTsVV2uqdO7VziWTOGSgLGD5YRPdsCjF7Q== - dependencies: - encoding "^0.1.12" - safe-buffer "^5.1.2" - -gettext-parser@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-1.4.0.tgz#f8baf34a292f03d5e42f02df099d301f167a7ace" - integrity sha512-sedZYLHlHeBop/gZ1jdg59hlUEcpcZJofLq2JFwJT1zTqAU3l2wFv6IsuwFHGqbiT9DWzMUW4/em2+hspnmMMA== - dependencies: - encoding "^0.1.12" - safe-buffer "^5.1.1" - -gettext-to-messageformat@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/gettext-to-messageformat/-/gettext-to-messageformat-0.3.1.tgz#c303ff9e31a5c781b14629b13bddb27b9ffca1f8" - integrity sha512-UyqIL3Ul4NryU95Wome/qtlcuVIqgEWVIFw0zi7Lv14ACLXfaVDCbrjZ7o+3BZ7u+4NS1mP/2O1eXZoHCoas8g== - dependencies: - gettext-parser "^1.4.0" - -glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" - integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== - -"glob@5 - 7", glob@^7.1.3, glob@^7.1.7: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globby@^11.0.1: - version "11.0.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" - integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" - slash "^3.0.0" - -google-protobuf@3.12.2: - version "3.12.2" - resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.12.2.tgz#50ce9f9b6281235724eb243d6a83e969a2176e53" - integrity sha512-4CZhpuRr1d6HjlyrxoXoocoGFnRYgKULgMtikMddA9ztRyYR59Aondv2FioyxWVamRo0rF2XpYawkTCBEQOSkA== - -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6: - version "4.2.8" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" - integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -handle-thing@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" - integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.1, has-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" - integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -he@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -html-entities@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488" - integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ== - -html-parse-stringify@^3: - version "3.0.1" - resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2" - integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg== - dependencies: - void-elements "3.1.0" - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= - -http-errors@1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" - integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.1" - -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-parser-js@>=0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.5.tgz#d7c30d5d3c90d865b4a2e870181f9d6f22ac7ac5" - integrity sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA== - -http-proxy-middleware@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.1.tgz#7ef3417a479fb7666a571e09966c66a39bd2c15f" - integrity sha512-cfaXRVoZxSed/BmkA7SwBVNI9Kj7HFltaE5rqYOub5kWzWZ+gofV2koVN1j2rMW7pEfSSlCHGJ31xmuyFyfLOg== - dependencies: - "@types/http-proxy" "^1.17.5" - http-proxy "^1.18.1" - is-glob "^4.0.1" - is-plain-obj "^3.0.0" - micromatch "^4.0.2" - -http-proxy@^1.18.1: - version "1.18.1" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" - integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -icss-utils@^5.0.0, icss-utils@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" - integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== - -ignore@^5.1.4: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== - -import-local@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.3.tgz#4d51c2c495ca9393da259ec66b62e022920211e0" - integrity sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -imports-loader@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-3.1.1.tgz#3e464d9aad1e303b1b34b658eb8f8aae22f96435" - integrity sha512-3QMyGU4RTgxLf0puWkUfT5+7zJvexvB00PI5skDIcxG8O20gZCbQsaRpNBv+cIO6yy/lmlOBwaxc3uH1CV+sww== - dependencies: - source-map "^0.6.1" - strip-comments "^2.0.1" - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -internal-ip@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-6.2.0.tgz#d5541e79716e406b74ac6b07b856ef18dc1621c1" - integrity sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg== - dependencies: - default-gateway "^6.0.0" - ipaddr.js "^1.9.1" - is-ip "^3.1.0" - p-event "^4.2.0" - -interpret@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" - integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== - -ip-regex@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" - integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== - -ip@^1.1.0: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= - -ipaddr.js@1.9.1, ipaddr.js@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -ipaddr.js@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" - integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== - -is-arguments@^1.0.4: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" - integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-core-module@^2.2.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" - integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-ip@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8" - integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q== - dependencies: - ip-regex "^4.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-path-cwd@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - -is-path-inside@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-plain-obj@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" - integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== - -is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-regex@^1.0.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isbinaryfile@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.8.tgz#5d34b94865bd4946633ecc78a026fc76c5b11fcf" - integrity sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -jest-worker@^27.4.1: - version "27.4.5" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.5.tgz#d696e3e46ae0f24cff3fa7195ffba22889262242" - integrity sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jquery@^3.5.1: - version "3.6.0" - resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470" - integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw== - -js-yaml@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -karma-chrome-launcher@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz#805a586799a4d05f4e54f72a204979f3f3066738" - integrity sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg== - dependencies: - which "^1.2.1" - -karma-mocha@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-2.0.1.tgz#4b0254a18dfee71bdbe6188d9a6861bf86b0cd7d" - integrity sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ== - dependencies: - minimist "^1.2.3" - -karma-sourcemap-loader@0.3.8: - version "0.3.8" - resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.8.tgz#d4bae72fb7a8397328a62b75013d2df937bdcf9c" - integrity sha512-zorxyAakYZuBcHRJE+vbrK2o2JXLFWK8VVjiT/6P+ltLBUGUvqTEkUiQ119MGdOrK7mrmxXHZF1/pfT6GgIZ6g== - dependencies: - graceful-fs "^4.1.2" - -karma-webpack@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.0.tgz#2a2c7b80163fe7ffd1010f83f5507f95ef39f840" - integrity sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA== - dependencies: - glob "^7.1.3" - minimatch "^3.0.4" - webpack-merge "^4.1.5" - -karma@6.3.4: - version "6.3.4" - resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.4.tgz#359899d3aab3d6b918ea0f57046fd2a6b68565e6" - integrity sha512-hbhRogUYIulfkBTZT7xoPrCYhRBnBoqbbL4fszWD0ReFGUxU+LYBr3dwKdAluaDQ/ynT9/7C+Lf7pPNW4gSx4Q== - dependencies: - body-parser "^1.19.0" - braces "^3.0.2" - chokidar "^3.5.1" - colors "^1.4.0" - connect "^3.7.0" - di "^0.0.1" - dom-serialize "^2.2.1" - glob "^7.1.7" - graceful-fs "^4.2.6" - http-proxy "^1.18.1" - isbinaryfile "^4.0.8" - lodash "^4.17.21" - log4js "^6.3.0" - mime "^2.5.2" - minimatch "^3.0.4" - qjobs "^1.2.0" - range-parser "^1.2.1" - rimraf "^3.0.2" - socket.io "^3.1.0" - source-map "^0.6.1" - tmp "^0.2.1" - ua-parser-js "^0.7.28" - yargs "^16.1.1" - -kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -kvision-assets@^5.0.7: - version "5.0.7" - resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-5.0.7.tgz#e6dc3e28a2d244b4c89318b060d3e7e337c15495" - integrity sha512-szoL8ixFRTivLkbnmkWFjGJMk3bsUW/loUS5QfWThPwFnyFEw8ht3eBUrJ0V51Rn/WaJbVoPvY4SfIaiNu13bg== - -leaflet@^1.7.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.7.1.tgz#10d684916edfe1bf41d688a3b97127c0322a2a19" - integrity sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw== - -loader-runner@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" - integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-symbols@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -log4js@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.3.0.tgz#10dfafbb434351a3e30277a00b9879446f715bcb" - integrity sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw== - dependencies: - date-format "^3.0.0" - debug "^4.1.1" - flatted "^2.0.1" - rfdc "^1.1.4" - streamroller "^2.2.4" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - -memfs@^3.2.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.0.tgz#8bc12062b973be6b295d4340595736a656f0a257" - integrity sha512-o/RfP0J1d03YwsAxyHxAYs2kyJp55AFkMazlFAZFR2I2IXkxiUTXRabJ6RmNNCQ83LAD2jy52Khj0m3OffpNdA== - dependencies: - fs-monkey "1.0.3" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - -micromatch@^4.0.2, micromatch@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" - integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== - dependencies: - braces "^3.0.1" - picomatch "^2.2.3" - -mime-db@1.51.0, "mime-db@>= 1.43.0 < 2": - version "1.51.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" - integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== - -mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24: - version "2.1.34" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" - integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== - dependencies: - mime-db "1.51.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mime@^2.5.2: - version "2.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" - integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimalistic-assert@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimatch@3.0.4, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -mkdirp@^0.5.5: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -mocha@9.1.2: - version "9.1.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.2.tgz#93f53175b0f0dc4014bd2d612218fccfcf3534d3" - integrity sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.2" - debug "4.3.2" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.1.7" - growl "1.10.5" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "3.0.4" - ms "2.1.3" - nanoid "3.1.25" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - workerpool "6.1.5" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -multicast-dns-service-types@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" - integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= - -multicast-dns@^6.0.1: - version "6.2.3" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" - integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== - dependencies: - dns-packet "^1.3.1" - thunky "^1.0.2" - -nanoid@3.1.25: - version "3.1.25" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" - integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== - -nanoid@^3.1.30: - version "3.1.30" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362" - integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ== - -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== - -neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -node-forge@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" - integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== - -node-releases@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" - integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -object-assign@^4: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-is@^1.0.1: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -open@^8.0.9: - version "8.4.0" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" - integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - -p-event@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" - integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== - dependencies: - p-timeout "^3.1.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -p-retry@^4.5.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c" - integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA== - dependencies: - "@types/retry" "^0.12.0" - retry "^0.13.1" - -p-timeout@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" - integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== - dependencies: - p-finally "^1.0.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -"parse5@5 - 6": - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - -parseurl@~1.3.2, parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" - integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== - -pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -pofile@1.0.x: - version "1.0.11" - resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.0.11.tgz#35aff58c17491d127a07336d5522ebc9df57c954" - integrity sha512-Vy9eH1dRD9wHjYt/QqXcTz+RnX/zg53xK+KljFSX30PvdDMb2z+c6uDUeblUGqqJgz3QFsdlA0IJvHziPmWtQg== - -portfinder@^1.0.28: - version "1.0.28" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" - integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== - dependencies: - async "^2.6.2" - debug "^3.1.1" - mkdirp "^0.5.5" - -postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" - integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== - -postcss-modules-local-by-default@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" - integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== - dependencies: - icss-utils "^5.0.0" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.1.0" - -postcss-modules-scope@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" - integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== - dependencies: - postcss-selector-parser "^6.0.4" - -postcss-modules-values@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" - integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== - dependencies: - icss-utils "^5.0.0" - -postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: - version "6.0.8" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.8.tgz#f023ed7a9ea736cd7ef70342996e8e78645a7914" - integrity sha512-D5PG53d209Z1Uhcc0qAZ5U3t5HagH3cxu+WLZ22jt3gLUpXM4eXXfiO14jiDWST3NNooX/E8wISfOhZ9eIjGTQ== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -postcss-value-parser@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" - integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== - -postcss@^8.2.15: - version "8.4.5" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95" - integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg== - dependencies: - nanoid "^3.1.30" - picocolors "^1.0.0" - source-map-js "^1.0.1" - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qjobs@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" - integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== - -qs@6.9.6: - version "6.9.6" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" - integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -range-parser@^1.2.1, range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32" - integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ== - dependencies: - bytes "3.1.1" - http-errors "1.8.1" - iconv-lite "0.4.24" - unpipe "1.0.0" - -readable-stream@^2.0.1: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -rechoir@^0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" - integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== - dependencies: - resolve "^1.9.0" - -redux-thunk@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.1.tgz#0dd8042cf47868f4b29699941de03c9301a75714" - integrity sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q== - -redux@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.2.tgz#140f35426d99bb4729af760afcf79eaaac407104" - integrity sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw== - dependencies: - "@babel/runtime" "^7.9.2" - -regenerator-runtime@^0.13.4: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== - -regexp.prototype.flags@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" - integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve@^1.9.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -retry@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rfdc@^1.1.4: - version "1.3.0" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== - -rimraf@^3.0.0, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -schema-utils@^3.1.0, schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" - integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== - dependencies: - "@types/json-schema" "^7.0.9" - ajv "^8.8.0" - ajv-formats "^2.1.1" - ajv-keywords "^5.0.0" - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= - -selfsigned@^1.10.11: - version "1.10.11" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.11.tgz#24929cd906fe0f44b6d01fb23999a739537acbe9" - integrity sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA== - dependencies: - node-forge "^0.10.0" - -semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - -send@0.17.2: - version "0.17.2" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" - integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "1.8.1" - mime "1.6.0" - ms "2.1.3" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" - -serialize-javascript@6.0.0, serialize-javascript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - -serve-static@1.14.2: - version "1.14.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" - integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.2" - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== - dependencies: - kind-of "^6.0.2" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -signal-exit@^3.0.3: - version "3.0.6" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" - integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -snabbdom@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.2.0.tgz#8ea6b2517739a7d9ca82df3f181d052adf1ca5ad" - integrity sha512-UWyfm8WbaFmbmYLC33pe5fawBfExhynkMDoZqQ8ehlHDwkxrgIOpWhKf5PaacLUW1n+Uwu5N5HND6mESU7cMlw== - -socket.io-adapter@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz#edc5dc36602f2985918d631c1399215e97a1b527" - integrity sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg== - -socket.io-parser@~4.0.3: - version "4.0.4" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0" - integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g== - dependencies: - "@types/component-emitter" "^1.2.10" - component-emitter "~1.3.0" - debug "~4.3.1" - -socket.io@^3.1.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-3.1.2.tgz#06e27caa1c4fc9617547acfbb5da9bc1747da39a" - integrity sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw== - dependencies: - "@types/cookie" "^0.4.0" - "@types/cors" "^2.8.8" - "@types/node" ">=10.0.0" - accepts "~1.3.4" - base64id "~2.0.0" - debug "~4.3.1" - engine.io "~4.1.0" - socket.io-adapter "~2.1.0" - socket.io-parser "~4.0.3" - -sockjs@^0.3.21: - version "0.3.24" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" - integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== - dependencies: - faye-websocket "^0.11.3" - uuid "^8.3.2" - websocket-driver "^0.7.4" - -source-map-js@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" - integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== - -source-map-js@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf" - integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA== - -source-map-loader@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.0.tgz#f2a04ee2808ad01c774dea6b7d2639839f3b3049" - integrity sha512-GKGWqWvYr04M7tn8dryIWvb0s8YM41z82iQv01yBtIylgxax0CwvSy6gc2Y02iuXwEfGWRlMicH0nvms9UZphw== - dependencies: - abab "^2.0.5" - iconv-lite "^0.6.2" - source-map-js "^0.6.2" - -source-map-support@0.5.20: - version "0.5.20" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" - integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0, source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -source-map@~0.7.2: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== - -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -split.js@^1.6.4: - version "1.6.4" - resolved "https://registry.yarnpkg.com/split.js/-/split.js-1.6.4.tgz#13d47cba53382adef230a53294ce5dacb2a2f2e1" - integrity sha512-kYmQZprRJrF1IOjg/E+gdBEsKFv5kbgUE6RJVJZvrIzTOK/IHzKSqIeiJnWs7IP5D9TnpTQ2CbanuDuIWcyDUQ== - -"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -streamroller@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-2.2.4.tgz#c198ced42db94086a6193608187ce80a5f2b0e53" - integrity sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ== - dependencies: - date-format "^2.1.0" - debug "^4.1.1" - fs-extra "^8.1.0" - -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== - dependencies: - ansi-regex "^6.0.1" - -strip-comments@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" - integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-json-comments@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -style-loader@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" - integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== - -supports-color@8.1.1, supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -tapable@^2.1.1, tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== - -terser-webpack-plugin@^5.1.3: - version "5.3.0" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz#21641326486ecf91d8054161c816e464435bae9f" - integrity sha512-LPIisi3Ol4chwAaPP8toUJ3L4qCM1G0wao7L3qNv57Drezxj6+VEyySpPw4B1HSO2Eg/hDY/MNF5XihCAoqnsQ== - dependencies: - jest-worker "^27.4.1" - schema-utils "^3.1.1" - serialize-javascript "^6.0.0" - source-map "^0.6.1" - terser "^5.7.2" - -terser@^5.7.2: - version "5.10.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc" - integrity sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA== - dependencies: - commander "^2.20.0" - source-map "~0.7.2" - source-map-support "~0.5.20" - -thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" - integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== - -tmp@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -"typescript@2 - 4": - version "4.5.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" - integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== - -typescript@3.9.5: - version "3.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" - integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== - -ua-parser-js@^0.7.28: - version "0.7.31" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" - integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -v8-compile-cache@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -vary@^1, vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - -void-elements@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" - integrity sha1-YU9/v42AHwu18GYfWy9XhXUOTwk= - -void-elements@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" - integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= - -watchpack@^2.2.0, watchpack@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25" - integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - -webpack-cli@4.9.0: - version "4.9.0" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.0.tgz#dc43e6e0f80dd52e89cbf73d5294bcd7ad6eb343" - integrity sha512-n/jZZBMzVEl4PYIBs+auy2WI0WTQ74EnJDiyD98O2JZY6IVIHJNitkYp/uTXOviIOMfgzrNvC9foKv/8o8KSZw== - dependencies: - "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.1.0" - "@webpack-cli/info" "^1.4.0" - "@webpack-cli/serve" "^1.6.0" - colorette "^2.0.14" - commander "^7.0.0" - execa "^5.0.0" - fastest-levenshtein "^1.0.12" - import-local "^3.0.2" - interpret "^2.2.0" - rechoir "^0.7.0" - v8-compile-cache "^2.2.0" - webpack-merge "^5.7.3" - -webpack-cli@4.9.1: - version "4.9.1" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3" - integrity sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ== - dependencies: - "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.1.0" - "@webpack-cli/info" "^1.4.0" - "@webpack-cli/serve" "^1.6.0" - colorette "^2.0.14" - commander "^7.0.0" - execa "^5.0.0" - fastest-levenshtein "^1.0.12" - import-local "^3.0.2" - interpret "^2.2.0" - rechoir "^0.7.0" - webpack-merge "^5.7.3" - -webpack-dev-middleware@^5.2.1, webpack-dev-middleware@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.0.tgz#8fc02dba6e72e1d373eca361623d84610f27be7c" - integrity sha512-MouJz+rXAm9B1OTOYaJnn6rtD/lWZPy2ufQCH3BPs8Rloh/Du6Jze4p7AeLYHkVi0giJnYLaSGDC7S+GM9arhg== - dependencies: - colorette "^2.0.10" - memfs "^3.2.2" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - -webpack-dev-server@4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.3.1.tgz#759d3337f0fbea297fbd1e433ab04ccfc000076b" - integrity sha512-qNXQCVYo1kYhH9pgLtm8LRNkXX3XzTfHSj/zqzaqYzGPca+Qjr+81wj1jgPMCHhIhso9WEQ+kX9z23iG9PzQ7w== - dependencies: - ansi-html-community "^0.0.8" - bonjour "^3.5.0" - chokidar "^3.5.1" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^1.6.0" - del "^6.0.0" - express "^4.17.1" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.0" - internal-ip "^6.2.0" - ipaddr.js "^2.0.1" - open "^8.0.9" - p-retry "^4.5.0" - portfinder "^1.0.28" - schema-utils "^3.1.0" - selfsigned "^1.10.11" - serve-index "^1.9.1" - sockjs "^0.3.21" - spdy "^4.0.2" - strip-ansi "^7.0.0" - url "^0.11.0" - webpack-dev-middleware "^5.2.1" - ws "^8.1.0" - -webpack-dev-server@4.7.2: - version "4.7.2" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.7.2.tgz#324b79046491f2cf0b9d9e275381198c8246b380" - integrity sha512-s6yEOSfPpB6g1T2+C5ZOUt5cQOMhjI98IVmmvMNb5cdiqHoxSUfACISHqU/wZy+q4ar/A9jW0pbNj7sa50XRVA== - dependencies: - "@types/bonjour" "^3.5.9" - "@types/connect-history-api-fallback" "^1.3.5" - "@types/serve-index" "^1.9.1" - "@types/sockjs" "^0.3.33" - "@types/ws" "^8.2.2" - ansi-html-community "^0.0.8" - bonjour "^3.5.0" - chokidar "^3.5.2" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^1.6.0" - default-gateway "^6.0.3" - del "^6.0.0" - express "^4.17.1" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.0" - ipaddr.js "^2.0.1" - open "^8.0.9" - p-retry "^4.5.0" - portfinder "^1.0.28" - schema-utils "^4.0.0" - selfsigned "^1.10.11" - serve-index "^1.9.1" - sockjs "^0.3.21" - spdy "^4.0.2" - strip-ansi "^7.0.0" - webpack-dev-middleware "^5.3.0" - ws "^8.1.0" - -webpack-merge@^4.1.5: - version "4.2.2" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" - integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== - dependencies: - lodash "^4.17.15" - -webpack-merge@^5.7.3: - version "5.8.0" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" - integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== - dependencies: - clone-deep "^4.0.1" - wildcard "^2.0.0" - -webpack-sources@^3.2.0, webpack-sources@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.2.tgz#d88e3741833efec57c4c789b6010db9977545260" - integrity sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw== - -webpack@5.57.1: - version "5.57.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.57.1.tgz#ead5ace2c17ecef2ae8126f143bfeaa7f55eab44" - integrity sha512-kHszukYjTPVfCOEyrUthA3jqJwduY/P3eO8I0gMNOZGIQWKAwZftxmp5hq6paophvwo9NoUrcZOecs9ulOyyTg== - dependencies: - "@types/eslint-scope" "^3.7.0" - "@types/estree" "^0.0.50" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.4.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.8.3" - es-module-lexer "^0.9.0" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.4" - json-parse-better-errors "^1.0.2" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.1.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.2.0" - webpack-sources "^3.2.0" - -webpack@5.65.0: - version "5.65.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.65.0.tgz#ed2891d9145ba1f0d318e4ea4f89c3fa18e6f9be" - integrity sha512-Q5or2o6EKs7+oKmJo7LaqZaMOlDWQse9Tm5l1WAfU/ujLGN5Pb0SqGeVkN/4bpPmEqEP5RnVhiqsOtWtUVwGRw== - dependencies: - "@types/eslint-scope" "^3.7.0" - "@types/estree" "^0.0.50" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.4.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.8.3" - es-module-lexer "^0.9.0" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.4" - json-parse-better-errors "^1.0.2" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.1.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.3.1" - webpack-sources "^3.2.2" - -websocket-driver@>=0.5.1, websocket-driver@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" - integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.4" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" - integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== - -which@2.0.2, which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -which@^1.2.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -wildcard@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" - integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== - -workerpool@6.1.5: - version "6.1.5" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" - integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -ws@^8.1.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.4.0.tgz#f05e982a0a88c604080e8581576e2a063802bed6" - integrity sha512-IHVsKe2pjajSUIl4KYMQOdlyliovpEPquKkqbwswulszzI7r0SfQrxnXdWAEqOlDCLrVSJzo+O1hAwdog2sKSQ== - -ws@~7.4.2: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@16.2.0, yargs@^16.1.1: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/build.gradle.kts b/build.gradle.kts index fcb9c04..c12c822 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.2.3" +version = "0.2.4" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 6566320..739d432 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -64,5 +64,3 @@ idea { isDownloadJavadoc = true } } - -//tasks.assemble { dependsOn(tasks.htmlDependencyReport) } diff --git a/buildSrc/repositories.settings.gradle.kts b/buildSrc/repositories.settings.gradle.kts index 670ad93..ff14164 100644 --- a/buildSrc/repositories.settings.gradle.kts +++ b/buildSrc/repositories.settings.gradle.kts @@ -1,4 +1,4 @@ -@Suppress("UnstableApiUsage") +@Suppress("UnstableApiUsage") // Central declaration of repositories is an incubating feature dependencyResolutionManagement { // https://github.com/gradle/gradle/issues/15754#issuecomment-763614651 @@ -11,10 +11,10 @@ dependencyResolutionManagement { repositories { mavenCentral() - gradlePluginPortal() jitpack() - maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") - maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") + gradlePluginPortal() +// maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") +// maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") // Declare the Node.js download repository ivy("https://nodejs.org/dist/") { @@ -37,7 +37,7 @@ dependencyResolutionManagement { gradlePluginPortal() mavenCentral() jitpack() - maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") +// maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") } } @@ -45,5 +45,12 @@ dependencyResolutionManagement { } fun RepositoryHandler.jitpack() { - maven("https://jitpack.io") + maven("https://jitpack.io") { +// content { +// includeGroup("com.github.aSemy") +// includeGroup("com.github.adamko-dev") +// includeGroup("com.github.adamko-dev.kotka-streams") +// includeGroup("dev.adamko.kotka") +// } + } } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts index 28cd163..a20acb2 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts @@ -3,6 +3,7 @@ package dev.adamko.kafkatorio.lang import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.kotlin import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension +import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension plugins { @@ -21,4 +22,12 @@ afterEvaluate { } } + rootProject.extensions.configure { + // kotlin-js adds a directory in the root-dir for the Yarn lock. + // That's a bit annoying. It's a little neater if it's in the + // gradle dir, next to the version-catalog. + lockFileDirectory = rootProject.rootDir.resolve("gradle/kotlin-js-store") + } + + } diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index 43783ab..d179872 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -1,5 +1,6 @@ import {handleConfigurationUpdate} from "./main/config-update/handleConfigurationUpdate"; require("./main/events/registerHandlers") +require("./main/commands/kafkatorioCommands") script.on_configuration_changed(handleConfigurationUpdate) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts index 3302903..3145904 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts @@ -16,5 +16,4 @@ interface FactorioConfigurationUpdate extends KafkatorioPacket { factorioData: FactorioGameDataUpdate; modVersion: string; packetType: PacketType; - prototypes: FactorioPrototype[]; } diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts index 56b2136..4d5583a 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts @@ -50,6 +50,7 @@ interface MapTiles extends FactorioObjectData { } interface MapChunk extends FactorioObjectData { + area: MapBoundingBox; objectName: ObjectName; position: MapChunkPosition; tiles: MapTiles; diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts index 67464d8..01d4958 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts @@ -6,6 +6,12 @@ interface FactorioPrototype { prototypeObjectName: PrototypeObjectName; } +interface FactorioPrototypes extends KafkatorioPacket { + modVersion: string; + packetType: PacketType; + prototypes: FactorioPrototype[]; +} + interface MapTilePrototype extends FactorioPrototype { canBeMined: boolean; collisionMasks: string[]; diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts index 7ac53c3..ad34892 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts @@ -1,6 +1,6 @@ // Generated by TypeScriptGenerator - do not edit this file manually -type PacketType = "EVENT" | "CONFIG"; +type PacketType = "EVENT" | "CONFIG" | "PROTOTYPES"; interface KafkatorioPacket { modVersion: string; @@ -27,12 +27,17 @@ interface MapEntityPosition { y: double; } -interface MapChunkPosition { - x: int; - y: int; -} - interface MapTilePosition { x: int; y: int; } + +interface MapBoundingBox { + bottomRight: MapTilePosition; + topLeft: MapTilePosition; +} + +interface MapChunkPosition { + x: int; + y: int; +} diff --git a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts new file mode 100644 index 0000000..8087f98 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts @@ -0,0 +1,12 @@ +import {emitPrototypes} from "../config-update/prototypes"; + +commands.add_command( + "kafkatorio", + "kafkatorio innit bruv", + (e: CustomCommandData) => { + if (e.parameter == undefined) { + // do nothing + } else if ("PROTOTYPES" == e.parameter.toUpperCase()) { + emitPrototypes() + } + }) diff --git a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts index 7298fb1..2d58bbd 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts @@ -1,6 +1,6 @@ import {emitPacket} from "../emitKafkatorioPacket"; -import {convertPrototypes} from "./convertPrototypes"; import {updateGlobal} from "./updateGlobal"; +import {emitPrototypes} from "./prototypes"; export function handleConfigurationUpdate(changeData: ConfigurationChangedData) { updateGlobal() @@ -9,10 +9,10 @@ export function handleConfigurationUpdate(changeData: ConfigurationChangedData) modVersion: global.MOD_VERSION, packetType: "CONFIG", allMods: allMods(changeData), - factorioData: factorioData(changeData), - prototypes: convertPrototypes() + factorioData: factorioData(changeData) }) + emitPrototypes() } function factorioData(changeData: ConfigurationChangedData): FactorioGameDataUpdate { diff --git a/modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts b/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts similarity index 76% rename from modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts rename to modules/events-mod/src/main/typescript/main/config-update/prototypes.ts index b9c6203..634d1a8 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/convertPrototypes.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts @@ -1,6 +1,15 @@ import {Converters} from "../events/converters"; +import {emitPacket} from "../emitKafkatorioPacket"; -export function convertPrototypes(): FactorioPrototype[] { +export function emitPrototypes() { + emitPacket({ + modVersion: global.MOD_VERSION, + packetType: "PROTOTYPES", + prototypes: prototypes() + }) +} + +function prototypes(): FactorioPrototype[] { let prototypes: FactorioPrototype[] = [] prototypes.push(...getMapTilePrototypes()) diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index 7e23e95..0ce8342 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -114,4 +114,11 @@ export namespace Converters { // } // } + export function convertBoundingBox(bb: BoundingBoxTable): MapBoundingBox { + return { + topLeft: mapTilePosition(bb.left_top as PositionTable), + bottomRight: mapTilePosition(bb.right_bottom as PositionTable), + } + } + } diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index 9197f56..d9fdf14 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -1,6 +1,6 @@ import {Converters} from "./converters" import {emitEvent} from "./emitEvent"; -import mapChunkPosition = Converters.mapChunkPosition; + export function handlePlayerUpdate(tick: uint, eventType: string, playerIndex: uint) { let player: LuaPlayer = game.players[playerIndex] @@ -80,7 +80,8 @@ export function handleChunkUpdate( let mapChunk: MapChunk = { objectName: "MapChunk", tiles: createMapTiles(surfaceIndex, convertedTiles), - position: mapChunkPosition(position) + position: Converters.mapChunkPosition(position), + area: Converters.convertBoundingBox(area) } emitEvent(mapChunk, tick, eventType) diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index e164848..29a486e 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.2", + "version": "0.2.4", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -74,9 +74,9 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.15.0.tgz", - "integrity": "sha512-hEpW+nRL3q5vg3aOxbNbYpwARxYzMTncihurAucwnpQ/IDc4w4PrO2/OWHI5R+PkZSEQUY5LSRxG7qrGqDeWHQ==" + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.16.0.tgz", + "integrity": "sha512-I6W1lhRkeE+mHzLBKBVIDZdquwBjBYaS7jkV0CKiWWkA9ptGqT+MblOkNUdYZ0ykR2Rvn1eF/6pzh8WwQ+mYVQ==" }, "typescript": { "version": "4.5.4", diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index c769a23..7d2945b 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.2", + "version": "0.2.4", "private": true, "scripts": { "build": "tstl", @@ -14,7 +14,7 @@ "lua-types": "^2.11.0", "@types/node": "^12.0.8", "typescript-to-lua": "1.3.0", - "typed-factorio": "0.15.0", + "typed-factorio": "0.16.0", "typescript": "4.5.4" }, "license": "UNLICENSED", diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index f49820c..74f6aaa 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -20,7 +20,7 @@ kotlin { } } - @Suppress("UnstableApiUsage") // enforcedPlatform is incubating + @Suppress("UnstableApiUsage") // platform + version catalogs is incubating sourceSets { all { diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index 1c4854b..48ce592 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -19,8 +19,8 @@ data class MapEntityPosition( ) { fun toMapChunkPosition() = MapChunkPosition( - (x / MAP_CHUNK_SIZE).roundToInt(), - (y / MAP_CHUNK_SIZE).roundToInt(), + (x / MAP_CHUNK_SIZE).toInt(), + (y / MAP_CHUNK_SIZE).toInt(), ) } @@ -36,10 +36,17 @@ data class MapChunkPosition( val x: Int, val y: Int, ) { + fun toMapEntityPosition() = MapEntityPosition( x * MAP_CHUNK_SIZE.toDouble(), y * MAP_CHUNK_SIZE.toDouble(), ) + + fun toMapTilePosition() = MapChunkPosition( + x * MAP_CHUNK_SIZE, + y * MAP_CHUNK_SIZE, + ) + } /** @@ -62,6 +69,14 @@ data class MapTilePosition( } + +@Serializable +data class MapBoundingBox( + val topLeft: MapTilePosition, + val bottomRight: MapTilePosition, +) + + /** * Red, green, blue and alpha values, all in range `[0, 1]` or all in range `[0, 255]` if any * value is > 1. @@ -81,7 +96,7 @@ data class Colour( ) { /** True if any value is greater than 1, so the values are hexadecimal. */ - fun isDecimal(): Boolean { + fun isHexadecimal(): Boolean { return red > 1f || green > 1f || blue > 1f @@ -89,9 +104,9 @@ data class Colour( } /** True if all values are between `[0..1]`. */ - fun isPercentage(): Boolean = !isDecimal() + fun isPercentage(): Boolean = !isHexadecimal() - fun asDecimal() = if (isPercentage()) { + fun asHexadecimal() = if (isPercentage()) { Colour( (red * 255).coerceIn(0f..255f), (green * 255).coerceIn(0f..255f), diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt index 8fd0333..994656a 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt @@ -1,10 +1,7 @@ package dev.adamko.kafkatorio.events.schema import kotlinx.serialization.EncodeDefault -import kotlinx.serialization.Required -import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient @Serializable @@ -12,10 +9,9 @@ data class FactorioConfigurationUpdate( override val modVersion: String, val factorioData: FactorioGameDataUpdate, val allMods: List, - val prototypes: List, ) : KafkatorioPacket() { @EncodeDefault - override val packetType = PacketType.CONFIG + override val packetType = PacketType.CONFIG } @Serializable diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt index 2ab170a..ff179db 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -119,6 +119,7 @@ data class SurfaceData( data class MapChunk( val tiles: MapTiles, val position: MapChunkPosition, + val area: MapBoundingBox, ) : FactorioObjectData() { @EncodeDefault override val objectName = ObjectName.MapChunk diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt index ea820a4..31dfabd 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt @@ -10,6 +10,16 @@ import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive +@Serializable +data class FactorioPrototypes( + override val modVersion: String, + val prototypes: List, +) : KafkatorioPacket() { + @EncodeDefault + override val packetType = PacketType.PROTOTYPES +} + + @Serializable(with = FactorioPrototypeSerializer::class) sealed class FactorioPrototype { @EncodeDefault @@ -49,6 +59,7 @@ data class MapTilePrototype( val name: String, val layer: UInt, val mapColour: Colour, + @Serializable(with = FactorioJsonListSerializer::class) val collisionMasks: List, val order: String, /** Can the tile be mined for resources? */ diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt index 42551b0..e477521 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt @@ -10,8 +10,17 @@ import kotlinx.serialization.json.JsonTransformingSerializer import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonObject +val jsonMapperKafkatorio = Json { + prettyPrint = true + prettyPrintIndent = " " +// serializersModule = FactorioEvent.kxsModule +// serializersModule = KafkatorioPacket.kxsModule + FactorioEvent.kxsModule +// serializersModule = SerializersModule { } +} + /** Factorio outputs lists as Json objects - this serializer converts an object back to a list. */ +// actually I'm not sure that it does - I think *empty* lists get encoded as *empty* objects internal class ListAsObjectSerializer(dataSerializer: KSerializer) : JsonTransformingSerializer>(ListSerializer(dataSerializer)) { @@ -26,10 +35,18 @@ internal class ListAsObjectSerializer(dataSerializer: KSerializer) : ) } -val jsonMapperKafkatorio = Json { - prettyPrint = true - prettyPrintIndent = " " -// serializersModule = FactorioEvent.kxsModule -// serializersModule = KafkatorioPacket.kxsModule + FactorioEvent.kxsModule -// serializersModule = SerializersModule { } + +/** Factorio outputs lists as Json objects - this serializer converts an object back to a list. */ +// actually I'm not sure that it does - I think *empty* lists get encoded as *empty* objects +internal class FactorioJsonListSerializer(dataSerializer: KSerializer) : + JsonTransformingSerializer>(ListSerializer(dataSerializer)) { + + override fun transformDeserialize(element: JsonElement): JsonElement { + return if (element is JsonObject) { + JsonArray(emptyList()) + } else { + element + } + } + } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt index 9248fb7..56e86cb 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt @@ -20,6 +20,7 @@ sealed class KafkatorioPacket { enum class PacketType { EVENT, CONFIG, + PROTOTYPES, } } @@ -41,6 +42,7 @@ object KafkatorioPacketSerializer : JsonContentPolymorphicSerializer FactorioEvent.serializer() KafkatorioPacket.PacketType.CONFIG -> FactorioConfigurationUpdate.serializer() + KafkatorioPacket.PacketType.PROTOTYPES -> FactorioPrototypes.serializer() null -> throw Exception("Unknown KafkatorioPacket ${key}: '$type' ") } diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt new file mode 100644 index 0000000..98da4ef --- /dev/null +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt @@ -0,0 +1,45 @@ +package dev.adamko.kafkatorio.events.schema + +import io.kotest.core.spec.style.BehaviorSpec +import kotlinx.serialization.decodeFromString + +class PrototypesTest : BehaviorSpec( + { + Given("Prototypes Json") { + //Language=JSON + val raw = """ + { + "modVersion":"0.2.4", + "packetType":"PROTOTYPES", + "prototypes":[ + { + "prototypeObjectName":"LuaTilePrototype", + "name":"tile-unknown", + "order":"z-a", + "layer":0, + "collisionMasks":{ + + }, + "mapColour":{ + "red":0, + "green":0, + "blue":0, + "alpha":255 + }, + "canBeMined":false + } + ] + } +""".trimIndent() + + Then("expect can be parsed") { + val data = jsonMapperKafkatorio.decodeFromString(raw) + println(data) + } + + } + } +) { + companion object { + } +} diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt index 3086333..705b607 100644 --- a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt @@ -16,6 +16,8 @@ fun main(args: Array) { addAll(KafkatorioPacket::class.sealedSubclasses) addAll(FactorioObjectData::class.sealedSubclasses) addAll(FactorioPrototype::class.sealedSubclasses) + add(FactorioPrototypes::class) + add(FactorioConfigurationUpdate::class) }, mappings = mapOf( // builtin Factorio numeric types > `typed-factorio/generated/builtin-types.d.ts` @@ -40,7 +42,6 @@ fun main(args: Array) { println(definitions) } else -> { - val outPath = Path(filename) outPath.createDirectories() @@ -64,17 +65,18 @@ private fun splitDefinitions(definitions: String): Map { .split("\n\n") .groupBy { def -> when { - "extends FactorioObjectData" in def || - "interface FactorioObjectData" in def || - "type ObjectName" in def -> "object-data.d.ts" - "extends FactorioPrototype" in def || - "interface FactorioPrototype" in def || - "type PrototypeObjectName" in def -> "prototype.d.ts" - "extends FactorioConfigurationUpdate" in def || - "interface FactorioConfigurationUpdate" in def || - "FactorioGameDataUpdate" in def || - "FactorioModInfo" in def -> "config-update.d.ts" - else -> "schema.d.ts" + "extends FactorioObjectData " in def || + "interface FactorioObjectData " in def || + "type ObjectName " in def -> "object-data.d.ts" + "extends FactorioPrototype " in def || + "interface FactorioPrototypes " in def || + "interface FactorioPrototype " in def || + "type PrototypeObjectName " in def -> "prototype.d.ts" + "extends FactorioConfigurationUpdate " in def || + "interface FactorioConfigurationUpdate " in def || + "FactorioGameDataUpdate " in def || + "FactorioModInfo " in def -> "config-update.d.ts" + else -> "schema.d.ts" } } .mapValues { (_, def) -> diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 2495d2f..241711d 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - id("dev.adamko.kafkatorio.lang.kotlin-jvm") + dev.adamko.kafkatorio.lang.`kotlin-jvm` kotlin("plugin.serialization") application } @@ -36,6 +36,16 @@ dependencies { implementation(libs.bundles.logging) implementation("com.sksamuel.scrimage:scrimage-core:4.0.24") + + val kotkaVersion = "0.0.5" + implementation("com.github.adamko-dev.kotka-streams:kotka-streams:$kotkaVersion") { + isChanging = true + } +// val kotkaVersion = "main-SNAPSHOT" +// implementation("dev.adamko.kotka:kotka-streams:$kotkaVersion") { +// isChanging = true +// } + } application { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt new file mode 100644 index 0000000..c67696a --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt @@ -0,0 +1,78 @@ +package dev.adamko.kafkatorio.admin + +import dev.adamko.kafkatorio.events.schema.FactorioObjectData +import dev.adamko.kafkatorio.events.schema.KafkatorioPacket +import dev.adamko.kafkatorio.processor.KafkatorioTopology +import java.util.concurrent.TimeUnit +import mu.KotlinLogging +import org.apache.kafka.clients.admin.Admin +import org.apache.kafka.clients.admin.CreateTopicsResult +import org.apache.kafka.clients.admin.NewTopic + +private val logger = KotlinLogging.logger {} + +fun main() { + CreateTopics.create() +} + +object CreateTopics { + + private val kafkaAdmin: Admin = + Admin.create( + mapOf( + "bootstrap.servers" to "http://localhost:9092", + "client.id" to "warehouse.setup-admin", + ) + ) + + fun create() { + + KafkatorioPacket.PacketType.values().forEach { packetType -> + + val kafkatorioTopics = buildList { + add(KafkatorioTopology.sourceTopic) + when (packetType) { + KafkatorioPacket.PacketType.EVENT -> + FactorioObjectData.ObjectName.values().forEach { objectName -> + add("kafkatorio.${packetType.name}.${objectName.name}") + } + KafkatorioPacket.PacketType.CONFIG -> + add("kafkatorio.${packetType.name}.FactorioConfigurationUpdate") + KafkatorioPacket.PacketType.PROTOTYPES -> + add("kafkatorio.${packetType.name}.all") + } + } + val result = kafkatorioTopics + .run { + logger.info("Creating $size topics") + kafkaAdmin.createTopics { this } + } + + // wait for all brokers to become aware of the created topics + Thread.sleep(TimeUnit.SECONDS.toMillis(5)) + + result.values().forEach { + logger.info("Created topic: ${it.key} ${it.value.get()}") + } + + Thread.sleep(TimeUnit.SECONDS.toMillis(5)) + + logger.info("Listing topics") + kafkaAdmin.listTopics() + .listings() + .get() + .forEach { + logger.info("Topic: $it") + } + } + } + + private fun Admin.createTopics( + numPartitions: Int = 1, + replicationFactor: Short = 1, + topicNames: () -> Collection, + ): CreateTopicsResult = + createTopics(topicNames().map { + NewTopic(it, numPartitions, replicationFactor) + }) +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/GlobalKTableDefinition.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/GlobalKTableDefinition.kt index d2b3fb7..630dea6 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/GlobalKTableDefinition.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/GlobalKTableDefinition.kt @@ -2,30 +2,30 @@ package dev.adamko.kafkatorio.extensions.kafkastreams import org.apache.kafka.streams.state.QueryableStoreTypes.timestampedKeyValueStore -/** - * * update topic [topicName] - * * plus table-source topic [tableName] - * * plus state store [globalStoreName] - * - * equals a GlobalTableDefinition - */ -abstract class GlobalKTableDefinition( - val tableName: String, - override val serdes: KeyValueSerdes, - val globalStoreName: String = "$tableName-store", - /** - * The backing topic, from which this table will be filled. - * - * Updates to items can be sent or received with this topic. - */ - final override val topicName: String = "$tableName-topic", - val storeType: TimestampedQueryStoreType = timestampedKeyValueStore(), -) : TopicDefinition { - val topicNames: Set - - init { - require(tableName != topicName) - require(tableName != globalStoreName) - topicNames = setOf(tableName, topicName) - } -} +///** +// * * update topic [topicName] +// * * plus table-source topic [tableName] +// * * plus state store [globalStoreName] +// * +// * equals a GlobalTableDefinition +// */ +//abstract class GlobalKTableDefinition( +// val tableName: String, +// override val serdes: KeyValueSerdes, +// val globalStoreName: String = "$tableName-store", +// /** +// * The backing topic, from which this table will be filled. +// * +// * Updates to items can be sent or received with this topic. +// */ +// final override val topicName: String = "$tableName-topic", +// val storeType: TimestampedQueryStoreType = timestampedKeyValueStore(), +//) : TopicDefinition { +// val topicNames: Set +// +// init { +// require(tableName != topicName) +// require(tableName != globalStoreName) +// topicNames = setOf(tableName, topicName) +// } +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KGroupedStream.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KGroupedStream.kt new file mode 100644 index 0000000..d93e27f --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KGroupedStream.kt @@ -0,0 +1,32 @@ +package dev.adamko.kafkatorio.extensions.kafkastreams +// +//import org.apache.kafka.common.utils.Bytes +//import org.apache.kafka.streams.kstream.KGroupedStream +//import org.apache.kafka.streams.kstream.KTable +//import org.apache.kafka.streams.kstream.Materialized +//import org.apache.kafka.streams.state.KeyValueStore +// +// +//fun KGroupedStream.count( +// name: String? = null, +// materialized: Materialized>? = null, +//): KTable { +// return when { +// name != null && materialized != null -> count(withName(name), materialized) +// name == null && materialized != null -> count(materialized) +// name != null && materialized == null -> count(withName(name)) +// else -> count() +// } +//} +// +// +// +//// CogroupedKStream cogroup(final Aggregator aggregator); +//// KTable aggregate(final Initializer initializer,final Aggregator aggregator, final Named named, final Materialized> materialized); +//// TimeWindowedKStream windowedBy(final Windows windows); +////KTable count(final Materialized> materialized); +////KTable reduce(final Reducer reducer); +////KTable reduce(final Reducer reducer, final Named named, final Materialized> materialized); +////KTable reduce(final Reducer reducer,final Materialized> materialized); +////SessionWindowedKStream windowedBy(final SessionWindows windows); +////TimeWindowedKStream windowedBy(final SlidingWindows windows); diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamExtensions.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamExtensions.kt index 28d1541..e29186f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamExtensions.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamExtensions.kt @@ -1,111 +1,152 @@ package dev.adamko.kafkatorio.extensions.kafkastreams - -import dev.adamko.kafkatorio.extensions.kafkastreams.KStreamExtensions.flatMap -import dev.adamko.kafkatorio.extensions.kafkastreams.KStreamExtensions.groupBy -import dev.adamko.kafkatorio.extensions.kafkastreams.KStreamExtensions.map -import dev.adamko.kafkatorio.extensions.kafkastreams.KStreamExtensions.mapValues -import dev.adamko.kafkatorio.extensions.kafkastreams.KafkaStreamsExtensions.withName -import dev.adamko.kafkatorio.extensions.kafkastreams.KeyPairExtensions.kvPair -import dev.adamko.kafkatorio.extensions.kafkastreams.KeyPairExtensions.toKeyValue -import org.apache.kafka.streams.KeyValue -import org.apache.kafka.streams.kstream.Grouped -import org.apache.kafka.streams.kstream.KGroupedStream -import org.apache.kafka.streams.kstream.KStream -import org.apache.kafka.streams.kstream.Transformer -import org.apache.kafka.streams.processor.ProcessorContext - -object KStreamExtensions { - -// /** @see KStream.map */ -// inline fun > KStream.map( -// name: String, -// crossinline mapper: (key: inK, value: inV) -> outV -// ): KStream = -// map({ k, v -> mapper(k, v).asKeyValue() }, withName(name)) - - /** @see KStream.map */ - inline fun KStream.map( - name: String, - crossinline mapper: (key: inK, value: inV) -> Pair - ): KStream = - map({ k, v -> mapper(k, v).toKeyValue() }, withName(name)) - - /** Wrapper for [KStream.mapValues] */ - fun KStream.mapValues( - name: String, - mapper: (key: K, value: inV) -> outV - ): KStream = - mapValues({ k, v -> mapper(k, v) }, withName(name)) - -// /** @see KStream.flatMap */ -// inline fun > KStream.flatMap( -// name: String, -// crossinline mapper: (key: inK, value: inV) -> Iterable -// ): KStream = flatMap( -// { k, v -> mapper(k, v).map { a: outV -> a.asKeyValue() } }, -// withName(name) -// ) - - /** @see KStream.flatMap */ - inline fun KStream.flatMap( - name: String, - crossinline mapper: (key: inK, value: inV) -> Iterable> - ): KStream = flatMap( - { k, v -> mapper(k, v).map { it.toKeyValue() } }, - withName(name) - ) - - /** @see KStream.groupBy */ - inline fun KStream.groupBy( - grouped: Grouped, - crossinline keySelector: KeyValue.() -> outK - ): KGroupedStream = - groupBy( - { k, v -> (k kvPair v).keySelector() }, - grouped - ) - - - -// @JvmName("flatMapKeyValuePairs") -// inline fun KStream.flatMap( -// name: String, -// crossinline mapper: (key: inK, value: inV) -> Iterable> -// ): KStream = -// flatMap( -// { k, v -> mapper(k, v).map { it.asKeyPair() } }, -// withName(name) -// ) - -// inline fun KStream.mapValues( -// name: String, -// crossinline mapper: (readOnlyKey: K, value: inV) -> outV -// ): KStream = -// map({ k, v -> (k to mapper(v)).asKeyPair() }, KafkaStreamsExtensions.withName(name)) - -} - - -//open class TransformerKt( -//) : Transformer> { // -// val onClose: TransformerKt.() -> Unit = {} -// val transformer: TransformerKt.(key: inK, value: inV) -> KeyValue? = -// {} +//import org.apache.kafka.streams.kstream.Grouped +//import org.apache.kafka.streams.kstream.KGroupedStream +//import org.apache.kafka.streams.kstream.KStream +//import org.apache.kafka.streams.kstream.Produced +//import org.apache.kafka.streams.processor.TopicNameExtractor // -// private lateinit var _context: ProcessorContext -// val context: ProcessorContext? -// get() = if (this::_context.isInitialized) _context else null +//// /** @see KStream.map */ +//// inline fun > KStream.map( +//// name: String, +//// crossinline mapper: (key: inK, value: inV) -> outV +//// ): KStream = +//// map({ k, v -> mapper(k, v).asKeyValue() }, withName(name)) // -// override fun init(context: ProcessorContext) { -// this._context = context -// } +///** @see KStream.map */ +//inline fun KStream.map( +// name: String, +// crossinline mapper: (key: inK, value: inV) -> Pair +//): KStream = +// map({ k, v -> mapper(k, v).toKeyValue() }, withName(name)) // -// override fun close() { -// onClose() -// } +///** @see [KStream.mapValues] */ +//inline fun KStream.mapValues( +// name: String, +// crossinline mapper: (key: K, value: inV) -> outV +//): KStream = mapValues({ k, v -> mapper(k, v) }, withName(name)) // -// override fun transform(key: inK, value: inV): KeyValue? { -// return transformer(key, value) -// } -//} +//// /** @see KStream.flatMap */ +//// inline fun > KStream.flatMap( +//// name: String, +//// crossinline mapper: (key: inK, value: inV) -> Iterable +//// ): KStream = flatMap( +//// { k, v -> mapper(k, v).map { a: outV -> a.toKeyValue() } }, +//// withName(name) +//// ) +// +///** @see KStream.flatMap */ +//inline fun KStream.flatMap( +// name: String, +// crossinline mapper: (key: inK, value: inV) -> Iterable> +//): KStream = flatMap( +// { k, v -> mapper(k, v).map { it.toKeyValue() } }, +// withName(name) +//) +// +///** @see KStream.groupBy */ +//fun KStream.groupBy( +// grouped: Grouped, +// keySelector: (K, V) -> outK +//): KGroupedStream = groupBy(keySelector, grouped) +// +//fun KStream.to( +// produced: Produced, +// topicNameExtractor: TopicNameExtractor, +//) = to(topicNameExtractor, produced) +// +//fun KStream.filter( +// name: String, +// predicate: (K, V) -> Boolean, +//): KStream = filter(predicate, withName(name)) +// +// +//fun KStream.filterNot( +// name: String, +// predicate: (K, V) -> Boolean, +//): KStream = filterNot(predicate, withName(name)) +// +// +//fun KStream.merge( +// name: String, +// other: KStream, +//): KStream = merge(other, withName(name)) +// +// +//// KStream filter(final Predicate predicate, final Named named); +//// KStream filterNot(final Predicate predicate, final Named named); +// +//// @JvmName("flatMapKeyValuePairs") +//// inline fun KStream.flatMap( +//// name: String, +//// crossinline mapper: (key: inK, value: inV) -> Iterable> +//// ): KStream = +//// flatMap( +//// { k, v -> mapper(k, v).map { it.asKeyPair() } }, +//// withName(name) +//// ) +// +//// inline fun KStream.mapValues( +//// name: String, +//// crossinline mapper: (readOnlyKey: K, value: inV) -> outV +//// ): KStream = +//// map({ k, v -> (k to mapper(v)).asKeyPair() }, KafkaStreamsExtensions.withName(name)) +// +// +////open class TransformerKt( +////) : Transformer> { +//// +//// val onClose: TransformerKt.() -> Unit = {} +//// val transformer: TransformerKt.(key: inK, value: inV) -> KeyValue? = +//// {} +//// +//// private lateinit var _context: ProcessorContext +//// val context: ProcessorContext? +//// get() = if (this::_context.isInitialized) _context else null +//// +//// override fun init(context: ProcessorContext) { +//// this._context = context +//// } +//// +//// override fun close() { +//// onClose() +//// } +//// +//// override fun transform(key: inK, value: inV): KeyValue? { +//// return transformer(key, value) +//// } +////} +//// +//// +//// /** one or the other or both */ +//// KTable toTable(final Named named, Materialized> materialized); +//// KStream join(final GlobalKTable globalTable, KeyValueMapper keySelector, ValueJoinerWithKey joiner, Named named); +//// KStream leftJoin(final GlobalKTable globalTable, KeyValueMapper keySelector, ValueJoinerWithKey valueJoiner, Named named); +//// KStream flatTransform(final TransformerSupplier>> transformerSupplier, Named named, String... stateStoreNames); +//// KStream flatTransform(final TransformerSupplier>> transformerSupplier, String... stateStoreNames); +//// KStream transform(final TransformerSupplier> transformerSupplier, Named named, String... stateStoreNames); +//// KStream transform(final TransformerSupplier> transformerSupplier, String... stateStoreNames); +//// KStream flatMap(final KeyValueMapper>> mapper, Named named); +//// KStream map(final KeyValueMapper> mapper, Named named); +//// KGroupedStream groupBy(final KeyValueMapper keySelector, Grouped grouped); +//// KStream selectKey(final KeyValueMapper mapper, Named named); +//// KStream join(final KStream otherStream, ValueJoinerWithKey joiner, JoinWindows windows, StreamJoined streamJoined); +//// KStream leftJoin(final KStream otherStream, ValueJoinerWithKey joiner, JoinWindows windows, StreamJoined streamJoined); +//// KStream outerJoin(final KStream otherStream, ValueJoinerWithKey joiner, JoinWindows windows, StreamJoined streamJoined); +//// KStream flatMapValues(final ValueMapperWithKey> mapper, Named named); +//// KStream flatTransformValues(final ValueTransformerWithKeySupplier> valueTransformerSupplier, Named named, String... stateStoreNames); +//// KStream mapValues(final ValueMapperWithKey mapper, Named named); +//// KStream transformValues(final ValueTransformerWithKeySupplier valueTransformerSupplier, Named named, String... stateStoreNames); +//// KStream join(final KTable table, ValueJoinerWithKey joiner, Joined joined); +//// KStream leftJoin(final KTable table, ValueJoinerWithKey joiner, Joined joined); +//// BranchedKStream split(final Named named); +//// KGroupedStream groupByKey(final Grouped grouped); +//// KStream merge(final KStream stream, final Named named); +//// KStream peek(final ForeachAction action, final Named named); +//// KStream repartition(final Repartitioned repartitioned); +//// void foreach(final ForeachAction action, final Named named); +//// void print(final Printed printed); +//// void process(final ProcessorSupplier processorSupplier, Named named, String... stateStoreNames); +//// void to(final String topic, Produced produced); +//// void to(final TopicNameExtractor topicExtractor, Produced produced); +//// diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamTransform.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamTransform.kt index b6cfd63..fa6837d 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamTransform.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamTransform.kt @@ -1,90 +1,90 @@ package dev.adamko.kafkatorio.extensions.kafkastreams - -import dev.adamko.kafkatorio.extensions.kafkastreams.KeyPairExtensions.toKeyValue -import kotlin.experimental.ExperimentalTypeInference -import org.apache.kafka.streams.KeyValue -import org.apache.kafka.streams.kstream.KStream -import org.apache.kafka.streams.kstream.Transformer -import org.apache.kafka.streams.kstream.TransformerSupplier -import org.apache.kafka.streams.processor.ProcessorContext - -/** @see KStream.transform */ -inline fun KStream.transformKt( - crossinline block: BuildTransformer -): KStream { - - val transformer = object : Transformer> { - - private lateinit var scope: TransformerScope - - override fun init(procContext: ProcessorContext) { - scope = TransformerScope(procContext) - scope.block() - } - - override fun close() { - scope.close() - } - - override fun transform(key: inK, value: inV): KeyValue? { - return scope.mapper(key, value)?.toKeyValue() - } - } - - return transform({ transformer }) -} - -/** @see KStream.transform */ -@OptIn(ExperimentalTypeInference::class) -inline fun > KStream.transformKt2( - @BuilderInference block: Transformer.() -> Unit -): KStream { - - val transformer = object : Transformer> { - - private lateinit var scope: TransformerScope - - override fun init(procContext: ProcessorContext) { - scope = TransformerScope(procContext) - } - - override fun close() { - scope.close() - - sequence { - - } - } - - override fun transform(key: inK, value: inV): KeyValue? { - return scope.mapper(key, value)?.toKeyValue() - } - } - - return transform(TransformerSupplier { transformer }) -} - -typealias BuildTransformer = TransformerScope.() -> Unit - -typealias TransformerMapper = (key: inK, value: inV) -> Pair? -typealias TransformerCloseHandler = (ProcessorContext) -> Unit - -open class TransformerScope( - val processorContext: ProcessorContext, -) : AutoCloseable { - - private var closeHandler: TransformerCloseHandler = {} - lateinit var mapper: TransformerMapper - - fun handleClose(closeHandler: TransformerCloseHandler) { - this.closeHandler = closeHandler - } - - fun mapEach(mapper: TransformerMapper) { - this.mapper = mapper - } - - override fun close() { - closeHandler(processorContext) - } -} +// +//import dev.adamko.kafkatorio.extensions.kafkastreams.* +//import kotlin.experimental.ExperimentalTypeInference +//import org.apache.kafka.streams.KeyValue +//import org.apache.kafka.streams.kstream.KStream +//import org.apache.kafka.streams.kstream.Transformer +//import org.apache.kafka.streams.kstream.TransformerSupplier +//import org.apache.kafka.streams.processor.ProcessorContext +// +///** @see KStream.transform */ +//inline fun KStream.transformKt( +// crossinline block: BuildTransformer +//): KStream { +// +// val transformer = object : Transformer> { +// +// private lateinit var scope: TransformerScope +// +// override fun init(procContext: ProcessorContext) { +// scope = TransformerScope(procContext) +// scope.block() +// } +// +// override fun close() { +// scope.close() +// } +// +// override fun transform(key: inK, value: inV): KeyValue? { +// return scope.mapper(key, value)?.toKeyValue() +// } +// } +// +// return transform({ transformer }) +//} +// +///** @see KStream.transform */ +//@OptIn(ExperimentalTypeInference::class) +//inline fun > KStream.transformKt2( +// @BuilderInference block: Transformer.() -> Unit +//): KStream { +// +// val transformer = object : Transformer> { +// +// private lateinit var scope: TransformerScope +// +// override fun init(procContext: ProcessorContext) { +// scope = TransformerScope(procContext) +// } +// +// override fun close() { +// scope.close() +// +// sequence { +// +// } +// } +// +// override fun transform(key: inK, value: inV): KeyValue? { +// return scope.mapper(key, value)?.toKeyValue() +// } +// } +// +// return transform(TransformerSupplier { transformer }) +//} +// +//typealias BuildTransformer = TransformerScope.() -> Unit +// +//typealias TransformerMapper = (key: inK, value: inV) -> Pair? +//typealias TransformerCloseHandler = (ProcessorContext) -> Unit +// +//open class TransformerScope( +// val processorContext: ProcessorContext, +//) : AutoCloseable { +// +// private var closeHandler: TransformerCloseHandler = {} +// lateinit var mapper: TransformerMapper +// +// fun handleClose(closeHandler: TransformerCloseHandler) { +// this.closeHandler = closeHandler +// } +// +// fun mapEach(mapper: TransformerMapper) { +// this.mapper = mapper +// } +// +// override fun close() { +// closeHandler(processorContext) +// } +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KTableExtensions.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KTableExtensions.kt index c573dd3..5986f81 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KTableExtensions.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KTableExtensions.kt @@ -1,19 +1,48 @@ package dev.adamko.kafkatorio.extensions.kafkastreams - -import dev.adamko.kafkatorio.extensions.kafkastreams.KTableExtensions.mapValues -import dev.adamko.kafkatorio.extensions.kafkastreams.KafkaStreamsExtensions.withName -import org.apache.kafka.streams.kstream.KTable - -object KTableExtensions { - - /** @see [KTable.mapValues] */ - fun KTable.mapValues( - name: String, - mapper: (readOnlyKey: K, value: inV) -> outV - ): KTable = - mapValues( - { k, v -> mapper(k, v) }, - withName(name) - ) - -} +// +// +//import org.apache.kafka.streams.KeyValue +//import org.apache.kafka.streams.kstream.Grouped +//import org.apache.kafka.streams.kstream.KGroupedTable +//import org.apache.kafka.streams.kstream.KTable +//import org.apache.kafka.streams.kstream.KeyValueMapper +// +///** @see [KTable.mapValues] */ +//fun KTable.mapValues( +// name: String, +// mapper: (readOnlyKey: K, value: inV) -> outV +//): KTable = +// mapValues( +// { k, v -> mapper(k, v) }, +// withName(name) +// ) +// +///** @See [KTable.groupBy] */ +//fun KTable.groupBy( +// grouped: Grouped? = null, +// selector: KeyValueMapper> +//): KGroupedTable = when (grouped) { +// null -> groupBy(selector) +// else -> groupBy(selector, grouped) +//} +// +// +//// +//// KStream toStream(final KeyValueMapper mapper,final Named named); +//// KTable join(final KTable other,final ValueJoiner joiner,final Named named,final Materialized> materialized); +//// KTable join(final KTable other,final Function foreignKeyExtractor,final ValueJoiner joiner,final Named named,final Materialized> materialized); +//// +//// KTable leftJoin(final KTable other,final ValueJoiner joiner,final Named named,final Materialized> materialized); +//// +//// KTable outerJoin(final KTable other,final ValueJoiner joiner,final Named named,final Materialized> materialized); +//// KTable leftJoin(final KTable other,final Function foreignKeyExtractor,final ValueJoiner joiner,final Named named,final Materialized> materialized); +//// KTable mapValues(final ValueMapper mapper,final Named named,final Materialized> materialized); +//// KTable mapValues(final ValueMapperWithKey mapper,final Named named,final Materialized> materialized); +//// KTable transformValues(final ValueTransformerWithKeySupplier transformerSupplier,final Materialized> materialized,final Named named,final String... stateStoreNames); +////KStream toStream(final Named named); +/////** materialized, named - optional */ +////KTable filter(final Predicate predicate,final Named named,final Materialized> materialized); +/////** materialized, named - optional */ +////KTable filterNot(final Predicate predicate,final Named named,final Materialized> materialized); +////KTable suppress(final Suppressed suppressed); +////String queryableStoreName(); diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KafkaStreamsExtensions.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KafkaStreamsExtensions.kt index 1bea403..54a9d0f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KafkaStreamsExtensions.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KafkaStreamsExtensions.kt @@ -1,93 +1,91 @@ package dev.adamko.kafkatorio.extensions.kafkastreams - -import org.apache.kafka.common.serialization.Serde -import org.apache.kafka.streams.kstream.Grouped -import org.apache.kafka.streams.kstream.Joined -import org.apache.kafka.streams.kstream.Materialized -import org.apache.kafka.streams.kstream.Named -import org.apache.kafka.streams.kstream.Produced -import org.apache.kafka.streams.kstream.Repartitioned -import org.apache.kafka.streams.processor.StateStore - -/** Helpful extensions & shortcuts for Kafka Streams */ -object KafkaStreamsExtensions { - - /** @see [Named] */ - fun withName(name: String): Named = Named.`as`(name) - -// @Suppress("FunctionName") -// inline fun MaterializedAs( -// tableDefinition: GlobalTableDefinition -// ) = MaterializedAs( -// tableDefinition.globalStoreName, -// tableDefinition.serdes.keySerde, -// tableDefinition.serdes.valueSerde -// ) - - /** @see Materialized */ - inline fun materializedAs( - name: String, - keySerde: Serde,//= kxsJsonSerde(), - valueSerde: Serde,//= kxsJsonSerde(), - ): Materialized = - Materialized.`as`(name) - .withKeySerde(keySerde) - .withValueSerde(valueSerde) - - /** @see Repartitioned */ - inline fun repartitionedAs( - name: String, - keySerde: Serde, - valueSerde: Serde, - ): Repartitioned = - Repartitioned.`as`(name) - .withKeySerde(keySerde) - .withValueSerde(valueSerde) - - /** @see Produced */ - fun producedAs(name: String): Produced = - Produced.`as`(name) - - /** @see Produced */ - inline fun producedAs( - name: String, - keySerde: Serde, - valueSerde: Serde, - ): Produced = - producedAs(name) - .withKeySerde(keySerde) - .withValueSerde(valueSerde) - -// @Suppress("FunctionName") -// fun JoinedAs(name: String): Joined = -// Joined.`as`(name) - - /** @see Joined */ - inline fun joinedAs( - name: String, - keySerde: Serde,// = kxsJsonSerde(), - valueSerde: Serde,//= kxsJsonSerde(), - otherValueSerde: Serde?,//= kxsJsonSerde(), - ): Joined = - Joined.`as`(name) - .withKeySerde(keySerde) - .withValueSerde(valueSerde) - .withOtherValueSerde(otherValueSerde) - - /** @see [Grouped.`as`] */ - inline fun groupedAs( - name: String, - keySerde: Serde?, //= kxsJsonSerde(), - valueSerde: Serde?,// = kxsJsonSerde(), - ): Grouped = - Grouped.`as`(name) - .withKeySerde(keySerde) - .withValueSerde(valueSerde) - -// fun InteractiveQueryService.getQueryableStore( -// tableDef: GlobalTableDefinition -// ): Optional>> { -// return getQueryableStore(tableDef.globalStoreName, tableDef.storeType) -// } - -} +// +//import org.apache.kafka.common.serialization.Serde +//import org.apache.kafka.streams.kstream.Grouped +//import org.apache.kafka.streams.kstream.Joined +//import org.apache.kafka.streams.kstream.Materialized +//import org.apache.kafka.streams.kstream.Named +//import org.apache.kafka.streams.kstream.Produced +//import org.apache.kafka.streams.kstream.Repartitioned +//import org.apache.kafka.streams.processor.StateStore +// +///** Helpful extensions & shortcuts for Kafka Streams */ +// +// +///** @see [Named] */ +//fun withName(name: String): Named = Named.`as`(name) +// +//// @Suppress("FunctionName") +//// inline fun MaterializedAs( +//// tableDefinition: GlobalTableDefinition +//// ) = MaterializedAs( +//// tableDefinition.globalStoreName, +//// tableDefinition.serdes.keySerde, +//// tableDefinition.serdes.valueSerde +//// ) +// +///** @see Materialized */ +//inline fun materializedAs( +// name: String, +// keySerde: Serde,//= kxsJsonSerde(), +// valueSerde: Serde,//= kxsJsonSerde(), +//): Materialized = +// Materialized.`as`(name) +// .withKeySerde(keySerde) +// .withValueSerde(valueSerde) +// +///** @see Repartitioned */ +//inline fun repartitionedAs( +// name: String, +// keySerde: Serde, +// valueSerde: Serde, +//): Repartitioned = +// Repartitioned.`as`(name) +// .withKeySerde(keySerde) +// .withValueSerde(valueSerde) +// +///** @see Produced */ +//fun producedAs(name: String): Produced = +// Produced.`as`(name) +// +///** @see Produced */ +//inline fun producedAs( +// name: String, +// keySerde: Serde, +// valueSerde: Serde, +//): Produced = +// producedAs(name) +// .withKeySerde(keySerde) +// .withValueSerde(valueSerde) +// +//// @Suppress("FunctionName") +//// fun JoinedAs(name: String): Joined = +//// Joined.`as`(name) +// +///** @see Joined */ +//inline fun joinedAs( +// name: String, +// keySerde: Serde,// = kxsJsonSerde(), +// valueSerde: Serde,//= kxsJsonSerde(), +// otherValueSerde: Serde?,//= kxsJsonSerde(), +//): Joined = +// Joined.`as`(name) +// .withKeySerde(keySerde) +// .withValueSerde(valueSerde) +// .withOtherValueSerde(otherValueSerde) +// +///** @see [Grouped.`as`] */ +//inline fun groupedAs( +// name: String, +// keySerde: Serde?, //= jsonMapper.serde(), +// valueSerde: Serde?, //= jsonMapper.serde(), +//): Grouped = +// Grouped.`as`(name) +// .withKeySerde(keySerde) +// .withValueSerde(valueSerde) +// +//// fun InteractiveQueryService.getQueryableStore( +//// tableDef: GlobalTableDefinition +//// ): Optional>> { +//// return getQueryableStore(tableDef.globalStoreName, tableDef.storeType) +//// } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyPairExtensions.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyPairExtensions.kt index 0bb1d21..4856ba4 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyPairExtensions.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyPairExtensions.kt @@ -1,35 +1,33 @@ package dev.adamko.kafkatorio.extensions.kafkastreams - -import org.apache.kafka.streams.KeyValue -import org.apache.kafka.streams.state.ValueAndTimestamp - -object KeyPairExtensions { - - inline fun Pair.toKeyValue(): KeyValue = - KeyValue.pair(first, second) - - infix fun K.kvPair(value: V): KeyValue = KeyValue(this, value) - - infix fun V.timestamped(timestamp: Long): ValueAndTimestamp = - ValueAndTimestamp.make(this, timestamp) - - - @JvmName("keyValueGetKey") - operator fun KeyValue.component1(): K = key - @JvmName("keyValueGetValue") - operator fun KeyValue.component2(): V = value - - - @JvmName("keyValueTimestampGetKey") - operator fun KeyValue>.component1(): K = key - @JvmName("keyValueTimestampGetValue") - operator fun KeyValue>.component2(): V = value.value() - @JvmName("keyValueTimestampGetTimestamp") - operator fun KeyValue>.component3(): Long = value.timestamp() - - - @JvmName("valueTimestampGetValue") - operator fun ValueAndTimestamp.component1(): V = value() - @JvmName("valueTimestampGetTimestamp") - operator fun ValueAndTimestamp.component2(): Long = timestamp() -} +// +//import org.apache.kafka.streams.KeyValue +//import org.apache.kafka.streams.state.ValueAndTimestamp +// +// +//inline fun Pair.toKeyValue(): KeyValue = +// KeyValue.pair(first, second) +// +//infix fun K.kvPair(value: V): KeyValue = KeyValue(this, value) +// +//infix fun V.timestamped(timestamp: Long): ValueAndTimestamp = +// ValueAndTimestamp.make(this, timestamp) +// +// +//@JvmName("keyValueGetKey") +//operator fun KeyValue.component1(): K = key +//@JvmName("keyValueGetValue") +//operator fun KeyValue.component2(): V = value +// +// +//@JvmName("keyValueTimestampGetKey") +//operator fun KeyValue>.component1(): K = key +//@JvmName("keyValueTimestampGetValue") +//operator fun KeyValue>.component2(): V = value.value() +//@JvmName("keyValueTimestampGetTimestamp") +//operator fun KeyValue>.component3(): Long = value.timestamp() +// +// +//@JvmName("valueTimestampGetValue") +//operator fun ValueAndTimestamp.component1(): V = value() +//@JvmName("valueTimestampGetTimestamp") +//operator fun ValueAndTimestamp.component2(): Long = timestamp() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyValueSerdes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyValueSerdes.kt index 431af7f..fa1aa18 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyValueSerdes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyValueSerdes.kt @@ -1,40 +1,41 @@ package dev.adamko.kafkatorio.extensions.kafkastreams -import dev.adamko.kafkatorio.extensions.kafkastreams.KotlinxSerializationExtensions.kxsJsonSerde -import org.apache.kafka.common.serialization.Serde -import org.apache.kafka.common.serialization.Serdes -import org.apache.kafka.streams.kstream.Consumed -import org.apache.kafka.streams.kstream.Produced -import org.apache.kafka.streams.kstream.Repartitioned - -/** - * A wrapper for two [Serde]s - [one for the Key][keySerde], [another for the Value][valueSerde]. - */ -open class KeyValueSerdes( - val keySerde: Serde, - val valueSerde: Serde, -) { - - fun consumer(name: String): Consumed = - Consumed.with(keySerde, valueSerde).withName(name) - - fun producer(name: String): Produced = - Produced.with(keySerde, valueSerde).withName(name) - - fun repartitioned(name: String): Repartitioned = - Repartitioned.with(keySerde, valueSerde).withName(name) - - companion object { - inline fun kxsJson(): KeyValueSerdes = - KeyValueSerdes( - kxsJsonSerde(), - kxsJsonSerde(), - ) - - fun string(): KeyValueSerdes = - KeyValueSerdes( - Serdes.String(), - Serdes.String(), - ) - } -} +//import dev.adamko.kafkatorio.extensions.kxs.KotlinxSerializationExtensions.serde +//import dev.adamko.kafkatorio.processor.jsonMapper +//import org.apache.kafka.common.serialization.Serde +//import org.apache.kafka.common.serialization.Serdes +//import org.apache.kafka.streams.kstream.Consumed +//import org.apache.kafka.streams.kstream.Produced +//import org.apache.kafka.streams.kstream.Repartitioned +// +///** +// * A wrapper for two [Serde]s - [one for the Key][keySerde], [another for the Value][valueSerde]. +// */ +//open class KeyValueSerdes( +// val keySerde: Serde, +// val valueSerde: Serde, +//) { +// +// fun consumer(name: String): Consumed = +// Consumed.with(keySerde, valueSerde).withName(name) +// +// fun producer(name: String): Produced = +// Produced.with(keySerde, valueSerde).withName(name) +// +// fun repartitioned(name: String): Repartitioned = +// Repartitioned.with(keySerde, valueSerde).withName(name) +// +// companion object { +// inline fun kxsJson(): KeyValueSerdes = +// KeyValueSerdes( +// jsonMapper.serde(), +// jsonMapper.serde(), +// ) +// +// fun string(): KeyValueSerdes = +// KeyValueSerdes( +// Serdes.String(), +// Serdes.String(), +// ) +// } +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KotlinxSerializationExtensions.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KotlinxSerializationExtensions.kt deleted file mode 100644 index 86acd86..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KotlinxSerializationExtensions.kt +++ /dev/null @@ -1,55 +0,0 @@ -package dev.adamko.kafkatorio.extensions.kafkastreams - -import kotlinx.serialization.decodeFromString -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import org.apache.kafka.common.serialization.Deserializer -import org.apache.kafka.common.serialization.Serde -import org.apache.kafka.common.serialization.Serializer - -object KotlinxSerializationExtensions { - - inline fun Json.kafkaSerializer() = Serializer { topic: String, data: T -> - runCatching { - encodeToString(data).encodeToByteArray() -// jsonMapper.encodeToString(data as T).encodeToByteArray() - }.getOrElse { e -> - println( - """ - Exception on encodeToString - Topic: $topic - topicData: $data - topicData as T: ${data as T} - """.trimIndent() - ) - e.printStackTrace() - throw e - } - } - - inline fun Json.kafkaDeserializer() = Deserializer { topic: String, data: ByteArray -> - runCatching { - decodeFromString(data.decodeToString()) - }.getOrElse { e -> - println( - """ - Exception on decodeFromString, - Topic: $topic - topicData: $data - topicData as T: ${data as T} - """.trimIndent() - ) - e.printStackTrace() - throw e - } - } - - - inline fun Json.serde() = object : Serde { - - override fun serializer(): Serializer = kafkaSerializer() - - override fun deserializer(): Deserializer = kafkaDeserializer() - } - -} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicData.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicData.kt index dd23620..33027c2 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicData.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicData.kt @@ -1,17 +1,17 @@ package dev.adamko.kafkatorio.extensions.kafkastreams -import org.apache.kafka.streams.KeyValue - -interface TopicData { - - val topicKey: K - - companion object { - fun > T.toPair(): Pair = topicKey to this - fun > T.toKeyValue(): KeyValue = KeyValue.pair(topicKey, this) - - operator fun > T.component1(): K = topicKey - operator fun > T.component2(): T = this - - } -} +//import org.apache.kafka.streams.KeyValue +// +//interface TopicData { +// +// val topicKey: K +// +// companion object { +// fun > T.toPair(): Pair = topicKey to this +// fun > T.toKeyValue(): KeyValue = KeyValue.pair(topicKey, this) +// +// operator fun > T.component1(): K = topicKey +// operator fun > T.component2(): T = this +// +// } +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicDefinition.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicDefinition.kt index 49ce40f..fbb2ea5 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicDefinition.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicDefinition.kt @@ -1,42 +1,42 @@ package dev.adamko.kafkatorio.extensions.kafkastreams; -/** - * A definition for all topics that are created in Kafka. - * - * These can be used to create KTopics, KTables, or GlobalKTables. - */ -interface TopicDefinition { - - /** unique kafka processor id */ - val pid: String - get() = this::class.simpleName!! - - /** - * Unique name for each [TopicDefinition] - * - * https://devshawn.com/blog/apache-kafka-topic-naming-conventions/ - * - * https://www.xeotek.com/topic-naming-conventions-how-do-i-name-my-topics-5-recommendations-with-examples/ - * - * Domain: warehouse - * Operation: stock-management - * Data type: - * - cdc=all instances of a specific object/thing/item, - * - cmd=command (mutation), - * - fct=fact (information (complete or partial) - * about an event at specific point in time) - * - sys=internal system topic - not meant for external use - * - tbl=a global table store (must be paired with another topic) - * Description: the data type - * - * Version: stored in message header - * - * ``` - * warehouse.stock-management.sts/cdc/cmd.warehouse-item - * ``` - */ - val topicName: String - - val serdes: KeyValueSerdes - -} +///** +// * A definition for all topics that are created in Kafka. +// * +// * These can be used to create KTopics, KTables, or GlobalKTables. +// */ +//interface TopicDefinition { +// +// /** unique kafka processor id */ +// val pid: String +// get() = this::class.simpleName!! +// +// /** +// * Unique name for each [TopicDefinition] +// * +// * https://devshawn.com/blog/apache-kafka-topic-naming-conventions/ +// * +// * https://www.xeotek.com/topic-naming-conventions-how-do-i-name-my-topics-5-recommendations-with-examples/ +// * +// * Domain: warehouse +// * Operation: stock-management +// * Data type: +// * - cdc=all instances of a specific object/thing/item, +// * - cmd=command (mutation), +// * - fct=fact (information (complete or partial) +// * about an event at specific point in time) +// * - sys=internal system topic - not meant for external use +// * - tbl=a global table store (must be paired with another topic) +// * Description: the data type +// * +// * Version: stored in message header +// * +// * ``` +// * warehouse.stock-management.sts/cdc/cmd.warehouse-item +// * ``` +// */ +// val topicName: String +// +// val serdes: KeyValueSerdes +// +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/aliases.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/aliases.kt index 8461387..78f35cf 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/aliases.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/aliases.kt @@ -4,4 +4,4 @@ import org.apache.kafka.streams.state.QueryableStoreType import org.apache.kafka.streams.state.ReadOnlyKeyValueStore import org.apache.kafka.streams.state.ValueAndTimestamp -typealias TimestampedQueryStoreType = QueryableStoreType>> +//typealias TimestampedQueryStoreType = QueryableStoreType>> diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kxs/KotlinxSerializationExtensions.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kxs/KotlinxSerializationExtensions.kt new file mode 100644 index 0000000..fc94a20 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kxs/KotlinxSerializationExtensions.kt @@ -0,0 +1,55 @@ +package dev.adamko.kafkatorio.extensions.kxs + +//import kotlinx.serialization.decodeFromString +//import kotlinx.serialization.encodeToString +//import kotlinx.serialization.json.Json +//import org.apache.kafka.common.serialization.Deserializer +//import org.apache.kafka.common.serialization.Serde +//import org.apache.kafka.common.serialization.Serializer +// +//object KotlinxSerializationExtensions { +// +// inline fun Json.kafkaSerializer() = Serializer { topic: String, data: T -> +// runCatching { +// encodeToString(data).encodeToByteArray() +//// jsonMapper.encodeToString(data as T).encodeToByteArray() +// }.getOrElse { e -> +// println( +// """ +// Exception on encodeToString +// Topic: $topic +// topicData: $data +// topicData as T: ${data as T} +// """.trimIndent() +// ) +// e.printStackTrace() +// throw e +// } +// } +// +// inline fun Json.kafkaDeserializer() = Deserializer { topic: String, data: ByteArray -> +// runCatching { +// decodeFromString(data.decodeToString()) +// }.getOrElse { e -> +// println( +// """ +// Exception on decodeFromString, +// Topic: $topic +// topicData: $data +// topicData as T: ${data as T} +// """.trimIndent() +// ) +// e.printStackTrace() +// throw e +// } +// } +// +// +// inline fun Json.serde() = object : Serde { +// +// override fun serializer(): Serializer = kafkaSerializer() +// +// override fun deserializer(): Deserializer = kafkaDeserializer() +// } +// +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index c80da00..6205e76 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -1,28 +1,39 @@ package dev.adamko.kafkatorio.processor import com.sksamuel.scrimage.ImmutableImage +import com.sksamuel.scrimage.color.RGBColor import com.sksamuel.scrimage.nio.PngWriter -import com.sksamuel.scrimage.pixels.Pixel -import com.sksamuel.scrimage.pixels.PixelTools import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate import dev.adamko.kafkatorio.events.schema.FactorioEvent import dev.adamko.kafkatorio.events.schema.FactorioObjectData +import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket +import dev.adamko.kafkatorio.events.schema.MAP_CHUNK_SIZE import dev.adamko.kafkatorio.events.schema.MapChunk import dev.adamko.kafkatorio.events.schema.MapChunkPosition import dev.adamko.kafkatorio.events.schema.MapTile import dev.adamko.kafkatorio.events.schema.MapTilePosition import dev.adamko.kafkatorio.events.schema.MapTilePrototype import dev.adamko.kafkatorio.events.schema.MapTiles -import dev.adamko.kafkatorio.extensions.kafkastreams.KafkaStreamsExtensions.materializedAs -import dev.adamko.kafkatorio.extensions.kafkastreams.KeyPairExtensions.toKeyValue -import dev.adamko.kafkatorio.extensions.kafkastreams.KotlinxSerializationExtensions.serde -import dev.adamko.kafkatorio.extensions.kafkastreams.TopicData -import dev.adamko.kafkatorio.extensions.kafkastreams.TopicData.Companion.toKeyValue +import dev.adamko.kotka.extensions.consumedAs +import dev.adamko.kotka.extensions.groupedAs +import dev.adamko.kotka.extensions.materializedAs +import dev.adamko.kotka.extensions.producedAs +import dev.adamko.kotka.extensions.streams.filter +import dev.adamko.kotka.extensions.streams.flatMap +import dev.adamko.kotka.extensions.streams.mapValues +import dev.adamko.kotka.extensions.streams.merge +import dev.adamko.kotka.extensions.streams.to +import dev.adamko.kotka.kxs.serde +import dev.adamko.kotka.topicdata.TopicRecord +import dev.adamko.kotka.topicdata.flatMapTopicRecords +import dev.adamko.kotka.topicdata.mapTopicRecords +import java.awt.Color import java.awt.image.BufferedImage import java.io.File import java.time.Duration import kotlin.math.roundToInt +import kotlin.math.sign import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString @@ -34,7 +45,7 @@ import org.apache.kafka.streams.TopologyDescription import org.apache.kafka.streams.kstream.Consumed import org.apache.kafka.streams.kstream.KStream import org.apache.kafka.streams.kstream.KTable -import org.apache.kafka.streams.kstream.Produced +import org.apache.kafka.streams.processor.RecordContext import org.apache.kafka.streams.state.QueryableStoreTypes import org.apache.kafka.streams.state.ReadOnlyKeyValueStore import org.apache.kafka.streams.state.ValueAndTimestamp @@ -45,27 +56,24 @@ class KafkatorioTopology( private val builder: StreamsBuilder = StreamsBuilder(), ) { - private val sourceTopic = "factorio-server-log" + companion object { + const val sourceTopic = "factorio-server-log" + } private lateinit var tilePrototypesStore: ReadOnlyKeyValueStore> + fun build() { parseAndSplitServerLog() sendPlayerUpdatesToWebSocket() // createMapTileImages() val tilePrototypesTable: KTable = tilePrototypesTable() + mapChunksStream() val topology = builder.build() val streams = KafkaStreams(topology, appProps.kafkaConfig) - tilePrototypesStore = streams.store( - StoreQueryParameters.fromNameAndType( - tilePrototypesTable.queryableStoreName(), - QueryableStoreTypes.timestampedKeyValueStore() - ) - ) - streams.setUncaughtExceptionHandler(StreamsExceptionHandler()) Runtime.getRuntime().addShutdownHook(Thread { streams.close(Duration.ofSeconds(1)) }) @@ -76,30 +84,47 @@ class KafkatorioTopology( println(description) streams.start() + + tilePrototypesStore = streams.store( + StoreQueryParameters.fromNameAndType( + tilePrototypesTable.queryableStoreName(), + QueryableStoreTypes.timestampedKeyValueStore() + ) + ) } private fun parseAndSplitServerLog() { builder.stream( sourceTopic, - Consumed.with(Serdes.String(), Serdes.String()) + consumedAs( + "read-raw-packets-from-server", + Serdes.String(), + Serdes.String(), + ) ) - .mapValues { readOnlyKey, value -> - println("Mapping $readOnlyKey:$value") + .mapValues("decode-packets") { _: String, value: String -> +// println("Mapping $readOnlyKey:$value") jsonMapper.decodeFromString(value) } .to( - { _, value, _ -> + producedAs( + "split-server-log", + Serdes.String(), + KafkatorioPacketSerde + ) + ) { _: String, value: KafkatorioPacket, _: RecordContext -> // println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") - when (value) { - is FactorioEvent -> - "kafkatorio.${value.packetType.name}.${value.data.objectName.name}" - is FactorioConfigurationUpdate -> - "kafkatorio.${value.packetType.name}.FactorioConfigurationUpdate" - } - }, - Produced.with(Serdes.String(), KafkatorioPacketSerde) - ) + when (value) { + is FactorioEvent -> + "kafkatorio.${value.packetType.name}.${value.data.objectName.name}" + is FactorioConfigurationUpdate -> + "kafkatorio.${value.packetType.name}.FactorioConfigurationUpdate" + is FactorioPrototypes -> + "kafkatorio.${value.packetType.name}.all" + } + } + } private fun sendPlayerUpdatesToWebSocket() { @@ -108,21 +133,23 @@ class KafkatorioTopology( Consumed.with(Serdes.String(), KafkatorioPacketSerde) ) .foreach { _, value -> +// println("sending ${value.packetType} packet to websocket") websocketServer.sendMessage(jsonMapper.encodeToString(value)) } } private fun tilePrototypesTable(): KTable { return builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.CONFIG}.FactorioConfigurationUpdate", - Consumed.with(Serdes.String(), jsonMapper.serde()) + "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", + Consumed.with(Serdes.String(), jsonMapper.serde()) ) - .flatMap { _, update: FactorioConfigurationUpdate -> - update - .prototypes + .flatMap("flatten-map-tile-prototypes") { _, prototypes: FactorioPrototypes -> + prototypes.prototypes .filterIsInstance() .map { proto -> proto.name to proto } - .map { it.toKeyValue() } + } + .peek { _, value -> + println("tile prototype: ${value.name}") } .toTable( materializedAs( @@ -132,22 +159,52 @@ class KafkatorioTopology( ) ) } - + + @Serializable + data class MapChunkDataPosition( + val position: MapChunkPosition, + val surfaceIndex: Int, + ) + + @Serializable + data class MapChunkData( + val position: MapChunkPosition, + val surfaceIndex: Int, + val tiles: Set, + ) : TopicRecord { + override val topicKey = MapChunkDataPosition(position, surfaceIndex) + + constructor(key: MapChunkDataPosition, tiles: Set) : + this(key.position, key.surfaceIndex, tiles) + } + private fun mapChunksStream() { val luaTilesUpdatesStream: KStream = builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", - Consumed.with(Serdes.String(), jsonMapper.serde()) - ) - .filter { _, event: FactorioEvent -> event.data is MapTiles } - .mapValues { _, event: FactorioEvent -> (event.data as? MapTiles)!! } - - val chunkTilesUpdateStream: KStream = builder.stream( "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", Consumed.with(Serdes.String(), jsonMapper.serde()) ) - .filter { _, event: FactorioEvent -> event.data is MapChunk } - .mapValues { _, event: FactorioEvent -> (event.data as? MapChunk)!!.tiles } + .peek { k, v -> + println("trying to handle MapChunk update... $k: ${v.eventType}") + } + .filter("events.filter.map-tiles") { _: String, event: FactorioEvent -> event.data is MapTiles } + .mapValues("events.extract-map-tiles") { _, event: FactorioEvent -> (event.data as? MapTiles)!! } + .peek { key, value -> + println("MapChunk update $key, tiles count: ${value.tiles.size}") + } + + val chunkTilesUpdateStream: KStream = builder.stream( + "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", + Consumed.with(Serdes.String(), jsonMapper.serde()) + ) + .peek { k, v -> + println("trying to handle LuaTiles update... $k: ${v.eventType} / ${v.data is MapChunk}") + } + .filter("events.filter.map-chunks") { _: String, event: FactorioEvent -> event.data is MapChunk } + .mapValues("events.extract-map-chunks") { _, event: FactorioEvent -> (event.data as? MapChunk)!!.tiles } + .peek { key, value -> + println("LuaTiles update $key, tiles count: ${value.tiles.size}") + } @Serializable data class TileUpdateRecordKey( @@ -160,96 +217,109 @@ class KafkatorioTopology( val surfaceIndex: Int, val tilePosition: MapTilePosition, val tile: MapTile - ) : TopicData { + ) : TopicRecord { override val topicKey: TileUpdateRecordKey = TileUpdateRecordKey(surfaceIndex, tilePosition) } val allTileUpdatesStream: KStream = luaTilesUpdatesStream - .merge(chunkTilesUpdateStream) - .flatMap { _, mapTiles: MapTiles -> + .merge("luaTilesUpdatesStream-and-chunkTilesUpdateStream", chunkTilesUpdateStream) + .flatMapTopicRecords("all-tiles-convert-to-TileUpdateRecord") { _, mapTiles: MapTiles -> + println("all map tiles update ${mapTiles.tiles.size}") mapTiles.tiles.map { tile -> TileUpdateRecord( mapTiles.surfaceIndex, tile.position, tile - ).toKeyValue() + ) } } - @Serializable - data class MapChunkDataPosition( - val position: MapChunkPosition, - val surfaceIndex: Int, - ) - - @Serializable - data class MapChunkData( - val position: MapChunkPosition, - val surfaceIndex: Int, - val tiles: Set, - ) : TopicData { - override val topicKey = MapChunkDataPosition(position, surfaceIndex) - - constructor(key: MapChunkDataPosition, tiles: Set) : - this(key.position, key.surfaceIndex, tiles) - } - - val chunksTable = + val chunksTable: KTable = allTileUpdatesStream - .groupBy { _: TileUpdateRecordKey, value: TileUpdateRecord -> - MapChunkDataPosition( + .mapTopicRecords("map-tile-updates-to-MapChunkData") { _: TileUpdateRecordKey, value: TileUpdateRecord -> + val key = MapChunkDataPosition( value.tilePosition.toMapChunkPosition(), value.surfaceIndex, ) + MapChunkData(key, setOf(value.tile)) } - .aggregate( - { setOf() }, - ) { _: MapChunkDataPosition, v: TileUpdateRecord, tiles: Set -> - tiles + v.tile - } - .mapValues { chunkPosition: MapChunkDataPosition, tiles: Set -> - MapChunkData(chunkPosition, tiles) - } - - chunksTable.toStream() - .foreach { key: MapChunkDataPosition, value: MapChunkData -> - - - value.tiles - .map { tile -> - - val colour = tilePrototypesStore.get(tile.prototypeName) - .value() - .mapColour - .asDecimal() - - - val pixelColour = PixelTools.argb( - colour.alpha.roundToInt(), - colour.red.roundToInt(), - colour.green.roundToInt(), - colour.blue.roundToInt(), - ) - - Pixel( - tile.position.x, - tile.position.y, - pixelColour - ) - } - - val chunkImg = ImmutableImage.create(32, 32, BufferedImage.TYPE_INT_ARGB) - - val zoom = 1u - chunkImg.output( - PngWriter.MaxCompression, - File("${key.surfaceIndex}/$zoom/${key.position.x}/${key.position.y}.png") + // group all tiles by chunk position + .groupByKey( + groupedAs("group-tile-updates-per-chunk-position", jsonMapper.serde(), jsonMapper.serde()) ) + .reduce { tileA, tileB -> + tileA.copy(tiles = tileA.tiles + tileB.tiles) + } + + chunksTable + .toStream() + .foreach { key: MapChunkDataPosition, value: MapChunkData -> + runCatching { + saveMapTilesPng(key, value) + }.onFailure { e -> + println("error saving map tile png ${value.position}") + e.printStackTrace() + throw e + } } } + private fun saveMapTilesPng(key: MapChunkDataPosition, chunk: MapChunkData) { + val (xChunk, yChunk) = chunk.position.toMapTilePosition() + val xOffset = when (xChunk.sign >= 0) { + true -> {} + false -> {} + } + + val chunkImage = + ImmutableImage.filled( + MAP_CHUNK_SIZE, + MAP_CHUNK_SIZE, + Color.BLACK, + BufferedImage.TYPE_INT_ARGB + ) + + chunk.tiles.forEach { tile -> + + + val prototypeColour = tilePrototypesStore.get(tile.prototypeName) + .value() + .mapColour + .asHexadecimal() + + val rgbColour = RGBColor( + prototypeColour.red.roundToInt(), + prototypeColour.green.roundToInt(), + prototypeColour.blue.roundToInt(), + prototypeColour.alpha.roundToInt(), + ) + + val x = (tile.position.x - xChunk) * xChunk.sign + val y = (tile.position.y - yChunk) * yChunk.sign + + chunkImage.setColor( + tile.position.x, + tile.position.y, + rgbColour + ) + + } + + val zoom = 1u + val file = + File("kafkatorio-web-map/${key.surfaceIndex}/$zoom/${key.position.x}/${key.position.y}.png") + + require(file.mkdirs()) { + "error creating map tile directory ${file.absolutePath}" + } + + println("saving map tile $file") + + chunkImage.output(PngWriter.MaxCompression, file) + } + // // private fun createMapTileImages() { // diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt index 78009c3..e188560 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt @@ -5,7 +5,7 @@ import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler.StreamThr class StreamsExceptionHandler : StreamsUncaughtExceptionHandler { override fun handle(exception: Throwable): StreamThreadExceptionResponse { - println("${exception.message} - ${exception.stackTrace}") + exception.printStackTrace() return StreamThreadExceptionResponse.SHUTDOWN_APPLICATION } } diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index 2b7d71e..c8f48e4 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio FACTORIO_VERSION=1.1.50 -KAFKATORIO_VERSION=0.2.2 +KAFKATORIO_VERSION=0.2.4 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index 7425adc..363e10c 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.2.2 +KAFKATORIO_VERSION=0.2.4 diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index 7425adc..363e10c 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.2.2 +KAFKATORIO_VERSION=0.2.4 diff --git a/settings.gradle.kts b/settings.gradle.kts index d05230b..8d3ab2b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,6 @@ rootProject.name = "kafkatorio" include( - ":modules:events-mod", ":modules:events-schema", ":modules:events-server", @@ -22,13 +21,17 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") apply(from = "./buildSrc/repositories.settings.gradle.kts") -@Suppress("UnstableApiUsage") // centralized repositories is incubating +@Suppress("UnstableApiUsage") // Central declaration of repositories is an incubating feature dependencyResolutionManagement { + + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + repositories { mavenLocal { - content { - includeGroup("io.kvision") - } +//// content { +//// includeGroup("io.kvision") +//// includeGroup("dev.adamko.kotka") +//// } } } } From a7a095ecbfe04e0d2332c80cdacb2db8d5b385e0 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 19 Jan 2022 16:53:24 +0100 Subject: [PATCH 155/629] map tiles are now saved! --- .../main/typescript/main/events/converters.ts | 15 +-- .../main/typescript/main/events/handlers.ts | 7 +- .../main/events/registerHandlers.ts | 1 + .../events/schema/converters/colour.kt | 64 ++++++++++ .../events/schema/converters/positions.kt | 58 +++++++++ .../events/schema/factorioCommonData.kt | 70 +---------- .../events/schema/factorioLuaObjects.kt | 2 +- modules/events-server/.gitignore | 1 + modules/events-server/build.gradle.kts | 2 +- .../adamko/kafkatorio/admin/CreateTopics.kt | 6 +- .../processor/KafkatorioTopology.kt | 112 ++++++++++++------ .../kafka/streams/state/annotations.xml | 5 + .../adamko/kafkatorio/webmap/converters.kt | 27 ----- .../dev/adamko/kafkatorio/webmap/state.kt | 1 + 14 files changed, 220 insertions(+), 151 deletions(-) create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/colour.kt create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/positions.kt create mode 100644 modules/events-server/.gitignore create mode 100644 modules/events-server/src/main/resources/external-annotations/org/apache/kafka/streams/state/annotations.xml diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index 0ce8342..26b8e18 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -105,19 +105,10 @@ export namespace Converters { } } - // export function convertMapTilePositionToMapChunkPosition( - // tilePosition: TilePositionTable - // ): ChunkPositionTable { - // return { - // x: tilePosition.x / 32, - // y: tilePosition.y / 32, - // } - // } - - export function convertBoundingBox(bb: BoundingBoxTable): MapBoundingBox { + export function convertBoundingBox(bb: BoundingBoxRead): MapBoundingBox { return { - topLeft: mapTilePosition(bb.left_top as PositionTable), - bottomRight: mapTilePosition(bb.right_bottom as PositionTable), + topLeft: mapTilePosition(bb.left_top), + bottomRight: mapTilePosition(bb.right_bottom), } } diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index d9fdf14..a35da1b 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -57,14 +57,11 @@ export function handleChunkUpdate( eventType: string, surfaceIndex: uint, position: ChunkPositionTable, - area: BoundingBoxTable, + area: BoundingBoxRead, ) { let surface = game.get_surface(surfaceIndex) - // let x = (position as ChunkPositionTable).x * CHUNK_SIZE - // let y = (position as ChunkPositionTable).y * CHUNK_SIZE - let tiles: LuaTile[] = surface?.find_tiles_filtered({ area: area, // position: {x: x, y: y}, @@ -81,7 +78,7 @@ export function handleChunkUpdate( objectName: "MapChunk", tiles: createMapTiles(surfaceIndex, convertedTiles), position: Converters.mapChunkPosition(position), - area: Converters.convertBoundingBox(area) + area: Converters.convertBoundingBox(area), } emitEvent(mapChunk, tick, eventType) diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index faa7e2e..26f2e8f 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -9,6 +9,7 @@ import { import on_player_built_tile = defines.events.on_player_built_tile; import on_robot_built_tile = defines.events.on_robot_built_tile; + const mapEventIdToName = new LuaTable() for (const [k, v] of pairs(defines.events)) { mapEventIdToName.set(v, k) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/colour.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/colour.kt new file mode 100644 index 0000000..88926b3 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/colour.kt @@ -0,0 +1,64 @@ +package dev.adamko.kafkatorio.events.schema.converters + +import dev.adamko.kafkatorio.events.schema.Colour +import kotlin.math.roundToInt + + +/** True if any value is greater than 1, so the values are hexadecimal. */ +fun Colour.isHexadecimal(): Boolean { + return red > 1f + || green > 1f + || blue > 1f + || alpha > 1f +} + +/** True if all values are between `[0..1]`. */ +fun Colour.isPercentage(): Boolean = !isHexadecimal() + +fun Colour.toHexadecimal() = if (isPercentage()) { + Colour( + (red * 255).coerceIn(0f..255f), + (green * 255).coerceIn(0f..255f), + (blue * 255).coerceIn(0f..255f), + (alpha * 255).coerceIn(0f..255f), + ) +} else { + this +} + +fun Colour.toPercentage() = if (isPercentage()) { + this +} else { + Colour( + (red / 255).coerceIn(0f..1f), + (green / 255).coerceIn(0f..1f), + (blue / 255).coerceIn(0f..1f), + (alpha / 255).coerceIn(0f..1f), + ) +} + +fun Colour.toHexString(includeAlpha: Boolean = false): String { + + val hexConverter: Float.() -> String = if (isHexadecimal()) { + Float::decimalToHex + } else { + Float::percentageToHex + } + + val length = if (includeAlpha) 9 else 7 + return buildString(length) { + append('#') + append(red.hexConverter()) + append(green.hexConverter()) + append(blue.hexConverter()) + if (includeAlpha) { + append(alpha.hexConverter()) + } + } +} + +fun Float.decimalToHex(): String = + roundToInt().toString(16).padStart(2, ' ') + +fun Float.percentageToHex(): String = + times(255).roundToInt().toString(16).padStart(2, ' ') diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/positions.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/positions.kt new file mode 100644 index 0000000..1cb0ca1 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/positions.kt @@ -0,0 +1,58 @@ +package dev.adamko.kafkatorio.events.schema.converters + +import dev.adamko.kafkatorio.events.schema.MAP_CHUNK_SIZE +import dev.adamko.kafkatorio.events.schema.MapBoundingBox +import dev.adamko.kafkatorio.events.schema.MapChunkPosition +import dev.adamko.kafkatorio.events.schema.MapEntityPosition +import dev.adamko.kafkatorio.events.schema.MapTilePosition +import kotlin.math.floor + +operator fun MapTilePosition.times(factor: Int) = + MapTilePosition(x * factor, y * factor) + +operator fun MapTilePosition.div(divisor: Int) = + MapTilePosition(x / divisor, y / divisor) + +operator fun MapTilePosition.plus(addend: Int) = + MapTilePosition(x + addend, y + addend) + + +fun MapTilePosition.toMapChunkPosition() = + MapChunkPosition( + floor(x.toDouble() / MAP_CHUNK_SIZE.toDouble()).toInt(), + floor(y.toDouble() / MAP_CHUNK_SIZE.toDouble()).toInt(), + ) + + +fun MapEntityPosition.toMapTilePosition() = + MapChunkPosition(floor(x).toInt(), floor(y).toInt()) + +fun MapEntityPosition.toMapChunkPosition() = + MapChunkPosition( + floor(x / MAP_CHUNK_SIZE.toDouble()).toInt(), + floor(y / MAP_CHUNK_SIZE.toDouble()).toInt(), + ) + + +operator fun MapChunkPosition.times(factor: Int) = + MapChunkPosition(x * factor, y * factor) + +operator fun MapChunkPosition.plus(addend: Int) = + MapChunkPosition(x + addend, y + addend) + +operator fun MapChunkPosition.minus(subtrahend: Int) = + MapChunkPosition(x - subtrahend, y - subtrahend) + + +val MapChunkPosition.leftTopTile: MapTilePosition + get() = MapTilePosition( + x * MAP_CHUNK_SIZE, + y * MAP_CHUNK_SIZE, + ) + +val MapChunkPosition.rightBottomTile: MapTilePosition + get() = leftTopTile + (MAP_CHUNK_SIZE - 1) + + +val MapChunkPosition.boundingBox: MapBoundingBox + get() = MapBoundingBox(leftTopTile, rightBottomTile) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index 48ce592..f519e95 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -1,9 +1,9 @@ package dev.adamko.kafkatorio.events.schema -import kotlin.math.roundToInt import kotlinx.serialization.EncodeDefault import kotlinx.serialization.Serializable + const val MAP_CHUNK_SIZE = 32 /** @@ -16,14 +16,8 @@ const val MAP_CHUNK_SIZE = 32 data class MapEntityPosition( val x: Double, val y: Double, -) { +) - fun toMapChunkPosition() = MapChunkPosition( - (x / MAP_CHUNK_SIZE).toInt(), - (y / MAP_CHUNK_SIZE).toInt(), - ) - -} /** Coordinates of a chunk in a [SurfaceData] where each integer `x`/`y` represents a different * chunk. @@ -35,19 +29,8 @@ data class MapEntityPosition( data class MapChunkPosition( val x: Int, val y: Int, -) { +) - fun toMapEntityPosition() = MapEntityPosition( - x * MAP_CHUNK_SIZE.toDouble(), - y * MAP_CHUNK_SIZE.toDouble(), - ) - - fun toMapTilePosition() = MapChunkPosition( - x * MAP_CHUNK_SIZE, - y * MAP_CHUNK_SIZE, - ) - -} /** * Coordinates of a tile in a chunk on a [SurfaceData] where each integer `x`/`y` represents a @@ -59,15 +42,7 @@ data class MapChunkPosition( data class MapTilePosition( val x: Int, val y: Int, -) { - constructor(x: Number, y: Number) : this(x.toInt(), y.toInt()) - - fun toMapChunkPosition() = MapChunkPosition( - x / MAP_CHUNK_SIZE, - y / MAP_CHUNK_SIZE, - ) - -} +) @Serializable @@ -93,39 +68,4 @@ data class Colour( val blue: Float = 0f, @EncodeDefault val alpha: Float = 1f, -) { - - /** True if any value is greater than 1, so the values are hexadecimal. */ - fun isHexadecimal(): Boolean { - return red > 1f - || green > 1f - || blue > 1f - || alpha > 1f - } - - /** True if all values are between `[0..1]`. */ - fun isPercentage(): Boolean = !isHexadecimal() - - fun asHexadecimal() = if (isPercentage()) { - Colour( - (red * 255).coerceIn(0f..255f), - (green * 255).coerceIn(0f..255f), - (blue * 255).coerceIn(0f..255f), - (alpha * 255).coerceIn(0f..255f), - ) - } else { - this - } - - fun asPercentage() = if (isPercentage()) { - this - } else { - Colour( - (red / 255).coerceIn(0f..1f), - (green / 255).coerceIn(0f..1f), - (blue / 255).coerceIn(0f..1f), - (alpha / 255).coerceIn(0f..1f), - ) - } - -} +) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt index ff179db..63d0c43 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -64,7 +64,7 @@ object FactorioObjectDataSerializer : JsonContentPolymorphicSerializer SurfaceData.serializer() FactorioObjectData.ObjectName.MapChunk -> MapChunk.serializer() FactorioObjectData.ObjectName.LuaTile -> MapTile.serializer() - FactorioObjectData.ObjectName.LuaTiles -> MapTiles.serializer() + FactorioObjectData.ObjectName.LuaTiles -> MapTiles.serializer() FactorioObjectData.ObjectName.ConsoleChatMessage -> ConsoleChatMessage.serializer() null -> throw Exception("Unknown FactorioObjectData $key: '$type' ") diff --git a/modules/events-server/.gitignore b/modules/events-server/.gitignore new file mode 100644 index 0000000..9ad4db8 --- /dev/null +++ b/modules/events-server/.gitignore @@ -0,0 +1 @@ +**/kafkatorio-web-map/** diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 241711d..2c6cb9f 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -37,7 +37,7 @@ dependencies { implementation("com.sksamuel.scrimage:scrimage-core:4.0.24") - val kotkaVersion = "0.0.5" + val kotkaVersion = "0.0.8" implementation("com.github.adamko-dev.kotka-streams:kotka-streams:$kotkaVersion") { isChanging = true } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt index c67696a..3d07c2e 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt @@ -29,8 +29,8 @@ object CreateTopics { KafkatorioPacket.PacketType.values().forEach { packetType -> - val kafkatorioTopics = buildList { - add(KafkatorioTopology.sourceTopic) + val kafkatorioTopics = buildSet { +// add(KafkatorioTopology.sourceTopic) when (packetType) { KafkatorioPacket.PacketType.EVENT -> FactorioObjectData.ObjectName.values().forEach { objectName -> @@ -72,7 +72,7 @@ object CreateTopics { replicationFactor: Short = 1, topicNames: () -> Collection, ): CreateTopicsResult = - createTopics(topicNames().map { + createTopics(topicNames().distinct().map { NewTopic(it, numPartitions, replicationFactor) }) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 6205e76..6083bd9 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -15,25 +15,29 @@ import dev.adamko.kafkatorio.events.schema.MapTile import dev.adamko.kafkatorio.events.schema.MapTilePosition import dev.adamko.kafkatorio.events.schema.MapTilePrototype import dev.adamko.kafkatorio.events.schema.MapTiles +import dev.adamko.kafkatorio.events.schema.converters.leftTopTile +import dev.adamko.kafkatorio.events.schema.converters.rightBottomTile +import dev.adamko.kafkatorio.events.schema.converters.toHexadecimal +import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.flatMap +import dev.adamko.kotka.extensions.streams.map import dev.adamko.kotka.extensions.streams.mapValues import dev.adamko.kotka.extensions.streams.merge import dev.adamko.kotka.extensions.streams.to import dev.adamko.kotka.kxs.serde import dev.adamko.kotka.topicdata.TopicRecord import dev.adamko.kotka.topicdata.flatMapTopicRecords -import dev.adamko.kotka.topicdata.mapTopicRecords import java.awt.Color import java.awt.image.BufferedImage import java.io.File import java.time.Duration +import kotlin.math.abs import kotlin.math.roundToInt -import kotlin.math.sign import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString @@ -76,7 +80,7 @@ class KafkatorioTopology( streams.setUncaughtExceptionHandler(StreamsExceptionHandler()) - Runtime.getRuntime().addShutdownHook(Thread { streams.close(Duration.ofSeconds(1)) }) + Runtime.getRuntime().addShutdownHook(Thread { streams.close(Duration.ofSeconds(10)) }) // streams.cleanUp() @@ -116,11 +120,11 @@ class KafkatorioTopology( ) { _: String, value: KafkatorioPacket, _: RecordContext -> // println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") when (value) { - is FactorioEvent -> + is FactorioEvent -> "kafkatorio.${value.packetType.name}.${value.data.objectName.name}" is FactorioConfigurationUpdate -> "kafkatorio.${value.packetType.name}.FactorioConfigurationUpdate" - is FactorioPrototypes -> + is FactorioPrototypes -> "kafkatorio.${value.packetType.name}.all" } } @@ -139,6 +143,10 @@ class KafkatorioTopology( } private fun tilePrototypesTable(): KTable { + +// val tilePrototypesStreamName = "kafkatorio.stream.prototypes-tiles" +// val tilePrototypesStoreName = "kafkatorio.store.prototypes-tiles" + return builder.stream( "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", Consumed.with(Serdes.String(), jsonMapper.serde()) @@ -158,6 +166,24 @@ class KafkatorioTopology( jsonMapper.serde() ) ) + +// .to( +// tilePrototypesStreamName, +// ) + +// return builder.globalTable( +// tilePrototypesStreamName, +// consumedAs( +// "send-tile-protos-to-gkt-store", +// jsonMapper.serde(), +// jsonMapper.serde() +// ), +// materializedAs( +// storeName = tilePrototypesStoreName, +// keySerde = jsonMapper.serde(), +// valueSerde = jsonMapper.serde(), +// ) +// ) } @Serializable @@ -168,14 +194,23 @@ class KafkatorioTopology( @Serializable data class MapChunkData( - val position: MapChunkPosition, - val surfaceIndex: Int, + val chunkPosition: MapChunkDataPosition, val tiles: Set, - ) : TopicRecord { - override val topicKey = MapChunkDataPosition(position, surfaceIndex) + ) +// : TopicRecord + { - constructor(key: MapChunkDataPosition, tiles: Set) : - this(key.position, key.surfaceIndex, tiles) + // @kotlinx.serialization.Transient +// override val topicKey by ::chunkPosition +// @kotlinx.serialization.Transient +// val surfaceIndex: Int by chunkPosition::surfaceIndex + +// @kotlinx.serialization.Transient +// val leftTopTile = chunkPosition.position.leftTopTile +// @kotlinx.serialization.Transient +// val rightBottom = chunkPosition.position.rightBottomTile +// @kotlinx.serialization.Transient +// val leftBottom = MapTilePosition(leftTopTile.x, rightBottom.x) } private fun mapChunksStream() { @@ -193,6 +228,7 @@ class KafkatorioTopology( println("MapChunk update $key, tiles count: ${value.tiles.size}") } + val chunkTilesUpdateStream: KStream = builder.stream( "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", Consumed.with(Serdes.String(), jsonMapper.serde()) @@ -238,12 +274,12 @@ class KafkatorioTopology( val chunksTable: KTable = allTileUpdatesStream - .mapTopicRecords("map-tile-updates-to-MapChunkData") { _: TileUpdateRecordKey, value: TileUpdateRecord -> + .map("map-tile-updates-to-MapChunkData") { _: TileUpdateRecordKey, value: TileUpdateRecord -> val key = MapChunkDataPosition( value.tilePosition.toMapChunkPosition(), value.surfaceIndex, ) - MapChunkData(key, setOf(value.tile)) + key to MapChunkData(key, setOf(value.tile)) } // group all tiles by chunk position .groupByKey( @@ -259,19 +295,18 @@ class KafkatorioTopology( runCatching { saveMapTilesPng(key, value) }.onFailure { e -> - println("error saving map tile png ${value.position}") + println("error saving map tile png chunk:${value.chunkPosition}") e.printStackTrace() throw e } } } + @Suppress("KotlinConstantConditions") private fun saveMapTilesPng(key: MapChunkDataPosition, chunk: MapChunkData) { - val (xChunk, yChunk) = chunk.position.toMapTilePosition() - val xOffset = when (xChunk.sign >= 0) { - true -> {} - false -> {} - } + + val chunkOriginX = chunk.chunkPosition.position.leftTopTile.x + val chunkOriginY = chunk.chunkPosition.position.rightBottomTile.y val chunkImage = ImmutableImage.filled( @@ -283,25 +318,28 @@ class KafkatorioTopology( chunk.tiles.forEach { tile -> + val prototypeColour = tilePrototypesStore + .get(tile.prototypeName) + ?.value() + ?.mapColour + ?.toHexadecimal() - val prototypeColour = tilePrototypesStore.get(tile.prototypeName) - .value() - .mapColour - .asHexadecimal() + val rgbColour = when (prototypeColour) { + null -> RGBColor(11, 11, 11, 0) + else -> RGBColor( + prototypeColour.red.roundToInt(), + prototypeColour.green.roundToInt(), + prototypeColour.blue.roundToInt(), + prototypeColour.alpha.roundToInt(), + ) + } - val rgbColour = RGBColor( - prototypeColour.red.roundToInt(), - prototypeColour.green.roundToInt(), - prototypeColour.blue.roundToInt(), - prototypeColour.alpha.roundToInt(), - ) - - val x = (tile.position.x - xChunk) * xChunk.sign - val y = (tile.position.y - yChunk) * yChunk.sign + val pixelX = abs(abs(tile.position.x) - abs(chunkOriginX)) + val pixelY = abs(abs(tile.position.y) - abs(chunkOriginY)) chunkImage.setColor( - tile.position.x, - tile.position.y, + pixelX, + pixelY, rgbColour ) @@ -309,10 +347,10 @@ class KafkatorioTopology( val zoom = 1u val file = - File("kafkatorio-web-map/${key.surfaceIndex}/$zoom/${key.position.x}/${key.position.y}.png") + File("kafkatorio-web-map/s${key.surfaceIndex}/z$zoom/x${key.position.x}/y${key.position.y}.png") - require(file.mkdirs()) { - "error creating map tile directory ${file.absolutePath}" + if (file.parentFile.mkdirs()) { + println("created new map tile parentFile directory ${file.absolutePath}") } println("saving map tile $file") diff --git a/modules/events-server/src/main/resources/external-annotations/org/apache/kafka/streams/state/annotations.xml b/modules/events-server/src/main/resources/external-annotations/org/apache/kafka/streams/state/annotations.xml new file mode 100644 index 0000000..2c28db5 --- /dev/null +++ b/modules/events-server/src/main/resources/external-annotations/org/apache/kafka/streams/state/annotations.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt index b09d924..6f9662d 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt @@ -6,31 +6,4 @@ import io.kvision.maps.externals.leaflet.geo.LatLng import io.kvision.maps.Maps import kotlin.math.roundToInt - -fun Colour.toHexString(includeAlpha: Boolean = false): String { - - val hexConverter: Float.() -> String = if (isDecimal()) { - Float::decimalToHex - } else { - Float::percentageToHex - } - - val length = if (includeAlpha) 9 else 7 - return buildString(length) { - append('#') - append(red.hexConverter()) - append(green.hexConverter()) - append(blue.hexConverter()) - if (includeAlpha) { - append(alpha.hexConverter()) - } - } -} - -fun Float.decimalToHex(): String = - roundToInt().toString(16).padStart(2, ' ') - -fun Float.percentageToHex(): String = - times(255).roundToInt().toString(16).padStart(2, ' ') - fun PlayerData.latLng(): LatLng = Maps.L.latLng((position.y * -1) to position.x) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt index dad8b9a..d42f6e9 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt @@ -2,6 +2,7 @@ package dev.adamko.kafkatorio.webmap import dev.adamko.kafkatorio.events.schema.FactorioEvent import dev.adamko.kafkatorio.events.schema.PlayerData +import dev.adamko.kafkatorio.events.schema.converters.toHexString import io.kvision.maps.externals.leaflet.layer.overlay.Tooltip import io.kvision.maps.externals.leaflet.layer.vector.CircleMarker import io.kvision.maps.Maps From 6fe3132f23aa457afa41f9bd5acb213375857392 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 19 Jan 2022 18:40:07 +0100 Subject: [PATCH 156/629] more tiles stuff working... --- modules/events-server/.gitignore | 1 - .../processor/KafkatorioTopology.kt | 34 ++++++++++++------- .../kafkatorio/processor/WebsocketServer.kt | 7 ++-- .../kafkatorio/processor/eventProcessor.kt | 10 +++++- .../processor/tileserver/WebMapTileServer.kt | 19 +++++++++++ .../src/main/resources/.gitignore | 1 + .../src/main/resources/logback.xml | 4 +-- .../dev/adamko/kafkatorio/webmap/map.kt | 11 +++++- 8 files changed, 66 insertions(+), 21 deletions(-) delete mode 100644 modules/events-server/.gitignore create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt create mode 100644 modules/events-server/src/main/resources/.gitignore diff --git a/modules/events-server/.gitignore b/modules/events-server/.gitignore deleted file mode 100644 index 9ad4db8..0000000 --- a/modules/events-server/.gitignore +++ /dev/null @@ -1 +0,0 @@ -**/kafkatorio-web-map/** diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 6083bd9..13a5290 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -49,6 +49,7 @@ import org.apache.kafka.streams.TopologyDescription import org.apache.kafka.streams.kstream.Consumed import org.apache.kafka.streams.kstream.KStream import org.apache.kafka.streams.kstream.KTable +import org.apache.kafka.streams.kstream.Suppressed import org.apache.kafka.streams.processor.RecordContext import org.apache.kafka.streams.state.QueryableStoreTypes import org.apache.kafka.streams.state.ReadOnlyKeyValueStore @@ -120,11 +121,11 @@ class KafkatorioTopology( ) { _: String, value: KafkatorioPacket, _: RecordContext -> // println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") when (value) { - is FactorioEvent -> + is FactorioEvent -> "kafkatorio.${value.packetType.name}.${value.data.objectName.name}" is FactorioConfigurationUpdate -> "kafkatorio.${value.packetType.name}.FactorioConfigurationUpdate" - is FactorioPrototypes -> + is FactorioPrototypes -> "kafkatorio.${value.packetType.name}.all" } } @@ -219,14 +220,14 @@ class KafkatorioTopology( "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", Consumed.with(Serdes.String(), jsonMapper.serde()) ) - .peek { k, v -> - println("trying to handle MapChunk update... $k: ${v.eventType}") - } +// .peek { k, v -> +// println("trying to handle MapChunk update... $k: ${v.eventType}") +// } .filter("events.filter.map-tiles") { _: String, event: FactorioEvent -> event.data is MapTiles } .mapValues("events.extract-map-tiles") { _, event: FactorioEvent -> (event.data as? MapTiles)!! } - .peek { key, value -> - println("MapChunk update $key, tiles count: ${value.tiles.size}") - } +// .peek { key, value -> +// println("MapChunk update $key, tiles count: ${value.tiles.size}") +// } val chunkTilesUpdateStream: KStream = builder.stream( @@ -262,7 +263,7 @@ class KafkatorioTopology( luaTilesUpdatesStream .merge("luaTilesUpdatesStream-and-chunkTilesUpdateStream", chunkTilesUpdateStream) .flatMapTopicRecords("all-tiles-convert-to-TileUpdateRecord") { _, mapTiles: MapTiles -> - println("all map tiles update ${mapTiles.tiles.size}") +// println("all map tiles update ${mapTiles.tiles.size}") mapTiles.tiles.map { tile -> TileUpdateRecord( mapTiles.surfaceIndex, @@ -288,6 +289,12 @@ class KafkatorioTopology( .reduce { tileA, tileB -> tileA.copy(tiles = tileA.tiles + tileB.tiles) } + .suppress( + Suppressed.untilTimeLimit( + Duration.ofSeconds(30), + Suppressed.BufferConfig.maxRecords(30) + ) + ) chunksTable .toStream() @@ -302,7 +309,7 @@ class KafkatorioTopology( } } - @Suppress("KotlinConstantConditions") +// @Suppress("KotlinConstantConditions") private fun saveMapTilesPng(key: MapChunkDataPosition, chunk: MapChunkData) { val chunkOriginX = chunk.chunkPosition.position.leftTopTile.x @@ -325,7 +332,10 @@ class KafkatorioTopology( ?.toHexadecimal() val rgbColour = when (prototypeColour) { - null -> RGBColor(11, 11, 11, 0) + null -> { + println("missing prototype: ${tile.prototypeName}") + RGBColor(11, 11, 11, 0) + } else -> RGBColor( prototypeColour.red.roundToInt(), prototypeColour.green.roundToInt(), @@ -347,7 +357,7 @@ class KafkatorioTopology( val zoom = 1u val file = - File("kafkatorio-web-map/s${key.surfaceIndex}/z$zoom/x${key.position.x}/y${key.position.y}.png") + File("src/main/resources/kafkatorio-web-map/s${key.surfaceIndex}/z$zoom/x${key.position.x}/y${key.position.y}.png") if (file.parentFile.mkdirs()) { println("created new map tile parentFile directory ${file.absolutePath}") diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt index 05efe69..d573ded 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt @@ -17,6 +17,7 @@ import org.http4k.routing.bind import org.http4k.routing.websockets import org.http4k.server.PolyHandler import org.http4k.websocket.Websocket +import org.http4k.websocket.WsHandler import org.http4k.websocket.WsMessage import org.http4k.websocket.WsStatus @@ -47,7 +48,7 @@ class WebsocketServer { messages.emit(msg) } - suspend fun build(): PolyHandler = supervisorScope builder@{ + suspend fun build(): WsHandler = supervisorScope builder@{ coroutineContext.job.invokeOnCompletion { e -> e?.let { serverJob.completeExceptionally(it) } ?: serverJob.complete() @@ -89,10 +90,8 @@ class WebsocketServer { } .launchIn(serverScope) - val http = { _: Request -> Response(OK) } - val ws = websockets("/ws" bind ::bindClient) - return@builder PolyHandler(http, ws) + return@builder websockets("/ws" bind ::bindClient) } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt index 499cb63..bc3ab88 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -2,7 +2,9 @@ package dev.adamko.kafkatorio.processor import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.processor.tileserver.WebMapTileServer import kotlinx.coroutines.runBlocking +import org.http4k.server.PolyHandler import org.http4k.server.Undertow import org.http4k.server.asServer @@ -11,10 +13,16 @@ val appProps = ApplicationProperties() fun main() = runBlocking { val wsServer = WebsocketServer() + val tileServer = WebMapTileServer() val topology = KafkatorioTopology(wsServer) topology.build() - wsServer.build().asServer(Undertow(9073)).start().block() + PolyHandler( + tileServer.build(), + wsServer.build(), + ).asServer(Undertow(9073)) + .start() + .block() } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt new file mode 100644 index 0000000..5c2ea5e --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt @@ -0,0 +1,19 @@ +package dev.adamko.kafkatorio.processor.tileserver + +import org.http4k.core.HttpHandler +import org.http4k.routing.ResourceLoader +import org.http4k.routing.RoutingHttpHandler +import org.http4k.routing.bind +import org.http4k.routing.routes +import org.http4k.routing.static + +class WebMapTileServer { + + private val routes: RoutingHttpHandler = routes( + "/tiles" bind static(ResourceLoader.Classpath("/kafkatorio-web-map")) + ) + + fun build(): HttpHandler { + return routes + } +} diff --git a/modules/events-server/src/main/resources/.gitignore b/modules/events-server/src/main/resources/.gitignore new file mode 100644 index 0000000..46d00ec --- /dev/null +++ b/modules/events-server/src/main/resources/.gitignore @@ -0,0 +1 @@ +kafkatorio-web-map/** diff --git a/modules/events-server/src/main/resources/logback.xml b/modules/events-server/src/main/resources/logback.xml index 4c3eb02..b53b7f5 100644 --- a/modules/events-server/src/main/resources/logback.xml +++ b/modules/events-server/src/main/resources/logback.xml @@ -5,13 +5,13 @@ - %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n + %cyan(%d{HH:mm:ss.SSS}) %white([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n - + diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index 3bf8615..1e310ee 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -1,8 +1,10 @@ package dev.adamko.kafkatorio.webmap +import io.kvision.maps.DefaultTileLayers import io.kvision.maps.externals.leaflet.geo.CRS import io.kvision.maps.externals.leaflet.geo.LatLng import io.kvision.maps.Maps +import io.kvision.maps.Maps.Companion.L import io.kvision.utils.px // @@ -24,9 +26,16 @@ fun createFactorioMap() = Maps { margin = 10.px configureLeafletMap { - setView(LatLng(0, 0), 13) + setView(LatLng(0, 0), 1) // DefaultTileLayers.OpenStreetMap.addTo(this) + L.tileLayer( + """http://localhost:9073/tiles/s1/z1/x{x}/y{y}.png""" + ) { + attribution = "kafkatorio" + tms = true + minZoom = 1 + }.addTo(this) with(options) { crs = CRS.Simple From a557c437cc5766d7ab2f32e3c4ea7af87dad79c9 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 19 Jan 2022 22:42:22 +0100 Subject: [PATCH 157/629] tiles are visible! the tileserver works! they're the right way up! they have colours! --- README.md | 5 ++ .../processor/KafkatorioTopology.kt | 87 ++++++++++++------- .../processor/tileserver/WebMapTileServer.kt | 11 ++- .../dev/adamko/kafkatorio/webmap/map.kt | 4 +- 4 files changed, 72 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 43670cc..f883e79 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,11 @@ While this project is under development, [no license](https://choosealicense.com/no-permission/) is provided. +## cmds + +`./bin/kafka-streams-application-reset.sh --application-id kafkatorio-events-processor --input-topics factorio-server-log` + + ## todo * add settings diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 13a5290..f491b6b 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -22,6 +22,7 @@ import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedAs +import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.flatMap @@ -29,6 +30,8 @@ import dev.adamko.kotka.extensions.streams.map import dev.adamko.kotka.extensions.streams.mapValues import dev.adamko.kotka.extensions.streams.merge import dev.adamko.kotka.extensions.streams.to +import dev.adamko.kotka.extensions.streams.toTable +import dev.adamko.kotka.extensions.tables.join import dev.adamko.kotka.kxs.serde import dev.adamko.kotka.topicdata.TopicRecord import dev.adamko.kotka.topicdata.flatMapTopicRecords @@ -73,17 +76,17 @@ class KafkatorioTopology( sendPlayerUpdatesToWebSocket() // createMapTileImages() val tilePrototypesTable: KTable = tilePrototypesTable() - mapChunksStream() + mapChunksStream(tilePrototypesTable) val topology = builder.build() val streams = KafkaStreams(topology, appProps.kafkaConfig) +// streams.cleanUp() streams.setUncaughtExceptionHandler(StreamsExceptionHandler()) Runtime.getRuntime().addShutdownHook(Thread { streams.close(Duration.ofSeconds(10)) }) -// streams.cleanUp() val description: TopologyDescription = topology.describe() println(description) @@ -121,11 +124,11 @@ class KafkatorioTopology( ) { _: String, value: KafkatorioPacket, _: RecordContext -> // println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") when (value) { - is FactorioEvent -> + is FactorioEvent -> "kafkatorio.${value.packetType.name}.${value.data.objectName.name}" is FactorioConfigurationUpdate -> "kafkatorio.${value.packetType.name}.FactorioConfigurationUpdate" - is FactorioPrototypes -> + is FactorioPrototypes -> "kafkatorio.${value.packetType.name}.all" } } @@ -167,7 +170,6 @@ class KafkatorioTopology( jsonMapper.serde() ) ) - // .to( // tilePrototypesStreamName, // ) @@ -187,6 +189,12 @@ class KafkatorioTopology( // ) } + @Serializable + data class MapTileWithPrototype( + val position: MapTilePosition, + val prototype: MapTilePrototype, + ) + @Serializable data class MapChunkDataPosition( val position: MapChunkPosition, @@ -197,24 +205,10 @@ class KafkatorioTopology( data class MapChunkData( val chunkPosition: MapChunkDataPosition, val tiles: Set, + val tilePrototypes: Set, ) -// : TopicRecord - { - // @kotlinx.serialization.Transient -// override val topicKey by ::chunkPosition -// @kotlinx.serialization.Transient -// val surfaceIndex: Int by chunkPosition::surfaceIndex - -// @kotlinx.serialization.Transient -// val leftTopTile = chunkPosition.position.leftTopTile -// @kotlinx.serialization.Transient -// val rightBottom = chunkPosition.position.rightBottomTile -// @kotlinx.serialization.Transient -// val leftBottom = MapTilePosition(leftTopTile.x, rightBottom.x) - } - - private fun mapChunksStream() { + private fun mapChunksStream(tilePrototypesTable: KTable) { val luaTilesUpdatesStream: KStream = builder.stream( "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", @@ -253,10 +247,10 @@ class KafkatorioTopology( data class TileUpdateRecord( val surfaceIndex: Int, val tilePosition: MapTilePosition, - val tile: MapTile + val tile: MapTile, + val tilePrototype: MapTilePrototype?, ) : TopicRecord { - override val topicKey: TileUpdateRecordKey = - TileUpdateRecordKey(surfaceIndex, tilePosition) + override val topicKey: TileUpdateRecordKey = TileUpdateRecordKey(surfaceIndex, tilePosition) } val allTileUpdatesStream: KStream = @@ -268,10 +262,27 @@ class KafkatorioTopology( TileUpdateRecord( mapTiles.surfaceIndex, tile.position, - tile + tile, + null ) } } + .toTable( + "all-tile-updates-table", + materializedWith(jsonMapper.serde(), jsonMapper.serde()) + ) + .join( + tilePrototypesTable, + "enrich-tiles-with-prototypes", + materializedWith(jsonMapper.serde(), jsonMapper.serde()), + { it.tile.prototypeName }, + ) { v1: TileUpdateRecord, v2: MapTilePrototype -> + v1.copy(tilePrototype = v2) + } + .toStream() + .filter { _, value -> + value.tilePrototype != null + } val chunksTable: KTable = allTileUpdatesStream @@ -280,19 +291,26 @@ class KafkatorioTopology( value.tilePosition.toMapChunkPosition(), value.surfaceIndex, ) - key to MapChunkData(key, setOf(value.tile)) + key to MapChunkData( + key, + setOf(value.tile), + setOfNotNull(value.tilePrototype) + ) } // group all tiles by chunk position .groupByKey( groupedAs("group-tile-updates-per-chunk-position", jsonMapper.serde(), jsonMapper.serde()) ) .reduce { tileA, tileB -> - tileA.copy(tiles = tileA.tiles + tileB.tiles) + tileA.copy( + tiles = tileA.tiles + tileB.tiles, + tilePrototypes = tileA.tilePrototypes + tileB.tilePrototypes + ) } .suppress( Suppressed.untilTimeLimit( Duration.ofSeconds(30), - Suppressed.BufferConfig.maxRecords(30) + Suppressed.BufferConfig.maxRecords(32*32*2) ) ) @@ -309,11 +327,15 @@ class KafkatorioTopology( } } -// @Suppress("KotlinConstantConditions") + private fun saveMapTilesPng(key: MapChunkDataPosition, chunk: MapChunkData) { + val tilePrototypes: Map = + chunk.tilePrototypes.associateBy { it.name }.withDefault { null } + val chunkOriginX = chunk.chunkPosition.position.leftTopTile.x - val chunkOriginY = chunk.chunkPosition.position.rightBottomTile.y +// val chunkOriginY = chunk.chunkPosition.position.rightBottomTile.y + val chunkOriginY = chunk.chunkPosition.position.leftTopTile.y val chunkImage = ImmutableImage.filled( @@ -325,9 +347,8 @@ class KafkatorioTopology( chunk.tiles.forEach { tile -> - val prototypeColour = tilePrototypesStore - .get(tile.prototypeName) - ?.value() + val prototypeColour = tilePrototypes + .getValue(tile.prototypeName) ?.mapColour ?.toHexadecimal() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt index 5c2ea5e..db5e420 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt @@ -1,6 +1,8 @@ package dev.adamko.kafkatorio.processor.tileserver import org.http4k.core.HttpHandler +import org.http4k.core.then +import org.http4k.filter.CachingFilters import org.http4k.routing.ResourceLoader import org.http4k.routing.RoutingHttpHandler import org.http4k.routing.bind @@ -10,7 +12,14 @@ import org.http4k.routing.static class WebMapTileServer { private val routes: RoutingHttpHandler = routes( - "/tiles" bind static(ResourceLoader.Classpath("/kafkatorio-web-map")) + "/tiles" bind CachingFilters.Response.NoCache() + .then( + static( + ResourceLoader.Directory( + """D:\Users\Adam\Projects\games\kafkatorio\modules\events-server\src\main\resources\kafkatorio-web-map\""" + ) + ) + ) ) fun build(): HttpHandler { diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index 1e310ee..4016479 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -30,11 +30,13 @@ fun createFactorioMap() = Maps { // DefaultTileLayers.OpenStreetMap.addTo(this) L.tileLayer( - """http://localhost:9073/tiles/s1/z1/x{x}/y{y}.png""" + """http://localhost:9073/tiles/s1/z{z}/x{x}/y{y}.png""" ) { attribution = "kafkatorio" tms = true minZoom = 1 +// maxZoom = 1 + maxNativeZoom = 1 }.addTo(this) with(options) { From 2c518e396bbf4ff922d411382e2d9df2e6f0e23d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 20 Jan 2022 13:58:46 +0100 Subject: [PATCH 158/629] massive tile processing speed improvement --- .../processor/KafkatorioTopology.kt | 460 +++++++++--------- .../kafkatorio/processor/eventProcessor.kt | 14 +- .../dev/adamko/kafkatorio/webmap/map.kt | 9 +- 3 files changed, 237 insertions(+), 246 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index f491b6b..969f136 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -16,7 +16,6 @@ import dev.adamko.kafkatorio.events.schema.MapTilePosition import dev.adamko.kafkatorio.events.schema.MapTilePrototype import dev.adamko.kafkatorio.events.schema.MapTiles import dev.adamko.kafkatorio.events.schema.converters.leftTopTile -import dev.adamko.kafkatorio.events.schema.converters.rightBottomTile import dev.adamko.kafkatorio.events.schema.converters.toHexadecimal import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition import dev.adamko.kotka.extensions.consumedAs @@ -24,14 +23,16 @@ import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.producedAs +import dev.adamko.kotka.extensions.streams.aggregate import dev.adamko.kotka.extensions.streams.filter -import dev.adamko.kotka.extensions.streams.flatMap +import dev.adamko.kotka.extensions.streams.groupBy import dev.adamko.kotka.extensions.streams.map import dev.adamko.kotka.extensions.streams.mapValues import dev.adamko.kotka.extensions.streams.merge +import dev.adamko.kotka.extensions.streams.reduce import dev.adamko.kotka.extensions.streams.to -import dev.adamko.kotka.extensions.streams.toTable import dev.adamko.kotka.extensions.tables.join +import dev.adamko.kotka.extensions.tables.mapValues import dev.adamko.kotka.kxs.serde import dev.adamko.kotka.topicdata.TopicRecord import dev.adamko.kotka.topicdata.flatMapTopicRecords @@ -42,6 +43,7 @@ import java.time.Duration import kotlin.math.abs import kotlin.math.roundToInt import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import org.apache.kafka.common.serialization.Serdes @@ -68,37 +70,41 @@ class KafkatorioTopology( const val sourceTopic = "factorio-server-log" } - private lateinit var tilePrototypesStore: ReadOnlyKeyValueStore> +// private lateinit var tilePrototypesStore: ReadOnlyKeyValueStore> fun build() { parseAndSplitServerLog() sendPlayerUpdatesToWebSocket() // createMapTileImages() - val tilePrototypesTable: KTable = tilePrototypesTable() - mapChunksStream(tilePrototypesTable) + val tilePrototypesTable: KTable = tilePrototypesTable() + + val tilesTable: KTable = buildTilesTable() + + val tilesGroupedByChunk: KTable = + buildChunkedTilesTable(tilesTable) + + createChunkTileImage(tilePrototypesTable, tilesGroupedByChunk) val topology = builder.build() val streams = KafkaStreams(topology, appProps.kafkaConfig) + // streams.cleanUp() - streams.setUncaughtExceptionHandler(StreamsExceptionHandler()) - - Runtime.getRuntime().addShutdownHook(Thread { streams.close(Duration.ofSeconds(10)) }) - + Runtime.getRuntime().addShutdownHook(Thread { streams.close(Duration.ofSeconds(1)) }) val description: TopologyDescription = topology.describe() println(description) streams.start() - tilePrototypesStore = streams.store( - StoreQueryParameters.fromNameAndType( - tilePrototypesTable.queryableStoreName(), - QueryableStoreTypes.timestampedKeyValueStore() - ) - ) +// tilePrototypesStore = streams.store( +// StoreQueryParameters.fromNameAndType( +// tilePrototypesTable.queryableStoreName(), +// QueryableStoreTypes.timestampedKeyValueStore() +// ) +// ) } private fun parseAndSplitServerLog() { @@ -124,11 +130,11 @@ class KafkatorioTopology( ) { _: String, value: KafkatorioPacket, _: RecordContext -> // println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") when (value) { - is FactorioEvent -> + is FactorioEvent -> "kafkatorio.${value.packetType.name}.${value.data.objectName.name}" is FactorioConfigurationUpdate -> "kafkatorio.${value.packetType.name}.FactorioConfigurationUpdate" - is FactorioPrototypes -> + is FactorioPrototypes -> "kafkatorio.${value.packetType.name}.all" } } @@ -146,30 +152,67 @@ class KafkatorioTopology( } } - private fun tilePrototypesTable(): KTable { + @Serializable + data class SurfaceIndex( + val surfaceIndex: Int + ) { + override fun toString() = "$surfaceIndex" + } + + @Serializable + data class SurfacePrototypesData( + val surfaceIndex: SurfaceIndex, + val mapTilePrototypes: Set, + ) + + private fun tilePrototypesTable(): KTable { // val tilePrototypesStreamName = "kafkatorio.stream.prototypes-tiles" // val tilePrototypesStoreName = "kafkatorio.store.prototypes-tiles" return builder.stream( "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", - Consumed.with(Serdes.String(), jsonMapper.serde()) + consumedAs( + "consume-all-prototypes-packets", + Serdes.String(), + jsonMapper.serde() + ) ) - .flatMap("flatten-map-tile-prototypes") { _, prototypes: FactorioPrototypes -> - prototypes.prototypes + .map("flatten-map-tile-prototypes") { _, prototypes: FactorioPrototypes -> + val tilePrototypes = prototypes.prototypes .filterIsInstance() - .map { proto -> proto.name to proto } + .toSet() + val key = SurfaceIndex(1) // TODO make surfaceIndex come from Factorio, not hard coded + val data = SurfacePrototypesData(key, tilePrototypes) + key to data } .peek { _, value -> - println("tile prototype: ${value.name}") + println("tile prototypes: ${value.mapTilePrototypes.joinToString { it.name }}") } - .toTable( - materializedAs( - "kafkatorio.prototypes.map-tiles", + .groupByKey( + groupedAs( + "grouping-tile-prototypes-by-surface-index", jsonMapper.serde(), jsonMapper.serde() ) ) + .reduce( + "group-surface-prototypes", + materializedWith( +// "kafkatorio.surface-prototypes", + jsonMapper.serde(), + jsonMapper.serde() + ) + ) { value1: SurfacePrototypesData, value2: SurfacePrototypesData -> + value1.copy(mapTilePrototypes = value1.mapTilePrototypes + value2.mapTilePrototypes) + } +// .toTable( +// materializedAs( +// "kafkatorio.prototypes.map-tiles", +// jsonMapper.serde(), +// jsonMapper.serde() +// ) +// ) // .to( // tilePrototypesStreamName, // ) @@ -190,137 +233,166 @@ class KafkatorioTopology( } @Serializable - data class MapTileWithPrototype( - val position: MapTilePosition, - val prototype: MapTilePrototype, + data class TileUpdateRecordKey( + val surfaceIndex: SurfaceIndex, + val tilePosition: MapTilePosition, ) + @Serializable + data class TileUpdateRecord( + val surfaceIndex: SurfaceIndex, + val tilePosition: MapTilePosition, + val tile: MapTile, + ) : TopicRecord { + @Transient + override val topicKey: TileUpdateRecordKey = TileUpdateRecordKey(surfaceIndex, tilePosition) + } + + private fun buildTilesTable(): KTable { + + val luaTilesUpdatesStream: KStream = builder.stream( + "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", + consumedAs("consume-map-tiles-packets", Serdes.String(), jsonMapper.serde()) + ) + .filter("events.filter.map-tiles") { _: String, event: FactorioEvent -> event.data is MapTiles } + .mapValues("events.extract-map-tiles") { _, event: FactorioEvent -> (event.data as? MapTiles)!! } + + val chunkTilesUpdateStream: KStream = builder.stream( + "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", + consumedAs("consume-map-chunk-packets", Serdes.String(), jsonMapper.serde()) + ) + .filter("events.filter.map-chunks") { _: String, event: FactorioEvent -> event.data is MapChunk } + .mapValues("events.extract-map-chunks") { _, event: FactorioEvent -> (event.data as? MapChunk)!!.tiles } + + return luaTilesUpdatesStream + .merge("luaTilesUpdatesStream-and-chunkTilesUpdateStream", chunkTilesUpdateStream) + .flatMapTopicRecords("all-tiles-convert-to-TileUpdateRecord") { _, mapTiles: MapTiles -> +// println("all map tiles update ${mapTiles.tiles.size}") + mapTiles.tiles.map { tile -> + TileUpdateRecord( + SurfaceIndex(mapTiles.surfaceIndex), + tile.position, + tile, + ) + } + } + .toTable(materializedWith(jsonMapper.serde(), jsonMapper.serde())) +// .suppress( +// Suppressed.untilTimeLimit( +// Duration.ofSeconds(30), +// Suppressed.BufferConfig +// .maxRecords(100) +// .emitEarlyWhenFull() +// ) +// ) + } + @Serializable data class MapChunkDataPosition( val position: MapChunkPosition, - val surfaceIndex: Int, + val surfaceIndex: SurfaceIndex, ) @Serializable data class MapChunkData( val chunkPosition: MapChunkDataPosition, val tiles: Set, - val tilePrototypes: Set, ) - private fun mapChunksStream(tilePrototypesTable: KTable) { - - val luaTilesUpdatesStream: KStream = builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", - Consumed.with(Serdes.String(), jsonMapper.serde()) - ) -// .peek { k, v -> -// println("trying to handle MapChunk update... $k: ${v.eventType}") -// } - .filter("events.filter.map-tiles") { _: String, event: FactorioEvent -> event.data is MapTiles } - .mapValues("events.extract-map-tiles") { _, event: FactorioEvent -> (event.data as? MapTiles)!! } -// .peek { key, value -> -// println("MapChunk update $key, tiles count: ${value.tiles.size}") -// } - - - val chunkTilesUpdateStream: KStream = builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", - Consumed.with(Serdes.String(), jsonMapper.serde()) - ) - .peek { k, v -> - println("trying to handle LuaTiles update... $k: ${v.eventType} / ${v.data is MapChunk}") - } - .filter("events.filter.map-chunks") { _: String, event: FactorioEvent -> event.data is MapChunk } - .mapValues("events.extract-map-chunks") { _, event: FactorioEvent -> (event.data as? MapChunk)!!.tiles } - .peek { key, value -> - println("LuaTiles update $key, tiles count: ${value.tiles.size}") - } + private fun buildChunkedTilesTable( + tilesTable: KTable + ): KTable { @Serializable - data class TileUpdateRecordKey( - val surfaceIndex: Int, - val tilePosition: MapTilePosition, + data class MapChunkDataAggregator( + val tiles: MutableSet = mutableSetOf(), ) - @Serializable - data class TileUpdateRecord( - val surfaceIndex: Int, - val tilePosition: MapTilePosition, - val tile: MapTile, - val tilePrototype: MapTilePrototype?, - ) : TopicRecord { - override val topicKey: TileUpdateRecordKey = TileUpdateRecordKey(surfaceIndex, tilePosition) - } - - val allTileUpdatesStream: KStream = - luaTilesUpdatesStream - .merge("luaTilesUpdatesStream-and-chunkTilesUpdateStream", chunkTilesUpdateStream) - .flatMapTopicRecords("all-tiles-convert-to-TileUpdateRecord") { _, mapTiles: MapTiles -> -// println("all map tiles update ${mapTiles.tiles.size}") - mapTiles.tiles.map { tile -> - TileUpdateRecord( - mapTiles.surfaceIndex, - tile.position, - tile, - null - ) - } - } - .toTable( - "all-tile-updates-table", - materializedWith(jsonMapper.serde(), jsonMapper.serde()) - ) - .join( - tilePrototypesTable, - "enrich-tiles-with-prototypes", - materializedWith(jsonMapper.serde(), jsonMapper.serde()), - { it.tile.prototypeName }, - ) { v1: TileUpdateRecord, v2: MapTilePrototype -> - v1.copy(tilePrototype = v2) - } - .toStream() - .filter { _, value -> - value.tilePrototype != null - } - - val chunksTable: KTable = - allTileUpdatesStream - .map("map-tile-updates-to-MapChunkData") { _: TileUpdateRecordKey, value: TileUpdateRecord -> - val key = MapChunkDataPosition( - value.tilePosition.toMapChunkPosition(), - value.surfaceIndex, - ) - key to MapChunkData( - key, - setOf(value.tile), - setOfNotNull(value.tilePrototype) - ) - } - // group all tiles by chunk position - .groupByKey( - groupedAs("group-tile-updates-per-chunk-position", jsonMapper.serde(), jsonMapper.serde()) - ) - .reduce { tileA, tileB -> - tileA.copy( - tiles = tileA.tiles + tileB.tiles, - tilePrototypes = tileA.tilePrototypes + tileB.tilePrototypes - ) - } - .suppress( - Suppressed.untilTimeLimit( - Duration.ofSeconds(30), - Suppressed.BufferConfig.maxRecords(32*32*2) - ) - ) - - chunksTable + return tilesTable .toStream() - .foreach { key: MapChunkDataPosition, value: MapChunkData -> +// .repartition( +// repartitionedAs( +// "repartition-all-tiles-before-chunk-grouping", +// jsonMapper.serde(), +// jsonMapper.serde() +// ) +// ) + .groupBy( + groupedAs("grouping-tiles-by-chunk-pos", jsonMapper.serde(), jsonMapper.serde()), + ) { key: TileUpdateRecordKey, value: TileUpdateRecord -> + MapChunkDataPosition( + value.tilePosition.toMapChunkPosition(), + key.surfaceIndex + ) + } + .aggregate( + "reducing-tiles-grouped-by-chunk-position", + materializedWith(jsonMapper.serde(), jsonMapper.serde()), + { MapChunkDataAggregator() }, + ) { _: MapChunkDataPosition, value: TileUpdateRecord, aggregate: MapChunkDataAggregator -> + aggregate.tiles.add(value.tile) + aggregate + } + // TODO maybe set serdes here? + .mapValues( + "tiles-grouped-by-chunk-position-finalise-aggregation", + materializedWith(jsonMapper.serde(), jsonMapper.serde()), + ) { k, v -> + MapChunkData(k, v.tiles) + } + + } + + private fun createChunkTileImage( + tilePrototypesTable: KTable, + tilesGroupedByChunk: KTable, + ) { + + @Serializable + data class ChunkTilesAndProtos( + val chunkTiles: MapChunkData, + val protos: SurfacePrototypesData + ) + +// tilesGroupedByChunk +// .join( +// tilePrototypesTable, +// { cd: MapChunkData -> cd.chunkPosition.surfaceIndex }, +// { chunkTiles: MapChunkData, protos: SurfacePrototypesData -> +// ChunkTilesAndProtos(chunkTiles, protos) +// }, +// namedAs("joining-chunks-tiles-prototypes"), +// materializedAs( +// "joined-chunked-tiles-with-prototypes", +// jsonMapper.serde(), +// jsonMapper.serde() +// ), +// ) + tilesGroupedByChunk + .join( + tilePrototypesTable, + "enrich-tiles-with-prototype-colour", + materializedAs( + "joined-chunked-tiles-with-prototypes", + jsonMapper.serde(), + jsonMapper.serde() + ), + { it.chunkPosition.surfaceIndex }, + ) { chunkTiles: MapChunkData, protos: SurfacePrototypesData -> + ChunkTilesAndProtos(chunkTiles, protos) + } + .suppress( + Suppressed.untilTimeLimit( + Duration.ofSeconds(30), + Suppressed.BufferConfig.maxRecords(30) + ) + ) + .toStream() + .foreach { _, (chunkTiles: MapChunkData, protos: SurfacePrototypesData) -> runCatching { - saveMapTilesPng(key, value) + saveMapTilesPng(chunkTiles, protos) }.onFailure { e -> - println("error saving map tile png chunk:${value.chunkPosition}") + println("error saving map tile png chunk:${chunkTiles.chunkPosition}") e.printStackTrace() throw e } @@ -328,14 +400,16 @@ class KafkatorioTopology( } - private fun saveMapTilesPng(key: MapChunkDataPosition, chunk: MapChunkData) { + private fun saveMapTilesPng(chunkTiles: MapChunkData, protos: SurfacePrototypesData) { + + val chunkPos = chunkTiles.chunkPosition val tilePrototypes: Map = - chunk.tilePrototypes.associateBy { it.name }.withDefault { null } + protos.mapTilePrototypes.associateBy { it.name }.withDefault { null } - val chunkOriginX = chunk.chunkPosition.position.leftTopTile.x + val chunkOriginX = chunkTiles.chunkPosition.position.leftTopTile.x // val chunkOriginY = chunk.chunkPosition.position.rightBottomTile.y - val chunkOriginY = chunk.chunkPosition.position.leftTopTile.y + val chunkOriginY = chunkTiles.chunkPosition.position.leftTopTile.y val chunkImage = ImmutableImage.filled( @@ -345,7 +419,7 @@ class KafkatorioTopology( BufferedImage.TYPE_INT_ARGB ) - chunk.tiles.forEach { tile -> + chunkTiles.tiles.forEach { tile -> val prototypeColour = tilePrototypes .getValue(tile.prototypeName) @@ -378,7 +452,9 @@ class KafkatorioTopology( val zoom = 1u val file = - File("src/main/resources/kafkatorio-web-map/s${key.surfaceIndex}/z$zoom/x${key.position.x}/y${key.position.y}.png") + File( + "src/main/resources/kafkatorio-web-map/s${chunkPos.surfaceIndex}/z$zoom/x${chunkOriginX}/y${chunkOriginY}.png" + ) if (file.parentFile.mkdirs()) { println("created new map tile parentFile directory ${file.absolutePath}") @@ -389,100 +465,4 @@ class KafkatorioTopology( chunkImage.output(PngWriter.MaxCompression, file) } -// -// private fun createMapTileImages() { -// -// val mapTilesByPrototypeName: KStream = -// builder.stream( -// "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", -// Consumed.with(Serdes.String(), KafkatorioPacketSerde) -// ) -// .filter { _, packet -> packet is FactorioEvent && packet.data is MapTiles } -// .mapValues { packet -> ((packet as? FactorioEvent)?.data as? MapTiles)!! } -// .flatMap { _, mapTiles -> -// mapTiles -// .tiles -// .map { tile -> tile.prototypeName to tile } -// .map { it.toKeyValue() } -// } -//// .groupByKey() -// -// @Serializable -// data class TileSurfaceCoord( -// val surfaceIndex: Int, -// val position: MapTilePosition, -// ) -// -// @Serializable -// data class TileSurfaceState( -// val surfaceIndex: Int, -// val position: MapTilePosition, -// val prototypeName: String, -// ) -// -// val mapTilesTable: KTable = -// builder.stream( -// "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", -// Consumed.with(Serdes.String(), KafkatorioPacketSerde) -// ) -// .filter { _, packet -> packet is FactorioEvent && packet.data is MapTiles } -// .mapValues { packet -> ((packet as? FactorioEvent)?.data as? MapTiles)!! } -// .flatMap({ _, mapTiles: MapTiles -> -// mapTiles.tiles.map { tile: MapTile -> -// val key = TileSurfaceCoord(mapTiles.surfaceIndex, tile.position) -// val value = TileSurfaceState(mapTiles.surfaceIndex, tile.position, tile.prototypeName) -// (key to value).toKeyValue() -// } -// } -// ) -// .toTable( -// materializedAs( -// "kafkatorio.table.map-tile-status", -// jsonMapper.serde(), -// jsonMapper.serde(), -// ) -// ) -// -// -// val tilePrototypesTable: KTable = -// builder.stream( -// "kafkatorio.${KafkatorioPacket.PacketType.CONFIG}.FactorioConfigurationUpdate", -// Consumed.with(Serdes.String(), KafkatorioPacketSerde) -// ) -// .flatMap(KeyValueMapper>> { _, packet -> -// when (packet) { -// is FactorioConfigurationUpdate -> -// packet.prototypes -// .filterIsInstance() -// .map { proto -> proto.name to proto } -// .map { it.toKeyValue() } -// is FactorioEvent -> -// emptyList() -// } -// }) -// .toTable( -// materializedAs("kafkatorio.table.tile-prototypes", Serdes.String(), jsonMapper.serde()) -// ) -// -// -// @Serializable -// data class TileSurfaceData( -// val surfaceIndex: Int, -// val position: MapTilePosition, -// val prototype: MapTilePrototype, -// ) -// -// val enrichedTiles: KTable = -// mapTilesTable.join( -// tilePrototypesTable, -// { tile: TileSurfaceState -> -// tile.prototypeName -// }, -// { tile: TileSurfaceState, proto: MapTilePrototype -> -// TileSurfaceData(tile.surfaceIndex, tile.position, proto) -// }, -// ) -// -// } - } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt index bc3ab88..faaf92b 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -3,6 +3,7 @@ package dev.adamko.kafkatorio.processor import dev.adamko.kafkatorio.processor.config.ApplicationProperties import dev.adamko.kafkatorio.processor.tileserver.WebMapTileServer +import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.http4k.server.PolyHandler import org.http4k.server.Undertow @@ -10,7 +11,7 @@ import org.http4k.server.asServer val appProps = ApplicationProperties() -fun main() = runBlocking { +fun main() = runBlocking { val wsServer = WebsocketServer() val tileServer = WebMapTileServer() @@ -18,11 +19,16 @@ fun main() = runBlocking { val topology = KafkatorioTopology(wsServer) topology.build() - PolyHandler( + val webServer = PolyHandler( tileServer.build(), wsServer.build(), ).asServer(Undertow(9073)) - .start() - .block() + +// Runtime.getRuntime().addShutdownHook(Thread { +// webServer.stop() +// }) +// launch { + webServer.start().block() +// } } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index 4016479..f29c4a2 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -34,11 +34,16 @@ fun createFactorioMap() = Maps { ) { attribution = "kafkatorio" tms = true - minZoom = 1 -// maxZoom = 1 + minZoom = -2 + maxZoom = 1 maxNativeZoom = 1 + minNativeZoom = 1 }.addTo(this) + L.scale { + + } + with(options) { crs = CRS.Simple } From 560a5d4172a894b7918e3725bdb98c94a9d19551 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 21 Jan 2022 07:55:36 +0100 Subject: [PATCH 159/629] the performance increase wasn't that good actually - so split up the topology into separate files so it's easier to read, and simplifying the png tile process so it joins tiles and prototypes sooner, with less info --- .../events/schema/converters/positions.kt | 32 +- .../processor/KafkatorioTopology.kt | 441 +----------------- .../kafkatorio/processor/WebsocketServer.kt | 4 - .../kafkatorio/processor/eventProcessor.kt | 9 +- .../processor/topology/FactorioGameState.kt | 68 --- .../processor/topology/FactorioServerState.kt | 74 +++ .../processor/topology/factorioMapTiles.kt | 86 ++++ .../topology/factorioServerPackets.kt | 54 +++ .../kafkatorio/processor/topology/model.kt | 10 + .../processor/topology/playerUpdates.kt | 26 ++ .../processor/topology/prototypes.kt | 100 ++++ .../processor/topology/webMapTileAggregate.kt | 125 +++++ .../processor/topology/webMapTiles.kt | 92 ++++ 13 files changed, 603 insertions(+), 518 deletions(-) delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioGameState.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioServerState.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/positions.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/positions.kt index 1cb0ca1..0f80a73 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/positions.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/positions.kt @@ -17,20 +17,20 @@ operator fun MapTilePosition.plus(addend: Int) = MapTilePosition(x + addend, y + addend) -fun MapTilePosition.toMapChunkPosition() = +fun MapTilePosition.toMapChunkPosition( chunkSize: Int = MAP_CHUNK_SIZE) = MapChunkPosition( - floor(x.toDouble() / MAP_CHUNK_SIZE.toDouble()).toInt(), - floor(y.toDouble() / MAP_CHUNK_SIZE.toDouble()).toInt(), + floor(x.toDouble() / chunkSize.toDouble()).toInt(), + floor(y.toDouble() / chunkSize.toDouble()).toInt(), ) fun MapEntityPosition.toMapTilePosition() = MapChunkPosition(floor(x).toInt(), floor(y).toInt()) -fun MapEntityPosition.toMapChunkPosition() = +fun MapEntityPosition.toMapChunkPosition( chunkSize: Int = MAP_CHUNK_SIZE) = MapChunkPosition( - floor(x / MAP_CHUNK_SIZE.toDouble()).toInt(), - floor(y / MAP_CHUNK_SIZE.toDouble()).toInt(), + floor(x / chunkSize.toDouble()).toInt(), + floor(y / chunkSize.toDouble()).toInt(), ) @@ -44,15 +44,15 @@ operator fun MapChunkPosition.minus(subtrahend: Int) = MapChunkPosition(x - subtrahend, y - subtrahend) -val MapChunkPosition.leftTopTile: MapTilePosition - get() = MapTilePosition( - x * MAP_CHUNK_SIZE, - y * MAP_CHUNK_SIZE, +fun MapChunkPosition.leftTopTile( chunkSize: Int = MAP_CHUNK_SIZE): MapTilePosition = + MapTilePosition( + x * chunkSize, + y * chunkSize, ) -val MapChunkPosition.rightBottomTile: MapTilePosition - get() = leftTopTile + (MAP_CHUNK_SIZE - 1) - - -val MapChunkPosition.boundingBox: MapBoundingBox - get() = MapBoundingBox(leftTopTile, rightBottomTile) +//val MapChunkPosition.rightBottomTile: MapTilePosition +// get() = leftTopTile + (MAP_CHUNK_SIZE - 1) +// +// +//val MapChunkPosition.boundingBox: MapBoundingBox +// get() = MapBoundingBox(leftTopTile, rightBottomTile) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 969f136..96cea83 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -1,64 +1,22 @@ package dev.adamko.kafkatorio.processor -import com.sksamuel.scrimage.ImmutableImage -import com.sksamuel.scrimage.color.RGBColor -import com.sksamuel.scrimage.nio.PngWriter -import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate -import dev.adamko.kafkatorio.events.schema.FactorioEvent -import dev.adamko.kafkatorio.events.schema.FactorioObjectData -import dev.adamko.kafkatorio.events.schema.FactorioPrototypes -import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -import dev.adamko.kafkatorio.events.schema.MAP_CHUNK_SIZE -import dev.adamko.kafkatorio.events.schema.MapChunk -import dev.adamko.kafkatorio.events.schema.MapChunkPosition import dev.adamko.kafkatorio.events.schema.MapTile import dev.adamko.kafkatorio.events.schema.MapTilePosition import dev.adamko.kafkatorio.events.schema.MapTilePrototype -import dev.adamko.kafkatorio.events.schema.MapTiles -import dev.adamko.kafkatorio.events.schema.converters.leftTopTile -import dev.adamko.kafkatorio.events.schema.converters.toHexadecimal -import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition -import dev.adamko.kotka.extensions.consumedAs -import dev.adamko.kotka.extensions.groupedAs -import dev.adamko.kotka.extensions.materializedAs -import dev.adamko.kotka.extensions.materializedWith -import dev.adamko.kotka.extensions.producedAs -import dev.adamko.kotka.extensions.streams.aggregate -import dev.adamko.kotka.extensions.streams.filter -import dev.adamko.kotka.extensions.streams.groupBy -import dev.adamko.kotka.extensions.streams.map -import dev.adamko.kotka.extensions.streams.mapValues -import dev.adamko.kotka.extensions.streams.merge -import dev.adamko.kotka.extensions.streams.reduce -import dev.adamko.kotka.extensions.streams.to -import dev.adamko.kotka.extensions.tables.join -import dev.adamko.kotka.extensions.tables.mapValues -import dev.adamko.kotka.kxs.serde -import dev.adamko.kotka.topicdata.TopicRecord -import dev.adamko.kotka.topicdata.flatMapTopicRecords -import java.awt.Color -import java.awt.image.BufferedImage -import java.io.File +import dev.adamko.kafkatorio.processor.topology.PrototypeName +import dev.adamko.kafkatorio.processor.topology.WebMapTileChunkPixels +import dev.adamko.kafkatorio.processor.topology.WebMapTileChunkPosition +import dev.adamko.kafkatorio.processor.topology.aggregateWebMapTiles +import dev.adamko.kafkatorio.processor.topology.allMapTilesTable +import dev.adamko.kafkatorio.processor.topology.playerUpdatesToWsServer +import dev.adamko.kafkatorio.processor.topology.prototypesTable +import dev.adamko.kafkatorio.processor.topology.saveTileImages +import dev.adamko.kafkatorio.processor.topology.splitFactorioServerLog import java.time.Duration -import kotlin.math.abs -import kotlin.math.roundToInt -import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient -import kotlinx.serialization.decodeFromString -import kotlinx.serialization.encodeToString -import org.apache.kafka.common.serialization.Serdes import org.apache.kafka.streams.KafkaStreams -import org.apache.kafka.streams.StoreQueryParameters import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.TopologyDescription -import org.apache.kafka.streams.kstream.Consumed -import org.apache.kafka.streams.kstream.KStream import org.apache.kafka.streams.kstream.KTable -import org.apache.kafka.streams.kstream.Suppressed -import org.apache.kafka.streams.processor.RecordContext -import org.apache.kafka.streams.state.QueryableStoreTypes -import org.apache.kafka.streams.state.ReadOnlyKeyValueStore -import org.apache.kafka.streams.state.ValueAndTimestamp class KafkatorioTopology( @@ -70,21 +28,18 @@ class KafkatorioTopology( const val sourceTopic = "factorio-server-log" } -// private lateinit var tilePrototypesStore: ReadOnlyKeyValueStore> - fun build() { - parseAndSplitServerLog() - sendPlayerUpdatesToWebSocket() -// createMapTileImages() - val tilePrototypesTable: KTable = tilePrototypesTable() + splitFactorioServerLog(builder) + playerUpdatesToWsServer(websocketServer, builder) - val tilesTable: KTable = buildTilesTable() + val allMapTilesTable: KTable = allMapTilesTable(builder) + val tilePrototypesTable: KTable = prototypesTable(builder) - val tilesGroupedByChunk: KTable = - buildChunkedTilesTable(tilesTable) + val webMapTiles: KTable = + aggregateWebMapTiles(allMapTilesTable, tilePrototypesTable) - createChunkTileImage(tilePrototypesTable, tilesGroupedByChunk) + saveTileImages(webMapTiles) val topology = builder.build() @@ -99,370 +54,6 @@ class KafkatorioTopology( streams.start() -// tilePrototypesStore = streams.store( -// StoreQueryParameters.fromNameAndType( -// tilePrototypesTable.queryableStoreName(), -// QueryableStoreTypes.timestampedKeyValueStore() -// ) -// ) - } - - private fun parseAndSplitServerLog() { - - builder.stream( - sourceTopic, - consumedAs( - "read-raw-packets-from-server", - Serdes.String(), - Serdes.String(), - ) - ) - .mapValues("decode-packets") { _: String, value: String -> -// println("Mapping $readOnlyKey:$value") - jsonMapper.decodeFromString(value) - } - .to( - producedAs( - "split-server-log", - Serdes.String(), - KafkatorioPacketSerde - ) - ) { _: String, value: KafkatorioPacket, _: RecordContext -> -// println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") - when (value) { - is FactorioEvent -> - "kafkatorio.${value.packetType.name}.${value.data.objectName.name}" - is FactorioConfigurationUpdate -> - "kafkatorio.${value.packetType.name}.FactorioConfigurationUpdate" - is FactorioPrototypes -> - "kafkatorio.${value.packetType.name}.all" - } - } - - } - - private fun sendPlayerUpdatesToWebSocket() { - builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaPlayer}", - Consumed.with(Serdes.String(), KafkatorioPacketSerde) - ) - .foreach { _, value -> -// println("sending ${value.packetType} packet to websocket") - websocketServer.sendMessage(jsonMapper.encodeToString(value)) - } - } - - @Serializable - data class SurfaceIndex( - val surfaceIndex: Int - ) { - override fun toString() = "$surfaceIndex" - } - - @Serializable - data class SurfacePrototypesData( - val surfaceIndex: SurfaceIndex, - val mapTilePrototypes: Set, - ) - - private fun tilePrototypesTable(): KTable { - -// val tilePrototypesStreamName = "kafkatorio.stream.prototypes-tiles" -// val tilePrototypesStoreName = "kafkatorio.store.prototypes-tiles" - - return builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", - consumedAs( - "consume-all-prototypes-packets", - Serdes.String(), - jsonMapper.serde() - ) - ) - .map("flatten-map-tile-prototypes") { _, prototypes: FactorioPrototypes -> - val tilePrototypes = prototypes.prototypes - .filterIsInstance() - .toSet() - val key = SurfaceIndex(1) // TODO make surfaceIndex come from Factorio, not hard coded - val data = SurfacePrototypesData(key, tilePrototypes) - key to data - } - .peek { _, value -> - println("tile prototypes: ${value.mapTilePrototypes.joinToString { it.name }}") - } - .groupByKey( - groupedAs( - "grouping-tile-prototypes-by-surface-index", - jsonMapper.serde(), - jsonMapper.serde() - ) - ) - .reduce( - "group-surface-prototypes", - materializedWith( -// "kafkatorio.surface-prototypes", - jsonMapper.serde(), - jsonMapper.serde() - ) - ) { value1: SurfacePrototypesData, value2: SurfacePrototypesData -> - value1.copy(mapTilePrototypes = value1.mapTilePrototypes + value2.mapTilePrototypes) - } -// .toTable( -// materializedAs( -// "kafkatorio.prototypes.map-tiles", -// jsonMapper.serde(), -// jsonMapper.serde() -// ) -// ) -// .to( -// tilePrototypesStreamName, -// ) - -// return builder.globalTable( -// tilePrototypesStreamName, -// consumedAs( -// "send-tile-protos-to-gkt-store", -// jsonMapper.serde(), -// jsonMapper.serde() -// ), -// materializedAs( -// storeName = tilePrototypesStoreName, -// keySerde = jsonMapper.serde(), -// valueSerde = jsonMapper.serde(), -// ) -// ) - } - - @Serializable - data class TileUpdateRecordKey( - val surfaceIndex: SurfaceIndex, - val tilePosition: MapTilePosition, - ) - - @Serializable - data class TileUpdateRecord( - val surfaceIndex: SurfaceIndex, - val tilePosition: MapTilePosition, - val tile: MapTile, - ) : TopicRecord { - @Transient - override val topicKey: TileUpdateRecordKey = TileUpdateRecordKey(surfaceIndex, tilePosition) - } - - private fun buildTilesTable(): KTable { - - val luaTilesUpdatesStream: KStream = builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", - consumedAs("consume-map-tiles-packets", Serdes.String(), jsonMapper.serde()) - ) - .filter("events.filter.map-tiles") { _: String, event: FactorioEvent -> event.data is MapTiles } - .mapValues("events.extract-map-tiles") { _, event: FactorioEvent -> (event.data as? MapTiles)!! } - - val chunkTilesUpdateStream: KStream = builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", - consumedAs("consume-map-chunk-packets", Serdes.String(), jsonMapper.serde()) - ) - .filter("events.filter.map-chunks") { _: String, event: FactorioEvent -> event.data is MapChunk } - .mapValues("events.extract-map-chunks") { _, event: FactorioEvent -> (event.data as? MapChunk)!!.tiles } - - return luaTilesUpdatesStream - .merge("luaTilesUpdatesStream-and-chunkTilesUpdateStream", chunkTilesUpdateStream) - .flatMapTopicRecords("all-tiles-convert-to-TileUpdateRecord") { _, mapTiles: MapTiles -> -// println("all map tiles update ${mapTiles.tiles.size}") - mapTiles.tiles.map { tile -> - TileUpdateRecord( - SurfaceIndex(mapTiles.surfaceIndex), - tile.position, - tile, - ) - } - } - .toTable(materializedWith(jsonMapper.serde(), jsonMapper.serde())) -// .suppress( -// Suppressed.untilTimeLimit( -// Duration.ofSeconds(30), -// Suppressed.BufferConfig -// .maxRecords(100) -// .emitEarlyWhenFull() -// ) -// ) - } - - @Serializable - data class MapChunkDataPosition( - val position: MapChunkPosition, - val surfaceIndex: SurfaceIndex, - ) - - @Serializable - data class MapChunkData( - val chunkPosition: MapChunkDataPosition, - val tiles: Set, - ) - - private fun buildChunkedTilesTable( - tilesTable: KTable - ): KTable { - - @Serializable - data class MapChunkDataAggregator( - val tiles: MutableSet = mutableSetOf(), - ) - - return tilesTable - .toStream() -// .repartition( -// repartitionedAs( -// "repartition-all-tiles-before-chunk-grouping", -// jsonMapper.serde(), -// jsonMapper.serde() -// ) -// ) - .groupBy( - groupedAs("grouping-tiles-by-chunk-pos", jsonMapper.serde(), jsonMapper.serde()), - ) { key: TileUpdateRecordKey, value: TileUpdateRecord -> - MapChunkDataPosition( - value.tilePosition.toMapChunkPosition(), - key.surfaceIndex - ) - } - .aggregate( - "reducing-tiles-grouped-by-chunk-position", - materializedWith(jsonMapper.serde(), jsonMapper.serde()), - { MapChunkDataAggregator() }, - ) { _: MapChunkDataPosition, value: TileUpdateRecord, aggregate: MapChunkDataAggregator -> - aggregate.tiles.add(value.tile) - aggregate - } - // TODO maybe set serdes here? - .mapValues( - "tiles-grouped-by-chunk-position-finalise-aggregation", - materializedWith(jsonMapper.serde(), jsonMapper.serde()), - ) { k, v -> - MapChunkData(k, v.tiles) - } - - } - - private fun createChunkTileImage( - tilePrototypesTable: KTable, - tilesGroupedByChunk: KTable, - ) { - - @Serializable - data class ChunkTilesAndProtos( - val chunkTiles: MapChunkData, - val protos: SurfacePrototypesData - ) - -// tilesGroupedByChunk -// .join( -// tilePrototypesTable, -// { cd: MapChunkData -> cd.chunkPosition.surfaceIndex }, -// { chunkTiles: MapChunkData, protos: SurfacePrototypesData -> -// ChunkTilesAndProtos(chunkTiles, protos) -// }, -// namedAs("joining-chunks-tiles-prototypes"), -// materializedAs( -// "joined-chunked-tiles-with-prototypes", -// jsonMapper.serde(), -// jsonMapper.serde() -// ), -// ) - tilesGroupedByChunk - .join( - tilePrototypesTable, - "enrich-tiles-with-prototype-colour", - materializedAs( - "joined-chunked-tiles-with-prototypes", - jsonMapper.serde(), - jsonMapper.serde() - ), - { it.chunkPosition.surfaceIndex }, - ) { chunkTiles: MapChunkData, protos: SurfacePrototypesData -> - ChunkTilesAndProtos(chunkTiles, protos) - } - .suppress( - Suppressed.untilTimeLimit( - Duration.ofSeconds(30), - Suppressed.BufferConfig.maxRecords(30) - ) - ) - .toStream() - .foreach { _, (chunkTiles: MapChunkData, protos: SurfacePrototypesData) -> - runCatching { - saveMapTilesPng(chunkTiles, protos) - }.onFailure { e -> - println("error saving map tile png chunk:${chunkTiles.chunkPosition}") - e.printStackTrace() - throw e - } - } - } - - - private fun saveMapTilesPng(chunkTiles: MapChunkData, protos: SurfacePrototypesData) { - - val chunkPos = chunkTiles.chunkPosition - - val tilePrototypes: Map = - protos.mapTilePrototypes.associateBy { it.name }.withDefault { null } - - val chunkOriginX = chunkTiles.chunkPosition.position.leftTopTile.x -// val chunkOriginY = chunk.chunkPosition.position.rightBottomTile.y - val chunkOriginY = chunkTiles.chunkPosition.position.leftTopTile.y - - val chunkImage = - ImmutableImage.filled( - MAP_CHUNK_SIZE, - MAP_CHUNK_SIZE, - Color.BLACK, - BufferedImage.TYPE_INT_ARGB - ) - - chunkTiles.tiles.forEach { tile -> - - val prototypeColour = tilePrototypes - .getValue(tile.prototypeName) - ?.mapColour - ?.toHexadecimal() - - val rgbColour = when (prototypeColour) { - null -> { - println("missing prototype: ${tile.prototypeName}") - RGBColor(11, 11, 11, 0) - } - else -> RGBColor( - prototypeColour.red.roundToInt(), - prototypeColour.green.roundToInt(), - prototypeColour.blue.roundToInt(), - prototypeColour.alpha.roundToInt(), - ) - } - - val pixelX = abs(abs(tile.position.x) - abs(chunkOriginX)) - val pixelY = abs(abs(tile.position.y) - abs(chunkOriginY)) - - chunkImage.setColor( - pixelX, - pixelY, - rgbColour - ) - - } - - val zoom = 1u - val file = - File( - "src/main/resources/kafkatorio-web-map/s${chunkPos.surfaceIndex}/z$zoom/x${chunkOriginX}/y${chunkOriginY}.png" - ) - - if (file.parentFile.mkdirs()) { - println("created new map tile parentFile directory ${file.absolutePath}") - } - - println("saving map tile $file") - - chunkImage.output(PngWriter.MaxCompression, file) } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt index d573ded..99721bb 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt @@ -10,12 +10,8 @@ import kotlinx.coroutines.flow.withIndex import kotlinx.coroutines.job import kotlinx.coroutines.runBlocking import kotlinx.coroutines.supervisorScope -import org.http4k.core.Request -import org.http4k.core.Response -import org.http4k.core.Status.Companion.OK import org.http4k.routing.bind import org.http4k.routing.websockets -import org.http4k.server.PolyHandler import org.http4k.websocket.Websocket import org.http4k.websocket.WsHandler import org.http4k.websocket.WsMessage diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt index faaf92b..634fb6b 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -3,7 +3,6 @@ package dev.adamko.kafkatorio.processor import dev.adamko.kafkatorio.processor.config.ApplicationProperties import dev.adamko.kafkatorio.processor.tileserver.WebMapTileServer -import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.http4k.server.PolyHandler import org.http4k.server.Undertow @@ -24,11 +23,11 @@ fun main() = runBlocking { wsServer.build(), ).asServer(Undertow(9073)) -// Runtime.getRuntime().addShutdownHook(Thread { -// webServer.stop() -// }) + Runtime.getRuntime().addShutdownHook(Thread { + webServer.stop() + }) // launch { - webServer.start().block() + webServer.start().block() // } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioGameState.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioGameState.kt deleted file mode 100644 index d66e7d1..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioGameState.kt +++ /dev/null @@ -1,68 +0,0 @@ -package dev.adamko.kafkatorio.processor.topology - -import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -import dev.adamko.kafkatorio.events.schema.MapChunkPosition -import dev.adamko.kafkatorio.events.schema.MapTilePosition -import dev.adamko.kafkatorio.events.schema.MapTilePrototype -import dev.adamko.kafkatorio.processor.jsonMapper -import kotlinx.serialization.Serializable -import kotlinx.serialization.decodeFromString -import org.apache.kafka.common.serialization.Serdes -import org.apache.kafka.streams.StreamsBuilder -import org.apache.kafka.streams.kstream.Consumed -import org.apache.kafka.streams.kstream.KGroupedStream - -class FactorioGameState ( -private val builder: StreamsBuilder = StreamsBuilder(), -) { - private val sourceTopic = "factorio-server-log" - - - private fun gatherGameState() { - - val serverPackets: KGroupedStream = - builder.stream( - sourceTopic, - Consumed.with(Serdes.String(), Serdes.String()) - ) - .mapValues { readOnlyKey, value -> - println("Mapping $readOnlyKey:$value") - jsonMapper.decodeFromString(value) - } - .groupByKey() - - @Serializable - data class TileSurfaceData( - val surfaceIndex: Int, - val position: MapTilePosition, - val prototype: MapTilePrototype, - ) - - @Serializable - data class MapChunkData( - val position: MapChunkPosition, - val tiles: List, - ) - - @Serializable - data class FactorioSurfaceData( - val surfaceIndex: Int, - val chunks: List, - ) - - @Serializable - data class FactorioServerState( - val surfaces: Map, - val tilePrototypes: List, - ) - - - -// serverPackets -// .aggregate( -// Initializer { FactorioServerState("", emptyMap(), emptyList()) } -// ) - } - - -} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioServerState.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioServerState.kt new file mode 100644 index 0000000..48a80b0 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioServerState.kt @@ -0,0 +1,74 @@ +package dev.adamko.kafkatorio.processor.topology + +import dev.adamko.kafkatorio.events.schema.KafkatorioPacket +import dev.adamko.kafkatorio.events.schema.MapChunkPosition +import dev.adamko.kafkatorio.events.schema.MapTilePosition +import dev.adamko.kafkatorio.events.schema.MapTilePrototype +import dev.adamko.kafkatorio.processor.jsonMapper +import kotlinx.serialization.Serializable +import kotlinx.serialization.decodeFromString +import org.apache.kafka.common.serialization.Serdes +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.kstream.Consumed +import org.apache.kafka.streams.kstream.KGroupedStream + +private const val sourceTopic = "factorio-server-log" + +@JvmInline +@Serializable +value class FactorioServerId(val id: String) { + override fun toString() = id +} + +@Serializable +data class FactorioServerState( + val serverId: FactorioServerId, + val mapTilePrototypes: Set, + val surfaceIndexes: Set, +) + + +private fun gatherGameState(builder: StreamsBuilder = StreamsBuilder()) { + + val serverPackets: KGroupedStream = + builder.stream( + sourceTopic, + Consumed.with(Serdes.String(), Serdes.String()) + ) + .mapValues { readOnlyKey, value -> + println("Mapping $readOnlyKey:$value") + jsonMapper.decodeFromString(value) + } + .groupByKey() + + @Serializable + data class TileSurfaceData( + val surfaceIndex: Int, + val position: MapTilePosition, + val prototype: MapTilePrototype, + ) + + @Serializable + data class MapChunkData( + val position: MapChunkPosition, + val tiles: List, + ) + + @Serializable + data class FactorioSurfaceData( + val surfaceIndex: Int, + val chunks: List, + ) + + @Serializable + data class FactorioServerState( + val surfaces: Map, + val tilePrototypes: List, + ) + + +// serverPackets +// .aggregate( +// Initializer { FactorioServerState("", emptyMap(), emptyList()) } +// ) +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt new file mode 100644 index 0000000..de01bd0 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt @@ -0,0 +1,86 @@ +package dev.adamko.kafkatorio.processor.topology + +import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.FactorioObjectData +import dev.adamko.kafkatorio.events.schema.KafkatorioPacket +import dev.adamko.kafkatorio.events.schema.MapChunk +import dev.adamko.kafkatorio.events.schema.MapTile +import dev.adamko.kafkatorio.events.schema.MapTilePosition +import dev.adamko.kafkatorio.events.schema.MapTiles +import dev.adamko.kafkatorio.processor.jsonMapper +import dev.adamko.kotka.extensions.consumedAs +import dev.adamko.kotka.extensions.materializedWith +import dev.adamko.kotka.extensions.streams.filter +import dev.adamko.kotka.extensions.streams.flatMap +import dev.adamko.kotka.extensions.streams.mapValues +import dev.adamko.kotka.extensions.streams.toTable +import dev.adamko.kotka.kxs.serde +import java.time.Duration +import kotlinx.serialization.Serializable +import org.apache.kafka.common.serialization.Serdes +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.kstream.KStream +import org.apache.kafka.streams.kstream.KTable +import org.apache.kafka.streams.kstream.Suppressed + +@Serializable +data class TileUpdateRecordKey( + val surfaceIndex: SurfaceIndex, + val tilePosition: MapTilePosition, +) + + +fun allMapTilesTable( + builder: StreamsBuilder +): KTable { + + val luaTilesUpdatesStream: KStream = builder.stream( + "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", + consumedAs("consume-map-tiles-packets", Serdes.String(), jsonMapper.serde()) + ) + .filter("events.filter.map-tiles") { _: String, event: FactorioEvent -> event.data is MapTiles } + .mapValues("events.extract-map-tiles") { _, event: FactorioEvent -> (event.data as? MapTiles)!! } + + val chunkTilesUpdateStream: KStream = builder.stream( + "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", + consumedAs("consume-map-chunk-packets", Serdes.String(), jsonMapper.serde()) + ) + .filter("events.filter.map-chunks") { _: String, event: FactorioEvent -> event.data is MapChunk } + .mapValues("events.extract-map-chunks") { _, event: FactorioEvent -> (event.data as? MapChunk)!!.tiles } + + return luaTilesUpdatesStream + .merge(chunkTilesUpdateStream) + .flatMap("flat-map-all-tiles") { _, value -> + value.tiles.map { it.position to it } + } + .toTable( + "all-tiles-keyed-on-position", + materializedWith(jsonMapper.serde(), jsonMapper.serde()) + ) + .suppress( + Suppressed.untilTimeLimit( + Duration.ofSeconds(30), + Suppressed.BufferConfig + .maxRecords(30) + .emitEarlyWhenFull() + ) + ) +} + +//fun buildTilesTable( +// builder: StreamsBuilder +//): KTable { +// +// return luaTilesUpdatesStream +// .merge("luaTilesUpdatesStream-and-chunkTilesUpdateStream", chunkTilesUpdateStream) +// .flatMapTopicRecords("all-tiles-convert-to-TileUpdateRecord") { _, mapTiles: MapTiles -> +// mapTiles.tiles.map { tile -> +// TileUpdateRecord( +// SurfaceIndex(mapTiles.surfaceIndex), +// tile.position, +// tile, +// ) +// } +// } +// .toTable(materializedWith(jsonMapper.serde(), jsonMapper.serde())) +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt new file mode 100644 index 0000000..d071ad2 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt @@ -0,0 +1,54 @@ +package dev.adamko.kafkatorio.processor.topology + +import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate +import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.FactorioPrototypes +import dev.adamko.kafkatorio.events.schema.KafkatorioPacket +import dev.adamko.kafkatorio.processor.KafkatorioPacketSerde +import dev.adamko.kafkatorio.processor.KafkatorioTopology +import dev.adamko.kafkatorio.processor.jsonMapper +import dev.adamko.kotka.extensions.consumedAs +import dev.adamko.kotka.extensions.producedAs +import dev.adamko.kotka.extensions.streams.mapValues +import dev.adamko.kotka.extensions.streams.to +import kotlinx.serialization.decodeFromString +import org.apache.kafka.common.serialization.Serdes +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.processor.RecordContext + + +fun splitFactorioServerLog( + builder: StreamsBuilder = StreamsBuilder(), +) { + + builder.stream( + KafkatorioTopology.sourceTopic, + consumedAs( + "read-raw-packets-from-server", + Serdes.String(), + Serdes.String(), + ) + ) + .mapValues("decode-packets") { _: String, value: String -> +// println("Mapping $readOnlyKey:$value") + jsonMapper.decodeFromString(value) + } + .to( + producedAs( + "split-server-log", + Serdes.String(), + KafkatorioPacketSerde + ) + ) { _: String, value: KafkatorioPacket, _: RecordContext -> +// println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") + when (value) { + is FactorioEvent -> + "kafkatorio.${value.packetType.name}.${value.data.objectName.name}" + is FactorioConfigurationUpdate -> + "kafkatorio.${value.packetType.name}.FactorioConfigurationUpdate" + is FactorioPrototypes -> + "kafkatorio.${value.packetType.name}.all" + } + } + +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt new file mode 100644 index 0000000..1ba0d5c --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt @@ -0,0 +1,10 @@ +package dev.adamko.kafkatorio.processor.topology + +import kotlinx.serialization.Serializable + +@Serializable +data class SurfaceIndex( + val surfaceIndex: Int +) { + override fun toString() = "$surfaceIndex" +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt new file mode 100644 index 0000000..da1838c --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt @@ -0,0 +1,26 @@ +package dev.adamko.kafkatorio.processor.topology + +import dev.adamko.kafkatorio.events.schema.FactorioObjectData +import dev.adamko.kafkatorio.events.schema.KafkatorioPacket +import dev.adamko.kafkatorio.processor.KafkatorioPacketSerde +import dev.adamko.kafkatorio.processor.WebsocketServer +import dev.adamko.kafkatorio.processor.jsonMapper +import kotlinx.serialization.encodeToString +import org.apache.kafka.common.serialization.Serdes +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.kstream.Consumed + + +fun playerUpdatesToWsServer( + websocketServer: WebsocketServer, + builder: StreamsBuilder = StreamsBuilder(), +) { + builder.stream( + "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaPlayer}", + Consumed.with(Serdes.String(), KafkatorioPacketSerde) + ) + .foreach { _, value -> +// println("sending ${value.packetType} packet to websocket") + websocketServer.sendMessage(jsonMapper.encodeToString(value)) + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt new file mode 100644 index 0000000..a09c5b7 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -0,0 +1,100 @@ +package dev.adamko.kafkatorio.processor.topology + +import dev.adamko.kafkatorio.events.schema.FactorioPrototypes +import dev.adamko.kafkatorio.events.schema.KafkatorioPacket +import dev.adamko.kafkatorio.events.schema.MapTilePrototype +import dev.adamko.kafkatorio.processor.jsonMapper +import dev.adamko.kotka.extensions.consumedAs +//import dev.adamko.kotka.extensions.groupedAs +import dev.adamko.kotka.extensions.materializedWith +import dev.adamko.kotka.extensions.streams.flatMap +//import dev.adamko.kotka.extensions.streams.* +import dev.adamko.kotka.kxs.serde +import kotlinx.serialization.Serializable +import org.apache.kafka.common.serialization.Serdes +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.kstream.KTable + + +@Serializable +@JvmInline +value class PrototypeName(val name: String) { + override fun toString() = name +} + + +fun prototypesTable(builder: StreamsBuilder): KTable { + return builder.stream( + "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", + consumedAs( + "consume-all-prototypes-packets", + Serdes.String(), + jsonMapper.serde() + ) + ) + .flatMap("map-MapTilePrototype") { _, prototypes: FactorioPrototypes -> + prototypes.prototypes + .filterIsInstance() + .map { PrototypeName(it.name) to it } + } + .toTable( + materializedWith( + jsonMapper.serde(), + jsonMapper.serde() + ) + ) +} + + +//@Serializable +//data class FactorioServerPrototypesRecord( +// val serverId: FactorioServerId, +// val mapTilePrototypes: Map, +//) +// +//fun serverPrototypesTable(builder: StreamsBuilder): KTable { +// +// return builder.stream( +// "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", +// consumedAs( +// "consume-all-prototypes-packets", +// Serdes.String(), +// jsonMapper.serde() +// ) +// ) +// .map("build-FactorioServerPrototypesRecord", ::buildPrototypesRecord) +// .peek { _, value -> +// println("tile prototypes: ${value.mapTilePrototypes.keys.joinToString()}") +// } +// .groupByKey( +// groupedAs( +// "grouping-tile-prototypes-by-surface-index", +// jsonMapper.serde(), +// jsonMapper.serde() +// ) +// ) +// .reduce( +// "group-surface-prototypes", +// materializedWith( +//// "kafkatorio.surface-prototypes", +// jsonMapper.serde(), +// jsonMapper.serde() +// ) +// ) { value1: FactorioServerPrototypesRecord, value2: FactorioServerPrototypesRecord -> +// val allTiles = value1.mapTilePrototypes + value2.mapTilePrototypes +// value1.copy(mapTilePrototypes = allTiles) +// } +//} +// +//private fun buildPrototypesRecord( +// serverId: String, +// prototypes: FactorioPrototypes +//): Pair { +// val tilePrototypes = prototypes.prototypes +// .filterIsInstance() +// .associateBy { PrototypeName(it.name) } +// +// val key = FactorioServerId(serverId) +// val data = FactorioServerPrototypesRecord(key, tilePrototypes) +// return key to data +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt new file mode 100644 index 0000000..954a46c --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt @@ -0,0 +1,125 @@ +package dev.adamko.kafkatorio.processor.topology + +import dev.adamko.kafkatorio.events.schema.Colour +import dev.adamko.kafkatorio.events.schema.MapTile +import dev.adamko.kafkatorio.events.schema.MapTilePosition +import dev.adamko.kafkatorio.events.schema.MapTilePrototype +import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition +import dev.adamko.kafkatorio.processor.jsonMapper +import dev.adamko.kotka.extensions.groupedAs +import dev.adamko.kotka.extensions.materializedAs +import dev.adamko.kotka.extensions.namedAs +import dev.adamko.kotka.extensions.tables.groupBy +import dev.adamko.kotka.extensions.tables.join +import dev.adamko.kotka.extensions.tables.mapValues +import dev.adamko.kotka.extensions.toKeyValue +import dev.adamko.kotka.kxs.serde +import java.time.Duration +import kotlinx.serialization.Serializable +import org.apache.kafka.streams.kstream.KTable +import org.apache.kafka.streams.kstream.Suppressed + +/** The tiles of the webmap will be this many pixels high/wide */ +const val WEB_MAP_IMAGE_TILE_SIZE = 32 + +//@Serializable +//data class MapChunkDataPosition( +// val position: MapChunkPosition, +// val surfaceIndex: SurfaceIndex, +//) +// +//@Serializable +//data class MapChunkData( +// val chunkPosition: MapChunkDataPosition, +// val tiles: Set, +//) + +@Serializable +data class WebMapTileChunkPosition( + val chunkSize: Int, + val x: Int, + val y: Int, +) + +@Serializable +data class WebMapTilePixel( + val mapColour: Colour, + val tilePosition: MapTilePosition, +) + +@Serializable +data class WebMapTileChunkPixels( + val pixels: Set = mutableSetOf(), +) + +/** Temporary mutable aggregator */ +@Serializable +private data class WebMapTileChunkPixelsAcc( + val pixels: MutableSet = mutableSetOf(), +) + +fun aggregateWebMapTiles( + allMapTilesTable: KTable, + tilePrototypesTable: KTable, +): KTable { + + val webmapTileColours: KTable = + allMapTilesTable + .join( + tilePrototypesTable, + "convert-tiles-to-colours", + materializedAs( + "store-web-map-tile-pixels", + jsonMapper.serde(), + jsonMapper.serde(), + ), + { PrototypeName(it.prototypeName) }, + ) { tile: MapTile, proto: MapTilePrototype -> + WebMapTilePixel(proto.mapColour, tile.position) + } + + + val webMapTileChunkAggregate: KTable = + webmapTileColours + .groupBy( + groupedAs( + "group-webmap-tile-colours-into-chunks", + jsonMapper.serde(), + jsonMapper.serde(), + ) + ) { pos: MapTilePosition, px: WebMapTilePixel -> + val (chunkX, chunkY) = pos.toMapChunkPosition(WEB_MAP_IMAGE_TILE_SIZE) + val chunkPos = WebMapTileChunkPosition(WEB_MAP_IMAGE_TILE_SIZE, chunkX, chunkY) + (chunkPos to px).toKeyValue() + } + .aggregate( + { WebMapTileChunkPixelsAcc() }, + /* adder */ + { _: WebMapTileChunkPosition, newValue: WebMapTilePixel, acc: WebMapTileChunkPixelsAcc -> + acc.apply { pixels.add(newValue) } + }, + /* subtractor */ + { _: WebMapTileChunkPosition, oldValue: WebMapTilePixel, acc: WebMapTileChunkPixelsAcc -> + acc.apply { pixels.minus(oldValue) } + }, + namedAs("web-map-tile-colours-into-$WEB_MAP_IMAGE_TILE_SIZE-chunks"), + materializedAs("web-map-tile-colour-chunks-aggregate", jsonMapper.serde(), jsonMapper.serde()) + ) + .suppress( + Suppressed.untilTimeLimit( + Duration.ofSeconds(30), + Suppressed.BufferConfig + .maxRecords(2) +// .withMaxBytes(31457280 ) // 30MB + .emitEarlyWhenFull() + ).withName("web-map-tile-aggregate-debounce") + ) + + return webMapTileChunkAggregate + .mapValues( + "finalise-web-map-tile-colour-chunk-aggregation", + materializedAs("web-map-tile-colour-chunks", jsonMapper.serde(), jsonMapper.serde()) + ) { _, v -> + WebMapTileChunkPixels(v.pixels) + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt new file mode 100644 index 0000000..5d8b231 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt @@ -0,0 +1,92 @@ +package dev.adamko.kafkatorio.processor.topology + +import com.sksamuel.scrimage.ImmutableImage +import com.sksamuel.scrimage.color.RGBColor +import com.sksamuel.scrimage.nio.PngWriter +import dev.adamko.kafkatorio.events.schema.MAP_CHUNK_SIZE +import dev.adamko.kotka.extensions.tables.toStream +import java.awt.Color +import java.awt.image.BufferedImage +import java.io.File +import java.time.Duration +import kotlin.math.abs +import kotlin.math.roundToInt +import org.apache.kafka.streams.kstream.KTable +import org.apache.kafka.streams.kstream.Suppressed + + +fun saveTileImages( + webMapTiles: KTable +) { + + webMapTiles + .suppress( + Suppressed.untilTimeLimit( + Duration.ofSeconds(30), + Suppressed.BufferConfig.maxRecords(30) + ) + ) + .toStream("get-webmap-tile-updates") + .foreach { position: WebMapTileChunkPosition, pixels: WebMapTileChunkPixels -> + runCatching { + saveMapTilesPng(position, pixels.pixels) + }.onFailure { e -> + println("error saving map tile png chunk: $position") + e.printStackTrace() + throw e + } + } +} + + +private fun saveMapTilesPng( + chunkPosition: WebMapTileChunkPosition, + pixels: Set +) { + val surfaceIndex = 1 // TODO get surface index + + val chunkOriginX = chunkPosition.x * chunkPosition.chunkSize + val chunkOriginY = chunkPosition.y * chunkPosition.chunkSize + + val chunkImage = + ImmutableImage.filled( + MAP_CHUNK_SIZE, + MAP_CHUNK_SIZE, + Color.BLACK, + BufferedImage.TYPE_INT_ARGB + ) + + pixels.forEach { pixel -> + + val rgbColour = RGBColor( + pixel.mapColour.red.roundToInt(), + pixel.mapColour.green.roundToInt(), + pixel.mapColour.blue.roundToInt(), + pixel.mapColour.alpha.roundToInt(), + ) + + val pixelX = abs(abs(pixel.tilePosition.x) - abs(chunkOriginX)) + val pixelY = abs(abs(pixel.tilePosition.y) - abs(chunkOriginY)) + + chunkImage.setColor( + pixelX, + pixelY, + rgbColour + ) + + } + + val zoom = 1u + val file = + File( + "src/main/resources/kafkatorio-web-map/s${surfaceIndex}/z$zoom/x${chunkOriginX}/y${chunkOriginY}.png" + ) + + if (file.parentFile.mkdirs()) { + println("created new map tile parentFile directory ${file.absolutePath}") + } + + println("saving map tile $file") + + chunkImage.output(PngWriter.MaxCompression, file) +} From 27776553ba3eb8f979deedd38609e74af2150f66 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 21 Jan 2022 07:56:36 +0100 Subject: [PATCH 160/629] increase partition size, try making performance better --- .../main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt index 3d07c2e..845a7c3 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt @@ -2,7 +2,6 @@ package dev.adamko.kafkatorio.admin import dev.adamko.kafkatorio.events.schema.FactorioObjectData import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -import dev.adamko.kafkatorio.processor.KafkatorioTopology import java.util.concurrent.TimeUnit import mu.KotlinLogging import org.apache.kafka.clients.admin.Admin @@ -68,8 +67,8 @@ object CreateTopics { } private fun Admin.createTopics( - numPartitions: Int = 1, - replicationFactor: Short = 1, + numPartitions: Int = 10, + replicationFactor: Short = 5, topicNames: () -> Collection, ): CreateTopicsResult = createTopics(topicNames().distinct().map { From 8c107b7b84628ef006e8ffb580901379811bbc44 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 21 Jan 2022 07:57:07 +0100 Subject: [PATCH 161/629] delete extensions, they were moved to kotka --- .../kafkastreams/GlobalKTableDefinition.kt | 31 ---- .../extensions/kafkastreams/KGroupedStream.kt | 32 ---- .../kafkastreams/KStreamExtensions.kt | 152 ------------------ .../kafkastreams/KStreamTransform.kt | 90 ----------- .../kafkastreams/KTableExtensions.kt | 48 ------ .../kafkastreams/KafkaStreamsExtensions.kt | 91 ----------- .../kafkastreams/KeyPairExtensions.kt | 33 ---- .../extensions/kafkastreams/KeyValueSerdes.kt | 41 ----- .../extensions/kafkastreams/TopicData.kt | 17 -- .../kafkastreams/TopicDefinition.kt | 42 ----- .../extensions/kafkastreams/aliases.kt | 7 - .../kxs/KotlinxSerializationExtensions.kt | 55 ------- 12 files changed, 639 deletions(-) delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/GlobalKTableDefinition.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KGroupedStream.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamExtensions.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamTransform.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KTableExtensions.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KafkaStreamsExtensions.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyPairExtensions.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyValueSerdes.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicData.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicDefinition.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/aliases.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kxs/KotlinxSerializationExtensions.kt diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/GlobalKTableDefinition.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/GlobalKTableDefinition.kt deleted file mode 100644 index 630dea6..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/GlobalKTableDefinition.kt +++ /dev/null @@ -1,31 +0,0 @@ -package dev.adamko.kafkatorio.extensions.kafkastreams - -import org.apache.kafka.streams.state.QueryableStoreTypes.timestampedKeyValueStore - -///** -// * * update topic [topicName] -// * * plus table-source topic [tableName] -// * * plus state store [globalStoreName] -// * -// * equals a GlobalTableDefinition -// */ -//abstract class GlobalKTableDefinition( -// val tableName: String, -// override val serdes: KeyValueSerdes, -// val globalStoreName: String = "$tableName-store", -// /** -// * The backing topic, from which this table will be filled. -// * -// * Updates to items can be sent or received with this topic. -// */ -// final override val topicName: String = "$tableName-topic", -// val storeType: TimestampedQueryStoreType = timestampedKeyValueStore(), -//) : TopicDefinition { -// val topicNames: Set -// -// init { -// require(tableName != topicName) -// require(tableName != globalStoreName) -// topicNames = setOf(tableName, topicName) -// } -//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KGroupedStream.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KGroupedStream.kt deleted file mode 100644 index d93e27f..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KGroupedStream.kt +++ /dev/null @@ -1,32 +0,0 @@ -package dev.adamko.kafkatorio.extensions.kafkastreams -// -//import org.apache.kafka.common.utils.Bytes -//import org.apache.kafka.streams.kstream.KGroupedStream -//import org.apache.kafka.streams.kstream.KTable -//import org.apache.kafka.streams.kstream.Materialized -//import org.apache.kafka.streams.state.KeyValueStore -// -// -//fun KGroupedStream.count( -// name: String? = null, -// materialized: Materialized>? = null, -//): KTable { -// return when { -// name != null && materialized != null -> count(withName(name), materialized) -// name == null && materialized != null -> count(materialized) -// name != null && materialized == null -> count(withName(name)) -// else -> count() -// } -//} -// -// -// -//// CogroupedKStream cogroup(final Aggregator aggregator); -//// KTable aggregate(final Initializer initializer,final Aggregator aggregator, final Named named, final Materialized> materialized); -//// TimeWindowedKStream windowedBy(final Windows windows); -////KTable count(final Materialized> materialized); -////KTable reduce(final Reducer reducer); -////KTable reduce(final Reducer reducer, final Named named, final Materialized> materialized); -////KTable reduce(final Reducer reducer,final Materialized> materialized); -////SessionWindowedKStream windowedBy(final SessionWindows windows); -////TimeWindowedKStream windowedBy(final SlidingWindows windows); diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamExtensions.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamExtensions.kt deleted file mode 100644 index e29186f..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamExtensions.kt +++ /dev/null @@ -1,152 +0,0 @@ -package dev.adamko.kafkatorio.extensions.kafkastreams -// -//import org.apache.kafka.streams.kstream.Grouped -//import org.apache.kafka.streams.kstream.KGroupedStream -//import org.apache.kafka.streams.kstream.KStream -//import org.apache.kafka.streams.kstream.Produced -//import org.apache.kafka.streams.processor.TopicNameExtractor -// -//// /** @see KStream.map */ -//// inline fun > KStream.map( -//// name: String, -//// crossinline mapper: (key: inK, value: inV) -> outV -//// ): KStream = -//// map({ k, v -> mapper(k, v).asKeyValue() }, withName(name)) -// -///** @see KStream.map */ -//inline fun KStream.map( -// name: String, -// crossinline mapper: (key: inK, value: inV) -> Pair -//): KStream = -// map({ k, v -> mapper(k, v).toKeyValue() }, withName(name)) -// -///** @see [KStream.mapValues] */ -//inline fun KStream.mapValues( -// name: String, -// crossinline mapper: (key: K, value: inV) -> outV -//): KStream = mapValues({ k, v -> mapper(k, v) }, withName(name)) -// -//// /** @see KStream.flatMap */ -//// inline fun > KStream.flatMap( -//// name: String, -//// crossinline mapper: (key: inK, value: inV) -> Iterable -//// ): KStream = flatMap( -//// { k, v -> mapper(k, v).map { a: outV -> a.toKeyValue() } }, -//// withName(name) -//// ) -// -///** @see KStream.flatMap */ -//inline fun KStream.flatMap( -// name: String, -// crossinline mapper: (key: inK, value: inV) -> Iterable> -//): KStream = flatMap( -// { k, v -> mapper(k, v).map { it.toKeyValue() } }, -// withName(name) -//) -// -///** @see KStream.groupBy */ -//fun KStream.groupBy( -// grouped: Grouped, -// keySelector: (K, V) -> outK -//): KGroupedStream = groupBy(keySelector, grouped) -// -//fun KStream.to( -// produced: Produced, -// topicNameExtractor: TopicNameExtractor, -//) = to(topicNameExtractor, produced) -// -//fun KStream.filter( -// name: String, -// predicate: (K, V) -> Boolean, -//): KStream = filter(predicate, withName(name)) -// -// -//fun KStream.filterNot( -// name: String, -// predicate: (K, V) -> Boolean, -//): KStream = filterNot(predicate, withName(name)) -// -// -//fun KStream.merge( -// name: String, -// other: KStream, -//): KStream = merge(other, withName(name)) -// -// -//// KStream filter(final Predicate predicate, final Named named); -//// KStream filterNot(final Predicate predicate, final Named named); -// -//// @JvmName("flatMapKeyValuePairs") -//// inline fun KStream.flatMap( -//// name: String, -//// crossinline mapper: (key: inK, value: inV) -> Iterable> -//// ): KStream = -//// flatMap( -//// { k, v -> mapper(k, v).map { it.asKeyPair() } }, -//// withName(name) -//// ) -// -//// inline fun KStream.mapValues( -//// name: String, -//// crossinline mapper: (readOnlyKey: K, value: inV) -> outV -//// ): KStream = -//// map({ k, v -> (k to mapper(v)).asKeyPair() }, KafkaStreamsExtensions.withName(name)) -// -// -////open class TransformerKt( -////) : Transformer> { -//// -//// val onClose: TransformerKt.() -> Unit = {} -//// val transformer: TransformerKt.(key: inK, value: inV) -> KeyValue? = -//// {} -//// -//// private lateinit var _context: ProcessorContext -//// val context: ProcessorContext? -//// get() = if (this::_context.isInitialized) _context else null -//// -//// override fun init(context: ProcessorContext) { -//// this._context = context -//// } -//// -//// override fun close() { -//// onClose() -//// } -//// -//// override fun transform(key: inK, value: inV): KeyValue? { -//// return transformer(key, value) -//// } -////} -//// -//// -//// /** one or the other or both */ -//// KTable toTable(final Named named, Materialized> materialized); -//// KStream join(final GlobalKTable globalTable, KeyValueMapper keySelector, ValueJoinerWithKey joiner, Named named); -//// KStream leftJoin(final GlobalKTable globalTable, KeyValueMapper keySelector, ValueJoinerWithKey valueJoiner, Named named); -//// KStream flatTransform(final TransformerSupplier>> transformerSupplier, Named named, String... stateStoreNames); -//// KStream flatTransform(final TransformerSupplier>> transformerSupplier, String... stateStoreNames); -//// KStream transform(final TransformerSupplier> transformerSupplier, Named named, String... stateStoreNames); -//// KStream transform(final TransformerSupplier> transformerSupplier, String... stateStoreNames); -//// KStream flatMap(final KeyValueMapper>> mapper, Named named); -//// KStream map(final KeyValueMapper> mapper, Named named); -//// KGroupedStream groupBy(final KeyValueMapper keySelector, Grouped grouped); -//// KStream selectKey(final KeyValueMapper mapper, Named named); -//// KStream join(final KStream otherStream, ValueJoinerWithKey joiner, JoinWindows windows, StreamJoined streamJoined); -//// KStream leftJoin(final KStream otherStream, ValueJoinerWithKey joiner, JoinWindows windows, StreamJoined streamJoined); -//// KStream outerJoin(final KStream otherStream, ValueJoinerWithKey joiner, JoinWindows windows, StreamJoined streamJoined); -//// KStream flatMapValues(final ValueMapperWithKey> mapper, Named named); -//// KStream flatTransformValues(final ValueTransformerWithKeySupplier> valueTransformerSupplier, Named named, String... stateStoreNames); -//// KStream mapValues(final ValueMapperWithKey mapper, Named named); -//// KStream transformValues(final ValueTransformerWithKeySupplier valueTransformerSupplier, Named named, String... stateStoreNames); -//// KStream join(final KTable table, ValueJoinerWithKey joiner, Joined joined); -//// KStream leftJoin(final KTable table, ValueJoinerWithKey joiner, Joined joined); -//// BranchedKStream split(final Named named); -//// KGroupedStream groupByKey(final Grouped grouped); -//// KStream merge(final KStream stream, final Named named); -//// KStream peek(final ForeachAction action, final Named named); -//// KStream repartition(final Repartitioned repartitioned); -//// void foreach(final ForeachAction action, final Named named); -//// void print(final Printed printed); -//// void process(final ProcessorSupplier processorSupplier, Named named, String... stateStoreNames); -//// void to(final String topic, Produced produced); -//// void to(final TopicNameExtractor topicExtractor, Produced produced); -//// diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamTransform.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamTransform.kt deleted file mode 100644 index fa6837d..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KStreamTransform.kt +++ /dev/null @@ -1,90 +0,0 @@ -package dev.adamko.kafkatorio.extensions.kafkastreams -// -//import dev.adamko.kafkatorio.extensions.kafkastreams.* -//import kotlin.experimental.ExperimentalTypeInference -//import org.apache.kafka.streams.KeyValue -//import org.apache.kafka.streams.kstream.KStream -//import org.apache.kafka.streams.kstream.Transformer -//import org.apache.kafka.streams.kstream.TransformerSupplier -//import org.apache.kafka.streams.processor.ProcessorContext -// -///** @see KStream.transform */ -//inline fun KStream.transformKt( -// crossinline block: BuildTransformer -//): KStream { -// -// val transformer = object : Transformer> { -// -// private lateinit var scope: TransformerScope -// -// override fun init(procContext: ProcessorContext) { -// scope = TransformerScope(procContext) -// scope.block() -// } -// -// override fun close() { -// scope.close() -// } -// -// override fun transform(key: inK, value: inV): KeyValue? { -// return scope.mapper(key, value)?.toKeyValue() -// } -// } -// -// return transform({ transformer }) -//} -// -///** @see KStream.transform */ -//@OptIn(ExperimentalTypeInference::class) -//inline fun > KStream.transformKt2( -// @BuilderInference block: Transformer.() -> Unit -//): KStream { -// -// val transformer = object : Transformer> { -// -// private lateinit var scope: TransformerScope -// -// override fun init(procContext: ProcessorContext) { -// scope = TransformerScope(procContext) -// } -// -// override fun close() { -// scope.close() -// -// sequence { -// -// } -// } -// -// override fun transform(key: inK, value: inV): KeyValue? { -// return scope.mapper(key, value)?.toKeyValue() -// } -// } -// -// return transform(TransformerSupplier { transformer }) -//} -// -//typealias BuildTransformer = TransformerScope.() -> Unit -// -//typealias TransformerMapper = (key: inK, value: inV) -> Pair? -//typealias TransformerCloseHandler = (ProcessorContext) -> Unit -// -//open class TransformerScope( -// val processorContext: ProcessorContext, -//) : AutoCloseable { -// -// private var closeHandler: TransformerCloseHandler = {} -// lateinit var mapper: TransformerMapper -// -// fun handleClose(closeHandler: TransformerCloseHandler) { -// this.closeHandler = closeHandler -// } -// -// fun mapEach(mapper: TransformerMapper) { -// this.mapper = mapper -// } -// -// override fun close() { -// closeHandler(processorContext) -// } -//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KTableExtensions.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KTableExtensions.kt deleted file mode 100644 index 5986f81..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KTableExtensions.kt +++ /dev/null @@ -1,48 +0,0 @@ -package dev.adamko.kafkatorio.extensions.kafkastreams -// -// -//import org.apache.kafka.streams.KeyValue -//import org.apache.kafka.streams.kstream.Grouped -//import org.apache.kafka.streams.kstream.KGroupedTable -//import org.apache.kafka.streams.kstream.KTable -//import org.apache.kafka.streams.kstream.KeyValueMapper -// -///** @see [KTable.mapValues] */ -//fun KTable.mapValues( -// name: String, -// mapper: (readOnlyKey: K, value: inV) -> outV -//): KTable = -// mapValues( -// { k, v -> mapper(k, v) }, -// withName(name) -// ) -// -///** @See [KTable.groupBy] */ -//fun KTable.groupBy( -// grouped: Grouped? = null, -// selector: KeyValueMapper> -//): KGroupedTable = when (grouped) { -// null -> groupBy(selector) -// else -> groupBy(selector, grouped) -//} -// -// -//// -//// KStream toStream(final KeyValueMapper mapper,final Named named); -//// KTable join(final KTable other,final ValueJoiner joiner,final Named named,final Materialized> materialized); -//// KTable join(final KTable other,final Function foreignKeyExtractor,final ValueJoiner joiner,final Named named,final Materialized> materialized); -//// -//// KTable leftJoin(final KTable other,final ValueJoiner joiner,final Named named,final Materialized> materialized); -//// -//// KTable outerJoin(final KTable other,final ValueJoiner joiner,final Named named,final Materialized> materialized); -//// KTable leftJoin(final KTable other,final Function foreignKeyExtractor,final ValueJoiner joiner,final Named named,final Materialized> materialized); -//// KTable mapValues(final ValueMapper mapper,final Named named,final Materialized> materialized); -//// KTable mapValues(final ValueMapperWithKey mapper,final Named named,final Materialized> materialized); -//// KTable transformValues(final ValueTransformerWithKeySupplier transformerSupplier,final Materialized> materialized,final Named named,final String... stateStoreNames); -////KStream toStream(final Named named); -/////** materialized, named - optional */ -////KTable filter(final Predicate predicate,final Named named,final Materialized> materialized); -/////** materialized, named - optional */ -////KTable filterNot(final Predicate predicate,final Named named,final Materialized> materialized); -////KTable suppress(final Suppressed suppressed); -////String queryableStoreName(); diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KafkaStreamsExtensions.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KafkaStreamsExtensions.kt deleted file mode 100644 index 54a9d0f..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KafkaStreamsExtensions.kt +++ /dev/null @@ -1,91 +0,0 @@ -package dev.adamko.kafkatorio.extensions.kafkastreams -// -//import org.apache.kafka.common.serialization.Serde -//import org.apache.kafka.streams.kstream.Grouped -//import org.apache.kafka.streams.kstream.Joined -//import org.apache.kafka.streams.kstream.Materialized -//import org.apache.kafka.streams.kstream.Named -//import org.apache.kafka.streams.kstream.Produced -//import org.apache.kafka.streams.kstream.Repartitioned -//import org.apache.kafka.streams.processor.StateStore -// -///** Helpful extensions & shortcuts for Kafka Streams */ -// -// -///** @see [Named] */ -//fun withName(name: String): Named = Named.`as`(name) -// -//// @Suppress("FunctionName") -//// inline fun MaterializedAs( -//// tableDefinition: GlobalTableDefinition -//// ) = MaterializedAs( -//// tableDefinition.globalStoreName, -//// tableDefinition.serdes.keySerde, -//// tableDefinition.serdes.valueSerde -//// ) -// -///** @see Materialized */ -//inline fun materializedAs( -// name: String, -// keySerde: Serde,//= kxsJsonSerde(), -// valueSerde: Serde,//= kxsJsonSerde(), -//): Materialized = -// Materialized.`as`(name) -// .withKeySerde(keySerde) -// .withValueSerde(valueSerde) -// -///** @see Repartitioned */ -//inline fun repartitionedAs( -// name: String, -// keySerde: Serde, -// valueSerde: Serde, -//): Repartitioned = -// Repartitioned.`as`(name) -// .withKeySerde(keySerde) -// .withValueSerde(valueSerde) -// -///** @see Produced */ -//fun producedAs(name: String): Produced = -// Produced.`as`(name) -// -///** @see Produced */ -//inline fun producedAs( -// name: String, -// keySerde: Serde, -// valueSerde: Serde, -//): Produced = -// producedAs(name) -// .withKeySerde(keySerde) -// .withValueSerde(valueSerde) -// -//// @Suppress("FunctionName") -//// fun JoinedAs(name: String): Joined = -//// Joined.`as`(name) -// -///** @see Joined */ -//inline fun joinedAs( -// name: String, -// keySerde: Serde,// = kxsJsonSerde(), -// valueSerde: Serde,//= kxsJsonSerde(), -// otherValueSerde: Serde?,//= kxsJsonSerde(), -//): Joined = -// Joined.`as`(name) -// .withKeySerde(keySerde) -// .withValueSerde(valueSerde) -// .withOtherValueSerde(otherValueSerde) -// -///** @see [Grouped.`as`] */ -//inline fun groupedAs( -// name: String, -// keySerde: Serde?, //= jsonMapper.serde(), -// valueSerde: Serde?, //= jsonMapper.serde(), -//): Grouped = -// Grouped.`as`(name) -// .withKeySerde(keySerde) -// .withValueSerde(valueSerde) -// -//// fun InteractiveQueryService.getQueryableStore( -//// tableDef: GlobalTableDefinition -//// ): Optional>> { -//// return getQueryableStore(tableDef.globalStoreName, tableDef.storeType) -//// } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyPairExtensions.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyPairExtensions.kt deleted file mode 100644 index 4856ba4..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyPairExtensions.kt +++ /dev/null @@ -1,33 +0,0 @@ -package dev.adamko.kafkatorio.extensions.kafkastreams -// -//import org.apache.kafka.streams.KeyValue -//import org.apache.kafka.streams.state.ValueAndTimestamp -// -// -//inline fun Pair.toKeyValue(): KeyValue = -// KeyValue.pair(first, second) -// -//infix fun K.kvPair(value: V): KeyValue = KeyValue(this, value) -// -//infix fun V.timestamped(timestamp: Long): ValueAndTimestamp = -// ValueAndTimestamp.make(this, timestamp) -// -// -//@JvmName("keyValueGetKey") -//operator fun KeyValue.component1(): K = key -//@JvmName("keyValueGetValue") -//operator fun KeyValue.component2(): V = value -// -// -//@JvmName("keyValueTimestampGetKey") -//operator fun KeyValue>.component1(): K = key -//@JvmName("keyValueTimestampGetValue") -//operator fun KeyValue>.component2(): V = value.value() -//@JvmName("keyValueTimestampGetTimestamp") -//operator fun KeyValue>.component3(): Long = value.timestamp() -// -// -//@JvmName("valueTimestampGetValue") -//operator fun ValueAndTimestamp.component1(): V = value() -//@JvmName("valueTimestampGetTimestamp") -//operator fun ValueAndTimestamp.component2(): Long = timestamp() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyValueSerdes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyValueSerdes.kt deleted file mode 100644 index fa1aa18..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/KeyValueSerdes.kt +++ /dev/null @@ -1,41 +0,0 @@ -package dev.adamko.kafkatorio.extensions.kafkastreams - -//import dev.adamko.kafkatorio.extensions.kxs.KotlinxSerializationExtensions.serde -//import dev.adamko.kafkatorio.processor.jsonMapper -//import org.apache.kafka.common.serialization.Serde -//import org.apache.kafka.common.serialization.Serdes -//import org.apache.kafka.streams.kstream.Consumed -//import org.apache.kafka.streams.kstream.Produced -//import org.apache.kafka.streams.kstream.Repartitioned -// -///** -// * A wrapper for two [Serde]s - [one for the Key][keySerde], [another for the Value][valueSerde]. -// */ -//open class KeyValueSerdes( -// val keySerde: Serde, -// val valueSerde: Serde, -//) { -// -// fun consumer(name: String): Consumed = -// Consumed.with(keySerde, valueSerde).withName(name) -// -// fun producer(name: String): Produced = -// Produced.with(keySerde, valueSerde).withName(name) -// -// fun repartitioned(name: String): Repartitioned = -// Repartitioned.with(keySerde, valueSerde).withName(name) -// -// companion object { -// inline fun kxsJson(): KeyValueSerdes = -// KeyValueSerdes( -// jsonMapper.serde(), -// jsonMapper.serde(), -// ) -// -// fun string(): KeyValueSerdes = -// KeyValueSerdes( -// Serdes.String(), -// Serdes.String(), -// ) -// } -//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicData.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicData.kt deleted file mode 100644 index 33027c2..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicData.kt +++ /dev/null @@ -1,17 +0,0 @@ -package dev.adamko.kafkatorio.extensions.kafkastreams - -//import org.apache.kafka.streams.KeyValue -// -//interface TopicData { -// -// val topicKey: K -// -// companion object { -// fun > T.toPair(): Pair = topicKey to this -// fun > T.toKeyValue(): KeyValue = KeyValue.pair(topicKey, this) -// -// operator fun > T.component1(): K = topicKey -// operator fun > T.component2(): T = this -// -// } -//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicDefinition.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicDefinition.kt deleted file mode 100644 index fbb2ea5..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/TopicDefinition.kt +++ /dev/null @@ -1,42 +0,0 @@ -package dev.adamko.kafkatorio.extensions.kafkastreams; - -///** -// * A definition for all topics that are created in Kafka. -// * -// * These can be used to create KTopics, KTables, or GlobalKTables. -// */ -//interface TopicDefinition { -// -// /** unique kafka processor id */ -// val pid: String -// get() = this::class.simpleName!! -// -// /** -// * Unique name for each [TopicDefinition] -// * -// * https://devshawn.com/blog/apache-kafka-topic-naming-conventions/ -// * -// * https://www.xeotek.com/topic-naming-conventions-how-do-i-name-my-topics-5-recommendations-with-examples/ -// * -// * Domain: warehouse -// * Operation: stock-management -// * Data type: -// * - cdc=all instances of a specific object/thing/item, -// * - cmd=command (mutation), -// * - fct=fact (information (complete or partial) -// * about an event at specific point in time) -// * - sys=internal system topic - not meant for external use -// * - tbl=a global table store (must be paired with another topic) -// * Description: the data type -// * -// * Version: stored in message header -// * -// * ``` -// * warehouse.stock-management.sts/cdc/cmd.warehouse-item -// * ``` -// */ -// val topicName: String -// -// val serdes: KeyValueSerdes -// -//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/aliases.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/aliases.kt deleted file mode 100644 index 78f35cf..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kafkastreams/aliases.kt +++ /dev/null @@ -1,7 +0,0 @@ -package dev.adamko.kafkatorio.extensions.kafkastreams - -import org.apache.kafka.streams.state.QueryableStoreType -import org.apache.kafka.streams.state.ReadOnlyKeyValueStore -import org.apache.kafka.streams.state.ValueAndTimestamp - -//typealias TimestampedQueryStoreType = QueryableStoreType>> diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kxs/KotlinxSerializationExtensions.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kxs/KotlinxSerializationExtensions.kt deleted file mode 100644 index fc94a20..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/extensions/kxs/KotlinxSerializationExtensions.kt +++ /dev/null @@ -1,55 +0,0 @@ -package dev.adamko.kafkatorio.extensions.kxs - -//import kotlinx.serialization.decodeFromString -//import kotlinx.serialization.encodeToString -//import kotlinx.serialization.json.Json -//import org.apache.kafka.common.serialization.Deserializer -//import org.apache.kafka.common.serialization.Serde -//import org.apache.kafka.common.serialization.Serializer -// -//object KotlinxSerializationExtensions { -// -// inline fun Json.kafkaSerializer() = Serializer { topic: String, data: T -> -// runCatching { -// encodeToString(data).encodeToByteArray() -//// jsonMapper.encodeToString(data as T).encodeToByteArray() -// }.getOrElse { e -> -// println( -// """ -// Exception on encodeToString -// Topic: $topic -// topicData: $data -// topicData as T: ${data as T} -// """.trimIndent() -// ) -// e.printStackTrace() -// throw e -// } -// } -// -// inline fun Json.kafkaDeserializer() = Deserializer { topic: String, data: ByteArray -> -// runCatching { -// decodeFromString(data.decodeToString()) -// }.getOrElse { e -> -// println( -// """ -// Exception on decodeFromString, -// Topic: $topic -// topicData: $data -// topicData as T: ${data as T} -// """.trimIndent() -// ) -// e.printStackTrace() -// throw e -// } -// } -// -// -// inline fun Json.serde() = object : Serde { -// -// override fun serializer(): Serializer = kafkaSerializer() -// -// override fun deserializer(): Deserializer = kafkaDeserializer() -// } -// -//} From f2ccbbd456cd4a7e22307cac589d86400419235b Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 21 Jan 2022 18:31:15 +0100 Subject: [PATCH 162/629] - factorio version bump - mod: add a couple of commands for emitting chunks - mod: decrease on_tick event rate - mod: version bump typed-factorio, tstl - kafka admin: decrease replication - kafka admin: filter out existing-topics when creating - events server: add more serdes, hopefully more performant than json - events server: lots of work trying to improve performance... - events server: increase tile size to 256 - events server: fix web-map-tile-image x/y location - kafka: version bump - kafka: increase default partition size - kafka ui: version bump - --- build.gradle.kts | 2 +- gradle/libs.versions.toml | 2 +- .../main/commands/kafkatorioCommands.ts | 58 +++++++- .../main/events/registerHandlers.ts | 2 +- .../src/main/typescript/package-lock.json | 42 +++--- .../src/main/typescript/package.json | 6 +- modules/events-server/build.gradle.kts | 1 + .../adamko/kafkatorio/admin/CreateTopics.kt | 24 +++- .../processor/KafkatorioTopology.kt | 4 +- .../kafkatorio/processor/serdes/kxsBinary.kt | 105 +++++++++++++++ .../{serdes.kt => serdes/kxsJson.kt} | 2 +- .../kafkatorio/processor/serdes/protobuf.kt | 59 +++++++++ .../processor/topology/FactorioServerState.kt | 124 +++++++++--------- .../processor/topology/factorioMapTiles.kt | 66 +++++----- .../topology/factorioServerPackets.kt | 56 +++++++- .../kafkatorio/processor/topology/model.kt | 7 +- .../processor/topology/playerUpdates.kt | 4 +- .../processor/topology/prototypes.kt | 4 +- .../processor/topology/webMapTileAggregate.kt | 39 +++--- .../processor/topology/webMapTiles.kt | 14 +- modules/infra-factorio-server/src/.env | 4 +- modules/infra-kafka-cluster/src/.env | 2 +- .../src/docker-compose.yml | 4 +- .../src/kafka-server.properties | 23 +--- modules/infra-kafka-pipe/src/.env | 2 +- .../dev/adamko/kafkatorio/webmap/map.kt | 5 +- .../adamko/kafkatorio/webmap/websockets.kt | 22 ++-- 27 files changed, 476 insertions(+), 207 deletions(-) create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/{serdes.kt => serdes/kxsJson.kt} (96%) create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/protobuf.kt diff --git a/build.gradle.kts b/build.gradle.kts index c12c822..f23f144 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.2.4" +version = "0.2.6" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a9e448b..7dd2fe9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,7 +23,7 @@ junit = "5.8.2" kotest = "5.0.1" ## infra ## -factorio = "1.1.50" +factorio = "1.1.53" confluent-kafkaConnect = "7.0.1" ######### diff --git a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts index 8087f98..20b692a 100644 --- a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts +++ b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts @@ -1,4 +1,6 @@ import {emitPrototypes} from "../config-update/prototypes"; +import {handleChunkUpdate} from "../events/handlers"; +import floor = math.floor; commands.add_command( "kafkatorio", @@ -6,7 +8,59 @@ commands.add_command( (e: CustomCommandData) => { if (e.parameter == undefined) { // do nothing - } else if ("PROTOTYPES" == e.parameter.toUpperCase()) { + } else if ("PROTOTYPES" == e.parameter.toUpperCase()) { emitPrototypes() + } else if ("CURRENT_CHUNK" == e.parameter.toUpperCase()) { + + if (e.player_index != undefined) { + + let player = game.players[e.player_index] + + let chunkPosition: ChunkPosition = { + x: floor(player.position.x / 32), + y: floor(player.position.y / 32), + } + + let chunkLeftTop: Position = { + x: chunkPosition.x * 32, + y: chunkPosition.y * 32, + } + let chunkBottomRight: Position = { + x: chunkLeftTop.x + 32 - 1, + y: chunkLeftTop.y + 32 - 1, + } + let chunkArea: BoundingBoxRead = { + left_top: chunkLeftTop, + right_bottom: chunkBottomRight + } + + handleChunkUpdate( + e.tick, + "player-command", + player.surface.index, + chunkPosition, + chunkArea, + ) + } + } else if ("CHUNKS" == e.parameter.toUpperCase()) { + + for (let [, surface] of game.surfaces) { + for (let chunk of surface.get_chunks()) { + if ( + (chunk.x >= -16 || chunk.x <= 16) + && + (chunk.y >= -16 || chunk.y <= 16) + ) { + handleChunkUpdate( + e.tick, + "player-command", + surface.index, + chunk, + chunk.area, + ) + } + } + } } - }) + } +) diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index 26f2e8f..4468bac 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -48,7 +48,7 @@ script.on_event( script.on_event( defines.events.on_tick, (e: OnTickEvent) => { - if (e.tick % 60 == 0) { + if (e.tick % 1000 == 0) { for (const [, surface] of pairs(game.surfaces)) { handleSurfaceUpdate(e.tick, mapEventIdToName.get(e.name), surface) } diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index 29a486e..5d7dc4f 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.4", + "version": "0.2.6", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -24,9 +24,9 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" }, "has": { "version": "1.0.3", @@ -37,9 +37,9 @@ } }, "is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", "requires": { "has": "^1.0.3" } @@ -55,12 +55,13 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "version": "1.21.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.1.tgz", + "integrity": "sha512-lfEImVbnolPuaSZuLQ52cAxPBHeI77sPwCOWRdy12UG/CNa8an7oBHH1R+Fp1/mUqSJi4c8TIP6FOIPSZAUrEQ==", "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "is-core-module": "^2.8.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, "source-map": { @@ -68,15 +69,20 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, "tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.16.0.tgz", - "integrity": "sha512-I6W1lhRkeE+mHzLBKBVIDZdquwBjBYaS7jkV0CKiWWkA9ptGqT+MblOkNUdYZ0ykR2Rvn1eF/6pzh8WwQ+mYVQ==" + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.17.0.tgz", + "integrity": "sha512-sFLQn+G/X0IROUBnlPwuIKQlvU561dckdI59WnRaClDRK1o8zyUEJRuJ4R+IJovKUd+I75xuoSdYVIWEwZoeHA==" }, "typescript": { "version": "4.5.4", @@ -84,9 +90,9 @@ "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==" }, "typescript-to-lua": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.3.0.tgz", - "integrity": "sha512-hFjZ7+Cv08WUql2VJChOEb1JH2nqYspyjw+9Og0cDLkP0QaEmM+Eh/slO2exdngDyQye/rrQysLy3zVzJe+PVg==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.3.3.tgz", + "integrity": "sha512-Fkt0+dLufN5CK0G/qpINY7Sb0+SNmWpov+PHhO/dq0HFoNBzR47M1SJd+hQbG92vTVFLBO4f+Np29LuVvoemMA==", "requires": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 7d2945b..b4993c8 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.4", + "version": "0.2.6", "private": true, "scripts": { "build": "tstl", @@ -13,8 +13,8 @@ "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", - "typescript-to-lua": "1.3.0", - "typed-factorio": "0.16.0", + "typescript-to-lua": "1.3.3", + "typed-factorio": "0.17.0", "typescript": "4.5.4" }, "license": "UNLICENSED", diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 2c6cb9f..491230d 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -26,6 +26,7 @@ dependencies { implementation(platform(libs.kotlinx.serialization.bom)) implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.json) + implementation("org.jetbrains.kotlinx:kotlinx-serialization-protobuf") implementation(libs.kotlinx.coroutines) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt index 845a7c3..1152dcc 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt @@ -2,11 +2,13 @@ package dev.adamko.kafkatorio.admin import dev.adamko.kafkatorio.events.schema.FactorioObjectData import dev.adamko.kafkatorio.events.schema.KafkatorioPacket +import dev.adamko.kafkatorio.processor.KafkatorioTopology import java.util.concurrent.TimeUnit import mu.KotlinLogging import org.apache.kafka.clients.admin.Admin import org.apache.kafka.clients.admin.CreateTopicsResult import org.apache.kafka.clients.admin.NewTopic +import org.apache.kafka.clients.admin.TopicListing private val logger = KotlinLogging.logger {} @@ -29,7 +31,7 @@ object CreateTopics { KafkatorioPacket.PacketType.values().forEach { packetType -> val kafkatorioTopics = buildSet { -// add(KafkatorioTopology.sourceTopic) + add(KafkatorioTopology.sourceTopic) when (packetType) { KafkatorioPacket.PacketType.EVENT -> FactorioObjectData.ObjectName.values().forEach { objectName -> @@ -41,7 +43,11 @@ object CreateTopics { add("kafkatorio.${packetType.name}.all") } } + + val currentTopics = currentTopics().map { it.name() } + val result = kafkatorioTopics + .filterNot { it in currentTopics } .run { logger.info("Creating $size topics") kafkaAdmin.createTopics { this } @@ -68,10 +74,18 @@ object CreateTopics { private fun Admin.createTopics( numPartitions: Int = 10, - replicationFactor: Short = 5, + replicationFactor: Short = 1, topicNames: () -> Collection, ): CreateTopicsResult = - createTopics(topicNames().distinct().map { - NewTopic(it, numPartitions, replicationFactor) - }) + createTopics(topicNames() + .distinct() + .map { + NewTopic(it, numPartitions, replicationFactor) + }) + + private fun currentTopics(): MutableCollection { + return kafkaAdmin.listTopics() + .listings() + .get() + } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 96cea83..0a68437 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -1,9 +1,9 @@ package dev.adamko.kafkatorio.processor import dev.adamko.kafkatorio.events.schema.MapTile -import dev.adamko.kafkatorio.events.schema.MapTilePosition import dev.adamko.kafkatorio.events.schema.MapTilePrototype import dev.adamko.kafkatorio.processor.topology.PrototypeName +import dev.adamko.kafkatorio.processor.topology.TileUpdateRecordKey import dev.adamko.kafkatorio.processor.topology.WebMapTileChunkPixels import dev.adamko.kafkatorio.processor.topology.WebMapTileChunkPosition import dev.adamko.kafkatorio.processor.topology.aggregateWebMapTiles @@ -33,7 +33,7 @@ class KafkatorioTopology( splitFactorioServerLog(builder) playerUpdatesToWsServer(websocketServer, builder) - val allMapTilesTable: KTable = allMapTilesTable(builder) + val allMapTilesTable: KTable = allMapTilesTable(builder) val tilePrototypesTable: KTable = prototypesTable(builder) val webMapTiles: KTable = diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt new file mode 100644 index 0000000..0c0a66f --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt @@ -0,0 +1,105 @@ +package dev.adamko.kafkatorio.processor.serdes + +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.DataInput +import java.io.DataInputStream +import java.io.DataOutput +import java.io.DataOutputStream +import java.util.zip.DeflaterOutputStream +import kotlinx.serialization.BinaryFormat +import kotlinx.serialization.DeserializationStrategy +import kotlinx.serialization.SerializationStrategy +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.AbstractDecoder +import kotlinx.serialization.encoding.AbstractEncoder +import kotlinx.serialization.encoding.CompositeDecoder +import kotlinx.serialization.encoding.CompositeEncoder +import kotlinx.serialization.modules.EmptySerializersModule +import kotlinx.serialization.modules.SerializersModule + + +val kxsBinaryMapper: KxsBinary = KxsBinary() + +/** [`https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/formats.md#efficient-binary-format`](https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/formats.md#efficient-binary-format) */ +class KxsBinary( + override val serializersModule: SerializersModule = EmptySerializersModule +) : BinaryFormat { + + override fun encodeToByteArray(serializer: SerializationStrategy, value: T): ByteArray { + val output = ByteArrayOutputStream() + val encoder = KxsDataOutputEncoder(DataOutputStream(output), serializersModule) + encoder.encodeSerializableValue(serializer, value) + return output.toByteArray() + } + + override fun decodeFromByteArray( + deserializer: DeserializationStrategy, + bytes: ByteArray + ): T { + val input = ByteArrayInputStream(bytes) + val decoder = KxsDataInputDecoder(DataInputStream(input), serializersModule) + return decoder.decodeSerializableValue(deserializer) + } +} + +class KxsDataOutputEncoder( + private val output: DataOutput, + override val serializersModule: SerializersModule = EmptySerializersModule, +) : AbstractEncoder() { + + override fun encodeBoolean(value: Boolean) = output.writeByte(if (value) 1 else 0) + override fun encodeByte(value: Byte) = output.writeByte(value.toInt()) + override fun encodeShort(value: Short) = output.writeShort(value.toInt()) + override fun encodeInt(value: Int) = output.writeInt(value) + override fun encodeLong(value: Long) = output.writeLong(value) + override fun encodeFloat(value: Float) = output.writeFloat(value) + override fun encodeDouble(value: Double) = output.writeDouble(value) + override fun encodeChar(value: Char) = output.writeChar(value.code) + override fun encodeString(value: String) = output.writeUTF(value) + override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) = output.writeInt(index) + + override fun beginCollection( + descriptor: SerialDescriptor, + collectionSize: Int + ): CompositeEncoder { + encodeInt(collectionSize) + return this + } + + override fun encodeNull() = encodeBoolean(false) + override fun encodeNotNullMark() = encodeBoolean(true) +} + +class KxsDataInputDecoder( + private val input: DataInput, + override val serializersModule: SerializersModule = EmptySerializersModule, + var elementsCount: Int = 0, +) : AbstractDecoder() { + private var elementIndex = 0 + override fun decodeBoolean(): Boolean = input.readByte().toInt() != 0 + override fun decodeByte(): Byte = input.readByte() + override fun decodeShort(): Short = input.readShort() + override fun decodeInt(): Int = input.readInt() + override fun decodeLong(): Long = input.readLong() + override fun decodeFloat(): Float = input.readFloat() + override fun decodeDouble(): Double = input.readDouble() + override fun decodeChar(): Char = input.readChar() + override fun decodeString(): String = input.readUTF() + override fun decodeEnum(enumDescriptor: SerialDescriptor): Int = input.readInt() + + override fun decodeElementIndex(descriptor: SerialDescriptor): Int { + if (elementIndex == elementsCount) return CompositeDecoder.DECODE_DONE + return elementIndex++ + } + + override fun beginStructure(descriptor: SerialDescriptor): CompositeDecoder = + KxsDataInputDecoder(input, serializersModule, descriptor.elementsCount) + + override fun decodeSequentially(): Boolean = true + + override fun decodeCollectionSize(descriptor: SerialDescriptor): Int = + decodeInt().also { elementsCount = it } + + override fun decodeNotNullMark(): Boolean = decodeBoolean() +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt similarity index 96% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt index e178d78..4cb82b9 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.processor +package dev.adamko.kafkatorio.processor.serdes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.events.schema.jsonMapperKafkatorio diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/protobuf.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/protobuf.kt new file mode 100644 index 0000000..527121f --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/protobuf.kt @@ -0,0 +1,59 @@ +package dev.adamko.kafkatorio.processor.serdes + +import dev.adamko.kafkatorio.events.schema.jsonMapperKafkatorio +import kotlinx.serialization.BinaryFormat +import kotlinx.serialization.decodeFromByteArray +import kotlinx.serialization.encodeToByteArray +import kotlinx.serialization.protobuf.ProtoBuf +import org.apache.kafka.common.serialization.Deserializer +import org.apache.kafka.common.serialization.Serde +import org.apache.kafka.common.serialization.Serializer + +val protoMapper: ProtoBuf = ProtoBuf { + serializersModule = jsonMapperKafkatorio.serializersModule +} + + +inline fun BinaryFormat.kafkaSerializer() = + Serializer { topic: String, data: T -> + runCatching { + encodeToByteArray(data) + }.getOrElse { e -> + println( + """ + Exception on encodeToString + Topic: $topic + topicData: $data + topicData as T: $data + """.trimIndent() + ) + e.printStackTrace() + throw e + } + } + +inline fun BinaryFormat.kafkaDeserializer() = + Deserializer { topic: String, data: ByteArray -> + runCatching { + decodeFromByteArray(data) + }.getOrElse { e -> + println( + """ + Exception on decodeFromString, + Topic: $topic + topicData: $data + topicData as T: ${data as? T} + """.trimIndent() + ) + e.printStackTrace() + throw e + } + } + +inline fun ProtoBuf.serde() = object : Serde { + + override fun serializer(): Serializer = kafkaSerializer() + + override fun deserializer(): Deserializer = kafkaDeserializer() + +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioServerState.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioServerState.kt index 48a80b0..a2f6045 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioServerState.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioServerState.kt @@ -1,16 +1,16 @@ package dev.adamko.kafkatorio.processor.topology -import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -import dev.adamko.kafkatorio.events.schema.MapChunkPosition -import dev.adamko.kafkatorio.events.schema.MapTilePosition -import dev.adamko.kafkatorio.events.schema.MapTilePrototype -import dev.adamko.kafkatorio.processor.jsonMapper +//import dev.adamko.kafkatorio.events.schema.KafkatorioPacket +//import dev.adamko.kafkatorio.events.schema.MapChunkPosition +//import dev.adamko.kafkatorio.events.schema.MapTilePosition +//import dev.adamko.kafkatorio.events.schema.MapTilePrototype +//import dev.adamko.kafkatorio.processor.serdes.jsonMapper import kotlinx.serialization.Serializable -import kotlinx.serialization.decodeFromString -import org.apache.kafka.common.serialization.Serdes -import org.apache.kafka.streams.StreamsBuilder -import org.apache.kafka.streams.kstream.Consumed -import org.apache.kafka.streams.kstream.KGroupedStream +//import kotlinx.serialization.decodeFromString +//import org.apache.kafka.common.serialization.Serdes +//import org.apache.kafka.streams.StreamsBuilder +//import org.apache.kafka.streams.kstream.Consumed +//import org.apache.kafka.streams.kstream.KGroupedStream private const val sourceTopic = "factorio-server-log" @@ -20,55 +20,55 @@ value class FactorioServerId(val id: String) { override fun toString() = id } -@Serializable -data class FactorioServerState( - val serverId: FactorioServerId, - val mapTilePrototypes: Set, - val surfaceIndexes: Set, -) - - -private fun gatherGameState(builder: StreamsBuilder = StreamsBuilder()) { - - val serverPackets: KGroupedStream = - builder.stream( - sourceTopic, - Consumed.with(Serdes.String(), Serdes.String()) - ) - .mapValues { readOnlyKey, value -> - println("Mapping $readOnlyKey:$value") - jsonMapper.decodeFromString(value) - } - .groupByKey() - - @Serializable - data class TileSurfaceData( - val surfaceIndex: Int, - val position: MapTilePosition, - val prototype: MapTilePrototype, - ) - - @Serializable - data class MapChunkData( - val position: MapChunkPosition, - val tiles: List, - ) - - @Serializable - data class FactorioSurfaceData( - val surfaceIndex: Int, - val chunks: List, - ) - - @Serializable - data class FactorioServerState( - val surfaces: Map, - val tilePrototypes: List, - ) - - -// serverPackets -// .aggregate( -// Initializer { FactorioServerState("", emptyMap(), emptyList()) } -// ) -} +//@Serializable +//data class FactorioServerState( +// val serverId: FactorioServerId, +// val mapTilePrototypes: Set, +// val surfaceIndexes: Set, +//) +// +// +//private fun gatherGameState(builder: StreamsBuilder = StreamsBuilder()) { +// +// val serverPackets: KGroupedStream = +// builder.stream( +// sourceTopic, +// Consumed.with(Serdes.String(), Serdes.String()) +// ) +// .mapValues { readOnlyKey, value -> +// println("Mapping $readOnlyKey:$value") +// jsonMapper.decodeFromString(value) +// } +// .groupByKey() +// +// @Serializable +// data class TileSurfaceData( +// val surfaceIndex: Int, +// val position: MapTilePosition, +// val prototype: MapTilePrototype, +// ) +// +// @Serializable +// data class MapChunkData( +// val position: MapChunkPosition, +// val tiles: List, +// ) +// +// @Serializable +// data class FactorioSurfaceData( +// val surfaceIndex: Int, +// val chunks: List, +// ) +// +// @Serializable +// data class FactorioServerState( +// val surfaces: Map, +// val tilePrototypes: List, +// ) +// +// +//// serverPackets +//// .aggregate( +//// Initializer { FactorioServerState("", emptyMap(), emptyList()) } +//// ) +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt index de01bd0..30ed815 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt @@ -7,7 +7,7 @@ import dev.adamko.kafkatorio.events.schema.MapChunk import dev.adamko.kafkatorio.events.schema.MapTile import dev.adamko.kafkatorio.events.schema.MapTilePosition import dev.adamko.kafkatorio.events.schema.MapTiles -import dev.adamko.kafkatorio.processor.jsonMapper +import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.streams.filter @@ -17,12 +17,12 @@ import dev.adamko.kotka.extensions.streams.toTable import dev.adamko.kotka.kxs.serde import java.time.Duration import kotlinx.serialization.Serializable -import org.apache.kafka.common.serialization.Serdes import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.kstream.KStream import org.apache.kafka.streams.kstream.KTable import org.apache.kafka.streams.kstream.Suppressed + @Serializable data class TileUpdateRecordKey( val surfaceIndex: SurfaceIndex, @@ -32,26 +32,42 @@ data class TileUpdateRecordKey( fun allMapTilesTable( builder: StreamsBuilder -): KTable { +): KTable { - val luaTilesUpdatesStream: KStream = builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", - consumedAs("consume-map-tiles-packets", Serdes.String(), jsonMapper.serde()) - ) - .filter("events.filter.map-tiles") { _: String, event: FactorioEvent -> event.data is MapTiles } - .mapValues("events.extract-map-tiles") { _, event: FactorioEvent -> (event.data as? MapTiles)!! } + val luaTilesUpdatesStream: KStream = + builder.stream( + "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", + consumedAs("consume-map-tiles-packets", jsonMapper.serde(), jsonMapper.serde()) + ) + .filter("events.filter.map-tiles") { _: FactorioPacketKey, event: FactorioEvent -> + event.data is MapTiles + } + .mapValues("events.extract-map-tiles") { _, event: FactorioEvent -> + (event.data as? MapTiles)!! + } - val chunkTilesUpdateStream: KStream = builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", - consumedAs("consume-map-chunk-packets", Serdes.String(), jsonMapper.serde()) - ) - .filter("events.filter.map-chunks") { _: String, event: FactorioEvent -> event.data is MapChunk } - .mapValues("events.extract-map-chunks") { _, event: FactorioEvent -> (event.data as? MapChunk)!!.tiles } + val chunkTilesUpdateStream: KStream = + builder.stream( + "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", + consumedAs("consume-map-chunk-packets", jsonMapper.serde(), jsonMapper.serde()) + ) + .filter("events.filter.map-chunks") { _: FactorioPacketKey, event: FactorioEvent -> + event.data is MapChunk + } + .mapValues("events.extract-map-chunks") { _, event: FactorioEvent -> + (event.data as? MapChunk)!!.tiles + } return luaTilesUpdatesStream .merge(chunkTilesUpdateStream) .flatMap("flat-map-all-tiles") { _, value -> - value.tiles.map { it.position to it } + value.tiles.map { tile -> + val key = TileUpdateRecordKey( + SurfaceIndex(value.surfaceIndex), + tile.position + ) + key to tile + } } .toTable( "all-tiles-keyed-on-position", @@ -66,21 +82,3 @@ fun allMapTilesTable( ) ) } - -//fun buildTilesTable( -// builder: StreamsBuilder -//): KTable { -// -// return luaTilesUpdatesStream -// .merge("luaTilesUpdatesStream-and-chunkTilesUpdateStream", chunkTilesUpdateStream) -// .flatMapTopicRecords("all-tiles-convert-to-TileUpdateRecord") { _, mapTiles: MapTiles -> -// mapTiles.tiles.map { tile -> -// TileUpdateRecord( -// SurfaceIndex(mapTiles.surfaceIndex), -// tile.position, -// tile, -// ) -// } -// } -// .toTable(materializedWith(jsonMapper.serde(), jsonMapper.serde())) -//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt index d071ad2..17fbcf1 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt @@ -1,22 +1,39 @@ package dev.adamko.kafkatorio.processor.topology +import dev.adamko.kafkatorio.events.schema.ConsoleChatMessage +import dev.adamko.kafkatorio.events.schema.EntityData import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate import dev.adamko.kafkatorio.events.schema.FactorioEvent import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -import dev.adamko.kafkatorio.processor.KafkatorioPacketSerde +import dev.adamko.kafkatorio.events.schema.MapChunk +import dev.adamko.kafkatorio.events.schema.MapTile +import dev.adamko.kafkatorio.events.schema.MapTiles +import dev.adamko.kafkatorio.events.schema.PlayerData +import dev.adamko.kafkatorio.events.schema.SurfaceData +import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition +import dev.adamko.kafkatorio.processor.serdes.KafkatorioPacketSerde import dev.adamko.kafkatorio.processor.KafkatorioTopology -import dev.adamko.kafkatorio.processor.jsonMapper +import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.producedAs -import dev.adamko.kotka.extensions.streams.mapValues +import dev.adamko.kotka.extensions.streams.map import dev.adamko.kotka.extensions.streams.to +import dev.adamko.kotka.kxs.serde +import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString import org.apache.kafka.common.serialization.Serdes import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.processor.RecordContext +@Serializable +data class FactorioPacketKey( + val serverId: FactorioServerId, + /** arbitrary distinctive key */ + val key: String, +) + fun splitFactorioServerLog( builder: StreamsBuilder = StreamsBuilder(), ) { @@ -29,17 +46,19 @@ fun splitFactorioServerLog( Serdes.String(), ) ) - .mapValues("decode-packets") { _: String, value: String -> + .map("decode-packets") { serverId: String, value: String -> // println("Mapping $readOnlyKey:$value") - jsonMapper.decodeFromString(value) + val packet = jsonMapper.decodeFromString(value) + val key: String = createPacketKey(packet) + FactorioPacketKey(FactorioServerId(serverId), key) to packet } .to( producedAs( "split-server-log", - Serdes.String(), + jsonMapper.serde(), KafkatorioPacketSerde ) - ) { _: String, value: KafkatorioPacket, _: RecordContext -> + ) { _: FactorioPacketKey, value: KafkatorioPacket, _: RecordContext -> // println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") when (value) { is FactorioEvent -> @@ -52,3 +71,26 @@ fun splitFactorioServerLog( } } + +private fun createPacketKey(packet: KafkatorioPacket): String { + + return when (packet) { + is FactorioEvent -> factorioEventKey(packet) + is FactorioConfigurationUpdate, + is FactorioPrototypes -> packet.hashCode().toString() + } +} + +private fun factorioEventKey(event: FactorioEvent): String { + val id: String = when (val data = event.data) { + is ConsoleChatMessage -> data.authorPlayerIndex?.toString() + is EntityData -> data.type + is MapChunk -> data.position.toString() + is MapTile -> data.position.toString() + is MapTiles -> data.tiles.firstOrNull()?.position?.toMapChunkPosition()?.toString() + is PlayerData -> (data.characterUnitNumber?.toString() ?: data.name) + is SurfaceData -> data.index.toString() + } ?: event.tick.toString() + + return id +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt index 1ba0d5c..58a3a8f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt @@ -3,8 +3,9 @@ package dev.adamko.kafkatorio.processor.topology import kotlinx.serialization.Serializable @Serializable -data class SurfaceIndex( - val surfaceIndex: Int +@JvmInline +value class SurfaceIndex( + val index: Int ) { - override fun toString() = "$surfaceIndex" + override fun toString() = "$index" } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt index da1838c..86f24d7 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt @@ -2,9 +2,9 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.events.schema.FactorioObjectData import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -import dev.adamko.kafkatorio.processor.KafkatorioPacketSerde +import dev.adamko.kafkatorio.processor.serdes.KafkatorioPacketSerde import dev.adamko.kafkatorio.processor.WebsocketServer -import dev.adamko.kafkatorio.processor.jsonMapper +import dev.adamko.kafkatorio.processor.serdes.jsonMapper import kotlinx.serialization.encodeToString import org.apache.kafka.common.serialization.Serdes import org.apache.kafka.streams.StreamsBuilder diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index a09c5b7..3f44473 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -3,12 +3,10 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.events.schema.MapTilePrototype -import dev.adamko.kafkatorio.processor.jsonMapper +import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kotka.extensions.consumedAs -//import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.streams.flatMap -//import dev.adamko.kotka.extensions.streams.* import dev.adamko.kotka.kxs.serde import kotlinx.serialization.Serializable import org.apache.kafka.common.serialization.Serdes diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt index 954a46c..c1f04fd 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt @@ -5,7 +5,7 @@ import dev.adamko.kafkatorio.events.schema.MapTile import dev.adamko.kafkatorio.events.schema.MapTilePosition import dev.adamko.kafkatorio.events.schema.MapTilePrototype import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition -import dev.adamko.kafkatorio.processor.jsonMapper +import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.namedAs @@ -19,26 +19,16 @@ import kotlinx.serialization.Serializable import org.apache.kafka.streams.kstream.KTable import org.apache.kafka.streams.kstream.Suppressed -/** The tiles of the webmap will be this many pixels high/wide */ -const val WEB_MAP_IMAGE_TILE_SIZE = 32 -//@Serializable -//data class MapChunkDataPosition( -// val position: MapChunkPosition, -// val surfaceIndex: SurfaceIndex, -//) -// -//@Serializable -//data class MapChunkData( -// val chunkPosition: MapChunkDataPosition, -// val tiles: Set, -//) +/** The tiles of the webmap will be this many pixels high/wide */ +const val WEB_MAP_IMAGE_TILE_SIZE = 256 @Serializable data class WebMapTileChunkPosition( val chunkSize: Int, val x: Int, val y: Int, + val surfaceIndex: SurfaceIndex, ) @Serializable @@ -59,11 +49,11 @@ private data class WebMapTileChunkPixelsAcc( ) fun aggregateWebMapTiles( - allMapTilesTable: KTable, + allMapTilesTable: KTable, tilePrototypesTable: KTable, ): KTable { - val webmapTileColours: KTable = + val webmapTileColours: KTable = allMapTilesTable .join( tilePrototypesTable, @@ -87,9 +77,14 @@ fun aggregateWebMapTiles( jsonMapper.serde(), jsonMapper.serde(), ) - ) { pos: MapTilePosition, px: WebMapTilePixel -> - val (chunkX, chunkY) = pos.toMapChunkPosition(WEB_MAP_IMAGE_TILE_SIZE) - val chunkPos = WebMapTileChunkPosition(WEB_MAP_IMAGE_TILE_SIZE, chunkX, chunkY) + ) { pos: TileUpdateRecordKey, px: WebMapTilePixel -> + val (chunkX, chunkY) = pos.tilePosition.toMapChunkPosition(WEB_MAP_IMAGE_TILE_SIZE) + val chunkPos = WebMapTileChunkPosition( + WEB_MAP_IMAGE_TILE_SIZE, + chunkX, + chunkY, + pos.surfaceIndex + ) (chunkPos to px).toKeyValue() } .aggregate( @@ -103,7 +98,11 @@ fun aggregateWebMapTiles( acc.apply { pixels.minus(oldValue) } }, namedAs("web-map-tile-colours-into-$WEB_MAP_IMAGE_TILE_SIZE-chunks"), - materializedAs("web-map-tile-colour-chunks-aggregate", jsonMapper.serde(), jsonMapper.serde()) + materializedAs( + "web-map-tile-colour-chunks-aggregate", + jsonMapper.serde(), + jsonMapper.serde() + ) ) .suppress( Suppressed.untilTimeLimit( diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt index 5d8b231..0ffc2b0 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt @@ -3,7 +3,6 @@ package dev.adamko.kafkatorio.processor.topology import com.sksamuel.scrimage.ImmutableImage import com.sksamuel.scrimage.color.RGBColor import com.sksamuel.scrimage.nio.PngWriter -import dev.adamko.kafkatorio.events.schema.MAP_CHUNK_SIZE import dev.adamko.kotka.extensions.tables.toStream import java.awt.Color import java.awt.image.BufferedImage @@ -43,15 +42,14 @@ private fun saveMapTilesPng( chunkPosition: WebMapTileChunkPosition, pixels: Set ) { - val surfaceIndex = 1 // TODO get surface index - - val chunkOriginX = chunkPosition.x * chunkPosition.chunkSize - val chunkOriginY = chunkPosition.y * chunkPosition.chunkSize + val chunkOriginX: Int = chunkPosition.x * chunkPosition.chunkSize + val chunkOriginY: Int = chunkPosition.y * chunkPosition.chunkSize + val surfaceIndex: Int = chunkPosition.surfaceIndex.index val chunkImage = ImmutableImage.filled( - MAP_CHUNK_SIZE, - MAP_CHUNK_SIZE, + chunkPosition.chunkSize, + chunkPosition.chunkSize, Color.BLACK, BufferedImage.TYPE_INT_ARGB ) @@ -79,7 +77,7 @@ private fun saveMapTilesPng( val zoom = 1u val file = File( - "src/main/resources/kafkatorio-web-map/s${surfaceIndex}/z$zoom/x${chunkOriginX}/y${chunkOriginY}.png" + "src/main/resources/kafkatorio-web-map/s${surfaceIndex}/z$zoom/x${chunkPosition.x}/y${chunkPosition.y}.png" ) if (file.parentFile.mkdirs()) { diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index c8f48e4..129db2a 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -FACTORIO_VERSION=1.1.50 -KAFKATORIO_VERSION=0.2.4 +FACTORIO_VERSION=1.1.53 +KAFKATORIO_VERSION=0.2.6 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index 363e10c..afa5814 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.2.4 +KAFKATORIO_VERSION=0.2.6 diff --git a/modules/infra-kafka-cluster/src/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml index c95fa8e..e05f8c9 100644 --- a/modules/infra-kafka-cluster/src/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -11,7 +11,7 @@ services: context: "." target: "kafka-kraft" args: - KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/3.0.0/kafka_2.13-3.0.0.tgz" + KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/3.1.0/kafka_2.13-3.1.0.tgz" networks: - "kafka-nw" - "kafkatorio-nw" @@ -20,7 +20,7 @@ services: - "9093:9093" kafka-ui: - image: provectuslabs/kafka-ui:0.3.1 + image: provectuslabs/kafka-ui:0.3.2 container_name: "kafka-ui" restart: "unless-stopped" networks: diff --git a/modules/infra-kafka-cluster/src/kafka-server.properties b/modules/infra-kafka-cluster/src/kafka-server.properties index 70ebc99..3f7c92c 100644 --- a/modules/infra-kafka-cluster/src/kafka-server.properties +++ b/modules/infra-kafka-cluster/src/kafka-server.properties @@ -1,22 +1,5 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# # This configuration file is intended for use in KRaft mode, where # Apache ZooKeeper is not present. See config/kraft/README.md for details. -# ############################# Server Basics ############################# @@ -83,7 +66,7 @@ log.dirs=/tmp/kraft-combined-logs # The default number of log partitions per topic. More partitions allow greater # parallelism for consumption, but this will also result in more files across # the brokers. -num.partitions=1 +num.partitions=3 # The number of threads per data directory to be used for log recovery at startup and flushing at shutdown. # This value is recommended to be increased for installations with data dirs located in RAID array. @@ -133,3 +116,7 @@ log.segment.bytes=1073741824 # The interval at which log segments are checked to see if they can be deleted according # to the retention policies log.retention.check.interval.ms=300000 + +### Compression ### +#compression.type=snappy +#linger.ms=5 diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index 363e10c..afa5814 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.2.4 +KAFKATORIO_VERSION=0.2.6 diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index f29c4a2..ff73df7 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -33,9 +33,10 @@ fun createFactorioMap() = Maps { """http://localhost:9073/tiles/s1/z{z}/x{x}/y{y}.png""" ) { attribution = "kafkatorio" +// tileSize = 256 tms = true - minZoom = -2 - maxZoom = 1 +// minZoom = -2 +// maxZoom = 1 maxNativeZoom = 1 minNativeZoom = 1 }.addTo(this) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt index 36c8a7c..2030fe5 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -4,9 +4,11 @@ import dev.adamko.kafkatorio.events.schema.ConsoleChatMessage import dev.adamko.kafkatorio.events.schema.EntityData import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.events.schema.MapChunk import dev.adamko.kafkatorio.events.schema.MapTile +import dev.adamko.kafkatorio.events.schema.MapTiles import dev.adamko.kafkatorio.events.schema.PlayerData import dev.adamko.kafkatorio.events.schema.SurfaceData import io.kvision.redux.ReduxStore @@ -37,18 +39,22 @@ class WebsocketService( println(data.replace('\n', ' ')) when (val event: KafkatorioPacket = jsonMapper.decodeFromString(data)) { - is FactorioEvent -> { + is FactorioEvent -> { when (val eventData = event.data) { - is PlayerData -> + is PlayerData -> reduxStore.dispatch(FactorioUpdate.PlayerUpdate(event, eventData)) - is ConsoleChatMessage -> {} - is EntityData -> {} - is MapChunk -> {} - is MapTile -> {} - is SurfaceData -> {} + is ConsoleChatMessage, + is EntityData, + is MapChunk, + is MapTile, + is SurfaceData, + is MapTiles -> { + } } } - is FactorioConfigurationUpdate -> {} + is FactorioConfigurationUpdate, + is FactorioPrototypes -> { + } } } else { From 678cf5504e42bece30d7fb6e994846ea6bdb0cf7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 23 Jan 2022 13:50:21 +0100 Subject: [PATCH 163/629] hack together some sort of queue to help stop the chunk updates overloading the server. It doesn't work too well I think... --- .../events-mod/src/main/typescript/control.ts | 7 + .../main/commands/kafkatorioCommands.ts | 59 ++++++--- .../handleConfigurationUpdate.ts | 2 + .../typescript/main/emitKafkatorioPacket.ts | 1 + .../main/typescript/main/events/emitEvent.ts | 3 - .../main/typescript/main/events/handlers.ts | 6 - .../main/events/registerHandlers.ts | 48 ++++++- .../src/main/typescript/main/queue/queue.ts | 124 ++++++++++++++++++ .../src/main/typescript/package-lock.json | 2 +- .../src/main/typescript/package.json | 2 +- .../src/main/typescript/tsconfig.json | 4 +- 11 files changed, 228 insertions(+), 30 deletions(-) create mode 100644 modules/events-mod/src/main/typescript/main/queue/queue.ts diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index d179872..df1cacc 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -1,6 +1,13 @@ import {handleConfigurationUpdate} from "./main/config-update/handleConfigurationUpdate"; +import {emitPrototypes} from "./main/config-update/prototypes"; +import {Queue} from "./main/queue/queue"; require("./main/events/registerHandlers") require("./main/commands/kafkatorioCommands") script.on_configuration_changed(handleConfigurationUpdate) + +script.on_init(() => { + Queue.reset() + emitPrototypes() +}) diff --git a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts index 20b692a..c1ecb3b 100644 --- a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts +++ b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts @@ -1,7 +1,9 @@ import {emitPrototypes} from "../config-update/prototypes"; import {handleChunkUpdate} from "../events/handlers"; +import {Queue} from "../queue/queue"; import floor = math.floor; + commands.add_command( "kafkatorio", "kafkatorio innit bruv", @@ -36,7 +38,7 @@ commands.add_command( handleChunkUpdate( e.tick, - "player-command", + "player-command-" + e.parameter, player.surface.index, chunkPosition, chunkArea, @@ -44,23 +46,50 @@ commands.add_command( } } else if ("CHUNKS" == e.parameter.toUpperCase()) { - for (let [, surface] of game.surfaces) { - for (let chunk of surface.get_chunks()) { - if ( - (chunk.x >= -16 || chunk.x <= 16) - && - (chunk.y >= -16 || chunk.y <= 16) - ) { - handleChunkUpdate( - e.tick, - "player-command", - surface.index, - chunk, - chunk.area, - ) + if (e.player_index != undefined) { + let player = game.players[e.player_index] + + let chunkPosition: ChunkPosition = { + x: floor(player.position.x / 32), + y: floor(player.position.y / 32), + } + + let delta = 1 + + let chunkXMin = chunkPosition.x - delta + let chunkXMax = chunkPosition.x + delta + let chunkYMin = chunkPosition.y - delta + let chunkYMax = chunkPosition.y + delta + + for (let [, surface] of game.surfaces) { + for (let chunk of surface.get_chunks()) { + if ( + (chunk.x >= chunkXMin || chunk.x <= chunkXMax) + && + (chunk.y >= chunkYMin || chunk.y <= chunkYMax) + ) { + + let data: OnChunkGeneratedEvent = { + name: defines.events.on_chunk_generated, + position: {x: chunk.x, y: chunk.y}, + area: chunk.area, + surface: surface, + tick: e.tick + } + + Queue.enqueue( + `${surface.index}${chunk.x}${chunk.y}`, + data, + 50 + ) + } } } } + } else if ("QUEUE_RESET" == e.parameter.toUpperCase()) { + Queue.reset() + } else if ("QUEUE_INIT" == e.parameter.toUpperCase()) { + Queue.init() } } ) diff --git a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts index 2d58bbd..8bb456f 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts @@ -1,6 +1,7 @@ import {emitPacket} from "../emitKafkatorioPacket"; import {updateGlobal} from "./updateGlobal"; import {emitPrototypes} from "./prototypes"; +import {Queue} from "../queue/queue"; export function handleConfigurationUpdate(changeData: ConfigurationChangedData) { updateGlobal() @@ -12,6 +13,7 @@ export function handleConfigurationUpdate(changeData: ConfigurationChangedData) factorioData: factorioData(changeData) }) + Queue.reset() emitPrototypes() } diff --git a/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts b/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts index c86af5d..fcaa92f 100644 --- a/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts +++ b/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts @@ -1,6 +1,7 @@ /** Emit a serialised KafkatorioPacket */ export function emitPacket(packet: T) { let data = game.table_to_json(packet) + // localised_print(`KafkatorioPacket: ${packet.packetType}`) localised_print(`KafkatorioPacket: ${data}`) // rcon.print(`KafkatorioPacket: ${data}`) } diff --git a/modules/events-mod/src/main/typescript/main/events/emitEvent.ts b/modules/events-mod/src/main/typescript/main/events/emitEvent.ts index 771b408..ab98b7f 100644 --- a/modules/events-mod/src/main/typescript/main/events/emitEvent.ts +++ b/modules/events-mod/src/main/typescript/main/events/emitEvent.ts @@ -1,6 +1,3 @@ -// const SERVER_ID: uint = 0 -// const EVENT_FILE_DIR: string = "events" - import {emitPacket} from "../emitKafkatorioPacket"; /** Emit a serialised event */ diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index a35da1b..1599367 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -1,12 +1,10 @@ import {Converters} from "./converters" import {emitEvent} from "./emitEvent"; - export function handlePlayerUpdate(tick: uint, eventType: string, playerIndex: uint) { let player: LuaPlayer = game.players[playerIndex] let table = Converters.playerToTable(player) - emitEvent(table, tick, eventType) handleCharactersEvent(tick, eventType, playerIndex) @@ -50,8 +48,6 @@ export function handleConsoleChat( emitEvent(table, tick, eventType) } -// const CHUNK_SIZE = 32 - export function handleChunkUpdate( tick: uint, eventType: string, @@ -64,8 +60,6 @@ export function handleChunkUpdate( let tiles: LuaTile[] = surface?.find_tiles_filtered({ area: area, - // position: {x: x, y: y}, - // radius: CHUNK_SIZE, collision_mask: ["ground-tile", "water-tile"] } ) ?? [] diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index 4468bac..c1dc0a4 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -6,13 +6,20 @@ import { handleSurfaceUpdate, handleTilesUpdate } from "./handlers"; +import {Queue} from "../queue/queue"; import on_player_built_tile = defines.events.on_player_built_tile; import on_robot_built_tile = defines.events.on_robot_built_tile; const mapEventIdToName = new LuaTable() -for (const [k, v] of pairs(defines.events)) { - mapEventIdToName.set(v, k) +for (const [eventName, eventId] of pairs(defines.events)) { + mapEventIdToName.set(eventId, eventName) +} + +const mapEventIdToDefinedType = new LuaTable, EventId>() +for (const [eventName, eventId] of pairs(defines.events)) { + let definedType = defines.events[eventName] + mapEventIdToDefinedType.set(eventId, definedType) } // script.on_event( @@ -34,6 +41,9 @@ script.on_event( script.on_event( defines.events.on_player_joined_game, (e: OnPlayerJoinedGameEvent) => { + + Queue.init() // TODO make Queue initialisation more stable, not dependent on events + handlePlayerUpdate(e.tick, mapEventIdToName.get(e.name), e.player_index) } ) @@ -52,6 +62,29 @@ script.on_event( for (const [, surface] of pairs(game.surfaces)) { handleSurfaceUpdate(e.tick, mapEventIdToName.get(e.name), surface) } + + // let packets = new KafkatorioPacketQueue().dequeueValues(1) + // for (const packet of packets) { + // emitPacket(packet) + // } + } + + if (e.tick % 30 == 0) { + let events: EventData[] = Queue.dequeueValues(1) + + if (events.length > 0) { + log(`[${e.tick}] dequed ${events.length} events, current size: ${Queue.size()}`) + + for (const event of events) { + + if (isEventType(event)) { + let eName = mapEventIdToName.get(event.name) + + log(`[${e.tick}] dequed event ${eName}`) + handleChunkUpdate(e.tick, eName, event.surface.index, event.position, event.area) + } + } + } } } ) @@ -82,3 +115,14 @@ script.on_event( ) } ) + + +function isEventType(e: EventData): e is E { + let id: EventId | string = e.name + if (typeof id === "string") { + return false + } else { + let name = mapEventIdToDefinedType.get(id) + return e.name == name + } +} diff --git a/modules/events-mod/src/main/typescript/main/queue/queue.ts b/modules/events-mod/src/main/typescript/main/queue/queue.ts new file mode 100644 index 0000000..693c4d1 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/queue/queue.ts @@ -0,0 +1,124 @@ +export namespace Queue { + + declare const global: { + store: EventQueueStore + + head: Node | null + tail: Node | null + + size: uint + } + + + export function init() { + if (global.store == undefined) { + log("initialising EventQueue") + reset() + } + } + + + export function reset() { + log("Resetting EventQueue") + global.store = {} + global.head = null + global.tail = null + global.size = 0 + } + + + export function size(): uint { + return global.size + } + + + export function enqueue(key: string, event: EventData, weight: int = 1) { + if (key ! in global.store) { + let node = new Node(key, weight) + if (global.head == null) { + global.head = node + } + if (global.tail != null) { + global.tail.next = node + } + global.tail = node + } + + global.store[key] = event + global.size++ + } + + + export function dequeue(): WeightedPacket | null { + if (global.head == null) { + return null + } else { + let weight = global.head.weight + let storeKey = global.head.storeKey + global.head = global.head.next + + let storedPacket = global.store[storeKey] + global.store[storeKey] = null + + if (storedPacket == null) { + return null + } else { + global.size-- + return { + value: storedPacket, + weight: weight, + } + } + } + } + + export function dequeueValues(targetWeight: uint = 50): EventData[] { + let values: EventData[] = [] + let weight: uint = 0 + + do { + let packet = dequeue() + + if (packet == null) { + break; + } else { + weight += packet.weight + values[values.length] = packet.value + } + } while (weight <= targetWeight) + + return values + } + + + class Node { + storeKey: string; + next: Node | null = null; + weight: uint + + constructor(storeKey: string, weight: uint) { + this.storeKey = storeKey; + this.weight = weight + } + } + + + interface EventQueueStore { + [key: string]: EventData | null; + } + +// interface PacketQueue { +// enqueue(key: string, packet: T, weight: int): void +// +// dequeue(): WeightedPacket | null +// +// dequeueValues(targetWeight: int): T[] +// } +// + interface WeightedPacket { + value: EventData, + weight: int, + } + + +} diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index 5d7dc4f..a8216e6 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.6", + "version": "0.2.7", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index b4993c8..c9efe3b 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.6", + "version": "0.2.7", "private": true, "scripts": { "build": "tstl", diff --git a/modules/events-mod/src/main/typescript/tsconfig.json b/modules/events-mod/src/main/typescript/tsconfig.json index 70b9ed4..d87f6f4 100644 --- a/modules/events-mod/src/main/typescript/tsconfig.json +++ b/modules/events-mod/src/main/typescript/tsconfig.json @@ -1,9 +1,9 @@ { "$schema": "https://raw.githubusercontent.com/TypeScriptToLua/vscode-typescript-to-lua/master/tsconfig-schema.json", "compilerOptions": { - "target": "es2019", + "target": "esnext", "lib": [ - "es2019" + "esnext" ], "module": "commonjs", "moduleResolution": "node", From 97d0de56e78cecff4d9c717590cc6d55caecf569 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 23 Jan 2022 13:52:54 +0100 Subject: [PATCH 164/629] tidy up event-schema ksx json stuff, and make the "empty list <-> empty object" thing contextual --- build.gradle.kts | 2 +- .../events/schema/factorioLuaObjects.kt | 12 +-- .../events/schema/factorioPrototypes.kt | 18 +++-- .../adamko/kafkatorio/events/schema/json.kt | 74 +++++++++++-------- .../events/schema/kafkatorioPacket.kt | 13 ++-- modules/infra-factorio-server/src/.env | 2 +- modules/infra-kafka-cluster/src/.env | 2 +- modules/infra-kafka-pipe/src/.env | 2 +- 8 files changed, 74 insertions(+), 51 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index f23f144..bfae4e2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.2.6" +version = "0.2.7" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt index 63d0c43..d142fbb 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.events.schema +import kotlinx.serialization.Contextual import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.EncodeDefault import kotlinx.serialization.Serializable @@ -9,7 +10,7 @@ import kotlinx.serialization.json.contentOrNull import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive -@Serializable(with = FactorioObjectDataSerializer::class) +@Serializable(with = FactorioObjectDataJsonSerializer::class) sealed class FactorioObjectData { @EncodeDefault @@ -43,7 +44,7 @@ sealed class FactorioObjectData { } } -object FactorioObjectDataSerializer : JsonContentPolymorphicSerializer( +object FactorioObjectDataJsonSerializer : JsonContentPolymorphicSerializer( FactorioObjectData::class ) { private val key = FactorioObjectData::objectName.name @@ -58,6 +59,8 @@ object FactorioObjectDataSerializer : JsonContentPolymorphicSerializer PlayerData.serializer() FactorioObjectData.ObjectName.LuaEntity -> EntityData.serializer() @@ -66,8 +69,6 @@ object FactorioObjectDataSerializer : JsonContentPolymorphicSerializer MapTile.serializer() FactorioObjectData.ObjectName.LuaTiles -> MapTiles.serializer() FactorioObjectData.ObjectName.ConsoleChatMessage -> ConsoleChatMessage.serializer() - null -> - throw Exception("Unknown FactorioObjectData $key: '$type' ") } } } @@ -75,7 +76,8 @@ object FactorioObjectDataSerializer : JsonContentPolymorphicSerializer, val characterUnitNumber: UInt?, val name: String, diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt index 31dfabd..8fc42ea 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt @@ -1,5 +1,7 @@ package dev.adamko.kafkatorio.events.schema +import dev.adamko.kafkatorio.events.schema.FactorioPrototype.PrototypeObjectName +import kotlinx.serialization.Contextual import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.EncodeDefault import kotlinx.serialization.Serializable @@ -20,7 +22,7 @@ data class FactorioPrototypes( } -@Serializable(with = FactorioPrototypeSerializer::class) +@Serializable(with = FactorioPrototypeJsonSerializer::class) sealed class FactorioPrototype { @EncodeDefault abstract val prototypeObjectName: PrototypeObjectName @@ -30,7 +32,8 @@ sealed class FactorioPrototype { } } -object FactorioPrototypeSerializer : JsonContentPolymorphicSerializer( + +object FactorioPrototypeJsonSerializer : JsonContentPolymorphicSerializer( FactorioPrototype::class ) { private val key = FactorioPrototype::prototypeObjectName.name @@ -42,13 +45,13 @@ object FactorioPrototypeSerializer : JsonContentPolymorphicSerializer - FactorioPrototype.PrototypeObjectName.values().firstOrNull { it.name == json } + PrototypeObjectName.values().firstOrNull { it.name == json } } + requireNotNull(type) { "Unknown FactorioPrototype ${key}: $element" } + return when (type) { - FactorioPrototype.PrototypeObjectName.LuaTilePrototype -> MapTilePrototype.serializer() - null -> - throw Exception("Unknown FactorioPrototype $key: '$type' ") + PrototypeObjectName.LuaTilePrototype -> MapTilePrototype.serializer() } } } @@ -59,7 +62,8 @@ data class MapTilePrototype( val name: String, val layer: UInt, val mapColour: Colour, - @Serializable(with = FactorioJsonListSerializer::class) +// @Serializable(with = FactorioJsonListSerializer::class) + @Contextual val collisionMasks: List, val order: String, /** Can the tile be mined for resources? */ diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt index e477521..0c4642e 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt @@ -7,46 +7,62 @@ import kotlinx.serialization.json.JsonArray import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonTransformingSerializer -import kotlinx.serialization.json.jsonArray -import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.modules.SerializersModule val jsonMapperKafkatorio = Json { prettyPrint = true prettyPrintIndent = " " -// serializersModule = FactorioEvent.kxsModule -// serializersModule = KafkatorioPacket.kxsModule + FactorioEvent.kxsModule -// serializersModule = SerializersModule { } + + serializersModule = SerializersModule { + contextual(List::class) { args -> FactorioJsonListSerializer(args[0]) } + } + } -/** Factorio outputs lists as Json objects - this serializer converts an object back to a list. */ -// actually I'm not sure that it does - I think *empty* lists get encoded as *empty* objects -internal class ListAsObjectSerializer(dataSerializer: KSerializer) : - JsonTransformingSerializer>(ListSerializer(dataSerializer)) { - - override fun transformDeserialize(element: JsonElement): JsonElement = - JsonArray( - element.jsonObject.values.toList() - ) - - override fun transformSerialize(element: JsonElement): JsonElement = - JsonObject( - element.jsonArray.mapIndexed { index, jsonElement -> "$index" to jsonElement }.toMap() - ) -} - - -/** Factorio outputs lists as Json objects - this serializer converts an object back to a list. */ -// actually I'm not sure that it does - I think *empty* lists get encoded as *empty* objects -internal class FactorioJsonListSerializer(dataSerializer: KSerializer) : +/** + * Factorio outputs an *empty* list as an *empty* Json object. This serde performs the same + * conversion + */ +class FactorioJsonListSerializer(dataSerializer: KSerializer) : JsonTransformingSerializer>(ListSerializer(dataSerializer)) { override fun transformDeserialize(element: JsonElement): JsonElement { - return if (element is JsonObject) { - JsonArray(emptyList()) - } else { - element + return when (element) { + is JsonObject -> JsonArray(emptyList()) + else -> element + } + } + + override fun transformSerialize(element: JsonElement): JsonElement { + return when { + element is JsonArray && element.isEmpty() -> buildJsonObject { } + else -> element } } } + +//internal class FactorioListSerializer( +// private val tSerializer: KSerializer +//) : KSerializer> { +// +// override val descriptor: SerialDescriptor get() = tSerializer.descriptor +// private val tListSerializer = ListSerializer(tSerializer) +// private val jsonTransformer = FactorioJsonListSerializer(tSerializer) +// +// override fun serialize(encoder: Encoder, value: List) { +// when (encoder) { +// is JsonEncoder -> jsonTransformer.serialize(encoder, value) +// else -> tListSerializer.serialize(encoder, value) +// } +// } +// +// override fun deserialize(decoder: Decoder): List { +// return when (decoder) { +// is JsonDecoder -> jsonTransformer.deserialize(decoder) +// else -> tListSerializer.deserialize(decoder) +// } +// } +//} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt index 56e86cb..cb98d95 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt @@ -10,7 +10,7 @@ import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive -@Serializable(with = KafkatorioPacketSerializer::class) +@Serializable(with = KafkatorioPacketJsonSerializer::class) sealed class KafkatorioPacket { /** Schema versioning */ abstract val modVersion: String @@ -24,7 +24,8 @@ sealed class KafkatorioPacket { } } -object KafkatorioPacketSerializer : JsonContentPolymorphicSerializer( + +object KafkatorioPacketJsonSerializer : JsonContentPolymorphicSerializer( KafkatorioPacket::class ) { private val key = KafkatorioPacket::packetType.name @@ -39,12 +40,12 @@ object KafkatorioPacketSerializer : JsonContentPolymorphicSerializer FactorioEvent.serializer() - KafkatorioPacket.PacketType.CONFIG -> FactorioConfigurationUpdate.serializer() + KafkatorioPacket.PacketType.EVENT -> FactorioEvent.serializer() + KafkatorioPacket.PacketType.CONFIG -> FactorioConfigurationUpdate.serializer() KafkatorioPacket.PacketType.PROTOTYPES -> FactorioPrototypes.serializer() - null -> - throw Exception("Unknown KafkatorioPacket ${key}: '$type' ") } } } diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index 129db2a..aecb9bc 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio FACTORIO_VERSION=1.1.53 -KAFKATORIO_VERSION=0.2.6 +KAFKATORIO_VERSION=0.2.7 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index afa5814..1ebae11 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.2.6 +KAFKATORIO_VERSION=0.2.7 diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index afa5814..1ebae11 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.2.6 +KAFKATORIO_VERSION=0.2.7 From 13a86dc0d5d3635fd78ca8c3c646e3526b82deb4 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 23 Jan 2022 13:54:32 +0100 Subject: [PATCH 165/629] - use byte array special function for KxsBinary format - --- .../kafkatorio/processor/serdes/kxsBinary.kt | 53 ++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt index 0c0a66f..c255676 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt @@ -6,10 +6,10 @@ import java.io.DataInput import java.io.DataInputStream import java.io.DataOutput import java.io.DataOutputStream -import java.util.zip.DeflaterOutputStream import kotlinx.serialization.BinaryFormat import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.SerializationStrategy +import kotlinx.serialization.builtins.ByteArraySerializer import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.AbstractDecoder import kotlinx.serialization.encoding.AbstractEncoder @@ -19,7 +19,7 @@ import kotlinx.serialization.modules.EmptySerializersModule import kotlinx.serialization.modules.SerializersModule -val kxsBinaryMapper: KxsBinary = KxsBinary() +val kxsBinary: KxsBinary = KxsBinary() /** [`https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/formats.md#efficient-binary-format`](https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/formats.md#efficient-binary-format) */ class KxsBinary( @@ -43,6 +43,8 @@ class KxsBinary( } } +private val byteArraySerializer = ByteArraySerializer() + class KxsDataOutputEncoder( private val output: DataOutput, override val serializersModule: SerializersModule = EmptySerializersModule, @@ -69,14 +71,38 @@ class KxsDataOutputEncoder( override fun encodeNull() = encodeBoolean(false) override fun encodeNotNullMark() = encodeBoolean(true) + + override fun encodeSerializableValue(serializer: SerializationStrategy, value: T) { + if (serializer.descriptor == byteArraySerializer.descriptor) + encodeByteArray(value as ByteArray) + else + super.encodeSerializableValue(serializer, value) + } + + private fun encodeByteArray(bytes: ByteArray) { + encodeCompactSize(bytes.size) + output.write(bytes) + } + + private fun encodeCompactSize(value: Int) { + if (value < 0xff) { + output.writeByte(value) + } else { + output.writeByte(0xff) + output.writeInt(value) + } + } } + class KxsDataInputDecoder( private val input: DataInput, override val serializersModule: SerializersModule = EmptySerializersModule, var elementsCount: Int = 0, ) : AbstractDecoder() { + private var elementIndex = 0 + override fun decodeBoolean(): Boolean = input.readByte().toInt() != 0 override fun decodeByte(): Byte = input.readByte() override fun decodeShort(): Short = input.readShort() @@ -102,4 +128,27 @@ class KxsDataInputDecoder( decodeInt().also { elementsCount = it } override fun decodeNotNullMark(): Boolean = decodeBoolean() + + override fun decodeSerializableValue( + deserializer: DeserializationStrategy, + previousValue: T? + ): T = + @Suppress("UNCHECKED_CAST") + when (deserializer.descriptor) { + byteArraySerializer.descriptor -> decodeByteArray() as T + else -> super.decodeSerializableValue(deserializer, previousValue) + } + + private fun decodeByteArray(): ByteArray { + val bytes = ByteArray(decodeCompactSize()) + input.readFully(bytes) + return bytes + } + + private fun decodeCompactSize(): Int { + val byte = input.readByte().toInt() and 0xff + if (byte < 0xff) return byte + return input.readInt() + } + } From 960782dc901839f765cb9e36c7599810fe386775 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 23 Jan 2022 13:54:56 +0100 Subject: [PATCH 166/629] mv FactorioServerId to model.kt, delete empty file --- .../processor/topology/FactorioServerState.kt | 74 ------------------- .../kafkatorio/processor/topology/model.kt | 6 ++ 2 files changed, 6 insertions(+), 74 deletions(-) delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioServerState.kt diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioServerState.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioServerState.kt deleted file mode 100644 index a2f6045..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/FactorioServerState.kt +++ /dev/null @@ -1,74 +0,0 @@ -package dev.adamko.kafkatorio.processor.topology - -//import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -//import dev.adamko.kafkatorio.events.schema.MapChunkPosition -//import dev.adamko.kafkatorio.events.schema.MapTilePosition -//import dev.adamko.kafkatorio.events.schema.MapTilePrototype -//import dev.adamko.kafkatorio.processor.serdes.jsonMapper -import kotlinx.serialization.Serializable -//import kotlinx.serialization.decodeFromString -//import org.apache.kafka.common.serialization.Serdes -//import org.apache.kafka.streams.StreamsBuilder -//import org.apache.kafka.streams.kstream.Consumed -//import org.apache.kafka.streams.kstream.KGroupedStream - -private const val sourceTopic = "factorio-server-log" - -@JvmInline -@Serializable -value class FactorioServerId(val id: String) { - override fun toString() = id -} - -//@Serializable -//data class FactorioServerState( -// val serverId: FactorioServerId, -// val mapTilePrototypes: Set, -// val surfaceIndexes: Set, -//) -// -// -//private fun gatherGameState(builder: StreamsBuilder = StreamsBuilder()) { -// -// val serverPackets: KGroupedStream = -// builder.stream( -// sourceTopic, -// Consumed.with(Serdes.String(), Serdes.String()) -// ) -// .mapValues { readOnlyKey, value -> -// println("Mapping $readOnlyKey:$value") -// jsonMapper.decodeFromString(value) -// } -// .groupByKey() -// -// @Serializable -// data class TileSurfaceData( -// val surfaceIndex: Int, -// val position: MapTilePosition, -// val prototype: MapTilePrototype, -// ) -// -// @Serializable -// data class MapChunkData( -// val position: MapChunkPosition, -// val tiles: List, -// ) -// -// @Serializable -// data class FactorioSurfaceData( -// val surfaceIndex: Int, -// val chunks: List, -// ) -// -// @Serializable -// data class FactorioServerState( -// val surfaces: Map, -// val tilePrototypes: List, -// ) -// -// -//// serverPackets -//// .aggregate( -//// Initializer { FactorioServerState("", emptyMap(), emptyList()) } -//// ) -//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt index 58a3a8f..0aa1fe7 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt @@ -9,3 +9,9 @@ value class SurfaceIndex( ) { override fun toString() = "$index" } + +@JvmInline +@Serializable +value class FactorioServerId(val id: String) { + override fun toString() = id +} From 28f985bdca8b9fb86f18475d0bcd64f29a0f2d1f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 23 Jan 2022 14:00:51 +0100 Subject: [PATCH 167/629] tweaking the kxs serde stuff --- .../processor/serdes/binaryFormat.kt | 50 +++++++++++++++++ .../kafkatorio/processor/serdes/kxsJson.kt | 1 + .../kafkatorio/processor/serdes/protobuf.kt | 55 +------------------ 3 files changed, 52 insertions(+), 54 deletions(-) create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/binaryFormat.kt diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/binaryFormat.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/binaryFormat.kt new file mode 100644 index 0000000..a1587f6 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/binaryFormat.kt @@ -0,0 +1,50 @@ +package dev.adamko.kafkatorio.processor.serdes + +import kotlinx.serialization.BinaryFormat +import kotlinx.serialization.decodeFromByteArray +import kotlinx.serialization.encodeToByteArray +import org.apache.kafka.common.serialization.Deserializer +import org.apache.kafka.common.serialization.Serde +import org.apache.kafka.common.serialization.Serializer + + +inline fun BinaryFormat.kafkaSerializer() = + Serializer { topic: String, data: T -> + runCatching { + encodeToByteArray(data) + }.getOrElse { e -> + println( + """ + Exception on encodeToString + Topic: $topic + topicData: $data + topicData as T: $data + """.trimIndent() + ) + e.printStackTrace() + throw e + } + } + +inline fun BinaryFormat.kafkaDeserializer() = + Deserializer { topic: String, data: ByteArray -> + runCatching { + decodeFromByteArray(data) + }.getOrElse { e -> + println( + """ + Exception on decodeFromString, + Topic: $topic + topicData: $data + topicData as T: ${data as? T} + """.trimIndent() + ) + e.printStackTrace() + throw e + } + } + +inline fun BinaryFormat.serde() = object : Serde { + override fun serializer(): Serializer = kafkaSerializer() + override fun deserializer(): Deserializer = kafkaDeserializer() +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt index 4cb82b9..0096037 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt @@ -12,6 +12,7 @@ import org.http4k.format.ConfigurableKotlinxSerialization import org.http4k.format.asConfigurable import org.http4k.format.withStandardMappings + object KafkatorioPacketSerde : Serde { override fun serializer() = Serializer { _, message -> jsonMapper.encodeToString(message).encodeToByteArray() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/protobuf.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/protobuf.kt index 527121f..8491485 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/protobuf.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/protobuf.kt @@ -1,59 +1,6 @@ package dev.adamko.kafkatorio.processor.serdes -import dev.adamko.kafkatorio.events.schema.jsonMapperKafkatorio -import kotlinx.serialization.BinaryFormat -import kotlinx.serialization.decodeFromByteArray -import kotlinx.serialization.encodeToByteArray import kotlinx.serialization.protobuf.ProtoBuf -import org.apache.kafka.common.serialization.Deserializer -import org.apache.kafka.common.serialization.Serde -import org.apache.kafka.common.serialization.Serializer - -val protoMapper: ProtoBuf = ProtoBuf { - serializersModule = jsonMapperKafkatorio.serializersModule -} -inline fun BinaryFormat.kafkaSerializer() = - Serializer { topic: String, data: T -> - runCatching { - encodeToByteArray(data) - }.getOrElse { e -> - println( - """ - Exception on encodeToString - Topic: $topic - topicData: $data - topicData as T: $data - """.trimIndent() - ) - e.printStackTrace() - throw e - } - } - -inline fun BinaryFormat.kafkaDeserializer() = - Deserializer { topic: String, data: ByteArray -> - runCatching { - decodeFromByteArray(data) - }.getOrElse { e -> - println( - """ - Exception on decodeFromString, - Topic: $topic - topicData: $data - topicData as T: ${data as? T} - """.trimIndent() - ) - e.printStackTrace() - throw e - } - } - -inline fun ProtoBuf.serde() = object : Serde { - - override fun serializer(): Serializer = kafkaSerializer() - - override fun deserializer(): Deserializer = kafkaDeserializer() - -} +val protoMapper: ProtoBuf = ProtoBuf { } From 494b9b4107561811d929ea392d4adae9b222d6d2 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 23 Jan 2022 22:57:11 +0100 Subject: [PATCH 168/629] kind of slow, but working... --- .../adamko/kafkatorio/admin/CreateTopics.kt | 2 +- .../processor/KafkatorioTopology.kt | 1 + .../kafkatorio/processor/eventProcessor.kt | 3 + .../processor/topology/factorioMapTiles.kt | 4 +- .../topology/factorioServerPackets.kt | 3 +- .../processor/topology/playerUpdates.kt | 9 ++- .../processor/topology/prototypes.kt | 66 ++----------------- .../processor/topology/webMapTileAggregate.kt | 22 +++---- .../processor/topology/webMapTiles.kt | 38 ++++++++--- .../dev/adamko/kafkatorio/webmap/map.kt | 2 +- 10 files changed, 61 insertions(+), 89 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt index 1152dcc..5f25d92 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt @@ -73,7 +73,7 @@ object CreateTopics { } private fun Admin.createTopics( - numPartitions: Int = 10, + numPartitions: Int = 3, replicationFactor: Short = 1, topicNames: () -> Collection, ): CreateTopicsResult = diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 0a68437..fdab787 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -31,6 +31,7 @@ class KafkatorioTopology( fun build() { splitFactorioServerLog(builder) + playerUpdatesToWsServer(websocketServer, builder) val allMapTilesTable: KTable = allMapTilesTable(builder) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt index 634fb6b..4e9df9a 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -1,6 +1,7 @@ package dev.adamko.kafkatorio.processor +import dev.adamko.kafkatorio.admin.CreateTopics import dev.adamko.kafkatorio.processor.config.ApplicationProperties import dev.adamko.kafkatorio.processor.tileserver.WebMapTileServer import kotlinx.coroutines.runBlocking @@ -12,6 +13,8 @@ val appProps = ApplicationProperties() fun main() = runBlocking { + CreateTopics.create() + val wsServer = WebsocketServer() val tileServer = WebMapTileServer() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt index 30ed815..7a48a0d 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt @@ -8,6 +8,8 @@ import dev.adamko.kafkatorio.events.schema.MapTile import dev.adamko.kafkatorio.events.schema.MapTilePosition import dev.adamko.kafkatorio.events.schema.MapTiles import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.processor.serdes.serde import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.streams.filter @@ -71,7 +73,7 @@ fun allMapTilesTable( } .toTable( "all-tiles-keyed-on-position", - materializedWith(jsonMapper.serde(), jsonMapper.serde()) + materializedWith(kxsBinary.serde(), kxsBinary.serde()) ) .suppress( Suppressed.untilTimeLimit( diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt index 17fbcf1..229c3f4 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt @@ -12,7 +12,6 @@ import dev.adamko.kafkatorio.events.schema.MapTiles import dev.adamko.kafkatorio.events.schema.PlayerData import dev.adamko.kafkatorio.events.schema.SurfaceData import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition -import dev.adamko.kafkatorio.processor.serdes.KafkatorioPacketSerde import dev.adamko.kafkatorio.processor.KafkatorioTopology import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kotka.extensions.consumedAs @@ -56,7 +55,7 @@ fun splitFactorioServerLog( producedAs( "split-server-log", jsonMapper.serde(), - KafkatorioPacketSerde + jsonMapper.serde(), ) ) { _: FactorioPacketKey, value: KafkatorioPacket, _: RecordContext -> // println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt index 86f24d7..eb51ecf 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt @@ -2,22 +2,21 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.events.schema.FactorioObjectData import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -import dev.adamko.kafkatorio.processor.serdes.KafkatorioPacketSerde import dev.adamko.kafkatorio.processor.WebsocketServer import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kotka.extensions.consumedAs +import dev.adamko.kotka.kxs.serde import kotlinx.serialization.encodeToString -import org.apache.kafka.common.serialization.Serdes import org.apache.kafka.streams.StreamsBuilder -import org.apache.kafka.streams.kstream.Consumed fun playerUpdatesToWsServer( websocketServer: WebsocketServer, builder: StreamsBuilder = StreamsBuilder(), ) { - builder.stream( + builder.stream( "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaPlayer}", - Consumed.with(Serdes.String(), KafkatorioPacketSerde) + consumedAs("stream-player-updates-for-ws-server", jsonMapper.serde(), jsonMapper.serde()) ) .foreach { _, value -> // println("sending ${value.packetType} packet to websocket") diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index 3f44473..0327096 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -4,6 +4,8 @@ import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.events.schema.MapTilePrototype import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.processor.serdes.serde import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.streams.flatMap @@ -22,12 +24,12 @@ value class PrototypeName(val name: String) { fun prototypesTable(builder: StreamsBuilder): KTable { - return builder.stream( + return builder.stream( "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", consumedAs( "consume-all-prototypes-packets", - Serdes.String(), - jsonMapper.serde() + jsonMapper.serde(), + jsonMapper.serde() ) ) .flatMap("map-MapTilePrototype") { _, prototypes: FactorioPrototypes -> @@ -37,62 +39,8 @@ fun prototypesTable(builder: StreamsBuilder): KTable, -//) -// -//fun serverPrototypesTable(builder: StreamsBuilder): KTable { -// -// return builder.stream( -// "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", -// consumedAs( -// "consume-all-prototypes-packets", -// Serdes.String(), -// jsonMapper.serde() -// ) -// ) -// .map("build-FactorioServerPrototypesRecord", ::buildPrototypesRecord) -// .peek { _, value -> -// println("tile prototypes: ${value.mapTilePrototypes.keys.joinToString()}") -// } -// .groupByKey( -// groupedAs( -// "grouping-tile-prototypes-by-surface-index", -// jsonMapper.serde(), -// jsonMapper.serde() -// ) -// ) -// .reduce( -// "group-surface-prototypes", -// materializedWith( -//// "kafkatorio.surface-prototypes", -// jsonMapper.serde(), -// jsonMapper.serde() -// ) -// ) { value1: FactorioServerPrototypesRecord, value2: FactorioServerPrototypesRecord -> -// val allTiles = value1.mapTilePrototypes + value2.mapTilePrototypes -// value1.copy(mapTilePrototypes = allTiles) -// } -//} -// -//private fun buildPrototypesRecord( -// serverId: String, -// prototypes: FactorioPrototypes -//): Pair { -// val tilePrototypes = prototypes.prototypes -// .filterIsInstance() -// .associateBy { PrototypeName(it.name) } -// -// val key = FactorioServerId(serverId) -// val data = FactorioServerPrototypesRecord(key, tilePrototypes) -// return key to data -//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt index c1f04fd..7583556 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt @@ -5,7 +5,8 @@ import dev.adamko.kafkatorio.events.schema.MapTile import dev.adamko.kafkatorio.events.schema.MapTilePosition import dev.adamko.kafkatorio.events.schema.MapTilePrototype import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition -import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.processor.serdes.serde import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.namedAs @@ -13,7 +14,6 @@ import dev.adamko.kotka.extensions.tables.groupBy import dev.adamko.kotka.extensions.tables.join import dev.adamko.kotka.extensions.tables.mapValues import dev.adamko.kotka.extensions.toKeyValue -import dev.adamko.kotka.kxs.serde import java.time.Duration import kotlinx.serialization.Serializable import org.apache.kafka.streams.kstream.KTable @@ -60,8 +60,8 @@ fun aggregateWebMapTiles( "convert-tiles-to-colours", materializedAs( "store-web-map-tile-pixels", - jsonMapper.serde(), - jsonMapper.serde(), + kxsBinary.serde(), + kxsBinary.serde(), ), { PrototypeName(it.prototypeName) }, ) { tile: MapTile, proto: MapTilePrototype -> @@ -74,8 +74,8 @@ fun aggregateWebMapTiles( .groupBy( groupedAs( "group-webmap-tile-colours-into-chunks", - jsonMapper.serde(), - jsonMapper.serde(), + kxsBinary.serde(), + kxsBinary.serde(), ) ) { pos: TileUpdateRecordKey, px: WebMapTilePixel -> val (chunkX, chunkY) = pos.tilePosition.toMapChunkPosition(WEB_MAP_IMAGE_TILE_SIZE) @@ -100,24 +100,24 @@ fun aggregateWebMapTiles( namedAs("web-map-tile-colours-into-$WEB_MAP_IMAGE_TILE_SIZE-chunks"), materializedAs( "web-map-tile-colour-chunks-aggregate", - jsonMapper.serde(), - jsonMapper.serde() + kxsBinary.serde(), + kxsBinary.serde() ) ) .suppress( Suppressed.untilTimeLimit( Duration.ofSeconds(30), Suppressed.BufferConfig - .maxRecords(2) + .maxRecords(30) // .withMaxBytes(31457280 ) // 30MB - .emitEarlyWhenFull() +// .emitEarlyWhenFull() ).withName("web-map-tile-aggregate-debounce") ) return webMapTileChunkAggregate .mapValues( "finalise-web-map-tile-colour-chunk-aggregation", - materializedAs("web-map-tile-colour-chunks", jsonMapper.serde(), jsonMapper.serde()) + materializedAs("web-map-tile-colour-chunks", kxsBinary.serde(), kxsBinary.serde()) ) { _, v -> WebMapTileChunkPixels(v.pixels) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt index 0ffc2b0..a1011b2 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt @@ -20,10 +20,10 @@ fun saveTileImages( webMapTiles .suppress( - Suppressed.untilTimeLimit( + Suppressed.untilTimeLimit( Duration.ofSeconds(30), Suppressed.BufferConfig.maxRecords(30) - ) + ).withName("save-tile-images-debounce") ) .toStream("get-webmap-tile-updates") .foreach { position: WebMapTileChunkPosition, pixels: WebMapTileChunkPixels -> @@ -37,13 +37,15 @@ fun saveTileImages( } } +//val saveMapTilesContext = Dispatchers.IO.limitedParallelism(1) + private fun saveMapTilesPng( chunkPosition: WebMapTileChunkPosition, pixels: Set ) { - val chunkOriginX: Int = chunkPosition.x * chunkPosition.chunkSize - val chunkOriginY: Int = chunkPosition.y * chunkPosition.chunkSize + val chunkOriginX: Int = chunkPosition.x * chunkPosition.chunkSize // - 1 + val chunkOriginY: Int = chunkPosition.y * chunkPosition.chunkSize // - 1 val surfaceIndex: Int = chunkPosition.surfaceIndex.index val chunkImage = @@ -76,15 +78,33 @@ private fun saveMapTilesPng( val zoom = 1u val file = - File( - "src/main/resources/kafkatorio-web-map/s${surfaceIndex}/z$zoom/x${chunkPosition.x}/y${chunkPosition.y}.png" - ) + File(tileFilename("$surfaceIndex", "$zoom", "${chunkPosition.x}", "${chunkPosition.y}")) if (file.parentFile.mkdirs()) { println("created new map tile parentFile directory ${file.absolutePath}") } println("saving map tile $file") - - chunkImage.output(PngWriter.MaxCompression, file) + val savedTile = chunkImage.output(PngWriter.NoCompression, file) + println("savedTile: $savedTile") } + +fun tileFilename( + surfaceIndex: String, + zoom: String, + chunkX: String, + chunkY: String, +) = "src/main/resources/kafkatorio-web-map/s${surfaceIndex}/z$zoom/x${chunkX}/y${chunkY}.png" + +//fun subdivide(tile: ImmutableImage, size: Int) { +// +// val halfSize = size / 2 +// +// val bl = tile.resizeTo(halfSize, halfSize, Position.BottomLeft) +// val savedTile = bl.output(PngWriter.NoCompression, file) +// +// tile.resizeTo(halfSize, halfSize, Position.BottomRight) +// tile.resizeTo(halfSize, halfSize, Position.TopLeft) +// tile.resizeTo(halfSize, halfSize, Position.TopRight) +// +//} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index ff73df7..14a3326 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -33,7 +33,7 @@ fun createFactorioMap() = Maps { """http://localhost:9073/tiles/s1/z{z}/x{x}/y{y}.png""" ) { attribution = "kafkatorio" -// tileSize = 256 + tileSize = 256 tms = true // minZoom = -2 // maxZoom = 1 From 46ad6181341f0523cd3d5dec69391f96a8e6eadf Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 23 Jan 2022 22:59:29 +0100 Subject: [PATCH 169/629] make 'chunks' command accept a 'radius' param (which makes current_chunk redundant) --- .../main/commands/kafkatorioCommands.ts | 56 +++++-------------- 1 file changed, 15 insertions(+), 41 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts index c1ecb3b..3cc2c79 100644 --- a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts +++ b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts @@ -1,5 +1,4 @@ import {emitPrototypes} from "../config-update/prototypes"; -import {handleChunkUpdate} from "../events/handlers"; import {Queue} from "../queue/queue"; import floor = math.floor; @@ -8,43 +7,20 @@ commands.add_command( "kafkatorio", "kafkatorio innit bruv", (e: CustomCommandData) => { + + let player = (e.player_index != null) ? game.get_player(e.player_index) : null + if (e.parameter == undefined) { + if (player != null) { + player.print("no parameter") + } // do nothing } else if ("PROTOTYPES" == e.parameter.toUpperCase()) { emitPrototypes() - } else if ("CURRENT_CHUNK" == e.parameter.toUpperCase()) { + } else if (e.parameter.toUpperCase().startsWith("CHUNKS")) { - if (e.player_index != undefined) { - - let player = game.players[e.player_index] - - let chunkPosition: ChunkPosition = { - x: floor(player.position.x / 32), - y: floor(player.position.y / 32), - } - - let chunkLeftTop: Position = { - x: chunkPosition.x * 32, - y: chunkPosition.y * 32, - } - let chunkBottomRight: Position = { - x: chunkLeftTop.x + 32 - 1, - y: chunkLeftTop.y + 32 - 1, - } - let chunkArea: BoundingBoxRead = { - left_top: chunkLeftTop, - right_bottom: chunkBottomRight - } - - handleChunkUpdate( - e.tick, - "player-command-" + e.parameter, - player.surface.index, - chunkPosition, - chunkArea, - ) - } - } else if ("CHUNKS" == e.parameter.toUpperCase()) { + let size = e.parameter.split(" ")?.[1] ?? null + let radius = (size != null) ? parseInt(size) : 1 if (e.player_index != undefined) { let player = game.players[e.player_index] @@ -54,19 +30,17 @@ commands.add_command( y: floor(player.position.y / 32), } - let delta = 1 - - let chunkXMin = chunkPosition.x - delta - let chunkXMax = chunkPosition.x + delta - let chunkYMin = chunkPosition.y - delta - let chunkYMax = chunkPosition.y + delta + let chunkXMin = chunkPosition.x - radius + let chunkXMax = chunkPosition.x + radius + let chunkYMin = chunkPosition.y - radius + let chunkYMax = chunkPosition.y + radius for (let [, surface] of game.surfaces) { for (let chunk of surface.get_chunks()) { if ( - (chunk.x >= chunkXMin || chunk.x <= chunkXMax) + (chunk.x >= chunkXMin && chunk.x <= chunkXMax) && - (chunk.y >= chunkYMin || chunk.y <= chunkYMax) + (chunk.y >= chunkYMin && chunk.y <= chunkYMax) ) { let data: OnChunkGeneratedEvent = { From dbeb0e73dd2b1318804e26656f883c241280d6d1 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 23 Jan 2022 22:59:47 +0100 Subject: [PATCH 170/629] try fixing queue size... --- modules/events-mod/src/main/typescript/main/queue/queue.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/events-mod/src/main/typescript/main/queue/queue.ts b/modules/events-mod/src/main/typescript/main/queue/queue.ts index 693c4d1..f5d60f2 100644 --- a/modules/events-mod/src/main/typescript/main/queue/queue.ts +++ b/modules/events-mod/src/main/typescript/main/queue/queue.ts @@ -56,6 +56,7 @@ export namespace Queue { let weight = global.head.weight let storeKey = global.head.storeKey global.head = global.head.next + global.size-- let storedPacket = global.store[storeKey] global.store[storeKey] = null @@ -63,7 +64,6 @@ export namespace Queue { if (storedPacket == null) { return null } else { - global.size-- return { value: storedPacket, weight: weight, From 4fc55b706fce1a8e8eb8b014d6a4f556c3a9c573 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 25 Jan 2022 00:11:38 +0100 Subject: [PATCH 171/629] only try to create topics if there are topics to be created --- .../adamko/kafkatorio/admin/CreateTopics.kt | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt index 5f25d92..0857e83 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt @@ -30,6 +30,8 @@ object CreateTopics { KafkatorioPacket.PacketType.values().forEach { packetType -> + val currentTopics = currentTopics().map { it.name() } + val kafkatorioTopics = buildSet { add(KafkatorioTopology.sourceTopic) when (packetType) { @@ -42,33 +44,30 @@ object CreateTopics { KafkatorioPacket.PacketType.PROTOTYPES -> add("kafkatorio.${packetType.name}.all") } - } + }.minus(currentTopics.toSet()) - val currentTopics = currentTopics().map { it.name() } + if (currentTopics.isNotEmpty()) { - val result = kafkatorioTopics - .filterNot { it in currentTopics } - .run { - logger.info("Creating $size topics") - kafkaAdmin.createTopics { this } + logger.info("Creating ${kafkatorioTopics.size} topics") + val result = kafkaAdmin.createTopics { kafkatorioTopics } + + // wait for all brokers to become aware of the created topics + Thread.sleep(TimeUnit.SECONDS.toMillis(5)) + + result.values().forEach { + logger.info("Created topic: ${it.key} ${it.value.get()}") } - // wait for all brokers to become aware of the created topics - Thread.sleep(TimeUnit.SECONDS.toMillis(5)) + Thread.sleep(TimeUnit.SECONDS.toMillis(5)) - result.values().forEach { - logger.info("Created topic: ${it.key} ${it.value.get()}") + logger.info("Listing topics") + kafkaAdmin.listTopics() + .listings() + .get() + .forEach { + logger.info("Topic: $it") + } } - - Thread.sleep(TimeUnit.SECONDS.toMillis(5)) - - logger.info("Listing topics") - kafkaAdmin.listTopics() - .listings() - .get() - .forEach { - logger.info("Topic: $it") - } } } From 8645b4552d28c8d82446d2c6c3cd39fe0775eaae Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 25 Jan 2022 00:12:05 +0100 Subject: [PATCH 172/629] debug print to try to figure out why websocker player position isn't working --- .../dev/adamko/kafkatorio/processor/topology/playerUpdates.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt index eb51ecf..2a51006 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt @@ -19,7 +19,7 @@ fun playerUpdatesToWsServer( consumedAs("stream-player-updates-for-ws-server", jsonMapper.serde(), jsonMapper.serde()) ) .foreach { _, value -> -// println("sending ${value.packetType} packet to websocket") + println("sending ${value.packetType} packet to websocket") websocketServer.sendMessage(jsonMapper.encodeToString(value)) } } From f5855ba5bdc5fc176d33bd288da4631e90c3ffd3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 25 Jan 2022 00:13:37 +0100 Subject: [PATCH 173/629] try making performance better... --- .../kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt | 2 +- .../adamko/kafkatorio/processor/topology/webMapTileAggregate.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt index 4e9df9a..8506cac 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -11,7 +11,7 @@ import org.http4k.server.asServer val appProps = ApplicationProperties() -fun main() = runBlocking { +fun main(): Unit = runBlocking { CreateTopics.create() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt index 7583556..f266978 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt @@ -110,7 +110,7 @@ fun aggregateWebMapTiles( Suppressed.BufferConfig .maxRecords(30) // .withMaxBytes(31457280 ) // 30MB -// .emitEarlyWhenFull() + .emitEarlyWhenFull() ).withName("web-map-tile-aggregate-debounce") ) From f1084310335d90ade39eed0590e5c830adddb805 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 5 Feb 2022 12:20:25 +0100 Subject: [PATCH 174/629] - bump kafka sdk version - fix kafka admin so it doesn't try making topics always - move some stuff to Kotka Streams - trying to optimise and debounce with windows... but it didn't work --- gradle/libs.versions.toml | 2 +- modules/events-server/build.gradle.kts | 8 +- .../adamko/kafkatorio/admin/CreateTopics.kt | 53 ++++----- .../processor/KafkatorioTopology.kt | 8 +- .../processor/serdes/binaryFormat.kt | 82 ++++++------- .../processor/topology/factorioMapTiles.kt | 10 +- .../kafkatorio/processor/topology/model.kt | 12 ++ .../processor/topology/playerUpdates.kt | 2 +- .../processor/topology/prototypes.kt | 33 +++++- .../processor/topology/webMapTileAggregate.kt | 111 +++++++++++++----- .../processor/topology/webMapTiles.kt | 30 ++--- 11 files changed, 216 insertions(+), 135 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7dd2fe9..625e7dd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ kotlin = "1.6.10" ## libs ## camel-kafkaConnectors = "0.11.0" http4k = "4.17.6.0" -kafka = "3.0.0" +kafka = "3.1.0" kotlinx-serialization = "1.3.2" kvision = "5.7.1" log4j2 = "2.14.1" diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 491230d..64c0fcf 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -38,7 +38,8 @@ dependencies { implementation("com.sksamuel.scrimage:scrimage-core:4.0.24") - val kotkaVersion = "0.0.8" +// val kotkaVersion = "0.0.11" + val kotkaVersion = "store-iterators-SNAPSHOT" implementation("com.github.adamko-dev.kotka-streams:kotka-streams:$kotkaVersion") { isChanging = true } @@ -49,6 +50,10 @@ dependencies { } +//configurations.all { +// resolutionStrategy.cacheDynamicVersionsFor(1, TimeUnit.MINUTES) +//} + application { mainClass.set("dev.adamko.kafkatorio.processor.EventProcessorKt") } @@ -56,5 +61,6 @@ application { tasks.withType { kotlinOptions.freeCompilerArgs += listOf( "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlinx.coroutines.FlowPreview", ) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt index 0857e83..02d4520 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt @@ -28,11 +28,10 @@ object CreateTopics { fun create() { - KafkatorioPacket.PacketType.values().forEach { packetType -> + val currentTopics = currentTopics().map { it.name() } - val currentTopics = currentTopics().map { it.name() } - - val kafkatorioTopics = buildSet { + val kafkatorioTopics = buildSet { + KafkatorioPacket.PacketType.values().forEach { packetType -> add(KafkatorioTopology.sourceTopic) when (packetType) { KafkatorioPacket.PacketType.EVENT -> @@ -44,30 +43,30 @@ object CreateTopics { KafkatorioPacket.PacketType.PROTOTYPES -> add("kafkatorio.${packetType.name}.all") } - }.minus(currentTopics.toSet()) - - if (currentTopics.isNotEmpty()) { - - logger.info("Creating ${kafkatorioTopics.size} topics") - val result = kafkaAdmin.createTopics { kafkatorioTopics } - - // wait for all brokers to become aware of the created topics - Thread.sleep(TimeUnit.SECONDS.toMillis(5)) - - result.values().forEach { - logger.info("Created topic: ${it.key} ${it.value.get()}") - } - - Thread.sleep(TimeUnit.SECONDS.toMillis(5)) - - logger.info("Listing topics") - kafkaAdmin.listTopics() - .listings() - .get() - .forEach { - logger.info("Topic: $it") - } } + }.minus(currentTopics.toSet()) + + if (kafkatorioTopics.isNotEmpty()) { + + logger.info("Creating ${kafkatorioTopics.size} topics") + val result = kafkaAdmin.createTopics { kafkatorioTopics } + + // wait for all brokers to become aware of the created topics + Thread.sleep(TimeUnit.SECONDS.toMillis(5)) + + result.values().forEach { + logger.info("Created topic: ${it.key} ${it.value.get()}") + } + + Thread.sleep(TimeUnit.SECONDS.toMillis(5)) + + logger.info("Listing topics") + kafkaAdmin.listTopics() + .listings() + .get() + .forEach { + logger.info("Topic: $it") + } } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index fdab787..89e9438 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -1,7 +1,7 @@ package dev.adamko.kafkatorio.processor +import dev.adamko.kafkatorio.events.schema.Colour import dev.adamko.kafkatorio.events.schema.MapTile -import dev.adamko.kafkatorio.events.schema.MapTilePrototype import dev.adamko.kafkatorio.processor.topology.PrototypeName import dev.adamko.kafkatorio.processor.topology.TileUpdateRecordKey import dev.adamko.kafkatorio.processor.topology.WebMapTileChunkPixels @@ -9,9 +9,9 @@ import dev.adamko.kafkatorio.processor.topology.WebMapTileChunkPosition import dev.adamko.kafkatorio.processor.topology.aggregateWebMapTiles import dev.adamko.kafkatorio.processor.topology.allMapTilesTable import dev.adamko.kafkatorio.processor.topology.playerUpdatesToWsServer -import dev.adamko.kafkatorio.processor.topology.prototypesTable import dev.adamko.kafkatorio.processor.topology.saveTileImages import dev.adamko.kafkatorio.processor.topology.splitFactorioServerLog +import dev.adamko.kafkatorio.processor.topology.tilePrototypeColourTable import java.time.Duration import org.apache.kafka.streams.KafkaStreams import org.apache.kafka.streams.StreamsBuilder @@ -35,10 +35,10 @@ class KafkatorioTopology( playerUpdatesToWsServer(websocketServer, builder) val allMapTilesTable: KTable = allMapTilesTable(builder) - val tilePrototypesTable: KTable = prototypesTable(builder) + val tilePrototypeColourTable: KTable = tilePrototypeColourTable(builder) val webMapTiles: KTable = - aggregateWebMapTiles(allMapTilesTable, tilePrototypesTable) + aggregateWebMapTiles(allMapTilesTable, tilePrototypeColourTable) saveTileImages(webMapTiles) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/binaryFormat.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/binaryFormat.kt index a1587f6..180db50 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/binaryFormat.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/binaryFormat.kt @@ -7,44 +7,44 @@ import org.apache.kafka.common.serialization.Deserializer import org.apache.kafka.common.serialization.Serde import org.apache.kafka.common.serialization.Serializer - -inline fun BinaryFormat.kafkaSerializer() = - Serializer { topic: String, data: T -> - runCatching { - encodeToByteArray(data) - }.getOrElse { e -> - println( - """ - Exception on encodeToString - Topic: $topic - topicData: $data - topicData as T: $data - """.trimIndent() - ) - e.printStackTrace() - throw e - } - } - -inline fun BinaryFormat.kafkaDeserializer() = - Deserializer { topic: String, data: ByteArray -> - runCatching { - decodeFromByteArray(data) - }.getOrElse { e -> - println( - """ - Exception on decodeFromString, - Topic: $topic - topicData: $data - topicData as T: ${data as? T} - """.trimIndent() - ) - e.printStackTrace() - throw e - } - } - -inline fun BinaryFormat.serde() = object : Serde { - override fun serializer(): Serializer = kafkaSerializer() - override fun deserializer(): Deserializer = kafkaDeserializer() -} +// +//inline fun BinaryFormat.kafkaSerializer() = +// Serializer { topic: String, data: T -> +// runCatching { +// encodeToByteArray(data) +// }.getOrElse { e -> +// println( +// """ +// Exception on encodeToString +// Topic: $topic +// topicData: $data +// topicData as T: $data +// """.trimIndent() +// ) +// e.printStackTrace() +// throw e +// } +// } +// +//inline fun BinaryFormat.kafkaDeserializer() = +// Deserializer { topic: String, data: ByteArray -> +// runCatching { +// decodeFromByteArray(data) +// }.getOrElse { e -> +// println( +// """ +// Exception on decodeFromString, +// Topic: $topic +// topicData: $data +// topicData as T: ${data as? T} +// """.trimIndent() +// ) +// e.printStackTrace() +// throw e +// } +// } +// +//inline fun BinaryFormat.serde() = object : Serde { +// override fun serializer(): Serializer = kafkaSerializer() +// override fun deserializer(): Deserializer = kafkaDeserializer() +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt index 7a48a0d..6a6ee07 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt @@ -9,7 +9,6 @@ import dev.adamko.kafkatorio.events.schema.MapTilePosition import dev.adamko.kafkatorio.events.schema.MapTiles import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kafkatorio.processor.serdes.serde import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.streams.filter @@ -75,12 +74,5 @@ fun allMapTilesTable( "all-tiles-keyed-on-position", materializedWith(kxsBinary.serde(), kxsBinary.serde()) ) - .suppress( - Suppressed.untilTimeLimit( - Duration.ofSeconds(30), - Suppressed.BufferConfig - .maxRecords(30) - .emitEarlyWhenFull() - ) - ) + } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt index 0aa1fe7..fb785c6 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt @@ -1,5 +1,8 @@ package dev.adamko.kafkatorio.processor.topology +import com.sksamuel.scrimage.color.RGBColor +import dev.adamko.kafkatorio.events.schema.Colour +import kotlin.math.roundToInt import kotlinx.serialization.Serializable @Serializable @@ -15,3 +18,12 @@ value class SurfaceIndex( value class FactorioServerId(val id: String) { override fun toString() = id } + +fun Colour.toRgbColor(): RGBColor { + return RGBColor( + red.roundToInt(), + green.roundToInt(), + blue.roundToInt(), + alpha.roundToInt(), + ) +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt index 2a51006..0843190 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt @@ -19,7 +19,7 @@ fun playerUpdatesToWsServer( consumedAs("stream-player-updates-for-ws-server", jsonMapper.serde(), jsonMapper.serde()) ) .foreach { _, value -> - println("sending ${value.packetType} packet to websocket") +// println("sending ${value.packetType} packet to websocket") websocketServer.sendMessage(jsonMapper.encodeToString(value)) } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index 0327096..13e9ae1 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -1,11 +1,12 @@ package dev.adamko.kafkatorio.processor.topology +import com.sksamuel.scrimage.color.RGBColor +import dev.adamko.kafkatorio.events.schema.Colour import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.events.schema.MapTilePrototype import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kafkatorio.processor.serdes.serde import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.streams.flatMap @@ -23,7 +24,31 @@ value class PrototypeName(val name: String) { } -fun prototypesTable(builder: StreamsBuilder): KTable { +//fun prototypesTable(builder: StreamsBuilder): KTable { +// return builder.stream( +// "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", +// consumedAs( +// "consume-all-prototypes-packets", +// jsonMapper.serde(), +// jsonMapper.serde() +// ) +// ) +// .flatMap("map-MapTilePrototype") { _, prototypes: FactorioPrototypes -> +// prototypes.prototypes +// .filterIsInstance() +// .map { PrototypeName(it.name) to it } +// } +// .toTable( +// materializedWith( +// kxsBinary.serde(), +// kxsBinary.serde() +// ) +// ) +//} + + +/** Get the [Colour] of each [MapTilePrototype] */ +fun tilePrototypeColourTable(builder: StreamsBuilder): KTable { return builder.stream( "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", consumedAs( @@ -35,7 +60,9 @@ fun prototypesTable(builder: StreamsBuilder): KTable prototypes.prototypes .filterIsInstance() - .map { PrototypeName(it.name) to it } + .map { + PrototypeName(it.name) to it.mapColour + } } .toTable( materializedWith( diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt index f266978..9f6115e 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt @@ -1,28 +1,37 @@ package dev.adamko.kafkatorio.processor.topology +import com.sksamuel.scrimage.color.RGBColor import dev.adamko.kafkatorio.events.schema.Colour import dev.adamko.kafkatorio.events.schema.MapTile import dev.adamko.kafkatorio.events.schema.MapTilePosition -import dev.adamko.kafkatorio.events.schema.MapTilePrototype import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kafkatorio.processor.serdes.serde import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedAs +import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.namedAs +import dev.adamko.kotka.extensions.streams.groupBy import dev.adamko.kotka.extensions.tables.groupBy import dev.adamko.kotka.extensions.tables.join import dev.adamko.kotka.extensions.tables.mapValues +import dev.adamko.kotka.extensions.tables.toStream import dev.adamko.kotka.extensions.toKeyValue +import dev.adamko.kotka.kxs.serde +import java.awt.Color import java.time.Duration import kotlinx.serialization.Serializable import org.apache.kafka.streams.kstream.KTable +import org.apache.kafka.streams.kstream.SessionWindows import org.apache.kafka.streams.kstream.Suppressed +import org.apache.kafka.streams.kstream.Windowed /** The tiles of the webmap will be this many pixels high/wide */ const val WEB_MAP_IMAGE_TILE_SIZE = 256 +/** Debounce duration */ +private val WINDOW_INACTIVITY_DURATION = Duration.ofSeconds(60) + @Serializable data class WebMapTileChunkPosition( val chunkSize: Int, @@ -32,31 +41,52 @@ data class WebMapTileChunkPosition( ) @Serializable -data class WebMapTilePixel( +private data class WebMapTilePixel( val mapColour: Colour, val tilePosition: MapTilePosition, ) @Serializable -data class WebMapTileChunkPixels( - val pixels: Set = mutableSetOf(), +@JvmInline +value class WebMapTileChunkPixels( + val pixels: Map, ) -/** Temporary mutable aggregator */ +/** Temporary mutable accumulator */ @Serializable -private data class WebMapTileChunkPixelsAcc( - val pixels: MutableSet = mutableSetOf(), -) +@JvmInline +private value class WebMapTileChunkPixelsAcc( + val pixels: MutableMap = mutableMapOf(), +) { + + operator fun plus(pixel: WebMapTilePixel): WebMapTileChunkPixelsAcc { + pixels[pixel.tilePosition] = pixel.mapColour + return this + } + + operator fun plus(other: WebMapTileChunkPixelsAcc): WebMapTileChunkPixelsAcc { + this.pixels += other.pixels + return this + } + + operator fun minus(other: WebMapTileChunkPixelsAcc): WebMapTileChunkPixelsAcc { + this.pixels -= other.pixels.keys + return this + } + +} + fun aggregateWebMapTiles( allMapTilesTable: KTable, - tilePrototypesTable: KTable, + tilePrototypeColourTable: KTable, ): KTable { - val webmapTileColours: KTable = + + val pixels: KTable = allMapTilesTable .join( - tilePrototypesTable, + tilePrototypeColourTable, "convert-tiles-to-colours", materializedAs( "store-web-map-tile-pixels", @@ -64,13 +94,14 @@ fun aggregateWebMapTiles( kxsBinary.serde(), ), { PrototypeName(it.prototypeName) }, - ) { tile: MapTile, proto: MapTilePrototype -> - WebMapTilePixel(proto.mapColour, tile.position) + ) { tile: MapTile, colour: Colour -> + WebMapTilePixel(colour, tile.position) } - val webMapTileChunkAggregate: KTable = - webmapTileColours + val chunkedPixelsWindowed: KTable, WebMapTileChunkPixelsAcc> = + pixels + .toStream("stream-webmap-tile-pixels") .groupBy( groupedAs( "group-webmap-tile-colours-into-chunks", @@ -85,17 +116,21 @@ fun aggregateWebMapTiles( chunkY, pos.surfaceIndex ) - (chunkPos to px).toKeyValue() + chunkPos } + .windowedBy( + SessionWindows.ofInactivityGapAndGrace( + WINDOW_INACTIVITY_DURATION, + WINDOW_INACTIVITY_DURATION, + ) + ) .aggregate( { WebMapTileChunkPixelsAcc() }, - /* adder */ { _: WebMapTileChunkPosition, newValue: WebMapTilePixel, acc: WebMapTileChunkPixelsAcc -> - acc.apply { pixels.add(newValue) } + acc + newValue }, - /* subtractor */ - { _: WebMapTileChunkPosition, oldValue: WebMapTilePixel, acc: WebMapTileChunkPixelsAcc -> - acc.apply { pixels.minus(oldValue) } + { _, aggOne: WebMapTileChunkPixelsAcc, aggTwo: WebMapTileChunkPixelsAcc -> + aggOne + aggTwo }, namedAs("web-map-tile-colours-into-$WEB_MAP_IMAGE_TILE_SIZE-chunks"), materializedAs( @@ -105,20 +140,34 @@ fun aggregateWebMapTiles( ) ) .suppress( - Suppressed.untilTimeLimit( - Duration.ofSeconds(30), - Suppressed.BufferConfig - .maxRecords(30) -// .withMaxBytes(31457280 ) // 30MB - .emitEarlyWhenFull() - ).withName("web-map-tile-aggregate-debounce") + Suppressed.untilWindowCloses( + Suppressed.BufferConfig.unbounded() + ).withName("chunked-pixels-debounce") ) - return webMapTileChunkAggregate + + // merge windows + val chunkedPixels: KTable = + chunkedPixelsWindowed + .groupBy( + groupedAs("merge-chunked-pixels.group-keys", kxsBinary.serde(), kxsBinary.serde()) + ) { a: Windowed, b: WebMapTileChunkPixelsAcc -> + (a.key() to b).toKeyValue() + } + .reduce( + /* adder */ + { pixels1, pixels2 -> pixels1 + pixels2 }, + /* subtractor */ + { pixels1, pixels2 -> pixels1 - pixels2 }, + namedAs("merge-chunked-pixels.reduce-values"), + materializedAs("merge-chunked-pixels.reduce-values.store", kxsBinary.serde(), kxsBinary.serde()) + ) + + return chunkedPixels .mapValues( "finalise-web-map-tile-colour-chunk-aggregation", materializedAs("web-map-tile-colour-chunks", kxsBinary.serde(), kxsBinary.serde()) - ) { _, v -> + ) { _: WebMapTileChunkPosition, v: WebMapTileChunkPixelsAcc -> WebMapTileChunkPixels(v.pixels) } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt index a1011b2..942c517 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt @@ -3,28 +3,24 @@ package dev.adamko.kafkatorio.processor.topology import com.sksamuel.scrimage.ImmutableImage import com.sksamuel.scrimage.color.RGBColor import com.sksamuel.scrimage.nio.PngWriter +import dev.adamko.kafkatorio.events.schema.Colour +import dev.adamko.kafkatorio.events.schema.MapTilePosition import dev.adamko.kotka.extensions.tables.toStream import java.awt.Color import java.awt.image.BufferedImage import java.io.File -import java.time.Duration import kotlin.math.abs import kotlin.math.roundToInt import org.apache.kafka.streams.kstream.KTable -import org.apache.kafka.streams.kstream.Suppressed +private val COLOUR_TRANSPARENT = RGBColor.fromAwt(Color(0f, 0f, 0f, 0f)) + fun saveTileImages( webMapTiles: KTable ) { webMapTiles - .suppress( - Suppressed.untilTimeLimit( - Duration.ofSeconds(30), - Suppressed.BufferConfig.maxRecords(30) - ).withName("save-tile-images-debounce") - ) .toStream("get-webmap-tile-updates") .foreach { position: WebMapTileChunkPosition, pixels: WebMapTileChunkPixels -> runCatching { @@ -42,7 +38,7 @@ fun saveTileImages( private fun saveMapTilesPng( chunkPosition: WebMapTileChunkPosition, - pixels: Set + pixels: Map, ) { val chunkOriginX: Int = chunkPosition.x * chunkPosition.chunkSize // - 1 val chunkOriginY: Int = chunkPosition.y * chunkPosition.chunkSize // - 1 @@ -52,21 +48,21 @@ private fun saveMapTilesPng( ImmutableImage.filled( chunkPosition.chunkSize, chunkPosition.chunkSize, - Color.BLACK, + COLOUR_TRANSPARENT.awt(), BufferedImage.TYPE_INT_ARGB ) - pixels.forEach { pixel -> + pixels.forEach { (tilePosition, colour) -> val rgbColour = RGBColor( - pixel.mapColour.red.roundToInt(), - pixel.mapColour.green.roundToInt(), - pixel.mapColour.blue.roundToInt(), - pixel.mapColour.alpha.roundToInt(), + colour.red.roundToInt(), + colour.green.roundToInt(), + colour.blue.roundToInt(), + colour.alpha.roundToInt(), ) - val pixelX = abs(abs(pixel.tilePosition.x) - abs(chunkOriginX)) - val pixelY = abs(abs(pixel.tilePosition.y) - abs(chunkOriginY)) + val pixelX = abs(abs(tilePosition.x) - abs(chunkOriginX)) + val pixelY = abs(abs(tilePosition.y) - abs(chunkOriginY)) chunkImage.setColor( pixelX, From f38143dee949f80d5103e186dbe8b33bc79ae965 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 5 Feb 2022 12:20:51 +0100 Subject: [PATCH 175/629] fixing deserialisation, and options --- .../dev/adamko/kafkatorio/webmap/converters.kt | 6 ++---- .../kotlin/dev/adamko/kafkatorio/webmap/json.kt | 2 ++ .../kotlin/dev/adamko/kafkatorio/webmap/map.kt | 15 ++++++++------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt index 6f9662d..1177aa7 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt @@ -1,9 +1,7 @@ package dev.adamko.kafkatorio.webmap -import dev.adamko.kafkatorio.events.schema.Colour import dev.adamko.kafkatorio.events.schema.PlayerData -import io.kvision.maps.externals.leaflet.geo.LatLng import io.kvision.maps.Maps -import kotlin.math.roundToInt +import io.kvision.maps.externals.leaflet.geo.LatLng -fun PlayerData.latLng(): LatLng = Maps.L.latLng((position.y * -1) to position.x) +fun PlayerData.latLng(): LatLng = Maps.L.latLng((position.y * -1) / 2 to position.x / 2) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt index d1acf02..0bed951 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt @@ -1,7 +1,9 @@ package dev.adamko.kafkatorio.webmap +import dev.adamko.kafkatorio.events.schema.jsonMapperKafkatorio import kotlinx.serialization.json.Json val jsonMapper = Json { prettyPrint = true + serializersModule = jsonMapperKafkatorio.serializersModule } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index 14a3326..1fc21aa 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -1,10 +1,9 @@ package dev.adamko.kafkatorio.webmap -import io.kvision.maps.DefaultTileLayers -import io.kvision.maps.externals.leaflet.geo.CRS -import io.kvision.maps.externals.leaflet.geo.LatLng import io.kvision.maps.Maps import io.kvision.maps.Maps.Companion.L +import io.kvision.maps.externals.leaflet.geo.CRS +import io.kvision.maps.externals.leaflet.geo.LatLng import io.kvision.utils.px // @@ -39,15 +38,17 @@ fun createFactorioMap() = Maps { // maxZoom = 1 maxNativeZoom = 1 minNativeZoom = 1 + noWrap = true + updateWhenIdle = true + updateWhenZooming = true }.addTo(this) L.scale { + metric = true + }.addTo(this) - } - with(options) { - crs = CRS.Simple - } + options.crs = CRS.Simple } } From ae893b626963b01335bc59c10bda0dc53aea2e6a Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 5 Feb 2022 12:20:58 +0100 Subject: [PATCH 176/629] bump kafka-ui --- modules/infra-kafka-cluster/src/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infra-kafka-cluster/src/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml index e05f8c9..1d0d4b5 100644 --- a/modules/infra-kafka-cluster/src/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -20,7 +20,7 @@ services: - "9093:9093" kafka-ui: - image: provectuslabs/kafka-ui:0.3.2 + image: provectuslabs/kafka-ui:0.3.3 container_name: "kafka-ui" restart: "unless-stopped" networks: From d75233e71e7af3fe0c1c3631f91fdda03a9e4107 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 5 Feb 2022 12:21:11 +0100 Subject: [PATCH 177/629] experimenting with a custom debouncer --- .../processor/misc/DebounceProcessor.kt | 212 ++++++++++++++++++ .../processor/misc/SuppressProcessor.java | 89 ++++++++ .../processor/misc/DebounceProcessorTest.kt | 49 ++++ 3 files changed, 350 insertions(+) create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/SuppressProcessor.java create mode 100644 modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessorTest.kt diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt new file mode 100644 index 0000000..8598c46 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt @@ -0,0 +1,212 @@ +package dev.adamko.kafkatorio.processor.misc + +import dev.adamko.kotka.extensions.component1 +import dev.adamko.kotka.extensions.component2 +import dev.adamko.kotka.extensions.state.allAsSequence +import kotlin.coroutines.CoroutineContext +import kotlin.time.Duration +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancelChildren +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.runningFold +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import org.apache.kafka.common.serialization.Serde +import org.apache.kafka.streams.KeyValue +import org.apache.kafka.streams.processor.api.Processor +import org.apache.kafka.streams.processor.api.ProcessorContext +import org.apache.kafka.streams.processor.api.ProcessorSupplier +import org.apache.kafka.streams.processor.api.Record +import org.apache.kafka.streams.state.StoreBuilder +import org.apache.kafka.streams.state.Stores +import org.apache.kafka.streams.state.TimestampedKeyValueStore +import org.apache.kafka.streams.state.ValueAndTimestamp + + +class DebounceProcessor( + private val inactivityDuration: Duration, + private val recordsTimestampedStoreName: String, + coroutineDispatcher: CoroutineDispatcher = Dispatchers.Default, +) : + Processor, + CoroutineScope { + + override var coroutineContext: CoroutineContext = + SupervisorJob() + + coroutineDispatcher + + CoroutineName("DebounceProcessor") + + private lateinit var kafkaContext: ProcessorContext + private lateinit var recordsTimestampedStore: TimestampedKeyValueStore + + private val recordsFlow: MutableSharedFlow> = + MutableSharedFlow( + replay = 0, + extraBufferCapacity = Int.MAX_VALUE, + onBufferOverflow = BufferOverflow.DROP_OLDEST, + ) + + override fun init(context: ProcessorContext) { + this.kafkaContext = context + + this.coroutineContext += CoroutineName("DebounceProcessor-${context.applicationId()}-${context.taskId()}") + + recordsTimestampedStore = kafkaContext.getStateStore(recordsTimestampedStoreName) + + // start collecting records - create a debounce-timer for each record + recordsFlow + .runningFold(mapOf()) { acc, (k, createTask) -> + require(coroutineContext.isActive) + + // cancel any previously existing debounce task + acc[k]?.cancel() + + // add a new debounce task + when (createTask) { + true -> acc.plus(k to createDebounceTask(k)) + false -> acc.minus(k) + } + + }.launchIn(this) + + // re-initialise the flow from previously-stored records + launch { + recordsFlow.emitAll( + recordsTimestampedStore + .allAsSequence() + .map { keyValue -> + require(coroutineContext.isActive) + DebounceTaskInitializer(keyValue) + } + .asFlow() + ) + } + } + + private fun createDebounceTask(key: K): Job { + return launch { + delay(inactivityDuration) + val (value, timestamp) = recordsTimestampedStore.get(key) + if (coroutineContext.isActive) { + kafkaContext.forward(Record(key, value, timestamp)) + } + } + } + + override fun process(record: Record) { + launch { + recordsTimestampedStore.put( + record.key(), + ValueAndTimestamp.make(record.value(), record.timestamp()) + ) + recordsFlow.emit(DebounceTaskInitializer(record)) + } + } + + override fun close() { + coroutineContext.cancelChildren(CancellationException("processor go sleepy bye bye")) + } + +} + +internal data class DebounceTaskInitializer( + val key: K, + val createTask: Boolean, +) { + constructor(keyValue: KeyValue) : this(keyValue.key, keyValue.value != null) + constructor(record: Record) : this(record.key(), record.value() != null) +} + + +fun debounceProcessor( + inactivityDuration: Duration, + storeName: String, + keySerde: Serde, + valueSerde: Serde, +): ProcessorSupplier = + object : ProcessorSupplier { + + override fun get(): Processor = DebounceProcessor(inactivityDuration, storeName) + + override fun stores(): Set> = setOf( + Stores.timestampedKeyValueStoreBuilder( + Stores.persistentTimestampedKeyValueStore(storeName), + keySerde, + valueSerde, + ) + ) + + } + + +//class SuppressProcessor( +// private val storeName: String, +// private val tickDuration: Duration = 1.seconds, +// private val debounceDuration: Duration, +//) : Processor { +// +// private lateinit var context: ProcessorContext +// +// private lateinit var stateStore: TimestampedKeyValueStore +// +// override fun init(context: ProcessorContext) { +// +// this.context = context +// +// stateStore = context.getStateStore(storeName) as TimestampedKeyValueStore +// +// context.schedule( +// tickDuration.toJavaDuration(), +// PunctuationType.WALL_CLOCK_TIME, +// ::punctuate, +// ) +// } +// +// override fun process(record: Record) { +// +// val (key, newVal) = record +// +// val storedVal: V? = stateStore[key]?.value() +// +// val cachedVal = ValueAndTimestamp.make( +// storedVal ?: newVal, +// System.currentTimeMillis() +// ) +// +// stateStore.put(key, cachedVal) +// +//// val newTimestamp = if (storedVal == null) System.currentTimeMillis() else storedTimestamp +//// stateStore.put(key, ValueAndTimestamp.make(storedVal, newTimestamp)) +// } +// +// private fun punctuate(currentTimestamp: Long) { +// +// stateStore.all().use { iterator -> +// iterator.forEach { record: KeyValue> -> +// +// val (k, v, storedTimestamp) = record +// +// if (currentTimestamp - storedTimestamp > debounceDuration.inWholeMilliseconds) { +// +// context.forward(Record(k, v, storedTimestamp)) +// +// stateStore.delete(k) +// } +// +// } +// } +// } +// +//} +// diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/SuppressProcessor.java b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/SuppressProcessor.java new file mode 100644 index 0000000..06d3ec8 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/SuppressProcessor.java @@ -0,0 +1,89 @@ +package dev.adamko.kafkatorio.processor.misc; + +import java.time.Duration; +import org.apache.kafka.streams.KeyValue; +import org.apache.kafka.streams.processor.PunctuationType; +import org.apache.kafka.streams.processor.api.Processor; +import org.apache.kafka.streams.processor.api.ProcessorContext; +import org.apache.kafka.streams.processor.api.Record; +import org.apache.kafka.streams.state.TimestampedKeyValueStore; +import org.apache.kafka.streams.state.ValueAndTimestamp; + +/** + * THIS PROCESSOR IS UNTESTED + *
+ * This processor mirrors the source, but waits for an inactivity gap before forwarding records. + *
+ * The suppression is key based. Newer values will replace previous values, and reset the inactivity + * gap. + */ +public class SuppressProcessor implements Processor { + + private final String storeName; + private final Duration debounceCheckInterval; + private final long suppressTimeoutMillis; + + private TimestampedKeyValueStore stateStore; + private ProcessorContext context; + + /** + * @param storeName The name of the {@link TimestampedKeyValueStore} which will hold + * records while they are being debounced. + * @param suppressTimeout The duration of inactivity before records will be forwarded. + * @param debounceCheckInterval How regularly all records will be checked to see if they are + * eligible to be forwarded. The interval should be shorter than + * {@code suppressTimeout}. + */ + public SuppressProcessor( + String storeName, + Duration suppressTimeout, + Duration debounceCheckInterval + ) { + this.storeName = storeName; + this.suppressTimeoutMillis = suppressTimeout.toMillis(); + this.debounceCheckInterval = debounceCheckInterval; + } + + @Override + public void init(ProcessorContext context) { + this.context = context; + + stateStore = context.getStateStore(storeName); + + context.schedule(debounceCheckInterval, PunctuationType.WALL_CLOCK_TIME, this::punctuate); + } + + @Override + public void process(Record record) { + + final var key = record.key(); + final var value = record.value(); + + final var storedRecord = stateStore.get(key); + + final var isNewRecord = storedRecord == null; + + final var timestamp = isNewRecord ? System.currentTimeMillis() : storedRecord.timestamp(); + + stateStore.put(key, ValueAndTimestamp.make(value, timestamp)); + } + + private void punctuate(long timestamp) { + try (var iterator = stateStore.all()) { + while (iterator.hasNext()) { + KeyValue> storedRecord = iterator.next(); + if (timestamp - storedRecord.value.timestamp() > suppressTimeoutMillis) { + + final var record = new Record<>( + storedRecord.key, + storedRecord.value.value(), + storedRecord.value.timestamp() + ); + + context.forward(record); + stateStore.delete(storedRecord.key); + } + } + } + } +} diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessorTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessorTest.kt new file mode 100644 index 0000000..b7ff622 --- /dev/null +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessorTest.kt @@ -0,0 +1,49 @@ +package dev.adamko.kafkatorio.processor.misc + +import io.kotest.core.spec.style.FunSpec +import io.kotest.core.spec.style.Test +import io.mockk.every +import io.mockk.mockk +import kotlin.time.Duration.Companion.minutes +import org.apache.kafka.common.serialization.Serdes +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.Topology +import org.apache.kafka.streams.state.KeyValueIterator +import org.apache.kafka.streams.state.TimestampedKeyValueStore + +class DebounceProcessorTest : FunSpec({ + + +}) { + @Test + fun blah() { + + + val topology = Topology() + + topology.addProcessor( + "blah", + debounceProcessor( + 1.minutes, + "asdasda", + Serdes.String(), + Serdes.String() + ) + ) + + +// val streamsBuilder = StreamsBuilder() +// +// streamsBuilder +// .stream("input-topic") +// .process( +// debounceProcessor( +// 1.minutes, +// "input-topic-debounce-store", +// Serdes.String(), +// Serdes.String(), +// ), +// ) + + } +} From ea0bfb350bb5fc1da31651e3ee2991f8b90b302e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 6 Feb 2022 21:05:37 +0100 Subject: [PATCH 178/629] - MapTile/LuaTile no longer a FactorioObjectData (it doesn't get sent as a packet) - trying to optimise the topology so it's faster... almost there but the records are now too large - map tile pngs, multiple zoom levels - use coroutines for faster map tiles --- .../kafkatorio-schema/object-data.d.ts | 8 +- .../generated/kafkatorio-schema/schema.d.ts | 6 + .../events/schema/factorioLuaObjects.kt | 12 +- modules/events-server/build.gradle.kts | 6 +- .../processor/KafkatorioTopology.kt | 36 ++-- .../processor/topology/factorioGameState.kt | 127 +++++++++++ .../processor/topology/factorioMapTiles.kt | 12 +- .../topology/factorioServerPackets.kt | 87 ++++---- .../processor/topology/flowMapTiles.kt | 198 ++++++++++++++++++ .../kafkatorio/processor/topology/model.kt | 27 +++ .../processor/topology/playerUpdates.kt | 2 +- .../processor/topology/prototypes.kt | 2 +- .../processor/topology/webMapTileAggregate.kt | 2 +- .../processor/topology/webMapTiles.kt | 9 +- .../dev/adamko/kafkatorio/webmap/map.kt | 2 +- .../adamko/kafkatorio/webmap/websockets.kt | 2 +- 16 files changed, 441 insertions(+), 97 deletions(-) create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts index 4d5583a..4585cfa 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts @@ -1,6 +1,6 @@ // Generated by TypeScriptGenerator - do not edit this file manually -type ObjectName = "LuaPlayer" | "LuaEntity" | "LuaSurface" | "MapChunk" | "LuaTile" | "LuaTiles" | "ConsoleChatMessage"; +type ObjectName = "LuaPlayer" | "LuaEntity" | "LuaSurface" | "MapChunk" | "LuaTiles" | "ConsoleChatMessage"; interface FactorioObjectData { objectName: ObjectName; @@ -37,12 +37,6 @@ interface SurfaceData extends FactorioObjectData { objectName: ObjectName; } -interface MapTile extends FactorioObjectData { - objectName: ObjectName; - position: MapTilePosition; - prototypeName: string; -} - interface MapTiles extends FactorioObjectData { objectName: ObjectName; surfaceIndex: int; diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts index ad34892..da32cea 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts @@ -41,3 +41,9 @@ interface MapChunkPosition { x: int; y: int; } + +interface MapTile { + objectName: string; + position: MapTilePosition; + prototypeName: string; +} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt index d142fbb..ac89d09 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -38,7 +38,7 @@ sealed class FactorioObjectData { LuaEntity, LuaSurface, MapChunk, - LuaTile, + // LuaTile, LuaTiles, ConsoleChatMessage, } @@ -66,7 +66,7 @@ object FactorioObjectDataJsonSerializer : JsonContentPolymorphicSerializer EntityData.serializer() FactorioObjectData.ObjectName.LuaSurface -> SurfaceData.serializer() FactorioObjectData.ObjectName.MapChunk -> MapChunk.serializer() - FactorioObjectData.ObjectName.LuaTile -> MapTile.serializer() +// FactorioObjectData.ObjectName.LuaTile -> MapTile.serializer() FactorioObjectData.ObjectName.LuaTiles -> MapTiles.serializer() FactorioObjectData.ObjectName.ConsoleChatMessage -> ConsoleChatMessage.serializer() } @@ -141,9 +141,11 @@ data class MapTiles( data class MapTile( val prototypeName: String, val position: MapTilePosition, -) : FactorioObjectData() { - @EncodeDefault - override val objectName = ObjectName.LuaTile +) +// : FactorioObjectData() +{ + // @EncodeDefault + val objectName: String = "" } @Serializable diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 64c0fcf..7e0bebf 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -17,7 +17,7 @@ val projectId: String by project.extra @Suppress("UnstableApiUsage") // platform + version-catalog is incubating dependencies { - implementation("org.apache.kafka:kafka-streams:3.0.0") + implementation("org.apache.kafka:kafka-streams:3.1.0") implementation(projects.modules.eventsSchema) @@ -38,8 +38,8 @@ dependencies { implementation("com.sksamuel.scrimage:scrimage-core:4.0.24") -// val kotkaVersion = "0.0.11" - val kotkaVersion = "store-iterators-SNAPSHOT" + val kotkaVersion = "v0.0.12" +// val kotkaVersion = "store-iterators-SNAPSHOT" implementation("com.github.adamko-dev.kotka-streams:kotka-streams:$kotkaVersion") { isChanging = true } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 89e9438..9049e61 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -1,22 +1,14 @@ package dev.adamko.kafkatorio.processor -import dev.adamko.kafkatorio.events.schema.Colour -import dev.adamko.kafkatorio.events.schema.MapTile -import dev.adamko.kafkatorio.processor.topology.PrototypeName -import dev.adamko.kafkatorio.processor.topology.TileUpdateRecordKey -import dev.adamko.kafkatorio.processor.topology.WebMapTileChunkPixels -import dev.adamko.kafkatorio.processor.topology.WebMapTileChunkPosition -import dev.adamko.kafkatorio.processor.topology.aggregateWebMapTiles -import dev.adamko.kafkatorio.processor.topology.allMapTilesTable +import dev.adamko.kafkatorio.processor.topology.buildFactorioServerMap +import dev.adamko.kafkatorio.processor.topology.factorioServerPacketStream import dev.adamko.kafkatorio.processor.topology.playerUpdatesToWsServer -import dev.adamko.kafkatorio.processor.topology.saveTileImages -import dev.adamko.kafkatorio.processor.topology.splitFactorioServerLog -import dev.adamko.kafkatorio.processor.topology.tilePrototypeColourTable +import dev.adamko.kafkatorio.processor.topology.saveMapTiles +import dev.adamko.kafkatorio.processor.topology.splitFactorioServerPacketStream import java.time.Duration import org.apache.kafka.streams.KafkaStreams import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.TopologyDescription -import org.apache.kafka.streams.kstream.KTable class KafkatorioTopology( @@ -30,17 +22,25 @@ class KafkatorioTopology( fun build() { - splitFactorioServerLog(builder) + val packets = factorioServerPacketStream(builder) + + splitFactorioServerPacketStream(packets) playerUpdatesToWsServer(websocketServer, builder) - val allMapTilesTable: KTable = allMapTilesTable(builder) - val tilePrototypeColourTable: KTable = tilePrototypeColourTable(builder) + val serverMapDataTable = buildFactorioServerMap(packets) - val webMapTiles: KTable = - aggregateWebMapTiles(allMapTilesTable, tilePrototypeColourTable) + saveMapTiles(serverMapDataTable) - saveTileImages(webMapTiles) + + // the old way... +// val allMapTilesTable: KTable = allMapTilesTable(builder) +// val tilePrototypeColourTable: KTable = tilePrototypeColourTable(builder) +// +// val webMapTiles: KTable = +// aggregateWebMapTiles(allMapTilesTable, tilePrototypeColourTable) +// +// saveTileImages(webMapTiles) val topology = builder.build() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt new file mode 100644 index 0000000..7e9df42 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt @@ -0,0 +1,127 @@ +package dev.adamko.kafkatorio.processor.topology + +import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate +import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.FactorioPrototypes +import dev.adamko.kafkatorio.events.schema.KafkatorioPacket +import dev.adamko.kafkatorio.events.schema.MapChunk +import dev.adamko.kafkatorio.events.schema.MapTilePosition +import dev.adamko.kafkatorio.events.schema.MapTilePrototype +import dev.adamko.kafkatorio.events.schema.MapTiles +import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kotka.extensions.groupedAs +import dev.adamko.kotka.extensions.materializedAs +import dev.adamko.kotka.extensions.materializedWith +import dev.adamko.kotka.extensions.streams.aggregate +import dev.adamko.kotka.extensions.tables.mapValues +import dev.adamko.kotka.kxs.serde +import kotlinx.serialization.Serializable +import org.apache.kafka.streams.kstream.KStream +import org.apache.kafka.streams.kstream.KTable + + +@Serializable +data class FactorioServerMap( + val serverId: FactorioServerId, + val tilePrototypes: Map, + val surfaces: Map, +) + + +@Serializable +data class FactorioMapSurface( + val index: SurfaceIndex, + val tiles: Map, +) + +/** Aggregate [KafkatorioPacket]s into a single [FactorioServerMap] (per [serverId][FactorioServerId]). */ +fun buildFactorioServerMap( + factorioServerPacketStream: KStream +): KTable { + + return factorioServerPacketStream + .groupByKey( + groupedAs("factorio-server-map-data-grouping", jsonMapper.serde(), jsonMapper.serde()) + ) + .aggregate( + "factorio-server-map-data-aggregate", + materializedAs("factorio-server-map-aggregate-store", kxsBinary.serde(), kxsBinary.serde()), + { FactorioServerMapAggregator() }, + ) { _: FactorioServerId, packet: KafkatorioPacket, aggregate: FactorioServerMapAggregator -> + aggregate + packet + } + .mapValues( + "finalise-factorio-server-map-aggregate", + materializedWith(kxsBinary.serde(), kxsBinary.serde()) + ) { readOnlyKey, aggregate -> + + val surfaces = aggregate.surfaces.mapValues { (_, surface) -> + FactorioMapSurface(surface.index, surface.tiles) + } + + FactorioServerMap(readOnlyKey, aggregate.tilePrototypes, surfaces) + } + +} + + +@Serializable +private data class FactorioServerMapAggregator( + val tilePrototypes: MutableMap = mutableMapOf(), + val surfaces: MutableMap = mutableMapOf(), +) { + + operator fun plus(packet: KafkatorioPacket): FactorioServerMapAggregator { + return when (packet) { + is FactorioEvent -> { + when (val data = packet.data) { + is MapChunk -> plus(data) + is MapTiles -> plus(data) +// is MapTile -> {} // hmmm... no surface index + else -> this + } + } + is FactorioPrototypes -> plus(packet) + is FactorioConfigurationUpdate -> this + } + } + + operator fun plus(mapTiles: MapTiles): FactorioServerMapAggregator { +// println("FactorioServerMapAggregator: adding ${mapTiles.tiles.size} MapTiles from surface ${mapTiles.surfaceIndex}") + + val surfaceIndex = SurfaceIndex(mapTiles.surfaceIndex) + + val surface = surfaces.getOrPut(surfaceIndex) { FactorioMapSurfaceAggregator(surfaceIndex) } + + val surfaceTiles = mapTiles.tiles.associate { it.position to PrototypeName(it.prototypeName) } + surface.tiles.putAll(surfaceTiles) + + return this + } + + operator fun plus(mapChunk: MapChunk): FactorioServerMapAggregator { +// println("FactorioServerMapAggregator: adding mapChunk ${mapChunk.position}") + return plus(mapChunk.tiles) + } + + operator fun plus(packet: FactorioPrototypes): FactorioServerMapAggregator { +// println("FactorioServerMapAggregator: adding FactorioPrototypes") + + val packetPrototypes = packet.prototypes + .filterIsInstance() + .associateBy { PrototypeName(it.name) } + + tilePrototypes.putAll(packetPrototypes) + + return this + } + +} + + +@Serializable +private data class FactorioMapSurfaceAggregator( + val index: SurfaceIndex, + val tiles: MutableMap = mutableMapOf(), +) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt index 6a6ee07..97242dc 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt @@ -35,24 +35,24 @@ fun allMapTilesTable( builder: StreamsBuilder ): KTable { - val luaTilesUpdatesStream: KStream = - builder.stream( + val luaTilesUpdatesStream: KStream = + builder.stream( "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", consumedAs("consume-map-tiles-packets", jsonMapper.serde(), jsonMapper.serde()) ) - .filter("events.filter.map-tiles") { _: FactorioPacketKey, event: FactorioEvent -> + .filter("events.filter.map-tiles") { _: FactorioServerId, event: FactorioEvent -> event.data is MapTiles } .mapValues("events.extract-map-tiles") { _, event: FactorioEvent -> (event.data as? MapTiles)!! } - val chunkTilesUpdateStream: KStream = - builder.stream( + val chunkTilesUpdateStream: KStream = + builder.stream( "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", consumedAs("consume-map-chunk-packets", jsonMapper.serde(), jsonMapper.serde()) ) - .filter("events.filter.map-chunks") { _: FactorioPacketKey, event: FactorioEvent -> + .filter("events.filter.map-chunks") { _: FactorioServerId, event: FactorioEvent -> event.data is MapChunk } .mapValues("events.extract-map-chunks") { _, event: FactorioEvent -> diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt index 229c3f4..ea7459d 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt @@ -1,17 +1,9 @@ package dev.adamko.kafkatorio.processor.topology -import dev.adamko.kafkatorio.events.schema.ConsoleChatMessage -import dev.adamko.kafkatorio.events.schema.EntityData import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate import dev.adamko.kafkatorio.events.schema.FactorioEvent import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -import dev.adamko.kafkatorio.events.schema.MapChunk -import dev.adamko.kafkatorio.events.schema.MapTile -import dev.adamko.kafkatorio.events.schema.MapTiles -import dev.adamko.kafkatorio.events.schema.PlayerData -import dev.adamko.kafkatorio.events.schema.SurfaceData -import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition import dev.adamko.kafkatorio.processor.KafkatorioTopology import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kotka.extensions.consumedAs @@ -19,25 +11,18 @@ import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.streams.map import dev.adamko.kotka.extensions.streams.to import dev.adamko.kotka.kxs.serde -import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString import org.apache.kafka.common.serialization.Serdes import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.kstream.KStream import org.apache.kafka.streams.processor.RecordContext -@Serializable -data class FactorioPacketKey( - val serverId: FactorioServerId, - /** arbitrary distinctive key */ - val key: String, -) - -fun splitFactorioServerLog( +fun factorioServerPacketStream( builder: StreamsBuilder = StreamsBuilder(), -) { +): KStream { - builder.stream( + return builder.stream( KafkatorioTopology.sourceTopic, consumedAs( "read-raw-packets-from-server", @@ -46,18 +31,22 @@ fun splitFactorioServerLog( ) ) .map("decode-packets") { serverId: String, value: String -> -// println("Mapping $readOnlyKey:$value") val packet = jsonMapper.decodeFromString(value) - val key: String = createPacketKey(packet) - FactorioPacketKey(FactorioServerId(serverId), key) to packet + FactorioServerId(serverId) to packet } +} + +fun splitFactorioServerPacketStream( + factorioServerPacketStream: KStream +) { + factorioServerPacketStream .to( producedAs( "split-server-log", jsonMapper.serde(), jsonMapper.serde(), ) - ) { _: FactorioPacketKey, value: KafkatorioPacket, _: RecordContext -> + ) { _: FactorioServerId, value: KafkatorioPacket, _: RecordContext -> // println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") when (value) { is FactorioEvent -> @@ -68,28 +57,34 @@ fun splitFactorioServerLog( "kafkatorio.${value.packetType.name}.all" } } - } -private fun createPacketKey(packet: KafkatorioPacket): String { - - return when (packet) { - is FactorioEvent -> factorioEventKey(packet) - is FactorioConfigurationUpdate, - is FactorioPrototypes -> packet.hashCode().toString() - } -} - -private fun factorioEventKey(event: FactorioEvent): String { - val id: String = when (val data = event.data) { - is ConsoleChatMessage -> data.authorPlayerIndex?.toString() - is EntityData -> data.type - is MapChunk -> data.position.toString() - is MapTile -> data.position.toString() - is MapTiles -> data.tiles.firstOrNull()?.position?.toMapChunkPosition()?.toString() - is PlayerData -> (data.characterUnitNumber?.toString() ?: data.name) - is SurfaceData -> data.index.toString() - } ?: event.tick.toString() - - return id -} +//@Serializable +//data class FactorioPacketKey( +// val serverId: FactorioServerId, +// /** arbitrary distinctive key */ +// val key: String, +//) +// +//private fun createPacketKey(packet: KafkatorioPacket): String { +// +// return when (packet) { +// is FactorioEvent -> factorioEventKey(packet) +// is FactorioConfigurationUpdate, +// is FactorioPrototypes -> packet.hashCode().toString() +// } +//} +// +//private fun factorioEventKey(event: FactorioEvent): String { +// val id: String = when (val data = event.data) { +// is ConsoleChatMessage -> data.authorPlayerIndex?.toString() +// is EntityData -> data.type +// is MapChunk -> data.position.toString() +//// is MapTile -> data.position.toString() +// is MapTiles -> data.tiles.firstOrNull()?.position?.toMapChunkPosition()?.toString() +// is PlayerData -> (data.characterUnitNumber?.toString() ?: data.name) +// is SurfaceData -> data.index.toString() +// } ?: event.tick.toString() +// +// return id +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt new file mode 100644 index 0000000..2aabdf4 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt @@ -0,0 +1,198 @@ +package dev.adamko.kafkatorio.processor.topology + +import com.sksamuel.scrimage.ImmutableImage +import com.sksamuel.scrimage.ScaleMethod +import com.sksamuel.scrimage.nio.PngWriter +import dev.adamko.kafkatorio.events.schema.Colour +import dev.adamko.kafkatorio.events.schema.MapChunkPosition +import dev.adamko.kafkatorio.events.schema.MapTilePosition +import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition +import java.awt.image.BufferedImage +import java.io.File +import kotlin.math.abs +import kotlin.time.Duration.Companion.seconds +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.conflate +import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.flow.flatMapMerge +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.mapLatest +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import org.apache.kafka.streams.kstream.KTable + + +private const val WEB_MAP_TILE_SIZE_PX = 256 + +private val cScope = CoroutineScope( + Dispatchers.Default + SupervisorJob() + CoroutineName("f-server-map-updates") +) + +/** A bridge between Kafka and Kotlin */ +private val serverMapDataFlow: MutableStateFlow = MutableStateFlow(null) + + +fun saveMapTiles( + serverMapTable: KTable +) { + + serverMapTable + .toStream() + .foreach { _, value -> + runBlocking(Dispatchers.Default) { + serverMapDataFlow.emit(value) + } + } + + cScope.launch { + println("launching serverMapDataFlow merging") + + + serverMapDataFlow + .filterNotNull() + + serverMapDataFlow + .filterNotNull() + .conflate() +// .transform { serverMapData -> + .flatMapMerge(10) { serverMapData -> + println("flatMapMerge serverMapData ${serverMapData.serverId}, surfaces ${serverMapData.surfaces.keys}") + + val prototypes = serverMapData.tilePrototypes + + serverMapData + .surfaces + .values +// .forEach { surfaceData -> + .asFlow() + .flatMapMerge(10) { surfaceData -> + println("flatMapMerge surfaceData ${surfaceData.index}") + + // get all tile colours for the surface + val surfaceTileColours = surfaceData.tiles + .entries + .mapNotNull { (tilePosition, prototypeName) -> + prototypes[prototypeName]?.let { prototype -> + tilePosition to prototype.mapColour + } + } + println("surfaceTileColours.size ${surfaceTileColours.size}") + + // split a surface into chunks, per zoom-level + ZoomLevel.values +// .forEach { zoom -> + .asFlow() + .flatMapMerge(10) { zoom -> + println("flatMapMerge zoom $zoom") + + surfaceTileColours + .groupBy { (tilePosition, _) -> + tilePosition.toMapChunkPosition(zoom.chunkSize) + } + .entries +// .forEach { (chunkPosition, tileColours) -> + .asFlow() + .mapLatest { (chunkPosition, tileColours) -> + println("mapLatest chunkPosition $chunkPosition") + + // mapLatest + delay = an alternative to debounce-per-key? + delay(30.seconds) + + println("emitting ChunkData $chunkPosition") + + ChunkData( + surfaceData.index, + zoom, + chunkPosition, + tileColours.toMap() + ) + } + } + } + } + .onEach { chunkData -> + + println("starting to save chunkData ${chunkData.chunkPosition}...") + + val chunkImageFile = File(chunkData.filename.value) + if (chunkImageFile.parentFile.mkdirs()) { + println("created new map tile parentFile directory ${chunkImageFile.absolutePath}") + } + + val image = + createMapTileImage(chunkData.chunkPosition, chunkData.tileColours, chunkData.zoomLevel) + + println("saving map tile $chunkImageFile") + val savedTile = image.output(PngWriter.NoCompression, chunkImageFile) + println("savedTile: $savedTile") + + } + .launchIn(this) + } +} + + +@JvmInline +private value class TilePngFilename( + val value: String, +) { + + constructor( + surfaceIndex: SurfaceIndex, + zoom: Int, + chunkX: Int, + chunkY: Int, + ) : this("src/main/resources/kafkatorio-web-map/s${surfaceIndex.index}/z$zoom/x${chunkX}/y${chunkY}.png") + +} + + +private data class ChunkData( + val surfaceIndex: SurfaceIndex, + val zoomLevel: ZoomLevel, + val chunkPosition: MapChunkPosition, + val tileColours: Map, +) { + val filename = TilePngFilename(surfaceIndex, zoomLevel.level, chunkPosition.x, chunkPosition.y) +} + +private fun createMapTileImage( + chunkPosition: MapChunkPosition, + chunkColours: Map, + z: ZoomLevel +): ImmutableImage { + + + val chunkImage = ImmutableImage.filled( + z.chunkSize, + z.chunkSize, + COLOUR_TRANSPARENT.awt(), + BufferedImage.TYPE_INT_ARGB + ) + + val chunkOriginX: Int = chunkPosition.x * z.chunkSize + val chunkOriginY: Int = chunkPosition.y * z.chunkSize + + chunkColours.forEach { (tilePosition, colour) -> + + val rgbColour = colour.toRgbColor() + + val pixelX = abs(abs(tilePosition.x) - abs(chunkOriginX)) + val pixelY = abs(abs(tilePosition.y) - abs(chunkOriginY)) + + chunkImage.setColor( + pixelX, + pixelY, + rgbColour + ) + } + + return chunkImage.scaleTo(WEB_MAP_TILE_SIZE_PX, WEB_MAP_TILE_SIZE_PX, ScaleMethod.Progressive) +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt index fb785c6..4f67bc5 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt @@ -2,9 +2,11 @@ package dev.adamko.kafkatorio.processor.topology import com.sksamuel.scrimage.color.RGBColor import dev.adamko.kafkatorio.events.schema.Colour +import kotlin.math.pow import kotlin.math.roundToInt import kotlinx.serialization.Serializable + @Serializable @JvmInline value class SurfaceIndex( @@ -13,12 +15,14 @@ value class SurfaceIndex( override fun toString() = "$index" } + @JvmInline @Serializable value class FactorioServerId(val id: String) { override fun toString() = id } + fun Colour.toRgbColor(): RGBColor { return RGBColor( red.roundToInt(), @@ -27,3 +31,26 @@ fun Colour.toRgbColor(): RGBColor { alpha.roundToInt(), ) } + + +enum class ZoomLevel( + val level: Int +) { + ZOOM_0(0), + ZOOM_1(1), + ZOOM_2(2), + ZOOM_3(3), + ZOOM_4(4), + ZOOM_5(5), + ; + + val chunkSize: Int = 2f.pow(10 - level).roundToInt() + + init { + require(chunkSize > 0) { "chunkSize must be positive" } + } + + companion object { + val values: List = values().asList() // better performance, KT-48872 + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt index 0843190..010ded3 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt @@ -14,7 +14,7 @@ fun playerUpdatesToWsServer( websocketServer: WebsocketServer, builder: StreamsBuilder = StreamsBuilder(), ) { - builder.stream( + builder.stream( "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaPlayer}", consumedAs("stream-player-updates-for-ws-server", jsonMapper.serde(), jsonMapper.serde()) ) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index 13e9ae1..30b8839 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -49,7 +49,7 @@ value class PrototypeName(val name: String) { /** Get the [Colour] of each [MapTilePrototype] */ fun tilePrototypeColourTable(builder: StreamsBuilder): KTable { - return builder.stream( + return builder.stream( "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", consumedAs( "consume-all-prototypes-packets", diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt index 9f6115e..1916e55 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt @@ -108,7 +108,7 @@ fun aggregateWebMapTiles( kxsBinary.serde(), kxsBinary.serde(), ) - ) { pos: TileUpdateRecordKey, px: WebMapTilePixel -> + ) { pos: TileUpdateRecordKey, _: WebMapTilePixel -> val (chunkX, chunkY) = pos.tilePosition.toMapChunkPosition(WEB_MAP_IMAGE_TILE_SIZE) val chunkPos = WebMapTileChunkPosition( WEB_MAP_IMAGE_TILE_SIZE, diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt index 942c517..e5f91c8 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt @@ -14,7 +14,7 @@ import kotlin.math.roundToInt import org.apache.kafka.streams.kstream.KTable -private val COLOUR_TRANSPARENT = RGBColor.fromAwt(Color(0f, 0f, 0f, 0f)) +val COLOUR_TRANSPARENT = RGBColor.fromAwt(Color(0f, 0f, 0f, 0f)) fun saveTileImages( webMapTiles: KTable @@ -54,12 +54,7 @@ private fun saveMapTilesPng( pixels.forEach { (tilePosition, colour) -> - val rgbColour = RGBColor( - colour.red.roundToInt(), - colour.green.roundToInt(), - colour.blue.roundToInt(), - colour.alpha.roundToInt(), - ) + val rgbColour = colour.toRgbColor() val pixelX = abs(abs(tilePosition.x) - abs(chunkOriginX)) val pixelY = abs(abs(tilePosition.y) - abs(chunkOriginY)) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index 1fc21aa..934ebb6 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -36,7 +36,7 @@ fun createFactorioMap() = Maps { tms = true // minZoom = -2 // maxZoom = 1 - maxNativeZoom = 1 + maxNativeZoom = 5 minNativeZoom = 1 noWrap = true updateWhenIdle = true diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt index 2030fe5..ff1d9f1 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -46,7 +46,7 @@ class WebsocketService( is ConsoleChatMessage, is EntityData, is MapChunk, - is MapTile, +// is MapTile, is SurfaceData, is MapTiles -> { } From bdb2d9577fbd7e3cdade96e4971e85dd301d5b80 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 8 Feb 2022 01:35:52 +0100 Subject: [PATCH 179/629] so close to working performantly.... just the tiles are transparent??? - bump some versions - MapTile no longer has objectName field - fix nulls/optional fields in FactorioConfigurationUpdate - use bytes to encode rgba colours - waaaayyyy smaller - increase Kafka record size to ~10mb --- build.gradle.kts | 2 +- gradle/libs.versions.toml | 8 +- .../generated/kafkatorio-schema/schema.d.ts | 1 - .../main/typescript/main/events/converters.ts | 2 - .../main/typescript/main/events/handlers.ts | 3 +- .../src/main/typescript/package-lock.json | 2 +- .../src/main/typescript/package.json | 2 +- .../events/schema/converters/colour.kt | 7 +- .../events/schema/factorioCommonData.kt | 38 ++- .../events/schema/factorioConfiguration.kt | 8 +- .../events/schema/factorioLuaObjects.kt | 11 - .../events/schema/FactorioEventTest.kt | 66 ++++- .../processor/KafkatorioTopology.kt | 18 +- .../processor/topology/factorioGameState.kt | 269 +++++++++++------- .../processor/topology/flowMapTiles.kt | 230 +++++++-------- .../kafkatorio/processor/topology/model.kt | 24 +- .../processor/topology/prototypes.kt | 89 +++--- .../processor/topology/webMapTiles.kt | 164 +++++------ .../kafkatorio/processor/misc/serdeSize.kt | 62 ++++ modules/infra-factorio-server/src/.env | 2 +- modules/infra-kafka-cluster/src/.env | 2 +- .../src/kafka-server.properties | 5 + .../infra-kafka-cluster/src/kafka.Dockerfile | 2 +- modules/web-map/build.gradle.kts | 6 +- 24 files changed, 619 insertions(+), 404 deletions(-) create mode 100644 modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt diff --git a/build.gradle.kts b/build.gradle.kts index bfae4e2..3cbf0c0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.2.7" +version = "0.2.8" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 625e7dd..a2ff04b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,17 +10,17 @@ kotlin = "1.6.10" ## libs ## camel-kafkaConnectors = "0.11.0" -http4k = "4.17.6.0" +http4k = "4.19.1.0" kafka = "3.1.0" kotlinx-serialization = "1.3.2" -kvision = "5.7.1" +kvision = "5.8.1" log4j2 = "2.14.1" qosLogback = "1.2.5" slf4j = "1.7.30" ## test ## junit = "5.8.2" -kotest = "5.0.1" +kotest = "5.1.0" ## infra ## factorio = "1.1.53" @@ -99,7 +99,7 @@ kotka = { group = "com.github.blueanvil", name = "kotka", versio ### test ### ############# -mockk = { group = "io.mockk", name = "mockk", version = "1.12.0" } +mockk = { group = "io.mockk", name = "mockk", version = "1.12.2" } ## junit ## junit-bom = { group = "org.junit", name = "junit-bom", version.ref = "junit" } diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts index da32cea..f1caf5a 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts @@ -43,7 +43,6 @@ interface MapChunkPosition { } interface MapTile { - objectName: string; position: MapTilePosition; prototypeName: string; } diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index 26b8e18..6314ba4 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -98,8 +98,6 @@ export namespace Converters { export function convertTile(tile: LuaTile): MapTile { return { - objectName: tile.object_name, - position: mapTilePosition(tile.position), prototypeName: tile.prototype.name, } diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index 1599367..569eb27 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -92,8 +92,7 @@ export function handleTilesUpdate( let convertedTiles: MapTile[] = updatedTiles.map((it) => { return { - objectName: "LuaTile", - position: it.position, + position: it.position, // TODO use converters for LuaTile prototypeName: newTileType.name, } }) diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index a8216e6..86d4591 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.7", + "version": "0.2.8", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index c9efe3b..3ce0e46 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.7", + "version": "0.2.8", "private": true, "scripts": { "build": "tstl", diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/colour.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/colour.kt index 88926b3..a4f6fba 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/colour.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/colour.kt @@ -23,7 +23,12 @@ fun Colour.toHexadecimal() = if (isPercentage()) { (alpha * 255).coerceIn(0f..255f), ) } else { - this + Colour( + red.coerceIn(0f..255f), + green.coerceIn(0f..255f), + blue.coerceIn(0f..255f), + alpha.coerceIn(0f..255f), + ) } fun Colour.toPercentage() = if (isPercentage()) { diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index f519e95..d6ffb50 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.events.schema +import dev.adamko.kafkatorio.events.schema.converters.toHexadecimal import kotlinx.serialization.EncodeDefault import kotlinx.serialization.Serializable @@ -56,7 +57,7 @@ data class MapBoundingBox( * Red, green, blue and alpha values, all in range `[0, 1]` or all in range `[0, 255]` if any * value is > 1. * - * All values here are optional. Colour channels default to 0, the alpha channel defaults to 1. + * All values here are optional. Colour channels default to `0`, the alpha channel defaults to `1`. */ @Serializable data class Colour( @@ -68,4 +69,39 @@ data class Colour( val blue: Float = 0f, @EncodeDefault val alpha: Float = 1f, +) { + + fun toHex() = toHexadecimal().let { + ColourHex( + it.red.toUInt().toUByte(), + it.green.toUInt().toUByte(), + it.blue.toUInt().toUByte(), + it.alpha.toUInt().toUByte(), + ) + } +} + + +/** Size-efficient version of [Colour] */ +@Serializable +data class ColourHex( + @EncodeDefault + val red: UByte = UByte.MIN_VALUE, + @EncodeDefault + val green: UByte = UByte.MIN_VALUE, + @EncodeDefault + val blue: UByte = UByte.MIN_VALUE, + @EncodeDefault + val alpha: UByte = UByte.MAX_VALUE, +) { + companion object { + val TRANSPARENT = ColourHex(0u, 0u, 0u, 0u) + } +} + + +@Serializable +data class MapTile( + val prototypeName: String, + val position: MapTilePosition, ) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt index 994656a..900e28d 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt @@ -16,13 +16,13 @@ data class FactorioConfigurationUpdate( @Serializable data class FactorioGameDataUpdate( - val oldVersion: String?, - val newVersion: String?, + val oldVersion: String? = null, + val newVersion: String? = null, ) @Serializable data class FactorioModInfo( val modName: String, - val currentVersion: String?, - val previousVersion: String?, + val currentVersion: String? = null, + val previousVersion: String? = null, ) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt index ac89d09..b6e2d09 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -137,17 +137,6 @@ data class MapTiles( override val objectName = ObjectName.LuaTiles } -@Serializable -data class MapTile( - val prototypeName: String, - val position: MapTilePosition, -) -// : FactorioObjectData() -{ - // @EncodeDefault - val objectName: String = "" -} - @Serializable data class ConsoleChatMessage( val authorPlayerIndex: UInt?, diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt index 65c291c..ce7c8a8 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt @@ -203,7 +203,6 @@ class FactorioEventTest : FunSpec({ "surfaceIndex": 1, "tiles": [ { - "objectName": "LuaTile", "position": { "y": 10, "x": -65 @@ -211,23 +210,20 @@ class FactorioEventTest : FunSpec({ "prototypeName": "refined-concrete" }, { - "objectName": "LuaTile", "position": { "y": 11, "x": -65 }, - "prototypeName": "refined-concrete" + "prototypeName": "red-earth" }, { - "objectName": "LuaTile", "position": { "y": 10, "x": -64 }, - "prototypeName": "refined-concrete" + "prototypeName": "blue-cheese" }, { - "objectName": "LuaTile", "position": { "y": 11, "x": -64 @@ -256,11 +252,11 @@ class FactorioEventTest : FunSpec({ position = MapTilePosition(-65, 10) ), MapTile( - prototypeName = "refined-concrete", + prototypeName = "red-earth", position = MapTilePosition(-65, 11) ), MapTile( - prototypeName = "refined-concrete", + prototypeName = "blue-cheese", position = MapTilePosition(-64, 10) ), MapTile( @@ -279,6 +275,60 @@ class FactorioEventTest : FunSpec({ expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaTiles } + test("Then: expect encode equals json") { + val encoded = jsonMapperKafkatorio.encodeToString(actual) + encoded.shouldEqualJson(json) + } + } + } + + context("Given: packet FactorioConfigurationUpdate") { + // language=JSON + val json = """ + { + "modVersion": "0.2.8", + "packetType": "CONFIG", + "allMods": [ + { + "modName": "kafkatorio-events", + "currentVersion": "0.2.8", + "previousVersion": "0.2.7" + }, + { + "modName": "base", + "currentVersion": "1.1.53" + } + ], + "factorioData": {} + } + """.trimIndent() + context("When: decoded") { + val actual: FactorioConfigurationUpdate = jsonMapperKafkatorio.decodeFromString(json) + + test("parse") { + + val expected = FactorioConfigurationUpdate( + modVersion = "0.2.8", + factorioData = FactorioGameDataUpdate(null, null), + allMods = listOf( + FactorioModInfo( + modName = "kafkatorio-events", + currentVersion = "0.2.8", + previousVersion = "0.2.7" + ), + FactorioModInfo( + modName = "base", + currentVersion = "1.1.53", + previousVersion = null + ), + ) + ) + + actual shouldBe expected + + expected.packetType shouldBe KafkatorioPacket.PacketType.CONFIG + } + test("Then: expect encode equals json") { val encoded = jsonMapperKafkatorio.encodeToString(actual) encoded.shouldEqualJson(json) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 9049e61..ec6fbb8 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -1,16 +1,16 @@ package dev.adamko.kafkatorio.processor -import dev.adamko.kafkatorio.processor.topology.buildFactorioServerMap import dev.adamko.kafkatorio.processor.topology.factorioServerPacketStream +import dev.adamko.kafkatorio.processor.topology.groupTilesIntoChunksWithColours import dev.adamko.kafkatorio.processor.topology.playerUpdatesToWsServer import dev.adamko.kafkatorio.processor.topology.saveMapTiles import dev.adamko.kafkatorio.processor.topology.splitFactorioServerPacketStream +import dev.adamko.kafkatorio.processor.topology.tileProtoColourDictionary import java.time.Duration import org.apache.kafka.streams.KafkaStreams import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.TopologyDescription - class KafkatorioTopology( private val websocketServer: WebsocketServer, private val builder: StreamsBuilder = StreamsBuilder(), @@ -20,17 +20,27 @@ class KafkatorioTopology( const val sourceTopic = "factorio-server-log" } + fun build() { + val packets = factorioServerPacketStream(builder) + + splitFactorioServerPacketStream(packets) playerUpdatesToWsServer(websocketServer, builder) - val serverMapDataTable = buildFactorioServerMap(packets) +// val serverMapDataTable = buildFactorioServerMap(packets, tilePrototypesTable) - saveMapTiles(serverMapDataTable) + val tileProtoColourDict = tileProtoColourDictionary(packets) + + val tilePrototypesTable = groupTilesIntoChunksWithColours( + packets, + tileProtoColourDict, + ) + saveMapTiles(tilePrototypesTable) // the old way... diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt index 7e9df42..02be069 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt @@ -1,127 +1,196 @@ package dev.adamko.kafkatorio.processor.topology -import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate +import dev.adamko.kafkatorio.events.schema.ColourHex import dev.adamko.kafkatorio.events.schema.FactorioEvent -import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.events.schema.MapChunk +import dev.adamko.kafkatorio.events.schema.MapChunkPosition import dev.adamko.kafkatorio.events.schema.MapTilePosition -import dev.adamko.kafkatorio.events.schema.MapTilePrototype import dev.adamko.kafkatorio.events.schema.MapTiles -import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.materializedWith -import dev.adamko.kotka.extensions.streams.aggregate -import dev.adamko.kotka.extensions.tables.mapValues +import dev.adamko.kotka.extensions.streams.flatMap +import dev.adamko.kotka.extensions.streams.reduce +import dev.adamko.kotka.extensions.tables.join import dev.adamko.kotka.kxs.serde import kotlinx.serialization.Serializable import org.apache.kafka.streams.kstream.KStream import org.apache.kafka.streams.kstream.KTable +//@Serializable +//data class FactorioServerMap( +// val serverId: FactorioServerId, +// val tilePrototypes: Map, +// val surfaces: Map, +//) + + +//@Serializable +//data class FactorioMapSurface( +// val index: SurfaceIndex, +// val tiles: Map, +//) + + @Serializable -data class FactorioServerMap( +data class ServerMapChunkId( val serverId: FactorioServerId, - val tilePrototypes: Map, - val surfaces: Map, + val chunkPosition: MapChunkPosition, + val surfaceIndex: SurfaceIndex, + val zoomLevel: ZoomLevel, ) @Serializable -data class FactorioMapSurface( - val index: SurfaceIndex, - val tiles: Map, -) - -/** Aggregate [KafkatorioPacket]s into a single [FactorioServerMap] (per [serverId][FactorioServerId]). */ -fun buildFactorioServerMap( - factorioServerPacketStream: KStream -): KTable { - - return factorioServerPacketStream - .groupByKey( - groupedAs("factorio-server-map-data-grouping", jsonMapper.serde(), jsonMapper.serde()) - ) - .aggregate( - "factorio-server-map-data-aggregate", - materializedAs("factorio-server-map-aggregate-store", kxsBinary.serde(), kxsBinary.serde()), - { FactorioServerMapAggregator() }, - ) { _: FactorioServerId, packet: KafkatorioPacket, aggregate: FactorioServerMapAggregator -> - aggregate + packet - } - .mapValues( - "finalise-factorio-server-map-aggregate", - materializedWith(kxsBinary.serde(), kxsBinary.serde()) - ) { readOnlyKey, aggregate -> - - val surfaces = aggregate.surfaces.mapValues { (_, surface) -> - FactorioMapSurface(surface.index, surface.tiles) - } - - FactorioServerMap(readOnlyKey, aggregate.tilePrototypes, surfaces) - } - -} - - -@Serializable -private data class FactorioServerMapAggregator( - val tilePrototypes: MutableMap = mutableMapOf(), - val surfaces: MutableMap = mutableMapOf(), +data class ServerMapChunkTiles( + val chunkId: ServerMapChunkId, + val map: Map, ) { - - operator fun plus(packet: KafkatorioPacket): FactorioServerMapAggregator { - return when (packet) { - is FactorioEvent -> { - when (val data = packet.data) { - is MapChunk -> plus(data) - is MapTiles -> plus(data) -// is MapTile -> {} // hmmm... no surface index - else -> this - } - } - is FactorioPrototypes -> plus(packet) - is FactorioConfigurationUpdate -> this - } - } - - operator fun plus(mapTiles: MapTiles): FactorioServerMapAggregator { -// println("FactorioServerMapAggregator: adding ${mapTiles.tiles.size} MapTiles from surface ${mapTiles.surfaceIndex}") - - val surfaceIndex = SurfaceIndex(mapTiles.surfaceIndex) - - val surface = surfaces.getOrPut(surfaceIndex) { FactorioMapSurfaceAggregator(surfaceIndex) } - - val surfaceTiles = mapTiles.tiles.associate { it.position to PrototypeName(it.prototypeName) } - surface.tiles.putAll(surfaceTiles) - - return this - } - - operator fun plus(mapChunk: MapChunk): FactorioServerMapAggregator { -// println("FactorioServerMapAggregator: adding mapChunk ${mapChunk.position}") - return plus(mapChunk.tiles) - } - - operator fun plus(packet: FactorioPrototypes): FactorioServerMapAggregator { -// println("FactorioServerMapAggregator: adding FactorioPrototypes") - - val packetPrototypes = packet.prototypes - .filterIsInstance() - .associateBy { PrototypeName(it.name) } - - tilePrototypes.putAll(packetPrototypes) - - return this - } - + operator fun plus(other: ServerMapChunkTiles) = copy(map = map + other.map) } -@Serializable -private data class FactorioMapSurfaceAggregator( - val index: SurfaceIndex, - val tiles: MutableMap = mutableMapOf(), -) +fun groupTilesIntoChunksWithColours( + factorioServerPacketStream: KStream, + tileProtoColourDict: KTable, +): KTable> { + + // group tiles by server & surface & chunk + val chunkedTilesTable: KTable> = + factorioServerPacketStream + .flatMap("server-map-data.tiles.flatMapByChunk") { key: FactorioServerId, packet: KafkatorioPacket -> + + val mapTileData = when (packet) { + is FactorioEvent -> + when (val data = packet.data) { + is MapChunk -> data.tiles + is MapTiles -> data + else -> null + } + else -> null + } + + val zoomLevel = ZoomLevel.ZOOM_0 + +// +// ZoomLevel +// .values +// .mapNotNull { zoomLevel -> + + mapTileData + ?.tiles + ?.groupBy { tile -> + tile.position.toMapChunkPosition(zoomLevel.chunkSize) + } + ?.map { (chunkPos, tiles) -> + + val chunkId = ServerMapChunkId( + key, + chunkPos, + SurfaceIndex(mapTileData.surfaceIndex), + zoomLevel, + ) + + val tilesMap = tiles.associate { it.position to TileProtoHashCode(it) } + + val chunkTiles = ServerMapChunkTiles(chunkId, tilesMap) + + chunkId to chunkTiles + } ?: listOf() +// }.flatten() + } + .groupByKey( + groupedAs("server-map-data.tiles.group", kxsBinary.serde(), kxsBinary.serde()) + ) + .reduce( + "server-map-data.tiles.reduce", + materializedAs("server-map-data.tiles.store", kxsBinary.serde(), kxsBinary.serde()), + ) { a, b -> a + b } + + + val colourisedChunkTable: KTable> = + chunkedTilesTable + .join( + other = tileProtoColourDict, + name = "server-map-data.join-tiles-with-prototypes", + materialized = materializedWith(kxsBinary.serde(), kxsBinary.serde()), + foreignKeyExtractor = { chunkTiles: ServerMapChunkTiles -> chunkTiles.chunkId.serverId } + ) { tiles: ServerMapChunkTiles, colourDict: TileColourDict -> + + ServerMapChunkTiles( + tiles.chunkId, + tiles.map.mapValues { (_, code) -> + colourDict.map.getOrElse(code) { + println("missing prototype $code") + ColourHex.TRANSPARENT + } + } + ) + } + + return colourisedChunkTable + +} + +//@Serializable +//private data class FactorioServerMapAggregator( +// val tilePrototypes: SortedMap = TreeMap(), +// val surfaces: MutableMap = mutableMapOf(), +//) { +// +// operator fun plus(packet: KafkatorioPacket): FactorioServerMapAggregator { +// return when (packet) { +// is FactorioEvent -> { +// when (val data = packet.data) { +// is MapChunk -> plus(data) +// is MapTiles -> plus(data) +// else -> this +// } +// } +// is FactorioPrototypes -> plus(packet) +// is FactorioConfigurationUpdate -> this +// } +// } +// +// operator fun plus(mapTiles: MapTiles): FactorioServerMapAggregator { +//// println("FactorioServerMapAggregator: adding ${mapTiles.tiles.size} MapTiles from surface ${mapTiles.surfaceIndex}") +// +// val surfaceIndex = SurfaceIndex(mapTiles.surfaceIndex) +// +// val surface = surfaces.getOrPut(surfaceIndex) { FactorioMapSurfaceAggregator(surfaceIndex) } +// +// val surfaceTiles = mapTiles.tiles.associate { it.position to PrototypeName(it.prototypeName) } +// surface.tiles.putAll(surfaceTiles) +// +// return this +// } +// +// operator fun plus(mapChunk: MapChunk): FactorioServerMapAggregator { +//// println("FactorioServerMapAggregator: adding mapChunk ${mapChunk.position}") +// return plus(mapChunk.tiles) +// } +// +// operator fun plus(packet: FactorioPrototypes): FactorioServerMapAggregator { +//// println("FactorioServerMapAggregator: adding FactorioPrototypes") +// +// val packetPrototypes = packet.prototypes +// .filterIsInstance() +// .associate { PrototypeName(it.name) to it.mapColour } +// +// tilePrototypes.putAll(packetPrototypes) +// +// return this +// } +// +//} + +// +//@Serializable +//private data class FactorioMapSurfaceAggregator( +// val index: SurfaceIndex, +// val tiles: MutableMap = mutableMapOf(), +//) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt index 2aabdf4..3ee7439 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt @@ -3,10 +3,9 @@ package dev.adamko.kafkatorio.processor.topology import com.sksamuel.scrimage.ImmutableImage import com.sksamuel.scrimage.ScaleMethod import com.sksamuel.scrimage.nio.PngWriter -import dev.adamko.kafkatorio.events.schema.Colour +import dev.adamko.kafkatorio.events.schema.ColourHex import dev.adamko.kafkatorio.events.schema.MapChunkPosition import dev.adamko.kafkatorio.events.schema.MapTilePosition -import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition import java.awt.image.BufferedImage import java.io.File import kotlin.math.abs @@ -15,17 +14,17 @@ import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.conflate -import kotlinx.coroutines.flow.filterNotNull -import kotlinx.coroutines.flow.flatMapMerge -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.mapLatest -import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.distinctUntilChangedBy +import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.supervisorScope import org.apache.kafka.streams.kstream.KTable @@ -36,106 +35,84 @@ private val cScope = CoroutineScope( ) /** A bridge between Kafka and Kotlin */ -private val serverMapDataFlow: MutableStateFlow = MutableStateFlow(null) +private val chunkedTiles: MutableSharedFlow> = + MutableSharedFlow( + 0, + 1, + BufferOverflow.SUSPEND + ) fun saveMapTiles( - serverMapTable: KTable + serverMapTable: KTable> ) { serverMapTable .toStream() .foreach { _, value -> - runBlocking(Dispatchers.Default) { - serverMapDataFlow.emit(value) + if (value != null) { + runBlocking(Dispatchers.Default) { + println("emitting chunkedTiles ${value.chunkId} tiles: ${value.map.size}") + chunkedTiles.emit(value) + } } } cScope.launch { - println("launching serverMapDataFlow merging") - - - serverMapDataFlow - .filterNotNull() - - serverMapDataFlow - .filterNotNull() - .conflate() -// .transform { serverMapData -> - .flatMapMerge(10) { serverMapData -> - println("flatMapMerge serverMapData ${serverMapData.serverId}, surfaces ${serverMapData.surfaces.keys}") - - val prototypes = serverMapData.tilePrototypes - - serverMapData - .surfaces - .values -// .forEach { surfaceData -> - .asFlow() - .flatMapMerge(10) { surfaceData -> - println("flatMapMerge surfaceData ${surfaceData.index}") - - // get all tile colours for the surface - val surfaceTileColours = surfaceData.tiles - .entries - .mapNotNull { (tilePosition, prototypeName) -> - prototypes[prototypeName]?.let { prototype -> - tilePosition to prototype.mapColour - } - } - println("surfaceTileColours.size ${surfaceTileColours.size}") - - // split a surface into chunks, per zoom-level - ZoomLevel.values -// .forEach { zoom -> - .asFlow() - .flatMapMerge(10) { zoom -> - println("flatMapMerge zoom $zoom") - - surfaceTileColours - .groupBy { (tilePosition, _) -> - tilePosition.toMapChunkPosition(zoom.chunkSize) - } - .entries -// .forEach { (chunkPosition, tileColours) -> - .asFlow() - .mapLatest { (chunkPosition, tileColours) -> - println("mapLatest chunkPosition $chunkPosition") - - // mapLatest + delay = an alternative to debounce-per-key? - delay(30.seconds) - - println("emitting ChunkData $chunkPosition") - - ChunkData( - surfaceData.index, - zoom, - chunkPosition, - tileColours.toMap() - ) - } - } - } - } - .onEach { chunkData -> - - println("starting to save chunkData ${chunkData.chunkPosition}...") - - val chunkImageFile = File(chunkData.filename.value) - if (chunkImageFile.parentFile.mkdirs()) { - println("created new map tile parentFile directory ${chunkImageFile.absolutePath}") + supervisorScope { + chunkedTiles + .conflate() + .distinctUntilChanged() + .debounce(5.seconds) + .map { + println("createMapTileImage ${it.chunkId}") + createMapTileImage(it) } - - val image = - createMapTileImage(chunkData.chunkPosition, chunkData.tileColours, chunkData.zoomLevel) - - println("saving map tile $chunkImageFile") - val savedTile = image.output(PngWriter.NoCompression, chunkImageFile) - println("savedTile: $savedTile") - - } - .launchIn(this) + .collect() + } } + +// cScope.launch { +// println("launching serverMapDataFlow merging") +// +// chunkedTiles +// .runningFold( +// mapOf>>() +// ) { accumulator, value -> +// +// println("folding chunkedTiles ${value.chunkId}, current flows: ${accumulator.keys}") +// +// val chunkFlow = accumulator.getOrElse(value.chunkId) { +// +// println("creating new MutableSharedFlow for ${value.chunkId}") +// +// val input = MutableSharedFlow>( +// replay = 0, +// extraBufferCapacity = 1, +// onBufferOverflow = BufferOverflow.DROP_OLDEST, +// ) +// +// supervisorScope { +// println("launching MutableSharedFlow for ${value.chunkId}") +// input +// .debounce(30.seconds) +// .mapLatest { +// println("createMapTileImage ${it.chunkId}") +// createMapTileImage(it) +// }.launchIn(this) +// } +// +// input +// } +// +// chunkFlow.emit(value) +// +// accumulator + (value.chunkId to chunkFlow) +// } +// .collect() +// +// println("end of cScope.launch") +// } } @@ -145,35 +122,58 @@ private value class TilePngFilename( ) { constructor( - surfaceIndex: SurfaceIndex, - zoom: Int, - chunkX: Int, - chunkY: Int, - ) : this("src/main/resources/kafkatorio-web-map/s${surfaceIndex.index}/z$zoom/x${chunkX}/y${chunkY}.png") - -} - - -private data class ChunkData( - val surfaceIndex: SurfaceIndex, - val zoomLevel: ZoomLevel, - val chunkPosition: MapChunkPosition, - val tileColours: Map, -) { - val filename = TilePngFilename(surfaceIndex, zoomLevel.level, chunkPosition.x, chunkPosition.y) + chunkId: ServerMapChunkId + ) : this(buildString { + append("src/main/resources/kafkatorio-web-map/s") + append(chunkId.surfaceIndex.index) + append("/z") + append(chunkId.zoomLevel.level) + append("/x") + append(chunkId.chunkPosition.x) + append("/y") + append(chunkId.chunkPosition.y) + append(".png") + }) } +private fun createMapTileImage( + chunkTiles: ServerMapChunkTiles +) { + + println("emitting ChunkData ${chunkTiles.chunkId.chunkPosition}") + + println("starting to save chunkData ${chunkTiles.chunkId.chunkPosition}...") + + val filename = TilePngFilename(chunkTiles.chunkId) + + val chunkImageFile = File(filename.value) + if (chunkImageFile.parentFile.mkdirs()) { + println("created new map tile parentFile directory ${chunkImageFile.absolutePath}") + } + + val image = + createMapTileImage( + chunkTiles.chunkId.chunkPosition, + chunkTiles.map, + chunkTiles.chunkId.zoomLevel + ) + + println("saving map tile $chunkImageFile") + val savedTile = image.output(PngWriter.NoCompression, chunkImageFile) + println("savedTile: $savedTile") +} + + private fun createMapTileImage( chunkPosition: MapChunkPosition, - chunkColours: Map, + chunkColours: Map, z: ZoomLevel ): ImmutableImage { - val chunkImage = ImmutableImage.filled( z.chunkSize, z.chunkSize, - COLOUR_TRANSPARENT.awt(), + ColourHex.TRANSPARENT.toRgbColor().awt(), BufferedImage.TYPE_INT_ARGB ) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt index 4f67bc5..3bae3f1 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt @@ -2,6 +2,7 @@ package dev.adamko.kafkatorio.processor.topology import com.sksamuel.scrimage.color.RGBColor import dev.adamko.kafkatorio.events.schema.Colour +import dev.adamko.kafkatorio.events.schema.ColourHex import kotlin.math.pow import kotlin.math.roundToInt import kotlinx.serialization.Serializable @@ -23,12 +24,12 @@ value class FactorioServerId(val id: String) { } -fun Colour.toRgbColor(): RGBColor { +fun ColourHex.toRgbColor(): RGBColor { return RGBColor( - red.roundToInt(), - green.roundToInt(), - blue.roundToInt(), - alpha.roundToInt(), + red.toInt(), + green.toInt(), + blue.toInt(), + alpha.toInt(), ) } @@ -36,15 +37,14 @@ fun Colour.toRgbColor(): RGBColor { enum class ZoomLevel( val level: Int ) { - ZOOM_0(0), - ZOOM_1(1), - ZOOM_2(2), - ZOOM_3(3), - ZOOM_4(4), - ZOOM_5(5), + ZOOM_0(0), // 512 + ZOOM_1(1), // 256 + ZOOM_2(2), // 128 + ZOOM_3(3), // 64 + ZOOM_4(4), // 32 ; - val chunkSize: Int = 2f.pow(10 - level).roundToInt() + val chunkSize: Int = 2f.pow(9 - level).roundToInt() init { require(chunkSize > 0) { "chunkSize must be positive" } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index 30b8839..ac19bbd 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -1,19 +1,17 @@ package dev.adamko.kafkatorio.processor.topology -import com.sksamuel.scrimage.color.RGBColor -import dev.adamko.kafkatorio.events.schema.Colour +import dev.adamko.kafkatorio.events.schema.ColourHex import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket +import dev.adamko.kafkatorio.events.schema.MapTile import dev.adamko.kafkatorio.events.schema.MapTilePrototype import dev.adamko.kafkatorio.processor.serdes.jsonMapper -import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kotka.extensions.consumedAs -import dev.adamko.kotka.extensions.materializedWith -import dev.adamko.kotka.extensions.streams.flatMap +import dev.adamko.kotka.extensions.materializedAs +import dev.adamko.kotka.extensions.streams.mapValues +import dev.adamko.kotka.extensions.streams.toTable import dev.adamko.kotka.kxs.serde import kotlinx.serialization.Serializable -import org.apache.kafka.common.serialization.Serdes -import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.kstream.KStream import org.apache.kafka.streams.kstream.KTable @@ -24,50 +22,45 @@ value class PrototypeName(val name: String) { } -//fun prototypesTable(builder: StreamsBuilder): KTable { -// return builder.stream( -// "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", -// consumedAs( -// "consume-all-prototypes-packets", -// jsonMapper.serde(), -// jsonMapper.serde() -// ) -// ) -// .flatMap("map-MapTilePrototype") { _, prototypes: FactorioPrototypes -> -// prototypes.prototypes -// .filterIsInstance() -// .map { PrototypeName(it.name) to it } -// } -// .toTable( -// materializedWith( -// kxsBinary.serde(), -// kxsBinary.serde() -// ) -// ) -//} +@JvmInline +@Serializable +value class TileProtoHashCode(val code: Int) { + constructor(prototype: MapTilePrototype) : this(prototype.name.hashCode()) + constructor(tile: MapTile) : this(tile.prototypeName.hashCode()) +} -/** Get the [Colour] of each [MapTilePrototype] */ -fun tilePrototypeColourTable(builder: StreamsBuilder): KTable { - return builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", - consumedAs( - "consume-all-prototypes-packets", - jsonMapper.serde(), - jsonMapper.serde() - ) - ) - .flatMap("map-MapTilePrototype") { _, prototypes: FactorioPrototypes -> - prototypes.prototypes - .filterIsInstance() - .map { - PrototypeName(it.name) to it.mapColour - } +@JvmInline +@Serializable +value class TileColourDict(val map: Map) { + operator fun plus(other: TileColourDict) = TileColourDict(this.map + other.map) +} + + +/** Aggregate [KafkatorioPacket]s into a single [FactorioServerMap] (per [serverId][FactorioServerId]). */ +fun tileProtoColourDictionary( + factorioServerPacketStream: KStream +): KTable { + + // get all the prototypes + return factorioServerPacketStream + .mapValues("server-map-data.tile-prototypes.mapValues") { _, packet -> + val map = when (packet) { + is FactorioPrototypes -> packet + .prototypes + .filterIsInstance() + .associate { TileProtoHashCode(it) to it.mapColour.toHex() } + else -> mapOf() + } + TileColourDict(map) } .toTable( - materializedWith( - kxsBinary.serde(), - kxsBinary.serde() + "server-map-data.tile-prototypes", + materializedAs( + "server-map-data.tile-prototypes.store", + jsonMapper.serde(), + jsonMapper.serde() ) ) + } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt index e5f91c8..2e609a7 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt @@ -13,89 +13,89 @@ import kotlin.math.abs import kotlin.math.roundToInt import org.apache.kafka.streams.kstream.KTable - -val COLOUR_TRANSPARENT = RGBColor.fromAwt(Color(0f, 0f, 0f, 0f)) - -fun saveTileImages( - webMapTiles: KTable -) { - - webMapTiles - .toStream("get-webmap-tile-updates") - .foreach { position: WebMapTileChunkPosition, pixels: WebMapTileChunkPixels -> - runCatching { - saveMapTilesPng(position, pixels.pixels) - }.onFailure { e -> - println("error saving map tile png chunk: $position") - e.printStackTrace() - throw e - } - } -} - -//val saveMapTilesContext = Dispatchers.IO.limitedParallelism(1) - - -private fun saveMapTilesPng( - chunkPosition: WebMapTileChunkPosition, - pixels: Map, -) { - val chunkOriginX: Int = chunkPosition.x * chunkPosition.chunkSize // - 1 - val chunkOriginY: Int = chunkPosition.y * chunkPosition.chunkSize // - 1 - val surfaceIndex: Int = chunkPosition.surfaceIndex.index - - val chunkImage = - ImmutableImage.filled( - chunkPosition.chunkSize, - chunkPosition.chunkSize, - COLOUR_TRANSPARENT.awt(), - BufferedImage.TYPE_INT_ARGB - ) - - pixels.forEach { (tilePosition, colour) -> - - val rgbColour = colour.toRgbColor() - - val pixelX = abs(abs(tilePosition.x) - abs(chunkOriginX)) - val pixelY = abs(abs(tilePosition.y) - abs(chunkOriginY)) - - chunkImage.setColor( - pixelX, - pixelY, - rgbColour - ) - - } - - val zoom = 1u - val file = - File(tileFilename("$surfaceIndex", "$zoom", "${chunkPosition.x}", "${chunkPosition.y}")) - - if (file.parentFile.mkdirs()) { - println("created new map tile parentFile directory ${file.absolutePath}") - } - - println("saving map tile $file") - val savedTile = chunkImage.output(PngWriter.NoCompression, file) - println("savedTile: $savedTile") -} - -fun tileFilename( - surfaceIndex: String, - zoom: String, - chunkX: String, - chunkY: String, -) = "src/main/resources/kafkatorio-web-map/s${surfaceIndex}/z$zoom/x${chunkX}/y${chunkY}.png" - -//fun subdivide(tile: ImmutableImage, size: Int) { // -// val halfSize = size / 2 +//val COLOUR_TRANSPARENT: RGBColor = RGBColor.fromAwt(Color(0f, 0f, 0f, 0f)) // -// val bl = tile.resizeTo(halfSize, halfSize, Position.BottomLeft) -// val savedTile = bl.output(PngWriter.NoCompression, file) -// -// tile.resizeTo(halfSize, halfSize, Position.BottomRight) -// tile.resizeTo(halfSize, halfSize, Position.TopLeft) -// tile.resizeTo(halfSize, halfSize, Position.TopRight) +//fun saveTileImages( +// webMapTiles: KTable +//) { // +// webMapTiles +// .toStream("get-webmap-tile-updates") +// .foreach { position: WebMapTileChunkPosition, pixels: WebMapTileChunkPixels -> +// runCatching { +// saveMapTilesPng(position, pixels.pixels) +// }.onFailure { e -> +// println("error saving map tile png chunk: $position") +// e.printStackTrace() +// throw e +// } +// } //} +// +////val saveMapTilesContext = Dispatchers.IO.limitedParallelism(1) +// +// +//private fun saveMapTilesPng( +// chunkPosition: WebMapTileChunkPosition, +// pixels: Map, +//) { +// val chunkOriginX: Int = chunkPosition.x * chunkPosition.chunkSize // - 1 +// val chunkOriginY: Int = chunkPosition.y * chunkPosition.chunkSize // - 1 +// val surfaceIndex: Int = chunkPosition.surfaceIndex.index +// +// val chunkImage = +// ImmutableImage.filled( +// chunkPosition.chunkSize, +// chunkPosition.chunkSize, +// COLOUR_TRANSPARENT.awt(), +// BufferedImage.TYPE_INT_ARGB +// ) +// +// pixels.forEach { (tilePosition, colour) -> +// +// val rgbColour = colour.toRgbColor() +// +// val pixelX = abs(abs(tilePosition.x) - abs(chunkOriginX)) +// val pixelY = abs(abs(tilePosition.y) - abs(chunkOriginY)) +// +// chunkImage.setColor( +// pixelX, +// pixelY, +// rgbColour +// ) +// +// } +// +// val zoom = 1u +// val file = +// File(tileFilename("$surfaceIndex", "$zoom", "${chunkPosition.x}", "${chunkPosition.y}")) +// +// if (file.parentFile.mkdirs()) { +// println("created new map tile parentFile directory ${file.absolutePath}") +// } +// +// println("saving map tile $file") +// val savedTile = chunkImage.output(PngWriter.NoCompression, file) +// println("savedTile: $savedTile") +//} +// +//fun tileFilename( +// surfaceIndex: String, +// zoom: String, +// chunkX: String, +// chunkY: String, +//) = "src/main/resources/kafkatorio-web-map/s${surfaceIndex}/z$zoom/x${chunkX}/y${chunkY}.png" +// +////fun subdivide(tile: ImmutableImage, size: Int) { +//// +//// val halfSize = size / 2 +//// +//// val bl = tile.resizeTo(halfSize, halfSize, Position.BottomLeft) +//// val savedTile = bl.output(PngWriter.NoCompression, file) +//// +//// tile.resizeTo(halfSize, halfSize, Position.BottomRight) +//// tile.resizeTo(halfSize, halfSize, Position.TopLeft) +//// tile.resizeTo(halfSize, halfSize, Position.TopRight) +//// +////} diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt new file mode 100644 index 0000000..941cc09 --- /dev/null +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt @@ -0,0 +1,62 @@ +package dev.adamko.kafkatorio.processor.misc + +import dev.adamko.kafkatorio.events.schema.ColourHex +import dev.adamko.kafkatorio.events.schema.MapChunkPosition +import dev.adamko.kafkatorio.events.schema.MapTilePosition +import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.processor.topology.FactorioServerId +import dev.adamko.kafkatorio.processor.topology.ServerMapChunkId +import dev.adamko.kafkatorio.processor.topology.ServerMapChunkTiles +import dev.adamko.kafkatorio.processor.topology.SurfaceIndex +import dev.adamko.kafkatorio.processor.topology.ZoomLevel +import java.util.UUID +import kotlinx.serialization.encodeToByteArray +import org.junit.jupiter.api.Test + +class Blah { + + @Test + fun asdad() { + + val tiles = ServerMapChunkTiles( + chunkId = ServerMapChunkId( + serverId = FactorioServerId(UUID.randomUUID().toString()), + chunkPosition = MapChunkPosition(Int.MAX_VALUE, Int.MAX_VALUE), + surfaceIndex = SurfaceIndex(Int.MAX_VALUE), + zoomLevel = ZoomLevel.ZOOM_0 + ), + buildMap { + repeat(512) { x -> + repeat(512) { y -> + put(MapTilePosition(x, y), ColourHex(255u, 255u, 255u, 255u)) + } + } + } + ) + + val encode = kxsBinary.encodeToByteArray(tiles) + + encode.inputStream() + val size = encode.size * Byte.SIZE_BYTES + + println(size) + + + val map2 = buildList { + repeat(512) { x -> + repeat(512) { y -> + val element = (x to y) to Int.MAX_VALUE + add(element) + } + } + } +// .toTypedArray() + val encode2 = kxsBinary.encodeToByteArray(map2) + + encode2.inputStream() + val size2 = encode2.size * Byte.SIZE_BYTES + + println(size2) + + } +} diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index aecb9bc..82dbe34 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio FACTORIO_VERSION=1.1.53 -KAFKATORIO_VERSION=0.2.7 +KAFKATORIO_VERSION=0.2.8 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index 1ebae11..8153f49 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.2.7 +KAFKATORIO_VERSION=0.2.8 diff --git a/modules/infra-kafka-cluster/src/kafka-server.properties b/modules/infra-kafka-cluster/src/kafka-server.properties index 3f7c92c..6c1f2d1 100644 --- a/modules/infra-kafka-cluster/src/kafka-server.properties +++ b/modules/infra-kafka-cluster/src/kafka-server.properties @@ -120,3 +120,8 @@ log.retention.check.interval.ms=300000 ### Compression ### #compression.type=snappy #linger.ms=5 + + +### record size ### +message.max.bytes=10485760 +replica.fetch.max.bytes=10485760 diff --git a/modules/infra-kafka-cluster/src/kafka.Dockerfile b/modules/infra-kafka-cluster/src/kafka.Dockerfile index dca9f09..9dd574d 100644 --- a/modules/infra-kafka-cluster/src/kafka.Dockerfile +++ b/modules/infra-kafka-cluster/src/kafka.Dockerfile @@ -1,4 +1,4 @@ -ARG KAFKA_DL_URL=https://dlcdn.apache.org/kafka/3.0.0/kafka_2.13-3.0.0.tgz +ARG KAFKA_DL_URL=https://dlcdn.apache.org/kafka/3.1.0/kafka_2.13-3.1.0.tgz ## builder ## FROM debian:11-slim as Kafka-Download diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index a7128f7..5c9cbf9 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -4,7 +4,7 @@ import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig plugins { id("dev.adamko.kafkatorio.lang.kotlin-js") kotlin("plugin.serialization") - id("io.kvision") version "5.7.1" + id("io.kvision") version "5.8.1" } kotlin { @@ -48,8 +48,8 @@ kotlin { implementation(projects.modules.eventsSchema) - implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7") - implementation("org.jetbrains.kotlinx:kotlinx-html:0.7.3") + implementation(libs.kotlinx.nodejs) + implementation(libs.kotlinx.html) kvision("kvision") kvision("kvision-bootstrap") From 5a59b3bd6da86a204c77f5c7e32221cb2e4010a1 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 8 Feb 2022 11:51:16 +0100 Subject: [PATCH 180/629] workinggggg!!!!!!! - fix map tiles proto colours KTable - test and tidy up Colour/ColourHex - reset event-server application --- .../events/schema/converters/colour.kt | 81 ++++++++++------- .../events/schema/converters/positions.kt | 9 +- .../events/schema/factorioCommonData.kt | 15 +--- .../kafkatorio/events/schema/ColourHexTest.kt | 86 +++++++++++++++++++ modules/events-server/build.gradle.kts | 17 ++++ .../adamko/kafkatorio/admin/CreateTopics.kt | 10 +-- .../processor/KafkatorioTopology.kt | 4 +- .../kafkatorio/processor/eventProcessor.kt | 6 +- .../processor/topology/factorioGameState.kt | 28 +++--- .../topology/factorioServerPackets.kt | 1 + .../processor/topology/flowMapTiles.kt | 19 +++- .../kafkatorio/processor/topology/model.kt | 13 --- .../processor/topology/prototypes.kt | 19 ++-- 13 files changed, 211 insertions(+), 97 deletions(-) create mode 100644 modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/colour.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/colour.kt index a4f6fba..845cfd0 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/colour.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/colour.kt @@ -1,6 +1,7 @@ package dev.adamko.kafkatorio.events.schema.converters import dev.adamko.kafkatorio.events.schema.Colour +import dev.adamko.kafkatorio.events.schema.ColourHex import kotlin.math.roundToInt @@ -15,39 +16,12 @@ fun Colour.isHexadecimal(): Boolean { /** True if all values are between `[0..1]`. */ fun Colour.isPercentage(): Boolean = !isHexadecimal() -fun Colour.toHexadecimal() = if (isPercentage()) { - Colour( - (red * 255).coerceIn(0f..255f), - (green * 255).coerceIn(0f..255f), - (blue * 255).coerceIn(0f..255f), - (alpha * 255).coerceIn(0f..255f), - ) -} else { - Colour( - red.coerceIn(0f..255f), - green.coerceIn(0f..255f), - blue.coerceIn(0f..255f), - alpha.coerceIn(0f..255f), - ) -} - -fun Colour.toPercentage() = if (isPercentage()) { - this -} else { - Colour( - (red / 255).coerceIn(0f..1f), - (green / 255).coerceIn(0f..1f), - (blue / 255).coerceIn(0f..1f), - (alpha / 255).coerceIn(0f..1f), - ) -} fun Colour.toHexString(includeAlpha: Boolean = false): String { - val hexConverter: Float.() -> String = if (isHexadecimal()) { - Float::decimalToHex - } else { - Float::percentageToHex + val hexConverter: Float.() -> String = when { + isHexadecimal() -> Float::hexadecimalToString + else -> Float::percentageToHexadecimalString } val length = if (includeAlpha) 9 else 7 @@ -62,8 +36,51 @@ fun Colour.toHexString(includeAlpha: Boolean = false): String { } } -fun Float.decimalToHex(): String = +fun Float.hexadecimalToString(): String = roundToInt().toString(16).padStart(2, ' ') -fun Float.percentageToHex(): String = +fun Float.percentageToHexadecimalString(): String = times(255).roundToInt().toString(16).padStart(2, ' ') + + +private val ubyteMaxFloat = UByte.MAX_VALUE.toFloat() +private val ubyteMinFloat = UByte.MIN_VALUE.toFloat() +private val ubyteRangeFloat = ubyteMinFloat..ubyteMaxFloat + + +private fun Float.toColourHex() = (this * ubyteMaxFloat) + .coerceIn(ubyteRangeFloat) + .toUInt() + .toUByte() + + +private fun Float.coerceToColourHex() = coerceIn(ubyteRangeFloat) + .toUInt() + .toUByte() + + +fun Colour.toHex(): ColourHex { + + val converter: Float.() -> UByte = when { + isPercentage() -> Float::toColourHex + else -> Float::coerceToColourHex + } + + return ColourHex( + red.converter(), + green.converter(), + blue.converter(), + alpha.converter(), + ) +} + +private fun UByte.toPercentileFloat() = (this.toFloat() / ubyteMaxFloat).coerceIn(0f..1f) + +fun ColourHex.toPercentile(): Colour { + return Colour( + red.toPercentileFloat(), + green.toPercentileFloat(), + blue.toPercentileFloat(), + alpha.toPercentileFloat(), + ) +} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/positions.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/positions.kt index 0f80a73..2729233 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/positions.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/positions.kt @@ -1,7 +1,6 @@ package dev.adamko.kafkatorio.events.schema.converters import dev.adamko.kafkatorio.events.schema.MAP_CHUNK_SIZE -import dev.adamko.kafkatorio.events.schema.MapBoundingBox import dev.adamko.kafkatorio.events.schema.MapChunkPosition import dev.adamko.kafkatorio.events.schema.MapEntityPosition import dev.adamko.kafkatorio.events.schema.MapTilePosition @@ -17,7 +16,7 @@ operator fun MapTilePosition.plus(addend: Int) = MapTilePosition(x + addend, y + addend) -fun MapTilePosition.toMapChunkPosition( chunkSize: Int = MAP_CHUNK_SIZE) = +fun MapTilePosition.toMapChunkPosition(chunkSize: Int = MAP_CHUNK_SIZE) = MapChunkPosition( floor(x.toDouble() / chunkSize.toDouble()).toInt(), floor(y.toDouble() / chunkSize.toDouble()).toInt(), @@ -27,7 +26,7 @@ fun MapTilePosition.toMapChunkPosition( chunkSize: Int = MAP_CHUNK_SIZE) = fun MapEntityPosition.toMapTilePosition() = MapChunkPosition(floor(x).toInt(), floor(y).toInt()) -fun MapEntityPosition.toMapChunkPosition( chunkSize: Int = MAP_CHUNK_SIZE) = +fun MapEntityPosition.toMapChunkPosition(chunkSize: Int = MAP_CHUNK_SIZE) = MapChunkPosition( floor(x / chunkSize.toDouble()).toInt(), floor(y / chunkSize.toDouble()).toInt(), @@ -44,8 +43,8 @@ operator fun MapChunkPosition.minus(subtrahend: Int) = MapChunkPosition(x - subtrahend, y - subtrahend) -fun MapChunkPosition.leftTopTile( chunkSize: Int = MAP_CHUNK_SIZE): MapTilePosition = - MapTilePosition( +fun MapChunkPosition.leftTopTile(chunkSize: Int = MAP_CHUNK_SIZE): MapTilePosition = + MapTilePosition( x * chunkSize, y * chunkSize, ) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index d6ffb50..f08eb79 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -1,6 +1,5 @@ package dev.adamko.kafkatorio.events.schema -import dev.adamko.kafkatorio.events.schema.converters.toHexadecimal import kotlinx.serialization.EncodeDefault import kotlinx.serialization.Serializable @@ -69,20 +68,10 @@ data class Colour( val blue: Float = 0f, @EncodeDefault val alpha: Float = 1f, -) { - - fun toHex() = toHexadecimal().let { - ColourHex( - it.red.toUInt().toUByte(), - it.green.toUInt().toUByte(), - it.blue.toUInt().toUByte(), - it.alpha.toUInt().toUByte(), - ) - } -} +) -/** Size-efficient version of [Colour] */ +/** Size-efficient version of [Colour] (`4*4` bytes vs `4*1` bytes) */ @Serializable data class ColourHex( @EncodeDefault diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt new file mode 100644 index 0000000..beaf512 --- /dev/null +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt @@ -0,0 +1,86 @@ +package dev.adamko.kafkatorio.events.schema + +import dev.adamko.kafkatorio.events.schema.converters.toHex +import dev.adamko.kafkatorio.events.schema.converters.toPercentile +import io.kotest.assertions.withClue +import io.kotest.core.spec.style.BehaviorSpec +import io.kotest.matchers.floats.shouldBeWithinPercentageOf +import io.kotest.matchers.should +import io.kotest.matchers.shouldBe +import io.kotest.property.checkAll +import kotlinx.serialization.decodeFromString + +class ColourHexTest : BehaviorSpec({ + + Given("colour json") { + + //Language=JSON + val colourJson = """ + { + "red": 0.1, + "green": 0.4, + "blue": 0.7, + "alpha": 0.6 + } + """.trimIndent() + + val colour: Colour = jsonMapperKafkatorio.decodeFromString(colourJson) + + Then("expect colour is decoded") { + colour shouldBe Colour( + 0.1f, + 0.4f, + 0.7f, + 0.6f, + ) + } + + Then("expect Colour can be converted to ColourHex and back") { + val colourHex = colour.toHex() + colourHex shouldBe ColourHex( + 25u, + 102u, + 178u, + 153u, + ) + + colourHex.toPercentile() should { back -> + withClue(back) { + + val tolerance = 2.6 // 2.6%, because 255/100 = 2.55 + + withClue("red") { back.red.shouldBeWithinPercentageOf(0.1f, tolerance) } + withClue("green") { back.green.shouldBeWithinPercentageOf(0.4f, tolerance) } + withClue("blue") { back.blue.shouldBeWithinPercentageOf(0.7f, tolerance) } + withClue("alpha") { back.alpha.shouldBeWithinPercentageOf(0.6f, tolerance) } + } + } + } + } + + Given("any colour json") { + Then("expect can always convert") { + + checkAll { r, g, b, a -> + + //Language=JSON + val colourJson = """ + { + "red": ${r.toFloat() / UByte.MAX_VALUE.toFloat()}, + "green": ${g.toFloat() / UByte.MAX_VALUE.toFloat()}, + "blue": ${b.toFloat() / UByte.MAX_VALUE.toFloat()}, + "alpha": ${a.toFloat() / UByte.MAX_VALUE.toFloat()} + } + """.trimIndent() + + val colour: Colour = jsonMapperKafkatorio.decodeFromString(colourJson) + val colourHex = colour.toHex() + colourHex shouldBe ColourHex(r, g, b, a) + + } + + } + } + + +}) diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 7e0bebf..0567e7f 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -1,4 +1,5 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { dev.adamko.kafkatorio.lang.`kotlin-jvm` @@ -64,3 +65,19 @@ tasks.withType { "-opt-in=kotlinx.coroutines.FlowPreview", ) } + +val kafkatorioEventsServerKafkaForceReset by tasks.registering(Exec::class) { + group = project.name + + val cmd = """ + /kafka/bin/kafka-streams-application-reset.sh --application-id kafkatorio-events-processor --input-topics factorio-server-log --force + """.trimIndent() + + logging.captureStandardOutput(LogLevel.LIFECYCLE) + + commandLine = parseSpaceSeparatedArgs(""" docker exec -d kafka $cmd """) +} + +tasks.run.configure { + dependsOn(kafkatorioEventsServerKafkaForceReset) +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt index 02d4520..dd9b89b 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt @@ -12,11 +12,11 @@ import org.apache.kafka.clients.admin.TopicListing private val logger = KotlinLogging.logger {} -fun main() { - CreateTopics.create() -} +//fun main() { +// KafkaAdmin.createKafkatorioTopics() +//} -object CreateTopics { +object KafkaAdmin { private val kafkaAdmin: Admin = Admin.create( @@ -26,7 +26,7 @@ object CreateTopics { ) ) - fun create() { + fun createKafkatorioTopics() { val currentTopics = currentTopics().map { it.name() } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index ec6fbb8..ffad94f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -16,6 +16,7 @@ class KafkatorioTopology( private val builder: StreamsBuilder = StreamsBuilder(), ) { + companion object { const val sourceTopic = "factorio-server-log" } @@ -23,11 +24,8 @@ class KafkatorioTopology( fun build() { - val packets = factorioServerPacketStream(builder) - - splitFactorioServerPacketStream(packets) playerUpdatesToWsServer(websocketServer, builder) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt index 8506cac..a8b487b 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -1,7 +1,7 @@ package dev.adamko.kafkatorio.processor -import dev.adamko.kafkatorio.admin.CreateTopics +import dev.adamko.kafkatorio.admin.KafkaAdmin import dev.adamko.kafkatorio.processor.config.ApplicationProperties import dev.adamko.kafkatorio.processor.tileserver.WebMapTileServer import kotlinx.coroutines.runBlocking @@ -9,11 +9,13 @@ import org.http4k.server.PolyHandler import org.http4k.server.Undertow import org.http4k.server.asServer + val appProps = ApplicationProperties() + fun main(): Unit = runBlocking { - CreateTopics.create() + KafkaAdmin.createKafkatorioTopics() val wsServer = WebsocketServer() val tileServer = WebMapTileServer() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt index 02be069..3de8cc6 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt @@ -76,11 +76,6 @@ fun groupTilesIntoChunksWithColours( val zoomLevel = ZoomLevel.ZOOM_0 -// -// ZoomLevel -// .values -// .mapNotNull { zoomLevel -> - mapTileData ?.tiles ?.groupBy { tile -> @@ -101,7 +96,7 @@ fun groupTilesIntoChunksWithColours( chunkId to chunkTiles } ?: listOf() -// }.flatten() + } .groupByKey( groupedAs("server-map-data.tiles.group", kxsBinary.serde(), kxsBinary.serde()) @@ -121,15 +116,20 @@ fun groupTilesIntoChunksWithColours( foreignKeyExtractor = { chunkTiles: ServerMapChunkTiles -> chunkTiles.chunkId.serverId } ) { tiles: ServerMapChunkTiles, colourDict: TileColourDict -> - ServerMapChunkTiles( - tiles.chunkId, - tiles.map.mapValues { (_, code) -> - colourDict.map.getOrElse(code) { - println("missing prototype $code") - ColourHex.TRANSPARENT - } + val missingProtos = mutableSetOf() + + val tileColours = tiles.map.mapValues { (_, code) -> + colourDict.map.getOrElse(code) { + missingProtos.add(code) + ColourHex.TRANSPARENT } - ) + } + + if (missingProtos.isNotEmpty()) { + println("missing ${missingProtos.size} tile prototypes: ${missingProtos.joinToString { "${it.code}" }}") + } + + ServerMapChunkTiles(tiles.chunkId, tileColours) } return colourisedChunkTable diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt index ea7459d..4987c33 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt @@ -36,6 +36,7 @@ fun factorioServerPacketStream( } } + fun splitFactorioServerPacketStream( factorioServerPacketStream: KStream ) { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt index 3ee7439..307c915 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt @@ -2,6 +2,7 @@ package dev.adamko.kafkatorio.processor.topology import com.sksamuel.scrimage.ImmutableImage import com.sksamuel.scrimage.ScaleMethod +import com.sksamuel.scrimage.color.RGBColor import com.sksamuel.scrimage.nio.PngWriter import dev.adamko.kafkatorio.events.schema.ColourHex import dev.adamko.kafkatorio.events.schema.MapChunkPosition @@ -20,7 +21,6 @@ import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.distinctUntilChangedBy import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @@ -63,7 +63,7 @@ fun saveMapTiles( chunkedTiles .conflate() .distinctUntilChanged() - .debounce(5.seconds) + .debounce(1.seconds) .map { println("createMapTileImage ${it.chunkId}") createMapTileImage(it) @@ -164,6 +164,9 @@ private fun createMapTileImage( } +private val TRANSPARENT_AWT = ColourHex.TRANSPARENT.toRgbColor().awt() + + private fun createMapTileImage( chunkPosition: MapChunkPosition, chunkColours: Map, @@ -173,7 +176,7 @@ private fun createMapTileImage( val chunkImage = ImmutableImage.filled( z.chunkSize, z.chunkSize, - ColourHex.TRANSPARENT.toRgbColor().awt(), + TRANSPARENT_AWT, BufferedImage.TYPE_INT_ARGB ) @@ -196,3 +199,13 @@ private fun createMapTileImage( return chunkImage.scaleTo(WEB_MAP_TILE_SIZE_PX, WEB_MAP_TILE_SIZE_PX, ScaleMethod.Progressive) } + + +private fun ColourHex.toRgbColor(): RGBColor { + return RGBColor( + red.toInt(), + green.toInt(), + blue.toInt(), + alpha.toInt(), + ) +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt index 3bae3f1..8bd855d 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt @@ -1,8 +1,5 @@ package dev.adamko.kafkatorio.processor.topology -import com.sksamuel.scrimage.color.RGBColor -import dev.adamko.kafkatorio.events.schema.Colour -import dev.adamko.kafkatorio.events.schema.ColourHex import kotlin.math.pow import kotlin.math.roundToInt import kotlinx.serialization.Serializable @@ -24,16 +21,6 @@ value class FactorioServerId(val id: String) { } -fun ColourHex.toRgbColor(): RGBColor { - return RGBColor( - red.toInt(), - green.toInt(), - blue.toInt(), - alpha.toInt(), - ) -} - - enum class ZoomLevel( val level: Int ) { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index ac19bbd..63ce083 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -5,8 +5,10 @@ import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.events.schema.MapTile import dev.adamko.kafkatorio.events.schema.MapTilePrototype +import dev.adamko.kafkatorio.events.schema.converters.toHex import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kotka.extensions.materializedAs +import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.mapValues import dev.adamko.kotka.extensions.streams.toTable import dev.adamko.kotka.kxs.serde @@ -22,9 +24,10 @@ value class PrototypeName(val name: String) { } +/** Use the hashcode of Prototypes names as keys - more efficient storage */ @JvmInline @Serializable -value class TileProtoHashCode(val code: Int) { +value class TileProtoHashCode private constructor(val code: Int) { constructor(prototype: MapTilePrototype) : this(prototype.name.hashCode()) constructor(tile: MapTile) : this(tile.prototypeName.hashCode()) } @@ -32,19 +35,17 @@ value class TileProtoHashCode(val code: Int) { @JvmInline @Serializable -value class TileColourDict(val map: Map) { - operator fun plus(other: TileColourDict) = TileColourDict(this.map + other.map) -} +value class TileColourDict(val map: Map) -/** Aggregate [KafkatorioPacket]s into a single [FactorioServerMap] (per [serverId][FactorioServerId]). */ +/** Get the latest map-tile colours per server. */ fun tileProtoColourDictionary( factorioServerPacketStream: KStream ): KTable { // get all the prototypes return factorioServerPacketStream - .mapValues("server-map-data.tile-prototypes.mapValues") { _, packet -> + .mapValues("server-map-data.tile-prototypes.mapValues") { _, packet: KafkatorioPacket -> val map = when (packet) { is FactorioPrototypes -> packet .prototypes @@ -53,13 +54,17 @@ fun tileProtoColourDictionary( else -> mapOf() } TileColourDict(map) + }.filter("server-map-data.tile-prototypes.filterMapTileProtos") { _, dict: TileColourDict -> + dict.map.isNotEmpty() + }.peek { serverId, dict: TileColourDict -> + println("server $serverId has TileColourDict[${dict.map.size}]: ${dict.map.entries.joinToString()}") } .toTable( "server-map-data.tile-prototypes", materializedAs( "server-map-data.tile-prototypes.store", jsonMapper.serde(), - jsonMapper.serde() + jsonMapper.serde(), ) ) From 1af591247779a92a70a061dc60186f8fc534e8b7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 8 Feb 2022 14:10:13 +0100 Subject: [PATCH 181/629] even more working - generate zoomed tiles (but also it doesn't work - it stops making new tiles at some point). --- modules/events-server/build.gradle.kts | 6 +- .../processor/topology/flowMapTiles.kt | 305 ++++++++++++++---- .../dev/adamko/kafkatorio/webmap/map.kt | 4 +- 3 files changed, 245 insertions(+), 70 deletions(-) diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 0567e7f..23e9470 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -78,6 +78,6 @@ val kafkatorioEventsServerKafkaForceReset by tasks.registering(Exec::class) { commandLine = parseSpaceSeparatedArgs(""" docker exec -d kafka $cmd """) } -tasks.run.configure { - dependsOn(kafkatorioEventsServerKafkaForceReset) -} +//tasks.run.configure { +// dependsOn(kafkatorioEventsServerKafkaForceReset) +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt index 307c915..5431617 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt @@ -7,21 +7,26 @@ import com.sksamuel.scrimage.nio.PngWriter import dev.adamko.kafkatorio.events.schema.ColourHex import dev.adamko.kafkatorio.events.schema.MapChunkPosition import dev.adamko.kafkatorio.events.schema.MapTilePosition +import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition import java.awt.image.BufferedImage import java.io.File +import kotlin.coroutines.CoroutineContext import kotlin.math.abs -import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.conflate -import kotlinx.coroutines.flow.debounce -import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.flatMapConcat import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.runningFold +import kotlinx.coroutines.job import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.supervisorScope @@ -34,13 +39,15 @@ private val cScope = CoroutineScope( Dispatchers.Default + SupervisorJob() + CoroutineName("f-server-map-updates") ) -/** A bridge between Kafka and Kotlin */ -private val chunkedTiles: MutableSharedFlow> = - MutableSharedFlow( - 0, - 1, - BufferOverflow.SUSPEND - ) +private val serverMapChunkHandler = ServerMapChunkHandler() + +///** A bridge between Kafka and Kotlin */ +//private val chunkedTiles: MutableSharedFlow> = +// MutableSharedFlow( +// 0, +// 1, +// BufferOverflow.SUSPEND +// ) fun saveMapTiles( @@ -53,29 +60,50 @@ fun saveMapTiles( if (value != null) { runBlocking(Dispatchers.Default) { println("emitting chunkedTiles ${value.chunkId} tiles: ${value.map.size}") - chunkedTiles.emit(value) +// chunkedTiles.emit(value) + serverMapChunkHandler.emit(value) } } } - cScope.launch { - supervisorScope { - chunkedTiles - .conflate() - .distinctUntilChanged() - .debounce(1.seconds) - .map { - println("createMapTileImage ${it.chunkId}") - createMapTileImage(it) - } - .collect() - } - } +// cScope.launch { +// supervisorScope { +// chunkedTiles +// .conflate() +// .distinctUntilChanged() +// .debounce(1.seconds) +// .map { +// println("createMapTileImage ${it.chunkId}") +// createMapTileImage(it) +// } +// .collect() +// } +// } // cScope.launch { // println("launching serverMapDataFlow merging") // // chunkedTiles +// .conflate() +// .flatMapConcat { chunk -> +// ZoomLevel.values +// .asFlow() +// .flatMapConcat { zoom -> +// chunk.map.entries +// .groupBy({ (tile, _) -> tile.toMapChunkPosition(zoom.chunkSize) } +// ) { +// it.key to it.value +// } +// .map { (chunkPos, tiles) -> +// val chunkId = chunk.chunkId.copy( +// zoomLevel = zoom, +// chunkPosition = chunkPos +// ) +// ServerMapChunkTiles(chunkId, tiles.toMap()) +// } +// .asFlow() +// } +// } // .runningFold( // mapOf>>() // ) { accumulator, value -> @@ -95,11 +123,14 @@ fun saveMapTiles( // supervisorScope { // println("launching MutableSharedFlow for ${value.chunkId}") // input +// .conflate() +// .distinctUntilChanged() // .debounce(30.seconds) // .mapLatest { // println("createMapTileImage ${it.chunkId}") // createMapTileImage(it) -// }.launchIn(this) +// } +// .launchIn(this) // } // // input @@ -120,49 +151,43 @@ fun saveMapTiles( private value class TilePngFilename( val value: String, ) { - - constructor( - chunkId: ServerMapChunkId - ) : this(buildString { - append("src/main/resources/kafkatorio-web-map/s") - append(chunkId.surfaceIndex.index) - append("/z") - append(chunkId.zoomLevel.level) - append("/x") - append(chunkId.chunkPosition.x) - append("/y") - append(chunkId.chunkPosition.y) + constructor(cmd: Cmd.CreateImage) : this(buildString { + append("src/main/resources/kafkatorio-web-map") + append("/s${cmd.surfaceIndex.index}") + append("/z${cmd.zoomLevel.level}") + append("/x${cmd.chunkPosition.x}") + append("/y${cmd.chunkPosition.y}") append(".png") }) } -private fun createMapTileImage( - chunkTiles: ServerMapChunkTiles -) { - - println("emitting ChunkData ${chunkTiles.chunkId.chunkPosition}") - - println("starting to save chunkData ${chunkTiles.chunkId.chunkPosition}...") - - val filename = TilePngFilename(chunkTiles.chunkId) - - val chunkImageFile = File(filename.value) - if (chunkImageFile.parentFile.mkdirs()) { - println("created new map tile parentFile directory ${chunkImageFile.absolutePath}") - } - - val image = - createMapTileImage( - chunkTiles.chunkId.chunkPosition, - chunkTiles.map, - chunkTiles.chunkId.zoomLevel - ) - - println("saving map tile $chunkImageFile") - val savedTile = image.output(PngWriter.NoCompression, chunkImageFile) - println("savedTile: $savedTile") -} - +//private fun createMapTileImage( +// chunkTiles: ServerMapChunkTiles, +// +// zoomLevel: ZoomLevel +//) { +// +// println("creating chunkData ${chunkTiles.chunkId.chunkPosition}...") +// +// val filename = TilePngFilename(chunkTiles.chunkId) +// +// val chunkImageFile = File(filename.value) +// if (chunkImageFile.parentFile.mkdirs()) { +// println("created new map tile parentFile directory ${chunkImageFile.absolutePath}") +// } +// +// val image = +// createMapTileImage( +// chunkTiles.chunkId.chunkPosition, +// chunkTiles.map, +// chunkTiles.chunkId.zoomLevel +// ) +// +// println("saving map tile $chunkImageFile") +// val savedTile = image.output(PngWriter.NoCompression, chunkImageFile) +// println("savedTile: $savedTile") +//} +// private val TRANSPARENT_AWT = ColourHex.TRANSPARENT.toRgbColor().awt() @@ -197,7 +222,7 @@ private fun createMapTileImage( ) } - return chunkImage.scaleTo(WEB_MAP_TILE_SIZE_PX, WEB_MAP_TILE_SIZE_PX, ScaleMethod.Progressive) + return chunkImage.scaleTo(WEB_MAP_TILE_SIZE_PX, WEB_MAP_TILE_SIZE_PX, ScaleMethod.FastScale) } @@ -209,3 +234,153 @@ private fun ColourHex.toRgbColor(): RGBColor { alpha.toInt(), ) } + +private class ServerMapChunkHandler : CoroutineScope { + + override val coroutineContext: CoroutineContext = Dispatchers.Default + + SupervisorJob(cScope.coroutineContext.job) + + CoroutineName("ServerMapChunkHandler") + + + private val allChunksFlow = MutableSharedFlow>( + replay = 0, + extraBufferCapacity = 10, + onBufferOverflow = BufferOverflow.SUSPEND, + ) + + private val saveImagesFlow = MutableSharedFlow( + replay = 0, + extraBufferCapacity = 10, + onBufferOverflow = BufferOverflow.SUSPEND, + ) + + + init { + + launch { + supervisorScope { + saveImagesFlow +// .conflate() + .onEach { (filename, img) -> + println("saving map tile $filename") + + val chunkImageFile = File(filename.value) + if (chunkImageFile.parentFile.mkdirs()) { + println("created new map tile parentFile directory ${chunkImageFile.absolutePath}") + } + + val savedTile = img.output(PngWriter.NoCompression, chunkImageFile) + println("savedTile: $savedTile") + } + .collect() + } + } + + launch { + supervisorScope { + allChunksFlow +// .conflate() + .runningFold(mapOf>()) { acc, src -> + + val flow = acc.getOrElse(src.chunkId) { + println("creating new subdivide-flow for chunkId ${src.chunkId}") + subdivisionFlow() + } + + launch { + flow.emit(Cmd.ChunkSubdivide(src.chunkId, src.map)) + } + + acc + (src.chunkId to flow) + } + .onEach { + println("allChunksFlow has ${it.size} subdivide-flows: ${it.keys.joinToString()}") + } + .collect() + } + } + + } + + fun emit(mapChunkTiles: ServerMapChunkTiles) { + launch { + allChunksFlow.emit(mapChunkTiles) + } + } + + private fun subdivisionFlow(): MutableSharedFlow { + + val flow = MutableSharedFlow( + replay = 0, + extraBufferCapacity = 10, + onBufferOverflow = BufferOverflow.SUSPEND, + ) + + val saveImgCommands = flow +// .conflate() + .flatMapConcat { subdivideCmd -> + ZoomLevel.values + .asFlow() + .flatMapConcat { zoom -> + subdivideCmd.tiles + .entries + .groupBy({ (tile, _) -> tile.toMapChunkPosition(zoom.chunkSize) } + ) { + it.key to it.value + } + .map { (chunkPos, tiles) -> + Cmd.CreateImage( + surfaceIndex = subdivideCmd.chunkId.surfaceIndex, + zoomLevel = zoom, + chunkPosition = chunkPos, + tiles = tiles.toMap() + ) + } + .asFlow() + } + } + .map { createCmd -> + val filename = TilePngFilename(createCmd) + + val img = createMapTileImage( + createCmd.chunkPosition, + createCmd.tiles, + createCmd.zoomLevel, + ) + + Cmd.SaveImage(filename, img) + } + + launch { + supervisorScope { + println("emitting all saveImgCommands to saveImagesFlow") + saveImagesFlow.emitAll(saveImgCommands) + } + } + + return flow + } + + +} + +private sealed interface Cmd { + + data class ChunkSubdivide( + val chunkId: ServerMapChunkId, + val tiles: Map, + ) : Cmd + + data class CreateImage( + val surfaceIndex: SurfaceIndex, + val zoomLevel: ZoomLevel, + val chunkPosition: MapChunkPosition, + val tiles: Map, + ) : Cmd + + data class SaveImage( + val filename: TilePngFilename, + val image: ImmutableImage, + ) : Cmd + +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index 934ebb6..a0ef35b 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -36,8 +36,8 @@ fun createFactorioMap() = Maps { tms = true // minZoom = -2 // maxZoom = 1 - maxNativeZoom = 5 - minNativeZoom = 1 + maxNativeZoom = 4 + minNativeZoom = 0 noWrap = true updateWhenIdle = true updateWhenZooming = true From 215ef66fbd25641b2d0b2631581bcdb24526394f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 8 Feb 2022 14:55:11 +0100 Subject: [PATCH 182/629] delete old code, try and tidy up coroutines launching --- .../processor/KafkatorioTopology.kt | 12 -- .../processor/topology/factorioGameState.kt | 75 ------- .../processor/topology/factorioMapTiles.kt | 78 -------- .../topology/factorioServerPackets.kt | 30 --- .../processor/topology/flowMapTiles.kt | 183 +++--------------- .../processor/topology/webMapTileAggregate.kt | 173 ----------------- .../processor/topology/webMapTiles.kt | 101 ---------- 7 files changed, 29 insertions(+), 623 deletions(-) delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index ffad94f..06bf8ac 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -30,8 +30,6 @@ class KafkatorioTopology( playerUpdatesToWsServer(websocketServer, builder) -// val serverMapDataTable = buildFactorioServerMap(packets, tilePrototypesTable) - val tileProtoColourDict = tileProtoColourDictionary(packets) val tilePrototypesTable = groupTilesIntoChunksWithColours( @@ -40,16 +38,6 @@ class KafkatorioTopology( ) saveMapTiles(tilePrototypesTable) - - // the old way... -// val allMapTilesTable: KTable = allMapTilesTable(builder) -// val tilePrototypeColourTable: KTable = tilePrototypeColourTable(builder) -// -// val webMapTiles: KTable = -// aggregateWebMapTiles(allMapTilesTable, tilePrototypeColourTable) -// -// saveTileImages(webMapTiles) - val topology = builder.build() val streams = KafkaStreams(topology, appProps.kafkaConfig) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt index 3de8cc6..c49d6fb 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt @@ -20,22 +20,6 @@ import kotlinx.serialization.Serializable import org.apache.kafka.streams.kstream.KStream import org.apache.kafka.streams.kstream.KTable - -//@Serializable -//data class FactorioServerMap( -// val serverId: FactorioServerId, -// val tilePrototypes: Map, -// val surfaces: Map, -//) - - -//@Serializable -//data class FactorioMapSurface( -// val index: SurfaceIndex, -// val tiles: Map, -//) - - @Serializable data class ServerMapChunkId( val serverId: FactorioServerId, @@ -135,62 +119,3 @@ fun groupTilesIntoChunksWithColours( return colourisedChunkTable } - -//@Serializable -//private data class FactorioServerMapAggregator( -// val tilePrototypes: SortedMap = TreeMap(), -// val surfaces: MutableMap = mutableMapOf(), -//) { -// -// operator fun plus(packet: KafkatorioPacket): FactorioServerMapAggregator { -// return when (packet) { -// is FactorioEvent -> { -// when (val data = packet.data) { -// is MapChunk -> plus(data) -// is MapTiles -> plus(data) -// else -> this -// } -// } -// is FactorioPrototypes -> plus(packet) -// is FactorioConfigurationUpdate -> this -// } -// } -// -// operator fun plus(mapTiles: MapTiles): FactorioServerMapAggregator { -//// println("FactorioServerMapAggregator: adding ${mapTiles.tiles.size} MapTiles from surface ${mapTiles.surfaceIndex}") -// -// val surfaceIndex = SurfaceIndex(mapTiles.surfaceIndex) -// -// val surface = surfaces.getOrPut(surfaceIndex) { FactorioMapSurfaceAggregator(surfaceIndex) } -// -// val surfaceTiles = mapTiles.tiles.associate { it.position to PrototypeName(it.prototypeName) } -// surface.tiles.putAll(surfaceTiles) -// -// return this -// } -// -// operator fun plus(mapChunk: MapChunk): FactorioServerMapAggregator { -//// println("FactorioServerMapAggregator: adding mapChunk ${mapChunk.position}") -// return plus(mapChunk.tiles) -// } -// -// operator fun plus(packet: FactorioPrototypes): FactorioServerMapAggregator { -//// println("FactorioServerMapAggregator: adding FactorioPrototypes") -// -// val packetPrototypes = packet.prototypes -// .filterIsInstance() -// .associate { PrototypeName(it.name) to it.mapColour } -// -// tilePrototypes.putAll(packetPrototypes) -// -// return this -// } -// -//} - -// -//@Serializable -//private data class FactorioMapSurfaceAggregator( -// val index: SurfaceIndex, -// val tiles: MutableMap = mutableMapOf(), -//) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt deleted file mode 100644 index 97242dc..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioMapTiles.kt +++ /dev/null @@ -1,78 +0,0 @@ -package dev.adamko.kafkatorio.processor.topology - -import dev.adamko.kafkatorio.events.schema.FactorioEvent -import dev.adamko.kafkatorio.events.schema.FactorioObjectData -import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -import dev.adamko.kafkatorio.events.schema.MapChunk -import dev.adamko.kafkatorio.events.schema.MapTile -import dev.adamko.kafkatorio.events.schema.MapTilePosition -import dev.adamko.kafkatorio.events.schema.MapTiles -import dev.adamko.kafkatorio.processor.serdes.jsonMapper -import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kotka.extensions.consumedAs -import dev.adamko.kotka.extensions.materializedWith -import dev.adamko.kotka.extensions.streams.filter -import dev.adamko.kotka.extensions.streams.flatMap -import dev.adamko.kotka.extensions.streams.mapValues -import dev.adamko.kotka.extensions.streams.toTable -import dev.adamko.kotka.kxs.serde -import java.time.Duration -import kotlinx.serialization.Serializable -import org.apache.kafka.streams.StreamsBuilder -import org.apache.kafka.streams.kstream.KStream -import org.apache.kafka.streams.kstream.KTable -import org.apache.kafka.streams.kstream.Suppressed - - -@Serializable -data class TileUpdateRecordKey( - val surfaceIndex: SurfaceIndex, - val tilePosition: MapTilePosition, -) - - -fun allMapTilesTable( - builder: StreamsBuilder -): KTable { - - val luaTilesUpdatesStream: KStream = - builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", - consumedAs("consume-map-tiles-packets", jsonMapper.serde(), jsonMapper.serde()) - ) - .filter("events.filter.map-tiles") { _: FactorioServerId, event: FactorioEvent -> - event.data is MapTiles - } - .mapValues("events.extract-map-tiles") { _, event: FactorioEvent -> - (event.data as? MapTiles)!! - } - - val chunkTilesUpdateStream: KStream = - builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", - consumedAs("consume-map-chunk-packets", jsonMapper.serde(), jsonMapper.serde()) - ) - .filter("events.filter.map-chunks") { _: FactorioServerId, event: FactorioEvent -> - event.data is MapChunk - } - .mapValues("events.extract-map-chunks") { _, event: FactorioEvent -> - (event.data as? MapChunk)!!.tiles - } - - return luaTilesUpdatesStream - .merge(chunkTilesUpdateStream) - .flatMap("flat-map-all-tiles") { _, value -> - value.tiles.map { tile -> - val key = TileUpdateRecordKey( - SurfaceIndex(value.surfaceIndex), - tile.position - ) - key to tile - } - } - .toTable( - "all-tiles-keyed-on-position", - materializedWith(kxsBinary.serde(), kxsBinary.serde()) - ) - -} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt index 4987c33..7731256 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt @@ -59,33 +59,3 @@ fun splitFactorioServerPacketStream( } } } - -//@Serializable -//data class FactorioPacketKey( -// val serverId: FactorioServerId, -// /** arbitrary distinctive key */ -// val key: String, -//) -// -//private fun createPacketKey(packet: KafkatorioPacket): String { -// -// return when (packet) { -// is FactorioEvent -> factorioEventKey(packet) -// is FactorioConfigurationUpdate, -// is FactorioPrototypes -> packet.hashCode().toString() -// } -//} -// -//private fun factorioEventKey(event: FactorioEvent): String { -// val id: String = when (val data = event.data) { -// is ConsoleChatMessage -> data.authorPlayerIndex?.toString() -// is EntityData -> data.type -// is MapChunk -> data.position.toString() -//// is MapTile -> data.position.toString() -// is MapTiles -> data.tiles.firstOrNull()?.position?.toMapChunkPosition()?.toString() -// is PlayerData -> (data.characterUnitNumber?.toString() ?: data.name) -// is SurfaceData -> data.index.toString() -// } ?: event.tick.toString() -// -// return id -//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt index 5431617..a119712 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt @@ -19,10 +19,9 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.asFlow -import kotlinx.coroutines.flow.collect -import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.emitAll import kotlinx.coroutines.flow.flatMapConcat +import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.runningFold @@ -39,15 +38,9 @@ private val cScope = CoroutineScope( Dispatchers.Default + SupervisorJob() + CoroutineName("f-server-map-updates") ) -private val serverMapChunkHandler = ServerMapChunkHandler() -///** A bridge between Kafka and Kotlin */ -//private val chunkedTiles: MutableSharedFlow> = -// MutableSharedFlow( -// 0, -// 1, -// BufferOverflow.SUSPEND -// ) +/** A bridge between Kafka and Kotlin */ +private val serverMapChunkHandler = ServerMapChunkHandler() fun saveMapTiles( @@ -60,90 +53,11 @@ fun saveMapTiles( if (value != null) { runBlocking(Dispatchers.Default) { println("emitting chunkedTiles ${value.chunkId} tiles: ${value.map.size}") -// chunkedTiles.emit(value) serverMapChunkHandler.emit(value) } } } -// cScope.launch { -// supervisorScope { -// chunkedTiles -// .conflate() -// .distinctUntilChanged() -// .debounce(1.seconds) -// .map { -// println("createMapTileImage ${it.chunkId}") -// createMapTileImage(it) -// } -// .collect() -// } -// } - -// cScope.launch { -// println("launching serverMapDataFlow merging") -// -// chunkedTiles -// .conflate() -// .flatMapConcat { chunk -> -// ZoomLevel.values -// .asFlow() -// .flatMapConcat { zoom -> -// chunk.map.entries -// .groupBy({ (tile, _) -> tile.toMapChunkPosition(zoom.chunkSize) } -// ) { -// it.key to it.value -// } -// .map { (chunkPos, tiles) -> -// val chunkId = chunk.chunkId.copy( -// zoomLevel = zoom, -// chunkPosition = chunkPos -// ) -// ServerMapChunkTiles(chunkId, tiles.toMap()) -// } -// .asFlow() -// } -// } -// .runningFold( -// mapOf>>() -// ) { accumulator, value -> -// -// println("folding chunkedTiles ${value.chunkId}, current flows: ${accumulator.keys}") -// -// val chunkFlow = accumulator.getOrElse(value.chunkId) { -// -// println("creating new MutableSharedFlow for ${value.chunkId}") -// -// val input = MutableSharedFlow>( -// replay = 0, -// extraBufferCapacity = 1, -// onBufferOverflow = BufferOverflow.DROP_OLDEST, -// ) -// -// supervisorScope { -// println("launching MutableSharedFlow for ${value.chunkId}") -// input -// .conflate() -// .distinctUntilChanged() -// .debounce(30.seconds) -// .mapLatest { -// println("createMapTileImage ${it.chunkId}") -// createMapTileImage(it) -// } -// .launchIn(this) -// } -// -// input -// } -// -// chunkFlow.emit(value) -// -// accumulator + (value.chunkId to chunkFlow) -// } -// .collect() -// -// println("end of cScope.launch") -// } } @@ -161,33 +75,6 @@ private value class TilePngFilename( }) } -//private fun createMapTileImage( -// chunkTiles: ServerMapChunkTiles, -// -// zoomLevel: ZoomLevel -//) { -// -// println("creating chunkData ${chunkTiles.chunkId.chunkPosition}...") -// -// val filename = TilePngFilename(chunkTiles.chunkId) -// -// val chunkImageFile = File(filename.value) -// if (chunkImageFile.parentFile.mkdirs()) { -// println("created new map tile parentFile directory ${chunkImageFile.absolutePath}") -// } -// -// val image = -// createMapTileImage( -// chunkTiles.chunkId.chunkPosition, -// chunkTiles.map, -// chunkTiles.chunkId.zoomLevel -// ) -// -// println("saving map tile $chunkImageFile") -// val savedTile = image.output(PngWriter.NoCompression, chunkImageFile) -// println("savedTile: $savedTile") -//} -// private val TRANSPARENT_AWT = ColourHex.TRANSPARENT.toRgbColor().awt() @@ -257,48 +144,36 @@ private class ServerMapChunkHandler : CoroutineScope { init { - launch { - supervisorScope { - saveImagesFlow -// .conflate() - .onEach { (filename, img) -> - println("saving map tile $filename") + allChunksFlow + .runningFold(mapOf>()) { acc, src -> - val chunkImageFile = File(filename.value) - if (chunkImageFile.parentFile.mkdirs()) { - println("created new map tile parentFile directory ${chunkImageFile.absolutePath}") - } + val flow = acc.getOrElse(src.chunkId) { + println("creating new subdivide-flow for chunkId ${src.chunkId}") + subdivisionFlow() + } - val savedTile = img.output(PngWriter.NoCompression, chunkImageFile) - println("savedTile: $savedTile") - } - .collect() + flow.emit(Cmd.ChunkSubdivide(src.chunkId, src.map)) + + acc + (src.chunkId to flow) } - } - - launch { - supervisorScope { - allChunksFlow -// .conflate() - .runningFold(mapOf>()) { acc, src -> - - val flow = acc.getOrElse(src.chunkId) { - println("creating new subdivide-flow for chunkId ${src.chunkId}") - subdivisionFlow() - } - - launch { - flow.emit(Cmd.ChunkSubdivide(src.chunkId, src.map)) - } - - acc + (src.chunkId to flow) - } - .onEach { - println("allChunksFlow has ${it.size} subdivide-flows: ${it.keys.joinToString()}") - } - .collect() + .onEach { + println("allChunksFlow has ${it.size} subdivide-flows: ${it.keys.joinToString()}") } - } + .launchIn(this) + + saveImagesFlow + .onEach { (filename, img) -> + println("saving map tile $filename") + + val chunkImageFile = File(filename.value) + if (chunkImageFile.parentFile.mkdirs()) { + println("created new map tile parentFile directory ${chunkImageFile.absolutePath}") + } + + val savedTile = img.output(PngWriter.NoCompression, chunkImageFile) + println("savedTile: $savedTile") + } + .launchIn(this) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt deleted file mode 100644 index 1916e55..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTileAggregate.kt +++ /dev/null @@ -1,173 +0,0 @@ -package dev.adamko.kafkatorio.processor.topology - -import com.sksamuel.scrimage.color.RGBColor -import dev.adamko.kafkatorio.events.schema.Colour -import dev.adamko.kafkatorio.events.schema.MapTile -import dev.adamko.kafkatorio.events.schema.MapTilePosition -import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition -import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kotka.extensions.groupedAs -import dev.adamko.kotka.extensions.materializedAs -import dev.adamko.kotka.extensions.materializedWith -import dev.adamko.kotka.extensions.namedAs -import dev.adamko.kotka.extensions.streams.groupBy -import dev.adamko.kotka.extensions.tables.groupBy -import dev.adamko.kotka.extensions.tables.join -import dev.adamko.kotka.extensions.tables.mapValues -import dev.adamko.kotka.extensions.tables.toStream -import dev.adamko.kotka.extensions.toKeyValue -import dev.adamko.kotka.kxs.serde -import java.awt.Color -import java.time.Duration -import kotlinx.serialization.Serializable -import org.apache.kafka.streams.kstream.KTable -import org.apache.kafka.streams.kstream.SessionWindows -import org.apache.kafka.streams.kstream.Suppressed -import org.apache.kafka.streams.kstream.Windowed - - -/** The tiles of the webmap will be this many pixels high/wide */ -const val WEB_MAP_IMAGE_TILE_SIZE = 256 - -/** Debounce duration */ -private val WINDOW_INACTIVITY_DURATION = Duration.ofSeconds(60) - -@Serializable -data class WebMapTileChunkPosition( - val chunkSize: Int, - val x: Int, - val y: Int, - val surfaceIndex: SurfaceIndex, -) - -@Serializable -private data class WebMapTilePixel( - val mapColour: Colour, - val tilePosition: MapTilePosition, -) - -@Serializable -@JvmInline -value class WebMapTileChunkPixels( - val pixels: Map, -) - -/** Temporary mutable accumulator */ -@Serializable -@JvmInline -private value class WebMapTileChunkPixelsAcc( - val pixels: MutableMap = mutableMapOf(), -) { - - operator fun plus(pixel: WebMapTilePixel): WebMapTileChunkPixelsAcc { - pixels[pixel.tilePosition] = pixel.mapColour - return this - } - - operator fun plus(other: WebMapTileChunkPixelsAcc): WebMapTileChunkPixelsAcc { - this.pixels += other.pixels - return this - } - - operator fun minus(other: WebMapTileChunkPixelsAcc): WebMapTileChunkPixelsAcc { - this.pixels -= other.pixels.keys - return this - } - -} - - -fun aggregateWebMapTiles( - allMapTilesTable: KTable, - tilePrototypeColourTable: KTable, -): KTable { - - - val pixels: KTable = - allMapTilesTable - .join( - tilePrototypeColourTable, - "convert-tiles-to-colours", - materializedAs( - "store-web-map-tile-pixels", - kxsBinary.serde(), - kxsBinary.serde(), - ), - { PrototypeName(it.prototypeName) }, - ) { tile: MapTile, colour: Colour -> - WebMapTilePixel(colour, tile.position) - } - - - val chunkedPixelsWindowed: KTable, WebMapTileChunkPixelsAcc> = - pixels - .toStream("stream-webmap-tile-pixels") - .groupBy( - groupedAs( - "group-webmap-tile-colours-into-chunks", - kxsBinary.serde(), - kxsBinary.serde(), - ) - ) { pos: TileUpdateRecordKey, _: WebMapTilePixel -> - val (chunkX, chunkY) = pos.tilePosition.toMapChunkPosition(WEB_MAP_IMAGE_TILE_SIZE) - val chunkPos = WebMapTileChunkPosition( - WEB_MAP_IMAGE_TILE_SIZE, - chunkX, - chunkY, - pos.surfaceIndex - ) - chunkPos - } - .windowedBy( - SessionWindows.ofInactivityGapAndGrace( - WINDOW_INACTIVITY_DURATION, - WINDOW_INACTIVITY_DURATION, - ) - ) - .aggregate( - { WebMapTileChunkPixelsAcc() }, - { _: WebMapTileChunkPosition, newValue: WebMapTilePixel, acc: WebMapTileChunkPixelsAcc -> - acc + newValue - }, - { _, aggOne: WebMapTileChunkPixelsAcc, aggTwo: WebMapTileChunkPixelsAcc -> - aggOne + aggTwo - }, - namedAs("web-map-tile-colours-into-$WEB_MAP_IMAGE_TILE_SIZE-chunks"), - materializedAs( - "web-map-tile-colour-chunks-aggregate", - kxsBinary.serde(), - kxsBinary.serde() - ) - ) - .suppress( - Suppressed.untilWindowCloses( - Suppressed.BufferConfig.unbounded() - ).withName("chunked-pixels-debounce") - ) - - - // merge windows - val chunkedPixels: KTable = - chunkedPixelsWindowed - .groupBy( - groupedAs("merge-chunked-pixels.group-keys", kxsBinary.serde(), kxsBinary.serde()) - ) { a: Windowed, b: WebMapTileChunkPixelsAcc -> - (a.key() to b).toKeyValue() - } - .reduce( - /* adder */ - { pixels1, pixels2 -> pixels1 + pixels2 }, - /* subtractor */ - { pixels1, pixels2 -> pixels1 - pixels2 }, - namedAs("merge-chunked-pixels.reduce-values"), - materializedAs("merge-chunked-pixels.reduce-values.store", kxsBinary.serde(), kxsBinary.serde()) - ) - - return chunkedPixels - .mapValues( - "finalise-web-map-tile-colour-chunk-aggregation", - materializedAs("web-map-tile-colour-chunks", kxsBinary.serde(), kxsBinary.serde()) - ) { _: WebMapTileChunkPosition, v: WebMapTileChunkPixelsAcc -> - WebMapTileChunkPixels(v.pixels) - } -} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt deleted file mode 100644 index 2e609a7..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/webMapTiles.kt +++ /dev/null @@ -1,101 +0,0 @@ -package dev.adamko.kafkatorio.processor.topology - -import com.sksamuel.scrimage.ImmutableImage -import com.sksamuel.scrimage.color.RGBColor -import com.sksamuel.scrimage.nio.PngWriter -import dev.adamko.kafkatorio.events.schema.Colour -import dev.adamko.kafkatorio.events.schema.MapTilePosition -import dev.adamko.kotka.extensions.tables.toStream -import java.awt.Color -import java.awt.image.BufferedImage -import java.io.File -import kotlin.math.abs -import kotlin.math.roundToInt -import org.apache.kafka.streams.kstream.KTable - -// -//val COLOUR_TRANSPARENT: RGBColor = RGBColor.fromAwt(Color(0f, 0f, 0f, 0f)) -// -//fun saveTileImages( -// webMapTiles: KTable -//) { -// -// webMapTiles -// .toStream("get-webmap-tile-updates") -// .foreach { position: WebMapTileChunkPosition, pixels: WebMapTileChunkPixels -> -// runCatching { -// saveMapTilesPng(position, pixels.pixels) -// }.onFailure { e -> -// println("error saving map tile png chunk: $position") -// e.printStackTrace() -// throw e -// } -// } -//} -// -////val saveMapTilesContext = Dispatchers.IO.limitedParallelism(1) -// -// -//private fun saveMapTilesPng( -// chunkPosition: WebMapTileChunkPosition, -// pixels: Map, -//) { -// val chunkOriginX: Int = chunkPosition.x * chunkPosition.chunkSize // - 1 -// val chunkOriginY: Int = chunkPosition.y * chunkPosition.chunkSize // - 1 -// val surfaceIndex: Int = chunkPosition.surfaceIndex.index -// -// val chunkImage = -// ImmutableImage.filled( -// chunkPosition.chunkSize, -// chunkPosition.chunkSize, -// COLOUR_TRANSPARENT.awt(), -// BufferedImage.TYPE_INT_ARGB -// ) -// -// pixels.forEach { (tilePosition, colour) -> -// -// val rgbColour = colour.toRgbColor() -// -// val pixelX = abs(abs(tilePosition.x) - abs(chunkOriginX)) -// val pixelY = abs(abs(tilePosition.y) - abs(chunkOriginY)) -// -// chunkImage.setColor( -// pixelX, -// pixelY, -// rgbColour -// ) -// -// } -// -// val zoom = 1u -// val file = -// File(tileFilename("$surfaceIndex", "$zoom", "${chunkPosition.x}", "${chunkPosition.y}")) -// -// if (file.parentFile.mkdirs()) { -// println("created new map tile parentFile directory ${file.absolutePath}") -// } -// -// println("saving map tile $file") -// val savedTile = chunkImage.output(PngWriter.NoCompression, file) -// println("savedTile: $savedTile") -//} -// -//fun tileFilename( -// surfaceIndex: String, -// zoom: String, -// chunkX: String, -// chunkY: String, -//) = "src/main/resources/kafkatorio-web-map/s${surfaceIndex}/z$zoom/x${chunkX}/y${chunkY}.png" -// -////fun subdivide(tile: ImmutableImage, size: Int) { -//// -//// val halfSize = size / 2 -//// -//// val bl = tile.resizeTo(halfSize, halfSize, Position.BottomLeft) -//// val savedTile = bl.output(PngWriter.NoCompression, file) -//// -//// tile.resizeTo(halfSize, halfSize, Position.BottomRight) -//// tile.resizeTo(halfSize, halfSize, Position.TopLeft) -//// tile.resizeTo(halfSize, halfSize, Position.TopRight) -//// -////} From ba03f761e0e67558e6e8c7a25d44c7a5c71d6335 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 8 Feb 2022 17:56:34 +0100 Subject: [PATCH 183/629] zoom zoom faster - make 3 different Kafka consumers for player/tile/packet updates --- .../processor/KafkatorioTopology.kt | 72 ++++++++++++++----- .../processor/config/ApplicationProperties.kt | 8 +-- .../kafkatorio/processor/eventProcessor.kt | 2 +- 3 files changed, 60 insertions(+), 22 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 06bf8ac..33d9a16 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -7,29 +7,38 @@ import dev.adamko.kafkatorio.processor.topology.saveMapTiles import dev.adamko.kafkatorio.processor.topology.splitFactorioServerPacketStream import dev.adamko.kafkatorio.processor.topology.tileProtoColourDictionary import java.time.Duration +import kotlin.coroutines.CoroutineContext +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.job +import kotlinx.coroutines.launch import org.apache.kafka.streams.KafkaStreams import org.apache.kafka.streams.StreamsBuilder -import org.apache.kafka.streams.TopologyDescription +import org.apache.kafka.streams.StreamsConfig +import org.apache.kafka.streams.Topology class KafkatorioTopology( private val websocketServer: WebsocketServer, - private val builder: StreamsBuilder = StreamsBuilder(), -) { +) : CoroutineScope { + override val coroutineContext: CoroutineContext = + Dispatchers.Default + SupervisorJob() + CoroutineName("KafkatorioTopology") companion object { const val sourceTopic = "factorio-server-log" } + fun start() { + saveTiles() + splitPackets() + playerUpdates() + } - fun build() { - + private fun saveTiles() { + val builder = StreamsBuilder() val packets = factorioServerPacketStream(builder) - - splitFactorioServerPacketStream(packets) - - playerUpdatesToWsServer(websocketServer, builder) - val tileProtoColourDict = tileProtoColourDictionary(packets) val tilePrototypesTable = groupTilesIntoChunksWithColours( @@ -40,17 +49,46 @@ class KafkatorioTopology( val topology = builder.build() - val streams = KafkaStreams(topology, appProps.kafkaConfig) + launchTopology("saveTiles", topology) + } -// streams.cleanUp() + private fun splitPackets() { + + val builder = StreamsBuilder() + val packets = factorioServerPacketStream(builder) + splitFactorioServerPacketStream(packets) + + val topology = builder.build() + + launchTopology("splitPackets", topology) + } + + private fun playerUpdates() { + val builder = StreamsBuilder() + playerUpdatesToWsServer(websocketServer, builder) + + val topology = builder.build() + + launchTopology("playerUpdates", topology) + } + + private fun launchTopology(id: String, topology: Topology) { + + val props = appProps.kafkaConfig + + val appId = props.compute(StreamsConfig.APPLICATION_ID_CONFIG) { _, v -> "$v.$id" } as? String + props.setProperty(StreamsConfig.APPLICATION_ID_CONFIG, appId) + + + val streams = KafkaStreams(topology, props) streams.setUncaughtExceptionHandler(StreamsExceptionHandler()) - Runtime.getRuntime().addShutdownHook(Thread { streams.close(Duration.ofSeconds(1)) }) - val description: TopologyDescription = topology.describe() - println(description) - - streams.start() + coroutineContext.job.invokeOnCompletion { + println("closing $id KafkaStreams") + streams.close(Duration.ofSeconds(1)) + } + launch { streams.start() } } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt index f462adb..a7f523e 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt @@ -45,10 +45,10 @@ class ApplicationProperties( val kafkaConfig: Properties get() = EnvironmentKey .nonEmptyString() - .map { - it.reader().use { sr -> - Properties().also { p -> - p.load(sr) + .map { srcString -> + srcString.reader().use { stringReader -> + Properties().also { properties -> + properties.load(stringReader) } } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt index a8b487b..8e0c334 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -21,7 +21,7 @@ fun main(): Unit = runBlocking { val tileServer = WebMapTileServer() val topology = KafkatorioTopology(wsServer) - topology.build() + topology.start() val webServer = PolyHandler( tileServer.build(), From 123cdb5e9a835bb44682f28e7c6c9fc6c4b2c834 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 8 Feb 2022 17:56:49 +0100 Subject: [PATCH 184/629] vlc save cmds --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index f883e79..4cb3c8b 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ is provided. `./bin/kafka-streams-application-reset.sh --application-id kafkatorio-events-processor --input-topics factorio-server-log` +`:screen-fps=60.000000 :live-caching=300 :screen-width=1920 :screen-height=1080 :screen-top=20 :screen-left:20` +`:screen-fps=60.000000 :live-caching=300 --screen-width=1920 --screen-height=1080 :sout=#transcode{vcodec=h264,vb=0,scale=0,acodec=mpga,ab=128,channels=2,samplerate=44100}:file{dst=D:\\savedir.mp4} :sout-keep` ## todo @@ -67,3 +69,5 @@ https://www.npmjs.com/package/wasm2lua?activeTab=readme * BSON * https://github.com/mpaland/bsonfy * https://github.com/tcoram/bson-lua + +* bebop https://rainway.com/blog/2020/12/09/bebop-an-efficient-schema-based-binary-serialization-format/ From 0f0d968a6a80a21cb9667cd4b6b3301817507215 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 8 Feb 2022 17:57:06 +0100 Subject: [PATCH 185/629] rm imperial map scale --- .../web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index a0ef35b..c6f308f 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -45,6 +45,7 @@ fun createFactorioMap() = Maps { L.scale { metric = true + imperial = false }.addTo(this) From 11cbb898218c472a26c2e1725471b0292830f174 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 9 Feb 2022 10:45:23 +0100 Subject: [PATCH 186/629] tweaking map scale/zoom --- README.md | 2 +- .../src/main/typescript/main/queue/queue.ts | 11 ++--------- .../adamko/kafkatorio/webmap/converters.kt | 2 +- .../dev/adamko/kafkatorio/webmap/map.kt | 19 +++++++++++++------ 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 4cb3c8b..8b73398 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ is provided. `./bin/kafka-streams-application-reset.sh --application-id kafkatorio-events-processor --input-topics factorio-server-log` -`:screen-fps=60.000000 :live-caching=300 :screen-width=1920 :screen-height=1080 :screen-top=20 :screen-left:20` +`:screen-fps=60.000000 :live-caching=300 :screen-width=1920 :screen-height=1080 :screen-top=100 :screen-left:20` `:screen-fps=60.000000 :live-caching=300 --screen-width=1920 --screen-height=1080 :sout=#transcode{vcodec=h264,vb=0,scale=0,acodec=mpga,ab=128,channels=2,samplerate=44100}:file{dst=D:\\savedir.mp4} :sout-keep` ## todo diff --git a/modules/events-mod/src/main/typescript/main/queue/queue.ts b/modules/events-mod/src/main/typescript/main/queue/queue.ts index f5d60f2..b985b2e 100644 --- a/modules/events-mod/src/main/typescript/main/queue/queue.ts +++ b/modules/events-mod/src/main/typescript/main/queue/queue.ts @@ -72,6 +72,7 @@ export namespace Queue { } } + export function dequeueValues(targetWeight: uint = 50): EventData[] { let values: EventData[] = [] let weight: uint = 0 @@ -107,18 +108,10 @@ export namespace Queue { [key: string]: EventData | null; } -// interface PacketQueue { -// enqueue(key: string, packet: T, weight: int): void -// -// dequeue(): WeightedPacket | null -// -// dequeueValues(targetWeight: int): T[] -// } -// + interface WeightedPacket { value: EventData, weight: int, } - } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt index 1177aa7..386370b 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt @@ -4,4 +4,4 @@ import dev.adamko.kafkatorio.events.schema.PlayerData import io.kvision.maps.Maps import io.kvision.maps.externals.leaflet.geo.LatLng -fun PlayerData.latLng(): LatLng = Maps.L.latLng((position.y * -1) / 2 to position.x / 2) +fun PlayerData.latLng(): LatLng = Maps.L.latLng((position.y * -1) to position.x) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index c6f308f..c8bda6d 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -27,22 +27,28 @@ fun createFactorioMap() = Maps { configureLeafletMap { setView(LatLng(0, 0), 1) -// DefaultTileLayers.OpenStreetMap.addTo(this) + L.tileLayer( """http://localhost:9073/tiles/s1/z{z}/x{x}/y{y}.png""" ) { attribution = "kafkatorio" tileSize = 256 tms = true -// minZoom = -2 -// maxZoom = 1 - maxNativeZoom = 4 - minNativeZoom = 0 + + minZoom = -2 + maxZoom = 6 + + // NOTE: offset the zoom, so 1 meter = 1 tile + maxNativeZoom = 3 + minNativeZoom = -1 + zoomOffset = 1 + noWrap = true - updateWhenIdle = true + updateWhenIdle = false updateWhenZooming = true }.addTo(this) + L.scale { metric = true imperial = false @@ -50,6 +56,7 @@ fun createFactorioMap() = Maps { options.crs = CRS.Simple + options.zoomSnap = 0.1 } } From 96412bf7c933462d640dce89923b7af82b332c05 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 9 Feb 2022 11:53:58 +0100 Subject: [PATCH 187/629] bump gradle version. gradle build scripts tidy up. Make versions more consistent, share some config --- .kotlin-js-store/yarn.lock | 3668 +++++++++++++++++ build.gradle.kts | 2 +- buildSrc/build.gradle.kts | 46 +- buildSrc/src/main/kotlin/Versions.kt | 13 + .../kotlin/dev/adamko/kafkatorio/common.kt | 17 + .../kafkatorio/lang/kotlin-js.gradle.kts | 13 +- .../kafkatorio/lang/kotlin-jvm.gradle.kts | 16 +- .../lang/kotlin-multiplatform.gradle.kts | 24 +- .../adamko/kafkatorio/lang/node.gradle.kts | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- modules/events-schema/build.gradle.kts | 4 +- modules/events-server/build.gradle.kts | 2 +- modules/web-map/build.gradle.kts | 2 +- 13 files changed, 3752 insertions(+), 61 deletions(-) create mode 100644 .kotlin-js-store/yarn.lock create mode 100644 buildSrc/src/main/kotlin/Versions.kt diff --git a/.kotlin-js-store/yarn.lock b/.kotlin-js-store/yarn.lock new file mode 100644 index 0000000..d6ee670 --- /dev/null +++ b/.kotlin-js-store/yarn.lock @@ -0,0 +1,3668 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/runtime@^7.9.2": + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941" + integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw== + dependencies: + regenerator-runtime "^0.13.4" + +"@discoveryjs/json-ext@^0.5.0": + version "0.5.6" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" + integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA== + +"@fortawesome/fontawesome-free@^5.15.4": + version "5.15.4" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5" + integrity sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@popperjs/core@^2.11.2": + version "2.11.2" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.2.tgz#830beaec4b4091a9e9398ac50f865ddea52186b9" + integrity sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA== + +"@rjaros/gettext.js@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@rjaros/gettext.js/-/gettext.js-1.1.3.tgz#8d1109f4a6f8e0c4dadba26281c7fe83de8ab18f" + integrity sha512-FgGWKCN88UE6nOmIjdv+gSnrE3AXjMx7f4uo3brLzKcC9dKzuNNDCzTIbuEDg38Pm1yYUTUH6QG4493T4sUnDg== + dependencies: + "@rjaros/po2json" "^1.0.0-beta-4" + +"@rjaros/po2json@^1.0.0-beta-4": + version "1.0.0-beta-4" + resolved "https://registry.yarnpkg.com/@rjaros/po2json/-/po2json-1.0.0-beta-4.tgz#0bd911af874afa39d868aeb88f6903cfabfbf5dd" + integrity sha512-VhNHrPJtX+caY99UnjCmMB0EWY4EgtZ/pj/Usyj4VUt3TtjHE5nV+fz4bVC0/OO641ncEFFfC3SJ2TurcwEWPw== + dependencies: + commander "^6.0.0" + gettext-parser "2.0.0" + gettext-to-messageformat "0.3.1" + +"@rjaros/snabbdom-virtualize@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@rjaros/snabbdom-virtualize/-/snabbdom-virtualize-1.0.0-beta.5.tgz#17f2586beee5e6c130e1b0ae2f589ff9162a86db" + integrity sha512-2rf1MI7wVSZLOgy+EXtOfYzqcwLtMjak4wzRBQUVJjO4qlCmlSo+bh890eKkILhRGxkp6aTQS9gMjH1fP9g8Nw== + dependencies: + html-parse-stringify "^3" + +"@socket.io/base64-arraybuffer@~1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#568d9beae00b0d835f4f8c53fd55714986492e61" + integrity sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ== + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.10" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" + integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== + dependencies: + "@types/node" "*" + +"@types/component-emitter@^1.2.10": + version "1.2.11" + resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" + integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== + +"@types/connect-history-api-fallback@^1.3.5": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" + integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/cookie@^0.4.0", "@types/cookie@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" + integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== + +"@types/cors@^2.8.12", "@types/cors@^2.8.8": + version "2.8.12" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" + integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== + +"@types/eslint-scope@^3.7.0": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224" + integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.4.1" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.1.tgz#c48251553e8759db9e656de3efc846954ac32304" + integrity sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + +"@types/estree@^0.0.50": + version "0.0.50" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" + integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== + +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": + version "4.17.28" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8" + integrity sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/geojson@*", "@types/geojson@7946.0.8": + version "7946.0.8" + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" + integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA== + +"@types/glob@5 - 7": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/http-proxy@^1.17.8": + version "1.17.8" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.8.tgz#968c66903e7e42b483608030ee85800f22d03f55" + integrity sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA== + dependencies: + "@types/node" "*" + +"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== + +"@types/leaflet@^1.7.7": + version "1.7.9" + resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.7.9.tgz#7993d34f14cfa88c45b3d490daba39a3a1be9a2b" + integrity sha512-H8vPgD49HKzqM41ArHGZM70g/tfhp8W+JcPxfnF+5H/Xvp+xiP+KQOUNWU8U89fqS1Jj3cpRY/+nbnaHFzwnFA== + dependencies: + "@types/geojson" "*" + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + +"@types/minimatch@*": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== + +"@types/node@*", "@types/node@>=10.0.0": + version "17.0.16" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.16.tgz#e3733f46797b9df9e853ca9f719c8a6f7b84cd26" + integrity sha512-ydLaGVfQOQ6hI1xK2A5nVh8bl0OGoIfYMxPWHqqYe9bTkWCfqiVvZoh2I/QF2sNSkZzZyROBoTefIEI+PB6iIA== + +"@types/parse5@^5": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" + integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/retry@^0.12.0": + version "0.12.1" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" + integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== + +"@types/serve-index@^1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" + integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== + dependencies: + "@types/express" "*" + +"@types/serve-static@*": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.33" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" + integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== + dependencies: + "@types/node" "*" + +"@types/ws@^8.2.2": + version "8.2.2" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.2.2.tgz#7c5be4decb19500ae6b3d563043cd407bf366c21" + integrity sha512-NOn5eIcgWLOo6qW8AcuLZ7G8PycXu0xTxxkS6Q18VWFxgPUSOwV0pBj2a/4viNZVu25i7RIB7GttdkAIUUXOOg== + dependencies: + "@types/node" "*" + +"@ungap/promise-all-settled@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== + +"@webassemblyjs/ast@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + +"@webassemblyjs/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== + +"@webassemblyjs/helper-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + +"@webassemblyjs/helper-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== + +"@webassemblyjs/helper-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== + +"@webassemblyjs/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + +"@webassemblyjs/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + +"@webassemblyjs/wasm-edit@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + +"@webassemblyjs/wasm-gen@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wasm-opt@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + +"@webassemblyjs/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webpack-cli/configtest@^1.1.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.1.tgz#9f53b1b7946a6efc2a749095a4f450e2932e8356" + integrity sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg== + +"@webpack-cli/info@^1.4.0": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.1.tgz#2360ea1710cbbb97ff156a3f0f24556e0fc1ebea" + integrity sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA== + dependencies: + envinfo "^7.7.3" + +"@webpack-cli/serve@^1.6.0": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.1.tgz#0de2875ac31b46b6c5bb1ae0a7d7f0ba5678dffe" + integrity sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abab@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + +acorn@^8.4.1: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.0, ajv@^8.8.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.10.0.tgz#e573f719bd3af069017e3b66538ab968d040e54d" + integrity sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +async@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +awesome-bootstrap-checkbox@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/awesome-bootstrap-checkbox/-/awesome-bootstrap-checkbox-1.0.1.tgz#dab10146b6001129ab0a0ec1e54bb77c6c30457a" + integrity sha1-2rEBRrYAESmrCg7B5Uu3fGwwRXo= + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-arraybuffer@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" + integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= + +base64id@2.0.0, base64id@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +body-parser@1.19.1, body-parser@^1.19.0: + version "1.19.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.1.tgz#1499abbaa9274af3ecc9f6f10396c995943e31d4" + integrity sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA== + dependencies: + bytes "3.1.1" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.9.6" + raw-body "2.4.2" + type-is "~1.6.18" + +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + +bootstrap-icons@^1.7.2: + version "1.8.1" + resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.8.1.tgz#773c1625bcbf3e86090ea9da4386c2c6459c5582" + integrity sha512-IXUqislddPJfwq6H+2nTkHyr9epO9h6u1AG0OZCx616w+TgzeoCjfmI3qJMQqt1J586gN2IxzB4M99Ip4sTZ1w== + +bootstrap@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.1.3.tgz#ba081b0c130f810fa70900acbc1c6d3c28fa8f34" + integrity sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserslist@^4.14.5: + version "4.19.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" + integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== + dependencies: + caniuse-lite "^1.0.30001286" + electron-to-chromium "^1.4.17" + escalade "^3.1.1" + node-releases "^2.0.1" + picocolors "^1.0.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +bytes@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a" + integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg== + +call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001286: + version "1.0.30001310" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001310.tgz#da02cd07432c9eece6992689d1b84ca18139eea8" + integrity sha512-cb9xTV8k9HTIUA3GnPUJCk0meUnrHL5gy5QePfDjxHyNBcnzPzrHFv5GqfP7ue5b1ZyzZL0RJboD6hQlPXjhjg== + +chalk@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chart.js@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.7.0.tgz#7a19c93035341df801d613993c2170a1fcf1d882" + integrity sha512-31gVuqqKp3lDIFmzpKIrBeum4OpZsQjSIAqlOpgjosHDJZlULtvwLEZKtEhIAZc7JMPaHlYMys40Qy9Mf+1AAg== + +chokidar@3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chokidar@3.5.3, chokidar@^3.5.1, chokidar@^3.5.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^2.0.10, colorette@^2.0.14: + version "2.0.16" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" + integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== + +colors@1.4.0, colors@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^6.0.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + +commander@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +component-emitter@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +connect@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== + dependencies: + debug "2.6.9" + finalhandler "1.1.2" + parseurl "~1.3.3" + utils-merge "1.0.1" + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + +cookie@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cors@~2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-loader@^6.5.1: + version "6.6.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.6.0.tgz#c792ad5510bd1712618b49381bd0310574fafbd3" + integrity sha512-FK7H2lisOixPT406s5gZM1S3l8GrfhEBT3ZiL2UX1Ng1XWs0y2GPllz/OTyvbaHe12VgQrIXIzuEGVlbUhodqg== + dependencies: + icss-utils "^5.1.0" + postcss "^8.4.5" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.3.5" + +css-selector-parser@^1.3: + version "1.4.1" + resolved "https://registry.yarnpkg.com/css-selector-parser/-/css-selector-parser-1.4.1.tgz#03f9cb8a81c3e5ab2c51684557d5aaf6d2569759" + integrity sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +custom-event@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" + integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= + +date-format@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.3.tgz#f63de5dc08dc02efd8ef32bf2a6918e486f35873" + integrity sha512-7P3FyqDcfeznLZp2b+OMitV9Sz2lUnsT87WaTat9nVwqsBkTzPG3lPLNwW3en6F4pHUiWzr6vb8CLhjdK9bcxQ== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + +debug@4.3.3, debug@^4.1.0, debug@^4.1.1, debug@^4.3.3, debug@~4.3.1, debug@~4.3.2: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +debug@^3.1.1: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +deep-equal@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +default-gateway@^6.0.0, default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +del@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/del/-/del-6.0.0.tgz#0b40d0332cea743f1614f818be4feb717714c952" + integrity sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ== + dependencies: + globby "^11.0.1" + graceful-fs "^4.2.4" + is-glob "^4.0.1" + is-path-cwd "^2.2.0" + is-path-inside "^3.0.2" + p-map "^4.0.0" + rimraf "^3.0.2" + slash "^3.0.0" + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +di@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" + integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw= + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + +dns-packet@^1.3.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" + integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + +dom-serialize@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" + integrity sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs= + dependencies: + custom-event "~1.0.0" + ent "~2.2.0" + extend "^3.0.0" + void-elements "^2.0.0" + +dukat@0.5.8-rc.3: + version "0.5.8-rc.3" + resolved "https://registry.yarnpkg.com/dukat/-/dukat-0.5.8-rc.3.tgz#4a2b848b9d2978cb610af8d5cf24ff5e5a408743" + integrity sha512-wzl9A5alTT1Mag4y7bUVjPF4L/wkts7AiiWxe6/6tL5gSDowexUzlJX/pYVTbnHcOo48/bok3Ao1gzU4/cFFjw== + dependencies: + google-protobuf "3.12.2" + typescript "3.9.5" + +dukat@0.5.8-rc.4: + version "0.5.8-rc.4" + resolved "https://registry.yarnpkg.com/dukat/-/dukat-0.5.8-rc.4.tgz#90384dcb50b14c26f0e99dae92b2dea44f5fce21" + integrity sha512-ZnMt6DGBjlVgK2uQamXfd7uP/AxH7RqI0BL9GLrrJb2gKdDxvJChWy+M9AQEaL+7/6TmxzJxFOsRiInY9oGWTA== + dependencies: + google-protobuf "3.12.2" + typescript "3.9.5" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +electron-to-chromium@^1.4.17: + version "1.4.67" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.67.tgz#699e59d6959d05f87865e12b3055bbcf492bbbee" + integrity sha512-A6a2jEPLueEDfb7kvh7/E94RKKnIb01qL+4I7RFxtajmo+G9F5Ei7HgY5PRbQ4RDrh6DGDW66P0hD5XI2nRAcg== + +element-resize-event@^3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/element-resize-event/-/element-resize-event-3.0.6.tgz#3a18efd4879ad615e979fd8bbf173b014987eb9a" + integrity sha512-sSeXY9rNDp86bJODW68pxLcy3A5FrPZfIgOrJHzqgYzX513Zq6/ytdBigp7KeJEpZZopBBSiO1cVuiRkZpNxLw== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +encoding@^0.1.12: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + +engine.io-parser@~4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-4.0.3.tgz#83d3a17acfd4226f19e721bb22a1ee8f7662d2f6" + integrity sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA== + dependencies: + base64-arraybuffer "0.1.4" + +engine.io-parser@~5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.3.tgz#ca1f0d7b11e290b4bfda251803baea765ed89c09" + integrity sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg== + dependencies: + "@socket.io/base64-arraybuffer" "~1.0.2" + +engine.io@~4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-4.1.2.tgz#f96ceb56d4b39cc7ca5bd29a20e9c99c1ad1a765" + integrity sha512-t5z6zjXuVLhXDMiFJPYsPOWEER8B0tIsD3ETgw19S1yg9zryvUfY3Vhtk3Gf4sihw/bQGIqQ//gjvVlu+Ca0bQ== + dependencies: + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~4.0.0" + ws "~7.4.2" + +engine.io@~6.1.0: + version "6.1.2" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.1.2.tgz#e7b9d546d90c62246ffcba4d88594be980d3855a" + integrity sha512-v/7eGHxPvO2AWsksyx2PUsQvBafuvqs0jJJQ0FdmJG1b9qIvgSbqDRGwNhfk2XHaTTbTXiC4quRE8Q9nRjsrQQ== + dependencies: + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~5.0.0" + ws "~8.2.3" + +enhanced-resolve@^5.8.3: + version "5.9.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.9.0.tgz#49ac24953ac8452ed8fed2ef1340fc8e043667ee" + integrity sha512-weDYmzbBygL7HzGGS26M3hGQx68vehdEg6VUmqSOaFzXExFqlnKuSvsEJCVGQHScS8CQMbrAqftT+AzzHNt/YA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +ent@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0= + +envinfo@^7.7.3: + version "7.8.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" + integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +express@^4.17.1: + version "4.17.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.2.tgz#c18369f265297319beed4e5558753cc8c1364cb3" + integrity sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.4.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.9.6" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.17.2" + serve-static "1.14.2" + setprototypeof "1.2.0" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fastest-levenshtein@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" + integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== + +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +fecha@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce" + integrity sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.1.2, finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatted@^3.2.4: + version "3.2.5" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" + integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== + +follow-redirects@^1.0.0: + version "1.14.8" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc" + integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA== + +format-util@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" + integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +fs-extra@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" + integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-extra@^8.0.1: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-monkey@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" + integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +geojson@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/geojson/-/geojson-0.5.0.tgz#3cd6c96399be65b56ee55596116fe9191ce701c0" + integrity sha1-PNbJY5m+ZbVu5VWWEW/pGRznAcA= + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +gettext-extract@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/gettext-extract/-/gettext-extract-2.0.1.tgz#4ade7e3d7c1c247d95a81f28059ca1923c355886" + integrity sha512-k51R90txkCZeXQEDjK0e7gNHfBHJVCu8IQ3AbSVZoOL5nR3yl+C+7qpzp6hoZwOtiniaY+CKeLyvNulsEUM6MA== + dependencies: + chalk "^2.3.0" + find-up "^4.1.0" + fs-extra "^8.0.1" + gettext-extractor "^3.1.0" + minimist "^1.2.0" + +gettext-extractor@^3.1.0: + version "3.5.3" + resolved "https://registry.yarnpkg.com/gettext-extractor/-/gettext-extractor-3.5.3.tgz#6ed46931c154a7485a80fa8b91b835ff7b8d0411" + integrity sha512-9EgJ+hmbtAbATdMIvCj4WnrkeDWH6fv1z+IJJ1XCxdcUMGx6JQdVVFTdzJkSyIHh4td53ngoB5EQbavbKJU9Og== + dependencies: + "@types/glob" "5 - 7" + "@types/parse5" "^5" + css-selector-parser "^1.3" + glob "5 - 7" + parse5 "5 - 6" + pofile "1.0.x" + typescript "2 - 4" + +gettext-parser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-2.0.0.tgz#c28bb31e61f76f14665dfafbb5c0518cdc1270ed" + integrity sha512-FDs/7XjNw58ToQwJFO7avZZbPecSYgw8PBYhd0An+4JtZSrSzKhEvTsVV2uqdO7VziWTOGSgLGD5YRPdsCjF7Q== + dependencies: + encoding "^0.1.12" + safe-buffer "^5.1.2" + +gettext-parser@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-1.4.0.tgz#f8baf34a292f03d5e42f02df099d301f167a7ace" + integrity sha512-sedZYLHlHeBop/gZ1jdg59hlUEcpcZJofLq2JFwJT1zTqAU3l2wFv6IsuwFHGqbiT9DWzMUW4/em2+hspnmMMA== + dependencies: + encoding "^0.1.12" + safe-buffer "^5.1.1" + +gettext-to-messageformat@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/gettext-to-messageformat/-/gettext-to-messageformat-0.3.1.tgz#c303ff9e31a5c781b14629b13bddb27b9ffca1f8" + integrity sha512-UyqIL3Ul4NryU95Wome/qtlcuVIqgEWVIFw0zi7Lv14ACLXfaVDCbrjZ7o+3BZ7u+4NS1mP/2O1eXZoHCoas8g== + dependencies: + gettext-parser "^1.4.0" + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +"glob@5 - 7", glob@7.2.0, glob@^7.1.3, glob@^7.1.7: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@7.1.7: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globby@^11.0.1: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +google-protobuf@3.12.2: + version "3.12.2" + resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.12.2.tgz#50ce9f9b6281235724eb243d6a83e969a2176e53" + integrity sha512-4CZhpuRr1d6HjlyrxoXoocoGFnRYgKULgMtikMddA9ztRyYR59Aondv2FioyxWVamRo0rF2XpYawkTCBEQOSkA== + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.9" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" + integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488" + integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ== + +html-parse-stringify@^3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2" + integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg== + dependencies: + void-elements "3.1.0" + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + +http-errors@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.5.tgz#d7c30d5d3c90d865b4a2e870181f9d6f22ac7ac5" + integrity sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA== + +http-proxy-middleware@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.3.tgz#5df04f69a89f530c2284cd71eeaa51ba52243289" + integrity sha512-1bloEwnrHMnCoO/Gcwbz7eSVvW50KPES01PecpagI+YLNLci4AcuKJrujW4Mc3sBLpFxMSlsLNHS5Nl/lvrTPA== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imports-loader@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-3.1.1.tgz#3e464d9aad1e303b1b34b658eb8f8aae22f96435" + integrity sha512-3QMyGU4RTgxLf0puWkUfT5+7zJvexvB00PI5skDIcxG8O20gZCbQsaRpNBv+cIO6yy/lmlOBwaxc3uH1CV+sww== + dependencies: + source-map "^0.6.1" + strip-comments "^2.0.1" + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +internal-ip@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-6.2.0.tgz#d5541e79716e406b74ac6b07b856ef18dc1621c1" + integrity sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg== + dependencies: + default-gateway "^6.0.0" + ipaddr.js "^1.9.1" + is-ip "^3.1.0" + p-event "^4.2.0" + +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + +ip-regex@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" + integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== + +ip@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.9.1, ipaddr.js@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-core-module@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" + integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-ip@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8" + integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q== + dependencies: + ip-regex "^4.0.0" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-cwd@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-regex@^1.0.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isbinaryfile@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.8.tgz#5d34b94865bd4946633ecc78a026fc76c5b11fcf" + integrity sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jquery@^3.5.1: + version "3.6.0" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470" + integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw== + +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +karma-chrome-launcher@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz#805a586799a4d05f4e54f72a204979f3f3066738" + integrity sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg== + dependencies: + which "^1.2.1" + +karma-mocha@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-2.0.1.tgz#4b0254a18dfee71bdbe6188d9a6861bf86b0cd7d" + integrity sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ== + dependencies: + minimist "^1.2.3" + +karma-sourcemap-loader@0.3.8: + version "0.3.8" + resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.8.tgz#d4bae72fb7a8397328a62b75013d2df937bdcf9c" + integrity sha512-zorxyAakYZuBcHRJE+vbrK2o2JXLFWK8VVjiT/6P+ltLBUGUvqTEkUiQ119MGdOrK7mrmxXHZF1/pfT6GgIZ6g== + dependencies: + graceful-fs "^4.1.2" + +karma-webpack@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.0.tgz#2a2c7b80163fe7ffd1010f83f5507f95ef39f840" + integrity sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA== + dependencies: + glob "^7.1.3" + minimatch "^3.0.4" + webpack-merge "^4.1.5" + +karma@6.3.12: + version "6.3.12" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.12.tgz#fe6347f027385fc16da1a9bb87d766e2d25981c6" + integrity sha512-qwIG+oB2YmHx4hjvYSRMNzL3YWAJ9baHaLAxiP7biFNkfpwYTUTtPck0joFpucalNLzMr+7z/FX1uY/kl8DV9A== + dependencies: + body-parser "^1.19.0" + braces "^3.0.2" + chokidar "^3.5.1" + colors "1.4.0" + connect "^3.7.0" + di "^0.0.1" + dom-serialize "^2.2.1" + glob "^7.1.7" + graceful-fs "^4.2.6" + http-proxy "^1.18.1" + isbinaryfile "^4.0.8" + lodash "^4.17.21" + log4js "^6.3.0" + mime "^2.5.2" + minimatch "^3.0.4" + qjobs "^1.2.0" + range-parser "^1.2.1" + rimraf "^3.0.2" + socket.io "^4.2.0" + source-map "^0.6.1" + tmp "^0.2.1" + ua-parser-js "^0.7.30" + yargs "^16.1.1" + +karma@6.3.4: + version "6.3.4" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.4.tgz#359899d3aab3d6b918ea0f57046fd2a6b68565e6" + integrity sha512-hbhRogUYIulfkBTZT7xoPrCYhRBnBoqbbL4fszWD0ReFGUxU+LYBr3dwKdAluaDQ/ynT9/7C+Lf7pPNW4gSx4Q== + dependencies: + body-parser "^1.19.0" + braces "^3.0.2" + chokidar "^3.5.1" + colors "^1.4.0" + connect "^3.7.0" + di "^0.0.1" + dom-serialize "^2.2.1" + glob "^7.1.7" + graceful-fs "^4.2.6" + http-proxy "^1.18.1" + isbinaryfile "^4.0.8" + lodash "^4.17.21" + log4js "^6.3.0" + mime "^2.5.2" + minimatch "^3.0.4" + qjobs "^1.2.0" + range-parser "^1.2.1" + rimraf "^3.0.2" + socket.io "^3.1.0" + source-map "^0.6.1" + tmp "^0.2.1" + ua-parser-js "^0.7.28" + yargs "^16.1.1" + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +kvision-assets@^5.0.8: + version "5.0.8" + resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-5.0.8.tgz#f2220135a94b1330cb2ac8f1804b53f40a9bd711" + integrity sha512-umq47D8z2W7cTYR/6RtJ+048mlsi5X515tcM/PFgDcbaI82Pd9EHv2m9520SxmBH6AD04GTweWNyUcKlPx9oZQ== + +leaflet@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.7.1.tgz#10d684916edfe1bf41d688a3b97127c0322a2a19" + integrity sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw== + +loader-runner@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" + integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log4js@^6.3.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.4.1.tgz#9d3a8bf2c31c1e213fe3fc398a6053f7a2bc53e8" + integrity sha512-iUiYnXqAmNKiIZ1XSAitQ4TmNs8CdZYTAWINARF3LjnsLN8tY5m0vRwd6uuWj/yNY0YHxeZodnbmxKFUOM2rMg== + dependencies: + date-format "^4.0.3" + debug "^4.3.3" + flatted "^3.2.4" + rfdc "^1.3.0" + streamroller "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +memfs@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.1.tgz#b78092f466a0dce054d63d39275b24c71d3f1305" + integrity sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw== + dependencies: + fs-monkey "1.0.3" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +mime-db@1.51.0, "mime-db@>= 1.43.0 < 2": + version "1.51.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" + integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== + +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.34" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" + integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== + dependencies: + mime-db "1.51.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.5.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^3.0.4: + version "3.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" + integrity sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mkdirp@^0.5.5: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mocha@9.1.2: + version "9.1.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.2.tgz#93f53175b0f0dc4014bd2d612218fccfcf3534d3" + integrity sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.2" + debug "4.3.2" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.1.7" + growl "1.10.5" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "3.0.4" + ms "2.1.3" + nanoid "3.1.25" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + workerpool "6.1.5" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +mocha@9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.0.tgz#2bfba73d46e392901f877ab9a47b7c9c5d0275cc" + integrity sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.3" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + growl "1.10.5" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "3.0.4" + ms "2.1.3" + nanoid "3.2.0" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + workerpool "6.2.0" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + +nanoid@3.1.25: + version "3.1.25" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" + integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== + +nanoid@3.2.0, nanoid@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" + integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +node-forge@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" + integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== + +node-forge@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.2.1.tgz#82794919071ef2eb5c509293325cec8afd0fd53c" + integrity sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w== + +node-releases@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01" + integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +object-assign@^4: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@^8.0.9: + version "8.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" + integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +p-event@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" + integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== + dependencies: + p-timeout "^3.1.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-retry@^4.5.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c" + integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA== + dependencies: + "@types/retry" "^0.12.0" + retry "^0.13.1" + +p-timeout@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +"parse5@5 - 6": + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pofile@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.0.11.tgz#35aff58c17491d127a07336d5522ebc9df57c954" + integrity sha512-Vy9eH1dRD9wHjYt/QqXcTz+RnX/zg53xK+KljFSX30PvdDMb2z+c6uDUeblUGqqJgz3QFsdlA0IJvHziPmWtQg== + +portfinder@^1.0.28: + version "1.0.28" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" + integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.5" + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.9" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f" + integrity sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.4.5: + version "8.4.6" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.6.tgz#c5ff3c3c457a23864f32cb45ac9b741498a09ae1" + integrity sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA== + dependencies: + nanoid "^3.2.0" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qjobs@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" + integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== + +qs@6.9.6: + version "6.9.6" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" + integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32" + integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ== + dependencies: + bytes "3.1.1" + http-errors "1.8.1" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readable-stream@^2.0.1: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" + integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== + dependencies: + resolve "^1.9.0" + +redux-thunk@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.1.tgz#0dd8042cf47868f4b29699941de03c9301a75714" + integrity sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q== + +redux@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.2.tgz#140f35426d99bb4729af760afcf79eaaac407104" + integrity sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw== + dependencies: + "@babel/runtime" "^7.9.2" + +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + +regexp.prototype.flags@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307" + integrity sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve@^1.9.0: + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== + dependencies: + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +schema-utils@^3.1.0, schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" + integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.8.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.0.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + +selfsigned@^1.10.11: + version "1.10.14" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.14.tgz#ee51d84d9dcecc61e07e4aba34f229ab525c1574" + integrity sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA== + dependencies: + node-forge "^0.10.0" + +selfsigned@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.0.tgz#e927cd5377cbb0a1075302cff8df1042cc2bce5b" + integrity sha512-cUdFiCbKoa1mZ6osuJs2uDHrs0k0oprsKveFiiaBKCNq3SYyb5gs2HxhQyDNLCmL51ZZThqi4YNDpCK6GOP1iQ== + dependencies: + node-forge "^1.2.0" + +semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +send@0.17.2: + version "0.17.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" + integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "1.8.1" + mime "1.6.0" + ms "2.1.3" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serialize-javascript@6.0.0, serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.14.2: + version "1.14.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" + integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.2" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +snabbdom@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.3.1.tgz#a2fb9a1c85cc19d6dc11c4c5e4c78cbbbaafff1f" + integrity sha512-FR9u20dCkktPd+qbedqwYNjMXzYhizhqlKTQzYZimLNeCJY0/5qgs0DtLVSmzIEL1bN3Dyb9sQpiHGCxUjyLnQ== + +socket.io-adapter@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz#edc5dc36602f2985918d631c1399215e97a1b527" + integrity sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg== + +socket.io-adapter@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz#4d6111e4d42e9f7646e365b4f578269821f13486" + integrity sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ== + +socket.io-parser@~4.0.3, socket.io-parser@~4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0" + integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g== + dependencies: + "@types/component-emitter" "^1.2.10" + component-emitter "~1.3.0" + debug "~4.3.1" + +socket.io@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-3.1.2.tgz#06e27caa1c4fc9617547acfbb5da9bc1747da39a" + integrity sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw== + dependencies: + "@types/cookie" "^0.4.0" + "@types/cors" "^2.8.8" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.1" + engine.io "~4.1.0" + socket.io-adapter "~2.1.0" + socket.io-parser "~4.0.3" + +socket.io@^4.2.0: + version "4.4.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.4.1.tgz#cd6de29e277a161d176832bb24f64ee045c56ab8" + integrity sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg== + dependencies: + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.2" + engine.io "~6.1.0" + socket.io-adapter "~2.3.3" + socket.io-parser "~4.0.4" + +sockjs@^0.3.21: + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + +source-map-js@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" + integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== + +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-loader@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.0.tgz#f2a04ee2808ad01c774dea6b7d2639839f3b3049" + integrity sha512-GKGWqWvYr04M7tn8dryIWvb0s8YM41z82iQv01yBtIylgxax0CwvSy6gc2Y02iuXwEfGWRlMicH0nvms9UZphw== + dependencies: + abab "^2.0.5" + iconv-lite "^0.6.2" + source-map-js "^0.6.2" + +source-map-support@0.5.20: + version "0.5.20" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" + integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +split.js@^1.6.5: + version "1.6.5" + resolved "https://registry.yarnpkg.com/split.js/-/split.js-1.6.5.tgz#f7f61da1044c9984cb42947df4de4fadb5a3f300" + integrity sha512-mPTnGCiS/RiuTNsVhCm9De9cCAUsrNFFviRbADdKiiV+Kk8HKp/0fWu7Kr8pi3/yBmsqLFHuXGT9UUZ+CNLwFw== + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +streamroller@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.0.2.tgz#30418d0eee3d6c93ec897f892ed098e3a81e68b7" + integrity sha512-ur6y5S5dopOaRXBuRIZ1u6GC5bcEXHRZKgfBjfCglMhmIf+roVCECjvkEYzNQOXIN2/JPnkMPW/8B3CZoKaEPA== + dependencies: + date-format "^4.0.3" + debug "^4.1.1" + fs-extra "^10.0.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" + integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== + dependencies: + ansi-regex "^6.0.1" + +strip-comments@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" + integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +style-loader@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" + integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== + +supports-color@8.1.1, supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +terser-webpack-plugin@^5.1.3: + version "5.3.1" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz#0320dcc270ad5372c1e8993fabbd927929773e54" + integrity sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g== + dependencies: + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + source-map "^0.6.1" + terser "^5.7.2" + +terser@^5.7.2: + version "5.10.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc" + integrity sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA== + dependencies: + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.20" + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +"typescript@2 - 4": + version "4.5.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3" + integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== + +typescript@3.9.5: + version "3.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" + integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== + +ua-parser-js@^0.7.28, ua-parser-js@^0.7.30: + version "0.7.31" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" + integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +v8-compile-cache@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +void-elements@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" + integrity sha1-YU9/v42AHwu18GYfWy9XhXUOTwk= + +void-elements@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= + +watchpack@^2.2.0, watchpack@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25" + integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webpack-cli@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.0.tgz#dc43e6e0f80dd52e89cbf73d5294bcd7ad6eb343" + integrity sha512-n/jZZBMzVEl4PYIBs+auy2WI0WTQ74EnJDiyD98O2JZY6IVIHJNitkYp/uTXOviIOMfgzrNvC9foKv/8o8KSZw== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.1.0" + "@webpack-cli/info" "^1.4.0" + "@webpack-cli/serve" "^1.6.0" + colorette "^2.0.14" + commander "^7.0.0" + execa "^5.0.0" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + v8-compile-cache "^2.2.0" + webpack-merge "^5.7.3" + +webpack-cli@4.9.1: + version "4.9.1" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3" + integrity sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.1.0" + "@webpack-cli/info" "^1.4.0" + "@webpack-cli/serve" "^1.6.0" + colorette "^2.0.14" + commander "^7.0.0" + execa "^5.0.0" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + webpack-merge "^5.7.3" + +webpack-dev-middleware@^5.2.1, webpack-dev-middleware@^5.3.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz#aa079a8dedd7e58bfeab358a9af7dab304cee57f" + integrity sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg== + dependencies: + colorette "^2.0.10" + memfs "^3.4.1" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.3.1.tgz#759d3337f0fbea297fbd1e433ab04ccfc000076b" + integrity sha512-qNXQCVYo1kYhH9pgLtm8LRNkXX3XzTfHSj/zqzaqYzGPca+Qjr+81wj1jgPMCHhIhso9WEQ+kX9z23iG9PzQ7w== + dependencies: + ansi-html-community "^0.0.8" + bonjour "^3.5.0" + chokidar "^3.5.1" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + del "^6.0.0" + express "^4.17.1" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.0" + internal-ip "^6.2.0" + ipaddr.js "^2.0.1" + open "^8.0.9" + p-retry "^4.5.0" + portfinder "^1.0.28" + schema-utils "^3.1.0" + selfsigned "^1.10.11" + serve-index "^1.9.1" + sockjs "^0.3.21" + spdy "^4.0.2" + strip-ansi "^7.0.0" + url "^0.11.0" + webpack-dev-middleware "^5.2.1" + ws "^8.1.0" + +webpack-dev-server@4.7.3: + version "4.7.3" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.7.3.tgz#4e995b141ff51fa499906eebc7906f6925d0beaa" + integrity sha512-mlxq2AsIw2ag016nixkzUkdyOE8ST2GTy34uKSABp1c4nhjZvH90D5ZRR+UOLSsG4Z3TFahAi72a3ymRtfRm+Q== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/serve-index" "^1.9.1" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.2.2" + ansi-html-community "^0.0.8" + bonjour "^3.5.0" + chokidar "^3.5.2" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + default-gateway "^6.0.3" + del "^6.0.0" + express "^4.17.1" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.0" + ipaddr.js "^2.0.1" + open "^8.0.9" + p-retry "^4.5.0" + portfinder "^1.0.28" + schema-utils "^4.0.0" + selfsigned "^2.0.0" + serve-index "^1.9.1" + sockjs "^0.3.21" + spdy "^4.0.2" + strip-ansi "^7.0.0" + webpack-dev-middleware "^5.3.0" + ws "^8.1.0" + +webpack-merge@^4.1.5: + version "4.2.2" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" + integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== + dependencies: + lodash "^4.17.15" + +webpack-merge@^5.7.3: + version "5.8.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" + integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + +webpack-sources@^3.2.0, webpack-sources@^3.2.2: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@5.57.1: + version "5.57.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.57.1.tgz#ead5ace2c17ecef2ae8126f143bfeaa7f55eab44" + integrity sha512-kHszukYjTPVfCOEyrUthA3jqJwduY/P3eO8I0gMNOZGIQWKAwZftxmp5hq6paophvwo9NoUrcZOecs9ulOyyTg== + dependencies: + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.50" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.4.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.8.3" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.4" + json-parse-better-errors "^1.0.2" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.2.0" + webpack-sources "^3.2.0" + +webpack@5.66.0: + version "5.66.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.66.0.tgz#789bf36287f407fc92b3e2d6f978ddff1bfc2dbb" + integrity sha512-NJNtGT7IKpGzdW7Iwpn/09OXz9inIkeIQ/ibY6B+MdV1x6+uReqz/5z1L89ezWnpPDWpXF0TY5PCYKQdWVn8Vg== + dependencies: + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.50" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.4.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.8.3" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-better-errors "^1.0.2" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.3.1" + webpack-sources "^3.2.2" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +which@2.0.2, which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +which@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wildcard@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" + integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== + +workerpool@6.1.5: + version "6.1.5" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" + integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== + +workerpool@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" + integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@^8.1.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" + integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== + +ws@~7.4.2: + version "7.4.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== + +ws@~8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0, yargs@^16.1.1: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/build.gradle.kts b/build.gradle.kts index 3cbf0c0..1007434 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -27,7 +27,7 @@ idea { } tasks.wrapper { - gradleVersion = "7.3.3" + gradleVersion = "7.4" distributionType = Wrapper.DistributionType.ALL } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 739d432..9e7f59f 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -7,36 +7,54 @@ plugins { `project-report` } + +object Versions { + const val jvmTarget = "11" + const val kotlinTarget = "1.6" + + const val gradleNodePlugin = "3.2.0" + const val gradleDockerComposePlugin = "0.15.0" + + const val kotlin = "1.6.10" + const val kotlinXSerialization = "1.3.2" + const val kvision = "5.8.1" + const val semver = "1.1.2" + + const val kotest = "5.1.0" +} + + dependencies { - val kotlinVersion = "1.6.10" - implementation(enforcedPlatform("org.jetbrains.kotlin:kotlin-bom:$kotlinVersion")) + implementation(enforcedPlatform("org.jetbrains.kotlin:kotlin-bom:${Versions.kotlin}")) implementation("org.jetbrains.kotlin:kotlin-serialization") implementation("org.jetbrains.kotlin:kotlin-reflect") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}") - val kotlinXSerializationVersion = "1.3.2" - implementation(enforcedPlatform("org.jetbrains.kotlinx:kotlinx-serialization-bom:$kotlinXSerializationVersion")) + implementation(enforcedPlatform("org.jetbrains.kotlinx:kotlinx-serialization-bom:${Versions.kotlinXSerialization}")) implementation("org.jetbrains.kotlinx:kotlinx-serialization-core") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json") // implementation("com.charleskorn.kaml:kaml:0.37.0") - implementation("com.github.node-gradle:gradle-node-plugin:3.1.1") + implementation("com.github.node-gradle:gradle-node-plugin:${Versions.gradleNodePlugin}") - implementation("net.swiftzer.semver:semver:1.1.2") + implementation("io.kotest:kotest-framework-multiplatform-plugin-gradle:${Versions.kotest}") + + implementation("io.kvision:io.kvision.gradle.plugin:${Versions.kvision}") + + implementation("net.swiftzer.semver:semver:${Versions.semver}") // https://github.com/avast/gradle-docker-compose-plugin - implementation("com.avast.gradle:gradle-docker-compose-plugin:0.14.12") + implementation("com.avast.gradle:gradle-docker-compose-plugin:${Versions.gradleDockerComposePlugin}") } -val projectJvmTarget = "11" tasks.withType().configureEach { kotlinOptions { - jvmTarget = projectJvmTarget - apiVersion = "1.6" - languageVersion = "1.6" + jvmTarget = Versions.jvmTarget + apiVersion = Versions.kotlinTarget + languageVersion = Versions.kotlinTarget } kotlinOptions.freeCompilerArgs += listOf( @@ -50,11 +68,11 @@ tasks.withType().configureEach { kotlin { jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(projectJvmTarget)) + (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(Versions.jvmTarget)) } kotlinDslPluginOptions { - jvmTarget.set(projectJvmTarget) + jvmTarget.set(Versions.jvmTarget) } } diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt new file mode 100644 index 0000000..bbd4ec7 --- /dev/null +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -0,0 +1,13 @@ +object Versions { + + const val kotlinLang = "1.6" + const val jvmTarget = "11" + + const val node = "14.19.0" + + const val kotlinWrappers = "0.0.1-pre.294-kotlin-1.6.10" + const val junit = "5.8.2" + const val kotest = "5.1.0" + const val mockk = "1.12.1" + +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt index 73c7011..6a779a7 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt @@ -1,8 +1,25 @@ package dev.adamko.kafkatorio import kotlinx.serialization.json.Json +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension val jsonMapper = Json { prettyPrint = true prettyPrintIndent = " " } + + +/** + * `kotlin-js` adds a directory in the root-dir for the Yarn lock. + * That's a bit annoying. It's a little neater if it's in the + * gradle dir, next to the version-catalog. + */ +fun Project.relocateKotlinJsStore() { + afterEvaluate { + rootProject.extensions.configure { + lockFileDirectory = rootProject.rootDir.resolve("gradle/kotlin-js-store") + } + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts index 4c11e6d..44f2edf 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts @@ -1,8 +1,9 @@ package dev.adamko.kafkatorio.lang +import Versions +import dev.adamko.kafkatorio.relocateKotlinJsStore import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask -import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension plugins { @@ -11,10 +12,9 @@ plugins { } dependencies { - val kotlinWrappersVersion = "0.0.1-pre.276-kotlin-1.6.0" implementation( project.dependencies.platform( - "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" + "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${Versions.kotlinWrappers}" ) ) } @@ -42,9 +42,4 @@ val nodeModulesDir: Directory by extra { file } -rootProject.extensions.configure { - // kotlin-js adds a directory in the root-dir for the Yarn lock. - // That's a bit annoying. It's a little neater if it's in the - // gradle dir, next to the version-catalog. - lockFileDirectory = rootProject.rootDir.resolve("gradle/kotlin-js-store") -} +relocateKotlinJsStore() diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index 9e79a0e..7938683 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -9,7 +9,7 @@ plugins { kotlin { jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(11)) + (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(Versions.jvmTarget)) } } @@ -17,30 +17,28 @@ dependencies { implementation(platform("org.jetbrains.kotlin:kotlin-bom")) - val junitVersion = "5.8.2" - testImplementation(platform("org.junit:junit-bom:$junitVersion")) + testImplementation(platform("org.junit:junit-bom:${Versions.junit}")) testImplementation("org.junit.jupiter:junit-jupiter") testRuntimeOnly("org.junit.platform:junit-platform-launcher") { because("Only needed to run tests in a version of IntelliJ IDEA that bundles older versions") } - val kotestVersion = "5.0.3" - testImplementation(platform("io.kotest:kotest-bom:$kotestVersion")) + testImplementation(platform("io.kotest:kotest-bom:${Versions.kotest}")) testImplementation("io.kotest:kotest-runner-junit5") testImplementation("io.kotest:kotest-assertions-core") testImplementation("io.kotest:kotest-property") testImplementation("io.kotest:kotest-assertions-json") - testImplementation("io.mockk:mockk:1.12.1") + testImplementation("io.mockk:mockk:${Versions.mockk}") } tasks.withType().configureEach { kotlinOptions { - jvmTarget = "11" - apiVersion = "1.6" - languageVersion = "1.6" + jvmTarget = Versions.jvmTarget + apiVersion = Versions.kotlinLang + languageVersion = Versions.kotlinLang } kotlinOptions.freeCompilerArgs += listOf( diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts index a20acb2..9734ff0 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts @@ -1,9 +1,6 @@ package dev.adamko.kafkatorio.lang -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.kotlin -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension -import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension +import dev.adamko.kafkatorio.relocateKotlinJsStore plugins { @@ -13,21 +10,4 @@ plugins { } -afterEvaluate { - - rootProject.extensions.configure { - val projectNodeInstallDir = file("$rootDir/.gradle").resolve("nodejs") - if (installationDir != projectNodeInstallDir) { - installationDir = projectNodeInstallDir - } - } - - rootProject.extensions.configure { - // kotlin-js adds a directory in the root-dir for the Yarn lock. - // That's a bit annoying. It's a little neater if it's in the - // gradle dir, next to the version-catalog. - lockFileDirectory = rootProject.rootDir.resolve("gradle/kotlin-js-store") - } - - -} +relocateKotlinJsStore() diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts index 642bf90..2360e37 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.lang +import Versions import com.github.gradle.node.NodePlugin import com.github.gradle.node.npm.task.NpmInstallTask import dev.adamko.kafkatorio.gradle.areJsonPropertiesUpToDate @@ -20,7 +21,7 @@ plugins { node { download.set(true) - version.set("14.18.0") + version.set(Versions.node) distBaseUrl.set(null as String?) // set by dependencyResolutionManagement } @@ -56,6 +57,7 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) { } tasks.assemble { dependsOn(updatePackageJson) } + tasks.withType { dependsOn(updatePackageJson) } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 669386b..b1159fc 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index 74f6aaa..098fbe4 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -4,7 +4,7 @@ import dev.adamko.kafkatorio.gradle.typescriptAttributes plugins { kotlin("multiplatform") kotlin("plugin.serialization") - id("io.kotest.multiplatform") version "5.0.2" + id("io.kotest.multiplatform") distribution } @@ -112,7 +112,7 @@ val schemaTs by distributions.registering { } } -val typescriptModelGenerated : Configuration by configurations.creating { +val typescriptModelGenerated: Configuration by configurations.creating { asProvider() typescriptAttributes(objects) diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 23e9470..2e90dfe 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -18,7 +18,7 @@ val projectId: String by project.extra @Suppress("UnstableApiUsage") // platform + version-catalog is incubating dependencies { - implementation("org.apache.kafka:kafka-streams:3.1.0") + implementation(libs.kafka.streams) implementation(projects.modules.eventsSchema) diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 5c9cbf9..76426f4 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -4,7 +4,7 @@ import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig plugins { id("dev.adamko.kafkatorio.lang.kotlin-js") kotlin("plugin.serialization") - id("io.kvision") version "5.8.1" + id("io.kvision") } kotlin { From 8040149e25910a99ce29544fefd2921708aa42f1 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 9 Feb 2022 13:16:57 +0100 Subject: [PATCH 188/629] version bumnp, more gradle tidying, and fix the kotlin-js-store yarn lock file location --- .kotlin-js-store/yarn.lock | 3668 ----------------- build.gradle.kts | 2 +- buildSrc/src/main/kotlin/Versions.kt | 13 - .../kotlin/dev/adamko/kafkatorio/common.kt | 26 +- .../adamko/kafkatorio/gradle/extensions.kt | 3 + .../kafkatorio/lang/kotlin-js.gradle.kts | 2 +- .../kafkatorio/lang/kotlin-jvm.gradle.kts | 1 + .../lang/kotlin-multiplatform.gradle.kts | 2 +- .../adamko/kafkatorio/lang/node.gradle.kts | 2 +- gradle/kotlin-js-store/yarn.lock | 635 ++- .../src/main/typescript/package-lock.json | 2 +- .../src/main/typescript/package.json | 2 +- modules/events-schema/build.gradle.kts | 17 +- modules/events-server/build.gradle.kts | 2 +- modules/infra-factorio-server/src/.env | 2 +- modules/infra-kafka-cluster/src/.env | 2 +- modules/infra-kafka-connect/build.gradle.kts | 2 - modules/infra-kafka-pipe/src/.env | 2 +- 18 files changed, 558 insertions(+), 3827 deletions(-) delete mode 100644 .kotlin-js-store/yarn.lock delete mode 100644 buildSrc/src/main/kotlin/Versions.kt diff --git a/.kotlin-js-store/yarn.lock b/.kotlin-js-store/yarn.lock deleted file mode 100644 index d6ee670..0000000 --- a/.kotlin-js-store/yarn.lock +++ /dev/null @@ -1,3668 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/runtime@^7.9.2": - version "7.17.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941" - integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw== - dependencies: - regenerator-runtime "^0.13.4" - -"@discoveryjs/json-ext@^0.5.0": - version "0.5.6" - resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" - integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA== - -"@fortawesome/fontawesome-free@^5.15.4": - version "5.15.4" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5" - integrity sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@popperjs/core@^2.11.2": - version "2.11.2" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.2.tgz#830beaec4b4091a9e9398ac50f865ddea52186b9" - integrity sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA== - -"@rjaros/gettext.js@^1.1.3": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@rjaros/gettext.js/-/gettext.js-1.1.3.tgz#8d1109f4a6f8e0c4dadba26281c7fe83de8ab18f" - integrity sha512-FgGWKCN88UE6nOmIjdv+gSnrE3AXjMx7f4uo3brLzKcC9dKzuNNDCzTIbuEDg38Pm1yYUTUH6QG4493T4sUnDg== - dependencies: - "@rjaros/po2json" "^1.0.0-beta-4" - -"@rjaros/po2json@^1.0.0-beta-4": - version "1.0.0-beta-4" - resolved "https://registry.yarnpkg.com/@rjaros/po2json/-/po2json-1.0.0-beta-4.tgz#0bd911af874afa39d868aeb88f6903cfabfbf5dd" - integrity sha512-VhNHrPJtX+caY99UnjCmMB0EWY4EgtZ/pj/Usyj4VUt3TtjHE5nV+fz4bVC0/OO641ncEFFfC3SJ2TurcwEWPw== - dependencies: - commander "^6.0.0" - gettext-parser "2.0.0" - gettext-to-messageformat "0.3.1" - -"@rjaros/snabbdom-virtualize@^1.0.0-beta.5": - version "1.0.0-beta.5" - resolved "https://registry.yarnpkg.com/@rjaros/snabbdom-virtualize/-/snabbdom-virtualize-1.0.0-beta.5.tgz#17f2586beee5e6c130e1b0ae2f589ff9162a86db" - integrity sha512-2rf1MI7wVSZLOgy+EXtOfYzqcwLtMjak4wzRBQUVJjO4qlCmlSo+bh890eKkILhRGxkp6aTQS9gMjH1fP9g8Nw== - dependencies: - html-parse-stringify "^3" - -"@socket.io/base64-arraybuffer@~1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#568d9beae00b0d835f4f8c53fd55714986492e61" - integrity sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ== - -"@types/body-parser@*": - version "1.19.2" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" - integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/bonjour@^3.5.9": - version "3.5.10" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" - integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== - dependencies: - "@types/node" "*" - -"@types/component-emitter@^1.2.10": - version "1.2.11" - resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" - integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== - -"@types/connect-history-api-fallback@^1.3.5": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" - integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== - dependencies: - "@types/express-serve-static-core" "*" - "@types/node" "*" - -"@types/connect@*": - version "3.4.35" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" - integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== - dependencies: - "@types/node" "*" - -"@types/cookie@^0.4.0", "@types/cookie@^0.4.1": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" - integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== - -"@types/cors@^2.8.12", "@types/cors@^2.8.8": - version "2.8.12" - resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" - integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== - -"@types/eslint-scope@^3.7.0": - version "3.7.3" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224" - integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "8.4.1" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.1.tgz#c48251553e8759db9e656de3efc846954ac32304" - integrity sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree@*": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== - -"@types/estree@^0.0.50": - version "0.0.50" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" - integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== - -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": - version "4.17.28" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8" - integrity sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - -"@types/express@*": - version "4.17.13" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" - integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.18" - "@types/qs" "*" - "@types/serve-static" "*" - -"@types/geojson@*", "@types/geojson@7946.0.8": - version "7946.0.8" - resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" - integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA== - -"@types/glob@5 - 7": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - -"@types/http-proxy@^1.17.8": - version "1.17.8" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.8.tgz#968c66903e7e42b483608030ee85800f22d03f55" - integrity sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA== - dependencies: - "@types/node" "*" - -"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.9" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" - integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== - -"@types/leaflet@^1.7.7": - version "1.7.9" - resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.7.9.tgz#7993d34f14cfa88c45b3d490daba39a3a1be9a2b" - integrity sha512-H8vPgD49HKzqM41ArHGZM70g/tfhp8W+JcPxfnF+5H/Xvp+xiP+KQOUNWU8U89fqS1Jj3cpRY/+nbnaHFzwnFA== - dependencies: - "@types/geojson" "*" - -"@types/mime@^1": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" - integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== - -"@types/minimatch@*": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" - integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== - -"@types/node@*", "@types/node@>=10.0.0": - version "17.0.16" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.16.tgz#e3733f46797b9df9e853ca9f719c8a6f7b84cd26" - integrity sha512-ydLaGVfQOQ6hI1xK2A5nVh8bl0OGoIfYMxPWHqqYe9bTkWCfqiVvZoh2I/QF2sNSkZzZyROBoTefIEI+PB6iIA== - -"@types/parse5@^5": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" - integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== - -"@types/qs@*": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== - -"@types/range-parser@*": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" - integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== - -"@types/retry@^0.12.0": - version "0.12.1" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" - integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== - -"@types/serve-index@^1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" - integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== - dependencies: - "@types/express" "*" - -"@types/serve-static@*": - version "1.13.10" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" - integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== - dependencies: - "@types/mime" "^1" - "@types/node" "*" - -"@types/sockjs@^0.3.33": - version "0.3.33" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" - integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== - dependencies: - "@types/node" "*" - -"@types/ws@^8.2.2": - version "8.2.2" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.2.2.tgz#7c5be4decb19500ae6b3d563043cd407bf366c21" - integrity sha512-NOn5eIcgWLOo6qW8AcuLZ7G8PycXu0xTxxkS6Q18VWFxgPUSOwV0pBj2a/4viNZVu25i7RIB7GttdkAIUUXOOg== - dependencies: - "@types/node" "*" - -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== - dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== - -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== - -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== - -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== - -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== - -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" - -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@xtuc/long" "4.2.2" - -"@webpack-cli/configtest@^1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.1.tgz#9f53b1b7946a6efc2a749095a4f450e2932e8356" - integrity sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg== - -"@webpack-cli/info@^1.4.0": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.1.tgz#2360ea1710cbbb97ff156a3f0f24556e0fc1ebea" - integrity sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA== - dependencies: - envinfo "^7.7.3" - -"@webpack-cli/serve@^1.6.0": - version "1.6.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.1.tgz#0de2875ac31b46b6c5bb1ae0a7d7f0ba5678dffe" - integrity sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw== - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - -abab@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" - integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== - -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: - version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== - -acorn@^8.4.1: - version "8.7.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" - integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv-formats@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" - integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== - dependencies: - ajv "^8.0.0" - -ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - -ajv-keywords@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" - integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== - dependencies: - fast-deep-equal "^3.1.3" - -ajv@^6.12.5: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^8.0.0, ajv@^8.8.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.10.0.tgz#e573f719bd3af069017e3b66538ab968d040e54d" - integrity sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-html-community@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" - integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - -array-flatten@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -async@^2.6.2: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== - dependencies: - lodash "^4.17.14" - -awesome-bootstrap-checkbox@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/awesome-bootstrap-checkbox/-/awesome-bootstrap-checkbox-1.0.1.tgz#dab10146b6001129ab0a0ec1e54bb77c6c30457a" - integrity sha1-2rEBRrYAESmrCg7B5Uu3fGwwRXo= - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base64-arraybuffer@0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" - integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= - -base64id@2.0.0, base64id@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" - integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== - -batch@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -body-parser@1.19.1, body-parser@^1.19.0: - version "1.19.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.1.tgz#1499abbaa9274af3ecc9f6f10396c995943e31d4" - integrity sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA== - dependencies: - bytes "3.1.1" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.2" - http-errors "1.8.1" - iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.9.6" - raw-body "2.4.2" - type-is "~1.6.18" - -bonjour@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" - integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= - dependencies: - array-flatten "^2.1.0" - deep-equal "^1.0.1" - dns-equal "^1.0.0" - dns-txt "^2.0.2" - multicast-dns "^6.0.1" - multicast-dns-service-types "^1.1.0" - -bootstrap-icons@^1.7.2: - version "1.8.1" - resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.8.1.tgz#773c1625bcbf3e86090ea9da4386c2c6459c5582" - integrity sha512-IXUqislddPJfwq6H+2nTkHyr9epO9h6u1AG0OZCx616w+TgzeoCjfmI3qJMQqt1J586gN2IxzB4M99Ip4sTZ1w== - -bootstrap@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.1.3.tgz#ba081b0c130f810fa70900acbc1c6d3c28fa8f34" - integrity sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -browserslist@^4.14.5: - version "4.19.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" - integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== - dependencies: - caniuse-lite "^1.0.30001286" - electron-to-chromium "^1.4.17" - escalade "^3.1.1" - node-releases "^2.0.1" - picocolors "^1.0.0" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer-indexof@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" - integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== - -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= - -bytes@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a" - integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg== - -call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -camelcase@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caniuse-lite@^1.0.30001286: - version "1.0.30001310" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001310.tgz#da02cd07432c9eece6992689d1b84ca18139eea8" - integrity sha512-cb9xTV8k9HTIUA3GnPUJCk0meUnrHL5gy5QePfDjxHyNBcnzPzrHFv5GqfP7ue5b1ZyzZL0RJboD6hQlPXjhjg== - -chalk@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chart.js@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.7.0.tgz#7a19c93035341df801d613993c2170a1fcf1d882" - integrity sha512-31gVuqqKp3lDIFmzpKIrBeum4OpZsQjSIAqlOpgjosHDJZlULtvwLEZKtEhIAZc7JMPaHlYMys40Qy9Mf+1AAg== - -chokidar@3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" - integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chokidar@3.5.3, chokidar@^3.5.1, chokidar@^3.5.2: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chrome-trace-event@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" - integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -clone-deep@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== - dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -colorette@^2.0.10, colorette@^2.0.14: - version "2.0.16" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" - integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== - -colors@1.4.0, colors@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@^6.0.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" - integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== - -commander@^7.0.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - -component-emitter@~1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -compressible@~2.0.16: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== - dependencies: - mime-db ">= 1.43.0 < 2" - -compression@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -connect-history-api-fallback@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" - integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== - -connect@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" - integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== - dependencies: - debug "2.6.9" - finalhandler "1.1.2" - parseurl "~1.3.3" - utils-merge "1.0.1" - -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - -cookie@0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" - integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== - -cookie@~0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" - integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -cors@~2.8.5: - version "2.8.5" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" - integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== - dependencies: - object-assign "^4" - vary "^1" - -cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -css-loader@^6.5.1: - version "6.6.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.6.0.tgz#c792ad5510bd1712618b49381bd0310574fafbd3" - integrity sha512-FK7H2lisOixPT406s5gZM1S3l8GrfhEBT3ZiL2UX1Ng1XWs0y2GPllz/OTyvbaHe12VgQrIXIzuEGVlbUhodqg== - dependencies: - icss-utils "^5.1.0" - postcss "^8.4.5" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" - postcss-modules-scope "^3.0.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.2.0" - semver "^7.3.5" - -css-selector-parser@^1.3: - version "1.4.1" - resolved "https://registry.yarnpkg.com/css-selector-parser/-/css-selector-parser-1.4.1.tgz#03f9cb8a81c3e5ab2c51684557d5aaf6d2569759" - integrity sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g== - -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - -custom-event@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" - integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= - -date-format@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.3.tgz#f63de5dc08dc02efd8ef32bf2a6918e486f35873" - integrity sha512-7P3FyqDcfeznLZp2b+OMitV9Sz2lUnsT87WaTat9nVwqsBkTzPG3lPLNwW3en6F4pHUiWzr6vb8CLhjdK9bcxQ== - -debug@2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - -debug@4.3.3, debug@^4.1.0, debug@^4.1.1, debug@^4.3.3, debug@~4.3.1, debug@~4.3.2: - version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== - dependencies: - ms "2.1.2" - -debug@^3.1.1: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -deep-equal@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - -default-gateway@^6.0.0, default-gateway@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" - integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== - dependencies: - execa "^5.0.0" - -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -del@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/del/-/del-6.0.0.tgz#0b40d0332cea743f1614f818be4feb717714c952" - integrity sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ== - dependencies: - globby "^11.0.1" - graceful-fs "^4.2.4" - is-glob "^4.0.1" - is-path-cwd "^2.2.0" - is-path-inside "^3.0.2" - p-map "^4.0.0" - rimraf "^3.0.2" - slash "^3.0.0" - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - -detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - -di@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" - integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw= - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= - -dns-packet@^1.3.1: - version "1.3.4" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" - integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== - dependencies: - ip "^1.1.0" - safe-buffer "^5.0.1" - -dns-txt@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" - integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= - dependencies: - buffer-indexof "^1.0.0" - -dom-serialize@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" - integrity sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs= - dependencies: - custom-event "~1.0.0" - ent "~2.2.0" - extend "^3.0.0" - void-elements "^2.0.0" - -dukat@0.5.8-rc.3: - version "0.5.8-rc.3" - resolved "https://registry.yarnpkg.com/dukat/-/dukat-0.5.8-rc.3.tgz#4a2b848b9d2978cb610af8d5cf24ff5e5a408743" - integrity sha512-wzl9A5alTT1Mag4y7bUVjPF4L/wkts7AiiWxe6/6tL5gSDowexUzlJX/pYVTbnHcOo48/bok3Ao1gzU4/cFFjw== - dependencies: - google-protobuf "3.12.2" - typescript "3.9.5" - -dukat@0.5.8-rc.4: - version "0.5.8-rc.4" - resolved "https://registry.yarnpkg.com/dukat/-/dukat-0.5.8-rc.4.tgz#90384dcb50b14c26f0e99dae92b2dea44f5fce21" - integrity sha512-ZnMt6DGBjlVgK2uQamXfd7uP/AxH7RqI0BL9GLrrJb2gKdDxvJChWy+M9AQEaL+7/6TmxzJxFOsRiInY9oGWTA== - dependencies: - google-protobuf "3.12.2" - typescript "3.9.5" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -electron-to-chromium@^1.4.17: - version "1.4.67" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.67.tgz#699e59d6959d05f87865e12b3055bbcf492bbbee" - integrity sha512-A6a2jEPLueEDfb7kvh7/E94RKKnIb01qL+4I7RFxtajmo+G9F5Ei7HgY5PRbQ4RDrh6DGDW66P0hD5XI2nRAcg== - -element-resize-event@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/element-resize-event/-/element-resize-event-3.0.6.tgz#3a18efd4879ad615e979fd8bbf173b014987eb9a" - integrity sha512-sSeXY9rNDp86bJODW68pxLcy3A5FrPZfIgOrJHzqgYzX513Zq6/ytdBigp7KeJEpZZopBBSiO1cVuiRkZpNxLw== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -encoding@^0.1.12: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - -engine.io-parser@~4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-4.0.3.tgz#83d3a17acfd4226f19e721bb22a1ee8f7662d2f6" - integrity sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA== - dependencies: - base64-arraybuffer "0.1.4" - -engine.io-parser@~5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.3.tgz#ca1f0d7b11e290b4bfda251803baea765ed89c09" - integrity sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg== - dependencies: - "@socket.io/base64-arraybuffer" "~1.0.2" - -engine.io@~4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-4.1.2.tgz#f96ceb56d4b39cc7ca5bd29a20e9c99c1ad1a765" - integrity sha512-t5z6zjXuVLhXDMiFJPYsPOWEER8B0tIsD3ETgw19S1yg9zryvUfY3Vhtk3Gf4sihw/bQGIqQ//gjvVlu+Ca0bQ== - dependencies: - accepts "~1.3.4" - base64id "2.0.0" - cookie "~0.4.1" - cors "~2.8.5" - debug "~4.3.1" - engine.io-parser "~4.0.0" - ws "~7.4.2" - -engine.io@~6.1.0: - version "6.1.2" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.1.2.tgz#e7b9d546d90c62246ffcba4d88594be980d3855a" - integrity sha512-v/7eGHxPvO2AWsksyx2PUsQvBafuvqs0jJJQ0FdmJG1b9qIvgSbqDRGwNhfk2XHaTTbTXiC4quRE8Q9nRjsrQQ== - dependencies: - "@types/cookie" "^0.4.1" - "@types/cors" "^2.8.12" - "@types/node" ">=10.0.0" - accepts "~1.3.4" - base64id "2.0.0" - cookie "~0.4.1" - cors "~2.8.5" - debug "~4.3.1" - engine.io-parser "~5.0.0" - ws "~8.2.3" - -enhanced-resolve@^5.8.3: - version "5.9.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.9.0.tgz#49ac24953ac8452ed8fed2ef1340fc8e043667ee" - integrity sha512-weDYmzbBygL7HzGGS26M3hGQx68vehdEg6VUmqSOaFzXExFqlnKuSvsEJCVGQHScS8CQMbrAqftT+AzzHNt/YA== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - -ent@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" - integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0= - -envinfo@^7.7.3: - version "7.8.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" - integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== - -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-string-regexp@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-scope@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -eventemitter3@^4.0.0: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -events@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -express@^4.17.1: - version "4.17.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.2.tgz#c18369f265297319beed4e5558753cc8c1364cb3" - integrity sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg== - dependencies: - accepts "~1.3.7" - array-flatten "1.1.1" - body-parser "1.19.1" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.4.1" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.1.2" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.7" - qs "6.9.6" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.17.2" - serve-static "1.14.2" - setprototypeof "1.2.0" - statuses "~1.5.0" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -extend@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@^3.2.9: - version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" - integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fastest-levenshtein@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" - integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== - -fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== - dependencies: - reusify "^1.0.4" - -faye-websocket@^0.11.3: - version "0.11.4" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" - integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== - dependencies: - websocket-driver ">=0.5.1" - -fecha@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce" - integrity sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q== - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@1.1.2, finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - -find-up@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^3.2.4: - version "3.2.5" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" - integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== - -follow-redirects@^1.0.0: - version "1.14.8" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc" - integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA== - -format-util@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" - integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -fs-extra@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" - integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^8.0.1: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-monkey@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" - integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -geojson@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/geojson/-/geojson-0.5.0.tgz#3cd6c96399be65b56ee55596116fe9191ce701c0" - integrity sha1-PNbJY5m+ZbVu5VWWEW/pGRznAcA= - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.0.2: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -gettext-extract@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/gettext-extract/-/gettext-extract-2.0.1.tgz#4ade7e3d7c1c247d95a81f28059ca1923c355886" - integrity sha512-k51R90txkCZeXQEDjK0e7gNHfBHJVCu8IQ3AbSVZoOL5nR3yl+C+7qpzp6hoZwOtiniaY+CKeLyvNulsEUM6MA== - dependencies: - chalk "^2.3.0" - find-up "^4.1.0" - fs-extra "^8.0.1" - gettext-extractor "^3.1.0" - minimist "^1.2.0" - -gettext-extractor@^3.1.0: - version "3.5.3" - resolved "https://registry.yarnpkg.com/gettext-extractor/-/gettext-extractor-3.5.3.tgz#6ed46931c154a7485a80fa8b91b835ff7b8d0411" - integrity sha512-9EgJ+hmbtAbATdMIvCj4WnrkeDWH6fv1z+IJJ1XCxdcUMGx6JQdVVFTdzJkSyIHh4td53ngoB5EQbavbKJU9Og== - dependencies: - "@types/glob" "5 - 7" - "@types/parse5" "^5" - css-selector-parser "^1.3" - glob "5 - 7" - parse5 "5 - 6" - pofile "1.0.x" - typescript "2 - 4" - -gettext-parser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-2.0.0.tgz#c28bb31e61f76f14665dfafbb5c0518cdc1270ed" - integrity sha512-FDs/7XjNw58ToQwJFO7avZZbPecSYgw8PBYhd0An+4JtZSrSzKhEvTsVV2uqdO7VziWTOGSgLGD5YRPdsCjF7Q== - dependencies: - encoding "^0.1.12" - safe-buffer "^5.1.2" - -gettext-parser@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-1.4.0.tgz#f8baf34a292f03d5e42f02df099d301f167a7ace" - integrity sha512-sedZYLHlHeBop/gZ1jdg59hlUEcpcZJofLq2JFwJT1zTqAU3l2wFv6IsuwFHGqbiT9DWzMUW4/em2+hspnmMMA== - dependencies: - encoding "^0.1.12" - safe-buffer "^5.1.1" - -gettext-to-messageformat@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/gettext-to-messageformat/-/gettext-to-messageformat-0.3.1.tgz#c303ff9e31a5c781b14629b13bddb27b9ffca1f8" - integrity sha512-UyqIL3Ul4NryU95Wome/qtlcuVIqgEWVIFw0zi7Lv14ACLXfaVDCbrjZ7o+3BZ7u+4NS1mP/2O1eXZoHCoas8g== - dependencies: - gettext-parser "^1.4.0" - -glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" - integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== - -"glob@5 - 7", glob@7.2.0, glob@^7.1.3, glob@^7.1.7: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globby@^11.0.1: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -google-protobuf@3.12.2: - version "3.12.2" - resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.12.2.tgz#50ce9f9b6281235724eb243d6a83e969a2176e53" - integrity sha512-4CZhpuRr1d6HjlyrxoXoocoGFnRYgKULgMtikMddA9ztRyYR59Aondv2FioyxWVamRo0rF2XpYawkTCBEQOSkA== - -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: - version "4.2.9" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" - integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -handle-thing@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" - integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.1, has-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" - integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -he@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -html-entities@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488" - integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ== - -html-parse-stringify@^3: - version "3.0.1" - resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2" - integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg== - dependencies: - void-elements "3.1.0" - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= - -http-errors@1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" - integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.1" - -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-parser-js@>=0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.5.tgz#d7c30d5d3c90d865b4a2e870181f9d6f22ac7ac5" - integrity sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA== - -http-proxy-middleware@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.3.tgz#5df04f69a89f530c2284cd71eeaa51ba52243289" - integrity sha512-1bloEwnrHMnCoO/Gcwbz7eSVvW50KPES01PecpagI+YLNLci4AcuKJrujW4Mc3sBLpFxMSlsLNHS5Nl/lvrTPA== - dependencies: - "@types/http-proxy" "^1.17.8" - http-proxy "^1.18.1" - is-glob "^4.0.1" - is-plain-obj "^3.0.0" - micromatch "^4.0.2" - -http-proxy@^1.18.1: - version "1.18.1" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" - integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -icss-utils@^5.0.0, icss-utils@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" - integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== - -ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== - -import-local@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -imports-loader@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-3.1.1.tgz#3e464d9aad1e303b1b34b658eb8f8aae22f96435" - integrity sha512-3QMyGU4RTgxLf0puWkUfT5+7zJvexvB00PI5skDIcxG8O20gZCbQsaRpNBv+cIO6yy/lmlOBwaxc3uH1CV+sww== - dependencies: - source-map "^0.6.1" - strip-comments "^2.0.1" - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -internal-ip@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-6.2.0.tgz#d5541e79716e406b74ac6b07b856ef18dc1621c1" - integrity sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg== - dependencies: - default-gateway "^6.0.0" - ipaddr.js "^1.9.1" - is-ip "^3.1.0" - p-event "^4.2.0" - -interpret@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" - integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== - -ip-regex@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" - integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== - -ip@^1.1.0: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= - -ipaddr.js@1.9.1, ipaddr.js@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -ipaddr.js@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" - integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== - -is-arguments@^1.0.4: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" - integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-core-module@^2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" - integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-ip@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8" - integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q== - dependencies: - ip-regex "^4.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-path-cwd@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - -is-path-inside@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-plain-obj@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" - integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== - -is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-regex@^1.0.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isbinaryfile@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.8.tgz#5d34b94865bd4946633ecc78a026fc76c5b11fcf" - integrity sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -jest-worker@^27.4.5: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" - integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jquery@^3.5.1: - version "3.6.0" - resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470" - integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw== - -js-yaml@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -karma-chrome-launcher@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz#805a586799a4d05f4e54f72a204979f3f3066738" - integrity sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg== - dependencies: - which "^1.2.1" - -karma-mocha@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-2.0.1.tgz#4b0254a18dfee71bdbe6188d9a6861bf86b0cd7d" - integrity sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ== - dependencies: - minimist "^1.2.3" - -karma-sourcemap-loader@0.3.8: - version "0.3.8" - resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.8.tgz#d4bae72fb7a8397328a62b75013d2df937bdcf9c" - integrity sha512-zorxyAakYZuBcHRJE+vbrK2o2JXLFWK8VVjiT/6P+ltLBUGUvqTEkUiQ119MGdOrK7mrmxXHZF1/pfT6GgIZ6g== - dependencies: - graceful-fs "^4.1.2" - -karma-webpack@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.0.tgz#2a2c7b80163fe7ffd1010f83f5507f95ef39f840" - integrity sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA== - dependencies: - glob "^7.1.3" - minimatch "^3.0.4" - webpack-merge "^4.1.5" - -karma@6.3.12: - version "6.3.12" - resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.12.tgz#fe6347f027385fc16da1a9bb87d766e2d25981c6" - integrity sha512-qwIG+oB2YmHx4hjvYSRMNzL3YWAJ9baHaLAxiP7biFNkfpwYTUTtPck0joFpucalNLzMr+7z/FX1uY/kl8DV9A== - dependencies: - body-parser "^1.19.0" - braces "^3.0.2" - chokidar "^3.5.1" - colors "1.4.0" - connect "^3.7.0" - di "^0.0.1" - dom-serialize "^2.2.1" - glob "^7.1.7" - graceful-fs "^4.2.6" - http-proxy "^1.18.1" - isbinaryfile "^4.0.8" - lodash "^4.17.21" - log4js "^6.3.0" - mime "^2.5.2" - minimatch "^3.0.4" - qjobs "^1.2.0" - range-parser "^1.2.1" - rimraf "^3.0.2" - socket.io "^4.2.0" - source-map "^0.6.1" - tmp "^0.2.1" - ua-parser-js "^0.7.30" - yargs "^16.1.1" - -karma@6.3.4: - version "6.3.4" - resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.4.tgz#359899d3aab3d6b918ea0f57046fd2a6b68565e6" - integrity sha512-hbhRogUYIulfkBTZT7xoPrCYhRBnBoqbbL4fszWD0ReFGUxU+LYBr3dwKdAluaDQ/ynT9/7C+Lf7pPNW4gSx4Q== - dependencies: - body-parser "^1.19.0" - braces "^3.0.2" - chokidar "^3.5.1" - colors "^1.4.0" - connect "^3.7.0" - di "^0.0.1" - dom-serialize "^2.2.1" - glob "^7.1.7" - graceful-fs "^4.2.6" - http-proxy "^1.18.1" - isbinaryfile "^4.0.8" - lodash "^4.17.21" - log4js "^6.3.0" - mime "^2.5.2" - minimatch "^3.0.4" - qjobs "^1.2.0" - range-parser "^1.2.1" - rimraf "^3.0.2" - socket.io "^3.1.0" - source-map "^0.6.1" - tmp "^0.2.1" - ua-parser-js "^0.7.28" - yargs "^16.1.1" - -kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -kvision-assets@^5.0.8: - version "5.0.8" - resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-5.0.8.tgz#f2220135a94b1330cb2ac8f1804b53f40a9bd711" - integrity sha512-umq47D8z2W7cTYR/6RtJ+048mlsi5X515tcM/PFgDcbaI82Pd9EHv2m9520SxmBH6AD04GTweWNyUcKlPx9oZQ== - -leaflet@^1.7.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.7.1.tgz#10d684916edfe1bf41d688a3b97127c0322a2a19" - integrity sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw== - -loader-runner@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" - integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-symbols@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -log4js@^6.3.0: - version "6.4.1" - resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.4.1.tgz#9d3a8bf2c31c1e213fe3fc398a6053f7a2bc53e8" - integrity sha512-iUiYnXqAmNKiIZ1XSAitQ4TmNs8CdZYTAWINARF3LjnsLN8tY5m0vRwd6uuWj/yNY0YHxeZodnbmxKFUOM2rMg== - dependencies: - date-format "^4.0.3" - debug "^4.3.3" - flatted "^3.2.4" - rfdc "^1.3.0" - streamroller "^3.0.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - -memfs@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.1.tgz#b78092f466a0dce054d63d39275b24c71d3f1305" - integrity sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw== - dependencies: - fs-monkey "1.0.3" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - -micromatch@^4.0.2, micromatch@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" - integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== - dependencies: - braces "^3.0.1" - picomatch "^2.2.3" - -mime-db@1.51.0, "mime-db@>= 1.43.0 < 2": - version "1.51.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" - integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== - -mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: - version "2.1.34" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" - integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== - dependencies: - mime-db "1.51.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mime@^2.5.2: - version "2.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" - integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimalistic-assert@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimatch@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^3.0.4: - version "3.0.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" - integrity sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -mkdirp@^0.5.5: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -mocha@9.1.2: - version "9.1.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.2.tgz#93f53175b0f0dc4014bd2d612218fccfcf3534d3" - integrity sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.2" - debug "4.3.2" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.1.7" - growl "1.10.5" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "3.0.4" - ms "2.1.3" - nanoid "3.1.25" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - workerpool "6.1.5" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -mocha@9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.0.tgz#2bfba73d46e392901f877ab9a47b7c9c5d0275cc" - integrity sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.3" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" - growl "1.10.5" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "3.0.4" - ms "2.1.3" - nanoid "3.2.0" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - workerpool "6.2.0" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -multicast-dns-service-types@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" - integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= - -multicast-dns@^6.0.1: - version "6.2.3" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" - integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== - dependencies: - dns-packet "^1.3.1" - thunky "^1.0.2" - -nanoid@3.1.25: - version "3.1.25" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" - integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== - -nanoid@3.2.0, nanoid@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" - integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== - -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -node-forge@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" - integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== - -node-forge@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.2.1.tgz#82794919071ef2eb5c509293325cec8afd0fd53c" - integrity sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w== - -node-releases@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01" - integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -object-assign@^4: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-is@^1.0.1: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -open@^8.0.9: - version "8.4.0" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" - integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - -p-event@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" - integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== - dependencies: - p-timeout "^3.1.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -p-retry@^4.5.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c" - integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA== - dependencies: - "@types/retry" "^0.12.0" - retry "^0.13.1" - -p-timeout@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" - integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== - dependencies: - p-finally "^1.0.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -"parse5@5 - 6": - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - -parseurl@~1.3.2, parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -pofile@1.0.x: - version "1.0.11" - resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.0.11.tgz#35aff58c17491d127a07336d5522ebc9df57c954" - integrity sha512-Vy9eH1dRD9wHjYt/QqXcTz+RnX/zg53xK+KljFSX30PvdDMb2z+c6uDUeblUGqqJgz3QFsdlA0IJvHziPmWtQg== - -portfinder@^1.0.28: - version "1.0.28" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" - integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== - dependencies: - async "^2.6.2" - debug "^3.1.1" - mkdirp "^0.5.5" - -postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" - integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== - -postcss-modules-local-by-default@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" - integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== - dependencies: - icss-utils "^5.0.0" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.1.0" - -postcss-modules-scope@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" - integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== - dependencies: - postcss-selector-parser "^6.0.4" - -postcss-modules-values@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" - integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== - dependencies: - icss-utils "^5.0.0" - -postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: - version "6.0.9" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f" - integrity sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" - integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== - -postcss@^8.4.5: - version "8.4.6" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.6.tgz#c5ff3c3c457a23864f32cb45ac9b741498a09ae1" - integrity sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA== - dependencies: - nanoid "^3.2.0" - picocolors "^1.0.0" - source-map-js "^1.0.2" - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qjobs@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" - integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== - -qs@6.9.6: - version "6.9.6" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" - integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -range-parser@^1.2.1, range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32" - integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ== - dependencies: - bytes "3.1.1" - http-errors "1.8.1" - iconv-lite "0.4.24" - unpipe "1.0.0" - -readable-stream@^2.0.1: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -rechoir@^0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" - integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== - dependencies: - resolve "^1.9.0" - -redux-thunk@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.1.tgz#0dd8042cf47868f4b29699941de03c9301a75714" - integrity sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q== - -redux@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.2.tgz#140f35426d99bb4729af760afcf79eaaac407104" - integrity sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw== - dependencies: - "@babel/runtime" "^7.9.2" - -regenerator-runtime@^0.13.4: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== - -regexp.prototype.flags@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307" - integrity sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve@^1.9.0: - version "1.22.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" - integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== - dependencies: - is-core-module "^2.8.1" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -retry@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rfdc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== - -rimraf@^3.0.0, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -schema-utils@^3.1.0, schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" - integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== - dependencies: - "@types/json-schema" "^7.0.9" - ajv "^8.8.0" - ajv-formats "^2.1.1" - ajv-keywords "^5.0.0" - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= - -selfsigned@^1.10.11: - version "1.10.14" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.14.tgz#ee51d84d9dcecc61e07e4aba34f229ab525c1574" - integrity sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA== - dependencies: - node-forge "^0.10.0" - -selfsigned@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.0.tgz#e927cd5377cbb0a1075302cff8df1042cc2bce5b" - integrity sha512-cUdFiCbKoa1mZ6osuJs2uDHrs0k0oprsKveFiiaBKCNq3SYyb5gs2HxhQyDNLCmL51ZZThqi4YNDpCK6GOP1iQ== - dependencies: - node-forge "^1.2.0" - -semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - -send@0.17.2: - version "0.17.2" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" - integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "1.8.1" - mime "1.6.0" - ms "2.1.3" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" - -serialize-javascript@6.0.0, serialize-javascript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - -serve-static@1.14.2: - version "1.14.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" - integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.2" - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== - dependencies: - kind-of "^6.0.2" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -signal-exit@^3.0.3: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -snabbdom@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.3.1.tgz#a2fb9a1c85cc19d6dc11c4c5e4c78cbbbaafff1f" - integrity sha512-FR9u20dCkktPd+qbedqwYNjMXzYhizhqlKTQzYZimLNeCJY0/5qgs0DtLVSmzIEL1bN3Dyb9sQpiHGCxUjyLnQ== - -socket.io-adapter@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz#edc5dc36602f2985918d631c1399215e97a1b527" - integrity sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg== - -socket.io-adapter@~2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz#4d6111e4d42e9f7646e365b4f578269821f13486" - integrity sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ== - -socket.io-parser@~4.0.3, socket.io-parser@~4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0" - integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g== - dependencies: - "@types/component-emitter" "^1.2.10" - component-emitter "~1.3.0" - debug "~4.3.1" - -socket.io@^3.1.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-3.1.2.tgz#06e27caa1c4fc9617547acfbb5da9bc1747da39a" - integrity sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw== - dependencies: - "@types/cookie" "^0.4.0" - "@types/cors" "^2.8.8" - "@types/node" ">=10.0.0" - accepts "~1.3.4" - base64id "~2.0.0" - debug "~4.3.1" - engine.io "~4.1.0" - socket.io-adapter "~2.1.0" - socket.io-parser "~4.0.3" - -socket.io@^4.2.0: - version "4.4.1" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.4.1.tgz#cd6de29e277a161d176832bb24f64ee045c56ab8" - integrity sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg== - dependencies: - accepts "~1.3.4" - base64id "~2.0.0" - debug "~4.3.2" - engine.io "~6.1.0" - socket.io-adapter "~2.3.3" - socket.io-parser "~4.0.4" - -sockjs@^0.3.21: - version "0.3.24" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" - integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== - dependencies: - faye-websocket "^0.11.3" - uuid "^8.3.2" - websocket-driver "^0.7.4" - -source-map-js@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" - integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== - -source-map-js@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" - integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== - -source-map-loader@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.0.tgz#f2a04ee2808ad01c774dea6b7d2639839f3b3049" - integrity sha512-GKGWqWvYr04M7tn8dryIWvb0s8YM41z82iQv01yBtIylgxax0CwvSy6gc2Y02iuXwEfGWRlMicH0nvms9UZphw== - dependencies: - abab "^2.0.5" - iconv-lite "^0.6.2" - source-map-js "^0.6.2" - -source-map-support@0.5.20: - version "0.5.20" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" - integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0, source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -source-map@~0.7.2: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== - -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -split.js@^1.6.5: - version "1.6.5" - resolved "https://registry.yarnpkg.com/split.js/-/split.js-1.6.5.tgz#f7f61da1044c9984cb42947df4de4fadb5a3f300" - integrity sha512-mPTnGCiS/RiuTNsVhCm9De9cCAUsrNFFviRbADdKiiV+Kk8HKp/0fWu7Kr8pi3/yBmsqLFHuXGT9UUZ+CNLwFw== - -"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -streamroller@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.0.2.tgz#30418d0eee3d6c93ec897f892ed098e3a81e68b7" - integrity sha512-ur6y5S5dopOaRXBuRIZ1u6GC5bcEXHRZKgfBjfCglMhmIf+roVCECjvkEYzNQOXIN2/JPnkMPW/8B3CZoKaEPA== - dependencies: - date-format "^4.0.3" - debug "^4.1.1" - fs-extra "^10.0.0" - -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== - dependencies: - ansi-regex "^6.0.1" - -strip-comments@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" - integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-json-comments@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -style-loader@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" - integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== - -supports-color@8.1.1, supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -tapable@^2.1.1, tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== - -terser-webpack-plugin@^5.1.3: - version "5.3.1" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz#0320dcc270ad5372c1e8993fabbd927929773e54" - integrity sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g== - dependencies: - jest-worker "^27.4.5" - schema-utils "^3.1.1" - serialize-javascript "^6.0.0" - source-map "^0.6.1" - terser "^5.7.2" - -terser@^5.7.2: - version "5.10.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc" - integrity sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA== - dependencies: - commander "^2.20.0" - source-map "~0.7.2" - source-map-support "~0.5.20" - -thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" - integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== - -tmp@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -"typescript@2 - 4": - version "4.5.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3" - integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== - -typescript@3.9.5: - version "3.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" - integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== - -ua-parser-js@^0.7.28, ua-parser-js@^0.7.30: - version "0.7.31" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" - integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -v8-compile-cache@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -vary@^1, vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - -void-elements@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" - integrity sha1-YU9/v42AHwu18GYfWy9XhXUOTwk= - -void-elements@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" - integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= - -watchpack@^2.2.0, watchpack@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25" - integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - -webpack-cli@4.9.0: - version "4.9.0" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.0.tgz#dc43e6e0f80dd52e89cbf73d5294bcd7ad6eb343" - integrity sha512-n/jZZBMzVEl4PYIBs+auy2WI0WTQ74EnJDiyD98O2JZY6IVIHJNitkYp/uTXOviIOMfgzrNvC9foKv/8o8KSZw== - dependencies: - "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.1.0" - "@webpack-cli/info" "^1.4.0" - "@webpack-cli/serve" "^1.6.0" - colorette "^2.0.14" - commander "^7.0.0" - execa "^5.0.0" - fastest-levenshtein "^1.0.12" - import-local "^3.0.2" - interpret "^2.2.0" - rechoir "^0.7.0" - v8-compile-cache "^2.2.0" - webpack-merge "^5.7.3" - -webpack-cli@4.9.1: - version "4.9.1" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3" - integrity sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ== - dependencies: - "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.1.0" - "@webpack-cli/info" "^1.4.0" - "@webpack-cli/serve" "^1.6.0" - colorette "^2.0.14" - commander "^7.0.0" - execa "^5.0.0" - fastest-levenshtein "^1.0.12" - import-local "^3.0.2" - interpret "^2.2.0" - rechoir "^0.7.0" - webpack-merge "^5.7.3" - -webpack-dev-middleware@^5.2.1, webpack-dev-middleware@^5.3.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz#aa079a8dedd7e58bfeab358a9af7dab304cee57f" - integrity sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg== - dependencies: - colorette "^2.0.10" - memfs "^3.4.1" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - -webpack-dev-server@4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.3.1.tgz#759d3337f0fbea297fbd1e433ab04ccfc000076b" - integrity sha512-qNXQCVYo1kYhH9pgLtm8LRNkXX3XzTfHSj/zqzaqYzGPca+Qjr+81wj1jgPMCHhIhso9WEQ+kX9z23iG9PzQ7w== - dependencies: - ansi-html-community "^0.0.8" - bonjour "^3.5.0" - chokidar "^3.5.1" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^1.6.0" - del "^6.0.0" - express "^4.17.1" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.0" - internal-ip "^6.2.0" - ipaddr.js "^2.0.1" - open "^8.0.9" - p-retry "^4.5.0" - portfinder "^1.0.28" - schema-utils "^3.1.0" - selfsigned "^1.10.11" - serve-index "^1.9.1" - sockjs "^0.3.21" - spdy "^4.0.2" - strip-ansi "^7.0.0" - url "^0.11.0" - webpack-dev-middleware "^5.2.1" - ws "^8.1.0" - -webpack-dev-server@4.7.3: - version "4.7.3" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.7.3.tgz#4e995b141ff51fa499906eebc7906f6925d0beaa" - integrity sha512-mlxq2AsIw2ag016nixkzUkdyOE8ST2GTy34uKSABp1c4nhjZvH90D5ZRR+UOLSsG4Z3TFahAi72a3ymRtfRm+Q== - dependencies: - "@types/bonjour" "^3.5.9" - "@types/connect-history-api-fallback" "^1.3.5" - "@types/serve-index" "^1.9.1" - "@types/sockjs" "^0.3.33" - "@types/ws" "^8.2.2" - ansi-html-community "^0.0.8" - bonjour "^3.5.0" - chokidar "^3.5.2" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^1.6.0" - default-gateway "^6.0.3" - del "^6.0.0" - express "^4.17.1" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.0" - ipaddr.js "^2.0.1" - open "^8.0.9" - p-retry "^4.5.0" - portfinder "^1.0.28" - schema-utils "^4.0.0" - selfsigned "^2.0.0" - serve-index "^1.9.1" - sockjs "^0.3.21" - spdy "^4.0.2" - strip-ansi "^7.0.0" - webpack-dev-middleware "^5.3.0" - ws "^8.1.0" - -webpack-merge@^4.1.5: - version "4.2.2" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" - integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== - dependencies: - lodash "^4.17.15" - -webpack-merge@^5.7.3: - version "5.8.0" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" - integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== - dependencies: - clone-deep "^4.0.1" - wildcard "^2.0.0" - -webpack-sources@^3.2.0, webpack-sources@^3.2.2: - version "3.2.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" - integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== - -webpack@5.57.1: - version "5.57.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.57.1.tgz#ead5ace2c17ecef2ae8126f143bfeaa7f55eab44" - integrity sha512-kHszukYjTPVfCOEyrUthA3jqJwduY/P3eO8I0gMNOZGIQWKAwZftxmp5hq6paophvwo9NoUrcZOecs9ulOyyTg== - dependencies: - "@types/eslint-scope" "^3.7.0" - "@types/estree" "^0.0.50" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.4.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.8.3" - es-module-lexer "^0.9.0" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.4" - json-parse-better-errors "^1.0.2" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.1.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.2.0" - webpack-sources "^3.2.0" - -webpack@5.66.0: - version "5.66.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.66.0.tgz#789bf36287f407fc92b3e2d6f978ddff1bfc2dbb" - integrity sha512-NJNtGT7IKpGzdW7Iwpn/09OXz9inIkeIQ/ibY6B+MdV1x6+uReqz/5z1L89ezWnpPDWpXF0TY5PCYKQdWVn8Vg== - dependencies: - "@types/eslint-scope" "^3.7.0" - "@types/estree" "^0.0.50" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.4.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.8.3" - es-module-lexer "^0.9.0" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" - json-parse-better-errors "^1.0.2" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.1.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.3.1" - webpack-sources "^3.2.2" - -websocket-driver@>=0.5.1, websocket-driver@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" - integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.4" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" - integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== - -which@2.0.2, which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -which@^1.2.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -wildcard@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" - integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== - -workerpool@6.1.5: - version "6.1.5" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" - integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== - -workerpool@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" - integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -ws@^8.1.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" - integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== - -ws@~7.4.2: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== - -ws@~8.2.3: - version "8.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" - integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@16.2.0, yargs@^16.1.1: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/build.gradle.kts b/build.gradle.kts index 1007434..9269694 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.2.8" +version = "0.2.9" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt deleted file mode 100644 index bbd4ec7..0000000 --- a/buildSrc/src/main/kotlin/Versions.kt +++ /dev/null @@ -1,13 +0,0 @@ -object Versions { - - const val kotlinLang = "1.6" - const val jvmTarget = "11" - - const val node = "14.19.0" - - const val kotlinWrappers = "0.0.1-pre.294-kotlin-1.6.10" - const val junit = "5.8.2" - const val kotest = "5.1.0" - const val mockk = "1.12.1" - -} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt index 6a779a7..11e6b2b 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt @@ -3,6 +3,7 @@ package dev.adamko.kafkatorio import kotlinx.serialization.json.Json import org.gradle.api.Project import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.extra import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension val jsonMapper = Json { @@ -11,15 +12,38 @@ val jsonMapper = Json { } +object Versions { + const val kotlinLang = "1.6" + const val jvmTarget = "11" + + const val node = "14.19.0" + + const val kotlinWrappers = "0.0.1-pre.294-kotlin-1.6.10" + const val junit = "5.8.2" + const val kotest = "5.1.0" + const val mockk = "1.12.1" +} + + /** * `kotlin-js` adds a directory in the root-dir for the Yarn lock. * That's a bit annoying. It's a little neater if it's in the * gradle dir, next to the version-catalog. */ fun Project.relocateKotlinJsStore() { + afterEvaluate { rootProject.extensions.configure { - lockFileDirectory = rootProject.rootDir.resolve("gradle/kotlin-js-store") + lockFileDirectory = project.rootDir.resolve("gradle/kotlin-js-store") } } + +// rootProject.plugins.withType(YarnPlugin::class) { +// rootProject.the().lockFileDirectory = +// project.rootDir.resolve("gradle/kotlin-js-store") +// } + + // KVision tries to be clever too - see io.kvision.gradle.KVisionGradleSubplugin + rootProject.extra.set("io.kvision.plugin.enableHiddenKotlinJsStore", "false") + } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt index 793ecef..7347c65 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt @@ -11,8 +11,10 @@ import org.gradle.api.provider.MapProperty import org.gradle.api.specs.Spec import org.gradle.kotlin.dsl.invoke + operator fun Spec.not(): Spec = Spec { !this(it) } + fun Project.isProcessRunning(process: String, ignoreCase: Boolean = true): Spec = Spec { ByteArrayOutputStream().use { outputStream -> @@ -25,6 +27,7 @@ fun Project.isProcessRunning(process: String, ignoreCase: Boolean = true): Spec< } } + fun Project.areJsonPropertiesUpToDate( packageJsonFile: RegularFileProperty, properties: MapProperty diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts index 44f2edf..68bf4cf 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts @@ -1,6 +1,6 @@ package dev.adamko.kafkatorio.lang -import Versions +import dev.adamko.kafkatorio.Versions import dev.adamko.kafkatorio.relocateKotlinJsStore import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index 7938683..342a119 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.lang +import dev.adamko.kafkatorio.Versions import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts index 9734ff0..478bd24 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts @@ -5,7 +5,7 @@ import dev.adamko.kafkatorio.relocateKotlinJsStore plugins { id("dev.adamko.kafkatorio.base") - id("dev.adamko.kafkatorio.lang.node") +// id("dev.adamko.kafkatorio.lang.node") kotlin("multiplatform") } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts index 2360e37..4a03369 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts @@ -1,8 +1,8 @@ package dev.adamko.kafkatorio.lang -import Versions import com.github.gradle.node.NodePlugin import com.github.gradle.node.npm.task.NpmInstallTask +import dev.adamko.kafkatorio.Versions import dev.adamko.kafkatorio.gradle.areJsonPropertiesUpToDate import dev.adamko.kafkatorio.gradle.not import dev.adamko.kafkatorio.jsonMapper diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index 09534e0..9eaf61e 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -40,29 +40,80 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@popperjs/core@^2.10.2": - version "2.11.0" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.0.tgz#6734f8ebc106a0860dff7f92bf90df193f0935d7" - integrity sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ== +"@popperjs/core@^2.11.2": + version "2.11.2" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.2.tgz#830beaec4b4091a9e9398ac50f865ddea52186b9" + integrity sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA== -"@rjaros/snabbdom-virtualize@^1.0.0-beta.0": - version "1.0.0-beta.0" - resolved "https://registry.yarnpkg.com/@rjaros/snabbdom-virtualize/-/snabbdom-virtualize-1.0.0-beta.0.tgz#b35f143d8772b3bdf1222784450f3a05a4403e6f" - integrity sha512-aIx4z9BDoTW0Tn1gIhnmv/NU5dYvlTjSJOKYSQvY0TX1WYMX9fQNQT37t1M2GEwqbQyBEffyhlEEfF100JCNGQ== +"@rjaros/gettext.js@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@rjaros/gettext.js/-/gettext.js-1.1.3.tgz#8d1109f4a6f8e0c4dadba26281c7fe83de8ab18f" + integrity sha512-FgGWKCN88UE6nOmIjdv+gSnrE3AXjMx7f4uo3brLzKcC9dKzuNNDCzTIbuEDg38Pm1yYUTUH6QG4493T4sUnDg== dependencies: - html-parse-stringify2 "^2" + "@rjaros/po2json" "^1.0.0-beta-4" + +"@rjaros/po2json@^1.0.0-beta-4": + version "1.0.0-beta-4" + resolved "https://registry.yarnpkg.com/@rjaros/po2json/-/po2json-1.0.0-beta-4.tgz#0bd911af874afa39d868aeb88f6903cfabfbf5dd" + integrity sha512-VhNHrPJtX+caY99UnjCmMB0EWY4EgtZ/pj/Usyj4VUt3TtjHE5nV+fz4bVC0/OO641ncEFFfC3SJ2TurcwEWPw== + dependencies: + commander "^6.0.0" + gettext-parser "2.0.0" + gettext-to-messageformat "0.3.1" + +"@rjaros/snabbdom-virtualize@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@rjaros/snabbdom-virtualize/-/snabbdom-virtualize-1.0.0-beta.5.tgz#17f2586beee5e6c130e1b0ae2f589ff9162a86db" + integrity sha512-2rf1MI7wVSZLOgy+EXtOfYzqcwLtMjak4wzRBQUVJjO4qlCmlSo+bh890eKkILhRGxkp6aTQS9gMjH1fP9g8Nw== + dependencies: + html-parse-stringify "^3" + +"@socket.io/base64-arraybuffer@~1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#568d9beae00b0d835f4f8c53fd55714986492e61" + integrity sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ== + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.10" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" + integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== + dependencies: + "@types/node" "*" "@types/component-emitter@^1.2.10": version "1.2.11" resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== -"@types/cookie@^0.4.0": +"@types/connect-history-api-fallback@^1.3.5": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" + integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/cookie@^0.4.0", "@types/cookie@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== -"@types/cors@^2.8.8": +"@types/cors@^2.8.12", "@types/cors@^2.8.8": version "2.8.12" resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== @@ -88,6 +139,25 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": + version "4.17.28" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8" + integrity sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + "@types/geojson@*", "@types/geojson@7946.0.8": version "7946.0.8" resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" @@ -120,6 +190,11 @@ dependencies: "@types/geojson" "*" +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + "@types/minimatch@*": version "3.0.5" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" @@ -135,11 +210,50 @@ resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + "@types/retry@^0.12.0": version "0.12.1" resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== +"@types/serve-index@^1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" + integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== + dependencies: + "@types/express" "*" + +"@types/serve-static@*": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.33" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" + integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== + dependencies: + "@types/node" "*" + +"@types/ws@^8.2.2": + version "8.2.2" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.2.2.tgz#7c5be4decb19500ae6b3d563043cd407bf366c21" + integrity sha512-NOn5eIcgWLOo6qW8AcuLZ7G8PycXu0xTxxkS6Q18VWFxgPUSOwV0pBj2a/4viNZVu25i7RIB7GttdkAIUUXOOg== + dependencies: + "@types/node" "*" + "@ungap/promise-all-settled@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" @@ -397,11 +511,6 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansi-styles@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" - integrity sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg= - anymatch@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" @@ -495,10 +604,10 @@ bonjour@^3.5.0: multicast-dns "^6.0.1" multicast-dns-service-types "^1.1.0" -bootstrap-icons@^1.6.0: - version "1.7.2" - resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.7.2.tgz#4024e081e2c850602552e1fed6451e682d09322a" - integrity sha512-NiR2PqC73AQOPdVSu6GJfnk+hN2z6powcistXk1JgPnKuoV2FSdSl26w931Oz9HYbKCcKUSB6ncZTYJAYJl3QQ== +bootstrap-icons@^1.7.2: + version "1.8.1" + resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.8.1.tgz#773c1625bcbf3e86090ea9da4386c2c6459c5582" + integrity sha512-IXUqislddPJfwq6H+2nTkHyr9epO9h6u1AG0OZCx616w+TgzeoCjfmI3qJMQqt1J586gN2IxzB4M99Ip4sTZ1w== bootstrap@^5.1.3: version "5.1.3" @@ -591,19 +700,10 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" - integrity sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8= - dependencies: - ansi-styles "~1.0.0" - has-color "~0.1.0" - strip-ansi "~0.1.0" - -chart.js@^3.6.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.6.2.tgz#47342c551f688ffdda2cd53b534cb7e461ecec33" - integrity sha512-Xz7f/fgtVltfQYWq0zL1Xbv7N2inpG+B54p3D5FSvpCdy3sM+oZhbqa42eNuYXltaVvajgX5UpKCU2GeeJIgxg== +chart.js@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.7.0.tgz#7a19c93035341df801d613993c2170a1fcf1d882" + integrity sha512-31gVuqqKp3lDIFmzpKIrBeum4OpZsQjSIAqlOpgjosHDJZlULtvwLEZKtEhIAZc7JMPaHlYMys40Qy9Mf+1AAg== chokidar@3.5.2, chokidar@^3.5.1, chokidar@^3.5.2: version "3.5.2" @@ -620,6 +720,21 @@ chokidar@3.5.2, chokidar@^3.5.1, chokidar@^3.5.2: optionalDependencies: fsevents "~2.3.2" +chokidar@3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + chrome-trace-event@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" @@ -677,7 +792,7 @@ colorette@^2.0.10, colorette@^2.0.14: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== -colors@^1.4.0: +colors@1.4.0, colors@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== @@ -687,6 +802,11 @@ commander@^2.20.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@^6.0.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + commander@^7.0.0: version "7.2.0" resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" @@ -834,6 +954,13 @@ debug@4.3.2: dependencies: ms "2.1.2" +debug@4.3.3, debug@^4.1.0, debug@^4.1.1, debug@~4.3.1, debug@~4.3.2: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + debug@^3.1.1: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -841,13 +968,6 @@ debug@^3.1.1: dependencies: ms "^2.1.1" -debug@^4.1.0, debug@^4.1.1, debug@~4.3.1: - version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== - dependencies: - ms "2.1.2" - decamelize@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" @@ -865,7 +985,7 @@ deep-equal@^1.0.1: object-keys "^1.1.1" regexp.prototype.flags "^1.2.0" -default-gateway@^6.0.3: +default-gateway@^6.0.0, default-gateway@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== @@ -1001,7 +1121,7 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.11: +encoding@^0.1.12: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== @@ -1015,6 +1135,13 @@ engine.io-parser@~4.0.0: dependencies: base64-arraybuffer "0.1.4" +engine.io-parser@~5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.3.tgz#ca1f0d7b11e290b4bfda251803baea765ed89c09" + integrity sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg== + dependencies: + "@socket.io/base64-arraybuffer" "~1.0.2" + engine.io@~4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-4.1.1.tgz#9a8f8a5ac5a5ea316183c489bf7f5b6cf91ace5b" @@ -1028,6 +1155,22 @@ engine.io@~4.1.0: engine.io-parser "~4.0.0" ws "~7.4.2" +engine.io@~6.1.0: + version "6.1.2" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.1.2.tgz#e7b9d546d90c62246ffcba4d88594be980d3855a" + integrity sha512-v/7eGHxPvO2AWsksyx2PUsQvBafuvqs0jJJQ0FdmJG1b9qIvgSbqDRGwNhfk2XHaTTbTXiC4quRE8Q9nRjsrQQ== + dependencies: + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~5.0.0" + ws "~8.2.3" + enhanced-resolve@^5.8.3: version "5.8.3" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" @@ -1355,19 +1498,28 @@ gettext-extractor@^3.1.0: pofile "1.0.x" typescript "2 - 4" -gettext-parser@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-1.1.0.tgz#2c5a6638d893934b9b55037d0ad82cb7004b2679" - integrity sha1-LFpmONiTk0ubVQN9CtgstwBLJnk= +gettext-parser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-2.0.0.tgz#c28bb31e61f76f14665dfafbb5c0518cdc1270ed" + integrity sha512-FDs/7XjNw58ToQwJFO7avZZbPecSYgw8PBYhd0An+4JtZSrSzKhEvTsVV2uqdO7VziWTOGSgLGD5YRPdsCjF7Q== dependencies: - encoding "^0.1.11" + encoding "^0.1.12" + safe-buffer "^5.1.2" -gettext.js@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/gettext.js/-/gettext.js-1.1.1.tgz#5644ee7a2cd687e7bbca0f508b75f08aa61eaf17" - integrity sha512-+GlPwSg/rGOVjRRU8kkgP4v6V6t+SulDZrT70D2YntUQVUN8q6TtfNMCa0F3h+QB5y7mvLY52V8MOSipdhrnow== +gettext-parser@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-1.4.0.tgz#f8baf34a292f03d5e42f02df099d301f167a7ace" + integrity sha512-sedZYLHlHeBop/gZ1jdg59hlUEcpcZJofLq2JFwJT1zTqAU3l2wFv6IsuwFHGqbiT9DWzMUW4/em2+hspnmMMA== dependencies: - po2json "^0.4.0" + encoding "^0.1.12" + safe-buffer "^5.1.1" + +gettext-to-messageformat@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/gettext-to-messageformat/-/gettext-to-messageformat-0.3.1.tgz#c303ff9e31a5c781b14629b13bddb27b9ffca1f8" + integrity sha512-UyqIL3Ul4NryU95Wome/qtlcuVIqgEWVIFw0zi7Lv14ACLXfaVDCbrjZ7o+3BZ7u+4NS1mP/2O1eXZoHCoas8g== + dependencies: + gettext-parser "^1.4.0" glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" @@ -1381,7 +1533,7 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -"glob@5 - 7", glob@^7.1.3, glob@^7.1.7: +"glob@5 - 7", glob@7.2.0, glob@^7.1.3, glob@^7.1.7: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== @@ -1427,6 +1579,11 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== +graceful-fs@^4.2.9: + version "4.2.9" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" + integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== + growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" @@ -1437,11 +1594,6 @@ handle-thing@^2.0.0: resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== -has-color@~0.1.0: - version "0.1.7" - resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" - integrity sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8= - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -1491,12 +1643,12 @@ html-entities@^2.3.2: resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488" integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ== -html-parse-stringify2@^2: - version "2.0.1" - resolved "https://registry.yarnpkg.com/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz#dc5670b7292ca158b7bc916c9a6735ac8872834a" - integrity sha1-3FZwtyksoVi3vJFsmmc1rIhyg0o= +html-parse-stringify@^3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2" + integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg== dependencies: - void-elements "^2.0.1" + void-elements "3.1.0" http-deceiver@^1.2.7: version "1.2.7" @@ -1617,17 +1769,32 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= +internal-ip@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-6.2.0.tgz#d5541e79716e406b74ac6b07b856ef18dc1621c1" + integrity sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg== + dependencies: + default-gateway "^6.0.0" + ipaddr.js "^1.9.1" + is-ip "^3.1.0" + p-event "^4.2.0" + interpret@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== +ip-regex@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" + integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== + ip@^1.1.0: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= -ipaddr.js@1.9.1: +ipaddr.js@1.9.1, ipaddr.js@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== @@ -1688,6 +1855,13 @@ is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-ip@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8" + integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q== + dependencies: + ip-regex "^4.0.0" + is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -1838,6 +2012,35 @@ karma-webpack@5.0.0: minimatch "^3.0.4" webpack-merge "^4.1.5" +karma@6.3.12: + version "6.3.12" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.12.tgz#fe6347f027385fc16da1a9bb87d766e2d25981c6" + integrity sha512-qwIG+oB2YmHx4hjvYSRMNzL3YWAJ9baHaLAxiP7biFNkfpwYTUTtPck0joFpucalNLzMr+7z/FX1uY/kl8DV9A== + dependencies: + body-parser "^1.19.0" + braces "^3.0.2" + chokidar "^3.5.1" + colors "1.4.0" + connect "^3.7.0" + di "^0.0.1" + dom-serialize "^2.2.1" + glob "^7.1.7" + graceful-fs "^4.2.6" + http-proxy "^1.18.1" + isbinaryfile "^4.0.8" + lodash "^4.17.21" + log4js "^6.3.0" + mime "^2.5.2" + minimatch "^3.0.4" + qjobs "^1.2.0" + range-parser "^1.2.1" + rimraf "^3.0.2" + socket.io "^4.2.0" + source-map "^0.6.1" + tmp "^0.2.1" + ua-parser-js "^0.7.30" + yargs "^16.1.1" + karma@6.3.4: version "6.3.4" resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.4.tgz#359899d3aab3d6b918ea0f57046fd2a6b68565e6" @@ -1872,10 +2075,10 @@ kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -kvision-assets@^5.0.7: - version "5.0.7" - resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-5.0.7.tgz#e6dc3e28a2d244b4c89318b060d3e7e337c15495" - integrity sha512-szoL8ixFRTivLkbnmkWFjGJMk3bsUW/loUS5QfWThPwFnyFEw8ht3eBUrJ0V51Rn/WaJbVoPvY4SfIaiNu13bg== +kvision-assets@^5.0.8: + version "5.0.8" + resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-5.0.8.tgz#f2220135a94b1330cb2ac8f1804b53f40a9bd711" + integrity sha512-umq47D8z2W7cTYR/6RtJ+048mlsi5X515tcM/PFgDcbaI82Pd9EHv2m9520SxmBH6AD04GTweWNyUcKlPx9oZQ== leaflet@^1.7.1: version "1.7.1" @@ -1944,6 +2147,13 @@ memfs@^3.2.2: dependencies: fs-monkey "1.0.3" +memfs@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.1.tgz#b78092f466a0dce054d63d39275b24c71d3f1305" + integrity sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw== + dependencies: + fs-monkey "1.0.3" + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -2053,6 +2263,36 @@ mocha@9.1.2: yargs-parser "20.2.4" yargs-unparser "2.0.0" +mocha@9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.0.tgz#2bfba73d46e392901f877ab9a47b7c9c5d0275cc" + integrity sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.3" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + growl "1.10.5" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "3.0.4" + ms "2.1.3" + nanoid "3.2.0" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + workerpool "6.2.0" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -2086,6 +2326,11 @@ nanoid@3.1.25: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== +nanoid@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" + integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== + nanoid@^3.1.30: version "3.1.30" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362" @@ -2106,19 +2351,16 @@ node-forge@^0.10.0: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== +node-forge@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.2.1.tgz#82794919071ef2eb5c509293325cec8afd0fd53c" + integrity sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w== + node-releases@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== -nomnom@1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" - integrity sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc= - dependencies: - chalk "~0.4.0" - underscore "~1.6.0" - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -2189,6 +2431,18 @@ open@^8.0.9: is-docker "^2.1.1" is-wsl "^2.2.0" +p-event@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" + integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== + dependencies: + p-timeout "^3.1.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -2232,6 +2486,13 @@ p-retry@^4.5.0: "@types/retry" "^0.12.0" retry "^0.13.1" +p-timeout@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -2294,14 +2555,6 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -po2json@^0.4.0: - version "0.4.5" - resolved "https://registry.yarnpkg.com/po2json/-/po2json-0.4.5.tgz#47bb2952da32d58a1be2f256a598eebc0b745118" - integrity sha1-R7spUtoy1Yob4vJWpZjuvAt0URg= - dependencies: - gettext-parser "1.1.0" - nomnom "1.8.1" - pofile@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.0.11.tgz#35aff58c17491d127a07336d5522ebc9df57c954" @@ -2561,7 +2814,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -2602,6 +2855,13 @@ selfsigned@^1.10.11: dependencies: node-forge "^0.10.0" +selfsigned@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.0.tgz#e927cd5377cbb0a1075302cff8df1042cc2bce5b" + integrity sha512-cUdFiCbKoa1mZ6osuJs2uDHrs0k0oprsKveFiiaBKCNq3SYyb5gs2HxhQyDNLCmL51ZZThqi4YNDpCK6GOP1iQ== + dependencies: + node-forge "^1.2.0" + semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" @@ -2697,17 +2957,22 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -snabbdom@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.2.0.tgz#8ea6b2517739a7d9ca82df3f181d052adf1ca5ad" - integrity sha512-UWyfm8WbaFmbmYLC33pe5fawBfExhynkMDoZqQ8ehlHDwkxrgIOpWhKf5PaacLUW1n+Uwu5N5HND6mESU7cMlw== +snabbdom@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.3.1.tgz#a2fb9a1c85cc19d6dc11c4c5e4c78cbbbaafff1f" + integrity sha512-FR9u20dCkktPd+qbedqwYNjMXzYhizhqlKTQzYZimLNeCJY0/5qgs0DtLVSmzIEL1bN3Dyb9sQpiHGCxUjyLnQ== socket.io-adapter@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz#edc5dc36602f2985918d631c1399215e97a1b527" integrity sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg== -socket.io-parser@~4.0.3: +socket.io-adapter@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz#4d6111e4d42e9f7646e365b4f578269821f13486" + integrity sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ== + +socket.io-parser@~4.0.3, socket.io-parser@~4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0" integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g== @@ -2731,6 +2996,18 @@ socket.io@^3.1.0: socket.io-adapter "~2.1.0" socket.io-parser "~4.0.3" +socket.io@^4.2.0: + version "4.4.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.4.1.tgz#cd6de29e277a161d176832bb24f64ee045c56ab8" + integrity sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg== + dependencies: + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.2" + engine.io "~6.1.0" + socket.io-adapter "~2.3.3" + socket.io-parser "~4.0.4" + sockjs@^0.3.21: version "0.3.24" resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" @@ -2759,14 +3036,6 @@ source-map-loader@3.0.0: iconv-lite "^0.6.2" source-map-js "^0.6.2" -source-map-support@0.5.20: - version "0.5.20" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" - integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" @@ -2808,10 +3077,10 @@ spdy@^4.0.2: select-hose "^2.0.0" spdy-transport "^3.0.0" -split.js@^1.6.4: - version "1.6.4" - resolved "https://registry.yarnpkg.com/split.js/-/split.js-1.6.4.tgz#13d47cba53382adef230a53294ce5dacb2a2f2e1" - integrity sha512-kYmQZprRJrF1IOjg/E+gdBEsKFv5kbgUE6RJVJZvrIzTOK/IHzKSqIeiJnWs7IP5D9TnpTQ2CbanuDuIWcyDUQ== +split.js@^1.6.5: + version "1.6.5" + resolved "https://registry.yarnpkg.com/split.js/-/split.js-1.6.5.tgz#f7f61da1044c9984cb42947df4de4fadb5a3f300" + integrity sha512-mPTnGCiS/RiuTNsVhCm9De9cCAUsrNFFviRbADdKiiV+Kk8HKp/0fWu7Kr8pi3/yBmsqLFHuXGT9UUZ+CNLwFw== "statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: version "1.5.0" @@ -2864,11 +3133,6 @@ strip-ansi@^7.0.0: dependencies: ansi-regex "^6.0.1" -strip-ansi@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" - integrity sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE= - strip-comments@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" @@ -2977,16 +3241,11 @@ typescript@3.9.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== -ua-parser-js@^0.7.28: +ua-parser-js@^0.7.28, ua-parser-js@^0.7.30: version "0.7.31" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== -underscore@~1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" - integrity sha1-izixDKze9jM3uLJOT/htRa6lKag= - universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" @@ -3027,17 +3286,27 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +v8-compile-cache@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= -void-elements@^2.0.0, void-elements@^2.0.1: +void-elements@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" + integrity sha1-YU9/v42AHwu18GYfWy9XhXUOTwk= + +void-elements@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= -watchpack@^2.3.0: +watchpack@^2.2.0, watchpack@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25" integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== @@ -3052,6 +3321,25 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" +webpack-cli@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.0.tgz#dc43e6e0f80dd52e89cbf73d5294bcd7ad6eb343" + integrity sha512-n/jZZBMzVEl4PYIBs+auy2WI0WTQ74EnJDiyD98O2JZY6IVIHJNitkYp/uTXOviIOMfgzrNvC9foKv/8o8KSZw== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.1.0" + "@webpack-cli/info" "^1.4.0" + "@webpack-cli/serve" "^1.6.0" + colorette "^2.0.14" + commander "^7.0.0" + execa "^5.0.0" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + v8-compile-cache "^2.2.0" + webpack-merge "^5.7.3" + webpack-cli@4.9.1: version "4.9.1" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3" @@ -3081,11 +3369,58 @@ webpack-dev-middleware@^5.2.1: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.6.0.tgz#e8648601c440172d9b6f248d28db98bed335315a" - integrity sha512-oojcBIKvx3Ya7qs1/AVWHDgmP1Xml8rGsEBnSobxU/UJSX1xP1GPM3MwsAnDzvqcVmVki8tV7lbcsjEjk0PtYg== +webpack-dev-middleware@^5.3.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz#aa079a8dedd7e58bfeab358a9af7dab304cee57f" + integrity sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg== dependencies: + colorette "^2.0.10" + memfs "^3.4.1" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.3.1.tgz#759d3337f0fbea297fbd1e433ab04ccfc000076b" + integrity sha512-qNXQCVYo1kYhH9pgLtm8LRNkXX3XzTfHSj/zqzaqYzGPca+Qjr+81wj1jgPMCHhIhso9WEQ+kX9z23iG9PzQ7w== + dependencies: + ansi-html-community "^0.0.8" + bonjour "^3.5.0" + chokidar "^3.5.1" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + del "^6.0.0" + express "^4.17.1" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.0" + internal-ip "^6.2.0" + ipaddr.js "^2.0.1" + open "^8.0.9" + p-retry "^4.5.0" + portfinder "^1.0.28" + schema-utils "^3.1.0" + selfsigned "^1.10.11" + serve-index "^1.9.1" + sockjs "^0.3.21" + spdy "^4.0.2" + strip-ansi "^7.0.0" + url "^0.11.0" + webpack-dev-middleware "^5.2.1" + ws "^8.1.0" + +webpack-dev-server@4.7.3: + version "4.7.3" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.7.3.tgz#4e995b141ff51fa499906eebc7906f6925d0beaa" + integrity sha512-mlxq2AsIw2ag016nixkzUkdyOE8ST2GTy34uKSABp1c4nhjZvH90D5ZRR+UOLSsG4Z3TFahAi72a3ymRtfRm+Q== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/serve-index" "^1.9.1" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.2.2" ansi-html-community "^0.0.8" bonjour "^3.5.0" chokidar "^3.5.2" @@ -3103,13 +3438,12 @@ webpack-dev-server@4.6.0: p-retry "^4.5.0" portfinder "^1.0.28" schema-utils "^4.0.0" - selfsigned "^1.10.11" + selfsigned "^2.0.0" serve-index "^1.9.1" sockjs "^0.3.21" spdy "^4.0.2" strip-ansi "^7.0.0" - url "^0.11.0" - webpack-dev-middleware "^5.2.1" + webpack-dev-middleware "^5.3.0" ws "^8.1.0" webpack-merge@^4.1.5: @@ -3127,15 +3461,20 @@ webpack-merge@^5.7.3: clone-deep "^4.0.1" wildcard "^2.0.0" +webpack-sources@^3.2.0: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + webpack-sources@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.2.tgz#d88e3741833efec57c4c789b6010db9977545260" integrity sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw== -webpack@5.64.4: - version "5.64.4" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.64.4.tgz#e1454b6a13009f57cc2c78e08416cd674622937b" - integrity sha512-LWhqfKjCLoYJLKJY8wk2C3h77i8VyHowG3qYNZiIqD6D0ZS40439S/KVuc/PY48jp2yQmy0mhMknq8cys4jFMw== +webpack@5.57.1: + version "5.57.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.57.1.tgz#ead5ace2c17ecef2ae8126f143bfeaa7f55eab44" + integrity sha512-kHszukYjTPVfCOEyrUthA3jqJwduY/P3eO8I0gMNOZGIQWKAwZftxmp5hq6paophvwo9NoUrcZOecs9ulOyyTg== dependencies: "@types/eslint-scope" "^3.7.0" "@types/estree" "^0.0.50" @@ -3159,7 +3498,37 @@ webpack@5.64.4: schema-utils "^3.1.0" tapable "^2.1.1" terser-webpack-plugin "^5.1.3" - watchpack "^2.3.0" + watchpack "^2.2.0" + webpack-sources "^3.2.0" + +webpack@5.66.0: + version "5.66.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.66.0.tgz#789bf36287f407fc92b3e2d6f978ddff1bfc2dbb" + integrity sha512-NJNtGT7IKpGzdW7Iwpn/09OXz9inIkeIQ/ibY6B+MdV1x6+uReqz/5z1L89ezWnpPDWpXF0TY5PCYKQdWVn8Vg== + dependencies: + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.50" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.4.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.8.3" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-better-errors "^1.0.2" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.3.1" webpack-sources "^3.2.2" websocket-driver@>=0.5.1, websocket-driver@^0.7.4: @@ -3200,6 +3569,11 @@ workerpool@6.1.5: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== +workerpool@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" + integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -3224,6 +3598,11 @@ ws@~7.4.2: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +ws@~8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== + y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index 86d4591..e5e5426 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.8", + "version": "0.2.9", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 3ce0e46..b29d3ca 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.8", + "version": "0.2.9", "private": true, "scripts": { "build": "tstl", diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index 098fbe4..cde4244 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -1,18 +1,26 @@ import dev.adamko.kafkatorio.gradle.asProvider import dev.adamko.kafkatorio.gradle.typescriptAttributes + plugins { - kotlin("multiplatform") - kotlin("plugin.serialization") + dev.adamko.kafkatorio.lang.`kotlin-multiplatform` id("io.kotest.multiplatform") + kotlin("plugin.serialization") distribution } + kotlin { js(IR) { binaries.executable() - browser() - nodejs() + browser { + testTask { + useKarma { + useChromeHeadless() + } + } + } +// nodejs() } jvm { testRuns["test"].executionTask.configure { @@ -20,7 +28,6 @@ kotlin { } } - @Suppress("UnstableApiUsage") // platform + version catalogs is incubating sourceSets { all { diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 2e90dfe..d6299a4 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -15,7 +15,7 @@ description = """ val projectId: String by project.extra -@Suppress("UnstableApiUsage") // platform + version-catalog is incubating + dependencies { implementation(libs.kafka.streams) diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index 82dbe34..de3cc23 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio FACTORIO_VERSION=1.1.53 -KAFKATORIO_VERSION=0.2.8 +KAFKATORIO_VERSION=0.2.9 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index 8153f49..c7501d2 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.2.8 +KAFKATORIO_VERSION=0.2.9 diff --git a/modules/infra-kafka-connect/build.gradle.kts b/modules/infra-kafka-connect/build.gradle.kts index 30c163a..eb1820c 100644 --- a/modules/infra-kafka-connect/build.gradle.kts +++ b/modules/infra-kafka-connect/build.gradle.kts @@ -1,5 +1,3 @@ -@file:Suppress("UnstableApiUsage") // VERSION_PLATFORM + platform(...) is unstable - import dev.adamko.kafkatorio.gradle.asConsumer import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index 1ebae11..c7501d2 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.2.7 +KAFKATORIO_VERSION=0.2.9 From f59cc0beb966b2696b0326664c1c1007ed003ad7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 9 Feb 2022 21:53:44 +0100 Subject: [PATCH 189/629] fix queue size? only increase if the key is new --- modules/events-mod/src/main/typescript/main/queue/queue.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/events-mod/src/main/typescript/main/queue/queue.ts b/modules/events-mod/src/main/typescript/main/queue/queue.ts index b985b2e..6483642 100644 --- a/modules/events-mod/src/main/typescript/main/queue/queue.ts +++ b/modules/events-mod/src/main/typescript/main/queue/queue.ts @@ -42,10 +42,10 @@ export namespace Queue { global.tail.next = node } global.tail = node + global.size++ } global.store[key] = event - global.size++ } From 66fa1fb53a2ee0a2c953ba5e6c39207eda917365 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 9 Feb 2022 23:02:00 +0100 Subject: [PATCH 190/629] reuse the packet-splitter topics for the tile-saver job --- .../processor/KafkatorioTopology.kt | 40 ++++++++++-- .../processor/topology/factorioGameState.kt | 63 ++++++++++++------- .../processor/topology/prototypes.kt | 2 +- 3 files changed, 78 insertions(+), 27 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 33d9a16..c0d86bb 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -1,11 +1,19 @@ package dev.adamko.kafkatorio.processor +import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.FactorioObjectData +import dev.adamko.kafkatorio.events.schema.FactorioPrototypes +import dev.adamko.kafkatorio.events.schema.KafkatorioPacket +import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.processor.topology.FactorioServerId import dev.adamko.kafkatorio.processor.topology.factorioServerPacketStream import dev.adamko.kafkatorio.processor.topology.groupTilesIntoChunksWithColours import dev.adamko.kafkatorio.processor.topology.playerUpdatesToWsServer import dev.adamko.kafkatorio.processor.topology.saveMapTiles import dev.adamko.kafkatorio.processor.topology.splitFactorioServerPacketStream import dev.adamko.kafkatorio.processor.topology.tileProtoColourDictionary +import dev.adamko.kotka.extensions.consumedAs +import dev.adamko.kotka.kxs.serde import java.time.Duration import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineName @@ -18,6 +26,8 @@ import org.apache.kafka.streams.KafkaStreams import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.StreamsConfig import org.apache.kafka.streams.Topology +import org.apache.kafka.streams.kstream.KStream + class KafkatorioTopology( private val websocketServer: WebsocketServer, @@ -38,17 +48,37 @@ class KafkatorioTopology( private fun saveTiles() { val builder = StreamsBuilder() - val packets = factorioServerPacketStream(builder) - val tileProtoColourDict = tileProtoColourDictionary(packets) + + val protosStream: KStream = + builder.stream( + "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", + consumedAs("consume.factorio-protos.all", jsonMapper.serde(), jsonMapper.serde()) + ) + val tileProtoColourDict = tileProtoColourDictionary(protosStream) + + + val mapTilesStream: KStream = + builder.stream( + "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", + consumedAs("consume.map-tiles", jsonMapper.serde(), jsonMapper.serde()) + ) + val mapChunksStream: KStream = + builder.stream( + "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", + consumedAs("consume.map-chunks", jsonMapper.serde(), jsonMapper.serde()) + ) val tilePrototypesTable = groupTilesIntoChunksWithColours( - packets, + mapTilesStream, + mapChunksStream, tileProtoColourDict, ) + + saveMapTiles(tilePrototypesTable) - val topology = builder.build() + val topology = builder.build() launchTopology("saveTiles", topology) } @@ -74,7 +104,7 @@ class KafkatorioTopology( private fun launchTopology(id: String, topology: Topology) { - val props = appProps.kafkaConfig + val props = appProps.kafkaConfig val appId = props.compute(StreamsConfig.APPLICATION_ID_CONFIG) { _, v -> "$v.$id" } as? String props.setProperty(StreamsConfig.APPLICATION_ID_CONFIG, appId) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt index c49d6fb..2130f77 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt @@ -2,7 +2,6 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.events.schema.ColourHex import dev.adamko.kafkatorio.events.schema.FactorioEvent -import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.events.schema.MapChunk import dev.adamko.kafkatorio.events.schema.MapChunkPosition import dev.adamko.kafkatorio.events.schema.MapTilePosition @@ -12,7 +11,10 @@ import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.materializedWith +import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.flatMap +import dev.adamko.kotka.extensions.streams.mapValues +import dev.adamko.kotka.extensions.streams.merge import dev.adamko.kotka.extensions.streams.reduce import dev.adamko.kotka.extensions.tables.join import dev.adamko.kotka.kxs.serde @@ -20,6 +22,7 @@ import kotlinx.serialization.Serializable import org.apache.kafka.streams.kstream.KStream import org.apache.kafka.streams.kstream.KTable + @Serializable data class ServerMapChunkId( val serverId: FactorioServerId, @@ -39,38 +42,54 @@ data class ServerMapChunkTiles( fun groupTilesIntoChunksWithColours( - factorioServerPacketStream: KStream, + mapTilePacketsStream: KStream, + mapChunksPacketsStream: KStream, tileProtoColourDict: KTable, ): KTable> { + + val mapChunkTilesStream: KStream = + mapChunksPacketsStream + .filter { _, packet: FactorioEvent? -> + packet != null + && packet.data is MapChunk + && !((packet.data as? MapChunk)?.tiles?.tiles.isNullOrEmpty()) + } + .mapValues("map-chunk-packets.convert-to-map-tiles") { _, packet: FactorioEvent -> + (packet.data as MapChunk).tiles + } + + val mapTilesStream: KStream = + mapTilePacketsStream + .filter { _, packet: FactorioEvent? -> + packet != null + && packet.data is MapTiles + && !((packet.data as? MapTiles)?.tiles.isNullOrEmpty()) + } + .mapValues("map-tiles-packets.convert-to-map-tiles") { _, packet: FactorioEvent -> + packet.data as MapTiles + } + // group tiles by server & surface & chunk val chunkedTilesTable: KTable> = - factorioServerPacketStream - .flatMap("server-map-data.tiles.flatMapByChunk") { key: FactorioServerId, packet: KafkatorioPacket -> - - val mapTileData = when (packet) { - is FactorioEvent -> - when (val data = packet.data) { - is MapChunk -> data.tiles - is MapTiles -> data - else -> null - } - else -> null - } + mapTilesStream + .merge("merge-map-chunk-tiles-with-map-tiles", mapChunkTilesStream) + .filter { _, value -> value != null && value.tiles.isNotEmpty() } + .flatMap("server-map-data.tiles.flatMapByChunk") { key: FactorioServerId, mapTiles: MapTiles -> val zoomLevel = ZoomLevel.ZOOM_0 - mapTileData - ?.tiles - ?.groupBy { tile -> + mapTiles + .tiles + .groupBy { tile -> tile.position.toMapChunkPosition(zoomLevel.chunkSize) } - ?.map { (chunkPos, tiles) -> + .map { (chunkPos, tiles) -> val chunkId = ServerMapChunkId( key, chunkPos, - SurfaceIndex(mapTileData.surfaceIndex), + SurfaceIndex(mapTiles.surfaceIndex), zoomLevel, ) @@ -79,8 +98,10 @@ fun groupTilesIntoChunksWithColours( val chunkTiles = ServerMapChunkTiles(chunkId, tilesMap) chunkId to chunkTiles - } ?: listOf() - + } + } + .filter("server-map-data.tiles.filter-not-empty") { _, value -> + value.map.isNotEmpty() } .groupByKey( groupedAs("server-map-data.tiles.group", kxsBinary.serde(), kxsBinary.serde()) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index 63ce083..b061bf7 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -40,7 +40,7 @@ value class TileColourDict(val map: Map) /** Get the latest map-tile colours per server. */ fun tileProtoColourDictionary( - factorioServerPacketStream: KStream + factorioServerPacketStream: KStream ): KTable { // get all the prototypes From e26327547970156cba17522f8e2031bb544ed373 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 9 Feb 2022 23:02:16 +0100 Subject: [PATCH 191/629] update kafka-resetter for the 3 applications --- modules/events-server/build.gradle.kts | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index d6299a4..5a35bec 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -66,16 +66,31 @@ tasks.withType { ) } -val kafkatorioEventsServerKafkaForceReset by tasks.registering(Exec::class) { +val kafkatorioEventsServerKafkaForceReset by tasks.registering { group = project.name - val cmd = """ - /kafka/bin/kafka-streams-application-reset.sh --application-id kafkatorio-events-processor --input-topics factorio-server-log --force + fun reset(applicationId: String) = """ + /kafka/bin/kafka-streams-application-reset.sh --application-id $applicationId --force """.trimIndent() - logging.captureStandardOutput(LogLevel.LIFECYCLE) + doLast { - commandLine = parseSpaceSeparatedArgs(""" docker exec -d kafka $cmd """) + exec { + val cmd = reset("kafkatorio-events-processor.saveTiles") + logging.captureStandardOutput(LogLevel.LIFECYCLE) + commandLine = parseSpaceSeparatedArgs(""" docker exec -d kafka $cmd """) + } + exec { + val cmd = reset("kafkatorio-events-processor.splitPackets") + logging.captureStandardOutput(LogLevel.LIFECYCLE) + commandLine = parseSpaceSeparatedArgs(""" docker exec -d kafka $cmd --input-topics factorio-server-log """) + } + exec { + val cmd = reset("kafkatorio-events-processor.playerUpdates") + logging.captureStandardOutput(LogLevel.LIFECYCLE) + commandLine = parseSpaceSeparatedArgs(""" docker exec -d kafka $cmd """) + } + } } //tasks.run.configure { From b37da373aee6048ce26848527b2cc288574d6ae3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 9 Feb 2022 23:38:12 +0100 Subject: [PATCH 192/629] split up the tile-chunk-grouping and save-tile applications --- modules/events-server/build.gradle.kts | 5 +++ .../adamko/kafkatorio/admin/CreateTopics.kt | 6 ++- .../processor/KafkatorioTopology.kt | 45 +++++++++++++++---- .../topology/factorioServerPackets.kt | 2 +- ...factorioGameState.kt => groupMapChunks.kt} | 0 5 files changed, 48 insertions(+), 10 deletions(-) rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/{factorioGameState.kt => groupMapChunks.kt} (100%) diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 5a35bec..8e140b2 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -90,6 +90,11 @@ val kafkatorioEventsServerKafkaForceReset by tasks.registering { logging.captureStandardOutput(LogLevel.LIFECYCLE) commandLine = parseSpaceSeparatedArgs(""" docker exec -d kafka $cmd """) } + exec { + val cmd = reset("kafkatorio-events-processor.groupTilesMapChunks") + logging.captureStandardOutput(LogLevel.LIFECYCLE) + commandLine = parseSpaceSeparatedArgs(""" docker exec -d kafka $cmd """) + } } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt index dd9b89b..c1784f6 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt @@ -32,7 +32,10 @@ object KafkaAdmin { val kafkatorioTopics = buildSet { KafkatorioPacket.PacketType.values().forEach { packetType -> - add(KafkatorioTopology.sourceTopic) + + add(KafkatorioTopology.TOPIC_GROUPED_MAP_CHUNKS) + add(KafkatorioTopology.TOPIC_SRC_SERVER_LOG) + when (packetType) { KafkatorioPacket.PacketType.EVENT -> FactorioObjectData.ObjectName.values().forEach { objectName -> @@ -43,6 +46,7 @@ object KafkaAdmin { KafkatorioPacket.PacketType.PROTOTYPES -> add("kafkatorio.${packetType.name}.all") } + } }.minus(currentTopics.toSet()) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index c0d86bb..efba5aa 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -1,11 +1,15 @@ package dev.adamko.kafkatorio.processor +import dev.adamko.kafkatorio.events.schema.ColourHex import dev.adamko.kafkatorio.events.schema.FactorioEvent import dev.adamko.kafkatorio.events.schema.FactorioObjectData import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kafkatorio.processor.topology.FactorioServerId +import dev.adamko.kafkatorio.processor.topology.ServerMapChunkId +import dev.adamko.kafkatorio.processor.topology.ServerMapChunkTiles import dev.adamko.kafkatorio.processor.topology.factorioServerPacketStream import dev.adamko.kafkatorio.processor.topology.groupTilesIntoChunksWithColours import dev.adamko.kafkatorio.processor.topology.playerUpdatesToWsServer @@ -13,6 +17,8 @@ import dev.adamko.kafkatorio.processor.topology.saveMapTiles import dev.adamko.kafkatorio.processor.topology.splitFactorioServerPacketStream import dev.adamko.kafkatorio.processor.topology.tileProtoColourDictionary import dev.adamko.kotka.extensions.consumedAs +import dev.adamko.kotka.extensions.producedAs +import dev.adamko.kotka.extensions.tables.toStream import dev.adamko.kotka.kxs.serde import java.time.Duration import kotlin.coroutines.CoroutineContext @@ -27,6 +33,7 @@ import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.StreamsConfig import org.apache.kafka.streams.Topology import org.apache.kafka.streams.kstream.KStream +import org.apache.kafka.streams.kstream.KTable class KafkatorioTopology( @@ -37,16 +44,18 @@ class KafkatorioTopology( Dispatchers.Default + SupervisorJob() + CoroutineName("KafkatorioTopology") companion object { - const val sourceTopic = "factorio-server-log" + const val TOPIC_SRC_SERVER_LOG = "factorio-server-log" + const val TOPIC_GROUPED_MAP_CHUNKS = "kafkatorio.MAP.grouped-map-chunks" } fun start() { + groupTilesMapChunks() saveTiles() splitPackets() playerUpdates() } - private fun saveTiles() { + private fun groupTilesMapChunks() { val builder = StreamsBuilder() @@ -68,15 +77,35 @@ class KafkatorioTopology( "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", consumedAs("consume.map-chunks", jsonMapper.serde(), jsonMapper.serde()) ) - val tilePrototypesTable = groupTilesIntoChunksWithColours( - mapTilesStream, - mapChunksStream, - tileProtoColourDict, - ) + val groupedMapChunkTiles: KTable> = + groupTilesIntoChunksWithColours( + mapTilesStream, + mapChunksStream, + tileProtoColourDict, + ) + + groupedMapChunkTiles + .toStream("stream-grouped-map-tiles") + .to( + TOPIC_GROUPED_MAP_CHUNKS, + producedAs("produce.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()) + ) - saveMapTiles(tilePrototypesTable) + val topology = builder.build() + launchTopology("groupTilesMapChunks", topology) + } + private fun saveTiles() { + val builder = StreamsBuilder() + + val groupedMapChunkTiles: KTable> = + builder.table( + TOPIC_GROUPED_MAP_CHUNKS, + consumedAs("consume.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()) + ) + + saveMapTiles(groupedMapChunkTiles) val topology = builder.build() launchTopology("saveTiles", topology) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt index 7731256..d1869d3 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt @@ -23,7 +23,7 @@ fun factorioServerPacketStream( ): KStream { return builder.stream( - KafkatorioTopology.sourceTopic, + KafkatorioTopology.TOPIC_SRC_SERVER_LOG, consumedAs( "read-raw-packets-from-server", Serdes.String(), diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt similarity index 100% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioGameState.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt From ec1f1bc2007a900f7e26b88165538299d88566e0 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 9 Feb 2022 23:44:21 +0100 Subject: [PATCH 193/629] reduce logging for saving tiles --- .../dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt index a119712..25b6f4d 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt @@ -163,7 +163,6 @@ private class ServerMapChunkHandler : CoroutineScope { saveImagesFlow .onEach { (filename, img) -> - println("saving map tile $filename") val chunkImageFile = File(filename.value) if (chunkImageFile.parentFile.mkdirs()) { From 7141d7e5f7778b2948b24400c4904325e4b25696 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 13 Feb 2022 10:42:13 +0100 Subject: [PATCH 194/629] - try making a factorio mod portal api client, for auto releasing - make webmapTileDir a configurable variable --- buildSrc/build.gradle.kts | 12 +- buildSrc/settings.gradle.kts | 10 ++ .../task/FactorioModPortalDeploy.kt | 23 ++++ gradle/libs.versions.toml | 4 +- modules/events-server/build.gradle.kts | 5 - .../adamko/kafkatorio/admin/CreateTopics.kt | 5 +- .../processor/KafkatorioTopology.kt | 4 +- .../processor/config/ApplicationProperties.kt | 19 ++-- .../processor/config/environmentExt.kt | 11 +- .../kafkatorio/processor/eventProcessor.kt | 6 +- .../processor/tileserver/WebMapTileServer.kt | 14 +-- .../build.gradle.kts | 37 ++++++ .../kafkatorio/ApplicationProperties.kt | 48 ++++++++ .../kafkatorio/FactorioModPortalClient.kt | 107 ++++++++++++++++++ .../dev/adamko/kafkatorio/modUploader.kt | 14 +++ settings.gradle.kts | 2 + 16 files changed, 287 insertions(+), 34 deletions(-) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/FactorioModPortalDeploy.kt create mode 100644 modules/factorio-mod-portal-client/build.gradle.kts create mode 100644 modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/ApplicationProperties.kt create mode 100644 modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalClient.kt create mode 100644 modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/modUploader.kt diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 9e7f59f..2d4696c 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -11,14 +11,16 @@ plugins { object Versions { const val jvmTarget = "11" const val kotlinTarget = "1.6" + const val kotlin = "1.6.10" const val gradleNodePlugin = "3.2.0" const val gradleDockerComposePlugin = "0.15.0" - const val kotlin = "1.6.10" const val kotlinXSerialization = "1.3.2" const val kvision = "5.8.1" const val semver = "1.1.2" + const val http4k = "4.19.1.0" + const val jsoup = "1.14.3" const val kotest = "5.1.0" } @@ -31,7 +33,7 @@ dependencies { implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}") - implementation(enforcedPlatform("org.jetbrains.kotlinx:kotlinx-serialization-bom:${Versions.kotlinXSerialization}")) + implementation(platform("org.jetbrains.kotlinx:kotlinx-serialization-bom:${Versions.kotlinXSerialization}")) implementation("org.jetbrains.kotlinx:kotlinx-serialization-core") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json") // implementation("com.charleskorn.kaml:kaml:0.37.0") @@ -46,6 +48,12 @@ dependencies { // https://github.com/avast/gradle-docker-compose-plugin implementation("com.avast.gradle:gradle-docker-compose-plugin:${Versions.gradleDockerComposePlugin}") + + implementation(platform("org.http4k:http4k-bom:${Versions.http4k}")) + implementation("org.http4k:http4k-core") + implementation("org.http4k:http4k-client-okhttp") + + implementation("org.jsoup:jsoup:${Versions.jsoup}") } diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts index 8065bb4..f5a0553 100644 --- a/buildSrc/settings.gradle.kts +++ b/buildSrc/settings.gradle.kts @@ -1,3 +1,13 @@ + rootProject.name = "buildSrc" apply(from = "./repositories.settings.gradle.kts") + +@Suppress("UnstableApiUsage") // Central declaration of repositories is an incubating feature +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/FactorioModPortalDeploy.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/FactorioModPortalDeploy.kt new file mode 100644 index 0000000..73ca284 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/FactorioModPortalDeploy.kt @@ -0,0 +1,23 @@ +package dev.adamko.kafkatorio.task + +import org.gradle.api.DefaultTask +import org.http4k.client.OkHttp +import org.http4k.core.Method +import org.http4k.core.Request + +abstract class FactorioModPortalDeploy : DefaultTask() { + + init { + super.doFirst { + + val client = OkHttp() + + val request = Request(Method.GET, "https://factorio.com/login?mods=1") + + println(client(request)) + + + } + } + +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a2ff04b..bd0d438 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -90,10 +90,12 @@ gcp-speech = { group = "com.google.cloud", name = "google-cloud-speech" ## kafka ## kafka-streams = { group = "org.apache.kafka", name = "kafka-streams", version.ref = "kafka" } - # kafka helpers kotka = { group = "com.github.blueanvil", name = "kotka", version = "1.1.1" } +jsoup = { group = "org.jsoup", name = "jsoup", version = "1.14.3" } +skrapeit = { group = "it.skrape", name = "skrapeit", version = "1.2.0" } + ############# ### test ### diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 8e140b2..be8c3c1 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -40,14 +40,9 @@ dependencies { implementation("com.sksamuel.scrimage:scrimage-core:4.0.24") val kotkaVersion = "v0.0.12" -// val kotkaVersion = "store-iterators-SNAPSHOT" implementation("com.github.adamko-dev.kotka-streams:kotka-streams:$kotkaVersion") { isChanging = true } -// val kotkaVersion = "main-SNAPSHOT" -// implementation("dev.adamko.kotka:kotka-streams:$kotkaVersion") { -// isChanging = true -// } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt index c1784f6..3f578e1 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt @@ -10,13 +10,14 @@ import org.apache.kafka.clients.admin.CreateTopicsResult import org.apache.kafka.clients.admin.NewTopic import org.apache.kafka.clients.admin.TopicListing -private val logger = KotlinLogging.logger {} //fun main() { // KafkaAdmin.createKafkatorioTopics() //} -object KafkaAdmin { +object KafkatorioKafkaAdmin { + + private val logger = KotlinLogging.logger {} private val kafkaAdmin: Admin = Admin.create( diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index efba5aa..26269b1 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -5,6 +5,7 @@ import dev.adamko.kafkatorio.events.schema.FactorioEvent import dev.adamko.kafkatorio.events.schema.FactorioObjectData import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket +import dev.adamko.kafkatorio.processor.config.ApplicationProperties import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kafkatorio.processor.topology.FactorioServerId @@ -36,8 +37,9 @@ import org.apache.kafka.streams.kstream.KStream import org.apache.kafka.streams.kstream.KTable -class KafkatorioTopology( +internal class KafkatorioTopology( private val websocketServer: WebsocketServer, + private val appProps: ApplicationProperties = ApplicationProperties(), ) : CoroutineScope { override val coroutineContext: CoroutineContext = diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt index a7f523e..e9ec6e3 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt @@ -1,8 +1,10 @@ package dev.adamko.kafkatorio.processor.config import dev.adamko.kafkatorio.processor.config.PortVal.Companion.portVal +import java.nio.file.Path import java.time.Clock import java.util.Properties +import kotlin.io.path.Path import org.http4k.cloudnative.env.Environment import org.http4k.cloudnative.env.EnvironmentKey import org.http4k.lens.nonEmptyString @@ -15,19 +17,21 @@ import org.http4k.lens.nonEmptyString * # 3. A resources-dir yaml file * */ -class ApplicationProperties( +internal class ApplicationProperties( vararg environments: Environment = arrayOf( Environment.env(), Environment.fromEnvVarPath(), Environment.fromResourcesFile(".secret.config.yml") ) ) { + + private val appProps: Environment = environments.reduce { acc, environment -> acc.overrides(environment) } + fun clock(): Clock = Clock.systemUTC() - // /** * The port of the server @@ -37,10 +41,6 @@ class ApplicationProperties( val serverPort: PortVal get() = EnvironmentKey.portVal().defaulted("PORT", PortVal.DEFAULT)[appProps] - // - - - // val kafkaConfig: Properties get() = EnvironmentKey @@ -54,6 +54,11 @@ class ApplicationProperties( } .required("kafka.config")[appProps] - // + + val webmapTileDir: Path + get() = EnvironmentKey + .nonEmptyString() + .map(::Path) + .required("tileServer.webmapTileDir")[appProps] } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt index 58d592e..4bfeec7 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt @@ -13,11 +13,11 @@ import org.http4k.lens.Lens * * (An improved version of [Environment.fromResource]) */ -internal fun Environment.Companion.fromResourcesFile( +fun Environment.Companion.fromResourcesFile( resource: String, default: Environment = EMPTY -) = - try { +): Environment { + return try { val file = this::class.java .getResource("/${resource.removePrefix("/")}") @@ -27,6 +27,7 @@ internal fun Environment.Companion.fromResourcesFile( } catch (e: FileNotFoundException) { default } +} /** * Try fetching a properties file the location provided by the @@ -35,7 +36,7 @@ internal fun Environment.Companion.fromResourcesFile( * * If it does not exist, return [default]. */ -internal fun Environment.Companion.fromEnvVarPath( +fun Environment.Companion.fromEnvVarPath( location: Lens = Lenses.APPLICATION_PROPERTIES_FILE_PATH, default: Environment = EMPTY, ): Environment { @@ -65,7 +66,7 @@ internal fun Environment.Companion.fromFile( } /** The same as [Environment.ENV], but refreshes on each invocation (which is useful for testing). */ -internal fun Environment.Companion.env(): Environment = +fun Environment.Companion.env(): Environment = MapEnvironment.from(System.getenv().toProperties()) /** The same as [Environment.JVM_PROPERTIES], but refreshes on each invocation (which is useful for testing). */ diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt index 8e0c334..e53bf6d 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -1,7 +1,7 @@ package dev.adamko.kafkatorio.processor -import dev.adamko.kafkatorio.admin.KafkaAdmin +import dev.adamko.kafkatorio.admin.KafkatorioKafkaAdmin import dev.adamko.kafkatorio.processor.config.ApplicationProperties import dev.adamko.kafkatorio.processor.tileserver.WebMapTileServer import kotlinx.coroutines.runBlocking @@ -10,12 +10,12 @@ import org.http4k.server.Undertow import org.http4k.server.asServer -val appProps = ApplicationProperties() +//private val appProps = ApplicationProperties() fun main(): Unit = runBlocking { - KafkaAdmin.createKafkatorioTopics() + KafkatorioKafkaAdmin.createKafkatorioTopics() val wsServer = WebsocketServer() val tileServer = WebMapTileServer() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt index db5e420..db9f440 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt @@ -1,5 +1,7 @@ package dev.adamko.kafkatorio.processor.tileserver +import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import kotlin.io.path.absolutePathString import org.http4k.core.HttpHandler import org.http4k.core.then import org.http4k.filter.CachingFilters @@ -9,17 +11,13 @@ import org.http4k.routing.bind import org.http4k.routing.routes import org.http4k.routing.static -class WebMapTileServer { +internal class WebMapTileServer( + appProps: ApplicationProperties = ApplicationProperties() +) { private val routes: RoutingHttpHandler = routes( "/tiles" bind CachingFilters.Response.NoCache() - .then( - static( - ResourceLoader.Directory( - """D:\Users\Adam\Projects\games\kafkatorio\modules\events-server\src\main\resources\kafkatorio-web-map\""" - ) - ) - ) + .then(static(ResourceLoader.Directory(appProps.webmapTileDir.absolutePathString()))) ) fun build(): HttpHandler { diff --git a/modules/factorio-mod-portal-client/build.gradle.kts b/modules/factorio-mod-portal-client/build.gradle.kts new file mode 100644 index 0000000..0f3cb8d --- /dev/null +++ b/modules/factorio-mod-portal-client/build.gradle.kts @@ -0,0 +1,37 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + dev.adamko.kafkatorio.lang.`kotlin-jvm` + kotlin("plugin.serialization") + application +} + + +dependencies { + + implementation(projects.modules.eventsServer) + + implementation(platform(libs.kotlinx.serialization.bom)) + implementation(libs.kotlinx.serialization.core) + implementation(libs.kotlinx.serialization.json) + + implementation(libs.kotlinx.coroutines) + + implementation(platform(libs.http4k.bom)) + implementation(libs.bundles.http4k) + implementation(libs.http4k.format.kotlinx) + + implementation(libs.skrapeit) +} + +// +//application { +// mainClass.set("dev.adamko.kafkatorio.processor.EventProcessorKt") +//} + +tasks.withType { + kotlinOptions.freeCompilerArgs += listOf( + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlinx.coroutines.FlowPreview", + ) +} diff --git a/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/ApplicationProperties.kt b/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/ApplicationProperties.kt new file mode 100644 index 0000000..be38903 --- /dev/null +++ b/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/ApplicationProperties.kt @@ -0,0 +1,48 @@ +package dev.adamko.kafkatorio + +import dev.adamko.kafkatorio.processor.config.env +import dev.adamko.kafkatorio.processor.config.fromEnvVarPath +import dev.adamko.kafkatorio.processor.config.fromResourcesFile +import java.time.Clock +import org.http4k.cloudnative.env.Environment +import org.http4k.cloudnative.env.EnvironmentKey +import org.http4k.cloudnative.env.Secret +import org.http4k.lens.nonEmptyString +import org.http4k.lens.secret + + +/** + * Load properties, in descending priority order, from + * + * 1. Environment variables + * 2. This app's env file (as defined by the environment variable [Lenses.APPLICATION_PROPERTIES_FILE_PATH]) + * # 3. A resources-dir yaml file + * + */ +internal class ApplicationProperties( + vararg environments: Environment = arrayOf( + Environment.env(), + Environment.fromEnvVarPath(), + Environment.fromResourcesFile(".secret.config.yml") + ) +) { + + private val appProps: Environment = + environments.reduce { acc, environment -> acc.overrides(environment) } + + + fun clock(): Clock = Clock.systemUTC() + + + val factorioModPortalUsername: String + get() = EnvironmentKey + .nonEmptyString() + .required("factorio-mod-portal.username")[appProps] + + + val factorioModPortalPassword: Secret + get() = EnvironmentKey + .secret() + .required("factorio-mod-portal.password")[appProps] + +} diff --git a/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalClient.kt b/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalClient.kt new file mode 100644 index 0000000..55fb5e2 --- /dev/null +++ b/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalClient.kt @@ -0,0 +1,107 @@ +package dev.adamko.kafkatorio + +import dev.adamko.kafkatorio.processor.serdes.KXS.asPrettyJsonString +import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import it.skrape.core.htmlDocument +import it.skrape.selects.html5.input +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.jsonObject +import org.http4k.client.OkHttp +import org.http4k.core.HttpHandler +import org.http4k.core.Method +import org.http4k.core.Request +import org.http4k.core.Response +import org.http4k.core.body.form +import org.http4k.core.cookie.Cookie +import org.http4k.core.cookie.cookie +import org.http4k.core.cookie.cookies +import org.http4k.core.then +import org.http4k.filter.ClientFilters + + +/** + * * https://github.com/shanemadden/factorio-mod-portal-publish/blob/master/entrypoint.sh + * * https://github.com/nicolas-lang/factorio-create-release-action/blob/master/entrypoint.py + * * https://github.com/nicolas-lang/factorio-create-release-action/blob/master/factorioModPortal.py + * * https://github.com/justarandomgeek/vscode-factoriomod-debug/blob/master/src/ModPackageProvider.ts#L530 + * + * + */ +internal class FactorioModPortalClient( + private val appProps: ApplicationProperties = ApplicationProperties(), + private val loginFormUrl: String = "https://factorio.com/login?mods=1", + private val loginUrl: String = "https://factorio.com/login", +) { + + private val client: HttpHandler = + ClientFilters.FollowRedirects() + .then(OkHttp()) + + private val csrfCookie: Cookie by lazy { fetchCsrfToken() } + private val sessionCookie: Cookie by lazy { login() } + + + private fun fetchCsrfToken(): Cookie { + + val request = Request(Method.GET, loginFormUrl) + val response: Response = client(request) + + val csrfToken = htmlDocument(response.bodyString()) { + input { + withId = csrfTokenName + withAttribute = "name" to csrfTokenName + findFirst { attribute("value") } + } + } + + println("csrfToken: $csrfToken") + return Cookie(csrfTokenName, csrfToken) + } + + + private fun login(): Cookie { + + val loginRequest = Request(Method.POST, loginUrl) + .header("Referer", loginFormUrl) +// .cookie(csrfCookie) + .form("csrf_token", csrfCookie.value) + .form("username_or_email", appProps.factorioModPortalUsername) + .form("password", appProps.factorioModPortalPassword.use { it }) + .form("next_url", "/profile") + + val loginResponse = client(loginRequest) + + println(loginResponse.bodyString()) + + val sessionCookie = loginResponse.cookies() + .first { it.name == "session" && it.domain == ".factorio.com" } + + println("sessionCookie: $sessionCookie") + + return sessionCookie + } + + fun getModInfo(modName: String): JsonObject { + val response = client( + Request(Method.GET, "https://mods.factorio.com/api/mods/${modName}/full") + .cookie(csrfCookie) + .cookie(sessionCookie) + ) + return jsonMapper.parseToJsonElement(response.bodyString()).jsonObject + } + + fun fetchModUploadToken(modName: String): String { + val response = client( + Request(Method.GET, "https://mods.factorio.com/mod/${modName}/edit") + .cookie(csrfCookie) + .cookie(sessionCookie) + ) + + return response.bodyString() + } + + companion object { + private const val csrfTokenName = "csrf_token" + } + +} diff --git a/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/modUploader.kt b/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/modUploader.kt new file mode 100644 index 0000000..0bb1279 --- /dev/null +++ b/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/modUploader.kt @@ -0,0 +1,14 @@ +package dev.adamko.kafkatorio + +import dev.adamko.kafkatorio.processor.serdes.KXS.asPrettyJsonString + + +private const val modName = "kafkatorio-events" + + +fun main() { + val client = FactorioModPortalClient() +// val modInfo = client.getModInfo(modName) +// println(modInfo.asPrettyJsonString()) + println(client.fetchModUploadToken(modName)) +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 8d3ab2b..174121e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -14,6 +14,8 @@ include( ":modules:kt-rcon", ":modules:web-map", + + ":modules:factorio-mod-portal-client", ) enableFeaturePreview("VERSION_CATALOGS") From d634ecc9090d19b54f211fd647f60097ae30935b Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 13 Feb 2022 10:44:13 +0100 Subject: [PATCH 195/629] release mod to portal (create logo, fix thumbnail, add desc) --- modules/events-mod/build.gradle.kts | 5 +- .../src/main/resources/kafkatorio-logo.png | Bin 0 -> 141155 bytes .../src/main/resources/kafkatorio-logo.svg | 7401 +++++++++++++++++ .../src/main/resources/mod-data/thumbnail.png | Bin 702 -> 77215 bytes .../main/resources/mod-portal-description.md | 8 + modules/events-schema/build.gradle.kts | 31 +- 6 files changed, 7435 insertions(+), 10 deletions(-) create mode 100644 modules/events-mod/src/main/resources/kafkatorio-logo.png create mode 100644 modules/events-mod/src/main/resources/kafkatorio-logo.svg create mode 100644 modules/events-mod/src/main/resources/mod-portal-description.md diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index c44ed62..8c942d5 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -9,7 +9,6 @@ import org.apache.tools.ant.filters.ReplaceTokens import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { - idea dev.adamko.kafkatorio.lang.node distribution } @@ -135,7 +134,9 @@ distributions { } from(licenseFile) from(typescriptToLua.map { it.outputs }) - filter("tokens" to projectTokens) + filesNotMatching("**/*.png") { + filter("tokens" to projectTokens) + } includeEmptyDirs = false exclude { // exclude empty files diff --git a/modules/events-mod/src/main/resources/kafkatorio-logo.png b/modules/events-mod/src/main/resources/kafkatorio-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ac2ffd29afabc520042c1137a098ea982b7d34d6 GIT binary patch literal 141155 zcmY)V2RNI5{56i>iM>aS8bw<*Yt*P&bZ9A!)~uaUo7k}ls;ycrwQ9DiD6xqxYSpf) z8M9{X9YpxuKHum2|3A;UE+R;-JMZ;6=e*7x`4skuj+&Di0025ojR(2_0NKCzVk8HD zllG9L3w$8;yr-#82_lg4R(o`r!`` ze~54SI&@u%t1Fzp^;}A`{$_oCyuFDCJF&%UT%7fvNUhlo<6R1cB!eUy-K1XrDE0A2 zw>0*rc9{KMv~Kim_QLu}XvsP3Wo8*dnjC>}@;WY}B7FM1hl`eTYO4{pg^v@5Tamce zmt|zMAGT1GH3o9vJeNyj9+n*t$`1U?4tzOH1+-HnU;KDQbqV}|TeZNjOf0!fEU{FK ztxSxi)ZDc7u!GJy% zzx4LMi~m2b?!5ojiFkOsT1#u}Ebsi)hFo)`n0u|=55PS6eafaKLDo5B(Wo>d#h%pT z|NiKbFMbR09|i?o!KKNS5l7ECO_>S(uOR+fRHUWE-^r!KUc1taR0mSz|NEjZIvPcU zzt^hIPqVBEt-Mldsw2$w)&!k%;c9+AT;!!OYG}RR|2-%_+GydH79EE(r(Dj>2V%}n zvg9jwgq7nqT#0PeAzNFrPz7P1j{ljC{~eE_4_=(O2r}pMIn}nqJ~@tT{43>M%4+Z_ zTx<1Rh4bqFHHDHdtX!`yPFsXrG1ZkV#Fw|@g|Z*zjGeXc!U-SZ;7am8#S#C{M{xhb zXyo&kT8Fl@`J50lBdvyseE$`}Z~MaklX=_!^TxlU;(J~YHtWZNSM|o2qw4owc^*<- zy|vh;dp2;!QJs^sZe{a-7SexLo?yYIYvbfm&h#rXA}Dy;;krjYS&$>OY5efk8KKO^ zc=Z37@CDzVX`bqk9rm$!e$V(eVCv~HE`$p=L!5f})b5MnBm#q*hs?^y?j3JS50KQD zi6`S?T=wi@6I3ycDP}cS4x&bEHn*ZzN;vlJIW>r<-MKMw(D}}-PwW|Ei`qR;wf~??g~QBr93C&1Rk?a7yt#R+=}6rdQ2F9{^W%^cA=&+p7r&yqHf z-DUjog5xLn5Z2NWA>;xdq0W}MJ5CR`I9HNh$~6i-l@G7E0!$Y3IoUL?uY4Fxd+&0k zc;d=7dc_j`@H|@5O^$u6k92vSblrbBV#)pI;jm+sNdaG}ozx>!&3Jw*BbBCmR(~{m z70XJc)r_9MBhK+!5wx0LxmeD)*XsLbE|WljlF_x8hl|zI2a}Z8k&36XB&Qtjx%L9C zFL!BYV}9&mof+l0j?-DbxN(P02;V`5iHCE0K_ zge#wq$Xk3^kJ6J_TXf^I(W3d^+6hbW25mQqZI)<30STRl5*=k`Y?XQq!pHkw1WoLDBvk^>eV6R~&j&1kz=ZAc* z?4pPWntEftRZ=Yl5)c37gwUEswTiU)K>$HMq3zGQoRiG`$U*ue60m8DX$VMzD7cl!Jgf? z{sWPeJ1JbY&`7ypXws2E{uc(gU2mx$4NVhfNr$AsIFp&O9lxnhYR)1eax)qFbCEZPv{Gp8u=u*6N%uzjWDKNMf$;AJBZeAloGL3odxYM=u-@uG%G1YO9;*8IQ?mrv7(Z};hnBtDKLH5rqWTikW+54H|GCyd1_u6EEo;<76vwlI|52^fjY zYh8>NTloA`NJch7d_#H0AL2kEDVXF@h)w6lunMKxw2Ug9A!75`vRChL)ESUoJ|-A0 z$BgX6OzIF15c->g{Z8LNK|BAs_Yz| zQi-!zHpG{t?Wq&)l=xh+Nj}i8KgcyE=2XFc*JXaK4G~iwLJ&@N2g_2-rqL#7!wjQ0 z8PRTTjHX{4kGgbdRhg$kPj`5&3F8B|q4mUwwvTUG=eGA{EZ{ACjWlDFY8#2=_O`~| zsS%S+-jjVPI-Er5UH>wz^9+x`>x8W~|5X^9w3RoSE6p?3^-)j#VAn~yy~EZG8l{S& zp|#{G>*2KA=Qr8#hrd{Zty>EQ0(6r$BG^lb;{(q0EBqs;s%MX!t#9RN%W7^uytycz z+|%y96jqyHHWsI+U8~pKdcXsk`p4R-AG%5dl zy}M%o-lTPKjTxvR$N)}*>YiBR>6jYvb@DdkePeJVT^>`qG`j(8Haa@kVPSTeDK=BV z*)Xdi=~Qi7ccz4%#XXo`fPUdvFabAqwkv_7{dN9VqV&eM;DD%}h@{;vO@-TElCcfR zHy0aM>JW($lk~tkX^*@ZqbdTJcG1qiGQ*{vPLbY7zmM$gpVpd1uxr&DU=c{9udT7q zx3C|SPfNf9+L85ckOP(2`oBuOY3hK0|4Mk%X?Z*9?2q19@I2QTvsT>|cB2}7+K79f z|NR>|=stkH*R$?P%}s|WpwE#eQG7;$Oo)zA7$wv5?T1dz*>h=xIKx8hKRDo zRfFZ{w{XvQJ!~38mL!OL_YmqU+A@VmI-Dn8N5+}^)Y(k+8_yn?y{Y1?Ybq&%-#!W_ z$!kcR_M^bP;q5St*CzL3&Um8evGXOPC4C+^0kO1Hq2Mzu(7a3~F|9~1OX;PtW-yztj$?cM@d%Q>*eymP@=%tte%Y)GW z2Oz%drBv!i)r9J&;CV@QF+sCRbPF3#E&6ETIkl?f>nFi>uYbHY9*GIseEvZnTuX~1 zql*h3hivg#XPA)sGFiG`=fllE4z(<=^=K=F)#9comp;D_YDu?sK6dYG+GH8^E{v}m zC;Pd9;Mn>W0`6WGYDje41xTV}FJPr~TY#j7gXYHxp)dcrR(TdkW_lKZ+j19x-2M*> z1LMxO)B1RHW;d&L4#T4AhB{oxu)IcYm?)*^;BI&1F22U^OWH@gd(kV(R z8;`dp9OB0Md&j)*KIs0+G1uL1)f2PD@Fc2q%6v3~dZF>+qAc5X??_*OL{jMjG?MZl zWd7U%(&%PQ;&7U8Zv=Z^fEDh30VcTJ1>S^8Crm#heLlEl0X?!H!(U9SPlPHW>A)h= zpk!F`VUQn3HuzcegzKA`G$`c@JRZ{h3faP!692N7dDm~;X8o#dQorD87_Q*?Le90} zVJz1Sq^fOb&FI>JehaLB8t}_pZnSW|li4v424LN}1u2&x&H@SG6iby#+`Pcg;{8st(hcSz zS2KDi@+0JGRx02cL8C~5v<}&NX#{Q(Ib;Kp`~X}d7G`bUPx0-2_FWU4)p5#UVg*@< z%h?pru_l6ewV=*~3-zCmT5AT9c1a%I^LA=5_MZWRQZTdM5@t1Sb3e!`qX+t~{*2e= zoH(q8Mb=gyAQa1RfU-QPF#U!^OAFU~YrYz%w=$(BeWP;A*8 zOg!;MnPL!Ab>4+#+T0|LImD#LhWLl#kJJ=_O)Gbg}S^KpAm z4zkXrtIt<>y{T53kJHBD$My_i(M#Z24-a0|w;q?tv$4)2d)2E8W0%jEtwT`o$#ok{ zX|w}fpUzqsg15tYPx+uHk(XBQrfYz!=KWW@HZlSl^NZ|G>c@~}kHp6y1C?1tvQq;) zHGCf*13f*LZyAW=52}=cOTr01K@{jo)x;Dz<3! zKUg(TNNVtFQVgB!2hkV+?17MIrY*&QXoxO0h$o%hOMKkLkNxv;Ah`$9+j|svtc=A1 z;FI0_pSNa$@Uz%?$aAxgUq3LR9=9(?J@97=i|@+4fqKNl!OfzMs;cr(V1bT}F}Ay1 z2C!>%5es{BAn%@=^^9tSr(eZv!PJvj{Zxu_(}KuPo2$y!M>eQDzbTsFr7rouud zS$ItnR299O;zVnt;c|A<{$gF}=4P{TdPV+%PX&n@c|-q>{q~D0bet87DIvkc(K6z^ z>Imfu|7tvNGL|xYpPBS7<(sl%11@~g%`vBDV-eOTyCVks(5?-Tg z={of|mlVRsc|cI0pY2o?PlRPa-D)LqbwlkN;>i`psM=Z+7jM?tPztMC&puj~zs&SO zcH3kz%o6c?$8MM5cAbmwIw6w?Qjfcgq|Lmc#8rb@R?@rM$A2U)zg5ow0&;Z=#v~rb zXi5kHpnesED$_Br*8}y>h_|@L0>)W0Yq7i%Pm}pIMc5$V23aNIHx4cQ{@rlS3e>%x zeSWqDdLn0$S6<&W(;LWCAJu5i3RQ@4ALPlhkld0T^#=8D#5Jt2+U7-BXTavfshq6j z#6i8cEhKS`ZjO{ES->aRaHqoO+fW@uBGJ{BX(1KATCys<9q2TPEY4JkcI|$^QPUZ zirVea+0wG$>#3B0UBUArLj@T5p_0!7cQ;1t;;t_gQhRf99YmrikO#|9JQ%a?HeN`J z_~;#QyqIhmd~D-%a}DGXJ|r^842B#}$Qa!uI@V_E+xe8xz4cA%t+tedd6q(i_aWYd z?*8oU+mbTwKBMBUfNpS%Z~oT$dsjsk%9E*?cEbXAs^7itZ+?vyt}@^0%+OHJ>v1#G zy_ZwCaJ-F49-oNUiTRk1T(?wmf-PrMO*)M#vMx^DxfdvQ3*Wg2c8jO|b<^waYF6zt zzVk71O+=So`m^6!z;U3sk1wU9vRQ$%3q+ad6>>hp25zdEtN{|ru%3vr#h4_IT9iwpOt$Aax@k#o6gW&&A`8hhW#bb5&g(wcA;s(8oULf=7It zJ3vChqZ1H8es+Tr;e#fZl=^$X76s(#1T+?~s8zkQSw#Bu*xUs)1oR5}o`8F@s%mX? zhsa0?N5mst#h7;`|06zcl6>!CUk00+(mDoc#!jcLn$+)?4DUVY^E6u9v5$L%Q{kKm zm})q;Z)WHVmOv_%^zCU9YW$ZYk>{%zjANryTivvy&hx4@zfa2Fk|;Eb%fW@HC||0T zgl|%D_Ec~VIi06R1s{l1TOL7MtPATlk@ZtN3`sg^8FxewXdbd%7!M`)8|n{pFG?`_(3Fe=UwQ`c zHG9V5| z!?@;TY?Bd?c_<$Aw1 znjwB;ipTZSS+MhYPsl%DrTM^gOl9ZQusH*$7cL1t-FsFdAj#F+SN8(_R!mNB2i`{K z^!0V(Qq2M2Cr1-&0og_V*i#M};%&_O<%=ufNd}-1-_tXG zbHKW{wug+7p5|WFyQFy!4tTIi1{*1$=@@u6{zQWk>p7r)jf)EiMd8FW0WB^0rVmWb zmhlV6y6*;EJMQK>-D8~GbYxA~wy6LR7@?&-KuIYcr0p!!?N$QeHk;FakD5xr3h~lI z_t>8X{K!u=s*4i%Jwd-IxerNxwF*7dmhUbKNn)Z7ou}TN0+hwt3&si3zkh=&Je_{M zGS1Gfr;aC_n=U-@(qyyK?K^`%FlM|uQeOuJ%+1S~@d8Es29ORd&Lgc6G;82C4 z($Q0ts9}%mgMga?e6#lHR~uj^^8+Ak{E3k88orGh29)z;$b0!WfMN zd{+)?f_~MeEC!O_hBHNMnrqYX5~ew(_{nkL@_g+Scc(jmpW&qyNC3wnH5w-t{>_l) zHtYm(ZXIBpOZ&kUhCXrGPsLans+_q_3OYUe;Uu50+fqV*uPe_+%cTix1@A` zDqA+L?tuJB8+H;H5vI(r)s&{~uM7+d)m2-IC?BX5S56`_@$K#U-wjE|W=aeRCxAS? z`A8(xHUxwpN5Uz(_)B{r0v2oRnrZNb@>;gVg@YAFyRN;S$M}opsF8lx(0Ce6>Z4>b zkwLz0So^~Vswh3`U;-p9`PXu(qcYt&Q+s;s)n5%}Z|=?2{W`%b3bOd?rL}+I1NQOr__nIx5Y?;_ zLx>ayChft^@w?;{w;rCCbzb}6Z&Vg&5&z4^l5rA&(rBB%IzR7+LZk1sY>-ou4=!H8 z{H9-ziuxzh2{|J2Fmyt|;&QKk!T&f=CF}8v-jf(E-yk|V2r1};6|TLTEJ^qeQZB|h|!S(6j+PACT6D{c=`YnPQscxTrOwEw(duoi?JLh+#$S#RfLH{&2hy7QAwGt5%UD zAA71eJGeNGnHH-K7=PX>x@6Q*IbIpD3Byn4OeADn| zx3PgvI`;T#Jj_Uh`%UpFLT)4~nIARxqTGCM_!U8u|D8I9t7oWo3czo&M&(-=`W!H+ z_ZOBlovdb^31d^G?fR9E`LX|o@^lg~@WMOh7kaThDn-A4{zFgIpwOj7na_0PGRsD5 zo`XNvhaUD-JnP($xpdHV%k)lM-ztWQ;1sOtlVDJPkkFknBRAj^q#C1GJng4vTCMG> ziaUtg|B`mRVjGZ5J$Ds>>6Fl4mqqCtA3nk9s52~iUf`pPZ){v?#Xz{)<-+)UBLo4%0?h5 zJg)tZ=c0Umx;LPD-e7hc&G9qR*~P`>L*2;CslZ5mk$!Xl&lT>s*Xq>fm-m*L8bXd* z(PAa+vxARr86Eu_vT!B3#|hkBlkqtk9j_n~<4H>!(qZ*xz|fGr1OusAu_Np3?&4FS z4?s$q^k^(>DV@IpH{HK{>mOIgr-ZGUAh{2Wq$moWw-0+3b7rScnK#z%^QngLbeiA% z@?-XJqxJq>;OzqqZ54l>x7RkWCbvpC>*=Xv2|*inA1lU)(8OPRiW^&6US1A4wT_n6 z5rBwWHU%DA^CsM9`n0%zF+EvHp1h|Ef~v<|I>AtF=X@X=((5RuWgFJOS^5plS9-n1 ziEO}DtyH=cLn6?~SG4SNK)eP0V=p9Wf2c*5zed)LT+RVoT`_v1`COmh+FS7cCijl( zoTqv-cwd|)UTk$lLpgRM^3oIW>JLE2rRfzo6>Ff`X1nFR7HYjEoPjX=2UeO)6L8 zGOW5cK>6pB?0v(i7PLO2+9f+qt$CHGm-;#_jg5_KgU!X`9+p>diACJ2H7funLqg;O zeT4?rTJF|H7q7MO+4{IWOTP1e&jC zZMM6Yw|_Mx*(Uh$0DNicouwLWYiL6V6q4D=o*iH4UjZdC&FqYzk8EG|<37$%y4>1~ zF%oj)1{XGw_=OS`xeQDPRy@7T)jA1LE;$bb)zJQ?c*pmW5)x2mMuWees?2gB*QkHRQs~H;5<1+z$u61`!(;<TJe#Wb*=joE#42qy?Dd}? ztL~de-RN5U>xZIY4{UmHk6Z)#4Iy`})Qr7R_Pvit^9b$lP{2^t(&Ta8v(UM{&sN#` zKLllhRX*Kms;`#*Gi%v??fdzt!O|F`C{XClXefRhujv6|_`%3KJG?}@n>HzmPjJBQ4)i^=cY3CN@vo4&y9rF1VE zkDJJ;CN)?p`a6tAb!KCJYqZu1$9Cwi|6cFtMS(4=r85cE#I zBBt9)!r~?a?8oPaw@v!*@O+_cId?@Q^~m%Lfa3Gdl0e7z^SJY?oy7@jCC7>l;1L=@ z!~T-pS71q)aeeySg2Y!EJ4O3T)=Je7T0h>k)caV<&Zoz}q+|%K`(O<6XU*@AVru$n zt@P|-&sc|*tq-Vlud>9;vKyjmhYxx(-tVK?#THFM&9-Pp-_DHR_-8KnuEc*fXere$ z^LXV^naO>juMNb%Ah=xN(c3)|ruckqeo4)VvCC>@LIWI{%*!5C7;e$Ns^8}7Dj&*U zuC1liebv1igiwr0^7^|A3vO|LThn&K;-BvW(VLn_$^2Js;|JQTW@h5fX#1FgB1w6C zJeU*fcEbS7AKuR+it)W`?M$-Y1fXM+Hxu_eGMzqX3nYx=THn7@B}k(f0%u8hkLp8= z#D_+1GN_(zw=$?kH}||;DB6Od!>4Z|wIlPqZTom2F_(8>v%{;(gYVS0kj;;`8Vw1u z*S|I5o*yomk=kCFp((T7rVYgpn-HI9&FNl?`9Zi+I}~n;Wm=QOys@_1>1;?YSX6#r_o|_!ml^LYY-E| z@Azy=r-SfQK9+%lC+(`jB_qz7$ogCKb>n{v!QObYphVnDW{7;UQ!kkg$`1}e6qy~+ zBl-bJA1w@rMS}H2K8pr?Mv46!SQ7a5G&Mt=CS*D9!QKZ&u{YZRzvJv#tZ`i>515u! zGCImVr`j@{KD2^Bi=qDWv|NKP&0g4;D#U*|w^sRUClhp3ju#SipbbZVqa>P+u65K{ z{|c+fo$|y|0y6g@aJg(bnpuZXCG`3(I+JB1K5S4|XrH;XFjbY)cvJ~3T8TKD(vD^ROMsm8d$ZB2P-iOv^(%{75(@)l; z6T}uDg8l90%Q5=;f6fsvFF-1`JX$R5q^MV*?`TIcn`mU=x2SXW%EAyS%dlWV2e0+d z^}72lK*{;M^CZ!z=}x(KaS@<=_?$ofahEY}aeb9Cg`ZrR<;OE7 zBRA;kKbfQ}X<3i>c)41CbL8ZVy>6wfevB$gH;ZYIpCCbElJ@(Jr%b~GrE3`Iuhk^% zG~g|yj7#3~vH9ob#R+|x0^evuPHu2$wm0?c3{;hHkYtcOw-9FwzY8Q6)=N40M|`wd z1Hr}lW0D$u52K;b0t&Ckxs|mIyva9L4N;9I*>ZY=a38n4VOMFf4I~NjdUu_%L3QF` zLkfpgf$eFdeqv;(KcU=d&^7C!y&M-@#9m-~Fm#t#^Y_CZbQP+%#N zkS({Tu8s4YjTFrE{TnF=fNK6Nf2h*|0W%X!*w_kY7yCdU7~Y)eSu~@c&Echcvo+P~ zznrQqy6v(apd34^xf(K4587#f+dMf`2y)z$Jip`5xUq0D-BpghO{1&;%Nxm`7q%;N z-Iu934^C%b{w1RtH~dgDUQywgr-?l0S)km96#NG!eYf}gzIiY*C}?VTs`5nM6oYIx z2w5rK*~>K~sd1n0h-p66(iXputsgcsuk~2$9xlwU(fw`#XCHMiwC%Ita~<)+(9{f- zS1PfN_38SiG{z1>S36tCrp2=n1}nuGYK^QVpRTH6vO{*FUXE*?FTT;L06R^eJ~^7* zl#<*MlQbeg*VVOZGt5S-KB}%&XI1^Tfe74hhKfOsuWCeAzvu$*|&Ys!-7TDV;(_n<4Wx$><0XsBP| z%`KBrKihDEI|Nx_Jz9T2`c;+}=^dI!w%Yhp6$Uu~!wU)gD34mRhkDTpyL&cSe&aYz zV_DI=)uULmzVObjvPD?s$03#2B=%Yk8VZmk#8J$Cc*NtkF!(4As^Bp6&&%JAV(ruU zuw`m<{-G~puj)>uZ=f|vc1hg)gEDFPgn?9A=t2j%iI--%jMddm(*4zDLHM*V`PB2D z|2{gy3fr59kPE(~*f+1Awv^RJy<=deR>L+71-`z=ZBzi9{+6Jlb3s7&4lxkwHW0&IQDl9pP3yD>$-+KB%wB{0jNx2JO1PCq#j4EY&8Xzh;B2uwSh) z;3=j%4563}x^7MoFY=`+%eR#sIe7A%!MJ&ZFlJYM!vmtc|LZ=(oqa|%z6*vYg_23W z45va*xFH#)2M&|u;9Gyo2+|)?NNc+y}+KV$9w&n&{f!bN&e{9 z5*7O0+j(FWG_h28o3aL9!bP$Ry`{D+G=da3vF+H&X*gmb>IXGD5-q`3Z=)c~{1Z$w z8nKK2*PFPW5M(y>3K=o1nH9zLc;YfO44qd zUS@daAIFtjyCLVU*6|#=?b(K{?@Qo}vwsTo@?e=?^L%gB$ugrh=)qp$5lno)k$h7I zHTstL9I|e*JW#B;)LU6Jq)Ym1;hhCdVwH4$;Z!WDt_y|8^y1`u(q|+QUdu5)b}%9) z$Jy&pU#iru3nN4n+L{>^o7L`ax8@rcNn|~Imwyoj{0wYQ2Y}rYxe#jsmPo5I%I!(d z!IdQeHOUoZA;j}qn-$pkmjqDblLx@J;AEdFn<37-CQdi&cDFvVked(+@q`iT&;-Gq z!1pIB9v-!a1pKj?xaN;?KU32b?fzaz$Qux8X#f|9(GpQtpPj$$QS1`Xix$oa{g`Pl zX-Iu|qXF@=jUPrY2`QU|lqOi;D8+|~HW;s|Umtlg)f;yuq5Ia;QPo&$$O_t{V+iof z`=}*NAph*0^Xm`GVOZ|uclN>$G;F`4E{F%%=7_ui701uC5TA>7^31u4!069q$my9g zGUy5)OZQ93HRR{_8i2mYm$!*O>JuCd;`ym&TY2fZGeh zp@X+?3y_;P-!Qc-oc3;#t?{Ye_9>jj4(RD!wkoYi7?}4nqF8N zahb*F2#Lp}u8D|R4{uPe8oIx|ba%>G&9(b)>}CjgYRJMd`7ASrJ0rG5%ePPPC+ zuwJdl4Hr9PEX^0>W%{p9$fDfjxr=o&@2btu&d$QEN&Z)Q0htnsy27aCEWukXD~>9% ziwB^E9jDApzqJ90j;=8)U_s4T7A|@K!;ZCPA}>6u9a*uU!i{_67c6eMbezZvYTbLE zoe%As<3@H6qp?qPRp! z86kNux;O53aQNNW1b*OdzG0L)>cCs`-GgX4v?E&WyP+tnvpN&p&CP9lp)1FeI}#M% zl!i(*J`A3>HRA68zp1Dp(x~YIU`yX^)DyIOk%i@LxM9}m^%U=%QDc~v$nr-p9tQP} z?`s5UK`&+E{F5P483&%rDYz~2Z13wU5YLJZJFri##q=4k4AMfc3+N-L-plozo}Mb( zmJ}P_paR7bWdzcv?DRRR}-!%l~jF&;pEupmAp_#Gt~N zs#VLp86QvOs@PXf;z91gf> zTZ3)Y@bLJ`3KGfNOFJyok1+US-zLNRlI-dz9EO2`43ho)BY&)tqh@S-sl{;+KH^>~ zEmj)T!T|w5)=}Gvy%bex+1>IW(c1KRJE(^stg^qOn7#Mly!pWImnAtGciAhbYql<~ zYis}fkRbS(N>ntXyh$#&2`P4A2g?_mby!v>T?B>KC6LU)n zkd$Ev(|1r#qsp1beyAvR2pc;@Whe6U=M5L&u23R9{Y$Nr-yobygn76AJGe9A&1X_8 z^_m=<>LGrzY<@~@Uxp@1uH4)Jhna>ADQz}~t}ZfNgt|T~sxu+GDrWJI6;bx%3j)dJ zGh}fLre_SA!7%T1JsdH*YmWpx>mjuhGi2dl1c*{n_5wG~n|c12i~kSHI<|=>E71qU zE$Jh4g=Mi3A?7ubl6>!glBT+PQA(gJWo8RWLJEB=c>lgi7XOReNH4$687AMWNqX@M zXb!B8&n?^3mt;m<(m`Hxzj#=bTuSzdgPz$7oQPi8FO^xgLBV_HX=3x`-;A52Ch$)) za?@94Y?Lw;qZAdkzA8_z2-(iL$};P-yr{aip>=V$hnDwrQ645Uy30nAcZ6wuOU-ymlA0Jb1hj_zvH zvs3=W(S-5&DnFM9vL%PVxIhcXtaeYBv&^sGmmlTj1&V5kqmQLq|4y61DuUDf2@bDw zGrmPkQT7BX(Y(OyeH;Cuy(j+|XZpgp#B$lGtjNbYRIc^Qv~m+H$y?C)kAtg`C3#gI zFtvfKS7PB)>y6&~WX1xSk;V^JQ@M}^b)CpPfZ)PaHd9&j2isAQJaI`vo z1b8Q`;fNaLi6a=CD1fTW?*RRlS%Kj~uWJV2mU+49!tGgK-`QIuU9ZT zAK#XANz&Bx{`;WSf+foN5ur(rwtsE;a_2A>_ohfKm1hqgT%*hs)H%dsR52ULwT~r) zp{tP(%0TtyhWhYlem?(bn~;{ZwA7Z#8-&J$Oq~R-n3jQM%ZuaJj!)YU75TSFCn=F! zKg~Q*R&a@W3T7<%p<3_jtKK;~`t`In`dxen*}b(hi#irs9&VuF#4-0CK(tf6uXUUg zXH{g{DDt`a0=#^nd7bkN1%^ju>ND&0LT7H4$}#6BX5t*JW;e(;9j$PEm6b|#V+S3@ zV8**x?zQR0QA{+GT{g(YuM8Z@WJ^n`^1u=7?1%GkVL9Eap=!5PRBl0LK>;6pKDc#5 zGyVb7n$k>N#I5QA7VNg0kiJNPj;(+xqIJ%Hd-J6hg4`^QLaeExg0h%`f-+^f|AqUb zMl9M}Dfi5~yp)}K~1yLT1K+KLdkOxR+v(ZMsW}khi-`axH12%T|k)QWN5cI6Hp+MNyAirA-QT|i!6PI%N+!@R?Lz#w- zj&-zL7oFOPPGwg{e3N&kVB>NQaZ8yeeW3MzgSZq&CF&A9E49T>kUF!%j)I(@3T`WK z`DXIsuCvFTLp3!Pu+R+sdq`HPH~_k6#54WJXTwV%`qH}bxV8(tN?)9!&DI|pQKhJ= z-YC`)Rh#Zw9Nyebif<22^s=wHBU)I*t{dEPu^1#IGjZ6$+e&pFBgm>>gTgd{gqaWTNq(Q}Q{Q3JkW$H628Zx&?i#|2r9?Wu zkdL$dDTKMAq#^6@GouQxt?bkKpZqgfiV^rI{z$8WSH){RJwU|0&+lP9NkYGwC3(3o z@GA2?qGiUp6hpm`0o|0rFZ09YR%@pAhkhP7%kACe;;#}C@u&LJ_i4sL^PLNSe%j}I zx2xQ=<4M5WGs`p`fI#=;QSgZ9NyKawE-pFtJ}RC#qgoSK%&p zV8Q?DJ1XztskrVVU%saWKa=*y$D5k`wd!@7{iYYc8$ztgOg3f#zQpgt4<7;-yACl! zE`Je$Ei^K{;u;tT=7XMBW9FVmjo`yAj2v@Dm5@JwPm7OaAaB+g6z>?;w)v!yHKxrJ zqzZnzwTAQx&0{TuDG};TjNDD;J-)Bi4;~ElG2)C2ZQux%6eY2LrX|n29UM;gopsC{ zx=4!rct%D?M_s4ld0$#v^XN48=?goUcuG){Mei)iM=$=X3=-@Scdt?j0!@B7ib}Km z#9%P#sk!#n$yZS8;F)B{o*Ut?1=0x##Mg6im0iZJe&;uDe3xVp_NR~X`Ha;oSun!a zVb+Z2aW74}f-W>DvOHf(0|r!8Z?lt0wBU~;LJrj#p40+EP0mPAZdfj4bcD@lFqfrY|K{jzu*oxu#f{D)3!cyOZuzBEYLC4T&Ad^gp#rLe2qqceK!8Or7VK67M;SQ!L-7K3+fFICwGxVh>w@?Lo6$9+?e~kFW&FZwfwUQ1dYb*m`f}N;%n@ENnctc%ownI&~XJ2(qzj$$s?W=8z1--?EL^ ze1oekYEvnDFBf*!saKPrb%vudJE%EBk1@v<42Wb z$+m|}HrKVEKu%X4)z^bD;qBvrES1J4@zG>g@|Ox!SGtPh;7#RW#bvxV6ZxA(g6)aQ?YC zyb$E49137hl{+&O$x18r3)-w!6r;TduYa&&nw_j|Y62g?n|Aw;`_j6;@&V4S$&X{i zCpKDYjtS0e74BZj)fw-%5*~DN8~>;ICw3xAk!$w!^n? zvgFg(AX@eV&r+yexGY$pKCXrF`2h}JU=|_7m(GAaBzpx^_Rz& z*dNR=p%5bx)=QE9Y$WAQBH(Yny4og(R;;T3`bRc-6YRjSMRjFSeM`6v#+eKa6$jSl zK94F%LARUF@hvUAv{IN4LZ5bN=c1Wg~^$A{{Zp_OfXH<_(ODW}P8{W#AC#Qg% zO*NaE_@7-6eC9}GHmvDt*N%o%tu4hKqN2(vL)wEVBkI2|ep^r=tmQEoUmB}=G7Ugf zmrTvV(Sdegiq`B>pMLi|#CNZ+@eXKg&t~%sF#WcVPO4zhB?)2 z2C(UvB~3eaAgXLHO1@vDvCTvb zeluw0eodpUel-*4^5)%!OW&;H>r_u$4-V|I$ex?`z2xkPts-9^eCBn_(&WcNu>XsD zPCvtRYwI3-As&qUJNojrU~Y3tN!hC&vg@b$S6<I1_Juqs(RnfzP={uv2I@nVW9Ahg zlQHF$c1J0lj_~)gF&MUfP(-l=q#E|QGBePkSWP+#suvVQM#twwg; zn%xUXPvI4AeGz2_w;d~f-2(8SA`la)L2Bdfd#(}B2Q(a6Nhv5&Zx3ZX{yoX9hF;pK zjOy6(nmGU=E9zSmSdvC{iX`!`h`n(8Jc#lfV`z_vJXr~owW72|=z!YPbT(|SA*IFI zWad#UxtE~5GMIfQU}gQ44Lg&ZykB5)avP52`MJD2nJ@ijqmH=u|Iu`o0a3MG+nyP^ zk&*_HmXhvLK~PEQ6r_>v96*!?QA%1s8l-aw5s(~^k_PD*LQ49(=6>F9{qYw#?AiO; zE6(#+>=+tgsJV$bmpN{qnsl)SjC3D4plxS}>uVo+X!*k5?ZceR>+#|cCD&u322dt+uIMB7Kk|alewecgz7QB%`{t<;t)}br>_GWQ^A+}fQ z!Q-d%7j+`X89AOvj~ORx?16F>vXanG^|On;UqXLq$x6`?gR#}YH>6(tzr?pwM|95g zjHf`9yCJo8-1iYu{E3;6s5tm$9Taa2P43|79fX|PCx_X#ywY5l`PNMq_&+Ks!&0Wl0p@LJ&qYVp1APEF-La0JLdB%?w z@$4a;(3Tgl!c)_O%fkyvaod-Vk_K>hS!XXhAgAt5#2=aa4K6fAMOE3_nU>NQ=VsG0 zFdO}+);?!pyR`VWc_J=O6M=OIwI|o2KhgrVxZgR^$GlJBB36>E+gnXH8VovVndSx! zGgw)Z&50q+*FCR*^JEgkopD<N~8TiK6*NY12(Q?j2Ew7HLCAT2{Bw93wqYnod=|-Zo@KAs9vk)1X*^XxA zf2BJ}f)bt*62q>RaKgVAYeT+lo+OgKb7BRSH}c55EZ%$~kf8Kvd{`i-m3PMe$pl8% z5^7S=7M+R%`%32)gGoC!lbs3A3Yyk2BKXXmal4a6o`-eB&EzKR)T!Q;AvG5vR;=Pi zc3e{zOXF@C==mIW(#I|<;7PubeId_}mL3A{&u~86Ev!F;hyzdVAzU3)O!UyQo&DIx#8uqCk}m z0?8(M#B+M~(3f7t@TuFqglmxG;NXOXfvJZ$P!#qI%ecDgNs`EdzwvA(pk;n$8`q&- zFB9unDW-JHUGK%Unc>mX8a}`4MyUx2-B~%rwN?$2i0AZBN!LQjjbv=|j^B2bYH=BB;fm)@=EJ8O*->iabE4MLpWc?uTh3v}jAHqRtp$h$Yi z8IJ6j3I7NUa*^L(Kr2PHR1jF{5J{9x)UUJaYg9@7z~A+Be}7q~OhNrx6URD8qoMCs z!Th`i?ov%Q(R;eQAr%9eD;}it&XiRH^TO7pkj=>6i~i2Ow6RDVydZWJ7!J0;YUrd4 zi%Q~4K8#PGmn}-LbZAceeto007s#EZ8yQNdcXNweVgI~oQ$`_+Lx*J$?}D=ry5Qb5 z^9w;3g)4}4sKFn{TJ+)yOv1K>DPV^3$)`ROq0OV_Kjr7=T&W9Ex7U4?B6%%FGEGHe zfn3U+BgFT?lptEbe@SO%e!@Qv=F&a2`W~#*tBn9NfueF9;_I;vk%)Z4t}^tA0xv&1 z_M7FD=X#Hd!93sHrHF)BRC0 zTM+YYddEVDC_^`{tKV^725S>xDvD|hktk1PDHp2%YLh}H>zJDP)BLRJU*E&^4{TL9 z-@?c2o=@|fDw1xO7SZ9Yqj=9)qXTLPypATD=uc~a*n2p;;ckQj6n7;AtEPpC{*&s- z^hMG|O--11$xW+Qzf8_v^OCr9`}_AkjNrqQY80Ap>#DL5VrfP_xr?bFKhbk|rv)NI z1aBY%P>S?1v-=+rv{egVh_?NvdTS^9bSqObF}Hi0f-b6{$17Us&)YQ0k1zDGjmCiS z#g1YRG5>2V9Fr|?;4VF>T2_iS>`*DZlRD>Aldbfcaa=;0?PGyfp{!w5hbY;PmJbMo zVs22-r&BImr?5rM8NX~~X_r$C&nEb3YJ4~0;*^2#DA6pvn}xE;VFIQWD;u%xpgOJ2 zLag5>6+45NUU{8H`^_E1$(}P-7IsMvHIkQ77@o~50-*&M+iDpS2>O{mODZXgs34y75eFT6pFz1jF6Z zv;%aHGR?ldUPy-`B+~HT5Hx2pMxpYX7U~jT*Q~iU)SH!WOz^oEt&6{Zzvi~X9B#cN zd^RY?@$O;iLNS%RvrVy{R;`3iZCm9|wqfnZ%MrD|lUw5UiC^lpg-81Q^*ia zNRKS@daz}6GLSy^-kypZ@%hcXZBC&Gqm-4M9>$(1xB_yy=-;ehC+h19|JZ51*-waBCo7k0%H5OE=cvKd*wr7p7u{!nUsO&{)yqo6H z5HotU>?7}OPbLnyCDxAqm7x-En4Q|H>kbw-&};y|j;sJr7#SD)tsO7|=k( zCPmr|p8e0W#Bo~c^kAmgi-7X_{Itxe{_tQaxEeIbF68v`e$S%^r`;+Q zmY{p8!CAW(T>g%450lUq7{$v=xJaHD&!zL0Dn*lxbX$lMG|_kFOm6lZQ8xweWlUZ6 z(Dm?1mqT3hUfUKK2A=4^H=Q zq19LjG`qseCbY@~vKVud`pUO(EviE7Wv{Ban2^_eMY89EM~5*HIt}&#gyXRoE}yT( zTJZJNq0MPk>$+O1-#?Rz3_r5QvfY)xZ?<=!-NuZWooKoIDPZ&_qlF9L| zetj1o1)b;Avn@ag(qxpYQJp(XDJc;XZ}KOgF#n(+8(W3SN?u+w2DOLolCe*&^@Xu1ujmHG62(7WshF zr1oXNLGX|PqfNN2u&q{T?E?HVf3%lrmAZ+AwHA;P@flDzhW&rD3eKG(HIy$bp0oY*r zG!Fzg>bS8W2a`rpQcCbfLcf{QkA1?r;m!*rcE~ISYWeX8DGd!nCh|sDf65;xj!fMC zUGr&83UBaTASN-I4QbISE4nr9j&DR-aVeo`QASQW2@0!MCFS0zG; zn*M)6%a#IvR& z&C0dVgC+BGCPEJ|b+#2hGqAk+O5k65*ZIf?DElNcW%1V^Uj?f?!SGz(&XwKs!Iy;kC&ai5Tfk=E%KNY=% zXh=ae%(VI5#>>eHYH>q-5Nm(`Sey~4OZAqCsy4M&L4l8$oLpQRwc+ni*C0uIS&q8$ z@CtXX?C{-3JcdEc9SCH^$bf9C>PhfN$9m%mU8p#*45lr(r{He8z5osLOS&yH#EfKQ z_Rdo5T)S3`6o%Jz6p0W8hCL+t)Gvf8brj}VZz_t^o*YDFP^2$t!=1#2A`Hxj8HI;2 z-S1m|8&tC|JiU;TmX>~Am~_Sj6o6H!r~V0$$HGy33)xq%gKz(^bgT^o2Br;;TE1~w zKXMZ5I2D~a+E^$38Q7*|em{BZ#M2{OkK|8}qq1Q(i4IP`!5SU!R{KS%kdQN?z&XU$ z!!e0wI{&s)E;S?I+)AP;`-6EsCk*$KvZl$!IVy ztCn28)u6)o(5LN)0sbt-qUwSfQgA;1TmEu?lhf41kCJ^p^zug5u%~aAgmCFR^YizF zcP-uz*Ub2)Hk+0Y8|Q%s61c)w014y096c@%9}IMh=M2O1UwmJ7@$q=+djp)vaXy^C z3tB(V_m@u-p@CCMhBGaw_=VjKT}TTJIEM!+ybQ(ClGx_etY-YM#)tOW4d~6i9Q{Bp z)%MZGq^xN=$5A;4%yqItzs?>y3>nVYM+3o?V&UIB__iAqO{R&DZ-6n^Qpd$b{Q)Ir zp)6%AA3w(65Ecygrtb3qR>IRy1E4i@>BZfBMC}gf1)#?rtIG{>^4QfI)8wf6JIK)uFZZpl z9X+2iV|Y4TF78xq$&hTS#fpgS^q>_a0)?5GppWyW zcQd5`aAh`g2nKW|KAT<`gGeUEztV>EqZ9Kh#V;YPreze2kv@o6gOxg{yFf(W3cB++ z4x5}&XqEZ*G1czRXLaW1c5Kq?&xB1&_7huNxoSe|UVr{-Dk|4-IIDdvr zOC8&-*>oP{*3h7{BkCz8GOya=N&5H4sQm~E{QN!1!#Ugb_M4!=5SQEQD*XbO%Sz93 zE)wTkjW+j0iqZY#6Nf2_s@G&oeH?*p-A^D5MwwRgp!~dlXK-QfNMt>t2*)$=(U-g3 zTvn6ga~!&G^g~u^vT_2ubgeEkf^O?hFzmBw6jo(Ux0+LN&=>yp=(Tp8YGLAF5Bcvx z>0$5*Gd0!<|As)&QorYnSdd?$7=Cq8x4{=%qoZ1QV4QGs1OB->zX{UB6nFpH-mV4R z+;ON)_&QcVwx@^pv(`W{-Wq4hS_0(=^p_E1WBR;VoP?54Zi(RR%ei8092{WOead-^ za>jU?$a?2zgGFuywg4DhSM^@q$lbcbk-;}}O_>bS7+=O3!3>aNV_o3HoMUM+okESb zaj_|^VrNxyoAty#*^p@IPxsA@#U1#DD|XxM_0S8@6CV;I#{;@QJFbtNq{Iq9T`GIt zXX{~wW$vR-Ato9ZD)s@WFd6Bz`AU`Clxtf|{pLMQ_(#$Mja$N6vOIsfVtVn;8d({L z2@GBNeKxhluc;cmD8i`Lc# z3XZ_DH8-$bbMqLXrgnH!D$Q{I)tRMdB7DgQ{!Fwudc%(9 zP27T9WFOB*3jg`$^`;cVq6Lz}h&`lY!n1Q6zr#V>sr znKP-t5W?JEmGqY#1YAxb8u)}x_WrRQTJq}E0st8o7wqhxklKLK#>8mY(qZfUnoXTv zUQ=js-DR%~kE%lb2$)fX7 zmU^z5^>Kao8GI}$Hh**Tg`3u~&&uUhYxBlT`B`p&<7J+F(o+ujv*{aPysq!)rP~(d z<@NYZ-nR)}zc2-bq6t!SqiLSHW}bnQIZc_I#a|^Vd2O06B2CZI<*W1pid=YouzystHcA?v5jP3wNnbWpl)SvjA{IsVal1`1V;<|2cZkeJOq=7g%m;a z9rD-f;kMz5ohqJ0@ffK_C(H%Y@#P?fUeqq-@_y6A#=*e>!qwmN^YfY6IQk~MRM$ap zA)Bip4^yXcG0_>4)qMvMP$@}Rr>__q6~%9V>{Bc~6spSqC^>QHQ)BfKl~GjlsX?1& zJd88az|^Sgr6~YFBZp7%u5Ny@#dx-Pa8daKXC@l_C9&vbg8fez!R zHP-T9D@fLcue8PG!~a0O5NR_$AhN3Z1;AKFCY+Gx&oRS%oIdqui(t5~+^S4hyHG!( z$IU6l@<;IP*h8~cetM4ENpHuct0t*}vC|UsaGT+XnHfKoW>VNTw}r%pZ3L(!g0H*pH{z z@KSlKy25i#$*|U_964?{UN`JrX*AwDvq?ToC5lIVV)6d2p@{o zMYur-!7H9B;wP_kC7iSi*#ogBj)6m8|b8x+J)H4%#10&xKP{zUl?_lOe7CyD( zCXzg5KVLXj_@6AvGEW0o>HAdL+pFL@8{PH@To}xi@4ZU|QKa&n;dEl6bL<$FfzVV^lLA;Mo64|7<#1u`O$p;gxA3vzxulzGK?$wk z65%~#a@V@KmafUHu4DSeEv5n~ZB0Zil_o{^1t~|}zIF?=gyVm4KEX1nd z(5^`~o}j2y$1!ap`2NPTSe6dQyZ(9my;(4innacnh)D9A4_X!$XT;A~0jlS0x0Ri)0L6PuTetrxdUP^p0J5LkpWN!Xh+BN5>%hx#JcX?_a zFrFC4H^BN#TxH=aejl?nk{kz8udgW;xS|d!C*3LW0QoO`p+}YD6V?kwh?PgTO8Q-tM&&S(H`n_ z1K<`JN!aNK-=nd)%%mOLkP!J5n|3p7*I$37k?zJDp6WvK{~7UM8ldbeNW5x7qb#xD zpnyhh#MiUdMzwkm>Zdl;4AwO>+8RynOo)(CC>o{KaHjr;1c0EClr=TVW`vd?QuzAdK^tnh zBU3mo>(80tp5G>*Cw(86zp+9cov83ZGA_D)cK@%)shZtGHy?fOdz@cn9;QE$8t%bv z{**1Q0Ga26=;5qp-l!+`C8eR<_cc|QgRXB6sZ4%rDWmARZT<0w~<%Tx;QU0}?5k$4hdjeS{405Mil~~p2O-`Z1Lvn+Rh+o`YTsmq^NysKHvG?`o@6NOPK|)LK6{X@`DX_0 zX#G()zYTlnRUxdZjA;XO0lYtO>)Fq|GnQ8+kJ0D{L8P2?eUs?`1Z*4f{_f3~xRtZSxu z~Kw z?t6=eDlniE#2#3?h^hal=g#NyM^LTfgJT0CHu+c{l2YT;UmQy*^V94IPO4F}d)d9BnM!l4{`aa@A9s#& zSsUTmNtiJO-!*D(!TAN4Rrnltxy$Rp-8n{H=k&sztu1cdW>x#rfb zn|9AY>Wvf=fGnN(NiPe$i>Y;gv-lewE>xtmM8^}Sdg{T)h6^gEH$b2h-+SmQDajqo zzF3N?{Pn$o@~Jn>tJ5y}lrz_!*BK-1ul5`n*r+Q7kqo}Tuvg<)V) zKhE!Y&pc^}1HPR!-~$@YLhX=0ffpAqFWc8Kb{K`Z*F|MdO^%2J_|b;cpWl-b3^f?T zTjFkM^)|dI!8%bJsI=De^c>y-NngL}_QOBh*{aKewHopVj#Swsl#pcs!&Mat@kE|D zxIM?WJ&Mu=n$`)!Zzl%7A_-(A7C~1ixU}@&Z829X-_O&;x521g3VeE;1l35EUT6eM z5IMRp0V5^+^E^|QfmqCNcw$05_-uan)@J`jmT_Oj z{X#R}i0l#T8m_j2WNlT~>337xjo=PbA3LdC7kxVApZDH>zlwYvZ4vQjj=rVON%S)I z#B`#RMkl=FyRV;CN50z{A;k7AFVKwdXa%y|Jx(^d$U9f;GbalnFjPJca{ z@oxLCsY-Z0^!i<;zpTBd;r#_=>+FyZO@Fp8*FbxX?=D&r$j=Mq;YG(iA2;KT%LxKw zsaRpmNg&2e>@$~BEpSOwTRGdR{fpp?vMA1f>77%+GvK!IA^*r#gAy;<$^a-~L*Y$( z%L06$Yz>KjeBdq|mEHAf?e=7~t(53q>^rho^0~K|d%gcf|7BUz^W0I011s~{=R!4w zc|VQ)jSB<3ZKV_b(#NZ1!!MXlFN|jd9lSWRt#xsO8c^}2l9v>N98817C^VUFA7ic= z7_U&Xn_PA`a-eD<#vJ+RxV z?`VGevl#Hs5|62MK}!eg>-&piFFPsY@NesA^VR61;|&Zj@iL~(&#*ERXZ6*3% z0jn8yta1Kl2KA=z;I2Qx_uHzBwOtSKkV;agqdK^R*1780WQR6MVCO6Bw;QZ2y0GY$ zM}2{9qcH>y4*hV|u5EN#${`y9zxnqN&e?1%Bm^-s`kyEO^0HL_v~&~_(H$Tghw<;E z^2ir}RIlh2uKs+{b#H>u5*3c^?+bq@7<^_d8;}YT;*Mzki|Yur%)+79x;YweuK3wf z<^wdQq+V>tP0j?}4xjX2Dik~2P7&u!*z*qTG*TMqsrA%@{aQIyEJHJNC}RxnI&K{8tkURhyam%J zs%YwFL{nte;s#RlMEb+Xsms*P^zPxqj{R#>VM9*9YI73PT{BOe>?fM<7Wc0+R-<4b zhKFM%dx}H&_#iAFIxAm+Vb1HC-~0QEddcJ9spp{8DT(+2?mE;gXWaXe`|}(($1;(V z^Jstje9M0}V&LxoUn*!zEhR}y?-PSr9R!~lH1^DU)Ez5Z>H2e?v9Q{4<#W1h*{e?C zd;9f&bK=Qbl|MK*QKlM{56fa5^+Ar*b^w#?jf_9`w`LI4zp|b^&5cH*g&Uk#erzv4 zf}35J=*M&moY6TbwHSv$AYBm_90y+Fw#EDUi-8SVk-bn|J(;WxBtT##zZv@Cl!>iT zaoUY#{qy5fy6~X0zdz`3RxbkP`e!ns#^vj>wmX@RWatx08-xPl{7Op#*u%1p^a*7) z5Q@vuPhv)VZUa>eO|Wc*(QeWl-A4w}*_EcqHI3bGTF}(A<#T&Vb1z-e$9I@1EDSU; z8{KiP-x(R5w=zR`cp8lp->%Kk62S}ApRr{FftrUTNa_W{-9en~*{MH8gT6^fC^eWi zL~VbhWih^aYyVdOqHbZ0xw?AKIm^X9c4{cg6@~(7{LF&VVNGxR=vYfbq0jdd(e1*T znox~$V0g6`5VMX;diqH<_3s^Akc_wg3vWWyfgj=H`?NL+!Z|4K?Fe#cXlTAEY+$y5 zGCqL63pXhfV6)I{2nzGytAB?p%JIiE{kvo^Il!Kn^d-X3U(t{Y{PZpYJbn$_tMh|B zfBx{_z*2G(45Wa_rNZ_l7tp1_{c;lEs zqOGxHY>rxxUzQ$D*7nfV_*tMc>E8afEsoaq_3fVW_-vl6EnjmR{fX(?!tgMs6_kz8 zKg1Uir}wYCVHmlw0WHx{unoG@oUSp9U6E#lKkr$_#e|UI8N@vXkp9vMTZ*NdYvbV+ zsJKM2E*8}N-$Pb}{wFKAqb`L3)lwG;8y6#vi}-;=1URPRgD7NtN=s2o^71$TGx0Jv zo?uvi93NlND=aXad+uO2e#1cgiN@H_&@if(@(po`ScP{$DNrx~`UpB~b3Er=T6;o_EMc>tVTC15t_Y4eyT_J z0^-C8=H)50vH=tS^77ve*bTHMgj~6N@3z=dJdwAoOSGzZgX4p51g7w!VOfmPMtIXg2ohgl%5vFT+~vD=IX5}g-=fkfG@ZAAjgTndKwc9|v?WOu z_c;f;%kunVBZt7nl+pnBv<;ytt#2 zhb;KFDf=s&+HX8X>2M*^f%rLUqXK!wb>x#EWX~i9HRHNx?yGYuhP#=^k`7g2P|xBW zUqXFg-_Xk62YR0pZ2p#=&X5%6?W0hr>x1|G)!=*?9zK>G2y2KX%94}AiRhho(tO-S z)ypNZY4|QGNM`3e05M!0^}g*Ti>tbjO;VUx|CSs;R?N=*01{u-?MU!+4G!8O?`{bt zb>@A-=HCC>TT^j2=WC8EJ!jm&)vuD31|v`IQsMfT@yX9m<+Ic5PIA(*+)_mH1Ak3S z7n(cmo>RM;g4_OMAG1$_a)_0Y`;|Ub_N}~p8mYm=@bGIIBAm@WGkupPL!9xw-2HJi z^-=9-+nYTy^VgyOzOlGm%;aPpDTK5JA|@A+!<<-9x%XZARBFzgS7A8ep-3DcxKFID zf9E;kKanI_4cy*KGqmsegZ_}u?7VSCN1k$B&F|$^(H01zD+IoN!ky(t=Bpk5ar;bg zErEk9@<+=)_q`oZ_mn9k<~F@H;>LXa@JR{(1|R^S-h>kuCeO3(Heo-*=*EpqRn_4p z#*r6{w8Dvx6PUW%Ez^2M4S!9R(wW07ObZE;>+KU%VichTX-pzT>}O|Ox_Zt0scsN8 zHc`0Q;H*Usag`hzZY+c2*{R{nFZFk#esZUmjH2I1$B?bRhPmE{!CM&==C@bG`sFRh zU5%_rzgftou>6>}6%gwWeO;K~CAI!py)&S-)3_2#6Y0gJm)w!DjVz%HCk4XitF24IG|^8!nP#lr%pdNA)V*>UxrQ3rzuXJ-uQz>DK8 zv9=KNdc>QGJ1>xpSKFnG>VkM3)tn`D;A*?j%je2};7t5c4OtV^z28wq-%aGIwCQ1C z;+g`o!PIp37OSSfG_|}*MNU@SYC@nMo$e%&8?;84j+<_d@1tgZcByS2=5wPb?T3wj zjU9X^H_-0S4cEYSrbjy;`}PdUlnUwN?AxphebY0CyS9BdIAzvWsQxbOADVK@XTPg8 zB57Qy7?zDRchcQUo4)5sjH9M8W(N;P2NoOV%kpG8aNHg?e%Y(gVf;z|QcoVCOWqBP zAdKEk-xQrIYkKz|-OI4P*|mwpge2en9vSF>c(antjlhO?CL=yCNN)MbtQsz<-P`SB z^#k^~gEzUlW++O0IeURZDv)(&Ur?xxPfgZ_B>q?eno>49pV111l#iG<*YtONWh+ho zTVb$pga!Jq0gN)M!MA5oy>lfLSqsPqes9fuyEj@IHTL$m>9d+;vVW6CLvPt z=yojoOQ+>4C|kjo(Mi%%Q;F@>q>FC;Ut0hL6h>lSr}?&8`#!Uosi|quwI}KXZIS!X zF&_W=7j;$M@{s;1ELfXemZx8S0bO~P8`|fzZfeOT%O6+_j&rkwI>%33a<{1h0Xr5Y@Cr>rj z!73j10S=5BA6Z?VT10F$Me_Z+xQz~H-ESw`8|Tz7)9w2mhs|bQ{=DFFjhrcltitBG zOxi&f_c4YS^71~~I$}I4n zlF4$C*qj*{K6^mAbgqQa`{bR1=8)2(!=J(bUKLYB)<(0>AexLPw!5)_d$r3ofbhV- zT};Y|52LKY%~+J+V0Rj{4Y)cEUD-cAH4g@3eAgW9=ae+>{-E7{y(8zUSUYnzHQE|X z92yN5|6;R{22GhN1itOU+wM?^g{LLLQ-n{)SZq4Cl+Epew zrDA5XG>6I>+21DHVlM-KqipHOBryV-Vjg0VFj?GT$?82aGX?_sQ#i$83+J?BN1umuOJlL&NadA`u6qNJL-7G?L7=XqPw4||0%Db9NtQhN z-9Xm}t5_F``O1S?eZR1P%|MM6B72mkv3X2UN#2!nPcfO2^2%XqZch;kHdavpcGBe; zc_c!HFpwmiLd2*1>;|BNuD-))OW0IYD95CjQbR8`hb@gaN_98J(|t2fj7jpEwzMD@ z!uj)`p_cgTD+KFG2HZF@*{_D9*(EWzS08Rtz&2fS8s{#Wzx7ZEW(Z6dv-ZBpJ(5dy|AT zNaAEB8yVR~h|4MwxkU*?^xks43evzy^-M9#WZiaj|6P?(QS|0auK#D@&d7FD@y7)bx4H#6r2aQ|bDwF1%Iqk_#Ba zR#u*2Z;mCLjxts<5aN4Lr}9gs?qrhg7-UPorT8T!hmJ+YU(cGh(DK>llJSB!!n8#F zJM~neti>;3|Nix2Kr=X(r?avxr*mEO&6-3+zKuOjaVz8cA(fke~7d1~zQXZKExjul4mzBcdpq6+pKr9P6Cil%=20p{1eVta{snm=>1{C>I&uwT;` zg=wcMF~sS4N|V-{t0uT73;AQ5O)Bs#wH2NG>(S4Kmu#-hPcapO0_VZnAgHNd-##ca*EeX`({&!p zj@fCxrhXZ@uanZIZAl&T>EGPO)eS<%Dwx$nuTqSbr}R^?HdA}^c>uj$DYUE{PZ11= zJ8_hidwU_&dO52l4hT8)8aW%AQF)WnEumGK@*5}c2)bsGd}d=2Q(61n!?hY{0nKzf z9)vWj5ZJZvHmz$5?8|Y z=&$6$W{~C+d_J;Y_qnSRy)2~8P*~DW9{+vUaxBqtM)1Yh%+3c~isIUxt=^B+)lQTn zHDJ@n|E<>|d^q_x6@&AOGn!MfctNGs$hp>`Rz6DF?MAaSBa$p5g9R3w;$oBI!CSnq zZ;Xlm>knx{jqx9HJYp)Cj9`)7Fy)suLuI+0h@ki}O{Ym@d&6OS{1n^9$yx*V%dub4 z-d+WPCk;|ztdMZ?Q#qjRId%ssc})?zv`dI=Fx?QRSCJBHH={rfL)s3)Z7JM)N15d> zuO}*pk(p}1Tda6b(=ix%`ndoX_O8RM>5m&FK7@oRDX@`O=d>4ykl#Pc!%5u6HyRZc^|`sCXQm>@JjT1jtXEp3 z8*>s8yDejHJ3I58^xsp=!ZfhQ#XhljexnOdG~}UgiJc0$p*`jj#TRu8uTL0ix61d< zYXdKy_uj>2PAK&cyAgDp4>3t*AWp_gU^Va(KWL;S$~X|EX#t46+=Kyu8xJML)#sP|Z5v@xjCt@O{@`l#4p_#b#KOU$`m}K%98$#K zS0Swq!QJ~u)6RkPbDlW8*?SoKfGNPm3mc7=wQq2E(>|ZKFu*zQ8z`vJdH^e#RAzwy zR_wWNG3x*%DXMGP3&R*OV@nUXMd#~-gXc}KU*p8Ys%%+$CC>&2aTO5@Wi-Fe#q0be zXr50_W~d2|XJ&#HJy-#d+LzNCVEJhDo5ooU8Vl7VfeHK#L_w+2!dNG+5Ss_dYY;f68;2L3_*E%Z2FX_4mZktDyg8OGDio5nodTXu z7k3H%lg11%m_=q=mOw)#>`hw#;v@I>U~>pMLMnXK3b1W07aJ?Yw64FJG5)ZFZ-A4m zzJA>$BLmIPc)|isGe9`yvNkArw!n}>8Iw;RApDJuj2dV4tl{fmLJx*can9lUWDbr- zX}Mn0=l6D|c|P-UiM*FSDW(WgXY>$c*4p&v4xfEMHEO(eQvYu04EFD|ZEl6^?f=&T zj5jmB;h^{fwnH@r&Tb5#@s@_XNid)DHJ8Sh_F^S6J_$qkp=6)itCr86k;$`bm%7rg zPv#XBGYc=iH+Al`?s}33{npHl3#f+Im(&D0oG(kmLt)#7U~#IapL3#3ApUj_yoRRN zxna(ubfd}oNVgsP&i%^S0?4uJoiOmY&RXVFTTa)iU>zy2&t30k%d>+viMo0c9`0IP zNoU;l*OqxFZ`RP9wmK{6q5(m_3fa?#?YCFP=Qo>0TFc_c84d61cS`jtbf%1_`EQij z!@6XA`;UAx-f0pSPDpHeRE$61^r+Y9h?MbN^3M+5FsuEseR}qc4b5ko-!psx=GaAs zo?zoP+q0Q&?_JpWrAh7304O8-i%Q;2*i$_rlV8ZUC%Bj1`NufUF@|BHUD zQp)J=KYe%|Xf)yN{37&cHLDIcB>UpiETVlAnKVi+>xJ+dD1G(^CPf z@GMT%;(G#_X`M)S_r{Fu-kSR#p8ZPBxy?JVe0Y(`5_GVY|CC-(An{eaFgqvK`yZ>r z$U94R0lBwh#356Dy&BvkLHL;B71Q5TXMHy^kK7d?jlM$EWm6BQ=m(I?`=vmG1nuv7wBYEM6p@{W7X_Kl6XhS_*-N^jDB9Ipk}4 z;_f^$+#HT@MQR*`B<9}Pexa8B*9X*&!W7JG>Pa(U6>A}4CB;OnujO+zkSmtQsiTjL z=tf$izuTesKX4}LQ<=Mtt`tutErMzl?A?eaC_8b~jRt>%Q3FI*Pfu?#KpRhCLUIc9 z4pHU2gLZ0#Mj^%1_rKPS6Xfgio-j5@{_5dgDx^p&)vE-HC3P-Uia>ku$Q`Hx%Xuk+ zKjwoMYaWxQB%sqIr(~*Ox{E+o%vg!Nyx60pNxs#tdg+zo{%WF!59n0hjs9&mdN;-* zWd@sH1pt*y13s(}6GLP#r)`h_z&cP$q~ipuQN7^E=8fulLipL*LC*SYTh?zCnBa*|H*8?$sDBR6+8U4}5+^CWw$2<@2k z)Y}<4=e94U)XXbPgJ9YJ4m zL-_Rkf3ot%R)m?BF5fXWeoB@sqUbD{lyr1Hl2==oG*HDO&l)OmK9jpQAA&GWwtClz za;2A--a7>Ir~ggAepvA7A&8lyib?`pG%A%@l-hq#>YRcKIr#eIbWX$Y*AL(Sa!H&4 zJS~HK*E>c+L1e69aI#BDC}B_VO0OszL$iv@PCMF_U!; zPTo~TMC-?Cgj(UDthu-heuCi6ko4Sh&kMnZzt*A{)rVD6Ip(FDhh#rA`Sa=;olyuT9|Hi|UI(v^@B0rGKZKxOVyoX{iwyM#~D7&8paj}iwP*vh} zZSlDg$ml7f{~NtJBf?7#dwZ|rwX@G-2I`vd64X)#PMQ;=i%t`Y;;)Y>LS!w9s z-O9vb7{yO6*4#js9-^$g$<-DlLn>cqes$eNa^wr}4~R4Sx|5UB%Yulw3447tyn72f zPm(OjK5S#Hu2u8Yl(|VK;X~Azs~Dweo=#3#oi9O_fD8D;`b8`FZ4xov#ubL;+D<_> zuaVXcBGR{tA+I3o>j$@8%eo`#V9b@JOp?rFxmVT&Js5JP!f$XQ;-^x+2jFo71KHP( z4h%=bQ$$ExGO}Dr7PEAmOMeBMau2hMuczFSs{N8(bP16@y5m0 zE?zLNxXEI9y5P%^wki&IwRxJ{IPZ`RlC{Rk5^8w4LDwhxWyZRMJ~I*%nIQrxk3d6t zR2z_2@^Wd*>UxXRuN|9_61M2bRIB9f3~ z&uq%h-eqTJ9UMn8GAmgb$H@EG%3jAv$UI~mo02__b?n3Msn75G{G;n~xvsA3<(${^ z`FK7a_xtUhF**b*4R2W5n9rx3tT;a0CJYBShcf%3=Gp8d3CuO-afTTZb{#>(L+AAb zI9O*h0b;l>Uv5A8oX5JCn%d9dkwDf6F3G>+0)DlcxycH@X!arBwS$ykq5o)sS`Yt< zUDN5VEFd=mN*vU6r6t#yAIEE9L?#kCTD1X1*l(qq-IQ%+W{}?AxgTk(?gtV9$oQpO zSNNI@%80G}WPpbZmhy;^#5bw^9zKH2PDqLdl*ez|`fOy!UzK$1LSzr+v%i+V!8eW2 zl8_`(5w{33N65w6hVjxT;bBlp(%!*QlN-^s#ReWh$HC#PSIw*Jg%Ur4Fk35l<~(RI zAZe~Z;j)W9GVt_1Pv(~OSI$S`YTxNXrp@<+Sy*pGQ-xaT72S6DSXnl}9 z$zPIxV?Z_cO_Is{L|0eWrI79+6hza$>a!;C=@~BK2?}+1x&rlj%r5JP$i!eRqT98v zhfqB}lEU1-$0MbcsW1G#q!fn!_$4y;L%4zfMko%h{`0t(il|OP*!%${cJg|uRuvjO z_4#3tYBRU_TE^h`kY?dtD|^QS?NT)R+`%V}S&c9>A!vl~ba_&nV)mwRznhD#5LIYr zn;>Y4S-6#uZEaa+U!{O>UgMkW(HQ~F9l{*sgm77a$ChLyOVg(4UpwW50Nvt|TD9}H zh<*Kf%(m&(u$0S~|9?82&LYSw0W5p#_8baRRgfTFGW&jnmoYd<<}=^;pBypZ19jq# z!J~tRU(5_ZcbEGIeg4W0QRV=lEZJM2yYB0bAa>%`VTs7q7Lz88>@+V`&qMduou#{V z8~?E7{NwqUDe5?&F2-rAqT+CT;g8r3gCsKqOb%||1j2Hlf5=$>#Y`UIIvkHL{-k1c?$&w9$NEqQ9yDcy$6+OuTa5E z#h9sQYqRsefh+{y>uI^Fq(r+w#B6BVE8sQlQGto)aQy#q-Wwi#prizq9rr<}tbyX3 z%t4*p+#JNKG3}0VB@~U{b%T3(+@?^Ex*T#p%t9~Ui}!hfl{y8?Jyf2=gNa;_RppWr zc7m;-NSxVScJ_)w~% zFDo{~CxM@KKlbo(*#E^>Yy3RnjO=^{4eCYsGW~LunKOBgnxV|f&=yyl|vErmlK-*N8h)F-cQXohyQPu0O-Q z)ztS;JjZdsd4|#sRj{s6YBkK-5}9mAsBor zmbTyzHtII(m`I&uap&pG*?1;8lJJw0<)i;RUwnC^IXeWSlL&tOc2+=OemxRmF6nEw z7FbXG^#;N;Idq1xH~<po%Y4P(Y3Hk51B2TPpT&H};3rC-(?Sdu zJ#Rghk-zJSjTDJK(>|3mNx{%X(POg z4nmC1p`GU$H3CP=h&baap{xLefyy2aX$xmbx3i#a?|c1;LW ziPuGS?m&mT#W*K1EwGb<1+euxs+L`bUz#~Cgf~ZnwEtNZmz@xJqL$q&3yXYbS*xlZ z#{|D?ze-h8J-}>KFvp{`@MFjSw6Q*F?O^RTwlrc!`mK49D@=g44xT(QIV8kR?Oy%c2q zErnh6nkJ`*#x&;1hNGR{F2F)k!c|CL(-5z;YU4A-rn?C7QPZ`vj#voeLXrGb=oKTkZx}w znVwdxM7eI^qN1VW2zotiNo`+t7G#_h{!|ryGpFGn)G@o{S0)&H2Lu@5eEcG+RAl;>Qq6Fb4eh+wjhovASei&!NTcOd ztjX+HQ?@8Mn!qx+=8K0-H*@!0F1x8m%PL)8>mZW9r|V^SeEU!BY&M-8Qk{YnmHYT@+zmoDZEuF8y{UT`&i}}>QB|KG+-I*{;_}USa#mT5 z5u|GK$frb?zsYR4=(mEfixJ)==WaX3y9^|Lr?uK!uy3qoeD|}rq~bG0D7}ZBxWU-3 z4G33E3V_{VyqNum&AjvP2meN7?qF=Mtvx)dhHmm*4!-|2q41P&681!pVygm4AH6Lm zC(*ZCQIT>PQy!J=>*(mXauCe+FA5lseRxw(YZDG$7dlFHSAW!{^{*`@zBX1%dGuuO z7BA-I+hVZ(G~5d>9=DS4+Z&+QE3;I>5iMr^k&`ay6DP^09ON-urJP@YByvd%ao_Ot zOcM-b=3vsh`qVLst4T@PM^;9dlC#->cP%TsfoX}MrKDSgsQRkrKFL|x)Mq7TLJFENpYzEgz$0mr3OoT>rRm1-1v^XF)ZszlGUuA^4 z{#~cBblJBFK`YP!Y6xpg^OxP=WCf>4y}tNzn~_j&?FX1-=6I%8(US=N7o|sZy(Q$k zaI!yeD$9(~UT`&ebz@D>(riwVi%$2)>q@4uMitP0=u4wG1jjzRc7c^~tbX@z3NmP> z6!_4s>6BhDDA7gz2>CgrId^s{{suT&F}}P=5!cu_*$+I)q)>KNd+>iMl}jZ0J5wL| zib1Gpik{cpniFllNB7+taWHee9aO`{b00ZqW&UA7a3H%Dxz&?rcM zfAs+|Uh$JmLPQ|oIs3Ym)tOCOwYYFW;#bc;2W3)|_g^M~{tE*vHPiXQnpPH^3&tkC zvr3`e{hBA$FB$cWIWJxD5ol(n1oLz)q>ZL{qI`_v*I-@MlL-@c_MYzDNjFB35)2B( zbF93&@hL!tFU1+^a;lis%pXkA{ETv15oNzcPQ*Mr;6Pues#T+$moHZH7xGF;{YgN zd=?FL;d5Y`{@rHt5HKVc1ftu+ND;Yr!i|j}JU5I-afVWV!3Nq;8_7B%I-@Q17wl;Y zb?LCoo>zcjv7lW6@>P8OD|I0IwiM<#Z<-*Hhts%yO^_@j z-oHf5lgOJ05|g}gX8c0dnyhBYj^pu@krUGW{SAi^FYL{F%^Y|<+ns*idz6O_ zoK=N8C|!n59UiNnlJ5pGGE&8hl($@Ogj{rB5)=3F7knMMCvAT>T@RKz3y+EhcUdGQ zKCjd5xF!=)q-U#hsM4Mz&Kg3;rrQ@*3ymcyLH{yM)Z@*FTHY8nc&o^wJhs!dy!tlC zD-%c-2~90Ay&eE?Hs?E&xkHSZ9Q-v&kBC*Z)3m$#Z;J z3&}Sa?EL%sI50}Rsa_}bBGqkTtYsng)-oe9btRa?82F+RDO*}ER>(Cq>;F1og^Q(S z-u3ZxgPu$M86W_|;UM7xK+SdvaN+8CtkSFY$g$wf=@;Wb_`Er_4Y1=6DB zF?tt$LiM~)_1`WuAQ9n;d)cpNWUfrn>8i@9vHI|?-KBUVH*cPs{V9y&8&b_#os$G3 znbB=ev<+UPnK8NeLy(Xb{y{5z-Cfll%OH) z5^9OPP-(R*wR@Fjim6@u?-MiV-vKEk;a1}(Ix4lD6M(G@zeh*6K>;iiFB#X8A5kg0 z&+W#{)&!(T5__QIw04igiH^TNDf&AXnX>)NmTlx*#njxyvyPV@p%Smo^=n1NUm`cwGM4N={d=Ez zdwMo@$^Kyo6Fqckc*gs59=d+WR_^oacmSl^yH%@VRn?Q}p)Ib{@0)Tf)qvE&71W9 z^mhpf+hGFgq+2J1GrYI3cH`c)H-{*hu)2A+bFs6g>QV8Lf?JV#*OhdN4HC^fKRbN< z+)N9Raak1AwYLOeCg$cY&paHP*e*o0{gPt0nHG<-hTmmmsJCyB8Cl+Z8_3$SVP|Yi z7O9x7slSU^V5UBua#+Tw1@G}B5<$ksY{{a$iuk{+QcqZa*gWE<`m|hbx_b?9#m?H+W;FfxSL>Z>_EHqpK;P;nkC#2Qdn)~#SNlG_Kc6+fx{XWFRc

Qx;=0!x^YK=Z>qRsYuXX>?K@*A~b;X8h&L1f0Z9XhrDCzwuNg;7wV!(DV zZmd5)GtcIQpt&*l`O`EtJRSRMo81B9rz=h&RQ> zXmj)RpI^imlwv~U*6Nk>XrgCr#XLM^ZTg4U6_9O#@5!>d);rvf+_Jf znJ>M6i}<+Pe5fQ%7duFMW9wZ*Uv;j}H}wK| zY!J(0*n~?EW!_ymKt7U^lF;oQ>jmD1b{lo$8clo}_q2kBxX*O=VScdTs&=k@y8eNq z8a9YQA#Sim+NI4Bc`@l6H{Q593AT>oEd{RE*yX!XZ-5Uj@B~<{0jVdsNm$g^Gbg>R zgY5H_OeuLtvlqF-=amCb#`cz^pg71|-&30~F?h+!1iS?ho;bS5xfm zO!^#QDtbiEDM?W!B%wSxqYjmJiZ`SE2>kroPvarTALDcja6G(9IoZ0|FnBUZ`WgX1 zh}ZHz_352k-X9BI)oYzQ5^wQs(&JU)SbV-M1|AWxCLX?7Ni-Zlw3K&m4+ca%nYlP) zkvM_BXe8dD8RpqZK8^$~N9j%L_@(j<`;>Wx|19?=XO;akUl1=FysbpLn0JN8k zC}VM_^%tK)bS7LBuvkJbpE&k%Y7*UT_mbhGh&9cRF;^7YbDdqj*dy1-h41v+zsCn; zu%Rt}f%7~;XV_D1I`CR+;XxlF?!o#2Tu6jmkns zYu2N|478y)t_GUHcM`I-c}WKxv_~#`nSh`G8Q5^?hbPE_#_VHp(K{b8`3E)6$*@3~ z$o5z?_RYC6t+8|x!ZqyYXLCMIgV&IXIIk%(_D8J6Y9%;vS1TDxg)YJQXR?!qo|4?e z*pcgA4Y1j^MTHKJmhp(NZ0EDH;cY!yBL&3*$BY-%(Kx%e4|1-+3ZPf0h#30 zeLv>b?dwP*vvsQfj*oK&#aD+ZtPb`EvfS~!QK?4+Cw44(y2%=LEyZ0Mq!#sQ=zLKm z3GBufw$+3NIOj`csMN)rh>OcFT$-0hWB2Q2OMVL~lQ1)9$!BAIUOenoi&tFr9u5;l zff{>wcZugs6fdM?{w`oFU|!%qIK2LP)FrqpAQ{bNDve|2Mu-dzitvX+?lXz1aX;d> z9lpCDU)2VWNnd8Ng$S9Dxc=)X7}GK)tjOZ1|0u_j8$`E0RhW%+{s|)SZoEApmw@3S&fZvU^@=N9pZW*J|I-4%&`ohIW0TspeC$p^S{$!Pme%C@_Ll!Edkw}#k>rZ0Y`gO`(zDNtbfD8QYAK4^WYmeIug_n*llcewW-@2EqY}=O-Y?bs&q~FMym!*6D_izD0Mg20;$b6)bbg*u-ZWM+la+p*J z>(4b4j-qAICr3+jqw&o^6t>i32Zf)`JB`F>`x+-Lz*veBUb*JfpG-Gwj9lX(jV?@a z=rfFogjDeQ)*l^P{`daC0^9o2?A0BwpM8HgD?CBOZPsKSKQiMAMJOWF`1%kKd)1_^ z<`0r(tAR8}&z`=$PeaFhHrj5%AD_$w6qHXwe{}YFNjoA+`$O`QKoiE)^ic9xz0c*J z?0I+k*u>fRTf5RV=ol zJiI}aWEWK$tD$)eG#NT?aAN-bePs1LX3F0wTB;~}V`Vn)rI>O%q4I2GEzSyF6yTB}8!L{!82{$m>uqr#>zE6X zdij2Wk=Y|Kh2OruUgF`3X9q5eUD*7zVd8(DS^ zi-Kt)s-iTinVcBO%5awj{LtfkEfH*^YjzMAxK1&%LSKOk~6O#+$_u8A;;G51D)NC+$2}Naq*T*a}pqI2V~xxYVtbsB6qOu{`@P zY$>WztpXTZ15=Jy4BkzQuY}n>sB~P)q;bx#kU&lL*3TsjNSI$_JEQcBMVtkMi%tOS zQ5OUhKb)!k?PD*Lax%qhH+JO6J@5;eHf4MzXe|9TW$J%s>)NVpDMQcCCa^v}05f!c zB&(%$zR>)N%!`0YWemTUME_O}GAB8E@5Xt1Gvp9+e$*OjTJx1(aQ=Cwm7+pFd(EGV8 zB{j`;WSi+5n`C5Xsx(^_Z~EkeuZ1@W5P5NjjM5obi@&*&-pm z#-#G6!yL{V-j{T$M!dcF&Vu`L)wFydXHjxn0Opd zZrf3R5R!YR*W>O0QzK@NNH&OFRUCWyvOagCWQxYM@WpfN`SIVb38oexI4ugo7m>8L z#Un$dv|yu{m+Adlfkbn%1QbdOc;egVXYVH>=C2MHNLkc9&GDXA$^ISdGL7Tz930tf zg0mw`C|Kh;^M)3s$;V%bG&GkH&a#h}mHXX#1=q){EoAr?qD%fVNX}P|uWlwY4Rj77 ztbT;r-q>QA-tK(-Wx9CHNrko+^v|2k(S(|WC3nxx?>>U7-ZKV>T61V)FzMDHAGsr7 z0Z%il7g>OG(qDrg=&`lBT?-(Mk_1{&(}28#sd@9f8T*50PEtxSUU0$afN0m`3Zd-c zBXxCs1z~3Mno4tHqWNV98)cz}Bza3LEke#Z&&8xpm(H2zj&@%GZfZ>^|004r;dpok zudKMI8;y0MTalx^YEokKV>k@&og@vsZHi7+FR#g6f<|PYH8Z`{vec?3IwY-#m+A$x=qM5U8!#B2|I9e zqw)HCj}EDS5Fa-Hc_bUJ)zv90BWYSN=Pe~emgVkSUs}bqNc}%V0v%;}uLq#d!1)um zyuKNgRqz3*T@*EW%Zg(i_ywIbM^ugxkJais3@T<)-!_E9a_1}5UzWtb_3PZ0UC zMK5Ci7Ie|Tzol=FuSoAfhiyTCO{472ix=p*fU`22XXQdp|)%i;9dP1pSzHqK`)oFOSgPGC4rl4qp9p z0Kl1Kg0cb>pnWs(x#u|_kzfpGqB?*x`ocBU&ns*&wZZ;(HbDrPFr#Dk)tXJvT*%P_dh=h?tF#oxL1fxd^)R*@t` zC$cuRqtUg4wO(Ccqy&3xZ=d%ONH7SvWOd6kp;2z!Yh=CSla$}aZmi@m|IriiOwaKJ z*aAJmEog0SZu}8K0Pf*k^*p@fIhXW}w)7xfe@kQe_2D&Iw(1`@AMgCNtb22UdcXhl zKV2x~J?GRL9-GZTenX&eMDTPAwei^a(dp>$%$)y0Z!B2XXw|z9Z=#cV(g$y^hQ4x3(cW}St(w7xE%~!n)Jj^i z>Ch?Nhe%(u9=D?j5}4zn$xXr;$jY@UHxQqQL0%3JMvd}U`l_6n=zOGGz2ov*Wp2RqIr#^n567nY^%)S(|qA` zl0AL(23bF}g#hcfhq!0=mrQ-qmn`gP9UHd##H!z6Eg)x$24mpjIdMk$+{mRpTd z-S-E?f0RR-=yAZWVOMtdmqT8r?OPQPQF~7tGw2Z^80sNyBma1dSxy zaZMSSRT|D~_WDIwE;Tyn8+kSLyHJ@O+HerWY-IB12zVAwnTe+hrbbro!T)FCA$8ED}UX<1)TDd-d8Nvv0d7PqExKP8!Ueo>c<-V7+%fx&D>RmIiZ_hBT7nOB+ zf&mI3cetDJle;fOb?WiwO86GMbs8z3qMq4U=-R3UddjC$Ab)t=!jjvgdK2BU+?69y zX|Z$BsJs%VBw#vG>6{_zau$z7vObe=hP3pV9z+9HC(Ph2)!^x|Z#%VEPPxOLKC z<@wK?e#6x65?i4W-nJ}N3$JGE#N~JG1yJ*#z}K@Gny8A$i!BTuVt1a;NTNm8d00i) zcMF$%AB{}+&9UW{E`2F%k0%-EqjC}L`D1%9+nE>hnWcSh@2PNXlZDUE$D))^i@P7( z5*2i_h`-B0HMClkM)#rCmBSC#xuFxXQwymb>~yqi&Xrg;A$$S(ai69AS7(i@P5SJh zNy((y+7Kgi?>b=iYHydz(uK~|8sN=KAUiM?%txtM0QyZ_b+Bw^rG)a-&E~Gsf4VbW znG&rB0>-@0303z_=1Vkgo9WJW-M|>ylW} zlqIDc8_LJn>uztaBO_{xRgzgnc9PNF+Xu*@pVEGD6{uAMf`m0v8Op0{czl&}&NKpd(3P}|pz>^$B*Ws~?_W$fzbT`5)_feLUl1IfvNr6n_) z6)tl}dd-Iz51!ad?CL<3R1E}@O4Z@!0IfGRk|X%IQ#caxEZl_i1#+KS;0U75PryN4 z&*_L&;FiOYIkYA92oaz57AMQBZ<|>uCU&G_+q*9;iH6p!`uv`#q?cjUJQUQ?KCfYyz( zyD0rUsf4f1k)>&xT;4+iXxO8yBCi)!pD_`)zlT6DK=R)n#tF<4pVy9pUEG=CPkPI# zRYbK4VClCMuiISBV(n;i;>@oJ9^FLd)&;NLxm7y*?N#s{{VLv`zPm)A)!~YH#;q`! zFOBlq+R~I>NnSh9VZ7EsG{D`u>mq!pnX?o)OlaZn9LKHq?clXYuI zmK9t*-O$x+qpn*71#=JQ?C$f9``NSK=+JB+Ipn!b* z@^)r_QgM($uBQ7!o1o9u0HW&M{&>WrwB_V*{qv5(kj147D~L`uYOU}Kt&Xb% zTob5%!JH6Zrgsk{WX{Qb43vRnb~=$#wFyo?rO$v&N15StpgTNr?yG7w2e@R)0dB`9 zLiqH_wgKzTH7f(v1{SZrSP9lUqmOjgS||i@B>WvDqM9LaZQ=pC#y&UUZ&=+BA0QU& zc1h%fsBwI|PZZa`y6$B5tD9@{fKeg%ub?SI>AM`(cLE4!?AP?Ewg{ser8n7~LtvZb853t%CjVdKs8DDmzJoxVH}V4i5vS&R?Jdvg+uLl5ae0R6gnhLtkg$eiab z6D6Hah{d|kRg?j5mk`M5#U=Mp%#9Rw61xYQ6&(dasOCM72oMM>4FqALFatD66L_jm zUd!}EZa4fU)TCU&gL?8?$!ft+XI}Rp)0+#!{6oYKDYr6SJ`|H=;)oGCW$-@lCEC>q zQ=}nUOkmn6Rav*E{If5{|LE8f4F>aT6APoCp)634ZfMYa+v;nsp=|W3#9y@3cw2aV zQ7|{Aa8x=QpOhRVGt6cP31VPh?yPV%D6OZ>g5xqV2YZgVU9JzU?nYO3j#rU1C&k4j zx8EnoFCQ`#y*DiKJ4agxGi#%L>NUH*@JM6;qvS$)XD*)xS0+salp&nT`Y@OQnbRrQ z?%{B4IS_qOYUqh8O3yiy{7mCwwO9GdtfB?m_1Ee_J!8lM)ZPi}fMmSH=f~ezxF6Pf z^gXTtEQiz=GbKoK13>`3;rO{58ZlwQbyqA7;gUS>+=L`qmcs02@XA*3_0&&OK#m&! zTv{JS)=LLhnfOY(qO+cQS9G-%l;%#KojYj-FFnR@HXCXRmxzikZT}RKD={bm1XlO- zp}NYK5Att8N0md5i^`O9j~YePhv4d5M0=wASqU*hkZ#_XTP zd{5|)-Hok(+I)*;0zM9aO3M*GX;!9*&N6CNn%9~B$4du;8_bfkxrkOVf2e9YEN9jM z(%XNrh!k_dDNK0*>s=6%yAS}VcQ0K8%JDs&_hb;b?-%bWRg7Kpri|VA>%Sltw+jO$ zY;m|nfnZE$=u8V-S;)uQvMq7SuWtx(v1hK8md`N8pZ6Z54a!uei3XbT7; z(BdORJFjV|@`LU6u8QocCm3QwaA>T<=@Ie(tA&5t0zN71T8>{JmHPr^(zqTn7j|nw z$YK`W8fb)(AZU_h`6y_u)lh|om-q;ZR&Rs$I>tFjR!8=#lFlo%O(^lg*W0+{_5@d7 z?W#YGs2q+?!I?n^a;#qJLbK;AZ5Tu_|xu*6wMwU!H|+>sOr=m7$*DEm=L z?M%8@>PMSiWux~mGzp_i&YvUQ-^{%RLWL@(PUzbwQnOTKCWywb2v%DiMa$|TwKeL+ zuK%>>EwUcJa%iZJ9~4TE4-K20W%A9MnYrc0#|LtLaOh-Jh7WgUoXv!U45wAKg9+Y9 z9J#Fala7D|cvL;p_4P?eUn`R*&g77s*IudyYve({423>DO zSZxbp#55(NlEyC?p>o`=Q!np_^$rq^413K45jm?o3(<*cy>fZcK>DWgt4?0QC9${{ z#t17xhF8G#=k*|~sn}}9L#yM$LE}`51KsbA~$vu=`eTjYVL#NjDX#=M8 z2usFABTgT`Ow;@fEp5UT=$G83*g%w$w!md=o(jENKrJqrmzub^YgJ<>@3GH{UBy+g zwzK5dlv%jhb!@l_LrN`5u;+_zkm?%aeau<$Np(c(PwJ0Fu6HlK6)Am0f%_F}YbE1{ z8Bp=mAGPUuTMy6%wqPGUj`IGN6yQ0hbu*fHq+H>B-?s3L9i`x(3%F?sj)rXk?B1!nm4FTPhlVw`)y1wr3&5F3o z)PBjDFC3|Gd*fty1twCaauA(FCt-OJY0R-HoA&(4QtWE5K_YqO0Yf1$-+$yJTGy;A z0mk&-?kDFN>5(}-q~HoLY0l^5hWx&yrP*yO5Aiz|P5@Y@gzKNM9PzxE7e0QR-#v07 zv)7G$S-hI=Rhko0yEC_?;G;w^Z#Nf=l3U+%!_$+Dnws)A(7vUm1tCbwdhz763qc^* z-{nCn$zlAthp%Yj_n&W7U;1fROXdS3$nPy|^GqrIK+})rVcWgEfS<9(W!f!IU4?iY zOH^i&$m>~Yp(_`C(bLm{D|5n`)R)KX-V`#5x6l7oLq>HxgICZEaM#Toi6!f$!TMwC zX6HG`?4PSP=+rGLyK*yAN8F($UBAdk5+63W5(#T<1jk6xbE>YH$+oK-ibV3;e@PTb z^$NOze*Y}zi{@Zr{<-BIIMu}3CKxmH?)r}-f0BcCrM;B0Vk=EfXdt&jgh8&h|HVsr zL`S22AyF4n&kq#EoY|7Q-$~XY?FmxGN&5v4cbE=U+4vxE8rHl@H>(-gFDy)5$HOAKJ7ZRd4e0aa7|>HX`5 zr50KSyo4qZcf;QwdgCRa1sZUuZG3G2OxABL3o3YJrC9eT)E z7D2!ADLZWi=H8Bi@ZW43UIX=APqz?aNDY~YTl3~q=Zb=SW56W$bl34euvV=*o}&LI zLh`y~01sD~t{OEw*PPYe6nY?DT7gVEJ~3?aT<8X@A&0vp>iGyaEx$P`vxw7~BOPC5{;n(>}zw2?&of|?+wLUQR^o(I(F224sx(~1S z7Wktr-1tV%8h`x@Zy%k4J45PbX9bG5gVLpT^>k_K#Fx1&A@>trBRe+(65c zKTDpB$*D2mDkmrLKn)`AP$GcrMB47YT*lJ<#FGQs-r)U52-P18 zPiQRfM;6Iinq@Ie?FcEeJA?)DBPcEq4cLz>8@bwII+EX4uafb+2#+Q2ct(6YVEGB~zHb z^P#_G_$;03E)#a`5>OtXrPssMGxj&L&X$7VgkzwMiVsd#JuN#Y-P&-wNoh%N3P^2$ z-z~IzbG+kOvhN#AzEySxS{e}%5KWW`N$DdwJ%1^osjWcg)zHzweKNnGdE||jA&)(x zGkx`sB=Tz84w~c-%SnksT6R3wwnd5Wy=&8nib~9}Om0nZ9c|Rd_)nS(yV8-dHbm5W z;DoIsDX}ZUH3Lcp!&g z)fkx0=R&S=Xl3F-T@11hPo8sIedz#QFAoT~UogemsG>0u;fUQ`gGA4YvTx=lve)Tg zt|MfXnogVF7-rl6eS{@t#0S`4fC)HO6ry_%60Sq})SGDaDcK{BHfy3i3y93}<2Cx7 zxE{bsUj3A&i3|ui2IVq8cnX0gqk>c1`IRkfFuI|kk?Otb*6Gb=F?H=S15r_E)9HfI z`bG`Z0`6}|*0WnhRDImM@~B_~nfWJ3H(6(GK^)tpH{IHRtx`h`o<5SCFC!!)V42_QktIM-8|f)Z^qwo2=@(dAfW=e0&gKd7Y~Ly_?tr zF)Z!Hyoloq|4aib>3Hy1X`?`wO*$wum6k+}C{o$uXs0Jz`&;CBqB<0SXUB^>Z(ca!Yex$TB>As{XP z&TW3;^qS1I#M2Shn$g|jFQtFZ(kgsIp~`oo#rrh#N&7jWx!K<PhB1>rF;h(*|5>xPZj)?*9!q2PO zodBW!B|el?&qB`zo8`aJ9*Xbs2!FkcDaaHNAUH=`f{+`32hckf0i&C4|op3IgwkE*3) z&kVtW7rNHc03p<$)yn5a4G3@JCH>lz*#}x8HLiI>uA(jdaqPgEq>1WOXl;sx?1NL& z)KtOB|4eG}i)B;Hfm&R1+OZa=*C$U}U{D)$2vYS8ZhEnbWA;Cdy!`zlpFY#1MYn7d z$XdX~|41rsQXqI7X2qWvFQbkMl?QnvFa*B^%l@QYo28G>R(`t@C(97ooJlyJH+$Iv z?SY@5{M*Ko$w}3f$C4U$ckeZz1FH$^#Tdf^NZ^|3{reFSs!sbigF^tN0n{>GUphm{ zD%=^Y+{$!shu$l}KsZ$1VoeKPy@C`M9|i^lK$bA%L@UDK%ezu?VrEDUewMI=%$?)e z%cPvU*k9o#SDj`>^SJMkiWGl+V?*r6dXV46Wf`X{FsddsZxyH}|TJ(=YJ7*gkPf=0|{4IXDeEF=A^vU$6M?`%Z8a;Q08L6e^tzMrkBPtu)2 z#J)hM%|rkVo!JSZ3s|`2nJ$UXMv@{Cba9XtTz4QZUI5J9{e;$MT6Y4~Q6BUZB%f+; zRYGbcAfmAJp?A5OoG%Y>x#wQ~j8`t%@W$TYV&3#^c&O=UYwM72*5SfSx;0Xklih0r zH8QE zWmf??*t8Y;#?TUgpA{g~dfBl#;3oYP3aN~_z3tF*>DzZb z<8K#-So`0#l7n9oT5EiHncA*(NgRq~?=Qfg2j+n2SU2QP8nxIK!Ir~Kh_+;A6qopT ziiD<)bxFDF({&tWe6tgLKl zmz73N!lfox{#zBs8x%nrP}qjiwVLq3gCq8&E6$`dj_qPT^)j%UnI#LNL$ly#`)4Er z)0(TJ@t5stW@imPv{tQ3h{esX`+$ouSX?@T*lv2Dn5=74K!6awX+ujTnyEpZM+m6| zc?|GxA_8F&NENN?i+`)gBG=HSCH02N8oZBZ*c=^PydV~gS5>7q4p-KVn`MzVYXF)h z5WEDN4clVn<&w~vW6BY2F!OH586DSY;y;~1<;^CBnCX)%Pr&y}Lir{KXW0Mt9z2PX ztH|`KB3v}lw;|~=03Y2QwQQ`<5uHOS2|7+Q{^VZWvWHpQVU1?}3m?@G5p4T@;4;7p z_w%^{6-T?r_60A@<5|Y@Rm?fro*Z6{{Uegl>hj=)G=ia!mtwiqLrmM_Q{nD{(3vj( zyzINcck^2m9Bv#poNZ$N)7Il6HFFkmg!;LN<@HqU;rg5JL9K%HH!>$6JwX60%81X7;hl-g|S9?bsaq@Vk7zx8L<=-AFI5^Lky^ zU1rp@Y|YoM%+NM;Tk4Apvg#K^FL{Pp#hrau9diFG`D1wd zE|Fqczr|qimw}~SAZ(Mx3V)QvWK~Wx9-hY-<<#yUl)m}W_LAqis&oM(&kAAkBah~c zhcE>s4Ma!dIH%4$CaB1jO~(X-m1r!Rd37|R*j`bSe<@8Al=mqPbR0!@h+p$E%fVtB zVp(3>u;0oDlD?~0lQbPEpWw8T!8j$dC$7(vHc%L22x_jAW zTCj>jro{eEJYCK5#dD9bS4s~q306wuq5VsLFd+!>kLSv0Urkjp$!m+6Opl;(QUTnE z2xf-dU3q9N<(?hZaa6AOUPRytuTlC%(pp05n{L*;2=it_s{3!KiF9l`#xCDi8gd!9 z{;wV1ac#}OBRdPM!?mFtA<4&qEp&L4+Yo`Yz04C$M=w6i08e?NYN95(wVp$bWc~)!BSbrhQ)@wcc9)owL?SR3;Z|He#EW{G^!Qx50R~){U^0DbSE4NQbD5=calUDydhdd(neK zffl2^eFRcH;A0j{K=WpA+`tTbW=tKLqZ`q2Q<1#C50ruI%B&*R6@Bap*8jud3*#T| zvt7HJP0DV)xgE+ActswseFJ}6Szj}c*d#8sA-4BBpkh~%yz9Kh%0m$_!yg$aXt}skv)#o?n_afB`XR5vBdig7rasm zeQ|$&c1c?-VhaOb^4GoP1iO~vva)jlGC1@#XAp@X!&9%hU@MXJ)eEz6OwWCV?@l)b ze8j}l#Q$!vF_m`fPp&VT6a?-c-ACggbVDx}L${CnUL)4h>FJf(0TVka{_x90+~~#| z^|qxilomeBs*L#n!1lva9IjzyHJBqI6-6Wg)jUuM`KM?92>}s0;;efb`#Y2Qm-Sbn5vIuy5&vb1$5#4T?Icb`L?f)!n<=b^^Cb z>%J+)4v+_HRjyhVxVwK~JZ_Nm+wJTB=d*&40twKLFh)DrmV8j%u>Th#sPn@q`l3Q5 zv>nKUP!bV#&imb!J1Q~C@gEdsB?N|ea6GSNkk|K?SijIB=;o#Fzw?=gW#G39m;Lx| zWYKDo!0l&trX%QwILL@!_5um_WG7h&McK;LX;8zi5!&V6zhE01>J zARVvq_*YkR_2Ex2$_{4I3a8No(~@7ZXJx_v`v^0;nJHC^8El zo`Oii4d;+AfTg^Q{$40sO5_Vj<8kHC5Z0eUJvKWBSE~~GLyS4`DnmD}x+-QY8S)?& z_U1P0N0Icc3@MzTaqWT!4Kn(6R5WW48FcZUe$95CG@A28G4xiL$+t z;Q6;LkBGKx+H`A7s8TY2eUWQ9)XA(q6E*7*lf^<8DQ^;>_f+Nx*}63LbDoS}%(n8! z2;>iQ$Ga^BtjIkg8VWg&P9_PN8oA$cDlcuGsXN&R<`_S6&{y!^=7Kt|U=JYk`2bz|+&*4YuvJJ*xz z9|CfADgsA!3Ht0Z!kCpvW8%hW@wSw(R6&9vA{k;ILzpwv$U)nAWTgH0BBWG*+w&oA zd_PmV!ocY!cjI+?`{t{aQHVzlqsN_t7)?Ut__?tG^_6hba}9B#pzTm{PqxoRZLreX zfz@2oxUUbo+)bOUkI*woe%X)> zY(^iOg_+J#3^7ffq(NtG;ftk>o|Pn!QycrF_-{i+GuQXd2! zTvF@^G34P)_vybFL+}gVECT)~H!I5z3ubg5Va=OhDf7K6K0~EnVX_V7%YX3s{n-Ua zu^PCCHCJLhF`h70T`^u~80IowP5nuZXJVp@!}kN}?sP*pNR11`LE9Sn1Sbe}WfL8K z?(qghZK7F+3&g$1OOb}w%r3|kxg~nMtzj%1o9g>o66e*3nKV_v0BBzV)A`yhXLTdz z2QM2mo;NpCg)kn z^$|wWnLNrtr7$V(O&8QevWe{}-0&x@%G*6QbE z%4bf~X!GjT))WU38eB-P#9H4xHEfl#o7X|@*Lwr*+!0W>CgHue z#FUfG6uD`_DZ-l~DFQh?pD3FhTK?YCcDU->o%?w#lAf^h;Zw|!jUh4i3VtBe0MRQn zfnWHSU-v<6u?GGu7=7%Z^zC*8awH6q%1Wc?INPiks!q5|4}I|X;Bk%&z(J*A+}27_ z=O|;=*Z~}i-$E&0^Xl~52KW13r#dl`jZ-Je2I*%OC*g$f#?OCEA63$2$N zOZunL4&14KR}|*+Q~2EfMvH>1{3U&1MQVBdbx_z{;%Dh90RBzyGW~`?6P3QfZzngh_PD|6-zHxjAC)an=H=hrK5H#hh1L4eGaZ89n`AwN|+)|nuf2==fe*FCFt-QFaO0W zVmNF^_|!&lB(%sak7k}_zFl>&?cQGXL3Dt^Rpkeel*qNRQl{=vu(0XZ! zRYoTcv>-Hij$W05iZUo5s%vU)RCHd=aWU(NMaim!jc#9_ zExtp*nj^MR!FE#{XHnglxF zjut!y&l_XCSf6*-a)iD>f0%&JR?5yltVr*dtKC-_CFN3+q9tTtT9W)DAXjsZYOsh~ zg76ysCAZx0)B0(y3Q7AZY}gc)HJZqm^X^q)W9{%=-n7tv5?_yHQSrYjqBe^*iz}nJ z?!WueW@Oi7OeU7w$$qDENc!2wR90VK8fn>48$rRO8ncS1^H*`TFa87H+>nNjJ0SuG zJ5%i@8UZRL+S_APT-_;qz8N?A#i_(K{*R>PwB%dMB*MO2>+yZQoa>2^Ce@`# z<3b!q`6hiACb1{R<0wBxadTSR?nLORv z&IOSN&#Hi&8cP}g+Ld&g8b@A*%I$9I7LBkWMTcvc_DzsGaymFi zj-+}!+Rg2qzb%m{W#biQXejMI0!+Ac1TDrw8k_d@X!pK%mU_|WU)z1-6C9#m zw@E__D6O7qj1g|^%R>tSAipLAXJ@s0$TL0aHS#aJT>kD_>`hKK=S4w8Ukao$Nc(;J zB;#O96rC4yq$U;CW-oMun11+E_O`Q=!-}h?cysHAp0~W=`0sM?(@e13u{4bMrTX`8 zM=Km9-5fJpKlr_PQ~7y!t@7Cu4F_@rZ{gwGRe+cIRAs<7PHh_I4a;zKVVFvlspoFE z{4O>(X6go^Bk8N%>yXg6_iAGbJe*Fa2Ke6#-5J8^9Wn>wtG=qn+k2-=Y;3iLY|Vyg zTalEdD)>;bj}f*$-56N2JhVcax5{|or(f#S)^@wZVUd}W4qf0p=@Htw!fz+Q3rHo8^eF&x1A0JUwk`30etD4%g&Zo;Sbmx5YbM zjt4Oz&=+6--;#NH^$gUIw-89pa^RQn!Pqq5&`Jn>g41f|dC`jdqy9rnlH1j&=E3fJ z2v3HmUj)9`1J`lmG2s-4k~BjFk{F@!UE@z8J9Y?EH~rvioEhRQ$>2KXGNrWa|Eq?u zOEjMbN~-_iYmz^2SyKw`mCt5Kla+$&yPnh1(g$&SAoF5n(8@|3N>ATX$WN5{4R5(y z26S8%C%!Z?xrp@b#FTf^KQrt!$$JwVMn#WAse7BvG`iwRqBH#d+jJ<tx!y<4`V?L{#GDQlrZw6L|!MKUS-C5fJmgj)!-X-7f8&8=`RRI(&^;i;TKn%wqO#fHa-GW?ejC zV=loYfdCRGA%vQjgeJ+B?e79eytVXKbaRId&6?|cB9fcNRN_xr5qAI5W# zA-;Qb^O?xYw7Eq3bkpPcbwfrNASkh~nDMF!>sEv@1jS=IVMp^Vsab4-o__sR&Y(Bz z$*@WB>notb^=TJCR8;<#_$%%sVf}zv?m;fp>ROUcHZ~SHIQF z9A4?vjj@F}aS1?u7kX)rk~G=-TR+Sg6+jG|7{jNw&6Yp*$sgJEHQd*DXhHa?jUV%O zw_`L_ov`}LPdP|{7qw*D@?vhe5$9U8pL7JBo4yf&QJ6$jFPOByY0B;BSmXzw2dbV~22iZmyvN@hNnh}#1IM&dn;V=Cz!yy`UIqZK z6{K9xz60I1t6}!=foVF(3v@s)FW0)*f-)_3M!z#t3V_ekCe(@p=v&Ftm9$o2Dc zv#^DubA{`k@xhvDoQ0)1jhrqvJJQ5H+V6rFoRb$d6ghtOg_ID}q^4$0n>!GQ0_Qc^ zV*F=Sme0vQXc67R!sn&p<-comS(!gM%3O1W$jRxVTx`41Zx0d1wf}8x+u0R-86%46 z%kD68^5J_Z6aIqSI$j}Jw=L|oAzk;5D+_r>iriNh*pHMHnrMnJa>Up{1-frr=zZZm zF*QaPR+n)3H&`Q+j!r0SJwD!AhRqbk<%3$a%3AQmx!em?PylUt0D=Dcb=uQb;{RF} zPjLM9f|z+gb;7{4k261@#4kMOUBi6dzR5b~-f2z~2SRSKM4+Nlu2LI#j-3tM4eNS^ zP-@#C!EH4>1P%-_e|;%|b~AvqyIC#eVP(2&Bv;#`(l?K*S%qM;r1dt#BjcF#$G?TR z>_4RG@=n6W3=VY$0&d1_`Y-Q@ob&o`$G>z2(CEWF={Bq_CiRtJvAw4g*+P#=db%pd z6X^jG)ASw|Ll%J&V(J)`E^BdkPniwWzX4&gD>;0jkDi_VD*YSfYOink?fXh*MR(Dw zi(D-!C3H=ETj_Vpf=z4|E}(Xi@EaMulp6xprL;7Ag$=Rgp5JL=D?oiCR1^||NS%Gx z&@-mW(Bvqh$RJ}*#Hn$ANXebB+Ap^;>|qrTetwnn)~ziVeqI zb?oVqZbY|JLJ#X1L#&aiDyzEA0ip6l-jp8h*1sX|<#v3Sm+kyoi;qgdeM(wZ$!I-v z6a)Xug-C36XMTg^Q-tL4`1?j_xgEQbD7E5bCIa;;yLfb`tJ=+`;Fs;1sE!ff*#uVOP8ZTNJ zqCoV!4$#Jo(N!B;I_%z&eo)wImeR%O$eCN zG2UhiZAb2YJ`qd7c>lK58L9SnbjHrxXhu6*)POlKQxT=mp5)zWC8jcrqw#+V*h4>$U@JHUhBsP~X%uCgfsWeY(AXRo614%N5u%_`tj?9`2 zZW-zs9qrJQ6(=&bItnt7xUPpx)y~aHG{Hr++ILSbKnd{v&2m}6;{v**^w|sPTdB-@ zep!&cgpv;}1O%P>$}hy=h*}Ltfrp=v$b9~EDWl!2QR2%;n45##e?v=jAkw?0k7Tv~ zE>r#nQnI`+L^PQ&U^i-xqEXKyUjmj@nir_bQgtUq4YBCBe=^s;S7%*a?sN;G(zA0w zwI#xfesA_4)KPLExFsmPlQZK5qOso3b@j$OCcgU#fvJ7Bs-W^z*7>7_%&pDFZ z5yl^tWPG~7!#A@HUJwnw1z&E2h^$agFX5ERDG2z*xmT!*Or5vO^8%T>{@hkf@);h# zbjASZ9f+C)1<`|eNI+AcHq+2|3z`v)Yjjg|w0UQZRwu;r_oBz+$2Lz0Y46(H;ujzx z7tPT)6MG<|y6o?@WAR&xso5zYzAvPOCYzCvncr#qvgK3al6j$r>z#$Yn6;L7kUYWo zsX07y+-h;kzv{=PBINJ|KrXV>#og`$Yc}n>+^`@EKh^T zP!j1=18DO(ZE2Nly1QBZ`50vE8N@%vwOQN)<@x2UIb>$i-`X-NsqMeU+h#V2IEG`~ z`pbf}>_NWh$C5<%xQU{rHr*W^peiaNX%Zz&`LGD$Jo5E&OhSYsRLKrYTuv}a$MTfS0{M$voMJA=l0jxeL z!jBSaMInV_8x{H>bE|5J#F`sY(!#h?Dp3O|FdzykE)1fsP$mJXq_^?F`P3wyMmU)G_3PKh^S7xbyos*&LdI^^+owDQZ~fP;u)h*z=P;0o z=a44BVm9>?2sZF*FevfgdtO^#L#WQZ z;+m3jqlZgWX60i0+&d)xU(?&utXT(d2#K9dJBZl>pzF+LLep7@AV2^Y^_HY z)WWYVt4ADN{y%(8(6BM)tSBZJ~*b`(i8T$%>wn5Uw$w`pFqN zvwGU577@-H94Jq8uJC(fI3`c+!Vl>54Za&k$3o42g8H=4vGkN>Guy}DH4XZqyjN*| z-HqgEIIqWIuH1^qRHF8JgLQo?FHUz5wS+@MI=x$l93 z4J{>h@FX%Swx=?E2bDYS=(rzcMuAu&6zQyP0s(N2Zlk;d$0?rG@0wgq2e$82=5p1& z5(^tu=p@zVFHk!>|5y<{E12vqVp6jP+01qDSqF{qTu87<`} zaGqg+Uj-B?W$K{SH`xEui6lR?MX}BMgm-mMgO;be?CoYQ72;aq+S*Sd4ga*KX?7-D z9?C;iQr%emJn$Cu4bTgv0*#N7;@1ou`t^8p`J@u%T5@|lT#ddTgF)Wftmu=cQedEG z5_q4*w3ei_(z3F@5AYQBYdUcDwtoLv_ya}EJnp;IVXQ8>HKiAwX9#Lry-_PLZ_JpM zEu1bZ-*3> zN`&n_8S)q9)sdvQJ9(<_h%|m{7!b_b-eY_7^TvQip*L~=cC~?&awGBqpou0XLahK< zBEz>h0M%Wja?`GVagn`Np8?SlN4P$6oeBFDy^`(ac}2>qms&~9xbBI=@zobazcf_1 z98|PkeUl;dgRp^ROLTDsR!Jb~O$IaRZ9cE2=6|KXL7-=MpEA5}%~aYOu~NWmDAN?H zaevd1V09YPnLt9Ne=Ueqg}WK#Ui>o3Gn}t^wHx}TC1Tv?2qm49iU(gCNfun6Z}1>q zYd{@xSE8MDi-20ZCe1{2|Nc8$CFyZF&deJZ(|}|sdL}3ObGqXLJY{m+EJJz3{b=(K z>SB=;a{H%U`*GYT5Kj@6jz+H&^QHD$4p`lfa;8~ux)w?{)XgsnHgZ~+npDgKpBlyQ zS_j^cfcq?s&_ct&q0abD~lEJRFZ1So%TpUQ$Lz#`SRGGO1GKA>R%6 zoPr`Lr6@3|%YP)=8-WQ=tET_>R@ZWvnoLW)_Ewz>%gq;<=&DzpuDaIF?myu!2Hn-w zI=pMHU0}Y79iOB*SNQ@-Xq*RyQ^A5_pEr3|=;+AqJCS&2;Ch}z@`Pj@Nn-4vE)5XF zbK=U30XCAbHvZQ0J@THhq2p7UK0&R1#VPf{Uw>q#qsm;yoSHXOGgVzT?tJTWoXsC# zcc?I&|CbG#*M@he}V(3 z58_bi+#v9rM$|CS$VqrD-OH|N**M~VIoNkx_YdTIdTwsy87I3?+o3DYjH3(87qyX1 z@wCTj?XzwBF1YLGT`P1r@_jJA9DK;iK7XDnoFkYr01S&34S3lgCl^oR0p?57k?Z4U zjXB3yzc5P6dOnG0ZbAIU&$T1&07tt^5BwtUH8s7N=q*DX>;3e9d-P+RJs)g6IKP7 zOz~Z#iD?==Q|x4LAl`7^u_h$Mr-+%^=9HTUbs%Hg^3msq132GDHjXOoyis-&t)9R2 z^4#o6UR?sWoV`#<;u3tK(7aMCjggFw&X5An**F(f}#G9!aNwS^XitZc&{$6?}Bb53p-Luk-W;qi^akNUF57 zAX~?9vESnZ$Vt3fR5TRqfoSOk&GI*%nHJBtlt`(0dd570JCU*7=HTE@OzysIR69(V zJNl|@YR?aMmO^#3Fx~ZL}JXtczmKE9&54WNB-5JD39#M1y3pf3f|02u`4O@BXzsnHA{{Giebo^PqL+Tbad zdk41Su8%7LfB%UxKVCr+JWz3H8`_46F3pT)*YsDVtity45-} za>h$I{f6SgJdw=qc?1nYAN>9N{4V!9T&{j%e%~av9+Vl<_04O;__f!Nfly$Zrg>kS zNKj7SKQplG98B2koBL~e@Me+6ag1?SX^@?vP^k3u^VJvlCsPAa5$t#56$h4~ywGaF z_aUKU(26IfbG)XgO;`Kx`Ek(TZnxM_xTp4gtIF{$HcpX3k=s!0GW&62)zh{0#=FE% zeWp1%IyHacO=1%CMt1dd0=G8_HkJ5X9z*!%cZTn13pNGZ-@R@NZ|%ywy_cYiV)A$Q z7Rex}@p1E_HaLR!Jy}WORD`YWgOU79PaWD5U`=1xDZxp(kF({SJVxM@usjj>6$?wXRcUP#}-% zlDwK7WM9L$8dh?{?4t>)jY~$tI36CwJeot2Nqv$B+~-gxMp}vw`eg9;l@#E$&Pd-f zh#3gbzT|!VFg_s92U%BFcfJ6H3>?;1q}qrF1tnXU>i^nFgJ~4e3^*2t_jmp~KdJXO zvT`UbdfuR%%x_&l7I|c6d$W{$0zurexG3viO;d?~)XN$+zQ#0iMZfh| zL=yHc8wh+0E+$PixXWEa4a_--J&WG6^J6oeLUIvLJ(3v=61|Z{#H7UgtTJC zN2|waR%TL>3Ha9$Dg);;MH(P}2!zG~$vdEnC3a*b@R>i_^z5M_teyH?i2zj8x(Qx8EKi{iV2nF zP4v5_H+R$7RQSEMeI6ap>ER}#-q7fN3tJl=zApO1=T7*W$Iyn80mI`ftF^EpA8u@# zENaAti1Mor%@OM4_j{ZmSq-rTK zDK}INsrxo0peD@9beDY)OE=5>NrzE*OK`E9g@wg3fb7wLYjE|Kde7@wR7~+(^6NkR zWx(HxoXeK&abcyFDaux!r5Y|0DD;&?WTYIPfo>@**0A3Shl}#(n5T@JK*dc=!K9wB zw4$Qo=%OjQ`Epj2j=1uK3s8Okw^;b+Q9>mWI*$swk8;xIduyIB3{LI8*Ep1-{T^<) z>};PZ?qV!>@fIzb7!OQ1(qgh|gQ#>*-=(FM0~F)C zGbPdE0OGCroE^+KTDo|dWrAS2;v{A1oeoi&wwP=<$?GuODA)OiiBf6ph=G%NX%PtI zbTlufP-aFsccA3E@KM9i`I^$T4kM>ek0fmc*YLuuXz$7dk&jMYKTscUFz_bVby`13 z+Z=LPS3Pq$&kFMRJN)4Ks6!Lq2e{1u#v_y>*;ULdiRv9xmSn^z;jwTeH~N7J;Q$GtLOGY#(#2T^8j1eMeF}=DWR#=?fz%o{I4-y2uu;sNbJ;@n3dnbqv^^9(wb* z`Ahi^`uBko?`y2*f4?L`9C_!kJ7W~?5M#}wBcpKuBQyNa+L|zs(^bMj+tXZh0a!X+ zd22MRk=mU|i5RkvKlBHSR%@}0SvRUq2C|k~fB82(f4zw4ta-IzwbKEv583DF$ z+uqR(S?!pW$7t?Yrwn8lAT(Q7=tjsxp$rCG`aY#l>85{UAd@phocn zU`v2lj33I8AYTjArjL^iK2(?mL1<9)3ydMAmUz28|FUVii{;_^#LeqcnyP0v*5)CK zt76WR0CLwz+S0A2!(*7#O@K|QT$GA(~aZj;A6Ksc-(D`KQ>ff=|;uG z{M}#Ak&`@wbN>*{iwNvNg)Tc<3`d?ZEf*@0L!5y_9^$d($*YYCJ^WVmI6sQU_S(T-|svN zB36mKEXt?Jf>|-l%;MrOJ`6gJds&~|=}4Iwfe+)Jk*~eXxOz$_dj#`%$iT03?0Il~ zz~5rsi7aRRFdx>}q$NvZT0KGSGEB@dkVcGq;Dhi&P0hV#hluo}-!2uaYf*|s(cgbb zwl|`dqflPeFXQ0o;*eq8&;>LId+kOZeLSx1LTrW%lZ3xWXMr`9kFvf!MV6}|LpeELG4 z`)#52BLwrp-M3uK5Vc&~KaK>7x!snt|Gb_%i@<`Wzd-%2#tsI;(5Chz9UDhB47-|n z&J1>PW0)V_gV@YL4EBF3zJS__7OsCQ6;9hMST4d5Y(*2(AU|twzu+0r_?GkL7zcLA z<)Y$+Of@w7TIi{HMXuje1uBK-V~R-lx#f2w!3)cFk!Qmt+I``ky*gkD?Sh0B1MoOz zb1eSiRaOna4EOB@GTjrcJpW0h%;DxuxEC5IB93ed92R83`>BNZ)@?(f?jch8pn=hO z1uGvoL2#M?t&uWSt^M=mk&5VQdr++yGp9ywig3=GaJ&WTrpY-{T+pW@x^uR+GNC58 zRJ4ShuHYXY zsah^RYxjZ4=*o1(b8{ePwDD?w$id)E1AX{O8TcmIeHVE`dxP{!V0p(qezFHusM_3t>B8NY>JF%9xto?js@@ zIiL5V)$l++I25&?bD>x836UzX>`KAd*P9`~7CF3Y`@4S1r^wT|$P-y<5;;py>52Iz z7VVg!w35Z9IOQrufCa%K7vpfNUYLsTC`I zF@?PV<^;b@O`)0Vi$I9U6%b4Y!qfNSC+2j|o|^p$JTWq7^vGp!wH&Das$ghxCYXEn z19;Fqsq}U$U5689+O}7ESMsQlz~NjmE3IE6F_@_*w4|I0mSRz<(@P+1&i2?2<=6F&@d0fv(Jgsk;=tbV(U_ z=?ARi9alS!O*|4NP8vChmX?yL(uD+^w)FMoK7bT@SS;I_$e9*Xo9RK6U(G6Pv>U)m&z5Oj$twH-yn$-xSPdk6rgKG4Tv-l=(bf9<*Nglx z)buFz2KKuX0FG&Jeabqdd}3Z^$|X)~HfXISZDLC*^`e_&?xwi(sl5^1L1Bdz-J1#< z!+b-gNH-vDC~6|<-Y!J`FsmTWbicDeN~C944U=hKMVSbYGrE6Gm^%&bZ!Z&+&Dy4< zdsy-z^PkIgqo?npbFQl&$-@4my@py)?EAHyIb9OS0_drGA~fSxOx^j&cQ*3lUuDbp z1ftt(tNbnFJf_Ax+4>hcfgab5J$R*co6eU*OwdVtHnsz))g7N5dOe*v$C8s?T7=g; z-f8tU6~Md~gPxNn{L}I3uZg>Jpd#etBJwn;QetzrDOv^_tFRnY_f^1@>Q?I2^~T%M zJ>-P)cmKYiws30fl|9wMoYx9Y#v^cePkG7wRgt-rj#28C`z_O-P`6rf?lco{E#X1& z#+k*rrQZ@#P!X(3E3^5t3=R)DQy|Ej9c)^5M+4R1=Kg6R)E^T2F{5gE@hfb7`gpWh zdEm+lf){B3F5dSM!p;#Jicb^pb|h&tsXi}UI;}chCW)3Ee+^Faia}81XcTjV7?S)!T(GJ4C>0%OtRUZb<$>4@@CuZ^0|n7JvogTl zTTnLnmQf;1GlpZ*;L%xP-1Z`7rg{i*G$?m^M8g>rPv+p1z-d(LXVB0)kn_hnkg1l5 zgCk~pj*CWDZ~r3vCBo#&HBdSQ&sk*Fv6izAoL;M{U#iumc8pnXJj!8NvU;eVcJxKK z@bqr83MimjoN{-6*CO@xR;y@|3Wl%uRx>$0Co*|I)k7{pM6gk=`<*V=f;+^jPz zT2*`s8F#w|Pkaag{VvHr5!W;tpnN~U|1yQCK)*B__o;;3Q0~?r=Cy-k9so6-AGN+H zn-mer5nFo^H_kQaH16i;+29Vd2dbca;EIwYL7nj(QJZU&59ggSUC7nM_2;(6<7bd) zPD*{lr(`lI4N?GQF)_Uh)YAC)b-nA~(m0=9IL@7)Tr)0^UGHt_sWjws(vK477wlXv zv;Td~9V{%M!4#O?)L2Wkr|qPsTst_kbA6q?x_2HG9d;44*W&F3m}O0KicREe@|_CYY7Yd`FupR{qX)9B0t$BNwRAS5VVQlL^wO{L%u{09VqW{{mlOCyxUKI64PSiEceG5l9 z-P~ApyYRX(83C@X6GQ3Oot`*lj&tH(Jv@)KQm4oLEN#Zx1%E6CREvv59xUpZ8$GktplZloSi)17? zvMKC2D4!@)MSZ^tguk=?SS3uHZ?Gb&b8f;D!Z@y(R~l8TaT{rDdbOHD*n7RRE0F9I zNH3{jg>$GK^EcUus&oijrptet7f7@R8h;Ld%$KAR7hCeP)Ou5N9ZOyAEy&ENo9{@x zjUut(!Fy2`XiZ2;PB}DeEuN=(=66#il^v?_3PiI!y%Nx=6Y${_ql}ctyEfwz+j%Ep zZ(`v!x#?TLC*HHx#^7@>I}wt)cKC09nI+FtTr?n9MQCQ{@VMu&*%^XNS0%z(x0fwL zZ)8&&0EbZbVNQ;PKyoh-6b!!8Jm&q0<6dNEY|z3T&BjJZ@=Yfy(q{)#<@Du?qZf78 z0^y!@hC*XtwNr-~6>;4V_`&UW!Nx!8GEtrBjM%ftxGy-0~I-FzFxbouLQ{QbRP3jH6l08 zV`=XNSL{Xx46rNuqdCPdE?GWSsd_BXzYn{`>?#svl!DjT`HgG4be_>|7sYp|6)u6749yqu10> zt=B0czMDBP;rMK}G=LVlJ11uBPc}I9!8)M6E-Me)xS*b9@ZhBm7~yICO>J5--#)go znsq$OH12Io9-HC6MhDB<2i;l@T+M|QrZ`m%Swq06p8&49nNZJ-7p z3LYWhXIWVGyzp~#gUsJx<(HOR8O@7gyx@%@w;`r>kJ211P|tiLt%60qZ^A^RicbRR z@tQP2{JH>FotwqCDlUf8=ytPCp;l8 zkW1<7_a0;0?H3iL&6GphT;Je`;d!hP&+*X+M1pVN zR?!$eD_*?^F&lRT4DEQ!gYy>twkNE&uR>VJs@krsR(T?0+SORe!o>>a@mm&!#5A;` zc2}bng!}HU#+XjDw1>SK05@^$qzLJ`NCDIx!sC^*y2!eJ0bMTFs6>1`GGNYZoh}|Y z%sV-emkfjtl-GUEk!R_bzh(+sb_LIg?HQpN=`+p-vSwsf>Kj2xXJlxo^o1V6#_KpG z_y{50D;;8_h7lpSYAVd+f<#B4B;t{{_-%r(YK3e5P6PGp^0y-$y^Br!pT&AFQ$U`_ zoG{p7Ts*157ag25RpHhBP99}bgHHb5x@xyQkNuY}$5-0dvzdMe+8-}BvLR&+M?$F~32UBD0575w%QoYLXh)YS89 zWJhq;@9oC-R`b~z5%3%Cd9`Ht0!I8~sQ zGIcu8Je0@hTk!#Y(q2n-Q@d(xIO~#E|E#FGQB+7ES@ed1HbBja1$R( zFJW@)RD0m#dNqEu8smjN1YW-9MQ<{9!M^`LhlU+b0B-XkGDFQ+1M~4F*B( z(oK2E_Lpg9zw<2c?6k{j08Kn zbOar}^6QS>@~*^JR_Xi$HuAktqGH23z(=y`BD|blEn8K+eN1gk&c+yV3{t)5wzb|) z%@KbH3jK`pU)##xx;3SnxZ6gBz(XTxADX`UC}Wy?R6qN7$mlsaRA^*&m6>}#gbh)L zFd~XW8H%<34vxwomLf{4mD@JH5UfYWHCLiB4;?(L^BFVI&q&C{Pq7yX-I{7oUS`eQ zI|Vxl5r4XcKfy2lD&~ua&8uOC#$eURYh#V?pTrW8#~!Cxp%m@UDh?V5%KRSak@lMV z?-&;j`!tKC)(?@=;BEcilXpu_-$3pyRN@Q!f)RItPerTmn}R(FNQWMezEa)voF@Ky z`;JdulycsaU?ED4lfXxn)lC_F`aHl9IUl&g;Jc$A_;@wRVi)zAo&Rm?B+c-Yc^N#e z(l~i{cul*o5&6}-fo8Lq{l@k~1)J~03j0buVeTsq-QZK1l(>0D-Q`fBqk2pRB1r{Y zWgHVYSlhQzvt8EK)guMQQNLzPw2{d5TOPLb@A7x;utaV(1=v;NATG?{hxS zhcoBwv-eu-stY@l?;4y`ksC*IH^Gy(_eirt3})rITPsK=hob#$v(7J_5^VxvFjB3eiT}Q2Tq*z; zWz6|OG?x~@HQWSGRd&k*9%ipS!ao1VCRy?{>K}>gcD>>Oav-k2SA;170#312jrF$A zI(hRahlhib2W_?2nhJGXGHtqV_j)K+2H*+X6!sY@e}i$JFyrU&zMm-IvaZ#22mgC3 zx7=04p{^$f2jIcBjZ4eqyFT@b1sX(LF_hSZgt!>BiD*9)JfZ&{!s4w)QP*8JTp2&S zrrAh)2(lD1JH6!uCOntewe+I9HZji8k{}0eqWZ~i z-)s9AUy=9y?~gc7>h5@hM?NYMak1^x*_NKzTB5kWjI61Ds_)?zd7k>U-`2zW)9|42 zcOw;I%2ZiuD?+J*vnMWJwU-uM5>VZLD!!CU!lAnN+<9Y9l7b%v3a*bz*^o2K>+xUk zQoo++#us4V-jvQ9|2#w4z)P@3Z0o_cTcz8ZSviIK;RYW5k$Y}m_@~#TX5td>rLDPfcCZ-BZm)0Bt7=TDTiHFR=|*NVAG;JYFrJm0EZgVSLZ%$s%?Z98O<0gq@YBD zm-lcdkW8F!ZQozZ4Ty4TM<6V;@nqaUx!6%nobFd2{rHHL41u{iP*03Izke*0o?IH1 zQ2Gd{@XQ}~fH@)MHqj_m`UP^wWwtub`U}XEBZ$^9eR#MJdxF*Pd^=KE@T#__9HDx@ zw9?SFwxDpI07$*=ZLIH&Qg3*dij~CZW>C2jX!U^yoi}hsVVpH)XF%w~d-~>5zsJoO zGOGg@9FJhfN?_|l71pM}pd$BugEjNdS1t2XRtR2$+n*AXQ~`vFE{L0FahATB zgE*m-e*i%;X#t@aw_dfPWsQmRzgJZ{iJwzVHEbT74_fsp2z{?h#$W-Ko^FZj*wmKM z!8x&4>27M;iEk`9W&Zx~$Tc#PCdAP=i1OI9X3cjb3vtEph%un(P+LM(mHsZUYV<^R zoP*|>uVa|Bk6YHV@#g6Qc;ejmO^BM_6UIHmCAap3U6%qHpKnGzqj=JGc3Ug06-MTW1L!bZAT{{oGH~o0ik<$t2u6` ziO&^#)`4oTLW>9W*RCW#CFKf7FDdTj;@G_K zntViO%!~b*W3yec|MxcWKzvvh{QHGyriv9^&Jtno{5~O;6tgBL%s%!7zgT=@!}WB& z{Pgk6YqtN0#%g`#AXeTDdbd}jSazJAj8YS)w|~qaFJ6Gq85yZ6$gnlr63 z!e_%tO3Khdi&~}!o5bTA)rh)DL2)J*3FbKqw^|6!2qcPCX)shSs<*5G5-!jzcK zP}~b7K1<2rC|+O&Q_#q}MJ!*>Oyo%*iYi}9LqKdn_}bcX(80CGyMXKM%1UIw{6_fGUw?jBq)G$d@t56AsplD!VdBTDb?&ZUP01A`t@c^FPO@#^R( z-tRYDh#8TW*fd@C0-46|FuYIt`<0}LM@tFLcL-D^Xe+boS*m333n}bavUS;>K+BQV ziEv@US&9P1XVG#)(z>A=wKQic8=mR>CRl%ki(85CS-~y+|HrYia@t&&V&Fvly2wM) zA?AMw)U&)iGj)zgt=%1Qnp-cnf+Py3J2QJSZYYurFEHv=eqJ%rr}27tR(jTmd4+L+ z9i9tf2Cs(H{y^S9ENIylx!X<#FBz}va|^uYqjWXkr!^G6-}VzSqD^tEY3=Hg30X@N z{|9#1f5)pjv9CrHKQ*Ujc~r~7ni0tEGfGUUInZ93O(1vC(YE%aE!L)3))K)K(f}e( zGU51whAVl)RT05y?yeuG?-F9#l0rrm{_T=o3KI6Dus-cV&1wNF^5Ie^eg!|dbI98dv@Gn zupSGzKKv%e!umM*nQVoV2hHd67pG1>u0UZ5los~dcMjl7)eo0MOCE57=d|x-rU|?K^%>O z9ZFYNzwA`uGRGA;;xMkE9d0ll% zR~BN9fwk`8t`(5=Sjx$hrhdU~c_ib~Q=&ZvKYsfuIP$r-v#-o8&_+MTYQp94a+-}e zXUB-EYD+5FMM3G+g;LR+J__59eUbi(3@TV(f7)RbJ>9A{mM8S$-Qk1=w_Yg--8#M{ z3LK+~s$9JDghc2-a%AW!0}$H5%6@a6N1Y<|bxOoD3Ylo;SXJkQwJ%-c)`Vq5X8eMnnrdUNKk92fjgz1d<4=x&L? z1O!X}mpwxzRvftFaFWFbvZ47pa9zFtQeB=RYfWQC{F=zl8%s`^=5)xMFi$gSv#Gy~<#|7JkMQ_FxAfUr>?L4)N zIP=^+osUDldDFNUbV>B!!5e3$l6T#rVGB^t2XtX?{_lH4TZ$by4{hOE628^oAR_gz zJZyfxQ;`Z3pWpGm)&rE|Ut5I%qOzU}V{+o8_kg^+)u+F^4CT-&I!XdcfuM2dJ1zy+vd_^|vb2LM4 zL+vv$JHtJtU*0KwebXJy$T-c`!8c&c_mlJ=Y{;MA?-_u?=$)`Xci#;Lpy_}U)^VTtG;HEl_OsWGaNolopoM~3_N@WXn@ZEti)FM? zsB9C=9N`&W&1MTFxrdns$tjVG86GW$j1uG!^I%W4p3gpG^RLWjC*@}IFvdXIl9xX< zsU`noA;6_}Z-fX4R_jORxmeiR;P7gG-(^oPs7aNbDZpsKHb3$g57uNe`A=InzddN< z1s)z?eE*h_xNki~ut2P#*fL^w6K^0vCoDwbHT77gwKH8Z|3O~d8Mni`h~ncQ5KF5s z>}ppF8}QU|Y`p5=wj{IS`h!Ld$$<@9;OFp3o`a0v)6?ca7{y}&l=nR6`5wxMQf|m} z9qetsYwLO2&d0o5&At7H<6--!&v-Gs%CJPueb<{nOv(z6q&Z8vkp>iRz$FMo5pB%< z21c*pYY@PM39^)LZms3_AWEG9mh4+Tiz`m5h0QLj4nwDJtExgP*29Phi4g2l15$)2 z>-Fsc2LRx&s7M$@f=p$-s3wXV40^Jg2cP_v+jL$l$3rH^^@3Wmd(l~;U^N$+kiG%r1 z4~bgmYIf+nc6=YoCNi{?tcOd&$NoX>$(7d|;HKF)T*{F}gkG_4{uow9kSgJW%nx2W ztkE^_eA_g~7W-pDT;nbXdDV?XaBMs2ZUR4Q#AE;?(NBueu=&xD@pJYh@7qX8^vh~VzpdP9?O>^# ztOd0fq0+vJL*Fm{9~WTRm4cDMRakl0S)_Ju0k$D5$RcBIg+)LFRiT&Cjba-6`d~Q+ zebQm(BD8)$((AG~MG}WL471fn-vPj+%xR@2|EeK@e{)D!?l{st8=G6xg9zx;)`V^| z*Iq$5F=i&&~-UDVl75?>d5U91Dt09+6r|M0jF+E`(`d(G3`WmXsgt`NKsal1LloQ!q(y6sz@}$jqqU zU!(&BnzMH?fJS5D*-FnV*QiSW)Fm2qOU!}L#xLy7z>QP zdv_$$ePQDkk#711QP(|U-`EvOmd&>KjJWpME@AKRCwGp5ogTc6kQqxl}( z_~pUI+Z@J z7sa=ISqd{hwePvqa17(~j&&tkU~u{Uw1tp>fFM((0DnwLKyYy5?|Y`m*9DM0&pqh4 z+Jzc6??V4K7K{pCc%n{W!}z_;y)n^|Dr(T8aa&B@?cL26Y)A)GQv7A^Oqs@3a}6A- zLO`Hh0=Yj}dDr57BhYbww?ahos|?lu@_p^KUwb4jYpR&RvmMU*mA+g4s+GT=y6^sR zLGHTSg#xa(uuc6J*NQljXV|&h-B@U_{>MR>U9=`_4vhE9V~XgJ*=2n6k!o%2WO@Lx zS+&ye<#po{ge-cph-5*9DUmRe2jV7@sdCb)TY|_^t|rms4QWixy^Lk6u$7^C@F4eW zblyGwL}OJH*{t1>vhWmLx?=}tnk_snd2miO8sp+=^ySj_ACBJ7h7TZcg3n3fAi~i0 zNS&9sZ@+vv1V|MlA|oS@#dSIHP^AEooB3PATc*UucWJ4D$Q&*&G(S;Zp^DvcKk+5o zu`Qe6kzkhQEX(rVA?yg_qdnUHT`$nw2jo@&;XV-Qv4Ii0CYB`ySzT^b?%6;U@)`l+ zd!+HdiAk};l+I|%*^eMeOcAh`Q% zC>{l4-f>-uA6M>?yjI>ctBvrJs|RFVLDIkw0fZMbh$ad6Jbp!B@tub zB5b(0T&4xY$m?jZ;~?}Q9*PXO#7h4fHmkZdzmMJyyM&P?lPUh>sF57&lF55_6*-wj8V0Va!IJyp# zzNNwadz*VGD~sI_8QFbLA(|{i3s_a&=C2kfZe!$uoi+&_K#%_&cMhZ;{Ab-YaPV?f zvTwG_V=ee4-I6%ohtf1|>)f48F)km)CqQELg;-q6(=T9#HM|KctaJ4@sxR)$?04AR z`ZukCT~d@Lbv5f!{t&fZiV^7Su{u6s2{A|3=!D(EBDcm zyYYAi?su)Wx1y*jsEq0)-STurzo+)I8k>-6XVuQkx& zf97jwzseu3l9kCqwcn7~;(G=#_ z$b(KjZbs&9g-aqQ!@{PuA#ymF&)=-5fa)K%Ak%Sm*{e=q1<25jyv<(vj&AdV4P-;8g?4u4NDTNnVtF)VIS4cV}Mj=;l&T@i|q$T1bzA2(Z=pNInmMs~11eijdgb8KqomNx|n%;rh;cY?M+u)#MF37Sk zUXGr<^LVwr@Y**_qE)~KPZTd6uE z!L|JD?Jx{QsGwl;J4oDaxvf2Z#I@JgCB&9*>lJfUd%#)Vr|%0313EV^f4#oR`5aO^ zigh@<<#loJKELC1^n+t7Vr~2I{=hMh9vf1%cLAM*k7iFZ4_39*N9KGT%*{m>B#&{| z)LHt|)MR;R{PipeY%(-;JQwc*0myW$@(f4@N1b!IwT2(8uWO?oVH45*yYfBi2p|@; z6&1}*Uc z7qBXUU*L1}1=j-KL)@mg|H&F5Ob@AuMWG_CkxN5wy<}g!r$(l2B1gXZ-iZ13LHWbY z7Z}y&^qa>{3C-3Ze=Q2Hy+_)=-4s*-MGR(`v_oNWZ&>5bsQ7I5x3byu^QI+bOeqr4 zOalUtxTYr8{KH|k{KFMLuJ}(^d&`SFAMEDZz&X+oH{7Y`>zAvL?q*kEt@)pdsCmSf zr^rfA`Ixw5v6AD4(b;VXP-huy#$)9O)_6}Pr)hW8wP)U`7RJynsV174ZiduR@i@(P ziSHfHa}4T~{yR2l42{TE-~D-i3-2~#MPEf=qIUgmB#U|Vh|#m{LL7aZN^p$(@?W&A zb(Q*-K)Cm}YXP4b=(8b2F~7H%Euk=n(%!JO=)$Q?)-fGT_6*Bd&; zA(?C1A&(=^z-dgkw6iS#PXu&3R)?*TySqNcyc@|J{`v>yjj4U}GL5E9;@GzK8Yd_=I0SMkF8u#O}QgRuK;M(`=OaGERJwruvCj zOrs)luZau2nwJioe`4H7iI38?u(B;p;^j`77(0CRQUuc#TI#}Sb~3WDOiUUlwL z&Tx>Rn9ZMhxRwUH2*m{ZUT{VPmjB9Ws)GryFR1Q0&f;g38vn;GfnL%0d0|&UVM`xs z!SlJnY(vfna1n@vgjcU)a%BLgOEmwU|4zw{;rFpxLkkF z@LPXJ?2Cw{<&yHO3;<_Tv121&avZ$fGT<2M_d8SMsP1;5R+wfv`!iZ-|1^X!q+T8S zwxP2{Fr1a-cfz){7KUr}MFf+Q2FNkJT(HA-1q-P+@}=P9{LC!HPd)UxJV~3>;XH`L!+VT7jC5to|*9 zk7vtInM9HSRkA3N@{!CV29?lFzQ{IJMz!W~MixeoO&q;m53#j|(O-M-%TS($U6A!^ ziVOxzU^6jq&wEjQgtnUSNrN&~on(63qzil|-;{<@{q6&9l}D>ax!DI#^ZX{ZoiwJ) zrqvb)4i#3baHlr^*>rtwO+_wWU(Dd6jCIu@9FpgW~SR+o~E zHXjNLHY=FxCjpNDUVqPsLu4(#_Tp|!2;Pm7nJtNd^7M-yg3a~6U`ZeADI*eze6u~8 zy<5KH>P&)w8f6UcU5>L=72X6pSS%H_moILDidzN~%8}TzTxMJ^@CB@aMTP#$7s~ol zNY7!&!B?(^{%CL~J{e@t53)x`JeTW4x;I1GZ!KE06ahNvO&inIkrMs(Ta1-Kx=K5XlLXL2F9y;C+!hG-)Q}++^YydQ?OC zdT}e66%?hYzser2tn5#`_+3Y0gmfeeUjFtiL?`(x4Sz3^2X|g6`B7WaxIE_fJHtj3 z;7tu&B`3Sh#C=Qqw9sxg?^H^7&Fj!i@!~JN@7Fwabk9=qbp3V~M3aE8%@gN?0|w{i z=16*2dOG&Mr(FNGoS4onF&DdnoCuDF>ptB1*})3VJF&cJ7n{PwXukkJzq|puRBuqGi$Mj?6WdKZ#6X9HJ)GRe)$LZas zkneG!VNK5b1E|8scY6BjC6?qi90|-Q6k~vkUSLGi=AS;9)n(HsPK!m(86~v%BVR&! zFfcioF#4U2oiPEH3e{^%>Aa5En=ob#^CFN6091VtjJh z{-5^A6*19J$I?M7-_9F6q?KO%Gsx;+S$ysCY3JW>H^ydW9}V?~S(5femVP@ROCjQ7 zfZkutQ$*BQ@p#i(*WwO^w6seS(M;I_%Pr&$&1iS@K{#go1PO+0Ted{^T{J_SiJje? zNh_~ZuQdIU`KP_o@&ojgNSRzUp_n(NbLqxG3qbI%*5QJHt>|da;>=mqzEm#JW<$B% zbTT^-UXnd*H(__B?m+B*`NW=m@rjC~e~b#h${vbF9P3K06Tj*shr;@uc#fBXq%q$_ z!iOQMlTNCnn_Eamr4Aeyx@;-M&KG6A?U<+`kfrw43oP+$l1E>`VBzz}v>)>HM{AHc zebgfxocG28a02O5^t(4wk@H81DkXnAaIsZ?JFmWKXa0`*G8U6s!$a^S{~{vMSIoB6 zJx`~|y}6UFqX%;^X%Lc2Ja`_BI)Cb~`N^+U!l@SNo8b*&ri%;plFR-lzx-6Wj0YN7WMvt0 zX`3YNx2|h~8>a))eP;SAT)aQQHK`^XjiIggrz%*xX#S_^jf(@g!M%*wlMp`3QZUOp z^&y>muDb*d9Yok|bhGskf=8Y=_^NvkOc{Rm1ByZ^{Uyr}yr*&|f z+~puc@$^Iuk(U)eSo@&JZ49KWVx{)y0IPEeG5cD7iD295-DzGiRZ4c7P)?Ao z>KYo6S;`TEzy0>_*0jNqueOUY5BKzLih)2$u=wkxQ#rIFIZdZ*OWD4{FQg9-7SF<% zPbxbi@a?x;^T$XA)uuYa^126SY!QNokuH#zM;zHuZQP0n7_isDAfpmgpQm<{pUgc^kHV79ANEruDp5MpzsEj23H9x-ywlL)M`A$ zp~^Icoi9D=)?6A<2H?-@Oi{jbRQKkpm>t|7daMv{F)>Lz%*T12r_7_-S*YebVk;$b z8bviQkY1~T7y5+lU}|LK)%cpU6qMKn671i$1VSo|%3%CYNVCkpfmrV3_4NJbby(AngkR}IjIqTJ^~X9KGJAiGB89HVV_=v_B(UO&&%-4JoOYU!j8n%>r+ORFD>4&bvWDC)bd7`F%CY8LE zfTt)H4sU}fcN3xh?rQaT|IWoW<+JBn1-G1V!&RAx3w3qJiIhy8YK%;JccmaIt8Xn% zA_9ctaMwLUV2ufve>)cOZ=YkVo>*kmQOSwui4%4IV0WYLAPUkecXB}SZq*ZTNuv5Z z_>6Y#v0Dzt`+#TJ<;LF<$h=t-QwDNC#=X+l9ewBynHEi~>tgJ(EI58PcqsWy0!Zs4 zF-R)IyS}>n;vSt0e(CE(fpnQp$LI~M6#;elm7^dv=8<;~*MyY-ioz(AiJubk*BPqG ziT111=fMYcxUjgg(rMIo8wD0AcHZqh2s7()Wwp_F|v7$)>HUWBX*%bp>&- z1im6i_dn(j59g< z81t~Z@xom!byB#$7-kMNsQgs!lxO7Dj2WAK-|{f8AS4oYH0WNI*#XVkdc33Bv&MKuQOJ>9vNy zcf`0Dkak)Ep>BqAy(9|xl41#hQb2(j9pTm$PnK0%nO8qlbqG>IW?H;t_z5~%?sH2m zAs0?}pD#OEqD$p+pl-QvQJH|$qr2;EQpTf3s6e1p5opjG{{4%{%)8hHt_v> zs{$R(wu*R9p4OnzIEw~xaA z`z*6iUk_)@4@mjR8l}NrEH!*8maY6xhzxhTUDeku7}3*zbMX@E5-~eX>>SbA_hU4G z^YJ_kO|ih6ro_M+rIuD`&4pd^{OEn{fD6RVE-z!_mn7i>#JZjd!x2b(hqKnpu| z<5WV30JPuPNC59>TU8+s1hvp!DGC`CLGmY4L`S%3h$7B+!z#ao(3AXbj^g9kl8BM- z54IIdd`G)lyQb3`ccVGVco2WP&Nk*JMqU{_8`cr`2R9L7@lD;r$S>{52QqmgM$IifDvV0xOwRK)Q5K@x?XA-SRz0gi`h zRwkl=h3nbvOTDkCC?H2msLY`IL|8{_IW|~_*!lWZZpWG5V}6CSBSuXns11-PrRK5v`v8*;sJUvbm3L@3U0r8$Qgo z9RKB_l3_uCl3v3n@+`w7C#|(D@~Z*B8vHNmLq}Bue;8Ag>wX0`M5h3gRs3k-NALyS zxwz%_T38116g^_w6J=%wUHU6zW>&vWLtS=N^ci1DmJ{~6pi|Y}@k`)Xm#t`C4O|JX zkUu^({?(IQq@?>MJ%wFpBg(=eM59^QJmYK|VDomVRim>HElO%kCrrpmXx}74hMdCr zil=yVrG)}J@%1H*y#R`gM`iLH@{zcU-)7W$O#wALA-mtN-NM+vm|u z=XG}1(N_1b4$92eE3-}%))peKCAwrpzCN&lIOVwnyuo)!pYEFn2j0suYJ z+RR1eY>X;OmjPRFX)xpJVeEDVVl=()^=nt|9NL3` zUwnPw3rf(C+yTMo%FR`b3hN^7>4*PZltTU^PW`SK(kHi9R?81VN+=j@rFQ zh(NU&e2B`-&6&}pb!5+q6(FL&nN0lFir-J$%7GGq39+XX%m0S@SHC#=03CbOwoo)c zRd_q!QCZk=;Z&9F5EPj|KIP^>p*=TAOmTRTC<7KG&}R4NI<1WhH*bMRbbY!IZcXjRyeoSX6yGsR@#4Z&K*Q0-|!^!#@MKq344pWVm8Pz_0Z4E6_}2 zP5O=(($QIe*t*G6m}cvu>-d31TiKZsVE`U#WPxFDMs z#pl&?oFO1azUUxo-dl0xi|SC>pn0AzLDn@2bD+NJ4-4{)pt-RondQYz6+}Cif(-U7 zfjVf`77`V@0AXRNifLTI?#m>kbk6dLcn^YvLA<9o_;%^Otop>f?D*fwcnZ-im(Pp( zL1{cBzv@gby#(*#34E9WEOCZj*4n{W4oOfHv~fV0%$ckyeqD_{_KmH?vaVI1ARybk zolH*58E1PUpQV$dRu#WQuIp^t}8Lf zW>1{~Ci3pBhh(8C(q zPk%UD{&P7WC?H7x=9s9d5<5`-#rxUx8>rfqJ(>6se%>@^CGOtkY!7DfqLUMzOaZDI zn>Jf5Wk+&bqDpp_*;bP=;%k?zvW1XDk5)uxrfEXx<$lZxNh5s};(Gj12XKgd@_E(I z+iv&vdSM6Mp!Q<7w3JKs$Yn zA@1epx4{DeMvlmTPFbkpFoGVrBB-IyK3e0=E0ur zSij_0J5?3W9xeROlIFD8>&<^j+TxpV@sY5Q>>1U9vAh8Pm^BKN=lm!BlZT4R-yQtobe9g-L&5Q8x~f{tS9Krjjn6H^9`j_Bn8U^xDDXS!(clAt|z7J@BBSp)* z%Kn=#GkV*1szV%){DU(6loF zEe!%#WB|*z7nab`9!?&%eezKao9^5D6a#`m|5_LX(e$H&J<8{=_p~J8VzX{h1$#%S z;jwqKgQUXJmK*A@JQ_g)NK_BZO~mCPDg9;2Dij;E;QHN?&XKfZ7-e~R0=pwNWSOl& z^Pbh5W)x4{0ShbTLs{%AZk|OAAK|FQALo}YwL1vZ#6j}ylfCNW2BzG;chEdrj6Z8B z15y`CBI4AAPWGk)-7u#I0u{<1v(zCxuEGuV+Spg?Di4>c_I|1j=9Ue*49h_ATf3!G z5ayKadE60>?k?IPV$+d29r#uhTa`Dbd8u8AT2Ox(s6a6O`h%=qRt#z4AL<_ZpoNU5 zrMd{;;gj@ME4e~KsHntDN^*rp=;E8S)u1>OpC7lL5?T&uT0=cUZ9N4_i|Y)r%%RgT zD8~5yMv`HWk|CacJ?^@WwEhipsW}`qc!whIGqM6U8MtCgpAv*9i3CAj!R#Lp=pSN8 zKH@zk9+E^nM>GOtfFSbGV)?tS&oZSEn1WMX#sV)m(!Vpc)2`;x#=ZjOKggn6a2R_2 z6n(n-?&y8NZ*GX7;~%pqvy~5y2shBGB}9dK7w{8Ppft{V#>&jbcEE;YCH6E#IVr<# zS64EFoX&z&zo3&mR^5O_$vw_yg!Gyar)U;SSAPb2SRzdVP80d@_E$2*V;_G=%1mA{ zsR5^XR|>F$?_zjV*H_O*chG+J7K_CMi7^ElCE*O^^^TcACOr56h^9OcB9vPna~G!+ zdJA~2%jaaZDz{8GwXBVB_Y7dWRf&Fv0~rCk&bc($)E(P{61(L8@g}bQ+^7BA_Y%MB z5~+8-u|3(DGjb}V{s{dHpO5lfdTDP9%#y0l&Yt@!?|5V+s9U$Z{A7q`43%5WK)ulS zqiA}^vQ!4maMeFt?A+cfHT;aOa&!~T6`M9#<~tN0r|}%3gd09H6Elj|>te)=Mhvi( zY^1%Uvdy7ML?_(U&k*Cnc(e(YRip1{%q4%j?g|$8LrxOzv@Lk;A&_u(H=}Y~;aEc* z6#oiEN{)U_70e%l$u6Ao&&4)j)z?TRh#+lwDN3`*{U3O$>%5oO^IlqM z&?P&Am;)^DwZ31SjFRFd=(j|)X8IFa#k5nyltryp)f=v0w=eN&{mUIu=j51`&4mH{ z$XN4}KBV^~T=-yE3>jrdy7`R_LH0UbMXCPc|x6XJZF8bdzE1BdC;WoWC`KIs*A z3SP$B@nvx3%bE1RK}QWy#=JlG9e)xp>?Z%@ecTgtU?BfX2Ms0I{OkK2k6=Az$+G}G zZO=4CEYz*fKZw0GxCBmr!MLh7*}dZpln0+z(4KEtX{T9Fo!D-|DDY3>X+Nk4hm3Cw zvbq$Chp7Y$cR_BivT13dlaQ|@_=Ko#Nfz^Z_?@?SCLK4qE3<;$V7i{J{O{)c#Nwe~v&?@SZ>Gqzhw$ri!NJ#bBuAz`=>AhDWOOj0CPi+fX#mnlU2u_r4Z zLF`)7@tm8&&|G(6FJWb(!dvjsc!>@eA}5f{EOo{kk=CM9GBvNKj{uWH|A1XJ9<4&<8~# zhP&XkAVVc;X8#hrG&21+zQ6j3v(SS{XB$53pmn}g?S3d&Md&P8N@_n z->UI;7KpuZwb_$zWGRM6H>^7jrfPxIZKR#OwDl;0D8LJ|uXb0E5@gohBddAQ>9vgL z9&t7!g|nlV+l^}%9IM$oblZLXTdGjU9I?V)yg)PlgWr|YV8(D9&b4|P!CcVUYsW|E z(`w9RqhQqdBam~j%HOpL-8Jv{c2$Z5{xkPUC8c4r(HVgzhqaej@~WF~wg=&6+L zQ4i(wbE(Wfo0PFCkrpq*Q3kgWRH!2(X>WmZZvQvm%r%G*Vdq^ZT0H!p93&o#QR0<4 z$*E5;nE14Ll-vg#9v9{wfWkT|l*Yp!ZA8H^f9%{Pc&~;W^QZWQKRqN-ifMan=yXYLSCBV){+~u*-(Q@?xy@** z1Z8H`8Bk*#B?qMrmXQUaZ#m8nWIX{fLtIXn6)_g^#y5B>#11LPs7s`N&in5 zYvFi*xtE^_(WHhnR$e!~BWl(sY!X+!IuhQpv^@yZUMxjzp3ZRcm7KD*?kLFc!2K+k zZlM=o7b(LI+lK7z^HWkoDT8Sw%VvFO+@_n~)#9(%m20zs^p7RZ(MTC&M4bVFv>0{I zr#klqy$x}&zT@MuqI(+&8r}qF-MWb4bVMimwV}IXbvo;G+UbNitIIA~`PkD7-gN%wFkFAgRqi`W~yPEI>cJMAPsg-dB5Pmx8)(SO^X6<@vsgBM zfDm#e7SU!Wx3QP5adTfbYcanDjFp8)*3=0m%`dM;yiTr^F>}U2;@f~X7eZv_Ez7YG zAj|DP+wOB#Fd#8^rp4+Q9z18JSdi$ivK?G>TifNn2tMF*=9Gy$=7IY)mGv?p;s>g} zz&Qcr?km2taKj3W%V%dFk;~9)1<*1vD}V_HIWrAbLr}Zkp8HtXwEe%2b@dXJ;{les zv6(yDU?r+aRWOb*eqk;Z{(VdFjG#fG6e@8rn+LN!kZ*@hVX#HZ)3{DBaNo5~yV_p^ zOl^nCDI*gj3MW%j_~(I$UzYU-e^G;Y4jI|$zZwIw%)`B#s9 zrsP}3zT$rXao}FZ43zl)Toy;hAJLSz86eE~;;}|yozkV72-L;4XN0!`$C$KF8p3M}CdHGECC@Fv^vrjA!c4Vz*{9>msn77>HXV293^+QU6Y8if3b@v)s)8Z+sTC<;UPcGgWkj z3=9$}-3*RSS+2T~jo(Ny=qR-lHIy&}eeVo8sJqco?wKKy!qUzrhFxl&4y-MeEb}&| z_2;drzRjn?Ti2#y_N>iIi*6s(4)1AWFSPbUDw6PY#Wp5DnnN=m|%^+RI)sHU4%74E`U9C-0st4 z!;d&#_0jO%@4CPLF1-Wsa-q`tI-T}GwB>}z*5+tTMoO%{OGS&83@kSeDN)Tp2Mqw> zhb*$1FO^v>i4=aw8@tG3eNzf8md_^#oG> zAND8>HkX-sm?qNg$rM<(jat7?)Q-K|t+fxYwYuqnR=Dh)tm?}4b4M%U1mer&2UrrW zA`!ncAd$@k;xzFmw}py&%GxnEerghmZZJ#ue$4$98JSY8*nWPagg%f;?Y8R`)?BXC z%q5$Lpd!G3wgl@U_Bct+OX z^b9=d&Yk^D8aF$Osb8Bp=^+mb-K`5cJz8t#nzA6ZAzJG(QM)dnR=ly=Y zp07*+ZRbXD{NNf~e)E$j&RNU6d^81FYcpOG1NAA1w4r%fc;J3%LrIa8^^O?(eHlPx zzZe^C)}}d5v_xX2_yT~+dUx=4xge_YAt&f+KXJv*l}+)Vj{sFxrnEE})I_S<-;M3< z(2rNO`qc!GA<&zSunXtu#;rfzt8JW>nR^^3($mcOPiZ|5ex8Rh5wO&B!i7t0yg$BzUafgQ-32JX8-s>YGR^YVoD` zfpZ#zTU+map71AY6#fanXWb&mnpL=)5P@1#(4TIy7H4k{yWE*65VHM+`&;`RZRb0X zj=kdN5?K_BGKSMqERltJ{`XtNsoW~8-5A=dU@eza9xwNILzVJA#a;TfCB@C7PFZ?D zCAuzKqUR>;Vq8)1Cn`6*TwbT_Ub%7ZrDiiSKmNxNKq*+8pWC-6qmGtKvTfjYdjI$D zVzwzsGPlG%bn~ys2Xdjz3D0jIcG>gXnVpirFt(}+hhqV)h=Ze%^e~_0zb84NorBzN z!}T`ZLxyoC67(Xh`C`n}Vn6yaAPOnDJ{Nx0CKINor%jYnkZ|NHJL`sA#QgQgp#S3T zTGp}w*fu~xN_Lpf6i~yq`7PtVrMtqpo$a=xcA(fwl1LPQen*q8C`1o$3U#@S3w?jr zm427sY3V-S9IKo*i`mB=gQF(g$D?%DapjLA>6p|m;vz(_Iw6Y1PwvE!mVy0F_e4h1 zZ8FdL%yJ7}vCJ=)M-?^p^H=brt zd(PD$>CV+so+w^wrMxfAT#t@JmGZFPDDFHgG9WE^MdwaAxr=oOQG?h>Hqpb7qGV<2 z?CT9V24ZtC9FF_YMwL60e4ae*d04^^kC0E8x4mL8=l;eLOa{GELlN@2SKPe`t$Si0 z?x|f<43B{&b0QGzfvibsLKti7CM9k&2Hz&CjlJt|v!5fTB1=9w$?2vA5qWtze|A@K zIXb)m)f5ER2^hvhmj2RP`}+FgW7u{GX_V?suaP&AKudnsL{BC|Lk6|OI_X{WlzX}b z2#TUAr+9HSLO+{WYhxjBUbgwt-Q3~i+>V~Q0-5^t7%p@6{h2Av~p;IBi9> zt%kiJY1|Pod~KtE4e4@)6(h{W8MH3Klve|QuFp|#X8Km=XYwxcRiAJjGk)=uvmu?K zWF-R!velx|+zc2>J9a5G$p3B)oqLZ9sdyp+17?1ZN79*c(2|SE-Udz161#3*Smhh) zY+ojx<2IbeqhMaE8g%oU0X}MXH|HOldz!o@Ls9mW4bB&ao*)o1^A@cy5AUOOIu}lk zWeRS#Id*hREHGN8+?`+VFg8)eaXZ-o$p+f1>a&mt-Ht=Jk&ro@c5%1%FYoA2o7rKo z*g7KKD86-83q1&cB&VD$D9B7cOQ-x3iMYu$&WS9!Jn{;4QuKpR8G_X~{k$9WKBoz^ z-ihnF6M-9ZWUXUewIVplpwo;9rM%c2&*&iR!I@i23-aPWV@-vur^ajnv>p5v9>s5| z?PvOGgpO9Ni0v?H)xIff2o~}WI0LFEnO=LE*C3FszefVPL&shI?tKs1TabM$h@$^_ zeG0eL^jaM>vQYkF8R7rZsp|+aa|Emzb8yAk+vCT~%jdto zFvCgw009C{+(Cu$yj+m2XBoZ&Q5OKf&Cd(BTcj$Gsq;B zyel!4QSveEkMG4yV*!aVMCk+hZxlYL>g|*IS)uQw-Xu=xlO0B+m9_-y$st1dWOspt zvhMj)8HE+ubDx2RjvSfY>*;QWgjVuxuQzzcwO!cx_=L%F@{gsto)x)nYff02)`ghK zv;K~F9QqqC-V~hE4+NNY+))N{Pgj<&braR%q}Au>$n5W^`Jf78dfemf3d3+H5mN{DA(jTv-=TS?Qw#b9Jwc)_#E}&GxPA zw5T`aB=?F}8G#JH4@d!K2Zz=CoFRjwJLEs~RYUd`@Zpv~%xb3HYRZZ5K$ zGZ_6x#$U=;-R@K`rP0%}I-efi(s_0LxuxVq*&CD&q2$}AS$By*ldM^G{t?0KK{0s& zit=zVI!N(i&p+qre#seEawgD93EeabKax}kcl0RqO5V#h3uhE@J}+6aP%;4e0!V!g z*=q2Wl#zK~&$Xuy4K-XejcpZ!2F#JNVu|)?q&pimQf!$b8Nk5Eb&gZ_m?rfba4QCL zLc@KZT*$1Kvv!Uo4d-a^UnC1SZZ_QT5%;ef0~mrY+pT!-#mcqWHG39+D}SA{A*-iz zaheEdws5*H;|iF%&K}pGvOH2iR8`qbU%8>Oy&Iq)@|rh{C>3=yAXb6zPO83r(+ub& zrtb{|iIzldDLmqBL*Xc?V1Dpy-=N_Tr4XGO3x0mesGjxp<&@1M3&PzeZx*9jj709IA;>&1It9GcAiLAghcyXyJe{|-WdWz% z!Pn$vhwK#s%YInF4reEHCkMOi)#OfgJhZ^Y4SaX)_{sG$(4LSpHlp9`qk_p)GdG)3 z_?cc~j>{}5F}z8pEJ*f!=Zj8Zq%nuAm$`@y?pxRc%%f60+h$_@f3<-3ihrwI0l*3LdRd*KGGv zE~P&apE64K;P{=A%w%}`64%wnMVE|19lkj%JQE29gjT2c-Q9@_NRo#5;lF{Nn13Iu zN`%0bS2Zc!NwZTd=K2CiP~_!D9kBtYYrvuZ;6E;9s6F1KH_w5-|gje-|KvuDT^66 zk);^HrLp9JM}m8YYzg1?b3XH^ofquaGDv1zYEdjCt`%7UB)`c&r!IPMlk2S=`)-qF z(cSSNx3}dR>n}Fye8-9DOHuDGAU|)=EFW1jE&d%uYYRZ;14|6z??JegMKcw-8()~- z>Br@qgAAlG_HVa%QB4hg-N?YB%CDNX8I?rycC_6{00paVxT(;~yAb7Lo0j&klpa3c z#lhDo?Yrk2tiheWbd{%~kZx70O#GVz#D+W%k z2RROWb;8oc+Pv4J&fDaa-f33~O+aE~hB1>F2=5?Tk1dYX>^!RVlTMoEyL=9c7<-~5 z0Su)t$Y@oL(hoLr|C9HprO2Q-bU)qdOV#Qtqp43UQN5~Uhyz)lqcq%D&Pj>TstzBxzhQer)_96#!0UPR3Qkz4;s*6izTFj5sDfVot2P*fxO~0cltEO($J*g;@-CWkk;ww30 zzTKvWP50BTRx1-l!iI6wMln&o)~Bar;8)i~9*01n+$3mrCe2p7WaxJmp;5u`dADG= zjQ(H0iIHKOnjg*GC&vRXnx{UF)@=By+ptFv4@UU`!urQEnMB@>I#_Mn=5A#T*|_uj zs71Wj9B&c~j$6Vn;TPtOy!(Ll`*8J<+;ITe}sL$ceF+ z=RfDLFa1uk=%3wN+>4At(SZP?)2Y*-L(qs`#825B<(+y%AjxJHmxoyF92EH(-w8em1zB$qtt9h5iG%D0QavCYcNe% z+J$82`n9H47Iwwpqqd{$kEBvbyvS?ajb06xDlyQUe8ATb_V%|Klb+rX_B z_|@g1TP-2wCCQ-G{X$3}_g=-C`i#8lR@DL*a5ipk3fB^WYF9XB)?I3JEJBGf7+ky= zXvmB!*MgVqUUT@NP5lQgNITG~U~$mDTN9h~WO_j0ZP*`w?LA5~LyeO@Y>bq4^~Dgz z?gJXwmhVA;wr5}kRH{kR2|oh3K=g`Zqm(qX&ZI^<9qM?;80fOB*;zg7IhVBGFq1EW zo0IebS;}n+X5$9%>&!F6+9qd}mP!q;#I(n5D>9!M)?V#8;!i#S1Av{$BMM&00M~Ro zlVQv#lRsuyCb@E=d;$`7;BWiIe3+}YY>+Qdr7E~XlOn)XM=BR}p91^s9&9MxzO%5- z>U5=3Az&w7H{W>aMvZaXFdE|R%CEbEUS8ZEiEnYuTe_D-m4<)_CnoH2g8)N z(Z069^-`%bvfDP*ojF*`n1?(zDS1Ktqa|Avd8OS0=Y$TFe(&myY~6 z2Rd&h3c&=JOGSB-mcHM-s5aW_@!l@@38qgCiD;KtkaGps*c^RCqY8YR#}B z1cGp4@!XqYeC3&aaP+*z5SA(st9>n}?G*gbf$q9IgNocCj2c(U3tskitK+l9mJaIW zpXPOJvr}?JRt(m1c2j1cLxiHkKQb8 z2v^lp+YeQO?46bl%-?->_!OkDek!R$8D(0EaWGSln_SFCNrj8fxI&W2QteV+p@SIc znv1AoaF31uQUCd+!`}LY$;w23z*qmL9Kt3+)xElTp3XS9{m!2v!t(RAONOWZbBhYP zEJ6l>(o*D&rW(0&(lf;ml&lJE!ft9`4Y8xx%+5lw7!}41Ze|{wKDy#KJ6k$u`!&ai z4!d+pu;NiVK14XM4K{8azQ-sZ$VQwVDPvK@icZ+!)6)$CzOZl}H`RH8punt}BBwYz zQ};qcr7GwbzEe6_)5%OBS-1OWYu$=O#}=ZbPad%MbDC(CCQxRo-UAYa(8524(*DeB zf=eXz&o3v)#|y|Kk$^BZihQ##~opYIa0G*r#DVb{P0tjRekB4>!N=-JNnkX1`{ z245(b{RF9BOI|URR4A|+Tx-b?(C)`*E?BkQ97rSY!j)3;yuJlmHUi9Cf&-9UnSuMv zD&lLqaaVvyP$|dEtf;@*N@s{VZwuCP!S?NZ+Qvu0ba(=1Q0MnH+zqS1y|r%?5bb|Q zN`%qf=$6?{#nAq`@KY=qU@=iqof5;zKuizd47~qvF~3ZNGq(wFIqc&VHjRj%6leVq z5Xl&tp{%yH(xZ?+uz7!t+1Z&ZDhO7(5;I`L-BPSH?|2?=^K zT7v4jH540J2H7)V@Rgp;oh{fNzz(SnJ<=uI;Y^zoFG}QJM)mvFdx!o6&|p7P4e;ca zNzB~`@rS@8YWDbGpO`F_uj zF<);afFoLT^l25vfqnfbWQW*h@er>va_-e7jSMI=4f*!HD2&}D-VcfQo?ogE(ks`* z9y%1+izW!EYUDciOP0uCdSbtFMm9{00A((*{!3)Rv_0RJJNzBsn0B2g4V?6Z%gBm1 zNknqnbvBT&VNI5&f~Vw*{5(!~I{sY%BVZ=>29yuS1tuZam5^!Kid<0rCf!9fZdPDz zT~s<-)^U`dz;C&EDx&K5J3crd<>eo+ zIf6EADB15%fvbXlwEfFFb%Od!x^c?=MmbT1mDOoa+vA?=oJ`xT~vdB zNhY}e|9)^7$7?BefKSz1){q9=z7u)`6PKcdTrh6RBfO&O#V){u+A7jAZjEoCC+LUH(aqLM7*$1{L;q#Y&xHW{^-MH zMVy(Q#wasJ=>GAEtxNeA;&^b^?%TtfySm_bQ@Qo3d+XnaKDqSfg*spFP+Z17*|2 z*JT6qa!8H*YX4Jw?65bNTX?7i!@ImEDkcAXgPyq>-J4155VYo3qm7h#hpU4r`dyPT z>O#3jB5!zy?e>p#bq zlKHez%URZZvTkW`W8>x4Ol6?#dz?%(F;Nwl7XE~}nCgO+72dR8zE!e6mIuO=L(bZ- z=B;;7)=Go-<|^Bth$3)Shp?`bF!+h`302psy-<h=+-e8Uy^lwx|Er=|Is zCZY%m(ym3_`E2}w9gUbau>H(#Iz(EtdsxBR;W%JUSuj&CI5-YcSX0#u-8#9L5)3EF z{vbJ|qdfvi0P)N1!wQj?V+IQDW)D85)FNCi9%nbYSM#L!ZtiB-3fX3{Kvm2)P9S9N zmzRHg!_|p@&tp^ms9!)oDpP8fcor{^AQG38{9fUmE|l~%466;hdH z?0RQxb@C^wp|&EyXA~6?ui)Sikoh>d-A_>%%a-KV27r*ep7rtA3#!yH8sXt_pM;#% z=7JGU617efbAsJu_4LLM^qYT3JRH1}kGx$vJS=MpaChw;^+vI-AJyg&d{?AJN?n>X zxy?;;v(Hv3ezFgz(-H#OE8Hm+OFlsde-t1&Z*1=Bvlfr(tG^PG&K}OoiSK+&SzzNwCQAK zl6dP-#<8W-s^ZVbNZ`?V$o4*^?$idld_rrXnp5! zWE8FNJ0W)GTZ$I)#VHUB1yNW;+&Kw>_C4l=AEbSE|F#q!vbO^X-#j6~!AY@5DvuBm zU=mf4x-rnr8}W%6_M}OC%>IpC;`6ep(frstU(&>*wa^L9FL%l@A*NkU<6)xef9#RG zw_HpibUaH+ATq##M0C0(FnIsc*Fd^J|NapP9lfbds}i6F#kaN=eFY^?YwJun7fzw$ zm+!`fO?gE{Wg70@F3CrW+vE4Tl3#^!VSm_gzQb?|FqdFd*~sbDn`S{~X5*M`p-Ye@ zJk&$Bax^dHq*INL^elE}|Abha_7#9sqFUZ<0XZKz%(2;;eehNZH67elPayV^7UL<& z`b)E*?uZJ=CMr25_>LPK95IbJDQ?LNGOND%Zq{^{&xEo$kR{*r2Oc>549ZZeG7*J^ zMgy3~nbVabAjvT&nfG2{xkEb`%utU6dxHUk1u}oN_wW{@Eat(RmUZ!VpcwlAvX}N= ziZZZ_*{yldrRM0oWA`~8yTXkz{7EduZwcDTye9|1fZMGLL00X!9olWh`|#{z)q|tj zE~V=p{$w+&c2_hY);=e|Id10uO}AyqNO3qJ%8c!0m`YRFO~RCqaN<-o#!@ki+~+ou zbY_}xae+X(^En}kH>|5IuqUMZKd_oASV@Qz^kaW+(z&Ic&~TF6{SMa``5%f=8uhGY z2UDACHe#7q<9pTaD13ibI+WiDqV4(hj6oqusmH3#tPXT`b^~?_3&8jVgzuYu0v!Dw zDI{y1s;4eLT*W^wD+GLmxL;Jn;AnrQyV0$y^1LbuSl7;T1EoP=DXPP&D)*I%o|XSt z*P>MEflkDno^o!lrysl8`%&^|GhLx+yvht%q-v6l78@#HZk_QO;u^JO&1Ee&DbE`U zNKd15M#|9F@$AFVP16T&S+;QcUsOqw>n%bTFRlJygYHSrvoQ{qp@4k%We>!Pzzl)4 zb_kj=QKE9T0gv=lsj%eghwmf%0bE}KY{`PFg;3R>Alcb>vd*wylg_v3yZW>XN4K7d zwjs!v&Uu@cM6Xa?pa9Y`rnN@yqr1>1hv!1|1g_bZ>cTnQ*Bi2VIsV^{UwzfRyO)~t zSKXIVq?h6a?%4X~M?uuhuH2%4Y|bmrg>DX9zGDsymC%x{jXdb-{bi zP@T@tm~W-0tYv^vEN57)hn>zhydaH`zb($grl(Wr@LT64>QgXyH{Zs_Tz4Db>?Kk8 z8F5ofQ#m))q^BRWjb*4v6F0|ScW=L*b7D+Q&&`{UAIT3|#8JKoLTs_tx@77o@@Nd$ z)rX@RAtT`5AVj!fMQ%R~55eF8=P1QDvSnzzS%_;rzjFN&|~5XJ0WZ=5y|ngY)-hWTF4D;Fw9*$9HqA(nxgWtB%2eXoX}VYFOpZy%qsMK?C$p)ocwt z9@bwS)cHz(J!Ki%-J*%5`9Pe_)7S~eO#FpTJv3Q|-v9_plVvrAr-6Pb+9(5G21dRkTQj5Ewa=!_vr^ zlG036c)kaQ)e2;oVK0^sSk&0sDtJJ~=i^yT(baJ2kpJ{j0k8LRLL(%vzj?G9L6C1=kw;uwy5!=o&z^%ZF(2xYvi{+v`;;K)+H?l?+z5DWz*N&gMpTYdRPkS zEjojm!5Ia<%NELo5>7_rJ2{koZLwrcD)ap(f((Z`#lwI|(=ba7;qnjTDn^2Lb@TLc zU<40Ii_EY4Yjdwkd8?=UH<#*-&EJIfgl^)M?Ee`Sx-1y+OOJU(xW?JkxZbPbBo-uxLR*jQQ@Zpq=?}<;)5rsKNCNS1IskvWpZTkx~>) zz>LjUUfQ!Lj>;tOSv_v8nVe*5Uw4Nsy|`GR3gqCrTvKi8ZI*D+0SILM&a?DUKQMc_ z=yC@#A96dBQ}BJtgS{cq_u%!|U<%2~`r{#{$5HG_zZv-TB=l5prf@{VnZ7Mt?p#}E ziPpP&QFfsnILbSO2WQNNRW*9I^9^rXa?hS_-gnr$Ll;Ba})z z{_!F&OFmJb!KP?{D0_%03^Lc5g72B#a&DY}#ocQ~0fvR|J51Ii-u-lH2dS`qu%T z90Bxj`AHYn;SNBG%aT{y2i>ZCt8W%GoTHdG@Rc<_tBte&roL23XWr**{*r6-XoJ8e zZ_ByzETw+B-ZH|v&bI$sbZvcyk%)_>m7xZ{W-C{@$~fzSuVd49aZr^dTs?S58dH%KtP8?|TY$jVDGT@fJZU}Ye$^%~?yZ-(W;AcW&*j#>prKrX4&?!p zwP)@=C}8YC@9v^9W1>VhV`f}t`|tBY@`LKMB~jbP&VE~oll(hM@@lC9DYc`DyTP4J zt)?|(?fWxmgo6Y7ht!AX!r?hPZyD)UdtOL$yepcrLQqqy-;&O-$)-@bHpbKW$LG4f zZLLNR-6h%tb@TEKQb1=Q{LsH1Oi4?!>=d~lcCYz;X}2yR+nMtQ4k-qY0HFjfDm~FA zQ*Or9<{PviL9IZ~JqP#f3u-kmLQ8;q;kP)qG?*OBy4qgwmsWLtPqdyaCp?@{S^Ugr zlRcYt&?~CjeW>DVK+105`&NdN72R!iq6zf(l1C3d$^$3GN)Y2rwI%hTLV2rv;2poa zGdYk0&*)v5?m+WLNE~Qs8@~u4^TV4_X^8KnBId!Om9>gL?4dm>U8x!; zd(-Z>M$%wy5O=mgAn5U+haXuP>NU}N7^#F#styW|$Q>OspwBmvZTr7l@d>-O!E|u5QsQ! zPR_U2D^H2Kq0XW33E1H@5`?xkPC;lXa!&^xV##oxrQcFEJ{1e_pGxfZ|0cr-s{ z-8p7H)x^AMplrBKGlS2$Z!!|5n;U%JuGDZx=?36X73wGAsL2WZf_g}3K7g%ePzYt( zUCK;|%Jn{OGwANT@y;*H4$8p*nJeTy3}LtF7KfObg@s=!IGx`QfB*?|Qvbw|S;As- ze`ylg3lwbJGw7@>@%Y?Y`o$z~y5o`|m0L*|&ot8e43aUtv)4j8lxCw)QFmrbG>Up! z{0*f}&MTYYnu+*07G7nssp%a3iNF2Y#NCQ!$+5zeVzJU$ zV2Hai5T<zFOR_`F)3yE!MK9@J{l6CA27dTDa};3ST7ECxd|c=Z%>uqq zAAyUSW%L494oFysdSGTh32VyIA=6?84^jwyPhF55-GqFiGykGNmXq#HCTjAa#}6B3 zL7YdUv+v%fGo)Iz+k_ zB2zT;8&@g7!Tj{)tKk?s`J{5{$5vBe8Pd-tZ?daRVX(Q99V~jh9Fux7n~`gSNZz) z!0_dh4Ex-k+Q(N`R^cs;F)NGIGD-Vt;Wd@y(J0ZbyyL#%;i=AZUE*nbi`@bA35BZ} z2Vb8Xq@C=$LqS`(IgEtz*B5c!Ir?_07#KyFwB@Sc-lH_;r?!w(eIvf-!zF4V5PY)O zJkR7)@)7x}3&axe#Itw)hk`Wp3gcev4GA_cSURhsW;U~R)1fvqv)|sCn33xe1bBQ( z2I!02mdb+euUk}`8OD>@ZZezl#FHHs zgp3wScve^dtC3o{dbY79icoF<9SES9E!hJ2@>Wg@dEr;;+|xEm8mk9`){tcx1$RS( z2Wf=H#w1lmrZqq42|B#pZ;QAHpJfrLrB`T(OcuI%ZP>xiQTQd^cZk22*U z)hRF6N&iy_Yw`4;{VN`-;5@6g0~2?2pneGEa)dIW@ZstWE9jxa>EHf$&-917mEDau zly&Z_=a2ZSjx1F*7S_@3_0Dcto$j&Lq)*8Qye+}=D6y)ik@*yY0sZgEjNSA92~Wl6 zh#_gYc=g{YoFwz0;gYtSFFr^L-kZNxwXL*G70j(ZJI8#xzVNFvPES5{LP*v3uzed$xjdz3`;;>&LABz5|e(eLcgfU~T1NG2Y#rM;ZBr4^+dV@!+&nOh)iKCOcP4bfCh-{cLC_${)8G-v9(eBa@Sd5ET0SOCS{b(*w+oQ6 ztZSdLJ_u&ii}NZNapo)CoYIsQF0p6psyf+TQa?lYi12@{yQ|)))frs7AzyU>s;{q; zFJQ;p*y`$&MJmXvS9ro%NJ53xyZhh1mC!rB+Ru2V$ns{@naMXydyRk`OCJ-WZ|9aQy1=_c-Q}XhtybFsPv%?D) zE-mnpW{as`B{8sa-r;@Py6fq z>VeHXY81aoy=IABBrG>_lzR#?ldtt8*Aa;N-Sga~?rvA80fzRRR7_CG*jpLvMh`Ag zX=$|r9jZ*=(Y{gh!p)%k8-Vjv#PF?bNPgS$1f zKx@~O=i=t87_6c@1NmZH^Q}971^6fzbG&tX}MY82^=#u4h*d zLd?rNbjZG#aTvN4B@f?!B6vF$+&-_|AM-Ic4QlhGsJoepM2{)drtl+X%g`S)>t3WA zgigteN_$NpR*rIvc$#$n2u={KWqziuf&6)VZ=P#?NPRkFYC-AD+hnzJI3|x<|?+GBDIjRI4)|yj7KyyQL z3p-Blcl%cN2`Salj92BspeII#9CtDpusN&9SnJ3XxJR85efKCZ?2dR-Q0QOFS3PQX zc=d)mr;QeX(2eF5wB0geOEU=5Yg@y{3wDD0oH%!l?th4ZYzmx{@C|ugzAc@|y*pE? zRzAohLny(Aon|gDLh#l|BCTKjHE!vfD++UvCGAVXy)+v-owYf?Pn(n7xmDr*633^% z<jO?D+8*TT6TB$_s{TaHgmCCEi4C#It#`Zjo zcL#b13F&M)UJyb!#2SBm2R*qXWp{LK%)z3W=a*BOH1tMPg&P=;&)@vcdCllI)Lf<;C`c@B(g=|i%3^*tkCcvyL1PTUhT}u$~IWYZeMRu z1h%ChXlt%@^+AY>Ve~f>x*TbjF!!sub5!$w>f#Jz}?^qj*XD37P#^GWbYpaM5? zL%6)vf8dF9`MUwXU?7cKqF60@%)dA{uTgsy8K|VY^qkt>*;-kld6O6@9#^pa`t@3* zPRaS-{(d{nUb4sG9=c6mi<#%vPw&CJ`=q5uU#RgdVUYZ(@?2X5{|J|)DBa)+j5hkh%Iw`n8_f!Gs} z)b3v${NpACHF`RF`(q!kUUdx>%u%n42`i|pXSzAl=+R7ktg%&g`*)Dng}Cj`%+pO$ z0|VtP@?5X=_4Tif?*S+0hA)}PJ2R}KY`3OD=sEro6DZ{AU_3#Z%4ov zBC&Xy{P*nHx=rK!@I(Txg7=rrN8l7Q=D(n z2X~>~)U3Geol=)ejAwAHCR;5VacZVBV+&L4Ujj+!WXx6AZ$_cUS@G-BltIUK90rLnrq>iJD?13@ptp3ZTEI9L8qXd)k6UY}njxAA^Eswd zedtdJRCpi!NOq%$8H>BFKGv$6Khb5niESwFa-r~U#2tVvtU10TatGYg%8GF^dlFHCj1%?(oB#Ra08VRzO7!b59b$j6EJgs$EAml zqo)|}^`dm)8&9*GM#O*do^3WE(!}Ex3$f_b`FthO#sh6K->NRjp9CL;|Ah60!uVr_ zGc@2K3C^Hb?1`GU;AM8X%%761AJ^w*e#OK;xP8R)SX zvWfv~btIyvaZm&7&UVZ88d0lWJdd(ewY!^tBS*@a7^l9T{Y4V|YGK#5Xi$cj7NNzbVHkWHB1Uv+#};+tBMG zQ~^%wwGM-?S^~^1zI0Gh9}7v)R4Pm8;%kT%(Nu=(^{C=?Ec#E6&qq6`+dO@YKp9>M zdv3(=}NdzN&kj&j&yp{iiFM|$x`(?MJR5kOv9FmFWe-h<2$J>1^< z8WHeqRd&QqVi4XQkVUUAFW{mJO<7q-3P>_@I0yB(^M>=HbAA|JIO+(&gFr(dc?8xE zJh2QGQ#Zy#Yw>ai5_6?bsBrVS-c>5|N5@;F7NgV>a{?*!4pnuPjh1{B2n@s=PuKf! zs3h0&GPcgTHc4|pM9f4BBN6Y3aW?F+=pDE((NFOGV~}DB)*FWB>7qt1FSV*hRYFX^ zFIN7`&0dznWKj4hs{WwYZPn*?=8qT`CW+sWMwN2e-9*^==)ljvfuLc&#a9g~O0&6T zSDg8FzyY}J0r?-jA2xXAC>t)v7*vGnQ~_7SnA0A;+l$42>yMAkX;MoXC9@n;<9;mL z0p$-0{+dNQ7cqBC$M$>&gmZUHJi*fx{%a2g%8ew<$J0|VzYD^^t%EXzE& zy8c$8ENjSWUv%nuH_}K{`=d1kU=WYfFpo+ z0Uf#-JasymQ^DfC!Uq#L^b;DhJazs%MK+RBS}B|zD5;v{X|PY zP|&GK^}oSRo|pg`Asa^&?CI_1K>Y&w%)f*eSA{3dc6dB z)?YE|F<(cd=)b`9v5>3X#6Q=y-3}yr+Sh~G(t`)wy7e?bMv|Z-7$HO(wICLJ*QpOA zgnRXMaf6Ghrag)e3);sXR4QG-FKdg%_ZN&2|64hBFJlAe&&>=A|7P^=5Mqvkz_SDu z+28&^gA;ja9^QSxLLIl%M+3lJe>|ja9N?FW%vWXT?Z72(Zy(YzsppR`c|bgM)_nxS zxB2g`?+`ZY>kA`V2|{E0aKhv}#4V1910H@;wduwvqBXbA$`S9EHViU2x@E@u=gN{y zEL14-{O;v*XJe;obI&$9iio77XSXhr{j{fu)aVj=!~{~tx(}uulnPHQ`NXkCiapd_ z6P#;%0o;tVtwD;|N+YT5JNxK{z~M5Icj}+;L&iOVgtI2_^Pi8;k70CujpFezwLBLc zvasb@jM#5{xDz{_l8aGw3D=xXxj?LFTnKuhiS(5I8KiMwm4Y52wx-lsd^}7~I2=4% z58GN>f7LIvlED53aL}`gUWq_$?c(CHiBU$({l*}7iO;?~X>2zgdJehB=K9r;cCr70 zYTOTy^6Mk_22yHB&c`Yjnm_M24u68e7 zNYxduM$-x?D=mN!SzoFS;9}qg*lppi`CR&)v;Pr&`IK3vV83YQSbXl(hf7DT2HUNZ z@xKKuE?3R#-uMa}kC_53TzO}wk;2y0lzq>poU|aPU&H5E@kF6j8~}M-rsoEFL9q;q zfZZ#34ki)BS2HUtsbpkT8G~dJS0={25fe)8r&dRP*?9=zP2Jog1Bh3sSL`}GM|ELx zBfr8`fm71HLHA>DMe_mKzN+Hd2m0hs#`J2_V&;x)WaA&lw!J*f!Cu5#O2p4xb@Q+A z>;4wiqhAG62s0N6fPNF5ELFa3M(3kBC%oNa4xV&|W!x|R^`~IBEdDbrNT%}KT66@WG@_dA{l+x1-dazb zNch085k$7lI{s=wwCwJG0dF<7LVGhGMYbnh735$6XoeKQ58s()Kx8ocaE3z3^ew3eiFpC~V5kPksG53k zHNvpm)Q(-m{YeF1s$y_#!Cx_}{w|%|Cs%84WS$xE@z2hITSV;lGyQX4xa}2mg9xj%xUKaQpWALJ$}h&(3PF<#pY2D9%Kq zrmxoE`LLrn_S{ksG*CHzep>Z{AG3c}mKs@q>B`KN^O+UX3;$vK3saGmIfh* zs?Bfua%IMoLkMeBF2HP7+nRuFlwL5j!j2Ydrf@4~s7qB*uiD3Vt=rxEHJdNKag@t? zONKu&M1$R^VQH>r}~C?JgqoV091Z1{{U*>n>z{tdMeB? zAIQ<*dRj9;a>JiMA*{5GABQMC(6I|vqGSre86dJ9k`!CnDjz@OR%4i^9U;9yAHz%o zA`>h%bp@b7#6Z1yU-E5$PBp9mx#2Q7(;^WlQSBHIDQZ&o`vqh|xco;GjJWOA27Ny- zR&_vevrmNul(JP2<1^*vH)~l3qr09fq0d(6JHuF7Cg;4)kOf5f8h#5bXw=Hdc8{Rk zI2c9Ql2a<4hIZViu(tcLRXqg_;J!-x4*h1BKk^8Tn6BjIZEl*f;Tb|dDj1iS|Lu}V zHx#=fagoKRjrigGJ8%Izv^TMvce;GOHY~LkMB10HOlafKx}n_Z&-jBVEUWsj7&xow6jbcN z5j{A-O0JrGAwl2uEed5RO4c5rUquPt(`Idmk&Q=bBP@IGY7Rq)M2MSoxlQK%wC{D0 zFlA&RRUK*2$5M0U9;-4@2Fv4dEOi4(KqY2skmH#huQzcw;&a)$fQ`*Z7AmfY-**wb%v_ zx%QbJe`CR^vCgR>v|ep@DCorGYLUg}QSGPyqv^Wiss8@|y>_;e-9;&TWbc(IW$#Ue ztZT1pT@;m!jO-OMFCy71m29%NGA=Hzb?xyxKEKEJ{NoRghr0K^?>Xo7oD4H{vgnb1 zf*dD8q&vV?@NmP_yYhs%YQlBZc_T**Ss2^4EXZe-aGh(qCZuq+<|kQ~{keb#2^@lx z)%F9yXU_@tBdN?DjDZUbKHK%;(HLMH+NL_c=y-tq`7kn1*MV^NpoLe?&9MyxIi9O? zsC-xiBi}7b9fBf#l`odWj|!Z{_t&1PnpqJ~%oEpnb!`gJK{?*45V@~o+$#Ar3>z&x zQ45;c36bYBQdt9b&@9=m7m}11GMP+Cb`1`p$n&8)^{~p}HLp)kjSk%l_sjIQ?5@Uw zl0dEWdenawUlS2!sSnRgKGsaz-fsuV!44GuuHrkV=H>d=e}Zw?r7bGn3KE8-fkj3x z3lHEE;GHYpGLyHe0B^XUr8RQrM7sYA3nhVj;M8wx&FO0d)T>n{85g#~pbU?I{4#2PDaQlAf{kUgDW zX&>rW5J_4hdIoc(L?(GZ7gWWxy`~3JiM{07jRdt7qU-1E?=M+YxJwXv?TrBF?={nj6P=#6e>gaDk;S7mD;I_79^5Z^MDU=Eo?b_G^?1)bW)ZUP-TUR68@)vn`^gCiy z06HXnheSHm+=YCf=pd3xkNYFxqkAsj6d_0(KiCJ=maOWv2f z7mP#!EZ_p$p2LEtm4$N<@%^OA1O+GyU(|Sofo!?hk{rX2-;o|BEpsDPCLl9#FKEwS z>Sn>E-XqQS9NRqhSkJpf;}}0Ic+lUyA`CYs4zMLGWz>%9d~z4kYp{hA<#0RnbNdQo z$$68?@z?U&ek9@U&T`Hn(ROgFUa+Pj$dyOe7VOFNhcp$UAD>i%+gL0y#SrKPldmr_DFRvdjOwX z-Kvj7y2m4D1vV^Nsc`(Jf1pSzsD~slwmk3~?08yV5vE-Xkqt5xc)rEI!eUDNX%Kx# z9I}Ah+QK_JPxRDU$mjxU3pQ&2V|UwvkE(D8fA#SBo7U?yHF&3EhPg=Z5(|NJ3Tr1a z!jqF|*KVE9+AqQL1pKtsbEq=8ray1^aOVH&>%$tT!;IX67W&~(*oQZ zz~8{qN0Eoy&XgEH3UBl{>)dItcQ&MDBx*z7cr|zP_w*rlk3EYf1(>ZPjfpgBW^hBQ z1v*lz;bD^Jg75rBH8rO~!O%|u^MWM?cXm9GwTg<`tR8HZ6Ky5LTQwOk!4nLZde=^q zGCZ8mI^oH}gtWKM><3MZKqLpWZ7MWkbmdmygp9ppD5ZbZF-uN#B!9ZyL8WlE{Xpv9 z4{{-ip1m^SHs&NJ_`c7*`}wnP4u4C^p=YOP2Pp{N1ATg-Q3$8hk_FXZO&BMFbbWUE zYSIwpiL5Hs=momM$&Cy7w#Cj^*30ckhTRNJr+F)m@9xXOiXiEG6a(?}EZUXjiYpwJ zgoYgOCEtl9?!hx}THOOFv`?PEeej%z8g6B8*PWF$PtD!o8U^JCl9CsZ9ji*@uPdDm#H0SX3tG`d>H9K4JOj*>9$wp8 z7LFiIc%=Jf!WqC{?Ml^?((a?X%H`wk8BKodms(lgVmJM+oTv3m8Qyr_>TgrT^Kw}W zb!oe(!Q47j#InQ2+)w=jK&Juzj15Yk2+c-sYxm*D~J3 z)W141ddS$AfMpMSeWv6Y@dCE|% zj@(({^}(7%lVSXk!sWhxSP}Cqmb(Z;wcb2t1>jd>z2P;l1jplPjzqYO|g~G@Cvw zZc>IWn9aXaO?V86aUxFJ+*A%l1K@uaE{mNVNEm)AwWja$=H4$EnV+B7AWeZLTteho z*s4QqL?!f@o`qcW=O8;LTS zwmU=yo}3RbTLSVG_|V2?F=a;|x}Lnv4caJKD(mXMf}1|Fv0k&-ISmd;%7vQo?|;V* zdvmO_`o=I}knQyOMD@~ANK_OrukRKlLm}kijJ~yqlJ-A1*M_l1Ew+qs#Zb?FoS8hj zS4;vSvqz6u|oG5+>vc5DZt|DkD10RNFW-S0Ul_bPp=10<7oLTBn|C~FZ5y4+>c z8(z-}ER#!ThwTg*aQ&2a8x`f>(v4UZGz%GtK*FIS>M)<(=Fr1X~5jpi#QWQ&8@xN}HUrOBnr?E$hF#)OEviWM1or zTdcHuli$uiF#XxOE7Yi(5?oF6A$t;;#R39GSFAwOxsQ-vARju77c0UPa)>P)_K^V? zR=ai0yLGfUb6ZE`>#%XM?JmyI^)p#y-><#!L@f^dnayc|aWG==R`|)jRxW(k_-A_* zD^+S9`vWa54yJgd)3`GG8B4ZP!S$Gbh+6}ApfbJQ0qHi$z*zPy=GKmWWbz-LV& z?IK9~{ok`-1t!`PvJppx2NSMG*9Y)H*yiNMuCO9U)z|%B%*L;m%;p^{#Qz{TI82ZGWw1?q z{W4X#j`3|X&fW))d9v+P9-S5u5mui#sXD%fEmlkt0Nnp=to--W3WJ_USaCWkM1}Nf z;mttKu07YKXw8xfIM@JH%{#T6TKfT-_sM%c z5ogGDUj^ISN7_Jqe1wS8JZ_=UI!Vd0-HxB!&VMZ1*$ENfhpE-rkpBJgmm?D$yc_3=cU+dDe)tC)W{G57^0*3J>N2UMq`|T35T93-X64 zrGtXtg4?B`02va3rIoSwc8>m#bH`sbFYp84Unn%XGO0Df6nop}wDqO4_wOeUoD z#Nb|aCB)6|w-Cw75ewrPOCHHYyHXwvDO5J-op;qO%7_mfAVO$yP`jY%UbEVV-I9!q zK~ExV)=OHY)Z3=tZA5u{dl%3{Trn5gBnq6d;-O;x8*9gk(|PlH>JY|?{>%psTDwo3 z`jl8{e`DwRmO<&I)j3bPg(=>fP7^x4J3^zNsNMv-ho0o?!QXBan^QHeA!aeOcj9smt(s#TvDoIrxd3eQcyr)Xet3P> zKrVMmc8fH|up}?|p7IRJc&_)i`HI8uM*nkhGPlB<^4O#4LU~-VR?xbhho(aZc+Z|T@|TpS5Z(= z4dT5mq9kW3qjfn*Mt~3A*Osv7)LW0HaL~6~M+-cqD&GUG<;XOyF@UkOvQYO(_S)-_ z8Xk}$$9w%l4>+poXSU$H6YNE;emY!|ED$oXFhzi=LN>Nm_Q1FKmukUvay(fOQ;MM# zuJA1#HyK;T^E=j!2XU#9RMjS;iVNb<6u}Nt($;5q_9@a;@ZfXXiJ0&&FPn_Fs&WU z@X&7!E18S+K_Kbi=cm4ithzDt{pMzm$u)wBdDf>a@I?B6=9tB;Ns;{`L4n&vzQelg z+Voel0fJ5?71F{5xhAE8A;kedao)(LYM?Q2Mtk;NAtEc=(#L@$>nNgDReaB%R!v;V zVD#+hc=}lvIx)Ri=ZOaQ6W|MeFG5|+%6WjKF{w+t|SWbEm$OUE$peFo@PwFYA}2-48oxb;-@LV3Hw6$ zuTUE?t9~gjFXZj3zKAq}=1}wVTdKFiKpDZaR-Lnfzg)@7Z$ec*nSYzq?rSyRRlK(T z#Td2X201$!ub%(75QBf1o{fBw`Fej=3P^sp^641wLe-gX7T^k>Q($x^=ppQZEet902F zyHKf`XEX*Kpw**RCiA0`e*AW*7L4=y{dIyDck2%Ka%wBo*gvbO6`49$|7BY8|1_^7 z_u_h}I>(^iL+{`{e{)?;uJi0J>)+CERX<4HK&jP#rtN+#RZ3f;&R*{L%q{b|jS$tz z7Q7h1UY?#@-_%^5=js1>zyeQso5Rrs^9F#Vf-hxfMbBv8U>L5!fkiL1lKUm|G#71( zV&-ixF2zQOU-94wn~Fi9~r!3w_J>>SULq%Fd1}F%7aEQgd7V| zov&cJcl}`Huc{Pgcr{29<}<74QPebg;_woqZ_nCKu2jF`b>PtYmO#FOOVm=z=g*pH zG#Z*E&z~d0hQfS7q4%ab>%LQ3DY7jN2=u0AJd9H!fqf1DF+3h|AP zdEnZiTe}$_c@`}(=eHOw@d63dDt0#(j`z?5A;(Y1Zw4Rqp1l?9aAO(3=i_%bm*!7a z`s86PsgK*wmNU)(4LOx2BtO`56iH*^ZoaaB^8n)Y0;>NiSDtJpsSnZZ=gXARXm zE)h?O+Jk)QA1oz*taJ>YAJ{|T8oF`{w}xQwRLxo^BkfXsCW;8?Rhm3G_$JQwpwEMm z^XCG|QCF#MAM*?Df|zwa5fdQo9QK^tP~|4qmwRRxVYBOR!Z)(0L^I$!rxbe;MK3p`&gYjHs1e6pMu@k*ogD0*0KF{?^Z94$h>qpEuEsbkRMFT8QxQl z0Hn)SS42z3>>;A@=fN?ylT(yzW0R2s_qr_1nVYlpUrsVAw@UuGFw#HVlPqX;aZn4C zpplWRL82FL%R7gi=}0{$Mb_;>6Q5}M?hieRuSr?%1%>Y{@rj97x##CQ?>4gtSpKlz zoniS`G#!28rIcE;uV#bCr6Upka!q0IpWqieoaE7W2RW%Os_jz}G_(8*s~e}P4Xu+O zuDVHEmi}d&oa;wRQRW!GFln7Xqkis~n3n}K|A3Ir)#ma#uG(PKTPXr%sofgcCCwOx z_N}o;%chJcbEef_T-AZ}J5oVS=w?RLtY@|$n2S=ZLyr%zN?K%?Ce(lSwy4csS%Z7r~NfiA7gL#k!vD{0m=fA|S)UG!9>?x-11u^Alb zala2FAsVt7Ov}?;jMt?H8J|Z}Vg%>UXgKY5j+U|luD6<-xJ#Q+PPapD7jQm4$xPG-lEbas6tmnmAxD}dLwMDj^x3UFsAQ(4t0?JzS}%a?F@*_O zZjjp)-Ysa+jyV>}-Ov+~AYLkCdZ)0CgB3D0>9B9AK2+qY4Jd&&*Yu`+$nt82AegS; zbRd|L3k^y!_XbKZFKJtvI>RrY$B1pN$b|&pdy+%!=dn^4W_7>0NAf8Jq~|U&hXR=s zh_RJtefPkoNXkEkJ3rl{hTF~X+7HmT9iFYAHY9P~C_VFTY@NBL2AQOjkprtfOZll! z;&a7P2A1XWfq}gC_C=+@;9Y{d!$mDs&Trc0fi=tjUPos;^rH3aD|9pnIIBFHJ!u$D z?de*d`Xre(=&SR?{XrjSf~Ti%Y$e|G@y|ee)Mt!(4x@@5D3sY3TB>!Jfk>hsiyr>s ze|~9;?|vl?Z(o>VDn}naU;44Nb(C!sE*{bT2#NDfCVTE(2^_V^xzuoZa~Ub_WJV%@ zX!Pj(IS4*%3=Fm-%BBq;d0T551#*Q!Kja?BdY%smZbiVQ95~{5PKExts`{r4kfy|T zAWApt#N0ScK;uUG(EodqQeLWvOx+_#@?rEDh z)2}5DARgefAYd6ezNNKytODc)M~ezEsy_+ zN9|s~9coo!y;rd&ownh(A4+-!P)Vd$6`2E0(W2?i_~{Zsg%$6%X^jp?I}QVv__h6; zMu{(qhH&-oPy1M1Q>}n4f0U|sN4mySZwGPcyN7&{2dg^GEni>EYWs{{+fztJn_cY* zyU9=i^E$V`sM>8wQ`^JDP6L3rfa1c!XruK#{YpQ znHqy*0iVQPhNNpqEhA+&K!_s)Ne*!{4lxwJs4ePjXJ@yPWc1>}Q?OODz)X$IHEEeC z(kT{3jb^tD72p2^_vfmxVo+YTUSTh6+`(~yjF_Ae1&W|NK!U;y42!s z0R_n4ID@Ij{3gd?pqgw4_z^meH(fg=*saX)C#La_xh?edZxI4m-;d9W!rmt zNR~W)2OQ2*lmo?MmMJAd0Xa@|Wa>E>N$9(Lpo7o2Fe9}epw|s~i~f+-cv9ywKd@Uh zY=Xk8EaOP(fe;hp8d5)baNITm`JKhI2yIv zueby5oQ@Zfaatt|)A`{IAI`JG8V+3Mn*8@xfUdxCwEI-!N>||ieb*@D^(C;2AI{X< zd4{kqP+hRGz)`MqT2G^4!;Ot^w4$O&mh?M)Cw3h(73CQGoX*cHrPjK?R8-8-ifyvm6~NE&R8?Sc8R%U9 zx}p8^;tmrM5^f-Nv<&7tC5G~~-FA_>F$kw_&D!%yzA+6dqVV=8`W^qehIfl>$sM+( zhM|+uzk)j}EiE7}uGkCe(l{0v6MiK)ygd^Xd_xAecE0GiP0o*C3)Cz6a${S#pk zKPWQS!zSu{Yd;X?*&igo-#g!Egc11~$`=4;N z+u9Orli`lVPupjvtl@-Wes|htHqcn0{LQ|mh&8lxp=GOj_PcSY?WG<3BtQJ5t~-_S z%cYIt_uuB;>jRlGzFRZ(cOvU}S&=~R7~=N^d4aJ?SD+z#?N|f!rLMsuOd1@fn21B7 zb=_-nPk!FEi`Tuidy%!P)RT_G_d%_1hQIsmfWI9qwR+yxtWfDh_PTJz>-L!LInJEY zDt5^POSMiJ$%VJHw_L@Amp?3SCP5={N3p^%AsHxi-2R3kG^L?`9cW{#O-at!ZcP4H ztqcACHUQfWQj1#4fi*ilfq6RcfhG%dJ@W)#jL{Mn_uRsF9<}#KaEM&Uf)Bnv57&y_ zE2g08xAm)QUpcM;VhD=B_QAm=Oil#eI{@ME4*+1gk z!7uG^j?n+NY<243=OCm41_EXmIu(A!>4+G__`^6G^1J)@Qk*8K-giBC!amZ@wk*%9 zWK0pKhQIsw=ln=pP+b9nB;YW(B)n1F8hbgTKW3$N$!z%LW6z`xrL%&zm5I9~&&_&S zv-;jD$6_PIH}LMn{CuIvX|2c9!j+$<|ErMAg%U~i%*{bm`?W$+d_@Adcaq_)2-QZo z@hZiB1jRLQiLjFs={7LmY?M~~3+%$GX$2H~y4(}V?6(8@l7SF;7NBAv(ZaQ?_{gk$ z3fWe=ZBq*p!NRCX86Etn32K?G;c)oYiU#Nw60iVV|I(m0*zez}%FO3EX6>pI{=CO} z^|IUX`G`+eKb+NnXpU*96Bb>DFx8N~V#c zcSgR{D0uyioGkgc_@^oeg)W>%pr%=EWtw3{=MdjSjMIzDXlY8+c+lXE^y-D#2UV90 ziw3W?KPL?cE^BZdafLs7DLCpchECO~Fe-)2pV>(UdW~2mWy*67N#J?Ls-fil59fLB zS7uL`qfgY4w|XZ&`R06ce&N7+a~FM{)$J%}cxs8kPL0=2cg2P6Fux@TlP>P?g}2Hj zEnuu-Re)=`^(ac^`x-&fs9!Mk4iD2|Jjc6bVdOlOHXpd2%f`ZV$o;(~g&0Bt($RvJ zKUhW&=Q=zz<}ZBEK37;Ut@5C!^s=zVu=vrdk@x4iFGb#l5nkn>voQ;;T?P{wWug5e z@s-Y3H2kl+TT{tZ4P}Ghb5l=G*UkF{ZoicP?(rv2AR))eYhG*+YLW@(g6oPLw@E&c zEbM)8MiDKz34vtMy4fpKBSN$0-a8=Gge0m*6ZPOF{wFQ^lENXC3CYkD(Zt&U&Ie-) z!Z&~fjT)Fas126Uj#)0EcvUiV* za*VmG$Cez(pm&bKl*EQ=+aXP?eutp+PHI|Jp`a%0C`WP5RsVp*ylxMeGx=ui_iBr`ue=XrgyJaRT*i}Sm^Yl z?J-Yf)!f0uEi8gy`+r&hAQ;8MkbnzBH1FavGBYzb>DEyPXP(lT{npeWm&aFd3_pL+ z#a>mU9GDIc4wh_z(0XgD+kjx?;CZza3t%Ayh!vk8p4AGf@iKL~hu@8NW9gJ)@z9hE z^#dqNdD(B=>YB7ekSmwcYuUeM|1A$qf8IFEwSGJFM`mahI4#jqc49P=sB;Au_RU4- z%dcckg=Y*v zP-?j7k9stO?d^fuNNliz1MaKuMFmyeVfwwIpo+7MekU|~ww6aneczEXaod;p4MZKl81xSf% zo4;`R0(8c}gG-7+B=uyXMV&#%$iAU16mdwKiK(Bbm<3M z9sXPY%6&e)-{*?Gvt$vwC|ok%9qOXOft)&sZfNKjb&Q-iR(!p#7DvFZVwNdM zq&Mjb_|EM4Klh1gf}P7_*f*aOdZ9Rfti~O>GZFOu*1#U#9sxd-H+wF06HF9eyBBpd z>(r#OEKjjU72Xqj-r)WO?y|)d*+6nCBO|%vOi|qA@sRr2{ob2!3dVfPOa<)Dqw9*O zh~@V%Ipu|VgcxeA$U6)uij0o66H7lL+fr_m%T0wMH4KN)>5bT1g= z8$5T*YqZ=S717yT8`-HbeRtsg=#9cPxlB$xJyXL{Kks#K+3B7hW2cV4+Po1Xf*e7T z+lCS4RAlS>mw&D^`T6)%o`@!O<=yx82z&T}j?PVPIZ76$7JJmMnTtHG<{C!tSWj}L zQ;eo}*kq|89TZqM@_xS#E*z~dIxVkb|?7I9E z-&!2?yv(GzBN_7#q@L0xB z@COUi;Q7*Q6kBlM`<{-D_HJ6r0E>ZV@MGHEXnb?ts5V9yl9V5DJ|c5!pP?s0RMh-P zheUe>b=)^oc*EF5IzR)je;8&Si54DY_;RW9aG7f*Z{iRjpd_k1|P&&ze=Gco!rDpUufCWLabdV+5=sw&N;w5 zWtl|!uI&S-fuW29U2kNcj?q@3wqnTW&V4*vHe~%6pwYPmEJtebh+hX54v+GHa{KTn zQx&?iEqbExk(oUux%FlW{1U$PGHSVw+)U{t!y4FZ00JT&c$;8yySJ-JIooUpM=5ZC&>m1X`KF{4M4cmsH-ekF%o%^HADQ$IsB5mw2FEIM3Zuj=;FWA`Nnt74 z$irXvkI2sK)BDd1WOl^a*30{yV$B5zG)j_DVrtD+avmt_^3iZhzJH>LvQ1v*3=)G@ zqHtp&Y-CS2e|)FEI}HWV*Nb+jD!`Z-+@3fdnT9s87Ev+(D|fDi_w_;`O`wYy0y#Qo zxRw)4?>*pd^evSUSTGXx2!68-VwV*pI7wc<>sl6OB*1FPD^a%wHSX1GFj0e^Kv}`$ z*U~+G@3|8gA@CmuPGV)salmg|oY=G>@i*VS)15`FU?{C`jve<^;l06kRip;{Sx0~4 zFN!7A_xQZ%kFj`Hml`92{*8-t!UjA4lfE%(hWz_NpY47?m~p=(H~*0(@YvnoB0jET zUG0Dy_3RW!lj$-Vj$xCaH!h{6q@?_JRW9b>^go}fQvTf}e)aX~J>HuUP|1+F%`L;h zLRO(t=v{vVw`i~*wFFVGRm+bIKVc#5H}X)+%M0BXN;1Ex8aHMr88s2uWZ6}D)+{u= zpb$F14?l7)BJtpo`&A|qG1yJqZ42(@03+Hkk)OB3)LUKdRCuB{4gz7JGTEJjb9s3O zanI5<4qoa~?m7^`QBUO1ce>G^gp)eoyiJ>%#@5_gc0Z72jgBBcBABDqE&rB}TlEbO z^KU(jp9D>|ffQtA;r+h9*iXa>Ju%_+lPu3_%soXs$2tp+o?W}?dq=ig_3f9;h?)Jz zh5@e4HoXT$%>J^d(_u_q#4UOV!?VW9L5taBWnL{!w`XHKzpAUA)#eG-u-1J$Tsf*U zwKYM$99b(HJ*k+dN&yM_p0Bzirl*vVciFH6b~TF|!7%l^`)0RTlhygi z+`RM!^d<$fh<~HMJhjLRUF^XugADSNOmFFjG(EjQ|LN%od}L6+<|U|+3|8IS^PRJz zY(d5m$V}=lxJ%B>N!2tbwPG5gHs9a>EaH$eo8vkJGF}ncv5Brd^;tGQ-I@<*mW@5c zTC2JL1-30dJZD#<(!P5LX{#p4Hn43L6!gE<0EfM5-hW(MWaJp0laq4mG0ZLRurN7N zqv9gk)NWus%Ofuo9MnSa$RA*=N4dHh5U1%J9_gn(a8V>pP$)a(JC$V3HUP6s-^yvEHWwg z*Eu+~(XvU(I@OaVhQ_EBGQ5dk$E|McvXa?<;X_zXEI}NKkC^az0f6!7a#ZvHxm=zMZ=|n~*Bg4Q1EGFFe=N`RX z)xm%9nAo@u(^WPzG}jB{b1@!*h)d0D3+Vpbzlz+uV_FH8n{%d?zewV)gqF7Mr>Ie~ zkt{L&q@1DO%j$PcMB!JFEl;f0n_~V$p{+@Tdwf>bvkvU^-{dDz(Aq^dX@<`Dv9S^n zl<8*A7A74JPj(S@cL)RdtM0T z`3A``un^=#lNNlg*1*+`j|tV9mv-I~Ie}j6u*Sx0_#j&^Fn(uIRs@xk1nf+NkT}og z)1+C&gB0yxmAjp;Tvn)Q#$+}TNv=A=W8YI8bS#8fi{Kr93r$-4(dBGRuL>m=Nl*vf2 zKNo?AhWVMi42ka#K6cio~$jfa<(5e&`^{iZ_NLeY~n69~Hmd2@4``Eb5oG9)=@#&!&^AQ!<{`7Rp z^Wcj>Um>H@^DVf%Yc=!?eR;OfjxvJ)`QhZoVGF=F^P+kA>x)p+i;^*(jnLrJY4zpC zdBP*D%eB89f+38cfes{o*P!DE`q+y)7yUA&dwSN=J#ygR9IdkTFKZ(54@KDe1{%$y zBUq$z>0IM9pA&TaQoR?R<)))@;|61fa4L!)cR`&K%Unim@@-}8pnFH02OTho{wL`% zFxo#~IX#>g(gCT5WqHVXHb;Y8${XL|ghH&gFprOI=GYw(0U?PenHEl$xPRA5JqCZ^ zHHLPyTbKjCAp2glBc!hIC{UeS^C3UTYdAcV36T-$*c)A6fVnnW z^s8^xShjBJ91HTOiSziChFd6T|5)y){1}o~1vkZHU!Konv3s&@A*Ze~GJqmQa_yca z@t)u#4F`3n1$s!o&#<&*U;6VM6o!y)w_YBCcDCVl*DZ>5US2L9HOKWlCKVz=$7Sr2 z^qR4~CFV$PnyN=UJ)Xer5H8#A4$@?go7f;5*ktuENL*LWJxHg`XjnM@V<7V-C9Dmw zeK-dPl!Z==f9-P;0G(^Ul++%>>p%Z!iu5thk>m0M{l$4MY^)M-fDSfO{X2ZcrG?Z?c1#UrjO4|{86i#RB#PW_1dIFoY~EAH?K|A-5Q5;O-^KgOhAEZ| zi!(#i?QI@;0@Wv9vt^8vXato*q3UuM9sM-MJ(koo9NqF9sZg9&ifxt4KUGthn)9iL zfcul~albFb*s!02Rg@JmLEp#5zT3S60{KVReOvJ3dgOvmqO2fi=^>tLy0?c~W29au zva(p`hwh#@1WEZI7HZx$aGw^A2&|GfV`1x>mkPldeI6`rXR;R;{h5;{JR+l0z)-1v zx0ZR~{P0P^vA?K6{cPrV4#-f5iP?75?SNZ!0y&q3z*CLCb^XFd_PHj6XQvwGD38Fr zh!V`GV6|sgG|`BT(oY_cX${F4vTZFRU$KiS(kPKW-UVTP zD&AA4E@;(?ogkE>}Zrd4uEOTT`&o@tT4?S@xDJ&;0 zlDP^|;g0&j-QIlF+T*>yTC$A8%U9)i_ z(_{FgQ&kxhtK!ruJj$uHN zgTlFkaD62tPIDZCT2Rdzk(eWid`ROtoUVaH5711kdy{V);OPlOvM6*u7?iA!!GXniX%`lQs zZeU)Sor{#`r=5!W=;C@Ojy{TkU1=Gd4-Ns5b|6O_XuXd*zf6EFQH}NSpVwp%@;f9; z>8zh`0uOQ5+Y|poz!dG~UK7X-DUzN;- z_2$OGL1mz+=)0p)*HeYFzhfTg?S&Xz>sYdF<|VQQQUBFF zynb{&l}h?j!fDRcr~Ek8(4Ez;4dWl4`XL=25o$xap5Vj|QzMbp*f#StHw!7G&$+xL zrV7v9mXRT^ZX(}qy)feY1}ZLVjd*rsksP_5O_rU(CxNT3h15%j^J*cV%*%UN+=iLd zQD^d*<@x~eqmt)J249u)dua$n+k1k;ygMJyztcl3n||9(_f&aX5rtDmrjF}PTKW?f zTz8%QzP>1W0j5PSQ$+KTKk8Q%uz+I@;(~+HK(eU#bZWTf6LlS_=p4DHxKNumU^SH> z{V|F(uef0Ra!Ujm7%#Vs=)F;vK`KeOH$?F$L3n;VAgf}$X-?f5eoe8~6dq=X-^Q_= zld_|jNvoZmDC}a#lD#VlsH(=oE$)o>pLR4yJ;ILzZI8oue0 zOILC(W*SljXMf2%JyD;RUvJ0QoB9$kF|9(h0K-c#CukLkJo(n8MO!Z6;7os1|hZNO}l zTBzTSDTmpmtFr3N44dErcM+A(^K@vHs@X?WTSg&-C8Rg4g7LmTI5ih9fF4aQ)P8kNXU;HS+$0qwCp#sA&+MFvg;l0d3rD3Q;Q;(QL~{!M<6}>rsMe z1Xt%5!Y_`5oW9FmTL``kmY&Vh9hyzp^g1x?lxX0VTXhWZk#_lpxTP5HDE6L0=raho zvXQFYs$T_`;8_jQG3feZ-s;b_oK4f`1&0LFd~D;-+P)~C@9TJUp+4%#cb|R#J+sT5 zqIJ*|WNr=rNRpv*I9iP7mB-JbYDq0}C_#uDVog!Cns*OtuoRR{nr`?uSXJ$KHLPRr1-8n^N!bkn%C>7q@gV#3fWd>nAWV}#}O%8 zM&DO46`};*7cFu>GC-j~9`=TgJ{5?TjLCy#kM24yLa<8Y<_UQJ@>XKZpuanBHI#QY zy_mR&7I|esg}imxbWnz@*CAqV?ra^}bF04dm7i?Y4p}`UG3WpV+RSvSb=6ibqRC(k zK`V3FAR0{NHu=OBSGivhf>0Y%s0BsNqaRM@8q`Hx=Gb6oI2{Nr>d^4QrB$Xuw@e`| z-f}V3(?*66l`pkY5#;Oz@xmR`85o6C$?D0pzJ8{ylR3`jtqvuXfA>%(U2Zwax!omf z!F0&Lk!y!0dx`0UD;@jKS=a)`R+jAmJ^~Bj4XwWmnJwX*PGUBOf!V18ZRi!xY1V^YA{3<~sOjjY<9|GKDQiehVsW7)_7jt zN)9g@sFI9{ekXoKo=D&5e!k{&850m@BX=isQdnWdg1DK5Y%z@sLzsow44D|TzH=x+ zKEViGLLlEK_2g@`&oprVFnsbsyvl^<$LxEK%g5RQ3QqNccE+Z-z+6*);->@Deg*BX zF6{# zHkLQ(4AR*lI7Glw=+qDn|3#iz^PKCYAFX_LpO440vsW|f3+05y;3sSBL*l7{C z7#pjPyxWxQ@}hv1%toLm>B<;^XLZkK6O%mW+t8pC;t>wZ93ZXa*JdT$=yYMM7<-_invBste&! zsxPx6xqon?i=pRc&sKP!`chQ;tiR~jo-Ed@BpiNqgq5CzdJ4v6B~qWbM-5U`EAWOM znc(fZN0u{7VHs(+-)CJih_#9`y#T6lM%&@92lL%hnCC|B5_@5pgl%$tIr7}=*t{~= zUs3hbSQQ=GuJCeNZYOb_TT_p=bF@#KzgdpQV>FRv!Oc^buMd7eYUZt)Ru8F6 z=>sx&Han1~LXeO}RW5xVT&rb)u5Z0qUb{KWzMCL!tCcUAnc^d%wMmSKZfPjQLgQyM zPF~)nuVfvIKz#43Mpm=`PYXcc-V8CO_%T2lhuM)Aui9A2L3g~_jP;l?gzmXBvS^Y4 z4L7Wj@eo%G^~zHWx(*p%#cAFtN@_>sNRJ-rHF z5rS3k@xw;mum4xodq>0hMeW}+dJBROU7|-#1kt4tB}$0i5+Qo;br6w6i!RZLkT68A z!$?u0moe%fdKZj7yl3)#p7lPz{YRFyVlZ>x=iK}3eeKT`p4BnT{v#QEoyEK1<6}s6 zIVxNJCdap4lEb^u76bZUK^)*b+S-cxnP0oD{?Pu-%@dmmMXd$>*O*f^zK03Rr^|2R zZGV109az@0jFMj|BLCI_Z&Xxo<-0qg3zTqaVOApnTefM@5-goj#Mevwen({~Q9HoW z!yCMjX8pcR7G_>c5B~HJVAUXIRl*PTbkIyAy**DkN5v(34uC23wVZ7dVzMXj@ zrx{4;V5E>?n~w87x|z2>dw|)U%IuEB@v^NU&ZS#rbDWW8yr? zEDw$WluY~LHr+UeBt54bO+&p;XbavZMdV1U7y||IZNW^10gfdFIdX`L)En)vpz3oP ziiLu{D86g2rhhjq>WSw#iF5KVr`wR^kR{xy5<9wcpLf4`4xa4jS}S|P^BNgnd0w1) zf*;#2lvVH?nR2Od1P=;g+f_L)kuoOHu|%Ua z7<_%9Ef+XSrh$>6)5f3kD_<0Ssmq%zl*_P~{B1#^oQdxQpKtpi{1DRrhPMNL{p31 zc4g{(B~O9iy)8oXv#CS-+SebtH=t)-IXykiLF8`d%{+)8@&UU?iBC9N3>~q#zH+{B z7P_Q#Jw*Y#bz^fYGn>(vH)ezMKd}U}&%(OxxN?#QysJEZ#~M77zD_r?!Jt~jeGjaS zGxzkiup;V#UfDd`-&j-gAm=B_)19mxF{BNk%+oYYYO);#6woR&R)O3)__F-s;@oy% zU6Tp$T0UQFr6Q@Tg}BTdoO(8Bm7ifODmuj>T|5StTfGEn?TC3CdMRg7faF*kQ6)ou?T=QUC!G@^o{47sog#q&dKL* z9$X=^S-dzsUAZtfcRtKq_eE60TdN{MT;9d3)FH-=@fECkk6+v6XfOn)QMBm;o1a%N ze7cNtWjbHXDp!?z@mH{h$i<(loL!D7_cr!XPI zkG-4Dutpl_&V+nkB(?buN+Ge#w2zDC! zdwa2E4DlCw%o62w=7b2&fkO>lohBC?%VG-+#R=QXDj*RlM=(+ulvK{G)V0R`+VCOr zjUt@IAYMG7g~Y{2{{r%iXv_ToFd#BI$^!gdV766Yp3Hg+?3k34WNRyVuAy=IC8)1J z(hStNimsPnqm-rmg;O6BPBR|Ra(+HPt*0VXfgIcKC!0chdIeldmV#8H++A~P0^w|y+xfY^?c)A#(fvH}p%^kuEL(!{GW%)0{% z67JTEUz9Mk#on=r!eU_}5AZRqdO0rKaSb5dAkwa{?*Z?>A71@lh8a|%qR-<33WwM! zu@pAjq`UI*xXcqO4-<~wiF9R?SkJ?(|AsYDuir*{#r&AF6cNHHHXm1LD8^z__IF-B%S5dT5x zEe1*E)B9R&j_4@y&eJgWL&?ry=1Zo}5tC2XqZsE^X;PoKl`OwD@Hlrkyf4uKUv5*o znXSHMExE;7h;#l7>;@Eby1V|NHX|Z-v7i55Gd%nSf>jy<**(@InQd5p{d&lrS#xEo zFy~8XQ3E$mVM;klmyKX z*Qir?((Y#j6~J0661p4AAb^1U_PVkm2rivt|E3Cj41UaYj`UeuCHPXKfk=#$6Pf&y zYJ;$t9oapLjVTyq^pJoy&{;jLQV0ld7`1^hr>}dOPmm165?}+MXm}n&SAeAHScLi=qI(=WHE0ZDxdFwwkz+3e&Q1pe^C1d6O7a3@*lg?{-6gA?c0vZgz-t9K!% zK3cgfoc1xm%B~bUlE+Yuz$w?%Cn^q`O-#P6H-vtKZU;=(e8UICZSH#{C6j39a-q-u z;o+gS76CY$sj8ClmAvbKj*j9L=Xd2Y;Fm^4)3_L-A$od)0v%8<-)-;A@`Lxn?D06n zt{<%R^2s38uUpqtHO*>a9h%LzJO%= z^U)fad>=am%}2Z288zdO=M_$=^9wJWylz(x1S0Z{1aiR;hdhVosDUgd1=d`h;uX5! z;n(u(VNah0d5=)jXS6ysdh9{{{+*E=bsXHw+%fEQ&EZzp9waHrqMQfi>TYTB`^A(C zB%A4B6d@B*E9>hS8<@(pv@~_3v8uh{#wt1J=uP`lxoq>!YF02tz|F=A(_-cFdD&ZX zP?BW2$9v0UwOt~=IV{y!s)Tn>{Dy&fyzq`ndua#IEeiXHx2M3u<_FXQ?dmVxrRyGt2q~Oz zINezM3wd+BJ@*ic#XiPwiVxkQ~w1 z-Xu{r&BP1#ot@(vAl0lL?Tq?#GH|MZ_Z)2E)5pfSc)17 zgI@eWZSUx0bn0Fb|K%PTmy7S|y?jlzdNL16!o9g+&J1qoK$?|Hv+5AtZrS+&w*KGB zE-wCQLM~P@$88bfydXw z$D$ip({_~ctlhq!hQ`Vlw^OMSM4_pZ@Mix5}Jc z?0elBAA};^S0?Zb=pyaz>>Gsv&p?D&oK`xhBO5M%le+(eL&7G|Fu;O$d^lF1Zj|he z1eak;4zuv0Eup8#dXa>*XbNK=n-I}{vYrs$UPLUu}+5C3l%KOPlw`d`z+y>CYh}XS6w9ApKhNEHn{Gy`0}0tb*Y&Y35B0@?x9lV35R)})pti?`!)Iv&OKelQcW{*;yWH*&MoSg%k^+Y1!yzQ zPMcS+xVVDJen?3P*$e&nsnrLk&6BZ>w@ZQw`%_d)P7bm00ms{cftN?VAWTi|jAzD> z=Zkv`(HDOSvz8e|8i%^0%(i|!YYthc)Jk1$QLKKi*QCCVLa%=haog3OIjDg(Bz}4_ zb{nzk)zTR+w*F(K5?*D; zhk{X@3m7HXKl6tH%b?Xm3?bL)JlH*I5SPG0^5MQ=D2qP#a9~Kv*3tmk)r1r9Ln%7*O?TBA8@luJ2LHLAM-rA|_G2C|a~vyRgfowO}P z&BL3sW7@KD0$WNPVG1HnUfy{nh?)4ZgWDmWgb+IpQ2*7Cnif~Kg_3P;vHmP}wzRgp zRQ|b}BqZNjldE0*u3l*8PNSE-7%2d6nxjN#EaMr}%2Oh%b{qm|X}9NBbW7EBG;Ck$ z3D&VHC$hzriNf%Rn)3yIAtnA%G(Mo0xT_O62yYm~;8V@!Eg`y+*6M zYF`BWGr>xK!XO4o#R3rZTM(+8|MB?<2_{ZN8EQkv_RGcF<5 zA6iCZESeN@ie4_Xxv#H#-r*r%FUI%4U0?smf0LWt-9^dmAt)CVI@SC^^CSqu5#J9m z6Hi|is0vx;;BSjndy)Zz&7xE*o78nX#%@0$Xafi39owp8$4g7LtFBEE4F+h9_0#+P zv;xy+Q^5L}o!ZNNdlQARG5ez7S}<8tu-?Qt|Hb!WZMA6VR!Hnd(a%N8ZuhU)raUGC zaH=ASAUz#Kp-__I5OHZ~Y2Qs2Wzi0IFe2!s{zN_wJ9yZ*luB^WqbcuFS1{>TLFTrk z>FX;RHQuF>#&{5NgJFkkZ*Q=;moLJf*D&DS-|QS!9scgX%|VAAEMoV5^9NYAM~BF^ zLz#SEZGf>vA=08mKEuSSrTP`+?S)2*?Z22nF_z7B!g}`tovWOH4JX35z6zYW#TY#s zAfxCi<0wKdjx-+KWCgh?muxWx2sOKhEHAm0HFwhGhx;#P@9YCT7sLe<1D@uL}i@k}o(kme$F>7gDfn zT3~QMHEzHw2XdE=!E<8QUvspvr3@!wCQaE0tcz5l)~w&Ud=6>+AhK4S#hCiCVEs$l zLBE6OPHb(_{=)&gp2o{%J1@EdSMs7b0#>d;z@)lQ(_#o2o-k0!8|>iVur|aCqfyc< zqG2bv%Iq!+yr62Db(9SqLFuY5%Wces^p5w}BL0kD7u$~;Q#929w8hDJ(Sw?_u@Pk2 z>+21f-NfGzB5LgH5Y@P`&B;l~{5)jNt>%>KRF$js8*F^IYsjSaVe?S20jINnrjU8; zF48n0G}&Yd`*Fe1`EEJ!PD+cVWyjdr{U~t*ixw7C$8vkD-N-ue*c8L7w!8jHcWECs zv2$fy`Gv87p`M6>4E99EvgtMXoC z$obW^wbg{GTEoOI_z)x+SAmp0fuJUbmHWp$C5+l9uXJJw7FD1rVKRiC65$OW=T#3M z0$>Gg$J(_<0@;TT*U0PPBx{Q&g@xU%jJXyxI}Xexm=#<;FRfv~tiWpBP~?z}y`2vd_y0XuBmOnwr?6 ztjvT7rds2T;nLDo#zlH0yH2An+gl{Fcf1PIh}V6sxBOt^7eVm@qAiM`9jNJi9#$vpu{rR1OQ-? zItm)cF6Xl`cC$K@{+-pX6iC`3U^s4N1!4q7LNh*sO8m{P4AF+JU<0j)U>gdaUjYMn$|x_>h`(&BQ8Oi-|&>W=H9w z3c#z0bcFu|f3DdF5fcMpQwljdda0=A-*h+=dVxEf>Byv6nQVI?G9Wcc5S}2qZOf)a zvTzc|T9sTv^InCZbkGWOgYweic@D6(of9{Z{?43Vn{Ud#A7H?>Uk@?RY8i0Ajn2a}55WKMi&;YE7!8G|_%ynQ83Lekob1H2cdET7oy^UD{D6ed zy5&k#PF#N{%7k<*kNnZbr7X;+7OulORg7!nYHaE6=jK3dJHV@{0Z+uyxiwU2(R;v= zy>&d~ww%_{hvz+lr}8QNC6X=;W)+QX%@**x0DPwZ91&Q}?b}&Kh6Oblm)CVPe@ldL+0RH8DT55?o-=R6W+3 z;Gc`xBZK!FItL0hd;_VYn7HBZau$Nd5XVlemri%1p8<(CJVe|iq7hZ;IO;hwB5`-5 z(mbHqYJEKZ`4FBdcRw#e^aNbWRXpV{a7*T_XSH5fKrMf45W2HgGC3IrG0~DKdML;lP7apL&WWA$3JTy17pgLhl=gbztW zJt!&^2L{|$n#*?D!WxOPxNka3qYndW>pTt)Rcc*%nT~7^h9!i~Eb?|8RpZ!XJQh0J zF7SHP4#M|9&N(h@LV=Be_b&Tm7QdHnvhkyBn23JQ=}Z%6nN8Q#isxq$MYpj}wO}?j zdtHj;HG;6*C{u@p*=3WmZLEzaf7c7Qw_rf9BsA&e{nc#LS}u6_D;;-@rq0lOL&S~` zW9dNOY7K};zcN{tHY-a?;Dg&yLaiy;P{K5{#zPI=nA6KWE;pDHO$|)Rwg1?xtbeg+HX2V>J4QOVRvdu+_x$yCc@LlIoWBN3MMK8%+?8Z9bInOkx3np>S|9qAVu%zNIna2 z{#)w4|EmS~>o9A}Xy{!+&@kj5$GAt!y)370J{B7%;`&tFFaXyx#feD#p7Oh6>x1Qm ztOG9d0w7G~IYtWA^4GlWU3k%l4$H&4XSTo3%i8~l%fcL4v~rSd*YXO^rVn zg&gg)?M;Aur91Lw0|H?e)*5JdL7K}mxA)TF28VAG^ep7=qe6(RoWEjD`LyGWZoYTv zpPW4C2z?jQy&o76oJ5F4nTY;fRGq2s>91MKG0Z`BdT+Y>A8eVI8YtZgXY|OSnITDz z1tkZk$Atsk(eE~NZ{C(Y2V*Bd!>x3F)7D0tZ}R|Sf!i)R2hpVl(<{=-%75V&$W;7D z@3+XsbzXc@|iA z*N}J?oD|xGCU(8>aDIFtyTVC$f^K;o;Ad1$@5$Cdeh+K3??Z@1OqxPRdMj!3UIZ$1 zr%JL^m7(v2ry{j%#_+44sR`I%02q(l(d;@Ng0ig|9Vkrl4gVjtwm%m#mO&G3byfds z2_;ufKbT*HDI-^VUK|`;zL*$88hLs6$E*CUcnngr2=DSupO`z@*(%)uQqjmQ?C36Q zG0o4|cihg^909_w=RFU%`lunwu43)`G&J1ldM|ud9le|{b$ocam;kXC z)sfc9&2Ja`suD`pWK*B+a zcemYiM$BA&`?CXfzCT>d8SqG3xqo>u95Wn2KW{=WOtQ8KJlmjwCB~z%LHUnq^ z;zL~Oa79-p1B>x+lBb~sB_Mt+h!Y5TKbTsz_@#`SiJBfDsdC%16$aLknwn#qO-*Dg zS2JEQy2q1-nKK+NuPBm@7Lyxw5omL%d!q%9*`Q66h}J&e0_3z)kjtvi7ly`SZEfy1 zuFi!|$V$g72;6gMPE{$HYhca$#2Sa}#$&5hKf*LP>s*V5Lqa_{xPFJwrxR_>MRA54 z9foo$JZNvf;i_G+^v}YUlIk;xh()M&(rMZG3avCjXGX7y>&S7hgP^Ob_`heXe{hEe z(69rbAr^-X+<&jLVy&E$u8bS+Uz;ZSxH1Mj`(73Wr+^PkD!!oK!>gYw3qMrP+1R$?y+hP<-NppJxTZ!WRVET_RDXQV@OmL zW9xeXYV>7gPr#EVg!cvW!SO)^*sEruexwU;?k=XJASel{mEFXv1US;(bv|{_w!bCw z4y(oI-Udsoj=Wd=;~CLkfR|7>PEZwRQt~IOH>-col~ZmoUbBYOvQm<~@^)+!64LtP znp!>W69EV?HGErd1_5pl@3+GbwuO88&d>HB5g_=r^f5mF@jccvLXYxlTQ!8BMa;;F z(pmW8F`VpAF99#1M{t-~SI8#Of=al*9B-S;LG!QcsWhL7y%nnJ3Y=WQLc2;swlkzr zjP+#vlpBbD{;%tCLME9+=x$aowv$l7mf^p4;6s{B&iw2@CTig+s*etazv;o?XD<;NV31=GVaRT}K)BKR@5T%!cBtSqQhhsg!%{0J8-K zP94v;nvSv^>jM5z)%QYY;gCO6omf`YDzu|3leqLmB*MIn4Wc0J>#JLEx1G$`=xB^R z>BhI`1e^+yzu~|##)%s{xIV2_zUvflL7SX>q2nlz4SH|?H^Q(oxIq?fa%fsETj0=~ z&MLC(^PdC6^XdK5L!q3U%4VhWqxtyOvs*Ag``9Rd07&scfHle?yqD5_%@1`W$>0md zcT;x7kB8t{RKabZj5zI_%k*7|kJZ*mNH4E+-O`>3lqVYvhjqZsNP|O9r(FpAlP4QVD4Lar9AG_T%&w{yNu(H>MU-9E1 z5-l{))92RXEiu2Z_uB*^h z{FH0-KpY(I{now|WuFu%5v;6%{93>c4mGD82#?F5Cs+G(2bOoOjunbfq;wb2kXzLx z*(_scUoo)=NPAlARZ_AlU&y76onGCW`(Y&P>3)-=Zk#&2euy~w5l_ytKdeTw$0zjk zV5@9e)O8!XE8ikEWG`t^tbe}uZ%5tBQ8hf+TNZN7!Cyiu+VFvCgB4pm?9ej$u42&y>LeE-qXsO)>4{knIkXp8y7 z3vOCvT#rOMLfGBtD{ri0%2jWX6TL=+Zp9>=p``4El7jVU3dUC@MuRucY5U(HLLxoL z(Tx^~2TEZgY)U{{_~0@ZDEMh-5sU#FWn+tW9xuD@r>Z>UOtc*SKj+8Ckiv_HPG5LMrM%_a1S8$F@N}E(r5up?Dk_PkL8Vnv({wLTmMNNWLC#Gu!gX+pbz!mb#`6&sgH8I@ zN+pZeFIC$TdBYi%_rXI9X0FzB^_w&wo?z+*kw4w2>Q_81rP@G2EE6IBXgt{czwLImqc8GK0f+7pM((OWdTna zqSamN>d@-cG(Ev4_T1JPm;OcCpNF*pu-cEto&sXX79uZ_Af&lo3i?F^x?Qr z-lRx^Ev9%+Ht<9DK=q?HBl7#)53Hr-E)t-3zekFNTvoUp5I}7q)EE!a?pq&-@Pv7Q znZIPv-;9Dxs?WmF$Gz0xaS%)BsbGe#A$bZ9YrcY~+4V;x z1a^ak7P<$Xzi(j%uaQNDJK4{S-=(~ra!H8TwNk&oFMrX`Z)|>i5|bfqeY2d&$~|HJ z_3H)MU5Jr|Fz}F#Cta`g^@2Pokjg+uk3R%L0$|orCTcuA>V$kgIH6`SY~?RY?^cpmDRGfS{>jKJ`SN!Y9Ded01@`eJ3ugabnX>T1Pq{EZ6v_!w+xz!ZI?Ai6s)n~!Y2|`h%x4V^+zP8NM=$S)_it|ilM}uqF!z3T$K;hG z_MOS%VF53&gLO&cdDZp&vQ>y83s5IWNlP#TC77=m-DM&m{yIJRCeEUM55ghw}0x}h;~jb>jM!07x1cY;&uGPJgK$UcscjKqB|%xv_F zyqO4>SgbC;dxKw#4syZ0-s-*j-1l&SCx3N_0=%C6Lq0QE65Ro1(F*>YWG0py4VA9{ z^1R<=8!zs@e9k@~b$ag=X0wvwP06JNTeqw_miI!?CnA&fuL_$7-3Rg&HX%zY`$E9k zr?zg9&90qdX&idAB&{nZtPk<}9e+07|5f6O>lUf5fR(1~=WAat(W-*|)y?^;|b`z(Y~ak+ECmSM~+gvLKbGWoVxW+bvdriEckp z2WRf0C%1CJIeoK+tA@VV5hVsv38rrus7mmx<2IjzLpJayEDC5(KRyVlF5x4u<5K?i z`8+KW*vwpXk|BYe>(&YBGcPZZSj`6!eNrty~*vDderT($>6_l|Tjq{=$hw-@egCKXbY4m6SP&GuQat#0W_?%dW-->}9sqb{*hgJ4pGDcF z4N_jA8e5m6MrE}4ZsVKJ3#HpB&rxb*V*->xc%?+%eX{fYS*;?xSHsFCv5}c357>6< z(v~HdA!(FtRUusEEz?VUjj&T-Hsab`(Ikg2%|92e_kM*hef0K%$2)|NZ))oSft3w! z3LR05Oc8n18CpUC?$MflFNb9+`EISooUsFf*lm06>{mp07!we4(-z}CP zrKqNM(QtatV_FiDQc8s{4E=$KbQ{G4`JHgu0jpt9~59G(-e= z46T#_P$)Tpt-YfAz4IxTTo&fmks`={1@eSlu|$vf ze?<;PDBe@U1@k}yx7fWx*NPC?UiPuBOej#jnQ=UJl@FN40)^Jssn8pasi3FX0c}3E zy(J?Xm|_tepw$wy@3nUpxVE~{{nD&s!2mP3V+(4#2QB@Qh6Z0iLp zHd^dsp+>&IJ9hST_=nU>cGpo`xn(vN>UGi)l+6~D4C<%-FmvW_j?gUtw04t;HMrv5l!oTPIcNBmpOela7|aU2-?_4 zbS;B;Y`m>;&9J=vd2q1ZwXJPe1+wntA9FR5;Gh){Fk}w{)%IPtG28XEdmVmh8V6=q zIXE~JJxR>bVrIqWB=G$cohNniiYF@t@rnfX!T+4KY_y{dlGR(2e1r>Z8CL9}m;g)F z5?FnP@7Id$rrHguA`QD$PJ} z5=mKX8OmOB6Fb=b7WA`esPi8#4&+VHGa{@TOl1tr*F$a)9~jh>*4_HHE)x>iF^})P zYh@GpEhMON_%B=z%C4V|)xM4Q17WfI z5v+}fh)qJJ{5Qs}e3~D79h|*) zMk#;R$hKs64F9-QHX3aIdBFwMUY-S%Q-G7Vucsl-4`99569NxuM~3aI5D8?RN`K$J z^UP?cKEebRD;=vh8hTJW9D!i!Pk$1(qJEMWK zhR8F~PoBfl2r0WPCubX&q>DLHI;I~{Ito*V0X0)`*W$E%ivO206Ceym|D8Xz9yVnk zVI}ra=uWFCurc3ux4UBHy017|si2>_i6`;Kb9PjkFZVt3*~!jc;@2ly(vJ^z1mQxB z{R0jnP$*Nwh|I(&-V-gYgW(r6~1U2C`->4wnqUAGrIw$4^{AJ$`*uB)xAEM1$ksE2-Iuk3tjby*oq|$4cp-R zn3mX+DVdR!tgS0r*A$N+*dH_*@O1$EbCEU~iDzqj%iJMI=*q!fnRdhbp#Da%b1qOeD^Wg?hwo2YiMZH9+!aVw#6K%EW&qYN=+cT;l zsS&f1sQ>z*=>~#1Z@M{Q$JY4+$L0_rxYg{p6v`*;hq~tR5Z>{}?{=D-oUtM4C56%LesA+H}=jZ#a&BKhh&W+V{ zt0B^>G8*lr-caAtlYli@Ah+<1deZQdqxw?35mdz8ak}zf58zYZ(}u_`xKF>l{mj6v zi1(>i5;N@tvKZG}Z;+(_?KPn;K=?y>ohkK<){=r8+ z)q?((W_P+l%`0eVU_=e`=^zE9Y@r^M1ua*AvSCv>J)u!g044eCxo4gcrN+-uSOT9alTqex zrmSPVWLrEIc*|~r|B}LI8$OntFwhu0#z7GOqB0Uw3egr_{x5^Xm*SnA*hT=}G^tA* zV*4FAxdACdADf_V^})<${tmI=6S3a({n$?+Cg-pul z2g#9Jg=syCD33dAaTtqgtJoNQS2(k9-{t~AIhr8yiJQdt8nZ5f*Tyh&=bc-B?x>77 zijnSu)=ieVdF5hO%OP0i@0g3OdPLptQ`i1zwkbGn@`YA8saqz@7e9qKe04qhQD?;* z=9V%5G!^VvZj-pu{u&XehB^@@B0LaYJQN5UrJB@)w!Ec0q>cjB^V z_;v%q*?XO8pV_L8&Tn18#n$&R`j4N(tA%RT_d@2K;(-Vsa7(eL>&3`~H8hxys|ip5 zQy5hos{DomUAb0-ok+y%tuB6D=|7oY$_FSk!N$Q)N47CNy#@;?pjQ&IdH6Eb8{2+2 z8W;2J=;JR*%p*5xk25$)e(ZT1Ty%42*x)TM+Tpq@)*VgpvzL0I*Q6aJgAOncxu!DU zuhv@$(cP?1PRT+x8woS=cHMBL{LOt4*jkqpe~HkGZnq|Mj(DUk_ZTfJ{`y)*uWf;@ z%xPeQ>>5x#(0v0=!X<;EBpYzj4O@r!%d?m*Ncre?7CF5TLEYe{y&$acM30?3a-~Rza^k%wIN>W(&n~m@FK<9U-uHKo5lkQ zz!Uz(gFb?ClB+kF{5FvzPBy=LbhMkVzz`o!o1V5!+vV0$T$lLv66U<6C=QWk*+7-D z5B4dSEri%hqP-=;8lFDy{vvDwdU?X4&$U>;o2`?LAA}y=9}#OU9Zm3eX3?}?{IWH< zeMarT8yOknABJ~Y-zsx@#snn68>Q3~wu08}!s}FHH4vYI$#Rt6$IDZ(&5D~Oy8#y= z6YQVh6eG5z+qQkKe6;94N4AwQb$|kYX$k&Z5Z!p8@-tNfocf22_%_=Jz3k&V;3q#@ zgITf5icuyA0e_3h*PtSz7<3ie;8`pr6QAMk{2=j(U~^a}aZACEt4w}XVT~5ZvNRjS zG|XIN$Ie>=Y-nH77N<)gy*g>+gf4rK`YU%c<6iQ0*Q3Ik$K7qf4lr3*N7*!VDhYHK zb+rSL!66o+8Mcp&P440TL>CJ>Hofz_9xVGkw3*iJ_|{qnN7XLnr0tK!wGbsdOOb~9 z&#Mp1Sg3a)eLzVQ5?ojbQ?M5}5^k6f=6*mTQlQyTg(L$4XUWNzwvd-xU|Dy&OOzCv zX^2Z(%hanIkLd||J+m}PO!6=_?IgcQG1R#@ZFQ9D7_75ao$F3N;{E$6ZM_+97g;zI)*gaxi(qV3IK^Bs@5H#7p<3vI{jAn(`59D&F|F zV|+XhlqaccVd7)vKKx4d3>f`f+YTbd=3F!^dD2_U%HDo;vaF;Uyzr<*^SS_~yzwY8 zXya!u!8))J%hw?g5(c#gclCuucT8Z_#+5myZCA3PO$V?-()v19qy(4CW=Nffza;$B z`Sq?j)z2DYb&`d(7|yEX44NLnE>p0vZEQe3J^3;+@$uL3YAH%>6Fyt2pX^+4Xiuz`D8l1OUh&T@1Qq34P|n%*kgz$c&o`g*T1g zZJ7?se(T*f98-q2m9;E^`60NhU!O~|(peoCc}N~sJ+G8jVC3n%mkla`d9(z_?XOYR zT|#Pku#+L)k>m}t)^{6xA5MZ!hKpM-f=9xXOSA|&^S8h=oRBajY+60H>|s;PMrZ?W zpXhN3VPMUC`Zb{juylSy%J~QIO9#$tWOAh$tJpem6I2vUNkO8a3;a-NtfVq11HtyU zDexNiqr>klwTn?b4O37Mxm;pp=W;A?D2c4 zAKnA3oq))pVqTB6%P}?^vwsHr`ZOU@9&9|^mpv8G)%2C=p*v8A%5>F&*S(TGGCIkN zI8r6$>438Bng{svX<}H`+BeE@t~*&L5wgy%)i%>kNS6cIKL&&cw#q%~U6>ef2)ZJU zb)qRT#oTZ!pYa+jrPt#&n*nFP^@j2uBh@UZzxAo{_>(e~CeTmG(|KR@Dx8%lCg0%puH3{%pigNvX&E17K zq7TMk8A-UINqJ1$3K6Ku4&=-oSgovGMq!o-Vf`phBEzQnDXcjGH%Z=^5*Iz1>Oruh zPa*QB;%d0x?Hds?yuOaEZ##5bkNF(b&uuxDgQGQXkdW$L>=zYlXI(e5(aYO~^yBdz zTWIQzwr!cXd7@{b?7p_fhOSCggiWc+#Zi=vAIui8M5^3o%W#TaIOcpbDtMHJWOj+v zT|_w@+E9s$@iCv7q%K?*WEl7(qE=jG4C?Ejyc(PPUM%!eAxp?nH!m=UI*yj2@L$lZ zpX(1FcP(W55l9vqTj#g`%vsj;oNDWL`d*^+P2$-hGriBut$`QcUrpC7UF}{?6oeONwNhGtrl^s;mq@**>Snww{-)E>nzhxS1ULfwIGo9~*q&Mdb8+n(5-tz!ynA z3?{qjAMfEJ#d5Q=Yt?B?ev)`^u{l(ha>~8_m|6Sb-*^4*x2ri)G`WqbbbpYh)>cwSlx&pRLQ*SQ$a$&)H`X_y%LBRX4BQrwDj9$`olmwMe;mo~ld zKY#lFyhcThM`s2k>D`tpIJj$GZ8l|~i2bm9Ck|J9@t0HgV$?N{nq)j4_W%54G4J&$ zuxIjXp(p$!3zw%){I`tr@`I7*(xDM2<1clS3bRnAFaPi7MDNY};emp5)Je_-Gqx4S zx)#(jt?~*QVEp%3N3SxhKZH@z7|02vRQ{hoZs^Ucd&Oy~IzUraa6U()Tcy53HLy+> zMTn&o%RL`fdZ-}tHsA%3WL32U{$l+1j=q1Ij(pyMM(fTrM4WJ*L$P8ZZS8NMjU@LL zCj|m$qs8+1(vI&(=~M-5{NG<@F9~j7SC{;d9f;(wxQhk;VnJhRdXkmbok)noJDZEM zWnE6iX3h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + Kafkatorio + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/events-mod/src/main/resources/mod-data/thumbnail.png b/modules/events-mod/src/main/resources/mod-data/thumbnail.png index d44317855df14c54ce51f825241d5dd4a3c7df01..5f8550678e5c8567f868d1c9c4c718802512455d 100644 GIT binary patch literal 77215 zcmV)gK%~EkP)1^@s6x7I%U00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmYE+YT{E+YYWr9XB6000McNliru<^l{71_1&fUg-b;AOJ~3 zK~#9!?7eq*RMqyz|5-DW9(qSWDJm!`qS$*u1>5!7yI9d{!7DcGz4zWw5D}yZ(xrri zA|>>aMra{~l8`_kb!Pwm*zY7`?)6^3_xtP5%|H9e%sFTFIeYJSul25Xtz-OO`qyf) zZ_mk4`>Stz9pu|?kNP(80^eFO|NZ;#-+%x9Z~AlZ`nLKK-)?=_w=0}))6#r9yTZ4d z_Ugp&|J&|lyl;;0?%N*&zAf#e8+HF}|J(kz{r_rPF~GOeuJrAN<-QHv@c%IGbWjI| zpXS?|m(}s`e+TZr?SI?+FV?G2zUZHd>pva{$07-kRnmM;4IA+^B< zcWXdzdfQ9--6jpL7d`H3wWk6B0>tU-H}rX^!S#u`j$sT2JJC+$AfO{1qu00KAB@8J zYWx50S^l zdKEaA4gADUd=7*OQ|mvkJ7%)lnSb!R4yd8V)qh8v!=683!z5nTyV=tqqQgUjIE^FJJfhp+3)zIX*&!FffHFdcyfc3Zjc0X_f zH}JAwkoJWJVldd@cDTI_yv1AO0T*(i4byL4sNR1Ew4epofxToe*(*S2Ix|Vviw^v? zK#-t40d}sPOJm>`Zn2AitGSxL>$sP6-TTy!8-P}{vfIG!v-`LTxRz_l2j(%)`Ups_ z()mB>{Ok1pRRY!vz%H~4xfHmZ%k50y9M0h^pb?E|E?`@v^N-N^N2U0ZXPRuJ?tS2lvD1e1AEy^Soa+Tu(Af%U#D)))&FCF{`999n9E#d17jHDeg-$& z&88KQLk>OkoPP4xccXOvTz%dPSj}qpp#Uuv+z2;<(Lfei?gRBp=eZAb{s+Js*6=p) zIFGv@z|C|sY3czn%DnJ_pNH-dU^&Yf4!p!mya{f(TkfKE#oN06qaLUj3_QXkZa26L zm%%IQ|N8=_TYxsS!NAqJTK5-VHnX`5xQxpp>mWQNJf!*%sOeeL^T1b7RZ&$@c01Ij z)u!!90>0o2m;YxMcgj@XzOSBkd*8Q@2p?+x_McinvUnbt1PT>^Z^8;?5gLSYDyr}QL*0tXP z1~b^61bf+D<{Kb^1RJdH-vB~{Y_JCO4X}YW&<6XRfai3*Av*qLKQML|@EDKrkYAuS zNE1=^o;{)CZw30$hkJkrc))G~yT-2J0pAa<)$w=gcu{f>}>siqS_OHL=w3GIFS?WY~VPKqmw4y8NdZxKnI{PjX4eMP&<@Hdfun$ zzM__2vf9Jcc2wK>pI8R}8~Zv694pmsSGz+Cxl9Xb9;t#mZ6^a*#3Hr<>sUuR zkVz(6{O2xBJNZ&w?>Dtt7EV+u>GeS7R=d^A1=2}(qkxf&WTO8cZL@BS&ih>L&p;Jb z?n7{M-CQODZ}YbM9GJ#5UWfrezb;C)Wgf6@sW*>?C=hRJ`a7K)Cg>nO$uDCh48Ci zNH!mMlQ&rgmSGvTP{5;!YHNX>^t7eGLKfOQu(#|j+alnZBNuEva4{F#M!!SZ7O*Gm z3Cs7uV_WpQ*}#z;X`6r<%&=^*2{yrsz)rPOEnCMG$wJBo&gN`31HbW`Z30_ti)|0s z&33bus2^GCZ<&6tzyq4?16HttDzLS-*7kwDVQ*M5Sa0iXWq#t-d5A%v2~DijTR>I< zJkRr1>vwcBusycNs=(4ModU3T?OkgM_P9N6C1A(ev6c+h)w)`tuAd^{DboEVs_p14 zEK8InSEhEI+Df%ufD<^ux&XIv+wa=w=h5S0&x>AXOU&;$oVEUaKPXZ^57F_3U`N~0 zmI8LC-D$N2CS#`v;$!G+P%@|XuJG4 z**@SYp0Yha7rNL^omZxDE&=OneQi6~RGVtqz(zJ&EpQ+A*?!IItonHromV!&CfHUF zptb?%OJCdKH%#(1-?oB1X-|?5w$V1)R{xyYsCm9b8_*)KN9+;H(z;0V8@O%KJeub> zAj<~(#=fz+z_)zMuey&lns76~uC;3|2*K}y-zAKK)az2OYm*I4E^BgGk3MIAZv?_98sV!J>8RIXObfA@=V-^P90@>NI;rH0y%fWYU0&qKLD z9(g2#wY9buHJMichjEw<@ur>?f}L$=Ghdd=Hdzw$fI$qh#TtqQPQfC2U-*g19% zIl#%BY}@2g<Y@6)NdwC#7buovwuB`OtetJNF|kJVBgty)9h5%?`{vQF5yzE!yRk!`Oz>^T45Z|T@QgTyr+jRsx zU85%;kQxR-nFaj+Nc1uFus=X$aP1lt89*}xf`!Diq!UbCA;9>)R0 z8E(;qQthv6#R8gaSvXt4x>+~&0CSi_9*{&*-HOZ=hqDK`gF7rBPODfzyAG1?O1>+x z2s)1JII{gU&~|9sq3!!ZAv#O;Gbj%^TI%K-rkGF=gej zyYcSEyEeeqBeot<&=&R`yzk%xAz%`dNY;ec{aBO(>IyWcIRQ=JEe*)^lj_{+e<3OP zCl1=~1}+i$9rKo7-Sy;}xg7N?O1e&qQVas#UEsF4Z8Q~WyAYVgEL$zE$AC?2qSCuc zRB8d&f}LWg)VY8O0*-y)R=5?E2$;%%(TsLG{dMe1KaTA3TqJwy0o&!eTq3~7e9Ue? zPuLFZW;Z!tovc%IKDy1|HoA@Ww7AOcz?XcF7u-hRRbI85fLdzZVz9s4-|azgc`lEIo*Sjm0}bOmV7pZw5bauU zH@llT85qSVmT8=tfDN^wZjE1G!BZePCpo8eDg-(QItOoo1EB+l^Wpexw7_ARqz;)!Fi4B#5BVIJ5B z8(~v{4s@^;y4XUQqD#C*#9Xk>*4d&g|2&!GZ|Xs3f!%JmGhd%;=OIHDQYJ8zq2z*f zx9+x005(tkd07_0d|mHlSvc9Ua1O)(Q#|puU4W76Cxq2#$BPHP=4(Tq;_XP;LgCE?g%I!SU#|{ zKkUDF|HWnNp?q!m+R|*Od8Ou+s+S>H8Z3>Q4RN#LW+irpmRnkGX)+%U`RI_34vD~t zTTk42dTS_|Su%6i-H_iRzeV0OSXZ#FAm=g&PYh3t?9+4G1suaMboApw2Yntjxl4f7 zw5CK{)4%%LBKTU%+PcpUkNLiuYLRA)gR0PACYsMdA%=sG*W{o;P1LJP9eZEQEb8=#UW+ywz_VYO!ZE`st`0Pe0O;@gHKGIlkmI>7a9z?sNNtwdtbLN-Spr?bZnPVjEz9B?Ey!HpGd^R6 z2Mqh%KVU1=Ku-gn=4tx^>}h+NPOgULi<>WLUI@i^?!Kqs9oU??f=RbQ z_3|C(uj&t3`zjl`6mWfPL}0ykq}PD4jIA4tPIArm_zCTPgV5)p7voz)hn3CFIp|Di zb?m_@#~uR5esb)I$E}4U{&K|SM`yyCL2CxBYy#`YtRIt`3hpcSm5aJAn`0~mfQ$Z@ zQQD~u!re6*|K>5S)Bz5-8Q$fwuy*e0BArv^@)Y@~6rBYmVOd7eFnKZ9!FF(6I9%gu zb7X1cgUfW8)W!hQXhyTg10aRE&K|H!?2d9d?2zWMX9u$H-W{(k6 zzjlCo&%H;Ej^76CVi&n!y{uPVzjMJ&aZ||klmlxOrCY1$XfD`T8_ODSqueOg0e|Q3 z6aw4XPKF0kH%Bh}?clC;*SZw~w(I2)OaU8a!&nOL1NQ-`9%x*YYwZg*$OdsVxbNI| zEYR-+)$cZ7x7w|&kV|D!U>wTHA4 z$$a7Qe@ITZq$MXnYF=tyr;8vE3QH(N@HC~VP4&QIX<&ET-4+F=xw1skfe-k= z=7POwFIu_~U13z4;aPn$!N%D*o8*DV3S%s)!#UhGE1WwYY_JWsjS8bj$-FJVo!m*5 z$h<7?1KVl=SDrYW0`Hnxo*#HC0Q<_mvOED#bf+s2N0ROPXWPN@E#EeSeQY0FmG{N1 z6avQujtfkLGlrcp?9@A<@40=??Y|6ach_#)HxBYbX}!L91R8Bz`omLiLigiJ)_#8} zbiX$^YSrs-bY)yw*|~tD6+QpO;!Y-+reG)AY4#X&8siR>j)G%8+#mN#DYSoL-FvTG z2}S43ne;{x>>j>jc=q>j+>qmjoZ#Ss!!9_i?;>dQN~2d&UKI)4Lv0s5r)=q_vVmhc z_FuNqVB2Hl2rX%8*81bXZt)APuzj|SQU_J9>BsPe7u zH|he<1iQs<;d{BbX}W(gIsD?kw+!zR2J#_wck1r;=K#O*Yv8+ow<8_X$hXHX6wsU_ z@3zU*KXkeB%ZbSXmnMmyrL`Ap5P`~W3X$PXS1Qps|i_! z2SL+zJYTa4LVxEf*8$?s=6%-)LMs^H+JN23E_W%Uw&w8KU2w#`2~7%qh0t4pVs`?h zEDzmNy&Mi*82Dk;6i7ID-OexHfQ*|m1`NLyl6oce3KhUbTtxqUaL|hfz1XG~SdkT3 zsoKNzybl9gX)FI_8$B+1Ua=M1KDD`O_j^~uTF9d83JhTgJAtdX$~wzMFY*9um3qF? zC0UZ@MJ?FrcDhw-BP$16U<<4XSb-JTUd^Xc;C}A60tF+aOEOtFwjJ!R_E)O}8*QU) zmjI?1c%S#JSV5D#7>=q1Ev(dA{d9ow_N2Py1E+GT zZK#ia5h7#@z+SaiS>?%oTMHb`(Ja&TmWV7~A)v`uKY#X?z7+`AC;5$;&5HJ>sUH%8 z+FZ#$W_utf9XN@T>I{LOz>cwFSmwD+OV{&@0?Z`IRnj1MUhus58c14|w5r44e;X^m zSW)(OqX2a2A0FF-9y|caCCMeNx@ZSzQs03(;F-;ATj9f|e6JfACk697ue_|g;V7A$ zrk!)99#A^iRd!XK>y)9LBpn#XI9mhup1o(wweu?)Vk<>Lr-9{Jp3MR4XZ`91B17TW zr6QTrwbSeXJJZgz3{8L?a>25E^umh3HrNKs(tU5&b+Th7)}b6~dm#0~)C-d`;Nqf- zi!Od0l5&!A;va*wacSee+X-8b-+KIt>wsL=GZEZIYZ`w!95}u9g+M%{_6gnWT0)Z_ z<5#&yAoIP(ziU13*PL>6fd z*emvmwFDbuV=PaW31H<`ZgF0pV+nG_OS~}Db}ML6BFieQ-_O@LRrvX2m0%y)M-~sZ z!*)=t`MObp&#?4TQGhE_|M!WD*$$RvS>`;qXa%zLqEXO7S@79j4`xMvev##=f#~(f zs^2K>FguJj0?gIG_k7O+0Yr?YZ^zs5wp7Pu08j9QZ4)q0RS;vD`ngT6>d(MY92E_o z*tcLO+sT%#`8->K(~oNhy7faqvD+Ll4m z`$_LNJ;RgI!4Ll(5S?|tIG|p~|Is1AdxQ5jdJjUCp~}QVVx;;lX=&eTAm<1vC2hA? zbpz>OGi(ME1VqDPEQ{XsW-{1Jn`z&O{M{NOl|PE3Y@sCOnLesuFUPn-DWot_6LO_o z!3{D&qfwVk?J%z^+`rX7X!0~+GGj>2Te!ux0*~@2dE#)QE?0Et+v)*_8kzhC@$bgJ z8(IT>H}>6lK>&iggS%ZX$T&OW?C%eT$}W{%_Rjj9@WD|F`!9FLC+0!Q;Lul*Zy_`~ z(1y+sxW|3~u#fE%zJsdQs)mPw&>}mWuOYAiUs>QYd%^*YhJ@Ny0p*iwx&frNiubzc z6Wknt;8}5JyArUaOtn{`G*I<<(rrK@XEPEa{UiNr(jl`~X0I`oaLn1qoPGH)I63d+ zyweL{&R^#IW#-*b+`qVgSz3e1QPbf6Sh6`9u3y9=qU_}A7?)-q^9U=t(@o^=P9Mb~ zH70ByBuKU2C=i87Q;l1^!rJlRwz{npO7WZGEi6jCOTb=5mrClRfOf8(%U=CoDdFRO zaUXkuPxyoaMb*mcxiK4H1ELCHdlB41w~(!#%OqD((5(`b=K543w(34}!9C<2Vq;8L zK1`Uc-nAlE{U`u8#0?==!ohq+Q5S=~X0N%W;C^+#+Kr+Z7K#&_>n%dsdh*-N0e79d z&TjAqfSV)B?JBVOHlMcO9&wMj=~_p9#bpKjx^;QrE_4@KU#~O5d7ySPrGGjX+(qsp z%zF}U5(Hep#oYo4XC<7~s?1YwMStvy&6Nez?GLdkppT!9c(@rrL7|1|o2zb)Iqnd$#!Sv~7~kVu^q!8qVM3kF!mh2w7m+mTeoQH_C?7 zMw~X{)RQ4~SL&{m5G+VukUXkXz_asrVd@|W(E1&_t11l+-II9Xu2+HGjG!}w*SMho zwXaA10uVaNegbIoOUelVsTagO2#_)(ZaY9~ZQMlwNi#z80GbsgJOmJ)6S*HCTAP?N!@JZ7Z;yw$nmjl~!pv(gC#;=df3nL&QfP&HT8V z0LgaC;*nm=Dt)xaQo-)ByKJ8pNU67YEFxELuTRmiU2;|SYF_S^WmY0Cac>OAGn1K? zrRYyoz!|k5NGK*&k^@FRJy5eA)#|Z=O!t?&!POsztlGbK#3>*QIcp} zN?c0voq7PT3wUNXuz0=}@Jwp}Jm1H-T7TnjOb7eKKCy3fz29Plf_gwU-p1QpJwSbL zlNDv!0JhYY+7z(%*4{Sg{KayG^5t7El|nRIz_dcH)k0Y=Yh+5!75TR@#-(aRBirIh zKo*Jg+^i^Gu3WXv&}~z1 zmcVv^&^>-RB&-f@1!#14+*JU{*ZcFUch#-}hz|ztCJjz|r17Hs)8Xi!LKDiy0Etvb z$y4wPNXy>o=@&eneewEeB1MFNo*EaYK(F&wQcV0JUyLEh?+Rb2pvA>WHw%S(P zMuqP;isOt5_VVQtEtZmfk)pGk1gPotKw|x^zb%kLdy8Dgh4mJtwYT;*59}BF#byGp z@QTgTb6p?+m<;y0eQryoYnvn>PgB2V$wi%{^|4&zH(t+SIN00vw$1f9Xf{1&-8Z5U zGr^|WG@B!j<2wj-2z5xx_rS!AKNKqNisonkV~WMW9L#eN%njxy+%Mo6E#Q$#$nF>L z{2<`@w1LHwR*$T8NE;wvGo{0r?FEN6ONgH#lY6Qj&~)G(-m!HGAC442tkQ9FfSb6< zeif&)K)!X9M4P4iSgW04smRJT;+Aq_IE%};%+kGn#ELu#SjS~Ved#O+CIyp%O`+GC zUTcmofuhRoX}O<5MaON=FYO13Ii!RS2iL@nbqk>FZT553i*UxnjlapyfzXq7a_tBR z_*e)jx5e!Th&wdUA0U(yNCOBR6Zi!nbb25QAareDJV5B-z&L==O=@optkLn)0D>if z=>Va@fvo^d3KCWTB>xt7rSg83xVxaw6^*8Dz7o1m4i%N(59}clo7G=+U)6nO+ad4G zytfzr42Lv5q-oa_X#7Cq2U0^|RaRwP8?;^27R$0(>s=tr1Ew?G4pQ4TCTjH{4_c1j z!L5aY1ADa)BN`uM@l*l_agYVT&a$(t2JBgT*7k`6ZVXmvh3xi1KP#5LtVWz+aZL2B zB`vKI>~Hor+X|LxnO3ZnhN76LXaWglTBzm~`*Qjrk`WPg9!O@CFvo z3?XY&7c?sdd51BK@4OzzqFLz*qw{V31GE7)fHgYrIUP4wKKgtmnNHV$YA50sr8aDk zYc)-|N=srS_U&kAkNV_5%a@KR-%IqPJ2i`eLpa1XN|Blmhi4t0)%8wDcF8W~3@E*4 z$%PZ2gmWKE{cBDtRP2h}8N3w&Z3920426Wx?B1$pA?`1BShyI1yR9cc!i&M90fN)) zB!J+=z+nJ^_bm}1kir50>tW**vG@YOdU|=F8>w9KgFICjnc#~|M0UB|0Fg|W3=qD+ zl>#ITV7ekd&j3_k7J15Tfj*m3vNjKaJ&%{I>(Uxh_Xo~(%^SvBih8-A1``PmAN(ECK7rdXC7YximIt{%?{XGfzU!O<-Tx7yJfpx|_~s z1y6p{{YG_e-IesZ2;8&oS-af}W;sTHF<+@kJ$(v?n+)8}?KV()rC-EV&GIQ1c83Q@ zH`;SdcC~bH5%uG6>E6+Mw;+A=RgYEPjh_w;$%xmCkDJ*B{e_-*WkQZ!v* z%OVNaW((ln5CATesrj@=auzDQIvKj|>AL5zPOzhQ(cTSBpyLSRfZ(&%2_PKjeDRL= z-Ms*jS)P0j{Tdhz5SbRa8^CSyayhq)(*S~<>{Nij***u~j`F}$J2P-AK-@1p4-oF^ z5&){4>tA~S&i**{)tqOcX1BXG@EN#U+%xVxu-SGekHL!RTNY=&2M5)3ef+Epi2pJE z$M__u-dw%8rfY-AvpI%z&LmTr@7rk;lO-Q5yHQ3NWpY(pXyIpzqf-)RoglJ0CPk!{ zT7t@Hs`lIqdx134*yHsr>=Q{H*8D2=DGC$|K#IU+xhzV2@+rGjC&$#U4PNF^2bfvl za$F9Dz_UE-a-|=7Mu3s)0m)uhO2kTV@4NTySskAzq2N6pnB8w)fNA$BTYZi!w?T?- zWq8t=^%5%1@s^oe>IIN?y;3+j`SKks^*}_bo_h!7$Su)xN)ix_5)fSjc7a_$SI+^u zX|m+{Nto#x08zBeOhC%&VPGHHhjtUVzOF9;1syhnondFVDG;a*REIA87XkS{1fUn} zg}^i|?4Pud=W6E|-+<$pE8v+PWAVthth0EAGu)!U^Gl4S)P^>UigEFdvZLxqz6l~9 zr_~Fhthe=!)iKbFX3UgtKF=#TEnUEuE)#UAcjfp^*~m*g@YIDF7b)95U&5@}%2v-- zE?XWndZ5t*shgqM`OVI6c^6dn*jl)B0VK5!uBmw+YPv?cTRbEc1aER?&)3#Yx|Te z>=_4Jp4$KQ5$8jAl3Un#JR~KB){zL2V^nSCexFhrEcNBff~~9vK=3xUV8_{&Oog~pY_4kzjlSA-+=BI9nH+8c9q#RLZ@X6F^l}@t zHEMgPYCsq1a(1fS2DZsI*HuP6>C04g@rY8DQY|=U}fH7 zxBYUBN~PDTQ1o-ZqN@9JopQ~O{SuDmihHcmdHG(KRHxsGa#y+D#kZ{zM&^1UtZkOX z9m53?B4l~W$=WE_K2Hlgr=CnEnPkfc`_jI&-@I#NIhwaC>r;%ZzxB73-lDQ!WYI_K zLM>Jj?Fg_mOS24-!cmTOqJk@F;-*Hcy2Eev^WP4)!)>UdcvBR7iE>dRJrFSl_?*w{ z^nbzu-jhM{zH~$?&}^Sc&T{I%cftNS2%V_`=&POKISKz>j3E^VFrd!j`6h(W(!b0(ga+tom44s_M38G z7D%A>nxDWd(ZIe@ALXDGtyl(~U1xW2bEuhFGqYkaY|q&_BoG1EKiJ zLST-a zf-!@(UvS6*D0?+h92W-|apr)&w4ezj6fxqkrf|u+)~&an3Mby!>d>X5p!$*Uqv4hi z2zmx9c!RI<<1VpUfIxr>fcQQEFOUD!wF3yO;9!8@&$gAGKzB0P4^5wSkMDR3N&=;y zZm)(`gIW!0dk<{Az z0+;U6De+tq#hRA^C0Rzp^p&!pc1sXjrf~NGSpvIM6`@?YUbV`aFY^6zS<)rFCYL5( zsSDXkso1V8@GMzKn`BXCsqmPRH_4J~m8ER;boFBgxKG?CZ1Sl-ZmCb*u)ldKz)kaE zbbAEc`R;t?D(gK<$=m7Pf^=!%Zg;oa?Ml%}RG2(Uwx18~a(6jSuIpq82`};WxabJ3 zzw7U2YaO1W@o?VKb5q4dMJ*!fw%iBc?sfNarl&&ed;w9G!uLOeJKP;^S7`j7Ymk!j zr|SU)yzr0DB#8PkCMwmN-aMyl^f!h4Gh@i%KWp(EX-7ttmrN9Le<$EsEP>eg7~r{? zn{BQSFOs1sM`ldU&v~3@v%%)tTuT@5#9BI?=ww^GV9OS&|M?=Nqk5lAxoQg~^i09GATGV++G;j2O0#vU4ivLTUn@q2*BdCHIke-BuJ zZME%CooIbRnK0(3U7?OIL0WkGfRi&Iu{`t>CqekT$dmfLEdYV-HWDB(+t(mSd?@rJ zKrtm5PLUO>SSFH?P;GOy#Z zGKImVQ?k9X#LFa@D^Pu$y)hQgP=?wTaegXsY86UB%2PFkt+L!U_$1Q0REmxD9H#ZP zzP3qnjio+H$4Xf`Sy~^zf!%NS+frZ^t89)o%-GC=*0g4!EV@i3HBX4q!8N0qO;L{6 z1Z4vP#qSwwSU!u*HXVfL0>+Yj{ohUwn;a5g@?Hz;#?_AJ^xAa3n|aopd}S1pp&sD#yLWTlRSa zi)Y?Hv3Pn~&!~yVWLZ4l3c1DJ^J|Q&^$-tPhN59VYXG83&Kw_IV48Ff>6)<8;n-MT zj=-{g7@wJnW~{6?VQE5>I#;m>>}UJg(v?j603>~o^g&87>}$8LU2zuy*(p%{n)MF8 z1L==cc4~DhMBb%QXd?t~vDE;@a9|qW0N6SHDeXV8c5t&As_d!a~Yw-xKqk*4uik@Z_~sC~A`<>L6;Ni5#{9Pug0M1weG=@zsg3+#1!-SR~;XDTeeK1KkWN~#qpN;glW`BDMn++}yuN0Q;B9qeu zymNHF8Cvie3cgHJ&?PpE{;s`ia}|c4q3G2&>d#C?b!Q7Wzm2KDm`bXBuL`Aq6A*o( z{{0AclAUB9D{A&(jAtWH$3C`??NiSUM@z@rr!rW+)j0p{KLH?s>+5quXhIWv9QcZ_ z>?;9J)N&au9nX87{54gCaJIWu!)f<|4j`QCRYLlbtHuW-nsdSBk%=x($}A>sIh;}ff( zYGBpC@`3;Os1iTn-0%!YzBBY>_;W}&Df9+_P4&6tmPrp^-O+9Y2={U80OEQE&H>nx zSN`!KuS5AT7Y?llyT~rGYE8r_knR%jR!g9_ADF-dt5%pd9*DQ4f%_rns=b$WIsoxk z1k(U&hI&iOc5t)!jLTG8=|q6!q|iwKjn9q00ifWX@P#Q)LpaWE3=EG6&-bnBTXqb% ziEg560rAE0#qkGAP?y`FjZ@H~yMRJ2RP2tsZ8>1S*>AQ~7R}_C9I!az7%!pX2G6yc_e^Fkuf=A z(P*_i8$yKmLF?o*84h2{Gl~M-DE0rm{}6!eHg)_ZU%tT7RM<%sUwPVB6tr(eqRnlf z<9SaVeqTG{n3x-m1)hc$&o`P_Gh&e4F#Ayte2xZSns(H0Vo2v8L00NP{s8vAy>H9) z`4shQo^%weL_TInUs4#OA3B3GY`#ZuWn5kXY;IUgSHB6ku9=yVEb*qg_YZ-f@0QE z(ZzDx<(e#MpqsN44@+&qvS8cRLF0x)@?(J z=vNy*qR8Od}Fz&G{f187fsnuMS8mey$|fbC<5YTpC_!pk|HJO0V0RAp7cN^mc^mt30a<9tycCHh^fLSc5e05w<- ztah9oXFHX=nGE)UePB+&x)rR{O09_$z&oT^HYK5!>b|3v%f5Ogww-7v+JP8XEZ1_a z7WkQ;txy)(o|v*3L4vkbisu|f?Y8-93gjqywxK=@PaE1;fx_c?0=#7^=%yfw6?#A* z!*evYRO7l-7HstStWaUSxt`mzOwH4u8(3H~6rCEXc^_ zedt3#F3Nr4P=;s+S?H0jt^(ngF?D<%;vq|yfG|pGeJ+HYsi;)CxTN7R$*Y4HWQ)AO zDQa>ORdD{~fyWjrTmG9EOQjv{EKT~4p$aEXib)=APkV+-kvm70*ec!QxEK<97{i#X z)Qn+z;4`Fih=;1Us<^5a5E>pD9*1($V*V;~BR5+=sC=L{Y|SAs(rO)${B+1up;!5W zmF`kE10ZgCU)M!43eCE4)yVsT>2~M!9q!jt^V|z?1&-^16iu_2HIG#fsIDaH zc9mewQ6aNUF_jKq6u(w8~Ww-0N9B|LO=UE|YK((0J;EUfg8{9It%%v-sa-|Ba z9TTH_E2We}!CmSubw5g8a=owYNyry!bH7PZ-Cw%6i06{rSa2KM2D=LX9yteWWvd&m z4eS{l5C=lSGQwt3FV4N?x}ZQzEwp?0oxMp6{I*F}Q&19!SR-A?gJ zZdQ09sCz;NLsL%`)Rox%Qx;GMI&g>(Gn&isfl8geq{2>mzmdHs9mLOGKU1fe{!nD_ zhdvA#twmcGP9N{Xm6jonXOvv2*R`V!1AgR3J`(WU*TCYL-2iwd$3)xCz#oC0m{4*gbj22kcExyNI;u9=B5o1O*LuG-bifbg{N zw8#%~J+d3L#cB^#)T(Wa>zHYo76IF5`vOVQ)3j8bpsm`-;#IDtTo!V)E>N||Q>S_~ zC9;_Jh(tEIcG-R&m`bhM?s|*Y&arc>0&J9xB3sd@Ex;vQVjE(TG80I!ZAz8MQNIgi zi7koAAxt2_7W?o$YehP5@Hu9Ti>W)*+j`psB}o?m7jcpOD%UGbK)yhnuE!aex$Q0?NV)Z&*tt+ErETT?ys|J>x(OT`}wJ}evU*C3{ z-NyI8UECG5cx9Zy9)JGkws6Xv z`17`34@pP4;kCy@>bTT#?Xuy(#Ro1vPy=qK+ev>t=R^OXjn>SL0%dZHT*%=#AOY%5 zh1ui9?d%aplLS^`C06P;BrCM>0z7EN*v1=$3Ih+G5XSrLiKQubZkE#^~#Zs*^-jJs; z4F6s`xnB0A-i|U{oY)B6*Vpx2j(ubw@gDvyFnSTA{j9oLZ%9%8gnsA!`ckidSnkI+ zL-b13xTHE{8WqMo7F`isk8Gci0`j1D;rmCki~1WAq1Sawa2Vc8*k1e^=(?F&?wA zs*tGnBJq`ecZvpLo-e9z&1AW)tS8OwTsxPw(7C*G`Jn-bEZuS2n$d7jVerIl<=~c3 zXt@yoWbg-eK;UiLMGe&6=z;)op+F07rPv?<8{tzY>=~Qr>-#vLOxoCj)$^d&2TdQ$ zyA3*Zh~F7M2I3k;CWH)99}4udq0s62gfA*u!Z}YhyL{XIaM88xe#qzoiN(RAOFKaA z#KOB98>5}+cvwh$onoMK%)y@0Ovgh(%zK-2utVf!C}Kz5`o zeh~z(Kd8rf5h#1K?9uXJP_nFK*`5o)YOKbJ)NW8)thSj*=ZKPr3&aKPmMcC$09E2s zAS~CHbui_I**dwPH;Plq)&`LYw##<0N*u=$?_$|pa3kGFx_Ln#*DE!lmlWCuX@Nw* z<-2_QR^jqhe%{c>bDK8DM;Ga;u>3f=x<`3e&3^L9p)^%=ZoI!g5~PC~<2gGLye^23 zR3i0DxukL4<+PuD!7&1=!cZ!`m)-zuUny(;5x>CgJ)MuDXQg0kYz=Rz+{mlI1~#zQ z&vyn3h#pp*q}^H<1rqYUEH39o2@Y3*eP*ArRf5f@rBr`d&#h4X-RMgrbE91A=LNU} zRURZ4s(M%TF1rmlhPv>+St3lODXw-q~@I1cH;XtRBlX`E0nr$UB zmwf}F(e_ki4OIMEYt|hCy=|QP0Bji{PJ_y4{fm^7OG7^Zgr5p{(zkVFCqS?&a2!D7 zQ1?DS?RDxE)l=!ch4Q ziZu`RidzXousT>BJP%rKXt|+z9<*rEqDk`=ka|Vx6^#Z!!pjLSC)PsT%D9zrsd8Zl zf!pnNM}|Yq(KSa`$3bObWnsl%VegfDuPi$sid>N^ngpd?OS|sP_fa~x0sk)d1>kOV zw^ATW;Ww|CcZ+2iT?g(%_o17lDAV&&bZ7XY^==xtpWV;)FmNSTx~~Ojx2qH@%Kd5^ zle<{uQ+n-1d(nLZ?iu%t4Zzn9uzs9Q5Rvv9^RM@D>An!3UFa7!T{Z9KfSc;3;{5mSYhT&W2KbV~bnpOs zK!m?Q+n`nWFcq0NBzP67C(|VLn(#>sS|#d`pu1bznEyO?3k_R|xun z6xC@Wz19n`(j>(CNP@hy7#Hpg&Zy&fM%Vkwbvb0Q7EfACibx!Bd?VnQ;U|F2tJg)) zfev+LLZ&M$`*jT92@v!8<@MWe5S)3hCuZSj zE(D0XJLumO|BLg%_;jCiT3h380f-#s-}oKb>zV^ZK6N_)YRkL@RPk$V3P7lJU^4+I z9u}@@(*rU;t~k7TEwow?%&z_d5}$E{D>_2ysL;usW`SqzxT$T8mC?& zb8{Qan?oD?KSRft#5n$Clwm5}nxL`}JH16kja;1y2#yPm3myku7k6EJ$feNc|6uJs zc1OFLZid>$wTm4ypm2QQ z_}zEF<@+z+e{vZ(E9!?=d&$04svUYFAgAbU>soSc7y z`zQBLd}yM5^-l(Qs3&E;&q7&bxL*)^x+$pob2+~6l-Lo>zw3pjkgNBl5H*rQ^rZxn zO{8JXkea1t=?9Ici-|%$Pn4;dHq$=6P+oU{w0vDmz!=$}yX)?Hj(E)m2zPa(tP}d( zAU}2)grz?bK+;uD3<)UdPNL+b7jL0^`amnwk-j*F7?S7FDOadmCZHnyoFW{Sa@ ztGWiJFhy+^uTHTXxIYQoE^gh1ak{7V+bNvWH(rPbXh1xFE<9VjreSf!sjmdue{9z9 z{DFIlAx15ge}5TNpbAt=q1~PB?rd`sB05HN4EqQUDx^C~*I|=fKs~J&!W*`PuRZ@cY4524MM`h00|)c>t^~^6X<*lz?x}21aN*sZSRQ2ur{)CL$g=G`6*%6 zr(Q=!I_W$OiCq%A-1Ij1Zu8w1*%JC(tc*OWo15z`C8pZH$r3=MM6B$X-*O0{Tt;rtWO0 z7(Kx2b$-x4=omRZIzee_X=?sFsNPh)DPLb}0jf2YthhR^R4FROQ>oS0VrtzYW7>s6O3%M4G57WL z_4U0OdX4Hes@F6qJzsjhU?!XjJr%m@ZMlL!;q^hc;i8@n-CTaxUs(>x=lz=&-V1fw z70N{L|G~Zuz(3IT4S@ZCHB$n}-ZvU6S)`mU%IZS-?xyMj(a0>9W)Lm5?8tAG~2NxGG!~HT&iD|Kc6^rMmam`@ryn!OKq0g3v%;hkGaxLk@uR z2ECfQq4IX;F8?gpaja@}i?eXKr#sKS3tUgCCAJjc7=a{tdu^zr0wPE1e^o7q#M(yB zM0^eIH7OsB+YGi_e18s^0SEmL`t2JHS7u+C?KmcG^ylOR?kgP0t62ZDY|Kc)LgP@1O@^)Wgion#cwonV61 zJcUE|0R4^rhCxPouY1ewF@~hq-Apc+_Ha6#r9h>C?x}m~*5-WI9nANldz+Sw?ofKD z^iW>46rj3mDM0D=^iU@>d8x@uZP%Dw6YEte2q#3Jvr9MJw_QCJ@KN*3%x zAGJfqiic$kx}U3y)Us7Jn*?#Jz8WFP$9$~zi(=Gc)mSPd+bJ2Ri)oK9r11PGg(q7I z&%r+-o|QE0IZ`Pqr9o%$r5P`({}`7ri)7mOlb1fI7rl5w#-~3)REww<5wAhprEQnq z@E<791$u7=6m>7^zH_V~H!m-Yx~TW*AuwWY&>g3LhKOChwn`uH*g8=Ho zTn_`-U$eyn_zk!60o11^#YmSJkwncd=e=TfHH&ofbvb}fgl!T)b-l9@*TdOw>awC% z!=^da%VTx`Z>xUl9j_xnqj5n{U{GLuJ|z8;^vjJ$;M}5fi_Wis!a0R=&MKMe^yI() zcn6Ys5Riw<@gN;fGGZNd`e%sh9M!qW5=gu+@xGQnz=fRR3y1#&=jNP$W9KfwAB&ZL zIC2#VtO*>}S&*{WcBHBYB#rfLedT!w|JMG}mGKbN%x68tz^Ag`HO{>IGT*wxSkUN@ z@AGtn`gh#-S&zb{$hvpKVj<^fU3&N&$U5!J350Nr4?q|*)JxE$b*;}j!gMLsysACPss{6|0?lRjtbbF(4)~!tIrEipiGy-%#-H$fF zQI2ZaiK7!u%!VE%B(gl8zQM$Y=osOuBtc&H0liso)?I=A^e4q!z;rU`LS3laLg|Fk z33-uFy}WvP{u9?yfHLeEp-yP>ZIf@?U1uy6>RBPRcFP#uvv=#fv|M{-Ji0{+%x)7l>z-TE!bucs}=f-WPa*Z%h=XS|$R(g)(J$1rm-V9EsZq zDSJ}(q^*Gbb@}Ud&w_IW=L+`zDhYrmAs|qH<-7@o3<#Qaq5v9|`|NgWut%wPSpuq^ zdK!PIoKqi1A_VQW&*c)>Ypru!1l?TL+paP0cIQ!dIKJSlboa&uzNc)9aDn>)eIr2S zN#{@MU2rUL`h{(R^;>Gbh_3?TWKE6a_ymp!91;5=B<@SxH*^y?iX27dyW#XJr(ena zLf*d!+tB}|_!LlpGT(OtLitU|=i_oEza)z1?GW-^$aldDA-!jM&-4gz>@B`{=ru^m zEjjaL3RKQ;FALZSnUkFH5elvxE_Pwe6YjCaBmjPP zI&W|h-1qCH`USABw04sKC0FV{jR=9lxk;O6d;~#}!SzjpU{~m_(4BLj`u*zntA7DK zQ_ti^b3Azp#vc&TXgyl@27cz}KOmwX^^dxb@s{cKQn>pFmo~;In00SsMbdGCL`H(1 zt!FaPV$9PY|FlGK}A9>4%~Mi9?uQh46;O00XH=lNO!s+M_;|2^E&!#u2J zOYFb_NVqxS=GX<0G&yN=o#e8+bT771Sj4h`I;V z2mF&#aBb7g)dZ+or@szA1t(K$UygVQLT|Cw)DH%mQ|)!%2JT<xE3fmKK z-TLd+U;iXjMO1|6Jp*a;FIIih6q>y6JIpZ=s#ZD2sd?aI*>)%wludVb4O)mK2ZGI3|V879o%*2TI9K(#aC5w%>nv$j_!RRDUF-eHvLCWOKjqE`acwsqwJ zRE@2l2@rJ3=Q;p=2V(*1YF(c(6Uv{ck5wb#;<)<4@G$swo4Yv42ihHMmo%vx)J>|J zL?!Ib-JQFqok1k-HK1S9uQALB40Z3Tt(iWpPcvQ+Pam;Tw2}8ZQ3_ZuDPW!xy@S#3 z=m9cD9|c_DitZ%HCmr-yJy!RUDOY!STz}Bd>SuM5iScMaLj6H+(wpdRypTH1$OLqp zv}Apa{ztcwLfBpQvZWY#jgB@KX5ASaOC3w|zJlsr)xGjATx$WED+p-5kj(dpq(1wq zS&os6ROjUc-ow>x7`^DFeifv2S~#6z5fpk_t{q<9vH$|q5s6+sC~oJ|Ua=jsn5DMJ zO62|WItRqFc0l$QEtP_`URt+MPs99aJ`bsKX{xR?Hrd7~xyL-v*wh;EH z{ekkkz)DhuoCQaZ`WAj~!}d>W@{&J?ieETxxBb`9IE@S17uw$}xfx>n+w;zhhu|qb zXLW1PBlTc>;L6E*E3gDM_pblE^;;1ApJt=_eg~n0LkA~LgW{KqUp}7=MG-|2=Xx45 zv4?MEA{${$*>qjLKdNZgdTDd9T^9vXa;y#fMu<`#YO3}nRmeV_F; zIN#EzDF(l2+c6G;PoTA#`=CDAeU7uBEA_u|LdcE2y8wKAtSA7hR^=F*fC-yWeT;}i ztuhL51HXE8yY|o#OW`1kMkfA3Yn|PijADf*VdvJ~jE&{gAsPcS-(p^4fRFqQYTj zjNX8V2Fui}pCFVTGBxWfNMtDJ$$Bz)!FV_I82P;0NrAe-jL~%q z;oc_7u%L@f!_ti&Jn9Prs)}8!L@Ykph$~ z1?cRx7NEV*WJQw|?GBr?e(P;n4|33pY(BvWbyB8Bo_K<6G0_!BBB6(b-X<{_*|J-H zpO<;(|3zkYm;Q$t`$o~-c>0)AMgQ-#ly4R%cb3u zo@$dMD*l<{*(QkRD=9q71W9=i&kAz|QJ+cS+3ID&O(20M&FiWS#)Zr$;NQZ(h5s-} z{UY^?)Sn@Ad+7F18#p$VWan)Fbzkw~U#COU+v@GVPll7P*4*0YHMls-`ZoBcKMD5! z%a5%+r`>Cy`xg5%XYL1|3%1!ThO;4hL(8wBbV&GZU7Zkid*k`(h2Wg$oTs0Lg24rY z3qFN1dzrmrp?to*h3oQcyYMjqZVVI-$p62*k!q@`G2B1{0;-p>YzYKC74%eq15)>< z?oDd}1!D@vuR8@nbIZs7o(Y|N0tVz9fq)xrxq1Kuf9BIzZvtC8Yb=0so!g`bT(K1c z_dUZVLWSy*I zWJ=cAv~0Q)=oY$#zFzcP-GDO6bTiOBbPpW|ju#v+WBvpZSRl!MznEaG2I1xs$r)NDg37m{$;BoY8=r*OTVijC`vHPt zf?|TBq58(^@g;kpd|vrGMZ=(IOwsTycNq^8H~;SiNCl}N+bC%KP~#6eR6(Q8AsypN zAh0~(VB`p>udT0jb%9HdTzcd}G+Y>VVc4a5&`b4FU1P4S%3~S~mERs6N2@;}pZ^U3 zsXzTbE(q#(NXksgY%vDxHoL9*AmmNRoA5(-;4Aj<2DDpiUsUovq=fm8IkOu=PWrr~ zCxUCPyA?pd0DCI{pGeyf09#w5Ft>fL`U6-~RTY5M*vQ{>N4Y)^rUd}y^4CpQtpRkP zo)2KPQRM*caGe6+Ua0E;T&)bJ<~p4mmnX9@iQ4E&3MSPf`H7%Iz7TU(he; z)<$7%H1eRkf__E6qI;QyO8F!WX}wS{)Gb98;2G1WivTkf99530+&U>hU9Y78b+C5` zZwZmFMZVT)=n>d(|Zeio)#2y&k$pZ_<@8x>fKaSqkj`!M8dK!ZQ4d0Ro2D zjc4vfH4VTPWW05@k(Qaw4AwsY=$$6L#(u=|1@P%_6^mwOfFPiQ0L~b9e}KA$?u7u> zERoB-W1ipL-@O9BIa_}Q;Ce@Y2vGZls{?@Z0e2KY$;tY=LSBa-iptxz@B!Ue^-y14 z6*wj>OIkMQID{647AAfH+tzGbvpq#}haQ#_x3>hnwK2mU-A{%bqowtV6`fBHnU;BU zKD|J{tKZc(7?-`~p>lRfT!BYf(bq%*`m7dQ6nt zE=a3%znnn(z53}_c!f+!|ChBRJz7r%vwnGrLid`&W- zM|SYHelBv6{h)2yrdz@}|8xH5n?udgnx!?KXx;DS?{rB_M7?oQgSe@EL4~SNa>XPX zCkJerc!17a!~0Pvn#+GzK=`@vb79-TmF>!|s)LFN6%$U+Hd9OQhc!Q88(8xjM2z;` zTipfRziP|a$87%quqK%u8n(q|MrnJ|GGY41_3Hq(aAUr;EwN6hC6H54zOK_GI2BRR zH+mmb;9k>c9R$u&UCLWR`gg&vUVIf=c5n39z8Ao?Sf6m+0Zz0r^L}Lw1hCC>zXqUR zHO!U|)-ZtjneOKS8lUl9R<;5XZ?~6KM?(&-)`5t5I|R zzX+K=*$9(qDd%lVOxXT-8Wv6deFQYqJ~KQ8B1c7zY9B8MV7BSy)pnUCd0M4>*)DKa z1d3+`fn-VR=2>yPS>h8;i%_vxT=ZvzYdL7fi0qcUA%X5{pCF||(e>=}3c7lWx703^ zaHu@73Hya)J|p{zc5-z;StOC_7hpTv)o%I11$n6zqNrZ$wJk%V)vr=`77F6|MG(&x zFJYsn@T^cP)OIOkOXdB)Dfu>QOpC|ILcYH*|GpYRJ_z|B_zp<-OZRKF7>+oOIQ~7z z6j1ktzkz^Wvb_}422y6G%)IR;$b2R9m7Ez+v%6+@&1a^dsYzlD7-wF;VItH={(g^+ zWSIPpklzxYfk*Kg@HdOl77->MgM_ye-i{v#x|{BHxgO3cN@<3AJP?$ zcCBj?mIf*wfA$DBG8tILQr-r=gY&vOv^wJZtfLc*Y0`Yb_5|?xM!j7;7Tl3$2B-%c z&dBL!5R)@f-v&?@?+OBND)$6{{D-SsHF+6!53gPo^(NFms%mU+LVXmA)j(+f%nkpU zIs*!`3bW6J!0D$>Kb7kTx{Yq5dl{jo_OvR)K|iUV)LlhznBb*|UZfZ4-lp}Try!9w zq8myy7ubgB)kxz7)2%?K=oC7Oa=N+vdxE)L#~bCf?rtm=x)?XeF5Z&;l5{80l4J|X)~6_z04-3x|~}p1TCOf3p1lnLlwr{r*&-JO#N@%%{zashR2E zcfa5L{$1fp$(51|ZM_PQ=P8@$7xeQGwbFOCqZ;%F`gQ>OG4&dNHQdbPtR|+>wK^O5 zt82RvZu;M67CC-5vnX?r1CA}PThllN)P2P00YEs4MaHepe$XH4f9Xx22J(cO1Se|h zJ_{QTE0&$Tx91X=m=w2j#TBS2bA~$`gYAs?h45XwaMo@UoNm6#hfk4jQTla zI;D%@a#VkF!qZg}N7qYB_5@}PPHV|*?__j2s*6D~Y>^zJ1ml&|)69j9bQwCNnBj|R zBk2zvg@T9{;pE+-%S)8+Emb(vG(kd%(z+*^Izf!Qjwc7m6KJ>OS`pAs5IG@oLWl7Z zRz1fguBlUAoX;_isdKWhFi#LpfyqbVlpu~B(kdO0?F|K@5I!%0#R7wrI3bv+N=BL9t6VTJG`Ujylp&9XI=v*eTPs z?`4{oB_6Wfaw2(zi_4|(G5sjsBp1V{HB-S?kOMt?&oBk0g{l&=rucvie!FIuR!S(_q-0zcwHeJ2<{BkYb7*MY6KD$tKXzwuv)1PbR#(Oc7%OKOYqqks#Au+t{->(xVuWmnCv+`t8$5{@EMkc0>Mv^2UP3Z5VD`?&CgANY9_;^*j&o03uja zGrY#~cW{R~W(tpIg)AqH5|sWXj9Wb}$RKUF<>!k2(@FI_sNmg40@%$`^$FrF2V?jKJB;d+Zcs>(^wi%O+`>iO; zzm05I_~cj2g1J>R zEQaG%UR9eV*z6~{T~n3Mn`5A~_E`T=Z=C~h^Z5VrKKoRBya zxSiYeZDI}a2>n0%aYD$VKlFFCfb(`1yZ{=1_Na68tO3#=BO`Va#^ShVF ztPg$2l)~f5e16t^p{fYfi|R#WUlJ#UG~X@AX0cpB4oT~>Nh~Fsr00EIp6@7TFWOPz zcos|HStN*Oiy)r$Qg}T3mG%nq_)*6HADhBTdvJf^{zSJCZ_vBffPh@M(4bfA)$|f; z%3L#ERr%)crbIs96B39uSRQvyE*#Y&;4GGDh^GaUy<82-XfY$wnZ&nYr&eX9%CqQ+*}l`;j$BCJ^KLk1_}4L)BL-8 zpOMkIC+c{Bh*`e(I6nvVYE>t883d+0u@^rJ2ljwWQ?D}@7`@aKA~gxKRRg2j(hDH8 zkG-PY4Xz*bUgm)B%eHd>?&Ug0_`%KqdK=9E>ZZ9L1aPJ}j{#H-a|bng6)yhZniP5z z&Lr2{10Ms|wniEL{h|44y;_F}1<^}#euf%_y`C)FD7qLfhmLYSco0T!V*z5l(dFpL zV#ZD~LlhDP;iL=VA8w}CG!rBgC;2{iNvoG6ok+Tz4=JWaSLtTRL!4ZIV$JzRtT|5f zPzfGO2R%ZMAjN#nq#5Bd5$62%M7mykAem=wKi=#2c*f%}Q>=z@yQh^Z#Y9wQODi+M z^wz4-oQNu43R|w+|CGGJEc1boWg;ud6XD_Gf}rwcoL*pJ1dwe7oRSYP+n8ECf;aV; zF~zBKn7vM?Z_!)yvtlvv zkhFe(qX3=Ygx(15Aa{^E9AXE>4vLG0nie%Js_%e`$rY0;Z-a^z6)P%(z}?2(#(mLT zSsR|eR8ELK#v@0i=)Q^t8F~;<$)A4z`6pebAltw_)IC%`3$A=uzB>u(FWF~>&IQ*l zJ(};pHbkx0JHYj_-p6dPbytgc5nSpZh)?Z2?nhgA|C+ZqVUKjj9 zUKKcRcALxQJG2MTktSA8Uovt4`kAup+t;KO*jiZcs%fzDO-DjPBdB_ak8JG$8!l=g z_GaJQkg4GGcmC{LCqoC>gGZ&|VAL2GR@S#D1kj>y+MkM3hQo(AtDk{N|l?nF=PtaoN2D` z>XZrNRt{;ca>XN-FPk$jdvQdA7(~8=T6@-_oRlkejx0jU^}7FU+@{W(1E@g>onxkH zYOTrfX;|QQ4j9EKRcO|kH0%Z2XS_D*q#4(%-Esn+miK>9HhUg1WIDUKx>Kzhk4fay|@sJ0= zf13Zaxc4DoL%@cnuYiAwM^@y6<6XzQrN^Kyye_@G2{ug603!bfGTO8M$thRNHV_vY7aDgTl-^YOp98tjhMFEfO@~G!ZKo=8!6)5H za&3S{ZS5iTuYl#^aUO-x@qS+e_~cnl0qkw9Z2)#3Yc+r?(EV?KpuRq@1MEn-xNG>! zuy$*CtHi-T05)FsGIPGG-_^GRkMlUU$oRUCStzMfVMzBzZ%w1E8w5{%wHDUaqj9$KcxqWfd*2fOuzyS{E zrqX(aNDG)G-nC$G)H&)-KM9o=D=+2*U26dvVG7Uh+kmuP(22ktoIpO`x6B8QD0Qu3I2y{>)l_0&p6fG9Sp8#n5roJs89`U=2)(pqVR zg2n^pYNNjd@b|Mlp>Bn}4_tn1$YZefa9RJPN5L6Moz=o?`ZZV2)sw+Cg5j<=V93&t zr*iLyZnrhb+mr>hzq#5tdx7OP)(-c}x*ovU%smjm=`wkcHKEQ$0PcbG2gsaV^f@cA=p4)ovou}Z^eV6WYBtZ6o>;t(6MR$`bh$UV0Iw`{Kq>3ji zL%df_M90%ztQX0`&7=t@lq_6N6DbHSOiQmrfqe3HoZOx&x}Ffp4@v{N&_yT9_nr>= zEB%#jZm0(x;gL*$eoMclqh;JKD>}8G&It%2V?|J)$1@ z!)oAP`Bj|))lGF%wO;u@r#Pjqm|jp_5+ULxQ28of?uga!b#;A?!*(Rpt207q)y7(mOQV*Hij|ktZ9`R$mwk0Ms6fqHbSoTiVqpYAa!1{ zstdegIa<+*EHS@s7q|ThK}_2qBse5Ecp@ZBPne#lz_!n}&piT)XBN*qyckLjmz4bW z9R%j+Gj$Hg=;ixrc_&D){LWmu9>N?x*H@K;wVsc73;2iXjvLg6;>a4%pt9b zhQ4@1G}zbL*M=_!#~H_&lEur4=AmE7YDE?3$>x_wQ0)lEe zTSMH@z^%DsAmo_u{G#4a{iZX4)1V53v0H7_YR;v49)Rmk_nQFDSUnA(G_H0gfRDC4 ztSne{zat`TJzN~E^ZdLlCcf|cz8_um6~Uq>4=4uo9r})j1jKYfd?`jTts9&4 z30g`4Og5GZ?Qb|q-Ben>NFl3R$hf_+kj$xOh@w;F^+G{!)Eh|_D@h}8)H~|4_euc@ zyw(ErEJTfr8hJwtGj6wJahW-eRf9z=|zgZiiM-P3{9(>R!3ieW*;^CDE0*?yQl1)yb3t` z(AkH!4gvcPXMR}-bjtRdP;xsYjtZE2{s-`ju+4Wj19geJ0MssF+Rm6o#5EgTs{!os z>K1_di|#!D>J_uEQV%xfNZOkuWBV-YJF&AI1MnFotCpWOvP135ivaFsdKiu1O5?f* zgLlH=8Px-0HbAbgyH9W>1eXNg+j^W_E&3W6!ujTs*{fp;`!@&s{@Q;A_ z;_D%?)_?Q)gTP@kdI)H2&jPSNYE1{Q&Z)Zq?6Im3fLdUtV=kLs0H8*jm<`()BOtUb zG0JM!JMQTKuF?9mT-DzdZ`n8i-AhjdaE&mD)y~)TPXMmI9IF$eba-_w8ZY{Nym9}zuGk|3L8 zqafF*2Jw(8x|$G({_XOPluTT zbo%{kEkHRC^vgnKG5$VBA{GRYNWa#jR)=Y&&oc)h=y zxQQJmzo?-F%$H!YJh{Jw;j4T>V%Y|Xk!gBrD+%KJ#rKQNhp3HF8>8NUvl(YI_S_Cv zKE5*T&~iu}Zhc?=3f#~+_~tW{A!xa6U;PhYJ*O7n2A#m?0QH01ri{AGRs`!NWxP*) z?7hS{cQ=5VZ#JAVK-4#R^4)!H^vC*oFoj2shsGOICA z<(^-+7Xlyli39Ne+ExHyOR+it*uGXRWO`NsU{x7H!0IOq&`~qfQ;(W8nR>Q$^>=L)H++UZ1K^(E-U(29i@Oa#-8R<*0NW}PxLbN}{UG%dl+1Mog&%^= zBdgCf?+EU1Ez55*wDxQ5H~BTV@bHC)ujE6{%AA#Xt=daZ$$6^|D&`q)fZci}e4Z=zTnTq06F2$(7dYiWGvg zB9JPTWI|8tRbzsj$O844dh8Fa;rD#6PJtSu#;8Isq_mE8>MW?CYN#htmXk&gqOt_} zcsQ;cK|V#s?5BJnAvqyAUPI)9$ORD{Apd0k$<3Xh;;FKQr*=cHuKt@YHi6`jz{>Og z0NV-GjAOv>W{g}{=L!L^MXF~2{KL#jWHsHyrK!`56C1~H0Nx-SK;5sp$Tt?*VD|IeV}V8y|T;}G&d$OEA-gL+H7Rs9Z>ZY$mP>pf5x zTo+tWBNvM9T>Fm;9|E99neTuLPeY4(zY*u|1-~$xlgnV+V|@(Z|AOr{0PA@b4q$6% zm_PNS3HY@}83e=$WrU3F%(gO}Bb0g@vp3DXo`+0Sg&qgsKBvNI6pelcf>Sk`drhQ9T&j7bYBCAu*<#yiHJ{_g);fbt-^HoCUsi=rf+C&IcCAd4(jA{LD^m_1<*v%W`V3MpJA zE*+1@#L zAXG1?UQjRv$`_R{+S%6xk=3r`|M@3q3?a@|F!+bS?=yEnqZ@pt)b|133)Uxm4zB+C zV*sVN6(C@ePip{MGov3;EBFdPMXCEGpzNVPXqd#NqipJT` z*B8#zo~bQ*5A?nIULA$mWa=@Qrhp!-2kSI*q10jWUehFathu2G8aSa~DHPFCDAJ`> z^93EC0~$D=Fk@0BUE((yNufwK0cEDybn*o3I`pb zBS;aBC=_(Q&etu#(bUm2`#z|=Pq-zx-+C=}+!Pxj!H;Hqolrg+#)$TdN{czE^ zW*c1Ar$jfDZsGy(m{^<3*u7SSPKi=bddL*43TR4GPD(CKy%9KaO7t5gB8WUG-kwT9 zGTDZs;5rdFPWCD&;~B5=40)$KVeDD*{!RkxS?|#=QDl_Ow1lwfVben|n!*$N4=7ZH zYR56C2rFBWxfF&T39Kr52AXI4zj~z~Sb-*nt!9VoCjkGswxOE!t|2ZB2P#1-4_Nb%(MY$nMRT_W}&|3lYBJ+5CNyPxD z8HPmFJIs||Y1@MU_O;d^fU0}y-v_Yuwq617`@!~*`v`Pf+Ngi-5pcIE>#FJ@XNKe9 z%@trzwkJ0Zgxcw~)3b_=)q?*Y3J+!E@jIk+v$C$lgT7unoWW4*=Xzgl1luEOnFg$% z)MgZv=hyuM4P0*oi`FdV3*ehXF)eQjZT}eV7Bgkiue2x_&bbQHtqP5%HegN+0 zOrf#XTX6u+1$6Z73dg5bKi;$wnojZA>-YkErcz!u90JGNPU_pCD5tKX=>@0@i{CqX z6>x9$)Veq*JX3h)T!DB1CyNeFEH^4$IF)d*He{FrgeO33fS9#ogrgK>Lu0u;Mf7cv z;z^7VE;e1#C4vpbp}UH1C=Roqtg$4PhKSB6R!q>LhI$}PtW#lfUPKC2;dvh(xDsUU zuRDmK(;rlG)tpH2Og@HL`1wB!O#k|)x2QnE2y4i7=^@jjPV$DN(5NBOI(cFQJmgy+ zQ6zf=Y(qpq*h@^1p0M-&VoB&>l&EqFqHYoWPESEpw|JQ%$1#p^@;V-&(^yehck_B) zji$HUe~8xmDl_z#45{&o>_%{SumlLRN5AaP~OR4(*Vp8Z}m8Xl@rpyyv*S6;xlh0JD9;lih|ZNUM!G5EEW@KS}D&z zSPGugYpfnhs5)n+R9q6XT**}vrD~;G;gAFVv>=~+F?~wGQlq6M+XXF-v^bKm4s@|D zt_g>;H=n(E+aYMBY!}Ktg{08HH;bo%bxz$%4b&DI#1k;W-WtH}XRQaYj8zt^r`eXJ zZdNM*ESK^Dux`T#K#doq(%75;Do+s65h>H3%EIIJ(l&c`Y#lQ#laAmbfZk~ei+1WJ z;SCA^03ZNKL_t*V0rY8O6;Mym$XwaYPI@)gScTpFB#<-7yuW}WHU~iU`_3#uOs4?+ zuCvW|KLx#(1r?sjfEB^zUnh-+x?1(2?Z*JQKt{j+L*e<1&upV0cxv#}F8?%Zfl@L+ zS?Xry!O_`eD}0s!-`0MzDH~e!^BaHuR;Vv^$E%f4w6T7A^S9x^GG|=)A_z{dYT_CM zX`6g^R9t~(i+!4xTM%4kyQgd?SU0IRopZp~*A~TQP>-3`S3hi$6a6;YI@1%5+A8KY zUkArd)cJ%SgR)E9<1-of95Zy$9|qRnIaXA2F9ef8MneT{As(t!1MwOvXsn3`pq;c(86Fv^ za4~{J{(zVUF{lA4c_Kq^lnUC#OOYEx41LXhF|PBve`h)~R7h`6#qMLqjB2bD9?$cS z7KAtYYQ@LGqB8{D5p+kuPG~Zz$)v~&aMpI#_UkSP*ynn<5@;VE^g_XCuq{@NaX@{h zdkKKw0^8#N_9&y6wdxEavJ|EOU1zp6*t!{Uf;C!lWoD{S0PAUG2e2)&62Tz<)+FTzU>j(K09e;c zVT?DFzIED&4y<59=*lQKW^Mq zfUUc&dt@YpEe~5hA{YFo`b|xq2Bn)yHnH_fY+a^Ll=S`b2jo@lf}P`+mkly{}$r?T4&;>PLoVK-nj}H(8R+#sy3vgk`693LdfvYD z^@L?N6vFOO*~L1b#z}$dV_f_Vg1SCN5XlsXYZ})y_9#^Ks_J!dF_a!D4LMZ|o&P`T z-aEdkD(mC^?sH3eLJ}Z^8hR0_3Wy4*pkS|KVMNr?8G9K!wsGt{qJlVzy-QO;L@6Qx z=~6`?385t3_9vF@AG-z`%g%?_uNzVTKl(t>$lb_j;$;I0OD#r zsgW4a<9S1BgiZ$V`K?|6)-t0uvi6$6FP2{nyxuq<>jV`9@LXs@G3yHB80_9A$=VbN z4*&@7H;p(GZt~3lNVwJa5J3DYUvGf89B(#2a=>o^SQTm~Krj$F8z7Jv$pf&q8Isj= zg=z$_PBKWx>LU)wqqYNBF=jT1wN||gV2M04KGt^*K=7-G`JTtr7XUpTh<~zVETn(J zguq{aW$pB!hpLCz(%900cS6cDDbJia0U{SiE{>lBl|3taR)ru~6RZg(Leqez0gbOg z)eluaRF8wW#`wSV-VZfPQg66?JycBam-Lzpgh~H}&`+a*0raFlM0U}j+Ca&Y(ElVq z57lo4Hz^-97DaC6X=uDQ{0{Fy<2m6%H3@3ZvU60~F^<}w{yYFF=_%>Q?}YA)x-Ysc z3%qN*Ytmao&dQvXdqzXeNi`?cUVv%T7Y(5oJURsDvmG7$ZvSajx~8M3Nc}3}J{mwV5hW{Z)U4iM_USuFZVDhupm=$8?GS zj=rwGP*Lh-5Q7{)&`-G8OzB=B=iy{Otv?cixj#5ikjqF+=e-rv(HtN z)tA1`=ex=dxYs~N{Nh0qe;rgm~$|LRiz=z%)A0g|BqxO2Y@g5LdpS62sfJ1 z&W$=C>Hb>jC)6ZGm4))4yBMLCIumDRy??lWxIY4|u4;8vdMz9{<-jT5)hXJgYjlrt-m?e6iF957GLyB5)MhxJDWP6OmXu2x= z8i4Q5R)2t`WPg#-tC(5ux`aCc0#`=Nc_4@$zKZe=@csE#vd#W;ykSf#jm?op2VVf-Tg=V|ZpP5Frp8HMK&HJ_$ z0*D;a+W@=|S}SxR3|<&J_2`MP?8~P4?LPu_E@>!GFRPamvmrh$KJDZ#;0yUeZQDY_ zqYaNXUI4+IU`}wVWPN1(ka}3E@HGVY1@{F*I@5l_DFNsK8MkNL-sUL?j|`8jp8z#wHDx)c!O3O*@2e+(Z?wwNgTcPX%wG4l zw;lqpo;C;x!1@?9Jb@pRWHLGe?bv*bAeTClhA#q^h zz|_8wR*+V3`sK#)G`c#Bf@>oWHB5t5-tfB_Pk`rb z`$7K@2v&JsO1=cF#ffjE-wf>+w|S%ORET>n?&S1=rmKN>6x2Rd`&9LCD7(Jw`rHp8 zP!K2xj5GG2ZxcamPuZZ`8AZN61$2y#p_OEpI*6kP$$IW0R6~-i*JKxm5*-FGp7FHB zG$0F!tRzDsiQcBDRd+XnUBmJLU840L!mVZ)1+&vSHzXu?KNmNYMjB}nc__@Bu|A+W zsZOf3)S87&)>&nUefDnF9|2~Z(@C5}Dv(XKQ>-kZr4cy%4hN*7q1SVg7LPiPI+t#z z7rh+FwcnNAwy+!z*i(?l9x317=Ynz`JkBWJU9KBAma*8<2PN8;A}Cq8{jLYqi(cv! zQ@ausB2p_HRC}Wzijvpl%Y&|LuIARu^>S7~>T9X5rF{f7SJhl~xD1G~Yr>~P$Eui} zWp{w`tA7CmABq$LBvkn(iRkfC0BfYA&0jTFV?Anstkr0;QA+SyQ&RXPfP}An4+D7r zr4|8{^le<6`3RjLh; z@C?sT4&l=9E8+GK7!(-P)D@~SsxnHSgIZs$uf8AHqwG=PGE>69{g{rO&$zgfF^tit zivzL**<@m-pfm{r=^*Lp9-uqx&WNCou!KO}T@gccy$@udN)-px&De_`E7V7AGv})M zseX7(2?T90<9ynPebu%=FkK{a37ev82jTQGcCNY@2c(O|A-Ve&1qteI;tvvBjwg!r zgcAnfU<-%%yAjaUu25?*gGmtfJl+L0qajeV7%_*6QwezKtrTHecIHcnI{@^B{Ad-xn)3sH>RAVMLrS;&`7=209~n6xZi9plzWc(1 zpk`FC13=vK-nT@67XVP%I>!`u8pW`B!vxkU)i|J-Q$33S>Msm^3E;ocD1tlu==-4R zudt=2p}g=Q*dN-#U>aCISU*_LfbFw=k$MrBK5yD$@FZ|Ick6$Op^P!vPIZdmE?6xB zxI0bNHSK}V`P}JG(+BLE?VEK^Xc*lvy0H&5SPfP~e^c6^7h)QAoo8C>swt+(m|386 zb*_CI*fZ^!ks_H&@jYfTXojgCr?<>P?=Fh&2_^*6LrmWux(l*VvW_!NDTNbqg`}jR zpE#g2K^_qau`bS5#*j>1h)FD78`$xd|zu5%8@1xud^Vk==(AxD;z~) zNS6Xj9Ov;a1SI4-Ll}bJoUa<+-1fskR1!(3!D=u`pp$fx^Swnayvq3hOfP$XqgKPb zhPFT|jlci~I393FiyIZ~lQY1)Pu0l|k=Nq5XSlc<3yY)DL2-bjAA>^1MW2an?9qhq^QB#vWV>eYg6)Z@dQ7 zHN3=P2wiG_4&eXDlOzSR_X4Q5rN+oa%&2(zJ=3^Z>m-#35KNCe1dyctvjG|(j=Y=_ zfH~!5`$xVEfu4Nj%K&vZchg=LM593V!>%lb2amc!N=$0SF!H5VZjW?2tOk5|*aO=S zg}>>z6WSM6PCmOW40|W-_=P~+Fz*8Zp(`TO0K9{&WdQmXHBICIxd5t`VnMgN0MuXf z9sqT`*?v?K7XYNz`$yI;08d(dQT;%Obcr0UO$X0Co_mts20PVGwOdII(tR>A`(n_i z>(kjM!nPeo>8|f^l?W_g0X+;Ut9pYzOP@t6;Vycc(iwdT=z)45Z3H=Wk`9z{!f9j} z1ZB?yJKN6Ioef8$(@fh6l_Cy34bv;TqY?D!0isWfGo=zvc2~)U7)2TxvJuuc_semR zQEz$^Zn0ta5qsz)4yf43NVFgvhsz9$eZ|S~q}0I?0QPj*jg3vRgj_?7%)vqaG%KnB zh!yH1Xg;UX#P0h3LYI{+dB0zTl%m9TB8ljAjWa?;4m+uU|B?fWj^}x;MXupEP#slA z4w)P1I3B-C@f0`<#UYB}Vo>F-kj|}V@VgvgCptNZEY?N#C6Y*$ z3z_-wG2A#FHKZ9yB#CekgbpQt$J$uPX=jusV)>YP3DQ{tVa1RkqqtZMNeU}-u$3W@GCk?NZbl4+Jkg*t= zzCcLa4&s1f#c+~EU)Ek6P?9)^G~p^TF|+Ag3({x>x}9!Enn5~xh>*2?Tp>J|RqQsAygCP2(3p0fcW zSLxlJ>tO98bt5_s1=aM5C@yQK>%ttDu^=)(YNg|xMJ&4?M)G_xGla!K;ez!ZPB zH;#yjre;lT;m;I9>yNCgz*AtivD?({kQ%@T4JpfAM%m6Sa-H`X168*h$Eu=jKK>-< zeWo~)lbp3>n&r21ZB)^nH(I^zQsS%8X5A=RSE`LT@;+jiqnp=<8m&eX>mr9GgmLsQ zrcTcMf3l>*$G9Ao`_-rUxu`zks5Lse{?r*iw+E-MQde<=Nv>>@+rE;U?}Kx-ZlrPg zv6bekuOKmtpF^DV7P=iv)|YDW_W{Q^ZX$_Dn*ZPaFa5XcQLW$n&Y_N(H+$Tcj-Z{S z*Z2V#VO}E)%h3Rf0l4QEni)K;XG)8lroOt2t`Wnx!QBJ*9YMX!xuKp13K$` zyAEPzt1Fv&0GXT%;4AZ($9s?5@IF#qeVZ{%^^BPR7-70@6E%fx+NLQfiKsp;_ujU)auacGE1wi+UX z%~+tOa}5GfQw>+5ZZX-aXpJ6c&^)950xpo&YbLbt;bV;Gv!Xh(uET{ z)lhLfC%V=}EU^x9h<+}{yx%dj%oYaT&Sf3L80I*h3IDb^|4h&JvkC%(cFoU(7VnP} zBT^sSSl1k%$!CnTmaIh_@7vFCHD93sY`)@j+-}376>o?#J zztk`Mz27g~&><}l+OOS!yREy`YhYh!Ul^Vbo}Jvr9iTQaQI7=@jk#O5n1)_XSlP>E z6mAK^;O1Q%Krb~DJ{e$^O+!w&P25$WMv(06aBYrxZT-|}dB82M-x;CYhUT^$ed+7$ z#Lr_KZj zZ??_dmoV7(qjeA0f__Rr6-gD6G)i&~19h4@&8a0C;!@7Lk*rt#KSi>Zr~SgRaLpxC ztyOEsAX>LT)GY@m4i{Zm%PlS87zWt5{>5KG5oQ4_Ayd1cXy(9wp9HD2k0qfPm@rPY0 z(qp}%D%xlU@NLtd2N_kQ<}k+I0Yv^^SP*Ug10n=GXHyv22%IPQ;a<#~*!7hD#^qWn zPQnt0+u>*T^Gdyf6qD^yqfMti4zzHD{O9xhue{p+AAOH2r2kbz{jJEs{qhO^NOkb- z|My<;fBd8WT?cf~MW+2?jJ zHAeUHlQuisb|-~z7SKHNGpcEEGJJ1|!IzqJJL}AGk{3cJxW5zr812z-!#|I z^Q7TfwoHC6H)m_#uKxnyPqo&%uOT=@pQF}+ny#jMlTGNQzZ1@76X;!fmy^{y@bhe` z^W4I&=T}ZS-~GaUaNRduuFIVyM)bAf7gl++?Mlo06FSDaDLdxVImSZ5*53gY$Eb|k zb&Peoo87<31y#%0Y;o?+f8JDg{SHU?--t|B{_*eg{^l<`#3AS3KeQmpaIy1EG&u{% z_dC%@vaNNA2ATZcqGW$LKB7pySYdS#W4Q(2nWy#YRCAql^jKEUQFu9-LJ&_3j z-dC+E0Q)H&hX(@h*>`#qK`pihBzDF0qd5tq82$m%MPaa9m%CJ9Gn<_dK3yDExn%p& zUF+!(hp56R@Y7r&+y*x2L*}?Ti>{!UL=|4Dx{l~To{Y{IcO!O5! zzn1goA}t*AvAjJG|6Bk3LFt`P->SYw0d&NO z3u00{w*fTeNA3VfxZC>*Z^FpfPj0nWes449G{b4r(Vm zojo?{SPx@#G)=A@JV=m2(ChVj@*w2_R@UV})|K(&)|P@!U>E~IKdqOW5K}PRIBk^A ze=+z$Uv8GOK0&bGIM&LuG^L2sOnP2-X9r!OWN>7q?;)`IdM{7>6trLa?e(UIF;jt) zI7vS%_rE8wpZz)uSjtk}+eHfRVi&!I1M1mK*6LMy6&--Y?|T z^{As{YHyc8+1O+^lg>I@XVV9`kP98m6Ah`VTKMn35Yf9aG6ee~a?ShFnEherJo z{>Zif>=*beK%b2%YE=dF{8R1YT`qvVvm%A*_qZ0?K@L(WKMRE1tPuxaCf8SnNr%>8 z`po3Wg3A|DbPwLQI41;`hy)jR1oBdFCHB%_` z@q#lanx^@BtkFY7?$EmdyrYbx4b<6BSkFM^GW}T0RS=u)S(97@k=#hGy~o^leWg5y zXg20zGlhXJ7zJ^()#x11ujp5FKgNMi@E zjAcF^k8;)l{Ru=5z||kWio@_-+~+19_C-iQ!jPwd)R{o1T1ptkO;V?k_5bxFY8o20(jLF~n;e#7XPB{B@ zID&4K^scG2oDlRmlN$jk<wH~1}oM3LN)}U*w9jR}EXPW21_;nCGHF#>E74QQ;L`!@04d%M^ zXy9@#*U>f-BQUK(`vPzCwv#36fEh>grg1dRbcptX7<$sIAZ|xHx`8Ltlj#`@-l5*1 z-YdbA>`7LKWgzARu-Dn^>=6)|6PXhp0Krp&rv$e`q)((zc!h*i?SNczo%LKPNJ4rl zJ0ar{&^z@`GB8tDDqMDxLykk!N0S;k#vb&yavgny>q(OkJc?v8#J>6f6PfsLRKkW9 z+0ZmW!r3jdi%~})=cShml8nf4qam8>dw+%i56E#_x7g^Dehw&DChzO_3!&rhc0f_& zGXU7iRtj1moI?4cWS7Hfq*1RkIuK$_<1p1I@5^`KTl2RsVTrTDxVavMa*)+Qj1=CM ztV*F2-zCaIX%dIFU3QvUU>)nCjw?DvLw{qAqYk^E^}{@@&xP8nYpDgG5JL8o&!N1^u2(1!rArJlI}_DN=b zmVS{30Bjirt)DOfv)(D47HiBl)HFY`55V`ibs~UnXC{&sJQ3WR@&tG{dPjF@1QxKs zQy`8c%7vT@`YZjFJ{6e6Bz=kO&=ZBMzFn%~2TSM_6$+kgCUMdkn95W-fl^8-1u;`% zrucV5{PXe8$9I63n__N?vB1i*vbfj`q|`S9Hu2#(!2hTv`d?tJRK?!5U|sIH!Q%nz z9+l!*0^zU2Uxy>mxTG|7F8A&>rpKE{vkP)MfZfSmKb^%7w)C zvCnZx`6jd`3)8vK#X0Hidb?haQFQllZMY#qPI4!TRI=pzEEmF8C{|-S6t-^uyxy+2 zvl*kHZ{>1GwbVutqh8|T8n>{;vF|M|d#s`6XXkrZA0~v6f7H0Ryl8Q)`}1S|paU`k zU4RcTH7~g>pjoBaA@l}U%oirClw>b=wl1Z9#VJ1lF*|xsU=e zz-mD@9#;ssj&-_J9<0|KS4DT8oEDr_RN`LhBKcBC!G^L)Ws}O!gI>dX4e!|+d`bS~ zl*4e~;y~Xv`HU%I2>@D_|_EnG&ObE6<5t@8WzQ)HObW!M{P)7+tqFSlZp#Q1=sm}o(=W#Qt5hGOG z!45qM)KlsyQX&5J_}AmlgM^fXl!WDA-C^Ak83cj3fw@O+hwAUDzbmpK*c5Ck=?~%Q z;pvsNkaZSMRUCru{bCMPF9My-Qr?04g0U=iSDOCLuOoNm)VdoDq&QIbm(%h z%fZfTAhavAE4&YmK6muFvUlLa0u1_lu}BA>{LrlR)Z>Y;nCjA zKWj*~jcpD&Rc|0Pd*p%|#Q`-+XjVvb?TiNxh2p@+ayDKuG?}zru z-k}gT+jC)fGuW3H1C1P&p(-h+<+!@jT(y0b0M!%CKBEShKrtfqF)<-;AAs<_$d>@Y zS0iTv#P|2D0La`BzkBDI(EecjO*;YY*QQze=Z5@NkD3AjtDkDeHi&kE(f61+Sb-Z% ztJbEoBVK^mGd(wp37td{Hi;lZb!qIz?-oB zgsKxtUx2EFs)S90z=8T|w{AJ4nHFk?7N${?|+N5;BBDkA^NkVfyEEY(XWo5<7~9oVyL@qFWgUprdxz z6?DGNryHhZsYcd!#5gb~3s~SH&G)j`aY*~bG4_xwV^s3E)m(>Ohv}nL7fMS?ONv`VW_f0L??x#7qIAlpCm}br;a~0k3Iir2W)|KCF*`kL z2|z<6G#4Q80iOb}#|W?;ZWuE)!rWuKu7$*4i+P`Sl2t2Cb{9bXjUm(E>_+twfM=Ha z9w4UD69!P1vp`a}O#p#@ktBfdT-yeSJgnyect5i40*E`#n*d;+EaQ3}(1QVNj}ao; zUCmEDMvn#1c{)pUPv*F_b~1o1IVR6>n5^E4$QsX+uw`^$VCoj2P}x5#D*l#l?Y$6K z8d$pJaR{#uuP@#WNm)r*BZ?q7DLE;*66#c)s(ZyuUJZ>hA&8y=326yw3136PWeJzX zoe2%kHcZVw7wX=tdwau1&=DO8jRIbi5^1;NalJe-`rODz(Dn|$U3)8#LtCx|HNzD3 zHY^GUtXNo)51>ptNz!Ce1{oQL&;jQp)`v@|(XKp{W0D7+O zxw`l3P;`FL`2{_ow6?UiY^w>8b+)kwXMR>s;Yi#ySYZr%xR$j}2$v|Nc6&@)n&RdV zPOsH#X^W|Pj~;i8aa3BG%>S%8d^zO~Ip4vxA+KYd!|8T1)Cuba!Q_hF^$}zhMPO@O z+|V|*X*n;g#6DXIz{qGJXHfrJA!2cJT261*+eO=J$m1MxD3%M0lEdGN=RM#;E&x9Y zX?VoNF@*`URc2W4aS5r)C}S;9L=nqef~Q<^Su5Wc6{xM19b|WlH0O39sh7CY{|z+g z<)Am|O^%>%o}AYzDE1b6k8A|{J^MXtF=TeiOdMGYo9lveTlIzNexWXLV?n1eAHcKH z8Vt~s5t#yD4>!e{dax;4wM$IH(MY2h_V>CYfc?H?lU~pUaU5nkK+I*HivVI)dCd5n z>rF*bQ+oIx09BU-mH<@81@8vX*GV<{VrvONY(MW}08gbEWEgqHsABBb%`}Y2P6O!e zDxCpf7sz>am7jg(=U$x%&~Rb+QviQg>k9xq!Hh26d9?n#jw_+zBQ?&u=U3K_2M?(b zIXQB2@kprtp!$Qa?uF3d(BXrZLCV0Cfyu8y!r_F&@tYudZSvaW7a;DExJ$ix5a?Ao zcV#E&PW}7yheFC5TGeN{G%7fJUI-1|E7)t_0iC8>r#DW3VcTP-Ra^=29XuVwuRz?% z-Y<9uVz2j}%S(_n%D32V3rQb%%Nj0%#4dCUuL92IuwM8xORwD* zFPB2uJ7w=~NrO&}or0Z`pyNp$PipTG!;f;FpNlMFuF2v>*PZ@GvV+-TM_)JFiQcF; zk}aWXR9LuCpp51%UBkrJoGZxdSAt=s9mvDLb7Z@Jo}od482sFxp)?qgOrwu zU952lDiwLbpa5wWQ^>B$f2q|D2BhO(B@xDvs>c77EUK@tFIKK~oEAxEfBi zK)FN0%_K-Vw8)UzI?t76jOtd_vtF%o{k@)gNP+`e>l!~w{ zinJ<4nVKt(sZv61c0jZJPn`&CQ`Px$}-w0?tFm(+N!?^ z)$}6<;Hpdm%vHY8RI6#GWYM$D+5wPow(J?#np!RWoG7s$z&OBh_D=x%WSNZmfLVU_ zA~PdhKc)>=^@Dl#`UG(}Uimr1gnIQ~g?<2t341aD?8i-&fAQIYajE@a``XYWDfIwq zQ)WbJAO z2WOE6k*DoN0E{>IK4yyNDL#ZqcY9b9@TX5xr~Om{r5^^*Nt*z>pKRKft|5PPcuw4t zK&=|D9s%`}KEZwqk~f#fFZ~{TYwf2hPJ)bZ`;X7q0`?^Pe*0oL9CJ9PsE3)YP7!bk zmpED9B+zs9T)G2ya;Kgr_o%m7x9-WPD3sHHteuO)Y@&%yBABddmJjG0okJ$3n756w z3%$xjAUXxOjLRHusi)X=dzbww6zML?BI-!$si&*RLlT;~CcRFtqcx^0L;GLR3I1jW z6m|kI98Z@gdW%XIxvM1j`jH@%k?x~V#8U+TCs2yVPG9sB;xv^z(yi%7E zGn;Hj&{)u{lhO0^JSsrls&3T>#iQ>PhgBsboacx>rcpSo1DN8%3SbU%2+4Kkh*CG- z=uW7BvfgFAkM@SN%(Tq(QP636r|DznLtai^ec343exUA$P9YfbVv^_38Q?o&_2F9x zo?{z*(7%j6$iLrXatGh(F9G;Mgpza2<5QwEwgwyhjp`&g@&l6wSASCHNvhR^V9|#j z9nIWJwu8x%Ht%m7oz5~(N&C#eT|LEM2K|9~yWP%2==S$I1;AEDu2=tPXeoeylV`0M zNmqc{uR<$gvtZ?04I|rM0NPfEoRQkQ{(y{MkWnBu5S#Ztgq{gKQ?eIgih1AL0Z!i$ zGjl@?B%SYlvgtMmOpSb^#zE5Ge4D~kpnt4y=l&)b@FBNaA3;JV-#PZZ5c!w=5`eu- zZvyb%YApardpPzC05t^D3wy4)|N77RZGe~uJ^SQ&RMQSJ`uKwtKs)^JRh$dG{}sqj z-vha?HGSRcedu{&%%rkM!M}i!we29LD)^@Zm%#yF$vCSMbU3}k-Di9cP4k=PH+%@? zbIRvb-qk{|*im#%Zrx3gAUlACER2Ry`V$ds_BOgW9oOub^me^nTJ#Qc1d$yD`A1tL zr@KO@Y_c8BCOW$LTXA^NS@Nxf!blTGlhl0P`bYgEHNc6SNV3>#2cb5KT-iRip6U-d zpxMj@;51Hil#M^SNG64%L@pqTG|F7*ZG}>+vfAa;pl{ zWcvv4IiKsj5^^1tg_|eG6%I&!D%?{o@F|}<n5LG~2@apSyZ+QdtO=x;JEL|tl@gTBVxCAD7=(8U6fXBj}N z#+n9a&J&C7f|CUSJ*>@RzuJ6G_cHsewk4aj+kBrr#~>g*-6T~b_u6LzG+Yv%3*cYw z`9>Dc0D$`M!e{sf!3wLkJ}VLI__()+o(@U(c<)Kx1$7B^3G2I?mY=3c>+gJtvfW;8 zFR$$fP4DQ{c0JVBhHvxS4E`!LL|p)h=Xx{rec-#+^Al-cU1he#+D$=a13akb1H@nM z?F(QXl~%dK)K&mBok^k=_Bxv>z$M%V5Yx^(!yr9VwFQ?cNMPH zYvd6Q*}X^Xv8$BAxUzV9r{1Zvf#D3-(N2uLU8OM!S@DkaSLUSwnLSsW4y!?+;ePSdMWPfvis_(NE9bFSc8nZBJOWYG9M_GT$xKRIdYY)d zX*RRj522z^QRsfi`%B(ma`U0jh(06wJ_8+VI@XMffwi*>uUlFR_Twy6=Rw~?31=J* zgLk!+!CcVS=|=%-R|hiy;_vmv19+Y^Y9uvMJr1D!f_M(7+W^#$@_0Loz;U$c)$H`~ z#o@1v0~#tgwYS+%^(4{ngbnwjbLIDmri8PpS0n`>Tw((Bn1?*$0PG^Z0H|9W{>C4G z6?1By?A8Wq<6`p%2OxP?(yT%Enj&6~1OKP~PuuQ->Km(XT=OD?9}YiUGDV(q!|(S; z`Z^V~5@CPO$h(>CAnhc7VtyTXFST;?kKj4mbo&XN8W{+XmK3`az}v%01h9^%H2~J} zY9oMkx~SQ5f*^fR?N=YIn`D};PT>#c7l?UK`-`W6B*Cu!aKD_EEMhX*3P;_ga@Qv6^ZQfc{i}N)@OZ)r~qw&LbD}3cZ3{(;HaL5>H$twNZ7Z z10f}H9(x4h=3!b_=3quPuQO75^&Hf{S^s83fk_JF=0T699!Grdm(^NTT=o29?w?* zcA1_CaHJ}*Fy$6l`B}q_9U38$8~?YV|Adq`lHM4spyrvHXX>Uy)260PO+iSWlsqYU zKcsI@-+tx_sOwVK<)`sbKcIfVmT_VTH~l^zgoXoGMi#|C4*llZFC<$KyCO2bsvPXu z`Z<8aBEOk!-_^9)@_cWCQ|oLM0kCRJ_Rt!|MN(^MvWE`|CE8a);d7<*xK$6<{w*xf#BR7a%>LvgyQ4J&no;r0sk3#wSa7~;0VE-%j{J8m$@=np@ z4O!6bzHaxO`7jjDESy=`+N`I><*v}{Fo)SGjz$oQ{+G#y>E42LdbvWcHF^!{rnb&$ z3ZDS_GyNGE;!x6E!o~T_*K>snYUR@Tta316b5ZOL2@Nw{4zHG4c1Uumx2rZUPv_}X zKp*-z$4!;<=w-MjuK(YV(BJW${tn0>Lw!Q?oGy3BRVO!~SV{*Dfx1WCqbnr6mnRUi z(KMt|vnA~)g9q7%=>dHN)AYJPJZPh&A@>_Zq7Syv@8k$l$!mdZ4hxr4GZL^uS@ zVwRH?$P>qy1A3~Ss$K;(QyD}g@7Mp(|KM9tAE*!XUZ}~c$*SE6x$|=8?Kv5GT-xK( zo{i9LK(})*$%35GhiaB~gpyCHTg83}BdX$`EG~qM)iJxOuLkd7YY&B>{$U(SNZA2^ zKzrkutW zkD2ZH7{Ff0XcPqg6CMG5(^BSmrruvyxJ0Q|8(ywOt ze@@FrUmdRYBsLv@b`QtKR=*3u5#cIsh4^}34**YJWvcP-QMUqEUzh>np0BKa0M=B~ z5G6cOo4$PA>@5Jk&Yo$K{o4*;KV+JsSO?79HgBqBN={bkAVA~-32nUpRhSv@lMAJBAs)A1*iK*!>a#U1k@r%z6w z+=qb#67*ou3-kiI12=J#gM2!Go~dV&iJ2XrB?dmjI4UiUNB4Bq%FSVpqgam4)!Q!) zWw%RL*F+P2fG_z{&uw-{I#1{6p2nd#4y?0KCT*pL?oe}R$O0BPB|=#)B({PT(c}JF zZ)jNx4T5FjoTf+Kr@T+4y$@~AZ+rgGCNpc=dIMCJ%2E-aD_vC{s9cq+0^%rgj7L_L zpw_GPN|e*83b=ziRKDpG6P+KXLcoi>s476+t?qV6&3(q>tD{CQq$FFVb{j;c4wX6AQC?Vg~Mu^Fe$@fQ~+l+2Ax~+iNiLn#?2jED~k({mfL*)e(H*CHU zdfjU+tSx}!Jn`d>TmY%dd^gk&2DLyphR%uRgUuLY&rTn+sdZuth!4ORuDJ)8Dy+DPz?^^K(m zRNYv0fr^pfU1q%l5L0C319<*v znQ0yun2^cS!#W?pzED&*Cz!&8xEH)%0)+0d+W~}@+I=&(gH^!9>UxM>=)I_6B!nI} z#loR)BI^LW#imzwXw?z5<}~{HC)3Vo&$lstqi9x~g~Y=b`ij zJtyX+=F4hZ*S2nGYiNJ4{lVdJu>R8Zm#&Wi`+NKQNKYC3*UcayJ;0>jbuZ9;bzgcL zB(Af}ebZU;{x&8Htusy5S@#9qL-)|_<@0@vKvB1nY*-)34tF-SVA^jSitZqetfMIo z);)~EJIX2Po}h2nx9eEUfWux+0t9`5zCc@s`p_MXBhsCu*?k;T6;u`ECqsQ%eOdk^ zzZU_`6C~2gq{)$Vyv~uT*$T-z70Mj2IYMStnR!YS%gE(IOdps+;cOZWXQOuu2U9GZ z!5#w<)f_=EyT#KMiYKoU4}YLJ8|IMUGnnC&isVYDI2-iy`gwMPnx>{XRpjgCM(2Zi zQN8F4Oxz3lN&TdH7}Oi;4R#BHI}G|-eXZUIDqCeE?L;^p0;dK}4eo=SM{^#{9Rite zX1>`j02!}mynfxD-OW(fHIS5w^&^P>`}TOfbTnN z5J0HXPEMZ;+51bgN9Mrhef6>JCPHa;Ls_GP2k>8k=@eZb! zb~PL=JzBc6Cv=+KY4(V5kalz0%_*Nl*}G-$R=f|~#%&C8DUd(VAJ7%Jp6m51&FOjl zvHn>1!i*8>-kfdHZ|S$#E~PA~F7o+RUZtBj9*Gci3a0x&w4FzmE1NZ&*^WNQ<4V)d zW_GlsM9(&Mta}4r^L3OHqL(zBOTrAN=;qQd{h<&nDj=FKF{J1e96e2;=xK^wdY&Lb zs(?i-auk@Q;<@*LUa41-Ct0WYQmhwMcou>>MV&&SurP{(+hBcu4d?MUrkW5-ulKs;Re|P?9yq@u}xT=~;qla1{;FmV#cbSM#GxVOVSA z2kL&&Z5%XJ)vS;mYc<&S+V|SSq3G?Rw~Kec(XmIzibJd_001BWNklXPd3Ag(E{DfW6J$FN=jYVpt>^xc%;1M6;my?qMw zc*37rn+w)CjN(2}0GL2$zpq)d0IY}AS^z7?$nUIvYQE8+n8sq zzSX5`UVw%`*i3}I)G}QG8r6CLtIE`}`z_BE01eARUjejR;u~J^8dx_q>}qo=*pt*G zYmpIR2K>-?R^wTfxsaBUmXdk}lua$0dQ?JFJyL{+rvgv#gcH(aiCwjqjW*i0H&Pr$4)<`9>S4k0q^jRLt3{pNhG=$szXahPTd3aUcFbRo5;rLDc%S4xB6SQV&|N4PV5OZtHt;NHkO@}reT3-&S-c;{^ z&d_FOo17u9K;YHD8#S@e)U|0##YM3DV+r259znX-PSe&zB#`BDOZ90p*_iS0@RPGA5-@u9DVQTd&M>cDg%{4 zZN}!PJ>qbpJKA8m-yu=HCW{0=?>ExPhd~8ZP}PIK-e2!O6Y65?Qp`Y9=$`4J#~s&`EA1!(0+$i_cWb^^*kO%{h2-i{o z>VP`H9z#B>eB;p69#DJK9<@(6m_nnIPz9hWRi!F1p_|Ib%y(J}YQNgA_5x|7sXS9l zriwuAQ~Ol0{C$&fR2vPlQaeEnQA5-^InQDv7f=O4lK3EFC)EZDvs3#om>U&@e zW7Jwui`8OQ7&1|PW4I@^(PRtMHkmgSMUG315>~AOHCatoqady@t}yOxNEwqdCgl!j zdu`im+nxveX6~CguRjDw21k~k@EeT%QZD6H=yF1r6RvIz4Z|CThbKez)at2KOQ7lN zrmq8=L5FpiyIs}hMmuC?e_tk9l@q1S!iku1OeY9(RG>~!C#YW;xvLNAgL<>*sY*?R z<#`FZ%;_?xOA;JeShW1JU2x{#y(_a{g81XT<07*__2(1yEySPUeMlEUj2=r&@$=vA2BfbB?&fYT z636o=K^9X$U!kwi;{@sVh0|Y3N-lZ;#@>}t`=y5ZPeZc+Jfn^5DD<&?96H{N z2~B6ZnXky^lyWoI6bS{YPQi-E5BX3|29@grT+39MYTg9%f%$;bimWc%-;)UDWAm{j zsG#Wt$j9&_g zQ~KcjZUd8Su{#CZR8d`51J_Gdr@=v61(2mW0ke$in<{`zkO^ien77T_vRQBFI{m!$ zHbpZ-E!iz!sGI;0BZdu-IzM%O$~MS6mU%2Q7Gg`pmWcgDuWQ&pC|>)lcHMcydBbdn zyFc9h;Z99RS)H;v^#hg2cLGK*!sG=ZUtz+82cQeOa1HxneUQesx+#tB2|P`8;q+9i*bQ3d zZl=%qAUG6vXISKG(E6bQO}GV~NFDn#!>Yy1WMdhQPsNt`E83p#$ktx_|BXz!TRp&e zQHI{R1I2EJEOWQPnTG!2H7A3wpJ#&Sbub6a0k(kqmirb@0@Ii#&+Bp21$kHAl}7s9 z1`tPS?F3kDg^4m&kxNxIsw=1E@A5$$(I(kMVW1uDD5m$P5Xk59xl95^GE&M1kMbQE*yl67P2s_niikkiXmHND}|Ke_(vR&s|?U~wg<>7GgB3hSJW6R zQ3v8BYMK0)HoM)>9<8Gms+rmP`?LD{GgzalE84QLQ7i2qw45O*oie%rEAqondc|DVOy(tSz%VvR~(Q4uN^yye^Yfm^MRu03;z5bzp-f*%Ikok+0-C(k;K10C_F+=DFPKXm?z6Q6OER;DQ zk21-81yY!mG9NORxy8&25b~0q~2L5kNKT|}X<308{l0eHt6YYlI zpj=RZs~M-rq_(93B+w()P*b21djA706%&+vE@iKS1guj#lRdkBI@7bLjQzSXm$B4` zo~ac`W{@G}H3KRUBv?!$i5<$#<`2>-osbjqF3^|09RIf@v}oBa&^7+E9>_^W27#*6 zQGGDKuwK5L1T)!8=2B1<=`DGS1VswU*>KcWsmx3;@0s`5qTTPx&2RzCXXZ0b29em$ z%kwM;Gt0~}Q#DYY*Bhk{Y!c8VY}cJ*hYcj=8I`{81I99z-z^C)n^YlMP08s8v~?p9 zOh404R_FsUPv?jg2J@5o$-H70s4P%!C`7Gfjiz#gZD5l*AkA$Txmj=4{|OQO#83D^ z9+StUhD~v(ik%etpz5Xm&QAy-_`u9J^Ude_pj8L?QofXuUg5uaeqy<0*I%M2A)p#K1ow3Up&Xml;I$sFq{tH ztKzl*@QhK{nQwFq&{u(GVbfpxCV$iGP#VBj-`&7$@UCzg(-qvY-rf;?K=w)=ceyQg zNKQ)~@T4BkP>^Tj8M#k4_C`U-=RJ9kIA8)30z)umm|aIw7Z}GlX%O`OC9;H)ShM|- z*?~#c$Qmhck#Vq&Nan~KiUW`ENS2jsQCoeZuqB=4)gW%_8~H}!l`}0D)UvgRMHE+L zefZySK(BgV&9fY0`^5ICIlxw-%$s0}nPTRMeK51QmdijCQRcYnY|bdhbJXtO=9qFf z$F0uBB-qGrE-UwNRzGLA3KF*kaY9GUQFBVGF9($qI&O1Yb5^Zcx2P^>qkYiLUge^+ zwZiPufVstbD;sSsF^7QGv^LwotTwC7F1-i1u;0m=kI!5m-|qs$T;I8DGQ zZh>+^^MGY6Gn+IJ1!jiL*3Vf7e8MN@7eySSAf$Up_t0rjxlH9UmHR_NT0+{QlaT&d z`e#>9{*3@MoZ-9;WuGnk?4WXRaqh*r*Ly?q_~h|7Cu&ML3g|;0+A2hE1g3#$V0vj$ zp_%TCmG2=PYyG(>5tzwtV*g9gVnz19o%7ClXBL$0QnpK3;L?ptH`X+Tl*E)Xr``sx zl7WEvn6uIhIuFe;_4GoB`6%@3TNfa_yXO&rkVK~-KuA^RR{(DV$CA)1tiUk*Deu!f z1#=V5zS!?QIC3_#MRXC6rLt58+OoC0rlfBVJ-iXR;XMM zH(VNAxX9x*!55nIlTw>u+re!IxA#+|dOyetSwRz^J?*7NkZ$Lw9F;mib*f7pMdD4h z_)-C+w3LIZ-LDscCVLmeNwn+7>K{SFWj?>X91h zhMG^2WDH0ZsUmTuxy&^m234=F zagCEUBFiZ-6U{_+D6;w0=C0-qn+k9?yJt(L$u!P@dDFZpM>In2RPN_D%L$oxgE*ma zGL9W!zA@j(UQLO1YlQwy1J49qID7O#+ombsW=;8OTYZEXt4?)?z*IF=Wre0>J7h=JzYl}|5C0$j`rzB)+mV?Y!bXIR z$bT17YNpgYB|xlokd#T3F`M9ed0+0_nUF7EXuDg0Z>MX8mV2E>0Pbg2dF4=99{{kr&eV+k%e{nJZ+^3|YZ7POl| zNE+zQ3HcIkzvXuH%z%nbBWA^1g!DTpRqno_HX4trea%i=<&p<=A=gtULzN%%qClD6?k27q&fU@{F#NCP7Fkpv3M>X97K51uep% zv?8Amf{@QbSx7w4kAAkBPLa}&@*_on?sTU(5JOC07{NbBKyeV;CALeAT3`m6fo7^j zHs+}A^v7*A${f>bRG{i~Mj_>TMK*yd)e%KDC-nD+fI<{9M}v^ladVtgmJ>3IG{Bs) zsfhVQckE+&fp%L`%xnVlka@^#4ywxar@z?+W}ca60{$yM0c9v-wu9Mk_Gc-hH)t7j ziK}A?e^avqt3tqri+cW6efAz6JWedBAwan_o3h zPu0Jht)KrbgocEMgiM91EvmMtS^|y_J3egDXOR9t`U6+@{*3_i2#>H3%6(AogTWKw z;?;{+uf{;q%%qvgkE^15q>_PkRRGvozrRCJssh<_t^zug+Cc~>Cpjsl)y#_b0HABO z2#__c0ZqYAK#?6qb`&lKq18jHrwW{lJQum7lOnI6ov~0sGc9c$bhsHEceDk#qookP zLu9^?u>fAL^DTgPo4tD8)y{YT|Fg0OAS}jH0^sf|nX?PegY^fl?yuVx_7zBtikS&% zd*!kd3Y?YxZayed*gHM70JN?c6LDf7#J!(;!j7jPZGgW5&x3QurdIA?J1@;w$9)*U z7cRpA(sTJQ0Ql#*O92u`r|r#u3x27U`evcdU>f4#hSiZdF4P@gcl@x@kT5P`+{q^( zv2J4Bvui+FOKYiQd$X*A5l~-A^zy)HMrV=4bu@rB(+#76BA6oDEM7+y(bW{GG_e~a zl|bSoPD*HxSxNo>dRhgG)1Jt3K}zb1Qjt1ZeN#t8DXGY(IPeF5WFe(EkQ!1$%3;0N z%R+M1NZ+)&%=s%c38wCo3%@L zv*kcIXvf!>cU9896r_W6V5KUXE7~2$JYvh_vP6Z5j(SWN)E1BrENLu1f>~%5GFNpo zUgeaYP(p`&m9 z4jH5T%>bPBW+{OCg+*NcA=V+>bId#qkUqe_0U)fH=a~x+K$q`|Jo*#R>SAVzu%eLm zx%+wC8{m1EIyWvr?x~?C&pikdZD+Eie&w6U^Wb^cX$jySwidSj2dqD$`=(fn-D=iH zDKpvsK7bi*()kn)_f4Ohrv{k(c!DQ_M(>W^UAhT)le|gc-@?^KR~ub@Ud{OX1CyCd z-|UT24$EQbVegj&Hii}|w7pNc&2KdD3{*ta#BxV8&}wTSm9CiZijVlSo0r&M+`tt^(sS;(hMwjK$9ng0d>b@X=3Qx;+; z#!jsMxScTSJguZ;fXg|i2B-px^harcghCS!5QO&lTwe#^ijdRkJ1f{~NS7 zO%18cat#FUgLja3karQpei-{(+0r(O|5Ht+eFj1*$N*0KfB)m+)c~0hH^cv zclY_@=|AQh1}oR6Bo}@I*hf**%nA@?6O>_e-i|E2Xo>7R_dMRtnWfTQsU#Utf_oMMK)zD zppZJMFDhdx6{(^Kr#?t|DNhCEe2VBsS{tOQRF#U#`IOTD7za{asuQO|)vEgar6Jjy z>^-#?QqHBEJ9Ye@1fUAu3VBLG?0vEKRZr3KunO4B31BKy&3WB%14`%9wuy}uw)e{D zSR8Z2lAdO-)#aE#Z`Tf>2~EsSFq_OK^LuuaC#5NEu7KHN_Lv=-(rpM@z}whn4r)rK zj(p~KO@)3@1frh4W{>4m%waH_&1SyQ6mnV6|IcQ&IjCi0EkBx-+I+fEIiR^ph6e)C z1`R|XX;tn+CEWv6!}o2K!F;MD_!p34L5>BHouJt3#a=Hu5Axj3b30!va4)zQGM3os z3RjoGnfYhtul9p)i*L)_d4D4SRiq*_b68z-}CQ4uU6B0$msv|6L1{}DBn**k!3}e6`2A@IZd;Z1%xk`ne2Jn1r z$^&?=nEC)tPm==RB-j>a^QCPZGHI$OdYlpJkgy9tYGaYjA{h)I&8(-lyVuI;{1e^t z0RAXB1dyKM-vf}k&sP~BbEaDkV8h_Mo#V&CrGs)kd}a0}2wxw*KHq+*^?9w&`|pAS zpB(t)_Zo0M@_gjwzBVI}7RnuV1L-WCX=wd*L<7IHvdBZ4s?A0dO?jGY;3%SGb3F}U zEj3eU0n%35N+s=1*YP~k4rI6tm-4n4V&|(UA{sB_rIhqHjaKjrlfKpASxHr?fLwt667l6^moa z32oK|y;He?M7txJ^Qvdrqvh{Ev^umEOk2}7P<1j1+7*8g%qTO8?Rszi^tJmK z;9ADDqq`bFow44CvgrM>o9r083ACf*l8XN(%Bi8)m^HcJ!q6>Bi$cyqKI-V$iY@~_mX_^7`s7D){f=OKsB(*^rNCWAra*f(Swi@rt z`%=MD6w*uYUjvZUvRcXjZD=F46{(cbDqA%xB$bBB%7qAAExOM05UHuW&)z-%>J*`XxxIt>8ZwY+{BOgU4|?A8mn&kCK) z_ezHE3Hts43@}@jGf^_xtkf2d4ccO{#eQC3iiY_`%jg?ae-sE%b2K2W1D3GFtkXa= zOaFg`BBD(yqw;>TJogw2@|5s)>8DETEN~t>igV8LD~}kr)E6tY?D&F^jPqf$Uo}7ju7`;-00T(U{~2)Wp`x4 zwZ_*PUtgD<0?VuNs+3cqU_jT?PkYCDg4CAUqQb<0!dUuhb+|P!g(+FTucj$idrL{s zR0Bdi6);xS&#R+>Byd0LXe&xtD;&-`j_P`RaVqF+9E6lUl~1Lx_L?bYD77pXB;~c5 z)&PtpVu#KMg=bA>ViTzN^+jd+EGJv;Y7g07*naRKeZ`j&jso08`48Vw-Xw z2Z7COHajhuX?CbE@q!gnnLSp}mz6?owcLw2V4Fs>kj*|NN4IK9_KOCtP0BG{vQUzx zV5*zyW^GUkHJQm~6PTCGO9YU~T16`RfsJf58^M$@Wmurd>su>eG@HOoFcY!@(HH*% z5&fv-^ZTkh`bw*2-$A~2^1YL{Jyg0{>1x&aaQo8jOXpiaLUcm(suK|TU`CDW8PIB2 z&XdQELdg40nv?}!J9*D^1%D5BB?aK_QX%FDZ2T>?W`SLhd!^IDe+wekJFBDy_;<)S zTEVT&{)?t5H0_mR`NiE3GMTcse+KVy(@Iu=H0OKL!B@)d%mG;cRqB%RE8tcgR)uec z0xuSLvHmECeJb{;stItp)8$T=zJYVK&egi`sJapu{{Mc?1~oCdxFmz|7?1f8Dx_3M ziT}fHAZf3`?cpa^&HoJ=>zrSKV&=^po8e{~-^iT5K-sl9 za$kxA&sa9fd*GjI&GkKnEduhEa+U!&$4o~6^O)kcAJw#frZpVSeA%^5h$G}_04bu| zP6Ut-Qp)*~Sqn}D=5h^ug=L0$9L!C;(hvBCp?m_zM@h2=IUy{hYL~&q;e7A&T`!D> zgJTblJ?!f9Hwxqxc}1F9L7{Ze0Nq(-FU_ssRpKodDxI@MnDUeSB+a!2BVIY3rrLDf zMfFVOu+wK61+{cMAx}t4RX%IgQwrE}y41D3gjw&eue0u}C<$I$5l=xY=a6bzHEXPL zoLYL^HI-8;q;ivDHUOQTtpVuDKMX)oej9+Q_fTuoCzQ+CtXz(cOg0CU>o^W(jakDE zMIvj}@N2u0!xR1MG0Dkrr`TL!+# z77ntIh310wls19+U|-rE7_(Rv%$t-HUX)!1XEKw`1`S{;q%*UF5YbD#WR`+?!MtE? z%#{Q3;^kwAjfstksR>ncRLxQS3Ai%q%BUl=;Z*FY*wvp~q$rahHU1j$7bc={95#+$@@TKC~e$DVp+1{2Abex$G>}4 zFZO=p&*4()rPNEU;OvOABhC-dfZHxWZ2Zl@vq=@?ceN~=tULQUTfXH2gf$9l6nezE zeN<`%X>-!%T&fG{`A;`nG!QBr_P%wx9bAa^<%o6Q$cO$MxxWT?zG>^Uhx`wj^64X> z#**-PNh_ex(y*D=PJr{Fnd}~elu+A58WQ5v1#k+R2moK435FtB z8j^SUKFk>p$6ikRIJOU5Zsn^Knh$E$3h#8GBZN0HU)>o9p<|q}vH>nk<<06dAnk_= zHHPMfl*uU(nKR+HlE0PQF;%&ezKSTCDB|g)*Xbc$z|A!9w9>%SJxKU@n$uF-mc^xw zmeq$U!f6iDNjgaZyJ3p9%1BGCX4SJ*D`~1JS4kBncCzJkS_BCdQ%RLdDpagymF-zd z>_$q0$0-S3D=6igB$K49R@nmYudWDaoDD#UPyf>Zr^4VUXjlR+p1s=tAEhm zASH5ddYcWl9G>NvxKXP)vla2IR+2g}!0;=p=P^sb{Ahm63PcNn0@16y`X7ks!ysfd zp7G4rs@X!wIXUO#9B1rQlzO?~`ibi&j<11)^9koyKB`7;bAqn;4UWkcXuCe*;JHeW zZ+6J~q%IJC+S7>XU<#Sn0aB*=Rs(ouTeXe1iB$ko*)}Ce6r%xTj4hJ;M!K&9giLi( z0lcf6bpUC(d>_&nlDcH30~Lnt62f9G_$>u(og@cq2=79sEAnaxaz@Tj%j(Odrk+os?B22DVadZz=Y-VP zQ(sSf=AQ(hcyD}EI^;{ums)Kg7@zT(;fh3lRZ@08n7wANIi+Ry)7reaNJ;2z))6tQ z8n#PQvSVQSn!Z^GWE(J;!Dhd5Nx$jNyjcU%&-Ox@wU!(;Cxh%V#xTZwX_eJxeULD) zBqf=p2wWqyVd`}<>MnwJSXEuQO!hFFLMM7U@m*Jf>C(TKQhF2S2tv?0) z3;hf4OofBv4vt$e$d0LTzy1?P;t&ZXPC757UV-}>MwU4}5JJkETp1G~vC2(<~Z$XiF zVcUv~=`qUz2l>Ayd2%23(FqDRD_Eyy7?ggo^yG#=K=QQYcW<_Z-P3kY+x;5&F8MC` zGA-hvog$uI`WdhM7sN9pTM#OzXbMtC z>PT~yM`$&RW|r)hCQ5c!4@$YV$QHUR!WWkK3Yd#S0% zUq|&wjX*}pC~CmX6*pI$&I76IQr9IO{HFovcZgXUv$X0tFi9rKnF6Mp>1G1LwC%uS zJZ9E{`NVu;bbz5brq!n3)h}nK3I|tc6>YtRcIGmecoWY`4Qy+GIm|J?*>ZSR!1zsd zKI^o~v|P#S0Li&n%jjSJ`R~kLtwznzZuF%#Fqu_H1Nzb z3)~gp##y~dUkR%&`uv?+f5<CTg{UnpjS=Aq@%px$UHf!9|X}wg6jM)I*t=_HPEf6;?Zd%z` z$U7$Qn3$g->E)!C6Ar-nH_yMhZ5w1X$!Kz8jJ8??nV;wUfGNJ^&|*-;uESLzqOT{# zjRUu~6eAMSkGd1gN3g$0deJflPQT-lqt9O)e;LZq9dZ}QU7*D4P_k&rq77<5uG+b3 z7mS3&w-et^_yLYoIa1~L+aPmguG`acE<9tKe5Gj+xtvBC<2CTK`5%bqK}9^>?g>2I zfo^o8e|8|lV5B@qD`_Pyw8cn;jnWKcrL2^SKnFTVOBJs6x~IxjTFL1yK>@43^p{$| zH+&=Nh$#123s`9e3}FcMf?71T$QG%kzCabM^={$>4M6fwmCzq+oBu5<^_R)|Ky6R~ z;t=hkzF@5zWfPc|rX|a)j)7ekdYVD1gg&CiMjO=zVzJF-&6COrZC0-2XX|T1aWFkh z4>L%+tber%W|OAAm1aDJ+V# zI@zk3Jg4Vz4dgz#k5&*qHhgSoGL#xqYE0?kkT@^#(;agmtx4Ls87usUgXwQRAenYkapT`T(m%u#C_=iOq<#%aI%`vDYsFTC#cCD8nwJnCr% zs|TmFDOevu7MSMl`;hZPNzU8|$*0cdTHg(dF0Qbo_aw;MFmHpXgOGGA=~!~b|B-S9 z3k)3`3Tfa8Oj6CI)w6Vv3vxliZR$)UWKPYTnwe<>-r<`Ndnfiz%qb`tUoyVr?@+Z- z)kY6^;pXO>o6kqX^@!^cN0Z@JnOkKNfjjv#$KFnWi>)#e@@|5dVIddOYlHVIbHhCZ zsfYZ-J+}nQ3-V6OJFRSS$e)})IX)h8t;n?^|6xd;kUZf= zQ`r8+_Aj=4Xie8|^#xfb%cP5v!EH3~w7e(q^whx9RG+(n_aL5Tig*TU;JFv^^w6&M z{z2rkAkr4(C3%S<>I$(TD5W|gN2G(=tvslKXT1szn_71X>7;_lfD(JD?dg&SY@o{` zr(0;s6)>z@tiOL)N$OfQBaxmOHv$4mRZ{cnKSe+-Am*o-pQ=1(n<<^wH8t65Z65+V znE64=)5omAlG&{i{3F`EK3|1{Yn5z198^YsjK}y2%nUQbtkV=KQG3DG0_$1N9QFAL z2nP>pligbFMqd$BCJ!gvY*1gJxvHcNRK>nmMD&Wa3oyT^!{3IW)T|iA%$sT_u+q*C z%i@4OhsxI~U#oBliVP?+px^G4qdRnO(bVc^?mJQ2kp^9fEy6ovxdg?yFt z2SgnXDU&(@yc?~TaabPDegMxw=Mex;s;L6t^fs9QPI+4!bSBxFUgrI-tJkb7fQ+Ia zfVYZc%inXc&5`vi1?jgl4{&?SVE})Oef7O4?*pXd%v=c|6<9!ixbbY}vRod>{MKI~ ztr>)DGK+jKf$u1#L-WG1W`!p|7Y(MJ=bgO6Vc*1k6Zf}Qg>9w(V-wrM9(Joe$0a4D zZzzKLL;t;3%f#C>Kn0N1mLMA#K$ZX>@PX+G`IGV|#rU95+d^#%?}jKh%FP2fy`A1} zBS?=0+GZrAb%VN#w?+g08cjO%!+I5*lPFIAR6>nBdylfHB znd$!^0C^614&^=s`3~nhT=gk1Bh5%NIH>ybJ>Q$(ROoj)=z-}&AF~0>0<*xZ4pK-* z6U{Q!6a8d+wgT3t=CCRaYqnUWyG@X!^~D)}B_7(ORo(L1h%O z4C^(%+BQcrS5xL~;CaaNkkcCSe3$3D+#?~{jdr7JL&T2}KSo@J&`Y70!m5Dtr1PX1 zqW(D>A!AO)ob>9D@>t4acgw={eb@ITy$Ltk-e`NX2e|d!`u;(R;9gh7@{=GVWCTxH zeVPnca`zow$gNemJPqr;+}`>PiTeF8LXk;R(gS*|S>-&n<_X{#4#hwa{$^}3@hvw|lx zSf%UB6k(x|6AMAj5Nm`cU#Juv-8ov?h|d94S{obD%}~`-j8}`;T42VQG4hR`{~z{7 znf4G{A+|!EId-~3SPRGqzr14K49NAh_m8{VA@hdYiPI2uCUmd#fsl?)2J67xYzNy# zBzrFaI8U4E0G{uS7r;~5v;c6Pusuco6Yk3ZIgW<(1h{@UZF156u)p<<2TI)!mqw@e z4ZRLI`g)dPpml z^d7gZ49q-~_nMS`{%yspidlQr<2*M%Lafv1k9B%`fwnQtK^q9N*)K4&%-tFbkpPOr-3Jcc-s9r z)yis>Xrb%kAq_n3HSjdcP66eFoS-LAi(1kvDDVVQwP)p7ngX+!B|U-=+&Wn&Eo?O{ zt3_v#BC(DtMC`7v2LU6rH6SBpq_ne$&(4

mTp`=&-gEO($480qJkc)8LTz$EIG?SO1eAHDGkNg9>FC*^?Ff(wFie+hm&=V&{#?B7HDj zdx1@R+e#tYLIK)M92|&VF|Wv{_ClG)b|;dhAY)_<*s2++8mL-ocX2YvP#J2P*=ARH z!`g_D00s9H+*7b4q}@upb!!Ef*>@WzJ^`t3M@(^E15Y03e!7Au(e!b5fD>vPKxCaf z0N{DwlmKv!+KH!5XHB&R+UW}Z1@35oh%4R%*2A_=S6*p20G5onzM<$>;7jHu&*PdV z4g@;!i0J`*n*4mh8c;SeG^Ru?=ySd3;@^rvPG88*i)SJ8m|GgaGs=ke=_CO-7i}pa zY>)R%fK>4n2k_)KZ{Pvvw#iEh-1*KI>sbQl)~4SV)*alvcXnUi3ehv8XXbyz`avbu zR&FmaIy=aaj1{aPN*AbK{e`xw;51Oq*O}y50VXpjfEf&t$|=NXm-u&@B74Z51X`7< z60h%D_UEpA$z!WJ6t?rWq=6;b*#Hb>Xx9722l?Y15NqcC8n1Dmav>$PN*Lfa27~OA zeKfXYtPBI*=lwt`M03^M)YNKN4;B0cJgEoi=Y6ZBZdFA*4+aIE|Au&iQY}8#z_Sln z&1&f%q?k^S1nOJY18JhYVx9H64$|)VrdTiPK0yfVkQ}0)-lryd9(}U|mkgDmbhG5N zbvf5Sw^Wu&b4@v$lkM#JuL6)hNHWMOHqAI|uq7+4{)b<*b>c~o$K`Q0*lL)p(hD00 zw56@-4{};gv%%U;$O=_t=C&8WjMf2x>-7Y`R+8G-$ZdM)T(Cv<0^?XDW!iyRVwTAA zAVl;sF9S$d=}I%}2gH6Qt2@~yTKU!rsyL_yX#Le->s`A8aKu&P z?tr@kk~YEFUc8k17C5;xnw6;mReldYaKXGYfV0>i45-n4uoP?D}`vEaO@-|J@`fOEp;McxT!Ab`KDtvzS75*G*V)by9h zT@-fSNSjvZ99&&Xa#%IUzv@oUiyNWn)S^>MJq6}d^Qn{oam2~8=eXCydUuu-!TyxJ zCk4~d-V!i0D`pk<99B{~(<8Am#jh@$c`hD#+@H}LnYiXf>A3!`$Y2f)o15d|neUY4y6Z{fHYMBd(ybYEm~{QslQgq0$fjTo7vDx4b1|7cR$EQxhQQd7aSUTh>cy{(j87HS|0MnpfDA4JRiBm;|CY?`S~;aimh z1gd6@fiL+|rrB;`lC`(1zB>Nx1$MLBG*hX18bsud$Q}6>TrYCH$hjmiwM`8(0nXqO zY2f_FcXyZS0o{-0E_1Xgq^W`td*1>uwX83lsbOVg<^eMUzzk+7KzcR*k2#9K z&uLed6q^Ffr;OwQ=ChC@YIl%B19OypaLA=SZXQh)^1#_VzK_Gdfdenxc&BDts5v|4 z!>vHN@h1V8PE1$lfCk#6Sq32Fg0mhVe3$bunXq$3>ebjOaP?cM5LOE)Z1GC!(A1Z2 z+<@>|;j_Y`z*+CCcP4?qmcN$o=O9k!8rMJ(v?3h*N;+>*9Zibks14_U@M;!;HkvamF(`s&At)f;WdxrZhZqY)Y%YG^#Y^Q;zOLmGV z&&%`D)*>E)15Yr=(@+CXKw&&sN#y2=cv@-T36%L;Yv38C-Rm7RMQo(kyD3O7=_Sp9 zm8_INYTZeZ-j}vnS(;}fz<{uk_O$0qJ^shCuLo(QWmWq+{b!hQ{%ZjGnV)gBoH$lL z@OAA4=>XD0dITUQQ?;!3f=2QdYUmXZKuxuNJo19t12hkcw1LR`7>`LCYoeXiB=?|R zz;1d$8*5|_XR$tM-*q26Tj=Wpm z>SN?J2<;o%*ZVa{Zpkg7`Wmku#qoCIk(2tGq-EN27LiDrl|{&1Engc=Il{6L5rRmJ zHd*>XrpOe@qvxF$BwC^cO{Jo2V3WKWcp~+4@__sye@HnyhDVC%@#Rru;Z+2aGf4S+ zOpZ}b7i4LmInAjJ>}00|#^cmhg>g}k0WyHHHieQZil|xyHFd6&b<)UgBvMT&jfUCH zpxoh()X>1xM+0efJ^v;_98V|dL_2-%1A(A1L~)@~j@u7!@`?Yg1Cz{C5Q8{GTaUs=D(J zu$&CtgL36fY?4VJ56i<62t-{pR~)Yq_C>w%ftl;|0g)}hb1ST;_^5_GY2W~HPzl+!o?rhD#_iIh+ z8S{k7^(8o6a+YgDO{`@^oN5&JkN=C7hfy-hw@#;b%m-(gv&?y#?3wZRz5;;-E3R@M z3E2x?j>=Ift%2X@&Y!8mxB_;3klfX>uopY^AxzI(#{~t(*+^bp$Wb~CB!{(&AR24t zo`xM^Tu3+4!06y2`aH#fJSY!J5ug&4q@1nxN@@L`5{ei~gM1>NNO8SSwQRLCYm#Yo z%^>Q7yeuzEbtQ2dX*s-6P~g}n`=q5>rB=`lvv-hy@Q56d`XEiD3GFrTGzsEd5+s3u zV*0NF&th3DO?6!w7 z>~&>`{#{_)(W-wLfMksBOt0v|9HuE%K(N$DS@Ve?pUG!g2hvXucz_KE(pMvClkCXK z*L*F5HS)H|hKOX4Awx7$2VX$#2F^l6m8c|*wQANn+X#sZT##m3W$3PBL-fI*gQkv^ zt&NA&RfN+rs4C#cPeqbY>Hq*B07*naR8326N=0xtxtnB(6(aiI1LvS~&{OCyF4l`C z#!Lj?U@7dW4Q>vxJ>chUxm=EDF?y%I|A4IxWFD8|01?BzpWQA1Qjhae)$X(u2A<Z?FhKc~^172v#RQ!YZ(T7J3?-d&}~qy2Sm9#wB# z;{7h|BDAE!ifmkr**G z4iHD2Bx*IX0CuK)4n?MZ4HSWq!8w8uO@btdPw#Jx3jD(CSRo0=T8S3ZX38jiu5|p2 z7?7Q^ld>R#WRR4$!a6CgW%cs<{(}1cc=gdKVV?tuw?0);RjGpbASLhtIUtRL{BtHS zLF(zo5%6fPqT{RTX-ZR0%k+T_zL*woIw}RxUXfSzY~-Jn2{fgtG|+X?{GPzmOxMvs zMLfa6#&I%EdTHQ!Ae(&V4gq*8htzkZoeF*@0LMB0CtcHAnJazt`UVixqk3KsXpdQc zyUut)|8B;=C84!>Q2MB%xR-vxO555%c~wL|fSs(kUgrl{j^hEiDhi#%~|GsKj122`2_NoU+o zLZh{6rF4Ug z#v0WXQI04)2sr_i&_Gd6Q-~s(^2PzJX-%LCrl?U~(G9tr_E^1Oks5J&9)t9KRqVz{ zWt*x=Ju6%!5D@PRY7(6%^Q513eUO@3U2dNJIkHd|(nxJGdTYSw64b4}SQg7rC6^!6 zz|$=V@r;vk(&L`M(@YUhJCKgjQ65qOaPuIc;W0TTL+o+UUXSYwydhQ8_FARs~bTyJ>$pj2lsdwCY*1$jXp%RYdt3pIcNGFZ!TBeTnaY-KAGHL`xF z7cKzN`fDJ1NFjIt5w!|JL=W?@w6Q5bR(Y~TwnCF$^rEe%c2&q8YvRL4TQzQ~tBTV~ zn!7j5_C?_U2c)~@f~2g4&NQ*)Bp*WRq|`}wqafFgTsvaImHa#hBydLdLFuQQ*Y9=# zlPn7}s>9uo%t8RZId&23QHl4%my(2Ui!MwqK;;hM^-o`h>bpV?CszUI5n1f6fSf5gQ(`AWMp{N%`g`C$ z=RW5zV@Yr+pZzK)o?_oWa>F)1b~Is)3S$f%Ga?VE}O z{CeJ@LDwOPB*~%IDUY3eD!COAd9ag2ODM8Z7XT@te;=cR`f_UZv%IZtNeN3eP)eV- z61p*#${xrkWu>fCu?tVC>hoG9$cJZ!%%H9|hn80tiAMUpP4zi!u3S@fs~?gU`rNkC z=eVMp%0H-?NM&6=O>|=#cn{*Kdk^Aitn2Dt#M9&+#4|(#Pm3UZ&`~)mLoCvwopM_N zVdG0Sg=4Y?o;KOSMUqI8@k-G=`EL-A*hx>)T3YjgLcAyKU_!pqX2tteaJ1Uaa;Kb) zcxH%&sO;3px!hW_@`XJ?(_AC%x}ct}9ON*aHBca}rD=9BP2m!E?0Ri0+@E=0cL-2jl@*`E&} zw1LwDz`bb=vs^JX0K6T{8vtp=tPZDA+dTF6hr__$?qSbHSkV6R$0cqi z zi)m4%uJ$OF%x>aD5bCO&rMM!Y`c~Hzs1`{xts(|Eng+mVMrSSXzy{pX25^GQ=^125 z*C2h-SQ#rl?7I5Li07f86z~EU{=_|fFW=Ks71f=yTSG`DS^8>qIo_tIffVkab3m80 zT-iiZp|1J`0cB@bjeJko9W86L?8BPVHqDNlS&>vDYar4}2k9Vv^@21G;%eqIUj~D; zlXlWVt7d^7lMWg<8mn}?HOM(RmsS00Zhd&9g_?CYw>xi^zezuvEj(SXWu)AnZ6NYbk#qo0NoO`dYJ_hC&qDP_V+!x>4$sdo*LQOz7?`_I zoy6YIadAwcEA61i@Yp9WwSp%iu&i z6~JAi-|w}9{n8%szXIT0>U;;_-Y@MeF)ycB2szq&yNL%vwtEIeG>7Q2(X9%Vf$KZ2 z@3^`^N!5~izsm=``tb|8)1TDWFhxjl`kJI<^d)^h3M+z1)m|l!J|CqO5#3ZJZ-fd< z!|VnjCA62!r*ecC{r-HaVD@X3Dq0asMWqZfwKpp-S(8CYCtdO=*O5cXVOOiWd4VGw z3Fd}KCRxgB6|#y=4JFQ&-=%60!cHMY%3Hmh6i{xov3`H?Ab+2ovXffc)m~7Wy#w4( zeqE2PEq6t8yCF-(piJQocW9-lRyC`83+8^Z0?*$?Jb`r#$N&vIJ#5RBG}70H%_uWI9^`n#{2fodXt%oBm*Gm>TkhDyt7!QksWU zcXC9nVLPir_gUL>Lmits(psGle^(`Sed|+1ZR-$c{$G3N9cNW}z5DMzGt3MF!xZWi z$}p8KAV`~`H$?@(5;CaR`^;txlJ>dxbMMFf&;G!iz30r{@4Mb-J?mM|J5W`n>%hCjyTm&M4oyEa z{m2_ov8H0pk(VJYsr}$ScS6wSk0w-i?+G+~rMV4^#{c z{|ST4Rw<7HM9(#6P}v4&EbA=ENyrWT9iV1*#CaV*9OA&G&|_idBL`g9e2BHcAKA}6 zP`5kQ4j}wivbm9=?sh$9(frt>05Q*8AbQev14KS?vbE}|ks5%cEup_M2tY(A8MH?a4N+&DuyXSqfIllYGmPR_Btnn5I-KNlM&w-OsO< z`AX}y&Zo#)I*()8tM{*yQk}wYA{>rzgbr>WJPM>B{;3-;KG$V8YC?8)9G1;?Elr#v z#5GgDe~?nF%fX(oCv3c{((<&%tuHKmUGrv)QZ(t<7#1LpE2yBSWG?55((v^+uQm!i z{|NDXVPDuxRgsT}c+M8$8Lkxg4E>$cR4pGSJ(Z8tE>a-A`rko7NhC#PNv|M5lHI1r zHd-FDei>aXyPeq(8RL;sk&~V5v~oeZaZafkmyGvQGv2vc8O~K1y}Y66ja96&aSkfm zQ2CDZ2ne(ebC`T*7-i$M@nMcuv?&^}Ig-}*Q;ODC0;?Vky*lh+kL5b(Y=zpIIT!3q zJJVLe=8l^?ZulPLUX{DI#Dgu@+P0zsi2l`5DTLZkG~{K&;c4|hN(e!9&&VGVE{7(M zCM*XCSGZzS^!(Ug0itiYt&F1&+baOkJ+=TKbWf-oK*9swP=NYYu?WD?bDhO#RWx!A zfOj5O0)*yx<$}R~1c>}1c0EAkNw=Y1biB@UV=m=861f$i*;!4x&;@qXhqKyV1_!rC z$}_%zqfbW8Oa2h{KUH^q^EQy2-r?&3$#9_KfsXs$gQJN@6RV5lFH;gYU(V%L;!wG@}NPn^O&y~kW3qZ*wP^|{WfLRD(pm`<`+F|ZU%u`Hz^m97`jnrXac z>b@D8=xMUe$OW5eGcCm-B65M7x!GDaLO7*DI5}Vs+Jh8pw}%3KzP%7hsXpIH)wxp1 zIJ&Al-h+l6M^&x04Yt9$gN?PZ)?2-3JrsB}t{EmoI8ftyl!_0-8xXp!u{BK7_v$8@ z%b0+UXT7brGUa;6C)8NPA)$o#wWsucpF5J!o1n7qJ>XsEUB^0gx%W{Qa(^MV z&d#vR?sg81d?qrzv$&K_YVs=v?<(&qdOPDW28uIUpp~Hz*1xmunn~Fri0hddd6;swsYHz z?fN0~XqCRS?XTgZl+H^Esal#P^1G#-)uAi+{W)4(Etu8aWydm1;`;M9s(f zN`2qfeQTtn$<@U4tFsBmwqlSY&Ze34HRNqe^4Ga^u0Zzt1 ze@*;+U4KeIhx5EWZ{ze_<|>en3k0}zwvM3+famCWpVA=w{fCHWSfFd(2N36Rp3Ts_ z4(f}1#B(3_`PDuqs^{(luuRL0Ern=qH20`){X6Tp2q^AF*KjOik+p;9^yu`uZ9)XY z^$SJ@BApRT>Gd}dQJH#drf4M^E!|B|S2bg%9_VRWNqmLrNL@by>`uFrzPj!- z-KW2VX`{8`bXRx2?-18dO4|WIDWx{t1ypOJ>xb%oT_nLTlg^`^Yg(jKQu4Nvz?VV& zfcgRTX|Qg_x)~p@hYrzBKkb4xK zTSH{GWh6|2Xp$`gsBRXy3m`H()&U@r=zw#iHZ}?%vcyIM)PESu2Z+2H>j@BfCDsHW z@2V2V*rX+A4WP_~4Skrpjw+oEAaT+;*8c- zCY=1%EbDP*?J(O#gO7~RYOu6yPwuP{6)4ENcuYvua?f-1=1<*I4 zZ^DG>kT@f8M#|1(p0I}pn;;vJB6l>M1Qko_h67ZUxUzlaTXhcr zL{5z*0@N>#4F!n25bFa_|75Hdp#IrdCO~Aa|8uwFcTGYh25>Z~{%L^74%g#dTO0W` zP2uxtRkL#Dz`|M8t#VpJ>|<|4=+waX%_Ngn(Bu6c@1HguLW4ttlha}KJ*)5e2vwh! z0k8AAZ3vu~veY){eQ(#fsL^?s-e*PNc^hU~`v1>VrOK7VW=!SdYNf!i+WSgz$- z6Y0DXRiT!vXX*vIy(0L=(NaLlD;9^#WQ8El7d!V4H2Tp>fx`K@iGM z_=)9f97;!I+3MEs=#aM+s+^xM<+gv{&MJZolw6=#tqy%;NY<~RYGxnVM^+@obuXo| zX9h^~C{df}o)i5P&KrIN4&oUan707EHLr(jp8MR=nF>6^ z6c^5Rlnv*(-oV<2)%^Y1apO;W1)%M-kN1i2{_y_8kBP-E5-B`WkuHdcJiKEN(dl-& z4HY*tT|e(G8-#L|?=RAQM~Y1J^%UQe7p;$kMg{B#p5r-6oiyFb9O>*f(N*)?MmAa( z2emm_I)ok?n7*XGj|{Hby5>jgr-7NT&y@yR9X{X#E0M2EI|ZZ?u7M4~HI3d_C|W6Npd?JMV}kq`U&lCmj7--r3OP<%D_M1Btss z%>fc`54{O+^w#?300(cYeHS2ncXTg6^&63k0czij&IYJHEAl14zHZfL14JrZwJote z)C3@uvPC--$9PSyi%XWGS?1-KKRxDt!3Thc7KV z1U2b3>9yrf5Nf3-I3Lw{Q=@a9kZQV=%Nv9^kBH0Z29{@evE6E!$qpcxKl5j+cU|(9 zBt#U`dy0u0&{EmNFmi4^$RPBw zqoMiLHrrM`--}`l8XAXCneOAwRR9*(nXx;CSYuOvYy0Z0n_Y zeSr|0k9f)y2d2oaV5*})>@)~p5Wb+|7RfNGju&03Hi`pUBb)gi-?Rk!Q{+#F`a?7p zjpa0Vg4pCdk<;_t7rr2UWHQCYJ$cw@XV z6e~au(7@~f*4?@@z`an~gE!5aMv-1fCke@l)a9H9m8VypUi~F3&RCqWFcn768a-=V zISf8+@M%+L!Lk|4X1w?uMCL^1gr_w;*YrmddPLSh?Jbdqyn0A#9vW&P@E)+Yi9u|! zSFXJB??te4!OjJH z!%oQ_?`r>&Z$BCvl7$DUa?*UsN(zm@9%0kz|;Txm*By+rKRv>$k z4nk@Lj--z(pbHul*tW`6S!e0zIw}S1+~|IT0{eV*p^KfOly7`Mp0ba9Ho+lA?p3dr zk7W8vAb63;eA#@^N8iWam19~X#N*q93|8QoqQEn`0rB|yqS%tylIUs(&kN7ncgqRJ z311!-0$OtX{S6-Har<9Ty|8-W!JG7;3Ijb|@AJORR74*xlF{dgrmJd}qd+uC56Bl> zovgC#NL8gqfGxG9aYQp&3gzz3SBT-x0L#yL872fZLMdLZ6t!h);`417%2iG2rE>fL zDU91oI9AZm1*Z;Z1Ko0;$)g zUYqq}7(QwEq>Jhxb3o>R_7j0U9AXP3j)^7JoDT^-ytY;h6<^o=(z^_fPObmcYYJ7X zqiLZ8Sb1yp$bt%Z@x8BSbcw*9-aoXV2w`}w||GYzxzKh;}n$A0vVuYQIi*<9{ zN^G}~QjT;uRccB-qTZ(jC(N^C=h|Q?N-0wG`@&k`vs4AjlBH-9x4>AMkV*@s_GzvP z8?Sz436ZpOfy?h5U&szzyRwbhsT136rQ6TrK>21 zKDdqL3Z(Sz)8N~~*L-a~ol=@IrAY0Cl*${bySC64+G*mXIw&O`6=-_hZM&^p2);a^ zT=o^&hdFHiJRBYrC6(4ifoGHg&(sFxv#q!FHV(oUg)cfX$N3o5_dZbodiN|L zpm%;L;zv_IjJ|T3|lbbA}Iew`7fp&fGv?Nv5y~tnmM0+yx@;e z-_G9Ne=DRM4P6s$0sO!lLF#|SruS?Cl4?3UP5D-iGS=c>~V8ABN=>eOR^{B1>60yb#d24dtg^=S8U%q`ulswRn5m9hZ~(6AB{i1UGHzL-ZO#Tt6uc-4axk*SYH`^ z3%HWvul7dQI+5cPb$C|Sc0N6xc2&~#lz6}`cJ zWxujZ#bx!zv1}H_e&C+e2=^uud=b99NZMlM4`Dxj2|d zCEWVdRVNtjoEBMzGn*eMn}mDSW46ro@-PUzQQj!t*Y7Ek175LGt1=mn{l)Eef%euW z+jX6z-X5}bT?u&Cd)JfabWs$#mCP$rPJMyfb-*hT0=odbsoqpFp~5PxY9P$tI)Cee zC!zPq-XpuWh3?OGf428_2tCo^oNhB<`}pnM*Z&0~{kL>l))!LGue$fM^I-i4k?vW4 z0N(Pt`@4R8>(P-!j>0FW*T0-z2=#LkSMy$G9U zZ9Zq?ELhQWMbnkPgSzUv>WI$-c5Re8Z9LBJREiScVfE7!e8&<6g4Kb*ny%$AwojbE<$QXc4f zUu$a_te^WmU^4?vuj_5SeGh0yJ4=D8tyNq1=DS|Lx(z29teft1=cU^lDWQM+tb8%F z_JqbXzBKAZy(6QcI=4D^Uj?MzntE&7%N$9^Fo#$eB(iS26R3fdrX#_-%)5-W?tyrt z)g<_Hu<16P-LChGVJ^_H!UYVkm-BV8-|P2$23|j}AKj%J@l&foj=ZKjc=vhtF~~h2 ziiBi3D)4|iE&Bif48Tc5K~&|tvaQ!oFK~u4)u%`Ts(c5{DRNDOzEF)~aYs2q2ql^r zY0B-h!167h&Ke-8U_Gs;t%TJrSGQbyHmvKjuFvPYp!dAqFZ8??@+agUD4YUmgYvic zJ_V{Ps;3>94LzD4*|7gTsC>5a*{@qc&A6IzN1lP`{^pMw^2TFhx#4$Yf2@00Zm)TPzkSAQ<-IDJRu)_hnyZtcu>w!)#6hgMd8E)MOw z0J7*zXEv(aylsFx__m||ILIf6fWF`hK5^ynID+Zu%D^0v4(M}rm*=UN@V3guEgGrS z`~VTrf9p&Wom+}4s&t6hGTnkjrhZSR-jD7pgOYf6zBQ50PG=Q8lHEdUO%)hA9lMTO zOnRl}a?mUiBI+bx9RK^~2lPG_RM;IdgYP6x=NIC1e7(_idLAb``wqL%k?9OjV7lyB zVIzf3&}d~^P<>rbUoEsgg>j}bgvoJlD)+gIg}lyJHMv}Y=j?_SDSORcvthcv3)D`n zoqG6lsOwwTckdG?Tqd3Bp9i(|XYCt}0?;iJJnX!R_^KvUMsIvVn1j) zqUng1TOG9Y%AAdbY0r3ey9w$IQQ7ec@SgLY;|rG(d6V>lXSrP4>n~rH2b>o)>m=@&K=xIe z;gzWRaDlq*i;-wWYt-c=GJl^Kd3vGYX_BX}nLDCCJFQklugo1>E zgvrjr)*gnsm31q_S30x&npD`kXYZc<*TAZ|tLA?6bJ#w1``BHNK>ZKue-Np1&nIqJ zk|Aa6R}JJWfN!S|KQ{269bTgV)ffT!qp(XL_44ri02ANnFhNz)KLPyVv*nZ4Sqtt-G?o*Mb=jfTVcRg$ccDe0P3TF(M_Dz6%Bf|IAYpr zTWzpg=qbcGQjQ5MED<7hp;EaKq8f&XLp!yhcha7*XBZ?Q=THdm4ezb&3{@9bUA*O9 z`TwjxA@Y$x=Lz2pym0`E2}EC`SF}tlK(mj&ajyz0*a9^5W*U>cT*C62p7ts0a7zvuU43&E5)fg{;&t7l4F zbtr#LQ+Oq|E{USK}+d0Wr(O5k)(=UlfVt+&Rd1pHYDW`@e3U%KnOvGS2g z(Df&|eb#*LAzqc*sEOb!jmQ3n0cf=X%AR9=dk87@_(%$5zemj1%`8_hVtbsI^m_IF zrHebNYAA;XIh6R{p{<~;l>%0}>uDrQ3h6M;`#3}6BSdW)z;bZA zWt24XHS!V8UGh5DxU&**KRJPb;|Gd$w$4f#kT)Y4X~p{e?E;2pn`{%=z(rhSB|>Dy zfhKD|#ad_!?P4Lwlhq1xMW7k{00-zVIZQVp{LukBjR+B&40g3$%?KH+)k1h;c;ev{ z1)ksHtaVQqc%ph!*Q>5qx$gwcsGsPTH%d(Yz};HPZurJW4|0&tp!WRQ^LM60j*F>^me$w;*Hkzsm?ElBZ0uvf)j#LR>{fV?t6R*BedA{ATwjDkxZAp5b^-fVtoyJ>BmFepg zkTbL(gpLhVam11KT=P>udtK>VuI;0AdB2RUeiWxSUsq|#qpRNsc4OZ(71 z(}+vw_*nrYFRj#F|73psKp6dha}_d#moPy;J{L#KZ60=@D&J z`C8A$f{br>MC3t%^#VP@YhKU~zIVJUB9}%kJv0*zzk2x9BWFX?wN2ONE`pS@l(LL5 z5Ly~q+GH?zgS<#f1E+GTcakLak2&PTav+^_hDfim+>yjy|A3FrRBx*1_t5;( zDK9<0e0!6sWI5nX@+SHFK6yE~joWT^6TmBwLVKoGpc3$Myc{y6%xx(jn3k?(fD*7v z?NYCmUgTNYrYKv;AxTw$jyh*LiNB-^6XLsCWQjCyDh0AXL6Y5y<)vul>@DP$0+wp2 z_W)i$tl?`J<>IYoH%#2Qc6H@Vx*6 zJIrA!mFoD2D9e@gX{YAa%tn8ApiFODZ7bR0dRnS__OuXAc7Tlbt6#fp7X=aw-mUKc z+=af7=>#7CWPnn98ie(47-#t7^z}~jE?OHXn_LMw8+)%vf^mGYrhiC!LR-hXg z5H|kZ{%${TRo>{=5ca}eMLtwtT7Bux-6EHJ{>v|3Ws2*SJo;Ol{u6c_y1?0_bA#H* z60~*M5B=TP#~=67$xM#D>=u;mK+Tq#ExT$UX<^dBR#|QVPQMEhCnZj5`fIlxPr@Be zXy~<4t3eE$A~(CZ??EqlDHjTV?#ri@V5E3Yw~O5?BZ8 zKpUVZJ!z)vGlh8SWJ@wpRk-@V#9GHXl67twZ=Y${&L)*q>cQGr8%lsY@@$7AF}+c0 z+D&&Y02~e2Wf;aFm(r1?V!$E&{LsGMgSBz~HAOCxJ}e?c z_Oa|%{NAbcjS$Rdf$#5=)KQ{jIsFUi3Q!p;XE#?MYwyNKyd0m}=97K?HbVKd}&|usz~X+z>oQ{vA~m&rAY2eGsC*5=H-vB4 z_n4EV)PL-%yZ^%5{ugm``MgJlxpndc9zctc9Eo?|!>`i;q z-okB2x%k*r(Dz=p`N|k>l=bbku52Dnhv>NIxT*)$Bzj1_T7NxJ%ftye9=(A_HVg3x z^VaZ5UbtK&!!*cyW_j#yW{`YL!oa|Hw7F)g4cYuYvupp@6$x} z{i)hRb=4L{Mqv@N@6O+yzdQdwdzPixCUL;CgyGVj`A;K9;(sRq)vNn!uKxYv)9&0y zO$uj-<{T#1=w8Z}oBu*UZ2xzQ%6G?i$N#lM8t!V51z$>lu|&!7e3j3aNs(34`oHyy Z|2LIBzHF35;S~S?002ovPDHLkV1l`Zhi?D? literal 702 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q4M;wBd$a>cF%}28J29*~C-ahlfvLjN#WAEJ z?(HQ*-U9{#ERM5xZfps?pfXAE&$i;frmJthuiTf)#lxM`(Dw9B9%F-p2P=cu&pC`q z3Ze`ePm9?)8bcTsOgS&9z!t>V5M-C$ATg?7G#m)0ho9`b+t)huzBJGUCP)TPS3j3^ HP6 Date: Sun, 13 Feb 2022 11:09:13 +0100 Subject: [PATCH 196/629] update logo (make grayscale) --- .../src/main/resources/kafkatorio-logo.png | Bin 141155 -> 52828 bytes .../src/main/resources/kafkatorio-logo.svg | 4577 +++++++++++------ .../src/main/resources/mod-data/thumbnail.png | Bin 77215 -> 10274 bytes 3 files changed, 2904 insertions(+), 1673 deletions(-) diff --git a/modules/events-mod/src/main/resources/kafkatorio-logo.png b/modules/events-mod/src/main/resources/kafkatorio-logo.png index ac2ffd29afabc520042c1137a098ea982b7d34d6..a37200e6995c6af2c45ff2670facd04b3d1542b7 100644 GIT binary patch literal 52828 zcmY&=2RxST`~HKBY_j(#J5)xtj14GKlg%fTnR}D!J_>djQgQ09if8(_~7uq8K$n36e;%?x4$KA`?)eht3 zy1UuN24DVwI)Ak^%zUU9`BrKP$Q!`qfKjW;yB1vvr*ot^m$itJe}!##!H_& zv+GB54NqSBbk=YG?s+>$#}g-DW|CsjAfom54GB}?Q+~U@O(DfcIf?fz_vbimOV8=& z$BG1OUHcYlY&LOxu->CoNEtEL`Apcj)Qr2>vN7;*Z}Zv6ZctZkc`;!(VI2N*hRylG z663NAUD2+Tv$y_x@G{3)$vdm*4?W{WaZy({6wz@ArIr`BxF!9ryMu;KW2C~5*BEdDp9sNdvhX2KxB}(>kA6K1E2NTZ>iGG zl#WAHgo$UomOA?92PsAeixEtMr*wYm5gun#+(klmAHe#TVnIcJ8w~Obwbe_ zWVe^n6~53P1mh79kuzBpPEx$uoB!Nj^4xiC@UWp;dXqsvKvx*Rnn=^QRY78tR@L}s z*+NR;!>P}4tkNlgZOQ)4?`O9EelO6;RO}2getjj0M?Hpmb9uZm==kW5LQkI7b5Zje z!*cwNg3lHIaht{s4XnB6&7ilx+VxD|NTtJ2sd>rKvQFB?hkrhuOwJZ?Nb z+Fx!w7Cqd>r>nz%0zele+Gr-Cqlto)bj&tSdAR)g_wm$#GK*j2F|jC47n{7h-4;Xd z;br;bfp$>AvPJzg>DVxemjX&CEDsihJM9BZv$AD9o>-=THwqCJvN9qw`-T5>_-28UwGdKIPMXg&jM8Rs=;naSgMh2C27s4_^!PWw+@{j|M&rgVIxNJuptNk`CfUq6`_*L1hU-OR=<0` z%ez^5f3Vo7b>+ML=T$eb6ic^;qN7kKUt-m6_QLjNt42}^aJ?7aSw!)GE^(N?E)`&F zsM>3J3|TX}y-x(ajR8i-3j+4H{{8x>aY-wGV(5+O`#axQX2z$YQ?|kLwb)!Jks~bm zyZ!9!=PH0JWfK&N#>;}p6 zD?I<9%Ybihp{(&}Z$WHke8_!M`)Hf!y-QJ9_um?PE060r^}gLNj7o02y;-Rl#N3@J z{L3^qs;psezND-{zy7ujZ$!sg6*ClUdVM+Sk7FLrTYk?q?F=-oa+z!iCtFzl-7tOD z;#L=ZNmJYXOLW%u8Wca>3bOO|cTrfgIeW?n9_*}6wf8gUy{P*v++||E`O3p6F=FJw z$;ZYtjzg5w`y3aq=JHW-D*ErNWY3Q~BMZ0I^WTTYWw@E&9xdOtK@r{;VJKy;xz+nR zU%Mn{obUt+YW9ohqaqkl%KV5zx^Hc!>$#X^>CTbAECWj!Pn~bU*MBbuJ|xdg`=p7! z43%PtV=QUfEKR2sc6r*jV^Qym#3ikAt6f8yI#QC;KL#Fq5kcZkK0CTRy;lvyY(M&c z)}q${ux>dqa`<Fqp>0qUmO6kgW_`s->W2wKtjV2!bSqrn22H&>hFJDn4 zFQr}ReVy=ng;(u`gw)QP$pQ*P0p~M^cN9Ht!)NoIPxg0bgYTqRnwXvvHG1t@s5_rhmerIeJ;`I4xG1P% zYT|NdtPYKhs?EaK4_6BWrMI5)>pTBBgn9hp4F_imvlD-Rw%(037|P8(*uDj}weY{ph0TQ_Xri63RLOCyPFi2)LXjyWC)xmYxnG!N&ws)It>?7P^oh3~Kb9FbpI8xzf8#8ezu=RfKO6kyTJ^+ezNV2^Ao zvYE#B0KBpR;Aw3RX-TJ2Q0oDx!C3#{$gj^|B1$@ZezYR*#>C$JKNnq^qG)(8$1-If z>?6Td_{JNiJ`fjuavM`V+me|Tw=%s`4ZM=qL?K0KEV)x!!_4<1_65(yy?*c*{0esV zBVOq}eNdo1bTl$SwKT;bI&A&&Kf>(!u=&IsPDr~2tP&CR_} zfjgWbU*sb|T}0j5w z5}8>tZnIxsUby?U{HpO~Zxk2%yv75zN4>`B59<7P(U8F}>ki`hhsNSu)Cjx8ww}SK zs+Ab@wbR~3wp{+Tm!a2Ff20dN`Y3gdLV9cR4@^(CJKISQLgWBauZREr_0f5}A%H>& zkGJ~0oj)e{xulV!zQ;ejmJt*;Uj!#LavWzWm|UTMn&~}BK@GUdmztm@G`1rFo~Ia% znj@8G40~sDCiliL+?Amz{!dHqeJAIyz5L^z!40cU9@b*n!Fx-qopJeBdjN)xWJgMU zndP3`>mOE0PeU;<-c7FLh|N2dG^yj5^StzgqPQ4CH3CB3YUS25Vg6*Tr#N2mR6Z5m zyYsW$x;290LMWd(4UFI1ddes;5;q6)&AMAsCG<83i}Z^0^E96cWph1Soq28W-<89NBO4q$AiT%d@?cn@eWO!2nYde9(?P5{+4y1dhWQ#VqQ)S3^6R0sJpiAjIu(f1AGsBu+-sJLQHfDiUvRTik@XJU9RGTuZKYOeRJm`eAUQ`plidEGA*AzyI}muPw@YE`eb1w`!r{-3|NTm zuNTN!n6CWo^BB?|s#A-mJ)@b-B@5n)f8$vGcleaOgi~*6eJQEQ z{g5YkHA~8B$kQ|`HWd8sCl+_g5(2Ea&}B*c_j+TjJbO6)jw^I8NYq36KCe9z4g&)w8lfY5B(=Gi#L9Dl5{aC zJp*=t(>e1O!!?l{lxZxz^t;+E(xF6fx&TWQXX^E@3ayJ4hVp_0)ZWB&Eq_^deDf2~ zU>ZAH6fce_RhVjCy@;XuI1CbGY9XYYqB}BT(ua`BmHhoC_`;l#J>uxzZ-A%@Bzw?2 zSM&G-5Ea947ELUnnGP&_3`CTw(wZ}hkcCBSrihqU*j{ZLzXga-Nw}fV8>C{G>3pWf z0q|$;eIAN4dT4syS`>UloScyQMQ@r;y=7)@YA!rGwL1H;;{-~vCGOGcAwdhdZihMw z$i5l%>`@f%40(B?VCep$8f}feY%LH`nsvLLiu~IL3ibu;WhbWF3dHzVUP#@s!3G`e z&SeH2otz;McYhj@;D(P;mA1YN*3XrHWmEGgVqyrauzVC6m9_;55trY*t1NPSfp<*Q z<-n6&_RbI7yVHGu=wyl>ZEkLIuvvw&-)JhzyFwHizbqchhbqKc<2xSXE6MsSjEnovbOFm>s(ij9mAm z@cAnSjuS40gb_~t5j}pbL3@7-G6VNcQkc7=kVpzcK|szPQOdn2q4yy3zP^!&s`l;q zc{(;Wou*!j`&{~E!FAttM>AT{gw&mObpTXqwJfF0rjSELy+Tv!J%jJk?%pAUEDvGy zDLIyNq%bo81$P7{XOlvzBLMZp?%CF-aySH`iigM?vOkx~tm(7R+#Nz>w~kE-rdlJMhcBw}o|m z^q(md6wj6FoZgaK3S?9?JWUWVqFd|F{sW)2|D{Dyeg(d;iQ0>8@Tmlby zHrLhuv@x7=ATKJKyk&}l23J?B0lwlZLEdae!On5VeV`nPa_E&u_)#tSyn*{(4U$j+ zOE<#zOPX{qC?aZ?iq}Aj;Jkmt2J*rDv)RVEO`98QStz)Y%Z7y%YL<#uAqAwaLltkr zY_)zn+X;n@;82Y6HB=tRxRrmSmVK3m)J1|a}C zlLfo#nm3JGTr6I&5C{nAa-sFH?4Yuqx0u1|ncjSt6Jg^%C|!HoK?L(BcZ6Xmv{7HL z?^&vdb3k|qL6)4v`?Ao+#0wjifqIqUll4m&Oc6_6`PaDb4!)rT@(+OCqD`pOUL=`S zD_Y;8dRE-!-7wtzbU{v765*z*4g|XG=3gVFCbt|-_lEC^yN_mlb$oBAB7|pPxD~KZ zD!5S5+N9)IzGl7z31ey@Agdnz2Z|{GExR`AJ$gtzkBAm0IUIw1nzNgKE|k%#M`k;e zbkszcUlp9MXr9Pk%+&V`w{iCau+7T(a-k^h%MvKP%##^)zxN`-6H<)av!(XyPAcva zar!bmMJ28iLBWdbY;lU3C2WP(d$KYTk)D^R6ob@-6nY>@ij_v>gau8_pa}QJ^gqho zEFSeBKAuGc4}{_x9qxDjmT_aDMv-;6?gKtRZW^X$iRB@D16o*+1=cL3Fv%=xCjDGboaqafeBKgQ~nsxTq<^7ZaTQ z_zKK}R}B#+kB|}j`C(Q0Ss+N7je5*rK4Y=?M^r$zb7Ip2Y2d?B`#i4T)dSkk(%a)| zJgZkW?o2f?Sl{8UZz#0gdKBsir9@Fs&Je01&*xD^)ocWjCZ(bsmMOR73Q*KyHZsUo z|Aq)P^%{K|L}BFH^Xw@K8{gdkcyT9H`K~L-qtNBF#`3hzHKA(iGmUI1WjqE^vnm(s zzh|jBS?ysZTC%t72P&I{(BmFNa+r<^QuYu@BrN70d?!;&`{Y%~g~dN;<%3jJw0vZ( z0MWMr481&~W>f@fu3Ir)SB)TNK5u)ane+g++gogz_I*#0Z7H-585{QH$ua|>bb0I~ zML!IW*Xfv16g5a2T%&a$x-%-d*y%=)RoWsL#($VB$jJH?NCAg@dB3Hphu3oTn`Eps9eYga)9pmr{NlwJI`%FH<+I+EA$Px5 z8vS0M>&a9Kve>2|-V}@{Aec%3BiE2>LES_9{`MkZVL38j}@iUg_HVhyAhXFMn=!HvLS7_1r0K}N{Ftcd$fAp5o zPikk}eODQWf5_Cy?u*qE`cDiQ~=YogMFM)iSFE)S79HCFx5ZIM4-(M(?WI?F@8)aly=IVKPQB*d@!&-tIKf-C64HbANTSqMKB62#S^_@T1f1Qsa2cLjx zuaVlJOJEAF;i~Pwu=+vXARGZ9TTF9rbNggr&ME%uNJAs%Xi0c0JM934e-7w`xL@7w z;bcH@c^VM3c;DAzE*$2k-T&P+AJ1_4G%{cEHC0q>q3tt@;!IBXa9>PhwJcJw6bxr;+Jk|=}yDQ(u=8>cG1jf-rRD7>)Nb!u&z?6$?(a-@)a-U$LDL7IV!q^ zH5b)A7P>AoK#PQvBe6hSRY3Hnw7DA!a-EIKpfuwdqgEc%U_0ha3RjF9X7vSXN$}qu z#m514p16XmaNt4I!7(W8%tjk6K^p!`5EhXw9MU@fie;@`XLw?`DCei9bK%5Ow%0W6 zj^{2Lld1Yx(vv9`l+K^KVUSv)yeKJ9qgh^(59CqmsgjBL41>AxX!Y8S*}Bw*Sh!(4wN?I?eDe6blW_NeOfpfH+S~i!`;IepfvdchBNWbFO1F zH|RP0ruWUy{Qmc*u#pfA9_9i0P^+%A3OPA@)Xj5od0It9&G+^LM_6ir;7hNkf+BR+ zee|KzNhbP5;|aj(>(AE{85&#tU}vI#3D8085t2jjY-JS%w=b;dDYn_z6q%L#LZaB< z6^Dihvk(-=*1tQ|K#B>fmjBAi%4W=@0hnYloMi&8x2`ffD*VN=z6;fF z=?yXEc_w;JiP$-Ik{fS1Px==(qgNXF;Is1{*F5f~{akhwqKIpzU}-mO3t??SWtEFA z$_EQjOW*8lY=1wbAJ((Fz;fdO(?vRSL$nvUJf@HXBZox?XQ>P1?SC@wOf{YISInS@ zrbxeAmZv{CGj16um3}9 z33I|u^9xK51>$>1_QSAJZH_)o%>k*zZC@TquTgI#Do%3{3#f7 zucwBtb}>*%8K;He`O+{Roq3rVqNX8=OO3R==MxfD!WvA$kh=uYkmrpTLyvvZ%|_?u zJnnCeb&9?S_Q6*_Zh{>0NQpUj#+9D6IGcqu-scC}^VCkw@wdhXM@40z{PwTGr1NfJ z`saxMC@7E;|8xdG|8TG?+SZxtaX9kxs69Xe<&6$GlZpCYdmIZ6EL9=WUk3mgeWeDA zRsmx-;w}eSDKo`K6)*^58$z1i)W2kvNEsq0$dt7qNJ+TS>6Bb4=>l7^)6&5?4sB4{ zR~rE0@4n{pZq_s=Mid`(U9&<~=|sfE`a#;J4=U~LwE-L~G30h!x(9`?)vW3JYWx3r z0lq=T_V&_H`m>gwLr*KiTR96rcqQ#}((hsvEdyd3ouR+`u#us=z$09BqgoxZu*Y_h z@pTUVSs4CwEtIuYiH{?O28Xji*Y#}pRq+h-=U&op1RqrSE8LieYN7g$1uE+r6|3PA zQFfZR)UoZ*;k=RQ&5xpVW8yXk{on#$2?(Je-6j0=x1!6WdMzv`Xg9B-tfjZI^#_U@ zt8+L}ZS7=Xgl}ZVG%&9F*b2O(wPT zv3YqS-+GYpHP)z}j+_Hi#C)-g>?H9sGQkTrO!An|w`CQKBe9G=a-t82f>e%wNv@!KbPM@JPK z?|XEa5nl&3e!$SQvm5hVR6WE0Nwu5ZJ*QHUnQBGY+aF-+zuRMbZ>TgvUtb}i*LnPN z2jcSx-hDV5E3&yEasCpg^!1dZy^`$ri8eGKmGL3-gq*dSRMN$A?~~vMyN-6;{yUz&DRJz5)+*AL3y!QLWqKLC1&N zWlCnRp*Av7#OT=UWkhJVLX4c3`=%yp+!(Gn(}z|Ew{^}USEbs@>!*122ug4BOHLJr z9>;O_No#f-CZY%lFqoznP>Rwykv&9F>($loH2Q(g-P2U>L*ai3pYZA~0O-*mZ}oz& z=A_%V3saK!3k9+Mv9X6L4i|hdmJgMK4uG_~$=C;bCu;7Hf6oL7Rk8-^g!(M2rg4OV4I22fPqEze>{O1+@bFrx|`3m;JcWvFnX_#KuI+ z;Zq_sP2O|*8$$Mwrc;LoCU|Fh76t9@9*X;ZlFrViH?u?2vZz?||DKU4^g`QB9`ldz z36AeTaz@vETmaw@Gzwd6(H)@S6I}?r4HA7vHLzyQJSG_e!Z-c*5`5MT^y=QJ+F*ix zaJu0sA75YJ`^!#zGP|wGa?7vw*L61ciN+A90oHv^fQu_Efn5<%dYR?a4lKRzr)qox zd-8`Gjv;Y*2LiN=>xX9s!7$D%1Y<>%1#tQ}Wbm#p#)4^*@AW)2 z8kxy=x|XW>m;C74nz}NekRbybpk%3=7!0*%_`g^Y zL4(VqoE7}+n5aiZ_u^N~;dY^W^I~=c&(OF-W_$^FVgd%lFkhoV7t};=ibmEs=q{BD z(@TPXQIApZvOxBk#92&waXBz90fj~b#ws4kuc(1Q4Qg^{Pp~sFSqOW2pimDiBwbb) zMEf{@+LAaiS-E9<+hn|5!7u8dfrHvr8*q$O8ndg&4!n$Q;##@6hik4LXNYi$A>9cw7zqA) zOaLulQl(Xicv(e~ZgFG__EETRLgF5k57wdKfF- zXVAfFJLll`o7b^WfX)Hk?{g~0%WZn&Q1hf8xPalpQoCpIH|#IfE;sDQ3!u7)yqRnd zZj;kgqAmBw3@uOaIEiaf_eY6w-g+Hdn+ueqHR|y(p_G@1iFkmojLF(#Fc0nbEc`e# z^3Dd`6N#J{*IfxS` zfm11?19Wv+b_uz#O;IMG_ofvs1$gM?>B!=ab}g!tD9-)PI8pQzaFXkEKr&NK2EHQU zX&YA*6-!G!>_!b`HCE0ig0l#|NhL;8M2@Zu+eS@?zZ}|B33kUt0v4Q zVRFK1!2Z9FRLx zol>ps%#>fOaErrcfPM z=y}iXFTU?l++V!F{TBL=!V3ezv(D&{_ORwQ{veYm{cP=A?IRQ?rc;aXFA-y+h@35^ zw1bKO2pii|TVDTH{jCLsiVKqgbZF3y!Ud=XT9pea8=gbLvK;N!fj%b*ko$m{c$$Vb z_lDocDBySMP_Sxtc>MF8g+{Tm&Bp(FwjTq78&@%Ozv+o_V=N*tN>%2|M}ce-kIbKh z>Rf<*@_D77@gQ?OJsPUm-5En;a``XO0IneaI5}NdNvRy-(nY<5(8>*IIRX_Sm_#bRtbY^ZlGn zgz_K!xCs$uO&7Xzu_TJxu+w(t#7tsMg6r6#6c9}!a}UVl&NG&Og)HXU09^Sz<7li~ zp{cT-i{OZot5Cw(hk}k_Xyt){HaXI81%T@&X!Q!y2PJG%Lz#+L4XQCLYgA~|JN+i4 zrWOUS5;@G|CfpfR?iToy69W1#Wr>a>wx7J1e?o!88um3v`f$94N9lDZvY-%Gm-YbK zQcaf=K5oEy@}LO9JG%X6efsyLxU@e&6e#CabbGkbfQ`2|qCn|RP}Y{fB8eJ*W5Qlv zA+)H_`;V{3;JA*?s+bLsx?DA=eUi^#IKduDIS}lX`kqV&<9-Q>nc5qO6&W>o{xKgi zxx<#+occ=y6fy5!(xKPK6kYP$Y8J>$SsYQ?(C=`S4k$ZVX7`<5gVAsR3 zVY8#RcI73!5eBQPXLpZ(-C@w`u!AD+o*^!_F`C) z?%O%#!CKlKI0x+dDOWylpG|6NpTjrz{7HqmJdD>wGAc3oO(KGl^NR>5KnIpT$L5LOaVPqF*Bs2db6z`^yJu&*# zipr`Hy2730d%p4R0?XTZb=e*d)YHU&ojMM-QD+SjVt^;=Va^K_On>E#VcYCYUBI6R z{UblvwkJ%2rH^-yB~&C|?x&pj4*)0d>0w8`IW9Z$Y7SXZbr6-2XFQHfpqtqA+KA>E;uo z4%p&Zp#f=zS;zz9>`{H6n2OIA-pFX^rzi-ecwhXFe~z==S$ar;pW2-SY5w3G-6r3O zl%KPg!d|T=b)afoZ(KNHq(|NK{PT!=8{w6D34pi~$+u`x6sTo4= zBd-$r`MG!yMS> z0($d%Lm|b9w1>9k3*-JPh%;z&^9*#|KE9@5RR<6S`0n{nr$o&4aQulKYQ*!$iXeuC z+M{IYZcj=EwZQ!XpZDy}4Fu@Vpk^Q2kU(7-ZgaHimr=0vtgmwrES2LNGXg_k*k$+$ z7S?|ke!F42jO!ugxJ`UMB0^)sL?{fc?52A+o%~OnrHR}?;huw<^6w9JZagx}fOXnS zd(?cJB9fFLKH*(_@1(3hB_3vjXunF@gZu8z&zBAFK-Q;|SE+F6DrovpuFQbJY_#Dr zP~fsTq!u&^@X7u$Hx4Yra}Lx37EHB(uq*;h@Rk2*75ga26uZC0L3izygN06=FCZU{ z6hxo7|t?gw^+<>((8uFdisc0zFrSe^o{Sk?O0o7SW&QJvLq4jB;xI_DlbVT zye5=-*Yu~%-pkSn0~Y_0kh=mKZE!I@-it!Hu{{ZAnEv#Hn$QYM!$A>==fo-CXgQ-6 zX>fwGgq#e;g#*9U0l7v-4V~YR1?eh%BV@Zpz=s$A_9|J%{S?k@*Ip*@tz_0}T?QNW z#-C_ByEVp6x9>joeULU2jr^o0D|?o$r{` zfx|^iyV*sF7a9+@emOTDUZw+udep)B-90WX@fpfk)@#+NQse&X-=xR=Re{W!Y`eGI zrFDvJ+=3YxVHyuqK7g*{$Cih&MIJxJRgm(W9InrTS&H<5zhH)h{ZV{wu}b$fFtig* z?Hb#APK8+ZG$1f>g-~-4V{$SWy*Q35YxKawBi92P?Z2b($I>3}5}ZK0k8`H+*8g8w zP9C#uYJRW0YY>?b^2K@W{0~n7Fw( zNYYHC{@o-A8uWY}R2~#Jk`&&Fvm*vkq=kg@w@a*@6+jV%g>6g5N2%-Y;nO6XXn-H6L&__wJOM)qFckdH+R1RdSL11x z8%2uPtO|8Qu+Su?c8HJRMI%f!*giXnunoh`GXmwMXq@b|Dqa6j!NBkx#Z0sII6jq* z2hb*zg}G;FKIX*SDfG3n5Ann0DcrQdsF&4_^Y!Yf*I0Qa`3O9#z|eSmhlyM@z;3n5 zRE;6OVNndi`FszV#pgcOO?34{mCq?4nskWv!--rR=rBsK+0%LU8dTtGJXFEoq;6U=;4LaGf<^$!@7G8Hcj zZ=g{ArELv;FRU<;-?Xhdu;pArUCFop6Pag3SRj%sE-W&&=}v0Lr9(IITPrpfWLy({ zQAASLz@DsyJYn|g3-5GU3C@LF=&X2Dox;JRHb?ikxI z-%=|++|f1)x(I7V>TtB0f0Ts@CI>gXJ#@8*`)Bdyr`?OMaL!veaJ5E^aSJ`XYI_Go zv4YC6$?0*O_ptfTJJsAcX(bSIc`V=c`psXIG5(4xn{aMM&U(2Ss!fr;guyaRo@J$p zT_+JK=anLcI01?9OnPg{Np%Et>MB^^$21TpWoaj#TVK{^)w{s9C4mckFf!~M2T@!P zDY@|(t%$}fypO>Ui#*dNDaK9tmuG3>L6z!vvN%qVF4d6agt&`Ok`no|DHe2JGXHcN zGQ86_!T6tW)EdBtMo6UIYHdKS`cVzo%F456hqS=x3}Z{BYb0UqFrK(2j(<3^-x;mu z<;PBa{?cz5G`R5uNO7KTsDls>LRKjO({AMvYSZUbG`oW2rU#wK5Lko1PY(KY^nxaD zaX2^-mb?r)Jfr0>*uT-gNTQlXOsK4o2Fvp`U^f~(R%m&Kk8uyL@{9h@@o8SbzEJh_ z`@0o}`&IggYKQd6--%aZf<-64ok3N+z=JC4#zUM@Dt{UmkD6)XaaHf#%z&-oyP4da zc$ks*&`?1OuhaUr`DXta)4f6C<9`B$Tdf)iwng5*#$94hA}t@m7Cr6~Kp*Jel?86S z5pnESJ32+r-evekK&y?6s@Z@tZ4Amgg(OJZB$jMzrNcL$m77ysIVrJ3M&)@Vfz161 z*&-HD)iS6-xrrHP&x?;iyE5V~z5Je8dABU;67!11d>pWQo1=0Zcf0!UeESqgKlary z2h0=DvGutbig|uQ`a>9d0#4zxxU@4L?-ZWKn7w9v`SG z<@UB4C`vJMh-&R#WJkV_i*I}BOMj(p zvSMJ2CZ zY_k>eVoYnZ?Che5*5>l>-^!_fo;r>pWBleDIog!^N7YAE3qQYd&6io!!(I zn;5TwO_lo6e{^_`7X9vcbaovPjHr^putz1=PE82=VEHk_TMevT*Suy2BVyjOYQ_h5 zeJTqm4D>vmz`}XP6`@^shUqgOoiJ)F%E@v|GhY1(=NkXlOEIKIpX^o8xaZM>=I}FH zgJeOyf0OC##zoftCNv&fq!68m+O!AC_uA>COcb0#$Wp?5&w}nIZeLh`00X2Ur=@V% zVU3Ib)<_6|8>g?N)~Ehh|GbJlnEONQ*V zsX?1O=^70tOQG)85p?CyE)>^&JgZ_ zl><9FL25{&_EVVj_vlt6XBtM`5R!goQC;z$im3ZZSJ$drnBazqsnhfN&@prh$_h51 z!)gYJ?rrn9+>eJka$Czvi2JO*4Q+BD875}*6rQr=78tG$+zi@=B<>Wwpgt-YfHx># zaNVlqp={~*=H6Y6%f5UC6LkspVz0SF0(mcxJ)R!9mo+MBA9D*&Ch~~nZrDRN;-l}Bb-Q0-BLhb?>Eb;EO74Q0@+38&?F{b) zm7yK7vp17F+E9cGoJOIxy9^8EC|m&@+Kz33?qI-NM>UWT8U~k!5mTZ4=ggo$YIjPK zf+J6^Yucg5XTT+yubkLHm6*j0Y>>6}+&6pFgF0Fx*@yFVp85u5s?c7+n)vL=qCF^i zr{RiU8pTY+Y>JGvBs>3@I`|1AMKn}Q9TA%SH3Y_smxWLP?A;J5DhfAA89Wr!czJH% z%E>Ea40kea8czoW6DG=quC+KVu8?GmCnPxE1ZDz(go3ZNi_mF_vw85#=+= z9}k1Q)GG`&^ch>W9f?J23V*YvnMoT*B#gj$Y~o90ur5oQoS1_2lvV+D9y+Le=o~$* zbzC7`I=6Nb<97Lb$or8{3v?u>Erz?bx&7Rr_QSmqvR>$`%jUqd>IM$dXxjN>%BTLy zhOhs~Bo4hk-kC~JI@$>XxDMZ`R!$fQ=waPnlG7`ZY~t z%;OZWT}O=o4chOpaR`{0Y99F#q8hwH?sAbQ<;NP>IbK*&gas#u9;}-38@H#l(R6-^ zIH#pyWE;pv967*A{4=QoTKJE9P61)>ZR5VW8Vc;Of+~O>B35@cd$O+R!NICLM#DTX zD8D7~`>+7CRwZ(9j`HnoXqsAhl)O#qGJ>9!630Tb3zVBv9x$FGRTQEYHxWMoAU(3Q ztgU}`vbfq)fQj-wE~(JsnxTask+KahQMHeyG@Eer_vHG@+T5Q!S2HAqT_V2BCxF?d zLT>;s5wAOv)RF(mft~cTJ3&Q`PY_m#d|RfnMb(U#vCV5ICc2s0Y=vKVNIPCRCl>lY z)j$<7)^hB#U7P*G^$?go$)AhCC;M@7sZ3yeSO=k}{>?J(D_1A=`K(}{b5E|@4!e>A zO(!u&8q>IX!KJ$n$|?+@y~xi$!EUb(8!sit`xUD6l=(RhEWmkcbJ%zno=`H+j8T?( z;Y$2xgPekH)?i4bi=8+?>>SK(ITqma_FRLm+r36Hva@8%Ff^C#ZsM9L3(PUF)L=u( zpe)(&DpSKv;{T~bID-c-L386npvv$;50Ui2`U;C1TrAfOVG5)^MEq8W>FOi(mLxw4 z4Sb?q>u+oZ|1dAapqD}o_8^OoDIKuNh7EAo`;~woiZ3fYtttUfjMh{-Mvo~$%uNHl znBYCDPWGry7+ajHBt2}xHD+;{9f=LdbE3`0jRh+fYQpmPG19|8s`gJ+@c5e~s^ULD zbq@9yXMp9}*~#Q^K2s_Gww9Z|Z- zw}hE|K*-WYy0jXa{+&F)`SlbFWqEq}vlSB`Vf7sqjx3s{sKm_s8dW_yt?V4#1<-ko zznc>aJnc%BOw7da01$IX2Wo1?{74N42SuMRfXNkKwP|37i&{g3S}yCGfIVvEfH4x0 z$z$~xIwbp(tZC55-?p(1f<5dgL%tybbqf{cdkzHUX18j zUVlQE`5Y3$!EYaPcVO?dC?oSgu3N)#a-m~iSl2Mqv}xvfTEott$6^gT_?w76A97-n zs2H8q)_TsT32J3yMcSE&q2G@zjt=Rqaf2u--MrRzD&4yRnPnn%@;P@eQ37)^|NrW6 zsED&>PYK=_kPW2Vb#+2#XZWxY zSksk&XD4O+{*!~e{_97@cS;0c9T$Y|=G(u|JJ_z`U>SKP_8rLcELp(%abo342cXY! z0&v=JCv9lJN6i)_7fanH6KZ()L^Ko&UT-)2rm@y>hhEcUuG6pw(rMlW*F=sQ9FicP zr|J3aLLB*=r)rF8;Z7Hv!X}*|bGMc5z|SIsv(YEApKvBc0tH5ZBYLg+!Im8x=m4r3 zqP;_Up~42{t0GmrEj?{>u`m&w;C{||&y83^ug?33WA1swxYqni(Mbk(n{iv5Zb;ft z)As5QG14;J;9K-Jiwuij=`b?Fb-S!jgS?XVX5Vdz7fi*!o=D9IH#64|hn(z{I6ltZ z-S+E)T`_tp5z_Z+8JAa)_B846;d6jKJY^pOr1yxAo2#AjTY|!fY2Cu=9cjee)9cL=^aDJ0wpA!q6T+y%w;o!Lo(44o3&i%wP^ImlS^O93NkURKZm^m`{_@x*6 ztZ%<(YAwAZbGUrvTJ$l|7JGsM3sW}IW3VuVE`*0~w2Y?NCBL*@V1*~0bcm54Jpe4z z*!1Uk+u$lNRus$JLF|TSfV^!VaHK?0=VT1R`93w6$|EK^|AQm!yl}+`d9!Jc(1a>MJuJFJAhoxWvo6wuo7K!<9@zOz0y$+wdM=I{fyxFrpg06 z5*g&_VI<%B(Q2InDhcWm$NM{qh?e-+jvHvS;i4mvIF}F4X%JXwFx}j5x zgCl#MOi|Gj4#8>`uw5Mg2aI>RV%qd-w+No#rd@cTCc`HS4-v}SuLDC-e;y^CuPc#} zK#`0^^97PLzLv?Oeg>CGl^ldhqkNkB$hmNI6wc$E(}N?XOG|L@>Jc*;;!qRk1xGJ* z&{$971|~EuJD#oL%s!iN&Y)%g5DF*n|EBOKU{Z0zmnx#q=1%!_%78jiU)Er_Gv^Hj zoFuXjLe_$PGdM2d7r%r*H2PKS)+uRB{n^e$&mA#+f33jG=R_Jf$BqARF2zzsPcm&D z96FWCf8YfDh|jzI>VrTlo7&xt&|pcK|9{K_=46F6)g)@yP8DmB-8PP1#7u}x2%nk~ zOMqt477`6x&dbvx(`!K&7Tqkz6=(4f+inz`X$#<*o^Rpx9Q%~_;B}reZY;>!_P&sc z)0-8G6Sn{+olB+H{OJET<+U4uv=cKYpsR-KKFq91oFgr%Dc;gb&Z0nBUjKf)zC!m8 zHhvzjo%0Smt--sP2)J6a1@UH z#68`A8jWu zRTDfTAxH6umtOTLn4J>5_QkF4p~qz94cNI#(@7Dkd-)HZR)JU&VtYdvKA?vS)_PLA z7Bz={ZErIS@6mRPR4!Io0)!F69hr!vs@_+SHfLhte>DQH(ECJ+#;k0kcs^Er&&ONZ z6AZOV=v_e(wVPZ3MYxF&-IuvcXyw4Yc;OJ1rpkd#WQ)Cd&|S(61H;Eh-yG|HnciP1 zb+nL0&($O$p;p`m1e6;$8cNuF!N_~IZD9Nq!ks9qp*|T6)p$|Fsk;W(GmQt_j{O1M zxapRk>SYg3-^86s24s-7ml+f9S{ZFtKM*6Itc5oeGFSFpJa;mkGY<26DeU>5+EJYP zhKvp)O}Bjh6?9y_+?rsX3@Ml-;aMA(6)~f|FhtWrt;0y9g8i88XfJgwe$q757ahHwG&Jc&GmkxGl<^89dU88_9LWSm5rj#{kMr_ zA%7B@kK?&WDIeK3DE-Q5&nCofauLS(@MAaPa&Q`03f&#Hi$*8fC8{7%BqNnd=%8=b zB7q~mp*GCOgPdptCy~53_j&&SHv-m&jxb+)nNz#JBICGQH75VwT8N$Jooqzimv6e| z7--U?BX{Cex;@)tYUKzj*r+?ecYEz$W~4dq`#A+qlGh^G>)@0iK~;CSA#wuoHk*=b zUp|CK10aqJ*Nt-)VS|;4!eO}`tLwNlJ!=r;UHsy%IQiLW@&sG@lYC?!b9!V*;(w+= zKTk|S_ggr1?g`e$brKom8PbbOarQ#Pj1umcP2tfwa&QzQ?TKzf_KNB^(jVVt?T(eac%+(8yaz0=%}3#P2ib ziFj70t*?AWk)p*dyq7abQ-pAS)DKl)qgmy^eW<-U+rt^SGa1Pl*lT$>YvYI3aU&1F zP-7fzY4H8eUQ!H{APQeuCIS}4{V_xoKR`(y;hKo(M+d<@}^Q6UW$43Ts{r9MArj5|qU zU686sr*iEM+B{{qvMr^BH85QgXu+lLKGOnH$fJ!62S_v{M$t<3i4CO5PsZFRkn;vQ z61it@iOLV&f*ew7u9|%29tBV+h(fgwSUq)-`WErT>iy(>Hel7`FcCHxaB=nq)Q6Gp z_V!W)-oCGJ^PWwg`wL^Lo@fkIwS-@<%j2feItfv~-$h8{`h7B>$Nc0>P85tk#yfriC}mU>Jlk}9rKef3BIG`9Os)f=iYM5wkZ;8j8RkMY zQ5E@2NJzQO<(uq##qlh{F)k4!6N-@Mm`;ZkU-`Ggg1#k&h6Wt0F~iMiI0J_-G;pt# z$0=~cM!12iL@EqwykLSdHrv`IBYlAX{X0~}I*5&;<53_{3Eigz(DnObGLyieWga(0 z#LEfpDIP8|$?E`NL#ngQp5+nMB^%(Rw1SE?;-rKptKxU6(}3yKiD35(XrU)V42{Tq z4O>w)wF0!L>Wap^fJGGYI`p($aVre&rlZA}VPPV&8sPI+*%iMB(ErO}0vLE7A$H7A z%F|(>Yo6zxF^8W2g-nX+iCzP9)fnXK$c@x|0UH^4+h#bAj!nZ1Em+HZ^+`Uc&i%n2 zuNJ(Q2E17!^>ct3Y4T_S=cQEU8l1o4eg)3pam(BGhZjJ(NQB;GCp@hUrhZuEs=)(V zt@maoz|mDgqjP@X2-E~?F?46zn!;xI>wSO!uc9E!4sERcA6M@kPv!gnf!~Kh%3g(R z85NpF%Aq5nvePiyDaoD@LK$U6Nq8ncGosAwaenu?UYGCV_xs)d zru&?8kL!B9p6k^HW#UZjH|RC^Fo5^qIs-@R)q{X#T>^Xaw$u$wlZsqSqxfgVa=_>p z1!k>t3(PdF>0U`X)TLEZ+CA6~P(G%xhIx=nq6y?>(9WZyyr%+sQ<@@A>MBw6n(h2I z>CcS7SeVoNE>B*^Lv_qB;((dm3{4Q>8q)!LtMM6~1kH}ZSy*)TK5Wft2c6)&&INA? z)8jJ>JaeLdjZQ{zC~XVLwY;%z=Skx)Qzz04{X<8epB8)lB;wDz1JyML{I^mT z7i87Uf~<-6oi?m97o;~t(TCTKqsTlBQ-`mD^E(nMan}x*mEvZb`}Z?ES%B+d* zQ$>rg{I_D&!I|E%hdE=85GJ(P$h#J^Z0;LYwcH+0`ovMxuk^;A<=H!qhQ(ZO z?}igKx}=?vuMsxjD`Vj&k+y`>wiQAOBLgLwp>7Qs5iZB2oibD|%5KCG-1m2k7s$BU zZChHzK%iZG8WenchhiMFt9 zW0MHd?i%VP$;EU$7CU!pi9_ApuRfnFn!W^9=(xViZ%9trZ>fFjszMqh{`t>p4CeNJ zi0My082i2vlw+MbJGq4pZMgAh*VH7|w2TI3gDgC;4=~B5qOR(X zWW`E;sn}KfXkAEFeQm~6IAzseAT#3^h9Ik*OWLj1@ML-m*S1hZ!{1^aEHFZU)l&KWU{1 zrL*LfnS@fFXFU5Hgv_jI`ccVKmmb0|;7lMCV2`P4?z>xGd~$EnKS4BIxyp&o2$OV= z;S3ybvTvreBJZg~9VNqy8D}k`!n+=M!n-qLIy+l_`rkW&KG)Q5$N)XVF^UL%w7d8^ zUbp@Pg29$+c4>Cq^WpYWfjY*_nLM3Qoz#fjx~WOF>$0vVOQl6Y=@^lXB=(*i^N&9- z9dR@Xg>ENj&P4m=liV$T!kl(hJo2ejkE4v!uPGD0ohQwqkN7WV)zyq8GX2p4SB5jT zg4eTYR=g$1B}scIrshXh7N=c}b&Kar(UT_yud`|&^vEr00X}dBmU343a^^&d$#?`E z>-w38tYYP%wxNvycbpa-{Loqp$fMFU^ZZVgWhQis2~8mYP*VQz4-RvE1`_M8|8}m< zgp>ahCGYRquVrITY)i^!5b3mB#4d4KCZITIbVvW3?-biR2r+SwewO?BQM=exoYXQ= zTYLMF;>Ug-!`DTwA$DI?T*w78{Vl>|Y(kf-s$T`kqna5A*6pWm-YxQg{;XWZb8f+> zVP&rxP}z$jmjN+iJ+&EBgZ>JemKc0B>}heyqYd*^N>fltQP zA$C8q>=^x#RUN1@vol)T^cR{bo0&MZNpaT??ix@px$K~m7?a`}eS^OH#nqS8x0!pe z)~NHh1U18JQZ611$~&=MSyJ#9bPP6zIL3hD$BBE;%ir!4^MLU8y9$nA*{PgT(hkflXI>nXqQS#UBBhxc;Ew0ITK9r{RQMj;CBKNN2zdI0MLozHKu8Hd zGg2DsZes>WOGpD_4&s3$FBD@dN$;Hp<;CJe)neKE=f4^yGvBX@0u-H)pYqpRMsU5#{jVT^wd-CKZ| zFMcRdl?FY1f0*lUKv+<@Z#Ww%1`m~cs@i+G_yy<;9@P$nckPKJ?>>=ED{wr_uOD+) zL|D@R3F)gBe1(1rl*Qg&U6;-pv}X?hIn{0Ho9xkXSGpC7@a2rxz&6K0)~@b|?LhqS z#XhK`UJmcj{qKmmIFWEOn|Y|j1v8H~`L@H_O408d6YsB0g}?OFd*l}Pt=X^JZwLU$ z@H}QD^Q_mWiw2?GgeeV(hqir}yV45ZSl_T2=+~QLiwNvF=?)dDX#X-23JOZVR@l1< z!o7CZ|2C?6zS$|-A|O+;XBg6t?M+R>Np$kpIWWZPZ%=q3E%JW5Oi_Sxx-Prv!Rq)8 zD;Dk`7vAeSA~->0Sntbp*REw;T0!6S)zU?QvsQa&_mxX2tvRL2AO)F5B^E(!KN|U5 zm>Q{|8*_5=A3%R-SoH-pn@Sui`fKv}wAB9r!Mv_Ub~B0A-oKhpDTa*V&~OV2AExoi z58E~bFfvVp!k$=EpCkBYG3(d(1^jRRTgd0ruH8^D#Fa%52}0_>kVboAQF$i1Yrnnh zUr1`P+ihd9vQ-7dEq0aDm&k{L`T=kkCFf(wot>fDEds%Y!KQSvot6~Ea$wi=8$qd3 zHRyXCnVo-4me`}tbS)hMPrhv*f+&Wa3FtCKkL~1dHQ5f-)3}%$^yqXl%7}zL&HJHdbxbe;wiHSVjeO%jL*Wrk6O2`y;D+eHJIJ~4LZZ3UAL%X_POPFl^)XunhX zo2zmDrjL3yq*YzQ(G3ou!+bL>a~=fpQ(mJY>Q}QaJMY%GCqamMnEIi65=}$N(Vdm~ zrM*{=6g@J45>;Vt0kp<^?{L^(C|ll(;Q@D%95glMXK}WK;#K=f5+sz9aa{5JkwB1D+0SM9immgSbJ3V({ za2bDF^b5d+6tp0NIBLOnYRdSKIyd>=C$K%c5CEu+oX$S;tm<;}16iDgTrpE&MLD$} zZ=V^?KA4<$E^6S4*r9CL6^3MhY>g1)S5RSeJN#!suc0-+_Q;*=7OokW!t54wL!7U+;cTTFAOiA=+b-Knyk$O9AQ ze0n}4USH4N+0wVo+pe+>2zky&juhUzA=QUTaU zw!h`i8iGx1kOnPj;V>gobbuQmU$?KUgp?k8*iG2^jfciHJ8$Gkt9}BWP@Xm%c>{3@ zSH?IA@`qiDFer#TU)3EZI|ZQ-Mk8r40%YO{x%}P&q$nxW$;8**UEk!=^~oK5ofzyl z92vM;I6&@JYAbhM83L=?SZG3G^*d&CYt`Tu@h86&qABKY^L$b zTOY`nZDTAfD{PkH>1ka=)g=o*HFlS(1r52 z7vRQ~jZnw}!nB-C-@@hXlXDsyxR}3RithZ{qazK1HWP*dMkXE;U>-fbQI~>?z`0+lE>*&erB5iv8F?g zQy4I9ahYIPb#@-=Btey$tYShu*wh{*1P;!N%Fdz zd!yN*fr{?c8&FX@yC^h`WcWK&QOMRru@R7KbH8V`T-(&kV6MPXhw z!AOPEiC#P3a;d2gBOx_64VIkiYI3n4H~Xb0lD4Vrc+-7(6k)*ID@5LfE9Q83k88pu>I%QcZNLLG9G=+W& z5m`Dn>DaLEw?#18?Qim8ZZ6YjY6nDmbi7@+u44tm&cfTh>$&?$vH!6Xm1_q*bE^1e zU_}q&yfWm7MMxzBNe{OEnk#fi=_cVgZaBq&NM}A;7jVGu-J=bgEBE@YZQT@yHhJ1V zAg4QvSnA~DKfgHmhi&!ojN!obOzN{dtS!6kOG5U)_=`J6{IL1e)sEs254ye=f};OG z^F;d6X+G9@^j$gec_*#B<9Dbx3pl@HA(D@S@lr|m$eX0N_+7#TjixjI?|&vb^Oke| zOM#qum6NR3RHGW5GacYw@p-#Qr%qJY)eFGBvVgpnuVyW=*EBb^L`1dZ9mltCl>w1R z0p~Byfw$<`66wxwKd~4WXx$~a$ch6Ldi0{*zH~@e#_nJ0W*{m9ek7_qlJ0GjgkT5q zS>3!WaLBl)>G88kmVD=^>Rs0&X9SruXtaIQuo?OqD=PyWpS%76yvV_5V~$gB`p%2} z;9)vEwaL9>>(Rgqs}c1Cf7WuYt)*$@t==F!VEo;Yx&PY#yw|P+=8^%|O$jar*oUzABT4o3&LSfw=D~;KSgK@RW!t2+YDTS(p6)ka& zJ$uZ&A*pA@F^JUHC?hw_Rx&+{!*+j1Waivf=c`{z8AlJ?%=|a1{QIyEVBTTh0<^!7 zwx;xbIKmkxh8@(okf_XmfhFU@C3YU#{XY+uI)-#XRYlXcZEIxyNB^ zb2clJoK5#H7)KN=nm-}9FCZnI)HIo-@SKD!SKb>INzvhCA6DpYm}a~AK`@cDflgw6nk;aDGa|$tQ9ePjK z96MZ?oB407LYK4;jbBfcS9Wp|YKmQ3pevGp;zKj{rDxlh3^Yd>eLGDjNxN9dePLU@ zo@D-#`0bpp-efvI6H)y>MqmDP)=o6qM$!1cUn(B0r^F-AOu3kSIN0VJPuaH_DaVzf zHmX}&zIzv0&Ar<4e%M?vm9k>Rg0I138YA3jpTvRZojR}2PMu!AzLBKX$fHVxN4hj% zt@5T#`rVJM>GAo5rW?(&wJ=0$XHYinY$I=C(SHTNg;@T{C?4K#x$lm$GCLQ4;{N?~b88XLCFsAH@@tzjhVN#k zY}jde`HC#HS@HXKy4%D#Gfj`o%wJDCsuSKMEk%EszIlE;Df8Da)#LBNjqEI<3EN7` zOey8&Y@x(``{?{)<>;@7%r*O1l9H8`LoU&}v#c0%+gbjZm&V+*8MhuKKgaTl0LWYK^5gBRguIkj-7G|qf`cS2;Cgj68a*3SeX21uo%-2__B+J zqC+3h@H=o2;%!K+KJ)aE_n2cX(u4XC+wiP3bR!yOX{^|Wn1yY0Ac_(c5tkj-2MGYw z?ZR9N_l6nujRwpvYzi_6s&VcbnAPyuZRzz_S=pE2GJYH)Gd5$S z4RaVY2sq!coJc1qo3!olegjSjexJg2u z(;n*1k=1!l`X^64h-B+4Qr6NsWcmGj)>)|%)a(iK?uFbMy@oC5OvKay8vs=1(8nJv}o{&poDZ^=K6S;EDs(Y_iIL0FG3`FN{qDi@w+8Svm(bh>+@WfK zsF+5#S9?(AFZuS3Jar#$2qmhY53knpOnAyUhvwRaoj6Yr$ufw%y3z;KyohKn$`{f8 zzYYZj1cp|j_`;jJ5v9O0POh3nR>+VyP><|%2<$%@kpJ2%qWWmX3Bh#ttzN0scBLh` z{*6#C+$R0HOaY?Ed2I^O_!;_Kedqxd7|m%n)TQSvTi7A7nj*8QRM}(WsY_C?lD$nu9Yw` zY=7C^sZJ+|{^k%=U(kf;Sb?2b?*4t~K|0kkT2x*+-&sUV z*V{`tQD@=6A?N2uQH+jUBuX#cN!|(l_ZGQmyi|x)Z@_7^mhnNDJ?Cq);e?5XcNTwR zm^0U^_~?L#^Yx06ADGFFpw4Y{kWV*UR6lfx?$$|LNRxa!D?q#7*_?71DYce4t^+>G zm4!m>psatk-U#8kyzwE!jptHxZGp|@2Z5O{4Jjk`ja~?Z&~-iPM~lacaj>kTXmW9Y z`Fz)#W~Wpw{GJLd4q95QLy-Nku(P!pmH}Nnmzb{@AVb`<(=aXy>&k{W^i1z4u_u3B zaytr{N|ACyiLL9OdcTQUUR+$t*5^48S^Y6d|73S{q~BWqkm_$=0VZ{&6J_~egN5Vvc$4U7Twi1{D zAv20(he{W}G+_hcVnU>rOU7TKW3pnl0$0~axBg~rCHeKK+ebd>+x=&!MW>gr^+kz9 zRj=A4I4`^vP1HF>XP&zA)+9mD$_39tygYW3*mwm$^C_#*n0*L)pxWqbc-WUwd=TC* z5q-%N3LBmKCFN5=MBWe(%=zDa{6884a)mu6@J&*Kj9Ud6-Et`G3pF}9D^EIu> z=ajk{tx;b&HVq37{QloF%1mVxy`kRBOck561)zuMppgVMcTeezVySx;hXenz>a_7=2gv~Xq#UU~=jWK@X(kxr@R;xy1dno&9 z%n@k+d%(4C39}@RUHG@a4p7rDiby@J%-R>oVliD5k`A|zcEM*2AL^SEsBTU(0 zJWY7#b?(5=opyOo=yo}P8taoU6H98OKm0X6Nci`+4c30vF)j}lW^s>YOH=T_D72Md zWkDnLP#S6+LTAXz!&D*V_U`(U*8cuJ#r~yuY~3n$aYC-EMG(kMr8vYg4dz=k-REkd zWGri3KJc|;>HhB$vmaHMvN_vA<={-ms;80H`W+s}X{2fbr@s;uEijwona+SFC6~9RMOT zYBBls9X8r!IU&S8dl%&ueFra*nFgzYnPSvyRjr`S8rx=ppD@@A)zV!%^8anVMQ2M9 zN|oa#VPklho~gOj%-*Xg{U3U}`QvZ94)U;~Lr(p=aBZCigc5|qSQ}GS@+8Urf%47; z`mDr#?9AhbvC>E0rd&_NPReg6^s1WS3BU@g4DgRQz4-IvKnXJ*)Xc5P0@+}gE!pmn znmCfS{N9n_jNHnnuJ$bLK~g2*#a!)9zq9fk^Cd8$J;FI~2({I^38*K1vhZF3t=qR9 z0LPGXLnW}_sWr@VCkU>&!y44kzNH7^hx-}6i^V4@F=#kPH}{|Y!cvz-EdZ_kFej`ttK;SjGt zf?=gP8UEtOLl>#q*?Xr^8gBb6`AiY=SCj?`(-TEpO^}JO3q@Od4{`)=eP$(`HuKRU z^#1BcmbaJxZO%9cYDDsP__9$^I;b`tY9}im==sKYBVZ=#9SluP;P)OIG{OK2ey{=U zqQO(M!3;DFp#vo9KuA&9gO2S+njF3_?UC#@+AJSrAA&NuoDs#|GpE7r(a04zh|Gcx zpSL?>Q;2loomU=p!@ay|BX4xZ_OPf#orO6fB3c^cd8zY9BexN|uRT2FzTeT1Vhq)M zNA1JxV9i-H6!N!1(?JUrXS@vc1e`zfuqH|;b=y|*e-mV*R;HecG~({RSzY!5Uf*+9 z;wvQFhx#e5@b&;TMmj0XWZo3Q|4K%j`x#d5y~oi-4jp5oc#qUzc_4*ZMg|e9iS})0 zA#01F^g&9vnE&}>#+sXe%UQc3*8)r3xv5n3sez4aw5av|kIboY8i?9kc96Ym4 zLt_y`c2WzBw#`LhpA^YO8O;oblp1#fM`{-DlP3Ue1y`|;)?&;;Bu z4aRIx;!pvz$_zu$1I%KXg%on|w+F%9*vwZA3y}3_+eqFC*l3^5G_uEJ_#v4ZZy{pq zaWvwiwvjfRO8~f|@|N>dR9ZzqX!I&NRaO$Oib-jw9$6XesKM z^yG?_)L$q_N_H;LPzcT1<;7{QGz23_<5&p|RZp~rgIA?`2%%sc5)L&0Qp8bz+AAnix~(0m*>tp-Ttyi z{N~u!5b_TRjyekUI5>+=(SU4l=?H$6G5?T~aTfuL1|VkNDy_!s!YbbgdK0Fr01?ru z2Tg!pBP?G=5*vCM24&n0iqKt!!=A3R=OlZq!oIBsAq8{!2VK~t_R=Bs%y{0LWEPpP zn{rfh1~&YLnVd8@!ma=2U>^X=-gHnwq-KJJhdNJGq43i^H>n=j5XSIs34W(3y#v|4 zPA?`3ET*%bDjFs`B<3!LJ+v z0OWn>qe6lq95lA)D$p3F1<~Coz}{$K7BaZ?s>0yu;pV-CK+ebewqHeEQ5+2g0d!sN z)G{x;SP0zZTi<2yU3!paNgs=4r#Lj(_mexr6Q9u4?QO%pvcHRtq3oMOG-!5cfS(A| z175y%&(o!!{{b(-yBEBq*axr2Zemz#vSSE{VAaK_8^K+niJr=n5SzCL_WX7J&zLf= zmoLN8DxWpSmn6k6*z;e!SYuoMY&m*SsF26^C_YyI@OLqr5wWc!FMC%WwKkF8%cA)A zT8R(wMtugqa-di}FqWk>RWLSjp-A{pYxAm9!?&vmxEovWEETzROXK&Wx|+Kl$;Q(H z`9V;>Ovn90a|h7w`=)ldybngL245URGSt1n1oTC*BgUMcme1N5%`nPYykWdiN4vM?$w(z&^lEa?itj*b)bx)OF4MoFS@g$OCCfOB#a6J1uV`$qm zU6@Py*|n7=sGn-DLny9pozzAwaIynD;Ue+#f{8w5DkWZbSluNGVP*dtfy-vTwGxjy zC*Q=VI`wbd8N_-dyO~MbGvJG|%1DxDioCKji~jKOj!Rm8KTC;1xd z4(QmVb9&7E*Mwz^nay1|{Iwya-0l3Z=hcTT?(BMJ*n93bQOd?~oLg7XQle?(<%ivS zg%U@N)38yOmpQ`4&yU_oNuPq1GlB(GwaX=siby`{Bx3WsZlO|QEKDg`e;kk@0f<57 z3quGlr}`i5`1`*#+PlThfJhtlmZDpXzD^co;&Cj%`)xj|tfFv*UuPk#Sf}-r6Vwvr zjh<7JLAU;!D+Q)BGbvtWd)$`6DMvD?oorIWp-2^%f&2k+RU$SO$zg3ryzepBK2ce~ zf*0is)krYG%c6_)(<0LCxML9vtf-b95ic`9ULgP1`z@MKW!A@G;i!282Wp&!`cp`< z5AcQoJmevgw_uY*aPOlxD_33VY*7@g##5-(7;_E}P^X6n&UXjjQ7j zkCjzpKiEkLhe#^c;KHn~`x`)pkQuu^Ex%A8Ekf3@#q0ts<;Q-Ql46H-gUl_;9Qy~t z_oJ=htaLi-_*-LPJe=(4Z*GOhu*PhQxQgUBrSlhBqX&WS7QUh3%5P~WlYr*qjsM-F zoEllHX|3VSiK+ndyJ?U^M96~%ziacCn~qwolRHpLnTSUR&um?G=I94q-)e20v<&%u zDN7RFp9~MU4z3_fb#DG*Zi~Z0y~@mB3{s&Q4vERUHyuUKxL*n%I$RrEIAt!%U8VVY zyN=!W`3}uk9o%O5p->Iy>A&RMB<6Zg5JsOd-UoTs)C43MP+YPr{h-mSy(vEJpMw35 z&VDog;aVm;1rVxEvD(^t7qNpho`b zDdwR#=n1WSsCf%)uQH!**8L0UE)0p-wj1Sle&FA8ke&I`lGl-nri7f1$=Pc2oqC%! zIsVl9{kO%op;v~EW=goo0HWC)Pzt&=8cZ)p9%caeOvCvnGtcIG$EGk`hv$m8+7flN zDzcg*b*Is+*Xh}Oy)O%rC2r!Cn+9EBwd75aHB!tYsE?egL+;~J8^PzkFl6=DzkTvG zQ61Dnw$NEZYsTmU3_2IU-DF-zPZA$yQ)!W<(x+3L55ZhY$Q>AMON&*?BB&5cIh(@KD^!Q@vplm?ws^4xOi%}lFq)L z28|Hv;rV%+y@r7&|~!GdAI_|MT*`pO{qYpDcs~qnRiiEBMZp z4L@p^aHE5iKW>dfW8+}a)Tn_;Wwgb(ifSj-@5L1oWxGGLt9e@4WkV0G6Wc=^ zkyAdOJyWfR1?}npOOSH?E;1glO2qkgg@w@cyME}=Ea&HwlaQm_oDMYT%}hW|6ku50 zc<6j2*o+&!$;2OS2zyy+hRV(4{^GzA3Bif&n(!J%;BA2p4le6}n6>t*ki}&Bt@&Xt zOt7*KP4k_l8fqxXBo%F!c5dDZx!Ziu?&=ooLs!R?6^O|4YbL0N)i8tD;d*#opZJc) zLm$XHfe@-f9**fO*TdY7bSWoHKe0#nA?J%8I^(tS9% z4h5Q?@!*YrTWQgN#kblhx>q0BTzd+kXGn3oT?I@4nOJ6cC3eff=fK)*Ix3fw!}kVM zVX?UNk?sd^S_HPsHa>h+0Ix|nQdiBXoy=G3l>M~$W;qw-cBW9k_q4ViOVGLwHW0-i zW8~GMQm9KyhUhX|tSqaYUw#49U+)(pog*UIiRmt-VA$Oi>tQ|0Ecr27rZWH z$n(+A_Y+o=U@PGTDeJ+?vOz;=!Ml+NtCV{4{1W?b50pQfMCp2lcSqmQh{jG`+#21f1z^5i$U}- zuPSurx`@Oo9G+FWT}8@Xyw3@S$LT34sWl=ys`N(G)-6oTzWGstg?%*OY}&H#UhZ7l zqfb)R43E?e!DZsqaVGL`|GlBJ7wQ(z(?J@oTfnzOk=w3ZO3AcC?65?Ax16`>iy1DI zJ0Zu3$`iBsjPPXPDtDsBajxm))4(%L4_`QTPLIUr78>^xk02N)OkNs#imy|bj{_E` zFoS2ETzyOZ-LCYd=-nOHhF3TquR!|CzoEb693rwFQTlYEzA+<$XuF5rTa(S;-sLoQ z!aF$~QpXSV5z~+dYtq3e{54k4kEAQ4s`LSL1T#+Zbg2R`yKMYI6tX zL2?U?Q9cvXV9`r-fCqL zqbC`avfUJP&~X3Q&qYLLuONLLMv=|cnh2{F@PvpTl80YVO*PyI$Tx@MH>TupxLtR; zbOE?A!_64EgZX&80DfG|61yq;TRedcKzkWjA#lh67m0153svU058NkIkh@z;M{p6l zB@c{x9bX&~0P{;p%j;*P3gnOf>MGR=3s7|+W52#d4c68zHjf07P@nHA zCaSK3?VJauFtarYs zkKo7K+X$KA{J?Ry$1K@6RZb$|baLD|4w0x=l0qv(iS{%LuIMUU@q zmY4$f4;FuP->AQ}f0!L*lGq!6UE2@wBX>&(>P59n-05%rze<@#($}ZcYLfh4y?a?k zzhj8zT8&;|f^UTHFMXjT=RG+^tdK=+dmE-NUI2c@`6Ge_J&H0HaMTk3A@)a0-Ao6? zEbP|)z)_qqS?y4H@(C5qTYPPO?q80&`pZ^-n*v*3m{@Hi^RPT>G!7LF)dLqDfNFJ4 z1s$tlz^=4=cgdRHMf*kKZ)|j752atPalOJ(nw?Q*g@y0NDzG(MoX9%*Vr*WK422TLI5hovyH*pLndqj=zy z_o8JPg3RHUb^)azV_IcP&$rI1nN*0);N8|RqXvKPP2gd7!*HJMoPT3M|E87=#;ki zKXP0*ZuI>-@VR!aMA@kMEf}-9+q3`LHvfVJA14hH-P77EHEC%NA7CD`yq0Xm{tn3N zkj2lTL)8Oe|344Ec91rX+bVC=iRDVI*1!<~>UrraQ-1n^Qo>+x$w`YtKW;vH3`s?F zX38n4?h)CQJN>F+)-7p@ZP>BB_Fy;GosQqi{cOC{=a-m8JtaNEXW0?d3#=peuPG7n zoZ)b}cpo7i6Q^H~@;haV(rqX!o-M^gvWlz3*tN8~yk%MrRtIh=Z6 zD%r3&dg}(X1dUg+9;0>BDm23khuf+(MA!(BjmHer9V)(v|+!P@7C#Q&|y{4nl={dhv2~=UUNGo@YNi zgfXl}=Ko>dyKD@IjY}Cq^{tEOA;Hj@prHX6oUw=;HeQi~^}LEXjGS3uEd=L(#xfBz z$xdd%_+7oFblBrpjZ+$agT3Xs?SZ54vZ^e8u9OUhCK^NJAb%?)r)OolBANtSEl7ua zC-!maL0BVpE;5@kGLh)e+aBH(@DURJ0vg#9J}t7cypu4%m;Wd1NtvVof(h-2DkB>y zmtlw8s!eFliz$zk7_OA^PF`QKI*j~7vXS2W9ezNBA8#{IZoJT1rSG8T!PJD)jUfdf zBv?)oN6bq>-FZ~9a|qNcf5{U|7VVXsvp_;!HqwH_ygxygt5K0k+aCTH;HY) zMx+#^ZV#`pJZwsnisa4>?2KMceiib8OOM0DSI9Hgoad3^shS@SK*Nphvi#o(vOqRv z%F~JR3CouUAHvj(1yM>!jqHM-0qxoi_-xn=FLW6*ckxG)aZVsb z;KRUECXXvf<(6Y=HHf-AV-o~D3Lv~m|L%^rXAsIRfP)nmpTS`s+*9`J^0$_L|9?m9 zijA`{a04QMeVUm(hHTtSy(?7)Kt-|^f|vFR4&2X#iRk(PyWm2OzsSsi3Y<^O1ZkAsK9)0h zhAYmmT)b$eaw&pbAG#t*mlX3)W%>bZkAUbTMLOtr8)LFMUjD+Nu4oE*;9RhuQWm_D z*D`^KlEZV`xo`{WC>;FTh3`wxu5SAO3#*Z*$0pFdU+`1 z`)>PBEe!fdC$S~v?l|A_<}jqp3BYv;$g)p^Xso-jAsNs_3C8P>nk#syQONCwTtD0< zF&Tz)ydfgZBva(zf2e7e$APTj(1dJnG&UO%Y=JsC0!IHGn4m06hz2C`jsw_egxnm; zCSA=d(2Bcfx|q8*ynU6Tcuq6UCC0I5{f%Pz?!c6D)B~NNDrb@CvAyFK``one1zo$D z6X-%-9ph)hUO_8{x$N+4@T+w}{;tGEGM0!e|M~EnPQz&|JztEGkYcl$Df8gX&64F6 zT1tlrhHK&wK%?1z5`6W-C93-J60vUWA1H-B>B>9eYru#VD$X;faq>T?Y?l8}fV{=3 z!D(N0)*9F6IKu&_Lu%Mlc++J`oZ?t}+|rt}pA8$x5S?pou&GOb@@UWS%*yS#W6%n| z;qZNEg5fec;Bef=>(YIEmMv3t$^^r+<*V!WqNhmrtxmENYqxbsY5TJ9kdb@p^Mss9F+2ICDFGGu&DABU9 zF_-s5-oO&#USz%EH8(vr$Y0PBS;nJLls8^jHz{#I9?9G#s zK+dAzzp9CeK5m-ajX#iDNbGJ1xf_u+v7-3tAKhX`5}MQ?LMjkE>a6tuW~rQ*j7He5 z0!a8}K_AYSYqWC&5ZJ{fS+Bk3$D0w3{Hdy~>>fB3nK#zmKtW+!MR>v4&Mq&AnB-f^ z&OGkfkyu77DSM4{g3DWZNSip={^S>w!`tEzI$~I#c7^pFWcr0Vz`7xrYaeoM*vn44 zJo3c(?Ooo%R&w=pk;ykz;#n{U+EH3k86}Z=4C#sX#v(_!aWx*F9 zMiT1-qgBgFJ5~t+FR|4OF8*FT9qR5ycp~`ry?SfdtKlLET|lfqx8-$2&L`&d+?Q%4YuUj@syVOO&Sjjdu1$-x{Wm^4KQi;Lm3z`g<7#hF@9gwxRk`-n z6PkC1UQb?};QTw(Y!jf3pkMtJgFvX#aMb1urSHLwNQUc690_q?-Bu1Foip++CFmWR zFrp;Qi9$pM=8lOIPmdy^dfy8muofLS1uE4r$S)iZgM#cmlG+UqMU3ETt2m7%9z>leD(|-( zGm}us3i}(CE_)CKRYg@c`Y?_=qyd*>x?)g!X+d$qVj(P6b6{(l1DswcXTs&uBd$oCZ!{xagcZ;^r^{8ie3-~faqE3zExxCuH z{&vU@SWowz0Q}+3Sl8qaKypmIXEjypr*Xc=7lsYgPKF*Zcs`tm6uwhdQ&tlm5+;SE zuxo{*o~MjL2O{F&Y|TTUm4zM;#(>5Jlf?yXb;VdADN|^plJxPu_eGmVH5iNPJqWAG zXwU`fyz~DzYD)TL=MU|yq4W%yRBelMx&xmL5I?yje7-3Ub}^N zgvJH-5+VpGJ@^w4+xuwYknLV|C_6hAHm15|0b%wJG^1x3z9YLe*@pqy5PGRecu+{K zFxd(JV!pU~(#2z)qCCUa8*lAdbKS7l-{)5ftJWn=@_{D5U(lD%M`h*}KVsh4HzAtD zxQ}&ajL##xgqwK9YSBVA)YJjjEzYgG`au95+v@A(HGag&3LWxy#yXr7?{D2icI`|# z5tZd4!W0>I6j9p{rwF*8jr+Qne3n)PeXH%SK%?~YuZa12?)O&Tp~x7XVW*NzB{^wC z50dI=usW!lp};?WGZdzDz2B*-@#keDWt=YQs^i$|wbvTiA?0`>mcV$J`~k{;ft&RS zBXum)LvC3FHst)((MfF>LO(}- zo?UIOY#C)W)f@lsJ4kQM8V4KEjLtL1H#S0c%4(Q|gIeiK?Lzw^MT{dsej!JS^!$+; zo;P9nCo84(S@Fxsy@g-XvOC6lWvabKg~ z&3;Tm?Lg#uk9C93vUXJ`4zcPS==i=I2PS{yv0*Mrhi>*iy|SHICFfOJ zqhlvu_a3{5S01T@ML(^O+(on=vP?`GK~2&z)AtH601NRCJ?xs*!3TXqQ&=xJK5ias z>yUB5fy z;XKEVV54iqd88}YJ3i@rrRM&5wO&5gi@g6quawE~2E*c!=YcMd`zhrh<}ug|L{(P_ zMGEP;sEcQt1v!mcz{?`+{JlOWXOFkgt+W7)<$@s4Us9&%H-Iu!aMVGPvOZFA` z>mm>~Dw-Tf^+Nsvg&CO8cwC0L+JDd*ngaGIA{w2^jE=2ns5;#Em(jiew>PRe@tL~L zN?_^T-`>douU{F{j4RVIa%ZKz?>IW>Kp}*{B+{kN);in)8*rSWEc0O1wfWz$c_^;o z03l#$UP^3k9<$O|x>S#BW4*peeurxu(dyfK$Gg>+T||QTt^$lbpj)At(4wat%Npex z@|EhkVPLAc8^*Kp;VKWmjO!(9VQR-tL8PEk5@zj;dvPP$xOd_G*xZc!h%5y3j!-@V zz3_NpsC%|dH$}2#I3)Q?Ctn_TJi_rr(>DPjrI=?-p0utN%h&*|(rMYR(&S#yB(> z0ZWE!mJQpad_Wn}F?}#@aI&(~P||<+4ZEa2RW9jcw_D+XrMHw!Y@Hp6PWENkWnKTn z8I3gT+VT4pFk|+AVpfOEK6NXzzF3wyS5h%#ZS(gBN)8Xk2>^=VzUupe>H`^^knRU6 zfwvd4=Vqrp@BiM!su4aGVn#+zpaYEQ9CTQ_xaUR4?VT*msZKbs6ig`R#)vP6w2xI% z_BOHa?dExRGb_v1a_MMv$usfL5*U3I=>TYS#d!0UmY4#`KY-;r1*VyYO&0c)Jt><1 z0<&axzkmsPXKTj4VV70O+~`Nu(z)E}c-ih-d-_Xi67AdOUXI4ESs)EJHb8>b1yZQ) ztXkEbM9@1Zw%35|Tpp$cm@`Tw&n@pu&#xvFNd9r z$G;q=0o5)x7?a&GDKf|oQwp5k{xqY`u*m@tY?Y#y>p(Y1Jl_EW?l2)IeL_ZLkdUP51+SMx~@C!dN${G zj(@gd;ops?S-02bI4BjYove7rJa)Nqt|#ISc*G_h8E$lIz4*5b1=I6N(ncH4oll&V z&)4?cF3mi2#dVuKiUiw#dbb5k{`8JO%EpDRc3qN< zC)ZgIO^C90{d*E&13?GERyH->m32MRuJl2imq?$-^J$)w9&`#*p7X`5HNWUSU61H* z-;xUsBsQ`jCTTeGbek(IBv5+De8fH!XJP2NSBq+piE3^IK#ZibP^(el$*i}SKUwEt zHfSk6bb6g5?iiA-Nw*svc*)dEwAk{K3m~eJsaLQ(x$}^_!)nj`harsU(++zegpfuS z>~~GuUy*-GeP5Bam#8~{rxlqYV5o2+mEC&nd1qb;+-U%g3rEIPKMszn0&-aC?? z&^B^{2D^>(SQnlXxNVSfIj>z_7{qTr#mu6FY$$f~iUflIk~hlJaP<)Dr#Idp$oVqY z#f@}@d@-}obnR!n3C-L4JP_wN;8Eao?Cq!+5W$yA?+qRYUwhv^@h2b_EAjx7&6`L| zLgJ}nA3G?AQapxaYyW%&DtJVTbbSX+RFDzira!Qp2So=Y&@55($zBiOKm?#dj<86A z$fL^kp9l=ixX|nbo90i=#gKw2$NykoB+r%`9P8z zv1JK4--3DFnJd9dkb(1Whsxq}X)Ps`b%n{Y{b3I^96ug9;Tcr|65jrOYSuV{loym* zeD_fb&2H69T+s&KIh@E~{lesoWETau(A7jhPY}+AD!(JH%1kzWw`6JuEA=r{$$Z@? zoRr)LeX3u%wGRUGZ^wmjS2{U0cOxB%z0?Gmvk;;aE?7~iBN(R&+@%`v{<=vWfD)z;{R~<|}6sn7c z73{(>oHW+6!3F+K>z2ewfN7qj=-KI(EO>K@qmeL>3`H8 z_4o`r{fwQAdsfQHndj4ckGcNe2T14+0Z*J9SbCq&&GvR@%^F0g(Eg=iZL9Z;?gdBH z;fYWHg%p`rBuJ%ft0R$~hfTWUlZ71nAqoU?Gq}yrZxXIYRKw;#^FIW^701*9l&lxN zGXMl=vh{yAB9obiC>>;8xBF&?N*Uz%M9+t%MU$-;hKeU8%)omvn3C_NW;937*K=Rvt3ihos4}PN$HcN+?#4ePZ28tW^a>u3@{0-Sr)~ z+r>M?_dq+S*=cwvt4D}t7rPn8M{zh8j9}*I!MBE=7Ye@l^codACatT#AqRpfBQ3hN zaH$@>2@LexuAU&3@w4+Ss&F6uWT2KUI!~_Q>GNupq~|#r0HlIbv$)Rkd?@ONa1J4? z37;A&+Ug60qdcUd-F|!Q*lH(m2uML%)D_cfsgl}gY;ibWCo7q)f;NfRB9Ob@z=c^K zG(3$z&koyo{DGuT!5`6_sjvKO4;wQ(&5f=PnE#h*Fp#S>_?686_($YQ!hgVgn#&zTqTqt6;2&_nbxidDoe zRHH5F9T!_r-gRa{o8kZ&>%38ql)99D+>Bh&-`@WZ!ZP{{$j_@A*UbC)ZV4vAkxsbU zP&!u{S6m8!53r6hK{W~`?4+-jEWwWShm!GXVALZ;wK1pBOoNe zZZnB{3cX5`^hJP2UcSO7~K0*0ZnO z<9UT~c~;-JvaLYJmC^MK08%Fz7zioDEE*JDY{|QjA%`~n7XysJv6wZCr=QGwXMoe+ z+2TX+jwH81AD_rf1|ze<=KnS(ge1DDb>)G3f*PA-)PCMc%9^|7Y2}Y6t~%Y{l~Gap zu7J71o4a5p2!x`>w)4$Gk-e1dnuU)U9*Bxi!4vqRq6y-2h^Zd)xTMhqY22BAgOgcB z^R>fLS;d_HJBgkty%$*T29uBYadHF=;gz^|?!4&v0;hiP+Hg1Y-{z> zv->_@Kbza20zfp!0_V_>?#|`fU&%`o%ip^1ZjA~;k7~NSN{ORe+0;{F#yW=b+ZuPF(4kohXnfDcy1K50k zm2V@n5VBq1e3f-8`>9rMe@HBr-iU6R^Yo<4%W(iZE@z^d=7-h|K2S+Dd&6^SD)=gB z!UxH?u%HA8!13@l8(S`tkUBpmRTA_6^mL_BO&wu0?2wdA*#rU<1q1}N%1$jrE4YLx zNF!SS+k*j`M#>U`LTC#f6eLnnYmg=2K|u{7Ph=4a6r+_bp-9?L0pWlP1`sKWNa)MV zYv=dNcP4q6nQ!iQzk4ZE%X7dr&C$swj24F#aI8Qfr zxdX=?^ajB0xt+FHOX)*_V$F46eK`i86f+d*-%<8aS-EJpb?d^S^66i((Ov!+se@^%R;4S~qj_I0ibk)7{D(MnnBdZlpW9Yy$lG zIV&j?1W8l~e)z7Qbh?W9Cbw|Uu!1L=N~nUHe@4fS`0!EU(u~(2Jb|r2?Tt_uuo0If z7{m3gb~;kDnau4}+Qr(4$TtwB(UVp&bpwq>@ndo=t zd8%x8r_ygwsPev1`I2tt+I>-}XQlm(&X8i*fROeqq!<--=mZ;a!A%ZGc9|B}yv?Yg zj~kAoamrs~^$A822e?%(`vn&WY7WrZf#V#Vvxq}^eY-EeH8V0e@cgZX`OM!V4r$?h zYamwss4%HCy)SrhIB%4)vh-R0HAT^(3Ue>`PojiT98OC>B{@Ykw1>}ybrxG(g;7M#T!44!Lwwy(oDI&8^6HKVzFyc!`<=xq0C=W+C%9@rp_5Jpr-f+LHK1 zm&Z2&r+#AFsU-_9>Zt1)Nq;fnGvWs>>tM9SJmQ(9n0|0{b`TT{QFLO40wp7&Vvw<_ zo=z^n{oYrNNGtCirW1)dsq&8nasp?Xw{b=CYxa!6?~p#i?4Q87F!Ad&GrEFcHOpXgrA zjBMM6Y_!8WQQ~G#yU>T!uDX%wtQi9-=i{C?MA#_6!^F32(%<*GqXw1a3V1y-Wop7N z^A2nVyjwQJTSk_+xB8QI zs999AfFfnPnW8?0-WA4VmGuBC$b|`pCu(h?7|(|6r-)={V`-5Azr>weTTx~Hf*?)t zV-LGI+s!?7B;}nKd*O{4+W{NW7Bcqq*NI@RQj64JQoULLI2zR>GpXvigWKiP~hTWt{O(vu0bxKT89Wn(y zX)C(?M)EZx)@RqRXR6VB?UtE6y*a7fM*NapuWOZPQI-<;8~YLs4N2k0wjzavq*d92 z<_+!oBJWFwY!RRP)>giBc6J+w!+#W(24Y_@6`Z5doDr^tmJ|21ogIN8k!>!>(qXi3 zekYfcreE42Zf>N6SX)FWBy}fDk;yqiM>aS8bw<*Yt*P&bZ9A!)~uaUo7k}ls;ycrwQ9DiD6xqxYSpf) z8M9{X9YpxuKHum2|3A;UE+R;-JMZ;6=e*7x`4skuj+&Di0025ojR(2_0NKCzVk8HD zllG9L3w$8;yr-#82_lg4R(o`r!`` ze~54SI&@u%t1Fzp^;}A`{$_oCyuFDCJF&%UT%7fvNUhlo<6R1cB!eUy-K1XrDE0A2 zw>0*rc9{KMv~Kim_QLu}XvsP3Wo8*dnjC>}@;WY}B7FM1hl`eTYO4{pg^v@5Tamce zmt|zMAGT1GH3o9vJeNyj9+n*t$`1U?4tzOH1+-HnU;KDQbqV}|TeZNjOf0!fEU{FK ztxSxi)ZDc7u!GJy% zzx4LMi~m2b?!5ojiFkOsT1#u}Ebsi)hFo)`n0u|=55PS6eafaKLDo5B(Wo>d#h%pT z|NiKbFMbR09|i?o!KKNS5l7ECO_>S(uOR+fRHUWE-^r!KUc1taR0mSz|NEjZIvPcU zzt^hIPqVBEt-Mldsw2$w)&!k%;c9+AT;!!OYG}RR|2-%_+GydH79EE(r(Dj>2V%}n zvg9jwgq7nqT#0PeAzNFrPz7P1j{ljC{~eE_4_=(O2r}pMIn}nqJ~@tT{43>M%4+Z_ zTx<1Rh4bqFHHDHdtX!`yPFsXrG1ZkV#Fw|@g|Z*zjGeXc!U-SZ;7am8#S#C{M{xhb zXyo&kT8Fl@`J50lBdvyseE$`}Z~MaklX=_!^TxlU;(J~YHtWZNSM|o2qw4owc^*<- zy|vh;dp2;!QJs^sZe{a-7SexLo?yYIYvbfm&h#rXA}Dy;;krjYS&$>OY5efk8KKO^ zc=Z37@CDzVX`bqk9rm$!e$V(eVCv~HE`$p=L!5f})b5MnBm#q*hs?^y?j3JS50KQD zi6`S?T=wi@6I3ycDP}cS4x&bEHn*ZzN;vlJIW>r<-MKMw(D}}-PwW|Ei`qR;wf~??g~QBr93C&1Rk?a7yt#R+=}6rdQ2F9{^W%^cA=&+p7r&yqHf z-DUjog5xLn5Z2NWA>;xdq0W}MJ5CR`I9HNh$~6i-l@G7E0!$Y3IoUL?uY4Fxd+&0k zc;d=7dc_j`@H|@5O^$u6k92vSblrbBV#)pI;jm+sNdaG}ozx>!&3Jw*BbBCmR(~{m z70XJc)r_9MBhK+!5wx0LxmeD)*XsLbE|WljlF_x8hl|zI2a}Z8k&36XB&Qtjx%L9C zFL!BYV}9&mof+l0j?-DbxN(P02;V`5iHCE0K_ zge#wq$Xk3^kJ6J_TXf^I(W3d^+6hbW25mQqZI)<30STRl5*=k`Y?XQq!pHkw1WoLDBvk^>eV6R~&j&1kz=ZAc* z?4pPWntEftRZ=Yl5)c37gwUEswTiU)K>$HMq3zGQoRiG`$U*ue60m8DX$VMzD7cl!Jgf? z{sWPeJ1JbY&`7ypXws2E{uc(gU2mx$4NVhfNr$AsIFp&O9lxnhYR)1eax)qFbCEZPv{Gp8u=u*6N%uzjWDKNMf$;AJBZeAloGL3odxYM=u-@uG%G1YO9;*8IQ?mrv7(Z};hnBtDKLH5rqWTikW+54H|GCyd1_u6EEo;<76vwlI|52^fjY zYh8>NTloA`NJch7d_#H0AL2kEDVXF@h)w6lunMKxw2Ug9A!75`vRChL)ESUoJ|-A0 z$BgX6OzIF15c->g{Z8LNK|BAs_Yz| zQi-!zHpG{t?Wq&)l=xh+Nj}i8KgcyE=2XFc*JXaK4G~iwLJ&@N2g_2-rqL#7!wjQ0 z8PRTTjHX{4kGgbdRhg$kPj`5&3F8B|q4mUwwvTUG=eGA{EZ{ACjWlDFY8#2=_O`~| zsS%S+-jjVPI-Er5UH>wz^9+x`>x8W~|5X^9w3RoSE6p?3^-)j#VAn~yy~EZG8l{S& zp|#{G>*2KA=Qr8#hrd{Zty>EQ0(6r$BG^lb;{(q0EBqs;s%MX!t#9RN%W7^uytycz z+|%y96jqyHHWsI+U8~pKdcXsk`p4R-AG%5dl zy}M%o-lTPKjTxvR$N)}*>YiBR>6jYvb@DdkePeJVT^>`qG`j(8Haa@kVPSTeDK=BV z*)Xdi=~Qi7ccz4%#XXo`fPUdvFabAqwkv_7{dN9VqV&eM;DD%}h@{;vO@-TElCcfR zHy0aM>JW($lk~tkX^*@ZqbdTJcG1qiGQ*{vPLbY7zmM$gpVpd1uxr&DU=c{9udT7q zx3C|SPfNf9+L85ckOP(2`oBuOY3hK0|4Mk%X?Z*9?2q19@I2QTvsT>|cB2}7+K79f z|NR>|=stkH*R$?P%}s|WpwE#eQG7;$Oo)zA7$wv5?T1dz*>h=xIKx8hKRDo zRfFZ{w{XvQJ!~38mL!OL_YmqU+A@VmI-Dn8N5+}^)Y(k+8_yn?y{Y1?Ybq&%-#!W_ z$!kcR_M^bP;q5St*CzL3&Um8evGXOPC4C+^0kO1Hq2Mzu(7a3~F|9~1OX;PtW-yztj$?cM@d%Q>*eymP@=%tte%Y)GW z2Oz%drBv!i)r9J&;CV@QF+sCRbPF3#E&6ETIkl?f>nFi>uYbHY9*GIseEvZnTuX~1 zql*h3hivg#XPA)sGFiG`=fllE4z(<=^=K=F)#9comp;D_YDu?sK6dYG+GH8^E{v}m zC;Pd9;Mn>W0`6WGYDje41xTV}FJPr~TY#j7gXYHxp)dcrR(TdkW_lKZ+j19x-2M*> z1LMxO)B1RHW;d&L4#T4AhB{oxu)IcYm?)*^;BI&1F22U^OWH@gd(kV(R z8;`dp9OB0Md&j)*KIs0+G1uL1)f2PD@Fc2q%6v3~dZF>+qAc5X??_*OL{jMjG?MZl zWd7U%(&%PQ;&7U8Zv=Z^fEDh30VcTJ1>S^8Crm#heLlEl0X?!H!(U9SPlPHW>A)h= zpk!F`VUQn3HuzcegzKA`G$`c@JRZ{h3faP!692N7dDm~;X8o#dQorD87_Q*?Le90} zVJz1Sq^fOb&FI>JehaLB8t}_pZnSW|li4v424LN}1u2&x&H@SG6iby#+`Pcg;{8st(hcSz zS2KDi@+0JGRx02cL8C~5v<}&NX#{Q(Ib;Kp`~X}d7G`bUPx0-2_FWU4)p5#UVg*@< z%h?pru_l6ewV=*~3-zCmT5AT9c1a%I^LA=5_MZWRQZTdM5@t1Sb3e!`qX+t~{*2e= zoH(q8Mb=gyAQa1RfU-QPF#U!^OAFU~YrYz%w=$(BeWP;A*8 zOg!;MnPL!Ab>4+#+T0|LImD#LhWLl#kJJ=_O)Gbg}S^KpAm z4zkXrtIt<>y{T53kJHBD$My_i(M#Z24-a0|w;q?tv$4)2d)2E8W0%jEtwT`o$#ok{ zX|w}fpUzqsg15tYPx+uHk(XBQrfYz!=KWW@HZlSl^NZ|G>c@~}kHp6y1C?1tvQq;) zHGCf*13f*LZyAW=52}=cOTr01K@{jo)x;Dz<3! zKUg(TNNVtFQVgB!2hkV+?17MIrY*&QXoxO0h$o%hOMKkLkNxv;Ah`$9+j|svtc=A1 z;FI0_pSNa$@Uz%?$aAxgUq3LR9=9(?J@97=i|@+4fqKNl!OfzMs;cr(V1bT}F}Ay1 z2C!>%5es{BAn%@=^^9tSr(eZv!PJvj{Zxu_(}KuPo2$y!M>eQDzbTsFr7rouud zS$ItnR299O;zVnt;c|A<{$gF}=4P{TdPV+%PX&n@c|-q>{q~D0bet87DIvkc(K6z^ z>Imfu|7tvNGL|xYpPBS7<(sl%11@~g%`vBDV-eOTyCVks(5?-Tg z={of|mlVRsc|cI0pY2o?PlRPa-D)LqbwlkN;>i`psM=Z+7jM?tPztMC&puj~zs&SO zcH3kz%o6c?$8MM5cAbmwIw6w?Qjfcgq|Lmc#8rb@R?@rM$A2U)zg5ow0&;Z=#v~rb zXi5kHpnesED$_Br*8}y>h_|@L0>)W0Yq7i%Pm}pIMc5$V23aNIHx4cQ{@rlS3e>%x zeSWqDdLn0$S6<&W(;LWCAJu5i3RQ@4ALPlhkld0T^#=8D#5Jt2+U7-BXTavfshq6j z#6i8cEhKS`ZjO{ES->aRaHqoO+fW@uBGJ{BX(1KATCys<9q2TPEY4JkcI|$^QPUZ zirVea+0wG$>#3B0UBUArLj@T5p_0!7cQ;1t;;t_gQhRf99YmrikO#|9JQ%a?HeN`J z_~;#QyqIhmd~D-%a}DGXJ|r^842B#}$Qa!uI@V_E+xe8xz4cA%t+tedd6q(i_aWYd z?*8oU+mbTwKBMBUfNpS%Z~oT$dsjsk%9E*?cEbXAs^7itZ+?vyt}@^0%+OHJ>v1#G zy_ZwCaJ-F49-oNUiTRk1T(?wmf-PrMO*)M#vMx^DxfdvQ3*Wg2c8jO|b<^waYF6zt zzVk71O+=So`m^6!z;U3sk1wU9vRQ$%3q+ad6>>hp25zdEtN{|ru%3vr#h4_IT9iwpOt$Aax@k#o6gW&&A`8hhW#bb5&g(wcA;s(8oULf=7It zJ3vChqZ1H8es+Tr;e#fZl=^$X76s(#1T+?~s8zkQSw#Bu*xUs)1oR5}o`8F@s%mX? zhsa0?N5mst#h7;`|06zcl6>!CUk00+(mDoc#!jcLn$+)?4DUVY^E6u9v5$L%Q{kKm zm})q;Z)WHVmOv_%^zCU9YW$ZYk>{%zjANryTivvy&hx4@zfa2Fk|;Eb%fW@HC||0T zgl|%D_Ec~VIi06R1s{l1TOL7MtPATlk@ZtN3`sg^8FxewXdbd%7!M`)8|n{pFG?`_(3Fe=UwQ`c zHG9V5| z!?@;TY?Bd?c_<$Aw1 znjwB;ipTZSS+MhYPsl%DrTM^gOl9ZQusH*$7cL1t-FsFdAj#F+SN8(_R!mNB2i`{K z^!0V(Qq2M2Cr1-&0og_V*i#M};%&_O<%=ufNd}-1-_tXG zbHKW{wug+7p5|WFyQFy!4tTIi1{*1$=@@u6{zQWk>p7r)jf)EiMd8FW0WB^0rVmWb zmhlV6y6*;EJMQK>-D8~GbYxA~wy6LR7@?&-KuIYcr0p!!?N$QeHk;FakD5xr3h~lI z_t>8X{K!u=s*4i%Jwd-IxerNxwF*7dmhUbKNn)Z7ou}TN0+hwt3&si3zkh=&Je_{M zGS1Gfr;aC_n=U-@(qyyK?K^`%FlM|uQeOuJ%+1S~@d8Es29ORd&Lgc6G;82C4 z($Q0ts9}%mgMga?e6#lHR~uj^^8+Ak{E3k88orGh29)z;$b0!WfMN zd{+)?f_~MeEC!O_hBHNMnrqYX5~ew(_{nkL@_g+Scc(jmpW&qyNC3wnH5w-t{>_l) zHtYm(ZXIBpOZ&kUhCXrGPsLans+_q_3OYUe;Uu50+fqV*uPe_+%cTix1@A` zDqA+L?tuJB8+H;H5vI(r)s&{~uM7+d)m2-IC?BX5S56`_@$K#U-wjE|W=aeRCxAS? z`A8(xHUxwpN5Uz(_)B{r0v2oRnrZNb@>;gVg@YAFyRN;S$M}opsF8lx(0Ce6>Z4>b zkwLz0So^~Vswh3`U;-p9`PXu(qcYt&Q+s;s)n5%}Z|=?2{W`%b3bOd?rL}+I1NQOr__nIx5Y?;_ zLx>ayChft^@w?;{w;rCCbzb}6Z&Vg&5&z4^l5rA&(rBB%IzR7+LZk1sY>-ou4=!H8 z{H9-ziuxzh2{|J2Fmyt|;&QKk!T&f=CF}8v-jf(E-yk|V2r1};6|TLTEJ^qeQZB|h|!S(6j+PACT6D{c=`YnPQscxTrOwEw(duoi?JLh+#$S#RfLH{&2hy7QAwGt5%UD zAA71eJGeNGnHH-K7=PX>x@6Q*IbIpD3Byn4OeADn| zx3PgvI`;T#Jj_Uh`%UpFLT)4~nIARxqTGCM_!U8u|D8I9t7oWo3czo&M&(-=`W!H+ z_ZOBlovdb^31d^G?fR9E`LX|o@^lg~@WMOh7kaThDn-A4{zFgIpwOj7na_0PGRsD5 zo`XNvhaUD-JnP($xpdHV%k)lM-ztWQ;1sOtlVDJPkkFknBRAj^q#C1GJng4vTCMG> ziaUtg|B`mRVjGZ5J$Ds>>6Fl4mqqCtA3nk9s52~iUf`pPZ){v?#Xz{)<-+)UBLo4%0?h5 zJg)tZ=c0Umx;LPD-e7hc&G9qR*~P`>L*2;CslZ5mk$!Xl&lT>s*Xq>fm-m*L8bXd* z(PAa+vxARr86Eu_vT!B3#|hkBlkqtk9j_n~<4H>!(qZ*xz|fGr1OusAu_Np3?&4FS z4?s$q^k^(>DV@IpH{HK{>mOIgr-ZGUAh{2Wq$moWw-0+3b7rScnK#z%^QngLbeiA% z@?-XJqxJq>;OzqqZ54l>x7RkWCbvpC>*=Xv2|*inA1lU)(8OPRiW^&6US1A4wT_n6 z5rBwWHU%DA^CsM9`n0%zF+EvHp1h|Ef~v<|I>AtF=X@X=((5RuWgFJOS^5plS9-n1 ziEO}DtyH=cLn6?~SG4SNK)eP0V=p9Wf2c*5zed)LT+RVoT`_v1`COmh+FS7cCijl( zoTqv-cwd|)UTk$lLpgRM^3oIW>JLE2rRfzo6>Ff`X1nFR7HYjEoPjX=2UeO)6L8 zGOW5cK>6pB?0v(i7PLO2+9f+qt$CHGm-;#_jg5_KgU!X`9+p>diACJ2H7funLqg;O zeT4?rTJF|H7q7MO+4{IWOTP1e&jC zZMM6Yw|_Mx*(Uh$0DNicouwLWYiL6V6q4D=o*iH4UjZdC&FqYzk8EG|<37$%y4>1~ zF%oj)1{XGw_=OS`xeQDPRy@7T)jA1LE;$bb)zJQ?c*pmW5)x2mMuWees?2gB*QkHRQs~H;5<1+z$u61`!(;<TJe#Wb*=joE#42qy?Dd}? ztL~de-RN5U>xZIY4{UmHk6Z)#4Iy`})Qr7R_Pvit^9b$lP{2^t(&Ta8v(UM{&sN#` zKLllhRX*Kms;`#*Gi%v??fdzt!O|F`C{XClXefRhujv6|_`%3KJG?}@n>HzmPjJBQ4)i^=cY3CN@vo4&y9rF1VE zkDJJ;CN)?p`a6tAb!KCJYqZu1$9Cwi|6cFtMS(4=r85cE#I zBBt9)!r~?a?8oPaw@v!*@O+_cId?@Q^~m%Lfa3Gdl0e7z^SJY?oy7@jCC7>l;1L=@ z!~T-pS71q)aeeySg2Y!EJ4O3T)=Je7T0h>k)caV<&Zoz}q+|%K`(O<6XU*@AVru$n zt@P|-&sc|*tq-Vlud>9;vKyjmhYxx(-tVK?#THFM&9-Pp-_DHR_-8KnuEc*fXere$ z^LXV^naO>juMNb%Ah=xN(c3)|ruckqeo4)VvCC>@LIWI{%*!5C7;e$Ns^8}7Dj&*U zuC1liebv1igiwr0^7^|A3vO|LThn&K;-BvW(VLn_$^2Js;|JQTW@h5fX#1FgB1w6C zJeU*fcEbS7AKuR+it)W`?M$-Y1fXM+Hxu_eGMzqX3nYx=THn7@B}k(f0%u8hkLp8= z#D_+1GN_(zw=$?kH}||;DB6Od!>4Z|wIlPqZTom2F_(8>v%{;(gYVS0kj;;`8Vw1u z*S|I5o*yomk=kCFp((T7rVYgpn-HI9&FNl?`9Zi+I}~n;Wm=QOys@_1>1;?YSX6#r_o|_!ml^LYY-E| z@Azy=r-SfQK9+%lC+(`jB_qz7$ogCKb>n{v!QObYphVnDW{7;UQ!kkg$`1}e6qy~+ zBl-bJA1w@rMS}H2K8pr?Mv46!SQ7a5G&Mt=CS*D9!QKZ&u{YZRzvJv#tZ`i>515u! zGCImVr`j@{KD2^Bi=qDWv|NKP&0g4;D#U*|w^sRUClhp3ju#SipbbZVqa>P+u65K{ z{|c+fo$|y|0y6g@aJg(bnpuZXCG`3(I+JB1K5S4|XrH;XFjbY)cvJ~3T8TKD(vD^ROMsm8d$ZB2P-iOv^(%{75(@)l; z6T}uDg8l90%Q5=;f6fsvFF-1`JX$R5q^MV*?`TIcn`mU=x2SXW%EAyS%dlWV2e0+d z^}72lK*{;M^CZ!z=}x(KaS@<=_?$ofahEY}aeb9Cg`ZrR<;OE7 zBRA;kKbfQ}X<3i>c)41CbL8ZVy>6wfevB$gH;ZYIpCCbElJ@(Jr%b~GrE3`Iuhk^% zG~g|yj7#3~vH9ob#R+|x0^evuPHu2$wm0?c3{;hHkYtcOw-9FwzY8Q6)=N40M|`wd z1Hr}lW0D$u52K;b0t&Ckxs|mIyva9L4N;9I*>ZY=a38n4VOMFf4I~NjdUu_%L3QF` zLkfpgf$eFdeqv;(KcU=d&^7C!y&M-@#9m-~Fm#t#^Y_CZbQP+%#N zkS({Tu8s4YjTFrE{TnF=fNK6Nf2h*|0W%X!*w_kY7yCdU7~Y)eSu~@c&Echcvo+P~ zznrQqy6v(apd34^xf(K4587#f+dMf`2y)z$Jip`5xUq0D-BpghO{1&;%Nxm`7q%;N z-Iu934^C%b{w1RtH~dgDUQywgr-?l0S)km96#NG!eYf}gzIiY*C}?VTs`5nM6oYIx z2w5rK*~>K~sd1n0h-p66(iXputsgcsuk~2$9xlwU(fw`#XCHMiwC%Ita~<)+(9{f- zS1PfN_38SiG{z1>S36tCrp2=n1}nuGYK^QVpRTH6vO{*FUXE*?FTT;L06R^eJ~^7* zl#<*MlQbeg*VVOZGt5S-KB}%&XI1^Tfe74hhKfOsuWCeAzvu$*|&Ys!-7TDV;(_n<4Wx$><0XsBP| z%`KBrKihDEI|Nx_Jz9T2`c;+}=^dI!w%Yhp6$Uu~!wU)gD34mRhkDTpyL&cSe&aYz zV_DI=)uULmzVObjvPD?s$03#2B=%Yk8VZmk#8J$Cc*NtkF!(4As^Bp6&&%JAV(ruU zuw`m<{-G~puj)>uZ=f|vc1hg)gEDFPgn?9A=t2j%iI--%jMddm(*4zDLHM*V`PB2D z|2{gy3fr59kPE(~*f+1Awv^RJy<=deR>L+71-`z=ZBzi9{+6Jlb3s7&4lxkwHW0&IQDl9pP3yD>$-+KB%wB{0jNx2JO1PCq#j4EY&8Xzh;B2uwSh) z;3=j%4563}x^7MoFY=`+%eR#sIe7A%!MJ&ZFlJYM!vmtc|LZ=(oqa|%z6*vYg_23W z45va*xFH#)2M&|u;9Gyo2+|)?NNc+y}+KV$9w&n&{f!bN&e{9 z5*7O0+j(FWG_h28o3aL9!bP$Ry`{D+G=da3vF+H&X*gmb>IXGD5-q`3Z=)c~{1Z$w z8nKK2*PFPW5M(y>3K=o1nH9zLc;YfO44qd zUS@daAIFtjyCLVU*6|#=?b(K{?@Qo}vwsTo@?e=?^L%gB$ugrh=)qp$5lno)k$h7I zHTstL9I|e*JW#B;)LU6Jq)Ym1;hhCdVwH4$;Z!WDt_y|8^y1`u(q|+QUdu5)b}%9) z$Jy&pU#iru3nN4n+L{>^o7L`ax8@rcNn|~Imwyoj{0wYQ2Y}rYxe#jsmPo5I%I!(d z!IdQeHOUoZA;j}qn-$pkmjqDblLx@J;AEdFn<37-CQdi&cDFvVked(+@q`iT&;-Gq z!1pIB9v-!a1pKj?xaN;?KU32b?fzaz$Qux8X#f|9(GpQtpPj$$QS1`Xix$oa{g`Pl zX-Iu|qXF@=jUPrY2`QU|lqOi;D8+|~HW;s|Umtlg)f;yuq5Ia;QPo&$$O_t{V+iof z`=}*NAph*0^Xm`GVOZ|uclN>$G;F`4E{F%%=7_ui701uC5TA>7^31u4!069q$my9g zGUy5)OZQ93HRR{_8i2mYm$!*O>JuCd;`ym&TY2fZGeh zp@X+?3y_;P-!Qc-oc3;#t?{Ye_9>jj4(RD!wkoYi7?}4nqF8N zahb*F2#Lp}u8D|R4{uPe8oIx|ba%>G&9(b)>}CjgYRJMd`7ASrJ0rG5%ePPPC+ zuwJdl4Hr9PEX^0>W%{p9$fDfjxr=o&@2btu&d$QEN&Z)Q0htnsy27aCEWukXD~>9% ziwB^E9jDApzqJ90j;=8)U_s4T7A|@K!;ZCPA}>6u9a*uU!i{_67c6eMbezZvYTbLE zoe%As<3@H6qp?qPRp! z86kNux;O53aQNNW1b*OdzG0L)>cCs`-GgX4v?E&WyP+tnvpN&p&CP9lp)1FeI}#M% zl!i(*J`A3>HRA68zp1Dp(x~YIU`yX^)DyIOk%i@LxM9}m^%U=%QDc~v$nr-p9tQP} z?`s5UK`&+E{F5P483&%rDYz~2Z13wU5YLJZJFri##q=4k4AMfc3+N-L-plozo}Mb( zmJ}P_paR7bWdzcv?DRRR}-!%l~jF&;pEupmAp_#Gt~N zs#VLp86QvOs@PXf;z91gf> zTZ3)Y@bLJ`3KGfNOFJyok1+US-zLNRlI-dz9EO2`43ho)BY&)tqh@S-sl{;+KH^>~ zEmj)T!T|w5)=}Gvy%bex+1>IW(c1KRJE(^stg^qOn7#Mly!pWImnAtGciAhbYql<~ zYis}fkRbS(N>ntXyh$#&2`P4A2g?_mby!v>T?B>KC6LU)n zkd$Ev(|1r#qsp1beyAvR2pc;@Whe6U=M5L&u23R9{Y$Nr-yobygn76AJGe9A&1X_8 z^_m=<>LGrzY<@~@Uxp@1uH4)Jhna>ADQz}~t}ZfNgt|T~sxu+GDrWJI6;bx%3j)dJ zGh}fLre_SA!7%T1JsdH*YmWpx>mjuhGi2dl1c*{n_5wG~n|c12i~kSHI<|=>E71qU zE$Jh4g=Mi3A?7ubl6>!glBT+PQA(gJWo8RWLJEB=c>lgi7XOReNH4$687AMWNqX@M zXb!B8&n?^3mt;m<(m`Hxzj#=bTuSzdgPz$7oQPi8FO^xgLBV_HX=3x`-;A52Ch$)) za?@94Y?Lw;qZAdkzA8_z2-(iL$};P-yr{aip>=V$hnDwrQ645Uy30nAcZ6wuOU-ymlA0Jb1hj_zvH zvs3=W(S-5&DnFM9vL%PVxIhcXtaeYBv&^sGmmlTj1&V5kqmQLq|4y61DuUDf2@bDw zGrmPkQT7BX(Y(OyeH;Cuy(j+|XZpgp#B$lGtjNbYRIc^Qv~m+H$y?C)kAtg`C3#gI zFtvfKS7PB)>y6&~WX1xSk;V^JQ@M}^b)CpPfZ)PaHd9&j2isAQJaI`vo z1b8Q`;fNaLi6a=CD1fTW?*RRlS%Kj~uWJV2mU+49!tGgK-`QIuU9ZT zAK#XANz&Bx{`;WSf+foN5ur(rwtsE;a_2A>_ohfKm1hqgT%*hs)H%dsR52ULwT~r) zp{tP(%0TtyhWhYlem?(bn~;{ZwA7Z#8-&J$Oq~R-n3jQM%ZuaJj!)YU75TSFCn=F! zKg~Q*R&a@W3T7<%p<3_jtKK;~`t`In`dxen*}b(hi#irs9&VuF#4-0CK(tf6uXUUg zXH{g{DDt`a0=#^nd7bkN1%^ju>ND&0LT7H4$}#6BX5t*JW;e(;9j$PEm6b|#V+S3@ zV8**x?zQR0QA{+GT{g(YuM8Z@WJ^n`^1u=7?1%GkVL9Eap=!5PRBl0LK>;6pKDc#5 zGyVb7n$k>N#I5QA7VNg0kiJNPj;(+xqIJ%Hd-J6hg4`^QLaeExg0h%`f-+^f|AqUb zMl9M}Dfi5~yp)}K~1yLT1K+KLdkOxR+v(ZMsW}khi-`axH12%T|k)QWN5cI6Hp+MNyAirA-QT|i!6PI%N+!@R?Lz#w- zj&-zL7oFOPPGwg{e3N&kVB>NQaZ8yeeW3MzgSZq&CF&A9E49T>kUF!%j)I(@3T`WK z`DXIsuCvFTLp3!Pu+R+sdq`HPH~_k6#54WJXTwV%`qH}bxV8(tN?)9!&DI|pQKhJ= z-YC`)Rh#Zw9Nyebif<22^s=wHBU)I*t{dEPu^1#IGjZ6$+e&pFBgm>>gTgd{gqaWTNq(Q}Q{Q3JkW$H628Zx&?i#|2r9?Wu zkdL$dDTKMAq#^6@GouQxt?bkKpZqgfiV^rI{z$8WSH){RJwU|0&+lP9NkYGwC3(3o z@GA2?qGiUp6hpm`0o|0rFZ09YR%@pAhkhP7%kACe;;#}C@u&LJ_i4sL^PLNSe%j}I zx2xQ=<4M5WGs`p`fI#=;QSgZ9NyKawE-pFtJ}RC#qgoSK%&p zV8Q?DJ1XztskrVVU%saWKa=*y$D5k`wd!@7{iYYc8$ztgOg3f#zQpgt4<7;-yACl! zE`Je$Ei^K{;u;tT=7XMBW9FVmjo`yAj2v@Dm5@JwPm7OaAaB+g6z>?;w)v!yHKxrJ zqzZnzwTAQx&0{TuDG};TjNDD;J-)Bi4;~ElG2)C2ZQux%6eY2LrX|n29UM;gopsC{ zx=4!rct%D?M_s4ld0$#v^XN48=?goUcuG){Mei)iM=$=X3=-@Scdt?j0!@B7ib}Km z#9%P#sk!#n$yZS8;F)B{o*Ut?1=0x##Mg6im0iZJe&;uDe3xVp_NR~X`Ha;oSun!a zVb+Z2aW74}f-W>DvOHf(0|r!8Z?lt0wBU~;LJrj#p40+EP0mPAZdfj4bcD@lFqfrY|K{jzu*oxu#f{D)3!cyOZuzBEYLC4T&Ad^gp#rLe2qqceK!8Or7VK67M;SQ!L-7K3+fFICwGxVh>w@?Lo6$9+?e~kFW&FZwfwUQ1dYb*m`f}N;%n@ENnctc%ownI&~XJ2(qzj$$s?W=8z1--?EL^ ze1oekYEvnDFBf*!saKPrb%vudJE%EBk1@v<42Wb z$+m|}HrKVEKu%X4)z^bD;qBvrES1J4@zG>g@|Ox!SGtPh;7#RW#bvxV6ZxA(g6)aQ?YC zyb$E49137hl{+&O$x18r3)-w!6r;TduYa&&nw_j|Y62g?n|Aw;`_j6;@&V4S$&X{i zCpKDYjtS0e74BZj)fw-%5*~DN8~>;ICw3xAk!$w!^n? zvgFg(AX@eV&r+yexGY$pKCXrF`2h}JU=|_7m(GAaBzpx^_Rz& z*dNR=p%5bx)=QE9Y$WAQBH(Yny4og(R;;T3`bRc-6YRjSMRjFSeM`6v#+eKa6$jSl zK94F%LARUF@hvUAv{IN4LZ5bN=c1Wg~^$A{{Zp_OfXH<_(ODW}P8{W#AC#Qg% zO*NaE_@7-6eC9}GHmvDt*N%o%tu4hKqN2(vL)wEVBkI2|ep^r=tmQEoUmB}=G7Ugf zmrTvV(Sdegiq`B>pMLi|#CNZ+@eXKg&t~%sF#WcVPO4zhB?)2 z2C(UvB~3eaAgXLHO1@vDvCTvb zeluw0eodpUel-*4^5)%!OW&;H>r_u$4-V|I$ex?`z2xkPts-9^eCBn_(&WcNu>XsD zPCvtRYwI3-As&qUJNojrU~Y3tN!hC&vg@b$S6<I1_Juqs(RnfzP={uv2I@nVW9Ahg zlQHF$c1J0lj_~)gF&MUfP(-l=q#E|QGBePkSWP+#suvVQM#twwg; zn%xUXPvI4AeGz2_w;d~f-2(8SA`la)L2Bdfd#(}B2Q(a6Nhv5&Zx3ZX{yoX9hF;pK zjOy6(nmGU=E9zSmSdvC{iX`!`h`n(8Jc#lfV`z_vJXr~owW72|=z!YPbT(|SA*IFI zWad#UxtE~5GMIfQU}gQ44Lg&ZykB5)avP52`MJD2nJ@ijqmH=u|Iu`o0a3MG+nyP^ zk&*_HmXhvLK~PEQ6r_>v96*!?QA%1s8l-aw5s(~^k_PD*LQ49(=6>F9{qYw#?AiO; zE6(#+>=+tgsJV$bmpN{qnsl)SjC3D4plxS}>uVo+X!*k5?ZceR>+#|cCD&u322dt+uIMB7Kk|alewecgz7QB%`{t<;t)}br>_GWQ^A+}fQ z!Q-d%7j+`X89AOvj~ORx?16F>vXanG^|On;UqXLq$x6`?gR#}YH>6(tzr?pwM|95g zjHf`9yCJo8-1iYu{E3;6s5tm$9Taa2P43|79fX|PCx_X#ywY5l`PNMq_&+Ks!&0Wl0p@LJ&qYVp1APEF-La0JLdB%?w z@$4a;(3Tgl!c)_O%fkyvaod-Vk_K>hS!XXhAgAt5#2=aa4K6fAMOE3_nU>NQ=VsG0 zFdO}+);?!pyR`VWc_J=O6M=OIwI|o2KhgrVxZgR^$GlJBB36>E+gnXH8VovVndSx! zGgw)Z&50q+*FCR*^JEgkopD<N~8TiK6*NY12(Q?j2Ew7HLCAT2{Bw93wqYnod=|-Zo@KAs9vk)1X*^XxA zf2BJ}f)bt*62q>RaKgVAYeT+lo+OgKb7BRSH}c55EZ%$~kf8Kvd{`i-m3PMe$pl8% z5^7S=7M+R%`%32)gGoC!lbs3A3Yyk2BKXXmal4a6o`-eB&EzKR)T!Q;AvG5vR;=Pi zc3e{zOXF@C==mIW(#I|<;7PubeId_}mL3A{&u~86Ev!F;hyzdVAzU3)O!UyQo&DIx#8uqCk}m z0?8(M#B+M~(3f7t@TuFqglmxG;NXOXfvJZ$P!#qI%ecDgNs`EdzwvA(pk;n$8`q&- zFB9unDW-JHUGK%Unc>mX8a}`4MyUx2-B~%rwN?$2i0AZBN!LQjjbv=|j^B2bYH=BB;fm)@=EJ8O*->iabE4MLpWc?uTh3v}jAHqRtp$h$Yi z8IJ6j3I7NUa*^L(Kr2PHR1jF{5J{9x)UUJaYg9@7z~A+Be}7q~OhNrx6URD8qoMCs z!Th`i?ov%Q(R;eQAr%9eD;}it&XiRH^TO7pkj=>6i~i2Ow6RDVydZWJ7!J0;YUrd4 zi%Q~4K8#PGmn}-LbZAceeto007s#EZ8yQNdcXNweVgI~oQ$`_+Lx*J$?}D=ry5Qb5 z^9w;3g)4}4sKFn{TJ+)yOv1K>DPV^3$)`ROq0OV_Kjr7=T&W9Ex7U4?B6%%FGEGHe zfn3U+BgFT?lptEbe@SO%e!@Qv=F&a2`W~#*tBn9NfueF9;_I;vk%)Z4t}^tA0xv&1 z_M7FD=X#Hd!93sHrHF)BRC0 zTM+YYddEVDC_^`{tKV^725S>xDvD|hktk1PDHp2%YLh}H>zJDP)BLRJU*E&^4{TL9 z-@?c2o=@|fDw1xO7SZ9Yqj=9)qXTLPypATD=uc~a*n2p;;ckQj6n7;AtEPpC{*&s- z^hMG|O--11$xW+Qzf8_v^OCr9`}_AkjNrqQY80Ap>#DL5VrfP_xr?bFKhbk|rv)NI z1aBY%P>S?1v-=+rv{egVh_?NvdTS^9bSqObF}Hi0f-b6{$17Us&)YQ0k1zDGjmCiS z#g1YRG5>2V9Fr|?;4VF>T2_iS>`*DZlRD>Aldbfcaa=;0?PGyfp{!w5hbY;PmJbMo zVs22-r&BImr?5rM8NX~~X_r$C&nEb3YJ4~0;*^2#DA6pvn}xE;VFIQWD;u%xpgOJ2 zLag5>6+45NUU{8H`^_E1$(}P-7IsMvHIkQ77@o~50-*&M+iDpS2>O{mODZXgs34y75eFT6pFz1jF6Z zv;%aHGR?ldUPy-`B+~HT5Hx2pMxpYX7U~jT*Q~iU)SH!WOz^oEt&6{Zzvi~X9B#cN zd^RY?@$O;iLNS%RvrVy{R;`3iZCm9|wqfnZ%MrD|lUw5UiC^lpg-81Q^*ia zNRKS@daz}6GLSy^-kypZ@%hcXZBC&Gqm-4M9>$(1xB_yy=-;ehC+h19|JZ51*-waBCo7k0%H5OE=cvKd*wr7p7u{!nUsO&{)yqo6H z5HotU>?7}OPbLnyCDxAqm7x-En4Q|H>kbw-&};y|j;sJr7#SD)tsO7|=k( zCPmr|p8e0W#Bo~c^kAmgi-7X_{Itxe{_tQaxEeIbF68v`e$S%^r`;+Q zmY{p8!CAW(T>g%450lUq7{$v=xJaHD&!zL0Dn*lxbX$lMG|_kFOm6lZQ8xweWlUZ6 z(Dm?1mqT3hUfUKK2A=4^H=Q zq19LjG`qseCbY@~vKVud`pUO(EviE7Wv{Ban2^_eMY89EM~5*HIt}&#gyXRoE}yT( zTJZJNq0MPk>$+O1-#?Rz3_r5QvfY)xZ?<=!-NuZWooKoIDPZ&_qlF9L| zetj1o1)b;Avn@ag(qxpYQJp(XDJc;XZ}KOgF#n(+8(W3SN?u+w2DOLolCe*&^@Xu1ujmHG62(7WshF zr1oXNLGX|PqfNN2u&q{T?E?HVf3%lrmAZ+AwHA;P@flDzhW&rD3eKG(HIy$bp0oY*r zG!Fzg>bS8W2a`rpQcCbfLcf{QkA1?r;m!*rcE~ISYWeX8DGd!nCh|sDf65;xj!fMC zUGr&83UBaTASN-I4QbISE4nr9j&DR-aVeo`QASQW2@0!MCFS0zG; zn*M)6%a#IvR& z&C0dVgC+BGCPEJ|b+#2hGqAk+O5k65*ZIf?DElNcW%1V^Uj?f?!SGz(&XwKs!Iy;kC&ai5Tfk=E%KNY=% zXh=ae%(VI5#>>eHYH>q-5Nm(`Sey~4OZAqCsy4M&L4l8$oLpQRwc+ni*C0uIS&q8$ z@CtXX?C{-3JcdEc9SCH^$bf9C>PhfN$9m%mU8p#*45lr(r{He8z5osLOS&yH#EfKQ z_Rdo5T)S3`6o%Jz6p0W8hCL+t)Gvf8brj}VZz_t^o*YDFP^2$t!=1#2A`Hxj8HI;2 z-S1m|8&tC|JiU;TmX>~Am~_Sj6o6H!r~V0$$HGy33)xq%gKz(^bgT^o2Br;;TE1~w zKXMZ5I2D~a+E^$38Q7*|em{BZ#M2{OkK|8}qq1Q(i4IP`!5SU!R{KS%kdQN?z&XU$ z!!e0wI{&s)E;S?I+)AP;`-6EsCk*$KvZl$!IVy ztCn28)u6)o(5LN)0sbt-qUwSfQgA;1TmEu?lhf41kCJ^p^zug5u%~aAgmCFR^YizF zcP-uz*Ub2)Hk+0Y8|Q%s61c)w014y096c@%9}IMh=M2O1UwmJ7@$q=+djp)vaXy^C z3tB(V_m@u-p@CCMhBGaw_=VjKT}TTJIEM!+ybQ(ClGx_etY-YM#)tOW4d~6i9Q{Bp z)%MZGq^xN=$5A;4%yqItzs?>y3>nVYM+3o?V&UIB__iAqO{R&DZ-6n^Qpd$b{Q)Ir zp)6%AA3w(65Ecygrtb3qR>IRy1E4i@>BZfBMC}gf1)#?rtIG{>^4QfI)8wf6JIK)uFZZpl z9X+2iV|Y4TF78xq$&hTS#fpgS^q>_a0)?5GppWyW zcQd5`aAh`g2nKW|KAT<`gGeUEztV>EqZ9Kh#V;YPreze2kv@o6gOxg{yFf(W3cB++ z4x5}&XqEZ*G1czRXLaW1c5Kq?&xB1&_7huNxoSe|UVr{-Dk|4-IIDdvr zOC8&-*>oP{*3h7{BkCz8GOya=N&5H4sQm~E{QN!1!#Ugb_M4!=5SQEQD*XbO%Sz93 zE)wTkjW+j0iqZY#6Nf2_s@G&oeH?*p-A^D5MwwRgp!~dlXK-QfNMt>t2*)$=(U-g3 zTvn6ga~!&G^g~u^vT_2ubgeEkf^O?hFzmBw6jo(Ux0+LN&=>yp=(Tp8YGLAF5Bcvx z>0$5*Gd0!<|As)&QorYnSdd?$7=Cq8x4{=%qoZ1QV4QGs1OB->zX{UB6nFpH-mV4R z+;ON)_&QcVwx@^pv(`W{-Wq4hS_0(=^p_E1WBR;VoP?54Zi(RR%ei8092{WOead-^ za>jU?$a?2zgGFuywg4DhSM^@q$lbcbk-;}}O_>bS7+=O3!3>aNV_o3HoMUM+okESb zaj_|^VrNxyoAty#*^p@IPxsA@#U1#DD|XxM_0S8@6CV;I#{;@QJFbtNq{Iq9T`GIt zXX{~wW$vR-Ato9ZD)s@WFd6Bz`AU`Clxtf|{pLMQ_(#$Mja$N6vOIsfVtVn;8d({L z2@GBNeKxhluc;cmD8i`Lc# z3XZ_DH8-$bbMqLXrgnH!D$Q{I)tRMdB7DgQ{!Fwudc%(9 zP27T9WFOB*3jg`$^`;cVq6Lz}h&`lY!n1Q6zr#V>sr znKP-t5W?JEmGqY#1YAxb8u)}x_WrRQTJq}E0st8o7wqhxklKLK#>8mY(qZfUnoXTv zUQ=js-DR%~kE%lb2$)fX7 zmU^z5^>Kao8GI}$Hh**Tg`3u~&&uUhYxBlT`B`p&<7J+F(o+ujv*{aPysq!)rP~(d z<@NYZ-nR)}zc2-bq6t!SqiLSHW}bnQIZc_I#a|^Vd2O06B2CZI<*W1pid=YouzystHcA?v5jP3wNnbWpl)SvjA{IsVal1`1V;<|2cZkeJOq=7g%m;a z9rD-f;kMz5ohqJ0@ffK_C(H%Y@#P?fUeqq-@_y6A#=*e>!qwmN^YfY6IQk~MRM$ap zA)Bip4^yXcG0_>4)qMvMP$@}Rr>__q6~%9V>{Bc~6spSqC^>QHQ)BfKl~GjlsX?1& zJd88az|^Sgr6~YFBZp7%u5Ny@#dx-Pa8daKXC@l_C9&vbg8fez!R zHP-T9D@fLcue8PG!~a0O5NR_$AhN3Z1;AKFCY+Gx&oRS%oIdqui(t5~+^S4hyHG!( z$IU6l@<;IP*h8~cetM4ENpHuct0t*}vC|UsaGT+XnHfKoW>VNTw}r%pZ3L(!g0H*pH{z z@KSlKy25i#$*|U_964?{UN`JrX*AwDvq?ToC5lIVV)6d2p@{o zMYur-!7H9B;wP_kC7iSi*#ogBj)6m8|b8x+J)H4%#10&xKP{zUl?_lOe7CyD( zCXzg5KVLXj_@6AvGEW0o>HAdL+pFL@8{PH@To}xi@4ZU|QKa&n;dEl6bL<$FfzVV^lLA;Mo64|7<#1u`O$p;gxA3vzxulzGK?$wk z65%~#a@V@KmafUHu4DSeEv5n~ZB0Zil_o{^1t~|}zIF?=gyVm4KEX1nd z(5^`~o}j2y$1!ap`2NPTSe6dQyZ(9my;(4innacnh)D9A4_X!$XT;A~0jlS0x0Ri)0L6PuTetrxdUP^p0J5LkpWN!Xh+BN5>%hx#JcX?_a zFrFC4H^BN#TxH=aejl?nk{kz8udgW;xS|d!C*3LW0QoO`p+}YD6V?kwh?PgTO8Q-tM&&S(H`n_ z1K<`JN!aNK-=nd)%%mOLkP!J5n|3p7*I$37k?zJDp6WvK{~7UM8ldbeNW5x7qb#xD zpnyhh#MiUdMzwkm>Zdl;4AwO>+8RynOo)(CC>o{KaHjr;1c0EClr=TVW`vd?QuzAdK^tnh zBU3mo>(80tp5G>*Cw(86zp+9cov83ZGA_D)cK@%)shZtGHy?fOdz@cn9;QE$8t%bv z{**1Q0Ga26=;5qp-l!+`C8eR<_cc|QgRXB6sZ4%rDWmARZT<0w~<%Tx;QU0}?5k$4hdjeS{405Mil~~p2O-`Z1Lvn+Rh+o`YTsmq^NysKHvG?`o@6NOPK|)LK6{X@`DX_0 zX#G()zYTlnRUxdZjA;XO0lYtO>)Fq|GnQ8+kJ0D{L8P2?eUs?`1Z*4f{_f3~xRtZSxu z~Kw z?t6=eDlniE#2#3?h^hal=g#NyM^LTfgJT0CHu+c{l2YT;UmQy*^V94IPO4F}d)d9BnM!l4{`aa@A9s#& zSsUTmNtiJO-!*D(!TAN4Rrnltxy$Rp-8n{H=k&sztu1cdW>x#rfb zn|9AY>Wvf=fGnN(NiPe$i>Y;gv-lewE>xtmM8^}Sdg{T)h6^gEH$b2h-+SmQDajqo zzF3N?{Pn$o@~Jn>tJ5y}lrz_!*BK-1ul5`n*r+Q7kqo}Tuvg<)V) zKhE!Y&pc^}1HPR!-~$@YLhX=0ffpAqFWc8Kb{K`Z*F|MdO^%2J_|b;cpWl-b3^f?T zTjFkM^)|dI!8%bJsI=De^c>y-NngL}_QOBh*{aKewHopVj#Swsl#pcs!&Mat@kE|D zxIM?WJ&Mu=n$`)!Zzl%7A_-(A7C~1ixU}@&Z829X-_O&;x521g3VeE;1l35EUT6eM z5IMRp0V5^+^E^|QfmqCNcw$05_-uan)@J`jmT_Oj z{X#R}i0l#T8m_j2WNlT~>337xjo=PbA3LdC7kxVApZDH>zlwYvZ4vQjj=rVON%S)I z#B`#RMkl=FyRV;CN50z{A;k7AFVKwdXa%y|Jx(^d$U9f;GbalnFjPJca{ z@oxLCsY-Z0^!i<;zpTBd;r#_=>+FyZO@Fp8*FbxX?=D&r$j=Mq;YG(iA2;KT%LxKw zsaRpmNg&2e>@$~BEpSOwTRGdR{fpp?vMA1f>77%+GvK!IA^*r#gAy;<$^a-~L*Y$( z%L06$Yz>KjeBdq|mEHAf?e=7~t(53q>^rho^0~K|d%gcf|7BUz^W0I011s~{=R!4w zc|VQ)jSB<3ZKV_b(#NZ1!!MXlFN|jd9lSWRt#xsO8c^}2l9v>N98817C^VUFA7ic= z7_U&Xn_PA`a-eD<#vJ+RxV z?`VGevl#Hs5|62MK}!eg>-&piFFPsY@NesA^VR61;|&Zj@iL~(&#*ERXZ6*3% z0jn8yta1Kl2KA=z;I2Qx_uHzBwOtSKkV;agqdK^R*1780WQR6MVCO6Bw;QZ2y0GY$ zM}2{9qcH>y4*hV|u5EN#${`y9zxnqN&e?1%Bm^-s`kyEO^0HL_v~&~_(H$Tghw<;E z^2ir}RIlh2uKs+{b#H>u5*3c^?+bq@7<^_d8;}YT;*Mzki|Yur%)+79x;YweuK3wf z<^wdQq+V>tP0j?}4xjX2Dik~2P7&u!*z*qTG*TMqsrA%@{aQIyEJHJNC}RxnI&K{8tkURhyam%J zs%YwFL{nte;s#RlMEb+Xsms*P^zPxqj{R#>VM9*9YI73PT{BOe>?fM<7Wc0+R-<4b zhKFM%dx}H&_#iAFIxAm+Vb1HC-~0QEddcJ9spp{8DT(+2?mE;gXWaXe`|}(($1;(V z^Jstje9M0}V&LxoUn*!zEhR}y?-PSr9R!~lH1^DU)Ez5Z>H2e?v9Q{4<#W1h*{e?C zd;9f&bK=Qbl|MK*QKlM{56fa5^+Ar*b^w#?jf_9`w`LI4zp|b^&5cH*g&Uk#erzv4 zf}35J=*M&moY6TbwHSv$AYBm_90y+Fw#EDUi-8SVk-bn|J(;WxBtT##zZv@Cl!>iT zaoUY#{qy5fy6~X0zdz`3RxbkP`e!ns#^vj>wmX@RWatx08-xPl{7Op#*u%1p^a*7) z5Q@vuPhv)VZUa>eO|Wc*(QeWl-A4w}*_EcqHI3bGTF}(A<#T&Vb1z-e$9I@1EDSU; z8{KiP-x(R5w=zR`cp8lp->%Kk62S}ApRr{FftrUTNa_W{-9en~*{MH8gT6^fC^eWi zL~VbhWih^aYyVdOqHbZ0xw?AKIm^X9c4{cg6@~(7{LF&VVNGxR=vYfbq0jdd(e1*T znox~$V0g6`5VMX;diqH<_3s^Akc_wg3vWWyfgj=H`?NL+!Z|4K?Fe#cXlTAEY+$y5 zGCqL63pXhfV6)I{2nzGytAB?p%JIiE{kvo^Il!Kn^d-X3U(t{Y{PZpYJbn$_tMh|B zfBx{_z*2G(45Wa_rNZ_l7tp1_{c;lEs zqOGxHY>rxxUzQ$D*7nfV_*tMc>E8afEsoaq_3fVW_-vl6EnjmR{fX(?!tgMs6_kz8 zKg1Uir}wYCVHmlw0WHx{unoG@oUSp9U6E#lKkr$_#e|UI8N@vXkp9vMTZ*NdYvbV+ zsJKM2E*8}N-$Pb}{wFKAqb`L3)lwG;8y6#vi}-;=1URPRgD7NtN=s2o^71$TGx0Jv zo?uvi93NlND=aXad+uO2e#1cgiN@H_&@if(@(po`ScP{$DNrx~`UpB~b3Er=T6;o_EMc>tVTC15t_Y4eyT_J z0^-C8=H)50vH=tS^77ve*bTHMgj~6N@3z=dJdwAoOSGzZgX4p51g7w!VOfmPMtIXg2ohgl%5vFT+~vD=IX5}g-=fkfG@ZAAjgTndKwc9|v?WOu z_c;f;%kunVBZt7nl+pnBv<;ytt#2 zhb;KFDf=s&+HX8X>2M*^f%rLUqXK!wb>x#EWX~i9HRHNx?yGYuhP#=^k`7g2P|xBW zUqXFg-_Xk62YR0pZ2p#=&X5%6?W0hr>x1|G)!=*?9zK>G2y2KX%94}AiRhho(tO-S z)ypNZY4|QGNM`3e05M!0^}g*Ti>tbjO;VUx|CSs;R?N=*01{u-?MU!+4G!8O?`{bt zb>@A-=HCC>TT^j2=WC8EJ!jm&)vuD31|v`IQsMfT@yX9m<+Ic5PIA(*+)_mH1Ak3S z7n(cmo>RM;g4_OMAG1$_a)_0Y`;|Ub_N}~p8mYm=@bGIIBAm@WGkupPL!9xw-2HJi z^-=9-+nYTy^VgyOzOlGm%;aPpDTK5JA|@A+!<<-9x%XZARBFzgS7A8ep-3DcxKFID zf9E;kKanI_4cy*KGqmsegZ_}u?7VSCN1k$B&F|$^(H01zD+IoN!ky(t=Bpk5ar;bg zErEk9@<+=)_q`oZ_mn9k<~F@H;>LXa@JR{(1|R^S-h>kuCeO3(Heo-*=*EpqRn_4p z#*r6{w8Dvx6PUW%Ez^2M4S!9R(wW07ObZE;>+KU%VichTX-pzT>}O|Ox_Zt0scsN8 zHc`0Q;H*Usag`hzZY+c2*{R{nFZFk#esZUmjH2I1$B?bRhPmE{!CM&==C@bG`sFRh zU5%_rzgftou>6>}6%gwWeO;K~CAI!py)&S-)3_2#6Y0gJm)w!DjVz%HCk4XitF24IG|^8!nP#lr%pdNA)V*>UxrQ3rzuXJ-uQz>DK8 zv9=KNdc>QGJ1>xpSKFnG>VkM3)tn`D;A*?j%je2};7t5c4OtV^z28wq-%aGIwCQ1C z;+g`o!PIp37OSSfG_|}*MNU@SYC@nMo$e%&8?;84j+<_d@1tgZcByS2=5wPb?T3wj zjU9X^H_-0S4cEYSrbjy;`}PdUlnUwN?AxphebY0CyS9BdIAzvWsQxbOADVK@XTPg8 zB57Qy7?zDRchcQUo4)5sjH9M8W(N;P2NoOV%kpG8aNHg?e%Y(gVf;z|QcoVCOWqBP zAdKEk-xQrIYkKz|-OI4P*|mwpge2en9vSF>c(antjlhO?CL=yCNN)MbtQsz<-P`SB z^#k^~gEzUlW++O0IeURZDv)(&Ur?xxPfgZ_B>q?eno>49pV111l#iG<*YtONWh+ho zTVb$pga!Jq0gN)M!MA5oy>lfLSqsPqes9fuyEj@IHTL$m>9d+;vVW6CLvPt z=yojoOQ+>4C|kjo(Mi%%Q;F@>q>FC;Ut0hL6h>lSr}?&8`#!Uosi|quwI}KXZIS!X zF&_W=7j;$M@{s;1ELfXemZx8S0bO~P8`|fzZfeOT%O6+_j&rkwI>%33a<{1h0Xr5Y@Cr>rj z!73j10S=5BA6Z?VT10F$Me_Z+xQz~H-ESw`8|Tz7)9w2mhs|bQ{=DFFjhrcltitBG zOxi&f_c4YS^71~~I$}I4n zlF4$C*qj*{K6^mAbgqQa`{bR1=8)2(!=J(bUKLYB)<(0>AexLPw!5)_d$r3ofbhV- zT};Y|52LKY%~+J+V0Rj{4Y)cEUD-cAH4g@3eAgW9=ae+>{-E7{y(8zUSUYnzHQE|X z92yN5|6;R{22GhN1itOU+wM?^g{LLLQ-n{)SZq4Cl+Epew zrDA5XG>6I>+21DHVlM-KqipHOBryV-Vjg0VFj?GT$?82aGX?_sQ#i$83+J?BN1umuOJlL&NadA`u6qNJL-7G?L7=XqPw4||0%Db9NtQhN z-9Xm}t5_F``O1S?eZR1P%|MM6B72mkv3X2UN#2!nPcfO2^2%XqZch;kHdavpcGBe; zc_c!HFpwmiLd2*1>;|BNuD-))OW0IYD95CjQbR8`hb@gaN_98J(|t2fj7jpEwzMD@ z!uj)`p_cgTD+KFG2HZF@*{_D9*(EWzS08Rtz&2fS8s{#Wzx7ZEW(Z6dv-ZBpJ(5dy|AT zNaAEB8yVR~h|4MwxkU*?^xks43evzy^-M9#WZiaj|6P?(QS|0auK#D@&d7FD@y7)bx4H#6r2aQ|bDwF1%Iqk_#Ba zR#u*2Z;mCLjxts<5aN4Lr}9gs?qrhg7-UPorT8T!hmJ+YU(cGh(DK>llJSB!!n8#F zJM~neti>;3|Nix2Kr=X(r?avxr*mEO&6-3+zKuOjaVz8cA(fke~7d1~zQXZKExjul4mzBcdpq6+pKr9P6Cil%=20p{1eVta{snm=>1{C>I&uwT;` zg=wcMF~sS4N|V-{t0uT73;AQ5O)Bs#wH2NG>(S4Kmu#-hPcapO0_VZnAgHNd-##ca*EeX`({&!p zj@fCxrhXZ@uanZIZAl&T>EGPO)eS<%Dwx$nuTqSbr}R^?HdA}^c>uj$DYUE{PZ11= zJ8_hidwU_&dO52l4hT8)8aW%AQF)WnEumGK@*5}c2)bsGd}d=2Q(61n!?hY{0nKzf z9)vWj5ZJZvHmz$5?8|Y z=&$6$W{~C+d_J;Y_qnSRy)2~8P*~DW9{+vUaxBqtM)1Yh%+3c~isIUxt=^B+)lQTn zHDJ@n|E<>|d^q_x6@&AOGn!MfctNGs$hp>`Rz6DF?MAaSBa$p5g9R3w;$oBI!CSnq zZ;Xlm>knx{jqx9HJYp)Cj9`)7Fy)suLuI+0h@ki}O{Ym@d&6OS{1n^9$yx*V%dub4 z-d+WPCk;|ztdMZ?Q#qjRId%ssc})?zv`dI=Fx?QRSCJBHH={rfL)s3)Z7JM)N15d> zuO}*pk(p}1Tda6b(=ix%`ndoX_O8RM>5m&FK7@oRDX@`O=d>4ykl#Pc!%5u6HyRZc^|`sCXQm>@JjT1jtXEp3 z8*>s8yDejHJ3I58^xsp=!ZfhQ#XhljexnOdG~}UgiJc0$p*`jj#TRu8uTL0ix61d< zYXdKy_uj>2PAK&cyAgDp4>3t*AWp_gU^Va(KWL;S$~X|EX#t46+=Kyu8xJML)#sP|Z5v@xjCt@O{@`l#4p_#b#KOU$`m}K%98$#K zS0Swq!QJ~u)6RkPbDlW8*?SoKfGNPm3mc7=wQq2E(>|ZKFu*zQ8z`vJdH^e#RAzwy zR_wWNG3x*%DXMGP3&R*OV@nUXMd#~-gXc}KU*p8Ys%%+$CC>&2aTO5@Wi-Fe#q0be zXr50_W~d2|XJ&#HJy-#d+LzNCVEJhDo5ooU8Vl7VfeHK#L_w+2!dNG+5Ss_dYY;f68;2L3_*E%Z2FX_4mZktDyg8OGDio5nodTXu z7k3H%lg11%m_=q=mOw)#>`hw#;v@I>U~>pMLMnXK3b1W07aJ?Yw64FJG5)ZFZ-A4m zzJA>$BLmIPc)|isGe9`yvNkArw!n}>8Iw;RApDJuj2dV4tl{fmLJx*can9lUWDbr- zX}Mn0=l6D|c|P-UiM*FSDW(WgXY>$c*4p&v4xfEMHEO(eQvYu04EFD|ZEl6^?f=&T zj5jmB;h^{fwnH@r&Tb5#@s@_XNid)DHJ8Sh_F^S6J_$qkp=6)itCr86k;$`bm%7rg zPv#XBGYc=iH+Al`?s}33{npHl3#f+Im(&D0oG(kmLt)#7U~#IapL3#3ApUj_yoRRN zxna(ubfd}oNVgsP&i%^S0?4uJoiOmY&RXVFTTa)iU>zy2&t30k%d>+viMo0c9`0IP zNoU;l*OqxFZ`RP9wmK{6q5(m_3fa?#?YCFP=Qo>0TFc_c84d61cS`jtbf%1_`EQij z!@6XA`;UAx-f0pSPDpHeRE$61^r+Y9h?MbN^3M+5FsuEseR}qc4b5ko-!psx=GaAs zo?zoP+q0Q&?_JpWrAh7304O8-i%Q;2*i$_rlV8ZUC%Bj1`NufUF@|BHUD zQp)J=KYe%|Xf)yN{37&cHLDIcB>UpiETVlAnKVi+>xJ+dD1G(^CPf z@GMT%;(G#_X`M)S_r{Fu-kSR#p8ZPBxy?JVe0Y(`5_GVY|CC-(An{eaFgqvK`yZ>r z$U94R0lBwh#356Dy&BvkLHL;B71Q5TXMHy^kK7d?jlM$EWm6BQ=m(I?`=vmG1nuv7wBYEM6p@{W7X_Kl6XhS_*-N^jDB9Ipk}4 z;_f^$+#HT@MQR*`B<9}Pexa8B*9X*&!W7JG>Pa(U6>A}4CB;OnujO+zkSmtQsiTjL z=tf$izuTesKX4}LQ<=Mtt`tutErMzl?A?eaC_8b~jRt>%Q3FI*Pfu?#KpRhCLUIc9 z4pHU2gLZ0#Mj^%1_rKPS6Xfgio-j5@{_5dgDx^p&)vE-HC3P-Uia>ku$Q`Hx%Xuk+ zKjwoMYaWxQB%sqIr(~*Ox{E+o%vg!Nyx60pNxs#tdg+zo{%WF!59n0hjs9&mdN;-* zWd@sH1pt*y13s(}6GLP#r)`h_z&cP$q~ipuQN7^E=8fulLipL*LC*SYTh?zCnBa*|H*8?$sDBR6+8U4}5+^CWw$2<@2k z)Y}<4=e94U)XXbPgJ9YJ4m zL-_Rkf3ot%R)m?BF5fXWeoB@sqUbD{lyr1Hl2==oG*HDO&l)OmK9jpQAA&GWwtClz za;2A--a7>Ir~ggAepvA7A&8lyib?`pG%A%@l-hq#>YRcKIr#eIbWX$Y*AL(Sa!H&4 zJS~HK*E>c+L1e69aI#BDC}B_VO0OszL$iv@PCMF_U!; zPTo~TMC-?Cgj(UDthu-heuCi6ko4Sh&kMnZzt*A{)rVD6Ip(FDhh#rA`Sa=;olyuT9|Hi|UI(v^@B0rGKZKxOVyoX{iwyM#~D7&8paj}iwP*vh} zZSlDg$ml7f{~NtJBf?7#dwZ|rwX@G-2I`vd64X)#PMQ;=i%t`Y;;)Y>LS!w9s z-O9vb7{yO6*4#js9-^$g$<-DlLn>cqes$eNa^wr}4~R4Sx|5UB%Yulw3447tyn72f zPm(OjK5S#Hu2u8Yl(|VK;X~Azs~Dweo=#3#oi9O_fD8D;`b8`FZ4xov#ubL;+D<_> zuaVXcBGR{tA+I3o>j$@8%eo`#V9b@JOp?rFxmVT&Js5JP!f$XQ;-^x+2jFo71KHP( z4h%=bQ$$ExGO}Dr7PEAmOMeBMau2hMuczFSs{N8(bP16@y5m0 zE?zLNxXEI9y5P%^wki&IwRxJ{IPZ`RlC{Rk5^8w4LDwhxWyZRMJ~I*%nIQrxk3d6t zR2z_2@^Wd*>UxXRuN|9_61M2bRIB9f3~ z&uq%h-eqTJ9UMn8GAmgb$H@EG%3jAv$UI~mo02__b?n3Msn75G{G;n~xvsA3<(${^ z`FK7a_xtUhF**b*4R2W5n9rx3tT;a0CJYBShcf%3=Gp8d3CuO-afTTZb{#>(L+AAb zI9O*h0b;l>Uv5A8oX5JCn%d9dkwDf6F3G>+0)DlcxycH@X!arBwS$ykq5o)sS`Yt< zUDN5VEFd=mN*vU6r6t#yAIEE9L?#kCTD1X1*l(qq-IQ%+W{}?AxgTk(?gtV9$oQpO zSNNI@%80G}WPpbZmhy;^#5bw^9zKH2PDqLdl*ez|`fOy!UzK$1LSzr+v%i+V!8eW2 zl8_`(5w{33N65w6hVjxT;bBlp(%!*QlN-^s#ReWh$HC#PSIw*Jg%Ur4Fk35l<~(RI zAZe~Z;j)W9GVt_1Pv(~OSI$S`YTxNXrp@<+Sy*pGQ-xaT72S6DSXnl}9 z$zPIxV?Z_cO_Is{L|0eWrI79+6hza$>a!;C=@~BK2?}+1x&rlj%r5JP$i!eRqT98v zhfqB}lEU1-$0MbcsW1G#q!fn!_$4y;L%4zfMko%h{`0t(il|OP*!%${cJg|uRuvjO z_4#3tYBRU_TE^h`kY?dtD|^QS?NT)R+`%V}S&c9>A!vl~ba_&nV)mwRznhD#5LIYr zn;>Y4S-6#uZEaa+U!{O>UgMkW(HQ~F9l{*sgm77a$ChLyOVg(4UpwW50Nvt|TD9}H zh<*Kf%(m&(u$0S~|9?82&LYSw0W5p#_8baRRgfTFGW&jnmoYd<<}=^;pBypZ19jq# z!J~tRU(5_ZcbEGIeg4W0QRV=lEZJM2yYB0bAa>%`VTs7q7Lz88>@+V`&qMduou#{V z8~?E7{NwqUDe5?&F2-rAqT+CT;g8r3gCsKqOb%||1j2Hlf5=$>#Y`UIIvkHL{-k1c?$&w9$NEqQ9yDcy$6+OuTa5E z#h9sQYqRsefh+{y>uI^Fq(r+w#B6BVE8sQlQGto)aQy#q-Wwi#prizq9rr<}tbyX3 z%t4*p+#JNKG3}0VB@~U{b%T3(+@?^Ex*T#p%t9~Ui}!hfl{y8?Jyf2=gNa;_RppWr zc7m;-NSxVScJ_)w~% zFDo{~CxM@KKlbo(*#E^>Yy3RnjO=^{4eCYsGW~LunKOBgnxV|f&=yyl|vErmlK-*N8h)F-cQXohyQPu0O-Q z)ztS;JjZdsd4|#sRj{s6YBkK-5}9mAsBor zmbTyzHtII(m`I&uap&pG*?1;8lJJw0<)i;RUwnC^IXeWSlL&tOc2+=OemxRmF6nEw z7FbXG^#;N;Idq1xH~<po%Y4P(Y3Hk51B2TPpT&H};3rC-(?Sdu zJ#Rghk-zJSjTDJK(>|3mNx{%X(POg z4nmC1p`GU$H3CP=h&baap{xLefyy2aX$xmbx3i#a?|c1;LW ziPuGS?m&mT#W*K1EwGb<1+euxs+L`bUz#~Cgf~ZnwEtNZmz@xJqL$q&3yXYbS*xlZ z#{|D?ze-h8J-}>KFvp{`@MFjSw6Q*F?O^RTwlrc!`mK49D@=g44xT(QIV8kR?Oy%c2q zErnh6nkJ`*#x&;1hNGR{F2F)k!c|CL(-5z;YU4A-rn?C7QPZ`vj#voeLXrGb=oKTkZx}w znVwdxM7eI^qN1VW2zotiNo`+t7G#_h{!|ryGpFGn)G@o{S0)&H2Lu@5eEcG+RAl;>Qq6Fb4eh+wjhovASei&!NTcOd ztjX+HQ?@8Mn!qx+=8K0-H*@!0F1x8m%PL)8>mZW9r|V^SeEU!BY&M-8Qk{YnmHYT@+zmoDZEuF8y{UT`&i}}>QB|KG+-I*{;_}USa#mT5 z5u|GK$frb?zsYR4=(mEfixJ)==WaX3y9^|Lr?uK!uy3qoeD|}rq~bG0D7}ZBxWU-3 z4G33E3V_{VyqNum&AjvP2meN7?qF=Mtvx)dhHmm*4!-|2q41P&681!pVygm4AH6Lm zC(*ZCQIT>PQy!J=>*(mXauCe+FA5lseRxw(YZDG$7dlFHSAW!{^{*`@zBX1%dGuuO z7BA-I+hVZ(G~5d>9=DS4+Z&+QE3;I>5iMr^k&`ay6DP^09ON-urJP@YByvd%ao_Ot zOcM-b=3vsh`qVLst4T@PM^;9dlC#->cP%TsfoX}MrKDSgsQRkrKFL|x)Mq7TLJFENpYzEgz$0mr3OoT>rRm1-1v^XF)ZszlGUuA^4 z{#~cBblJBFK`YP!Y6xpg^OxP=WCf>4y}tNzn~_j&?FX1-=6I%8(US=N7o|sZy(Q$k zaI!yeD$9(~UT`&ebz@D>(riwVi%$2)>q@4uMitP0=u4wG1jjzRc7c^~tbX@z3NmP> z6!_4s>6BhDDA7gz2>CgrId^s{{suT&F}}P=5!cu_*$+I)q)>KNd+>iMl}jZ0J5wL| zib1Gpik{cpniFllNB7+taWHee9aO`{b00ZqW&UA7a3H%Dxz&?rcM zfAs+|Uh$JmLPQ|oIs3Ym)tOCOwYYFW;#bc;2W3)|_g^M~{tE*vHPiXQnpPH^3&tkC zvr3`e{hBA$FB$cWIWJxD5ol(n1oLz)q>ZL{qI`_v*I-@MlL-@c_MYzDNjFB35)2B( zbF93&@hL!tFU1+^a;lis%pXkA{ETv15oNzcPQ*Mr;6Pues#T+$moHZH7xGF;{YgN zd=?FL;d5Y`{@rHt5HKVc1ftu+ND;Yr!i|j}JU5I-afVWV!3Nq;8_7B%I-@Q17wl;Y zb?LCoo>zcjv7lW6@>P8OD|I0IwiM<#Z<-*Hhts%yO^_@j z-oHf5lgOJ05|g}gX8c0dnyhBYj^pu@krUGW{SAi^FYL{F%^Y|<+ns*idz6O_ zoK=N8C|!n59UiNnlJ5pGGE&8hl($@Ogj{rB5)=3F7knMMCvAT>T@RKz3y+EhcUdGQ zKCjd5xF!=)q-U#hsM4Mz&Kg3;rrQ@*3ymcyLH{yM)Z@*FTHY8nc&o^wJhs!dy!tlC zD-%c-2~90Ay&eE?Hs?E&xkHSZ9Q-v&kBC*Z)3m$#Z;J z3&}Sa?EL%sI50}Rsa_}bBGqkTtYsng)-oe9btRa?82F+RDO*}ER>(Cq>;F1og^Q(S z-u3ZxgPu$M86W_|;UM7xK+SdvaN+8CtkSFY$g$wf=@;Wb_`Er_4Y1=6DB zF?tt$LiM~)_1`WuAQ9n;d)cpNWUfrn>8i@9vHI|?-KBUVH*cPs{V9y&8&b_#os$G3 znbB=ev<+UPnK8NeLy(Xb{y{5z-Cfll%OH) z5^9OPP-(R*wR@Fjim6@u?-MiV-vKEk;a1}(Ix4lD6M(G@zeh*6K>;iiFB#X8A5kg0 z&+W#{)&!(T5__QIw04igiH^TNDf&AXnX>)NmTlx*#njxyvyPV@p%Smo^=n1NUm`cwGM4N={d=Ez zdwMo@$^Kyo6Fqckc*gs59=d+WR_^oacmSl^yH%@VRn?Q}p)Ib{@0)Tf)qvE&71W9 z^mhpf+hGFgq+2J1GrYI3cH`c)H-{*hu)2A+bFs6g>QV8Lf?JV#*OhdN4HC^fKRbN< z+)N9Raak1AwYLOeCg$cY&paHP*e*o0{gPt0nHG<-hTmmmsJCyB8Cl+Z8_3$SVP|Yi z7O9x7slSU^V5UBua#+Tw1@G}B5<$ksY{{a$iuk{+QcqZa*gWE<`m|hbx_b?9#m?H+W;FfxSL>Z>_EHqpK;P;nkC#2Qdn)~#SNlG_Kc6+fx{XWFRc

Qx;=0!x^YK=Z>qRsYuXX>?K@*A~b;X8h&L1f0Z9XhrDCzwuNg;7wV!(DV zZmd5)GtcIQpt&*l`O`EtJRSRMo81B9rz=h&RQ> zXmj)RpI^imlwv~U*6Nk>XrgCr#XLM^ZTg4U6_9O#@5!>d);rvf+_Jf znJ>M6i}<+Pe5fQ%7duFMW9wZ*Uv;j}H}wK| zY!J(0*n~?EW!_ymKt7U^lF;oQ>jmD1b{lo$8clo}_q2kBxX*O=VScdTs&=k@y8eNq z8a9YQA#Sim+NI4Bc`@l6H{Q593AT>oEd{RE*yX!XZ-5Uj@B~<{0jVdsNm$g^Gbg>R zgY5H_OeuLtvlqF-=amCb#`cz^pg71|-&30~F?h+!1iS?ho;bS5xfm zO!^#QDtbiEDM?W!B%wSxqYjmJiZ`SE2>kroPvarTALDcja6G(9IoZ0|FnBUZ`WgX1 zh}ZHz_352k-X9BI)oYzQ5^wQs(&JU)SbV-M1|AWxCLX?7Ni-Zlw3K&m4+ca%nYlP) zkvM_BXe8dD8RpqZK8^$~N9j%L_@(j<`;>Wx|19?=XO;akUl1=FysbpLn0JN8k zC}VM_^%tK)bS7LBuvkJbpE&k%Y7*UT_mbhGh&9cRF;^7YbDdqj*dy1-h41v+zsCn; zu%Rt}f%7~;XV_D1I`CR+;XxlF?!o#2Tu6jmkns zYu2N|478y)t_GUHcM`I-c}WKxv_~#`nSh`G8Q5^?hbPE_#_VHp(K{b8`3E)6$*@3~ z$o5z?_RYC6t+8|x!ZqyYXLCMIgV&IXIIk%(_D8J6Y9%;vS1TDxg)YJQXR?!qo|4?e z*pcgA4Y1j^MTHKJmhp(NZ0EDH;cY!yBL&3*$BY-%(Kx%e4|1-+3ZPf0h#30 zeLv>b?dwP*vvsQfj*oK&#aD+ZtPb`EvfS~!QK?4+Cw44(y2%=LEyZ0Mq!#sQ=zLKm z3GBufw$+3NIOj`csMN)rh>OcFT$-0hWB2Q2OMVL~lQ1)9$!BAIUOenoi&tFr9u5;l zff{>wcZugs6fdM?{w`oFU|!%qIK2LP)FrqpAQ{bNDve|2Mu-dzitvX+?lXz1aX;d> z9lpCDU)2VWNnd8Ng$S9Dxc=)X7}GK)tjOZ1|0u_j8$`E0RhW%+{s|)SZoEApmw@3S&fZvU^@=N9pZW*J|I-4%&`ohIW0TspeC$p^S{$!Pme%C@_Ll!Edkw}#k>rZ0Y`gO`(zDNtbfD8QYAK4^WYmeIug_n*llcewW-@2EqY}=O-Y?bs&q~FMym!*6D_izD0Mg20;$b6)bbg*u-ZWM+la+p*J z>(4b4j-qAICr3+jqw&o^6t>i32Zf)`JB`F>`x+-Lz*veBUb*JfpG-Gwj9lX(jV?@a z=rfFogjDeQ)*l^P{`daC0^9o2?A0BwpM8HgD?CBOZPsKSKQiMAMJOWF`1%kKd)1_^ z<`0r(tAR8}&z`=$PeaFhHrj5%AD_$w6qHXwe{}YFNjoA+`$O`QKoiE)^ic9xz0c*J z?0I+k*u>fRTf5RV=ol zJiI}aWEWK$tD$)eG#NT?aAN-bePs1LX3F0wTB;~}V`Vn)rI>O%q4I2GEzSyF6yTB}8!L{!82{$m>uqr#>zE6X zdij2Wk=Y|Kh2OruUgF`3X9q5eUD*7zVd8(DS^ zi-Kt)s-iTinVcBO%5awj{LtfkEfH*^YjzMAxK1&%LSKOk~6O#+$_u8A;;G51D)NC+$2}Naq*T*a}pqI2V~xxYVtbsB6qOu{`@P zY$>WztpXTZ15=Jy4BkzQuY}n>sB~P)q;bx#kU&lL*3TsjNSI$_JEQcBMVtkMi%tOS zQ5OUhKb)!k?PD*Lax%qhH+JO6J@5;eHf4MzXe|9TW$J%s>)NVpDMQcCCa^v}05f!c zB&(%$zR>)N%!`0YWemTUME_O}GAB8E@5Xt1Gvp9+e$*OjTJx1(aQ=Cwm7+pFd(EGV8 zB{j`;WSi+5n`C5Xsx(^_Z~EkeuZ1@W5P5NjjM5obi@&*&-pm z#-#G6!yL{V-j{T$M!dcF&Vu`L)wFydXHjxn0Opd zZrf3R5R!YR*W>O0QzK@NNH&OFRUCWyvOagCWQxYM@WpfN`SIVb38oexI4ugo7m>8L z#Un$dv|yu{m+Adlfkbn%1QbdOc;egVXYVH>=C2MHNLkc9&GDXA$^ISdGL7Tz930tf zg0mw`C|Kh;^M)3s$;V%bG&GkH&a#h}mHXX#1=q){EoAr?qD%fVNX}P|uWlwY4Rj77 ztbT;r-q>QA-tK(-Wx9CHNrko+^v|2k(S(|WC3nxx?>>U7-ZKV>T61V)FzMDHAGsr7 z0Z%il7g>OG(qDrg=&`lBT?-(Mk_1{&(}28#sd@9f8T*50PEtxSUU0$afN0m`3Zd-c zBXxCs1z~3Mno4tHqWNV98)cz}Bza3LEke#Z&&8xpm(H2zj&@%GZfZ>^|004r;dpok zudKMI8;y0MTalx^YEokKV>k@&og@vsZHi7+FR#g6f<|PYH8Z`{vec?3IwY-#m+A$x=qM5U8!#B2|I9e zqw)HCj}EDS5Fa-Hc_bUJ)zv90BWYSN=Pe~emgVkSUs}bqNc}%V0v%;}uLq#d!1)um zyuKNgRqz3*T@*EW%Zg(i_ywIbM^ugxkJais3@T<)-!_E9a_1}5UzWtb_3PZ0UC zMK5Ci7Ie|Tzol=FuSoAfhiyTCO{472ix=p*fU`22XXQdp|)%i;9dP1pSzHqK`)oFOSgPGC4rl4qp9p z0Kl1Kg0cb>pnWs(x#u|_kzfpGqB?*x`ocBU&ns*&wZZ;(HbDrPFr#Dk)tXJvT*%P_dh=h?tF#oxL1fxd^)R*@t` zC$cuRqtUg4wO(Ccqy&3xZ=d%ONH7SvWOd6kp;2z!Yh=CSla$}aZmi@m|IriiOwaKJ z*aAJmEog0SZu}8K0Pf*k^*p@fIhXW}w)7xfe@kQe_2D&Iw(1`@AMgCNtb22UdcXhl zKV2x~J?GRL9-GZTenX&eMDTPAwei^a(dp>$%$)y0Z!B2XXw|z9Z=#cV(g$y^hQ4x3(cW}St(w7xE%~!n)Jj^i z>Ch?Nhe%(u9=D?j5}4zn$xXr;$jY@UHxQqQL0%3JMvd}U`l_6n=zOGGz2ov*Wp2RqIr#^n567nY^%)S(|qA` zl0AL(23bF}g#hcfhq!0=mrQ-qmn`gP9UHd##H!z6Eg)x$24mpjIdMk$+{mRpTd z-S-E?f0RR-=yAZWVOMtdmqT8r?OPQPQF~7tGw2Z^80sNyBma1dSxy zaZMSSRT|D~_WDIwE;Tyn8+kSLyHJ@O+HerWY-IB12zVAwnTe+hrbbro!T)FCA$8ED}UX<1)TDd-d8Nvv0d7PqExKP8!Ueo>c<-V7+%fx&D>RmIiZ_hBT7nOB+ zf&mI3cetDJle;fOb?WiwO86GMbs8z3qMq4U=-R3UddjC$Ab)t=!jjvgdK2BU+?69y zX|Z$BsJs%VBw#vG>6{_zau$z7vObe=hP3pV9z+9HC(Ph2)!^x|Z#%VEPPxOLKC z<@wK?e#6x65?i4W-nJ}N3$JGE#N~JG1yJ*#z}K@Gny8A$i!BTuVt1a;NTNm8d00i) zcMF$%AB{}+&9UW{E`2F%k0%-EqjC}L`D1%9+nE>hnWcSh@2PNXlZDUE$D))^i@P7( z5*2i_h`-B0HMClkM)#rCmBSC#xuFxXQwymb>~yqi&Xrg;A$$S(ai69AS7(i@P5SJh zNy((y+7Kgi?>b=iYHydz(uK~|8sN=KAUiM?%txtM0QyZ_b+Bw^rG)a-&E~Gsf4VbW znG&rB0>-@0303z_=1Vkgo9WJW-M|>ylW} zlqIDc8_LJn>uztaBO_{xRgzgnc9PNF+Xu*@pVEGD6{uAMf`m0v8Op0{czl&}&NKpd(3P}|pz>^$B*Ws~?_W$fzbT`5)_feLUl1IfvNr6n_) z6)tl}dd-Iz51!ad?CL<3R1E}@O4Z@!0IfGRk|X%IQ#caxEZl_i1#+KS;0U75PryN4 z&*_L&;FiOYIkYA92oaz57AMQBZ<|>uCU&G_+q*9;iH6p!`uv`#q?cjUJQUQ?KCfYyz( zyD0rUsf4f1k)>&xT;4+iXxO8yBCi)!pD_`)zlT6DK=R)n#tF<4pVy9pUEG=CPkPI# zRYbK4VClCMuiISBV(n;i;>@oJ9^FLd)&;NLxm7y*?N#s{{VLv`zPm)A)!~YH#;q`! zFOBlq+R~I>NnSh9VZ7EsG{D`u>mq!pnX?o)OlaZn9LKHq?clXYuI zmK9t*-O$x+qpn*71#=JQ?C$f9``NSK=+JB+Ipn!b* z@^)r_QgM($uBQ7!o1o9u0HW&M{&>WrwB_V*{qv5(kj147D~L`uYOU}Kt&Xb% zTob5%!JH6Zrgsk{WX{Qb43vRnb~=$#wFyo?rO$v&N15StpgTNr?yG7w2e@R)0dB`9 zLiqH_wgKzTH7f(v1{SZrSP9lUqmOjgS||i@B>WvDqM9LaZQ=pC#y&UUZ&=+BA0QU& zc1h%fsBwI|PZZa`y6$B5tD9@{fKeg%ub?SI>AM`(cLE4!?AP?Ewg{ser8n7~LtvZb853t%CjVdKs8DDmzJoxVH}V4i5vS&R?Jdvg+uLl5ae0R6gnhLtkg$eiab z6D6Hah{d|kRg?j5mk`M5#U=Mp%#9Rw61xYQ6&(dasOCM72oMM>4FqALFatD66L_jm zUd!}EZa4fU)TCU&gL?8?$!ft+XI}Rp)0+#!{6oYKDYr6SJ`|H=;)oGCW$-@lCEC>q zQ=}nUOkmn6Rav*E{If5{|LE8f4F>aT6APoCp)634ZfMYa+v;nsp=|W3#9y@3cw2aV zQ7|{Aa8x=QpOhRVGt6cP31VPh?yPV%D6OZ>g5xqV2YZgVU9JzU?nYO3j#rU1C&k4j zx8EnoFCQ`#y*DiKJ4agxGi#%L>NUH*@JM6;qvS$)XD*)xS0+salp&nT`Y@OQnbRrQ z?%{B4IS_qOYUqh8O3yiy{7mCwwO9GdtfB?m_1Ee_J!8lM)ZPi}fMmSH=f~ezxF6Pf z^gXTtEQiz=GbKoK13>`3;rO{58ZlwQbyqA7;gUS>+=L`qmcs02@XA*3_0&&OK#m&! zTv{JS)=LLhnfOY(qO+cQS9G-%l;%#KojYj-FFnR@HXCXRmxzikZT}RKD={bm1XlO- zp}NYK5Att8N0md5i^`O9j~YePhv4d5M0=wASqU*hkZ#_XTP zd{5|)-Hok(+I)*;0zM9aO3M*GX;!9*&N6CNn%9~B$4du;8_bfkxrkOVf2e9YEN9jM z(%XNrh!k_dDNK0*>s=6%yAS}VcQ0K8%JDs&_hb;b?-%bWRg7Kpri|VA>%Sltw+jO$ zY;m|nfnZE$=u8V-S;)uQvMq7SuWtx(v1hK8md`N8pZ6Z54a!uei3XbT7; z(BdORJFjV|@`LU6u8QocCm3QwaA>T<=@Ie(tA&5t0zN71T8>{JmHPr^(zqTn7j|nw z$YK`W8fb)(AZU_h`6y_u)lh|om-q;ZR&Rs$I>tFjR!8=#lFlo%O(^lg*W0+{_5@d7 z?W#YGs2q+?!I?n^a;#qJLbK;AZ5Tu_|xu*6wMwU!H|+>sOr=m7$*DEm=L z?M%8@>PMSiWux~mGzp_i&YvUQ-^{%RLWL@(PUzbwQnOTKCWywb2v%DiMa$|TwKeL+ zuK%>>EwUcJa%iZJ9~4TE4-K20W%A9MnYrc0#|LtLaOh-Jh7WgUoXv!U45wAKg9+Y9 z9J#Fala7D|cvL;p_4P?eUn`R*&g77s*IudyYve({423>DO zSZxbp#55(NlEyC?p>o`=Q!np_^$rq^413K45jm?o3(<*cy>fZcK>DWgt4?0QC9${{ z#t17xhF8G#=k*|~sn}}9L#yM$LE}`51KsbA~$vu=`eTjYVL#NjDX#=M8 z2usFABTgT`Ow;@fEp5UT=$G83*g%w$w!md=o(jENKrJqrmzub^YgJ<>@3GH{UBy+g zwzK5dlv%jhb!@l_LrN`5u;+_zkm?%aeau<$Np(c(PwJ0Fu6HlK6)Am0f%_F}YbE1{ z8Bp=mAGPUuTMy6%wqPGUj`IGN6yQ0hbu*fHq+H>B-?s3L9i`x(3%F?sj)rXk?B1!nm4FTPhlVw`)y1wr3&5F3o z)PBjDFC3|Gd*fty1twCaauA(FCt-OJY0R-HoA&(4QtWE5K_YqO0Yf1$-+$yJTGy;A z0mk&-?kDFN>5(}-q~HoLY0l^5hWx&yrP*yO5Aiz|P5@Y@gzKNM9PzxE7e0QR-#v07 zv)7G$S-hI=Rhko0yEC_?;G;w^Z#Nf=l3U+%!_$+Dnws)A(7vUm1tCbwdhz763qc^* z-{nCn$zlAthp%Yj_n&W7U;1fROXdS3$nPy|^GqrIK+})rVcWgEfS<9(W!f!IU4?iY zOH^i&$m>~Yp(_`C(bLm{D|5n`)R)KX-V`#5x6l7oLq>HxgICZEaM#Toi6!f$!TMwC zX6HG`?4PSP=+rGLyK*yAN8F($UBAdk5+63W5(#T<1jk6xbE>YH$+oK-ibV3;e@PTb z^$NOze*Y}zi{@Zr{<-BIIMu}3CKxmH?)r}-f0BcCrM;B0Vk=EfXdt&jgh8&h|HVsr zL`S22AyF4n&kq#EoY|7Q-$~XY?FmxGN&5v4cbE=U+4vxE8rHl@H>(-gFDy)5$HOAKJ7ZRd4e0aa7|>HX`5 zr50KSyo4qZcf;QwdgCRa1sZUuZG3G2OxABL3o3YJrC9eT)E z7D2!ADLZWi=H8Bi@ZW43UIX=APqz?aNDY~YTl3~q=Zb=SW56W$bl34euvV=*o}&LI zLh`y~01sD~t{OEw*PPYe6nY?DT7gVEJ~3?aT<8X@A&0vp>iGyaEx$P`vxw7~BOPC5{;n(>}zw2?&of|?+wLUQR^o(I(F224sx(~1S z7Wktr-1tV%8h`x@Zy%k4J45PbX9bG5gVLpT^>k_K#Fx1&A@>trBRe+(65c zKTDpB$*D2mDkmrLKn)`AP$GcrMB47YT*lJ<#FGQs-r)U52-P18 zPiQRfM;6Iinq@Ie?FcEeJA?)DBPcEq4cLz>8@bwII+EX4uafb+2#+Q2ct(6YVEGB~zHb z^P#_G_$;03E)#a`5>OtXrPssMGxj&L&X$7VgkzwMiVsd#JuN#Y-P&-wNoh%N3P^2$ z-z~IzbG+kOvhN#AzEySxS{e}%5KWW`N$DdwJ%1^osjWcg)zHzweKNnGdE||jA&)(x zGkx`sB=Tz84w~c-%SnksT6R3wwnd5Wy=&8nib~9}Om0nZ9c|Rd_)nS(yV8-dHbm5W z;DoIsDX}ZUH3Lcp!&g z)fkx0=R&S=Xl3F-T@11hPo8sIedz#QFAoT~UogemsG>0u;fUQ`gGA4YvTx=lve)Tg zt|MfXnogVF7-rl6eS{@t#0S`4fC)HO6ry_%60Sq})SGDaDcK{BHfy3i3y93}<2Cx7 zxE{bsUj3A&i3|ui2IVq8cnX0gqk>c1`IRkfFuI|kk?Otb*6Gb=F?H=S15r_E)9HfI z`bG`Z0`6}|*0WnhRDImM@~B_~nfWJ3H(6(GK^)tpH{IHRtx`h`o<5SCFC!!)V42_QktIM-8|f)Z^qwo2=@(dAfW=e0&gKd7Y~Ly_?tr zF)Z!Hyoloq|4aib>3Hy1X`?`wO*$wum6k+}C{o$uXs0Jz`&;CBqB<0SXUB^>Z(ca!Yex$TB>As{XP z&TW3;^qS1I#M2Shn$g|jFQtFZ(kgsIp~`oo#rrh#N&7jWx!K<PhB1>rF;h(*|5>xPZj)?*9!q2PO zodBW!B|el?&qB`zo8`aJ9*Xbs2!FkcDaaHNAUH=`f{+`32hckf0i&C4|op3IgwkE*3) z&kVtW7rNHc03p<$)yn5a4G3@JCH>lz*#}x8HLiI>uA(jdaqPgEq>1WOXl;sx?1NL& z)KtOB|4eG}i)B;Hfm&R1+OZa=*C$U}U{D)$2vYS8ZhEnbWA;Cdy!`zlpFY#1MYn7d z$XdX~|41rsQXqI7X2qWvFQbkMl?QnvFa*B^%l@QYo28G>R(`t@C(97ooJlyJH+$Iv z?SY@5{M*Ko$w}3f$C4U$ckeZz1FH$^#Tdf^NZ^|3{reFSs!sbigF^tN0n{>GUphm{ zD%=^Y+{$!shu$l}KsZ$1VoeKPy@C`M9|i^lK$bA%L@UDK%ezu?VrEDUewMI=%$?)e z%cPvU*k9o#SDj`>^SJMkiWGl+V?*r6dXV46Wf`X{FsddsZxyH}|TJ(=YJ7*gkPf=0|{4IXDeEF=A^vU$6M?`%Z8a;Q08L6e^tzMrkBPtu)2 z#J)hM%|rkVo!JSZ3s|`2nJ$UXMv@{Cba9XtTz4QZUI5J9{e;$MT6Y4~Q6BUZB%f+; zRYGbcAfmAJp?A5OoG%Y>x#wQ~j8`t%@W$TYV&3#^c&O=UYwM72*5SfSx;0Xklih0r zH8QE zWmf??*t8Y;#?TUgpA{g~dfBl#;3oYP3aN~_z3tF*>DzZb z<8K#-So`0#l7n9oT5EiHncA*(NgRq~?=Qfg2j+n2SU2QP8nxIK!Ir~Kh_+;A6qopT ziiD<)bxFDF({&tWe6tgLKl zmz73N!lfox{#zBs8x%nrP}qjiwVLq3gCq8&E6$`dj_qPT^)j%UnI#LNL$ly#`)4Er z)0(TJ@t5stW@imPv{tQ3h{esX`+$ouSX?@T*lv2Dn5=74K!6awX+ujTnyEpZM+m6| zc?|GxA_8F&NENN?i+`)gBG=HSCH02N8oZBZ*c=^PydV~gS5>7q4p-KVn`MzVYXF)h z5WEDN4clVn<&w~vW6BY2F!OH586DSY;y;~1<;^CBnCX)%Pr&y}Lir{KXW0Mt9z2PX ztH|`KB3v}lw;|~=03Y2QwQQ`<5uHOS2|7+Q{^VZWvWHpQVU1?}3m?@G5p4T@;4;7p z_w%^{6-T?r_60A@<5|Y@Rm?fro*Z6{{Uegl>hj=)G=ia!mtwiqLrmM_Q{nD{(3vj( zyzINcck^2m9Bv#poNZ$N)7Il6HFFkmg!;LN<@HqU;rg5JL9K%HH!>$6JwX60%81X7;hl-g|S9?bsaq@Vk7zx8L<=-AFI5^Lky^ zU1rp@Y|YoM%+NM;Tk4Apvg#K^FL{Pp#hrau9diFG`D1wd zE|Fqczr|qimw}~SAZ(Mx3V)QvWK~Wx9-hY-<<#yUl)m}W_LAqis&oM(&kAAkBah~c zhcE>s4Ma!dIH%4$CaB1jO~(X-m1r!Rd37|R*j`bSe<@8Al=mqPbR0!@h+p$E%fVtB zVp(3>u;0oDlD?~0lQbPEpWw8T!8j$dC$7(vHc%L22x_jAW zTCj>jro{eEJYCK5#dD9bS4s~q306wuq5VsLFd+!>kLSv0Urkjp$!m+6Opl;(QUTnE z2xf-dU3q9N<(?hZaa6AOUPRytuTlC%(pp05n{L*;2=it_s{3!KiF9l`#xCDi8gd!9 z{;wV1ac#}OBRdPM!?mFtA<4&qEp&L4+Yo`Yz04C$M=w6i08e?NYN95(wVp$bWc~)!BSbrhQ)@wcc9)owL?SR3;Z|He#EW{G^!Qx50R~){U^0DbSE4NQbD5=calUDydhdd(neK zffl2^eFRcH;A0j{K=WpA+`tTbW=tKLqZ`q2Q<1#C50ruI%B&*R6@Bap*8jud3*#T| zvt7HJP0DV)xgE+ActswseFJ}6Szj}c*d#8sA-4BBpkh~%yz9Kh%0m$_!yg$aXt}skv)#o?n_afB`XR5vBdig7rasm zeQ|$&c1c?-VhaOb^4GoP1iO~vva)jlGC1@#XAp@X!&9%hU@MXJ)eEz6OwWCV?@l)b ze8j}l#Q$!vF_m`fPp&VT6a?-c-ACggbVDx}L${CnUL)4h>FJf(0TVka{_x90+~~#| z^|qxilomeBs*L#n!1lva9IjzyHJBqI6-6Wg)jUuM`KM?92>}s0;;efb`#Y2Qm-Sbn5vIuy5&vb1$5#4T?Icb`L?f)!n<=b^^Cb z>%J+)4v+_HRjyhVxVwK~JZ_Nm+wJTB=d*&40twKLFh)DrmV8j%u>Th#sPn@q`l3Q5 zv>nKUP!bV#&imb!J1Q~C@gEdsB?N|ea6GSNkk|K?SijIB=;o#Fzw?=gW#G39m;Lx| zWYKDo!0l&trX%QwILL@!_5um_WG7h&McK;LX;8zi5!&V6zhE01>J zARVvq_*YkR_2Ex2$_{4I3a8No(~@7ZXJx_v`v^0;nJHC^8El zo`Oii4d;+AfTg^Q{$40sO5_Vj<8kHC5Z0eUJvKWBSE~~GLyS4`DnmD}x+-QY8S)?& z_U1P0N0Icc3@MzTaqWT!4Kn(6R5WW48FcZUe$95CG@A28G4xiL$+t z;Q6;LkBGKx+H`A7s8TY2eUWQ9)XA(q6E*7*lf^<8DQ^;>_f+Nx*}63LbDoS}%(n8! z2;>iQ$Ga^BtjIkg8VWg&P9_PN8oA$cDlcuGsXN&R<`_S6&{y!^=7Kt|U=JYk`2bz|+&*4YuvJJ*xz z9|CfADgsA!3Ht0Z!kCpvW8%hW@wSw(R6&9vA{k;ILzpwv$U)nAWTgH0BBWG*+w&oA zd_PmV!ocY!cjI+?`{t{aQHVzlqsN_t7)?Ut__?tG^_6hba}9B#pzTm{PqxoRZLreX zfz@2oxUUbo+)bOUkI*woe%X)> zY(^iOg_+J#3^7ffq(NtG;ftk>o|Pn!QycrF_-{i+GuQXd2! zTvF@^G34P)_vybFL+}gVECT)~H!I5z3ubg5Va=OhDf7K6K0~EnVX_V7%YX3s{n-Ua zu^PCCHCJLhF`h70T`^u~80IowP5nuZXJVp@!}kN}?sP*pNR11`LE9Sn1Sbe}WfL8K z?(qghZK7F+3&g$1OOb}w%r3|kxg~nMtzj%1o9g>o66e*3nKV_v0BBzV)A`yhXLTdz z2QM2mo;NpCg)kn z^$|wWnLNrtr7$V(O&8QevWe{}-0&x@%G*6QbE z%4bf~X!GjT))WU38eB-P#9H4xHEfl#o7X|@*Lwr*+!0W>CgHue z#FUfG6uD`_DZ-l~DFQh?pD3FhTK?YCcDU->o%?w#lAf^h;Zw|!jUh4i3VtBe0MRQn zfnWHSU-v<6u?GGu7=7%Z^zC*8awH6q%1Wc?INPiks!q5|4}I|X;Bk%&z(J*A+}27_ z=O|;=*Z~}i-$E&0^Xl~52KW13r#dl`jZ-Je2I*%OC*g$f#?OCEA63$2$N zOZunL4&14KR}|*+Q~2EfMvH>1{3U&1MQVBdbx_z{;%Dh90RBzyGW~`?6P3QfZzngh_PD|6-zHxjAC)an=H=hrK5H#hh1L4eGaZ89n`AwN|+)|nuf2==fe*FCFt-QFaO0W zVmNF^_|!&lB(%sak7k}_zFl>&?cQGXL3Dt^Rpkeel*qNRQl{=vu(0XZ! zRYoTcv>-Hij$W05iZUo5s%vU)RCHd=aWU(NMaim!jc#9_ zExtp*nj^MR!FE#{XHnglxF zjut!y&l_XCSf6*-a)iD>f0%&JR?5yltVr*dtKC-_CFN3+q9tTtT9W)DAXjsZYOsh~ zg76ysCAZx0)B0(y3Q7AZY}gc)HJZqm^X^q)W9{%=-n7tv5?_yHQSrYjqBe^*iz}nJ z?!WueW@Oi7OeU7w$$qDENc!2wR90VK8fn>48$rRO8ncS1^H*`TFa87H+>nNjJ0SuG zJ5%i@8UZRL+S_APT-_;qz8N?A#i_(K{*R>PwB%dMB*MO2>+yZQoa>2^Ce@`# z<3b!q`6hiACb1{R<0wBxadTSR?nLORv z&IOSN&#Hi&8cP}g+Ld&g8b@A*%I$9I7LBkWMTcvc_DzsGaymFi zj-+}!+Rg2qzb%m{W#biQXejMI0!+Ac1TDrw8k_d@X!pK%mU_|WU)z1-6C9#m zw@E__D6O7qj1g|^%R>tSAipLAXJ@s0$TL0aHS#aJT>kD_>`hKK=S4w8Ukao$Nc(;J zB;#O96rC4yq$U;CW-oMun11+E_O`Q=!-}h?cysHAp0~W=`0sM?(@e13u{4bMrTX`8 zM=Km9-5fJpKlr_PQ~7y!t@7Cu4F_@rZ{gwGRe+cIRAs<7PHh_I4a;zKVVFvlspoFE z{4O>(X6go^Bk8N%>yXg6_iAGbJe*Fa2Ke6#-5J8^9Wn>wtG=qn+k2-=Y;3iLY|Vyg zTalEdD)>;bj}f*$-56N2JhVcax5{|or(f#S)^@wZVUd}W4qf0p=@Htw!fz+Q3rHo8^eF&x1A0JUwk`30etD4%g&Zo;Sbmx5YbM zjt4Oz&=+6--;#NH^$gUIw-89pa^RQn!Pqq5&`Jn>g41f|dC`jdqy9rnlH1j&=E3fJ z2v3HmUj)9`1J`lmG2s-4k~BjFk{F@!UE@z8J9Y?EH~rvioEhRQ$>2KXGNrWa|Eq?u zOEjMbN~-_iYmz^2SyKw`mCt5Kla+$&yPnh1(g$&SAoF5n(8@|3N>ATX$WN5{4R5(y z26S8%C%!Z?xrp@b#FTf^KQrt!$$JwVMn#WAse7BvG`iwRqBH#d+jJ<tx!y<4`V?L{#GDQlrZw6L|!MKUS-C5fJmgj)!-X-7f8&8=`RRI(&^;i;TKn%wqO#fHa-GW?ejC zV=loYfdCRGA%vQjgeJ+B?e79eytVXKbaRId&6?|cB9fcNRN_xr5qAI5W# zA-;Qb^O?xYw7Eq3bkpPcbwfrNASkh~nDMF!>sEv@1jS=IVMp^Vsab4-o__sR&Y(Bz z$*@WB>notb^=TJCR8;<#_$%%sVf}zv?m;fp>ROUcHZ~SHIQF z9A4?vjj@F}aS1?u7kX)rk~G=-TR+Sg6+jG|7{jNw&6Yp*$sgJEHQd*DXhHa?jUV%O zw_`L_ov`}LPdP|{7qw*D@?vhe5$9U8pL7JBo4yf&QJ6$jFPOByY0B;BSmXzw2dbV~22iZmyvN@hNnh}#1IM&dn;V=Cz!yy`UIqZK z6{K9xz60I1t6}!=foVF(3v@s)FW0)*f-)_3M!z#t3V_ekCe(@p=v&Ftm9$o2Dc zv#^DubA{`k@xhvDoQ0)1jhrqvJJQ5H+V6rFoRb$d6ghtOg_ID}q^4$0n>!GQ0_Qc^ zV*F=Sme0vQXc67R!sn&p<-comS(!gM%3O1W$jRxVTx`41Zx0d1wf}8x+u0R-86%46 z%kD68^5J_Z6aIqSI$j}Jw=L|oAzk;5D+_r>iriNh*pHMHnrMnJa>Up{1-frr=zZZm zF*QaPR+n)3H&`Q+j!r0SJwD!AhRqbk<%3$a%3AQmx!em?PylUt0D=Dcb=uQb;{RF} zPjLM9f|z+gb;7{4k261@#4kMOUBi6dzR5b~-f2z~2SRSKM4+Nlu2LI#j-3tM4eNS^ zP-@#C!EH4>1P%-_e|;%|b~AvqyIC#eVP(2&Bv;#`(l?K*S%qM;r1dt#BjcF#$G?TR z>_4RG@=n6W3=VY$0&d1_`Y-Q@ob&o`$G>z2(CEWF={Bq_CiRtJvAw4g*+P#=db%pd z6X^jG)ASw|Ll%J&V(J)`E^BdkPniwWzX4&gD>;0jkDi_VD*YSfYOink?fXh*MR(Dw zi(D-!C3H=ETj_Vpf=z4|E}(Xi@EaMulp6xprL;7Ag$=Rgp5JL=D?oiCR1^||NS%Gx z&@-mW(Bvqh$RJ}*#Hn$ANXebB+Ap^;>|qrTetwnn)~ziVeqI zb?oVqZbY|JLJ#X1L#&aiDyzEA0ip6l-jp8h*1sX|<#v3Sm+kyoi;qgdeM(wZ$!I-v z6a)Xug-C36XMTg^Q-tL4`1?j_xgEQbD7E5bCIa;;yLfb`tJ=+`;Fs;1sE!ff*#uVOP8ZTNJ zqCoV!4$#Jo(N!B;I_%z&eo)wImeR%O$eCN zG2UhiZAb2YJ`qd7c>lK58L9SnbjHrxXhu6*)POlKQxT=mp5)zWC8jcrqw#+V*h4>$U@JHUhBsP~X%uCgfsWeY(AXRo614%N5u%_`tj?9`2 zZW-zs9qrJQ6(=&bItnt7xUPpx)y~aHG{Hr++ILSbKnd{v&2m}6;{v**^w|sPTdB-@ zep!&cgpv;}1O%P>$}hy=h*}Ltfrp=v$b9~EDWl!2QR2%;n45##e?v=jAkw?0k7Tv~ zE>r#nQnI`+L^PQ&U^i-xqEXKyUjmj@nir_bQgtUq4YBCBe=^s;S7%*a?sN;G(zA0w zwI#xfesA_4)KPLExFsmPlQZK5qOso3b@j$OCcgU#fvJ7Bs-W^z*7>7_%&pDFZ z5yl^tWPG~7!#A@HUJwnw1z&E2h^$agFX5ERDG2z*xmT!*Or5vO^8%T>{@hkf@);h# zbjASZ9f+C)1<`|eNI+AcHq+2|3z`v)Yjjg|w0UQZRwu;r_oBz+$2Lz0Y46(H;ujzx z7tPT)6MG<|y6o?@WAR&xso5zYzAvPOCYzCvncr#qvgK3al6j$r>z#$Yn6;L7kUYWo zsX07y+-h;kzv{=PBINJ|KrXV>#og`$Yc}n>+^`@EKh^T zP!j1=18DO(ZE2Nly1QBZ`50vE8N@%vwOQN)<@x2UIb>$i-`X-NsqMeU+h#V2IEG`~ z`pbf}>_NWh$C5<%xQU{rHr*W^peiaNX%Zz&`LGD$Jo5E&OhSYsRLKrYTuv}a$MTfS0{M$voMJA=l0jxeL z!jBSaMInV_8x{H>bE|5J#F`sY(!#h?Dp3O|FdzykE)1fsP$mJXq_^?F`P3wyMmU)G_3PKh^S7xbyos*&LdI^^+owDQZ~fP;u)h*z=P;0o z=a44BVm9>?2sZF*FevfgdtO^#L#WQZ z;+m3jqlZgWX60i0+&d)xU(?&utXT(d2#K9dJBZl>pzF+LLep7@AV2^Y^_HY z)WWYVt4ADN{y%(8(6BM)tSBZJ~*b`(i8T$%>wn5Uw$w`pFqN zvwGU577@-H94Jq8uJC(fI3`c+!Vl>54Za&k$3o42g8H=4vGkN>Guy}DH4XZqyjN*| z-HqgEIIqWIuH1^qRHF8JgLQo?FHUz5wS+@MI=x$l93 z4J{>h@FX%Swx=?E2bDYS=(rzcMuAu&6zQyP0s(N2Zlk;d$0?rG@0wgq2e$82=5p1& z5(^tu=p@zVFHk!>|5y<{E12vqVp6jP+01qDSqF{qTu87<`} zaGqg+Uj-B?W$K{SH`xEui6lR?MX}BMgm-mMgO;be?CoYQ72;aq+S*Sd4ga*KX?7-D z9?C;iQr%emJn$Cu4bTgv0*#N7;@1ou`t^8p`J@u%T5@|lT#ddTgF)Wftmu=cQedEG z5_q4*w3ei_(z3F@5AYQBYdUcDwtoLv_ya}EJnp;IVXQ8>HKiAwX9#Lry-_PLZ_JpM zEu1bZ-*3> zN`&n_8S)q9)sdvQJ9(<_h%|m{7!b_b-eY_7^TvQip*L~=cC~?&awGBqpou0XLahK< zBEz>h0M%Wja?`GVagn`Np8?SlN4P$6oeBFDy^`(ac}2>qms&~9xbBI=@zobazcf_1 z98|PkeUl;dgRp^ROLTDsR!Jb~O$IaRZ9cE2=6|KXL7-=MpEA5}%~aYOu~NWmDAN?H zaevd1V09YPnLt9Ne=Ueqg}WK#Ui>o3Gn}t^wHx}TC1Tv?2qm49iU(gCNfun6Z}1>q zYd{@xSE8MDi-20ZCe1{2|Nc8$CFyZF&deJZ(|}|sdL}3ObGqXLJY{m+EJJz3{b=(K z>SB=;a{H%U`*GYT5Kj@6jz+H&^QHD$4p`lfa;8~ux)w?{)XgsnHgZ~+npDgKpBlyQ zS_j^cfcq?s&_ct&q0abD~lEJRFZ1So%TpUQ$Lz#`SRGGO1GKA>R%6 zoPr`Lr6@3|%YP)=8-WQ=tET_>R@ZWvnoLW)_Ewz>%gq;<=&DzpuDaIF?myu!2Hn-w zI=pMHU0}Y79iOB*SNQ@-Xq*RyQ^A5_pEr3|=;+AqJCS&2;Ch}z@`Pj@Nn-4vE)5XF zbK=U30XCAbHvZQ0J@THhq2p7UK0&R1#VPf{Uw>q#qsm;yoSHXOGgVzT?tJTWoXsC# zcc?I&|CbG#*M@he}V(3 z58_bi+#v9rM$|CS$VqrD-OH|N**M~VIoNkx_YdTIdTwsy87I3?+o3DYjH3(87qyX1 z@wCTj?XzwBF1YLGT`P1r@_jJA9DK;iK7XDnoFkYr01S&34S3lgCl^oR0p?57k?Z4U zjXB3yzc5P6dOnG0ZbAIU&$T1&07tt^5BwtUH8s7N=q*DX>;3e9d-P+RJs)g6IKP7 zOz~Z#iD?==Q|x4LAl`7^u_h$Mr-+%^=9HTUbs%Hg^3msq132GDHjXOoyis-&t)9R2 z^4#o6UR?sWoV`#<;u3tK(7aMCjggFw&X5An**F(f}#G9!aNwS^XitZc&{$6?}Bb53p-Luk-W;qi^akNUF57 zAX~?9vESnZ$Vt3fR5TRqfoSOk&GI*%nHJBtlt`(0dd570JCU*7=HTE@OzysIR69(V zJNl|@YR?aMmO^#3Fx~ZL}JXtczmKE9&54WNB-5JD39#M1y3pf3f|02u`4O@BXzsnHA{{Giebo^PqL+Tbad zdk41Su8%7LfB%UxKVCr+JWz3H8`_46F3pT)*YsDVtity45-} za>h$I{f6SgJdw=qc?1nYAN>9N{4V!9T&{j%e%~av9+Vl<_04O;__f!Nfly$Zrg>kS zNKj7SKQplG98B2koBL~e@Me+6ag1?SX^@?vP^k3u^VJvlCsPAa5$t#56$h4~ywGaF z_aUKU(26IfbG)XgO;`Kx`Ek(TZnxM_xTp4gtIF{$HcpX3k=s!0GW&62)zh{0#=FE% zeWp1%IyHacO=1%CMt1dd0=G8_HkJ5X9z*!%cZTn13pNGZ-@R@NZ|%ywy_cYiV)A$Q z7Rex}@p1E_HaLR!Jy}WORD`YWgOU79PaWD5U`=1xDZxp(kF({SJVxM@usjj>6$?wXRcUP#}-% zlDwK7WM9L$8dh?{?4t>)jY~$tI36CwJeot2Nqv$B+~-gxMp}vw`eg9;l@#E$&Pd-f zh#3gbzT|!VFg_s92U%BFcfJ6H3>?;1q}qrF1tnXU>i^nFgJ~4e3^*2t_jmp~KdJXO zvT`UbdfuR%%x_&l7I|c6d$W{$0zurexG3viO;d?~)XN$+zQ#0iMZfh| zL=yHc8wh+0E+$PixXWEa4a_--J&WG6^J6oeLUIvLJ(3v=61|Z{#H7UgtTJC zN2|waR%TL>3Ha9$Dg);;MH(P}2!zG~$vdEnC3a*b@R>i_^z5M_teyH?i2zj8x(Qx8EKi{iV2nF zP4v5_H+R$7RQSEMeI6ap>ER}#-q7fN3tJl=zApO1=T7*W$Iyn80mI`ftF^EpA8u@# zENaAti1Mor%@OM4_j{ZmSq-rTK zDK}INsrxo0peD@9beDY)OE=5>NrzE*OK`E9g@wg3fb7wLYjE|Kde7@wR7~+(^6NkR zWx(HxoXeK&abcyFDaux!r5Y|0DD;&?WTYIPfo>@**0A3Shl}#(n5T@JK*dc=!K9wB zw4$Qo=%OjQ`Epj2j=1uK3s8Okw^;b+Q9>mWI*$swk8;xIduyIB3{LI8*Ep1-{T^<) z>};PZ?qV!>@fIzb7!OQ1(qgh|gQ#>*-=(FM0~F)C zGbPdE0OGCroE^+KTDo|dWrAS2;v{A1oeoi&wwP=<$?GuODA)OiiBf6ph=G%NX%PtI zbTlufP-aFsccA3E@KM9i`I^$T4kM>ek0fmc*YLuuXz$7dk&jMYKTscUFz_bVby`13 z+Z=LPS3Pq$&kFMRJN)4Ks6!Lq2e{1u#v_y>*;ULdiRv9xmSn^z;jwTeH~N7J;Q$GtLOGY#(#2T^8j1eMeF}=DWR#=?fz%o{I4-y2uu;sNbJ;@n3dnbqv^^9(wb* z`Ahi^`uBko?`y2*f4?L`9C_!kJ7W~?5M#}wBcpKuBQyNa+L|zs(^bMj+tXZh0a!X+ zd22MRk=mU|i5RkvKlBHSR%@}0SvRUq2C|k~fB82(f4zw4ta-IzwbKEv583DF$ z+uqR(S?!pW$7t?Yrwn8lAT(Q7=tjsxp$rCG`aY#l>85{UAd@phocn zU`v2lj33I8AYTjArjL^iK2(?mL1<9)3ydMAmUz28|FUVii{;_^#LeqcnyP0v*5)CK zt76WR0CLwz+S0A2!(*7#O@K|QT$GA(~aZj;A6Ksc-(D`KQ>ff=|;uG z{M}#Ak&`@wbN>*{iwNvNg)Tc<3`d?ZEf*@0L!5y_9^$d($*YYCJ^WVmI6sQU_S(T-|svN zB36mKEXt?Jf>|-l%;MrOJ`6gJds&~|=}4Iwfe+)Jk*~eXxOz$_dj#`%$iT03?0Il~ zz~5rsi7aRRFdx>}q$NvZT0KGSGEB@dkVcGq;Dhi&P0hV#hluo}-!2uaYf*|s(cgbb zwl|`dqflPeFXQ0o;*eq8&;>LId+kOZeLSx1LTrW%lZ3xWXMr`9kFvf!MV6}|LpeELG4 z`)#52BLwrp-M3uK5Vc&~KaK>7x!snt|Gb_%i@<`Wzd-%2#tsI;(5Chz9UDhB47-|n z&J1>PW0)V_gV@YL4EBF3zJS__7OsCQ6;9hMST4d5Y(*2(AU|twzu+0r_?GkL7zcLA z<)Y$+Of@w7TIi{HMXuje1uBK-V~R-lx#f2w!3)cFk!Qmt+I``ky*gkD?Sh0B1MoOz zb1eSiRaOna4EOB@GTjrcJpW0h%;DxuxEC5IB93ed92R83`>BNZ)@?(f?jch8pn=hO z1uGvoL2#M?t&uWSt^M=mk&5VQdr++yGp9ywig3=GaJ&WTrpY-{T+pW@x^uR+GNC58 zRJ4ShuHYXY zsah^RYxjZ4=*o1(b8{ePwDD?w$id)E1AX{O8TcmIeHVE`dxP{!V0p(qezFHusM_3t>B8NY>JF%9xto?js@@ zIiL5V)$l++I25&?bD>x836UzX>`KAd*P9`~7CF3Y`@4S1r^wT|$P-y<5;;py>52Iz z7VVg!w35Z9IOQrufCa%K7vpfNUYLsTC`I zF@?PV<^;b@O`)0Vi$I9U6%b4Y!qfNSC+2j|o|^p$JTWq7^vGp!wH&Das$ghxCYXEn z19;Fqsq}U$U5689+O}7ESMsQlz~NjmE3IE6F_@_*w4|I0mSRz<(@P+1&i2?2<=6F&@d0fv(Jgsk;=tbV(U_ z=?ARi9alS!O*|4NP8vChmX?yL(uD+^w)FMoK7bT@SS;I_$e9*Xo9RK6U(G6Pv>U)m&z5Oj$twH-yn$-xSPdk6rgKG4Tv-l=(bf9<*Nglx z)buFz2KKuX0FG&Jeabqdd}3Z^$|X)~HfXISZDLC*^`e_&?xwi(sl5^1L1Bdz-J1#< z!+b-gNH-vDC~6|<-Y!J`FsmTWbicDeN~C944U=hKMVSbYGrE6Gm^%&bZ!Z&+&Dy4< zdsy-z^PkIgqo?npbFQl&$-@4my@py)?EAHyIb9OS0_drGA~fSxOx^j&cQ*3lUuDbp z1ftt(tNbnFJf_Ax+4>hcfgab5J$R*co6eU*OwdVtHnsz))g7N5dOe*v$C8s?T7=g; z-f8tU6~Md~gPxNn{L}I3uZg>Jpd#etBJwn;QetzrDOv^_tFRnY_f^1@>Q?I2^~T%M zJ>-P)cmKYiws30fl|9wMoYx9Y#v^cePkG7wRgt-rj#28C`z_O-P`6rf?lco{E#X1& z#+k*rrQZ@#P!X(3E3^5t3=R)DQy|Ej9c)^5M+4R1=Kg6R)E^T2F{5gE@hfb7`gpWh zdEm+lf){B3F5dSM!p;#Jicb^pb|h&tsXi}UI;}chCW)3Ee+^Faia}81XcTjV7?S)!T(GJ4C>0%OtRUZb<$>4@@CuZ^0|n7JvogTl zTTnLnmQf;1GlpZ*;L%xP-1Z`7rg{i*G$?m^M8g>rPv+p1z-d(LXVB0)kn_hnkg1l5 zgCk~pj*CWDZ~r3vCBo#&HBdSQ&sk*Fv6izAoL;M{U#iumc8pnXJj!8NvU;eVcJxKK z@bqr83MimjoN{-6*CO@xR;y@|3Wl%uRx>$0Co*|I)k7{pM6gk=`<*V=f;+^jPz zT2*`s8F#w|Pkaag{VvHr5!W;tpnN~U|1yQCK)*B__o;;3Q0~?r=Cy-k9so6-AGN+H zn-mer5nFo^H_kQaH16i;+29Vd2dbca;EIwYL7nj(QJZU&59ggSUC7nM_2;(6<7bd) zPD*{lr(`lI4N?GQF)_Uh)YAC)b-nA~(m0=9IL@7)Tr)0^UGHt_sWjws(vK477wlXv zv;Td~9V{%M!4#O?)L2Wkr|qPsTst_kbA6q?x_2HG9d;44*W&F3m}O0KicREe@|_CYY7Yd`FupR{qX)9B0t$BNwRAS5VVQlL^wO{L%u{09VqW{{mlOCyxUKI64PSiEceG5l9 z-P~ApyYRX(83C@X6GQ3Oot`*lj&tH(Jv@)KQm4oLEN#Zx1%E6CREvv59xUpZ8$GktplZloSi)17? zvMKC2D4!@)MSZ^tguk=?SS3uHZ?Gb&b8f;D!Z@y(R~l8TaT{rDdbOHD*n7RRE0F9I zNH3{jg>$GK^EcUus&oijrptet7f7@R8h;Ld%$KAR7hCeP)Ou5N9ZOyAEy&ENo9{@x zjUut(!Fy2`XiZ2;PB}DeEuN=(=66#il^v?_3PiI!y%Nx=6Y${_ql}ctyEfwz+j%Ep zZ(`v!x#?TLC*HHx#^7@>I}wt)cKC09nI+FtTr?n9MQCQ{@VMu&*%^XNS0%z(x0fwL zZ)8&&0EbZbVNQ;PKyoh-6b!!8Jm&q0<6dNEY|z3T&BjJZ@=Yfy(q{)#<@Du?qZf78 z0^y!@hC*XtwNr-~6>;4V_`&UW!Nx!8GEtrBjM%ftxGy-0~I-FzFxbouLQ{QbRP3jH6l08 zV`=XNSL{Xx46rNuqdCPdE?GWSsd_BXzYn{`>?#svl!DjT`HgG4be_>|7sYp|6)u6749yqu10> zt=B0czMDBP;rMK}G=LVlJ11uBPc}I9!8)M6E-Me)xS*b9@ZhBm7~yICO>J5--#)go znsq$OH12Io9-HC6MhDB<2i;l@T+M|QrZ`m%Swq06p8&49nNZJ-7p z3LYWhXIWVGyzp~#gUsJx<(HOR8O@7gyx@%@w;`r>kJ211P|tiLt%60qZ^A^RicbRR z@tQP2{JH>FotwqCDlUf8=ytPCp;l8 zkW1<7_a0;0?H3iL&6GphT;Je`;d!hP&+*X+M1pVN zR?!$eD_*?^F&lRT4DEQ!gYy>twkNE&uR>VJs@krsR(T?0+SORe!o>>a@mm&!#5A;` zc2}bng!}HU#+XjDw1>SK05@^$qzLJ`NCDIx!sC^*y2!eJ0bMTFs6>1`GGNYZoh}|Y z%sV-emkfjtl-GUEk!R_bzh(+sb_LIg?HQpN=`+p-vSwsf>Kj2xXJlxo^o1V6#_KpG z_y{50D;;8_h7lpSYAVd+f<#B4B;t{{_-%r(YK3e5P6PGp^0y-$y^Br!pT&AFQ$U`_ zoG{p7Ts*157ag25RpHhBP99}bgHHb5x@xyQkNuY}$5-0dvzdMe+8-}BvLR&+M?$F~32UBD0575w%QoYLXh)YS89 zWJhq;@9oC-R`b~z5%3%Cd9`Ht0!I8~sQ zGIcu8Je0@hTk!#Y(q2n-Q@d(xIO~#E|E#FGQB+7ES@ed1HbBja1$R( zFJW@)RD0m#dNqEu8smjN1YW-9MQ<{9!M^`LhlU+b0B-XkGDFQ+1M~4F*B( z(oK2E_Lpg9zw<2c?6k{j08Kn zbOar}^6QS>@~*^JR_Xi$HuAktqGH23z(=y`BD|blEn8K+eN1gk&c+yV3{t)5wzb|) z%@KbH3jK`pU)##xx;3SnxZ6gBz(XTxADX`UC}Wy?R6qN7$mlsaRA^*&m6>}#gbh)L zFd~XW8H%<34vxwomLf{4mD@JH5UfYWHCLiB4;?(L^BFVI&q&C{Pq7yX-I{7oUS`eQ zI|Vxl5r4XcKfy2lD&~ua&8uOC#$eURYh#V?pTrW8#~!Cxp%m@UDh?V5%KRSak@lMV z?-&;j`!tKC)(?@=;BEcilXpu_-$3pyRN@Q!f)RItPerTmn}R(FNQWMezEa)voF@Ky z`;JdulycsaU?ED4lfXxn)lC_F`aHl9IUl&g;Jc$A_;@wRVi)zAo&Rm?B+c-Yc^N#e z(l~i{cul*o5&6}-fo8Lq{l@k~1)J~03j0buVeTsq-QZK1l(>0D-Q`fBqk2pRB1r{Y zWgHVYSlhQzvt8EK)guMQQNLzPw2{d5TOPLb@A7x;utaV(1=v;NATG?{hxS zhcoBwv-eu-stY@l?;4y`ksC*IH^Gy(_eirt3})rITPsK=hob#$v(7J_5^VxvFjB3eiT}Q2Tq*z; zWz6|OG?x~@HQWSGRd&k*9%ipS!ao1VCRy?{>K}>gcD>>Oav-k2SA;170#312jrF$A zI(hRahlhib2W_?2nhJGXGHtqV_j)K+2H*+X6!sY@e}i$JFyrU&zMm-IvaZ#22mgC3 zx7=04p{^$f2jIcBjZ4eqyFT@b1sX(LF_hSZgt!>BiD*9)JfZ&{!s4w)QP*8JTp2&S zrrAh)2(lD1JH6!uCOntewe+I9HZji8k{}0eqWZ~i z-)s9AUy=9y?~gc7>h5@hM?NYMak1^x*_NKzTB5kWjI61Ds_)?zd7k>U-`2zW)9|42 zcOw;I%2ZiuD?+J*vnMWJwU-uM5>VZLD!!CU!lAnN+<9Y9l7b%v3a*bz*^o2K>+xUk zQoo++#us4V-jvQ9|2#w4z)P@3Z0o_cTcz8ZSviIK;RYW5k$Y}m_@~#TX5td>rLDPfcCZ-BZm)0Bt7=TDTiHFR=|*NVAG;JYFrJm0EZgVSLZ%$s%?Z98O<0gq@YBD zm-lcdkW8F!ZQozZ4Ty4TM<6V;@nqaUx!6%nobFd2{rHHL41u{iP*03Izke*0o?IH1 zQ2Gd{@XQ}~fH@)MHqj_m`UP^wWwtub`U}XEBZ$^9eR#MJdxF*Pd^=KE@T#__9HDx@ zw9?SFwxDpI07$*=ZLIH&Qg3*dij~CZW>C2jX!U^yoi}hsVVpH)XF%w~d-~>5zsJoO zGOGg@9FJhfN?_|l71pM}pd$BugEjNdS1t2XRtR2$+n*AXQ~`vFE{L0FahATB zgE*m-e*i%;X#t@aw_dfPWsQmRzgJZ{iJwzVHEbT74_fsp2z{?h#$W-Ko^FZj*wmKM z!8x&4>27M;iEk`9W&Zx~$Tc#PCdAP=i1OI9X3cjb3vtEph%un(P+LM(mHsZUYV<^R zoP*|>uVa|Bk6YHV@#g6Qc;ejmO^BM_6UIHmCAap3U6%qHpKnGzqj=JGc3Ug06-MTW1L!bZAT{{oGH~o0ik<$t2u6` ziO&^#)`4oTLW>9W*RCW#CFKf7FDdTj;@G_K zntViO%!~b*W3yec|MxcWKzvvh{QHGyriv9^&Jtno{5~O;6tgBL%s%!7zgT=@!}WB& z{Pgk6YqtN0#%g`#AXeTDdbd}jSazJAj8YS)w|~qaFJ6Gq85yZ6$gnlr63 z!e_%tO3Khdi&~}!o5bTA)rh)DL2)J*3FbKqw^|6!2qcPCX)shSs<*5G5-!jzcK zP}~b7K1<2rC|+O&Q_#q}MJ!*>Oyo%*iYi}9LqKdn_}bcX(80CGyMXKM%1UIw{6_fGUw?jBq)G$d@t56AsplD!VdBTDb?&ZUP01A`t@c^FPO@#^R( z-tRYDh#8TW*fd@C0-46|FuYIt`<0}LM@tFLcL-D^Xe+boS*m333n}bavUS;>K+BQV ziEv@US&9P1XVG#)(z>A=wKQic8=mR>CRl%ki(85CS-~y+|HrYia@t&&V&Fvly2wM) zA?AMw)U&)iGj)zgt=%1Qnp-cnf+Py3J2QJSZYYurFEHv=eqJ%rr}27tR(jTmd4+L+ z9i9tf2Cs(H{y^S9ENIylx!X<#FBz}va|^uYqjWXkr!^G6-}VzSqD^tEY3=Hg30X@N z{|9#1f5)pjv9CrHKQ*Ujc~r~7ni0tEGfGUUInZ93O(1vC(YE%aE!L)3))K)K(f}e( zGU51whAVl)RT05y?yeuG?-F9#l0rrm{_T=o3KI6Dus-cV&1wNF^5Ie^eg!|dbI98dv@Gn zupSGzKKv%e!umM*nQVoV2hHd67pG1>u0UZ5los~dcMjl7)eo0MOCE57=d|x-rU|?K^%>O z9ZFYNzwA`uGRGA;;xMkE9d0ll% zR~BN9fwk`8t`(5=Sjx$hrhdU~c_ib~Q=&ZvKYsfuIP$r-v#-o8&_+MTYQp94a+-}e zXUB-EYD+5FMM3G+g;LR+J__59eUbi(3@TV(f7)RbJ>9A{mM8S$-Qk1=w_Yg--8#M{ z3LK+~s$9JDghc2-a%AW!0}$H5%6@a6N1Y<|bxOoD3Ylo;SXJkQwJ%-c)`Vq5X8eMnnrdUNKk92fjgz1d<4=x&L? z1O!X}mpwxzRvftFaFWFbvZ47pa9zFtQeB=RYfWQC{F=zl8%s`^=5)xMFi$gSv#Gy~<#|7JkMQ_FxAfUr>?L4)N zIP=^+osUDldDFNUbV>B!!5e3$l6T#rVGB^t2XtX?{_lH4TZ$by4{hOE628^oAR_gz zJZyfxQ;`Z3pWpGm)&rE|Ut5I%qOzU}V{+o8_kg^+)u+F^4CT-&I!XdcfuM2dJ1zy+vd_^|vb2LM4 zL+vv$JHtJtU*0KwebXJy$T-c`!8c&c_mlJ=Y{;MA?-_u?=$)`Xci#;Lpy_}U)^VTtG;HEl_OsWGaNolopoM~3_N@WXn@ZEti)FM? zsB9C=9N`&W&1MTFxrdns$tjVG86GW$j1uG!^I%W4p3gpG^RLWjC*@}IFvdXIl9xX< zsU`noA;6_}Z-fX4R_jORxmeiR;P7gG-(^oPs7aNbDZpsKHb3$g57uNe`A=InzddN< z1s)z?eE*h_xNki~ut2P#*fL^w6K^0vCoDwbHT77gwKH8Z|3O~d8Mni`h~ncQ5KF5s z>}ppF8}QU|Y`p5=wj{IS`h!Ld$$<@9;OFp3o`a0v)6?ca7{y}&l=nR6`5wxMQf|m} z9qetsYwLO2&d0o5&At7H<6--!&v-Gs%CJPueb<{nOv(z6q&Z8vkp>iRz$FMo5pB%< z21c*pYY@PM39^)LZms3_AWEG9mh4+Tiz`m5h0QLj4nwDJtExgP*29Phi4g2l15$)2 z>-Fsc2LRx&s7M$@f=p$-s3wXV40^Jg2cP_v+jL$l$3rH^^@3Wmd(l~;U^N$+kiG%r1 z4~bgmYIf+nc6=YoCNi{?tcOd&$NoX>$(7d|;HKF)T*{F}gkG_4{uow9kSgJW%nx2W ztkE^_eA_g~7W-pDT;nbXdDV?XaBMs2ZUR4Q#AE;?(NBueu=&xD@pJYh@7qX8^vh~VzpdP9?O>^# ztOd0fq0+vJL*Fm{9~WTRm4cDMRakl0S)_Ju0k$D5$RcBIg+)LFRiT&Cjba-6`d~Q+ zebQm(BD8)$((AG~MG}WL471fn-vPj+%xR@2|EeK@e{)D!?l{st8=G6xg9zx;)`V^| z*Iq$5F=i&&~-UDVl75?>d5U91Dt09+6r|M0jF+E`(`d(G3`WmXsgt`NKsal1LloQ!q(y6sz@}$jqqU zU!(&BnzMH?fJS5D*-FnV*QiSW)Fm2qOU!}L#xLy7z>QP zdv_$$ePQDkk#711QP(|U-`EvOmd&>KjJWpME@AKRCwGp5ogTc6kQqxl}( z_~pUI+Z@J z7sa=ISqd{hwePvqa17(~j&&tkU~u{Uw1tp>fFM((0DnwLKyYy5?|Y`m*9DM0&pqh4 z+Jzc6??V4K7K{pCc%n{W!}z_;y)n^|Dr(T8aa&B@?cL26Y)A)GQv7A^Oqs@3a}6A- zLO`Hh0=Yj}dDr57BhYbww?ahos|?lu@_p^KUwb4jYpR&RvmMU*mA+g4s+GT=y6^sR zLGHTSg#xa(uuc6J*NQljXV|&h-B@U_{>MR>U9=`_4vhE9V~XgJ*=2n6k!o%2WO@Lx zS+&ye<#po{ge-cph-5*9DUmRe2jV7@sdCb)TY|_^t|rms4QWixy^Lk6u$7^C@F4eW zblyGwL}OJH*{t1>vhWmLx?=}tnk_snd2miO8sp+=^ySj_ACBJ7h7TZcg3n3fAi~i0 zNS&9sZ@+vv1V|MlA|oS@#dSIHP^AEooB3PATc*UucWJ4D$Q&*&G(S;Zp^DvcKk+5o zu`Qe6kzkhQEX(rVA?yg_qdnUHT`$nw2jo@&;XV-Qv4Ii0CYB`ySzT^b?%6;U@)`l+ zd!+HdiAk};l+I|%*^eMeOcAh`Q% zC>{l4-f>-uA6M>?yjI>ctBvrJs|RFVLDIkw0fZMbh$ad6Jbp!B@tub zB5b(0T&4xY$m?jZ;~?}Q9*PXO#7h4fHmkZdzmMJyyM&P?lPUh>sF57&lF55_6*-wj8V0Va!IJyp# zzNNwadz*VGD~sI_8QFbLA(|{i3s_a&=C2kfZe!$uoi+&_K#%_&cMhZ;{Ab-YaPV?f zvTwG_V=ee4-I6%ohtf1|>)f48F)km)CqQELg;-q6(=T9#HM|KctaJ4@sxR)$?04AR z`ZukCT~d@Lbv5f!{t&fZiV^7Su{u6s2{A|3=!D(EBDcm zyYYAi?su)Wx1y*jsEq0)-STurzo+)I8k>-6XVuQkx& zf97jwzseu3l9kCqwcn7~;(G=#_ z$b(KjZbs&9g-aqQ!@{PuA#ymF&)=-5fa)K%Ak%Sm*{e=q1<25jyv<(vj&AdV4P-;8g?4u4NDTNnVtF)VIS4cV}Mj=;l&T@i|q$T1bzA2(Z=pNInmMs~11eijdgb8KqomNx|n%;rh;cY?M+u)#MF37Sk zUXGr<^LVwr@Y**_qE)~KPZTd6uE z!L|JD?Jx{QsGwl;J4oDaxvf2Z#I@JgCB&9*>lJfUd%#)Vr|%0313EV^f4#oR`5aO^ zigh@<<#loJKELC1^n+t7Vr~2I{=hMh9vf1%cLAM*k7iFZ4_39*N9KGT%*{m>B#&{| z)LHt|)MR;R{PipeY%(-;JQwc*0myW$@(f4@N1b!IwT2(8uWO?oVH45*yYfBi2p|@; z6&1}*Uc z7qBXUU*L1}1=j-KL)@mg|H&F5Ob@AuMWG_CkxN5wy<}g!r$(l2B1gXZ-iZ13LHWbY z7Z}y&^qa>{3C-3Ze=Q2Hy+_)=-4s*-MGR(`v_oNWZ&>5bsQ7I5x3byu^QI+bOeqr4 zOalUtxTYr8{KH|k{KFMLuJ}(^d&`SFAMEDZz&X+oH{7Y`>zAvL?q*kEt@)pdsCmSf zr^rfA`Ixw5v6AD4(b;VXP-huy#$)9O)_6}Pr)hW8wP)U`7RJynsV174ZiduR@i@(P ziSHfHa}4T~{yR2l42{TE-~D-i3-2~#MPEf=qIUgmB#U|Vh|#m{LL7aZN^p$(@?W&A zb(Q*-K)Cm}YXP4b=(8b2F~7H%Euk=n(%!JO=)$Q?)-fGT_6*Bd&; zA(?C1A&(=^z-dgkw6iS#PXu&3R)?*TySqNcyc@|J{`v>yjj4U}GL5E9;@GzK8Yd_=I0SMkF8u#O}QgRuK;M(`=OaGERJwruvCj zOrs)luZau2nwJioe`4H7iI38?u(B;p;^j`77(0CRQUuc#TI#}Sb~3WDOiUUlwL z&Tx>Rn9ZMhxRwUH2*m{ZUT{VPmjB9Ws)GryFR1Q0&f;g38vn;GfnL%0d0|&UVM`xs z!SlJnY(vfna1n@vgjcU)a%BLgOEmwU|4zw{;rFpxLkkF z@LPXJ?2Cw{<&yHO3;<_Tv121&avZ$fGT<2M_d8SMsP1;5R+wfv`!iZ-|1^X!q+T8S zwxP2{Fr1a-cfz){7KUr}MFf+Q2FNkJT(HA-1q-P+@}=P9{LC!HPd)UxJV~3>;XH`L!+VT7jC5to|*9 zk7vtInM9HSRkA3N@{!CV29?lFzQ{IJMz!W~MixeoO&q;m53#j|(O-M-%TS($U6A!^ ziVOxzU^6jq&wEjQgtnUSNrN&~on(63qzil|-;{<@{q6&9l}D>ax!DI#^ZX{ZoiwJ) zrqvb)4i#3baHlr^*>rtwO+_wWU(Dd6jCIu@9FpgW~SR+o~E zHXjNLHY=FxCjpNDUVqPsLu4(#_Tp|!2;Pm7nJtNd^7M-yg3a~6U`ZeADI*eze6u~8 zy<5KH>P&)w8f6UcU5>L=72X6pSS%H_moILDidzN~%8}TzTxMJ^@CB@aMTP#$7s~ol zNY7!&!B?(^{%CL~J{e@t53)x`JeTW4x;I1GZ!KE06ahNvO&inIkrMs(Ta1-Kx=K5XlLXL2F9y;C+!hG-)Q}++^YydQ?OC zdT}e66%?hYzser2tn5#`_+3Y0gmfeeUjFtiL?`(x4Sz3^2X|g6`B7WaxIE_fJHtj3 z;7tu&B`3Sh#C=Qqw9sxg?^H^7&Fj!i@!~JN@7Fwabk9=qbp3V~M3aE8%@gN?0|w{i z=16*2dOG&Mr(FNGoS4onF&DdnoCuDF>ptB1*})3VJF&cJ7n{PwXukkJzq|puRBuqGi$Mj?6WdKZ#6X9HJ)GRe)$LZas zkneG!VNK5b1E|8scY6BjC6?qi90|-Q6k~vkUSLGi=AS;9)n(HsPK!m(86~v%BVR&! zFfcioF#4U2oiPEH3e{^%>Aa5En=ob#^CFN6091VtjJh z{-5^A6*19J$I?M7-_9F6q?KO%Gsx;+S$ysCY3JW>H^ydW9}V?~S(5femVP@ROCjQ7 zfZkutQ$*BQ@p#i(*WwO^w6seS(M;I_%Pr&$&1iS@K{#go1PO+0Ted{^T{J_SiJje? zNh_~ZuQdIU`KP_o@&ojgNSRzUp_n(NbLqxG3qbI%*5QJHt>|da;>=mqzEm#JW<$B% zbTT^-UXnd*H(__B?m+B*`NW=m@rjC~e~b#h${vbF9P3K06Tj*shr;@uc#fBXq%q$_ z!iOQMlTNCnn_Eamr4Aeyx@;-M&KG6A?U<+`kfrw43oP+$l1E>`VBzz}v>)>HM{AHc zebgfxocG28a02O5^t(4wk@H81DkXnAaIsZ?JFmWKXa0`*G8U6s!$a^S{~{vMSIoB6 zJx`~|y}6UFqX%;^X%Lc2Ja`_BI)Cb~`N^+U!l@SNo8b*&ri%;plFR-lzx-6Wj0YN7WMvt0 zX`3YNx2|h~8>a))eP;SAT)aQQHK`^XjiIggrz%*xX#S_^jf(@g!M%*wlMp`3QZUOp z^&y>muDb*d9Yok|bhGskf=8Y=_^NvkOc{Rm1ByZ^{Uyr}yr*&|f z+~puc@$^Iuk(U)eSo@&JZ49KWVx{)y0IPEeG5cD7iD295-DzGiRZ4c7P)?Ao z>KYo6S;`TEzy0>_*0jNqueOUY5BKzLih)2$u=wkxQ#rIFIZdZ*OWD4{FQg9-7SF<% zPbxbi@a?x;^T$XA)uuYa^126SY!QNokuH#zM;zHuZQP0n7_isDAfpmgpQm<{pUgc^kHV79ANEruDp5MpzsEj23H9x-ywlL)M`A$ zp~^Icoi9D=)?6A<2H?-@Oi{jbRQKkpm>t|7daMv{F)>Lz%*T12r_7_-S*YebVk;$b z8bviQkY1~T7y5+lU}|LK)%cpU6qMKn671i$1VSo|%3%CYNVCkpfmrV3_4NJbby(AngkR}IjIqTJ^~X9KGJAiGB89HVV_=v_B(UO&&%-4JoOYU!j8n%>r+ORFD>4&bvWDC)bd7`F%CY8LE zfTt)H4sU}fcN3xh?rQaT|IWoW<+JBn1-G1V!&RAx3w3qJiIhy8YK%;JccmaIt8Xn% zA_9ctaMwLUV2ufve>)cOZ=YkVo>*kmQOSwui4%4IV0WYLAPUkecXB}SZq*ZTNuv5Z z_>6Y#v0Dzt`+#TJ<;LF<$h=t-QwDNC#=X+l9ewBynHEi~>tgJ(EI58PcqsWy0!Zs4 zF-R)IyS}>n;vSt0e(CE(fpnQp$LI~M6#;elm7^dv=8<;~*MyY-ioz(AiJubk*BPqG ziT111=fMYcxUjgg(rMIo8wD0AcHZqh2s7()Wwp_F|v7$)>HUWBX*%bp>&- z1im6i_dn(j59g< z81t~Z@xom!byB#$7-kMNsQgs!lxO7Dj2WAK-|{f8AS4oYH0WNI*#XVkdc33Bv&MKuQOJ>9vNy zcf`0Dkak)Ep>BqAy(9|xl41#hQb2(j9pTm$PnK0%nO8qlbqG>IW?H;t_z5~%?sH2m zAs0?}pD#OEqD$p+pl-QvQJH|$qr2;EQpTf3s6e1p5opjG{{4%{%)8hHt_v> zs{$R(wu*R9p4OnzIEw~xaA z`z*6iUk_)@4@mjR8l}NrEH!*8maY6xhzxhTUDeku7}3*zbMX@E5-~eX>>SbA_hU4G z^YJ_kO|ih6ro_M+rIuD`&4pd^{OEn{fD6RVE-z!_mn7i>#JZjd!x2b(hqKnpu| z<5WV30JPuPNC59>TU8+s1hvp!DGC`CLGmY4L`S%3h$7B+!z#ao(3AXbj^g9kl8BM- z54IIdd`G)lyQb3`ccVGVco2WP&Nk*JMqU{_8`cr`2R9L7@lD;r$S>{52QqmgM$IifDvV0xOwRK)Q5K@x?XA-SRz0gi`h zRwkl=h3nbvOTDkCC?H2msLY`IL|8{_IW|~_*!lWZZpWG5V}6CSBSuXns11-PrRK5v`v8*;sJUvbm3L@3U0r8$Qgo z9RKB_l3_uCl3v3n@+`w7C#|(D@~Z*B8vHNmLq}Bue;8Ag>wX0`M5h3gRs3k-NALyS zxwz%_T38116g^_w6J=%wUHU6zW>&vWLtS=N^ci1DmJ{~6pi|Y}@k`)Xm#t`C4O|JX zkUu^({?(IQq@?>MJ%wFpBg(=eM59^QJmYK|VDomVRim>HElO%kCrrpmXx}74hMdCr zil=yVrG)}J@%1H*y#R`gM`iLH@{zcU-)7W$O#wALA-mtN-NM+vm|u z=XG}1(N_1b4$92eE3-}%))peKCAwrpzCN&lIOVwnyuo)!pYEFn2j0suYJ z+RR1eY>X;OmjPRFX)xpJVeEDVVl=()^=nt|9NL3` zUwnPw3rf(C+yTMo%FR`b3hN^7>4*PZltTU^PW`SK(kHi9R?81VN+=j@rFQ zh(NU&e2B`-&6&}pb!5+q6(FL&nN0lFir-J$%7GGq39+XX%m0S@SHC#=03CbOwoo)c zRd_q!QCZk=;Z&9F5EPj|KIP^>p*=TAOmTRTC<7KG&}R4NI<1WhH*bMRbbY!IZcXjRyeoSX6yGsR@#4Z&K*Q0-|!^!#@MKq344pWVm8Pz_0Z4E6_}2 zP5O=(($QIe*t*G6m}cvu>-d31TiKZsVE`U#WPxFDMs z#pl&?oFO1azUUxo-dl0xi|SC>pn0AzLDn@2bD+NJ4-4{)pt-RondQYz6+}Cif(-U7 zfjVf`77`V@0AXRNifLTI?#m>kbk6dLcn^YvLA<9o_;%^Otop>f?D*fwcnZ-im(Pp( zL1{cBzv@gby#(*#34E9WEOCZj*4n{W4oOfHv~fV0%$ckyeqD_{_KmH?vaVI1ARybk zolH*58E1PUpQV$dRu#WQuIp^t}8Lf zW>1{~Ci3pBhh(8C(q zPk%UD{&P7WC?H7x=9s9d5<5`-#rxUx8>rfqJ(>6se%>@^CGOtkY!7DfqLUMzOaZDI zn>Jf5Wk+&bqDpp_*;bP=;%k?zvW1XDk5)uxrfEXx<$lZxNh5s};(Gj12XKgd@_E(I z+iv&vdSM6Mp!Q<7w3JKs$Yn zA@1epx4{DeMvlmTPFbkpFoGVrBB-IyK3e0=E0ur zSij_0J5?3W9xeROlIFD8>&<^j+TxpV@sY5Q>>1U9vAh8Pm^BKN=lm!BlZT4R-yQtobe9g-L&5Q8x~f{tS9Krjjn6H^9`j_Bn8U^xDDXS!(clAt|z7J@BBSp)* z%Kn=#GkV*1szV%){DU(6loF zEe!%#WB|*z7nab`9!?&%eezKao9^5D6a#`m|5_LX(e$H&J<8{=_p~J8VzX{h1$#%S z;jwqKgQUXJmK*A@JQ_g)NK_BZO~mCPDg9;2Dij;E;QHN?&XKfZ7-e~R0=pwNWSOl& z^Pbh5W)x4{0ShbTLs{%AZk|OAAK|FQALo}YwL1vZ#6j}ylfCNW2BzG;chEdrj6Z8B z15y`CBI4AAPWGk)-7u#I0u{<1v(zCxuEGuV+Spg?Di4>c_I|1j=9Ue*49h_ATf3!G z5ayKadE60>?k?IPV$+d29r#uhTa`Dbd8u8AT2Ox(s6a6O`h%=qRt#z4AL<_ZpoNU5 zrMd{;;gj@ME4e~KsHntDN^*rp=;E8S)u1>OpC7lL5?T&uT0=cUZ9N4_i|Y)r%%RgT zD8~5yMv`HWk|CacJ?^@WwEhipsW}`qc!whIGqM6U8MtCgpAv*9i3CAj!R#Lp=pSN8 zKH@zk9+E^nM>GOtfFSbGV)?tS&oZSEn1WMX#sV)m(!Vpc)2`;x#=ZjOKggn6a2R_2 z6n(n-?&y8NZ*GX7;~%pqvy~5y2shBGB}9dK7w{8Ppft{V#>&jbcEE;YCH6E#IVr<# zS64EFoX&z&zo3&mR^5O_$vw_yg!Gyar)U;SSAPb2SRzdVP80d@_E$2*V;_G=%1mA{ zsR5^XR|>F$?_zjV*H_O*chG+J7K_CMi7^ElCE*O^^^TcACOr56h^9OcB9vPna~G!+ zdJA~2%jaaZDz{8GwXBVB_Y7dWRf&Fv0~rCk&bc($)E(P{61(L8@g}bQ+^7BA_Y%MB z5~+8-u|3(DGjb}V{s{dHpO5lfdTDP9%#y0l&Yt@!?|5V+s9U$Z{A7q`43%5WK)ulS zqiA}^vQ!4maMeFt?A+cfHT;aOa&!~T6`M9#<~tN0r|}%3gd09H6Elj|>te)=Mhvi( zY^1%Uvdy7ML?_(U&k*Cnc(e(YRip1{%q4%j?g|$8LrxOzv@Lk;A&_u(H=}Y~;aEc* z6#oiEN{)U_70e%l$u6Ao&&4)j)z?TRh#+lwDN3`*{U3O$>%5oO^IlqM z&?P&Am;)^DwZ31SjFRFd=(j|)X8IFa#k5nyltryp)f=v0w=eN&{mUIu=j51`&4mH{ z$XN4}KBV^~T=-yE3>jrdy7`R_LH0UbMXCPc|x6XJZF8bdzE1BdC;WoWC`KIs*A z3SP$B@nvx3%bE1RK}QWy#=JlG9e)xp>?Z%@ecTgtU?BfX2Ms0I{OkK2k6=Az$+G}G zZO=4CEYz*fKZw0GxCBmr!MLh7*}dZpln0+z(4KEtX{T9Fo!D-|DDY3>X+Nk4hm3Cw zvbq$Chp7Y$cR_BivT13dlaQ|@_=Ko#Nfz^Z_?@?SCLK4qE3<;$V7i{J{O{)c#Nwe~v&?@SZ>Gqzhw$ri!NJ#bBuAz`=>AhDWOOj0CPi+fX#mnlU2u_r4Z zLF`)7@tm8&&|G(6FJWb(!dvjsc!>@eA}5f{EOo{kk=CM9GBvNKj{uWH|A1XJ9<4&<8~# zhP&XkAVVc;X8#hrG&21+zQ6j3v(SS{XB$53pmn}g?S3d&Md&P8N@_n z->UI;7KpuZwb_$zWGRM6H>^7jrfPxIZKR#OwDl;0D8LJ|uXb0E5@gohBddAQ>9vgL z9&t7!g|nlV+l^}%9IM$oblZLXTdGjU9I?V)yg)PlgWr|YV8(D9&b4|P!CcVUYsW|E z(`w9RqhQqdBam~j%HOpL-8Jv{c2$Z5{xkPUC8c4r(HVgzhqaej@~WF~wg=&6+L zQ4i(wbE(Wfo0PFCkrpq*Q3kgWRH!2(X>WmZZvQvm%r%G*Vdq^ZT0H!p93&o#QR0<4 z$*E5;nE14Ll-vg#9v9{wfWkT|l*Yp!ZA8H^f9%{Pc&~;W^QZWQKRqN-ifMan=yXYLSCBV){+~u*-(Q@?xy@** z1Z8H`8Bk*#B?qMrmXQUaZ#m8nWIX{fLtIXn6)_g^#y5B>#11LPs7s`N&in5 zYvFi*xtE^_(WHhnR$e!~BWl(sY!X+!IuhQpv^@yZUMxjzp3ZRcm7KD*?kLFc!2K+k zZlM=o7b(LI+lK7z^HWkoDT8Sw%VvFO+@_n~)#9(%m20zs^p7RZ(MTC&M4bVFv>0{I zr#klqy$x}&zT@MuqI(+&8r}qF-MWb4bVMimwV}IXbvo;G+UbNitIIA~`PkD7-gN%wFkFAgRqi`W~yPEI>cJMAPsg-dB5Pmx8)(SO^X6<@vsgBM zfDm#e7SU!Wx3QP5adTfbYcanDjFp8)*3=0m%`dM;yiTr^F>}U2;@f~X7eZv_Ez7YG zAj|DP+wOB#Fd#8^rp4+Q9z18JSdi$ivK?G>TifNn2tMF*=9Gy$=7IY)mGv?p;s>g} zz&Qcr?km2taKj3W%V%dFk;~9)1<*1vD}V_HIWrAbLr}Zkp8HtXwEe%2b@dXJ;{les zv6(yDU?r+aRWOb*eqk;Z{(VdFjG#fG6e@8rn+LN!kZ*@hVX#HZ)3{DBaNo5~yV_p^ zOl^nCDI*gj3MW%j_~(I$UzYU-e^G;Y4jI|$zZwIw%)`B#s9 zrsP}3zT$rXao}FZ43zl)Toy;hAJLSz86eE~;;}|yozkV72-L;4XN0!`$C$KF8p3M}CdHGECC@Fv^vrjA!c4Vz*{9>msn77>HXV293^+QU6Y8if3b@v)s)8Z+sTC<;UPcGgWkj z3=9$}-3*RSS+2T~jo(Ny=qR-lHIy&}eeVo8sJqco?wKKy!qUzrhFxl&4y-MeEb}&| z_2;drzRjn?Ti2#y_N>iIi*6s(4)1AWFSPbUDw6PY#Wp5DnnN=m|%^+RI)sHU4%74E`U9C-0st4 z!;d&#_0jO%@4CPLF1-Wsa-q`tI-T}GwB>}z*5+tTMoO%{OGS&83@kSeDN)Tp2Mqw> zhb*$1FO^v>i4=aw8@tG3eNzf8md_^#oG> zAND8>HkX-sm?qNg$rM<(jat7?)Q-K|t+fxYwYuqnR=Dh)tm?}4b4M%U1mer&2UrrW zA`!ncAd$@k;xzFmw}py&%GxnEerghmZZJ#ue$4$98JSY8*nWPagg%f;?Y8R`)?BXC z%q5$Lpd!G3wgl@U_Bct+OX z^b9=d&Yk^D8aF$Osb8Bp=^+mb-K`5cJz8t#nzA6ZAzJG(QM)dnR=ly=Y zp07*+ZRbXD{NNf~e)E$j&RNU6d^81FYcpOG1NAA1w4r%fc;J3%LrIa8^^O?(eHlPx zzZe^C)}}d5v_xX2_yT~+dUx=4xge_YAt&f+KXJv*l}+)Vj{sFxrnEE})I_S<-;M3< z(2rNO`qc!GA<&zSunXtu#;rfzt8JW>nR^^3($mcOPiZ|5ex8Rh5wO&B!i7t0yg$BzUafgQ-32JX8-s>YGR^YVoD` zfpZ#zTU+map71AY6#fanXWb&mnpL=)5P@1#(4TIy7H4k{yWE*65VHM+`&;`RZRb0X zj=kdN5?K_BGKSMqERltJ{`XtNsoW~8-5A=dU@eza9xwNILzVJA#a;TfCB@C7PFZ?D zCAuzKqUR>;Vq8)1Cn`6*TwbT_Ub%7ZrDiiSKmNxNKq*+8pWC-6qmGtKvTfjYdjI$D zVzwzsGPlG%bn~ys2Xdjz3D0jIcG>gXnVpirFt(}+hhqV)h=Ze%^e~_0zb84NorBzN z!}T`ZLxyoC67(Xh`C`n}Vn6yaAPOnDJ{Nx0CKINor%jYnkZ|NHJL`sA#QgQgp#S3T zTGp}w*fu~xN_Lpf6i~yq`7PtVrMtqpo$a=xcA(fwl1LPQen*q8C`1o$3U#@S3w?jr zm427sY3V-S9IKo*i`mB=gQF(g$D?%DapjLA>6p|m;vz(_Iw6Y1PwvE!mVy0F_e4h1 zZ8FdL%yJ7}vCJ=)M-?^p^H=brt zd(PD$>CV+so+w^wrMxfAT#t@JmGZFPDDFHgG9WE^MdwaAxr=oOQG?h>Hqpb7qGV<2 z?CT9V24ZtC9FF_YMwL60e4ae*d04^^kC0E8x4mL8=l;eLOa{GELlN@2SKPe`t$Si0 z?x|f<43B{&b0QGzfvibsLKti7CM9k&2Hz&CjlJt|v!5fTB1=9w$?2vA5qWtze|A@K zIXb)m)f5ER2^hvhmj2RP`}+FgW7u{GX_V?suaP&AKudnsL{BC|Lk6|OI_X{WlzX}b z2#TUAr+9HSLO+{WYhxjBUbgwt-Q3~i+>V~Q0-5^t7%p@6{h2Av~p;IBi9> zt%kiJY1|Pod~KtE4e4@)6(h{W8MH3Klve|QuFp|#X8Km=XYwxcRiAJjGk)=uvmu?K zWF-R!velx|+zc2>J9a5G$p3B)oqLZ9sdyp+17?1ZN79*c(2|SE-Udz161#3*Smhh) zY+ojx<2IbeqhMaE8g%oU0X}MXH|HOldz!o@Ls9mW4bB&ao*)o1^A@cy5AUOOIu}lk zWeRS#Id*hREHGN8+?`+VFg8)eaXZ-o$p+f1>a&mt-Ht=Jk&ro@c5%1%FYoA2o7rKo z*g7KKD86-83q1&cB&VD$D9B7cOQ-x3iMYu$&WS9!Jn{;4QuKpR8G_X~{k$9WKBoz^ z-ihnF6M-9ZWUXUewIVplpwo;9rM%c2&*&iR!I@i23-aPWV@-vur^ajnv>p5v9>s5| z?PvOGgpO9Ni0v?H)xIff2o~}WI0LFEnO=LE*C3FszefVPL&shI?tKs1TabM$h@$^_ zeG0eL^jaM>vQYkF8R7rZsp|+aa|Emzb8yAk+vCT~%jdto zFvCgw009C{+(Cu$yj+m2XBoZ&Q5OKf&Cd(BTcj$Gsq;B zyel!4QSveEkMG4yV*!aVMCk+hZxlYL>g|*IS)uQw-Xu=xlO0B+m9_-y$st1dWOspt zvhMj)8HE+ubDx2RjvSfY>*;QWgjVuxuQzzcwO!cx_=L%F@{gsto)x)nYff02)`ghK zv;K~F9QqqC-V~hE4+NNY+))N{Pgj<&braR%q}Au>$n5W^`Jf78dfemf3d3+H5mN{DA(jTv-=TS?Qw#b9Jwc)_#E}&GxPA zw5T`aB=?F}8G#JH4@d!K2Zz=CoFRjwJLEs~RYUd`@Zpv~%xb3HYRZZ5K$ zGZ_6x#$U=;-R@K`rP0%}I-efi(s_0LxuxVq*&CD&q2$}AS$By*ldM^G{t?0KK{0s& zit=zVI!N(i&p+qre#seEawgD93EeabKax}kcl0RqO5V#h3uhE@J}+6aP%;4e0!V!g z*=q2Wl#zK~&$Xuy4K-XejcpZ!2F#JNVu|)?q&pimQf!$b8Nk5Eb&gZ_m?rfba4QCL zLc@KZT*$1Kvv!Uo4d-a^UnC1SZZ_QT5%;ef0~mrY+pT!-#mcqWHG39+D}SA{A*-iz zaheEdws5*H;|iF%&K}pGvOH2iR8`qbU%8>Oy&Iq)@|rh{C>3=yAXb6zPO83r(+ub& zrtb{|iIzldDLmqBL*Xc?V1Dpy-=N_Tr4XGO3x0mesGjxp<&@1M3&PzeZx*9jj709IA;>&1It9GcAiLAghcyXyJe{|-WdWz% z!Pn$vhwK#s%YInF4reEHCkMOi)#OfgJhZ^Y4SaX)_{sG$(4LSpHlp9`qk_p)GdG)3 z_?cc~j>{}5F}z8pEJ*f!=Zj8Zq%nuAm$`@y?pxRc%%f60+h$_@f3<-3ihrwI0l*3LdRd*KGGv zE~P&apE64K;P{=A%w%}`64%wnMVE|19lkj%JQE29gjT2c-Q9@_NRo#5;lF{Nn13Iu zN`%0bS2Zc!NwZTd=K2CiP~_!D9kBtYYrvuZ;6E;9s6F1KH_w5-|gje-|KvuDT^66 zk);^HrLp9JM}m8YYzg1?b3XH^ofquaGDv1zYEdjCt`%7UB)`c&r!IPMlk2S=`)-qF z(cSSNx3}dR>n}Fye8-9DOHuDGAU|)=EFW1jE&d%uYYRZ;14|6z??JegMKcw-8()~- z>Br@qgAAlG_HVa%QB4hg-N?YB%CDNX8I?rycC_6{00paVxT(;~yAb7Lo0j&klpa3c z#lhDo?Yrk2tiheWbd{%~kZx70O#GVz#D+W%k z2RROWb;8oc+Pv4J&fDaa-f33~O+aE~hB1>F2=5?Tk1dYX>^!RVlTMoEyL=9c7<-~5 z0Su)t$Y@oL(hoLr|C9HprO2Q-bU)qdOV#Qtqp43UQN5~Uhyz)lqcq%D&Pj>TstzBxzhQer)_96#!0UPR3Qkz4;s*6izTFj5sDfVot2P*fxO~0cltEO($J*g;@-CWkk;ww30 zzTKvWP50BTRx1-l!iI6wMln&o)~Bar;8)i~9*01n+$3mrCe2p7WaxJmp;5u`dADG= zjQ(H0iIHKOnjg*GC&vRXnx{UF)@=By+ptFv4@UU`!urQEnMB@>I#_Mn=5A#T*|_uj zs71Wj9B&c~j$6Vn;TPtOy!(Ll`*8J<+;ITe}sL$ceF+ z=RfDLFa1uk=%3wN+>4At(SZP?)2Y*-L(qs`#825B<(+y%AjxJHmxoyF92EH(-w8em1zB$qtt9h5iG%D0QavCYcNe% z+J$82`n9H47Iwwpqqd{$kEBvbyvS?ajb06xDlyQUe8ATb_V%|Klb+rX_B z_|@g1TP-2wCCQ-G{X$3}_g=-C`i#8lR@DL*a5ipk3fB^WYF9XB)?I3JEJBGf7+ky= zXvmB!*MgVqUUT@NP5lQgNITG~U~$mDTN9h~WO_j0ZP*`w?LA5~LyeO@Y>bq4^~Dgz z?gJXwmhVA;wr5}kRH{kR2|oh3K=g`Zqm(qX&ZI^<9qM?;80fOB*;zg7IhVBGFq1EW zo0IebS;}n+X5$9%>&!F6+9qd}mP!q;#I(n5D>9!M)?V#8;!i#S1Av{$BMM&00M~Ro zlVQv#lRsuyCb@E=d;$`7;BWiIe3+}YY>+Qdr7E~XlOn)XM=BR}p91^s9&9MxzO%5- z>U5=3Az&w7H{W>aMvZaXFdE|R%CEbEUS8ZEiEnYuTe_D-m4<)_CnoH2g8)N z(Z069^-`%bvfDP*ojF*`n1?(zDS1Ktqa|Avd8OS0=Y$TFe(&myY~6 z2Rd&h3c&=JOGSB-mcHM-s5aW_@!l@@38qgCiD;KtkaGps*c^RCqY8YR#}B z1cGp4@!XqYeC3&aaP+*z5SA(st9>n}?G*gbf$q9IgNocCj2c(U3tskitK+l9mJaIW zpXPOJvr}?JRt(m1c2j1cLxiHkKQb8 z2v^lp+YeQO?46bl%-?->_!OkDek!R$8D(0EaWGSln_SFCNrj8fxI&W2QteV+p@SIc znv1AoaF31uQUCd+!`}LY$;w23z*qmL9Kt3+)xElTp3XS9{m!2v!t(RAONOWZbBhYP zEJ6l>(o*D&rW(0&(lf;ml&lJE!ft9`4Y8xx%+5lw7!}41Ze|{wKDy#KJ6k$u`!&ai z4!d+pu;NiVK14XM4K{8azQ-sZ$VQwVDPvK@icZ+!)6)$CzOZl}H`RH8punt}BBwYz zQ};qcr7GwbzEe6_)5%OBS-1OWYu$=O#}=ZbPad%MbDC(CCQxRo-UAYa(8524(*DeB zf=eXz&o3v)#|y|Kk$^BZihQ##~opYIa0G*r#DVb{P0tjRekB4>!N=-JNnkX1`{ z245(b{RF9BOI|URR4A|+Tx-b?(C)`*E?BkQ97rSY!j)3;yuJlmHUi9Cf&-9UnSuMv zD&lLqaaVvyP$|dEtf;@*N@s{VZwuCP!S?NZ+Qvu0ba(=1Q0MnH+zqS1y|r%?5bb|Q zN`%qf=$6?{#nAq`@KY=qU@=iqof5;zKuizd47~qvF~3ZNGq(wFIqc&VHjRj%6leVq z5Xl&tp{%yH(xZ?+uz7!t+1Z&ZDhO7(5;I`L-BPSH?|2?=^K zT7v4jH540J2H7)V@Rgp;oh{fNzz(SnJ<=uI;Y^zoFG}QJM)mvFdx!o6&|p7P4e;ca zNzB~`@rS@8YWDbGpO`F_uj zF<);afFoLT^l25vfqnfbWQW*h@er>va_-e7jSMI=4f*!HD2&}D-VcfQo?ogE(ks`* z9y%1+izW!EYUDciOP0uCdSbtFMm9{00A((*{!3)Rv_0RJJNzBsn0B2g4V?6Z%gBm1 zNknqnbvBT&VNI5&f~Vw*{5(!~I{sY%BVZ=>29yuS1tuZam5^!Kid<0rCf!9fZdPDz zT~s<-)^U`dz;C&EDx&K5J3crd<>eo+ zIf6EADB15%fvbXlwEfFFb%Od!x^c?=MmbT1mDOoa+vA?=oJ`xT~vdB zNhY}e|9)^7$7?BefKSz1){q9=z7u)`6PKcdTrh6RBfO&O#V){u+A7jAZjEoCC+LUH(aqLM7*$1{L;q#Y&xHW{^-MH zMVy(Q#wasJ=>GAEtxNeA;&^b^?%TtfySm_bQ@Qo3d+XnaKDqSfg*spFP+Z17*|2 z*JT6qa!8H*YX4Jw?65bNTX?7i!@ImEDkcAXgPyq>-J4155VYo3qm7h#hpU4r`dyPT z>O#3jB5!zy?e>p#bq zlKHez%URZZvTkW`W8>x4Ol6?#dz?%(F;Nwl7XE~}nCgO+72dR8zE!e6mIuO=L(bZ- z=B;;7)=Go-<|^Bth$3)Shp?`bF!+h`302psy-<h=+-e8Uy^lwx|Er=|Is zCZY%m(ym3_`E2}w9gUbau>H(#Iz(EtdsxBR;W%JUSuj&CI5-YcSX0#u-8#9L5)3EF z{vbJ|qdfvi0P)N1!wQj?V+IQDW)D85)FNCi9%nbYSM#L!ZtiB-3fX3{Kvm2)P9S9N zmzRHg!_|p@&tp^ms9!)oDpP8fcor{^AQG38{9fUmE|l~%466;hdH z?0RQxb@C^wp|&EyXA~6?ui)Sikoh>d-A_>%%a-KV27r*ep7rtA3#!yH8sXt_pM;#% z=7JGU617efbAsJu_4LLM^qYT3JRH1}kGx$vJS=MpaChw;^+vI-AJyg&d{?AJN?n>X zxy?;;v(Hv3ezFgz(-H#OE8Hm+OFlsde-t1&Z*1=Bvlfr(tG^PG&K}OoiSK+&SzzNwCQAK zl6dP-#<8W-s^ZVbNZ`?V$o4*^?$idld_rrXnp5! zWE8FNJ0W)GTZ$I)#VHUB1yNW;+&Kw>_C4l=AEbSE|F#q!vbO^X-#j6~!AY@5DvuBm zU=mf4x-rnr8}W%6_M}OC%>IpC;`6ep(frstU(&>*wa^L9FL%l@A*NkU<6)xef9#RG zw_HpibUaH+ATq##M0C0(FnIsc*Fd^J|NapP9lfbds}i6F#kaN=eFY^?YwJun7fzw$ zm+!`fO?gE{Wg70@F3CrW+vE4Tl3#^!VSm_gzQb?|FqdFd*~sbDn`S{~X5*M`p-Ye@ zJk&$Bax^dHq*INL^elE}|Abha_7#9sqFUZ<0XZKz%(2;;eehNZH67elPayV^7UL<& z`b)E*?uZJ=CMr25_>LPK95IbJDQ?LNGOND%Zq{^{&xEo$kR{*r2Oc>549ZZeG7*J^ zMgy3~nbVabAjvT&nfG2{xkEb`%utU6dxHUk1u}oN_wW{@Eat(RmUZ!VpcwlAvX}N= ziZZZ_*{yldrRM0oWA`~8yTXkz{7EduZwcDTye9|1fZMGLL00X!9olWh`|#{z)q|tj zE~V=p{$w+&c2_hY);=e|Id10uO}AyqNO3qJ%8c!0m`YRFO~RCqaN<-o#!@ki+~+ou zbY_}xae+X(^En}kH>|5IuqUMZKd_oASV@Qz^kaW+(z&Ic&~TF6{SMa``5%f=8uhGY z2UDACHe#7q<9pTaD13ibI+WiDqV4(hj6oqusmH3#tPXT`b^~?_3&8jVgzuYu0v!Dw zDI{y1s;4eLT*W^wD+GLmxL;Jn;AnrQyV0$y^1LbuSl7;T1EoP=DXPP&D)*I%o|XSt z*P>MEflkDno^o!lrysl8`%&^|GhLx+yvht%q-v6l78@#HZk_QO;u^JO&1Ee&DbE`U zNKd15M#|9F@$AFVP16T&S+;QcUsOqw>n%bTFRlJygYHSrvoQ{qp@4k%We>!Pzzl)4 zb_kj=QKE9T0gv=lsj%eghwmf%0bE}KY{`PFg;3R>Alcb>vd*wylg_v3yZW>XN4K7d zwjs!v&Uu@cM6Xa?pa9Y`rnN@yqr1>1hv!1|1g_bZ>cTnQ*Bi2VIsV^{UwzfRyO)~t zSKXIVq?h6a?%4X~M?uuhuH2%4Y|bmrg>DX9zGDsymC%x{jXdb-{bi zP@T@tm~W-0tYv^vEN57)hn>zhydaH`zb($grl(Wr@LT64>QgXyH{Zs_Tz4Db>?Kk8 z8F5ofQ#m))q^BRWjb*4v6F0|ScW=L*b7D+Q&&`{UAIT3|#8JKoLTs_tx@77o@@Nd$ z)rX@RAtT`5AVj!fMQ%R~55eF8=P1QDvSnzzS%_;rzjFN&|~5XJ0WZ=5y|ngY)-hWTF4D;Fw9*$9HqA(nxgWtB%2eXoX}VYFOpZy%qsMK?C$p)ocwt z9@bwS)cHz(J!Ki%-J*%5`9Pe_)7S~eO#FpTJv3Q|-v9_plVvrAr-6Pb+9(5G21dRkTQj5Ewa=!_vr^ zlG036c)kaQ)e2;oVK0^sSk&0sDtJJ~=i^yT(baJ2kpJ{j0k8LRLL(%vzj?G9L6C1=kw;uwy5!=o&z^%ZF(2xYvi{+v`;;K)+H?l?+z5DWz*N&gMpTYdRPkS zEjojm!5Ia<%NELo5>7_rJ2{koZLwrcD)ap(f((Z`#lwI|(=ba7;qnjTDn^2Lb@TLc zU<40Ii_EY4Yjdwkd8?=UH<#*-&EJIfgl^)M?Ee`Sx-1y+OOJU(xW?JkxZbPbBo-uxLR*jQQ@Zpq=?}<;)5rsKNCNS1IskvWpZTkx~>) zz>LjUUfQ!Lj>;tOSv_v8nVe*5Uw4Nsy|`GR3gqCrTvKi8ZI*D+0SILM&a?DUKQMc_ z=yC@#A96dBQ}BJtgS{cq_u%!|U<%2~`r{#{$5HG_zZv-TB=l5prf@{VnZ7Mt?p#}E ziPpP&QFfsnILbSO2WQNNRW*9I^9^rXa?hS_-gnr$Ll;Ba})z z{_!F&OFmJb!KP?{D0_%03^Lc5g72B#a&DY}#ocQ~0fvR|J51Ii-u-lH2dS`qu%T z90Bxj`AHYn;SNBG%aT{y2i>ZCt8W%GoTHdG@Rc<_tBte&roL23XWr**{*r6-XoJ8e zZ_ByzETw+B-ZH|v&bI$sbZvcyk%)_>m7xZ{W-C{@$~fzSuVd49aZr^dTs?S58dH%KtP8?|TY$jVDGT@fJZU}Ye$^%~?yZ-(W;AcW&*j#>prKrX4&?!p zwP)@=C}8YC@9v^9W1>VhV`f}t`|tBY@`LKMB~jbP&VE~oll(hM@@lC9DYc`DyTP4J zt)?|(?fWxmgo6Y7ht!AX!r?hPZyD)UdtOL$yepcrLQqqy-;&O-$)-@bHpbKW$LG4f zZLLNR-6h%tb@TEKQb1=Q{LsH1Oi4?!>=d~lcCYz;X}2yR+nMtQ4k-qY0HFjfDm~FA zQ*Or9<{PviL9IZ~JqP#f3u-kmLQ8;q;kP)qG?*OBy4qgwmsWLtPqdyaCp?@{S^Ugr zlRcYt&?~CjeW>DVK+105`&NdN72R!iq6zf(l1C3d$^$3GN)Y2rwI%hTLV2rv;2poa zGdYk0&*)v5?m+WLNE~Qs8@~u4^TV4_X^8KnBId!Om9>gL?4dm>U8x!; zd(-Z>M$%wy5O=mgAn5U+haXuP>NU}N7^#F#styW|$Q>OspwBmvZTr7l@d>-O!E|u5QsQ! zPR_U2D^H2Kq0XW33E1H@5`?xkPC;lXa!&^xV##oxrQcFEJ{1e_pGxfZ|0cr-s{ z-8p7H)x^AMplrBKGlS2$Z!!|5n;U%JuGDZx=?36X73wGAsL2WZf_g}3K7g%ePzYt( zUCK;|%Jn{OGwANT@y;*H4$8p*nJeTy3}LtF7KfObg@s=!IGx`QfB*?|Qvbw|S;As- ze`ylg3lwbJGw7@>@%Y?Y`o$z~y5o`|m0L*|&ot8e43aUtv)4j8lxCw)QFmrbG>Up! z{0*f}&MTYYnu+*07G7nssp%a3iNF2Y#NCQ!$+5zeVzJU$ zV2Hai5T<zFOR_`F)3yE!MK9@J{l6CA27dTDa};3ST7ECxd|c=Z%>uqq zAAyUSW%L494oFysdSGTh32VyIA=6?84^jwyPhF55-GqFiGykGNmXq#HCTjAa#}6B3 zL7YdUv+v%fGo)Iz+k_ zB2zT;8&@g7!Tj{)tKk?s`J{5{$5vBe8Pd-tZ?daRVX(Q99V~jh9Fux7n~`gSNZz) z!0_dh4Ex-k+Q(N`R^cs;F)NGIGD-Vt;Wd@y(J0ZbyyL#%;i=AZUE*nbi`@bA35BZ} z2Vb8Xq@C=$LqS`(IgEtz*B5c!Ir?_07#KyFwB@Sc-lH_;r?!w(eIvf-!zF4V5PY)O zJkR7)@)7x}3&axe#Itw)hk`Wp3gcev4GA_cSURhsW;U~R)1fvqv)|sCn33xe1bBQ( z2I!02mdb+euUk}`8OD>@ZZezl#FHHs zgp3wScve^dtC3o{dbY79icoF<9SES9E!hJ2@>Wg@dEr;;+|xEm8mk9`){tcx1$RS( z2Wf=H#w1lmrZqq42|B#pZ;QAHpJfrLrB`T(OcuI%ZP>xiQTQd^cZk22*U z)hRF6N&iy_Yw`4;{VN`-;5@6g0~2?2pneGEa)dIW@ZstWE9jxa>EHf$&-917mEDau zly&Z_=a2ZSjx1F*7S_@3_0Dcto$j&Lq)*8Qye+}=D6y)ik@*yY0sZgEjNSA92~Wl6 zh#_gYc=g{YoFwz0;gYtSFFr^L-kZNxwXL*G70j(ZJI8#xzVNFvPES5{LP*v3uzed$xjdz3`;;>&LABz5|e(eLcgfU~T1NG2Y#rM;ZBr4^+dV@!+&nOh)iKCOcP4bfCh-{cLC_${)8G-v9(eBa@Sd5ET0SOCS{b(*w+oQ6 ztZSdLJ_u&ii}NZNapo)CoYIsQF0p6psyf+TQa?lYi12@{yQ|)))frs7AzyU>s;{q; zFJQ;p*y`$&MJmXvS9ro%NJ53xyZhh1mC!rB+Ru2V$ns{@naMXydyRk`OCJ-WZ|9aQy1=_c-Q}XhtybFsPv%?D) zE-mnpW{as`B{8sa-r;@Py6fq z>VeHXY81aoy=IABBrG>_lzR#?ldtt8*Aa;N-Sga~?rvA80fzRRR7_CG*jpLvMh`Ag zX=$|r9jZ*=(Y{gh!p)%k8-Vjv#PF?bNPgS$1f zKx@~O=i=t87_6c@1NmZH^Q}971^6fzbG&tX}MY82^=#u4h*d zLd?rNbjZG#aTvN4B@f?!B6vF$+&-_|AM-Ic4QlhGsJoepM2{)drtl+X%g`S)>t3WA zgigteN_$NpR*rIvc$#$n2u={KWqziuf&6)VZ=P#?NPRkFYC-AD+hnzJI3|x<|?+GBDIjRI4)|yj7KyyQL z3p-Blcl%cN2`Salj92BspeII#9CtDpusN&9SnJ3XxJR85efKCZ?2dR-Q0QOFS3PQX zc=d)mr;QeX(2eF5wB0geOEU=5Yg@y{3wDD0oH%!l?th4ZYzmx{@C|ugzAc@|y*pE? zRzAohLny(Aon|gDLh#l|BCTKjHE!vfD++UvCGAVXy)+v-owYf?Pn(n7xmDr*633^% z<jO?D+8*TT6TB$_s{TaHgmCCEi4C#It#`Zjo zcL#b13F&M)UJyb!#2SBm2R*qXWp{LK%)z3W=a*BOH1tMPg&P=;&)@vcdCllI)Lf<;C`c@B(g=|i%3^*tkCcvyL1PTUhT}u$~IWYZeMRu z1h%ChXlt%@^+AY>Ve~f>x*TbjF!!sub5!$w>f#Jz}?^qj*XD37P#^GWbYpaM5? zL%6)vf8dF9`MUwXU?7cKqF60@%)dA{uTgsy8K|VY^qkt>*;-kld6O6@9#^pa`t@3* zPRaS-{(d{nUb4sG9=c6mi<#%vPw&CJ`=q5uU#RgdVUYZ(@?2X5{|J|)DBa)+j5hkh%Iw`n8_f!Gs} z)b3v${NpACHF`RF`(q!kUUdx>%u%n42`i|pXSzAl=+R7ktg%&g`*)Dng}Cj`%+pO$ z0|VtP@?5X=_4Tif?*S+0hA)}PJ2R}KY`3OD=sEro6DZ{AU_3#Z%4ov zBC&Xy{P*nHx=rK!@I(Txg7=rrN8l7Q=D(n z2X~>~)U3Geol=)ejAwAHCR;5VacZVBV+&L4Ujj+!WXx6AZ$_cUS@G-BltIUK90rLnrq>iJD?13@ptp3ZTEI9L8qXd)k6UY}njxAA^Eswd zedtdJRCpi!NOq%$8H>BFKGv$6Khb5niESwFa-r~U#2tVvtU10TatGYg%8GF^dlFHCj1%?(oB#Ra08VRzO7!b59b$j6EJgs$EAml zqo)|}^`dm)8&9*GM#O*do^3WE(!}Ex3$f_b`FthO#sh6K->NRjp9CL;|Ah60!uVr_ zGc@2K3C^Hb?1`GU;AM8X%%761AJ^w*e#OK;xP8R)SX zvWfv~btIyvaZm&7&UVZ88d0lWJdd(ewY!^tBS*@a7^l9T{Y4V|YGK#5Xi$cj7NNzbVHkWHB1Uv+#};+tBMG zQ~^%wwGM-?S^~^1zI0Gh9}7v)R4Pm8;%kT%(Nu=(^{C=?Ec#E6&qq6`+dO@YKp9>M zdv3(=}NdzN&kj&j&yp{iiFM|$x`(?MJR5kOv9FmFWe-h<2$J>1^< z8WHeqRd&QqVi4XQkVUUAFW{mJO<7q-3P>_@I0yB(^M>=HbAA|JIO+(&gFr(dc?8xE zJh2QGQ#Zy#Yw>ai5_6?bsBrVS-c>5|N5@;F7NgV>a{?*!4pnuPjh1{B2n@s=PuKf! zs3h0&GPcgTHc4|pM9f4BBN6Y3aW?F+=pDE((NFOGV~}DB)*FWB>7qt1FSV*hRYFX^ zFIN7`&0dznWKj4hs{WwYZPn*?=8qT`CW+sWMwN2e-9*^==)ljvfuLc&#a9g~O0&6T zSDg8FzyY}J0r?-jA2xXAC>t)v7*vGnQ~_7SnA0A;+l$42>yMAkX;MoXC9@n;<9;mL z0p$-0{+dNQ7cqBC$M$>&gmZUHJi*fx{%a2g%8ew<$J0|VzYD^^t%EXzE& zy8c$8ENjSWUv%nuH_}K{`=d1kU=WYfFpo+ z0Uf#-JasymQ^DfC!Uq#L^b;DhJazs%MK+RBS}B|zD5;v{X|PY zP|&GK^}oSRo|pg`Asa^&?CI_1K>Y&w%)f*eSA{3dc6dB z)?YE|F<(cd=)b`9v5>3X#6Q=y-3}yr+Sh~G(t`)wy7e?bMv|Z-7$HO(wICLJ*QpOA zgnRXMaf6Ghrag)e3);sXR4QG-FKdg%_ZN&2|64hBFJlAe&&>=A|7P^=5Mqvkz_SDu z+28&^gA;ja9^QSxLLIl%M+3lJe>|ja9N?FW%vWXT?Z72(Zy(YzsppR`c|bgM)_nxS zxB2g`?+`ZY>kA`V2|{E0aKhv}#4V1910H@;wduwvqBXbA$`S9EHViU2x@E@u=gN{y zEL14-{O;v*XJe;obI&$9iio77XSXhr{j{fu)aVj=!~{~tx(}uulnPHQ`NXkCiapd_ z6P#;%0o;tVtwD;|N+YT5JNxK{z~M5Icj}+;L&iOVgtI2_^Pi8;k70CujpFezwLBLc zvasb@jM#5{xDz{_l8aGw3D=xXxj?LFTnKuhiS(5I8KiMwm4Y52wx-lsd^}7~I2=4% z58GN>f7LIvlED53aL}`gUWq_$?c(CHiBU$({l*}7iO;?~X>2zgdJehB=K9r;cCr70 zYTOTy^6Mk_22yHB&c`Yjnm_M24u68e7 zNYxduM$-x?D=mN!SzoFS;9}qg*lppi`CR&)v;Pr&`IK3vV83YQSbXl(hf7DT2HUNZ z@xKKuE?3R#-uMa}kC_53TzO}wk;2y0lzq>poU|aPU&H5E@kF6j8~}M-rsoEFL9q;q zfZZ#34ki)BS2HUtsbpkT8G~dJS0={25fe)8r&dRP*?9=zP2Jog1Bh3sSL`}GM|ELx zBfr8`fm71HLHA>DMe_mKzN+Hd2m0hs#`J2_V&;x)WaA&lw!J*f!Cu5#O2p4xb@Q+A z>;4wiqhAG62s0N6fPNF5ELFa3M(3kBC%oNa4xV&|W!x|R^`~IBEdDbrNT%}KT66@WG@_dA{l+x1-dazb zNch085k$7lI{s=wwCwJG0dF<7LVGhGMYbnh735$6XoeKQ58s()Kx8ocaE3z3^ew3eiFpC~V5kPksG53k zHNvpm)Q(-m{YeF1s$y_#!Cx_}{w|%|Cs%84WS$xE@z2hITSV;lGyQX4xa}2mg9xj%xUKaQpWALJ$}h&(3PF<#pY2D9%Kq zrmxoE`LLrn_S{ksG*CHzep>Z{AG3c}mKs@q>B`KN^O+UX3;$vK3saGmIfh* zs?Bfua%IMoLkMeBF2HP7+nRuFlwL5j!j2Ydrf@4~s7qB*uiD3Vt=rxEHJdNKag@t? zONKu&M1$R^VQH>r}~C?JgqoV091Z1{{U*>n>z{tdMeB? zAIQ<*dRj9;a>JiMA*{5GABQMC(6I|vqGSre86dJ9k`!CnDjz@OR%4i^9U;9yAHz%o zA`>h%bp@b7#6Z1yU-E5$PBp9mx#2Q7(;^WlQSBHIDQZ&o`vqh|xco;GjJWOA27Ny- zR&_vevrmNul(JP2<1^*vH)~l3qr09fq0d(6JHuF7Cg;4)kOf5f8h#5bXw=Hdc8{Rk zI2c9Ql2a<4hIZViu(tcLRXqg_;J!-x4*h1BKk^8Tn6BjIZEl*f;Tb|dDj1iS|Lu}V zHx#=fagoKRjrigGJ8%Izv^TMvce;GOHY~LkMB10HOlafKx}n_Z&-jBVEUWsj7&xow6jbcN z5j{A-O0JrGAwl2uEed5RO4c5rUquPt(`Idmk&Q=bBP@IGY7Rq)M2MSoxlQK%wC{D0 zFlA&RRUK*2$5M0U9;-4@2Fv4dEOi4(KqY2skmH#huQzcw;&a)$fQ`*Z7AmfY-**wb%v_ zx%QbJe`CR^vCgR>v|ep@DCorGYLUg}QSGPyqv^Wiss8@|y>_;e-9;&TWbc(IW$#Ue ztZT1pT@;m!jO-OMFCy71m29%NGA=Hzb?xyxKEKEJ{NoRghr0K^?>Xo7oD4H{vgnb1 zf*dD8q&vV?@NmP_yYhs%YQlBZc_T**Ss2^4EXZe-aGh(qCZuq+<|kQ~{keb#2^@lx z)%F9yXU_@tBdN?DjDZUbKHK%;(HLMH+NL_c=y-tq`7kn1*MV^NpoLe?&9MyxIi9O? zsC-xiBi}7b9fBf#l`odWj|!Z{_t&1PnpqJ~%oEpnb!`gJK{?*45V@~o+$#Ar3>z&x zQ45;c36bYBQdt9b&@9=m7m}11GMP+Cb`1`p$n&8)^{~p}HLp)kjSk%l_sjIQ?5@Uw zl0dEWdenawUlS2!sSnRgKGsaz-fsuV!44GuuHrkV=H>d=e}Zw?r7bGn3KE8-fkj3x z3lHEE;GHYpGLyHe0B^XUr8RQrM7sYA3nhVj;M8wx&FO0d)T>n{85g#~pbU?I{4#2PDaQlAf{kUgDW zX&>rW5J_4hdIoc(L?(GZ7gWWxy`~3JiM{07jRdt7qU-1E?=M+YxJwXv?TrBF?={nj6P=#6e>gaDk;S7mD;I_79^5Z^MDU=Eo?b_G^?1)bW)ZUP-TUR68@)vn`^gCiy z06HXnheSHm+=YCf=pd3xkNYFxqkAsj6d_0(KiCJ=maOWv2f z7mP#!EZ_p$p2LEtm4$N<@%^OA1O+GyU(|Sofo!?hk{rX2-;o|BEpsDPCLl9#FKEwS z>Sn>E-XqQS9NRqhSkJpf;}}0Ic+lUyA`CYs4zMLGWz>%9d~z4kYp{hA<#0RnbNdQo z$$68?@z?U&ek9@U&T`Hn(ROgFUa+Pj$dyOe7VOFNhcp$UAD>i%+gL0y#SrKPldmr_DFRvdjOwX z-Kvj7y2m4D1vV^Nsc`(Jf1pSzsD~slwmk3~?08yV5vE-Xkqt5xc)rEI!eUDNX%Kx# z9I}Ah+QK_JPxRDU$mjxU3pQ&2V|UwvkE(D8fA#SBo7U?yHF&3EhPg=Z5(|NJ3Tr1a z!jqF|*KVE9+AqQL1pKtsbEq=8ray1^aOVH&>%$tT!;IX67W&~(*oQZ zz~8{qN0Eoy&XgEH3UBl{>)dItcQ&MDBx*z7cr|zP_w*rlk3EYf1(>ZPjfpgBW^hBQ z1v*lz;bD^Jg75rBH8rO~!O%|u^MWM?cXm9GwTg<`tR8HZ6Ky5LTQwOk!4nLZde=^q zGCZ8mI^oH}gtWKM><3MZKqLpWZ7MWkbmdmygp9ppD5ZbZF-uN#B!9ZyL8WlE{Xpv9 z4{{-ip1m^SHs&NJ_`c7*`}wnP4u4C^p=YOP2Pp{N1ATg-Q3$8hk_FXZO&BMFbbWUE zYSIwpiL5Hs=momM$&Cy7w#Cj^*30ckhTRNJr+F)m@9xXOiXiEG6a(?}EZUXjiYpwJ zgoYgOCEtl9?!hx}THOOFv`?PEeej%z8g6B8*PWF$PtD!o8U^JCl9CsZ9ji*@uPdDm#H0SX3tG`d>H9K4JOj*>9$wp8 z7LFiIc%=Jf!WqC{?Ml^?((a?X%H`wk8BKodms(lgVmJM+oTv3m8Qyr_>TgrT^Kw}W zb!oe(!Q47j#InQ2+)w=jK&Juzj15Yk2+c-sYxm*D~J3 z)W141ddS$AfMpMSeWv6Y@dCE|% zj@(({^}(7%lVSXk!sWhxSP}Cqmb(Z;wcb2t1>jd>z2P;l1jplPjzqYO|g~G@Cvw zZc>IWn9aXaO?V86aUxFJ+*A%l1K@uaE{mNVNEm)AwWja$=H4$EnV+B7AWeZLTteho z*s4QqL?!f@o`qcW=O8;LTS zwmU=yo}3RbTLSVG_|V2?F=a;|x}Lnv4caJKD(mXMf}1|Fv0k&-ISmd;%7vQo?|;V* zdvmO_`o=I}knQyOMD@~ANK_OrukRKlLm}kijJ~yqlJ-A1*M_l1Ew+qs#Zb?FoS8hj zS4;vSvqz6u|oG5+>vc5DZt|DkD10RNFW-S0Ul_bPp=10<7oLTBn|C~FZ5y4+>c z8(z-}ER#!ThwTg*aQ&2a8x`f>(v4UZGz%GtK*FIS>M)<(=Fr1X~5jpi#QWQ&8@xN}HUrOBnr?E$hF#)OEviWM1or zTdcHuli$uiF#XxOE7Yi(5?oF6A$t;;#R39GSFAwOxsQ-vARju77c0UPa)>P)_K^V? zR=ai0yLGfUb6ZE`>#%XM?JmyI^)p#y-><#!L@f^dnayc|aWG==R`|)jRxW(k_-A_* zD^+S9`vWa54yJgd)3`GG8B4ZP!S$Gbh+6}ApfbJQ0qHi$z*zPy=GKmWWbz-LV& z?IK9~{ok`-1t!`PvJppx2NSMG*9Y)H*yiNMuCO9U)z|%B%*L;m%;p^{#Qz{TI82ZGWw1?q z{W4X#j`3|X&fW))d9v+P9-S5u5mui#sXD%fEmlkt0Nnp=to--W3WJ_USaCWkM1}Nf z;mttKu07YKXw8xfIM@JH%{#T6TKfT-_sM%c z5ogGDUj^ISN7_Jqe1wS8JZ_=UI!Vd0-HxB!&VMZ1*$ENfhpE-rkpBJgmm?D$yc_3=cU+dDe)tC)W{G57^0*3J>N2UMq`|T35T93-X64 zrGtXtg4?B`02va3rIoSwc8>m#bH`sbFYp84Unn%XGO0Df6nop}wDqO4_wOeUoD z#Nb|aCB)6|w-Cw75ewrPOCHHYyHXwvDO5J-op;qO%7_mfAVO$yP`jY%UbEVV-I9!q zK~ExV)=OHY)Z3=tZA5u{dl%3{Trn5gBnq6d;-O;x8*9gk(|PlH>JY|?{>%psTDwo3 z`jl8{e`DwRmO<&I)j3bPg(=>fP7^x4J3^zNsNMv-ho0o?!QXBan^QHeA!aeOcj9smt(s#TvDoIrxd3eQcyr)Xet3P> zKrVMmc8fH|up}?|p7IRJc&_)i`HI8uM*nkhGPlB<^4O#4LU~-VR?xbhho(aZc+Z|T@|TpS5Z(= z4dT5mq9kW3qjfn*Mt~3A*Osv7)LW0HaL~6~M+-cqD&GUG<;XOyF@UkOvQYO(_S)-_ z8Xk}$$9w%l4>+poXSU$H6YNE;emY!|ED$oXFhzi=LN>Nm_Q1FKmukUvay(fOQ;MM# zuJA1#HyK;T^E=j!2XU#9RMjS;iVNb<6u}Nt($;5q_9@a;@ZfXXiJ0&&FPn_Fs&WU z@X&7!E18S+K_Kbi=cm4ithzDt{pMzm$u)wBdDf>a@I?B6=9tB;Ns;{`L4n&vzQelg z+Voel0fJ5?71F{5xhAE8A;kedao)(LYM?Q2Mtk;NAtEc=(#L@$>nNgDReaB%R!v;V zVD#+hc=}lvIx)Ri=ZOaQ6W|MeFG5|+%6WjKF{w+t|SWbEm$OUE$peFo@PwFYA}2-48oxb;-@LV3Hw6$ zuTUE?t9~gjFXZj3zKAq}=1}wVTdKFiKpDZaR-Lnfzg)@7Z$ec*nSYzq?rSyRRlK(T z#Td2X201$!ub%(75QBf1o{fBw`Fej=3P^sp^641wLe-gX7T^k>Q($x^=ppQZEet902F zyHKf`XEX*Kpw**RCiA0`e*AW*7L4=y{dIyDck2%Ka%wBo*gvbO6`49$|7BY8|1_^7 z_u_h}I>(^iL+{`{e{)?;uJi0J>)+CERX<4HK&jP#rtN+#RZ3f;&R*{L%q{b|jS$tz z7Q7h1UY?#@-_%^5=js1>zyeQso5Rrs^9F#Vf-hxfMbBv8U>L5!fkiL1lKUm|G#71( zV&-ixF2zQOU-94wn~Fi9~r!3w_J>>SULq%Fd1}F%7aEQgd7V| zov&cJcl}`Huc{Pgcr{29<}<74QPebg;_woqZ_nCKu2jF`b>PtYmO#FOOVm=z=g*pH zG#Z*E&z~d0hQfS7q4%ab>%LQ3DY7jN2=u0AJd9H!fqf1DF+3h|AP zdEnZiTe}$_c@`}(=eHOw@d63dDt0#(j`z?5A;(Y1Zw4Rqp1l?9aAO(3=i_%bm*!7a z`s86PsgK*wmNU)(4LOx2BtO`56iH*^ZoaaB^8n)Y0;>NiSDtJpsSnZZ=gXARXm zE)h?O+Jk)QA1oz*taJ>YAJ{|T8oF`{w}xQwRLxo^BkfXsCW;8?Rhm3G_$JQwpwEMm z^XCG|QCF#MAM*?Df|zwa5fdQo9QK^tP~|4qmwRRxVYBOR!Z)(0L^I$!rxbe;MK3p`&gYjHs1e6pMu@k*ogD0*0KF{?^Z94$h>qpEuEsbkRMFT8QxQl z0Hn)SS42z3>>;A@=fN?ylT(yzW0R2s_qr_1nVYlpUrsVAw@UuGFw#HVlPqX;aZn4C zpplWRL82FL%R7gi=}0{$Mb_;>6Q5}M?hieRuSr?%1%>Y{@rj97x##CQ?>4gtSpKlz zoniS`G#!28rIcE;uV#bCr6Upka!q0IpWqieoaE7W2RW%Os_jz}G_(8*s~e}P4Xu+O zuDVHEmi}d&oa;wRQRW!GFln7Xqkis~n3n}K|A3Ir)#ma#uG(PKTPXr%sofgcCCwOx z_N}o;%chJcbEef_T-AZ}J5oVS=w?RLtY@|$n2S=ZLyr%zN?K%?Ce(lSwy4csS%Z7r~NfiA7gL#k!vD{0m=fA|S)UG!9>?x-11u^Alb zala2FAsVt7Ov}?;jMt?H8J|Z}Vg%>UXgKY5j+U|luD6<-xJ#Q+PPapD7jQm4$xPG-lEbas6tmnmAxD}dLwMDj^x3UFsAQ(4t0?JzS}%a?F@*_O zZjjp)-Ysa+jyV>}-Ov+~AYLkCdZ)0CgB3D0>9B9AK2+qY4Jd&&*Yu`+$nt82AegS; zbRd|L3k^y!_XbKZFKJtvI>RrY$B1pN$b|&pdy+%!=dn^4W_7>0NAf8Jq~|U&hXR=s zh_RJtefPkoNXkEkJ3rl{hTF~X+7HmT9iFYAHY9P~C_VFTY@NBL2AQOjkprtfOZll! z;&a7P2A1XWfq}gC_C=+@;9Y{d!$mDs&Trc0fi=tjUPos;^rH3aD|9pnIIBFHJ!u$D z?de*d`Xre(=&SR?{XrjSf~Ti%Y$e|G@y|ee)Mt!(4x@@5D3sY3TB>!Jfk>hsiyr>s ze|~9;?|vl?Z(o>VDn}naU;44Nb(C!sE*{bT2#NDfCVTE(2^_V^xzuoZa~Ub_WJV%@ zX!Pj(IS4*%3=Fm-%BBq;d0T551#*Q!Kja?BdY%smZbiVQ95~{5PKExts`{r4kfy|T zAWApt#N0ScK;uUG(EodqQeLWvOx+_#@?rEDh z)2}5DARgefAYd6ezNNKytODc)M~ezEsy_+ zN9|s~9coo!y;rd&ownh(A4+-!P)Vd$6`2E0(W2?i_~{Zsg%$6%X^jp?I}QVv__h6; zMu{(qhH&-oPy1M1Q>}n4f0U|sN4mySZwGPcyN7&{2dg^GEni>EYWs{{+fztJn_cY* zyU9=i^E$V`sM>8wQ`^JDP6L3rfa1c!XruK#{YpQ znHqy*0iVQPhNNpqEhA+&K!_s)Ne*!{4lxwJs4ePjXJ@yPWc1>}Q?OODz)X$IHEEeC z(kT{3jb^tD72p2^_vfmxVo+YTUSTh6+`(~yjF_Ae1&W|NK!U;y42!s z0R_n4ID@Ij{3gd?pqgw4_z^meH(fg=*saX)C#La_xh?edZxI4m-;d9W!rmt zNR~W)2OQ2*lmo?MmMJAd0Xa@|Wa>E>N$9(Lpo7o2Fe9}epw|s~i~f+-cv9ywKd@Uh zY=Xk8EaOP(fe;hp8d5)baNITm`JKhI2yIv zueby5oQ@Zfaatt|)A`{IAI`JG8V+3Mn*8@xfUdxCwEI-!N>||ieb*@D^(C;2AI{X< zd4{kqP+hRGz)`MqT2G^4!;Ot^w4$O&mh?M)Cw3h(73CQGoX*cHrPjK?R8-8-ifyvm6~NE&R8?Sc8R%U9 zx}p8^;tmrM5^f-Nv<&7tC5G~~-FA_>F$kw_&D!%yzA+6dqVV=8`W^qehIfl>$sM+( zhM|+uzk)j}EiE7}uGkCe(l{0v6MiK)ygd^Xd_xAecE0GiP0o*C3)Cz6a${S#pk zKPWQS!zSu{Yd;X?*&igo-#g!Egc11~$`=4;N z+u9Orli`lVPupjvtl@-Wes|htHqcn0{LQ|mh&8lxp=GOj_PcSY?WG<3BtQJ5t~-_S z%cYIt_uuB;>jRlGzFRZ(cOvU}S&=~R7~=N^d4aJ?SD+z#?N|f!rLMsuOd1@fn21B7 zb=_-nPk!FEi`Tuidy%!P)RT_G_d%_1hQIsmfWI9qwR+yxtWfDh_PTJz>-L!LInJEY zDt5^POSMiJ$%VJHw_L@Amp?3SCP5={N3p^%AsHxi-2R3kG^L?`9cW{#O-at!ZcP4H ztqcACHUQfWQj1#4fi*ilfq6RcfhG%dJ@W)#jL{Mn_uRsF9<}#KaEM&Uf)Bnv57&y_ zE2g08xAm)QUpcM;VhD=B_QAm=Oil#eI{@ME4*+1gk z!7uG^j?n+NY<243=OCm41_EXmIu(A!>4+G__`^6G^1J)@Qk*8K-giBC!amZ@wk*%9 zWK0pKhQIsw=ln=pP+b9nB;YW(B)n1F8hbgTKW3$N$!z%LW6z`xrL%&zm5I9~&&_&S zv-;jD$6_PIH}LMn{CuIvX|2c9!j+$<|ErMAg%U~i%*{bm`?W$+d_@Adcaq_)2-QZo z@hZiB1jRLQiLjFs={7LmY?M~~3+%$GX$2H~y4(}V?6(8@l7SF;7NBAv(ZaQ?_{gk$ z3fWe=ZBq*p!NRCX86Etn32K?G;c)oYiU#Nw60iVV|I(m0*zez}%FO3EX6>pI{=CO} z^|IUX`G`+eKb+NnXpU*96Bb>DFx8N~V#c zcSgR{D0uyioGkgc_@^oeg)W>%pr%=EWtw3{=MdjSjMIzDXlY8+c+lXE^y-D#2UV90 ziw3W?KPL?cE^BZdafLs7DLCpchECO~Fe-)2pV>(UdW~2mWy*67N#J?Ls-fil59fLB zS7uL`qfgY4w|XZ&`R06ce&N7+a~FM{)$J%}cxs8kPL0=2cg2P6Fux@TlP>P?g}2Hj zEnuu-Re)=`^(ac^`x-&fs9!Mk4iD2|Jjc6bVdOlOHXpd2%f`ZV$o;(~g&0Bt($RvJ zKUhW&=Q=zz<}ZBEK37;Ut@5C!^s=zVu=vrdk@x4iFGb#l5nkn>voQ;;T?P{wWug5e z@s-Y3H2kl+TT{tZ4P}Ghb5l=G*UkF{ZoicP?(rv2AR))eYhG*+YLW@(g6oPLw@E&c zEbM)8MiDKz34vtMy4fpKBSN$0-a8=Gge0m*6ZPOF{wFQ^lENXC3CYkD(Zt&U&Ie-) z!Z&~fjT)Fas126Uj#)0EcvUiV* za*VmG$Cez(pm&bKl*EQ=+aXP?eutp+PHI|Jp`a%0C`WP5RsVp*ylxMeGx=ui_iBr`ue=XrgyJaRT*i}Sm^Yl z?J-Yf)!f0uEi8gy`+r&hAQ;8MkbnzBH1FavGBYzb>DEyPXP(lT{npeWm&aFd3_pL+ z#a>mU9GDIc4wh_z(0XgD+kjx?;CZza3t%Ayh!vk8p4AGf@iKL~hu@8NW9gJ)@z9hE z^#dqNdD(B=>YB7ekSmwcYuUeM|1A$qf8IFEwSGJFM`mahI4#jqc49P=sB;Au_RU4- z%dcckg=Y*v zP-?j7k9stO?d^fuNNliz1MaKuMFmyeVfwwIpo+7MekU|~ww6aneczEXaod;p4MZKl81xSf% zo4;`R0(8c}gG-7+B=uyXMV&#%$iAU16mdwKiK(Bbm<3M z9sXPY%6&e)-{*?Gvt$vwC|ok%9qOXOft)&sZfNKjb&Q-iR(!p#7DvFZVwNdM zq&Mjb_|EM4Klh1gf}P7_*f*aOdZ9Rfti~O>GZFOu*1#U#9sxd-H+wF06HF9eyBBpd z>(r#OEKjjU72Xqj-r)WO?y|)d*+6nCBO|%vOi|qA@sRr2{ob2!3dVfPOa<)Dqw9*O zh~@V%Ipu|VgcxeA$U6)uij0o66H7lL+fr_m%T0wMH4KN)>5bT1g= z8$5T*YqZ=S717yT8`-HbeRtsg=#9cPxlB$xJyXL{Kks#K+3B7hW2cV4+Po1Xf*e7T z+lCS4RAlS>mw&D^`T6)%o`@!O<=yx82z&T}j?PVPIZ76$7JJmMnTtHG<{C!tSWj}L zQ;eo}*kq|89TZqM@_xS#E*z~dIxVkb|?7I9E z-&!2?yv(GzBN_7#q@L0xB z@COUi;Q7*Q6kBlM`<{-D_HJ6r0E>ZV@MGHEXnb?ts5V9yl9V5DJ|c5!pP?s0RMh-P zheUe>b=)^oc*EF5IzR)je;8&Si54DY_;RW9aG7f*Z{iRjpd_k1|P&&ze=Gco!rDpUufCWLabdV+5=sw&N;w5 zWtl|!uI&S-fuW29U2kNcj?q@3wqnTW&V4*vHe~%6pwYPmEJtebh+hX54v+GHa{KTn zQx&?iEqbExk(oUux%FlW{1U$PGHSVw+)U{t!y4FZ00JT&c$;8yySJ-JIooUpM=5ZC&>m1X`KF{4M4cmsH-ekF%o%^HADQ$IsB5mw2FEIM3Zuj=;FWA`Nnt74 z$irXvkI2sK)BDd1WOl^a*30{yV$B5zG)j_DVrtD+avmt_^3iZhzJH>LvQ1v*3=)G@ zqHtp&Y-CS2e|)FEI}HWV*Nb+jD!`Z-+@3fdnT9s87Ev+(D|fDi_w_;`O`wYy0y#Qo zxRw)4?>*pd^evSUSTGXx2!68-VwV*pI7wc<>sl6OB*1FPD^a%wHSX1GFj0e^Kv}`$ z*U~+G@3|8gA@CmuPGV)salmg|oY=G>@i*VS)15`FU?{C`jve<^;l06kRip;{Sx0~4 zFN!7A_xQZ%kFj`Hml`92{*8-t!UjA4lfE%(hWz_NpY47?m~p=(H~*0(@YvnoB0jET zUG0Dy_3RW!lj$-Vj$xCaH!h{6q@?_JRW9b>^go}fQvTf}e)aX~J>HuUP|1+F%`L;h zLRO(t=v{vVw`i~*wFFVGRm+bIKVc#5H}X)+%M0BXN;1Ex8aHMr88s2uWZ6}D)+{u= zpb$F14?l7)BJtpo`&A|qG1yJqZ42(@03+Hkk)OB3)LUKdRCuB{4gz7JGTEJjb9s3O zanI5<4qoa~?m7^`QBUO1ce>G^gp)eoyiJ>%#@5_gc0Z72jgBBcBABDqE&rB}TlEbO z^KU(jp9D>|ffQtA;r+h9*iXa>Ju%_+lPu3_%soXs$2tp+o?W}?dq=ig_3f9;h?)Jz zh5@e4HoXT$%>J^d(_u_q#4UOV!?VW9L5taBWnL{!w`XHKzpAUA)#eG-u-1J$Tsf*U zwKYM$99b(HJ*k+dN&yM_p0Bzirl*vVciFH6b~TF|!7%l^`)0RTlhygi z+`RM!^d<$fh<~HMJhjLRUF^XugADSNOmFFjG(EjQ|LN%od}L6+<|U|+3|8IS^PRJz zY(d5m$V}=lxJ%B>N!2tbwPG5gHs9a>EaH$eo8vkJGF}ncv5Brd^;tGQ-I@<*mW@5c zTC2JL1-30dJZD#<(!P5LX{#p4Hn43L6!gE<0EfM5-hW(MWaJp0laq4mG0ZLRurN7N zqv9gk)NWus%Ofuo9MnSa$RA*=N4dHh5U1%J9_gn(a8V>pP$)a(JC$V3HUP6s-^yvEHWwg z*Eu+~(XvU(I@OaVhQ_EBGQ5dk$E|McvXa?<;X_zXEI}NKkC^az0f6!7a#ZvHxm=zMZ=|n~*Bg4Q1EGFFe=N`RX z)xm%9nAo@u(^WPzG}jB{b1@!*h)d0D3+Vpbzlz+uV_FH8n{%d?zewV)gqF7Mr>Ie~ zkt{L&q@1DO%j$PcMB!JFEl;f0n_~V$p{+@Tdwf>bvkvU^-{dDz(Aq^dX@<`Dv9S^n zl<8*A7A74JPj(S@cL)RdtM0T z`3A``un^=#lNNlg*1*+`j|tV9mv-I~Ie}j6u*Sx0_#j&^Fn(uIRs@xk1nf+NkT}og z)1+C&gB0yxmAjp;Tvn)Q#$+}TNv=A=W8YI8bS#8fi{Kr93r$-4(dBGRuL>m=Nl*vf2 zKNo?AhWVMi42ka#K6cio~$jfa<(5e&`^{iZ_NLeY~n69~Hmd2@4``Eb5oG9)=@#&!&^AQ!<{`7Rp z^Wcj>Um>H@^DVf%Yc=!?eR;OfjxvJ)`QhZoVGF=F^P+kA>x)p+i;^*(jnLrJY4zpC zdBP*D%eB89f+38cfes{o*P!DE`q+y)7yUA&dwSN=J#ygR9IdkTFKZ(54@KDe1{%$y zBUq$z>0IM9pA&TaQoR?R<)))@;|61fa4L!)cR`&K%Unim@@-}8pnFH02OTho{wL`% zFxo#~IX#>g(gCT5WqHVXHb;Y8${XL|ghH&gFprOI=GYw(0U?PenHEl$xPRA5JqCZ^ zHHLPyTbKjCAp2glBc!hIC{UeS^C3UTYdAcV36T-$*c)A6fVnnW z^s8^xShjBJ91HTOiSziChFd6T|5)y){1}o~1vkZHU!Konv3s&@A*Ze~GJqmQa_yca z@t)u#4F`3n1$s!o&#<&*U;6VM6o!y)w_YBCcDCVl*DZ>5US2L9HOKWlCKVz=$7Sr2 z^qR4~CFV$PnyN=UJ)Xer5H8#A4$@?go7f;5*ktuENL*LWJxHg`XjnM@V<7V-C9Dmw zeK-dPl!Z==f9-P;0G(^Ul++%>>p%Z!iu5thk>m0M{l$4MY^)M-fDSfO{X2ZcrG?Z?c1#UrjO4|{86i#RB#PW_1dIFoY~EAH?K|A-5Q5;O-^KgOhAEZ| zi!(#i?QI@;0@Wv9vt^8vXato*q3UuM9sM-MJ(koo9NqF9sZg9&ifxt4KUGthn)9iL zfcul~albFb*s!02Rg@JmLEp#5zT3S60{KVReOvJ3dgOvmqO2fi=^>tLy0?c~W29au zva(p`hwh#@1WEZI7HZx$aGw^A2&|GfV`1x>mkPldeI6`rXR;R;{h5;{JR+l0z)-1v zx0ZR~{P0P^vA?K6{cPrV4#-f5iP?75?SNZ!0y&q3z*CLCb^XFd_PHj6XQvwGD38Fr zh!V`GV6|sgG|`BT(oY_cX${F4vTZFRU$KiS(kPKW-UVTP zD&AA4E@;(?ogkE>}Zrd4uEOTT`&o@tT4?S@xDJ&;0 zlDP^|;g0&j-QIlF+T*>yTC$A8%U9)i_ z(_{FgQ&kxhtK!ruJj$uHN zgTlFkaD62tPIDZCT2Rdzk(eWid`ROtoUVaH5711kdy{V);OPlOvM6*u7?iA!!GXniX%`lQs zZeU)Sor{#`r=5!W=;C@Ojy{TkU1=Gd4-Ns5b|6O_XuXd*zf6EFQH}NSpVwp%@;f9; z>8zh`0uOQ5+Y|poz!dG~UK7X-DUzN;- z_2$OGL1mz+=)0p)*HeYFzhfTg?S&Xz>sYdF<|VQQQUBFF zynb{&l}h?j!fDRcr~Ek8(4Ez;4dWl4`XL=25o$xap5Vj|QzMbp*f#StHw!7G&$+xL zrV7v9mXRT^ZX(}qy)feY1}ZLVjd*rsksP_5O_rU(CxNT3h15%j^J*cV%*%UN+=iLd zQD^d*<@x~eqmt)J249u)dua$n+k1k;ygMJyztcl3n||9(_f&aX5rtDmrjF}PTKW?f zTz8%QzP>1W0j5PSQ$+KTKk8Q%uz+I@;(~+HK(eU#bZWTf6LlS_=p4DHxKNumU^SH> z{V|F(uef0Ra!Ujm7%#Vs=)F;vK`KeOH$?F$L3n;VAgf}$X-?f5eoe8~6dq=X-^Q_= zld_|jNvoZmDC}a#lD#VlsH(=oE$)o>pLR4yJ;ILzZI8oue0 zOILC(W*SljXMf2%JyD;RUvJ0QoB9$kF|9(h0K-c#CukLkJo(n8MO!Z6;7os1|hZNO}l zTBzTSDTmpmtFr3N44dErcM+A(^K@vHs@X?WTSg&-C8Rg4g7LmTI5ih9fF4aQ)P8kNXU;HS+$0qwCp#sA&+MFvg;l0d3rD3Q;Q;(QL~{!M<6}>rsMe z1Xt%5!Y_`5oW9FmTL``kmY&Vh9hyzp^g1x?lxX0VTXhWZk#_lpxTP5HDE6L0=raho zvXQFYs$T_`;8_jQG3feZ-s;b_oK4f`1&0LFd~D;-+P)~C@9TJUp+4%#cb|R#J+sT5 zqIJ*|WNr=rNRpv*I9iP7mB-JbYDq0}C_#uDVog!Cns*OtuoRR{nr`?uSXJ$KHLPRr1-8n^N!bkn%C>7q@gV#3fWd>nAWV}#}O%8 zM&DO46`};*7cFu>GC-j~9`=TgJ{5?TjLCy#kM24yLa<8Y<_UQJ@>XKZpuanBHI#QY zy_mR&7I|esg}imxbWnz@*CAqV?ra^}bF04dm7i?Y4p}`UG3WpV+RSvSb=6ibqRC(k zK`V3FAR0{NHu=OBSGivhf>0Y%s0BsNqaRM@8q`Hx=Gb6oI2{Nr>d^4QrB$Xuw@e`| z-f}V3(?*66l`pkY5#;Oz@xmR`85o6C$?D0pzJ8{ylR3`jtqvuXfA>%(U2Zwax!omf z!F0&Lk!y!0dx`0UD;@jKS=a)`R+jAmJ^~Bj4XwWmnJwX*PGUBOf!V18ZRi!xY1V^YA{3<~sOjjY<9|GKDQiehVsW7)_7jt zN)9g@sFI9{ekXoKo=D&5e!k{&850m@BX=isQdnWdg1DK5Y%z@sLzsow44D|TzH=x+ zKEViGLLlEK_2g@`&oprVFnsbsyvl^<$LxEK%g5RQ3QqNccE+Z-z+6*);->@Deg*BX zF6{# zHkLQ(4AR*lI7Glw=+qDn|3#iz^PKCYAFX_LpO440vsW|f3+05y;3sSBL*l7{C z7#pjPyxWxQ@}hv1%toLm>B<;^XLZkK6O%mW+t8pC;t>wZ93ZXa*JdT$=yYMM7<-_invBste&! zsxPx6xqon?i=pRc&sKP!`chQ;tiR~jo-Ed@BpiNqgq5CzdJ4v6B~qWbM-5U`EAWOM znc(fZN0u{7VHs(+-)CJih_#9`y#T6lM%&@92lL%hnCC|B5_@5pgl%$tIr7}=*t{~= zUs3hbSQQ=GuJCeNZYOb_TT_p=bF@#KzgdpQV>FRv!Oc^buMd7eYUZt)Ru8F6 z=>sx&Han1~LXeO}RW5xVT&rb)u5Z0qUb{KWzMCL!tCcUAnc^d%wMmSKZfPjQLgQyM zPF~)nuVfvIKz#43Mpm=`PYXcc-V8CO_%T2lhuM)Aui9A2L3g~_jP;l?gzmXBvS^Y4 z4L7Wj@eo%G^~zHWx(*p%#cAFtN@_>sNRJ-rHF z5rS3k@xw;mum4xodq>0hMeW}+dJBROU7|-#1kt4tB}$0i5+Qo;br6w6i!RZLkT68A z!$?u0moe%fdKZj7yl3)#p7lPz{YRFyVlZ>x=iK}3eeKT`p4BnT{v#QEoyEK1<6}s6 zIVxNJCdap4lEb^u76bZUK^)*b+S-cxnP0oD{?Pu-%@dmmMXd$>*O*f^zK03Rr^|2R zZGV109az@0jFMj|BLCI_Z&Xxo<-0qg3zTqaVOApnTefM@5-goj#Mevwen({~Q9HoW z!yCMjX8pcR7G_>c5B~HJVAUXIRl*PTbkIyAy**DkN5v(34uC23wVZ7dVzMXj@ zrx{4;V5E>?n~w87x|z2>dw|)U%IuEB@v^NU&ZS#rbDWW8yr? zEDw$WluY~LHr+UeBt54bO+&p;XbavZMdV1U7y||IZNW^10gfdFIdX`L)En)vpz3oP ziiLu{D86g2rhhjq>WSw#iF5KVr`wR^kR{xy5<9wcpLf4`4xa4jS}S|P^BNgnd0w1) zf*;#2lvVH?nR2Od1P=;g+f_L)kuoOHu|%Ua z7<_%9Ef+XSrh$>6)5f3kD_<0Ssmq%zl*_P~{B1#^oQdxQpKtpi{1DRrhPMNL{p31 zc4g{(B~O9iy)8oXv#CS-+SebtH=t)-IXykiLF8`d%{+)8@&UU?iBC9N3>~q#zH+{B z7P_Q#Jw*Y#bz^fYGn>(vH)ezMKd}U}&%(OxxN?#QysJEZ#~M77zD_r?!Jt~jeGjaS zGxzkiup;V#UfDd`-&j-gAm=B_)19mxF{BNk%+oYYYO);#6woR&R)O3)__F-s;@oy% zU6Tp$T0UQFr6Q@Tg}BTdoO(8Bm7ifODmuj>T|5StTfGEn?TC3CdMRg7faF*kQ6)ou?T=QUC!G@^o{47sog#q&dKL* z9$X=^S-dzsUAZtfcRtKq_eE60TdN{MT;9d3)FH-=@fECkk6+v6XfOn)QMBm;o1a%N ze7cNtWjbHXDp!?z@mH{h$i<(loL!D7_cr!XPI zkG-4Dutpl_&V+nkB(?buN+Ge#w2zDC! zdwa2E4DlCw%o62w=7b2&fkO>lohBC?%VG-+#R=QXDj*RlM=(+ulvK{G)V0R`+VCOr zjUt@IAYMG7g~Y{2{{r%iXv_ToFd#BI$^!gdV766Yp3Hg+?3k34WNRyVuAy=IC8)1J z(hStNimsPnqm-rmg;O6BPBR|Ra(+HPt*0VXfgIcKC!0chdIeldmV#8H++A~P0^w|y+xfY^?c)A#(fvH}p%^kuEL(!{GW%)0{% z67JTEUz9Mk#on=r!eU_}5AZRqdO0rKaSb5dAkwa{?*Z?>A71@lh8a|%qR-<33WwM! zu@pAjq`UI*xXcqO4-<~wiF9R?SkJ?(|AsYDuir*{#r&AF6cNHHHXm1LD8^z__IF-B%S5dT5x zEe1*E)B9R&j_4@y&eJgWL&?ry=1Zo}5tC2XqZsE^X;PoKl`OwD@Hlrkyf4uKUv5*o znXSHMExE;7h;#l7>;@Eby1V|NHX|Z-v7i55Gd%nSf>jy<**(@InQd5p{d&lrS#xEo zFy~8XQ3E$mVM;klmyKX z*Qir?((Y#j6~J0661p4AAb^1U_PVkm2rivt|E3Cj41UaYj`UeuCHPXKfk=#$6Pf&y zYJ;$t9oapLjVTyq^pJoy&{;jLQV0ld7`1^hr>}dOPmm165?}+MXm}n&SAeAHScLi=qI(=WHE0ZDxdFwwkz+3e&Q1pe^C1d6O7a3@*lg?{-6gA?c0vZgz-t9K!% zK3cgfoc1xm%B~bUlE+Yuz$w?%Cn^q`O-#P6H-vtKZU;=(e8UICZSH#{C6j39a-q-u z;o+gS76CY$sj8ClmAvbKj*j9L=Xd2Y;Fm^4)3_L-A$od)0v%8<-)-;A@`Lxn?D06n zt{<%R^2s38uUpqtHO*>a9h%LzJO%= z^U)fad>=am%}2Z288zdO=M_$=^9wJWylz(x1S0Z{1aiR;hdhVosDUgd1=d`h;uX5! z;n(u(VNah0d5=)jXS6ysdh9{{{+*E=bsXHw+%fEQ&EZzp9waHrqMQfi>TYTB`^A(C zB%A4B6d@B*E9>hS8<@(pv@~_3v8uh{#wt1J=uP`lxoq>!YF02tz|F=A(_-cFdD&ZX zP?BW2$9v0UwOt~=IV{y!s)Tn>{Dy&fyzq`ndua#IEeiXHx2M3u<_FXQ?dmVxrRyGt2q~Oz zINezM3wd+BJ@*ic#XiPwiVxkQ~w1 z-Xu{r&BP1#ot@(vAl0lL?Tq?#GH|MZ_Z)2E)5pfSc)17 zgI@eWZSUx0bn0Fb|K%PTmy7S|y?jlzdNL16!o9g+&J1qoK$?|Hv+5AtZrS+&w*KGB zE-wCQLM~P@$88bfydXw z$D$ip({_~ctlhq!hQ`Vlw^OMSM4_pZ@Mix5}Jc z?0elBAA};^S0?Zb=pyaz>>Gsv&p?D&oK`xhBO5M%le+(eL&7G|Fu;O$d^lF1Zj|he z1eak;4zuv0Eup8#dXa>*XbNK=n-I}{vYrs$UPLUu}+5C3l%KOPlw`d`z+y>CYh}XS6w9ApKhNEHn{Gy`0}0tb*Y&Y35B0@?x9lV35R)})pti?`!)Iv&OKelQcW{*;yWH*&MoSg%k^+Y1!yzQ zPMcS+xVVDJen?3P*$e&nsnrLk&6BZ>w@ZQw`%_d)P7bm00ms{cftN?VAWTi|jAzD> z=Zkv`(HDOSvz8e|8i%^0%(i|!YYthc)Jk1$QLKKi*QCCVLa%=haog3OIjDg(Bz}4_ zb{nzk)zTR+w*F(K5?*D; zhk{X@3m7HXKl6tH%b?Xm3?bL)JlH*I5SPG0^5MQ=D2qP#a9~Kv*3tmk)r1r9Ln%7*O?TBA8@luJ2LHLAM-rA|_G2C|a~vyRgfowO}P z&BL3sW7@KD0$WNPVG1HnUfy{nh?)4ZgWDmWgb+IpQ2*7Cnif~Kg_3P;vHmP}wzRgp zRQ|b}BqZNjldE0*u3l*8PNSE-7%2d6nxjN#EaMr}%2Oh%b{qm|X}9NBbW7EBG;Ck$ z3D&VHC$hzriNf%Rn)3yIAtnA%G(Mo0xT_O62yYm~;8V@!Eg`y+*6M zYF`BWGr>xK!XO4o#R3rZTM(+8|MB?<2_{ZN8EQkv_RGcF<5 zA6iCZESeN@ie4_Xxv#H#-r*r%FUI%4U0?smf0LWt-9^dmAt)CVI@SC^^CSqu5#J9m z6Hi|is0vx;;BSjndy)Zz&7xE*o78nX#%@0$Xafi39owp8$4g7LtFBEE4F+h9_0#+P zv;xy+Q^5L}o!ZNNdlQARG5ez7S}<8tu-?Qt|Hb!WZMA6VR!Hnd(a%N8ZuhU)raUGC zaH=ASAUz#Kp-__I5OHZ~Y2Qs2Wzi0IFe2!s{zN_wJ9yZ*luB^WqbcuFS1{>TLFTrk z>FX;RHQuF>#&{5NgJFkkZ*Q=;moLJf*D&DS-|QS!9scgX%|VAAEMoV5^9NYAM~BF^ zLz#SEZGf>vA=08mKEuSSrTP`+?S)2*?Z22nF_z7B!g}`tovWOH4JX35z6zYW#TY#s zAfxCi<0wKdjx-+KWCgh?muxWx2sOKhEHAm0HFwhGhx;#P@9YCT7sLe<1D@uL}i@k}o(kme$F>7gDfn zT3~QMHEzHw2XdE=!E<8QUvspvr3@!wCQaE0tcz5l)~w&Ud=6>+AhK4S#hCiCVEs$l zLBE6OPHb(_{=)&gp2o{%J1@EdSMs7b0#>d;z@)lQ(_#o2o-k0!8|>iVur|aCqfyc< zqG2bv%Iq!+yr62Db(9SqLFuY5%Wces^p5w}BL0kD7u$~;Q#929w8hDJ(Sw?_u@Pk2 z>+21f-NfGzB5LgH5Y@P`&B;l~{5)jNt>%>KRF$js8*F^IYsjSaVe?S20jINnrjU8; zF48n0G}&Yd`*Fe1`EEJ!PD+cVWyjdr{U~t*ixw7C$8vkD-N-ue*c8L7w!8jHcWECs zv2$fy`Gv87p`M6>4E99EvgtMXoC z$obW^wbg{GTEoOI_z)x+SAmp0fuJUbmHWp$C5+l9uXJJw7FD1rVKRiC65$OW=T#3M z0$>Gg$J(_<0@;TT*U0PPBx{Q&g@xU%jJXyxI}Xexm=#<;FRfv~tiWpBP~?z}y`2vd_y0XuBmOnwr?6 ztjvT7rds2T;nLDo#zlH0yH2An+gl{Fcf1PIh}V6sxBOt^7eVm@qAiM`9jNJi9#$vpu{rR1OQ-? zItm)cF6Xl`cC$K@{+-pX6iC`3U^s4N1!4q7LNh*sO8m{P4AF+JU<0j)U>gdaUjYMn$|x_>h`(&BQ8Oi-|&>W=H9w z3c#z0bcFu|f3DdF5fcMpQwljdda0=A-*h+=dVxEf>Byv6nQVI?G9Wcc5S}2qZOf)a zvTzc|T9sTv^InCZbkGWOgYweic@D6(of9{Z{?43Vn{Ud#A7H?>Uk@?RY8i0Ajn2a}55WKMi&;YE7!8G|_%ynQ83Lekob1H2cdET7oy^UD{D6ed zy5&k#PF#N{%7k<*kNnZbr7X;+7OulORg7!nYHaE6=jK3dJHV@{0Z+uyxiwU2(R;v= zy>&d~ww%_{hvz+lr}8QNC6X=;W)+QX%@**x0DPwZ91&Q}?b}&Kh6Oblm)CVPe@ldL+0RH8DT55?o-=R6W+3 z;Gc`xBZK!FItL0hd;_VYn7HBZau$Nd5XVlemri%1p8<(CJVe|iq7hZ;IO;hwB5`-5 z(mbHqYJEKZ`4FBdcRw#e^aNbWRXpV{a7*T_XSH5fKrMf45W2HgGC3IrG0~DKdML;lP7apL&WWA$3JTy17pgLhl=gbztW zJt!&^2L{|$n#*?D!WxOPxNka3qYndW>pTt)Rcc*%nT~7^h9!i~Eb?|8RpZ!XJQh0J zF7SHP4#M|9&N(h@LV=Be_b&Tm7QdHnvhkyBn23JQ=}Z%6nN8Q#isxq$MYpj}wO}?j zdtHj;HG;6*C{u@p*=3WmZLEzaf7c7Qw_rf9BsA&e{nc#LS}u6_D;;-@rq0lOL&S~` zW9dNOY7K};zcN{tHY-a?;Dg&yLaiy;P{K5{#zPI=nA6KWE;pDHO$|)Rwg1?xtbeg+HX2V>J4QOVRvdu+_x$yCc@LlIoWBN3MMK8%+?8Z9bInOkx3np>S|9qAVu%zNIna2 z{#)w4|EmS~>o9A}Xy{!+&@kj5$GAt!y)370J{B7%;`&tFFaXyx#feD#p7Oh6>x1Qm ztOG9d0w7G~IYtWA^4GlWU3k%l4$H&4XSTo3%i8~l%fcL4v~rSd*YXO^rVn zg&gg)?M;Aur91Lw0|H?e)*5JdL7K}mxA)TF28VAG^ep7=qe6(RoWEjD`LyGWZoYTv zpPW4C2z?jQy&o76oJ5F4nTY;fRGq2s>91MKG0Z`BdT+Y>A8eVI8YtZgXY|OSnITDz z1tkZk$Atsk(eE~NZ{C(Y2V*Bd!>x3F)7D0tZ}R|Sf!i)R2hpVl(<{=-%75V&$W;7D z@3+XsbzXc@|iA z*N}J?oD|xGCU(8>aDIFtyTVC$f^K;o;Ad1$@5$Cdeh+K3??Z@1OqxPRdMj!3UIZ$1 zr%JL^m7(v2ry{j%#_+44sR`I%02q(l(d;@Ng0ig|9Vkrl4gVjtwm%m#mO&G3byfds z2_;ufKbT*HDI-^VUK|`;zL*$88hLs6$E*CUcnngr2=DSupO`z@*(%)uQqjmQ?C36Q zG0o4|cihg^909_w=RFU%`lunwu43)`G&J1ldM|ud9le|{b$ocam;kXC z)sfc9&2Ja`suD`pWK*B+a zcemYiM$BA&`?CXfzCT>d8SqG3xqo>u95Wn2KW{=WOtQ8KJlmjwCB~z%LHUnq^ z;zL~Oa79-p1B>x+lBb~sB_Mt+h!Y5TKbTsz_@#`SiJBfDsdC%16$aLknwn#qO-*Dg zS2JEQy2q1-nKK+NuPBm@7Lyxw5omL%d!q%9*`Q66h}J&e0_3z)kjtvi7ly`SZEfy1 zuFi!|$V$g72;6gMPE{$HYhca$#2Sa}#$&5hKf*LP>s*V5Lqa_{xPFJwrxR_>MRA54 z9foo$JZNvf;i_G+^v}YUlIk;xh()M&(rMZG3avCjXGX7y>&S7hgP^Ob_`heXe{hEe z(69rbAr^-X+<&jLVy&E$u8bS+Uz;ZSxH1Mj`(73Wr+^PkD!!oK!>gYw3qMrP+1R$?y+hP<-NppJxTZ!WRVET_RDXQV@OmL zW9xeXYV>7gPr#EVg!cvW!SO)^*sEruexwU;?k=XJASel{mEFXv1US;(bv|{_w!bCw z4y(oI-Udsoj=Wd=;~CLkfR|7>PEZwRQt~IOH>-col~ZmoUbBYOvQm<~@^)+!64LtP znp!>W69EV?HGErd1_5pl@3+GbwuO88&d>HB5g_=r^f5mF@jccvLXYxlTQ!8BMa;;F z(pmW8F`VpAF99#1M{t-~SI8#Of=al*9B-S;LG!QcsWhL7y%nnJ3Y=WQLc2;swlkzr zjP+#vlpBbD{;%tCLME9+=x$aowv$l7mf^p4;6s{B&iw2@CTig+s*etazv;o?XD<;NV31=GVaRT}K)BKR@5T%!cBtSqQhhsg!%{0J8-K zP94v;nvSv^>jM5z)%QYY;gCO6omf`YDzu|3leqLmB*MIn4Wc0J>#JLEx1G$`=xB^R z>BhI`1e^+yzu~|##)%s{xIV2_zUvflL7SX>q2nlz4SH|?H^Q(oxIq?fa%fsETj0=~ z&MLC(^PdC6^XdK5L!q3U%4VhWqxtyOvs*Ag``9Rd07&scfHle?yqD5_%@1`W$>0md zcT;x7kB8t{RKabZj5zI_%k*7|kJZ*mNH4E+-O`>3lqVYvhjqZsNP|O9r(FpAlP4QVD4Lar9AG_T%&w{yNu(H>MU-9E1 z5-l{))92RXEiu2Z_uB*^h z{FH0-KpY(I{now|WuFu%5v;6%{93>c4mGD82#?F5Cs+G(2bOoOjunbfq;wb2kXzLx z*(_scUoo)=NPAlARZ_AlU&y76onGCW`(Y&P>3)-=Zk#&2euy~w5l_ytKdeTw$0zjk zV5@9e)O8!XE8ikEWG`t^tbe}uZ%5tBQ8hf+TNZN7!Cyiu+VFvCgB4pm?9ej$u42&y>LeE-qXsO)>4{knIkXp8y7 z3vOCvT#rOMLfGBtD{ri0%2jWX6TL=+Zp9>=p``4El7jVU3dUC@MuRucY5U(HLLxoL z(Tx^~2TEZgY)U{{_~0@ZDEMh-5sU#FWn+tW9xuD@r>Z>UOtc*SKj+8Ckiv_HPG5LMrM%_a1S8$F@N}E(r5up?Dk_PkL8Vnv({wLTmMNNWLC#Gu!gX+pbz!mb#`6&sgH8I@ zN+pZeFIC$TdBYi%_rXI9X0FzB^_w&wo?z+*kw4w2>Q_81rP@G2EE6IBXgt{czwLImqc8GK0f+7pM((OWdTna zqSamN>d@-cG(Ev4_T1JPm;OcCpNF*pu-cEto&sXX79uZ_Af&lo3i?F^x?Qr z-lRx^Ev9%+Ht<9DK=q?HBl7#)53Hr-E)t-3zekFNTvoUp5I}7q)EE!a?pq&-@Pv7Q znZIPv-;9Dxs?WmF$Gz0xaS%)BsbGe#A$bZ9YrcY~+4V;x z1a^ak7P<$Xzi(j%uaQNDJK4{S-=(~ra!H8TwNk&oFMrX`Z)|>i5|bfqeY2d&$~|HJ z_3H)MU5Jr|Fz}F#Cta`g^@2Pokjg+uk3R%L0$|orCTcuA>V$kgIH6`SY~?RY?^cpmDRGfS{>jKJ`SN!Y9Ded01@`eJ3ugabnX>T1Pq{EZ6v_!w+xz!ZI?Ai6s)n~!Y2|`h%x4V^+zP8NM=$S)_it|ilM}uqF!z3T$K;hG z_MOS%VF53&gLO&cdDZp&vQ>y83s5IWNlP#TC77=m-DM&m{yIJRCeEUM55ghw}0x}h;~jb>jM!07x1cY;&uGPJgK$UcscjKqB|%xv_F zyqO4>SgbC;dxKw#4syZ0-s-*j-1l&SCx3N_0=%C6Lq0QE65Ro1(F*>YWG0py4VA9{ z^1R<=8!zs@e9k@~b$ag=X0wvwP06JNTeqw_miI!?CnA&fuL_$7-3Rg&HX%zY`$E9k zr?zg9&90qdX&idAB&{nZtPk<}9e+07|5f6O>lUf5fR(1~=WAat(W-*|)y?^;|b`z(Y~ak+ECmSM~+gvLKbGWoVxW+bvdriEckp z2WRf0C%1CJIeoK+tA@VV5hVsv38rrus7mmx<2IjzLpJayEDC5(KRyVlF5x4u<5K?i z`8+KW*vwpXk|BYe>(&YBGcPZZSj`6!eNrty~*vDderT($>6_l|Tjq{=$hw-@egCKXbY4m6SP&GuQat#0W_?%dW-->}9sqb{*hgJ4pGDcF z4N_jA8e5m6MrE}4ZsVKJ3#HpB&rxb*V*->xc%?+%eX{fYS*;?xSHsFCv5}c357>6< z(v~HdA!(FtRUusEEz?VUjj&T-Hsab`(Ikg2%|92e_kM*hef0K%$2)|NZ))oSft3w! z3LR05Oc8n18CpUC?$MflFNb9+`EISooUsFf*lm06>{mp07!we4(-z}CP zrKqNM(QtatV_FiDQc8s{4E=$KbQ{G4`JHgu0jpt9~59G(-e= z46T#_P$)Tpt-YfAz4IxTTo&fmks`={1@eSlu|$vf ze?<;PDBe@U1@k}yx7fWx*NPC?UiPuBOej#jnQ=UJl@FN40)^Jssn8pasi3FX0c}3E zy(J?Xm|_tepw$wy@3nUpxVE~{{nD&s!2mP3V+(4#2QB@Qh6Z0iLp zHd^dsp+>&IJ9hST_=nU>cGpo`xn(vN>UGi)l+6~D4C<%-FmvW_j?gUtw04t;HMrv5l!oTPIcNBmpOela7|aU2-?_4 zbS;B;Y`m>;&9J=vd2q1ZwXJPe1+wntA9FR5;Gh){Fk}w{)%IPtG28XEdmVmh8V6=q zIXE~JJxR>bVrIqWB=G$cohNniiYF@t@rnfX!T+4KY_y{dlGR(2e1r>Z8CL9}m;g)F z5?FnP@7Id$rrHguA`QD$PJ} z5=mKX8OmOB6Fb=b7WA`esPi8#4&+VHGa{@TOl1tr*F$a)9~jh>*4_HHE)x>iF^})P zYh@GpEhMON_%B=z%C4V|)xM4Q17WfI z5v+}fh)qJJ{5Qs}e3~D79h|*) zMk#;R$hKs64F9-QHX3aIdBFwMUY-S%Q-G7Vucsl-4`99569NxuM~3aI5D8?RN`K$J z^UP?cKEebRD;=vh8hTJW9D!i!Pk$1(qJEMWK zhR8F~PoBfl2r0WPCubX&q>DLHI;I~{Ito*V0X0)`*W$E%ivO206Ceym|D8Xz9yVnk zVI}ra=uWFCurc3ux4UBHy017|si2>_i6`;Kb9PjkFZVt3*~!jc;@2ly(vJ^z1mQxB z{R0jnP$*Nwh|I(&-V-gYgW(r6~1U2C`->4wnqUAGrIw$4^{AJ$`*uB)xAEM1$ksE2-Iuk3tjby*oq|$4cp-R zn3mX+DVdR!tgS0r*A$N+*dH_*@O1$EbCEU~iDzqj%iJMI=*q!fnRdhbp#Da%b1qOeD^Wg?hwo2YiMZH9+!aVw#6K%EW&qYN=+cT;l zsS&f1sQ>z*=>~#1Z@M{Q$JY4+$L0_rxYg{p6v`*;hq~tR5Z>{}?{=D-oUtM4C56%LesA+H}=jZ#a&BKhh&W+V{ zt0B^>G8*lr-caAtlYli@Ah+<1deZQdqxw?35mdz8ak}zf58zYZ(}u_`xKF>l{mj6v zi1(>i5;N@tvKZG}Z;+(_?KPn;K=?y>ohkK<){=r8+ z)q?((W_P+l%`0eVU_=e`=^zE9Y@r^M1ua*AvSCv>J)u!g044eCxo4gcrN+-uSOT9alTqex zrmSPVWLrEIc*|~r|B}LI8$OntFwhu0#z7GOqB0Uw3egr_{x5^Xm*SnA*hT=}G^tA* zV*4FAxdACdADf_V^})<${tmI=6S3a({n$?+Cg-pul z2g#9Jg=syCD33dAaTtqgtJoNQS2(k9-{t~AIhr8yiJQdt8nZ5f*Tyh&=bc-B?x>77 zijnSu)=ieVdF5hO%OP0i@0g3OdPLptQ`i1zwkbGn@`YA8saqz@7e9qKe04qhQD?;* z=9V%5G!^VvZj-pu{u&XehB^@@B0LaYJQN5UrJB@)w!Ec0q>cjB^V z_;v%q*?XO8pV_L8&Tn18#n$&R`j4N(tA%RT_d@2K;(-Vsa7(eL>&3`~H8hxys|ip5 zQy5hos{DomUAb0-ok+y%tuB6D=|7oY$_FSk!N$Q)N47CNy#@;?pjQ&IdH6Eb8{2+2 z8W;2J=;JR*%p*5xk25$)e(ZT1Ty%42*x)TM+Tpq@)*VgpvzL0I*Q6aJgAOncxu!DU zuhv@$(cP?1PRT+x8woS=cHMBL{LOt4*jkqpe~HkGZnq|Mj(DUk_ZTfJ{`y)*uWf;@ z%xPeQ>>5x#(0v0=!X<;EBpYzj4O@r!%d?m*Ncre?7CF5TLEYe{y&$acM30?3a-~Rza^k%wIN>W(&n~m@FK<9U-uHKo5lkQ zz!Uz(gFb?ClB+kF{5FvzPBy=LbhMkVzz`o!o1V5!+vV0$T$lLv66U<6C=QWk*+7-D z5B4dSEri%hqP-=;8lFDy{vvDwdU?X4&$U>;o2`?LAA}y=9}#OU9Zm3eX3?}?{IWH< zeMarT8yOknABJ~Y-zsx@#snn68>Q3~wu08}!s}FHH4vYI$#Rt6$IDZ(&5D~Oy8#y= z6YQVh6eG5z+qQkKe6;94N4AwQb$|kYX$k&Z5Z!p8@-tNfocf22_%_=Jz3k&V;3q#@ zgITf5icuyA0e_3h*PtSz7<3ie;8`pr6QAMk{2=j(U~^a}aZACEt4w}XVT~5ZvNRjS zG|XIN$Ie>=Y-nH77N<)gy*g>+gf4rK`YU%c<6iQ0*Q3Ik$K7qf4lr3*N7*!VDhYHK zb+rSL!66o+8Mcp&P440TL>CJ>Hofz_9xVGkw3*iJ_|{qnN7XLnr0tK!wGbsdOOb~9 z&#Mp1Sg3a)eLzVQ5?ojbQ?M5}5^k6f=6*mTQlQyTg(L$4XUWNzwvd-xU|Dy&OOzCv zX^2Z(%hanIkLd||J+m}PO!6=_?IgcQG1R#@ZFQ9D7_75ao$F3N;{E$6ZM_+97g;zI)*gaxi(qV3IK^Bs@5H#7p<3vI{jAn(`59D&F|F zV|+XhlqaccVd7)vKKx4d3>f`f+YTbd=3F!^dD2_U%HDo;vaF;Uyzr<*^SS_~yzwY8 zXya!u!8))J%hw?g5(c#gclCuucT8Z_#+5myZCA3PO$V?-()v19qy(4CW=Nffza;$B z`Sq?j)z2DYb&`d(7|yEX44NLnE>p0vZEQe3J^3;+@$uL3YAH%>6Fyt2pX^+4Xiuz`D8l1OUh&T@1Qq34P|n%*kgz$c&o`g*T1g zZJ7?se(T*f98-q2m9;E^`60NhU!O~|(peoCc}N~sJ+G8jVC3n%mkla`d9(z_?XOYR zT|#Pku#+L)k>m}t)^{6xA5MZ!hKpM-f=9xXOSA|&^S8h=oRBajY+60H>|s;PMrZ?W zpXhN3VPMUC`Zb{juylSy%J~QIO9#$tWOAh$tJpem6I2vUNkO8a3;a-NtfVq11HtyU zDexNiqr>klwTn?b4O37Mxm;pp=W;A?D2c4 zAKnA3oq))pVqTB6%P}?^vwsHr`ZOU@9&9|^mpv8G)%2C=p*v8A%5>F&*S(TGGCIkN zI8r6$>438Bng{svX<}H`+BeE@t~*&L5wgy%)i%>kNS6cIKL&&cw#q%~U6>ef2)ZJU zb)qRT#oTZ!pYa+jrPt#&n*nFP^@j2uBh@UZzxAo{_>(e~CeTmG(|KR@Dx8%lCg0%puH3{%pigNvX&E17K zq7TMk8A-UINqJ1$3K6Ku4&=-oSgovGMq!o-Vf`phBEzQnDXcjGH%Z=^5*Iz1>Oruh zPa*QB;%d0x?Hds?yuOaEZ##5bkNF(b&uuxDgQGQXkdW$L>=zYlXI(e5(aYO~^yBdz zTWIQzwr!cXd7@{b?7p_fhOSCggiWc+#Zi=vAIui8M5^3o%W#TaIOcpbDtMHJWOj+v zT|_w@+E9s$@iCv7q%K?*WEl7(qE=jG4C?Ejyc(PPUM%!eAxp?nH!m=UI*yj2@L$lZ zpX(1FcP(W55l9vqTj#g`%vsj;oNDWL`d*^+P2$-hGriBut$`QcUrpC7UF}{?6oeONwNhGtrl^s;mq@**>Snww{-)E>nzhxS1ULfwIGo9~*q&Mdb8+n(5-tz!ynA z3?{qjAMfEJ#d5Q=Yt?B?ev)`^u{l(ha>~8_m|6Sb-*^4*x2ri)G`WqbbbpYh)>cwSlx&pRLQ*SQ$a$&)H`X_y%LBRX4BQrwDj9$`olmwMe;mo~ld zKY#lFyhcThM`s2k>D`tpIJj$GZ8l|~i2bm9Ck|J9@t0HgV$?N{nq)j4_W%54G4J&$ zuxIjXp(p$!3zw%){I`tr@`I7*(xDM2<1clS3bRnAFaPi7MDNY};emp5)Je_-Gqx4S zx)#(jt?~*QVEp%3N3SxhKZH@z7|02vRQ{hoZs^Ucd&Oy~IzUraa6U()Tcy53HLy+> zMTn&o%RL`fdZ-}tHsA%3WL32U{$l+1j=q1Ij(pyMM(fTrM4WJ*L$P8ZZS8NMjU@LL zCj|m$qs8+1(vI&(=~M-5{NG<@F9~j7SC{;d9f;(wxQhk;VnJhRdXkmbok)noJDZEM zWnE6iX3h + id="color-profile11553" /> @@ -78,28 +78,6 @@ width="317.53241" height="106.20419" id="rect5387" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + gradientTransform="matrix(2.1181803,0,0,1.9900553,328.97283,-280.16098)" + cx="-294.20374" + cy="282.9751" + fx="-294.20374" + fy="282.9751" + r="62.682014" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Kafkatorio + id="tspan12750">Kafkatorio @@ -5251,8 +5636,93 @@ sodipodi:nodetypes="ccccc" /> + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + inkscape:export-ydpi="27.614807" + sodipodi:nodetypes="ccsccccccccscccccccsssss" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + =Cj#dqgB;mL19}GufMD(-1O}otf=_ zzu)~|508h(!`<)q{d_*}_xtmU!Q54&AY~?nKp+$v>bLIUz9s^nNFoRX+B!n%jQa-e zp{${cz!8A3j>dgY;-+rof%`EU_=Nt3&BAa$Wb#xo^t|tC>*;Oz*aqV5?JZ*O;^^_v z(#=N1_3@+3O$BBMgae{+OG($~`-YjXDV-k64QA&wdS+|CkCDzZ2YJj!U`5J$o>NVT+6w{-_-rJsfq_JL8&dK8y5@n0J;~H z(-JlcM~g4CZyXiutZ8mJs+i@wXw)d$wBp~)K=Ai__W^2NC;onOdj;-R=(CDmqFWkB zG*0gac^~kgERHEid6Km8SKYhs;U9x9&d*N%)%_gfrCD9*S)ud$!&zqVXU2c4>EDb$ z$+!151F6C$ZyI@=t0 z^5mQWMgTxkQVQ@s*KKX$+F>vTAaOs_!3Ur|a**z&?s+mDEx=bxkF(Xc70t)1g6CzL zAXa?Oy!KZo-WpWYwz&*-e6MkwDmQcVZ66<;51!R{OCfyG@)UrKlR?C^-tAZD6F&4V zNgtKa#gbo(U4Rd#7uN;Pq5h-kVP(^fp&8`BPdXY|2#Fhfcj6K70uwJbHywyRig za_@$X*SO2u+FDxwy+0%QYE+kEb%J1KA3aw_3!jF(l;s782u>(LvTT(Iz~6ngqB3j9 zJ6yLcJV?@g2qk%b;qr|zCVt{g@_4>Mg?W?Teo_Gz0J8f)HeKD3>d(rA@dVv?Ri^&p zuh+rnN6W8+lSQ$k5yPJd3}~|AZp@X{&G@aA)xE!%4Zb-0Hyhkic&p(f0P6APbc4t8 z7ittWK$~LFk6LHkhgNUP#rerr%f&L=?=DcEhbZ`}t}KY}fsg6KVMFX34s@`(3izRU_wPr30`zI=|#S?cQ_A zyKk9uHgO_$%P8_5to|x(NYGD%REM1(pco29H zFU*dpYxRkl*fwRKfEOBJKVGbpuNse#3qC*fm8_WNXAM!7l6|ZB2iH~J+|4%hgrruM z1seL2A&>nFZ3js7SYqOG&9^YtVsc7CEyCJLgg|IV<=s*5zWswv3dviY@6x}MRaZ1*Qf z=O0{)xB>>MSTFkT#Ps#=Lhn+#lSQdIvGz_kvIRl|sq6zi!gkfA;kq2R~2iMef?p zs$l#N|DRCr$Qcu`rc%8FiH@IS66)_RbjP#ExHy$$ExB{h24;xZQQc0Lu<1{}l5|V3 zUr2@B5gbacq8hm%rwiRZ09yBK0C@egRk`l0I~Y1HJADNzg(9^r$iL&SS)A$)PmHZh zT7lEdC*R%Qg8_xch9F^MHxOR^j;N(JFW%k_jxqJ5CU$WF%T&#;LJ4WV8X5IQo&5D- zwGTgBCKrAp-fwEt_{ey}#m05`*nv!odGj^T8PM4-&gyj6#2hDqMr?HOZu0pu*Pnjl z(Zms_(E<(Jk#xA5^#~kiTYLqd08GzC43EywO_qLPLW*?XU!Kfp;A%g(fL_)++|@pU zX3DtYUZ;mfPUON<(dNVXr=mWggm(f6R>e-q0z<*3M)xe=PbV~{RWPV0exQrc2krdD zx$ftaAI^1svp*Z_C{Z+?fd@u7eS<@plKn=&;a|($Q>3rK%uTB6d&4)WsOMJzG|M)MOxB7r3tkby6Lt$(MzEBv%4l~ zN>^d`^VK1RU2?}aUTIoVcEdSJVMJHRC9l?&ghRhmY*gkx1iRQFtWrm@T=^zL74#tzNLMzu)QwYk<9i^@mDy((f0B ziJ1(vYU&=H(bU|kamdiz?{K$d8Wjxtp1eW@G_;3?HPI_I1%S!BIUOW?IFD>;COEVXLhHDV-QbzznTr(iThpt^=*fZ>g-&k*CNFkz^_K z(HraAl$vEAc7Kf!u_-Cs{o!mjOedPImOkzY z8?tvA_|HxLBt|t36Qz1@5gK;^CWCJLKh-pPUtRY zJ?rv{HY9^-ThJ3l(;9Q>3Jz%`x!~yw`FtSrdU#SBOe%sHC%KT*lnN=Yn1dO*I(fYh# zOT|qY&y{}M%3Qj3^+Rm~nqYwoYOcK@zTVWFdjA?&~s4wJN%j9;N}d9c zTSxxU0Ubo0UiI!}?~xoGQmJKiFei=bsxLc%j_HMv8o3(d2R73*Hf5i)c@M%np(Go5|YsiAzePX3`5bAJt2$QhxP72 zzwEguFhR(;Fz^x(8giU~Zn*a3oo_`;$9Hrz)i#{C>z@Lb>CvQBg?k^zf@I^I>@+=5 z9ep>iXeC1F`9I;3{ZM{)amTfEG0XOF5}NS%1n>A2L+I!jkOfl56b(?9OW zYslA+BAW(JMeyG}I;Q}DS3HTbEx#5FH5r2J!WF^F6qPN>* znS&00MX?7RDka&W?kD|u=h$}gP{@mAQf3B&KizI z@?7P4aK#r}Us*#z0-_nJYbr#;s>S85dGy;y(ewt7W~=<+5x^Ca(HeD0K?|SFhUHiO zn{qvcjVWr$_8dBgCVuX_cc<%SFF!;1J_9YpLyu!p5T3qSfCs(@^pljA94EuSFG7m{+_<@VudQUl!;B zA07!a&6hXW_-To~C95qZ><;(hl$D9Pmpvf`ee4AwwMCT%j-lPd*B*}n?#+r4Cf$Js zx-mvdm|qdB7`a=LLvA7+yP>qsGdBkdXZez82DKG?)vcsfj56Tl|1<1uBN-ouTD zUr`~tsf)zkQY^Z4=#PKg&{Q-G%8!dQZ+lKA-K~-d-O{dRr*(gBUl~`NFr^W`IVe)-rQ?|TTGThInnyC?sC*PDl;s>m;@a6E8*mT zW6Dud#(EOmG_tt=7v}cY;jdg}A>eOtLg09a-~}mulz5*nrx+Su1FbdReoBslv>`R| zy}zm!PN3O4KYFw6PC=V+4MZ@Q?GCX*yd|yJXNJOpYU!+{)AdWl5@it1&9=-&7s(sv zhYJac=V^)hWyZJ(6}vQ9E%D8StbW6m<-OyvwLopwDm`lsIKuv2wg&D%6s4Z1?3`}6 z|1+3$Q>ET!MYpRZ;CQCWFKHRs5ymcV!^0HD+!nS={hw(>9r{1UCQ&tr2T)Oa-KNXy zG+g(p-?zw?dP^j6M}R;>rz|w=F~a;l` zZzt?*pF+r>A7hEx1OB!Vvo8jhR{{(_nPI0&P}u3^PEg>2cYDI%uF=GC7GlhJ>&I~6 zfxl;&NX9Xe#Cv@us5oY%+Lh_JsbppBI^6T>UkvC~%Y((HJ7WNAtgape(0shbdAHDO zQ{ni_-$3)}z7hF{cV6}n|6q^Eu$~t4ylN3JhLaGuJ7qKNo0k>-@&mpNS=9{o9w=^i z(r7De!#T@9Pb|f9&h?0-s&>6|@>=8y9I@LxoVLv0+Svj0Yh2T|rF+`D>DYyZ5)hFy zq7m75tjwVjW<1RMq6Z({iec!|&L04o7fsOs2>rSO12-%vN$c)9S?Uw)i&cTto?PRf zZ51G{<#5uN*eDF`7}2MAE~QG)2c>|-V|CIdVRS)uFsrz!%r~S;~%4#fB%y%S%n{@=KH7bc9s2B zJ9)#n+F_2N)VzP5H4;kjclvRS^=k!afx^@Q4eMA>2rEUUifSCAxK$@&X{bavabZ8O zZ9|479I^suCe=9|qLJi%#o<{i;N@$fb=A@ECL-}}t6(R^@2bd8C!391%_rqH!ORs? zm!#FK0eE(a24Q@hq{mow$?k-ki5!dy#m+pp+^_pYeU^r+*>Qw5(Ui$a^TshtIpD17 zySRu)jwH}|NH@RyO=$8%3&v>FqMYF3t2j2|h}K78U@Vez?msMvWZY}z=A)+pc-T(d zqce~G%8Z$&O!<<3rZ-CKRxz^qA{$`v-W9(P=~syWNa;@1FWs^4ZfH7CQ$lL8CnXsC zyFysIiIh{XgE~;{!rj6j?S?!4INmX^LSSDUHC(1aIbxJ>E$NLd9cz?KUcBx76xT}! z?f9(jcYW>aj<0BZeAu*elGB%Rzt>Vw2R3b0W|E8TbI!pF)ED1KKe=mvGNm!jNb$*F z0pBpUej3qxcu3|CbkPJFpMD1RFtFA%T;8h|gyu_@l`WJwiF2u zhdx}Qk9@-PVZIkkg+|W9|606FT`}fE+h#LRC4;U)+*QN%ln6$oDlQhrbZ5p0*M!9S zgD;F2M~qkWOUa7Oh}vjuRjolwT6HcUhh$=t0k2M489|ZnVz0$bl4(Y~RDFFqF+cyd zpG~jx%NPEg-#Ukxbo@8e0>6L(qxs-Hdf0a?k5mS-yyvOt42&$STu0|?zW_+wno5NT z2Uk1_Gmawr(=oW>DwHvxlSSgFo>a^tL^6&VPJYItWAePOZQs$FM{QH6MV-4j$rA`l z-`tHMGaF0H0(i$GW++S&B}XaB=$m}WY(2hsirS^BA!M41bbH))c6WJ9&->0|BBy7B z(clZ+D)|GyzZ^pS4yjvTvR7h>=rK-DS-AD9J{4k=!o?k3$L zrbRq5LbraF1?O-SPfV?kI%-gMttN|Jbh5-vOrt7Kd4s(mq7xShjCaM;B8xS0K362| z^$S*f+UXZGrlS_(2@ZZXzw-5YdGJ}G{;%QR3hrS}gvR+i8r5y+r2o_4+WSgkaQHfO zv9IO|4-ap77j}C3Ppp8%Qi%gz6NHCH0FcanpNvibcvR!5ZjxJ!Qc35iQ)6kyqP<{? zey>2{q~^NO|H@l}v)2NpiqaP$zoN_R1RR-%dG3($7&a;!12D6+L$ZLtzQMzZu|sAy zV0TbvR;(+(^F4xa9E>G0Kg^iyO$tzR8R!F`cK(mModU!(x8d+T2v0ntmZyhGwU^_i zKcXLvzue1|vtK(oS;J#JsGi=H26GM;DmJ{4Nlk`w@`J(?m`0#Dg)r* zgw|@P|0YI#VP8cCm6!WNC&gW$G0FR54ZpOMBw z#p(Rxxt@=%@g?O16p9PA8eCle;XQ6f?HB;&9*3VGJ(uDlM?b+koFD`VP>%XkLx2R1&};Y zeD-D7L~klXt6zF)Z?FTOmUpfe!vo_nXxL>>aWe3aeqGBUR1)l~VGL32`d@=p8D{Bs zf>cT%%CKt@^5Wu>DKzrPm*^b%kezUx*~eLzFq?cB$R0ZbeUy0@LC#;AhpjcR&c`g$ zK->^kKdTHSkquWS1s&>0Fl+vs7!!X5-S+&byXbn0BG~FZ%$s}v=Wf7e#Hzf2KF6F; zX#|%J;UL%5H%7azG%%3*K$1HqH2y_-l4`tX4%#UX#HcdN3{h!)z}hN- z?T$J=^L0J-RZ_~)Bc#e3fe40tiXd#W1H}lR?Jtf4YhmQu(7d(_YTY-x+u`%nq`ej# zCcBd+u1))sCUM$5I@tD3&YO|sM;FiG7V24GV(nqb$xVfj5H+l{z-24%T2b^FO%N3~ zk0j3x^g7AnIX{FBSCE&{g-#$soIoBDXQ?VhVmIis-No=AU|Xg3LolG&1O7s}l?T8@ zCYLonV!nC~-2z?AC4}!>2r-+_98@}}mw!M-aCj#q)=tS%kQP&8fj|3Jj?M&D`oJ!X zn!1~P_9sAgym-4IgWToYX}DMhu39Y(q~Q09koUk@Qo26Rte1$Gm(8au!<`?QPB61# zRae&lh}k%&TvciB05B3`Dwz2s;$2PBw}mP26bozXdV?z1{0}yj8Eo7d2b6eumD#+NL zBBbhqUaPf%R!Av*rRRE~Pcjl*pE@b*3kYQC5OZ^I&?b`Rn0FWJ^da&n0jE9J_WSJT z95yn-miCrlC>Dce&XJU#G=ABm)0$~fLI=vb6yo=GW+{%zZd*%{s{4~65QGIVMoBP(VYHie zj{;*GOgFVNeNH*A5Wwg9c6oBKTZA=O;AKEahyB2{^3d@@F3h_XG)xwxedcBGKO?aF z?5lQhFw%W#yvSZXG5e!LkmBe7Ai$}WDrEHDIwsNagEB3b0EDjcYoBwWnAkuQ-cH-b z1^Cf%(9YoY<+y3x&ej&SzMQk(K)vfGv6vqL*eK*;Hm6+udN&zvf9AJ`KXCkSK52e)7CxHX~#8!z-%=r=+Op4(vQRArr8 z=vyR-$+z+C&Wc3DgI_`59zZ zeGMI((HEz$mrQe~+8KzKx)m_xBO*ptLKpH}EPOrme_ItV5&1OF0NQ2) zGx#?O&Y#jVS+|H^%xi>2@d!6lJ$DkE9Ihm6ZO0B+35(g&{XDC@)jt66Z5cC5c-Owu zTFl_KYa+9e@@Mb2_C`9EP?B-PZQQTZfWU0gBF)B4J7|6+^db zi9)}m&4i?}_M=WgI?otL)mv#H|7ux_--OIFfx0m&JYp_Z*%$d>;#gNPS5_&u`M}qdHj-)Wm zU@1W)4>@ATu?EYaKvWw+8E&rc!Bmw!I}EO3+Mb4lsa|2z9d9qhOOuCfcO66eO6}z7 zkVug<0?3M`p@I)~UxI>5z3inHv)K`NP`-T+`=-wBjStPj@oFmeL zI+PWLEf{K9C5&FY2awnxfaPNFkM*Q2MSP_r-5*vE;IN@7AIghDN$D`@=MUAY%{WM^yE^{6%f2a~;54Vsy0IU{aVpr()Xz`ALi;M^Nno5MZ3%t0w01UI^^#=%I5fFx|Y2Hv9D_teF`ihC2KM2Iv zPQtO{IRr)$zd{Me@1+Fqr#TQ>-L{*#HC3wf6a$*kd42alch%v6F4P)O-#v%sW3+OBnVzYG>O7i zvEt&JAh);YRC7*PrldFkTAx(Wd8R*%B~TwX1Jz~PK-AZSdmhDDEIqo}^^29;@!mvm z9IJ-G;vFFa`EU18#kLp+j7Hvq15eD(pURY4Hgyzlph2+d>PHQf4HxZ{Q7hx{aM*jc zhM?@LZ$u89KbAkJD0n;UL6FDiA5UNIj9&V1?;Ua5$}j+iqOIjEJyiyV5N8WHBmV-p zDWkxk$9GoVGrIg?H-7+!;)86W7X{$}@Z2LpxC4zoUWRMrv7{S6U7l0=SV}3)aZDik z>>|pp(l`nCAPmlJQM>2E;jB#6I}eiV$aTu{o>$o0>oXgtjW+pI=|_a89LQ>*HlC#v zyaN!@$Q#U@S0zK}^4Xhtl*@)ys*O}USL{$u+iYAfHXub5@uQmMsaFWu~$defzym9zHp!Kl}o k{>Pw$Z~JVC`-kk%93Fwmn28qL^L!8umAkjfl`TU5164+adH?_b literal 77215 zcmV)gK%~EkP)1^@s6x7I%U00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmYE+YT{E+YYWr9XB6000McNliru<^l{71_1&fUg-b;AOJ~3 zK~#9!?7eq*RMqyz|5-DW9(qSWDJm!`qS$*u1>5!7yI9d{!7DcGz4zWw5D}yZ(xrri zA|>>aMra{~l8`_kb!Pwm*zY7`?)6^3_xtP5%|H9e%sFTFIeYJSul25Xtz-OO`qyf) zZ_mk4`>Stz9pu|?kNP(80^eFO|NZ;#-+%x9Z~AlZ`nLKK-)?=_w=0}))6#r9yTZ4d z_Ugp&|J&|lyl;;0?%N*&zAf#e8+HF}|J(kz{r_rPF~GOeuJrAN<-QHv@c%IGbWjI| zpXS?|m(}s`e+TZr?SI?+FV?G2zUZHd>pva{$07-kRnmM;4IA+^B< zcWXdzdfQ9--6jpL7d`H3wWk6B0>tU-H}rX^!S#u`j$sT2JJC+$AfO{1qu00KAB@8J zYWx50S^l zdKEaA4gADUd=7*OQ|mvkJ7%)lnSb!R4yd8V)qh8v!=683!z5nTyV=tqqQgUjIE^FJJfhp+3)zIX*&!FffHFdcyfc3Zjc0X_f zH}JAwkoJWJVldd@cDTI_yv1AO0T*(i4byL4sNR1Ew4epofxToe*(*S2Ix|Vviw^v? zK#-t40d}sPOJm>`Zn2AitGSxL>$sP6-TTy!8-P}{vfIG!v-`LTxRz_l2j(%)`Ups_ z()mB>{Ok1pRRY!vz%H~4xfHmZ%k50y9M0h^pb?E|E?`@v^N-N^N2U0ZXPRuJ?tS2lvD1e1AEy^Soa+Tu(Af%U#D)))&FCF{`999n9E#d17jHDeg-$& z&88KQLk>OkoPP4xccXOvTz%dPSj}qpp#Uuv+z2;<(Lfei?gRBp=eZAb{s+Js*6=p) zIFGv@z|C|sY3czn%DnJ_pNH-dU^&Yf4!p!mya{f(TkfKE#oN06qaLUj3_QXkZa26L zm%%IQ|N8=_TYxsS!NAqJTK5-VHnX`5xQxpp>mWQNJf!*%sOeeL^T1b7RZ&$@c01Ij z)u!!90>0o2m;YxMcgj@XzOSBkd*8Q@2p?+x_McinvUnbt1PT>^Z^8;?5gLSYDyr}QL*0tXP z1~b^61bf+D<{Kb^1RJdH-vB~{Y_JCO4X}YW&<6XRfai3*Av*qLKQML|@EDKrkYAuS zNE1=^o;{)CZw30$hkJkrc))G~yT-2J0pAa<)$w=gcu{f>}>siqS_OHL=w3GIFS?WY~VPKqmw4y8NdZxKnI{PjX4eMP&<@Hdfun$ zzM__2vf9Jcc2wK>pI8R}8~Zv694pmsSGz+Cxl9Xb9;t#mZ6^a*#3Hr<>sUuR zkVz(6{O2xBJNZ&w?>Dtt7EV+u>GeS7R=d^A1=2}(qkxf&WTO8cZL@BS&ih>L&p;Jb z?n7{M-CQODZ}YbM9GJ#5UWfrezb;C)Wgf6@sW*>?C=hRJ`a7K)Cg>nO$uDCh48Ci zNH!mMlQ&rgmSGvTP{5;!YHNX>^t7eGLKfOQu(#|j+alnZBNuEva4{F#M!!SZ7O*Gm z3Cs7uV_WpQ*}#z;X`6r<%&=^*2{yrsz)rPOEnCMG$wJBo&gN`31HbW`Z30_ti)|0s z&33bus2^GCZ<&6tzyq4?16HttDzLS-*7kwDVQ*M5Sa0iXWq#t-d5A%v2~DijTR>I< zJkRr1>vwcBusycNs=(4ModU3T?OkgM_P9N6C1A(ev6c+h)w)`tuAd^{DboEVs_p14 zEK8InSEhEI+Df%ufD<^ux&XIv+wa=w=h5S0&x>AXOU&;$oVEUaKPXZ^57F_3U`N~0 zmI8LC-D$N2CS#`v;$!G+P%@|XuJG4 z**@SYp0Yha7rNL^omZxDE&=OneQi6~RGVtqz(zJ&EpQ+A*?!IItonHromV!&CfHUF zptb?%OJCdKH%#(1-?oB1X-|?5w$V1)R{xyYsCm9b8_*)KN9+;H(z;0V8@O%KJeub> zAj<~(#=fz+z_)zMuey&lns76~uC;3|2*K}y-zAKK)az2OYm*I4E^BgGk3MIAZv?_98sV!J>8RIXObfA@=V-^P90@>NI;rH0y%fWYU0&qKLD z9(g2#wY9buHJMichjEw<@ur>?f}L$=Ghdd=Hdzw$fI$qh#TtqQPQfC2U-*g19% zIl#%BY}@2g<Y@6)NdwC#7buovwuB`OtetJNF|kJVBgty)9h5%?`{vQF5yzE!yRk!`Oz>^T45Z|T@QgTyr+jRsx zU85%;kQxR-nFaj+Nc1uFus=X$aP1lt89*}xf`!Diq!UbCA;9>)R0 z8E(;qQthv6#R8gaSvXt4x>+~&0CSi_9*{&*-HOZ=hqDK`gF7rBPODfzyAG1?O1>+x z2s)1JII{gU&~|9sq3!!ZAv#O;Gbj%^TI%K-rkGF=gej zyYcSEyEeeqBeot<&=&R`yzk%xAz%`dNY;ec{aBO(>IyWcIRQ=JEe*)^lj_{+e<3OP zCl1=~1}+i$9rKo7-Sy;}xg7N?O1e&qQVas#UEsF4Z8Q~WyAYVgEL$zE$AC?2qSCuc zRB8d&f}LWg)VY8O0*-y)R=5?E2$;%%(TsLG{dMe1KaTA3TqJwy0o&!eTq3~7e9Ue? zPuLFZW;Z!tovc%IKDy1|HoA@Ww7AOcz?XcF7u-hRRbI85fLdzZVz9s4-|azgc`lEIo*Sjm0}bOmV7pZw5bauU zH@llT85qSVmT8=tfDN^wZjE1G!BZePCpo8eDg-(QItOoo1EB+l^Wpexw7_ARqz;)!Fi4B#5BVIJ5B z8(~v{4s@^;y4XUQqD#C*#9Xk>*4d&g|2&!GZ|Xs3f!%JmGhd%;=OIHDQYJ8zq2z*f zx9+x005(tkd07_0d|mHlSvc9Ua1O)(Q#|puU4W76Cxq2#$BPHP=4(Tq;_XP;LgCE?g%I!SU#|{ zKkUDF|HWnNp?q!m+R|*Od8Ou+s+S>H8Z3>Q4RN#LW+irpmRnkGX)+%U`RI_34vD~t zTTk42dTS_|Su%6i-H_iRzeV0OSXZ#FAm=g&PYh3t?9+4G1suaMboApw2Yntjxl4f7 zw5CK{)4%%LBKTU%+PcpUkNLiuYLRA)gR0PACYsMdA%=sG*W{o;P1LJP9eZEQEb8=#UW+ywz_VYO!ZE`st`0Pe0O;@gHKGIlkmI>7a9z?sNNtwdtbLN-Spr?bZnPVjEz9B?Ey!HpGd^R6 z2Mqh%KVU1=Ku-gn=4tx^>}h+NPOgULi<>WLUI@i^?!Kqs9oU??f=RbQ z_3|C(uj&t3`zjl`6mWfPL}0ykq}PD4jIA4tPIArm_zCTPgV5)p7voz)hn3CFIp|Di zb?m_@#~uR5esb)I$E}4U{&K|SM`yyCL2CxBYy#`YtRIt`3hpcSm5aJAn`0~mfQ$Z@ zQQD~u!re6*|K>5S)Bz5-8Q$fwuy*e0BArv^@)Y@~6rBYmVOd7eFnKZ9!FF(6I9%gu zb7X1cgUfW8)W!hQXhyTg10aRE&K|H!?2d9d?2zWMX9u$H-W{(k6 zzjlCo&%H;Ej^76CVi&n!y{uPVzjMJ&aZ||klmlxOrCY1$XfD`T8_ODSqueOg0e|Q3 z6aw4XPKF0kH%Bh}?clC;*SZw~w(I2)OaU8a!&nOL1NQ-`9%x*YYwZg*$OdsVxbNI| zEYR-+)$cZ7x7w|&kV|D!U>wTHA4 z$$a7Qe@ITZq$MXnYF=tyr;8vE3QH(N@HC~VP4&QIX<&ET-4+F=xw1skfe-k= z=7POwFIu_~U13z4;aPn$!N%D*o8*DV3S%s)!#UhGE1WwYY_JWsjS8bj$-FJVo!m*5 z$h<7?1KVl=SDrYW0`Hnxo*#HC0Q<_mvOED#bf+s2N0ROPXWPN@E#EeSeQY0FmG{N1 z6avQujtfkLGlrcp?9@A<@40=??Y|6ach_#)HxBYbX}!L91R8Bz`omLiLigiJ)_#8} zbiX$^YSrs-bY)yw*|~tD6+QpO;!Y-+reG)AY4#X&8siR>j)G%8+#mN#DYSoL-FvTG z2}S43ne;{x>>j>jc=q>j+>qmjoZ#Ss!!9_i?;>dQN~2d&UKI)4Lv0s5r)=q_vVmhc z_FuNqVB2Hl2rX%8*81bXZt)APuzj|SQU_J9>BsPe7u zH|he<1iQs<;d{BbX}W(gIsD?kw+!zR2J#_wck1r;=K#O*Yv8+ow<8_X$hXHX6wsU_ z@3zU*KXkeB%ZbSXmnMmyrL`Ap5P`~W3X$PXS1Qps|i_! z2SL+zJYTa4LVxEf*8$?s=6%-)LMs^H+JN23E_W%Uw&w8KU2w#`2~7%qh0t4pVs`?h zEDzmNy&Mi*82Dk;6i7ID-OexHfQ*|m1`NLyl6oce3KhUbTtxqUaL|hfz1XG~SdkT3 zsoKNzybl9gX)FI_8$B+1Ua=M1KDD`O_j^~uTF9d83JhTgJAtdX$~wzMFY*9um3qF? zC0UZ@MJ?FrcDhw-BP$16U<<4XSb-JTUd^Xc;C}A60tF+aOEOtFwjJ!R_E)O}8*QU) zmjI?1c%S#JSV5D#7>=q1Ev(dA{d9ow_N2Py1E+GT zZK#ia5h7#@z+SaiS>?%oTMHb`(Ja&TmWV7~A)v`uKY#X?z7+`AC;5$;&5HJ>sUH%8 z+FZ#$W_utf9XN@T>I{LOz>cwFSmwD+OV{&@0?Z`IRnj1MUhus58c14|w5r44e;X^m zSW)(OqX2a2A0FF-9y|caCCMeNx@ZSzQs03(;F-;ATj9f|e6JfACk697ue_|g;V7A$ zrk!)99#A^iRd!XK>y)9LBpn#XI9mhup1o(wweu?)Vk<>Lr-9{Jp3MR4XZ`91B17TW zr6QTrwbSeXJJZgz3{8L?a>25E^umh3HrNKs(tU5&b+Th7)}b6~dm#0~)C-d`;Nqf- zi!Od0l5&!A;va*wacSee+X-8b-+KIt>wsL=GZEZIYZ`w!95}u9g+M%{_6gnWT0)Z_ z<5#&yAoIP(ziU13*PL>6fd z*emvmwFDbuV=PaW31H<`ZgF0pV+nG_OS~}Db}ML6BFieQ-_O@LRrvX2m0%y)M-~sZ z!*)=t`MObp&#?4TQGhE_|M!WD*$$RvS>`;qXa%zLqEXO7S@79j4`xMvev##=f#~(f zs^2K>FguJj0?gIG_k7O+0Yr?YZ^zs5wp7Pu08j9QZ4)q0RS;vD`ngT6>d(MY92E_o z*tcLO+sT%#`8->K(~oNhy7faqvD+Ll4m z`$_LNJ;RgI!4Ll(5S?|tIG|p~|Is1AdxQ5jdJjUCp~}QVVx;;lX=&eTAm<1vC2hA? zbpz>OGi(ME1VqDPEQ{XsW-{1Jn`z&O{M{NOl|PE3Y@sCOnLesuFUPn-DWot_6LO_o z!3{D&qfwVk?J%z^+`rX7X!0~+GGj>2Te!ux0*~@2dE#)QE?0Et+v)*_8kzhC@$bgJ z8(IT>H}>6lK>&iggS%ZX$T&OW?C%eT$}W{%_Rjj9@WD|F`!9FLC+0!Q;Lul*Zy_`~ z(1y+sxW|3~u#fE%zJsdQs)mPw&>}mWuOYAiUs>QYd%^*YhJ@Ny0p*iwx&frNiubzc z6Wknt;8}5JyArUaOtn{`G*I<<(rrK@XEPEa{UiNr(jl`~X0I`oaLn1qoPGH)I63d+ zyweL{&R^#IW#-*b+`qVgSz3e1QPbf6Sh6`9u3y9=qU_}A7?)-q^9U=t(@o^=P9Mb~ zH70ByBuKU2C=i87Q;l1^!rJlRwz{npO7WZGEi6jCOTb=5mrClRfOf8(%U=CoDdFRO zaUXkuPxyoaMb*mcxiK4H1ELCHdlB41w~(!#%OqD((5(`b=K543w(34}!9C<2Vq;8L zK1`Uc-nAlE{U`u8#0?==!ohq+Q5S=~X0N%W;C^+#+Kr+Z7K#&_>n%dsdh*-N0e79d z&TjAqfSV)B?JBVOHlMcO9&wMj=~_p9#bpKjx^;QrE_4@KU#~O5d7ySPrGGjX+(qsp z%zF}U5(Hep#oYo4XC<7~s?1YwMStvy&6Nez?GLdkppT!9c(@rrL7|1|o2zb)Iqnd$#!Sv~7~kVu^q!8qVM3kF!mh2w7m+mTeoQH_C?7 zMw~X{)RQ4~SL&{m5G+VukUXkXz_asrVd@|W(E1&_t11l+-II9Xu2+HGjG!}w*SMho zwXaA10uVaNegbIoOUelVsTagO2#_)(ZaY9~ZQMlwNi#z80GbsgJOmJ)6S*HCTAP?N!@JZ7Z;yw$nmjl~!pv(gC#;=df3nL&QfP&HT8V z0LgaC;*nm=Dt)xaQo-)ByKJ8pNU67YEFxELuTRmiU2;|SYF_S^WmY0Cac>OAGn1K? zrRYyoz!|k5NGK*&k^@FRJy5eA)#|Z=O!t?&!POsztlGbK#3>*QIcp} zN?c0voq7PT3wUNXuz0=}@Jwp}Jm1H-T7TnjOb7eKKCy3fz29Plf_gwU-p1QpJwSbL zlNDv!0JhYY+7z(%*4{Sg{KayG^5t7El|nRIz_dcH)k0Y=Yh+5!75TR@#-(aRBirIh zKo*Jg+^i^Gu3WXv&}~z1 zmcVv^&^>-RB&-f@1!#14+*JU{*ZcFUch#-}hz|ztCJjz|r17Hs)8Xi!LKDiy0Etvb z$y4wPNXy>o=@&eneewEeB1MFNo*EaYK(F&wQcV0JUyLEh?+Rb2pvA>WHw%S(P zMuqP;isOt5_VVQtEtZmfk)pGk1gPotKw|x^zb%kLdy8Dgh4mJtwYT;*59}BF#byGp z@QTgTb6p?+m<;y0eQryoYnvn>PgB2V$wi%{^|4&zH(t+SIN00vw$1f9Xf{1&-8Z5U zGr^|WG@B!j<2wj-2z5xx_rS!AKNKqNisonkV~WMW9L#eN%njxy+%Mo6E#Q$#$nF>L z{2<`@w1LHwR*$T8NE;wvGo{0r?FEN6ONgH#lY6Qj&~)G(-m!HGAC442tkQ9FfSb6< zeif&)K)!X9M4P4iSgW04smRJT;+Aq_IE%};%+kGn#ELu#SjS~Ved#O+CIyp%O`+GC zUTcmofuhRoX}O<5MaON=FYO13Ii!RS2iL@nbqk>FZT553i*UxnjlapyfzXq7a_tBR z_*e)jx5e!Th&wdUA0U(yNCOBR6Zi!nbb25QAareDJV5B-z&L==O=@optkLn)0D>if z=>Va@fvo^d3KCWTB>xt7rSg83xVxaw6^*8Dz7o1m4i%N(59}clo7G=+U)6nO+ad4G zytfzr42Lv5q-oa_X#7Cq2U0^|RaRwP8?;^27R$0(>s=tr1Ew?G4pQ4TCTjH{4_c1j z!L5aY1ADa)BN`uM@l*l_agYVT&a$(t2JBgT*7k`6ZVXmvh3xi1KP#5LtVWz+aZL2B zB`vKI>~Hor+X|LxnO3ZnhN76LXaWglTBzm~`*Qjrk`WPg9!O@CFvo z3?XY&7c?sdd51BK@4OzzqFLz*qw{V31GE7)fHgYrIUP4wKKgtmnNHV$YA50sr8aDk zYc)-|N=srS_U&kAkNV_5%a@KR-%IqPJ2i`eLpa1XN|Blmhi4t0)%8wDcF8W~3@E*4 z$%PZ2gmWKE{cBDtRP2h}8N3w&Z3920426Wx?B1$pA?`1BShyI1yR9cc!i&M90fN)) zB!J+=z+nJ^_bm}1kir50>tW**vG@YOdU|=F8>w9KgFICjnc#~|M0UB|0Fg|W3=qD+ zl>#ITV7ekd&j3_k7J15Tfj*m3vNjKaJ&%{I>(Uxh_Xo~(%^SvBih8-A1``PmAN(ECK7rdXC7YximIt{%?{XGfzU!O<-Tx7yJfpx|_~s z1y6p{{YG_e-IesZ2;8&oS-af}W;sTHF<+@kJ$(v?n+)8}?KV()rC-EV&GIQ1c83Q@ zH`;SdcC~bH5%uG6>E6+Mw;+A=RgYEPjh_w;$%xmCkDJ*B{e_-*WkQZ!v* z%OVNaW((ln5CATesrj@=auzDQIvKj|>AL5zPOzhQ(cTSBpyLSRfZ(&%2_PKjeDRL= z-Ms*jS)P0j{Tdhz5SbRa8^CSyayhq)(*S~<>{Nij***u~j`F}$J2P-AK-@1p4-oF^ z5&){4>tA~S&i**{)tqOcX1BXG@EN#U+%xVxu-SGekHL!RTNY=&2M5)3ef+Epi2pJE z$M__u-dw%8rfY-AvpI%z&LmTr@7rk;lO-Q5yHQ3NWpY(pXyIpzqf-)RoglJ0CPk!{ zT7t@Hs`lIqdx134*yHsr>=Q{H*8D2=DGC$|K#IU+xhzV2@+rGjC&$#U4PNF^2bfvl za$F9Dz_UE-a-|=7Mu3s)0m)uhO2kTV@4NTySskAzq2N6pnB8w)fNA$BTYZi!w?T?- zWq8t=^%5%1@s^oe>IIN?y;3+j`SKks^*}_bo_h!7$Su)xN)ix_5)fSjc7a_$SI+^u zX|m+{Nto#x08zBeOhC%&VPGHHhjtUVzOF9;1syhnondFVDG;a*REIA87XkS{1fUn} zg}^i|?4Pud=W6E|-+<$pE8v+PWAVthth0EAGu)!U^Gl4S)P^>UigEFdvZLxqz6l~9 zr_~Fhthe=!)iKbFX3UgtKF=#TEnUEuE)#UAcjfp^*~m*g@YIDF7b)95U&5@}%2v-- zE?XWndZ5t*shgqM`OVI6c^6dn*jl)B0VK5!uBmw+YPv?cTRbEc1aER?&)3#Yx|Te z>=_4Jp4$KQ5$8jAl3Un#JR~KB){zL2V^nSCexFhrEcNBff~~9vK=3xUV8_{&Oog~pY_4kzjlSA-+=BI9nH+8c9q#RLZ@X6F^l}@t zHEMgPYCsq1a(1fS2DZsI*HuP6>C04g@rY8DQY|=U}fH7 zxBYUBN~PDTQ1o-ZqN@9JopQ~O{SuDmihHcmdHG(KRHxsGa#y+D#kZ{zM&^1UtZkOX z9m53?B4l~W$=WE_K2Hlgr=CnEnPkfc`_jI&-@I#NIhwaC>r;%ZzxB73-lDQ!WYI_K zLM>Jj?Fg_mOS24-!cmTOqJk@F;-*Hcy2Eev^WP4)!)>UdcvBR7iE>dRJrFSl_?*w{ z^nbzu-jhM{zH~$?&}^Sc&T{I%cftNS2%V_`=&POKISKz>j3E^VFrd!j`6h(W(!b0(ga+tom44s_M38G z7D%A>nxDWd(ZIe@ALXDGtyl(~U1xW2bEuhFGqYkaY|q&_BoG1EKiJ zLST-a zf-!@(UvS6*D0?+h92W-|apr)&w4ezj6fxqkrf|u+)~&an3Mby!>d>X5p!$*Uqv4hi z2zmx9c!RI<<1VpUfIxr>fcQQEFOUD!wF3yO;9!8@&$gAGKzB0P4^5wSkMDR3N&=;y zZm)(`gIW!0dk<{Az z0+;U6De+tq#hRA^C0Rzp^p&!pc1sXjrf~NGSpvIM6`@?YUbV`aFY^6zS<)rFCYL5( zsSDXkso1V8@GMzKn`BXCsqmPRH_4J~m8ER;boFBgxKG?CZ1Sl-ZmCb*u)ldKz)kaE zbbAEc`R;t?D(gK<$=m7Pf^=!%Zg;oa?Ml%}RG2(Uwx18~a(6jSuIpq82`};WxabJ3 zzw7U2YaO1W@o?VKb5q4dMJ*!fw%iBc?sfNarl&&ed;w9G!uLOeJKP;^S7`j7Ymk!j zr|SU)yzr0DB#8PkCMwmN-aMyl^f!h4Gh@i%KWp(EX-7ttmrN9Le<$EsEP>eg7~r{? zn{BQSFOs1sM`ldU&v~3@v%%)tTuT@5#9BI?=ww^GV9OS&|M?=Nqk5lAxoQg~^i09GATGV++G;j2O0#vU4ivLTUn@q2*BdCHIke-BuJ zZME%CooIbRnK0(3U7?OIL0WkGfRi&Iu{`t>CqekT$dmfLEdYV-HWDB(+t(mSd?@rJ zKrtm5PLUO>SSFH?P;GOy#Z zGKImVQ?k9X#LFa@D^Pu$y)hQgP=?wTaegXsY86UB%2PFkt+L!U_$1Q0REmxD9H#ZP zzP3qnjio+H$4Xf`Sy~^zf!%NS+frZ^t89)o%-GC=*0g4!EV@i3HBX4q!8N0qO;L{6 z1Z4vP#qSwwSU!u*HXVfL0>+Yj{ohUwn;a5g@?Hz;#?_AJ^xAa3n|aopd}S1pp&sD#yLWTlRSa zi)Y?Hv3Pn~&!~yVWLZ4l3c1DJ^J|Q&^$-tPhN59VYXG83&Kw_IV48Ff>6)<8;n-MT zj=-{g7@wJnW~{6?VQE5>I#;m>>}UJg(v?j603>~o^g&87>}$8LU2zuy*(p%{n)MF8 z1L==cc4~DhMBb%QXd?t~vDE;@a9|qW0N6SHDeXV8c5t&As_d!a~Yw-xKqk*4uik@Z_~sC~A`<>L6;Ni5#{9Pug0M1weG=@zsg3+#1!-SR~;XDTeeK1KkWN~#qpN;glW`BDMn++}yuN0Q;B9qeu zymNHF8Cvie3cgHJ&?PpE{;s`ia}|c4q3G2&>d#C?b!Q7Wzm2KDm`bXBuL`Aq6A*o( z{{0AclAUB9D{A&(jAtWH$3C`??NiSUM@z@rr!rW+)j0p{KLH?s>+5quXhIWv9QcZ_ z>?;9J)N&au9nX87{54gCaJIWu!)f<|4j`QCRYLlbtHuW-nsdSBk%=x($}A>sIh;}ff( zYGBpC@`3;Os1iTn-0%!YzBBY>_;W}&Df9+_P4&6tmPrp^-O+9Y2={U80OEQE&H>nx zSN`!KuS5AT7Y?llyT~rGYE8r_knR%jR!g9_ADF-dt5%pd9*DQ4f%_rns=b$WIsoxk z1k(U&hI&iOc5t)!jLTG8=|q6!q|iwKjn9q00ifWX@P#Q)LpaWE3=EG6&-bnBTXqb% ziEg560rAE0#qkGAP?y`FjZ@H~yMRJ2RP2tsZ8>1S*>AQ~7R}_C9I!az7%!pX2G6yc_e^Fkuf=A z(P*_i8$yKmLF?o*84h2{Gl~M-DE0rm{}6!eHg)_ZU%tT7RM<%sUwPVB6tr(eqRnlf z<9SaVeqTG{n3x-m1)hc$&o`P_Gh&e4F#Ayte2xZSns(H0Vo2v8L00NP{s8vAy>H9) z`4shQo^%weL_TInUs4#OA3B3GY`#ZuWn5kXY;IUgSHB6ku9=yVEb*qg_YZ-f@0QE z(ZzDx<(e#MpqsN44@+&qvS8cRLF0x)@?(J z=vNy*qR8Od}Fz&G{f187fsnuMS8mey$|fbC<5YTpC_!pk|HJO0V0RAp7cN^mc^mt30a<9tycCHh^fLSc5e05w<- ztah9oXFHX=nGE)UePB+&x)rR{O09_$z&oT^HYK5!>b|3v%f5Ogww-7v+JP8XEZ1_a z7WkQ;txy)(o|v*3L4vkbisu|f?Y8-93gjqywxK=@PaE1;fx_c?0=#7^=%yfw6?#A* z!*evYRO7l-7HstStWaUSxt`mzOwH4u8(3H~6rCEXc^_ zedt3#F3Nr4P=;s+S?H0jt^(ngF?D<%;vq|yfG|pGeJ+HYsi;)CxTN7R$*Y4HWQ)AO zDQa>ORdD{~fyWjrTmG9EOQjv{EKT~4p$aEXib)=APkV+-kvm70*ec!QxEK<97{i#X z)Qn+z;4`Fih=;1Us<^5a5E>pD9*1($V*V;~BR5+=sC=L{Y|SAs(rO)${B+1up;!5W zmF`kE10ZgCU)M!43eCE4)yVsT>2~M!9q!jt^V|z?1&-^16iu_2HIG#fsIDaH zc9mewQ6aNUF_jKq6u(w8~Ww-0N9B|LO=UE|YK((0J;EUfg8{9It%%v-sa-|Ba z9TTH_E2We}!CmSubw5g8a=owYNyry!bH7PZ-Cw%6i06{rSa2KM2D=LX9yteWWvd&m z4eS{l5C=lSGQwt3FV4N?x}ZQzEwp?0oxMp6{I*F}Q&19!SR-A?gJ zZdQ09sCz;NLsL%`)Rox%Qx;GMI&g>(Gn&isfl8geq{2>mzmdHs9mLOGKU1fe{!nD_ zhdvA#twmcGP9N{Xm6jonXOvv2*R`V!1AgR3J`(WU*TCYL-2iwd$3)xCz#oC0m{4*gbj22kcExyNI;u9=B5o1O*LuG-bifbg{N zw8#%~J+d3L#cB^#)T(Wa>zHYo76IF5`vOVQ)3j8bpsm`-;#IDtTo!V)E>N||Q>S_~ zC9;_Jh(tEIcG-R&m`bhM?s|*Y&arc>0&J9xB3sd@Ex;vQVjE(TG80I!ZAz8MQNIgi zi7koAAxt2_7W?o$YehP5@Hu9Ti>W)*+j`psB}o?m7jcpOD%UGbK)yhnuE!aex$Q0?NV)Z&*tt+ErETT?ys|J>x(OT`}wJ}evU*C3{ z-NyI8UECG5cx9Zy9)JGkws6Xv z`17`34@pP4;kCy@>bTT#?Xuy(#Ro1vPy=qK+ev>t=R^OXjn>SL0%dZHT*%=#AOY%5 zh1ui9?d%aplLS^`C06P;BrCM>0z7EN*v1=$3Ih+G5XSrLiKQubZkE#^~#Zs*^-jJs; z4F6s`xnB0A-i|U{oY)B6*Vpx2j(ubw@gDvyFnSTA{j9oLZ%9%8gnsA!`ckidSnkI+ zL-b13xTHE{8WqMo7F`isk8Gci0`j1D;rmCki~1WAq1Sawa2Vc8*k1e^=(?F&?wA zs*tGnBJq`ecZvpLo-e9z&1AW)tS8OwTsxPw(7C*G`Jn-bEZuS2n$d7jVerIl<=~c3 zXt@yoWbg-eK;UiLMGe&6=z;)op+F07rPv?<8{tzY>=~Qr>-#vLOxoCj)$^d&2TdQ$ zyA3*Zh~F7M2I3k;CWH)99}4udq0s62gfA*u!Z}YhyL{XIaM88xe#qzoiN(RAOFKaA z#KOB98>5}+cvwh$onoMK%)y@0Ovgh(%zK-2utVf!C}Kz5`o zeh~z(Kd8rf5h#1K?9uXJP_nFK*`5o)YOKbJ)NW8)thSj*=ZKPr3&aKPmMcC$09E2s zAS~CHbui_I**dwPH;Plq)&`LYw##<0N*u=$?_$|pa3kGFx_Ln#*DE!lmlWCuX@Nw* z<-2_QR^jqhe%{c>bDK8DM;Ga;u>3f=x<`3e&3^L9p)^%=ZoI!g5~PC~<2gGLye^23 zR3i0DxukL4<+PuD!7&1=!cZ!`m)-zuUny(;5x>CgJ)MuDXQg0kYz=Rz+{mlI1~#zQ z&vyn3h#pp*q}^H<1rqYUEH39o2@Y3*eP*ArRf5f@rBr`d&#h4X-RMgrbE91A=LNU} zRURZ4s(M%TF1rmlhPv>+St3lODXw-q~@I1cH;XtRBlX`E0nr$UB zmwf}F(e_ki4OIMEYt|hCy=|QP0Bji{PJ_y4{fm^7OG7^Zgr5p{(zkVFCqS?&a2!D7 zQ1?DS?RDxE)l=!ch4Q ziZu`RidzXousT>BJP%rKXt|+z9<*rEqDk`=ka|Vx6^#Z!!pjLSC)PsT%D9zrsd8Zl zf!pnNM}|Yq(KSa`$3bObWnsl%VegfDuPi$sid>N^ngpd?OS|sP_fa~x0sk)d1>kOV zw^ATW;Ww|CcZ+2iT?g(%_o17lDAV&&bZ7XY^==xtpWV;)FmNSTx~~Ojx2qH@%Kd5^ zle<{uQ+n-1d(nLZ?iu%t4Zzn9uzs9Q5Rvv9^RM@D>An!3UFa7!T{Z9KfSc;3;{5mSYhT&W2KbV~bnpOs zK!m?Q+n`nWFcq0NBzP67C(|VLn(#>sS|#d`pu1bznEyO?3k_R|xun z6xC@Wz19n`(j>(CNP@hy7#Hpg&Zy&fM%Vkwbvb0Q7EfACibx!Bd?VnQ;U|F2tJg)) zfev+LLZ&M$`*jT92@v!8<@MWe5S)3hCuZSj zE(D0XJLumO|BLg%_;jCiT3h380f-#s-}oKb>zV^ZK6N_)YRkL@RPk$V3P7lJU^4+I z9u}@@(*rU;t~k7TEwow?%&z_d5}$E{D>_2ysL;usW`SqzxT$T8mC?& zb8{Qan?oD?KSRft#5n$Clwm5}nxL`}JH16kja;1y2#yPm3myku7k6EJ$feNc|6uJs zc1OFLZid>$wTm4ypm2QQ z_}zEF<@+z+e{vZ(E9!?=d&$04svUYFAgAbU>soSc7y z`zQBLd}yM5^-l(Qs3&E;&q7&bxL*)^x+$pob2+~6l-Lo>zw3pjkgNBl5H*rQ^rZxn zO{8JXkea1t=?9Ici-|%$Pn4;dHq$=6P+oU{w0vDmz!=$}yX)?Hj(E)m2zPa(tP}d( zAU}2)grz?bK+;uD3<)UdPNL+b7jL0^`amnwk-j*F7?S7FDOadmCZHnyoFW{Sa@ ztGWiJFhy+^uTHTXxIYQoE^gh1ak{7V+bNvWH(rPbXh1xFE<9VjreSf!sjmdue{9z9 z{DFIlAx15ge}5TNpbAt=q1~PB?rd`sB05HN4EqQUDx^C~*I|=fKs~J&!W*`PuRZ@cY4524MM`h00|)c>t^~^6X<*lz?x}21aN*sZSRQ2ur{)CL$g=G`6*%6 zr(Q=!I_W$OiCq%A-1Ij1Zu8w1*%JC(tc*OWo15z`C8pZH$r3=MM6B$X-*O0{Tt;rtWO0 z7(Kx2b$-x4=omRZIzee_X=?sFsNPh)DPLb}0jf2YthhR^R4FROQ>oS0VrtzYW7>s6O3%M4G57WL z_4U0OdX4Hes@F6qJzsjhU?!XjJr%m@ZMlL!;q^hc;i8@n-CTaxUs(>x=lz=&-V1fw z70N{L|G~Zuz(3IT4S@ZCHB$n}-ZvU6S)`mU%IZS-?xyMj(a0>9W)Lm5?8tAG~2NxGG!~HT&iD|Kc6^rMmam`@ryn!OKq0g3v%;hkGaxLk@uR z2ECfQq4IX;F8?gpaja@}i?eXKr#sKS3tUgCCAJjc7=a{tdu^zr0wPE1e^o7q#M(yB zM0^eIH7OsB+YGi_e18s^0SEmL`t2JHS7u+C?KmcG^ylOR?kgP0t62ZDY|Kc)LgP@1O@^)Wgion#cwonV61 zJcUE|0R4^rhCxPouY1ewF@~hq-Apc+_Ha6#r9h>C?x}m~*5-WI9nANldz+Sw?ofKD z^iW>46rj3mDM0D=^iU@>d8x@uZP%Dw6YEte2q#3Jvr9MJw_QCJ@KN*3%x zAGJfqiic$kx}U3y)Us7Jn*?#Jz8WFP$9$~zi(=Gc)mSPd+bJ2Ri)oK9r11PGg(q7I z&%r+-o|QE0IZ`Pqr9o%$r5P`({}`7ri)7mOlb1fI7rl5w#-~3)REww<5wAhprEQnq z@E<791$u7=6m>7^zH_V~H!m-Yx~TW*AuwWY&>g3LhKOChwn`uH*g8=Ho zTn_`-U$eyn_zk!60o11^#YmSJkwncd=e=TfHH&ofbvb}fgl!T)b-l9@*TdOw>awC% z!=^da%VTx`Z>xUl9j_xnqj5n{U{GLuJ|z8;^vjJ$;M}5fi_Wis!a0R=&MKMe^yI() zcn6Ys5Riw<@gN;fGGZNd`e%sh9M!qW5=gu+@xGQnz=fRR3y1#&=jNP$W9KfwAB&ZL zIC2#VtO*>}S&*{WcBHBYB#rfLedT!w|JMG}mGKbN%x68tz^Ag`HO{>IGT*wxSkUN@ z@AGtn`gh#-S&zb{$hvpKVj<^fU3&N&$U5!J350Nr4?q|*)JxE$b*;}j!gMLsysACPss{6|0?lRjtbbF(4)~!tIrEipiGy-%#-H$fF zQI2ZaiK7!u%!VE%B(gl8zQM$Y=osOuBtc&H0liso)?I=A^e4q!z;rU`LS3laLg|Fk z33-uFy}WvP{u9?yfHLeEp-yP>ZIf@?U1uy6>RBPRcFP#uvv=#fv|M{-Ji0{+%x)7l>z-TE!bucs}=f-WPa*Z%h=XS|$R(g)(J$1rm-V9EsZq zDSJ}(q^*Gbb@}Ud&w_IW=L+`zDhYrmAs|qH<-7@o3<#Qaq5v9|`|NgWut%wPSpuq^ zdK!PIoKqi1A_VQW&*c)>Ypru!1l?TL+paP0cIQ!dIKJSlboa&uzNc)9aDn>)eIr2S zN#{@MU2rUL`h{(R^;>Gbh_3?TWKE6a_ymp!91;5=B<@SxH*^y?iX27dyW#XJr(ena zLf*d!+tB}|_!LlpGT(OtLitU|=i_oEza)z1?GW-^$aldDA-!jM&-4gz>@B`{=ru^m zEjjaL3RKQ;FALZSnUkFH5elvxE_Pwe6YjCaBmjPP zI&W|h-1qCH`USABw04sKC0FV{jR=9lxk;O6d;~#}!SzjpU{~m_(4BLj`u*zntA7DK zQ_ti^b3Azp#vc&TXgyl@27cz}KOmwX^^dxb@s{cKQn>pFmo~;In00SsMbdGCL`H(1 zt!FaPV$9PY|FlGK}A9>4%~Mi9?uQh46;O00XH=lNO!s+M_;|2^E&!#u2J zOYFb_NVqxS=GX<0G&yN=o#e8+bT771Sj4h`I;V z2mF&#aBb7g)dZ+or@szA1t(K$UygVQLT|Cw)DH%mQ|)!%2JT<xE3fmKK z-TLd+U;iXjMO1|6Jp*a;FIIih6q>y6JIpZ=s#ZD2sd?aI*>)%wludVb4O)mK2ZGI3|V879o%*2TI9K(#aC5w%>nv$j_!RRDUF-eHvLCWOKjqE`acwsqwJ zRE@2l2@rJ3=Q;p=2V(*1YF(c(6Uv{ck5wb#;<)<4@G$swo4Yv42ihHMmo%vx)J>|J zL?!Ib-JQFqok1k-HK1S9uQALB40Z3Tt(iWpPcvQ+Pam;Tw2}8ZQ3_ZuDPW!xy@S#3 z=m9cD9|c_DitZ%HCmr-yJy!RUDOY!STz}Bd>SuM5iScMaLj6H+(wpdRypTH1$OLqp zv}Apa{ztcwLfBpQvZWY#jgB@KX5ASaOC3w|zJlsr)xGjATx$WED+p-5kj(dpq(1wq zS&os6ROjUc-ow>x7`^DFeifv2S~#6z5fpk_t{q<9vH$|q5s6+sC~oJ|Ua=jsn5DMJ zO62|WItRqFc0l$QEtP_`URt+MPs99aJ`bsKX{xR?Hrd7~xyL-v*wh;EH z{ekkkz)DhuoCQaZ`WAj~!}d>W@{&J?ieETxxBb`9IE@S17uw$}xfx>n+w;zhhu|qb zXLW1PBlTc>;L6E*E3gDM_pblE^;;1ApJt=_eg~n0LkA~LgW{KqUp}7=MG-|2=Xx45 zv4?MEA{${$*>qjLKdNZgdTDd9T^9vXa;y#fMu<`#YO3}nRmeV_F; zIN#EzDF(l2+c6G;PoTA#`=CDAeU7uBEA_u|LdcE2y8wKAtSA7hR^=F*fC-yWeT;}i ztuhL51HXE8yY|o#OW`1kMkfA3Yn|PijADf*VdvJ~jE&{gAsPcS-(p^4fRFqQYTj zjNX8V2Fui}pCFVTGBxWfNMtDJ$$Bz)!FV_I82P;0NrAe-jL~%q z;oc_7u%L@f!_ti&Jn9Prs)}8!L@Ykph$~ z1?cRx7NEV*WJQw|?GBr?e(P;n4|33pY(BvWbyB8Bo_K<6G0_!BBB6(b-X<{_*|J-H zpO<;(|3zkYm;Q$t`$o~-c>0)AMgQ-#ly4R%cb3u zo@$dMD*l<{*(QkRD=9q71W9=i&kAz|QJ+cS+3ID&O(20M&FiWS#)Zr$;NQZ(h5s-} z{UY^?)Sn@Ad+7F18#p$VWan)Fbzkw~U#COU+v@GVPll7P*4*0YHMls-`ZoBcKMD5! z%a5%+r`>Cy`xg5%XYL1|3%1!ThO;4hL(8wBbV&GZU7Zkid*k`(h2Wg$oTs0Lg24rY z3qFN1dzrmrp?to*h3oQcyYMjqZVVI-$p62*k!q@`G2B1{0;-p>YzYKC74%eq15)>< z?oDd}1!D@vuR8@nbIZs7o(Y|N0tVz9fq)xrxq1Kuf9BIzZvtC8Yb=0so!g`bT(K1c z_dUZVLWSy*I zWJ=cAv~0Q)=oY$#zFzcP-GDO6bTiOBbPpW|ju#v+WBvpZSRl!MznEaG2I1xs$r)NDg37m{$;BoY8=r*OTVijC`vHPt zf?|TBq58(^@g;kpd|vrGMZ=(IOwsTycNq^8H~;SiNCl}N+bC%KP~#6eR6(Q8AsypN zAh0~(VB`p>udT0jb%9HdTzcd}G+Y>VVc4a5&`b4FU1P4S%3~S~mERs6N2@;}pZ^U3 zsXzTbE(q#(NXksgY%vDxHoL9*AmmNRoA5(-;4Aj<2DDpiUsUovq=fm8IkOu=PWrr~ zCxUCPyA?pd0DCI{pGeyf09#w5Ft>fL`U6-~RTY5M*vQ{>N4Y)^rUd}y^4CpQtpRkP zo)2KPQRM*caGe6+Ua0E;T&)bJ<~p4mmnX9@iQ4E&3MSPf`H7%Iz7TU(he; z)<$7%H1eRkf__E6qI;QyO8F!WX}wS{)Gb98;2G1WivTkf99530+&U>hU9Y78b+C5` zZwZmFMZVT)=n>d(|Zeio)#2y&k$pZ_<@8x>fKaSqkj`!M8dK!ZQ4d0Ro2D zjc4vfH4VTPWW05@k(Qaw4AwsY=$$6L#(u=|1@P%_6^mwOfFPiQ0L~b9e}KA$?u7u> zERoB-W1ipL-@O9BIa_}Q;Ce@Y2vGZls{?@Z0e2KY$;tY=LSBa-iptxz@B!Ue^-y14 z6*wj>OIkMQID{647AAfH+tzGbvpq#}haQ#_x3>hnwK2mU-A{%bqowtV6`fBHnU;BU zKD|J{tKZc(7?-`~p>lRfT!BYf(bq%*`m7dQ6nt zE=a3%znnn(z53}_c!f+!|ChBRJz7r%vwnGrLid`&W- zM|SYHelBv6{h)2yrdz@}|8xH5n?udgnx!?KXx;DS?{rB_M7?oQgSe@EL4~SNa>XPX zCkJerc!17a!~0Pvn#+GzK=`@vb79-TmF>!|s)LFN6%$U+Hd9OQhc!Q88(8xjM2z;` zTipfRziP|a$87%quqK%u8n(q|MrnJ|GGY41_3Hq(aAUr;EwN6hC6H54zOK_GI2BRR zH+mmb;9k>c9R$u&UCLWR`gg&vUVIf=c5n39z8Ao?Sf6m+0Zz0r^L}Lw1hCC>zXqUR zHO!U|)-ZtjneOKS8lUl9R<;5XZ?~6KM?(&-)`5t5I|R zzX+K=*$9(qDd%lVOxXT-8Wv6deFQYqJ~KQ8B1c7zY9B8MV7BSy)pnUCd0M4>*)DKa z1d3+`fn-VR=2>yPS>h8;i%_vxT=ZvzYdL7fi0qcUA%X5{pCF||(e>=}3c7lWx703^ zaHu@73Hya)J|p{zc5-z;StOC_7hpTv)o%I11$n6zqNrZ$wJk%V)vr=`77F6|MG(&x zFJYsn@T^cP)OIOkOXdB)Dfu>QOpC|ILcYH*|GpYRJ_z|B_zp<-OZRKF7>+oOIQ~7z z6j1ktzkz^Wvb_}422y6G%)IR;$b2R9m7Ez+v%6+@&1a^dsYzlD7-wF;VItH={(g^+ zWSIPpklzxYfk*Kg@HdOl77->MgM_ye-i{v#x|{BHxgO3cN@<3AJP?$ zcCBj?mIf*wfA$DBG8tILQr-r=gY&vOv^wJZtfLc*Y0`Yb_5|?xM!j7;7Tl3$2B-%c z&dBL!5R)@f-v&?@?+OBND)$6{{D-SsHF+6!53gPo^(NFms%mU+LVXmA)j(+f%nkpU zIs*!`3bW6J!0D$>Kb7kTx{Yq5dl{jo_OvR)K|iUV)LlhznBb*|UZfZ4-lp}Try!9w zq8myy7ubgB)kxz7)2%?K=oC7Oa=N+vdxE)L#~bCf?rtm=x)?XeF5Z&;l5{80l4J|X)~6_z04-3x|~}p1TCOf3p1lnLlwr{r*&-JO#N@%%{zashR2E zcfa5L{$1fp$(51|ZM_PQ=P8@$7xeQGwbFOCqZ;%F`gQ>OG4&dNHQdbPtR|+>wK^O5 zt82RvZu;M67CC-5vnX?r1CA}PThllN)P2P00YEs4MaHepe$XH4f9Xx22J(cO1Se|h zJ_{QTE0&$Tx91X=m=w2j#TBS2bA~$`gYAs?h45XwaMo@UoNm6#hfk4jQTla zI;D%@a#VkF!qZg}N7qYB_5@}PPHV|*?__j2s*6D~Y>^zJ1ml&|)69j9bQwCNnBj|R zBk2zvg@T9{;pE+-%S)8+Emb(vG(kd%(z+*^Izf!Qjwc7m6KJ>OS`pAs5IG@oLWl7Z zRz1fguBlUAoX;_isdKWhFi#LpfyqbVlpu~B(kdO0?F|K@5I!%0#R7wrI3bv+N=BL9t6VTJG`Ujylp&9XI=v*eTPs z?`4{oB_6Wfaw2(zi_4|(G5sjsBp1V{HB-S?kOMt?&oBk0g{l&=rucvie!FIuR!S(_q-0zcwHeJ2<{BkYb7*MY6KD$tKXzwuv)1PbR#(Oc7%OKOYqqks#Au+t{->(xVuWmnCv+`t8$5{@EMkc0>Mv^2UP3Z5VD`?&CgANY9_;^*j&o03uja zGrY#~cW{R~W(tpIg)AqH5|sWXj9Wb}$RKUF<>!k2(@FI_sNmg40@%$`^$FrF2V?jKJB;d+Zcs>(^wi%O+`>iO; zzm05I_~cj2g1J>R zEQaG%UR9eV*z6~{T~n3Mn`5A~_E`T=Z=C~h^Z5VrKKoRBya zxSiYeZDI}a2>n0%aYD$VKlFFCfb(`1yZ{=1_Na68tO3#=BO`Va#^ShVF ztPg$2l)~f5e16t^p{fYfi|R#WUlJ#UG~X@AX0cpB4oT~>Nh~Fsr00EIp6@7TFWOPz zcos|HStN*Oiy)r$Qg}T3mG%nq_)*6HADhBTdvJf^{zSJCZ_vBffPh@M(4bfA)$|f; z%3L#ERr%)crbIs96B39uSRQvyE*#Y&;4GGDh^GaUy<82-XfY$wnZ&nYr&eX9%CqQ+*}l`;j$BCJ^KLk1_}4L)BL-8 zpOMkIC+c{Bh*`e(I6nvVYE>t883d+0u@^rJ2ljwWQ?D}@7`@aKA~gxKRRg2j(hDH8 zkG-PY4Xz*bUgm)B%eHd>?&Ug0_`%KqdK=9E>ZZ9L1aPJ}j{#H-a|bng6)yhZniP5z z&Lr2{10Ms|wniEL{h|44y;_F}1<^}#euf%_y`C)FD7qLfhmLYSco0T!V*z5l(dFpL zV#ZD~LlhDP;iL=VA8w}CG!rBgC;2{iNvoG6ok+Tz4=JWaSLtTRL!4ZIV$JzRtT|5f zPzfGO2R%ZMAjN#nq#5Bd5$62%M7mykAem=wKi=#2c*f%}Q>=z@yQh^Z#Y9wQODi+M z^wz4-oQNu43R|w+|CGGJEc1boWg;ud6XD_Gf}rwcoL*pJ1dwe7oRSYP+n8ECf;aV; zF~zBKn7vM?Z_!)yvtlvv zkhFe(qX3=Ygx(15Aa{^E9AXE>4vLG0nie%Js_%e`$rY0;Z-a^z6)P%(z}?2(#(mLT zSsR|eR8ELK#v@0i=)Q^t8F~;<$)A4z`6pebAltw_)IC%`3$A=uzB>u(FWF~>&IQ*l zJ(};pHbkx0JHYj_-p6dPbytgc5nSpZh)?Z2?nhgA|C+ZqVUKjj9 zUKKcRcALxQJG2MTktSA8Uovt4`kAup+t;KO*jiZcs%fzDO-DjPBdB_ak8JG$8!l=g z_GaJQkg4GGcmC{LCqoC>gGZ&|VAL2GR@S#D1kj>y+MkM3hQo(AtDk{N|l?nF=PtaoN2D` z>XZrNRt{;ca>XN-FPk$jdvQdA7(~8=T6@-_oRlkejx0jU^}7FU+@{W(1E@g>onxkH zYOTrfX;|QQ4j9EKRcO|kH0%Z2XS_D*q#4(%-Esn+miK>9HhUg1WIDUKx>Kzhk4fay|@sJ0= zf13Zaxc4DoL%@cnuYiAwM^@y6<6XzQrN^Kyye_@G2{ug603!bfGTO8M$thRNHV_vY7aDgTl-^YOp98tjhMFEfO@~G!ZKo=8!6)5H za&3S{ZS5iTuYl#^aUO-x@qS+e_~cnl0qkw9Z2)#3Yc+r?(EV?KpuRq@1MEn-xNG>! zuy$*CtHi-T05)FsGIPGG-_^GRkMlUU$oRUCStzMfVMzBzZ%w1E8w5{%wHDUaqj9$KcxqWfd*2fOuzyS{E zrqX(aNDG)G-nC$G)H&)-KM9o=D=+2*U26dvVG7Uh+kmuP(22ktoIpO`x6B8QD0Qu3I2y{>)l_0&p6fG9Sp8#n5roJs89`U=2)(pqVR zg2n^pYNNjd@b|Mlp>Bn}4_tn1$YZefa9RJPN5L6Moz=o?`ZZV2)sw+Cg5j<=V93&t zr*iLyZnrhb+mr>hzq#5tdx7OP)(-c}x*ovU%smjm=`wkcHKEQ$0PcbG2gsaV^f@cA=p4)ovou}Z^eV6WYBtZ6o>;t(6MR$`bh$UV0Iw`{Kq>3ji zL%df_M90%ztQX0`&7=t@lq_6N6DbHSOiQmrfqe3HoZOx&x}Ffp4@v{N&_yT9_nr>= zEB%#jZm0(x;gL*$eoMclqh;JKD>}8G&It%2V?|J)$1@ z!)oAP`Bj|))lGF%wO;u@r#Pjqm|jp_5+ULxQ28of?uga!b#;A?!*(Rpt207q)y7(mOQV*Hij|ktZ9`R$mwk0Ms6fqHbSoTiVqpYAa!1{ zstdegIa<+*EHS@s7q|ThK}_2qBse5Ecp@ZBPne#lz_!n}&piT)XBN*qyckLjmz4bW z9R%j+Gj$Hg=;ixrc_&D){LWmu9>N?x*H@K;wVsc73;2iXjvLg6;>a4%pt9b zhQ4@1G}zbL*M=_!#~H_&lEur4=AmE7YDE?3$>x_wQ0)lEe zTSMH@z^%DsAmo_u{G#4a{iZX4)1V53v0H7_YR;v49)Rmk_nQFDSUnA(G_H0gfRDC4 ztSne{zat`TJzN~E^ZdLlCcf|cz8_um6~Uq>4=4uo9r})j1jKYfd?`jTts9&4 z30g`4Og5GZ?Qb|q-Ben>NFl3R$hf_+kj$xOh@w;F^+G{!)Eh|_D@h}8)H~|4_euc@ zyw(ErEJTfr8hJwtGj6wJahW-eRf9z=|zgZiiM-P3{9(>R!3ieW*;^CDE0*?yQl1)yb3t` z(AkH!4gvcPXMR}-bjtRdP;xsYjtZE2{s-`ju+4Wj19geJ0MssF+Rm6o#5EgTs{!os z>K1_di|#!D>J_uEQV%xfNZOkuWBV-YJF&AI1MnFotCpWOvP135ivaFsdKiu1O5?f* zgLlH=8Px-0HbAbgyH9W>1eXNg+j^W_E&3W6!ujTs*{fp;`!@&s{@Q;A_ z;_D%?)_?Q)gTP@kdI)H2&jPSNYE1{Q&Z)Zq?6Im3fLdUtV=kLs0H8*jm<`()BOtUb zG0JM!JMQTKuF?9mT-DzdZ`n8i-AhjdaE&mD)y~)TPXMmI9IF$eba-_w8ZY{Nym9}zuGk|3L8 zqafF*2Jw(8x|$G({_XOPluTT zbo%{kEkHRC^vgnKG5$VBA{GRYNWa#jR)=Y&&oc)h=y zxQQJmzo?-F%$H!YJh{Jw;j4T>V%Y|Xk!gBrD+%KJ#rKQNhp3HF8>8NUvl(YI_S_Cv zKE5*T&~iu}Zhc?=3f#~+_~tW{A!xa6U;PhYJ*O7n2A#m?0QH01ri{AGRs`!NWxP*) z?7hS{cQ=5VZ#JAVK-4#R^4)!H^vC*oFoj2shsGOICA z<(^-+7Xlyli39Ne+ExHyOR+it*uGXRWO`NsU{x7H!0IOq&`~qfQ;(W8nR>Q$^>=L)H++UZ1K^(E-U(29i@Oa#-8R<*0NW}PxLbN}{UG%dl+1Mog&%^= zBdgCf?+EU1Ez55*wDxQ5H~BTV@bHC)ujE6{%AA#Xt=daZ$$6^|D&`q)fZci}e4Z=zTnTq06F2$(7dYiWGvg zB9JPTWI|8tRbzsj$O844dh8Fa;rD#6PJtSu#;8Isq_mE8>MW?CYN#htmXk&gqOt_} zcsQ;cK|V#s?5BJnAvqyAUPI)9$ORD{Apd0k$<3Xh;;FKQr*=cHuKt@YHi6`jz{>Og z0NV-GjAOv>W{g}{=L!L^MXF~2{KL#jWHsHyrK!`56C1~H0Nx-SK;5sp$Tt?*VD|IeV}V8y|T;}G&d$OEA-gL+H7Rs9Z>ZY$mP>pf5x zTo+tWBNvM9T>Fm;9|E99neTuLPeY4(zY*u|1-~$xlgnV+V|@(Z|AOr{0PA@b4q$6% zm_PNS3HY@}83e=$WrU3F%(gO}Bb0g@vp3DXo`+0Sg&qgsKBvNI6pelcf>Sk`drhQ9T&j7bYBCAu*<#yiHJ{_g);fbt-^HoCUsi=rf+C&IcCAd4(jA{LD^m_1<*v%W`V3MpJA zE*+1@#L zAXG1?UQjRv$`_R{+S%6xk=3r`|M@3q3?a@|F!+bS?=yEnqZ@pt)b|133)Uxm4zB+C zV*sVN6(C@ePip{MGov3;EBFdPMXCEGpzNVPXqd#NqipJT` z*B8#zo~bQ*5A?nIULA$mWa=@Qrhp!-2kSI*q10jWUehFathu2G8aSa~DHPFCDAJ`> z^93EC0~$D=Fk@0BUE((yNufwK0cEDybn*o3I`pb zBS;aBC=_(Q&etu#(bUm2`#z|=Pq-zx-+C=}+!Pxj!H;Hqolrg+#)$TdN{czE^ zW*c1Ar$jfDZsGy(m{^<3*u7SSPKi=bddL*43TR4GPD(CKy%9KaO7t5gB8WUG-kwT9 zGTDZs;5rdFPWCD&;~B5=40)$KVeDD*{!RkxS?|#=QDl_Ow1lwfVben|n!*$N4=7ZH zYR56C2rFBWxfF&T39Kr52AXI4zj~z~Sb-*nt!9VoCjkGswxOE!t|2ZB2P#1-4_Nb%(MY$nMRT_W}&|3lYBJ+5CNyPxD z8HPmFJIs||Y1@MU_O;d^fU0}y-v_Yuwq617`@!~*`v`Pf+Ngi-5pcIE>#FJ@XNKe9 z%@trzwkJ0Zgxcw~)3b_=)q?*Y3J+!E@jIk+v$C$lgT7unoWW4*=Xzgl1luEOnFg$% z)MgZv=hyuM4P0*oi`FdV3*ehXF)eQjZT}eV7Bgkiue2x_&bbQHtqP5%HegN+0 zOrf#XTX6u+1$6Z73dg5bKi;$wnojZA>-YkErcz!u90JGNPU_pCD5tKX=>@0@i{CqX z6>x9$)Veq*JX3h)T!DB1CyNeFEH^4$IF)d*He{FrgeO33fS9#ogrgK>Lu0u;Mf7cv z;z^7VE;e1#C4vpbp}UH1C=Roqtg$4PhKSB6R!q>LhI$}PtW#lfUPKC2;dvh(xDsUU zuRDmK(;rlG)tpH2Og@HL`1wB!O#k|)x2QnE2y4i7=^@jjPV$DN(5NBOI(cFQJmgy+ zQ6zf=Y(qpq*h@^1p0M-&VoB&>l&EqFqHYoWPESEpw|JQ%$1#p^@;V-&(^yehck_B) zji$HUe~8xmDl_z#45{&o>_%{SumlLRN5AaP~OR4(*Vp8Z}m8Xl@rpyyv*S6;xlh0JD9;lih|ZNUM!G5EEW@KS}D&z zSPGugYpfnhs5)n+R9q6XT**}vrD~;G;gAFVv>=~+F?~wGQlq6M+XXF-v^bKm4s@|D zt_g>;H=n(E+aYMBY!}Ktg{08HH;bo%bxz$%4b&DI#1k;W-WtH}XRQaYj8zt^r`eXJ zZdNM*ESK^Dux`T#K#doq(%75;Do+s65h>H3%EIIJ(l&c`Y#lQ#laAmbfZk~ei+1WJ z;SCA^03ZNKL_t*V0rY8O6;Mym$XwaYPI@)gScTpFB#<-7yuW}WHU~iU`_3#uOs4?+ zuCvW|KLx#(1r?sjfEB^zUnh-+x?1(2?Z*JQKt{j+L*e<1&upV0cxv#}F8?%Zfl@L+ zS?Xry!O_`eD}0s!-`0MzDH~e!^BaHuR;Vv^$E%f4w6T7A^S9x^GG|=)A_z{dYT_CM zX`6g^R9t~(i+!4xTM%4kyQgd?SU0IRopZp~*A~TQP>-3`S3hi$6a6;YI@1%5+A8KY zUkArd)cJ%SgR)E9<1-of95Zy$9|qRnIaXA2F9ef8MneT{As(t!1MwOvXsn3`pq;c(86Fv^ za4~{J{(zVUF{lA4c_Kq^lnUC#OOYEx41LXhF|PBve`h)~R7h`6#qMLqjB2bD9?$cS z7KAtYYQ@LGqB8{D5p+kuPG~Zz$)v~&aMpI#_UkSP*ynn<5@;VE^g_XCuq{@NaX@{h zdkKKw0^8#N_9&y6wdxEavJ|EOU1zp6*t!{Uf;C!lWoD{S0PAUG2e2)&62Tz<)+FTzU>j(K09e;c zVT?DFzIED&4y<59=*lQKW^Mq zfUUc&dt@YpEe~5hA{YFo`b|xq2Bn)yHnH_fY+a^Ll=S`b2jo@lf}P`+mkly{}$r?T4&;>PLoVK-nj}H(8R+#sy3vgk`693LdfvYD z^@L?N6vFOO*~L1b#z}$dV_f_Vg1SCN5XlsXYZ})y_9#^Ks_J!dF_a!D4LMZ|o&P`T z-aEdkD(mC^?sH3eLJ}Z^8hR0_3Wy4*pkS|KVMNr?8G9K!wsGt{qJlVzy-QO;L@6Qx z=~6`?385t3_9vF@AG-z`%g%?_uNzVTKl(t>$lb_j;$;I0OD#r zsgW4a<9S1BgiZ$V`K?|6)-t0uvi6$6FP2{nyxuq<>jV`9@LXs@G3yHB80_9A$=VbN z4*&@7H;p(GZt~3lNVwJa5J3DYUvGf89B(#2a=>o^SQTm~Krj$F8z7Jv$pf&q8Isj= zg=z$_PBKWx>LU)wqqYNBF=jT1wN||gV2M04KGt^*K=7-G`JTtr7XUpTh<~zVETn(J zguq{aW$pB!hpLCz(%900cS6cDDbJia0U{SiE{>lBl|3taR)ru~6RZg(Leqez0gbOg z)eluaRF8wW#`wSV-VZfPQg66?JycBam-Lzpgh~H}&`+a*0raFlM0U}j+Ca&Y(ElVq z57lo4Hz^-97DaC6X=uDQ{0{Fy<2m6%H3@3ZvU60~F^<}w{yYFF=_%>Q?}YA)x-Ysc z3%qN*Ytmao&dQvXdqzXeNi`?cUVv%T7Y(5oJURsDvmG7$ZvSajx~8M3Nc}3}J{mwV5hW{Z)U4iM_USuFZVDhupm=$8?GS zj=rwGP*Lh-5Q7{)&`-G8OzB=B=iy{Otv?cixj#5ikjqF+=e-rv(HtN z)tA1`=ex=dxYs~N{Nh0qe;rgm~$|LRiz=z%)A0g|BqxO2Y@g5LdpS62sfJ1 z&W$=C>Hb>jC)6ZGm4))4yBMLCIumDRy??lWxIY4|u4;8vdMz9{<-jT5)hXJgYjlrt-m?e6iF957GLyB5)MhxJDWP6OmXu2x= z8i4Q5R)2t`WPg#-tC(5ux`aCc0#`=Nc_4@$zKZe=@csE#vd#W;ykSf#jm?op2VVf-Tg=V|ZpP5Frp8HMK&HJ_$ z0*D;a+W@=|S}SxR3|<&J_2`MP?8~P4?LPu_E@>!GFRPamvmrh$KJDZ#;0yUeZQDY_ zqYaNXUI4+IU`}wVWPN1(ka}3E@HGVY1@{F*I@5l_DFNsK8MkNL-sUL?j|`8jp8z#wHDx)c!O3O*@2e+(Z?wwNgTcPX%wG4l zw;lqpo;C;x!1@?9Jb@pRWHLGe?bv*bAeTClhA#q^h zz|_8wR*+V3`sK#)G`c#Bf@>oWHB5t5-tfB_Pk`rb z`$7K@2v&JsO1=cF#ffjE-wf>+w|S%ORET>n?&S1=rmKN>6x2Rd`&9LCD7(Jw`rHp8 zP!K2xj5GG2ZxcamPuZZ`8AZN61$2y#p_OEpI*6kP$$IW0R6~-i*JKxm5*-FGp7FHB zG$0F!tRzDsiQcBDRd+XnUBmJLU840L!mVZ)1+&vSHzXu?KNmNYMjB}nc__@Bu|A+W zsZOf3)S87&)>&nUefDnF9|2~Z(@C5}Dv(XKQ>-kZr4cy%4hN*7q1SVg7LPiPI+t#z z7rh+FwcnNAwy+!z*i(?l9x317=Ynz`JkBWJU9KBAma*8<2PN8;A}Cq8{jLYqi(cv! zQ@ausB2p_HRC}Wzijvpl%Y&|LuIARu^>S7~>T9X5rF{f7SJhl~xD1G~Yr>~P$Eui} zWp{w`tA7CmABq$LBvkn(iRkfC0BfYA&0jTFV?Anstkr0;QA+SyQ&RXPfP}An4+D7r zr4|8{^le<6`3RjLh; z@C?sT4&l=9E8+GK7!(-P)D@~SsxnHSgIZs$uf8AHqwG=PGE>69{g{rO&$zgfF^tit zivzL**<@m-pfm{r=^*Lp9-uqx&WNCou!KO}T@gccy$@udN)-px&De_`E7V7AGv})M zseX7(2?T90<9ynPebu%=FkK{a37ev82jTQGcCNY@2c(O|A-Ve&1qteI;tvvBjwg!r zgcAnfU<-%%yAjaUu25?*gGmtfJl+L0qajeV7%_*6QwezKtrTHecIHcnI{@^B{Ad-xn)3sH>RAVMLrS;&`7=209~n6xZi9plzWc(1 zpk`FC13=vK-nT@67XVP%I>!`u8pW`B!vxkU)i|J-Q$33S>Msm^3E;ocD1tlu==-4R zudt=2p}g=Q*dN-#U>aCISU*_LfbFw=k$MrBK5yD$@FZ|Ick6$Op^P!vPIZdmE?6xB zxI0bNHSK}V`P}JG(+BLE?VEK^Xc*lvy0H&5SPfP~e^c6^7h)QAoo8C>swt+(m|386 zb*_CI*fZ^!ks_H&@jYfTXojgCr?<>P?=Fh&2_^*6LrmWux(l*VvW_!NDTNbqg`}jR zpE#g2K^_qau`bS5#*j>1h)FD78`$xd|zu5%8@1xud^Vk==(AxD;z~) zNS6Xj9Ov;a1SI4-Ll}bJoUa<+-1fskR1!(3!D=u`pp$fx^Swnayvq3hOfP$XqgKPb zhPFT|jlci~I393FiyIZ~lQY1)Pu0l|k=Nq5XSlc<3yY)DL2-bjAA>^1MW2an?9qhq^QB#vWV>eYg6)Z@dQ7 zHN3=P2wiG_4&eXDlOzSR_X4Q5rN+oa%&2(zJ=3^Z>m-#35KNCe1dyctvjG|(j=Y=_ zfH~!5`$xVEfu4Nj%K&vZchg=LM593V!>%lb2amc!N=$0SF!H5VZjW?2tOk5|*aO=S zg}>>z6WSM6PCmOW40|W-_=P~+Fz*8Zp(`TO0K9{&WdQmXHBICIxd5t`VnMgN0MuXf z9sqT`*?v?K7XYNz`$yI;08d(dQT;%Obcr0UO$X0Co_mts20PVGwOdII(tR>A`(n_i z>(kjM!nPeo>8|f^l?W_g0X+;Ut9pYzOP@t6;Vycc(iwdT=z)45Z3H=Wk`9z{!f9j} z1ZB?yJKN6Ioef8$(@fh6l_Cy34bv;TqY?D!0isWfGo=zvc2~)U7)2TxvJuuc_semR zQEz$^Zn0ta5qsz)4yf43NVFgvhsz9$eZ|S~q}0I?0QPj*jg3vRgj_?7%)vqaG%KnB zh!yH1Xg;UX#P0h3LYI{+dB0zTl%m9TB8ljAjWa?;4m+uU|B?fWj^}x;MXupEP#slA z4w)P1I3B-C@f0`<#UYB}Vo>F-kj|}V@VgvgCptNZEY?N#C6Y*$ z3z_-wG2A#FHKZ9yB#CekgbpQt$J$uPX=jusV)>YP3DQ{tVa1RkqqtZMNeU}-u$3W@GCk?NZbl4+Jkg*t= zzCcLa4&s1f#c+~EU)Ek6P?9)^G~p^TF|+Ag3({x>x}9!Enn5~xh>*2?Tp>J|RqQsAygCP2(3p0fcW zSLxlJ>tO98bt5_s1=aM5C@yQK>%ttDu^=)(YNg|xMJ&4?M)G_xGla!K;ez!ZPB zH;#yjre;lT;m;I9>yNCgz*AtivD?({kQ%@T4JpfAM%m6Sa-H`X168*h$Eu=jKK>-< zeWo~)lbp3>n&r21ZB)^nH(I^zQsS%8X5A=RSE`LT@;+jiqnp=<8m&eX>mr9GgmLsQ zrcTcMf3l>*$G9Ao`_-rUxu`zks5Lse{?r*iw+E-MQde<=Nv>>@+rE;U?}Kx-ZlrPg zv6bekuOKmtpF^DV7P=iv)|YDW_W{Q^ZX$_Dn*ZPaFa5XcQLW$n&Y_N(H+$Tcj-Z{S z*Z2V#VO}E)%h3Rf0l4QEni)K;XG)8lroOt2t`Wnx!QBJ*9YMX!xuKp13K$` zyAEPzt1Fv&0GXT%;4AZ($9s?5@IF#qeVZ{%^^BPR7-70@6E%fx+NLQfiKsp;_ujU)auacGE1wi+UX z%~+tOa}5GfQw>+5ZZX-aXpJ6c&^)950xpo&YbLbt;bV;Gv!Xh(uET{ z)lhLfC%V=}EU^x9h<+}{yx%dj%oYaT&Sf3L80I*h3IDb^|4h&JvkC%(cFoU(7VnP} zBT^sSSl1k%$!CnTmaIh_@7vFCHD93sY`)@j+-}376>o?#J zztk`Mz27g~&><}l+OOS!yREy`YhYh!Ul^Vbo}Jvr9iTQaQI7=@jk#O5n1)_XSlP>E z6mAK^;O1Q%Krb~DJ{e$^O+!w&P25$WMv(06aBYrxZT-|}dB82M-x;CYhUT^$ed+7$ z#Lr_KZj zZ??_dmoV7(qjeA0f__Rr6-gD6G)i&~19h4@&8a0C;!@7Lk*rt#KSi>Zr~SgRaLpxC ztyOEsAX>LT)GY@m4i{Zm%PlS87zWt5{>5KG5oQ4_Ayd1cXy(9wp9HD2k0qfPm@rPY0 z(qp}%D%xlU@NLtd2N_kQ<}k+I0Yv^^SP*Ug10n=GXHyv22%IPQ;a<#~*!7hD#^qWn zPQnt0+u>*T^Gdyf6qD^yqfMti4zzHD{O9xhue{p+AAOH2r2kbz{jJEs{qhO^NOkb- z|My<;fBd8WT?cf~MW+2?jJ zHAeUHlQuisb|-~z7SKHNGpcEEGJJ1|!IzqJJL}AGk{3cJxW5zr812z-!#|I z^Q7TfwoHC6H)m_#uKxnyPqo&%uOT=@pQF}+ny#jMlTGNQzZ1@76X;!fmy^{y@bhe` z^W4I&=T}ZS-~GaUaNRduuFIVyM)bAf7gl++?Mlo06FSDaDLdxVImSZ5*53gY$Eb|k zb&Peoo87<31y#%0Y;o?+f8JDg{SHU?--t|B{_*eg{^l<`#3AS3KeQmpaIy1EG&u{% z_dC%@vaNNA2ATZcqGW$LKB7pySYdS#W4Q(2nWy#YRCAql^jKEUQFu9-LJ&_3j z-dC+E0Q)H&hX(@h*>`#qK`pihBzDF0qd5tq82$m%MPaa9m%CJ9Gn<_dK3yDExn%p& zUF+!(hp56R@Y7r&+y*x2L*}?Ti>{!UL=|4Dx{l~To{Y{IcO!O5! zzn1goA}t*AvAjJG|6Bk3LFt`P->SYw0d&NO z3u00{w*fTeNA3VfxZC>*Z^FpfPj0nWes449G{b4r(Vm zojo?{SPx@#G)=A@JV=m2(ChVj@*w2_R@UV})|K(&)|P@!U>E~IKdqOW5K}PRIBk^A ze=+z$Uv8GOK0&bGIM&LuG^L2sOnP2-X9r!OWN>7q?;)`IdM{7>6trLa?e(UIF;jt) zI7vS%_rE8wpZz)uSjtk}+eHfRVi&!I1M1mK*6LMy6&--Y?|T z^{As{YHyc8+1O+^lg>I@XVV9`kP98m6Ah`VTKMn35Yf9aG6ee~a?ShFnEherJo z{>Zif>=*beK%b2%YE=dF{8R1YT`qvVvm%A*_qZ0?K@L(WKMRE1tPuxaCf8SnNr%>8 z`po3Wg3A|DbPwLQI41;`hy)jR1oBdFCHB%_` z@q#lanx^@BtkFY7?$EmdyrYbx4b<6BSkFM^GW}T0RS=u)S(97@k=#hGy~o^leWg5y zXg20zGlhXJ7zJ^()#x11ujp5FKgNMi@E zjAcF^k8;)l{Ru=5z||kWio@_-+~+19_C-iQ!jPwd)R{o1T1ptkO;V?k_5bxFY8o20(jLF~n;e#7XPB{B@ zID&4K^scG2oDlRmlN$jk<wH~1}oM3LN)}U*w9jR}EXPW21_;nCGHF#>E74QQ;L`!@04d%M^ zXy9@#*U>f-BQUK(`vPzCwv#36fEh>grg1dRbcptX7<$sIAZ|xHx`8Ltlj#`@-l5*1 z-YdbA>`7LKWgzARu-Dn^>=6)|6PXhp0Krp&rv$e`q)((zc!h*i?SNczo%LKPNJ4rl zJ0ar{&^z@`GB8tDDqMDxLykk!N0S;k#vb&yavgny>q(OkJc?v8#J>6f6PfsLRKkW9 z+0ZmW!r3jdi%~})=cShml8nf4qam8>dw+%i56E#_x7g^Dehw&DChzO_3!&rhc0f_& zGXU7iRtj1moI?4cWS7Hfq*1RkIuK$_<1p1I@5^`KTl2RsVTrTDxVavMa*)+Qj1=CM ztV*F2-zCaIX%dIFU3QvUU>)nCjw?DvLw{qAqYk^E^}{@@&xP8nYpDgG5JL8o&!N1^u2(1!rArJlI}_DN=b zmVS{30Bjirt)DOfv)(D47HiBl)HFY`55V`ibs~UnXC{&sJQ3WR@&tG{dPjF@1QxKs zQy`8c%7vT@`YZjFJ{6e6Bz=kO&=ZBMzFn%~2TSM_6$+kgCUMdkn95W-fl^8-1u;`% zrucV5{PXe8$9I63n__N?vB1i*vbfj`q|`S9Hu2#(!2hTv`d?tJRK?!5U|sIH!Q%nz z9+l!*0^zU2Uxy>mxTG|7F8A&>rpKE{vkP)MfZfSmKb^%7w)C zvCnZx`6jd`3)8vK#X0Hidb?haQFQllZMY#qPI4!TRI=pzEEmF8C{|-S6t-^uyxy+2 zvl*kHZ{>1GwbVutqh8|T8n>{;vF|M|d#s`6XXkrZA0~v6f7H0Ryl8Q)`}1S|paU`k zU4RcTH7~g>pjoBaA@l}U%oirClw>b=wl1Z9#VJ1lF*|xsU=e zz-mD@9#;ssj&-_J9<0|KS4DT8oEDr_RN`LhBKcBC!G^L)Ws}O!gI>dX4e!|+d`bS~ zl*4e~;y~Xv`HU%I2>@D_|_EnG&ObE6<5t@8WzQ)HObW!M{P)7+tqFSlZp#Q1=sm}o(=W#Qt5hGOG z!45qM)KlsyQX&5J_}AmlgM^fXl!WDA-C^Ak83cj3fw@O+hwAUDzbmpK*c5Ck=?~%Q z;pvsNkaZSMRUCru{bCMPF9My-Qr?04g0U=iSDOCLuOoNm)VdoDq&QIbm(%h z%fZfTAhavAE4&YmK6muFvUlLa0u1_lu}BA>{LrlR)Z>Y;nCjA zKWj*~jcpD&Rc|0Pd*p%|#Q`-+XjVvb?TiNxh2p@+ayDKuG?}zru z-k}gT+jC)fGuW3H1C1P&p(-h+<+!@jT(y0b0M!%CKBEShKrtfqF)<-;AAs<_$d>@Y zS0iTv#P|2D0La`BzkBDI(EecjO*;YY*QQze=Z5@NkD3AjtDkDeHi&kE(f61+Sb-Z% ztJbEoBVK^mGd(wp37td{Hi;lZb!qIz?-oB zgsKxtUx2EFs)S90z=8T|w{AJ4nHFk?7N${?|+N5;BBDkA^NkVfyEEY(XWo5<7~9oVyL@qFWgUprdxz z6?DGNryHhZsYcd!#5gb~3s~SH&G)j`aY*~bG4_xwV^s3E)m(>Ohv}nL7fMS?ONv`VW_f0L??x#7qIAlpCm}br;a~0k3Iir2W)|KCF*`kL z2|z<6G#4Q80iOb}#|W?;ZWuE)!rWuKu7$*4i+P`Sl2t2Cb{9bXjUm(E>_+twfM=Ha z9w4UD69!P1vp`a}O#p#@ktBfdT-yeSJgnyect5i40*E`#n*d;+EaQ3}(1QVNj}ao; zUCmEDMvn#1c{)pUPv*F_b~1o1IVR6>n5^E4$QsX+uw`^$VCoj2P}x5#D*l#l?Y$6K z8d$pJaR{#uuP@#WNm)r*BZ?q7DLE;*66#c)s(ZyuUJZ>hA&8y=326yw3136PWeJzX zoe2%kHcZVw7wX=tdwau1&=DO8jRIbi5^1;NalJe-`rODz(Dn|$U3)8#LtCx|HNzD3 zHY^GUtXNo)51>ptNz!Ce1{oQL&;jQp)`v@|(XKp{W0D7+O zxw`l3P;`FL`2{_ow6?UiY^w>8b+)kwXMR>s;Yi#ySYZr%xR$j}2$v|Nc6&@)n&RdV zPOsH#X^W|Pj~;i8aa3BG%>S%8d^zO~Ip4vxA+KYd!|8T1)Cuba!Q_hF^$}zhMPO@O z+|V|*X*n;g#6DXIz{qGJXHfrJA!2cJT261*+eO=J$m1MxD3%M0lEdGN=RM#;E&x9Y zX?VoNF@*`URc2W4aS5r)C}S;9L=nqef~Q<^Su5Wc6{xM19b|WlH0O39sh7CY{|z+g z<)Am|O^%>%o}AYzDE1b6k8A|{J^MXtF=TeiOdMGYo9lveTlIzNexWXLV?n1eAHcKH z8Vt~s5t#yD4>!e{dax;4wM$IH(MY2h_V>CYfc?H?lU~pUaU5nkK+I*HivVI)dCd5n z>rF*bQ+oIx09BU-mH<@81@8vX*GV<{VrvONY(MW}08gbEWEgqHsABBb%`}Y2P6O!e zDxCpf7sz>am7jg(=U$x%&~Rb+QviQg>k9xq!Hh26d9?n#jw_+zBQ?&u=U3K_2M?(b zIXQB2@kprtp!$Qa?uF3d(BXrZLCV0Cfyu8y!r_F&@tYudZSvaW7a;DExJ$ix5a?Ao zcV#E&PW}7yheFC5TGeN{G%7fJUI-1|E7)t_0iC8>r#DW3VcTP-Ra^=29XuVwuRz?% z-Y<9uVz2j}%S(_n%D32V3rQb%%Nj0%#4dCUuL92IuwM8xORwD* zFPB2uJ7w=~NrO&}or0Z`pyNp$PipTG!;f;FpNlMFuF2v>*PZ@GvV+-TM_)JFiQcF; zk}aWXR9LuCpp51%UBkrJoGZxdSAt=s9mvDLb7Z@Jo}od482sFxp)?qgOrwu zU952lDiwLbpa5wWQ^>B$f2q|D2BhO(B@xDvs>c77EUK@tFIKK~oEAxEfBi zK)FN0%_K-Vw8)UzI?t76jOtd_vtF%o{k@)gNP+`e>l!~w{ zinJ<4nVKt(sZv61c0jZJPn`&CQ`Px$}-w0?tFm(+N!?^ z)$}6<;Hpdm%vHY8RI6#GWYM$D+5wPow(J?#np!RWoG7s$z&OBh_D=x%WSNZmfLVU_ zA~PdhKc)>=^@Dl#`UG(}Uimr1gnIQ~g?<2t341aD?8i-&fAQIYajE@a``XYWDfIwq zQ)WbJAO z2WOE6k*DoN0E{>IK4yyNDL#ZqcY9b9@TX5xr~Om{r5^^*Nt*z>pKRKft|5PPcuw4t zK&=|D9s%`}KEZwqk~f#fFZ~{TYwf2hPJ)bZ`;X7q0`?^Pe*0oL9CJ9PsE3)YP7!bk zmpED9B+zs9T)G2ya;Kgr_o%m7x9-WPD3sHHteuO)Y@&%yBABddmJjG0okJ$3n756w z3%$xjAUXxOjLRHusi)X=dzbww6zML?BI-!$si&*RLlT;~CcRFtqcx^0L;GLR3I1jW z6m|kI98Z@gdW%XIxvM1j`jH@%k?x~V#8U+TCs2yVPG9sB;xv^z(yi%7E zGn;Hj&{)u{lhO0^JSsrls&3T>#iQ>PhgBsboacx>rcpSo1DN8%3SbU%2+4Kkh*CG- z=uW7BvfgFAkM@SN%(Tq(QP636r|DznLtai^ec343exUA$P9YfbVv^_38Q?o&_2F9x zo?{z*(7%j6$iLrXatGh(F9G;Mgpza2<5QwEwgwyhjp`&g@&l6wSASCHNvhR^V9|#j z9nIWJwu8x%Ht%m7oz5~(N&C#eT|LEM2K|9~yWP%2==S$I1;AEDu2=tPXeoeylV`0M zNmqc{uR<$gvtZ?04I|rM0NPfEoRQkQ{(y{MkWnBu5S#Ztgq{gKQ?eIgih1AL0Z!i$ zGjl@?B%SYlvgtMmOpSb^#zE5Ge4D~kpnt4y=l&)b@FBNaA3;JV-#PZZ5c!w=5`eu- zZvyb%YApardpPzC05t^D3wy4)|N77RZGe~uJ^SQ&RMQSJ`uKwtKs)^JRh$dG{}sqj z-vha?HGSRcedu{&%%rkM!M}i!we29LD)^@Zm%#yF$vCSMbU3}k-Di9cP4k=PH+%@? zbIRvb-qk{|*im#%Zrx3gAUlACER2Ry`V$ds_BOgW9oOub^me^nTJ#Qc1d$yD`A1tL zr@KO@Y_c8BCOW$LTXA^NS@Nxf!blTGlhl0P`bYgEHNc6SNV3>#2cb5KT-iRip6U-d zpxMj@;51Hil#M^SNG64%L@pqTG|F7*ZG}>+vfAa;pl{ zWcvv4IiKsj5^^1tg_|eG6%I&!D%?{o@F|}<n5LG~2@apSyZ+QdtO=x;JEL|tl@gTBVxCAD7=(8U6fXBj}N z#+n9a&J&C7f|CUSJ*>@RzuJ6G_cHsewk4aj+kBrr#~>g*-6T~b_u6LzG+Yv%3*cYw z`9>Dc0D$`M!e{sf!3wLkJ}VLI__()+o(@U(c<)Kx1$7B^3G2I?mY=3c>+gJtvfW;8 zFR$$fP4DQ{c0JVBhHvxS4E`!LL|p)h=Xx{rec-#+^Al-cU1he#+D$=a13akb1H@nM z?F(QXl~%dK)K&mBok^k=_Bxv>z$M%V5Yx^(!yr9VwFQ?cNMPH zYvd6Q*}X^Xv8$BAxUzV9r{1Zvf#D3-(N2uLU8OM!S@DkaSLUSwnLSsW4y!?+;ePSdMWPfvis_(NE9bFSc8nZBJOWYG9M_GT$xKRIdYY)d zX*RRj522z^QRsfi`%B(ma`U0jh(06wJ_8+VI@XMffwi*>uUlFR_Twy6=Rw~?31=J* zgLk!+!CcVS=|=%-R|hiy;_vmv19+Y^Y9uvMJr1D!f_M(7+W^#$@_0Loz;U$c)$H`~ z#o@1v0~#tgwYS+%^(4{ngbnwjbLIDmri8PpS0n`>Tw((Bn1?*$0PG^Z0H|9W{>C4G z6?1By?A8Wq<6`p%2OxP?(yT%Enj&6~1OKP~PuuQ->Km(XT=OD?9}YiUGDV(q!|(S; z`Z^V~5@CPO$h(>CAnhc7VtyTXFST;?kKj4mbo&XN8W{+XmK3`az}v%01h9^%H2~J} zY9oMkx~SQ5f*^fR?N=YIn`D};PT>#c7l?UK`-`W6B*Cu!aKD_EEMhX*3P;_ga@Qv6^ZQfc{i}N)@OZ)r~qw&LbD}3cZ3{(;HaL5>H$twNZ7Z z10f}H9(x4h=3!b_=3quPuQO75^&Hf{S^s83fk_JF=0T699!Grdm(^NTT=o29?w?* zcA1_CaHJ}*Fy$6l`B}q_9U38$8~?YV|Adq`lHM4spyrvHXX>Uy)260PO+iSWlsqYU zKcsI@-+tx_sOwVK<)`sbKcIfVmT_VTH~l^zgoXoGMi#|C4*llZFC<$KyCO2bsvPXu z`Z<8aBEOk!-_^9)@_cWCQ|oLM0kCRJ_Rt!|MN(^MvWE`|CE8a);d7<*xK$6<{w*xf#BR7a%>LvgyQ4J&no;r0sk3#wSa7~;0VE-%j{J8m$@=np@ z4O!6bzHaxO`7jjDESy=`+N`I><*v}{Fo)SGjz$oQ{+G#y>E42LdbvWcHF^!{rnb&$ z3ZDS_GyNGE;!x6E!o~T_*K>snYUR@Tta316b5ZOL2@Nw{4zHG4c1Uumx2rZUPv_}X zKp*-z$4!;<=w-MjuK(YV(BJW${tn0>Lw!Q?oGy3BRVO!~SV{*Dfx1WCqbnr6mnRUi z(KMt|vnA~)g9q7%=>dHN)AYJPJZPh&A@>_Zq7Syv@8k$l$!mdZ4hxr4GZL^uS@ zVwRH?$P>qy1A3~Ss$K;(QyD}g@7Mp(|KM9tAE*!XUZ}~c$*SE6x$|=8?Kv5GT-xK( zo{i9LK(})*$%35GhiaB~gpyCHTg83}BdX$`EG~qM)iJxOuLkd7YY&B>{$U(SNZA2^ zKzrkutW zkD2ZH7{Ff0XcPqg6CMG5(^BSmrruvyxJ0Q|8(ywOt ze@@FrUmdRYBsLv@b`QtKR=*3u5#cIsh4^}34**YJWvcP-QMUqEUzh>np0BKa0M=B~ z5G6cOo4$PA>@5Jk&Yo$K{o4*;KV+JsSO?79HgBqBN={bkAVA~-32nUpRhSv@lMAJBAs)A1*iK*!>a#U1k@r%z6w z+=qb#67*ou3-kiI12=J#gM2!Go~dV&iJ2XrB?dmjI4UiUNB4Bq%FSVpqgam4)!Q!) zWw%RL*F+P2fG_z{&uw-{I#1{6p2nd#4y?0KCT*pL?oe}R$O0BPB|=#)B({PT(c}JF zZ)jNx4T5FjoTf+Kr@T+4y$@~AZ+rgGCNpc=dIMCJ%2E-aD_vC{s9cq+0^%rgj7L_L zpw_GPN|e*83b=ziRKDpG6P+KXLcoi>s476+t?qV6&3(q>tD{CQq$FFVb{j;c4wX6AQC?Vg~Mu^Fe$@fQ~+l+2Ax~+iNiLn#?2jED~k({mfL*)e(H*CHU zdfjU+tSx}!Jn`d>TmY%dd^gk&2DLyphR%uRgUuLY&rTn+sdZuth!4ORuDJ)8Dy+DPz?^^K(m zRNYv0fr^pfU1q%l5L0C319<*v znQ0yun2^cS!#W?pzED&*Cz!&8xEH)%0)+0d+W~}@+I=&(gH^!9>UxM>=)I_6B!nI} z#loR)BI^LW#imzwXw?z5<}~{HC)3Vo&$lstqi9x~g~Y=b`ij zJtyX+=F4hZ*S2nGYiNJ4{lVdJu>R8Zm#&Wi`+NKQNKYC3*UcayJ;0>jbuZ9;bzgcL zB(Af}ebZU;{x&8Htusy5S@#9qL-)|_<@0@vKvB1nY*-)34tF-SVA^jSitZqetfMIo z);)~EJIX2Po}h2nx9eEUfWux+0t9`5zCc@s`p_MXBhsCu*?k;T6;u`ECqsQ%eOdk^ zzZU_`6C~2gq{)$Vyv~uT*$T-z70Mj2IYMStnR!YS%gE(IOdps+;cOZWXQOuu2U9GZ z!5#w<)f_=EyT#KMiYKoU4}YLJ8|IMUGnnC&isVYDI2-iy`gwMPnx>{XRpjgCM(2Zi zQN8F4Oxz3lN&TdH7}Oi;4R#BHI}G|-eXZUIDqCeE?L;^p0;dK}4eo=SM{^#{9Rite zX1>`j02!}mynfxD-OW(fHIS5w^&^P>`}TOfbTnN z5J0HXPEMZ;+51bgN9Mrhef6>JCPHa;Ls_GP2k>8k=@eZb! zb~PL=JzBc6Cv=+KY4(V5kalz0%_*Nl*}G-$R=f|~#%&C8DUd(VAJ7%Jp6m51&FOjl zvHn>1!i*8>-kfdHZ|S$#E~PA~F7o+RUZtBj9*Gci3a0x&w4FzmE1NZ&*^WNQ<4V)d zW_GlsM9(&Mta}4r^L3OHqL(zBOTrAN=;qQd{h<&nDj=FKF{J1e96e2;=xK^wdY&Lb zs(?i-auk@Q;<@*LUa41-Ct0WYQmhwMcou>>MV&&SurP{(+hBcu4d?MUrkW5-ulKs;Re|P?9yq@u}xT=~;qla1{;FmV#cbSM#GxVOVSA z2kL&&Z5%XJ)vS;mYc<&S+V|SSq3G?Rw~Kec(XmIzibJd_001BWNklXPd3Ag(E{DfW6J$FN=jYVpt>^xc%;1M6;my?qMw zc*37rn+w)CjN(2}0GL2$zpq)d0IY}AS^z7?$nUIvYQE8+n8sq zzSX5`UVw%`*i3}I)G}QG8r6CLtIE`}`z_BE01eARUjejR;u~J^8dx_q>}qo=*pt*G zYmpIR2K>-?R^wTfxsaBUmXdk}lua$0dQ?JFJyL{+rvgv#gcH(aiCwjqjW*i0H&Pr$4)<`9>S4k0q^jRLt3{pNhG=$szXahPTd3aUcFbRo5;rLDc%S4xB6SQV&|N4PV5OZtHt;NHkO@}reT3-&S-c;{^ z&d_FOo17u9K;YHD8#S@e)U|0##YM3DV+r259znX-PSe&zB#`BDOZ90p*_iS0@RPGA5-@u9DVQTd&M>cDg%{4 zZN}!PJ>qbpJKA8m-yu=HCW{0=?>ExPhd~8ZP}PIK-e2!O6Y65?Qp`Y9=$`4J#~s&`EA1!(0+$i_cWb^^*kO%{h2-i{o z>VP`H9z#B>eB;p69#DJK9<@(6m_nnIPz9hWRi!F1p_|Ib%y(J}YQNgA_5x|7sXS9l zriwuAQ~Ol0{C$&fR2vPlQaeEnQA5-^InQDv7f=O4lK3EFC)EZDvs3#om>U&@e zW7Jwui`8OQ7&1|PW4I@^(PRtMHkmgSMUG315>~AOHCatoqady@t}yOxNEwqdCgl!j zdu`im+nxveX6~CguRjDw21k~k@EeT%QZD6H=yF1r6RvIz4Z|CThbKez)at2KOQ7lN zrmq8=L5FpiyIs}hMmuC?e_tk9l@q1S!iku1OeY9(RG>~!C#YW;xvLNAgL<>*sY*?R z<#`FZ%;_?xOA;JeShW1JU2x{#y(_a{g81XT<07*__2(1yEySPUeMlEUj2=r&@$=vA2BfbB?&fYT z636o=K^9X$U!kwi;{@sVh0|Y3N-lZ;#@>}t`=y5ZPeZc+Jfn^5DD<&?96H{N z2~B6ZnXky^lyWoI6bS{YPQi-E5BX3|29@grT+39MYTg9%f%$;bimWc%-;)UDWAm{j zsG#Wt$j9&_g zQ~KcjZUd8Su{#CZR8d`51J_Gdr@=v61(2mW0ke$in<{`zkO^ien77T_vRQBFI{m!$ zHbpZ-E!iz!sGI;0BZdu-IzM%O$~MS6mU%2Q7Gg`pmWcgDuWQ&pC|>)lcHMcydBbdn zyFc9h;Z99RS)H;v^#hg2cLGK*!sG=ZUtz+82cQeOa1HxneUQesx+#tB2|P`8;q+9i*bQ3d zZl=%qAUG6vXISKG(E6bQO}GV~NFDn#!>Yy1WMdhQPsNt`E83p#$ktx_|BXz!TRp&e zQHI{R1I2EJEOWQPnTG!2H7A3wpJ#&Sbub6a0k(kqmirb@0@Ii#&+Bp21$kHAl}7s9 z1`tPS?F3kDg^4m&kxNxIsw=1E@A5$$(I(kMVW1uDD5m$P5Xk59xl95^GE&M1kMbQE*yl67P2s_niikkiXmHND}|Ke_(vR&s|?U~wg<>7GgB3hSJW6R zQ3v8BYMK0)HoM)>9<8Gms+rmP`?LD{GgzalE84QLQ7i2qw45O*oie%rEAqondc|DVOy(tSz%VvR~(Q4uN^yye^Yfm^MRu03;z5bzp-f*%Ikok+0-C(k;K10C_F+=DFPKXm?z6Q6OER;DQ zk21-81yY!mG9NORxy8&25b~0q~2L5kNKT|}X<308{l0eHt6YYlI zpj=RZs~M-rq_(93B+w()P*b21djA706%&+vE@iKS1guj#lRdkBI@7bLjQzSXm$B4` zo~ac`W{@G}H3KRUBv?!$i5<$#<`2>-osbjqF3^|09RIf@v}oBa&^7+E9>_^W27#*6 zQGGDKuwK5L1T)!8=2B1<=`DGS1VswU*>KcWsmx3;@0s`5qTTPx&2RzCXXZ0b29em$ z%kwM;Gt0~}Q#DYY*Bhk{Y!c8VY}cJ*hYcj=8I`{81I99z-z^C)n^YlMP08s8v~?p9 zOh404R_FsUPv?jg2J@5o$-H70s4P%!C`7Gfjiz#gZD5l*AkA$Txmj=4{|OQO#83D^ z9+StUhD~v(ik%etpz5Xm&QAy-_`u9J^Ude_pj8L?QofXuUg5uaeqy<0*I%M2A)p#K1ow3Up&Xml;I$sFq{tH ztKzl*@QhK{nQwFq&{u(GVbfpxCV$iGP#VBj-`&7$@UCzg(-qvY-rf;?K=w)=ceyQg zNKQ)~@T4BkP>^Tj8M#k4_C`U-=RJ9kIA8)30z)umm|aIw7Z}GlX%O`OC9;H)ShM|- z*?~#c$Qmhck#Vq&Nan~KiUW`ENS2jsQCoeZuqB=4)gW%_8~H}!l`}0D)UvgRMHE+L zefZySK(BgV&9fY0`^5ICIlxw-%$s0}nPTRMeK51QmdijCQRcYnY|bdhbJXtO=9qFf z$F0uBB-qGrE-UwNRzGLA3KF*kaY9GUQFBVGF9($qI&O1Yb5^Zcx2P^>qkYiLUge^+ zwZiPufVstbD;sSsF^7QGv^LwotTwC7F1-i1u;0m=kI!5m-|qs$T;I8DGQ zZh>+^^MGY6Gn+IJ1!jiL*3Vf7e8MN@7eySSAf$Up_t0rjxlH9UmHR_NT0+{QlaT&d z`e#>9{*3@MoZ-9;WuGnk?4WXRaqh*r*Ly?q_~h|7Cu&ML3g|;0+A2hE1g3#$V0vj$ zp_%TCmG2=PYyG(>5tzwtV*g9gVnz19o%7ClXBL$0QnpK3;L?ptH`X+Tl*E)Xr``sx zl7WEvn6uIhIuFe;_4GoB`6%@3TNfa_yXO&rkVK~-KuA^RR{(DV$CA)1tiUk*Deu!f z1#=V5zS!?QIC3_#MRXC6rLt58+OoC0rlfBVJ-iXR;XMM zH(VNAxX9x*!55nIlTw>u+re!IxA#+|dOyetSwRz^J?*7NkZ$Lw9F;mib*f7pMdD4h z_)-C+w3LIZ-LDscCVLmeNwn+7>K{SFWj?>X91h zhMG^2WDH0ZsUmTuxy&^m234=F zagCEUBFiZ-6U{_+D6;w0=C0-qn+k9?yJt(L$u!P@dDFZpM>In2RPN_D%L$oxgE*ma zGL9W!zA@j(UQLO1YlQwy1J49qID7O#+ombsW=;8OTYZEXt4?)?z*IF=Wre0>J7h=JzYl}|5C0$j`rzB)+mV?Y!bXIR z$bT17YNpgYB|xlokd#T3F`M9ed0+0_nUF7EXuDg0Z>MX8mV2E>0Pbg2dF4=99{{kr&eV+k%e{nJZ+^3|YZ7POl| zNE+zQ3HcIkzvXuH%z%nbBWA^1g!DTpRqno_HX4trea%i=<&p<=A=gtULzN%%qClD6?k27q&fU@{F#NCP7Fkpv3M>X97K51uep% zv?8Amf{@QbSx7w4kAAkBPLa}&@*_on?sTU(5JOC07{NbBKyeV;CALeAT3`m6fo7^j zHs+}A^v7*A${f>bRG{i~Mj_>TMK*yd)e%KDC-nD+fI<{9M}v^ladVtgmJ>3IG{Bs) zsfhVQckE+&fp%L`%xnVlka@^#4ywxar@z?+W}ca60{$yM0c9v-wu9Mk_Gc-hH)t7j ziK}A?e^avqt3tqri+cW6efAz6JWedBAwan_o3h zPu0Jht)KrbgocEMgiM91EvmMtS^|y_J3egDXOR9t`U6+@{*3_i2#>H3%6(AogTWKw z;?;{+uf{;q%%qvgkE^15q>_PkRRGvozrRCJssh<_t^zug+Cc~>Cpjsl)y#_b0HABO z2#__c0ZqYAK#?6qb`&lKq18jHrwW{lJQum7lOnI6ov~0sGc9c$bhsHEceDk#qookP zLu9^?u>fAL^DTgPo4tD8)y{YT|Fg0OAS}jH0^sf|nX?PegY^fl?yuVx_7zBtikS&% zd*!kd3Y?YxZayed*gHM70JN?c6LDf7#J!(;!j7jPZGgW5&x3QurdIA?J1@;w$9)*U z7cRpA(sTJQ0Ql#*O92u`r|r#u3x27U`evcdU>f4#hSiZdF4P@gcl@x@kT5P`+{q^( zv2J4Bvui+FOKYiQd$X*A5l~-A^zy)HMrV=4bu@rB(+#76BA6oDEM7+y(bW{GG_e~a zl|bSoPD*HxSxNo>dRhgG)1Jt3K}zb1Qjt1ZeN#t8DXGY(IPeF5WFe(EkQ!1$%3;0N z%R+M1NZ+)&%=s%c38wCo3%@L zv*kcIXvf!>cU9896r_W6V5KUXE7~2$JYvh_vP6Z5j(SWN)E1BrENLu1f>~%5GFNpo zUgeaYP(p`&m9 z4jH5T%>bPBW+{OCg+*NcA=V+>bId#qkUqe_0U)fH=a~x+K$q`|Jo*#R>SAVzu%eLm zx%+wC8{m1EIyWvr?x~?C&pikdZD+Eie&w6U^Wb^cX$jySwidSj2dqD$`=(fn-D=iH zDKpvsK7bi*()kn)_f4Ohrv{k(c!DQ_M(>W^UAhT)le|gc-@?^KR~ub@Ud{OX1CyCd z-|UT24$EQbVegj&Hii}|w7pNc&2KdD3{*ta#BxV8&}wTSm9CiZijVlSo0r&M+`tt^(sS;(hMwjK$9ng0d>b@X=3Qx;+; z#!jsMxScTSJguZ;fXg|i2B-px^harcghCS!5QO&lTwe#^ijdRkJ1f{~NS7 zO%18cat#FUgLja3karQpei-{(+0r(O|5Ht+eFj1*$N*0KfB)m+)c~0hH^cv zclY_@=|AQh1}oR6Bo}@I*hf**%nA@?6O>_e-i|E2Xo>7R_dMRtnWfTQsU#Utf_oMMK)zD zppZJMFDhdx6{(^Kr#?t|DNhCEe2VBsS{tOQRF#U#`IOTD7za{asuQO|)vEgar6Jjy z>^-#?QqHBEJ9Ye@1fUAu3VBLG?0vEKRZr3KunO4B31BKy&3WB%14`%9wuy}uw)e{D zSR8Z2lAdO-)#aE#Z`Tf>2~EsSFq_OK^LuuaC#5NEu7KHN_Lv=-(rpM@z}whn4r)rK zj(p~KO@)3@1frh4W{>4m%waH_&1SyQ6mnV6|IcQ&IjCi0EkBx-+I+fEIiR^ph6e)C z1`R|XX;tn+CEWv6!}o2K!F;MD_!p34L5>BHouJt3#a=Hu5Axj3b30!va4)zQGM3os z3RjoGnfYhtul9p)i*L)_d4D4SRiq*_b68z-}CQ4uU6B0$msv|6L1{}DBn**k!3}e6`2A@IZd;Z1%xk`ne2Jn1r z$^&?=nEC)tPm==RB-j>a^QCPZGHI$OdYlpJkgy9tYGaYjA{h)I&8(-lyVuI;{1e^t z0RAXB1dyKM-vf}k&sP~BbEaDkV8h_Mo#V&CrGs)kd}a0}2wxw*KHq+*^?9w&`|pAS zpB(t)_Zo0M@_gjwzBVI}7RnuV1L-WCX=wd*L<7IHvdBZ4s?A0dO?jGY;3%SGb3F}U zEj3eU0n%35N+s=1*YP~k4rI6tm-4n4V&|(UA{sB_rIhqHjaKjrlfKpASxHr?fLwt667l6^moa z32oK|y;He?M7txJ^Qvdrqvh{Ev^umEOk2}7P<1j1+7*8g%qTO8?Rszi^tJmK z;9ADDqq`bFow44CvgrM>o9r083ACf*l8XN(%Bi8)m^HcJ!q6>Bi$cyqKI-V$iY@~_mX_^7`s7D){f=OKsB(*^rNCWAra*f(Swi@rt z`%=MD6w*uYUjvZUvRcXjZD=F46{(cbDqA%xB$bBB%7qAAExOM05UHuW&)z-%>J*`XxxIt>8ZwY+{BOgU4|?A8mn&kCK) z_ezHE3Hts43@}@jGf^_xtkf2d4ccO{#eQC3iiY_`%jg?ae-sE%b2K2W1D3GFtkXa= zOaFg`BBD(yqw;>TJogw2@|5s)>8DETEN~t>igV8LD~}kr)E6tY?D&F^jPqf$Uo}7ju7`;-00T(U{~2)Wp`x4 zwZ_*PUtgD<0?VuNs+3cqU_jT?PkYCDg4CAUqQb<0!dUuhb+|P!g(+FTucj$idrL{s zR0Bdi6);xS&#R+>Byd0LXe&xtD;&-`j_P`RaVqF+9E6lUl~1Lx_L?bYD77pXB;~c5 z)&PtpVu#KMg=bA>ViTzN^+jd+EGJv;Y7g07*naRKeZ`j&jso08`48Vw-Xw z2Z7COHajhuX?CbE@q!gnnLSp}mz6?owcLw2V4Fs>kj*|NN4IK9_KOCtP0BG{vQUzx zV5*zyW^GUkHJQm~6PTCGO9YU~T16`RfsJf58^M$@Wmurd>su>eG@HOoFcY!@(HH*% z5&fv-^ZTkh`bw*2-$A~2^1YL{Jyg0{>1x&aaQo8jOXpiaLUcm(suK|TU`CDW8PIB2 z&XdQELdg40nv?}!J9*D^1%D5BB?aK_QX%FDZ2T>?W`SLhd!^IDe+wekJFBDy_;<)S zTEVT&{)?t5H0_mR`NiE3GMTcse+KVy(@Iu=H0OKL!B@)d%mG;cRqB%RE8tcgR)uec z0xuSLvHmECeJb{;stItp)8$T=zJYVK&egi`sJapu{{Mc?1~oCdxFmz|7?1f8Dx_3M ziT}fHAZf3`?cpa^&HoJ=>zrSKV&=^po8e{~-^iT5K-sl9 za$kxA&sa9fd*GjI&GkKnEduhEa+U!&$4o~6^O)kcAJw#frZpVSeA%^5h$G}_04bu| zP6Ut-Qp)*~Sqn}D=5h^ug=L0$9L!C;(hvBCp?m_zM@h2=IUy{hYL~&q;e7A&T`!D> zgJTblJ?!f9Hwxqxc}1F9L7{Ze0Nq(-FU_ssRpKodDxI@MnDUeSB+a!2BVIY3rrLDf zMfFVOu+wK61+{cMAx}t4RX%IgQwrE}y41D3gjw&eue0u}C<$I$5l=xY=a6bzHEXPL zoLYL^HI-8;q;ivDHUOQTtpVuDKMX)oej9+Q_fTuoCzQ+CtXz(cOg0CU>o^W(jakDE zMIvj}@N2u0!xR1MG0Dkrr`TL!+# z77ntIh310wls19+U|-rE7_(Rv%$t-HUX)!1XEKw`1`S{;q%*UF5YbD#WR`+?!MtE? z%#{Q3;^kwAjfstksR>ncRLxQS3Ai%q%BUl=;Z*FY*wvp~q$rahHU1j$7bc={95#+$@@TKC~e$DVp+1{2Abex$G>}4 zFZO=p&*4()rPNEU;OvOABhC-dfZHxWZ2Zl@vq=@?ceN~=tULQUTfXH2gf$9l6nezE zeN<`%X>-!%T&fG{`A;`nG!QBr_P%wx9bAa^<%o6Q$cO$MxxWT?zG>^Uhx`wj^64X> z#**-PNh_ex(y*D=PJr{Fnd}~elu+A58WQ5v1#k+R2moK435FtB z8j^SUKFk>p$6ikRIJOU5Zsn^Knh$E$3h#8GBZN0HU)>o9p<|q}vH>nk<<06dAnk_= zHHPMfl*uU(nKR+HlE0PQF;%&ezKSTCDB|g)*Xbc$z|A!9w9>%SJxKU@n$uF-mc^xw zmeq$U!f6iDNjgaZyJ3p9%1BGCX4SJ*D`~1JS4kBncCzJkS_BCdQ%RLdDpagymF-zd z>_$q0$0-S3D=6igB$K49R@nmYudWDaoDD#UPyf>Zr^4VUXjlR+p1s=tAEhm zASH5ddYcWl9G>NvxKXP)vla2IR+2g}!0;=p=P^sb{Ahm63PcNn0@16y`X7ks!ysfd zp7G4rs@X!wIXUO#9B1rQlzO?~`ibi&j<11)^9koyKB`7;bAqn;4UWkcXuCe*;JHeW zZ+6J~q%IJC+S7>XU<#Sn0aB*=Rs(ouTeXe1iB$ko*)}Ce6r%xTj4hJ;M!K&9giLi( z0lcf6bpUC(d>_&nlDcH30~Lnt62f9G_$>u(og@cq2=79sEAnaxaz@Tj%j(Odrk+os?B22DVadZz=Y-VP zQ(sSf=AQ(hcyD}EI^;{ums)Kg7@zT(;fh3lRZ@08n7wANIi+Ry)7reaNJ;2z))6tQ z8n#PQvSVQSn!Z^GWE(J;!Dhd5Nx$jNyjcU%&-Ox@wU!(;Cxh%V#xTZwX_eJxeULD) zBqf=p2wWqyVd`}<>MnwJSXEuQO!hFFLMM7U@m*Jf>C(TKQhF2S2tv?0) z3;hf4OofBv4vt$e$d0LTzy1?P;t&ZXPC757UV-}>MwU4}5JJkETp1G~vC2(<~Z$XiF zVcUv~=`qUz2l>Ayd2%23(FqDRD_Eyy7?ggo^yG#=K=QQYcW<_Z-P3kY+x;5&F8MC` zGA-hvog$uI`WdhM7sN9pTM#OzXbMtC z>PT~yM`$&RW|r)hCQ5c!4@$YV$QHUR!WWkK3Yd#S0% zUq|&wjX*}pC~CmX6*pI$&I76IQr9IO{HFovcZgXUv$X0tFi9rKnF6Mp>1G1LwC%uS zJZ9E{`NVu;bbz5brq!n3)h}nK3I|tc6>YtRcIGmecoWY`4Qy+GIm|J?*>ZSR!1zsd zKI^o~v|P#S0Li&n%jjSJ`R~kLtwznzZuF%#Fqu_H1Nzb z3)~gp##y~dUkR%&`uv?+f5<CTg{UnpjS=Aq@%px$UHf!9|X}wg6jM)I*t=_HPEf6;?Zd%z` z$U7$Qn3$g->E)!C6Ar-nH_yMhZ5w1X$!Kz8jJ8??nV;wUfGNJ^&|*-;uESLzqOT{# zjRUu~6eAMSkGd1gN3g$0deJflPQT-lqt9O)e;LZq9dZ}QU7*D4P_k&rq77<5uG+b3 z7mS3&w-et^_yLYoIa1~L+aPmguG`acE<9tKe5Gj+xtvBC<2CTK`5%bqK}9^>?g>2I zfo^o8e|8|lV5B@qD`_Pyw8cn;jnWKcrL2^SKnFTVOBJs6x~IxjTFL1yK>@43^p{$| zH+&=Nh$#123s`9e3}FcMf?71T$QG%kzCabM^={$>4M6fwmCzq+oBu5<^_R)|Ky6R~ z;t=hkzF@5zWfPc|rX|a)j)7ekdYVD1gg&CiMjO=zVzJF-&6COrZC0-2XX|T1aWFkh z4>L%+tber%W|OAAm1aDJ+V# zI@zk3Jg4Vz4dgz#k5&*qHhgSoGL#xqYE0?kkT@^#(;agmtx4Ls87usUgXwQRAenYkapT`T(m%u#C_=iOq<#%aI%`vDYsFTC#cCD8nwJnCr% zs|TmFDOevu7MSMl`;hZPNzU8|$*0cdTHg(dF0Qbo_aw;MFmHpXgOGGA=~!~b|B-S9 z3k)3`3Tfa8Oj6CI)w6Vv3vxliZR$)UWKPYTnwe<>-r<`Ndnfiz%qb`tUoyVr?@+Z- z)kY6^;pXO>o6kqX^@!^cN0Z@JnOkKNfjjv#$KFnWi>)#e@@|5dVIddOYlHVIbHhCZ zsfYZ-J+}nQ3-V6OJFRSS$e)})IX)h8t;n?^|6xd;kUZf= zQ`r8+_Aj=4Xie8|^#xfb%cP5v!EH3~w7e(q^whx9RG+(n_aL5Tig*TU;JFv^^w6&M z{z2rkAkr4(C3%S<>I$(TD5W|gN2G(=tvslKXT1szn_71X>7;_lfD(JD?dg&SY@o{` zr(0;s6)>z@tiOL)N$OfQBaxmOHv$4mRZ{cnKSe+-Am*o-pQ=1(n<<^wH8t65Z65+V znE64=)5omAlG&{i{3F`EK3|1{Yn5z198^YsjK}y2%nUQbtkV=KQG3DG0_$1N9QFAL z2nP>pligbFMqd$BCJ!gvY*1gJxvHcNRK>nmMD&Wa3oyT^!{3IW)T|iA%$sT_u+q*C z%i@4OhsxI~U#oBliVP?+px^G4qdRnO(bVc^?mJQ2kp^9fEy6ovxdg?yFt z2SgnXDU&(@yc?~TaabPDegMxw=Mex;s;L6t^fs9QPI+4!bSBxFUgrI-tJkb7fQ+Ia zfVYZc%inXc&5`vi1?jgl4{&?SVE})Oef7O4?*pXd%v=c|6<9!ixbbY}vRod>{MKI~ ztr>)DGK+jKf$u1#L-WG1W`!p|7Y(MJ=bgO6Vc*1k6Zf}Qg>9w(V-wrM9(Joe$0a4D zZzzKLL;t;3%f#C>Kn0N1mLMA#K$ZX>@PX+G`IGV|#rU95+d^#%?}jKh%FP2fy`A1} zBS?=0+GZrAb%VN#w?+g08cjO%!+I5*lPFIAR6>nBdylfHB znd$!^0C^614&^=s`3~nhT=gk1Bh5%NIH>ybJ>Q$(ROoj)=z-}&AF~0>0<*xZ4pK-* z6U{Q!6a8d+wgT3t=CCRaYqnUWyG@X!^~D)}B_7(ORo(L1h%O z4C^(%+BQcrS5xL~;CaaNkkcCSe3$3D+#?~{jdr7JL&T2}KSo@J&`Y70!m5Dtr1PX1 zqW(D>A!AO)ob>9D@>t4acgw={eb@ITy$Ltk-e`NX2e|d!`u;(R;9gh7@{=GVWCTxH zeVPnca`zow$gNemJPqr;+}`>PiTeF8LXk;R(gS*|S>-&n<_X{#4#hwa{$^}3@hvw|lx zSf%UB6k(x|6AMAj5Nm`cU#Juv-8ov?h|d94S{obD%}~`-j8}`;T42VQG4hR`{~z{7 znf4G{A+|!EId-~3SPRGqzr14K49NAh_m8{VA@hdYiPI2uCUmd#fsl?)2J67xYzNy# zBzrFaI8U4E0G{uS7r;~5v;c6Pusuco6Yk3ZIgW<(1h{@UZF156u)p<<2TI)!mqw@e z4ZRLI`g)dPpml z^d7gZ49q-~_nMS`{%yspidlQr<2*M%Lafv1k9B%`fwnQtK^q9N*)K4&%-tFbkpPOr-3Jcc-s9r z)yis>Xrb%kAq_n3HSjdcP66eFoS-LAi(1kvDDVVQwP)p7ngX+!B|U-=+&Wn&Eo?O{ zt3_v#BC(DtMC`7v2LU6rH6SBpq_ne$&(4

mTp`=&-gEO($480qJkc)8LTz$EIG?SO1eAHDGkNg9>FC*^?Ff(wFie+hm&=V&{#?B7HDj zdx1@R+e#tYLIK)M92|&VF|Wv{_ClG)b|;dhAY)_<*s2++8mL-ocX2YvP#J2P*=ARH z!`g_D00s9H+*7b4q}@upb!!Ef*>@WzJ^`t3M@(^E15Y03e!7Au(e!b5fD>vPKxCaf z0N{DwlmKv!+KH!5XHB&R+UW}Z1@35oh%4R%*2A_=S6*p20G5onzM<$>;7jHu&*PdV z4g@;!i0J`*n*4mh8c;SeG^Ru?=ySd3;@^rvPG88*i)SJ8m|GgaGs=ke=_CO-7i}pa zY>)R%fK>4n2k_)KZ{Pvvw#iEh-1*KI>sbQl)~4SV)*alvcXnUi3ehv8XXbyz`avbu zR&FmaIy=aaj1{aPN*AbK{e`xw;51Oq*O}y50VXpjfEf&t$|=NXm-u&@B74Z51X`7< z60h%D_UEpA$z!WJ6t?rWq=6;b*#Hb>Xx9722l?Y15NqcC8n1Dmav>$PN*Lfa27~OA zeKfXYtPBI*=lwt`M03^M)YNKN4;B0cJgEoi=Y6ZBZdFA*4+aIE|Au&iQY}8#z_Sln z&1&f%q?k^S1nOJY18JhYVx9H64$|)VrdTiPK0yfVkQ}0)-lryd9(}U|mkgDmbhG5N zbvf5Sw^Wu&b4@v$lkM#JuL6)hNHWMOHqAI|uq7+4{)b<*b>c~o$K`Q0*lL)p(hD00 zw56@-4{};gv%%U;$O=_t=C&8WjMf2x>-7Y`R+8G-$ZdM)T(Cv<0^?XDW!iyRVwTAA zAVl;sF9S$d=}I%}2gH6Qt2@~yTKU!rsyL_yX#Le->s`A8aKu&P z?tr@kk~YEFUc8k17C5;xnw6;mReldYaKXGYfV0>i45-n4uoP?D}`vEaO@-|J@`fOEp;McxT!Ab`KDtvzS75*G*V)by9h zT@-fSNSjvZ99&&Xa#%IUzv@oUiyNWn)S^>MJq6}d^Qn{oam2~8=eXCydUuu-!TyxJ zCk4~d-V!i0D`pk<99B{~(<8Am#jh@$c`hD#+@H}LnYiXf>A3!`$Y2f)o15d|neUY4y6Z{fHYMBd(ybYEm~{QslQgq0$fjTo7vDx4b1|7cR$EQxhQQd7aSUTh>cy{(j87HS|0MnpfDA4JRiBm;|CY?`S~;aimh z1gd6@fiL+|rrB;`lC`(1zB>Nx1$MLBG*hX18bsud$Q}6>TrYCH$hjmiwM`8(0nXqO zY2f_FcXyZS0o{-0E_1Xgq^W`td*1>uwX83lsbOVg<^eMUzzk+7KzcR*k2#9K z&uLed6q^Ffr;OwQ=ChC@YIl%B19OypaLA=SZXQh)^1#_VzK_Gdfdenxc&BDts5v|4 z!>vHN@h1V8PE1$lfCk#6Sq32Fg0mhVe3$bunXq$3>ebjOaP?cM5LOE)Z1GC!(A1Z2 z+<@>|;j_Y`z*+CCcP4?qmcN$o=O9k!8rMJ(v?3h*N;+>*9Zibks14_U@M;!;HkvamF(`s&At)f;WdxrZhZqY)Y%YG^#Y^Q;zOLmGV z&&%`D)*>E)15Yr=(@+CXKw&&sN#y2=cv@-T36%L;Yv38C-Rm7RMQo(kyD3O7=_Sp9 zm8_INYTZeZ-j}vnS(;}fz<{uk_O$0qJ^shCuLo(QWmWq+{b!hQ{%ZjGnV)gBoH$lL z@OAA4=>XD0dITUQQ?;!3f=2QdYUmXZKuxuNJo19t12hkcw1LR`7>`LCYoeXiB=?|R zz;1d$8*5|_XR$tM-*q26Tj=Wpm z>SN?J2<;o%*ZVa{Zpkg7`Wmku#qoCIk(2tGq-EN27LiDrl|{&1Engc=Il{6L5rRmJ zHd*>XrpOe@qvxF$BwC^cO{Jo2V3WKWcp~+4@__sye@HnyhDVC%@#Rru;Z+2aGf4S+ zOpZ}b7i4LmInAjJ>}00|#^cmhg>g}k0WyHHHieQZil|xyHFd6&b<)UgBvMT&jfUCH zpxoh()X>1xM+0efJ^v;_98V|dL_2-%1A(A1L~)@~j@u7!@`?Yg1Cz{C5Q8{GTaUs=D(J zu$&CtgL36fY?4VJ56i<62t-{pR~)Yq_C>w%ftl;|0g)}hb1ST;_^5_GY2W~HPzl+!o?rhD#_iIh+ z8S{k7^(8o6a+YgDO{`@^oN5&JkN=C7hfy-hw@#;b%m-(gv&?y#?3wZRz5;;-E3R@M z3E2x?j>=Ift%2X@&Y!8mxB_;3klfX>uopY^AxzI(#{~t(*+^bp$Wb~CB!{(&AR24t zo`xM^Tu3+4!06y2`aH#fJSY!J5ug&4q@1nxN@@L`5{ei~gM1>NNO8SSwQRLCYm#Yo z%^>Q7yeuzEbtQ2dX*s-6P~g}n`=q5>rB=`lvv-hy@Q56d`XEiD3GFrTGzsEd5+s3u zV*0NF&th3DO?6!w7 z>~&>`{#{_)(W-wLfMksBOt0v|9HuE%K(N$DS@Ve?pUG!g2hvXucz_KE(pMvClkCXK z*L*F5HS)H|hKOX4Awx7$2VX$#2F^l6m8c|*wQANn+X#sZT##m3W$3PBL-fI*gQkv^ zt&NA&RfN+rs4C#cPeqbY>Hq*B07*naR8326N=0xtxtnB(6(aiI1LvS~&{OCyF4l`C z#!Lj?U@7dW4Q>vxJ>chUxm=EDF?y%I|A4IxWFD8|01?BzpWQA1Qjhae)$X(u2A<Z?FhKc~^172v#RQ!YZ(T7J3?-d&}~qy2Sm9#wB# z;{7h|BDAE!ifmkr**G z4iHD2Bx*IX0CuK)4n?MZ4HSWq!8w8uO@btdPw#Jx3jD(CSRo0=T8S3ZX38jiu5|p2 z7?7Q^ld>R#WRR4$!a6CgW%cs<{(}1cc=gdKVV?tuw?0);RjGpbASLhtIUtRL{BtHS zLF(zo5%6fPqT{RTX-ZR0%k+T_zL*woIw}RxUXfSzY~-Jn2{fgtG|+X?{GPzmOxMvs zMLfa6#&I%EdTHQ!Ae(&V4gq*8htzkZoeF*@0LMB0CtcHAnJazt`UVixqk3KsXpdQc zyUut)|8B;=C84!>Q2MB%xR-vxO555%c~wL|fSs(kUgrl{j^hEiDhi#%~|GsKj122`2_NoU+o zLZh{6rF4Ug z#v0WXQI04)2sr_i&_Gd6Q-~s(^2PzJX-%LCrl?U~(G9tr_E^1Oks5J&9)t9KRqVz{ zWt*x=Ju6%!5D@PRY7(6%^Q513eUO@3U2dNJIkHd|(nxJGdTYSw64b4}SQg7rC6^!6 zz|$=V@r;vk(&L`M(@YUhJCKgjQ65qOaPuIc;W0TTL+o+UUXSYwydhQ8_FARs~bTyJ>$pj2lsdwCY*1$jXp%RYdt3pIcNGFZ!TBeTnaY-KAGHL`xF z7cKzN`fDJ1NFjIt5w!|JL=W?@w6Q5bR(Y~TwnCF$^rEe%c2&q8YvRL4TQzQ~tBTV~ zn!7j5_C?_U2c)~@f~2g4&NQ*)Bp*WRq|`}wqafFgTsvaImHa#hBydLdLFuQQ*Y9=# zlPn7}s>9uo%t8RZId&23QHl4%my(2Ui!MwqK;;hM^-o`h>bpV?CszUI5n1f6fSf5gQ(`AWMp{N%`g`C$ z=RW5zV@Yr+pZzK)o?_oWa>F)1b~Is)3S$f%Ga?VE}O z{CeJ@LDwOPB*~%IDUY3eD!COAd9ag2ODM8Z7XT@te;=cR`f_UZv%IZtNeN3eP)eV- z61p*#${xrkWu>fCu?tVC>hoG9$cJZ!%%H9|hn80tiAMUpP4zi!u3S@fs~?gU`rNkC z=eVMp%0H-?NM&6=O>|=#cn{*Kdk^Aitn2Dt#M9&+#4|(#Pm3UZ&`~)mLoCvwopM_N zVdG0Sg=4Y?o;KOSMUqI8@k-G=`EL-A*hx>)T3YjgLcAyKU_!pqX2tteaJ1Uaa;Kb) zcxH%&sO;3px!hW_@`XJ?(_AC%x}ct}9ON*aHBca}rD=9BP2m!E?0Ri0+@E=0cL-2jl@*`E&} zw1LwDz`bb=vs^JX0K6T{8vtp=tPZDA+dTF6hr__$?qSbHSkV6R$0cqi z zi)m4%uJ$OF%x>aD5bCO&rMM!Y`c~Hzs1`{xts(|Eng+mVMrSSXzy{pX25^GQ=^125 z*C2h-SQ#rl?7I5Li07f86z~EU{=_|fFW=Ks71f=yTSG`DS^8>qIo_tIffVkab3m80 zT-iiZp|1J`0cB@bjeJko9W86L?8BPVHqDNlS&>vDYar4}2k9Vv^@21G;%eqIUj~D; zlXlWVt7d^7lMWg<8mn}?HOM(RmsS00Zhd&9g_?CYw>xi^zezuvEj(SXWu)AnZ6NYbk#qo0NoO`dYJ_hC&qDP_V+!x>4$sdo*LQOz7?`_I zoy6YIadAwcEA61i@Yp9WwSp%iu&i z6~JAi-|w}9{n8%szXIT0>U;;_-Y@MeF)ycB2szq&yNL%vwtEIeG>7Q2(X9%Vf$KZ2 z@3^`^N!5~izsm=``tb|8)1TDWFhxjl`kJI<^d)^h3M+z1)m|l!J|CqO5#3ZJZ-fd< z!|VnjCA62!r*ecC{r-HaVD@X3Dq0asMWqZfwKpp-S(8CYCtdO=*O5cXVOOiWd4VGw z3Fd}KCRxgB6|#y=4JFQ&-=%60!cHMY%3Hmh6i{xov3`H?Ab+2ovXffc)m~7Wy#w4( zeqE2PEq6t8yCF-(piJQocW9-lRyC`83+8^Z0?*$?Jb`r#$N&vIJ#5RBG}70H%_uWI9^`n#{2fodXt%oBm*Gm>TkhDyt7!QksWU zcXC9nVLPir_gUL>Lmits(psGle^(`Sed|+1ZR-$c{$G3N9cNW}z5DMzGt3MF!xZWi z$}p8KAV`~`H$?@(5;CaR`^;txlJ>dxbMMFf&;G!iz30r{@4Mb-J?mM|J5W`n>%hCjyTm&M4oyEa z{m2_ov8H0pk(VJYsr}$ScS6wSk0w-i?+G+~rMV4^#{c z{|ST4Rw<7HM9(#6P}v4&EbA=ENyrWT9iV1*#CaV*9OA&G&|_idBL`g9e2BHcAKA}6 zP`5kQ4j}wivbm9=?sh$9(frt>05Q*8AbQev14KS?vbE}|ks5%cEup_M2tY(A8MH?a4N+&DuyXSqfIllYGmPR_Btnn5I-KNlM&w-OsO< z`AX}y&Zo#)I*()8tM{*yQk}wYA{>rzgbr>WJPM>B{;3-;KG$V8YC?8)9G1;?Elr#v z#5GgDe~?nF%fX(oCv3c{((<&%tuHKmUGrv)QZ(t<7#1LpE2yBSWG?55((v^+uQm!i z{|NDXVPDuxRgsT}c+M8$8Lkxg4E>$cR4pGSJ(Z8tE>a-A`rko7NhC#PNv|M5lHI1r zHd-FDei>aXyPeq(8RL;sk&~V5v~oeZaZafkmyGvQGv2vc8O~K1y}Y66ja96&aSkfm zQ2CDZ2ne(ebC`T*7-i$M@nMcuv?&^}Ig-}*Q;ODC0;?Vky*lh+kL5b(Y=zpIIT!3q zJJVLe=8l^?ZulPLUX{DI#Dgu@+P0zsi2l`5DTLZkG~{K&;c4|hN(e!9&&VGVE{7(M zCM*XCSGZzS^!(Ug0itiYt&F1&+baOkJ+=TKbWf-oK*9swP=NYYu?WD?bDhO#RWx!A zfOj5O0)*yx<$}R~1c>}1c0EAkNw=Y1biB@UV=m=861f$i*;!4x&;@qXhqKyV1_!rC z$}_%zqfbW8Oa2h{KUH^q^EQy2-r?&3$#9_KfsXs$gQJN@6RV5lFH;gYU(V%L;!wG@}NPn^O&y~kW3qZ*wP^|{WfLRD(pm`<`+F|ZU%u`Hz^m97`jnrXac z>b@D8=xMUe$OW5eGcCm-B65M7x!GDaLO7*DI5}Vs+Jh8pw}%3KzP%7hsXpIH)wxp1 zIJ&Al-h+l6M^&x04Yt9$gN?PZ)?2-3JrsB}t{EmoI8ftyl!_0-8xXp!u{BK7_v$8@ z%b0+UXT7brGUa;6C)8NPA)$o#wWsucpF5J!o1n7qJ>XsEUB^0gx%W{Qa(^MV z&d#vR?sg81d?qrzv$&K_YVs=v?<(&qdOPDW28uIUpp~Hz*1xmunn~Fri0hddd6;swsYHz z?fN0~XqCRS?XTgZl+H^Esal#P^1G#-)uAi+{W)4(Etu8aWydm1;`;M9s(f zN`2qfeQTtn$<@U4tFsBmwqlSY&Ze34HRNqe^4Ga^u0Zzt1 ze@*;+U4KeIhx5EWZ{ze_<|>en3k0}zwvM3+famCWpVA=w{fCHWSfFd(2N36Rp3Ts_ z4(f}1#B(3_`PDuqs^{(luuRL0Ern=qH20`){X6Tp2q^AF*KjOik+p;9^yu`uZ9)XY z^$SJ@BApRT>Gd}dQJH#drf4M^E!|B|S2bg%9_VRWNqmLrNL@by>`uFrzPj!- z-KW2VX`{8`bXRx2?-18dO4|WIDWx{t1ypOJ>xb%oT_nLTlg^`^Yg(jKQu4Nvz?VV& zfcgRTX|Qg_x)~p@hYrzBKkb4xK zTSH{GWh6|2Xp$`gsBRXy3m`H()&U@r=zw#iHZ}?%vcyIM)PESu2Z+2H>j@BfCDsHW z@2V2V*rX+A4WP_~4Skrpjw+oEAaT+;*8c- zCY=1%EbDP*?J(O#gO7~RYOu6yPwuP{6)4ENcuYvua?f-1=1<*I4 zZ^DG>kT@f8M#|1(p0I}pn;;vJB6l>M1Qko_h67ZUxUzlaTXhcr zL{5z*0@N>#4F!n25bFa_|75Hdp#IrdCO~Aa|8uwFcTGYh25>Z~{%L^74%g#dTO0W` zP2uxtRkL#Dz`|M8t#VpJ>|<|4=+waX%_Ngn(Bu6c@1HguLW4ttlha}KJ*)5e2vwh! z0k8AAZ3vu~veY){eQ(#fsL^?s-e*PNc^hU~`v1>VrOK7VW=!SdYNf!i+WSgz$- z6Y0DXRiT!vXX*vIy(0L=(NaLlD;9^#WQ8El7d!V4H2Tp>fx`K@iGM z_=)9f97;!I+3MEs=#aM+s+^xM<+gv{&MJZolw6=#tqy%;NY<~RYGxnVM^+@obuXo| zX9h^~C{df}o)i5P&KrIN4&oUan707EHLr(jp8MR=nF>6^ z6c^5Rlnv*(-oV<2)%^Y1apO;W1)%M-kN1i2{_y_8kBP-E5-B`WkuHdcJiKEN(dl-& z4HY*tT|e(G8-#L|?=RAQM~Y1J^%UQe7p;$kMg{B#p5r-6oiyFb9O>*f(N*)?MmAa( z2emm_I)ok?n7*XGj|{Hby5>jgr-7NT&y@yR9X{X#E0M2EI|ZZ?u7M4~HI3d_C|W6Npd?JMV}kq`U&lCmj7--r3OP<%D_M1Btss z%>fc`54{O+^w#?300(cYeHS2ncXTg6^&63k0czij&IYJHEAl14zHZfL14JrZwJote z)C3@uvPC--$9PSyi%XWGS?1-KKRxDt!3Thc7KV z1U2b3>9yrf5Nf3-I3Lw{Q=@a9kZQV=%Nv9^kBH0Z29{@evE6E!$qpcxKl5j+cU|(9 zBt#U`dy0u0&{EmNFmi4^$RPBw zqoMiLHrrM`--}`l8XAXCneOAwRR9*(nXx;CSYuOvYy0Z0n_Y zeSr|0k9f)y2d2oaV5*})>@)~p5Wb+|7RfNGju&03Hi`pUBb)gi-?Rk!Q{+#F`a?7p zjpa0Vg4pCdk<;_t7rr2UWHQCYJ$cw@XV z6e~au(7@~f*4?@@z`an~gE!5aMv-1fCke@l)a9H9m8VypUi~F3&RCqWFcn768a-=V zISf8+@M%+L!Lk|4X1w?uMCL^1gr_w;*YrmddPLSh?Jbdqyn0A#9vW&P@E)+Yi9u|! zSFXJB??te4!OjJH z!%oQ_?`r>&Z$BCvl7$DUa?*UsN(zm@9%0kz|;Txm*By+rKRv>$k z4nk@Lj--z(pbHul*tW`6S!e0zIw}S1+~|IT0{eV*p^KfOly7`Mp0ba9Ho+lA?p3dr zk7W8vAb63;eA#@^N8iWam19~X#N*q93|8QoqQEn`0rB|yqS%tylIUs(&kN7ncgqRJ z311!-0$OtX{S6-Har<9Ty|8-W!JG7;3Ijb|@AJORR74*xlF{dgrmJd}qd+uC56Bl> zovgC#NL8gqfGxG9aYQp&3gzz3SBT-x0L#yL872fZLMdLZ6t!h);`417%2iG2rE>fL zDU91oI9AZm1*Z;Z1Ko0;$)g zUYqq}7(QwEq>Jhxb3o>R_7j0U9AXP3j)^7JoDT^-ytY;h6<^o=(z^_fPObmcYYJ7X zqiLZ8Sb1yp$bt%Z@x8BSbcw*9-aoXV2w`}w||GYzxzKh;}n$A0vVuYQIi*<9{ zN^G}~QjT;uRccB-qTZ(jC(N^C=h|Q?N-0wG`@&k`vs4AjlBH-9x4>AMkV*@s_GzvP z8?Sz436ZpOfy?h5U&szzyRwbhsT136rQ6TrK>21 zKDdqL3Z(Sz)8N~~*L-a~ol=@IrAY0Cl*${bySC64+G*mXIw&O`6=-_hZM&^p2);a^ zT=o^&hdFHiJRBYrC6(4ifoGHg&(sFxv#q!FHV(oUg)cfX$N3o5_dZbodiN|L zpm%;L;zv_IjJ|T3|lbbA}Iew`7fp&fGv?Nv5y~tnmM0+yx@;e z-_G9Ne=DRM4P6s$0sO!lLF#|SruS?Cl4?3UP5D-iGS=c>~V8ABN=>eOR^{B1>60yb#d24dtg^=S8U%q`ulswRn5m9hZ~(6AB{i1UGHzL-ZO#Tt6uc-4axk*SYH`^ z3%HWvul7dQI+5cPb$C|Sc0N6xc2&~#lz6}`cJ zWxujZ#bx!zv1}H_e&C+e2=^uud=b99NZMlM4`Dxj2|d zCEWVdRVNtjoEBMzGn*eMn}mDSW46ro@-PUzQQj!t*Y7Ek175LGt1=mn{l)Eef%euW z+jX6z-X5}bT?u&Cd)JfabWs$#mCP$rPJMyfb-*hT0=odbsoqpFp~5PxY9P$tI)Cee zC!zPq-XpuWh3?OGf428_2tCo^oNhB<`}pnM*Z&0~{kL>l))!LGue$fM^I-i4k?vW4 z0N(Pt`@4R8>(P-!j>0FW*T0-z2=#LkSMy$G9U zZ9Zq?ELhQWMbnkPgSzUv>WI$-c5Re8Z9LBJREiScVfE7!e8&<6g4Kb*ny%$AwojbE<$QXc4f zUu$a_te^WmU^4?vuj_5SeGh0yJ4=D8tyNq1=DS|Lx(z29teft1=cU^lDWQM+tb8%F z_JqbXzBKAZy(6QcI=4D^Uj?MzntE&7%N$9^Fo#$eB(iS26R3fdrX#_-%)5-W?tyrt z)g<_Hu<16P-LChGVJ^_H!UYVkm-BV8-|P2$23|j}AKj%J@l&foj=ZKjc=vhtF~~h2 ziiBi3D)4|iE&Bif48Tc5K~&|tvaQ!oFK~u4)u%`Ts(c5{DRNDOzEF)~aYs2q2ql^r zY0B-h!167h&Ke-8U_Gs;t%TJrSGQbyHmvKjuFvPYp!dAqFZ8??@+agUD4YUmgYvic zJ_V{Ps;3>94LzD4*|7gTsC>5a*{@qc&A6IzN1lP`{^pMw^2TFhx#4$Yf2@00Zm)TPzkSAQ<-IDJRu)_hnyZtcu>w!)#6hgMd8E)MOw z0J7*zXEv(aylsFx__m||ILIf6fWF`hK5^ynID+Zu%D^0v4(M}rm*=UN@V3guEgGrS z`~VTrf9p&Wom+}4s&t6hGTnkjrhZSR-jD7pgOYf6zBQ50PG=Q8lHEdUO%)hA9lMTO zOnRl}a?mUiBI+bx9RK^~2lPG_RM;IdgYP6x=NIC1e7(_idLAb``wqL%k?9OjV7lyB zVIzf3&}d~^P<>rbUoEsgg>j}bgvoJlD)+gIg}lyJHMv}Y=j?_SDSORcvthcv3)D`n zoqG6lsOwwTckdG?Tqd3Bp9i(|XYCt}0?;iJJnX!R_^KvUMsIvVn1j) zqUng1TOG9Y%AAdbY0r3ey9w$IQQ7ec@SgLY;|rG(d6V>lXSrP4>n~rH2b>o)>m=@&K=xIe z;gzWRaDlq*i;-wWYt-c=GJl^Kd3vGYX_BX}nLDCCJFQklugo1>E zgvrjr)*gnsm31q_S30x&npD`kXYZc<*TAZ|tLA?6bJ#w1``BHNK>ZKue-Np1&nIqJ zk|Aa6R}JJWfN!S|KQ{269bTgV)ffT!qp(XL_44ri02ANnFhNz)KLPyVv*nZ4Sqtt-G?o*Mb=jfTVcRg$ccDe0P3TF(M_Dz6%Bf|IAYpr zTWzpg=qbcGQjQ5MED<7hp;EaKq8f&XLp!yhcha7*XBZ?Q=THdm4ezb&3{@9bUA*O9 z`TwjxA@Y$x=Lz2pym0`E2}EC`SF}tlK(mj&ajyz0*a9^5W*U>cT*C62p7ts0a7zvuU43&E5)fg{;&t7l4F zbtr#LQ+Oq|E{USK}+d0Wr(O5k)(=UlfVt+&Rd1pHYDW`@e3U%KnOvGS2g z(Df&|eb#*LAzqc*sEOb!jmQ3n0cf=X%AR9=dk87@_(%$5zemj1%`8_hVtbsI^m_IF zrHebNYAA;XIh6R{p{<~;l>%0}>uDrQ3h6M;`#3}6BSdW)z;bZA zWt24XHS!V8UGh5DxU&**KRJPb;|Gd$w$4f#kT)Y4X~p{e?E;2pn`{%=z(rhSB|>Dy zfhKD|#ad_!?P4Lwlhq1xMW7k{00-zVIZQVp{LukBjR+B&40g3$%?KH+)k1h;c;ev{ z1)ksHtaVQqc%ph!*Q>5qx$gwcsGsPTH%d(Yz};HPZurJW4|0&tp!WRQ^LM60j*F>^me$w;*Hkzsm?ElBZ0uvf)j#LR>{fV?t6R*BedA{ATwjDkxZAp5b^-fVtoyJ>BmFepg zkTbL(gpLhVam11KT=P>udtK>VuI;0AdB2RUeiWxSUsq|#qpRNsc4OZ(71 z(}+vw_*nrYFRj#F|73psKp6dha}_d#moPy;J{L#KZ60=@D&J z`C8A$f{br>MC3t%^#VP@YhKU~zIVJUB9}%kJv0*zzk2x9BWFX?wN2ONE`pS@l(LL5 z5Ly~q+GH?zgS<#f1E+GTcakLak2&PTav+^_hDfim+>yjy|A3FrRBx*1_t5;( zDK9<0e0!6sWI5nX@+SHFK6yE~joWT^6TmBwLVKoGpc3$Myc{y6%xx(jn3k?(fD*7v z?NYCmUgTNYrYKv;AxTw$jyh*LiNB-^6XLsCWQjCyDh0AXL6Y5y<)vul>@DP$0+wp2 z_W)i$tl?`J<>IYoH%#2Qc6H@Vx*6 zJIrA!mFoD2D9e@gX{YAa%tn8ApiFODZ7bR0dRnS__OuXAc7Tlbt6#fp7X=aw-mUKc z+=af7=>#7CWPnn98ie(47-#t7^z}~jE?OHXn_LMw8+)%vf^mGYrhiC!LR-hXg z5H|kZ{%${TRo>{=5ca}eMLtwtT7Bux-6EHJ{>v|3Ws2*SJo;Ol{u6c_y1?0_bA#H* z60~*M5B=TP#~=67$xM#D>=u;mK+Tq#ExT$UX<^dBR#|QVPQMEhCnZj5`fIlxPr@Be zXy~<4t3eE$A~(CZ??EqlDHjTV?#ri@V5E3Yw~O5?BZ8 zKpUVZJ!z)vGlh8SWJ@wpRk-@V#9GHXl67twZ=Y${&L)*q>cQGr8%lsY@@$7AF}+c0 z+D&&Y02~e2Wf;aFm(r1?V!$E&{LsGMgSBz~HAOCxJ}e?c z_Oa|%{NAbcjS$Rdf$#5=)KQ{jIsFUi3Q!p;XE#?MYwyNKyd0m}=97K?HbVKd}&|usz~X+z>oQ{vA~m&rAY2eGsC*5=H-vB4 z_n4EV)PL-%yZ^%5{ugm``MgJlxpndc9zctc9Eo?|!>`i;q z-okB2x%k*r(Dz=p`N|k>l=bbku52Dnhv>NIxT*)$Bzj1_T7NxJ%ftye9=(A_HVg3x z^VaZ5UbtK&!!*cyW_j#yW{`YL!oa|Hw7F)g4cYuYvupp@6$x} z{i)hRb=4L{Mqv@N@6O+yzdQdwdzPixCUL;CgyGVj`A;K9;(sRq)vNn!uKxYv)9&0y zO$uj-<{T#1=w8Z}oBu*UZ2xzQ%6G?i$N#lM8t!V51z$>lu|&!7e3j3aNs(34`oHyy Z|2LIBzHF35;S~S?002ovPDHLkV1l`Zhi?D? From 23d61335b6cf9c767983e135ebfa8bba3eef4222 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 13 Feb 2022 11:09:32 +0100 Subject: [PATCH 197/629] map - make zooming more granular --- .../src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index c8bda6d..f8108f0 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -56,7 +56,8 @@ fun createFactorioMap() = Maps { options.crs = CRS.Simple - options.zoomSnap = 0.1 + options.zoomSnap = 0 + options.zoomDelta = 0.1 } } From f821c2818362e79663b6995ee2bbacc70ffc57b2 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 13 Feb 2022 11:15:51 +0100 Subject: [PATCH 198/629] yan lock update --- gradle/kotlin-js-store/yarn.lock | 282 ++----------------------------- 1 file changed, 16 insertions(+), 266 deletions(-) diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index 9eaf61e..e85a1c8 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -108,12 +108,12 @@ dependencies: "@types/node" "*" -"@types/cookie@^0.4.0", "@types/cookie@^0.4.1": +"@types/cookie@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== -"@types/cors@^2.8.12", "@types/cors@^2.8.8": +"@types/cors@^2.8.12": version "2.8.12" resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== @@ -556,11 +556,6 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-arraybuffer@0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" - integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= - base64id@2.0.0, base64id@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" @@ -792,7 +787,7 @@ colorette@^2.0.10, colorette@^2.0.14: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== -colors@1.4.0, colors@^1.4.0: +colors@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== @@ -985,7 +980,7 @@ deep-equal@^1.0.1: object-keys "^1.1.1" regexp.prototype.flags "^1.2.0" -default-gateway@^6.0.0, default-gateway@^6.0.3: +default-gateway@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== @@ -1128,13 +1123,6 @@ encoding@^0.1.12: dependencies: iconv-lite "^0.6.2" -engine.io-parser@~4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-4.0.3.tgz#83d3a17acfd4226f19e721bb22a1ee8f7662d2f6" - integrity sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA== - dependencies: - base64-arraybuffer "0.1.4" - engine.io-parser@~5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.3.tgz#ca1f0d7b11e290b4bfda251803baea765ed89c09" @@ -1142,19 +1130,6 @@ engine.io-parser@~5.0.0: dependencies: "@socket.io/base64-arraybuffer" "~1.0.2" -engine.io@~4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-4.1.1.tgz#9a8f8a5ac5a5ea316183c489bf7f5b6cf91ace5b" - integrity sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w== - dependencies: - accepts "~1.3.4" - base64id "2.0.0" - cookie "~0.4.1" - cors "~2.8.5" - debug "~4.3.1" - engine.io-parser "~4.0.0" - ws "~7.4.2" - engine.io@~6.1.0: version "6.1.2" resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.1.2.tgz#e7b9d546d90c62246ffcba4d88594be980d3855a" @@ -1769,32 +1744,17 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -internal-ip@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-6.2.0.tgz#d5541e79716e406b74ac6b07b856ef18dc1621c1" - integrity sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg== - dependencies: - default-gateway "^6.0.0" - ipaddr.js "^1.9.1" - is-ip "^3.1.0" - p-event "^4.2.0" - interpret@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== -ip-regex@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" - integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== - ip@^1.1.0: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= -ipaddr.js@1.9.1, ipaddr.js@^1.9.1: +ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== @@ -1855,13 +1815,6 @@ is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-ip@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8" - integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q== - dependencies: - ip-regex "^4.0.0" - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -2041,35 +1994,6 @@ karma@6.3.12: ua-parser-js "^0.7.30" yargs "^16.1.1" -karma@6.3.4: - version "6.3.4" - resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.4.tgz#359899d3aab3d6b918ea0f57046fd2a6b68565e6" - integrity sha512-hbhRogUYIulfkBTZT7xoPrCYhRBnBoqbbL4fszWD0ReFGUxU+LYBr3dwKdAluaDQ/ynT9/7C+Lf7pPNW4gSx4Q== - dependencies: - body-parser "^1.19.0" - braces "^3.0.2" - chokidar "^3.5.1" - colors "^1.4.0" - connect "^3.7.0" - di "^0.0.1" - dom-serialize "^2.2.1" - glob "^7.1.7" - graceful-fs "^4.2.6" - http-proxy "^1.18.1" - isbinaryfile "^4.0.8" - lodash "^4.17.21" - log4js "^6.3.0" - mime "^2.5.2" - minimatch "^3.0.4" - qjobs "^1.2.0" - range-parser "^1.2.1" - rimraf "^3.0.2" - socket.io "^3.1.0" - source-map "^0.6.1" - tmp "^0.2.1" - ua-parser-js "^0.7.28" - yargs "^16.1.1" - kind-of@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" @@ -2140,13 +2064,6 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= -memfs@^3.2.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.0.tgz#8bc12062b973be6b295d4340595736a656f0a257" - integrity sha512-o/RfP0J1d03YwsAxyHxAYs2kyJp55AFkMazlFAZFR2I2IXkxiUTXRabJ6RmNNCQ83LAD2jy52Khj0m3OffpNdA== - dependencies: - fs-monkey "1.0.3" - memfs@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.1.tgz#b78092f466a0dce054d63d39275b24c71d3f1305" @@ -2346,11 +2263,6 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -node-forge@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" - integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== - node-forge@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.2.1.tgz#82794919071ef2eb5c509293325cec8afd0fd53c" @@ -2431,18 +2343,6 @@ open@^8.0.9: is-docker "^2.1.1" is-wsl "^2.2.0" -p-event@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" - integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== - dependencies: - p-timeout "^3.1.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -2486,13 +2386,6 @@ p-retry@^4.5.0: "@types/retry" "^0.12.0" retry "^0.13.1" -p-timeout@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" - integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== - dependencies: - p-finally "^1.0.0" - p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -2632,11 +2525,6 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -2652,11 +2540,6 @@ qs@6.9.6: resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -2848,13 +2731,6 @@ select-hose@^2.0.0: resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= -selfsigned@^1.10.11: - version "1.10.11" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.11.tgz#24929cd906fe0f44b6d01fb23999a739537acbe9" - integrity sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA== - dependencies: - node-forge "^0.10.0" - selfsigned@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.0.tgz#e927cd5377cbb0a1075302cff8df1042cc2bce5b" @@ -2962,17 +2838,12 @@ snabbdom@^3.3.1: resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.3.1.tgz#a2fb9a1c85cc19d6dc11c4c5e4c78cbbbaafff1f" integrity sha512-FR9u20dCkktPd+qbedqwYNjMXzYhizhqlKTQzYZimLNeCJY0/5qgs0DtLVSmzIEL1bN3Dyb9sQpiHGCxUjyLnQ== -socket.io-adapter@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz#edc5dc36602f2985918d631c1399215e97a1b527" - integrity sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg== - socket.io-adapter@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz#4d6111e4d42e9f7646e365b4f578269821f13486" integrity sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ== -socket.io-parser@~4.0.3, socket.io-parser@~4.0.4: +socket.io-parser@~4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0" integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g== @@ -2981,21 +2852,6 @@ socket.io-parser@~4.0.3, socket.io-parser@~4.0.4: component-emitter "~1.3.0" debug "~4.3.1" -socket.io@^3.1.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-3.1.2.tgz#06e27caa1c4fc9617547acfbb5da9bc1747da39a" - integrity sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw== - dependencies: - "@types/cookie" "^0.4.0" - "@types/cors" "^2.8.8" - "@types/node" ">=10.0.0" - accepts "~1.3.4" - base64id "~2.0.0" - debug "~4.3.1" - engine.io "~4.1.0" - socket.io-adapter "~2.1.0" - socket.io-parser "~4.0.3" - socket.io@^4.2.0: version "4.4.1" resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.4.1.tgz#cd6de29e277a161d176832bb24f64ee045c56ab8" @@ -3036,6 +2892,14 @@ source-map-loader@3.0.0: iconv-lite "^0.6.2" source-map-js "^0.6.2" +source-map-support@0.5.20: + version "0.5.20" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" + integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" @@ -3241,7 +3105,7 @@ typescript@3.9.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== -ua-parser-js@^0.7.28, ua-parser-js@^0.7.30: +ua-parser-js@^0.7.30: version "0.7.31" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== @@ -3263,14 +3127,6 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -3286,11 +3142,6 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -v8-compile-cache@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -3306,7 +3157,7 @@ void-elements@^2.0.0: resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= -watchpack@^2.2.0, watchpack@^2.3.1: +watchpack@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25" integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== @@ -3321,25 +3172,6 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" -webpack-cli@4.9.0: - version "4.9.0" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.0.tgz#dc43e6e0f80dd52e89cbf73d5294bcd7ad6eb343" - integrity sha512-n/jZZBMzVEl4PYIBs+auy2WI0WTQ74EnJDiyD98O2JZY6IVIHJNitkYp/uTXOviIOMfgzrNvC9foKv/8o8KSZw== - dependencies: - "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.1.0" - "@webpack-cli/info" "^1.4.0" - "@webpack-cli/serve" "^1.6.0" - colorette "^2.0.14" - commander "^7.0.0" - execa "^5.0.0" - fastest-levenshtein "^1.0.12" - import-local "^3.0.2" - interpret "^2.2.0" - rechoir "^0.7.0" - v8-compile-cache "^2.2.0" - webpack-merge "^5.7.3" - webpack-cli@4.9.1: version "4.9.1" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3" @@ -3358,17 +3190,6 @@ webpack-cli@4.9.1: rechoir "^0.7.0" webpack-merge "^5.7.3" -webpack-dev-middleware@^5.2.1: - version "5.3.0" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.0.tgz#8fc02dba6e72e1d373eca361623d84610f27be7c" - integrity sha512-MouJz+rXAm9B1OTOYaJnn6rtD/lWZPy2ufQCH3BPs8Rloh/Du6Jze4p7AeLYHkVi0giJnYLaSGDC7S+GM9arhg== - dependencies: - colorette "^2.0.10" - memfs "^3.2.2" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - webpack-dev-middleware@^5.3.0: version "5.3.1" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz#aa079a8dedd7e58bfeab358a9af7dab304cee57f" @@ -3380,37 +3201,6 @@ webpack-dev-middleware@^5.3.0: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.3.1.tgz#759d3337f0fbea297fbd1e433ab04ccfc000076b" - integrity sha512-qNXQCVYo1kYhH9pgLtm8LRNkXX3XzTfHSj/zqzaqYzGPca+Qjr+81wj1jgPMCHhIhso9WEQ+kX9z23iG9PzQ7w== - dependencies: - ansi-html-community "^0.0.8" - bonjour "^3.5.0" - chokidar "^3.5.1" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^1.6.0" - del "^6.0.0" - express "^4.17.1" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.0" - internal-ip "^6.2.0" - ipaddr.js "^2.0.1" - open "^8.0.9" - p-retry "^4.5.0" - portfinder "^1.0.28" - schema-utils "^3.1.0" - selfsigned "^1.10.11" - serve-index "^1.9.1" - sockjs "^0.3.21" - spdy "^4.0.2" - strip-ansi "^7.0.0" - url "^0.11.0" - webpack-dev-middleware "^5.2.1" - ws "^8.1.0" - webpack-dev-server@4.7.3: version "4.7.3" resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.7.3.tgz#4e995b141ff51fa499906eebc7906f6925d0beaa" @@ -3461,46 +3251,11 @@ webpack-merge@^5.7.3: clone-deep "^4.0.1" wildcard "^2.0.0" -webpack-sources@^3.2.0: - version "3.2.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" - integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== - webpack-sources@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.2.tgz#d88e3741833efec57c4c789b6010db9977545260" integrity sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw== -webpack@5.57.1: - version "5.57.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.57.1.tgz#ead5ace2c17ecef2ae8126f143bfeaa7f55eab44" - integrity sha512-kHszukYjTPVfCOEyrUthA3jqJwduY/P3eO8I0gMNOZGIQWKAwZftxmp5hq6paophvwo9NoUrcZOecs9ulOyyTg== - dependencies: - "@types/eslint-scope" "^3.7.0" - "@types/estree" "^0.0.50" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.4.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.8.3" - es-module-lexer "^0.9.0" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.4" - json-parse-better-errors "^1.0.2" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.1.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.2.0" - webpack-sources "^3.2.0" - webpack@5.66.0: version "5.66.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.66.0.tgz#789bf36287f407fc92b3e2d6f978ddff1bfc2dbb" @@ -3593,11 +3348,6 @@ ws@^8.1.0: resolved "https://registry.yarnpkg.com/ws/-/ws-8.4.0.tgz#f05e982a0a88c604080e8581576e2a063802bed6" integrity sha512-IHVsKe2pjajSUIl4KYMQOdlyliovpEPquKkqbwswulszzI7r0SfQrxnXdWAEqOlDCLrVSJzo+O1hAwdog2sKSQ== -ws@~7.4.2: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== - ws@~8.2.3: version "8.2.3" resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" From 0475d24bcf1b9bfbc762088aa8d6ef72282839e8 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 13 Feb 2022 12:00:59 +0100 Subject: [PATCH 199/629] maybe make 'updatePackageJson' task run properly when the project version changes? --- .../main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts index 4a03369..577b83c 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts @@ -4,7 +4,6 @@ import com.github.gradle.node.NodePlugin import com.github.gradle.node.npm.task.NpmInstallTask import dev.adamko.kafkatorio.Versions import dev.adamko.kafkatorio.gradle.areJsonPropertiesUpToDate -import dev.adamko.kafkatorio.gradle.not import dev.adamko.kafkatorio.jsonMapper import dev.adamko.kafkatorio.task.UpdatePackageJson import kotlinx.serialization.encodeToString @@ -33,7 +32,8 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) { propertiesToCheck.put("version", "${project.version}") // check to see if the properties are already up-to-date - onlyIf(!areJsonPropertiesUpToDate(packageJsonFile, propertiesToCheck)) + outputs.upToDateWhen(areJsonPropertiesUpToDate(packageJsonFile, propertiesToCheck)) +// onlyIf(!areJsonPropertiesUpToDate(packageJsonFile, propertiesToCheck)) doLast { val packageJsonContent = packageJsonFile.get().asFile.readText() From 6d6429ebac85b9333d509b7c857d5a99f9b48a02 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 13 Feb 2022 12:01:12 +0100 Subject: [PATCH 200/629] rename&move KafkatorioKafkaAdmin.kt --- .../admin/KafkatorioKafkaAdmin.kt} | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/{admin/CreateTopics.kt => processor/admin/KafkatorioKafkaAdmin.kt} (96%) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt similarity index 96% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt index 3f578e1..107c411 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/admin/CreateTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.admin +package dev.adamko.kafkatorio.processor.admin import dev.adamko.kafkatorio.events.schema.FactorioObjectData import dev.adamko.kafkatorio.events.schema.KafkatorioPacket @@ -11,10 +11,6 @@ import org.apache.kafka.clients.admin.NewTopic import org.apache.kafka.clients.admin.TopicListing -//fun main() { -// KafkaAdmin.createKafkatorioTopics() -//} - object KafkatorioKafkaAdmin { private val logger = KotlinLogging.logger {} From a518255027c43ea71e3ff4dc28e46838438f3246 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 13 Feb 2022 12:20:37 +0100 Subject: [PATCH 201/629] dependency and project version bumps --- build.gradle.kts | 2 +- .../src/main/typescript/package-lock.json | 14 +++++++------- .../events-mod/src/main/typescript/package.json | 6 +++--- modules/infra-factorio-server/src/.env | 2 +- modules/infra-kafka-cluster/src/.env | 2 +- modules/infra-kafka-pipe/src/.env | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9269694..a3f7c07 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.2.9" +version = "0.2.10" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index e5e5426..899c75e 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.9", + "version": "0.2.10", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -80,14 +80,14 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.17.0.tgz", - "integrity": "sha512-sFLQn+G/X0IROUBnlPwuIKQlvU561dckdI59WnRaClDRK1o8zyUEJRuJ4R+IJovKUd+I75xuoSdYVIWEwZoeHA==" + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.17.1.tgz", + "integrity": "sha512-YXKFOYEeUVkHCuwtwseXhA8V1aw33AYGCH7W5Yqb6K3eDg1V2hESSw0uCbANKMFigp9bqCiVg9kid3qf9cQlQw==" }, "typescript": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", - "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==" + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==" }, "typescript-to-lua": { "version": "1.3.3", diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index b29d3ca..4b9a5f7 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.9", + "version": "0.2.10", "private": true, "scripts": { "build": "tstl", @@ -14,8 +14,8 @@ "lua-types": "^2.11.0", "@types/node": "^12.0.8", "typescript-to-lua": "1.3.3", - "typed-factorio": "0.17.0", - "typescript": "4.5.4" + "typed-factorio": "0.17.1", + "typescript": "4.5.5" }, "license": "UNLICENSED", "peerDependencies": {}, diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index de3cc23..844cf24 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio FACTORIO_VERSION=1.1.53 -KAFKATORIO_VERSION=0.2.9 +KAFKATORIO_VERSION=0.2.10 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index c7501d2..7e3cb8d 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.2.9 +KAFKATORIO_VERSION=0.2.10 diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index c7501d2..7e3cb8d 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.2.9 +KAFKATORIO_VERSION=0.2.10 From d5a55b423d1c96269cb12a71cdb2b64f7f27fbb6 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 12:21:08 +0100 Subject: [PATCH 202/629] add some IntelliJ exclusions --- build.gradle.kts | 8 +++++++ buildSrc/settings.gradle.kts | 3 --- .../adamko/kafkatorio/gradle/extensions.kt | 21 +++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index a3f7c07..abd2597 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,5 @@ +import dev.adamko.kafkatorio.gradle.excludeGeneratedGradleDsl + plugins { idea base @@ -23,6 +25,12 @@ idea { module { isDownloadSources = true isDownloadJavadoc = true + excludeGeneratedGradleDsl(layout) + excludeDirs = excludeDirs + layout.files( + ".idea", + "gradle/kotlin-js-store", + "gradle/wrapper", + ) } } diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts index f5a0553..f19b951 100644 --- a/buildSrc/settings.gradle.kts +++ b/buildSrc/settings.gradle.kts @@ -1,6 +1,3 @@ - -rootProject.name = "buildSrc" - apply(from = "./repositories.settings.gradle.kts") @Suppress("UnstableApiUsage") // Central declaration of repositories is an incubating feature diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt index 7347c65..6969d30 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt @@ -6,10 +6,12 @@ import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive import org.gradle.api.Project import org.gradle.api.Task +import org.gradle.api.file.ProjectLayout import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.MapProperty import org.gradle.api.specs.Spec import org.gradle.kotlin.dsl.invoke +import org.gradle.plugins.ide.idea.model.IdeaModule operator fun Spec.not(): Spec = Spec { !this(it) } @@ -50,3 +52,22 @@ fun Project.areJsonPropertiesUpToDate( isUpToDate } } + + +/** exclude generated Gradle code, so it doesn't clog up search results */ +fun IdeaModule.excludeGeneratedGradleDsl(layout: ProjectLayout) { + excludeDirs.addAll( + layout.files( + "buildSrc/build/generated-sources/kotlin-dsl-accessors", + "buildSrc/build/generated-sources/kotlin-dsl-accessors/kotlin", + "buildSrc/build/generated-sources/kotlin-dsl-accessors/kotlin/gradle", + "buildSrc/build/generated-sources/kotlin-dsl-external-plugin-spec-builders", + "buildSrc/build/generated-sources/kotlin-dsl-external-plugin-spec-builders/kotlin", + "buildSrc/build/generated-sources/kotlin-dsl-external-plugin-spec-builders/kotlin/gradle", + "buildSrc/build/generated-sources/kotlin-dsl-plugins", + "buildSrc/build/generated-sources/kotlin-dsl-plugins/kotlin", + "buildSrc/build/generated-sources/kotlin-dsl-plugins/kotlin/dev", + "buildSrc/build/pluginUnderTestMetadata", + ) + ) +} From d3c7abff9507cc31b3c7af87c2d6b52962c8c5fd Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 12:21:46 +0100 Subject: [PATCH 203/629] rm unused class (moved to kotka-streams) --- .../processor/serdes/binaryFormat.kt | 50 ------------------- 1 file changed, 50 deletions(-) delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/binaryFormat.kt diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/binaryFormat.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/binaryFormat.kt deleted file mode 100644 index 180db50..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/binaryFormat.kt +++ /dev/null @@ -1,50 +0,0 @@ -package dev.adamko.kafkatorio.processor.serdes - -import kotlinx.serialization.BinaryFormat -import kotlinx.serialization.decodeFromByteArray -import kotlinx.serialization.encodeToByteArray -import org.apache.kafka.common.serialization.Deserializer -import org.apache.kafka.common.serialization.Serde -import org.apache.kafka.common.serialization.Serializer - -// -//inline fun BinaryFormat.kafkaSerializer() = -// Serializer { topic: String, data: T -> -// runCatching { -// encodeToByteArray(data) -// }.getOrElse { e -> -// println( -// """ -// Exception on encodeToString -// Topic: $topic -// topicData: $data -// topicData as T: $data -// """.trimIndent() -// ) -// e.printStackTrace() -// throw e -// } -// } -// -//inline fun BinaryFormat.kafkaDeserializer() = -// Deserializer { topic: String, data: ByteArray -> -// runCatching { -// decodeFromByteArray(data) -// }.getOrElse { e -> -// println( -// """ -// Exception on decodeFromString, -// Topic: $topic -// topicData: $data -// topicData as T: ${data as? T} -// """.trimIndent() -// ) -// e.printStackTrace() -// throw e -// } -// } -// -//inline fun BinaryFormat.serde() = object : Serde { -// override fun serializer(): Serializer = kafkaSerializer() -// override fun deserializer(): Deserializer = kafkaDeserializer() -//} From 727836a03115c02b864a36a1e8300dbf24fddf9e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 12:23:29 +0100 Subject: [PATCH 204/629] create TypeScriptToLua Gradle task, and some Gradle cleanup / experiments --- .../kafkatorio/task/TypescriptToLuaTask.kt | 43 ++++++ modules/events-mod/build.gradle.kts | 140 ++++++++---------- modules/events-schema/build.gradle.kts | 2 +- 3 files changed, 103 insertions(+), 82 deletions(-) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt new file mode 100644 index 0000000..3c6f797 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt @@ -0,0 +1,43 @@ +package dev.adamko.kafkatorio.task + +import com.github.gradle.node.npm.task.NpmTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.plugins.BasePlugin +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.api.tasks.SkipWhenEmpty +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + +abstract class TypescriptToLuaTask : NpmTask() { + + @get:InputDirectory + @get:SkipWhenEmpty + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val sourceFiles: DirectoryProperty + + @get:OutputFile + abstract val outputDirectory: DirectoryProperty + + + init { + super.setGroup(BasePlugin.BUILD_GROUP) + super.setDescription("Convert Typescript To Lua") + super.execOverrides { standardOutput = System.out } + super.npmCommand.set(listOf("run", "build")) + super.args.set(parseSpaceSeparatedArgs("-- --outDir $temporaryDir")) + super.ignoreExitValue.set(false) + super.doFirst("cleanTemporaryDir") { + project.delete(temporaryDir) + project.mkdir(temporaryDir) + } + super.doLast("syncTstlOutput") { + project.sync { + from(temporaryDir) + into(outputDirectory) + } + } + } + +} diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 8c942d5..73e8687 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -1,12 +1,10 @@ -import com.github.gradle.node.npm.task.NpmTask import dev.adamko.kafkatorio.gradle.asConsumer import dev.adamko.kafkatorio.gradle.asProvider import dev.adamko.kafkatorio.gradle.factorioModAttributes import dev.adamko.kafkatorio.gradle.typescriptAttributes -import groovy.json.JsonOutput +import dev.adamko.kafkatorio.task.TypescriptToLuaTask import net.swiftzer.semver.SemVer import org.apache.tools.ant.filters.ReplaceTokens -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { dev.adamko.kafkatorio.lang.node @@ -47,6 +45,7 @@ node { } val typescriptEventsSchema: Configuration by configurations.creating { + description = "Fetch the TypeScript schema from the event-schema subproject" asConsumer() typescriptAttributes(objects) } @@ -55,39 +54,11 @@ dependencies { typescriptEventsSchema(projects.modules.eventsSchema) } -val typescriptToLua by tasks.registering(NpmTask::class) { - description = "Convert Typescript To Lua" - group = project.name - +val typescriptToLua by tasks.registering(TypescriptToLuaTask::class) { dependsOn(tasks.npmInstall, installEventsTsSchema, tasks.updatePackageJson) - execOverrides { standardOutput = System.out } - - npmCommand.set(listOf("run", "build")) - - inputs.dir(tsSrcDir) - .skipWhenEmpty() - .withPropertyName("sourceFiles") - .withPathSensitivity(PathSensitivity.RELATIVE) - - args.set(parseSpaceSeparatedArgs("-- --outDir $temporaryDir")) - val outputDir = layout.buildDirectory.dir("typescriptToLua") - outputs.dir(outputDir) - .withPropertyName("outputDir") - - ignoreExitValue.set(false) - - doFirst("clean") { - delete(temporaryDir) - mkdir(temporaryDir) - } - - doLast("syncTstlOutput") { - sync { - from(temporaryDir) - into(outputDir) - } - } + sourceFiles.set(tsSrcDir) + outputDirectory.set(layout.buildDirectory.dir("typescriptToLua")) } val installEventsTsSchema by tasks.registering(Sync::class) { @@ -133,7 +104,7 @@ distributions { include("**/**") } from(licenseFile) - from(typescriptToLua.map { it.outputs }) + from(typescriptToLua.map { it.outputDirectory }) filesNotMatching("**/*.png") { filter("tokens" to projectTokens) } @@ -149,34 +120,34 @@ distributions { } } -val downloadFactorioApiDocs by tasks.registering { - group = project.name - - val target = uri("https://lua-api.factorio.com/latest/runtime-api.json") - val apiFilename = File(target.path).name - val downloadedFile = file("$temporaryDir/$apiFilename") - - val apiFile = layout.buildDirectory.file(apiFilename) - outputs.file(apiFile) - - doLast { - - ant.invokeMethod( - "get", mapOf( - "src" to target, - "dest" to downloadedFile, - "verbose" to true, - ) - ) - - val json = downloadedFile.readText() - val prettyJson = JsonOutput.prettyPrint(json) - - apiFile.get().asFile.writeText(prettyJson) - - logger.lifecycle("Downloaded Factorio API json: $apiFile") - } -} +//val downloadFactorioApiDocs by tasks.registering { +// group = project.name +// +// val target = uri("https://lua-api.factorio.com/latest/runtime-api.json") +// val apiFilename = File(target.path).name +// val downloadedFile = file("$temporaryDir/$apiFilename") +// +// val apiFile = layout.buildDirectory.file(apiFilename) +// outputs.file(apiFile) +// +// doLast { +// +// ant.invokeMethod( +// "get", mapOf( +// "src" to target, +// "dest" to downloadedFile, +// "verbose" to true, +// ) +// ) +// +// val json = downloadedFile.readText() +// val prettyJson = JsonOutput.prettyPrint(json) +// +// apiFile.get().asFile.writeText(prettyJson) +// +// logger.lifecycle("Downloaded Factorio API json: $apiFile") +// } +//} val factorioModProvider by configurations.registering { asProvider() @@ -191,27 +162,34 @@ tasks.updatePackageJson { tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) } -// -//idea { -// // this doesn't work - no source sets? -// module { -// sourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript").asFile)) -// excludeDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript/node_modules").asFile)) -// resourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/resources").asFile)) -// resourceDirs.add(mkdir(layout.projectDirectory.dir("infra").asFile)) -// excludeDirs.add(mkdir(layout.projectDirectory.dir("infra/factorio-server").asFile)) -// } + +// trying to get Gradle+idea to recognise the ts-src... + +//val typescriptSrcSet = project.objects.sourceDirectorySet("typescript", "TypeScript").apply { +// srcDirs(tsSrcDir) +// compiledBy(typescriptToLua, TypescriptToLuaTask::outputDirectory) +//// destinationDirectory.set(layout.buildDirectory.dir("typescriptToLua")) //} // -//val typescriptSrcSet = -// project.objects.sourceDirectorySet("typescript", "typescript").apply { -// srcDir(layout.projectDirectory.dir("src/main/typescript")) +//val tsSrcConfiguration by configurations.registering { +// asProvider() +// outgoing.artifact(tsSrcDir) +//} // -// destinationDirectory.set(modBuildDir.dir("typescriptToLua").asFile) -// compiledBy(tstlTask) { -// -// project.objects.directoryProperty().apply { -// set(modBuildDir.dir("typescriptToLua")) +//idea { +// module { +// // Not using += due to https://github.com/gradle/gradle/issues/8749 +// sourceDirs = sourceDirs + typescriptSrcSet.sourceDirectories +// resourceDirs.add(file("src/main/resources")) +// excludeDirs.add(layout.projectDirectory.dir("src/main/typescript/node_modules").asFile) +// scopes.compute("MAIN") { _: String, scope: MutableMap>? -> +// val s = (scope ?: mutableMapOf()) +// s.compute("plus") { _, conf -> +// val c = conf ?: mutableListOf() +// c.add(tsSrcConfiguration.get()) +// c // } +// s // } // } +//} diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index fe9d531..178a5ce 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -96,7 +96,7 @@ kotlin { val generateTypescript by tasks.registering(JavaExec::class) { - group = project.name + group = "kt2ts" val jvmJar by tasks.getting(Jar::class) val main by kotlin.jvm().compilations.getting From e989d25a3c4987b7ddd3e119962b5bb7f29beaa1 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 12:24:24 +0100 Subject: [PATCH 205/629] mucking about with updating kotlin 1.6.20 --- buildSrc/build.gradle.kts | 2 ++ buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt | 2 +- .../kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts | 1 + gradle/libs.versions.toml | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 2d4696c..91135ae 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -11,6 +11,7 @@ plugins { object Versions { const val jvmTarget = "11" const val kotlinTarget = "1.6" +// const val kotlin = "1.6.20-M1" const val kotlin = "1.6.10" const val gradleNodePlugin = "3.2.0" @@ -66,6 +67,7 @@ tasks.withType().configureEach { } kotlinOptions.freeCompilerArgs += listOf( +// "-Xcontext-receivers", "-opt-in=kotlin.RequiresOptIn", "-opt-in=kotlin.ExperimentalStdlibApi", "-opt-in=kotlin.time.ExperimentalTime", diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt index 11e6b2b..63aa77a 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt @@ -18,7 +18,7 @@ object Versions { const val node = "14.19.0" - const val kotlinWrappers = "0.0.1-pre.294-kotlin-1.6.10" + const val kotlinWrappers = "0.0.1-pre.300-kotlin-1.6.10" const val junit = "5.8.2" const val kotest = "5.1.0" const val mockk = "1.12.1" diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index 342a119..4228ba7 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -43,6 +43,7 @@ tasks.withType().configureEach { } kotlinOptions.freeCompilerArgs += listOf( +// "-Xcontext-receivers", "-opt-in=kotlin.RequiresOptIn", "-opt-in=kotlin.ExperimentalStdlibApi", "-opt-in=kotlin.time.ExperimentalTime", diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bd0d438..1295f7c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,6 +6,7 @@ ## compilation ## jvm = "11" +#kotlin = "1.6.20-M1" kotlin = "1.6.10" ## libs ## From 8f9ebdb1e1d8194ad6b7494a5441cbcf407f7187 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 12:29:34 +0100 Subject: [PATCH 206/629] update events schema - unwrap value classes when generating TS - add value classes for some data types - add FactorioEventUpdates (for new incremental event updates) - use static lists for enum values (better performance) - add LuaControl for sharing Player/Entity fields --- .../kafkatorio-schema/object-data.d.ts | 26 +--- .../kafkatorio-schema/prototype.d.ts | 2 +- .../generated/kafkatorio-schema/schema.d.ts | 89 ++++++++++++- .../events/schema/factorioCommonData.kt | 13 +- .../events/schema/factorioEventUpdates.kt | 124 ++++++++++++++++++ .../events/schema/factorioEvents.kt | 2 +- .../kafkatorio/events/schema/factorioIds.kt | 36 +++++ .../events/schema/factorioLuaObjects.kt | 56 +++++--- .../events/schema/factorioPrototypes.kt | 9 +- .../events/schema/kafkatorioPacket.kt | 7 +- .../events/schema/FactorioEventTest.kt | 23 ++-- .../events/schema/ValueClassTransformer.kt | 67 ++++++++++ .../adamko/kafkatorio/events/schema/kt2ts.kt | 9 +- 13 files changed, 396 insertions(+), 67 deletions(-) create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioIds.kt create mode 100644 modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts index 4585cfa..9313d83 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts @@ -6,30 +6,6 @@ interface FactorioObjectData { objectName: ObjectName; } -interface PlayerData extends FactorioObjectData { - associatedCharactersUnitNumbers: uint[]; - characterUnitNumber: uint | null; - chatColour: Colour; - colour: Colour; - lastOnline: uint; - name: string; - objectName: ObjectName; - position: MapEntityPosition; -} - -interface EntityData extends FactorioObjectData { - active: boolean; - health: double | null; - healthRatio: double; - name: string; - objectName: ObjectName; - playerIndex: uint | null; - position: MapEntityPosition; - surfaceIndex: int; - type: string; - unitNumber: uint | null; -} - interface SurfaceData extends FactorioObjectData { daytime: double; index: uint; @@ -39,7 +15,7 @@ interface SurfaceData extends FactorioObjectData { interface MapTiles extends FactorioObjectData { objectName: ObjectName; - surfaceIndex: int; + surfaceIndex: uint; tiles: MapTile[]; } diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts index 01d4958..9021c35 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts @@ -15,7 +15,7 @@ interface FactorioPrototypes extends KafkatorioPacket { interface MapTilePrototype extends FactorioPrototype { canBeMined: boolean; collisionMasks: string[]; - layer: uint; + layer: int; mapColour: Colour; name: string; order: string; diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts index f1caf5a..3ba828d 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts @@ -15,6 +15,17 @@ interface FactorioEvent extends KafkatorioPacket { tick: uint; } +interface MapEntityPosition { + x: double; + y: double; +} + +interface FactorioLuaControl { + force: uint; + position: MapEntityPosition; + surface: uint; +} + interface Colour { alpha: float; blue: float; @@ -22,9 +33,31 @@ interface Colour { red: float; } -interface MapEntityPosition { - x: double; - y: double; +interface PlayerData extends FactorioObjectData, FactorioLuaControl { + associatedCharactersUnitNumbers: uint[]; + characterUnitNumber: uint | null; + chatColour: Colour; + colour: Colour; + force: uint; + lastOnline: uint; + name: string; + objectName: ObjectName; + position: MapEntityPosition; + surface: uint; +} + +interface EntityData extends FactorioObjectData, FactorioLuaControl { + active: boolean; + force: uint; + health: double | null; + healthRatio: double; + name: string; + objectName: ObjectName; + playerIndex: uint | null; + position: MapEntityPosition; + surface: uint; + type: string; + unitNumber: uint | null; } interface MapTilePosition { @@ -46,3 +79,53 @@ interface MapTile { position: MapTilePosition; prototypeName: string; } + +type FactorioEventUpdateType = "PLAYER" | "MAP_CHUNK" | "ENTITY"; + +interface FactorioEventUpdate { + updateType: FactorioEventUpdateType; +} + +interface PlayerUpdate extends FactorioEventUpdate { + characterUnitNumber: uint | null; + chatColour: Colour | null; + colour: Colour | null; + disconnectReason: string | null; + forceIndex: uint | null; + index: uint; + isAdmin: boolean | null; + isConnected: boolean | null; + isShowOnMap: boolean | null; + isSpectator: boolean | null; + lastOnline: uint | null; + name: string | null; + onlineTime: uint | null; + position: MapEntityPosition | null; + surfaceIndex: uint | null; + tag: string | null; + updateType: FactorioEventUpdateType; +} + +interface EntityUpdate extends FactorioEventUpdate { + chunkPosition: MapChunkPosition | null; + graphicsVariation: number | null; + health: float | null; + isActive: boolean | null; + isRotatable: boolean | null; + lastUser: int | null; + localisedDescription: string | null; + localisedName: string | null; + name: string | null; + prototype: string | null; + type: string | null; + unitNumber: uint; + updateType: FactorioEventUpdateType; +} + +interface MapChunkUpdate extends FactorioEventUpdate { + chunkPosition: MapChunkPosition; + isDeleted: boolean | null; + surfaceIndex: uint; + tiles: MapTiles | null; + updateType: FactorioEventUpdateType; +} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index f08eb79..f5cdf9c 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -1,11 +1,18 @@ package dev.adamko.kafkatorio.events.schema +import kotlin.jvm.JvmInline import kotlinx.serialization.EncodeDefault import kotlinx.serialization.Serializable const val MAP_CHUNK_SIZE = 32 + +@Serializable +@JvmInline +value class Tick(val value: UInt) + + /** * Coordinates of a [EntityData] on a map. * @@ -60,7 +67,7 @@ data class MapBoundingBox( */ @Serializable data class Colour( - @EncodeDefault + @EncodeDefault // remove encode default? val red: Float = 0f, @EncodeDefault val green: Float = 0f, @@ -74,7 +81,7 @@ data class Colour( /** Size-efficient version of [Colour] (`4*4` bytes vs `4*1` bytes) */ @Serializable data class ColourHex( - @EncodeDefault + @EncodeDefault // remove encode default? val red: UByte = UByte.MIN_VALUE, @EncodeDefault val green: UByte = UByte.MIN_VALUE, @@ -91,6 +98,6 @@ data class ColourHex( @Serializable data class MapTile( - val prototypeName: String, + val prototypeName: PrototypeName, val position: MapTilePosition, ) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt new file mode 100644 index 0000000..a109ca7 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt @@ -0,0 +1,124 @@ +package dev.adamko.kafkatorio.events.schema + +import kotlinx.serialization.DeserializationStrategy +import kotlinx.serialization.EncodeDefault +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonContentPolymorphicSerializer +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.contentOrNull +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive + + +@Serializable(with = FactorioEventUpdate.Companion.JsonSerializer::class) +sealed class FactorioEventUpdate { + + @EncodeDefault + abstract val updateType: FactorioEventUpdateType + + @Serializable + enum class FactorioEventUpdateType { + PLAYER, + MAP_CHUNK, + ENTITY, + ; + + companion object { + val values: List = values().toList() + } + } + + companion object { + + object JsonSerializer : JsonContentPolymorphicSerializer( + FactorioEventUpdate::class + ) { + private val key = FactorioEventUpdate::updateType.name + + override fun selectDeserializer(element: JsonElement): DeserializationStrategy { + + val type = element + .jsonObject[key] + ?.jsonPrimitive + ?.contentOrNull + ?.let { json -> + FactorioEventUpdateType.values.firstOrNull { it.name == json } + } + + requireNotNull(type) { "Unknown FactorioEventUpdate $key: $element" } + + return when (type) { + FactorioEventUpdateType.PLAYER -> PlayerUpdate.serializer() + FactorioEventUpdateType.MAP_CHUNK -> TODO() + FactorioEventUpdateType.ENTITY -> EntityUpdate.serializer() + } + } + } + + } +} + + +@Serializable +data class PlayerUpdate( + val index: PlayerIndex, + + val characterUnitNumber: UnitNumber? = null, + val chatColour: Colour? = null, + val colour: Colour? = null, + val name: String? = null, + + val disconnectReason: String? = null, + val forceIndex: ForceIndex? = null, + val isAdmin: Boolean? = null, + val isConnected: Boolean? = null, + val isShowOnMap: Boolean? = null, + val isSpectator: Boolean? = null, + val lastOnline: Tick? = null, + val onlineTime: Tick? = null, + val position: MapEntityPosition? = null, + val surfaceIndex: SurfaceIndex? = null, + val tag: String? = null, +) : FactorioEventUpdate() { + @EncodeDefault + override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.PLAYER +} + + +@Serializable +data class EntityUpdate( + /** + * A [unitNumber] is required for caching, else the Entity Update should be emitted without + * debouncing/throttling + */ + val unitNumber: UnitNumber, + + val name: String? = null, + val type: String? = null, + val chunkPosition: MapChunkPosition? = null, + val graphicsVariation: UShort? = null, + val health: Float? = null, + val isActive: Boolean? = null, + val isRotatable: Boolean? = null, + val lastUser: UInt? = null, + val localisedDescription: String? = null, + val localisedName: String? = null, + val prototype: PrototypeName? = null, +) : FactorioEventUpdate() { + @EncodeDefault + override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.ENTITY +} + + +@Serializable +data class MapChunkUpdate( + val chunkPosition: MapChunkPosition, + val surfaceIndex: SurfaceIndex, + + /** Might be a partial list of updated tiles */ + val tiles: MapTiles? = null, + val isDeleted: Boolean? = null, +) : FactorioEventUpdate() { + @EncodeDefault + override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.MAP_CHUNK +} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index 9477af1..0cb882e 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -10,7 +10,7 @@ data class FactorioEvent( /** the initial Factorio event (`defines.events`) trigger */ val eventType: String, /** game time */ - val tick: UInt, + val tick: Tick, val data: FactorioObjectData, ) : KafkatorioPacket() { @EncodeDefault diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioIds.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioIds.kt new file mode 100644 index 0000000..525ada3 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioIds.kt @@ -0,0 +1,36 @@ +package dev.adamko.kafkatorio.events.schema + +import kotlin.jvm.JvmInline +import kotlinx.serialization.Serializable + + +/** + * Unique ID associated with this surface + * + * See [`LuaSurface.index`](https://lua-api.factorio.com/latest/LuaSurface.html#LuaSurface.index) + */ +@Serializable +@JvmInline +value class SurfaceIndex(val value: UInt) + + +@Serializable +@JvmInline +value class ForceIndex(val value: UInt) + + +/** The player's index in `LuaGameScript::players` */ +@Serializable +@JvmInline +value class PlayerIndex(val value: UInt) + + +/** This is universally unique for every entity that has one, for the lifetime of a whole game. */ +@Serializable +@JvmInline +value class UnitNumber(val value: UInt) + + +@Serializable +@JvmInline +value class PrototypeName(val value: String) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt index b6e2d09..796914d 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -10,6 +10,7 @@ import kotlinx.serialization.json.contentOrNull import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive + @Serializable(with = FactorioObjectDataJsonSerializer::class) sealed class FactorioObjectData { @@ -41,9 +42,15 @@ sealed class FactorioObjectData { // LuaTile, LuaTiles, ConsoleChatMessage, + ; + + companion object { + val values: List = values().toList() + } } } + object FactorioObjectDataJsonSerializer : JsonContentPolymorphicSerializer( FactorioObjectData::class ) { @@ -56,7 +63,7 @@ object FactorioObjectDataJsonSerializer : JsonContentPolymorphicSerializer - FactorioObjectData.ObjectName.values().firstOrNull { it.name == json } + FactorioObjectData.ObjectName.values.firstOrNull { it.name == json } } requireNotNull(type) { "Unknown FactorioObjectData $key: $element" } @@ -74,48 +81,61 @@ object FactorioObjectDataJsonSerializer : JsonContentPolymorphicSerializer, - val characterUnitNumber: UInt?, - val name: String, - val position: MapEntityPosition, - val colour: Colour, + val associatedCharactersUnitNumbers: List, + val characterUnitNumber: UnitNumber?, val chatColour: Colour, - val lastOnline: UInt, -) : FactorioObjectData() { + val colour: Colour, + val lastOnline: Tick, + val name: String, +) : FactorioObjectData(), FactorioLuaControl { @EncodeDefault override val objectName = ObjectName.LuaPlayer } + @Serializable data class EntityData( + override val force: ForceIndex, + override val position: MapEntityPosition, + override val surface: SurfaceIndex, val active: Boolean, val health: Double?, val healthRatio: Double, val name: String, - val position: MapEntityPosition, - val surfaceIndex: Int, + val playerIndex: PlayerIndex? = null, val type: String, - val unitNumber: UInt? = null, - val playerIndex: UInt? = null, -) : FactorioObjectData() { + val unitNumber: UnitNumber? = null, +) : FactorioObjectData(), FactorioLuaControl { @EncodeDefault override val objectName = ObjectName.LuaEntity } + @Serializable data class SurfaceData( val daytime: Double, - val index: UInt, + val index: SurfaceIndex, val name: String, ) : FactorioObjectData() { @EncodeDefault override val objectName = ObjectName.LuaSurface } + /** This isn't a Factorio Lua type, but a helpful collection of Chunk info */ @Serializable data class MapChunk( @@ -127,19 +147,21 @@ data class MapChunk( override val objectName = ObjectName.MapChunk } + /** This isn't a Factorio Lua type, but a helpful collection of [MapTile]s */ @Serializable data class MapTiles( - val surfaceIndex: Int, + val surfaceIndex: SurfaceIndex, val tiles: List, ) : FactorioObjectData() { @EncodeDefault override val objectName = ObjectName.LuaTiles } + @Serializable data class ConsoleChatMessage( - val authorPlayerIndex: UInt?, + val authorPlayerIndex: PlayerIndex?, val content: String, ) : FactorioObjectData() { @EncodeDefault diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt index 8fc42ea..0cce79d 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt @@ -28,7 +28,12 @@ sealed class FactorioPrototype { abstract val prototypeObjectName: PrototypeObjectName enum class PrototypeObjectName { - LuaTilePrototype + LuaTilePrototype, + ; + + companion object { + val values: List = values().toList() + } } } @@ -45,7 +50,7 @@ object FactorioPrototypeJsonSerializer : JsonContentPolymorphicSerializer - PrototypeObjectName.values().firstOrNull { it.name == json } + PrototypeObjectName.values.firstOrNull { it.name == json } } requireNotNull(type) { "Unknown FactorioPrototype ${key}: $element" } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt index cb98d95..fd59bc2 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt @@ -21,6 +21,11 @@ sealed class KafkatorioPacket { EVENT, CONFIG, PROTOTYPES, + ; + + companion object { + val values: List = values().toList() + } } } @@ -37,7 +42,7 @@ object KafkatorioPacketJsonSerializer : JsonContentPolymorphicSerializer - KafkatorioPacket.PacketType.values().firstOrNull { it.name == json } + KafkatorioPacket.PacketType.values.firstOrNull { it.name == json } } requireNotNull(type) { "Unknown KafkatorioPacket ${key}: $element" } diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt index ce7c8a8..400b8bf 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt @@ -50,7 +50,9 @@ class FactorioEventTest : FunSpec({ val expected = FactorioEvent( data = PlayerData( name = "fredthedeadhead", - characterUnitNumber = 1u, + surface = SurfaceIndex(1u), + force = ForceIndex(1u), + characterUnitNumber = UnitNumber(1u), associatedCharactersUnitNumbers = emptyList(), position = MapEntityPosition( x = 30.6, @@ -68,11 +70,11 @@ class FactorioEventTest : FunSpec({ blue = 0.25f, alpha = 1f ), - lastOnline = 2287061u + lastOnline = Tick(2287061u) ), eventType = "on_player_joined_game", modVersion = "0.2.1", - tick = 2287072u + tick = Tick(2287072u) ) actual shouldBe expected @@ -112,12 +114,12 @@ class FactorioEventTest : FunSpec({ val expected = FactorioEvent( data = SurfaceData( name = "nauvis", - index = 1u, + index = SurfaceIndex(1u), daytime = 0.745 ), eventType = "on_tick", modVersion = "0.2.1", - tick = 2301240u + tick = Tick(2301240u) ) actual shouldBe expected @@ -168,8 +170,9 @@ class FactorioEventTest : FunSpec({ active = true, health = 250.0, healthRatio = 1.0, - surfaceIndex = 1, - unitNumber = 1u, + surface = SurfaceIndex(1u), + unitNumber = UnitNumber(1u), + force = ForceIndex(1u), playerIndex = null, position = MapEntityPosition( x = 37.5, @@ -178,7 +181,7 @@ class FactorioEventTest : FunSpec({ ), eventType = "on_player_changed_position", modVersion = "0.2.1", - tick = 2301231u + tick = Tick(2301231u) ) actual shouldBe expected @@ -245,7 +248,7 @@ class FactorioEventTest : FunSpec({ val expected = FactorioEvent( data = MapTiles( - surfaceIndex = 1, + surfaceIndex = SurfaceIndex(1u), tiles = listOf( MapTile( prototypeName = "refined-concrete", @@ -267,7 +270,7 @@ class FactorioEventTest : FunSpec({ ), eventType = "on_player_built_tile", modVersion = "0.2.2", - tick = 2429929u + tick = Tick(2429929u) ) actual shouldBe expected diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt new file mode 100644 index 0000000..bdc9747 --- /dev/null +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt @@ -0,0 +1,67 @@ +package dev.adamko.kafkatorio.events.schema + +import kotlin.reflect.KClass +import kotlin.reflect.KProperty +import kotlin.reflect.KType +import kotlin.reflect.KTypeProjection +import kotlin.reflect.full.createType +import kotlin.reflect.full.declaredMemberProperties +import kotlin.reflect.full.withNullability +import me.ntrrgc.tsGenerator.ClassTransformer + +/** + * 'Unwrap' value classes + */ +object ValueClassTransformer : ClassTransformer { + + override fun transformPropertyType(type: KType, property: KProperty<*>, klass: KClass<*>): KType { + + val classifier = type.classifier ?: return super.transformPropertyType(type, property, klass) + + val valueClassType = unwrapValueClassType(type) + + if (valueClassType != null) { + println("$klass has a value class $type -> $valueClassType") + return valueClassType + } + + val hasValueClassTypeParameters = type.arguments + .mapNotNull { it.type?.classifier } + .filterIsInstance>() + .any { it.isValue } + + if (hasValueClassTypeParameters) { + + val args = type.arguments.map { arg -> + when (val vct = unwrapValueClassType(arg.type)) { + null -> arg + else -> KTypeProjection(arg.variance, vct.withNullability(arg.type!!.isMarkedNullable)) + } + } + + println("$klass has a prop with value class type parameters ${type.arguments} -> $args") + + return classifier.createType( + arguments = args, + nullable = type.isMarkedNullable, + annotations = type.annotations, + ) + } + + return super.transformPropertyType(type, property, klass) + } + + private fun unwrapValueClassType(type: KType?): KType? { + val klass = type?.classifier as? KClass<*> ?: return null + + return when { + klass.isValue -> klass + .declaredMemberProperties + .first() + .returnType + .withNullability(type.isMarkedNullable) + + else -> null + } + } +} diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt index 705b607..6d6e492 100644 --- a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt @@ -18,6 +18,7 @@ fun main(args: Array) { addAll(FactorioPrototype::class.sealedSubclasses) add(FactorioPrototypes::class) add(FactorioConfigurationUpdate::class) + addAll(FactorioEventUpdate::class.sealedSubclasses) }, mappings = mapOf( // builtin Factorio numeric types > `typed-factorio/generated/builtin-types.d.ts` @@ -31,16 +32,16 @@ fun main(args: Array) { ULong::class to "uint64", ), classTransformers = listOf( + ValueClassTransformer, // PropertyNameTransformer, - ) + ), +// voidType = VoidType.UNDEFINED, ) val definitions = gen.definitionsText when (val filename = args.firstOrNull()) { - null -> { - println(definitions) - } + null -> println(definitions) else -> { val outPath = Path(filename) outPath.createDirectories() From 254c6003092cd724ea2a7350a0c5a5f99097ed74 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 12:30:08 +0100 Subject: [PATCH 207/629] use static enum values, not values() (better performance) --- .../adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt index 107c411..2fdc3d4 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt @@ -28,14 +28,14 @@ object KafkatorioKafkaAdmin { val currentTopics = currentTopics().map { it.name() } val kafkatorioTopics = buildSet { - KafkatorioPacket.PacketType.values().forEach { packetType -> + KafkatorioPacket.PacketType.values.forEach { packetType -> add(KafkatorioTopology.TOPIC_GROUPED_MAP_CHUNKS) add(KafkatorioTopology.TOPIC_SRC_SERVER_LOG) when (packetType) { KafkatorioPacket.PacketType.EVENT -> - FactorioObjectData.ObjectName.values().forEach { objectName -> + FactorioObjectData.ObjectName.values.forEach { objectName -> add("kafkatorio.${packetType.name}.${objectName.name}") } KafkatorioPacket.PacketType.CONFIG -> From e1a33286c1443f80386baab80c840b2bb95293d5 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 12:30:22 +0100 Subject: [PATCH 208/629] more IntelliJ exclusions --- modules/infra-factorio-server/build.gradle.kts | 7 +++++++ modules/infra-kafka-connect/build.gradle.kts | 10 ++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 392f15c..7f7254c 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -50,3 +50,10 @@ tasks.dockerEnv { } tasks.build { dependsOn(deployModToServer) } + + +idea { + module { + excludeDirs.add(file("src/factorio-server")) + } +} diff --git a/modules/infra-kafka-connect/build.gradle.kts b/modules/infra-kafka-connect/build.gradle.kts index eb1820c..7e4acff 100644 --- a/modules/infra-kafka-connect/build.gradle.kts +++ b/modules/infra-kafka-connect/build.gradle.kts @@ -79,8 +79,8 @@ val downloadCamelConnectors by tasks.registering(Sync::class) { fileTree(temporaryDir) .asFileTree .forEach { zip -> - from(tarTree(zip)) - } + from(tarTree(zip)) + } into(connectorJarDir) } } @@ -101,3 +101,9 @@ tasks.dockerEnv { "KAFKA_CONNECT_VERSION" to libs.versions.confluent.kafkaConnect.get(), ) } + +idea { + module { + excludeDirs.add(file("src/main/docker/camel-kafka-connectors")) + } +} From e12e98ee713c5638eecf650b19d54f41dea31f8f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 12:30:45 +0100 Subject: [PATCH 209/629] update readme overview --- README.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 8b73398..deb2e88 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ +# Kafkatorio + 1. output events from Factorio into Kafka. - 1. Factorio mod listens to events. - 2. For each event, it emits a file. - 3. A Kafka Connector consumes each file. -2. Factorio Web Map reads data from Kafka - 1. converts data to images + 1. Factorio mod listens to events https://mods.factorio.com/mod/kafkatorio-events + 2. For each event, it emits a log message + 3. A tool (e.g. Kafkatorio Kafka Pipe) reads the logs, and sends the messages to a Kafka cluster +2. Kafkatorio Events Server reads the messages from Kafka + 1. create images of the map 2. hosts a web map ## License @@ -66,8 +68,9 @@ https://www.npmjs.com/package/wasm2lua?activeTab=readme * https://www.zash.se/lua-cbor.html * https://code.zash.se/lua-cbor/archive/68b3a36d0816.tar.gz -* BSON - * https://github.com/mpaland/bsonfy - * https://github.com/tcoram/bson-lua +* BSON + * https://github.com/mpaland/bsonfy + * https://github.com/tcoram/bson-lua -* bebop https://rainway.com/blog/2020/12/09/bebop-an-efficient-schema-based-binary-serialization-format/ +* bebop + https://rainway.com/blog/2020/12/09/bebop-an-efficient-schema-based-binary-serialization-format/ From cecafedd78e5278af1c37847e0e889751941d8e0 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 12:31:06 +0100 Subject: [PATCH 210/629] bump typed-factorio version, and add some more TS strictness --- .../src/main/typescript/package-lock.json | 6 +++--- .../events-mod/src/main/typescript/package.json | 14 +++++++++----- .../events-mod/src/main/typescript/tsconfig.json | 5 ++++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index 899c75e..b901f4a 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -80,9 +80,9 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.17.1.tgz", - "integrity": "sha512-YXKFOYEeUVkHCuwtwseXhA8V1aw33AYGCH7W5Yqb6K3eDg1V2hESSw0uCbANKMFigp9bqCiVg9kid3qf9cQlQw==" + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.18.1.tgz", + "integrity": "sha512-osjGO4V809tlDnDI7lXTIOPCcDBwBfKfW6o8zFR04S0/uBAzP4eY3X3GXTPzWK/P3HJ9GXDUHV2Nai2ZRicbkA==" }, "typescript": { "version": "4.5.5", diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 4b9a5f7..66c3a39 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -9,16 +9,20 @@ "engines": { "node": ">=10.13.0" }, - "devDependencies": {}, + "devDependencies": { + }, "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", "typescript-to-lua": "1.3.3", - "typed-factorio": "0.17.1", + "typed-factorio": "0.18.1", "typescript": "4.5.5" }, "license": "UNLICENSED", - "peerDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": [] + "peerDependencies": { + }, + "optionalDependencies": { + }, + "bundledDependencies": [ + ] } diff --git a/modules/events-mod/src/main/typescript/tsconfig.json b/modules/events-mod/src/main/typescript/tsconfig.json index d87f6f4..87b2667 100644 --- a/modules/events-mod/src/main/typescript/tsconfig.json +++ b/modules/events-mod/src/main/typescript/tsconfig.json @@ -24,7 +24,10 @@ "strict": true, "strictFunctionTypes": true, "strictNullChecks": true, - "traceResolution": true + "traceResolution": true, + "noImplicitReturns": true, + "noImplicitOverride": true, + "noFallthroughCasesInSwitch": true }, "tstl": { "luaTarget": "5.2", From 2aed3a670c12047fb072931d317e6ddbb2ea09f3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 12:31:39 +0100 Subject: [PATCH 211/629] kxsBinary.kt - formatting --- .../kafkatorio/processor/serdes/kxsBinary.kt | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt index c255676..de83b36 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt @@ -52,14 +52,14 @@ class KxsDataOutputEncoder( override fun encodeBoolean(value: Boolean) = output.writeByte(if (value) 1 else 0) override fun encodeByte(value: Byte) = output.writeByte(value.toInt()) - override fun encodeShort(value: Short) = output.writeShort(value.toInt()) + override fun encodeChar(value: Char) = output.writeChar(value.code) + override fun encodeDouble(value: Double) = output.writeDouble(value) + override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) = output.writeInt(index) + override fun encodeFloat(value: Float) = output.writeFloat(value) override fun encodeInt(value: Int) = output.writeInt(value) override fun encodeLong(value: Long) = output.writeLong(value) - override fun encodeFloat(value: Float) = output.writeFloat(value) - override fun encodeDouble(value: Double) = output.writeDouble(value) - override fun encodeChar(value: Char) = output.writeChar(value.code) + override fun encodeShort(value: Short) = output.writeShort(value.toInt()) override fun encodeString(value: String) = output.writeUTF(value) - override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) = output.writeInt(index) override fun beginCollection( descriptor: SerialDescriptor, @@ -73,10 +73,10 @@ class KxsDataOutputEncoder( override fun encodeNotNullMark() = encodeBoolean(true) override fun encodeSerializableValue(serializer: SerializationStrategy, value: T) { - if (serializer.descriptor == byteArraySerializer.descriptor) - encodeByteArray(value as ByteArray) - else - super.encodeSerializableValue(serializer, value) + when (serializer.descriptor) { + byteArraySerializer.descriptor -> encodeByteArray(value as ByteArray) + else -> super.encodeSerializableValue(serializer, value) + } } private fun encodeByteArray(bytes: ByteArray) { @@ -105,14 +105,14 @@ class KxsDataInputDecoder( override fun decodeBoolean(): Boolean = input.readByte().toInt() != 0 override fun decodeByte(): Byte = input.readByte() - override fun decodeShort(): Short = input.readShort() + override fun decodeChar(): Char = input.readChar() + override fun decodeDouble(): Double = input.readDouble() + override fun decodeEnum(enumDescriptor: SerialDescriptor): Int = input.readInt() + override fun decodeFloat(): Float = input.readFloat() override fun decodeInt(): Int = input.readInt() override fun decodeLong(): Long = input.readLong() - override fun decodeFloat(): Float = input.readFloat() - override fun decodeDouble(): Double = input.readDouble() - override fun decodeChar(): Char = input.readChar() + override fun decodeShort(): Short = input.readShort() override fun decodeString(): String = input.readUTF() - override fun decodeEnum(enumDescriptor: SerialDescriptor): Int = input.readInt() override fun decodeElementIndex(descriptor: SerialDescriptor): Int { if (elementIndex == elementsCount) return CompositeDecoder.DECODE_DONE @@ -132,12 +132,13 @@ class KxsDataInputDecoder( override fun decodeSerializableValue( deserializer: DeserializationStrategy, previousValue: T? - ): T = + ): T { @Suppress("UNCHECKED_CAST") - when (deserializer.descriptor) { + return when (deserializer.descriptor) { byteArraySerializer.descriptor -> decodeByteArray() as T else -> super.decodeSerializableValue(deserializer, previousValue) } + } private fun decodeByteArray(): ByteArray { val bytes = ByteArray(decodeCompactSize()) From a8337552e61fc737e743135eeb227d8fe7fdd62d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 12:32:17 +0100 Subject: [PATCH 212/629] use compact size for collections (I think I tried this already and it failed - but I'm going to wipe all data this time, so hopefully it works) --- .../dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt index de83b36..f61bf25 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt @@ -65,7 +65,7 @@ class KxsDataOutputEncoder( descriptor: SerialDescriptor, collectionSize: Int ): CompositeEncoder { - encodeInt(collectionSize) + encodeCompactSize(collectionSize) return this } @@ -125,7 +125,7 @@ class KxsDataInputDecoder( override fun decodeSequentially(): Boolean = true override fun decodeCollectionSize(descriptor: SerialDescriptor): Int = - decodeInt().also { elementsCount = it } + decodeCompactSize().also { elementsCount = it } override fun decodeNotNullMark(): Boolean = decodeBoolean() From c53d1d7c8783040386a3b8fecab94691427d45f7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 12:36:53 +0100 Subject: [PATCH 213/629] refactoring (I can't remember what... it's untested for sure), and using the latest things from event-schema --- .../kafkatorio/processor/eventProcessor.kt | 3 +- .../processor/topology/flowMapTiles.kt | 137 ++++++++++-------- .../processor/topology/groupMapChunks.kt | 11 +- .../kafkatorio/processor/topology/model.kt | 43 +++--- .../kafkatorio/processor/misc/serdeSize.kt | 9 +- 5 files changed, 111 insertions(+), 92 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt index e53bf6d..921e401 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -1,8 +1,7 @@ package dev.adamko.kafkatorio.processor -import dev.adamko.kafkatorio.admin.KafkatorioKafkaAdmin -import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.processor.admin.KafkatorioKafkaAdmin import dev.adamko.kafkatorio.processor.tileserver.WebMapTileServer import kotlinx.coroutines.runBlocking import org.http4k.server.PolyHandler diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt index 25b6f4d..e604844 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt @@ -7,6 +7,7 @@ import com.sksamuel.scrimage.nio.PngWriter import dev.adamko.kafkatorio.events.schema.ColourHex import dev.adamko.kafkatorio.events.schema.MapChunkPosition import dev.adamko.kafkatorio.events.schema.MapTilePosition +import dev.adamko.kafkatorio.events.schema.SurfaceIndex import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition import java.awt.image.BufferedImage import java.io.File @@ -16,6 +17,8 @@ import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.asFlow @@ -67,8 +70,8 @@ private value class TilePngFilename( ) { constructor(cmd: Cmd.CreateImage) : this(buildString { append("src/main/resources/kafkatorio-web-map") - append("/s${cmd.surfaceIndex.index}") - append("/z${cmd.zoomLevel.level}") + append("/s${cmd.surfaceIndex.value}") + append("/z${cmd.chunkSize.zoomLevel}") append("/x${cmd.chunkPosition.x}") append("/y${cmd.chunkPosition.y}") append(".png") @@ -79,40 +82,6 @@ private value class TilePngFilename( private val TRANSPARENT_AWT = ColourHex.TRANSPARENT.toRgbColor().awt() -private fun createMapTileImage( - chunkPosition: MapChunkPosition, - chunkColours: Map, - z: ZoomLevel -): ImmutableImage { - - val chunkImage = ImmutableImage.filled( - z.chunkSize, - z.chunkSize, - TRANSPARENT_AWT, - BufferedImage.TYPE_INT_ARGB - ) - - val chunkOriginX: Int = chunkPosition.x * z.chunkSize - val chunkOriginY: Int = chunkPosition.y * z.chunkSize - - chunkColours.forEach { (tilePosition, colour) -> - - val rgbColour = colour.toRgbColor() - - val pixelX = abs(abs(tilePosition.x) - abs(chunkOriginX)) - val pixelY = abs(abs(tilePosition.y) - abs(chunkOriginY)) - - chunkImage.setColor( - pixelX, - pixelY, - rgbColour - ) - } - - return chunkImage.scaleTo(WEB_MAP_TILE_SIZE_PX, WEB_MAP_TILE_SIZE_PX, ScaleMethod.FastScale) -} - - private fun ColourHex.toRgbColor(): RGBColor { return RGBColor( red.toInt(), @@ -122,6 +91,7 @@ private fun ColourHex.toRgbColor(): RGBColor { ) } + private class ServerMapChunkHandler : CoroutineScope { override val coroutineContext: CoroutineContext = Dispatchers.Default + @@ -129,19 +99,26 @@ private class ServerMapChunkHandler : CoroutineScope { CoroutineName("ServerMapChunkHandler") + /** The inbox for this handler. */ private val allChunksFlow = MutableSharedFlow>( replay = 0, extraBufferCapacity = 10, onBufferOverflow = BufferOverflow.SUSPEND, ) + fun emit(mapChunkTiles: ServerMapChunkTiles) { + launch { + allChunksFlow.emit(mapChunkTiles) + } + } + + /** This flow saves images one-by-one */ private val saveImagesFlow = MutableSharedFlow( replay = 0, extraBufferCapacity = 10, onBufferOverflow = BufferOverflow.SUSPEND, ) - init { allChunksFlow @@ -149,7 +126,7 @@ private class ServerMapChunkHandler : CoroutineScope { val flow = acc.getOrElse(src.chunkId) { println("creating new subdivide-flow for chunkId ${src.chunkId}") - subdivisionFlow() + createSubdivisionFlow() } flow.emit(Cmd.ChunkSubdivide(src.chunkId, src.map)) @@ -161,6 +138,7 @@ private class ServerMapChunkHandler : CoroutineScope { } .launchIn(this) + saveImagesFlow .onEach { (filename, img) -> @@ -176,42 +154,45 @@ private class ServerMapChunkHandler : CoroutineScope { } - fun emit(mapChunkTiles: ServerMapChunkTiles) { - launch { - allChunksFlow.emit(mapChunkTiles) - } - } - private fun subdivisionFlow(): MutableSharedFlow { + /** + * Given a chunk, split it into multiple, smaller sub-tiles. + * + * Send each sub-tile to [saveImagesFlow] to be saved as a PNG + */ + private fun createSubdivisionFlow(): MutableSharedFlow { - val flow = MutableSharedFlow( + val subdivisionFlow = MutableSharedFlow( replay = 0, extraBufferCapacity = 10, onBufferOverflow = BufferOverflow.SUSPEND, ) - val saveImgCommands = flow -// .conflate() + val saveImgCommands = subdivisionFlow .flatMapConcat { subdivideCmd -> - ZoomLevel.values - .asFlow() - .flatMapConcat { zoom -> + ChunkSize + .values + .flatMap { chunkSize -> subdivideCmd.tiles .entries - .groupBy({ (tile, _) -> tile.toMapChunkPosition(zoom.chunkSize) } + .groupBy( + { (tile, _) -> tile.toMapChunkPosition(chunkSize.tilesPerChunk) } ) { it.key to it.value } .map { (chunkPos, tiles) -> - Cmd.CreateImage( - surfaceIndex = subdivideCmd.chunkId.surfaceIndex, - zoomLevel = zoom, - chunkPosition = chunkPos, - tiles = tiles.toMap() - ) + async { + Cmd.CreateImage( + surfaceIndex = subdivideCmd.chunkId.surfaceIndex, + chunkSize = chunkSize, + chunkPosition = chunkPos, + tiles = tiles.toMap() + ) + } } - .asFlow() } + .awaitAll() + .asFlow() } .map { createCmd -> val filename = TilePngFilename(createCmd) @@ -219,7 +200,7 @@ private class ServerMapChunkHandler : CoroutineScope { val img = createMapTileImage( createCmd.chunkPosition, createCmd.tiles, - createCmd.zoomLevel, + createCmd.chunkSize, ) Cmd.SaveImage(filename, img) @@ -232,12 +213,46 @@ private class ServerMapChunkHandler : CoroutineScope { } } - return flow + return subdivisionFlow } + /** Create (but don't save) a PNG for the given chunk. */ + private fun createMapTileImage( + chunkPosition: MapChunkPosition, + chunkColours: Map, + chunkSize: ChunkSize + ): ImmutableImage { + + val chunkImage = ImmutableImage.filled( + chunkSize.tilesPerChunk, + chunkSize.tilesPerChunk, + TRANSPARENT_AWT, + BufferedImage.TYPE_INT_ARGB + ) + + val chunkOriginX: Int = chunkPosition.x * chunkSize.tilesPerChunk + val chunkOriginY: Int = chunkPosition.y * chunkSize.tilesPerChunk + + chunkColours.forEach { (tilePosition, colour) -> + + val rgbColour = colour.toRgbColor() + + val pixelX = abs(abs(tilePosition.x) - abs(chunkOriginX)) + val pixelY = abs(abs(tilePosition.y) - abs(chunkOriginY)) + + chunkImage.setColor( + pixelX, + pixelY, + rgbColour + ) + } + + return chunkImage.scaleTo(WEB_MAP_TILE_SIZE_PX, WEB_MAP_TILE_SIZE_PX, ScaleMethod.FastScale) + } } + private sealed interface Cmd { data class ChunkSubdivide( @@ -247,7 +262,7 @@ private sealed interface Cmd { data class CreateImage( val surfaceIndex: SurfaceIndex, - val zoomLevel: ZoomLevel, + val chunkSize: ChunkSize, val chunkPosition: MapChunkPosition, val tiles: Map, ) : Cmd diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt index 2130f77..17a1e82 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt @@ -6,6 +6,7 @@ import dev.adamko.kafkatorio.events.schema.MapChunk import dev.adamko.kafkatorio.events.schema.MapChunkPosition import dev.adamko.kafkatorio.events.schema.MapTilePosition import dev.adamko.kafkatorio.events.schema.MapTiles +import dev.adamko.kafkatorio.events.schema.SurfaceIndex import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kotka.extensions.groupedAs @@ -28,7 +29,7 @@ data class ServerMapChunkId( val serverId: FactorioServerId, val chunkPosition: MapChunkPosition, val surfaceIndex: SurfaceIndex, - val zoomLevel: ZoomLevel, + val chunkSize: ChunkSize, ) @@ -77,20 +78,20 @@ fun groupTilesIntoChunksWithColours( .filter { _, value -> value != null && value.tiles.isNotEmpty() } .flatMap("server-map-data.tiles.flatMapByChunk") { key: FactorioServerId, mapTiles: MapTiles -> - val zoomLevel = ZoomLevel.ZOOM_0 + val standardChunkSize = ChunkSize.MAX mapTiles .tiles .groupBy { tile -> - tile.position.toMapChunkPosition(zoomLevel.chunkSize) + tile.position.toMapChunkPosition(standardChunkSize.tilesPerChunk) } .map { (chunkPos, tiles) -> val chunkId = ServerMapChunkId( key, chunkPos, - SurfaceIndex(mapTiles.surfaceIndex), - zoomLevel, + mapTiles.surfaceIndex, + standardChunkSize, ) val tilesMap = tiles.associate { it.position to TileProtoHashCode(it) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt index 8bd855d..93375ee 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt @@ -5,15 +5,6 @@ import kotlin.math.roundToInt import kotlinx.serialization.Serializable -@Serializable -@JvmInline -value class SurfaceIndex( - val index: Int -) { - override fun toString() = "$index" -} - - @JvmInline @Serializable value class FactorioServerId(val id: String) { @@ -21,23 +12,35 @@ value class FactorioServerId(val id: String) { } -enum class ZoomLevel( - val level: Int -) { - ZOOM_0(0), // 512 - ZOOM_1(1), // 256 - ZOOM_2(2), // 128 - ZOOM_3(3), // 64 - ZOOM_4(4), // 32 +@Serializable +enum class ChunkSize( + val zoomLevel: Int, +) : Comparable { + CHUNK_512(-1), // 512 + CHUNK_256(0), // 256 + CHUNK_128(1), // 128 + CHUNK_064(2), // 64 + CHUNK_032(3), // 32 ; - val chunkSize: Int = 2f.pow(9 - level).roundToInt() + val tilesPerChunk: Int = 2f.pow(8 - zoomLevel).roundToInt() init { - require(chunkSize > 0) { "chunkSize must be positive" } + require(tilesPerChunk > 0) { "chunkSize must be positive" } + // 1000 & 0111 = 0000 => pow^2 + // 1001 & 1000 = 1000 => !pow^2 + require(tilesPerChunk and (tilesPerChunk - 1) == 0) { + "tilesPerChunk must be a power-of-two number" + } } companion object { - val values: List = values().asList() // better performance, KT-48872 + // cache values for better performance. KT-48872 + val values: List = values().asList() + + val MAX: ChunkSize = values.maxByOrNull { it.tilesPerChunk }!! + val MIN: ChunkSize = values.minByOrNull { it.tilesPerChunk }!! + val STANDARD: ChunkSize = values.first { it.zoomLevel == 0 } + } } diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt index 941cc09..747ed65 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt @@ -3,16 +3,17 @@ package dev.adamko.kafkatorio.processor.misc import dev.adamko.kafkatorio.events.schema.ColourHex import dev.adamko.kafkatorio.events.schema.MapChunkPosition import dev.adamko.kafkatorio.events.schema.MapTilePosition +import dev.adamko.kafkatorio.events.schema.SurfaceIndex import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.processor.topology.ChunkSize import dev.adamko.kafkatorio.processor.topology.FactorioServerId import dev.adamko.kafkatorio.processor.topology.ServerMapChunkId import dev.adamko.kafkatorio.processor.topology.ServerMapChunkTiles -import dev.adamko.kafkatorio.processor.topology.SurfaceIndex -import dev.adamko.kafkatorio.processor.topology.ZoomLevel import java.util.UUID import kotlinx.serialization.encodeToByteArray import org.junit.jupiter.api.Test + class Blah { @Test @@ -22,8 +23,8 @@ class Blah { chunkId = ServerMapChunkId( serverId = FactorioServerId(UUID.randomUUID().toString()), chunkPosition = MapChunkPosition(Int.MAX_VALUE, Int.MAX_VALUE), - surfaceIndex = SurfaceIndex(Int.MAX_VALUE), - zoomLevel = ZoomLevel.ZOOM_0 + surfaceIndex = SurfaceIndex(UInt.MAX_VALUE), + chunkSize = ChunkSize.MAX ), buildMap { repeat(512) { x -> From 16510488da6317bb1ac23ade7e9152a54ed69963 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 12:38:11 +0100 Subject: [PATCH 214/629] create an event-cacher, for debouncing/throttling --- .../events-mod/src/main/typescript/control.ts | 2 + .../typescript/main/cache/EventDataCache.ts | 169 ++++++++++++++++++ .../src/main/typescript/main/global.d.ts | 8 + 3 files changed, 179 insertions(+) create mode 100644 modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index df1cacc..296e0ce 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -1,6 +1,7 @@ import {handleConfigurationUpdate} from "./main/config-update/handleConfigurationUpdate"; import {emitPrototypes} from "./main/config-update/prototypes"; import {Queue} from "./main/queue/queue"; +import {EventDataCache} from "./main/cache/EventDataCache"; require("./main/events/registerHandlers") require("./main/commands/kafkatorioCommands") @@ -10,4 +11,5 @@ script.on_configuration_changed(handleConfigurationUpdate) script.on_init(() => { Queue.reset() emitPrototypes() + EventDataCache.init() }) diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts new file mode 100644 index 0000000..3252242 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts @@ -0,0 +1,169 @@ +import {ExcludeNullKeys} from "../global"; + +export namespace EventDataCache { + + + declare const global: { + cache: LuaTable, CacheEntry>, + DEFAULT_EXPIRATION_DURATION_TICKS: uint, + } + + + export function init() { + if (typeof global.cache == undefined) { + global.cache = new LuaTable, CacheEntry>() + + global.DEFAULT_EXPIRATION_DURATION_TICKS = 60 * 60 // ~60 seconds + } + } + + /** + * Update the cache data without restarting the 'time-to-emit' countdown, so that the data won't + * be emitted more than once per {@link CacheEntry.expirationDurationTicks}. + */ + export function throttle( + key: CacheKey, + mutate: (data: CacheData | undefined) => void, + ) { + update(key, mutate, false) + } + + /** + * Update the cache data and reset the 'time-to-emit' countdown, so the data won't be emitted + * until there's an inactivity gap of {@link CacheEntry.expirationDurationTicks}. + */ + export function debounce( + key: CacheKey, + mutate: (data: CacheData | undefined) => void, + ) { + update(key, mutate, true) + } + + function update( + key: CacheKey, + mutate: (data: CacheData | undefined) => void, + resetLastUpdated: boolean, + ) { + const entry = getCacheEntry(key) + mutate(entry?.data) + if (entry != undefined && resetLastUpdated) { + entry.lastUpdatedTick = game.tick + } + } + + /** + * Usage example: If an urgent update comes in, then the expiration can be reduced so that + * it's transmitted sooner. + */ + export function setExpiration( + key: CacheKey, + expirationDurationTicks?: uint, + ) { + const entry = getCacheEntry(key) + if (entry != undefined) { + entry.expirationDurationTicks = expirationDurationTicks + } + } + + function getCacheEntry( + key: CacheKey + ): CacheEntry | undefined { + if (!global.cache.has(key)) { + return undefined + } + const value: CacheEntry = global.cache.get(key) + if (isType(value, key.updateType)) { + return value + } else { + // Type mismatch. This shouldn't happen... + return undefined + } + } + + type UpdateType = T["updateType"] + + /** Only include the non-null properties */ + export type CacheKey = ExcludeNullKeys & { + updateType: UpdateType + } + + /** Make the generated schema objects generic closed-polymorphic */ + export type CacheData = Omit & { + updateType: UpdateType + } + + + class CacheEntry { + lastUpdatedTick: uint = game.tick + expirationDurationTicks?: uint + + data: CacheData + + constructor( + data: CacheData, + expirationDurationTicks?: uint, + ) { + this.data = data + if (expirationDurationTicks != undefined) { + this.expirationDurationTicks = expirationDurationTicks + } + } + + isExpired(): boolean { + return game.tick - + this.lastUpdatedTick > + (this.expirationDurationTicks ?? global.DEFAULT_EXPIRATION_DURATION_TICKS) + } + } + + function isType( + data: CacheEntry, + updateType: UpdateType, + ): data is CacheEntry { + return data.data.updateType == updateType + } + +} + +// interface FactorioEventUpdate { +// type: string +// } +// +// interface Update { +// type: T +// } +// +// export interface PlayerUpdate extends Update<"PLAYER"> { +// index: uint +// +// unhandledEvents?: string[] +// +// characterUnitNumber?: uint +// chatColour?: Colour +// colour?: Colour +// disconnectReason?: string +// forceIndex?: uint +// isAdmin?: boolean +// isConnected?: boolean +// isShowOnMap?: boolean +// isSpectator?: boolean +// lastOnline?: uint +// afkTime?: uint +// name?: string +// onlineTime?: uint +// position?: MapEntityPosition +// surfaceIndex?: uint +// ticksToRespawn?: uint +// tag?: string +// } + +// export type CacheKey = MapChunkCacheKey | EntityCacheKey | PlayerCacheKey & { +// type: Type +// } +// +// export function isCacheType( +// cacheKey: CacheKey, +// type: CacheType +// ): cacheKey is CK { +// return cacheKey.type == type +// } diff --git a/modules/events-mod/src/main/typescript/main/global.d.ts b/modules/events-mod/src/main/typescript/main/global.d.ts index 7a73643..b8122e7 100644 --- a/modules/events-mod/src/main/typescript/main/global.d.ts +++ b/modules/events-mod/src/main/typescript/main/global.d.ts @@ -2,3 +2,11 @@ declare const global: { MOD_VERSION: string FACTORIO_VERSION: string } + +export type EventName = keyof typeof defines.events + +type NonNullKeys = { + [P in keyof T]: null extends Exclude ? never : P +}[keyof T]; + +type ExcludeNullKeys = Pick> From e0b9ef9788b3a1e2ca819b050ec31c52477fa148 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 12:40:55 +0100 Subject: [PATCH 215/629] update event-type checker, plus some refactoring/updating --- .../main/events/registerHandlers.ts | 42 +++++++++---------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index c1dc0a4..61e4f60 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -7,20 +7,19 @@ import { handleTilesUpdate } from "./handlers"; import {Queue} from "../queue/queue"; -import on_player_built_tile = defines.events.on_player_built_tile; -import on_robot_built_tile = defines.events.on_robot_built_tile; +import {EventName} from "../global"; -const mapEventIdToName = new LuaTable() +const mapEventIdToName = new LuaTable() for (const [eventName, eventId] of pairs(defines.events)) { mapEventIdToName.set(eventId, eventName) } -const mapEventIdToDefinedType = new LuaTable, EventId>() -for (const [eventName, eventId] of pairs(defines.events)) { - let definedType = defines.events[eventName] - mapEventIdToDefinedType.set(eventId, definedType) -} +// const mapEventIdToDefinedType = new LuaTable, EventId>() +// for (const [eventName, eventId] of pairs(defines.events)) { +// let definedType = defines.events[eventName] +// mapEventIdToDefinedType.set(eventId, definedType) +// } // script.on_event( // [defines.events.on_pre_build, defines.events.on_player_dropped_item], @@ -41,9 +40,6 @@ script.on_event( script.on_event( defines.events.on_player_joined_game, (e: OnPlayerJoinedGameEvent) => { - - Queue.init() // TODO make Queue initialisation more stable, not dependent on events - handlePlayerUpdate(e.tick, mapEventIdToName.get(e.name), e.player_index) } ) @@ -59,7 +55,7 @@ script.on_event( defines.events.on_tick, (e: OnTickEvent) => { if (e.tick % 1000 == 0) { - for (const [, surface] of pairs(game.surfaces)) { + for (const [, surface] of game.surfaces) { handleSurfaceUpdate(e.tick, mapEventIdToName.get(e.name), surface) } @@ -76,8 +72,7 @@ script.on_event( log(`[${e.tick}] dequed ${events.length} events, current size: ${Queue.size()}`) for (const event of events) { - - if (isEventType(event)) { + if (isEventType(event, defines.events.on_chunk_generated)) { let eName = mapEventIdToName.get(event.name) log(`[${e.tick}] dequed event ${eName}`) @@ -104,7 +99,10 @@ script.on_event( ) script.on_event( - [on_player_built_tile, on_robot_built_tile], + [ + defines.events.on_player_built_tile, + defines.events.on_robot_built_tile, + ], (builtTilesEvent) => { handleTilesUpdate( builtTilesEvent.tick, @@ -117,12 +115,10 @@ script.on_event( ) -function isEventType(e: EventData): e is E { - let id: EventId | string = e.name - if (typeof id === "string") { - return false - } else { - let name = mapEventIdToDefinedType.get(id) - return e.name == name - } +function isEventType( + eventData: EventData, + type: ED extends CustomInputEvent ? string : EventId +): eventData is ED { + let id: EventId | string = eventData.name + return id == type } From dd45bece5366d8a47774e608cb375307408cd732 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 22:16:09 +0100 Subject: [PATCH 216/629] model updates, and fix tests --- .../generated/kafkatorio-schema/schema.d.ts | 40 ++++++++++++++---- .../events/schema/factorioCommonData.kt | 7 ++++ .../events/schema/factorioEventUpdates.kt | 41 ++++++++++++++----- .../events/schema/kafkatorioPacket.kt | 2 + .../events/schema/FactorioEventTest.kt | 13 +++--- .../topology/factorioServerPackets.kt | 18 ++++---- 6 files changed, 90 insertions(+), 31 deletions(-) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts index 3ba828d..41a6c66 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts @@ -1,12 +1,25 @@ // Generated by TypeScriptGenerator - do not edit this file manually -type PacketType = "EVENT" | "CONFIG" | "PROTOTYPES"; +type PacketType = "EVENT" | "CONFIG" | "PROTOTYPES" | "UPDATE"; interface KafkatorioPacket { modVersion: string; packetType: PacketType; } +type FactorioEventUpdateType = "PLAYER" | "MAP_CHUNK" | "ENTITY"; + +interface FactorioEventUpdate { + updateType: FactorioEventUpdateType; +} + +interface FactorioEventUpdatePacket extends KafkatorioPacket { + modVersion: string; + packetType: PacketType; + tick: uint; + update: FactorioEventUpdate; +} + interface FactorioEvent extends KafkatorioPacket { data: FactorioObjectData; eventType: string; @@ -80,33 +93,39 @@ interface MapTile { prototypeName: string; } -type FactorioEventUpdateType = "PLAYER" | "MAP_CHUNK" | "ENTITY"; - -interface FactorioEventUpdate { - updateType: FactorioEventUpdateType; +interface EntityIdentifiers { + name: string; + type: string; + unitNumber: uint | null; } interface PlayerUpdate extends FactorioEventUpdate { + afkTime: uint | null; + bannedReason: string | null; characterUnitNumber: uint | null; chatColour: Colour | null; colour: Colour | null; + diedCause: EntityIdentifiers | null; disconnectReason: string | null; forceIndex: uint | null; index: uint; isAdmin: boolean | null; isConnected: boolean | null; + isRemoved: boolean | null; isShowOnMap: boolean | null; isSpectator: boolean | null; + kickedReason: string | null; lastOnline: uint | null; name: string | null; onlineTime: uint | null; position: MapEntityPosition | null; surfaceIndex: uint | null; tag: string | null; + ticksToRespawn: uint | null; updateType: FactorioEventUpdateType; } -interface EntityUpdate extends FactorioEventUpdate { +interface EntityUpdate extends FactorioEventUpdate, EntityIdentifiers { chunkPosition: MapChunkPosition | null; graphicsVariation: number | null; health: float | null; @@ -115,17 +134,20 @@ interface EntityUpdate extends FactorioEventUpdate { lastUser: int | null; localisedDescription: string | null; localisedName: string | null; - name: string | null; + name: string; prototype: string | null; - type: string | null; + type: string; unitNumber: uint; updateType: FactorioEventUpdateType; } interface MapChunkUpdate extends FactorioEventUpdate { chunkPosition: MapChunkPosition; + force: uint | null; isDeleted: boolean | null; + player: uint | null; + robot: EntityIdentifiers | null; surfaceIndex: uint; - tiles: MapTiles | null; + tiles: Map | null; updateType: FactorioEventUpdateType; } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index f5cdf9c..0ce9fe3 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -101,3 +101,10 @@ data class MapTile( val prototypeName: PrototypeName, val position: MapTilePosition, ) + + +interface EntityIdentifiers { + val unitNumber: UnitNumber? + val name: String + val type: String +} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt index a109ca7..61b85bc 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt @@ -10,6 +10,18 @@ import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive +@Serializable +class FactorioEventUpdatePacket( + override val modVersion: String, + /** game time */ + val tick: Tick, + val update: FactorioEventUpdate, +) : KafkatorioPacket() { + @EncodeDefault + override val packetType: PacketType = PacketType.UPDATE +} + + @Serializable(with = FactorioEventUpdate.Companion.JsonSerializer::class) sealed class FactorioEventUpdate { @@ -68,7 +80,8 @@ data class PlayerUpdate( val colour: Colour? = null, val name: String? = null, - val disconnectReason: String? = null, + val afkTime: Tick? = null, + val ticksToRespawn: Tick? = null, val forceIndex: ForceIndex? = null, val isAdmin: Boolean? = null, val isConnected: Boolean? = null, @@ -79,6 +92,13 @@ data class PlayerUpdate( val position: MapEntityPosition? = null, val surfaceIndex: SurfaceIndex? = null, val tag: String? = null, + val diedCause: EntityIdentifiers? = null, + + val bannedReason: String? = null, + val kickedReason: String? = null, + val disconnectReason: String? = null, + /** `true` when a player is removed (deleted) from the game */ + val isRemoved: Boolean? = null, ) : FactorioEventUpdate() { @EncodeDefault override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.PLAYER @@ -87,14 +107,11 @@ data class PlayerUpdate( @Serializable data class EntityUpdate( - /** - * A [unitNumber] is required for caching, else the Entity Update should be emitted without - * debouncing/throttling - */ - val unitNumber: UnitNumber, + /** A [unitNumber] is required for caching */ + override val unitNumber: UnitNumber, + override val name: String, + override val type: String, - val name: String? = null, - val type: String? = null, val chunkPosition: MapChunkPosition? = null, val graphicsVariation: UShort? = null, val health: Float? = null, @@ -104,7 +121,7 @@ data class EntityUpdate( val localisedDescription: String? = null, val localisedName: String? = null, val prototype: PrototypeName? = null, -) : FactorioEventUpdate() { +) : FactorioEventUpdate(), EntityIdentifiers { @EncodeDefault override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.ENTITY } @@ -115,8 +132,12 @@ data class MapChunkUpdate( val chunkPosition: MapChunkPosition, val surfaceIndex: SurfaceIndex, + val player: PlayerIndex? = null, + val robot: EntityIdentifiers? = null, + val force: ForceIndex? = null, + /** Might be a partial list of updated tiles */ - val tiles: MapTiles? = null, + val tiles: Map? = null, val isDeleted: Boolean? = null, ) : FactorioEventUpdate() { @EncodeDefault diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt index fd59bc2..7d852f1 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt @@ -21,6 +21,7 @@ sealed class KafkatorioPacket { EVENT, CONFIG, PROTOTYPES, + UPDATE, ; companion object { @@ -51,6 +52,7 @@ object KafkatorioPacketJsonSerializer : JsonContentPolymorphicSerializer FactorioEvent.serializer() KafkatorioPacket.PacketType.CONFIG -> FactorioConfigurationUpdate.serializer() KafkatorioPacket.PacketType.PROTOTYPES -> FactorioPrototypes.serializer() + KafkatorioPacket.PacketType.UPDATE -> FactorioEventUpdatePacket.serializer() } } } diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt index 400b8bf..6597434 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt @@ -15,6 +15,8 @@ class FactorioEventTest : FunSpec({ { "data": { "objectName": "LuaPlayer", + "force": 1, + "surface": 1, "name": "fredthedeadhead", "characterUnitNumber": 1, "associatedCharactersUnitNumbers": {}, @@ -145,7 +147,8 @@ class FactorioEventTest : FunSpec({ "active": true, "health": 250, "healthRatio": 1, - "surfaceIndex": 1, + "surface": 1, + "force": 1, "unitNumber": 1, "position": { "x": 37.5, @@ -251,19 +254,19 @@ class FactorioEventTest : FunSpec({ surfaceIndex = SurfaceIndex(1u), tiles = listOf( MapTile( - prototypeName = "refined-concrete", + prototypeName = PrototypeName("refined-concrete"), position = MapTilePosition(-65, 10) ), MapTile( - prototypeName = "red-earth", + prototypeName = PrototypeName("red-earth"), position = MapTilePosition(-65, 11) ), MapTile( - prototypeName = "blue-cheese", + prototypeName = PrototypeName("blue-cheese"), position = MapTilePosition(-64, 10) ), MapTile( - prototypeName = "refined-concrete", + prototypeName = PrototypeName("refined-concrete"), position = MapTilePosition(-64, 11) ), ) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt index d1869d3..9371f9f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt @@ -2,6 +2,7 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.FactorioEventUpdatePacket import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.processor.KafkatorioTopology @@ -49,13 +50,16 @@ fun splitFactorioServerPacketStream( ) ) { _: FactorioServerId, value: KafkatorioPacket, _: RecordContext -> // println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") - when (value) { - is FactorioEvent -> - "kafkatorio.${value.packetType.name}.${value.data.objectName.name}" - is FactorioConfigurationUpdate -> - "kafkatorio.${value.packetType.name}.FactorioConfigurationUpdate" - is FactorioPrototypes -> - "kafkatorio.${value.packetType.name}.all" + + val base = "kafkatorio.${value.packetType.name}" + + val type: String = when (value) { + is FactorioEvent -> value.data.objectName.name + is FactorioConfigurationUpdate -> "FactorioConfigurationUpdate" + is FactorioPrototypes -> "all" + is FactorioEventUpdatePacket -> "all" } + + "$base.$type" } } From d14d0cd991d5c659331980a4af4cbb1f16885f96 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 22:18:14 +0100 Subject: [PATCH 217/629] finish first implementation of incremental updates --- .../typescript/main/cache/EventDataCache.ts | 143 ++++++++---- .../typescript/main/cache/cacheChecker.ts | 52 +++++ .../main/config-update/prototypes.ts | 1 + .../typescript/main/emitKafkatorioPacket.ts | 1 - .../main/typescript/main/events/converters.ts | 35 +-- .../typescript/main/events/eventTypeCheck.ts | 8 + .../main/typescript/main/events/handlers.ts | 16 +- .../main/typescript/main/events/mapEvents.ts | 213 ++++++++++++++++++ .../typescript/main/events/playerEvents.ts | 178 +++++++++++++++ .../main/events/registerHandlers.ts | 39 ++-- .../src/main/typescript/main/global.d.ts | 8 - .../src/main/typescript/main/types.d.ts | 17 ++ 12 files changed, 614 insertions(+), 97 deletions(-) create mode 100644 modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts create mode 100644 modules/events-mod/src/main/typescript/main/events/eventTypeCheck.ts create mode 100644 modules/events-mod/src/main/typescript/main/events/mapEvents.ts create mode 100644 modules/events-mod/src/main/typescript/main/events/playerEvents.ts create mode 100644 modules/events-mod/src/main/typescript/main/types.d.ts diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts index 3252242..7c9225a 100644 --- a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts +++ b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts @@ -1,62 +1,78 @@ -import {ExcludeNullKeys} from "../global"; +import {ExcludeNullKeys, NonNullableKeys} from "../types"; export namespace EventDataCache { declare const global: { - cache: LuaTable, CacheEntry>, - DEFAULT_EXPIRATION_DURATION_TICKS: uint, + cache: LuaTable, CacheEntry>, + DEFAULT_CACHE_DURATION_TICKS: LuaTable, + DEFAULT_CACHE_DURATION_TICKS2: Record, + MAP_CHUNK_CACHE_DURATION_TICKS: uint, } export function init() { if (typeof global.cache == undefined) { - global.cache = new LuaTable, CacheEntry>() + global.cache = new LuaTable, CacheEntry>() - global.DEFAULT_EXPIRATION_DURATION_TICKS = 60 * 60 // ~60 seconds + global.DEFAULT_CACHE_DURATION_TICKS = new LuaTable() + global.DEFAULT_CACHE_DURATION_TICKS.set("PLAYER", 30) // 0.5 seconds + global.DEFAULT_CACHE_DURATION_TICKS.set("MAP_CHUNK", 60 * 15) // ~ 15 seconds + global.DEFAULT_CACHE_DURATION_TICKS.set("ENTITY", 60 * 2) // ~2 seconds + + global.DEFAULT_CACHE_DURATION_TICKS2 = { + "PLAYER": 30, // 0.5 seconds + "MAP_CHUNK": 60 * 15, // ~ 15 seconds + "ENTITY": 60 * 2, // ~2 seconds + "default": 60 + } } } + /** * Update the cache data without restarting the 'time-to-emit' countdown, so that the data won't * be emitted more than once per {@link CacheEntry.expirationDurationTicks}. */ - export function throttle( - key: CacheKey, - mutate: (data: CacheData | undefined) => void, + export function throttle( + key: CacheKey, + mutate: CacheDataMutator, ) { update(key, mutate, false) } + /** * Update the cache data and reset the 'time-to-emit' countdown, so the data won't be emitted * until there's an inactivity gap of {@link CacheEntry.expirationDurationTicks}. */ - export function debounce( - key: CacheKey, - mutate: (data: CacheData | undefined) => void, + export function debounce( + key: CacheKey, + mutate: CacheDataMutator, ) { update(key, mutate, true) } - function update( - key: CacheKey, - mutate: (data: CacheData | undefined) => void, + + function update( + key: CacheKey, + mutate: CacheDataMutator, resetLastUpdated: boolean, ) { - const entry = getCacheEntry(key) - mutate(entry?.data) - if (entry != undefined && resetLastUpdated) { + const entry = getCacheEntry(key) ?? createCacheEntry(key, mutate) + mutate(entry.data) + if (resetLastUpdated) { entry.lastUpdatedTick = game.tick } } + /** * Usage example: If an urgent update comes in, then the expiration can be reduced so that * it's transmitted sooner. */ export function setExpiration( - key: CacheKey, + key: CacheKey, expirationDurationTicks?: uint, ) { const entry = getCacheEntry(key) @@ -65,9 +81,22 @@ export namespace EventDataCache { } } - function getCacheEntry( - key: CacheKey - ): CacheEntry | undefined { + + export function extractExpired(): Array> { + const expiredData: Array> = [] + for (let [key, entry] of global.cache) { + if (entry.isExpired()) { + expiredData.push(entry.data) + global.cache.delete(key) + } + } + return expiredData + } + + + function getCacheEntry( + key: CacheKey + ): CacheEntry | undefined { if (!global.cache.has(key)) { return undefined } @@ -80,27 +109,57 @@ export namespace EventDataCache { } } - type UpdateType = T["updateType"] - /** Only include the non-null properties */ - export type CacheKey = ExcludeNullKeys & { - updateType: UpdateType - } - - /** Make the generated schema objects generic closed-polymorphic */ - export type CacheData = Omit & { - updateType: UpdateType + function createCacheEntry( + key: CacheKey, + mutate: CacheDataMutator, + ): CacheEntry { + // @ts-ignore // TODO remove ts-ignore for "not assignable to type" + const data: CacheData = {updateType: key.updateType} + mutate(data) + let entry: CacheEntry = new CacheEntry(data) + global.cache.set(key, entry) + return entry } - class CacheEntry { + /** Map a {@link FactorioEventUpdateType} to a {@link FactorioEventUpdate} DTO */ + type ConvertUpdateType = + TYPE extends "PLAYER" ? PlayerUpdate : + TYPE extends "MAP_CHUNK" ? MapChunkUpdate : + TYPE extends "ENTITY" ? EntityUpdate : + never + + + /** Only include the non-null properties, and make `updateType` specific */ + export type CacheKey = + CacheTyped + & Omit>, "updateType"> + + + /** Exclude {@link CacheKey} fields, and make `updateType` specific */ + export type CacheData = + CacheTyped + & NonNullableKeys, keyof CacheKey | "updateType">>> + + + export type CacheTyped = { + readonly updateType: TYPE + } + + + export type CacheDataMutator = + (data: CacheData) => void + + + class CacheEntry { lastUpdatedTick: uint = game.tick expirationDurationTicks?: uint - data: CacheData + data: CacheData constructor( - data: CacheData, + data: CacheData, expirationDurationTicks?: uint, ) { this.data = data @@ -110,16 +169,18 @@ export namespace EventDataCache { } isExpired(): boolean { - return game.tick - - this.lastUpdatedTick > - (this.expirationDurationTicks ?? global.DEFAULT_EXPIRATION_DURATION_TICKS) + const cacheDuration = + this.expirationDurationTicks ?? global.DEFAULT_CACHE_DURATION_TICKS2[this.data.updateType] + + return game.tick - this.lastUpdatedTick > cacheDuration } } - function isType( - data: CacheEntry, - updateType: UpdateType, - ): data is CacheEntry { + + function isType( + data: CacheEntry, + updateType: TYPE, + ): data is CacheEntry { return data.data.updateType == updateType } @@ -129,7 +190,7 @@ export namespace EventDataCache { // type: string // } // -// interface Update { +// interface Update { // type: T // } // diff --git a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts new file mode 100644 index 0000000..4404725 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts @@ -0,0 +1,52 @@ +import {EventDataCache} from "./EventDataCache"; +import {emitPacket} from "../emitKafkatorioPacket"; +// import { global } from "../global"; + +/** Every 0.1 seconds */ +script.on_nth_tick(6, (nthTick: NthTickEventData) => { + + const cachedEvents: Array> = EventDataCache.extractExpired() + + for (const event of cachedEvents) { + + const packet: FactorioEventUpdatePacket = { + tick: nthTick.tick, + modVersion: global.MOD_VERSION, + packetType: "UPDATE", + update: event, + } + + emitPacket(packet) + } +}) + +// +// function createEntityUpdate(cacheKey: EntityCacheKey, events: EventName[]): EntityUpdate | null { +// +// +// return null +// } +// +// interface EntityUpdate { +// name: string +// +// unit_number: uint +// +// unhandledEvents?: string[] +// +// chunkPosition: MapChunkPosition +// graphics_variation?: uint8 +// health?: float +// isActive?: boolean +// isRotatable?: boolean +// last_user?: uint +// localised_description?: string +// localised_name?: string +// prototype?: string +// +// // ghost_localised_description?: string +// // ghost_localised_name?: string +// // ghost_name?: string +// // ghost_prototype?: string +// // ghost_unit_number?: uint +// } diff --git a/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts b/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts index 634d1a8..8b494da 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts @@ -1,5 +1,6 @@ import {Converters} from "../events/converters"; import {emitPacket} from "../emitKafkatorioPacket"; +// import { global } from "../global"; export function emitPrototypes() { emitPacket({ diff --git a/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts b/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts index fcaa92f..c86af5d 100644 --- a/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts +++ b/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts @@ -1,7 +1,6 @@ /** Emit a serialised KafkatorioPacket */ export function emitPacket(packet: T) { let data = game.table_to_json(packet) - // localised_print(`KafkatorioPacket: ${packet.packetType}`) localised_print(`KafkatorioPacket: ${data}`) // rcon.print(`KafkatorioPacket: ${data}`) } diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index 6314ba4..7acecb2 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -1,19 +1,19 @@ export namespace Converters { - export function playerToTable(player: LuaPlayer): PlayerData { - let charIds = entitiesToUnitNumbers(player.get_associated_characters()) - return { - objectName: player.object_name, - - name: player.name, - characterUnitNumber: player.character?.unit_number ?? null, - associatedCharactersUnitNumbers: charIds, - position: mapEntityPosition(player.position), - colour: mapColour(player.color), - chatColour: mapColour(player.chat_color), - lastOnline: player.last_online - } - } + // export function playerToTable(player: LuaPlayer): PlayerData { + // let charIds = entitiesToUnitNumbers(player.get_associated_characters()) + // return { + // objectName: player.object_name, + // + // name: player.name, + // characterUnitNumber: player.character?.unit_number ?? null, + // associatedCharactersUnitNumbers: charIds, + // position: mapEntityPosition(player.position), + // colour: mapColour(player.color), + // chatColour: mapColour(player.chat_color), + // lastOnline: player.last_online + // } + // } export function entityToTable(entity: LuaEntity): EntityData { @@ -28,9 +28,10 @@ export namespace Converters { active: entity.active, health: entity.health ?? null, healthRatio: entity.get_health_ratio(), - surfaceIndex: entity.surface.index, + surface: entity.surface.index, unitNumber: entity.unit_number ?? null, position: mapEntityPosition(entity.position), + force: entity.force.index, // player data playerIndex: player?.index ?? null @@ -103,6 +104,10 @@ export namespace Converters { } } + export function convertTiles(tiles: LuaTile[]): MapTile[] { + return tiles.map((tile: LuaTile) => convertTile(tile)) + } + export function convertBoundingBox(bb: BoundingBoxRead): MapBoundingBox { return { topLeft: mapTilePosition(bb.left_top), diff --git a/modules/events-mod/src/main/typescript/main/events/eventTypeCheck.ts b/modules/events-mod/src/main/typescript/main/events/eventTypeCheck.ts new file mode 100644 index 0000000..e3769f2 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/events/eventTypeCheck.ts @@ -0,0 +1,8 @@ + +function isEventType( + eventData: EventData, + type: ED extends CustomInputEvent ? string : EventId +): eventData is ED { + let id: EventId | string = eventData.name + return id == type +} diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index 569eb27..2feb68c 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -1,14 +1,14 @@ import {Converters} from "./converters" import {emitEvent} from "./emitEvent"; -export function handlePlayerUpdate(tick: uint, eventType: string, playerIndex: uint) { - let player: LuaPlayer = game.players[playerIndex] - let table = Converters.playerToTable(player) - - emitEvent(table, tick, eventType) - - handleCharactersEvent(tick, eventType, playerIndex) -} +// export function handlePlayerUpdate(tick: uint, eventType: string, playerIndex: uint) { +// let player: LuaPlayer = game.players[playerIndex] +// let table = Converters.playerToTable(player) +// +// emitEvent(table, tick, eventType) +// +// handleCharactersEvent(tick, eventType, playerIndex) +// } export function handleCharactersEvent(tick: uint, eventType: string, playerIndex: uint) { diff --git a/modules/events-mod/src/main/typescript/main/events/mapEvents.ts b/modules/events-mod/src/main/typescript/main/events/mapEvents.ts new file mode 100644 index 0000000..5744703 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/events/mapEvents.ts @@ -0,0 +1,213 @@ +import {EventDataCache} from "../cache/EventDataCache"; +import CacheKey = EventDataCache.CacheKey; +import CacheData = EventDataCache.CacheData; + + +type MapChunkUpdater = (data: CacheData<"MAP_CHUNK">) => void + + +function mapTilesUpdateDebounce( + surface: LuaSurface | undefined, + chunkPosition: ChunkPositionTable, + tiles: TileRead[], + updater?: MapChunkUpdater +) { + if (surface == undefined) { + return + } + + EventDataCache.debounce<"MAP_CHUNK">( + { + surfaceIndex: surface.index, + chunkPosition: chunkPosition, + updateType: "MAP_CHUNK", + }, + data => { + if (data.tiles == undefined) { + data.tiles = new Map() + } + + for (const tile of tiles) { + const position: MapTilePosition = {x: tile.position.x, y: tile.position.y} + data.tiles.set(position, tile.name) + } + + if (updater != undefined) { + updater(data) + } + } + ) +} + + +function getTiles( + surface: LuaSurface | undefined, + area: BoundingBoxTable +): LuaTile[] { + return surface?.find_tiles_filtered({ + area: area, + // collision_mask: ["ground-tile", "water-tile"] + } + ) ?? [] +} + +function getSurface(surfaceIndex: uint): LuaSurface | undefined { + return game.surfaces[surfaceIndex] +} + +script.on_event( + defines.events.on_chunk_generated, + (e: OnChunkGeneratedEvent) => { + let tiles = getTiles(e.surface, e.area) + mapTilesUpdateDebounce(e.surface, e.position, tiles) + } +) + +script.on_event( + defines.events.on_chunk_charted, + (e: OnChunkChartedEvent) => { + + const surface = getSurface(e.surface_index) + if (surface == undefined) { + return + } + + let tiles = getTiles(surface, e.area) + mapTilesUpdateDebounce(surface, e.position, tiles, (data => { + data.force = e.force.index + })) + } +) + +script.on_event( + defines.events.script_raised_set_tiles, + (e: ScriptRaisedSetTilesEvent) => { + + const surface = getSurface(e.surface_index) + if (surface == undefined) { + return + } + + const groupedTiles = groupTiles(e.tiles) + + for (const [chunkPos, tiles] of groupedTiles) { + mapTilesUpdateDebounce(surface, chunkPos, tiles) + } + } +) + + +function groupTiles(tiles: TileRead[]): Map { + + const mapChunkPositionToTiles = new Map() + for (const tile of tiles) { + const chunkPosition = { + x: math.floor((tile.position.x / 32)), + y: math.floor((tile.position.y / 32)), + } + if (!mapChunkPositionToTiles.has(chunkPosition)) { + mapChunkPositionToTiles.set(chunkPosition, []) + } + mapChunkPositionToTiles.get(chunkPosition)?.push(tile) + } + return mapChunkPositionToTiles +} + +function convertOldPosition( + oldTiles: OldTileAndPosition[], + placedTile: LuaTilePrototype, +): TileRead[] { + + return oldTiles.map((tile) => { + return { + position: {x: tile.position.x, y: tile.position.y}, + name: placedTile.name, + } + } + ) +} + +function onBuildTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) { + + const surface = getSurface(event.surface_index) + if (surface == undefined) { + return + } + + const tiles: TileRead[] = convertOldPosition(event.tiles, event.tile) + const groupedTiles = groupTiles(tiles) + + for (const [chunkPos, tiles] of groupedTiles) { + mapTilesUpdateDebounce( + surface, + chunkPos, + tiles, + (data => { + if (isEventType(event, defines.events.on_player_built_tile)) { + data.player = event.player_index + return + } + if (isEventType(event, defines.events.on_robot_built_tile)) { + data.robot = { + unitNumber: event.robot?.unit_number ?? null, + name: event.robot.name, + type: event.robot.type, + } + return + } + // this line will not compile if the previous 'if' statements are not exhaustive + // noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols + const exhaustiveCheck: never = event + } + ) + ) + } +} + +script.on_event(defines.events.on_player_built_tile, (e: OnPlayerBuiltTileEvent) => onBuildTileEvent(e)) +script.on_event(defines.events.on_robot_built_tile, (e: OnRobotBuiltTileEvent) => onBuildTileEvent(e)) + +// script.on_event( +// defines.events.on_player_mined_tile, +// (e: OnPlayerMinedTileEvent) => { +// // need to group tiles by ChunkPosition... +// +// } +// ) + +// script.on_event( +// defines.events.on_robot_mined_tile, +// (e: OnRobotMinedTileEvent) => { +// // need to group tiles by ChunkPosition... +// +// } +// ) + + +script.on_event( + defines.events.on_pre_chunk_deleted, + (e: OnPreChunkDeletedEvent) => { + + const surface = getSurface(e.surface_index) + if (surface == undefined) { + return + } + + for (const position of e.positions) { + const key: CacheKey<"MAP_CHUNK"> = { + surfaceIndex: surface.index, + chunkPosition: position, + updateType: "MAP_CHUNK", + } + + EventDataCache.debounce<"MAP_CHUNK">( + key, + data => { + data.isDeleted = true + } + ) + // deletion is important - emit ASAP + EventDataCache.setExpiration(key, 0) + } + } +) diff --git a/modules/events-mod/src/main/typescript/main/events/playerEvents.ts b/modules/events-mod/src/main/typescript/main/events/playerEvents.ts new file mode 100644 index 0000000..4cf49b0 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/events/playerEvents.ts @@ -0,0 +1,178 @@ +import {EventDataCache} from "../cache/EventDataCache"; +import {Converters} from "./converters"; +import CacheData = EventDataCache.CacheData; + +type PlayerUpdater = (player: LuaPlayer, data: CacheData<"PLAYER">) => void + +function playerUpdateThrottle( + playerIndex: uint, + mutate: PlayerUpdater, +) { + EventDataCache.throttle<"PLAYER">( + {index: playerIndex, updateType: "PLAYER"}, + (data => { + const player = game.players[playerIndex] + if (player != undefined) { + mutate(player, data) + } + }) + ) +} + +function playerUpdateDebounce(playerIndex: uint, mutate: PlayerUpdater) { + EventDataCache.debounce<"PLAYER">( + {index: playerIndex, updateType: "PLAYER"}, + (data => { + const player = game.players[playerIndex] + mutate(player, data) + }) + ) +} + +function playerOnlineInfo(player: LuaPlayer, data: CacheData<"PLAYER">) { + data.lastOnline = player.last_online + data.onlineTime = player.online_time + data.afkTime = player.afk_time + data.isConnected = player.connected +} + +script.on_event( + defines.events.on_player_joined_game, + (e: OnPlayerJoinedGameEvent) => { + playerUpdateThrottle( + e.player_index, + (player, data) => { + data.isAdmin = player.admin + data.characterUnitNumber = player.character?.unit_number + data.chatColour = Converters.mapColour(player.chat_color) + data.colour = Converters.mapColour(player.color) + data.forceIndex = player.force.index + data.name = player.name + data.isShowOnMap = player.show_on_map + data.isSpectator = player.spectator + data.tag = player.tag + playerOnlineInfo(player, data) + } + ) + } +) + +script.on_event( + defines.events.on_player_changed_position, + (e: OnPlayerChangedPositionEvent) => { + playerUpdateThrottle( + e.player_index, + (player, data) => { + data.position = player.position + } + ) + } +) + +script.on_event( + defines.events.on_player_changed_surface, + (e: OnPlayerChangedSurfaceEvent) => { + playerUpdateThrottle( + e.player_index, + (player, data) => { + data.position = player.position + data.surfaceIndex = player.surface.index + } + ) + } +) + +script.on_event( + defines.events.on_player_died, + (e: OnPlayerDiedEvent) => { + playerUpdateThrottle( + e.player_index, + (player, data) => { + data.ticksToRespawn = player.ticks_to_respawn + playerOnlineInfo(player, data) + if (e.cause != undefined) { + data.diedCause = { + unitNumber: e.cause.unit_number ?? null, + name: e.cause.name, + type: e.cause.type + } + } + } + ) + } +) + +script.on_event( + defines.events.on_player_banned, + (e: OnPlayerBannedEvent) => { + if (e.player_index != undefined) { + playerUpdateThrottle( + e.player_index, + (player, data) => { + data.bannedReason = e.reason + playerOnlineInfo(player, data) + } + ) + } + } +) + +script.on_event( + defines.events.on_player_unbanned, + (e: OnPlayerUnbannedEvent) => { + if (e.player_index != undefined) { + playerUpdateThrottle( + e.player_index, + (player, data) => { + data.bannedReason = e.reason + playerOnlineInfo(player, data) + } + ) + } + } +) + +script.on_event( + defines.events.on_player_kicked, + (e: OnPlayerKickedEvent) => { + playerUpdateThrottle( + e.player_index, + (player, data) => { + data.kickedReason = e.reason + playerOnlineInfo(player, data) + } + ) + } +) + + +const disconnectReasons = new LuaTable() +for (const [name, disconnectId] of pairs(defines.disconnect_reason)) { + disconnectReasons.set(disconnectId, name) +} + +script.on_event( + defines.events.on_pre_player_left_game, + (e: OnPrePlayerLeftGameEvent) => { + playerUpdateThrottle( + e.player_index, + (player, data) => { + data.disconnectReason = disconnectReasons.get(e.reason) + playerOnlineInfo(player, data) + } + ) + } +) + +script.on_event( + defines.events.on_player_removed, + (e: OnPlayerRemovedEvent) => { + playerUpdateThrottle( + e.player_index, + (player, data) => { + data.isRemoved = true + playerOnlineInfo(player, data) + } + ) + } +) diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index 61e4f60..339ce17 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -2,12 +2,12 @@ import { handleChunkUpdate, handleConsoleChat, handleEntityUpdate, - handlePlayerUpdate, + // handlePlayerUpdate, handleSurfaceUpdate, handleTilesUpdate } from "./handlers"; import {Queue} from "../queue/queue"; -import {EventName} from "../global"; +import {EventName} from "../types"; const mapEventIdToName = new LuaTable() @@ -32,24 +32,24 @@ script.on_event( defines.events.on_player_mined_entity, (e: OnPlayerMinedEntityEvent) => { let eventName = mapEventIdToName.get(e.name) - handlePlayerUpdate(e.tick, eventName, e.player_index) + // handlePlayerUpdate(e.tick, eventName, e.player_index) handleEntityUpdate(e.tick, eventName, e.entity) } ) -script.on_event( - defines.events.on_player_joined_game, - (e: OnPlayerJoinedGameEvent) => { - handlePlayerUpdate(e.tick, mapEventIdToName.get(e.name), e.player_index) - } -) +// script.on_event( +// defines.events.on_player_joined_game, +// (e: OnPlayerJoinedGameEvent) => { +// handlePlayerUpdate(e.tick, mapEventIdToName.get(e.name), e.player_index) +// } +// ) -script.on_event( - defines.events.on_player_changed_position, - (e: OnPlayerChangedPositionEvent) => { - handlePlayerUpdate(e.tick, mapEventIdToName.get(e.name), e.player_index) - } -) +// script.on_event( +// defines.events.on_player_changed_position, +// (e: OnPlayerChangedPositionEvent) => { +// handlePlayerUpdate(e.tick, mapEventIdToName.get(e.name), e.player_index) +// } +// ) script.on_event( defines.events.on_tick, @@ -113,12 +113,3 @@ script.on_event( ) } ) - - -function isEventType( - eventData: EventData, - type: ED extends CustomInputEvent ? string : EventId -): eventData is ED { - let id: EventId | string = eventData.name - return id == type -} diff --git a/modules/events-mod/src/main/typescript/main/global.d.ts b/modules/events-mod/src/main/typescript/main/global.d.ts index b8122e7..7a73643 100644 --- a/modules/events-mod/src/main/typescript/main/global.d.ts +++ b/modules/events-mod/src/main/typescript/main/global.d.ts @@ -2,11 +2,3 @@ declare const global: { MOD_VERSION: string FACTORIO_VERSION: string } - -export type EventName = keyof typeof defines.events - -type NonNullKeys = { - [P in keyof T]: null extends Exclude ? never : P -}[keyof T]; - -type ExcludeNullKeys = Pick> diff --git a/modules/events-mod/src/main/typescript/main/types.d.ts b/modules/events-mod/src/main/typescript/main/types.d.ts new file mode 100644 index 0000000..62198ea --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/types.d.ts @@ -0,0 +1,17 @@ +export type EventName = keyof typeof defines.events + + +/** Get all keys of `TYPE` that are not nullable. */ +type NonNullKeys = { + [KEY in keyof TYPE]: null extends Exclude ? never : KEY +}[keyof TYPE]; + + +/** Exclude all nullable keys from `TYPE`. */ +type ExcludeNullKeys = Pick> + + +/** Make all keys of `TYPE` non-nullable. */ +type NonNullableKeys = { + [KEY in keyof TYPE]: NonNullable; +} From 7481c8162ad9738f281e8ceea3992d128dfac19f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 22:30:56 +0100 Subject: [PATCH 218/629] fixing 'when' statements, tidying up some code, --- .../main/typescript/main/cache/cacheChecker.ts | 1 - .../kafkatorio/events/schema/kafkatorioPacket.kt | 2 +- .../dev/adamko/kafkatorio/events/schema/kt2ts.kt | 1 + .../processor/admin/KafkatorioKafkaAdmin.kt | 15 ++++++++++----- .../processor/topology/factorioServerPackets.kt | 3 ++- .../dev/adamko/kafkatorio/webmap/websockets.kt | 4 +++- 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts index 4404725..e0d918c 100644 --- a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts +++ b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts @@ -1,6 +1,5 @@ import {EventDataCache} from "./EventDataCache"; import {emitPacket} from "../emitKafkatorioPacket"; -// import { global } from "../global"; /** Every 0.1 seconds */ script.on_nth_tick(6, (nthTick: NthTickEventData) => { diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt index 7d852f1..be9bfef 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt @@ -52,7 +52,7 @@ object KafkatorioPacketJsonSerializer : JsonContentPolymorphicSerializer FactorioEvent.serializer() KafkatorioPacket.PacketType.CONFIG -> FactorioConfigurationUpdate.serializer() KafkatorioPacket.PacketType.PROTOTYPES -> FactorioPrototypes.serializer() - KafkatorioPacket.PacketType.UPDATE -> FactorioEventUpdatePacket.serializer() + KafkatorioPacket.PacketType.UPDATE -> FactorioEventUpdatePacket.serializer() } } } diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt index 6d6e492..a19221f 100644 --- a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt @@ -18,6 +18,7 @@ fun main(args: Array) { addAll(FactorioPrototype::class.sealedSubclasses) add(FactorioPrototypes::class) add(FactorioConfigurationUpdate::class) + add(FactorioEventUpdatePacket::class) addAll(FactorioEventUpdate::class.sealedSubclasses) }, mappings = mapOf( diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt index 2fdc3d4..a51916f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt @@ -33,17 +33,19 @@ object KafkatorioKafkaAdmin { add(KafkatorioTopology.TOPIC_GROUPED_MAP_CHUNKS) add(KafkatorioTopology.TOPIC_SRC_SERVER_LOG) + val base = topicNameBase(packetType) + when (packetType) { KafkatorioPacket.PacketType.EVENT -> FactorioObjectData.ObjectName.values.forEach { objectName -> - add("kafkatorio.${packetType.name}.${objectName.name}") + add("$base.${objectName.name}") } - KafkatorioPacket.PacketType.CONFIG -> - add("kafkatorio.${packetType.name}.FactorioConfigurationUpdate") - KafkatorioPacket.PacketType.PROTOTYPES -> - add("kafkatorio.${packetType.name}.all") + KafkatorioPacket.PacketType.CONFIG -> add("$base.FactorioConfigurationUpdate") + KafkatorioPacket.PacketType.PROTOTYPES -> add("$base.all") + KafkatorioPacket.PacketType.UPDATE -> add("$base.all") } + } }.minus(currentTopics.toSet()) @@ -87,4 +89,7 @@ object KafkatorioKafkaAdmin { .listings() .get() } + + fun topicNameBase(packetType: KafkatorioPacket.PacketType): String = + "kafkatorio.${packetType.name}" } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt index 9371f9f..7c1d8ef 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt @@ -6,6 +6,7 @@ import dev.adamko.kafkatorio.events.schema.FactorioEventUpdatePacket import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.processor.KafkatorioTopology +import dev.adamko.kafkatorio.processor.admin.KafkatorioKafkaAdmin import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.producedAs @@ -51,7 +52,7 @@ fun splitFactorioServerPacketStream( ) { _: FactorioServerId, value: KafkatorioPacket, _: RecordContext -> // println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") - val base = "kafkatorio.${value.packetType.name}" + val base = KafkatorioKafkaAdmin.topicNameBase(value.packetType) val type: String = when (value) { is FactorioEvent -> value.data.objectName.name diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt index ff1d9f1..9023676 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -4,10 +4,10 @@ import dev.adamko.kafkatorio.events.schema.ConsoleChatMessage import dev.adamko.kafkatorio.events.schema.EntityData import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.FactorioEventUpdatePacket import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.events.schema.MapChunk -import dev.adamko.kafkatorio.events.schema.MapTile import dev.adamko.kafkatorio.events.schema.MapTiles import dev.adamko.kafkatorio.events.schema.PlayerData import dev.adamko.kafkatorio.events.schema.SurfaceData @@ -52,8 +52,10 @@ class WebsocketService( } } } + is FactorioEventUpdatePacket, is FactorioConfigurationUpdate, is FactorioPrototypes -> { + // to be continued... } } From 3a92149424883c53613a73ab507d7e71578323b3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 22:31:13 +0100 Subject: [PATCH 219/629] version bump --- build.gradle.kts | 2 +- modules/events-mod/src/main/typescript/package-lock.json | 2 +- modules/events-mod/src/main/typescript/package.json | 2 +- modules/infra-factorio-server/src/.env | 2 +- modules/infra-kafka-cluster/src/.env | 2 +- modules/infra-kafka-pipe/src/.env | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index abd2597..5ce154b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.2.10" +version = "0.3.0" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index b901f4a..a065da6 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.10", + "version": "0.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 66c3a39..973f8aa 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.2.10", + "version": "0.3.0", "private": true, "scripts": { "build": "tstl", diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index 844cf24..63ff5e8 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio FACTORIO_VERSION=1.1.53 -KAFKATORIO_VERSION=0.2.10 +KAFKATORIO_VERSION=0.3.0 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index 7e3cb8d..869256f 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.2.10 +KAFKATORIO_VERSION=0.3.0 diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index 7e3cb8d..869256f 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.2.10 +KAFKATORIO_VERSION=0.3.0 From 8dff124a71045cf23bda4f545ba5a2f8be1bcfd9 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 20 Feb 2022 23:38:44 +0100 Subject: [PATCH 220/629] fix tstl task --- buildSrc/build.gradle.kts | 2 +- .../kafkatorio/task/TypescriptToLuaTask.kt | 16 +++------------- modules/events-mod/build.gradle.kts | 11 +++++++++++ .../events-mod/src/main/typescript/package.json | 12 ++++-------- 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 91135ae..4e68cf3 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -14,7 +14,7 @@ object Versions { // const val kotlin = "1.6.20-M1" const val kotlin = "1.6.10" - const val gradleNodePlugin = "3.2.0" + const val gradleNodePlugin = "3.2.1" const val gradleDockerComposePlugin = "0.15.0" const val kotlinXSerialization = "1.3.2" diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt index 3c6f797..0aaa4cb 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt @@ -4,7 +4,7 @@ import com.github.gradle.node.npm.task.NpmTask import org.gradle.api.file.DirectoryProperty import org.gradle.api.plugins.BasePlugin import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.PathSensitive import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.SkipWhenEmpty @@ -17,7 +17,7 @@ abstract class TypescriptToLuaTask : NpmTask() { @get:PathSensitive(PathSensitivity.RELATIVE) abstract val sourceFiles: DirectoryProperty - @get:OutputFile + @get:OutputDirectory abstract val outputDirectory: DirectoryProperty @@ -26,18 +26,8 @@ abstract class TypescriptToLuaTask : NpmTask() { super.setDescription("Convert Typescript To Lua") super.execOverrides { standardOutput = System.out } super.npmCommand.set(listOf("run", "build")) - super.args.set(parseSpaceSeparatedArgs("-- --outDir $temporaryDir")) super.ignoreExitValue.set(false) - super.doFirst("cleanTemporaryDir") { - project.delete(temporaryDir) - project.mkdir(temporaryDir) - } - super.doLast("syncTstlOutput") { - project.sync { - from(temporaryDir) - into(outputDirectory) - } - } + super.args.set(parseSpaceSeparatedArgs("-- --outDir $temporaryDir")) } } diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 73e8687..3fb9ec1 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -59,6 +59,17 @@ val typescriptToLua by tasks.registering(TypescriptToLuaTask::class) { sourceFiles.set(tsSrcDir) outputDirectory.set(layout.buildDirectory.dir("typescriptToLua")) + + doFirst("cleanTemporaryDir") { + delete(temporaryDir) + mkdir(temporaryDir) + } + doLast("syncTstlOutput") { + sync { + from(temporaryDir) + into(outputDirectory) + } + } } val installEventsTsSchema by tasks.registering(Sync::class) { diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 973f8aa..a14305b 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -9,8 +9,7 @@ "engines": { "node": ">=10.13.0" }, - "devDependencies": { - }, + "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", @@ -19,10 +18,7 @@ "typescript": "4.5.5" }, "license": "UNLICENSED", - "peerDependencies": { - }, - "optionalDependencies": { - }, - "bundledDependencies": [ - ] + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] } From 494913d3b9cda53c22cfd06dda49622575724a29 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 21 Feb 2022 15:36:12 +0100 Subject: [PATCH 221/629] fix init of global vars, make MapTile DTO more concise, and version bump --- build.gradle.kts | 2 +- .../events-mod/src/main/typescript/control.ts | 39 ++++++++++-- .../generated/kafkatorio-schema/schema.d.ts | 5 +- .../typescript/main/cache/EventDataCache.ts | 16 ++--- .../typescript/main/cache/cacheChecker.ts | 20 ++++--- .../handleConfigurationUpdate.ts | 8 +-- .../main/config-update/prototypes.ts | 4 +- .../main/config-update/updateGlobal.ts | 4 -- .../main/typescript/main/events/converters.ts | 5 +- .../main/typescript/main/events/handlers.ts | 5 +- .../main/events/registerHandlers.ts | 59 ++++++++----------- .../src/main/typescript/package-lock.json | 2 +- .../src/main/typescript/package.json | 14 +++-- .../src/main/typescript/tsconfig.json | 2 +- .../events/schema/factorioCommonData.kt | 5 +- .../events/schema/factorioPrototypes.kt | 2 +- .../events/schema/FactorioEventTest.kt | 52 ++++++++-------- .../processor/topology/groupMapChunks.kt | 4 ++ .../processor/topology/prototypes.kt | 9 +-- modules/infra-factorio-server/src/.env | 2 +- modules/infra-kafka-cluster/src/.env | 2 +- modules/infra-kafka-pipe/src/.env | 2 +- 22 files changed, 137 insertions(+), 126 deletions(-) delete mode 100644 modules/events-mod/src/main/typescript/main/config-update/updateGlobal.ts diff --git a/build.gradle.kts b/build.gradle.kts index 5ce154b..60b1341 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.3.0" +version = "0.3.2" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index 296e0ce..f97e909 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -1,15 +1,44 @@ -import {handleConfigurationUpdate} from "./main/config-update/handleConfigurationUpdate"; +import {emitConfigurationUpdate} from "./main/config-update/handleConfigurationUpdate"; import {emitPrototypes} from "./main/config-update/prototypes"; import {Queue} from "./main/queue/queue"; import {EventDataCache} from "./main/cache/EventDataCache"; require("./main/events/registerHandlers") require("./main/commands/kafkatorioCommands") +require("./main/cache/cacheChecker") + +script.on_configuration_changed((data: ConfigurationChangedData) => { + // runs whenever the version of the base game, or a mod, changes + + reInitGlobal() + emitConfigurationUpdate(data) + emitPrototypes() +}) -script.on_configuration_changed(handleConfigurationUpdate) script.on_init(() => { - Queue.reset() - emitPrototypes() - EventDataCache.init() + // runs only once (when the mod is first added to the save) + initGlobal() }) + + +function initGlobal() { + log("Initialising Kafkatorio Global variables...") + + Queue.init() + EventDataCache.init() + + log("Finished initialising Kafkatorio Global variables") +} + +function reInitGlobal() { + log("Re-initialising Kafkatorio Global variables...") + + global.MOD_VERSION = script.active_mods[script.mod_name] + global.FACTORIO_VERSION = script.active_mods["base"] + + Queue.reset() + EventDataCache.reset() + + log("Finished re-initialising Kafkatorio Global variables") +} diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts index 41a6c66..e200e6e 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts @@ -89,8 +89,9 @@ interface MapChunkPosition { } interface MapTile { - position: MapTilePosition; - prototypeName: string; + proto: string; + x: int; + y: int; } interface EntityIdentifiers { diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts index 7c9225a..4caddfa 100644 --- a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts +++ b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts @@ -5,20 +5,20 @@ export namespace EventDataCache { declare const global: { cache: LuaTable, CacheEntry>, - DEFAULT_CACHE_DURATION_TICKS: LuaTable, DEFAULT_CACHE_DURATION_TICKS2: Record, - MAP_CHUNK_CACHE_DURATION_TICKS: uint, + } + + + export function reset() { + log("Resetting EventDataCache") + global.cache = new LuaTable, CacheEntry>() } export function init() { if (typeof global.cache == undefined) { - global.cache = new LuaTable, CacheEntry>() - - global.DEFAULT_CACHE_DURATION_TICKS = new LuaTable() - global.DEFAULT_CACHE_DURATION_TICKS.set("PLAYER", 30) // 0.5 seconds - global.DEFAULT_CACHE_DURATION_TICKS.set("MAP_CHUNK", 60 * 15) // ~ 15 seconds - global.DEFAULT_CACHE_DURATION_TICKS.set("ENTITY", 60 * 2) // ~2 seconds + log("Initialising EventDataCache") + reset() global.DEFAULT_CACHE_DURATION_TICKS2 = { "PLAYER": 30, // 0.5 seconds diff --git a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts index e0d918c..119046d 100644 --- a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts +++ b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts @@ -6,16 +6,20 @@ script.on_nth_tick(6, (nthTick: NthTickEventData) => { const cachedEvents: Array> = EventDataCache.extractExpired() - for (const event of cachedEvents) { + if (cachedEvents.length > 0) { + log(`nth tick ${nthTick.tick} has ${cachedEvents.length} events`) - const packet: FactorioEventUpdatePacket = { - tick: nthTick.tick, - modVersion: global.MOD_VERSION, - packetType: "UPDATE", - update: event, + for (const event of cachedEvents) { + + const packet: FactorioEventUpdatePacket = { + tick: nthTick.tick, + modVersion: global.MOD_VERSION, + packetType: "UPDATE", + update: event, + } + + emitPacket(packet) } - - emitPacket(packet) } }) diff --git a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts index 8bb456f..dab8aef 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts @@ -1,10 +1,6 @@ import {emitPacket} from "../emitKafkatorioPacket"; -import {updateGlobal} from "./updateGlobal"; -import {emitPrototypes} from "./prototypes"; -import {Queue} from "../queue/queue"; -export function handleConfigurationUpdate(changeData: ConfigurationChangedData) { - updateGlobal() +export function emitConfigurationUpdate(changeData: ConfigurationChangedData) { emitPacket({ modVersion: global.MOD_VERSION, @@ -13,8 +9,6 @@ export function handleConfigurationUpdate(changeData: ConfigurationChangedData) factorioData: factorioData(changeData) }) - Queue.reset() - emitPrototypes() } function factorioData(changeData: ConfigurationChangedData): FactorioGameDataUpdate { diff --git a/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts b/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts index 8b494da..d4d2bfe 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts @@ -1,6 +1,6 @@ import {Converters} from "../events/converters"; import {emitPacket} from "../emitKafkatorioPacket"; -// import { global } from "../global"; + export function emitPrototypes() { emitPacket({ @@ -20,7 +20,7 @@ function prototypes(): FactorioPrototype[] { function getMapTilePrototypes(): MapTilePrototype[] { let tiles: MapTilePrototype[] = [] - for (let [, tile] of pairs(game.tile_prototypes)) { + for (let [, tile] of game.tile_prototypes) { tiles.push( { prototypeObjectName: tile.object_name, diff --git a/modules/events-mod/src/main/typescript/main/config-update/updateGlobal.ts b/modules/events-mod/src/main/typescript/main/config-update/updateGlobal.ts deleted file mode 100644 index c81be94..0000000 --- a/modules/events-mod/src/main/typescript/main/config-update/updateGlobal.ts +++ /dev/null @@ -1,4 +0,0 @@ -export function updateGlobal() { - global.MOD_VERSION = script.active_mods[script.mod_name] - global.FACTORIO_VERSION = script.active_mods["base"] -} diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index 7acecb2..b4bc12d 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -99,8 +99,9 @@ export namespace Converters { export function convertTile(tile: LuaTile): MapTile { return { - position: mapTilePosition(tile.position), - prototypeName: tile.prototype.name, + x: tile.position.x, + y: tile.position.y, + proto: tile.prototype.name, } } diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index 2feb68c..5fffc85 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -92,8 +92,9 @@ export function handleTilesUpdate( let convertedTiles: MapTile[] = updatedTiles.map((it) => { return { - position: it.position, // TODO use converters for LuaTile - prototypeName: newTileType.name, + x: it.position.x, + y: it.position.y, + proto: newTileType.name } }) diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index 339ce17..763aae5 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -2,9 +2,8 @@ import { handleChunkUpdate, handleConsoleChat, handleEntityUpdate, - // handlePlayerUpdate, handleSurfaceUpdate, - handleTilesUpdate + // handleTilesUpdate } from "./handlers"; import {Queue} from "../queue/queue"; import {EventName} from "../types"; @@ -15,18 +14,6 @@ for (const [eventName, eventId] of pairs(defines.events)) { mapEventIdToName.set(eventId, eventName) } -// const mapEventIdToDefinedType = new LuaTable, EventId>() -// for (const [eventName, eventId] of pairs(defines.events)) { -// let definedType = defines.events[eventName] -// mapEventIdToDefinedType.set(eventId, definedType) -// } - -// script.on_event( -// [defines.events.on_pre_build, defines.events.on_player_dropped_item], -// (e: OnPreBuildEvent | OnPlayerDroppedItemEvent) => { -// game.print("player " + e.player_index + " dropped item, tick:" + e.tick) -// } -// ); script.on_event( defines.events.on_player_mined_entity, @@ -91,25 +78,25 @@ script.on_event( } ) -script.on_event( - defines.events.on_chunk_generated, - (e: OnChunkGeneratedEvent) => { - handleChunkUpdate(e.tick, mapEventIdToName.get(e.name), e.surface.index, e.position, e.area) - } -) - -script.on_event( - [ - defines.events.on_player_built_tile, - defines.events.on_robot_built_tile, - ], - (builtTilesEvent) => { - handleTilesUpdate( - builtTilesEvent.tick, - mapEventIdToName.get(builtTilesEvent.name), - builtTilesEvent.surface_index, - builtTilesEvent.tile, - builtTilesEvent.tiles, - ) - } -) +// script.on_event( +// defines.events.on_chunk_generated, +// (e: OnChunkGeneratedEvent) => { +// handleChunkUpdate(e.tick, mapEventIdToName.get(e.name), e.surface.index, e.position, e.area) +// } +// ) +// +// script.on_event( +// [ +// defines.events.on_player_built_tile, +// defines.events.on_robot_built_tile, +// ], +// (builtTilesEvent) => { +// handleTilesUpdate( +// builtTilesEvent.tick, +// mapEventIdToName.get(builtTilesEvent.name), +// builtTilesEvent.surface_index, +// builtTilesEvent.tile, +// builtTilesEvent.tiles, +// ) +// } +// ) diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index a065da6..c8fc916 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.3.0", + "version": "0.3.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index a14305b..90084ae 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.3.0", + "version": "0.3.2", "private": true, "scripts": { "build": "tstl", @@ -9,7 +9,8 @@ "engines": { "node": ">=10.13.0" }, - "devDependencies": {}, + "devDependencies": { + }, "dependencies": { "lua-types": "^2.11.0", "@types/node": "^12.0.8", @@ -18,7 +19,10 @@ "typescript": "4.5.5" }, "license": "UNLICENSED", - "peerDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": [] + "peerDependencies": { + }, + "optionalDependencies": { + }, + "bundledDependencies": [ + ] } diff --git a/modules/events-mod/src/main/typescript/tsconfig.json b/modules/events-mod/src/main/typescript/tsconfig.json index 87b2667..e7fb1ff 100644 --- a/modules/events-mod/src/main/typescript/tsconfig.json +++ b/modules/events-mod/src/main/typescript/tsconfig.json @@ -34,6 +34,6 @@ "tstlVerbose": true, "noHeader": true, "noImplicitSelf": true, - "luaLibImport": "inline" + "luaLibImport": "require" } } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index 0ce9fe3..3ea33fd 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -98,8 +98,9 @@ data class ColourHex( @Serializable data class MapTile( - val prototypeName: PrototypeName, - val position: MapTilePosition, + val x: Int, + val y: Int, + val proto: PrototypeName, ) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt index 0cce79d..0fb80b2 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt @@ -64,7 +64,7 @@ object FactorioPrototypeJsonSerializer : JsonContentPolymorphicSerializer Date: Wed, 23 Feb 2022 11:51:15 +0100 Subject: [PATCH 222/629] - make each event update have a key/data interface - separate .d.ts file for event updates - fix initialisation of global items --- .../events-mod/src/main/typescript/control.ts | 31 +-- .../kafkatorio-schema/object-data.d.ts | 27 +++ .../generated/kafkatorio-schema/schema.d.ts | 93 --------- .../generated/kafkatorio-schema/update.d.ts | 134 +++++++++++++ .../typescript/main/cache/EventDataCache.ts | 84 ++++---- .../typescript/main/cache/cacheChecker.ts | 33 +--- .../main/commands/kafkatorioCommands.ts | 19 +- .../typescript/main/events/eventTypeCheck.ts | 2 +- .../main/typescript/main/events/mapEvents.ts | 27 ++- .../main/events/registerHandlers.ts | 1 + .../src/main/typescript/main/global-init.ts | 15 ++ .../src/main/typescript/main/queue/queue.ts | 31 +-- .../events/schema/factorioEventUpdates.kt | 187 +++++++++++++----- .../adamko/kafkatorio/events/schema/kt2ts.kt | 33 +++- 14 files changed, 451 insertions(+), 266 deletions(-) create mode 100644 modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts create mode 100644 modules/events-mod/src/main/typescript/main/global-init.ts diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index f97e909..13ddeb1 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -1,16 +1,17 @@ import {emitConfigurationUpdate} from "./main/config-update/handleConfigurationUpdate"; import {emitPrototypes} from "./main/config-update/prototypes"; -import {Queue} from "./main/queue/queue"; -import {EventDataCache} from "./main/cache/EventDataCache"; +import {initGlobal} from "./main/global-init"; require("./main/events/registerHandlers") +require("./main/events/playerEvents") +require("./main/events/mapEvents") require("./main/commands/kafkatorioCommands") require("./main/cache/cacheChecker") script.on_configuration_changed((data: ConfigurationChangedData) => { // runs whenever the version of the base game, or a mod, changes - reInitGlobal() + initGlobal(true) emitConfigurationUpdate(data) emitPrototypes() }) @@ -18,27 +19,5 @@ script.on_configuration_changed((data: ConfigurationChangedData) => { script.on_init(() => { // runs only once (when the mod is first added to the save) - initGlobal() + initGlobal(true) }) - - -function initGlobal() { - log("Initialising Kafkatorio Global variables...") - - Queue.init() - EventDataCache.init() - - log("Finished initialising Kafkatorio Global variables") -} - -function reInitGlobal() { - log("Re-initialising Kafkatorio Global variables...") - - global.MOD_VERSION = script.active_mods[script.mod_name] - global.FACTORIO_VERSION = script.active_mods["base"] - - Queue.reset() - EventDataCache.reset() - - log("Finished re-initialising Kafkatorio Global variables") -} diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts index 9313d83..62bb0c4 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts @@ -6,6 +6,33 @@ interface FactorioObjectData { objectName: ObjectName; } +interface PlayerData extends FactorioObjectData, FactorioLuaControl { + associatedCharactersUnitNumbers: uint[]; + characterUnitNumber: uint | null; + chatColour: Colour; + colour: Colour; + force: uint; + lastOnline: uint; + name: string; + objectName: ObjectName; + position: MapEntityPosition; + surface: uint; +} + +interface EntityData extends FactorioObjectData, FactorioLuaControl { + active: boolean; + force: uint; + health: double | null; + healthRatio: double; + name: string; + objectName: ObjectName; + playerIndex: uint | null; + position: MapEntityPosition; + surface: uint; + type: string; + unitNumber: uint | null; +} + interface SurfaceData extends FactorioObjectData { daytime: double; index: uint; diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts index e200e6e..ca76f05 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts @@ -7,19 +7,6 @@ interface KafkatorioPacket { packetType: PacketType; } -type FactorioEventUpdateType = "PLAYER" | "MAP_CHUNK" | "ENTITY"; - -interface FactorioEventUpdate { - updateType: FactorioEventUpdateType; -} - -interface FactorioEventUpdatePacket extends KafkatorioPacket { - modVersion: string; - packetType: PacketType; - tick: uint; - update: FactorioEventUpdate; -} - interface FactorioEvent extends KafkatorioPacket { data: FactorioObjectData; eventType: string; @@ -46,33 +33,6 @@ interface Colour { red: float; } -interface PlayerData extends FactorioObjectData, FactorioLuaControl { - associatedCharactersUnitNumbers: uint[]; - characterUnitNumber: uint | null; - chatColour: Colour; - colour: Colour; - force: uint; - lastOnline: uint; - name: string; - objectName: ObjectName; - position: MapEntityPosition; - surface: uint; -} - -interface EntityData extends FactorioObjectData, FactorioLuaControl { - active: boolean; - force: uint; - health: double | null; - healthRatio: double; - name: string; - objectName: ObjectName; - playerIndex: uint | null; - position: MapEntityPosition; - surface: uint; - type: string; - unitNumber: uint | null; -} - interface MapTilePosition { x: int; y: int; @@ -99,56 +59,3 @@ interface EntityIdentifiers { type: string; unitNumber: uint | null; } - -interface PlayerUpdate extends FactorioEventUpdate { - afkTime: uint | null; - bannedReason: string | null; - characterUnitNumber: uint | null; - chatColour: Colour | null; - colour: Colour | null; - diedCause: EntityIdentifiers | null; - disconnectReason: string | null; - forceIndex: uint | null; - index: uint; - isAdmin: boolean | null; - isConnected: boolean | null; - isRemoved: boolean | null; - isShowOnMap: boolean | null; - isSpectator: boolean | null; - kickedReason: string | null; - lastOnline: uint | null; - name: string | null; - onlineTime: uint | null; - position: MapEntityPosition | null; - surfaceIndex: uint | null; - tag: string | null; - ticksToRespawn: uint | null; - updateType: FactorioEventUpdateType; -} - -interface EntityUpdate extends FactorioEventUpdate, EntityIdentifiers { - chunkPosition: MapChunkPosition | null; - graphicsVariation: number | null; - health: float | null; - isActive: boolean | null; - isRotatable: boolean | null; - lastUser: int | null; - localisedDescription: string | null; - localisedName: string | null; - name: string; - prototype: string | null; - type: string; - unitNumber: uint; - updateType: FactorioEventUpdateType; -} - -interface MapChunkUpdate extends FactorioEventUpdate { - chunkPosition: MapChunkPosition; - force: uint | null; - isDeleted: boolean | null; - player: uint | null; - robot: EntityIdentifiers | null; - surfaceIndex: uint; - tiles: Map | null; - updateType: FactorioEventUpdateType; -} diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts new file mode 100644 index 0000000..1d6898d --- /dev/null +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts @@ -0,0 +1,134 @@ +// Generated by TypeScriptGenerator - do not edit this file manually + +type FactorioEventUpdateType = "PLAYER" | "MAP_CHUNK" | "ENTITY"; + +interface FactorioEventUpdateKey { + updateType: FactorioEventUpdateType; +} + +interface FactorioEventUpdateData { + updateType: FactorioEventUpdateType; +} + +interface FactorioEventUpdate extends FactorioEventUpdateKey, FactorioEventUpdateData { + updateType: FactorioEventUpdateType; +} + +interface FactorioEventUpdatePacket extends KafkatorioPacket { + modVersion: string; + packetType: PacketType; + tick: uint; + update: FactorioEventUpdate; +} + +interface PlayerUpdateKey extends FactorioEventUpdateKey { + index: uint; +} + +interface PlayerUpdateData extends FactorioEventUpdateData { + afkTime: uint | null; + bannedReason: string | null; + characterUnitNumber: uint | null; + chatColour: Colour | null; + colour: Colour | null; + diedCause: EntityIdentifiers | null; + disconnectReason: string | null; + forceIndex: uint | null; + isAdmin: boolean | null; + isConnected: boolean | null; + isRemoved: boolean | null; + isShowOnMap: boolean | null; + isSpectator: boolean | null; + kickedReason: string | null; + lastOnline: uint | null; + name: string | null; + onlineTime: uint | null; + position: MapEntityPosition | null; + surfaceIndex: uint | null; + tag: string | null; + ticksToRespawn: uint | null; +} + +interface PlayerUpdate extends FactorioEventUpdate, PlayerUpdateKey, PlayerUpdateData { + afkTime: uint | null; + bannedReason: string | null; + characterUnitNumber: uint | null; + chatColour: Colour | null; + colour: Colour | null; + diedCause: EntityIdentifiers | null; + disconnectReason: string | null; + forceIndex: uint | null; + index: uint; + isAdmin: boolean | null; + isConnected: boolean | null; + isRemoved: boolean | null; + isShowOnMap: boolean | null; + isSpectator: boolean | null; + kickedReason: string | null; + lastOnline: uint | null; + name: string | null; + onlineTime: uint | null; + position: MapEntityPosition | null; + surfaceIndex: uint | null; + tag: string | null; + ticksToRespawn: uint | null; + updateType: FactorioEventUpdateType; +} + +interface EntityUpdateKey extends EntityIdentifiers, FactorioEventUpdateKey { + name: string; + type: string; + unitNumber: uint; +} + +interface EntityUpdateData extends FactorioEventUpdateData { + chunkPosition: MapChunkPosition | null; + graphicsVariation: number | null; + health: float | null; + isActive: boolean | null; + isRotatable: boolean | null; + lastUser: int | null; + localisedDescription: string | null; + localisedName: string | null; + prototype: string | null; +} + +interface EntityUpdate extends FactorioEventUpdate, EntityIdentifiers, EntityUpdateKey, EntityUpdateData { + chunkPosition: MapChunkPosition | null; + graphicsVariation: number | null; + health: float | null; + isActive: boolean | null; + isRotatable: boolean | null; + lastUser: int | null; + localisedDescription: string | null; + localisedName: string | null; + name: string; + prototype: string | null; + type: string; + unitNumber: uint; + updateType: FactorioEventUpdateType; +} + +interface MapChunkUpdateKey extends FactorioEventUpdateKey { + chunkPosition: MapChunkPosition; + surfaceIndex: uint; +} + +interface MapChunkUpdateData extends FactorioEventUpdateData { + force: uint | null; + isDeleted: boolean | null; + player: uint | null; + robot: EntityIdentifiers | null; + tiles: MapTile[] | null; +} + +interface MapChunkUpdate extends FactorioEventUpdate, MapChunkUpdateKey, MapChunkUpdateData { + chunkPosition: MapChunkPosition; + force: uint | null; + isDeleted: boolean | null; + player: uint | null; + robot: EntityIdentifiers | null; + surfaceIndex: uint; + tiles: MapTile[] | null; + updateType: FactorioEventUpdateType; +} diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts index 4caddfa..a26e5b1 100644 --- a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts +++ b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts @@ -1,32 +1,34 @@ -import {ExcludeNullKeys, NonNullableKeys} from "../types"; +import {NonNullableKeys} from "../types"; export namespace EventDataCache { declare const global: { cache: LuaTable, CacheEntry>, - DEFAULT_CACHE_DURATION_TICKS2: Record, + defaultCacheDurationTicks: Record, } - export function reset() { - log("Resetting EventDataCache") - global.cache = new LuaTable, CacheEntry>() - } + export function init(force?: boolean) { + const isAnythingUndefined = global.cache == undefined || + global.defaultCacheDurationTicks == undefined - export function init() { - if (typeof global.cache == undefined) { - log("Initialising EventDataCache") - reset() + log(`Initialising EventDataCache (force=${force}, isAnythingUndefined=${isAnythingUndefined})...`) - global.DEFAULT_CACHE_DURATION_TICKS2 = { - "PLAYER": 30, // 0.5 seconds - "MAP_CHUNK": 60 * 15, // ~ 15 seconds - "ENTITY": 60 * 2, // ~2 seconds - "default": 60 + if (force == true || isAnythingUndefined) { + log("Initialising global.cache") + global.cache = new LuaTable, CacheEntry>() + + log("Initialising global.DEFAULT_CACHE_DURATION_TICKS") + global.defaultCacheDurationTicks = { + "PLAYER": 60, // 1 second + "MAP_CHUNK": 60 * 30, // 30 seconds + "ENTITY": 60 * 2, // 2 seconds + "default": 60 * 5, // 5 seconds } } + log(`Finished initialising EventDataCache`) } @@ -73,7 +75,7 @@ export namespace EventDataCache { */ export function setExpiration( key: CacheKey, - expirationDurationTicks?: uint, + expirationDurationTicks: uint, ) { const entry = getCacheEntry(key) if (entry != undefined) { @@ -82,11 +84,12 @@ export namespace EventDataCache { } - export function extractExpired(): Array> { - const expiredData: Array> = [] + export function extractExpired(): Array { + const expiredData: Array = [] for (let [key, entry] of global.cache) { - if (entry.isExpired()) { - expiredData.push(entry.data) + if (isExpired(entry)) { + const update: FactorioEventUpdate = {...key, ...entry.data} + expiredData.push(update) global.cache.delete(key) } } @@ -114,7 +117,7 @@ export namespace EventDataCache { key: CacheKey, mutate: CacheDataMutator, ): CacheEntry { - // @ts-ignore // TODO remove ts-ignore for "not assignable to type" + // @ts-ignore // TODO resolve ts-ignore for "not assignable to type" const data: CacheData = {updateType: key.updateType} mutate(data) let entry: CacheEntry = new CacheEntry(data) @@ -123,24 +126,35 @@ export namespace EventDataCache { } - /** Map a {@link FactorioEventUpdateType} to a {@link FactorioEventUpdate} DTO */ - type ConvertUpdateType = - TYPE extends "PLAYER" ? PlayerUpdate : - TYPE extends "MAP_CHUNK" ? MapChunkUpdate : - TYPE extends "ENTITY" ? EntityUpdate : + // /** Map a {@link FactorioEventUpdateType} to a {@link FactorioEventUpdate} DTO */ + // type ConvertUpdateType = + // TYPE extends "PLAYER" ? PlayerUpdate : + // TYPE extends "MAP_CHUNK" ? MapChunkUpdate : + // TYPE extends "ENTITY" ? EntityUpdate : + // never + + type ConvertKeyType = + TYPE extends "PLAYER" ? PlayerUpdateKey : + TYPE extends "MAP_CHUNK" ? MapChunkUpdateKey : + TYPE extends "ENTITY" ? EntityUpdateKey : + never + type ConvertKeyData = + TYPE extends "PLAYER" ? PlayerUpdateData : + TYPE extends "MAP_CHUNK" ? MapChunkUpdateData : + TYPE extends "ENTITY" ? EntityUpdateData : never /** Only include the non-null properties, and make `updateType` specific */ export type CacheKey = CacheTyped - & Omit>, "updateType"> + & Omit, "updateType"> /** Exclude {@link CacheKey} fields, and make `updateType` specific */ export type CacheData = CacheTyped - & NonNullableKeys, keyof CacheKey | "updateType">>> + & NonNullableKeys, "updateType">>> export type CacheTyped = { @@ -163,17 +177,15 @@ export namespace EventDataCache { expirationDurationTicks?: uint, ) { this.data = data - if (expirationDurationTicks != undefined) { - this.expirationDurationTicks = expirationDurationTicks - } + this.expirationDurationTicks = expirationDurationTicks } + } - isExpired(): boolean { - const cacheDuration = - this.expirationDurationTicks ?? global.DEFAULT_CACHE_DURATION_TICKS2[this.data.updateType] - return game.tick - this.lastUpdatedTick > cacheDuration - } + function isExpired(entry: CacheEntry): boolean { + const expiryDuration = + entry.expirationDurationTicks ?? global.defaultCacheDurationTicks[entry.data.updateType] + return game.tick - entry.lastUpdatedTick > expiryDuration } diff --git a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts index 119046d..9a7e056 100644 --- a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts +++ b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts @@ -4,7 +4,7 @@ import {emitPacket} from "../emitKafkatorioPacket"; /** Every 0.1 seconds */ script.on_nth_tick(6, (nthTick: NthTickEventData) => { - const cachedEvents: Array> = EventDataCache.extractExpired() + const cachedEvents: Array = EventDataCache.extractExpired() if (cachedEvents.length > 0) { log(`nth tick ${nthTick.tick} has ${cachedEvents.length} events`) @@ -22,34 +22,3 @@ script.on_nth_tick(6, (nthTick: NthTickEventData) => { } } }) - -// -// function createEntityUpdate(cacheKey: EntityCacheKey, events: EventName[]): EntityUpdate | null { -// -// -// return null -// } -// -// interface EntityUpdate { -// name: string -// -// unit_number: uint -// -// unhandledEvents?: string[] -// -// chunkPosition: MapChunkPosition -// graphics_variation?: uint8 -// health?: float -// isActive?: boolean -// isRotatable?: boolean -// last_user?: uint -// localised_description?: string -// localised_name?: string -// prototype?: string -// -// // ghost_localised_description?: string -// // ghost_localised_name?: string -// // ghost_name?: string -// // ghost_prototype?: string -// // ghost_unit_number?: uint -// } diff --git a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts index 3cc2c79..9b5faba 100644 --- a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts +++ b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts @@ -1,5 +1,6 @@ import {emitPrototypes} from "../config-update/prototypes"; import {Queue} from "../queue/queue"; +import {initGlobal} from "../global-init"; import floor = math.floor; @@ -8,18 +9,20 @@ commands.add_command( "kafkatorio innit bruv", (e: CustomCommandData) => { - let player = (e.player_index != null) ? game.get_player(e.player_index) : null + const player = (e.player_index != null) ? game.get_player(e.player_index) : null - if (e.parameter == undefined) { + const paramUppercase = e.parameter?.toUpperCase() + + if (paramUppercase == undefined) { if (player != null) { player.print("no parameter") } // do nothing - } else if ("PROTOTYPES" == e.parameter.toUpperCase()) { + } else if ("PROTOTYPES" == paramUppercase) { emitPrototypes() - } else if (e.parameter.toUpperCase().startsWith("CHUNKS")) { + } else if (paramUppercase.startsWith("CHUNKS")) { - let size = e.parameter.split(" ")?.[1] ?? null + let size = paramUppercase.split(" ")?.[1] ?? null let radius = (size != null) ? parseInt(size) : 1 if (e.player_index != undefined) { @@ -60,10 +63,8 @@ commands.add_command( } } } - } else if ("QUEUE_RESET" == e.parameter.toUpperCase()) { - Queue.reset() - } else if ("QUEUE_INIT" == e.parameter.toUpperCase()) { - Queue.init() + } else if (paramUppercase.startsWith("INIT_GLOBAL")) { + initGlobal(paramUppercase.startsWith("INIT_GLOBAL FORCE")) } } ) diff --git a/modules/events-mod/src/main/typescript/main/events/eventTypeCheck.ts b/modules/events-mod/src/main/typescript/main/events/eventTypeCheck.ts index e3769f2..4321eb3 100644 --- a/modules/events-mod/src/main/typescript/main/events/eventTypeCheck.ts +++ b/modules/events-mod/src/main/typescript/main/events/eventTypeCheck.ts @@ -1,5 +1,5 @@ -function isEventType( +export function isEventType( eventData: EventData, type: ED extends CustomInputEvent ? string : EventId ): eventData is ED { diff --git a/modules/events-mod/src/main/typescript/main/events/mapEvents.ts b/modules/events-mod/src/main/typescript/main/events/mapEvents.ts index 5744703..bb8b58c 100644 --- a/modules/events-mod/src/main/typescript/main/events/mapEvents.ts +++ b/modules/events-mod/src/main/typescript/main/events/mapEvents.ts @@ -1,4 +1,5 @@ import {EventDataCache} from "../cache/EventDataCache"; +import {isEventType} from "./eventTypeCheck"; import CacheKey = EventDataCache.CacheKey; import CacheData = EventDataCache.CacheData; @@ -24,12 +25,17 @@ function mapTilesUpdateDebounce( }, data => { if (data.tiles == undefined) { - data.tiles = new Map() + data.tiles = [] } for (const tile of tiles) { - const position: MapTilePosition = {x: tile.position.x, y: tile.position.y} - data.tiles.set(position, tile.name) + data.tiles.push( + { + x: tile.position.x, + y: tile.position.y, + proto: tile.name, + } + ) } if (updater != undefined) { @@ -58,6 +64,8 @@ function getSurface(surfaceIndex: uint): LuaSurface | undefined { script.on_event( defines.events.on_chunk_generated, (e: OnChunkGeneratedEvent) => { + log(`on_chunk_generated ${e.tick}`) + let tiles = getTiles(e.surface, e.area) mapTilesUpdateDebounce(e.surface, e.position, tiles) } @@ -66,6 +74,7 @@ script.on_event( script.on_event( defines.events.on_chunk_charted, (e: OnChunkChartedEvent) => { + log(`on_chunk_charted ${e.tick}`) const surface = getSurface(e.surface_index) if (surface == undefined) { @@ -82,6 +91,7 @@ script.on_event( script.on_event( defines.events.script_raised_set_tiles, (e: ScriptRaisedSetTilesEvent) => { + log(`script_raised_set_tiles ${e.tick}`) const surface = getSurface(e.surface_index) if (surface == undefined) { @@ -164,8 +174,14 @@ function onBuildTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) } } -script.on_event(defines.events.on_player_built_tile, (e: OnPlayerBuiltTileEvent) => onBuildTileEvent(e)) -script.on_event(defines.events.on_robot_built_tile, (e: OnRobotBuiltTileEvent) => onBuildTileEvent(e)) +script.on_event(defines.events.on_player_built_tile, (e: OnPlayerBuiltTileEvent) => { + log(`on_player_built_tile ${e.tick}`) + onBuildTileEvent(e) +}) +script.on_event(defines.events.on_robot_built_tile, (e: OnRobotBuiltTileEvent) => { + log(`on_robot_built_tile ${e.tick}`) + onBuildTileEvent(e) +}) // script.on_event( // defines.events.on_player_mined_tile, @@ -187,6 +203,7 @@ script.on_event(defines.events.on_robot_built_tile, (e: OnRobotBuiltTileEvent) = script.on_event( defines.events.on_pre_chunk_deleted, (e: OnPreChunkDeletedEvent) => { + log(`on_pre_chunk_deleted ${e.tick}`) const surface = getSurface(e.surface_index) if (surface == undefined) { diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index 763aae5..d059674 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -7,6 +7,7 @@ import { } from "./handlers"; import {Queue} from "../queue/queue"; import {EventName} from "../types"; +import {isEventType} from "./eventTypeCheck"; const mapEventIdToName = new LuaTable() diff --git a/modules/events-mod/src/main/typescript/main/global-init.ts b/modules/events-mod/src/main/typescript/main/global-init.ts new file mode 100644 index 0000000..920549b --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/global-init.ts @@ -0,0 +1,15 @@ +import {Queue} from "./queue/queue"; +import {EventDataCache} from "./cache/EventDataCache"; + + +export function initGlobal(force: boolean = false) { + log(`Initialising Kafkatorio Global variables (force=${force})...`) + + global.MOD_VERSION = script.active_mods[script.mod_name] + global.FACTORIO_VERSION = script.active_mods["base"] + + Queue.init(true) + EventDataCache.init(true) + + log("Finished initialising Kafkatorio Global variables") +} diff --git a/modules/events-mod/src/main/typescript/main/queue/queue.ts b/modules/events-mod/src/main/typescript/main/queue/queue.ts index 6483642..95fd0cd 100644 --- a/modules/events-mod/src/main/typescript/main/queue/queue.ts +++ b/modules/events-mod/src/main/typescript/main/queue/queue.ts @@ -10,24 +10,27 @@ export namespace Queue { } - export function init() { - if (global.store == undefined) { - log("initialising EventQueue") - reset() + export function init(force?: boolean) { + + const isAnythingUndefined = global.store == undefined || + global.size == undefined || + global.head == undefined || + global.tail == undefined + + log(`Initialising EventQueue globals (force=${force}, isAnythingUndefined=${isAnythingUndefined})`) + + if (force == true || isAnythingUndefined) { + global.store = {} + global.head = null + global.tail = null + global.size = 0 } + + log(`Finished initialising EventQueue`) } - export function reset() { - log("Resetting EventQueue") - global.store = {} - global.head = null - global.tail = null - global.size = 0 - } - - - export function size(): uint { + export function size(): uint | undefined { return global.size } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt index 61b85bc..c88f0e2 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.events.schema +import dev.adamko.kafkatorio.events.schema.FactorioEventUpdate.FactorioEventUpdateType import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.EncodeDefault import kotlinx.serialization.Serializable @@ -22,11 +23,24 @@ class FactorioEventUpdatePacket( } +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +sealed interface FactorioEventUpdateKey { + val updateType: FactorioEventUpdateType +} + + +sealed interface FactorioEventUpdateData { + val updateType: FactorioEventUpdateType +} + + @Serializable(with = FactorioEventUpdate.Companion.JsonSerializer::class) -sealed class FactorioEventUpdate { +sealed class FactorioEventUpdate : FactorioEventUpdateKey, FactorioEventUpdateData { @EncodeDefault - abstract val updateType: FactorioEventUpdateType + abstract override val updateType: FactorioEventUpdateType @Serializable enum class FactorioEventUpdateType { @@ -61,7 +75,7 @@ sealed class FactorioEventUpdate { return when (type) { FactorioEventUpdateType.PLAYER -> PlayerUpdate.serializer() - FactorioEventUpdateType.MAP_CHUNK -> TODO() + FactorioEventUpdateType.MAP_CHUNK -> MapChunkUpdate.serializer() FactorioEventUpdateType.ENTITY -> EntityUpdate.serializer() } } @@ -71,75 +85,154 @@ sealed class FactorioEventUpdate { } +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +sealed interface PlayerUpdateKey : FactorioEventUpdateKey { + val index: PlayerIndex +} + + +sealed interface PlayerUpdateData : FactorioEventUpdateData { + val characterUnitNumber: UnitNumber? + val chatColour: Colour? + val colour: Colour? + val name: String? + + val afkTime: Tick? + val ticksToRespawn: Tick? + val forceIndex: ForceIndex? + val isAdmin: Boolean? + val isConnected: Boolean? + val isShowOnMap: Boolean? + val isSpectator: Boolean? + val lastOnline: Tick? + val onlineTime: Tick? + val position: MapEntityPosition? + val surfaceIndex: SurfaceIndex? + val tag: String? + val diedCause: EntityIdentifiers? + + val bannedReason: String? + val kickedReason: String? + val disconnectReason: String? + /** `true` when a player is removed (deleted) from the game */ + val isRemoved: Boolean? +} + + @Serializable data class PlayerUpdate( - val index: PlayerIndex, + override val index: PlayerIndex, - val characterUnitNumber: UnitNumber? = null, - val chatColour: Colour? = null, - val colour: Colour? = null, - val name: String? = null, + override val characterUnitNumber: UnitNumber? = null, + override val chatColour: Colour? = null, + override val colour: Colour? = null, + override val name: String? = null, - val afkTime: Tick? = null, - val ticksToRespawn: Tick? = null, - val forceIndex: ForceIndex? = null, - val isAdmin: Boolean? = null, - val isConnected: Boolean? = null, - val isShowOnMap: Boolean? = null, - val isSpectator: Boolean? = null, - val lastOnline: Tick? = null, - val onlineTime: Tick? = null, - val position: MapEntityPosition? = null, - val surfaceIndex: SurfaceIndex? = null, - val tag: String? = null, - val diedCause: EntityIdentifiers? = null, + override val afkTime: Tick? = null, + override val ticksToRespawn: Tick? = null, + override val forceIndex: ForceIndex? = null, + override val isAdmin: Boolean? = null, + override val isConnected: Boolean? = null, + override val isShowOnMap: Boolean? = null, + override val isSpectator: Boolean? = null, + override val lastOnline: Tick? = null, + override val onlineTime: Tick? = null, + override val position: MapEntityPosition? = null, + override val surfaceIndex: SurfaceIndex? = null, + override val tag: String? = null, + override val diedCause: EntityIdentifiers? = null, - val bannedReason: String? = null, - val kickedReason: String? = null, - val disconnectReason: String? = null, + override val bannedReason: String? = null, + override val kickedReason: String? = null, + override val disconnectReason: String? = null, /** `true` when a player is removed (deleted) from the game */ - val isRemoved: Boolean? = null, -) : FactorioEventUpdate() { + override val isRemoved: Boolean? = null, +) : FactorioEventUpdate(), PlayerUpdateKey, PlayerUpdateData { @EncodeDefault override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.PLAYER } +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +sealed interface EntityUpdateKey : EntityIdentifiers, FactorioEventUpdateKey { + /** A [unitNumber] is required for caching */ + override val unitNumber: UnitNumber + override val name: String + override val type: String +} + +sealed interface EntityUpdateData : FactorioEventUpdateData { + val chunkPosition: MapChunkPosition? + val graphicsVariation: UShort? + val health: Float? + val isActive: Boolean? + val isRotatable: Boolean? + val lastUser: UInt? + val localisedDescription: String? + val localisedName: String? + val prototype: PrototypeName? +} + @Serializable data class EntityUpdate( - /** A [unitNumber] is required for caching */ override val unitNumber: UnitNumber, override val name: String, override val type: String, - val chunkPosition: MapChunkPosition? = null, - val graphicsVariation: UShort? = null, - val health: Float? = null, - val isActive: Boolean? = null, - val isRotatable: Boolean? = null, - val lastUser: UInt? = null, - val localisedDescription: String? = null, - val localisedName: String? = null, - val prototype: PrototypeName? = null, -) : FactorioEventUpdate(), EntityIdentifiers { + override val chunkPosition: MapChunkPosition? = null, + override val graphicsVariation: UShort? = null, + override val health: Float? = null, + override val isActive: Boolean? = null, + override val isRotatable: Boolean? = null, + override val lastUser: UInt? = null, + override val localisedDescription: String? = null, + override val localisedName: String? = null, + override val prototype: PrototypeName? = null, +) : FactorioEventUpdate(), EntityIdentifiers, EntityUpdateKey, EntityUpdateData { @EncodeDefault override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.ENTITY } +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +sealed interface MapChunkUpdateKey : FactorioEventUpdateKey { + val chunkPosition: MapChunkPosition + val surfaceIndex: SurfaceIndex +} + + +sealed interface MapChunkUpdateData : FactorioEventUpdateData { + val player: PlayerIndex? + val robot: EntityIdentifiers? + val force: ForceIndex? + /** updated tiles - might be partial */ + val tiles: List? + val isDeleted: Boolean? +} + + @Serializable data class MapChunkUpdate( - val chunkPosition: MapChunkPosition, - val surfaceIndex: SurfaceIndex, + override val chunkPosition: MapChunkPosition, + override val surfaceIndex: SurfaceIndex, - val player: PlayerIndex? = null, - val robot: EntityIdentifiers? = null, - val force: ForceIndex? = null, - - /** Might be a partial list of updated tiles */ - val tiles: Map? = null, - val isDeleted: Boolean? = null, -) : FactorioEventUpdate() { + override val player: PlayerIndex? = null, + override val robot: EntityIdentifiers? = null, + override val force: ForceIndex? = null, + // note: this must be a List, not a Map + // because JSON can't have non-string keys. + override val tiles: List? = null, + override val isDeleted: Boolean? = null, +) : FactorioEventUpdate(), MapChunkUpdateKey, MapChunkUpdateData { @EncodeDefault override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.MAP_CHUNK } + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt index a19221f..1d5a9cb 100644 --- a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt @@ -14,12 +14,19 @@ fun main(args: Array) { TypeScriptGenerator( rootClasses = buildSet { addAll(KafkatorioPacket::class.sealedSubclasses) + addAll(FactorioObjectData::class.sealedSubclasses) + addAll(FactorioPrototype::class.sealedSubclasses) add(FactorioPrototypes::class) add(FactorioConfigurationUpdate::class) + + add(FactorioEventUpdatePacket::class) addAll(FactorioEventUpdate::class.sealedSubclasses) + addAll(FactorioEventUpdateKey::class.sealedSubclasses) + addAll(FactorioEventUpdateData::class.sealedSubclasses) + }, mappings = mapOf( // builtin Factorio numeric types > `typed-factorio/generated/builtin-types.d.ts` @@ -66,18 +73,38 @@ private fun splitDefinitions(definitions: String): Map { return definitions .split("\n\n") .groupBy { def -> + + when { - "extends FactorioObjectData " in def || - "interface FactorioObjectData " in def || - "type ObjectName " in def -> "object-data.d.ts" + + "interface FactorioObjectData " in def || + "type ObjectName " in def || + def.contains(Regex("interface.+extends.+(FactorioObjectData).*")) + -> "object-data.d.ts" + "extends FactorioPrototype " in def || "interface FactorioPrototypes " in def || "interface FactorioPrototype " in def || "type PrototypeObjectName " in def -> "prototype.d.ts" + "extends FactorioConfigurationUpdate " in def || "interface FactorioConfigurationUpdate " in def || "FactorioGameDataUpdate " in def || "FactorioModInfo " in def -> "config-update.d.ts" + + "interface FactorioEventUpdatePacket" in def || + "type FactorioEventUpdateType =" in def || + "interface FactorioEventUpdateKey {" in def || + "interface FactorioEventUpdateData {" in def || + def.contains( + Regex( + """ + interface.+extends.+(FactorioEventUpdate|PlayerUpdateKey|PlayerUpdateData).* + """.trimIndent() + ) + ) + -> "update.d.ts" + else -> "schema.d.ts" } } From b82e3a1bbf6ef1ce146e235fc7fa443c0522c979 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 23 Feb 2022 11:57:37 +0100 Subject: [PATCH 223/629] rename files --- modules/events-mod/src/main/typescript/control.ts | 4 ++-- .../main/events/{mapEvents.ts => onMapChunkEventListeners.ts} | 0 .../events/{playerEvents.ts => onPlayerEventListeners.ts} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename modules/events-mod/src/main/typescript/main/events/{mapEvents.ts => onMapChunkEventListeners.ts} (100%) rename modules/events-mod/src/main/typescript/main/events/{playerEvents.ts => onPlayerEventListeners.ts} (100%) diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index 13ddeb1..40c1b21 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -3,8 +3,8 @@ import {emitPrototypes} from "./main/config-update/prototypes"; import {initGlobal} from "./main/global-init"; require("./main/events/registerHandlers") -require("./main/events/playerEvents") -require("./main/events/mapEvents") +require("./main/events/onMapChunkEventListeners") +require("./main/events/onPlayerEventListeners") require("./main/commands/kafkatorioCommands") require("./main/cache/cacheChecker") diff --git a/modules/events-mod/src/main/typescript/main/events/mapEvents.ts b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts similarity index 100% rename from modules/events-mod/src/main/typescript/main/events/mapEvents.ts rename to modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts diff --git a/modules/events-mod/src/main/typescript/main/events/playerEvents.ts b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts similarity index 100% rename from modules/events-mod/src/main/typescript/main/events/playerEvents.ts rename to modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts From 8e7208ba08d175bf785bce65a349567ddaa60f4e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 23 Feb 2022 17:56:56 +0100 Subject: [PATCH 224/629] - update data model: simplify key/data (by removing data) --- .../generated/kafkatorio-schema/update.d.ts | 60 +----- .../typescript/main/cache/EventDataCache.ts | 98 +++------ .../main/typescript/main/events/converters.ts | 14 ++ .../main/events/onMapChunkEventListeners.ts | 36 ++-- .../main/events/onPlayerEventListeners.ts | 64 +++--- .../main/events/registerHandlers.ts | 41 +--- .../events/schema/factorioEventUpdates.kt | 188 ++++++++++-------- .../adamko/kafkatorio/events/schema/kt2ts.kt | 2 +- 8 files changed, 221 insertions(+), 282 deletions(-) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts index 1d6898d..66d53db 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts @@ -6,11 +6,8 @@ interface FactorioEventUpdateKey { updateType: FactorioEventUpdateType; } -interface FactorioEventUpdateData { - updateType: FactorioEventUpdateType; -} - -interface FactorioEventUpdate extends FactorioEventUpdateKey, FactorioEventUpdateData { +interface FactorioEventUpdate extends FactorioEventUpdateKey { + events: string[] | null; updateType: FactorioEventUpdateType; } @@ -25,31 +22,7 @@ interface PlayerUpdateKey extends FactorioEventUpdateKey { index: uint; } -interface PlayerUpdateData extends FactorioEventUpdateData { - afkTime: uint | null; - bannedReason: string | null; - characterUnitNumber: uint | null; - chatColour: Colour | null; - colour: Colour | null; - diedCause: EntityIdentifiers | null; - disconnectReason: string | null; - forceIndex: uint | null; - isAdmin: boolean | null; - isConnected: boolean | null; - isRemoved: boolean | null; - isShowOnMap: boolean | null; - isSpectator: boolean | null; - kickedReason: string | null; - lastOnline: uint | null; - name: string | null; - onlineTime: uint | null; - position: MapEntityPosition | null; - surfaceIndex: uint | null; - tag: string | null; - ticksToRespawn: uint | null; -} - -interface PlayerUpdate extends FactorioEventUpdate, PlayerUpdateKey, PlayerUpdateData { +interface PlayerUpdate extends FactorioEventUpdate, PlayerUpdateKey { afkTime: uint | null; bannedReason: string | null; characterUnitNumber: uint | null; @@ -57,6 +30,7 @@ interface PlayerUpdate extends FactorioEventUpdate, PlayerUpdateKey, PlayerUpdat colour: Colour | null; diedCause: EntityIdentifiers | null; disconnectReason: string | null; + events: string[] | null; forceIndex: uint | null; index: uint; isAdmin: boolean | null; @@ -81,20 +55,9 @@ interface EntityUpdateKey extends EntityIdentifiers, FactorioEventUpdateKey { unitNumber: uint; } -interface EntityUpdateData extends FactorioEventUpdateData { - chunkPosition: MapChunkPosition | null; - graphicsVariation: number | null; - health: float | null; - isActive: boolean | null; - isRotatable: boolean | null; - lastUser: int | null; - localisedDescription: string | null; - localisedName: string | null; - prototype: string | null; -} - -interface EntityUpdate extends FactorioEventUpdate, EntityIdentifiers, EntityUpdateKey, EntityUpdateData { +interface EntityUpdate extends FactorioEventUpdate, EntityIdentifiers, EntityUpdateKey { chunkPosition: MapChunkPosition | null; + events: string[] | null; graphicsVariation: number | null; health: float | null; isActive: boolean | null; @@ -114,16 +77,9 @@ interface MapChunkUpdateKey extends FactorioEventUpdateKey { surfaceIndex: uint; } -interface MapChunkUpdateData extends FactorioEventUpdateData { - force: uint | null; - isDeleted: boolean | null; - player: uint | null; - robot: EntityIdentifiers | null; - tiles: MapTile[] | null; -} - -interface MapChunkUpdate extends FactorioEventUpdate, MapChunkUpdateKey, MapChunkUpdateData { +interface MapChunkUpdate extends FactorioEventUpdate, MapChunkUpdateKey { chunkPosition: MapChunkPosition; + events: string[] | null; force: uint | null; isDeleted: boolean | null; player: uint | null; diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts index a26e5b1..dfa38d7 100644 --- a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts +++ b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts @@ -1,5 +1,3 @@ -import {NonNullableKeys} from "../types"; - export namespace EventDataCache { @@ -88,8 +86,7 @@ export namespace EventDataCache { const expiredData: Array = [] for (let [key, entry] of global.cache) { if (isExpired(entry)) { - const update: FactorioEventUpdate = {...key, ...entry.data} - expiredData.push(update) + expiredData.push(entry.data) global.cache.delete(key) } } @@ -104,7 +101,7 @@ export namespace EventDataCache { return undefined } const value: CacheEntry = global.cache.get(key) - if (isType(value, key.updateType)) { + if (isEntryInstanceOf(value, key.updateType)) { return value } else { // Type mismatch. This shouldn't happen... @@ -117,8 +114,7 @@ export namespace EventDataCache { key: CacheKey, mutate: CacheDataMutator, ): CacheEntry { - // @ts-ignore // TODO resolve ts-ignore for "not assignable to type" - const data: CacheData = {updateType: key.updateType} + const data: CacheData = >{updateType: key.updateType} mutate(data) let entry: CacheEntry = new CacheEntry(data) global.cache.set(key, entry) @@ -127,34 +123,35 @@ export namespace EventDataCache { // /** Map a {@link FactorioEventUpdateType} to a {@link FactorioEventUpdate} DTO */ - // type ConvertUpdateType = - // TYPE extends "PLAYER" ? PlayerUpdate : - // TYPE extends "MAP_CHUNK" ? MapChunkUpdate : - // TYPE extends "ENTITY" ? EntityUpdate : - // never + type ConvertToUpdate = + TYPE extends "PLAYER" ? PlayerUpdate : + TYPE extends "MAP_CHUNK" ? MapChunkUpdate : + TYPE extends "ENTITY" ? EntityUpdate : + never - type ConvertKeyType = + type ConvertToUpdateKey = TYPE extends "PLAYER" ? PlayerUpdateKey : TYPE extends "MAP_CHUNK" ? MapChunkUpdateKey : TYPE extends "ENTITY" ? EntityUpdateKey : never - type ConvertKeyData = - TYPE extends "PLAYER" ? PlayerUpdateData : - TYPE extends "MAP_CHUNK" ? MapChunkUpdateData : - TYPE extends "ENTITY" ? EntityUpdateData : - never + // type ConvertToUpdateData = + // TYPE extends "PLAYER" ? PlayerUpdateData : + // TYPE extends "MAP_CHUNK" ? MapChunkUpdateData : + // TYPE extends "ENTITY" ? EntityUpdateData : + // never - /** Only include the non-null properties, and make `updateType` specific */ + /** Make `updateType` specific */ export type CacheKey = CacheTyped - & Omit, "updateType"> + & Omit, "updateType"> - /** Exclude {@link CacheKey} fields, and make `updateType` specific */ + /** Make nullable-fields optional, and `updateType` specific */ export type CacheData = CacheTyped - & NonNullableKeys, "updateType">>> + & Omit, "updateType"> + // & NullablePartial, "updateType">> export type CacheTyped = { @@ -189,54 +186,19 @@ export namespace EventDataCache { } - function isType( - data: CacheEntry, + function isEntryInstanceOf( + data: CacheEntry, updateType: TYPE, ): data is CacheEntry { - return data.data.updateType == updateType + return isDataInstanceOf(data.data, updateType) + } + + + function isDataInstanceOf( + data: CacheData, + updateType: TYPE, + ): data is CacheData { + return data.updateType == updateType } } - -// interface FactorioEventUpdate { -// type: string -// } -// -// interface Update { -// type: T -// } -// -// export interface PlayerUpdate extends Update<"PLAYER"> { -// index: uint -// -// unhandledEvents?: string[] -// -// characterUnitNumber?: uint -// chatColour?: Colour -// colour?: Colour -// disconnectReason?: string -// forceIndex?: uint -// isAdmin?: boolean -// isConnected?: boolean -// isShowOnMap?: boolean -// isSpectator?: boolean -// lastOnline?: uint -// afkTime?: uint -// name?: string -// onlineTime?: uint -// position?: MapEntityPosition -// surfaceIndex?: uint -// ticksToRespawn?: uint -// tag?: string -// } - -// export type CacheKey = MapChunkCacheKey | EntityCacheKey | PlayerCacheKey & { -// type: Type -// } -// -// export function isCacheType( -// cacheKey: CacheKey, -// type: CacheType -// ): cacheKey is CK { -// return cacheKey.type == type -// } diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index b4bc12d..75b8de0 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -1,3 +1,5 @@ +import {EventName} from "../types"; + export namespace Converters { // export function playerToTable(player: LuaPlayer): PlayerData { @@ -15,6 +17,18 @@ export namespace Converters { // } // } + + const mapEventIdToName = new LuaTable() + for (const [eventName, eventId] of pairs(defines.events)) { + mapEventIdToName.set(eventId, eventName) + } + + + export function eventNameString(event: defines.Events): EventName { + return mapEventIdToName.get(event) + } + + export function entityToTable(entity: LuaEntity): EntityData { let player: LuaPlayer | null = entity.is_player() ? entity.player!! : null diff --git a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts index bb8b58c..8f5a4ae 100644 --- a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts @@ -1,5 +1,6 @@ import {EventDataCache} from "../cache/EventDataCache"; import {isEventType} from "./eventTypeCheck"; +import {Converters} from "./converters"; import CacheKey = EventDataCache.CacheKey; import CacheData = EventDataCache.CacheData; @@ -11,8 +12,10 @@ function mapTilesUpdateDebounce( surface: LuaSurface | undefined, chunkPosition: ChunkPositionTable, tiles: TileRead[], - updater?: MapChunkUpdater + eventName: string, + updater?: MapChunkUpdater, ) { + if (surface == undefined) { return } @@ -38,6 +41,13 @@ function mapTilesUpdateDebounce( ) } + if (data.events == null) { + data.events = [] + } + if (eventName ! in data.events) { + data.events.push(eventName) + } + if (updater != undefined) { updater(data) } @@ -67,7 +77,7 @@ script.on_event( log(`on_chunk_generated ${e.tick}`) let tiles = getTiles(e.surface, e.area) - mapTilesUpdateDebounce(e.surface, e.position, tiles) + mapTilesUpdateDebounce(e.surface, e.position, tiles, Converters.eventNameString(e.name)) } ) @@ -76,15 +86,15 @@ script.on_event( (e: OnChunkChartedEvent) => { log(`on_chunk_charted ${e.tick}`) - const surface = getSurface(e.surface_index) - if (surface == undefined) { - return - } - - let tiles = getTiles(surface, e.area) - mapTilesUpdateDebounce(surface, e.position, tiles, (data => { - data.force = e.force.index - })) + // const surface = getSurface(e.surface_index) + // if (surface == undefined) { + // return + // } + // + // let tiles = getTiles(surface, e.area) + // mapTilesUpdateDebounce(surface, e.position, tiles, (data => { + // data.force = e.force.index + // })) } ) @@ -101,7 +111,7 @@ script.on_event( const groupedTiles = groupTiles(e.tiles) for (const [chunkPos, tiles] of groupedTiles) { - mapTilesUpdateDebounce(surface, chunkPos, tiles) + mapTilesUpdateDebounce(surface, chunkPos, tiles, Converters.eventNameString(e.name)) } } ) @@ -146,12 +156,14 @@ function onBuildTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) const tiles: TileRead[] = convertOldPosition(event.tiles, event.tile) const groupedTiles = groupTiles(tiles) + const eventName = Converters.eventNameString(event.name) for (const [chunkPos, tiles] of groupedTiles) { mapTilesUpdateDebounce( surface, chunkPos, tiles, + eventName, (data => { if (isEventType(event, defines.events.on_player_built_tile)) { data.player = event.player_index diff --git a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts index 4cf49b0..ca9f813 100644 --- a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts @@ -6,6 +6,7 @@ type PlayerUpdater = (player: LuaPlayer, data: CacheData<"PLAYER">) => void function playerUpdateThrottle( playerIndex: uint, + eventName: string, mutate: PlayerUpdater, ) { EventDataCache.throttle<"PLAYER">( @@ -15,6 +16,13 @@ function playerUpdateThrottle( if (player != undefined) { mutate(player, data) } + + if (data.events == null) { + data.events = [] + } + if (eventName ! in data.events) { + data.events.push(eventName) + } }) ) } @@ -41,9 +49,10 @@ script.on_event( (e: OnPlayerJoinedGameEvent) => { playerUpdateThrottle( e.player_index, + Converters.eventNameString(e.name), (player, data) => { data.isAdmin = player.admin - data.characterUnitNumber = player.character?.unit_number + data.characterUnitNumber = player.character?.unit_number ?? null data.chatColour = Converters.mapColour(player.chat_color) data.colour = Converters.mapColour(player.color) data.forceIndex = player.force.index @@ -62,6 +71,7 @@ script.on_event( (e: OnPlayerChangedPositionEvent) => { playerUpdateThrottle( e.player_index, + Converters.eventNameString(e.name), (player, data) => { data.position = player.position } @@ -74,6 +84,7 @@ script.on_event( (e: OnPlayerChangedSurfaceEvent) => { playerUpdateThrottle( e.player_index, + Converters.eventNameString(e.name), (player, data) => { data.position = player.position data.surfaceIndex = player.surface.index @@ -87,8 +98,9 @@ script.on_event( (e: OnPlayerDiedEvent) => { playerUpdateThrottle( e.player_index, + Converters.eventNameString(e.name), (player, data) => { - data.ticksToRespawn = player.ticks_to_respawn + data.ticksToRespawn = player.ticks_to_respawn ?? null playerOnlineInfo(player, data) if (e.cause != undefined) { data.diedCause = { @@ -102,43 +114,31 @@ script.on_event( } ) -script.on_event( - defines.events.on_player_banned, - (e: OnPlayerBannedEvent) => { - if (e.player_index != undefined) { - playerUpdateThrottle( - e.player_index, - (player, data) => { - data.bannedReason = e.reason - playerOnlineInfo(player, data) - } - ) - } - } -) +script.on_event(defines.events.on_player_banned, handleBannedEvent) +script.on_event(defines.events.on_player_unbanned, handleBannedEvent) -script.on_event( - defines.events.on_player_unbanned, - (e: OnPlayerUnbannedEvent) => { - if (e.player_index != undefined) { - playerUpdateThrottle( - e.player_index, - (player, data) => { - data.bannedReason = e.reason - playerOnlineInfo(player, data) - } - ) - } - } -) +function handleBannedEvent(e: OnPlayerBannedEvent | OnPlayerUnbannedEvent) { + + if (e.player_index != undefined) { + playerUpdateThrottle( + e.player_index, + Converters.eventNameString(e.name), + (player, data) => { + data.bannedReason = e.reason ?? null + playerOnlineInfo(player, data) + } + ) + } +} script.on_event( defines.events.on_player_kicked, (e: OnPlayerKickedEvent) => { playerUpdateThrottle( e.player_index, + Converters.eventNameString(e.name), (player, data) => { - data.kickedReason = e.reason + data.kickedReason = e.reason ?? null playerOnlineInfo(player, data) } ) @@ -156,6 +156,7 @@ script.on_event( (e: OnPrePlayerLeftGameEvent) => { playerUpdateThrottle( e.player_index, + Converters.eventNameString(e.name), (player, data) => { data.disconnectReason = disconnectReasons.get(e.reason) playerOnlineInfo(player, data) @@ -169,6 +170,7 @@ script.on_event( (e: OnPlayerRemovedEvent) => { playerUpdateThrottle( e.player_index, + Converters.eventNameString(e.name), (player, data) => { data.isRemoved = true playerOnlineInfo(player, data) diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index d059674..61a1138 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -3,23 +3,16 @@ import { handleConsoleChat, handleEntityUpdate, handleSurfaceUpdate, - // handleTilesUpdate } from "./handlers"; import {Queue} from "../queue/queue"; -import {EventName} from "../types"; import {isEventType} from "./eventTypeCheck"; - - -const mapEventIdToName = new LuaTable() -for (const [eventName, eventId] of pairs(defines.events)) { - mapEventIdToName.set(eventId, eventName) -} +import {Converters} from "./converters"; script.on_event( defines.events.on_player_mined_entity, (e: OnPlayerMinedEntityEvent) => { - let eventName = mapEventIdToName.get(e.name) + let eventName = Converters.eventNameString(e.name) // handlePlayerUpdate(e.tick, eventName, e.player_index) handleEntityUpdate(e.tick, eventName, e.entity) } @@ -44,7 +37,7 @@ script.on_event( (e: OnTickEvent) => { if (e.tick % 1000 == 0) { for (const [, surface] of game.surfaces) { - handleSurfaceUpdate(e.tick, mapEventIdToName.get(e.name), surface) + handleSurfaceUpdate(e.tick, Converters.eventNameString(e.name), surface) } // let packets = new KafkatorioPacketQueue().dequeueValues(1) @@ -61,7 +54,7 @@ script.on_event( for (const event of events) { if (isEventType(event, defines.events.on_chunk_generated)) { - let eName = mapEventIdToName.get(event.name) + let eName = Converters.eventNameString(event.name) log(`[${e.tick}] dequed event ${eName}`) handleChunkUpdate(e.tick, eName, event.surface.index, event.position, event.area) @@ -75,29 +68,15 @@ script.on_event( script.on_event( defines.events.on_console_chat, (e: OnConsoleChatEvent) => { - handleConsoleChat(e.tick, mapEventIdToName.get(e.name), e.player_index, e.message) + handleConsoleChat(e.tick, Converters.eventNameString(e.name), e.player_index, e.message) } ) // script.on_event( // defines.events.on_chunk_generated, // (e: OnChunkGeneratedEvent) => { -// handleChunkUpdate(e.tick, mapEventIdToName.get(e.name), e.surface.index, e.position, e.area) -// } -// ) -// -// script.on_event( -// [ -// defines.events.on_player_built_tile, -// defines.events.on_robot_built_tile, -// ], -// (builtTilesEvent) => { -// handleTilesUpdate( -// builtTilesEvent.tick, -// mapEventIdToName.get(builtTilesEvent.name), -// builtTilesEvent.surface_index, -// builtTilesEvent.tile, -// builtTilesEvent.tiles, -// ) -// } -// ) +// handleChunkUpdate(e.tick, mapEventIdToName.get(e.name), e.surface.index, e.position, +// e.area) } ) script.on_event( [ defines.events.on_player_built_tile, +// defines.events.on_robot_built_tile, ], (builtTilesEvent) => { handleTilesUpdate( +// builtTilesEvent.tick, mapEventIdToName.get(builtTilesEvent.name), builtTilesEvent.surface_index, +// builtTilesEvent.tile, builtTilesEvent.tiles, ) } ) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt index c88f0e2..54c3fbf 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt @@ -1,6 +1,7 @@ package dev.adamko.kafkatorio.events.schema import dev.adamko.kafkatorio.events.schema.FactorioEventUpdate.FactorioEventUpdateType +import kotlinx.serialization.Contextual import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.EncodeDefault import kotlinx.serialization.Serializable @@ -31,16 +32,19 @@ sealed interface FactorioEventUpdateKey { } -sealed interface FactorioEventUpdateData { - val updateType: FactorioEventUpdateType -} +//sealed interface FactorioEventUpdateData { +// val updateType: FactorioEventUpdateType +// val event: String? +//} @Serializable(with = FactorioEventUpdate.Companion.JsonSerializer::class) -sealed class FactorioEventUpdate : FactorioEventUpdateKey, FactorioEventUpdateData { +sealed class FactorioEventUpdate : FactorioEventUpdateKey { @EncodeDefault abstract override val updateType: FactorioEventUpdateType + @Contextual + abstract val events: List? @Serializable enum class FactorioEventUpdateType { @@ -93,63 +97,66 @@ sealed interface PlayerUpdateKey : FactorioEventUpdateKey { } -sealed interface PlayerUpdateData : FactorioEventUpdateData { - val characterUnitNumber: UnitNumber? - val chatColour: Colour? - val colour: Colour? - val name: String? - - val afkTime: Tick? - val ticksToRespawn: Tick? - val forceIndex: ForceIndex? - val isAdmin: Boolean? - val isConnected: Boolean? - val isShowOnMap: Boolean? - val isSpectator: Boolean? - val lastOnline: Tick? - val onlineTime: Tick? - val position: MapEntityPosition? - val surfaceIndex: SurfaceIndex? - val tag: String? - val diedCause: EntityIdentifiers? - - val bannedReason: String? - val kickedReason: String? - val disconnectReason: String? - /** `true` when a player is removed (deleted) from the game */ - val isRemoved: Boolean? -} +//sealed interface PlayerUpdateData : FactorioEventUpdateData { +// val characterUnitNumber: UnitNumber? +// val chatColour: Colour? +// val colour: Colour? +// val name: String? +// +// val afkTime: Tick? +// val ticksToRespawn: Tick? +// val forceIndex: ForceIndex? +// val isAdmin: Boolean? +// val isConnected: Boolean? +// val isShowOnMap: Boolean? +// val isSpectator: Boolean? +// val lastOnline: Tick? +// val onlineTime: Tick? +// val position: MapEntityPosition? +// val surfaceIndex: SurfaceIndex? +// val tag: String? +// val diedCause: EntityIdentifiers? +// +// val bannedReason: String? +// val kickedReason: String? +// val disconnectReason: String? +// /** `true` when a player is removed (deleted) from the game */ +// val isRemoved: Boolean? +//} @Serializable data class PlayerUpdate( override val index: PlayerIndex, - override val characterUnitNumber: UnitNumber? = null, - override val chatColour: Colour? = null, - override val colour: Colour? = null, - override val name: String? = null, + @Contextual + override val events: List? = null, - override val afkTime: Tick? = null, - override val ticksToRespawn: Tick? = null, - override val forceIndex: ForceIndex? = null, - override val isAdmin: Boolean? = null, - override val isConnected: Boolean? = null, - override val isShowOnMap: Boolean? = null, - override val isSpectator: Boolean? = null, - override val lastOnline: Tick? = null, - override val onlineTime: Tick? = null, - override val position: MapEntityPosition? = null, - override val surfaceIndex: SurfaceIndex? = null, - override val tag: String? = null, - override val diedCause: EntityIdentifiers? = null, + val characterUnitNumber: UnitNumber? = null, + val chatColour: Colour? = null, + val colour: Colour? = null, + val name: String? = null, - override val bannedReason: String? = null, - override val kickedReason: String? = null, - override val disconnectReason: String? = null, + val afkTime: Tick? = null, + val ticksToRespawn: Tick? = null, + val forceIndex: ForceIndex? = null, + val isAdmin: Boolean? = null, + val isConnected: Boolean? = null, + val isShowOnMap: Boolean? = null, + val isSpectator: Boolean? = null, + val lastOnline: Tick? = null, + val onlineTime: Tick? = null, + val position: MapEntityPosition? = null, + val surfaceIndex: SurfaceIndex? = null, + val tag: String? = null, + val diedCause: EntityIdentifiers? = null, + + val bannedReason: String? = null, + val kickedReason: String? = null, + val disconnectReason: String? = null, /** `true` when a player is removed (deleted) from the game */ - override val isRemoved: Boolean? = null, -) : FactorioEventUpdate(), PlayerUpdateKey, PlayerUpdateData { + val isRemoved: Boolean? = null, +) : FactorioEventUpdate(), PlayerUpdateKey { @EncodeDefault override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.PLAYER } @@ -165,17 +172,17 @@ sealed interface EntityUpdateKey : EntityIdentifiers, FactorioEventUpdateKey { override val type: String } -sealed interface EntityUpdateData : FactorioEventUpdateData { - val chunkPosition: MapChunkPosition? - val graphicsVariation: UShort? - val health: Float? - val isActive: Boolean? - val isRotatable: Boolean? - val lastUser: UInt? - val localisedDescription: String? - val localisedName: String? - val prototype: PrototypeName? -} +//sealed interface EntityUpdateData : FactorioEventUpdateData { +// val chunkPosition: MapChunkPosition? +// val graphicsVariation: UShort? +// val health: Float? +// val isActive: Boolean? +// val isRotatable: Boolean? +// val lastUser: UInt? +// val localisedDescription: String? +// val localisedName: String? +// val prototype: PrototypeName? +//} @Serializable data class EntityUpdate( @@ -183,16 +190,19 @@ data class EntityUpdate( override val name: String, override val type: String, - override val chunkPosition: MapChunkPosition? = null, - override val graphicsVariation: UShort? = null, - override val health: Float? = null, - override val isActive: Boolean? = null, - override val isRotatable: Boolean? = null, - override val lastUser: UInt? = null, - override val localisedDescription: String? = null, - override val localisedName: String? = null, - override val prototype: PrototypeName? = null, -) : FactorioEventUpdate(), EntityIdentifiers, EntityUpdateKey, EntityUpdateData { + @Contextual + override val events: List? = null, + + val chunkPosition: MapChunkPosition? = null, + val graphicsVariation: UShort? = null, + val health: Float? = null, + val isActive: Boolean? = null, + val isRotatable: Boolean? = null, + val lastUser: UInt? = null, + val localisedDescription: String? = null, + val localisedName: String? = null, + val prototype: PrototypeName? = null, +) : FactorioEventUpdate(), EntityIdentifiers, EntityUpdateKey { @EncodeDefault override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.ENTITY } @@ -207,14 +217,13 @@ sealed interface MapChunkUpdateKey : FactorioEventUpdateKey { } -sealed interface MapChunkUpdateData : FactorioEventUpdateData { - val player: PlayerIndex? - val robot: EntityIdentifiers? - val force: ForceIndex? - /** updated tiles - might be partial */ - val tiles: List? - val isDeleted: Boolean? -} +//sealed interface MapChunkUpdateData : FactorioEventUpdateData { +// val player: PlayerIndex? +// val robot: EntityIdentifiers? +// val force: ForceIndex? +// val tiles: List? +// val isDeleted: Boolean? +//} @Serializable @@ -222,14 +231,19 @@ data class MapChunkUpdate( override val chunkPosition: MapChunkPosition, override val surfaceIndex: SurfaceIndex, - override val player: PlayerIndex? = null, - override val robot: EntityIdentifiers? = null, - override val force: ForceIndex? = null, + @Contextual + override val events: List? = null, + + val player: PlayerIndex? = null, + val robot: EntityIdentifiers? = null, + val force: ForceIndex? = null, + /** updated tiles - might be partial */ // note: this must be a List, not a Map // because JSON can't have non-string keys. - override val tiles: List? = null, - override val isDeleted: Boolean? = null, -) : FactorioEventUpdate(), MapChunkUpdateKey, MapChunkUpdateData { + @Contextual + val tiles: List? = null, + val isDeleted: Boolean? = null, +) : FactorioEventUpdate(), MapChunkUpdateKey { @EncodeDefault override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.MAP_CHUNK } diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt index 1d5a9cb..e9c51ef 100644 --- a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt @@ -25,7 +25,7 @@ fun main(args: Array) { add(FactorioEventUpdatePacket::class) addAll(FactorioEventUpdate::class.sealedSubclasses) addAll(FactorioEventUpdateKey::class.sealedSubclasses) - addAll(FactorioEventUpdateData::class.sealedSubclasses) +// addAll(FactorioEventUpdateData::class.sealedSubclasses) }, mappings = mapOf( From 066f68ff4df2e5771a26b84f9b0a61ce0c828093 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 24 Feb 2022 21:17:51 +0100 Subject: [PATCH 225/629] event debouncing / throttling basically working now --- .../typescript/main/cache/EventDataCache.ts | 42 +++++++++++++------ .../main/events/onPlayerEventListeners.ts | 4 +- .../src/main/typescript/package-lock.json | 5 --- .../src/main/typescript/package.json | 2 +- .../topology/factorioServerPackets.kt | 2 +- 5 files changed, 33 insertions(+), 22 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts index dfa38d7..08b7e17 100644 --- a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts +++ b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts @@ -2,7 +2,8 @@ export namespace EventDataCache { declare const global: { - cache: LuaTable, CacheEntry>, + cache: LuaTable>, + // cache: Map>, defaultCacheDurationTicks: Record, } @@ -16,7 +17,8 @@ export namespace EventDataCache { if (force == true || isAnythingUndefined) { log("Initialising global.cache") - global.cache = new LuaTable, CacheEntry>() + // global.cache = new Map, CacheEntry>() + global.cache = new LuaTable>() log("Initialising global.DEFAULT_CACHE_DURATION_TICKS") global.defaultCacheDurationTicks = { @@ -83,13 +85,19 @@ export namespace EventDataCache { export function extractExpired(): Array { + let countExpired = 0 + let countTotal = 0 const expiredData: Array = [] for (let [key, entry] of global.cache) { + countTotal++ if (isExpired(entry)) { + countExpired++ expiredData.push(entry.data) global.cache.delete(key) + } } + log(`cache expired items count: ${countExpired}, total: ${countTotal}`) return expiredData } @@ -97,10 +105,12 @@ export namespace EventDataCache { function getCacheEntry( key: CacheKey ): CacheEntry | undefined { - if (!global.cache.has(key)) { + const hash = game.encode_string(game.table_to_json(key))!! + // const value: CacheEntry | undefined = global.cache.get(hash) + if (!global.cache.has(hash)) { return undefined } - const value: CacheEntry = global.cache.get(key) + const value: CacheEntry = global.cache.get(hash) if (isEntryInstanceOf(value, key.updateType)) { return value } else { @@ -114,10 +124,11 @@ export namespace EventDataCache { key: CacheKey, mutate: CacheDataMutator, ): CacheEntry { - const data: CacheData = >{updateType: key.updateType} + const data: CacheData = >{...key} mutate(data) let entry: CacheEntry = new CacheEntry(data) - global.cache.set(key, entry) + const hash = game.encode_string(game.table_to_json(key))!! + global.cache.set(hash, entry) return entry } @@ -151,7 +162,6 @@ export namespace EventDataCache { export type CacheData = CacheTyped & Omit, "updateType"> - // & NullablePartial, "updateType">> export type CacheTyped = { @@ -187,18 +197,26 @@ export namespace EventDataCache { function isEntryInstanceOf( - data: CacheEntry, + entry: CacheEntry | undefined, updateType: TYPE, - ): data is CacheEntry { - return isDataInstanceOf(data.data, updateType) + ): entry is CacheEntry { + return isDataInstanceOf(entry?.data, updateType) } function isDataInstanceOf( - data: CacheData, + data: CacheData | undefined, updateType: TYPE, ): data is CacheData { - return data.updateType == updateType + return data != undefined && data.updateType == updateType + } + + + function isKeyInstanceOf( + key: CacheKey | undefined, + updateType: TYPE, + ): key is CacheKey { + return key != undefined && key.updateType == updateType } } diff --git a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts index ca9f813..1463b9e 100644 --- a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts @@ -20,9 +20,7 @@ function playerUpdateThrottle( if (data.events == null) { data.events = [] } - if (eventName ! in data.events) { - data.events.push(eventName) - } + data.events.push(eventName) }) ) } diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index c8fc916..44d891d 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -4,11 +4,6 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@types/node": { - "version": "12.20.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz", - "integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw==" - }, "enhanced-resolve": { "version": "5.8.3", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 90084ae..5190f46 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -13,11 +13,11 @@ }, "dependencies": { "lua-types": "^2.11.0", - "@types/node": "^12.0.8", "typescript-to-lua": "1.3.3", "typed-factorio": "0.18.1", "typescript": "4.5.5" }, + "// @types/node": "^12.0.8", "license": "UNLICENSED", "peerDependencies": { }, diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt index 7c1d8ef..0d8c58b 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt @@ -58,7 +58,7 @@ fun splitFactorioServerPacketStream( is FactorioEvent -> value.data.objectName.name is FactorioConfigurationUpdate -> "FactorioConfigurationUpdate" is FactorioPrototypes -> "all" - is FactorioEventUpdatePacket -> "all" + is FactorioEventUpdatePacket -> value.update.updateType.name } "$base.$type" From 93e02e852afdae612ed3f753e233a34cb40c6689 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 24 Feb 2022 22:17:00 +0100 Subject: [PATCH 226/629] code tidy --- .../typescript/main/cache/EventDataCache.ts | 9 +-- .../events/schema/factorioEventUpdates.kt | 56 +------------------ 2 files changed, 2 insertions(+), 63 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts index 08b7e17..2cc0ebe 100644 --- a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts +++ b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts @@ -3,7 +3,6 @@ export namespace EventDataCache { declare const global: { cache: LuaTable>, - // cache: Map>, defaultCacheDurationTicks: Record, } @@ -94,7 +93,6 @@ export namespace EventDataCache { countExpired++ expiredData.push(entry.data) global.cache.delete(key) - } } log(`cache expired items count: ${countExpired}, total: ${countTotal}`) @@ -106,7 +104,6 @@ export namespace EventDataCache { key: CacheKey ): CacheEntry | undefined { const hash = game.encode_string(game.table_to_json(key))!! - // const value: CacheEntry | undefined = global.cache.get(hash) if (!global.cache.has(hash)) { return undefined } @@ -140,16 +137,12 @@ export namespace EventDataCache { TYPE extends "ENTITY" ? EntityUpdate : never + type ConvertToUpdateKey = TYPE extends "PLAYER" ? PlayerUpdateKey : TYPE extends "MAP_CHUNK" ? MapChunkUpdateKey : TYPE extends "ENTITY" ? EntityUpdateKey : never - // type ConvertToUpdateData = - // TYPE extends "PLAYER" ? PlayerUpdateData : - // TYPE extends "MAP_CHUNK" ? MapChunkUpdateData : - // TYPE extends "ENTITY" ? EntityUpdateData : - // never /** Make `updateType` specific */ diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt index 54c3fbf..b6c393b 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt @@ -32,19 +32,13 @@ sealed interface FactorioEventUpdateKey { } -//sealed interface FactorioEventUpdateData { -// val updateType: FactorioEventUpdateType -// val event: String? -//} - - @Serializable(with = FactorioEventUpdate.Companion.JsonSerializer::class) sealed class FactorioEventUpdate : FactorioEventUpdateKey { @EncodeDefault abstract override val updateType: FactorioEventUpdateType @Contextual - abstract val events: List? + abstract val events: List? // TODO change this to Map @Serializable enum class FactorioEventUpdateType { @@ -97,34 +91,6 @@ sealed interface PlayerUpdateKey : FactorioEventUpdateKey { } -//sealed interface PlayerUpdateData : FactorioEventUpdateData { -// val characterUnitNumber: UnitNumber? -// val chatColour: Colour? -// val colour: Colour? -// val name: String? -// -// val afkTime: Tick? -// val ticksToRespawn: Tick? -// val forceIndex: ForceIndex? -// val isAdmin: Boolean? -// val isConnected: Boolean? -// val isShowOnMap: Boolean? -// val isSpectator: Boolean? -// val lastOnline: Tick? -// val onlineTime: Tick? -// val position: MapEntityPosition? -// val surfaceIndex: SurfaceIndex? -// val tag: String? -// val diedCause: EntityIdentifiers? -// -// val bannedReason: String? -// val kickedReason: String? -// val disconnectReason: String? -// /** `true` when a player is removed (deleted) from the game */ -// val isRemoved: Boolean? -//} - - @Serializable data class PlayerUpdate( override val index: PlayerIndex, @@ -172,17 +138,6 @@ sealed interface EntityUpdateKey : EntityIdentifiers, FactorioEventUpdateKey { override val type: String } -//sealed interface EntityUpdateData : FactorioEventUpdateData { -// val chunkPosition: MapChunkPosition? -// val graphicsVariation: UShort? -// val health: Float? -// val isActive: Boolean? -// val isRotatable: Boolean? -// val lastUser: UInt? -// val localisedDescription: String? -// val localisedName: String? -// val prototype: PrototypeName? -//} @Serializable data class EntityUpdate( @@ -217,15 +172,6 @@ sealed interface MapChunkUpdateKey : FactorioEventUpdateKey { } -//sealed interface MapChunkUpdateData : FactorioEventUpdateData { -// val player: PlayerIndex? -// val robot: EntityIdentifiers? -// val force: ForceIndex? -// val tiles: List? -// val isDeleted: Boolean? -//} - - @Serializable data class MapChunkUpdate( override val chunkPosition: MapChunkPosition, From 758fea41954739789e286a03ec96ca585952f9bc Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 25 Feb 2022 21:44:13 +0100 Subject: [PATCH 227/629] only log a message if there are event cache entries, and formatting --- .../typescript/main/cache/EventDataCache.ts | 22 ++++++++++--------- .../events/schema/factorioEventUpdates.kt | 10 ++++----- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts index 2cc0ebe..7920507 100644 --- a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts +++ b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts @@ -16,7 +16,6 @@ export namespace EventDataCache { if (force == true || isAnythingUndefined) { log("Initialising global.cache") - // global.cache = new Map, CacheEntry>() global.cache = new LuaTable>() log("Initialising global.DEFAULT_CACHE_DURATION_TICKS") @@ -95,7 +94,9 @@ export namespace EventDataCache { global.cache.delete(key) } } - log(`cache expired items count: ${countExpired}, total: ${countTotal}`) + if (countExpired + countTotal > 0) { + log(`cache expired items count: ${countExpired}, total: ${countTotal}`) + } return expiredData } @@ -130,7 +131,7 @@ export namespace EventDataCache { } - // /** Map a {@link FactorioEventUpdateType} to a {@link FactorioEventUpdate} DTO */ + /** Map a {@link FactorioEventUpdateType} to a {@link FactorioEventUpdate} DTO */ type ConvertToUpdate = TYPE extends "PLAYER" ? PlayerUpdate : TYPE extends "MAP_CHUNK" ? MapChunkUpdate : @@ -138,6 +139,7 @@ export namespace EventDataCache { never + /** Map a {@link FactorioEventUpdateType} to a {@link FactorioEventUpdateKey} */ type ConvertToUpdateKey = TYPE extends "PLAYER" ? PlayerUpdateKey : TYPE extends "MAP_CHUNK" ? MapChunkUpdateKey : @@ -151,7 +153,7 @@ export namespace EventDataCache { & Omit, "updateType"> - /** Make nullable-fields optional, and `updateType` specific */ + /** Make `updateType` specific */ export type CacheData = CacheTyped & Omit, "updateType"> @@ -205,11 +207,11 @@ export namespace EventDataCache { } - function isKeyInstanceOf( - key: CacheKey | undefined, - updateType: TYPE, - ): key is CacheKey { - return key != undefined && key.updateType == updateType - } + // function isKeyInstanceOf( + // key: CacheKey | undefined, + // updateType: TYPE, + // ): key is CacheKey { + // return key != undefined && key.updateType == updateType + // } } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt index b6c393b..67d45ff 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt @@ -24,7 +24,7 @@ class FactorioEventUpdatePacket( } -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ sealed interface FactorioEventUpdateKey { @@ -83,7 +83,7 @@ sealed class FactorioEventUpdate : FactorioEventUpdateKey { } -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ sealed interface PlayerUpdateKey : FactorioEventUpdateKey { @@ -128,7 +128,7 @@ data class PlayerUpdate( } -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ sealed interface EntityUpdateKey : EntityIdentifiers, FactorioEventUpdateKey { @@ -163,7 +163,7 @@ data class EntityUpdate( } -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ sealed interface MapChunkUpdateKey : FactorioEventUpdateKey { @@ -195,4 +195,4 @@ data class MapChunkUpdate( } -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ From 462314b2811b7f3a002a47c7a67c542c9a02b60d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 26 Feb 2022 17:33:53 +0100 Subject: [PATCH 228/629] fix some KotlinCompile opt-in warnings --- buildSrc/build.gradle.kts | 2 +- .../kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 4e68cf3..5af130a 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -71,7 +71,7 @@ tasks.withType().configureEach { "-opt-in=kotlin.RequiresOptIn", "-opt-in=kotlin.ExperimentalStdlibApi", "-opt-in=kotlin.time.ExperimentalTime", - "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", +// "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", ) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index 4228ba7..a888607 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -48,7 +48,7 @@ tasks.withType().configureEach { "-opt-in=kotlin.ExperimentalStdlibApi", "-opt-in=kotlin.time.ExperimentalTime", // "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", +// "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", ) } From b42eaaa67eba44df81b132b17c027992264c9e99 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 26 Feb 2022 17:34:31 +0100 Subject: [PATCH 229/629] create KafkaConsumers reset task --- .../adamko/kafkatorio/gradle/extensions.kt | 15 +++++ .../task/KafkaConsumersResetTask.kt | 61 +++++++++++++++++++ .../kafkatorio/task/TypescriptToLuaTask.kt | 3 + .../kafkatorio/task/UpdatePackageJson.kt | 2 + modules/events-server/build.gradle.kts | 35 ++--------- 5 files changed, 86 insertions(+), 30 deletions(-) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/KafkaConsumersResetTask.kt diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt index 6969d30..05006ae 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt @@ -12,6 +12,7 @@ import org.gradle.api.provider.MapProperty import org.gradle.api.specs.Spec import org.gradle.kotlin.dsl.invoke import org.gradle.plugins.ide.idea.model.IdeaModule +import org.gradle.process.ExecSpec operator fun Spec.not(): Spec = Spec { !this(it) } @@ -71,3 +72,17 @@ fun IdeaModule.excludeGeneratedGradleDsl(layout: ProjectLayout) { ) ) } + + +// https://stackoverflow.com/a/70317110/4161471 +fun Project.execCapture(spec: ExecSpec.() -> Unit): String { + return ByteArrayOutputStream().use { outputStream -> + exec { + this.spec() + this.standardOutput = outputStream + } + val output = outputStream.toString().trim() + logger.lifecycle(output) + output + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/KafkaConsumersResetTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/KafkaConsumersResetTask.kt new file mode 100644 index 0000000..08feb0e --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/KafkaConsumersResetTask.kt @@ -0,0 +1,61 @@ +package dev.adamko.kafkatorio.task + +import dev.adamko.kafkatorio.gradle.execCapture +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.logging.LogLevel +import org.gradle.api.tasks.Destroys +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.TaskAction +import org.intellij.lang.annotations.Language +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + +abstract class KafkaConsumersResetTask : DefaultTask() { + + @get:Input + val bootstrapServer: String = "localhost:9092" + @get:Input + val kafkaContainerName: String = "kafka" + @get:Destroys + abstract val kafkaStateDir: DirectoryProperty + + + @TaskAction + fun resetKafkaConsumers() { + val bootstrapArg = "--bootstrap-server $bootstrapServer" + + val allGroups = dockerExec( + """ + /kafka/bin/kafka-consumer-groups.sh --list $bootstrapArg + """.trimIndent() + ).lines() + .filter { it.trim().isNotBlank() } + + allGroups + .forEach { group -> + logger.lifecycle("Resetting group $group\n---") + dockerExec( + """ + /kafka/bin/kafka-consumer-groups.sh --group $group --execute --reset-offsets --all-topics --to-earliest $bootstrapArg + """.trimIndent() + ) + logger.lifecycle("---") + } + + project.delete { + delete(kafkaStateDir) + } + } + +// fun reset(applicationId: String) = """ +// /kafka/bin/kafka-streams-application-reset.sh --application-id $applicationId --force --to-earliest +// """.trimIndent() + + private fun dockerExec( + @Language("Shell Script") + cmd: String + ): String = project.execCapture { + logging.captureStandardOutput(LogLevel.LIFECYCLE) + commandLine = parseSpaceSeparatedArgs(""" docker exec $kafkaContainerName $cmd """) + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt index 0aaa4cb..bd42a41 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt @@ -8,6 +8,7 @@ import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.PathSensitive import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.SkipWhenEmpty +import org.gradle.work.NormalizeLineEndings import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs abstract class TypescriptToLuaTask : NpmTask() { @@ -15,6 +16,8 @@ abstract class TypescriptToLuaTask : NpmTask() { @get:InputDirectory @get:SkipWhenEmpty @get:PathSensitive(PathSensitivity.RELATIVE) + @Suppress("UnstableApiUsage") + @get:NormalizeLineEndings abstract val sourceFiles: DirectoryProperty @get:OutputDirectory diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt index 9017d20..5843ed1 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt @@ -7,8 +7,10 @@ import org.gradle.api.tasks.Input import org.gradle.api.tasks.OutputFile abstract class UpdatePackageJson : DefaultTask() { + @get:Input abstract val propertiesToCheck: MapProperty + @get:OutputFile abstract val packageJsonFile: RegularFileProperty diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index be8c3c1..281f368 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -1,5 +1,5 @@ +import dev.adamko.kafkatorio.task.KafkaConsumersResetTask import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { dev.adamko.kafkatorio.lang.`kotlin-jvm` @@ -58,39 +58,14 @@ tasks.withType { kotlinOptions.freeCompilerArgs += listOf( "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", "-opt-in=kotlinx.coroutines.FlowPreview", + "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", ) } -val kafkatorioEventsServerKafkaForceReset by tasks.registering { + +val kafkaConsumersReset by tasks.registering(KafkaConsumersResetTask::class) { group = project.name - - fun reset(applicationId: String) = """ - /kafka/bin/kafka-streams-application-reset.sh --application-id $applicationId --force - """.trimIndent() - - doLast { - - exec { - val cmd = reset("kafkatorio-events-processor.saveTiles") - logging.captureStandardOutput(LogLevel.LIFECYCLE) - commandLine = parseSpaceSeparatedArgs(""" docker exec -d kafka $cmd """) - } - exec { - val cmd = reset("kafkatorio-events-processor.splitPackets") - logging.captureStandardOutput(LogLevel.LIFECYCLE) - commandLine = parseSpaceSeparatedArgs(""" docker exec -d kafka $cmd --input-topics factorio-server-log """) - } - exec { - val cmd = reset("kafkatorio-events-processor.playerUpdates") - logging.captureStandardOutput(LogLevel.LIFECYCLE) - commandLine = parseSpaceSeparatedArgs(""" docker exec -d kafka $cmd """) - } - exec { - val cmd = reset("kafkatorio-events-processor.groupTilesMapChunks") - logging.captureStandardOutput(LogLevel.LIFECYCLE) - commandLine = parseSpaceSeparatedArgs(""" docker exec -d kafka $cmd """) - } - } + kafkaStateDir.set(project.layout.buildDirectory.dir("kafka-state")) } //tasks.run.configure { From 1ba4371b145c5fa53d792fd06a670cc826d95ec7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 26 Feb 2022 22:23:08 +0100 Subject: [PATCH 230/629] update packet, add 'eventCounts' --- .../generated/kafkatorio-schema/update.d.ts | 8 +- .../main/events/onMapChunkEventListeners.ts | 10 +- .../main/events/onPlayerEventListeners.ts | 7 +- .../events/schema/factorioEventUpdates.kt | 15 +- .../events/schema/UpdatePacketsTest.kt | 149 ++++++++++++++++++ 5 files changed, 167 insertions(+), 22 deletions(-) create mode 100644 modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts index 66d53db..a9598fc 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts @@ -7,7 +7,7 @@ interface FactorioEventUpdateKey { } interface FactorioEventUpdate extends FactorioEventUpdateKey { - events: string[] | null; + eventCounts: { [key: string]: int } | null; updateType: FactorioEventUpdateType; } @@ -30,7 +30,7 @@ interface PlayerUpdate extends FactorioEventUpdate, PlayerUpdateKey { colour: Colour | null; diedCause: EntityIdentifiers | null; disconnectReason: string | null; - events: string[] | null; + eventCounts: { [key: string]: int } | null; forceIndex: uint | null; index: uint; isAdmin: boolean | null; @@ -57,7 +57,7 @@ interface EntityUpdateKey extends EntityIdentifiers, FactorioEventUpdateKey { interface EntityUpdate extends FactorioEventUpdate, EntityIdentifiers, EntityUpdateKey { chunkPosition: MapChunkPosition | null; - events: string[] | null; + eventCounts: { [key: string]: int } | null; graphicsVariation: number | null; health: float | null; isActive: boolean | null; @@ -79,7 +79,7 @@ interface MapChunkUpdateKey extends FactorioEventUpdateKey { interface MapChunkUpdate extends FactorioEventUpdate, MapChunkUpdateKey { chunkPosition: MapChunkPosition; - events: string[] | null; + eventCounts: { [key: string]: int } | null; force: uint | null; isDeleted: boolean | null; player: uint | null; diff --git a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts index 8f5a4ae..f2e6665 100644 --- a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts @@ -41,12 +41,10 @@ function mapTilesUpdateDebounce( ) } - if (data.events == null) { - data.events = [] - } - if (eventName ! in data.events) { - data.events.push(eventName) + if (data.eventCounts == undefined) { + data.eventCounts = {} } + data.eventCounts[eventName] = ((data.eventCounts ?? {}) [eventName] ?? 0) + 1 if (updater != undefined) { updater(data) @@ -111,7 +109,7 @@ script.on_event( const groupedTiles = groupTiles(e.tiles) for (const [chunkPos, tiles] of groupedTiles) { - mapTilesUpdateDebounce(surface, chunkPos, tiles, Converters.eventNameString(e.name)) + mapTilesUpdateDebounce(surface, chunkPos, tiles, Converters.eventNameString(e.name)) } } ) diff --git a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts index 1463b9e..f844ec3 100644 --- a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts @@ -17,10 +17,10 @@ function playerUpdateThrottle( mutate(player, data) } - if (data.events == null) { - data.events = [] + if (data.eventCounts == undefined) { + data.eventCounts = {} } - data.events.push(eventName) + data.eventCounts[eventName] = ((data.eventCounts ?? {}) [eventName] ?? 0) + 1 }) ) } @@ -57,6 +57,7 @@ script.on_event( data.name = player.name data.isShowOnMap = player.show_on_map data.isSpectator = player.spectator + data.surfaceIndex = player.surface.index data.tag = player.tag playerOnlineInfo(player, data) } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt index 67d45ff..fbcd3a1 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt @@ -13,7 +13,7 @@ import kotlinx.serialization.json.jsonPrimitive @Serializable -class FactorioEventUpdatePacket( +data class FactorioEventUpdatePacket( override val modVersion: String, /** game time */ val tick: Tick, @@ -37,8 +37,8 @@ sealed class FactorioEventUpdate : FactorioEventUpdateKey { @EncodeDefault abstract override val updateType: FactorioEventUpdateType - @Contextual - abstract val events: List? // TODO change this to Map + + abstract val eventCounts: Map? @Serializable enum class FactorioEventUpdateType { @@ -95,8 +95,7 @@ sealed interface PlayerUpdateKey : FactorioEventUpdateKey { data class PlayerUpdate( override val index: PlayerIndex, - @Contextual - override val events: List? = null, + override val eventCounts: Map? = null, val characterUnitNumber: UnitNumber? = null, val chatColour: Colour? = null, @@ -145,8 +144,7 @@ data class EntityUpdate( override val name: String, override val type: String, - @Contextual - override val events: List? = null, + override val eventCounts: Map? = null, val chunkPosition: MapChunkPosition? = null, val graphicsVariation: UShort? = null, @@ -177,8 +175,7 @@ data class MapChunkUpdate( override val chunkPosition: MapChunkPosition, override val surfaceIndex: SurfaceIndex, - @Contextual - override val events: List? = null, + override val eventCounts: Map? = null, val player: PlayerIndex? = null, val robot: EntityIdentifiers? = null, diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt new file mode 100644 index 0000000..02c1760 --- /dev/null +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt @@ -0,0 +1,149 @@ +package dev.adamko.kafkatorio.events.schema + +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.shouldBe +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString + +class UpdatePacketsTest : FunSpec({ + + context("player update packet") { + // language=JSON + val json = """ + { + "tick": 66, + "modVersion": "0.3.2", + "packetType": "UPDATE", + "update": { + "afkTime": 0, + "chatColour": { + "red": 1, + "green": 0.4, + "blue": 0.6, + "alpha": 1 + }, + "colour": { + "red": 0.8, + "green": 0.5, + "blue": 0.2, + "alpha": 0.5 + }, + "eventCounts": { + "on_player_changed_position": 7, + "on_player_joined_game": 1 + }, + "forceIndex": 1, + "index": 1, + "isAdmin": true, + "isConnected": true, + "isShowOnMap": true, + "isSpectator": false, + "lastOnline": 0, + "name": "fredthedeadhead", + "onlineTime": 0, + "position": { + "y": 13, + "x": -58 + }, + "tag": "", + "updateType": "PLAYER" + } + } + """.trimIndent() + + test("decode") { + val packet: FactorioEventUpdatePacket = jsonMapperKafkatorio.decodeFromString(json) + + packet shouldBe FactorioEventUpdatePacket( + modVersion = "0.3.2", + tick = Tick(66u), + update = PlayerUpdate( + afkTime = Tick(0u), + bannedReason = null, + characterUnitNumber = null, + chatColour = Colour(red = 1f, green = 0.4f, blue = 0.6f, alpha = 1f), + colour = Colour(red = 0.8f, green = 0.5f, blue = 0.2f, alpha = 0.5f), + diedCause = null, + disconnectReason = null, + eventCounts = mapOf("on_player_changed_position" to 7u, "on_player_joined_game" to 1u), + forceIndex = ForceIndex(1u), + index = PlayerIndex(1u), + isAdmin = true, + isConnected = true, + isRemoved = null, + isShowOnMap = true, + isSpectator = false, + kickedReason = null, + lastOnline = Tick(0u), + name = "fredthedeadhead", + onlineTime = Tick(0u), + position = MapEntityPosition(-58.0, 13.0), + surfaceIndex = null, + tag = "", + ticksToRespawn = null, + ) + ) + } + + test("encode") { + val v = FactorioEventUpdatePacket( + modVersion = "0.3.2", + tick = Tick(66u), + update = PlayerUpdate( + index = PlayerIndex(1u), + characterUnitNumber = null, + chatColour = null, + colour = null, + name = "fredthedeadhead", + afkTime = Tick(0u), + ticksToRespawn = null, + forceIndex = null, + isAdmin = null, + isConnected = null, + isShowOnMap = true, + isSpectator = false, + lastOnline = Tick(0u), + onlineTime = Tick(0u), + position = MapEntityPosition(-58.0, 13.0), + surfaceIndex = null, + tag = null, + diedCause = null, + bannedReason = null, + kickedReason = null, + disconnectReason = null, + isRemoved = null, + ) + ) + + val string = jsonMapperKafkatorio.encodeToString(v) + // language=JSON + string shouldBe """ + { + "modVersion": "0.3.2", + "tick": 66, + "update": { + "index": 1, + "name": "fredthedeadhead", + "afkTime": 0, + "isShowOnMap": true, + "isSpectator": false, + "lastOnline": 0, + "onlineTime": 0, + "position": { + "x": -58.0, + "y": 13.0 + }, + "updateType": "PLAYER" + }, + "packetType": "UPDATE" + } + """.trimIndent() + } + } + + +}) + +/* +{"tick":66,"modVersion":"0.3.2","packetType":"UPDATE","update":{"index":1,"updateType":"PLAYER","position":{"y":13.5234375,"x":-58.9375},"eventCounts":{"on_player_changed_position":7,"on_player_joined_game":1},"isAdmin":true,"chatColour":{"red":1,"green":0.62999999523162841796875,"blue":0.259000003337860107421875,"alpha":1},"colour":{"red":0.869000017642974853515625,"green":0.5,"blue":0.12999999523162841796875,"alpha":0.5},"forceIndex":1,"name":"fredthedeadhead","isShowOnMap":true,"isSpectator":false,"tag":"","lastOnline":0,"onlineTime":0,"afkTime":0,"isConnected":true}} + */ From 33de9f0d06a022cfe4937a93fe57e7a8672b5cc0 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 26 Feb 2022 22:24:04 +0100 Subject: [PATCH 231/629] fix compiler warning for opt-in requirement --- modules/infra-kafka-connect/build.gradle.kts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/infra-kafka-connect/build.gradle.kts b/modules/infra-kafka-connect/build.gradle.kts index 7e4acff..67954a0 100644 --- a/modules/infra-kafka-connect/build.gradle.kts +++ b/modules/infra-kafka-connect/build.gradle.kts @@ -1,4 +1,5 @@ import dev.adamko.kafkatorio.gradle.asConsumer +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { @@ -107,3 +108,9 @@ idea { excludeDirs.add(file("src/main/docker/camel-kafka-connectors")) } } + +tasks.withType().configureEach { + kotlinOptions.freeCompilerArgs += listOf( + "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", + ) +} From 8a57f9daea91af5853506fd6221d988161a692ad Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 26 Feb 2022 22:24:42 +0100 Subject: [PATCH 232/629] add commented out -Xextended-compiler-checks just in case it happens again --- .../main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index a888607..02cee18 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -47,6 +47,7 @@ tasks.withType().configureEach { "-opt-in=kotlin.RequiresOptIn", "-opt-in=kotlin.ExperimentalStdlibApi", "-opt-in=kotlin.time.ExperimentalTime", +// "-Xextended-compiler-checks", // "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", // "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", ) From 99a7167485a104920fe98639e6f07e9710fb248d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 27 Feb 2022 01:01:24 +0100 Subject: [PATCH 233/629] improve kafka consumer group gradle task --- .../task/KafkaConsumersResetTask.kt | 66 ++++++++++++------- modules/events-server/build.gradle.kts | 11 +++- 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/KafkaConsumersResetTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/KafkaConsumersResetTask.kt index 08feb0e..e9599f3 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/KafkaConsumersResetTask.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/KafkaConsumersResetTask.kt @@ -2,60 +2,76 @@ package dev.adamko.kafkatorio.task import dev.adamko.kafkatorio.gradle.execCapture import org.gradle.api.DefaultTask -import org.gradle.api.file.DirectoryProperty import org.gradle.api.logging.LogLevel -import org.gradle.api.tasks.Destroys import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal import org.gradle.api.tasks.TaskAction import org.intellij.lang.annotations.Language import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs -abstract class KafkaConsumersResetTask : DefaultTask() { +abstract class KafkaConsumerGroupsTask : DefaultTask() { @get:Input val bootstrapServer: String = "localhost:9092" @get:Input - val kafkaContainerName: String = "kafka" - @get:Destroys - abstract val kafkaStateDir: DirectoryProperty + val kafkaDockerContainerName: String = "kafka" + @get:Internal + protected val bootstrapArg = "--bootstrap-server $bootstrapServer" - @TaskAction - fun resetKafkaConsumers() { - val bootstrapArg = "--bootstrap-server $bootstrapServer" + abstract class ResetAll : KafkaConsumerGroupsTask() { - val allGroups = dockerExec( + @get:Input + @Language("Shell Script") + val resetCommand: String = """ - /kafka/bin/kafka-consumer-groups.sh --list $bootstrapArg + /kafka/bin/kafka-consumer-groups.sh --execute --reset-offsets --all-topics --to-earliest $bootstrapArg """.trimIndent() - ).lines() - .filter { it.trim().isNotBlank() } - allGroups - .forEach { group -> + @TaskAction + fun reset() { + getAllGroups().forEach { group -> logger.lifecycle("Resetting group $group\n---") - dockerExec( - """ - /kafka/bin/kafka-consumer-groups.sh --group $group --execute --reset-offsets --all-topics --to-earliest $bootstrapArg - """.trimIndent() - ) + dockerExec("$resetCommand --group $group") logger.lifecycle("---") } - - project.delete { - delete(kafkaStateDir) } } + abstract class DeleteAll : KafkaConsumerGroupsTask() { + + @get:Input + @Language("Shell Script") + val deleteCommand: String = + """ + /kafka/bin/kafka-consumer-groups.sh --delete $bootstrapArg + """.trimIndent() + + @TaskAction + fun reset() { + val groups = getAllGroups().joinToString(" ") { group -> "--group $group" } + dockerExec("$deleteCommand $groups") + } + } + + @Internal + protected fun getAllGroups(): List = dockerExec( + """ + /kafka/bin/kafka-consumer-groups.sh --list $bootstrapArg + """.trimIndent() + ).lines() + .filter { it.trim().isNotBlank() } + + // fun reset(applicationId: String) = """ // /kafka/bin/kafka-streams-application-reset.sh --application-id $applicationId --force --to-earliest // """.trimIndent() - private fun dockerExec( + protected fun dockerExec( @Language("Shell Script") cmd: String ): String = project.execCapture { logging.captureStandardOutput(LogLevel.LIFECYCLE) - commandLine = parseSpaceSeparatedArgs(""" docker exec $kafkaContainerName $cmd """) + commandLine = parseSpaceSeparatedArgs(""" docker exec $kafkaDockerContainerName $cmd """) } } diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 281f368..4007c64 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -1,4 +1,4 @@ -import dev.adamko.kafkatorio.task.KafkaConsumersResetTask +import dev.adamko.kafkatorio.task.KafkaConsumerGroupsTask import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -63,9 +63,14 @@ tasks.withType { } -val kafkaConsumersReset by tasks.registering(KafkaConsumersResetTask::class) { +val kafkaStateDirDelete by tasks.registering(Delete::class) { + group = project.name + mustRunAfter(kafkaConsumersDelete) + delete(layout.buildDirectory.dir("kafka-state")) +} + +val kafkaConsumersDelete by tasks.registering(KafkaConsumerGroupsTask.DeleteAll::class) { group = project.name - kafkaStateDir.set(project.layout.buildDirectory.dir("kafka-state")) } //tasks.run.configure { From ebb8482201d0738e056209d3e439f6f59ffa81c1 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 27 Feb 2022 01:02:33 +0100 Subject: [PATCH 234/629] make factorio ID value classes, nicer, and remove 'EncodeDefault' from colours --- .../events/schema/factorioCommonData.kt | 8 -------- .../kafkatorio/events/schema/factorioIds.kt | 20 ++++++++++++++----- .../events/schema/FactorioEventTest.kt | 3 +-- .../kafkatorio/processor/eventProcessor.kt | 3 --- .../processor/topology/flowMapTiles.kt | 2 +- 5 files changed, 17 insertions(+), 19 deletions(-) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index 3ea33fd..993e00d 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -67,13 +67,9 @@ data class MapBoundingBox( */ @Serializable data class Colour( - @EncodeDefault // remove encode default? val red: Float = 0f, - @EncodeDefault val green: Float = 0f, - @EncodeDefault val blue: Float = 0f, - @EncodeDefault val alpha: Float = 1f, ) @@ -81,13 +77,9 @@ data class Colour( /** Size-efficient version of [Colour] (`4*4` bytes vs `4*1` bytes) */ @Serializable data class ColourHex( - @EncodeDefault // remove encode default? val red: UByte = UByte.MIN_VALUE, - @EncodeDefault val green: UByte = UByte.MIN_VALUE, - @EncodeDefault val blue: UByte = UByte.MIN_VALUE, - @EncodeDefault val alpha: UByte = UByte.MAX_VALUE, ) { companion object { diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioIds.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioIds.kt index 525ada3..4dcdb76 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioIds.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioIds.kt @@ -11,26 +11,36 @@ import kotlinx.serialization.Serializable */ @Serializable @JvmInline -value class SurfaceIndex(val value: UInt) +value class SurfaceIndex(private val id: UInt) { + override fun toString(): String = "$id" +} @Serializable @JvmInline -value class ForceIndex(val value: UInt) +value class ForceIndex(private val id: UInt) { + override fun toString(): String = "$id" +} /** The player's index in `LuaGameScript::players` */ @Serializable @JvmInline -value class PlayerIndex(val value: UInt) +value class PlayerIndex(private val id: UInt) { + override fun toString(): String = "$id" +} /** This is universally unique for every entity that has one, for the lifetime of a whole game. */ @Serializable @JvmInline -value class UnitNumber(val value: UInt) +value class UnitNumber(private val id: UInt) { + override fun toString(): String = "$id" +} @Serializable @JvmInline -value class PrototypeName(val value: String) +value class PrototypeName(private val id: String) { + override fun toString(): String = id +} diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt index 4c2abd3..248e22b 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt @@ -33,8 +33,7 @@ class FactorioEventTest : FunSpec({ "chatColour": { "red": 1, "green": 0.62, - "blue": 0.25, - "alpha": 1 + "blue": 0.25 }, "lastOnline": 2287061 }, diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt index 921e401..8d9c6e2 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -9,9 +9,6 @@ import org.http4k.server.Undertow import org.http4k.server.asServer -//private val appProps = ApplicationProperties() - - fun main(): Unit = runBlocking { KafkatorioKafkaAdmin.createKafkatorioTopics() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt index e604844..3b30df1 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt @@ -70,7 +70,7 @@ private value class TilePngFilename( ) { constructor(cmd: Cmd.CreateImage) : this(buildString { append("src/main/resources/kafkatorio-web-map") - append("/s${cmd.surfaceIndex.value}") + append("/s${cmd.surfaceIndex}") append("/z${cmd.chunkSize.zoomLevel}") append("/x${cmd.chunkPosition.x}") append("/y${cmd.chunkPosition.y}") From 52fcfbaa939bdda6f7a2c43241e1c2b90396df4e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 28 Feb 2022 20:34:56 +0100 Subject: [PATCH 235/629] update web-map to include event-update changes --- .../adamko/kafkatorio/webmap/converters.kt | 7 +- .../dev/adamko/kafkatorio/webmap/state.kt | 186 ++++++++++++++---- .../adamko/kafkatorio/webmap/websockets.kt | 29 ++- 3 files changed, 159 insertions(+), 63 deletions(-) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt index 386370b..4c241ae 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt @@ -1,7 +1,10 @@ package dev.adamko.kafkatorio.webmap -import dev.adamko.kafkatorio.events.schema.PlayerData +import dev.adamko.kafkatorio.events.schema.MapEntityPosition +import dev.adamko.kafkatorio.events.schema.PlayerUpdate import io.kvision.maps.Maps import io.kvision.maps.externals.leaflet.geo.LatLng -fun PlayerData.latLng(): LatLng = Maps.L.latLng((position.y * -1) to position.x) +fun PlayerUpdate.latLng(): LatLng? = position?.latLng() + +fun MapEntityPosition.latLng(): LatLng = Maps.L.latLng((this.y * -1) to this.x) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt index d42f6e9..041eff0 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt @@ -1,12 +1,17 @@ package dev.adamko.kafkatorio.webmap -import dev.adamko.kafkatorio.events.schema.FactorioEvent -import dev.adamko.kafkatorio.events.schema.PlayerData +import dev.adamko.kafkatorio.events.schema.Colour +import dev.adamko.kafkatorio.events.schema.MapEntityPosition +import dev.adamko.kafkatorio.events.schema.PlayerIndex +import dev.adamko.kafkatorio.events.schema.PlayerUpdate +import dev.adamko.kafkatorio.events.schema.SurfaceIndex +import dev.adamko.kafkatorio.events.schema.Tick import dev.adamko.kafkatorio.events.schema.converters.toHexString -import io.kvision.maps.externals.leaflet.layer.overlay.Tooltip -import io.kvision.maps.externals.leaflet.layer.vector.CircleMarker import io.kvision.maps.Maps import io.kvision.maps.Maps.Companion.L +import io.kvision.maps.externals.leaflet.geo.LatLng +import io.kvision.maps.externals.leaflet.layer.overlay.Tooltip +import io.kvision.maps.externals.leaflet.layer.vector.CircleMarker import io.kvision.redux.ReduxStore import io.kvision.redux.createReduxStore import io.kvision.utils.obj @@ -25,71 +30,166 @@ fun createFactorioReduxStore(): ReduxStore = data class FactorioGameState( val kvMaps: Maps, - val players: Map, + val players: Map, ) sealed class FactorioUpdate : RAction { - data class PlayerUpdate(val event: FactorioEvent, val playerData: PlayerData) : - FactorioUpdate() + data class Player(val tick: Tick, val data: PlayerUpdate) : FactorioUpdate() } fun factorioGameReducer(state: FactorioGameState, update: FactorioUpdate): FactorioGameState = when (update) { - is FactorioUpdate.PlayerUpdate -> { + is FactorioUpdate.Player -> { - val playerState = state.players.getOrElse(update.playerData.name) { - val newState = PlayerState(update.playerData) - state.kvMaps.leafletMap { - addLayer(newState.mapMarker) - newState.mapMarker.openPopup() -// setView(update.playerData.latLng()) - } - newState + val playerState = state.players.getOrElse(update.data.index) { + PlayerState(update.data.index, update.tick) } - playerState.update(update.playerData) + playerState.update(update.tick, update.data) - val updatedPlayersState = state.players + (update.playerData.name to playerState) + state.kvMaps.leafletMap { + + val playerMarker = playerState.mapMarker + + if (playerMarker != null) { + when (playerState.playerDetails) { + is PlayerDetailsState.Known -> if (!hasLayer(playerMarker)) addLayer(playerMarker) + is PlayerDetailsState.Unknown -> if (hasLayer(playerMarker)) removeLayer(playerMarker) + } + } + } + + val updatedPlayersState = state.players + (playerState.index to playerState) state.copy(players = updatedPlayersState) } } -data class PlayerState( - private var playerData: PlayerData, - val mapMarker: CircleMarker = createMapMarker(playerData) +class PlayerState( + val index: PlayerIndex, + private var lastTick: Tick, ) { + var playerDetails: PlayerDetailsState = PlayerDetailsState.Unknown(index) + private set - fun update(playerData: PlayerData) { - this.playerData = playerData - mapMarker.setLatLng(playerData.latLng()) - println("updated player ${playerData.name}") + var mapMarker: CircleMarker? = null + private set + + fun update(tick: Tick, update: PlayerUpdate) { + + if (lastTick.value > tick.value) { + println("discarding old PlayerUpdate, ${lastTick.value} > ${tick.value}") + return + } + this.lastTick = tick + this.playerDetails = updatePlayerDetails(update) + + updateMapPosition() + + println("updated PlayerState index:${playerDetails.index}, name:${playerDetails.name}") } - companion object { + private fun updatePlayerDetails(update: PlayerUpdate): PlayerDetailsState { - fun createMapMarker(playerData: PlayerData): CircleMarker { + val position = update.position ?: playerDetails.position + val surfaceIndex = update.surfaceIndex ?: playerDetails.surfaceIndex + val colour = update.colour ?: playerDetails.colour + val name = update.name ?: playerDetails.name - val playerLatLng = playerData.latLng() - val playerMapTooltip = "${playerData.name} [$playerLatLng]" + return when { + position != null && surfaceIndex != null && colour != null && name != null -> + PlayerDetailsState.Known( + index = playerDetails.index, + position = position, + surfaceIndex = surfaceIndex, + colour = colour, + name = name, + ) - val circle = L.circleMarker(playerLatLng) { - color = playerData.colour.toHexString(false) - fillColor = color - fillOpacity = 1f - radius = 10 - className = playerData.objectName.name -// interactive = false - } - - circle.bindTooltip(playerMapTooltip, obj { -// interactive = false - }) - - return circle + else -> + PlayerDetailsState.Unknown( + index = playerDetails.index, + position = position, + surfaceIndex = surfaceIndex, + colour = colour, + name = name, + ) } } + + private fun updateMapPosition() { + + when (val details = playerDetails) { + is PlayerDetailsState.Unknown -> { + println("removing player ${details.index} map marker") + mapMarker?.remove() + } + is PlayerDetailsState.Known -> updateMapMarker(details) + } + + } + + private fun updateMapMarker(playerDetails: PlayerDetailsState.Known) { + + if (mapMarker == null) { + mapMarker = L.circleMarker(playerDetails.latLng) { + fillOpacity = 1f + radius = 10 + className = "player-marker" +// interactive = false + }.also { circle -> + circle.bindTooltip("", obj { +// interactive = false + }) + } + } + + mapMarker?.apply { + val playerColour = playerDetails.colour.toHexString(false) + options.color = playerColour + options.fillColor = playerColour + + setTooltipContent("${playerDetails.name} [${playerDetails.latLng}]") + setLatLng(playerDetails.latLng) + } + + } +} + + +sealed interface PlayerDetailsState { + + val index: PlayerIndex + + val position: MapEntityPosition? + val surfaceIndex: SurfaceIndex? + val colour: Colour? + val name: String? + val latLng: LatLng? + + data class Unknown( + override val index: PlayerIndex, + + override val position: MapEntityPosition? = null, + override val surfaceIndex: SurfaceIndex? = null, + override val colour: Colour? = null, + override val name: String? = null, + ) : PlayerDetailsState { + override val latLng: LatLng? = null + } + + data class Known( + override val index: PlayerIndex, + + override val position: MapEntityPosition, + override val surfaceIndex: SurfaceIndex, + override val colour: Colour, + override val name: String, + ) : PlayerDetailsState { + override val latLng: LatLng = position.latLng() + } + } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt index 9023676..3e0c8a5 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -1,16 +1,13 @@ package dev.adamko.kafkatorio.webmap -import dev.adamko.kafkatorio.events.schema.ConsoleChatMessage -import dev.adamko.kafkatorio.events.schema.EntityData +import dev.adamko.kafkatorio.events.schema.EntityUpdate import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate import dev.adamko.kafkatorio.events.schema.FactorioEvent import dev.adamko.kafkatorio.events.schema.FactorioEventUpdatePacket import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -import dev.adamko.kafkatorio.events.schema.MapChunk -import dev.adamko.kafkatorio.events.schema.MapTiles -import dev.adamko.kafkatorio.events.schema.PlayerData -import dev.adamko.kafkatorio.events.schema.SurfaceData +import dev.adamko.kafkatorio.events.schema.MapChunkUpdate +import dev.adamko.kafkatorio.events.schema.PlayerUpdate import io.kvision.redux.ReduxStore import kotlinx.serialization.decodeFromString import org.w3c.dom.MessageEvent @@ -39,22 +36,18 @@ class WebsocketService( println(data.replace('\n', ' ')) when (val event: KafkatorioPacket = jsonMapper.decodeFromString(data)) { - is FactorioEvent -> { - when (val eventData = event.data) { - is PlayerData -> - reduxStore.dispatch(FactorioUpdate.PlayerUpdate(event, eventData)) - is ConsoleChatMessage, - is EntityData, - is MapChunk, -// is MapTile, - is SurfaceData, - is MapTiles -> { + is FactorioEvent -> { + } + is FactorioEventUpdatePacket -> { + when (val eventUpdate = event.update) { + is PlayerUpdate -> reduxStore.dispatch(FactorioUpdate.Player(event.tick, eventUpdate)) + is EntityUpdate, + is MapChunkUpdate -> { } } } - is FactorioEventUpdatePacket, is FactorioConfigurationUpdate, - is FactorioPrototypes -> { + is FactorioPrototypes -> { // to be continued... } } From c5d4ae8d63eb6e7bc3db14f599476ccafd155c0c Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 28 Feb 2022 20:35:15 +0100 Subject: [PATCH 236/629] fix factorio command --- .../main/commands/kafkatorioCommands.ts | 81 ++++++++++--------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts index 9b5faba..8286f8c 100644 --- a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts +++ b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts @@ -11,60 +11,63 @@ commands.add_command( const player = (e.player_index != null) ? game.get_player(e.player_index) : null - const paramUppercase = e.parameter?.toUpperCase() - - if (paramUppercase == undefined) { + if (e.parameter == undefined) { if (player != null) { player.print("no parameter") } // do nothing - } else if ("PROTOTYPES" == paramUppercase) { - emitPrototypes() - } else if (paramUppercase.startsWith("CHUNKS")) { + } else { - let size = paramUppercase.split(" ")?.[1] ?? null - let radius = (size != null) ? parseInt(size) : 1 + const paramUppercase: string = e.parameter.toUpperCase() - if (e.player_index != undefined) { - let player = game.players[e.player_index] + if ("PROTOTYPES" == paramUppercase) { + emitPrototypes() + } else if (paramUppercase.startsWith("CHUNKS")) { - let chunkPosition: ChunkPosition = { - x: floor(player.position.x / 32), - y: floor(player.position.y / 32), - } + let size = paramUppercase.split(" ")?.[1] ?? null + let radius = (size != null) ? parseInt(size) : 1 - let chunkXMin = chunkPosition.x - radius - let chunkXMax = chunkPosition.x + radius - let chunkYMin = chunkPosition.y - radius - let chunkYMax = chunkPosition.y + radius + if (e.player_index != undefined) { + let player = game.players[e.player_index] - for (let [, surface] of game.surfaces) { - for (let chunk of surface.get_chunks()) { - if ( - (chunk.x >= chunkXMin && chunk.x <= chunkXMax) - && - (chunk.y >= chunkYMin && chunk.y <= chunkYMax) - ) { + let chunkPosition: ChunkPosition = { + x: floor(player.position.x / 32), + y: floor(player.position.y / 32), + } - let data: OnChunkGeneratedEvent = { - name: defines.events.on_chunk_generated, - position: {x: chunk.x, y: chunk.y}, - area: chunk.area, - surface: surface, - tick: e.tick + let chunkXMin = chunkPosition.x - radius + let chunkXMax = chunkPosition.x + radius + let chunkYMin = chunkPosition.y - radius + let chunkYMax = chunkPosition.y + radius + + for (let [, surface] of game.surfaces) { + for (let chunk of surface.get_chunks()) { + if ( + (chunk.x >= chunkXMin && chunk.x <= chunkXMax) + && + (chunk.y >= chunkYMin && chunk.y <= chunkYMax) + ) { + + let data: OnChunkGeneratedEvent = { + name: defines.events.on_chunk_generated, + position: {x: chunk.x, y: chunk.y}, + area: chunk.area, + surface: surface, + tick: e.tick + } + + Queue.enqueue( + `${surface.index}${chunk.x}${chunk.y}`, + data, + 50 + ) } - - Queue.enqueue( - `${surface.index}${chunk.x}${chunk.y}`, - data, - 50 - ) } } } + } else if (paramUppercase.startsWith("INIT_GLOBAL")) { + initGlobal(paramUppercase.startsWith("INIT_GLOBAL FORCE")) } - } else if (paramUppercase.startsWith("INIT_GLOBAL")) { - initGlobal(paramUppercase.startsWith("INIT_GLOBAL FORCE")) } } ) From b055397d25d721cfbaebc6aecaf687c165fa70a0 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 2 Mar 2022 18:38:51 +0100 Subject: [PATCH 237/629] - wicked sick size optimisation of map-tiles update packet - fix ts-generator recursive value class unwrapping - move kafka state dir - try fixing kafka streams for tile generation (simplifying it, and fixing some nullability problems) --- .../kafkatorio-schema/prototype.d.ts | 2 +- .../generated/kafkatorio-schema/schema.d.ts | 5 + .../generated/kafkatorio-schema/update.d.ts | 14 +-- .../typescript/main/cache/EventDataCache.ts | 2 +- .../main/events/onMapChunkEventListeners.ts | 41 ++++--- .../events/schema/factorioCommonData.kt | 39 ++++++- .../events/schema/factorioEventUpdates.kt | 9 +- .../events/schema/ValueClassTransformer.kt | 101 +++++++++++------- .../adamko/kafkatorio/events/schema/kt2ts.kt | 4 - modules/events-server/.gitignore | 1 + modules/events-server/build.gradle.kts | 2 +- .../processor/KafkatorioTopology.kt | 49 ++++++--- .../processor/topology/groupMapChunks.kt | 96 +++++++++++------ .../processor/topology/playerUpdates.kt | 6 +- 14 files changed, 253 insertions(+), 118 deletions(-) create mode 100644 modules/events-server/.gitignore diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts index 9021c35..01d4958 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts @@ -15,7 +15,7 @@ interface FactorioPrototypes extends KafkatorioPacket { interface MapTilePrototype extends FactorioPrototype { canBeMined: boolean; collisionMasks: string[]; - layer: int; + layer: uint; mapColour: Colour; name: string; order: string; diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts index ca76f05..7091073 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts @@ -59,3 +59,8 @@ interface EntityIdentifiers { type: string; unitNumber: uint | null; } + +interface MapTileDictionary { + protos: { [key: string]: string }; + tilesXY: { [key: string]: { [key: string]: string } }; +} diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts index a9598fc..ed61598 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts @@ -7,7 +7,7 @@ interface FactorioEventUpdateKey { } interface FactorioEventUpdate extends FactorioEventUpdateKey { - eventCounts: { [key: string]: int } | null; + eventCounts: { [key: string]: uint } | null; updateType: FactorioEventUpdateType; } @@ -30,7 +30,7 @@ interface PlayerUpdate extends FactorioEventUpdate, PlayerUpdateKey { colour: Colour | null; diedCause: EntityIdentifiers | null; disconnectReason: string | null; - eventCounts: { [key: string]: int } | null; + eventCounts: { [key: string]: uint } | null; forceIndex: uint | null; index: uint; isAdmin: boolean | null; @@ -57,12 +57,12 @@ interface EntityUpdateKey extends EntityIdentifiers, FactorioEventUpdateKey { interface EntityUpdate extends FactorioEventUpdate, EntityIdentifiers, EntityUpdateKey { chunkPosition: MapChunkPosition | null; - eventCounts: { [key: string]: int } | null; - graphicsVariation: number | null; + eventCounts: { [key: string]: uint } | null; + graphicsVariation: uint8 | null; health: float | null; isActive: boolean | null; isRotatable: boolean | null; - lastUser: int | null; + lastUser: uint | null; localisedDescription: string | null; localisedName: string | null; name: string; @@ -79,12 +79,12 @@ interface MapChunkUpdateKey extends FactorioEventUpdateKey { interface MapChunkUpdate extends FactorioEventUpdate, MapChunkUpdateKey { chunkPosition: MapChunkPosition; - eventCounts: { [key: string]: int } | null; + eventCounts: { [key: string]: uint } | null; force: uint | null; isDeleted: boolean | null; player: uint | null; robot: EntityIdentifiers | null; surfaceIndex: uint; - tiles: MapTile[] | null; + tileDictionary: MapTileDictionary | null; updateType: FactorioEventUpdateType; } diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts index 7920507..ed59119 100644 --- a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts +++ b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts @@ -20,7 +20,7 @@ export namespace EventDataCache { log("Initialising global.DEFAULT_CACHE_DURATION_TICKS") global.defaultCacheDurationTicks = { - "PLAYER": 60, // 1 second + "PLAYER": 15, // 0.25 seconds "MAP_CHUNK": 60 * 30, // 30 seconds "ENTITY": 60 * 2, // 2 seconds "default": 60 * 5, // 5 seconds diff --git a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts index f2e6665..7d6851b 100644 --- a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts @@ -8,6 +8,17 @@ import CacheData = EventDataCache.CacheData; type MapChunkUpdater = (data: CacheData<"MAP_CHUNK">) => void +const mapProtoNameToKey: { [key: string]: string } = {} +let protoIndex: uint = 0 + +function getProtoKey(protoName: string): string { + if (mapProtoNameToKey[protoName] == undefined) { + mapProtoNameToKey[protoName] = `${protoIndex++}` + } + return mapProtoNameToKey[protoName] +} + + function mapTilesUpdateDebounce( surface: LuaSurface | undefined, chunkPosition: ChunkPositionTable, @@ -27,24 +38,26 @@ function mapTilesUpdateDebounce( updateType: "MAP_CHUNK", }, data => { - if (data.tiles == undefined) { - data.tiles = [] + data.tileDictionary ??= { + tilesXY: {}, + protos: {}, } - for (const tile of tiles) { - data.tiles.push( - { - x: tile.position.x, - y: tile.position.y, - proto: tile.name, - } - ) + for (let tile of tiles) { + + const xString = `${tile.position.x}` + const yString = `${tile.position.y}` + const protoKey = getProtoKey(tile.name) + + data.tileDictionary.protos[protoKey] = tile.name + + data.tileDictionary.tilesXY[xString] ??= {} + data.tileDictionary.tilesXY[xString][yString] = protoKey } - if (data.eventCounts == undefined) { - data.eventCounts = {} - } - data.eventCounts[eventName] = ((data.eventCounts ?? {}) [eventName] ?? 0) + 1 + data.eventCounts ??= {} + data.eventCounts[eventName] ??= 0 + data.eventCounts[eventName]++ if (updater != undefined) { updater(data) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index 993e00d..16d4b55 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -1,7 +1,6 @@ package dev.adamko.kafkatorio.events.schema import kotlin.jvm.JvmInline -import kotlinx.serialization.EncodeDefault import kotlinx.serialization.Serializable @@ -101,3 +100,41 @@ interface EntityIdentifiers { val name: String val type: String } + + +/** + * Size-optimised 2D map of x/y tile positions and prototype-name. + * + * Each X/Y coordinate maps to an arbitrary [PrototypeKey] (which is only valid for any specific + * instance). [protos] is specific to each instance of [MapTileDictionary], can be used to convert from a + */ +@Serializable +data class MapTileDictionary( + /** Map an X,Y coordinate a prototype name */ + val tilesXY: Map>, + val protos: Map +) { + fun toMapTileList(): List = buildList { + tilesXY.forEach { (xString, row) -> + row.forEach { (yString, protoIndex) -> + val x = xString.toIntOrNull() + val y = yString.toIntOrNull() + val protoName = protos[protoIndex] + if (x != null && y != null && protoName != null) { + add(MapTile(x, y, protoName)) + } + } + } + } + + companion object { + fun MapTileDictionary?.isNullOrEmpty(): Boolean { + return this == null || (tilesXY.isEmpty() && tilesXY.all { it.value.isEmpty() }) + } + } +} + + +@Serializable +@JvmInline +value class PrototypeKey(val index: String) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt index fbcd3a1..e66f16f 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt @@ -147,7 +147,7 @@ data class EntityUpdate( override val eventCounts: Map? = null, val chunkPosition: MapChunkPosition? = null, - val graphicsVariation: UShort? = null, + val graphicsVariation: UByte? = null, val health: Float? = null, val isActive: Boolean? = null, val isRotatable: Boolean? = null, @@ -180,11 +180,8 @@ data class MapChunkUpdate( val player: PlayerIndex? = null, val robot: EntityIdentifiers? = null, val force: ForceIndex? = null, - /** updated tiles - might be partial */ - // note: this must be a List, not a Map - // because JSON can't have non-string keys. - @Contextual - val tiles: List? = null, + /** updated tiles - might be partial and not all tiles in the chunk */ + val tileDictionary: MapTileDictionary? = null, val isDeleted: Boolean? = null, ) : FactorioEventUpdate(), MapChunkUpdateKey { @EncodeDefault diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt index bdc9747..daedc28 100644 --- a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt @@ -1,11 +1,15 @@ package dev.adamko.kafkatorio.events.schema +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.contract import kotlin.reflect.KClass +import kotlin.reflect.KClassifier import kotlin.reflect.KProperty import kotlin.reflect.KType import kotlin.reflect.KTypeProjection import kotlin.reflect.full.createType import kotlin.reflect.full.declaredMemberProperties +import kotlin.reflect.full.starProjectedType import kotlin.reflect.full.withNullability import me.ntrrgc.tsGenerator.ClassTransformer @@ -14,54 +18,77 @@ import me.ntrrgc.tsGenerator.ClassTransformer */ object ValueClassTransformer : ClassTransformer { + private val mappedValueClasses: MutableMap = mutableMapOf( + // don't unwrap unsigned numbers - they're mapped to Factorio types + UInt::class.starProjectedType to UInt::class.starProjectedType, + UByte::class.starProjectedType to UByte::class.starProjectedType, + UShort::class.starProjectedType to UShort::class.starProjectedType, + ULong::class.starProjectedType to ULong::class.starProjectedType, + ) + override fun transformPropertyType(type: KType, property: KProperty<*>, klass: KClass<*>): KType { - - val classifier = type.classifier ?: return super.transformPropertyType(type, property, klass) - - val valueClassType = unwrapValueClassType(type) - - if (valueClassType != null) { - println("$klass has a value class $type -> $valueClassType") - return valueClassType + val unwrappedType = + unwrapValueClassType(type, property, klass) + ?: unwrapArgs(type, property, klass) + return when (unwrappedType) { + null -> super.transformPropertyType(type, property, klass) + else -> super.transformPropertyType(unwrappedType, property, klass) } + } - val hasValueClassTypeParameters = type.arguments - .mapNotNull { it.type?.classifier } - .filterIsInstance>() - .any { it.isValue } + private fun unwrapArgs(type: KType, property: KProperty<*>, klass: KClass<*>): KType? { - if (hasValueClassTypeParameters) { + val classifier: KClassifier = type.classifier ?: return type - val args = type.arguments.map { arg -> - when (val vct = unwrapValueClassType(arg.type)) { - null -> arg - else -> KTypeProjection(arg.variance, vct.withNullability(arg.type!!.isMarkedNullable)) - } + return if (type.arguments.isNotEmpty()) { + println("unwrapping args for $type - ${type.arguments}") + + val args = type.arguments.map { arg: KTypeProjection -> + // recursively map each argument + val argType = arg.type!! + val converted = transformPropertyType(argType, property, klass) + KTypeProjection(arg.variance, converted.withNullability(argType.isMarkedNullable)) } - println("$klass has a prop with value class type parameters ${type.arguments} -> $args") - - return classifier.createType( + classifier.createType( arguments = args, nullable = type.isMarkedNullable, annotations = type.annotations, ) - } - - return super.transformPropertyType(type, property, klass) - } - - private fun unwrapValueClassType(type: KType?): KType? { - val klass = type?.classifier as? KClass<*> ?: return null - - return when { - klass.isValue -> klass - .declaredMemberProperties - .first() - .returnType - .withNullability(type.isMarkedNullable) - - else -> null + } else { + null } } + + private fun unwrapValueClassType(type: KType, property: KProperty<*>, klass: KClass<*>): KType? { + + val valueKlass: KClass<*> = type.classifier as? KClass<*> ?: return null + + return if (isValueClass(type)) { + val mappedType = mappedValueClasses.getOrPut(type.withNullability(false)) { + + val result = valueKlass + .declaredMemberProperties + .first() + .returnType + .withNullability(type.isMarkedNullable) + + println("unwrapping value class $type -> $result") + + // recursively unwrap... + val transformed = transformPropertyType(result, property, klass) + transformed.withNullability(false) + } + mappedType.withNullability(type.isMarkedNullable) + } else { + null + } + } + + @OptIn(ExperimentalContracts::class) + private fun isValueClass(type: KType?): Boolean { + contract { returnsNotNull() implies (type != null) } + return (type?.classifier as? KClass<*>)?.isValue == true + } + } diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt index e9c51ef..8483604 100644 --- a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt @@ -21,12 +21,9 @@ fun main(args: Array) { add(FactorioPrototypes::class) add(FactorioConfigurationUpdate::class) - add(FactorioEventUpdatePacket::class) addAll(FactorioEventUpdate::class.sealedSubclasses) addAll(FactorioEventUpdateKey::class.sealedSubclasses) -// addAll(FactorioEventUpdateData::class.sealedSubclasses) - }, mappings = mapOf( // builtin Factorio numeric types > `typed-factorio/generated/builtin-types.d.ts` @@ -74,7 +71,6 @@ private fun splitDefinitions(definitions: String): Map { .split("\n\n") .groupBy { def -> - when { "interface FactorioObjectData " in def || diff --git a/modules/events-server/.gitignore b/modules/events-server/.gitignore new file mode 100644 index 0000000..e7abcfb --- /dev/null +++ b/modules/events-server/.gitignore @@ -0,0 +1 @@ +kafka-state/ diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 4007c64..f0a19ef 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -66,7 +66,7 @@ tasks.withType { val kafkaStateDirDelete by tasks.registering(Delete::class) { group = project.name mustRunAfter(kafkaConsumersDelete) - delete(layout.buildDirectory.dir("kafka-state")) + delete(layout.projectDirectory.dir("kafka-state")) } val kafkaConsumersDelete by tasks.registering(KafkaConsumerGroupsTask.DeleteAll::class) { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 26269b1..5fe672b 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -2,6 +2,8 @@ package dev.adamko.kafkatorio.processor import dev.adamko.kafkatorio.events.schema.ColourHex import dev.adamko.kafkatorio.events.schema.FactorioEvent +import dev.adamko.kafkatorio.events.schema.FactorioEventUpdate +import dev.adamko.kafkatorio.events.schema.FactorioEventUpdatePacket import dev.adamko.kafkatorio.events.schema.FactorioObjectData import dev.adamko.kafkatorio.events.schema.FactorioPrototypes import dev.adamko.kafkatorio.events.schema.KafkatorioPacket @@ -33,6 +35,7 @@ import org.apache.kafka.streams.KafkaStreams import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.StreamsConfig import org.apache.kafka.streams.Topology +import org.apache.kafka.streams.TopologyDescription import org.apache.kafka.streams.kstream.KStream import org.apache.kafka.streams.kstream.KTable @@ -69,20 +72,29 @@ internal class KafkatorioTopology( val tileProtoColourDict = tileProtoColourDictionary(protosStream) - val mapTilesStream: KStream = +// val mapTilesStream: KStream = +// builder.stream( +// "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", +// consumedAs("consume.map-tiles", jsonMapper.serde(), jsonMapper.serde()) +// ) +// +// val mapChunksStream: KStream = +// builder.stream( +// "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", +// consumedAs("consume.map-chunks", jsonMapper.serde(), jsonMapper.serde()) +// ) + + val mapChunksUpdatesStream: KStream = builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", - consumedAs("consume.map-tiles", jsonMapper.serde(), jsonMapper.serde()) - ) - val mapChunksStream: KStream = - builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", - consumedAs("consume.map-chunks", jsonMapper.serde(), jsonMapper.serde()) + "kafkatorio.${KafkatorioPacket.PacketType.UPDATE}.${FactorioEventUpdate.FactorioEventUpdateType.MAP_CHUNK}", + consumedAs("consume.map-chunk-updates", jsonMapper.serde(), jsonMapper.serde()) ) + val groupedMapChunkTiles: KTable> = groupTilesIntoChunksWithColours( - mapTilesStream, - mapChunksStream, +// mapTilesStream, +// mapChunksStream, + mapChunksUpdatesStream, tileProtoColourDict, ) @@ -90,7 +102,11 @@ internal class KafkatorioTopology( .toStream("stream-grouped-map-tiles") .to( TOPIC_GROUPED_MAP_CHUNKS, - producedAs("produce.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()) + producedAs( + "produce.grouped-map-chunks", + kxsBinary.serde(), + kxsBinary.serde?>() + ) ) @@ -140,10 +156,19 @@ internal class KafkatorioTopology( val appId = props.compute(StreamsConfig.APPLICATION_ID_CONFIG) { _, v -> "$v.$id" } as? String props.setProperty(StreamsConfig.APPLICATION_ID_CONFIG, appId) - val streams = KafkaStreams(topology, props) streams.setUncaughtExceptionHandler(StreamsExceptionHandler()) + val description: TopologyDescription = topology.describe() + println( + """ + |---------------- + |$appId + |$description + |---------------- + """.trimMargin() + ) + coroutineContext.job.invokeOnCompletion { println("closing $id KafkaStreams") streams.close(Duration.ofSeconds(1)) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt index cb78bd9..28eaab6 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt @@ -1,10 +1,11 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.events.schema.ColourHex -import dev.adamko.kafkatorio.events.schema.FactorioEvent -import dev.adamko.kafkatorio.events.schema.MapChunk +import dev.adamko.kafkatorio.events.schema.FactorioEventUpdatePacket import dev.adamko.kafkatorio.events.schema.MapChunkPosition +import dev.adamko.kafkatorio.events.schema.MapChunkUpdate import dev.adamko.kafkatorio.events.schema.MapTile +import dev.adamko.kafkatorio.events.schema.MapTileDictionary.Companion.isNullOrEmpty import dev.adamko.kafkatorio.events.schema.MapTilePosition import dev.adamko.kafkatorio.events.schema.MapTiles import dev.adamko.kafkatorio.events.schema.SurfaceIndex @@ -13,10 +14,8 @@ import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.materializedWith -import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.flatMap import dev.adamko.kotka.extensions.streams.mapValues -import dev.adamko.kotka.extensions.streams.merge import dev.adamko.kotka.extensions.streams.reduce import dev.adamko.kotka.extensions.tables.join import dev.adamko.kotka.kxs.serde @@ -44,39 +43,70 @@ data class ServerMapChunkTiles( fun groupTilesIntoChunksWithColours( - mapTilePacketsStream: KStream, - mapChunksPacketsStream: KStream, +// mapTilePacketsStream: KStream, +// mapChunksPacketsStream: KStream, + mapChunkUpdatePacketsStream: KStream, tileProtoColourDict: KTable, ): KTable> { - val mapChunkTilesStream: KStream = - mapChunksPacketsStream - .filter { _, packet: FactorioEvent? -> - packet != null - && packet.data is MapChunk - && !((packet.data as? MapChunk)?.tiles?.tiles.isNullOrEmpty()) +// val mapChunkTilesStream: KStream = +// mapChunksPacketsStream +// .filter { _, packet: FactorioEvent? -> +// when (val data = packet?.data) { +// is MapChunk -> data.tiles.tiles.isNotEmpty() +// else -> false +// } +// } +// .mapValues("map-chunk-packets.convert-to-map-tiles") { _, packet: FactorioEvent -> +// (packet.data as MapChunk).tiles +// } +// +// +// val mapTilesStream: KStream = +// mapTilePacketsStream +// .filter { _, packet: FactorioEvent? -> +// when (val data = packet?.data) { +// is MapTiles -> data.tiles.isNotEmpty() +// else -> false +// } +// } +// .mapValues("map-tiles-packets.convert-to-map-tiles") { _, packet: FactorioEvent -> +// packet.data as MapTiles +// } + + val mapChunkUpdatesStream: KStream = + mapChunkUpdatePacketsStream + .filter { _, packet: FactorioEventUpdatePacket? -> + when (val data = packet?.update) { + is MapChunkUpdate -> !data.tileDictionary.isNullOrEmpty() + else -> false + } } - .mapValues("map-chunk-packets.convert-to-map-tiles") { _, packet: FactorioEvent -> - (packet.data as MapChunk).tiles + .mapValues("map-chunk-update-packets.convert-to-map-tiles") { _, packet: FactorioEventUpdatePacket -> + + val mapChunkUpdate: MapChunkUpdate = requireNotNull(packet.update as? MapChunkUpdate) { + "invalid UpdatePacket type $packet" + } + + val tiles: List = requireNotNull(mapChunkUpdate.tileDictionary?.toMapTileList()) { + "invalid MapChunkUpdate packet, tiles must not be null" + } + require(tiles.isNotEmpty()) { + "invalid MapChunkUpdate packet, tiles must not be empty" + } + + MapTiles(mapChunkUpdate.surfaceIndex, tiles) } - val mapTilesStream: KStream = - mapTilePacketsStream - .filter { _, packet: FactorioEvent? -> - packet != null - && packet.data is MapTiles - && !((packet.data as? MapTiles)?.tiles.isNullOrEmpty()) - } - .mapValues("map-tiles-packets.convert-to-map-tiles") { _, packet: FactorioEvent -> - packet.data as MapTiles - } // group tiles by server & surface & chunk val chunkedTilesTable: KTable> = - mapTilesStream - .merge("merge-map-chunk-tiles-with-map-tiles", mapChunkTilesStream) - .filter { _, value -> value != null && value.tiles.isNotEmpty() } + mapChunkUpdatesStream +// mapTilesStream +// .merge("merge-mapTilesStream-with-mapChunkTilesStream", mapChunkTilesStream) +// .merge("merge-mapTilesStream-with-mapChunkUpdatesStream", mapChunkUpdatesStream) +// .filter { _, value -> !value?.tiles.isNullOrEmpty() } .flatMap("server-map-data.tiles.flatMapByChunk") { key: FactorioServerId, mapTiles: MapTiles -> val standardChunkSize = ChunkSize.MAX @@ -102,11 +132,15 @@ fun groupTilesIntoChunksWithColours( chunkId to chunkTiles } } - .filter("server-map-data.tiles.filter-not-empty") { _, value -> - value.map.isNotEmpty() - } +// .filter("server-map-data.tiles.filter-not-empty") { _, value -> +// value.map.isNotEmpty() +// } .groupByKey( - groupedAs("server-map-data.tiles.group", kxsBinary.serde(), kxsBinary.serde()) + groupedAs( + "server-map-data.tiles.group", + kxsBinary.serde(), + kxsBinary.serde>() + ) ) .reduce( "server-map-data.tiles.reduce", diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt index 010ded3..b8fb092 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt @@ -1,6 +1,6 @@ package dev.adamko.kafkatorio.processor.topology -import dev.adamko.kafkatorio.events.schema.FactorioObjectData +import dev.adamko.kafkatorio.events.schema.FactorioEventUpdate import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.processor.WebsocketServer import dev.adamko.kafkatorio.processor.serdes.jsonMapper @@ -15,8 +15,8 @@ fun playerUpdatesToWsServer( builder: StreamsBuilder = StreamsBuilder(), ) { builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaPlayer}", - consumedAs("stream-player-updates-for-ws-server", jsonMapper.serde(), jsonMapper.serde()) + "kafkatorio.${KafkatorioPacket.PacketType.UPDATE}.${FactorioEventUpdate.FactorioEventUpdateType.PLAYER}", + consumedAs("EventUpdate.Player-updates-for-ws-server", jsonMapper.serde(), jsonMapper.serde()), ) .foreach { _, value -> // println("sending ${value.packetType} packet to websocket") From a9782a4d908e6d80a0e8c38da3e337d2354e4f3b Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 4 Mar 2022 23:54:45 +0100 Subject: [PATCH 238/629] version bumps, schema tweaks, code tweaks, --- .../kafkatorio-schema/object-data.d.ts | 2 +- .../kafkatorio-schema/prototype.d.ts | 12 +- .../generated/kafkatorio-schema/schema.d.ts | 16 +- .../typescript/main/cache/cacheChecker.ts | 1 - .../main/commands/kafkatorioCommands.ts | 4 +- .../main/typescript/main/events/converters.ts | 2 +- .../main/events/onMapChunkEventListeners.ts | 14 +- .../src/main/typescript/package-lock.json | 26 +- .../src/main/typescript/package.json | 4 +- .../events/schema/factorioLuaObjects.kt | 2 +- .../events/schema/kafkatorioPacket.kt | 2 +- .../events/schema/PrototypesTest.kt | 921 +++++++++++++++++- .../adamko/kafkatorio/events/schema/kt2ts.kt | 2 + .../processor/KafkatorioTopology.kt | 3 +- .../processor/topology/flowMapTiles.kt | 2 +- 15 files changed, 954 insertions(+), 59 deletions(-) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts index 62bb0c4..60cd5c8 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts @@ -23,7 +23,7 @@ interface EntityData extends FactorioObjectData, FactorioLuaControl { active: boolean; force: uint; health: double | null; - healthRatio: double; + healthRatio: double | null; name: string; objectName: ObjectName; playerIndex: uint | null; diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts index 01d4958..a18dd09 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts @@ -6,12 +6,6 @@ interface FactorioPrototype { prototypeObjectName: PrototypeObjectName; } -interface FactorioPrototypes extends KafkatorioPacket { - modVersion: string; - packetType: PacketType; - prototypes: FactorioPrototype[]; -} - interface MapTilePrototype extends FactorioPrototype { canBeMined: boolean; collisionMasks: string[]; @@ -21,3 +15,9 @@ interface MapTilePrototype extends FactorioPrototype { order: string; prototypeObjectName: PrototypeObjectName; } + +interface FactorioPrototypes extends KafkatorioPacket { + modVersion: string; + packetType: PacketType; + prototypes: FactorioPrototype[]; +} diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts index 7091073..d60941b 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts @@ -7,14 +7,6 @@ interface KafkatorioPacket { packetType: PacketType; } -interface FactorioEvent extends KafkatorioPacket { - data: FactorioObjectData; - eventType: string; - modVersion: string; - packetType: PacketType; - tick: uint; -} - interface MapEntityPosition { x: double; y: double; @@ -54,6 +46,14 @@ interface MapTile { y: int; } +interface FactorioEvent extends KafkatorioPacket { + data: FactorioObjectData; + eventType: string; + modVersion: string; + packetType: PacketType; + tick: uint; +} + interface EntityIdentifiers { name: string; type: string; diff --git a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts index 9a7e056..3a3f7ab 100644 --- a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts +++ b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts @@ -3,7 +3,6 @@ import {emitPacket} from "../emitKafkatorioPacket"; /** Every 0.1 seconds */ script.on_nth_tick(6, (nthTick: NthTickEventData) => { - const cachedEvents: Array = EventDataCache.extractExpired() if (cachedEvents.length > 0) { diff --git a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts index 8286f8c..940b8d6 100644 --- a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts +++ b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts @@ -40,8 +40,8 @@ commands.add_command( let chunkYMin = chunkPosition.y - radius let chunkYMax = chunkPosition.y + radius - for (let [, surface] of game.surfaces) { - for (let chunk of surface.get_chunks()) { + for (const [, surface] of game.surfaces) { + for (const chunk of surface.get_chunks()) { if ( (chunk.x >= chunkXMin && chunk.x <= chunkXMax) && diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index 75b8de0..c29e1c5 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -41,7 +41,7 @@ export namespace Converters { type: entity.type, active: entity.active, health: entity.health ?? null, - healthRatio: entity.get_health_ratio(), + healthRatio: entity.get_health_ratio() ?? null, surface: entity.surface.index, unitNumber: entity.unit_number ?? null, position: mapEntityPosition(entity.position), diff --git a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts index 7d6851b..9ec0d13 100644 --- a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts @@ -31,19 +31,21 @@ function mapTilesUpdateDebounce( return } + const key: CacheKey<"MAP_CHUNK"> = { + surfaceIndex: surface.index, + chunkPosition: chunkPosition, + updateType: "MAP_CHUNK", + } + EventDataCache.debounce<"MAP_CHUNK">( - { - surfaceIndex: surface.index, - chunkPosition: chunkPosition, - updateType: "MAP_CHUNK", - }, + key, data => { data.tileDictionary ??= { tilesXY: {}, protos: {}, } - for (let tile of tiles) { + for (const tile of tiles) { const xString = `${tile.position.x}` const yString = `${tile.position.y}` diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index 44d891d..12bc07a 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "enhanced-resolve": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", - "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz", + "integrity": "sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA==", "requires": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -50,11 +50,11 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "resolve": { - "version": "1.21.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.1.tgz", - "integrity": "sha512-lfEImVbnolPuaSZuLQ52cAxPBHeI77sPwCOWRdy12UG/CNa8an7oBHH1R+Fp1/mUqSJi4c8TIP6FOIPSZAUrEQ==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", "requires": { - "is-core-module": "^2.8.0", + "is-core-module": "^2.8.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -75,9 +75,9 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.18.1.tgz", - "integrity": "sha512-osjGO4V809tlDnDI7lXTIOPCcDBwBfKfW6o8zFR04S0/uBAzP4eY3X3GXTPzWK/P3HJ9GXDUHV2Nai2ZRicbkA==" + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.19.1.tgz", + "integrity": "sha512-/iLa916Cw33vC6wgmCb4cPLjmvUA2zVviTx/vy80iEvpOHjoNkuHkGSsmvss1aItwUKUlHaLi3k0fK5OPiw1iA==" }, "typescript": { "version": "4.5.5", @@ -85,9 +85,9 @@ "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==" }, "typescript-to-lua": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.3.3.tgz", - "integrity": "sha512-Fkt0+dLufN5CK0G/qpINY7Sb0+SNmWpov+PHhO/dq0HFoNBzR47M1SJd+hQbG92vTVFLBO4f+Np29LuVvoemMA==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.3.4.tgz", + "integrity": "sha512-9NkUOSUd9tufvwCGiWJ6Z1edizYcECUfjdZJZfDRKTEXKIddbAdV3IFR6u5gxvYYRfXhfNV6IKvqHS2HxHFs6w==", "requires": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 5190f46..c477325 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -13,8 +13,8 @@ }, "dependencies": { "lua-types": "^2.11.0", - "typescript-to-lua": "1.3.3", - "typed-factorio": "0.18.1", + "typescript-to-lua": "1.3.4", + "typed-factorio": "0.19.1", "typescript": "4.5.5" }, "// @types/node": "^12.0.8", diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt index 796914d..e4b45db 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -114,7 +114,7 @@ data class EntityData( override val surface: SurfaceIndex, val active: Boolean, val health: Double?, - val healthRatio: Double, + val healthRatio: Double?, val name: String, val playerIndex: PlayerIndex? = null, val type: String, diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt index be9bfef..e5e947e 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt @@ -38,7 +38,7 @@ object KafkatorioPacketJsonSerializer : JsonContentPolymorphicSerializer { - val type = element + val type: KafkatorioPacket.PacketType? = element .jsonObject[key] ?.jsonPrimitive ?.contentOrNull diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt index 98da4ef..5356ad2 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt @@ -1,13 +1,14 @@ package dev.adamko.kafkatorio.events.schema import io.kotest.core.spec.style.BehaviorSpec +import io.kotest.matchers.collections.shouldContain +import io.kotest.matchers.types.shouldBeInstanceOf import kotlinx.serialization.decodeFromString -class PrototypesTest : BehaviorSpec( - { - Given("Prototypes Json") { - //Language=JSON - val raw = """ +class PrototypesTest : BehaviorSpec({ + Given("Prototypes Json") { + // language=JSON + val raw = """ { "modVersion":"0.2.4", "packetType":"PROTOTYPES", @@ -30,16 +31,908 @@ class PrototypesTest : BehaviorSpec( } ] } -""".trimIndent() - - Then("expect can be parsed") { - val data = jsonMapperKafkatorio.decodeFromString(raw) - println(data) - } + """.trimIndent() + Then("expect can be parsed") { + val data = jsonMapperKafkatorio.decodeFromString(raw) + println(data) } + } -) { - companion object { + + Given("Big prototypes json") { + // language=JSON + val raw = """ + { + "modVersion":"0.3.2", + "packetType":"PROTOTYPES", + "prototypes":[ + { + "prototypeObjectName":"LuaTilePrototype", + "name":"stone-path", + "order":"a[artificial]-a[tier-1]-a[stone-path]", + "layer":60, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":86, + "green":82, + "blue":74, + "alpha":255 + }, + "canBeMined":true + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"concrete", + "order":"a[artificial]-b[tier-2]-a[concrete]", + "layer":61, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":63, + "green":61, + "blue":59, + "alpha":255 + }, + "canBeMined":true + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"hazard-concrete-left", + "order":"a[artificial]-b[tier-2]-b[hazard-concrete-left]", + "layer":62, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":176, + "green":142, + "blue":39, + "alpha":255 + }, + "canBeMined":true + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"hazard-concrete-right", + "order":"a[artificial]-b[tier-2]-c[hazard-concrete-right]", + "layer":62, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":176, + "green":142, + "blue":39, + "alpha":255 + }, + "canBeMined":true + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"refined-concrete", + "order":"a[artificial]-c[tier-3]-a[refined-concrete]", + "layer":64, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":49, + "green":48, + "blue":45, + "alpha":255 + }, + "canBeMined":true + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"refined-hazard-concrete-left", + "order":"a[artificial]-c[tier-3]-b[refined-hazard-concrete-left]", + "layer":65, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":116, + "green":94, + "blue":26, + "alpha":255 + }, + "canBeMined":true + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"refined-hazard-concrete-right", + "order":"a[artificial]-c[tier-3]-c[refined-hazard-concrete-right]", + "layer":65, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":116, + "green":94, + "blue":26, + "alpha":255 + }, + "canBeMined":true + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"landfill", + "order":"a[artificial]-d[utility]-a[landfill]", + "layer":57, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":57, + "green":39, + "blue":26, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"acid-refined-concrete", + "order":"a[artificial]-e[color-concrete]-acid", + "layer":97, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":142, + "green":194, + "blue":40, + "alpha":127 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"black-refined-concrete", + "order":"a[artificial]-e[color-concrete]-black", + "layer":88, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":25, + "green":25, + "blue":25, + "alpha":127 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"blue-refined-concrete", + "order":"a[artificial]-e[color-concrete]-blue", + "layer":73, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":39, + "green":137, + "blue":228, + "alpha":127 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"brown-refined-concrete", + "order":"a[artificial]-e[color-concrete]-brown", + "layer":91, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":76, + "green":29, + "blue":0, + "alpha":127 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"cyan-refined-concrete", + "order":"a[artificial]-e[color-concrete]-cyan", + "layer":94, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":70, + "green":192, + "blue":181, + "alpha":127 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"green-refined-concrete", + "order":"a[artificial]-e[color-concrete]-green", + "layer":70, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":23, + "green":195, + "blue":43, + "alpha":127 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"orange-refined-concrete", + "order":"a[artificial]-e[color-concrete]-orange", + "layer":76, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":221, + "green":127, + "blue":33, + "alpha":127 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"pink-refined-concrete", + "order":"a[artificial]-e[color-concrete]-pink", + "layer":82, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":236, + "green":98, + "blue":131, + "alpha":127 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"purple-refined-concrete", + "order":"a[artificial]-e[color-concrete]-purple", + "layer":85, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":123, + "green":28, + "blue":168, + "alpha":127 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"red-refined-concrete", + "order":"a[artificial]-e[color-concrete]-red", + "layer":67, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":207, + "green":6, + "blue":0, + "alpha":127 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"yellow-refined-concrete", + "order":"a[artificial]-e[color-concrete]-yellow", + "layer":79, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":212, + "green":169, + "blue":19, + "alpha":127 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"grass-1", + "order":"b[natural]-a[grass]-a[grass-1]", + "layer":26, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":55, + "green":53, + "blue":11, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"grass-2", + "order":"b[natural]-a[grass]-b[grass-2]", + "layer":28, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":66, + "green":57, + "blue":15, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"grass-3", + "order":"b[natural]-a[grass]-c[grass-3]", + "layer":29, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":65, + "green":52, + "blue":28, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"grass-4", + "order":"b[natural]-a[grass]-d[grass-4]", + "layer":30, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":59, + "green":40, + "blue":18, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"dry-dirt", + "order":"b[natural]-b[dirt]-a[dry-dirt]", + "layer":18, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":94, + "green":66, + "blue":37, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"dirt-1", + "order":"b[natural]-b[dirt]-b[dirt-1]", + "layer":19, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":141, + "green":104, + "blue":60, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"dirt-2", + "order":"b[natural]-b[dirt]-c[dirt-2]", + "layer":20, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":136, + "green":96, + "blue":59, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"dirt-3", + "order":"b[natural]-b[dirt]-d[dirt-3]", + "layer":21, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":133, + "green":92, + "blue":53, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"dirt-4", + "order":"b[natural]-b[dirt]-e[dirt-4]", + "layer":22, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":103, + "green":72, + "blue":43, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"dirt-5", + "order":"b[natural]-b[dirt]-f[dirt-5]", + "layer":23, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":91, + "green":63, + "blue":38, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"dirt-6", + "order":"b[natural]-b[dirt]-g[dirt-6]", + "layer":24, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":80, + "green":55, + "blue":31, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"dirt-7", + "order":"b[natural]-b[dirt]-h[dirt-7]", + "layer":25, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":80, + "green":54, + "blue":28, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"sand-1", + "order":"b[natural]-c[sand]-a[sand-1]", + "layer":8, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":138, + "green":103, + "blue":58, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"sand-2", + "order":"b[natural]-c[sand]-b[sand-2]", + "layer":9, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":128, + "green":93, + "blue":52, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"sand-3", + "order":"b[natural]-c[sand]-c[sand-3]", + "layer":10, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":115, + "green":83, + "blue":47, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"red-desert-0", + "order":"b[natural]-d[red-desert]-a[red-desert-0]", + "layer":31, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":103, + "green":70, + "blue":32, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"red-desert-1", + "order":"b[natural]-d[red-desert]-b[red-desert-1]", + "layer":14, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":116, + "green":81, + "blue":39, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"red-desert-2", + "order":"b[natural]-d[red-desert]-c[red-desert-2]", + "layer":15, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":116, + "green":84, + "blue":43, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"red-desert-3", + "order":"b[natural]-d[red-desert]-d[red-desert-3]", + "layer":16, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":128, + "green":93, + "blue":52, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"water", + "order":"c[water]-a[water]", + "layer":3, + "collisionMasks":[ + "doodad-layer", + "item-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "mapColour":{ + "red":51, + "green":83, + "blue":95, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"deepwater", + "order":"c[water]-b[deep-water]", + "layer":3, + "collisionMasks":[ + "doodad-layer", + "item-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "mapColour":{ + "red":38, + "green":64, + "blue":73, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"water-green", + "order":"c[water]-c[water-green]", + "layer":3, + "collisionMasks":[ + "doodad-layer", + "item-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "mapColour":{ + "red":31, + "green":48, + "blue":18, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"deepwater-green", + "order":"c[water]-d[deepwater-green]", + "layer":3, + "collisionMasks":[ + "doodad-layer", + "item-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "mapColour":{ + "red":23, + "green":37, + "blue":16, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"water-shallow", + "order":"c[water]-e[water-shallow]", + "layer":6, + "collisionMasks":[ + "item-layer", + "object-layer", + "resource-layer", + "water-tile" + ], + "mapColour":{ + "red":82, + "green":98, + "blue":92, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"water-mud", + "order":"c[water]-g[water-mud]", + "layer":7, + "collisionMasks":[ + "item-layer", + "object-layer", + "resource-layer", + "water-tile" + ], + "mapColour":{ + "red":65, + "green":89, + "blue":90, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"nuclear-ground", + "order":"d[destruction]-a[nuclear]-a[nuclear-ground]", + "layer":33, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":48, + "green":40, + "blue":35, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"water-wube", + "order":"x[wube]-a[water-wube]", + "layer":2, + "collisionMasks":[ + "doodad-layer", + "item-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "mapColour":{ + "red":0, + "green":0, + "blue":0, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"tile-unknown", + "order":"z-a", + "layer":0, + "collisionMasks":{ + + }, + "mapColour":{ + "red":0, + "green":0, + "blue":0, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"out-of-map", + "order":"z[other]-a[out-of-map]", + "layer":0, + "collisionMasks":[ + "doodad-layer", + "floor-layer", + "ground-tile", + "item-layer", + "object-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "mapColour":{ + "red":0, + "green":0, + "blue":0, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"lab-dark-1", + "order":"z[other]-b[lab]-a[lab-dark-1]", + "layer":70, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":49, + "green":49, + "blue":49, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"lab-dark-2", + "order":"z[other]-b[lab]-b[lab-dark-2]", + "layer":70, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":0, + "green":0, + "blue":0, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"lab-white", + "order":"z[other]-b[lab]-c[lab-white]", + "layer":70, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":255, + "green":255, + "blue":255, + "alpha":255 + }, + "canBeMined":false + }, + { + "prototypeObjectName":"LuaTilePrototype", + "name":"tutorial-grid", + "order":"z[other]-c[tutorial]-a[tutorial-grid]", + "layer":55, + "collisionMasks":[ + "ground-tile" + ], + "mapColour":{ + "red":122, + "green":122, + "blue":122, + "alpha":255 + }, + "canBeMined":false + } + ] + } + """.trimIndent() + + Then("expect can be parsed") { + val data: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(raw) + println(data) + + data.shouldBeInstanceOf() + + data.prototypes.shouldContain( + MapTilePrototype( + name = PrototypeName("tutorial-grid"), + order = "z[other]-c[tutorial]-a[tutorial-grid]", + layer = 55u, + collisionMasks = listOf("ground-tile"), + mapColour = Colour(122f, 122f, 122f, 255f), + canBeMined = false, + ) + ) + } + } -} +}) diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt index 8483604..3a04314 100644 --- a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt @@ -21,6 +21,8 @@ fun main(args: Array) { add(FactorioPrototypes::class) add(FactorioConfigurationUpdate::class) + add(FactorioEvent::class) + add(FactorioEventUpdatePacket::class) addAll(FactorioEventUpdate::class.sealedSubclasses) addAll(FactorioEventUpdateKey::class.sealedSubclasses) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 5fe672b..1e8dd10 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -109,7 +109,6 @@ internal class KafkatorioTopology( ) ) - val topology = builder.build() launchTopology("groupTilesMapChunks", topology) } @@ -117,7 +116,7 @@ internal class KafkatorioTopology( private fun saveTiles() { val builder = StreamsBuilder() - val groupedMapChunkTiles: KTable> = + val groupedMapChunkTiles: KTable?> = builder.table( TOPIC_GROUPED_MAP_CHUNKS, consumedAs("consume.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt index 3b30df1..f0b189e 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt @@ -47,7 +47,7 @@ private val serverMapChunkHandler = ServerMapChunkHandler() fun saveMapTiles( - serverMapTable: KTable> + serverMapTable: KTable?> ) { serverMapTable From e630ce3702e7e99d3be9e966c95bc3f65ffd3bc7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 9 Mar 2022 21:40:40 +0100 Subject: [PATCH 239/629] Gradle version bump, and fiddling with some gradle config. Add a 'hardReset' Gradle task. Add a 'docker remove' task. --- build.gradle.kts | 2 +- buildSrc/build.gradle.kts | 8 +++--- buildSrc/repositories.settings.gradle.kts | 14 +--------- .../dev/adamko/kafkatorio/base.gradle.kts | 25 ++++++++++++------ .../infra/docker-compose.gradle.kts | 10 +++++++ ...esetTask.kt => KafkaConsumerGroupsTask.kt} | 0 gradle/wrapper/gradle-wrapper.jar | Bin 59536 -> 59821 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 10 +++---- modules/events-server/build.gradle.kts | 2 +- .../kafkatorio/processor/serdes/kxsBinary.kt | 2 +- .../infra-factorio-client/build.gradle.kts | 2 +- .../infra-factorio-server/build.gradle.kts | 16 ++++++++++- modules/infra-kafka-cluster/build.gradle.kts | 2 +- modules/infra-kafka-connect/build.gradle.kts | 4 +-- modules/infra-kafka-pipe/build.gradle.kts | 2 +- modules/kt-rcon/build.gradle.kts | 4 +-- modules/web-map/build.gradle.kts | 8 +++--- settings.gradle.kts | 16 +++++------ 19 files changed, 77 insertions(+), 52 deletions(-) rename buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/{KafkaConsumersResetTask.kt => KafkaConsumerGroupsTask.kt} (100%) diff --git a/build.gradle.kts b/build.gradle.kts index 60b1341..bf22bd1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -35,7 +35,7 @@ idea { } tasks.wrapper { - gradleVersion = "7.4" + gradleVersion = "7.4.1" distributionType = Wrapper.DistributionType.ALL } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 5af130a..c2216ac 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -15,13 +15,12 @@ object Versions { const val kotlin = "1.6.10" const val gradleNodePlugin = "3.2.1" - const val gradleDockerComposePlugin = "0.15.0" + const val gradleDockerComposePlugin = "0.15.1" const val kotlinXSerialization = "1.3.2" const val kvision = "5.8.1" const val semver = "1.1.2" const val http4k = "4.19.1.0" - const val jsoup = "1.14.3" const val kotest = "5.1.0" } @@ -54,7 +53,10 @@ dependencies { implementation("org.http4k:http4k-core") implementation("org.http4k:http4k-client-okhttp") - implementation("org.jsoup:jsoup:${Versions.jsoup}") + + // https://github.com/gradle/gradle/issues/15383#issuecomment-779893192 + // https://youtrack.jetbrains.com/issue/IDEA-262280#focus=Comments-27-5397040.0-0 +// implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location)) } diff --git a/buildSrc/repositories.settings.gradle.kts b/buildSrc/repositories.settings.gradle.kts index ff14164..a9c0f1e 100644 --- a/buildSrc/repositories.settings.gradle.kts +++ b/buildSrc/repositories.settings.gradle.kts @@ -13,8 +13,6 @@ dependencyResolutionManagement { mavenCentral() jitpack() gradlePluginPortal() -// maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") -// maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") // Declare the Node.js download repository ivy("https://nodejs.org/dist/") { @@ -32,25 +30,15 @@ dependencyResolutionManagement { } pluginManagement { - repositories { gradlePluginPortal() mavenCentral() jitpack() -// maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") } - } } fun RepositoryHandler.jitpack() { - maven("https://jitpack.io") { -// content { -// includeGroup("com.github.aSemy") -// includeGroup("com.github.adamko-dev") -// includeGroup("com.github.adamko-dev.kotka-streams") -// includeGroup("dev.adamko.kotka") -// } - } + maven("https://jitpack.io") } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts index 732bd75..202f788 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts @@ -1,21 +1,30 @@ package dev.adamko.kafkatorio +import org.gradle.api.internal.tasks.userinput.UserInputHandler +import org.gradle.kotlin.dsl.support.serviceOf + plugins { - idea base + idea } -group = "${rootProject.group}.${project.name}" +group = rootProject.group version = rootProject.version -idea { - module { - isDownloadSources = true - isDownloadJavadoc = true - } -} tasks.withType().configureEach { encoding = Charsets.UTF_8.name() comment = " Do not edit manually. This file was created with task '$name'" } + +val hardReset by tasks.registering(Delete::class) { + group = rootProject.name + doFirst("hardResetConfirmation") { + val answer = project.serviceOf() + .askYesNoQuestion("Are you sure you want to permanently delete Kafkatorio data?") + + if (answer != true) { + throw GradleException("Aborting hard reset") + } + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts index a565841..b12d5ef 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts @@ -31,6 +31,16 @@ val dockerDown by tasks.registering(Exec::class) { commandLine = parseSpaceSeparatedArgs(""" docker-compose down """) } + +val dockerRemove by tasks.registering(Exec::class) { + group = dockerComposeTaskGroup + + logging.captureStandardOutput(LogLevel.LIFECYCLE) + + workingDir = dockerSrcDir.asFile + commandLine = parseSpaceSeparatedArgs(""" docker-compose rm --stop -v -f """) +} + afterEvaluate { tasks.named("processRun") { dependsOn(dockerUp, dockerEnv) } tasks.named("processKill") { dependsOn(dockerDown) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/KafkaConsumersResetTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/KafkaConsumerGroupsTask.kt similarity index 100% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/KafkaConsumersResetTask.kt rename to buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/KafkaConsumerGroupsTask.kt diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180f2ae8848c63b8b4dea2cb829da983f2fa..41d9927a4d4fb3f96a785543079b8df6723c946b 100644 GIT binary patch delta 8958 zcmY+KWl$VIlZIh&f(Hri?gR<$?iyT!TL`X;1^2~W7YVSq1qtqM!JWlDxLm%}UESUM zndj}Uny%^UnjhVhFb!8V3s(a#fIy>`VW15{5nuy;_V&a5O#0S&!a4dSkUMz_VHu3S zGA@p9Q$T|Sj}tYGWdjH;Mpp8m&yu&YURcrt{K;R|kM~(*{v%QwrBJIUF+K1kX5ZmF zty3i{d`y0;DgE+de>vN@yYqFPe1Ud{!&G*Q?iUc^V=|H%4~2|N zW+DM)W!`b&V2mQ0Y4u_)uB=P@-2`v|Wm{>CxER1P^ z>c}ZPZ)xxdOCDu59{X^~2id7+6l6x)U}C4Em?H~F`uOxS1?}xMxTV|5@}PlN%Cg$( zwY6c}r60=z5ZA1L zTMe;84rLtYvcm?M(H~ZqU;6F7Evo{P7!LGcdwO|qf1w+)MsnvK5^c@Uzj<{ zUoej1>95tuSvDJ|5K6k%&UF*uE6kBn47QJw^yE&#G;u^Z9oYWrK(+oL97hBsUMc_^ z;-lmxebwlB`Er_kXp2$`&o+rPJAN<`WX3ws2K{q@qUp}XTfV{t%KrsZ5vM!Q#4{V& zq>iO$MCiLq#%wXj%`W$_%FRg_WR*quv65TdHhdpV&jlq<=K^K`&!Kl5mA6p4n~p3u zWE{20^hYpn1M}}VmSHBXl1*-)2MP=0_k)EPr#>EoZukiXFDz?Di1I>2@Z^P$pvaF+ zN+qUy63jek2m59;YG)`r^F3-O)0RDIXPhf)XOOdkmu`3SMMSW(g+`Ajt{=h1dt~ks ztrhhP|L4G%5x79N#kwAHh5N){@{fzE7n&%dnisCm65Za<8r_hKvfx4Bg*`%-*-Mvn zFvn~)VP@}1sAyD+B{{8l{EjD10Av&Mz9^Xff*t`lU=q=S#(|>ls520;n3<}X#pyh& z*{CJf7$*&~!9jMnw_D~ikUKJ2+UnXmN6qak{xx%W;BKuXt7@ky!LPI1qk?gDwG@@o zkY+BkIie>{{q==5)kXw(*t#I?__Kwi>`=+s?Gq6X+vtSsaAO&Tf+Bl$vKnzc&%BHM z=loWOQq~n}>l=EL(5&6((ESsQC3^@4jlO5Od{qN#sWV)vqXw}aA>*uvwZopNN(|-T zRTF%5Y_k1R$;(d-)n;hWex{;7b6KgdAVE@&0pd(*qDzBO#YZV%kh%pYt1`hnQ(Fa& zYiDrOTDqk5M7hzp9kI2h!PxNnuJ&xl*zF8sx6!67bA49R1bmUF5bpK&&{eI0U~cH}PM z3aW1$lRb|ItkG5~_eBNu$|I|vYIdAA9a!pVq<+UTx*M}fG`23zxXp&E=FfnY- zEzKj;Cu_s4v>leO7M2-mE(UzKHL4c$c`3dS*19OpLV^4NI*hWWnJQ9lvzP4c;c?do zqrcsKT*i~eIHl0D3r4N{)+RsB6XhrC^;sp2cf_Eq#6*CV;t8v=V!ISe>>9kPgh}NI z=1UZutslxcT$Ad;_P^;Oouoa(cs!Ctpvi>%aQ+Zp=1d|h{W9Wmf7JWxa(~<#tSZ?C%wu4_5F!fc!<@PIBeJ)Nr^$bB6!_Gic_7}c3J{QI~Gg5g5jTp9}V6KYgrgaX>pJt}7$!wOht&KO|+z{Iw@YL|@~D zMww}+lG}rm2^peNx>58ME||ZQxFQeVSX8iogHLq_vXb`>RnoEKaTWBF-$JD#Q4BMv zt2(2Qb*x-?ur1Y(NsW8AdtX0#rDB?O(Vs4_xA(u-o!-tBG03OI!pQD+2UytbL5>lG z*(F)KacHqMa4?dxa(Vcrw>IIAeB$3cx#;;5r2X;HE8|}eYdAgCw#tpXNy7C3w1q`9 zGxZ6;@1G%8shz9e+!K2MO*{_RjO}Jo6eL3{TSZ>nY7)Qs`Dhi5><@oh0r)gT7H-?3 zLDsd^@m%JvrS8sta5`QiZNs^*GT}Hiy^zjK2^Ni%`Z|ma)D2 zuyumbvw$M8$haCTI~6M%d4+P)uX%u{Sfg4Al+F7c6;O-*)DKI7E8izSOKB#FcV{M+ zEvY0FBkq!$J0EW$Cxl}3{JwV^ki-T?q6C30Y5e&p@8Rd?$ST-Ghn*-`tB{k54W<>F z5I)TFpUC!E9298=sk>m#FI4sUDy_!8?51FqqW!9LN1(zuDnB3$!pEUjL>N>RNgAG~-9Xm|1lqHseW(%v&6K(DZ3Pano(1-Qe?3%J&>0`~w^Q-p&@ zg@HjvhJk?*hpF7$9P|gkzz`zBz_5Z!C4_-%fCcAgiSilzFQef!@amHDrW!YZS@?7C zs2Y9~>yqO+rkih?kXztzvnB^6W=f52*iyuZPv$c42$WK7>PHb z6%MYIr5D32KPdwL1hJf{_#jn?`k(taW?mwmZVvrr=y~fNcV$`}v(8};o9AjOJumS4 z`889O91^pkF+|@$d9wVoZ3;^j;^sUs&Ubo_qD&MTL%O z&*SE0ujG~zm;?x)8TLC&ft))nyI zcg44@*Q{cYT+qGrA=In_X{NNCD+B0w#;@g)jvBU;_8od6U>;7HIo@F*=g8CQUo(u^ z3r4FJ7#<@)MXO&5+DgKE&^>^`r!loe7CWE*1k0*0wLFzSOV8jvlX~WOQ?$1v zk$Or}!;ix0g78^6W;+<=J>z@CBs!<<)HvF(Ls-&`matpesJ5kkjC)6nGB@b{ii6-Uoho$BT%iJgugTOeZ$5Xo4D7Pd< zC*LJh5V@2#5%aBZCgzlQi3@<_!VfiL07ywc)ZbwKPfcR|ElQoS(8x|a7#IR}7#Io= zwg4$8S{egr-NffD)Fg&X9bJSoM25pF&%hf>(T&9bI}=#dPQyNYz;ZZ7EZ=u1n701SWKkZ9n(-qU ztN`sdWL1uxQ1mKS@x11;O|@^AD9!NeoPx}?EKIr!2>1Qq4gjfGU)tr6?Z5l7JAS3j zZeq{vG{rb%DFE4%$szK}d2UzB{4>L?Tv+NAlE*&Nq6g+XauaSI+N2Y8PJLw+aNg1p zbxr|hI8wcMP&&+(Cu|%+Jq|r>+BHk@{AvfBXKiVldN)@}TBS0LdIpnANCVE26WL-} zV}HJ^?m&$Rkq;Zf*i-hoasnpJVyTH__dbGWrB_R55d*>pTyl6(?$EO@>RCmTX1Hzr zT2)rOng?D4FfZ_C49hjMV*UonG2DlG$^+k=Y%|?Dqae4}JOU=8=fgY4Uh!pa9eEqf zFX&WLPu!jArN*^(>|H>dj~g`ONZhaaD%h_HHrHkk%d~TR_RrX{&eM#P@3x=S^%_6h zh=A)A{id16$zEFq@-D7La;kTuE!oopx^9{uA3y<}9 z^bQ@U<&pJV6kq7LRF47&!UAvgkBx=)KS_X!NY28^gQr27P=gKh0+E>$aCx&^vj2uc}ycsfSEP zedhTgUwPx%?;+dESs!g1z}5q9EC+fol}tAH9#fhZQ?q1GjyIaR@}lGCSpM-014T~l zEwriqt~ftwz=@2tn$xP&-rJt?nn5sy8sJ5Roy;pavj@O+tm}d_qmAlvhG(&k>(arz z;e|SiTr+0<&6(-An0*4{7akwUk~Yf4M!!YKj^swp9WOa%al`%R>V7mi z+5+UodFAaPdi4(8_FO&O!Ymb#@yxkuVMrog(7gkj$G@FLA#ENMxG)4f<}S%Fn?Up$+C%{02AgMKa^ z4SFGWp6U>{Q6VRJV}yjxXT*e`1XaX}(dW1F&RNhpTzvCtzuu;LMhMfJ2LBEy?{^GHG!OF!! zDvs64TG)?MX&9NCE#H3(M0K>O>`ca0WT2YR>PTe&tn?~0FV!MRtdb@v?MAUG&Ef7v zW%7>H(;Mm)RJkt18GXv!&np z?RUxOrCfs;m{fBz5MVlq59idhov21di5>WXWD-594L-X5;|@kyWi@N+(jLuh=o+5l zGGTi~)nflP_G}Yg5Pi%pl88U4+^*ihDoMP&zA*^xJE_X*Ah!jODrijCqQ^{=&hD7& z^)qv3;cu?olaT3pc{)Kcy9jA2E8I)#Kn8qO>70SQ5P8YSCN=_+_&)qg)OYBg|-k^d3*@jRAeB?;yd-O1A0wJ z?K*RDm|wE<(PBz~+C%2CTtzCTUohxP2*1kE8Of~{KRAvMrO_}NN&@P7SUO{;zx0iK z@or9R8ydYOFZf(cHASCAatL%;62IL27~SmASr(7F&NMr+#gNw@z1VM z_ALFwo3)SoANEwRerBdRV`>y`t72#aF2ConmWQp(Xy|msN9$yxhZ1jAQ67lq{vbC5 zujj|MlGo`6Bfn0TfKgi(k=gq0`K~W+X(@GzYlPI4g0M;owH3yG14rhK>lG8lS{`!K z+Nc@glT-DGz?Ym?v#Hq|_mEdPAlHH5jZuh*6glq!+>Lk$S%ED2@+ea6CE@&1-9a?s znglt|fmIK}fg<9@XgHe4*q!aO<-;Xj$T?IzB-{&2`#eA6rdtCi80mpP&vw(Uytxu$#YzNI_cB>LS zmim>ys;ir;*Dzbr22ZDxO2s;671&J0U<9(n1yj)J zHFNz=ufPcQVEG+ePjB<5C;=H0{>Mi*xD>hQq8`Vi7TjJ$V04$`h3EZGL|}a07oQdR z?{cR(z+d>arn^AUug&voOzzi$ZqaS)blz-z3zr;10x;oP2)|Cyb^WtN2*wNn`YX!Y z+$Pji<7|!XyMCEw4so}xXLU)p)BA~2fl>y2Tt}o9*BPm?AXA8UE8a;>rOgyCwZBFa zyl42y`bc3}+hiZL_|L_LY29vVerM+BVE@YxK>TGm@dHi@Uw*7AIq?QA9?THL603J% zIBJ4y3n8OFzsOI;NH%DZ!MDwMl<#$)d9eVVeqVl(5ZX$PPbt*p_(_9VSXhaUPa9Qu z7)q4vqYKX7ieVSjOmVEbLj4VYtnDpe*0Y&+>0dS^bJ<8s*eHq3tjRAw^+Mu4W^-E= z4;&namG4G;3pVDyPkUw#0kWEO1;HI6M51(1<0|*pa(I!sj}F^)avrE`ShVMKBz}nE zzKgOPMSEp6M>hJzyTHHcjV%W*;Tdb}1xJjCP#=iQuBk_Eho6yCRVp&e!}4IBJ&?ksVc&u#g3+G$oNlJ?mWfADjeBS-Ph3`DKk-~Z70XugH8sq2eba@4 zIC1H_J$`9b$K`J)sGX3d!&>OmC@@rx1TL~NinQOYy72Q_+^&Mg>Ku(fTgaXdr$p_V z#gav1o{k~c>#)u3r@~6v^o)Lf=C{rAlL@!s457pq)pO;Cojx7U{urO4cvXP|E>+dV zmr2?!-5)tk-&*ap^D^2x7NG6nOop2zNFQ9v8-EZ{WCz-h36C)<^|f{V#R_WE^@(T0+d-at5hXX{U?zak*ac-XnyINo+yBD~~3O1I=a z99|CI>502&s-Qi5bv>^2#cQ%ut<4d7KgQ^kE|=%6#VlGiY8$rdJUH{sra;P~cyb_i zeX(kS%w0C?mjhJl9TZp8RS;N~y3(EXEz13oPhOSE4WaTljGkVXWd~|#)vsG6_76I)Kb z8ro?;{j^lxNsaxE-cfP;g(e;mhh3)&ba}li?woV2#7ByioiD>s%L_D;?#;C#z;a(N z-_WY<=SH42m9bFQ>Nb z@4K$@4l8pD7AKxCR>t0%`Qoy9=hA?<<^Vcj8;-E+oBe3ReW1`el8np8E$k{LgFQ}2 z2t8a`wOXFdJ9!5$&mEfD1CnJ)TB+RJih88-Zos9@HZ# zL#{qfbF0ARTXkR@G{lwlOH~nnL)1jcyu!qv2`57S&%oKz0}r{~l9U_UHaJ5!8#nrs z?2FrL`mxnzu&{bweD&62)ilz*?pYIvt`T!XFVVA78})p1YEy7 z8fK#s?b~Yo$n7&_a?EBdXH-_W)Z44?!;DFx6pZ?~RArtBI*Qm4~6nX6Z_T*i$bQPE;Qz?DAPstpGSqr-AJ zo%m9cA`oDDm?&dTaoh_>@F>a?!y4qt_;NGN9Z<%SS;fX-cSu|>+Pba22`CRb#|HZa z;{)yHE>M-pc1C0mrnT~80!u&dvVTYFV8xTQ#g;6{c<9d!FDqU%TK5T6h*w*p980D~ zUyCb`y3{-?(mJFP)0*-Nt;mI$-gc4VQumh|rs&j_^R{sgTPF`1Xja2YWstsKFuQ(d zmZMxV$p$|qQUXchu&8%J(9|)B?`~rIx&)LqDS>ob5%gTeTP#Sbny#y*rnJ&?(l=!( zoV~}LJ1DPLnF8oyM(2ScrQ0{Q4m4-BWnS4wilgCW-~~;}pw=&<+HggRD_3c@3RQIr z9+-%!%}u_{`YS=&>h%kPO3ce}>y!d-zqiniNR-b5r97u;+K6HA2tS>Z#cV{+eFI`* zd8RMGAUtX1KWfPV;q<-5JAykS+2sY$2~UX+4461a(%{P#{rwFPu0xpIuYlbgD{C7C z=U{FUarVTYX6ZUq3wE@G^QT4H2Re;n$Fz9cJ>hABl)9T8pozqbA1)H-%1=WKm^QMu zjnUZ&Pu>q+X&6Co*y#@pxc-4waKMInEPGmE_>3@Ym3S*dedSradmc5mlJn`i0vMW6 zhBnGQD^Z;&S0lnS0curqDO@({J7kTtRE+Ra?nl^HP9<)W&C>~`!258f$XDbyQOQXG zP8hhySnarOpgu8xv8@WlXnm(Uk~)_3$Sg0vTbU3 z{W!5B(L3{Yy3K5PN<@jEarAtja`}@KYva&zFRF*s+_%jIXh$T(S=an8?=Ry3H*NRqWgsM`&!#|@kf1>=4q%bFw7^Rhz!z5I zyI^zU8_R1WN9`88Z=n>pIZQ`Ixr~_9G%Q}@A7rd#*%y7G zXl^Id=^ZL?Rx}}gWXCqzj9C6;x(~mAH|$JteXa1MH<6UQig@!Hf~t}B%tP0I|H&;y zO6N0}svOa1a^PyP9N5?4W6VF%=Bj{qHUgc8@siw4bafT=UPFSoQqKgyUX>sXTBZ=x zOh^Ad!{kOM9v{%5y}`-8u*T&C7Vq6mD%GR}UeU(*epO&qgC-CkD;%=l)ZuinSzHM` z{@`j&_vC6dDe{Yb9k@1zeV_K6!l(@=6ucoI=R^cH=6{i71%4W3$J-?<8Qn#$-DMtA z6Qqi)t?4ifrt%3jSA#6ji#{f(($KBL-iQh-xrC||3U3lq`9>r)>X%oLvtimuHW-)} zy}>9~|M>w4eES`g7;iBM%Se5-OP%1U6gNWp3AZqT8C6OlFFfQ$|7LL;tBV)(qlp4K zruar^K8FnJN3@_}B;G`a~H`t|3+6d>q3#`ctTkE-D^1#d9NalQ04lH*qUW2!V zhk7#z8OwHhSl8w14;KctfO8ubZJ4$dEdpXE78wABz=n5*=q9ex3S}`e7x~~V-jmHOhtX2*n+pBslo3uosdE7xABK=V#-t{1Hd~?i z{i~%Bw6NYF+F$aK$M`r#xe=NxhA5=p%i7!$);sd>Q}#`G?Q~fygrMXmZw?0#5#17W}6Tj+&kFexG{!mYl5FoA99}3G9l;3lVQ^ z48^~gsVppE*x91WheqI(A%F0Z#$#1UJP1R12Mj9r)y(A?a+iquX+d8WD4WAQJ_!oq z9rTISr7bPd(GTP57xm$}C}&kjMivi;zi^Y9g3&X0A;ovdJ?{%_wHgt%%9P&N4H z^XzV(uNA4 zAP`hgP6BEN5`YXh|DF~6Pud?~gWfhUKoPX4>z|}0aocC&K+AoV%|SX*N!wGq3|y< zg4lP(04XIPmt6}$N!dTk+pZv>u;MTB{L4hp9uXk7>aS!6jqM2lVr%{)H3$O127TSZ z0x9hi0k-P?nWFdQ0K`pykqUIT&jD~B0tHP{ffS(}fZ(aW$oBWTSfHO!A^><6vA?qar%tzN-5NQO zL&|F{nGiQyzNJ+bM$Y`n=Lx^3wTG^o2bGB@cwr1eb+6c-1tN=U+Db;bc~eJ!hwM{SbI=#g?$!PjDB+) zPgU_2EIxocr*EOJG52-~!gml&|D|C2OQ3Y(zAhL}iae4-Ut0F*!z!VEdfw8#`LAi# zhJ_EM*~;S|FMV6y%-SduHjPOI3cFM(GpH|HES<}*=vqY+64%dJYc|k?n6Br7)D#~# zEqO(xepfaf2F{>{E2`xb=AO%A<7RtUq6kU_Iu0m?@0K(+<}u3gVw5fy=Y4CC*{IE3 zLP3YBJ7x+U(os5=&NT%gKi23bbaZ`@;%ln)wp4GpDUT$J8NtFDHJzIe_-t}{!HAsh zJ4<^WovY};)9IKAskSebdQiXv$y5}THuJZ}ouoElIZRui=6lrupV|_Jz=9^&;@HwL;J#@23k?A;k`0Bgf;ioO>W`IQ+4? z7A)eKoY4%+g%=w;=Vm8}H>@U*=*AWNtPqgWRqib#5RTGA@Q=43FrQn3J`GkTUV5yp0U`EOTqjfp+-9;0F8!dMEwwcK%(6`8sDD^aR04 zd6O5vh|Xk?&3dy4f|1QK&Ulf{h6Iq;d-&*ti#Ck>wZFG;GHwc?b;X~eBITx49>2d8 z4HcK&1&DvEGT6kXdzAm4oO8%c}8OBt~8H956_;YP-ss*uMf==a+%w~F>Qkm7r)IAuxuoX}h92$gHqbFUun#8m zWHdy`Zrm#=Pa98x8cO0vd@Tgkr*lm0{dky+Gocr0P8y%HGEI#c3qLqIRc`Oq_C%*; zG+QTr(#Q|yHKv6R@!DmLlwJQ3FAB)Yor-I4zyDyqM4yp5n2TrQH>gRt*Zw0+WI-Sj`EgmYHh=t9! zF6lz^xpqGGpo6!5`sc0a^FVhy_Uxq|@~(1@IIzV)nTpY9sY`CV!?8e&bB8=M&sYEb z2i}fvKdhp9Hs68Y-!QJ<=wE(iQ5+49tqt;Rh|jhYrI5VW-mIz|UY{h8E=rC5sh#DU z?wGgk-Tn!I?+Zer7pHlF_Z^!Kd1qkS3&lv#%s6-<5Y%jQL${cge5=G5Ab?D&|9$Y~ zf%rJC2+=2vg;y0-SJb3<@3%}BO$T$C66q$L_H33a`VUbgW~N(4B=v5(<=My|#|J7q z*Ox4wL4kbJd_~EjLTABSu4U7Jk#`y(6O*U6(k6XxM}CtGZB(H@3~kh*zaGRXM}Iwp zQ%xFk2>@wiZrVCV_G4G~v;NebCQ%T7{SDyPpSv&dT@Cn)Mx@IK*IdNrj{*4pkV4wv z)y0J538h>cpB7iPSzA~x24T`{dzNkpvGIqvt1Dvdq@o-`B=$hkczX8$yFMhsWNK-X zxr$kR$tMD0@W)Vxe1^t9qVmsg&K^F@u84)(n2dttIEAZFN6VD$&tskpG%SI7whGL3 z)DeRiwe&?8m7U{G`oW8!SCi*dM>oYL%UKQnKxV_0RXAEBQg1kStExGEUVwLJ0orGGwb7uv+kPDl7_E2*iD|J*=8A@;XCvwq0aw5oJYN*Yh&o=l} z2z8YKb-fIAH5spql4eXqp*)o2*b>#1@DSt?zZi{GPj0gH&Nm+EI<3^z0w%YTEV4xw zI6$+=Faa|Y4o5i0zm5lOg|&tmnJ806DBovU@Ll6XsA;NRrTK~t*AAJIAS=v-UZ%Pr z$oddI@NRir&erzCwq|)ciJemr-E061j{0Vc@Ys7K(mW|JYj*$+i1Q8XlIK8T?TYS(AXu$`2U zQ@fHxc=AVHl_}cRZQ)w0anMEoqRKKIvS^`<-aMf*FM`NsG&Uowneo+Ji$7DUDYc7*Hjg;-&aHM%3 zXO6cz$$G};Uqh+iY7Wpme>PHG4cu(q;xyskNLs$^uRRMfEg?8Cj~aE-ajM%CXkx0F z>C?g3tIA#9sBQOpe`J+04{q7^TqhFk^F1jFtk4JDRO*`d-fx`GYHb=&(JiaM1b?Y^ zO3Kj3sj76ieol|N$;>j@t#tKj=@*gP+mv}KwlTcPYgR$+)2(gk)2JNE=jSauPq!$< z<|?Sb%W)wS)b>b6i{8!x!^!xIdU3{CJFVnTcw0j{M%DUCF=_>eYYEUWnA-|B(+KYL z_W_`JI&&u^@t0})@DH^1LDuT0s3dMpCHIbYBgOT4Zh_4yHbSqRbtIKndeT4Q*Jg91 z@>rO!^t-G~*AIW;FQ$3J=b;oGg8?CTa~qNCb>&cgp@e;?0AqA&paz~(%PYO+QBo4( zp?}ZdSMWx0iJm7HVNk9A#^9Osa#GPJ!_pYEW}($8>&2}fbr@&ygZ?${A7_9?X$(&5 z#~-hxdPQwCNEpf=^+WH-3`2LxrrBMTa}~qJC9S;VzhG!On^JLyW6WkF{8aAE$sM+( zxr8xLW(KIjI`Rm(24r3OJBk<3GF=G!uSP0-G&AY32mLm8q=#Xom&Pqv=1C{d3>1^ zAjsmV@XZ%BKq^eUfBpa8KvO8ob|F3hAjJv*yo2Bhl0)KUus{qA9m8jf)KnOGGTa6~4>3@J_VzkL|vYPl*uL+Ot*Q7W!f5rJw5+AsjP_IfL+-S*2p| zB7!FhjvkUTxQkGWGSg{X;h~dK>gAJivW?88Nu!3o>ySDaABn$rAYt086#27fbjPQS zhq>55ASvm*60qRdVOY9=bU^+{Pi#!OaZwENN;zy5?EztOHK-Q5;rCuiFl}BSc1YaQ zC-S{=KsGDz@Ji9O5W;XxE0xI|@3o6(2~i4b8Ii9VT;^G$*dRw(V?=br)D&q^XkeBX z+gl~+R@rVD-Hwv@7RHV?Bip5KMI)aV^&snt?H<$Nt=OPx#VxF&BGi?2A2+lNOYywNUGMeGL;|(=UjGDtLG0sN&LpGx;|U;xa13s z;W_|SPk^G}!M9_^pO zA3bt3-tca%^42sHeDtfcC0S3w3H1ny!Bxpa=*k?XRPpx9Bb-gx1J9Yvx)4J(8cG+q z(iCPZ9dsf3#QVyZgD_MW#G#qgV)olu$59&3(PzQfw@%4uZ~<5J=ABvdY43(Qnp{;G zHg3>@T#>DbTuhFl3)fb3TFqdh)V2aq7!;&JOHseTWukvA7}(iGUq;v-{2J0iHSNHq z;+)h!p6Ok^+Sp8-jgL($n6Qu47xyE`cFO5SdZR6;R!FET`tm#0D37z339Suxjpv+s z*=%2-N$N?X&0?x_uut3erF@aBGj;9$k9?3FlbDO{RQa1_qtxrh4!4#fjp4x~akvdTp@ zos?^Q&XE;3N93s4rHQGPrV7+au1$$aB6$hLy*Yz_kN$~dweb9PcB!eYVQTGjFuJP> zZCEwBtb>TIgIO^qAzq@Bv-qud_ZD-2W<_at&ml-gv`tPt$@DF5`HlA zM>DmmMkpv&Zm-8)Y#0bLQf4MpD4_-7M8eu6rh(tL8dq8onHs#R9J~dGd2IaXXMC~h z91pKhnQa%Fsn29nAA1;x(%oC zhca~qQDJaMf?wFrl-Pj;e$bZMYmMF!Y3Lv&Sb?Sjn#!NVx&NDyc^$b4uYyo2OmERa zRz;yDGd@JTykzFLe|Wk-y7#3x`6$wt$zR8r48mdUvfbeL+4D|Z``~7$PrE@qc7rZe zVsIoIbCwzjLZ@_M1*bD{HaYn();Z1-q*-I{tEnTZ(}Zmk&%MXSNBX>o| z-u*RNkAyKC-Srp7c-=@5f)xMWg>o2WWl}j6j9=8+D8;T z>0*0q#;qw8%U8i;6s0fu#I*%(g*@@a2Er@@nyI}{=@W{Z-;`=wN4N~>6Xrh&z#g}l zN1g5}0-#(nHUTv_rl2{yUZ;h#t&Fd?tY!7L%ClY)>uH-Ny2ET$lW$S)IQiN79H)D^ zb&0AXYkupy0~w8)*>Sj_p9}4L?lGTq%VG|2p`nWGhnM^!g|j-|O{%9Q%swOq63|*W zw$(N_laI}`ilB+o!a-wl?er~;;3+)$_akSQ!8YO_&-e*SI7n^(QQ;X0ZE`{4f!gAl z5$d+9CKVNonM!NO_frREICIAxOv)wm>}-k?iRisM`R7;=lyo|E_YR~FpS&PS`Lg0f zl-ON<0S%Uix8J%#yZdkCz4YNhcec<|7*P(JsM#>-L>+tYg_71q9~70FAc^6KW5jql zw!crdgVLH1G_eET=|SEc977;)ezVC|{PJZfra|}@rD;0s&@61mTEBJtILllg{%{vN zfhb&lq0yChaLhnJ-Qb62MB7`>M;|_ceHKZAeeh@#8tbrK!ArP6oXIhMK;dhEJTY`@ z0Tq>MIe0`7tGv)N*F0IGYSJv0vN?Az8g+4K9S!pW2~9F4W(_U_T=jCZrzuZ3*|__T zONp_UWmyePv8C~rckc?Xji;Z5OEqg zC*Um)i;Wh4TEwqReQdVVbUKT^2>Tpi6z_^-uF*adUFug4i@JhzpWT^Sk&E>CyP2?H zWf6x}ehuTs6wvzCnTU&gYzT029Nz19(In1WC z`(1IGmi!O%2AR|BjQa4Q0~u)kM%}?xQyjWuQ16^Gp++;`vr7!k--UZWM*~7Zl|ceO@I3`OpaRhD;YoCuo5IC0uHx>9 z478hu@H|e0Zlo)Zj@01#;8BDs@991xe~^9uG2}UXLM(m7fa}AMwX*tjioBeV&Q8Gx zSq$6wZFkRBK`cMI>R(@W@+lo2t)L+4q-negWRLWZBz*|%=W4v62JrmzNuOtA*x)QE z5L%=OH#@KMdB%Jp^r?0tE}5-*6oP`-lO7Sf)0)n*e<{HA=&qhLR)oD8-+V}Z4=md) z+k9lKf64DB2hAT)UaCP~di?-V3~JBH7itYyk~L6hrnxM%?RKntqd`=!b|e7eFnAcu z3*V;g{xr7TSTm$}DY%~SMpl>m{Sj!We+WfxSEor?YeiAxYUy25pn(?T()E>ByP^c@ zipwvWrhIK((R((VU+;@LmOnDu)ZXB3YArzzin!Z^0;PyJWnlfflo|q8(QY;o1*5CO z##hnkO{uynTMdk`~DOC#1 zdiYxQoy}=@7(ke#A8$YZZVtk4wo$8x28&I;cY3Ro-|kW=*yiiHgCLZeAr)UtVx>Tu z|LvL0hq|1-jC0I4x#>&QZCfrVB=zT!nR|~Uz`9%~2 znl{uZ{VEszW`Fad^q_HB!K9*|U-stK%?~;g?&&+12A}Rq$z($Bzuk^2X(Y=hF?-dQ ztc3DsQKI;qhWIV`99Q#R3xnU0AvY!i*BECj-z9l74|%O=V@nlv|qqC^r^-~C?E zGW%c|uYgnfJ(gjsTm_cIqcv*mYM{+i+&@F@+69ZQOK&u#v4oxUSQJ=tvqQ3W=*m;| z>SkBi8LYb-qRY7Sthh*0%3XAC%$z1rhOJzuX=PkTOa=DlocZUpE#KxVNH5)_4n=T( zGi3YrH7e~sPNYVBd~Grcq#CF~rN{p9Zza-Ntnwfma@TB)=3g36*0lSZg#ixEjFe%+ zX=&LDZ5zqculZ`=RYc^ln(~;nN|Qh6gN=!6f9-N2h+3NWbIxYud&;4SX*tWf5slk4 z{q@@l71UAZgj~*6edXb57fBUxvAS7s(RI=X868JM0+^DCn2yC>;v%S;qPOjB>YVsz(Zx9a>>BK&M zIQK>7_n)4ud0X5YM}^i*keH{ehLsiy9@NvOpsFeQjdI6anLGvVbBw_*fU1TzdVS$i z*4j7z!I5RF#rSz|8ibi$;qE{4`aqWYik7QB5U&F5C*;TO_x+gtzPGpzNt!7~nsBT7)Ckc(K~%uv&{{6A`mmBJVAk-{s~52Vu|HbCH7_W1~ZCX^RflOakGg=jo2Z z<*s;5-J+2@^LRDZ-7EV&Pq+FTErw@pfFqvx^i%E7Fx#^n(E`m2(c>K-O5`M`Yek9el zzTGs5qD6*G;y#~xu3>qWuO?-amKYtvRA}I9z#UspEeM;wOERYeot_n_EUMJf$4_u?E!6X~?q)tPoZb^_;8Y_Ox2h1m<+Le-fsRd|T8db<8#$bqez zua^Z|>h%zdnuU^ww$#-dZ9NTM`FN+!IlLkz*FqWb!x^Z|C{KyGjZ+>G;;7Mb@LY|H zc+Gp`L((Dw7pnDlHNm&;SfHedhx*kad$I^uGz{`0BYelq0yEUHpNKSkvj$|dpvY3{7*YGyhXA^LP0&wOw9oNoC=QoVx1<2Dne8qqZL zm>nFh5DX(-RnQwvHCZQwn^#Z=E!SPVlaRJ78Bo@}!!9dRt^qZy?-*`Pt4WSmgucJv zV1yFkcjlEM^uz-;b#Q7ZCP@Lk)m}uPX={R4B=56k7WNh11BN~0T*vr@!!ow^B0hOR zQ)4)&(e%>bNNL%bm<&8H{*l_L7s0$2GUgX2Vd;=4d9Dm2v3TaL+;L>{K7h7 zV#k?xDPm(NDE31$ z<}|X)pEY6myjK+^gaIMk&Yj2~F0rSKemNqlsVm4c|N7mp_C*L01s;GNx#D-*&gk!qQr}^?_r@q!8fuXw!)fA7xkd} zb>vHvdx~H$5qqAWrow7}+8zBM65-JOt5z za=T6f7MK`XJuQog8kIEboPdhcaVJeHy)5z7EBLK5NRr()E|#K0L0N^JD@pUA^Czb` zbUZ_558y+vqAGeyHCbrvOvLD67Ph}06959VzQ_|>RrXQAqE+AQ(-AaKdxoWaF8hdt z{O3W@b^*o#-f1VuU>YMV03ELF7zkCN4Q&b#prz%3Nne0lSbRo@@ z^ihv%oIl~Qyl6Q;a#$*jOC%x0_;eis*)J7=f@Ct*)xF5 zo}u~@-I}2|$b%5L7>@+Z?4o+1r&v6ceIy+vroK&jCQ<4q&45HP2wCol4hVm3pZtjf zHz1D7oyaSKJ~T{Gx}7ONLA)D5k(%%`WswrDyzX*rn}i}}TB4^y#@mAwPzoC)`?rYv zHgx|trUN#mu*VzUV~8TnJM2Qh*ZM5B{x&y>5An`(M7=Z*Q>TdiH@j*2=moNuOtvpz z+G`@~-`%~+AgPKgke@XiRPgndh@bp*-HRsh;HTtz@-y_uhb%7ylVOTqG0#u?Vn5c5 zEp*XRo|8hcgG^$#{$O9CJ&NE;TrfRpSnLmes&MO{m=N%zc`}gb!eQ7odl$oy1%PI} z#AIxx%oRVy&{O~9xnK4$EY>(eQj}!HKIV$Fz*H=-=Kn)N0D6u`(;iO|VraI4fu_W` z;b5{7;Lyx4za}DU#+U7}=H0dAS#YJJ&g2!P@Htu-AL&w=-)*%P9h2{wR|@?Ff9~)b z^+e_3Hetq7W%ls{!?<6&Y$Z;NNB41pvrv)|MET6AZXFXJeFqbFW5@i5WGzl?bP+~? z*&_puH;wKv2)9T_d+P`bLvJFqX#j&xa*-;0nGBbQf0DC>o~=J_Wmtf*2SZQr?{i~X z9-IbRH8{iy?<0v9Ir1?$66+igy|yDQ5J~A9sFX@Pe<*kCY8+MwH?I z`P}zfQ6l^AO8ehZ=l^ZR;R%uu4;BK*=?W9t|0{+-at(MQZ(CtG=EJFNaFMlKCMXu30(gJUqj5+ z`GM|!keqcj;FKTa_qq;{*dHRXAq157hlB@kL#8%yAm2AgfU|*rDKX@FLlp=HL8ddv zAWLCHe@DcDeB2}fl7#=0+#<05c3=VqM*O3bkr@9X4nO|)q0hU;Gye{L8ZN*NH8Id@mP-u;Fmb8YuorjLrW&ndip8CN%_qp982r w1WEnz9^$&s1hkp_3#lPJQ~!HI7WYYjA7>z!`?f%npAh2%rB@vD|Lau$2O)#1n*aa+ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b1159fc..d7e66b5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index c53aefa..1b6c787 100644 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -32,10 +32,10 @@ # Busybox and similar reduced shells will NOT work, because this script # requires all of these POSIX shell features: # * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». # # Important for patching: # diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index f0a19ef..6972839 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -39,7 +39,7 @@ dependencies { implementation("com.sksamuel.scrimage:scrimage-core:4.0.24") - val kotkaVersion = "v0.0.12" + val kotkaVersion = "v0.0.13" implementation("com.github.adamko-dev.kotka-streams:kotka-streams:$kotkaVersion") { isChanging = true } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt index f61bf25..b1be03c 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt @@ -98,7 +98,7 @@ class KxsDataOutputEncoder( class KxsDataInputDecoder( private val input: DataInput, override val serializersModule: SerializersModule = EmptySerializersModule, - var elementsCount: Int = 0, + private var elementsCount: Int = 0, ) : AbstractDecoder() { private var elementIndex = 0 diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index c52e925..ba5d671 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -5,7 +5,7 @@ import dev.adamko.kafkatorio.gradle.not import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { - id("dev.adamko.kafkatorio.infra.process-runner") + dev.adamko.kafkatorio.infra.`process-runner` } description = "Start the Factorio game client" diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 7f7254c..7cff893 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -3,7 +3,7 @@ import dev.adamko.kafkatorio.gradle.factorioModAttributes import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { - id("dev.adamko.kafkatorio.infra.docker-compose") + dev.adamko.kafkatorio.infra.`docker-compose` } val dockerSrcDir: Directory by extra @@ -57,3 +57,17 @@ idea { excludeDirs.add(file("src/factorio-server")) } } + + +tasks.hardReset { + + dependsOn(tasks.dockerRemove) + + delete( + factorioServerDataDir.dir("saves"), + factorioServerDataDir.dir("temp"), + factorioServerDataDir.file("factorio-current.log"), + factorioServerDataDir.file("factorio-previous.log"), + factorioServerDataDir.file(".lock"), + ) +} diff --git a/modules/infra-kafka-cluster/build.gradle.kts b/modules/infra-kafka-cluster/build.gradle.kts index 8cb355b..35b7263 100644 --- a/modules/infra-kafka-cluster/build.gradle.kts +++ b/modules/infra-kafka-cluster/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("dev.adamko.kafkatorio.infra.docker-compose") + dev.adamko.kafkatorio.infra.`docker-compose` } description = "Kafka cluster" diff --git a/modules/infra-kafka-connect/build.gradle.kts b/modules/infra-kafka-connect/build.gradle.kts index 67954a0..19ce2fa 100644 --- a/modules/infra-kafka-connect/build.gradle.kts +++ b/modules/infra-kafka-connect/build.gradle.kts @@ -3,8 +3,8 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { - id("dev.adamko.kafkatorio.infra.docker-compose") - id("dev.adamko.kafkatorio.lang.kotlin-jvm") + dev.adamko.kafkatorio.infra.`docker-compose` + dev.adamko.kafkatorio.lang.`kotlin-jvm` } val dockerSrcDir: Directory by extra(layout.projectDirectory.dir("src/main/docker")) diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index e2878bb..8566525 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -2,7 +2,7 @@ import org.jetbrains.kotlin.incremental.md5 import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { - id("dev.adamko.kafkatorio.infra.docker-compose") + dev.adamko.kafkatorio.infra.`docker-compose` } description = "Send events from a Factorio server to a Kafka topic " diff --git a/modules/kt-rcon/build.gradle.kts b/modules/kt-rcon/build.gradle.kts index 236d9f6..caa6ded 100644 --- a/modules/kt-rcon/build.gradle.kts +++ b/modules/kt-rcon/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("dev.adamko.kafkatorio.lang.kotlin-jvm") + dev.adamko.kafkatorio.lang.`kotlin-jvm` } //group = "${rootProject.group}.server" @@ -14,4 +14,4 @@ dependencies { implementation("io.ktor:ktor-network:1.6.4") -} \ No newline at end of file +} diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 76426f4..eeebeb0 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -2,7 +2,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig plugins { - id("dev.adamko.kafkatorio.lang.kotlin-js") + dev.adamko.kafkatorio.lang.`kotlin-js` kotlin("plugin.serialization") id("io.kvision") } @@ -39,8 +39,10 @@ kotlin { sourceSets { all { - languageSettings.optIn("kotlin.RequiresOptIn") - languageSettings.optIn("kotlinx.serialization.ExperimentalSerializationApi") + languageSettings.apply { + optIn("kotlin.RequiresOptIn") + optIn("kotlinx.serialization.ExperimentalSerializationApi") + } } main { diff --git a/settings.gradle.kts b/settings.gradle.kts index 174121e..51dc0c9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -28,12 +28,12 @@ dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) - repositories { - mavenLocal { -//// content { -//// includeGroup("io.kvision") -//// includeGroup("dev.adamko.kotka") -//// } - } - } +// repositories { +// mavenLocal { +// content { +// includeGroup("io.kvision") +// includeGroup("dev.adamko.kotka") +// } +// } +// } } From 8eac84da50af8ced1fe9ccd84e4fffcfcd7a320c Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 9 Mar 2022 22:28:29 +0100 Subject: [PATCH 240/629] - add some proper Factorio settings to control EventDataCache - bump Typescript version - make some classes a bit more typescript-ey - comment out some unused code --- .../resources/mod-data/locale/en/locale.cfg | 20 ++ .../events-mod/src/main/typescript/control.ts | 3 + .../kafkatorio-schema/prototype.d.ts | 12 +- .../generated/kafkatorio-schema/schema.d.ts | 16 +- .../typescript/main/cache/EventDataCache.ts | 274 +++++++++--------- .../typescript/main/cache/cacheChecker.ts | 4 +- .../main/typescript/main/events/handlers.ts | 50 ++-- .../main/events/onMapChunkEventListeners.ts | 12 +- .../main/events/onPlayerEventListeners.ts | 29 +- .../main/events/registerHandlers.ts | 41 ++- .../src/main/typescript/main/global-init.ts | 4 +- .../main/settings/KafkatorioSettings.ts | 70 +++++ .../src/main/typescript/package-lock.json | 6 +- .../src/main/typescript/package.json | 2 +- .../src/main/typescript/settings.ts | 7 + 15 files changed, 331 insertions(+), 219 deletions(-) create mode 100644 modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg create mode 100644 modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts create mode 100644 modules/events-mod/src/main/typescript/settings.ts diff --git a/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg b/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg new file mode 100644 index 0000000..0fa9177 --- /dev/null +++ b/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg @@ -0,0 +1,20 @@ +[mod-setting-name] + +kafkatorio_event-cache_default-expiration-duration-seconds_PLAYER=Kafkatorio: Player update rate (seconds) +kafkatorio_event-cache_default-expiration-duration-seconds_MAP_CHUNK=Kafkatorio: Map update rate (seconds) +kafkatorio_event-cache_default-expiration-duration-seconds_ENTITY=Kafkatorio: Entity update rate (seconds) + + +[mod-setting-description] + +kafkatorio_event-cache_default-expiration-duration-seconds_PLAYER=How frequently Player updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (0.25 seconds) is probably fine! +kafkatorio_event-cache_default-expiration-duration-seconds_MAP_CHUNK=How frequently Map updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine! +kafkatorio_event-cache_default-expiration-duration-seconds_ENTITY=How frequently Entity updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (5 seconds) is probably fine! + + +[string-mod-setting] +#-= + + +[string-mod-setting-description] +#-= diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index 40c1b21..18e9161 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -1,6 +1,7 @@ import {emitConfigurationUpdate} from "./main/config-update/handleConfigurationUpdate"; import {emitPrototypes} from "./main/config-update/prototypes"; import {initGlobal} from "./main/global-init"; +import KafkatorioSettings from "./main/settings/KafkatorioSettings"; require("./main/events/registerHandlers") require("./main/events/onMapChunkEventListeners") @@ -12,6 +13,7 @@ script.on_configuration_changed((data: ConfigurationChangedData) => { // runs whenever the version of the base game, or a mod, changes initGlobal(true) + KafkatorioSettings.loadSettings() emitConfigurationUpdate(data) emitPrototypes() }) @@ -20,4 +22,5 @@ script.on_configuration_changed((data: ConfigurationChangedData) => { script.on_init(() => { // runs only once (when the mod is first added to the save) initGlobal(true) + KafkatorioSettings.loadSettings() }) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts index a18dd09..01d4958 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts @@ -6,6 +6,12 @@ interface FactorioPrototype { prototypeObjectName: PrototypeObjectName; } +interface FactorioPrototypes extends KafkatorioPacket { + modVersion: string; + packetType: PacketType; + prototypes: FactorioPrototype[]; +} + interface MapTilePrototype extends FactorioPrototype { canBeMined: boolean; collisionMasks: string[]; @@ -15,9 +21,3 @@ interface MapTilePrototype extends FactorioPrototype { order: string; prototypeObjectName: PrototypeObjectName; } - -interface FactorioPrototypes extends KafkatorioPacket { - modVersion: string; - packetType: PacketType; - prototypes: FactorioPrototype[]; -} diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts index d60941b..7091073 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts @@ -7,6 +7,14 @@ interface KafkatorioPacket { packetType: PacketType; } +interface FactorioEvent extends KafkatorioPacket { + data: FactorioObjectData; + eventType: string; + modVersion: string; + packetType: PacketType; + tick: uint; +} + interface MapEntityPosition { x: double; y: double; @@ -46,14 +54,6 @@ interface MapTile { y: int; } -interface FactorioEvent extends KafkatorioPacket { - data: FactorioObjectData; - eventType: string; - modVersion: string; - packetType: PacketType; - tick: uint; -} - interface EntityIdentifiers { name: string; type: string; diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts index ed59119..8a0b89b 100644 --- a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts +++ b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts @@ -1,133 +1,162 @@ -export namespace EventDataCache { +import KafkatorioSettings from "../settings/KafkatorioSettings"; + +export namespace EventUpdates { declare const global: { cache: LuaTable>, - defaultCacheDurationTicks: Record, } - export function init(force?: boolean) { + export class Manager { - const isAnythingUndefined = global.cache == undefined || - global.defaultCacheDurationTicks == undefined - log(`Initialising EventDataCache (force=${force}, isAnythingUndefined=${isAnythingUndefined})...`) + init(force?: boolean) { - if (force == true || isAnythingUndefined) { - log("Initialising global.cache") - global.cache = new LuaTable>() + const isAnythingUndefined = global.cache == undefined - log("Initialising global.DEFAULT_CACHE_DURATION_TICKS") - global.defaultCacheDurationTicks = { - "PLAYER": 15, // 0.25 seconds - "MAP_CHUNK": 60 * 30, // 30 seconds - "ENTITY": 60 * 2, // 2 seconds - "default": 60 * 5, // 5 seconds + log(`Initialising EventDataCache (force=${force}, isAnythingUndefined=${isAnythingUndefined})...`) + + if (force == true || isAnythingUndefined) { + log("Initialising global.cache") + global.cache = new LuaTable>() + } + log(`Finished initialising EventDataCache`) + } + + + /** + * Update the cache data without restarting the 'time-to-emit' countdown, so that the data won't + * be emitted more than once per {@link CacheEntry.expirationDurationTicks}. + */ + public throttle( + key: CacheKey, + mutate: CacheDataMutator, + ) { + this.update(key, mutate, false) + } + + + /** + * Update the cache data and reset the 'time-to-emit' countdown, so the data won't be emitted + * until there's an inactivity gap of {@link CacheEntry.expirationDurationTicks}. + */ + public debounce( + key: CacheKey, + mutate: CacheDataMutator, + ) { + this.update(key, mutate, true) + } + + + private update( + key: CacheKey, + mutate: CacheDataMutator, + resetLastUpdated: boolean, + ) { + const entry = this.getCacheEntry(key) ?? this.createCacheEntry(key, mutate) + mutate(entry.data) + if (resetLastUpdated) { + entry.lastUpdatedTick = game.tick } } - log(`Finished initialising EventDataCache`) - } - /** - * Update the cache data without restarting the 'time-to-emit' countdown, so that the data won't - * be emitted more than once per {@link CacheEntry.expirationDurationTicks}. - */ - export function throttle( - key: CacheKey, - mutate: CacheDataMutator, - ) { - update(key, mutate, false) - } - - - /** - * Update the cache data and reset the 'time-to-emit' countdown, so the data won't be emitted - * until there's an inactivity gap of {@link CacheEntry.expirationDurationTicks}. - */ - export function debounce( - key: CacheKey, - mutate: CacheDataMutator, - ) { - update(key, mutate, true) - } - - - function update( - key: CacheKey, - mutate: CacheDataMutator, - resetLastUpdated: boolean, - ) { - const entry = getCacheEntry(key) ?? createCacheEntry(key, mutate) - mutate(entry.data) - if (resetLastUpdated) { - entry.lastUpdatedTick = game.tick - } - } - - - /** - * Usage example: If an urgent update comes in, then the expiration can be reduced so that - * it's transmitted sooner. - */ - export function setExpiration( - key: CacheKey, - expirationDurationTicks: uint, - ) { - const entry = getCacheEntry(key) - if (entry != undefined) { - entry.expirationDurationTicks = expirationDurationTicks - } - } - - - export function extractExpired(): Array { - let countExpired = 0 - let countTotal = 0 - const expiredData: Array = [] - for (let [key, entry] of global.cache) { - countTotal++ - if (isExpired(entry)) { - countExpired++ - expiredData.push(entry.data) - global.cache.delete(key) + /** + * Usage example: If an urgent update comes in, then the expiration can be reduced so that + * it's transmitted sooner. + */ + public setExpiration( + key: CacheKey, + expirationDurationTicks: uint, + ) { + const entry = this.getCacheEntry(key) + if (entry != undefined) { + entry.expirationDurationTicks = expirationDurationTicks } } - if (countExpired + countTotal > 0) { - log(`cache expired items count: ${countExpired}, total: ${countTotal}`) + + + public extractExpired(): Array { + let countExpired = 0 + let countTotal = 0 + const expiredData: Array = [] + for (let [key, entry] of global.cache) { + countTotal++ + if (this.isExpired(entry)) { + countExpired++ + expiredData.push(entry.data) + global.cache.delete(key) + } + } + if (countExpired + countTotal > 0) { + log(`cache expired items count: ${countExpired}, total: ${countTotal}`) + } + return expiredData } - return expiredData - } - function getCacheEntry( - key: CacheKey - ): CacheEntry | undefined { - const hash = game.encode_string(game.table_to_json(key))!! - if (!global.cache.has(hash)) { - return undefined + private getCacheEntry( + key: CacheKey + ): CacheEntry | undefined { + const hash = game.encode_string(game.table_to_json(key))!! + if (!global.cache.has(hash)) { + return undefined + } + const value: CacheEntry = global.cache.get(hash) + if (this.isEntryInstanceOf(value, key.updateType)) { + return value + } else { + // Type mismatch. This shouldn't happen... + return undefined + } } - const value: CacheEntry = global.cache.get(hash) - if (isEntryInstanceOf(value, key.updateType)) { - return value - } else { - // Type mismatch. This shouldn't happen... - return undefined + + + private createCacheEntry( + key: CacheKey, + mutate: CacheDataMutator, + ): CacheEntry { + const data: CacheData = >{...key} + mutate(data) + let entry: CacheEntry = new CacheEntry(data) + const hash = game.encode_string(game.table_to_json(key))!! + global.cache.set(hash, entry) + return entry } - } - function createCacheEntry( - key: CacheKey, - mutate: CacheDataMutator, - ): CacheEntry { - const data: CacheData = >{...key} - mutate(data) - let entry: CacheEntry = new CacheEntry(data) - const hash = game.encode_string(game.table_to_json(key))!! - global.cache.set(hash, entry) - return entry + isExpired(entry: CacheEntry): boolean { + const expiryDuration = entry.expirationDurationTicks + ?? + KafkatorioSettings.getEventCacheExpirationTicks(entry.data.updateType) + return game.tick - entry.lastUpdatedTick > expiryDuration + } + + + isEntryInstanceOf( + entry: CacheEntry | undefined, + updateType: TYPE, + ): entry is CacheEntry { + return this.isDataInstanceOf(entry?.data, updateType) + } + + + isDataInstanceOf( + data: CacheData | undefined, + updateType: TYPE, + ): data is CacheData { + return data != undefined && data.updateType == updateType + } + + + // function isKeyInstanceOf( + // key: CacheKey | undefined, + // updateType: TYPE, + // ): key is CacheKey { + // return key != undefined && key.updateType == updateType + // } + } @@ -184,34 +213,7 @@ export namespace EventDataCache { } - function isExpired(entry: CacheEntry): boolean { - const expiryDuration = - entry.expirationDurationTicks ?? global.defaultCacheDurationTicks[entry.data.updateType] - return game.tick - entry.lastUpdatedTick > expiryDuration - } - - - function isEntryInstanceOf( - entry: CacheEntry | undefined, - updateType: TYPE, - ): entry is CacheEntry { - return isDataInstanceOf(entry?.data, updateType) - } - - - function isDataInstanceOf( - data: CacheData | undefined, - updateType: TYPE, - ): data is CacheData { - return data != undefined && data.updateType == updateType - } - - - // function isKeyInstanceOf( - // key: CacheKey | undefined, - // updateType: TYPE, - // ): key is CacheKey { - // return key != undefined && key.updateType == updateType - // } - } + +const EventUpdatesManager = new EventUpdates.Manager() +export default EventUpdatesManager diff --git a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts index 3a3f7ab..2edcb1e 100644 --- a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts +++ b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts @@ -1,9 +1,9 @@ -import {EventDataCache} from "./EventDataCache"; import {emitPacket} from "../emitKafkatorioPacket"; +import EventCacheService from "./EventDataCache"; /** Every 0.1 seconds */ script.on_nth_tick(6, (nthTick: NthTickEventData) => { - const cachedEvents: Array = EventDataCache.extractExpired() + const cachedEvents: Array = EventCacheService.extractExpired() if (cachedEvents.length > 0) { log(`nth tick ${nthTick.tick} has ${cachedEvents.length} events`) diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index 5fffc85..cb6f485 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -78,31 +78,31 @@ export function handleChunkUpdate( emitEvent(mapChunk, tick, eventType) } -export function handleTilesUpdate( - tick: uint, - eventType: string, - surfaceIndex: uint, - newTileType: LuaTilePrototype, - updatedTiles: OldTileAndPosition[], -) { - - if (!newTileType.collision_mask["ground-tile"] && !newTileType.collision_mask["water-tile"]) { - return - } else { - - let convertedTiles: MapTile[] = updatedTiles.map((it) => { - return { - x: it.position.x, - y: it.position.y, - proto: newTileType.name - } - }) - - let mapTiles: MapTiles = createMapTiles(surfaceIndex, convertedTiles) - - emitEvent(mapTiles, tick, eventType) - } -} +// export function handleTilesUpdate( +// tick: uint, +// eventType: string, +// surfaceIndex: uint, +// newTileType: LuaTilePrototype, +// updatedTiles: OldTileAndPosition[], +// ) { +// +// if (!newTileType.collision_mask["ground-tile"] && !newTileType.collision_mask["water-tile"]) { +// return +// } else { +// +// let convertedTiles: MapTile[] = updatedTiles.map((it) => { +// return { +// x: it.position.x, +// y: it.position.y, +// proto: newTileType.name +// } +// }) +// +// let mapTiles: MapTiles = createMapTiles(surfaceIndex, convertedTiles) +// +// emitEvent(mapTiles, tick, eventType) +// } +// } function createMapTiles( surfaceIndex: uint, diff --git a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts index 9ec0d13..3b2284e 100644 --- a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts @@ -1,8 +1,8 @@ -import {EventDataCache} from "../cache/EventDataCache"; import {isEventType} from "./eventTypeCheck"; import {Converters} from "./converters"; -import CacheKey = EventDataCache.CacheKey; -import CacheData = EventDataCache.CacheData; +import EventUpdatesManager, {EventUpdates} from "../cache/EventDataCache"; +import CacheKey = EventUpdates.CacheKey; +import CacheData = EventUpdates.CacheData; type MapChunkUpdater = (data: CacheData<"MAP_CHUNK">) => void @@ -37,7 +37,7 @@ function mapTilesUpdateDebounce( updateType: "MAP_CHUNK", } - EventDataCache.debounce<"MAP_CHUNK">( + EventUpdatesManager.debounce<"MAP_CHUNK">( key, data => { data.tileDictionary ??= { @@ -242,14 +242,14 @@ script.on_event( updateType: "MAP_CHUNK", } - EventDataCache.debounce<"MAP_CHUNK">( + EventUpdatesManager.debounce<"MAP_CHUNK">( key, data => { data.isDeleted = true } ) // deletion is important - emit ASAP - EventDataCache.setExpiration(key, 0) + EventUpdatesManager.setExpiration(key, 0) } } ) diff --git a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts index f844ec3..1f2f6bf 100644 --- a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts @@ -1,6 +1,7 @@ -import {EventDataCache} from "../cache/EventDataCache"; import {Converters} from "./converters"; -import CacheData = EventDataCache.CacheData; +import EventUpdatesManager, {EventUpdates} from "../cache/EventDataCache"; +import CacheData = EventUpdates.CacheData; + type PlayerUpdater = (player: LuaPlayer, data: CacheData<"PLAYER">) => void @@ -9,9 +10,9 @@ function playerUpdateThrottle( eventName: string, mutate: PlayerUpdater, ) { - EventDataCache.throttle<"PLAYER">( + EventUpdatesManager.throttle<"PLAYER">( {index: playerIndex, updateType: "PLAYER"}, - (data => { + data => { const player = game.players[playerIndex] if (player != undefined) { mutate(player, data) @@ -21,19 +22,19 @@ function playerUpdateThrottle( data.eventCounts = {} } data.eventCounts[eventName] = ((data.eventCounts ?? {}) [eventName] ?? 0) + 1 - }) + } ) } -function playerUpdateDebounce(playerIndex: uint, mutate: PlayerUpdater) { - EventDataCache.debounce<"PLAYER">( - {index: playerIndex, updateType: "PLAYER"}, - (data => { - const player = game.players[playerIndex] - mutate(player, data) - }) - ) -} +// function playerUpdateDebounce(playerIndex: uint, mutate: PlayerUpdater) { +// EventUpdatesManager.debounce<"PLAYER">( +// {index: playerIndex, updateType: "PLAYER"}, +// data => { +// const player = game.players[playerIndex] +// mutate(player, data) +// } +// ) +// } function playerOnlineInfo(player: LuaPlayer, data: CacheData<"PLAYER">) { data.lastOnline = player.last_online diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index 61a1138..a5781b4 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -7,6 +7,7 @@ import { import {Queue} from "../queue/queue"; import {isEventType} from "./eventTypeCheck"; import {Converters} from "./converters"; +import KafkatorioSettings from "../settings/KafkatorioSettings"; script.on_event( @@ -46,22 +47,22 @@ script.on_event( // } } - if (e.tick % 30 == 0) { - let events: EventData[] = Queue.dequeueValues(1) - - if (events.length > 0) { - log(`[${e.tick}] dequed ${events.length} events, current size: ${Queue.size()}`) - - for (const event of events) { - if (isEventType(event, defines.events.on_chunk_generated)) { - let eName = Converters.eventNameString(event.name) - - log(`[${e.tick}] dequed event ${eName}`) - handleChunkUpdate(e.tick, eName, event.surface.index, event.position, event.area) - } - } - } - } + // if (e.tick % 30 == 0) { + // let events: EventData[] = Queue.dequeueValues(1) + // + // if (events.length > 0) { + // log(`[${e.tick}] dequed ${events.length} events, current size: ${Queue.size()}`) + // + // for (const event of events) { + // if (isEventType(event, defines.events.on_chunk_generated)) { + // let eName = Converters.eventNameString(event.name) + // + // log(`[${e.tick}] dequed event ${eName}`) + // handleChunkUpdate(e.tick, eName, event.surface.index, event.position, event.area) + // } + // } + // } + // } } ) @@ -80,3 +81,11 @@ script.on_event( // defines.events.on_robot_built_tile, ], (builtTilesEvent) => { handleTilesUpdate( // builtTilesEvent.tick, mapEventIdToName.get(builtTilesEvent.name), builtTilesEvent.surface_index, // builtTilesEvent.tile, builtTilesEvent.tiles, ) } ) + +script.on_event( + defines.events.on_runtime_mod_setting_changed, + (e: OnRuntimeModSettingChangedEvent) => { + print(`Settings changed ${e.setting_type}, ${e.player_index}, ${e.setting}, ${e.mod_name}`) + KafkatorioSettings.loadSettings() + } +) diff --git a/modules/events-mod/src/main/typescript/main/global-init.ts b/modules/events-mod/src/main/typescript/main/global-init.ts index 920549b..9670afb 100644 --- a/modules/events-mod/src/main/typescript/main/global-init.ts +++ b/modules/events-mod/src/main/typescript/main/global-init.ts @@ -1,5 +1,5 @@ import {Queue} from "./queue/queue"; -import {EventDataCache} from "./cache/EventDataCache"; +import EventUpdatesManager from "./cache/EventDataCache"; export function initGlobal(force: boolean = false) { @@ -9,7 +9,7 @@ export function initGlobal(force: boolean = false) { global.FACTORIO_VERSION = script.active_mods["base"] Queue.init(true) - EventDataCache.init(true) + EventUpdatesManager.init(true) log("Finished initialising Kafkatorio Global variables") } diff --git a/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts b/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts new file mode 100644 index 0000000..31aee02 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts @@ -0,0 +1,70 @@ +import {Data, DoubleSettingDefinition} from "typed-factorio/settings/types" + +export class KafkatorioSettingsConfig { + + + private static eventCacheExpirationDefaultSeconds: Record = { + "PLAYER": 0.25, + "MAP_CHUNK": 30, + "ENTITY": 5, + } + + + private eventCacheExpirationTicks: Record = { + "PLAYER": KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds["PLAYER"], + "MAP_CHUNK": KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds["MAP_CHUNK"], + "ENTITY": KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds["ENTITY"], + } + + + public getEventCacheExpirationTicks(type: FactorioEventUpdateType): uint { + return this.eventCacheExpirationTicks[type] + } + + + loadSettings(): void { + const types: FactorioEventUpdateType[] = ["PLAYER", "MAP_CHUNK", "ENTITY"] + for (const type of types) { + const seconds: double = settings.global[KafkatorioSettingsConfig.cacheDurationSettingName(type)].value as double + this.eventCacheExpirationTicks[type] = seconds * 60 // convert ticks to seconds + } + } + + + initialiseSettings(data: Data): void { + data.extend( + [ + this.createDefaultCacheDuration("PLAYER"), + this.createDefaultCacheDuration("MAP_CHUNK"), + this.createDefaultCacheDuration("ENTITY"), + ] + ) + } + + + private createDefaultCacheDuration( + type: FactorioEventUpdateType, + defaultExpirationSeconds: uint = KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[type], + ): DoubleSettingDefinition { + return { + type: "double-setting", + name: KafkatorioSettingsConfig.cacheDurationSettingName(type), + setting_type: "runtime-global", + default_value: defaultExpirationSeconds, + // min: 0.25 seconds, max: 2 minutes + minimum_value: 0.25, + maximum_value: 120, + } + } + + + private static cacheDurationSettingName(type: FactorioEventUpdateType): string { + return `kafkatorio_event-cache_default-expiration-duration-seconds_${type}` + } + + +} + + +const KafkatorioSettings = new KafkatorioSettingsConfig() +export default KafkatorioSettings diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index 12bc07a..cf4979b 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -80,9 +80,9 @@ "integrity": "sha512-/iLa916Cw33vC6wgmCb4cPLjmvUA2zVviTx/vy80iEvpOHjoNkuHkGSsmvss1aItwUKUlHaLi3k0fK5OPiw1iA==" }, "typescript": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", - "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==" + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", + "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==" }, "typescript-to-lua": { "version": "1.3.4", diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index c477325..f8f8ea1 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -15,7 +15,7 @@ "lua-types": "^2.11.0", "typescript-to-lua": "1.3.4", "typed-factorio": "0.19.1", - "typescript": "4.5.5" + "typescript": "4.6.2" }, "// @types/node": "^12.0.8", "license": "UNLICENSED", diff --git a/modules/events-mod/src/main/typescript/settings.ts b/modules/events-mod/src/main/typescript/settings.ts new file mode 100644 index 0000000..5a65e74 --- /dev/null +++ b/modules/events-mod/src/main/typescript/settings.ts @@ -0,0 +1,7 @@ +import {Data, Mods} from "typed-factorio/settings/types" +import KafkatorioSettings from "./main/settings/KafkatorioSettings"; + +declare const data: Data +declare const mods: Mods + +KafkatorioSettings.initialiseSettings(data) From e32e2a03114d2eca51ff08ddd18bece391ad73c7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 12 Mar 2022 01:36:00 +0100 Subject: [PATCH 241/629] try and fix 'no task named assemble' warning by adding base plugin (it didn't work...) --- .../kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts index b12d5ef..520fa83 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts @@ -3,6 +3,7 @@ package dev.adamko.kafkatorio.infra import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { + base id("dev.adamko.kafkatorio.infra.process-runner") } From e3954c184ae5c2740708bf4431f3645f59fb3a3d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 12 Mar 2022 01:37:35 +0100 Subject: [PATCH 242/629] code tidy up --- modules/events-server/build.gradle.kts | 9 ++++++++- .../adamko/kafkatorio/processor/topology/model.kt | 14 +++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 6972839..996c2ce 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -15,6 +15,7 @@ description = """ val projectId: String by project.extra +val kafkaStateDir = layout.projectDirectory.dir("kafka-state") dependencies { @@ -66,7 +67,7 @@ tasks.withType { val kafkaStateDirDelete by tasks.registering(Delete::class) { group = project.name mustRunAfter(kafkaConsumersDelete) - delete(layout.projectDirectory.dir("kafka-state")) + delete(kafkaStateDir) } val kafkaConsumersDelete by tasks.registering(KafkaConsumerGroupsTask.DeleteAll::class) { @@ -76,3 +77,9 @@ val kafkaConsumersDelete by tasks.registering(KafkaConsumerGroupsTask.DeleteAll: //tasks.run.configure { // dependsOn(kafkatorioEventsServerKafkaForceReset) //} + +idea { + module { + excludeDirs = excludeDirs + kafkaStateDir.asFile + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt index 93375ee..d32032f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt @@ -16,21 +16,21 @@ value class FactorioServerId(val id: String) { enum class ChunkSize( val zoomLevel: Int, ) : Comparable { - CHUNK_512(-1), // 512 - CHUNK_256(0), // 256 - CHUNK_128(1), // 128 - CHUNK_064(2), // 64 - CHUNK_032(3), // 32 + CHUNK_512(-1), + CHUNK_256(0), + CHUNK_128(1), + CHUNK_064(2), + CHUNK_032(3), ; val tilesPerChunk: Int = 2f.pow(8 - zoomLevel).roundToInt() init { - require(tilesPerChunk > 0) { "chunkSize must be positive" } + require(tilesPerChunk > 0) { "tilesPerChunk $tilesPerChunk must be positive" } // 1000 & 0111 = 0000 => pow^2 // 1001 & 1000 = 1000 => !pow^2 require(tilesPerChunk and (tilesPerChunk - 1) == 0) { - "tilesPerChunk must be a power-of-two number" + "tilesPerChunk $tilesPerChunk must be a power-of-two number" } } From b6f8d2e4227dd879a1e0e129969f155cf8f2d37d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 12 Mar 2022 01:38:00 +0100 Subject: [PATCH 243/629] KafkaAdmin - make all event-update topics --- .../kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt index a51916f..fb89dbc 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.processor.admin +import dev.adamko.kafkatorio.events.schema.FactorioEventUpdate import dev.adamko.kafkatorio.events.schema.FactorioObjectData import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.processor.KafkatorioTopology @@ -42,10 +43,14 @@ object KafkatorioKafkaAdmin { } KafkatorioPacket.PacketType.CONFIG -> add("$base.FactorioConfigurationUpdate") KafkatorioPacket.PacketType.PROTOTYPES -> add("$base.all") - KafkatorioPacket.PacketType.UPDATE -> add("$base.all") + KafkatorioPacket.PacketType.UPDATE -> { + add("$base.all") + FactorioEventUpdate.FactorioEventUpdateType.values.forEach { objectName -> + add("$base.${objectName.name}") + } + } } - } }.minus(currentTopics.toSet()) From 7a46ea7b75f4f79b03d7f278f019d815a5f8b7d5 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 12 Mar 2022 01:38:13 +0100 Subject: [PATCH 244/629] KxsBinaryTests --- .../processor/misc/KxsBinaryTests.kt | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt new file mode 100644 index 0000000..bd4489e --- /dev/null +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt @@ -0,0 +1,76 @@ +package dev.adamko.kafkatorio.processor.misc + +import dev.adamko.kafkatorio.events.schema.MapChunkPosition +import dev.adamko.kafkatorio.events.schema.SurfaceIndex +import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.processor.topology.ChunkSize +import dev.adamko.kafkatorio.processor.topology.FactorioServerId +import dev.adamko.kafkatorio.processor.topology.ServerMapChunkId +import io.kotest.assertions.withClue +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.equality.shouldBeEqualToComparingFields +import io.kotest.matchers.shouldBe +import kotlinx.serialization.decodeFromByteArray +import kotlinx.serialization.encodeToByteArray + + +class KxsBinaryTests : FunSpec({ + + test("byte array") { + val ba = byteArrayOf( + 0, 4, 116, 101, 115, 116, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 3 + ) + + val result = kxsBinary.decodeFromByteArray(ServerMapChunkId.serializer(), ba) + + withClue(ba.toString(Charsets.UTF_8)) { + + result shouldBeEqualToComparingFields ServerMapChunkId( + serverId = FactorioServerId("test"), + chunkPosition = MapChunkPosition(1, 2), + surfaceIndex = SurfaceIndex(1u), + chunkSize = ChunkSize.CHUNK_064, + ) + + } + } + + test("encoding") { + val ba = kxsBinary.encodeToByteArray( + ServerMapChunkId( + serverId = FactorioServerId("test"), + chunkPosition = MapChunkPosition(1, 2), + surfaceIndex = SurfaceIndex(1u), + chunkSize = ChunkSize.CHUNK_064, + ) + ) + + withClue(ba.toString(Charsets.UTF_8)) { + ba shouldBe byteArrayOf( + 0, 4, 116, 101, 115, 116, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 3 + ) + } + } + + context("inline value class") { + val uuid = "fa858d73-6205-44cf-aeeb-6bbf3148c4a7" + //@formatter:off + val expectedBytes = byteArrayOf(0, 36, 102, 97, 56, 53, 56, 100, 55, 51, 45, 54, 50, 48, 53, 45, 52, 52, 99, 102, 45, 97, 101, 101, 98, 45, 54, 98, 98, 102, 51, 49, 52, 56, 99, 52, 97, 55) + //@formatter:on + + test("encode") { + val ba = kxsBinary.encodeToByteArray(FactorioServerId(uuid)) + + withClue(ba.toString(Charsets.UTF_8)) { + ba shouldBe expectedBytes + } + } + test("decode") { + val ba = kxsBinary.encodeToByteArray(FactorioServerId(uuid)) + val id: FactorioServerId = kxsBinary.decodeFromByteArray(ba) + + id shouldBeEqualToComparingFields FactorioServerId(uuid) + } + } + +}) From 19bfe3a232aee89f74c89bf0b6b0bbb74843d22e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 12 Mar 2022 01:39:19 +0100 Subject: [PATCH 245/629] shutdown all KafkaStream apps if one crashes --- .../dev/adamko/kafkatorio/events/schema/factorioIds.kt | 2 +- .../dev/adamko/kafkatorio/processor/KafkatorioTopology.kt | 4 +++- .../adamko/kafkatorio/processor/StreamsExceptionHandler.kt | 5 ++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioIds.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioIds.kt index 4dcdb76..e8a9e90 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioIds.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioIds.kt @@ -31,7 +31,7 @@ value class PlayerIndex(private val id: UInt) { } -/** This is universally unique for every entity that has one, for the lifetime of a whole game. */ +/** > This is universally unique for every entity that has one, for the lifetime of a whole game. */ @Serializable @JvmInline value class UnitNumber(private val id: UInt) { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 1e8dd10..3d35424 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -156,7 +156,9 @@ internal class KafkatorioTopology( props.setProperty(StreamsConfig.APPLICATION_ID_CONFIG, appId) val streams = KafkaStreams(topology, props) - streams.setUncaughtExceptionHandler(StreamsExceptionHandler()) + streams.setUncaughtExceptionHandler(StreamsExceptionHandler { + coroutineContext.job.cancel(CancellationException(cause = it)) + }) val description: TopologyDescription = topology.describe() println( diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt index e188560..18ab16a 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt @@ -3,9 +3,12 @@ package dev.adamko.kafkatorio.processor import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler.StreamThreadExceptionResponse -class StreamsExceptionHandler : StreamsUncaughtExceptionHandler { +class StreamsExceptionHandler( + val shutdown: (e: Throwable) -> Unit, +) : StreamsUncaughtExceptionHandler { override fun handle(exception: Throwable): StreamThreadExceptionResponse { exception.printStackTrace() + shutdown(exception) return StreamThreadExceptionResponse.SHUTDOWN_APPLICATION } } From bfdee32d6127e3e757b29aeaa2cdcdd5c990669f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 12 Mar 2022 02:10:40 +0100 Subject: [PATCH 246/629] bump kotka-streams versions (fix deserialization bug, because of nullable val) --- modules/events-server/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 996c2ce..a5f5c14 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -40,7 +40,7 @@ dependencies { implementation("com.sksamuel.scrimage:scrimage-core:4.0.24") - val kotkaVersion = "v0.0.13" + val kotkaVersion = "v0.0.14" implementation("com.github.adamko-dev.kotka-streams:kotka-streams:$kotkaVersion") { isChanging = true } From b8ba8b7c9ed63c0d142c551e880029cb3d823216 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 12 Mar 2022 16:42:24 +0100 Subject: [PATCH 247/629] - tidy up groupMapChunks.kt - add ticks to all Kafkatorio Packets - add Kafka Streams test for groupMapChunks.kt --- gradle/libs.versions.toml | 5 +- .../kafkatorio-schema/config-update.d.ts | 1 + .../kafkatorio-schema/prototype.d.ts | 1 + .../generated/kafkatorio-schema/schema.d.ts | 1 + .../handleConfigurationUpdate.ts | 3 +- .../main/config-update/prototypes.ts | 3 +- .../main/typescript/main/events/emitEvent.ts | 2 +- .../events/schema/factorioCommonData.kt | 3 +- .../events/schema/factorioConfiguration.kt | 1 + .../events/schema/factorioEventUpdates.kt | 3 +- .../events/schema/factorioEvents.kt | 3 +- .../events/schema/factorioPrototypes.kt | 1 + .../events/schema/kafkatorioPacket.kt | 1 + .../events/schema/FactorioEventTest.kt | 2 + .../events/schema/PrototypesTest.kt | 2 + modules/events-server/build.gradle.kts | 3 +- .../processor/KafkatorioTopology.kt | 64 +-------- .../kafkatorio/processor/serdes/kxsBinary.kt | 8 +- .../processor/topology/flowMapTiles.kt | 3 +- .../processor/topology/groupMapChunks.kt | 119 +++++++++++++--- .../processor/topology/prototypes.kt | 10 +- .../processor/topology/GroupMapChunksTest.kt | 130 ++++++++++++++++++ 22 files changed, 271 insertions(+), 98 deletions(-) create mode 100644 modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1295f7c..0f0eae2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -90,9 +90,10 @@ gcp-speech = { group = "com.google.cloud", name = "google-cloud-speech" ## kafka ## -kafka-streams = { group = "org.apache.kafka", name = "kafka-streams", version.ref = "kafka" } +kafka-streams = { group = "org.apache.kafka", name = "kafka-streams", version.ref = "kafka" } +kafka-streamsTestUtils = { group = "org.apache.kafka", name = "kafka-streams-test-utils", version.ref = "kafka" } # kafka helpers -kotka = { group = "com.github.blueanvil", name = "kotka", version = "1.1.1" } +#kotka = { group = "com.github.blueanvil", name = "kotka", version = "1.1.1" } jsoup = { group = "org.jsoup", name = "jsoup", version = "1.14.3" } skrapeit = { group = "it.skrape", name = "skrapeit", version = "1.2.0" } diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts index 3145904..6fa06d0 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts @@ -16,4 +16,5 @@ interface FactorioConfigurationUpdate extends KafkatorioPacket { factorioData: FactorioGameDataUpdate; modVersion: string; packetType: PacketType; + tick: uint; } diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts index 01d4958..5dbd1c0 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts @@ -10,6 +10,7 @@ interface FactorioPrototypes extends KafkatorioPacket { modVersion: string; packetType: PacketType; prototypes: FactorioPrototype[]; + tick: uint; } interface MapTilePrototype extends FactorioPrototype { diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts index 7091073..3c42507 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts @@ -5,6 +5,7 @@ type PacketType = "EVENT" | "CONFIG" | "PROTOTYPES" | "UPDATE"; interface KafkatorioPacket { modVersion: string; packetType: PacketType; + tick: uint; } interface FactorioEvent extends KafkatorioPacket { diff --git a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts index dab8aef..783f611 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts @@ -6,7 +6,8 @@ export function emitConfigurationUpdate(changeData: ConfigurationChangedData) { modVersion: global.MOD_VERSION, packetType: "CONFIG", allMods: allMods(changeData), - factorioData: factorioData(changeData) + factorioData: factorioData(changeData), + tick: game.tick, }) } diff --git a/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts b/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts index d4d2bfe..bd96832 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts @@ -6,7 +6,8 @@ export function emitPrototypes() { emitPacket({ modVersion: global.MOD_VERSION, packetType: "PROTOTYPES", - prototypes: prototypes() + prototypes: prototypes(), + tick: game.tick, }) } diff --git a/modules/events-mod/src/main/typescript/main/events/emitEvent.ts b/modules/events-mod/src/main/typescript/main/events/emitEvent.ts index ab98b7f..d095fbc 100644 --- a/modules/events-mod/src/main/typescript/main/events/emitEvent.ts +++ b/modules/events-mod/src/main/typescript/main/events/emitEvent.ts @@ -7,6 +7,6 @@ export function emitEvent(eventData: T, tick: uint packetType: "EVENT", eventType: eventType, modVersion: global.MOD_VERSION, - tick: tick + tick: tick, }) } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index 16d4b55..65b7e36 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -112,8 +112,9 @@ interface EntityIdentifiers { data class MapTileDictionary( /** Map an X,Y coordinate a prototype name */ val tilesXY: Map>, - val protos: Map + val protos: Map, ) { + fun toMapTileList(): List = buildList { tilesXY.forEach { (xString, row) -> row.forEach { (yString, protoIndex) -> diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt index 900e28d..37aa57f 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt @@ -7,6 +7,7 @@ import kotlinx.serialization.Serializable @Serializable data class FactorioConfigurationUpdate( override val modVersion: String, + override val tick: Tick, val factorioData: FactorioGameDataUpdate, val allMods: List, ) : KafkatorioPacket() { diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt index e66f16f..e930361 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt @@ -15,8 +15,7 @@ import kotlinx.serialization.json.jsonPrimitive @Serializable data class FactorioEventUpdatePacket( override val modVersion: String, - /** game time */ - val tick: Tick, + override val tick: Tick, val update: FactorioEventUpdate, ) : KafkatorioPacket() { @EncodeDefault diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt index 0cb882e..177bf21 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt @@ -7,10 +7,9 @@ import kotlinx.serialization.Serializable @Serializable data class FactorioEvent( override val modVersion: String, + override val tick: Tick, /** the initial Factorio event (`defines.events`) trigger */ val eventType: String, - /** game time */ - val tick: Tick, val data: FactorioObjectData, ) : KafkatorioPacket() { @EncodeDefault diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt index 0fb80b2..c5c3f3e 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt @@ -15,6 +15,7 @@ import kotlinx.serialization.json.jsonPrimitive @Serializable data class FactorioPrototypes( override val modVersion: String, + override val tick: Tick, val prototypes: List, ) : KafkatorioPacket() { @EncodeDefault diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt index e5e947e..e562dfa 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt @@ -14,6 +14,7 @@ import kotlinx.serialization.json.jsonPrimitive sealed class KafkatorioPacket { /** Schema versioning */ abstract val modVersion: String + abstract val tick: Tick @EncodeDefault abstract val packetType: PacketType diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt index 248e22b..bd93da6 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt @@ -289,6 +289,7 @@ class FactorioEventTest : FunSpec({ { "modVersion": "0.2.8", "packetType": "CONFIG", + "tick": 534, "allMods": [ { "modName": "kafkatorio-events", @@ -310,6 +311,7 @@ class FactorioEventTest : FunSpec({ val expected = FactorioConfigurationUpdate( modVersion = "0.2.8", + tick = Tick(534u), factorioData = FactorioGameDataUpdate(null, null), allMods = listOf( FactorioModInfo( diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt index 5356ad2..974af26 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt @@ -12,6 +12,7 @@ class PrototypesTest : BehaviorSpec({ { "modVersion":"0.2.4", "packetType":"PROTOTYPES", + "tick": 534, "prototypes":[ { "prototypeObjectName":"LuaTilePrototype", @@ -46,6 +47,7 @@ class PrototypesTest : BehaviorSpec({ { "modVersion":"0.3.2", "packetType":"PROTOTYPES", + "tick": 534, "prototypes":[ { "prototypeObjectName":"LuaTilePrototype", diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index a5f5c14..e9c353c 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -20,6 +20,7 @@ val kafkaStateDir = layout.projectDirectory.dir("kafka-state") dependencies { implementation(libs.kafka.streams) + testImplementation(libs.kafka.streamsTestUtils) implementation(projects.modules.eventsSchema) @@ -40,7 +41,7 @@ dependencies { implementation("com.sksamuel.scrimage:scrimage-core:4.0.24") - val kotkaVersion = "v0.0.14" + val kotkaVersion = "v0.0.15" implementation("com.github.adamko-dev.kotka-streams:kotka-streams:$kotkaVersion") { isChanging = true } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 3d35424..076db30 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -1,30 +1,20 @@ package dev.adamko.kafkatorio.processor import dev.adamko.kafkatorio.events.schema.ColourHex -import dev.adamko.kafkatorio.events.schema.FactorioEvent -import dev.adamko.kafkatorio.events.schema.FactorioEventUpdate -import dev.adamko.kafkatorio.events.schema.FactorioEventUpdatePacket -import dev.adamko.kafkatorio.events.schema.FactorioObjectData -import dev.adamko.kafkatorio.events.schema.FactorioPrototypes -import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.processor.config.ApplicationProperties -import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kafkatorio.processor.topology.FactorioServerId import dev.adamko.kafkatorio.processor.topology.ServerMapChunkId import dev.adamko.kafkatorio.processor.topology.ServerMapChunkTiles import dev.adamko.kafkatorio.processor.topology.factorioServerPacketStream -import dev.adamko.kafkatorio.processor.topology.groupTilesIntoChunksWithColours +import dev.adamko.kafkatorio.processor.topology.groupMapChunks import dev.adamko.kafkatorio.processor.topology.playerUpdatesToWsServer import dev.adamko.kafkatorio.processor.topology.saveMapTiles import dev.adamko.kafkatorio.processor.topology.splitFactorioServerPacketStream -import dev.adamko.kafkatorio.processor.topology.tileProtoColourDictionary import dev.adamko.kotka.extensions.consumedAs -import dev.adamko.kotka.extensions.producedAs -import dev.adamko.kotka.extensions.tables.toStream import dev.adamko.kotka.kxs.serde import java.time.Duration import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.cancellation.CancellationException import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -36,7 +26,6 @@ import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.StreamsConfig import org.apache.kafka.streams.Topology import org.apache.kafka.streams.TopologyDescription -import org.apache.kafka.streams.kstream.KStream import org.apache.kafka.streams.kstream.KTable @@ -62,54 +51,7 @@ internal class KafkatorioTopology( private fun groupTilesMapChunks() { val builder = StreamsBuilder() - - - val protosStream: KStream = - builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", - consumedAs("consume.factorio-protos.all", jsonMapper.serde(), jsonMapper.serde()) - ) - val tileProtoColourDict = tileProtoColourDictionary(protosStream) - - -// val mapTilesStream: KStream = -// builder.stream( -// "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", -// consumedAs("consume.map-tiles", jsonMapper.serde(), jsonMapper.serde()) -// ) -// -// val mapChunksStream: KStream = -// builder.stream( -// "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", -// consumedAs("consume.map-chunks", jsonMapper.serde(), jsonMapper.serde()) -// ) - - val mapChunksUpdatesStream: KStream = - builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.UPDATE}.${FactorioEventUpdate.FactorioEventUpdateType.MAP_CHUNK}", - consumedAs("consume.map-chunk-updates", jsonMapper.serde(), jsonMapper.serde()) - ) - - val groupedMapChunkTiles: KTable> = - groupTilesIntoChunksWithColours( -// mapTilesStream, -// mapChunksStream, - mapChunksUpdatesStream, - tileProtoColourDict, - ) - - groupedMapChunkTiles - .toStream("stream-grouped-map-tiles") - .to( - TOPIC_GROUPED_MAP_CHUNKS, - producedAs( - "produce.grouped-map-chunks", - kxsBinary.serde(), - kxsBinary.serde?>() - ) - ) - - val topology = builder.build() + val topology = groupMapChunks(builder) launchTopology("groupTilesMapChunks", topology) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt index b1be03c..4e1a99c 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt @@ -60,12 +60,14 @@ class KxsDataOutputEncoder( override fun encodeLong(value: Long) = output.writeLong(value) override fun encodeShort(value: Short) = output.writeShort(value.toInt()) override fun encodeString(value: String) = output.writeUTF(value) +// override fun encodeString(value: String) = encodeByteArray(value.toByteArray(Charsets.UTF_8)) override fun beginCollection( descriptor: SerialDescriptor, collectionSize: Int ): CompositeEncoder { - encodeCompactSize(collectionSize) + encodeInt(collectionSize) +// encodeCompactSize(collectionSize) return this } @@ -113,6 +115,7 @@ class KxsDataInputDecoder( override fun decodeLong(): Long = input.readLong() override fun decodeShort(): Short = input.readShort() override fun decodeString(): String = input.readUTF() +// override fun decodeString(): String = decodeByteArray().toString(Charsets.UTF_8) override fun decodeElementIndex(descriptor: SerialDescriptor): Int { if (elementIndex == elementsCount) return CompositeDecoder.DECODE_DONE @@ -125,7 +128,8 @@ class KxsDataInputDecoder( override fun decodeSequentially(): Boolean = true override fun decodeCollectionSize(descriptor: SerialDescriptor): Int = - decodeCompactSize().also { elementsCount = it } + decodeInt().also { elementsCount = it } +// decodeCompactSize().also { elementsCount = it } override fun decodeNotNullMark(): Boolean = decodeBoolean() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt index f0b189e..69c5304 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt @@ -9,6 +9,7 @@ import dev.adamko.kafkatorio.events.schema.MapChunkPosition import dev.adamko.kafkatorio.events.schema.MapTilePosition import dev.adamko.kafkatorio.events.schema.SurfaceIndex import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition +import dev.adamko.kotka.extensions.streams.* import java.awt.image.BufferedImage import java.io.File import kotlin.coroutines.CoroutineContext @@ -52,7 +53,7 @@ fun saveMapTiles( serverMapTable .toStream() - .foreach { _, value -> + .forEach("save-chunked-tiles") { _, value -> if (value != null) { runBlocking(Dispatchers.Default) { println("emitting chunkedTiles ${value.chunkId} tiles: ${value.map.size}") diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt index 28eaab6..1858986 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt @@ -1,7 +1,10 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.events.schema.ColourHex +import dev.adamko.kafkatorio.events.schema.FactorioEventUpdate import dev.adamko.kafkatorio.events.schema.FactorioEventUpdatePacket +import dev.adamko.kafkatorio.events.schema.FactorioPrototypes +import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.events.schema.MapChunkPosition import dev.adamko.kafkatorio.events.schema.MapChunkUpdate import dev.adamko.kafkatorio.events.schema.MapTile @@ -10,16 +13,20 @@ import dev.adamko.kafkatorio.events.schema.MapTilePosition import dev.adamko.kafkatorio.events.schema.MapTiles import dev.adamko.kafkatorio.events.schema.SurfaceIndex import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition +import dev.adamko.kafkatorio.processor.KafkatorioTopology +import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.groupedAs -import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.materializedWith -import dev.adamko.kotka.extensions.streams.flatMap -import dev.adamko.kotka.extensions.streams.mapValues -import dev.adamko.kotka.extensions.streams.reduce +import dev.adamko.kotka.extensions.producedAs +import dev.adamko.kotka.extensions.streams.* import dev.adamko.kotka.extensions.tables.join +import dev.adamko.kotka.extensions.tables.toStream import dev.adamko.kotka.kxs.serde import kotlinx.serialization.Serializable +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.Topology import org.apache.kafka.streams.kstream.KStream import org.apache.kafka.streams.kstream.KTable @@ -42,7 +49,74 @@ data class ServerMapChunkTiles( } -fun groupTilesIntoChunksWithColours( +fun groupMapChunks( + builder: StreamsBuilder, + prototypesTopicName: String = "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", + mapChunkUpdatesTopicName: String = "kafkatorio.${KafkatorioPacket.PacketType.UPDATE}.${FactorioEventUpdate.FactorioEventUpdateType.MAP_CHUNK}", +): Topology { + + val protosStream: KStream = + builder.stream( + prototypesTopicName, + consumedAs("consume.factorio-protos.all", jsonMapper.serde(), jsonMapper.serde()) + ) + val tileProtoColourDict: KTable = + tileProtoColourDictionary(protosStream) + + +// val mapTilesStream: KStream = +// builder.stream( +// "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", +// consumedAs("consume.map-tiles", jsonMapper.serde(), jsonMapper.serde()) +// ) +// +// val mapChunksStream: KStream = +// builder.stream( +// "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", +// consumedAs("consume.map-chunks", jsonMapper.serde(), jsonMapper.serde()) +// ) + + val mapChunksUpdatesStream: KStream = + builder.stream( + mapChunkUpdatesTopicName, + consumedAs( + "consume.map-chunk-updates", + jsonMapper.serde(), + jsonMapper.serde(), + ) + ) +// .repartition( +// repartitionedAs( +// "map-chunk-updates.repartition.change-serde", +// kxsBinary.serde(), +// kxsBinary.serde(), +// numberOfPartitions = 3, +// ) +// ) + + val groupedMapChunkTiles: KTable> = + groupTilesIntoChunksWithColours( +// mapTilesStream, +// mapChunksStream, + mapChunksUpdatesStream, + tileProtoColourDict, + ) + + groupedMapChunkTiles + .toStream("stream-grouped-map-tiles") + .to( + KafkatorioTopology.TOPIC_GROUPED_MAP_CHUNKS, + producedAs( + "produce.grouped-map-chunks", + kxsBinary.serde(), + kxsBinary.serde?>() + ) + ) + + return builder.build() +} + +private fun groupTilesIntoChunksWithColours( // mapTilePacketsStream: KStream, // mapChunksPacketsStream: KStream, mapChunkUpdatePacketsStream: KStream, @@ -107,7 +181,7 @@ fun groupTilesIntoChunksWithColours( // .merge("merge-mapTilesStream-with-mapChunkTilesStream", mapChunkTilesStream) // .merge("merge-mapTilesStream-with-mapChunkUpdatesStream", mapChunkUpdatesStream) // .filter { _, value -> !value?.tiles.isNullOrEmpty() } - .flatMap("server-map-data.tiles.flatMapByChunk") { key: FactorioServerId, mapTiles: MapTiles -> + .flatMap("server-map-data.tiles.flatMapByChunk") { serverId: FactorioServerId, mapTiles: MapTiles -> val standardChunkSize = ChunkSize.MAX @@ -119,10 +193,10 @@ fun groupTilesIntoChunksWithColours( .map { (chunkPos, tiles) -> val chunkId = ServerMapChunkId( - key, - chunkPos, - mapTiles.surfaceIndex, - standardChunkSize, + serverId = serverId, + chunkPosition = chunkPos, + surfaceIndex = mapTiles.surfaceIndex, + chunkSize = standardChunkSize, ) val tilesMap = tiles.associate { it.position to TileProtoHashCode(it) } @@ -132,20 +206,24 @@ fun groupTilesIntoChunksWithColours( chunkId to chunkTiles } } -// .filter("server-map-data.tiles.filter-not-empty") { _, value -> -// value.map.isNotEmpty() -// } + .filter("server-map-data.tiles.filter-not-empty") { _, value -> + value.map.isNotEmpty() + } .groupByKey( groupedAs( "server-map-data.tiles.group", - kxsBinary.serde(), - kxsBinary.serde>() + kxsBinary.serde(), + kxsBinary.serde?>(), ) ) .reduce( - "server-map-data.tiles.reduce", - materializedAs("server-map-data.tiles.store", kxsBinary.serde(), kxsBinary.serde()), - ) { a, b -> a + b } + "server-map-data.tiles.reduce", materializedWith( + // "server-map-data.tiles.store", + kxsBinary.serde(), + kxsBinary.serde>(), + ), + ServerMapChunkTiles::plus + ) val colourisedChunkTable: KTable> = @@ -153,7 +231,10 @@ fun groupTilesIntoChunksWithColours( .join( other = tileProtoColourDict, name = "server-map-data.join-tiles-with-prototypes", - materialized = materializedWith(kxsBinary.serde(), kxsBinary.serde()), + materialized = materializedWith( + kxsBinary.serde(), + kxsBinary.serde>(), + ), foreignKeyExtractor = { chunkTiles: ServerMapChunkTiles -> chunkTiles.chunkId.serverId } ) { tiles: ServerMapChunkTiles, colourDict: TileColourDict -> diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index b63d67e..ad25cfb 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -7,7 +7,9 @@ import dev.adamko.kafkatorio.events.schema.MapTile import dev.adamko.kafkatorio.events.schema.MapTilePrototype import dev.adamko.kafkatorio.events.schema.converters.toHex import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kotka.extensions.materializedAs +import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.mapValues import dev.adamko.kotka.extensions.streams.toTable @@ -54,10 +56,10 @@ fun tileProtoColourDictionary( } .toTable( "server-map-data.tile-prototypes", - materializedAs( - "server-map-data.tile-prototypes.store", - jsonMapper.serde(), - jsonMapper.serde(), + materializedWith( +// "server-map-data.tile-prototypes.store", + kxsBinary.serde(), + kxsBinary.serde(), ) ) diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt new file mode 100644 index 0000000..bed9571 --- /dev/null +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt @@ -0,0 +1,130 @@ +package dev.adamko.kafkatorio.processor.topology + +import dev.adamko.kafkatorio.events.schema.Colour +import dev.adamko.kafkatorio.events.schema.ColourHex +import dev.adamko.kafkatorio.events.schema.FactorioEventUpdatePacket +import dev.adamko.kafkatorio.events.schema.FactorioPrototypes +import dev.adamko.kafkatorio.events.schema.MapChunkPosition +import dev.adamko.kafkatorio.events.schema.MapChunkUpdate +import dev.adamko.kafkatorio.events.schema.MapTileDictionary +import dev.adamko.kafkatorio.events.schema.MapTilePosition +import dev.adamko.kafkatorio.events.schema.MapTilePrototype +import dev.adamko.kafkatorio.events.schema.PrototypeKey +import dev.adamko.kafkatorio.events.schema.PrototypeName +import dev.adamko.kafkatorio.events.schema.SurfaceIndex +import dev.adamko.kafkatorio.events.schema.Tick +import dev.adamko.kafkatorio.processor.KafkatorioTopology +import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kotka.kxs.serde +import io.kotest.assertions.withClue +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.collections.shouldHaveSize +import io.kotest.matchers.equality.shouldBeEqualToComparingFields +import io.kotest.matchers.nulls.shouldNotBeNull +import io.kotest.matchers.should +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.TestInputTopic +import org.apache.kafka.streams.TestOutputTopic +import org.apache.kafka.streams.TopologyTestDriver + + +class GroupMapChunksTest : FunSpec({ + + test("basic test") { + + val prototypesTopicName = "prototypes-topic" + val mapChunkUpdatesTopicName = "map-chunk-updates-topic" + + val topology = groupMapChunks( + StreamsBuilder(), + prototypesTopicName, + mapChunkUpdatesTopicName, + ) + + val testDriver = TopologyTestDriver(topology) + + val prototypesTestInputTopic: TestInputTopic = + testDriver.createInputTopic( + prototypesTopicName, + jsonMapper.serde().serializer(), + jsonMapper.serde().serializer(), + ) + + val serverId = FactorioServerId("test-server-id") + + prototypesTestInputTopic.pipeInput( + serverId, + FactorioPrototypes( + modVersion = "1.2.3", + tick = Tick(456u), + listOf( + MapTilePrototype( + PrototypeName("fake-proto"), + layer = 1u, + mapColour = Colour(0.3f, 0.2f, 0.1f, 1.0f), + collisionMasks = listOf("fake-mask"), + order = "fake-order", + canBeMined = false, + ) + ) + ) + ) + + val mapChunkUpdatesInputTopic: TestInputTopic = + testDriver.createInputTopic( + mapChunkUpdatesTopicName, + jsonMapper.serde().serializer(), + jsonMapper.serde().serializer(), + ) + mapChunkUpdatesInputTopic.pipeInput( + serverId, + FactorioEventUpdatePacket( + modVersion = "1.2.3", + tick = Tick(854u), + update = MapChunkUpdate( + MapChunkPosition(11, 22), + SurfaceIndex(1u), + tileDictionary = MapTileDictionary( + tilesXY = mapOf( + "1" to mapOf("2" to PrototypeKey("33")) + ), + protos = mapOf(PrototypeKey("33") to PrototypeName("fake-proto")) + ) + ) + ) + ) + + val outputTopic: TestOutputTopic?> = + testDriver + .createOutputTopic( + KafkatorioTopology.TOPIC_GROUPED_MAP_CHUNKS, + kxsBinary.serde().deserializer(), + kxsBinary.serde?>().deserializer(), + ) + + val records = outputTopic.readRecordsToList() + + withClue(records) { + records shouldHaveSize 1 + + records.map { it.key to it.value }.first() should { (key, value) -> + key.shouldNotBeNull() + key shouldBeEqualToComparingFields ServerMapChunkId( + serverId = serverId, + chunkPosition = MapChunkPosition(0, 0), + surfaceIndex = SurfaceIndex(1u), + chunkSize = ChunkSize.CHUNK_512, + ) + value.shouldNotBeNull() + value shouldBeEqualToComparingFields ServerMapChunkTiles( + chunkId = key, + map = mapOf( + MapTilePosition(1, 2) to ColourHex(76u, 51u, 25u, 255u) + ) + ) + } + } + } + +}) From 3a10485ed43d6278d5249340fdd38fda650bf7e4 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 12 Mar 2022 22:00:58 +0100 Subject: [PATCH 248/629] bump some versions, pin some npm dependencies to satisfy GitHub depend-a-bot, remove protobuf (unused) --- buildSrc/build.gradle.kts | 4 +- gradle/kotlin-js-store/yarn.lock | 254 ++++++++++-------- gradle/libs.versions.toml | 34 +-- modules/events-server/build.gradle.kts | 7 +- .../kafkatorio/processor/serdes/protobuf.kt | 6 - modules/web-map/build.gradle.kts | 6 + 6 files changed, 172 insertions(+), 139 deletions(-) delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/protobuf.kt diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index c2216ac..6f37f3b 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -11,14 +11,14 @@ plugins { object Versions { const val jvmTarget = "11" const val kotlinTarget = "1.6" -// const val kotlin = "1.6.20-M1" + const val kotlin = "1.6.10" const val gradleNodePlugin = "3.2.1" const val gradleDockerComposePlugin = "0.15.1" const val kotlinXSerialization = "1.3.2" - const val kvision = "5.8.1" + const val kvision = "5.8.2" const val semver = "1.1.2" const val http4k = "4.19.1.0" diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index e85a1c8..c064a0d 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -118,10 +118,10 @@ resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== -"@types/eslint-scope@^3.7.0": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.2.tgz#11e96a868c67acf65bf6f11d10bb89ea71d5e473" - integrity sha512-TzgYCWoPiTeRg6RQYgtuW7iODtVoKu3RVL72k3WohqhjfaOLK5Mg2T4Tg1o2bSfu0vPkoI48wdQFv5b/Xe04wQ== +"@types/eslint-scope@^3.7.3": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224" + integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g== dependencies: "@types/eslint" "*" "@types/estree" "*" @@ -134,11 +134,16 @@ "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*", "@types/estree@^0.0.50": +"@types/estree@*": version "0.0.50" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== +"@types/estree@^0.0.51": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": version "4.17.28" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8" @@ -148,7 +153,7 @@ "@types/qs" "*" "@types/range-parser" "*" -"@types/express@*": +"@types/express@*", "@types/express@^4.17.13": version "4.17.13" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== @@ -380,22 +385,22 @@ "@webassemblyjs/ast" "1.11.1" "@xtuc/long" "4.2.2" -"@webpack-cli/configtest@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.0.tgz#8342bef0badfb7dfd3b576f2574ab80c725be043" - integrity sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg== +"@webpack-cli/configtest@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.1.tgz#9f53b1b7946a6efc2a749095a4f450e2932e8356" + integrity sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg== -"@webpack-cli/info@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.0.tgz#b9179c3227ab09cbbb149aa733475fcf99430223" - integrity sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw== +"@webpack-cli/info@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.1.tgz#2360ea1710cbbb97ff156a3f0f24556e0fc1ebea" + integrity sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA== dependencies: envinfo "^7.7.3" -"@webpack-cli/serve@^1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.0.tgz#2c275aa05c895eccebbfc34cfb223c6e8bd591a2" - integrity sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA== +"@webpack-cli/serve@^1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.1.tgz#0de2875ac31b46b6c5bb1ae0a7d7f0ba5678dffe" + integrity sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw== "@xtuc/ieee754@^1.2.0": version "1.2.0" @@ -700,7 +705,7 @@ chart.js@^3.7.0: resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.7.0.tgz#7a19c93035341df801d613993c2170a1fcf1d882" integrity sha512-31gVuqqKp3lDIFmzpKIrBeum4OpZsQjSIAqlOpgjosHDJZlULtvwLEZKtEhIAZc7JMPaHlYMys40Qy9Mf+1AAg== -chokidar@3.5.2, chokidar@^3.5.1, chokidar@^3.5.2: +chokidar@3.5.2, chokidar@^3.5.1: version "3.5.2" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== @@ -715,7 +720,7 @@ chokidar@3.5.2, chokidar@^3.5.1, chokidar@^3.5.2: optionalDependencies: fsevents "~2.3.2" -chokidar@3.5.3: +chokidar@3.5.3, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -896,18 +901,18 @@ cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -css-loader@^6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.5.1.tgz#0c43d4fbe0d97f699c91e9818cb585759091d1b1" - integrity sha512-gEy2w9AnJNnD9Kuo4XAP9VflW/ujKoS9c/syO+uWMlm5igc7LysKzPXaDoR2vroROkSwsTS2tGr1yGGEbZOYZQ== +css-loader@^6.6.0: + version "6.7.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.1.tgz#e98106f154f6e1baf3fc3bc455cb9981c1d5fd2e" + integrity sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw== dependencies: icss-utils "^5.1.0" - postcss "^8.2.15" + postcss "^8.4.7" postcss-modules-extract-imports "^3.0.0" postcss-modules-local-by-default "^4.0.0" postcss-modules-scope "^3.0.0" postcss-modules-values "^4.0.0" - postcss-value-parser "^4.1.0" + postcss-value-parser "^4.2.0" semver "^7.3.5" css-selector-parser@^1.3: @@ -925,15 +930,10 @@ custom-event@~1.0.0: resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= -date-format@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/date-format/-/date-format-2.1.0.tgz#31d5b5ea211cf5fd764cd38baf9d033df7e125cf" - integrity sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA== - -date-format@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/date-format/-/date-format-3.0.0.tgz#eb8780365c7d2b1511078fb491e6479780f3ad95" - integrity sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w== +date-format@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.4.tgz#b58036e29e74121fca3e1b3e0dc4a62c65faa233" + integrity sha512-/jyf4rhB17ge328HJuJjAcmRtCsGd+NDeAtahRBTaK6vSPR6MO5HlrAit3Nn7dVjaa6sowW0WXt8yQtLyZQFRg== debug@2.6.9: version "2.6.9" @@ -949,7 +949,7 @@ debug@4.3.2: dependencies: ms "2.1.2" -debug@4.3.3, debug@^4.1.0, debug@^4.1.1, debug@~4.3.1, debug@~4.3.2: +debug@4.3.3, debug@^4.1.0, debug@^4.3.3, debug@~4.3.1, debug@~4.3.2: version "4.3.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== @@ -1371,16 +1371,21 @@ flat@^5.0.2: resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== -flatted@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== +flatted@^3.2.5: + version "3.2.5" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" + integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== follow-redirects@^1.0.0: version "1.14.6" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.6.tgz#8cfb281bbc035b3c067d6cd975b0f6ade6e855cd" integrity sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A== +follow-redirects@^1.14.8: + version "1.14.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" + integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== + format-util@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" @@ -1396,7 +1401,16 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= -fs-extra@^8.0.1, fs-extra@^8.1.0: +fs-extra@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.1.tgz#27de43b4320e833f6867cc044bfce29fdf0ef3b8" + integrity sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-extra@^8.0.1: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== @@ -1935,6 +1949,15 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + karma-chrome-launcher@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz#805a586799a4d05f4e54f72a204979f3f3066738" @@ -1965,10 +1988,10 @@ karma-webpack@5.0.0: minimatch "^3.0.4" webpack-merge "^4.1.5" -karma@6.3.12: - version "6.3.12" - resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.12.tgz#fe6347f027385fc16da1a9bb87d766e2d25981c6" - integrity sha512-qwIG+oB2YmHx4hjvYSRMNzL3YWAJ9baHaLAxiP7biFNkfpwYTUTtPck0joFpucalNLzMr+7z/FX1uY/kl8DV9A== +karma@6.3.16: + version "6.3.16" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.16.tgz#76d1a705fd1cf864ee5ed85270b572641e0958ef" + integrity sha512-nEU50jLvDe5yvXqkEJRf8IuvddUkOY2x5Xc4WXHz6dxINgGDrgD2uqQWeVrJs4hbfNaotn+HQ1LZJ4yOXrL7xQ== dependencies: body-parser "^1.19.0" braces "^3.0.2" @@ -1982,9 +2005,10 @@ karma@6.3.12: http-proxy "^1.18.1" isbinaryfile "^4.0.8" lodash "^4.17.21" - log4js "^6.3.0" + log4js "^6.4.1" mime "^2.5.2" minimatch "^3.0.4" + mkdirp "^0.5.5" qjobs "^1.2.0" range-parser "^1.2.1" rimraf "^3.0.2" @@ -2041,16 +2065,16 @@ log-symbols@4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -log4js@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.3.0.tgz#10dfafbb434351a3e30277a00b9879446f715bcb" - integrity sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw== +log4js@^6.4.0, log4js@^6.4.1: + version "6.4.2" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.4.2.tgz#45ec783835acc525b397f52cf086e26994fe3b70" + integrity sha512-k80cggS2sZQLBwllpT1p06GtfvzMmSdUCkW96f0Hj83rKGJDAu2vZjt9B9ag2vx8Zz1IXzxoLgqvRJCdMKybGg== dependencies: - date-format "^3.0.0" - debug "^4.1.1" - flatted "^2.0.1" - rfdc "^1.1.4" - streamroller "^2.2.4" + date-format "^4.0.4" + debug "^4.3.3" + flatted "^3.2.5" + rfdc "^1.3.0" + streamroller "^3.0.4" lru-cache@^6.0.0: version "6.0.0" @@ -2180,10 +2204,10 @@ mocha@9.1.2: yargs-parser "20.2.4" yargs-unparser "2.0.0" -mocha@9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.0.tgz#2bfba73d46e392901f877ab9a47b7c9c5d0275cc" - integrity sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q== +mocha@9.2.1: + version "9.2.1" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.1.tgz#a1abb675aa9a8490798503af57e8782a78f1338e" + integrity sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ== dependencies: "@ungap/promise-all-settled" "1.1.2" ansi-colors "4.1.1" @@ -2248,10 +2272,10 @@ nanoid@3.2.0: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== -nanoid@^3.1.30: - version "3.1.30" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362" - integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ== +nanoid@^3.1.31, nanoid@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" + integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== negotiator@0.6.2: version "0.6.2" @@ -2498,19 +2522,19 @@ postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: cssesc "^3.0.0" util-deprecate "^1.0.2" -postcss-value-parser@^4.1.0: +postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8.2.15: - version "8.4.5" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95" - integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg== +postcss@^8.4.7: + version "8.4.8" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.8.tgz#dad963a76e82c081a0657d3a2f3602ce10c2e032" + integrity sha512-2tXEqGxrjvAO6U+CJzDL2Fk2kPHTv1jQsYkSoMeOis2SsYaXRO2COxTdQp99cYvif9JTXaAk9lYGc3VhJt7JPQ== dependencies: - nanoid "^3.1.30" + nanoid "^3.3.1" picocolors "^1.0.0" - source-map-js "^1.0.1" + source-map-js "^1.0.2" process-nextick-args@~2.0.0: version "2.0.1" @@ -2673,7 +2697,7 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rfdc@^1.1.4: +rfdc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== @@ -2878,10 +2902,10 @@ source-map-js@^0.6.2: resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== -source-map-js@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf" - integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA== +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== source-map-loader@3.0.0: version "3.0.0" @@ -2951,14 +2975,14 @@ split.js@^1.6.5: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -streamroller@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-2.2.4.tgz#c198ced42db94086a6193608187ce80a5f2b0e53" - integrity sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ== +streamroller@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.0.4.tgz#27ad87339d829483f89c5f33fd60ea6731e4183c" + integrity sha512-GI9NzeD+D88UFuIlJkKNDH/IsuR+qIN7Qh8EsmhoRZr9bQoehTraRgwtLUkZbpcAw+hLPfHOypmppz8YyGK68w== dependencies: - date-format "^2.1.0" - debug "^4.1.1" - fs-extra "^8.1.0" + date-format "^4.0.4" + debug "^4.3.3" + fs-extra "^10.0.1" string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" @@ -3115,6 +3139,11 @@ universalify@^0.1.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -3172,15 +3201,15 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" -webpack-cli@4.9.1: - version "4.9.1" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3" - integrity sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ== +webpack-cli@4.9.2: + version "4.9.2" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.2.tgz#77c1adaea020c3f9e2db8aad8ea78d235c83659d" + integrity sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ== dependencies: "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.1.0" - "@webpack-cli/info" "^1.4.0" - "@webpack-cli/serve" "^1.6.0" + "@webpack-cli/configtest" "^1.1.1" + "@webpack-cli/info" "^1.4.1" + "@webpack-cli/serve" "^1.6.1" colorette "^2.0.14" commander "^7.0.0" execa "^5.0.0" @@ -3190,7 +3219,7 @@ webpack-cli@4.9.1: rechoir "^0.7.0" webpack-merge "^5.7.3" -webpack-dev-middleware@^5.3.0: +webpack-dev-middleware@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz#aa079a8dedd7e58bfeab358a9af7dab304cee57f" integrity sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg== @@ -3201,19 +3230,20 @@ webpack-dev-middleware@^5.3.0: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@4.7.3: - version "4.7.3" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.7.3.tgz#4e995b141ff51fa499906eebc7906f6925d0beaa" - integrity sha512-mlxq2AsIw2ag016nixkzUkdyOE8ST2GTy34uKSABp1c4nhjZvH90D5ZRR+UOLSsG4Z3TFahAi72a3ymRtfRm+Q== +webpack-dev-server@4.7.4: + version "4.7.4" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.7.4.tgz#d0ef7da78224578384e795ac228d8efb63d5f945" + integrity sha512-nfdsb02Zi2qzkNmgtZjkrMOcXnYZ6FLKcQwpxT7MvmHKc+oTtDsBju8j+NMyAygZ9GW1jMEUpy3itHtqgEhe1A== dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" "@types/serve-index" "^1.9.1" "@types/sockjs" "^0.3.33" "@types/ws" "^8.2.2" ansi-html-community "^0.0.8" bonjour "^3.5.0" - chokidar "^3.5.2" + chokidar "^3.5.3" colorette "^2.0.10" compression "^1.7.4" connect-history-api-fallback "^1.6.0" @@ -3233,8 +3263,8 @@ webpack-dev-server@4.7.3: sockjs "^0.3.21" spdy "^4.0.2" strip-ansi "^7.0.0" - webpack-dev-middleware "^5.3.0" - ws "^8.1.0" + webpack-dev-middleware "^5.3.1" + ws "^8.4.2" webpack-merge@^4.1.5: version "4.2.2" @@ -3251,18 +3281,18 @@ webpack-merge@^5.7.3: clone-deep "^4.0.1" wildcard "^2.0.0" -webpack-sources@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.2.tgz#d88e3741833efec57c4c789b6010db9977545260" - integrity sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw== +webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@5.66.0: - version "5.66.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.66.0.tgz#789bf36287f407fc92b3e2d6f978ddff1bfc2dbb" - integrity sha512-NJNtGT7IKpGzdW7Iwpn/09OXz9inIkeIQ/ibY6B+MdV1x6+uReqz/5z1L89ezWnpPDWpXF0TY5PCYKQdWVn8Vg== +webpack@5.69.1: + version "5.69.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.69.1.tgz#8cfd92c192c6a52c99ab00529b5a0d33aa848dc5" + integrity sha512-+VyvOSJXZMT2V5vLzOnDuMz5GxEqLk7hKWQ56YxPW/PQRUuKimPqmEIJOx8jHYeyo65pKbapbW464mvsKbaj4A== dependencies: - "@types/eslint-scope" "^3.7.0" - "@types/estree" "^0.0.50" + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^0.0.51" "@webassemblyjs/ast" "1.11.1" "@webassemblyjs/wasm-edit" "1.11.1" "@webassemblyjs/wasm-parser" "1.11.1" @@ -3284,7 +3314,7 @@ webpack@5.66.0: tapable "^2.1.1" terser-webpack-plugin "^5.1.3" watchpack "^2.3.1" - webpack-sources "^3.2.2" + webpack-sources "^3.2.3" websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" @@ -3343,10 +3373,10 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@^8.1.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.4.0.tgz#f05e982a0a88c604080e8581576e2a063802bed6" - integrity sha512-IHVsKe2pjajSUIl4KYMQOdlyliovpEPquKkqbwswulszzI7r0SfQrxnXdWAEqOlDCLrVSJzo+O1hAwdog2sKSQ== +ws@^8.4.2: + version "8.5.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" + integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== ws@~8.2.3: version "8.2.3" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0f0eae2..aeafacf 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,6 @@ ## compilation ## jvm = "11" -#kotlin = "1.6.20-M1" kotlin = "1.6.10" ## libs ## @@ -14,10 +13,10 @@ camel-kafkaConnectors = "0.11.0" http4k = "4.19.1.0" kafka = "3.1.0" kotlinx-serialization = "1.3.2" -kvision = "5.8.1" -log4j2 = "2.14.1" -qosLogback = "1.2.5" -slf4j = "1.7.30" +kvision = "5.8.2" +log4j2 = "2.17.2" +qosLogback = "1.2.11" +slf4j = "1.7.36" ## test ## junit = "5.8.2" @@ -35,7 +34,7 @@ kotlinJvm = { id = "org.jetbrains.kotlin.jvm", vers kotlinJs = { id = "org.jetbrains.kotlin.js", version.ref = "kotlin" } kotlinSerialization = { id = "org.jetbrains.kotlin.kotlin-serialization", version.ref = "kotlin" } -loggingCapabilities = { id = "dev.jacomet.logging-capabilities", version = "0.9.0" } +loggingCapabilities = { id = "dev.jacomet.logging-capabilities", version = "0.10.0" } shadowJar = { id = "com.github.jengelman.gradle.plugins.shadow", version = "6.1.0" } dependencyCheck = { id = "com.github.ben-manes.versions", version = "0.39.0" } @@ -47,10 +46,12 @@ dependencyCheck = { id = "com.github.ben-manes.versions", vers ## kotlin ## kotlin-bom = { group = "org.jetbrains.kotlin", name = "kotlin-bom", version.ref = "kotlin" } -kotlinx-serialization-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-bom", version.ref = "kotlinx-serialization" } -kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core" } -kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json" } -kotlinx-serialization-yaml = { group = "com.charleskorn.kaml", name = "kaml", version = "0.37.0" } +kotlinx-serialization-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-bom", version.ref = "kotlinx-serialization" } +kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core" } +kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json" } +kotlinx-serialization-protobuf = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-protobuf" } + +kotlinx-serialization-yaml = { group = "com.charleskorn.kaml", name = "kaml", version = "0.37.0" } kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.6.0" } @@ -78,15 +79,15 @@ http4k-graphql = { group = "org.http4k", name = "http4k-graphql" ## logging ## slf4j-api = { group = "org.slf4j", name = "slf4j-api", version.ref = "slf4j" } -kotlin-logging = { group = "io.github.microutils", name = "kotlin-logging-jvm", version = "2.0.11" } +kotlin-logging = { group = "io.github.microutils", name = "kotlin-logging-jvm", version = "2.1.21" } logback-core = { group = "ch.qos.logback", name = "logback-core", version.ref = "qosLogback" } logback-classic = { group = "ch.qos.logback", name = "logback-classic", version.ref = "qosLogback" } logback-encoder = { group = "net.logstash.logback", name = "logstash-logback-encoder", version = "6.6" } ## gcp ## -gcp-bom = { group = "com.google.cloud", name = "libraries-bom", version = "23.1.0" } -gcp-pubsub = { group = "com.google.cloud", name = "google-cloud-pubsub" } -gcp-speech = { group = "com.google.cloud", name = "google-cloud-speech" } +#gcp-bom = { group = "com.google.cloud", name = "libraries-bom", version = "23.1.0" } +#gcp-pubsub = { group = "com.google.cloud", name = "google-cloud-pubsub" } +#gcp-speech = { group = "com.google.cloud", name = "google-cloud-speech" } ## kafka ## @@ -95,15 +96,18 @@ kafka-streamsTestUtils = { group = "org.apache.kafka", name = "kafka-streams-tes # kafka helpers #kotka = { group = "com.github.blueanvil", name = "kotka", version = "1.1.1" } +kafka-kotkaStreams = { group = "com.github.adamko-dev.kotka-streams", name = "kotka-streams", version = "0.0.15" } + jsoup = { group = "org.jsoup", name = "jsoup", version = "1.14.3" } skrapeit = { group = "it.skrape", name = "skrapeit", version = "1.2.0" } +scrimage-core = { group = "com.sksamuel.scrimage", name = "scrimage-core", version = "4.0.31" } ############# ### test ### ############# -mockk = { group = "io.mockk", name = "mockk", version = "1.12.2" } +mockk = { group = "io.mockk", name = "mockk", version = "1.12.3" } ## junit ## junit-bom = { group = "org.junit", name = "junit-bom", version.ref = "junit" } diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index e9c353c..b035f7c 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -29,7 +29,7 @@ dependencies { implementation(platform(libs.kotlinx.serialization.bom)) implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.json) - implementation("org.jetbrains.kotlinx:kotlinx-serialization-protobuf") +// implementation("org.jetbrains.kotlinx:kotlinx-serialization-protobuf") implementation(libs.kotlinx.coroutines) @@ -39,10 +39,9 @@ dependencies { implementation(libs.bundles.logging) - implementation("com.sksamuel.scrimage:scrimage-core:4.0.24") + implementation(libs.scrimage.core) - val kotkaVersion = "v0.0.15" - implementation("com.github.adamko-dev.kotka-streams:kotka-streams:$kotkaVersion") { + implementation(libs.kafka.kotkaStreams) { isChanging = true } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/protobuf.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/protobuf.kt deleted file mode 100644 index 8491485..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/protobuf.kt +++ /dev/null @@ -1,6 +0,0 @@ -package dev.adamko.kafkatorio.processor.serdes - -import kotlinx.serialization.protobuf.ProtoBuf - - -val protoMapper: ProtoBuf = ProtoBuf { } diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index eeebeb0..47d1227 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -65,6 +65,10 @@ kotlin { kvision("kvision-state-flow") implementation(libs.kotlinx.coroutines) + + implementation(npm("follow-redirects", "^1.14.8")) + implementation(npm("log4js", "^6.4.0")) + implementation(npm("nanoid", "^3.1.31")) } val webDir = file("src/main/web") @@ -76,6 +80,8 @@ kotlin { implementation(kotlin("test-js")) kvision("kvision-testutils") + + implementation(npm("karma", "^6.3.16")) } } } From 70349d86a708c33a81873035a357e13c4146df12 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 13 Mar 2022 11:03:47 +0100 Subject: [PATCH 249/629] emit prototypes on_init (they don't seem to always emit, otherwise?) --- modules/events-mod/src/main/typescript/control.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index 18e9161..37ae877 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -23,4 +23,5 @@ script.on_init(() => { // runs only once (when the mod is first added to the save) initGlobal(true) KafkatorioSettings.loadSettings() + emitPrototypes() }) From 3ebc8997d297a49b1c4ca34429a6af8e7fd88cf0 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 13 Mar 2022 11:04:09 +0100 Subject: [PATCH 250/629] code tidy --- modules/events-mod/build.gradle.kts | 3 +-- .../dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 3fb9ec1..660658c 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -24,8 +24,7 @@ val distributionZipName: String by extra("${modName}_${project.version}.zip") // version of Factorio that the mod is compatible with (must only be "major.minor" - patch causes error) val modFactorioCompatibility: String by extra( libs.versions.factorio - .map { SemVer.parse(it) } - .map { it.run { "$major.$minor" } } + .map { SemVer.parse(it).run { "$major.$minor" } } .get() ) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt index c5c3f3e..16593ca 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt @@ -68,7 +68,6 @@ data class MapTilePrototype( val name: PrototypeName, val layer: UInt, val mapColour: Colour, -// @Serializable(with = FactorioJsonListSerializer::class) @Contextual val collisionMasks: List, val order: String, From 8bb73b8291285ab7bbf942522c27159500e49a94 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 13 Mar 2022 11:06:30 +0100 Subject: [PATCH 251/629] remove commented out code, try using materializedAs to fix KTable-KTable join not working, make 'saveMapTiles' more encapsulated --- .../processor/KafkatorioTopology.kt | 18 +-- .../processor/topology/flowMapTiles.kt | 24 +++- .../processor/topology/groupMapChunks.kt | 116 ++++++++---------- .../processor/topology/prototypes.kt | 4 +- .../processor/topology/GroupMapChunksTest.kt | 6 +- 5 files changed, 78 insertions(+), 90 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 076db30..1b22f49 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -1,17 +1,11 @@ package dev.adamko.kafkatorio.processor -import dev.adamko.kafkatorio.events.schema.ColourHex import dev.adamko.kafkatorio.processor.config.ApplicationProperties -import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kafkatorio.processor.topology.ServerMapChunkId -import dev.adamko.kafkatorio.processor.topology.ServerMapChunkTiles import dev.adamko.kafkatorio.processor.topology.factorioServerPacketStream import dev.adamko.kafkatorio.processor.topology.groupMapChunks import dev.adamko.kafkatorio.processor.topology.playerUpdatesToWsServer import dev.adamko.kafkatorio.processor.topology.saveMapTiles import dev.adamko.kafkatorio.processor.topology.splitFactorioServerPacketStream -import dev.adamko.kotka.extensions.consumedAs -import dev.adamko.kotka.kxs.serde import java.time.Duration import kotlin.coroutines.CoroutineContext import kotlin.coroutines.cancellation.CancellationException @@ -26,7 +20,6 @@ import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.StreamsConfig import org.apache.kafka.streams.Topology import org.apache.kafka.streams.TopologyDescription -import org.apache.kafka.streams.kstream.KTable internal class KafkatorioTopology( @@ -57,16 +50,7 @@ internal class KafkatorioTopology( private fun saveTiles() { val builder = StreamsBuilder() - - val groupedMapChunkTiles: KTable?> = - builder.table( - TOPIC_GROUPED_MAP_CHUNKS, - consumedAs("consume.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()) - ) - - saveMapTiles(groupedMapChunkTiles) - - val topology = builder.build() + val topology = saveMapTiles(builder) launchTopology("saveTiles", topology) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt index 69c5304..cab13f7 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt @@ -9,7 +9,11 @@ import dev.adamko.kafkatorio.events.schema.MapChunkPosition import dev.adamko.kafkatorio.events.schema.MapTilePosition import dev.adamko.kafkatorio.events.schema.SurfaceIndex import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition -import dev.adamko.kotka.extensions.streams.* +import dev.adamko.kafkatorio.processor.KafkatorioTopology +import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kotka.extensions.consumedAs +import dev.adamko.kotka.extensions.streams.forEach +import dev.adamko.kotka.kxs.serde import java.awt.image.BufferedImage import java.io.File import kotlin.coroutines.CoroutineContext @@ -33,7 +37,9 @@ import kotlinx.coroutines.job import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.supervisorScope -import org.apache.kafka.streams.kstream.KTable +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.Topology +import org.apache.kafka.streams.kstream.KStream private const val WEB_MAP_TILE_SIZE_PX = 256 @@ -48,11 +54,16 @@ private val serverMapChunkHandler = ServerMapChunkHandler() fun saveMapTiles( - serverMapTable: KTable?> -) { + builder: StreamsBuilder, +): Topology { - serverMapTable - .toStream() + val groupedMapChunkTiles: KStream> = + builder.stream( + KafkatorioTopology.TOPIC_GROUPED_MAP_CHUNKS, + consumedAs("consume.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()) + ) + + groupedMapChunkTiles .forEach("save-chunked-tiles") { _, value -> if (value != null) { runBlocking(Dispatchers.Default) { @@ -62,6 +73,7 @@ fun saveMapTiles( } } + return builder.build() } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt index 1858986..d9b0bbd 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt @@ -18,12 +18,20 @@ import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.groupedAs -import dev.adamko.kotka.extensions.materializedWith +import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.producedAs -import dev.adamko.kotka.extensions.streams.* +import dev.adamko.kotka.extensions.streams.filter +import dev.adamko.kotka.extensions.streams.flatMap +import dev.adamko.kotka.extensions.streams.mapValues +import dev.adamko.kotka.extensions.streams.peek +import dev.adamko.kotka.extensions.streams.reduce import dev.adamko.kotka.extensions.tables.join import dev.adamko.kotka.extensions.tables.toStream import dev.adamko.kotka.kxs.serde +import kotlin.coroutines.CoroutineContext +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.serialization.Serializable import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.Topology @@ -104,12 +112,21 @@ fun groupMapChunks( groupedMapChunkTiles .toStream("stream-grouped-map-tiles") + .filter("stream-grouped-map-tiles.filter-not-null") { _, v -> + !v?.map.isNullOrEmpty() + } + .mapValues("stream-grouped-map-tiles.map-not-null") { _, v -> + v as ServerMapChunkTiles + } + .peek("stream-grouped-map-tiles.peek") { _, v -> + println("Grouping map tiles result: ${v.chunkId} / ${v.map.size}") + } .to( KafkatorioTopology.TOPIC_GROUPED_MAP_CHUNKS, producedAs( "produce.grouped-map-chunks", - kxsBinary.serde(), - kxsBinary.serde?>() + kxsBinary.serde(), + kxsBinary.serde>() ) ) @@ -117,38 +134,10 @@ fun groupMapChunks( } private fun groupTilesIntoChunksWithColours( -// mapTilePacketsStream: KStream, -// mapChunksPacketsStream: KStream, mapChunkUpdatePacketsStream: KStream, tileProtoColourDict: KTable, ): KTable> { - -// val mapChunkTilesStream: KStream = -// mapChunksPacketsStream -// .filter { _, packet: FactorioEvent? -> -// when (val data = packet?.data) { -// is MapChunk -> data.tiles.tiles.isNotEmpty() -// else -> false -// } -// } -// .mapValues("map-chunk-packets.convert-to-map-tiles") { _, packet: FactorioEvent -> -// (packet.data as MapChunk).tiles -// } -// -// -// val mapTilesStream: KStream = -// mapTilePacketsStream -// .filter { _, packet: FactorioEvent? -> -// when (val data = packet?.data) { -// is MapTiles -> data.tiles.isNotEmpty() -// else -> false -// } -// } -// .mapValues("map-tiles-packets.convert-to-map-tiles") { _, packet: FactorioEvent -> -// packet.data as MapTiles -// } - val mapChunkUpdatesStream: KStream = mapChunkUpdatePacketsStream .filter { _, packet: FactorioEventUpdatePacket? -> @@ -174,37 +163,38 @@ private fun groupTilesIntoChunksWithColours( } - // group tiles by server & surface & chunk val chunkedTilesTable: KTable> = mapChunkUpdatesStream -// mapTilesStream -// .merge("merge-mapTilesStream-with-mapChunkTilesStream", mapChunkTilesStream) -// .merge("merge-mapTilesStream-with-mapChunkUpdatesStream", mapChunkUpdatesStream) -// .filter { _, value -> !value?.tiles.isNullOrEmpty() } + // group tiles by server & surface & chunk .flatMap("server-map-data.tiles.flatMapByChunk") { serverId: FactorioServerId, mapTiles: MapTiles -> val standardChunkSize = ChunkSize.MAX - mapTiles - .tiles - .groupBy { tile -> - tile.position.toMapChunkPosition(standardChunkSize.tilesPerChunk) - } - .map { (chunkPos, tiles) -> + val flatMappedChunkTiles: List>> = + mapTiles + .tiles + .groupBy { tile -> + tile.position.toMapChunkPosition(standardChunkSize.tilesPerChunk) + } + .map { (chunkPos, tiles) -> - val chunkId = ServerMapChunkId( - serverId = serverId, - chunkPosition = chunkPos, - surfaceIndex = mapTiles.surfaceIndex, - chunkSize = standardChunkSize, - ) + val chunkId = ServerMapChunkId( + serverId = serverId, + chunkPosition = chunkPos, + surfaceIndex = mapTiles.surfaceIndex, + chunkSize = standardChunkSize, + ) - val tilesMap = tiles.associate { it.position to TileProtoHashCode(it) } + val tilesMap = tiles.associate { it.position to TileProtoHashCode(it) } - val chunkTiles = ServerMapChunkTiles(chunkId, tilesMap) + val chunkTiles = ServerMapChunkTiles(chunkId, tilesMap) - chunkId to chunkTiles - } + chunkId to chunkTiles + } + +// println("[${System.currentTimeMillis()}] Flat-mapped ${flatMappedChunkTiles.size} chunk, with ${flatMappedChunkTiles.joinToString { it.second.map.size.toString() }} tiles") + + flatMappedChunkTiles } .filter("server-map-data.tiles.filter-not-empty") { _, value -> value.map.isNotEmpty() @@ -212,18 +202,18 @@ private fun groupTilesIntoChunksWithColours( .groupByKey( groupedAs( "server-map-data.tiles.group", - kxsBinary.serde(), - kxsBinary.serde?>(), + kxsBinary.serde(), + kxsBinary.serde>(), ) ) .reduce( - "server-map-data.tiles.reduce", materializedWith( - // "server-map-data.tiles.store", + "server-map-data.tiles.reduce", + materializedAs( + "server-map-data.tiles.store", kxsBinary.serde(), kxsBinary.serde>(), - ), - ServerMapChunkTiles::plus - ) + ) + ) { chunkTiles, other -> chunkTiles + other } val colourisedChunkTable: KTable> = @@ -231,7 +221,8 @@ private fun groupTilesIntoChunksWithColours( .join( other = tileProtoColourDict, name = "server-map-data.join-tiles-with-prototypes", - materialized = materializedWith( + materialized = materializedAs( + "server-map-data.join-tiles-with-prototypes.store", kxsBinary.serde(), kxsBinary.serde>(), ), @@ -251,11 +242,12 @@ private fun groupTilesIntoChunksWithColours( println("missing ${missingProtos.size} tile prototypes: ${missingProtos.joinToString { "${it.code}" }}") } + println("Set tile colours for chunk ${tiles.chunkId}") + ServerMapChunkTiles(tiles.chunkId, tileColours) } return colourisedChunkTable - } val MapTile.position diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index ad25cfb..9f307eb 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -56,8 +56,8 @@ fun tileProtoColourDictionary( } .toTable( "server-map-data.tile-prototypes", - materializedWith( -// "server-map-data.tile-prototypes.store", + materializedAs( + "server-map-data.tile-prototypes.store", kxsBinary.serde(), kxsBinary.serde(), ) diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt index bed9571..4d46be7 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt @@ -95,12 +95,12 @@ class GroupMapChunksTest : FunSpec({ ) ) - val outputTopic: TestOutputTopic?> = + val outputTopic: TestOutputTopic> = testDriver .createOutputTopic( KafkatorioTopology.TOPIC_GROUPED_MAP_CHUNKS, - kxsBinary.serde().deserializer(), - kxsBinary.serde?>().deserializer(), + kxsBinary.serde().deserializer(), + kxsBinary.serde>().deserializer(), ) val records = outputTopic.readRecordsToList() From 6bb514afc47f322a3b3f4c957b4194b4f59639f3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 13 Mar 2022 12:37:43 +0100 Subject: [PATCH 252/629] still a bit janky (the prototype/tiles join ordering isn't right) but it mostly works, and is performant --- .../processor/topology/groupMapChunks.kt | 141 +++++++++++++----- 1 file changed, 100 insertions(+), 41 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt index d9b0bbd..6c630e6 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt @@ -19,19 +19,28 @@ import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedAs +import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.producedAs +import dev.adamko.kotka.extensions.repartitionedAs import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.flatMap import dev.adamko.kotka.extensions.streams.mapValues import dev.adamko.kotka.extensions.streams.peek import dev.adamko.kotka.extensions.streams.reduce +import dev.adamko.kotka.extensions.streams.toTable +import dev.adamko.kotka.extensions.tableJoined +import dev.adamko.kotka.extensions.tables.filter import dev.adamko.kotka.extensions.tables.join +import dev.adamko.kotka.extensions.tables.mapValues import dev.adamko.kotka.extensions.tables.toStream import dev.adamko.kotka.kxs.serde import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.runBlocking import kotlinx.serialization.Serializable import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.Topology @@ -71,19 +80,6 @@ fun groupMapChunks( val tileProtoColourDict: KTable = tileProtoColourDictionary(protosStream) - -// val mapTilesStream: KStream = -// builder.stream( -// "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.LuaTiles}", -// consumedAs("consume.map-tiles", jsonMapper.serde(), jsonMapper.serde()) -// ) -// -// val mapChunksStream: KStream = -// builder.stream( -// "kafkatorio.${KafkatorioPacket.PacketType.EVENT}.${FactorioObjectData.ObjectName.MapChunk}", -// consumedAs("consume.map-chunks", jsonMapper.serde(), jsonMapper.serde()) -// ) - val mapChunksUpdatesStream: KStream = builder.stream( mapChunkUpdatesTopicName, @@ -93,19 +89,9 @@ fun groupMapChunks( jsonMapper.serde(), ) ) -// .repartition( -// repartitionedAs( -// "map-chunk-updates.repartition.change-serde", -// kxsBinary.serde(), -// kxsBinary.serde(), -// numberOfPartitions = 3, -// ) -// ) val groupedMapChunkTiles: KTable> = groupTilesIntoChunksWithColours( -// mapTilesStream, -// mapChunksStream, mapChunksUpdatesStream, tileProtoColourDict, ) @@ -133,6 +119,11 @@ fun groupMapChunks( return builder.build() } + +private val coroutineContext: CoroutineContext = + Dispatchers.Default + SupervisorJob() + CoroutineName("groupTilesIntoChunksWithColours") + + private fun groupTilesIntoChunksWithColours( mapChunkUpdatePacketsStream: KStream, tileProtoColourDict: KTable, @@ -171,29 +162,36 @@ private fun groupTilesIntoChunksWithColours( val standardChunkSize = ChunkSize.MAX val flatMappedChunkTiles: List>> = - mapTiles - .tiles - .groupBy { tile -> - tile.position.toMapChunkPosition(standardChunkSize.tilesPerChunk) - } - .map { (chunkPos, tiles) -> + // println("[${System.currentTimeMillis()}] Flat-mapped ${flatMappedChunkTiles.size} chunk, with ${flatMappedChunkTiles.joinToString { it.second.map.size.toString() }} tiles") + runBlocking(coroutineContext) { - val chunkId = ServerMapChunkId( - serverId = serverId, - chunkPosition = chunkPos, - surfaceIndex = mapTiles.surfaceIndex, - chunkSize = standardChunkSize, - ) + mapTiles + .tiles + .groupBy { tile -> + tile.position.toMapChunkPosition(standardChunkSize.tilesPerChunk) + } + .map { (chunkPos, tiles) -> - val tilesMap = tiles.associate { it.position to TileProtoHashCode(it) } + async { - val chunkTiles = ServerMapChunkTiles(chunkId, tilesMap) + val chunkId = ServerMapChunkId( + serverId = serverId, + chunkPosition = chunkPos, + surfaceIndex = mapTiles.surfaceIndex, + chunkSize = standardChunkSize, + ) - chunkId to chunkTiles - } + val tilesMap = tiles.associate { it.position to TileProtoHashCode(it) } + + val chunkTiles = ServerMapChunkTiles(chunkId, tilesMap) + + chunkId to chunkTiles + } + }.awaitAll() // println("[${System.currentTimeMillis()}] Flat-mapped ${flatMappedChunkTiles.size} chunk, with ${flatMappedChunkTiles.joinToString { it.second.map.size.toString() }} tiles") + } flatMappedChunkTiles } .filter("server-map-data.tiles.filter-not-empty") { _, value -> @@ -214,13 +212,74 @@ private fun groupTilesIntoChunksWithColours( kxsBinary.serde>(), ) ) { chunkTiles, other -> chunkTiles + other } + .toStream("server-map-data.tiles.repartition.to-stream") + .repartition( + repartitionedAs( + "server-map-data.tiles.repartition.config", + kxsBinary.serde(), + kxsBinary.serde?>(), + 3, + ) + ).toTable( + "server-map-data.tiles.repartition.to-table", + materializedAs( + "server-map-data.tiles.repartition.to-table.store", + kxsBinary.serde(), + kxsBinary.serde?>(), + ) + ) + .filter("server-map-data.tiles.repartition.filter-not-null") { _: ServerMapChunkId, v: ServerMapChunkTiles? -> + v != null + } + .mapValues( + "server-map-data.tiles.repartition.map-not-null", + materializedWith( + kxsBinary.serde(), + kxsBinary.serde>(), + ) + ) { _: ServerMapChunkId, v: ServerMapChunkTiles? -> + v as ServerMapChunkTiles + } + + + // repartition to try and fix KTable-KTable joining skipping records + val tileProtoColourDictRepartitioned = + tileProtoColourDict + .toStream("tileProtoColourDict.repartition.to-stream") + .repartition( + repartitionedAs( + "tileProtoColourDict.repartition.config", + kxsBinary.serde(), + kxsBinary.serde(), + 3, + ) + ).toTable( + "tileProtoColourDict.repartition.to-table", + materializedAs( + "tileProtoColourDict.repartition.to-table.store", + kxsBinary.serde(), + kxsBinary.serde(), + ) + ) + .filter("tileProtoColourDict.repartition.filter-not-null") { _: FactorioServerId, v: TileColourDict? -> + v != null + } + .mapValues( + "tileProtoColourDict.repartition.map-not-null", + materializedWith( + kxsBinary.serde(), + kxsBinary.serde(), + ) + ) { _: FactorioServerId, v: TileColourDict? -> + v as TileColourDict + } val colourisedChunkTable: KTable> = chunkedTilesTable .join( - other = tileProtoColourDict, - name = "server-map-data.join-tiles-with-prototypes", + other = tileProtoColourDictRepartitioned, + tableJoined = tableJoined("server-map-data.join-tiles-with-prototypes"), materialized = materializedAs( "server-map-data.join-tiles-with-prototypes.store", kxsBinary.serde(), From 0cf2b344e37c520a90cce2b12634c3d2066a8f7f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 13 Mar 2022 23:54:15 +0100 Subject: [PATCH 253/629] webmap: temp-fix white line gap bug --- .../src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt | 2 ++ modules/web-map/src/main/resources/css/kafkatorio.css | 5 +++++ 2 files changed, 7 insertions(+) create mode 100644 modules/web-map/src/main/resources/css/kafkatorio.css diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index 7615b19..57ae7d8 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -12,6 +12,7 @@ import io.kvision.maps.Maps import io.kvision.module import io.kvision.panel.root import io.kvision.redux.ReduxStore +import io.kvision.require import io.kvision.startApplication @@ -27,6 +28,7 @@ class App( init { this.reduxStore = reduxStore this.wsService = wsService + require("./css/kafkatorio.css") } private val kvMaps: Maps diff --git a/modules/web-map/src/main/resources/css/kafkatorio.css b/modules/web-map/src/main/resources/css/kafkatorio.css new file mode 100644 index 0000000..b6b3d9b --- /dev/null +++ b/modules/web-map/src/main/resources/css/kafkatorio.css @@ -0,0 +1,5 @@ +/* https://github.com/Leaflet/Leaflet/issues/3575 */ +.leaflet-tile { + width: 257px !important; + height: 257px !important; +} From 8c22329b108a92915ed58d21fa0365a00334aee7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 13 Mar 2022 23:58:14 +0100 Subject: [PATCH 254/629] webmap: remove zoom offset (no longer required, changed the zoom offset in processing) --- .../web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index f8108f0..21ee00b 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -41,7 +41,7 @@ fun createFactorioMap() = Maps { // NOTE: offset the zoom, so 1 meter = 1 tile maxNativeZoom = 3 minNativeZoom = -1 - zoomOffset = 1 +// zoomOffset = 1 noWrap = true updateWhenIdle = false From 0ebf492b42d2b2da3181dff08fcace0a6bffc171 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 13 Mar 2022 23:58:41 +0100 Subject: [PATCH 255/629] max task idle ms - try fixing ktable-ktable join... --- .../dev/adamko/kafkatorio/processor/KafkatorioTopology.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 1b22f49..1fcd511 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -9,6 +9,7 @@ import dev.adamko.kafkatorio.processor.topology.splitFactorioServerPacketStream import java.time.Duration import kotlin.coroutines.CoroutineContext import kotlin.coroutines.cancellation.CancellationException +import kotlin.time.Duration.Companion.minutes import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -80,6 +81,7 @@ internal class KafkatorioTopology( val appId = props.compute(StreamsConfig.APPLICATION_ID_CONFIG) { _, v -> "$v.$id" } as? String props.setProperty(StreamsConfig.APPLICATION_ID_CONFIG, appId) + props.setProperty(StreamsConfig.MAX_TASK_IDLE_MS_CONFIG, "${1.minutes.inWholeMilliseconds}") val streams = KafkaStreams(topology, props) streams.setUncaughtExceptionHandler(StreamsExceptionHandler { From 057eee6a687d4f76f39fb0815d00334802949eea Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 14 Mar 2022 00:00:04 +0100 Subject: [PATCH 256/629] - remove coroutines (most packets will only have one group, so it doesn't help much) - don't materialize to named stores (unneeded) --- .../processor/topology/groupMapChunks.kt | 76 +++++++++---------- 1 file changed, 35 insertions(+), 41 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt index 6c630e6..8dd972f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt @@ -18,7 +18,6 @@ import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.groupedAs -import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.repartitionedAs @@ -34,13 +33,20 @@ import dev.adamko.kotka.extensions.tables.join import dev.adamko.kotka.extensions.tables.mapValues import dev.adamko.kotka.extensions.tables.toStream import dev.adamko.kotka.kxs.serde -import kotlin.coroutines.CoroutineContext -import kotlinx.coroutines.CoroutineName -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.runBlocking +import kotlin.collections.List +import kotlin.collections.Map +import kotlin.collections.associate +import kotlin.collections.component1 +import kotlin.collections.component2 +import kotlin.collections.getOrElse +import kotlin.collections.groupBy +import kotlin.collections.isNotEmpty +import kotlin.collections.isNullOrEmpty +import kotlin.collections.joinToString +import kotlin.collections.map +import kotlin.collections.mapValues +import kotlin.collections.mutableSetOf +import kotlin.collections.plus import kotlinx.serialization.Serializable import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.Topology @@ -120,10 +126,6 @@ fun groupMapChunks( } -private val coroutineContext: CoroutineContext = - Dispatchers.Default + SupervisorJob() + CoroutineName("groupTilesIntoChunksWithColours") - - private fun groupTilesIntoChunksWithColours( mapChunkUpdatePacketsStream: KStream, tileProtoColourDict: KTable, @@ -163,35 +165,30 @@ private fun groupTilesIntoChunksWithColours( val flatMappedChunkTiles: List>> = // println("[${System.currentTimeMillis()}] Flat-mapped ${flatMappedChunkTiles.size} chunk, with ${flatMappedChunkTiles.joinToString { it.second.map.size.toString() }} tiles") - runBlocking(coroutineContext) { - mapTiles - .tiles - .groupBy { tile -> - tile.position.toMapChunkPosition(standardChunkSize.tilesPerChunk) - } - .map { (chunkPos, tiles) -> + mapTiles + .tiles + .groupBy { tile -> + tile.position.toMapChunkPosition(standardChunkSize.tilesPerChunk) + } + .map { (chunkPos, tiles) -> - async { + val chunkId = ServerMapChunkId( + serverId = serverId, + chunkPosition = chunkPos, + surfaceIndex = mapTiles.surfaceIndex, + chunkSize = standardChunkSize, + ) - val chunkId = ServerMapChunkId( - serverId = serverId, - chunkPosition = chunkPos, - surfaceIndex = mapTiles.surfaceIndex, - chunkSize = standardChunkSize, - ) + val tilesMap = tiles.associate { it.position to TileProtoHashCode(it) } - val tilesMap = tiles.associate { it.position to TileProtoHashCode(it) } + val chunkTiles = ServerMapChunkTiles(chunkId, tilesMap) - val chunkTiles = ServerMapChunkTiles(chunkId, tilesMap) - - chunkId to chunkTiles - } - }.awaitAll() + chunkId to chunkTiles + } // println("[${System.currentTimeMillis()}] Flat-mapped ${flatMappedChunkTiles.size} chunk, with ${flatMappedChunkTiles.joinToString { it.second.map.size.toString() }} tiles") - } flatMappedChunkTiles } .filter("server-map-data.tiles.filter-not-empty") { _, value -> @@ -206,8 +203,7 @@ private fun groupTilesIntoChunksWithColours( ) .reduce( "server-map-data.tiles.reduce", - materializedAs( - "server-map-data.tiles.store", + materializedWith( kxsBinary.serde(), kxsBinary.serde>(), ) @@ -222,8 +218,7 @@ private fun groupTilesIntoChunksWithColours( ) ).toTable( "server-map-data.tiles.repartition.to-table", - materializedAs( - "server-map-data.tiles.repartition.to-table.store", + materializedWith( kxsBinary.serde(), kxsBinary.serde?>(), ) @@ -255,8 +250,7 @@ private fun groupTilesIntoChunksWithColours( ) ).toTable( "tileProtoColourDict.repartition.to-table", - materializedAs( - "tileProtoColourDict.repartition.to-table.store", + materializedWith( kxsBinary.serde(), kxsBinary.serde(), ) @@ -280,8 +274,8 @@ private fun groupTilesIntoChunksWithColours( .join( other = tileProtoColourDictRepartitioned, tableJoined = tableJoined("server-map-data.join-tiles-with-prototypes"), - materialized = materializedAs( - "server-map-data.join-tiles-with-prototypes.store", + materialized = materializedWith( +// "server-map-data.join-tiles-with-prototypes.store", kxsBinary.serde(), kxsBinary.serde>(), ), From 1fbe0d87b0d7a22341a0d9ff9eecb566fa445f42 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 14 Mar 2022 00:01:51 +0100 Subject: [PATCH 257/629] fix EntityIdentifiers deserialization bug (kxs has polymorphism problems with interfaces) --- .../generated/kafkatorio-schema/update.d.ts | 6 +- .../events/schema/factorioCommonData.kt | 10 +++ .../events/schema/factorioEventUpdates.kt | 6 +- .../events/schema/UpdatePacketsTest.kt | 71 +++++++++++++++++-- 4 files changed, 82 insertions(+), 11 deletions(-) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts index ed61598..058fb45 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts @@ -28,7 +28,7 @@ interface PlayerUpdate extends FactorioEventUpdate, PlayerUpdateKey { characterUnitNumber: uint | null; chatColour: Colour | null; colour: Colour | null; - diedCause: EntityIdentifiers | null; + diedCause: EntityIdentifiersData | null; disconnectReason: string | null; eventCounts: { [key: string]: uint } | null; forceIndex: uint | null; @@ -55,7 +55,7 @@ interface EntityUpdateKey extends EntityIdentifiers, FactorioEventUpdateKey { unitNumber: uint; } -interface EntityUpdate extends FactorioEventUpdate, EntityIdentifiers, EntityUpdateKey { +interface EntityUpdate extends FactorioEventUpdate, EntityUpdateKey { chunkPosition: MapChunkPosition | null; eventCounts: { [key: string]: uint } | null; graphicsVariation: uint8 | null; @@ -83,7 +83,7 @@ interface MapChunkUpdate extends FactorioEventUpdate, MapChunkUpdateKey { force: uint | null; isDeleted: boolean | null; player: uint | null; - robot: EntityIdentifiers | null; + robot: EntityIdentifiersData | null; surfaceIndex: uint; tileDictionary: MapTileDictionary | null; updateType: FactorioEventUpdateType; diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index 65b7e36..fb91302 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -102,6 +102,16 @@ interface EntityIdentifiers { } +// instant of EntityIdentifiers, because kxs needs a concrete instance +@Serializable +data class EntityIdentifiersData( + override val unitNumber: UnitNumber? = null, + override val name: String, + /** The prototype-type of the entity. */ + override val type: String, +) : EntityIdentifiers + + /** * Size-optimised 2D map of x/y tile positions and prototype-name. * diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt index e930361..2e7441d 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt @@ -113,7 +113,7 @@ data class PlayerUpdate( val position: MapEntityPosition? = null, val surfaceIndex: SurfaceIndex? = null, val tag: String? = null, - val diedCause: EntityIdentifiers? = null, + val diedCause: EntityIdentifiersData? = null, val bannedReason: String? = null, val kickedReason: String? = null, @@ -154,7 +154,7 @@ data class EntityUpdate( val localisedDescription: String? = null, val localisedName: String? = null, val prototype: PrototypeName? = null, -) : FactorioEventUpdate(), EntityIdentifiers, EntityUpdateKey { +) : FactorioEventUpdate(), EntityUpdateKey { @EncodeDefault override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.ENTITY } @@ -177,7 +177,7 @@ data class MapChunkUpdate( override val eventCounts: Map? = null, val player: PlayerIndex? = null, - val robot: EntityIdentifiers? = null, + val robot: EntityIdentifiersData? = null, val force: ForceIndex? = null, /** updated tiles - might be partial and not all tiles in the chunk */ val tileDictionary: MapTileDictionary? = null, diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt index 02c1760..638ceea 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt @@ -62,7 +62,7 @@ class UpdatePacketsTest : FunSpec({ bannedReason = null, characterUnitNumber = null, chatColour = Colour(red = 1f, green = 0.4f, blue = 0.6f, alpha = 1f), - colour = Colour(red = 0.8f, green = 0.5f, blue = 0.2f, alpha = 0.5f), + colour = Colour(red = 0.8f, green = 0.5f, blue = 0.2f, alpha = 0.5f), diedCause = null, disconnectReason = null, eventCounts = mapOf("on_player_changed_position" to 7u, "on_player_joined_game" to 1u), @@ -141,9 +141,70 @@ class UpdatePacketsTest : FunSpec({ } } + context("player died") { + // language=JSON + val json = """ + { + "tick": 227934, + "modVersion": "0.3.2", + "packetType": "UPDATE", + "update": { + "index": 1, + "updateType": "PLAYER", + "lastOnline": 227932, + "onlineTime": 227888, + "afkTime": 324, + "isConnected": true, + "diedCause": { + "unitNumber": 66, + "name": "small-biter", + "type": "unit" + }, + "eventCounts": { + "on_player_died": 2 + } + } + } + """.trimIndent() + + test("decode") { + val packet: FactorioEventUpdatePacket = jsonMapperKafkatorio.decodeFromString(json) + + packet shouldBe FactorioEventUpdatePacket( + modVersion = "0.3.2", + tick = Tick(227934u), + update = PlayerUpdate( + afkTime = Tick(324u), + bannedReason = null, + characterUnitNumber = null, + chatColour = null, + colour = null, + diedCause = EntityIdentifiersData( + unitNumber = UnitNumber(66u), + name = "small-biter", + type = "unit", + ), + disconnectReason = null, + eventCounts = mapOf("on_player_died" to 2u), + forceIndex = null, + index = PlayerIndex(1u), + isAdmin = null, + isConnected = true, + isRemoved = null, + isShowOnMap = null, + isSpectator = null, + kickedReason = null, + lastOnline = Tick(227932u), + name = null, + onlineTime = Tick(227888u), + position = null, + surfaceIndex = null, + tag = null, + ticksToRespawn = null, + ) + ) + } + + } }) - -/* -{"tick":66,"modVersion":"0.3.2","packetType":"UPDATE","update":{"index":1,"updateType":"PLAYER","position":{"y":13.5234375,"x":-58.9375},"eventCounts":{"on_player_changed_position":7,"on_player_joined_game":1},"isAdmin":true,"chatColour":{"red":1,"green":0.62999999523162841796875,"blue":0.259000003337860107421875,"alpha":1},"colour":{"red":0.869000017642974853515625,"green":0.5,"blue":0.12999999523162841796875,"alpha":0.5},"forceIndex":1,"name":"fredthedeadhead","isShowOnMap":true,"isSpectator":false,"tag":"","lastOnline":0,"onlineTime":0,"afkTime":0,"isConnected":true}} - */ From 8d36111d9af88c4d222e27b23f592efc5fa4ff20 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 14 Mar 2022 00:05:15 +0100 Subject: [PATCH 258/629] - start code clean up by commenting out unused/deprecated code (start moving towards the 'event updates' Kafkatorio packets - bring back the event Queue, and the command to emit lots of chunks - allow setting the event update timeout directly when debouncing/throttling an update --- .../events-mod/src/main/typescript/control.ts | 1 - .../kafkatorio-schema/object-data.d.ts | 42 +- .../generated/kafkatorio-schema/schema.d.ts | 48 +- .../typescript/main/cache/EventDataCache.ts | 12 +- .../main/commands/kafkatorioCommands.ts | 21 +- .../main/typescript/main/events/converters.ts | 134 ++-- .../main/typescript/main/events/handlers.ts | 112 +-- .../main/events/onMapChunkEventListeners.ts | 37 +- .../main/events/registerHandlers.ts | 58 +- .../events/schema/factorioLuaObjects.kt | 122 ++-- .../events/schema/FactorioEventTest.kt | 662 +++++++++--------- 11 files changed, 613 insertions(+), 636 deletions(-) diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index 37ae877..6501c36 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -11,7 +11,6 @@ require("./main/cache/cacheChecker") script.on_configuration_changed((data: ConfigurationChangedData) => { // runs whenever the version of the base game, or a mod, changes - initGlobal(true) KafkatorioSettings.loadSettings() emitConfigurationUpdate(data) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts index 60cd5c8..e6d895d 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts @@ -1,38 +1,11 @@ // Generated by TypeScriptGenerator - do not edit this file manually -type ObjectName = "LuaPlayer" | "LuaEntity" | "LuaSurface" | "MapChunk" | "LuaTiles" | "ConsoleChatMessage"; +type ObjectName = "LuaSurface" | "ConsoleChatMessage"; interface FactorioObjectData { objectName: ObjectName; } -interface PlayerData extends FactorioObjectData, FactorioLuaControl { - associatedCharactersUnitNumbers: uint[]; - characterUnitNumber: uint | null; - chatColour: Colour; - colour: Colour; - force: uint; - lastOnline: uint; - name: string; - objectName: ObjectName; - position: MapEntityPosition; - surface: uint; -} - -interface EntityData extends FactorioObjectData, FactorioLuaControl { - active: boolean; - force: uint; - health: double | null; - healthRatio: double | null; - name: string; - objectName: ObjectName; - playerIndex: uint | null; - position: MapEntityPosition; - surface: uint; - type: string; - unitNumber: uint | null; -} - interface SurfaceData extends FactorioObjectData { daytime: double; index: uint; @@ -40,19 +13,6 @@ interface SurfaceData extends FactorioObjectData { objectName: ObjectName; } -interface MapTiles extends FactorioObjectData { - objectName: ObjectName; - surfaceIndex: uint; - tiles: MapTile[]; -} - -interface MapChunk extends FactorioObjectData { - area: MapBoundingBox; - objectName: ObjectName; - position: MapChunkPosition; - tiles: MapTiles; -} - interface ConsoleChatMessage extends FactorioObjectData { authorPlayerIndex: uint | null; content: string; diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts index 3c42507..7ce627e 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts @@ -16,17 +16,6 @@ interface FactorioEvent extends KafkatorioPacket { tick: uint; } -interface MapEntityPosition { - x: double; - y: double; -} - -interface FactorioLuaControl { - force: uint; - position: MapEntityPosition; - surface: uint; -} - interface Colour { alpha: float; blue: float; @@ -34,33 +23,28 @@ interface Colour { red: float; } -interface MapTilePosition { - x: int; - y: int; -} - -interface MapBoundingBox { - bottomRight: MapTilePosition; - topLeft: MapTilePosition; -} - -interface MapChunkPosition { - x: int; - y: int; -} - -interface MapTile { - proto: string; - x: int; - y: int; -} - interface EntityIdentifiers { name: string; type: string; unitNumber: uint | null; } +interface EntityIdentifiersData extends EntityIdentifiers { + name: string; + type: string; + unitNumber: uint | null; +} + +interface MapEntityPosition { + x: double; + y: double; +} + +interface MapChunkPosition { + x: int; + y: int; +} + interface MapTileDictionary { protos: { [key: string]: string }; tilesXY: { [key: string]: { [key: string]: string } }; diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts index 8a0b89b..a77510c 100644 --- a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts +++ b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts @@ -32,8 +32,9 @@ export namespace EventUpdates { public throttle( key: CacheKey, mutate: CacheDataMutator, + expirationDurationTicks?: uint, ) { - this.update(key, mutate, false) + this.update(key, mutate, false, expirationDurationTicks) } @@ -44,8 +45,9 @@ export namespace EventUpdates { public debounce( key: CacheKey, mutate: CacheDataMutator, + expirationDurationTicks?: uint, ) { - this.update(key, mutate, true) + this.update(key, mutate, true, expirationDurationTicks) } @@ -53,12 +55,16 @@ export namespace EventUpdates { key: CacheKey, mutate: CacheDataMutator, resetLastUpdated: boolean, + expirationDurationTicks?: uint, ) { - const entry = this.getCacheEntry(key) ?? this.createCacheEntry(key, mutate) + const entry: CacheEntry = this.getCacheEntry(key) ?? this.createCacheEntry(key, mutate) mutate(entry.data) if (resetLastUpdated) { entry.lastUpdatedTick = game.tick } + if (expirationDurationTicks != undefined) { + entry.expirationDurationTicks = expirationDurationTicks + } } diff --git a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts index 940b8d6..1443028 100644 --- a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts +++ b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts @@ -1,7 +1,7 @@ import {emitPrototypes} from "../config-update/prototypes"; -import {Queue} from "../queue/queue"; import {initGlobal} from "../global-init"; import floor = math.floor; +import {Queue} from "../queue/queue"; commands.add_command( @@ -24,22 +24,24 @@ commands.add_command( emitPrototypes() } else if (paramUppercase.startsWith("CHUNKS")) { - let size = paramUppercase.split(" ")?.[1] ?? null + const size = paramUppercase.split(" ")?.[1] ?? null let radius = (size != null) ? parseInt(size) : 1 + // radius = Math.max(radius, 10) if (e.player_index != undefined) { let player = game.players[e.player_index] - let chunkPosition: ChunkPosition = { + const chunkPosition: ChunkPosition = { x: floor(player.position.x / 32), y: floor(player.position.y / 32), } - let chunkXMin = chunkPosition.x - radius - let chunkXMax = chunkPosition.x + radius - let chunkYMin = chunkPosition.y - radius - let chunkYMax = chunkPosition.y + radius + const chunkXMin = chunkPosition.x - radius + const chunkXMax = chunkPosition.x + radius + const chunkYMin = chunkPosition.y - radius + const chunkYMax = chunkPosition.y + radius + // let i = 100 for (const [, surface] of game.surfaces) { for (const chunk of surface.get_chunks()) { if ( @@ -48,7 +50,7 @@ commands.add_command( (chunk.y >= chunkYMin && chunk.y <= chunkYMax) ) { - let data: OnChunkGeneratedEvent = { + const data: OnChunkGeneratedEvent = { name: defines.events.on_chunk_generated, position: {x: chunk.x, y: chunk.y}, area: chunk.area, @@ -61,6 +63,9 @@ commands.add_command( data, 50 ) + + // handleChunkGeneratedEvent(data, i) + // i = i + 10 } } } diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index c29e1c5..3eedfa7 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -29,38 +29,38 @@ export namespace Converters { } - export function entityToTable(entity: LuaEntity): EntityData { - - let player: LuaPlayer | null = entity.is_player() ? entity.player!! : null - - return { - objectName: entity.object_name, - - // entity data - name: entity.name, - type: entity.type, - active: entity.active, - health: entity.health ?? null, - healthRatio: entity.get_health_ratio() ?? null, - surface: entity.surface.index, - unitNumber: entity.unit_number ?? null, - position: mapEntityPosition(entity.position), - force: entity.force.index, - - // player data - playerIndex: player?.index ?? null - } - } - - function entitiesToUnitNumbers(entities: LuaEntity[]): uint[] { - let result: (uint) [] = [] - for (let entity of entities) { - if (entity.unit_number != null) { - result[result.length] = entity.unit_number - } - } - return result - } + // export function entityToTable(entity: LuaEntity): EntityData { + // + // let player: LuaPlayer | null = entity.is_player() ? entity.player!! : null + // + // return { + // objectName: entity.object_name, + // + // // entity data + // name: entity.name, + // type: entity.type, + // active: entity.active, + // health: entity.health ?? null, + // healthRatio: entity.get_health_ratio() ?? null, + // surface: entity.surface.index, + // unitNumber: entity.unit_number ?? null, + // position: mapEntityPosition(entity.position), + // force: entity.force.index, + // + // // player data + // playerIndex: player?.index ?? null + // } + // } + // + // function entitiesToUnitNumbers(entities: LuaEntity[]): uint[] { + // let result: (uint) [] = [] + // for (let entity of entities) { + // if (entity.unit_number != null) { + // result[result.length] = entity.unit_number + // } + // } + // return result + // } export function surfaceToTable(surface: LuaSurface): SurfaceData { return { @@ -72,26 +72,26 @@ export namespace Converters { } } - export function mapEntityPosition(mapPos: MapPositionTable): MapEntityPosition { - return { - x: mapPos.x, - y: mapPos.y, - } - } + // export function mapEntityPosition(mapPos: MapPositionTable): MapEntityPosition { + // return { + // x: mapPos.x, + // y: mapPos.y, + // } + // } - export function mapTilePosition(mapPos: MapPositionTable): MapTilePosition { - return { - x: mapPos.x, - y: mapPos.y, - } - } + // export function mapTilePosition(mapPos: MapPositionTable): MapTilePosition { + // return { + // x: mapPos.x, + // y: mapPos.y, + // } + // } - export function mapChunkPosition(mapPos: ChunkPositionTable): MapChunkPosition { - return { - x: mapPos.x, - y: mapPos.y, - } - } + // export function mapChunkPosition(mapPos: ChunkPositionTable): MapChunkPosition { + // return { + // x: mapPos.x, + // y: mapPos.y, + // } + // } export function mapColour(color: ColorTable): Colour { return { @@ -111,23 +111,23 @@ export namespace Converters { } } - export function convertTile(tile: LuaTile): MapTile { - return { - x: tile.position.x, - y: tile.position.y, - proto: tile.prototype.name, - } - } + // export function convertTile(tile: LuaTile): MapTile { + // return { + // x: tile.position.x, + // y: tile.position.y, + // proto: tile.prototype.name, + // } + // } + // + // export function convertTiles(tiles: LuaTile[]): MapTile[] { + // return tiles.map((tile: LuaTile) => convertTile(tile)) + // } - export function convertTiles(tiles: LuaTile[]): MapTile[] { - return tiles.map((tile: LuaTile) => convertTile(tile)) - } - - export function convertBoundingBox(bb: BoundingBoxRead): MapBoundingBox { - return { - topLeft: mapTilePosition(bb.left_top), - bottomRight: mapTilePosition(bb.right_bottom), - } - } + // export function convertBoundingBox(bb: BoundingBoxRead): MapBoundingBox { + // return { + // topLeft: mapTilePosition(bb.left_top), + // bottomRight: mapTilePosition(bb.right_bottom), + // } + // } } diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index cb6f485..4de8672 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -10,24 +10,24 @@ import {emitEvent} from "./emitEvent"; // handleCharactersEvent(tick, eventType, playerIndex) // } -export function handleCharactersEvent(tick: uint, eventType: string, playerIndex: uint) { +// export function handleCharactersEvent(tick: uint, eventType: string, playerIndex: uint) { +// +// let player: LuaPlayer = game.players[playerIndex] +// +// if (player.character != undefined) { +// handleEntityUpdate(tick, eventType, player.character) +// } +// for (const character of player.get_associated_characters()) { +// if (character != undefined) { +// handleEntityUpdate(tick, eventType, character) +// } +// } +// } - let player: LuaPlayer = game.players[playerIndex] - - if (player.character != undefined) { - handleEntityUpdate(tick, eventType, player.character) - } - for (const character of player.get_associated_characters()) { - if (character != undefined) { - handleEntityUpdate(tick, eventType, character) - } - } -} - -export function handleEntityUpdate(tick: uint, eventType: string, entity: LuaEntity) { - let table = Converters.entityToTable(entity) - emitEvent(table, tick, eventType) -} +// export function handleEntityUpdate(tick: uint, eventType: string, entity: LuaEntity) { +// let table = Converters.entityToTable(entity) +// emitEvent(table, tick, eventType) +// } export function handleSurfaceUpdate( tick: uint, @@ -48,35 +48,35 @@ export function handleConsoleChat( emitEvent(table, tick, eventType) } -export function handleChunkUpdate( - tick: uint, - eventType: string, - surfaceIndex: uint, - position: ChunkPositionTable, - area: BoundingBoxRead, -) { - - let surface = game.get_surface(surfaceIndex) - - let tiles: LuaTile[] = surface?.find_tiles_filtered({ - area: area, - collision_mask: ["ground-tile", "water-tile"] - } - ) ?? [] - - let convertedTiles: MapTile[] = tiles.map((tile: LuaTile) => { - return Converters.convertTile(tile) - }) - - let mapChunk: MapChunk = { - objectName: "MapChunk", - tiles: createMapTiles(surfaceIndex, convertedTiles), - position: Converters.mapChunkPosition(position), - area: Converters.convertBoundingBox(area), - } - - emitEvent(mapChunk, tick, eventType) -} +// export function handleChunkUpdate( +// tick: uint, +// eventType: string, +// surfaceIndex: uint, +// position: ChunkPositionTable, +// area: BoundingBoxRead, +// ) { +// +// let surface = game.get_surface(surfaceIndex) +// +// let tiles: LuaTile[] = surface?.find_tiles_filtered({ +// area: area, +// collision_mask: ["ground-tile", "water-tile"] +// } +// ) ?? [] +// +// let convertedTiles: MapTile[] = tiles.map((tile: LuaTile) => { +// return Converters.convertTile(tile) +// }) +// +// let mapChunk: MapChunk = { +// objectName: "MapChunk", +// tiles: createMapTiles(surfaceIndex, convertedTiles), +// position: Converters.mapChunkPosition(position), +// area: Converters.convertBoundingBox(area), +// } +// +// emitEvent(mapChunk, tick, eventType) +// } // export function handleTilesUpdate( // tick: uint, @@ -104,13 +104,13 @@ export function handleChunkUpdate( // } // } -function createMapTiles( - surfaceIndex: uint, - tiles: MapTile[], -): MapTiles { - return { - objectName: "LuaTiles", - surfaceIndex: surfaceIndex, - tiles: tiles, - } -} +// function createMapTiles( +// surfaceIndex: uint, +// tiles: MapTile[], +// ): MapTiles { +// return { +// objectName: "LuaTiles", +// surfaceIndex: surfaceIndex, +// tiles: tiles, +// } +// } diff --git a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts index 3b2284e..91a49e9 100644 --- a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts @@ -11,6 +11,7 @@ type MapChunkUpdater = (data: CacheData<"MAP_CHUNK">) => void const mapProtoNameToKey: { [key: string]: string } = {} let protoIndex: uint = 0 + function getProtoKey(protoName: string): string { if (mapProtoNameToKey[protoName] == undefined) { mapProtoNameToKey[protoName] = `${protoIndex++}` @@ -25,6 +26,7 @@ function mapTilesUpdateDebounce( tiles: TileRead[], eventName: string, updater?: MapChunkUpdater, + expirationDurationTicks?: uint, ) { if (surface == undefined) { @@ -64,7 +66,8 @@ function mapTilesUpdateDebounce( if (updater != undefined) { updater(data) } - } + }, + expirationDurationTicks, ) } @@ -80,20 +83,37 @@ function getTiles( ) ?? [] } + function getSurface(surfaceIndex: uint): LuaSurface | undefined { return game.surfaces[surfaceIndex] } + script.on_event( defines.events.on_chunk_generated, (e: OnChunkGeneratedEvent) => { log(`on_chunk_generated ${e.tick}`) - - let tiles = getTiles(e.surface, e.area) - mapTilesUpdateDebounce(e.surface, e.position, tiles, Converters.eventNameString(e.name)) + handleChunkGeneratedEvent(e) } ) + +export function handleChunkGeneratedEvent( + e: OnChunkGeneratedEvent, + expirationDurationTicks?: uint, +) { + let tiles = getTiles(e.surface, e.area) + mapTilesUpdateDebounce( + e.surface, + e.position, + tiles, + Converters.eventNameString(e.name), + undefined, + expirationDurationTicks, + ) +} + + script.on_event( defines.events.on_chunk_charted, (e: OnChunkChartedEvent) => { @@ -111,6 +131,7 @@ script.on_event( } ) + script.on_event( defines.events.script_raised_set_tiles, (e: ScriptRaisedSetTilesEvent) => { @@ -146,6 +167,7 @@ function groupTiles(tiles: TileRead[]): Map { return mapChunkPositionToTiles } + function convertOldPosition( oldTiles: OldTileAndPosition[], placedTile: LuaTilePrototype, @@ -160,6 +182,7 @@ function convertOldPosition( ) } + function onBuildTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) { const surface = getSurface(event.surface_index) @@ -199,6 +222,7 @@ function onBuildTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) } } + script.on_event(defines.events.on_player_built_tile, (e: OnPlayerBuiltTileEvent) => { log(`on_player_built_tile ${e.tick}`) onBuildTileEvent(e) @@ -246,10 +270,9 @@ script.on_event( key, data => { data.isDeleted = true - } + }, + 0, // deletion is important - emit ASAP ) - // deletion is important - emit ASAP - EventUpdatesManager.setExpiration(key, 0) } } ) diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index a5781b4..b1315ee 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -1,23 +1,19 @@ -import { - handleChunkUpdate, - handleConsoleChat, - handleEntityUpdate, - handleSurfaceUpdate, -} from "./handlers"; +import {handleConsoleChat, handleSurfaceUpdate,} from "./handlers"; import {Queue} from "../queue/queue"; import {isEventType} from "./eventTypeCheck"; import {Converters} from "./converters"; import KafkatorioSettings from "../settings/KafkatorioSettings"; +import {handleChunkGeneratedEvent} from "./onMapChunkEventListeners"; -script.on_event( - defines.events.on_player_mined_entity, - (e: OnPlayerMinedEntityEvent) => { - let eventName = Converters.eventNameString(e.name) - // handlePlayerUpdate(e.tick, eventName, e.player_index) - handleEntityUpdate(e.tick, eventName, e.entity) - } -) +// script.on_event( +// defines.events.on_player_mined_entity, +// (e: OnPlayerMinedEntityEvent) => { +// let eventName = Converters.eventNameString(e.name) +// // handlePlayerUpdate(e.tick, eventName, e.player_index) +// handleEntityUpdate(e.tick, eventName, e.entity) +// } +// ) // script.on_event( // defines.events.on_player_joined_game, @@ -47,22 +43,24 @@ script.on_event( // } } - // if (e.tick % 30 == 0) { - // let events: EventData[] = Queue.dequeueValues(1) - // - // if (events.length > 0) { - // log(`[${e.tick}] dequed ${events.length} events, current size: ${Queue.size()}`) - // - // for (const event of events) { - // if (isEventType(event, defines.events.on_chunk_generated)) { - // let eName = Converters.eventNameString(event.name) - // - // log(`[${e.tick}] dequed event ${eName}`) - // handleChunkUpdate(e.tick, eName, event.surface.index, event.position, event.area) - // } - // } - // } - // } + if (e.tick % 7 == 0) { + const events: EventData[] = Queue.dequeueValues(1) + + if (events.length > 0) { + log(`[${e.tick}] dequed ${events.length} events, current size: ${Queue.size()}`) + + let i = 100 + for (const event of events) { + if (isEventType(event, defines.events.on_chunk_generated)) { + let eName = Converters.eventNameString(event.name) + + log(`[${e.tick}] dequed event ${eName}`) + handleChunkGeneratedEvent(event, i) + i += 10 + } + } + } + } } ) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt index e4b45db..b146158 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt @@ -35,12 +35,12 @@ sealed class FactorioObjectData { // } enum class ObjectName { - LuaPlayer, - LuaEntity, +// LuaPlayer, +// LuaEntity, LuaSurface, - MapChunk, +// MapChunk, // LuaTile, - LuaTiles, +// LuaTiles, ConsoleChatMessage, ; @@ -69,60 +69,60 @@ object FactorioObjectDataJsonSerializer : JsonContentPolymorphicSerializer PlayerData.serializer() - FactorioObjectData.ObjectName.LuaEntity -> EntityData.serializer() +// FactorioObjectData.ObjectName.LuaPlayer -> PlayerData.serializer() +// FactorioObjectData.ObjectName.LuaEntity -> EntityData.serializer() FactorioObjectData.ObjectName.LuaSurface -> SurfaceData.serializer() - FactorioObjectData.ObjectName.MapChunk -> MapChunk.serializer() +// FactorioObjectData.ObjectName.MapChunk -> MapChunk.serializer() // FactorioObjectData.ObjectName.LuaTile -> MapTile.serializer() - FactorioObjectData.ObjectName.LuaTiles -> MapTiles.serializer() +// FactorioObjectData.ObjectName.LuaTiles -> MapTiles.serializer() FactorioObjectData.ObjectName.ConsoleChatMessage -> ConsoleChatMessage.serializer() } } } -/** [`LuaControl`](https://lua-api.factorio.com/latest/LuaControl.html) */ -interface FactorioLuaControl { - val position: MapEntityPosition - val surface: SurfaceIndex - val force: ForceIndex -} +///** [`LuaControl`](https://lua-api.factorio.com/latest/LuaControl.html) */ +//interface FactorioLuaControl { +// val position: MapEntityPosition +// val surface: SurfaceIndex +// val force: ForceIndex +//} -@Serializable -data class PlayerData( - override val force: ForceIndex, - override val position: MapEntityPosition, - override val surface: SurfaceIndex, - @Contextual - val associatedCharactersUnitNumbers: List, - val characterUnitNumber: UnitNumber?, - val chatColour: Colour, - val colour: Colour, - val lastOnline: Tick, - val name: String, -) : FactorioObjectData(), FactorioLuaControl { - @EncodeDefault - override val objectName = ObjectName.LuaPlayer -} +//@Serializable +//data class PlayerData( +// override val force: ForceIndex, +// override val position: MapEntityPosition, +// override val surface: SurfaceIndex, +// @Contextual +// val associatedCharactersUnitNumbers: List, +// val characterUnitNumber: UnitNumber?, +// val chatColour: Colour, +// val colour: Colour, +// val lastOnline: Tick, +// val name: String, +//) : FactorioObjectData(), FactorioLuaControl { +// @EncodeDefault +// override val objectName = ObjectName.LuaPlayer +//} -@Serializable -data class EntityData( - override val force: ForceIndex, - override val position: MapEntityPosition, - override val surface: SurfaceIndex, - val active: Boolean, - val health: Double?, - val healthRatio: Double?, - val name: String, - val playerIndex: PlayerIndex? = null, - val type: String, - val unitNumber: UnitNumber? = null, -) : FactorioObjectData(), FactorioLuaControl { - @EncodeDefault - override val objectName = ObjectName.LuaEntity -} +//@Serializable +//data class EntityData( +// override val force: ForceIndex, +// override val position: MapEntityPosition, +// override val surface: SurfaceIndex, +// val active: Boolean, +// val health: Double?, +// val healthRatio: Double?, +// val name: String, +// val playerIndex: PlayerIndex? = null, +// val type: String, +// val unitNumber: UnitNumber? = null, +//) : FactorioObjectData(), FactorioLuaControl { +// @EncodeDefault +// override val objectName = ObjectName.LuaEntity +//} @Serializable @@ -136,16 +136,16 @@ data class SurfaceData( } -/** This isn't a Factorio Lua type, but a helpful collection of Chunk info */ -@Serializable -data class MapChunk( - val tiles: MapTiles, - val position: MapChunkPosition, - val area: MapBoundingBox, -) : FactorioObjectData() { - @EncodeDefault - override val objectName = ObjectName.MapChunk -} +///** This isn't a Factorio Lua type, but a helpful collection of Chunk info */ +//@Serializable +//data class MapChunk( +// val tiles: MapTiles, +// val position: MapChunkPosition, +// val area: MapBoundingBox, +//) : FactorioObjectData() { +// @EncodeDefault +// override val objectName = ObjectName.MapChunk +//} /** This isn't a Factorio Lua type, but a helpful collection of [MapTile]s */ @@ -153,10 +153,12 @@ data class MapChunk( data class MapTiles( val surfaceIndex: SurfaceIndex, val tiles: List, -) : FactorioObjectData() { - @EncodeDefault - override val objectName = ObjectName.LuaTiles -} +) +// : FactorioObjectData() +//{ +// @EncodeDefault +// override val objectName = ObjectName.LuaTiles +//} @Serializable diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt index bd93da6..ce48c8a 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt @@ -8,335 +8,335 @@ import kotlinx.serialization.encodeToString class FactorioEventTest : FunSpec({ - context("Given: json on_player_joined_game") { - - // language=JSON - val json = """ - { - "data": { - "objectName": "LuaPlayer", - "force": 1, - "surface": 1, - "name": "fredthedeadhead", - "characterUnitNumber": 1, - "associatedCharactersUnitNumbers": {}, - "position": { - "x": 30.6, - "y": 84.1 - }, - "colour": { - "red": 0.86, - "green": 0.5, - "blue": 0.12, - "alpha": 0.5 - }, - "chatColour": { - "red": 1, - "green": 0.62, - "blue": 0.25 - }, - "lastOnline": 2287061 - }, - "packetType": "EVENT", - "eventType": "on_player_joined_game", - "modVersion": "0.2.1", - "tick": 2287072 - } - """.trimIndent() - context("When: decoded") { - val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) - - test("Then: parse") { - - val expected = FactorioEvent( - data = PlayerData( - name = "fredthedeadhead", - surface = SurfaceIndex(1u), - force = ForceIndex(1u), - characterUnitNumber = UnitNumber(1u), - associatedCharactersUnitNumbers = emptyList(), - position = MapEntityPosition( - x = 30.6, - y = 84.1, - ), - colour = Colour( - red = 0.86f, - green = 0.5f, - blue = 0.12f, - alpha = 0.5f - ), - chatColour = Colour( - red = 1f, - green = 0.62f, - blue = 0.25f, - alpha = 1f - ), - lastOnline = Tick(2287061u) - ), - eventType = "on_player_joined_game", - modVersion = "0.2.1", - tick = Tick(2287072u) - ) - - actual shouldBe expected - - expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaPlayer - } - - test("Then: expect encode equals json") { - val encoded = jsonMapperKafkatorio.encodeToString(actual) - encoded.shouldEqualJson(json) - } - } - } - - context("Given: json LuaSurface") { - // language=JSON - val json = """ - { - "data": { - "objectName": "LuaSurface", - "name": "nauvis", - "index": 1, - "daytime": 0.745 - }, - "packetType": "EVENT", - "eventType": "on_tick", - "modVersion": "0.2.1", - "tick": 2301240 - } - """.trimIndent() - - context("When: decoded") { - val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) - - test("should equal obj") { - - val expected = FactorioEvent( - data = SurfaceData( - name = "nauvis", - index = SurfaceIndex(1u), - daytime = 0.745 - ), - eventType = "on_tick", - modVersion = "0.2.1", - tick = Tick(2301240u) - ) - - actual shouldBe expected - - expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaSurface - } - - test("Then: expect encode equals json") { - val encoded = jsonMapperKafkatorio.encodeToString(actual) - encoded.shouldEqualJson(json) - } - } - } - - context("Given: LuaEntity on_player_changed_position") { - // language=JSON - val json = """ - { - "data": { - "objectName": "LuaEntity", - "name": "character", - "type": "character", - "active": true, - "health": 250, - "healthRatio": 1, - "surface": 1, - "force": 1, - "unitNumber": 1, - "position": { - "x": 37.5, - "y": 81.1 - } - }, - "packetType": "EVENT", - "eventType": "on_player_changed_position", - "modVersion": "0.2.1", - "tick": 2301231 - } - """.trimIndent() - context("When: decoded") { - val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) - - test("parse") { - - val expected = FactorioEvent( - data = EntityData( - name = "character", - type = "character", - active = true, - health = 250.0, - healthRatio = 1.0, - surface = SurfaceIndex(1u), - unitNumber = UnitNumber(1u), - force = ForceIndex(1u), - playerIndex = null, - position = MapEntityPosition( - x = 37.5, - y = 81.1, - ) - ), - eventType = "on_player_changed_position", - modVersion = "0.2.1", - tick = Tick(2301231u) - ) - - actual shouldBe expected - - expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaEntity - } - - test("Then: expect encode equals json") { - val encoded = jsonMapperKafkatorio.encodeToString(actual) - encoded.shouldEqualJson(json) - } - } - - } - - context("Given: LuaTiles on_player_built_tile") { - // language=JSON - val json = """ - { - "data": { - "objectName": "LuaTiles", - "surfaceIndex": 1, - "tiles": [ - { - "y": 10, - "x": -65, - "proto": "refined-concrete" - }, - { - "y": 11, - "x": -65, - "proto": "red-earth" - }, - { - "y": 10, - "x": -64, - "proto": "blue-cheese" - }, - { - "y": 11, - "x": -64, - "proto": "refined-concrete" - } - ] - }, - "packetType": "EVENT", - "eventType": "on_player_built_tile", - "modVersion": "0.2.2", - "tick": 2429929 - } - """.trimIndent() - context("When: decoded") { - val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) - - test("parse") { - - val expected = FactorioEvent( - data = MapTiles( - surfaceIndex = SurfaceIndex(1u), - tiles = listOf( - MapTile( - proto = PrototypeName("refined-concrete"), - x = -65, - y = 10, - ), - MapTile( - proto = PrototypeName("red-earth"), - x = -65, - y = 11, - ), - MapTile( - proto = PrototypeName("blue-cheese"), - x = -64, - y = 10, - ), - MapTile( - proto = PrototypeName("refined-concrete"), - x = -64, - y = 11, - ), - ) - ), - eventType = "on_player_built_tile", - modVersion = "0.2.2", - tick = Tick(2429929u) - ) - - actual shouldBe expected - - expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaTiles - } - - test("Then: expect encode equals json") { - val encoded = jsonMapperKafkatorio.encodeToString(actual) - encoded.shouldEqualJson(json) - } - } - } - - context("Given: packet FactorioConfigurationUpdate") { - // language=JSON - val json = """ - { - "modVersion": "0.2.8", - "packetType": "CONFIG", - "tick": 534, - "allMods": [ - { - "modName": "kafkatorio-events", - "currentVersion": "0.2.8", - "previousVersion": "0.2.7" - }, - { - "modName": "base", - "currentVersion": "1.1.53" - } - ], - "factorioData": {} - } - """.trimIndent() - context("When: decoded") { - val actual: FactorioConfigurationUpdate = jsonMapperKafkatorio.decodeFromString(json) - - test("parse") { - - val expected = FactorioConfigurationUpdate( - modVersion = "0.2.8", - tick = Tick(534u), - factorioData = FactorioGameDataUpdate(null, null), - allMods = listOf( - FactorioModInfo( - modName = "kafkatorio-events", - currentVersion = "0.2.8", - previousVersion = "0.2.7" - ), - FactorioModInfo( - modName = "base", - currentVersion = "1.1.53", - previousVersion = null - ), - ) - ) - - actual shouldBe expected - - expected.packetType shouldBe KafkatorioPacket.PacketType.CONFIG - } - - test("Then: expect encode equals json") { - val encoded = jsonMapperKafkatorio.encodeToString(actual) - encoded.shouldEqualJson(json) - } - } - - } +// context("Given: json on_player_joined_game") { +// +// // language=JSON +// val json = """ +// { +// "data": { +// "objectName": "LuaPlayer", +// "force": 1, +// "surface": 1, +// "name": "fredthedeadhead", +// "characterUnitNumber": 1, +// "associatedCharactersUnitNumbers": {}, +// "position": { +// "x": 30.6, +// "y": 84.1 +// }, +// "colour": { +// "red": 0.86, +// "green": 0.5, +// "blue": 0.12, +// "alpha": 0.5 +// }, +// "chatColour": { +// "red": 1, +// "green": 0.62, +// "blue": 0.25 +// }, +// "lastOnline": 2287061 +// }, +// "packetType": "EVENT", +// "eventType": "on_player_joined_game", +// "modVersion": "0.2.1", +// "tick": 2287072 +// } +// """.trimIndent() +// context("When: decoded") { +// val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) +// +// test("Then: parse") { +// +// val expected = FactorioEvent( +// data = PlayerData( +// name = "fredthedeadhead", +// surface = SurfaceIndex(1u), +// force = ForceIndex(1u), +// characterUnitNumber = UnitNumber(1u), +// associatedCharactersUnitNumbers = emptyList(), +// position = MapEntityPosition( +// x = 30.6, +// y = 84.1, +// ), +// colour = Colour( +// red = 0.86f, +// green = 0.5f, +// blue = 0.12f, +// alpha = 0.5f +// ), +// chatColour = Colour( +// red = 1f, +// green = 0.62f, +// blue = 0.25f, +// alpha = 1f +// ), +// lastOnline = Tick(2287061u) +// ), +// eventType = "on_player_joined_game", +// modVersion = "0.2.1", +// tick = Tick(2287072u) +// ) +// +// actual shouldBe expected +// +// expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaPlayer +// } +// +// test("Then: expect encode equals json") { +// val encoded = jsonMapperKafkatorio.encodeToString(actual) +// encoded.shouldEqualJson(json) +// } +// } +// } +// +// context("Given: json LuaSurface") { +// // language=JSON +// val json = """ +// { +// "data": { +// "objectName": "LuaSurface", +// "name": "nauvis", +// "index": 1, +// "daytime": 0.745 +// }, +// "packetType": "EVENT", +// "eventType": "on_tick", +// "modVersion": "0.2.1", +// "tick": 2301240 +// } +// """.trimIndent() +// +// context("When: decoded") { +// val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) +// +// test("should equal obj") { +// +// val expected = FactorioEvent( +// data = SurfaceData( +// name = "nauvis", +// index = SurfaceIndex(1u), +// daytime = 0.745 +// ), +// eventType = "on_tick", +// modVersion = "0.2.1", +// tick = Tick(2301240u) +// ) +// +// actual shouldBe expected +// +// expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaSurface +// } +// +// test("Then: expect encode equals json") { +// val encoded = jsonMapperKafkatorio.encodeToString(actual) +// encoded.shouldEqualJson(json) +// } +// } +// } +// +// context("Given: LuaEntity on_player_changed_position") { +// // language=JSON +// val json = """ +// { +// "data": { +// "objectName": "LuaEntity", +// "name": "character", +// "type": "character", +// "active": true, +// "health": 250, +// "healthRatio": 1, +// "surface": 1, +// "force": 1, +// "unitNumber": 1, +// "position": { +// "x": 37.5, +// "y": 81.1 +// } +// }, +// "packetType": "EVENT", +// "eventType": "on_player_changed_position", +// "modVersion": "0.2.1", +// "tick": 2301231 +// } +// """.trimIndent() +// context("When: decoded") { +// val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) +// +// test("parse") { +// +// val expected = FactorioEvent( +// data = EntityData( +// name = "character", +// type = "character", +// active = true, +// health = 250.0, +// healthRatio = 1.0, +// surface = SurfaceIndex(1u), +// unitNumber = UnitNumber(1u), +// force = ForceIndex(1u), +// playerIndex = null, +// position = MapEntityPosition( +// x = 37.5, +// y = 81.1, +// ) +// ), +// eventType = "on_player_changed_position", +// modVersion = "0.2.1", +// tick = Tick(2301231u) +// ) +// +// actual shouldBe expected +// +// expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaEntity +// } +// +// test("Then: expect encode equals json") { +// val encoded = jsonMapperKafkatorio.encodeToString(actual) +// encoded.shouldEqualJson(json) +// } +// } +// +// } +// +// context("Given: LuaTiles on_player_built_tile") { +// // language=JSON +// val json = """ +// { +// "data": { +// "objectName": "LuaTiles", +// "surfaceIndex": 1, +// "tiles": [ +// { +// "y": 10, +// "x": -65, +// "proto": "refined-concrete" +// }, +// { +// "y": 11, +// "x": -65, +// "proto": "red-earth" +// }, +// { +// "y": 10, +// "x": -64, +// "proto": "blue-cheese" +// }, +// { +// "y": 11, +// "x": -64, +// "proto": "refined-concrete" +// } +// ] +// }, +// "packetType": "EVENT", +// "eventType": "on_player_built_tile", +// "modVersion": "0.2.2", +// "tick": 2429929 +// } +// """.trimIndent() +// context("When: decoded") { +// val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) +// +// test("parse") { +// +// val expected = FactorioEvent( +// data = MapTiles( +// surfaceIndex = SurfaceIndex(1u), +// tiles = listOf( +// MapTile( +// proto = PrototypeName("refined-concrete"), +// x = -65, +// y = 10, +// ), +// MapTile( +// proto = PrototypeName("red-earth"), +// x = -65, +// y = 11, +// ), +// MapTile( +// proto = PrototypeName("blue-cheese"), +// x = -64, +// y = 10, +// ), +// MapTile( +// proto = PrototypeName("refined-concrete"), +// x = -64, +// y = 11, +// ), +// ) +// ), +// eventType = "on_player_built_tile", +// modVersion = "0.2.2", +// tick = Tick(2429929u) +// ) +// +// actual shouldBe expected +// +// expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaTiles +// } +// +// test("Then: expect encode equals json") { +// val encoded = jsonMapperKafkatorio.encodeToString(actual) +// encoded.shouldEqualJson(json) +// } +// } +// } +// +// context("Given: packet FactorioConfigurationUpdate") { +// // language=JSON +// val json = """ +// { +// "modVersion": "0.2.8", +// "packetType": "CONFIG", +// "tick": 534, +// "allMods": [ +// { +// "modName": "kafkatorio-events", +// "currentVersion": "0.2.8", +// "previousVersion": "0.2.7" +// }, +// { +// "modName": "base", +// "currentVersion": "1.1.53" +// } +// ], +// "factorioData": {} +// } +// """.trimIndent() +// context("When: decoded") { +// val actual: FactorioConfigurationUpdate = jsonMapperKafkatorio.decodeFromString(json) +// +// test("parse") { +// +// val expected = FactorioConfigurationUpdate( +// modVersion = "0.2.8", +// tick = Tick(534u), +// factorioData = FactorioGameDataUpdate(null, null), +// allMods = listOf( +// FactorioModInfo( +// modName = "kafkatorio-events", +// currentVersion = "0.2.8", +// previousVersion = "0.2.7" +// ), +// FactorioModInfo( +// modName = "base", +// currentVersion = "1.1.53", +// previousVersion = null +// ), +// ) +// ) +// +// actual shouldBe expected +// +// expected.packetType shouldBe KafkatorioPacket.PacketType.CONFIG +// } +// +// test("Then: expect encode equals json") { +// val encoded = jsonMapperKafkatorio.encodeToString(actual) +// encoded.shouldEqualJson(json) +// } +// } +// +// } }) From f26f4286e93cb699cf8207771b23df58dada388e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 14 Mar 2022 22:19:58 +0100 Subject: [PATCH 259/629] remove extraneous word from mod setting titles --- .../src/main/resources/mod-data/locale/en/locale.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg b/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg index 0fa9177..c8622fd 100644 --- a/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg +++ b/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg @@ -1,8 +1,8 @@ [mod-setting-name] -kafkatorio_event-cache_default-expiration-duration-seconds_PLAYER=Kafkatorio: Player update rate (seconds) -kafkatorio_event-cache_default-expiration-duration-seconds_MAP_CHUNK=Kafkatorio: Map update rate (seconds) -kafkatorio_event-cache_default-expiration-duration-seconds_ENTITY=Kafkatorio: Entity update rate (seconds) +kafkatorio_event-cache_default-expiration-duration-seconds_PLAYER=Player update rate (seconds) +kafkatorio_event-cache_default-expiration-duration-seconds_MAP_CHUNK=Map update rate (seconds) +kafkatorio_event-cache_default-expiration-duration-seconds_ENTITY=Entity update rate (seconds) [mod-setting-description] From f1d15085e627c5f0a7c73061065cf563170c67a5 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 14 Mar 2022 22:20:39 +0100 Subject: [PATCH 260/629] reduce log output when saving tiles --- .../dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt index cab13f7..6f5a524 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt @@ -161,7 +161,9 @@ private class ServerMapChunkHandler : CoroutineScope { } val savedTile = img.output(PngWriter.NoCompression, chunkImageFile) - println("savedTile: $savedTile") + if (filename.value.contains("z-1")) { + println("savedTile: $savedTile") + } } .launchIn(this) From 9e55a3388276fb867d234fe25c965ab84f95ebcc Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 14 Mar 2022 22:21:17 +0100 Subject: [PATCH 261/629] disable max.task.idle.ms setting (I don't know what it's supposed to do, and setting it high causes OOM) --- .../dev/adamko/kafkatorio/processor/KafkatorioTopology.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 1fcd511..fbe99ee 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -81,7 +81,7 @@ internal class KafkatorioTopology( val appId = props.compute(StreamsConfig.APPLICATION_ID_CONFIG) { _, v -> "$v.$id" } as? String props.setProperty(StreamsConfig.APPLICATION_ID_CONFIG, appId) - props.setProperty(StreamsConfig.MAX_TASK_IDLE_MS_CONFIG, "${1.minutes.inWholeMilliseconds}") +// props.setProperty(StreamsConfig.MAX_TASK_IDLE_MS_CONFIG, "${30.minutes.inWholeMilliseconds}") val streams = KafkaStreams(topology, props) streams.setUncaughtExceptionHandler(StreamsExceptionHandler { From 303734daaa2eb4f151eb02bde81f55e7258f499f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 14 Mar 2022 22:22:03 +0100 Subject: [PATCH 262/629] default zoom, reduce by one --- .../src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt | 5 +---- .../src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt | 7 +++++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index 21ee00b..bd3717e 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -25,8 +25,7 @@ fun createFactorioMap() = Maps { margin = 10.px configureLeafletMap { - setView(LatLng(0, 0), 1) - + setView(center = LatLng(0, 0), zoom = 0) L.tileLayer( """http://localhost:9073/tiles/s1/z{z}/x{x}/y{y}.png""" @@ -38,10 +37,8 @@ fun createFactorioMap() = Maps { minZoom = -2 maxZoom = 6 - // NOTE: offset the zoom, so 1 meter = 1 tile maxNativeZoom = 3 minNativeZoom = -1 -// zoomOffset = 1 noWrap = true updateWhenIdle = false diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt index 041eff0..451c401 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt @@ -99,7 +99,10 @@ class PlayerState( val name = update.name ?: playerDetails.name return when { - position != null && surfaceIndex != null && colour != null && name != null -> + position != null + && surfaceIndex != null + && colour != null + && name != null -> PlayerDetailsState.Known( index = playerDetails.index, position = position, @@ -108,7 +111,7 @@ class PlayerState( name = name, ) - else -> + else -> PlayerDetailsState.Unknown( index = playerDetails.index, position = position, From db14865ca958e1629078591cf96c73c36698fa64 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 16 Mar 2022 23:27:37 +0100 Subject: [PATCH 263/629] start simplifying schema packets --- .../events/schema/factorioCommonData.kt | 7 + .../events/schema/factorioConfiguration.kt | 29 --- .../events/schema/factorioEventUpdates.kt | 190 +++++++++++++----- .../events/schema/factorioEvents.kt | 17 -- .../events/schema/factorioLuaObjects.kt | 171 ---------------- .../events/schema/factorioPrototypes.kt | 10 - .../adamko/kafkatorio/events/schema/json.kt | 26 +-- .../events/schema/kafkatorioPacket.kt | 59 ------ 8 files changed, 152 insertions(+), 357 deletions(-) delete mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt delete mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt delete mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt delete mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt index fb91302..4181a05 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt @@ -87,6 +87,13 @@ data class ColourHex( } +@Serializable +data class MapTiles( + val surfaceIndex: SurfaceIndex, + val tiles: List, +) + + @Serializable data class MapTile( val x: Int, diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt deleted file mode 100644 index 37aa57f..0000000 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioConfiguration.kt +++ /dev/null @@ -1,29 +0,0 @@ -package dev.adamko.kafkatorio.events.schema - -import kotlinx.serialization.EncodeDefault -import kotlinx.serialization.Serializable - - -@Serializable -data class FactorioConfigurationUpdate( - override val modVersion: String, - override val tick: Tick, - val factorioData: FactorioGameDataUpdate, - val allMods: List, -) : KafkatorioPacket() { - @EncodeDefault - override val packetType = PacketType.CONFIG -} - -@Serializable -data class FactorioGameDataUpdate( - val oldVersion: String? = null, - val newVersion: String? = null, -) - -@Serializable -data class FactorioModInfo( - val modName: String, - val currentVersion: String? = null, - val previousVersion: String? = null, -) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt index 2e7441d..dbfbc21 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt @@ -1,7 +1,6 @@ package dev.adamko.kafkatorio.events.schema -import dev.adamko.kafkatorio.events.schema.FactorioEventUpdate.FactorioEventUpdateType -import kotlinx.serialization.Contextual +import dev.adamko.kafkatorio.events.schema.FactorioUpdateData.FactorioUpdateDataType import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.EncodeDefault import kotlinx.serialization.Serializable @@ -13,71 +12,77 @@ import kotlinx.serialization.json.jsonPrimitive @Serializable -data class FactorioEventUpdatePacket( - override val modVersion: String, - override val tick: Tick, - val update: FactorioEventUpdate, -) : KafkatorioPacket() { - @EncodeDefault - override val packetType: PacketType = PacketType.UPDATE +sealed class KafkatorioPacket { + /** Schema versioning */ + abstract val modVersion: String + abstract val tick: Tick + abstract val update: FactorioUpdateData } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -sealed interface FactorioEventUpdateKey { - val updateType: FactorioEventUpdateType +sealed interface FactorioUpdateDataKey { + val updateType: FactorioUpdateDataType } -@Serializable(with = FactorioEventUpdate.Companion.JsonSerializer::class) -sealed class FactorioEventUpdate : FactorioEventUpdateKey { +@Serializable(with = FactorioUpdateData.JsonSerializer::class) +sealed class FactorioUpdateData : FactorioUpdateDataKey { + /** Discriminator for [FactorioUpdateData] */ @EncodeDefault - abstract override val updateType: FactorioEventUpdateType + abstract override val updateType: FactorioUpdateDataType + /** the initial Factorio event (`defines.events`) trigger */ abstract val eventCounts: Map? @Serializable - enum class FactorioEventUpdateType { + enum class FactorioUpdateDataType { PLAYER, MAP_CHUNK, ENTITY, + CONSOLE_CHAT, + CONSOLE_COMMAND, + SURFACE, + CONFIG, + PROTOTYPES, ; companion object { - val values: List = values().toList() + val values: List = values().toList() } } - companion object { + object JsonSerializer : JsonContentPolymorphicSerializer( + FactorioUpdateData::class + ) { + private val key = FactorioUpdateData::updateType.name - object JsonSerializer : JsonContentPolymorphicSerializer( - FactorioEventUpdate::class - ) { - private val key = FactorioEventUpdate::updateType.name + override fun selectDeserializer(element: JsonElement): DeserializationStrategy { - override fun selectDeserializer(element: JsonElement): DeserializationStrategy { - - val type = element - .jsonObject[key] - ?.jsonPrimitive - ?.contentOrNull - ?.let { json -> - FactorioEventUpdateType.values.firstOrNull { it.name == json } - } - - requireNotNull(type) { "Unknown FactorioEventUpdate $key: $element" } - - return when (type) { - FactorioEventUpdateType.PLAYER -> PlayerUpdate.serializer() - FactorioEventUpdateType.MAP_CHUNK -> MapChunkUpdate.serializer() - FactorioEventUpdateType.ENTITY -> EntityUpdate.serializer() + val type = element + .jsonObject[key] + ?.jsonPrimitive + ?.contentOrNull + ?.let { json -> + FactorioUpdateDataType.values.firstOrNull { it.name == json } } + + requireNotNull(type) { "Unknown FactorioEventUpdate $key: $element" } + + return when (type) { + FactorioUpdateDataType.PLAYER -> PlayerUpdate.serializer() + FactorioUpdateDataType.MAP_CHUNK -> MapChunkUpdate.serializer() + FactorioUpdateDataType.ENTITY -> EntityUpdate.serializer() + FactorioUpdateDataType.CONSOLE_CHAT -> ConsoleChatUpdate.serializer() + FactorioUpdateDataType.CONSOLE_COMMAND -> ConsoleCommandUpdate.serializer() + FactorioUpdateDataType.SURFACE -> SurfaceUpdate.serializer() + FactorioUpdateDataType.CONFIG -> ConfigurationUpdate.serializer() + FactorioUpdateDataType.PROTOTYPES -> PrototypesUpdate.serializer() } } - } } @@ -85,7 +90,7 @@ sealed class FactorioEventUpdate : FactorioEventUpdateKey { /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -sealed interface PlayerUpdateKey : FactorioEventUpdateKey { +sealed interface PlayerUpdateKey : FactorioUpdateDataKey { val index: PlayerIndex } @@ -120,16 +125,16 @@ data class PlayerUpdate( val disconnectReason: String? = null, /** `true` when a player is removed (deleted) from the game */ val isRemoved: Boolean? = null, -) : FactorioEventUpdate(), PlayerUpdateKey { +) : FactorioUpdateData(), PlayerUpdateKey { @EncodeDefault - override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.PLAYER + override val updateType: FactorioUpdateDataType = FactorioUpdateDataType.PLAYER } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -sealed interface EntityUpdateKey : EntityIdentifiers, FactorioEventUpdateKey { +sealed interface EntityUpdateKey : EntityIdentifiers, FactorioUpdateDataKey { /** A [unitNumber] is required for caching */ override val unitNumber: UnitNumber override val name: String @@ -154,16 +159,16 @@ data class EntityUpdate( val localisedDescription: String? = null, val localisedName: String? = null, val prototype: PrototypeName? = null, -) : FactorioEventUpdate(), EntityUpdateKey { +) : FactorioUpdateData(), EntityUpdateKey { @EncodeDefault - override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.ENTITY + override val updateType: FactorioUpdateDataType = FactorioUpdateDataType.ENTITY } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -sealed interface MapChunkUpdateKey : FactorioEventUpdateKey { +sealed interface MapChunkUpdateKey : FactorioUpdateDataKey { val chunkPosition: MapChunkPosition val surfaceIndex: SurfaceIndex } @@ -182,9 +187,100 @@ data class MapChunkUpdate( /** updated tiles - might be partial and not all tiles in the chunk */ val tileDictionary: MapTileDictionary? = null, val isDeleted: Boolean? = null, -) : FactorioEventUpdate(), MapChunkUpdateKey { +) : FactorioUpdateData(), MapChunkUpdateKey { @EncodeDefault - override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.MAP_CHUNK + override val updateType: FactorioUpdateDataType = FactorioUpdateDataType.MAP_CHUNK +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +@Serializable +data class ConsoleChatUpdate( + override val eventCounts: Map? = null, + + val authorPlayerIndex: PlayerIndex?, + val content: String, +) : FactorioUpdateData() { + @EncodeDefault + override val updateType: FactorioUpdateDataType = FactorioUpdateDataType.CONSOLE_CHAT + +} + +@Serializable +data class ConsoleCommandUpdate( + override val eventCounts: Map? = null, + + val authorPlayerIndex: PlayerIndex?, + val command: String, + val parameters: String, +) : FactorioUpdateData() { + @EncodeDefault + override val updateType: FactorioUpdateDataType = FactorioUpdateDataType.CONSOLE_COMMAND +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +sealed interface SurfaceUpdateKey : FactorioUpdateDataKey { + val index: SurfaceIndex +} + +@Serializable +data class SurfaceUpdate( + override val index: SurfaceIndex, + + override val eventCounts: Map? = null, + + val daytime: Double, + val name: String, +) : FactorioUpdateData(), SurfaceUpdateKey { + @EncodeDefault + override val updateType: FactorioUpdateDataType = FactorioUpdateDataType.SURFACE +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +@Serializable +data class ConfigurationUpdate( + override val eventCounts: Map? = null, + + val factorioData: GameData, + val allMods: List, +) : FactorioUpdateData() { + @EncodeDefault + override val updateType: FactorioUpdateDataType = FactorioUpdateDataType.CONFIG + + @Serializable + data class GameData( + val oldVersion: String? = null, + val newVersion: String? = null, + ) + + @Serializable + data class ModData( + val modName: String, + val currentVersion: String? = null, + val previousVersion: String? = null, + ) +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +@Serializable +data class PrototypesUpdate( + override val eventCounts: Map? = null, + + val prototypes: List, +) : FactorioUpdateData() { + @EncodeDefault + override val updateType: FactorioUpdateDataType = FactorioUpdateDataType.PROTOTYPES } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt deleted file mode 100644 index 177bf21..0000000 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEvents.kt +++ /dev/null @@ -1,17 +0,0 @@ -package dev.adamko.kafkatorio.events.schema - - -import kotlinx.serialization.EncodeDefault -import kotlinx.serialization.Serializable - -@Serializable -data class FactorioEvent( - override val modVersion: String, - override val tick: Tick, - /** the initial Factorio event (`defines.events`) trigger */ - val eventType: String, - val data: FactorioObjectData, -) : KafkatorioPacket() { - @EncodeDefault - override val packetType: PacketType = PacketType.EVENT -} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt deleted file mode 100644 index b146158..0000000 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioLuaObjects.kt +++ /dev/null @@ -1,171 +0,0 @@ -package dev.adamko.kafkatorio.events.schema - -import kotlinx.serialization.Contextual -import kotlinx.serialization.DeserializationStrategy -import kotlinx.serialization.EncodeDefault -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.JsonContentPolymorphicSerializer -import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.contentOrNull -import kotlinx.serialization.json.jsonObject -import kotlinx.serialization.json.jsonPrimitive - - -@Serializable(with = FactorioObjectDataJsonSerializer::class) -sealed class FactorioObjectData { - - @EncodeDefault - abstract val objectName: ObjectName - - // workaround - https://github.com/Kotlin/kotlinx.serialization/issues/1664 -// val objectName: String by lazy { -// serializer().descriptor.serialName -// } - -// val objectName: String by lazy { -// kotlinx.serialization.serializer(this::class.starProjectedType).descriptor.serialName -// } - - // alternative: find the @SerialName annotation - // Again it must be delegated so there's no backing field and kxs ignores it -// val objectName: String by lazy { -// requireNotNull(this::class.findAnnotation()?.value) { -// "Couldn't find @SerialName for ${this::class}!" -// } -// } - - enum class ObjectName { -// LuaPlayer, -// LuaEntity, - LuaSurface, -// MapChunk, - // LuaTile, -// LuaTiles, - ConsoleChatMessage, - ; - - companion object { - val values: List = values().toList() - } - } -} - - -object FactorioObjectDataJsonSerializer : JsonContentPolymorphicSerializer( - FactorioObjectData::class -) { - private val key = FactorioObjectData::objectName.name - - override fun selectDeserializer(element: JsonElement): DeserializationStrategy { - - val type = element - .jsonObject[key] - ?.jsonPrimitive - ?.contentOrNull - ?.let { json -> - FactorioObjectData.ObjectName.values.firstOrNull { it.name == json } - } - - requireNotNull(type) { "Unknown FactorioObjectData $key: $element" } - - return when (type) { -// FactorioObjectData.ObjectName.LuaPlayer -> PlayerData.serializer() -// FactorioObjectData.ObjectName.LuaEntity -> EntityData.serializer() - FactorioObjectData.ObjectName.LuaSurface -> SurfaceData.serializer() -// FactorioObjectData.ObjectName.MapChunk -> MapChunk.serializer() -// FactorioObjectData.ObjectName.LuaTile -> MapTile.serializer() -// FactorioObjectData.ObjectName.LuaTiles -> MapTiles.serializer() - FactorioObjectData.ObjectName.ConsoleChatMessage -> ConsoleChatMessage.serializer() - } - } -} - - -///** [`LuaControl`](https://lua-api.factorio.com/latest/LuaControl.html) */ -//interface FactorioLuaControl { -// val position: MapEntityPosition -// val surface: SurfaceIndex -// val force: ForceIndex -//} - - -//@Serializable -//data class PlayerData( -// override val force: ForceIndex, -// override val position: MapEntityPosition, -// override val surface: SurfaceIndex, -// @Contextual -// val associatedCharactersUnitNumbers: List, -// val characterUnitNumber: UnitNumber?, -// val chatColour: Colour, -// val colour: Colour, -// val lastOnline: Tick, -// val name: String, -//) : FactorioObjectData(), FactorioLuaControl { -// @EncodeDefault -// override val objectName = ObjectName.LuaPlayer -//} - - -//@Serializable -//data class EntityData( -// override val force: ForceIndex, -// override val position: MapEntityPosition, -// override val surface: SurfaceIndex, -// val active: Boolean, -// val health: Double?, -// val healthRatio: Double?, -// val name: String, -// val playerIndex: PlayerIndex? = null, -// val type: String, -// val unitNumber: UnitNumber? = null, -//) : FactorioObjectData(), FactorioLuaControl { -// @EncodeDefault -// override val objectName = ObjectName.LuaEntity -//} - - -@Serializable -data class SurfaceData( - val daytime: Double, - val index: SurfaceIndex, - val name: String, -) : FactorioObjectData() { - @EncodeDefault - override val objectName = ObjectName.LuaSurface -} - - -///** This isn't a Factorio Lua type, but a helpful collection of Chunk info */ -//@Serializable -//data class MapChunk( -// val tiles: MapTiles, -// val position: MapChunkPosition, -// val area: MapBoundingBox, -//) : FactorioObjectData() { -// @EncodeDefault -// override val objectName = ObjectName.MapChunk -//} - - -/** This isn't a Factorio Lua type, but a helpful collection of [MapTile]s */ -@Serializable -data class MapTiles( - val surfaceIndex: SurfaceIndex, - val tiles: List, -) -// : FactorioObjectData() -//{ -// @EncodeDefault -// override val objectName = ObjectName.LuaTiles -//} - - -@Serializable -data class ConsoleChatMessage( - val authorPlayerIndex: PlayerIndex?, - val content: String, -) : FactorioObjectData() { - @EncodeDefault - override val objectName = ObjectName.ConsoleChatMessage -} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt index 16593ca..063cbbd 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt @@ -12,16 +12,6 @@ import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive -@Serializable -data class FactorioPrototypes( - override val modVersion: String, - override val tick: Tick, - val prototypes: List, -) : KafkatorioPacket() { - @EncodeDefault - override val packetType = PacketType.PROTOTYPES -} - @Serializable(with = FactorioPrototypeJsonSerializer::class) sealed class FactorioPrototype { diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt index 0c4642e..93af18d 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt @@ -10,6 +10,7 @@ import kotlinx.serialization.json.JsonTransformingSerializer import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.modules.SerializersModule + val jsonMapperKafkatorio = Json { prettyPrint = true prettyPrintIndent = " " @@ -23,7 +24,7 @@ val jsonMapperKafkatorio = Json { /** * Factorio outputs an *empty* list as an *empty* Json object. This serde performs the same - * conversion + * conversion. */ class FactorioJsonListSerializer(dataSerializer: KSerializer) : JsonTransformingSerializer>(ListSerializer(dataSerializer)) { @@ -43,26 +44,3 @@ class FactorioJsonListSerializer(dataSerializer: KSerializer) : } } - -//internal class FactorioListSerializer( -// private val tSerializer: KSerializer -//) : KSerializer> { -// -// override val descriptor: SerialDescriptor get() = tSerializer.descriptor -// private val tListSerializer = ListSerializer(tSerializer) -// private val jsonTransformer = FactorioJsonListSerializer(tSerializer) -// -// override fun serialize(encoder: Encoder, value: List) { -// when (encoder) { -// is JsonEncoder -> jsonTransformer.serialize(encoder, value) -// else -> tListSerializer.serialize(encoder, value) -// } -// } -// -// override fun deserialize(decoder: Decoder): List { -// return when (decoder) { -// is JsonDecoder -> jsonTransformer.deserialize(decoder) -// else -> tListSerializer.deserialize(decoder) -// } -// } -//} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt deleted file mode 100644 index e562dfa..0000000 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/kafkatorioPacket.kt +++ /dev/null @@ -1,59 +0,0 @@ -package dev.adamko.kafkatorio.events.schema; - -import kotlinx.serialization.DeserializationStrategy -import kotlinx.serialization.EncodeDefault -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.JsonContentPolymorphicSerializer -import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.contentOrNull -import kotlinx.serialization.json.jsonObject -import kotlinx.serialization.json.jsonPrimitive - - -@Serializable(with = KafkatorioPacketJsonSerializer::class) -sealed class KafkatorioPacket { - /** Schema versioning */ - abstract val modVersion: String - abstract val tick: Tick - @EncodeDefault - abstract val packetType: PacketType - - enum class PacketType { - EVENT, - CONFIG, - PROTOTYPES, - UPDATE, - ; - - companion object { - val values: List = values().toList() - } - } -} - - -object KafkatorioPacketJsonSerializer : JsonContentPolymorphicSerializer( - KafkatorioPacket::class -) { - private val key = KafkatorioPacket::packetType.name - - override fun selectDeserializer(element: JsonElement): DeserializationStrategy { - - val type: KafkatorioPacket.PacketType? = element - .jsonObject[key] - ?.jsonPrimitive - ?.contentOrNull - ?.let { json -> - KafkatorioPacket.PacketType.values.firstOrNull { it.name == json } - } - - requireNotNull(type) { "Unknown KafkatorioPacket ${key}: $element" } - - return when (type) { - KafkatorioPacket.PacketType.EVENT -> FactorioEvent.serializer() - KafkatorioPacket.PacketType.CONFIG -> FactorioConfigurationUpdate.serializer() - KafkatorioPacket.PacketType.PROTOTYPES -> FactorioPrototypes.serializer() - KafkatorioPacket.PacketType.UPDATE -> FactorioEventUpdatePacket.serializer() - } - } -} From 3fff57d46dd37d1e52264d51f85ee7270518bfd3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 19 Apr 2022 23:25:10 +0200 Subject: [PATCH 264/629] biggest refactor ever... - use kxs-ts-gen for TypeScript schemas - update schema files, so they're tidier (no need for typescript-generator workarounds) - version bumps (kotlin, gradle, tstl, factorio, kotest) - improve kxs binary format (use okio) - move schema files package ('events' wasn't needed) - tidy up topic creation, naming. base it off classes, make util functions --- .gitignore | 1 + build.gradle.kts | 13 +- buildSrc/build.gradle.kts | 4 +- buildSrc/repositories.settings.gradle.kts | 16 + .../kotlin/dev/adamko/kafkatorio/common.kt | 6 +- .../kafkatorio/lang/kotlin-jvm.gradle.kts | 1 - gradle.properties | 4 +- gradle/libs.versions.toml | 17 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../kafkatorio-schema/config-update.d.ts | 20 - .../kafkatorio-schema/kafkatorio-schema.ts | 217 +++++++++++ .../kafkatorio-schema/object-data.d.ts | 20 - .../kafkatorio-schema/prototype.d.ts | 24 -- .../generated/kafkatorio-schema/schema.d.ts | 51 --- .../generated/kafkatorio-schema/update.d.ts | 90 ----- .../src/main/typescript/main/PacketEmitter.ts | 41 +++ .../typescript/main/cache/EventDataCache.ts | 183 ++++++---- .../typescript/main/cache/cacheChecker.ts | 15 +- .../handleConfigurationUpdate.ts | 28 +- .../main/config-update/prototypes.ts | 31 +- .../typescript/main/emitKafkatorioPacket.ts | 6 - .../main/typescript/main/events/converters.ts | 18 +- .../main/typescript/main/events/emitEvent.ts | 12 - .../main/typescript/main/events/handlers.ts | 28 +- .../main/events/onConsoleEventHandlers.ts | 31 ++ .../main/events/onMapChunkEventListeners.ts | 119 +++--- .../main/events/onPlayerEventListeners.ts | 21 +- .../main/events/registerHandlers.ts | 24 +- .../main/settings/KafkatorioSettings.ts | 60 +-- .../src/main/typescript/main/types.d.ts | 9 + .../src/main/typescript/package-lock.json | 32 +- .../src/main/typescript/package.json | 22 +- modules/events-schema/build.gradle.kts | 18 +- .../events/schema/converters/positions.kt | 57 --- .../events/schema/factorioCommonData.kt | 158 -------- .../events/schema/factorioEventUpdates.kt | 287 --------------- .../colour.kt => schema/common/colours.kt} | 38 +- .../schema => schema/common}/factorioIds.kt | 24 +- .../kafkatorio/schema/common/mapTile.kt | 75 ++++ .../kafkatorio/schema/common/positions.kt | 142 ++++++++ .../schema/events/kafkatorioPacket.kt | 68 ++++ .../schema/events/kafkatorioPacketInstant.kt | 95 +++++ .../schema/events/kafkatorioPacketKeyed.kt | 135 +++++++ .../kafkatorio/{events => }/schema/json.kt | 33 +- .../prototypes}/factorioPrototypes.kt | 49 +-- .../schema/prototypes/factorioPrototypes2.kt | 23 ++ .../kafkatorio/schema2/kafkatorioPacket2.kt | 16 + .../schema2/kafkatorioPacketInstant2.kt | 70 ++++ .../schema2/kafkatorioPacketKeyed2.kt | 126 +++++++ .../kafkatorio/events/schema/ColourHexTest.kt | 9 +- .../events/schema/FactorioEventTest.kt | 342 ------------------ .../events/schema/MapChunkUpdateTest.kt | 93 +++++ .../schema/common/MapTileDictionaryTest.kt | 42 +++ .../adamko/kafkatorio/events/schema/kt2ts.kt | 129 ++++--- .../adamko/kafkatorio/events/schema/kt2ts2.kt | 55 +++ modules/events-server/build.gradle.kts | 3 + .../processor/KafkatorioTopology.kt | 23 +- .../processor/StreamsExceptionHandler.kt | 1 + .../processor/admin/KafkatorioKafkaAdmin.kt | 48 +-- .../processor/admin/kafkatorioTopics.kt | 104 ++++++ .../kafkatorio/processor/serdes/kxsBinary.kt | 67 ++-- .../kafkatorio/processor/serdes/kxsJson.kt | 22 +- .../topology/factorioServerPackets.kt | 40 +- .../processor/topology/flowMapTiles.kt | 126 +++---- .../processor/topology/groupMapChunks.kt | 236 ++++++------ .../kafkatorio/processor/topology/model.kt | 8 +- .../processor/topology/packetDataStreams.kt | 27 ++ .../processor/topology/playerUpdates.kt | 16 +- .../processor/topology/prototypes.kt | 86 +++-- .../processor/misc/KxsBinaryTests.kt | 252 ++++++++++++- .../kafkatorio/processor/misc/serdeSize.kt | 5 +- .../processor/topology/GroupMapChunksTest.kt | 62 ++-- modules/infra-factorio-server/src/.env | 4 +- modules/infra-kafka-cluster/src/.env | 2 +- .../src/kafka-server.properties | 3 + modules/infra-kafka-pipe/src/.env | 2 +- .../infra-kafka-pipe/src/docker-compose.yml | 2 +- modules/infra-kafka-pipe/src/kafka-pipe.sh | 2 +- .../adamko/kafkatorio/webmap/converters.kt | 4 +- .../dev/adamko/kafkatorio/webmap/json.kt | 2 +- .../dev/adamko/kafkatorio/webmap/state.kt | 18 +- .../adamko/kafkatorio/webmap/websockets.kt | 44 ++- 82 files changed, 2545 insertions(+), 1914 deletions(-) delete mode 100644 modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts create mode 100644 modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts delete mode 100644 modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts delete mode 100644 modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts delete mode 100644 modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts delete mode 100644 modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts create mode 100644 modules/events-mod/src/main/typescript/main/PacketEmitter.ts delete mode 100644 modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts delete mode 100644 modules/events-mod/src/main/typescript/main/events/emitEvent.ts create mode 100644 modules/events-mod/src/main/typescript/main/events/onConsoleEventHandlers.ts delete mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/positions.kt delete mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt delete mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt rename modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/{events/schema/converters/colour.kt => schema/common/colours.kt} (68%) rename modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/{events/schema => schema/common}/factorioIds.kt (65%) create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacket.kt create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketInstant.kt create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketKeyed.kt rename modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/{events => }/schema/json.kt (57%) rename modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/{events/schema => schema/prototypes}/factorioPrototypes.kt (50%) create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes2.kt create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacket2.kt create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketInstant2.kt create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketKeyed2.kt delete mode 100644 modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt create mode 100644 modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt create mode 100644 modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt create mode 100644 modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt diff --git a/.gitignore b/.gitignore index 57dfac2..9982af0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .secret.* .idea +!.idea/icon.svg node_modules diff --git a/build.gradle.kts b/build.gradle.kts index bf22bd1..9439362 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.3.2" +version = "0.4.0" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) @@ -35,7 +35,7 @@ idea { } tasks.wrapper { - gradleVersion = "7.4.1" + gradleVersion = "7.4.2" distributionType = Wrapper.DistributionType.ALL } @@ -57,3 +57,12 @@ val runKafkatorio by tasks.registering { ":modules:infra-factorio-server:processRestart", ) } + + +val runEventsServer by tasks.registering { + group = project.name + + dependsOn( + ":modules:events-server:run", + ) +} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 6f37f3b..3764e2b 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -12,7 +12,7 @@ object Versions { const val jvmTarget = "11" const val kotlinTarget = "1.6" - const val kotlin = "1.6.10" + const val kotlin = "1.6.20" const val gradleNodePlugin = "3.2.1" const val gradleDockerComposePlugin = "0.15.1" @@ -22,7 +22,7 @@ object Versions { const val semver = "1.1.2" const val http4k = "4.19.1.0" - const val kotest = "5.1.0" + const val kotest = "5.2.3" } diff --git a/buildSrc/repositories.settings.gradle.kts b/buildSrc/repositories.settings.gradle.kts index a9c0f1e..8e5cd0e 100644 --- a/buildSrc/repositories.settings.gradle.kts +++ b/buildSrc/repositories.settings.gradle.kts @@ -10,6 +10,7 @@ dependencyResolutionManagement { // repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) repositories { + myMavenLocal() mavenCentral() jitpack() gradlePluginPortal() @@ -31,6 +32,7 @@ dependencyResolutionManagement { pluginManagement { repositories { + myMavenLocal() gradlePluginPortal() mavenCentral() jitpack() @@ -39,6 +41,20 @@ dependencyResolutionManagement { } + fun RepositoryHandler.jitpack() { maven("https://jitpack.io") } + + +fun RepositoryHandler.myMavenLocal(enabled: Boolean = true) { + if (enabled) { + logger.lifecycle("Maven local is enabled") + mavenLocal { + content { + includeGroup("dev.adamko") + includeGroup("dev.adamko.kxtsgen") + } + } + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt index 63aa77a..d443846 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt @@ -16,11 +16,11 @@ object Versions { const val kotlinLang = "1.6" const val jvmTarget = "11" - const val node = "14.19.0" + const val node = "14.19.1" - const val kotlinWrappers = "0.0.1-pre.300-kotlin-1.6.10" + const val kotlinWrappers = "0.0.1-pre.330-kotlin-1.6.20" const val junit = "5.8.2" - const val kotest = "5.1.0" + const val kotest = "5.2.3" const val mockk = "1.12.1" } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index 02cee18..a888607 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -47,7 +47,6 @@ tasks.withType().configureEach { "-opt-in=kotlin.RequiresOptIn", "-opt-in=kotlin.ExperimentalStdlibApi", "-opt-in=kotlin.time.ExperimentalTime", -// "-Xextended-compiler-checks", // "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", // "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", ) diff --git a/gradle.properties b/gradle.properties index d609dd0..a46318c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ kotlin.js.compiler=ir kotlin.mpp.stability.nowarn=true -kotlin.mpp.enableGranularSourceSetsMetadata=true -kotlin.native.enableDependencyPropagation=false +#kotlin.mpp.enableGranularSourceSetsMetadata=true +#kotlin.native.enableDependencyPropagation=false org.gradle.dependency.verification.console=verbose diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index aeafacf..f51d3e2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ ## compilation ## jvm = "11" -kotlin = "1.6.10" +kotlin = "1.6.20" ## libs ## camel-kafkaConnectors = "0.11.0" @@ -17,13 +17,14 @@ kvision = "5.8.2" log4j2 = "2.17.2" qosLogback = "1.2.11" slf4j = "1.7.36" +okio = "3.1.0" ## test ## junit = "5.8.2" -kotest = "5.1.0" +kotest = "5.2.3" ## infra ## -factorio = "1.1.53" +factorio = "1.1.57" confluent-kafkaConnect = "7.0.1" ######### @@ -53,9 +54,9 @@ kotlinx-serialization-protobuf = { group = "org.jetbrains.kotlinx", name = "kotl kotlinx-serialization-yaml = { group = "com.charleskorn.kaml", name = "kaml", version = "0.37.0" } -kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.6.0" } +kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.6.1" } -kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.7.3" } +kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.7.5" } kotlinx-nodejs = { group = "org.jetbrains.kotlinx", name = "kotlinx-nodejs", version = "0.0.7" } @@ -103,6 +104,12 @@ skrapeit = { group = "it.skrape", name = "skrapeit", version = "1.2.0" } scrimage-core = { group = "com.sksamuel.scrimage", name = "scrimage-core", version = "4.0.31" } + +## okio ## +okio-bom = { group = "com.squareup.okio", name = "okio-bom", version.ref = "okio" } +okio-core = { group = "com.squareup.okio", name = "okio" } + + ############# ### test ### ############# diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d7e66b5..92f06b5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts deleted file mode 100644 index 6fa06d0..0000000 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/config-update.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -// Generated by TypeScriptGenerator - do not edit this file manually - -interface FactorioModInfo { - currentVersion: string | null; - modName: string; - previousVersion: string | null; -} - -interface FactorioGameDataUpdate { - newVersion: string | null; - oldVersion: string | null; -} - -interface FactorioConfigurationUpdate extends KafkatorioPacket { - allMods: FactorioModInfo[]; - factorioData: FactorioGameDataUpdate; - modVersion: string; - packetType: PacketType; - tick: uint; -} diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts new file mode 100644 index 0000000..e215deb --- /dev/null +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts @@ -0,0 +1,217 @@ +// Generated by TypeScriptGenerator - do not edit this file manually + +export interface KafkatorioPacket2 { + modVersion: string; + tick: Tick; + data: KafkatorioPacketData2; +} + +export type Tick = UInt; + +export type KafkatorioPacketData2 = + | KafkatorioPacketData2.ConfigurationUpdate + | KafkatorioPacketData2.ConsoleChatUpdate + | KafkatorioPacketData2.ConsoleCommandUpdate + | KafkatorioPacketData2.EntityUpdate + | KafkatorioPacketData2.MapChunkUpdate + | KafkatorioPacketData2.PlayerUpdate + | KafkatorioPacketData2.PrototypesUpdate + | KafkatorioPacketData2.SurfaceUpdate; + +export namespace KafkatorioPacketData2 { + export enum Type { + ConfigurationUpdate = "dev.adamko.kafkatorio.schema2.ConfigurationUpdate", + ConsoleChatUpdate = "dev.adamko.kafkatorio.schema2.ConsoleChatUpdate", + ConsoleCommandUpdate = "dev.adamko.kafkatorio.schema2.ConsoleCommandUpdate", + PrototypesUpdate = "dev.adamko.kafkatorio.schema2.PrototypesUpdate", + SurfaceUpdate = "dev.adamko.kafkatorio.schema2.SurfaceUpdate", + EntityUpdate = "dev.adamko.kafkatorio.schema2.EntityUpdate", + MapChunkUpdate = "dev.adamko.kafkatorio.schema2.MapChunkUpdate", + PlayerUpdate = "dev.adamko.kafkatorio.schema2.PlayerUpdate", + } + + export interface ConfigurationUpdate { + type: KafkatorioPacketData2.Type.ConfigurationUpdate; + factorioData: ConfigurationUpdateGameData; + allMods: ConfigurationUpdateModData[]; + modStartupSettingsChange: boolean; + migrationApplied: boolean; + } + + export interface ConsoleChatUpdate { + type: KafkatorioPacketData2.Type.ConsoleChatUpdate; + authorPlayerIndex: PlayerIndex | null; + content: string; + } + + export interface ConsoleCommandUpdate { + type: KafkatorioPacketData2.Type.ConsoleCommandUpdate; + authorPlayerIndex: PlayerIndex | null; + command: string; + parameters: string; + } + + export interface PrototypesUpdate { + type: KafkatorioPacketData2.Type.PrototypesUpdate; + prototypes: FactorioPrototype2[]; + } + + export interface SurfaceUpdate { + type: KafkatorioPacketData2.Type.SurfaceUpdate; + index: SurfaceIndex; + daytime: Double; + name: string; + } + + export interface EntityUpdate { + type: KafkatorioPacketData2.Type.EntityUpdate; + key: EntityUpdateKey; + eventCounts?: { [key: string]: UInt } | null; + chunkPosition?: MapChunkPosition | null; + graphicsVariation?: UByte | null; + health?: Float | null; + isActive?: boolean | null; + isRotatable?: boolean | null; + lastUser?: UInt | null; + localisedDescription?: string | null; + localisedName?: string | null; + prototype?: PrototypeName | null; + } + + export interface MapChunkUpdate { + type: KafkatorioPacketData2.Type.MapChunkUpdate; + key: MapChunkUpdateKey; + eventCounts?: { [key: string]: UInt } | null; + player?: PlayerIndex | null; + robot?: EntityIdentifiersData | null; + force?: ForceIndex | null; + tileDictionary?: MapTileDictionary | null; + isDeleted?: boolean | null; + } + + export interface PlayerUpdate { + type: KafkatorioPacketData2.Type.PlayerUpdate; + key: PlayerUpdateKey; + eventCounts?: { [key: string]: UInt } | null; + characterUnitNumber?: UnitNumber | null; + chatColour?: Colour | null; + colour?: Colour | null; + name?: string | null; + afkTime?: Tick | null; + ticksToRespawn?: Tick | null; + forceIndex?: ForceIndex | null; + isAdmin?: boolean | null; + isConnected?: boolean | null; + isShowOnMap?: boolean | null; + isSpectator?: boolean | null; + lastOnline?: Tick | null; + onlineTime?: Tick | null; + position?: MapEntityPosition | null; + surfaceIndex?: SurfaceIndex | null; + tag?: string | null; + diedCause?: EntityIdentifiersData | null; + bannedReason?: string | null; + kickedReason?: string | null; + disconnectReason?: string | null; + isRemoved?: boolean | null; + } +} + +export type UInt = uint; + +export interface ConfigurationUpdateGameData { + oldVersion?: string | null; + newVersion?: string | null; +} + +export type PlayerIndex = UInt; + +export type SurfaceIndex = UInt; + +export type Double = double; + +export interface EntityUpdateKey { + unitNumber: UnitNumber; + name: string; + protoType: string; +} + +export type MapChunkPosition = [ + x: Int, + y: Int, +]; + +export type UByte = uint8; + +export type Float = float; + +export type PrototypeName = string; + +export interface MapChunkUpdateKey { + chunkPosition: MapChunkPosition; + surfaceIndex: SurfaceIndex; +} + +export interface EntityIdentifiersData { + unitNumber?: UnitNumber | null; + name: string; + protoType: string; +} + +export type ForceIndex = UInt; + +export interface MapTileDictionary { + tilesXY: { [key: string]: { [key: string]: PrototypeKey } }; + protos: { [key: PrototypeName]: PrototypeKey }; +} + +export interface PlayerUpdateKey { + index: PlayerIndex; +} + +export type UnitNumber = UInt; + +export interface Colour { + red?: Float; + green?: Float; + blue?: Float; + alpha?: Float; +} + +export type MapEntityPosition = [ + x: Double, + y: Double, +]; + +export type Int = int; + +export interface ConfigurationUpdateModData { + modName: string; + currentVersion?: string | null; + previousVersion?: string | null; +} + +export type FactorioPrototype2 = + | FactorioPrototype2.MapTile; + +export namespace FactorioPrototype2 { + export enum Type { + MapTile = "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + } + + export interface MapTile { + type: FactorioPrototype2.Type.MapTile; + name: PrototypeName; + layer: UInt; + mapColour: Colour; + collisionMasks: List; + order: string; + canBeMined: boolean; + } +} + +export type Byte = int8; + +export type List = any; + +export type PrototypeKey = Int; \ No newline at end of file diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts deleted file mode 100644 index e6d895d..0000000 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/object-data.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -// Generated by TypeScriptGenerator - do not edit this file manually - -type ObjectName = "LuaSurface" | "ConsoleChatMessage"; - -interface FactorioObjectData { - objectName: ObjectName; -} - -interface SurfaceData extends FactorioObjectData { - daytime: double; - index: uint; - name: string; - objectName: ObjectName; -} - -interface ConsoleChatMessage extends FactorioObjectData { - authorPlayerIndex: uint | null; - content: string; - objectName: ObjectName; -} diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts deleted file mode 100644 index 5dbd1c0..0000000 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/prototype.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Generated by TypeScriptGenerator - do not edit this file manually - -type PrototypeObjectName = "LuaTilePrototype"; - -interface FactorioPrototype { - prototypeObjectName: PrototypeObjectName; -} - -interface FactorioPrototypes extends KafkatorioPacket { - modVersion: string; - packetType: PacketType; - prototypes: FactorioPrototype[]; - tick: uint; -} - -interface MapTilePrototype extends FactorioPrototype { - canBeMined: boolean; - collisionMasks: string[]; - layer: uint; - mapColour: Colour; - name: string; - order: string; - prototypeObjectName: PrototypeObjectName; -} diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts deleted file mode 100644 index 7ce627e..0000000 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/schema.d.ts +++ /dev/null @@ -1,51 +0,0 @@ -// Generated by TypeScriptGenerator - do not edit this file manually - -type PacketType = "EVENT" | "CONFIG" | "PROTOTYPES" | "UPDATE"; - -interface KafkatorioPacket { - modVersion: string; - packetType: PacketType; - tick: uint; -} - -interface FactorioEvent extends KafkatorioPacket { - data: FactorioObjectData; - eventType: string; - modVersion: string; - packetType: PacketType; - tick: uint; -} - -interface Colour { - alpha: float; - blue: float; - green: float; - red: float; -} - -interface EntityIdentifiers { - name: string; - type: string; - unitNumber: uint | null; -} - -interface EntityIdentifiersData extends EntityIdentifiers { - name: string; - type: string; - unitNumber: uint | null; -} - -interface MapEntityPosition { - x: double; - y: double; -} - -interface MapChunkPosition { - x: int; - y: int; -} - -interface MapTileDictionary { - protos: { [key: string]: string }; - tilesXY: { [key: string]: { [key: string]: string } }; -} diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts deleted file mode 100644 index 058fb45..0000000 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/update.d.ts +++ /dev/null @@ -1,90 +0,0 @@ -// Generated by TypeScriptGenerator - do not edit this file manually - -type FactorioEventUpdateType = "PLAYER" | "MAP_CHUNK" | "ENTITY"; - -interface FactorioEventUpdateKey { - updateType: FactorioEventUpdateType; -} - -interface FactorioEventUpdate extends FactorioEventUpdateKey { - eventCounts: { [key: string]: uint } | null; - updateType: FactorioEventUpdateType; -} - -interface FactorioEventUpdatePacket extends KafkatorioPacket { - modVersion: string; - packetType: PacketType; - tick: uint; - update: FactorioEventUpdate; -} - -interface PlayerUpdateKey extends FactorioEventUpdateKey { - index: uint; -} - -interface PlayerUpdate extends FactorioEventUpdate, PlayerUpdateKey { - afkTime: uint | null; - bannedReason: string | null; - characterUnitNumber: uint | null; - chatColour: Colour | null; - colour: Colour | null; - diedCause: EntityIdentifiersData | null; - disconnectReason: string | null; - eventCounts: { [key: string]: uint } | null; - forceIndex: uint | null; - index: uint; - isAdmin: boolean | null; - isConnected: boolean | null; - isRemoved: boolean | null; - isShowOnMap: boolean | null; - isSpectator: boolean | null; - kickedReason: string | null; - lastOnline: uint | null; - name: string | null; - onlineTime: uint | null; - position: MapEntityPosition | null; - surfaceIndex: uint | null; - tag: string | null; - ticksToRespawn: uint | null; - updateType: FactorioEventUpdateType; -} - -interface EntityUpdateKey extends EntityIdentifiers, FactorioEventUpdateKey { - name: string; - type: string; - unitNumber: uint; -} - -interface EntityUpdate extends FactorioEventUpdate, EntityUpdateKey { - chunkPosition: MapChunkPosition | null; - eventCounts: { [key: string]: uint } | null; - graphicsVariation: uint8 | null; - health: float | null; - isActive: boolean | null; - isRotatable: boolean | null; - lastUser: uint | null; - localisedDescription: string | null; - localisedName: string | null; - name: string; - prototype: string | null; - type: string; - unitNumber: uint; - updateType: FactorioEventUpdateType; -} - -interface MapChunkUpdateKey extends FactorioEventUpdateKey { - chunkPosition: MapChunkPosition; - surfaceIndex: uint; -} - -interface MapChunkUpdate extends FactorioEventUpdate, MapChunkUpdateKey { - chunkPosition: MapChunkPosition; - eventCounts: { [key: string]: uint } | null; - force: uint | null; - isDeleted: boolean | null; - player: uint | null; - robot: EntityIdentifiersData | null; - surfaceIndex: uint; - tileDictionary: MapTileDictionary | null; - updateType: FactorioEventUpdateType; -} diff --git a/modules/events-mod/src/main/typescript/main/PacketEmitter.ts b/modules/events-mod/src/main/typescript/main/PacketEmitter.ts new file mode 100644 index 0000000..d73907f --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/PacketEmitter.ts @@ -0,0 +1,41 @@ +import { + KafkatorioPacket2, + KafkatorioPacketData2 +} from "../generated/kafkatorio-schema/kafkatorio-schema"; +import {KafkatorioKeyedPacketData} from "./types"; + +export class KafkatorioPacketEmitter { + + emitInstantPacket( + data: DATA, + ) { + KafkatorioPacketEmitter.emitPacket({ + data: data, + modVersion: global.MOD_VERSION, + tick: game.tick, + }) + } + + emitKeyedPacket( + data: DATA, + ) { + KafkatorioPacketEmitter.emitPacket({ + data: data, + modVersion: global.MOD_VERSION, + tick: game.tick, + }) + } + + /** Emit a serialised KafkatorioPacket */ + private static emitPacket(packet: T) { + let data = game.table_to_json(packet) + localised_print(`KafkatorioPacket: ${data}`) + // rcon.print(`KafkatorioPacket: ${data}`) + } + +} + + +const PacketEmitter = new KafkatorioPacketEmitter() + +export default PacketEmitter diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts index a77510c..d61e801 100644 --- a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts +++ b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts @@ -1,10 +1,12 @@ import KafkatorioSettings from "../settings/KafkatorioSettings"; +import {KafkatorioKeyedPacketData} from "../types"; export namespace EventUpdates { declare const global: { - cache: LuaTable>, + /** Map the hash of the key, as a string, a cache entry */ + cache: LuaTable>, } @@ -19,7 +21,7 @@ export namespace EventUpdates { if (force == true || isAnythingUndefined) { log("Initialising global.cache") - global.cache = new LuaTable>() + global.cache = new LuaTable>() } log(`Finished initialising EventDataCache`) } @@ -29,12 +31,13 @@ export namespace EventUpdates { * Update the cache data without restarting the 'time-to-emit' countdown, so that the data won't * be emitted more than once per {@link CacheEntry.expirationDurationTicks}. */ - public throttle( - key: CacheKey, - mutate: CacheDataMutator, + public throttle( + key: PacketKey, + type: PacketType, + mutate: CacheDataMutator, expirationDurationTicks?: uint, ) { - this.update(key, mutate, false, expirationDurationTicks) + this.update(key, type, mutate, false, expirationDurationTicks) } @@ -42,23 +45,26 @@ export namespace EventUpdates { * Update the cache data and reset the 'time-to-emit' countdown, so the data won't be emitted * until there's an inactivity gap of {@link CacheEntry.expirationDurationTicks}. */ - public debounce( - key: CacheKey, - mutate: CacheDataMutator, + public debounce( + key: PacketKey, + type: PacketType, + mutate: CacheDataMutator, expirationDurationTicks?: uint, ) { - this.update(key, mutate, true, expirationDurationTicks) + this.update(key, type, mutate, true, expirationDurationTicks) } - private update( - key: CacheKey, - mutate: CacheDataMutator, + private update( + key: PacketKey, + type: PacketType, + mutate: CacheDataMutator, resetLastUpdated: boolean, expirationDurationTicks?: uint, ) { - const entry: CacheEntry = this.getCacheEntry(key) ?? this.createCacheEntry(key, mutate) - mutate(entry.data) + const entry: CacheEntry = this.getCacheEntry(key) ?? + Manager.createCacheEntry(key, type) + mutate(entry.packet) if (resetLastUpdated) { entry.lastUpdatedTick = game.tick } @@ -72,8 +78,8 @@ export namespace EventUpdates { * Usage example: If an urgent update comes in, then the expiration can be reduced so that * it's transmitted sooner. */ - public setExpiration( - key: CacheKey, + public setExpiration( + key: PacketKey, expirationDurationTicks: uint, ) { const entry = this.getCacheEntry(key) @@ -83,15 +89,16 @@ export namespace EventUpdates { } - public extractExpired(): Array { + // use in/out v4.7.0 https://github.com/microsoft/TypeScript/pull/48240 + public extractExpired(): Array { let countExpired = 0 let countTotal = 0 - const expiredData: Array = [] + const expiredData: Array = [] for (let [key, entry] of global.cache) { countTotal++ if (this.isExpired(entry)) { countExpired++ - expiredData.push(entry.data) + expiredData.push(entry.packet) global.cache.delete(key) } } @@ -102,15 +109,15 @@ export namespace EventUpdates { } - private getCacheEntry( - key: CacheKey - ): CacheEntry | undefined { - const hash = game.encode_string(game.table_to_json(key))!! + private getCacheEntry( + key: PacketKey + ): CacheEntry | undefined { + const hash = Manager.hashKey(key) if (!global.cache.has(hash)) { return undefined } const value: CacheEntry = global.cache.get(hash) - if (this.isEntryInstanceOf(value, key.updateType)) { + if (this.isEntryInstanceOf(value, key)) { return value } else { // Type mismatch. This shouldn't happen... @@ -119,40 +126,53 @@ export namespace EventUpdates { } - private createCacheEntry( - key: CacheKey, - mutate: CacheDataMutator, - ): CacheEntry { - const data: CacheData = >{...key} - mutate(data) - let entry: CacheEntry = new CacheEntry(data) - const hash = game.encode_string(game.table_to_json(key))!! + private static createCacheEntry( + key: PacketKey, + type: PacketType, + ): CacheEntry { + const data: PACKET = { + type: type, + key: key, + } + let entry: CacheEntry = new CacheEntry(data) + const hash = Manager.hashKey(key) global.cache.set(hash, entry) return entry } - isExpired(entry: CacheEntry): boolean { - const expiryDuration = entry.expirationDurationTicks - ?? - KafkatorioSettings.getEventCacheExpirationTicks(entry.data.updateType) - return game.tick - entry.lastUpdatedTick > expiryDuration + isExpired(entry: CacheEntry): boolean { + const expiryDuration = + entry.expirationDurationTicks + ?? KafkatorioSettings.getEventCacheExpirationTicks(entry.packet) + + if (expiryDuration == undefined) { + return true + } else { + return game.tick - entry.lastUpdatedTick > expiryDuration + } } - isEntryInstanceOf( + isEntryInstanceOf( entry: CacheEntry | undefined, - updateType: TYPE, - ): entry is CacheEntry { - return this.isDataInstanceOf(entry?.data, updateType) + key: PacketKey, + ): entry is CacheEntry { + return this.isDataInstanceOf(entry?.packet, key) } - isDataInstanceOf( - data: CacheData | undefined, - updateType: TYPE, - ): data is CacheData { - return data != undefined && data.updateType == updateType + isDataInstanceOf( + packet: PACKET | undefined, + key: PacketKey, + ): packet is PACKET { + return packet != undefined && packet.key == key + } + + private static hashKey( + key: PacketKey, + ): string { + return game.encode_string(game.table_to_json(key))!! } @@ -166,54 +186,56 @@ export namespace EventUpdates { } - /** Map a {@link FactorioEventUpdateType} to a {@link FactorioEventUpdate} DTO */ - type ConvertToUpdate = - TYPE extends "PLAYER" ? PlayerUpdate : - TYPE extends "MAP_CHUNK" ? MapChunkUpdate : - TYPE extends "ENTITY" ? EntityUpdate : - never + // export type KeyedPacketType = Exclude + + // /** Map a {@link KeyedPacketType} to a {@link KafkatorioPacketData} DTO */ + // type ConvertToUpdate = + // TYPE extends "PLAYER" ? PlayerUpdate : + // TYPE extends "MAP_CHUNK" ? MapChunkUpdate : + // TYPE extends "ENTITY" ? EntityUpdate : + // never - /** Map a {@link FactorioEventUpdateType} to a {@link FactorioEventUpdateKey} */ - type ConvertToUpdateKey = - TYPE extends "PLAYER" ? PlayerUpdateKey : - TYPE extends "MAP_CHUNK" ? MapChunkUpdateKey : - TYPE extends "ENTITY" ? EntityUpdateKey : - never + // /** Map a {@link KeyedPacketType} to a {@link KafkatorioKeyedPacketKey} */ + // type ConvertToUpdateKey = + // TYPE extends "PLAYER" ? PlayerUpdateKey : + // TYPE extends "MAP_CHUNK" ? MapChunkUpdateKey : + // TYPE extends "ENTITY" ? EntityUpdateKey : + // never - /** Make `updateType` specific */ - export type CacheKey = - CacheTyped - & Omit, "updateType"> + // /** Make `updateType` specific */ + export type PacketKey = PACKET["key"] + export type PacketType = PACKET["type"] + // + // + // /** Make `updateType` specific */ + // export type CacheData = + // CacheTyped + // & Omit, "updateType"> + // + // + // export type CacheTyped = { + // readonly updateType: TYPE + // } - /** Make `updateType` specific */ - export type CacheData = - CacheTyped - & Omit, "updateType"> + export type CacheDataMutator = (packet: PACKET) => void - export type CacheTyped = { - readonly updateType: TYPE - } - - - export type CacheDataMutator = - (data: CacheData) => void - - - class CacheEntry { + class CacheEntry { lastUpdatedTick: uint = game.tick expirationDurationTicks?: uint - data: CacheData + packet: PACKET constructor( - data: CacheData, + packet: PACKET, expirationDurationTicks?: uint, ) { - this.data = data + + this.packet = packet this.expirationDurationTicks = expirationDurationTicks } } @@ -222,4 +244,5 @@ export namespace EventUpdates { } const EventUpdatesManager = new EventUpdates.Manager() + export default EventUpdatesManager diff --git a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts index 2edcb1e..febd47e 100644 --- a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts +++ b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts @@ -1,23 +1,16 @@ -import {emitPacket} from "../emitKafkatorioPacket"; import EventCacheService from "./EventDataCache"; +import packetEmitter from "../PacketEmitter"; +import {KafkatorioKeyedPacketData} from "../types"; /** Every 0.1 seconds */ script.on_nth_tick(6, (nthTick: NthTickEventData) => { - const cachedEvents: Array = EventCacheService.extractExpired() + const cachedEvents: Array = EventCacheService.extractExpired() if (cachedEvents.length > 0) { log(`nth tick ${nthTick.tick} has ${cachedEvents.length} events`) for (const event of cachedEvents) { - - const packet: FactorioEventUpdatePacket = { - tick: nthTick.tick, - modVersion: global.MOD_VERSION, - packetType: "UPDATE", - update: event, - } - - emitPacket(packet) + packetEmitter.emitKeyedPacket(event) } } }) diff --git a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts index 783f611..8652d83 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts @@ -1,25 +1,33 @@ -import {emitPacket} from "../emitKafkatorioPacket"; +import PacketEmitter from "../PacketEmitter"; +import { + ConfigurationUpdateGameData, + ConfigurationUpdateModData, + KafkatorioPacketData2 +} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +import Type = KafkatorioPacketData2.Type; +import ConfigurationUpdate = KafkatorioPacketData2.ConfigurationUpdate; export function emitConfigurationUpdate(changeData: ConfigurationChangedData) { - emitPacket({ - modVersion: global.MOD_VERSION, - packetType: "CONFIG", + const configUpdateData: ConfigurationUpdate = { + type: Type.ConfigurationUpdate, + migrationApplied: changeData.migration_applied, + modStartupSettingsChange: changeData.mod_startup_settings_changed, allMods: allMods(changeData), - factorioData: factorioData(changeData), - tick: game.tick, - }) + factorioData: factorioData(changeData) + } + PacketEmitter.emitInstantPacket(configUpdateData) } -function factorioData(changeData: ConfigurationChangedData): FactorioGameDataUpdate { +function factorioData(changeData: ConfigurationChangedData): ConfigurationUpdateGameData { return { oldVersion: changeData.old_version ?? null, newVersion: changeData.new_version ?? null, } } -function allMods(e: ConfigurationChangedData): FactorioModInfo[] { +function allMods(e: ConfigurationChangedData): ConfigurationUpdateModData[] { let namesOfChangedMods: string[] = Object.keys(e.mod_changes) let namesOfCurrentMods: string[] = Object.keys(script.active_mods) @@ -33,7 +41,7 @@ function allMods(e: ConfigurationChangedData): FactorioModInfo[] { let currentVer = script.active_mods[modName] ?? e.mod_changes[modName].new_version ?? null let previousVer = e.mod_changes[modName]?.old_version ?? null - return { + return { modName: modName, currentVersion: currentVer, previousVersion: previousVer, diff --git a/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts b/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts index bd96832..573512b 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts @@ -1,30 +1,37 @@ import {Converters} from "../events/converters"; -import {emitPacket} from "../emitKafkatorioPacket"; +import PacketEmitter from "../PacketEmitter"; +import { + FactorioPrototype2, + KafkatorioPacketData2 +} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +import Type = KafkatorioPacketData2.Type; +import PrototypesUpdate = KafkatorioPacketData2.PrototypesUpdate; export function emitPrototypes() { - emitPacket({ - modVersion: global.MOD_VERSION, - packetType: "PROTOTYPES", + + const data: PrototypesUpdate = { prototypes: prototypes(), - tick: game.tick, - }) + type: Type.PrototypesUpdate, + } + + PacketEmitter.emitInstantPacket(data) } -function prototypes(): FactorioPrototype[] { - let prototypes: FactorioPrototype[] = [] +function prototypes(): FactorioPrototype2[] { + let prototypes: FactorioPrototype2[] = [] prototypes.push(...getMapTilePrototypes()) return prototypes } -function getMapTilePrototypes(): MapTilePrototype[] { - let tiles: MapTilePrototype[] = [] +function getMapTilePrototypes(): FactorioPrototype2.MapTile[] { + let tiles: FactorioPrototype2.MapTile[] = [] for (let [, tile] of game.tile_prototypes) { tiles.push( - { - prototypeObjectName: tile.object_name, + { + type: FactorioPrototype2.Type.MapTile, name: tile.name, order: tile.order, diff --git a/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts b/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts deleted file mode 100644 index c86af5d..0000000 --- a/modules/events-mod/src/main/typescript/main/emitKafkatorioPacket.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** Emit a serialised KafkatorioPacket */ -export function emitPacket(packet: T) { - let data = game.table_to_json(packet) - localised_print(`KafkatorioPacket: ${data}`) - // rcon.print(`KafkatorioPacket: ${data}`) -} diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index 3eedfa7..a7dcdbe 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -1,4 +1,5 @@ import {EventName} from "../types"; +import {Colour} from "../../generated/kafkatorio-schema/kafkatorio-schema"; export namespace Converters { @@ -62,15 +63,6 @@ export namespace Converters { // return result // } - export function surfaceToTable(surface: LuaSurface): SurfaceData { - return { - objectName: surface.object_name, - - name: surface.name, - index: surface.index, - daytime: surface.daytime, - } - } // export function mapEntityPosition(mapPos: MapPositionTable): MapEntityPosition { // return { @@ -102,14 +94,6 @@ export namespace Converters { } } - export function consoleChat(content: string, playerIndex?: uint): ConsoleChatMessage { - return { - objectName: "ConsoleChatMessage", - - authorPlayerIndex: playerIndex ?? null, - content: content - } - } // export function convertTile(tile: LuaTile): MapTile { // return { diff --git a/modules/events-mod/src/main/typescript/main/events/emitEvent.ts b/modules/events-mod/src/main/typescript/main/events/emitEvent.ts deleted file mode 100644 index d095fbc..0000000 --- a/modules/events-mod/src/main/typescript/main/events/emitEvent.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {emitPacket} from "../emitKafkatorioPacket"; - -/** Emit a serialised event */ -export function emitEvent(eventData: T, tick: uint, eventType: string) { - emitPacket({ - data: eventData, - packetType: "EVENT", - eventType: eventType, - modVersion: global.MOD_VERSION, - tick: tick, - }) -} diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index 4de8672..1d1fe5b 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -1,5 +1,6 @@ -import {Converters} from "./converters" -import {emitEvent} from "./emitEvent"; +import PacketEmitter from "../PacketEmitter"; +import {KafkatorioPacketData2} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +import Type = KafkatorioPacketData2.Type; // export function handlePlayerUpdate(tick: uint, eventType: string, playerIndex: uint) { // let player: LuaPlayer = game.players[playerIndex] @@ -29,24 +30,23 @@ import {emitEvent} from "./emitEvent"; // emitEvent(table, tick, eventType) // } + export function handleSurfaceUpdate( - tick: uint, + event: OnTickEvent, eventType: string, surface: LuaSurface, ) { - let table = Converters.surfaceToTable(surface) - emitEvent(table, tick, eventType) + const update: KafkatorioPacketData2.SurfaceUpdate = { + type: Type.SurfaceUpdate, + + name: surface.name, + index: surface.index, + daytime: surface.daytime + } + + PacketEmitter.emitInstantPacket(update) } -export function handleConsoleChat( - tick: uint, - eventType: string, - playerIndex: uint | undefined, - message: string, -) { - let table = Converters.consoleChat(message, playerIndex) - emitEvent(table, tick, eventType) -} // export function handleChunkUpdate( // tick: uint, diff --git a/modules/events-mod/src/main/typescript/main/events/onConsoleEventHandlers.ts b/modules/events-mod/src/main/typescript/main/events/onConsoleEventHandlers.ts new file mode 100644 index 0000000..48b2b8b --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/events/onConsoleEventHandlers.ts @@ -0,0 +1,31 @@ +import PacketEmitter from "../PacketEmitter"; +import {KafkatorioPacketData2} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +import Type = KafkatorioPacketData2.Type; + +script.on_event( + defines.events.on_console_chat, + (event: OnConsoleChatEvent) => { + const update: KafkatorioPacketData2.ConsoleChatUpdate = { + type: Type.ConsoleChatUpdate, + + authorPlayerIndex: event.player_index ?? null, + content: event.message + } + PacketEmitter.emitInstantPacket(update) + } +) + +script.on_event( + defines.events.on_console_command, + (event: OnConsoleCommandEvent) => { + const update: KafkatorioPacketData2.ConsoleCommandUpdate = { + type: Type.ConsoleCommandUpdate, + + authorPlayerIndex: event.player_index ?? null, + command: event.command, + parameters: event.parameters, + } + + PacketEmitter.emitInstantPacket(update) + } +) diff --git a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts index 91a49e9..c3be4bf 100644 --- a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts @@ -1,20 +1,25 @@ import {isEventType} from "./eventTypeCheck"; import {Converters} from "./converters"; import EventUpdatesManager, {EventUpdates} from "../cache/EventDataCache"; -import CacheKey = EventUpdates.CacheKey; -import CacheData = EventUpdates.CacheData; +import { + KafkatorioPacketData2, + MapChunkPosition, + MapTileDictionary +} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +import CacheKey = EventUpdates.PacketKey; +import Type = KafkatorioPacketData2.Type; -type MapChunkUpdater = (data: CacheData<"MAP_CHUNK">) => void +type MapChunkUpdater = (data: KafkatorioPacketData2.MapChunkUpdate) => void -const mapProtoNameToKey: { [key: string]: string } = {} +const mapProtoNameToKey: { [key: string]: uint } = {} let protoIndex: uint = 0 -function getProtoKey(protoName: string): string { +function getProtoKey(protoName: string): uint { if (mapProtoNameToKey[protoName] == undefined) { - mapProtoNameToKey[protoName] = `${protoIndex++}` + mapProtoNameToKey[protoName] = protoIndex++ } return mapProtoNameToKey[protoName] } @@ -22,7 +27,7 @@ function getProtoKey(protoName: string): string { function mapTilesUpdateDebounce( surface: LuaSurface | undefined, - chunkPosition: ChunkPositionTable, + chunkPosition: MapChunkPosition, tiles: TileRead[], eventName: string, updater?: MapChunkUpdater, @@ -33,14 +38,14 @@ function mapTilesUpdateDebounce( return } - const key: CacheKey<"MAP_CHUNK"> = { + const key: KafkatorioPacketData2.MapChunkUpdate["key"] = { surfaceIndex: surface.index, chunkPosition: chunkPosition, - updateType: "MAP_CHUNK", } - EventUpdatesManager.debounce<"MAP_CHUNK">( + EventUpdatesManager.debounce( key, + Type.MapChunkUpdate, data => { data.tileDictionary ??= { tilesXY: {}, @@ -53,7 +58,7 @@ function mapTilesUpdateDebounce( const yString = `${tile.position.y}` const protoKey = getProtoKey(tile.name) - data.tileDictionary.protos[protoKey] = tile.name + data.tileDictionary.protos[tile.name] = protoIndex data.tileDictionary.tilesXY[xString] ??= {} data.tileDictionary.tilesXY[xString][yString] = protoKey @@ -105,7 +110,7 @@ export function handleChunkGeneratedEvent( let tiles = getTiles(e.surface, e.area) mapTilesUpdateDebounce( e.surface, - e.position, + [e.position.x, e.position.y], tiles, Converters.eventNameString(e.name), undefined, @@ -114,22 +119,22 @@ export function handleChunkGeneratedEvent( } -script.on_event( - defines.events.on_chunk_charted, - (e: OnChunkChartedEvent) => { - log(`on_chunk_charted ${e.tick}`) - - // const surface = getSurface(e.surface_index) - // if (surface == undefined) { - // return - // } - // - // let tiles = getTiles(surface, e.area) - // mapTilesUpdateDebounce(surface, e.position, tiles, (data => { - // data.force = e.force.index - // })) - } -) +// script.on_event( +// defines.events.on_chunk_charted, +// (e: OnChunkChartedEvent) => { +// log(`on_chunk_charted ${e.tick}`) +// +// // const surface = getSurface(e.surface_index) +// // if (surface == undefined) { +// // return +// // } +// // +// // let tiles = getTiles(surface, e.area) +// // mapTilesUpdateDebounce(surface, e.position, tiles, (data => { +// // data.force = e.force.index +// // })) +// } +// ) script.on_event( @@ -155,14 +160,19 @@ function groupTiles(tiles: TileRead[]): Map { const mapChunkPositionToTiles = new Map() for (const tile of tiles) { - const chunkPosition = { - x: math.floor((tile.position.x / 32)), - y: math.floor((tile.position.y / 32)), - } + const chunkPosition: MapChunkPosition = [ + math.floor((tile.position.x / 32)), + math.floor((tile.position.y / 32)), + ] if (!mapChunkPositionToTiles.has(chunkPosition)) { mapChunkPositionToTiles.set(chunkPosition, []) } - mapChunkPositionToTiles.get(chunkPosition)?.push(tile) + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1256 + // mapChunkPositionToTiles.get(chunkPosition)?.push(tile) + const tiles = mapChunkPositionToTiles.get(chunkPosition) + if (tiles != null) { + tiles.push(tile) + } } return mapChunkPositionToTiles } @@ -183,7 +193,7 @@ function convertOldPosition( } -function onBuildTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) { +function handleBuiltTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) { const surface = getSurface(event.surface_index) if (surface == undefined) { @@ -209,7 +219,7 @@ function onBuildTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) data.robot = { unitNumber: event.robot?.unit_number ?? null, name: event.robot.name, - type: event.robot.type, + protoType: event.robot.type, } return } @@ -225,28 +235,25 @@ function onBuildTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) script.on_event(defines.events.on_player_built_tile, (e: OnPlayerBuiltTileEvent) => { log(`on_player_built_tile ${e.tick}`) - onBuildTileEvent(e) + handleBuiltTileEvent(e) }) script.on_event(defines.events.on_robot_built_tile, (e: OnRobotBuiltTileEvent) => { log(`on_robot_built_tile ${e.tick}`) - onBuildTileEvent(e) + handleBuiltTileEvent(e) }) -// script.on_event( -// defines.events.on_player_mined_tile, -// (e: OnPlayerMinedTileEvent) => { -// // need to group tiles by ChunkPosition... -// -// } -// ) -// script.on_event( -// defines.events.on_robot_mined_tile, -// (e: OnRobotMinedTileEvent) => { -// // need to group tiles by ChunkPosition... +// function handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) { +// } // -// } -// ) +// script.on_event(defines.events.on_player_mined_tile, (e: OnPlayerMinedTileEvent) => { +// log(`on_player_mined_tile ${e.tick}`) +// handleMinedTileEvent(e) +// }) +// script.on_event(defines.events.on_robot_mined_tile, (e: OnRobotMinedTileEvent) => { +// log(`on_robot_mined_tile ${e.tick}`) +// handleMinedTileEvent(e) +// }) script.on_event( @@ -260,17 +267,15 @@ script.on_event( } for (const position of e.positions) { - const key: CacheKey<"MAP_CHUNK"> = { + const key: CacheKey = { surfaceIndex: surface.index, - chunkPosition: position, - updateType: "MAP_CHUNK", + chunkPosition: [position.x, position.y], } - EventUpdatesManager.debounce<"MAP_CHUNK">( + EventUpdatesManager.debounce( key, - data => { - data.isDeleted = true - }, + Type.MapChunkUpdate, + data => data.isDeleted = true, 0, // deletion is important - emit ASAP ) } diff --git a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts index 1f2f6bf..c60a891 100644 --- a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts @@ -1,17 +1,20 @@ import {Converters} from "./converters"; -import EventUpdatesManager, {EventUpdates} from "../cache/EventDataCache"; -import CacheData = EventUpdates.CacheData; +import EventUpdatesManager from "../cache/EventDataCache"; +import {KafkatorioPacketData2} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +import Type = KafkatorioPacketData2.Type; -type PlayerUpdater = (player: LuaPlayer, data: CacheData<"PLAYER">) => void +type PlayerUpdater = (player: LuaPlayer, data: KafkatorioPacketData2.PlayerUpdate) => void function playerUpdateThrottle( playerIndex: uint, eventName: string, mutate: PlayerUpdater, ) { - EventUpdatesManager.throttle<"PLAYER">( - {index: playerIndex, updateType: "PLAYER"}, + + EventUpdatesManager.throttle( + {index: playerIndex}, + Type.PlayerUpdate, data => { const player = game.players[playerIndex] if (player != undefined) { @@ -36,7 +39,7 @@ function playerUpdateThrottle( // ) // } -function playerOnlineInfo(player: LuaPlayer, data: CacheData<"PLAYER">) { +function playerOnlineInfo(player: LuaPlayer, data: KafkatorioPacketData2.PlayerUpdate) { data.lastOnline = player.last_online data.onlineTime = player.online_time data.afkTime = player.afk_time @@ -73,7 +76,7 @@ script.on_event( e.player_index, Converters.eventNameString(e.name), (player, data) => { - data.position = player.position + data.position = [player.position.x, player.position.y] } ) } @@ -86,7 +89,7 @@ script.on_event( e.player_index, Converters.eventNameString(e.name), (player, data) => { - data.position = player.position + data.position = [player.position.x, player.position.y] data.surfaceIndex = player.surface.index } ) @@ -106,7 +109,7 @@ script.on_event( data.diedCause = { unitNumber: e.cause.unit_number ?? null, name: e.cause.name, - type: e.cause.type + protoType: e.cause.type } } } diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index b1315ee..815f196 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -1,9 +1,9 @@ -import {handleConsoleChat, handleSurfaceUpdate,} from "./handlers"; import {Queue} from "../queue/queue"; import {isEventType} from "./eventTypeCheck"; import {Converters} from "./converters"; import KafkatorioSettings from "../settings/KafkatorioSettings"; import {handleChunkGeneratedEvent} from "./onMapChunkEventListeners"; +import {handleSurfaceUpdate} from "./handlers"; // script.on_event( @@ -34,13 +34,8 @@ script.on_event( (e: OnTickEvent) => { if (e.tick % 1000 == 0) { for (const [, surface] of game.surfaces) { - handleSurfaceUpdate(e.tick, Converters.eventNameString(e.name), surface) + handleSurfaceUpdate(e, Converters.eventNameString(e.name), surface) } - - // let packets = new KafkatorioPacketQueue().dequeueValues(1) - // for (const packet of packets) { - // emitPacket(packet) - // } } if (e.tick % 7 == 0) { @@ -64,21 +59,6 @@ script.on_event( } ) -script.on_event( - defines.events.on_console_chat, - (e: OnConsoleChatEvent) => { - handleConsoleChat(e.tick, Converters.eventNameString(e.name), e.player_index, e.message) - } -) - -// script.on_event( -// defines.events.on_chunk_generated, -// (e: OnChunkGeneratedEvent) => { -// handleChunkUpdate(e.tick, mapEventIdToName.get(e.name), e.surface.index, e.position, -// e.area) } ) script.on_event( [ defines.events.on_player_built_tile, -// defines.events.on_robot_built_tile, ], (builtTilesEvent) => { handleTilesUpdate( -// builtTilesEvent.tick, mapEventIdToName.get(builtTilesEvent.name), builtTilesEvent.surface_index, -// builtTilesEvent.tile, builtTilesEvent.tiles, ) } ) script.on_event( defines.events.on_runtime_mod_setting_changed, diff --git a/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts b/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts index 31aee02..d07be70 100644 --- a/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts +++ b/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts @@ -1,52 +1,57 @@ import {Data, DoubleSettingDefinition} from "typed-factorio/settings/types" +import {KafkatorioKeyedPacketData, KafkatorioKeyedPacketTypes} from "../types"; +import {KafkatorioPacketData2} from "../../generated/kafkatorio-schema/kafkatorio-schema"; export class KafkatorioSettingsConfig { - private static eventCacheExpirationDefaultSeconds: Record = { - "PLAYER": 0.25, - "MAP_CHUNK": 30, - "ENTITY": 5, + private static eventCacheExpirationDefaultSeconds: Record = { + "dev.adamko.kafkatorio.schema2.PlayerUpdate": 0.5, + "dev.adamko.kafkatorio.schema2.MapChunkUpdate": 30, + "dev.adamko.kafkatorio.schema2.EntityUpdate": 5, } - private eventCacheExpirationTicks: Record = { - "PLAYER": KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds["PLAYER"], - "MAP_CHUNK": KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds["MAP_CHUNK"], - "ENTITY": KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds["ENTITY"], + private eventCacheExpirationTicks: Record = { + "dev.adamko.kafkatorio.schema2.PlayerUpdate": + KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData2.Type.PlayerUpdate], + "dev.adamko.kafkatorio.schema2.MapChunkUpdate": + KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData2.Type.MapChunkUpdate], + "dev.adamko.kafkatorio.schema2.EntityUpdate": + KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData2.Type.EntityUpdate], } - - public getEventCacheExpirationTicks(type: FactorioEventUpdateType): uint { - return this.eventCacheExpirationTicks[type] + public getEventCacheExpirationTicks(packet: KafkatorioKeyedPacketData): uint { + return this.eventCacheExpirationTicks[packet.type] } + private static types: KafkatorioKeyedPacketTypes[] = [ + KafkatorioPacketData2.Type.PlayerUpdate, + KafkatorioPacketData2.Type.MapChunkUpdate, + KafkatorioPacketData2.Type.EntityUpdate, + ] - loadSettings(): void { - const types: FactorioEventUpdateType[] = ["PLAYER", "MAP_CHUNK", "ENTITY"] - for (const type of types) { + public loadSettings(): void { + for (const type of KafkatorioSettingsConfig.types) { const seconds: double = settings.global[KafkatorioSettingsConfig.cacheDurationSettingName(type)].value as double this.eventCacheExpirationTicks[type] = seconds * 60 // convert ticks to seconds } } - initialiseSettings(data: Data): void { - data.extend( - [ - this.createDefaultCacheDuration("PLAYER"), - this.createDefaultCacheDuration("MAP_CHUNK"), - this.createDefaultCacheDuration("ENTITY"), - ] + public initialiseSettings(data: Data): void { + const settings = KafkatorioSettingsConfig.types.map( + type => KafkatorioSettingsConfig.createDefaultCacheDuration(type) ) + data.extend(settings) } - private createDefaultCacheDuration( - type: FactorioEventUpdateType, + private static createDefaultCacheDuration( + type: KafkatorioKeyedPacketTypes, defaultExpirationSeconds: uint = KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[type], ): DoubleSettingDefinition { - return { + return { type: "double-setting", name: KafkatorioSettingsConfig.cacheDurationSettingName(type), setting_type: "runtime-global", @@ -58,13 +63,12 @@ export class KafkatorioSettingsConfig { } - private static cacheDurationSettingName(type: FactorioEventUpdateType): string { - return `kafkatorio_event-cache_default-expiration-duration-seconds_${type}` + private static cacheDurationSettingName(type: KafkatorioKeyedPacketTypes): string { + return `kafkatorio_event-cache_default-expiration-duration-seconds_${type.replaceAll(".", "-")}` } - } - const KafkatorioSettings = new KafkatorioSettingsConfig() + export default KafkatorioSettings diff --git a/modules/events-mod/src/main/typescript/main/types.d.ts b/modules/events-mod/src/main/typescript/main/types.d.ts index 62198ea..edf30aa 100644 --- a/modules/events-mod/src/main/typescript/main/types.d.ts +++ b/modules/events-mod/src/main/typescript/main/types.d.ts @@ -1,3 +1,5 @@ +import {KafkatorioPacketData2} from "../generated/kafkatorio-schema/kafkatorio-schema"; + export type EventName = keyof typeof defines.events @@ -15,3 +17,10 @@ type ExcludeNullKeys = Pick> type NonNullableKeys = { [KEY in keyof TYPE]: NonNullable; } + + +type KafkatorioKeyedPacketData = Extract + +type KafkatorioKeyedPacketTypes = KafkatorioKeyedPacketData["type"]; + +type KafkatorioKeyedPacketKeys = KafkatorioKeyedPacketData["key"]; diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index cf4979b..3b77285 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,13 +1,13 @@ { "name": "kafkatorio-events-mod", - "version": "0.3.2", + "version": "0.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { "enhanced-resolve": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz", - "integrity": "sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz", + "integrity": "sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==", "requires": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -19,9 +19,9 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "has": { "version": "1.0.3", @@ -75,19 +75,19 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.19.1.tgz", - "integrity": "sha512-/iLa916Cw33vC6wgmCb4cPLjmvUA2zVviTx/vy80iEvpOHjoNkuHkGSsmvss1aItwUKUlHaLi3k0fK5OPiw1iA==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.0.0.tgz", + "integrity": "sha512-8JYdjizJKMUhEpaZ7SoVLQ+toe0XTebK/Zh/Iwwvs29x8Ml758XACX5Bn71LJK22u3obgu7YN2yn2GxZbQ554g==" }, "typescript": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", - "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==" + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==" }, "typescript-to-lua": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.3.4.tgz", - "integrity": "sha512-9NkUOSUd9tufvwCGiWJ6Z1edizYcECUfjdZJZfDRKTEXKIddbAdV3IFR6u5gxvYYRfXhfNV6IKvqHS2HxHFs6w==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.4.3.tgz", + "integrity": "sha512-oGJO1BqXKSxdfwavfOzthelxaQVAc7ykJ4Z/BF96nAWz35nmuLyv9FOSS132TgzLmV02859ndMuTYZtiVnN6jQ==", "requires": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index f8f8ea1..ea7c2fb 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,28 +1,24 @@ { "name": "kafkatorio-events-mod", - "version": "0.3.2", + "version": "0.4.0", "private": true, "scripts": { "build": "tstl", "dev": "tstl --watch" }, "engines": { - "node": ">=10.13.0" - }, - "devDependencies": { + "node": "~14.19.1" }, + "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", - "typescript-to-lua": "1.3.4", - "typed-factorio": "0.19.1", - "typescript": "4.6.2" + "typescript-to-lua": "1.4.3", + "typed-factorio": "1.0.0", + "typescript": "4.6.3" }, "// @types/node": "^12.0.8", "license": "UNLICENSED", - "peerDependencies": { - }, - "optionalDependencies": { - }, - "bundledDependencies": [ - ] + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] } diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index 178a5ce..d1d16e8 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -1,5 +1,6 @@ import dev.adamko.kafkatorio.gradle.asProvider import dev.adamko.kafkatorio.gradle.typescriptAttributes +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -11,6 +12,7 @@ plugins { kotlin { + js(IR) { binaries.executable() // browser{} causes this error: @@ -32,6 +34,11 @@ kotlin { nodejs() } jvm { + val main by compilations.getting { + kotlinOptions { + jvmTarget = "11" + } + } testRuns["test"].executionTask.configure { useJUnitPlatform() } @@ -56,6 +63,10 @@ kotlin { implementation(project.dependencies.platform(libs.kotlinx.serialization.bom)) implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.json) + api("dev.adamko.kxtsgen:kxs-ts-gen-core:dev-SNAPSHOT") +// implementation("com.github.adamko-dev:kotlinx-serialization-typescript-generator:dev-SNAPSHOT") { +// isChanging = true +// } } } @@ -76,7 +87,9 @@ kotlin { dependencies { implementation("com.github.aSemy:ts-generator:v1.2.1") // implementation("com.github.ntrrgc:ts-generator:1.1.2") - implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation(kotlin("reflect")) + +// implementation("com.github.adamko-dev:kotlinx-serialization-typescript-generator:0.0.5") } } @@ -105,7 +118,8 @@ val generateTypescript by tasks.registering(JavaExec::class) { main.runtimeDependencyFiles ) - mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2tsKt") +// mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2tsKt") + mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2ts2Kt") val tempOutputDirectory = file("$temporaryDir") args(tempOutputDirectory) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/positions.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/positions.kt deleted file mode 100644 index 2729233..0000000 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/positions.kt +++ /dev/null @@ -1,57 +0,0 @@ -package dev.adamko.kafkatorio.events.schema.converters - -import dev.adamko.kafkatorio.events.schema.MAP_CHUNK_SIZE -import dev.adamko.kafkatorio.events.schema.MapChunkPosition -import dev.adamko.kafkatorio.events.schema.MapEntityPosition -import dev.adamko.kafkatorio.events.schema.MapTilePosition -import kotlin.math.floor - -operator fun MapTilePosition.times(factor: Int) = - MapTilePosition(x * factor, y * factor) - -operator fun MapTilePosition.div(divisor: Int) = - MapTilePosition(x / divisor, y / divisor) - -operator fun MapTilePosition.plus(addend: Int) = - MapTilePosition(x + addend, y + addend) - - -fun MapTilePosition.toMapChunkPosition(chunkSize: Int = MAP_CHUNK_SIZE) = - MapChunkPosition( - floor(x.toDouble() / chunkSize.toDouble()).toInt(), - floor(y.toDouble() / chunkSize.toDouble()).toInt(), - ) - - -fun MapEntityPosition.toMapTilePosition() = - MapChunkPosition(floor(x).toInt(), floor(y).toInt()) - -fun MapEntityPosition.toMapChunkPosition(chunkSize: Int = MAP_CHUNK_SIZE) = - MapChunkPosition( - floor(x / chunkSize.toDouble()).toInt(), - floor(y / chunkSize.toDouble()).toInt(), - ) - - -operator fun MapChunkPosition.times(factor: Int) = - MapChunkPosition(x * factor, y * factor) - -operator fun MapChunkPosition.plus(addend: Int) = - MapChunkPosition(x + addend, y + addend) - -operator fun MapChunkPosition.minus(subtrahend: Int) = - MapChunkPosition(x - subtrahend, y - subtrahend) - - -fun MapChunkPosition.leftTopTile(chunkSize: Int = MAP_CHUNK_SIZE): MapTilePosition = - MapTilePosition( - x * chunkSize, - y * chunkSize, - ) - -//val MapChunkPosition.rightBottomTile: MapTilePosition -// get() = leftTopTile + (MAP_CHUNK_SIZE - 1) -// -// -//val MapChunkPosition.boundingBox: MapBoundingBox -// get() = MapBoundingBox(leftTopTile, rightBottomTile) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt deleted file mode 100644 index 4181a05..0000000 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioCommonData.kt +++ /dev/null @@ -1,158 +0,0 @@ -package dev.adamko.kafkatorio.events.schema - -import kotlin.jvm.JvmInline -import kotlinx.serialization.Serializable - - -const val MAP_CHUNK_SIZE = 32 - - -@Serializable -@JvmInline -value class Tick(val value: UInt) - - -/** - * Coordinates of a [EntityData] on a map. - * - * A [MapEntityPosition] can be translated to a [MapChunkPosition] by dividing the `x`/`y` values - * by [32][MAP_CHUNK_SIZE]. - */ -@Serializable -data class MapEntityPosition( - val x: Double, - val y: Double, -) - - -/** Coordinates of a chunk in a [SurfaceData] where each integer `x`/`y` represents a different - * chunk. - * - * A [MapChunkPosition] can be translated to a [MapEntityPosition] by multiplying the `x`/`y` - * values by [32][MAP_CHUNK_SIZE]. - */ -@Serializable -data class MapChunkPosition( - val x: Int, - val y: Int, -) - - -/** - * Coordinates of a tile in a chunk on a [SurfaceData] where each integer `x`/`y` represents a - * different [MapTile]. - * - * It rounds any `x`/`y` down to whole numbers. - */ -@Serializable -data class MapTilePosition( - val x: Int, - val y: Int, -) - - -@Serializable -data class MapBoundingBox( - val topLeft: MapTilePosition, - val bottomRight: MapTilePosition, -) - - -/** - * Red, green, blue and alpha values, all in range `[0, 1]` or all in range `[0, 255]` if any - * value is > 1. - * - * All values here are optional. Colour channels default to `0`, the alpha channel defaults to `1`. - */ -@Serializable -data class Colour( - val red: Float = 0f, - val green: Float = 0f, - val blue: Float = 0f, - val alpha: Float = 1f, -) - - -/** Size-efficient version of [Colour] (`4*4` bytes vs `4*1` bytes) */ -@Serializable -data class ColourHex( - val red: UByte = UByte.MIN_VALUE, - val green: UByte = UByte.MIN_VALUE, - val blue: UByte = UByte.MIN_VALUE, - val alpha: UByte = UByte.MAX_VALUE, -) { - companion object { - val TRANSPARENT = ColourHex(0u, 0u, 0u, 0u) - } -} - - -@Serializable -data class MapTiles( - val surfaceIndex: SurfaceIndex, - val tiles: List, -) - - -@Serializable -data class MapTile( - val x: Int, - val y: Int, - val proto: PrototypeName, -) - - -interface EntityIdentifiers { - val unitNumber: UnitNumber? - val name: String - val type: String -} - - -// instant of EntityIdentifiers, because kxs needs a concrete instance -@Serializable -data class EntityIdentifiersData( - override val unitNumber: UnitNumber? = null, - override val name: String, - /** The prototype-type of the entity. */ - override val type: String, -) : EntityIdentifiers - - -/** - * Size-optimised 2D map of x/y tile positions and prototype-name. - * - * Each X/Y coordinate maps to an arbitrary [PrototypeKey] (which is only valid for any specific - * instance). [protos] is specific to each instance of [MapTileDictionary], can be used to convert from a - */ -@Serializable -data class MapTileDictionary( - /** Map an X,Y coordinate a prototype name */ - val tilesXY: Map>, - val protos: Map, -) { - - fun toMapTileList(): List = buildList { - tilesXY.forEach { (xString, row) -> - row.forEach { (yString, protoIndex) -> - val x = xString.toIntOrNull() - val y = yString.toIntOrNull() - val protoName = protos[protoIndex] - if (x != null && y != null && protoName != null) { - add(MapTile(x, y, protoName)) - } - } - } - } - - companion object { - fun MapTileDictionary?.isNullOrEmpty(): Boolean { - return this == null || (tilesXY.isEmpty() && tilesXY.all { it.value.isEmpty() }) - } - } -} - - -@Serializable -@JvmInline -value class PrototypeKey(val index: String) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt deleted file mode 100644 index dbfbc21..0000000 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioEventUpdates.kt +++ /dev/null @@ -1,287 +0,0 @@ -package dev.adamko.kafkatorio.events.schema - -import dev.adamko.kafkatorio.events.schema.FactorioUpdateData.FactorioUpdateDataType -import kotlinx.serialization.DeserializationStrategy -import kotlinx.serialization.EncodeDefault -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.JsonContentPolymorphicSerializer -import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.contentOrNull -import kotlinx.serialization.json.jsonObject -import kotlinx.serialization.json.jsonPrimitive - - -@Serializable -sealed class KafkatorioPacket { - /** Schema versioning */ - abstract val modVersion: String - abstract val tick: Tick - abstract val update: FactorioUpdateData -} - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - -sealed interface FactorioUpdateDataKey { - val updateType: FactorioUpdateDataType -} - - -@Serializable(with = FactorioUpdateData.JsonSerializer::class) -sealed class FactorioUpdateData : FactorioUpdateDataKey { - - /** Discriminator for [FactorioUpdateData] */ - @EncodeDefault - abstract override val updateType: FactorioUpdateDataType - - /** the initial Factorio event (`defines.events`) trigger */ - abstract val eventCounts: Map? - - @Serializable - enum class FactorioUpdateDataType { - PLAYER, - MAP_CHUNK, - ENTITY, - CONSOLE_CHAT, - CONSOLE_COMMAND, - SURFACE, - CONFIG, - PROTOTYPES, - ; - - companion object { - val values: List = values().toList() - } - } - - object JsonSerializer : JsonContentPolymorphicSerializer( - FactorioUpdateData::class - ) { - private val key = FactorioUpdateData::updateType.name - - override fun selectDeserializer(element: JsonElement): DeserializationStrategy { - - val type = element - .jsonObject[key] - ?.jsonPrimitive - ?.contentOrNull - ?.let { json -> - FactorioUpdateDataType.values.firstOrNull { it.name == json } - } - - requireNotNull(type) { "Unknown FactorioEventUpdate $key: $element" } - - return when (type) { - FactorioUpdateDataType.PLAYER -> PlayerUpdate.serializer() - FactorioUpdateDataType.MAP_CHUNK -> MapChunkUpdate.serializer() - FactorioUpdateDataType.ENTITY -> EntityUpdate.serializer() - FactorioUpdateDataType.CONSOLE_CHAT -> ConsoleChatUpdate.serializer() - FactorioUpdateDataType.CONSOLE_COMMAND -> ConsoleCommandUpdate.serializer() - FactorioUpdateDataType.SURFACE -> SurfaceUpdate.serializer() - FactorioUpdateDataType.CONFIG -> ConfigurationUpdate.serializer() - FactorioUpdateDataType.PROTOTYPES -> PrototypesUpdate.serializer() - } - } - } -} - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - -sealed interface PlayerUpdateKey : FactorioUpdateDataKey { - val index: PlayerIndex -} - - -@Serializable -data class PlayerUpdate( - override val index: PlayerIndex, - - override val eventCounts: Map? = null, - - val characterUnitNumber: UnitNumber? = null, - val chatColour: Colour? = null, - val colour: Colour? = null, - val name: String? = null, - - val afkTime: Tick? = null, - val ticksToRespawn: Tick? = null, - val forceIndex: ForceIndex? = null, - val isAdmin: Boolean? = null, - val isConnected: Boolean? = null, - val isShowOnMap: Boolean? = null, - val isSpectator: Boolean? = null, - val lastOnline: Tick? = null, - val onlineTime: Tick? = null, - val position: MapEntityPosition? = null, - val surfaceIndex: SurfaceIndex? = null, - val tag: String? = null, - val diedCause: EntityIdentifiersData? = null, - - val bannedReason: String? = null, - val kickedReason: String? = null, - val disconnectReason: String? = null, - /** `true` when a player is removed (deleted) from the game */ - val isRemoved: Boolean? = null, -) : FactorioUpdateData(), PlayerUpdateKey { - @EncodeDefault - override val updateType: FactorioUpdateDataType = FactorioUpdateDataType.PLAYER -} - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - -sealed interface EntityUpdateKey : EntityIdentifiers, FactorioUpdateDataKey { - /** A [unitNumber] is required for caching */ - override val unitNumber: UnitNumber - override val name: String - override val type: String -} - - -@Serializable -data class EntityUpdate( - override val unitNumber: UnitNumber, - override val name: String, - override val type: String, - - override val eventCounts: Map? = null, - - val chunkPosition: MapChunkPosition? = null, - val graphicsVariation: UByte? = null, - val health: Float? = null, - val isActive: Boolean? = null, - val isRotatable: Boolean? = null, - val lastUser: UInt? = null, - val localisedDescription: String? = null, - val localisedName: String? = null, - val prototype: PrototypeName? = null, -) : FactorioUpdateData(), EntityUpdateKey { - @EncodeDefault - override val updateType: FactorioUpdateDataType = FactorioUpdateDataType.ENTITY -} - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - -sealed interface MapChunkUpdateKey : FactorioUpdateDataKey { - val chunkPosition: MapChunkPosition - val surfaceIndex: SurfaceIndex -} - - -@Serializable -data class MapChunkUpdate( - override val chunkPosition: MapChunkPosition, - override val surfaceIndex: SurfaceIndex, - - override val eventCounts: Map? = null, - - val player: PlayerIndex? = null, - val robot: EntityIdentifiersData? = null, - val force: ForceIndex? = null, - /** updated tiles - might be partial and not all tiles in the chunk */ - val tileDictionary: MapTileDictionary? = null, - val isDeleted: Boolean? = null, -) : FactorioUpdateData(), MapChunkUpdateKey { - @EncodeDefault - override val updateType: FactorioUpdateDataType = FactorioUpdateDataType.MAP_CHUNK -} - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - -@Serializable -data class ConsoleChatUpdate( - override val eventCounts: Map? = null, - - val authorPlayerIndex: PlayerIndex?, - val content: String, -) : FactorioUpdateData() { - @EncodeDefault - override val updateType: FactorioUpdateDataType = FactorioUpdateDataType.CONSOLE_CHAT - -} - -@Serializable -data class ConsoleCommandUpdate( - override val eventCounts: Map? = null, - - val authorPlayerIndex: PlayerIndex?, - val command: String, - val parameters: String, -) : FactorioUpdateData() { - @EncodeDefault - override val updateType: FactorioUpdateDataType = FactorioUpdateDataType.CONSOLE_COMMAND -} - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - -sealed interface SurfaceUpdateKey : FactorioUpdateDataKey { - val index: SurfaceIndex -} - -@Serializable -data class SurfaceUpdate( - override val index: SurfaceIndex, - - override val eventCounts: Map? = null, - - val daytime: Double, - val name: String, -) : FactorioUpdateData(), SurfaceUpdateKey { - @EncodeDefault - override val updateType: FactorioUpdateDataType = FactorioUpdateDataType.SURFACE -} - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - -@Serializable -data class ConfigurationUpdate( - override val eventCounts: Map? = null, - - val factorioData: GameData, - val allMods: List, -) : FactorioUpdateData() { - @EncodeDefault - override val updateType: FactorioUpdateDataType = FactorioUpdateDataType.CONFIG - - @Serializable - data class GameData( - val oldVersion: String? = null, - val newVersion: String? = null, - ) - - @Serializable - data class ModData( - val modName: String, - val currentVersion: String? = null, - val previousVersion: String? = null, - ) -} - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - -@Serializable -data class PrototypesUpdate( - override val eventCounts: Map? = null, - - val prototypes: List, -) : FactorioUpdateData() { - @EncodeDefault - override val updateType: FactorioUpdateDataType = FactorioUpdateDataType.PROTOTYPES -} - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/colour.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt similarity index 68% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/colour.kt rename to modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt index 845cfd0..dab6394 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/converters/colour.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt @@ -1,8 +1,38 @@ -package dev.adamko.kafkatorio.events.schema.converters +package dev.adamko.kafkatorio.schema.common -import dev.adamko.kafkatorio.events.schema.Colour -import dev.adamko.kafkatorio.events.schema.ColourHex import kotlin.math.roundToInt +import kotlinx.serialization.Serializable + +/** + * Red, green, blue and alpha values, all in range `[0, 1]` or all in range `[0, 255]` if any + * value is > 1. + * + * All values here are optional. Colour channels default to `0`, the alpha channel defaults to `1`. + */ +@Serializable +data class Colour( + val red: Float = 0f, + val green: Float = 0f, + val blue: Float = 0f, + val alpha: Float = 1f, +) + + +/** Size-efficient version of [Colour] (`4*4` bytes vs `4*1` bytes) */ +@Serializable +data class ColourHex( + val red: UByte = UByte.MIN_VALUE, + val green: UByte = UByte.MIN_VALUE, + val blue: UByte = UByte.MIN_VALUE, + val alpha: UByte = UByte.MAX_VALUE, +) { + companion object { + val TRANSPARENT = ColourHex(0u, 0u, 0u, 0u) + } +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** True if any value is greater than 1, so the values are hexadecimal. */ @@ -74,8 +104,10 @@ fun Colour.toHex(): ColourHex { ) } + private fun UByte.toPercentileFloat() = (this.toFloat() / ubyteMaxFloat).coerceIn(0f..1f) + fun ColourHex.toPercentile(): Colour { return Colour( red.toPercentileFloat(), diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioIds.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt similarity index 65% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioIds.kt rename to modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt index e8a9e90..c632ee2 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioIds.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt @@ -1,9 +1,14 @@ -package dev.adamko.kafkatorio.events.schema +package dev.adamko.kafkatorio.schema.common import kotlin.jvm.JvmInline import kotlinx.serialization.Serializable +@Serializable +@JvmInline +value class Tick(val value: UInt) + + /** * Unique ID associated with this surface * @@ -44,3 +49,20 @@ value class UnitNumber(private val id: UInt) { value class PrototypeName(private val id: String) { override fun toString(): String = id } + + +interface EntityIdentifiers { + val unitNumber: UnitNumber? + val name: String + /** The prototype-type of the entity. */ + val protoType: String +} + + +// instant of EntityIdentifiers, because kxs needs a concrete instance +@Serializable +data class EntityIdentifiersData( + override val unitNumber: UnitNumber? = null, + override val name: String, + override val protoType: String, +) : EntityIdentifiers diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt new file mode 100644 index 0000000..7073785 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt @@ -0,0 +1,75 @@ +package dev.adamko.kafkatorio.schema.common + +import dev.adamko.kafkatorio.schema.common.MapTileDictionary.PrototypeKey +import kotlin.jvm.JvmInline +import kotlinx.serialization.Serializable + + +const val MAP_CHUNK_SIZE = 32 + +@Serializable +data class MapTiles( + val surfaceIndex: SurfaceIndex, + val tiles: List, +) + + +@Serializable +data class MapTile( + val x: Int, + val y: Int, + val proto: PrototypeName, +) + + +/** + * 2D map of x/y tile positions and prototype-name, optimised for JSON size. + * + * [protos] is a one-to-one map between a [PrototypeName] and [PrototypeKey]. + * + * [PrototypeKey] is an arbitrary integer value, which maps to one [PrototypeName] only for a + * specific instance of [MapTileDictionary]. + * + * Each X/Y coordinate in [tilesXY] maps to a [PrototypeKey]. + */ +@Serializable +data class MapTileDictionary( + /** Map an X,Y coordinate a prototype name */ + val tilesXY: Map>, + val protos: Map, +) { + private val protosIndexToName: Map by lazy { + protos.entries.associate { (name, key) -> key to name } + } + + fun toMapTileList(): List = buildList { + tilesXY.forEach { (xString, row) -> + row.forEach { (yString, protoIndex) -> + val x = xString.toIntOrNull() + val y = yString.toIntOrNull() + val protoName = protosIndexToName[protoIndex] + if (x != null && y != null && protoName != null) { + add(MapTile(x, y, protoName)) + } + } + } + } + + /** The collection-index of a prototype in [MapTileDictionary.protos] */ + @Serializable + @JvmInline + value class PrototypeKey(val index: Int) + + companion object { + fun MapTileDictionary?.isNullOrEmpty(): Boolean { + return this == null || (tilesXY.isEmpty() && tilesXY.all { it.value.isEmpty() }) + } + } +} + + +@Serializable +data class MapBoundingBox( + val topLeft: MapTilePosition, + val bottomRight: MapTilePosition, +) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt new file mode 100644 index 0000000..f6a4463 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt @@ -0,0 +1,142 @@ +package dev.adamko.kafkatorio.schema.common + +import dev.adamko.kxstsgen.core.* +import dev.adamko.kxstsgen.core.experiments.TupleSerializer +import kotlin.math.floor +import kotlinx.serialization.Serializable + +/** + * Coordinates of a [EntityData] on a map. + * + * A [MapEntityPosition] can be translated to a [MapChunkPosition] by dividing the `x`/`y` values + * by [32][MAP_CHUNK_SIZE]. + */ +@Serializable(with = MapEntityPosition.Serializer::class) +data class MapEntityPosition( + val x: Double, + val y: Double, +) { + object Serializer : TupleSerializer( + "MapEntityPosition", + { + element(MapEntityPosition::x) + element(MapEntityPosition::y) + } + ) { + override fun tupleConstructor(elements: Iterator<*>): MapEntityPosition { + return MapEntityPosition( + elements.next() as Double, + elements.next() as Double, + ) + } + } +} + + +/** Coordinates of a chunk in a [SurfaceData] where each integer `x`/`y` represents a different + * chunk. + * + * A [MapChunkPosition] can be translated to a [MapEntityPosition] by multiplying the `x`/`y` + * values by [32][MAP_CHUNK_SIZE]. + */ +@Serializable(with = MapChunkPosition.Serializer::class) +data class MapChunkPosition( + val x: Int, + val y: Int, +) { + object Serializer : TupleSerializer( + "MapChunkPosition", + { + element(MapChunkPosition::x) + element(MapChunkPosition::y) + } + ) { + override fun tupleConstructor(elements: Iterator<*>): MapChunkPosition { + return MapChunkPosition( + elements.next() as Int, + elements.next() as Int, + ) + } + } +} + + +/** + * Coordinates of a tile in a chunk on a [SurfaceData] where each integer `x`/`y` represents a + * different [MapTile]. + * + * It rounds any `x`/`y` down to whole numbers. + */ +@Serializable(with = MapTilePosition.Serializer::class) +data class MapTilePosition( + val x: Int, + val y: Int, +) { + object Serializer : TupleSerializer( + "MapTilePosition", + { + element(MapTilePosition::x) + element(MapTilePosition::y) + } + ) { + override fun tupleConstructor(elements: Iterator<*>): MapTilePosition { + val x = requireNotNull(elements.next() as? Int) + val y = requireNotNull(elements.next() as? Int) + return MapTilePosition(x, y) + } + } +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +operator fun MapTilePosition.times(factor: Int) = + MapTilePosition(x * factor, y * factor) + +operator fun MapTilePosition.div(divisor: Int) = + MapTilePosition(x / divisor, y / divisor) + +operator fun MapTilePosition.plus(addend: Int) = + MapTilePosition(x + addend, y + addend) + + +fun MapTilePosition.toMapChunkPosition(chunkSize: Int = MAP_CHUNK_SIZE) = + MapChunkPosition( + floor(x.toDouble() / chunkSize.toDouble()).toInt(), + floor(y.toDouble() / chunkSize.toDouble()).toInt(), + ) + + +fun MapEntityPosition.toMapTilePosition() = + MapChunkPosition(floor(x).toInt(), floor(y).toInt()) + +fun MapEntityPosition.toMapChunkPosition(chunkSize: Int = MAP_CHUNK_SIZE) = + MapChunkPosition( + floor(x / chunkSize.toDouble()).toInt(), + floor(y / chunkSize.toDouble()).toInt(), + ) + + +operator fun MapChunkPosition.times(factor: Int) = + MapChunkPosition(x * factor, y * factor) + +operator fun MapChunkPosition.plus(addend: Int) = + MapChunkPosition(x + addend, y + addend) + +operator fun MapChunkPosition.minus(subtrahend: Int) = + MapChunkPosition(x - subtrahend, y - subtrahend) + + +fun MapChunkPosition.leftTopTile(chunkSize: Int = MAP_CHUNK_SIZE): MapTilePosition = + MapTilePosition( + x * chunkSize, + y * chunkSize, + ) + +//val MapChunkPosition.rightBottomTile: MapTilePosition +// get() = leftTopTile + (MAP_CHUNK_SIZE - 1) +// +// +//val MapChunkPosition.boundingBox: MapBoundingBox +// get() = MapBoundingBox(leftTopTile, rightBottomTile) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacket.kt new file mode 100644 index 0000000..0809d9a --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacket.kt @@ -0,0 +1,68 @@ +package dev.adamko.kafkatorio.schema.events + +import dev.adamko.kafkatorio.schema.SerializerProvider +import dev.adamko.kafkatorio.schema.SerializerProviderDeserializer +import dev.adamko.kafkatorio.schema.common.Tick +import kotlin.reflect.KClass +import kotlin.reflect.KType +import kotlin.reflect.typeOf +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable + + +//@Serializable +//data class KafkatorioPacket( +// val modVersion: String, +// val tick: Tick, +// val data: KafkatorioPacketData, +//) + + +@Serializable(with = KafkatorioPacketData.JsonSerializer::class) +sealed class KafkatorioPacketData { + abstract val updateType: KafkatorioPacketDataType + + object JsonSerializer : SerializerProviderDeserializer( + KafkatorioPacketData::class, + KafkatorioPacketData::updateType.name, + { json -> KafkatorioPacketDataType.entries.firstOrNull { it.name == json } } + ) +} + + +/** Discriminator for [KafkatorioPacketData] */ +@Serializable +enum class KafkatorioPacketDataType( + override val serializer: KSerializer +) : SerializerProvider { + + // non-keyed + CONFIG(ConfigurationUpdate.serializer()), + CONSOLE_CHAT(ConsoleChatUpdate.serializer()), + CONSOLE_COMMAND(ConsoleCommandUpdate.serializer()), + PROTOTYPES(PrototypesUpdate.serializer()), + SURFACE(SurfaceUpdate.serializer()), + + // keyed + ENTITY(EntityUpdate.serializer()), + MAP_CHUNK(MapChunkUpdate.serializer()), + PLAYER(PlayerUpdate.serializer()), + ; + + companion object { + val entries: Set = values().toSet() + } +} + +//inline fun KafkatorioPacketDataType.isType (): KClass { +// return when (this) { +// KafkatorioPacketDataType.CONFIG -> ConfigurationUpdate::class +// KafkatorioPacketDataType.CONSOLE_CHAT -> ConsoleChatUpdate::class +// KafkatorioPacketDataType.CONSOLE_COMMAND -> ConsoleCommandUpdate::class +// KafkatorioPacketDataType.PROTOTYPES -> PrototypesUpdate::class +// KafkatorioPacketDataType.SURFACE -> SurfaceUpdate::class +// KafkatorioPacketDataType.ENTITY -> EntityUpdate::class +// KafkatorioPacketDataType.MAP_CHUNK -> MapChunkUpdate::class +// KafkatorioPacketDataType.PLAYER -> PlayerUpdate::class +// } +//} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketInstant.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketInstant.kt new file mode 100644 index 0000000..c86f507 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketInstant.kt @@ -0,0 +1,95 @@ +package dev.adamko.kafkatorio.schema.events + +import dev.adamko.kafkatorio.schema.common.PlayerIndex +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype +import kotlinx.serialization.EncodeDefault +import kotlinx.serialization.Serializable + + +/** No key, no caching. Must be sent instantly. */ +sealed class KafkatorioInstantPacketData : KafkatorioPacketData() + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ + + +@Serializable +data class ConfigurationUpdate( + val factorioData: ConfigurationUpdateGameData, + val allMods: List, + val modStartupSettingsChange: Boolean, + val migrationApplied: Boolean, +) : KafkatorioInstantPacketData() { + @EncodeDefault + override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.CONFIG + + @Serializable + data class ConfigurationUpdateGameData( + val oldVersion: String? = null, + val newVersion: String? = null, + ) + + @Serializable + data class ConfigurationUpdateModData( + val modName: String, + val currentVersion: String? = null, + val previousVersion: String? = null, + ) +} + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ + + +@Serializable +data class ConsoleChatUpdate( + val authorPlayerIndex: PlayerIndex?, + val content: String, +) : KafkatorioInstantPacketData() { + @EncodeDefault + override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.CONSOLE_CHAT +} + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ + + +@Serializable +data class ConsoleCommandUpdate( + val authorPlayerIndex: PlayerIndex?, + val command: String, + val parameters: String, +) : KafkatorioInstantPacketData() { + @EncodeDefault + override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.CONSOLE_COMMAND +} + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ + + +@Serializable +data class PrototypesUpdate( + val prototypes: List, +) : KafkatorioInstantPacketData() { + @EncodeDefault + override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.PROTOTYPES +} + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ + + +@Serializable +data class SurfaceUpdate( + val index: SurfaceIndex, + val daytime: Double, + val name: String, +) : KafkatorioInstantPacketData() { + @EncodeDefault + override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.SURFACE +} + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketKeyed.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketKeyed.kt new file mode 100644 index 0000000..14d8551 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketKeyed.kt @@ -0,0 +1,135 @@ +package dev.adamko.kafkatorio.schema.events + +import dev.adamko.kafkatorio.schema.common.Colour +import dev.adamko.kafkatorio.schema.common.EntityIdentifiers +import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData +import dev.adamko.kafkatorio.schema.common.ForceIndex +import dev.adamko.kafkatorio.schema.common.MapChunkPosition +import dev.adamko.kafkatorio.schema.common.MapEntityPosition +import dev.adamko.kafkatorio.schema.common.MapTileDictionary +import dev.adamko.kafkatorio.schema.common.PlayerIndex +import dev.adamko.kafkatorio.schema.common.PrototypeName +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.common.Tick +import dev.adamko.kafkatorio.schema.common.UnitNumber +import kotlinx.serialization.EncodeDefault +import kotlinx.serialization.Serializable + + +sealed interface KafkatorioKeyedPacketKey + + +/** Has a key, so it can be debounced */ +sealed class KafkatorioKeyedPacketData : KafkatorioPacketData() { + /** Count how many events this packet is aggregating data from */ + abstract val eventCounts: Map? +} + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ + + +sealed interface EntityUpdateKey : EntityIdentifiers, KafkatorioKeyedPacketKey { + /** A [unitNumber] is required for caching */ + override val unitNumber: UnitNumber + override val name: String + override val protoType: String +} + + +@Serializable +data class EntityUpdate( + override val unitNumber: UnitNumber, + override val name: String, + override val protoType: String, + + override val eventCounts: Map? = null, + + val chunkPosition: MapChunkPosition? = null, + val graphicsVariation: UByte? = null, + val health: Float? = null, + val isActive: Boolean? = null, + val isRotatable: Boolean? = null, + val lastUser: UInt? = null, + val localisedDescription: String? = null, + val localisedName: String? = null, + val prototype: PrototypeName? = null, +) : KafkatorioKeyedPacketData(), EntityUpdateKey { + @EncodeDefault + override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.ENTITY +} + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ + + +sealed interface MapChunkUpdateKey : KafkatorioKeyedPacketKey { + val chunkPosition: MapChunkPosition + val surfaceIndex: SurfaceIndex +} + + +@Serializable +data class MapChunkUpdate( + override val chunkPosition: MapChunkPosition, + override val surfaceIndex: SurfaceIndex, + + override val eventCounts: Map? = null, + + val player: PlayerIndex? = null, + val robot: EntityIdentifiersData? = null, + val force: ForceIndex? = null, + /** updated tiles - might be partial and not all tiles in the chunk */ + val tileDictionary: MapTileDictionary? = null, + val isDeleted: Boolean? = null, +) : KafkatorioKeyedPacketData(), MapChunkUpdateKey { + @EncodeDefault + override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.MAP_CHUNK +} + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ + + +sealed interface PlayerUpdateKey : KafkatorioKeyedPacketKey { + val index: PlayerIndex +} + + +@Serializable +data class PlayerUpdate( + override val index: PlayerIndex, + + override val eventCounts: Map? = null, + + val characterUnitNumber: UnitNumber? = null, + val chatColour: Colour? = null, + val colour: Colour? = null, + val name: String? = null, + + val afkTime: Tick? = null, + val ticksToRespawn: Tick? = null, + val forceIndex: ForceIndex? = null, + val isAdmin: Boolean? = null, + val isConnected: Boolean? = null, + val isShowOnMap: Boolean? = null, + val isSpectator: Boolean? = null, + val lastOnline: Tick? = null, + val onlineTime: Tick? = null, + val position: MapEntityPosition? = null, + val surfaceIndex: SurfaceIndex? = null, + val tag: String? = null, + val diedCause: EntityIdentifiersData? = null, + + val bannedReason: String? = null, + val kickedReason: String? = null, + val disconnectReason: String? = null, + /** `true` when a player is removed (deleted) from the game */ + val isRemoved: Boolean? = null, +) : KafkatorioKeyedPacketData(), PlayerUpdateKey { + @EncodeDefault + override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.PLAYER +} + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/json.kt similarity index 57% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt rename to modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/json.kt index 93af18d..ea57da1 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/json.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/json.kt @@ -1,13 +1,19 @@ -package dev.adamko.kafkatorio.events.schema +package dev.adamko.kafkatorio.schema +import kotlin.reflect.KClass +import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.KSerializer import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.JsonContentPolymorphicSerializer import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonTransformingSerializer import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.contentOrNull +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.modules.SerializersModule @@ -44,3 +50,28 @@ class FactorioJsonListSerializer(dataSerializer: KSerializer) : } } + + +interface SerializerProvider { + val serializer: KSerializer +} + +open class SerializerProviderDeserializer( + private val baseClass: KClass, + private val key: String, + private val selector: (String) -> SerializerProvider?, +) : JsonContentPolymorphicSerializer(baseClass) { + + override fun selectDeserializer(element: JsonElement): DeserializationStrategy { + + val type = element + .jsonObject[key] + ?.jsonPrimitive + ?.contentOrNull + ?.let { json -> selector(json) } + + requireNotNull(type) { "Unknown ${baseClass.simpleName} $key: $element" } + + return type.serializer + } +} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt similarity index 50% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt rename to modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt index 063cbbd..775b664 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/events/schema/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt @@ -1,9 +1,14 @@ -package dev.adamko.kafkatorio.events.schema +package dev.adamko.kafkatorio.schema.prototypes -import dev.adamko.kafkatorio.events.schema.FactorioPrototype.PrototypeObjectName +import dev.adamko.kafkatorio.schema.SerializerProvider +import dev.adamko.kafkatorio.schema.SerializerProviderDeserializer +import dev.adamko.kafkatorio.schema.common.Colour +import dev.adamko.kafkatorio.schema.common.PrototypeName +import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.PrototypeObjectName import kotlinx.serialization.Contextual import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.EncodeDefault +import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonContentPolymorphicSerializer import kotlinx.serialization.json.JsonElement @@ -12,46 +17,30 @@ import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive - -@Serializable(with = FactorioPrototypeJsonSerializer::class) +@Serializable(with = FactorioPrototype.JsonSerializer::class) sealed class FactorioPrototype { @EncodeDefault abstract val prototypeObjectName: PrototypeObjectName - enum class PrototypeObjectName { - LuaTilePrototype, + enum class PrototypeObjectName( + override val serializer: KSerializer + ) : SerializerProvider { + LuaTilePrototype(MapTilePrototype.serializer()), ; companion object { - val values: List = values().toList() + val entries: Set = values().toSet() } } + + object JsonSerializer : SerializerProviderDeserializer( + FactorioPrototype::class, + FactorioPrototype::prototypeObjectName.name, + { json -> PrototypeObjectName.entries.firstOrNull { it.name == json } } + ) } -object FactorioPrototypeJsonSerializer : JsonContentPolymorphicSerializer( - FactorioPrototype::class -) { - private val key = FactorioPrototype::prototypeObjectName.name - - override fun selectDeserializer(element: JsonElement): DeserializationStrategy { - - val type = element - .jsonObject[key] - ?.jsonPrimitive - ?.contentOrNull - ?.let { json -> - PrototypeObjectName.values.firstOrNull { it.name == json } - } - - requireNotNull(type) { "Unknown FactorioPrototype ${key}: $element" } - - return when (type) { - PrototypeObjectName.LuaTilePrototype -> MapTilePrototype.serializer() - } - } -} - @Serializable data class MapTilePrototype( diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes2.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes2.kt new file mode 100644 index 0000000..3769128 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes2.kt @@ -0,0 +1,23 @@ +package dev.adamko.kafkatorio.schema.prototypes + +import dev.adamko.kafkatorio.schema.common.Colour +import dev.adamko.kafkatorio.schema.common.PrototypeName +import kotlinx.serialization.Contextual +import kotlinx.serialization.Serializable + + +@Serializable +sealed class FactorioPrototype2 { + + @Serializable + data class MapTile( + val name: PrototypeName, + val layer: UInt, + val mapColour: Colour, + @Contextual + val collisionMasks: List, + val order: String, + /** Can the tile be mined for resources? */ + val canBeMined: Boolean, + ) : FactorioPrototype2() +} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacket2.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacket2.kt new file mode 100644 index 0000000..8149322 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacket2.kt @@ -0,0 +1,16 @@ +package dev.adamko.kafkatorio.schema2 + +import dev.adamko.kafkatorio.schema.common.Tick +import kotlinx.serialization.Serializable + + +@Serializable +data class KafkatorioPacket2( + val modVersion: String, + val tick: Tick, + val data: KafkatorioPacketData2, +) + + +@Serializable +sealed class KafkatorioPacketData2 diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketInstant2.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketInstant2.kt new file mode 100644 index 0000000..fe75146 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketInstant2.kt @@ -0,0 +1,70 @@ +package dev.adamko.kafkatorio.schema2 + +import dev.adamko.kafkatorio.schema.common.PlayerIndex +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype +import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2 +import kotlinx.serialization.Serializable + + +/** No key, no caching. Must be sent instantly. */ +@Serializable +sealed class KafkatorioInstantPacketData2 : KafkatorioPacketData2() + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ + + +@Serializable +data class ConfigurationUpdate( + val factorioData: ConfigurationUpdateGameData, + val allMods: List, + val modStartupSettingsChange: Boolean, + val migrationApplied: Boolean, +) : KafkatorioInstantPacketData2() { + + @Serializable + data class ConfigurationUpdateGameData( + val oldVersion: String? = null, + val newVersion: String? = null, + ) + + @Serializable + data class ConfigurationUpdateModData( + val modName: String, + val currentVersion: String? = null, + val previousVersion: String? = null, + ) +} + + +@Serializable +data class ConsoleChatUpdate( + val authorPlayerIndex: PlayerIndex?, + val content: String, +) : KafkatorioInstantPacketData2() + + +@Serializable +data class ConsoleCommandUpdate( + val authorPlayerIndex: PlayerIndex?, + val command: String, + val parameters: String, +) : KafkatorioInstantPacketData2() + + +@Serializable +data class PrototypesUpdate( + val prototypes: List, +) : KafkatorioInstantPacketData2() + + +@Serializable +data class SurfaceUpdate( + val index: SurfaceIndex, + val daytime: Double, + val name: String, +) : KafkatorioInstantPacketData2() + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketKeyed2.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketKeyed2.kt new file mode 100644 index 0000000..2b08157 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketKeyed2.kt @@ -0,0 +1,126 @@ +package dev.adamko.kafkatorio.schema2 + +import dev.adamko.kafkatorio.schema.common.Colour +import dev.adamko.kafkatorio.schema.common.EntityIdentifiers +import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData +import dev.adamko.kafkatorio.schema.common.ForceIndex +import dev.adamko.kafkatorio.schema.common.MapChunkPosition +import dev.adamko.kafkatorio.schema.common.MapEntityPosition +import dev.adamko.kafkatorio.schema.common.MapTileDictionary +import dev.adamko.kafkatorio.schema.common.PlayerIndex +import dev.adamko.kafkatorio.schema.common.PrototypeName +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.common.Tick +import dev.adamko.kafkatorio.schema.common.UnitNumber +import kotlinx.serialization.Serializable + + +/** Has a key, so it can be debounced */ +@Serializable +sealed class KafkatorioKeyedPacketData2 : KafkatorioPacketData2() { + /** Count how many events this packet is aggregating data from */ + abstract val key: KafkatorioKeyedPacketKey2 + abstract val eventCounts: Map? +} + +@Serializable +sealed class KafkatorioKeyedPacketKey2 + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ + + +@Serializable +data class EntityUpdateKey( + /** While normally optional, here a [unitNumber] is required for caching */ + override val unitNumber: UnitNumber, + override val name: String, + override val protoType: String, +) : EntityIdentifiers, KafkatorioKeyedPacketKey2() + + +@Serializable +data class EntityUpdate( + override val key: EntityUpdateKey, + + override val eventCounts: Map? = null, + + val chunkPosition: MapChunkPosition? = null, + val graphicsVariation: UByte? = null, + val health: Float? = null, + val isActive: Boolean? = null, + val isRotatable: Boolean? = null, + val lastUser: UInt? = null, + val localisedDescription: String? = null, + val localisedName: String? = null, + val prototype: PrototypeName? = null, +) : KafkatorioKeyedPacketData2() + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ + + +@Serializable +data class MapChunkUpdateKey( + val chunkPosition: MapChunkPosition, + val surfaceIndex: SurfaceIndex, +) : KafkatorioKeyedPacketKey2() + + +@Serializable +data class MapChunkUpdate( + override val key: MapChunkUpdateKey, + + override val eventCounts: Map? = null, + + val player: PlayerIndex? = null, + val robot: EntityIdentifiersData? = null, + val force: ForceIndex? = null, + /** updated tiles - might be partial and not all tiles in the chunk */ + val tileDictionary: MapTileDictionary? = null, + val isDeleted: Boolean? = null, +) : KafkatorioKeyedPacketData2() + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ + +@Serializable +data class PlayerUpdateKey( + val index: PlayerIndex, +) : KafkatorioKeyedPacketKey2() + + +@Serializable +data class PlayerUpdate( + override val key: PlayerUpdateKey, + + override val eventCounts: Map? = null, + + val characterUnitNumber: UnitNumber? = null, + val chatColour: Colour? = null, + val colour: Colour? = null, + val name: String? = null, + + val afkTime: Tick? = null, + val ticksToRespawn: Tick? = null, + val forceIndex: ForceIndex? = null, + val isAdmin: Boolean? = null, + val isConnected: Boolean? = null, + val isShowOnMap: Boolean? = null, + val isSpectator: Boolean? = null, + val lastOnline: Tick? = null, + val onlineTime: Tick? = null, + val position: MapEntityPosition? = null, + val surfaceIndex: SurfaceIndex? = null, + val tag: String? = null, + val diedCause: EntityIdentifiersData? = null, + + val bannedReason: String? = null, + val kickedReason: String? = null, + val disconnectReason: String? = null, + /** `true` when a player is removed (deleted) from the game */ + val isRemoved: Boolean? = null, +) : KafkatorioKeyedPacketData2() + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt index beaf512..e0c02e5 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt @@ -1,7 +1,10 @@ package dev.adamko.kafkatorio.events.schema -import dev.adamko.kafkatorio.events.schema.converters.toHex -import dev.adamko.kafkatorio.events.schema.converters.toPercentile +import dev.adamko.kafkatorio.schema.common.Colour +import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.toHex +import dev.adamko.kafkatorio.schema.common.toPercentile +import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio import io.kotest.assertions.withClue import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.floats.shouldBeWithinPercentageOf @@ -81,6 +84,4 @@ class ColourHexTest : BehaviorSpec({ } } - - }) diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt deleted file mode 100644 index ce48c8a..0000000 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/FactorioEventTest.kt +++ /dev/null @@ -1,342 +0,0 @@ -package dev.adamko.kafkatorio.events.schema - -import io.kotest.assertions.json.shouldEqualJson -import io.kotest.core.spec.style.FunSpec -import io.kotest.matchers.shouldBe -import kotlinx.serialization.decodeFromString -import kotlinx.serialization.encodeToString - -class FactorioEventTest : FunSpec({ - -// context("Given: json on_player_joined_game") { -// -// // language=JSON -// val json = """ -// { -// "data": { -// "objectName": "LuaPlayer", -// "force": 1, -// "surface": 1, -// "name": "fredthedeadhead", -// "characterUnitNumber": 1, -// "associatedCharactersUnitNumbers": {}, -// "position": { -// "x": 30.6, -// "y": 84.1 -// }, -// "colour": { -// "red": 0.86, -// "green": 0.5, -// "blue": 0.12, -// "alpha": 0.5 -// }, -// "chatColour": { -// "red": 1, -// "green": 0.62, -// "blue": 0.25 -// }, -// "lastOnline": 2287061 -// }, -// "packetType": "EVENT", -// "eventType": "on_player_joined_game", -// "modVersion": "0.2.1", -// "tick": 2287072 -// } -// """.trimIndent() -// context("When: decoded") { -// val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) -// -// test("Then: parse") { -// -// val expected = FactorioEvent( -// data = PlayerData( -// name = "fredthedeadhead", -// surface = SurfaceIndex(1u), -// force = ForceIndex(1u), -// characterUnitNumber = UnitNumber(1u), -// associatedCharactersUnitNumbers = emptyList(), -// position = MapEntityPosition( -// x = 30.6, -// y = 84.1, -// ), -// colour = Colour( -// red = 0.86f, -// green = 0.5f, -// blue = 0.12f, -// alpha = 0.5f -// ), -// chatColour = Colour( -// red = 1f, -// green = 0.62f, -// blue = 0.25f, -// alpha = 1f -// ), -// lastOnline = Tick(2287061u) -// ), -// eventType = "on_player_joined_game", -// modVersion = "0.2.1", -// tick = Tick(2287072u) -// ) -// -// actual shouldBe expected -// -// expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaPlayer -// } -// -// test("Then: expect encode equals json") { -// val encoded = jsonMapperKafkatorio.encodeToString(actual) -// encoded.shouldEqualJson(json) -// } -// } -// } -// -// context("Given: json LuaSurface") { -// // language=JSON -// val json = """ -// { -// "data": { -// "objectName": "LuaSurface", -// "name": "nauvis", -// "index": 1, -// "daytime": 0.745 -// }, -// "packetType": "EVENT", -// "eventType": "on_tick", -// "modVersion": "0.2.1", -// "tick": 2301240 -// } -// """.trimIndent() -// -// context("When: decoded") { -// val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) -// -// test("should equal obj") { -// -// val expected = FactorioEvent( -// data = SurfaceData( -// name = "nauvis", -// index = SurfaceIndex(1u), -// daytime = 0.745 -// ), -// eventType = "on_tick", -// modVersion = "0.2.1", -// tick = Tick(2301240u) -// ) -// -// actual shouldBe expected -// -// expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaSurface -// } -// -// test("Then: expect encode equals json") { -// val encoded = jsonMapperKafkatorio.encodeToString(actual) -// encoded.shouldEqualJson(json) -// } -// } -// } -// -// context("Given: LuaEntity on_player_changed_position") { -// // language=JSON -// val json = """ -// { -// "data": { -// "objectName": "LuaEntity", -// "name": "character", -// "type": "character", -// "active": true, -// "health": 250, -// "healthRatio": 1, -// "surface": 1, -// "force": 1, -// "unitNumber": 1, -// "position": { -// "x": 37.5, -// "y": 81.1 -// } -// }, -// "packetType": "EVENT", -// "eventType": "on_player_changed_position", -// "modVersion": "0.2.1", -// "tick": 2301231 -// } -// """.trimIndent() -// context("When: decoded") { -// val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) -// -// test("parse") { -// -// val expected = FactorioEvent( -// data = EntityData( -// name = "character", -// type = "character", -// active = true, -// health = 250.0, -// healthRatio = 1.0, -// surface = SurfaceIndex(1u), -// unitNumber = UnitNumber(1u), -// force = ForceIndex(1u), -// playerIndex = null, -// position = MapEntityPosition( -// x = 37.5, -// y = 81.1, -// ) -// ), -// eventType = "on_player_changed_position", -// modVersion = "0.2.1", -// tick = Tick(2301231u) -// ) -// -// actual shouldBe expected -// -// expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaEntity -// } -// -// test("Then: expect encode equals json") { -// val encoded = jsonMapperKafkatorio.encodeToString(actual) -// encoded.shouldEqualJson(json) -// } -// } -// -// } -// -// context("Given: LuaTiles on_player_built_tile") { -// // language=JSON -// val json = """ -// { -// "data": { -// "objectName": "LuaTiles", -// "surfaceIndex": 1, -// "tiles": [ -// { -// "y": 10, -// "x": -65, -// "proto": "refined-concrete" -// }, -// { -// "y": 11, -// "x": -65, -// "proto": "red-earth" -// }, -// { -// "y": 10, -// "x": -64, -// "proto": "blue-cheese" -// }, -// { -// "y": 11, -// "x": -64, -// "proto": "refined-concrete" -// } -// ] -// }, -// "packetType": "EVENT", -// "eventType": "on_player_built_tile", -// "modVersion": "0.2.2", -// "tick": 2429929 -// } -// """.trimIndent() -// context("When: decoded") { -// val actual: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) -// -// test("parse") { -// -// val expected = FactorioEvent( -// data = MapTiles( -// surfaceIndex = SurfaceIndex(1u), -// tiles = listOf( -// MapTile( -// proto = PrototypeName("refined-concrete"), -// x = -65, -// y = 10, -// ), -// MapTile( -// proto = PrototypeName("red-earth"), -// x = -65, -// y = 11, -// ), -// MapTile( -// proto = PrototypeName("blue-cheese"), -// x = -64, -// y = 10, -// ), -// MapTile( -// proto = PrototypeName("refined-concrete"), -// x = -64, -// y = 11, -// ), -// ) -// ), -// eventType = "on_player_built_tile", -// modVersion = "0.2.2", -// tick = Tick(2429929u) -// ) -// -// actual shouldBe expected -// -// expected.data.objectName shouldBe FactorioObjectData.ObjectName.LuaTiles -// } -// -// test("Then: expect encode equals json") { -// val encoded = jsonMapperKafkatorio.encodeToString(actual) -// encoded.shouldEqualJson(json) -// } -// } -// } -// -// context("Given: packet FactorioConfigurationUpdate") { -// // language=JSON -// val json = """ -// { -// "modVersion": "0.2.8", -// "packetType": "CONFIG", -// "tick": 534, -// "allMods": [ -// { -// "modName": "kafkatorio-events", -// "currentVersion": "0.2.8", -// "previousVersion": "0.2.7" -// }, -// { -// "modName": "base", -// "currentVersion": "1.1.53" -// } -// ], -// "factorioData": {} -// } -// """.trimIndent() -// context("When: decoded") { -// val actual: FactorioConfigurationUpdate = jsonMapperKafkatorio.decodeFromString(json) -// -// test("parse") { -// -// val expected = FactorioConfigurationUpdate( -// modVersion = "0.2.8", -// tick = Tick(534u), -// factorioData = FactorioGameDataUpdate(null, null), -// allMods = listOf( -// FactorioModInfo( -// modName = "kafkatorio-events", -// currentVersion = "0.2.8", -// previousVersion = "0.2.7" -// ), -// FactorioModInfo( -// modName = "base", -// currentVersion = "1.1.53", -// previousVersion = null -// ), -// ) -// ) -// -// actual shouldBe expected -// -// expected.packetType shouldBe KafkatorioPacket.PacketType.CONFIG -// } -// -// test("Then: expect encode equals json") { -// val encoded = jsonMapperKafkatorio.encodeToString(actual) -// encoded.shouldEqualJson(json) -// } -// } -// -// } -}) diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt new file mode 100644 index 0000000..4bf7bea --- /dev/null +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt @@ -0,0 +1,93 @@ +package dev.adamko.kafkatorio.events.schema + +import dev.adamko.kafkatorio.schema.common.MapChunkPosition +import dev.adamko.kafkatorio.schema.common.MapTileDictionary +import dev.adamko.kafkatorio.schema.common.PrototypeName +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.common.Tick +import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio +import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 +import dev.adamko.kafkatorio.schema2.MapChunkUpdate +import dev.adamko.kafkatorio.schema2.MapChunkUpdateKey +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.shouldBe +import kotlin.math.exp +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString + +class MapChunkUpdateTest : FunSpec({ + + context("MapChunkUpdate update") { + //language=json + val json = """ +{ + "data": { + "type": "dev.adamko.kafkatorio.schema2.MapChunkUpdate", + "key": { + "surfaceIndex": 1, + "chunkPosition": [ + -6, + -3 + ] + }, + "tileDictionary": { + "tilesXY": { + "-192": { + "-65": 2 + }, + "161": { + "-96": 1, + "-95": 2, + "94": 2, + "93": 32 + } + }, + "protos": { + "water": 1, + "grass-4": 2, + "grass-3": 32 + } + }, + "eventCounts": { + "on_chunk_generated": 1 + } + }, + "modVersion": "0.4.0", + "tick": 36 +} + """.trimIndent() + + val expected = KafkatorioPacket2( + tick = Tick(36u), + modVersion = "0.4.0", + data = MapChunkUpdate( + key = MapChunkUpdateKey( + MapChunkPosition(-6, -3), + SurfaceIndex(1u), + ), + eventCounts = mapOf("on_chunk_generated" to 1u), + tileDictionary = MapTileDictionary( + tilesXY = mapOf( + "-192" to mapOf("-65" to MapTileDictionary.PrototypeKey(2)), + "161" to mapOf( + "-96" to MapTileDictionary.PrototypeKey(1), + "-95" to MapTileDictionary.PrototypeKey(2), + "94" to MapTileDictionary.PrototypeKey(2), + "93" to MapTileDictionary.PrototypeKey(32), + ), + ), + protos = mapOf( + PrototypeName("water") to MapTileDictionary.PrototypeKey(1), + PrototypeName("grass-4") to MapTileDictionary.PrototypeKey(2), + PrototypeName("grass-3") to MapTileDictionary.PrototypeKey(32), + ) + ) + ) + ) + + test("decode") { + val packet: KafkatorioPacket2 = jsonMapperKafkatorio.decodeFromString(json) + packet shouldBe expected + } + } +}) diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt new file mode 100644 index 0000000..720c405 --- /dev/null +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt @@ -0,0 +1,42 @@ +package dev.adamko.kafkatorio.schema.common + +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.collections.shouldContainAll + +class MapTileDictionaryTest : FunSpec({ + + context("MapTileDictionary") { + val actual = MapTileDictionary( + tilesXY = mapOf( + "-192" to mapOf("-65" to MapTileDictionary.PrototypeKey(2)), + "161" to mapOf( + "-96" to MapTileDictionary.PrototypeKey(1), + "-95" to MapTileDictionary.PrototypeKey(2), + "94" to MapTileDictionary.PrototypeKey(2), + "93" to MapTileDictionary.PrototypeKey(32), + ), + + // unknown prototype + "44" to mapOf("1" to MapTileDictionary.PrototypeKey(44)), + ), + protos = mapOf( + PrototypeName("water") to MapTileDictionary.PrototypeKey(1), + PrototypeName("grass-4") to MapTileDictionary.PrototypeKey(2), + PrototypeName("grass-3") to MapTileDictionary.PrototypeKey(32), + + PrototypeName("not-used") to MapTileDictionary.PrototypeKey(99), + ) + ) + + test("toMapTileList") { + actual.toMapTileList() shouldContainAll listOf( + MapTile(-192, -65, PrototypeName("grass-4")), + + MapTile(161, -96, PrototypeName("water")), + MapTile(161, -95, PrototypeName("grass-4")), + MapTile(161, 94, PrototypeName("grass-4")), + MapTile(161, 93, PrototypeName("grass-3")), + ) + } + } +}) diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt index 3a04314..22a3aef 100644 --- a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt @@ -1,5 +1,10 @@ package dev.adamko.kafkatorio.events.schema +import dev.adamko.kafkatorio.schema.events.KafkatorioInstantPacketData +import dev.adamko.kafkatorio.schema.events.KafkatorioKeyedPacketData +import dev.adamko.kafkatorio.schema.events.KafkatorioKeyedPacketKey +//import dev.adamko.kafkatorio.schema.events.KafkatorioPacket +import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype import kotlin.io.path.Path import kotlin.io.path.createDirectories import me.ntrrgc.tsGenerator.TypeScriptGenerator @@ -10,40 +15,38 @@ import org.intellij.lang.annotations.Language */ fun main(args: Array) { - val gen = - TypeScriptGenerator( - rootClasses = buildSet { - addAll(KafkatorioPacket::class.sealedSubclasses) + val gen = TypeScriptGenerator( + rootClasses = buildSet { +// add(KafkatorioPacket::class) +// addAll(KafkatorioPacket::class.sealedSubclasses) - addAll(FactorioObjectData::class.sealedSubclasses) + add(KafkatorioInstantPacketData::class) + addAll(KafkatorioInstantPacketData::class.sealedSubclasses) - addAll(FactorioPrototype::class.sealedSubclasses) - add(FactorioPrototypes::class) - add(FactorioConfigurationUpdate::class) + add(KafkatorioKeyedPacketData::class) + addAll(KafkatorioKeyedPacketData::class.sealedSubclasses) + addAll(KafkatorioKeyedPacketKey::class.sealedSubclasses) - add(FactorioEvent::class) - - add(FactorioEventUpdatePacket::class) - addAll(FactorioEventUpdate::class.sealedSubclasses) - addAll(FactorioEventUpdateKey::class.sealedSubclasses) - }, - mappings = mapOf( - // builtin Factorio numeric types > `typed-factorio/generated/builtin-types.d.ts` - Float::class to "float", - Double::class to "double", - Int::class to "int", - Byte::class to "int8", - UInt::class to "uint", - UByte::class to "uint8", - UShort::class to "uint16", - ULong::class to "uint64", - ), - classTransformers = listOf( - ValueClassTransformer, + add(FactorioPrototype::class) + addAll(FactorioPrototype::class.sealedSubclasses) + }, + mappings = mapOf( + // builtin Factorio numeric types > `typed-factorio/generated/builtin-types.d.ts` + Float::class to "float", + Double::class to "double", + Int::class to "int", + Byte::class to "int8", + UInt::class to "uint", + UByte::class to "uint8", + UShort::class to "uint16", + ULong::class to "uint64", + ), + classTransformers = listOf( + ValueClassTransformer, // PropertyNameTransformer, - ), + ), // voidType = VoidType.UNDEFINED, - ) + ) val definitions = gen.definitionsText @@ -57,7 +60,7 @@ fun main(args: Array) { .forEach { (defFile, def) -> val outFile = outPath.resolve(defFile).toFile() outFile.printWriter().use { - it.println(header) + it.println(kt2tsHeader) it.print(def) } println("Generated file: $outFile") @@ -67,6 +70,7 @@ fun main(args: Array) { } } + /** Split the TypeScript interfaces into different files */ private fun splitDefinitions(definitions: String): Map { return definitions @@ -74,51 +78,64 @@ private fun splitDefinitions(definitions: String): Map { .groupBy { def -> when { + def isInterface "KafkatorioPacket" + || def extendsAny listOf("KafkatorioPacket") + || def isType "KafkatorioPacketDataType" + -> "kafkatorio-packet.d.ts" - "interface FactorioObjectData " in def || - "type ObjectName " in def || - def.contains(Regex("interface.+extends.+(FactorioObjectData).*")) - -> "object-data.d.ts" + def isInterface "KafkatorioInstantPacketData" + || def extends "KafkatorioInstantPacketData" + || def isType "KafkatorioInstantPacketDataType" - "extends FactorioPrototype " in def || - "interface FactorioPrototypes " in def || - "interface FactorioPrototype " in def || - "type PrototypeObjectName " in def -> "prototype.d.ts" + || def isInterface "ConfigurationUpdateGameData" + || def isInterface "ConfigurationUpdateModData" + -> "kafkatorio-instant-packet.d.ts" - "extends FactorioConfigurationUpdate " in def || - "interface FactorioConfigurationUpdate " in def || - "FactorioGameDataUpdate " in def || - "FactorioModInfo " in def -> "config-update.d.ts" + def isInterface "KafkatorioKeyedPacket" + || def isInterface "KafkatorioKeyedPacketData" + || def extends "KafkatorioKeyedPacket" + || def isType "KafkatorioKeyedPacketDataType" - "interface FactorioEventUpdatePacket" in def || - "type FactorioEventUpdateType =" in def || - "interface FactorioEventUpdateKey {" in def || - "interface FactorioEventUpdateData {" in def || - def.contains( - Regex( - """ - interface.+extends.+(FactorioEventUpdate|PlayerUpdateKey|PlayerUpdateData).* - """.trimIndent() - ) - ) - -> "update.d.ts" + || def isInterface "KafkatorioKeyedPacketKey" + -> "kafkatorio-keyed-packet.d.ts" - else -> "schema.d.ts" + def isInterface "FactorioPrototypes" + || def isInterface "FactorioPrototype" + || def extends "FactorioPrototype" + || def isType "PrototypeObjectName" + -> "prototype.d.ts" + + else -> "schema.d.ts" } } .mapValues { (_, def) -> def + .sorted() .joinToString("\n\n", postfix = "\n") .replace(" ", " ") } } @Language("TypeScript") -val header = """ +val kt2tsHeader = """ |// Generated by TypeScriptGenerator - do not edit this file manually | """.trimMargin() +private infix fun String.extends(types: String): Boolean = + contains(Regex(".+extends.*(${types})")) + +private infix fun String.extendsAny(types: List): Boolean = + extends(types.joinToString("|") { "$it,".replaceAfterLast(',', "") }) + +private infix fun String.isInterface(type: String): Boolean = + contains(Regex("interface $type.*")) + + +private infix fun String.isType(type: String): Boolean = + contains(Regex("type $type.*")) + + //object PropertyNameTransformer : ClassTransformer { // override fun transformPropertyName( // propertyName: String, diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt new file mode 100644 index 0000000..38b03e3 --- /dev/null +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt @@ -0,0 +1,55 @@ +package dev.adamko.kafkatorio.events.schema + +import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 +import dev.adamko.kxstsgen.KxsTsConfig +import dev.adamko.kxstsgen.KxsTsGenerator +import dev.adamko.kxstsgen.core.TsDeclaration.TsTypeAlias +import dev.adamko.kxstsgen.core.TsElementId +import dev.adamko.kxstsgen.core.TsLiteral +import dev.adamko.kxstsgen.core.TsTypeRef +import kotlin.io.path.Path +import kotlin.io.path.createDirectories +import kotlinx.serialization.builtins.serializer + + +@ExperimentalUnsignedTypes +fun main(args: Array) { + + val config = KxsTsConfig( +// typeAliasTyping = BrandTyping + ) + + val gen2 = KxsTsGenerator(config) + + gen2.descriptorOverrides += mapOf( +//@formatter:off + Float .serializer().descriptor to TsTypeAlias(TsElementId("kotlin.Float" ), TsTypeRef.Literal(TsLiteral.Custom("float" ), false)), + Double.serializer().descriptor to TsTypeAlias(TsElementId("kotlin.Double"), TsTypeRef.Literal(TsLiteral.Custom("double"), false)), + Int .serializer().descriptor to TsTypeAlias(TsElementId("kotlin.Int" ), TsTypeRef.Literal(TsLiteral.Custom("int" ), false)), + Byte .serializer().descriptor to TsTypeAlias(TsElementId("kotlin.Byte" ), TsTypeRef.Literal(TsLiteral.Custom("int8" ), false)), + UInt .serializer().descriptor to TsTypeAlias(TsElementId("kotlin.UInt" ), TsTypeRef.Literal(TsLiteral.Custom("uint" ), false)), + UByte .serializer().descriptor to TsTypeAlias(TsElementId("kotlin.UByte" ), TsTypeRef.Literal(TsLiteral.Custom("uint8" ), false)), + UShort.serializer().descriptor to TsTypeAlias(TsElementId("kotlin.UShort"), TsTypeRef.Literal(TsLiteral.Custom("uint16"), false)), + ULong .serializer().descriptor to TsTypeAlias(TsElementId("kotlin.ULong" ), TsTypeRef.Literal(TsLiteral.Custom("uint64"), false)), +//@formatter:on + ) + + val definitions = gen2.generate( + KafkatorioPacket2.serializer(), +// KafkatorioKeyedPacketKey2.serializer(), + ) + + + when (val filename = args.firstOrNull()) { + null -> println(definitions) + else -> { + val outPath = Path(filename) + outPath.createDirectories() + val outFile = outPath.resolve("kafkatorio-schema.ts").toFile() + outFile.printWriter().use { + it.println(kt2tsHeader) + it.print(definitions) + } + } + } +} diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index b035f7c..581dd35 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -41,6 +41,9 @@ dependencies { implementation(libs.scrimage.core) + implementation(platform(libs.okio.bom)) + implementation(libs.okio.core) + implementation(libs.kafka.kotkaStreams) { isChanging = true } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index fbe99ee..dd6bc5e 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -7,9 +7,9 @@ import dev.adamko.kafkatorio.processor.topology.playerUpdatesToWsServer import dev.adamko.kafkatorio.processor.topology.saveMapTiles import dev.adamko.kafkatorio.processor.topology.splitFactorioServerPacketStream import java.time.Duration +import java.util.Properties import kotlin.coroutines.CoroutineContext import kotlin.coroutines.cancellation.CancellationException -import kotlin.time.Duration.Companion.minutes import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -31,15 +31,12 @@ internal class KafkatorioTopology( override val coroutineContext: CoroutineContext = Dispatchers.Default + SupervisorJob() + CoroutineName("KafkatorioTopology") - companion object { - const val TOPIC_SRC_SERVER_LOG = "factorio-server-log" - const val TOPIC_GROUPED_MAP_CHUNKS = "kafkatorio.MAP.grouped-map-chunks" - } - fun start() { + splitPackets() + groupTilesMapChunks() saveTiles() - splitPackets() + playerUpdates() } @@ -56,7 +53,6 @@ internal class KafkatorioTopology( } private fun splitPackets() { - val builder = StreamsBuilder() val packets = factorioServerPacketStream(builder) splitFactorioServerPacketStream(packets) @@ -75,12 +71,19 @@ internal class KafkatorioTopology( launchTopology("playerUpdates", topology) } - private fun launchTopology(id: String, topology: Topology) { + private fun launchTopology( + id: String, + topology: Topology, + config: Map = mapOf() + ) { - val props = appProps.kafkaConfig + val props: Properties = appProps.kafkaConfig + + config.forEach { (k, v) -> props.setProperty(k, v) } val appId = props.compute(StreamsConfig.APPLICATION_ID_CONFIG) { _, v -> "$v.$id" } as? String props.setProperty(StreamsConfig.APPLICATION_ID_CONFIG, appId) + // props.setProperty(StreamsConfig.MAX_TASK_IDLE_MS_CONFIG, "${30.minutes.inWholeMilliseconds}") val streams = KafkaStreams(topology, props) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt index 18ab16a..a80dd72 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt @@ -3,6 +3,7 @@ package dev.adamko.kafkatorio.processor import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler.StreamThreadExceptionResponse + class StreamsExceptionHandler( val shutdown: (e: Throwable) -> Unit, ) : StreamsUncaughtExceptionHandler { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt index fb89dbc..27f4a17 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt @@ -1,9 +1,5 @@ package dev.adamko.kafkatorio.processor.admin -import dev.adamko.kafkatorio.events.schema.FactorioEventUpdate -import dev.adamko.kafkatorio.events.schema.FactorioObjectData -import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -import dev.adamko.kafkatorio.processor.KafkatorioTopology import java.util.concurrent.TimeUnit import mu.KotlinLogging import org.apache.kafka.clients.admin.Admin @@ -28,34 +24,9 @@ object KafkatorioKafkaAdmin { val currentTopics = currentTopics().map { it.name() } - val kafkatorioTopics = buildSet { - KafkatorioPacket.PacketType.values.forEach { packetType -> - - add(KafkatorioTopology.TOPIC_GROUPED_MAP_CHUNKS) - add(KafkatorioTopology.TOPIC_SRC_SERVER_LOG) - - val base = topicNameBase(packetType) - - when (packetType) { - KafkatorioPacket.PacketType.EVENT -> - FactorioObjectData.ObjectName.values.forEach { objectName -> - add("$base.${objectName.name}") - } - KafkatorioPacket.PacketType.CONFIG -> add("$base.FactorioConfigurationUpdate") - KafkatorioPacket.PacketType.PROTOTYPES -> add("$base.all") - KafkatorioPacket.PacketType.UPDATE -> { - add("$base.all") - FactorioEventUpdate.FactorioEventUpdateType.values.forEach { objectName -> - add("$base.${objectName.name}") - } - } - } - - } - }.minus(currentTopics.toSet()) + val kafkatorioTopics = allTopics() - currentTopics.toSet() if (kafkatorioTopics.isNotEmpty()) { - logger.info("Creating ${kafkatorioTopics.size} topics") val result = kafkaAdmin.createTopics { kafkatorioTopics } @@ -83,11 +54,14 @@ object KafkatorioKafkaAdmin { replicationFactor: Short = 1, topicNames: () -> Collection, ): CreateTopicsResult = - createTopics(topicNames() - .distinct() - .map { - NewTopic(it, numPartitions, replicationFactor) - }) + createTopics( + topicNames() + .distinct() + .map { + NewTopic(it, numPartitions, replicationFactor) +// .configs(mapOf("cleanup.policy" to "compact")) + } + ) private fun currentTopics(): MutableCollection { return kafkaAdmin.listTopics() @@ -95,6 +69,6 @@ object KafkatorioKafkaAdmin { .get() } - fun topicNameBase(packetType: KafkatorioPacket.PacketType): String = - "kafkatorio.${packetType.name}" +// fun topicNameBase(packetType: KafkatorioPacketDataType): String = +// "kafkatorio.${packetType.name}" } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt new file mode 100644 index 0000000..6047fc0 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt @@ -0,0 +1,104 @@ +package dev.adamko.kafkatorio.processor.admin + +import dev.adamko.kafkatorio.schema2.ConfigurationUpdate +import dev.adamko.kafkatorio.schema2.ConsoleChatUpdate +import dev.adamko.kafkatorio.schema2.ConsoleCommandUpdate +import dev.adamko.kafkatorio.schema2.EntityUpdate +import dev.adamko.kafkatorio.schema2.KafkatorioPacketData2 +import dev.adamko.kafkatorio.schema2.MapChunkUpdate +import dev.adamko.kafkatorio.schema2.PlayerUpdate +import dev.adamko.kafkatorio.schema2.PrototypesUpdate +import dev.adamko.kafkatorio.schema2.SurfaceUpdate +import kotlin.reflect.KClass + + +private const val DOMAIN = "kafkatorio" + + +const val TOPIC_SRC_SERVER_LOG = "$DOMAIN.src.server-log" +// "factorio-server-log" +const val TOPIC_GROUPED_MAP_CHUNKS_STATE = "$DOMAIN.state.map-chunks.grouped" + + +fun allTopics(): Set = buildSet { + add(TOPIC_SRC_SERVER_LOG) + add(TOPIC_GROUPED_MAP_CHUNKS_STATE) + + addAll(packetTopicNames.values) +} + +//fun KafkatorioPacket2.topicName(): String = data.topicName() + +//fun KafkatorioPacketData2.topicName(): String = "$DOMAIN.packet.${topicName}" + + +val KafkatorioPacketData2.topicName: String + get() = when (this) { + is ConfigurationUpdate -> packetTopicNames.getValue(ConfigurationUpdate::class) + is ConsoleChatUpdate -> packetTopicNames.getValue(ConsoleChatUpdate::class) + is ConsoleCommandUpdate -> packetTopicNames.getValue(ConsoleCommandUpdate::class) + is PrototypesUpdate -> packetTopicNames.getValue(PrototypesUpdate::class) + is SurfaceUpdate -> packetTopicNames.getValue(SurfaceUpdate::class) + is EntityUpdate -> packetTopicNames.getValue(EntityUpdate::class) + is MapChunkUpdate -> packetTopicNames.getValue(MapChunkUpdate::class) + is PlayerUpdate -> packetTopicNames.getValue(PlayerUpdate::class) + } + + +private val packetTopicNames: Map, String> = mapOf( + ConfigurationUpdate::class to "configuration", + ConsoleChatUpdate::class to "console-chat", + ConsoleCommandUpdate::class to "console-command", + PrototypesUpdate::class to "prototypes", + SurfaceUpdate::class to "surface", + EntityUpdate::class to "entity", + MapChunkUpdate::class to "map-chunk", + PlayerUpdate::class to "player", +).mapValues { (_, v) -> + "$DOMAIN.packet.$v" +} + +val KClass.topicName: String + get() = packetTopicNames.getValue(this) + +//fun packetTopic( +// dataType: KafkatorioKeyedPacketData.KafkatorioKeyedPacketDataType, +//): String = packetTopic(KafkatorioPacketType.KEYED, dataType.name.lowercase()) +// +//private fun packetTopic( +// packetType: KafkatorioPacketType, +// dataType: String, +//): String { +// return "$DOMAIN.packet.$packetType.$dataType" +//} + +//sealed interface KafkatorioTopic { +// +// val type: String +// val entity: String +// val description: String +// +// companion object { +// private const val DOMAIN = "kafkatorio" +// +// val KafkatorioTopic.topic +// get() = listOf(DOMAIN, type, entity, description).joinToString(".") +// +// } +// +// data class Event( +// override val entity: String, +// override val description: String, +// ) : KafkatorioTopic { +// override val type: String = "event" +// } +// +// +// data class State( +// override val entity: String, +// override val description: String, +// ) : KafkatorioTopic { +// override val type: String = "state" +// } +// +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt index 4e1a99c..f474a85 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt @@ -1,11 +1,5 @@ package dev.adamko.kafkatorio.processor.serdes -import java.io.ByteArrayInputStream -import java.io.ByteArrayOutputStream -import java.io.DataInput -import java.io.DataInputStream -import java.io.DataOutput -import java.io.DataOutputStream import kotlinx.serialization.BinaryFormat import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.SerializationStrategy @@ -17,6 +11,9 @@ import kotlinx.serialization.encoding.CompositeDecoder import kotlinx.serialization.encoding.CompositeEncoder import kotlinx.serialization.modules.EmptySerializersModule import kotlinx.serialization.modules.SerializersModule +import okio.Buffer +import okio.BufferedSink +import okio.BufferedSource val kxsBinary: KxsBinary = KxsBinary() @@ -27,18 +24,18 @@ class KxsBinary( ) : BinaryFormat { override fun encodeToByteArray(serializer: SerializationStrategy, value: T): ByteArray { - val output = ByteArrayOutputStream() - val encoder = KxsDataOutputEncoder(DataOutputStream(output), serializersModule) + val output = Buffer() + val encoder = KxsDataOutputEncoder(output, serializersModule) encoder.encodeSerializableValue(serializer, value) - return output.toByteArray() + return output.readByteArray() } override fun decodeFromByteArray( deserializer: DeserializationStrategy, bytes: ByteArray ): T { - val input = ByteArrayInputStream(bytes) - val decoder = KxsDataInputDecoder(DataInputStream(input), serializersModule) + val input = Buffer().write(bytes) + val decoder = KxsDataInputDecoder(input, serializersModule) return decoder.decodeSerializableValue(deserializer) } } @@ -46,28 +43,31 @@ class KxsBinary( private val byteArraySerializer = ByteArraySerializer() class KxsDataOutputEncoder( - private val output: DataOutput, + private val output: BufferedSink, override val serializersModule: SerializersModule = EmptySerializersModule, ) : AbstractEncoder() { - override fun encodeBoolean(value: Boolean) = output.writeByte(if (value) 1 else 0) - override fun encodeByte(value: Byte) = output.writeByte(value.toInt()) - override fun encodeChar(value: Char) = output.writeChar(value.code) - override fun encodeDouble(value: Double) = output.writeDouble(value) - override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) = output.writeInt(index) - override fun encodeFloat(value: Float) = output.writeFloat(value) - override fun encodeInt(value: Int) = output.writeInt(value) - override fun encodeLong(value: Long) = output.writeLong(value) - override fun encodeShort(value: Short) = output.writeShort(value.toInt()) - override fun encodeString(value: String) = output.writeUTF(value) -// override fun encodeString(value: String) = encodeByteArray(value.toByteArray(Charsets.UTF_8)) + private operator fun BufferedSink.invoke(action: BufferedSink.() -> Unit): Unit = action() + + override fun encodeBoolean(value: Boolean) = output { writeByte(if (value) 1 else 0) } + override fun encodeByte(value: Byte) = output { writeByte(value.toInt()) } + override fun encodeChar(value: Char) = output { writeUtf8CodePoint(value.code) } + override fun encodeDouble(value: Double) = output { writeLong(value.toRawBits()) } + override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) = output { writeInt(index) } + override fun encodeFloat(value: Float) = output { writeInt(value.toRawBits()) } + override fun encodeInt(value: Int) = output { writeInt(value) } + override fun encodeLong(value: Long) = output { writeLong(value) } + override fun encodeShort(value: Short) = output { writeShort(value.toInt()) } + override fun encodeString(value: String) = output { + encodeCompactSize(value.length) + writeUtf8(value) + } override fun beginCollection( descriptor: SerialDescriptor, collectionSize: Int ): CompositeEncoder { - encodeInt(collectionSize) -// encodeCompactSize(collectionSize) + encodeCompactSize(collectionSize) return this } @@ -98,7 +98,7 @@ class KxsDataOutputEncoder( class KxsDataInputDecoder( - private val input: DataInput, + private val input: BufferedSource, override val serializersModule: SerializersModule = EmptySerializersModule, private var elementsCount: Int = 0, ) : AbstractDecoder() { @@ -107,15 +107,17 @@ class KxsDataInputDecoder( override fun decodeBoolean(): Boolean = input.readByte().toInt() != 0 override fun decodeByte(): Byte = input.readByte() - override fun decodeChar(): Char = input.readChar() - override fun decodeDouble(): Double = input.readDouble() + override fun decodeChar(): Char = input.readUtf8CodePoint().toChar() + override fun decodeDouble(): Double = Double.fromBits(input.readLong()) override fun decodeEnum(enumDescriptor: SerialDescriptor): Int = input.readInt() - override fun decodeFloat(): Float = input.readFloat() + override fun decodeFloat(): Float = Float.fromBits(input.readInt()) override fun decodeInt(): Int = input.readInt() override fun decodeLong(): Long = input.readLong() override fun decodeShort(): Short = input.readShort() - override fun decodeString(): String = input.readUTF() -// override fun decodeString(): String = decodeByteArray().toString(Charsets.UTF_8) + override fun decodeString(): String { + val size = decodeCompactSize() + return input.readUtf8(size.toLong()) + } override fun decodeElementIndex(descriptor: SerialDescriptor): Int { if (elementIndex == elementsCount) return CompositeDecoder.DECODE_DONE @@ -128,8 +130,7 @@ class KxsDataInputDecoder( override fun decodeSequentially(): Boolean = true override fun decodeCollectionSize(descriptor: SerialDescriptor): Int = - decodeInt().also { elementsCount = it } -// decodeCompactSize().also { elementsCount = it } + decodeCompactSize().also { elementsCount = it } override fun decodeNotNullMark(): Boolean = decodeBoolean() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt index 0096037..8869207 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt @@ -1,7 +1,7 @@ package dev.adamko.kafkatorio.processor.serdes -import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -import dev.adamko.kafkatorio.events.schema.jsonMapperKafkatorio +import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio +import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json @@ -13,15 +13,15 @@ import org.http4k.format.asConfigurable import org.http4k.format.withStandardMappings -object KafkatorioPacketSerde : Serde { - override fun serializer() = Serializer { _, message -> - jsonMapper.encodeToString(message).encodeToByteArray() - } - - override fun deserializer() = Deserializer { _, bytes -> - jsonMapper.decodeFromString(bytes.decodeToString()) - } -} +//object KafkatorioPacketSerde : Serde { +// override fun serializer() = Serializer { _, message -> +// jsonMapper.encodeToString(message).encodeToByteArray() +// } +// +// override fun deserializer() = Deserializer { _, bytes -> +// jsonMapper.decodeFromString(bytes.decodeToString()) +// } +//} val jsonMapper: Json = Json { prettyPrint = true diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt index 0d8c58b..2a3e6dd 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt @@ -1,13 +1,10 @@ package dev.adamko.kafkatorio.processor.topology -import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate -import dev.adamko.kafkatorio.events.schema.FactorioEvent -import dev.adamko.kafkatorio.events.schema.FactorioEventUpdatePacket -import dev.adamko.kafkatorio.events.schema.FactorioPrototypes -import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -import dev.adamko.kafkatorio.processor.KafkatorioTopology -import dev.adamko.kafkatorio.processor.admin.KafkatorioKafkaAdmin + +import dev.adamko.kafkatorio.processor.admin.TOPIC_SRC_SERVER_LOG +import dev.adamko.kafkatorio.processor.admin.topicName import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.streams.map @@ -22,25 +19,24 @@ import org.apache.kafka.streams.processor.RecordContext fun factorioServerPacketStream( builder: StreamsBuilder = StreamsBuilder(), -): KStream { +): KStream { return builder.stream( - KafkatorioTopology.TOPIC_SRC_SERVER_LOG, + TOPIC_SRC_SERVER_LOG, consumedAs( "read-raw-packets-from-server", Serdes.String(), Serdes.String(), ) - ) - .map("decode-packets") { serverId: String, value: String -> - val packet = jsonMapper.decodeFromString(value) - FactorioServerId(serverId) to packet - } + ).map("decode-packets") { serverId: String, value: String -> + val packet = jsonMapper.decodeFromString(value) + FactorioServerId(serverId) to packet + } } fun splitFactorioServerPacketStream( - factorioServerPacketStream: KStream + factorioServerPacketStream: KStream ) { factorioServerPacketStream .to( @@ -49,18 +45,8 @@ fun splitFactorioServerPacketStream( jsonMapper.serde(), jsonMapper.serde(), ) - ) { _: FactorioServerId, value: KafkatorioPacket, _: RecordContext -> + ) { _: FactorioServerId, value: KafkatorioPacket2, _: RecordContext -> // println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") - - val base = KafkatorioKafkaAdmin.topicNameBase(value.packetType) - - val type: String = when (value) { - is FactorioEvent -> value.data.objectName.name - is FactorioConfigurationUpdate -> "FactorioConfigurationUpdate" - is FactorioPrototypes -> "all" - is FactorioEventUpdatePacket -> value.update.updateType.name - } - - "$base.$type" + value.data.topicName } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt index 6f5a524..3909488 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt @@ -4,12 +4,8 @@ import com.sksamuel.scrimage.ImmutableImage import com.sksamuel.scrimage.ScaleMethod import com.sksamuel.scrimage.color.RGBColor import com.sksamuel.scrimage.nio.PngWriter -import dev.adamko.kafkatorio.events.schema.ColourHex -import dev.adamko.kafkatorio.events.schema.MapChunkPosition -import dev.adamko.kafkatorio.events.schema.MapTilePosition -import dev.adamko.kafkatorio.events.schema.SurfaceIndex -import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition -import dev.adamko.kafkatorio.processor.KafkatorioTopology +import dev.adamko.kafkatorio.schema.common.* +import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.streams.forEach @@ -17,7 +13,9 @@ import dev.adamko.kotka.kxs.serde import java.awt.image.BufferedImage import java.io.File import kotlin.coroutines.CoroutineContext +import kotlin.io.path.fileSize import kotlin.math.abs +import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -25,17 +23,18 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.distinctUntilChangedBy import kotlinx.coroutines.flow.emitAll import kotlinx.coroutines.flow.flatMapConcat import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.runningFold -import kotlinx.coroutines.job import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking import kotlinx.coroutines.supervisorScope import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.Topology @@ -44,10 +43,6 @@ import org.apache.kafka.streams.kstream.KStream private const val WEB_MAP_TILE_SIZE_PX = 256 -private val cScope = CoroutineScope( - Dispatchers.Default + SupervisorJob() + CoroutineName("f-server-map-updates") -) - /** A bridge between Kafka and Kotlin */ private val serverMapChunkHandler = ServerMapChunkHandler() @@ -59,17 +54,15 @@ fun saveMapTiles( val groupedMapChunkTiles: KStream> = builder.stream( - KafkatorioTopology.TOPIC_GROUPED_MAP_CHUNKS, + TOPIC_GROUPED_MAP_CHUNKS_STATE, consumedAs("consume.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()) ) groupedMapChunkTiles .forEach("save-chunked-tiles") { _, value -> if (value != null) { - runBlocking(Dispatchers.Default) { - println("emitting chunkedTiles ${value.chunkId} tiles: ${value.map.size}") - serverMapChunkHandler.emit(value) - } + println("emitting chunkedTiles ${value.chunkId} tiles: ${value.map.size}") + serverMapChunkHandler.emit(value) } } @@ -107,9 +100,8 @@ private fun ColourHex.toRgbColor(): RGBColor { private class ServerMapChunkHandler : CoroutineScope { - override val coroutineContext: CoroutineContext = Dispatchers.Default + - SupervisorJob(cScope.coroutineContext.job) + - CoroutineName("ServerMapChunkHandler") + override val coroutineContext: CoroutineContext = + Dispatchers.Default + SupervisorJob() + CoroutineName("ServerMapChunkHandler") /** The inbox for this handler. */ @@ -119,10 +111,8 @@ private class ServerMapChunkHandler : CoroutineScope { onBufferOverflow = BufferOverflow.SUSPEND, ) - fun emit(mapChunkTiles: ServerMapChunkTiles) { - launch { - allChunksFlow.emit(mapChunkTiles) - } + fun emit(mapChunkTiles: ServerMapChunkTiles) = launch { + allChunksFlow.emit(mapChunkTiles) } /** This flow saves images one-by-one */ @@ -135,17 +125,18 @@ private class ServerMapChunkHandler : CoroutineScope { init { allChunksFlow - .runningFold(mapOf>()) { acc, src -> + .runningFold(mutableMapOf>()) { acc, src -> - val flow = acc.getOrElse(src.chunkId) { + val flow = acc.getOrPut(src.chunkId) { println("creating new subdivide-flow for chunkId ${src.chunkId}") createSubdivisionFlow() } flow.emit(Cmd.ChunkSubdivide(src.chunkId, src.map)) - acc + (src.chunkId to flow) + acc } + .distinctUntilChangedBy { it.size } .onEach { println("allChunksFlow has ${it.size} subdivide-flows: ${it.keys.joinToString()}") } @@ -160,9 +151,15 @@ private class ServerMapChunkHandler : CoroutineScope { println("created new map tile parentFile directory ${chunkImageFile.absolutePath}") } + val sizeBefore = chunkImageFile.takeIf { it.exists() }?.toPath()?.fileSize() + val savedTile = img.output(PngWriter.NoCompression, chunkImageFile) - if (filename.value.contains("z-1")) { - println("savedTile: $savedTile") + + val sizeAfter = savedTile.takeIf { it.exists() }?.toPath()?.fileSize() + if (sizeBefore != sizeAfter) { +// println("savedTile $sizeBefore/$sizeAfter: $savedTile") + } else { + println("savedTile NO-SIZE-CHANGE $sizeBefore/$sizeAfter: $savedTile") } } .launchIn(this) @@ -183,43 +180,46 @@ private class ServerMapChunkHandler : CoroutineScope { onBufferOverflow = BufferOverflow.SUSPEND, ) - val saveImgCommands = subdivisionFlow - .flatMapConcat { subdivideCmd -> - ChunkSize - .values - .flatMap { chunkSize -> - subdivideCmd.tiles - .entries - .groupBy( - { (tile, _) -> tile.toMapChunkPosition(chunkSize.tilesPerChunk) } - ) { - it.key to it.value - } - .map { (chunkPos, tiles) -> - async { - Cmd.CreateImage( - surfaceIndex = subdivideCmd.chunkId.surfaceIndex, - chunkSize = chunkSize, - chunkPosition = chunkPos, - tiles = tiles.toMap() - ) + val saveImgCommands: Flow = + subdivisionFlow + .debounce(30.seconds) + .flatMapConcat { subdivideCmd -> + ChunkSize + .entries + .flatMap { chunkSize -> + subdivideCmd + .tiles + .entries + .groupBy( + { (tile, _) -> tile.toMapChunkPosition(chunkSize.tilesPerChunk) } + ) { (tilePosition, colour) -> + tilePosition to colour } - } - } - .awaitAll() - .asFlow() - } - .map { createCmd -> - val filename = TilePngFilename(createCmd) + .map { (chunkPos, tiles) -> + async { + Cmd.CreateImage( + surfaceIndex = subdivideCmd.chunkId.surfaceIndex, + chunkSize = chunkSize, + chunkPosition = chunkPos, + tiles = tiles.toMap() + ) + } + } + } + .awaitAll() + .asFlow() + } + .map { createCmd -> + val filename = TilePngFilename(createCmd) - val img = createMapTileImage( - createCmd.chunkPosition, - createCmd.tiles, - createCmd.chunkSize, - ) + val img = createMapTileImage( + createCmd.chunkPosition, + createCmd.tiles, + createCmd.chunkSize, + ) - Cmd.SaveImage(filename, img) - } + Cmd.SaveImage(filename, img) + } launch { supervisorScope { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt index 8dd972f..ee03ef6 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt @@ -1,52 +1,31 @@ package dev.adamko.kafkatorio.processor.topology -import dev.adamko.kafkatorio.events.schema.ColourHex -import dev.adamko.kafkatorio.events.schema.FactorioEventUpdate -import dev.adamko.kafkatorio.events.schema.FactorioEventUpdatePacket -import dev.adamko.kafkatorio.events.schema.FactorioPrototypes -import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -import dev.adamko.kafkatorio.events.schema.MapChunkPosition -import dev.adamko.kafkatorio.events.schema.MapChunkUpdate -import dev.adamko.kafkatorio.events.schema.MapTile -import dev.adamko.kafkatorio.events.schema.MapTileDictionary.Companion.isNullOrEmpty -import dev.adamko.kafkatorio.events.schema.MapTilePosition -import dev.adamko.kafkatorio.events.schema.MapTiles -import dev.adamko.kafkatorio.events.schema.SurfaceIndex -import dev.adamko.kafkatorio.events.schema.converters.toMapChunkPosition -import dev.adamko.kafkatorio.processor.KafkatorioTopology -import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kotka.extensions.consumedAs +import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.MapChunkPosition +import dev.adamko.kafkatorio.schema.common.MapTile +import dev.adamko.kafkatorio.schema.common.MapTileDictionary.Companion.isNullOrEmpty +import dev.adamko.kafkatorio.schema.common.MapTilePosition +import dev.adamko.kafkatorio.schema.common.MapTiles +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.common.toMapChunkPosition +import dev.adamko.kafkatorio.schema2.MapChunkUpdate +import dev.adamko.kafkatorio.schema2.PrototypesUpdate import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.producedAs -import dev.adamko.kotka.extensions.repartitionedAs import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.flatMap import dev.adamko.kotka.extensions.streams.mapValues import dev.adamko.kotka.extensions.streams.peek import dev.adamko.kotka.extensions.streams.reduce -import dev.adamko.kotka.extensions.streams.toTable import dev.adamko.kotka.extensions.tableJoined -import dev.adamko.kotka.extensions.tables.filter import dev.adamko.kotka.extensions.tables.join -import dev.adamko.kotka.extensions.tables.mapValues import dev.adamko.kotka.extensions.tables.toStream import dev.adamko.kotka.kxs.serde -import kotlin.collections.List -import kotlin.collections.Map -import kotlin.collections.associate import kotlin.collections.component1 import kotlin.collections.component2 -import kotlin.collections.getOrElse -import kotlin.collections.groupBy -import kotlin.collections.isNotEmpty -import kotlin.collections.isNullOrEmpty -import kotlin.collections.joinToString -import kotlin.collections.map -import kotlin.collections.mapValues -import kotlin.collections.mutableSetOf -import kotlin.collections.plus import kotlinx.serialization.Serializable import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.Topology @@ -72,33 +51,39 @@ data class ServerMapChunkTiles( } -fun groupMapChunks( - builder: StreamsBuilder, - prototypesTopicName: String = "kafkatorio.${KafkatorioPacket.PacketType.PROTOTYPES}.all", - mapChunkUpdatesTopicName: String = "kafkatorio.${KafkatorioPacket.PacketType.UPDATE}.${FactorioEventUpdate.FactorioEventUpdateType.MAP_CHUNK}", -): Topology { +fun groupMapChunks(builder: StreamsBuilder): Topology { + + val mapChunksStream: KStream = builder.streamPacketData() + val protosStream: KStream = builder.streamPacketData() + +// val protosStream: KStream = +// builder.stream( +// prototypesTopicName, +// consumedAs("consume.factorio-protos.all", jsonMapper.serde(), jsonMapper.serde()) +// ).filter { key: FactorioServerId?, value: KafkatorioPacket2? -> +// key != null +// && value != null +// && value.data == +// } +// .map + - val protosStream: KStream = - builder.stream( - prototypesTopicName, - consumedAs("consume.factorio-protos.all", jsonMapper.serde(), jsonMapper.serde()) - ) val tileProtoColourDict: KTable = tileProtoColourDictionary(protosStream) - val mapChunksUpdatesStream: KStream = - builder.stream( - mapChunkUpdatesTopicName, - consumedAs( - "consume.map-chunk-updates", - jsonMapper.serde(), - jsonMapper.serde(), - ) - ) +// val mapChunksUpdatesStream: KStream = +// builder.stream( +// mapChunkUpdatesTopicName, +// consumedAs( +// "consume.map-chunk-updates", +// jsonMapper.serde(), +// jsonMapper.serde(), +// ) +// ) val groupedMapChunkTiles: KTable> = groupTilesIntoChunksWithColours( - mapChunksUpdatesStream, + mapChunksStream, tileProtoColourDict, ) @@ -108,13 +93,13 @@ fun groupMapChunks( !v?.map.isNullOrEmpty() } .mapValues("stream-grouped-map-tiles.map-not-null") { _, v -> - v as ServerMapChunkTiles + requireNotNull(v) } .peek("stream-grouped-map-tiles.peek") { _, v -> println("Grouping map tiles result: ${v.chunkId} / ${v.map.size}") } .to( - KafkatorioTopology.TOPIC_GROUPED_MAP_CHUNKS, + TOPIC_GROUPED_MAP_CHUNKS_STATE, producedAs( "produce.grouped-map-chunks", kxsBinary.serde(), @@ -127,37 +112,24 @@ fun groupMapChunks( private fun groupTilesIntoChunksWithColours( - mapChunkUpdatePacketsStream: KStream, + mapChunksStream: KStream, tileProtoColourDict: KTable, ): KTable> { - val mapChunkUpdatesStream: KStream = - mapChunkUpdatePacketsStream - .filter { _, packet: FactorioEventUpdatePacket? -> - when (val data = packet?.update) { - is MapChunkUpdate -> !data.tileDictionary.isNullOrEmpty() - else -> false - } - } - .mapValues("map-chunk-update-packets.convert-to-map-tiles") { _, packet: FactorioEventUpdatePacket -> - val mapChunkUpdate: MapChunkUpdate = requireNotNull(packet.update as? MapChunkUpdate) { - "invalid UpdatePacket type $packet" - } - - val tiles: List = requireNotNull(mapChunkUpdate.tileDictionary?.toMapTileList()) { - "invalid MapChunkUpdate packet, tiles must not be null" - } - require(tiles.isNotEmpty()) { - "invalid MapChunkUpdate packet, tiles must not be empty" - } - - MapTiles(mapChunkUpdate.surfaceIndex, tiles) - } + val mapTilesStream: KStream = + mapChunksStream.filter { _, value -> + !value.tileDictionary.isNullOrEmpty() + }.mapValues("map-chunk-update-packets.convert-to-map-tiles") { _, packet: MapChunkUpdate -> + val mapTiles = packet.tileDictionary?.toMapTileList() ?: emptyList() + MapTiles(packet.key.surfaceIndex, mapTiles) + }.filter { _, value -> + value.tiles.isNotEmpty() + } val chunkedTilesTable: KTable> = - mapChunkUpdatesStream + mapTilesStream // group tiles by server & surface & chunk .flatMap("server-map-data.tiles.flatMapByChunk") { serverId: FactorioServerId, mapTiles: MapTiles -> @@ -208,65 +180,65 @@ private fun groupTilesIntoChunksWithColours( kxsBinary.serde>(), ) ) { chunkTiles, other -> chunkTiles + other } - .toStream("server-map-data.tiles.repartition.to-stream") - .repartition( - repartitionedAs( - "server-map-data.tiles.repartition.config", - kxsBinary.serde(), - kxsBinary.serde?>(), - 3, - ) - ).toTable( - "server-map-data.tiles.repartition.to-table", - materializedWith( - kxsBinary.serde(), - kxsBinary.serde?>(), - ) - ) - .filter("server-map-data.tiles.repartition.filter-not-null") { _: ServerMapChunkId, v: ServerMapChunkTiles? -> - v != null - } - .mapValues( - "server-map-data.tiles.repartition.map-not-null", - materializedWith( - kxsBinary.serde(), - kxsBinary.serde>(), - ) - ) { _: ServerMapChunkId, v: ServerMapChunkTiles? -> - v as ServerMapChunkTiles - } +// .toStream("server-map-data.tiles.repartition.to-stream") +// .repartition( +// repartitionedAs( +// "server-map-data.tiles.repartition.config", +// kxsBinary.serde(), +// kxsBinary.serde?>(), +// 3, +// ) +// ).toTable( +// "server-map-data.tiles.repartition.to-table", +// materializedWith( +// kxsBinary.serde(), +// kxsBinary.serde?>(), +// ) +// ) +// .filter("server-map-data.tiles.repartition.filter-not-null") { _: ServerMapChunkId, v: ServerMapChunkTiles? -> +// v != null +// } +// .mapValues( +// "server-map-data.tiles.repartition.map-not-null", +// materializedWith( +// kxsBinary.serde(), +// kxsBinary.serde>(), +// ) +// ) { _: ServerMapChunkId, v: ServerMapChunkTiles? -> +// v as ServerMapChunkTiles +// } // repartition to try and fix KTable-KTable joining skipping records val tileProtoColourDictRepartitioned = tileProtoColourDict - .toStream("tileProtoColourDict.repartition.to-stream") - .repartition( - repartitionedAs( - "tileProtoColourDict.repartition.config", - kxsBinary.serde(), - kxsBinary.serde(), - 3, - ) - ).toTable( - "tileProtoColourDict.repartition.to-table", - materializedWith( - kxsBinary.serde(), - kxsBinary.serde(), - ) - ) - .filter("tileProtoColourDict.repartition.filter-not-null") { _: FactorioServerId, v: TileColourDict? -> - v != null - } - .mapValues( - "tileProtoColourDict.repartition.map-not-null", - materializedWith( - kxsBinary.serde(), - kxsBinary.serde(), - ) - ) { _: FactorioServerId, v: TileColourDict? -> - v as TileColourDict - } +// .toStream("tileProtoColourDict.repartition.to-stream") +// .repartition( +// repartitionedAs( +// "tileProtoColourDict.repartition.config", +// kxsBinary.serde(), +// kxsBinary.serde(), +// 3, +// ) +// ).toTable( +// "tileProtoColourDict.repartition.to-table", +// materializedWith( +// kxsBinary.serde(), +// kxsBinary.serde(), +// ) +// ) +// .filter("tileProtoColourDict.repartition.filter-not-null") { _: FactorioServerId, v: TileColourDict? -> +// v != null +// } +// .mapValues( +// "tileProtoColourDict.repartition.map-not-null", +// materializedWith( +// kxsBinary.serde(), +// kxsBinary.serde(), +// ) +// ) { _: FactorioServerId, v: TileColourDict? -> +// v as TileColourDict +// } val colourisedChunkTable: KTable> = diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt index d32032f..3ed4ef8 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt @@ -36,11 +36,11 @@ enum class ChunkSize( companion object { // cache values for better performance. KT-48872 - val values: List = values().asList() + val entries: Set = values().toSet() - val MAX: ChunkSize = values.maxByOrNull { it.tilesPerChunk }!! - val MIN: ChunkSize = values.minByOrNull { it.tilesPerChunk }!! - val STANDARD: ChunkSize = values.first { it.zoomLevel == 0 } + val MAX: ChunkSize = entries.maxByOrNull { it.tilesPerChunk }!! + val MIN: ChunkSize = entries.minByOrNull { it.tilesPerChunk }!! + val STANDARD: ChunkSize = entries.first { it.zoomLevel == 0 } } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt new file mode 100644 index 0000000..1df6221 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt @@ -0,0 +1,27 @@ +package dev.adamko.kafkatorio.processor.topology + +import dev.adamko.kafkatorio.processor.admin.topicName +import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 +import dev.adamko.kafkatorio.schema2.KafkatorioPacketData2 +import dev.adamko.kotka.extensions.consumedAs +import dev.adamko.kotka.extensions.streams.mapValues +import dev.adamko.kotka.kxs.serde +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.kstream.KStream + + +inline fun StreamsBuilder.streamPacketData(): KStream { + + val simpleName = T::class.simpleName!! + val topicName = T::class.topicName + + return stream( + topicName, + consumedAs("consume.${simpleName}", jsonMapper.serde(), jsonMapper.serde()) + ).filter { key: FactorioServerId?, value: KafkatorioPacket2? -> + key != null && value?.data is T + }.mapValues("consume.map-values.${simpleName}") { _: FactorioServerId, packet: KafkatorioPacket2 -> + packet.data as T + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt index b8fb092..f99a6e4 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt @@ -1,9 +1,10 @@ package dev.adamko.kafkatorio.processor.topology -import dev.adamko.kafkatorio.events.schema.FactorioEventUpdate -import dev.adamko.kafkatorio.events.schema.KafkatorioPacket import dev.adamko.kafkatorio.processor.WebsocketServer +import dev.adamko.kafkatorio.processor.admin.topicName import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 +import dev.adamko.kafkatorio.schema2.PlayerUpdate import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.kxs.serde import kotlinx.serialization.encodeToString @@ -14,12 +15,11 @@ fun playerUpdatesToWsServer( websocketServer: WebsocketServer, builder: StreamsBuilder = StreamsBuilder(), ) { - builder.stream( - "kafkatorio.${KafkatorioPacket.PacketType.UPDATE}.${FactorioEventUpdate.FactorioEventUpdateType.PLAYER}", + builder.stream( + PlayerUpdate::class.topicName, consumedAs("EventUpdate.Player-updates-for-ws-server", jsonMapper.serde(), jsonMapper.serde()), - ) - .foreach { _, value -> + ).foreach { _, value -> // println("sending ${value.packetType} packet to websocket") - websocketServer.sendMessage(jsonMapper.encodeToString(value)) - } + websocketServer.sendMessage(jsonMapper.encodeToString(value)) + } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index 9f307eb..3ab14fc 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -1,15 +1,13 @@ package dev.adamko.kafkatorio.processor.topology -import dev.adamko.kafkatorio.events.schema.ColourHex -import dev.adamko.kafkatorio.events.schema.FactorioPrototypes -import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -import dev.adamko.kafkatorio.events.schema.MapTile -import dev.adamko.kafkatorio.events.schema.MapTilePrototype -import dev.adamko.kafkatorio.events.schema.converters.toHex -import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.MapTile +import dev.adamko.kafkatorio.schema.common.toHex +import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2 +import dev.adamko.kafkatorio.schema.prototypes.MapTilePrototype +import dev.adamko.kafkatorio.schema2.PrototypesUpdate import dev.adamko.kotka.extensions.materializedAs -import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.mapValues import dev.adamko.kotka.extensions.streams.toTable @@ -25,6 +23,7 @@ import org.apache.kafka.streams.kstream.KTable value class TileProtoHashCode private constructor(val code: Int) { constructor(prototype: MapTilePrototype) : this(prototype.name.hashCode()) constructor(tile: MapTile) : this(tile.proto.hashCode()) + constructor(tile: FactorioPrototype2.MapTile) : this(tile.name.hashCode()) } @@ -35,32 +34,53 @@ value class TileColourDict(val map: Map) /** Get the latest map-tile colours per server. */ fun tileProtoColourDictionary( - factorioServerPacketStream: KStream + factorioServerPacketStream: KStream ): KTable { - // get all the prototypes - return factorioServerPacketStream - .mapValues("server-map-data.tile-prototypes.mapValues") { _, packet: KafkatorioPacket -> - val map = when (packet) { - is FactorioPrototypes -> packet - .prototypes - .filterIsInstance() - .associate { TileProtoHashCode(it) to it.mapColour.toHex() } - else -> mapOf() - } - TileColourDict(map) - }.filter("server-map-data.tile-prototypes.filterMapTileProtos") { _, dict: TileColourDict -> - dict.map.isNotEmpty() - }.peek { serverId, dict: TileColourDict -> - println("server $serverId has TileColourDict[${dict.map.size}]: ${dict.map.entries.joinToString()}") - } - .toTable( - "server-map-data.tile-prototypes", - materializedAs( - "server-map-data.tile-prototypes.store", - kxsBinary.serde(), - kxsBinary.serde(), - ) - ) + return factorioServerPacketStream.mapValues("server-map-data.tile-prototypes.map-values") { _, protoPacket: PrototypesUpdate -> + val map = protoPacket + .prototypes + .filterIsInstance() + .associate { TileProtoHashCode(it) to it.mapColour.toHex() } + TileColourDict(map) + }.filter("server-map-data.tile-prototypes.filterMapTileProtos") { _, dict: TileColourDict -> + dict.map.isNotEmpty() + }.peek { serverId, dict: TileColourDict -> + println("server $serverId has TileColourDict[${dict.map.size}]: ${dict.map.entries.joinToString()}") + }.toTable( + "server-map-data.tile-prototypes", + materializedAs( + "server-map-data.tile-prototypes.store", + kxsBinary.serde(), + kxsBinary.serde(), + ) + ) } + +// get all the prototypes +// return factorioServerPacketStream +// .mapValues("server-map-data.tile-prototypes.mapValues") { _, packet: KafkatorioPacket -> +// val map = when (packet) { +// is FactorioPrototype -> packet +// .prototypes +// .filterIsInstance() +// .associate { TileProtoHashCode(it) to it.mapColour.toHex() } +// else -> mapOf() +// } +// TileColourDict(map) +// }.filter("server-map-data.tile-prototypes.filterMapTileProtos") { _, dict: TileColourDict -> +// dict.map.isNotEmpty() +// }.peek { serverId, dict: TileColourDict -> +// println("server $serverId has TileColourDict[${dict.map.size}]: ${dict.map.entries.joinToString()}") +// } +// .toTable( +// "server-map-data.tile-prototypes", +// materializedAs( +// "server-map-data.tile-prototypes.store", +// kxsBinary.serde(), +// kxsBinary.serde(), +// ) +// ) +// +//} diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt index bd4489e..26cf707 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt @@ -1,24 +1,59 @@ package dev.adamko.kafkatorio.processor.misc -import dev.adamko.kafkatorio.events.schema.MapChunkPosition -import dev.adamko.kafkatorio.events.schema.SurfaceIndex import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kafkatorio.processor.topology.ChunkSize import dev.adamko.kafkatorio.processor.topology.FactorioServerId import dev.adamko.kafkatorio.processor.topology.ServerMapChunkId +import dev.adamko.kafkatorio.processor.topology.ServerMapChunkTiles +import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.MapChunkPosition +import dev.adamko.kafkatorio.schema.common.MapTilePosition +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio import io.kotest.assertions.withClue import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.collections.shouldContainExactly +import io.kotest.matchers.comparables.shouldBeEqualComparingTo import io.kotest.matchers.equality.shouldBeEqualToComparingFields +import io.kotest.matchers.ints.shouldBeExactly +import io.kotest.matchers.longs.shouldBeExactly import io.kotest.matchers.shouldBe +import io.kotest.property.Arb +import io.kotest.property.arbitrary.boolean +import io.kotest.property.arbitrary.booleanArray +import io.kotest.property.arbitrary.byte +import io.kotest.property.arbitrary.byteArray +import io.kotest.property.arbitrary.char +import io.kotest.property.arbitrary.charArray +import io.kotest.property.arbitrary.double +import io.kotest.property.arbitrary.doubleArray +import io.kotest.property.arbitrary.float +import io.kotest.property.arbitrary.floatArray +import io.kotest.property.arbitrary.int +import io.kotest.property.arbitrary.intArray +import io.kotest.property.arbitrary.long +import io.kotest.property.arbitrary.longArray +import io.kotest.property.arbitrary.positiveInt +import io.kotest.property.arbitrary.short +import io.kotest.property.arbitrary.shortArray +import io.kotest.property.arbitrary.string +import io.kotest.property.arbitrary.uByte +import io.kotest.property.arbitrary.uInt +import io.kotest.property.arbitrary.uLong +import io.kotest.property.arbitrary.uShort +import io.kotest.property.checkAll +import kotlinx.serialization.builtins.serializer import kotlinx.serialization.decodeFromByteArray +import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToByteArray +import kotlinx.serialization.encodeToString class KxsBinaryTests : FunSpec({ test("byte array") { val ba = byteArrayOf( - 0, 4, 116, 101, 115, 116, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 3 + 4, 116, 101, 115, 116, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 3 ) val result = kxsBinary.decodeFromByteArray(ServerMapChunkId.serializer(), ba) @@ -47,7 +82,7 @@ class KxsBinaryTests : FunSpec({ withClue(ba.toString(Charsets.UTF_8)) { ba shouldBe byteArrayOf( - 0, 4, 116, 101, 115, 116, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 3 + 4, 116, 101, 115, 116, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 3 ) } } @@ -55,7 +90,10 @@ class KxsBinaryTests : FunSpec({ context("inline value class") { val uuid = "fa858d73-6205-44cf-aeeb-6bbf3148c4a7" //@formatter:off - val expectedBytes = byteArrayOf(0, 36, 102, 97, 56, 53, 56, 100, 55, 51, 45, 54, 50, 48, 53, 45, 52, 52, 99, 102, 45, 97, 101, 101, 98, 45, 54, 98, 98, 102, 51, 49, 52, 56, 99, 52, 97, 55) + val expectedBytes = byteArrayOf( + 36, 102, 97, 56, 53, 56, 100, 55, 51, 45, 54, 50, 48, 53, 45, 52, 52, 99, + 102, 45, 97, 101, 101, 98, 45, 54, 98, 98, 102, 51, 49, 52, 56, 99, 52, 97, 55, + ) //@formatter:on test("encode") { @@ -73,4 +111,208 @@ class KxsBinaryTests : FunSpec({ } } + context("ServerMapChunkTiles") { + val initial = ServerMapChunkTiles( + ServerMapChunkId( + FactorioServerId("server-id"), + MapChunkPosition(33, 44), + SurfaceIndex(4u), + ChunkSize.CHUNK_032, + ), + mapOf( + MapTilePosition(1, 2) to ColourHex(1u, 2u, 3u, 4u), + ) + ) + + test("!json round trip") { + val jsonEncoded = jsonMapperKafkatorio.encodeToString(initial) + val jsonDecoded = + jsonMapperKafkatorio.decodeFromString>(jsonEncoded) + + jsonDecoded shouldBeEqualToComparingFields initial + } + + test("binary round trip") { + val binaryEncoded = kxsBinary.encodeToByteArray(initial) + val binaryDecoded = kxsBinary.decodeFromByteArray>(binaryEncoded) + + binaryDecoded shouldBeEqualToComparingFields initial + } + } + + context("primitives round trip") { + test("double") { + checkAll(Arb.double()) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: Double = kxsBinary.decodeFromByteArray(encoded) + decoded shouldBeEqualComparingTo input + } + } + + test("float") { + checkAll(Arb.float()) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: Float = kxsBinary.decodeFromByteArray(encoded) + decoded shouldBeEqualComparingTo input + } + } + + test("int") { + checkAll(Arb.int()) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: Int = kxsBinary.decodeFromByteArray(encoded) + decoded shouldBeExactly input + } + } + + test("long") { + checkAll(Arb.long()) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: Long = kxsBinary.decodeFromByteArray(encoded) + decoded shouldBeExactly input + } + } + + test("short") { + checkAll(Arb.short()) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: Short = kxsBinary.decodeFromByteArray(encoded) + decoded shouldBeEqualComparingTo input + } + } + + test("byte") { + checkAll(Arb.byte()) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: Byte = kxsBinary.decodeFromByteArray(encoded) + decoded shouldBeEqualComparingTo input + } + } + + test("boolean") { + checkAll(Arb.boolean()) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: Boolean = kxsBinary.decodeFromByteArray(encoded) + decoded shouldBeEqualComparingTo input + } + } + + test("char") { + checkAll(Arb.char()) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: Char = kxsBinary.decodeFromByteArray(encoded) + decoded shouldBeEqualComparingTo input + } + } + + test("string") { + checkAll(Arb.string()) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: String = kxsBinary.decodeFromByteArray(encoded) + decoded shouldBeEqualComparingTo input + } + } + } + + + @OptIn(ExperimentalUnsignedTypes::class) + context("unsigned numbers round trip") { + test("uint") { + checkAll(Arb.uInt()) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(UInt.serializer(), input) + val decoded: UInt = kxsBinary.decodeFromByteArray(UInt.serializer(), encoded) + decoded shouldBeEqualComparingTo input + } + } + + test("ulong") { + checkAll(Arb.uLong()) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(ULong.serializer(), input) + val decoded: ULong = kxsBinary.decodeFromByteArray(ULong.serializer(), encoded) + decoded shouldBeEqualComparingTo input + } + } + + test("ushort") { + checkAll(Arb.uShort()) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(UShort.serializer(), input) + val decoded: UShort = kxsBinary.decodeFromByteArray(UShort.serializer(), encoded) + decoded shouldBeEqualComparingTo input + } + } + + test("ubyte") { + checkAll(Arb.uByte()) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(UByte.serializer(), input) + val decoded: UByte = kxsBinary.decodeFromByteArray(UByte.serializer(), encoded) + decoded shouldBeEqualComparingTo input + } + } + } + + context("primitive arrays round trip") { + test("double array") { + checkAll(Arb.doubleArray(Arb.positiveInt(50), Arb.double())) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: DoubleArray = kxsBinary.decodeFromByteArray(encoded) + decoded.asList() shouldContainExactly input.asList() + } + } + + test("float array") { + checkAll(Arb.floatArray(Arb.positiveInt(50), Arb.float())) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: FloatArray = kxsBinary.decodeFromByteArray(encoded) + decoded.asList() shouldContainExactly input.asList() + } + } + + test("int array") { + checkAll(Arb.intArray(Arb.positiveInt(50), Arb.int())) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: IntArray = kxsBinary.decodeFromByteArray(encoded) + decoded.asList() shouldContainExactly input.asList() + } + } + + test("long array") { + checkAll(Arb.longArray(Arb.positiveInt(50), Arb.long())) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: LongArray = kxsBinary.decodeFromByteArray(encoded) + decoded.asList() shouldContainExactly input.asList() + } + } + + test("short array") { + checkAll(Arb.shortArray(Arb.positiveInt(50), Arb.short())) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: ShortArray = kxsBinary.decodeFromByteArray(encoded) + decoded.asList() shouldContainExactly input.asList() + } + } + + test("byte array") { + checkAll(Arb.byteArray(Arb.positiveInt(50), Arb.byte())) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: ByteArray = kxsBinary.decodeFromByteArray(encoded) + decoded.asList() shouldContainExactly input.asList() + } + } + + test("boolean array") { + checkAll(Arb.booleanArray(Arb.positiveInt(50), Arb.boolean())) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: BooleanArray = kxsBinary.decodeFromByteArray(encoded) + decoded.asList() shouldContainExactly input.asList() + } + } + + test("char array") { + checkAll(Arb.charArray(Arb.positiveInt(50), Arb.char())) { input -> + val encoded: ByteArray = kxsBinary.encodeToByteArray(input) + val decoded: CharArray = kxsBinary.decodeFromByteArray(encoded) + decoded.asList() shouldContainExactly input.asList() + } + } + } }) diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt index 747ed65..f68de10 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt @@ -1,14 +1,11 @@ package dev.adamko.kafkatorio.processor.misc -import dev.adamko.kafkatorio.events.schema.ColourHex -import dev.adamko.kafkatorio.events.schema.MapChunkPosition -import dev.adamko.kafkatorio.events.schema.MapTilePosition -import dev.adamko.kafkatorio.events.schema.SurfaceIndex import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kafkatorio.processor.topology.ChunkSize import dev.adamko.kafkatorio.processor.topology.FactorioServerId import dev.adamko.kafkatorio.processor.topology.ServerMapChunkId import dev.adamko.kafkatorio.processor.topology.ServerMapChunkTiles +import dev.adamko.kafkatorio.schema.common.* import java.util.UUID import kotlinx.serialization.encodeToByteArray import org.junit.jupiter.api.Test diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt index 4d46be7..2edf2ee 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt @@ -1,21 +1,15 @@ package dev.adamko.kafkatorio.processor.topology -import dev.adamko.kafkatorio.events.schema.Colour -import dev.adamko.kafkatorio.events.schema.ColourHex -import dev.adamko.kafkatorio.events.schema.FactorioEventUpdatePacket -import dev.adamko.kafkatorio.events.schema.FactorioPrototypes -import dev.adamko.kafkatorio.events.schema.MapChunkPosition -import dev.adamko.kafkatorio.events.schema.MapChunkUpdate -import dev.adamko.kafkatorio.events.schema.MapTileDictionary -import dev.adamko.kafkatorio.events.schema.MapTilePosition -import dev.adamko.kafkatorio.events.schema.MapTilePrototype -import dev.adamko.kafkatorio.events.schema.PrototypeKey -import dev.adamko.kafkatorio.events.schema.PrototypeName -import dev.adamko.kafkatorio.events.schema.SurfaceIndex -import dev.adamko.kafkatorio.events.schema.Tick import dev.adamko.kafkatorio.processor.KafkatorioTopology +import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.schema.common.* +import dev.adamko.kafkatorio.schema.common.MapTileDictionary.PrototypeKey +import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2 +import dev.adamko.kafkatorio.schema2.MapChunkUpdate +import dev.adamko.kafkatorio.schema2.MapChunkUpdateKey +import dev.adamko.kafkatorio.schema2.PrototypesUpdate import dev.adamko.kotka.kxs.serde import io.kotest.assertions.withClue import io.kotest.core.spec.style.FunSpec @@ -32,34 +26,29 @@ import org.apache.kafka.streams.TopologyTestDriver class GroupMapChunksTest : FunSpec({ test("basic test") { + val streamsBuilder = StreamsBuilder() val prototypesTopicName = "prototypes-topic" val mapChunkUpdatesTopicName = "map-chunk-updates-topic" - val topology = groupMapChunks( - StreamsBuilder(), - prototypesTopicName, - mapChunkUpdatesTopicName, - ) + val topology = groupMapChunks(streamsBuilder) val testDriver = TopologyTestDriver(topology) - val prototypesTestInputTopic: TestInputTopic = + val prototypesTestInputTopic: TestInputTopic = testDriver.createInputTopic( prototypesTopicName, jsonMapper.serde().serializer(), - jsonMapper.serde().serializer(), + jsonMapper.serde().serializer(), ) val serverId = FactorioServerId("test-server-id") prototypesTestInputTopic.pipeInput( serverId, - FactorioPrototypes( - modVersion = "1.2.3", - tick = Tick(456u), + PrototypesUpdate( listOf( - MapTilePrototype( + FactorioPrototype2.MapTile( PrototypeName("fake-proto"), layer = 1u, mapColour = Colour(0.3f, 0.2f, 0.1f, 1.0f), @@ -71,26 +60,25 @@ class GroupMapChunksTest : FunSpec({ ) ) - val mapChunkUpdatesInputTopic: TestInputTopic = + val mapChunkUpdatesInputTopic: TestInputTopic = testDriver.createInputTopic( mapChunkUpdatesTopicName, jsonMapper.serde().serializer(), - jsonMapper.serde().serializer(), + jsonMapper.serde().serializer(), ) + mapChunkUpdatesInputTopic.pipeInput( serverId, - FactorioEventUpdatePacket( - modVersion = "1.2.3", - tick = Tick(854u), - update = MapChunkUpdate( + MapChunkUpdate( + key = MapChunkUpdateKey( MapChunkPosition(11, 22), SurfaceIndex(1u), - tileDictionary = MapTileDictionary( - tilesXY = mapOf( - "1" to mapOf("2" to PrototypeKey("33")) - ), - protos = mapOf(PrototypeKey("33") to PrototypeName("fake-proto")) - ) + ), + tileDictionary = MapTileDictionary( + tilesXY = mapOf( + "1" to mapOf("2" to PrototypeKey(33)) + ), + protos = mapOf(PrototypeName("fake-proto") to PrototypeKey(33)) ) ) ) @@ -98,7 +86,7 @@ class GroupMapChunksTest : FunSpec({ val outputTopic: TestOutputTopic> = testDriver .createOutputTopic( - KafkatorioTopology.TOPIC_GROUPED_MAP_CHUNKS, + TOPIC_GROUPED_MAP_CHUNKS_STATE, kxsBinary.serde().deserializer(), kxsBinary.serde>().deserializer(), ) diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index 6795546..3d89e79 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -FACTORIO_VERSION=1.1.53 -KAFKATORIO_VERSION=0.3.2 +FACTORIO_VERSION=1.1.57 +KAFKATORIO_VERSION=0.4.0 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index 52378b8..469b75e 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.3.2 +KAFKATORIO_VERSION=0.4.0 diff --git a/modules/infra-kafka-cluster/src/kafka-server.properties b/modules/infra-kafka-cluster/src/kafka-server.properties index 6c1f2d1..02928c4 100644 --- a/modules/infra-kafka-cluster/src/kafka-server.properties +++ b/modules/infra-kafka-cluster/src/kafka-server.properties @@ -125,3 +125,6 @@ log.retention.check.interval.ms=300000 ### record size ### message.max.bytes=10485760 replica.fetch.max.bytes=10485760 + +log.cleanup.policy=compact +auto.create.topics.enable=false diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index 52378b8..469b75e 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.3.2 +KAFKATORIO_VERSION=0.4.0 diff --git a/modules/infra-kafka-pipe/src/docker-compose.yml b/modules/infra-kafka-pipe/src/docker-compose.yml index 33bfde1..31ef1fa 100644 --- a/modules/infra-kafka-pipe/src/docker-compose.yml +++ b/modules/infra-kafka-pipe/src/docker-compose.yml @@ -2,7 +2,7 @@ version: "3.9" services: kafka-pipe: - image: openjdk:11-jre-buster + image: dev-adamko/kafka-pipe/${KAFKATORIO_VERSION} container_name: "kafka-pipe" build: dockerfile: "kafka-pipe.Dockerfile" diff --git a/modules/infra-kafka-pipe/src/kafka-pipe.sh b/modules/infra-kafka-pipe/src/kafka-pipe.sh index f9fc1ce..f6273ac 100644 --- a/modules/infra-kafka-pipe/src/kafka-pipe.sh +++ b/modules/infra-kafka-pipe/src/kafka-pipe.sh @@ -19,7 +19,7 @@ while :; do sed -n -e 's/^KafkatorioPacket: //p' | kcat -P -T \ -b "$KAFKA_HOST" \ - -t factorio-server-log \ + -t kafkatorio.src.server-log \ -k "$INSTANCE_ID" \ -H "KAFKA-PIPE-VERSION=$KAFKATORIO_VERSION" diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt index 4c241ae..99bcb2c 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt @@ -1,7 +1,7 @@ package dev.adamko.kafkatorio.webmap -import dev.adamko.kafkatorio.events.schema.MapEntityPosition -import dev.adamko.kafkatorio.events.schema.PlayerUpdate +import dev.adamko.kafkatorio.schema.common.MapEntityPosition +import dev.adamko.kafkatorio.schema2.PlayerUpdate import io.kvision.maps.Maps import io.kvision.maps.externals.leaflet.geo.LatLng diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt index 0bed951..7acdff3 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt @@ -1,6 +1,6 @@ package dev.adamko.kafkatorio.webmap -import dev.adamko.kafkatorio.events.schema.jsonMapperKafkatorio +import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio import kotlinx.serialization.json.Json val jsonMapper = Json { diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt index 451c401..d6be2cc 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt @@ -1,12 +1,12 @@ package dev.adamko.kafkatorio.webmap -import dev.adamko.kafkatorio.events.schema.Colour -import dev.adamko.kafkatorio.events.schema.MapEntityPosition -import dev.adamko.kafkatorio.events.schema.PlayerIndex -import dev.adamko.kafkatorio.events.schema.PlayerUpdate -import dev.adamko.kafkatorio.events.schema.SurfaceIndex -import dev.adamko.kafkatorio.events.schema.Tick -import dev.adamko.kafkatorio.events.schema.converters.toHexString +import dev.adamko.kafkatorio.schema.common.Colour +import dev.adamko.kafkatorio.schema.common.MapEntityPosition +import dev.adamko.kafkatorio.schema.common.PlayerIndex +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.common.Tick +import dev.adamko.kafkatorio.schema.common.toHexString +import dev.adamko.kafkatorio.schema2.PlayerUpdate import io.kvision.maps.Maps import io.kvision.maps.Maps.Companion.L import io.kvision.maps.externals.leaflet.geo.LatLng @@ -43,8 +43,8 @@ fun factorioGameReducer(state: FactorioGameState, update: FactorioUpdate): Facto when (update) { is FactorioUpdate.Player -> { - val playerState = state.players.getOrElse(update.data.index) { - PlayerState(update.data.index, update.tick) + val playerState = state.players.getOrElse(update.data.key.index) { + PlayerState(update.data.key.index, update.tick) } playerState.update(update.tick, update.data) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt index 3e0c8a5..97130f0 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -1,13 +1,14 @@ package dev.adamko.kafkatorio.webmap -import dev.adamko.kafkatorio.events.schema.EntityUpdate -import dev.adamko.kafkatorio.events.schema.FactorioConfigurationUpdate -import dev.adamko.kafkatorio.events.schema.FactorioEvent -import dev.adamko.kafkatorio.events.schema.FactorioEventUpdatePacket -import dev.adamko.kafkatorio.events.schema.FactorioPrototypes -import dev.adamko.kafkatorio.events.schema.KafkatorioPacket -import dev.adamko.kafkatorio.events.schema.MapChunkUpdate -import dev.adamko.kafkatorio.events.schema.PlayerUpdate +import dev.adamko.kafkatorio.schema2.ConfigurationUpdate +import dev.adamko.kafkatorio.schema2.ConsoleChatUpdate +import dev.adamko.kafkatorio.schema2.ConsoleCommandUpdate +import dev.adamko.kafkatorio.schema2.EntityUpdate +import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 +import dev.adamko.kafkatorio.schema2.MapChunkUpdate +import dev.adamko.kafkatorio.schema2.PlayerUpdate +import dev.adamko.kafkatorio.schema2.PrototypesUpdate +import dev.adamko.kafkatorio.schema2.SurfaceUpdate import io.kvision.redux.ReduxStore import kotlinx.serialization.decodeFromString import org.w3c.dom.MessageEvent @@ -35,26 +36,23 @@ class WebsocketService( println(data.replace('\n', ' ')) - when (val event: KafkatorioPacket = jsonMapper.decodeFromString(data)) { - is FactorioEvent -> { - } - is FactorioEventUpdatePacket -> { - when (val eventUpdate = event.update) { - is PlayerUpdate -> reduxStore.dispatch(FactorioUpdate.Player(event.tick, eventUpdate)) - is EntityUpdate, - is MapChunkUpdate -> { - } - } - } - is FactorioConfigurationUpdate, - is FactorioPrototypes -> { + val packet: KafkatorioPacket2 = jsonMapper.decodeFromString(data) + + when (val packetData = packet.data) { + + is PlayerUpdate -> reduxStore.dispatch(FactorioUpdate.Player(packet.tick, packetData)) + is ConfigurationUpdate, + is ConsoleChatUpdate, + is ConsoleCommandUpdate, + is PrototypesUpdate, + is SurfaceUpdate, + is EntityUpdate, + is MapChunkUpdate -> { // to be continued... } } - } else { println(data) } - } } From 1e0a35d9ca26a56429f8d504ccaf22497cde63f7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 10:18:54 +0200 Subject: [PATCH 265/629] bump kvision --- build.gradle.kts | 11 +++++--- gradle/kotlin-js-store/yarn.lock | 47 ++++++++++++++------------------ gradle/libs.versions.toml | 2 +- modules/web-map/build.gradle.kts | 8 +++--- 4 files changed, 33 insertions(+), 35 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9439362..f39581b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -58,11 +58,14 @@ val runKafkatorio by tasks.registering { ) } - val runEventsServer by tasks.registering { group = project.name - dependsOn( - ":modules:events-server:run", - ) + dependsOn(":modules:events-server:run") +} + +val runWebMap by tasks.registering { + group = project.name + + dependsOn(":modules:web-map:browserDevelopmentRun") } diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index c064a0d..55971ba 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -14,10 +14,10 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA== -"@fortawesome/fontawesome-free@^5.15.4": - version "5.15.4" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5" - integrity sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg== +"@fortawesome/fontawesome-free@^6.1.1": + version "6.1.1" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.1.1.tgz#bf5d45611ab74890be386712a0e5d998c65ee2a1" + integrity sha512-J/3yg2AIXc9wznaVqpHVX3Wa5jwKovVF0AMYSnbmcXTiL3PpRPfF58pzWucCwEiCJBp+hCNRLWClTomD8SseKg== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -40,10 +40,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@popperjs/core@^2.11.2": - version "2.11.2" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.2.tgz#830beaec4b4091a9e9398ac50f865ddea52186b9" - integrity sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA== +"@popperjs/core@^2.11.4": + version "2.11.5" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64" + integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw== "@rjaros/gettext.js@^1.1.3": version "1.1.3" @@ -604,7 +604,7 @@ bonjour@^3.5.0: multicast-dns "^6.0.1" multicast-dns-service-types "^1.1.0" -bootstrap-icons@^1.7.2: +bootstrap-icons@^1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.8.1.tgz#773c1625bcbf3e86090ea9da4386c2c6459c5582" integrity sha512-IXUqislddPJfwq6H+2nTkHyr9epO9h6u1AG0OZCx616w+TgzeoCjfmI3qJMQqt1J586gN2IxzB4M99Ip4sTZ1w== @@ -700,10 +700,10 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chart.js@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.7.0.tgz#7a19c93035341df801d613993c2170a1fcf1d882" - integrity sha512-31gVuqqKp3lDIFmzpKIrBeum4OpZsQjSIAqlOpgjosHDJZlULtvwLEZKtEhIAZc7JMPaHlYMys40Qy9Mf+1AAg== +chart.js@^3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.7.1.tgz#0516f690c6a8680c6c707e31a4c1807a6f400ada" + integrity sha512-8knRegQLFnPQAheZV8MjxIXc5gQEfDFD897BJgv/klO/vtIyFFmgMXrNfgrXpbTr/XbTturxRgxIXx/Y+ASJBA== chokidar@3.5.2, chokidar@^3.5.1: version "3.5.2" @@ -901,7 +901,7 @@ cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -css-loader@^6.6.0: +css-loader@^6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.1.tgz#e98106f154f6e1baf3fc3bc455cb9981c1d5fd2e" integrity sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw== @@ -1381,11 +1381,6 @@ follow-redirects@^1.0.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.6.tgz#8cfb281bbc035b3c067d6cd975b0f6ade6e855cd" integrity sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A== -follow-redirects@^1.14.8: - version "1.14.9" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" - integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== - format-util@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" @@ -2065,7 +2060,7 @@ log-symbols@4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -log4js@^6.4.0, log4js@^6.4.1: +log4js@^6.4.1: version "6.4.2" resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.4.2.tgz#45ec783835acc525b397f52cf086e26994fe3b70" integrity sha512-k80cggS2sZQLBwllpT1p06GtfvzMmSdUCkW96f0Hj83rKGJDAu2vZjt9B9ag2vx8Zz1IXzxoLgqvRJCdMKybGg== @@ -2272,7 +2267,7 @@ nanoid@3.2.0: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== -nanoid@^3.1.31, nanoid@^3.3.1: +nanoid@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== @@ -2627,7 +2622,7 @@ rechoir@^0.7.0: dependencies: resolve "^1.9.0" -redux-thunk@^2.4.0: +redux-thunk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.1.tgz#0dd8042cf47868f4b29699941de03c9301a75714" integrity sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q== @@ -2857,10 +2852,10 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -snabbdom@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.3.1.tgz#a2fb9a1c85cc19d6dc11c4c5e4c78cbbbaafff1f" - integrity sha512-FR9u20dCkktPd+qbedqwYNjMXzYhizhqlKTQzYZimLNeCJY0/5qgs0DtLVSmzIEL1bN3Dyb9sQpiHGCxUjyLnQ== +snabbdom@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.4.0.tgz#c76ed02643729f84a63875b7894a0fbcdc95c710" + integrity sha512-Sr5H1l5QxJa0B/68ZtpWi7MuGIzLWS2Up64QqXe/wzvWOjXvM9rL7+C8GhMmDVtJ7dFWypvyWJHR3nmeZN8YIQ== socket.io-adapter@~2.3.3: version "2.3.3" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f51d3e2..f0a50d9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ camel-kafkaConnectors = "0.11.0" http4k = "4.19.1.0" kafka = "3.1.0" kotlinx-serialization = "1.3.2" -kvision = "5.8.2" +kvision = "5.9.0" log4j2 = "2.17.2" qosLogback = "1.2.11" slf4j = "1.7.36" diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 47d1227..e0a6aa1 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -66,9 +66,9 @@ kotlin { implementation(libs.kotlinx.coroutines) - implementation(npm("follow-redirects", "^1.14.8")) - implementation(npm("log4js", "^6.4.0")) - implementation(npm("nanoid", "^3.1.31")) +// implementation(npm("follow-redirects", "^1.14.8")) +// implementation(npm("log4js", "^6.4.0")) +// implementation(npm("nanoid", "^3.1.31")) } val webDir = file("src/main/web") @@ -81,7 +81,7 @@ kotlin { kvision("kvision-testutils") - implementation(npm("karma", "^6.3.16")) +// implementation(npm("karma", "^6.3.16")) } } } From 448dd4a5b8c3c53203721f2ffa119fb3c182b557 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 11:27:32 +0200 Subject: [PATCH 266/629] try fixing dependabot alerts --- gradle/kotlin-js-store/yarn.lock | 27 +++++++++++++++++++++++++++ gradle/libs.versions.toml | 5 +++++ modules/web-map/build.gradle.kts | 10 +++++++--- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index 55971ba..877dddb 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -551,6 +551,13 @@ async@^2.6.2: dependencies: lodash "^4.17.14" +async@^2.6.4: + version "2.6.4" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" + integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== + dependencies: + lodash "^4.17.14" + awesome-bootstrap-checkbox@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/awesome-bootstrap-checkbox/-/awesome-bootstrap-checkbox-1.0.1.tgz#dab10146b6001129ab0a0ec1e54bb77c6c30457a" @@ -1381,6 +1388,11 @@ follow-redirects@^1.0.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.6.tgz#8cfb281bbc035b3c067d6cd975b0f6ade6e855cd" integrity sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A== +follow-redirects@^1.14.8: + version "1.14.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" + integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== + format-util@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" @@ -2162,6 +2174,11 @@ minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +minimist@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + mkdirp@^0.5.5: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" @@ -2267,6 +2284,11 @@ nanoid@3.2.0: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== +nanoid@^3.1.31: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + nanoid@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" @@ -2287,6 +2309,11 @@ node-forge@^1.2.0: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.2.1.tgz#82794919071ef2eb5c509293325cec8afd0fd53c" integrity sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w== +node-forge@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + node-releases@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f0a50d9..0ea7317 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,6 +19,9 @@ qosLogback = "1.2.11" slf4j = "1.7.36" okio = "3.1.0" +kotlinJsWrappers = "0.0.1-pre.331-kotlin-1.6.20" + + ## test ## junit = "5.8.2" kotest = "5.2.3" @@ -59,6 +62,8 @@ kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx- kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.7.5" } kotlinx-nodejs = { group = "org.jetbrains.kotlinx", name = "kotlinx-nodejs", version = "0.0.7" } +kotlin-jsWrappers-bom = { group = "org.jetbrains.kotlin-wrappers", name = "kotlin-wrappers-bom", version.ref = "kotlinJsWrappers" } + ## http4k ## http4k-bom = { group = "org.http4k", name = "http4k-bom", version.ref = "http4k" } diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index e0a6aa1..66494dc 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -66,9 +66,13 @@ kotlin { implementation(libs.kotlinx.coroutines) -// implementation(npm("follow-redirects", "^1.14.8")) -// implementation(npm("log4js", "^6.4.0")) -// implementation(npm("nanoid", "^3.1.31")) + implementation(dependencies.platform(libs.kotlin.jsWrappers.bom)) + + implementation(npm("follow-redirects", "^1.14.8")) + implementation(npm("nanoid", "^3.1.31")) + implementation(npm("minimist", "^1.2.6")) + implementation(npm("async", "^2.6.4")) + implementation(npm("node-forge", "^1.3.0")) } val webDir = file("src/main/web") From 8bf393f9c3ce4541f147063e500ecb5ae0bee7ce Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 11:28:30 +0200 Subject: [PATCH 267/629] start tidying up after schema->schema2 migration --- .../kafkatorio-schema/kafkatorio-schema.ts | 2 +- .../src/main/typescript/package.json | 12 +- .../schema/events/kafkatorioPacket.kt | 128 ++++---- .../schema/events/kafkatorioPacketInstant.kt | 188 ++++++------ .../schema/events/kafkatorioPacketKeyed.kt | 266 ++++++++-------- .../schema/prototypes/factorioPrototypes.kt | 114 +++---- .../schema2/kafkatorioPacketInstant2.kt | 1 - .../adamko/kafkatorio/events/schema/kt2ts.kt | 286 +++++++++--------- .../adamko/kafkatorio/events/schema/kt2ts2.kt | 7 + .../processor/topology/prototypes.kt | 2 - 10 files changed, 507 insertions(+), 499 deletions(-) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts index e215deb..16872e0 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts @@ -1,4 +1,4 @@ -// Generated by TypeScriptGenerator - do not edit this file manually +// Generated by kxs-ts-gen - do not edit this file manually export interface KafkatorioPacket2 { modVersion: string; diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index ea7c2fb..dc5d159 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -9,7 +9,8 @@ "engines": { "node": "~14.19.1" }, - "devDependencies": {}, + "devDependencies": { + }, "dependencies": { "lua-types": "^2.11.0", "typescript-to-lua": "1.4.3", @@ -18,7 +19,10 @@ }, "// @types/node": "^12.0.8", "license": "UNLICENSED", - "peerDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": [] + "peerDependencies": { + }, + "optionalDependencies": { + }, + "bundledDependencies": [ + ] } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacket.kt index 0809d9a..02413d8 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacket.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacket.kt @@ -1,68 +1,68 @@ package dev.adamko.kafkatorio.schema.events - -import dev.adamko.kafkatorio.schema.SerializerProvider -import dev.adamko.kafkatorio.schema.SerializerProviderDeserializer -import dev.adamko.kafkatorio.schema.common.Tick -import kotlin.reflect.KClass -import kotlin.reflect.KType -import kotlin.reflect.typeOf -import kotlinx.serialization.KSerializer -import kotlinx.serialization.Serializable - - +// +//import dev.adamko.kafkatorio.schema.SerializerProvider +//import dev.adamko.kafkatorio.schema.SerializerProviderDeserializer +//import dev.adamko.kafkatorio.schema.common.Tick +//import kotlin.reflect.KClass +//import kotlin.reflect.KType +//import kotlin.reflect.typeOf +//import kotlinx.serialization.KSerializer +//import kotlinx.serialization.Serializable +// +// +////@Serializable +////data class KafkatorioPacket( +//// val modVersion: String, +//// val tick: Tick, +//// val data: KafkatorioPacketData, +////) +// +// +//@Serializable(with = KafkatorioPacketData.JsonSerializer::class) +//sealed class KafkatorioPacketData { +// abstract val updateType: KafkatorioPacketDataType +// +// object JsonSerializer : SerializerProviderDeserializer( +// KafkatorioPacketData::class, +// KafkatorioPacketData::updateType.name, +// { json -> KafkatorioPacketDataType.entries.firstOrNull { it.name == json } } +// ) +//} +// +// +///** Discriminator for [KafkatorioPacketData] */ //@Serializable -//data class KafkatorioPacket( -// val modVersion: String, -// val tick: Tick, -// val data: KafkatorioPacketData, -//) - - -@Serializable(with = KafkatorioPacketData.JsonSerializer::class) -sealed class KafkatorioPacketData { - abstract val updateType: KafkatorioPacketDataType - - object JsonSerializer : SerializerProviderDeserializer( - KafkatorioPacketData::class, - KafkatorioPacketData::updateType.name, - { json -> KafkatorioPacketDataType.entries.firstOrNull { it.name == json } } - ) -} - - -/** Discriminator for [KafkatorioPacketData] */ -@Serializable -enum class KafkatorioPacketDataType( - override val serializer: KSerializer -) : SerializerProvider { - - // non-keyed - CONFIG(ConfigurationUpdate.serializer()), - CONSOLE_CHAT(ConsoleChatUpdate.serializer()), - CONSOLE_COMMAND(ConsoleCommandUpdate.serializer()), - PROTOTYPES(PrototypesUpdate.serializer()), - SURFACE(SurfaceUpdate.serializer()), - - // keyed - ENTITY(EntityUpdate.serializer()), - MAP_CHUNK(MapChunkUpdate.serializer()), - PLAYER(PlayerUpdate.serializer()), - ; - - companion object { - val entries: Set = values().toSet() - } -} - -//inline fun KafkatorioPacketDataType.isType (): KClass { -// return when (this) { -// KafkatorioPacketDataType.CONFIG -> ConfigurationUpdate::class -// KafkatorioPacketDataType.CONSOLE_CHAT -> ConsoleChatUpdate::class -// KafkatorioPacketDataType.CONSOLE_COMMAND -> ConsoleCommandUpdate::class -// KafkatorioPacketDataType.PROTOTYPES -> PrototypesUpdate::class -// KafkatorioPacketDataType.SURFACE -> SurfaceUpdate::class -// KafkatorioPacketDataType.ENTITY -> EntityUpdate::class -// KafkatorioPacketDataType.MAP_CHUNK -> MapChunkUpdate::class -// KafkatorioPacketDataType.PLAYER -> PlayerUpdate::class +//enum class KafkatorioPacketDataType( +// override val serializer: KSerializer +//) : SerializerProvider { +// +// // non-keyed +// CONFIG(ConfigurationUpdate.serializer()), +// CONSOLE_CHAT(ConsoleChatUpdate.serializer()), +// CONSOLE_COMMAND(ConsoleCommandUpdate.serializer()), +// PROTOTYPES(PrototypesUpdate.serializer()), +// SURFACE(SurfaceUpdate.serializer()), +// +// // keyed +// ENTITY(EntityUpdate.serializer()), +// MAP_CHUNK(MapChunkUpdate.serializer()), +// PLAYER(PlayerUpdate.serializer()), +// ; +// +// companion object { +// val entries: Set = values().toSet() // } //} +// +////inline fun KafkatorioPacketDataType.isType (): KClass { +//// return when (this) { +//// KafkatorioPacketDataType.CONFIG -> ConfigurationUpdate::class +//// KafkatorioPacketDataType.CONSOLE_CHAT -> ConsoleChatUpdate::class +//// KafkatorioPacketDataType.CONSOLE_COMMAND -> ConsoleCommandUpdate::class +//// KafkatorioPacketDataType.PROTOTYPES -> PrototypesUpdate::class +//// KafkatorioPacketDataType.SURFACE -> SurfaceUpdate::class +//// KafkatorioPacketDataType.ENTITY -> EntityUpdate::class +//// KafkatorioPacketDataType.MAP_CHUNK -> MapChunkUpdate::class +//// KafkatorioPacketDataType.PLAYER -> PlayerUpdate::class +//// } +////} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketInstant.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketInstant.kt index c86f507..6dc03cc 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketInstant.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketInstant.kt @@ -1,95 +1,95 @@ package dev.adamko.kafkatorio.schema.events - -import dev.adamko.kafkatorio.schema.common.PlayerIndex -import dev.adamko.kafkatorio.schema.common.SurfaceIndex -import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype -import kotlinx.serialization.EncodeDefault -import kotlinx.serialization.Serializable - - -/** No key, no caching. Must be sent instantly. */ -sealed class KafkatorioInstantPacketData : KafkatorioPacketData() - - -/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ - - -@Serializable -data class ConfigurationUpdate( - val factorioData: ConfigurationUpdateGameData, - val allMods: List, - val modStartupSettingsChange: Boolean, - val migrationApplied: Boolean, -) : KafkatorioInstantPacketData() { - @EncodeDefault - override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.CONFIG - - @Serializable - data class ConfigurationUpdateGameData( - val oldVersion: String? = null, - val newVersion: String? = null, - ) - - @Serializable - data class ConfigurationUpdateModData( - val modName: String, - val currentVersion: String? = null, - val previousVersion: String? = null, - ) -} - - -/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ - - -@Serializable -data class ConsoleChatUpdate( - val authorPlayerIndex: PlayerIndex?, - val content: String, -) : KafkatorioInstantPacketData() { - @EncodeDefault - override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.CONSOLE_CHAT -} - - -/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ - - -@Serializable -data class ConsoleCommandUpdate( - val authorPlayerIndex: PlayerIndex?, - val command: String, - val parameters: String, -) : KafkatorioInstantPacketData() { - @EncodeDefault - override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.CONSOLE_COMMAND -} - - -/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ - - -@Serializable -data class PrototypesUpdate( - val prototypes: List, -) : KafkatorioInstantPacketData() { - @EncodeDefault - override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.PROTOTYPES -} - - -/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ - - -@Serializable -data class SurfaceUpdate( - val index: SurfaceIndex, - val daytime: Double, - val name: String, -) : KafkatorioInstantPacketData() { - @EncodeDefault - override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.SURFACE -} - - -/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ +// +//import dev.adamko.kafkatorio.schema.common.PlayerIndex +//import dev.adamko.kafkatorio.schema.common.SurfaceIndex +//import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype +//import kotlinx.serialization.EncodeDefault +//import kotlinx.serialization.Serializable +// +// +///** No key, no caching. Must be sent instantly. */ +//sealed class KafkatorioInstantPacketData : KafkatorioPacketData() +// +// +///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ +// +// +//@Serializable +//data class ConfigurationUpdate( +// val factorioData: ConfigurationUpdateGameData, +// val allMods: List, +// val modStartupSettingsChange: Boolean, +// val migrationApplied: Boolean, +//) : KafkatorioInstantPacketData() { +// @EncodeDefault +// override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.CONFIG +// +// @Serializable +// data class ConfigurationUpdateGameData( +// val oldVersion: String? = null, +// val newVersion: String? = null, +// ) +// +// @Serializable +// data class ConfigurationUpdateModData( +// val modName: String, +// val currentVersion: String? = null, +// val previousVersion: String? = null, +// ) +//} +// +// +///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ +// +// +//@Serializable +//data class ConsoleChatUpdate( +// val authorPlayerIndex: PlayerIndex?, +// val content: String, +//) : KafkatorioInstantPacketData() { +// @EncodeDefault +// override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.CONSOLE_CHAT +//} +// +// +///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ +// +// +//@Serializable +//data class ConsoleCommandUpdate( +// val authorPlayerIndex: PlayerIndex?, +// val command: String, +// val parameters: String, +//) : KafkatorioInstantPacketData() { +// @EncodeDefault +// override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.CONSOLE_COMMAND +//} +// +// +///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ +// +// +//@Serializable +//data class PrototypesUpdate( +// val prototypes: List, +//) : KafkatorioInstantPacketData() { +// @EncodeDefault +// override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.PROTOTYPES +//} +// +// +///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ +// +// +//@Serializable +//data class SurfaceUpdate( +// val index: SurfaceIndex, +// val daytime: Double, +// val name: String, +//) : KafkatorioInstantPacketData() { +// @EncodeDefault +// override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.SURFACE +//} +// +// +///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketKeyed.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketKeyed.kt index 14d8551..236ac6e 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketKeyed.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketKeyed.kt @@ -1,135 +1,135 @@ package dev.adamko.kafkatorio.schema.events -import dev.adamko.kafkatorio.schema.common.Colour -import dev.adamko.kafkatorio.schema.common.EntityIdentifiers -import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData -import dev.adamko.kafkatorio.schema.common.ForceIndex -import dev.adamko.kafkatorio.schema.common.MapChunkPosition -import dev.adamko.kafkatorio.schema.common.MapEntityPosition -import dev.adamko.kafkatorio.schema.common.MapTileDictionary -import dev.adamko.kafkatorio.schema.common.PlayerIndex -import dev.adamko.kafkatorio.schema.common.PrototypeName -import dev.adamko.kafkatorio.schema.common.SurfaceIndex -import dev.adamko.kafkatorio.schema.common.Tick -import dev.adamko.kafkatorio.schema.common.UnitNumber -import kotlinx.serialization.EncodeDefault -import kotlinx.serialization.Serializable - - -sealed interface KafkatorioKeyedPacketKey - - -/** Has a key, so it can be debounced */ -sealed class KafkatorioKeyedPacketData : KafkatorioPacketData() { - /** Count how many events this packet is aggregating data from */ - abstract val eventCounts: Map? -} - - -/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ - - -sealed interface EntityUpdateKey : EntityIdentifiers, KafkatorioKeyedPacketKey { - /** A [unitNumber] is required for caching */ - override val unitNumber: UnitNumber - override val name: String - override val protoType: String -} - - -@Serializable -data class EntityUpdate( - override val unitNumber: UnitNumber, - override val name: String, - override val protoType: String, - - override val eventCounts: Map? = null, - - val chunkPosition: MapChunkPosition? = null, - val graphicsVariation: UByte? = null, - val health: Float? = null, - val isActive: Boolean? = null, - val isRotatable: Boolean? = null, - val lastUser: UInt? = null, - val localisedDescription: String? = null, - val localisedName: String? = null, - val prototype: PrototypeName? = null, -) : KafkatorioKeyedPacketData(), EntityUpdateKey { - @EncodeDefault - override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.ENTITY -} - - -/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ - - -sealed interface MapChunkUpdateKey : KafkatorioKeyedPacketKey { - val chunkPosition: MapChunkPosition - val surfaceIndex: SurfaceIndex -} - - -@Serializable -data class MapChunkUpdate( - override val chunkPosition: MapChunkPosition, - override val surfaceIndex: SurfaceIndex, - - override val eventCounts: Map? = null, - - val player: PlayerIndex? = null, - val robot: EntityIdentifiersData? = null, - val force: ForceIndex? = null, - /** updated tiles - might be partial and not all tiles in the chunk */ - val tileDictionary: MapTileDictionary? = null, - val isDeleted: Boolean? = null, -) : KafkatorioKeyedPacketData(), MapChunkUpdateKey { - @EncodeDefault - override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.MAP_CHUNK -} - - -/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ - - -sealed interface PlayerUpdateKey : KafkatorioKeyedPacketKey { - val index: PlayerIndex -} - - -@Serializable -data class PlayerUpdate( - override val index: PlayerIndex, - - override val eventCounts: Map? = null, - - val characterUnitNumber: UnitNumber? = null, - val chatColour: Colour? = null, - val colour: Colour? = null, - val name: String? = null, - - val afkTime: Tick? = null, - val ticksToRespawn: Tick? = null, - val forceIndex: ForceIndex? = null, - val isAdmin: Boolean? = null, - val isConnected: Boolean? = null, - val isShowOnMap: Boolean? = null, - val isSpectator: Boolean? = null, - val lastOnline: Tick? = null, - val onlineTime: Tick? = null, - val position: MapEntityPosition? = null, - val surfaceIndex: SurfaceIndex? = null, - val tag: String? = null, - val diedCause: EntityIdentifiersData? = null, - - val bannedReason: String? = null, - val kickedReason: String? = null, - val disconnectReason: String? = null, - /** `true` when a player is removed (deleted) from the game */ - val isRemoved: Boolean? = null, -) : KafkatorioKeyedPacketData(), PlayerUpdateKey { - @EncodeDefault - override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.PLAYER -} - - -/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ +//import dev.adamko.kafkatorio.schema.common.Colour +//import dev.adamko.kafkatorio.schema.common.EntityIdentifiers +//import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData +//import dev.adamko.kafkatorio.schema.common.ForceIndex +//import dev.adamko.kafkatorio.schema.common.MapChunkPosition +//import dev.adamko.kafkatorio.schema.common.MapEntityPosition +//import dev.adamko.kafkatorio.schema.common.MapTileDictionary +//import dev.adamko.kafkatorio.schema.common.PlayerIndex +//import dev.adamko.kafkatorio.schema.common.PrototypeName +//import dev.adamko.kafkatorio.schema.common.SurfaceIndex +//import dev.adamko.kafkatorio.schema.common.Tick +//import dev.adamko.kafkatorio.schema.common.UnitNumber +//import kotlinx.serialization.EncodeDefault +//import kotlinx.serialization.Serializable +// +// +//sealed interface KafkatorioKeyedPacketKey +// +// +///** Has a key, so it can be debounced */ +//sealed class KafkatorioKeyedPacketData : KafkatorioPacketData() { +// /** Count how many events this packet is aggregating data from */ +// abstract val eventCounts: Map? +//} +// +// +///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ +// +// +//sealed interface EntityUpdateKey : EntityIdentifiers, KafkatorioKeyedPacketKey { +// /** A [unitNumber] is required for caching */ +// override val unitNumber: UnitNumber +// override val name: String +// override val protoType: String +//} +// +// +//@Serializable +//data class EntityUpdate( +// override val unitNumber: UnitNumber, +// override val name: String, +// override val protoType: String, +// +// override val eventCounts: Map? = null, +// +// val chunkPosition: MapChunkPosition? = null, +// val graphicsVariation: UByte? = null, +// val health: Float? = null, +// val isActive: Boolean? = null, +// val isRotatable: Boolean? = null, +// val lastUser: UInt? = null, +// val localisedDescription: String? = null, +// val localisedName: String? = null, +// val prototype: PrototypeName? = null, +//) : KafkatorioKeyedPacketData(), EntityUpdateKey { +// @EncodeDefault +// override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.ENTITY +//} +// +// +///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ +// +// +//sealed interface MapChunkUpdateKey : KafkatorioKeyedPacketKey { +// val chunkPosition: MapChunkPosition +// val surfaceIndex: SurfaceIndex +//} +// +// +//@Serializable +//data class MapChunkUpdate( +// override val chunkPosition: MapChunkPosition, +// override val surfaceIndex: SurfaceIndex, +// +// override val eventCounts: Map? = null, +// +// val player: PlayerIndex? = null, +// val robot: EntityIdentifiersData? = null, +// val force: ForceIndex? = null, +// /** updated tiles - might be partial and not all tiles in the chunk */ +// val tileDictionary: MapTileDictionary? = null, +// val isDeleted: Boolean? = null, +//) : KafkatorioKeyedPacketData(), MapChunkUpdateKey { +// @EncodeDefault +// override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.MAP_CHUNK +//} +// +// +///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ +// +// +//sealed interface PlayerUpdateKey : KafkatorioKeyedPacketKey { +// val index: PlayerIndex +//} +// +// +//@Serializable +//data class PlayerUpdate( +// override val index: PlayerIndex, +// +// override val eventCounts: Map? = null, +// +// val characterUnitNumber: UnitNumber? = null, +// val chatColour: Colour? = null, +// val colour: Colour? = null, +// val name: String? = null, +// +// val afkTime: Tick? = null, +// val ticksToRespawn: Tick? = null, +// val forceIndex: ForceIndex? = null, +// val isAdmin: Boolean? = null, +// val isConnected: Boolean? = null, +// val isShowOnMap: Boolean? = null, +// val isSpectator: Boolean? = null, +// val lastOnline: Tick? = null, +// val onlineTime: Tick? = null, +// val position: MapEntityPosition? = null, +// val surfaceIndex: SurfaceIndex? = null, +// val tag: String? = null, +// val diedCause: EntityIdentifiersData? = null, +// +// val bannedReason: String? = null, +// val kickedReason: String? = null, +// val disconnectReason: String? = null, +// /** `true` when a player is removed (deleted) from the game */ +// val isRemoved: Boolean? = null, +//) : KafkatorioKeyedPacketData(), PlayerUpdateKey { +// @EncodeDefault +// override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.PLAYER +//} +// +// +///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt index 775b664..a65c77d 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt @@ -1,58 +1,58 @@ package dev.adamko.kafkatorio.schema.prototypes - -import dev.adamko.kafkatorio.schema.SerializerProvider -import dev.adamko.kafkatorio.schema.SerializerProviderDeserializer -import dev.adamko.kafkatorio.schema.common.Colour -import dev.adamko.kafkatorio.schema.common.PrototypeName -import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.PrototypeObjectName -import kotlinx.serialization.Contextual -import kotlinx.serialization.DeserializationStrategy -import kotlinx.serialization.EncodeDefault -import kotlinx.serialization.KSerializer -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.JsonContentPolymorphicSerializer -import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.contentOrNull -import kotlinx.serialization.json.jsonObject -import kotlinx.serialization.json.jsonPrimitive - - -@Serializable(with = FactorioPrototype.JsonSerializer::class) -sealed class FactorioPrototype { - @EncodeDefault - abstract val prototypeObjectName: PrototypeObjectName - - enum class PrototypeObjectName( - override val serializer: KSerializer - ) : SerializerProvider { - LuaTilePrototype(MapTilePrototype.serializer()), - ; - - companion object { - val entries: Set = values().toSet() - } - } - - object JsonSerializer : SerializerProviderDeserializer( - FactorioPrototype::class, - FactorioPrototype::prototypeObjectName.name, - { json -> PrototypeObjectName.entries.firstOrNull { it.name == json } } - ) -} - - - -@Serializable -data class MapTilePrototype( - val name: PrototypeName, - val layer: UInt, - val mapColour: Colour, - @Contextual - val collisionMasks: List, - val order: String, - /** Can the tile be mined for resources? */ - val canBeMined: Boolean, -) : FactorioPrototype() { - @EncodeDefault - override val prototypeObjectName: PrototypeObjectName = PrototypeObjectName.LuaTilePrototype -} +// +//import dev.adamko.kafkatorio.schema.SerializerProvider +//import dev.adamko.kafkatorio.schema.SerializerProviderDeserializer +//import dev.adamko.kafkatorio.schema.common.Colour +//import dev.adamko.kafkatorio.schema.common.PrototypeName +//import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.PrototypeObjectName +//import kotlinx.serialization.Contextual +//import kotlinx.serialization.DeserializationStrategy +//import kotlinx.serialization.EncodeDefault +//import kotlinx.serialization.KSerializer +//import kotlinx.serialization.Serializable +//import kotlinx.serialization.json.JsonContentPolymorphicSerializer +//import kotlinx.serialization.json.JsonElement +//import kotlinx.serialization.json.contentOrNull +//import kotlinx.serialization.json.jsonObject +//import kotlinx.serialization.json.jsonPrimitive +// +// +//@Serializable(with = FactorioPrototype.JsonSerializer::class) +//sealed class FactorioPrototype { +// @EncodeDefault +// abstract val prototypeObjectName: PrototypeObjectName +// +// enum class PrototypeObjectName( +// override val serializer: KSerializer +// ) : SerializerProvider { +// LuaTilePrototype(MapTilePrototype.serializer()), +// ; +// +// companion object { +// val entries: Set = values().toSet() +// } +// } +// +// object JsonSerializer : SerializerProviderDeserializer( +// FactorioPrototype::class, +// FactorioPrototype::prototypeObjectName.name, +// { json -> PrototypeObjectName.entries.firstOrNull { it.name == json } } +// ) +//} +// +// +// +//@Serializable +//data class MapTilePrototype( +// val name: PrototypeName, +// val layer: UInt, +// val mapColour: Colour, +// @Contextual +// val collisionMasks: List, +// val order: String, +// /** Can the tile be mined for resources? */ +// val canBeMined: Boolean, +//) : FactorioPrototype() { +// @EncodeDefault +// override val prototypeObjectName: PrototypeObjectName = PrototypeObjectName.LuaTilePrototype +//} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketInstant2.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketInstant2.kt index fe75146..0dd179d 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketInstant2.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketInstant2.kt @@ -2,7 +2,6 @@ package dev.adamko.kafkatorio.schema2 import dev.adamko.kafkatorio.schema.common.PlayerIndex import dev.adamko.kafkatorio.schema.common.SurfaceIndex -import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2 import kotlinx.serialization.Serializable diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt index 22a3aef..eaf55a8 100644 --- a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt @@ -1,147 +1,147 @@ package dev.adamko.kafkatorio.events.schema -import dev.adamko.kafkatorio.schema.events.KafkatorioInstantPacketData -import dev.adamko.kafkatorio.schema.events.KafkatorioKeyedPacketData -import dev.adamko.kafkatorio.schema.events.KafkatorioKeyedPacketKey -//import dev.adamko.kafkatorio.schema.events.KafkatorioPacket -import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype -import kotlin.io.path.Path -import kotlin.io.path.createDirectories -import me.ntrrgc.tsGenerator.TypeScriptGenerator -import org.intellij.lang.annotations.Language - -/** - * Convert Kotlin classes to Typescript classes, using [TypeScriptGenerator] - */ -fun main(args: Array) { - - val gen = TypeScriptGenerator( - rootClasses = buildSet { -// add(KafkatorioPacket::class) -// addAll(KafkatorioPacket::class.sealedSubclasses) - - add(KafkatorioInstantPacketData::class) - addAll(KafkatorioInstantPacketData::class.sealedSubclasses) - - add(KafkatorioKeyedPacketData::class) - addAll(KafkatorioKeyedPacketData::class.sealedSubclasses) - addAll(KafkatorioKeyedPacketKey::class.sealedSubclasses) - - add(FactorioPrototype::class) - addAll(FactorioPrototype::class.sealedSubclasses) - }, - mappings = mapOf( - // builtin Factorio numeric types > `typed-factorio/generated/builtin-types.d.ts` - Float::class to "float", - Double::class to "double", - Int::class to "int", - Byte::class to "int8", - UInt::class to "uint", - UByte::class to "uint8", - UShort::class to "uint16", - ULong::class to "uint64", - ), - classTransformers = listOf( - ValueClassTransformer, -// PropertyNameTransformer, - ), -// voidType = VoidType.UNDEFINED, - ) - - val definitions = gen.definitionsText - - when (val filename = args.firstOrNull()) { - null -> println(definitions) - else -> { - val outPath = Path(filename) - outPath.createDirectories() - - splitDefinitions(definitions) - .forEach { (defFile, def) -> - val outFile = outPath.resolve(defFile).toFile() - outFile.printWriter().use { - it.println(kt2tsHeader) - it.print(def) - } - println("Generated file: $outFile") - } - - } - } -} - - -/** Split the TypeScript interfaces into different files */ -private fun splitDefinitions(definitions: String): Map { - return definitions - .split("\n\n") - .groupBy { def -> - - when { - def isInterface "KafkatorioPacket" - || def extendsAny listOf("KafkatorioPacket") - || def isType "KafkatorioPacketDataType" - -> "kafkatorio-packet.d.ts" - - def isInterface "KafkatorioInstantPacketData" - || def extends "KafkatorioInstantPacketData" - || def isType "KafkatorioInstantPacketDataType" - - || def isInterface "ConfigurationUpdateGameData" - || def isInterface "ConfigurationUpdateModData" - -> "kafkatorio-instant-packet.d.ts" - - def isInterface "KafkatorioKeyedPacket" - || def isInterface "KafkatorioKeyedPacketData" - || def extends "KafkatorioKeyedPacket" - || def isType "KafkatorioKeyedPacketDataType" - - || def isInterface "KafkatorioKeyedPacketKey" - -> "kafkatorio-keyed-packet.d.ts" - - def isInterface "FactorioPrototypes" - || def isInterface "FactorioPrototype" - || def extends "FactorioPrototype" - || def isType "PrototypeObjectName" - -> "prototype.d.ts" - - else -> "schema.d.ts" - } - } - .mapValues { (_, def) -> - def - .sorted() - .joinToString("\n\n", postfix = "\n") - .replace(" ", " ") - } -} - -@Language("TypeScript") -val kt2tsHeader = """ - |// Generated by TypeScriptGenerator - do not edit this file manually - | -""".trimMargin() - -private infix fun String.extends(types: String): Boolean = - contains(Regex(".+extends.*(${types})")) - -private infix fun String.extendsAny(types: List): Boolean = - extends(types.joinToString("|") { "$it,".replaceAfterLast(',', "") }) - -private infix fun String.isInterface(type: String): Boolean = - contains(Regex("interface $type.*")) - - -private infix fun String.isType(type: String): Boolean = - contains(Regex("type $type.*")) - - -//object PropertyNameTransformer : ClassTransformer { -// override fun transformPropertyName( -// propertyName: String, -// property: KProperty<*>, -// klass: KClass<*> -// ): String { -// return camelCaseToSnakeCase(propertyName) +//import dev.adamko.kafkatorio.schema.events.KafkatorioInstantPacketData +//import dev.adamko.kafkatorio.schema.events.KafkatorioKeyedPacketData +//import dev.adamko.kafkatorio.schema.events.KafkatorioKeyedPacketKey +////import dev.adamko.kafkatorio.schema.events.KafkatorioPacket +//import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype +//import kotlin.io.path.Path +//import kotlin.io.path.createDirectories +//import me.ntrrgc.tsGenerator.TypeScriptGenerator +//import org.intellij.lang.annotations.Language +// +///** +// * Convert Kotlin classes to Typescript classes, using [TypeScriptGenerator] +// */ +//fun main(args: Array) { +// +// val gen = TypeScriptGenerator( +// rootClasses = buildSet { +//// add(KafkatorioPacket::class) +//// addAll(KafkatorioPacket::class.sealedSubclasses) +// +// add(KafkatorioInstantPacketData::class) +// addAll(KafkatorioInstantPacketData::class.sealedSubclasses) +// +// add(KafkatorioKeyedPacketData::class) +// addAll(KafkatorioKeyedPacketData::class.sealedSubclasses) +// addAll(KafkatorioKeyedPacketKey::class.sealedSubclasses) +// +// add(FactorioPrototype::class) +// addAll(FactorioPrototype::class.sealedSubclasses) +// }, +// mappings = mapOf( +// // builtin Factorio numeric types > `typed-factorio/generated/builtin-types.d.ts` +// Float::class to "float", +// Double::class to "double", +// Int::class to "int", +// Byte::class to "int8", +// UInt::class to "uint", +// UByte::class to "uint8", +// UShort::class to "uint16", +// ULong::class to "uint64", +// ), +// classTransformers = listOf( +// ValueClassTransformer, +//// PropertyNameTransformer, +// ), +//// voidType = VoidType.UNDEFINED, +// ) +// +// val definitions = gen.definitionsText +// +// when (val filename = args.firstOrNull()) { +// null -> println(definitions) +// else -> { +// val outPath = Path(filename) +// outPath.createDirectories() +// +// splitDefinitions(definitions) +// .forEach { (defFile, def) -> +// val outFile = outPath.resolve(defFile).toFile() +// outFile.printWriter().use { +// it.println(kt2tsHeader) +// it.print(def) +// } +// println("Generated file: $outFile") +// } +// +// } // } //} +// +// +///** Split the TypeScript interfaces into different files */ +//private fun splitDefinitions(definitions: String): Map { +// return definitions +// .split("\n\n") +// .groupBy { def -> +// +// when { +// def isInterface "KafkatorioPacket" +// || def extendsAny listOf("KafkatorioPacket") +// || def isType "KafkatorioPacketDataType" +// -> "kafkatorio-packet.d.ts" +// +// def isInterface "KafkatorioInstantPacketData" +// || def extends "KafkatorioInstantPacketData" +// || def isType "KafkatorioInstantPacketDataType" +// +// || def isInterface "ConfigurationUpdateGameData" +// || def isInterface "ConfigurationUpdateModData" +// -> "kafkatorio-instant-packet.d.ts" +// +// def isInterface "KafkatorioKeyedPacket" +// || def isInterface "KafkatorioKeyedPacketData" +// || def extends "KafkatorioKeyedPacket" +// || def isType "KafkatorioKeyedPacketDataType" +// +// || def isInterface "KafkatorioKeyedPacketKey" +// -> "kafkatorio-keyed-packet.d.ts" +// +// def isInterface "FactorioPrototypes" +// || def isInterface "FactorioPrototype" +// || def extends "FactorioPrototype" +// || def isType "PrototypeObjectName" +// -> "prototype.d.ts" +// +// else -> "schema.d.ts" +// } +// } +// .mapValues { (_, def) -> +// def +// .sorted() +// .joinToString("\n\n", postfix = "\n") +// .replace(" ", " ") +// } +//} +// +//@Language("TypeScript") +//val kt2tsHeader = """ +// |// Generated by TypeScriptGenerator - do not edit this file manually +// | +//""".trimMargin() +// +//private infix fun String.extends(types: String): Boolean = +// contains(Regex(".+extends.*(${types})")) +// +//private infix fun String.extendsAny(types: List): Boolean = +// extends(types.joinToString("|") { "$it,".replaceAfterLast(',', "") }) +// +//private infix fun String.isInterface(type: String): Boolean = +// contains(Regex("interface $type.*")) +// +// +//private infix fun String.isType(type: String): Boolean = +// contains(Regex("type $type.*")) +// +// +////object PropertyNameTransformer : ClassTransformer { +//// override fun transformPropertyName( +//// propertyName: String, +//// property: KProperty<*>, +//// klass: KClass<*> +//// ): String { +//// return camelCaseToSnakeCase(propertyName) +//// } +////} diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt index 38b03e3..6976f5b 100644 --- a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt @@ -10,6 +10,7 @@ import dev.adamko.kxstsgen.core.TsTypeRef import kotlin.io.path.Path import kotlin.io.path.createDirectories import kotlinx.serialization.builtins.serializer +import org.intellij.lang.annotations.Language @ExperimentalUnsignedTypes @@ -53,3 +54,9 @@ fun main(args: Array) { } } } + +@Language("TypeScript") +val kt2tsHeader = """ + |// Generated by kxs-ts-gen - do not edit this file manually + | +""".trimMargin() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index 3ab14fc..96c055a 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -5,7 +5,6 @@ import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.MapTile import dev.adamko.kafkatorio.schema.common.toHex import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2 -import dev.adamko.kafkatorio.schema.prototypes.MapTilePrototype import dev.adamko.kafkatorio.schema2.PrototypesUpdate import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.streams.filter @@ -21,7 +20,6 @@ import org.apache.kafka.streams.kstream.KTable @JvmInline @Serializable value class TileProtoHashCode private constructor(val code: Int) { - constructor(prototype: MapTilePrototype) : this(prototype.name.hashCode()) constructor(tile: MapTile) : this(tile.proto.hashCode()) constructor(tile: FactorioPrototype2.MapTile) : this(tile.name.hashCode()) } From 03e8e9442a5dfea8e71617a88ed23e2c249012b9 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 11:52:00 +0200 Subject: [PATCH 268/629] try fixing dependabot alerts --- gradle/kotlin-js-store/yarn.lock | 660 +++++++++++++++++-------------- modules/web-map/build.gradle.kts | 10 +- 2 files changed, 375 insertions(+), 295 deletions(-) diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index 877dddb..7449ad4 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -3,16 +3,16 @@ "@babel/runtime@^7.9.2": - version "7.16.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.5.tgz#7f3e34bf8bdbbadf03fbb7b1ea0d929569c9487a" - integrity sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA== + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72" + integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg== dependencies: regenerator-runtime "^0.13.4" "@discoveryjs/json-ext@^0.5.0": - version "0.5.6" - resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" - integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA== + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== "@fortawesome/fontawesome-free@^6.1.1": version "6.1.1" @@ -127,19 +127,14 @@ "@types/estree" "*" "@types/eslint@*": - version "8.2.1" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.2.1.tgz#13f3d69bac93c2ae008019c28783868d0a1d6605" - integrity sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ== + version "8.4.1" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.1.tgz#c48251553e8759db9e656de3efc846954ac32304" + integrity sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA== dependencies: "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*": - version "0.0.50" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" - integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== - -"@types/estree@^0.0.51": +"@types/estree@*", "@types/estree@^0.0.51": version "0.0.51" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== @@ -176,7 +171,7 @@ "@types/minimatch" "*" "@types/node" "*" -"@types/http-proxy@^1.17.5": +"@types/http-proxy@^1.17.8": version "1.17.8" resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.8.tgz#968c66903e7e42b483608030ee85800f22d03f55" integrity sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA== @@ -184,14 +179,14 @@ "@types/node" "*" "@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.9" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" - integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== "@types/leaflet@^1.7.7": - version "1.7.7" - resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.7.7.tgz#3c9f629126e03405ed68cc1aa395e32df3312376" - integrity sha512-5/nNqTviSqUwPxbS3PlHl8ODjfnlpOXSFtUAi7dexnisO8E3pfyotChRY/hlIYGvbBiBcKNd6V18xA8O4OpHiQ== + version "1.7.9" + resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.7.9.tgz#7993d34f14cfa88c45b3d490daba39a3a1be9a2b" + integrity sha512-H8vPgD49HKzqM41ArHGZM70g/tfhp8W+JcPxfnF+5H/Xvp+xiP+KQOUNWU8U89fqS1Jj3cpRY/+nbnaHFzwnFA== dependencies: "@types/geojson" "*" @@ -206,9 +201,9 @@ integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== "@types/node@*", "@types/node@>=10.0.0": - version "17.0.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.2.tgz#a4c07d47ff737e8ee7e586fe636ff0e1ddff070a" - integrity sha512-JepeIUPFDARgIs0zD/SKPgFsJEAF0X5/qO80llx59gOxFTboS9Amv3S+QfB7lqBId5sFXJ99BN0J6zFRvL9dDA== + version "17.0.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.25.tgz#527051f3c2f77aa52e5dc74e45a3da5fb2301448" + integrity sha512-wANk6fBrUwdpY4isjWrKTufkrXdu1D2YHCot2fD/DfWxF5sMrVSA+KN7ydckvaTCh0HiqX9IVl0L5/ZoXg5M7w== "@types/parse5@^5": version "5.0.3" @@ -253,9 +248,9 @@ "@types/node" "*" "@types/ws@^8.2.2": - version "8.2.2" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.2.2.tgz#7c5be4decb19500ae6b3d563043cd407bf366c21" - integrity sha512-NOn5eIcgWLOo6qW8AcuLZ7G8PycXu0xTxxkS6Q18VWFxgPUSOwV0pBj2a/4viNZVu25i7RIB7GttdkAIUUXOOg== + version "8.5.3" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== dependencies: "@types/node" "*" @@ -413,27 +408,27 @@ integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== abab@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" - integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" + mime-types "~2.1.34" + negotiator "0.6.3" acorn-import-assertions@^1.7.6: version "1.8.0" resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== -acorn@^8.4.1: - version "8.6.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" - integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== +acorn@^8.4.1, acorn@^8.5.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== aggregate-error@^3.0.0: version "3.1.0" @@ -473,9 +468,9 @@ ajv@^6.12.5: uri-js "^4.2.2" ajv@^8.0.0, ajv@^8.8.0: - version "8.8.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.8.2.tgz#01b4fef2007a28bf75f0b7fc009f62679de4abbb" - integrity sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw== + version "8.11.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" + integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -544,14 +539,7 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -async@^2.6.2: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== - dependencies: - lodash "^4.17.14" - -async@^2.6.4: +async@^2.6.2, async@^2.6.4: version "2.6.4" resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== @@ -583,22 +571,40 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -body-parser@1.19.1, body-parser@^1.19.0: - version "1.19.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.1.tgz#1499abbaa9274af3ecc9f6f10396c995943e31d4" - integrity sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA== +body-parser@1.19.2: + version "1.19.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.2.tgz#4714ccd9c157d44797b8b5607d72c0b89952f26e" + integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw== dependencies: - bytes "3.1.1" + bytes "3.1.2" content-type "~1.0.4" debug "2.6.9" depd "~1.1.2" http-errors "1.8.1" iconv-lite "0.4.24" on-finished "~2.3.0" - qs "6.9.6" - raw-body "2.4.2" + qs "6.9.7" + raw-body "2.4.3" type-is "~1.6.18" +body-parser@^1.19.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" + integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.10.3" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + bonjour@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" @@ -629,7 +635,7 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: +braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -642,14 +648,14 @@ browser-stdout@1.3.1: integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== browserslist@^4.14.5: - version "4.19.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" - integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== + version "4.20.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88" + integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA== dependencies: - caniuse-lite "^1.0.30001286" - electron-to-chromium "^1.4.17" + caniuse-lite "^1.0.30001317" + electron-to-chromium "^1.4.84" escalade "^3.1.1" - node-releases "^2.0.1" + node-releases "^2.0.2" picocolors "^1.0.0" buffer-from@^1.0.0: @@ -667,12 +673,12 @@ bytes@3.0.0: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= -bytes@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a" - integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg== +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -call-bind@^1.0.2: +call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== @@ -681,14 +687,14 @@ call-bind@^1.0.2: get-intrinsic "^1.0.2" camelcase@^6.0.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.1.tgz#250fd350cfd555d0d2160b1d51510eaf8326e86e" - integrity sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA== + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001286: - version "1.0.30001292" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001292.tgz#4a55f61c06abc9595965cfd77897dc7bc1cdc456" - integrity sha512-jnT4Tq0Q4ma+6nncYQVe7d73kmDmE9C3OGTx3MvW7lBM/eY1S1DZTMBON7dqV481RhNiS5OxD7k9JQvmDOTirw== +caniuse-lite@^1.0.30001317: + version "1.0.30001332" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001332.tgz#39476d3aa8d83ea76359c70302eafdd4a1d727dd" + integrity sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw== chalk@^2.3.0: version "2.4.2" @@ -712,7 +718,7 @@ chart.js@^3.7.1: resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.7.1.tgz#0516f690c6a8680c6c707e31a4c1807a6f400ada" integrity sha512-8knRegQLFnPQAheZV8MjxIXc5gQEfDFD897BJgv/klO/vtIyFFmgMXrNfgrXpbTr/XbTturxRgxIXx/Y+ASJBA== -chokidar@3.5.2, chokidar@^3.5.1: +chokidar@3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== @@ -727,7 +733,7 @@ chokidar@3.5.2, chokidar@^3.5.1: optionalDependencies: fsevents "~2.3.2" -chokidar@3.5.3, chokidar@^3.5.3: +chokidar@3.5.3, chokidar@^3.5.1, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -881,10 +887,10 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= -cookie@0.4.1, cookie@~0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" - integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== +cookie@0.4.2, cookie@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== core-util-is@~1.0.0: version "1.0.3" @@ -937,10 +943,10 @@ custom-event@~1.0.0: resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= -date-format@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.4.tgz#b58036e29e74121fca3e1b3e0dc4a62c65faa233" - integrity sha512-/jyf4rhB17ge328HJuJjAcmRtCsGd+NDeAtahRBTaK6vSPR6MO5HlrAit3Nn7dVjaa6sowW0WXt8yQtLyZQFRg== +date-format@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.7.tgz#aa1cf4400badfe693c8462bbfcba43ab821d7d14" + integrity sha512-k5xqlzDGIfv2N/DHR/BR8Kc4N9CRy9ReuDkmdxeX/jNfit94QXd36emWMm40ZOEDKNm/c91yV9EO3uGPkR7wWQ== debug@2.6.9: version "2.6.9" @@ -956,7 +962,7 @@ debug@4.3.2: dependencies: ms "2.1.2" -debug@4.3.3, debug@^4.1.0, debug@^4.3.3, debug@~4.3.1, debug@~4.3.2: +debug@4.3.3: version "4.3.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== @@ -970,6 +976,13 @@ debug@^3.1.1: dependencies: ms "^2.1.1" +debug@^4.1.0, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + decamelize@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" @@ -1000,11 +1013,12 @@ define-lazy-prop@^2.0.0: integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== dependencies: - object-keys "^1.0.12" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" del@^6.0.0: version "6.0.0" @@ -1020,11 +1034,21 @@ del@^6.0.0: rimraf "^3.0.2" slash "^3.0.0" +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" @@ -1103,10 +1127,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.4.17: - version "1.4.27" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.27.tgz#bfc6e798d8a56a17d658312f4b7ae1a7ca87724f" - integrity sha512-uZ95szi3zUbzRDx1zx/xnsCG+2xgZyy57pDOeaeO4r8zx5Dqe8Jv1ti8cunvBwJHVI5LzPuw8umKwZb3WKYxSQ== +electron-to-chromium@^1.4.84: + version "1.4.114" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.114.tgz#d85ec0808dd50b0cf6e6b262480ffd385f71c873" + integrity sha512-gRwLpVYWHGbERPU6o8pKfR168V6enWEXzZc6zQNNXbgJ7UJna+9qzAIHY94+9KOv71D/CH+QebLA9pChD2q8zA== element-resize-event@^3.0.6: version "3.0.6" @@ -1130,7 +1154,7 @@ encoding@^0.1.12: dependencies: iconv-lite "^0.6.2" -engine.io-parser@~5.0.0: +engine.io-parser@~5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.3.tgz#ca1f0d7b11e290b4bfda251803baea765ed89c09" integrity sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg== @@ -1138,9 +1162,9 @@ engine.io-parser@~5.0.0: "@socket.io/base64-arraybuffer" "~1.0.2" engine.io@~6.1.0: - version "6.1.2" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.1.2.tgz#e7b9d546d90c62246ffcba4d88594be980d3855a" - integrity sha512-v/7eGHxPvO2AWsksyx2PUsQvBafuvqs0jJJQ0FdmJG1b9qIvgSbqDRGwNhfk2XHaTTbTXiC4quRE8Q9nRjsrQQ== + version "6.1.3" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.1.3.tgz#f156293d011d99a3df5691ac29d63737c3302e6f" + integrity sha512-rqs60YwkvWTLLnfazqgZqLa/aKo+9cueVfEi/dZ8PyGyaf8TLOxj++4QMIgeG3Gn0AhrWiFXvghsoY9L9h25GA== dependencies: "@types/cookie" "^0.4.1" "@types/cors" "^2.8.12" @@ -1150,13 +1174,13 @@ engine.io@~6.1.0: cookie "~0.4.1" cors "~2.8.5" debug "~4.3.1" - engine.io-parser "~5.0.0" + engine.io-parser "~5.0.3" ws "~8.2.3" enhanced-resolve@^5.8.3: - version "5.8.3" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" - integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA== + version "5.9.3" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz#44a342c012cbc473254af5cc6ae20ebd0aae5d88" + integrity sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -1252,16 +1276,16 @@ execa@^5.0.0: strip-final-newline "^2.0.0" express@^4.17.1: - version "4.17.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.2.tgz#c18369f265297319beed4e5558753cc8c1364cb3" - integrity sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg== + version "4.17.3" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.3.tgz#f6c7302194a4fb54271b73a1fe7a06478c8f85a1" + integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg== dependencies: - accepts "~1.3.7" + accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.19.1" + body-parser "1.19.2" content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.4.1" + cookie "0.4.2" cookie-signature "1.0.6" debug "2.6.9" depd "~1.1.2" @@ -1276,7 +1300,7 @@ express@^4.17.1: parseurl "~1.3.3" path-to-regexp "0.1.7" proxy-addr "~2.0.7" - qs "6.9.6" + qs "6.9.7" range-parser "~1.2.1" safe-buffer "5.2.1" send "0.17.2" @@ -1297,10 +1321,10 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.1.1: - version "3.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" - integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== +fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -1333,9 +1357,9 @@ faye-websocket@^0.11.3: websocket-driver ">=0.5.1" fecha@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce" - integrity sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q== + version "4.2.3" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" + integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw== fill-range@^7.0.1: version "7.0.1" @@ -1383,12 +1407,7 @@ flatted@^3.2.5: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== -follow-redirects@^1.0.0: - version "1.14.6" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.6.tgz#8cfb281bbc035b3c067d6cd975b0f6ade6e855cd" - integrity sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A== - -follow-redirects@^1.14.8: +follow-redirects@^1.0.0, follow-redirects@^1.14.8: version "1.14.9" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== @@ -1409,9 +1428,9 @@ fresh@0.5.2: integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= fs-extra@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.1.tgz#27de43b4320e833f6867cc044bfce29fdf0ef3b8" - integrity sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag== + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" @@ -1446,6 +1465,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +functions-have-names@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + geojson@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/geojson/-/geojson-0.5.0.tgz#3cd6c96399be65b56ee55596116fe9191ce701c0" @@ -1456,7 +1480,7 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2: +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== @@ -1482,9 +1506,9 @@ gettext-extract@^2.0.1: minimist "^1.2.0" gettext-extractor@^3.1.0: - version "3.5.3" - resolved "https://registry.yarnpkg.com/gettext-extractor/-/gettext-extractor-3.5.3.tgz#6ed46931c154a7485a80fa8b91b835ff7b8d0411" - integrity sha512-9EgJ+hmbtAbATdMIvCj4WnrkeDWH6fv1z+IJJ1XCxdcUMGx6JQdVVFTdzJkSyIHh4td53ngoB5EQbavbKJU9Og== + version "3.5.4" + resolved "https://registry.yarnpkg.com/gettext-extractor/-/gettext-extractor-3.5.4.tgz#bd36c65b4d26014ffd925f9ac7b4738d6893d6b2" + integrity sha512-iK4tSnteSw+pFMts43OP8hUnsOklbkxz3ytWqru7dPf8Ec3uzTYv1aw70ojAvKItmofpj1ibfY7sZWsdSN6zIw== dependencies: "@types/glob" "5 - 7" "@types/parse5" "^5" @@ -1554,15 +1578,15 @@ glob@7.1.7: path-is-absolute "^1.0.0" globby@^11.0.1: - version "11.0.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" - integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" slash "^3.0.0" google-protobuf@3.12.2: @@ -1570,15 +1594,10 @@ google-protobuf@3.12.2: resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.12.2.tgz#50ce9f9b6281235724eb243d6a83e969a2176e53" integrity sha512-4CZhpuRr1d6HjlyrxoXoocoGFnRYgKULgMtikMddA9ztRyYR59Aondv2FioyxWVamRo0rF2XpYawkTCBEQOSkA== -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6: - version "4.2.8" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" - integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== - -graceful-fs@^4.2.9: - version "4.2.9" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" - integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== growl@1.10.5: version "1.10.5" @@ -1600,10 +1619,17 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + has-symbols@^1.0.1, has-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" - integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== has-tostringtag@^1.0.0: version "1.0.0" @@ -1635,9 +1661,9 @@ hpack.js@^2.1.6: wbuf "^1.1.0" html-entities@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488" - integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ== + version "2.3.3" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" + integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== html-parse-stringify@^3: version "3.0.1" @@ -1662,6 +1688,17 @@ http-errors@1.8.1: statuses ">= 1.5.0 < 2" toidentifier "1.0.1" +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + http-errors@~1.6.2: version "1.6.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" @@ -1673,16 +1710,16 @@ http-errors@~1.6.2: statuses ">= 1.4.0 < 2" http-parser-js@>=0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.5.tgz#d7c30d5d3c90d865b4a2e870181f9d6f22ac7ac5" - integrity sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA== + version "0.5.6" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.6.tgz#2e02406ab2df8af8a7abfba62e0da01c62b95afd" + integrity sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA== http-proxy-middleware@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.1.tgz#7ef3417a479fb7666a571e09966c66a39bd2c15f" - integrity sha512-cfaXRVoZxSed/BmkA7SwBVNI9Kj7HFltaE5rqYOub5kWzWZ+gofV2koVN1j2rMW7pEfSSlCHGJ31xmuyFyfLOg== + version "2.0.5" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.5.tgz#2d12fb41a414889372643a1f54279a2f6470aa93" + integrity sha512-ORErEaxkjyrhifofwCuQttHPUSestLtiPDwV0qQOFB0ww6695H953wIGRnkakw1K+GAP+t8/RPbfDB75RFL4Fg== dependencies: - "@types/http-proxy" "^1.17.5" + "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" is-glob "^4.0.1" is-plain-obj "^3.0.0" @@ -1721,15 +1758,15 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -ignore@^5.1.4: +ignore@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== import-local@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.3.tgz#4d51c2c495ca9393da259ec66b62e022920211e0" - integrity sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== dependencies: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" @@ -1800,10 +1837,10 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-core-module@^2.2.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" - integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== +is-core-module@^2.8.1: + version "2.9.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== dependencies: has "^1.0.3" @@ -1899,9 +1936,9 @@ isarray@~1.0.0: integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= isbinaryfile@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.8.tgz#5d34b94865bd4946633ecc78a026fc76c5b11fcf" - integrity sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w== + version "4.0.10" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" + integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== isexe@^2.0.0: version "2.0.0" @@ -1913,10 +1950,10 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -jest-worker@^27.4.1: - version "27.4.5" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.5.tgz#d696e3e46ae0f24cff3fa7195ffba22889262242" - integrity sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg== +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== dependencies: "@types/node" "*" merge-stream "^2.0.0" @@ -2036,14 +2073,14 @@ kvision-assets@^5.0.8: integrity sha512-umq47D8z2W7cTYR/6RtJ+048mlsi5X515tcM/PFgDcbaI82Pd9EHv2m9520SxmBH6AD04GTweWNyUcKlPx9oZQ== leaflet@^1.7.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.7.1.tgz#10d684916edfe1bf41d688a3b97127c0322a2a19" - integrity sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw== + version "1.8.0" + resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.8.0.tgz#4615db4a22a304e8e692cae9270b983b38a2055e" + integrity sha512-gwhMjFCQiYs3x/Sf+d49f10ERXaEFCPr+nVTryhAW8DWbMGqJqt9G4XuIaHmFW08zYvhgdzqXGr8AlW8v8dQkA== loader-runner@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" - integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== locate-path@^5.0.0: version "5.0.0" @@ -2073,15 +2110,15 @@ log-symbols@4.1.0: is-unicode-supported "^0.1.0" log4js@^6.4.1: - version "6.4.2" - resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.4.2.tgz#45ec783835acc525b397f52cf086e26994fe3b70" - integrity sha512-k80cggS2sZQLBwllpT1p06GtfvzMmSdUCkW96f0Hj83rKGJDAu2vZjt9B9ag2vx8Zz1IXzxoLgqvRJCdMKybGg== + version "6.4.5" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.4.5.tgz#5cca31b29ece65a625efbc3df6fcbd9cecb9ee7b" + integrity sha512-43RJcYZ7nfUxpPO2woTl8CJ0t5+gucLJZ43mtp2PlInT+LygCp/bl6hNJtKulCJ+++fQsjIv4EO3Mp611PfeLQ== dependencies: - date-format "^4.0.4" - debug "^4.3.3" + date-format "^4.0.7" + debug "^4.3.4" flatted "^3.2.5" rfdc "^1.3.0" - streamroller "^3.0.4" + streamroller "^3.0.7" lru-cache@^6.0.0: version "6.0.0" @@ -2112,7 +2149,7 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.3.0: +merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -2123,24 +2160,24 @@ methods@~1.1.2: integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= micromatch@^4.0.2, micromatch@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" - integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== dependencies: - braces "^3.0.1" - picomatch "^2.2.3" + braces "^3.0.2" + picomatch "^2.3.1" -mime-db@1.51.0, "mime-db@>= 1.43.0 < 2": - version "1.51.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" - integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24: - version "2.1.34" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" - integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: - mime-db "1.51.0" + mime-db "1.52.0" mime@1.6.0: version "1.6.0" @@ -2162,29 +2199,31 @@ minimalistic-assert@^1.0.0: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@3.0.4, minimatch@^3.0.4: +minimatch@3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +minimatch@^3.0.4: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" -minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== mkdirp@^0.5.5: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== dependencies: - minimist "^1.2.5" + minimist "^1.2.6" mocha@9.1.2: version "9.1.2" @@ -2284,40 +2323,30 @@ nanoid@3.2.0: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== -nanoid@^3.1.31: +nanoid@^3.1.31, nanoid@^3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== -nanoid@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" - integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== - -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -node-forge@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.2.1.tgz#82794919071ef2eb5c509293325cec8afd0fd53c" - integrity sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w== - -node-forge@^1.3.0: +node-forge@^1, node-forge@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== -node-releases@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" - integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== +node-releases@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" + integrity sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -2336,6 +2365,11 @@ object-assign@^4: resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= +object-inspect@^1.9.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" + integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== + object-is@^1.0.1: version "1.1.5" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" @@ -2344,7 +2378,7 @@ object-is@^1.0.1: call-bind "^1.0.2" define-properties "^1.1.3" -object-keys@^1.0.12, object-keys@^1.1.1: +object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -2354,6 +2388,13 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -2462,7 +2503,7 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.6: +path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== @@ -2482,10 +2523,10 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" - integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== pkg-dir@^4.2.0: version "4.2.0" @@ -2537,9 +2578,9 @@ postcss-modules-values@^4.0.0: icss-utils "^5.0.0" postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: - version "6.0.8" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.8.tgz#f023ed7a9ea736cd7ef70342996e8e78645a7914" - integrity sha512-D5PG53d209Z1Uhcc0qAZ5U3t5HagH3cxu+WLZ22jt3gLUpXM4eXXfiO14jiDWST3NNooX/E8wISfOhZ9eIjGTQ== + version "6.0.10" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" + integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -2550,9 +2591,9 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== postcss@^8.4.7: - version "8.4.8" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.8.tgz#dad963a76e82c081a0657d3a2f3602ce10c2e032" - integrity sha512-2tXEqGxrjvAO6U+CJzDL2Fk2kPHTv1jQsYkSoMeOis2SsYaXRO2COxTdQp99cYvif9JTXaAk9lYGc3VhJt7JPQ== + version "8.4.12" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.12.tgz#1e7de78733b28970fa4743f7da6f3763648b1905" + integrity sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg== dependencies: nanoid "^3.3.1" picocolors "^1.0.0" @@ -2581,10 +2622,17 @@ qjobs@^1.2.0: resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== -qs@6.9.6: - version "6.9.6" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" - integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== +qs@6.10.3: + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== + dependencies: + side-channel "^1.0.4" + +qs@6.9.7: + version "6.9.7" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe" + integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== queue-microtask@^1.2.2: version "1.2.3" @@ -2603,16 +2651,26 @@ range-parser@^1.2.1, range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32" - integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ== +raw-body@2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.3.tgz#8f80305d11c2a0a545c2d9d89d7a0286fcead43c" + integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g== dependencies: - bytes "3.1.1" + bytes "3.1.2" http-errors "1.8.1" iconv-lite "0.4.24" unpipe "1.0.0" +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + readable-stream@^2.0.1: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" @@ -2655,9 +2713,9 @@ redux-thunk@^2.4.1: integrity sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q== redux@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.2.tgz#140f35426d99bb4729af760afcf79eaaac407104" - integrity sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw== + version "4.2.0" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.0.tgz#46f10d6e29b6666df758780437651eeb2b969f13" + integrity sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA== dependencies: "@babel/runtime" "^7.9.2" @@ -2667,12 +2725,13 @@ regenerator-runtime@^0.13.4: integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== regexp.prototype.flags@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" - integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" + functions-have-names "^1.2.2" require-directory@^2.1.1: version "2.1.1" @@ -2702,12 +2761,13 @@ resolve-from@^5.0.0: integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== resolve@^1.9.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" retry@^0.13.1: version "0.13.1" @@ -2778,16 +2838,16 @@ select-hose@^2.0.0: integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= selfsigned@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.0.tgz#e927cd5377cbb0a1075302cff8df1042cc2bce5b" - integrity sha512-cUdFiCbKoa1mZ6osuJs2uDHrs0k0oprsKveFiiaBKCNq3SYyb5gs2HxhQyDNLCmL51ZZThqi4YNDpCK6GOP1iQ== + version "2.0.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" + integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ== dependencies: - node-forge "^1.2.0" + node-forge "^1" semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== dependencies: lru-cache "^6.0.0" @@ -2869,10 +2929,19 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + signal-exit@^3.0.3: - version "3.0.6" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" - integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== slash@^3.0.0: version "3.0.0" @@ -2992,18 +3061,23 @@ split.js@^1.6.5: resolved "https://registry.yarnpkg.com/split.js/-/split.js-1.6.5.tgz#f7f61da1044c9984cb42947df4de4fadb5a3f300" integrity sha512-mPTnGCiS/RiuTNsVhCm9De9cCAUsrNFFviRbADdKiiV+Kk8HKp/0fWu7Kr8pi3/yBmsqLFHuXGT9UUZ+CNLwFw== +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + "statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -streamroller@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.0.4.tgz#27ad87339d829483f89c5f33fd60ea6731e4183c" - integrity sha512-GI9NzeD+D88UFuIlJkKNDH/IsuR+qIN7Qh8EsmhoRZr9bQoehTraRgwtLUkZbpcAw+hLPfHOypmppz8YyGK68w== +streamroller@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.0.7.tgz#d566353d3d8b5d2f3d813d2df557c08083b414cf" + integrity sha512-kh68kwiDGuIPiPDWwRbEC5us+kfARP1e9AsQiaLaSqGrctOvMn0mtL8iNY3r4/o5nIoYi3gPI1jexguZsXDlxw== dependencies: - date-format "^4.0.4" - debug "^4.3.3" + date-format "^4.0.7" + debug "^4.3.4" fs-extra "^10.0.1" string-width@^4.1.0, string-width@^4.2.0: @@ -3084,27 +3158,33 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tapable@^2.1.1, tapable@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== terser-webpack-plugin@^5.1.3: - version "5.3.0" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz#21641326486ecf91d8054161c816e464435bae9f" - integrity sha512-LPIisi3Ol4chwAaPP8toUJ3L4qCM1G0wao7L3qNv57Drezxj6+VEyySpPw4B1HSO2Eg/hDY/MNF5XihCAoqnsQ== + version "5.3.1" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz#0320dcc270ad5372c1e8993fabbd927929773e54" + integrity sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g== dependencies: - jest-worker "^27.4.1" + jest-worker "^27.4.5" schema-utils "^3.1.1" serialize-javascript "^6.0.0" source-map "^0.6.1" terser "^5.7.2" terser@^5.7.2: - version "5.10.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc" - integrity sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA== + version "5.12.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.12.1.tgz#4cf2ebed1f5bceef5c83b9f60104ac4a78b49e9c" + integrity sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ== dependencies: + acorn "^8.5.0" commander "^2.20.0" source-map "~0.7.2" source-map-support "~0.5.20" @@ -3142,9 +3222,9 @@ type-is@~1.6.18: mime-types "~2.1.24" "typescript@2 - 4": - version "4.5.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" - integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== + version "4.6.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" + integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== typescript@3.9.5: version "3.9.5" diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 66494dc..c52cfb1 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -68,11 +68,11 @@ kotlin { implementation(dependencies.platform(libs.kotlin.jsWrappers.bom)) - implementation(npm("follow-redirects", "^1.14.8")) - implementation(npm("nanoid", "^3.1.31")) - implementation(npm("minimist", "^1.2.6")) - implementation(npm("async", "^2.6.4")) - implementation(npm("node-forge", "^1.3.0")) + implementation(dependencies.platform(npm("follow-redirects", "^1.14.8"))) + implementation(dependencies.platform(npm("nanoid", "^3.1.31"))) + implementation(dependencies.platform(npm("minimist", "^1.2.6"))) + implementation(dependencies.platform(npm("async", "^2.6.4"))) + implementation(dependencies.platform(npm("node-forge", "^1.3.0"))) } val webDir = file("src/main/web") From d1353eec604d107f7f1768c0ce827afaed54d10c Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 12:58:04 +0200 Subject: [PATCH 269/629] fix broken tests --- .../kafkatorio/events/schema/ColourHexTest.kt | 2 - .../events/schema/PrototypesTest.kt | 1614 +++++++++-------- .../events/schema/UpdatePacketsTest.kt | 114 +- .../processor/topology/GroupMapChunksTest.kt | 68 +- 4 files changed, 929 insertions(+), 869 deletions(-) diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt index e0c02e5..522989f 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt @@ -79,9 +79,7 @@ class ColourHexTest : BehaviorSpec({ val colour: Colour = jsonMapperKafkatorio.decodeFromString(colourJson) val colourHex = colour.toHex() colourHex shouldBe ColourHex(r, g, b, a) - } - } } }) diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt index 974af26..8746f64 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt @@ -1,7 +1,14 @@ package dev.adamko.kafkatorio.events.schema +import dev.adamko.kafkatorio.schema.common.Colour +import dev.adamko.kafkatorio.schema.common.PrototypeName +import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio +import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2 +import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 +import dev.adamko.kafkatorio.schema2.PrototypesUpdate import io.kotest.core.spec.style.BehaviorSpec -import io.kotest.matchers.collections.shouldContain +import io.kotest.inspectors.forOne +import io.kotest.matchers.shouldBe import io.kotest.matchers.types.shouldBeInstanceOf import kotlinx.serialization.decodeFromString @@ -9,33 +16,33 @@ class PrototypesTest : BehaviorSpec({ Given("Prototypes Json") { // language=JSON val raw = """ +{ + "modVersion": "0.2.4", + "tick": 534, + "data": { + "type": "dev.adamko.kafkatorio.schema2.PrototypesUpdate", + "prototypes": [ { - "modVersion":"0.2.4", - "packetType":"PROTOTYPES", - "tick": 534, - "prototypes":[ - { - "prototypeObjectName":"LuaTilePrototype", - "name":"tile-unknown", - "order":"z-a", - "layer":0, - "collisionMasks":{ - - }, - "mapColour":{ - "red":0, - "green":0, - "blue":0, - "alpha":255 - }, - "canBeMined":false - } - ] + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "tile-unknown", + "order": "z-a", + "layer": 0, + "collisionMasks": {}, + "mapColour": { + "red": 0, + "green": 0, + "blue": 0, + "alpha": 255 + }, + "canBeMined": false } + ] + } +} """.trimIndent() Then("expect can be parsed") { - val data = jsonMapperKafkatorio.decodeFromString(raw) + val data = jsonMapperKafkatorio.decodeFromString(raw) println(data) } @@ -45,896 +52,895 @@ class PrototypesTest : BehaviorSpec({ // language=JSON val raw = """ { - "modVersion":"0.3.2", - "packetType":"PROTOTYPES", - "tick": 534, - "prototypes":[ + "modVersion": "0.3.2", + "tick": 534, + "data": { + "type": "dev.adamko.kafkatorio.schema2.PrototypesUpdate", + "prototypes": [ { - "prototypeObjectName":"LuaTilePrototype", - "name":"stone-path", - "order":"a[artificial]-a[tier-1]-a[stone-path]", - "layer":60, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":86, - "green":82, - "blue":74, - "alpha":255 - }, - "canBeMined":true + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "stone-path", + "order": "a[artificial]-a[tier-1]-a[stone-path]", + "layer": 60, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 86, + "green": 82, + "blue": 74, + "alpha": 255 + }, + "canBeMined": true }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"concrete", - "order":"a[artificial]-b[tier-2]-a[concrete]", - "layer":61, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":63, - "green":61, - "blue":59, - "alpha":255 - }, - "canBeMined":true + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "concrete", + "order": "a[artificial]-b[tier-2]-a[concrete]", + "layer": 61, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 63, + "green": 61, + "blue": 59, + "alpha": 255 + }, + "canBeMined": true }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"hazard-concrete-left", - "order":"a[artificial]-b[tier-2]-b[hazard-concrete-left]", - "layer":62, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":176, - "green":142, - "blue":39, - "alpha":255 - }, - "canBeMined":true + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "hazard-concrete-left", + "order": "a[artificial]-b[tier-2]-b[hazard-concrete-left]", + "layer": 62, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 176, + "green": 142, + "blue": 39, + "alpha": 255 + }, + "canBeMined": true }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"hazard-concrete-right", - "order":"a[artificial]-b[tier-2]-c[hazard-concrete-right]", - "layer":62, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":176, - "green":142, - "blue":39, - "alpha":255 - }, - "canBeMined":true + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "hazard-concrete-right", + "order": "a[artificial]-b[tier-2]-c[hazard-concrete-right]", + "layer": 62, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 176, + "green": 142, + "blue": 39, + "alpha": 255 + }, + "canBeMined": true }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"refined-concrete", - "order":"a[artificial]-c[tier-3]-a[refined-concrete]", - "layer":64, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":49, - "green":48, - "blue":45, - "alpha":255 - }, - "canBeMined":true + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "refined-concrete", + "order": "a[artificial]-c[tier-3]-a[refined-concrete]", + "layer": 64, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 49, + "green": 48, + "blue": 45, + "alpha": 255 + }, + "canBeMined": true }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"refined-hazard-concrete-left", - "order":"a[artificial]-c[tier-3]-b[refined-hazard-concrete-left]", - "layer":65, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":116, - "green":94, - "blue":26, - "alpha":255 - }, - "canBeMined":true + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "refined-hazard-concrete-left", + "order": "a[artificial]-c[tier-3]-b[refined-hazard-concrete-left]", + "layer": 65, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 116, + "green": 94, + "blue": 26, + "alpha": 255 + }, + "canBeMined": true }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"refined-hazard-concrete-right", - "order":"a[artificial]-c[tier-3]-c[refined-hazard-concrete-right]", - "layer":65, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":116, - "green":94, - "blue":26, - "alpha":255 - }, - "canBeMined":true + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "refined-hazard-concrete-right", + "order": "a[artificial]-c[tier-3]-c[refined-hazard-concrete-right]", + "layer": 65, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 116, + "green": 94, + "blue": 26, + "alpha": 255 + }, + "canBeMined": true }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"landfill", - "order":"a[artificial]-d[utility]-a[landfill]", - "layer":57, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":57, - "green":39, - "blue":26, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "landfill", + "order": "a[artificial]-d[utility]-a[landfill]", + "layer": 57, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 57, + "green": 39, + "blue": 26, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"acid-refined-concrete", - "order":"a[artificial]-e[color-concrete]-acid", - "layer":97, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":142, - "green":194, - "blue":40, - "alpha":127 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "acid-refined-concrete", + "order": "a[artificial]-e[color-concrete]-acid", + "layer": 97, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 142, + "green": 194, + "blue": 40, + "alpha": 127 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"black-refined-concrete", - "order":"a[artificial]-e[color-concrete]-black", - "layer":88, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":25, - "green":25, - "blue":25, - "alpha":127 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "black-refined-concrete", + "order": "a[artificial]-e[color-concrete]-black", + "layer": 88, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 25, + "green": 25, + "blue": 25, + "alpha": 127 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"blue-refined-concrete", - "order":"a[artificial]-e[color-concrete]-blue", - "layer":73, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":39, - "green":137, - "blue":228, - "alpha":127 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "blue-refined-concrete", + "order": "a[artificial]-e[color-concrete]-blue", + "layer": 73, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 39, + "green": 137, + "blue": 228, + "alpha": 127 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"brown-refined-concrete", - "order":"a[artificial]-e[color-concrete]-brown", - "layer":91, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":76, - "green":29, - "blue":0, - "alpha":127 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "brown-refined-concrete", + "order": "a[artificial]-e[color-concrete]-brown", + "layer": 91, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 76, + "green": 29, + "blue": 0, + "alpha": 127 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"cyan-refined-concrete", - "order":"a[artificial]-e[color-concrete]-cyan", - "layer":94, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":70, - "green":192, - "blue":181, - "alpha":127 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "cyan-refined-concrete", + "order": "a[artificial]-e[color-concrete]-cyan", + "layer": 94, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 70, + "green": 192, + "blue": 181, + "alpha": 127 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"green-refined-concrete", - "order":"a[artificial]-e[color-concrete]-green", - "layer":70, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":23, - "green":195, - "blue":43, - "alpha":127 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "green-refined-concrete", + "order": "a[artificial]-e[color-concrete]-green", + "layer": 70, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 23, + "green": 195, + "blue": 43, + "alpha": 127 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"orange-refined-concrete", - "order":"a[artificial]-e[color-concrete]-orange", - "layer":76, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":221, - "green":127, - "blue":33, - "alpha":127 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "orange-refined-concrete", + "order": "a[artificial]-e[color-concrete]-orange", + "layer": 76, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 221, + "green": 127, + "blue": 33, + "alpha": 127 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"pink-refined-concrete", - "order":"a[artificial]-e[color-concrete]-pink", - "layer":82, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":236, - "green":98, - "blue":131, - "alpha":127 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "pink-refined-concrete", + "order": "a[artificial]-e[color-concrete]-pink", + "layer": 82, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 236, + "green": 98, + "blue": 131, + "alpha": 127 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"purple-refined-concrete", - "order":"a[artificial]-e[color-concrete]-purple", - "layer":85, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":123, - "green":28, - "blue":168, - "alpha":127 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "purple-refined-concrete", + "order": "a[artificial]-e[color-concrete]-purple", + "layer": 85, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 123, + "green": 28, + "blue": 168, + "alpha": 127 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"red-refined-concrete", - "order":"a[artificial]-e[color-concrete]-red", - "layer":67, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":207, - "green":6, - "blue":0, - "alpha":127 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "red-refined-concrete", + "order": "a[artificial]-e[color-concrete]-red", + "layer": 67, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 207, + "green": 6, + "blue": 0, + "alpha": 127 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"yellow-refined-concrete", - "order":"a[artificial]-e[color-concrete]-yellow", - "layer":79, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":212, - "green":169, - "blue":19, - "alpha":127 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "yellow-refined-concrete", + "order": "a[artificial]-e[color-concrete]-yellow", + "layer": 79, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 212, + "green": 169, + "blue": 19, + "alpha": 127 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"grass-1", - "order":"b[natural]-a[grass]-a[grass-1]", - "layer":26, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":55, - "green":53, - "blue":11, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "grass-1", + "order": "b[natural]-a[grass]-a[grass-1]", + "layer": 26, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 55, + "green": 53, + "blue": 11, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"grass-2", - "order":"b[natural]-a[grass]-b[grass-2]", - "layer":28, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":66, - "green":57, - "blue":15, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "grass-2", + "order": "b[natural]-a[grass]-b[grass-2]", + "layer": 28, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 66, + "green": 57, + "blue": 15, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"grass-3", - "order":"b[natural]-a[grass]-c[grass-3]", - "layer":29, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":65, - "green":52, - "blue":28, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "grass-3", + "order": "b[natural]-a[grass]-c[grass-3]", + "layer": 29, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 65, + "green": 52, + "blue": 28, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"grass-4", - "order":"b[natural]-a[grass]-d[grass-4]", - "layer":30, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":59, - "green":40, - "blue":18, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "grass-4", + "order": "b[natural]-a[grass]-d[grass-4]", + "layer": 30, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 59, + "green": 40, + "blue": 18, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"dry-dirt", - "order":"b[natural]-b[dirt]-a[dry-dirt]", - "layer":18, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":94, - "green":66, - "blue":37, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "dry-dirt", + "order": "b[natural]-b[dirt]-a[dry-dirt]", + "layer": 18, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 94, + "green": 66, + "blue": 37, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"dirt-1", - "order":"b[natural]-b[dirt]-b[dirt-1]", - "layer":19, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":141, - "green":104, - "blue":60, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "dirt-1", + "order": "b[natural]-b[dirt]-b[dirt-1]", + "layer": 19, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 141, + "green": 104, + "blue": 60, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"dirt-2", - "order":"b[natural]-b[dirt]-c[dirt-2]", - "layer":20, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":136, - "green":96, - "blue":59, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "dirt-2", + "order": "b[natural]-b[dirt]-c[dirt-2]", + "layer": 20, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 136, + "green": 96, + "blue": 59, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"dirt-3", - "order":"b[natural]-b[dirt]-d[dirt-3]", - "layer":21, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":133, - "green":92, - "blue":53, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "dirt-3", + "order": "b[natural]-b[dirt]-d[dirt-3]", + "layer": 21, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 133, + "green": 92, + "blue": 53, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"dirt-4", - "order":"b[natural]-b[dirt]-e[dirt-4]", - "layer":22, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":103, - "green":72, - "blue":43, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "dirt-4", + "order": "b[natural]-b[dirt]-e[dirt-4]", + "layer": 22, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 103, + "green": 72, + "blue": 43, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"dirt-5", - "order":"b[natural]-b[dirt]-f[dirt-5]", - "layer":23, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":91, - "green":63, - "blue":38, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "dirt-5", + "order": "b[natural]-b[dirt]-f[dirt-5]", + "layer": 23, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 91, + "green": 63, + "blue": 38, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"dirt-6", - "order":"b[natural]-b[dirt]-g[dirt-6]", - "layer":24, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":80, - "green":55, - "blue":31, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "dirt-6", + "order": "b[natural]-b[dirt]-g[dirt-6]", + "layer": 24, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 80, + "green": 55, + "blue": 31, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"dirt-7", - "order":"b[natural]-b[dirt]-h[dirt-7]", - "layer":25, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":80, - "green":54, - "blue":28, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "dirt-7", + "order": "b[natural]-b[dirt]-h[dirt-7]", + "layer": 25, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 80, + "green": 54, + "blue": 28, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"sand-1", - "order":"b[natural]-c[sand]-a[sand-1]", - "layer":8, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":138, - "green":103, - "blue":58, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "sand-1", + "order": "b[natural]-c[sand]-a[sand-1]", + "layer": 8, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 138, + "green": 103, + "blue": 58, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"sand-2", - "order":"b[natural]-c[sand]-b[sand-2]", - "layer":9, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":128, - "green":93, - "blue":52, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "sand-2", + "order": "b[natural]-c[sand]-b[sand-2]", + "layer": 9, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 128, + "green": 93, + "blue": 52, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"sand-3", - "order":"b[natural]-c[sand]-c[sand-3]", - "layer":10, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":115, - "green":83, - "blue":47, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "sand-3", + "order": "b[natural]-c[sand]-c[sand-3]", + "layer": 10, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 115, + "green": 83, + "blue": 47, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"red-desert-0", - "order":"b[natural]-d[red-desert]-a[red-desert-0]", - "layer":31, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":103, - "green":70, - "blue":32, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "red-desert-0", + "order": "b[natural]-d[red-desert]-a[red-desert-0]", + "layer": 31, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 103, + "green": 70, + "blue": 32, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"red-desert-1", - "order":"b[natural]-d[red-desert]-b[red-desert-1]", - "layer":14, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":116, - "green":81, - "blue":39, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "red-desert-1", + "order": "b[natural]-d[red-desert]-b[red-desert-1]", + "layer": 14, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 116, + "green": 81, + "blue": 39, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"red-desert-2", - "order":"b[natural]-d[red-desert]-c[red-desert-2]", - "layer":15, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":116, - "green":84, - "blue":43, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "red-desert-2", + "order": "b[natural]-d[red-desert]-c[red-desert-2]", + "layer": 15, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 116, + "green": 84, + "blue": 43, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"red-desert-3", - "order":"b[natural]-d[red-desert]-d[red-desert-3]", - "layer":16, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":128, - "green":93, - "blue":52, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "red-desert-3", + "order": "b[natural]-d[red-desert]-d[red-desert-3]", + "layer": 16, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 128, + "green": 93, + "blue": 52, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"water", - "order":"c[water]-a[water]", - "layer":3, - "collisionMasks":[ - "doodad-layer", - "item-layer", - "player-layer", - "resource-layer", - "water-tile" - ], - "mapColour":{ - "red":51, - "green":83, - "blue":95, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "water", + "order": "c[water]-a[water]", + "layer": 3, + "collisionMasks": [ + "doodad-layer", + "item-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "mapColour": { + "red": 51, + "green": 83, + "blue": 95, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"deepwater", - "order":"c[water]-b[deep-water]", - "layer":3, - "collisionMasks":[ - "doodad-layer", - "item-layer", - "player-layer", - "resource-layer", - "water-tile" - ], - "mapColour":{ - "red":38, - "green":64, - "blue":73, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "deepwater", + "order": "c[water]-b[deep-water]", + "layer": 3, + "collisionMasks": [ + "doodad-layer", + "item-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "mapColour": { + "red": 38, + "green": 64, + "blue": 73, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"water-green", - "order":"c[water]-c[water-green]", - "layer":3, - "collisionMasks":[ - "doodad-layer", - "item-layer", - "player-layer", - "resource-layer", - "water-tile" - ], - "mapColour":{ - "red":31, - "green":48, - "blue":18, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "water-green", + "order": "c[water]-c[water-green]", + "layer": 3, + "collisionMasks": [ + "doodad-layer", + "item-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "mapColour": { + "red": 31, + "green": 48, + "blue": 18, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"deepwater-green", - "order":"c[water]-d[deepwater-green]", - "layer":3, - "collisionMasks":[ - "doodad-layer", - "item-layer", - "player-layer", - "resource-layer", - "water-tile" - ], - "mapColour":{ - "red":23, - "green":37, - "blue":16, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "deepwater-green", + "order": "c[water]-d[deepwater-green]", + "layer": 3, + "collisionMasks": [ + "doodad-layer", + "item-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "mapColour": { + "red": 23, + "green": 37, + "blue": 16, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"water-shallow", - "order":"c[water]-e[water-shallow]", - "layer":6, - "collisionMasks":[ - "item-layer", - "object-layer", - "resource-layer", - "water-tile" - ], - "mapColour":{ - "red":82, - "green":98, - "blue":92, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "water-shallow", + "order": "c[water]-e[water-shallow]", + "layer": 6, + "collisionMasks": [ + "item-layer", + "object-layer", + "resource-layer", + "water-tile" + ], + "mapColour": { + "red": 82, + "green": 98, + "blue": 92, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"water-mud", - "order":"c[water]-g[water-mud]", - "layer":7, - "collisionMasks":[ - "item-layer", - "object-layer", - "resource-layer", - "water-tile" - ], - "mapColour":{ - "red":65, - "green":89, - "blue":90, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "water-mud", + "order": "c[water]-g[water-mud]", + "layer": 7, + "collisionMasks": [ + "item-layer", + "object-layer", + "resource-layer", + "water-tile" + ], + "mapColour": { + "red": 65, + "green": 89, + "blue": 90, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"nuclear-ground", - "order":"d[destruction]-a[nuclear]-a[nuclear-ground]", - "layer":33, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":48, - "green":40, - "blue":35, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "nuclear-ground", + "order": "d[destruction]-a[nuclear]-a[nuclear-ground]", + "layer": 33, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 48, + "green": 40, + "blue": 35, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"water-wube", - "order":"x[wube]-a[water-wube]", - "layer":2, - "collisionMasks":[ - "doodad-layer", - "item-layer", - "player-layer", - "resource-layer", - "water-tile" - ], - "mapColour":{ - "red":0, - "green":0, - "blue":0, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "water-wube", + "order": "x[wube]-a[water-wube]", + "layer": 2, + "collisionMasks": [ + "doodad-layer", + "item-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "mapColour": { + "red": 0, + "green": 0, + "blue": 0, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"tile-unknown", - "order":"z-a", - "layer":0, - "collisionMasks":{ - - }, - "mapColour":{ - "red":0, - "green":0, - "blue":0, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "tile-unknown", + "order": "z-a", + "layer": 0, + "collisionMasks": { + }, + "mapColour": { + "red": 0, + "green": 0, + "blue": 0, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"out-of-map", - "order":"z[other]-a[out-of-map]", - "layer":0, - "collisionMasks":[ - "doodad-layer", - "floor-layer", - "ground-tile", - "item-layer", - "object-layer", - "player-layer", - "resource-layer", - "water-tile" - ], - "mapColour":{ - "red":0, - "green":0, - "blue":0, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "out-of-map", + "order": "z[other]-a[out-of-map]", + "layer": 0, + "collisionMasks": [ + "doodad-layer", + "floor-layer", + "ground-tile", + "item-layer", + "object-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "mapColour": { + "red": 0, + "green": 0, + "blue": 0, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"lab-dark-1", - "order":"z[other]-b[lab]-a[lab-dark-1]", - "layer":70, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":49, - "green":49, - "blue":49, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "lab-dark-1", + "order": "z[other]-b[lab]-a[lab-dark-1]", + "layer": 70, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 49, + "green": 49, + "blue": 49, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"lab-dark-2", - "order":"z[other]-b[lab]-b[lab-dark-2]", - "layer":70, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":0, - "green":0, - "blue":0, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "lab-dark-2", + "order": "z[other]-b[lab]-b[lab-dark-2]", + "layer": 70, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 0, + "green": 0, + "blue": 0, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"lab-white", - "order":"z[other]-b[lab]-c[lab-white]", - "layer":70, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":255, - "green":255, - "blue":255, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "lab-white", + "order": "z[other]-b[lab]-c[lab-white]", + "layer": 70, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 255, + "green": 255, + "blue": 255, + "alpha": 255 + }, + "canBeMined": false }, { - "prototypeObjectName":"LuaTilePrototype", - "name":"tutorial-grid", - "order":"z[other]-c[tutorial]-a[tutorial-grid]", - "layer":55, - "collisionMasks":[ - "ground-tile" - ], - "mapColour":{ - "red":122, - "green":122, - "blue":122, - "alpha":255 - }, - "canBeMined":false + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "name": "tutorial-grid", + "order": "z[other]-c[tutorial]-a[tutorial-grid]", + "layer": 55, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": { + "red": 122, + "green": 122, + "blue": 122, + "alpha": 255 + }, + "canBeMined": false } - ] + ] + } } """.trimIndent() Then("expect can be parsed") { - val data: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(raw) - println(data) + val packet: KafkatorioPacket2 = jsonMapperKafkatorio.decodeFromString(raw) +// println(packet) - data.shouldBeInstanceOf() - - data.prototypes.shouldContain( - MapTilePrototype( - name = PrototypeName("tutorial-grid"), - order = "z[other]-c[tutorial]-a[tutorial-grid]", - layer = 55u, - collisionMasks = listOf("ground-tile"), - mapColour = Colour(122f, 122f, 122f, 255f), - canBeMined = false, - ) - ) + packet.data.shouldBeInstanceOf() + .prototypes + .forOne { + it.shouldBeInstanceOf() + it.name shouldBe PrototypeName("tutorial-grid") + it.order shouldBe "z[other]-c[tutorial]-a[tutorial-grid]" + it.layer shouldBe 55u + it.collisionMasks shouldBe listOf("ground-tile") + it.mapColour shouldBe Colour(122f, 122f, 122f, 255f) + it.canBeMined shouldBe false + } } - } }) diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt index 638ceea..2d1d4df 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt @@ -1,5 +1,18 @@ package dev.adamko.kafkatorio.events.schema +import dev.adamko.kafkatorio.schema.common.Colour +import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData +import dev.adamko.kafkatorio.schema.common.ForceIndex +import dev.adamko.kafkatorio.schema.common.MapEntityPosition +import dev.adamko.kafkatorio.schema.common.PlayerIndex +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.common.Tick +import dev.adamko.kafkatorio.schema.common.UnitNumber +import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio +import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 +import dev.adamko.kafkatorio.schema2.PlayerUpdate +import dev.adamko.kafkatorio.schema2.PlayerUpdateKey +import dev.adamko.kafkatorio.schema2.SurfaceUpdate import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import kotlinx.serialization.decodeFromString @@ -13,8 +26,9 @@ class UpdatePacketsTest : FunSpec({ { "tick": 66, "modVersion": "0.3.2", - "packetType": "UPDATE", - "update": { + "data": { + "type": "dev.adamko.kafkatorio.schema2.PlayerUpdate", + "key": {"index": 1}, "afkTime": 0, "chatColour": { "red": 1, @@ -33,7 +47,6 @@ class UpdatePacketsTest : FunSpec({ "on_player_joined_game": 1 }, "forceIndex": 1, - "index": 1, "isAdmin": true, "isConnected": true, "isShowOnMap": true, @@ -41,23 +54,20 @@ class UpdatePacketsTest : FunSpec({ "lastOnline": 0, "name": "fredthedeadhead", "onlineTime": 0, - "position": { - "y": 13, - "x": -58 - }, - "tag": "", - "updateType": "PLAYER" + "position": [-58, 13], + "tag": "" } } """.trimIndent() test("decode") { - val packet: FactorioEventUpdatePacket = jsonMapperKafkatorio.decodeFromString(json) + val packet: KafkatorioPacket2 = jsonMapperKafkatorio.decodeFromString(json) - packet shouldBe FactorioEventUpdatePacket( + packet shouldBe KafkatorioPacket2( modVersion = "0.3.2", tick = Tick(66u), - update = PlayerUpdate( + data = PlayerUpdate( + key = PlayerUpdateKey(PlayerIndex(1u)), afkTime = Tick(0u), bannedReason = null, characterUnitNumber = null, @@ -67,7 +77,6 @@ class UpdatePacketsTest : FunSpec({ disconnectReason = null, eventCounts = mapOf("on_player_changed_position" to 7u, "on_player_joined_game" to 1u), forceIndex = ForceIndex(1u), - index = PlayerIndex(1u), isAdmin = true, isConnected = true, isRemoved = null, @@ -86,11 +95,11 @@ class UpdatePacketsTest : FunSpec({ } test("encode") { - val v = FactorioEventUpdatePacket( + val v = KafkatorioPacket2( modVersion = "0.3.2", tick = Tick(66u), - update = PlayerUpdate( - index = PlayerIndex(1u), + data = PlayerUpdate( + key = PlayerUpdateKey(PlayerIndex(1u)), characterUnitNumber = null, chatColour = null, colour = null, @@ -121,21 +130,22 @@ class UpdatePacketsTest : FunSpec({ { "modVersion": "0.3.2", "tick": 66, - "update": { - "index": 1, + "data": { + "type": "dev.adamko.kafkatorio.schema2.PlayerUpdate", + "key": { + "index": 1 + }, "name": "fredthedeadhead", "afkTime": 0, "isShowOnMap": true, "isSpectator": false, "lastOnline": 0, "onlineTime": 0, - "position": { - "x": -58.0, - "y": 13.0 - }, - "updateType": "PLAYER" - }, - "packetType": "UPDATE" + "position": [ + -58.0, + 13.0 + ] + } } """.trimIndent() } @@ -147,10 +157,11 @@ class UpdatePacketsTest : FunSpec({ { "tick": 227934, "modVersion": "0.3.2", - "packetType": "UPDATE", - "update": { - "index": 1, - "updateType": "PLAYER", + "data": { + "type": "dev.adamko.kafkatorio.schema2.PlayerUpdate", + "key": { + "index": 1 + }, "lastOnline": 227932, "onlineTime": 227888, "afkTime": 324, @@ -158,7 +169,7 @@ class UpdatePacketsTest : FunSpec({ "diedCause": { "unitNumber": 66, "name": "small-biter", - "type": "unit" + "protoType": "unit" }, "eventCounts": { "on_player_died": 2 @@ -168,12 +179,12 @@ class UpdatePacketsTest : FunSpec({ """.trimIndent() test("decode") { - val packet: FactorioEventUpdatePacket = jsonMapperKafkatorio.decodeFromString(json) + val packet: KafkatorioPacket2 = jsonMapperKafkatorio.decodeFromString(json) - packet shouldBe FactorioEventUpdatePacket( + packet shouldBe KafkatorioPacket2( modVersion = "0.3.2", tick = Tick(227934u), - update = PlayerUpdate( + data = PlayerUpdate( afkTime = Tick(324u), bannedReason = null, characterUnitNumber = null, @@ -182,12 +193,12 @@ class UpdatePacketsTest : FunSpec({ diedCause = EntityIdentifiersData( unitNumber = UnitNumber(66u), name = "small-biter", - type = "unit", + protoType = "unit", ), disconnectReason = null, eventCounts = mapOf("on_player_died" to 2u), forceIndex = null, - index = PlayerIndex(1u), + key = PlayerUpdateKey(PlayerIndex(1u)), isAdmin = null, isConnected = true, isRemoved = null, @@ -204,7 +215,38 @@ class UpdatePacketsTest : FunSpec({ ) ) } - } + context("surface update") { + //language=json + val json = """ + { + "data": { + "type": "dev.adamko.kafkatorio.schema2.SurfaceUpdate", + "name": "nauvis", + "index": 1, + "daytime": 0.73 + }, + "modVersion": "0.3.2", + "tick": 176000 + } + """.trimIndent() + + val expected = KafkatorioPacket2( + tick = Tick(176000u), + modVersion = "0.3.2", + data = SurfaceUpdate( + name = "nauvis", + index = SurfaceIndex(1u), + daytime = 0.73, + ) + ) + + println(jsonMapperKafkatorio.encodeToString(expected)) + + test("decode") { + val packet: KafkatorioPacket2 = jsonMapperKafkatorio.decodeFromString(json) + packet shouldBe expected + } + } }) diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt index 2edf2ee..79bc5a0 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt @@ -1,12 +1,19 @@ package dev.adamko.kafkatorio.processor.topology -import dev.adamko.kafkatorio.processor.KafkatorioTopology import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kafkatorio.schema.common.* +import dev.adamko.kafkatorio.schema.common.Colour +import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.MapChunkPosition +import dev.adamko.kafkatorio.schema.common.MapTileDictionary import dev.adamko.kafkatorio.schema.common.MapTileDictionary.PrototypeKey +import dev.adamko.kafkatorio.schema.common.MapTilePosition +import dev.adamko.kafkatorio.schema.common.PrototypeName +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2 +import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 import dev.adamko.kafkatorio.schema2.MapChunkUpdate import dev.adamko.kafkatorio.schema2.MapChunkUpdateKey import dev.adamko.kafkatorio.schema2.PrototypesUpdate @@ -28,57 +35,65 @@ class GroupMapChunksTest : FunSpec({ test("basic test") { val streamsBuilder = StreamsBuilder() - val prototypesTopicName = "prototypes-topic" - val mapChunkUpdatesTopicName = "map-chunk-updates-topic" + val prototypesTopicName = "kafkatorio.packet.prototypes" + val mapChunkUpdatesTopicName = "kafkatorio.packet.map-chunk" val topology = groupMapChunks(streamsBuilder) val testDriver = TopologyTestDriver(topology) - val prototypesTestInputTopic: TestInputTopic = + val prototypesTestInputTopic: TestInputTopic = testDriver.createInputTopic( prototypesTopicName, jsonMapper.serde().serializer(), - jsonMapper.serde().serializer(), + jsonMapper.serde().serializer(), ) val serverId = FactorioServerId("test-server-id") prototypesTestInputTopic.pipeInput( serverId, - PrototypesUpdate( - listOf( - FactorioPrototype2.MapTile( - PrototypeName("fake-proto"), - layer = 1u, - mapColour = Colour(0.3f, 0.2f, 0.1f, 1.0f), - collisionMasks = listOf("fake-mask"), - order = "fake-order", - canBeMined = false, + KafkatorioPacket2( + modVersion = "1.2.3", + tick = Tick(22u), + PrototypesUpdate( + listOf( + FactorioPrototype2.MapTile( + PrototypeName("fake-proto"), + layer = 1u, + mapColour = Colour(0.3f, 0.2f, 0.1f, 1.0f), + collisionMasks = listOf("fake-mask"), + order = "fake-order", + canBeMined = false, + ) ) ) ) ) - val mapChunkUpdatesInputTopic: TestInputTopic = + val mapChunkUpdatesInputTopic: TestInputTopic = testDriver.createInputTopic( mapChunkUpdatesTopicName, jsonMapper.serde().serializer(), - jsonMapper.serde().serializer(), + jsonMapper.serde().serializer(), ) mapChunkUpdatesInputTopic.pipeInput( serverId, - MapChunkUpdate( - key = MapChunkUpdateKey( - MapChunkPosition(11, 22), - SurfaceIndex(1u), - ), - tileDictionary = MapTileDictionary( - tilesXY = mapOf( - "1" to mapOf("2" to PrototypeKey(33)) + KafkatorioPacket2( + modVersion = "1.2.3", + tick = Tick(44u), + MapChunkUpdate( + key = MapChunkUpdateKey( + MapChunkPosition(11, 22), + SurfaceIndex(1u), ), - protos = mapOf(PrototypeName("fake-proto") to PrototypeKey(33)) + tileDictionary = MapTileDictionary( + tilesXY = mapOf( + "1" to mapOf("2" to PrototypeKey(33)) + ), + protos = mapOf(PrototypeName("fake-proto") to PrototypeKey(33)) + ) ) ) ) @@ -114,5 +129,4 @@ class GroupMapChunksTest : FunSpec({ } } } - }) From a3e8b20acb8e7022971727e2d7e3b829197d1959 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 16:30:23 +0200 Subject: [PATCH 270/629] try fixing dependabot alerts --- .../adamko/kafkatorio/gradle/extensions.kt | 5 + gradle/kotlin-js-store/yarn.lock | 109 +++--------------- modules/web-map/build.gradle.kts | 24 +++- 3 files changed, 39 insertions(+), 99 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt index 05006ae..7bc9b86 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt @@ -13,7 +13,9 @@ import org.gradle.api.specs.Spec import org.gradle.kotlin.dsl.invoke import org.gradle.plugins.ide.idea.model.IdeaModule import org.gradle.process.ExecSpec +import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension +import org.jetbrains.kotlin.gradle.targets.js.yarn.yarn operator fun Spec.not(): Spec = Spec { !this(it) } @@ -86,3 +88,6 @@ fun Project.execCapture(spec: ExecSpec.() -> Unit): String { output } } + +/** https://youtrack.jetbrains.com/issue/KT-50848 */ +fun Project.yarn(configure: YarnRootExtension.() -> Unit) = with(yarn, configure) diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index 7449ad4..6011da2 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -539,7 +539,7 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -async@^2.6.2, async@^2.6.4: +async@2.6.4, async@^2.6.2: version "2.6.4" resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== @@ -718,21 +718,6 @@ chart.js@^3.7.1: resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.7.1.tgz#0516f690c6a8680c6c707e31a4c1807a6f400ada" integrity sha512-8knRegQLFnPQAheZV8MjxIXc5gQEfDFD897BJgv/klO/vtIyFFmgMXrNfgrXpbTr/XbTturxRgxIXx/Y+ASJBA== -chokidar@3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" - integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - chokidar@3.5.3, chokidar@^3.5.1, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" @@ -955,13 +940,6 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - debug@4.3.3: version "4.3.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" @@ -1407,10 +1385,10 @@ flatted@^3.2.5: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== -follow-redirects@^1.0.0, follow-redirects@^1.14.8: - version "1.14.9" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" - integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== +follow-redirects@1.14.8, follow-redirects@^1.0.0: + version "1.14.8" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc" + integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA== format-util@1.0.5: version "1.0.5" @@ -1565,18 +1543,6 @@ glob-to-regexp@^0.4.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - globby@^11.0.1: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" @@ -2213,7 +2179,7 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6: +minimist@1.2.6, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== @@ -2225,37 +2191,7 @@ mkdirp@^0.5.5: dependencies: minimist "^1.2.6" -mocha@9.1.2: - version "9.1.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.2.tgz#93f53175b0f0dc4014bd2d612218fccfcf3534d3" - integrity sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.2" - debug "4.3.2" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.1.7" - growl "1.10.5" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "3.0.4" - ms "2.1.3" - nanoid "3.1.25" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - workerpool "6.1.5" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -mocha@9.2.1: +mocha@9.1.2, mocha@9.2.1: version "9.2.1" resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.1.tgz#a1abb675aa9a8490798503af57e8782a78f1338e" integrity sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ== @@ -2313,20 +2249,10 @@ multicast-dns@^6.0.1: dns-packet "^1.3.1" thunky "^1.0.2" -nanoid@3.1.25: - version "3.1.25" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" - integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== - -nanoid@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" - integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== - -nanoid@^3.1.31, nanoid@^3.3.1: - version "3.3.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" - integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== +nanoid@3.1.31, nanoid@3.2.0, nanoid@^3.3.1: + version "3.1.31" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.31.tgz#f5b58a1ce1b7604da5f0605757840598d8974dc6" + integrity sha512-ZivnJm0o9bb13p2Ot5CpgC2rQdzB9Uxm/mFZweqm5eMViqOJe3PV6LU2E30SiLgheesmcPrjquqraoolONSA0A== negotiator@0.6.3: version "0.6.3" @@ -2338,10 +2264,10 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -node-forge@^1, node-forge@^1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" - integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== +node-forge@1.3.0, node-forge@^1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.0.tgz#37a874ea723855f37db091e6c186e5b67a01d4b2" + integrity sha512-08ARB91bUi6zNKzVmaj3QO7cr397uiDT2nJ63cHjyNtCTWIgvS47j3eT0WfzUwS9+6Z5YshRaoasFkXCKrIYbA== node-releases@^2.0.2: version "2.0.3" @@ -3451,11 +3377,6 @@ wildcard@^2.0.0: resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== -workerpool@6.1.5: - version "6.1.5" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" - integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== - workerpool@6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index c52cfb1..75c94f5 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -1,6 +1,8 @@ +import dev.adamko.kafkatorio.gradle.yarn import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig + plugins { dev.adamko.kafkatorio.lang.`kotlin-js` kotlin("plugin.serialization") @@ -68,11 +70,11 @@ kotlin { implementation(dependencies.platform(libs.kotlin.jsWrappers.bom)) - implementation(dependencies.platform(npm("follow-redirects", "^1.14.8"))) - implementation(dependencies.platform(npm("nanoid", "^3.1.31"))) - implementation(dependencies.platform(npm("minimist", "^1.2.6"))) - implementation(dependencies.platform(npm("async", "^2.6.4"))) - implementation(dependencies.platform(npm("node-forge", "^1.3.0"))) +// implementation(dependencies.platform(npm("follow-redirects", "^1.14.8"))) +// implementation(dependencies.platform(npm("nanoid", "^3.1.31"))) +// implementation(dependencies.platform(npm("minimist", "^1.2.6"))) +// implementation(dependencies.platform(npm("async", "^2.6.4"))) +// implementation(dependencies.platform(npm("node-forge", "^1.3.0"))) } val webDir = file("src/main/web") @@ -100,3 +102,15 @@ fun KotlinDependencyHandler.kvision( ) { implementation("io.kvision:$module:${version.get()}", configure) } + +// https://youtrack.jetbrains.com/issue/KT-42420 +afterEvaluate { + yarn { + resolution("mocha", "9.2.1") + resolution("follow-redirects", "1.14.8") + resolution("nanoid", "3.1.31") + resolution("minimist", "1.2.6") + resolution("async", "2.6.4") + resolution("node-forge", "1.3.0") + } +} From 7f65ec025c60efc1bd8890dadb213389d20ea96a Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 16:32:10 +0200 Subject: [PATCH 271/629] try fixing dependabot alerts --- gradle/kotlin-js-store/yarn.lock | 22 +++++++++++----------- modules/web-map/build.gradle.kts | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index 6011da2..95c25bf 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -2165,10 +2165,10 @@ minimalistic-assert@^1.0.0: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== +minimatch@4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" + integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== dependencies: brace-expansion "^1.1.7" @@ -2191,10 +2191,10 @@ mkdirp@^0.5.5: dependencies: minimist "^1.2.6" -mocha@9.1.2, mocha@9.2.1: - version "9.2.1" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.1.tgz#a1abb675aa9a8490798503af57e8782a78f1338e" - integrity sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ== +mocha@9.1.2, mocha@9.2.1, mocha@9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" + integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== dependencies: "@ungap/promise-all-settled" "1.1.2" ansi-colors "4.1.1" @@ -2209,9 +2209,9 @@ mocha@9.1.2, mocha@9.2.1: he "1.2.0" js-yaml "4.1.0" log-symbols "4.1.0" - minimatch "3.0.4" + minimatch "4.2.1" ms "2.1.3" - nanoid "3.2.0" + nanoid "3.3.1" serialize-javascript "6.0.0" strip-json-comments "3.1.1" supports-color "8.1.1" @@ -2249,7 +2249,7 @@ multicast-dns@^6.0.1: dns-packet "^1.3.1" thunky "^1.0.2" -nanoid@3.1.31, nanoid@3.2.0, nanoid@^3.3.1: +nanoid@3.1.31, nanoid@3.3.1, nanoid@^3.3.1: version "3.1.31" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.31.tgz#f5b58a1ce1b7604da5f0605757840598d8974dc6" integrity sha512-ZivnJm0o9bb13p2Ot5CpgC2rQdzB9Uxm/mFZweqm5eMViqOJe3PV6LU2E30SiLgheesmcPrjquqraoolONSA0A== diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 75c94f5..189500f 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -106,7 +106,7 @@ fun KotlinDependencyHandler.kvision( // https://youtrack.jetbrains.com/issue/KT-42420 afterEvaluate { yarn { - resolution("mocha", "9.2.1") + resolution("mocha", "9.2.2") resolution("follow-redirects", "1.14.8") resolution("nanoid", "3.1.31") resolution("minimist", "1.2.6") From 1c55fae23647dbefb0680334c439282d73f81a50 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 17:03:23 +0200 Subject: [PATCH 272/629] tidying up schema files --- .../schema/events/kafkatorioPacket.kt | 68 --------- .../schema/events/kafkatorioPacketInstant.kt | 95 ------------ .../schema/events/kafkatorioPacketKeyed.kt | 135 ------------------ .../schema/prototypes/factorioPrototypes.kt | 58 -------- .../processor/KafkatorioTopology.kt | 20 +-- 5 files changed, 10 insertions(+), 366 deletions(-) delete mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacket.kt delete mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketInstant.kt delete mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketKeyed.kt delete mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacket.kt deleted file mode 100644 index 02413d8..0000000 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacket.kt +++ /dev/null @@ -1,68 +0,0 @@ -package dev.adamko.kafkatorio.schema.events -// -//import dev.adamko.kafkatorio.schema.SerializerProvider -//import dev.adamko.kafkatorio.schema.SerializerProviderDeserializer -//import dev.adamko.kafkatorio.schema.common.Tick -//import kotlin.reflect.KClass -//import kotlin.reflect.KType -//import kotlin.reflect.typeOf -//import kotlinx.serialization.KSerializer -//import kotlinx.serialization.Serializable -// -// -////@Serializable -////data class KafkatorioPacket( -//// val modVersion: String, -//// val tick: Tick, -//// val data: KafkatorioPacketData, -////) -// -// -//@Serializable(with = KafkatorioPacketData.JsonSerializer::class) -//sealed class KafkatorioPacketData { -// abstract val updateType: KafkatorioPacketDataType -// -// object JsonSerializer : SerializerProviderDeserializer( -// KafkatorioPacketData::class, -// KafkatorioPacketData::updateType.name, -// { json -> KafkatorioPacketDataType.entries.firstOrNull { it.name == json } } -// ) -//} -// -// -///** Discriminator for [KafkatorioPacketData] */ -//@Serializable -//enum class KafkatorioPacketDataType( -// override val serializer: KSerializer -//) : SerializerProvider { -// -// // non-keyed -// CONFIG(ConfigurationUpdate.serializer()), -// CONSOLE_CHAT(ConsoleChatUpdate.serializer()), -// CONSOLE_COMMAND(ConsoleCommandUpdate.serializer()), -// PROTOTYPES(PrototypesUpdate.serializer()), -// SURFACE(SurfaceUpdate.serializer()), -// -// // keyed -// ENTITY(EntityUpdate.serializer()), -// MAP_CHUNK(MapChunkUpdate.serializer()), -// PLAYER(PlayerUpdate.serializer()), -// ; -// -// companion object { -// val entries: Set = values().toSet() -// } -//} -// -////inline fun KafkatorioPacketDataType.isType (): KClass { -//// return when (this) { -//// KafkatorioPacketDataType.CONFIG -> ConfigurationUpdate::class -//// KafkatorioPacketDataType.CONSOLE_CHAT -> ConsoleChatUpdate::class -//// KafkatorioPacketDataType.CONSOLE_COMMAND -> ConsoleCommandUpdate::class -//// KafkatorioPacketDataType.PROTOTYPES -> PrototypesUpdate::class -//// KafkatorioPacketDataType.SURFACE -> SurfaceUpdate::class -//// KafkatorioPacketDataType.ENTITY -> EntityUpdate::class -//// KafkatorioPacketDataType.MAP_CHUNK -> MapChunkUpdate::class -//// KafkatorioPacketDataType.PLAYER -> PlayerUpdate::class -//// } -////} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketInstant.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketInstant.kt deleted file mode 100644 index 6dc03cc..0000000 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketInstant.kt +++ /dev/null @@ -1,95 +0,0 @@ -package dev.adamko.kafkatorio.schema.events -// -//import dev.adamko.kafkatorio.schema.common.PlayerIndex -//import dev.adamko.kafkatorio.schema.common.SurfaceIndex -//import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype -//import kotlinx.serialization.EncodeDefault -//import kotlinx.serialization.Serializable -// -// -///** No key, no caching. Must be sent instantly. */ -//sealed class KafkatorioInstantPacketData : KafkatorioPacketData() -// -// -///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ -// -// -//@Serializable -//data class ConfigurationUpdate( -// val factorioData: ConfigurationUpdateGameData, -// val allMods: List, -// val modStartupSettingsChange: Boolean, -// val migrationApplied: Boolean, -//) : KafkatorioInstantPacketData() { -// @EncodeDefault -// override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.CONFIG -// -// @Serializable -// data class ConfigurationUpdateGameData( -// val oldVersion: String? = null, -// val newVersion: String? = null, -// ) -// -// @Serializable -// data class ConfigurationUpdateModData( -// val modName: String, -// val currentVersion: String? = null, -// val previousVersion: String? = null, -// ) -//} -// -// -///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ -// -// -//@Serializable -//data class ConsoleChatUpdate( -// val authorPlayerIndex: PlayerIndex?, -// val content: String, -//) : KafkatorioInstantPacketData() { -// @EncodeDefault -// override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.CONSOLE_CHAT -//} -// -// -///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ -// -// -//@Serializable -//data class ConsoleCommandUpdate( -// val authorPlayerIndex: PlayerIndex?, -// val command: String, -// val parameters: String, -//) : KafkatorioInstantPacketData() { -// @EncodeDefault -// override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.CONSOLE_COMMAND -//} -// -// -///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ -// -// -//@Serializable -//data class PrototypesUpdate( -// val prototypes: List, -//) : KafkatorioInstantPacketData() { -// @EncodeDefault -// override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.PROTOTYPES -//} -// -// -///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ -// -// -//@Serializable -//data class SurfaceUpdate( -// val index: SurfaceIndex, -// val daytime: Double, -// val name: String, -//) : KafkatorioInstantPacketData() { -// @EncodeDefault -// override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.SURFACE -//} -// -// -///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketKeyed.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketKeyed.kt deleted file mode 100644 index 236ac6e..0000000 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/events/kafkatorioPacketKeyed.kt +++ /dev/null @@ -1,135 +0,0 @@ -package dev.adamko.kafkatorio.schema.events - -//import dev.adamko.kafkatorio.schema.common.Colour -//import dev.adamko.kafkatorio.schema.common.EntityIdentifiers -//import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData -//import dev.adamko.kafkatorio.schema.common.ForceIndex -//import dev.adamko.kafkatorio.schema.common.MapChunkPosition -//import dev.adamko.kafkatorio.schema.common.MapEntityPosition -//import dev.adamko.kafkatorio.schema.common.MapTileDictionary -//import dev.adamko.kafkatorio.schema.common.PlayerIndex -//import dev.adamko.kafkatorio.schema.common.PrototypeName -//import dev.adamko.kafkatorio.schema.common.SurfaceIndex -//import dev.adamko.kafkatorio.schema.common.Tick -//import dev.adamko.kafkatorio.schema.common.UnitNumber -//import kotlinx.serialization.EncodeDefault -//import kotlinx.serialization.Serializable -// -// -//sealed interface KafkatorioKeyedPacketKey -// -// -///** Has a key, so it can be debounced */ -//sealed class KafkatorioKeyedPacketData : KafkatorioPacketData() { -// /** Count how many events this packet is aggregating data from */ -// abstract val eventCounts: Map? -//} -// -// -///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ -// -// -//sealed interface EntityUpdateKey : EntityIdentifiers, KafkatorioKeyedPacketKey { -// /** A [unitNumber] is required for caching */ -// override val unitNumber: UnitNumber -// override val name: String -// override val protoType: String -//} -// -// -//@Serializable -//data class EntityUpdate( -// override val unitNumber: UnitNumber, -// override val name: String, -// override val protoType: String, -// -// override val eventCounts: Map? = null, -// -// val chunkPosition: MapChunkPosition? = null, -// val graphicsVariation: UByte? = null, -// val health: Float? = null, -// val isActive: Boolean? = null, -// val isRotatable: Boolean? = null, -// val lastUser: UInt? = null, -// val localisedDescription: String? = null, -// val localisedName: String? = null, -// val prototype: PrototypeName? = null, -//) : KafkatorioKeyedPacketData(), EntityUpdateKey { -// @EncodeDefault -// override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.ENTITY -//} -// -// -///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ -// -// -//sealed interface MapChunkUpdateKey : KafkatorioKeyedPacketKey { -// val chunkPosition: MapChunkPosition -// val surfaceIndex: SurfaceIndex -//} -// -// -//@Serializable -//data class MapChunkUpdate( -// override val chunkPosition: MapChunkPosition, -// override val surfaceIndex: SurfaceIndex, -// -// override val eventCounts: Map? = null, -// -// val player: PlayerIndex? = null, -// val robot: EntityIdentifiersData? = null, -// val force: ForceIndex? = null, -// /** updated tiles - might be partial and not all tiles in the chunk */ -// val tileDictionary: MapTileDictionary? = null, -// val isDeleted: Boolean? = null, -//) : KafkatorioKeyedPacketData(), MapChunkUpdateKey { -// @EncodeDefault -// override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.MAP_CHUNK -//} -// -// -///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ -// -// -//sealed interface PlayerUpdateKey : KafkatorioKeyedPacketKey { -// val index: PlayerIndex -//} -// -// -//@Serializable -//data class PlayerUpdate( -// override val index: PlayerIndex, -// -// override val eventCounts: Map? = null, -// -// val characterUnitNumber: UnitNumber? = null, -// val chatColour: Colour? = null, -// val colour: Colour? = null, -// val name: String? = null, -// -// val afkTime: Tick? = null, -// val ticksToRespawn: Tick? = null, -// val forceIndex: ForceIndex? = null, -// val isAdmin: Boolean? = null, -// val isConnected: Boolean? = null, -// val isShowOnMap: Boolean? = null, -// val isSpectator: Boolean? = null, -// val lastOnline: Tick? = null, -// val onlineTime: Tick? = null, -// val position: MapEntityPosition? = null, -// val surfaceIndex: SurfaceIndex? = null, -// val tag: String? = null, -// val diedCause: EntityIdentifiersData? = null, -// -// val bannedReason: String? = null, -// val kickedReason: String? = null, -// val disconnectReason: String? = null, -// /** `true` when a player is removed (deleted) from the game */ -// val isRemoved: Boolean? = null, -//) : KafkatorioKeyedPacketData(), PlayerUpdateKey { -// @EncodeDefault -// override val updateType: KafkatorioPacketDataType = KafkatorioPacketDataType.PLAYER -//} -// -// -///* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt deleted file mode 100644 index a65c77d..0000000 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt +++ /dev/null @@ -1,58 +0,0 @@ -package dev.adamko.kafkatorio.schema.prototypes -// -//import dev.adamko.kafkatorio.schema.SerializerProvider -//import dev.adamko.kafkatorio.schema.SerializerProviderDeserializer -//import dev.adamko.kafkatorio.schema.common.Colour -//import dev.adamko.kafkatorio.schema.common.PrototypeName -//import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.PrototypeObjectName -//import kotlinx.serialization.Contextual -//import kotlinx.serialization.DeserializationStrategy -//import kotlinx.serialization.EncodeDefault -//import kotlinx.serialization.KSerializer -//import kotlinx.serialization.Serializable -//import kotlinx.serialization.json.JsonContentPolymorphicSerializer -//import kotlinx.serialization.json.JsonElement -//import kotlinx.serialization.json.contentOrNull -//import kotlinx.serialization.json.jsonObject -//import kotlinx.serialization.json.jsonPrimitive -// -// -//@Serializable(with = FactorioPrototype.JsonSerializer::class) -//sealed class FactorioPrototype { -// @EncodeDefault -// abstract val prototypeObjectName: PrototypeObjectName -// -// enum class PrototypeObjectName( -// override val serializer: KSerializer -// ) : SerializerProvider { -// LuaTilePrototype(MapTilePrototype.serializer()), -// ; -// -// companion object { -// val entries: Set = values().toSet() -// } -// } -// -// object JsonSerializer : SerializerProviderDeserializer( -// FactorioPrototype::class, -// FactorioPrototype::prototypeObjectName.name, -// { json -> PrototypeObjectName.entries.firstOrNull { it.name == json } } -// ) -//} -// -// -// -//@Serializable -//data class MapTilePrototype( -// val name: PrototypeName, -// val layer: UInt, -// val mapColour: Colour, -// @Contextual -// val collisionMasks: List, -// val order: String, -// /** Can the tile be mined for resources? */ -// val canBeMined: Boolean, -//) : FactorioPrototype() { -// @EncodeDefault -// override val prototypeObjectName: PrototypeObjectName = PrototypeObjectName.LuaTilePrototype -//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index dd6bc5e..9aa4332 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -40,6 +40,16 @@ internal class KafkatorioTopology( playerUpdates() } + private fun splitPackets() { + val builder = StreamsBuilder() + val packets = factorioServerPacketStream(builder) + splitFactorioServerPacketStream(packets) + + val topology = builder.build() + + launchTopology("splitPackets", topology) + } + private fun groupTilesMapChunks() { val builder = StreamsBuilder() val topology = groupMapChunks(builder) @@ -52,16 +62,6 @@ internal class KafkatorioTopology( launchTopology("saveTiles", topology) } - private fun splitPackets() { - val builder = StreamsBuilder() - val packets = factorioServerPacketStream(builder) - splitFactorioServerPacketStream(packets) - - val topology = builder.build() - - launchTopology("splitPackets", topology) - } - private fun playerUpdates() { val builder = StreamsBuilder() playerUpdatesToWsServer(websocketServer, builder) From 6bfcd30558bbc44c4e9e42e2298af8b0b22b4840 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 17:04:24 +0200 Subject: [PATCH 273/629] use tuples for colours --- .../kafkatorio-schema/kafkatorio-schema.ts | 12 +- .../main/typescript/main/events/converters.ts | 12 +- .../src/main/typescript/package.json | 12 +- .../kafkatorio/schema/common/colours.kt | 24 +- .../kafkatorio/events/schema/ColourHexTest.kt | 19 +- .../events/schema/PrototypesTest.kt | 371 +++--------------- .../events/schema/UpdatePacketsTest.kt | 19 +- .../processor/serdes/MapTileDictionaryTest.kt | 41 ++ 8 files changed, 145 insertions(+), 365 deletions(-) create mode 100644 modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/serdes/MapTileDictionaryTest.kt diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts index 16872e0..8c9cb3a 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts @@ -171,12 +171,12 @@ export interface PlayerUpdateKey { export type UnitNumber = UInt; -export interface Colour { - red?: Float; - green?: Float; - blue?: Float; - alpha?: Float; -} +export type Colour = [ + red: Float, + green: Float, + blue: Float, + alpha: Float, +]; export type MapEntityPosition = [ x: Double, diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index a7dcdbe..861ec53 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -86,12 +86,12 @@ export namespace Converters { // } export function mapColour(color: ColorTable): Colour { - return { - red: color.r ?? 0, - green: color.g ?? 0, - blue: color.b ?? 0, - alpha: color.a ?? 0, - } + return [ + color.r ?? 0, + color.g ?? 0, + color.b ?? 0, + color.a ?? 0, + ] } diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index dc5d159..ea7c2fb 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -9,8 +9,7 @@ "engines": { "node": "~14.19.1" }, - "devDependencies": { - }, + "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", "typescript-to-lua": "1.4.3", @@ -19,10 +18,7 @@ }, "// @types/node": "^12.0.8", "license": "UNLICENSED", - "peerDependencies": { - }, - "optionalDependencies": { - }, - "bundledDependencies": [ - ] + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt index dab6394..a39baa0 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.schema.common +import dev.adamko.kxstsgen.core.experiments.TupleSerializer import kotlin.math.roundToInt import kotlinx.serialization.Serializable @@ -9,13 +10,32 @@ import kotlinx.serialization.Serializable * * All values here are optional. Colour channels default to `0`, the alpha channel defaults to `1`. */ -@Serializable +@Serializable(with = Colour.Serializer::class) data class Colour( val red: Float = 0f, val green: Float = 0f, val blue: Float = 0f, val alpha: Float = 1f, -) +) { + object Serializer : TupleSerializer( + "Colour", + { + element(Colour::red) + element(Colour::green) + element(Colour::blue) + element(Colour::alpha) + } + ) { + override fun tupleConstructor(elements: Iterator<*>): Colour { + return Colour( + elements.next() as Float, + elements.next() as Float, + elements.next() as Float, + elements.next() as Float, + ) + } + } +} /** Size-efficient version of [Colour] (`4*4` bytes vs `4*1` bytes) */ diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt index 522989f..935ca93 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt @@ -19,12 +19,7 @@ class ColourHexTest : BehaviorSpec({ //Language=JSON val colourJson = """ - { - "red": 0.1, - "green": 0.4, - "blue": 0.7, - "alpha": 0.6 - } + [0.1, 0.4, 0.7, 0.6] """.trimIndent() val colour: Colour = jsonMapperKafkatorio.decodeFromString(colourJson) @@ -68,12 +63,12 @@ class ColourHexTest : BehaviorSpec({ //Language=JSON val colourJson = """ - { - "red": ${r.toFloat() / UByte.MAX_VALUE.toFloat()}, - "green": ${g.toFloat() / UByte.MAX_VALUE.toFloat()}, - "blue": ${b.toFloat() / UByte.MAX_VALUE.toFloat()}, - "alpha": ${a.toFloat() / UByte.MAX_VALUE.toFloat()} - } + [ + ${r.toFloat() / UByte.MAX_VALUE.toFloat()}, + ${g.toFloat() / UByte.MAX_VALUE.toFloat()}, + ${b.toFloat() / UByte.MAX_VALUE.toFloat()}, + ${a.toFloat() / UByte.MAX_VALUE.toFloat()} + ] """.trimIndent() val colour: Colour = jsonMapperKafkatorio.decodeFromString(colourJson) diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt index 8746f64..e4230ed 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt @@ -28,12 +28,7 @@ class PrototypesTest : BehaviorSpec({ "order": "z-a", "layer": 0, "collisionMasks": {}, - "mapColour": { - "red": 0, - "green": 0, - "blue": 0, - "alpha": 255 - }, + "mapColour": [0, 0, 0, 255], "canBeMined": false } ] @@ -65,12 +60,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 86, - "green": 82, - "blue": 74, - "alpha": 255 - }, + "mapColour": [86, 82, 74, 255], "canBeMined": true }, { @@ -81,12 +71,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 63, - "green": 61, - "blue": 59, - "alpha": 255 - }, + "mapColour": [63, 61, 59, 255], "canBeMined": true }, { @@ -97,12 +82,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 176, - "green": 142, - "blue": 39, - "alpha": 255 - }, + "mapColour": [176, 142, 39, 255], "canBeMined": true }, { @@ -113,12 +93,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 176, - "green": 142, - "blue": 39, - "alpha": 255 - }, + "mapColour": [176, 142, 39, 255], "canBeMined": true }, { @@ -129,12 +104,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 49, - "green": 48, - "blue": 45, - "alpha": 255 - }, + "mapColour": [49, 48, 45, 255], "canBeMined": true }, { @@ -145,12 +115,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 116, - "green": 94, - "blue": 26, - "alpha": 255 - }, + "mapColour": [116, 94, 26, 255], "canBeMined": true }, { @@ -161,12 +126,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 116, - "green": 94, - "blue": 26, - "alpha": 255 - }, + "mapColour": [116, 94, 26, 255], "canBeMined": true }, { @@ -177,12 +137,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 57, - "green": 39, - "blue": 26, - "alpha": 255 - }, + "mapColour": [57, 39, 26, 255], "canBeMined": false }, { @@ -193,12 +148,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 142, - "green": 194, - "blue": 40, - "alpha": 127 - }, + "mapColour": [142, 194, 40, 127], "canBeMined": false }, { @@ -209,12 +159,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 25, - "green": 25, - "blue": 25, - "alpha": 127 - }, + "mapColour": [25, 25, 25, 127], "canBeMined": false }, { @@ -225,12 +170,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 39, - "green": 137, - "blue": 228, - "alpha": 127 - }, + "mapColour": [39, 137, 228, 127], "canBeMined": false }, { @@ -241,12 +181,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 76, - "green": 29, - "blue": 0, - "alpha": 127 - }, + "mapColour": [76, 29, 0, 127], "canBeMined": false }, { @@ -257,12 +192,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 70, - "green": 192, - "blue": 181, - "alpha": 127 - }, + "mapColour": [70, 192, 181, 127], "canBeMined": false }, { @@ -273,12 +203,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 23, - "green": 195, - "blue": 43, - "alpha": 127 - }, + "mapColour": [23, 195, 43, 127], "canBeMined": false }, { @@ -289,12 +214,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 221, - "green": 127, - "blue": 33, - "alpha": 127 - }, + "mapColour": [221, 127, 33, 127], "canBeMined": false }, { @@ -305,12 +225,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 236, - "green": 98, - "blue": 131, - "alpha": 127 - }, + "mapColour": [236, 98, 131, 127], "canBeMined": false }, { @@ -321,12 +236,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 123, - "green": 28, - "blue": 168, - "alpha": 127 - }, + "mapColour": [123, 28, 168, 127], "canBeMined": false }, { @@ -337,12 +247,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 207, - "green": 6, - "blue": 0, - "alpha": 127 - }, + "mapColour": [207, 6, 0, 127], "canBeMined": false }, { @@ -353,12 +258,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 212, - "green": 169, - "blue": 19, - "alpha": 127 - }, + "mapColour": [212, 169, 19, 127], "canBeMined": false }, { @@ -369,12 +269,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 55, - "green": 53, - "blue": 11, - "alpha": 255 - }, + "mapColour": [55, 53, 11, 255], "canBeMined": false }, { @@ -385,12 +280,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 66, - "green": 57, - "blue": 15, - "alpha": 255 - }, + "mapColour": [66, 57, 15, 255], "canBeMined": false }, { @@ -401,12 +291,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 65, - "green": 52, - "blue": 28, - "alpha": 255 - }, + "mapColour": [65, 52, 28, 255], "canBeMined": false }, { @@ -417,12 +302,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 59, - "green": 40, - "blue": 18, - "alpha": 255 - }, + "mapColour": [59, 40, 18, 255], "canBeMined": false }, { @@ -433,12 +313,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 94, - "green": 66, - "blue": 37, - "alpha": 255 - }, + "mapColour": [94, 66, 37, 255], "canBeMined": false }, { @@ -449,12 +324,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 141, - "green": 104, - "blue": 60, - "alpha": 255 - }, + "mapColour": [141, 104, 60, 255], "canBeMined": false }, { @@ -465,12 +335,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 136, - "green": 96, - "blue": 59, - "alpha": 255 - }, + "mapColour": [136, 96, 59, 255], "canBeMined": false }, { @@ -481,12 +346,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 133, - "green": 92, - "blue": 53, - "alpha": 255 - }, + "mapColour": [133, 92, 53, 255], "canBeMined": false }, { @@ -497,12 +357,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 103, - "green": 72, - "blue": 43, - "alpha": 255 - }, + "mapColour": [103, 72, 43, 255], "canBeMined": false }, { @@ -513,12 +368,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 91, - "green": 63, - "blue": 38, - "alpha": 255 - }, + "mapColour": [91, 63, 38, 255], "canBeMined": false }, { @@ -529,12 +379,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 80, - "green": 55, - "blue": 31, - "alpha": 255 - }, + "mapColour": [80, 55, 31, 255], "canBeMined": false }, { @@ -545,12 +390,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 80, - "green": 54, - "blue": 28, - "alpha": 255 - }, + "mapColour": [80, 54, 28, 255], "canBeMined": false }, { @@ -561,12 +401,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 138, - "green": 103, - "blue": 58, - "alpha": 255 - }, + "mapColour": [138, 103, 58, 255], "canBeMined": false }, { @@ -577,12 +412,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 128, - "green": 93, - "blue": 52, - "alpha": 255 - }, + "mapColour": [128, 93, 52, 255], "canBeMined": false }, { @@ -593,12 +423,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 115, - "green": 83, - "blue": 47, - "alpha": 255 - }, + "mapColour": [115, 83, 47, 255], "canBeMined": false }, { @@ -609,12 +434,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 103, - "green": 70, - "blue": 32, - "alpha": 255 - }, + "mapColour": [103, 70, 32, 255], "canBeMined": false }, { @@ -625,12 +445,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 116, - "green": 81, - "blue": 39, - "alpha": 255 - }, + "mapColour": [116, 81, 39, 255], "canBeMined": false }, { @@ -641,12 +456,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 116, - "green": 84, - "blue": 43, - "alpha": 255 - }, + "mapColour": [116, 84, 43, 255], "canBeMined": false }, { @@ -657,12 +467,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 128, - "green": 93, - "blue": 52, - "alpha": 255 - }, + "mapColour": [128, 93, 52, 255], "canBeMined": false }, { @@ -677,12 +482,7 @@ class PrototypesTest : BehaviorSpec({ "resource-layer", "water-tile" ], - "mapColour": { - "red": 51, - "green": 83, - "blue": 95, - "alpha": 255 - }, + "mapColour": [51, 83, 95, 255], "canBeMined": false }, { @@ -697,12 +497,7 @@ class PrototypesTest : BehaviorSpec({ "resource-layer", "water-tile" ], - "mapColour": { - "red": 38, - "green": 64, - "blue": 73, - "alpha": 255 - }, + "mapColour": [38, 64, 73, 255], "canBeMined": false }, { @@ -717,12 +512,7 @@ class PrototypesTest : BehaviorSpec({ "resource-layer", "water-tile" ], - "mapColour": { - "red": 31, - "green": 48, - "blue": 18, - "alpha": 255 - }, + "mapColour": [31, 48, 18, 255], "canBeMined": false }, { @@ -737,12 +527,7 @@ class PrototypesTest : BehaviorSpec({ "resource-layer", "water-tile" ], - "mapColour": { - "red": 23, - "green": 37, - "blue": 16, - "alpha": 255 - }, + "mapColour": [23, 37, 16, 255], "canBeMined": false }, { @@ -756,12 +541,7 @@ class PrototypesTest : BehaviorSpec({ "resource-layer", "water-tile" ], - "mapColour": { - "red": 82, - "green": 98, - "blue": 92, - "alpha": 255 - }, + "mapColour": [82, 98, 92, 255], "canBeMined": false }, { @@ -775,12 +555,7 @@ class PrototypesTest : BehaviorSpec({ "resource-layer", "water-tile" ], - "mapColour": { - "red": 65, - "green": 89, - "blue": 90, - "alpha": 255 - }, + "mapColour": [65, 89, 90, 255], "canBeMined": false }, { @@ -791,12 +566,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 48, - "green": 40, - "blue": 35, - "alpha": 255 - }, + "mapColour": [48, 40, 35, 255], "canBeMined": false }, { @@ -811,12 +581,7 @@ class PrototypesTest : BehaviorSpec({ "resource-layer", "water-tile" ], - "mapColour": { - "red": 0, - "green": 0, - "blue": 0, - "alpha": 255 - }, + "mapColour": [0, 0, 0, 255], "canBeMined": false }, { @@ -826,12 +591,7 @@ class PrototypesTest : BehaviorSpec({ "layer": 0, "collisionMasks": { }, - "mapColour": { - "red": 0, - "green": 0, - "blue": 0, - "alpha": 255 - }, + "mapColour": [0, 0, 0, 255], "canBeMined": false }, { @@ -849,12 +609,7 @@ class PrototypesTest : BehaviorSpec({ "resource-layer", "water-tile" ], - "mapColour": { - "red": 0, - "green": 0, - "blue": 0, - "alpha": 255 - }, + "mapColour": [0, 0, 0, 255], "canBeMined": false }, { @@ -865,12 +620,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 49, - "green": 49, - "blue": 49, - "alpha": 255 - }, + "mapColour": [49, 49, 49, 255], "canBeMined": false }, { @@ -881,12 +631,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 0, - "green": 0, - "blue": 0, - "alpha": 255 - }, + "mapColour": [0, 0, 0, 255], "canBeMined": false }, { @@ -897,12 +642,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 255, - "green": 255, - "blue": 255, - "alpha": 255 - }, + "mapColour": [255, 255, 255, 255], "canBeMined": false }, { @@ -913,12 +653,7 @@ class PrototypesTest : BehaviorSpec({ "collisionMasks": [ "ground-tile" ], - "mapColour": { - "red": 122, - "green": 122, - "blue": 122, - "alpha": 255 - }, + "mapColour": [122, 122, 122, 255], "canBeMined": false } ] diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt index 2d1d4df..7ca4869 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt @@ -30,18 +30,8 @@ class UpdatePacketsTest : FunSpec({ "type": "dev.adamko.kafkatorio.schema2.PlayerUpdate", "key": {"index": 1}, "afkTime": 0, - "chatColour": { - "red": 1, - "green": 0.4, - "blue": 0.6, - "alpha": 1 - }, - "colour": { - "red": 0.8, - "green": 0.5, - "blue": 0.2, - "alpha": 0.5 - }, + "chatColour": [1, 0.4, 0.6, 1], + "colour": [0.8, 0.5, 0.2, 0.5], "eventCounts": { "on_player_changed_position": 7, "on_player_joined_game": 1 @@ -54,7 +44,10 @@ class UpdatePacketsTest : FunSpec({ "lastOnline": 0, "name": "fredthedeadhead", "onlineTime": 0, - "position": [-58, 13], + "position": [ + -58, + 13 + ], "tag": "" } } diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/serdes/MapTileDictionaryTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/serdes/MapTileDictionaryTest.kt new file mode 100644 index 0000000..31addee --- /dev/null +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/serdes/MapTileDictionaryTest.kt @@ -0,0 +1,41 @@ +package dev.adamko.kafkatorio.processor.serdes + +import dev.adamko.kafkatorio.schema.common.MapTileDictionary +import dev.adamko.kafkatorio.schema.common.PrototypeName +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.equality.shouldBeEqualToComparingFields +import kotlinx.serialization.decodeFromByteArray +import kotlinx.serialization.encodeToByteArray + +class MapTileDictionaryTest : FunSpec({ + + context("encode MapTileDictionary") { + val actual = MapTileDictionary( + tilesXY = mapOf( + "-192" to mapOf("-65" to MapTileDictionary.PrototypeKey(2)), + "161" to mapOf( + "-96" to MapTileDictionary.PrototypeKey(1), + "-95" to MapTileDictionary.PrototypeKey(2), + "94" to MapTileDictionary.PrototypeKey(2), + "93" to MapTileDictionary.PrototypeKey(32), + ), + + // unknown prototype + "44" to mapOf("1" to MapTileDictionary.PrototypeKey(44)), + ), + protos = mapOf( + PrototypeName("water") to MapTileDictionary.PrototypeKey(1), + PrototypeName("grass-4") to MapTileDictionary.PrototypeKey(2), + PrototypeName("grass-3") to MapTileDictionary.PrototypeKey(32), + + PrototypeName("not-used") to MapTileDictionary.PrototypeKey(99), + ) + ) + + test("binary round trip") { + val encoded: ByteArray = kxsBinary.encodeToByteArray(actual) + val decoded: MapTileDictionary = kxsBinary.decodeFromByteArray(encoded) + decoded.shouldBeEqualToComparingFields(actual) + } + } +}) From b0a6151c360da6ee5b7883db755c6221929ea7d3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 17:18:09 +0200 Subject: [PATCH 274/629] move from schema2 to schema --- .../kafkatorio-schema/kafkatorio-schema.ts | 68 +++++----- .../src/main/typescript/main/PacketEmitter.ts | 12 +- .../handleConfigurationUpdate.ts | 6 +- .../main/config-update/prototypes.ts | 20 +-- .../main/typescript/main/events/handlers.ts | 6 +- .../main/events/onConsoleEventHandlers.ts | 8 +- .../main/events/onMapChunkEventListeners.ts | 14 +- .../main/events/onPlayerEventListeners.ts | 10 +- .../main/settings/KafkatorioSettings.ts | 26 ++-- .../src/main/typescript/main/types.d.ts | 4 +- .../src/main/typescript/package.json | 12 +- .../packets/kafkatorioPacket.kt} | 8 +- .../packets/kafkatorioPacketInstant.kt} | 18 +-- .../packets/kafkatorioPacketKeyed.kt} | 10 +- ...ioPrototypes2.kt => factorioPrototypes.kt} | 4 +- .../events/schema/MapChunkUpdateTest.kt | 14 +- .../events/schema/PrototypesTest.kt | 122 +++++++++--------- .../events/schema/UpdatePacketsTest.kt | 30 ++--- .../adamko/kafkatorio/events/schema/kt2ts2.kt | 4 +- .../processor/admin/kafkatorioTopics.kt | 73 ++--------- .../kafkatorio/processor/serdes/kxsJson.kt | 17 --- .../topology/factorioServerPackets.kt | 10 +- .../processor/topology/groupMapChunks.kt | 4 +- .../processor/topology/packetDataStreams.kt | 12 +- .../processor/topology/playerUpdates.kt | 6 +- .../processor/topology/prototypes.kt | 8 +- .../processor/topology/GroupMapChunksTest.kt | 24 ++-- .../adamko/kafkatorio/webmap/converters.kt | 2 +- .../dev/adamko/kafkatorio/webmap/state.kt | 2 +- .../adamko/kafkatorio/webmap/websockets.kt | 20 +-- 30 files changed, 256 insertions(+), 318 deletions(-) rename modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/{schema2/kafkatorioPacket2.kt => schema/packets/kafkatorioPacket.kt} (54%) rename modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/{schema2/kafkatorioPacketInstant2.kt => schema/packets/kafkatorioPacketInstant.kt} (81%) rename modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/{schema2/kafkatorioPacketKeyed2.kt => schema/packets/kafkatorioPacketKeyed.kt} (94%) rename modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/{factorioPrototypes2.kt => factorioPrototypes.kt} (89%) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts index 8c9cb3a..741fb77 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts @@ -1,37 +1,37 @@ // Generated by kxs-ts-gen - do not edit this file manually -export interface KafkatorioPacket2 { +export interface KafkatorioPacket { modVersion: string; tick: Tick; - data: KafkatorioPacketData2; + data: KafkatorioPacketData; } export type Tick = UInt; -export type KafkatorioPacketData2 = - | KafkatorioPacketData2.ConfigurationUpdate - | KafkatorioPacketData2.ConsoleChatUpdate - | KafkatorioPacketData2.ConsoleCommandUpdate - | KafkatorioPacketData2.EntityUpdate - | KafkatorioPacketData2.MapChunkUpdate - | KafkatorioPacketData2.PlayerUpdate - | KafkatorioPacketData2.PrototypesUpdate - | KafkatorioPacketData2.SurfaceUpdate; +export type KafkatorioPacketData = + | KafkatorioPacketData.ConfigurationUpdate + | KafkatorioPacketData.ConsoleChatUpdate + | KafkatorioPacketData.ConsoleCommandUpdate + | KafkatorioPacketData.EntityUpdate + | KafkatorioPacketData.MapChunkUpdate + | KafkatorioPacketData.PlayerUpdate + | KafkatorioPacketData.PrototypesUpdate + | KafkatorioPacketData.SurfaceUpdate; -export namespace KafkatorioPacketData2 { +export namespace KafkatorioPacketData { export enum Type { - ConfigurationUpdate = "dev.adamko.kafkatorio.schema2.ConfigurationUpdate", - ConsoleChatUpdate = "dev.adamko.kafkatorio.schema2.ConsoleChatUpdate", - ConsoleCommandUpdate = "dev.adamko.kafkatorio.schema2.ConsoleCommandUpdate", - PrototypesUpdate = "dev.adamko.kafkatorio.schema2.PrototypesUpdate", - SurfaceUpdate = "dev.adamko.kafkatorio.schema2.SurfaceUpdate", - EntityUpdate = "dev.adamko.kafkatorio.schema2.EntityUpdate", - MapChunkUpdate = "dev.adamko.kafkatorio.schema2.MapChunkUpdate", - PlayerUpdate = "dev.adamko.kafkatorio.schema2.PlayerUpdate", + ConfigurationUpdate = "dev.adamko.kafkatorio.schema.packets.ConfigurationUpdate", + ConsoleChatUpdate = "dev.adamko.kafkatorio.schema.packets.ConsoleChatUpdate", + ConsoleCommandUpdate = "dev.adamko.kafkatorio.schema.packets.ConsoleCommandUpdate", + PrototypesUpdate = "dev.adamko.kafkatorio.schema.packets.PrototypesUpdate", + SurfaceUpdate = "dev.adamko.kafkatorio.schema.packets.SurfaceUpdate", + EntityUpdate = "dev.adamko.kafkatorio.schema.packets.EntityUpdate", + MapChunkUpdate = "dev.adamko.kafkatorio.schema.packets.MapChunkUpdate", + PlayerUpdate = "dev.adamko.kafkatorio.schema.packets.PlayerUpdate", } export interface ConfigurationUpdate { - type: KafkatorioPacketData2.Type.ConfigurationUpdate; + type: KafkatorioPacketData.Type.ConfigurationUpdate; factorioData: ConfigurationUpdateGameData; allMods: ConfigurationUpdateModData[]; modStartupSettingsChange: boolean; @@ -39,32 +39,32 @@ export namespace KafkatorioPacketData2 { } export interface ConsoleChatUpdate { - type: KafkatorioPacketData2.Type.ConsoleChatUpdate; + type: KafkatorioPacketData.Type.ConsoleChatUpdate; authorPlayerIndex: PlayerIndex | null; content: string; } export interface ConsoleCommandUpdate { - type: KafkatorioPacketData2.Type.ConsoleCommandUpdate; + type: KafkatorioPacketData.Type.ConsoleCommandUpdate; authorPlayerIndex: PlayerIndex | null; command: string; parameters: string; } export interface PrototypesUpdate { - type: KafkatorioPacketData2.Type.PrototypesUpdate; - prototypes: FactorioPrototype2[]; + type: KafkatorioPacketData.Type.PrototypesUpdate; + prototypes: FactorioPrototype[]; } export interface SurfaceUpdate { - type: KafkatorioPacketData2.Type.SurfaceUpdate; + type: KafkatorioPacketData.Type.SurfaceUpdate; index: SurfaceIndex; daytime: Double; name: string; } export interface EntityUpdate { - type: KafkatorioPacketData2.Type.EntityUpdate; + type: KafkatorioPacketData.Type.EntityUpdate; key: EntityUpdateKey; eventCounts?: { [key: string]: UInt } | null; chunkPosition?: MapChunkPosition | null; @@ -79,7 +79,7 @@ export namespace KafkatorioPacketData2 { } export interface MapChunkUpdate { - type: KafkatorioPacketData2.Type.MapChunkUpdate; + type: KafkatorioPacketData.Type.MapChunkUpdate; key: MapChunkUpdateKey; eventCounts?: { [key: string]: UInt } | null; player?: PlayerIndex | null; @@ -90,7 +90,7 @@ export namespace KafkatorioPacketData2 { } export interface PlayerUpdate { - type: KafkatorioPacketData2.Type.PlayerUpdate; + type: KafkatorioPacketData.Type.PlayerUpdate; key: PlayerUpdateKey; eventCounts?: { [key: string]: UInt } | null; characterUnitNumber?: UnitNumber | null; @@ -191,16 +191,16 @@ export interface ConfigurationUpdateModData { previousVersion?: string | null; } -export type FactorioPrototype2 = - | FactorioPrototype2.MapTile; +export type FactorioPrototype = + | FactorioPrototype.MapTile; -export namespace FactorioPrototype2 { +export namespace FactorioPrototype { export enum Type { - MapTile = "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + MapTile = "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", } export interface MapTile { - type: FactorioPrototype2.Type.MapTile; + type: FactorioPrototype.Type.MapTile; name: PrototypeName; layer: UInt; mapColour: Colour; diff --git a/modules/events-mod/src/main/typescript/main/PacketEmitter.ts b/modules/events-mod/src/main/typescript/main/PacketEmitter.ts index d73907f..55a1ba7 100644 --- a/modules/events-mod/src/main/typescript/main/PacketEmitter.ts +++ b/modules/events-mod/src/main/typescript/main/PacketEmitter.ts @@ -1,15 +1,15 @@ import { - KafkatorioPacket2, - KafkatorioPacketData2 + KafkatorioPacket, + KafkatorioPacketData } from "../generated/kafkatorio-schema/kafkatorio-schema"; import {KafkatorioKeyedPacketData} from "./types"; export class KafkatorioPacketEmitter { - emitInstantPacket( + emitInstantPacket( data: DATA, ) { - KafkatorioPacketEmitter.emitPacket({ + KafkatorioPacketEmitter.emitPacket({ data: data, modVersion: global.MOD_VERSION, tick: game.tick, @@ -19,7 +19,7 @@ export class KafkatorioPacketEmitter { emitKeyedPacket( data: DATA, ) { - KafkatorioPacketEmitter.emitPacket({ + KafkatorioPacketEmitter.emitPacket({ data: data, modVersion: global.MOD_VERSION, tick: game.tick, @@ -27,7 +27,7 @@ export class KafkatorioPacketEmitter { } /** Emit a serialised KafkatorioPacket */ - private static emitPacket(packet: T) { + private static emitPacket(packet: T) { let data = game.table_to_json(packet) localised_print(`KafkatorioPacket: ${data}`) // rcon.print(`KafkatorioPacket: ${data}`) diff --git a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts index 8652d83..208ab7d 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts @@ -2,10 +2,10 @@ import PacketEmitter from "../PacketEmitter"; import { ConfigurationUpdateGameData, ConfigurationUpdateModData, - KafkatorioPacketData2 + KafkatorioPacketData } from "../../generated/kafkatorio-schema/kafkatorio-schema"; -import Type = KafkatorioPacketData2.Type; -import ConfigurationUpdate = KafkatorioPacketData2.ConfigurationUpdate; +import Type = KafkatorioPacketData.Type; +import ConfigurationUpdate = KafkatorioPacketData.ConfigurationUpdate; export function emitConfigurationUpdate(changeData: ConfigurationChangedData) { diff --git a/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts b/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts index 573512b..10ab43e 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts @@ -1,11 +1,11 @@ import {Converters} from "../events/converters"; import PacketEmitter from "../PacketEmitter"; import { - FactorioPrototype2, - KafkatorioPacketData2 + FactorioPrototype, + KafkatorioPacketData } from "../../generated/kafkatorio-schema/kafkatorio-schema"; -import Type = KafkatorioPacketData2.Type; -import PrototypesUpdate = KafkatorioPacketData2.PrototypesUpdate; +import Type = KafkatorioPacketData.Type; +import PrototypesUpdate = KafkatorioPacketData.PrototypesUpdate; export function emitPrototypes() { @@ -18,20 +18,20 @@ export function emitPrototypes() { PacketEmitter.emitInstantPacket(data) } -function prototypes(): FactorioPrototype2[] { - let prototypes: FactorioPrototype2[] = [] +function prototypes(): FactorioPrototype[] { + let prototypes: FactorioPrototype[] = [] prototypes.push(...getMapTilePrototypes()) return prototypes } -function getMapTilePrototypes(): FactorioPrototype2.MapTile[] { - let tiles: FactorioPrototype2.MapTile[] = [] +function getMapTilePrototypes(): FactorioPrototype.MapTile[] { + let tiles: FactorioPrototype.MapTile[] = [] for (let [, tile] of game.tile_prototypes) { tiles.push( - { - type: FactorioPrototype2.Type.MapTile, + { + type: FactorioPrototype.Type.MapTile, name: tile.name, order: tile.order, diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index 1d1fe5b..fa5cd25 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -1,6 +1,6 @@ import PacketEmitter from "../PacketEmitter"; -import {KafkatorioPacketData2} from "../../generated/kafkatorio-schema/kafkatorio-schema"; -import Type = KafkatorioPacketData2.Type; +import {KafkatorioPacketData} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +import Type = KafkatorioPacketData.Type; // export function handlePlayerUpdate(tick: uint, eventType: string, playerIndex: uint) { // let player: LuaPlayer = game.players[playerIndex] @@ -36,7 +36,7 @@ export function handleSurfaceUpdate( eventType: string, surface: LuaSurface, ) { - const update: KafkatorioPacketData2.SurfaceUpdate = { + const update: KafkatorioPacketData.SurfaceUpdate = { type: Type.SurfaceUpdate, name: surface.name, diff --git a/modules/events-mod/src/main/typescript/main/events/onConsoleEventHandlers.ts b/modules/events-mod/src/main/typescript/main/events/onConsoleEventHandlers.ts index 48b2b8b..c76b673 100644 --- a/modules/events-mod/src/main/typescript/main/events/onConsoleEventHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/onConsoleEventHandlers.ts @@ -1,11 +1,11 @@ import PacketEmitter from "../PacketEmitter"; -import {KafkatorioPacketData2} from "../../generated/kafkatorio-schema/kafkatorio-schema"; -import Type = KafkatorioPacketData2.Type; +import {KafkatorioPacketData} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +import Type = KafkatorioPacketData.Type; script.on_event( defines.events.on_console_chat, (event: OnConsoleChatEvent) => { - const update: KafkatorioPacketData2.ConsoleChatUpdate = { + const update: KafkatorioPacketData.ConsoleChatUpdate = { type: Type.ConsoleChatUpdate, authorPlayerIndex: event.player_index ?? null, @@ -18,7 +18,7 @@ script.on_event( script.on_event( defines.events.on_console_command, (event: OnConsoleCommandEvent) => { - const update: KafkatorioPacketData2.ConsoleCommandUpdate = { + const update: KafkatorioPacketData.ConsoleCommandUpdate = { type: Type.ConsoleCommandUpdate, authorPlayerIndex: event.player_index ?? null, diff --git a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts index c3be4bf..84fdad3 100644 --- a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts @@ -2,15 +2,15 @@ import {isEventType} from "./eventTypeCheck"; import {Converters} from "./converters"; import EventUpdatesManager, {EventUpdates} from "../cache/EventDataCache"; import { - KafkatorioPacketData2, + KafkatorioPacketData, MapChunkPosition, MapTileDictionary } from "../../generated/kafkatorio-schema/kafkatorio-schema"; import CacheKey = EventUpdates.PacketKey; -import Type = KafkatorioPacketData2.Type; +import Type = KafkatorioPacketData.Type; -type MapChunkUpdater = (data: KafkatorioPacketData2.MapChunkUpdate) => void +type MapChunkUpdater = (data: KafkatorioPacketData.MapChunkUpdate) => void const mapProtoNameToKey: { [key: string]: uint } = {} @@ -38,12 +38,12 @@ function mapTilesUpdateDebounce( return } - const key: KafkatorioPacketData2.MapChunkUpdate["key"] = { + const key: KafkatorioPacketData.MapChunkUpdate["key"] = { surfaceIndex: surface.index, chunkPosition: chunkPosition, } - EventUpdatesManager.debounce( + EventUpdatesManager.debounce( key, Type.MapChunkUpdate, data => { @@ -267,12 +267,12 @@ script.on_event( } for (const position of e.positions) { - const key: CacheKey = { + const key: CacheKey = { surfaceIndex: surface.index, chunkPosition: [position.x, position.y], } - EventUpdatesManager.debounce( + EventUpdatesManager.debounce( key, Type.MapChunkUpdate, data => data.isDeleted = true, diff --git a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts index c60a891..bb69d2f 100644 --- a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts @@ -1,10 +1,10 @@ import {Converters} from "./converters"; import EventUpdatesManager from "../cache/EventDataCache"; -import {KafkatorioPacketData2} from "../../generated/kafkatorio-schema/kafkatorio-schema"; -import Type = KafkatorioPacketData2.Type; +import {KafkatorioPacketData} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +import Type = KafkatorioPacketData.Type; -type PlayerUpdater = (player: LuaPlayer, data: KafkatorioPacketData2.PlayerUpdate) => void +type PlayerUpdater = (player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) => void function playerUpdateThrottle( playerIndex: uint, @@ -12,7 +12,7 @@ function playerUpdateThrottle( mutate: PlayerUpdater, ) { - EventUpdatesManager.throttle( + EventUpdatesManager.throttle( {index: playerIndex}, Type.PlayerUpdate, data => { @@ -39,7 +39,7 @@ function playerUpdateThrottle( // ) // } -function playerOnlineInfo(player: LuaPlayer, data: KafkatorioPacketData2.PlayerUpdate) { +function playerOnlineInfo(player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) { data.lastOnline = player.last_online data.onlineTime = player.online_time data.afkTime = player.afk_time diff --git a/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts b/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts index d07be70..1137513 100644 --- a/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts +++ b/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts @@ -1,24 +1,24 @@ import {Data, DoubleSettingDefinition} from "typed-factorio/settings/types" import {KafkatorioKeyedPacketData, KafkatorioKeyedPacketTypes} from "../types"; -import {KafkatorioPacketData2} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +import {KafkatorioPacketData} from "../../generated/kafkatorio-schema/kafkatorio-schema"; export class KafkatorioSettingsConfig { private static eventCacheExpirationDefaultSeconds: Record = { - "dev.adamko.kafkatorio.schema2.PlayerUpdate": 0.5, - "dev.adamko.kafkatorio.schema2.MapChunkUpdate": 30, - "dev.adamko.kafkatorio.schema2.EntityUpdate": 5, + "dev.adamko.kafkatorio.schema.packets.PlayerUpdate": 0.5, + "dev.adamko.kafkatorio.schema.packets.MapChunkUpdate": 30, + "dev.adamko.kafkatorio.schema.packets.EntityUpdate": 5, } private eventCacheExpirationTicks: Record = { - "dev.adamko.kafkatorio.schema2.PlayerUpdate": - KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData2.Type.PlayerUpdate], - "dev.adamko.kafkatorio.schema2.MapChunkUpdate": - KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData2.Type.MapChunkUpdate], - "dev.adamko.kafkatorio.schema2.EntityUpdate": - KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData2.Type.EntityUpdate], + "dev.adamko.kafkatorio.schema.packets.PlayerUpdate": + KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.PlayerUpdate], + "dev.adamko.kafkatorio.schema.packets.MapChunkUpdate": + KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.MapChunkUpdate], + "dev.adamko.kafkatorio.schema.packets.EntityUpdate": + KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.EntityUpdate], } public getEventCacheExpirationTicks(packet: KafkatorioKeyedPacketData): uint { @@ -26,9 +26,9 @@ export class KafkatorioSettingsConfig { } private static types: KafkatorioKeyedPacketTypes[] = [ - KafkatorioPacketData2.Type.PlayerUpdate, - KafkatorioPacketData2.Type.MapChunkUpdate, - KafkatorioPacketData2.Type.EntityUpdate, + KafkatorioPacketData.Type.PlayerUpdate, + KafkatorioPacketData.Type.MapChunkUpdate, + KafkatorioPacketData.Type.EntityUpdate, ] public loadSettings(): void { diff --git a/modules/events-mod/src/main/typescript/main/types.d.ts b/modules/events-mod/src/main/typescript/main/types.d.ts index edf30aa..3259757 100644 --- a/modules/events-mod/src/main/typescript/main/types.d.ts +++ b/modules/events-mod/src/main/typescript/main/types.d.ts @@ -1,4 +1,4 @@ -import {KafkatorioPacketData2} from "../generated/kafkatorio-schema/kafkatorio-schema"; +import {KafkatorioPacketData} from "../generated/kafkatorio-schema/kafkatorio-schema"; export type EventName = keyof typeof defines.events @@ -19,7 +19,7 @@ type NonNullableKeys = { } -type KafkatorioKeyedPacketData = Extract +type KafkatorioKeyedPacketData = Extract type KafkatorioKeyedPacketTypes = KafkatorioKeyedPacketData["type"]; diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index ea7c2fb..dc5d159 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -9,7 +9,8 @@ "engines": { "node": "~14.19.1" }, - "devDependencies": {}, + "devDependencies": { + }, "dependencies": { "lua-types": "^2.11.0", "typescript-to-lua": "1.4.3", @@ -18,7 +19,10 @@ }, "// @types/node": "^12.0.8", "license": "UNLICENSED", - "peerDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": [] + "peerDependencies": { + }, + "optionalDependencies": { + }, + "bundledDependencies": [ + ] } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacket2.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt similarity index 54% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacket2.kt rename to modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt index 8149322..fc08e8f 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacket2.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt @@ -1,16 +1,16 @@ -package dev.adamko.kafkatorio.schema2 +package dev.adamko.kafkatorio.schema.packets import dev.adamko.kafkatorio.schema.common.Tick import kotlinx.serialization.Serializable @Serializable -data class KafkatorioPacket2( +data class KafkatorioPacket( val modVersion: String, val tick: Tick, - val data: KafkatorioPacketData2, + val data: KafkatorioPacketData, ) @Serializable -sealed class KafkatorioPacketData2 +sealed class KafkatorioPacketData diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketInstant2.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt similarity index 81% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketInstant2.kt rename to modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt index 0dd179d..f43ecec 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketInstant2.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt @@ -1,14 +1,14 @@ -package dev.adamko.kafkatorio.schema2 +package dev.adamko.kafkatorio.schema.packets import dev.adamko.kafkatorio.schema.common.PlayerIndex import dev.adamko.kafkatorio.schema.common.SurfaceIndex -import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2 +import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype import kotlinx.serialization.Serializable /** No key, no caching. Must be sent instantly. */ @Serializable -sealed class KafkatorioInstantPacketData2 : KafkatorioPacketData2() +sealed class KafkatorioInstantPacketData : KafkatorioPacketData() /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ @@ -20,7 +20,7 @@ data class ConfigurationUpdate( val allMods: List, val modStartupSettingsChange: Boolean, val migrationApplied: Boolean, -) : KafkatorioInstantPacketData2() { +) : KafkatorioInstantPacketData() { @Serializable data class ConfigurationUpdateGameData( @@ -41,7 +41,7 @@ data class ConfigurationUpdate( data class ConsoleChatUpdate( val authorPlayerIndex: PlayerIndex?, val content: String, -) : KafkatorioInstantPacketData2() +) : KafkatorioInstantPacketData() @Serializable @@ -49,13 +49,13 @@ data class ConsoleCommandUpdate( val authorPlayerIndex: PlayerIndex?, val command: String, val parameters: String, -) : KafkatorioInstantPacketData2() +) : KafkatorioInstantPacketData() @Serializable data class PrototypesUpdate( - val prototypes: List, -) : KafkatorioInstantPacketData2() + val prototypes: List, +) : KafkatorioInstantPacketData() @Serializable @@ -63,7 +63,7 @@ data class SurfaceUpdate( val index: SurfaceIndex, val daytime: Double, val name: String, -) : KafkatorioInstantPacketData2() +) : KafkatorioInstantPacketData() /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketKeyed2.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt similarity index 94% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketKeyed2.kt rename to modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt index 2b08157..6856725 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema2/kafkatorioPacketKeyed2.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.schema2 +package dev.adamko.kafkatorio.schema.packets import dev.adamko.kafkatorio.schema.common.Colour import dev.adamko.kafkatorio.schema.common.EntityIdentifiers @@ -17,7 +17,7 @@ import kotlinx.serialization.Serializable /** Has a key, so it can be debounced */ @Serializable -sealed class KafkatorioKeyedPacketData2 : KafkatorioPacketData2() { +sealed class KafkatorioKeyedPacketData : KafkatorioPacketData() { /** Count how many events this packet is aggregating data from */ abstract val key: KafkatorioKeyedPacketKey2 abstract val eventCounts: Map? @@ -54,7 +54,7 @@ data class EntityUpdate( val localisedDescription: String? = null, val localisedName: String? = null, val prototype: PrototypeName? = null, -) : KafkatorioKeyedPacketData2() +) : KafkatorioKeyedPacketData() /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ @@ -79,7 +79,7 @@ data class MapChunkUpdate( /** updated tiles - might be partial and not all tiles in the chunk */ val tileDictionary: MapTileDictionary? = null, val isDeleted: Boolean? = null, -) : KafkatorioKeyedPacketData2() +) : KafkatorioKeyedPacketData() /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ @@ -120,7 +120,7 @@ data class PlayerUpdate( val disconnectReason: String? = null, /** `true` when a player is removed (deleted) from the game */ val isRemoved: Boolean? = null, -) : KafkatorioKeyedPacketData2() +) : KafkatorioKeyedPacketData() /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes2.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt similarity index 89% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes2.kt rename to modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt index 3769128..a09c06f 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes2.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt @@ -7,7 +7,7 @@ import kotlinx.serialization.Serializable @Serializable -sealed class FactorioPrototype2 { +sealed class FactorioPrototype { @Serializable data class MapTile( @@ -19,5 +19,5 @@ sealed class FactorioPrototype2 { val order: String, /** Can the tile be mined for resources? */ val canBeMined: Boolean, - ) : FactorioPrototype2() + ) : FactorioPrototype() } diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt index 4bf7bea..046127a 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt @@ -6,14 +6,12 @@ import dev.adamko.kafkatorio.schema.common.PrototypeName import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio -import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 -import dev.adamko.kafkatorio.schema2.MapChunkUpdate -import dev.adamko.kafkatorio.schema2.MapChunkUpdateKey +import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket +import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate +import dev.adamko.kafkatorio.schema.packets.MapChunkUpdateKey import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe -import kotlin.math.exp import kotlinx.serialization.decodeFromString -import kotlinx.serialization.encodeToString class MapChunkUpdateTest : FunSpec({ @@ -22,7 +20,7 @@ class MapChunkUpdateTest : FunSpec({ val json = """ { "data": { - "type": "dev.adamko.kafkatorio.schema2.MapChunkUpdate", + "type": "dev.adamko.kafkatorio.schema.packets.MapChunkUpdate", "key": { "surfaceIndex": 1, "chunkPosition": [ @@ -57,7 +55,7 @@ class MapChunkUpdateTest : FunSpec({ } """.trimIndent() - val expected = KafkatorioPacket2( + val expected = KafkatorioPacket( tick = Tick(36u), modVersion = "0.4.0", data = MapChunkUpdate( @@ -86,7 +84,7 @@ class MapChunkUpdateTest : FunSpec({ ) test("decode") { - val packet: KafkatorioPacket2 = jsonMapperKafkatorio.decodeFromString(json) + val packet: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) packet shouldBe expected } } diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt index e4230ed..cfb67a8 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt @@ -3,9 +3,9 @@ package dev.adamko.kafkatorio.events.schema import dev.adamko.kafkatorio.schema.common.Colour import dev.adamko.kafkatorio.schema.common.PrototypeName import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio -import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2 -import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 -import dev.adamko.kafkatorio.schema2.PrototypesUpdate +import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype +import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket +import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import io.kotest.core.spec.style.BehaviorSpec import io.kotest.inspectors.forOne import io.kotest.matchers.shouldBe @@ -20,10 +20,10 @@ class PrototypesTest : BehaviorSpec({ "modVersion": "0.2.4", "tick": 534, "data": { - "type": "dev.adamko.kafkatorio.schema2.PrototypesUpdate", + "type": "dev.adamko.kafkatorio.schema.packets.PrototypesUpdate", "prototypes": [ { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "tile-unknown", "order": "z-a", "layer": 0, @@ -37,7 +37,7 @@ class PrototypesTest : BehaviorSpec({ """.trimIndent() Then("expect can be parsed") { - val data = jsonMapperKafkatorio.decodeFromString(raw) + val data = jsonMapperKafkatorio.decodeFromString(raw) println(data) } @@ -50,10 +50,10 @@ class PrototypesTest : BehaviorSpec({ "modVersion": "0.3.2", "tick": 534, "data": { - "type": "dev.adamko.kafkatorio.schema2.PrototypesUpdate", + "type": "dev.adamko.kafkatorio.schema.packets.PrototypesUpdate", "prototypes": [ { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "stone-path", "order": "a[artificial]-a[tier-1]-a[stone-path]", "layer": 60, @@ -64,7 +64,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "concrete", "order": "a[artificial]-b[tier-2]-a[concrete]", "layer": 61, @@ -75,7 +75,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "hazard-concrete-left", "order": "a[artificial]-b[tier-2]-b[hazard-concrete-left]", "layer": 62, @@ -86,7 +86,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "hazard-concrete-right", "order": "a[artificial]-b[tier-2]-c[hazard-concrete-right]", "layer": 62, @@ -97,7 +97,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "refined-concrete", "order": "a[artificial]-c[tier-3]-a[refined-concrete]", "layer": 64, @@ -108,7 +108,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "refined-hazard-concrete-left", "order": "a[artificial]-c[tier-3]-b[refined-hazard-concrete-left]", "layer": 65, @@ -119,7 +119,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "refined-hazard-concrete-right", "order": "a[artificial]-c[tier-3]-c[refined-hazard-concrete-right]", "layer": 65, @@ -130,7 +130,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "landfill", "order": "a[artificial]-d[utility]-a[landfill]", "layer": 57, @@ -141,7 +141,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "acid-refined-concrete", "order": "a[artificial]-e[color-concrete]-acid", "layer": 97, @@ -152,7 +152,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "black-refined-concrete", "order": "a[artificial]-e[color-concrete]-black", "layer": 88, @@ -163,7 +163,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "blue-refined-concrete", "order": "a[artificial]-e[color-concrete]-blue", "layer": 73, @@ -174,7 +174,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "brown-refined-concrete", "order": "a[artificial]-e[color-concrete]-brown", "layer": 91, @@ -185,7 +185,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "cyan-refined-concrete", "order": "a[artificial]-e[color-concrete]-cyan", "layer": 94, @@ -196,7 +196,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "green-refined-concrete", "order": "a[artificial]-e[color-concrete]-green", "layer": 70, @@ -207,7 +207,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "orange-refined-concrete", "order": "a[artificial]-e[color-concrete]-orange", "layer": 76, @@ -218,7 +218,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "pink-refined-concrete", "order": "a[artificial]-e[color-concrete]-pink", "layer": 82, @@ -229,7 +229,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "purple-refined-concrete", "order": "a[artificial]-e[color-concrete]-purple", "layer": 85, @@ -240,7 +240,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "red-refined-concrete", "order": "a[artificial]-e[color-concrete]-red", "layer": 67, @@ -251,7 +251,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "yellow-refined-concrete", "order": "a[artificial]-e[color-concrete]-yellow", "layer": 79, @@ -262,7 +262,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "grass-1", "order": "b[natural]-a[grass]-a[grass-1]", "layer": 26, @@ -273,7 +273,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "grass-2", "order": "b[natural]-a[grass]-b[grass-2]", "layer": 28, @@ -284,7 +284,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "grass-3", "order": "b[natural]-a[grass]-c[grass-3]", "layer": 29, @@ -295,7 +295,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "grass-4", "order": "b[natural]-a[grass]-d[grass-4]", "layer": 30, @@ -306,7 +306,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "dry-dirt", "order": "b[natural]-b[dirt]-a[dry-dirt]", "layer": 18, @@ -317,7 +317,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "dirt-1", "order": "b[natural]-b[dirt]-b[dirt-1]", "layer": 19, @@ -328,7 +328,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "dirt-2", "order": "b[natural]-b[dirt]-c[dirt-2]", "layer": 20, @@ -339,7 +339,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "dirt-3", "order": "b[natural]-b[dirt]-d[dirt-3]", "layer": 21, @@ -350,7 +350,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "dirt-4", "order": "b[natural]-b[dirt]-e[dirt-4]", "layer": 22, @@ -361,7 +361,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "dirt-5", "order": "b[natural]-b[dirt]-f[dirt-5]", "layer": 23, @@ -372,7 +372,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "dirt-6", "order": "b[natural]-b[dirt]-g[dirt-6]", "layer": 24, @@ -383,7 +383,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "dirt-7", "order": "b[natural]-b[dirt]-h[dirt-7]", "layer": 25, @@ -394,7 +394,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "sand-1", "order": "b[natural]-c[sand]-a[sand-1]", "layer": 8, @@ -405,7 +405,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "sand-2", "order": "b[natural]-c[sand]-b[sand-2]", "layer": 9, @@ -416,7 +416,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "sand-3", "order": "b[natural]-c[sand]-c[sand-3]", "layer": 10, @@ -427,7 +427,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "red-desert-0", "order": "b[natural]-d[red-desert]-a[red-desert-0]", "layer": 31, @@ -438,7 +438,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "red-desert-1", "order": "b[natural]-d[red-desert]-b[red-desert-1]", "layer": 14, @@ -449,7 +449,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "red-desert-2", "order": "b[natural]-d[red-desert]-c[red-desert-2]", "layer": 15, @@ -460,7 +460,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "red-desert-3", "order": "b[natural]-d[red-desert]-d[red-desert-3]", "layer": 16, @@ -471,7 +471,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "water", "order": "c[water]-a[water]", "layer": 3, @@ -486,7 +486,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "deepwater", "order": "c[water]-b[deep-water]", "layer": 3, @@ -501,7 +501,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "water-green", "order": "c[water]-c[water-green]", "layer": 3, @@ -516,7 +516,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "deepwater-green", "order": "c[water]-d[deepwater-green]", "layer": 3, @@ -531,7 +531,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "water-shallow", "order": "c[water]-e[water-shallow]", "layer": 6, @@ -545,7 +545,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "water-mud", "order": "c[water]-g[water-mud]", "layer": 7, @@ -559,7 +559,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "nuclear-ground", "order": "d[destruction]-a[nuclear]-a[nuclear-ground]", "layer": 33, @@ -570,7 +570,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "water-wube", "order": "x[wube]-a[water-wube]", "layer": 2, @@ -585,7 +585,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "tile-unknown", "order": "z-a", "layer": 0, @@ -595,7 +595,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "out-of-map", "order": "z[other]-a[out-of-map]", "layer": 0, @@ -613,7 +613,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "lab-dark-1", "order": "z[other]-b[lab]-a[lab-dark-1]", "layer": 70, @@ -624,7 +624,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "lab-dark-2", "order": "z[other]-b[lab]-b[lab-dark-2]", "layer": 70, @@ -635,7 +635,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "lab-white", "order": "z[other]-b[lab]-c[lab-white]", "layer": 70, @@ -646,7 +646,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2.MapTile", + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", "name": "tutorial-grid", "order": "z[other]-c[tutorial]-a[tutorial-grid]", "layer": 55, @@ -662,13 +662,13 @@ class PrototypesTest : BehaviorSpec({ """.trimIndent() Then("expect can be parsed") { - val packet: KafkatorioPacket2 = jsonMapperKafkatorio.decodeFromString(raw) + val packet: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(raw) // println(packet) packet.data.shouldBeInstanceOf() .prototypes .forOne { - it.shouldBeInstanceOf() + it.shouldBeInstanceOf() it.name shouldBe PrototypeName("tutorial-grid") it.order shouldBe "z[other]-c[tutorial]-a[tutorial-grid]" it.layer shouldBe 55u diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt index 7ca4869..742b234 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt @@ -9,10 +9,10 @@ import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.common.UnitNumber import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio -import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 -import dev.adamko.kafkatorio.schema2.PlayerUpdate -import dev.adamko.kafkatorio.schema2.PlayerUpdateKey -import dev.adamko.kafkatorio.schema2.SurfaceUpdate +import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket +import dev.adamko.kafkatorio.schema.packets.PlayerUpdate +import dev.adamko.kafkatorio.schema.packets.PlayerUpdateKey +import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import kotlinx.serialization.decodeFromString @@ -27,7 +27,7 @@ class UpdatePacketsTest : FunSpec({ "tick": 66, "modVersion": "0.3.2", "data": { - "type": "dev.adamko.kafkatorio.schema2.PlayerUpdate", + "type": "dev.adamko.kafkatorio.schema.packets.PlayerUpdate", "key": {"index": 1}, "afkTime": 0, "chatColour": [1, 0.4, 0.6, 1], @@ -54,9 +54,9 @@ class UpdatePacketsTest : FunSpec({ """.trimIndent() test("decode") { - val packet: KafkatorioPacket2 = jsonMapperKafkatorio.decodeFromString(json) + val packet: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) - packet shouldBe KafkatorioPacket2( + packet shouldBe KafkatorioPacket( modVersion = "0.3.2", tick = Tick(66u), data = PlayerUpdate( @@ -88,7 +88,7 @@ class UpdatePacketsTest : FunSpec({ } test("encode") { - val v = KafkatorioPacket2( + val v = KafkatorioPacket( modVersion = "0.3.2", tick = Tick(66u), data = PlayerUpdate( @@ -124,7 +124,7 @@ class UpdatePacketsTest : FunSpec({ "modVersion": "0.3.2", "tick": 66, "data": { - "type": "dev.adamko.kafkatorio.schema2.PlayerUpdate", + "type": "dev.adamko.kafkatorio.schema.packets.PlayerUpdate", "key": { "index": 1 }, @@ -151,7 +151,7 @@ class UpdatePacketsTest : FunSpec({ "tick": 227934, "modVersion": "0.3.2", "data": { - "type": "dev.adamko.kafkatorio.schema2.PlayerUpdate", + "type": "dev.adamko.kafkatorio.schema.packets.PlayerUpdate", "key": { "index": 1 }, @@ -172,9 +172,9 @@ class UpdatePacketsTest : FunSpec({ """.trimIndent() test("decode") { - val packet: KafkatorioPacket2 = jsonMapperKafkatorio.decodeFromString(json) + val packet: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) - packet shouldBe KafkatorioPacket2( + packet shouldBe KafkatorioPacket( modVersion = "0.3.2", tick = Tick(227934u), data = PlayerUpdate( @@ -215,7 +215,7 @@ class UpdatePacketsTest : FunSpec({ val json = """ { "data": { - "type": "dev.adamko.kafkatorio.schema2.SurfaceUpdate", + "type": "dev.adamko.kafkatorio.schema.packets.SurfaceUpdate", "name": "nauvis", "index": 1, "daytime": 0.73 @@ -225,7 +225,7 @@ class UpdatePacketsTest : FunSpec({ } """.trimIndent() - val expected = KafkatorioPacket2( + val expected = KafkatorioPacket( tick = Tick(176000u), modVersion = "0.3.2", data = SurfaceUpdate( @@ -238,7 +238,7 @@ class UpdatePacketsTest : FunSpec({ println(jsonMapperKafkatorio.encodeToString(expected)) test("decode") { - val packet: KafkatorioPacket2 = jsonMapperKafkatorio.decodeFromString(json) + val packet: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) packet shouldBe expected } } diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt index 6976f5b..36b0972 100644 --- a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt +++ b/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt @@ -1,6 +1,6 @@ package dev.adamko.kafkatorio.events.schema -import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 +import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kxstsgen.KxsTsConfig import dev.adamko.kxstsgen.KxsTsGenerator import dev.adamko.kxstsgen.core.TsDeclaration.TsTypeAlias @@ -36,7 +36,7 @@ fun main(args: Array) { ) val definitions = gen2.generate( - KafkatorioPacket2.serializer(), + KafkatorioPacket.serializer(), // KafkatorioKeyedPacketKey2.serializer(), ) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt index 6047fc0..5a7781e 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt @@ -1,14 +1,14 @@ package dev.adamko.kafkatorio.processor.admin -import dev.adamko.kafkatorio.schema2.ConfigurationUpdate -import dev.adamko.kafkatorio.schema2.ConsoleChatUpdate -import dev.adamko.kafkatorio.schema2.ConsoleCommandUpdate -import dev.adamko.kafkatorio.schema2.EntityUpdate -import dev.adamko.kafkatorio.schema2.KafkatorioPacketData2 -import dev.adamko.kafkatorio.schema2.MapChunkUpdate -import dev.adamko.kafkatorio.schema2.PlayerUpdate -import dev.adamko.kafkatorio.schema2.PrototypesUpdate -import dev.adamko.kafkatorio.schema2.SurfaceUpdate +import dev.adamko.kafkatorio.schema.packets.ConfigurationUpdate +import dev.adamko.kafkatorio.schema.packets.ConsoleChatUpdate +import dev.adamko.kafkatorio.schema.packets.ConsoleCommandUpdate +import dev.adamko.kafkatorio.schema.packets.EntityUpdate +import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData +import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate +import dev.adamko.kafkatorio.schema.packets.PlayerUpdate +import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate +import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate import kotlin.reflect.KClass @@ -16,7 +16,7 @@ private const val DOMAIN = "kafkatorio" const val TOPIC_SRC_SERVER_LOG = "$DOMAIN.src.server-log" -// "factorio-server-log" + const val TOPIC_GROUPED_MAP_CHUNKS_STATE = "$DOMAIN.state.map-chunks.grouped" @@ -27,12 +27,7 @@ fun allTopics(): Set = buildSet { addAll(packetTopicNames.values) } -//fun KafkatorioPacket2.topicName(): String = data.topicName() - -//fun KafkatorioPacketData2.topicName(): String = "$DOMAIN.packet.${topicName}" - - -val KafkatorioPacketData2.topicName: String +val KafkatorioPacketData.topicName: String get() = when (this) { is ConfigurationUpdate -> packetTopicNames.getValue(ConfigurationUpdate::class) is ConsoleChatUpdate -> packetTopicNames.getValue(ConsoleChatUpdate::class) @@ -45,7 +40,7 @@ val KafkatorioPacketData2.topicName: String } -private val packetTopicNames: Map, String> = mapOf( +private val packetTopicNames: Map, String> = mapOf( ConfigurationUpdate::class to "configuration", ConsoleChatUpdate::class to "console-chat", ConsoleCommandUpdate::class to "console-command", @@ -58,47 +53,5 @@ private val packetTopicNames: Map, String> = m "$DOMAIN.packet.$v" } -val KClass.topicName: String +val KClass.topicName: String get() = packetTopicNames.getValue(this) - -//fun packetTopic( -// dataType: KafkatorioKeyedPacketData.KafkatorioKeyedPacketDataType, -//): String = packetTopic(KafkatorioPacketType.KEYED, dataType.name.lowercase()) -// -//private fun packetTopic( -// packetType: KafkatorioPacketType, -// dataType: String, -//): String { -// return "$DOMAIN.packet.$packetType.$dataType" -//} - -//sealed interface KafkatorioTopic { -// -// val type: String -// val entity: String -// val description: String -// -// companion object { -// private const val DOMAIN = "kafkatorio" -// -// val KafkatorioTopic.topic -// get() = listOf(DOMAIN, type, entity, description).joinToString(".") -// -// } -// -// data class Event( -// override val entity: String, -// override val description: String, -// ) : KafkatorioTopic { -// override val type: String = "event" -// } -// -// -// data class State( -// override val entity: String, -// override val description: String, -// ) : KafkatorioTopic { -// override val type: String = "state" -// } -// -//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt index 8869207..bf6becd 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt @@ -1,28 +1,11 @@ package dev.adamko.kafkatorio.processor.serdes import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio -import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 -import kotlinx.serialization.decodeFromString -import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json -import org.apache.kafka.common.serialization.Deserializer -import org.apache.kafka.common.serialization.Serde -import org.apache.kafka.common.serialization.Serializer import org.http4k.format.ConfigurableKotlinxSerialization import org.http4k.format.asConfigurable import org.http4k.format.withStandardMappings - -//object KafkatorioPacketSerde : Serde { -// override fun serializer() = Serializer { _, message -> -// jsonMapper.encodeToString(message).encodeToByteArray() -// } -// -// override fun deserializer() = Deserializer { _, bytes -> -// jsonMapper.decodeFromString(bytes.decodeToString()) -// } -//} - val jsonMapper: Json = Json { prettyPrint = true prettyPrintIndent = " " diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt index 2a3e6dd..37254c7 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt @@ -4,7 +4,7 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.processor.admin.TOPIC_SRC_SERVER_LOG import dev.adamko.kafkatorio.processor.admin.topicName import dev.adamko.kafkatorio.processor.serdes.jsonMapper -import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 +import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.streams.map @@ -19,7 +19,7 @@ import org.apache.kafka.streams.processor.RecordContext fun factorioServerPacketStream( builder: StreamsBuilder = StreamsBuilder(), -): KStream { +): KStream { return builder.stream( TOPIC_SRC_SERVER_LOG, @@ -29,14 +29,14 @@ fun factorioServerPacketStream( Serdes.String(), ) ).map("decode-packets") { serverId: String, value: String -> - val packet = jsonMapper.decodeFromString(value) + val packet = jsonMapper.decodeFromString(value) FactorioServerId(serverId) to packet } } fun splitFactorioServerPacketStream( - factorioServerPacketStream: KStream + factorioServerPacketStream: KStream ) { factorioServerPacketStream .to( @@ -45,7 +45,7 @@ fun splitFactorioServerPacketStream( jsonMapper.serde(), jsonMapper.serde(), ) - ) { _: FactorioServerId, value: KafkatorioPacket2, _: RecordContext -> + ) { _: FactorioServerId, value: KafkatorioPacket, _: RecordContext -> // println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") value.data.topicName } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt index ee03ef6..3122622 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt @@ -10,8 +10,8 @@ import dev.adamko.kafkatorio.schema.common.MapTilePosition import dev.adamko.kafkatorio.schema.common.MapTiles import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.toMapChunkPosition -import dev.adamko.kafkatorio.schema2.MapChunkUpdate -import dev.adamko.kafkatorio.schema2.PrototypesUpdate +import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate +import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.producedAs diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt index 1df6221..31a1bde 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt @@ -2,8 +2,8 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.processor.admin.topicName import dev.adamko.kafkatorio.processor.serdes.jsonMapper -import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 -import dev.adamko.kafkatorio.schema2.KafkatorioPacketData2 +import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket +import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.streams.mapValues import dev.adamko.kotka.kxs.serde @@ -11,17 +11,17 @@ import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.kstream.KStream -inline fun StreamsBuilder.streamPacketData(): KStream { +inline fun StreamsBuilder.streamPacketData(): KStream { val simpleName = T::class.simpleName!! val topicName = T::class.topicName - return stream( + return stream( topicName, consumedAs("consume.${simpleName}", jsonMapper.serde(), jsonMapper.serde()) - ).filter { key: FactorioServerId?, value: KafkatorioPacket2? -> + ).filter { key: FactorioServerId?, value: KafkatorioPacket? -> key != null && value?.data is T - }.mapValues("consume.map-values.${simpleName}") { _: FactorioServerId, packet: KafkatorioPacket2 -> + }.mapValues("consume.map-values.${simpleName}") { _: FactorioServerId, packet: KafkatorioPacket -> packet.data as T } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt index f99a6e4..ef10585 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt @@ -3,8 +3,8 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.processor.WebsocketServer import dev.adamko.kafkatorio.processor.admin.topicName import dev.adamko.kafkatorio.processor.serdes.jsonMapper -import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 -import dev.adamko.kafkatorio.schema2.PlayerUpdate +import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket +import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.kxs.serde import kotlinx.serialization.encodeToString @@ -15,7 +15,7 @@ fun playerUpdatesToWsServer( websocketServer: WebsocketServer, builder: StreamsBuilder = StreamsBuilder(), ) { - builder.stream( + builder.stream( PlayerUpdate::class.topicName, consumedAs("EventUpdate.Player-updates-for-ws-server", jsonMapper.serde(), jsonMapper.serde()), ).foreach { _, value -> diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index 96c055a..4661507 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -4,8 +4,8 @@ import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.MapTile import dev.adamko.kafkatorio.schema.common.toHex -import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2 -import dev.adamko.kafkatorio.schema2.PrototypesUpdate +import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype +import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.mapValues @@ -21,7 +21,7 @@ import org.apache.kafka.streams.kstream.KTable @Serializable value class TileProtoHashCode private constructor(val code: Int) { constructor(tile: MapTile) : this(tile.proto.hashCode()) - constructor(tile: FactorioPrototype2.MapTile) : this(tile.name.hashCode()) + constructor(tile: FactorioPrototype.MapTile) : this(tile.name.hashCode()) } @@ -38,7 +38,7 @@ fun tileProtoColourDictionary( return factorioServerPacketStream.mapValues("server-map-data.tile-prototypes.map-values") { _, protoPacket: PrototypesUpdate -> val map = protoPacket .prototypes - .filterIsInstance() + .filterIsInstance() .associate { TileProtoHashCode(it) to it.mapColour.toHex() } TileColourDict(map) diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt index 79bc5a0..5c8fffe 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt @@ -12,11 +12,11 @@ import dev.adamko.kafkatorio.schema.common.MapTilePosition import dev.adamko.kafkatorio.schema.common.PrototypeName import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.Tick -import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype2 -import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 -import dev.adamko.kafkatorio.schema2.MapChunkUpdate -import dev.adamko.kafkatorio.schema2.MapChunkUpdateKey -import dev.adamko.kafkatorio.schema2.PrototypesUpdate +import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype +import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket +import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate +import dev.adamko.kafkatorio.schema.packets.MapChunkUpdateKey +import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import dev.adamko.kotka.kxs.serde import io.kotest.assertions.withClue import io.kotest.core.spec.style.FunSpec @@ -42,23 +42,23 @@ class GroupMapChunksTest : FunSpec({ val testDriver = TopologyTestDriver(topology) - val prototypesTestInputTopic: TestInputTopic = + val prototypesTestInputTopic: TestInputTopic = testDriver.createInputTopic( prototypesTopicName, jsonMapper.serde().serializer(), - jsonMapper.serde().serializer(), + jsonMapper.serde().serializer(), ) val serverId = FactorioServerId("test-server-id") prototypesTestInputTopic.pipeInput( serverId, - KafkatorioPacket2( + KafkatorioPacket( modVersion = "1.2.3", tick = Tick(22u), PrototypesUpdate( listOf( - FactorioPrototype2.MapTile( + FactorioPrototype.MapTile( PrototypeName("fake-proto"), layer = 1u, mapColour = Colour(0.3f, 0.2f, 0.1f, 1.0f), @@ -71,16 +71,16 @@ class GroupMapChunksTest : FunSpec({ ) ) - val mapChunkUpdatesInputTopic: TestInputTopic = + val mapChunkUpdatesInputTopic: TestInputTopic = testDriver.createInputTopic( mapChunkUpdatesTopicName, jsonMapper.serde().serializer(), - jsonMapper.serde().serializer(), + jsonMapper.serde().serializer(), ) mapChunkUpdatesInputTopic.pipeInput( serverId, - KafkatorioPacket2( + KafkatorioPacket( modVersion = "1.2.3", tick = Tick(44u), MapChunkUpdate( diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt index 99bcb2c..b47e73b 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt @@ -1,7 +1,7 @@ package dev.adamko.kafkatorio.webmap import dev.adamko.kafkatorio.schema.common.MapEntityPosition -import dev.adamko.kafkatorio.schema2.PlayerUpdate +import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import io.kvision.maps.Maps import io.kvision.maps.externals.leaflet.geo.LatLng diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt index d6be2cc..050e966 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt @@ -6,7 +6,7 @@ import dev.adamko.kafkatorio.schema.common.PlayerIndex import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.common.toHexString -import dev.adamko.kafkatorio.schema2.PlayerUpdate +import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import io.kvision.maps.Maps import io.kvision.maps.Maps.Companion.L import io.kvision.maps.externals.leaflet.geo.LatLng diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt index 97130f0..cdeffb9 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -1,14 +1,14 @@ package dev.adamko.kafkatorio.webmap -import dev.adamko.kafkatorio.schema2.ConfigurationUpdate -import dev.adamko.kafkatorio.schema2.ConsoleChatUpdate -import dev.adamko.kafkatorio.schema2.ConsoleCommandUpdate -import dev.adamko.kafkatorio.schema2.EntityUpdate -import dev.adamko.kafkatorio.schema2.KafkatorioPacket2 -import dev.adamko.kafkatorio.schema2.MapChunkUpdate -import dev.adamko.kafkatorio.schema2.PlayerUpdate -import dev.adamko.kafkatorio.schema2.PrototypesUpdate -import dev.adamko.kafkatorio.schema2.SurfaceUpdate +import dev.adamko.kafkatorio.schema.packets.ConfigurationUpdate +import dev.adamko.kafkatorio.schema.packets.ConsoleChatUpdate +import dev.adamko.kafkatorio.schema.packets.ConsoleCommandUpdate +import dev.adamko.kafkatorio.schema.packets.EntityUpdate +import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket +import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate +import dev.adamko.kafkatorio.schema.packets.PlayerUpdate +import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate +import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate import io.kvision.redux.ReduxStore import kotlinx.serialization.decodeFromString import org.w3c.dom.MessageEvent @@ -36,7 +36,7 @@ class WebsocketService( println(data.replace('\n', ' ')) - val packet: KafkatorioPacket2 = jsonMapper.decodeFromString(data) + val packet: KafkatorioPacket = jsonMapper.decodeFromString(data) when (val packetData = packet.data) { From 2287582880bb0dc0aec965cb845530e86b5a7f9f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 17:54:54 +0200 Subject: [PATCH 275/629] tidy up code --- .../processor/topology/groupMapChunks.kt | 22 ------------------- .../kafkatorio/processor/topology/model.kt | 2 +- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt index 3122622..9ac4fff 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt @@ -56,31 +56,9 @@ fun groupMapChunks(builder: StreamsBuilder): Topology { val mapChunksStream: KStream = builder.streamPacketData() val protosStream: KStream = builder.streamPacketData() -// val protosStream: KStream = -// builder.stream( -// prototypesTopicName, -// consumedAs("consume.factorio-protos.all", jsonMapper.serde(), jsonMapper.serde()) -// ).filter { key: FactorioServerId?, value: KafkatorioPacket2? -> -// key != null -// && value != null -// && value.data == -// } -// .map - - val tileProtoColourDict: KTable = tileProtoColourDictionary(protosStream) -// val mapChunksUpdatesStream: KStream = -// builder.stream( -// mapChunkUpdatesTopicName, -// consumedAs( -// "consume.map-chunk-updates", -// jsonMapper.serde(), -// jsonMapper.serde(), -// ) -// ) - val groupedMapChunkTiles: KTable> = groupTilesIntoChunksWithColours( mapChunksStream, diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt index 3ed4ef8..376e63d 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt @@ -7,7 +7,7 @@ import kotlinx.serialization.Serializable @JvmInline @Serializable -value class FactorioServerId(val id: String) { +value class FactorioServerId(private val id: String) { override fun toString() = id } From badc8928a98d5560d77b29c507febe84f1733dee Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 17:55:21 +0200 Subject: [PATCH 276/629] don't make topics compact by default --- modules/infra-kafka-cluster/src/kafka-server.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infra-kafka-cluster/src/kafka-server.properties b/modules/infra-kafka-cluster/src/kafka-server.properties index 02928c4..cffe0e8 100644 --- a/modules/infra-kafka-cluster/src/kafka-server.properties +++ b/modules/infra-kafka-cluster/src/kafka-server.properties @@ -126,5 +126,5 @@ log.retention.check.interval.ms=300000 message.max.bytes=10485760 replica.fetch.max.bytes=10485760 -log.cleanup.policy=compact +#log.cleanup.policy=compact auto.create.topics.enable=false From 2ba44229cad88e0c5afc4303cb801123a17bbe16 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 22:56:51 +0200 Subject: [PATCH 277/629] bump kotlin version --- buildSrc/build.gradle.kts | 2 +- gradle/libs.versions.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 3764e2b..0bb56bd 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -12,7 +12,7 @@ object Versions { const val jvmTarget = "11" const val kotlinTarget = "1.6" - const val kotlin = "1.6.20" + const val kotlin = "1.6.21" const val gradleNodePlugin = "3.2.1" const val gradleDockerComposePlugin = "0.15.1" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0ea7317..ce36119 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ ## compilation ## jvm = "11" -kotlin = "1.6.20" +kotlin = "1.6.21" ## libs ## camel-kafkaConnectors = "0.11.0" From 8ae4e934f75d58e1716cc11b25a521b37cf0b618 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 22:57:19 +0200 Subject: [PATCH 278/629] rm object casting TypeScript (no longer needed) --- .../handleConfigurationUpdate.ts | 2 +- .../main/config-update/prototypes.ts | 20 +++++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts index 208ab7d..109d5b7 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts @@ -41,7 +41,7 @@ function allMods(e: ConfigurationChangedData): ConfigurationUpdateModData[] { let currentVer = script.active_mods[modName] ?? e.mod_changes[modName].new_version ?? null let previousVer = e.mod_changes[modName]?.old_version ?? null - return { + return { modName: modName, currentVersion: currentVer, previousVersion: previousVer, diff --git a/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts b/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts index 10ab43e..d52776c 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts @@ -29,18 +29,16 @@ function prototypes(): FactorioPrototype[] { function getMapTilePrototypes(): FactorioPrototype.MapTile[] { let tiles: FactorioPrototype.MapTile[] = [] for (let [, tile] of game.tile_prototypes) { - tiles.push( - { - type: FactorioPrototype.Type.MapTile, + tiles.push({ + type: FactorioPrototype.Type.MapTile, - name: tile.name, - order: tile.order, - layer: tile.layer, - collisionMasks: convertCollisionMaskToNames(tile.collision_mask), - mapColour: Converters.mapColour(tile.map_color), - canBeMined: tile.mineable_properties.minable, - } - ) + name: tile.name, + order: tile.order, + layer: tile.layer, + collisionMasks: convertCollisionMaskToNames(tile.collision_mask), + mapColour: Converters.mapColour(tile.map_color), + canBeMined: tile.mineable_properties.minable, + }) } return tiles } From 2a3b0de95353a5b92ec0d5859ffe115467c083c7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 22:58:06 +0200 Subject: [PATCH 279/629] more tests for grouping map chunks --- .../processor/topology/GroupMapChunksTest.kt | 226 ++++++++++++------ 1 file changed, 153 insertions(+), 73 deletions(-) diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt index 5c8fffe..7cf0bca 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt @@ -12,11 +12,11 @@ import dev.adamko.kafkatorio.schema.common.MapTilePosition import dev.adamko.kafkatorio.schema.common.PrototypeName import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.Tick -import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate import dev.adamko.kafkatorio.schema.packets.MapChunkUpdateKey import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate +import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype import dev.adamko.kotka.kxs.serde import io.kotest.assertions.withClue import io.kotest.core.spec.style.FunSpec @@ -32,81 +32,17 @@ import org.apache.kafka.streams.TopologyTestDriver class GroupMapChunksTest : FunSpec({ - test("basic test") { - val streamsBuilder = StreamsBuilder() + test("proto, then map chunk") { - val prototypesTopicName = "kafkatorio.packet.prototypes" - val mapChunkUpdatesTopicName = "kafkatorio.packet.map-chunk" + val scenario = Scenario() - val topology = groupMapChunks(streamsBuilder) - - val testDriver = TopologyTestDriver(topology) - - val prototypesTestInputTopic: TestInputTopic = - testDriver.createInputTopic( - prototypesTopicName, - jsonMapper.serde().serializer(), - jsonMapper.serde().serializer(), - ) - - val serverId = FactorioServerId("test-server-id") - - prototypesTestInputTopic.pipeInput( - serverId, - KafkatorioPacket( - modVersion = "1.2.3", - tick = Tick(22u), - PrototypesUpdate( - listOf( - FactorioPrototype.MapTile( - PrototypeName("fake-proto"), - layer = 1u, - mapColour = Colour(0.3f, 0.2f, 0.1f, 1.0f), - collisionMasks = listOf("fake-mask"), - order = "fake-order", - canBeMined = false, - ) - ) - ) - ) + scenario.pipePrototypePacket( + PrototypesUpdate(listOf(testMockTile)) ) - val mapChunkUpdatesInputTopic: TestInputTopic = - testDriver.createInputTopic( - mapChunkUpdatesTopicName, - jsonMapper.serde().serializer(), - jsonMapper.serde().serializer(), - ) + scenario.pipeMapChunkPacket(testMapChunkUpdate) - mapChunkUpdatesInputTopic.pipeInput( - serverId, - KafkatorioPacket( - modVersion = "1.2.3", - tick = Tick(44u), - MapChunkUpdate( - key = MapChunkUpdateKey( - MapChunkPosition(11, 22), - SurfaceIndex(1u), - ), - tileDictionary = MapTileDictionary( - tilesXY = mapOf( - "1" to mapOf("2" to PrototypeKey(33)) - ), - protos = mapOf(PrototypeName("fake-proto") to PrototypeKey(33)) - ) - ) - ) - ) - - val outputTopic: TestOutputTopic> = - testDriver - .createOutputTopic( - TOPIC_GROUPED_MAP_CHUNKS_STATE, - kxsBinary.serde().deserializer(), - kxsBinary.serde>().deserializer(), - ) - - val records = outputTopic.readRecordsToList() + val records = scenario.mapTilesOutputTopic.readRecordsToList() withClue(records) { records shouldHaveSize 1 @@ -114,7 +50,7 @@ class GroupMapChunksTest : FunSpec({ records.map { it.key to it.value }.first() should { (key, value) -> key.shouldNotBeNull() key shouldBeEqualToComparingFields ServerMapChunkId( - serverId = serverId, + serverId = FactorioServerId("test-server-id"), chunkPosition = MapChunkPosition(0, 0), surfaceIndex = SurfaceIndex(1u), chunkSize = ChunkSize.CHUNK_512, @@ -129,4 +65,148 @@ class GroupMapChunksTest : FunSpec({ } } } -}) + + test("map chunk, then proto") { + + val scenario = Scenario() + + scenario.pipePrototypePacket( + PrototypesUpdate(listOf(testMockTile.copy(mapColour = COLOUR_ONE))) + ) + + scenario.pipeMapChunkPacket(testMapChunkUpdate) + + var records = scenario.mapTilesOutputTopic.readRecordsToList() + + withClue(records) { + records shouldHaveSize 1 + + records.map { it.key to it.value }.first() should { (key, value) -> + key.shouldNotBeNull() + key shouldBeEqualToComparingFields ServerMapChunkId( + serverId = FactorioServerId("test-server-id"), + chunkPosition = MapChunkPosition(0, 0), + surfaceIndex = SurfaceIndex(1u), + chunkSize = ChunkSize.CHUNK_512, + ) + value.shouldNotBeNull() + value shouldBeEqualToComparingFields ServerMapChunkTiles( + chunkId = key, + map = mapOf( + MapTilePosition(1, 2) to ColourHex(25u, 25u, 25u, 25u) + ) + ) + } + } + + scenario.pipePrototypePacket( + PrototypesUpdate(listOf(testMockTile.copy(mapColour = COLOUR_TWO))) + ) + + records = scenario.mapTilesOutputTopic.readRecordsToList() + + withClue(records) { + records shouldHaveSize 1 + + records.map { it.key to it.value }.first() should { (key, value) -> + key.shouldNotBeNull() + key shouldBeEqualToComparingFields ServerMapChunkId( + serverId = FactorioServerId("test-server-id"), + chunkPosition = MapChunkPosition(0, 0), + surfaceIndex = SurfaceIndex(1u), + chunkSize = ChunkSize.CHUNK_512, + ) + value.shouldNotBeNull() + value shouldBeEqualToComparingFields ServerMapChunkTiles( + chunkId = key, + map = mapOf( + MapTilePosition(1, 2) to ColourHex(51u, 51u, 51u, 51u) + ) + ) + } + } + } +}) { + + class Scenario( + streamsBuilder: StreamsBuilder = StreamsBuilder(), + + prototypesTopicName: String = "kafkatorio.packet.prototypes", + mapChunkUpdatesTopicName: String = "kafkatorio.packet.map-chunk", + + private val serverId: FactorioServerId = FactorioServerId("test-server-id"), + ) { + private val topology = groupMapChunks(streamsBuilder) + private val testDriver: TopologyTestDriver = TopologyTestDriver(topology) + + private val prototypesTestInputTopic: TestInputTopic = + testDriver.createInputTopic( + prototypesTopicName, + jsonMapper.serde().serializer(), + jsonMapper.serde().serializer(), + ) + + private val mapChunkUpdatesInputTopic: TestInputTopic = + testDriver.createInputTopic( + mapChunkUpdatesTopicName, + jsonMapper.serde().serializer(), + jsonMapper.serde().serializer(), + ) + + val mapTilesOutputTopic: TestOutputTopic> = + testDriver.createOutputTopic( + TOPIC_GROUPED_MAP_CHUNKS_STATE, + kxsBinary.serde().deserializer(), + kxsBinary.serde>().deserializer(), + ) + + fun pipePrototypePacket(prototypeUpdate: PrototypesUpdate) { + prototypesTestInputTopic.pipeInput( + serverId, + KafkatorioPacket( + modVersion = "1.2.3", + tick = Tick(22u), + data = prototypeUpdate, + ) + ) + } + + fun pipeMapChunkPacket(mapChunkUpdate: MapChunkUpdate) { + mapChunkUpdatesInputTopic.pipeInput( + serverId, + KafkatorioPacket( + modVersion = "1.2.3", + tick = Tick(44u), + data = mapChunkUpdate + ) + ) + } + } + + companion object { + val COLOUR_ONE = Colour(0.1f, 0.1f, 0.1f, 0.1f) + val COLOUR_TWO = Colour(0.2f, 0.2f, 0.2f, 0.2f) + + val testMockTile = FactorioPrototype.MapTile( + PrototypeName("fake-proto"), + layer = 1u, + mapColour = Colour(0.3f, 0.2f, 0.1f, 1.0f), + collisionMasks = listOf("fake-mask"), + order = "fake-order", + canBeMined = false, + ) + + val testMapChunkUpdate = MapChunkUpdate( + key = MapChunkUpdateKey( + MapChunkPosition(11, 22), + SurfaceIndex(1u), + ), + tileDictionary = MapTileDictionary( + tilesXY = mapOf( + "1" to mapOf("2" to PrototypeKey(33)) + ), + protos = mapOf(PrototypeName("fake-proto") to PrototypeKey(33)) + ) + ) + } +} From 648cb31de89c3a351f3e64f54054b5a9e9c95fbe Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 23:07:17 +0200 Subject: [PATCH 280/629] disable topic auto create --- modules/infra-kafka-cluster/src/kafka-server.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infra-kafka-cluster/src/kafka-server.properties b/modules/infra-kafka-cluster/src/kafka-server.properties index cffe0e8..dd3de1f 100644 --- a/modules/infra-kafka-cluster/src/kafka-server.properties +++ b/modules/infra-kafka-cluster/src/kafka-server.properties @@ -127,4 +127,4 @@ message.max.bytes=10485760 replica.fetch.max.bytes=10485760 #log.cleanup.policy=compact -auto.create.topics.enable=false +#auto.create.topics.enable=false From bb54f6666b6735acd4d2634e0b3970659f476da3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 23:15:20 +0200 Subject: [PATCH 281/629] fix 'prototype key' in MapTileDictionary --- .../main/events/onMapChunkEventListeners.ts | 27 +++++++------------ .../kafkatorio/schema/common/mapTile.kt | 6 +++-- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts index 84fdad3..e30886d 100644 --- a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts @@ -3,8 +3,7 @@ import {Converters} from "./converters"; import EventUpdatesManager, {EventUpdates} from "../cache/EventDataCache"; import { KafkatorioPacketData, - MapChunkPosition, - MapTileDictionary + MapChunkPosition } from "../../generated/kafkatorio-schema/kafkatorio-schema"; import CacheKey = EventUpdates.PacketKey; import Type = KafkatorioPacketData.Type; @@ -13,18 +12,6 @@ import Type = KafkatorioPacketData.Type; type MapChunkUpdater = (data: KafkatorioPacketData.MapChunkUpdate) => void -const mapProtoNameToKey: { [key: string]: uint } = {} -let protoIndex: uint = 0 - - -function getProtoKey(protoName: string): uint { - if (mapProtoNameToKey[protoName] == undefined) { - mapProtoNameToKey[protoName] = protoIndex++ - } - return mapProtoNameToKey[protoName] -} - - function mapTilesUpdateDebounce( surface: LuaSurface | undefined, chunkPosition: MapChunkPosition, @@ -47,27 +34,31 @@ function mapTilesUpdateDebounce( key, Type.MapChunkUpdate, data => { - data.tileDictionary ??= { + + // tile dictionary update + data.tileDictionary ??= { tilesXY: {}, protos: {}, } + let protosCount: uint = 0 for (const tile of tiles) { + data.tileDictionary.protos[tile.name] ??= protosCount++ + const protoKey = data.tileDictionary.protos[tile.name] const xString = `${tile.position.x}` const yString = `${tile.position.y}` - const protoKey = getProtoKey(tile.name) - - data.tileDictionary.protos[tile.name] = protoIndex data.tileDictionary.tilesXY[xString] ??= {} data.tileDictionary.tilesXY[xString][yString] = protoKey } + // events count update data.eventCounts ??= {} data.eventCounts[eventName] ??= 0 data.eventCounts[eventName]++ + // apply mutator if (updater != undefined) { updater(data) } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt index 7073785..ef2ec02 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt @@ -50,15 +50,17 @@ data class MapTileDictionary( val protoName = protosIndexToName[protoIndex] if (x != null && y != null && protoName != null) { add(MapTile(x, y, protoName)) + } else if (protoName == null) { + println("warning: no prototype name found for index:$protoIndex. $protosIndexToName") } } } } - /** The collection-index of a prototype in [MapTileDictionary.protos] */ + /** An arbitrary ID for a prototype in [MapTileDictionary.protos]. */ @Serializable @JvmInline - value class PrototypeKey(val index: Int) + value class PrototypeKey(private val index: Int) companion object { fun MapTileDictionary?.isNullOrEmpty(): Boolean { From f339333f76b1593e961f631d36a92dd8b0a7666b Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 20 Apr 2022 23:17:50 +0200 Subject: [PATCH 282/629] change Kafka admin id warehouse->kafkatorio --- .../adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt index 27f4a17..b0fbb20 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt @@ -16,7 +16,7 @@ object KafkatorioKafkaAdmin { Admin.create( mapOf( "bootstrap.servers" to "http://localhost:9092", - "client.id" to "warehouse.setup-admin", + "client.id" to "kafkatorio.setup-admin", ) ) From b81e62e2fd49c2959f23287eb7217dddcf5a037d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 23 Apr 2022 17:59:37 +0200 Subject: [PATCH 283/629] enable gradle build cache, and improve tasks --- buildSrc/build.gradle.kts | 14 +++- .../adamko/kafkatorio/gradle/extensions.kt | 67 ++++++------------- .../kafkatorio/lang/kotlin-jvm.gradle.kts | 25 ++++--- .../adamko/kafkatorio/lang/node.gradle.kts | 55 +++++++-------- .../kafkatorio/task/DockerComposeExec.kt | 63 +++++++++++++++++ .../task/JsonPropertiesUpToDateSpec.kt | 46 +++++++++++++ .../kafkatorio/task/ProcessRunningSpec.kt | 38 +++++++++++ .../kafkatorio/task/TypescriptToLuaTask.kt | 22 +++++- .../kafkatorio/task/UpdatePackageJson.kt | 46 +++++++++++++ gradle.properties | 6 ++ modules/events-mod/build.gradle.kts | 24 +++---- .../src/main/typescript/package.json | 12 ++-- modules/events-schema/build.gradle.kts | 12 ++-- .../processor/topology/groupMapChunks.kt | 66 ++---------------- .../infra-factorio-client/build.gradle.kts | 4 +- modules/infra-kafka-pipe/build.gradle.kts | 29 ++++---- settings.gradle.kts | 1 - 17 files changed, 330 insertions(+), 200 deletions(-) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerComposeExec.kt create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 0bb56bd..cbac159 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -3,7 +3,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { idea `kotlin-dsl` - kotlin("jvm") version "1.6.10" + kotlin("jvm") version "1.6.21" `project-report` } @@ -15,7 +15,7 @@ object Versions { const val kotlin = "1.6.21" const val gradleNodePlugin = "3.2.1" - const val gradleDockerComposePlugin = "0.15.1" + const val gradleDockerComposePlugin = "0.15.2" const val kotlinXSerialization = "1.3.2" const val kvision = "5.8.2" @@ -31,6 +31,7 @@ dependencies { implementation(enforcedPlatform("org.jetbrains.kotlin:kotlin-bom:${Versions.kotlin}")) implementation("org.jetbrains.kotlin:kotlin-serialization") implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}") implementation(platform("org.jetbrains.kotlinx:kotlinx-serialization-bom:${Versions.kotlinXSerialization}")) @@ -60,7 +61,14 @@ dependencies { } -tasks.withType().configureEach { +//tasks.compileKotlin { +// kotlinOptions { +// // needed by IntelliJ? Even though below does the same? +// languageVersion = "1.6" +// } +//} + +tasks.withType().all { kotlinOptions { jvmTarget = Versions.jvmTarget diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt index 7bc9b86..71a85d1 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt @@ -1,60 +1,30 @@ package dev.adamko.kafkatorio.gradle -import dev.adamko.kafkatorio.jsonMapper import java.io.ByteArrayOutputStream -import kotlinx.serialization.json.jsonObject -import kotlinx.serialization.json.jsonPrimitive import org.gradle.api.Project -import org.gradle.api.Task +import org.gradle.api.file.Directory import org.gradle.api.file.ProjectLayout -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.MapProperty +import org.gradle.api.specs.NotSpec import org.gradle.api.specs.Spec -import org.gradle.kotlin.dsl.invoke import org.gradle.plugins.ide.idea.model.IdeaModule import org.gradle.process.ExecSpec import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension - import org.jetbrains.kotlin.gradle.targets.js.yarn.yarn - -operator fun Spec.not(): Spec = Spec { !this(it) } +import org.jetbrains.kotlin.incremental.md5 -fun Project.isProcessRunning(process: String, ignoreCase: Boolean = true): Spec = - Spec { - ByteArrayOutputStream().use { outputStream -> - project.exec { - commandLine("tasklist") // Windows only for now... - standardOutput = outputStream - } - outputStream.toString() - .contains(process, ignoreCase) - } - } - - -fun Project.areJsonPropertiesUpToDate( - packageJsonFile: RegularFileProperty, - properties: MapProperty -): Spec = Spec { - val packageJsonContent = packageJsonFile.get().asFile.readText() - val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject - - properties.get().all { (key, expectedVal) -> - val actualVal = packageJson[key]?.jsonPrimitive?.content - val isUpToDate = expectedVal == actualVal - - if (isUpToDate) { - logger.info("package.json property is up to date, '$key = $actualVal'") - } else { - logger.lifecycle( - "package.json has outdated property '$key' (expected: $expectedVal, actual: $actualVal)" - ) - } - - isUpToDate - } -} +operator fun Spec.not(): NotSpec = NotSpec(this) +// +// +//fun isProcessRunning(process: String, ignoreCase: Boolean = true): Spec = +// Spec { +// ByteArrayOutputStream().use { outputStream -> +// project.exec { +// } +// outputStream.toString().contains(process, ignoreCase) +// } +// } +// /** exclude generated Gradle code, so it doesn't clog up search results */ @@ -91,3 +61,10 @@ fun Project.execCapture(spec: ExecSpec.() -> Unit): String { /** https://youtrack.jetbrains.com/issue/KT-50848 */ fun Project.yarn(configure: YarnRootExtension.() -> Unit) = with(yarn, configure) + + +fun Directory.filesChecksum() = asFileTree + .files + .map { it.readBytes() + it.absolutePath.toByteArray() } + .fold(byteArrayOf()) { acc, bytes -> acc + bytes } + .md5() diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index a888607..216378c 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -8,12 +8,6 @@ plugins { kotlin("jvm") } -kotlin { - jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(Versions.jvmTarget)) - } -} - dependencies { implementation(platform("org.jetbrains.kotlin:kotlin-bom")) @@ -40,22 +34,27 @@ tasks.withType().configureEach { jvmTarget = Versions.jvmTarget apiVersion = Versions.kotlinLang languageVersion = Versions.kotlinLang - } - - kotlinOptions.freeCompilerArgs += listOf( + freeCompilerArgs += listOf( // "-Xcontext-receivers", - "-opt-in=kotlin.RequiresOptIn", - "-opt-in=kotlin.ExperimentalStdlibApi", - "-opt-in=kotlin.time.ExperimentalTime", + "-opt-in=kotlin.RequiresOptIn", + "-opt-in=kotlin.ExperimentalStdlibApi", + "-opt-in=kotlin.time.ExperimentalTime", // "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", // "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", - ) + ) + } } tasks.compileTestKotlin { kotlinOptions.freeCompilerArgs += "-opt-in=io.kotest.common.ExperimentalKotest" } +kotlin { + jvmToolchain { + (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(Versions.jvmTarget)) + } +} + tasks.withType { useJUnitPlatform() } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts index 577b83c..4a309db 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts @@ -1,17 +1,8 @@ package dev.adamko.kafkatorio.lang -import com.github.gradle.node.NodePlugin import com.github.gradle.node.npm.task.NpmInstallTask import dev.adamko.kafkatorio.Versions -import dev.adamko.kafkatorio.gradle.areJsonPropertiesUpToDate -import dev.adamko.kafkatorio.jsonMapper import dev.adamko.kafkatorio.task.UpdatePackageJson -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.JsonPrimitive -import kotlinx.serialization.json.jsonObject -import org.gradle.kotlin.dsl.support.useToRun -import org.jetbrains.kotlin.util.suffixIfNot plugins { id("com.github.node-gradle.node") @@ -26,34 +17,34 @@ node { } val updatePackageJson by tasks.registering(UpdatePackageJson::class) { - group = NodePlugin.NODE_GROUP - description = "Read the package.json file and update the version and name, based on the project." +// group = NodePlugin.NODE_GROUP +// description = "Read the package.json file and update the version and name, based on the project." - propertiesToCheck.put("version", "${project.version}") + propertiesToCheck.put("version", providers.provider { "${project.version}" }) // check to see if the properties are already up-to-date - outputs.upToDateWhen(areJsonPropertiesUpToDate(packageJsonFile, propertiesToCheck)) +// outputs.upToDateWhen(areJsonPropertiesUpToDate(packageJsonFile, propertiesToCheck)) // onlyIf(!areJsonPropertiesUpToDate(packageJsonFile, propertiesToCheck)) - doLast { - val packageJsonContent = packageJsonFile.get().asFile.readText() - val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject - - val newJsonProps = propertiesToCheck.get().mapValues { (_, newVal) -> JsonPrimitive(newVal) } - - val packageJsonUpdate = JsonObject(packageJson + newJsonProps) - val packageJsonContentUpdated = - jsonMapper - .encodeToString(packageJsonUpdate) - .suffixIfNot("\n") - - logger.debug(packageJsonContentUpdated) - - packageJsonFile.get().asFile.writer().useToRun { - write(packageJsonContentUpdated) - } - - } +// doLast { +// val packageJsonContent = packageJsonFile.get().asFile.readText() +// val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject +// +// val newJsonProps = propertiesToCheck.get().mapValues { (_, newVal) -> JsonPrimitive(newVal) } +// +// val packageJsonUpdate = JsonObject(packageJson + newJsonProps) +// val packageJsonContentUpdated = +// jsonMapper +// .encodeToString(packageJsonUpdate) +// .suffixIfNot("\n") +// +// logger.debug(packageJsonContentUpdated) +// +// packageJsonFile.get().asFile.writer().useToRun { +// write(packageJsonContentUpdated) +// } +// +// } } tasks.assemble { dependsOn(updatePackageJson) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerComposeExec.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerComposeExec.kt new file mode 100644 index 0000000..e451896 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerComposeExec.kt @@ -0,0 +1,63 @@ +package dev.adamko.kafkatorio.task + +import dev.adamko.kafkatorio.gradle.filesChecksum +import javax.inject.Inject +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.logging.LogLevel +import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.Property +import org.gradle.api.tasks.CacheableTask +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.api.tasks.SkipWhenEmpty +import org.gradle.api.tasks.TaskAction +import org.gradle.process.ExecOperations +import org.gradle.work.Incremental +import org.gradle.work.NormalizeLineEndings +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + +@CacheableTask +abstract class DockerComposeExec @Inject constructor( + private val executor: ExecOperations, + private val objectFactory: ObjectFactory, +) : DefaultTask() { + + @get:InputDirectory + @get:SkipWhenEmpty + @get:PathSensitive(PathSensitivity.RELATIVE) + @get:NormalizeLineEndings + abstract val dockerComposeDir: DirectoryProperty + + @get:Input + abstract val command: Property + + @get:OutputFile + val stateFile: RegularFileProperty = objectFactory.fileProperty().convention { + temporaryDir.resolve("docker-files.md5") + } + + init { + group = DOCKER_COMPOSE_GROUP + logging.captureStandardOutput(LogLevel.LIFECYCLE) + } + + @TaskAction + fun exec() { + executor.exec { + workingDir = dockerComposeDir.asFile.get() + commandLine = parseSpaceSeparatedArgs(command.get()) + } + + val inputChecksum = dockerComposeDir.get().filesChecksum() + stateFile.get().asFile.writeText("$inputChecksum") + } + + companion object { + const val DOCKER_COMPOSE_GROUP: String = "docker-compose" + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt new file mode 100644 index 0000000..ea4c13d --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt @@ -0,0 +1,46 @@ +package dev.adamko.kafkatorio.task + +import dev.adamko.kafkatorio.jsonMapper +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive +import org.gradle.api.Task +import org.gradle.api.internal.specs.ExplainingSpec + +object JsonPropertiesUpToDateSpec : ExplainingSpec { + + override fun isSatisfiedBy(element: Task?): Boolean = whyUnsatisfied(element) == null + + + // Returns a description explaining why the task is outdated, + // or null if the task is up to date + override fun whyUnsatisfied(element: Task?): String? = with(element) { + when (this) { + null -> "task is null" + + !is UpdatePackageJson -> + "task ${this::class.simpleName} is not instance of ${UpdatePackageJson::class.simpleName}" + + else -> { + + val packageJsonContent = packageJsonFile.get().asFile.readText() + val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject + + val outdatedProperties = propertiesToCheck.get().mapNotNull { (key, expectedVal) -> + val actualVal = packageJson[key]?.jsonPrimitive?.content + when { + expectedVal == actualVal -> null + else -> "'$key' (expected: $expectedVal, actual: $actualVal)" + } + } + + when { + outdatedProperties.isEmpty() -> null + outdatedProperties.size == 1 -> + "package.json has outdated property: ${outdatedProperties.single()}" + else -> + "package.json has outdated properties: ${outdatedProperties.joinToString(", ")}" + } + } + } + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt new file mode 100644 index 0000000..5b95510 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt @@ -0,0 +1,38 @@ +package dev.adamko.kafkatorio.task + +import java.io.ByteArrayOutputStream +import org.gradle.api.Task +import org.gradle.api.internal.specs.ExplainingSpec +import org.gradle.api.tasks.Exec + +/** Checks if a process is running. Windows only. */ +class ProcessRunningSpec( + private val process: String, + private val ignoreCase: Boolean = true, +) : ExplainingSpec { + + override fun isSatisfiedBy(element: Task?): Boolean = whyUnsatisfied(element) == null + + override fun whyUnsatisfied(element: Task?): String? = with(element) { + + when (this) { + null -> "task is null" + !is Exec -> "task ${this::class.simpleName} is not ${Exec::class.simpleName}" + else -> { + return ByteArrayOutputStream().use { outputStream -> + + project.exec { + commandLine("tasklist") // Windows only for now... + standardOutput = outputStream + } + + if (outputStream.toString().contains(process, ignoreCase)) { + "found $process in tasklist" + } else { + null + } + } + } + } + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt index bd42a41..e98ddf6 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt @@ -1,28 +1,35 @@ package dev.adamko.kafkatorio.task import com.github.gradle.node.npm.task.NpmTask +import javax.inject.Inject import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.FileSystemOperations import org.gradle.api.plugins.BasePlugin +import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.PathSensitive import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.SkipWhenEmpty +import org.gradle.api.tasks.TaskAction +import org.gradle.work.Incremental import org.gradle.work.NormalizeLineEndings import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs +@CacheableTask abstract class TypescriptToLuaTask : NpmTask() { @get:InputDirectory @get:SkipWhenEmpty @get:PathSensitive(PathSensitivity.RELATIVE) - @Suppress("UnstableApiUsage") @get:NormalizeLineEndings abstract val sourceFiles: DirectoryProperty @get:OutputDirectory abstract val outputDirectory: DirectoryProperty + @get:Inject + abstract val fs: FileSystemOperations init { super.setGroup(BasePlugin.BUILD_GROUP) @@ -33,4 +40,17 @@ abstract class TypescriptToLuaTask : NpmTask() { super.args.set(parseSpaceSeparatedArgs("-- --outDir $temporaryDir")) } + @TaskAction + fun tstl() { + fs.delete { delete(temporaryDir) } + temporaryDir.mkdirs() + + super.exec() + + fs.sync { + from(temporaryDir) + into(outputDirectory) + } + } + } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt index 5843ed1..418bfdd 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt @@ -1,11 +1,24 @@ package dev.adamko.kafkatorio.task +import com.github.gradle.node.NodePlugin +import dev.adamko.kafkatorio.jsonMapper +import javax.inject.Inject +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.jsonObject import org.gradle.api.DefaultTask import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.MapProperty +import org.gradle.api.provider.ProviderFactory +import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction +import org.gradle.kotlin.dsl.support.useToRun +import org.jetbrains.kotlin.util.suffixIfNot +@CacheableTask abstract class UpdatePackageJson : DefaultTask() { @get:Input @@ -14,10 +27,43 @@ abstract class UpdatePackageJson : DefaultTask() { @get:OutputFile abstract val packageJsonFile: RegularFileProperty + @get:Inject + abstract val providers: ProviderFactory +// +// @get:Inject +// abstract val fs: FileSystemOperations + init { + group = NodePlugin.NODE_GROUP + description = "Read the package.json file and update the version and name, based on the project." + + outputs.upToDateWhen(JsonPropertiesUpToDateSpec) + super.doFirst { propertiesToCheck.disallowChanges() packageJsonFile.disallowChanges() } } + + @TaskAction + fun exec() { + val pj = packageJsonFile.asFile.get() + + logger.info("updating package.json ${pj.canonicalPath}") + val packageJson = jsonMapper.parseToJsonElement(pj.readText()).jsonObject + + val newJsonProps = propertiesToCheck.get().mapValues { (_, newVal) -> JsonPrimitive(newVal) } + + val packageJsonUpdate = JsonObject(packageJson + newJsonProps) + val packageJsonContentUpdated = + jsonMapper + .encodeToString(packageJsonUpdate) + .suffixIfNot("\n") + + logger.debug(packageJsonContentUpdated) + + packageJsonFile.get().asFile.writer().useToRun { + write(packageJsonContentUpdated) + } + } } diff --git a/gradle.properties b/gradle.properties index a46318c..ffa83bb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,3 +3,9 @@ kotlin.mpp.stability.nowarn=true #kotlin.mpp.enableGranularSourceSetsMetadata=true #kotlin.native.enableDependencyPropagation=false org.gradle.dependency.verification.console=verbose + +org.gradle.caching=true +org.gradle.unsafe.configuration-cache=true +org.gradle.unsafe.configuration-cache-problems=warn + +org.gradle.kotlin.dsl.precompiled.accessors.strict=true diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 660658c..3c7eee1 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -39,6 +39,7 @@ projectTokens += mapOf( val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") + node { nodeProjectDir.set(tsSrcDir) } @@ -49,28 +50,20 @@ val typescriptEventsSchema: Configuration by configurations.creating { typescriptAttributes(objects) } + dependencies { typescriptEventsSchema(projects.modules.eventsSchema) } + val typescriptToLua by tasks.registering(TypescriptToLuaTask::class) { dependsOn(tasks.npmInstall, installEventsTsSchema, tasks.updatePackageJson) sourceFiles.set(tsSrcDir) outputDirectory.set(layout.buildDirectory.dir("typescriptToLua")) - - doFirst("cleanTemporaryDir") { - delete(temporaryDir) - mkdir(temporaryDir) - } - doLast("syncTstlOutput") { - sync { - from(temporaryDir) - into(outputDirectory) - } - } } + val installEventsTsSchema by tasks.registering(Sync::class) { description = "Fetch the latest shared data-model" group = project.name @@ -100,10 +93,13 @@ val installEventsTsSchema by tasks.registering(Sync::class) { into(outputDir) } + tasks.distZip { - archiveFileName.set(distributionZipName) + archiveFileName.set(provider { distributionZipName }) + } + distributions { main { @@ -165,11 +161,13 @@ val factorioModProvider by configurations.registering { outgoing.artifact(tasks.distZip.flatMap { it.archiveFile }) } + tasks.updatePackageJson { - propertiesToCheck.put("name", "${rootProject.name}-${project.name}") + propertiesToCheck.put("name", providers.provider { "${rootProject.name}-${project.name}" }) packageJsonFile.set(layout.projectDirectory.file("src/main/typescript/package.json")) } + tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) } diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index dc5d159..ea7c2fb 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -9,8 +9,7 @@ "engines": { "node": "~14.19.1" }, - "devDependencies": { - }, + "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", "typescript-to-lua": "1.4.3", @@ -19,10 +18,7 @@ }, "// @types/node": "^12.0.8", "license": "UNLICENSED", - "peerDependencies": { - }, - "optionalDependencies": { - }, - "bundledDependencies": [ - ] + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] } diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index d1d16e8..4e784c9 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -1,6 +1,5 @@ import dev.adamko.kafkatorio.gradle.asProvider import dev.adamko.kafkatorio.gradle.typescriptAttributes -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -111,11 +110,16 @@ kotlin { val generateTypescript by tasks.registering(JavaExec::class) { group = "kt2ts" - val jvmJar by tasks.getting(Jar::class) - val main by kotlin.jvm().compilations.getting + val jvmJar = tasks.named(kotlin.jvm().artifactsTaskName) + dependsOn(jvmJar) + + val mainCompilation = kotlin.jvm().compilations.named("main").map { it.runtimeDependencyFiles } +// dependsOn(mainCompilation) + inputs.files(mainCompilation) + classpath( jvmJar, - main.runtimeDependencyFiles + mainCompilation ) // mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2tsKt") diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt index 9ac4fff..0cb62d3 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt @@ -13,6 +13,7 @@ import dev.adamko.kafkatorio.schema.common.toMapChunkPosition import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import dev.adamko.kotka.extensions.groupedAs +import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.streams.filter @@ -158,74 +159,15 @@ private fun groupTilesIntoChunksWithColours( kxsBinary.serde>(), ) ) { chunkTiles, other -> chunkTiles + other } -// .toStream("server-map-data.tiles.repartition.to-stream") -// .repartition( -// repartitionedAs( -// "server-map-data.tiles.repartition.config", -// kxsBinary.serde(), -// kxsBinary.serde?>(), -// 3, -// ) -// ).toTable( -// "server-map-data.tiles.repartition.to-table", -// materializedWith( -// kxsBinary.serde(), -// kxsBinary.serde?>(), -// ) -// ) -// .filter("server-map-data.tiles.repartition.filter-not-null") { _: ServerMapChunkId, v: ServerMapChunkTiles? -> -// v != null -// } -// .mapValues( -// "server-map-data.tiles.repartition.map-not-null", -// materializedWith( -// kxsBinary.serde(), -// kxsBinary.serde>(), -// ) -// ) { _: ServerMapChunkId, v: ServerMapChunkTiles? -> -// v as ServerMapChunkTiles -// } - - - // repartition to try and fix KTable-KTable joining skipping records - val tileProtoColourDictRepartitioned = - tileProtoColourDict -// .toStream("tileProtoColourDict.repartition.to-stream") -// .repartition( -// repartitionedAs( -// "tileProtoColourDict.repartition.config", -// kxsBinary.serde(), -// kxsBinary.serde(), -// 3, -// ) -// ).toTable( -// "tileProtoColourDict.repartition.to-table", -// materializedWith( -// kxsBinary.serde(), -// kxsBinary.serde(), -// ) -// ) -// .filter("tileProtoColourDict.repartition.filter-not-null") { _: FactorioServerId, v: TileColourDict? -> -// v != null -// } -// .mapValues( -// "tileProtoColourDict.repartition.map-not-null", -// materializedWith( -// kxsBinary.serde(), -// kxsBinary.serde(), -// ) -// ) { _: FactorioServerId, v: TileColourDict? -> -// v as TileColourDict -// } val colourisedChunkTable: KTable> = chunkedTilesTable .join( - other = tileProtoColourDictRepartitioned, + other = tileProtoColourDict, tableJoined = tableJoined("server-map-data.join-tiles-with-prototypes"), - materialized = materializedWith( -// "server-map-data.join-tiles-with-prototypes.store", + materialized = materializedAs( + "server-map-data.join-tiles-with-prototypes.store", kxsBinary.serde(), kxsBinary.serde>(), ), diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index ba5d671..c92ee46 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -1,7 +1,7 @@ import dev.adamko.kafkatorio.gradle.asConsumer import dev.adamko.kafkatorio.gradle.factorioModAttributes -import dev.adamko.kafkatorio.gradle.isProcessRunning import dev.adamko.kafkatorio.gradle.not +import dev.adamko.kafkatorio.task.ProcessRunningSpec import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { @@ -38,7 +38,7 @@ val deployModToClient by tasks.registering(Copy::class) { // // -fun isFactorioRunning(): Spec = isProcessRunning("factorio.exe") +fun isFactorioRunning(): Spec = ProcessRunningSpec("factorio.exe") val clientLaunch by tasks.registering(Exec::class) { description = "Run Factorio Steam game client" diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index 8566525..77b8da2 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -1,4 +1,3 @@ -import org.jetbrains.kotlin.incremental.md5 import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { @@ -9,35 +8,32 @@ description = "Send events from a Factorio server to a Kafka topic " val dockerSrcDir: Directory by extra -fun Directory.filesChecksum() = asFileTree - .files - .map { it.readBytes() + it.absolutePath.toByteArray() } - .fold(byteArrayOf()) { acc, bytes -> acc + bytes } - .md5() tasks.dockerUp { dependsOn(":modules:infra-kafka-cluster:dockerUp") } -val dockerBuildKafkaPipe by tasks.registering(Exec::class) { - group = "docker-compose" - logging.captureStandardOutput(LogLevel.LIFECYCLE) +@Suppress("UnstableApiUsage") // normalizeLineEndings is incubating +val dockerBuildKafkaPipe by tasks.registering(dev.adamko.kafkatorio.task.DockerComposeExec::class) { dependsOn(tasks.dockerEnv) - inputs.dir(dockerSrcDir) - inputs.property("dockerSrcDirChecksum") { dockerSrcDir.filesChecksum() } + dockerComposeDir.set(dockerSrcDir) + command.set("docker-compose build kafka-pipe") - outputs.upToDateWhen { - it.inputs.properties["dockerSrcDirChecksum"] as? Long? == dockerSrcDir.filesChecksum() - } + +// inputs.property("dockerSrcDirChecksum") { dockerSrcDir.filesChecksum() } +// +// outputs.upToDateWhen { +// it.inputs.properties["dockerSrcDirChecksum"] as? Long? == dockerSrcDir.filesChecksum() +// } // val imageIdFile = file("$temporaryDir/docker-image-id.txt") // outputs.file(imageIdFile) - workingDir = dockerSrcDir.asFile - commandLine = parseSpaceSeparatedArgs(""" docker-compose build kafka-pipe """) +// workingDir = dockerSrcDir.asFile +// commandLine = parseSpaceSeparatedArgs(""" docker-compose build kafka-pipe """) // doLast { // sync { @@ -53,4 +49,5 @@ val dockerBuildKafkaPipe by tasks.registering(Exec::class) { // } //} } + tasks.assemble { dependsOn(dockerBuildKafkaPipe) } diff --git a/settings.gradle.kts b/settings.gradle.kts index 51dc0c9..8d88dea 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -18,7 +18,6 @@ include( ":modules:factorio-mod-portal-client", ) -enableFeaturePreview("VERSION_CATALOGS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") apply(from = "./buildSrc/repositories.settings.gradle.kts") From fea0d5bb97bef4b2949d9d70f80ffa906bf45bb1 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 23 Apr 2022 17:59:52 +0200 Subject: [PATCH 284/629] one more group map chunks test --- .../processor/topology/GroupMapChunksTest.kt | 2066 ++++++++++++++++- 1 file changed, 2057 insertions(+), 9 deletions(-) diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt index 7cf0bca..74e9329 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt @@ -12,6 +12,7 @@ import dev.adamko.kafkatorio.schema.common.MapTilePosition import dev.adamko.kafkatorio.schema.common.PrototypeName import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.Tick +import dev.adamko.kafkatorio.schema.common.toHex import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate import dev.adamko.kafkatorio.schema.packets.MapChunkUpdateKey @@ -20,10 +21,12 @@ import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype import dev.adamko.kotka.kxs.serde import io.kotest.assertions.withClue import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.collections.shouldContainAnyOf import io.kotest.matchers.collections.shouldHaveSize import io.kotest.matchers.equality.shouldBeEqualToComparingFields import io.kotest.matchers.nulls.shouldNotBeNull import io.kotest.matchers.should +import kotlinx.serialization.decodeFromString import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.TestInputTopic import org.apache.kafka.streams.TestOutputTopic @@ -66,6 +69,58 @@ class GroupMapChunksTest : FunSpec({ } } + test("raw actual JSON messages") { + + val scenario = Scenario() + + val prototypesPacket: KafkatorioPacket = jsonMapper.decodeFromString(rawPrototypesJson) + scenario.prototypesInputTopic.pipeInput(scenario.serverId, prototypesPacket) + + val mapChunkPacket: KafkatorioPacket = jsonMapper.decodeFromString(rawMapChunkUpdateJson) + scenario.mapChunkInputTopic.pipeInput(scenario.serverId, mapChunkPacket) + + val records = scenario.mapTilesOutputTopic.readRecordsToList() + + records shouldHaveSize 1 + + records.map { it.key to it.value }.first() should { (key, value) -> + key.shouldNotBeNull() + key shouldBeEqualToComparingFields ServerMapChunkId( + serverId = FactorioServerId("test-server-id"), + chunkPosition = MapChunkPosition(-1, -1), + surfaceIndex = SurfaceIndex(1u), + chunkSize = ChunkSize.CHUNK_512, + ) + value.shouldNotBeNull() + + value.chunkId shouldBeEqualToComparingFields key + + value.map.values.toSet().shouldContainAnyOf( + (prototypesPacket.data as PrototypesUpdate).prototypes + .filterIsInstance() + .map { + it.mapColour.toHex() + }.toSet() + ) + +// value shouldBeEqualToComparingFields ServerMapChunkTiles( +// chunkId = key, +// map = mapOf( +// MapTilePosition(x=-224, y=-224) to ColourHex(red=91u, green=63u, blue=38u, alpha=255u), +// MapTilePosition(x=-224, y=-223) to ColourHex(red=91u, green=63u, blue=38u, alpha=255u), +// MapTilePosition(x=-224, y=-222) to ColourHex(red=91u, green=63u, blue=38u, alpha=255u), +// MapTilePosition(x=-224, y=-221) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), +// MapTilePosition(x=-224, y=-220) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), +// MapTilePosition(x=-224, y=-219) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), +// MapTilePosition(x=-224, y=-218) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), +// MapTilePosition(x=-224, y=-217) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), +// MapTilePosition(x=-224, y=-216) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), +// MapTilePosition(x=-224, y=-215) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), +// ) +// ) + } + } + test("map chunk, then proto") { val scenario = Scenario() @@ -134,19 +189,19 @@ class GroupMapChunksTest : FunSpec({ prototypesTopicName: String = "kafkatorio.packet.prototypes", mapChunkUpdatesTopicName: String = "kafkatorio.packet.map-chunk", - private val serverId: FactorioServerId = FactorioServerId("test-server-id"), + val serverId: FactorioServerId = FactorioServerId("test-server-id"), ) { private val topology = groupMapChunks(streamsBuilder) private val testDriver: TopologyTestDriver = TopologyTestDriver(topology) - private val prototypesTestInputTopic: TestInputTopic = + val prototypesInputTopic: TestInputTopic = testDriver.createInputTopic( prototypesTopicName, jsonMapper.serde().serializer(), jsonMapper.serde().serializer(), ) - private val mapChunkUpdatesInputTopic: TestInputTopic = + val mapChunkInputTopic: TestInputTopic = testDriver.createInputTopic( mapChunkUpdatesTopicName, jsonMapper.serde().serializer(), @@ -155,13 +210,13 @@ class GroupMapChunksTest : FunSpec({ val mapTilesOutputTopic: TestOutputTopic> = testDriver.createOutputTopic( - TOPIC_GROUPED_MAP_CHUNKS_STATE, - kxsBinary.serde().deserializer(), - kxsBinary.serde>().deserializer(), - ) + TOPIC_GROUPED_MAP_CHUNKS_STATE, + kxsBinary.serde().deserializer(), + kxsBinary.serde>().deserializer(), + ) fun pipePrototypePacket(prototypeUpdate: PrototypesUpdate) { - prototypesTestInputTopic.pipeInput( + prototypesInputTopic.pipeInput( serverId, KafkatorioPacket( modVersion = "1.2.3", @@ -172,7 +227,7 @@ class GroupMapChunksTest : FunSpec({ } fun pipeMapChunkPacket(mapChunkUpdate: MapChunkUpdate) { - mapChunkUpdatesInputTopic.pipeInput( + mapChunkInputTopic.pipeInput( serverId, KafkatorioPacket( modVersion = "1.2.3", @@ -208,5 +263,1998 @@ class GroupMapChunksTest : FunSpec({ protos = mapOf(PrototypeName("fake-proto") to PrototypeKey(33)) ) ) + + const val rawMapChunkUpdateJson = """ + { + "modVersion": "0.4.0", + "tick": 36, + "data": { + "type": "dev.adamko.kafkatorio.schema.packets.MapChunkUpdate", + "key": { + "chunkPosition": [ + -7, + -7 + ], + "surfaceIndex": 1 + }, + "eventCounts": { + "on_chunk_generated": 1 + }, + "tileDictionary": { + "tilesXY": { + "-224": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 1, + "-220": 1, + "-219": 1, + "-218": 1, + "-217": 1, + "-216": 1, + "-215": 1, + "-214": 1, + "-213": 1, + "-212": 1, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 2, + "-206": 2, + "-205": 2, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-223": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 1, + "-218": 1, + "-217": 1, + "-216": 1, + "-215": 1, + "-214": 1, + "-213": 1, + "-212": 1, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 2, + "-206": 2, + "-205": 2, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-222": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 1, + "-217": 1, + "-216": 1, + "-215": 1, + "-214": 1, + "-213": 1, + "-212": 1, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 2, + "-206": 2, + "-205": 2, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-221": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 1, + "-216": 1, + "-215": 1, + "-214": 1, + "-213": 1, + "-212": 1, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 2, + "-206": 2, + "-205": 2, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 1 + }, + "-220": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 1, + "-215": 1, + "-214": 1, + "-213": 1, + "-212": 1, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 2, + "-205": 2, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-219": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 0, + "-213": 0, + "-212": 0, + "-211": 0, + "-210": 0, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 2, + "-205": 2, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-218": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 0, + "-213": 0, + "-212": 0, + "-211": 0, + "-210": 0, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 2, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-217": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 0, + "-213": 0, + "-212": 0, + "-211": 0, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-216": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 0, + "-213": 0, + "-212": 0, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-215": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 0, + "-213": 0, + "-212": 0, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-214": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 0, + "-213": 0, + "-212": 0, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 1, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-213": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 0, + "-213": 0, + "-212": 0, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 1, + "-203": 1, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 1 + }, + "-212": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 0, + "-213": 0, + "-212": 0, + "-211": 0, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 1, + "-203": 1, + "-202": 1, + "-201": 1, + "-200": 2, + "-199": 2, + "-198": 0, + "-197": 0, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 1 + }, + "-211": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 0, + "-213": 0, + "-212": 0, + "-211": 0, + "-210": 0, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 1, + "-203": 1, + "-202": 1, + "-201": 1, + "-200": 1, + "-199": 2, + "-198": 0, + "-197": 0, + "-196": 2, + "-195": 1, + "-194": 1, + "-193": 1 + }, + "-210": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 0, + "-213": 0, + "-212": 0, + "-211": 0, + "-210": 0, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 0, + "-205": 0, + "-204": 1, + "-203": 1, + "-202": 1, + "-201": 1, + "-200": 1, + "-199": 1, + "-198": 2, + "-197": 2, + "-196": 1, + "-195": 1, + "-194": 1, + "-193": 1 + }, + "-209": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 0, + "-213": 0, + "-212": 0, + "-211": 0, + "-210": 0, + "-209": 0, + "-208": 1, + "-207": 1, + "-206": 0, + "-205": 0, + "-204": 0, + "-203": 1, + "-202": 1, + "-201": 1, + "-200": 1, + "-199": 1, + "-198": 2, + "-197": 2, + "-196": 1, + "-195": 1, + "-194": 1, + "-193": 1 + }, + "-208": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 0, + "-213": 0, + "-212": 0, + "-211": 0, + "-210": 0, + "-209": 0, + "-208": 1, + "-207": 1, + "-206": 0, + "-205": 0, + "-204": 0, + "-203": 1, + "-202": 1, + "-201": 1, + "-200": 1, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 1, + "-195": 1, + "-194": 1, + "-193": 1 + }, + "-207": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 0, + "-213": 0, + "-212": 0, + "-211": 0, + "-210": 0, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 1, + "-203": 1, + "-202": 1, + "-201": 1, + "-200": 1, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 1, + "-195": 1, + "-194": 1, + "-193": 1 + }, + "-206": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 0, + "-213": 1, + "-212": 1, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 1, + "-203": 1, + "-202": 1, + "-201": 1, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 1, + "-196": 1, + "-195": 1, + "-194": 1, + "-193": 1 + }, + "-205": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 1, + "-213": 1, + "-212": 1, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 1, + "-203": 1, + "-202": 1, + "-201": 1, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 1, + "-196": 1, + "-195": 1, + "-194": 1, + "-193": 2 + }, + "-204": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 1, + "-215": 1, + "-214": 1, + "-213": 1, + "-212": 1, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 1, + "-203": 1, + "-202": 1, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 1, + "-196": 1, + "-195": 1, + "-194": 1, + "-193": 2 + }, + "-203": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 1, + "-216": 1, + "-215": 1, + "-214": 1, + "-213": 1, + "-212": 1, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 1, + "-203": 1, + "-202": 1, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 1, + "-194": 2, + "-193": 2 + }, + "-202": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 1, + "-216": 1, + "-215": 1, + "-214": 1, + "-213": 1, + "-212": 1, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 1, + "-203": 1, + "-202": 1, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-201": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 3, + "-217": 1, + "-216": 1, + "-215": 1, + "-214": 1, + "-213": 1, + "-212": 1, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 1, + "-203": 1, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-200": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 3, + "-218": 3, + "-217": 3, + "-216": 1, + "-215": 1, + "-214": 1, + "-213": 1, + "-212": 1, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 1, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-199": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 3, + "-218": 3, + "-217": 3, + "-216": 1, + "-215": 1, + "-214": 1, + "-213": 1, + "-212": 1, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-198": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 3, + "-218": 3, + "-217": 3, + "-216": 1, + "-215": 1, + "-214": 1, + "-213": 1, + "-212": 1, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 1, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-197": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 3, + "-218": 3, + "-217": 0, + "-216": 0, + "-215": 1, + "-214": 1, + "-213": 1, + "-212": 1, + "-211": 1, + "-210": 1, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 2, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-196": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 1, + "-214": 1, + "-213": 1, + "-212": 2, + "-211": 2, + "-210": 2, + "-209": 1, + "-208": 1, + "-207": 1, + "-206": 1, + "-205": 2, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-195": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 1, + "-213": 1, + "-212": 2, + "-211": 2, + "-210": 2, + "-209": 2, + "-208": 2, + "-207": 2, + "-206": 1, + "-205": 2, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-194": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 1, + "-213": 2, + "-212": 2, + "-211": 2, + "-210": 2, + "-209": 2, + "-208": 2, + "-207": 2, + "-206": 2, + "-205": 2, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + }, + "-193": { + "-224": 0, + "-223": 0, + "-222": 0, + "-221": 0, + "-220": 0, + "-219": 0, + "-218": 0, + "-217": 0, + "-216": 0, + "-215": 0, + "-214": 2, + "-213": 2, + "-212": 2, + "-211": 2, + "-210": 2, + "-209": 2, + "-208": 2, + "-207": 2, + "-206": 2, + "-205": 2, + "-204": 2, + "-203": 2, + "-202": 2, + "-201": 2, + "-200": 2, + "-199": 2, + "-198": 2, + "-197": 2, + "-196": 2, + "-195": 2, + "-194": 2, + "-193": 2 + } + }, + "protos": { + "dirt-5": 0, + "grass-2": 1, + "dirt-6": 2, + "red-desert-0": 3 + } + } + } + } + """ + + const val rawPrototypesJson = """ + { + "modVersion": "0.4.0", + "tick": 4352, + "data": { + "type": "dev.adamko.kafkatorio.schema.packets.PrototypesUpdate", + "prototypes": [ + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "stone-path", + "layer": 60, + "mapColour": [ + 86, + 82, + 74, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-a[tier-1]-a[stone-path]", + "canBeMined": true + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "concrete", + "layer": 61, + "mapColour": [ + 63, + 61, + 59, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-b[tier-2]-a[concrete]", + "canBeMined": true + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "hazard-concrete-left", + "layer": 62, + "mapColour": [ + 176, + 142, + 39, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-b[tier-2]-b[hazard-concrete-left]", + "canBeMined": true + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "hazard-concrete-right", + "layer": 62, + "mapColour": [ + 176, + 142, + 39, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-b[tier-2]-c[hazard-concrete-right]", + "canBeMined": true + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "refined-concrete", + "layer": 64, + "mapColour": [ + 49, + 48, + 45, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-c[tier-3]-a[refined-concrete]", + "canBeMined": true + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "refined-hazard-concrete-left", + "layer": 65, + "mapColour": [ + 116, + 94, + 26, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-c[tier-3]-b[refined-hazard-concrete-left]", + "canBeMined": true + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "refined-hazard-concrete-right", + "layer": 65, + "mapColour": [ + 116, + 94, + 26, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-c[tier-3]-c[refined-hazard-concrete-right]", + "canBeMined": true + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "landfill", + "layer": 57, + "mapColour": [ + 57, + 39, + 26, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-d[utility]-a[landfill]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "acid-refined-concrete", + "layer": 97, + "mapColour": [ + 142, + 194, + 40, + 127 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-e[color-concrete]-acid", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "black-refined-concrete", + "layer": 88, + "mapColour": [ + 25, + 25, + 25, + 127 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-e[color-concrete]-black", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "blue-refined-concrete", + "layer": 73, + "mapColour": [ + 39, + 137, + 228, + 127 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-e[color-concrete]-blue", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "brown-refined-concrete", + "layer": 91, + "mapColour": [ + 76, + 29, + 0, + 127 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-e[color-concrete]-brown", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "cyan-refined-concrete", + "layer": 94, + "mapColour": [ + 70, + 192, + 181, + 127 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-e[color-concrete]-cyan", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "green-refined-concrete", + "layer": 70, + "mapColour": [ + 23, + 195, + 43, + 127 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-e[color-concrete]-green", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "orange-refined-concrete", + "layer": 76, + "mapColour": [ + 221, + 127, + 33, + 127 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-e[color-concrete]-orange", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "pink-refined-concrete", + "layer": 82, + "mapColour": [ + 236, + 98, + 131, + 127 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-e[color-concrete]-pink", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "purple-refined-concrete", + "layer": 85, + "mapColour": [ + 123, + 28, + 168, + 127 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-e[color-concrete]-purple", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "red-refined-concrete", + "layer": 67, + "mapColour": [ + 207, + 6, + 0, + 127 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-e[color-concrete]-red", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "yellow-refined-concrete", + "layer": 79, + "mapColour": [ + 212, + 169, + 19, + 127 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "a[artificial]-e[color-concrete]-yellow", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "grass-1", + "layer": 26, + "mapColour": [ + 55, + 53, + 11, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-a[grass]-a[grass-1]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "grass-2", + "layer": 28, + "mapColour": [ + 66, + 57, + 15, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-a[grass]-b[grass-2]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "grass-3", + "layer": 29, + "mapColour": [ + 65, + 52, + 28, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-a[grass]-c[grass-3]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "grass-4", + "layer": 30, + "mapColour": [ + 59, + 40, + 18, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-a[grass]-d[grass-4]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "dry-dirt", + "layer": 18, + "mapColour": [ + 94, + 66, + 37, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-b[dirt]-a[dry-dirt]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "dirt-1", + "layer": 19, + "mapColour": [ + 141, + 104, + 60, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-b[dirt]-b[dirt-1]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "dirt-2", + "layer": 20, + "mapColour": [ + 136, + 96, + 59, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-b[dirt]-c[dirt-2]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "dirt-3", + "layer": 21, + "mapColour": [ + 133, + 92, + 53, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-b[dirt]-d[dirt-3]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "dirt-4", + "layer": 22, + "mapColour": [ + 103, + 72, + 43, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-b[dirt]-e[dirt-4]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "dirt-5", + "layer": 23, + "mapColour": [ + 91, + 63, + 38, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-b[dirt]-f[dirt-5]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "dirt-6", + "layer": 24, + "mapColour": [ + 80, + 55, + 31, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-b[dirt]-g[dirt-6]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "dirt-7", + "layer": 25, + "mapColour": [ + 80, + 54, + 28, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-b[dirt]-h[dirt-7]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "sand-1", + "layer": 8, + "mapColour": [ + 138, + 103, + 58, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-c[sand]-a[sand-1]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "sand-2", + "layer": 9, + "mapColour": [ + 128, + 93, + 52, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-c[sand]-b[sand-2]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "sand-3", + "layer": 10, + "mapColour": [ + 115, + 83, + 47, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-c[sand]-c[sand-3]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "red-desert-0", + "layer": 31, + "mapColour": [ + 103, + 70, + 32, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-d[red-desert]-a[red-desert-0]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "red-desert-1", + "layer": 14, + "mapColour": [ + 116, + 81, + 39, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-d[red-desert]-b[red-desert-1]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "red-desert-2", + "layer": 15, + "mapColour": [ + 116, + 84, + 43, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-d[red-desert]-c[red-desert-2]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "red-desert-3", + "layer": 16, + "mapColour": [ + 128, + 93, + 52, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "b[natural]-d[red-desert]-d[red-desert-3]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "water", + "layer": 3, + "mapColour": [ + 51, + 83, + 95, + 255 + ], + "collisionMasks": [ + "doodad-layer", + "item-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "order": "c[water]-a[water]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "deepwater", + "layer": 3, + "mapColour": [ + 38, + 64, + 73, + 255 + ], + "collisionMasks": [ + "doodad-layer", + "item-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "order": "c[water]-b[deep-water]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "water-green", + "layer": 3, + "mapColour": [ + 31, + 48, + 18, + 255 + ], + "collisionMasks": [ + "doodad-layer", + "item-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "order": "c[water]-c[water-green]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "deepwater-green", + "layer": 3, + "mapColour": [ + 23, + 37, + 16, + 255 + ], + "collisionMasks": [ + "doodad-layer", + "item-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "order": "c[water]-d[deepwater-green]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "water-shallow", + "layer": 6, + "mapColour": [ + 82, + 98, + 92, + 255 + ], + "collisionMasks": [ + "item-layer", + "object-layer", + "resource-layer", + "water-tile" + ], + "order": "c[water]-e[water-shallow]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "water-mud", + "layer": 7, + "mapColour": [ + 65, + 89, + 90, + 255 + ], + "collisionMasks": [ + "item-layer", + "object-layer", + "resource-layer", + "water-tile" + ], + "order": "c[water]-g[water-mud]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "nuclear-ground", + "layer": 33, + "mapColour": [ + 48, + 40, + 35, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "d[destruction]-a[nuclear]-a[nuclear-ground]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "water-wube", + "layer": 2, + "mapColour": [ + 0, + 0, + 0, + 255 + ], + "collisionMasks": [ + "doodad-layer", + "item-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "order": "x[wube]-a[water-wube]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "tile-unknown", + "layer": 0, + "mapColour": [ + 0, + 0, + 0, + 255 + ], + "collisionMasks": {}, + "order": "z-a", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "out-of-map", + "layer": 0, + "mapColour": [ + 0, + 0, + 0, + 255 + ], + "collisionMasks": [ + "doodad-layer", + "floor-layer", + "ground-tile", + "item-layer", + "object-layer", + "player-layer", + "resource-layer", + "water-tile" + ], + "order": "z[other]-a[out-of-map]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "lab-dark-1", + "layer": 70, + "mapColour": [ + 49, + 49, + 49, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "z[other]-b[lab]-a[lab-dark-1]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "lab-dark-2", + "layer": 70, + "mapColour": [ + 0, + 0, + 0, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "z[other]-b[lab]-b[lab-dark-2]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "lab-white", + "layer": 70, + "mapColour": [ + 255, + 255, + 255, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "z[other]-b[lab]-c[lab-white]", + "canBeMined": false + }, + { + "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "name": "tutorial-grid", + "layer": 55, + "mapColour": [ + 122, + 122, + 122, + 255 + ], + "collisionMasks": [ + "ground-tile" + ], + "order": "z[other]-c[tutorial]-a[tutorial-grid]", + "canBeMined": false + } + ] + } + } + """ } } From 2c383041b51095617c5fd41922d8c8b6e2fb8eef Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 23 Apr 2022 21:56:08 +0200 Subject: [PATCH 285/629] fix inverted check in ProcessRunningSpec --- .../kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt index 5b95510..46406a8 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt @@ -27,9 +27,9 @@ class ProcessRunningSpec( } if (outputStream.toString().contains(process, ignoreCase)) { - "found $process in tasklist" - } else { null + } else { + "found $process in tasklist" } } } From 0d81650400370afe9404700fa9834d4455209f64 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 23 Apr 2022 21:56:43 +0200 Subject: [PATCH 286/629] save topology description to disk --- .../adamko/kafkatorio/processor/KafkatorioTopology.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 9aa4332..5f5b68f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -10,6 +10,7 @@ import java.time.Duration import java.util.Properties import kotlin.coroutines.CoroutineContext import kotlin.coroutines.cancellation.CancellationException +import kotlin.io.path.Path import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -92,10 +93,17 @@ internal class KafkatorioTopology( }) val description: TopologyDescription = topology.describe() + + val descFile = Path("./build/$appId.txt").toFile().apply { + parentFile.mkdirs() + if (!exists()) createNewFile() + writeText(description.toString()) + } + println( """ |---------------- - |$appId + |$appId - ${descFile.canonicalPath} |$description |---------------- """.trimMargin() From 7e497ffd59ad22de830e420a1346a01a8f722119 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 23 Apr 2022 21:57:46 +0200 Subject: [PATCH 287/629] setup grafana, prometheus, jmx --- .../infra/docker-compose.gradle.kts | 1 + gradle/libs.versions.toml | 2 + modules/infra-kafka-cluster/build.gradle.kts | 21 + modules/infra-kafka-cluster/src/.env | 3 + ...fana_dashboard_broker_hard_disk_usage.json | 378 ++++ .../grafana_dashboard_broker_jvm_os.json | 801 +++++++ .../grafana_dashboard_broker_performance.json | 1532 +++++++++++++ .../grafana_dashboard_broker_zookeeper.json | 688 ++++++ ..._dashboard_client_consumers_fetch_lag.json | 492 +++++ ...grafana_dashboard_cluster_healthcheck.json | 1887 +++++++++++++++++ ...grafana_dashboard_cluster_replication.json | 574 +++++ .../grafana_dashboard_topics_logs.json | 876 ++++++++ .../provisioning/dashboards/kafka.yaml | 12 + .../provisioning/datasources/datasource.yaml | 50 + .../src/config/jmx_exporter_kafka_broker.yml | 505 +++++ .../src/config/prometheus.yml | 29 + .../src/docker-compose.yml | 49 + 17 files changed, 7900 insertions(+) create mode 100644 modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_broker_hard_disk_usage.json create mode 100644 modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_broker_jvm_os.json create mode 100644 modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_broker_performance.json create mode 100644 modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_broker_zookeeper.json create mode 100644 modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_client_consumers_fetch_lag.json create mode 100644 modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_cluster_healthcheck.json create mode 100644 modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_cluster_replication.json create mode 100644 modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_topics_logs.json create mode 100644 modules/infra-kafka-cluster/src/config/grafana/provisioning/dashboards/kafka.yaml create mode 100644 modules/infra-kafka-cluster/src/config/grafana/provisioning/datasources/datasource.yaml create mode 100644 modules/infra-kafka-cluster/src/config/jmx_exporter_kafka_broker.yml create mode 100644 modules/infra-kafka-cluster/src/config/prometheus.yml diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts index 520fa83..7bb535a 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts @@ -53,6 +53,7 @@ val dockerEnv by tasks.registering(WriteProperties::class) { logging.captureStandardOutput(LogLevel.LIFECYCLE) setOutputFile(dockerSrcDir.file(".env")) + properties( "COMPOSE_PROJECT_NAME" to dockerComposeProjectName, "KAFKATORIO_VERSION" to project.version, diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ce36119..ad0931d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,6 +29,8 @@ kotest = "5.2.3" ## infra ## factorio = "1.1.57" confluent-kafkaConnect = "7.0.1" +grafana = "8.5.0" +prometheus = "v2.34.0" ######### [plugins] diff --git a/modules/infra-kafka-cluster/build.gradle.kts b/modules/infra-kafka-cluster/build.gradle.kts index 35b7263..8f52b7e 100644 --- a/modules/infra-kafka-cluster/build.gradle.kts +++ b/modules/infra-kafka-cluster/build.gradle.kts @@ -3,3 +3,24 @@ plugins { } description = "Kafka cluster" + +tasks.dockerEnv { + properties( + "GRAFANA_VERSION" to libs.versions.grafana, + "PROMETHEUS_VERSION" to libs.versions.prometheus, + "KAFKA_VERSION" to libs.versions.kafka, + + // Limit JVM Heap Size +// "KAFKA_BROKER_HEAP_OPTS" to "-XX:MaxRAMPercentage=70.0", +// "KAFKA_CONNECT_HEAP_OPTS" to "-XX:MaxRAMPercentage=70.0", +// "SCHEMA_REGISTRY_HEAP_OPTS" to "-XX:MaxRAMPercentage=70.0", +// "KAFKA_KSQL_HEAP_OPTS" to "-XX:MaxRAMPercentage=70.0", +// "PROMETHEUS_JMX_AGENT_JVM_OPTS" to "-Xmx128M", + +// // Limit container resources +// "KAFKA_BROKER_MEM_LIMIT" to "512m", +// "KAFKA_CONNECT_MEM_LIMIT" to "512m", +// "KAFKA_KSQL_MEM_LIMIT" to "256m", +// "SCHEMA_REGISTRY_MEM_LIMIT" to "256m", + ) +} diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index 469b75e..bb45ded 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,3 +1,6 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio +GRAFANA_VERSION=8.5.0 KAFKATORIO_VERSION=0.4.0 +KAFKA_VERSION=3.1.0 +PROMETHEUS_VERSION=v2.34.0 diff --git a/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_broker_hard_disk_usage.json b/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_broker_hard_disk_usage.json new file mode 100644 index 0000000..0ff0182 --- /dev/null +++ b/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_broker_hard_disk_usage.json @@ -0,0 +1,378 @@ +{ + "__inputs": [ + { + "name": "Prometheus", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "5.2.1" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "5.0.0" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "5.0.0" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "iteration": 1540328526402, + "links": [], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(kafka_log_size{env=\"$env\"}) by (topic)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{topic}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Global Topics Size (including replicas)", + "tooltip": { + "shared": true, + "sort": 1, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 5, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(sum(kafka_log_size{env=\"$env\"}) by (topic, partition) / sum(kafka_cluster_partition_replicascount{env=\"$env\"}) by(partition, topic)) by (topic)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{topic}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Global Topics Size (without replication)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 3, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(kafka_log_size{env=\"$env\"}) by (instance)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Logs Size Per Broker (including replicas)", + "tooltip": { + "shared": true, + "sort": 1, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "5s", + "schemaVersion": 16, + "style": "dark", + "tags": [ + "kafka", + "topics", + "disk" + ], + "templating": { + "list": [ + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "hide": 0, + "includeAll": false, + "label": "Env", + "multi": false, + "name": "env", + "options": [], + "query": "label_values(kafka_log_size, env)", + "refresh": 1, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Kafka / Hard Disk Usage", + "uid": "zApgMBbik", + "version": 1 +} \ No newline at end of file diff --git a/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_broker_jvm_os.json b/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_broker_jvm_os.json new file mode 100644 index 0000000..8fad773 --- /dev/null +++ b/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_broker_jvm_os.json @@ -0,0 +1,801 @@ +{ + "__inputs": [ + { + "name": "prometheus", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "5.2.1" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "5.0.0" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "5.0.0" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Java Virtual Machine Memory and OS metrics", + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "iteration": 1540307470986, + "links": [], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 7, + "x": 0, + "y": 0 + }, + "id": 8, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_jvm_non_heap_usage{env=\"$env\", type=\"used\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}} ", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "JVM Memory Used (Non-Heap)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 7, + "y": 0 + }, + "id": 6, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_jvm_heap_usage{env=\"$env\", type=\"used\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "JVM Memory Used (Heap)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 9, + "x": 15, + "y": 0 + }, + "id": 10, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_jvm_gc_collection_time{env=\"$env\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}} / {{name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "GC Process Time", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 5, + "w": 12, + "x": 0, + "y": 7 + }, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_jvm_os_systemcpuload{env=\"$env\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "CPU", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 5, + "w": 12, + "x": 12, + "y": 7 + }, + "id": 11, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_jvm_os_processcpuload{env=\"$env\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Process CPU", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 5, + "w": 12, + "x": 0, + "y": 12 + }, + "id": 2, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_jvm_os_openfiledescriptorcount{env=\"$env\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Open File Descriptors", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "The amount of free physical memory in bytes.", + "fill": 1, + "gridPos": { + "h": 5, + "w": 6, + "x": 12, + "y": 12 + }, + "id": 13, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_jvm_os_freephysicalmemorysize{env=\"$env\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Free Physical Memory", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "The amount of virtual memory that is guaranteed to be available to the running process in bytes", + "fill": 1, + "gridPos": { + "h": 5, + "w": 6, + "x": 18, + "y": 12 + }, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_jvm_os_committedvirtualmemorysize{env=\"$env\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Available Virtual Memory", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "decimals": null, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "5s", + "schemaVersion": 16, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "hide": 0, + "includeAll": false, + "label": "Env", + "multi": false, + "name": "env", + "options": [], + "query": "label_values(kafka_jvm_os_openfiledescriptorcount, env)", + "refresh": 1, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Kafka / Brokers JVM & OS", + "uid": "AdG9A1xmk", + "version": 3 +} \ No newline at end of file diff --git a/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_broker_performance.json b/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_broker_performance.json new file mode 100644 index 0000000..fd95efb --- /dev/null +++ b/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_broker_performance.json @@ -0,0 +1,1532 @@ +{ + "__inputs": [ + { + "name": "Prometheus", + "label": "prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "5.2.1" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "5.0.0" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "5.0.0" + }, + { + "type": "panel", + "id": "singlestat", + "name": "Singlestat", + "version": "5.0.0" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "iteration": 1532113327583, + "links": [], + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 17, + "panels": [], + "repeat": "instance", + "title": "Request Latency : $request ($instance)", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 8, + "w": 15, + "x": 0, + "y": 1 + }, + "id": 1, + "isNew": true, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"Mean\", scope=~\"Total\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{ aggregate}}", + "refId": "A", + "step": 10 + }, + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"99thPercentile\", scope=~\"Total\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{ aggregate}}", + "refId": "B", + "step": 10 + }, + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"75thPercentile\", scope=~\"Total\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{ aggregate}}", + "refId": "C", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Request Total Time Ms", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "decimals": null, + "editable": true, + "error": false, + "format": "percentunit", + "gauge": { + "maxValue": 1, + "minValue": 0, + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 15, + "y": 1 + }, + "id": 16, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "kafka_network_socket_server_processor_avg_idle_percent{instance=~\"$instance\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 60 + } + ], + "thresholds": "0.3,0.5,0.8", + "title": "Network Socket Avg Idle Percent", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "decimals": null, + "editable": true, + "error": false, + "format": "percentunit", + "gauge": { + "maxValue": 1, + "minValue": 0, + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 18, + "y": 1 + }, + "id": 15, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "kafka_server_request_handler_avg_idle_percent{instance=~\"$instance\", aggregate=~\"OneMinuteRate\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 60 + } + ], + "thresholds": "0.3,0.5,0.8", + "title": "Request Handler Avg Idle Percent", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "editable": true, + "error": false, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 21, + "y": 1 + }, + "id": 12, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "kafka_network_request_per_sec{aggregate=~\"OneMinuteRate\",instance=~\"$instance\",request=~\"$request\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "metric": "", + "refId": "A", + "step": 60 + } + ], + "thresholds": "", + "title": "Requests Per Sec", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "editable": true, + "error": false, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 15, + "y": 5 + }, + "id": 10, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "kafka_network_request_channel_queue_size{instance=~\"$instance\", queue=~\"Response\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}}", + "metric": "", + "refId": "A", + "step": 60 + } + ], + "thresholds": "0,50,1000", + "title": "Response Queue Size", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "editable": true, + "error": false, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 18, + "y": 5 + }, + "id": 9, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "kafka_network_request_channel_queue_size{instance=~\"$instance\", queue=~\"Request\", env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}}", + "metric": "", + "refId": "A", + "step": 60 + } + ], + "thresholds": "0,50,1000", + "title": "Request Queue Size", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 9 + }, + "id": 2, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"Mean\", scope=~\"RequestQueue\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "A", + "step": 10 + }, + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"75thPercentile\", scope=~\"RequestQueue\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "B", + "step": 10 + }, + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"99thPercentile\", scope=~\"RequestQueue\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "C", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Request Queue Time(Ms)", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 9 + }, + "id": 3, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"Mean\", scope=~\"Local\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "A", + "step": 10 + }, + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"75thPercentile\", scope=~\"Local\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "B", + "step": 10 + }, + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"99thPercentile\", scope=~\"Local\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "C", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Local Time(Ms)", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 9 + }, + "id": 4, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"Mean\", scope=~\"Remote\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "A", + "step": 10 + }, + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"75thPercentile\", scope=~\"Remote\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "B", + "step": 10 + }, + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"99thPercentile\", scope=~\"Remote\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "C", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Remote Time(Ms)", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 16 + }, + "id": 5, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"Mean\", scope=~\"Throttle\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "A", + "step": 10 + }, + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"75thPercentile\", scope=~\"Throttle\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "B", + "step": 10 + }, + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"99thPercentile\", scope=~\"Throttle\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "C", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Throttle Time(Ms)", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 16 + }, + "id": 6, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"Mean\", scope=~\"ResponseQueue\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "A", + "step": 10 + }, + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"75thPercentile\", scope=~\"ResponseQueue\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "B", + "step": 10 + }, + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"99thPercentile\", scope=~\"ResponseQueue\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "C", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Response Queue Time(Ms)", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 16 + }, + "id": 7, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"Mean\", scope=~\"ResponseSend\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "A", + "step": 10 + }, + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"75thPercentile\", scope=~\"ResponseSend\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "B", + "step": 10 + }, + { + "expr": "kafka_network_request_metrics_time_ms{instance=~\"$instance\", request=~\"$request\", aggregate=~\"99thPercentile\", scope=~\"ResponseSend\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}} / {{aggregate}}", + "refId": "C", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Response Send Time(Ms)", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 23 + }, + "id": 8, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_network_processor_idle_percent{instance=~\"$instance\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{processor}}", + "metric": "kafka_network_processor_idle_percent", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Network Processor Idle Percent", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": "", + "logBase": 1, + "max": 1, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 23 + }, + "id": 14, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_server_request_handler_avg_idle_percent{instance=~\"$instance\", aggregate=~\"OneMinuteRate\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{processor}}", + "metric": "kafka_network_processor_idle_percent", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Request Handler Avg Idle Percent", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": "", + "logBase": 1, + "max": 1, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "5s", + "schemaVersion": 16, + "style": "dark", + "tags": [ + "kafka", + "broker", + "troubleshoot" + ], + "templating": { + "list": [ + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "hide": 0, + "includeAll": false, + "label": "Envrionment", + "multi": false, + "name": "env", + "options": [], + "query": "label_values(kafka_server_brokerstate, env)", + "refresh": 1, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "hide": 0, + "includeAll": true, + "label": "Broker Host", + "multi": true, + "name": "instance", + "options": [], + "query": "label_values(kafka_network_request_metrics_time_ms{env=\"$env\"}, instance)", + "refresh": 1, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "hide": 0, + "includeAll": false, + "label": "Request Type", + "multi": false, + "name": "request", + "options": [], + "query": "label_values(kafka_network_request_metrics_time_ms, request)", + "refresh": 1, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "browser", + "title": "Kafka Broker / Performance & Latency", + "uid": "aRNaJwOmk", + "version": 8 +} diff --git a/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_broker_zookeeper.json b/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_broker_zookeeper.json new file mode 100644 index 0000000..156b989 --- /dev/null +++ b/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_broker_zookeeper.json @@ -0,0 +1,688 @@ +{ + "__inputs": [ + { + "name": "Prometheus", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "5.2.1" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "5.0.0" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "5.0.0" + }, + { + "type": "panel", + "id": "text", + "name": "Text", + "version": "5.0.0" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "iteration": 1539721769054, + "links": [], + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 8, + "panels": [], + "title": "Kafka/Zookeeper Session Expire Listener", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 1 + }, + "id": 1, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_zookeeper_session_expire_listener_zookeepersyncconnectspersec{aggregate=\"OneMinute\", env=\"$env\"}", + "intervalFactor": 2, + "legendFormat": "{{instance}}", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Zookeeper Sync Connects Per Sec", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 1 + }, + "id": 2, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_zookeeper_session_expire_listener_zookeeperdisconnectspersec{env=\"$env\", aggregate=\"OneMinute\"}", + "intervalFactor": 2, + "legendFormat": "{{instance}}", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Zookeeper Disconnects Per Sec", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "content": "The ZooKeeper session has expired. **When a session expires, we can have leader changes and even a new controller.**\n\nIt is important to keep an eye on the number of such events across a Kafka cluster and if the overall number is high, then we have a few recommendations:\n\n* Check the health of your network\n* Check for garbage collection issues and tune it accordingly\n * If necessary, increase the session time out by setting the value of zookeeper.connection.timeout.ms.\n\nDocumentation : [monitoring.html#zookeeper-metrics](http://docs.confluent.io/current/kafka/monitoring.html#zookeeper-metrics)\n", + "editable": true, + "error": false, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 1 + }, + "id": 7, + "isNew": true, + "links": [], + "mode": "markdown", + "title": "The ZooKeeper session has expired ?", + "transparent": true, + "type": "text" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 5, + "w": 8, + "x": 0, + "y": 8 + }, + "id": 4, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_zookeeper_session_expire_listener_zookeeperreadonlyconnectspersec{env=\"$env\", aggregate=\"OneMinute\"}", + "intervalFactor": 2, + "legendFormat": "{{instance}}", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Zookeeper Read Only Connects Per Sec", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 5, + "w": 8, + "x": 8, + "y": 8 + }, + "id": 3, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_zookeeper_session_expire_listener_zookeeperexpirespersec{env=\"$env\", aggregate=\"OneMinute\"}", + "intervalFactor": 2, + "legendFormat": "{{instance}}", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Zookeeper Expires Per Sec", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 5, + "w": 8, + "x": 0, + "y": 13 + }, + "id": 6, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_zookeeper_session_expire_listener_zookeeperauthfailurespersec{env=\"$env\", aggregate=\"OneMinute\"}", + "intervalFactor": 2, + "legendFormat": "{{instance}}", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Zookeeper SASL Authentications Per Sec", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 5, + "w": 8, + "x": 8, + "y": 13 + }, + "id": 5, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_zookeeper_session_expire_listener_zookeeperauthfailurespersec{env=\"$env\", aggregate=\"OneMinute\"}", + "intervalFactor": 2, + "legendFormat": "{{instance}}", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Zookeeper Auth Failures Per Sec", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "5s", + "schemaVersion": 16, + "style": "dark", + "tags": [ + "kafka", + "zookeeper" + ], + "templating": { + "list": [ + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "hide": 0, + "includeAll": false, + "label": "Env", + "multi": false, + "name": "env", + "options": [], + "query": "label_values(kafka_server_brokerstate, env)", + "refresh": 1, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "browser", + "title": "Kafka Broker / Zookeeper Connection", + "uid": "142Xi34mk", + "version": 1 +} \ No newline at end of file diff --git a/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_client_consumers_fetch_lag.json b/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_client_consumers_fetch_lag.json new file mode 100644 index 0000000..a6703b4 --- /dev/null +++ b/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_client_consumers_fetch_lag.json @@ -0,0 +1,492 @@ +{ + "__inputs": [ + { + "name": "Prometheus", + "label": "prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "5.2.1" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "5.0.0" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "5.0.0" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "", + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "iteration": 1532113236152, + "links": [], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "The latest lag of each client", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 8, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(kafka_consumer_fetch_manager_metrics_records_lag{env=\"$env\", topic=\"$topic\"}) by(topic, client_id, instance)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{client_id}} ({{instance}})", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Consumer Client Lag", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "The average number of bytes fetched per request for a topic", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 10, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_consumer_fetch_manager_metrics_fetch_size_avg{env=\"$env\", topic=\"$topic\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{client_id}} ({{instance}})", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Fetch Bytes Per Request", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "decbytes", + "label": "", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "The average number of bytes consumed per second", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 6 + }, + "id": 3, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_consumer_fetch_manager_metrics_bytes_consumed_rate{env=\"$env\", topic=\"$topic\"}", + "format": "time_series", + "hide": false, + "instant": false, + "intervalFactor": 1, + "legendFormat": "{{client_id}} ({{instance}})", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Consumed Bytes Rate Per Second", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "The average number of records consumed per second", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 6 + }, + "id": 2, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_consumer_fetch_manager_metrics_records_consumed_rate{env=\"$env\", topic=\"$topic\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{client_id}} ({{instance}})", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Consumed Records Rate Per Second", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "rps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "5s", + "schemaVersion": 16, + "style": "dark", + "tags": [ + "kafka", + "clients" + ], + "templating": { + "list": [ + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "hide": 0, + "includeAll": false, + "label": "env", + "multi": false, + "name": "env", + "options": [], + "query": "label_values(kafka_consumer_fetch_manager_metrics_records_consumed_rate, env)", + "refresh": 1, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "hide": 0, + "includeAll": false, + "label": "topic", + "multi": false, + "name": "topic", + "options": [], + "query": "label_values(kafka_consumer_fetch_manager_metrics_records_consumed_rate, topic)", + "refresh": 1, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "browser", + "title": "Kafka Consumers / Fetch Rate & Records Lag", + "uid": "Ni95Y3dmz", + "version": 20 +} diff --git a/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_cluster_healthcheck.json b/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_cluster_healthcheck.json new file mode 100644 index 0000000..78cae0d --- /dev/null +++ b/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_cluster_healthcheck.json @@ -0,0 +1,1887 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "iteration": 1540310392981, + "links": [], + "panels": [ + { + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 29, + "title": "Healthcheck", + "type": "row" + }, + { + "cacheTimeout": null, + "colorBackground": true, + "colorValue": false, + "colors": [ + "#d44a3a", + "rgba(237, 129, 40, 0.89)", + "#299c46" + ], + "datasource": "Prometheus", + "description": "Number of active controllers in the cluster. Alert if the aggregated sum across all brokers in the cluster is anything other than 1 because there should be exactly one controller per cluster.", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 0, + "y": 1 + }, + "id": 31, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kafka_controller_activecontrollercount{env=\"$env\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "0,1", + "title": "Active Controller", + "type": "singlestat", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "description": "Number of partitions that don’t have an active leader and are hence not writable or readable. Alert if value is greater than 0.", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 3, + "y": 1 + }, + "id": 32, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kafka_controller_offlinepartitionscount{env=\"$env\"})", + "format": "time_series", + "instant": false, + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "1,1", + "title": "Offline Partitions Count", + "type": "singlestat", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "description": "Number of under-replicated partitions (| ISR | < | all replicas |). Alert if value is greater than 0.", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 7, + "y": 1 + }, + "id": 33, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kafka_server_replica_manager_underreplicatedpartitions{env=\"$env\"})", + "format": "time_series", + "instant": false, + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "1,1", + "title": "Under Replicated Partitions", + "type": "singlestat", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "description": "Number of under-replicated partitions (| ISR | < | min.insync.replicas |). Alert if value is greater than 0.", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 11, + "y": 1 + }, + "id": 36, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kafka_cluster_partition_underminisr{env=\"$env\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "1,1", + "title": "Partitions Under Min ISR", + "type": "singlestat", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "description": "", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 15, + "y": 1 + }, + "id": 34, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kafka_controller_preferredreplicaimbalancecount{env=\"$env\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "1,1", + "title": "Preferred Replica Imbalance", + "type": "singlestat", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "content": "\"Apache\n\n

+* [[Prototype/Achievement]] '''achievement''' +** [[Prototype/BuildEntityAchievement]] '''build-entity-achievement''' +** [[Prototype/CombatRobotCountAchievement]] '''combat-robot-count''' +** [[Prototype/ConstructWithRobotsAchievement]] '''construct-with-robots-achievement''' +** [[Prototype/DeconstructWithRobotsAchievement]] '''deconstruct-with-robots-achievement''' +** [[Prototype/DeliverByRobotsAchievement]] '''deliver-by-robots-achievement''' +** [[Prototype/DontBuildEntityAchievement]] '''dont-build-entity-achievement''' +** [[Prototype/DontCraftManuallyAchievement]] '''dont-craft-manually-achievement''' +** [[Prototype/DontUseEntityInEnergyProductionAchievement]] '''dont-use-entity-in-energy-production-achievement''' +** [[Prototype/FinishTheGameAchievement]] '''finish-the-game-achievement''' +** [[Prototype/GroupAttackAchievement]] '''group-attack-achievement''' +** [[Prototype/KillAchievement]] '''kill-achievement''' +** [[Prototype/PlayerDamagedAchievement]] '''player-damaged-achievement''' +** [[Prototype/ProduceAchievement]] '''produce-achievement''' +** [[Prototype/ProducePerHourAchievement]] '''produce-per-hour-achievement''' +** [[Prototype/ResearchAchievement]] '''research-achievement''' +** [[Prototype/TrainPathAchievement]] '''train-path-achievement''' +* [[Prototype/AmmoCategory]] '''ammo-category''' +* [[Prototype/AutoplaceControl]] '''autoplace-control''' +* [[Prototype/CustomInput]] '''custom-input''' +* [[Prototype/DamageType]] '''damage-type''' +* [[Prototype/Decorative]] '''optimized-decorative''' +* [[Prototype/Entity]] +** [[Prototype/Arrow]] '''arrow''' +** [[Prototype/ArtilleryFlare]] '''artillery-flare''' +** [[Prototype/ArtilleryProjectile]] '''artillery-projectile''' +** [[Prototype/Beam]] '''beam''' +** [[Prototype/CharacterCorpse]] '''character-corpse''' +** [[Prototype/Cliff]] '''cliff''' +** [[Prototype/Corpse]] '''corpse''' +*** [[Prototype/RailRemnants]] '''rail-remnants''' +** [[Prototype/DeconstructibleTileProxy]] '''deconstructible-tile-proxy''' +** [[Prototype/EntityGhost]] '''entity-ghost''' +** [[Prototype/EntityParticle]] '''particle''' (for migration, cannot be used) +*** [[Prototype/LeafParticle]] '''leaf-particle''' (for migration, cannot be used) +** [[Prototype/EntityWithHealth]] +*** [[Prototype/EntityWithOwner]] +**** [[Prototype/Accumulator]] '''accumulator''' +**** [[Prototype/ArtilleryTurret]] '''artillery-turret''' +**** [[Prototype/Beacon]] '''beacon''' +**** [[Prototype/Boiler]] '''boiler''' +**** [[Prototype/BurnerGenerator]] '''burner-generator''' +**** [[Prototype/Character]] '''character''' +**** [[Prototype/Combinator]] +***** [[Prototype/ArithmeticCombinator]] '''arithmetic-combinator''' +***** [[Prototype/DeciderCombinator]] '''decider-combinator''' +**** [[Prototype/ConstantCombinator]] '''constant-combinator''' +**** [[Prototype/Container]] '''container''' +***** [[Prototype/LogisticContainer]] '''logistic-container''' +****** [[Prototype/InfinityContainer]] '''infinity-container''' +**** [[Prototype/CraftingMachine]] +***** [[Prototype/AssemblingMachine]] '''assembling-machine''' +****** [[Prototype/RocketSilo]] '''rocket-silo''' +***** [[Prototype/Furnace]] '''furnace''' +**** [[Prototype/ElectricEnergyInterface]] '''electric-energy-interface''' +**** [[Prototype/ElectricPole]] '''electric-pole''' +**** [[Prototype/EnemySpawner]] '''unit-spawner''' +**** [[Prototype/FlyingRobot]] +***** [[Prototype/CombatRobot]] '''combat-robot''' +***** [[Prototype/RobotWithLogisticInterface]] +****** [[Prototype/ConstructionRobot]] '''construction-robot''' +****** [[Prototype/LogisticRobot]] '''logistic-robot''' +**** [[Prototype/Gate]] '''gate''' +**** [[Prototype/Generator]] '''generator''' +**** [[Prototype/HeatInterface]] '''heat-interface''' +**** [[Prototype/HeatPipe]] '''heat-pipe''' +**** [[Prototype/Inserter]] '''inserter''' +**** [[Prototype/Lab]] '''lab''' +**** [[Prototype/Lamp]] '''lamp''' +**** [[Prototype/LandMine]] '''land-mine''' +**** [[Prototype/LinkedContainer]] '''linked-container''' +**** [[Prototype/Market]] '''market''' +**** [[Prototype/MiningDrill]] '''mining-drill''' +**** [[Prototype/OffshorePump]] '''offshore-pump''' +**** [[Prototype/Pipe]] '''pipe''' +***** [[Prototype/InfinityPipe]] '''infinity-pipe''' +**** [[Prototype/PipeToGround]] '''pipe-to-ground''' +**** [[Prototype/PlayerPort]] '''player-port''' +**** [[Prototype/PowerSwitch]] '''power-switch''' +**** [[Prototype/ProgrammableSpeaker]] '''programmable-speaker''' +**** [[Prototype/Pump]] '''pump''' +**** [[Prototype/Radar]] '''radar''' +**** [[Prototype/Rail]] +***** [[Prototype/CurvedRail]] '''curved-rail''' +***** [[Prototype/StraightRail]] '''straight-rail''' +**** [[Prototype/RailSignalBase]] +***** [[Prototype/RailChainSignal]] '''rail-chain-signal''' +***** [[Prototype/RailSignal]] '''rail-signal''' +**** [[Prototype/Reactor]] '''reactor''' +**** [[Prototype/Roboport]] '''roboport''' +**** [[Prototype/SimpleEntityWithOwner]] '''simple-entity-with-owner''' +***** [[Prototype/SimpleEntityWithForce]] '''simple-entity-with-force''' +**** [[Prototype/SolarPanel]] '''solar-panel''' +**** [[Prototype/StorageTank]] '''storage-tank''' +**** [[Prototype/TrainStop]] '''train-stop''' +**** [[Prototype/TransportBeltConnectable]] +***** [[Prototype/LinkedBelt]] '''linked-belt''' +***** [[Prototype/Loader1x1]] '''loader-1x1''' +***** [[Prototype/Loader1x2]] '''loader''' +***** [[Prototype/Splitter]] '''splitter''' +***** [[Prototype/TransportBelt]] '''transport-belt''' +***** [[Prototype/UndergroundBelt]] '''underground-belt''' +**** [[Prototype/Turret]] '''turret''' +***** [[Prototype/AmmoTurret]] '''ammo-turret''' +***** [[Prototype/ElectricTurret]] '''electric-turret''' +***** [[Prototype/FluidTurret]] '''fluid-turret''' +**** [[Prototype/Unit]] '''unit''' +**** [[Prototype/Vehicle]] +***** [[Prototype/Car]] '''car''' +***** [[Prototype/RollingStock]] +****** [[Prototype/ArtilleryWagon]] '''artillery-wagon''' +****** [[Prototype/CargoWagon]] '''cargo-wagon''' +****** [[Prototype/FluidWagon]] '''fluid-wagon''' +****** [[Prototype/Locomotive]] '''locomotive''' +***** [[Prototype/SpiderVehicle]] '''spider-vehicle''' +**** [[Prototype/Wall]] '''wall''' +*** [[Prototype/Fish]] '''fish''' +*** [[Prototype/SimpleEntity]] '''simple-entity''' +*** [[Prototype/SpiderLeg]] '''spider-leg''' +*** [[Prototype/Tree]] '''tree''' +** [[Prototype/Explosion]] '''explosion''' +*** [[Prototype/FlameThrowerExplosion]] '''flame-thrower-explosion''' +** [[Prototype/FireFlame]] '''fire''' +** [[Prototype/FluidStream]] '''stream''' +** [[Prototype/FlyingText]] '''flying-text''' +** [[Prototype/HighlightBoxEntity]] '''highlight-box''' +** [[Prototype/ItemEntity]] '''item-entity''' +** [[Prototype/ItemRequestProxy]] '''item-request-proxy''' +** [[Prototype/ParticleSource]] '''particle-source''' +** [[Prototype/Projectile]] '''projectile''' +** [[Prototype/ResourceEntity]] '''resource''' +** [[Prototype/RocketSiloRocket]] '''rocket-silo-rocket''' +** [[Prototype/RocketSiloRocketShadow]] '''rocket-silo-rocket-shadow''' +** [[Prototype/Smoke]] +*** [[Prototype/SimpleSmoke]] '''smoke''' (for migration, cannot be used) +*** [[Prototype/SmokeWithTrigger]] '''smoke-with-trigger''' +** [[Prototype/SpeechBubble]] '''speech-bubble''' +** [[Prototype/Sticker]] '''sticker''' +** [[Prototype/TileGhost]] '''tile-ghost''' +* [[Prototype/Equipment]] +** [[Prototype/ActiveDefenseEquipment]] '''active-defense-equipment''' +** [[Prototype/BatteryEquipment]] '''battery-equipment''' +** [[Prototype/BeltImmunityEquipment]] '''belt-immunity-equipment''' +** [[Prototype/EnergyShieldEquipment]] '''energy-shield-equipment''' +** [[Prototype/GeneratorEquipment]] '''generator-equipment''' +** [[Prototype/MovementBonusEquipment]] '''movement-bonus-equipment''' +** [[Prototype/NightVisionEquipment]] '''night-vision-equipment''' +** [[Prototype/RoboportEquipment]] '''roboport-equipment''' +** [[Prototype/SolarPanelEquipment]] '''solar-panel-equipment''' +* [[Prototype/EquipmentCategory]] '''equipment-category''' +* [[Prototype/EquipmentGrid]] '''equipment-grid''' +* [[Prototype/Fluid]] '''fluid''' +* [[Prototype/FuelCategory]] '''fuel-category''' +* [[Prototype/GuiStyle]] '''gui-style''' +* [[Prototype/Item]] '''item''' +** [[Prototype/AmmoItem]] '''ammo''' +** [[Prototype/Capsule]] '''capsule''' +** [[Prototype/Gun]] '''gun''' +** [[Prototype/ItemWithEntityData]] '''item-with-entity-data''' +** [[Prototype/ItemWithLabel]] '''item-with-label''' +*** [[Prototype/ItemWithInventory]] '''item-with-inventory''' +**** [[Prototype/BlueprintBook]] '''blueprint-book''' +*** [[Prototype/ItemWithTags]] '''item-with-tags''' +*** [[Prototype/SelectionTool]] '''selection-tool''' +**** [[Prototype/BlueprintItem]] '''blueprint''' +**** [[Prototype/CopyPasteTool]] '''copy-paste-tool''' +**** [[Prototype/DeconstructionItem]] '''deconstruction-item''' +**** [[Prototype/UpgradeItem]] '''upgrade-item''' +** [[Prototype/Module]] '''module''' +** [[Prototype/RailPlanner]] '''rail-planner''' +** [[Prototype/SpidertronRemote]] '''spidertron-remote''' +** [[Prototype/Tool]] '''tool''' +*** [[Prototype/Armor]] '''armor''' +*** [[Prototype/MiningTool]] '''mining-tool''' (for migration, cannot be used) +*** [[Prototype/RepairTool]] '''repair-tool''' +* [[Prototype/ItemGroup]] '''item-group''' +* [[Prototype/ItemSubGroup]] '''item-subgroup''' +* [[Prototype/ModuleCategory]] '''module-category''' +* [[Prototype/NamedNoiseExpression]] '''noise-expression''' +* [[Prototype/NoiseLayer]] '''noise-layer''' +* [[Prototype/Particle]] '''optimized-particle''' +* [[Prototype/Recipe]] '''recipe''' +* [[Prototype/RecipeCategory]] '''recipe-category''' +* [[Prototype/ResourceCategory]] '''resource-category''' +* [[Prototype/Shortcut]] '''shortcut''' +* [[Prototype/Technology]] '''technology''' +* [[Prototype/Tile]] '''tile''' +* [[Prototype/TipsAndTricksItem]] '''tips-and-tricks-item''' +* [[Prototype/TrivialSmoke]] '''trivial-smoke''' +* [[Prototype/Tutorial]] '''tutorial''' +* [[Prototype/UtilityConstants]] '''utility-constants''' +* [[Prototype/UtilitySounds]] '''utility-sounds''' +* [[Prototype/UtilitySprites]] '''utility-sprites''' +* [[Prototype/VirtualSignal]] '''virtual-signal''' + + */ diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt index d21a750..bec5bf3 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt @@ -6,16 +6,11 @@ import kotlinx.serialization.Serializable @Serializable @SerialName("kafkatorio.resource.MinedProduct") -data class MinedProduct( - /** `item` or `fluid`. */ - val type: Type, +sealed interface MinedProduct { - /** Prototype name of the result. */ - @SerialName("name") - val resultPrototype: PrototypeName, - -//Amount of the item or fluid to give. If not specified, amount_min, amount_max and probability must all be specified. - val amount: Double?, + val resultProtoId: PrototypeId + //Amount of the item or fluid to give. If not specified, amount_min, amount_max and probability must all be specified. + val amount: Double? //Minimal amount of the item or fluid to give. Has no effect when amount is specified. //amount_min : Uint or double?, @@ -26,17 +21,24 @@ data class MinedProduct( //A value in range [0, 1]. Item or fluid is only given with this probability; otherwise no product is produced. //probability : Double?, -//How much of this product is a catalyst. + //How much of this product is a catalyst. //catalyst_amount : Uint or double?, -) { + @Serializable - @SerialName("kafkatorio.resource.MinedProductType") - enum class Type { - @SerialName("item") - ITEM, - @SerialName("fluid") - FLUID, - } + @SerialName("kafkatorio.resource.MinedProduct.MinedProductFluid") + data class Fluid( + override val amount: Double? = null, + override val resultProtoId: PrototypeId, + ) : MinedProduct + + + @Serializable + @SerialName("kafkatorio.resource.MinedProduct.MinedProductItem") + data class Item( + override val amount: Double? = null, + override val resultProtoId: PrototypeId, + ) : MinedProduct + } diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt index 8d93b8a..748ac8b 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt @@ -4,12 +4,13 @@ import dev.adamko.kafkatorio.schema.common.Colour import dev.adamko.kafkatorio.schema.common.EntityIdentifiers import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData import dev.adamko.kafkatorio.schema.common.EventName +import dev.adamko.kafkatorio.schema.common.FactorioEntityData import dev.adamko.kafkatorio.schema.common.ForceIndex import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapEntityPosition import dev.adamko.kafkatorio.schema.common.MapTileDictionary import dev.adamko.kafkatorio.schema.common.PlayerIndex -import dev.adamko.kafkatorio.schema.common.PrototypeName +import dev.adamko.kafkatorio.schema.common.PrototypeId import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.common.UnitNumber @@ -23,6 +24,8 @@ import kotlinx.serialization.Serializable sealed class KafkatorioKeyedPacketData : KafkatorioPacketData() { abstract val key: KafkatorioKeyedPacketKey /** A list of all events that have been aggregated into this packet. */ + // Maybe change to be Map, where Tick is the most recent event? + // A complete event timeline isn't necessary. The most recent tick of an event is good enough, and requires less space. abstract val events: Map>? } @@ -40,8 +43,7 @@ sealed class KafkatorioKeyedPacketKey data class EntityUpdateKey( /** While normally optional, here a [unitNumber] is required for caching */ override val unitNumber: UnitNumber, - override val name: String, - override val protoType: String, + override val protoId: PrototypeId, ) : EntityIdentifiers, KafkatorioKeyedPacketKey() @@ -60,7 +62,6 @@ data class EntityUpdate( val lastUser: UInt? = null, val localisedDescription: String? = null, val localisedName: String? = null, - val prototype: PrototypeName? = null, ) : KafkatorioKeyedPacketData() @@ -68,17 +69,18 @@ data class EntityUpdate( @Serializable -@SerialName("kafkatorio.packet.keyed.MapChunkUpdateKey") -data class MapChunkUpdateKey( +@SerialName("kafkatorio.packet.keyed.MapChunkTileUpdateKey") +data class MapChunkTileUpdateKey( +// val index: PlayerIndex, // maybe add player/robot key, to allow metrics like 'player x mined y tiles' val chunkPosition: MapChunkPosition, val surfaceIndex: SurfaceIndex, ) : KafkatorioKeyedPacketKey() @Serializable -@SerialName("kafkatorio.packet.keyed.MapChunkUpdate") -data class MapChunkUpdate( - override val key: MapChunkUpdateKey, +@SerialName("kafkatorio.packet.keyed.MapChunkTileUpdate") +data class MapChunkTileUpdate( + override val key: MapChunkTileUpdateKey, override val events: Map>? = null, @@ -93,6 +95,7 @@ data class MapChunkUpdate( /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ + @Serializable @SerialName("kafkatorio.packet.keyed.PlayerUpdateKey") data class PlayerUpdateKey( @@ -134,4 +137,32 @@ data class PlayerUpdate( ) : KafkatorioKeyedPacketData() +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ + + +@Serializable +@SerialName("kafkatorio.packet.keyed.MapChunkEntityUpdateKey") +data class MapChunkEntityUpdateKey( + val protoId: PrototypeId, + val surfaceIndex: SurfaceIndex, + val chunkPosition: MapChunkPosition, +) : KafkatorioKeyedPacketKey() + + +/** + * @property[distinctEntities] Distinct entities. The key is arbitrary and is only used + * for de-duplicating updates. It should only contain data that can be obtained from + * [the value][FactorioEntityData]. + */ +@Serializable +@SerialName("kafkatorio.packet.keyed.MapChunkEntityUpdate") +data class MapChunkEntityUpdate( + override val key: MapChunkEntityUpdateKey, + + override val events: Map>? = null, + + val distinctEntities: Map? = null, +) : KafkatorioKeyedPacketData() + + /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt index 9a3aaf9..53c2b62 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt @@ -4,12 +4,12 @@ import dev.adamko.kafkatorio.library.jsonMapperKafkatorio import dev.adamko.kafkatorio.schema.common.EventName import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapTileDictionary -import dev.adamko.kafkatorio.schema.common.PrototypeName +import dev.adamko.kafkatorio.schema.common.PrototypeId import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.tick import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket -import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate -import dev.adamko.kafkatorio.schema.packets.MapChunkUpdateKey +import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate +import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdateKey import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import kotlinx.serialization.decodeFromString @@ -59,8 +59,8 @@ class MapChunkUpdateTest : FunSpec({ val expected = KafkatorioPacket( tick = 36u.tick, modVersion = "0.4.0", - data = MapChunkUpdate( - key = MapChunkUpdateKey( + data = MapChunkTileUpdate( + key = MapChunkTileUpdateKey( MapChunkPosition(-6, -3), SurfaceIndex(1u), ), @@ -78,9 +78,9 @@ class MapChunkUpdateTest : FunSpec({ ), ), protos = mapOf( - PrototypeName("water") to MapTileDictionary.PrototypeKey(1), - PrototypeName("grass-4") to MapTileDictionary.PrototypeKey(2), - PrototypeName("grass-3") to MapTileDictionary.PrototypeKey(32), + PrototypeId("tile", "water") to MapTileDictionary.PrototypeKey(1), + PrototypeId("tile", "grass-4") to MapTileDictionary.PrototypeKey(2), + PrototypeId("tile", "grass-3") to MapTileDictionary.PrototypeKey(32), ) ) ) diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt index 17387a2..022e939 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt @@ -3,7 +3,7 @@ package dev.adamko.kafkatorio.events.schema import dev.adamko.kafkatorio.library.jsonMapperKafkatorio import dev.adamko.kafkatorio.schema.common.Colour import dev.adamko.kafkatorio.schema.common.FactorioPrototype -import dev.adamko.kafkatorio.schema.common.PrototypeName +import dev.adamko.kafkatorio.schema.common.PrototypeId import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import io.kotest.core.spec.style.BehaviorSpec @@ -12,6 +12,7 @@ import io.kotest.matchers.shouldBe import io.kotest.matchers.types.shouldBeInstanceOf import kotlinx.serialization.decodeFromString + class PrototypesTest : BehaviorSpec({ Given("Prototypes Json") { // language=JSON @@ -669,7 +670,7 @@ class PrototypesTest : BehaviorSpec({ .prototypes .forOne { it.shouldBeInstanceOf() - it.name shouldBe PrototypeName("tutorial-grid") + it.protoId shouldBe PrototypeId.MapTile("tutorial-grid") it.order shouldBe "z[other]-c[tutorial]-a[tutorial-grid]" it.layer shouldBe 55u it.collisionMasks shouldBe listOf("ground-tile") diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt index b6249c6..b1f2e17 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt @@ -7,6 +7,7 @@ import dev.adamko.kafkatorio.schema.common.EventName import dev.adamko.kafkatorio.schema.common.ForceIndex import dev.adamko.kafkatorio.schema.common.MapEntityPosition import dev.adamko.kafkatorio.schema.common.PlayerIndex +import dev.adamko.kafkatorio.schema.common.PrototypeId import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.common.UnitNumber @@ -190,8 +191,7 @@ class UpdatePacketsTest : FunSpec({ colour = null, diedCause = EntityIdentifiersData( unitNumber = UnitNumber(66u), - name = "small-biter", - protoType = "unit", + protoId = PrototypeId("unit/small-biter"), ), disconnectReason = null, events = mapOf( diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt index 720c405..c611056 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt @@ -20,22 +20,22 @@ class MapTileDictionaryTest : FunSpec({ "44" to mapOf("1" to MapTileDictionary.PrototypeKey(44)), ), protos = mapOf( - PrototypeName("water") to MapTileDictionary.PrototypeKey(1), - PrototypeName("grass-4") to MapTileDictionary.PrototypeKey(2), - PrototypeName("grass-3") to MapTileDictionary.PrototypeKey(32), + PrototypeId.MapTile("water") to MapTileDictionary.PrototypeKey(1), + PrototypeId.MapTile("grass-4") to MapTileDictionary.PrototypeKey(2), + PrototypeId.MapTile("grass-3") to MapTileDictionary.PrototypeKey(32), - PrototypeName("not-used") to MapTileDictionary.PrototypeKey(99), + PrototypeId.MapTile("not-used") to MapTileDictionary.PrototypeKey(99), ) ) test("toMapTileList") { actual.toMapTileList() shouldContainAll listOf( - MapTile(-192, -65, PrototypeName("grass-4")), + MapTile(-192, -65, PrototypeId.MapTile("grass-4")), - MapTile(161, -96, PrototypeName("water")), - MapTile(161, -95, PrototypeName("grass-4")), - MapTile(161, 94, PrototypeName("grass-4")), - MapTile(161, 93, PrototypeName("grass-3")), + MapTile(161, -96, PrototypeId.MapTile("water")), + MapTile(161, -95, PrototypeId.MapTile("grass-4")), + MapTile(161, 94, PrototypeId.MapTile("grass-4")), + MapTile(161, 93, PrototypeId.MapTile("grass-3")), ) } } diff --git a/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt b/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt index 36b0972..69be148 100644 --- a/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt +++ b/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt @@ -1,11 +1,16 @@ package dev.adamko.kafkatorio.events.schema +import dev.adamko.kafkatorio.schema.common.PlayerIndex +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.common.UnitNumber import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kxstsgen.KxsTsConfig +import dev.adamko.kxstsgen.KxsTsConfig.TypeAliasTypingConfig.BrandTyping import dev.adamko.kxstsgen.KxsTsGenerator import dev.adamko.kxstsgen.core.TsDeclaration.TsTypeAlias import dev.adamko.kxstsgen.core.TsElementId import dev.adamko.kxstsgen.core.TsLiteral +import dev.adamko.kxstsgen.core.TsSourceCodeGenerator import dev.adamko.kxstsgen.core.TsTypeRef import kotlin.io.path.Path import kotlin.io.path.createDirectories @@ -13,14 +18,24 @@ import kotlinx.serialization.builtins.serializer import org.intellij.lang.annotations.Language -@ExperimentalUnsignedTypes fun main(args: Array) { val config = KxsTsConfig( -// typeAliasTyping = BrandTyping + typeAliasTyping = BrandTyping ) - val gen2 = KxsTsGenerator(config) + val gen2 = KxsTsGenerator( + config = config, + sourceCodeGenerator = MySourceCodeGenerator(config), + ) + +// gen2.serializerDescriptorOverrides += mapOf( +////@formatter:off +// SurfaceIndex.serializer() to emptySet(), +// PlayerIndex.serializer() to emptySet(), +// UnitNumber.serializer() to emptySet(), +////@formatter:on +// ) gen2.descriptorOverrides += mapOf( //@formatter:off @@ -32,6 +47,10 @@ fun main(args: Array) { UByte .serializer().descriptor to TsTypeAlias(TsElementId("kotlin.UByte" ), TsTypeRef.Literal(TsLiteral.Custom("uint8" ), false)), UShort.serializer().descriptor to TsTypeAlias(TsElementId("kotlin.UShort"), TsTypeRef.Literal(TsLiteral.Custom("uint16"), false)), ULong .serializer().descriptor to TsTypeAlias(TsElementId("kotlin.ULong" ), TsTypeRef.Literal(TsLiteral.Custom("uint64"), false)), + + PlayerIndex.serializer().descriptor to TsTypeAlias(TsElementId("PlayerIndex" ), TsTypeRef.Literal(TsLiteral.Custom("PlayerIndex"), false)), + SurfaceIndex.serializer().descriptor to TsTypeAlias(TsElementId("SurfaceIndex" ), TsTypeRef.Literal(TsLiteral.Custom("SurfaceIndex"), false)), + UnitNumber.serializer().descriptor to TsTypeAlias(TsElementId("UnitNumber" ), TsTypeRef.Literal(TsLiteral.Custom("UnitNumber"), false)), //@formatter:on ) @@ -60,3 +79,26 @@ val kt2tsHeader = """ |// Generated by kxs-ts-gen - do not edit this file manually | """.trimMargin() + + +class MySourceCodeGenerator( + config: KxsTsConfig, +) : TsSourceCodeGenerator.Default(config) { + + override fun generateTypeAlias(element: TsTypeAlias): String { + + return if (element.id.name in listOf("PlayerIndex", "SurfaceIndex", "UnitNumber")) { + "" + } else if ( + (element.typeRef as? TsTypeRef.Literal)?.element is TsLiteral.Custom + || element.id.name == "Tick" + ) { + val aliasedRef = generateTypeReference(element.typeRef) + """ + |export type ${element.id.name} = ${aliasedRef}; + """.trimMargin() + } else { + super.generateTypeAlias(element) + } + } +} diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 9380d84..e1d4cd7 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -101,7 +101,7 @@ val installEventsTsSchema by tasks.registering(Sync::class) { } ) { // drop the first directory inside the zip - eachFile { relativePath = dropDirectory() } +// eachFile { relativePath = dropDirectory() } includeEmptyDirs = false } into(outputDir) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index d3a6fbd..c81337c 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -75,9 +75,9 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.3.0.tgz", - "integrity": "sha512-qBHKjE+m9Im7vDhsGvl0uwaSFzJ5asqyfw414gF0owZwmSax2CIjdLx367qUgdD4flsB0n9HecBaZ0Yzt9zMPQ==" + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.3.2.tgz", + "integrity": "sha512-sAVIDvSSBPWL7trI94SPd2Suq9dLjXmXL1WFKJIYJpFQocNwJUb0ydGRBsvJjZhVAyEZYJC0lHlDWH47RWP/tw==" }, "typescript": { "version": "4.7.4", diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 41f214b..a0f189b 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -9,15 +9,19 @@ "engines": { "node": "~14.19.1" }, - "devDependencies": {}, + "devDependencies": { + }, "dependencies": { "lua-types": "^2.11.0", "typescript-to-lua": "1.6.1", - "typed-factorio": "1.3.0", + "typed-factorio": "1.3.2", "typescript": "4.7.4" }, "license": "UNLICENSED", - "peerDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": [] + "peerDependencies": { + }, + "optionalDependencies": { + }, + "bundledDependencies": [ + ] } diff --git a/modules/events-mod/src/generated/lua/control.lua b/modules/events-mod/src/generated/lua/control.lua index 0bd8e16..a2839ec 100644 --- a/modules/events-mod/src/generated/lua/control.lua +++ b/modules/events-mod/src/generated/lua/control.lua @@ -3,7 +3,7 @@ local ____global_2Dinit = require("main.global-init") local initGlobal = ____global_2Dinit.initGlobal local ____prototypeUpdates = require("main.events.prototypeUpdates") local emitPrototypes = ____prototypeUpdates.emitPrototypes -require("main.events.registerHandlers") +require("main.events.registerEventListeners") require("main.events.mapChunkUpdates") require("main.events.playerUpdates") require("main.events.entityUpdates") diff --git a/modules/events-mod/src/generated/lua/generated/kafkatorio-schema.lua b/modules/events-mod/src/generated/lua/generated/kafkatorio-schema.lua index 65df7de..46a4058 100644 --- a/modules/events-mod/src/generated/lua/generated/kafkatorio-schema.lua +++ b/modules/events-mod/src/generated/lua/generated/kafkatorio-schema.lua @@ -9,7 +9,8 @@ do KafkatorioPacketData.Type.PrototypesUpdate = "kafkatorio.packet.instant.PrototypesUpdate" KafkatorioPacketData.Type.SurfaceUpdate = "kafkatorio.packet.instant.SurfaceUpdate" KafkatorioPacketData.Type.EntityUpdate = "kafkatorio.packet.keyed.EntityUpdate" - KafkatorioPacketData.Type.MapChunkUpdate = "kafkatorio.packet.keyed.MapChunkUpdate" + KafkatorioPacketData.Type.MapChunkEntityUpdate = "kafkatorio.packet.keyed.MapChunkEntityUpdate" + KafkatorioPacketData.Type.MapChunkTileUpdate = "kafkatorio.packet.keyed.MapChunkTileUpdate" KafkatorioPacketData.Type.PlayerUpdate = "kafkatorio.packet.keyed.PlayerUpdate" KafkatorioPacketData.Type.Error = "kafkatorio.packet.KafkatorioPacketData.Error" end @@ -20,7 +21,62 @@ do FactorioPrototype.Type.Entity = "kafkatorio.prototype.Entity" FactorioPrototype.Type.MapTile = "kafkatorio.prototype.MapTile" end -____exports.MinedProductType = MinedProductType or ({}) -____exports.MinedProductType.item = "item" -____exports.MinedProductType.fluid = "fluid" +____exports.FactorioEntityData = {} +local FactorioEntityData = ____exports.FactorioEntityData +do + FactorioEntityData.Type = Type or ({}) + FactorioEntityData.Type.Resource = "kafkatorio.entity.FactorioEntityData.Resource" + FactorioEntityData.Type.Standard = "kafkatorio.entity.FactorioEntityData.Standard" +end +____exports.EntityStatus = EntityStatus or ({}) +____exports.EntityStatus.CANT_DIVIDE_SEGMENTS = "CANT_DIVIDE_SEGMENTS" +____exports.EntityStatus.CHARGING = "CHARGING" +____exports.EntityStatus.CLOSED_BY_CIRCUIT_NETWORK = "CLOSED_BY_CIRCUIT_NETWORK" +____exports.EntityStatus.DISABLED = "DISABLED" +____exports.EntityStatus.DISABLED_BY_CONTROL_BEHAVIOR = "DISABLED_BY_CONTROL_BEHAVIOR" +____exports.EntityStatus.DISABLED_BY_SCRIPT = "DISABLED_BY_SCRIPT" +____exports.EntityStatus.DISCHARGING = "DISCHARGING" +____exports.EntityStatus.FLUID_INGREDIENT_SHORTAGE = "FLUID_INGREDIENT_SHORTAGE" +____exports.EntityStatus.FULLY_CHARGED = "FULLY_CHARGED" +____exports.EntityStatus.FULL_OUTPUT = "FULL_OUTPUT" +____exports.EntityStatus.ITEM_INGREDIENT_SHORTAGE = "ITEM_INGREDIENT_SHORTAGE" +____exports.EntityStatus.LAUNCHING_ROCKET = "LAUNCHING_ROCKET" +____exports.EntityStatus.LOW_INPUT_FLUID = "LOW_INPUT_FLUID" +____exports.EntityStatus.LOW_POWER = "LOW_POWER" +____exports.EntityStatus.LOW_TEMPERATURE = "LOW_TEMPERATURE" +____exports.EntityStatus.MARKED_FOR_DECONSTRUCTION = "MARKED_FOR_DECONSTRUCTION" +____exports.EntityStatus.MISSING_REQUIRED_FLUID = "MISSING_REQUIRED_FLUID" +____exports.EntityStatus.MISSING_SCIENCE_PACKS = "MISSING_SCIENCE_PACKS" +____exports.EntityStatus.NETWORKS_CONNECTED = "NETWORKS_CONNECTED" +____exports.EntityStatus.NETWORKS_DISCONNECTED = "NETWORKS_DISCONNECTED" +____exports.EntityStatus.NORMAL = "NORMAL" +____exports.EntityStatus.NOT_CONNECTED_TO_RAIL = "NOT_CONNECTED_TO_RAIL" +____exports.EntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK = "NOT_PLUGGED_IN_ELECTRIC_NETWORK" +____exports.EntityStatus.NO_AMMO = "NO_AMMO" +____exports.EntityStatus.NO_FUEL = "NO_FUEL" +____exports.EntityStatus.NO_INGREDIENTS = "NO_INGREDIENTS" +____exports.EntityStatus.NO_INPUT_FLUID = "NO_INPUT_FLUID" +____exports.EntityStatus.NO_MINABLE_RESOURCES = "NO_MINABLE_RESOURCES" +____exports.EntityStatus.NO_MODULES_TO_TRANSMIT = "NO_MODULES_TO_TRANSMIT" +____exports.EntityStatus.NO_POWER = "NO_POWER" +____exports.EntityStatus.NO_RECIPE = "NO_RECIPE" +____exports.EntityStatus.NO_RESEARCH_IN_PROGRESS = "NO_RESEARCH_IN_PROGRESS" +____exports.EntityStatus.OPENED_BY_CIRCUIT_NETWORK = "OPENED_BY_CIRCUIT_NETWORK" +____exports.EntityStatus.OUT_OF_LOGISTIC_NETWORK = "OUT_OF_LOGISTIC_NETWORK" +____exports.EntityStatus.PREPARING_ROCKET_FOR_LAUNCH = "PREPARING_ROCKET_FOR_LAUNCH" +____exports.EntityStatus.RECHARGING_AFTER_POWER_OUTAGE = "RECHARGING_AFTER_POWER_OUTAGE" +____exports.EntityStatus.TURNED_OFF_DURING_DAYTIME = "TURNED_OFF_DURING_DAYTIME" +____exports.EntityStatus.WAITING_FOR_SOURCE_ITEMS = "WAITING_FOR_SOURCE_ITEMS" +____exports.EntityStatus.WAITING_FOR_SPACE_IN_DESTINATION = "WAITING_FOR_SPACE_IN_DESTINATION" +____exports.EntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT = "WAITING_FOR_TARGET_TO_BE_BUILT" +____exports.EntityStatus.WAITING_FOR_TRAIN = "WAITING_FOR_TRAIN" +____exports.EntityStatus.WAITING_TO_LAUNCH_ROCKET = "WAITING_TO_LAUNCH_ROCKET" +____exports.EntityStatus.WORKING = "WORKING" +____exports.MinedProduct = {} +local MinedProduct = ____exports.MinedProduct +do + MinedProduct.Type = Type or ({}) + MinedProduct.Type.MinedProductFluid = "kafkatorio.resource.MinedProduct.MinedProductFluid" + MinedProduct.Type.MinedProductItem = "kafkatorio.resource.MinedProduct.MinedProductItem" +end return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/converters.lua b/modules/events-mod/src/generated/lua/main/events/converters.lua index 4dcc755..2131d67 100644 --- a/modules/events-mod/src/generated/lua/main/events/converters.lua +++ b/modules/events-mod/src/generated/lua/main/events/converters.lua @@ -1,7 +1,22 @@ local ____exports = {} +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local EntityStatus = ____kafkatorio_2Dschema.EntityStatus +local FactorioEntityData = ____kafkatorio_2Dschema.FactorioEntityData ____exports.Converters = {} local Converters = ____exports.Converters do + local convertEntityStatus, EntityStatusRecord + function convertEntityStatus(status) + if status == nil then + return nil + else + return EntityStatusRecord[status] + end + end + function Converters.prototypeId(____type, name) + return (____type .. "/") .. name + end + local floor = math.floor local mapEventIdToName = {} for eventName, eventId in pairs(defines.events) do mapEventIdToName[eventId] = eventName @@ -36,5 +51,86 @@ do end return masks end + function Converters.convertResourceEntity(entity) + if entity.type ~= "resource" then + return nil + else + return { + type = FactorioEntityData.Type.Resource, + protoId = Converters.prototypeId(entity.type, entity.name), + status = convertEntityStatus(entity.status), + amount = entity.amount, + initialAmount = entity.initial_amount, + position = Converters.convertMapTablePosition(entity.position) + } + end + end + function Converters.prototypeIdEntity(entity) + return Converters.prototypeId(entity.type, entity.name) + end + function Converters.tilePositionToChunkPosition(mapPosition) + return { + floor(mapPosition.x / 32), + floor(mapPosition.y) + } + end + function Converters.mapPositionToChunkPosition(mapPosition) + return { + floor(mapPosition.x / 32), + floor(mapPosition.y) + } + end + function Converters.entityStatus(status) + if status == nil then + return nil + else + return EntityStatusRecord[status] + end + end + EntityStatusRecord = { + [defines.entity_status.cant_divide_segments] = EntityStatus.CANT_DIVIDE_SEGMENTS, + [defines.entity_status.charging] = EntityStatus.CHARGING, + [defines.entity_status.closed_by_circuit_network] = EntityStatus.CLOSED_BY_CIRCUIT_NETWORK, + [defines.entity_status.disabled] = EntityStatus.DISABLED, + [defines.entity_status.disabled_by_control_behavior] = EntityStatus.DISABLED_BY_CONTROL_BEHAVIOR, + [defines.entity_status.disabled_by_script] = EntityStatus.DISABLED_BY_SCRIPT, + [defines.entity_status.discharging] = EntityStatus.DISCHARGING, + [defines.entity_status.fluid_ingredient_shortage] = EntityStatus.FLUID_INGREDIENT_SHORTAGE, + [defines.entity_status.fully_charged] = EntityStatus.FULLY_CHARGED, + [defines.entity_status.full_output] = EntityStatus.FULL_OUTPUT, + [defines.entity_status.item_ingredient_shortage] = EntityStatus.ITEM_INGREDIENT_SHORTAGE, + [defines.entity_status.launching_rocket] = EntityStatus.LAUNCHING_ROCKET, + [defines.entity_status.low_input_fluid] = EntityStatus.LOW_INPUT_FLUID, + [defines.entity_status.low_power] = EntityStatus.LOW_POWER, + [defines.entity_status.low_temperature] = EntityStatus.LOW_TEMPERATURE, + [defines.entity_status.marked_for_deconstruction] = EntityStatus.MARKED_FOR_DECONSTRUCTION, + [defines.entity_status.missing_required_fluid] = EntityStatus.MISSING_REQUIRED_FLUID, + [defines.entity_status.missing_science_packs] = EntityStatus.MISSING_SCIENCE_PACKS, + [defines.entity_status.networks_connected] = EntityStatus.NETWORKS_CONNECTED, + [defines.entity_status.networks_disconnected] = EntityStatus.NETWORKS_DISCONNECTED, + [defines.entity_status.normal] = EntityStatus.NORMAL, + [defines.entity_status.not_connected_to_rail] = EntityStatus.NOT_CONNECTED_TO_RAIL, + [defines.entity_status.not_plugged_in_electric_network] = EntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK, + [defines.entity_status.no_ammo] = EntityStatus.NO_AMMO, + [defines.entity_status.no_fuel] = EntityStatus.NO_FUEL, + [defines.entity_status.no_ingredients] = EntityStatus.NO_INGREDIENTS, + [defines.entity_status.no_input_fluid] = EntityStatus.NO_INPUT_FLUID, + [defines.entity_status.no_minable_resources] = EntityStatus.NO_MINABLE_RESOURCES, + [defines.entity_status.no_modules_to_transmit] = EntityStatus.NO_MODULES_TO_TRANSMIT, + [defines.entity_status.no_power] = EntityStatus.NO_POWER, + [defines.entity_status.no_recipe] = EntityStatus.NO_RECIPE, + [defines.entity_status.no_research_in_progress] = EntityStatus.NO_RESEARCH_IN_PROGRESS, + [defines.entity_status.opened_by_circuit_network] = EntityStatus.OPENED_BY_CIRCUIT_NETWORK, + [defines.entity_status.out_of_logistic_network] = EntityStatus.OUT_OF_LOGISTIC_NETWORK, + [defines.entity_status.preparing_rocket_for_launch] = EntityStatus.PREPARING_ROCKET_FOR_LAUNCH, + [defines.entity_status.recharging_after_power_outage] = EntityStatus.RECHARGING_AFTER_POWER_OUTAGE, + [defines.entity_status.turned_off_during_daytime] = EntityStatus.TURNED_OFF_DURING_DAYTIME, + [defines.entity_status.waiting_for_source_items] = EntityStatus.WAITING_FOR_SOURCE_ITEMS, + [defines.entity_status.waiting_for_space_in_destination] = EntityStatus.WAITING_FOR_SPACE_IN_DESTINATION, + [defines.entity_status.waiting_for_target_to_be_built] = EntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT, + [defines.entity_status.waiting_for_train] = EntityStatus.WAITING_FOR_TRAIN, + [defines.entity_status.waiting_to_launch_rocket] = EntityStatus.WAITING_TO_LAUNCH_ROCKET, + [defines.entity_status.working] = EntityStatus.WORKING + } end return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/entityUpdates.lua b/modules/events-mod/src/generated/lua/main/events/entityUpdates.lua index c5fd3ee..86eb956 100644 --- a/modules/events-mod/src/generated/lua/main/events/entityUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/entityUpdates.lua @@ -1,105 +1,203 @@ +local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local __TS__New = ____lualib.__TS__New local ____exports = {} -local handleBuiltEntityEvent, handleMinedEntityEvent local ____converters = require("main.events.converters") local Converters = ____converters.Converters local ____EventDataCache = require("main.cache.EventDataCache") local EventDataCache = ____EventDataCache.default local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local FactorioEntityData = ____kafkatorio_2Dschema.FactorioEntityData local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData -function handleBuiltEntityEvent(event) - local eventName = Converters.eventNameString(event.name) - if event.created_entity.unit_number == nil then +____exports.EntityUpdatesHandler = __TS__Class() +local EntityUpdatesHandler = ____exports.EntityUpdatesHandler +EntityUpdatesHandler.name = "EntityUpdatesHandler" +function EntityUpdatesHandler.prototype.____constructor(self) +end +function EntityUpdatesHandler.prototype.handleMinedTileEvent(self, event) + local surface = game.get_surface(event.surface_index) + if surface == nil then return end - local key = {name = event.created_entity.name, protoType = event.created_entity.prototype.name, unitNumber = event.created_entity.unit_number} - EventDataCache:debounce( - key, - KafkatorioPacketData.Type.EntityUpdate, + local tilesByChunk = {} + for ____, tile in ipairs(event.tiles) do + local chunkPosition = Converters.tilePositionToChunkPosition(tile.position) + tilesByChunk[chunkPosition] = tile + end + for chunkPos, tiles in pairs(tilesByChunk) do + local entities = {} + for tile in pairs(tiles) do + local resources = ____exports.EntityUpdatesHandler:getTileResourceEntities(surface, chunkPos) + for ____, resource in ipairs(resources) do + entities[#entities + 1] = resource + end + end + ____exports.EntityUpdatesHandler:throttleResourceEntitiesUpdate( + Converters.eventNameString(event.name), + event.tick, + event.surface_index, + {chunkPos[1], chunkPos[2]}, + entities + ) + end +end +function EntityUpdatesHandler.prototype.handleMinedEntityEvent(self, event) + ____exports.EntityUpdatesHandler:throttleEntityUpdate(event, event.entity) +end +function EntityUpdatesHandler.prototype.handleBuiltEntityEvent(self, event) + ____exports.EntityUpdatesHandler:throttleEntityUpdate(event, event.created_entity) +end +function EntityUpdatesHandler.prototype.handleChunkGeneratedEvent(self, event) + local entities = ____exports.EntityUpdatesHandler:getAreaResourceEntities(event.surface, event.area) + ____exports.EntityUpdatesHandler:throttleResourceEntitiesUpdate( + Converters.eventNameString(event.name), + event.tick, + event.surface.index, + {event.position.x, event.position.y}, + entities + ) +end +function EntityUpdatesHandler.throttleEntityUpdate(self, event, entity) + if entity.unit_number == nil then + return + end + local eventName = Converters.eventNameString(event.name) + local entityUpdateKey = { + protoId = Converters.prototypeIdEntity(entity), + surfaceIndex = entity.surface.index, + chunkPosition = Converters.mapPositionToChunkPosition(entity.position) + } + local ____FactorioEntityData_Type_Standard_2 = FactorioEntityData.Type.Standard + local ____Converters_prototypeIdEntity_result_3 = Converters.prototypeIdEntity(entity) + local ____entity_graphics_variation_4 = entity.graphics_variation + local ____entity_health_5 = entity.health + local ____entity_active_6 = entity.active + local ____entity_rotatable_7 = entity.rotatable + local ____entity_last_user_index_0 = entity.last_user + if ____entity_last_user_index_0 ~= nil then + ____entity_last_user_index_0 = ____entity_last_user_index_0.index + end + local entityUpdate = { + type = ____FactorioEntityData_Type_Standard_2, + protoId = ____Converters_prototypeIdEntity_result_3, + graphicsVariation = ____entity_graphics_variation_4, + health = ____entity_health_5, + isActive = ____entity_active_6, + isRotatable = ____entity_rotatable_7, + lastUser = ____entity_last_user_index_0, + localisedDescription = nil, + localisedName = nil, + position = {entity.position.x, entity.position.y}, + status = Converters.entityStatus(entity.status) + } + local entityKey = tostring(entity.unit_number) + EventDataCache:throttle( + entityUpdateKey, + KafkatorioPacketData.Type.MapChunkEntityUpdate, function(data) if data.events == nil then data.events = {} end - local ____data_events_0, ____eventName_1 = data.events, eventName - if ____data_events_0[____eventName_1] == nil then - ____data_events_0[____eventName_1] = {} + local ____data_events_8, ____eventName_9 = data.events, eventName + if ____data_events_8[____eventName_9] == nil then + ____data_events_8[____eventName_9] = {} end - local ____data_events_eventName_2 = data.events[eventName] - ____data_events_eventName_2[#____data_events_eventName_2 + 1] = event.tick - data.chunkPosition = Converters.convertMapTablePosition(event.created_entity.position) - data.graphicsVariation = event.created_entity.graphics_variation - data.health = event.created_entity.health - data.isActive = event.created_entity.active - data.isRotatable = event.created_entity.rotatable - local ____data_5 = data - local ____event_created_entity_last_user_index_3 = event.created_entity.last_user - if ____event_created_entity_last_user_index_3 ~= nil then - ____event_created_entity_last_user_index_3 = ____event_created_entity_last_user_index_3.index + local ____data_events_eventName_10 = data.events[eventName] + ____data_events_eventName_10[#____data_events_eventName_10 + 1] = event.tick + if data.distinctEntities == nil then + data.distinctEntities = {} end - ____data_5.lastUser = ____event_created_entity_last_user_index_3 - data.prototype = event.created_entity.prototype.name + data.distinctEntities[entityKey] = entityUpdate end ) end -function handleMinedEntityEvent(event) - local eventName = Converters.eventNameString(event.name) - if event.entity.unit_number == nil then - return +function EntityUpdatesHandler.throttleResourceEntitiesUpdate(self, eventName, eventTick, surfaceIndex, chunkPosition, entities) + local entitiesByProtoId = {} + for ____, entity in ipairs(entities) do + local ____entitiesByProtoId_11, ____entity_protoId_12 = entitiesByProtoId, entity.protoId + if ____entitiesByProtoId_11[____entity_protoId_12] == nil then + ____entitiesByProtoId_11[____entity_protoId_12] = {} + end + local ____entitiesByProtoId_entity_protoId_13 = entitiesByProtoId[entity.protoId] + ____entitiesByProtoId_entity_protoId_13[#____entitiesByProtoId_entity_protoId_13 + 1] = entity end - local key = {name = event.entity.name, protoType = event.entity.prototype.name, unitNumber = event.entity.unit_number} - EventDataCache:debounce( - key, - KafkatorioPacketData.Type.EntityUpdate, - function(data) - if data.events == nil then - data.events = {} + for protoId, resourceEntities in pairs(entitiesByProtoId) do + local entityUpdateKey = {protoId = protoId, surfaceIndex = surfaceIndex, chunkPosition = {chunkPosition[1], chunkPosition[2]}} + EventDataCache:throttle( + entityUpdateKey, + KafkatorioPacketData.Type.MapChunkEntityUpdate, + function(data) + if data.events == nil then + data.events = {} + end + local ____data_events_14, ____eventName_15 = data.events, eventName + if ____data_events_14[____eventName_15] == nil then + ____data_events_14[____eventName_15] = {} + end + local ____data_events_eventName_16 = data.events[eventName] + ____data_events_eventName_16[#____data_events_eventName_16 + 1] = eventTick + for ____, entity in ipairs(resourceEntities) do + local x, y = table.unpack(entity.position) + local entityKey = (tostring(x) .. ",") .. tostring(y) + if data.distinctEntities == nil then + data.distinctEntities = {} + end + data.distinctEntities[entityKey] = entity + end end - local ____data_events_6, ____eventName_7 = data.events, eventName - if ____data_events_6[____eventName_7] == nil then - ____data_events_6[____eventName_7] = {} - end - local ____data_events_eventName_8 = data.events[eventName] - ____data_events_eventName_8[#____data_events_eventName_8 + 1] = event.tick - data.chunkPosition = Converters.convertMapTablePosition(event.entity.position) - data.graphicsVariation = event.entity.graphics_variation - data.health = event.entity.health - data.isActive = event.entity.active - data.isRotatable = event.entity.rotatable - local ____data_11 = data - local ____event_entity_last_user_index_9 = event.entity.last_user - if ____event_entity_last_user_index_9 ~= nil then - ____event_entity_last_user_index_9 = ____event_entity_last_user_index_9.index - end - ____data_11.lastUser = ____event_entity_last_user_index_9 - data.prototype = event.entity.prototype.name - end - ) + ) + end end +function EntityUpdatesHandler.getTileResourceEntities(self, surface, mapPosition) + local rawEntities = surface.find_entities_filtered({position = mapPosition, collision_mask = "resource-layer"}) + local resources = {} + for ____, rawEntity in ipairs(rawEntities) do + local entity = Converters.convertResourceEntity(rawEntity) + if entity ~= nil then + resources[#resources + 1] = entity + end + end + return resources +end +function EntityUpdatesHandler.getAreaResourceEntities(self, surface, area) + local rawEntities = surface.find_entities_filtered({area = area, collision_mask = "resource-layer"}) + local resources = {} + for ____, rawEntity in ipairs(rawEntities) do + local entity = Converters.convertResourceEntity(rawEntity) + if entity ~= nil then + resources[#resources + 1] = entity + end + end + return resources +end +local EntityUpdates = __TS__New(____exports.EntityUpdatesHandler) +____exports.default = EntityUpdates script.on_event( defines.events.on_built_entity, function(e) log("on_built_entity " .. tostring(e.tick)) - handleBuiltEntityEvent(e) + EntityUpdates:handleBuiltEntityEvent(e) end ) script.on_event( defines.events.on_robot_built_entity, function(e) log("on_robot_built_entity " .. tostring(e.tick)) - handleBuiltEntityEvent(e) + EntityUpdates:handleBuiltEntityEvent(e) end ) script.on_event( defines.events.on_player_mined_entity, function(e) log("on_player_mined_entity " .. tostring(e.tick)) - handleMinedEntityEvent(e) + EntityUpdates:handleMinedEntityEvent(e) end ) script.on_event( defines.events.on_robot_mined_entity, function(e) log("on_robot_mined_entity " .. tostring(e.tick)) - handleMinedEntityEvent(e) + EntityUpdates:handleMinedEntityEvent(e) end ) return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua b/modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua index 146ade2..a21a929 100644 --- a/modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua @@ -1,9 +1,9 @@ local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class local Map = ____lualib.Map local __TS__Iterator = ____lualib.__TS__Iterator local __TS__New = ____lualib.__TS__New local ____exports = {} -local mapTilesUpdateDebounce, getTiles, getSurface, groupTiles, handleBuiltTileEvent, handleMinedTileEvent, Type local ____eventTypeCheck = require("main.events.eventTypeCheck") local isEventType = ____eventTypeCheck.isEventType local ____converters = require("main.events.converters") @@ -12,65 +12,16 @@ local ____EventDataCache = require("main.cache.EventDataCache") local EventUpdatesManager = ____EventDataCache.default local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData -function mapTilesUpdateDebounce(surface, chunkPosition, tiles, event, updater, expirationDurationTicks) - if surface == nil then - return - end - local eventName = Converters.eventNameString(event.name) - local key = {surfaceIndex = surface.index, chunkPosition = chunkPosition} - EventUpdatesManager:debounce( - key, - Type.MapChunkUpdate, - function(data) - if data.tileDictionary == nil then - data.tileDictionary = {tilesXY = {}, protos = {}} - end - local protosCount = table_size(data.tileDictionary.protos) - for ____, tile in ipairs(tiles) do - local ____data_tileDictionary_protos_1, ____tile_name_2 = data.tileDictionary.protos, tile.name - if ____data_tileDictionary_protos_1[____tile_name_2] == nil then - local ____protosCount_0 = protosCount - protosCount = ____protosCount_0 + 1 - ____data_tileDictionary_protos_1[____tile_name_2] = ____protosCount_0 - end - local protoKey = data.tileDictionary.protos[tile.name] - local xString = tostring(tile.position.x) - local yString = tostring(tile.position.y) - local ____data_tileDictionary_tilesXY_3, ____xString_4 = data.tileDictionary.tilesXY, xString - if ____data_tileDictionary_tilesXY_3[____xString_4] == nil then - ____data_tileDictionary_tilesXY_3[____xString_4] = {} - end - data.tileDictionary.tilesXY[xString][yString] = protoKey - end - if data.events == nil then - data.events = {} - end - local ____data_events_5, ____eventName_6 = data.events, eventName - if ____data_events_5[____eventName_6] == nil then - ____data_events_5[____eventName_6] = {} - end - local ____data_events_eventName_7 = data.events[eventName] - ____data_events_eventName_7[#____data_events_eventName_7 + 1] = event.tick - if updater ~= nil then - updater(data) - end - end, - expirationDurationTicks - ) +local ____entityUpdates = require("main.events.entityUpdates") +local EntityUpdates = ____entityUpdates.default +local Type = KafkatorioPacketData.Type +local MapChunkUpdateHandler = __TS__Class() +MapChunkUpdateHandler.name = "MapChunkUpdateHandler" +function MapChunkUpdateHandler.prototype.____constructor(self) end -function getTiles(surface, area) - local ____surface_find_tiles_filtered_result_8 = surface - if ____surface_find_tiles_filtered_result_8 ~= nil then - ____surface_find_tiles_filtered_result_8 = ____surface_find_tiles_filtered_result_8.find_tiles_filtered({area = area}) - end - return ____surface_find_tiles_filtered_result_8 or ({}) -end -function getSurface(surfaceIndex) - return game.surfaces[surfaceIndex] -end -function ____exports.handleChunkGeneratedEvent(event, expirationDurationTicks) - local tiles = getTiles(event.surface, event.area) - mapTilesUpdateDebounce( +function MapChunkUpdateHandler.prototype.handleChunkGeneratedEvent(self, event, expirationDurationTicks) + local tiles = event.surface.find_tiles_filtered({area = event.area}) + MapChunkUpdateHandler:mapTilesUpdateDebounce( event.surface, Converters.convertMapTablePosition(event.position), tiles, @@ -79,38 +30,19 @@ function ____exports.handleChunkGeneratedEvent(event, expirationDurationTicks) expirationDurationTicks ) end -function groupTiles(tiles) - local mapChunkPositionToTiles = __TS__New(Map) - for ____, tile in ipairs(tiles) do - local chunkPosition = { - math.floor(tile.position.x / 32), - math.floor(tile.position.y / 32) - } - if not mapChunkPositionToTiles:has(chunkPosition) then - mapChunkPositionToTiles:set(chunkPosition, {}) - end - local ____mapChunkPositionToTiles_get_result_push_result_10 = mapChunkPositionToTiles:get(chunkPosition) - if ____mapChunkPositionToTiles_get_result_push_result_10 ~= nil then - local ____temp_11 = mapChunkPositionToTiles:get(chunkPosition) - ____temp_11[#____temp_11 + 1] = tile - ____mapChunkPositionToTiles_get_result_push_result_10 = nil - end - end - return mapChunkPositionToTiles -end -function handleBuiltTileEvent(event) - local surface = getSurface(event.surface_index) +function MapChunkUpdateHandler.prototype.handleBuiltTileEvent(self, event) + local surface = game.get_surface(event.surface_index) if surface == nil then local eventName = Converters.eventNameString(event.name) log("[handleBuiltTileEvent] undefined surface " .. eventName) return end local tiles = Converters.convertPlacedTiles(event.tile, event.tiles) - local groupedTiles = groupTiles(tiles) + local groupedTiles = MapChunkUpdateHandler:groupTiles(tiles) for ____, ____value in __TS__Iterator(groupedTiles) do local chunkPos = ____value[1] local tiles = ____value[2] - mapTilesUpdateDebounce( + MapChunkUpdateHandler:mapTilesUpdateDebounce( surface, chunkPos, tiles, @@ -121,12 +53,15 @@ function handleBuiltTileEvent(event) return end if isEventType(event, defines.events.on_robot_built_tile) then - local ____data_15 = data - local ____event_robot_unit_number_13 = event.robot - if ____event_robot_unit_number_13 ~= nil then - ____event_robot_unit_number_13 = ____event_robot_unit_number_13.unit_number + local ____data_2 = data + local ____event_robot_unit_number_0 = event.robot + if ____event_robot_unit_number_0 ~= nil then + ____event_robot_unit_number_0 = ____event_robot_unit_number_0.unit_number end - ____data_15.robot = {unitNumber = ____event_robot_unit_number_13 or nil, name = event.robot.name, protoType = event.robot.type} + ____data_2.robot = { + unitNumber = ____event_robot_unit_number_0 or nil, + protoId = Converters.prototypeId(event.robot.type, event.robot.name) + } return end local exhaustiveCheck = event @@ -134,19 +69,19 @@ function handleBuiltTileEvent(event) ) end end -function handleMinedTileEvent(event) - local surface = getSurface(event.surface_index) +function MapChunkUpdateHandler.prototype.handleMinedTileEvent(self, event) + local surface = game.get_surface(event.surface_index) if surface == nil then local eventName = Converters.eventNameString(event.name) log("[handleMinedTileEvent] undefined surface " .. eventName) return end local tiles = Converters.convertRemovedTiles(surface, event.tiles) - local groupedTiles = groupTiles(tiles) + local groupedTiles = MapChunkUpdateHandler:groupTiles(tiles) for ____, ____value in __TS__Iterator(groupedTiles) do local chunkPos = ____value[1] local tiles = ____value[2] - mapTilesUpdateDebounce( + MapChunkUpdateHandler:mapTilesUpdateDebounce( surface, chunkPos, tiles, @@ -157,12 +92,15 @@ function handleMinedTileEvent(event) return end if isEventType(event, defines.events.on_robot_mined_tile) then - local ____data_18 = data - local ____event_robot_unit_number_16 = event.robot - if ____event_robot_unit_number_16 ~= nil then - ____event_robot_unit_number_16 = ____event_robot_unit_number_16.unit_number + local ____data_5 = data + local ____event_robot_unit_number_3 = event.robot + if ____event_robot_unit_number_3 ~= nil then + ____event_robot_unit_number_3 = ____event_robot_unit_number_3.unit_number end - ____data_18.robot = {unitNumber = ____event_robot_unit_number_16 or nil, name = event.robot.name, protoType = event.robot.type} + ____data_5.robot = { + unitNumber = ____event_robot_unit_number_3 or nil, + protoId = Converters.prototypeId(event.robot.type, event.robot.name) + } return end local exhaustiveCheck = event @@ -170,78 +108,155 @@ function handleMinedTileEvent(event) ) end end -Type = KafkatorioPacketData.Type +function MapChunkUpdateHandler.prototype.handleScriptSetTilesEvent(self, event) + local surface = game.get_surface(event.surface_index) + if surface == nil then + return + end + local groupedTiles = MapChunkUpdateHandler:groupTiles(event.tiles) + for ____, ____value in __TS__Iterator(groupedTiles) do + local chunkPos = ____value[1] + local tiles = ____value[2] + MapChunkUpdateHandler:mapTilesUpdateDebounce(surface, chunkPos, tiles, event) + end +end +function MapChunkUpdateHandler.prototype.handlePreChunkDeleted(self, event) + local surface = game.get_surface(event.surface_index) + if surface == nil then + return + end + for ____, position in ipairs(event.positions) do + local key = {surfaceIndex = surface.index, chunkPosition = {position.x, position.y}} + EventUpdatesManager:debounce( + key, + Type.MapChunkTileUpdate, + function(data) + data.isDeleted = true + return true + end, + 0 + ) + end +end +function MapChunkUpdateHandler.mapTilesUpdateDebounce(self, surface, chunkPosition, tiles, event, updater, expirationDurationTicks) + if surface == nil then + return + end + local eventName = Converters.eventNameString(event.name) + local key = {surfaceIndex = surface.index, chunkPosition = chunkPosition} + EventUpdatesManager:debounce( + key, + Type.MapChunkTileUpdate, + function(data) + if data.tileDictionary == nil then + data.tileDictionary = {tilesXY = {}, protos = {}} + end + local protosCount = table_size(data.tileDictionary.protos) + for ____, tile in ipairs(tiles) do + local protoId = Converters.prototypeId("tile", tile.name) + if data.tileDictionary.protos[protoId] == nil then + end + local ____data_tileDictionary_protos_7, ____protoId_8 = data.tileDictionary.protos, protoId + if ____data_tileDictionary_protos_7[____protoId_8] == nil then + local ____protosCount_6 = protosCount + protosCount = ____protosCount_6 + 1 + ____data_tileDictionary_protos_7[____protoId_8] = ____protosCount_6 + end + local protoKey = data.tileDictionary.protos[protoId] + local xString = tostring(tile.position.x) + local yString = tostring(tile.position.y) + local ____data_tileDictionary_tilesXY_9, ____xString_10 = data.tileDictionary.tilesXY, xString + if ____data_tileDictionary_tilesXY_9[____xString_10] == nil then + ____data_tileDictionary_tilesXY_9[____xString_10] = {} + end + data.tileDictionary.tilesXY[xString][yString] = protoKey + end + if data.events == nil then + data.events = {} + end + local ____data_events_11, ____eventName_12 = data.events, eventName + if ____data_events_11[____eventName_12] == nil then + ____data_events_11[____eventName_12] = {} + end + local ____data_events_eventName_13 = data.events[eventName] + ____data_events_eventName_13[#____data_events_eventName_13 + 1] = event.tick + if updater ~= nil then + updater(data) + end + end, + expirationDurationTicks + ) +end +function MapChunkUpdateHandler.groupTiles(self, tiles) + local mapChunkPositionToTiles = __TS__New(Map) + for ____, tile in ipairs(tiles) do + local chunkPosition = { + math.floor(tile.position.x / 32), + math.floor(tile.position.y / 32) + } + if not mapChunkPositionToTiles:has(chunkPosition) then + mapChunkPositionToTiles:set(chunkPosition, {}) + end + local ____mapChunkPositionToTiles_get_result_push_result_14 = mapChunkPositionToTiles:get(chunkPosition) + if ____mapChunkPositionToTiles_get_result_push_result_14 ~= nil then + local ____temp_15 = mapChunkPositionToTiles:get(chunkPosition) + ____temp_15[#____temp_15 + 1] = tile + ____mapChunkPositionToTiles_get_result_push_result_14 = nil + end + end + return mapChunkPositionToTiles +end +local MapChunkUpdate = __TS__New(MapChunkUpdateHandler) +____exports.default = MapChunkUpdate script.on_event( defines.events.on_chunk_generated, function(e) log("on_chunk_generated " .. tostring(e.tick)) - ____exports.handleChunkGeneratedEvent(e) + MapChunkUpdate:handleChunkGeneratedEvent(e) + EntityUpdates:handleChunkGeneratedEvent(e) end ) script.on_event( defines.events.script_raised_set_tiles, function(event) log("script_raised_set_tiles " .. tostring(event.tick)) - local surface = getSurface(event.surface_index) - if surface == nil then - return - end - local groupedTiles = groupTiles(event.tiles) - for ____, ____value in __TS__Iterator(groupedTiles) do - local chunkPos = ____value[1] - local tiles = ____value[2] - mapTilesUpdateDebounce(surface, chunkPos, tiles, event) - end + MapChunkUpdate:handleScriptSetTilesEvent(event) end ) script.on_event( defines.events.on_player_built_tile, function(e) log("on_player_built_tile " .. tostring(e.tick)) - handleBuiltTileEvent(e) + MapChunkUpdate:handleBuiltTileEvent(e) end ) script.on_event( defines.events.on_robot_built_tile, function(e) log("on_robot_built_tile " .. tostring(e.tick)) - handleBuiltTileEvent(e) + MapChunkUpdate:handleBuiltTileEvent(e) end ) script.on_event( defines.events.on_player_mined_tile, function(e) log("on_player_mined_tile " .. tostring(e.tick)) - handleMinedTileEvent(e) + MapChunkUpdate:handleMinedTileEvent(e) + EntityUpdates:handleMinedTileEvent(e) end ) script.on_event( defines.events.on_robot_mined_tile, function(e) log("on_robot_mined_tile " .. tostring(e.tick)) - handleMinedTileEvent(e) + MapChunkUpdate:handleMinedTileEvent(e) end ) script.on_event( defines.events.on_pre_chunk_deleted, function(e) log("on_pre_chunk_deleted " .. tostring(e.tick)) - local surface = getSurface(e.surface_index) - if surface == nil then - return - end - for ____, position in ipairs(e.positions) do - local key = {surfaceIndex = surface.index, chunkPosition = {position.x, position.y}} - EventUpdatesManager:debounce( - key, - Type.MapChunkUpdate, - function(data) - data.isDeleted = true - return true - end, - 0 - ) - end + MapChunkUpdate:handlePreChunkDeleted(e) end ) return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/playerUpdates.lua b/modules/events-mod/src/generated/lua/main/events/playerUpdates.lua index 3cfa307..47840de 100644 --- a/modules/events-mod/src/generated/lua/main/events/playerUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/playerUpdates.lua @@ -115,7 +115,10 @@ script.on_event( data.ticksToRespawn = player.ticks_to_respawn or nil playerOnlineInfo(player, data) if e.cause ~= nil then - data.diedCause = {unitNumber = e.cause.unit_number or nil, name = e.cause.name, protoType = e.cause.type} + data.diedCause = { + unitNumber = e.cause.unit_number or nil, + protoId = Converters.prototypeId(e.cause.type, e.cause.name) + } end end ) diff --git a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua index 1daa787..a1d6f07 100644 --- a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua @@ -22,7 +22,7 @@ function getMapTilePrototypes() for ____, tile in pairs(game.tile_prototypes) do tiles[#tiles + 1] = { type = FactorioPrototype.Type.MapTile, - name = tile.name, + protoId = Converters.prototypeId("tile", tile.name), order = tile.order, layer = tile.layer, collisionMasks = Converters.convertCollisionMaskToNames(tile.collision_mask), diff --git a/modules/events-mod/src/generated/lua/main/events/registerHandlers.lua b/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua similarity index 93% rename from modules/events-mod/src/generated/lua/main/events/registerHandlers.lua rename to modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua index 65aacb2..757ef9a 100644 --- a/modules/events-mod/src/generated/lua/main/events/registerHandlers.lua +++ b/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua @@ -5,12 +5,12 @@ local ____eventTypeCheck = require("main.events.eventTypeCheck") local isEventType = ____eventTypeCheck.isEventType local ____converters = require("main.events.converters") local Converters = ____converters.Converters -local ____mapChunkUpdates = require("main.events.mapChunkUpdates") -local handleChunkGeneratedEvent = ____mapChunkUpdates.handleChunkGeneratedEvent local ____surfaceUpdates = require("main.events.surfaceUpdates") local handleSurfaceUpdate = ____surfaceUpdates.handleSurfaceUpdate local ____EventDataCache = require("main.cache.EventDataCache") local EventCacheService = ____EventDataCache.default +local ____mapChunkUpdates = require("main.events.mapChunkUpdates") +local MapChunkUpdate = ____mapChunkUpdates.default script.on_event( defines.events.on_tick, function(event) @@ -38,7 +38,7 @@ script.on_event( if isEventType(event, defines.events.on_chunk_generated) then local eName = Converters.eventNameString(event.name) log((((("[on_tick:" .. tostring(event.tick)) .. "] dequed event ") .. eName) .. ", delay ") .. tostring(i)) - handleChunkGeneratedEvent(event, i) + MapChunkUpdate:handleChunkGeneratedEvent(event, i) i = i + 1 end end diff --git a/modules/events-mod/src/generated/lua/main/events/resourceEntityUpdates.lua b/modules/events-mod/src/generated/lua/main/events/resourceEntityUpdates.lua new file mode 100644 index 0000000..e69de29 diff --git a/modules/events-mod/src/generated/lua/main/settings/KafkatorioSettings.lua b/modules/events-mod/src/generated/lua/main/settings/KafkatorioSettings.lua index aa8a574..28eac97 100644 --- a/modules/events-mod/src/generated/lua/main/settings/KafkatorioSettings.lua +++ b/modules/events-mod/src/generated/lua/main/settings/KafkatorioSettings.lua @@ -34,7 +34,7 @@ end function KafkatorioSettingsConfig.cacheDurationSettingName(self, ____type) return "kafkatorio:cache-expiration-seconds_" .. __TS__StringReplaceAll(____type, ".", "-") end -KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds = {["kafkatorio.packet.keyed.PlayerUpdate"] = 0.5, ["kafkatorio.packet.keyed.MapChunkUpdate"] = 30, ["kafkatorio.packet.keyed.EntityUpdate"] = 5} +KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds = {["kafkatorio.packet.keyed.PlayerUpdate"] = 0.5, ["kafkatorio.packet.keyed.MapChunkTileUpdate"] = 30, ["kafkatorio.packet.keyed.MapChunkEntityUpdate"] = 30, ["kafkatorio.packet.keyed.EntityUpdate"] = 5} local KafkatorioSettings = __TS__New(____exports.KafkatorioSettingsConfig) ____exports.default = KafkatorioSettings return ____exports diff --git a/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg b/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg index 491d391..f3d4ab6 100644 --- a/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg +++ b/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg @@ -1,14 +1,16 @@ [mod-setting-name] kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-PlayerUpdate=Player update rate (seconds) -kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkUpdate=Map update rate (seconds) +kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkTileUpdate=Map tile update rate (seconds) +kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkEntityUpdate=Entity update rate (seconds) kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-EntityUpdate=Entity update rate (seconds) [mod-setting-description] kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-PlayerUpdate=How frequently Player updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (0.25 seconds) is probably fine! -kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkUpdate=How frequently Map updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine! +kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkTileUpdate=How frequently Map updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine! +kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkEntityUpdate=How frequently entity updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine! kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-EntityUpdate=How frequently Entity updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (5 seconds) is probably fine! diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index 3800be5..3cb0824 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -1,7 +1,7 @@ import {initGlobal} from "./main/global-init"; import {emitPrototypes} from "./main/events/prototypeUpdates"; -require("./main/events/registerHandlers") +require("./main/events/registerEventListeners") require("./main/events/mapChunkUpdates") require("./main/events/playerUpdates") require("./main/events/entityUpdates") diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts index e01e826..0ff6cea 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts @@ -14,7 +14,8 @@ export type KafkatorioPacketData = | KafkatorioPacketData.ConsoleCommandUpdate | KafkatorioPacketData.EntityUpdate | KafkatorioPacketData.Error - | KafkatorioPacketData.MapChunkUpdate + | KafkatorioPacketData.MapChunkEntityUpdate + | KafkatorioPacketData.MapChunkTileUpdate | KafkatorioPacketData.PlayerUpdate | KafkatorioPacketData.PrototypesUpdate | KafkatorioPacketData.SurfaceUpdate; @@ -27,7 +28,8 @@ export namespace KafkatorioPacketData { PrototypesUpdate = "kafkatorio.packet.instant.PrototypesUpdate", SurfaceUpdate = "kafkatorio.packet.instant.SurfaceUpdate", EntityUpdate = "kafkatorio.packet.keyed.EntityUpdate", - MapChunkUpdate = "kafkatorio.packet.keyed.MapChunkUpdate", + MapChunkEntityUpdate = "kafkatorio.packet.keyed.MapChunkEntityUpdate", + MapChunkTileUpdate = "kafkatorio.packet.keyed.MapChunkTileUpdate", PlayerUpdate = "kafkatorio.packet.keyed.PlayerUpdate", Error = "kafkatorio.packet.KafkatorioPacketData.Error", } @@ -77,12 +79,18 @@ export namespace KafkatorioPacketData { lastUser?: UInt | null; localisedDescription?: string | null; localisedName?: string | null; - prototype?: PrototypeName | null; } - export interface MapChunkUpdate { - type: KafkatorioPacketData.Type.MapChunkUpdate; - key: MapChunkUpdateKey; + export interface MapChunkEntityUpdate { + type: KafkatorioPacketData.Type.MapChunkEntityUpdate; + key: MapChunkEntityUpdateKey; + events?: { [key: EventName]: Tick[] } | null; + distinctEntities?: { [key: string]: FactorioEntityData } | null; + } + + export interface MapChunkTileUpdate { + type: KafkatorioPacketData.Type.MapChunkTileUpdate; + key: MapChunkTileUpdateKey; events?: { [key: EventName]: Tick[] } | null; player?: PlayerIndex | null; robot?: EntityIdentifiersData | null; @@ -132,16 +140,11 @@ export interface ConfigurationUpdateGameData { newVersion?: string | null; } -export type PlayerIndex = UInt; - -export type SurfaceIndex = UInt; - export type Double = double; export interface EntityUpdateKey { unitNumber: UnitNumber; - name: string; - protoType: string; + protoId: PrototypeId; } export type MapEntityPosition = [ @@ -153,32 +156,33 @@ export type UByte = uint8; export type Float = float; -export type PrototypeName = string; +export interface MapChunkEntityUpdateKey { + protoId: PrototypeId; + surfaceIndex: SurfaceIndex; + chunkPosition: MapChunkPosition; +} -export interface MapChunkUpdateKey { +export interface MapChunkTileUpdateKey { chunkPosition: MapChunkPosition; surfaceIndex: SurfaceIndex; } export interface EntityIdentifiersData { unitNumber?: UnitNumber | null; - name: string; - protoType: string; + protoId: PrototypeId; } -export type ForceIndex = UInt; +export type ForceIndex = UInt & { __ForceIndex__: void }; export interface MapTileDictionary { tilesXY: { [key: string]: { [key: string]: PrototypeKey } }; - protos: { [key: PrototypeName]: PrototypeKey }; + protos: { [key: PrototypeId]: PrototypeKey }; } export interface PlayerUpdateKey { index: PlayerIndex; } -export type UnitNumber = UInt; - export type Colour = [ red: Float, green: Float, @@ -206,7 +210,7 @@ export namespace FactorioPrototype { export interface Entity { type: FactorioPrototype.Type.Entity; - name: PrototypeName; + protoId: PrototypeId; mapColour: Colour; protoType: string; objectName: string; @@ -220,7 +224,7 @@ export namespace FactorioPrototype { export interface MapTile { type: FactorioPrototype.Type.MapTile; - name: PrototypeName; + protoId: PrototypeId; mapColour: Colour; layer: UInt; collisionMasks: List; @@ -229,7 +233,9 @@ export namespace FactorioPrototype { } } -export type EventName = string; +export type PrototypeId = string & { __PrototypeId__: void }; + +export type EventName = string & { __EventName__: void }; export type Byte = int8; @@ -238,22 +244,114 @@ export type MapChunkPosition = [ y: Int, ]; +export type FactorioEntityData = + | FactorioEntityData.Resource + | FactorioEntityData.Standard; + +export namespace FactorioEntityData { + export enum Type { + Resource = "kafkatorio.entity.FactorioEntityData.Resource", + Standard = "kafkatorio.entity.FactorioEntityData.Standard", + } + + export interface Resource { + type: FactorioEntityData.Type.Resource; + protoId: PrototypeId; + status?: EntityStatus | null; + position: MapEntityPosition; + amount: UInt; + initialAmount?: UInt | null; + } + + export interface Standard { + type: FactorioEntityData.Type.Standard; + protoId: PrototypeId; + status?: EntityStatus | null; + position: MapEntityPosition; + graphicsVariation?: UByte | null; + health?: Float | null; + isActive?: boolean | null; + isRotatable?: boolean | null; + lastUser?: UInt | null; + localisedDescription?: string | null; + localisedName?: string | null; + } +} + export interface MiningProperties { canBeMined: boolean; products: MinedProduct[] | null; } -export type List = any; +export type List = any & { __List__: void }; -export type PrototypeKey = Int; - -export interface MinedProduct { - type: MinedProductType; - name: PrototypeName; - amount: Double | null; +export enum EntityStatus { + CANT_DIVIDE_SEGMENTS = "CANT_DIVIDE_SEGMENTS", + CHARGING = "CHARGING", + CLOSED_BY_CIRCUIT_NETWORK = "CLOSED_BY_CIRCUIT_NETWORK", + DISABLED = "DISABLED", + DISABLED_BY_CONTROL_BEHAVIOR = "DISABLED_BY_CONTROL_BEHAVIOR", + DISABLED_BY_SCRIPT = "DISABLED_BY_SCRIPT", + DISCHARGING = "DISCHARGING", + FLUID_INGREDIENT_SHORTAGE = "FLUID_INGREDIENT_SHORTAGE", + FULLY_CHARGED = "FULLY_CHARGED", + FULL_OUTPUT = "FULL_OUTPUT", + ITEM_INGREDIENT_SHORTAGE = "ITEM_INGREDIENT_SHORTAGE", + LAUNCHING_ROCKET = "LAUNCHING_ROCKET", + LOW_INPUT_FLUID = "LOW_INPUT_FLUID", + LOW_POWER = "LOW_POWER", + LOW_TEMPERATURE = "LOW_TEMPERATURE", + MARKED_FOR_DECONSTRUCTION = "MARKED_FOR_DECONSTRUCTION", + MISSING_REQUIRED_FLUID = "MISSING_REQUIRED_FLUID", + MISSING_SCIENCE_PACKS = "MISSING_SCIENCE_PACKS", + NETWORKS_CONNECTED = "NETWORKS_CONNECTED", + NETWORKS_DISCONNECTED = "NETWORKS_DISCONNECTED", + NORMAL = "NORMAL", + NOT_CONNECTED_TO_RAIL = "NOT_CONNECTED_TO_RAIL", + NOT_PLUGGED_IN_ELECTRIC_NETWORK = "NOT_PLUGGED_IN_ELECTRIC_NETWORK", + NO_AMMO = "NO_AMMO", + NO_FUEL = "NO_FUEL", + NO_INGREDIENTS = "NO_INGREDIENTS", + NO_INPUT_FLUID = "NO_INPUT_FLUID", + NO_MINABLE_RESOURCES = "NO_MINABLE_RESOURCES", + NO_MODULES_TO_TRANSMIT = "NO_MODULES_TO_TRANSMIT", + NO_POWER = "NO_POWER", + NO_RECIPE = "NO_RECIPE", + NO_RESEARCH_IN_PROGRESS = "NO_RESEARCH_IN_PROGRESS", + OPENED_BY_CIRCUIT_NETWORK = "OPENED_BY_CIRCUIT_NETWORK", + OUT_OF_LOGISTIC_NETWORK = "OUT_OF_LOGISTIC_NETWORK", + PREPARING_ROCKET_FOR_LAUNCH = "PREPARING_ROCKET_FOR_LAUNCH", + RECHARGING_AFTER_POWER_OUTAGE = "RECHARGING_AFTER_POWER_OUTAGE", + TURNED_OFF_DURING_DAYTIME = "TURNED_OFF_DURING_DAYTIME", + WAITING_FOR_SOURCE_ITEMS = "WAITING_FOR_SOURCE_ITEMS", + WAITING_FOR_SPACE_IN_DESTINATION = "WAITING_FOR_SPACE_IN_DESTINATION", + WAITING_FOR_TARGET_TO_BE_BUILT = "WAITING_FOR_TARGET_TO_BE_BUILT", + WAITING_FOR_TRAIN = "WAITING_FOR_TRAIN", + WAITING_TO_LAUNCH_ROCKET = "WAITING_TO_LAUNCH_ROCKET", + WORKING = "WORKING", } -export enum MinedProductType { - item = "item", - fluid = "fluid", +export type PrototypeKey = Int & { __PrototypeKey__: void }; + +export type MinedProduct = + | MinedProduct.MinedProductFluid + | MinedProduct.MinedProductItem; + +export namespace MinedProduct { + export enum Type { + MinedProductFluid = "kafkatorio.resource.MinedProduct.MinedProductFluid", + MinedProductItem = "kafkatorio.resource.MinedProduct.MinedProductItem", + } + + export interface MinedProductFluid { + type: MinedProduct.Type.MinedProductFluid; + amount?: Double | null; + resultProtoId: PrototypeId; + } + + export interface MinedProductItem { + type: MinedProduct.Type.MinedProductItem; + amount?: Double | null; + resultProtoId: PrototypeId; + } } \ No newline at end of file diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts index 17bcabb..4c9b572 100644 --- a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts +++ b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts @@ -101,7 +101,7 @@ export namespace EventUpdates { let countExpired = 0 let countTotal = 0 const expiredData: Array = [] - for (let [key, entry] of global.cache) { + for (const [key, entry] of global.cache) { countTotal++ if (this.isExpired(entry)) { countExpired++ diff --git a/modules/events-mod/src/main/typescript/main/events/consoleUpdates.ts b/modules/events-mod/src/main/typescript/main/events/consoleUpdates.ts index 08b2c48..2dcd812 100644 --- a/modules/events-mod/src/main/typescript/main/events/consoleUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/consoleUpdates.ts @@ -23,7 +23,7 @@ script.on_event( const update: KafkatorioPacketData.ConsoleCommandUpdate = { type: Type.ConsoleCommandUpdate, - authorPlayerIndex: event.player_index ?? null, + authorPlayerIndex: event.player_index ?? null, command: event.command, parameters: event.parameters, } diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index db6fe3e..220484e 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -1,16 +1,25 @@ -import {EventName} from "../types"; -import {Colour, MapChunkPosition} from "../../generated/kafkatorio-schema"; +import {DefinedEventName} from "../types"; +import { + Colour, + EntityStatus, + EventName, + FactorioEntityData, + MapChunkPosition, + PrototypeId, +} from "../../generated/kafkatorio-schema"; export namespace Converters { - const mapEventIdToName = new LuaTable() + + import floor = math.floor; + const mapEventIdToName = new LuaTable() for (const [eventName, eventId] of pairs(defines.events)) { mapEventIdToName.set(eventId, eventName) } export function eventNameString(event: defines.Events): EventName { - return mapEventIdToName.get(event) + return mapEventIdToName.get(event) as EventName } @@ -60,10 +69,115 @@ export namespace Converters { export function convertCollisionMaskToNames(cm: CollisionMask): string[] { let masks: string[] = [] - for (let [name] of pairs(cm)) { + for (const [name] of pairs(cm)) { masks.push(name) } return masks } + + export function convertResourceEntity( + entity: LuaEntity + ): FactorioEntityData.Resource | null { + if (entity.type != "resource") { + return null + } else { + return { + type: FactorioEntityData.Type.Resource, + protoId: prototypeId(entity.type, entity.name), + status: convertEntityStatus(entity.status), + amount: entity.amount, + initialAmount: entity.initial_amount, + position: convertMapTablePosition(entity.position), + } + } + } + + + function convertEntityStatus( + status: defines.entity_status | undefined + ): EntityStatus | null { + if (status == undefined) { + return null + } else { + return EntityStatusRecord[status] + } + } + + + export function prototypeIdEntity(entity: LuaEntity): PrototypeId { + return prototypeId(entity.type, entity.name) + } + + + export function prototypeId(type: string, name: string): PrototypeId { + return `${type}/${name}` as PrototypeId + } + + + export function tilePositionToChunkPosition(mapPosition: TilePositionTable): MapChunkPosition { + return [floor(mapPosition.x / 32), floor(mapPosition.y)] + } + + export function mapPositionToChunkPosition(mapPosition: MapPositionTable): MapChunkPosition { + return [floor(mapPosition.x / 32), floor(mapPosition.y)] + } + + + export function entityStatus(status: defines.entity_status | undefined): EntityStatus | undefined { + if (status == undefined) { + return undefined + } else { + return EntityStatusRecord[status] + } + } + + + const EntityStatusRecord: Record = { + //@formatter:off + [ defines.entity_status.cant_divide_segments ]: EntityStatus.CANT_DIVIDE_SEGMENTS, + [ defines.entity_status.charging ]: EntityStatus.CHARGING, + [ defines.entity_status.closed_by_circuit_network ]: EntityStatus.CLOSED_BY_CIRCUIT_NETWORK, + [ defines.entity_status.disabled ]: EntityStatus.DISABLED, + [ defines.entity_status.disabled_by_control_behavior ]: EntityStatus.DISABLED_BY_CONTROL_BEHAVIOR, + [ defines.entity_status.disabled_by_script ]: EntityStatus.DISABLED_BY_SCRIPT, + [ defines.entity_status.discharging ]: EntityStatus.DISCHARGING, + [ defines.entity_status.fluid_ingredient_shortage ]: EntityStatus.FLUID_INGREDIENT_SHORTAGE, + [ defines.entity_status.fully_charged ]: EntityStatus.FULLY_CHARGED, + [ defines.entity_status.full_output ]: EntityStatus.FULL_OUTPUT, + [ defines.entity_status.item_ingredient_shortage ]: EntityStatus.ITEM_INGREDIENT_SHORTAGE, + [ defines.entity_status.launching_rocket ]: EntityStatus.LAUNCHING_ROCKET, + [ defines.entity_status.low_input_fluid ]: EntityStatus.LOW_INPUT_FLUID, + [ defines.entity_status.low_power ]: EntityStatus.LOW_POWER, + [ defines.entity_status.low_temperature ]: EntityStatus.LOW_TEMPERATURE, + [ defines.entity_status.marked_for_deconstruction ]: EntityStatus.MARKED_FOR_DECONSTRUCTION, + [ defines.entity_status.missing_required_fluid ]: EntityStatus.MISSING_REQUIRED_FLUID, + [ defines.entity_status.missing_science_packs ]: EntityStatus.MISSING_SCIENCE_PACKS, + [ defines.entity_status.networks_connected ]: EntityStatus.NETWORKS_CONNECTED, + [ defines.entity_status.networks_disconnected ]: EntityStatus.NETWORKS_DISCONNECTED, + [ defines.entity_status.normal ]: EntityStatus.NORMAL, + [ defines.entity_status.not_connected_to_rail ]: EntityStatus.NOT_CONNECTED_TO_RAIL, + [ defines.entity_status.not_plugged_in_electric_network ]: EntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK, + [ defines.entity_status.no_ammo ]: EntityStatus.NO_AMMO, + [ defines.entity_status.no_fuel ]: EntityStatus.NO_FUEL, + [ defines.entity_status.no_ingredients ]: EntityStatus.NO_INGREDIENTS, + [ defines.entity_status.no_input_fluid ]: EntityStatus.NO_INPUT_FLUID, + [ defines.entity_status.no_minable_resources ]: EntityStatus.NO_MINABLE_RESOURCES, + [ defines.entity_status.no_modules_to_transmit ]: EntityStatus.NO_MODULES_TO_TRANSMIT, + [ defines.entity_status.no_power ]: EntityStatus.NO_POWER, + [ defines.entity_status.no_recipe ]: EntityStatus.NO_RECIPE, + [ defines.entity_status.no_research_in_progress ]: EntityStatus.NO_RESEARCH_IN_PROGRESS, + [ defines.entity_status.opened_by_circuit_network ]: EntityStatus.OPENED_BY_CIRCUIT_NETWORK, + [ defines.entity_status.out_of_logistic_network ]: EntityStatus.OUT_OF_LOGISTIC_NETWORK, + [ defines.entity_status.preparing_rocket_for_launch ]: EntityStatus.PREPARING_ROCKET_FOR_LAUNCH, + [ defines.entity_status.recharging_after_power_outage ]: EntityStatus.RECHARGING_AFTER_POWER_OUTAGE, + [ defines.entity_status.turned_off_during_daytime ]: EntityStatus.TURNED_OFF_DURING_DAYTIME, + [ defines.entity_status.waiting_for_source_items ]: EntityStatus.WAITING_FOR_SOURCE_ITEMS, + [ defines.entity_status.waiting_for_space_in_destination ]: EntityStatus.WAITING_FOR_SPACE_IN_DESTINATION, + [ defines.entity_status.waiting_for_target_to_be_built ]: EntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT, + [ defines.entity_status.waiting_for_train ]: EntityStatus.WAITING_FOR_TRAIN, + [ defines.entity_status.waiting_to_launch_rocket ]: EntityStatus.WAITING_TO_LAUNCH_ROCKET, + [ defines.entity_status.working ]: EntityStatus.WORKING, + //@formatter:on + } } diff --git a/modules/events-mod/src/main/typescript/main/events/entityUpdates.ts b/modules/events-mod/src/main/typescript/main/events/entityUpdates.ts index 791f3e6..f262eb3 100644 --- a/modules/events-mod/src/main/typescript/main/events/entityUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/entityUpdates.ts @@ -1,97 +1,276 @@ import {Converters} from "./converters"; import EventDataCache from "../cache/EventDataCache"; import { - EntityUpdateKey, - KafkatorioPacketData + EventName, + FactorioEntityData, + KafkatorioPacketData, + MapChunkPosition, + PrototypeId, + Tick, } from "../../generated/kafkatorio-schema"; +export class EntityUpdatesHandler { + + + handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) { + + const surface = game.get_surface(event.surface_index) + if (surface == null) { + return + } + + const tilesByChunk: LuaTable = new LuaTable() + + for (const tile of event.tiles) { + const chunkPosition = Converters.tilePositionToChunkPosition(tile.position) + tilesByChunk.set(chunkPosition, tile) + } + + for (const [chunkPos, tiles] of pairs(tilesByChunk)) { + + const entities: FactorioEntityData.Resource[] = [] + + for (const tile in tiles) { + const resources: FactorioEntityData.Resource[] = EntityUpdatesHandler.getTileResourceEntities(surface, chunkPos) + for (const resource of resources) { + entities[entities.length] = resource + } + } + + EntityUpdatesHandler.throttleResourceEntitiesUpdate( + Converters.eventNameString(event.name), + event.tick as Tick, + event.surface_index, + [chunkPos[0], chunkPos[1]], + entities, + ) + } + } + + + handleMinedEntityEvent( + event: OnPlayerMinedEntityEvent | OnRobotMinedEntityEvent, + ) { + EntityUpdatesHandler.throttleEntityUpdate(event, event.entity) + } + + + handleBuiltEntityEvent( + event: OnBuiltEntityEvent | OnRobotBuiltEntityEvent, + ) { + EntityUpdatesHandler.throttleEntityUpdate(event, event.created_entity) + } + + + handleChunkGeneratedEvent(event: OnChunkGeneratedEvent) { + const entities = EntityUpdatesHandler.getAreaResourceEntities(event.surface, event.area) + EntityUpdatesHandler.throttleResourceEntitiesUpdate( + Converters.eventNameString(event.name), + event.tick as Tick, + event.surface.index, + [event.position.x, event.position.y], + entities, + ) + } + + + private static throttleEntityUpdate(event: EntityUpdateEvent, entity: LuaEntity) { + + if (entity.unit_number == undefined) { + // ignore for now - I'm not sure how to track entities without a unit_number + return + } + const eventName = Converters.eventNameString(event.name) + + const entityUpdateKey: KafkatorioPacketData.MapChunkEntityUpdate["key"] = { + protoId: Converters.prototypeIdEntity(entity), + surfaceIndex: entity.surface.index, + chunkPosition: Converters.mapPositionToChunkPosition(entity.position) + } + + const entityUpdate: FactorioEntityData.Standard = { + type: FactorioEntityData.Type.Standard, + protoId: Converters.prototypeIdEntity(entity), + graphicsVariation: entity.graphics_variation, + health: entity.health, + isActive: entity.active, + isRotatable: entity.rotatable, + lastUser: entity.last_user?.index, + localisedDescription: null, + localisedName: null, + position: [entity.position.x, entity.position.y], + status: Converters.entityStatus(entity.status), + } + + const entityKey: string = `${entity.unit_number}` + + EventDataCache.throttle( + entityUpdateKey, + KafkatorioPacketData.Type.MapChunkEntityUpdate, + data => { + + data.events ??= {} + data.events[eventName] ??= [] + data.events[eventName].push(event.tick) + + data.distinctEntities ??= {} + data.distinctEntities[entityKey] = entityUpdate + } + ) + } + + + private static throttleResourceEntitiesUpdate( + eventName: EventName, + eventTick: Tick, + surfaceIndex: SurfaceIndex, + chunkPosition: MapChunkPosition, + entities: FactorioEntityData.Resource[], + ) { + + // first group by prototype ID + const entitiesByProtoId: { [protoId: PrototypeId]: FactorioEntityData.Resource[] } = {} + + for (const entity of entities) { + entitiesByProtoId[entity.protoId] ??= [] + entitiesByProtoId[entity.protoId].push(entity) + } + + for (const [protoId, resourceEntities] of pairs(entitiesByProtoId)) { + + // create an update for each prototype + + const entityUpdateKey: KafkatorioPacketData.MapChunkEntityUpdate["key"] = { + protoId: protoId, + surfaceIndex: surfaceIndex, + chunkPosition: [chunkPosition[0], chunkPosition[1]], + } + + EventDataCache.throttle( + entityUpdateKey, + KafkatorioPacketData.Type.MapChunkEntityUpdate, + data => { + + data.events ??= {} + data.events[eventName] ??= [] + data.events[eventName].push(eventTick) + + for (const entity of resourceEntities) { + const [x, y] = entity.position + const entityKey: string = `${x},${y}` + + data.distinctEntities ??= {} + data.distinctEntities[entityKey] = entity + } + } + ) + } + + } + + + /** Get all resources on a tile-position */ + private static getTileResourceEntities( + surface: LuaSurface, + mapPosition: MapPosition, + ): FactorioEntityData.Resource[] { + + const rawEntities = surface.find_entities_filtered({ + position: mapPosition, + collision_mask: "resource-layer", + } + ) + + const resources: FactorioEntityData.Resource[] = [] + + for (const rawEntity of rawEntities) { + const entity = Converters.convertResourceEntity(rawEntity) + if (entity != null) { + resources[resources.length] = entity + } + } + + return resources + } + + + /** Get all resources within a map-area */ + private static getAreaResourceEntities( + surface: LuaSurface, + area: BoundingBoxTable, + ): FactorioEntityData.Resource[] { + + const rawEntities = surface.find_entities_filtered({ + area: area, + collision_mask: "resource-layer", + } + ) + + const resources: FactorioEntityData.Resource[] = [] + + for (const rawEntity of rawEntities) { + const entity = Converters.convertResourceEntity(rawEntity) + if (entity != null) { + resources[resources.length] = entity + } + } + + return resources + } +} + + +const EntityUpdates = new EntityUpdatesHandler() + +export default EntityUpdates + + script.on_event(defines.events.on_built_entity, (e: OnBuiltEntityEvent) => { log(`on_built_entity ${e.tick}`) - handleBuiltEntityEvent(e) + EntityUpdates.handleBuiltEntityEvent(e) }) script.on_event(defines.events.on_robot_built_entity, (e: OnRobotBuiltEntityEvent) => { log(`on_robot_built_entity ${e.tick}`) - handleBuiltEntityEvent(e) + EntityUpdates.handleBuiltEntityEvent(e) }) -function handleBuiltEntityEvent(event: OnBuiltEntityEvent | OnRobotBuiltEntityEvent) { - const eventName = Converters.eventNameString(event.name) - - if (event.created_entity.unit_number == undefined) { - return - } - - const key: EntityUpdateKey = { - name: event.created_entity.name, - protoType: event.created_entity.prototype.name, - unitNumber: event.created_entity.unit_number - } - - EventDataCache.debounce( - key, - KafkatorioPacketData.Type.EntityUpdate, - data => { - - data.events ??= {} - data.events[eventName] ??= [] - data.events[eventName].push(event.tick) - - data.chunkPosition = Converters.convertMapTablePosition(event.created_entity.position) - data.graphicsVariation = event.created_entity.graphics_variation - data.health = event.created_entity.health - data.isActive = event.created_entity.active - data.isRotatable = event.created_entity.rotatable - data.lastUser = event.created_entity.last_user?.index - data.prototype = event.created_entity.prototype.name - } - ) -} - script.on_event(defines.events.on_player_mined_entity, (e: OnPlayerMinedEntityEvent) => { log(`on_player_mined_entity ${e.tick}`) - handleMinedEntityEvent(e) + EntityUpdates.handleMinedEntityEvent(e) }) script.on_event(defines.events.on_robot_mined_entity, (e: OnRobotMinedEntityEvent) => { log(`on_robot_mined_entity ${e.tick}`) - handleMinedEntityEvent(e) + EntityUpdates.handleMinedEntityEvent(e) }) -function handleMinedEntityEvent(event: OnPlayerMinedEntityEvent | OnRobotMinedEntityEvent) { - const eventName = Converters.eventNameString(event.name) +type EntityUpdateEvent = + | OnBuiltEntityEvent - if (event.entity.unit_number == undefined) { - return - } + | OnEntityClonedEvent + | OnEntityDamagedEvent + | OnEntityDestroyedEvent + | OnEntityDiedEvent + | OnEntityLogisticSlotChangedEvent + | OnEntityRenamedEvent + | OnEntitySettingsPastedEvent + | OnEntitySpawnedEvent - const key: EntityUpdateKey = { - name: event.entity.name, - protoType: event.entity.prototype.name, - unitNumber: event.entity.unit_number - } + | OnPlayerMinedEntityEvent + | OnPlayerRepairedEntityEvent + | OnPlayerRotatedEntityEvent - EventDataCache.debounce( - key, - KafkatorioPacketData.Type.EntityUpdate, - data => { + | OnRobotMinedEntityEvent + | OnRobotBuiltEntityEvent - data.events ??= {} - data.events[eventName] ??= [] - data.events[eventName].push(event.tick) + | OnPostEntityDiedEvent + | OnPreEntitySettingsPastedEvent - data.chunkPosition = Converters.convertMapTablePosition(event.entity.position) - data.graphicsVariation = event.entity.graphics_variation - data.health = event.entity.health - data.isActive = event.entity.active - data.isRotatable = event.entity.rotatable - data.lastUser = event.entity.last_user?.index - data.prototype = event.entity.prototype.name - } - ) -} + | OnSelectedEntityChangedEvent + | OnTriggerCreatedEntityEvent diff --git a/modules/events-mod/src/main/typescript/main/events/mapChunkUpdates.ts b/modules/events-mod/src/main/typescript/main/events/mapChunkUpdates.ts index 509afc5..e914a5e 100644 --- a/modules/events-mod/src/main/typescript/main/events/mapChunkUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/mapChunkUpdates.ts @@ -3,129 +3,270 @@ import {Converters} from "./converters"; import EventUpdatesManager, {EventUpdates} from "../cache/EventDataCache"; import { KafkatorioPacketData, - MapChunkPosition + MapChunkPosition, PrototypeId, + PrototypeKey, } from "../../generated/kafkatorio-schema"; +import EntityUpdates from "./entityUpdates"; import CacheKey = EventUpdates.PacketKey; import Type = KafkatorioPacketData.Type; -type MapChunkUpdater = (data: KafkatorioPacketData.MapChunkUpdate) => void +type MapChunkTileUpdater = (data: KafkatorioPacketData.MapChunkTileUpdate) => void -type MapTileUpdateEvent = - | OnChunkGeneratedEvent +export type MapTileChangeEvent = | OnPlayerBuiltTileEvent - | OnPlayerMinedEntityEvent | OnPlayerMinedTileEvent | OnRobotBuiltTileEvent - | OnRobotMinedEntityEvent | OnRobotMinedTileEvent | ScriptRaisedSetTilesEvent -function mapTilesUpdateDebounce( - surface: LuaSurface | undefined, - chunkPosition: MapChunkPosition, - tiles: TileRead[], - event: MapTileUpdateEvent, - updater?: MapChunkUpdater, - expirationDurationTicks?: uint, -) { +export type MapChunkUpdateEvent = + | OnChunkChartedEvent + | OnChunkDeletedEvent + | OnChunkGeneratedEvent + | OnPreChunkDeletedEvent - if (surface == undefined) { - return + +class MapChunkUpdateHandler { + + handleChunkGeneratedEvent( + event: OnChunkGeneratedEvent, + expirationDurationTicks?: uint, + ) { + const tiles = event.surface.find_tiles_filtered({area: event.area}) + + MapChunkUpdateHandler.mapTilesUpdateDebounce( + event.surface, + Converters.convertMapTablePosition(event.position), + tiles, + event, + undefined, + expirationDurationTicks, + ) } - const eventName = Converters.eventNameString(event.name) - const key: KafkatorioPacketData.MapChunkUpdate["key"] = { - surfaceIndex: surface.index, - chunkPosition: chunkPosition, + handleBuiltTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) { + + const surface = game.get_surface(event.surface_index) + if (surface == undefined) { + const eventName = Converters.eventNameString(event.name) + log(`[handleBuiltTileEvent] undefined surface ${eventName}`) + return + } + + const tiles: TileRead[] = Converters.convertPlacedTiles(event.tile, event.tiles) + const groupedTiles = MapChunkUpdateHandler.groupTiles(tiles) + + for (const [chunkPos, tiles] of groupedTiles) { + MapChunkUpdateHandler.mapTilesUpdateDebounce( + surface, + chunkPos, + tiles, + event, + (data => { + if (isEventType(event, defines.events.on_player_built_tile)) { + data.player = event.player_index + return + } + if (isEventType(event, defines.events.on_robot_built_tile)) { + data.robot = { + unitNumber: event.robot?.unit_number ?? null, + protoId: Converters.prototypeId(event.robot.type, event.robot.name), + } + return + } + // this line will not compile if the previous 'if' statements are not exhaustive + // noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols + const exhaustiveCheck: never = event + } + ) + ) + } } - EventUpdatesManager.debounce( - key, - Type.MapChunkUpdate, - data => { - // tile dictionary update - if (data.tileDictionary == undefined) { - data.tileDictionary = { - tilesXY: {}, - protos: {}, - } - } + handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) { + const surface = game.get_surface(event.surface_index) + if (surface == undefined) { + const eventName = Converters.eventNameString(event.name) + log(`[handleMinedTileEvent] undefined surface ${eventName}`) + return + } - let protosCount: uint = table_size(data.tileDictionary.protos) - for (const tile of tiles) { - data.tileDictionary.protos[tile.name] ??= protosCount++ + const tiles: TileRead[] = Converters.convertRemovedTiles(surface, event.tiles) + const groupedTiles = MapChunkUpdateHandler.groupTiles(tiles) - const protoKey = data.tileDictionary.protos[tile.name] + for (const [chunkPos, tiles] of groupedTiles) { - const xString = `${tile.position.x}` - const yString = `${tile.position.y}` - - data.tileDictionary.tilesXY[xString] ??= {} - data.tileDictionary.tilesXY[xString][yString] = protoKey - } - - // events count update - data.events ??= {} - data.events[eventName] ??= [] - data.events[eventName].push(event.tick) - - // apply mutator - if (updater != undefined) { - updater(data) - } - }, - expirationDurationTicks, - ) -} + MapChunkUpdateHandler.mapTilesUpdateDebounce( + surface, + chunkPos, + tiles, + event, + (data => { + if (isEventType(event, defines.events.on_player_mined_tile)) { + data.player = event.player_index + return + } + if (isEventType(event, defines.events.on_robot_mined_tile)) { + data.robot = { + unitNumber: event.robot?.unit_number ?? null, + protoId: Converters.prototypeId(event.robot.type, event.robot.name), + } + return + } + // this line will not compile if the previous 'if' statements are not exhaustive + // noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols + const exhaustiveCheck: never = event + } + ) + ) + } + } -function getTiles( - surface: LuaSurface | undefined, - area: BoundingBoxTable -): LuaTile[] { - return surface?.find_tiles_filtered({ - area: area, - // collision_mask: ["ground-tile", "water-tile"] + handleScriptSetTilesEvent(event: ScriptRaisedSetTilesEvent) { + + const surface = game.get_surface(event.surface_index) + if (surface == undefined) { + return + } + + const groupedTiles = MapChunkUpdateHandler.groupTiles(event.tiles) + + for (const [chunkPos, tiles] of groupedTiles) { + MapChunkUpdateHandler.mapTilesUpdateDebounce(surface, chunkPos, tiles, event) + } + } + + + handlePreChunkDeleted(event: OnPreChunkDeletedEvent) { + + const surface = game.get_surface(event.surface_index) + if (surface == undefined) { + return + } + + for (const position of event.positions) { + const key: CacheKey = { + surfaceIndex: surface.index, + chunkPosition: [position.x, position.y], } - ) ?? [] + + EventUpdatesManager.debounce( + key, + Type.MapChunkTileUpdate, + data => data.isDeleted = true, + 0, // deletion is important - emit ASAP + ) + } + } + + + private static mapTilesUpdateDebounce( + surface: LuaSurface | undefined, + chunkPosition: MapChunkPosition, + tiles: TileRead[], + event: MapChunkUpdateEvent | MapTileChangeEvent, + updater?: MapChunkTileUpdater, + expirationDurationTicks?: uint, + ) { + + if (surface == undefined) { + return + } + + const eventName = Converters.eventNameString(event.name) + + const key: KafkatorioPacketData.MapChunkTileUpdate["key"] = { + surfaceIndex: surface.index, + chunkPosition: chunkPosition, + } + + EventUpdatesManager.debounce( + key, + Type.MapChunkTileUpdate, + data => { + + // tile dictionary update + if (data.tileDictionary == undefined) { + data.tileDictionary = { + tilesXY: {}, + protos: {}, + } + } + + let protosCount: uint = table_size(data.tileDictionary.protos) + for (const tile of tiles) { + const protoId = Converters.prototypeId("tile", tile.name) + + if (data.tileDictionary.protos[protoId] == null) { + + } + data.tileDictionary.protos[protoId] ??= protosCount++ as PrototypeKey + + const protoKey = data.tileDictionary.protos[protoId] + + const xString = `${tile.position.x}` + const yString = `${tile.position.y}` + + data.tileDictionary.tilesXY[xString] ??= {} + data.tileDictionary.tilesXY[xString][yString] = protoKey + } + + // events count update + data.events ??= {} + data.events[eventName] ??= [] + data.events[eventName].push(event.tick) + + // apply mutator + if (updater != undefined) { + updater(data) + } + }, + expirationDurationTicks, + ) + } + + + private static groupTiles(tiles: TileRead[]): Map { + + const mapChunkPositionToTiles = new Map() + for (const tile of tiles) { + const chunkPosition: MapChunkPosition = [ + math.floor((tile.position.x / 32)), + math.floor((tile.position.y / 32)), + ] + if (!mapChunkPositionToTiles.has(chunkPosition)) { + mapChunkPositionToTiles.set(chunkPosition, []) + } + mapChunkPositionToTiles.get(chunkPosition)?.push(tile) + } + return mapChunkPositionToTiles + } + + } -function getSurface(surfaceIndex: uint): LuaSurface | undefined { - return game.surfaces[surfaceIndex] -} +const MapChunkUpdate = new MapChunkUpdateHandler() + +export default MapChunkUpdate script.on_event( defines.events.on_chunk_generated, (e: OnChunkGeneratedEvent) => { log(`on_chunk_generated ${e.tick}`) - handleChunkGeneratedEvent(e) + MapChunkUpdate.handleChunkGeneratedEvent(e) + EntityUpdates.handleChunkGeneratedEvent(e) } ) -export function handleChunkGeneratedEvent( - event: OnChunkGeneratedEvent, - expirationDurationTicks?: uint, -) { - let tiles = getTiles(event.surface, event.area) - mapTilesUpdateDebounce( - event.surface, - Converters.convertMapTablePosition(event.position), - tiles, - event, - undefined, - expirationDurationTicks, - ) -} - - // script.on_event( // defines.events.on_chunk_charted, // (e: OnChunkChartedEvent) => { @@ -144,169 +285,38 @@ export function handleChunkGeneratedEvent( // ) -script.on_event( - defines.events.script_raised_set_tiles, - (event: ScriptRaisedSetTilesEvent) => { - log(`script_raised_set_tiles ${event.tick}`) - - const surface = getSurface(event.surface_index) - if (surface == undefined) { - return - } - - const groupedTiles = groupTiles(event.tiles) - - for (const [chunkPos, tiles] of groupedTiles) { - mapTilesUpdateDebounce(surface, chunkPos, tiles, event) - } - } -) - - -function groupTiles(tiles: TileRead[]): Map { - - const mapChunkPositionToTiles = new Map() - for (const tile of tiles) { - const chunkPosition: MapChunkPosition = [ - math.floor((tile.position.x / 32)), - math.floor((tile.position.y / 32)), - ] - if (!mapChunkPositionToTiles.has(chunkPosition)) { - mapChunkPositionToTiles.set(chunkPosition, []) - } - // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1256 - mapChunkPositionToTiles.get(chunkPosition)?.push(tile) - // const tiles = mapChunkPositionToTiles.get(chunkPosition) - // if (tiles != null) { - // tiles.push(tile) - // } - } - return mapChunkPositionToTiles -} +script.on_event(defines.events.script_raised_set_tiles, (event: ScriptRaisedSetTilesEvent) => { + log(`script_raised_set_tiles ${event.tick}`) + MapChunkUpdate.handleScriptSetTilesEvent(event) +}) script.on_event(defines.events.on_player_built_tile, (e: OnPlayerBuiltTileEvent) => { log(`on_player_built_tile ${e.tick}`) - handleBuiltTileEvent(e) + MapChunkUpdate.handleBuiltTileEvent(e) }) + + script.on_event(defines.events.on_robot_built_tile, (e: OnRobotBuiltTileEvent) => { log(`on_robot_built_tile ${e.tick}`) - handleBuiltTileEvent(e) + MapChunkUpdate.handleBuiltTileEvent(e) }) -function handleBuiltTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) { - - const surface = getSurface(event.surface_index) - if (surface == undefined) { - const eventName = Converters.eventNameString(event.name) - log(`[handleBuiltTileEvent] undefined surface ${eventName}`) - return - } - - const tiles: TileRead[] = Converters.convertPlacedTiles(event.tile, event.tiles) - const groupedTiles = groupTiles(tiles) - - for (const [chunkPos, tiles] of groupedTiles) { - mapTilesUpdateDebounce( - surface, - chunkPos, - tiles, - event, - (data => { - if (isEventType(event, defines.events.on_player_built_tile)) { - data.player = event.player_index - return - } - if (isEventType(event, defines.events.on_robot_built_tile)) { - data.robot = { - unitNumber: event.robot?.unit_number ?? null, - name: event.robot.name, - protoType: event.robot.type, - } - return - } - // this line will not compile if the previous 'if' statements are not exhaustive - // noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols - const exhaustiveCheck: never = event - } - ) - ) - } -} - script.on_event(defines.events.on_player_mined_tile, (e: OnPlayerMinedTileEvent) => { log(`on_player_mined_tile ${e.tick}`) - handleMinedTileEvent(e) + MapChunkUpdate.handleMinedTileEvent(e) + EntityUpdates.handleMinedTileEvent(e) }) + script.on_event(defines.events.on_robot_mined_tile, (e: OnRobotMinedTileEvent) => { log(`on_robot_mined_tile ${e.tick}`) - handleMinedTileEvent(e) + MapChunkUpdate.handleMinedTileEvent(e) }) -function handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) { - const surface = getSurface(event.surface_index) - if (surface == undefined) { - const eventName = Converters.eventNameString(event.name) - log(`[handleMinedTileEvent] undefined surface ${eventName}`) - return - } - const tiles: TileRead[] = Converters.convertRemovedTiles(surface, event.tiles) - const groupedTiles = groupTiles(tiles) - - for (const [chunkPos, tiles] of groupedTiles) { - mapTilesUpdateDebounce( - surface, - chunkPos, - tiles, - event, - (data => { - if (isEventType(event, defines.events.on_player_mined_tile)) { - data.player = event.player_index - return - } - if (isEventType(event, defines.events.on_robot_mined_tile)) { - data.robot = { - unitNumber: event.robot?.unit_number ?? null, - name: event.robot.name, - protoType: event.robot.type, - } - return - } - // this line will not compile if the previous 'if' statements are not exhaustive - // noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols - const exhaustiveCheck: never = event - } - ) - ) - } -} - - -script.on_event( - defines.events.on_pre_chunk_deleted, - (e: OnPreChunkDeletedEvent) => { - log(`on_pre_chunk_deleted ${e.tick}`) - - const surface = getSurface(e.surface_index) - if (surface == undefined) { - return - } - - for (const position of e.positions) { - const key: CacheKey = { - surfaceIndex: surface.index, - chunkPosition: [position.x, position.y], - } - - EventUpdatesManager.debounce( - key, - Type.MapChunkUpdate, - data => data.isDeleted = true, - 0, // deletion is important - emit ASAP - ) - } - } -) +script.on_event(defines.events.on_pre_chunk_deleted, (e: OnPreChunkDeletedEvent) => { + log(`on_pre_chunk_deleted ${e.tick}`) + MapChunkUpdate.handlePreChunkDeleted(e) +}) diff --git a/modules/events-mod/src/main/typescript/main/events/playerUpdates.ts b/modules/events-mod/src/main/typescript/main/events/playerUpdates.ts index da55741..18b46f2 100644 --- a/modules/events-mod/src/main/typescript/main/events/playerUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/playerUpdates.ts @@ -1,11 +1,8 @@ import {Converters} from "./converters"; import EventUpdatesManager from "../cache/EventDataCache"; -import { - KafkatorioPacketData, - PlayerUpdateKey -} from "../../generated/kafkatorio-schema"; -import Type = KafkatorioPacketData.Type; +import {ForceIndex, KafkatorioPacketData, PlayerUpdateKey} from "../../generated/kafkatorio-schema"; import packetEmitter from "../PacketEmitter"; +import Type = KafkatorioPacketData.Type; type PlayerUpdater = (player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) => void @@ -36,7 +33,7 @@ function playerUpdateThrottle( const eventName = Converters.eventNameString(event.name) EventUpdatesManager.throttle( - {index: playerIndex}, + {index: playerIndex }, Type.PlayerUpdate, data => { const player = game.players[playerIndex] @@ -88,7 +85,7 @@ script.on_event( data.characterUnitNumber = player.character?.unit_number ?? null data.chatColour = Converters.mapColour(player.chat_color) data.colour = Converters.mapColour(player.color) - data.forceIndex = player.force.index + data.forceIndex = player.force.index as ForceIndex data.name = player.name data.isShowOnMap = player.show_on_map data.isSpectator = player.spectator @@ -139,8 +136,7 @@ script.on_event( if (e.cause != undefined) { data.diedCause = { unitNumber: e.cause.unit_number ?? null, - name: e.cause.name, - protoType: e.cause.type + protoId: Converters.prototypeId(e.cause.type, e.cause.name), } } } @@ -189,7 +185,7 @@ script.on_event( log(`on_pre_player_left_game ${event.tick} ${event.name}`) const playerUpdateKey: PlayerUpdateKey = { - index: event.player_index + index: event.player_index , } const playerUpdate: KafkatorioPacketData.PlayerUpdate = { diff --git a/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts b/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts index 8c71f9b..b424383 100644 --- a/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts @@ -26,11 +26,11 @@ function prototypeUpdates(): FactorioPrototype[] { function getMapTilePrototypes(): FactorioPrototype.MapTile[] { let tiles: FactorioPrototype.MapTile[] = [] - for (let [, tile] of game.tile_prototypes) { + for (const [, tile] of game.tile_prototypes) { tiles.push({ type: FactorioPrototype.Type.MapTile, - name: tile.name, + protoId: Converters.prototypeId("tile", tile.name), order: tile.order, layer: tile.layer, collisionMasks: Converters.convertCollisionMaskToNames(tile.collision_mask), @@ -44,7 +44,7 @@ function getMapTilePrototypes(): FactorioPrototype.MapTile[] { // function getEntityPrototypes(): FactorioPrototype.MapTile[] { // let tiles: FactorioPrototype.MapTile[] = [] -// for (let [, tile] of game.tile_prototypes) { +// for (const [, tile] of game.tile_prototypes) { // tiles.push({ // type: FactorioPrototype.Type.MapTile, // diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts similarity index 92% rename from modules/events-mod/src/main/typescript/main/events/registerHandlers.ts rename to modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts index d3758c7..095c3a2 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts @@ -1,9 +1,9 @@ import {Queue} from "../queue/queue"; import {isEventType} from "./eventTypeCheck"; import {Converters} from "./converters"; -import {handleChunkGeneratedEvent} from "./mapChunkUpdates"; import {handleSurfaceUpdate} from "./surfaceUpdates"; import EventCacheService from "../cache/EventDataCache"; +import MapChunkUpdate from "./mapChunkUpdates"; script.on_event( @@ -35,7 +35,7 @@ script.on_event( let eName = Converters.eventNameString(event.name) log(`[on_tick:${event.tick}] dequed event ${eName}, delay ${i}`) - handleChunkGeneratedEvent(event, i) + MapChunkUpdate.handleChunkGeneratedEvent(event, i) i += 1 } } diff --git a/modules/events-mod/src/main/typescript/main/events/resourceEntityUpdates.ts b/modules/events-mod/src/main/typescript/main/events/resourceEntityUpdates.ts new file mode 100644 index 0000000..5955137 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/events/resourceEntityUpdates.ts @@ -0,0 +1,99 @@ +// import {isEventType} from "./eventTypeCheck"; +// import {Converters} from "./converters"; +// import EventUpdatesManager, {EventUpdates} from "../cache/EventDataCache"; +// import { +// KafkatorioPacketData, +// MapChunkPosition, +// PrototypeKey, +// } from "../../generated/kafkatorio-schema"; +// import CacheKey = EventUpdates.PacketKey; +// import Type = KafkatorioPacketData.Type; +// +// +// export class ResourceEntityUpdatesHandler { +// +// +// handleChunkGeneratedEvent( +// event: OnChunkGeneratedEvent, +// expirationDurationTicks?: uint, +// ) { +// const resourceEntities = this.getAreaResourceEntities(event.surface, event.area) +// +// mapTilesUpdateDebounce( +// event.surface, +// Converters.convertMapTablePosition(event.position), +// tiles, +// event, +// undefined, +// expirationDurationTicks, +// ) +// } +// +// +// private resourceEntityUpdatesThrottle( +// surface: LuaSurface | undefined, +// chunkPosition: MapChunkPosition, +// tiles: TileRead[], +// event: MapTileUpdateEvent, +// updater?: MapChunkUpdater, +// expirationDurationTicks?: uint, +// ) { +// +// if (surface == undefined) { +// return +// } +// +// const eventName = Converters.eventNameString(event.name) +// +// const key: KafkatorioPacketData.ResourceEntitiesUpdate["key"] = { +// surfaceIndex: surface.index as SurfaceIndex, +// chunkPosition: chunkPosition, +// } +// +// EventUpdatesManager.throttle( +// key, +// Type.MapChunkUpdate, +// data => { +// +// // tile dictionary update +// if (data.tileDictionary == undefined) { +// data.tileDictionary = { +// tilesXY: {}, +// protos: {}, +// } +// } +// +// let protosCount: uint = table_size(data.tileDictionary.protos) +// for (const tile of tiles) { +// const tileName = tile.name as PrototypeIdMapTile +// const protoKey = protosCount++ as PrototypeKey +// data.tileDictionary.protos[tileName] ??= protoKey +// +// const xString = `${tile.position.x}` +// const yString = `${tile.position.y}` +// +// data.tileDictionary.tilesXY[xString] ??= {} +// data.tileDictionary.tilesXY[xString][yString] = protoKey +// } +// +// // events count update +// data.events ??= {} +// data.events[eventName] ??= [] +// data.events[eventName].push(event.tick) +// +// // apply mutator +// if (updater != undefined) { +// updater(data) +// } +// }, +// expirationDurationTicks, +// ) +// } +// +// } +// +// +// +// const ResourceEntityUpdates = new ResourceEntityUpdatesHandler() +// +// export default ResourceEntityUpdates diff --git a/modules/events-mod/src/main/typescript/main/events/surfaceUpdates.ts b/modules/events-mod/src/main/typescript/main/events/surfaceUpdates.ts index 9c90da5..a2bde69 100644 --- a/modules/events-mod/src/main/typescript/main/events/surfaceUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/surfaceUpdates.ts @@ -13,7 +13,7 @@ export function handleSurfaceUpdate( name: surface.name, index: surface.index, - daytime: surface.daytime + daytime: surface.daytime, } PacketEmitter.emitInstantPacket(update) diff --git a/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts b/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts index 618554a..f5caa89 100644 --- a/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts +++ b/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts @@ -6,7 +6,8 @@ export class KafkatorioSettingsConfig { private static eventCacheExpirationDefaultSeconds: Record = { "kafkatorio.packet.keyed.PlayerUpdate": 0.5, - "kafkatorio.packet.keyed.MapChunkUpdate": 30, + "kafkatorio.packet.keyed.MapChunkTileUpdate": 30, + "kafkatorio.packet.keyed.MapChunkEntityUpdate": 30, "kafkatorio.packet.keyed.EntityUpdate": 5, } @@ -21,7 +22,7 @@ export class KafkatorioSettingsConfig { public initialiseSettings(data: Data): void { for (const [type,] of pairs(KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds)) { data.extend( - [ KafkatorioSettingsConfig.createDefaultCacheDuration(type)] + [KafkatorioSettingsConfig.createDefaultCacheDuration(type)] ) } } diff --git a/modules/events-mod/src/main/typescript/main/types.d.ts b/modules/events-mod/src/main/typescript/main/types.d.ts index fcdc914..10270f3 100644 --- a/modules/events-mod/src/main/typescript/main/types.d.ts +++ b/modules/events-mod/src/main/typescript/main/types.d.ts @@ -1,6 +1,6 @@ import {KafkatorioPacketData} from "../generated/kafkatorio-schema"; -export type EventName = keyof typeof defines.events +export type DefinedEventName = keyof typeof defines.events /** Get all keys of `TYPE` that are not nullable. */ diff --git a/modules/events-mod/tsconfig.json b/modules/events-mod/tsconfig.json index 7036839..eaf883f 100644 --- a/modules/events-mod/tsconfig.json +++ b/modules/events-mod/tsconfig.json @@ -10,7 +10,8 @@ "types": [ "typescript-to-lua/language-extensions", "lua-types/5.2", - "typed-factorio/runtime" + "typed-factorio/runtime", + "typed-factorio/strict-index-types" ], "plugins": [ { @@ -32,8 +33,7 @@ "traceResolution": true, "noImplicitReturns": true, "noImplicitOverride": true, - "noFallthroughCasesInSwitch": true, - "skipLibCheck": true + "noFallthroughCasesInSwitch": true }, "tstl": { "luaTarget": "5.2", diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt index facbf6d..f1c547d 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt @@ -2,11 +2,13 @@ package dev.adamko.kafkatorio.server.processor import com.github.palindromicity.syslog.dsl.SyslogFieldKeys import dev.adamko.kafkatorio.server.config.ApplicationProperties +import dev.adamko.kafkatorio.server.processor.topology.broadcastToWebsocket import dev.adamko.kafkatorio.server.processor.topology.colourMapChunks -import dev.adamko.kafkatorio.server.processor.topology.* +import dev.adamko.kafkatorio.server.processor.topology.factorioServerPacketStream +import dev.adamko.kafkatorio.server.processor.topology.saveMapTiles +import dev.adamko.kafkatorio.server.processor.topology.splitFactorioServerPacketStream import dev.adamko.kafkatorio.server.socket.SyslogSocketServer import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer -import dev.adamko.kafkatorio.server.web.websocket.broadcastToWebsocket import java.util.Properties import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/admin/KafkatorioKafkaAdmin.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/admin/KafkatorioKafkaAdmin.kt index 071a52f..a052945 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/admin/KafkatorioKafkaAdmin.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/admin/KafkatorioKafkaAdmin.kt @@ -1,7 +1,7 @@ package dev.adamko.kafkatorio.server.processor.admin -import dev.adamko.kafkatorio.server.processor.allTopics import dev.adamko.kafkatorio.server.config.ApplicationProperties +import dev.adamko.kafkatorio.server.processor.allTopics import java.util.concurrent.TimeUnit import mu.KotlinLogging import org.apache.kafka.clients.admin.Admin diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt index 8dc6cf1..95b2be4 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt @@ -1,9 +1,9 @@ package dev.adamko.kafkatorio.server.processor -import dev.adamko.kafkatorio.server.socket.SyslogSocketServer -import dev.adamko.kafkatorio.server.processor.admin.KafkatorioKafkaAdmin import dev.adamko.kafkatorio.server.config.ApplicationProperties +import dev.adamko.kafkatorio.server.processor.admin.KafkatorioKafkaAdmin +import dev.adamko.kafkatorio.server.socket.SyslogSocketServer import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.coroutineScope @@ -27,11 +27,11 @@ suspend fun eventsProcessor( val topology = KafkatorioTopology(appProps, wsServer, syslogServer) - launch { - topology.start() + launch { + topology.start() - println("launched KafkatorioTopology") + println("launched KafkatorioTopology") - awaitCancellation() - } + awaitCancellation() + } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt index e25ee8f..8eb65a3 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt @@ -5,7 +5,8 @@ import dev.adamko.kafkatorio.schema.packets.ConsoleChatUpdate import dev.adamko.kafkatorio.schema.packets.ConsoleCommandUpdate import dev.adamko.kafkatorio.schema.packets.EntityUpdate import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData -import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate +import dev.adamko.kafkatorio.schema.packets.MapChunkEntityUpdate +import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate @@ -54,9 +55,10 @@ val KafkatorioPacketData.topicName: String is PrototypesUpdate -> packetTopicNames.getValue(PrototypesUpdate::class) is SurfaceUpdate -> packetTopicNames.getValue(SurfaceUpdate::class) is EntityUpdate -> packetTopicNames.getValue(EntityUpdate::class) - is MapChunkUpdate -> packetTopicNames.getValue(MapChunkUpdate::class) + is MapChunkTileUpdate -> packetTopicNames.getValue(MapChunkTileUpdate::class) is PlayerUpdate -> packetTopicNames.getValue(PlayerUpdate::class) is KafkatorioPacketData.Error -> packetTopicNames.getValue(KafkatorioPacketData.Error::class) + is MapChunkEntityUpdate -> packetTopicNames.getValue(MapChunkEntityUpdate::class) } @@ -67,12 +69,14 @@ private val packetTopicNames: Map, String> = ma PrototypesUpdate::class to "prototypes", SurfaceUpdate::class to "surface", EntityUpdate::class to "entity", - MapChunkUpdate::class to "map-chunk", + MapChunkTileUpdate::class to "map-chunk-tile", PlayerUpdate::class to "player", + MapChunkEntityUpdate::class to "map-chunk-entity", KafkatorioPacketData.Error::class to "error", ).mapValues { (_, v) -> "$DOMAIN.packet.$v" } + val KClass.topicName: String get() = packetTopicNames.getValue(this) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt index 5800e33..b4a7528 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt @@ -1,8 +1,5 @@ package dev.adamko.kafkatorio.server.processor.topology -import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_032_STATE -import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_STATE -import dev.adamko.kafkatorio.server.processor.DebounceProcessor.Companion.addDebounceProcessor import dev.adamko.kafkatorio.library.kxsBinary import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex @@ -10,8 +7,11 @@ import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.ServerMapChunkId import dev.adamko.kafkatorio.schema.common.leftTopTile import dev.adamko.kafkatorio.schema.common.toMapChunkPosition -import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate +import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate +import dev.adamko.kafkatorio.server.processor.DebounceProcessor.Companion.addDebounceProcessor +import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_032_STATE +import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_STATE import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedAs @@ -39,10 +39,10 @@ import org.apache.kafka.streams.kstream.KTable private const val pid: String = "colourMapChunks" -/** Add colour to each [MapChunkUpdate] */ +/** Add colour to each [MapChunkTileUpdate] */ fun colourMapChunks(builder: StreamsBuilder): Topology { - val mapChunksStream: KStream = builder.streamPacketData() + val mapChunksStream: KStream = builder.streamPacketData() val protosStream: KStream = builder.streamPacketData() val protosTable: KTable = @@ -78,7 +78,7 @@ fun colourMapChunks(builder: StreamsBuilder): Topology { ChunkSize.CHUNK_032 to ChunkSize.CHUNK_256, ChunkSize.CHUNK_256 to ChunkSize.CHUNK_512, - ).forEach { (from, to) -> + ).forEach { (from, to) -> chunkTilesColoured .filter("$pid.combine-chunks.filter-$from-to-$to") { key, _ -> key.chunkSize == from @@ -98,12 +98,12 @@ fun colourMapChunks(builder: StreamsBuilder): Topology { } -private fun KStream.convertToServerMapChunkTiles() +private fun KStream.convertToServerMapChunkTiles() : KStream> { val pid = "$pid.convertToMapTiles" - return map("$pid.map") { serverId: FactorioServerId, update: MapChunkUpdate -> + return map("$pid.map") { serverId: FactorioServerId, update: MapChunkTileUpdate -> val mapTileList = update.tileDictionary?.toMapTileList() ?: emptyList() @@ -112,7 +112,7 @@ private fun KStream.convertToServerMapChunkTil } if (invalidMapTilesList.isNotEmpty()) { - println("WARNING [reduceMapTilesToTable] MapChunkUpdate contained out-of-bounds tiles $invalidMapTilesList") + println("WARNING [reduceMapTilesToTable] MapChunkTileUpdate contained out-of-bounds tiles $invalidMapTilesList") } val validMapTilesToProtoHashCode = @@ -232,7 +232,7 @@ fun KTable>.streamMapChunkColou /** - * Group [MapChunkUpdate]s by the Chunk position. + * Group [MapChunkTileUpdate]s by the Chunk position. * * They should already be grouped, but do it again to make sure, and to filter out empty updates. */ diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt index 013f635..c7e4ae1 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt @@ -1,12 +1,12 @@ package dev.adamko.kafkatorio.server.processor.topology -import dev.adamko.kafkatorio.server.processor.TOPIC_SRC_SERVER_LOG -import dev.adamko.kafkatorio.server.processor.topicName -import dev.adamko.kafkatorio.server.config.jsonMapper import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData +import dev.adamko.kafkatorio.server.config.jsonMapper +import dev.adamko.kafkatorio.server.processor.TOPIC_SRC_SERVER_LOG +import dev.adamko.kafkatorio.server.processor.topicName import dev.adamko.kotka.extensions.component1 import dev.adamko.kotka.extensions.component2 import dev.adamko.kotka.extensions.consumedAs @@ -35,7 +35,7 @@ fun factorioServerPacketStream( val packet = runCatching { jsonMapper.decodeFromString(value) }.getOrElse { e -> - KafkatorioPacket( + KafkatorioPacket( modVersion = "unknown", tick = Tick(0u), data = KafkatorioPacketData.Error( diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/packetDataStreams.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/packetDataStreams.kt index 67a882a..f21625f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/packetDataStreams.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/packetDataStreams.kt @@ -1,10 +1,10 @@ package dev.adamko.kafkatorio.server.processor.topology -import dev.adamko.kafkatorio.server.processor.topicName -import dev.adamko.kafkatorio.server.config.jsonMapper import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData +import dev.adamko.kafkatorio.server.config.jsonMapper +import dev.adamko.kafkatorio.server.processor.topicName import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.mapValues diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/prototypes.kt index f74fab9..825f7b7 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/prototypes.kt @@ -22,8 +22,8 @@ import org.apache.kafka.streams.kstream.KTable @JvmInline @Serializable value class TileProtoHashCode private constructor(val code: Int) { - constructor(tile: MapTile) : this(tile.proto.hashCode()) - constructor(tile: FactorioPrototype.MapTile) : this(tile.name.hashCode()) + constructor(tile: MapTile) : this(tile.protoId.hashCode()) + constructor(tile: FactorioPrototype.MapTile) : this(tile.protoId.hashCode()) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt index 3d986dc..3592c58 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt @@ -3,15 +3,15 @@ package dev.adamko.kafkatorio.server.processor.topology import com.sksamuel.scrimage.ImmutableImage import com.sksamuel.scrimage.ScaleMethod import com.sksamuel.scrimage.nio.PngWriter -import dev.adamko.kafkatorio.server.processor.TOPIC_BROADCAST_TO_WEBSOCKET -import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_STATE -import dev.adamko.kafkatorio.server.config.jsonMapper import dev.adamko.kafkatorio.library.kxsBinary import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.ServerMapChunkId import dev.adamko.kafkatorio.schema.common.TilePngFilename import dev.adamko.kafkatorio.schema.packets.EventServerPacket +import dev.adamko.kafkatorio.server.config.jsonMapper +import dev.adamko.kafkatorio.server.processor.TOPIC_BROADCAST_TO_WEBSOCKET +import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_STATE import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.streams.map @@ -32,7 +32,7 @@ private const val WEB_MAP_TILE_SIZE_PX = 256 /** - * @param[serverDataDir] [dev.adamko.kafkatorio.processor.config.ApplicationProperties.serverDataDir] + * @param[serverDataDir] [dev.adamko.kafkatorio.server.config.ApplicationProperties.serverDataDir] */ fun saveMapTiles( builder: StreamsBuilder, diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/websocketBroadcaster.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/websocketBroadcaster.kt index 6783dd1..a173a26 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/websocketBroadcaster.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/websocketBroadcaster.kt @@ -1,13 +1,14 @@ -package dev.adamko.kafkatorio.server.web.websocket +package dev.adamko.kafkatorio.server.processor.topology import dev.adamko.kafkatorio.library.jsonMapperKafkatorio -import dev.adamko.kafkatorio.server.processor.TOPIC_BROADCAST_TO_WEBSOCKET -import dev.adamko.kafkatorio.server.processor.topicName import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.packets.EventServerPacket import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate +import dev.adamko.kafkatorio.server.processor.TOPIC_BROADCAST_TO_WEBSOCKET +import dev.adamko.kafkatorio.server.processor.topicName +import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.stream diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt index 7b518d5..86f3637 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt @@ -59,12 +59,14 @@ class SyslogSocketServer( launch { val channel = socket.openReadChannel() try { - while (socket.socketContext.isActive) { + while (socket.socketContext.isActive && !channel.isClosedForRead) { val line = runCatching { channel.readUTF8Line() }.fold( onSuccess = { line -> - log("received '$line' from $socket") + if (line != null) { + log("received '$line' from ${socket.description()}") + } line }, onFailure = { e -> diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt index 01035d2..906c692 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt @@ -10,9 +10,7 @@ import io.ktor.http.content.EntityTagVersion import io.ktor.http.content.versions import io.ktor.resources.Resource import io.ktor.server.application.ApplicationCall -import io.ktor.server.application.application import io.ktor.server.application.call -import io.ktor.server.application.log import io.ktor.server.http.content.LastModifiedVersion import io.ktor.server.resources.get import io.ktor.server.response.respond diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index 4c29a79..5ecf3ec 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -41,7 +41,9 @@ val deployModToLocalClient by tasks.registering(Copy::class) { description = "Copy the mod to the Factorio client" group = FactorioMod.TASK_GROUP - onlyIf { clientModsDirectory.orNull?.asFile?.exists() == true } + val clientModsDirectory123 = clientModsDirectory + + onlyIf { clientModsDirectory123.orNull?.asFile?.exists() == true } from(factorioMod) into(clientModsDirectory) @@ -61,9 +63,12 @@ val clientLaunch by tasks.registering(Exec::class) { description = "Run local Factorio Steam game client" group = FactorioMod.TASK_GROUP + val steamExe123 = steamExe + val clientModsDirectory444 = clientModsDirectory + onlyIf(!serviceOf().isFactorioRunning()) - onlyIf { steamExe.orNull?.asFile?.exists() == true } - onlyIf { clientModsDirectory.orNull?.asFile?.exists() == true } + onlyIf { steamExe123.orNull?.asFile?.exists() == true } + onlyIf { clientModsDirectory444.orNull?.asFile?.exists() == true } dependsOn(deployModToLocalClient) mustRunAfter(clientKill, ":modules:infra-factorio-server:processRun") diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index da16a1f..c6d1744 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -FACTORIO_VERSION=1.1.59 +FACTORIO_VERSION=1.1.61 KAFKATORIO_VERSION=0.6.1 diff --git a/modules/infra-factorio-server/src/docker-compose.yml b/modules/infra-factorio-server/src/docker-compose.yml index 34fd329..9e1e947 100644 --- a/modules/infra-factorio-server/src/docker-compose.yml +++ b/modules/infra-factorio-server/src/docker-compose.yml @@ -19,7 +19,7 @@ services: logging: driver: syslog options: - syslog-address: "tcp://host.docker.internal:12092" + syslog-address: "tcp://host.docker.internal:12034" syslog-format: "rfc5424" # environment: diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt index 077472f..7c94823 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -6,7 +6,7 @@ import dev.adamko.kafkatorio.schema.packets.ConsoleCommandUpdate import dev.adamko.kafkatorio.schema.packets.EntityUpdate import dev.adamko.kafkatorio.schema.packets.EventServerPacket import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData -import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate +import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate @@ -84,7 +84,7 @@ class WebsocketService( is PrototypesUpdate, is SurfaceUpdate, is EntityUpdate, - is MapChunkUpdate, + is MapChunkTileUpdate, is KafkatorioPacketData.Error -> { // to be continued... } From b9b6065735f5a1da7e9d65f624bb32d538aaeeb3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 16:18:48 +0200 Subject: [PATCH 447/629] try fixing projects must be configuring bug --- .../kafkatorio/lang/kotlin-js.gradle.kts | 25 +++++++++++++++++++ .../lang/kotlin-multiplatform.gradle.kts | 23 +++++++++++++++++ modules/web-map/build.gradle.kts | 16 +----------- 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts index 6d2168b..36e535b 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts @@ -2,7 +2,11 @@ package dev.adamko.kafkatorio.lang import dev.adamko.kafkatorio.Versions import dev.adamko.kafkatorio.relocateKotlinJsStore +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject +import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension + //import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask @@ -42,4 +46,25 @@ plugins { // file //} + relocateKotlinJsStore() + + +plugins.withType { + configure { + nodeVersion = "16.0.0" + } +} + + +afterEvaluate { + rootProject.extensions.configure { + // https://github.com/rjaros/kvision/issues/410 + versions.webpackCli.version = "4.10.0" + versions.webpackDevServer.version = "4.9.2" + } + + rootProject.extensions.configure { + resolution("http-proxy-middleware", "^2.0.6") + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts index 478bd24..dc77fd0 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts @@ -1,6 +1,9 @@ package dev.adamko.kafkatorio.lang import dev.adamko.kafkatorio.relocateKotlinJsStore +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin +import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension plugins { @@ -11,3 +14,23 @@ plugins { relocateKotlinJsStore() + + +plugins.withType { + configure { + nodeVersion = "16.0.0" + } +} + + +afterEvaluate { + rootProject.extensions.configure { + // https://github.com/rjaros/kvision/issues/410 + versions.webpackCli.version = "4.10.0" + versions.webpackDevServer.version = "4.9.2" + } + + rootProject.extensions.configure { + resolution("http-proxy-middleware", "^2.0.6") + } +} diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index ef2b535..97082ac 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -1,7 +1,5 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig -import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension plugins { @@ -17,18 +15,6 @@ kvision { } -afterEvaluate { - rootProject.extensions.configure { - // https://github.com/rjaros/kvision/issues/410 - versions.webpackCli.version = "4.10.0" - versions.webpackDevServer.version = "4.9.2" - } - - rootProject.extensions.configure { - resolution("http-proxy-middleware", "^2.0.6") - } -} - kotlin { js(IR) { browser { @@ -124,7 +110,7 @@ kotlin { test { dependencies { - implementation(kotlin("test-js")) + implementation(kotlin("test")) kvision("kvision-testutils") // implementation(npm("karma", "^6.3.16")) From 5a304245f1aa27e5a7c0ef868db88cc43c76c618 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 16:20:11 +0200 Subject: [PATCH 448/629] bump kvision, js wrappers. organise dependencies --- gradle/kotlin-js-store/yarn.lock | 42 +++++++-------- gradle/libs.versions.toml | 59 ++++++++-------------- modules/events-library/build.gradle.kts | 8 +-- modules/versions-platform/build.gradle.kts | 14 +++-- 4 files changed, 55 insertions(+), 68 deletions(-) diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index bc40042..6b8baf8 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -551,10 +551,10 @@ bonjour-service@^1.0.11: fast-deep-equal "^3.1.3" multicast-dns "^7.2.5" -bootstrap-icons@^1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.8.1.tgz#773c1625bcbf3e86090ea9da4386c2c6459c5582" - integrity sha512-IXUqislddPJfwq6H+2nTkHyr9epO9h6u1AG0OZCx616w+TgzeoCjfmI3qJMQqt1J586gN2IxzB4M99Ip4sTZ1w== +bootstrap-icons@^1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.8.3.tgz#14c15e26deaddd42af9f88c4d81f7c45bf26aa98" + integrity sha512-s5kmttnbq4BXbx3Bwnj39y+t7Vc3blTtyD77W3aYQ1LlNoS3lNbbGvSYhIbg26Im8KmjScyFpHEevlPOBcIDdA== bootstrap@^5.1.3: version "5.1.3" @@ -771,10 +771,10 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -connect-history-api-fallback@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" - integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== +connect-history-api-fallback@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" + integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== connect@^3.7.0: version "3.7.0" @@ -1795,10 +1795,10 @@ kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -kvision-assets@^5.0.8: - version "5.0.8" - resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-5.0.8.tgz#f2220135a94b1330cb2ac8f1804b53f40a9bd711" - integrity sha512-umq47D8z2W7cTYR/6RtJ+048mlsi5X515tcM/PFgDcbaI82Pd9EHv2m9520SxmBH6AD04GTweWNyUcKlPx9oZQ== +kvision-assets@^5.0.9: + version "5.0.9" + resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-5.0.9.tgz#6f305e4c085a4eab57897f6741c208121e9b035c" + integrity sha512-pMbKmlGbc6FYtJVPbH6oKXWFOp6O6Uljhi6KODs4AGuIiqZxhjXKXwMEhaaLzheuP5/bu0hNYWa4LGSwcvIOJQ== leaflet@^1.8.0: version "1.8.0" @@ -2544,10 +2544,10 @@ signal-exit@^3.0.3: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -snabbdom@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.5.0.tgz#e75acbdedb26ea327c75028a433ba064db0ccf6e" - integrity sha512-Ff5BKG18KrrPuskHJlA9aujPHqEabItaDl96l7ZZndF4zt5AYSczz7ZjjgQAX5IBd5cd25lw9NfgX21yVUJ+9g== +snabbdom@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.5.1.tgz#25f80ef15b194baea703d9d5441892e369de18e1" + integrity sha512-wHMNIOjkm/YNE5EM3RCbr/+DVgPg6AqQAX1eOxO46zYNvCXjKP5Y865tqQj3EXnaMBjkxmQA5jFuDpDK/dbfiA== socket.io-adapter@~2.4.0: version "2.4.0" @@ -2908,10 +2908,10 @@ webpack-dev-middleware@^5.3.1: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@4.9.2: - version "4.9.2" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.9.2.tgz#c188db28c7bff12f87deda2a5595679ebbc3c9bc" - integrity sha512-H95Ns95dP24ZsEzO6G9iT+PNw4Q7ltll1GfJHV4fKphuHWgKFzGHWi4alTlTnpk1SPPk41X+l2RB7rLfIhnB9Q== +webpack-dev-server@4.9.3: + version "4.9.3" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.9.3.tgz#2360a5d6d532acb5410a668417ad549ee3b8a3c9" + integrity sha512-3qp/eoboZG5/6QgiZ3llN8TUzkSpYg1Ko9khWX1h40MIEUNS2mDoIa8aXsPfskER+GbTvs/IJZ1QTBBhhuetSw== dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5" @@ -2925,7 +2925,7 @@ webpack-dev-server@4.9.2: chokidar "^3.5.3" colorette "^2.0.10" compression "^1.7.4" - connect-history-api-fallback "^1.6.0" + connect-history-api-fallback "^2.0.0" default-gateway "^6.0.3" express "^4.17.3" graceful-fs "^4.2.6" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a4a42ab..fa2fbf6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,20 +12,20 @@ kotlin = "1.7.0" camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" kafka = "3.2.0" -kvision = "5.11.0" +kvision = "5.12.0" log4j2 = "2.17.2" -qosLogback = "1.2.11" -slf4j = "1.7.36" okio = "3.2.0" +qosLogback = "1.2.11" scrimage = "4.0.31" semver = "1.2.0" +slf4j = "1.7.36" kotlinx-serialization = "1.3.3" kxs-charleskornKaml = "0.44.0" kxs-mamoeYamlkt = "0.12.0" kxs-kxsTsGen = "0.2.1" -kotlinJsWrappers = "1.0.0-pre.349" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom +kotlinJsWrappers = "1.0.0-pre.351" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom kotlinx-cli = "0.3.4" kotlinx-coroutines = "1.6.3" @@ -41,6 +41,7 @@ simpleSyslogParser = "0.0.6" kotkaStreams = "dev-SNAPSHOT" +marykRocksDb = "7.3.1" # https://search.maven.org/artifact/io.maryk.rocksdb/rocksdb-multiplatform ## test ## junit = "5.8.2" @@ -204,7 +205,7 @@ kafka-streamsTestUtils = { group = "org.apache.kafka", name = "kafka-streams-tes kafka-kotkaStreams = { group = "dev.adamko.kotka", name = "kotka-streams", version.ref = "kotkaStreams" } -rocksdb = { group = "io.maryk.rocksdb", name = "rocksdb-multiplatform", version = "7.0.3" } +mary-rocksdb = { group = "io.maryk.rocksdb", name = "rocksdb-multiplatform", version.ref = "marykRocksDb" } jsoup = { group = "org.jsoup", name = "jsoup", version = "1.14.3" } skrapeit = { group = "it.skrape", name = "skrapeit", version = "1.2.0" } @@ -239,12 +240,13 @@ junit-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine" junit-launcher = { group = "org.junit.platform", name = "junit-platform-launcher" } # version = "1.7.2" } ## kotest ## -kotest-bom = { group = "io.kotest", name = "kotest-bom", version.ref = "kotest" } -kotest-core = { group = "io.kotest", name = "kotest-assertions-core", version.ref = "kotest" } -kotest-datatest = { group = "io.kotest", name = "kotest-framework-datatest", version.ref = "kotest" } -kotest-runner = { group = "io.kotest", name = "kotest-runner-junit5", version.ref = "kotest" } -kotest-prop = { group = "io.kotest", name = "kotest-property", version.ref = "kotest" } -kotest-json = { group = "io.kotest", name = "kotest-assertions-json", version.ref = "kotest" } +kotest-bom = { group = "io.kotest", name = "kotest-bom", version.ref = "kotest" } +kotest-core = { group = "io.kotest", name = "kotest-assertions-core" } +kotest-datatest = { group = "io.kotest", name = "kotest-framework-datatest" } +kotest-json = { group = "io.kotest", name = "kotest-assertions-json" } +kotest-prop = { group = "io.kotest", name = "kotest-property" } +kotest-frameworkEngine = { group = "io.kotest", name = "kotest-framework-engine" } +kotest-runnerJunit5 = { group = "io.kotest", name = "kotest-runner-junit5" } ## http4k ## http4k-test-chaos = { group = "org.http4k", name = "http4k-testing-chaos", version.ref = "http4k" } @@ -264,39 +266,20 @@ logging = [ "logback-encoder", ] -kt-testing = [ - "kotest-core", - "kotest-datatest", - "kotest-runner", - "kotest-prop", - "kotest-json", - "mockk", -] +#kt-testing = [ +# "kotest-core", +# "kotest-datatest", +# "kotest-runner", +# "kotest-prop", +# "kotest-json", +# "mockk", +#] junit-runtime = [ "junit-engine", "junit-launcher", ] -http4k = [ - "http4k-core", - "http4k-contract", - "http4k-client-okhttp", - "http4k-client-ws", - "http4k-server", - "http4k-cloudnative", -# "http4k-format-jackson-xml", -# "http4k-format-jackson-json", -# "http4k-format-jackson-yaml", - "http4k-format-kotlinx", -] - -http4k-test = [ - "http4k-test-chaos", - "http4k-test-approval", - "http4k-test-kotest", -] - kotlinScripting-def = [ "kotlinScripting-common", "kotlinScripting-jvm", diff --git a/modules/events-library/build.gradle.kts b/modules/events-library/build.gradle.kts index b99515a..bd304c5 100644 --- a/modules/events-library/build.gradle.kts +++ b/modules/events-library/build.gradle.kts @@ -71,11 +71,11 @@ kotlin { implementation(kotlin("test")) implementation(project.dependencies.platform(libs.kotest.bom)) - implementation("io.kotest:kotest-framework-engine") implementation(libs.kotest.core) implementation(libs.kotest.datatest) - implementation(libs.kotest.prop) + implementation(libs.kotest.frameworkEngine) implementation(libs.kotest.json) + implementation(libs.kotest.prop) } } @@ -87,13 +87,13 @@ kotlin { val jvmTest by getting { dependencies { - implementation("io.kotest:kotest-runner-junit5") + implementation(libs.kotest.runnerJunit5) } } val jsTest by getting { dependencies { - implementation(kotlin("test-js")) +// implementation(kotlin("test-js")) } } } diff --git a/modules/versions-platform/build.gradle.kts b/modules/versions-platform/build.gradle.kts index 593c4b9..54222d2 100644 --- a/modules/versions-platform/build.gradle.kts +++ b/modules/versions-platform/build.gradle.kts @@ -22,15 +22,19 @@ dependencies { api(platform(libs.kotest.bom)) constraints { - api(libs.skrapeit) - api(libs.kxs.charleskornKaml) - api(libs.kxs.mamoeYamlkt) api(libs.kafka.kotkaStreams) api(libs.kafka.streams) - api(libs.okio.core) - api(libs.scrimage.core) api(libs.kafka.streamsTestUtils) + api(libs.kxs.charleskornKaml) + api(libs.kxs.mamoeYamlkt) + + api(libs.okio.core) + + api(libs.scrimage.core) + + api(libs.skrapeit) + api(libs.mockk) } } From 412cf150979dbd0012ebccaf02ec019cf2907741 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 16:20:29 +0200 Subject: [PATCH 449/629] fix tests after The Big Entity Refactor --- .../events/schema/PrototypesTest.kt | 502 ++++++++++++++---- .../events/schema/UpdatePacketsTest.kt | 2 +- .../common/MapChunkPositionBoundsTest.kt | 8 +- .../schema/common/MapTileDictionaryTest.kt | 18 +- 4 files changed, 398 insertions(+), 132 deletions(-) diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt index 022e939..922362e 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt @@ -25,12 +25,19 @@ class PrototypesTest : BehaviorSpec({ "prototypes": [ { "type": "kafkatorio.prototype.MapTile", - "name": "tile-unknown", - "order": "z-a", - "layer": 0, - "collisionMasks": {}, - "mapColour": [0, 0, 0, 255], - "canBeMined": false + "protoId": "tile/stone-path", + "order": "a[artificial]-a[tier-1]-a[stone-path]", + "layer": 60, + "collisionMasks": [ + "ground-tile" + ], + "mapColour": [ + 86, + 82, + 74, + 255 + ], + "canBeMined": true } ] } @@ -48,432 +55,619 @@ class PrototypesTest : BehaviorSpec({ // language=JSON val raw = """ { - "modVersion": "0.3.2", - "tick": 534, "data": { - "type": "kafkatorio.packet.instant.PrototypesUpdate", "prototypes": [ { "type": "kafkatorio.prototype.MapTile", - "name": "stone-path", + "protoId": "tile/stone-path", "order": "a[artificial]-a[tier-1]-a[stone-path]", "layer": 60, "collisionMasks": [ "ground-tile" ], - "mapColour": [86, 82, 74, 255], + "mapColour": [ + 86, + 82, + 74, + 255 + ], "canBeMined": true }, { "type": "kafkatorio.prototype.MapTile", - "name": "concrete", + "protoId": "tile/concrete", "order": "a[artificial]-b[tier-2]-a[concrete]", "layer": 61, "collisionMasks": [ "ground-tile" ], - "mapColour": [63, 61, 59, 255], + "mapColour": [ + 63, + 61, + 59, + 255 + ], "canBeMined": true }, { "type": "kafkatorio.prototype.MapTile", - "name": "hazard-concrete-left", + "protoId": "tile/hazard-concrete-left", "order": "a[artificial]-b[tier-2]-b[hazard-concrete-left]", "layer": 62, "collisionMasks": [ "ground-tile" ], - "mapColour": [176, 142, 39, 255], + "mapColour": [ + 176, + 142, + 39, + 255 + ], "canBeMined": true }, { "type": "kafkatorio.prototype.MapTile", - "name": "hazard-concrete-right", + "protoId": "tile/hazard-concrete-right", "order": "a[artificial]-b[tier-2]-c[hazard-concrete-right]", "layer": 62, "collisionMasks": [ "ground-tile" ], - "mapColour": [176, 142, 39, 255], + "mapColour": [ + 176, + 142, + 39, + 255 + ], "canBeMined": true }, { "type": "kafkatorio.prototype.MapTile", - "name": "refined-concrete", + "protoId": "tile/refined-concrete", "order": "a[artificial]-c[tier-3]-a[refined-concrete]", "layer": 64, "collisionMasks": [ "ground-tile" ], - "mapColour": [49, 48, 45, 255], + "mapColour": [ + 49, + 48, + 45, + 255 + ], "canBeMined": true }, { "type": "kafkatorio.prototype.MapTile", - "name": "refined-hazard-concrete-left", + "protoId": "tile/refined-hazard-concrete-left", "order": "a[artificial]-c[tier-3]-b[refined-hazard-concrete-left]", "layer": 65, "collisionMasks": [ "ground-tile" ], - "mapColour": [116, 94, 26, 255], + "mapColour": [ + 116, + 94, + 26, + 255 + ], "canBeMined": true }, { "type": "kafkatorio.prototype.MapTile", - "name": "refined-hazard-concrete-right", + "protoId": "tile/refined-hazard-concrete-right", "order": "a[artificial]-c[tier-3]-c[refined-hazard-concrete-right]", "layer": 65, "collisionMasks": [ "ground-tile" ], - "mapColour": [116, 94, 26, 255], + "mapColour": [ + 116, + 94, + 26, + 255 + ], "canBeMined": true }, { "type": "kafkatorio.prototype.MapTile", - "name": "landfill", + "protoId": "tile/landfill", "order": "a[artificial]-d[utility]-a[landfill]", "layer": 57, "collisionMasks": [ "ground-tile" ], - "mapColour": [57, 39, 26, 255], + "mapColour": [ + 57, + 39, + 26, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "acid-refined-concrete", + "protoId": "tile/acid-refined-concrete", "order": "a[artificial]-e[color-concrete]-acid", "layer": 97, "collisionMasks": [ "ground-tile" ], - "mapColour": [142, 194, 40, 127], + "mapColour": [ + 142, + 194, + 40, + 127 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "black-refined-concrete", + "protoId": "tile/black-refined-concrete", "order": "a[artificial]-e[color-concrete]-black", "layer": 88, "collisionMasks": [ "ground-tile" ], - "mapColour": [25, 25, 25, 127], + "mapColour": [ + 25, + 25, + 25, + 127 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "blue-refined-concrete", + "protoId": "tile/blue-refined-concrete", "order": "a[artificial]-e[color-concrete]-blue", "layer": 73, "collisionMasks": [ "ground-tile" ], - "mapColour": [39, 137, 228, 127], + "mapColour": [ + 39, + 137, + 228, + 127 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "brown-refined-concrete", + "protoId": "tile/brown-refined-concrete", "order": "a[artificial]-e[color-concrete]-brown", "layer": 91, "collisionMasks": [ "ground-tile" ], - "mapColour": [76, 29, 0, 127], + "mapColour": [ + 76, + 29, + 0, + 127 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "cyan-refined-concrete", + "protoId": "tile/cyan-refined-concrete", "order": "a[artificial]-e[color-concrete]-cyan", "layer": 94, "collisionMasks": [ "ground-tile" ], - "mapColour": [70, 192, 181, 127], + "mapColour": [ + 70, + 192, + 181, + 127 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "green-refined-concrete", + "protoId": "tile/green-refined-concrete", "order": "a[artificial]-e[color-concrete]-green", "layer": 70, "collisionMasks": [ "ground-tile" ], - "mapColour": [23, 195, 43, 127], + "mapColour": [ + 23, + 195, + 43, + 127 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "orange-refined-concrete", + "protoId": "tile/orange-refined-concrete", "order": "a[artificial]-e[color-concrete]-orange", "layer": 76, "collisionMasks": [ "ground-tile" ], - "mapColour": [221, 127, 33, 127], + "mapColour": [ + 221, + 127, + 33, + 127 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "pink-refined-concrete", + "protoId": "tile/pink-refined-concrete", "order": "a[artificial]-e[color-concrete]-pink", "layer": 82, "collisionMasks": [ "ground-tile" ], - "mapColour": [236, 98, 131, 127], + "mapColour": [ + 236, + 98, + 131, + 127 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "purple-refined-concrete", + "protoId": "tile/purple-refined-concrete", "order": "a[artificial]-e[color-concrete]-purple", "layer": 85, "collisionMasks": [ "ground-tile" ], - "mapColour": [123, 28, 168, 127], + "mapColour": [ + 123, + 28, + 168, + 127 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "red-refined-concrete", + "protoId": "tile/red-refined-concrete", "order": "a[artificial]-e[color-concrete]-red", "layer": 67, "collisionMasks": [ "ground-tile" ], - "mapColour": [207, 6, 0, 127], + "mapColour": [ + 207, + 6, + 0, + 127 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "yellow-refined-concrete", + "protoId": "tile/yellow-refined-concrete", "order": "a[artificial]-e[color-concrete]-yellow", "layer": 79, "collisionMasks": [ "ground-tile" ], - "mapColour": [212, 169, 19, 127], + "mapColour": [ + 212, + 169, + 19, + 127 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "grass-1", + "protoId": "tile/grass-1", "order": "b[natural]-a[grass]-a[grass-1]", "layer": 26, "collisionMasks": [ "ground-tile" ], - "mapColour": [55, 53, 11, 255], + "mapColour": [ + 55, + 53, + 11, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "grass-2", + "protoId": "tile/grass-2", "order": "b[natural]-a[grass]-b[grass-2]", "layer": 28, "collisionMasks": [ "ground-tile" ], - "mapColour": [66, 57, 15, 255], + "mapColour": [ + 66, + 57, + 15, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "grass-3", + "protoId": "tile/grass-3", "order": "b[natural]-a[grass]-c[grass-3]", "layer": 29, "collisionMasks": [ "ground-tile" ], - "mapColour": [65, 52, 28, 255], + "mapColour": [ + 65, + 52, + 28, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "grass-4", + "protoId": "tile/grass-4", "order": "b[natural]-a[grass]-d[grass-4]", "layer": 30, "collisionMasks": [ "ground-tile" ], - "mapColour": [59, 40, 18, 255], + "mapColour": [ + 59, + 40, + 18, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "dry-dirt", + "protoId": "tile/dry-dirt", "order": "b[natural]-b[dirt]-a[dry-dirt]", "layer": 18, "collisionMasks": [ "ground-tile" ], - "mapColour": [94, 66, 37, 255], + "mapColour": [ + 94, + 66, + 37, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "dirt-1", + "protoId": "tile/dirt-1", "order": "b[natural]-b[dirt]-b[dirt-1]", "layer": 19, "collisionMasks": [ "ground-tile" ], - "mapColour": [141, 104, 60, 255], + "mapColour": [ + 141, + 104, + 60, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "dirt-2", + "protoId": "tile/dirt-2", "order": "b[natural]-b[dirt]-c[dirt-2]", "layer": 20, "collisionMasks": [ "ground-tile" ], - "mapColour": [136, 96, 59, 255], + "mapColour": [ + 136, + 96, + 59, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "dirt-3", + "protoId": "tile/dirt-3", "order": "b[natural]-b[dirt]-d[dirt-3]", "layer": 21, "collisionMasks": [ "ground-tile" ], - "mapColour": [133, 92, 53, 255], + "mapColour": [ + 133, + 92, + 53, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "dirt-4", + "protoId": "tile/dirt-4", "order": "b[natural]-b[dirt]-e[dirt-4]", "layer": 22, "collisionMasks": [ "ground-tile" ], - "mapColour": [103, 72, 43, 255], + "mapColour": [ + 103, + 72, + 43, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "dirt-5", + "protoId": "tile/dirt-5", "order": "b[natural]-b[dirt]-f[dirt-5]", "layer": 23, "collisionMasks": [ "ground-tile" ], - "mapColour": [91, 63, 38, 255], + "mapColour": [ + 91, + 63, + 38, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "dirt-6", + "protoId": "tile/dirt-6", "order": "b[natural]-b[dirt]-g[dirt-6]", "layer": 24, "collisionMasks": [ "ground-tile" ], - "mapColour": [80, 55, 31, 255], + "mapColour": [ + 80, + 55, + 31, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "dirt-7", + "protoId": "tile/dirt-7", "order": "b[natural]-b[dirt]-h[dirt-7]", "layer": 25, "collisionMasks": [ "ground-tile" ], - "mapColour": [80, 54, 28, 255], + "mapColour": [ + 80, + 54, + 28, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "sand-1", + "protoId": "tile/sand-1", "order": "b[natural]-c[sand]-a[sand-1]", "layer": 8, "collisionMasks": [ "ground-tile" ], - "mapColour": [138, 103, 58, 255], + "mapColour": [ + 138, + 103, + 58, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "sand-2", + "protoId": "tile/sand-2", "order": "b[natural]-c[sand]-b[sand-2]", "layer": 9, "collisionMasks": [ "ground-tile" ], - "mapColour": [128, 93, 52, 255], + "mapColour": [ + 128, + 93, + 52, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "sand-3", + "protoId": "tile/sand-3", "order": "b[natural]-c[sand]-c[sand-3]", "layer": 10, "collisionMasks": [ "ground-tile" ], - "mapColour": [115, 83, 47, 255], + "mapColour": [ + 115, + 83, + 47, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "red-desert-0", + "protoId": "tile/red-desert-0", "order": "b[natural]-d[red-desert]-a[red-desert-0]", "layer": 31, "collisionMasks": [ "ground-tile" ], - "mapColour": [103, 70, 32, 255], + "mapColour": [ + 103, + 70, + 32, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "red-desert-1", + "protoId": "tile/red-desert-1", "order": "b[natural]-d[red-desert]-b[red-desert-1]", "layer": 14, "collisionMasks": [ "ground-tile" ], - "mapColour": [116, 81, 39, 255], + "mapColour": [ + 116, + 81, + 39, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "red-desert-2", + "protoId": "tile/red-desert-2", "order": "b[natural]-d[red-desert]-c[red-desert-2]", "layer": 15, "collisionMasks": [ "ground-tile" ], - "mapColour": [116, 84, 43, 255], + "mapColour": [ + 116, + 84, + 43, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "red-desert-3", + "protoId": "tile/red-desert-3", "order": "b[natural]-d[red-desert]-d[red-desert-3]", "layer": 16, "collisionMasks": [ "ground-tile" ], - "mapColour": [128, 93, 52, 255], + "mapColour": [ + 128, + 93, + 52, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "water", + "protoId": "tile/water", "order": "c[water]-a[water]", "layer": 3, "collisionMasks": [ @@ -483,12 +677,17 @@ class PrototypesTest : BehaviorSpec({ "resource-layer", "water-tile" ], - "mapColour": [51, 83, 95, 255], + "mapColour": [ + 51, + 83, + 95, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "deepwater", + "protoId": "tile/deepwater", "order": "c[water]-b[deep-water]", "layer": 3, "collisionMasks": [ @@ -498,12 +697,17 @@ class PrototypesTest : BehaviorSpec({ "resource-layer", "water-tile" ], - "mapColour": [38, 64, 73, 255], + "mapColour": [ + 38, + 64, + 73, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "water-green", + "protoId": "tile/water-green", "order": "c[water]-c[water-green]", "layer": 3, "collisionMasks": [ @@ -513,12 +717,17 @@ class PrototypesTest : BehaviorSpec({ "resource-layer", "water-tile" ], - "mapColour": [31, 48, 18, 255], + "mapColour": [ + 31, + 48, + 18, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "deepwater-green", + "protoId": "tile/deepwater-green", "order": "c[water]-d[deepwater-green]", "layer": 3, "collisionMasks": [ @@ -528,12 +737,17 @@ class PrototypesTest : BehaviorSpec({ "resource-layer", "water-tile" ], - "mapColour": [23, 37, 16, 255], + "mapColour": [ + 23, + 37, + 16, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "water-shallow", + "protoId": "tile/water-shallow", "order": "c[water]-e[water-shallow]", "layer": 6, "collisionMasks": [ @@ -542,12 +756,17 @@ class PrototypesTest : BehaviorSpec({ "resource-layer", "water-tile" ], - "mapColour": [82, 98, 92, 255], + "mapColour": [ + 82, + 98, + 92, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "water-mud", + "protoId": "tile/water-mud", "order": "c[water]-g[water-mud]", "layer": 7, "collisionMasks": [ @@ -556,23 +775,33 @@ class PrototypesTest : BehaviorSpec({ "resource-layer", "water-tile" ], - "mapColour": [65, 89, 90, 255], + "mapColour": [ + 65, + 89, + 90, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "nuclear-ground", + "protoId": "tile/nuclear-ground", "order": "d[destruction]-a[nuclear]-a[nuclear-ground]", "layer": 33, "collisionMasks": [ "ground-tile" ], - "mapColour": [48, 40, 35, 255], + "mapColour": [ + 48, + 40, + 35, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "water-wube", + "protoId": "tile/water-wube", "order": "x[wube]-a[water-wube]", "layer": 2, "collisionMasks": [ @@ -582,22 +811,31 @@ class PrototypesTest : BehaviorSpec({ "resource-layer", "water-tile" ], - "mapColour": [0, 0, 0, 255], + "mapColour": [ + 0, + 0, + 0, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "tile-unknown", + "protoId": "tile/tile-unknown", "order": "z-a", "layer": 0, - "collisionMasks": { - }, - "mapColour": [0, 0, 0, 255], + "collisionMasks": {}, + "mapColour": [ + 0, + 0, + 0, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "out-of-map", + "protoId": "tile/out-of-map", "order": "z[other]-a[out-of-map]", "layer": 0, "collisionMasks": [ @@ -610,55 +848,83 @@ class PrototypesTest : BehaviorSpec({ "resource-layer", "water-tile" ], - "mapColour": [0, 0, 0, 255], + "mapColour": [ + 0, + 0, + 0, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "lab-dark-1", + "protoId": "tile/lab-dark-1", "order": "z[other]-b[lab]-a[lab-dark-1]", "layer": 70, "collisionMasks": [ "ground-tile" ], - "mapColour": [49, 49, 49, 255], + "mapColour": [ + 49, + 49, + 49, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "lab-dark-2", + "protoId": "tile/lab-dark-2", "order": "z[other]-b[lab]-b[lab-dark-2]", "layer": 70, "collisionMasks": [ "ground-tile" ], - "mapColour": [0, 0, 0, 255], + "mapColour": [ + 0, + 0, + 0, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "lab-white", + "protoId": "tile/lab-white", "order": "z[other]-b[lab]-c[lab-white]", "layer": 70, "collisionMasks": [ "ground-tile" ], - "mapColour": [255, 255, 255, 255], + "mapColour": [ + 255, + 255, + 255, + 255 + ], "canBeMined": false }, { "type": "kafkatorio.prototype.MapTile", - "name": "tutorial-grid", + "protoId": "tile/tutorial-grid", "order": "z[other]-c[tutorial]-a[tutorial-grid]", "layer": 55, "collisionMasks": [ "ground-tile" ], - "mapColour": [122, 122, 122, 255], + "mapColour": [ + 122, + 122, + 122, + 255 + ], "canBeMined": false } - ] - } + ], + "type": "kafkatorio.packet.instant.PrototypesUpdate" + }, + "modVersion": "0.6.1", + "tick": 58468 } """.trimIndent() @@ -670,7 +936,7 @@ class PrototypesTest : BehaviorSpec({ .prototypes .forOne { it.shouldBeInstanceOf() - it.protoId shouldBe PrototypeId.MapTile("tutorial-grid") + it.protoId shouldBe PrototypeId("tile", "tutorial-grid") it.order shouldBe "z[other]-c[tutorial]-a[tutorial-grid]" it.layer shouldBe 55u it.collisionMasks shouldBe listOf("ground-tile") diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt index b1f2e17..e480379 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt @@ -191,7 +191,7 @@ class UpdatePacketsTest : FunSpec({ colour = null, diedCause = EntityIdentifiersData( unitNumber = UnitNumber(66u), - protoId = PrototypeId("unit/small-biter"), + protoId = PrototypeId("unit", "small-biter"), ), disconnectReason = null, events = mapOf( diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt index 565818b..0e543a6 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt @@ -116,11 +116,11 @@ class MapChunkPositionBoundsTest : FunSpec({ "44" to mapOf("1" to MapTileDictionary.PrototypeKey(44)), ), protos = mapOf( - PrototypeName("water") to MapTileDictionary.PrototypeKey(1), - PrototypeName("grass-4") to MapTileDictionary.PrototypeKey(2), - PrototypeName("grass-3") to MapTileDictionary.PrototypeKey(32), + PrototypeId("tile", "water") to MapTileDictionary.PrototypeKey(1), + PrototypeId("tile", "grass-4") to MapTileDictionary.PrototypeKey(2), + PrototypeId("tile", "grass-3") to MapTileDictionary.PrototypeKey(32), - PrototypeName("not-used") to MapTileDictionary.PrototypeKey(99), + PrototypeId("tile", "not-used") to MapTileDictionary.PrototypeKey(99), ) ) diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt index c611056..0822dc7 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt @@ -20,22 +20,22 @@ class MapTileDictionaryTest : FunSpec({ "44" to mapOf("1" to MapTileDictionary.PrototypeKey(44)), ), protos = mapOf( - PrototypeId.MapTile("water") to MapTileDictionary.PrototypeKey(1), - PrototypeId.MapTile("grass-4") to MapTileDictionary.PrototypeKey(2), - PrototypeId.MapTile("grass-3") to MapTileDictionary.PrototypeKey(32), + PrototypeId("tile", "water") to MapTileDictionary.PrototypeKey(1), + PrototypeId("tile", "grass-4") to MapTileDictionary.PrototypeKey(2), + PrototypeId("tile", "grass-3") to MapTileDictionary.PrototypeKey(32), - PrototypeId.MapTile("not-used") to MapTileDictionary.PrototypeKey(99), + PrototypeId("tile", "not-used") to MapTileDictionary.PrototypeKey(99), ) ) test("toMapTileList") { actual.toMapTileList() shouldContainAll listOf( - MapTile(-192, -65, PrototypeId.MapTile("grass-4")), + MapTile(-192, -65, PrototypeId("tile", "grass-4")), - MapTile(161, -96, PrototypeId.MapTile("water")), - MapTile(161, -95, PrototypeId.MapTile("grass-4")), - MapTile(161, 94, PrototypeId.MapTile("grass-4")), - MapTile(161, 93, PrototypeId.MapTile("grass-3")), + MapTile(161, -96, PrototypeId("tile", "water")), + MapTile(161, -95, PrototypeId("tile", "grass-4")), + MapTile(161, 94, PrototypeId("tile", "grass-4")), + MapTile(161, 93, PrototypeId("tile", "grass-3")), ) } } From d9e9e1af7dc6664425517f23b66d0e63a88328ea Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 16:21:07 +0200 Subject: [PATCH 450/629] close socket if null received --- .../adamko/kafkatorio/server/socket/SyslogSocketServer.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt index 86f3637..38a6944 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt @@ -64,8 +64,12 @@ class SyslogSocketServer( channel.readUTF8Line() }.fold( onSuccess = { line -> - if (line != null) { - log("received '$line' from ${socket.description()}") + when (line) { + null -> { + log("received 'null' from ${socket.description()} - closing connection") + socket.close() + } + else -> log("received '$line' from ${socket.description()}") } line }, From 1b3966cc4fe944e53ef429f20eb0b07fbbaaeb43 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 16:21:25 +0200 Subject: [PATCH 451/629] filter kotka-streams repo --- buildSrc/repositories.settings.gradle.kts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/buildSrc/repositories.settings.gradle.kts b/buildSrc/repositories.settings.gradle.kts index 3568925..874aff0 100644 --- a/buildSrc/repositories.settings.gradle.kts +++ b/buildSrc/repositories.settings.gradle.kts @@ -32,7 +32,9 @@ dependencyResolutionManagement { content { includeModule("com.yarnpkg", "yarn") } } - maven("https://raw.githubusercontent.com/adamko-dev/kotka-streams/artifacts/m2") + maven("https://raw.githubusercontent.com/adamko-dev/kotka-streams/artifacts/m2") { + content { includeGroup("dev.adamko.kotka") } + } } pluginManagement { From f0c384b5c52b494f7bf893d48f789f1eb49dbbf5 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 16:21:50 +0200 Subject: [PATCH 452/629] rm commented out code --- .../kafkatorio/schema/common/prototypeIds.kt | 43 ------------------- 1 file changed, 43 deletions(-) diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/prototypeIds.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/prototypeIds.kt index 9cc98ba..4ebb776 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/prototypeIds.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/prototypeIds.kt @@ -8,51 +8,8 @@ import kotlinx.serialization.Serializable /** * Both a [name] and [type] are required to unique identify a [prototype][FactorioPrototype]. * - * * @property[name] The name of the prototype, which is unique per specific Prototype [type] */ -// * Each subclass of [PrototypeId] is equivalent to a Prototype `type`. -//sealed interface PrototypeId { -// -// val name: String -// -// @Serializable -// @JvmInline -// @SerialName("kafkatorio.prototype.id.PrototypeIdMapTile") -// value class MapTile(override val name: String) : PrototypeId { -// override fun toString(): String = name -// } -// -// @Serializable -// @JvmInline -// @SerialName("kafkatorio.prototype.id.PrototypeIdEntity") -// value class Entity(override val name: String) : PrototypeId { -// override fun toString(): String = name -// } -// -// @Serializable -// @JvmInline -// @SerialName("kafkatorio.prototype.id.PrototypeIdResourceEntity") -// value class ResourceEntity(override val name: String) : PrototypeId { -// override fun toString(): String = name -// } -// -// @Serializable -// @JvmInline -// @SerialName("kafkatorio.prototype.id.PrototypeIdFluid") -// value class Fluid(override val name: String) : PrototypeId { -// override fun toString(): String = name -// } -// -// @Serializable -// @JvmInline -// @SerialName("kafkatorio.prototype.id.PrototypeIdItem") -// value class Item(override val name: String) : PrototypeId { -// override fun toString(): String = name -// } -// -//} - @Serializable @JvmInline @SerialName("kafkatorio.id.PrototypeId") From 8f4823ae9787196d00f0352d2bfbbc7024607cbe Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 16:22:50 +0200 Subject: [PATCH 453/629] add MapChunkEntityUpdate to webmap --- .../main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt index 7c94823..58ddf51 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -6,6 +6,7 @@ import dev.adamko.kafkatorio.schema.packets.ConsoleCommandUpdate import dev.adamko.kafkatorio.schema.packets.EntityUpdate import dev.adamko.kafkatorio.schema.packets.EventServerPacket import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData +import dev.adamko.kafkatorio.schema.packets.MapChunkEntityUpdate import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate @@ -81,10 +82,11 @@ class WebsocketService( is ConfigurationUpdate, is ConsoleChatUpdate, is ConsoleCommandUpdate, + is EntityUpdate, + is MapChunkEntityUpdate, + is MapChunkTileUpdate, is PrototypesUpdate, is SurfaceUpdate, - is EntityUpdate, - is MapChunkTileUpdate, is KafkatorioPacketData.Error -> { // to be continued... } From 9dbd6f68f344fb2d5fd7dd02ed2e93a6b0438956 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 16:23:08 +0200 Subject: [PATCH 454/629] experiment with adding jwt to docker syslogger --- modules/infra-factorio-server/src/docker-compose.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/infra-factorio-server/src/docker-compose.yml b/modules/infra-factorio-server/src/docker-compose.yml index 9e1e947..85bfd03 100644 --- a/modules/infra-factorio-server/src/docker-compose.yml +++ b/modules/infra-factorio-server/src/docker-compose.yml @@ -21,6 +21,10 @@ services: options: syslog-address: "tcp://host.docker.internal:12034" syslog-format: "rfc5424" + tag: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJrZXkiOiIwMTIzNDU2Nzg5YWJjZGVmIn0.rozxe6m4HmvQIVtESq2kT_CumIw7cFK2zbeKc5aUwEg" + + +# correct horse battery staple # environment: # RCON_PORT: 27715 From c4f74fd3ca9e8385f9be466faa02de82c42bb7eb Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 16:51:00 +0200 Subject: [PATCH 455/629] try fixing annoying package.json differences --- .../kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt index d074957..943426e 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt @@ -50,6 +50,12 @@ abstract class UpdatePackageJson @Inject constructor( val packageJsonContentUpdated = jsonMapper .encodeToString(updatedPackageJson) + + // change empty arrays/objects, because `npm install` also formats package.json, but + // slightly differently to kxs. + .replace(": {\n },", ": {},") + .replace(": [\n ],", ": [],") + .suffixIfNot("\n") logger.debug(packageJsonContentUpdated) From 3affed66d6abf06cbaf4fb3dc3aad1304d7d3b05 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 17:08:00 +0200 Subject: [PATCH 456/629] try fixing annoying package.json differences --- .../dev/adamko/kafkatorio/task/UpdatePackageJson.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt index 943426e..ddfa6ce 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt @@ -31,9 +31,9 @@ abstract class UpdatePackageJson @Inject constructor( init { - group = NodePlugin.NODE_GROUP + group = NodePlugin.NPM_GROUP description = - "Read the package.json file and update the version and name, based on the project." + "Read the package.json file and update the version and name, based on the current project." outputs.upToDateWhen(JsonPropertiesUpToDateSpec) } @@ -53,8 +53,8 @@ abstract class UpdatePackageJson @Inject constructor( // change empty arrays/objects, because `npm install` also formats package.json, but // slightly differently to kxs. - .replace(": {\n },", ": {},") - .replace(": [\n ],", ": [],") + .replace( ": {\n }", ": {}") + .replace( ": [\n ]", ": []") .suffixIfNot("\n") From 2454a3faafc6572ec1d84140fba4db209fab90d3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 17:09:51 +0200 Subject: [PATCH 457/629] fix test --- .../adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt index 53c2b62..13b69ff 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt @@ -21,7 +21,7 @@ class MapChunkUpdateTest : FunSpec({ val json = """ { "data": { - "type": "kafkatorio.packet.keyed.MapChunkUpdate", + "type": "kafkatorio.packet.keyed.MapChunkTileUpdate", "key": { "surfaceIndex": 1, "chunkPosition": [ @@ -42,9 +42,9 @@ class MapChunkUpdateTest : FunSpec({ } }, "protos": { - "water": 1, - "grass-4": 2, - "grass-3": 32 + "tile/water": 1, + "tile/grass-4": 2, + "tile/grass-3": 32 } }, "events": { From c29b66aada3a81db428630886b85a74050dd6ad8 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 17:15:42 +0200 Subject: [PATCH 458/629] bump tstl --- modules/events-mod/package-lock.json | 6 +++--- modules/events-mod/package.json | 14 +++++--------- .../events-mod/src/generated/lua/lualib_bundle.lua | 9 ++++++--- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index c81337c..3eb3396 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -85,9 +85,9 @@ "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" }, "typescript-to-lua": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.6.1.tgz", - "integrity": "sha512-ekF9U9GhfaoyJcBYiw4uHkT1I9d7Gcoo38N1Aiv/csylodwzNYnThUv/ae+aDhtSD8A4L6uwxMS/OJn5uLbohw==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.6.2.tgz", + "integrity": "sha512-m0TZ2RqL6BPy3/TNIjbVDTr9N6M45Qyb2/VJpBz0qnS3zTXxhAOugc+PaILSVwvCb1vent8ateWDt2fcEtcsRw==", "requires": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index a0f189b..9099d70 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -9,19 +9,15 @@ "engines": { "node": "~14.19.1" }, - "devDependencies": { - }, + "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", - "typescript-to-lua": "1.6.1", + "typescript-to-lua": "1.6.2", "typed-factorio": "1.3.2", "typescript": "4.7.4" }, "license": "UNLICENSED", - "peerDependencies": { - }, - "optionalDependencies": { - }, - "bundledDependencies": [ - ] + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] } diff --git a/modules/events-mod/src/generated/lua/lualib_bundle.lua b/modules/events-mod/src/generated/lua/lualib_bundle.lua index 93c797b..cdebff7 100644 --- a/modules/events-mod/src/generated/lua/lualib_bundle.lua +++ b/modules/events-mod/src/generated/lua/lualib_bundle.lua @@ -651,7 +651,7 @@ do end else local ____self_fulfilledCallbacks_2 = self.fulfilledCallbacks - ____self_fulfilledCallbacks_2[#____self_fulfilledCallbacks_2 + 1] = function() return resolve(nil, nil) end + ____self_fulfilledCallbacks_2[#____self_fulfilledCallbacks_2 + 1] = function(____, v) return resolve(nil, v) end end if onRejected then local internalCallback = self:createPromiseResolvingCallback(onRejected, resolve, reject) @@ -660,6 +660,9 @@ do if isRejected then internalCallback(nil, self.rejectionReason) end + else + local ____self_rejectedCallbacks_4 = self.rejectedCallbacks + ____self_rejectedCallbacks_4[#____self_rejectedCallbacks_4 + 1] = function(____, err) return reject(nil, err) end end if isFulfilled then resolve(nil, self.value) @@ -674,8 +677,8 @@ do end function __TS__Promise.prototype.finally(self, onFinally) if onFinally then - local ____self_finallyCallbacks_4 = self.finallyCallbacks - ____self_finallyCallbacks_4[#____self_finallyCallbacks_4 + 1] = onFinally + local ____self_finallyCallbacks_5 = self.finallyCallbacks + ____self_finallyCallbacks_5[#____self_finallyCallbacks_5 + 1] = onFinally if self.state ~= 0 then onFinally(nil) end From 5fcb831df2ab81ef88916b044536759689d92691 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 17:16:09 +0200 Subject: [PATCH 459/629] use version platform more, try fixing projects must be configuring bug --- modules/events-library/build.gradle.kts | 15 +++++++-------- .../kafkatorio/events/schema/UpdatePacketsTest.kt | 3 +-- .../kafkatorio/schema/packets/EntityUpdateTest.kt | 6 ++---- modules/events-mod/build.gradle.kts | 2 -- modules/versions-platform/build.gradle.kts | 3 +++ modules/web-map/build.gradle.kts | 5 +++-- 6 files changed, 16 insertions(+), 18 deletions(-) diff --git a/modules/events-library/build.gradle.kts b/modules/events-library/build.gradle.kts index bd304c5..107c99e 100644 --- a/modules/events-library/build.gradle.kts +++ b/modules/events-library/build.gradle.kts @@ -50,27 +50,24 @@ kotlin { val commonMain by getting { dependencies { - implementation(project.dependencies.platform(libs.kotlin.bom)) + implementation(dependencies.platform(projects.modules.versionsPlatform)) - implementation(project.dependencies.platform(libs.kotlinx.serialization.bom)) implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.json) api(libs.kxs.kxsTsGen) - implementation(dependencies.platform(libs.okio.bom)) implementation(libs.okio.core) - implementation(dependencies.platform(libs.kotlinx.coroutines.bom)) implementation(libs.kotlinx.coroutines.core) } } val commonTest by getting { dependencies { + implementation(dependencies.platform(projects.modules.versionsPlatform)) implementation(kotlin("test")) - implementation(project.dependencies.platform(libs.kotest.bom)) implementation(libs.kotest.core) implementation(libs.kotest.datatest) implementation(libs.kotest.frameworkEngine) @@ -81,20 +78,22 @@ kotlin { val jvmMain by getting { dependencies { + implementation(dependencies.platform(projects.modules.versionsPlatform)) + implementation(kotlin("reflect")) } } val jvmTest by getting { dependencies { + implementation(dependencies.platform(projects.modules.versionsPlatform)) + implementation(libs.kotest.runnerJunit5) } } val jsTest by getting { - dependencies { -// implementation(kotlin("test-js")) - } + dependencies { } } } } diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt index e480379..605874e 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt @@ -167,8 +167,7 @@ class UpdatePacketsTest : FunSpec({ "isConnected": true, "diedCause": { "unitNumber": 66, - "name": "small-biter", - "protoType": "unit" + "protoId": "unit/small-biter" }, "events": { "on_player_died": [2] diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt index 47c3552..061ccbb 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt @@ -14,8 +14,7 @@ class EntityUpdateTest : FunSpec({ "data": { "type": "kafkatorio.packet.keyed.EntityUpdate", "key": { - "name": "assembling-machine-2", - "protoType": "assembling-machine-2", + "protoId": "entity/assembling-machine-2", "unitNumber": 4622 }, "events": { @@ -30,8 +29,7 @@ class EntityUpdateTest : FunSpec({ "health": 350, "isActive": true, "isRotatable": true, - "lastUser": 1, - "prototype": "assembling-machine-2" + "lastUser": 1 }, "modVersion": "0.4.0", "tick": 38388 diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index e1d4cd7..6953c71 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -1,7 +1,6 @@ import dev.adamko.kafkatorio.factoriomod.portal.FactorioModPublishTask import dev.adamko.kafkatorio.gradle.asConsumer import dev.adamko.kafkatorio.gradle.asProvider -import dev.adamko.kafkatorio.gradle.dropDirectory import dev.adamko.kafkatorio.gradle.factorioModAttributes import dev.adamko.kafkatorio.gradle.typescriptAttributes import dev.adamko.kafkatorio.task.TypescriptToLuaTask @@ -51,7 +50,6 @@ val projectTokensX1 = projectTokens.apply { val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") - node { nodeProjectDir.set(layout.projectDirectory) } diff --git a/modules/versions-platform/build.gradle.kts b/modules/versions-platform/build.gradle.kts index 54222d2..c1f3914 100644 --- a/modules/versions-platform/build.gradle.kts +++ b/modules/versions-platform/build.gradle.kts @@ -12,6 +12,8 @@ dependencies { api(platform(libs.kotlin.bom)) api(platform(libs.kotlinx.coroutines.bom)) api(platform(libs.kotlinx.serialization.bom)) + api(platform(libs.kotlin.jsWrappers.bom)) + api(platform(libs.http4k.bom)) @@ -28,6 +30,7 @@ dependencies { api(libs.kxs.charleskornKaml) api(libs.kxs.mamoeYamlkt) + api(libs.kxs.kxsTsGen) api(libs.okio.core) diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 97082ac..091ccfb 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -66,10 +66,10 @@ kotlin { } } + main { dependencies { - implementation(dependencies.platform(libs.kotlinx.coroutines.bom)) - implementation(dependencies.platform(libs.kotlin.jsWrappers.bom)) + implementation(dependencies.platform(projects.modules.versionsPlatform)) implementation(libs.kotlinx.coroutines.core) @@ -119,6 +119,7 @@ kotlin { } } + fun KotlinDependencyHandler.kvision( module: String, version: Provider = libs.versions.kvision, From 665327e010e180c12c5d71470cf2580d6f89ceea Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 17:40:21 +0200 Subject: [PATCH 460/629] bump project to 0.7.0 (and fix docker .env task for all docker .envs) --- build.gradle.kts | 2 +- .../adamko/kafkatorio/gradle/extensions.kt | 3 +++ .../infra/docker-compose.gradle.kts | 21 +++++++-------- .../kafkatorio/task/DockerEnvUpdateTask.kt | 27 +++++++++++++++++++ modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- modules/events-server/build.gradle.kts | 12 +++++++++ modules/events-server/docker/.env | 4 +-- .../infra-factorio-server/build.gradle.kts | 2 +- modules/infra-factorio-server/src/.env | 4 +-- modules/infra-kafka-cluster/build.gradle.kts | 2 +- modules/infra-kafka-cluster/src/.env | 4 +-- modules/infra-kafka-pipe/build.gradle.kts | 2 +- modules/infra-kafka-pipe/src/.env | 4 +-- modules/web-map/build.gradle.kts | 11 ++++++++ modules/web-map/docker/.env | 4 +-- 16 files changed, 78 insertions(+), 28 deletions(-) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerEnvUpdateTask.kt diff --git a/build.gradle.kts b/build.gradle.kts index ae6a2ff..aa78c3d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.6.1" +version = "0.7.0" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt index 5f1400c..961f730 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt @@ -91,3 +91,6 @@ fun Project.taskProvider(taskName: String): Provider = providers.provider }.flatMap { tasks.named(it) } + + +const val DOCKER_COMPOSE_TASK_GROUP = "docker-compose" diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts index 830c9fb..261b2fa 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts @@ -1,5 +1,7 @@ package dev.adamko.kafkatorio.infra +import dev.adamko.kafkatorio.gradle.DOCKER_COMPOSE_TASK_GROUP +import dev.adamko.kafkatorio.task.DockerEnvUpdateTask import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { @@ -7,14 +9,13 @@ plugins { id("dev.adamko.kafkatorio.infra.process-runner") } -val dockerComposeTaskGroup: String by extra("docker-compose") val dockerComposeProjectName: String by extra(rootProject.name) val dockerSrcDir: Directory by extra(layout.projectDirectory.dir("src")) val dockerUp by tasks.registering(Exec::class) { - group = dockerComposeTaskGroup + group = DOCKER_COMPOSE_TASK_GROUP dependsOn(tasks.assemble) logging.captureStandardOutput(LogLevel.LIFECYCLE) @@ -25,7 +26,7 @@ val dockerUp by tasks.registering(Exec::class) { val dockerDown by tasks.registering(Exec::class) { - group = dockerComposeTaskGroup + group = DOCKER_COMPOSE_TASK_GROUP logging.captureStandardOutput(LogLevel.LIFECYCLE) @@ -35,7 +36,7 @@ val dockerDown by tasks.registering(Exec::class) { val dockerRemove by tasks.registering(Exec::class) { - group = dockerComposeTaskGroup + group = DOCKER_COMPOSE_TASK_GROUP logging.captureStandardOutput(LogLevel.LIFECYCLE) @@ -45,17 +46,13 @@ val dockerRemove by tasks.registering(Exec::class) { afterEvaluate { - tasks.named("processRun") { dependsOn(dockerUp, dockerEnv) } + tasks.named("processRun") { dependsOn(dockerUp, dockerEnvUpdate) } tasks.named("processKill") { dependsOn(dockerDown) } } -val dockerEnv by tasks.registering(WriteProperties::class) { - group = dockerComposeTaskGroup - - logging.captureStandardOutput(LogLevel.LIFECYCLE) - - setOutputFile(dockerSrcDir.file(".env")) +val dockerEnvUpdate by tasks.registering(DockerEnvUpdateTask::class) { + dotEnvFile.set(dockerSrcDir.file(".env")) properties( "COMPOSE_PROJECT_NAME" to dockerComposeProjectName, @@ -64,4 +61,4 @@ val dockerEnv by tasks.registering(WriteProperties::class) { } -tasks.assemble { dependsOn(dockerEnv) } +tasks.assemble { dependsOn(dockerEnvUpdate) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerEnvUpdateTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerEnvUpdateTask.kt new file mode 100644 index 0000000..cda0978 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerEnvUpdateTask.kt @@ -0,0 +1,27 @@ +package dev.adamko.kafkatorio.task + +import dev.adamko.kafkatorio.gradle.DOCKER_COMPOSE_TASK_GROUP +import javax.inject.Inject +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.logging.LogLevel +import org.gradle.api.model.ObjectFactory +import org.gradle.api.tasks.CacheableTask +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.WriteProperties + + +@CacheableTask +open class DockerEnvUpdateTask @Inject constructor( + private val objects: ObjectFactory +) : WriteProperties() { + + @Internal + val dotEnvFile: RegularFileProperty = objects.fileProperty() + + init { + group = DOCKER_COMPOSE_TASK_GROUP + super.setOutputFile(dotEnvFile) + super.getLogging().captureStandardOutput(LogLevel.LIFECYCLE) + } + +} diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 3eb3396..840585c 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.6.1", + "version": "0.7.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 9099d70..5ba45ac 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.6.1", + "version": "0.7.0", "private": true, "scripts": { "build": "tstl", diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index a2a99f3..b2b9382 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -1,3 +1,4 @@ +import dev.adamko.kafkatorio.task.DockerEnvUpdateTask import dev.adamko.kafkatorio.task.KafkaConsumerGroupsTask import org.jetbrains.kotlin.gradle.tasks.KotlinCompile @@ -106,3 +107,14 @@ idea { ) } } + + +val dockerEnvUpdate by tasks.registering(DockerEnvUpdateTask::class) { + dotEnvFile.set(layout.projectDirectory.file("docker/.env")) + + properties( + "COMPOSE_PROJECT_NAME" to rootProject.name, + "KAFKATORIO_VERSION" to project.version, + ) +} +tasks.assemble { dependsOn(dockerEnvUpdate) } diff --git a/modules/events-server/docker/.env b/modules/events-server/docker/.env index 4a03adb..e000eaa 100644 --- a/modules/events-server/docker/.env +++ b/modules/events-server/docker/.env @@ -1,3 +1,3 @@ -# Do not edit manually. This file was created with task 'dockerEnv' +# Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.6.1 +KAFKATORIO_VERSION=0.7.0 diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 11c61b7..6e5f8b2 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -53,7 +53,7 @@ tasks.dockerUp { } -tasks.dockerEnv { +tasks.dockerEnvUpdate { properties("FACTORIO_VERSION" to libs.versions.factorio.get()) } diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index c6d1744..e0b28af 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ -# Do not edit manually. This file was created with task 'dockerEnv' +# Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio FACTORIO_VERSION=1.1.61 -KAFKATORIO_VERSION=0.6.1 +KAFKATORIO_VERSION=0.7.0 diff --git a/modules/infra-kafka-cluster/build.gradle.kts b/modules/infra-kafka-cluster/build.gradle.kts index dba548c..9341a8e 100644 --- a/modules/infra-kafka-cluster/build.gradle.kts +++ b/modules/infra-kafka-cluster/build.gradle.kts @@ -4,7 +4,7 @@ plugins { description = "Kafka cluster" -tasks.dockerEnv { +tasks.dockerEnvUpdate { properties( "GRAFANA_VERSION" to libs.versions.grafana, "PROMETHEUS_VERSION" to libs.versions.prometheus, diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index d33aea8..2279b0c 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,7 +1,7 @@ -# Do not edit manually. This file was created with task 'dockerEnv' +# Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio GRAFANA_VERSION=8.5.0 -KAFKATORIO_VERSION=0.6.1 +KAFKATORIO_VERSION=0.7.0 KAFKA_DL_URL=https\://dlcdn.apache.org/kafka/3.2.0/kafka_2.13-3.2.0.tgz KAFKA_VERSION=3.2.0 PROMETHEUS_VERSION=v2.34.0 diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index ab7f0a3..58301f1 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -15,7 +15,7 @@ tasks.dockerUp { val dockerBuildKafkaPipe by tasks.registering(DockerComposeExec::class) { - dependsOn(tasks.dockerEnv) + dependsOn(tasks.dockerEnvUpdate) dockerComposeDir.set(dockerSrcDir) command.set("docker-compose build kafka-pipe") diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index 4a03adb..e000eaa 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,3 +1,3 @@ -# Do not edit manually. This file was created with task 'dockerEnv' +# Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.6.1 +KAFKATORIO_VERSION=0.7.0 diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 091ccfb..4905ccf 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -144,3 +144,14 @@ fun KotlinDependencyHandler.kvision( // resolution("webpack-dev-server", "4.9.1") // } //} + + +val dockerEnvUpdate by tasks.registering(dev.adamko.kafkatorio.task.DockerEnvUpdateTask::class) { + dotEnvFile.set(layout.projectDirectory.file("docker/.env")) + + properties( + "COMPOSE_PROJECT_NAME" to rootProject.name, + "KAFKATORIO_VERSION" to project.version, + ) +} +tasks.assemble { dependsOn(dockerEnvUpdate) } diff --git a/modules/web-map/docker/.env b/modules/web-map/docker/.env index 4a03adb..e000eaa 100644 --- a/modules/web-map/docker/.env +++ b/modules/web-map/docker/.env @@ -1,3 +1,3 @@ -# Do not edit manually. This file was created with task 'dockerEnv' +# Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.6.1 +KAFKATORIO_VERSION=0.7.0 From fe5413195a5858586b6b6f0fdeb6c212d22b08c7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 17:45:45 +0200 Subject: [PATCH 461/629] set up docker config for pc & nuc --- modules/events-server/docker/docker-compose.yml | 6 +++--- modules/infra-factorio-server/src/docker-compose.yml | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/events-server/docker/docker-compose.yml b/modules/events-server/docker/docker-compose.yml index c410cc2..c2af7ad 100644 --- a/modules/events-server/docker/docker-compose.yml +++ b/modules/events-server/docker/docker-compose.yml @@ -18,13 +18,13 @@ services: SERVER_PORT: "8080" ports: - "12080:8080" # http and ws + - "12034:9002" # syslog socket networks: - "kafka-nw" - "kafkatorio-nw" - "traefik-nw" - labels: - - "traefik.enable=true" -# - "traefik.http.services.events-server-kafkatorio.loadbalancer.server.port=12081" +# labels: +# - "traefik.enable=true" networks: kafka-nw: diff --git a/modules/infra-factorio-server/src/docker-compose.yml b/modules/infra-factorio-server/src/docker-compose.yml index 85bfd03..e040f34 100644 --- a/modules/infra-factorio-server/src/docker-compose.yml +++ b/modules/infra-factorio-server/src/docker-compose.yml @@ -19,7 +19,8 @@ services: logging: driver: syslog options: - syslog-address: "tcp://host.docker.internal:12034" + syslog-address: "tcp://host.docker.internal:12034" # pc +# syslog-address: "tcp://localhost:12034" # nuc syslog-format: "rfc5424" tag: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJrZXkiOiIwMTIzNDU2Nzg5YWJjZGVmIn0.rozxe6m4HmvQIVtESq2kT_CumIw7cFK2zbeKc5aUwEg" From dab07fbaae61fdb9d6b70e669bea9fde517c303b Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 19:42:58 +0200 Subject: [PATCH 462/629] fix docker volume name --- modules/events-server/docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/events-server/docker/Dockerfile b/modules/events-server/docker/Dockerfile index 2bad738..f9254a3 100644 --- a/modules/events-server/docker/Dockerfile +++ b/modules/events-server/docker/Dockerfile @@ -11,7 +11,7 @@ EXPOSE $SERVER_PORT ENV SERVER_DATA_DIR="/app/data" ENV KAFKA_STREAMS_STATE_DIR="/app/kafka-state" -VOLUME ${TILE_DIR} \ +VOLUME ${SERVER_DATA_DIR} \ ${KAFKA_STREAMS_STATE_DIR} COPY ${DIST_DIR}/events-server-${KAFKATORIO_VERSION}.tar events-server.tar From 1b3e3dc539e9ab6ab8562597a284c1ba1f8fc106 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 6 Jul 2022 21:02:43 +0200 Subject: [PATCH 463/629] events-server: fix socker server port --- modules/events-server/docker/Dockerfile | 3 +++ modules/events-server/docker/docker-compose.yml | 1 + 2 files changed, 4 insertions(+) diff --git a/modules/events-server/docker/Dockerfile b/modules/events-server/docker/Dockerfile index f9254a3..48e4647 100644 --- a/modules/events-server/docker/Dockerfile +++ b/modules/events-server/docker/Dockerfile @@ -9,6 +9,9 @@ WORKDIR /app ENV SERVER_PORT=8080 EXPOSE $SERVER_PORT +ENV SOCKET_SERVER_PORT=9002 +EXPOSE $SOCKET_SERVER_PORT + ENV SERVER_DATA_DIR="/app/data" ENV KAFKA_STREAMS_STATE_DIR="/app/kafka-state" VOLUME ${SERVER_DATA_DIR} \ diff --git a/modules/events-server/docker/docker-compose.yml b/modules/events-server/docker/docker-compose.yml index c2af7ad..d3b16f9 100644 --- a/modules/events-server/docker/docker-compose.yml +++ b/modules/events-server/docker/docker-compose.yml @@ -16,6 +16,7 @@ services: KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" # KAFKA_STREAMS_STATE_DIR: "" SERVER_PORT: "8080" + SOCKET_SERVER_PORT: "9002" ports: - "12080:8080" # http and ws - "12034:9002" # syslog socket From 4510ec4a6e8f0731105f33d26738f04cb058e373 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 7 Jul 2022 22:28:47 +0200 Subject: [PATCH 464/629] only save png tiles 256px and up --- modules/events-server/build.gradle.kts | 3 --- .../kafkatorio/server/processor/eventProcessor.kt | 6 ------ .../server/processor/topology/saveMapTiles.kt | 15 +++++++++++---- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index b2b9382..01a01fe 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -27,7 +27,6 @@ dependencies { implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.json) -// implementation("org.jetbrains.kotlinx:kotlinx-serialization-protobuf") implementation(libs.kotlinx.coroutines.core) @@ -46,7 +45,6 @@ dependencies { implementation(callLogging) implementation(contentNegotiaion) implementation(cio) -// implementation(netty) implementation(autoHeadResponse) implementation(partialContent) implementation(resources) @@ -59,7 +57,6 @@ dependencies { implementation(core) implementation(tls) } - // diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt index 95b2be4..b10982a 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt @@ -16,17 +16,11 @@ suspend fun eventsProcessor( wsServer: WebmapWebsocketServer, ): Unit = coroutineScope { - val admin = KafkatorioKafkaAdmin(appProps) admin.createKafkatorioTopics() - -// val syslogServer = SyslogSocketServer(appProps) -// val wsServer = WebsocketServer() -// val tileServer = WebMapTileServer(appProps) val topology = KafkatorioTopology(appProps, wsServer, syslogServer) - launch { topology.start() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt index 3592c58..cbeef9b 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt @@ -4,6 +4,7 @@ import com.sksamuel.scrimage.ImmutableImage import com.sksamuel.scrimage.ScaleMethod import com.sksamuel.scrimage.nio.PngWriter import dev.adamko.kafkatorio.library.kxsBinary +import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.ServerMapChunkId @@ -14,11 +15,15 @@ import dev.adamko.kafkatorio.server.processor.TOPIC_BROADCAST_TO_WEBSOCKET import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_STATE import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.producedAs +import dev.adamko.kotka.extensions.stream +import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.map import dev.adamko.kotka.extensions.streams.mapValues import dev.adamko.kotka.kxs.serde import java.awt.image.BufferedImage import java.nio.file.Path +import kotlin.collections.component1 +import kotlin.collections.component2 import kotlin.io.path.fileSize import kotlin.math.abs import org.apache.kafka.streams.StreamsBuilder @@ -41,13 +46,15 @@ fun saveMapTiles( val subdividedMapChunkTilesDebounced: KStream> = builder.stream( - TOPIC_MAP_CHUNK_COLOURED_STATE, consumedAs( "$pid.consume.grouped-map-chunks", - kxsBinary.serde(), - kxsBinary.serde(), + kxsBinary.serde(ServerMapChunkId.serializer()), + kxsBinary.serde(ServerMapChunkTiles.serializer(ColourHex.serializer())), ), - ) + TOPIC_MAP_CHUNK_COLOURED_STATE, + ).filter("$pid.consume.grouped-map-chunks.filter-size") { _, y -> + y.chunkId.chunkSize.zoomLevel >= ChunkSize.CHUNK_256.zoomLevel + } val savedChunkFilenames: KStream = subdividedMapChunkTilesDebounced.saveChunkAsImage(serverDataDir) From 80eb001bbf9ec632aa9d6b126a51a6a6774eb2ea Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 8 Jul 2022 21:06:09 +0200 Subject: [PATCH 465/629] emit entity prototypes - mod: refactor event handlers to separate files - lib: update models for prototypes --- .../schema/common/factorioPrototypes.kt | 35 +- .../lua/main/events/configurationUpdate.lua | 58 +--- .../generated/lua/main/events/converters.lua | 29 ++ .../lua/main/events/entityUpdates.lua | 175 +--------- .../handlers/ConfigurationUpdateHandler.lua | 62 ++++ .../events/handlers/EntityUpdateHandler.lua | 175 ++++++++++ .../events/handlers/MapChunkUpdateHandler.lua | 208 ++++++++++++ .../events/handlers/PlayerUpdateHandler.lua | 60 ++++ .../lua/main/events/mapChunkUpdates.lua | 213 +------------ .../lua/main/events/playerUpdates.lua | 107 ++----- .../lua/main/events/prototypeUpdates.lua | 76 ++++- .../main/events/registerEventListeners.lua | 4 +- .../lua/main/events/resourceEntityUpdates.lua | 0 .../typescript/generated/kafkatorio-schema.ts | 20 +- .../main/events/configurationUpdate.ts | 57 +--- .../main/typescript/main/events/converters.ts | 43 +++ .../typescript/main/events/entityUpdates.ts | 254 +-------------- .../handlers/ConfigurationUpdateHandler.ts | 62 ++++ .../events/handlers/EntityUpdateHandler.ts | 250 +++++++++++++++ .../events/handlers/MapChunkUpdateHandler.ts | 242 ++++++++++++++ .../events/handlers/PlayerUpdateHandler.ts | 75 +++++ .../typescript/main/events/mapChunkUpdates.ts | 257 +-------------- .../typescript/main/events/playerUpdates.ts | 300 +++++++----------- .../main/events/prototypeUpdates.ts | 129 +++++--- .../main/events/registerEventListeners.ts | 2 +- .../main/events/resourceEntityUpdates.ts | 99 ------ .../processor/topology/colourMapChunks.kt | 15 +- 27 files changed, 1570 insertions(+), 1437 deletions(-) create mode 100644 modules/events-mod/src/generated/lua/main/events/handlers/ConfigurationUpdateHandler.lua create mode 100644 modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua create mode 100644 modules/events-mod/src/generated/lua/main/events/handlers/MapChunkUpdateHandler.lua create mode 100644 modules/events-mod/src/generated/lua/main/events/handlers/PlayerUpdateHandler.lua delete mode 100644 modules/events-mod/src/generated/lua/main/events/resourceEntityUpdates.lua create mode 100644 modules/events-mod/src/main/typescript/main/events/handlers/ConfigurationUpdateHandler.ts create mode 100644 modules/events-mod/src/main/typescript/main/events/handlers/EntityUpdateHandler.ts create mode 100644 modules/events-mod/src/main/typescript/main/events/handlers/MapChunkUpdateHandler.ts create mode 100644 modules/events-mod/src/main/typescript/main/events/handlers/PlayerUpdateHandler.ts delete mode 100644 modules/events-mod/src/main/typescript/main/events/resourceEntityUpdates.ts diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt index 393ad8a..ec752b1 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt @@ -8,15 +8,16 @@ import kotlinx.serialization.Serializable @Serializable @SerialName("kafkatorio.prototype.FactorioPrototype") sealed interface FactorioPrototype { + val protoId: PrototypeId - val mapColour: Colour @SerialName("kafkatorio.prototype.MapTile") @Serializable data class MapTile( override val protoId: PrototypeId, - override val mapColour: Colour, + + val mapColour: Colour, val layer: UInt, @Contextual @@ -27,27 +28,47 @@ sealed interface FactorioPrototype { ) : FactorioPrototype + /** + * @param[colour] The colour of the prototype, or `null` if the prototype doesn't have colour. + * @param[mapColour] The map colour used when charting this entity if a + * [friendly][mapColourFriend] or [enemy][mapColourEnemy] colour isn't defined or `null`. + * @param[mapColourFriend] The friendly map colour used when charting this entity. + * @param[mapColourEnemy] The enemy map colour used when charting this entity. + */ @SerialName("kafkatorio.prototype.Entity") @Serializable data class Entity( override val protoId: PrototypeId, - override val mapColour: Colour, - val protoType: String, - val objectName: String, - val colour: Colour, + val group: ItemGroup, + val subgroup: ItemGroup, + + val colour: Colour? = null, + val mapColour: Colour? = null, + val mapColourFriend: Colour? = null, + val mapColourEnemy: Colour? = null, + val maxHealth: Float, val isBuilding: Boolean, val isEntityWithOwner: Boolean, val isMilitaryTarget: Boolean, - val miningProperties: MiningProperties + val miningProperties: MiningProperties? = null, ) : FactorioPrototype { @Serializable + @SerialName("kafkatorio.prototype.EntityMiningProperties") data class MiningProperties( val canBeMined: Boolean, val products: List?, ) + @Serializable + @SerialName("kafkatorio.prototype.EntityItemGroup") + data class ItemGroup( + val name: String, + val type: String, + val parentName: String? = null, + ) + } } diff --git a/modules/events-mod/src/generated/lua/main/events/configurationUpdate.lua b/modules/events-mod/src/generated/lua/main/events/configurationUpdate.lua index 1e49bb7..6560c95 100644 --- a/modules/events-mod/src/generated/lua/main/events/configurationUpdate.lua +++ b/modules/events-mod/src/generated/lua/main/events/configurationUpdate.lua @@ -1,65 +1,13 @@ -local ____lualib = require("lualib_bundle") -local __TS__ObjectKeys = ____lualib.__TS__ObjectKeys -local __TS__ArrayConcat = ____lualib.__TS__ArrayConcat -local Set = ____lualib.Set -local __TS__New = ____lualib.__TS__New -local __TS__Spread = ____lualib.__TS__Spread -local __TS__ArrayMap = ____lualib.__TS__ArrayMap local ____exports = {} -local emitConfigurationUpdate, factorioData, allMods, Type -local ____PacketEmitter = require("main.PacketEmitter") -local PacketEmitter = ____PacketEmitter.default -local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") -local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData local ____global_2Dinit = require("main.global-init") local initGlobal = ____global_2Dinit.initGlobal local ____prototypeUpdates = require("main.events.prototypeUpdates") local emitPrototypes = ____prototypeUpdates.emitPrototypes -function emitConfigurationUpdate(changeData) - local configUpdateData = { - type = Type.ConfigurationUpdate, - migrationApplied = changeData.migration_applied, - modStartupSettingsChange = changeData.mod_startup_settings_changed, - allMods = allMods(changeData), - factorioData = factorioData(changeData) - } - PacketEmitter:emitInstantPacket(configUpdateData) -end -function factorioData(changeData) - return {oldVersion = changeData.old_version or nil, newVersion = changeData.new_version or nil} -end -function allMods(e) - local namesOfChangedMods = __TS__ObjectKeys(e.mod_changes) - local namesOfCurrentMods = __TS__ObjectKeys(script.active_mods) - local modNames = {__TS__Spread(__TS__New( - Set, - __TS__ArrayConcat(namesOfChangedMods, namesOfCurrentMods) - ))} - return __TS__ArrayMap( - modNames, - function(____, modName) - local ____script_active_mods_modName_2 = script.active_mods[modName] - if ____script_active_mods_modName_2 == nil then - local ____e_mod_changes_modName_new_version_0 = e.mod_changes[modName] - if ____e_mod_changes_modName_new_version_0 ~= nil then - ____e_mod_changes_modName_new_version_0 = ____e_mod_changes_modName_new_version_0.new_version - end - ____script_active_mods_modName_2 = ____e_mod_changes_modName_new_version_0 - end - local currentVer = ____script_active_mods_modName_2 or nil - local ____e_mod_changes_modName_old_version_3 = e.mod_changes[modName] - if ____e_mod_changes_modName_old_version_3 ~= nil then - ____e_mod_changes_modName_old_version_3 = ____e_mod_changes_modName_old_version_3.old_version - end - local previousVer = ____e_mod_changes_modName_old_version_3 or nil - return {modName = modName, currentVersion = currentVer, previousVersion = previousVer} - end - ) -end -Type = KafkatorioPacketData.Type +local ____ConfigurationUpdateHandler = require("main.events.handlers.ConfigurationUpdateHandler") +local ConfigurationUpdates = ____ConfigurationUpdateHandler.default script.on_configuration_changed(function(data) initGlobal(true) - emitConfigurationUpdate(data) + ConfigurationUpdates:emitConfigurationUpdate(data) emitPrototypes() end) return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/converters.lua b/modules/events-mod/src/generated/lua/main/events/converters.lua index 2131d67..8020aaa 100644 --- a/modules/events-mod/src/generated/lua/main/events/converters.lua +++ b/modules/events-mod/src/generated/lua/main/events/converters.lua @@ -2,6 +2,7 @@ local ____exports = {} local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") local EntityStatus = ____kafkatorio_2Dschema.EntityStatus local FactorioEntityData = ____kafkatorio_2Dschema.FactorioEntityData +local MinedProduct = ____kafkatorio_2Dschema.MinedProduct ____exports.Converters = {} local Converters = ____exports.Converters do @@ -87,6 +88,34 @@ do return EntityStatusRecord[status] end end + function Converters.miningProperties(properties) + local products = {} + if properties.products ~= nil then + for ____, product in ipairs(properties.products) do + if product.type == "fluid" then + products[#products + 1] = { + type = MinedProduct.Type.MinedProductFluid, + amount = product.amount, + resultProtoId = ____exports.Converters.prototypeId(product.type, product.name) + } + end + if product.type == "item" then + products[#products + 1] = { + type = MinedProduct.Type.MinedProductItem, + amount = product.amount, + resultProtoId = ____exports.Converters.prototypeId(product.type, product.name) + } + end + end + end + return {canBeMined = properties.minable, products = products} + end + function Converters.playerOnlineInfo(player, data) + data.lastOnline = player.last_online + data.onlineTime = player.online_time + data.afkTime = player.afk_time + data.isConnected = player.connected + end EntityStatusRecord = { [defines.entity_status.cant_divide_segments] = EntityStatus.CANT_DIVIDE_SEGMENTS, [defines.entity_status.charging] = EntityStatus.CHARGING, diff --git a/modules/events-mod/src/generated/lua/main/events/entityUpdates.lua b/modules/events-mod/src/generated/lua/main/events/entityUpdates.lua index 86eb956..6f4d323 100644 --- a/modules/events-mod/src/generated/lua/main/events/entityUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/entityUpdates.lua @@ -1,177 +1,6 @@ -local ____lualib = require("lualib_bundle") -local __TS__Class = ____lualib.__TS__Class -local __TS__New = ____lualib.__TS__New local ____exports = {} -local ____converters = require("main.events.converters") -local Converters = ____converters.Converters -local ____EventDataCache = require("main.cache.EventDataCache") -local EventDataCache = ____EventDataCache.default -local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") -local FactorioEntityData = ____kafkatorio_2Dschema.FactorioEntityData -local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData -____exports.EntityUpdatesHandler = __TS__Class() -local EntityUpdatesHandler = ____exports.EntityUpdatesHandler -EntityUpdatesHandler.name = "EntityUpdatesHandler" -function EntityUpdatesHandler.prototype.____constructor(self) -end -function EntityUpdatesHandler.prototype.handleMinedTileEvent(self, event) - local surface = game.get_surface(event.surface_index) - if surface == nil then - return - end - local tilesByChunk = {} - for ____, tile in ipairs(event.tiles) do - local chunkPosition = Converters.tilePositionToChunkPosition(tile.position) - tilesByChunk[chunkPosition] = tile - end - for chunkPos, tiles in pairs(tilesByChunk) do - local entities = {} - for tile in pairs(tiles) do - local resources = ____exports.EntityUpdatesHandler:getTileResourceEntities(surface, chunkPos) - for ____, resource in ipairs(resources) do - entities[#entities + 1] = resource - end - end - ____exports.EntityUpdatesHandler:throttleResourceEntitiesUpdate( - Converters.eventNameString(event.name), - event.tick, - event.surface_index, - {chunkPos[1], chunkPos[2]}, - entities - ) - end -end -function EntityUpdatesHandler.prototype.handleMinedEntityEvent(self, event) - ____exports.EntityUpdatesHandler:throttleEntityUpdate(event, event.entity) -end -function EntityUpdatesHandler.prototype.handleBuiltEntityEvent(self, event) - ____exports.EntityUpdatesHandler:throttleEntityUpdate(event, event.created_entity) -end -function EntityUpdatesHandler.prototype.handleChunkGeneratedEvent(self, event) - local entities = ____exports.EntityUpdatesHandler:getAreaResourceEntities(event.surface, event.area) - ____exports.EntityUpdatesHandler:throttleResourceEntitiesUpdate( - Converters.eventNameString(event.name), - event.tick, - event.surface.index, - {event.position.x, event.position.y}, - entities - ) -end -function EntityUpdatesHandler.throttleEntityUpdate(self, event, entity) - if entity.unit_number == nil then - return - end - local eventName = Converters.eventNameString(event.name) - local entityUpdateKey = { - protoId = Converters.prototypeIdEntity(entity), - surfaceIndex = entity.surface.index, - chunkPosition = Converters.mapPositionToChunkPosition(entity.position) - } - local ____FactorioEntityData_Type_Standard_2 = FactorioEntityData.Type.Standard - local ____Converters_prototypeIdEntity_result_3 = Converters.prototypeIdEntity(entity) - local ____entity_graphics_variation_4 = entity.graphics_variation - local ____entity_health_5 = entity.health - local ____entity_active_6 = entity.active - local ____entity_rotatable_7 = entity.rotatable - local ____entity_last_user_index_0 = entity.last_user - if ____entity_last_user_index_0 ~= nil then - ____entity_last_user_index_0 = ____entity_last_user_index_0.index - end - local entityUpdate = { - type = ____FactorioEntityData_Type_Standard_2, - protoId = ____Converters_prototypeIdEntity_result_3, - graphicsVariation = ____entity_graphics_variation_4, - health = ____entity_health_5, - isActive = ____entity_active_6, - isRotatable = ____entity_rotatable_7, - lastUser = ____entity_last_user_index_0, - localisedDescription = nil, - localisedName = nil, - position = {entity.position.x, entity.position.y}, - status = Converters.entityStatus(entity.status) - } - local entityKey = tostring(entity.unit_number) - EventDataCache:throttle( - entityUpdateKey, - KafkatorioPacketData.Type.MapChunkEntityUpdate, - function(data) - if data.events == nil then - data.events = {} - end - local ____data_events_8, ____eventName_9 = data.events, eventName - if ____data_events_8[____eventName_9] == nil then - ____data_events_8[____eventName_9] = {} - end - local ____data_events_eventName_10 = data.events[eventName] - ____data_events_eventName_10[#____data_events_eventName_10 + 1] = event.tick - if data.distinctEntities == nil then - data.distinctEntities = {} - end - data.distinctEntities[entityKey] = entityUpdate - end - ) -end -function EntityUpdatesHandler.throttleResourceEntitiesUpdate(self, eventName, eventTick, surfaceIndex, chunkPosition, entities) - local entitiesByProtoId = {} - for ____, entity in ipairs(entities) do - local ____entitiesByProtoId_11, ____entity_protoId_12 = entitiesByProtoId, entity.protoId - if ____entitiesByProtoId_11[____entity_protoId_12] == nil then - ____entitiesByProtoId_11[____entity_protoId_12] = {} - end - local ____entitiesByProtoId_entity_protoId_13 = entitiesByProtoId[entity.protoId] - ____entitiesByProtoId_entity_protoId_13[#____entitiesByProtoId_entity_protoId_13 + 1] = entity - end - for protoId, resourceEntities in pairs(entitiesByProtoId) do - local entityUpdateKey = {protoId = protoId, surfaceIndex = surfaceIndex, chunkPosition = {chunkPosition[1], chunkPosition[2]}} - EventDataCache:throttle( - entityUpdateKey, - KafkatorioPacketData.Type.MapChunkEntityUpdate, - function(data) - if data.events == nil then - data.events = {} - end - local ____data_events_14, ____eventName_15 = data.events, eventName - if ____data_events_14[____eventName_15] == nil then - ____data_events_14[____eventName_15] = {} - end - local ____data_events_eventName_16 = data.events[eventName] - ____data_events_eventName_16[#____data_events_eventName_16 + 1] = eventTick - for ____, entity in ipairs(resourceEntities) do - local x, y = table.unpack(entity.position) - local entityKey = (tostring(x) .. ",") .. tostring(y) - if data.distinctEntities == nil then - data.distinctEntities = {} - end - data.distinctEntities[entityKey] = entity - end - end - ) - end -end -function EntityUpdatesHandler.getTileResourceEntities(self, surface, mapPosition) - local rawEntities = surface.find_entities_filtered({position = mapPosition, collision_mask = "resource-layer"}) - local resources = {} - for ____, rawEntity in ipairs(rawEntities) do - local entity = Converters.convertResourceEntity(rawEntity) - if entity ~= nil then - resources[#resources + 1] = entity - end - end - return resources -end -function EntityUpdatesHandler.getAreaResourceEntities(self, surface, area) - local rawEntities = surface.find_entities_filtered({area = area, collision_mask = "resource-layer"}) - local resources = {} - for ____, rawEntity in ipairs(rawEntities) do - local entity = Converters.convertResourceEntity(rawEntity) - if entity ~= nil then - resources[#resources + 1] = entity - end - end - return resources -end -local EntityUpdates = __TS__New(____exports.EntityUpdatesHandler) -____exports.default = EntityUpdates +local ____EntityUpdateHandler = require("main.events.handlers.EntityUpdateHandler") +local EntityUpdates = ____EntityUpdateHandler.default script.on_event( defines.events.on_built_entity, function(e) diff --git a/modules/events-mod/src/generated/lua/main/events/handlers/ConfigurationUpdateHandler.lua b/modules/events-mod/src/generated/lua/main/events/handlers/ConfigurationUpdateHandler.lua new file mode 100644 index 0000000..b81701c --- /dev/null +++ b/modules/events-mod/src/generated/lua/main/events/handlers/ConfigurationUpdateHandler.lua @@ -0,0 +1,62 @@ +local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local __TS__ObjectKeys = ____lualib.__TS__ObjectKeys +local __TS__ArrayConcat = ____lualib.__TS__ArrayConcat +local Set = ____lualib.Set +local __TS__New = ____lualib.__TS__New +local __TS__Spread = ____lualib.__TS__Spread +local __TS__ArrayMap = ____lualib.__TS__ArrayMap +local ____exports = {} +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +local ____PacketEmitter = require("main.PacketEmitter") +local PacketEmitter = ____PacketEmitter.default +____exports.ConfigurationUpdateHandler = __TS__Class() +local ConfigurationUpdateHandler = ____exports.ConfigurationUpdateHandler +ConfigurationUpdateHandler.name = "ConfigurationUpdateHandler" +function ConfigurationUpdateHandler.prototype.____constructor(self) +end +function ConfigurationUpdateHandler.prototype.emitConfigurationUpdate(self, changeData) + local configUpdateData = { + type = KafkatorioPacketData.Type.ConfigurationUpdate, + migrationApplied = changeData.migration_applied, + modStartupSettingsChange = changeData.mod_startup_settings_changed, + allMods = ____exports.ConfigurationUpdateHandler:allMods(changeData), + factorioData = ____exports.ConfigurationUpdateHandler:factorioData(changeData) + } + PacketEmitter:emitInstantPacket(configUpdateData) +end +function ConfigurationUpdateHandler.factorioData(self, changeData) + return {oldVersion = changeData.old_version or nil, newVersion = changeData.new_version or nil} +end +function ConfigurationUpdateHandler.allMods(self, e) + local namesOfChangedMods = __TS__ObjectKeys(e.mod_changes) + local namesOfCurrentMods = __TS__ObjectKeys(script.active_mods) + local modNames = {__TS__Spread(__TS__New( + Set, + __TS__ArrayConcat(namesOfChangedMods, namesOfCurrentMods) + ))} + return __TS__ArrayMap( + modNames, + function(____, modName) + local ____script_active_mods_modName_2 = script.active_mods[modName] + if ____script_active_mods_modName_2 == nil then + local ____e_mod_changes_modName_new_version_0 = e.mod_changes[modName] + if ____e_mod_changes_modName_new_version_0 ~= nil then + ____e_mod_changes_modName_new_version_0 = ____e_mod_changes_modName_new_version_0.new_version + end + ____script_active_mods_modName_2 = ____e_mod_changes_modName_new_version_0 + end + local currentVer = ____script_active_mods_modName_2 or nil + local ____e_mod_changes_modName_old_version_3 = e.mod_changes[modName] + if ____e_mod_changes_modName_old_version_3 ~= nil then + ____e_mod_changes_modName_old_version_3 = ____e_mod_changes_modName_old_version_3.old_version + end + local previousVer = ____e_mod_changes_modName_old_version_3 or nil + return {modName = modName, currentVersion = currentVer, previousVersion = previousVer} + end + ) +end +local ConfigurationUpdates = __TS__New(____exports.ConfigurationUpdateHandler) +____exports.default = ConfigurationUpdates +return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua b/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua new file mode 100644 index 0000000..99afb01 --- /dev/null +++ b/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua @@ -0,0 +1,175 @@ +local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local __TS__New = ____lualib.__TS__New +local ____exports = {} +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local FactorioEntityData = ____kafkatorio_2Dschema.FactorioEntityData +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +local ____converters = require("main.events.converters") +local Converters = ____converters.Converters +local ____EventDataCache = require("main.cache.EventDataCache") +local EventDataCache = ____EventDataCache.default +____exports.EntityUpdatesHandler = __TS__Class() +local EntityUpdatesHandler = ____exports.EntityUpdatesHandler +EntityUpdatesHandler.name = "EntityUpdatesHandler" +function EntityUpdatesHandler.prototype.____constructor(self) +end +function EntityUpdatesHandler.prototype.handleMinedTileEvent(self, event) + local surface = game.get_surface(event.surface_index) + if surface == nil then + return + end + local tilesByChunk = {} + for ____, tile in ipairs(event.tiles) do + local chunkPosition = Converters.tilePositionToChunkPosition(tile.position) + tilesByChunk[chunkPosition] = tile + end + for chunkPos, tiles in pairs(tilesByChunk) do + local entities = {} + for tile in pairs(tiles) do + local resources = ____exports.EntityUpdatesHandler:getTileResourceEntities(surface, chunkPos) + for ____, resource in ipairs(resources) do + entities[#entities + 1] = resource + end + end + ____exports.EntityUpdatesHandler:throttleResourceEntitiesUpdate( + Converters.eventNameString(event.name), + event.tick, + event.surface_index, + {chunkPos[1], chunkPos[2]}, + entities + ) + end +end +function EntityUpdatesHandler.prototype.handleMinedEntityEvent(self, event) + ____exports.EntityUpdatesHandler:throttleEntityUpdate(event, event.entity) +end +function EntityUpdatesHandler.prototype.handleBuiltEntityEvent(self, event) + ____exports.EntityUpdatesHandler:throttleEntityUpdate(event, event.created_entity) +end +function EntityUpdatesHandler.prototype.handleChunkGeneratedEvent(self, event) + local entities = ____exports.EntityUpdatesHandler:getAreaResourceEntities(event.surface, event.area) + ____exports.EntityUpdatesHandler:throttleResourceEntitiesUpdate( + Converters.eventNameString(event.name), + event.tick, + event.surface.index, + {event.position.x, event.position.y}, + entities + ) +end +function EntityUpdatesHandler.throttleEntityUpdate(self, event, entity) + if entity.unit_number == nil then + return + end + local eventName = Converters.eventNameString(event.name) + local entityUpdateKey = { + protoId = Converters.prototypeIdEntity(entity), + surfaceIndex = entity.surface.index, + chunkPosition = Converters.mapPositionToChunkPosition(entity.position) + } + local ____FactorioEntityData_Type_Standard_2 = FactorioEntityData.Type.Standard + local ____Converters_prototypeIdEntity_result_3 = Converters.prototypeIdEntity(entity) + local ____entity_graphics_variation_4 = entity.graphics_variation + local ____entity_health_5 = entity.health + local ____entity_active_6 = entity.active + local ____entity_rotatable_7 = entity.rotatable + local ____entity_last_user_index_0 = entity.last_user + if ____entity_last_user_index_0 ~= nil then + ____entity_last_user_index_0 = ____entity_last_user_index_0.index + end + local entityUpdate = { + type = ____FactorioEntityData_Type_Standard_2, + protoId = ____Converters_prototypeIdEntity_result_3, + graphicsVariation = ____entity_graphics_variation_4, + health = ____entity_health_5, + isActive = ____entity_active_6, + isRotatable = ____entity_rotatable_7, + lastUser = ____entity_last_user_index_0, + localisedDescription = nil, + localisedName = nil, + position = {entity.position.x, entity.position.y}, + status = Converters.entityStatus(entity.status) + } + local entityKey = tostring(entity.unit_number) + EventDataCache:throttle( + entityUpdateKey, + KafkatorioPacketData.Type.MapChunkEntityUpdate, + function(data) + if data.events == nil then + data.events = {} + end + local ____data_events_8, ____eventName_9 = data.events, eventName + if ____data_events_8[____eventName_9] == nil then + ____data_events_8[____eventName_9] = {} + end + local ____data_events_eventName_10 = data.events[eventName] + ____data_events_eventName_10[#____data_events_eventName_10 + 1] = event.tick + if data.distinctEntities == nil then + data.distinctEntities = {} + end + data.distinctEntities[entityKey] = entityUpdate + end + ) +end +function EntityUpdatesHandler.throttleResourceEntitiesUpdate(self, eventName, eventTick, surfaceIndex, chunkPosition, entities) + local entitiesByProtoId = {} + for ____, entity in ipairs(entities) do + local ____entitiesByProtoId_11, ____entity_protoId_12 = entitiesByProtoId, entity.protoId + if ____entitiesByProtoId_11[____entity_protoId_12] == nil then + ____entitiesByProtoId_11[____entity_protoId_12] = {} + end + local ____entitiesByProtoId_entity_protoId_13 = entitiesByProtoId[entity.protoId] + ____entitiesByProtoId_entity_protoId_13[#____entitiesByProtoId_entity_protoId_13 + 1] = entity + end + for protoId, resourceEntities in pairs(entitiesByProtoId) do + local entityUpdateKey = {protoId = protoId, surfaceIndex = surfaceIndex, chunkPosition = {chunkPosition[1], chunkPosition[2]}} + EventDataCache:throttle( + entityUpdateKey, + KafkatorioPacketData.Type.MapChunkEntityUpdate, + function(data) + if data.events == nil then + data.events = {} + end + local ____data_events_14, ____eventName_15 = data.events, eventName + if ____data_events_14[____eventName_15] == nil then + ____data_events_14[____eventName_15] = {} + end + local ____data_events_eventName_16 = data.events[eventName] + ____data_events_eventName_16[#____data_events_eventName_16 + 1] = eventTick + for ____, entity in ipairs(resourceEntities) do + local x, y = table.unpack(entity.position) + local entityKey = (tostring(x) .. ",") .. tostring(y) + if data.distinctEntities == nil then + data.distinctEntities = {} + end + data.distinctEntities[entityKey] = entity + end + end + ) + end +end +function EntityUpdatesHandler.getTileResourceEntities(self, surface, mapPosition) + local rawEntities = surface.find_entities_filtered({position = mapPosition, collision_mask = "resource-layer"}) + local resources = {} + for ____, rawEntity in ipairs(rawEntities) do + local entity = Converters.convertResourceEntity(rawEntity) + if entity ~= nil then + resources[#resources + 1] = entity + end + end + return resources +end +function EntityUpdatesHandler.getAreaResourceEntities(self, surface, area) + local rawEntities = surface.find_entities_filtered({area = area, collision_mask = "resource-layer"}) + local resources = {} + for ____, rawEntity in ipairs(rawEntities) do + local entity = Converters.convertResourceEntity(rawEntity) + if entity ~= nil then + resources[#resources + 1] = entity + end + end + return resources +end +local EntityUpdates = __TS__New(____exports.EntityUpdatesHandler) +____exports.default = EntityUpdates +return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/handlers/MapChunkUpdateHandler.lua b/modules/events-mod/src/generated/lua/main/events/handlers/MapChunkUpdateHandler.lua new file mode 100644 index 0000000..f047ad7 --- /dev/null +++ b/modules/events-mod/src/generated/lua/main/events/handlers/MapChunkUpdateHandler.lua @@ -0,0 +1,208 @@ +local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local Map = ____lualib.Map +local __TS__Iterator = ____lualib.__TS__Iterator +local __TS__New = ____lualib.__TS__New +local ____exports = {} +local ____converters = require("main.events.converters") +local Converters = ____converters.Converters +local ____eventTypeCheck = require("main.events.eventTypeCheck") +local isEventType = ____eventTypeCheck.isEventType +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +local ____EventDataCache = require("main.cache.EventDataCache") +local EventUpdatesManager = ____EventDataCache.default +local MapChunkUpdateHandler = __TS__Class() +MapChunkUpdateHandler.name = "MapChunkUpdateHandler" +function MapChunkUpdateHandler.prototype.____constructor(self) +end +function MapChunkUpdateHandler.prototype.handleChunkGeneratedEvent(self, event, expirationDurationTicks) + local tiles = event.surface.find_tiles_filtered({area = event.area}) + MapChunkUpdateHandler:mapTilesUpdateDebounce( + event.surface, + Converters.convertMapTablePosition(event.position), + tiles, + event, + nil, + expirationDurationTicks + ) +end +function MapChunkUpdateHandler.prototype.handleBuiltTileEvent(self, event) + local surface = game.get_surface(event.surface_index) + if surface == nil then + local eventName = Converters.eventNameString(event.name) + log("[handleBuiltTileEvent] undefined surface " .. eventName) + return + end + local tiles = Converters.convertPlacedTiles(event.tile, event.tiles) + local groupedTiles = MapChunkUpdateHandler:groupTiles(tiles) + for ____, ____value in __TS__Iterator(groupedTiles) do + local chunkPos = ____value[1] + local tiles = ____value[2] + MapChunkUpdateHandler:mapTilesUpdateDebounce( + surface, + chunkPos, + tiles, + event, + function(data) + if isEventType(event, defines.events.on_player_built_tile) then + data.player = event.player_index + return + end + if isEventType(event, defines.events.on_robot_built_tile) then + local ____data_2 = data + local ____event_robot_unit_number_0 = event.robot + if ____event_robot_unit_number_0 ~= nil then + ____event_robot_unit_number_0 = ____event_robot_unit_number_0.unit_number + end + ____data_2.robot = { + unitNumber = ____event_robot_unit_number_0 or nil, + protoId = Converters.prototypeId(event.robot.type, event.robot.name) + } + return + end + local exhaustiveCheck = event + end + ) + end +end +function MapChunkUpdateHandler.prototype.handleMinedTileEvent(self, event) + local surface = game.get_surface(event.surface_index) + if surface == nil then + local eventName = Converters.eventNameString(event.name) + log("[handleMinedTileEvent] undefined surface " .. eventName) + return + end + local tiles = Converters.convertRemovedTiles(surface, event.tiles) + local groupedTiles = MapChunkUpdateHandler:groupTiles(tiles) + for ____, ____value in __TS__Iterator(groupedTiles) do + local chunkPos = ____value[1] + local tiles = ____value[2] + MapChunkUpdateHandler:mapTilesUpdateDebounce( + surface, + chunkPos, + tiles, + event, + function(data) + if isEventType(event, defines.events.on_player_mined_tile) then + data.player = event.player_index + return + end + if isEventType(event, defines.events.on_robot_mined_tile) then + local ____data_5 = data + local ____event_robot_unit_number_3 = event.robot + if ____event_robot_unit_number_3 ~= nil then + ____event_robot_unit_number_3 = ____event_robot_unit_number_3.unit_number + end + ____data_5.robot = { + unitNumber = ____event_robot_unit_number_3 or nil, + protoId = Converters.prototypeId(event.robot.type, event.robot.name) + } + return + end + local exhaustiveCheck = event + end + ) + end +end +function MapChunkUpdateHandler.prototype.handleScriptSetTilesEvent(self, event) + local surface = game.get_surface(event.surface_index) + if surface == nil then + return + end + local groupedTiles = MapChunkUpdateHandler:groupTiles(event.tiles) + for ____, ____value in __TS__Iterator(groupedTiles) do + local chunkPos = ____value[1] + local tiles = ____value[2] + MapChunkUpdateHandler:mapTilesUpdateDebounce(surface, chunkPos, tiles, event) + end +end +function MapChunkUpdateHandler.prototype.handlePreChunkDeleted(self, event) + local surface = game.get_surface(event.surface_index) + if surface == nil then + return + end + for ____, position in ipairs(event.positions) do + local key = {surfaceIndex = surface.index, chunkPosition = {position.x, position.y}} + EventUpdatesManager:debounce( + key, + KafkatorioPacketData.Type.MapChunkTileUpdate, + function(data) + data.isDeleted = true + return true + end, + 0 + ) + end +end +function MapChunkUpdateHandler.mapTilesUpdateDebounce(self, surface, chunkPosition, tiles, event, updater, expirationDurationTicks) + if surface == nil then + return + end + local eventName = Converters.eventNameString(event.name) + local key = {surfaceIndex = surface.index, chunkPosition = chunkPosition} + EventUpdatesManager:debounce( + key, + KafkatorioPacketData.Type.MapChunkTileUpdate, + function(data) + if data.tileDictionary == nil then + data.tileDictionary = {tilesXY = {}, protos = {}} + end + local protosCount = table_size(data.tileDictionary.protos) + for ____, tile in ipairs(tiles) do + local protoId = Converters.prototypeId("tile", tile.name) + if data.tileDictionary.protos[protoId] == nil then + end + local ____data_tileDictionary_protos_7, ____protoId_8 = data.tileDictionary.protos, protoId + if ____data_tileDictionary_protos_7[____protoId_8] == nil then + local ____protosCount_6 = protosCount + protosCount = ____protosCount_6 + 1 + ____data_tileDictionary_protos_7[____protoId_8] = ____protosCount_6 + end + local protoKey = data.tileDictionary.protos[protoId] + local xString = tostring(tile.position.x) + local yString = tostring(tile.position.y) + local ____data_tileDictionary_tilesXY_9, ____xString_10 = data.tileDictionary.tilesXY, xString + if ____data_tileDictionary_tilesXY_9[____xString_10] == nil then + ____data_tileDictionary_tilesXY_9[____xString_10] = {} + end + data.tileDictionary.tilesXY[xString][yString] = protoKey + end + if data.events == nil then + data.events = {} + end + local ____data_events_11, ____eventName_12 = data.events, eventName + if ____data_events_11[____eventName_12] == nil then + ____data_events_11[____eventName_12] = {} + end + local ____data_events_eventName_13 = data.events[eventName] + ____data_events_eventName_13[#____data_events_eventName_13 + 1] = event.tick + if updater ~= nil then + updater(data) + end + end, + expirationDurationTicks + ) +end +function MapChunkUpdateHandler.groupTiles(self, tiles) + local mapChunkPositionToTiles = __TS__New(Map) + for ____, tile in ipairs(tiles) do + local chunkPosition = { + math.floor(tile.position.x / 32), + math.floor(tile.position.y / 32) + } + if not mapChunkPositionToTiles:has(chunkPosition) then + mapChunkPositionToTiles:set(chunkPosition, {}) + end + local ____mapChunkPositionToTiles_get_result_push_result_14 = mapChunkPositionToTiles:get(chunkPosition) + if ____mapChunkPositionToTiles_get_result_push_result_14 ~= nil then + local ____temp_15 = mapChunkPositionToTiles:get(chunkPosition) + ____temp_15[#____temp_15 + 1] = tile + ____mapChunkPositionToTiles_get_result_push_result_14 = nil + end + end + return mapChunkPositionToTiles +end +local MapChunkUpdate = __TS__New(MapChunkUpdateHandler) +____exports.default = MapChunkUpdate +return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/handlers/PlayerUpdateHandler.lua b/modules/events-mod/src/generated/lua/main/events/handlers/PlayerUpdateHandler.lua new file mode 100644 index 0000000..0591e9b --- /dev/null +++ b/modules/events-mod/src/generated/lua/main/events/handlers/PlayerUpdateHandler.lua @@ -0,0 +1,60 @@ +local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local __TS__New = ____lualib.__TS__New +local ____exports = {} +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +local ____converters = require("main.events.converters") +local Converters = ____converters.Converters +local ____EventDataCache = require("main.cache.EventDataCache") +local EventUpdatesManager = ____EventDataCache.default +____exports.PlayerUpdateHandler = __TS__Class() +local PlayerUpdateHandler = ____exports.PlayerUpdateHandler +PlayerUpdateHandler.name = "PlayerUpdateHandler" +function PlayerUpdateHandler.prototype.____constructor(self) +end +function PlayerUpdateHandler.prototype.handleBannedEvent(self, event) + self:playerUpdateThrottle( + event, + function(player, data) + data.bannedReason = event.reason or nil + Converters.playerOnlineInfo(player, data) + end + ) +end +function PlayerUpdateHandler.prototype.playerUpdateThrottle(self, event, mutate, expirationDurationTicks) + if expirationDurationTicks == nil then + expirationDurationTicks = nil + end + local playerIndex = event.player_index + if playerIndex == nil then + return + end + local eventName = Converters.eventNameString(event.name) + EventUpdatesManager:throttle( + {index = playerIndex}, + KafkatorioPacketData.Type.PlayerUpdate, + function(data) + local player = game.players[playerIndex] + if player ~= nil then + mutate(player, data) + end + if data.events == nil then + data.events = {} + end + local ____data_events_0, ____eventName_1 = data.events, eventName + if ____data_events_0[____eventName_1] == nil then + ____data_events_0[____eventName_1] = {} + end + local ____data_events_eventName_2 = data.events[eventName] + ____data_events_eventName_2[#____data_events_eventName_2 + 1] = event.tick + end, + expirationDurationTicks + ) +end +function PlayerUpdateHandler.prototype.playerUpdateImmediate(self, event, mutate) + self:playerUpdateThrottle(event, mutate, 0) +end +local PlayerUpdates = __TS__New(____exports.PlayerUpdateHandler) +____exports.default = PlayerUpdates +return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua b/modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua index a21a929..b3c5857 100644 --- a/modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua @@ -1,213 +1,8 @@ -local ____lualib = require("lualib_bundle") -local __TS__Class = ____lualib.__TS__Class -local Map = ____lualib.Map -local __TS__Iterator = ____lualib.__TS__Iterator -local __TS__New = ____lualib.__TS__New local ____exports = {} -local ____eventTypeCheck = require("main.events.eventTypeCheck") -local isEventType = ____eventTypeCheck.isEventType -local ____converters = require("main.events.converters") -local Converters = ____converters.Converters -local ____EventDataCache = require("main.cache.EventDataCache") -local EventUpdatesManager = ____EventDataCache.default -local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") -local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData -local ____entityUpdates = require("main.events.entityUpdates") -local EntityUpdates = ____entityUpdates.default -local Type = KafkatorioPacketData.Type -local MapChunkUpdateHandler = __TS__Class() -MapChunkUpdateHandler.name = "MapChunkUpdateHandler" -function MapChunkUpdateHandler.prototype.____constructor(self) -end -function MapChunkUpdateHandler.prototype.handleChunkGeneratedEvent(self, event, expirationDurationTicks) - local tiles = event.surface.find_tiles_filtered({area = event.area}) - MapChunkUpdateHandler:mapTilesUpdateDebounce( - event.surface, - Converters.convertMapTablePosition(event.position), - tiles, - event, - nil, - expirationDurationTicks - ) -end -function MapChunkUpdateHandler.prototype.handleBuiltTileEvent(self, event) - local surface = game.get_surface(event.surface_index) - if surface == nil then - local eventName = Converters.eventNameString(event.name) - log("[handleBuiltTileEvent] undefined surface " .. eventName) - return - end - local tiles = Converters.convertPlacedTiles(event.tile, event.tiles) - local groupedTiles = MapChunkUpdateHandler:groupTiles(tiles) - for ____, ____value in __TS__Iterator(groupedTiles) do - local chunkPos = ____value[1] - local tiles = ____value[2] - MapChunkUpdateHandler:mapTilesUpdateDebounce( - surface, - chunkPos, - tiles, - event, - function(data) - if isEventType(event, defines.events.on_player_built_tile) then - data.player = event.player_index - return - end - if isEventType(event, defines.events.on_robot_built_tile) then - local ____data_2 = data - local ____event_robot_unit_number_0 = event.robot - if ____event_robot_unit_number_0 ~= nil then - ____event_robot_unit_number_0 = ____event_robot_unit_number_0.unit_number - end - ____data_2.robot = { - unitNumber = ____event_robot_unit_number_0 or nil, - protoId = Converters.prototypeId(event.robot.type, event.robot.name) - } - return - end - local exhaustiveCheck = event - end - ) - end -end -function MapChunkUpdateHandler.prototype.handleMinedTileEvent(self, event) - local surface = game.get_surface(event.surface_index) - if surface == nil then - local eventName = Converters.eventNameString(event.name) - log("[handleMinedTileEvent] undefined surface " .. eventName) - return - end - local tiles = Converters.convertRemovedTiles(surface, event.tiles) - local groupedTiles = MapChunkUpdateHandler:groupTiles(tiles) - for ____, ____value in __TS__Iterator(groupedTiles) do - local chunkPos = ____value[1] - local tiles = ____value[2] - MapChunkUpdateHandler:mapTilesUpdateDebounce( - surface, - chunkPos, - tiles, - event, - function(data) - if isEventType(event, defines.events.on_player_mined_tile) then - data.player = event.player_index - return - end - if isEventType(event, defines.events.on_robot_mined_tile) then - local ____data_5 = data - local ____event_robot_unit_number_3 = event.robot - if ____event_robot_unit_number_3 ~= nil then - ____event_robot_unit_number_3 = ____event_robot_unit_number_3.unit_number - end - ____data_5.robot = { - unitNumber = ____event_robot_unit_number_3 or nil, - protoId = Converters.prototypeId(event.robot.type, event.robot.name) - } - return - end - local exhaustiveCheck = event - end - ) - end -end -function MapChunkUpdateHandler.prototype.handleScriptSetTilesEvent(self, event) - local surface = game.get_surface(event.surface_index) - if surface == nil then - return - end - local groupedTiles = MapChunkUpdateHandler:groupTiles(event.tiles) - for ____, ____value in __TS__Iterator(groupedTiles) do - local chunkPos = ____value[1] - local tiles = ____value[2] - MapChunkUpdateHandler:mapTilesUpdateDebounce(surface, chunkPos, tiles, event) - end -end -function MapChunkUpdateHandler.prototype.handlePreChunkDeleted(self, event) - local surface = game.get_surface(event.surface_index) - if surface == nil then - return - end - for ____, position in ipairs(event.positions) do - local key = {surfaceIndex = surface.index, chunkPosition = {position.x, position.y}} - EventUpdatesManager:debounce( - key, - Type.MapChunkTileUpdate, - function(data) - data.isDeleted = true - return true - end, - 0 - ) - end -end -function MapChunkUpdateHandler.mapTilesUpdateDebounce(self, surface, chunkPosition, tiles, event, updater, expirationDurationTicks) - if surface == nil then - return - end - local eventName = Converters.eventNameString(event.name) - local key = {surfaceIndex = surface.index, chunkPosition = chunkPosition} - EventUpdatesManager:debounce( - key, - Type.MapChunkTileUpdate, - function(data) - if data.tileDictionary == nil then - data.tileDictionary = {tilesXY = {}, protos = {}} - end - local protosCount = table_size(data.tileDictionary.protos) - for ____, tile in ipairs(tiles) do - local protoId = Converters.prototypeId("tile", tile.name) - if data.tileDictionary.protos[protoId] == nil then - end - local ____data_tileDictionary_protos_7, ____protoId_8 = data.tileDictionary.protos, protoId - if ____data_tileDictionary_protos_7[____protoId_8] == nil then - local ____protosCount_6 = protosCount - protosCount = ____protosCount_6 + 1 - ____data_tileDictionary_protos_7[____protoId_8] = ____protosCount_6 - end - local protoKey = data.tileDictionary.protos[protoId] - local xString = tostring(tile.position.x) - local yString = tostring(tile.position.y) - local ____data_tileDictionary_tilesXY_9, ____xString_10 = data.tileDictionary.tilesXY, xString - if ____data_tileDictionary_tilesXY_9[____xString_10] == nil then - ____data_tileDictionary_tilesXY_9[____xString_10] = {} - end - data.tileDictionary.tilesXY[xString][yString] = protoKey - end - if data.events == nil then - data.events = {} - end - local ____data_events_11, ____eventName_12 = data.events, eventName - if ____data_events_11[____eventName_12] == nil then - ____data_events_11[____eventName_12] = {} - end - local ____data_events_eventName_13 = data.events[eventName] - ____data_events_eventName_13[#____data_events_eventName_13 + 1] = event.tick - if updater ~= nil then - updater(data) - end - end, - expirationDurationTicks - ) -end -function MapChunkUpdateHandler.groupTiles(self, tiles) - local mapChunkPositionToTiles = __TS__New(Map) - for ____, tile in ipairs(tiles) do - local chunkPosition = { - math.floor(tile.position.x / 32), - math.floor(tile.position.y / 32) - } - if not mapChunkPositionToTiles:has(chunkPosition) then - mapChunkPositionToTiles:set(chunkPosition, {}) - end - local ____mapChunkPositionToTiles_get_result_push_result_14 = mapChunkPositionToTiles:get(chunkPosition) - if ____mapChunkPositionToTiles_get_result_push_result_14 ~= nil then - local ____temp_15 = mapChunkPositionToTiles:get(chunkPosition) - ____temp_15[#____temp_15 + 1] = tile - ____mapChunkPositionToTiles_get_result_push_result_14 = nil - end - end - return mapChunkPositionToTiles -end -local MapChunkUpdate = __TS__New(MapChunkUpdateHandler) -____exports.default = MapChunkUpdate +local ____EntityUpdateHandler = require("main.events.handlers.EntityUpdateHandler") +local EntityUpdates = ____EntityUpdateHandler.default +local ____MapChunkUpdateHandler = require("main.events.handlers.MapChunkUpdateHandler") +local MapChunkUpdate = ____MapChunkUpdateHandler.default script.on_event( defines.events.on_chunk_generated, function(e) diff --git a/modules/events-mod/src/generated/lua/main/events/playerUpdates.lua b/modules/events-mod/src/generated/lua/main/events/playerUpdates.lua index 47840de..885348b 100644 --- a/modules/events-mod/src/generated/lua/main/events/playerUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/playerUpdates.lua @@ -1,75 +1,26 @@ local ____exports = {} -local playerUpdateThrottle, playerOnlineInfo, handleBannedEvent, Type +local disconnectReasons local ____converters = require("main.events.converters") local Converters = ____converters.Converters -local ____EventDataCache = require("main.cache.EventDataCache") -local EventUpdatesManager = ____EventDataCache.default local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData local ____PacketEmitter = require("main.PacketEmitter") local packetEmitter = ____PacketEmitter.default -function playerUpdateThrottle(event, mutate, expirationDurationTicks) - if expirationDurationTicks == nil then - expirationDurationTicks = nil - end - local playerIndex = event.player_index - if playerIndex == nil then - return - end - local eventName = Converters.eventNameString(event.name) - EventUpdatesManager:throttle( - {index = playerIndex}, - Type.PlayerUpdate, - function(data) - local player = game.players[playerIndex] - if player ~= nil then - mutate(player, data) - end - if data.events == nil then - data.events = {} - end - local ____data_events_0, ____eventName_1 = data.events, eventName - if ____data_events_0[____eventName_1] == nil then - ____data_events_0[____eventName_1] = {} - end - local ____data_events_eventName_2 = data.events[eventName] - ____data_events_eventName_2[#____data_events_eventName_2 + 1] = event.tick - end, - expirationDurationTicks - ) -end -function playerOnlineInfo(player, data) - data.lastOnline = player.last_online - data.onlineTime = player.online_time - data.afkTime = player.afk_time - data.isConnected = player.connected -end -function handleBannedEvent(event) - playerUpdateThrottle( - event, - function(player, data) - data.bannedReason = event.reason or nil - playerOnlineInfo(player, data) - end - ) -end -Type = KafkatorioPacketData.Type -local function playerUpdateImmediate(event, mutate) - playerUpdateThrottle(event, mutate, 0) -end +local ____PlayerUpdateHandler = require("main.events.handlers.PlayerUpdateHandler") +local PlayerUpdates = ____PlayerUpdateHandler.default script.on_event( defines.events.on_player_joined_game, function(e) - playerUpdateThrottle( + PlayerUpdates:playerUpdateThrottle( e, function(player, data) data.isAdmin = player.admin - local ____data_5 = data - local ____player_character_unit_number_3 = player.character - if ____player_character_unit_number_3 ~= nil then - ____player_character_unit_number_3 = ____player_character_unit_number_3.unit_number + local ____data_2 = data + local ____player_character_unit_number_0 = player.character + if ____player_character_unit_number_0 ~= nil then + ____player_character_unit_number_0 = ____player_character_unit_number_0.unit_number end - ____data_5.characterUnitNumber = ____player_character_unit_number_3 or nil + ____data_2.characterUnitNumber = ____player_character_unit_number_0 or nil data.chatColour = Converters.mapColour(player.chat_color) data.colour = Converters.mapColour(player.color) data.forceIndex = player.force.index @@ -78,7 +29,7 @@ script.on_event( data.isSpectator = player.spectator data.surfaceIndex = player.surface.index data.tag = player.tag - playerOnlineInfo(player, data) + Converters.playerOnlineInfo(player, data) end ) end @@ -86,7 +37,7 @@ script.on_event( script.on_event( defines.events.on_player_changed_position, function(e) - playerUpdateThrottle( + PlayerUpdates:playerUpdateThrottle( e, function(player, data) data.position = {player.position.x, player.position.y} @@ -97,7 +48,7 @@ script.on_event( script.on_event( defines.events.on_player_changed_surface, function(e) - playerUpdateThrottle( + PlayerUpdates:playerUpdateThrottle( e, function(player, data) data.position = {player.position.x, player.position.y} @@ -109,11 +60,11 @@ script.on_event( script.on_event( defines.events.on_player_died, function(e) - playerUpdateThrottle( + PlayerUpdates:playerUpdateThrottle( e, function(player, data) data.ticksToRespawn = player.ticks_to_respawn or nil - playerOnlineInfo(player, data) + Converters.playerOnlineInfo(player, data) if e.cause ~= nil then data.diedCause = { unitNumber = e.cause.unit_number or nil, @@ -124,25 +75,31 @@ script.on_event( ) end ) -script.on_event(defines.events.on_player_banned, handleBannedEvent) -script.on_event(defines.events.on_player_unbanned, handleBannedEvent) +script.on_event( + defines.events.on_player_banned, + function(event) + PlayerUpdates:handleBannedEvent(event) + end +) +script.on_event( + defines.events.on_player_unbanned, + function(event) + PlayerUpdates:handleBannedEvent(event) + end +) script.on_event( defines.events.on_player_kicked, function(event) log((("on_player_kicked " .. tostring(event.tick)) .. " ") .. tostring(event.name)) - playerUpdateImmediate( + PlayerUpdates:playerUpdateImmediate( event, function(player, data) data.kickedReason = event.reason or nil - playerOnlineInfo(player, data) + Converters.playerOnlineInfo(player, data) end ) end ) -local disconnectReasons = {} -for name, disconnectId in pairs(defines.disconnect_reason) do - disconnectReasons[disconnectId] = name -end script.on_event( defines.events.on_pre_player_left_game, function(event) @@ -156,13 +113,17 @@ script.on_event( defines.events.on_player_removed, function(event) log((("on_player_removed " .. tostring(event.tick)) .. " ") .. tostring(event.name)) - playerUpdateImmediate( + PlayerUpdates:playerUpdateImmediate( event, function(player, data) data.isRemoved = true - playerOnlineInfo(player, data) + Converters.playerOnlineInfo(player, data) end ) end ) +disconnectReasons = {} +for name, disconnectId in pairs(defines.disconnect_reason) do + disconnectReasons[disconnectId] = name +end return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua index a1d6f07..551e592 100644 --- a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua @@ -1,7 +1,5 @@ -local ____lualib = require("lualib_bundle") -local __TS__ArrayPushArray = ____lualib.__TS__ArrayPushArray local ____exports = {} -local prototypeUpdates, getMapTilePrototypes +local emit, getMapTilePrototypes, getEntityPrototypes, convertItemGroup, convertItemSubgroup local ____PacketEmitter = require("main.PacketEmitter") local PacketEmitter = ____PacketEmitter.default local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") @@ -9,18 +7,19 @@ local FactorioPrototype = ____kafkatorio_2Dschema.FactorioPrototype local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData local ____converters = require("main.events.converters") local Converters = ____converters.Converters -function prototypeUpdates() - local prototypes = {} - __TS__ArrayPushArray( - prototypes, - getMapTilePrototypes() - ) - return prototypes +function emit(protosByType) + for ____, protos in pairs(protosByType) do + PacketEmitter:emitInstantPacket({type = KafkatorioPacketData.Type.PrototypesUpdate, prototypes = protos}) + end end function getMapTilePrototypes() local tiles = {} + if not (tiles.tile ~= nil) then + tiles.tile = {} + end for ____, tile in pairs(game.tile_prototypes) do - tiles[#tiles + 1] = { + local ____tiles_tile_0 = tiles.tile + ____tiles_tile_0[#____tiles_tile_0 + 1] = { type = FactorioPrototype.Type.MapTile, protoId = Converters.prototypeId("tile", tile.name), order = tile.order, @@ -32,11 +31,56 @@ function getMapTilePrototypes() end return tiles end +function getEntityPrototypes() + local protos = {} + for ____, entity in pairs(game.entity_prototypes) do + local key = (entity.group.name .. "/") .. entity.subgroup.name + if not (protos[key] ~= nil) then + protos[key] = {} + end + local entityProto = { + type = FactorioPrototype.Type.Entity, + protoId = Converters.prototypeId(entity.type, entity.name), + group = convertItemGroup(entity.group), + subgroup = convertItemSubgroup(entity.subgroup), + isBuilding = entity.is_building, + isEntityWithOwner = entity.is_entity_with_owner, + isMilitaryTarget = entity.is_military_target, + maxHealth = entity.max_health + } + if entity.map_color ~= nil then + entityProto.mapColour = Converters.mapColour(entity.map_color) + end + if entity.friendly_map_color ~= nil then + entityProto.mapColourFriend = Converters.mapColour(entity.friendly_map_color) + end + if entity.enemy_map_color ~= nil then + entityProto.mapColourEnemy = Converters.mapColour(entity.enemy_map_color) + end + entityProto.miningProperties = Converters.miningProperties(entity.mineable_properties) + local ____protos_key_1 = protos[key] + ____protos_key_1[#____protos_key_1 + 1] = entityProto + end + return protos +end +function convertItemGroup(itemGroup) + return {name = itemGroup.name, type = itemGroup.type, parentName = nil} +end +function convertItemSubgroup(itemGroup) + local ____itemGroup_name_4 = itemGroup.name + local ____itemGroup_type_5 = itemGroup.type + local ____itemGroup_group_name_2 = itemGroup.group + if ____itemGroup_group_name_2 ~= nil then + ____itemGroup_group_name_2 = ____itemGroup_group_name_2.name + end + return {name = ____itemGroup_name_4, type = ____itemGroup_type_5, parentName = ____itemGroup_group_name_2} +end function ____exports.emitPrototypes() - local data = { - prototypes = prototypeUpdates(), - type = KafkatorioPacketData.Type.PrototypesUpdate - } - PacketEmitter:emitInstantPacket(data) + local mapTileProtos = getMapTilePrototypes() + emit(mapTileProtos) + local ____ = game.item_group_prototypes + local ____ = game.item_subgroup_prototypes + local entityProtos = getEntityPrototypes() + emit(entityProtos) end return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua b/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua index 757ef9a..421c0b0 100644 --- a/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua +++ b/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua @@ -9,8 +9,8 @@ local ____surfaceUpdates = require("main.events.surfaceUpdates") local handleSurfaceUpdate = ____surfaceUpdates.handleSurfaceUpdate local ____EventDataCache = require("main.cache.EventDataCache") local EventCacheService = ____EventDataCache.default -local ____mapChunkUpdates = require("main.events.mapChunkUpdates") -local MapChunkUpdate = ____mapChunkUpdates.default +local ____MapChunkUpdateHandler = require("main.events.handlers.MapChunkUpdateHandler") +local MapChunkUpdate = ____MapChunkUpdateHandler.default script.on_event( defines.events.on_tick, function(event) diff --git a/modules/events-mod/src/generated/lua/main/events/resourceEntityUpdates.lua b/modules/events-mod/src/generated/lua/main/events/resourceEntityUpdates.lua deleted file mode 100644 index e69de29..0000000 diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts index 0ff6cea..3598c28 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts @@ -211,15 +211,17 @@ export namespace FactorioPrototype { export interface Entity { type: FactorioPrototype.Type.Entity; protoId: PrototypeId; - mapColour: Colour; - protoType: string; - objectName: string; - colour: Colour; + group: EntityItemGroup; + subgroup: EntityItemGroup; + colour?: Colour | null; + mapColour?: Colour | null; + mapColourFriend?: Colour | null; + mapColourEnemy?: Colour | null; maxHealth: Float; isBuilding: boolean; isEntityWithOwner: boolean; isMilitaryTarget: boolean; - miningProperties: MiningProperties; + miningProperties?: EntityMiningProperties | null; } export interface MapTile { @@ -278,7 +280,13 @@ export namespace FactorioEntityData { } } -export interface MiningProperties { +export interface EntityItemGroup { + name: string; + type: string; + parentName?: string | null; +} + +export interface EntityMiningProperties { canBeMined: boolean; products: MinedProduct[] | null; } diff --git a/modules/events-mod/src/main/typescript/main/events/configurationUpdate.ts b/modules/events-mod/src/main/typescript/main/events/configurationUpdate.ts index b11863f..a49b740 100644 --- a/modules/events-mod/src/main/typescript/main/events/configurationUpdate.ts +++ b/modules/events-mod/src/main/typescript/main/events/configurationUpdate.ts @@ -1,65 +1,12 @@ -import PacketEmitter from "../PacketEmitter"; -import { - ConfigurationUpdateGameData, - ConfigurationUpdateModData, - KafkatorioPacketData -} from "../../generated/kafkatorio-schema"; import {initGlobal} from "../global-init"; import {emitPrototypes} from "./prototypeUpdates"; -import Type = KafkatorioPacketData.Type; -import ConfigurationUpdate = KafkatorioPacketData.ConfigurationUpdate; +import ConfigurationUpdates from "./handlers/ConfigurationUpdateHandler"; script.on_configuration_changed((data: ConfigurationChangedData) => { // runs whenever the version of the base game, or a mod, changes initGlobal(true) // KafkatorioSettings.loadSettings() - emitConfigurationUpdate(data) + ConfigurationUpdates.emitConfigurationUpdate(data) emitPrototypes() }) - - -function emitConfigurationUpdate(changeData: ConfigurationChangedData) { - - const configUpdateData: ConfigurationUpdate = { - type: Type.ConfigurationUpdate, - migrationApplied: changeData.migration_applied, - modStartupSettingsChange: changeData.mod_startup_settings_changed, - allMods: allMods(changeData), - factorioData: factorioData(changeData) - } - - PacketEmitter.emitInstantPacket(configUpdateData) -} - - -function factorioData(changeData: ConfigurationChangedData): ConfigurationUpdateGameData { - return { - oldVersion: changeData.old_version ?? null, - newVersion: changeData.new_version ?? null, - } -} - - -function allMods(e: ConfigurationChangedData): ConfigurationUpdateModData[] { - - let namesOfChangedMods: string[] = Object.keys(e.mod_changes) - let namesOfCurrentMods: string[] = Object.keys(script.active_mods) - - let modNames = [...new Set( - namesOfChangedMods.concat(namesOfCurrentMods) - )] - - return modNames.map((modName) => { - - let currentVer = script.active_mods[modName] ?? e.mod_changes[modName]?.new_version ?? null - let previousVer = e.mod_changes[modName]?.old_version ?? null - - return { - modName: modName, - currentVersion: currentVer, - previousVersion: previousVer, - } - }) - -} diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index 220484e..861c546 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -1,10 +1,13 @@ import {DefinedEventName} from "../types"; import { Colour, + EntityMiningProperties, EntityStatus, EventName, FactorioEntityData, + KafkatorioPacketData, MapChunkPosition, + MinedProduct, PrototypeId, } from "../../generated/kafkatorio-schema"; @@ -133,6 +136,46 @@ export namespace Converters { } + export function miningProperties( + properties: LuaEntityPrototype["mineable_properties"] + ): EntityMiningProperties { + + const products: MinedProduct[] = [] + + if (properties.products != null) { + for (const product of properties.products) { + if (product.type == "fluid") { + products[products.length] = { + type: MinedProduct.Type.MinedProductFluid, + amount: product.amount, + resultProtoId: Converters.prototypeId(product.type, product.name), + } + } + if (product.type == "item") { + products[products.length] = { + type: MinedProduct.Type.MinedProductItem, + amount: product.amount, + resultProtoId: Converters.prototypeId(product.type, product.name), + } + } + } + } + + return { + canBeMined: properties.minable, + products: products, + } + } + + + export function playerOnlineInfo(player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) { + data.lastOnline = player.last_online + data.onlineTime = player.online_time + data.afkTime = player.afk_time + data.isConnected = player.connected + } + + const EntityStatusRecord: Record = { //@formatter:off [ defines.entity_status.cant_divide_segments ]: EntityStatus.CANT_DIVIDE_SEGMENTS, diff --git a/modules/events-mod/src/main/typescript/main/events/entityUpdates.ts b/modules/events-mod/src/main/typescript/main/events/entityUpdates.ts index f262eb3..05507ae 100644 --- a/modules/events-mod/src/main/typescript/main/events/entityUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/entityUpdates.ts @@ -1,230 +1,4 @@ -import {Converters} from "./converters"; -import EventDataCache from "../cache/EventDataCache"; -import { - EventName, - FactorioEntityData, - KafkatorioPacketData, - MapChunkPosition, - PrototypeId, - Tick, -} from "../../generated/kafkatorio-schema"; - - -export class EntityUpdatesHandler { - - - handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) { - - const surface = game.get_surface(event.surface_index) - if (surface == null) { - return - } - - const tilesByChunk: LuaTable = new LuaTable() - - for (const tile of event.tiles) { - const chunkPosition = Converters.tilePositionToChunkPosition(tile.position) - tilesByChunk.set(chunkPosition, tile) - } - - for (const [chunkPos, tiles] of pairs(tilesByChunk)) { - - const entities: FactorioEntityData.Resource[] = [] - - for (const tile in tiles) { - const resources: FactorioEntityData.Resource[] = EntityUpdatesHandler.getTileResourceEntities(surface, chunkPos) - for (const resource of resources) { - entities[entities.length] = resource - } - } - - EntityUpdatesHandler.throttleResourceEntitiesUpdate( - Converters.eventNameString(event.name), - event.tick as Tick, - event.surface_index, - [chunkPos[0], chunkPos[1]], - entities, - ) - } - } - - - handleMinedEntityEvent( - event: OnPlayerMinedEntityEvent | OnRobotMinedEntityEvent, - ) { - EntityUpdatesHandler.throttleEntityUpdate(event, event.entity) - } - - - handleBuiltEntityEvent( - event: OnBuiltEntityEvent | OnRobotBuiltEntityEvent, - ) { - EntityUpdatesHandler.throttleEntityUpdate(event, event.created_entity) - } - - - handleChunkGeneratedEvent(event: OnChunkGeneratedEvent) { - const entities = EntityUpdatesHandler.getAreaResourceEntities(event.surface, event.area) - EntityUpdatesHandler.throttleResourceEntitiesUpdate( - Converters.eventNameString(event.name), - event.tick as Tick, - event.surface.index, - [event.position.x, event.position.y], - entities, - ) - } - - - private static throttleEntityUpdate(event: EntityUpdateEvent, entity: LuaEntity) { - - if (entity.unit_number == undefined) { - // ignore for now - I'm not sure how to track entities without a unit_number - return - } - const eventName = Converters.eventNameString(event.name) - - const entityUpdateKey: KafkatorioPacketData.MapChunkEntityUpdate["key"] = { - protoId: Converters.prototypeIdEntity(entity), - surfaceIndex: entity.surface.index, - chunkPosition: Converters.mapPositionToChunkPosition(entity.position) - } - - const entityUpdate: FactorioEntityData.Standard = { - type: FactorioEntityData.Type.Standard, - protoId: Converters.prototypeIdEntity(entity), - graphicsVariation: entity.graphics_variation, - health: entity.health, - isActive: entity.active, - isRotatable: entity.rotatable, - lastUser: entity.last_user?.index, - localisedDescription: null, - localisedName: null, - position: [entity.position.x, entity.position.y], - status: Converters.entityStatus(entity.status), - } - - const entityKey: string = `${entity.unit_number}` - - EventDataCache.throttle( - entityUpdateKey, - KafkatorioPacketData.Type.MapChunkEntityUpdate, - data => { - - data.events ??= {} - data.events[eventName] ??= [] - data.events[eventName].push(event.tick) - - data.distinctEntities ??= {} - data.distinctEntities[entityKey] = entityUpdate - } - ) - } - - - private static throttleResourceEntitiesUpdate( - eventName: EventName, - eventTick: Tick, - surfaceIndex: SurfaceIndex, - chunkPosition: MapChunkPosition, - entities: FactorioEntityData.Resource[], - ) { - - // first group by prototype ID - const entitiesByProtoId: { [protoId: PrototypeId]: FactorioEntityData.Resource[] } = {} - - for (const entity of entities) { - entitiesByProtoId[entity.protoId] ??= [] - entitiesByProtoId[entity.protoId].push(entity) - } - - for (const [protoId, resourceEntities] of pairs(entitiesByProtoId)) { - - // create an update for each prototype - - const entityUpdateKey: KafkatorioPacketData.MapChunkEntityUpdate["key"] = { - protoId: protoId, - surfaceIndex: surfaceIndex, - chunkPosition: [chunkPosition[0], chunkPosition[1]], - } - - EventDataCache.throttle( - entityUpdateKey, - KafkatorioPacketData.Type.MapChunkEntityUpdate, - data => { - - data.events ??= {} - data.events[eventName] ??= [] - data.events[eventName].push(eventTick) - - for (const entity of resourceEntities) { - const [x, y] = entity.position - const entityKey: string = `${x},${y}` - - data.distinctEntities ??= {} - data.distinctEntities[entityKey] = entity - } - } - ) - } - - } - - - /** Get all resources on a tile-position */ - private static getTileResourceEntities( - surface: LuaSurface, - mapPosition: MapPosition, - ): FactorioEntityData.Resource[] { - - const rawEntities = surface.find_entities_filtered({ - position: mapPosition, - collision_mask: "resource-layer", - } - ) - - const resources: FactorioEntityData.Resource[] = [] - - for (const rawEntity of rawEntities) { - const entity = Converters.convertResourceEntity(rawEntity) - if (entity != null) { - resources[resources.length] = entity - } - } - - return resources - } - - - /** Get all resources within a map-area */ - private static getAreaResourceEntities( - surface: LuaSurface, - area: BoundingBoxTable, - ): FactorioEntityData.Resource[] { - - const rawEntities = surface.find_entities_filtered({ - area: area, - collision_mask: "resource-layer", - } - ) - - const resources: FactorioEntityData.Resource[] = [] - - for (const rawEntity of rawEntities) { - const entity = Converters.convertResourceEntity(rawEntity) - if (entity != null) { - resources[resources.length] = entity - } - } - - return resources - } -} - - -const EntityUpdates = new EntityUpdatesHandler() - -export default EntityUpdates - +import EntityUpdates from "./handlers/EntityUpdateHandler"; script.on_event(defines.events.on_built_entity, (e: OnBuiltEntityEvent) => { log(`on_built_entity ${e.tick}`) @@ -248,29 +22,3 @@ script.on_event(defines.events.on_robot_mined_entity, (e: OnRobotMinedEntityEven log(`on_robot_mined_entity ${e.tick}`) EntityUpdates.handleMinedEntityEvent(e) }) - - -type EntityUpdateEvent = - | OnBuiltEntityEvent - - | OnEntityClonedEvent - | OnEntityDamagedEvent - | OnEntityDestroyedEvent - | OnEntityDiedEvent - | OnEntityLogisticSlotChangedEvent - | OnEntityRenamedEvent - | OnEntitySettingsPastedEvent - | OnEntitySpawnedEvent - - | OnPlayerMinedEntityEvent - | OnPlayerRepairedEntityEvent - | OnPlayerRotatedEntityEvent - - | OnRobotMinedEntityEvent - | OnRobotBuiltEntityEvent - - | OnPostEntityDiedEvent - | OnPreEntitySettingsPastedEvent - - | OnSelectedEntityChangedEvent - | OnTriggerCreatedEntityEvent diff --git a/modules/events-mod/src/main/typescript/main/events/handlers/ConfigurationUpdateHandler.ts b/modules/events-mod/src/main/typescript/main/events/handlers/ConfigurationUpdateHandler.ts new file mode 100644 index 0000000..b90fec1 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/events/handlers/ConfigurationUpdateHandler.ts @@ -0,0 +1,62 @@ +import { + ConfigurationUpdateGameData, + ConfigurationUpdateModData, + KafkatorioPacketData +} from "../../../generated/kafkatorio-schema"; +import PacketEmitter from "../../PacketEmitter"; +import ConfigurationUpdate = KafkatorioPacketData.ConfigurationUpdate; + + +export class ConfigurationUpdateHandler { + + + emitConfigurationUpdate(changeData: ConfigurationChangedData) { + + const configUpdateData: ConfigurationUpdate = { + type: KafkatorioPacketData.Type.ConfigurationUpdate, + migrationApplied: changeData.migration_applied, + modStartupSettingsChange: changeData.mod_startup_settings_changed, + allMods: ConfigurationUpdateHandler.allMods(changeData), + factorioData: ConfigurationUpdateHandler.factorioData(changeData) + } + + PacketEmitter.emitInstantPacket(configUpdateData) + } + + + private static factorioData(changeData: ConfigurationChangedData): ConfigurationUpdateGameData { + return { + oldVersion: changeData.old_version ?? null, + newVersion: changeData.new_version ?? null, + } + } + + + private static allMods(e: ConfigurationChangedData): ConfigurationUpdateModData[] { + + let namesOfChangedMods: string[] = Object.keys(e.mod_changes) + let namesOfCurrentMods: string[] = Object.keys(script.active_mods) + + let modNames = [...new Set( + namesOfChangedMods.concat(namesOfCurrentMods) + )] + + return modNames.map((modName) => { + + let currentVer = script.active_mods[modName] ?? e.mod_changes[modName]?.new_version ?? null + let previousVer = e.mod_changes[modName]?.old_version ?? null + + return { + modName: modName, + currentVersion: currentVer, + previousVersion: previousVer, + } + }) + + } + +} + +const ConfigurationUpdates = new ConfigurationUpdateHandler() + +export default ConfigurationUpdates diff --git a/modules/events-mod/src/main/typescript/main/events/handlers/EntityUpdateHandler.ts b/modules/events-mod/src/main/typescript/main/events/handlers/EntityUpdateHandler.ts new file mode 100644 index 0000000..7ac7d13 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/events/handlers/EntityUpdateHandler.ts @@ -0,0 +1,250 @@ +import { + EventName, + FactorioEntityData, + KafkatorioPacketData, + MapChunkPosition, PrototypeId, + Tick +} from "../../../generated/kafkatorio-schema"; +import {Converters} from "../converters"; +import EventDataCache from "../../cache/EventDataCache"; + + +export class EntityUpdatesHandler { + + + handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) { + + const surface = game.get_surface(event.surface_index) + if (surface == null) { + return + } + + const tilesByChunk: LuaTable = new LuaTable() + + for (const tile of event.tiles) { + const chunkPosition = Converters.tilePositionToChunkPosition(tile.position) + tilesByChunk.set(chunkPosition, tile) + } + + for (const [chunkPos, tiles] of pairs(tilesByChunk)) { + + const entities: FactorioEntityData.Resource[] = [] + + for (const tile in tiles) { + const resources: FactorioEntityData.Resource[] = EntityUpdatesHandler.getTileResourceEntities(surface, chunkPos) + for (const resource of resources) { + entities[entities.length] = resource + } + } + + EntityUpdatesHandler.throttleResourceEntitiesUpdate( + Converters.eventNameString(event.name), + event.tick as Tick, + event.surface_index, + [chunkPos[0], chunkPos[1]], + entities, + ) + } + } + + + handleMinedEntityEvent( + event: OnPlayerMinedEntityEvent | OnRobotMinedEntityEvent, + ) { + EntityUpdatesHandler.throttleEntityUpdate(event, event.entity) + } + + + handleBuiltEntityEvent( + event: OnBuiltEntityEvent | OnRobotBuiltEntityEvent, + ) { + EntityUpdatesHandler.throttleEntityUpdate(event, event.created_entity) + } + + + handleChunkGeneratedEvent(event: OnChunkGeneratedEvent) { + const entities = EntityUpdatesHandler.getAreaResourceEntities(event.surface, event.area) + EntityUpdatesHandler.throttleResourceEntitiesUpdate( + Converters.eventNameString(event.name), + event.tick as Tick, + event.surface.index, + [event.position.x, event.position.y], + entities, + ) + } + + + private static throttleEntityUpdate(event: EntityUpdateEvent, entity: LuaEntity) { + + if (entity.unit_number == undefined) { + // ignore for now - I'm not sure how to track entities without a unit_number + return + } + const eventName = Converters.eventNameString(event.name) + + const entityUpdateKey: KafkatorioPacketData.MapChunkEntityUpdate["key"] = { + protoId: Converters.prototypeIdEntity(entity), + surfaceIndex: entity.surface.index, + chunkPosition: Converters.mapPositionToChunkPosition(entity.position) + } + + const entityUpdate: FactorioEntityData.Standard = { + type: FactorioEntityData.Type.Standard, + protoId: Converters.prototypeIdEntity(entity), + graphicsVariation: entity.graphics_variation, + health: entity.health, + isActive: entity.active, + isRotatable: entity.rotatable, + lastUser: entity.last_user?.index, + localisedDescription: null, + localisedName: null, + position: [entity.position.x, entity.position.y], + status: Converters.entityStatus(entity.status), + } + + const entityKey: string = `${entity.unit_number}` + + EventDataCache.throttle( + entityUpdateKey, + KafkatorioPacketData.Type.MapChunkEntityUpdate, + data => { + + data.events ??= {} + data.events[eventName] ??= [] + data.events[eventName].push(event.tick) + + data.distinctEntities ??= {} + data.distinctEntities[entityKey] = entityUpdate + } + ) + } + + + private static throttleResourceEntitiesUpdate( + eventName: EventName, + eventTick: Tick, + surfaceIndex: SurfaceIndex, + chunkPosition: MapChunkPosition, + entities: FactorioEntityData.Resource[], + ) { + + // first group by prototype ID + const entitiesByProtoId: { [protoId: PrototypeId]: FactorioEntityData.Resource[] } = {} + + for (const entity of entities) { + entitiesByProtoId[entity.protoId] ??= [] + entitiesByProtoId[entity.protoId].push(entity) + } + + for (const [protoId, resourceEntities] of pairs(entitiesByProtoId)) { + + // create an update for each prototype + + const entityUpdateKey: KafkatorioPacketData.MapChunkEntityUpdate["key"] = { + protoId: protoId, + surfaceIndex: surfaceIndex, + chunkPosition: [chunkPosition[0], chunkPosition[1]], + } + + EventDataCache.throttle( + entityUpdateKey, + KafkatorioPacketData.Type.MapChunkEntityUpdate, + data => { + + data.events ??= {} + data.events[eventName] ??= [] + data.events[eventName].push(eventTick) + + for (const entity of resourceEntities) { + const [x, y] = entity.position + const entityKey: string = `${x},${y}` + + data.distinctEntities ??= {} + data.distinctEntities[entityKey] = entity + } + } + ) + } + + } + + + /** Get all resources on a tile-position */ + private static getTileResourceEntities( + surface: LuaSurface, + mapPosition: MapPosition, + ): FactorioEntityData.Resource[] { + + const rawEntities = surface.find_entities_filtered({ + position: mapPosition, + collision_mask: "resource-layer", + } + ) + + const resources: FactorioEntityData.Resource[] = [] + + for (const rawEntity of rawEntities) { + const entity = Converters.convertResourceEntity(rawEntity) + if (entity != null) { + resources[resources.length] = entity + } + } + + return resources + } + + + /** Get all resources within a map-area */ + private static getAreaResourceEntities( + surface: LuaSurface, + area: BoundingBoxTable, + ): FactorioEntityData.Resource[] { + + const rawEntities = surface.find_entities_filtered({ + area: area, + collision_mask: "resource-layer", + } + ) + + const resources: FactorioEntityData.Resource[] = [] + + for (const rawEntity of rawEntities) { + const entity = Converters.convertResourceEntity(rawEntity) + if (entity != null) { + resources[resources.length] = entity + } + } + + return resources + } +} + +const EntityUpdates = new EntityUpdatesHandler() + +export default EntityUpdates + + +type EntityUpdateEvent = + | OnBuiltEntityEvent + + | OnEntityClonedEvent + | OnEntityDamagedEvent + | OnEntityDestroyedEvent + | OnEntityDiedEvent + | OnEntityLogisticSlotChangedEvent + | OnEntityRenamedEvent + | OnEntitySettingsPastedEvent + | OnEntitySpawnedEvent + + | OnPlayerMinedEntityEvent + | OnPlayerRepairedEntityEvent + | OnPlayerRotatedEntityEvent + + | OnRobotMinedEntityEvent + | OnRobotBuiltEntityEvent + + | OnPostEntityDiedEvent + | OnPreEntitySettingsPastedEvent + + | OnSelectedEntityChangedEvent + | OnTriggerCreatedEntityEvent diff --git a/modules/events-mod/src/main/typescript/main/events/handlers/MapChunkUpdateHandler.ts b/modules/events-mod/src/main/typescript/main/events/handlers/MapChunkUpdateHandler.ts new file mode 100644 index 0000000..fabbe7c --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/events/handlers/MapChunkUpdateHandler.ts @@ -0,0 +1,242 @@ +import {Converters} from "../converters"; +import {isEventType} from "../eventTypeCheck"; +import { + KafkatorioPacketData, + MapChunkPosition, + MinedProduct, + PrototypeKey +} from "../../../generated/kafkatorio-schema"; +import EventUpdatesManager, {EventUpdates} from "../../cache/EventDataCache"; +import {MapChunkUpdateEvent, MapTileChangeEvent} from "../mapChunkUpdates"; +import PacketKey = EventUpdates.PacketKey; +import Type = MinedProduct.Type; + +type MapChunkTileUpdater = (data: KafkatorioPacketData.MapChunkTileUpdate) => void + + +class MapChunkUpdateHandler { + + handleChunkGeneratedEvent( + event: OnChunkGeneratedEvent, + expirationDurationTicks?: uint, + ) { + const tiles = event.surface.find_tiles_filtered({area: event.area}) + + MapChunkUpdateHandler.mapTilesUpdateDebounce( + event.surface, + Converters.convertMapTablePosition(event.position), + tiles, + event, + undefined, + expirationDurationTicks, + ) + } + + + handleBuiltTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) { + + const surface = game.get_surface(event.surface_index) + if (surface == undefined) { + const eventName = Converters.eventNameString(event.name) + log(`[handleBuiltTileEvent] undefined surface ${eventName}`) + return + } + + const tiles: TileRead[] = Converters.convertPlacedTiles(event.tile, event.tiles) + const groupedTiles = MapChunkUpdateHandler.groupTiles(tiles) + + for (const [chunkPos, tiles] of groupedTiles) { + MapChunkUpdateHandler.mapTilesUpdateDebounce( + surface, + chunkPos, + tiles, + event, + (data => { + if (isEventType(event, defines.events.on_player_built_tile)) { + data.player = event.player_index + return + } + if (isEventType(event, defines.events.on_robot_built_tile)) { + data.robot = { + unitNumber: event.robot?.unit_number ?? null, + protoId: Converters.prototypeId(event.robot.type, event.robot.name), + } + return + } + // this line will not compile if the previous 'if' statements are not exhaustive + // noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols + const exhaustiveCheck: never = event + } + ) + ) + } + } + + + handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) { + const surface = game.get_surface(event.surface_index) + if (surface == undefined) { + const eventName = Converters.eventNameString(event.name) + log(`[handleMinedTileEvent] undefined surface ${eventName}`) + return + } + + const tiles: TileRead[] = Converters.convertRemovedTiles(surface, event.tiles) + const groupedTiles = MapChunkUpdateHandler.groupTiles(tiles) + + for (const [chunkPos, tiles] of groupedTiles) { + + MapChunkUpdateHandler.mapTilesUpdateDebounce( + surface, + chunkPos, + tiles, + event, + (data => { + if (isEventType(event, defines.events.on_player_mined_tile)) { + data.player = event.player_index + return + } + if (isEventType(event, defines.events.on_robot_mined_tile)) { + data.robot = { + unitNumber: event.robot?.unit_number ?? null, + protoId: Converters.prototypeId(event.robot.type, event.robot.name), + } + return + } + // this line will not compile if the previous 'if' statements are not exhaustive + // noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols + const exhaustiveCheck: never = event + } + ) + ) + } + } + + + handleScriptSetTilesEvent(event: ScriptRaisedSetTilesEvent) { + + const surface = game.get_surface(event.surface_index) + if (surface == undefined) { + return + } + + const groupedTiles = MapChunkUpdateHandler.groupTiles(event.tiles) + + for (const [chunkPos, tiles] of groupedTiles) { + MapChunkUpdateHandler.mapTilesUpdateDebounce(surface, chunkPos, tiles, event) + } + } + + + handlePreChunkDeleted(event: OnPreChunkDeletedEvent) { + + const surface = game.get_surface(event.surface_index) + if (surface == undefined) { + return + } + + for (const position of event.positions) { + const key: PacketKey = { + surfaceIndex: surface.index, + chunkPosition: [position.x, position.y], + } + + EventUpdatesManager.debounce( + key, + KafkatorioPacketData.Type.MapChunkTileUpdate, + data => data.isDeleted = true, + 0, // deletion is important - emit ASAP + ) + } + } + + + private static mapTilesUpdateDebounce( + surface: LuaSurface | undefined, + chunkPosition: MapChunkPosition, + tiles: TileRead[], + event: MapChunkUpdateEvent | MapTileChangeEvent, + updater?: MapChunkTileUpdater, + expirationDurationTicks?: uint, + ) { + + if (surface == undefined) { + return + } + + const eventName = Converters.eventNameString(event.name) + + const key: KafkatorioPacketData.MapChunkTileUpdate["key"] = { + surfaceIndex: surface.index, + chunkPosition: chunkPosition, + } + + EventUpdatesManager.debounce( + key, + KafkatorioPacketData.Type.MapChunkTileUpdate, + data => { + + // tile dictionary update + if (data.tileDictionary == undefined) { + data.tileDictionary = { + tilesXY: {}, + protos: {}, + } + } + + let protosCount: uint = table_size(data.tileDictionary.protos) + for (const tile of tiles) { + const protoId = Converters.prototypeId("tile", tile.name) + + if (data.tileDictionary.protos[protoId] == null) { + + } + data.tileDictionary.protos[protoId] ??= protosCount++ as PrototypeKey + + const protoKey = data.tileDictionary.protos[protoId] + + const xString = `${tile.position.x}` + const yString = `${tile.position.y}` + + data.tileDictionary.tilesXY[xString] ??= {} + data.tileDictionary.tilesXY[xString][yString] = protoKey + } + + // events count update + data.events ??= {} + data.events[eventName] ??= [] + data.events[eventName].push(event.tick) + + // apply mutator + if (updater != undefined) { + updater(data) + } + }, + expirationDurationTicks, + ) + } + + + private static groupTiles(tiles: TileRead[]): Map { + + const mapChunkPositionToTiles = new Map() + for (const tile of tiles) { + const chunkPosition: MapChunkPosition = [ + math.floor((tile.position.x / 32)), + math.floor((tile.position.y / 32)), + ] + if (!mapChunkPositionToTiles.has(chunkPosition)) { + mapChunkPositionToTiles.set(chunkPosition, []) + } + mapChunkPositionToTiles.get(chunkPosition)?.push(tile) + } + return mapChunkPositionToTiles + } + + +} + + +const MapChunkUpdate = new MapChunkUpdateHandler() + +export default MapChunkUpdate diff --git a/modules/events-mod/src/main/typescript/main/events/handlers/PlayerUpdateHandler.ts b/modules/events-mod/src/main/typescript/main/events/handlers/PlayerUpdateHandler.ts new file mode 100644 index 0000000..d9a9a14 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/events/handlers/PlayerUpdateHandler.ts @@ -0,0 +1,75 @@ +import {KafkatorioPacketData} from "../../../generated/kafkatorio-schema"; +import {Converters} from "../converters"; +import EventUpdatesManager from "../../cache/EventDataCache"; + + +export type PlayerUpdater = (player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) => void + + +export type PlayerUpdateEvent = + | OnPlayerJoinedGameEvent + | OnPlayerChangedPositionEvent + | OnPlayerChangedSurfaceEvent + | OnPlayerDiedEvent + | OnPlayerBannedEvent + | OnPlayerUnbannedEvent + | OnPlayerKickedEvent + | OnPrePlayerLeftGameEvent + | OnPlayerRemovedEvent + + +export class PlayerUpdateHandler { + + handleBannedEvent(event: OnPlayerBannedEvent | OnPlayerUnbannedEvent) { + this.playerUpdateThrottle( + event, + (player, data) => { + data.bannedReason = event.reason ?? null + Converters.playerOnlineInfo(player, data) + } + ) + } + + + playerUpdateThrottle( + event: PlayerUpdateEvent, + mutate: PlayerUpdater, + expirationDurationTicks: uint | undefined = undefined, + ) { + const playerIndex = event.player_index + if (playerIndex == undefined) { + return + } + + const eventName = Converters.eventNameString(event.name) + + EventUpdatesManager.throttle( + {index: playerIndex}, + KafkatorioPacketData.Type.PlayerUpdate, + data => { + const player = game.players[playerIndex] + if (player != undefined) { + mutate(player, data) + } + + data.events ??= {} + data.events[eventName] ??= [] + data.events[eventName].push(event.tick) + }, + expirationDurationTicks, + ) + } + + + playerUpdateImmediate( + event: PlayerUpdateEvent, + mutate: PlayerUpdater, + ) { + this.playerUpdateThrottle(event, mutate, 0) + } + +} + +const PlayerUpdates = new PlayerUpdateHandler() + +export default PlayerUpdates diff --git a/modules/events-mod/src/main/typescript/main/events/mapChunkUpdates.ts b/modules/events-mod/src/main/typescript/main/events/mapChunkUpdates.ts index e914a5e..ca3cda0 100644 --- a/modules/events-mod/src/main/typescript/main/events/mapChunkUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/mapChunkUpdates.ts @@ -1,17 +1,5 @@ -import {isEventType} from "./eventTypeCheck"; -import {Converters} from "./converters"; -import EventUpdatesManager, {EventUpdates} from "../cache/EventDataCache"; -import { - KafkatorioPacketData, - MapChunkPosition, PrototypeId, - PrototypeKey, -} from "../../generated/kafkatorio-schema"; -import EntityUpdates from "./entityUpdates"; -import CacheKey = EventUpdates.PacketKey; -import Type = KafkatorioPacketData.Type; - - -type MapChunkTileUpdater = (data: KafkatorioPacketData.MapChunkTileUpdate) => void +import EntityUpdates from "./handlers/EntityUpdateHandler"; +import MapChunkUpdate from "./handlers/MapChunkUpdateHandler"; export type MapTileChangeEvent = @@ -29,242 +17,11 @@ export type MapChunkUpdateEvent = | OnPreChunkDeletedEvent -class MapChunkUpdateHandler { - - handleChunkGeneratedEvent( - event: OnChunkGeneratedEvent, - expirationDurationTicks?: uint, - ) { - const tiles = event.surface.find_tiles_filtered({area: event.area}) - - MapChunkUpdateHandler.mapTilesUpdateDebounce( - event.surface, - Converters.convertMapTablePosition(event.position), - tiles, - event, - undefined, - expirationDurationTicks, - ) - } - - - handleBuiltTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) { - - const surface = game.get_surface(event.surface_index) - if (surface == undefined) { - const eventName = Converters.eventNameString(event.name) - log(`[handleBuiltTileEvent] undefined surface ${eventName}`) - return - } - - const tiles: TileRead[] = Converters.convertPlacedTiles(event.tile, event.tiles) - const groupedTiles = MapChunkUpdateHandler.groupTiles(tiles) - - for (const [chunkPos, tiles] of groupedTiles) { - MapChunkUpdateHandler.mapTilesUpdateDebounce( - surface, - chunkPos, - tiles, - event, - (data => { - if (isEventType(event, defines.events.on_player_built_tile)) { - data.player = event.player_index - return - } - if (isEventType(event, defines.events.on_robot_built_tile)) { - data.robot = { - unitNumber: event.robot?.unit_number ?? null, - protoId: Converters.prototypeId(event.robot.type, event.robot.name), - } - return - } - // this line will not compile if the previous 'if' statements are not exhaustive - // noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols - const exhaustiveCheck: never = event - } - ) - ) - } - } - - - handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) { - const surface = game.get_surface(event.surface_index) - if (surface == undefined) { - const eventName = Converters.eventNameString(event.name) - log(`[handleMinedTileEvent] undefined surface ${eventName}`) - return - } - - const tiles: TileRead[] = Converters.convertRemovedTiles(surface, event.tiles) - const groupedTiles = MapChunkUpdateHandler.groupTiles(tiles) - - for (const [chunkPos, tiles] of groupedTiles) { - - MapChunkUpdateHandler.mapTilesUpdateDebounce( - surface, - chunkPos, - tiles, - event, - (data => { - if (isEventType(event, defines.events.on_player_mined_tile)) { - data.player = event.player_index - return - } - if (isEventType(event, defines.events.on_robot_mined_tile)) { - data.robot = { - unitNumber: event.robot?.unit_number ?? null, - protoId: Converters.prototypeId(event.robot.type, event.robot.name), - } - return - } - // this line will not compile if the previous 'if' statements are not exhaustive - // noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols - const exhaustiveCheck: never = event - } - ) - ) - } - } - - - handleScriptSetTilesEvent(event: ScriptRaisedSetTilesEvent) { - - const surface = game.get_surface(event.surface_index) - if (surface == undefined) { - return - } - - const groupedTiles = MapChunkUpdateHandler.groupTiles(event.tiles) - - for (const [chunkPos, tiles] of groupedTiles) { - MapChunkUpdateHandler.mapTilesUpdateDebounce(surface, chunkPos, tiles, event) - } - } - - - handlePreChunkDeleted(event: OnPreChunkDeletedEvent) { - - const surface = game.get_surface(event.surface_index) - if (surface == undefined) { - return - } - - for (const position of event.positions) { - const key: CacheKey = { - surfaceIndex: surface.index, - chunkPosition: [position.x, position.y], - } - - EventUpdatesManager.debounce( - key, - Type.MapChunkTileUpdate, - data => data.isDeleted = true, - 0, // deletion is important - emit ASAP - ) - } - } - - - private static mapTilesUpdateDebounce( - surface: LuaSurface | undefined, - chunkPosition: MapChunkPosition, - tiles: TileRead[], - event: MapChunkUpdateEvent | MapTileChangeEvent, - updater?: MapChunkTileUpdater, - expirationDurationTicks?: uint, - ) { - - if (surface == undefined) { - return - } - - const eventName = Converters.eventNameString(event.name) - - const key: KafkatorioPacketData.MapChunkTileUpdate["key"] = { - surfaceIndex: surface.index, - chunkPosition: chunkPosition, - } - - EventUpdatesManager.debounce( - key, - Type.MapChunkTileUpdate, - data => { - - // tile dictionary update - if (data.tileDictionary == undefined) { - data.tileDictionary = { - tilesXY: {}, - protos: {}, - } - } - - let protosCount: uint = table_size(data.tileDictionary.protos) - for (const tile of tiles) { - const protoId = Converters.prototypeId("tile", tile.name) - - if (data.tileDictionary.protos[protoId] == null) { - - } - data.tileDictionary.protos[protoId] ??= protosCount++ as PrototypeKey - - const protoKey = data.tileDictionary.protos[protoId] - - const xString = `${tile.position.x}` - const yString = `${tile.position.y}` - - data.tileDictionary.tilesXY[xString] ??= {} - data.tileDictionary.tilesXY[xString][yString] = protoKey - } - - // events count update - data.events ??= {} - data.events[eventName] ??= [] - data.events[eventName].push(event.tick) - - // apply mutator - if (updater != undefined) { - updater(data) - } - }, - expirationDurationTicks, - ) - } - - - private static groupTiles(tiles: TileRead[]): Map { - - const mapChunkPositionToTiles = new Map() - for (const tile of tiles) { - const chunkPosition: MapChunkPosition = [ - math.floor((tile.position.x / 32)), - math.floor((tile.position.y / 32)), - ] - if (!mapChunkPositionToTiles.has(chunkPosition)) { - mapChunkPositionToTiles.set(chunkPosition, []) - } - mapChunkPositionToTiles.get(chunkPosition)?.push(tile) - } - return mapChunkPositionToTiles - } - - -} - - -const MapChunkUpdate = new MapChunkUpdateHandler() - -export default MapChunkUpdate - - -script.on_event( - defines.events.on_chunk_generated, - (e: OnChunkGeneratedEvent) => { - log(`on_chunk_generated ${e.tick}`) - MapChunkUpdate.handleChunkGeneratedEvent(e) - EntityUpdates.handleChunkGeneratedEvent(e) - } -) +script.on_event(defines.events.on_chunk_generated, (e: OnChunkGeneratedEvent) => { + log(`on_chunk_generated ${e.tick}`) + MapChunkUpdate.handleChunkGeneratedEvent(e) + EntityUpdates.handleChunkGeneratedEvent(e) +}) // script.on_event( diff --git a/modules/events-mod/src/main/typescript/main/events/playerUpdates.ts b/modules/events-mod/src/main/typescript/main/events/playerUpdates.ts index 18b46f2..d20afb4 100644 --- a/modules/events-mod/src/main/typescript/main/events/playerUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/playerUpdates.ts @@ -1,61 +1,7 @@ import {Converters} from "./converters"; -import EventUpdatesManager from "../cache/EventDataCache"; import {ForceIndex, KafkatorioPacketData, PlayerUpdateKey} from "../../generated/kafkatorio-schema"; import packetEmitter from "../PacketEmitter"; -import Type = KafkatorioPacketData.Type; - - -type PlayerUpdater = (player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) => void - - -type PlayerUpdateEvent = - | OnPlayerJoinedGameEvent - | OnPlayerChangedPositionEvent - | OnPlayerChangedSurfaceEvent - | OnPlayerDiedEvent - | OnPlayerBannedEvent - | OnPlayerUnbannedEvent - | OnPlayerKickedEvent - | OnPrePlayerLeftGameEvent - | OnPlayerRemovedEvent - - -function playerUpdateThrottle( - event: PlayerUpdateEvent, - mutate: PlayerUpdater, - expirationDurationTicks: uint | undefined = undefined, -) { - const playerIndex = event.player_index - if (playerIndex == undefined) { - return - } - - const eventName = Converters.eventNameString(event.name) - - EventUpdatesManager.throttle( - {index: playerIndex }, - Type.PlayerUpdate, - data => { - const player = game.players[playerIndex] - if (player != undefined) { - mutate(player, data) - } - - data.events ??= {} - data.events[eventName] ??= [] - data.events[eventName].push(event.tick) - }, - expirationDurationTicks, - ) -} - - -function playerUpdateImmediate( - event: PlayerUpdateEvent, - mutate: PlayerUpdater, -) { - playerUpdateThrottle(event, mutate, 0) -} +import PlayerUpdates from "./handlers/PlayerUpdateHandler"; // function playerUpdateDebounce(playerIndex: uint, mutate: PlayerUpdater) { @@ -68,154 +14,122 @@ function playerUpdateImmediate( // ) // } -function playerOnlineInfo(player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) { - data.lastOnline = player.last_online - data.onlineTime = player.online_time - data.afkTime = player.afk_time - data.isConnected = player.connected -} -script.on_event( - defines.events.on_player_joined_game, - (e: OnPlayerJoinedGameEvent) => { - playerUpdateThrottle( - e, - (player, data) => { - data.isAdmin = player.admin - data.characterUnitNumber = player.character?.unit_number ?? null - data.chatColour = Converters.mapColour(player.chat_color) - data.colour = Converters.mapColour(player.color) - data.forceIndex = player.force.index as ForceIndex - data.name = player.name - data.isShowOnMap = player.show_on_map - data.isSpectator = player.spectator - data.surfaceIndex = player.surface.index - data.tag = player.tag - playerOnlineInfo(player, data) - } - ) - } -) - - -script.on_event( - defines.events.on_player_changed_position, - (e: OnPlayerChangedPositionEvent) => { - playerUpdateThrottle( - e, - (player, data) => { - data.position = [player.position.x, player.position.y] - } - ) - } -) - - -script.on_event( - defines.events.on_player_changed_surface, - (e: OnPlayerChangedSurfaceEvent) => { - playerUpdateThrottle( - e, - (player, data) => { - data.position = [player.position.x, player.position.y] - data.surfaceIndex = player.surface.index - } - ) - } -) - - -script.on_event( - defines.events.on_player_died, - (e: OnPlayerDiedEvent) => { - playerUpdateThrottle( - e, - (player, data) => { - data.ticksToRespawn = player.ticks_to_respawn ?? null - playerOnlineInfo(player, data) - if (e.cause != undefined) { - data.diedCause = { - unitNumber: e.cause.unit_number ?? null, - protoId: Converters.prototypeId(e.cause.type, e.cause.name), - } - } - } - ) - } -) - - -script.on_event(defines.events.on_player_banned, handleBannedEvent) -script.on_event(defines.events.on_player_unbanned, handleBannedEvent) - -function handleBannedEvent(event: OnPlayerBannedEvent | OnPlayerUnbannedEvent) { - playerUpdateThrottle( - event, +script.on_event(defines.events.on_player_joined_game, (e: OnPlayerJoinedGameEvent) => { + PlayerUpdates.playerUpdateThrottle( + e, (player, data) => { - data.bannedReason = event.reason ?? null - playerOnlineInfo(player, data) + data.isAdmin = player.admin + data.characterUnitNumber = player.character?.unit_number ?? null + data.chatColour = Converters.mapColour(player.chat_color) + data.colour = Converters.mapColour(player.color) + data.forceIndex = player.force.index as ForceIndex + data.name = player.name + data.isShowOnMap = player.show_on_map + data.isSpectator = player.spectator + data.surfaceIndex = player.surface.index + data.tag = player.tag + Converters.playerOnlineInfo(player, data) } ) -} +}) -script.on_event( - defines.events.on_player_kicked, - (event: OnPlayerKickedEvent) => { - log(`on_player_kicked ${event.tick} ${event.name}`) - playerUpdateImmediate( - event, - (player, data) => { - data.kickedReason = event.reason ?? null - playerOnlineInfo(player, data) +script.on_event(defines.events.on_player_changed_position, (e: OnPlayerChangedPositionEvent) => { + PlayerUpdates.playerUpdateThrottle( + e, + (player, data) => { + data.position = [player.position.x, player.position.y] + } + ) +}) + + +script.on_event(defines.events.on_player_changed_surface, (e: OnPlayerChangedSurfaceEvent) => { + PlayerUpdates.playerUpdateThrottle( + e, + (player, data) => { + data.position = [player.position.x, player.position.y] + data.surfaceIndex = player.surface.index + } + ) +}) + + +script.on_event(defines.events.on_player_died, (e: OnPlayerDiedEvent) => { + PlayerUpdates.playerUpdateThrottle( + e, + (player, data) => { + data.ticksToRespawn = player.ticks_to_respawn ?? null + Converters.playerOnlineInfo(player, data) + if (e.cause != undefined) { + data.diedCause = { + unitNumber: e.cause.unit_number ?? null, + protoId: Converters.prototypeId(e.cause.type, e.cause.name), } - ) - } -) + } + } + ) +}) + + +script.on_event(defines.events.on_player_banned, (event: OnPlayerBannedEvent) => { + PlayerUpdates.handleBannedEvent(event) +}) +script.on_event(defines.events.on_player_unbanned, (event: OnPlayerBannedEvent) => { + PlayerUpdates.handleBannedEvent(event) +}) + + +script.on_event(defines.events.on_player_kicked, (event: OnPlayerKickedEvent) => { + log(`on_player_kicked ${event.tick} ${event.name}`) + PlayerUpdates.playerUpdateImmediate( + event, + (player, data) => { + data.kickedReason = event.reason ?? null + Converters.playerOnlineInfo(player, data) + } + ) +}) + + +script.on_event(defines.events.on_pre_player_left_game, (event: OnPrePlayerLeftGameEvent) => { + log(`on_pre_player_left_game ${event.tick} ${event.name}`) + + const playerUpdateKey: PlayerUpdateKey = { + index: event.player_index, + } + + const playerUpdate: KafkatorioPacketData.PlayerUpdate = { + type: KafkatorioPacketData.Type.PlayerUpdate, + key: playerUpdateKey, + disconnectReason: disconnectReasons.get(event.reason) + } + + packetEmitter.emitKeyedPacket(playerUpdate) + + // playerUpdateImmediate( + // event, + // (player, data) => { + // data.disconnectReason = disconnectReasons.get(event.reason) + // playerOnlineInfo(player, data) + // } + // ) +}) + +script.on_event(defines.events.on_player_removed, (event: OnPlayerRemovedEvent) => { + log(`on_player_removed ${event.tick} ${event.name}`) + PlayerUpdates.playerUpdateImmediate( + event, + (player, data) => { + data.isRemoved = true + Converters.playerOnlineInfo(player, data) + } + ) +}) const disconnectReasons = new LuaTable() for (const [name, disconnectId] of pairs(defines.disconnect_reason)) { disconnectReasons.set(disconnectId, name) } - -script.on_event( - defines.events.on_pre_player_left_game, - (event: OnPrePlayerLeftGameEvent) => { - log(`on_pre_player_left_game ${event.tick} ${event.name}`) - - const playerUpdateKey: PlayerUpdateKey = { - index: event.player_index , - } - - const playerUpdate: KafkatorioPacketData.PlayerUpdate = { - type: KafkatorioPacketData.Type.PlayerUpdate, - key: playerUpdateKey, - disconnectReason: disconnectReasons.get(event.reason) - } - - packetEmitter.emitKeyedPacket(playerUpdate) - - // playerUpdateImmediate( - // event, - // (player, data) => { - // data.disconnectReason = disconnectReasons.get(event.reason) - // playerOnlineInfo(player, data) - // } - // ) - } -) - -script.on_event( - defines.events.on_player_removed, - (event: OnPlayerRemovedEvent) => { - log(`on_player_removed ${event.tick} ${event.name}`) - playerUpdateImmediate( - event, - (player, data) => { - data.isRemoved = true - playerOnlineInfo(player, data) - } - ) - } -) diff --git a/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts b/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts index b424383..6d17469 100644 --- a/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts @@ -1,33 +1,48 @@ import PacketEmitter from "../PacketEmitter"; -import {FactorioPrototype, KafkatorioPacketData} from "../../generated/kafkatorio-schema"; +import { + EntityItemGroup, + FactorioPrototype, + KafkatorioPacketData +} from "../../generated/kafkatorio-schema"; import {Converters} from "./converters"; -import PrototypesUpdate = KafkatorioPacketData.PrototypesUpdate; + + +type PrototypesByType = LuaTable export function emitPrototypes() { - const data: PrototypesUpdate = { - prototypes: prototypeUpdates(), - type: KafkatorioPacketData.Type.PrototypesUpdate, + const mapTileProtos: PrototypesByType = getMapTilePrototypes() + emit(mapTileProtos) + + + game.item_group_prototypes + game.item_subgroup_prototypes + + + const entityProtos: PrototypesByType = getEntityPrototypes() + emit(entityProtos) +} + + +function emit(protosByType: PrototypesByType) { + for (const [, protos] of pairs(protosByType)) { + PacketEmitter.emitInstantPacket({ + type: KafkatorioPacketData.Type.PrototypesUpdate, + prototypes: protos, + }) + } +} + + +function getMapTilePrototypes(): PrototypesByType { + const tiles = new LuaTable() + if (!tiles.has("tile")) { + tiles.set("tile", []) } - PacketEmitter.emitInstantPacket(data) -} - - -function prototypeUpdates(): FactorioPrototype[] { - let prototypes: FactorioPrototype[] = [] - - prototypes.push(...getMapTilePrototypes()) - - return prototypes -} - - -function getMapTilePrototypes(): FactorioPrototype.MapTile[] { - let tiles: FactorioPrototype.MapTile[] = [] for (const [, tile] of game.tile_prototypes) { - tiles.push({ + tiles.get("tile").push({ type: FactorioPrototype.Type.MapTile, protoId: Converters.prototypeId("tile", tile.name), @@ -42,19 +57,59 @@ function getMapTilePrototypes(): FactorioPrototype.MapTile[] { } -// function getEntityPrototypes(): FactorioPrototype.MapTile[] { -// let tiles: FactorioPrototype.MapTile[] = [] -// for (const [, tile] of game.tile_prototypes) { -// tiles.push({ -// type: FactorioPrototype.Type.MapTile, -// -// name: tile.name, -// order: tile.order, -// layer: tile.layer, -// collisionMasks: convertCollisionMaskToNames(tile.collision_mask), -// mapColour: Converters.mapColour(tile.map_color), -// canBeMined: tile.mineable_properties.minable, -// }) -// } -// return tiles -// } +function getEntityPrototypes(): PrototypesByType { + const protos = new LuaTable() + + for (const [, entity] of game.entity_prototypes) { + const key: string = `${entity.group.name}/${entity.subgroup.name}` + + if (!protos.has(key)) { + protos.set(key, []) + } + + const entityProto: FactorioPrototype.Entity = { + type: FactorioPrototype.Type.Entity, + protoId: Converters.prototypeId(entity.type, entity.name), + + group: convertItemGroup(entity.group), + subgroup: convertItemSubgroup(entity.subgroup), + + isBuilding: entity.is_building, + isEntityWithOwner: entity.is_entity_with_owner, + isMilitaryTarget: entity.is_military_target, + maxHealth: entity.max_health, + } + + if (entity.map_color != undefined) { + entityProto.mapColour = Converters.mapColour(entity.map_color) + } + if (entity.friendly_map_color != undefined) { + entityProto.mapColourFriend = Converters.mapColour(entity.friendly_map_color) + } + if (entity.enemy_map_color != undefined) { + entityProto.mapColourEnemy = Converters.mapColour(entity.enemy_map_color) + } + entityProto.miningProperties = Converters.miningProperties(entity.mineable_properties) + + protos.get(key).push(entityProto) + } + return protos +} + + +function convertItemGroup(itemGroup: LuaGroup): EntityItemGroup { + return { + name: itemGroup.name, + type: itemGroup.type, + parentName: null, + } +} + + +function convertItemSubgroup(itemGroup: LuaGroup): EntityItemGroup { + return { + name: itemGroup.name, + type: itemGroup.type, + parentName: itemGroup.group?.name, + } +} diff --git a/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts index 095c3a2..54ee97e 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts @@ -3,7 +3,7 @@ import {isEventType} from "./eventTypeCheck"; import {Converters} from "./converters"; import {handleSurfaceUpdate} from "./surfaceUpdates"; import EventCacheService from "../cache/EventDataCache"; -import MapChunkUpdate from "./mapChunkUpdates"; +import MapChunkUpdate from "./handlers/MapChunkUpdateHandler"; script.on_event( diff --git a/modules/events-mod/src/main/typescript/main/events/resourceEntityUpdates.ts b/modules/events-mod/src/main/typescript/main/events/resourceEntityUpdates.ts deleted file mode 100644 index 5955137..0000000 --- a/modules/events-mod/src/main/typescript/main/events/resourceEntityUpdates.ts +++ /dev/null @@ -1,99 +0,0 @@ -// import {isEventType} from "./eventTypeCheck"; -// import {Converters} from "./converters"; -// import EventUpdatesManager, {EventUpdates} from "../cache/EventDataCache"; -// import { -// KafkatorioPacketData, -// MapChunkPosition, -// PrototypeKey, -// } from "../../generated/kafkatorio-schema"; -// import CacheKey = EventUpdates.PacketKey; -// import Type = KafkatorioPacketData.Type; -// -// -// export class ResourceEntityUpdatesHandler { -// -// -// handleChunkGeneratedEvent( -// event: OnChunkGeneratedEvent, -// expirationDurationTicks?: uint, -// ) { -// const resourceEntities = this.getAreaResourceEntities(event.surface, event.area) -// -// mapTilesUpdateDebounce( -// event.surface, -// Converters.convertMapTablePosition(event.position), -// tiles, -// event, -// undefined, -// expirationDurationTicks, -// ) -// } -// -// -// private resourceEntityUpdatesThrottle( -// surface: LuaSurface | undefined, -// chunkPosition: MapChunkPosition, -// tiles: TileRead[], -// event: MapTileUpdateEvent, -// updater?: MapChunkUpdater, -// expirationDurationTicks?: uint, -// ) { -// -// if (surface == undefined) { -// return -// } -// -// const eventName = Converters.eventNameString(event.name) -// -// const key: KafkatorioPacketData.ResourceEntitiesUpdate["key"] = { -// surfaceIndex: surface.index as SurfaceIndex, -// chunkPosition: chunkPosition, -// } -// -// EventUpdatesManager.throttle( -// key, -// Type.MapChunkUpdate, -// data => { -// -// // tile dictionary update -// if (data.tileDictionary == undefined) { -// data.tileDictionary = { -// tilesXY: {}, -// protos: {}, -// } -// } -// -// let protosCount: uint = table_size(data.tileDictionary.protos) -// for (const tile of tiles) { -// const tileName = tile.name as PrototypeIdMapTile -// const protoKey = protosCount++ as PrototypeKey -// data.tileDictionary.protos[tileName] ??= protoKey -// -// const xString = `${tile.position.x}` -// const yString = `${tile.position.y}` -// -// data.tileDictionary.tilesXY[xString] ??= {} -// data.tileDictionary.tilesXY[xString][yString] = protoKey -// } -// -// // events count update -// data.events ??= {} -// data.events[eventName] ??= [] -// data.events[eventName].push(event.tick) -// -// // apply mutator -// if (updater != undefined) { -// updater(data) -// } -// }, -// expirationDurationTicks, -// ) -// } -// -// } -// -// -// -// const ResourceEntityUpdates = new ResourceEntityUpdatesHandler() -// -// export default ResourceEntityUpdates diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt index b4a7528..c7f02cd 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt @@ -211,16 +211,15 @@ fun KTable>.streamMapChunkColou val pid = "$pid.output-chunk.${chunkSize.name}" toStream("$pid.stream") - .filter("$pid.filter-tiles-not-empty") { _, v -> - !v?.map.isNullOrEmpty() + .filter("$pid.filter-tiles-not-empty") { _, chunkTiles -> + !chunkTiles?.map.isNullOrEmpty() } - .mapValues("$pid.map-not-null") { _, v -> - requireNotNull(v) + .mapValues("$pid.map-not-null") { _, chunkTiles -> + requireNotNull(chunkTiles) } - .peek("$pid.print-group-result") { _, v -> - println("Grouping map tiles result: ${v.chunkId} / ${v.map.size}") - } - .to( + .peek("$pid.print-group-result") { _, chunkTiles -> + println("Grouping map tiles result: ${chunkTiles.chunkId} / size:${chunkTiles.map.size}") + }.to( outputTopic, producedAs( "$pid.grouped-map-chunks", From 0e6a9880ff435e9b79a4d45cf089e3c681e3a431 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 8 Jul 2022 21:06:50 +0200 Subject: [PATCH 466/629] add k svg (maybe do resources in SVGs?) --- gradle/libs.versions.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fa2fbf6..579a7a0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -33,6 +33,8 @@ kotlinx-datetime = "0.3.3" kotlinx-html = "0.7.5" kotlinx-nodejs = "0.0.7" +kSvgDsl = "v2.2.0" + ktor = "2.0.3" hoplite = "2.1.5" @@ -111,6 +113,9 @@ kotlinx-cli = { group = "org.jetbrains.kotlinx", name = "kotl kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinx-datetime" } +kSvgDsl = { group = "com.github.nwillc", name = "ksvg", version.ref = "kSvgDsl" } + + kotlin-jsWrappers-bom = { group = "org.jetbrains.kotlin-wrappers", name = "kotlin-wrappers-bom", version.ref = "kotlinJsWrappers" } From ae0eb98f126dac837fceda3108aadf5a886902b3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 8 Jul 2022 21:48:19 +0200 Subject: [PATCH 467/629] version bump --- build.gradle.kts | 2 +- modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- modules/events-server/docker/.env | 2 +- modules/infra-factorio-server/src/.env | 2 +- modules/infra-kafka-cluster/src/.env | 2 +- modules/infra-kafka-pipe/src/.env | 2 +- modules/web-map/docker/.env | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index aa78c3d..eda9b8e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.7.0" +version = "0.7.1" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 840585c..82b0c61 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.7.0", + "version": "0.7.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 5ba45ac..83e563c 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.7.0", + "version": "0.7.1", "private": true, "scripts": { "build": "tstl", diff --git a/modules/events-server/docker/.env b/modules/events-server/docker/.env index e000eaa..45177a6 100644 --- a/modules/events-server/docker/.env +++ b/modules/events-server/docker/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.7.0 +KAFKATORIO_VERSION=0.7.1 diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index e0b28af..f085f4c 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio FACTORIO_VERSION=1.1.61 -KAFKATORIO_VERSION=0.7.0 +KAFKATORIO_VERSION=0.7.1 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index 2279b0c..29cc092 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,7 +1,7 @@ # Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio GRAFANA_VERSION=8.5.0 -KAFKATORIO_VERSION=0.7.0 +KAFKATORIO_VERSION=0.7.1 KAFKA_DL_URL=https\://dlcdn.apache.org/kafka/3.2.0/kafka_2.13-3.2.0.tgz KAFKA_VERSION=3.2.0 PROMETHEUS_VERSION=v2.34.0 diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index e000eaa..45177a6 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.7.0 +KAFKATORIO_VERSION=0.7.1 diff --git a/modules/web-map/docker/.env b/modules/web-map/docker/.env index e000eaa..45177a6 100644 --- a/modules/web-map/docker/.env +++ b/modules/web-map/docker/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.7.0 +KAFKATORIO_VERSION=0.7.1 From 90aa086dd4cbf50450dcbb895364928661c9b16e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 9 Jul 2022 14:03:57 +0200 Subject: [PATCH 468/629] mod: entity prototype improvements and refactoring - refactor and move queue & emitter classes for consistency - don't emit all prototypes at once - add simple queue for 'instant' packets so the printer doesn't get overwhelmed and mix up the output --- .../lua/main/cache/EventDataCache.lua | 144 ----------- .../lua/main/commands/kafkatorioCommands.lua | 6 +- .../lua/main/emitting/EventDataCache.lua | 141 ++++++++++ .../main/emitting/KafkatorioPacketQueue.lua | 44 ++++ .../lua/main/{ => emitting}/PacketEmitter.lua | 0 .../lua/main/events/consoleUpdates.lua | 13 +- .../handlers/ConfigurationUpdateHandler.lua | 6 +- .../events/handlers/EntityUpdateHandler.lua | 2 +- .../events/handlers/MapChunkUpdateHandler.lua | 8 +- .../events/handlers/PlayerUpdateHandler.lua | 6 +- .../lua/main/events/playerUpdates.lua | 2 +- .../lua/main/events/prototypeUpdates.lua | 34 +-- .../main/events/registerEventListeners.lua | 18 +- .../lua/main/events/surfaceUpdates.lua | 2 +- .../src/generated/lua/main/global-init.lua | 10 +- .../src/generated/lua/main/queue/queue.lua | 147 +++++------ .../typescript/main/cache/EventDataCache.ts | 235 ----------------- .../main/commands/kafkatorioCommands.ts | 4 +- .../main/emitting/EventDataCache.ts | 240 ++++++++++++++++++ .../main/emitting/KafkatorioPacketQueue.ts | 48 ++++ .../main/{ => emitting}/PacketEmitter.ts | 7 +- .../typescript/main/events/consoleUpdates.ts | 43 ++-- .../handlers/ConfigurationUpdateHandler.ts | 5 +- .../events/handlers/EntityUpdateHandler.ts | 2 +- .../events/handlers/MapChunkUpdateHandler.ts | 10 +- .../events/handlers/PlayerUpdateHandler.ts | 4 +- .../typescript/main/events/playerUpdates.ts | 2 +- .../main/events/prototypeUpdates.ts | 33 +-- .../main/events/registerEventListeners.ts | 67 ++--- .../typescript/main/events/settingsUpdate.ts | 11 +- .../typescript/main/events/surfaceUpdates.ts | 2 +- .../src/main/typescript/main/global-init.ts | 8 +- .../src/main/typescript/main/queue/queue.ts | 90 ++++--- 33 files changed, 742 insertions(+), 652 deletions(-) delete mode 100644 modules/events-mod/src/generated/lua/main/cache/EventDataCache.lua create mode 100644 modules/events-mod/src/generated/lua/main/emitting/EventDataCache.lua create mode 100644 modules/events-mod/src/generated/lua/main/emitting/KafkatorioPacketQueue.lua rename modules/events-mod/src/generated/lua/main/{ => emitting}/PacketEmitter.lua (100%) delete mode 100644 modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts create mode 100644 modules/events-mod/src/main/typescript/main/emitting/EventDataCache.ts create mode 100644 modules/events-mod/src/main/typescript/main/emitting/KafkatorioPacketQueue.ts rename modules/events-mod/src/main/typescript/main/{ => emitting}/PacketEmitter.ts (85%) diff --git a/modules/events-mod/src/generated/lua/main/cache/EventDataCache.lua b/modules/events-mod/src/generated/lua/main/cache/EventDataCache.lua deleted file mode 100644 index 610cf57..0000000 --- a/modules/events-mod/src/generated/lua/main/cache/EventDataCache.lua +++ /dev/null @@ -1,144 +0,0 @@ -local ____lualib = require("lualib_bundle") -local __TS__Class = ____lualib.__TS__Class -local __TS__New = ____lualib.__TS__New -local ____exports = {} -local ____KafkatorioSettings = require("main.settings.KafkatorioSettings") -local KafkatorioSettings = ____KafkatorioSettings.default -local ____PacketEmitter = require("main.PacketEmitter") -local packetEmitter = ____PacketEmitter.default -____exports.EventUpdates = {} -local EventUpdates = ____exports.EventUpdates -do - local CacheEntry - EventUpdates.Manager = __TS__Class() - local Manager = EventUpdates.Manager - Manager.name = "Manager" - function Manager.prototype.____constructor(self) - end - function Manager.prototype.init(self, force) - local isAnythingUndefined = global.cache == nil - log(((("Initialising EventDataCache (force=" .. tostring(force)) .. ", isAnythingUndefined=") .. tostring(isAnythingUndefined)) .. ")...") - if force == true or isAnythingUndefined then - log("Initialising global.cache") - global.cache = {} - end - log("Finished initialising EventDataCache") - end - function Manager.prototype.throttle(self, key, ____type, mutate, expirationDurationTicks) - self:update( - key, - ____type, - mutate, - false, - expirationDurationTicks - ) - end - function Manager.prototype.debounce(self, key, ____type, mutate, expirationDurationTicks) - self:update( - key, - ____type, - mutate, - true, - expirationDurationTicks - ) - end - function Manager.prototype.update(self, key, ____type, mutate, resetLastUpdated, expirationDurationTicks) - local entry = self:getCacheEntry(key, ____type) or EventUpdates.Manager:createCacheEntry(key, ____type) - mutate(entry.packet) - if resetLastUpdated then - entry.lastUpdatedTick = game.tick - end - if expirationDurationTicks ~= nil then - entry.expirationDurationTicks = expirationDurationTicks - end - if entry.expirationDurationTicks ~= nil and entry.expirationDurationTicks <= 0 then - self:extractAndEmitExpiredPackets() - end - end - function Manager.prototype.setExpiration(self, key, ____type, expirationDurationTicks) - local entry = self:getCacheEntry(key, ____type) - if entry ~= nil then - entry.expirationDurationTicks = expirationDurationTicks - end - end - function Manager.prototype.extractExpired(self) - local countExpired = 0 - local countTotal = 0 - local expiredData = {} - for key, entry in pairs(global.cache) do - countTotal = countTotal + 1 - if self:isExpired(entry) then - countExpired = countExpired + 1 - expiredData[#expiredData + 1] = entry.packet - global.cache[key] = nil - end - end - local hasExpiredItems = countExpired > 0 - local hasAnyItem = countTotal > 0 - if hasExpiredItems or game.tick % 30 == 0 and hasAnyItem then - log((("[extractExpired] expired items: " .. tostring(countExpired)) .. ", total: ") .. tostring(countTotal)) - end - return expiredData - end - function Manager.prototype.extractAndEmitExpiredPackets(self) - local cachedEvents = self:extractExpired() - if #cachedEvents > 0 then - log((("[EventDataCache] emitting " .. tostring(#cachedEvents)) .. " events on tick ") .. tostring(game.tick)) - for ____, event in ipairs(cachedEvents) do - packetEmitter:emitKeyedPacket(event) - end - end - return #cachedEvents - end - function Manager.prototype.getCacheEntry(self, key, ____type) - local hash = EventUpdates.Manager:hashKey(key) - if not (global.cache[hash] ~= nil) then - return nil - end - local value = global.cache[hash] - if self:isEntryInstanceOf(value, ____type) then - return value - else - return nil - end - end - function Manager.createCacheEntry(self, key, ____type) - local data = {type = ____type, key = key} - local entry = __TS__New(CacheEntry, data) - local hash = EventUpdates.Manager:hashKey(key) - global.cache[hash] = entry - return entry - end - function Manager.prototype.isExpired(self, entry) - local expiryDuration = entry.expirationDurationTicks or KafkatorioSettings:getEventCacheExpirationTicks(entry.packet) - if expiryDuration == nil then - return true - else - return game.tick - entry.lastUpdatedTick > expiryDuration - end - end - function Manager.prototype.isEntryInstanceOf(self, entry, ____type) - local ____self_isDataInstanceOf_2 = self.isDataInstanceOf - local ____entry_packet_0 = entry - if ____entry_packet_0 ~= nil then - ____entry_packet_0 = ____entry_packet_0.packet - end - return ____self_isDataInstanceOf_2(self, ____entry_packet_0, ____type) - end - function Manager.prototype.isDataInstanceOf(self, packet, ____type) - return packet ~= nil and packet.type == ____type - end - function Manager.hashKey(self, key) - return game.encode_string(game.table_to_json(key)) - end - CacheEntry = __TS__Class() - CacheEntry.name = "CacheEntry" - function CacheEntry.prototype.____constructor(self, packet, expirationDurationTicks) - self.lastUpdatedTick = game.tick - self.packet = packet - self.expirationDurationTicks = expirationDurationTicks - end -end -local EventUpdatesManager = __TS__New(____exports.EventUpdates.Manager) -____exports.default = EventUpdatesManager -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/commands/kafkatorioCommands.lua b/modules/events-mod/src/generated/lua/main/commands/kafkatorioCommands.lua index e9939d2..48f6c25 100644 --- a/modules/events-mod/src/generated/lua/main/commands/kafkatorioCommands.lua +++ b/modules/events-mod/src/generated/lua/main/commands/kafkatorioCommands.lua @@ -5,10 +5,10 @@ local __TS__ParseInt = ____lualib.__TS__ParseInt local ____exports = {} local ____global_2Dinit = require("main.global-init") local initGlobal = ____global_2Dinit.initGlobal -local ____queue = require("main.queue.queue") -local Queue = ____queue.Queue local ____prototypeUpdates = require("main.events.prototypeUpdates") local emitPrototypes = ____prototypeUpdates.emitPrototypes +local ____queue = require("main.queue.queue") +local EventDataQueue = ____queue.default commands.add_command( "kafkatorio", "kafkatorio innit bruv", @@ -56,7 +56,7 @@ commands.add_command( surface = surface, tick = e.tick } - Queue.enqueue( + EventDataQueue:enqueue( (tostring(surface.index) .. tostring(chunk.x)) .. tostring(chunk.y), data, 50 diff --git a/modules/events-mod/src/generated/lua/main/emitting/EventDataCache.lua b/modules/events-mod/src/generated/lua/main/emitting/EventDataCache.lua new file mode 100644 index 0000000..7d4b9be --- /dev/null +++ b/modules/events-mod/src/generated/lua/main/emitting/EventDataCache.lua @@ -0,0 +1,141 @@ +local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local __TS__New = ____lualib.__TS__New +local ____exports = {} +local CacheEntry +local ____KafkatorioSettings = require("main.settings.KafkatorioSettings") +local KafkatorioSettings = ____KafkatorioSettings.default +local ____PacketEmitter = require("main.emitting.PacketEmitter") +local PacketEmitter = ____PacketEmitter.default +____exports.EventUpdatesManager = __TS__Class() +local EventUpdatesManager = ____exports.EventUpdatesManager +EventUpdatesManager.name = "EventUpdatesManager" +function EventUpdatesManager.prototype.____constructor(self) + self:init() +end +function EventUpdatesManager.prototype.init(self, force) + local isAnythingUndefined = global.eventUpdatesManagerCache == nil + log(((("Initialising EventDataCache (force=" .. tostring(force)) .. ", isAnythingUndefined=") .. tostring(isAnythingUndefined)) .. ")...") + if force == true or isAnythingUndefined then + log("Initialising global.cache") + global.eventUpdatesManagerCache = {} + end + log("Finished initialising EventDataCache") +end +function EventUpdatesManager.prototype.throttle(self, key, ____type, mutate, expirationDurationTicks) + self:update( + key, + ____type, + mutate, + false, + expirationDurationTicks + ) +end +function EventUpdatesManager.prototype.debounce(self, key, ____type, mutate, expirationDurationTicks) + self:update( + key, + ____type, + mutate, + true, + expirationDurationTicks + ) +end +function EventUpdatesManager.prototype.update(self, key, ____type, mutate, resetLastUpdated, expirationDurationTicks) + local entry = self:getCacheEntry(key, ____type) or ____exports.EventUpdatesManager:createCacheEntry(key, ____type) + mutate(entry.packet) + if resetLastUpdated then + entry.lastUpdatedTick = game.tick + end + if expirationDurationTicks ~= nil then + entry.expirationDurationTicks = expirationDurationTicks + end + if entry.expirationDurationTicks ~= nil and entry.expirationDurationTicks <= 0 then + self:extractAndEmitExpiredPackets() + end +end +function EventUpdatesManager.prototype.setExpiration(self, key, ____type, expirationDurationTicks) + local entry = self:getCacheEntry(key, ____type) + if entry ~= nil then + entry.expirationDurationTicks = expirationDurationTicks + end +end +function EventUpdatesManager.prototype.extractExpired(self) + local countExpired = 0 + local countTotal = 0 + local expiredData = {} + for key, entry in pairs(global.eventUpdatesManagerCache) do + countTotal = countTotal + 1 + if self:isExpired(entry) then + countExpired = countExpired + 1 + expiredData[#expiredData + 1] = entry.packet + global.eventUpdatesManagerCache[key] = nil + end + end + local hasExpiredItems = countExpired > 0 + local hasAnyItem = countTotal > 0 + if hasExpiredItems or game.tick % 30 == 0 and hasAnyItem then + log((("[extractExpired] expired items: " .. tostring(countExpired)) .. ", total: ") .. tostring(countTotal)) + end + return expiredData +end +function EventUpdatesManager.prototype.extractAndEmitExpiredPackets(self) + local cachedEvents = self:extractExpired() + if #cachedEvents > 0 then + log((("[EventDataCache] emitting " .. tostring(#cachedEvents)) .. " events on tick ") .. tostring(game.tick)) + for ____, event in ipairs(cachedEvents) do + PacketEmitter:emitKeyedPacket(event) + end + end + return #cachedEvents +end +function EventUpdatesManager.prototype.getCacheEntry(self, key, ____type) + local hash = ____exports.EventUpdatesManager:hashKey(key) + if not (global.eventUpdatesManagerCache[hash] ~= nil) then + return nil + end + local value = global.eventUpdatesManagerCache[hash] + if self:isEntryInstanceOf(value, ____type) then + return value + else + return nil + end +end +function EventUpdatesManager.createCacheEntry(self, key, ____type) + local data = {type = ____type, key = key} + local entry = __TS__New(CacheEntry, data) + local hash = ____exports.EventUpdatesManager:hashKey(key) + global.eventUpdatesManagerCache[hash] = entry + return entry +end +function EventUpdatesManager.prototype.isExpired(self, entry) + local expiryDuration = entry.expirationDurationTicks or KafkatorioSettings:getEventCacheExpirationTicks(entry.packet) + if expiryDuration == nil then + return true + else + return game.tick - entry.lastUpdatedTick > expiryDuration + end +end +function EventUpdatesManager.prototype.isEntryInstanceOf(self, entry, ____type) + local ____self_isDataInstanceOf_2 = self.isDataInstanceOf + local ____entry_packet_0 = entry + if ____entry_packet_0 ~= nil then + ____entry_packet_0 = ____entry_packet_0.packet + end + return ____self_isDataInstanceOf_2(self, ____entry_packet_0, ____type) +end +function EventUpdatesManager.prototype.isDataInstanceOf(self, packet, ____type) + return packet ~= nil and packet.type == ____type +end +function EventUpdatesManager.hashKey(self, key) + return game.encode_string(game.table_to_json(key)) +end +local EventUpdates = __TS__New(____exports.EventUpdatesManager) +____exports.default = EventUpdates +CacheEntry = __TS__Class() +CacheEntry.name = "CacheEntry" +function CacheEntry.prototype.____constructor(self, packet, expirationDurationTicks) + self.lastUpdatedTick = game.tick + self.packet = packet + self.expirationDurationTicks = expirationDurationTicks +end +return ____exports diff --git a/modules/events-mod/src/generated/lua/main/emitting/KafkatorioPacketQueue.lua b/modules/events-mod/src/generated/lua/main/emitting/KafkatorioPacketQueue.lua new file mode 100644 index 0000000..a64395e --- /dev/null +++ b/modules/events-mod/src/generated/lua/main/emitting/KafkatorioPacketQueue.lua @@ -0,0 +1,44 @@ +local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local __TS__SetDescriptor = ____lualib.__TS__SetDescriptor +local __TS__New = ____lualib.__TS__New +local ____exports = {} +____exports.KafkatorioPacketQueueManager = __TS__Class() +local KafkatorioPacketQueueManager = ____exports.KafkatorioPacketQueueManager +KafkatorioPacketQueueManager.name = "KafkatorioPacketQueueManager" +function KafkatorioPacketQueueManager.prototype.____constructor(self) + self.size = 0 + self.first = nil + self.last = nil +end +__TS__SetDescriptor( + KafkatorioPacketQueueManager.prototype, + "length", + {get = function(self) + return self.size + end}, + true +) +function KafkatorioPacketQueueManager.prototype.enqueue(self, packet) + local last = self.last + self.last = {value = packet} + if last ~= nil then + last.next = self.last + end + if self.first == nil then + self.first = self.last + end + self.size = self.size + 1 +end +function KafkatorioPacketQueueManager.prototype.dequeue(self) + local first = self.first + if first == nil then + return nil + end + self.first = first.next or nil + self.size = self.size - 1 + return first.value +end +local KafkatorioPacketQueue = __TS__New(____exports.KafkatorioPacketQueueManager) +____exports.default = KafkatorioPacketQueue +return ____exports diff --git a/modules/events-mod/src/generated/lua/main/PacketEmitter.lua b/modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua similarity index 100% rename from modules/events-mod/src/generated/lua/main/PacketEmitter.lua rename to modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua diff --git a/modules/events-mod/src/generated/lua/main/events/consoleUpdates.lua b/modules/events-mod/src/generated/lua/main/events/consoleUpdates.lua index daf3956..b764aa4 100644 --- a/modules/events-mod/src/generated/lua/main/events/consoleUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/consoleUpdates.lua @@ -1,21 +1,20 @@ local ____exports = {} -local ____PacketEmitter = require("main.PacketEmitter") -local PacketEmitter = ____PacketEmitter.default local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData -local Type = KafkatorioPacketData.Type +local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue") +local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default script.on_event( defines.events.on_console_chat, function(event) - local update = {type = Type.ConsoleChatUpdate, authorPlayerIndex = event.player_index or nil, content = event.message} - PacketEmitter:emitInstantPacket(update) + local update = {type = KafkatorioPacketData.Type.ConsoleChatUpdate, authorPlayerIndex = event.player_index or nil, content = event.message} + KafkatorioPacketQueue:enqueue(update) end ) script.on_event( defines.events.on_console_command, function(event) - local update = {type = Type.ConsoleCommandUpdate, authorPlayerIndex = event.player_index or nil, command = event.command, parameters = event.parameters} - PacketEmitter:emitInstantPacket(update) + local update = {type = KafkatorioPacketData.Type.ConsoleCommandUpdate, authorPlayerIndex = event.player_index or nil, command = event.command, parameters = event.parameters} + KafkatorioPacketQueue:enqueue(update) end ) return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/handlers/ConfigurationUpdateHandler.lua b/modules/events-mod/src/generated/lua/main/events/handlers/ConfigurationUpdateHandler.lua index b81701c..7463e91 100644 --- a/modules/events-mod/src/generated/lua/main/events/handlers/ConfigurationUpdateHandler.lua +++ b/modules/events-mod/src/generated/lua/main/events/handlers/ConfigurationUpdateHandler.lua @@ -9,8 +9,8 @@ local __TS__ArrayMap = ____lualib.__TS__ArrayMap local ____exports = {} local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData -local ____PacketEmitter = require("main.PacketEmitter") -local PacketEmitter = ____PacketEmitter.default +local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue") +local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default ____exports.ConfigurationUpdateHandler = __TS__Class() local ConfigurationUpdateHandler = ____exports.ConfigurationUpdateHandler ConfigurationUpdateHandler.name = "ConfigurationUpdateHandler" @@ -24,7 +24,7 @@ function ConfigurationUpdateHandler.prototype.emitConfigurationUpdate(self, chan allMods = ____exports.ConfigurationUpdateHandler:allMods(changeData), factorioData = ____exports.ConfigurationUpdateHandler:factorioData(changeData) } - PacketEmitter:emitInstantPacket(configUpdateData) + KafkatorioPacketQueue:enqueue(configUpdateData) end function ConfigurationUpdateHandler.factorioData(self, changeData) return {oldVersion = changeData.old_version or nil, newVersion = changeData.new_version or nil} diff --git a/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua b/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua index 99afb01..16222f5 100644 --- a/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua +++ b/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua @@ -7,7 +7,7 @@ local FactorioEntityData = ____kafkatorio_2Dschema.FactorioEntityData local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData local ____converters = require("main.events.converters") local Converters = ____converters.Converters -local ____EventDataCache = require("main.cache.EventDataCache") +local ____EventDataCache = require("main.emitting.EventDataCache") local EventDataCache = ____EventDataCache.default ____exports.EntityUpdatesHandler = __TS__Class() local EntityUpdatesHandler = ____exports.EntityUpdatesHandler diff --git a/modules/events-mod/src/generated/lua/main/events/handlers/MapChunkUpdateHandler.lua b/modules/events-mod/src/generated/lua/main/events/handlers/MapChunkUpdateHandler.lua index f047ad7..b4efcbb 100644 --- a/modules/events-mod/src/generated/lua/main/events/handlers/MapChunkUpdateHandler.lua +++ b/modules/events-mod/src/generated/lua/main/events/handlers/MapChunkUpdateHandler.lua @@ -10,8 +10,8 @@ local ____eventTypeCheck = require("main.events.eventTypeCheck") local isEventType = ____eventTypeCheck.isEventType local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData -local ____EventDataCache = require("main.cache.EventDataCache") -local EventUpdatesManager = ____EventDataCache.default +local ____EventDataCache = require("main.emitting.EventDataCache") +local EventUpdates = ____EventDataCache.default local MapChunkUpdateHandler = __TS__Class() MapChunkUpdateHandler.name = "MapChunkUpdateHandler" function MapChunkUpdateHandler.prototype.____constructor(self) @@ -124,7 +124,7 @@ function MapChunkUpdateHandler.prototype.handlePreChunkDeleted(self, event) end for ____, position in ipairs(event.positions) do local key = {surfaceIndex = surface.index, chunkPosition = {position.x, position.y}} - EventUpdatesManager:debounce( + EventUpdates:debounce( key, KafkatorioPacketData.Type.MapChunkTileUpdate, function(data) @@ -141,7 +141,7 @@ function MapChunkUpdateHandler.mapTilesUpdateDebounce(self, surface, chunkPositi end local eventName = Converters.eventNameString(event.name) local key = {surfaceIndex = surface.index, chunkPosition = chunkPosition} - EventUpdatesManager:debounce( + EventUpdates:debounce( key, KafkatorioPacketData.Type.MapChunkTileUpdate, function(data) diff --git a/modules/events-mod/src/generated/lua/main/events/handlers/PlayerUpdateHandler.lua b/modules/events-mod/src/generated/lua/main/events/handlers/PlayerUpdateHandler.lua index 0591e9b..f56b95d 100644 --- a/modules/events-mod/src/generated/lua/main/events/handlers/PlayerUpdateHandler.lua +++ b/modules/events-mod/src/generated/lua/main/events/handlers/PlayerUpdateHandler.lua @@ -6,8 +6,8 @@ local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData local ____converters = require("main.events.converters") local Converters = ____converters.Converters -local ____EventDataCache = require("main.cache.EventDataCache") -local EventUpdatesManager = ____EventDataCache.default +local ____EventDataCache = require("main.emitting.EventDataCache") +local EventUpdates = ____EventDataCache.default ____exports.PlayerUpdateHandler = __TS__Class() local PlayerUpdateHandler = ____exports.PlayerUpdateHandler PlayerUpdateHandler.name = "PlayerUpdateHandler" @@ -31,7 +31,7 @@ function PlayerUpdateHandler.prototype.playerUpdateThrottle(self, event, mutate, return end local eventName = Converters.eventNameString(event.name) - EventUpdatesManager:throttle( + EventUpdates:throttle( {index = playerIndex}, KafkatorioPacketData.Type.PlayerUpdate, function(data) diff --git a/modules/events-mod/src/generated/lua/main/events/playerUpdates.lua b/modules/events-mod/src/generated/lua/main/events/playerUpdates.lua index 885348b..09e39b7 100644 --- a/modules/events-mod/src/generated/lua/main/events/playerUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/playerUpdates.lua @@ -4,7 +4,7 @@ local ____converters = require("main.events.converters") local Converters = ____converters.Converters local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData -local ____PacketEmitter = require("main.PacketEmitter") +local ____PacketEmitter = require("main.emitting.PacketEmitter") local packetEmitter = ____PacketEmitter.default local ____PlayerUpdateHandler = require("main.events.handlers.PlayerUpdateHandler") local PlayerUpdates = ____PlayerUpdateHandler.default diff --git a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua index 551e592..145c154 100644 --- a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua @@ -1,25 +1,21 @@ local ____exports = {} local emit, getMapTilePrototypes, getEntityPrototypes, convertItemGroup, convertItemSubgroup -local ____PacketEmitter = require("main.PacketEmitter") -local PacketEmitter = ____PacketEmitter.default local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") local FactorioPrototype = ____kafkatorio_2Dschema.FactorioPrototype local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData local ____converters = require("main.events.converters") local Converters = ____converters.Converters +local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue") +local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default function emit(protosByType) for ____, protos in pairs(protosByType) do - PacketEmitter:emitInstantPacket({type = KafkatorioPacketData.Type.PrototypesUpdate, prototypes = protos}) + KafkatorioPacketQueue:enqueue({type = KafkatorioPacketData.Type.PrototypesUpdate, prototypes = protos}) end end function getMapTilePrototypes() local tiles = {} - if not (tiles.tile ~= nil) then - tiles.tile = {} - end for ____, tile in pairs(game.tile_prototypes) do - local ____tiles_tile_0 = tiles.tile - ____tiles_tile_0[#____tiles_tile_0 + 1] = { + tiles[#tiles + 1] = { type = FactorioPrototype.Type.MapTile, protoId = Converters.prototypeId("tile", tile.name), order = tile.order, @@ -29,13 +25,13 @@ function getMapTilePrototypes() canBeMined = tile.mineable_properties.minable } end - return tiles + return {tiles = tiles} end function getEntityPrototypes() local protos = {} for ____, entity in pairs(game.entity_prototypes) do local key = (entity.group.name .. "/") .. entity.subgroup.name - if not (protos[key] ~= nil) then + if protos[key] == nil then protos[key] = {} end local entityProto = { @@ -58,8 +54,8 @@ function getEntityPrototypes() entityProto.mapColourEnemy = Converters.mapColour(entity.enemy_map_color) end entityProto.miningProperties = Converters.miningProperties(entity.mineable_properties) - local ____protos_key_1 = protos[key] - ____protos_key_1[#____protos_key_1 + 1] = entityProto + local ____protos_key_0 = protos[key] + ____protos_key_0[#____protos_key_0 + 1] = entityProto end return protos end @@ -67,19 +63,17 @@ function convertItemGroup(itemGroup) return {name = itemGroup.name, type = itemGroup.type, parentName = nil} end function convertItemSubgroup(itemGroup) - local ____itemGroup_name_4 = itemGroup.name - local ____itemGroup_type_5 = itemGroup.type - local ____itemGroup_group_name_2 = itemGroup.group - if ____itemGroup_group_name_2 ~= nil then - ____itemGroup_group_name_2 = ____itemGroup_group_name_2.name + local ____itemGroup_name_3 = itemGroup.name + local ____itemGroup_type_4 = itemGroup.type + local ____itemGroup_group_name_1 = itemGroup.group + if ____itemGroup_group_name_1 ~= nil then + ____itemGroup_group_name_1 = ____itemGroup_group_name_1.name end - return {name = ____itemGroup_name_4, type = ____itemGroup_type_5, parentName = ____itemGroup_group_name_2} + return {name = ____itemGroup_name_3, type = ____itemGroup_type_4, parentName = ____itemGroup_group_name_1} end function ____exports.emitPrototypes() local mapTileProtos = getMapTilePrototypes() emit(mapTileProtos) - local ____ = game.item_group_prototypes - local ____ = game.item_subgroup_prototypes local entityProtos = getEntityPrototypes() emit(entityProtos) end diff --git a/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua b/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua index 421c0b0..4d6e911 100644 --- a/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua +++ b/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua @@ -1,16 +1,20 @@ local ____exports = {} -local ____queue = require("main.queue.queue") -local Queue = ____queue.Queue local ____eventTypeCheck = require("main.events.eventTypeCheck") local isEventType = ____eventTypeCheck.isEventType local ____converters = require("main.events.converters") local Converters = ____converters.Converters local ____surfaceUpdates = require("main.events.surfaceUpdates") local handleSurfaceUpdate = ____surfaceUpdates.handleSurfaceUpdate -local ____EventDataCache = require("main.cache.EventDataCache") +local ____EventDataCache = require("main.emitting.EventDataCache") local EventCacheService = ____EventDataCache.default local ____MapChunkUpdateHandler = require("main.events.handlers.MapChunkUpdateHandler") local MapChunkUpdate = ____MapChunkUpdateHandler.default +local ____queue = require("main.queue.queue") +local EventDataQueue = ____queue.default +local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue") +local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default +local ____PacketEmitter = require("main.emitting.PacketEmitter") +local PacketEmitter = ____PacketEmitter.default script.on_event( defines.events.on_tick, function(event) @@ -23,6 +27,10 @@ script.on_event( ) end end + local kPacket = KafkatorioPacketQueue:dequeue() + if kPacket ~= nil then + PacketEmitter:emitInstantPacket(kPacket) + end if event.tick % 6 == 0 then local emittedCount = EventCacheService:extractAndEmitExpiredPackets() if emittedCount > 0 then @@ -30,9 +38,9 @@ script.on_event( end end if event.tick % 7 == 0 then - local events = Queue.dequeueValues(1) + local events = EventDataQueue:dequeueValues(1) if #events > 0 then - log((((("[on_tick:" .. tostring(event.tick)) .. "] dequeued ") .. tostring(#events)) .. " events, current size: ") .. tostring(Queue.size())) + log((((("[on_tick:" .. tostring(event.tick)) .. "] dequeued ") .. tostring(#events)) .. " events, current size: ") .. tostring(EventDataQueue:size())) local i = 1 for ____, event in ipairs(events) do if isEventType(event, defines.events.on_chunk_generated) then diff --git a/modules/events-mod/src/generated/lua/main/events/surfaceUpdates.lua b/modules/events-mod/src/generated/lua/main/events/surfaceUpdates.lua index 3e2f804..a1ff33a 100644 --- a/modules/events-mod/src/generated/lua/main/events/surfaceUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/surfaceUpdates.lua @@ -1,5 +1,5 @@ local ____exports = {} -local ____PacketEmitter = require("main.PacketEmitter") +local ____PacketEmitter = require("main.emitting.PacketEmitter") local PacketEmitter = ____PacketEmitter.default local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData diff --git a/modules/events-mod/src/generated/lua/main/global-init.lua b/modules/events-mod/src/generated/lua/main/global-init.lua index 5f21c61..28b970b 100644 --- a/modules/events-mod/src/generated/lua/main/global-init.lua +++ b/modules/events-mod/src/generated/lua/main/global-init.lua @@ -1,8 +1,8 @@ local ____exports = {} +local ____EventDataCache = require("main.emitting.EventDataCache") +local EventUpdates = ____EventDataCache.default local ____queue = require("main.queue.queue") -local Queue = ____queue.Queue -local ____EventDataCache = require("main.cache.EventDataCache") -local EventUpdatesManager = ____EventDataCache.default +local EventDataQueueManager = ____queue.EventDataQueueManager function ____exports.initGlobal(force) if force == nil then force = false @@ -10,8 +10,8 @@ function ____exports.initGlobal(force) log(("Initialising Kafkatorio Global variables (force=" .. tostring(force)) .. ")...") global.MOD_VERSION = script.active_mods[script.mod_name] global.FACTORIO_VERSION = script.active_mods.base - Queue.init(true) - EventUpdatesManager:init(true) + EventDataQueueManager:init(true) + EventUpdates:init(true) log("Finished initialising Kafkatorio Global variables") end return ____exports diff --git a/modules/events-mod/src/generated/lua/main/queue/queue.lua b/modules/events-mod/src/generated/lua/main/queue/queue.lua index 2dcf0ca..a8da3b8 100644 --- a/modules/events-mod/src/generated/lua/main/queue/queue.lua +++ b/modules/events-mod/src/generated/lua/main/queue/queue.lua @@ -1,84 +1,87 @@ local ____lualib = require("lualib_bundle") -local __TS__New = ____lualib.__TS__New local __TS__Class = ____lualib.__TS__Class +local __TS__New = ____lualib.__TS__New local ____exports = {} -____exports.Queue = {} -local Queue = ____exports.Queue -do - local Node - function Queue.init(force) - local isAnythingUndefined = global.store == nil or global.size == nil or global.head == nil or global.tail == nil - log(((("Initialising EventQueue globals (force=" .. tostring(force)) .. ", isAnythingUndefined=") .. tostring(isAnythingUndefined)) .. ")") - if force == true or isAnythingUndefined then - global.store = {} - global.head = nil - global.tail = nil - global.size = 0 - end - log("Finished initialising EventQueue") +local Node +____exports.EventDataQueueManager = __TS__Class() +local EventDataQueueManager = ____exports.EventDataQueueManager +EventDataQueueManager.name = "EventDataQueueManager" +function EventDataQueueManager.prototype.____constructor(self) +end +function EventDataQueueManager.init(self, force) + local isAnythingUndefined = global.store == nil or global.size == nil or global.head == nil or global.tail == nil + log(((("Initialising EventDataQueueManager globals (force=" .. tostring(force)) .. ", isAnythingUndefined=") .. tostring(isAnythingUndefined)) .. ")") + if force == true or isAnythingUndefined then + global.store = {} + global.head = nil + global.tail = nil + global.size = 0 end - function Queue.size() - return global.size + log("Finished initialising EventDataQueueManager") +end +function EventDataQueueManager.prototype.size(self) + return global.size +end +function EventDataQueueManager.prototype.enqueue(self, key, event, weight) + if weight == nil then + weight = 1 end - function Queue.enqueue(key, event, weight) - if weight == nil then - weight = 1 - end - if global.store[key] ~= nil then - local node = __TS__New(Node, key, weight) - if global.head == nil then - global.head = node - end - if global.tail ~= nil then - global.tail.next = node - end - global.tail = node - global.size = global.size + 1 - end - global.store[key] = event - end - function Queue.dequeue() + if global.store[key] ~= nil then + local node = __TS__New(Node, key, weight) if global.head == nil then + global.head = node + end + if global.tail ~= nil then + global.tail.next = node + end + global.tail = node + global.size = global.size + 1 + end + global.store[key] = event +end +function EventDataQueueManager.prototype.dequeue(self) + if global.head == nil then + return nil + else + local weight = global.head.weight + local storeKey = global.head.storeKey + global.head = global.head.next + global.size = global.size - 1 + local storedPacket = global.store[storeKey] + global.store[storeKey] = nil + if storedPacket == nil then return nil else - local weight = global.head.weight - local storeKey = global.head.storeKey - global.head = global.head.next - global.size = global.size - 1 - local storedPacket = global.store[storeKey] - global.store[storeKey] = nil - if storedPacket == nil then - return nil - else - return {value = storedPacket, weight = weight} - end + return {value = storedPacket, weight = weight} end end - function Queue.dequeueValues(targetWeight) - if targetWeight == nil then - targetWeight = 50 - end - local values = {} - local weight = 0 - repeat - do - local packet = Queue.dequeue() - if packet == nil then - break - else - weight = weight + packet.weight - values[#values + 1] = packet.value - end - end - until not (weight <= targetWeight) - return values - end - Node = __TS__Class() - Node.name = "Node" - function Node.prototype.____constructor(self, storeKey, weight) - self.next = nil - self.storeKey = storeKey - self.weight = weight - end +end +function EventDataQueueManager.prototype.dequeueValues(self, targetWeight) + if targetWeight == nil then + targetWeight = 50 + end + local values = {} + local weight = 0 + repeat + do + local packet = self:dequeue() + if packet == nil then + break + else + weight = weight + packet.weight + values[#values + 1] = packet.value + end + end + until not (weight <= targetWeight) + return values +end +local EventDataQueue = __TS__New(____exports.EventDataQueueManager) +____exports.default = EventDataQueue +Node = __TS__Class() +Node.name = "Node" +function Node.prototype.____constructor(self, storeKey, weight) + self.next = nil + self.storeKey = storeKey + self.weight = weight end return ____exports diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts deleted file mode 100644 index 4c9b572..0000000 --- a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts +++ /dev/null @@ -1,235 +0,0 @@ -import KafkatorioSettings from "../settings/KafkatorioSettings"; -import {KafkatorioKeyedPacketData} from "../types"; -import packetEmitter from "../PacketEmitter"; - -export namespace EventUpdates { - - - declare const global: { - /** Map the hash of the key, as a string, a cache entry */ - cache: LuaTable>, - } - - - export class Manager { - - - init(force?: boolean) { - - const isAnythingUndefined = global.cache == undefined - - log(`Initialising EventDataCache (force=${force}, isAnythingUndefined=${isAnythingUndefined})...`) - - if (force == true || isAnythingUndefined) { - log("Initialising global.cache") - global.cache = new LuaTable>() - } - log(`Finished initialising EventDataCache`) - } - - - /** - * Update the cache data without restarting the 'time-to-emit' countdown, so that the data won't - * be emitted more than once per {@link CacheEntry.expirationDurationTicks}. - */ - public throttle( - key: PacketKey, - type: PacketType, - mutate: CacheDataMutator, - expirationDurationTicks?: uint, - ) { - this.update(key, type, mutate, false, expirationDurationTicks) - } - - - /** - * Update the cache data and reset the 'time-to-emit' countdown, so the data won't be emitted - * until there's an inactivity gap of {@link CacheEntry.expirationDurationTicks}. - */ - public debounce( - key: PacketKey, - type: PacketType, - mutate: CacheDataMutator, - expirationDurationTicks?: uint, - ) { - this.update(key, type, mutate, true, expirationDurationTicks) - } - - - private update( - key: PacketKey, - type: PacketType, - mutate: CacheDataMutator, - resetLastUpdated: boolean, - expirationDurationTicks?: uint, - ) { - const entry: CacheEntry = this.getCacheEntry(key, type) ?? - Manager.createCacheEntry(key, type) - mutate(entry.packet) - if (resetLastUpdated) { - entry.lastUpdatedTick = game.tick - } - if (expirationDurationTicks != undefined) { - entry.expirationDurationTicks = expirationDurationTicks - } - - if (entry.expirationDurationTicks != undefined && entry.expirationDurationTicks <= 0) { - this.extractAndEmitExpiredPackets() - } - } - - - /** - * Usage example: If an urgent update comes in, then the expiration can be reduced so that - * it's transmitted sooner. - */ - public setExpiration( - key: PacketKey, - type: PacketType, - expirationDurationTicks: uint, - ) { - const entry = this.getCacheEntry(key, type) - if (entry != undefined) { - entry.expirationDurationTicks = expirationDurationTicks - } - } - - - /** Removes all expired entries from the cache, and return them. */ - // use in/out v4.7.0 https://github.com/microsoft/TypeScript/pull/48240 - private extractExpired(): Array { - let countExpired = 0 - let countTotal = 0 - const expiredData: Array = [] - for (const [key, entry] of global.cache) { - countTotal++ - if (this.isExpired(entry)) { - countExpired++ - expiredData.push(entry.packet) - global.cache.delete(key) - } - } - - const hasExpiredItems = countExpired > 0 - const hasAnyItem = countTotal > 0 - - if (hasExpiredItems || (game.tick % 30 == 0 && hasAnyItem)) { - log(`[extractExpired] expired items: ${countExpired}, total: ${countTotal}`) - } - return expiredData - } - - - /** - * Removes and emits all expired packets. - * - * @return the number of emitted packets - */ - public extractAndEmitExpiredPackets() { - const cachedEvents: Array = this.extractExpired() - - if (cachedEvents.length > 0) { - log(`[EventDataCache] emitting ${cachedEvents.length} events on tick ${game.tick}`) - for (const event of cachedEvents) { - packetEmitter.emitKeyedPacket(event) - } - } - - return cachedEvents.length - } - - - private getCacheEntry( - key: EventUpdates.PacketKey, - type: EventUpdates.PacketType, - ): CacheEntry | undefined { - const hash = Manager.hashKey(key) - if (!global.cache.has(hash)) { - return undefined - } - const value: CacheEntry = global.cache.get(hash) - if (this.isEntryInstanceOf(value, type)) { - return value - } else { - // Type mismatch. This shouldn't happen... - return undefined - } - } - - - private static createCacheEntry( - key: PacketKey, - type: PacketType, - ): CacheEntry { - const data: PACKET = { - type: type, - key: key, - } - const entry: CacheEntry = new CacheEntry(data) - const hash = Manager.hashKey(key) - global.cache.set(hash, entry) - return entry - } - - - isExpired(entry: CacheEntry): boolean { - const expiryDuration = - entry.expirationDurationTicks - ?? KafkatorioSettings.getEventCacheExpirationTicks(entry.packet) - - if (expiryDuration == undefined) { - return true - } else { - return game.tick - entry.lastUpdatedTick > expiryDuration - } - } - - - isEntryInstanceOf( - entry: CacheEntry | undefined, - type: EventUpdates.PacketType, - ): entry is CacheEntry { - return this.isDataInstanceOf(entry?.packet, type) - } - - - isDataInstanceOf( - packet: PACKET | undefined, - type: EventUpdates.PacketType, - ): packet is PACKET { - return packet != undefined && packet.type == type - } - - private static hashKey( - key: PacketKey, - ): string { - return game.encode_string(game.table_to_json(key))!! - } - - } - - export type PacketKey = PACKET["key"] - export type PacketType = PACKET["type"] - - export type CacheDataMutator = (packet: PACKET) => void - - class CacheEntry { - lastUpdatedTick: uint = game.tick - expirationDurationTicks?: uint - - packet: PACKET - - constructor( - packet: PACKET, - expirationDurationTicks?: uint, - ) { - - this.packet = packet - this.expirationDurationTicks = expirationDurationTicks - } - } -} - -const EventUpdatesManager = new EventUpdates.Manager() - -export default EventUpdatesManager diff --git a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts index c9bdcc0..a1e4c67 100644 --- a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts +++ b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts @@ -1,6 +1,6 @@ import {initGlobal} from "../global-init"; -import {Queue} from "../queue/queue"; import {emitPrototypes} from "../events/prototypeUpdates"; +import EventDataQueue from "../queue/queue"; commands.add_command( @@ -58,7 +58,7 @@ commands.add_command( tick: e.tick, } - Queue.enqueue( + EventDataQueue.enqueue( `${surface.index}${chunk.x}${chunk.y}`, data, 50 diff --git a/modules/events-mod/src/main/typescript/main/emitting/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/emitting/EventDataCache.ts new file mode 100644 index 0000000..2547dab --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/emitting/EventDataCache.ts @@ -0,0 +1,240 @@ +import KafkatorioSettings from "../settings/KafkatorioSettings"; +import {KafkatorioKeyedPacketData} from "../types"; +import PacketEmitter from "./PacketEmitter"; + + +declare const global: { + /** Map the hash of the key, as a string, a cache entry */ + eventUpdatesManagerCache: LuaTable>, +} + + +export class EventUpdatesManager { + + constructor() { + this.init() + } + + + init(force?: boolean) { + + const isAnythingUndefined = global.eventUpdatesManagerCache == undefined + + log(`Initialising EventDataCache (force=${force}, isAnythingUndefined=${isAnythingUndefined})...`) + + if (force == true || isAnythingUndefined) { + log("Initialising global.cache") + global.eventUpdatesManagerCache = new LuaTable>() + } + log(`Finished initialising EventDataCache`) + } + + + /** + * Update the cache data without restarting the 'time-to-emit' countdown, so that the data won't + * be emitted more than once per {@link CacheEntry.expirationDurationTicks}. + */ + public throttle( + key: PacketKey, + type: PacketType, + mutate: CacheDataMutator, + expirationDurationTicks?: uint, + ) { + this.update(key, type, mutate, false, expirationDurationTicks) + } + + + /** + * Update the cache data and reset the 'time-to-emit' countdown, so the data won't be emitted + * until there's an inactivity gap of {@link CacheEntry.expirationDurationTicks}. + */ + public debounce( + key: PacketKey, + type: PacketType, + mutate: CacheDataMutator, + expirationDurationTicks?: uint, + ) { + this.update(key, type, mutate, true, expirationDurationTicks) + } + + + private update( + key: PacketKey, + type: PacketType, + mutate: CacheDataMutator, + resetLastUpdated: boolean, + expirationDurationTicks?: uint, + ) { + const entry: CacheEntry = this.getCacheEntry(key, type) ?? + EventUpdatesManager.createCacheEntry(key, type) + mutate(entry.packet) + if (resetLastUpdated) { + entry.lastUpdatedTick = game.tick + } + if (expirationDurationTicks != undefined) { + entry.expirationDurationTicks = expirationDurationTicks + } + + if (entry.expirationDurationTicks != undefined && entry.expirationDurationTicks <= 0) { + this.extractAndEmitExpiredPackets() + } + } + + + /** + * Usage example: If an urgent update comes in, then the expiration can be reduced so that + * it's transmitted sooner. + */ + public setExpiration( + key: PacketKey, + type: PacketType, + expirationDurationTicks: uint, + ) { + const entry = this.getCacheEntry(key, type) + if (entry != undefined) { + entry.expirationDurationTicks = expirationDurationTicks + } + } + + + /** Removes all expired entries from the cache, and return them. */ + // use in/out v4.7.0 https://github.com/microsoft/TypeScript/pull/48240 + private extractExpired(): Array { + let countExpired = 0 + let countTotal = 0 + const expiredData: Array = [] + for (const [key, entry] of global.eventUpdatesManagerCache) { + countTotal++ + if (this.isExpired(entry)) { + countExpired++ + expiredData.push(entry.packet) + global.eventUpdatesManagerCache.delete(key) + } + } + + const hasExpiredItems = countExpired > 0 + const hasAnyItem = countTotal > 0 + + if (hasExpiredItems || (game.tick % 30 == 0 && hasAnyItem)) { + log(`[extractExpired] expired items: ${countExpired}, total: ${countTotal}`) + } + return expiredData + } + + + /** + * Removes and emits all expired packets. + * + * @return the number of emitted packets + */ + public extractAndEmitExpiredPackets() { + const cachedEvents: Array = this.extractExpired() + + if (cachedEvents.length > 0) { + log(`[EventDataCache] emitting ${cachedEvents.length} events on tick ${game.tick}`) + for (const event of cachedEvents) { + PacketEmitter.emitKeyedPacket(event) + } + } + + return cachedEvents.length + } + + + private getCacheEntry( + key: PacketKey, + type: PacketType, + ): CacheEntry | undefined { + const hash = EventUpdatesManager.hashKey(key) + if (!global.eventUpdatesManagerCache.has(hash)) { + return undefined + } + const value: CacheEntry = global.eventUpdatesManagerCache.get(hash) + if (this.isEntryInstanceOf(value, type)) { + return value + } else { + // Type mismatch. This shouldn't happen... + return undefined + } + } + + + private static createCacheEntry( + key: PacketKey, + type: PacketType, + ): CacheEntry { + const data: PACKET = { + type: type, + key: key, + } + const entry: CacheEntry = new CacheEntry(data) + const hash = EventUpdatesManager.hashKey(key) + global.eventUpdatesManagerCache.set(hash, entry) + return entry + } + + + isExpired(entry: CacheEntry): boolean { + const expiryDuration = + entry.expirationDurationTicks + ?? KafkatorioSettings.getEventCacheExpirationTicks(entry.packet) + + if (expiryDuration == undefined) { + return true + } else { + return game.tick - entry.lastUpdatedTick > expiryDuration + } + } + + + isEntryInstanceOf( + entry: CacheEntry | undefined, + type: PacketType, + ): entry is CacheEntry { + return this.isDataInstanceOf(entry?.packet, type) + } + + + isDataInstanceOf( + packet: PACKET | undefined, + type: PacketType, + ): packet is PACKET { + return packet != undefined && packet.type == type + } + + + private static hashKey( + key: PacketKey, + ): string { + return game.encode_string(game.table_to_json(key))!! + } + +} + + +const EventUpdates = new EventUpdatesManager() + +export default EventUpdates + + +export type PacketKey = PACKET["key"] +export type PacketType = PACKET["type"] + +export type CacheDataMutator = (packet: PACKET) => void + + +class CacheEntry { + lastUpdatedTick: uint = game.tick + expirationDurationTicks?: uint + + packet: PACKET + + constructor( + packet: PACKET, + expirationDurationTicks?: uint, + ) { + + this.packet = packet + this.expirationDurationTicks = expirationDurationTicks + } +} diff --git a/modules/events-mod/src/main/typescript/main/emitting/KafkatorioPacketQueue.ts b/modules/events-mod/src/main/typescript/main/emitting/KafkatorioPacketQueue.ts new file mode 100644 index 0000000..406ec86 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/emitting/KafkatorioPacketQueue.ts @@ -0,0 +1,48 @@ +import {KafkatorioPacketData} from "../../generated/kafkatorio-schema"; + +export class KafkatorioPacketQueueManager { + + private size: int = 0 + private first: Node | null = null + private last: Node | null = null + + public get length() { + return this.size + } + + public enqueue(packet: T) { + const last = this.last + this.last = { + value: packet + } + if (last != null) { + last.next = this.last + } + if (this.first == null) { + this.first = this.last + } + this.size++ + } + + public dequeue(): T | null { + const first = this.first + + if (first == null) { + return null + } + + this.first = first.next ?? null + this.size-- + return first.value + } + +} + +const KafkatorioPacketQueue = new KafkatorioPacketQueueManager() + +export default KafkatorioPacketQueue + +interface Node { + value: T + next?: Node +} diff --git a/modules/events-mod/src/main/typescript/main/PacketEmitter.ts b/modules/events-mod/src/main/typescript/main/emitting/PacketEmitter.ts similarity index 85% rename from modules/events-mod/src/main/typescript/main/PacketEmitter.ts rename to modules/events-mod/src/main/typescript/main/emitting/PacketEmitter.ts index a566499..5c3b943 100644 --- a/modules/events-mod/src/main/typescript/main/PacketEmitter.ts +++ b/modules/events-mod/src/main/typescript/main/emitting/PacketEmitter.ts @@ -1,8 +1,5 @@ -import { - KafkatorioPacket, - KafkatorioPacketData -} from "../generated/kafkatorio-schema"; -import {KafkatorioKeyedPacketData} from "./types"; +import {KafkatorioPacket, KafkatorioPacketData} from "../../generated/kafkatorio-schema"; +import {KafkatorioKeyedPacketData} from "../types"; export class KafkatorioPacketEmitter { diff --git a/modules/events-mod/src/main/typescript/main/events/consoleUpdates.ts b/modules/events-mod/src/main/typescript/main/events/consoleUpdates.ts index 2dcd812..ddfd728 100644 --- a/modules/events-mod/src/main/typescript/main/events/consoleUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/consoleUpdates.ts @@ -1,33 +1,26 @@ -import PacketEmitter from "../PacketEmitter"; import {KafkatorioPacketData} from "../../generated/kafkatorio-schema"; -import Type = KafkatorioPacketData.Type; +import KafkatorioPacketQueue from "../emitting/KafkatorioPacketQueue"; -script.on_event( - defines.events.on_console_chat, - (event: OnConsoleChatEvent) => { - const update: KafkatorioPacketData.ConsoleChatUpdate = { - type: Type.ConsoleChatUpdate, +script.on_event(defines.events.on_console_chat, (event: OnConsoleChatEvent) => { + const update: KafkatorioPacketData.ConsoleChatUpdate = { + type: KafkatorioPacketData.Type.ConsoleChatUpdate, - authorPlayerIndex: event.player_index ?? null, - content: event.message - } - PacketEmitter.emitInstantPacket(update) - } -) + authorPlayerIndex: event.player_index ?? null, + content: event.message + } + KafkatorioPacketQueue.enqueue(update) +}) -script.on_event( - defines.events.on_console_command, - (event: OnConsoleCommandEvent) => { - const update: KafkatorioPacketData.ConsoleCommandUpdate = { - type: Type.ConsoleCommandUpdate, +script.on_event(defines.events.on_console_command, (event: OnConsoleCommandEvent) => { + const update: KafkatorioPacketData.ConsoleCommandUpdate = { + type: KafkatorioPacketData.Type.ConsoleCommandUpdate, - authorPlayerIndex: event.player_index ?? null, - command: event.command, - parameters: event.parameters, - } + authorPlayerIndex: event.player_index ?? null, + command: event.command, + parameters: event.parameters, + } - PacketEmitter.emitInstantPacket(update) - } -) + KafkatorioPacketQueue.enqueue(update) +}) diff --git a/modules/events-mod/src/main/typescript/main/events/handlers/ConfigurationUpdateHandler.ts b/modules/events-mod/src/main/typescript/main/events/handlers/ConfigurationUpdateHandler.ts index b90fec1..72f63a3 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers/ConfigurationUpdateHandler.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers/ConfigurationUpdateHandler.ts @@ -3,8 +3,9 @@ import { ConfigurationUpdateModData, KafkatorioPacketData } from "../../../generated/kafkatorio-schema"; -import PacketEmitter from "../../PacketEmitter"; +import PacketEmitter from "../../emitting/PacketEmitter"; import ConfigurationUpdate = KafkatorioPacketData.ConfigurationUpdate; +import KafkatorioPacketQueue from "../../emitting/KafkatorioPacketQueue"; export class ConfigurationUpdateHandler { @@ -20,7 +21,7 @@ export class ConfigurationUpdateHandler { factorioData: ConfigurationUpdateHandler.factorioData(changeData) } - PacketEmitter.emitInstantPacket(configUpdateData) + KafkatorioPacketQueue.enqueue(configUpdateData) } diff --git a/modules/events-mod/src/main/typescript/main/events/handlers/EntityUpdateHandler.ts b/modules/events-mod/src/main/typescript/main/events/handlers/EntityUpdateHandler.ts index 7ac7d13..19c7afc 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers/EntityUpdateHandler.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers/EntityUpdateHandler.ts @@ -6,7 +6,7 @@ import { Tick } from "../../../generated/kafkatorio-schema"; import {Converters} from "../converters"; -import EventDataCache from "../../cache/EventDataCache"; +import EventDataCache from "../../emitting/EventDataCache"; export class EntityUpdatesHandler { diff --git a/modules/events-mod/src/main/typescript/main/events/handlers/MapChunkUpdateHandler.ts b/modules/events-mod/src/main/typescript/main/events/handlers/MapChunkUpdateHandler.ts index fabbe7c..5fcb365 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers/MapChunkUpdateHandler.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers/MapChunkUpdateHandler.ts @@ -3,13 +3,11 @@ import {isEventType} from "../eventTypeCheck"; import { KafkatorioPacketData, MapChunkPosition, - MinedProduct, PrototypeKey } from "../../../generated/kafkatorio-schema"; -import EventUpdatesManager, {EventUpdates} from "../../cache/EventDataCache"; +import EventUpdates, {PacketKey} from "../../emitting/EventDataCache"; import {MapChunkUpdateEvent, MapTileChangeEvent} from "../mapChunkUpdates"; -import PacketKey = EventUpdates.PacketKey; -import Type = MinedProduct.Type; + type MapChunkTileUpdater = (data: KafkatorioPacketData.MapChunkTileUpdate) => void @@ -141,7 +139,7 @@ class MapChunkUpdateHandler { chunkPosition: [position.x, position.y], } - EventUpdatesManager.debounce( + EventUpdates.debounce( key, KafkatorioPacketData.Type.MapChunkTileUpdate, data => data.isDeleted = true, @@ -171,7 +169,7 @@ class MapChunkUpdateHandler { chunkPosition: chunkPosition, } - EventUpdatesManager.debounce( + EventUpdates.debounce( key, KafkatorioPacketData.Type.MapChunkTileUpdate, data => { diff --git a/modules/events-mod/src/main/typescript/main/events/handlers/PlayerUpdateHandler.ts b/modules/events-mod/src/main/typescript/main/events/handlers/PlayerUpdateHandler.ts index d9a9a14..59e243b 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers/PlayerUpdateHandler.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers/PlayerUpdateHandler.ts @@ -1,6 +1,6 @@ import {KafkatorioPacketData} from "../../../generated/kafkatorio-schema"; import {Converters} from "../converters"; -import EventUpdatesManager from "../../cache/EventDataCache"; +import EventUpdates from "../../emitting/EventDataCache"; export type PlayerUpdater = (player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) => void @@ -43,7 +43,7 @@ export class PlayerUpdateHandler { const eventName = Converters.eventNameString(event.name) - EventUpdatesManager.throttle( + EventUpdates.throttle( {index: playerIndex}, KafkatorioPacketData.Type.PlayerUpdate, data => { diff --git a/modules/events-mod/src/main/typescript/main/events/playerUpdates.ts b/modules/events-mod/src/main/typescript/main/events/playerUpdates.ts index d20afb4..da34131 100644 --- a/modules/events-mod/src/main/typescript/main/events/playerUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/playerUpdates.ts @@ -1,6 +1,6 @@ import {Converters} from "./converters"; import {ForceIndex, KafkatorioPacketData, PlayerUpdateKey} from "../../generated/kafkatorio-schema"; -import packetEmitter from "../PacketEmitter"; +import packetEmitter from "../emitting/PacketEmitter"; import PlayerUpdates from "./handlers/PlayerUpdateHandler"; diff --git a/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts b/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts index 6d17469..73dd991 100644 --- a/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts @@ -1,13 +1,14 @@ -import PacketEmitter from "../PacketEmitter"; +import PacketEmitter from "../emitting/PacketEmitter"; import { EntityItemGroup, FactorioPrototype, KafkatorioPacketData } from "../../generated/kafkatorio-schema"; import {Converters} from "./converters"; +import KafkatorioPacketQueue from "../emitting/KafkatorioPacketQueue"; -type PrototypesByType = LuaTable +type PrototypesByType = Record export function emitPrototypes() { @@ -16,10 +17,6 @@ export function emitPrototypes() { emit(mapTileProtos) - game.item_group_prototypes - game.item_subgroup_prototypes - - const entityProtos: PrototypesByType = getEntityPrototypes() emit(entityProtos) } @@ -27,7 +24,7 @@ export function emitPrototypes() { function emit(protosByType: PrototypesByType) { for (const [, protos] of pairs(protosByType)) { - PacketEmitter.emitInstantPacket({ + KafkatorioPacketQueue.enqueue({ type: KafkatorioPacketData.Type.PrototypesUpdate, prototypes: protos, }) @@ -36,13 +33,10 @@ function emit(protosByType: PrototypesByType) { function getMapTilePrototypes(): PrototypesByType { - const tiles = new LuaTable() - if (!tiles.has("tile")) { - tiles.set("tile", []) - } + const tiles: FactorioPrototype.MapTile[] = [] for (const [, tile] of game.tile_prototypes) { - tiles.get("tile").push({ + tiles[tiles.length] = { type: FactorioPrototype.Type.MapTile, protoId: Converters.prototypeId("tile", tile.name), @@ -51,21 +45,22 @@ function getMapTilePrototypes(): PrototypesByType { collisionMasks: Converters.convertCollisionMaskToNames(tile.collision_mask), mapColour: Converters.mapColour(tile.map_color), canBeMined: tile.mineable_properties.minable, - }) + } + } + + return { + "tiles": tiles } - return tiles } function getEntityPrototypes(): PrototypesByType { - const protos = new LuaTable() + const protos: PrototypesByType = {} for (const [, entity] of game.entity_prototypes) { const key: string = `${entity.group.name}/${entity.subgroup.name}` - if (!protos.has(key)) { - protos.set(key, []) - } + protos[key] ??= [] const entityProto: FactorioPrototype.Entity = { type: FactorioPrototype.Type.Entity, @@ -91,7 +86,7 @@ function getEntityPrototypes(): PrototypesByType { } entityProto.miningProperties = Converters.miningProperties(entity.mineable_properties) - protos.get(key).push(entityProto) + protos[key].push(entityProto) } return protos } diff --git a/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts index 54ee97e..cd0ee06 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts @@ -1,45 +1,50 @@ -import {Queue} from "../queue/queue"; import {isEventType} from "./eventTypeCheck"; import {Converters} from "./converters"; import {handleSurfaceUpdate} from "./surfaceUpdates"; -import EventCacheService from "../cache/EventDataCache"; +import EventCacheService from "../emitting/EventDataCache"; import MapChunkUpdate from "./handlers/MapChunkUpdateHandler"; +import EventDataQueue from "../queue/queue"; +import KafkatorioPacketQueue from "../emitting/KafkatorioPacketQueue"; +import PacketEmitter from "../emitting/PacketEmitter"; +import {KafkatorioPacketData} from "../../generated/kafkatorio-schema"; -script.on_event( - defines.events.on_tick, - (event: OnTickEvent) => { - if (event.tick % 1000 == 0) { - for (const [, surface] of game.surfaces) { - handleSurfaceUpdate(event, Converters.eventNameString(event.name), surface) - } - } +script.on_event(defines.events.on_tick, (event: OnTickEvent) => { + if (event.tick % 1000 == 0) { + for (const [, surface] of game.surfaces) { + handleSurfaceUpdate(event, Converters.eventNameString(event.name), surface) + } + } - if (event.tick % 6 == 0) { - // Every 0.1 seconds - const emittedCount = EventCacheService.extractAndEmitExpiredPackets() - if (emittedCount > 0) { - log(`[on_tick:${event.tick}] emitted ${emittedCount} events`) - } - } + const kPacket: KafkatorioPacketData | null = KafkatorioPacketQueue.dequeue() + if (kPacket != null) { + PacketEmitter.emitInstantPacket(kPacket) + } - if (event.tick % 7 == 0) { - const events: EventData[] = Queue.dequeueValues(1) + if (event.tick % 6 == 0) { + // Every 0.1 seconds + const emittedCount = EventCacheService.extractAndEmitExpiredPackets() + if (emittedCount > 0) { + log(`[on_tick:${event.tick}] emitted ${emittedCount} events`) + } + } - if (events.length > 0) { - log(`[on_tick:${event.tick}] dequeued ${events.length} events, current size: ${Queue.size()}`) + if (event.tick % 7 == 0) { + const events: EventData[] = EventDataQueue.dequeueValues(1) - let i = 1 - for (const event of events) { - if (isEventType(event, defines.events.on_chunk_generated)) { - let eName = Converters.eventNameString(event.name) + if (events.length > 0) { + log(`[on_tick:${event.tick}] dequeued ${events.length} events, current size: ${EventDataQueue.size()}`) - log(`[on_tick:${event.tick}] dequed event ${eName}, delay ${i}`) - MapChunkUpdate.handleChunkGeneratedEvent(event, i) - i += 1 - } - } + let i = 1 + for (const event of events) { + if (isEventType(event, defines.events.on_chunk_generated)) { + let eName = Converters.eventNameString(event.name) + + log(`[on_tick:${event.tick}] dequed event ${eName}, delay ${i}`) + MapChunkUpdate.handleChunkGeneratedEvent(event, i) + i += 1 } } } -) + } +}) diff --git a/modules/events-mod/src/main/typescript/main/events/settingsUpdate.ts b/modules/events-mod/src/main/typescript/main/events/settingsUpdate.ts index 93e3593..e22b244 100644 --- a/modules/events-mod/src/main/typescript/main/events/settingsUpdate.ts +++ b/modules/events-mod/src/main/typescript/main/events/settingsUpdate.ts @@ -1,7 +1,4 @@ -script.on_event( - defines.events.on_runtime_mod_setting_changed, - (e: OnRuntimeModSettingChangedEvent) => { - print(`Settings changed ${e.setting_type}, ${e.player_index}, ${e.setting}, ${e.mod_name}`) - // KafkatorioSettings.loadSettings() - } -) +script.on_event(defines.events.on_runtime_mod_setting_changed, (e: OnRuntimeModSettingChangedEvent) => { + print(`Settings changed ${e.setting_type}, ${e.player_index}, ${e.setting}, ${e.mod_name}`) + // KafkatorioSettings.loadSettings() +}) diff --git a/modules/events-mod/src/main/typescript/main/events/surfaceUpdates.ts b/modules/events-mod/src/main/typescript/main/events/surfaceUpdates.ts index a2bde69..005ca34 100644 --- a/modules/events-mod/src/main/typescript/main/events/surfaceUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/surfaceUpdates.ts @@ -1,4 +1,4 @@ -import PacketEmitter from "../PacketEmitter"; +import PacketEmitter from "../emitting/PacketEmitter"; import {KafkatorioPacketData} from "../../generated/kafkatorio-schema"; import Type = KafkatorioPacketData.Type; diff --git a/modules/events-mod/src/main/typescript/main/global-init.ts b/modules/events-mod/src/main/typescript/main/global-init.ts index 9670afb..21b366b 100644 --- a/modules/events-mod/src/main/typescript/main/global-init.ts +++ b/modules/events-mod/src/main/typescript/main/global-init.ts @@ -1,5 +1,5 @@ -import {Queue} from "./queue/queue"; -import EventUpdatesManager from "./cache/EventDataCache"; +import EventUpdates from "./emitting/EventDataCache"; +import {EventDataQueueManager} from "./queue/queue"; export function initGlobal(force: boolean = false) { @@ -8,8 +8,8 @@ export function initGlobal(force: boolean = false) { global.MOD_VERSION = script.active_mods[script.mod_name] global.FACTORIO_VERSION = script.active_mods["base"] - Queue.init(true) - EventUpdatesManager.init(true) + EventDataQueueManager.init(true) + EventUpdates.init(true) log("Finished initialising Kafkatorio Global variables") } diff --git a/modules/events-mod/src/main/typescript/main/queue/queue.ts b/modules/events-mod/src/main/typescript/main/queue/queue.ts index 95fd0cd..725ae75 100644 --- a/modules/events-mod/src/main/typescript/main/queue/queue.ts +++ b/modules/events-mod/src/main/typescript/main/queue/queue.ts @@ -1,23 +1,13 @@ -export namespace Queue { +export class EventDataQueueManager { - declare const global: { - store: EventQueueStore - - head: Node | null - tail: Node | null - - size: uint - } - - - export function init(force?: boolean) { + static init(force?: boolean) { const isAnythingUndefined = global.store == undefined || global.size == undefined || global.head == undefined || global.tail == undefined - log(`Initialising EventQueue globals (force=${force}, isAnythingUndefined=${isAnythingUndefined})`) + log(`Initialising EventDataQueueManager globals (force=${force}, isAnythingUndefined=${isAnythingUndefined})`) if (force == true || isAnythingUndefined) { global.store = {} @@ -26,16 +16,16 @@ export namespace Queue { global.size = 0 } - log(`Finished initialising EventQueue`) + log(`Finished initialising EventDataQueueManager`) } - export function size(): uint | undefined { + size(): uint | undefined { return global.size } - export function enqueue(key: string, event: EventData, weight: int = 1) { + enqueue(key: string, event: EventData, weight: int = 1) { if (key ! in global.store) { let node = new Node(key, weight) if (global.head == null) { @@ -52,7 +42,7 @@ export namespace Queue { } - export function dequeue(): WeightedPacket | null { + dequeue(): WeightedPacket | null { if (global.head == null) { return null } else { @@ -76,12 +66,12 @@ export namespace Queue { } - export function dequeueValues(targetWeight: uint = 50): EventData[] { + dequeueValues(targetWeight: uint = 50): EventData[] { let values: EventData[] = [] let weight: uint = 0 do { - let packet = dequeue() + let packet = this.dequeue() if (packet == null) { break; @@ -94,27 +84,43 @@ export namespace Queue { return values } - - class Node { - storeKey: string; - next: Node | null = null; - weight: uint - - constructor(storeKey: string, weight: uint) { - this.storeKey = storeKey; - this.weight = weight - } - } - - - interface EventQueueStore { - [key: string]: EventData | null; - } - - - interface WeightedPacket { - value: EventData, - weight: int, - } - +} + + +const EventDataQueue = new EventDataQueueManager() + + +export default EventDataQueue + + +declare const global: { + store: EventQueueStore + + head: Node | null + tail: Node | null + + size: uint +} + + +class Node { + storeKey: string; + next: Node | null = null; + weight: uint + + constructor(storeKey: string, weight: uint) { + this.storeKey = storeKey; + this.weight = weight + } +} + + +interface EventQueueStore { + [key: string]: EventData | null; +} + + +interface WeightedPacket { + value: EventData, + weight: int, } From 567ec6a68c07f381c629a40f67ec07f3a7c37472 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 9 Jul 2022 14:06:15 +0200 Subject: [PATCH 469/629] server: fix saving tiles >= chunk size 256 --- .../adamko/kafkatorio/server/processor/topology/saveMapTiles.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt index cbeef9b..a8a68ec 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt @@ -53,7 +53,7 @@ fun saveMapTiles( ), TOPIC_MAP_CHUNK_COLOURED_STATE, ).filter("$pid.consume.grouped-map-chunks.filter-size") { _, y -> - y.chunkId.chunkSize.zoomLevel >= ChunkSize.CHUNK_256.zoomLevel + y.chunkId.chunkSize.lengthInTiles >= ChunkSize.CHUNK_256.lengthInTiles } val savedChunkFilenames: KStream = From e4a7401baa116e47ebd448ec7a65521da079cd04 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 12 Jul 2022 22:39:33 +0200 Subject: [PATCH 470/629] buildSrc rm unused dependencies --- buildSrc/build.gradle.kts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index d1f2d38..8dbc6c5 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -55,10 +55,6 @@ dependencies { // https://github.com/avast/gradle-docker-compose-plugin // implementation("com.avast.gradle:gradle-docker-compose-plugin:${Versions.gradleDockerComposePlugin}") -// implementation(platform("org.http4k:http4k-bom:${libs.versions.http4k.get()}")) -// implementation("org.http4k:http4k-core") -// implementation("org.http4k:http4k-client-okhttp") - // https://github.com/gradle/gradle/issues/15383#issuecomment-779893192 // https://youtrack.jetbrains.com/issue/IDEA-262280#focus=Comments-27-5397040.0-0 // implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location)) From a805d2ad63c233b1a4442e3cecd23ac9cd8a77fa Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 12 Jul 2022 22:40:03 +0200 Subject: [PATCH 471/629] bump kotlin 1.7.10 --- gradle/kotlin-js-store/yarn.lock | 24 ++++++++++++------------ gradle/libs.versions.toml | 8 +++----- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index 6b8baf8..0152645 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -384,7 +384,7 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -abab@^2.0.5: +abab@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== @@ -1730,10 +1730,10 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -karma-chrome-launcher@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz#805a586799a4d05f4e54f72a204979f3f3066738" - integrity sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg== +karma-chrome-launcher@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz#baca9cc071b1562a1db241827257bfe5cab597ea" + integrity sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ== dependencies: which "^1.2.1" @@ -2584,19 +2584,19 @@ sockjs@^0.3.24: uuid "^8.3.2" websocket-driver "^0.7.4" -source-map-js@^1.0.1, source-map-js@^1.0.2: +source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== -source-map-loader@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.1.tgz#9ae5edc7c2d42570934be4c95d1ccc6352eba52d" - integrity sha512-Vp1UsfyPvgujKQzi4pyDiTOnE3E4H+yHvkVRN3c/9PJmQS4CQJExvcDvaX/D+RV+xQben9HJ56jMJS3CgUeWyA== +source-map-loader@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-4.0.0.tgz#bdc6b118bc6c87ee4d8d851f2d4efcc5abdb2ef5" + integrity sha512-i3KVgM3+QPAHNbGavK+VBq03YoJl24m9JWNbLgsjTj8aJzXG9M61bantBTNBt7CNwY2FYf+RJRYJ3pzalKjIrw== dependencies: - abab "^2.0.5" + abab "^2.0.6" iconv-lite "^0.6.3" - source-map-js "^1.0.1" + source-map-js "^1.0.2" source-map-support@~0.5.20: version "0.5.21" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 579a7a0..a026552 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,12 +6,12 @@ ## compilation ## jvm = "11" -kotlin = "1.7.0" +kotlin = "1.7.10" ## libs ## camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" -kafka = "3.2.0" +kafka = "3.2.0" # https://kafka.apache.org/downloads kvision = "5.12.0" log4j2 = "2.17.2" okio = "3.2.0" @@ -71,8 +71,6 @@ kotlinJs = { id = "org.jetbrains.kotlin.js", vers kotlinSerialization = { id = "org.jetbrains.kotlin.kotlin-serialization", version.ref = "kotlin" } loggingCapabilities = { id = "dev.jacomet.logging-capabilities", version = "0.10.0" } -#shadowJar = { id = "com.github.jengelman.gradle.plugins.shadow", version = "6.1.0" } -#dependencyCheck = { id = "com.github.ben-manes.versions", version = "0.39.0" } ########### @@ -210,7 +208,7 @@ kafka-streamsTestUtils = { group = "org.apache.kafka", name = "kafka-streams-tes kafka-kotkaStreams = { group = "dev.adamko.kotka", name = "kotka-streams", version.ref = "kotkaStreams" } -mary-rocksdb = { group = "io.maryk.rocksdb", name = "rocksdb-multiplatform", version.ref = "marykRocksDb" } +marykRocksDb = { group = "io.maryk.rocksdb", name = "rocksdb-multiplatform", version.ref = "marykRocksDb" } jsoup = { group = "org.jsoup", name = "jsoup", version = "1.14.3" } skrapeit = { group = "it.skrape", name = "skrapeit", version = "1.2.0" } From b507081eacc38e280c609628b5a2060dd24280c2 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 16 Jul 2022 23:10:32 +0200 Subject: [PATCH 472/629] Render buildings and resources - create LuaJsonList to handle empty Lua JSON lists being sent as empty objects - fix exporting of resources and entities - split up map tiles into different layer directories - add 'chunk size' to MapChunkPosition - move tests to correct packages - bump tstl - decrease tstl logging - remove some defined, but unused, kafka topics - syslog, rest, websocket servers & web-map: decrease logging - webmap: add additional layers for buildings and resources --- build.gradle.kts | 31 +- gradle.properties | 2 +- modules/events-library/build.gradle.kts | 2 +- .../dev/adamko/kafkatorio/library/json.kt | 97 ++-- .../kafkatorio/library/positionOperations.kt | 103 ++++ .../kafkatorio/schema/common/colours.kt | 1 + .../kafkatorio/schema/common/entities.kt | 312 +++++++++---- .../schema/common/factorioPrototypes.kt | 20 +- .../kafkatorio/schema/common/mapTile.kt | 82 ++-- .../kafkatorio/schema/common/positions.kt | 293 ++++++------ .../kafkatorio/schema/common/prototypeIds.kt | 9 + .../schema/packets/eventServerPacket.kt | 4 +- .../schema/packets/kafkatorioPacket.kt | 15 +- .../schema/packets/kafkatorioPacketInstant.kt | 7 +- .../schema/packets/kafkatorioPacketKeyed.kt | 78 +++- .../schema => schema/common}/ColourHexTest.kt | 6 +- .../common/MapChunkPositionBoundsTest.kt | 83 +++- .../schema/common/MapChunkPositionTest.kt | 4 +- .../schema/common/MapTilePositionTest.kt | 24 +- .../common}/PrototypesTest.kt | 5 +- .../packets/MapChunkTileUpdateTest.kt} | 18 +- .../packets}/UpdatePacketsTest.kt | 14 +- .../kafkatorio/{events => }/schema/kt2ts2.kt | 10 +- .../kafkatorio/library/KxsBinaryTests.kt | 23 +- modules/events-mod/build.gradle.kts | 6 +- modules/events-mod/package-lock.json | 6 +- modules/events-mod/package.json | 2 +- .../lua/generated/kafkatorio-schema.lua | 102 ++-- .../lua/main/commands/kafkatorioCommands.lua | 4 +- .../queue.lua => emitting/EventDataQueue.lua} | 0 .../main/emitting/KafkatorioPacketQueue.lua | 4 + .../generated/lua/main/events/converters.lua | 136 +++--- .../events/handlers/EntityUpdateHandler.lua | 132 +++--- .../events/handlers/MapChunkUpdateHandler.lua | 12 +- .../lua/main/events/prototypeUpdates.lua | 6 +- .../main/events/registerEventListeners.lua | 4 +- .../src/generated/lua/main/global-init.lua | 4 +- .../lua/main/settings/KafkatorioSettings.lua | 8 +- .../resources/mod-data/locale/en/locale.cfg | 8 +- .../typescript/generated/kafkatorio-schema.ts | 195 ++++---- .../main/commands/kafkatorioCommands.ts | 2 +- .../queue.ts => emitting/EventDataQueue.ts} | 0 .../main/emitting/KafkatorioPacketQueue.ts | 7 + .../main/typescript/main/events/converters.ts | 136 +++--- .../events/handlers/EntityUpdateHandler.ts | 108 ++--- .../events/handlers/MapChunkUpdateHandler.ts | 9 +- .../main/events/prototypeUpdates.ts | 6 +- .../main/events/registerEventListeners.ts | 2 +- .../src/main/typescript/main/global-init.ts | 2 +- .../main/settings/KafkatorioSettings.ts | 1 + modules/events-mod/tsconfig.json | 10 +- .../adamko/kafkatorio/server/eventsServer.kt | 2 - .../server/processor/DebounceProcessor.kt | 20 +- .../server/processor/KafkatorioTopology.kt | 73 ++- .../server/processor/kafkatorioTopics.kt | 57 ++- .../processor/topology/colourMapChunks.kt | 219 +++++---- .../topology/colourResourceChunks.kt | 442 ++++++++++++++++++ .../topology/factorioServerPackets.kt | 8 +- .../server/processor/topology/model.kt | 4 +- .../server/processor/topology/prototypes.kt | 96 +++- .../server/processor/topology/saveMapTiles.kt | 41 +- .../server/socket/SyslogSocketServer.kt | 2 +- .../server/web/rest/factorioServersRoutes.kt | 23 +- .../kafkatorio/server/web/rest/restApi.kt | 8 +- .../web/websocket/WebmapWebsocketServer.kt | 4 +- .../src/main/resources/config.yml | 2 +- .../kafkatorio/processor/misc/serdeSize.kt | 5 +- .../processor/topology/SaveMapChunksTest.kt | 26 +- .../src/docker-compose.yml | 1 + .../dev/adamko/kafkatorio/webmap/App.kt | 2 +- .../dev/adamko/kafkatorio/webmap/map.kt | 33 +- .../adamko/kafkatorio/webmap/websockets.kt | 12 +- 72 files changed, 2167 insertions(+), 1068 deletions(-) create mode 100644 modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/positionOperations.kt rename modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/{events/schema => schema/common}/ColourHexTest.kt (89%) rename modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/{events/schema => schema/common}/PrototypesTest.kt (99%) rename modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/{events/schema/MapChunkUpdateTest.kt => schema/packets/MapChunkTileUpdateTest.kt} (84%) rename modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/{events/schema => schema/packets}/UpdatePacketsTest.kt (93%) rename modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/{events => }/schema/kt2ts2.kt (92%) rename modules/events-mod/src/generated/lua/main/{queue/queue.lua => emitting/EventDataQueue.lua} (100%) rename modules/events-mod/src/main/typescript/main/{queue/queue.ts => emitting/EventDataQueue.ts} (100%) create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourResourceChunks.kt diff --git a/build.gradle.kts b/build.gradle.kts index eda9b8e..5ca67e0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -47,8 +47,8 @@ val startInfra by tasks.registering { group = project.name dependsOn( - ":modules:infra-kafka-pipe:processRun", - ":modules:infra-kafka-cluster:processRun", +// ":modules:infra-kafka-pipe:processRun", + runKafkaCluster // ":modules:infra-kafka-connect:processRun", ) } @@ -74,3 +74,30 @@ val runWebMap by tasks.registering { dependsOn(":modules:web-map:browserDevelopmentRun") } + + +val runKafkaCluster by tasks.registering { + group = project.name + + dependsOn( + ":modules:infra-kafka-cluster:processRun", + ) +} + + +val runFactorioServer by tasks.registering { + group = project.name + + dependsOn( + ":modules:infra-factorio-server:processRun", + ) +} + + +val runFactorioClient by tasks.registering { + group = project.name + + dependsOn( + ":modules:infra-factorio-client:processRun", + ) +} diff --git a/gradle.properties b/gradle.properties index 0298688..e4be207 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ org.gradle.unsafe.configuration-cache-problems=warn org.gradle.kotlin.dsl.precompiled.accessors.strict=true -org.gradle.parallel=true +#org.gradle.parallel=true # helps with pRoJeCtS mUsT bE cOnFiGuRiNg # pRoJeCtS mUsT bE cOnFiGuRiNg org.gradle.configureondemand=false diff --git a/modules/events-library/build.gradle.kts b/modules/events-library/build.gradle.kts index 107c99e..cf03c93 100644 --- a/modules/events-library/build.gradle.kts +++ b/modules/events-library/build.gradle.kts @@ -129,7 +129,7 @@ val generateTypeScript by tasks.registering(GenerateTypeScriptTask::class) { // kotlinMainDependencies, ) output.set(layout.buildDirectory.dir("generated/typescript")) - mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2ts2Kt") + mainClass.set("dev.adamko.kafkatorio.schema.Kt2ts2Kt") args(temporaryDir.canonicalPath) } diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/json.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/json.kt index ee63cc1..33bdffc 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/json.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/json.kt @@ -1,19 +1,17 @@ package dev.adamko.kafkatorio.library -import kotlin.reflect.KClass -import kotlinx.serialization.DeserializationStrategy +import kotlin.jvm.JvmInline import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.SerializationException import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonArray -import kotlinx.serialization.json.JsonContentPolymorphicSerializer -import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonDecoder import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.JsonTransformingSerializer -import kotlinx.serialization.json.buildJsonObject -import kotlinx.serialization.json.contentOrNull -import kotlinx.serialization.json.jsonObject -import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.modules.SerializersModule @@ -22,55 +20,60 @@ val jsonMapperKafkatorio = Json { prettyPrintIndent = " " serializersModule = SerializersModule { - contextual(List::class) { args -> FactorioJsonListSerializer(args[0]) } +// contextual(List::class) { args -> FactorioListJsonSerializer(args[0]) } } } +/** @see LuaJsonListSerializer */ +@Serializable(with = LuaJsonListSerializer::class) +@JvmInline +value class LuaJsonList(private val list: List) : List by list + + /** - * Factorio outputs an *empty* list as an *empty* Json object. This serde performs the same - * conversion. + * Factorio outputs **empty** lists `[]` as *empty* Json objects `{}`. + * + * When deserializing JSON, this serializer transforms any incoming empty objects to empty + * [array][JsonArray]s. */ -class FactorioJsonListSerializer(dataSerializer: KSerializer) : - JsonTransformingSerializer>(ListSerializer(dataSerializer)) { +class LuaJsonListSerializer( + elementSerializer: KSerializer +) : KSerializer> { - override fun transformDeserialize(element: JsonElement): JsonElement { - return when (element) { - is JsonObject -> JsonArray(emptyList()) - else -> element + private val listSerializer: KSerializer> = ListSerializer(elementSerializer) + + override val descriptor: SerialDescriptor = + SerialDescriptor("kafkatorio.LuaList", listSerializer.descriptor) + + override fun deserialize(decoder: Decoder): LuaJsonList = LuaJsonList( + when (decoder) { + is JsonDecoder -> deserializeJson(decoder) + else -> decoder.decodeSerializableValue(listSerializer) } - } + ) - override fun transformSerialize(element: JsonElement): JsonElement { - return when { - element is JsonArray && element.isEmpty() -> buildJsonObject { } - else -> element + private fun deserializeJson(decoder: JsonDecoder): List = + when (val element = decoder.decodeJsonElement()) { + is JsonObject -> when { + element.entries.isEmpty() -> emptyList() + else -> deserializeError( + "expected empty Json object, but contained ${element.entries.size} entries ${element.entries}" + ) + } + is JsonArray -> decoder.json.decodeFromJsonElement(listSerializer, element) + else -> deserializeError( + "expected empty Json object or a Json array, but was $element" + ) } + + override fun serialize(encoder: Encoder, value: LuaJsonList) { + encoder.encodeSerializableValue(listSerializer, value) } -} - - -interface SerializerProvider { - val serializer: KSerializer -} - -open class SerializerProviderDeserializer( - private val baseClass: KClass, - private val key: String, - private val selector: (String) -> SerializerProvider?, -) : JsonContentPolymorphicSerializer(baseClass) { - - override fun selectDeserializer(element: JsonElement): DeserializationStrategy { - - val type = element - .jsonObject[key] - ?.jsonPrimitive - ?.contentOrNull - ?.let { json -> selector(json) } - - requireNotNull(type) { "Unknown ${baseClass.simpleName} $key: $element" } - - return type.serializer + companion object { + private fun deserializeError(msg: String): Nothing = throw SerializationException( + "Error deserializing LuaList: $msg" + ) } } diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/positionOperations.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/positionOperations.kt new file mode 100644 index 0000000..2467172 --- /dev/null +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/positionOperations.kt @@ -0,0 +1,103 @@ +package dev.adamko.kafkatorio.library + +import dev.adamko.kafkatorio.schema.common.ChunkSize +import dev.adamko.kafkatorio.schema.common.MapChunkPosition +import dev.adamko.kafkatorio.schema.common.MapEntityPosition +import dev.adamko.kafkatorio.schema.common.MapTilePosition +import kotlin.math.floor + + +operator fun MapTilePosition.times(factor: Int): MapTilePosition = + MapTilePosition(x * factor, y * factor) + + +operator fun MapTilePosition.div(divisor: Int): MapTilePosition = + MapTilePosition(x / divisor, y / divisor) + + +operator fun MapTilePosition.plus(addend: Int): MapTilePosition = + MapTilePosition(x + addend, y + addend) + + +operator fun MapTilePosition.plus(addend: MapTilePosition): MapTilePosition = + MapTilePosition(x + addend.x, y + addend.y) + + +operator fun MapTilePosition.minus(subtrahend: MapTilePosition): MapTilePosition = + MapTilePosition(x - subtrahend.x, y - subtrahend.y) + + +/** Get the [MapChunkPosition] of the tile */ +fun MapTilePosition.toMapChunkPosition(chunkSize: ChunkSize): MapChunkPosition = + MapChunkPosition( + x = floor(x.toDouble() / chunkSize.lengthInTiles.toDouble()).toInt(), + y = floor(y.toDouble() / chunkSize.lengthInTiles.toDouble()).toInt(), + chunkSize = chunkSize, + ) + + +/** Get the [MapTilePosition] of the entity */ +fun MapEntityPosition.toMapTilePosition(): MapTilePosition = + MapTilePosition( + x = floor(x).toInt(), + y = floor(y).toInt(), + ) + + +/** Get the [MapChunkPosition] of the entity */ +fun MapEntityPosition.toMapChunkPosition(chunkSize: ChunkSize): MapChunkPosition = + MapChunkPosition( + x = floor(x / chunkSize.lengthInTiles.toDouble()).toInt(), + y = floor(y / chunkSize.lengthInTiles.toDouble()).toInt(), + chunkSize = chunkSize, + ) + + +fun MapChunkPosition.resize(chunkSize: ChunkSize): MapChunkPosition = + leftTopTile().toMapChunkPosition(chunkSize) + + +operator fun MapChunkPosition.times(factor: Int): MapChunkPosition = + copy(x = x * factor, y = y * factor) + + +operator fun MapChunkPosition.plus(addend: Int): MapChunkPosition = + copy(x = x + addend, y = y + addend) + + +operator fun MapChunkPosition.minus(subtrahend: Int): MapChunkPosition = + copy(x = x - subtrahend, y = y - subtrahend) + + +fun MapChunkPosition.leftTopTile(): MapTilePosition = + MapTilePosition( + x * chunkSize.lengthInTiles, + y * chunkSize.lengthInTiles, + ) + + +fun MapChunkPosition.rightBottomTile(): MapTilePosition = + leftTopTile() + (chunkSize.lengthInTiles - 1) + + +/** Iterate over all possible [MapTilePosition]s in the chunk. */ +fun MapChunkPosition.iterateTiles(): Iterator { + val leftTop = leftTopTile() + val rightBottom = rightBottomTile() + + return iterator { + (leftTop.x..rightBottom.x).forEach { x -> + (leftTop.y..rightBottom.y).forEach { y -> + yield(MapTilePosition(x, y)) + } + } + } +} + + +//val MapChunkPosition.rightBottomTile: MapTilePosition +// get() = leftTopTile + (MAP_CHUNK_SIZE - 1) + +// +//val MapChunkPosition.boundingBox: MapBoundingBox +// get() = MapBoundingBox(leftTopTile, rightBottomTile) diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt index 6aa4cae..c7c7f22 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt @@ -52,6 +52,7 @@ data class ColourHex( ) { companion object { val TRANSPARENT = ColourHex(0u, 0u, 0u, 0u) + val WHITE = ColourHex(UByte.MAX_VALUE, UByte.MAX_VALUE, UByte.MAX_VALUE, UByte.MAX_VALUE) } } diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/entities.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/entities.kt index 2a101a2..8bc91fd 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/entities.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/entities.kt @@ -1,24 +1,29 @@ package dev.adamko.kafkatorio.schema.common +import kotlin.jvm.JvmInline import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +// TODO change all booleans to be optional, and default to 'false' (also in events-mod) + + @Serializable @SerialName("kafkatorio.entity.FactorioEntityData") sealed interface FactorioEntityData { val protoId: PrototypeId - val status: Status? val position: MapEntityPosition /** Non-specific entity data */ @Serializable - @SerialName("kafkatorio.entity.FactorioEntityData.Standard") + @SerialName("kafkatorio.entity.FactorioEntityData") data class Standard( override val protoId: PrototypeId, - override val status: Status? = null, + val status: Status? = null, + + val unitNumber: UnitNumber? = null, override val position: MapEntityPosition, val graphicsVariation: UByte? = null, @@ -26,121 +31,230 @@ sealed interface FactorioEntityData { val isActive: Boolean? = null, val isRotatable: Boolean? = null, val lastUser: UInt? = null, - val localisedDescription: String? = null, - val localisedName: String? = null, - ) : FactorioEntityData + ) : FactorioEntityData { + constructor( + position: MapEntityPosition, + protoId: PrototypeId, + element: FactorioEntityUpdateElement.Entity + ) : this( + protoId = protoId, + position = position, + + status = element.status, + unitNumber = element.unitNumber, + graphicsVariation = element.graphicsVariation, + health = element.health, + isActive = element.isActive, + isRotatable = element.isRotatable, + lastUser = element.lastUser + ) + } @Serializable - @SerialName("kafkatorio.entity.FactorioEntityData.Resource") + @SerialName("kafkatorio.entity.FactorioResourceData") data class Resource( override val protoId: PrototypeId, - override val status: Status? = null, override val position: MapEntityPosition, val amount: UInt, /** Count of initial resource units contained. `null` if resource is not infinite. */ val initialAmount: UInt? = null, - ) : FactorioEntityData + ) : FactorioEntityData { + constructor( + position: MapEntityPosition, + protoId: PrototypeId, + element: FactorioEntityUpdateElement.Resource + ) : this( + protoId = protoId, + position = position, + + amount = element.amount, + initialAmount = element.initialAmount, + ) + } + /** + * [`https://lua-api.factorio.com/latest/defines.html#defines.entity_status`](https://lua-api.factorio.com/latest/defines.html#defines.entity_status) + */ + @Suppress("unused") // not directly used at the moment - maybe later @Serializable - @SerialName("kafkatorio.entity.FactorioEntityData.EntityStatus") + @SerialName("kafkatorio.entity.FactorioEntityData.FactorioEntityStatus") enum class Status { - CANT_DIVIDE_SEGMENTS, - CHARGING, - CLOSED_BY_CIRCUIT_NETWORK, - DISABLED, - DISABLED_BY_CONTROL_BEHAVIOR, - DISABLED_BY_SCRIPT, - DISCHARGING, - FLUID_INGREDIENT_SHORTAGE, - FULLY_CHARGED, - FULL_OUTPUT, - ITEM_INGREDIENT_SHORTAGE, - LAUNCHING_ROCKET, - LOW_INPUT_FLUID, - LOW_POWER, - LOW_TEMPERATURE, - MARKED_FOR_DECONSTRUCTION, - MISSING_REQUIRED_FLUID, - MISSING_SCIENCE_PACKS, - NETWORKS_CONNECTED, - NETWORKS_DISCONNECTED, - NORMAL, - NOT_CONNECTED_TO_RAIL, - NOT_PLUGGED_IN_ELECTRIC_NETWORK, - NO_AMMO, - NO_FUEL, - NO_INGREDIENTS, - NO_INPUT_FLUID, - NO_MINABLE_RESOURCES, - NO_MODULES_TO_TRANSMIT, - NO_POWER, - NO_RECIPE, - NO_RESEARCH_IN_PROGRESS, - OPENED_BY_CIRCUIT_NETWORK, - OUT_OF_LOGISTIC_NETWORK, - PREPARING_ROCKET_FOR_LAUNCH, - RECHARGING_AFTER_POWER_OUTAGE, - TURNED_OFF_DURING_DAYTIME, - WAITING_FOR_SOURCE_ITEMS, - WAITING_FOR_SPACE_IN_DESTINATION, - WAITING_FOR_TARGET_TO_BE_BUILT, - WAITING_FOR_TRAIN, - WAITING_TO_LAUNCH_ROCKET, WORKING, + NORMAL, + NO_POWER, + LOW_POWER, + NO_FUEL, + DISABLED_BY_CONTROL_BEHAVIOR, + OPENED_BY_CIRCUIT_NETWORK, + CLOSED_BY_CIRCUIT_NETWORK, + DISABLED_BY_SCRIPT, + MARKED_FOR_DECONSTRUCTION, + + /** Used by generators and solar panels. */ + NOT_PLUGGED_IN_ELECTRIC_NETWORK, + + /** Used by power switches. */ + NETWORKS_CONNECTED, + + /** Used by power switches. */ + NETWORKS_DISCONNECTED, + + /** Used by accumulators. */ + CHARGING, + /** Used by accumulators. */ + DISCHARGING, + /** Used by accumulators. */ + FULLY_CHARGED, + + /** Used by logistic containers. */ + OUT_OF_LOGISTIC_NETWORK, + + /** Used by assembling machines. */ + NO_RECIPE, + + /** Used by furnaces. */ + NO_INGREDIENTS, + + /** USED BY BOILERS, fluid turrets and fluid energy sources: Boiler has no fluid to work with. */ + NO_INPUT_FLUID, + + /** Used by labs. */ + NO_RESEARCH_IN_PROGRESS, + + /** Used by mining drills. */ + NO_MINABLE_RESOURCES, + + /** Used by boilers and fluid turrets: Boiler still has some fluid but is about to run out. */ + LOW_INPUT_FLUID, + + /** Used by crafting machines. */ + FLUID_INGREDIENT_SHORTAGE, + + /** + * Used by crafting machines, boilers, burner energy sources and reactors: Reactor/burner has + * full burnt result inventory, boiler has full output fluid box. + */ + FULL_OUTPUT, + + /** Used by crafting machines. */ + ITEM_INGREDIENT_SHORTAGE, + + /** Used by mining drills when the mining fluid is missing. */ + MISSING_REQUIRED_FLUID, + + /** Used by labs. */ + MISSING_SCIENCE_PACKS, + + /** Used by inserters. */ + WAITING_FOR_SOURCE_ITEMS, + + /** Used by inserters and mining drills. */ + WAITING_FOR_SPACE_IN_DESTINATION, + + /** Used by the rocket silo. */ + PREPARING_ROCKET_FOR_LAUNCH, + /** Used by the rocket silo. */ + WAITING_TO_LAUNCH_ROCKET, + /** Used by the rocket silo. */ + LAUNCHING_ROCKET, + + /** Used by beacons. */ + NO_MODULES_TO_TRANSMIT, + + /** Used by roboports. */ + RECHARGING_AFTER_POWER_OUTAGE, + + /** Used by inserters targeting entity ghosts. */ + WAITING_FOR_TARGET_TO_BE_BUILT, + /** Used by inserters targeting rails. */ + WAITING_FOR_TRAIN, + + /** Used by ammo turrets. */ + NO_AMMO, + + /** Used by heat energy sources. */ + LOW_TEMPERATURE, + + /** Used by constant combinators: Combinator is turned off via switch in GUI. */ + DISABLED, + + /** Used by lamps. */ + TURNED_OFF_DURING_DAYTIME, + + /** Used by rail signals. */ + NOT_CONNECTED_TO_RAIL, + /** Used by rail signals. */ + CANT_DIVIDE_SEGMENTS, } } -/* - enum entity_status { - working, - normal, - no_power, - low_power, - no_fuel, - disabled_by_control_behavior, - opened_by_circuit_network, - closed_by_circuit_network, - disabled_by_script, - marked_for_deconstruction, - not_plugged_in_electric_network, - networks_connected, - networks_disconnected, - charging, - discharging, - fully_charged, - out_of_logistic_network, - no_recipe, - no_ingredients, - no_input_fluid, - no_research_in_progress, - no_minable_resources, - low_input_fluid, - fluid_ingredient_shortage, - full_output, - item_ingredient_shortage, - missing_required_fluid, - missing_science_packs, - waiting_for_source_items, - waiting_for_space_in_destination, - preparing_rocket_for_launch, - waiting_to_launch_rocket, - launching_rocket, - no_modules_to_transmit, - recharging_after_power_outage, - waiting_for_target_to_be_built, - waiting_for_train, - no_ammo, - low_temperature, - disabled, - turned_off_during_daytime, - not_connected_to_rail, - cant_divide_segments, - } - */ + +sealed interface FactorioEntityUpdateDictionary + : Iterable> { + + val entitiesXY: Map> + + operator fun get(position: MapEntityPosition): T? = + entitiesXY[position.x.toString()]?.get(position.y.toString()) + + override fun iterator(): Iterator> = + iterator { + entitiesXY.forEach { (x, column) -> + column.forEach { (y, entity) -> + yield( + MapEntityPosition(x.toDouble(), y.toDouble()) to entity + ) + } + } + } + + @Serializable + @SerialName("kafkatorio.entity.FactorioEntityUpdateResourceDictionary") + @JvmInline + value class Resource( + override val entitiesXY: Map> + ) : FactorioEntityUpdateDictionary + + @Serializable + @SerialName("kafkatorio.entity.FactorioEntityUpdateEntityDictionary") + @JvmInline + value class Entity( + override val entitiesXY: Map> + ) : FactorioEntityUpdateDictionary + +} + + +sealed interface FactorioEntityUpdateElement { + + @Serializable + @SerialName("kafkatorio.entity.FactorioEntityUpdateResource") + data class Resource( + val amount: UInt, + /** Count of initial resource units contained. `null` if resource is not infinite. */ + val initialAmount: UInt? = null, + ) : FactorioEntityUpdateElement + + @Serializable + @SerialName("kafkatorio.entity.FactorioEntityUpdateEntity") + data class Entity( + val status: FactorioEntityData.Status? = null, + + val unitNumber: UnitNumber? = null, + + val graphicsVariation: UByte? = null, + val health: Float? = null, + val isActive: Boolean? = null, + val isRotatable: Boolean? = null, + val lastUser: UInt? = null, + ) : FactorioEntityUpdateElement + +} + /* AssemblingMachine diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt index ec752b1..05c15af 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt @@ -1,6 +1,6 @@ package dev.adamko.kafkatorio.schema.common -import kotlinx.serialization.Contextual +import dev.adamko.kafkatorio.library.LuaJsonList import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -20,8 +20,8 @@ sealed interface FactorioPrototype { val mapColour: Colour, val layer: UInt, - @Contextual - val collisionMasks: List, +// @Contextual + val collisionMasks: LuaJsonList, val order: String, /** Can the tile be mined for resources? */ val canBeMined: Boolean, @@ -49,17 +49,23 @@ sealed interface FactorioPrototype { val mapColourEnemy: Colour? = null, val maxHealth: Float, - val isBuilding: Boolean, - val isEntityWithOwner: Boolean, - val isMilitaryTarget: Boolean, + val isBuilding: Boolean = false, + val isEntityWithOwner: Boolean = false, + val isMilitaryTarget: Boolean = false, val miningProperties: MiningProperties? = null, + + val collisionBox: MapBoundingBox? = null, ) : FactorioPrototype { + val tileHeight: Int? get() = collisionBox?.tileHeight + val tileWidth: Int? get() = collisionBox?.tileWidth + @Serializable @SerialName("kafkatorio.prototype.EntityMiningProperties") data class MiningProperties( val canBeMined: Boolean, - val products: List?, +// @Contextual + val products: LuaJsonList?, ) @Serializable diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt index c7b98b8..2661272 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt @@ -1,10 +1,11 @@ package dev.adamko.kafkatorio.schema.common - import dev.adamko.kafkatorio.schema.common.MapTileDictionary.PrototypeKey import kotlin.jvm.JvmInline +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable + const val MAP_CHUNK_SIZE = 32 @@ -24,11 +25,11 @@ data class MapTile( * [PrototypeKey] is an arbitrary integer value, which maps to one [PrototypeId] only for a * specific instance of [MapTileDictionary]. * - * Each X/Y coordinate in [tilesXY] maps to a [PrototypeKey]. + * @param[tilesXY] Map an X/Y coordinate to a [PrototypeKey]. */ @Serializable +@SerialName("kafkatorio.packet.keyed.MapTileDictionary") data class MapTileDictionary( - /** Map an X,Y coordinate a prototype name */ val tilesXY: Map>, val protos: Map, ) { @@ -55,59 +56,68 @@ data class MapTileDictionary( /** An arbitrary ID for a prototype in [MapTileDictionary.protos]. */ @Serializable @JvmInline - value class PrototypeKey(private val index: Int) + value class PrototypeKey(private val index: Int) : Comparable by index - companion object { - fun MapTileDictionary?.isNullOrEmpty(): Boolean { - return this == null || (tilesXY.isEmpty() && tilesXY.all { it.value.isEmpty() }) - } - } +// companion object { +// fun MapTileDictionary?.isNullOrEmpty(): Boolean { +// return this == null || (tilesXY.isEmpty() && tilesXY.all { it.value.isEmpty() }) +// } +// } } -@Serializable -data class MapBoundingBox( - val topLeft: MapTilePosition, - val bottomRight: MapTilePosition, -) - - @Serializable data class ServerMapChunkId( val serverId: FactorioServerId, + val layer: ServerMapTileLayer, val chunkPosition: MapChunkPosition, val surfaceIndex: SurfaceIndex, - val chunkSize: ChunkSize, -) +) { + val chunkSize: ChunkSize get() = chunkPosition.chunkSize +} -/** `${serverDataDir}/servers/{serverId}/map/tiles/s{surfaceIndex}/z{zoomLevel}/x{chunkX}/y{chunkY}.png` */ +@Serializable +enum class ServerMapTileLayer(val dir: String) { + @SerialName("terrain") + TERRAIN("terrain"), + @SerialName("resource") + RESOURCE("resource"), + @SerialName("building") + BUILDING("building"), +} + + +/** `${serverDataDir}/servers/{serverId}/map/${layer}/s{surfaceIndex}/z{zoomLevel}/x{chunkX}/y{chunkY}.png` */ @Serializable @JvmInline -value class TilePngFilename( - val value: String, -) { +value class ServerMapTilePngFilename(val value: String) { + constructor(id: ServerMapChunkId) : this( - id.serverId, - id.surfaceIndex, - id.chunkSize.zoomLevel, - id.chunkPosition.x, - id.chunkPosition.y, + serverId = id.serverId, + layer = id.layer, + surfaceIndex = id.surfaceIndex, + zoomLevel = id.chunkSize.zoomLevel, + chunkX = id.chunkPosition.x, + chunkY = id.chunkPosition.y, ) constructor( serverId: FactorioServerId, + layer: ServerMapTileLayer, surfaceIndex: SurfaceIndex, zoomLevel: Int, chunkX: Int, chunkY: Int, - ) : this(buildString { - append("servers/${serverId}") - append("/map/tiles") - append("/s${surfaceIndex}") - append("/z${zoomLevel}") - append("/x${chunkX}") - append("/y${chunkY}") - append(".png") - }) + ) : this( + "servers/${serverId}" + + "/map" + + "/layers/${layer.dir}" + + "/s${surfaceIndex}" + + "/z${zoomLevel}" + + "/x${chunkX}" + + "/y${chunkY}" + + ".png" + ) + } diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt index a9ede2a..54f6d2d 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt @@ -1,83 +1,171 @@ package dev.adamko.kafkatorio.schema.common -import dev.adamko.kxstsgen.core.* +import dev.adamko.kafkatorio.library.leftTopTile +import dev.adamko.kafkatorio.library.rightBottomTile import dev.adamko.kxstsgen.core.experiments.TupleSerializer -import kotlin.math.floor +import kotlin.math.abs +import kotlin.math.ceil import kotlin.math.pow import kotlin.math.roundToInt +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable + /** - * Coordinates of a [EntityData] on a map. + * The position of something that exists in-game (not conceptually, like a + * [chunk][MapChunkPosition]) + */ +sealed interface MapPosition : Comparable { + val x: Number + val y: Number +} + + +/** + * Coordinates of an [entity][FactorioEntityData.Standard] on a map. + * + * Positive y points south, positive x points east. * * A [MapEntityPosition] can be translated to a [MapChunkPosition] by dividing the `x`/`y` values * by [32][MAP_CHUNK_SIZE]. */ -@Serializable(with = MapEntityPosition.Serializer::class) +@Serializable(with = MapEntityPosition.Companion.Serializer::class) data class MapEntityPosition( - val x: Double, - val y: Double, -) { - object Serializer : TupleSerializer( - "MapEntityPosition", - { - element(MapEntityPosition::x) - element(MapEntityPosition::y) + override val x: Double, + override val y: Double, +) : MapPosition { + + + override fun compareTo(other: MapPosition): Int = + when (val resultX = x.compareTo(other.x.toDouble())) { + 0 -> y.compareTo(other.y.toDouble()) + else -> resultX } - ) { - override fun tupleConstructor(elements: Iterator<*>): MapEntityPosition { - return MapEntityPosition( - elements.next() as Double, - elements.next() as Double, - ) + + + companion object { + object Serializer : TupleSerializer( + "MapEntityPosition", + { + element(MapEntityPosition::x) + element(MapEntityPosition::y) + } + ) { + override fun tupleConstructor(elements: Iterator<*>): MapEntityPosition { + return MapEntityPosition( + elements.next() as Double, + elements.next() as Double, + ) + } } } } -/** Coordinates of a chunk in a [SurfaceData] where each integer `x`/`y` represents a different +/** + * Coordinates of a tile on a surface, where each `x`/`y` coordinate represents a different + * [MapTile]. + * + * Positive y points south, positive x points east. + * + * It rounds any `x`/`y` down to whole numbers. + */ +@Serializable(with = MapTilePosition.Companion.Serializer::class) +data class MapTilePosition( + override val x: Int, + override val y: Int, +) : MapPosition { + + + override fun compareTo(other: MapPosition): Int = + when (val resultX = x.compareTo(other.x.toInt())) { + 0 -> y.compareTo(other.y.toInt()) + else -> resultX + } + + + companion object { + object Serializer : TupleSerializer( + "MapTilePosition", + { + element(MapTilePosition::x) + element(MapTilePosition::y) + } + ) { + override fun tupleConstructor(elements: Iterator<*>): MapTilePosition { + val x = requireNotNull(elements.next() as? Int) + val y = requireNotNull(elements.next() as? Int) + return MapTilePosition(x, y) + } + } + } + +} + + +/** + * Coordinates of a chunk on a surface, where each `x`/`y` coordinate represents a different * chunk. * + * Positive y points south, positive x points east. + * * A [MapChunkPosition] can be translated to a [MapEntityPosition] by multiplying the `x`/`y` * values by [32][MAP_CHUNK_SIZE]. */ -@Serializable(with = MapChunkPosition.Serializer::class) +@Serializable(with = MapChunkPosition.Companion.Serializer::class) data class MapChunkPosition( val x: Int, val y: Int, + // Don't set a default for ChunkSize. It could default to 32, but it's clearer to make it explicit + // and avoid accidentally not setting it. Also, a default doesn't save much in serialization size. + val chunkSize: ChunkSize, ) { - object Serializer : TupleSerializer( - "MapChunkPosition", - { - element(MapChunkPosition::x) - element(MapChunkPosition::y) - } - ) { - override fun tupleConstructor(elements: Iterator<*>): MapChunkPosition { - return MapChunkPosition( - elements.next() as Int, - elements.next() as Int, - ) - } - } - private val bounds: MapChunkPositionBounds by lazy { - MapChunkPositionBounds(this, ChunkSize.CHUNK_032) + val bounds: MapChunkPositionBounds by lazy { + MapChunkPositionBounds(this) } operator fun contains(tilePosition: MapTilePosition): Boolean = tilePosition in bounds + operator fun contains(entityPosition: MapEntityPosition): Boolean = entityPosition in bounds + + companion object { + object Serializer : TupleSerializer( + "MapChunkPosition", + { + element(MapChunkPosition::x) + element(MapChunkPosition::y) + element(MapChunkPosition::chunkSize) + } + ) { + override fun tupleConstructor(elements: Iterator<*>): MapChunkPosition { + return MapChunkPosition( + elements.next() as Int, + elements.next() as Int, + elements.next() as ChunkSize, + ) + } + } + } } +/** + * The bounds of a [MapChunkPosition], that may contain a [MapPosition]. + * + * Because Factorio uses screen-coordinates, the lowest `x/y` coordinate is the [leftTop], and + * the highest is [rightBottomTile]. + */ @Serializable data class MapChunkPositionBounds( val leftTop: MapTilePosition, val rightBottom: MapTilePosition, -) : ClosedRange { + val chunkSize: ChunkSize, // should be computable based on the tiles, but include it for completeness +) : ClosedRange { - constructor(chunkPosition: MapChunkPosition, chunkSize: ChunkSize) : this( - chunkPosition.leftTopTile(chunkSize), - chunkPosition.rightBottomTile(chunkSize), + constructor(chunkPosition: MapChunkPosition) : this( + chunkPosition.leftTopTile(), + chunkPosition.rightBottomTile(), + chunkPosition.chunkSize, ) override val start: MapTilePosition @@ -88,117 +176,6 @@ data class MapChunkPositionBounds( } -/** - * Coordinates of a tile in a chunk on a [SurfaceData] where each integer `x`/`y` represents a - * different [MapTile]. - * - * It rounds any `x`/`y` down to whole numbers. - */ -@Serializable(with = MapTilePosition.Serializer::class) -data class MapTilePosition( - val x: Int, - val y: Int, -) : Comparable { - object Serializer : TupleSerializer( - "MapTilePosition", - { - element(MapTilePosition::x) - element(MapTilePosition::y) - } - ) { - override fun tupleConstructor(elements: Iterator<*>): MapTilePosition { - val x = requireNotNull(elements.next() as? Int) - val y = requireNotNull(elements.next() as? Int) - return MapTilePosition(x, y) - } - } - - override operator fun compareTo(other: MapTilePosition): Int = - when { - other.x != x -> x.compareTo(other.x) - else -> y.compareTo(other.y) - } -} - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - -operator fun MapTilePosition.times(factor: Int) = - MapTilePosition(x * factor, y * factor) - -operator fun MapTilePosition.div(divisor: Int) = - MapTilePosition(x / divisor, y / divisor) - -operator fun MapTilePosition.plus(addend: Int) = - MapTilePosition(x + addend, y + addend) - -operator fun MapTilePosition.plus(addend: MapTilePosition) = - MapTilePosition(x + addend.x, y + addend.y) - - -operator fun MapTilePosition.minus(subtrahend: MapTilePosition) = - MapTilePosition(x - subtrahend.x, y - subtrahend.y) - - -fun MapTilePosition.toMapChunkPosition(chunkSize: ChunkSize) = - MapChunkPosition( - floor(x.toDouble() / chunkSize.lengthInTiles.toDouble()).toInt(), - floor(y.toDouble() / chunkSize.lengthInTiles.toDouble()).toInt(), - ) - - -fun MapEntityPosition.toMapTilePosition() = - MapChunkPosition(floor(x).toInt(), floor(y).toInt()) - -fun MapEntityPosition.toMapChunkPosition(chunkSize: ChunkSize) = - MapChunkPosition( - floor(x / chunkSize.lengthInTiles.toDouble()).toInt(), - floor(y / chunkSize.lengthInTiles.toDouble()).toInt(), - ) - - -operator fun MapChunkPosition.times(factor: Int) = - MapChunkPosition(x * factor, y * factor) - -operator fun MapChunkPosition.plus(addend: Int) = - MapChunkPosition(x + addend, y + addend) - -operator fun MapChunkPosition.minus(subtrahend: Int) = - MapChunkPosition(x - subtrahend, y - subtrahend) - - -fun MapChunkPosition.leftTopTile(chunkSize: ChunkSize): MapTilePosition = - MapTilePosition( - x * chunkSize.lengthInTiles, - y * chunkSize.lengthInTiles, - ) - -fun MapChunkPosition.rightBottomTile(chunkSize: ChunkSize): MapTilePosition = - leftTopTile(chunkSize) + (chunkSize.lengthInTiles - 1) - - -fun MapChunkPosition.iterateTiles(chunkSize: ChunkSize): Iterator { - val leftTop = leftTopTile(chunkSize) - val rightBottom = rightBottomTile(chunkSize) - return iterator { - (leftTop.x..rightBottom.x).forEach { x -> - (leftTop.y..rightBottom.y).forEach { y -> - yield(MapTilePosition(x, y)) - } - } - } -} - - -//val MapChunkPosition.rightBottomTile: MapTilePosition -// get() = leftTopTile + (MAP_CHUNK_SIZE - 1) - -// -//val MapChunkPosition.boundingBox: MapBoundingBox -// get() = MapBoundingBox(leftTopTile, rightBottomTile) - - @Serializable enum class ChunkSize( val zoomLevel: Int, @@ -231,3 +208,17 @@ enum class ChunkSize( val STANDARD: ChunkSize = entries.first { it.zoomLevel == 0 } } } + + +@Serializable +@SerialName("kafkatorio.position.MapBoundingBox") +data class MapBoundingBox( + val leftTop: MapEntityPosition, + val rightBottom: MapEntityPosition, +) { + val width: Double get() = abs(leftTop.x - rightBottom.x) + val height: Double get() = abs(leftTop.y - rightBottom.y) + + val tileWidth: Int get() = ceil(width).toInt() + val tileHeight: Int get() = ceil(height).toInt() +} diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/prototypeIds.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/prototypeIds.kt index 4ebb776..be4441a 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/prototypeIds.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/prototypeIds.kt @@ -55,6 +55,15 @@ value class PrototypeId private constructor( } +/** Serialize a [PrototypeId] as an integer - more efficient storage */ +@JvmInline +@Serializable +value class PrototypeHashCode private constructor(val code: Int) { + constructor(id: PrototypeId) : this(id.hashCode()) + constructor(tile: FactorioPrototype) : this(tile.protoId) +} + + //@Suppress("unused") //enum class PrototypeTypeId( // val id: String diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/eventServerPacket.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/eventServerPacket.kt index 363aded..83e7fc0 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/eventServerPacket.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/eventServerPacket.kt @@ -1,7 +1,7 @@ package dev.adamko.kafkatorio.schema.packets import dev.adamko.kafkatorio.schema.common.ServerMapChunkId -import dev.adamko.kafkatorio.schema.common.TilePngFilename +import dev.adamko.kafkatorio.schema.common.ServerMapTilePngFilename import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -21,7 +21,7 @@ sealed class EventServerPacket { @SerialName("kafkatorio.event-server-packet.ChunkTileSaved") data class ChunkTileSaved( val chunkId: ServerMapChunkId, - val filename: TilePngFilename, + val filename: ServerMapTilePngFilename, ) : EventServerPacket() } diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt index b3f2a53..6ef27b2 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt @@ -16,13 +16,12 @@ data class KafkatorioPacket( @Serializable @SerialName("kafkatorio.packet.KafkatorioPacketData") -sealed class KafkatorioPacketData { +sealed class KafkatorioPacketData - @Serializable - @SerialName("kafkatorio.packet.KafkatorioPacketData.Error") - data class Error( - val message: String? = null, - val rawValue: String? = null, - ) : KafkatorioPacketData() -} +@Serializable +@SerialName("kafkatorio.packet.KafkatorioPacketData.Error") +data class KafkatorioPacketDataError( + val message: String? = null, + val rawValue: String? = null, +) : KafkatorioPacketData() diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt index b6af82e..a0ee1b5 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.schema.packets +import dev.adamko.kafkatorio.library.LuaJsonList import dev.adamko.kafkatorio.schema.common.FactorioPrototype import dev.adamko.kafkatorio.schema.common.PlayerIndex import dev.adamko.kafkatorio.schema.common.SurfaceIndex @@ -20,7 +21,8 @@ sealed class KafkatorioInstantPacketData : KafkatorioPacketData() @SerialName("kafkatorio.packet.instant.ConfigurationUpdate") data class ConfigurationUpdate( val factorioData: ConfigurationUpdateGameData, - val allMods: List, +// @Contextual + val allMods: LuaJsonList, val modStartupSettingsChange: Boolean, val migrationApplied: Boolean, ) : KafkatorioInstantPacketData() { @@ -62,7 +64,8 @@ data class ConsoleCommandUpdate( @Serializable @SerialName("kafkatorio.packet.instant.PrototypesUpdate") data class PrototypesUpdate( - val prototypes: List, +// @Contextual + val prototypes: LuaJsonList, ) : KafkatorioInstantPacketData() diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt index 748ac8b..0eb3410 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt @@ -1,10 +1,12 @@ package dev.adamko.kafkatorio.schema.packets +import dev.adamko.kafkatorio.library.LuaJsonList import dev.adamko.kafkatorio.schema.common.Colour import dev.adamko.kafkatorio.schema.common.EntityIdentifiers import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData import dev.adamko.kafkatorio.schema.common.EventName import dev.adamko.kafkatorio.schema.common.FactorioEntityData +import dev.adamko.kafkatorio.schema.common.FactorioEntityUpdateDictionary import dev.adamko.kafkatorio.schema.common.ForceIndex import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapEntityPosition @@ -26,7 +28,7 @@ sealed class KafkatorioKeyedPacketData : KafkatorioPacketData() { /** A list of all events that have been aggregated into this packet. */ // Maybe change to be Map, where Tick is the most recent event? // A complete event timeline isn't necessary. The most recent tick of an event is good enough, and requires less space. - abstract val events: Map>? + abstract val events: Map>? } @@ -52,13 +54,13 @@ data class EntityUpdateKey( data class EntityUpdate( override val key: EntityUpdateKey, - override val events: Map>? = null, + override val events: Map>? = null, val chunkPosition: MapEntityPosition? = null, val graphicsVariation: UByte? = null, val health: Float? = null, - val isActive: Boolean? = null, - val isRotatable: Boolean? = null, + val isActive: Boolean = false, + val isRotatable: Boolean = false, val lastUser: UInt? = null, val localisedDescription: String? = null, val localisedName: String? = null, @@ -82,14 +84,14 @@ data class MapChunkTileUpdateKey( data class MapChunkTileUpdate( override val key: MapChunkTileUpdateKey, - override val events: Map>? = null, + override val events: Map>? = null, val player: PlayerIndex? = null, val robot: EntityIdentifiersData? = null, val force: ForceIndex? = null, /** updated tiles - might be partial and not all tiles in the chunk */ val tileDictionary: MapTileDictionary? = null, - val isDeleted: Boolean? = null, + val isDeleted: Boolean = false, ) : KafkatorioKeyedPacketData() @@ -108,7 +110,7 @@ data class PlayerUpdateKey( data class PlayerUpdate( override val key: PlayerUpdateKey, - override val events: Map>? = null, + override val events: Map>? = null, val characterUnitNumber: UnitNumber? = null, val chatColour: Colour? = null, @@ -118,10 +120,10 @@ data class PlayerUpdate( val afkTime: Tick? = null, val ticksToRespawn: Tick? = null, val forceIndex: ForceIndex? = null, - val isAdmin: Boolean? = null, - val isConnected: Boolean? = null, - val isShowOnMap: Boolean? = null, - val isSpectator: Boolean? = null, + val isAdmin: Boolean = false, + val isConnected: Boolean = false, + val isShowOnMap: Boolean = false, + val isSpectator: Boolean = false, val lastOnline: Tick? = null, val onlineTime: Tick? = null, val position: MapEntityPosition? = null, @@ -149,20 +151,58 @@ data class MapChunkEntityUpdateKey( ) : KafkatorioKeyedPacketKey() -/** - * @property[distinctEntities] Distinct entities. The key is arbitrary and is only used - * for de-duplicating updates. It should only contain data that can be obtained from - * [the value][FactorioEntityData]. - */ @Serializable @SerialName("kafkatorio.packet.keyed.MapChunkEntityUpdate") data class MapChunkEntityUpdate( override val key: MapChunkEntityUpdateKey, - override val events: Map>? = null, + override val events: Map>? = null, - val distinctEntities: Map? = null, -) : KafkatorioKeyedPacketData() + val entitiesXY: FactorioEntityUpdateDictionary.Entity, +) : KafkatorioKeyedPacketData() { + + fun entities(): List = + entitiesXY.map { (position, entity) -> + FactorioEntityData.Standard( + protoId = key.protoId, + position = position, + element = entity, + ) + } +} + + +/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ + + +@Serializable +@SerialName("kafkatorio.packet.keyed.MapChunkResourceUpdateKey") +data class MapChunkResourceUpdateKey( + val protoId: PrototypeId, + val surfaceIndex: SurfaceIndex, + val chunkPosition: MapChunkPosition, +) : KafkatorioKeyedPacketKey() + + +@Serializable +@SerialName("kafkatorio.packet.keyed.MapChunkResourceUpdate") +data class MapChunkResourceUpdate( + override val key: MapChunkResourceUpdateKey, + + override val events: Map>? = null, + + val resourcesXY: FactorioEntityUpdateDictionary.Resource, +) : KafkatorioKeyedPacketData() { + + fun resources(): List = + resourcesXY.map { (position, resource) -> + FactorioEntityData.Resource( + protoId = key.protoId, + position = position, + element = resource, + ) + } +} /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/ColourHexTest.kt similarity index 89% rename from modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt rename to modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/ColourHexTest.kt index 3279283..2fbf0d3 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/ColourHexTest.kt @@ -1,10 +1,6 @@ -package dev.adamko.kafkatorio.events.schema +package dev.adamko.kafkatorio.schema.common import dev.adamko.kafkatorio.library.jsonMapperKafkatorio -import dev.adamko.kafkatorio.schema.common.Colour -import dev.adamko.kafkatorio.schema.common.ColourHex -import dev.adamko.kafkatorio.schema.common.toHex -import dev.adamko.kafkatorio.schema.common.toPercentile import io.kotest.assertions.withClue import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.floats.shouldBeWithinPercentageOf diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt index 0e543a6..040d4c1 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt @@ -2,10 +2,12 @@ package dev.adamko.kafkatorio.schema.common import dev.adamko.kafkatorio.library.kxsBinary import io.kotest.assertions.asClue +import io.kotest.assertions.withClue import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.collections.shouldContainExactly import io.kotest.matchers.ints.shouldBeExactly import io.kotest.matchers.maps.shouldContainExactly +import io.kotest.matchers.shouldBe import kotlinx.serialization.decodeFromByteArray import kotlinx.serialization.encodeToByteArray @@ -17,18 +19,17 @@ class MapChunkPositionBoundsTest : FunSpec({ context("chunk size 32") { - val chunkPos = MapChunkPosition(0, 0) - val bounds = MapChunkPositionBounds(chunkPos, ChunkSize.CHUNK_032) + val chunkPos = MapChunkPosition(0, 0, ChunkSize.CHUNK_032) test("leftTop should be 0,0") { - bounds.leftTop.asClue { + chunkPos.bounds.leftTop.asClue { it.x shouldBeExactly 0 it.y shouldBeExactly 0 } } test("rightBottom should be 31,31") { - bounds.rightBottom.asClue { + chunkPos.bounds.rightBottom.asClue { it.x shouldBeExactly 31 it.y shouldBeExactly 31 } @@ -38,18 +39,17 @@ class MapChunkPositionBoundsTest : FunSpec({ context("chunk size 256") { - val chunkPos = MapChunkPosition(0, 0) - val bounds = MapChunkPositionBounds(chunkPos, ChunkSize.CHUNK_256) + val chunkPos = MapChunkPosition(0, 0, ChunkSize.CHUNK_256) test("leftTop should be 0,0") { - bounds.leftTop.asClue { + chunkPos.bounds.leftTop.asClue { it.x shouldBeExactly 0 it.y shouldBeExactly 0 } } test("rightBottom should be 255,255") { - bounds.rightBottom.asClue { + chunkPos.bounds.rightBottom.asClue { it.x shouldBeExactly 255 it.y shouldBeExactly 255 } @@ -61,18 +61,17 @@ class MapChunkPositionBoundsTest : FunSpec({ context("chunk size 32") { - val chunkPos = MapChunkPosition(-10, -10) - val bounds = MapChunkPositionBounds(chunkPos, ChunkSize.CHUNK_032) + val chunkPos = MapChunkPosition(-10, -10, ChunkSize.CHUNK_032) test("leftTop should be -320,-320") { - bounds.leftTop.asClue { + chunkPos.bounds.leftTop.asClue { it.x shouldBeExactly -320 it.y shouldBeExactly -320 } } test("rightBottom should be -289,-289") { - bounds.rightBottom.asClue { + chunkPos.bounds.rightBottom.asClue { it.x shouldBeExactly -289 it.y shouldBeExactly -289 } @@ -81,18 +80,17 @@ class MapChunkPositionBoundsTest : FunSpec({ context("chunk size 256") { - val chunkPos = MapChunkPosition(-10, -10) - val bounds = MapChunkPositionBounds(chunkPos, ChunkSize.CHUNK_256) + val chunkPos = MapChunkPosition(-10, -10, ChunkSize.CHUNK_256) test("leftTop should be -2560") { - bounds.leftTop.asClue { + chunkPos.bounds.leftTop.asClue { it.x shouldBeExactly -2560 it.y shouldBeExactly -2560 } } test("rightBottom should be (-2560 + 255)") { - bounds.rightBottom.asClue { + chunkPos.bounds.rightBottom.asClue { it.x shouldBeExactly (-2560 + 255) it.y shouldBeExactly (-2560 + 255) } @@ -134,4 +132,57 @@ class MapChunkPositionBoundsTest : FunSpec({ decoded.toMapTileList() shouldContainExactly actual.toMapTileList() } } + + context("verify map chunk 'contains'") { + + context("MapChunkPosition(1, 1)") { + + val chunkPos = MapChunkPosition(1, 1, ChunkSize.CHUNK_032) // from 32,32 to 63,63 + + test("tile outside of chunk") { + val outerTilePos = MapTilePosition(1, 1) + + withClue("$outerTilePos in ${chunkPos.bounds}") { + (outerTilePos in chunkPos) shouldBe false + } + } + + test("tile inside of chunk") { + val innerTilePos = MapTilePosition(34, 33) + + withClue("$innerTilePos in ${chunkPos.bounds}") { + (innerTilePos in chunkPos) shouldBe true + } + } + + test("entity outside of chunk") { + val outerEntityPos = MapEntityPosition(1.0, 1.0) + + withClue("$outerEntityPos in ${chunkPos.bounds}") { + (outerEntityPos !in chunkPos) shouldBe true + (outerEntityPos in chunkPos) shouldBe false + } + } + + test("entity inside of chunk") { + val innerEntityPos = MapEntityPosition(34.0, 33.0) + + withClue("$innerEntityPos in ${chunkPos.bounds}") { + (innerEntityPos !in chunkPos) shouldBe false + (innerEntityPos in chunkPos) shouldBe true + } + } + } + context(" MapChunkPosition(9, -5)") { + val chunkPos2 = MapChunkPosition(9, -5, ChunkSize.CHUNK_032) + + test("tile inside of chunk") { + val innerTilePos = MapTilePosition(288, -160) + + withClue("$innerTilePos in ${chunkPos2.bounds}") { + (innerTilePos in chunkPos2) shouldBe true + } + } + } + } }) diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionTest.kt index 99cfdc7..b72f45c 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionTest.kt @@ -14,7 +14,7 @@ class MapChunkPositionTest : FunSpec({ context("MapChunkPosition(0, 0)") { - val chunkPos = MapChunkPosition(0, 0) + val chunkPos = MapChunkPosition(0, 0, ChunkSize.CHUNK_032) test("should contain tiles from (0,0) to (31,31)") { checkAll(mapTilePositionArb(0..31)) { tilePos -> @@ -40,7 +40,7 @@ class MapChunkPositionTest : FunSpec({ } context("MapChunkPosition(-10, -10)") { - val chunkPos = MapChunkPosition(-10, -10) + val chunkPos = MapChunkPosition(-10, -10, ChunkSize.CHUNK_032) test("should contain tiles from (-320,-320) to (-289,-289)") { checkAll(mapTilePositionArb(-320..-289)) { tilePos -> diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTilePositionTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTilePositionTest.kt index 15dfddc..b5756e7 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTilePositionTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTilePositionTest.kt @@ -1,5 +1,7 @@ package dev.adamko.kafkatorio.schema.common +import dev.adamko.kafkatorio.library.minus +import dev.adamko.kafkatorio.library.plus import dev.adamko.kafkatorio.schema.common.MapChunkPositionTest.Companion.mapTilePositionArb import io.kotest.core.spec.style.FunSpec import io.kotest.property.forAll @@ -17,15 +19,27 @@ class MapTilePositionTest : FunSpec({ } } - test("less than or equal to <=") { + test("equal comparing to ==") { forAll(mapTilePositionArb()) { tilePos -> - tilePos <= (tilePos) + tilePos.compareTo(tilePos) == 0 + } + } + + test("less than or equal to <=") { + forAll( + mapTilePositionArb(), + mapTilePositionArb(0..1), + ) { tilePos, delta -> + tilePos <= (tilePos + delta) } } test("greater than or equal to >=") { - forAll(mapTilePositionArb()) { tilePos -> - tilePos >= (tilePos) + forAll( + mapTilePositionArb(), + mapTilePositionArb(0..1), + ) { tilePos, delta -> + tilePos >= (tilePos - delta) } } @@ -37,7 +51,5 @@ class MapTilePositionTest : FunSpec({ tilePos > (tilePos - delta) } } - } - }) diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/PrototypesTest.kt similarity index 99% rename from modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt rename to modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/PrototypesTest.kt index 922362e..37ed7eb 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/PrototypesTest.kt @@ -1,9 +1,6 @@ -package dev.adamko.kafkatorio.events.schema +package dev.adamko.kafkatorio.schema.common import dev.adamko.kafkatorio.library.jsonMapperKafkatorio -import dev.adamko.kafkatorio.schema.common.Colour -import dev.adamko.kafkatorio.schema.common.FactorioPrototype -import dev.adamko.kafkatorio.schema.common.PrototypeId import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import io.kotest.core.spec.style.BehaviorSpec diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/MapChunkTileUpdateTest.kt similarity index 84% rename from modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt rename to modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/MapChunkTileUpdateTest.kt index 13b69ff..fa209b7 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/MapChunkTileUpdateTest.kt @@ -1,22 +1,21 @@ -package dev.adamko.kafkatorio.events.schema +package dev.adamko.kafkatorio.schema.packets +import dev.adamko.kafkatorio.library.LuaJsonList import dev.adamko.kafkatorio.library.jsonMapperKafkatorio +import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.EventName import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapTileDictionary import dev.adamko.kafkatorio.schema.common.PrototypeId import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.tick -import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket -import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate -import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdateKey import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import kotlinx.serialization.decodeFromString -class MapChunkUpdateTest : FunSpec({ +class MapChunkTileUpdateTest : FunSpec({ - context("MapChunkUpdate update") { + context("MapChunkTileUpdate update") { //language=json val json = """ { @@ -26,7 +25,8 @@ class MapChunkUpdateTest : FunSpec({ "surfaceIndex": 1, "chunkPosition": [ -6, - -3 + -3, + "CHUNK_032" ] }, "tileDictionary": { @@ -61,11 +61,11 @@ class MapChunkUpdateTest : FunSpec({ modVersion = "0.4.0", data = MapChunkTileUpdate( key = MapChunkTileUpdateKey( - MapChunkPosition(-6, -3), + MapChunkPosition(-6, -3, ChunkSize.CHUNK_032), SurfaceIndex(1u), ), events = mapOf( - EventName("on_chunk_generated") to listOf(1u.tick) + EventName("on_chunk_generated") to LuaJsonList(listOf(1u.tick)) ), tileDictionary = MapTileDictionary( tilesXY = mapOf( diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/UpdatePacketsTest.kt similarity index 93% rename from modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt rename to modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/UpdatePacketsTest.kt index 605874e..81c8144 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/UpdatePacketsTest.kt @@ -1,5 +1,6 @@ -package dev.adamko.kafkatorio.events.schema +package dev.adamko.kafkatorio.schema.packets +import dev.adamko.kafkatorio.library.LuaJsonList import dev.adamko.kafkatorio.library.jsonMapperKafkatorio import dev.adamko.kafkatorio.schema.common.Colour import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData @@ -12,15 +13,12 @@ import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.common.UnitNumber import dev.adamko.kafkatorio.schema.common.tick -import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket -import dev.adamko.kafkatorio.schema.packets.PlayerUpdate -import dev.adamko.kafkatorio.schema.packets.PlayerUpdateKey -import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString + class UpdatePacketsTest : FunSpec({ context("player update packet") { @@ -72,8 +70,8 @@ class UpdatePacketsTest : FunSpec({ diedCause = null, disconnectReason = null, events = mapOf( - EventName("on_player_changed_position") to listOf(7u.tick, 99u.tick), - EventName("on_player_joined_game") to listOf(14u.tick), + EventName("on_player_changed_position") to LuaJsonList(listOf(7u.tick, 99u.tick)), + EventName("on_player_joined_game") to LuaJsonList(listOf(14u.tick)), ), forceIndex = ForceIndex(1u), isAdmin = true, @@ -194,7 +192,7 @@ class UpdatePacketsTest : FunSpec({ ), disconnectReason = null, events = mapOf( - EventName("on_player_died") to listOf(2u.tick), + EventName("on_player_died") to LuaJsonList(listOf(2u.tick)), ), forceIndex = null, key = PlayerUpdateKey(PlayerIndex(1u)), diff --git a/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt b/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/schema/kt2ts2.kt similarity index 92% rename from modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt rename to modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/schema/kt2ts2.kt index 69be148..6a095a4 100644 --- a/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt +++ b/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/schema/kt2ts2.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.events.schema +package dev.adamko.kafkatorio.schema import dev.adamko.kafkatorio.schema.common.PlayerIndex import dev.adamko.kafkatorio.schema.common.SurfaceIndex @@ -85,13 +85,21 @@ class MySourceCodeGenerator( config: KxsTsConfig, ) : TsSourceCodeGenerator.Default(config) { + private val seenTypeAliases: MutableSet = mutableSetOf() + override fun generateTypeAlias(element: TsTypeAlias): String { + if (!seenTypeAliases.add(element.id)) { + return "" + } + return if (element.id.name in listOf("PlayerIndex", "SurfaceIndex", "UnitNumber")) { "" } else if ( (element.typeRef as? TsTypeRef.Literal)?.element is TsLiteral.Custom || element.id.name == "Tick" + || element.id.name == "FactorioEntityUpdateEntityDictionary" + || element.id.name == "FactorioEntityUpdateResourceDictionary" ) { val aliasedRef = generateTypeReference(element.typeRef) """ diff --git a/modules/events-library/src/jvmTest/kotlin/dev/adamko/kafkatorio/library/KxsBinaryTests.kt b/modules/events-library/src/jvmTest/kotlin/dev/adamko/kafkatorio/library/KxsBinaryTests.kt index 541f243..c7a00ac 100644 --- a/modules/events-library/src/jvmTest/kotlin/dev/adamko/kafkatorio/library/KxsBinaryTests.kt +++ b/modules/events-library/src/jvmTest/kotlin/dev/adamko/kafkatorio/library/KxsBinaryTests.kt @@ -1,11 +1,12 @@ package dev.adamko.kafkatorio.library -import dev.adamko.kafkatorio.schema.common.ServerMapChunkId import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapTilePosition +import dev.adamko.kafkatorio.schema.common.ServerMapChunkId +import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer import dev.adamko.kafkatorio.schema.common.SurfaceIndex import io.kotest.assertions.withClue import io.kotest.core.spec.style.FunSpec @@ -51,7 +52,7 @@ class KxsBinaryTests : FunSpec({ test("byte array") { val ba = byteArrayOf( - 4, 116, 101, 115, 116, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 3 + 4, 116, 101, 115, 116, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 1 ) val result = kxsBinary.decodeFromByteArray(ServerMapChunkId.serializer(), ba) @@ -60,9 +61,9 @@ class KxsBinaryTests : FunSpec({ result shouldBeEqualToComparingFields ServerMapChunkId( serverId = FactorioServerId("test"), - chunkPosition = MapChunkPosition(1, 2), + layer = ServerMapTileLayer.TERRAIN, + chunkPosition = MapChunkPosition(1, 2, ChunkSize.CHUNK_064), surfaceIndex = SurfaceIndex(1u), - chunkSize = ChunkSize.CHUNK_064, ) } @@ -72,15 +73,15 @@ class KxsBinaryTests : FunSpec({ val ba = kxsBinary.encodeToByteArray( ServerMapChunkId( serverId = FactorioServerId("test"), - chunkPosition = MapChunkPosition(1, 2), + layer = ServerMapTileLayer.TERRAIN, + chunkPosition = MapChunkPosition(1, 2, ChunkSize.CHUNK_064), surfaceIndex = SurfaceIndex(1u), - chunkSize = ChunkSize.CHUNK_064, ) ) withClue(ba.toString(Charsets.UTF_8)) { ba shouldBe byteArrayOf( - 4, 116, 101, 115, 116, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 3 + 4, 116, 101, 115, 116, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 1 ) } } @@ -112,10 +113,10 @@ class KxsBinaryTests : FunSpec({ context("ServerMapChunkTiles") { val initial = ServerMapChunkTiles( ServerMapChunkId( - FactorioServerId("server-id"), - MapChunkPosition(33, 44), - SurfaceIndex(4u), - ChunkSize.CHUNK_032, + serverId = FactorioServerId("server-id"), + layer = ServerMapTileLayer.TERRAIN, + chunkPosition = MapChunkPosition(33, 44, ChunkSize.CHUNK_032), + surfaceIndex = SurfaceIndex(4u), ), mapOf( MapTilePosition(1, 2) to ColourHex(1u, 2u, 3u, 4u), diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 6953c71..206b8d8 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -68,7 +68,11 @@ dependencies { val typescriptToLua by tasks.registering(TypescriptToLuaTask::class) { - dependsOn(tasks.npmInstall, installEventsTsSchema, tasks.updatePackageJson) + dependsOn( + tasks.npmInstall, + installEventsTsSchema, + tasks.updatePackageJson, + ) inputs.file(tasks.updatePackageJson.map { it.packageJsonFile }) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 82b0c61..8337468 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -85,9 +85,9 @@ "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" }, "typescript-to-lua": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.6.2.tgz", - "integrity": "sha512-m0TZ2RqL6BPy3/TNIjbVDTr9N6M45Qyb2/VJpBz0qnS3zTXxhAOugc+PaILSVwvCb1vent8ateWDt2fcEtcsRw==", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.6.3.tgz", + "integrity": "sha512-yfXxGjOwX6453wSgEB37lLdxZZ8m+LH1g3PfebNfKaZHGGtbm9owxE6oRKB3sWcy2CICkfobAjWf3VdhKnEETg==", "requires": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 83e563c..6a5d159 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -12,7 +12,7 @@ "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", - "typescript-to-lua": "1.6.2", + "typescript-to-lua": "1.6.3", "typed-factorio": "1.3.2", "typescript": "4.7.4" }, diff --git a/modules/events-mod/src/generated/lua/generated/kafkatorio-schema.lua b/modules/events-mod/src/generated/lua/generated/kafkatorio-schema.lua index 46a4058..dba2989 100644 --- a/modules/events-mod/src/generated/lua/generated/kafkatorio-schema.lua +++ b/modules/events-mod/src/generated/lua/generated/kafkatorio-schema.lua @@ -10,6 +10,7 @@ do KafkatorioPacketData.Type.SurfaceUpdate = "kafkatorio.packet.instant.SurfaceUpdate" KafkatorioPacketData.Type.EntityUpdate = "kafkatorio.packet.keyed.EntityUpdate" KafkatorioPacketData.Type.MapChunkEntityUpdate = "kafkatorio.packet.keyed.MapChunkEntityUpdate" + KafkatorioPacketData.Type.MapChunkResourceUpdate = "kafkatorio.packet.keyed.MapChunkResourceUpdate" KafkatorioPacketData.Type.MapChunkTileUpdate = "kafkatorio.packet.keyed.MapChunkTileUpdate" KafkatorioPacketData.Type.PlayerUpdate = "kafkatorio.packet.keyed.PlayerUpdate" KafkatorioPacketData.Type.Error = "kafkatorio.packet.KafkatorioPacketData.Error" @@ -21,57 +22,12 @@ do FactorioPrototype.Type.Entity = "kafkatorio.prototype.Entity" FactorioPrototype.Type.MapTile = "kafkatorio.prototype.MapTile" end -____exports.FactorioEntityData = {} -local FactorioEntityData = ____exports.FactorioEntityData -do - FactorioEntityData.Type = Type or ({}) - FactorioEntityData.Type.Resource = "kafkatorio.entity.FactorioEntityData.Resource" - FactorioEntityData.Type.Standard = "kafkatorio.entity.FactorioEntityData.Standard" -end -____exports.EntityStatus = EntityStatus or ({}) -____exports.EntityStatus.CANT_DIVIDE_SEGMENTS = "CANT_DIVIDE_SEGMENTS" -____exports.EntityStatus.CHARGING = "CHARGING" -____exports.EntityStatus.CLOSED_BY_CIRCUIT_NETWORK = "CLOSED_BY_CIRCUIT_NETWORK" -____exports.EntityStatus.DISABLED = "DISABLED" -____exports.EntityStatus.DISABLED_BY_CONTROL_BEHAVIOR = "DISABLED_BY_CONTROL_BEHAVIOR" -____exports.EntityStatus.DISABLED_BY_SCRIPT = "DISABLED_BY_SCRIPT" -____exports.EntityStatus.DISCHARGING = "DISCHARGING" -____exports.EntityStatus.FLUID_INGREDIENT_SHORTAGE = "FLUID_INGREDIENT_SHORTAGE" -____exports.EntityStatus.FULLY_CHARGED = "FULLY_CHARGED" -____exports.EntityStatus.FULL_OUTPUT = "FULL_OUTPUT" -____exports.EntityStatus.ITEM_INGREDIENT_SHORTAGE = "ITEM_INGREDIENT_SHORTAGE" -____exports.EntityStatus.LAUNCHING_ROCKET = "LAUNCHING_ROCKET" -____exports.EntityStatus.LOW_INPUT_FLUID = "LOW_INPUT_FLUID" -____exports.EntityStatus.LOW_POWER = "LOW_POWER" -____exports.EntityStatus.LOW_TEMPERATURE = "LOW_TEMPERATURE" -____exports.EntityStatus.MARKED_FOR_DECONSTRUCTION = "MARKED_FOR_DECONSTRUCTION" -____exports.EntityStatus.MISSING_REQUIRED_FLUID = "MISSING_REQUIRED_FLUID" -____exports.EntityStatus.MISSING_SCIENCE_PACKS = "MISSING_SCIENCE_PACKS" -____exports.EntityStatus.NETWORKS_CONNECTED = "NETWORKS_CONNECTED" -____exports.EntityStatus.NETWORKS_DISCONNECTED = "NETWORKS_DISCONNECTED" -____exports.EntityStatus.NORMAL = "NORMAL" -____exports.EntityStatus.NOT_CONNECTED_TO_RAIL = "NOT_CONNECTED_TO_RAIL" -____exports.EntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK = "NOT_PLUGGED_IN_ELECTRIC_NETWORK" -____exports.EntityStatus.NO_AMMO = "NO_AMMO" -____exports.EntityStatus.NO_FUEL = "NO_FUEL" -____exports.EntityStatus.NO_INGREDIENTS = "NO_INGREDIENTS" -____exports.EntityStatus.NO_INPUT_FLUID = "NO_INPUT_FLUID" -____exports.EntityStatus.NO_MINABLE_RESOURCES = "NO_MINABLE_RESOURCES" -____exports.EntityStatus.NO_MODULES_TO_TRANSMIT = "NO_MODULES_TO_TRANSMIT" -____exports.EntityStatus.NO_POWER = "NO_POWER" -____exports.EntityStatus.NO_RECIPE = "NO_RECIPE" -____exports.EntityStatus.NO_RESEARCH_IN_PROGRESS = "NO_RESEARCH_IN_PROGRESS" -____exports.EntityStatus.OPENED_BY_CIRCUIT_NETWORK = "OPENED_BY_CIRCUIT_NETWORK" -____exports.EntityStatus.OUT_OF_LOGISTIC_NETWORK = "OUT_OF_LOGISTIC_NETWORK" -____exports.EntityStatus.PREPARING_ROCKET_FOR_LAUNCH = "PREPARING_ROCKET_FOR_LAUNCH" -____exports.EntityStatus.RECHARGING_AFTER_POWER_OUTAGE = "RECHARGING_AFTER_POWER_OUTAGE" -____exports.EntityStatus.TURNED_OFF_DURING_DAYTIME = "TURNED_OFF_DURING_DAYTIME" -____exports.EntityStatus.WAITING_FOR_SOURCE_ITEMS = "WAITING_FOR_SOURCE_ITEMS" -____exports.EntityStatus.WAITING_FOR_SPACE_IN_DESTINATION = "WAITING_FOR_SPACE_IN_DESTINATION" -____exports.EntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT = "WAITING_FOR_TARGET_TO_BE_BUILT" -____exports.EntityStatus.WAITING_FOR_TRAIN = "WAITING_FOR_TRAIN" -____exports.EntityStatus.WAITING_TO_LAUNCH_ROCKET = "WAITING_TO_LAUNCH_ROCKET" -____exports.EntityStatus.WORKING = "WORKING" +____exports.ChunkSize = ChunkSize or ({}) +____exports.ChunkSize.CHUNK_512 = "CHUNK_512" +____exports.ChunkSize.CHUNK_256 = "CHUNK_256" +____exports.ChunkSize.CHUNK_128 = "CHUNK_128" +____exports.ChunkSize.CHUNK_064 = "CHUNK_064" +____exports.ChunkSize.CHUNK_032 = "CHUNK_032" ____exports.MinedProduct = {} local MinedProduct = ____exports.MinedProduct do @@ -79,4 +35,48 @@ do MinedProduct.Type.MinedProductFluid = "kafkatorio.resource.MinedProduct.MinedProductFluid" MinedProduct.Type.MinedProductItem = "kafkatorio.resource.MinedProduct.MinedProductItem" end +____exports.FactorioEntityStatus = FactorioEntityStatus or ({}) +____exports.FactorioEntityStatus.WORKING = "WORKING" +____exports.FactorioEntityStatus.NORMAL = "NORMAL" +____exports.FactorioEntityStatus.NO_POWER = "NO_POWER" +____exports.FactorioEntityStatus.LOW_POWER = "LOW_POWER" +____exports.FactorioEntityStatus.NO_FUEL = "NO_FUEL" +____exports.FactorioEntityStatus.DISABLED_BY_CONTROL_BEHAVIOR = "DISABLED_BY_CONTROL_BEHAVIOR" +____exports.FactorioEntityStatus.OPENED_BY_CIRCUIT_NETWORK = "OPENED_BY_CIRCUIT_NETWORK" +____exports.FactorioEntityStatus.CLOSED_BY_CIRCUIT_NETWORK = "CLOSED_BY_CIRCUIT_NETWORK" +____exports.FactorioEntityStatus.DISABLED_BY_SCRIPT = "DISABLED_BY_SCRIPT" +____exports.FactorioEntityStatus.MARKED_FOR_DECONSTRUCTION = "MARKED_FOR_DECONSTRUCTION" +____exports.FactorioEntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK = "NOT_PLUGGED_IN_ELECTRIC_NETWORK" +____exports.FactorioEntityStatus.NETWORKS_CONNECTED = "NETWORKS_CONNECTED" +____exports.FactorioEntityStatus.NETWORKS_DISCONNECTED = "NETWORKS_DISCONNECTED" +____exports.FactorioEntityStatus.CHARGING = "CHARGING" +____exports.FactorioEntityStatus.DISCHARGING = "DISCHARGING" +____exports.FactorioEntityStatus.FULLY_CHARGED = "FULLY_CHARGED" +____exports.FactorioEntityStatus.OUT_OF_LOGISTIC_NETWORK = "OUT_OF_LOGISTIC_NETWORK" +____exports.FactorioEntityStatus.NO_RECIPE = "NO_RECIPE" +____exports.FactorioEntityStatus.NO_INGREDIENTS = "NO_INGREDIENTS" +____exports.FactorioEntityStatus.NO_INPUT_FLUID = "NO_INPUT_FLUID" +____exports.FactorioEntityStatus.NO_RESEARCH_IN_PROGRESS = "NO_RESEARCH_IN_PROGRESS" +____exports.FactorioEntityStatus.NO_MINABLE_RESOURCES = "NO_MINABLE_RESOURCES" +____exports.FactorioEntityStatus.LOW_INPUT_FLUID = "LOW_INPUT_FLUID" +____exports.FactorioEntityStatus.FLUID_INGREDIENT_SHORTAGE = "FLUID_INGREDIENT_SHORTAGE" +____exports.FactorioEntityStatus.FULL_OUTPUT = "FULL_OUTPUT" +____exports.FactorioEntityStatus.ITEM_INGREDIENT_SHORTAGE = "ITEM_INGREDIENT_SHORTAGE" +____exports.FactorioEntityStatus.MISSING_REQUIRED_FLUID = "MISSING_REQUIRED_FLUID" +____exports.FactorioEntityStatus.MISSING_SCIENCE_PACKS = "MISSING_SCIENCE_PACKS" +____exports.FactorioEntityStatus.WAITING_FOR_SOURCE_ITEMS = "WAITING_FOR_SOURCE_ITEMS" +____exports.FactorioEntityStatus.WAITING_FOR_SPACE_IN_DESTINATION = "WAITING_FOR_SPACE_IN_DESTINATION" +____exports.FactorioEntityStatus.PREPARING_ROCKET_FOR_LAUNCH = "PREPARING_ROCKET_FOR_LAUNCH" +____exports.FactorioEntityStatus.WAITING_TO_LAUNCH_ROCKET = "WAITING_TO_LAUNCH_ROCKET" +____exports.FactorioEntityStatus.LAUNCHING_ROCKET = "LAUNCHING_ROCKET" +____exports.FactorioEntityStatus.NO_MODULES_TO_TRANSMIT = "NO_MODULES_TO_TRANSMIT" +____exports.FactorioEntityStatus.RECHARGING_AFTER_POWER_OUTAGE = "RECHARGING_AFTER_POWER_OUTAGE" +____exports.FactorioEntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT = "WAITING_FOR_TARGET_TO_BE_BUILT" +____exports.FactorioEntityStatus.WAITING_FOR_TRAIN = "WAITING_FOR_TRAIN" +____exports.FactorioEntityStatus.NO_AMMO = "NO_AMMO" +____exports.FactorioEntityStatus.LOW_TEMPERATURE = "LOW_TEMPERATURE" +____exports.FactorioEntityStatus.DISABLED = "DISABLED" +____exports.FactorioEntityStatus.TURNED_OFF_DURING_DAYTIME = "TURNED_OFF_DURING_DAYTIME" +____exports.FactorioEntityStatus.NOT_CONNECTED_TO_RAIL = "NOT_CONNECTED_TO_RAIL" +____exports.FactorioEntityStatus.CANT_DIVIDE_SEGMENTS = "CANT_DIVIDE_SEGMENTS" return ____exports diff --git a/modules/events-mod/src/generated/lua/main/commands/kafkatorioCommands.lua b/modules/events-mod/src/generated/lua/main/commands/kafkatorioCommands.lua index 48f6c25..2608d96 100644 --- a/modules/events-mod/src/generated/lua/main/commands/kafkatorioCommands.lua +++ b/modules/events-mod/src/generated/lua/main/commands/kafkatorioCommands.lua @@ -7,8 +7,8 @@ local ____global_2Dinit = require("main.global-init") local initGlobal = ____global_2Dinit.initGlobal local ____prototypeUpdates = require("main.events.prototypeUpdates") local emitPrototypes = ____prototypeUpdates.emitPrototypes -local ____queue = require("main.queue.queue") -local EventDataQueue = ____queue.default +local ____EventDataQueue = require("main.emitting.EventDataQueue") +local EventDataQueue = ____EventDataQueue.default commands.add_command( "kafkatorio", "kafkatorio innit bruv", diff --git a/modules/events-mod/src/generated/lua/main/queue/queue.lua b/modules/events-mod/src/generated/lua/main/emitting/EventDataQueue.lua similarity index 100% rename from modules/events-mod/src/generated/lua/main/queue/queue.lua rename to modules/events-mod/src/generated/lua/main/emitting/EventDataQueue.lua diff --git a/modules/events-mod/src/generated/lua/main/emitting/KafkatorioPacketQueue.lua b/modules/events-mod/src/generated/lua/main/emitting/KafkatorioPacketQueue.lua index a64395e..972b662 100644 --- a/modules/events-mod/src/generated/lua/main/emitting/KafkatorioPacketQueue.lua +++ b/modules/events-mod/src/generated/lua/main/emitting/KafkatorioPacketQueue.lua @@ -3,6 +3,10 @@ local __TS__Class = ____lualib.__TS__Class local __TS__SetDescriptor = ____lualib.__TS__SetDescriptor local __TS__New = ____lualib.__TS__New local ____exports = {} +--- Simple ordered queue for {@link KafkatorioPacketData}. +-- +-- Implemented so printing multiple packets won't flood the output log, causing messages to be +-- missed or garbled. ____exports.KafkatorioPacketQueueManager = __TS__Class() local KafkatorioPacketQueueManager = ____exports.KafkatorioPacketQueueManager KafkatorioPacketQueueManager.name = "KafkatorioPacketQueueManager" diff --git a/modules/events-mod/src/generated/lua/main/events/converters.lua b/modules/events-mod/src/generated/lua/main/events/converters.lua index 8020aaa..3b3e727 100644 --- a/modules/events-mod/src/generated/lua/main/events/converters.lua +++ b/modules/events-mod/src/generated/lua/main/events/converters.lua @@ -1,19 +1,12 @@ local ____exports = {} local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") -local EntityStatus = ____kafkatorio_2Dschema.EntityStatus -local FactorioEntityData = ____kafkatorio_2Dschema.FactorioEntityData +local ChunkSize = ____kafkatorio_2Dschema.ChunkSize +local FactorioEntityStatus = ____kafkatorio_2Dschema.FactorioEntityStatus local MinedProduct = ____kafkatorio_2Dschema.MinedProduct ____exports.Converters = {} local Converters = ____exports.Converters do - local convertEntityStatus, EntityStatusRecord - function convertEntityStatus(status) - if status == nil then - return nil - else - return EntityStatusRecord[status] - end - end + local EntityStatusRecord function Converters.prototypeId(____type, name) return (____type .. "/") .. name end @@ -42,9 +35,6 @@ do end return converted end - function Converters.convertMapTablePosition(position) - return {position.x, position.y} - end function Converters.convertCollisionMaskToNames(cm) local masks = {} for name in pairs(cm) do @@ -56,14 +46,14 @@ do if entity.type ~= "resource" then return nil else - return { - type = FactorioEntityData.Type.Resource, - protoId = Converters.prototypeId(entity.type, entity.name), - status = convertEntityStatus(entity.status), - amount = entity.amount, - initialAmount = entity.initial_amount, - position = Converters.convertMapTablePosition(entity.position) - } + return {amount = entity.amount, initialAmount = entity.initial_amount} + end + end + local function convertEntityStatus(status) + if status == nil then + return nil + else + return EntityStatusRecord[status] end end function Converters.prototypeIdEntity(entity) @@ -72,15 +62,23 @@ do function Converters.tilePositionToChunkPosition(mapPosition) return { floor(mapPosition.x / 32), - floor(mapPosition.y) + floor(mapPosition.y / 32), + ChunkSize.CHUNK_032 } end function Converters.mapPositionToChunkPosition(mapPosition) return { floor(mapPosition.x / 32), - floor(mapPosition.y) + floor(mapPosition.y / 32), + ChunkSize.CHUNK_032 } end + function Converters.entityPosition(position) + return {position.x, position.y} + end + function Converters.chunkPosition(position) + return {position.x, position.y, ChunkSize.CHUNK_032} + end function Converters.entityStatus(status) if status == nil then return nil @@ -116,50 +114,56 @@ do data.afkTime = player.afk_time data.isConnected = player.connected end + function Converters.collisionBox(collision_box) + return { + leftTop = ____exports.Converters.entityPosition(collision_box.left_top), + rightBottom = ____exports.Converters.entityPosition(collision_box.right_bottom) + } + end EntityStatusRecord = { - [defines.entity_status.cant_divide_segments] = EntityStatus.CANT_DIVIDE_SEGMENTS, - [defines.entity_status.charging] = EntityStatus.CHARGING, - [defines.entity_status.closed_by_circuit_network] = EntityStatus.CLOSED_BY_CIRCUIT_NETWORK, - [defines.entity_status.disabled] = EntityStatus.DISABLED, - [defines.entity_status.disabled_by_control_behavior] = EntityStatus.DISABLED_BY_CONTROL_BEHAVIOR, - [defines.entity_status.disabled_by_script] = EntityStatus.DISABLED_BY_SCRIPT, - [defines.entity_status.discharging] = EntityStatus.DISCHARGING, - [defines.entity_status.fluid_ingredient_shortage] = EntityStatus.FLUID_INGREDIENT_SHORTAGE, - [defines.entity_status.fully_charged] = EntityStatus.FULLY_CHARGED, - [defines.entity_status.full_output] = EntityStatus.FULL_OUTPUT, - [defines.entity_status.item_ingredient_shortage] = EntityStatus.ITEM_INGREDIENT_SHORTAGE, - [defines.entity_status.launching_rocket] = EntityStatus.LAUNCHING_ROCKET, - [defines.entity_status.low_input_fluid] = EntityStatus.LOW_INPUT_FLUID, - [defines.entity_status.low_power] = EntityStatus.LOW_POWER, - [defines.entity_status.low_temperature] = EntityStatus.LOW_TEMPERATURE, - [defines.entity_status.marked_for_deconstruction] = EntityStatus.MARKED_FOR_DECONSTRUCTION, - [defines.entity_status.missing_required_fluid] = EntityStatus.MISSING_REQUIRED_FLUID, - [defines.entity_status.missing_science_packs] = EntityStatus.MISSING_SCIENCE_PACKS, - [defines.entity_status.networks_connected] = EntityStatus.NETWORKS_CONNECTED, - [defines.entity_status.networks_disconnected] = EntityStatus.NETWORKS_DISCONNECTED, - [defines.entity_status.normal] = EntityStatus.NORMAL, - [defines.entity_status.not_connected_to_rail] = EntityStatus.NOT_CONNECTED_TO_RAIL, - [defines.entity_status.not_plugged_in_electric_network] = EntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK, - [defines.entity_status.no_ammo] = EntityStatus.NO_AMMO, - [defines.entity_status.no_fuel] = EntityStatus.NO_FUEL, - [defines.entity_status.no_ingredients] = EntityStatus.NO_INGREDIENTS, - [defines.entity_status.no_input_fluid] = EntityStatus.NO_INPUT_FLUID, - [defines.entity_status.no_minable_resources] = EntityStatus.NO_MINABLE_RESOURCES, - [defines.entity_status.no_modules_to_transmit] = EntityStatus.NO_MODULES_TO_TRANSMIT, - [defines.entity_status.no_power] = EntityStatus.NO_POWER, - [defines.entity_status.no_recipe] = EntityStatus.NO_RECIPE, - [defines.entity_status.no_research_in_progress] = EntityStatus.NO_RESEARCH_IN_PROGRESS, - [defines.entity_status.opened_by_circuit_network] = EntityStatus.OPENED_BY_CIRCUIT_NETWORK, - [defines.entity_status.out_of_logistic_network] = EntityStatus.OUT_OF_LOGISTIC_NETWORK, - [defines.entity_status.preparing_rocket_for_launch] = EntityStatus.PREPARING_ROCKET_FOR_LAUNCH, - [defines.entity_status.recharging_after_power_outage] = EntityStatus.RECHARGING_AFTER_POWER_OUTAGE, - [defines.entity_status.turned_off_during_daytime] = EntityStatus.TURNED_OFF_DURING_DAYTIME, - [defines.entity_status.waiting_for_source_items] = EntityStatus.WAITING_FOR_SOURCE_ITEMS, - [defines.entity_status.waiting_for_space_in_destination] = EntityStatus.WAITING_FOR_SPACE_IN_DESTINATION, - [defines.entity_status.waiting_for_target_to_be_built] = EntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT, - [defines.entity_status.waiting_for_train] = EntityStatus.WAITING_FOR_TRAIN, - [defines.entity_status.waiting_to_launch_rocket] = EntityStatus.WAITING_TO_LAUNCH_ROCKET, - [defines.entity_status.working] = EntityStatus.WORKING + [defines.entity_status.cant_divide_segments] = FactorioEntityStatus.CANT_DIVIDE_SEGMENTS, + [defines.entity_status.charging] = FactorioEntityStatus.CHARGING, + [defines.entity_status.closed_by_circuit_network] = FactorioEntityStatus.CLOSED_BY_CIRCUIT_NETWORK, + [defines.entity_status.disabled] = FactorioEntityStatus.DISABLED, + [defines.entity_status.disabled_by_control_behavior] = FactorioEntityStatus.DISABLED_BY_CONTROL_BEHAVIOR, + [defines.entity_status.disabled_by_script] = FactorioEntityStatus.DISABLED_BY_SCRIPT, + [defines.entity_status.discharging] = FactorioEntityStatus.DISCHARGING, + [defines.entity_status.fluid_ingredient_shortage] = FactorioEntityStatus.FLUID_INGREDIENT_SHORTAGE, + [defines.entity_status.fully_charged] = FactorioEntityStatus.FULLY_CHARGED, + [defines.entity_status.full_output] = FactorioEntityStatus.FULL_OUTPUT, + [defines.entity_status.item_ingredient_shortage] = FactorioEntityStatus.ITEM_INGREDIENT_SHORTAGE, + [defines.entity_status.launching_rocket] = FactorioEntityStatus.LAUNCHING_ROCKET, + [defines.entity_status.low_input_fluid] = FactorioEntityStatus.LOW_INPUT_FLUID, + [defines.entity_status.low_power] = FactorioEntityStatus.LOW_POWER, + [defines.entity_status.low_temperature] = FactorioEntityStatus.LOW_TEMPERATURE, + [defines.entity_status.marked_for_deconstruction] = FactorioEntityStatus.MARKED_FOR_DECONSTRUCTION, + [defines.entity_status.missing_required_fluid] = FactorioEntityStatus.MISSING_REQUIRED_FLUID, + [defines.entity_status.missing_science_packs] = FactorioEntityStatus.MISSING_SCIENCE_PACKS, + [defines.entity_status.networks_connected] = FactorioEntityStatus.NETWORKS_CONNECTED, + [defines.entity_status.networks_disconnected] = FactorioEntityStatus.NETWORKS_DISCONNECTED, + [defines.entity_status.normal] = FactorioEntityStatus.NORMAL, + [defines.entity_status.not_connected_to_rail] = FactorioEntityStatus.NOT_CONNECTED_TO_RAIL, + [defines.entity_status.not_plugged_in_electric_network] = FactorioEntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK, + [defines.entity_status.no_ammo] = FactorioEntityStatus.NO_AMMO, + [defines.entity_status.no_fuel] = FactorioEntityStatus.NO_FUEL, + [defines.entity_status.no_ingredients] = FactorioEntityStatus.NO_INGREDIENTS, + [defines.entity_status.no_input_fluid] = FactorioEntityStatus.NO_INPUT_FLUID, + [defines.entity_status.no_minable_resources] = FactorioEntityStatus.NO_MINABLE_RESOURCES, + [defines.entity_status.no_modules_to_transmit] = FactorioEntityStatus.NO_MODULES_TO_TRANSMIT, + [defines.entity_status.no_power] = FactorioEntityStatus.NO_POWER, + [defines.entity_status.no_recipe] = FactorioEntityStatus.NO_RECIPE, + [defines.entity_status.no_research_in_progress] = FactorioEntityStatus.NO_RESEARCH_IN_PROGRESS, + [defines.entity_status.opened_by_circuit_network] = FactorioEntityStatus.OPENED_BY_CIRCUIT_NETWORK, + [defines.entity_status.out_of_logistic_network] = FactorioEntityStatus.OUT_OF_LOGISTIC_NETWORK, + [defines.entity_status.preparing_rocket_for_launch] = FactorioEntityStatus.PREPARING_ROCKET_FOR_LAUNCH, + [defines.entity_status.recharging_after_power_outage] = FactorioEntityStatus.RECHARGING_AFTER_POWER_OUTAGE, + [defines.entity_status.turned_off_during_daytime] = FactorioEntityStatus.TURNED_OFF_DURING_DAYTIME, + [defines.entity_status.waiting_for_source_items] = FactorioEntityStatus.WAITING_FOR_SOURCE_ITEMS, + [defines.entity_status.waiting_for_space_in_destination] = FactorioEntityStatus.WAITING_FOR_SPACE_IN_DESTINATION, + [defines.entity_status.waiting_for_target_to_be_built] = FactorioEntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT, + [defines.entity_status.waiting_for_train] = FactorioEntityStatus.WAITING_FOR_TRAIN, + [defines.entity_status.waiting_to_launch_rocket] = FactorioEntityStatus.WAITING_TO_LAUNCH_ROCKET, + [defines.entity_status.working] = FactorioEntityStatus.WORKING } end return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua b/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua index 16222f5..c18c0bb 100644 --- a/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua +++ b/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua @@ -3,7 +3,6 @@ local __TS__Class = ____lualib.__TS__Class local __TS__New = ____lualib.__TS__New local ____exports = {} local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") -local FactorioEntityData = ____kafkatorio_2Dschema.FactorioEntityData local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData local ____converters = require("main.events.converters") local Converters = ____converters.Converters @@ -22,21 +21,26 @@ function EntityUpdatesHandler.prototype.handleMinedTileEvent(self, event) local tilesByChunk = {} for ____, tile in ipairs(event.tiles) do local chunkPosition = Converters.tilePositionToChunkPosition(tile.position) - tilesByChunk[chunkPosition] = tile + if not (tilesByChunk[chunkPosition] ~= nil) then + tilesByChunk[chunkPosition] = {} + end + local tiles = tilesByChunk[chunkPosition] + tiles[#tiles + 1] = tile + tilesByChunk[chunkPosition] = tiles end for chunkPos, tiles in pairs(tilesByChunk) do local entities = {} - for tile in pairs(tiles) do - local resources = ____exports.EntityUpdatesHandler:getTileResourceEntities(surface, chunkPos) - for ____, resource in ipairs(resources) do + for ____, tile in ipairs(tiles) do + local tileEntities = ____exports.EntityUpdatesHandler:getTileResourceEntities(surface, tile.position) + for ____, resource in ipairs(tileEntities) do entities[#entities + 1] = resource end end - ____exports.EntityUpdatesHandler:throttleResourceEntitiesUpdate( + ____exports.EntityUpdatesHandler:throttleResourcesUpdate( Converters.eventNameString(event.name), event.tick, event.surface_index, - {chunkPos[1], chunkPos[2]}, + chunkPos, entities ) end @@ -49,11 +53,11 @@ function EntityUpdatesHandler.prototype.handleBuiltEntityEvent(self, event) end function EntityUpdatesHandler.prototype.handleChunkGeneratedEvent(self, event) local entities = ____exports.EntityUpdatesHandler:getAreaResourceEntities(event.surface, event.area) - ____exports.EntityUpdatesHandler:throttleResourceEntitiesUpdate( + ____exports.EntityUpdatesHandler:throttleResourcesUpdate( Converters.eventNameString(event.name), event.tick, event.surface.index, - {event.position.x, event.position.y}, + Converters.chunkPosition(event.position), entities ) end @@ -67,30 +71,24 @@ function EntityUpdatesHandler.throttleEntityUpdate(self, event, entity) surfaceIndex = entity.surface.index, chunkPosition = Converters.mapPositionToChunkPosition(entity.position) } - local ____FactorioEntityData_Type_Standard_2 = FactorioEntityData.Type.Standard - local ____Converters_prototypeIdEntity_result_3 = Converters.prototypeIdEntity(entity) - local ____entity_graphics_variation_4 = entity.graphics_variation - local ____entity_health_5 = entity.health - local ____entity_active_6 = entity.active - local ____entity_rotatable_7 = entity.rotatable + local ____entity_unit_number_2 = entity.unit_number + local ____entity_graphics_variation_3 = entity.graphics_variation + local ____entity_health_4 = entity.health + local ____entity_active_5 = entity.active + local ____entity_rotatable_6 = entity.rotatable local ____entity_last_user_index_0 = entity.last_user if ____entity_last_user_index_0 ~= nil then ____entity_last_user_index_0 = ____entity_last_user_index_0.index end local entityUpdate = { - type = ____FactorioEntityData_Type_Standard_2, - protoId = ____Converters_prototypeIdEntity_result_3, - graphicsVariation = ____entity_graphics_variation_4, - health = ____entity_health_5, - isActive = ____entity_active_6, - isRotatable = ____entity_rotatable_7, + unitNumber = ____entity_unit_number_2, + graphicsVariation = ____entity_graphics_variation_3, + health = ____entity_health_4, + isActive = ____entity_active_5, + isRotatable = ____entity_rotatable_6, lastUser = ____entity_last_user_index_0, - localisedDescription = nil, - localisedName = nil, - position = {entity.position.x, entity.position.y}, status = Converters.entityStatus(entity.status) } - local entityKey = tostring(entity.unit_number) EventDataCache:throttle( entityUpdateKey, KafkatorioPacketData.Type.MapChunkEntityUpdate, @@ -98,77 +96,73 @@ function EntityUpdatesHandler.throttleEntityUpdate(self, event, entity) if data.events == nil then data.events = {} end - local ____data_events_8, ____eventName_9 = data.events, eventName - if ____data_events_8[____eventName_9] == nil then - ____data_events_8[____eventName_9] = {} + local ____data_events_7, ____eventName_8 = data.events, eventName + if ____data_events_7[____eventName_8] == nil then + ____data_events_7[____eventName_8] = {} end - local ____data_events_eventName_10 = data.events[eventName] - ____data_events_eventName_10[#____data_events_eventName_10 + 1] = event.tick - if data.distinctEntities == nil then - data.distinctEntities = {} + local ____data_events_eventName_9 = data.events[eventName] + ____data_events_eventName_9[#____data_events_eventName_9 + 1] = event.tick + if data.entitiesXY == nil then + data.entitiesXY = {} + end + local ____data_entitiesXY_10, ____tostring_result_11 = data.entitiesXY, tostring(entity.position.x) + if ____data_entitiesXY_10[____tostring_result_11] == nil then + ____data_entitiesXY_10[____tostring_result_11] = {} + end + local ____data_entitiesXY_tostring_result_12, ____tostring_result_13 = data.entitiesXY[tostring(entity.position.x)], tostring(entity.position.y) + if ____data_entitiesXY_tostring_result_12[____tostring_result_13] == nil then + ____data_entitiesXY_tostring_result_12[____tostring_result_13] = entityUpdate end - data.distinctEntities[entityKey] = entityUpdate end ) end -function EntityUpdatesHandler.throttleResourceEntitiesUpdate(self, eventName, eventTick, surfaceIndex, chunkPosition, entities) +function EntityUpdatesHandler.throttleResourcesUpdate(self, eventName, eventTick, surfaceIndex, chunkPosition, entities) local entitiesByProtoId = {} for ____, entity in ipairs(entities) do - local ____entitiesByProtoId_11, ____entity_protoId_12 = entitiesByProtoId, entity.protoId - if ____entitiesByProtoId_11[____entity_protoId_12] == nil then - ____entitiesByProtoId_11[____entity_protoId_12] = {} + local protoId = Converters.prototypeIdEntity(entity) + if entitiesByProtoId[protoId] == nil then + entitiesByProtoId[protoId] = {} end - local ____entitiesByProtoId_entity_protoId_13 = entitiesByProtoId[entity.protoId] - ____entitiesByProtoId_entity_protoId_13[#____entitiesByProtoId_entity_protoId_13 + 1] = entity + local ____entitiesByProtoId_protoId_14 = entitiesByProtoId[protoId] + ____entitiesByProtoId_protoId_14[#____entitiesByProtoId_protoId_14 + 1] = entity end for protoId, resourceEntities in pairs(entitiesByProtoId) do - local entityUpdateKey = {protoId = protoId, surfaceIndex = surfaceIndex, chunkPosition = {chunkPosition[1], chunkPosition[2]}} + local entityUpdateKey = {protoId = protoId, surfaceIndex = surfaceIndex, chunkPosition = chunkPosition} EventDataCache:throttle( entityUpdateKey, - KafkatorioPacketData.Type.MapChunkEntityUpdate, + KafkatorioPacketData.Type.MapChunkResourceUpdate, function(data) if data.events == nil then data.events = {} end - local ____data_events_14, ____eventName_15 = data.events, eventName - if ____data_events_14[____eventName_15] == nil then - ____data_events_14[____eventName_15] = {} + local ____data_events_15, ____eventName_16 = data.events, eventName + if ____data_events_15[____eventName_16] == nil then + ____data_events_15[____eventName_16] = {} end - local ____data_events_eventName_16 = data.events[eventName] - ____data_events_eventName_16[#____data_events_eventName_16 + 1] = eventTick + local ____data_events_eventName_17 = data.events[eventName] + ____data_events_eventName_17[#____data_events_eventName_17 + 1] = eventTick for ____, entity in ipairs(resourceEntities) do - local x, y = table.unpack(entity.position) - local entityKey = (tostring(x) .. ",") .. tostring(y) - if data.distinctEntities == nil then - data.distinctEntities = {} + local resourceUpdate = Converters.convertResourceEntity(entity) + if resourceUpdate ~= nil then + if data.resourcesXY == nil then + data.resourcesXY = {} + end + local ____data_resourcesXY_18, ____tostring_result_19 = data.resourcesXY, tostring(entity.position.x) + if ____data_resourcesXY_18[____tostring_result_19] == nil then + ____data_resourcesXY_18[____tostring_result_19] = {} + end + data.resourcesXY[tostring(entity.position.x)][tostring(entity.position.y)] = resourceUpdate end - data.distinctEntities[entityKey] = entity end end ) end end function EntityUpdatesHandler.getTileResourceEntities(self, surface, mapPosition) - local rawEntities = surface.find_entities_filtered({position = mapPosition, collision_mask = "resource-layer"}) - local resources = {} - for ____, rawEntity in ipairs(rawEntities) do - local entity = Converters.convertResourceEntity(rawEntity) - if entity ~= nil then - resources[#resources + 1] = entity - end - end - return resources + return surface.find_entities_filtered({position = mapPosition, collision_mask = "resource-layer"}) end function EntityUpdatesHandler.getAreaResourceEntities(self, surface, area) - local rawEntities = surface.find_entities_filtered({area = area, collision_mask = "resource-layer"}) - local resources = {} - for ____, rawEntity in ipairs(rawEntities) do - local entity = Converters.convertResourceEntity(rawEntity) - if entity ~= nil then - resources[#resources + 1] = entity - end - end - return resources + return surface.find_entities_filtered({area = area, collision_mask = "resource-layer"}) end local EntityUpdates = __TS__New(____exports.EntityUpdatesHandler) ____exports.default = EntityUpdates diff --git a/modules/events-mod/src/generated/lua/main/events/handlers/MapChunkUpdateHandler.lua b/modules/events-mod/src/generated/lua/main/events/handlers/MapChunkUpdateHandler.lua index b4efcbb..66c8f6e 100644 --- a/modules/events-mod/src/generated/lua/main/events/handlers/MapChunkUpdateHandler.lua +++ b/modules/events-mod/src/generated/lua/main/events/handlers/MapChunkUpdateHandler.lua @@ -20,7 +20,7 @@ function MapChunkUpdateHandler.prototype.handleChunkGeneratedEvent(self, event, local tiles = event.surface.find_tiles_filtered({area = event.area}) MapChunkUpdateHandler:mapTilesUpdateDebounce( event.surface, - Converters.convertMapTablePosition(event.position), + Converters.chunkPosition(event.position), tiles, event, nil, @@ -123,7 +123,10 @@ function MapChunkUpdateHandler.prototype.handlePreChunkDeleted(self, event) return end for ____, position in ipairs(event.positions) do - local key = {surfaceIndex = surface.index, chunkPosition = {position.x, position.y}} + local key = { + surfaceIndex = surface.index, + chunkPosition = Converters.chunkPosition(position) + } EventUpdates:debounce( key, KafkatorioPacketData.Type.MapChunkTileUpdate, @@ -187,10 +190,7 @@ end function MapChunkUpdateHandler.groupTiles(self, tiles) local mapChunkPositionToTiles = __TS__New(Map) for ____, tile in ipairs(tiles) do - local chunkPosition = { - math.floor(tile.position.x / 32), - math.floor(tile.position.y / 32) - } + local chunkPosition = Converters.tilePositionToChunkPosition(tile.position) if not mapChunkPositionToTiles:has(chunkPosition) then mapChunkPositionToTiles:set(chunkPosition, {}) end diff --git a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua index 145c154..58bdd23 100644 --- a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua @@ -30,7 +30,7 @@ end function getEntityPrototypes() local protos = {} for ____, entity in pairs(game.entity_prototypes) do - local key = (entity.group.name .. "/") .. entity.subgroup.name + local key = (((entity.group.name .. "/") .. entity.subgroup.name) .. "/") .. entity.type if protos[key] == nil then protos[key] = {} end @@ -42,8 +42,10 @@ function getEntityPrototypes() isBuilding = entity.is_building, isEntityWithOwner = entity.is_entity_with_owner, isMilitaryTarget = entity.is_military_target, - maxHealth = entity.max_health + maxHealth = entity.max_health, + collisionBox = Converters.collisionBox(entity.collision_box) } + local ____ = entity.infinite_resource if entity.map_color ~= nil then entityProto.mapColour = Converters.mapColour(entity.map_color) end diff --git a/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua b/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua index 4d6e911..16e8d02 100644 --- a/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua +++ b/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua @@ -9,12 +9,12 @@ local ____EventDataCache = require("main.emitting.EventDataCache") local EventCacheService = ____EventDataCache.default local ____MapChunkUpdateHandler = require("main.events.handlers.MapChunkUpdateHandler") local MapChunkUpdate = ____MapChunkUpdateHandler.default -local ____queue = require("main.queue.queue") -local EventDataQueue = ____queue.default local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue") local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default local ____PacketEmitter = require("main.emitting.PacketEmitter") local PacketEmitter = ____PacketEmitter.default +local ____EventDataQueue = require("main.emitting.EventDataQueue") +local EventDataQueue = ____EventDataQueue.default script.on_event( defines.events.on_tick, function(event) diff --git a/modules/events-mod/src/generated/lua/main/global-init.lua b/modules/events-mod/src/generated/lua/main/global-init.lua index 28b970b..ff07189 100644 --- a/modules/events-mod/src/generated/lua/main/global-init.lua +++ b/modules/events-mod/src/generated/lua/main/global-init.lua @@ -1,8 +1,8 @@ local ____exports = {} local ____EventDataCache = require("main.emitting.EventDataCache") local EventUpdates = ____EventDataCache.default -local ____queue = require("main.queue.queue") -local EventDataQueueManager = ____queue.EventDataQueueManager +local ____EventDataQueue = require("main.emitting.EventDataQueue") +local EventDataQueueManager = ____EventDataQueue.EventDataQueueManager function ____exports.initGlobal(force) if force == nil then force = false diff --git a/modules/events-mod/src/generated/lua/main/settings/KafkatorioSettings.lua b/modules/events-mod/src/generated/lua/main/settings/KafkatorioSettings.lua index 28eac97..597c9d4 100644 --- a/modules/events-mod/src/generated/lua/main/settings/KafkatorioSettings.lua +++ b/modules/events-mod/src/generated/lua/main/settings/KafkatorioSettings.lua @@ -34,7 +34,13 @@ end function KafkatorioSettingsConfig.cacheDurationSettingName(self, ____type) return "kafkatorio:cache-expiration-seconds_" .. __TS__StringReplaceAll(____type, ".", "-") end -KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds = {["kafkatorio.packet.keyed.PlayerUpdate"] = 0.5, ["kafkatorio.packet.keyed.MapChunkTileUpdate"] = 30, ["kafkatorio.packet.keyed.MapChunkEntityUpdate"] = 30, ["kafkatorio.packet.keyed.EntityUpdate"] = 5} +KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds = { + ["kafkatorio.packet.keyed.PlayerUpdate"] = 0.5, + ["kafkatorio.packet.keyed.MapChunkTileUpdate"] = 30, + ["kafkatorio.packet.keyed.MapChunkEntityUpdate"] = 30, + ["kafkatorio.packet.keyed.MapChunkResourceUpdate"] = 30, + ["kafkatorio.packet.keyed.EntityUpdate"] = 5 +} local KafkatorioSettings = __TS__New(____exports.KafkatorioSettingsConfig) ____exports.default = KafkatorioSettings return ____exports diff --git a/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg b/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg index f3d4ab6..91e03f8 100644 --- a/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg +++ b/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg @@ -2,15 +2,17 @@ kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-PlayerUpdate=Player update rate (seconds) kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkTileUpdate=Map tile update rate (seconds) -kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkEntityUpdate=Entity update rate (seconds) +kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkEntityUpdate=Map entity update rate (seconds) +kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkResourceUpdate=Map resource update rate (seconds) kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-EntityUpdate=Entity update rate (seconds) [mod-setting-description] kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-PlayerUpdate=How frequently Player updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (0.25 seconds) is probably fine! -kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkTileUpdate=How frequently Map updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine! -kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkEntityUpdate=How frequently entity updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine! +kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkTileUpdate=How frequently map-tile updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine! +kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkEntityUpdate=How frequently map-entity updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine! +kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkResourceUpdate=How frequently map-resource updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine! kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-EntityUpdate=How frequently Entity updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (5 seconds) is probably fine! diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts index 3598c28..a82fefe 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts @@ -15,6 +15,7 @@ export type KafkatorioPacketData = | KafkatorioPacketData.EntityUpdate | KafkatorioPacketData.Error | KafkatorioPacketData.MapChunkEntityUpdate + | KafkatorioPacketData.MapChunkResourceUpdate | KafkatorioPacketData.MapChunkTileUpdate | KafkatorioPacketData.PlayerUpdate | KafkatorioPacketData.PrototypesUpdate @@ -29,6 +30,7 @@ export namespace KafkatorioPacketData { SurfaceUpdate = "kafkatorio.packet.instant.SurfaceUpdate", EntityUpdate = "kafkatorio.packet.keyed.EntityUpdate", MapChunkEntityUpdate = "kafkatorio.packet.keyed.MapChunkEntityUpdate", + MapChunkResourceUpdate = "kafkatorio.packet.keyed.MapChunkResourceUpdate", MapChunkTileUpdate = "kafkatorio.packet.keyed.MapChunkTileUpdate", PlayerUpdate = "kafkatorio.packet.keyed.PlayerUpdate", Error = "kafkatorio.packet.KafkatorioPacketData.Error", @@ -74,8 +76,8 @@ export namespace KafkatorioPacketData { chunkPosition?: MapEntityPosition | null; graphicsVariation?: UByte | null; health?: Float | null; - isActive?: boolean | null; - isRotatable?: boolean | null; + isActive?: boolean; + isRotatable?: boolean; lastUser?: UInt | null; localisedDescription?: string | null; localisedName?: string | null; @@ -85,7 +87,14 @@ export namespace KafkatorioPacketData { type: KafkatorioPacketData.Type.MapChunkEntityUpdate; key: MapChunkEntityUpdateKey; events?: { [key: EventName]: Tick[] } | null; - distinctEntities?: { [key: string]: FactorioEntityData } | null; + entitiesXY: FactorioEntityUpdateEntityDictionary; + } + + export interface MapChunkResourceUpdate { + type: KafkatorioPacketData.Type.MapChunkResourceUpdate; + key: MapChunkResourceUpdateKey; + events?: { [key: EventName]: Tick[] } | null; + resourcesXY: FactorioEntityUpdateResourceDictionary; } export interface MapChunkTileUpdate { @@ -96,7 +105,7 @@ export namespace KafkatorioPacketData { robot?: EntityIdentifiersData | null; force?: ForceIndex | null; tileDictionary?: MapTileDictionary | null; - isDeleted?: boolean | null; + isDeleted?: boolean; } export interface PlayerUpdate { @@ -110,10 +119,10 @@ export namespace KafkatorioPacketData { afkTime?: Tick | null; ticksToRespawn?: Tick | null; forceIndex?: ForceIndex | null; - isAdmin?: boolean | null; - isConnected?: boolean | null; - isShowOnMap?: boolean | null; - isSpectator?: boolean | null; + isAdmin?: boolean; + isConnected?: boolean; + isShowOnMap?: boolean; + isSpectator?: boolean; lastOnline?: Tick | null; onlineTime?: Tick | null; position?: MapEntityPosition | null; @@ -162,6 +171,16 @@ export interface MapChunkEntityUpdateKey { chunkPosition: MapChunkPosition; } +export type FactorioEntityUpdateEntityDictionary = { [key: string]: { [key: string]: FactorioEntityUpdateEntity } }; + +export interface MapChunkResourceUpdateKey { + protoId: PrototypeId; + surfaceIndex: SurfaceIndex; + chunkPosition: MapChunkPosition; +} + +export type FactorioEntityUpdateResourceDictionary = { [key: string]: { [key: string]: FactorioEntityUpdateResource } }; + export interface MapChunkTileUpdateKey { chunkPosition: MapChunkPosition; surfaceIndex: SurfaceIndex; @@ -218,10 +237,11 @@ export namespace FactorioPrototype { mapColourFriend?: Colour | null; mapColourEnemy?: Colour | null; maxHealth: Float; - isBuilding: boolean; - isEntityWithOwner: boolean; - isMilitaryTarget: boolean; + isBuilding?: boolean; + isEntityWithOwner?: boolean; + isMilitaryTarget?: boolean; miningProperties?: EntityMiningProperties | null; + collisionBox?: MapBoundingBox | null; } export interface MapTile { @@ -229,7 +249,7 @@ export namespace FactorioPrototype { protoId: PrototypeId; mapColour: Colour; layer: UInt; - collisionMasks: List; + collisionMasks: string[]; order: string; canBeMined: boolean; } @@ -244,42 +264,9 @@ export type Byte = int8; export type MapChunkPosition = [ x: Int, y: Int, + chunkSize: ChunkSize, ]; -export type FactorioEntityData = - | FactorioEntityData.Resource - | FactorioEntityData.Standard; - -export namespace FactorioEntityData { - export enum Type { - Resource = "kafkatorio.entity.FactorioEntityData.Resource", - Standard = "kafkatorio.entity.FactorioEntityData.Standard", - } - - export interface Resource { - type: FactorioEntityData.Type.Resource; - protoId: PrototypeId; - status?: EntityStatus | null; - position: MapEntityPosition; - amount: UInt; - initialAmount?: UInt | null; - } - - export interface Standard { - type: FactorioEntityData.Type.Standard; - protoId: PrototypeId; - status?: EntityStatus | null; - position: MapEntityPosition; - graphicsVariation?: UByte | null; - health?: Float | null; - isActive?: boolean | null; - isRotatable?: boolean | null; - lastUser?: UInt | null; - localisedDescription?: string | null; - localisedName?: string | null; - } -} - export interface EntityItemGroup { name: string; type: string; @@ -291,56 +278,36 @@ export interface EntityMiningProperties { products: MinedProduct[] | null; } -export type List = any & { __List__: void }; +export interface MapBoundingBox { + leftTop: MapEntityPosition; + rightBottom: MapEntityPosition; +} -export enum EntityStatus { - CANT_DIVIDE_SEGMENTS = "CANT_DIVIDE_SEGMENTS", - CHARGING = "CHARGING", - CLOSED_BY_CIRCUIT_NETWORK = "CLOSED_BY_CIRCUIT_NETWORK", - DISABLED = "DISABLED", - DISABLED_BY_CONTROL_BEHAVIOR = "DISABLED_BY_CONTROL_BEHAVIOR", - DISABLED_BY_SCRIPT = "DISABLED_BY_SCRIPT", - DISCHARGING = "DISCHARGING", - FLUID_INGREDIENT_SHORTAGE = "FLUID_INGREDIENT_SHORTAGE", - FULLY_CHARGED = "FULLY_CHARGED", - FULL_OUTPUT = "FULL_OUTPUT", - ITEM_INGREDIENT_SHORTAGE = "ITEM_INGREDIENT_SHORTAGE", - LAUNCHING_ROCKET = "LAUNCHING_ROCKET", - LOW_INPUT_FLUID = "LOW_INPUT_FLUID", - LOW_POWER = "LOW_POWER", - LOW_TEMPERATURE = "LOW_TEMPERATURE", - MARKED_FOR_DECONSTRUCTION = "MARKED_FOR_DECONSTRUCTION", - MISSING_REQUIRED_FLUID = "MISSING_REQUIRED_FLUID", - MISSING_SCIENCE_PACKS = "MISSING_SCIENCE_PACKS", - NETWORKS_CONNECTED = "NETWORKS_CONNECTED", - NETWORKS_DISCONNECTED = "NETWORKS_DISCONNECTED", - NORMAL = "NORMAL", - NOT_CONNECTED_TO_RAIL = "NOT_CONNECTED_TO_RAIL", - NOT_PLUGGED_IN_ELECTRIC_NETWORK = "NOT_PLUGGED_IN_ELECTRIC_NETWORK", - NO_AMMO = "NO_AMMO", - NO_FUEL = "NO_FUEL", - NO_INGREDIENTS = "NO_INGREDIENTS", - NO_INPUT_FLUID = "NO_INPUT_FLUID", - NO_MINABLE_RESOURCES = "NO_MINABLE_RESOURCES", - NO_MODULES_TO_TRANSMIT = "NO_MODULES_TO_TRANSMIT", - NO_POWER = "NO_POWER", - NO_RECIPE = "NO_RECIPE", - NO_RESEARCH_IN_PROGRESS = "NO_RESEARCH_IN_PROGRESS", - OPENED_BY_CIRCUIT_NETWORK = "OPENED_BY_CIRCUIT_NETWORK", - OUT_OF_LOGISTIC_NETWORK = "OUT_OF_LOGISTIC_NETWORK", - PREPARING_ROCKET_FOR_LAUNCH = "PREPARING_ROCKET_FOR_LAUNCH", - RECHARGING_AFTER_POWER_OUTAGE = "RECHARGING_AFTER_POWER_OUTAGE", - TURNED_OFF_DURING_DAYTIME = "TURNED_OFF_DURING_DAYTIME", - WAITING_FOR_SOURCE_ITEMS = "WAITING_FOR_SOURCE_ITEMS", - WAITING_FOR_SPACE_IN_DESTINATION = "WAITING_FOR_SPACE_IN_DESTINATION", - WAITING_FOR_TARGET_TO_BE_BUILT = "WAITING_FOR_TARGET_TO_BE_BUILT", - WAITING_FOR_TRAIN = "WAITING_FOR_TRAIN", - WAITING_TO_LAUNCH_ROCKET = "WAITING_TO_LAUNCH_ROCKET", - WORKING = "WORKING", +export enum ChunkSize { + CHUNK_512 = "CHUNK_512", + CHUNK_256 = "CHUNK_256", + CHUNK_128 = "CHUNK_128", + CHUNK_064 = "CHUNK_064", + CHUNK_032 = "CHUNK_032", } export type PrototypeKey = Int & { __PrototypeKey__: void }; +export interface FactorioEntityUpdateEntity { + status?: FactorioEntityStatus | null; + unitNumber?: UnitNumber | null; + graphicsVariation?: UByte | null; + health?: Float | null; + isActive?: boolean | null; + isRotatable?: boolean | null; + lastUser?: UInt | null; +} + +export interface FactorioEntityUpdateResource { + amount: UInt; + initialAmount?: UInt | null; +} + export type MinedProduct = | MinedProduct.MinedProductFluid | MinedProduct.MinedProductItem; @@ -362,4 +329,50 @@ export namespace MinedProduct { amount?: Double | null; resultProtoId: PrototypeId; } +} + +export enum FactorioEntityStatus { + WORKING = "WORKING", + NORMAL = "NORMAL", + NO_POWER = "NO_POWER", + LOW_POWER = "LOW_POWER", + NO_FUEL = "NO_FUEL", + DISABLED_BY_CONTROL_BEHAVIOR = "DISABLED_BY_CONTROL_BEHAVIOR", + OPENED_BY_CIRCUIT_NETWORK = "OPENED_BY_CIRCUIT_NETWORK", + CLOSED_BY_CIRCUIT_NETWORK = "CLOSED_BY_CIRCUIT_NETWORK", + DISABLED_BY_SCRIPT = "DISABLED_BY_SCRIPT", + MARKED_FOR_DECONSTRUCTION = "MARKED_FOR_DECONSTRUCTION", + NOT_PLUGGED_IN_ELECTRIC_NETWORK = "NOT_PLUGGED_IN_ELECTRIC_NETWORK", + NETWORKS_CONNECTED = "NETWORKS_CONNECTED", + NETWORKS_DISCONNECTED = "NETWORKS_DISCONNECTED", + CHARGING = "CHARGING", + DISCHARGING = "DISCHARGING", + FULLY_CHARGED = "FULLY_CHARGED", + OUT_OF_LOGISTIC_NETWORK = "OUT_OF_LOGISTIC_NETWORK", + NO_RECIPE = "NO_RECIPE", + NO_INGREDIENTS = "NO_INGREDIENTS", + NO_INPUT_FLUID = "NO_INPUT_FLUID", + NO_RESEARCH_IN_PROGRESS = "NO_RESEARCH_IN_PROGRESS", + NO_MINABLE_RESOURCES = "NO_MINABLE_RESOURCES", + LOW_INPUT_FLUID = "LOW_INPUT_FLUID", + FLUID_INGREDIENT_SHORTAGE = "FLUID_INGREDIENT_SHORTAGE", + FULL_OUTPUT = "FULL_OUTPUT", + ITEM_INGREDIENT_SHORTAGE = "ITEM_INGREDIENT_SHORTAGE", + MISSING_REQUIRED_FLUID = "MISSING_REQUIRED_FLUID", + MISSING_SCIENCE_PACKS = "MISSING_SCIENCE_PACKS", + WAITING_FOR_SOURCE_ITEMS = "WAITING_FOR_SOURCE_ITEMS", + WAITING_FOR_SPACE_IN_DESTINATION = "WAITING_FOR_SPACE_IN_DESTINATION", + PREPARING_ROCKET_FOR_LAUNCH = "PREPARING_ROCKET_FOR_LAUNCH", + WAITING_TO_LAUNCH_ROCKET = "WAITING_TO_LAUNCH_ROCKET", + LAUNCHING_ROCKET = "LAUNCHING_ROCKET", + NO_MODULES_TO_TRANSMIT = "NO_MODULES_TO_TRANSMIT", + RECHARGING_AFTER_POWER_OUTAGE = "RECHARGING_AFTER_POWER_OUTAGE", + WAITING_FOR_TARGET_TO_BE_BUILT = "WAITING_FOR_TARGET_TO_BE_BUILT", + WAITING_FOR_TRAIN = "WAITING_FOR_TRAIN", + NO_AMMO = "NO_AMMO", + LOW_TEMPERATURE = "LOW_TEMPERATURE", + DISABLED = "DISABLED", + TURNED_OFF_DURING_DAYTIME = "TURNED_OFF_DURING_DAYTIME", + NOT_CONNECTED_TO_RAIL = "NOT_CONNECTED_TO_RAIL", + CANT_DIVIDE_SEGMENTS = "CANT_DIVIDE_SEGMENTS", } \ No newline at end of file diff --git a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts index a1e4c67..cc29083 100644 --- a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts +++ b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts @@ -1,6 +1,6 @@ import {initGlobal} from "../global-init"; import {emitPrototypes} from "../events/prototypeUpdates"; -import EventDataQueue from "../queue/queue"; +import EventDataQueue from "../emitting/EventDataQueue"; commands.add_command( diff --git a/modules/events-mod/src/main/typescript/main/queue/queue.ts b/modules/events-mod/src/main/typescript/main/emitting/EventDataQueue.ts similarity index 100% rename from modules/events-mod/src/main/typescript/main/queue/queue.ts rename to modules/events-mod/src/main/typescript/main/emitting/EventDataQueue.ts diff --git a/modules/events-mod/src/main/typescript/main/emitting/KafkatorioPacketQueue.ts b/modules/events-mod/src/main/typescript/main/emitting/KafkatorioPacketQueue.ts index 406ec86..60aebdb 100644 --- a/modules/events-mod/src/main/typescript/main/emitting/KafkatorioPacketQueue.ts +++ b/modules/events-mod/src/main/typescript/main/emitting/KafkatorioPacketQueue.ts @@ -1,5 +1,12 @@ import {KafkatorioPacketData} from "../../generated/kafkatorio-schema"; + +/** + * Simple ordered queue for {@link KafkatorioPacketData}. + * + * Implemented so printing multiple packets won't flood the output log, causing messages to be + * missed or garbled. + */ export class KafkatorioPacketQueueManager { private size: int = 0 diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index 861c546..b2fb56d 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -1,16 +1,20 @@ import {DefinedEventName} from "../types"; import { + ChunkSize, Colour, EntityMiningProperties, - EntityStatus, EventName, - FactorioEntityData, + FactorioEntityStatus, + FactorioEntityUpdateResource, KafkatorioPacketData, + MapBoundingBox, MapChunkPosition, + MapEntityPosition, MinedProduct, PrototypeId, } from "../../generated/kafkatorio-schema"; + export namespace Converters { @@ -63,13 +67,6 @@ export namespace Converters { } - export function convertMapTablePosition( - position: MapPositionTable, - ): MapChunkPosition { - return [position.x, position.y] - } - - export function convertCollisionMaskToNames(cm: CollisionMask): string[] { let masks: string[] = [] for (const [name] of pairs(cm)) { @@ -81,17 +78,13 @@ export namespace Converters { export function convertResourceEntity( entity: LuaEntity - ): FactorioEntityData.Resource | null { + ): FactorioEntityUpdateResource | null { if (entity.type != "resource") { return null } else { return { - type: FactorioEntityData.Type.Resource, - protoId: prototypeId(entity.type, entity.name), - status: convertEntityStatus(entity.status), amount: entity.amount, initialAmount: entity.initial_amount, - position: convertMapTablePosition(entity.position), } } } @@ -99,7 +92,7 @@ export namespace Converters { function convertEntityStatus( status: defines.entity_status | undefined - ): EntityStatus | null { + ): FactorioEntityStatus | null { if (status == undefined) { return null } else { @@ -119,15 +112,26 @@ export namespace Converters { export function tilePositionToChunkPosition(mapPosition: TilePositionTable): MapChunkPosition { - return [floor(mapPosition.x / 32), floor(mapPosition.y)] + return [floor(mapPosition.x / 32), floor(mapPosition.y / 32), ChunkSize.CHUNK_032] } + export function mapPositionToChunkPosition(mapPosition: MapPositionTable): MapChunkPosition { - return [floor(mapPosition.x / 32), floor(mapPosition.y)] + return [floor(mapPosition.x / 32), floor(mapPosition.y / 32), ChunkSize.CHUNK_032] } - export function entityStatus(status: defines.entity_status | undefined): EntityStatus | undefined { + export function entityPosition(position: MapPositionTable): MapEntityPosition { + return [position.x, position.y]; + } + + + export function chunkPosition(position: ChunkPositionTable): MapChunkPosition { + return [position.x, position.y, ChunkSize.CHUNK_032] + } + + + export function entityStatus(status: defines.entity_status | undefined): FactorioEntityStatus | undefined { if (status == undefined) { return undefined } else { @@ -176,51 +180,59 @@ export namespace Converters { } - const EntityStatusRecord: Record = { + export function collisionBox(collision_box: BoundingBoxRead): MapBoundingBox { + return { + leftTop: Converters.entityPosition(collision_box.left_top), + rightBottom: Converters.entityPosition(collision_box.right_bottom), + } + } + + + const EntityStatusRecord: Record = { //@formatter:off - [ defines.entity_status.cant_divide_segments ]: EntityStatus.CANT_DIVIDE_SEGMENTS, - [ defines.entity_status.charging ]: EntityStatus.CHARGING, - [ defines.entity_status.closed_by_circuit_network ]: EntityStatus.CLOSED_BY_CIRCUIT_NETWORK, - [ defines.entity_status.disabled ]: EntityStatus.DISABLED, - [ defines.entity_status.disabled_by_control_behavior ]: EntityStatus.DISABLED_BY_CONTROL_BEHAVIOR, - [ defines.entity_status.disabled_by_script ]: EntityStatus.DISABLED_BY_SCRIPT, - [ defines.entity_status.discharging ]: EntityStatus.DISCHARGING, - [ defines.entity_status.fluid_ingredient_shortage ]: EntityStatus.FLUID_INGREDIENT_SHORTAGE, - [ defines.entity_status.fully_charged ]: EntityStatus.FULLY_CHARGED, - [ defines.entity_status.full_output ]: EntityStatus.FULL_OUTPUT, - [ defines.entity_status.item_ingredient_shortage ]: EntityStatus.ITEM_INGREDIENT_SHORTAGE, - [ defines.entity_status.launching_rocket ]: EntityStatus.LAUNCHING_ROCKET, - [ defines.entity_status.low_input_fluid ]: EntityStatus.LOW_INPUT_FLUID, - [ defines.entity_status.low_power ]: EntityStatus.LOW_POWER, - [ defines.entity_status.low_temperature ]: EntityStatus.LOW_TEMPERATURE, - [ defines.entity_status.marked_for_deconstruction ]: EntityStatus.MARKED_FOR_DECONSTRUCTION, - [ defines.entity_status.missing_required_fluid ]: EntityStatus.MISSING_REQUIRED_FLUID, - [ defines.entity_status.missing_science_packs ]: EntityStatus.MISSING_SCIENCE_PACKS, - [ defines.entity_status.networks_connected ]: EntityStatus.NETWORKS_CONNECTED, - [ defines.entity_status.networks_disconnected ]: EntityStatus.NETWORKS_DISCONNECTED, - [ defines.entity_status.normal ]: EntityStatus.NORMAL, - [ defines.entity_status.not_connected_to_rail ]: EntityStatus.NOT_CONNECTED_TO_RAIL, - [ defines.entity_status.not_plugged_in_electric_network ]: EntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK, - [ defines.entity_status.no_ammo ]: EntityStatus.NO_AMMO, - [ defines.entity_status.no_fuel ]: EntityStatus.NO_FUEL, - [ defines.entity_status.no_ingredients ]: EntityStatus.NO_INGREDIENTS, - [ defines.entity_status.no_input_fluid ]: EntityStatus.NO_INPUT_FLUID, - [ defines.entity_status.no_minable_resources ]: EntityStatus.NO_MINABLE_RESOURCES, - [ defines.entity_status.no_modules_to_transmit ]: EntityStatus.NO_MODULES_TO_TRANSMIT, - [ defines.entity_status.no_power ]: EntityStatus.NO_POWER, - [ defines.entity_status.no_recipe ]: EntityStatus.NO_RECIPE, - [ defines.entity_status.no_research_in_progress ]: EntityStatus.NO_RESEARCH_IN_PROGRESS, - [ defines.entity_status.opened_by_circuit_network ]: EntityStatus.OPENED_BY_CIRCUIT_NETWORK, - [ defines.entity_status.out_of_logistic_network ]: EntityStatus.OUT_OF_LOGISTIC_NETWORK, - [ defines.entity_status.preparing_rocket_for_launch ]: EntityStatus.PREPARING_ROCKET_FOR_LAUNCH, - [ defines.entity_status.recharging_after_power_outage ]: EntityStatus.RECHARGING_AFTER_POWER_OUTAGE, - [ defines.entity_status.turned_off_during_daytime ]: EntityStatus.TURNED_OFF_DURING_DAYTIME, - [ defines.entity_status.waiting_for_source_items ]: EntityStatus.WAITING_FOR_SOURCE_ITEMS, - [ defines.entity_status.waiting_for_space_in_destination ]: EntityStatus.WAITING_FOR_SPACE_IN_DESTINATION, - [ defines.entity_status.waiting_for_target_to_be_built ]: EntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT, - [ defines.entity_status.waiting_for_train ]: EntityStatus.WAITING_FOR_TRAIN, - [ defines.entity_status.waiting_to_launch_rocket ]: EntityStatus.WAITING_TO_LAUNCH_ROCKET, - [ defines.entity_status.working ]: EntityStatus.WORKING, + [ defines.entity_status.cant_divide_segments ]: FactorioEntityStatus.CANT_DIVIDE_SEGMENTS, + [ defines.entity_status.charging ]: FactorioEntityStatus.CHARGING, + [ defines.entity_status.closed_by_circuit_network ]: FactorioEntityStatus.CLOSED_BY_CIRCUIT_NETWORK, + [ defines.entity_status.disabled ]: FactorioEntityStatus.DISABLED, + [ defines.entity_status.disabled_by_control_behavior ]: FactorioEntityStatus.DISABLED_BY_CONTROL_BEHAVIOR, + [ defines.entity_status.disabled_by_script ]: FactorioEntityStatus.DISABLED_BY_SCRIPT, + [ defines.entity_status.discharging ]: FactorioEntityStatus.DISCHARGING, + [ defines.entity_status.fluid_ingredient_shortage ]: FactorioEntityStatus.FLUID_INGREDIENT_SHORTAGE, + [ defines.entity_status.fully_charged ]: FactorioEntityStatus.FULLY_CHARGED, + [ defines.entity_status.full_output ]: FactorioEntityStatus.FULL_OUTPUT, + [ defines.entity_status.item_ingredient_shortage ]: FactorioEntityStatus.ITEM_INGREDIENT_SHORTAGE, + [ defines.entity_status.launching_rocket ]: FactorioEntityStatus.LAUNCHING_ROCKET, + [ defines.entity_status.low_input_fluid ]: FactorioEntityStatus.LOW_INPUT_FLUID, + [ defines.entity_status.low_power ]: FactorioEntityStatus.LOW_POWER, + [ defines.entity_status.low_temperature ]: FactorioEntityStatus.LOW_TEMPERATURE, + [ defines.entity_status.marked_for_deconstruction ]: FactorioEntityStatus.MARKED_FOR_DECONSTRUCTION, + [ defines.entity_status.missing_required_fluid ]: FactorioEntityStatus.MISSING_REQUIRED_FLUID, + [ defines.entity_status.missing_science_packs ]: FactorioEntityStatus.MISSING_SCIENCE_PACKS, + [ defines.entity_status.networks_connected ]: FactorioEntityStatus.NETWORKS_CONNECTED, + [ defines.entity_status.networks_disconnected ]: FactorioEntityStatus.NETWORKS_DISCONNECTED, + [ defines.entity_status.normal ]: FactorioEntityStatus.NORMAL, + [ defines.entity_status.not_connected_to_rail ]: FactorioEntityStatus.NOT_CONNECTED_TO_RAIL, + [ defines.entity_status.not_plugged_in_electric_network ]: FactorioEntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK, + [ defines.entity_status.no_ammo ]: FactorioEntityStatus.NO_AMMO, + [ defines.entity_status.no_fuel ]: FactorioEntityStatus.NO_FUEL, + [ defines.entity_status.no_ingredients ]: FactorioEntityStatus.NO_INGREDIENTS, + [ defines.entity_status.no_input_fluid ]: FactorioEntityStatus.NO_INPUT_FLUID, + [ defines.entity_status.no_minable_resources ]: FactorioEntityStatus.NO_MINABLE_RESOURCES, + [ defines.entity_status.no_modules_to_transmit ]: FactorioEntityStatus.NO_MODULES_TO_TRANSMIT, + [ defines.entity_status.no_power ]: FactorioEntityStatus.NO_POWER, + [ defines.entity_status.no_recipe ]: FactorioEntityStatus.NO_RECIPE, + [ defines.entity_status.no_research_in_progress ]: FactorioEntityStatus.NO_RESEARCH_IN_PROGRESS, + [ defines.entity_status.opened_by_circuit_network ]: FactorioEntityStatus.OPENED_BY_CIRCUIT_NETWORK, + [ defines.entity_status.out_of_logistic_network ]: FactorioEntityStatus.OUT_OF_LOGISTIC_NETWORK, + [ defines.entity_status.preparing_rocket_for_launch ]: FactorioEntityStatus.PREPARING_ROCKET_FOR_LAUNCH, + [ defines.entity_status.recharging_after_power_outage ]: FactorioEntityStatus.RECHARGING_AFTER_POWER_OUTAGE, + [ defines.entity_status.turned_off_during_daytime ]: FactorioEntityStatus.TURNED_OFF_DURING_DAYTIME, + [ defines.entity_status.waiting_for_source_items ]: FactorioEntityStatus.WAITING_FOR_SOURCE_ITEMS, + [ defines.entity_status.waiting_for_space_in_destination ]: FactorioEntityStatus.WAITING_FOR_SPACE_IN_DESTINATION, + [ defines.entity_status.waiting_for_target_to_be_built ]: FactorioEntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT, + [ defines.entity_status.waiting_for_train ]: FactorioEntityStatus.WAITING_FOR_TRAIN, + [ defines.entity_status.waiting_to_launch_rocket ]: FactorioEntityStatus.WAITING_TO_LAUNCH_ROCKET, + [ defines.entity_status.working ]: FactorioEntityStatus.WORKING, //@formatter:on } } diff --git a/modules/events-mod/src/main/typescript/main/events/handlers/EntityUpdateHandler.ts b/modules/events-mod/src/main/typescript/main/events/handlers/EntityUpdateHandler.ts index 19c7afc..6ccb787 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers/EntityUpdateHandler.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers/EntityUpdateHandler.ts @@ -1,8 +1,9 @@ import { EventName, - FactorioEntityData, + FactorioEntityUpdateEntity, KafkatorioPacketData, - MapChunkPosition, PrototypeId, + MapChunkPosition, + PrototypeId, Tick } from "../../../generated/kafkatorio-schema"; import {Converters} from "../converters"; @@ -19,29 +20,34 @@ export class EntityUpdatesHandler { return } - const tilesByChunk: LuaTable = new LuaTable() + const tilesByChunk: LuaTable = new LuaTable() for (const tile of event.tiles) { const chunkPosition = Converters.tilePositionToChunkPosition(tile.position) - tilesByChunk.set(chunkPosition, tile) + if (!tilesByChunk.has(chunkPosition)) { + tilesByChunk.set(chunkPosition, []) + } + const tiles = tilesByChunk.get(chunkPosition) + tiles[tiles.length] = tile + tilesByChunk.set(chunkPosition, tiles) } for (const [chunkPos, tiles] of pairs(tilesByChunk)) { - const entities: FactorioEntityData.Resource[] = [] + const entities: LuaEntity[] = [] - for (const tile in tiles) { - const resources: FactorioEntityData.Resource[] = EntityUpdatesHandler.getTileResourceEntities(surface, chunkPos) - for (const resource of resources) { + for (const tile of tiles) { + const tileEntities = EntityUpdatesHandler.getTileResourceEntities(surface, tile.position) + for (const resource of tileEntities) { entities[entities.length] = resource } } - EntityUpdatesHandler.throttleResourceEntitiesUpdate( + EntityUpdatesHandler.throttleResourcesUpdate( Converters.eventNameString(event.name), event.tick as Tick, event.surface_index, - [chunkPos[0], chunkPos[1]], + chunkPos, entities, ) } @@ -64,11 +70,11 @@ export class EntityUpdatesHandler { handleChunkGeneratedEvent(event: OnChunkGeneratedEvent) { const entities = EntityUpdatesHandler.getAreaResourceEntities(event.surface, event.area) - EntityUpdatesHandler.throttleResourceEntitiesUpdate( + EntityUpdatesHandler.throttleResourcesUpdate( Converters.eventNameString(event.name), event.tick as Tick, event.surface.index, - [event.position.x, event.position.y], + Converters.chunkPosition(event.position), entities, ) } @@ -88,22 +94,16 @@ export class EntityUpdatesHandler { chunkPosition: Converters.mapPositionToChunkPosition(entity.position) } - const entityUpdate: FactorioEntityData.Standard = { - type: FactorioEntityData.Type.Standard, - protoId: Converters.prototypeIdEntity(entity), + const entityUpdate: FactorioEntityUpdateEntity = { + unitNumber: entity.unit_number, graphicsVariation: entity.graphics_variation, health: entity.health, isActive: entity.active, isRotatable: entity.rotatable, lastUser: entity.last_user?.index, - localisedDescription: null, - localisedName: null, - position: [entity.position.x, entity.position.y], status: Converters.entityStatus(entity.status), } - const entityKey: string = `${entity.unit_number}` - EventDataCache.throttle( entityUpdateKey, KafkatorioPacketData.Type.MapChunkEntityUpdate, @@ -113,42 +113,44 @@ export class EntityUpdatesHandler { data.events[eventName] ??= [] data.events[eventName].push(event.tick) - data.distinctEntities ??= {} - data.distinctEntities[entityKey] = entityUpdate + data.entitiesXY ??= {} + data.entitiesXY[`${entity.position.x}`] ??= {} + data.entitiesXY[`${entity.position.x}`][`${entity.position.y}`] ??= entityUpdate } ) } - private static throttleResourceEntitiesUpdate( + private static throttleResourcesUpdate( eventName: EventName, eventTick: Tick, surfaceIndex: SurfaceIndex, chunkPosition: MapChunkPosition, - entities: FactorioEntityData.Resource[], + entities: LuaEntity[], ) { // first group by prototype ID - const entitiesByProtoId: { [protoId: PrototypeId]: FactorioEntityData.Resource[] } = {} + const entitiesByProtoId: { [protoId: PrototypeId]: LuaEntity[] } = {} for (const entity of entities) { - entitiesByProtoId[entity.protoId] ??= [] - entitiesByProtoId[entity.protoId].push(entity) + const protoId = Converters.prototypeIdEntity(entity) + entitiesByProtoId[protoId] ??= [] + entitiesByProtoId[protoId].push(entity) } for (const [protoId, resourceEntities] of pairs(entitiesByProtoId)) { - // create an update for each prototype + // create an update for each prototype ID - const entityUpdateKey: KafkatorioPacketData.MapChunkEntityUpdate["key"] = { + const entityUpdateKey: KafkatorioPacketData.MapChunkResourceUpdate["key"] = { protoId: protoId, surfaceIndex: surfaceIndex, - chunkPosition: [chunkPosition[0], chunkPosition[1]], + chunkPosition: chunkPosition, } - EventDataCache.throttle( + EventDataCache.throttle( entityUpdateKey, - KafkatorioPacketData.Type.MapChunkEntityUpdate, + KafkatorioPacketData.Type.MapChunkResourceUpdate, data => { data.events ??= {} @@ -156,11 +158,13 @@ export class EntityUpdatesHandler { data.events[eventName].push(eventTick) for (const entity of resourceEntities) { - const [x, y] = entity.position - const entityKey: string = `${x},${y}` + const resourceUpdate = Converters.convertResourceEntity(entity) - data.distinctEntities ??= {} - data.distinctEntities[entityKey] = entity + if (resourceUpdate != null) { + data.resourcesXY ??= {} + data.resourcesXY[`${entity.position.x}`] ??= {} + data.resourcesXY[`${entity.position.x}`][`${entity.position.y}`] = resourceUpdate + } } } ) @@ -173,24 +177,12 @@ export class EntityUpdatesHandler { private static getTileResourceEntities( surface: LuaSurface, mapPosition: MapPosition, - ): FactorioEntityData.Resource[] { - - const rawEntities = surface.find_entities_filtered({ + ): LuaEntity[] { + return surface.find_entities_filtered({ position: mapPosition, collision_mask: "resource-layer", } ) - - const resources: FactorioEntityData.Resource[] = [] - - for (const rawEntity of rawEntities) { - const entity = Converters.convertResourceEntity(rawEntity) - if (entity != null) { - resources[resources.length] = entity - } - } - - return resources } @@ -198,24 +190,12 @@ export class EntityUpdatesHandler { private static getAreaResourceEntities( surface: LuaSurface, area: BoundingBoxTable, - ): FactorioEntityData.Resource[] { - - const rawEntities = surface.find_entities_filtered({ + ): LuaEntity[] { + return surface.find_entities_filtered({ area: area, collision_mask: "resource-layer", } ) - - const resources: FactorioEntityData.Resource[] = [] - - for (const rawEntity of rawEntities) { - const entity = Converters.convertResourceEntity(rawEntity) - if (entity != null) { - resources[resources.length] = entity - } - } - - return resources } } diff --git a/modules/events-mod/src/main/typescript/main/events/handlers/MapChunkUpdateHandler.ts b/modules/events-mod/src/main/typescript/main/events/handlers/MapChunkUpdateHandler.ts index 5fcb365..5ab13ec 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers/MapChunkUpdateHandler.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers/MapChunkUpdateHandler.ts @@ -22,7 +22,7 @@ class MapChunkUpdateHandler { MapChunkUpdateHandler.mapTilesUpdateDebounce( event.surface, - Converters.convertMapTablePosition(event.position), + Converters.chunkPosition(event.position), tiles, event, undefined, @@ -136,7 +136,7 @@ class MapChunkUpdateHandler { for (const position of event.positions) { const key: PacketKey = { surfaceIndex: surface.index, - chunkPosition: [position.x, position.y], + chunkPosition: Converters.chunkPosition(position), } EventUpdates.debounce( @@ -219,10 +219,7 @@ class MapChunkUpdateHandler { const mapChunkPositionToTiles = new Map() for (const tile of tiles) { - const chunkPosition: MapChunkPosition = [ - math.floor((tile.position.x / 32)), - math.floor((tile.position.y / 32)), - ] + const chunkPosition = Converters.tilePositionToChunkPosition(tile.position) if (!mapChunkPositionToTiles.has(chunkPosition)) { mapChunkPositionToTiles.set(chunkPosition, []) } diff --git a/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts b/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts index 73dd991..109e32a 100644 --- a/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts @@ -1,4 +1,3 @@ -import PacketEmitter from "../emitting/PacketEmitter"; import { EntityItemGroup, FactorioPrototype, @@ -16,7 +15,6 @@ export function emitPrototypes() { const mapTileProtos: PrototypesByType = getMapTilePrototypes() emit(mapTileProtos) - const entityProtos: PrototypesByType = getEntityPrototypes() emit(entityProtos) } @@ -58,7 +56,7 @@ function getEntityPrototypes(): PrototypesByType { const protos: PrototypesByType = {} for (const [, entity] of game.entity_prototypes) { - const key: string = `${entity.group.name}/${entity.subgroup.name}` + const key: string = `${entity.group.name}/${entity.subgroup.name}/${entity.type}` protos[key] ??= [] @@ -73,7 +71,9 @@ function getEntityPrototypes(): PrototypesByType { isEntityWithOwner: entity.is_entity_with_owner, isMilitaryTarget: entity.is_military_target, maxHealth: entity.max_health, + collisionBox: Converters.collisionBox(entity.collision_box), } + entity.infinite_resource if (entity.map_color != undefined) { entityProto.mapColour = Converters.mapColour(entity.map_color) diff --git a/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts index cd0ee06..4bc1d43 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts @@ -3,10 +3,10 @@ import {Converters} from "./converters"; import {handleSurfaceUpdate} from "./surfaceUpdates"; import EventCacheService from "../emitting/EventDataCache"; import MapChunkUpdate from "./handlers/MapChunkUpdateHandler"; -import EventDataQueue from "../queue/queue"; import KafkatorioPacketQueue from "../emitting/KafkatorioPacketQueue"; import PacketEmitter from "../emitting/PacketEmitter"; import {KafkatorioPacketData} from "../../generated/kafkatorio-schema"; +import EventDataQueue from "../emitting/EventDataQueue"; script.on_event(defines.events.on_tick, (event: OnTickEvent) => { diff --git a/modules/events-mod/src/main/typescript/main/global-init.ts b/modules/events-mod/src/main/typescript/main/global-init.ts index 21b366b..3e63718 100644 --- a/modules/events-mod/src/main/typescript/main/global-init.ts +++ b/modules/events-mod/src/main/typescript/main/global-init.ts @@ -1,5 +1,5 @@ import EventUpdates from "./emitting/EventDataCache"; -import {EventDataQueueManager} from "./queue/queue"; +import {EventDataQueueManager} from "./emitting/EventDataQueue"; export function initGlobal(force: boolean = false) { diff --git a/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts b/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts index f5caa89..3f53bcd 100644 --- a/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts +++ b/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts @@ -8,6 +8,7 @@ export class KafkatorioSettingsConfig { "kafkatorio.packet.keyed.PlayerUpdate": 0.5, "kafkatorio.packet.keyed.MapChunkTileUpdate": 30, "kafkatorio.packet.keyed.MapChunkEntityUpdate": 30, + "kafkatorio.packet.keyed.MapChunkResourceUpdate": 30, "kafkatorio.packet.keyed.EntityUpdate": 5, } diff --git a/modules/events-mod/tsconfig.json b/modules/events-mod/tsconfig.json index eaf883f..9526305 100644 --- a/modules/events-mod/tsconfig.json +++ b/modules/events-mod/tsconfig.json @@ -24,20 +24,20 @@ "forceConsistentCasingInFileNames": true, "listEmittedFiles": true, "listFiles": true, + "noFallthroughCasesInSwitch": true, "noImplicitAny": true, + "noImplicitOverride": true, + "noImplicitReturns": true, "noImplicitThis": true, "sourceMap": false, "strict": true, "strictFunctionTypes": true, "strictNullChecks": true, - "traceResolution": true, - "noImplicitReturns": true, - "noImplicitOverride": true, - "noFallthroughCasesInSwitch": true + "traceResolution": false }, "tstl": { "luaTarget": "5.2", - "tstlVerbose": true, + "tstlVerbose": false, "noHeader": true, "noImplicitSelf": true, "sourceMapTraceback": false, diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt index 1df2ddf..b9c9db1 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt @@ -20,12 +20,10 @@ suspend fun main(): Unit = coroutineScope { startWebServer(appProps, websocketServer) } - launch { syslogSocketServer.start() } - launch { eventsProcessor(appProps, syslogSocketServer, websocketServer) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/DebounceProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/DebounceProcessor.kt index de17abb..b3cd20f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/DebounceProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/DebounceProcessor.kt @@ -20,19 +20,15 @@ import org.apache.kafka.streams.state.StoreBuilder import org.apache.kafka.streams.state.Stores import org.apache.kafka.streams.state.TimestampedKeyValueStore import org.apache.kafka.streams.state.ValueAndTimestamp -import java.time.Duration as DurationJvm -import kotlin.time.Duration as DurationKt +import kotlin.time.Duration class DebounceProcessor( - private val inactivityDuration: DurationKt, - checkInterval: DurationKt, + private val inactivityDuration: Duration, + private val checkInterval: Duration, private val storeName: String, ) : Processor { - - private val checkInterval: DurationJvm = checkInterval.toJavaDuration() - private lateinit var state: State @@ -70,7 +66,7 @@ class DebounceProcessor( ) : State { val store: TimestampedKeyValueStore = context.getStateStore(storeName) val schedule: Cancellable = context.schedule( - checkInterval, + checkInterval.toJavaDuration(), PunctuationType.WALL_CLOCK_TIME, ::checkRecords ) @@ -95,8 +91,8 @@ class DebounceProcessor( sourceTopic: String, sinkTopic: String, - inactivityDuration: DurationKt, - checkInterval: DurationKt = inactivityDuration / 10, + inactivityDuration: Duration, + checkInterval: Duration = inactivityDuration / 10, keySerde: Serde, valueSerde: Serde, storeName: String = "$namePrefix.debounce-store", @@ -131,8 +127,8 @@ class DebounceProcessor( } class Supplier( - private val inactivityDuration: DurationKt, - private val checkInterval: DurationKt, + private val inactivityDuration: Duration, + private val checkInterval: Duration, private val storeName: String, private val keySerde: Serde, private val valueSerde: Serde, diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt index f1c547d..4d05dcf 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt @@ -1,12 +1,24 @@ package dev.adamko.kafkatorio.server.processor import com.github.palindromicity.syslog.dsl.SyslogFieldKeys +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.common.PrototypeHashCode +import dev.adamko.kafkatorio.schema.common.ServerMapChunkId +import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer +import dev.adamko.kafkatorio.schema.packets.MapChunkEntityUpdate +import dev.adamko.kafkatorio.schema.packets.MapChunkResourceUpdate +import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import dev.adamko.kafkatorio.server.config.ApplicationProperties +import dev.adamko.kafkatorio.server.processor.topology.ServerMapChunkTiles import dev.adamko.kafkatorio.server.processor.topology.broadcastToWebsocket +import dev.adamko.kafkatorio.server.processor.topology.colourEntityChunks import dev.adamko.kafkatorio.server.processor.topology.colourMapChunks +import dev.adamko.kafkatorio.server.processor.topology.convertEntityUpdateToServerMapChunkTiles +import dev.adamko.kafkatorio.server.processor.topology.convertResourceUpdateToServerMapChunkTiles import dev.adamko.kafkatorio.server.processor.topology.factorioServerPacketStream import dev.adamko.kafkatorio.server.processor.topology.saveMapTiles import dev.adamko.kafkatorio.server.processor.topology.splitFactorioServerPacketStream +import dev.adamko.kafkatorio.server.processor.topology.streamPacketData import dev.adamko.kafkatorio.server.socket.SyslogSocketServer import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer import java.util.Properties @@ -35,6 +47,7 @@ import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.StreamsConfig import org.apache.kafka.streams.Topology import org.apache.kafka.streams.TopologyDescription +import org.apache.kafka.streams.kstream.KStream internal class KafkatorioTopology( @@ -50,6 +63,19 @@ internal class KafkatorioTopology( splitPackets() groupTilesMapChunks() + + groupEntitiesMapChunks( + layer = ServerMapTileLayer.BUILDING, + colouredUpdatesStreamTopic = TOPIC_MAP_CHUNK_BUILDING_COLOURED_032_UPDATES, + colouredChunkStateTopic = TOPIC_MAP_CHUNK_BUILDING_COLOURED_STATE, + ) + + groupEntitiesMapChunks( + layer = ServerMapTileLayer.RESOURCE, + colouredUpdatesStreamTopic = TOPIC_MAP_CHUNK_RESOURCE_COLOURED_032_UPDATES, + colouredChunkStateTopic = TOPIC_MAP_CHUNK_RESOURCE_COLOURED_STATE, + ) + saveTiles() websocketBroadcaster() @@ -69,10 +95,53 @@ internal class KafkatorioTopology( } + /** Terrain tiles */ private suspend fun groupTilesMapChunks() { val builder = StreamsBuilder() - val topology = colourMapChunks(builder) - launchTopology("groupTilesMapChunks", topology) + + val protosStream: KStream = + builder.streamPacketData() + + val topology = colourMapChunks(builder, protosStream) + + launchTopology("groupTilesMapChunks.${ServerMapTileLayer.TERRAIN.dir}", topology) + } + + + /** Building and resource tiles */ + private suspend fun groupEntitiesMapChunks( + layer: ServerMapTileLayer, + colouredUpdatesStreamTopic: String, + colouredChunkStateTopic: String, + ) { + val builder = StreamsBuilder() + + val entityChunksStream: KStream> = + when (layer) { + ServerMapTileLayer.TERRAIN -> return + + ServerMapTileLayer.RESOURCE -> + builder.streamPacketData() + .convertResourceUpdateToServerMapChunkTiles("groupEntitiesMapChunks.${layer.dir}") + + ServerMapTileLayer.BUILDING -> + builder.streamPacketData() + .convertEntityUpdateToServerMapChunkTiles("groupEntitiesMapChunks.${layer.dir}") + } + + val protosStream: KStream = + builder.streamPacketData() + + val topology = colourEntityChunks( + builder, + entityChunksStream, + protosStream, + layer, + colouredUpdatesStreamTopic, + colouredChunkStateTopic, + ) + + launchTopology("groupTilesMapChunks.${layer.dir}", topology) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt index 8eb65a3..e61f270 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt @@ -5,7 +5,9 @@ import dev.adamko.kafkatorio.schema.packets.ConsoleChatUpdate import dev.adamko.kafkatorio.schema.packets.ConsoleCommandUpdate import dev.adamko.kafkatorio.schema.packets.EntityUpdate import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData +import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketDataError import dev.adamko.kafkatorio.schema.packets.MapChunkEntityUpdate +import dev.adamko.kafkatorio.schema.packets.MapChunkResourceUpdate import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate @@ -17,14 +19,21 @@ private const val DOMAIN = "kafkatorio" const val TOPIC_SRC_SERVER_LOG = "$DOMAIN.src.server-log" -const val TOPIC_GROUPED_MAP_CHUNKS_STATE = "$DOMAIN.state.map-chunks.grouped" +//const val TOPIC_GROUPED_MAP_CHUNKS_STATE = "$DOMAIN.state.map-chunks.grouped" -const val TOPIC_MAP_CHUNK_COLOURED_032_STATE = "$DOMAIN.state.map-chunk-032.colour" +const val TOPIC_MAP_CHUNK_TERRAIN_COLOURED_032_UPDATES = + "$DOMAIN.state-updates.map-chunk-032.terrain.colour" +const val TOPIC_MAP_CHUNK_RESOURCE_COLOURED_032_UPDATES = + "$DOMAIN.state-updates.map-chunk-032.resource.colour" +const val TOPIC_MAP_CHUNK_BUILDING_COLOURED_032_UPDATES = + "$DOMAIN.state-updates.map-chunk-032.building.colour" -const val TOPIC_MAP_CHUNK_COLOURED_STATE = "$DOMAIN.state.map-chunk.colour" +const val TOPIC_MAP_CHUNK_TERRAIN_COLOURED_STATE = "$DOMAIN.state.map-chunk.terrain.colour" +const val TOPIC_MAP_CHUNK_RESOURCE_COLOURED_STATE = "$DOMAIN.state.map-chunk.resource.colour" +const val TOPIC_MAP_CHUNK_BUILDING_COLOURED_STATE = "$DOMAIN.state.map-chunk.building.colour" -const val TOPIC_SUBDIVIDED_MAP_TILES = "$DOMAIN.map-tiles.subdivided" -const val TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED = "$TOPIC_SUBDIVIDED_MAP_TILES.debounced" +//const val TOPIC_SUBDIVIDED_MAP_TILES = "$DOMAIN.map-tiles.subdivided" +//const val TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED = "$TOPIC_SUBDIVIDED_MAP_TILES.debounced" /** Broadcast these events out, via websocket */ @@ -33,14 +42,18 @@ const val TOPIC_BROADCAST_TO_WEBSOCKET = "$DOMAIN.broadcast.websocket" fun allTopics(): Set = buildSet { add(TOPIC_SRC_SERVER_LOG) - add(TOPIC_GROUPED_MAP_CHUNKS_STATE) +// add(TOPIC_GROUPED_MAP_CHUNKS_STATE) - add(TOPIC_MAP_CHUNK_COLOURED_032_STATE) + add(TOPIC_MAP_CHUNK_TERRAIN_COLOURED_032_UPDATES) + add(TOPIC_MAP_CHUNK_RESOURCE_COLOURED_032_UPDATES) + add(TOPIC_MAP_CHUNK_BUILDING_COLOURED_032_UPDATES) - add(TOPIC_MAP_CHUNK_COLOURED_STATE) + add(TOPIC_MAP_CHUNK_TERRAIN_COLOURED_STATE) + add(TOPIC_MAP_CHUNK_RESOURCE_COLOURED_STATE) + add(TOPIC_MAP_CHUNK_BUILDING_COLOURED_STATE) - add(TOPIC_SUBDIVIDED_MAP_TILES) - add(TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED) +// add(TOPIC_SUBDIVIDED_MAP_TILES) +// add(TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED) add(TOPIC_BROADCAST_TO_WEBSOCKET) @@ -49,16 +62,17 @@ fun allTopics(): Set = buildSet { val KafkatorioPacketData.topicName: String get() = when (this) { - is ConfigurationUpdate -> packetTopicNames.getValue(ConfigurationUpdate::class) - is ConsoleChatUpdate -> packetTopicNames.getValue(ConsoleChatUpdate::class) - is ConsoleCommandUpdate -> packetTopicNames.getValue(ConsoleCommandUpdate::class) - is PrototypesUpdate -> packetTopicNames.getValue(PrototypesUpdate::class) - is SurfaceUpdate -> packetTopicNames.getValue(SurfaceUpdate::class) - is EntityUpdate -> packetTopicNames.getValue(EntityUpdate::class) - is MapChunkTileUpdate -> packetTopicNames.getValue(MapChunkTileUpdate::class) - is PlayerUpdate -> packetTopicNames.getValue(PlayerUpdate::class) - is KafkatorioPacketData.Error -> packetTopicNames.getValue(KafkatorioPacketData.Error::class) - is MapChunkEntityUpdate -> packetTopicNames.getValue(MapChunkEntityUpdate::class) + is ConfigurationUpdate -> packetTopicNames.getValue(ConfigurationUpdate::class) + is ConsoleChatUpdate -> packetTopicNames.getValue(ConsoleChatUpdate::class) + is ConsoleCommandUpdate -> packetTopicNames.getValue(ConsoleCommandUpdate::class) + is PrototypesUpdate -> packetTopicNames.getValue(PrototypesUpdate::class) + is SurfaceUpdate -> packetTopicNames.getValue(SurfaceUpdate::class) + is EntityUpdate -> packetTopicNames.getValue(EntityUpdate::class) + is MapChunkTileUpdate -> packetTopicNames.getValue(MapChunkTileUpdate::class) + is PlayerUpdate -> packetTopicNames.getValue(PlayerUpdate::class) + is KafkatorioPacketDataError -> packetTopicNames.getValue(KafkatorioPacketDataError::class) + is MapChunkEntityUpdate -> packetTopicNames.getValue(MapChunkEntityUpdate::class) + is MapChunkResourceUpdate -> packetTopicNames.getValue(MapChunkResourceUpdate::class) } @@ -72,7 +86,8 @@ private val packetTopicNames: Map, String> = ma MapChunkTileUpdate::class to "map-chunk-tile", PlayerUpdate::class to "player", MapChunkEntityUpdate::class to "map-chunk-entity", - KafkatorioPacketData.Error::class to "error", + MapChunkResourceUpdate::class to "map-chunk-resource", + KafkatorioPacketDataError::class to "error", ).mapValues { (_, v) -> "$DOMAIN.packet.$v" } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt index c7f02cd..9bcf517 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt @@ -1,17 +1,20 @@ package dev.adamko.kafkatorio.server.processor.topology import dev.adamko.kafkatorio.library.kxsBinary +import dev.adamko.kafkatorio.library.resize +import dev.adamko.kafkatorio.library.toMapChunkPosition import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.common.MapTilePosition +import dev.adamko.kafkatorio.schema.common.PrototypeHashCode import dev.adamko.kafkatorio.schema.common.ServerMapChunkId -import dev.adamko.kafkatorio.schema.common.leftTopTile -import dev.adamko.kafkatorio.schema.common.toMapChunkPosition +import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import dev.adamko.kafkatorio.server.processor.DebounceProcessor.Companion.addDebounceProcessor -import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_032_STATE -import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_STATE +import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_TERRAIN_COLOURED_032_UPDATES +import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_TERRAIN_COLOURED_STATE import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedAs @@ -19,8 +22,8 @@ import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.repartitionedAs import dev.adamko.kotka.extensions.stream import dev.adamko.kotka.extensions.streams.filter +import dev.adamko.kotka.extensions.streams.flatMap import dev.adamko.kotka.extensions.streams.map -import dev.adamko.kotka.extensions.streams.mapValues import dev.adamko.kotka.extensions.streams.peek import dev.adamko.kotka.extensions.streams.reduce import dev.adamko.kotka.extensions.tableJoined @@ -36,27 +39,27 @@ import org.apache.kafka.streams.kstream.KStream import org.apache.kafka.streams.kstream.KTable -private const val pid: String = "colourMapChunks" - - /** Add colour to each [MapChunkTileUpdate] */ -fun colourMapChunks(builder: StreamsBuilder): Topology { +fun colourMapChunks( + builder: StreamsBuilder, + protosStream: KStream +): Topology { + val pid = "colourMapChunks.terrain" val mapChunksStream: KStream = builder.streamPacketData() - val protosStream: KStream = builder.streamPacketData() val protosTable: KTable = protosStream.createTilePrototypeTable() val chunkTilesColouredTable032: KTable> = mapChunksStream - .convertToServerMapChunkTiles() - .reduceServerMapChunkTilesToTable() - .enrichWithColourData(protosTable) + .convertToServerMapChunkTiles(pid) + .reduceServerMapChunkTilesToTable(pid) + .enrichWithColourData(pid, protosTable) chunkTilesColouredTable032.streamMapChunkColouredTo( - ChunkSize.CHUNK_032, - TOPIC_MAP_CHUNK_COLOURED_032_STATE, + "$pid.${ChunkSize.CHUNK_032}", + TOPIC_MAP_CHUNK_TERRAIN_COLOURED_032_UPDATES, ) val chunkTilesColoured: KStream> = @@ -66,7 +69,7 @@ fun colourMapChunks(builder: StreamsBuilder): Topology { kxsBinary.serde(ServerMapChunkId.serializer()), kxsBinary.serde(ServerMapChunkTiles.serializer(ColourHex.serializer())), ), - TOPIC_MAP_CHUNK_COLOURED_STATE, + TOPIC_MAP_CHUNK_TERRAIN_COLOURED_STATE, ) mapOf( @@ -77,71 +80,78 @@ fun colourMapChunks(builder: StreamsBuilder): Topology { ChunkSize.CHUNK_032 to ChunkSize.CHUNK_256, ChunkSize.CHUNK_256 to ChunkSize.CHUNK_512, - - ).forEach { (from, to) -> + ).forEach { (from, to) -> chunkTilesColoured - .filter("$pid.combine-chunks.filter-$from-to-$to") { key, _ -> + .filter("$pid.combine-chunks.filter-$from-to-$to") { key: ServerMapChunkId, _: ServerMapChunkTiles -> key.chunkSize == from - }.groupByChunkPosition(to) - .streamMapChunkColouredTo(to, TOPIC_MAP_CHUNK_COLOURED_STATE) + }.groupByChunkPosition("$pid.from-$from-to-$to", to) + .streamMapChunkColouredTo( + "$pid.from-$from-to-$to", + TOPIC_MAP_CHUNK_TERRAIN_COLOURED_STATE + ) } return builder.build() .addDebounceProcessor( - namePrefix = "groupTilesMapChunks", - sourceTopic = TOPIC_MAP_CHUNK_COLOURED_032_STATE, - sinkTopic = TOPIC_MAP_CHUNK_COLOURED_STATE, - inactivityDuration = 5.seconds, + namePrefix = "groupMapChunks.terrain", + sourceTopic = TOPIC_MAP_CHUNK_TERRAIN_COLOURED_032_UPDATES, + sinkTopic = TOPIC_MAP_CHUNK_TERRAIN_COLOURED_STATE, + inactivityDuration = 15.seconds, keySerde = kxsBinary.serde(ServerMapChunkId.serializer()), valueSerde = kxsBinary.serde(ServerMapChunkTiles.serializer(ColourHex.serializer())), ) } -private fun KStream.convertToServerMapChunkTiles() - : KStream> { +private fun KStream.convertToServerMapChunkTiles( + callerPid: String +): KStream> { - val pid = "$pid.convertToMapTiles" + val pid = "$callerPid.convertToMapTiles" return map("$pid.map") { serverId: FactorioServerId, update: MapChunkTileUpdate -> val mapTileList = update.tileDictionary?.toMapTileList() ?: emptyList() - val (validMapTilesList, invalidMapTilesList) = mapTileList.partition { + val (validMapTiles, invalidMapTiles) = mapTileList.partition { it.position in update.key.chunkPosition } - if (invalidMapTilesList.isNotEmpty()) { - println("WARNING [reduceMapTilesToTable] MapChunkTileUpdate contained out-of-bounds tiles $invalidMapTilesList") + if (invalidMapTiles.isNotEmpty()) { + println( + "WARNING [$pid] MapChunkTileUpdate contained ${invalidMapTiles.size} out-of-bounds tiles, " + + "key: ${update.key},\n" + + "invalid tiles:" + invalidMapTiles.joinToString(limit = 10) + ) } - val validMapTilesToProtoHashCode = - validMapTilesList.associate { it.position to TileProtoHashCode(it) } + val validMapTilesToProtoHashCode = validMapTiles.associate { + it.position to PrototypeHashCode(it.protoId) + } val chunkId = ServerMapChunkId( serverId = serverId, + layer = ServerMapTileLayer.TERRAIN, chunkPosition = update.key.chunkPosition, surfaceIndex = update.key.surfaceIndex, - chunkSize = ChunkSize.CHUNK_032, ) - val chunkTiles = ServerMapChunkTiles(chunkId, validMapTilesToProtoHashCode) - - chunkId to chunkTiles + chunkId to ServerMapChunkTiles(chunkId, validMapTilesToProtoHashCode) } } -private fun KStream>.reduceServerMapChunkTilesToTable() - : KTable> { +fun KStream>.reduceServerMapChunkTilesToTable( + callerPid: String, +): KTable> { - val pid = "$pid.reduceServerMapChunkTilesToTable" + val pid = "$callerPid.reduceServerMapChunkTilesToTable" return repartition( repartitionedAs( "$pid.pre-table-repartition", kxsBinary.serde(), - kxsBinary.serde>(), + kxsBinary.serde>(), // force, otherwise KTable-KTable FK join doesn't work numberOfPartitions = 1, ) @@ -149,14 +159,14 @@ private fun KStream>.re groupedAs( "$pid.group-by-key", kxsBinary.serde(), - kxsBinary.serde>(), + kxsBinary.serde>(), ) ).reduce( "$pid.reduce", materializedAs( "$pid.reduce.store", kxsBinary.serde(), - kxsBinary.serde>(), + kxsBinary.serde>(), ) ) { chunkTiles, otherChunkTiles -> chunkTiles + otherChunkTiles @@ -164,13 +174,14 @@ private fun KStream>.re } -private fun KTable>.enrichWithColourData( +private fun KTable>.enrichWithColourData( + callerPid: String, protosTable: KTable, ): KTable> { - val pid = "$pid.enrichWithColourData" + val pid = "$callerPid.enrichWithColourData" - return this.join( + return join( other = protosTable, tableJoined = tableJoined("$pid.join-tiles-with-prototypes"), materialized = materializedAs( @@ -178,26 +189,30 @@ private fun KTable>.enr kxsBinary.serde(), kxsBinary.serde(), ), - foreignKeyExtractor = { chunkTiles: ServerMapChunkTiles -> + foreignKeyExtractor = { chunkTiles: ServerMapChunkTiles -> chunkTiles.chunkId.serverId } - ) { tiles: ServerMapChunkTiles, colourDict: TileColourDict -> -// println("joining tiles:${tiles.map.size} with colourDict:${colourDict.map.size}") + ) { tiles: ServerMapChunkTiles, colourDict: TileColourDict -> + println("joining tiles:${tiles.map.size} with colourDict:${colourDict.size}") - val missingProtos = mutableSetOf() + val missingProtos = mutableSetOf() - val tileColours = tiles.map.mapValues { (_, code) -> - colourDict.getOrElse(code) { - missingProtos.add(code) - ColourHex.TRANSPARENT - } - } + val tileColours: Map = + tiles.map.mapNotNull { (position, code) -> + when (val colour = colourDict[code]) { + null -> { + missingProtos.add(code) + null + } + else -> position to colour + } + }.toMap() if (missingProtos.isNotEmpty()) { println("[$pid] missing ${missingProtos.size} tile prototypes: ${missingProtos.joinToString { "${it.code}" }}") } - println("[$pid] Set tile colours for chunk ${tiles.chunkId}") + println("[$pid] Set ${tileColours.size} tile colours for chunk ${tiles.chunkId}") ServerMapChunkTiles(tiles.chunkId, tileColours) } @@ -205,20 +220,16 @@ private fun KTable>.enr fun KTable>.streamMapChunkColouredTo( - chunkSize: ChunkSize, + callerPid: String, outputTopic: String, ) { - val pid = "$pid.output-chunk.${chunkSize.name}" + val pid = "$callerPid.output-chunk" toStream("$pid.stream") - .filter("$pid.filter-tiles-not-empty") { _, chunkTiles -> - !chunkTiles?.map.isNullOrEmpty() - } - .mapValues("$pid.map-not-null") { _, chunkTiles -> - requireNotNull(chunkTiles) - } - .peek("$pid.print-group-result") { _, chunkTiles -> - println("Grouping map tiles result: ${chunkTiles.chunkId} / size:${chunkTiles.map.size}") + .flatMap("$pid.group-by-chunks") { _: ServerMapChunkId, tiles: ServerMapChunkTiles? -> + reChunkTiles(pid, tiles) + }.peek("$pid.print-group-result") { _, chunkTiles -> + println("[$pid] Grouping map tiles result: ${chunkTiles.chunkId} / size:${chunkTiles.map.size}") }.to( outputTopic, producedAs( @@ -235,26 +246,22 @@ fun KTable>.streamMapChunkColou * * They should already be grouped, but do it again to make sure, and to filter out empty updates. */ -private fun KStream>.groupByChunkPosition( - chunkSize: ChunkSize = ChunkSize.CHUNK_032 +fun KStream>.groupByChunkPosition( + callerPid: String, + targetChunkSize: ChunkSize = ChunkSize.CHUNK_032 ): KTable> { - val pid = "$pid.groupByChunkPosition.${chunkSize.name}" + val pid = "$callerPid.groupByChunkPosition.${targetChunkSize.name}" - return map("$pid.change-chunk-size") { chunkId: ServerMapChunkId, chunkTiles: ServerMapChunkTiles? -> + return flatMap("$pid.change-chunk-size") { _: ServerMapChunkId, chunkTiles: ServerMapChunkTiles? -> +// println("[$pid] changing chunk size for $chunkId") + chunkTiles ?: return@flatMap emptyList() - val newChunkPosition = chunkId.chunkPosition - .leftTopTile(chunkId.chunkSize) - .toMapChunkPosition(chunkSize) + val newChunkPosition = chunkTiles.chunkId.chunkPosition.resize(targetChunkSize) + val newId = chunkTiles.chunkId.copy(chunkPosition = newChunkPosition) + val newChunkTiles = chunkTiles.copy(chunkId = newId) - val newId = chunkId.copy( - chunkSize = chunkSize, - chunkPosition = newChunkPosition, - ) - - val newChunkTiles = chunkTiles?.map ?: emptyMap() - - newId to ServerMapChunkTiles(chunkId = newId, map = newChunkTiles) + reChunkTiles(pid, newChunkTiles) }.groupByKey( groupedAs( "$pid.group-by-key", @@ -272,3 +279,51 @@ private fun KStream>.groupByChu chunkTiles + otherChunkTiles } } + + +fun reChunkTiles( + pid: String, + tiles: ServerMapChunkTiles?, +): List>> { + + return when { + tiles == null || tiles.map.isEmpty() -> emptyList() + + tiles.map.keys.all { it in tiles.chunkId.chunkPosition } -> listOf(tiles.chunkId to tiles) + + else -> { + val chunkId = tiles.chunkId + + val (boundedTiles, unboundedTiles) = tiles.map.entries.partition { (position, _) -> + position in chunkId.chunkPosition + } + + if (unboundedTiles.isNotEmpty()) { + val unboundedEntities = unboundedTiles.map { (_, entity) -> entity } + println( + "WARNING [$pid] MapChunkEntityUpdate $chunkId " + + "contained ${unboundedEntities.size} out-of-bounds entities " + + unboundedEntities.joinToString(limit = 10) + ) + } + + // the existing chunkId and its tiles + val boundedTilesChunk = + chunkId to ServerMapChunkTiles(chunkId, boundedTiles.associate { it.key to it.value }) + + // re-calculate a chunk for the out-of-bounds tiles + val chunkedUnboundedTiles = unboundedTiles + .map { it.key to it.value } + .groupBy { (position, _) -> + position.toMapChunkPosition(chunkId.chunkSize) + }.map { (newChunkPosition, tiles) -> + val newChunkId = chunkId.copy(chunkPosition = newChunkPosition) + newChunkId to ServerMapChunkTiles(newChunkId, tiles.toMap()) + } + + println("[$pid] re-bounded ${unboundedTiles.size} tiles into ${chunkedUnboundedTiles.size} chunks in $chunkId") + + listOf(boundedTilesChunk) + chunkedUnboundedTiles + } + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourResourceChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourResourceChunks.kt new file mode 100644 index 0000000..d4c5521 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourResourceChunks.kt @@ -0,0 +1,442 @@ +package dev.adamko.kafkatorio.server.processor.topology + +import dev.adamko.kafkatorio.library.kxsBinary +import dev.adamko.kafkatorio.library.toMapTilePosition +import dev.adamko.kafkatorio.schema.common.ChunkSize +import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.FactorioPrototype +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.common.MapBoundingBox +import dev.adamko.kafkatorio.schema.common.MapTilePosition +import dev.adamko.kafkatorio.schema.common.PrototypeHashCode +import dev.adamko.kafkatorio.schema.common.ServerMapChunkId +import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer +import dev.adamko.kafkatorio.schema.common.toHex +import dev.adamko.kafkatorio.schema.packets.MapChunkEntityUpdate +import dev.adamko.kafkatorio.schema.packets.MapChunkResourceUpdate +import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate +import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate +import dev.adamko.kafkatorio.server.processor.DebounceProcessor.Companion.addDebounceProcessor +import dev.adamko.kotka.extensions.consumedAs +import dev.adamko.kotka.extensions.materializedAs +import dev.adamko.kotka.extensions.stream +import dev.adamko.kotka.extensions.streams.filter +import dev.adamko.kotka.extensions.streams.flatMap +import dev.adamko.kotka.extensions.tableJoined +import dev.adamko.kotka.extensions.tables.join +import dev.adamko.kotka.kxs.serde +import kotlin.collections.component1 +import kotlin.collections.component2 +import kotlin.math.ceil +import kotlin.math.floor +import kotlin.time.Duration.Companion.seconds +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.Topology +import org.apache.kafka.streams.kstream.KStream +import org.apache.kafka.streams.kstream.KTable + + +/** + * Add colour to each [MapChunkTileUpdate] + * + * @param[colouredUpdatesStreamTopic] Output topic for the result of converting input updates into 32 sized chunks + * @param[colouredChunkStateTopic] Post-debounce state topic, used to recursively combine chunks + */ +fun colourEntityChunks( + builder: StreamsBuilder, + entityChunksStream: KStream>, + protosStream: KStream, + layer: ServerMapTileLayer, + colouredUpdatesStreamTopic: String, + colouredChunkStateTopic: String, +): Topology { + val pid = "colourEntityChunks.${layer.dir}" + + val protosTable: KTable = + protosStream.createEntityPrototypeMap(pid) + + val chunkEntitiesColouredTable032: KTable> = + entityChunksStream + .reduceServerMapChunkTilesToTable(pid) + .enrichWithColourData(pid, protosTable) + + chunkEntitiesColouredTable032.streamMapChunkColouredTo( + "$pid.${ChunkSize.CHUNK_032}", + colouredUpdatesStreamTopic, + ) + + val chunkTilesColoured: KStream> = + builder.stream( + consumedAs( + "$pid.consume.map-chunks-debounced", + kxsBinary.serde(ServerMapChunkId.serializer()), + kxsBinary.serde(ServerMapChunkTiles.serializer(ColourHex.serializer())), + ), + colouredChunkStateTopic, + ) + + mapOf( +// ChunkSize.CHUNK_032 to ChunkSize.CHUNK_064, +// ChunkSize.CHUNK_064 to ChunkSize.CHUNK_128, +// ChunkSize.CHUNK_128 to ChunkSize.CHUNK_256, +// ChunkSize.CHUNK_256 to ChunkSize.CHUNK_512, + + ChunkSize.CHUNK_032 to ChunkSize.CHUNK_256, + ChunkSize.CHUNK_256 to ChunkSize.CHUNK_512, + ).forEach { (from, to) -> + chunkTilesColoured + .filter("$pid.combine-chunks.filter-$from-to-$to") { key, _ -> + key.chunkSize == from && key.layer == layer + }.groupByChunkPosition(pid, to) + .streamMapChunkColouredTo( + "$pid.from-$from-to-$to", + colouredChunkStateTopic, + ) + } + + return builder.build().addDebounceProcessor( + namePrefix = "groupMapChunks.${layer.dir}", + sourceTopic = colouredUpdatesStreamTopic, + sinkTopic = colouredChunkStateTopic, + inactivityDuration = 15.seconds, + keySerde = kxsBinary.serde(ServerMapChunkId.serializer()), + valueSerde = kxsBinary.serde(ServerMapChunkTiles.serializer(ColourHex.serializer())), + ) +} + + +fun KStream.convertEntityUpdateToServerMapChunkTiles( + callerPid: String, +): KStream> { + + val pid = "$callerPid.convertToServerMapChunkTiles" + + return flatMap("$pid.map") { serverId: FactorioServerId, update: MapChunkEntityUpdate -> + +// val entities = update.entitiesXY.convert { entity, position -> +// FactorioEntityData.Standard( +// protoId = update.key.protoId, +// position = position, +// element = entity, +// ) +// } + +// val (validEntityPositions, unboundedEntityPositions) = entities.map { entity -> +// entity.position.toMapTilePosition() to entity +// }.partition { (position, _) -> +// position in update.key.chunkPosition +// } +// +// if (unboundedEntityPositions.isNotEmpty()) { +// val unboundedEntities = unboundedEntityPositions.map { (_, entity) -> entity } +// println( +// "WARNING [convertToServerMapChunkTiles] MapChunkEntityUpdate ${update.key} " + "contained ${unboundedEntities.size} out-of-bounds entities " + unboundedEntities.joinToString( +// limit = 10 +// ) +// ) +// } +// +// // TODO There might be multiple resources per tile position, therefore this will arbitrarily +// // exclude resources. Maybe change it from a Map to a List? Or have multiple resources per +// // tile position? +// val mapValidEntitiesToPrototypeHash = validEntityPositions.associate { (pos, resource) -> +// pos to PrototypeHashCode(resource.protoId) +// } + + val entitiesToPrototypeHash = update.entities().associate { entity -> + entity.position.toMapTilePosition() to PrototypeHashCode(entity.protoId) + } + + val chunkId = ServerMapChunkId( + serverId = serverId, + layer = ServerMapTileLayer.BUILDING, + chunkPosition = update.key.chunkPosition, + surfaceIndex = update.key.surfaceIndex, + ) + + val tiles = ServerMapChunkTiles(chunkId, entitiesToPrototypeHash) + + reChunkTiles(pid, tiles) + } +} + + +fun KStream.convertResourceUpdateToServerMapChunkTiles( + callerPid: String, +): KStream> { + + val pid = "$callerPid.convertResourceUpdateToChunkTiles" + + return flatMap("$pid.map") { serverId: FactorioServerId, update: MapChunkResourceUpdate -> + +// // TODO There might be multiple resources per tile position, therefore this will arbitrarily +// // exclude resources. Maybe change it from a Map to a List? Or have multiple resources per +// // tile position? +// val mapValidEntitiesToPrototypeHash = validEntityPositions.associate { (pos, resource) -> +// pos to PrototypeHashCode(resource.protoId) +// } + + val entitiesToPrototypeHash = update.resources().associate { entity -> + entity.position.toMapTilePosition() to PrototypeHashCode(entity.protoId) + } + + val chunkId = ServerMapChunkId( + serverId = serverId, + layer = ServerMapTileLayer.RESOURCE, + chunkPosition = update.key.chunkPosition, + surfaceIndex = update.key.surfaceIndex, + ) + + val tiles = ServerMapChunkTiles(chunkId, entitiesToPrototypeHash) + + reChunkTiles(pid, tiles) + } +} + + +//private fun KStream>.reduceServerMapResourceTilesToTable() +// : KTable> { +// +// val pid = "$pid.reduceServerMapResourceTilesToTable" +// +// return repartition( +// repartitionedAs( +// "$pid.pre-table-repartition", +// kxsBinary.serde(), +// kxsBinary.serde>(), +// // force, otherwise KTable-KTable FK join doesn't work +// numberOfPartitions = 1, +// ) +// ).groupByKey( +// groupedAs( +// "$pid.group-by-key", +// kxsBinary.serde(), +// kxsBinary.serde>(), +// ) +// ).reduce( +// "$pid.reduce", +// materializedAs( +// "$pid.reduce.store", +// kxsBinary.serde(), +// kxsBinary.serde>(), +// ) +// ) { chunkTiles, otherChunkTiles -> +// chunkTiles + otherChunkTiles +// } +//} + + +private fun KTable>.enrichWithColourData( + callerPid: String, + protosTable: KTable, +): KTable> { + + val pid = "$callerPid.enrichWithColourData" + + return join( + other = protosTable, + tableJoined = tableJoined("$pid.join-tiles-with-prototypes"), + materialized = materializedAs( + "$pid.join-tiles-with-prototypes.store", + kxsBinary.serde(), + kxsBinary.serde(), + ), + foreignKeyExtractor = { chunkTiles: ServerMapChunkTiles -> + chunkTiles.chunkId.serverId + }) { tiles: ServerMapChunkTiles, prototypes: EntityPrototypeMap -> + println("joining tiles:${tiles.map.size} with prototypes:${prototypes.size}") + + val missingProtos = mutableSetOf() + + val tileColours: Map = buildList { + tiles.map.forEach { (position, code) -> + when (val proto = prototypes[code]) { + + null -> missingProtos += code + + else -> when (val box = proto.collisionBox) { + + null -> add(position to proto.mapColour()) + + else -> box.iterator(position).forEach { entitySubTile -> + add(entitySubTile to proto.mapColour()) + } + } + } + } + }.fold(mapOf()) { acc, (pos, colour) -> + // merge overlapping colours + val newColour = when (val existing = acc[pos]) { + null -> colour + else -> (existing / 2u) + (colour / 2u) + } + acc + (pos to newColour) + } + + if (missingProtos.isNotEmpty()) { + println("[$pid] missing ${missingProtos.size} tile prototypes: ${missingProtos.joinToString { "${it.code}" }}") + } + + println("[$pid] Set ${tileColours.size} tile colours for chunk ${tiles.chunkId}") + + ServerMapChunkTiles(tiles.chunkId, tileColours) + } +} + + +private fun MapBoundingBox.iterator(origin: MapTilePosition): Iterator { + + val xOffset: Int = floor(tileWidth.toDouble() / 2).toInt() + val startX = origin.x - xOffset + val endX = origin.x + xOffset + + val yOffset: Int = floor(tileHeight.toDouble() / 2).toInt() + val startY = origin.y - yOffset + val endY = origin.y + yOffset + + return iterator { + for (x in (startX..endX)) { + for (y in (startY..endY)) { // screen coordinates = +y points to the floor, -y to the ceiling + yield(MapTilePosition(x, y)) + } + } + } +} + + +/** + * Rounds a number 'up', away from zero. + * (Towards positive infinity if positive, and towards negative infinity if negative.) + */ +private fun Double.roundToInfinity(): Int = when { + this > 0 -> ceil(this).toInt() + this < 0 -> floor(this).toInt() + else -> 0 +} +// ceil(abs(this)).toInt() * this.sign.toInt() + + +private fun FactorioPrototype.Entity.mapColour(): ColourHex = + (colour ?: mapColour ?: mapColourFriend)?.toHex() ?: ColourHex.WHITE + + +private operator fun ColourHex.div(divisor: UInt): ColourHex = copy( + red = (red / divisor).toUByte(), + green = (green / divisor).toUByte(), + blue = (blue / divisor).toUByte(), + alpha = (alpha / divisor).toUByte(), +) + + +private operator fun ColourHex.plus(other: ColourHex): ColourHex = copy( + red = (red + other.red).toUByte(), + green = (green + other.green).toUByte(), + blue = (blue + other.blue).toUByte(), + alpha = (alpha + other.alpha).toUByte(), +) + + +//// https://stackoverflow.com/a/9355778/4161471 +//private operator fun ColourHex.plus(other: ColourHex): ColourHex { +// +// @Suppress("LocalVariableName") +// val `255` = UByte.MAX_VALUE +// +// val compositeAlpha: UByte = ( +// `255` - ((`255` - other.alpha) * (`255` - this.alpha)) / `255` +// ).toUByte() +// +// if (compositeAlpha == UByte.MIN_VALUE) { +// return ColourHex.TRANSPARENT +// } else { +// +// fun compositeColour( +// colour: (ColourHex) -> UByte, +// ): UByte { +// val colour1 = colour(this) +// val colour2 = colour(other) +// return (( +// ( +// ( colour2 * other.alpha) + (colour1 * this.alpha * ( other.alpha)) +// ) / compositeAlpha +// ) / `255` +// ).toUByte() +// } +// +// return ColourHex( +// compositeColour(ColourHex::red), +// compositeColour(ColourHex::green), +// compositeColour(ColourHex::blue), +// compositeAlpha, +// ) +// } +//} + +//private fun KTable>.streamMapChunkColouredTo( +// chunkSize: ChunkSize, +// outputTopic: String, +//) { +// val pid = "$pid.output-chunk.${chunkSize.name}" +// +// toStream("$pid.stream") +// .filter("$pid.filter-tiles-not-empty") { _, chunkTiles -> +// !chunkTiles?.map.isNullOrEmpty() +// } +// .mapValues("$pid.map-not-null") { _, chunkTiles -> +// requireNotNull(chunkTiles) +// } +// .peek("$pid.print-group-result") { _, chunkTiles -> +// println("Grouping map tiles result: ${chunkTiles.chunkId} / size:${chunkTiles.map.size}") +// }.to( +// outputTopic, +// producedAs( +// "$pid.grouped-map-chunks", +// kxsBinary.serde(), +// kxsBinary.serde>(), +// ) +// ) +//} + + +///** +// * Group [MapChunkTileUpdate]s by the Chunk position. +// * +// * They should already be grouped, but do it again to make sure, and to filter out empty updates. +// */ +//private fun KStream>.groupByChunkPosition( +// chunkSize: ChunkSize = ChunkSize.CHUNK_032 +//): KTable> { +// +// val pid = "$pid.groupByChunkPosition.${chunkSize.name}" +// +// return map("$pid.change-chunk-size") { chunkId: ServerMapChunkId, chunkTiles: ServerMapChunkTiles? -> +// +// val newChunkPosition = chunkId.chunkPosition +// .leftTopTile(chunkId.chunkSize) +// .toMapChunkPosition(chunkSize) +// +// val newId = chunkId.copy( +// chunkSize = chunkSize, +// chunkPosition = newChunkPosition, +// ) +// +// val newChunkTiles = chunkTiles?.map ?: emptyMap() +// +// newId to ServerMapChunkTiles(chunkId = newId, map = newChunkTiles) +// }.groupByKey( +// groupedAs( +// "$pid.group-by-key", +// kxsBinary.serde(), +// kxsBinary.serde>(), +// ) +// ).reduce( +// "$pid.reduce", +// materializedAs( +// "$pid.reduce.store", +// kxsBinary.serde(), +// kxsBinary.serde>(), +// ) +// ) { chunkTiles, otherChunkTiles -> +// chunkTiles + otherChunkTiles +// } +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt index c7e4ae1..cfb4567 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt @@ -3,7 +3,7 @@ package dev.adamko.kafkatorio.server.processor.topology import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket -import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData +import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketDataError import dev.adamko.kafkatorio.server.config.jsonMapper import dev.adamko.kafkatorio.server.processor.TOPIC_SRC_SERVER_LOG import dev.adamko.kafkatorio.server.processor.topicName @@ -38,20 +38,18 @@ fun factorioServerPacketStream( KafkatorioPacket( modVersion = "unknown", tick = Tick(0u), - data = KafkatorioPacketData.Error( + data = KafkatorioPacketDataError( message = e.message, rawValue = value, ) ) } - if (packet.data is KafkatorioPacketData.Error) { + if (packet.data is KafkatorioPacketDataError) { println("error parsing $TOPIC_SRC_SERVER_LOG message: ${packet.data}") } FactorioServerId(serverId) to packet - }.filter { _, value -> - value.data !is KafkatorioPacketData.Error } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/model.kt index 72aa0ca..e2f158a 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/model.kt @@ -10,7 +10,7 @@ import kotlinx.serialization.Serializable @Serializable -data class ServerMapChunkTiles( +data class ServerMapChunkTiles( val chunkId: ServerMapChunkId, val map: Map, ) { @@ -19,7 +19,7 @@ data class ServerMapChunkTiles( val MapTile.position - get() = MapTilePosition(x, y) + get() = MapTilePosition(x = x, y = y) val TRANSPARENT_AWT: Color = ColourHex.TRANSPARENT.toRgbColor().awt() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/prototypes.kt index 825f7b7..848ea69 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/prototypes.kt @@ -2,36 +2,34 @@ package dev.adamko.kafkatorio.server.processor.topology import dev.adamko.kafkatorio.library.kxsBinary import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.FactorioEntityData import dev.adamko.kafkatorio.schema.common.FactorioPrototype import dev.adamko.kafkatorio.schema.common.FactorioServerId -import dev.adamko.kafkatorio.schema.common.MapTile +import dev.adamko.kafkatorio.schema.common.PrototypeHashCode +import dev.adamko.kafkatorio.schema.common.PrototypeId import dev.adamko.kafkatorio.schema.common.toHex import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate +import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedAs -import dev.adamko.kotka.extensions.repartitionedAs -import dev.adamko.kotka.extensions.streams.filter +import dev.adamko.kotka.extensions.materializedWith +import dev.adamko.kotka.extensions.* +import dev.adamko.kotka.extensions.streams.* import dev.adamko.kotka.extensions.streams.mapValues import dev.adamko.kotka.extensions.streams.toTable +import dev.adamko.kotka.extensions.tables.* import dev.adamko.kotka.kxs.serde import kotlinx.serialization.Serializable import org.apache.kafka.streams.kstream.KStream import org.apache.kafka.streams.kstream.KTable -/** Use the hashcode of Prototypes names as keys - more efficient storage */ -@JvmInline -@Serializable -value class TileProtoHashCode private constructor(val code: Int) { - constructor(tile: MapTile) : this(tile.protoId.hashCode()) - constructor(tile: FactorioPrototype.MapTile) : this(tile.protoId.hashCode()) -} - - @JvmInline @Serializable value class TileColourDict( - private val map: Map -) : Map by map + private val map: Map +) : Map by map { + operator fun plus(other: TileColourDict): TileColourDict = TileColourDict(this.map + other.map) +} /** Get the latest map-tile colours per server. */ @@ -46,7 +44,7 @@ fun KStream.createTilePrototypeTable() val map = protoPacket .prototypes .filterIsInstance() - .associate { TileProtoHashCode(it) to it.mapColour.toHex() } + .associate { PrototypeHashCode(it) to it.mapColour.toHex() } TileColourDict(map) }.filter("$pid.filterMapTileProtos") { _, dict: TileColourDict -> @@ -70,3 +68,71 @@ fun KStream.createTilePrototypeTable() ) ) } + + +@JvmInline +@Serializable +value class EntityPrototypeMap( + private val map: Map +) : Map by map { + operator fun plus(other: EntityPrototypeMap): EntityPrototypeMap = + EntityPrototypeMap(this.map + other.map) + + operator fun get(protoId: PrototypeId): FactorioPrototype.Entity? = + map[PrototypeHashCode(protoId)] + + operator fun get(entity: FactorioEntityData): FactorioPrototype.Entity? = + map[PrototypeHashCode(entity.protoId)] +} + + +/** Get the latest entity colours per server. */ +fun KStream.createEntityPrototypeMap( + callerPid: String +): KTable { + + val pid = "$callerPid.createEntityPrototypeMap" + + return mapValues("$pid.colour-dict.build") { _, protoPacket: PrototypesUpdate -> + val map = protoPacket + .prototypes + .filterIsInstance() + .associateBy { entityProto -> + PrototypeHashCode(entityProto) + } + + EntityPrototypeMap(map) + }.filter("$pid.filterEntityProtos") { _, dict: EntityPrototypeMap -> + dict.isNotEmpty() + }.groupByKey(groupedAs("$pid.group-by-key")) + .reduce( + "$pid.merge", + materializedWith( + kxsBinary.serde(), + kxsBinary.serde(), + ) + ) { dict1: EntityPrototypeMap, dict2: EntityPrototypeMap -> + dict1 + dict2 + }.toStream("$pid.") + .filter("$pid.not-null.filter") { _, v -> v != null } + .mapValues("$pid.not-null.require") { _, value -> + requireNotNull(value) + }.peek { serverId, dict: EntityPrototypeMap -> + println("$pid: server $serverId has EntityPrototypeMap (size:${dict.size}): ${dict.entries.joinToString()}") + }.repartition( + repartitionedAs( + "$pid.pre-table-repartition", + kxsBinary.serde(), + kxsBinary.serde(), + // force, otherwise KTable-KTable FK join doesn't work + numberOfPartitions = 1, + ) + ).toTable( + "$pid.create-table", + materializedAs( + "$pid.output-store", + kxsBinary.serde(), + kxsBinary.serde(), + ) + ) +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt index a8a68ec..bff04b3 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt @@ -8,11 +8,13 @@ import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.ServerMapChunkId -import dev.adamko.kafkatorio.schema.common.TilePngFilename +import dev.adamko.kafkatorio.schema.common.ServerMapTilePngFilename import dev.adamko.kafkatorio.schema.packets.EventServerPacket import dev.adamko.kafkatorio.server.config.jsonMapper import dev.adamko.kafkatorio.server.processor.TOPIC_BROADCAST_TO_WEBSOCKET -import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_STATE +import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_BUILDING_COLOURED_STATE +import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_RESOURCE_COLOURED_STATE +import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_TERRAIN_COLOURED_STATE import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.stream @@ -51,12 +53,14 @@ fun saveMapTiles( kxsBinary.serde(ServerMapChunkId.serializer()), kxsBinary.serde(ServerMapChunkTiles.serializer(ColourHex.serializer())), ), - TOPIC_MAP_CHUNK_COLOURED_STATE, + TOPIC_MAP_CHUNK_TERRAIN_COLOURED_STATE, + TOPIC_MAP_CHUNK_RESOURCE_COLOURED_STATE, + TOPIC_MAP_CHUNK_BUILDING_COLOURED_STATE, ).filter("$pid.consume.grouped-map-chunks.filter-size") { _, y -> y.chunkId.chunkSize.lengthInTiles >= ChunkSize.CHUNK_256.lengthInTiles } - val savedChunkFilenames: KStream = + val savedChunkFilenames: KStream = subdividedMapChunkTilesDebounced.saveChunkAsImage(serverDataDir) savedChunkFilenames.broadcastSavedTileUpdates() @@ -67,7 +71,7 @@ fun saveMapTiles( private fun KStream>.saveChunkAsImage( tileDirectory: Path, -): KStream = mapValues( +): KStream = mapValues( "$pid.save-tiles" ) { chunkId: ServerMapChunkId, tileColours: ServerMapChunkTiles -> @@ -81,19 +85,36 @@ private fun KStream>.saveChunkA val chunkOriginX: Int = chunkId.chunkPosition.x * chunkId.chunkSize.lengthInTiles val chunkOriginY: Int = chunkId.chunkPosition.y * chunkId.chunkSize.lengthInTiles + val validPixelRangeX = 0 until chunkImage.width + val validPixelRangeY = 0 until chunkImage.height + tileColours.map.forEach { (tilePosition, colour) -> val rgbColour = colour.toRgbColor() val pixelX = abs(abs(tilePosition.x) - abs(chunkOriginX)) val pixelY = abs(abs(tilePosition.y) - abs(chunkOriginY)) - chunkImage.setColor(pixelX, pixelY, rgbColour) + if (!(pixelX in validPixelRangeX && pixelY in validPixelRangeY)) { + // TODO figure out why buildings on chunk boundaries aren't re-chunked, and so cause this error + println( + "ERROR - pixel XY:[$pixelX,$pixelY] was out of bounds (x:$validPixelRangeX, y:$validPixelRangeY). $tilePosition, $colour, chunkOriginXY[$chunkOriginX,$chunkOriginY], $chunkId" + ) + } else { + try { + chunkImage.setColor(pixelX, pixelY, rgbColour) + } catch (e: Exception) { + println( + "ERROR $e - pixel XY:[$pixelX,$pixelY] (x:$validPixelRangeX, y:$validPixelRangeY). $tilePosition, $colour, chunkOriginXY[$chunkOriginX,$chunkOriginY], $chunkId" + ) + throw e + } + } } val scaledImage = chunkImage.scaleTo(WEB_MAP_TILE_SIZE_PX, WEB_MAP_TILE_SIZE_PX, ScaleMethod.FastScale) - val filename = TilePngFilename(chunkId) + val filename = ServerMapTilePngFilename(chunkId) saveTile(filename, tileDirectory, scaledImage) filename } @@ -101,7 +122,7 @@ private fun KStream>.saveChunkA @Synchronized private fun saveTile( - filename: TilePngFilename, + filename: ServerMapTilePngFilename, serverDataDir: Path, img: ImmutableImage, ) { @@ -124,8 +145,8 @@ private fun saveTile( } -private fun KStream.broadcastSavedTileUpdates() { - map( +private fun KStream.broadcastSavedTileUpdates() { + map( "$pid.broadcast.filename-update.convert", ) { id, filename -> id.serverId to EventServerPacket.ChunkTileSaved(id, filename) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt index 38a6944..15ad792 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt @@ -69,7 +69,7 @@ class SyslogSocketServer( log("received 'null' from ${socket.description()} - closing connection") socket.close() } - else -> log("received '$line' from ${socket.description()}") +// else -> log("received '$line' from ${socket.description()}") } line }, diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt index 906c692..1a42e16 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt @@ -2,8 +2,9 @@ package dev.adamko.kafkatorio.server.web.rest import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.PlayerIndex +import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer +import dev.adamko.kafkatorio.schema.common.ServerMapTilePngFilename import dev.adamko.kafkatorio.schema.common.SurfaceIndex -import dev.adamko.kafkatorio.schema.common.TilePngFilename import dev.adamko.kafkatorio.server.config.ApplicationProperties import io.ktor.http.HttpStatusCode import io.ktor.http.content.EntityTagVersion @@ -41,8 +42,9 @@ private suspend fun PipelineContext.handleTileRequest( appProps: ApplicationProperties, ) { - val tileFilename = TilePngFilename( + val tileFilename = ServerMapTilePngFilename( tile.serverId, + tile.layer, tile.surfaceIndex, tile.zoomLevel, tile.chunkX, @@ -60,6 +62,19 @@ private suspend fun PipelineContext.handleTileRequest( } } else { call.respond(HttpStatusCode.NotFound) +// // It's not a client error to request this tile, it just doesn't exist (yet). So return 304? +// call.response.cacheControl(CacheControl.NoStore(null)) +// +// HeadersBuilder(size = 2).apply { +// EntityTagVersion(System.currentTimeMillis().hashCode().toString()) +// .appendHeadersTo(this) +// LastModifiedVersion(System.currentTimeMillis()) +// .appendHeadersTo(this) +// }.build().flattenForEach { name, value -> +// call.response.header(name, value) +// } +// +// call.respond(HttpStatusCode.NotModified) } } @@ -82,9 +97,11 @@ data class FactorioServer( ) { @Serializable - @Resource("tiles/s{surfaceIndex}/z{zoomLevel}/x{chunkX}/y{chunkY}.png") + @Resource("layers/{layer}/s{surfaceIndex}/z{zoomLevel}/x{chunkX}/y{chunkY}.png") data class Tile( val mapData: MapData, + + val layer: ServerMapTileLayer, val surfaceIndex: SurfaceIndex, val zoomLevel: Int, val chunkX: Int, diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/restApi.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/restApi.kt index 8aef3a3..0fe7f45 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/restApi.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/restApi.kt @@ -3,6 +3,7 @@ package dev.adamko.kafkatorio.server.web.rest import dev.adamko.kafkatorio.server.config.ApplicationProperties import io.ktor.http.ContentType import io.ktor.http.HttpStatusCode +import io.ktor.http.isSuccess import io.ktor.serialization.kotlinx.json.json import io.ktor.server.application.Application import io.ktor.server.application.install @@ -24,7 +25,12 @@ import io.ktor.server.routing.routing fun Application.webmapTileServer(appProps: ApplicationProperties) { install(AutoHeadResponse) - install(CallLogging) + install(CallLogging) { + filter { call -> + // only log failures + !(call.response.status()?.isSuccess() ?: false) + } + } install(Compression) { default() minimumSize(1024) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt index 3d99524..6f0e8e3 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt @@ -97,7 +97,9 @@ class WebmapWebsocketServer { override suspend fun send(frame: Frame): Unit = runCatching { super.send(frame) }.fold( - onSuccess = { log("sent message to client $name: $frame") }, + onSuccess = { +// log("sent message to client $name: $frame") + }, onFailure = { e -> log("failed to send message to client $name: $e") } ) diff --git a/modules/events-server/src/main/resources/config.yml b/modules/events-server/src/main/resources/config.yml index a5117f3..c377231 100644 --- a/modules/events-server/src/main/resources/config.yml +++ b/modules/events-server/src/main/resources/config.yml @@ -5,7 +5,7 @@ server-data-dir: ${SERVER_DATA_DIR:-./server-data} socket-server-host: ${SOCKET_SERVER_HOST:-127.0.0.1} -socket-server-port: ${SOCKET_SERVER_PORT:-12092} +#socket-server-port: ${SOCKET_SERVER_PORT:-12092} kafka-admin-config: diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt index 502ed3e..7c96280 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt @@ -7,6 +7,7 @@ import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapTilePosition +import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.server.processor.topology.ServerMapChunkTiles import java.util.UUID @@ -22,9 +23,9 @@ class Blah { val tiles = ServerMapChunkTiles( chunkId = ServerMapChunkId( serverId = FactorioServerId(UUID.randomUUID().toString()), - chunkPosition = MapChunkPosition(Int.MAX_VALUE, Int.MAX_VALUE), + layer = ServerMapTileLayer.BUILDING, + chunkPosition = MapChunkPosition(Int.MAX_VALUE, Int.MAX_VALUE, ChunkSize.MAX), surfaceIndex = SurfaceIndex(UInt.MAX_VALUE), - chunkSize = ChunkSize.MAX, ), buildMap { repeat(512) { x -> diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/SaveMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/SaveMapChunksTest.kt index d7a07fa..919bef3 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/SaveMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/SaveMapChunksTest.kt @@ -1,15 +1,16 @@ package dev.adamko.kafkatorio.server.processor.topology +import dev.adamko.kafkatorio.library.iterateTiles import dev.adamko.kafkatorio.library.kxsBinary +import dev.adamko.kafkatorio.library.toMapChunkPosition import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapTilePosition import dev.adamko.kafkatorio.schema.common.ServerMapChunkId +import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer import dev.adamko.kafkatorio.schema.common.SurfaceIndex -import dev.adamko.kafkatorio.schema.common.iterateTiles -import dev.adamko.kafkatorio.schema.common.toMapChunkPosition import dev.adamko.kotka.kxs.serde import io.kotest.core.spec.style.FunSpec import io.kotest.property.Arb @@ -55,11 +56,11 @@ class SaveMapChunksTest : FunSpec({ scenario += 1.minutes delay(5.seconds) scenario += 1.minutes -// delay(5.seconds) + // delay(5.seconds) scenario += 1.minutes -// delay(5.seconds) + // delay(5.seconds) scenario += 1.minutes -// delay(5.seconds) + // delay(5.seconds) println("file:///${scenario.outputDir.absolutePathString()}") } @@ -71,7 +72,7 @@ class SaveMapChunksTest : FunSpec({ class Scenario( streamsBuilder: StreamsBuilder = StreamsBuilder(), - groupedMapChunksInputTopicName: String = "kafkatorio.state.map-chunk.colour", + groupedMapChunksInputTopicName: String = "kafkatorio.state.map-chunk.terrain.colour", val serverId: FactorioServerId = FactorioServerId("test-server-id"), ) : AutoCloseable { @@ -104,8 +105,9 @@ class SaveMapChunksTest : FunSpec({ private fun mapChunkPositionArb( xArb: Arb = Arb.int(-10..10), yArb: Arb = Arb.int(-10..10), + chunkSize: ChunkSize = ChunkSize.MAX, ): Arb = arbitrary { - MapChunkPosition(xArb.bind(), yArb.bind()) + MapChunkPosition(xArb.bind(), yArb.bind(), chunkSize) } private fun colourHexArb( @@ -124,15 +126,15 @@ class SaveMapChunksTest : FunSpec({ private fun serverMapChunkIdArb( serverId: FactorioServerId, - chunkPosition: Arb = mapChunkPositionArb(), - surfaceIndex: SurfaceIndex = SurfaceIndex(1u), chunkSize: ChunkSize = ChunkSize.MAX, + chunkPosition: Arb = mapChunkPositionArb(chunkSize = chunkSize), + surfaceIndex: SurfaceIndex = SurfaceIndex(1u), ): Arb = arbitrary { ServerMapChunkId( serverId = serverId, + layer = ServerMapTileLayer.RESOURCE, chunkPosition = chunkPosition.bind(), surfaceIndex = surfaceIndex, - chunkSize = chunkSize, ) } @@ -145,7 +147,7 @@ class SaveMapChunksTest : FunSpec({ println("chunk size: ${chunkId.chunkSize} ${chunkId.chunkSize.lengthInTiles}") val map = chunkId.chunkPosition - .iterateTiles(chunkId.chunkSize) + .iterateTiles() .asSequence() .map { tilePos -> val colour = @@ -154,7 +156,7 @@ class SaveMapChunksTest : FunSpec({ } tilePos to colour } -// .take(2500) +// .take(100) .toMap() println(map.size) diff --git a/modules/infra-kafka-cluster/src/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml index d60961f..83124c0 100644 --- a/modules/infra-kafka-cluster/src/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -14,6 +14,7 @@ services: KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/${KAFKA_VERSION}/kafka_2.13-${KAFKA_VERSION}.tgz" volumes: - "./kafka-server.properties:/kafka/server.properties" +# - "./kafka-data:/tmp/kraft-combined-logs" # see Dockerfile environment: JMX_PORT: "9991" # KAFKA_JMX_OPTS: "9991" diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index 03ac670..aab0664 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -78,7 +78,7 @@ class App( wsService.packetsFlow .filterIsInstance() .onEach { tileSavedEvent -> - println("[packetsFlow] triggering tile refresh ${tileSavedEvent.filename.value}") +// println("[packetsFlow] triggering tile refresh ${tileSavedEvent.filename.value}") gameState.map.refreshUpdatedTilePng(tileSavedEvent.filename) }.launchIn(this) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index 9ee6b7c..bff9f1a 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -1,6 +1,7 @@ package dev.adamko.kafkatorio.webmap -import dev.adamko.kafkatorio.schema.common.TilePngFilename +import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer +import dev.adamko.kafkatorio.schema.common.ServerMapTilePngFilename import dev.adamko.kafkatorio.webmap.externals.TileOnLoadFn import dev.adamko.kafkatorio.webmap.externals.tileOnLoad import io.kvision.maps.Maps @@ -30,9 +31,7 @@ import org.w3c.fetch.RequestInit import org.w3c.fetch.RequestMode -class FactorioMap( - private val tileUrlTemplate: String = """/kafkatorio/data/servers/syslog-test/map/tiles/s1/z{z}/x{x}/y{y}.png""", -) { +class FactorioMap { val kvMap: Maps = Maps { width = 800.px @@ -40,18 +39,22 @@ class FactorioMap( margin = 10.px } - private val factorioTerrainLayer: TileLayer<*> = buildFactorioTerrainLayer() + private val terrainTileLayer: TileLayer<*> = createServerTileLayer(ServerMapTileLayer.TERRAIN) + private val resourcesTileLayer: TileLayer<*> = createServerTileLayer(ServerMapTileLayer.RESOURCE) + private val buildingsTileLayer: TileLayer<*> = createServerTileLayer(ServerMapTileLayer.BUILDING) val playerIconsLayer: LayerGroup = LayerGroup() init { val baseLayers: Control.LayersObject = jso { - set("Terrain", factorioTerrainLayer) + set("Terrain", terrainTileLayer) } val overlays: Control.LayersObject = jso { set("Players", playerIconsLayer) + set("Resources", resourcesTileLayer) + set("Buildings", buildingsTileLayer) } val layersControl = Layers( @@ -76,14 +79,17 @@ class FactorioMap( // options.fadeAnimation = false addControl(layersControl) - factorioTerrainLayer.addTo(this) + terrainTileLayer.addTo(this) + resourcesTileLayer.addTo(this) + buildingsTileLayer.addTo(this) + playerIconsLayer.addTo(this) } } suspend fun refreshUpdatedTilePng( - tilePngFilename: TilePngFilename, + tilePngFilename: ServerMapTilePngFilename, ): Unit = coroutineScope { document .querySelectorAll("img.leaflet-tile-loaded") @@ -111,10 +117,14 @@ class FactorioMap( } } - private fun buildFactorioTerrainLayer(): TileLayer { + private fun createServerTileLayer( + layer: ServerMapTileLayer + ): TileLayer { + + val urlTemplate: String = tileLayerUrlTemplate(layer) val baseTileLayer = L.tileLayer( - tileUrlTemplate + urlTemplate ) { attribution = "kafkatorio" tileSize = 256 @@ -147,5 +157,8 @@ class FactorioMap( companion object { const val DYNAMIC_RELOAD_ATT = "dynamic-reload" + + private fun tileLayerUrlTemplate(layer: ServerMapTileLayer): String = + "/kafkatorio/data/servers/syslog-test/map/layers/${layer.dir}/s1/z{z}/x{x}/y{y}.png" } } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt index 58ddf51..b48f91f 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -5,8 +5,9 @@ import dev.adamko.kafkatorio.schema.packets.ConsoleChatUpdate import dev.adamko.kafkatorio.schema.packets.ConsoleCommandUpdate import dev.adamko.kafkatorio.schema.packets.EntityUpdate import dev.adamko.kafkatorio.schema.packets.EventServerPacket -import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData +import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketDataError import dev.adamko.kafkatorio.schema.packets.MapChunkEntityUpdate +import dev.adamko.kafkatorio.schema.packets.MapChunkResourceUpdate import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate @@ -76,18 +77,19 @@ class WebsocketService( is EventServerPacket.Kafkatorio -> when (val packetData = packet.packet.data) { - is PlayerUpdate -> reduxStore.dispatch( - FactorioUpdate.Player(packet.packet.tick, packetData) - ) + is PlayerUpdate -> + reduxStore.dispatch(FactorioUpdate.Player(packet.packet.tick, packetData)) + is ConfigurationUpdate, is ConsoleChatUpdate, is ConsoleCommandUpdate, is EntityUpdate, is MapChunkEntityUpdate, + is MapChunkResourceUpdate, is MapChunkTileUpdate, is PrototypesUpdate, is SurfaceUpdate, - is KafkatorioPacketData.Error -> { + is KafkatorioPacketDataError -> { // to be continued... } } From 5d99b86dca757564b3e6c17c81e813df989329f4 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 16 Jul 2022 23:17:02 +0200 Subject: [PATCH 473/629] rm unused code --- .../topology/colourResourceChunks.kt | 172 ------------------ 1 file changed, 172 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourResourceChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourResourceChunks.kt index d4c5521..96d1835 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourResourceChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourResourceChunks.kt @@ -113,28 +113,6 @@ fun KStream.convertEntityUpdateToServerM return flatMap("$pid.map") { serverId: FactorioServerId, update: MapChunkEntityUpdate -> -// val entities = update.entitiesXY.convert { entity, position -> -// FactorioEntityData.Standard( -// protoId = update.key.protoId, -// position = position, -// element = entity, -// ) -// } - -// val (validEntityPositions, unboundedEntityPositions) = entities.map { entity -> -// entity.position.toMapTilePosition() to entity -// }.partition { (position, _) -> -// position in update.key.chunkPosition -// } -// -// if (unboundedEntityPositions.isNotEmpty()) { -// val unboundedEntities = unboundedEntityPositions.map { (_, entity) -> entity } -// println( -// "WARNING [convertToServerMapChunkTiles] MapChunkEntityUpdate ${update.key} " + "contained ${unboundedEntities.size} out-of-bounds entities " + unboundedEntities.joinToString( -// limit = 10 -// ) -// ) -// } // // // TODO There might be multiple resources per tile position, therefore this will arbitrarily // // exclude resources. Maybe change it from a Map to a List? Or have multiple resources per @@ -194,38 +172,6 @@ fun KStream.convertResourceUpdateToSer } -//private fun KStream>.reduceServerMapResourceTilesToTable() -// : KTable> { -// -// val pid = "$pid.reduceServerMapResourceTilesToTable" -// -// return repartition( -// repartitionedAs( -// "$pid.pre-table-repartition", -// kxsBinary.serde(), -// kxsBinary.serde>(), -// // force, otherwise KTable-KTable FK join doesn't work -// numberOfPartitions = 1, -// ) -// ).groupByKey( -// groupedAs( -// "$pid.group-by-key", -// kxsBinary.serde(), -// kxsBinary.serde>(), -// ) -// ).reduce( -// "$pid.reduce", -// materializedAs( -// "$pid.reduce.store", -// kxsBinary.serde(), -// kxsBinary.serde>(), -// ) -// ) { chunkTiles, otherChunkTiles -> -// chunkTiles + otherChunkTiles -// } -//} - - private fun KTable>.enrichWithColourData( callerPid: String, protosTable: KTable, @@ -304,18 +250,6 @@ private fun MapBoundingBox.iterator(origin: MapTilePosition): Iterator 0 -> ceil(this).toInt() - this < 0 -> floor(this).toInt() - else -> 0 -} -// ceil(abs(this)).toInt() * this.sign.toInt() - - private fun FactorioPrototype.Entity.mapColour(): ColourHex = (colour ?: mapColour ?: mapColourFriend)?.toHex() ?: ColourHex.WHITE @@ -334,109 +268,3 @@ private operator fun ColourHex.plus(other: ColourHex): ColourHex = copy( blue = (blue + other.blue).toUByte(), alpha = (alpha + other.alpha).toUByte(), ) - - -//// https://stackoverflow.com/a/9355778/4161471 -//private operator fun ColourHex.plus(other: ColourHex): ColourHex { -// -// @Suppress("LocalVariableName") -// val `255` = UByte.MAX_VALUE -// -// val compositeAlpha: UByte = ( -// `255` - ((`255` - other.alpha) * (`255` - this.alpha)) / `255` -// ).toUByte() -// -// if (compositeAlpha == UByte.MIN_VALUE) { -// return ColourHex.TRANSPARENT -// } else { -// -// fun compositeColour( -// colour: (ColourHex) -> UByte, -// ): UByte { -// val colour1 = colour(this) -// val colour2 = colour(other) -// return (( -// ( -// ( colour2 * other.alpha) + (colour1 * this.alpha * ( other.alpha)) -// ) / compositeAlpha -// ) / `255` -// ).toUByte() -// } -// -// return ColourHex( -// compositeColour(ColourHex::red), -// compositeColour(ColourHex::green), -// compositeColour(ColourHex::blue), -// compositeAlpha, -// ) -// } -//} - -//private fun KTable>.streamMapChunkColouredTo( -// chunkSize: ChunkSize, -// outputTopic: String, -//) { -// val pid = "$pid.output-chunk.${chunkSize.name}" -// -// toStream("$pid.stream") -// .filter("$pid.filter-tiles-not-empty") { _, chunkTiles -> -// !chunkTiles?.map.isNullOrEmpty() -// } -// .mapValues("$pid.map-not-null") { _, chunkTiles -> -// requireNotNull(chunkTiles) -// } -// .peek("$pid.print-group-result") { _, chunkTiles -> -// println("Grouping map tiles result: ${chunkTiles.chunkId} / size:${chunkTiles.map.size}") -// }.to( -// outputTopic, -// producedAs( -// "$pid.grouped-map-chunks", -// kxsBinary.serde(), -// kxsBinary.serde>(), -// ) -// ) -//} - - -///** -// * Group [MapChunkTileUpdate]s by the Chunk position. -// * -// * They should already be grouped, but do it again to make sure, and to filter out empty updates. -// */ -//private fun KStream>.groupByChunkPosition( -// chunkSize: ChunkSize = ChunkSize.CHUNK_032 -//): KTable> { -// -// val pid = "$pid.groupByChunkPosition.${chunkSize.name}" -// -// return map("$pid.change-chunk-size") { chunkId: ServerMapChunkId, chunkTiles: ServerMapChunkTiles? -> -// -// val newChunkPosition = chunkId.chunkPosition -// .leftTopTile(chunkId.chunkSize) -// .toMapChunkPosition(chunkSize) -// -// val newId = chunkId.copy( -// chunkSize = chunkSize, -// chunkPosition = newChunkPosition, -// ) -// -// val newChunkTiles = chunkTiles?.map ?: emptyMap() -// -// newId to ServerMapChunkTiles(chunkId = newId, map = newChunkTiles) -// }.groupByKey( -// groupedAs( -// "$pid.group-by-key", -// kxsBinary.serde(), -// kxsBinary.serde>(), -// ) -// ).reduce( -// "$pid.reduce", -// materializedAs( -// "$pid.reduce.store", -// kxsBinary.serde(), -// kxsBinary.serde>(), -// ) -// ) { chunkTiles, otherChunkTiles -> -// chunkTiles + otherChunkTiles -// } -//} From 731c037f0e0aacbb46f07df248bddcfc80e56ecd Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 16 Jul 2022 23:20:14 +0200 Subject: [PATCH 474/629] fix tests --- .../kafkatorio/schema/packets/UpdatePacketsTest.kt | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/UpdatePacketsTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/UpdatePacketsTest.kt index 81c8144..937fd5d 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/UpdatePacketsTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/UpdatePacketsTest.kt @@ -41,7 +41,6 @@ class UpdatePacketsTest : FunSpec({ "isAdmin": true, "isConnected": true, "isShowOnMap": true, - "isSpectator": false, "lastOnline": 0, "name": "fredthedeadhead", "onlineTime": 0, @@ -104,8 +103,8 @@ class UpdatePacketsTest : FunSpec({ afkTime = Tick(0u), ticksToRespawn = null, forceIndex = null, - isAdmin = null, - isConnected = null, +// isAdmin = , +// isConnected = , isShowOnMap = true, isSpectator = false, lastOnline = Tick(0u), @@ -135,7 +134,6 @@ class UpdatePacketsTest : FunSpec({ "name": "fredthedeadhead", "afkTime": 0, "isShowOnMap": true, - "isSpectator": false, "lastOnline": 0, "onlineTime": 0, "position": [ @@ -196,11 +194,11 @@ class UpdatePacketsTest : FunSpec({ ), forceIndex = null, key = PlayerUpdateKey(PlayerIndex(1u)), - isAdmin = null, +// isAdmin = , isConnected = true, isRemoved = null, - isShowOnMap = null, - isSpectator = null, +// isShowOnMap = , +// isSpectator = , kickedReason = null, lastOnline = 227932u.tick, name = null, From 10c54998c7d260d1f1d7fcf642c92e7d37c6d0c2 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 16 Jul 2022 23:23:55 +0200 Subject: [PATCH 475/629] version bump to 0.8.0 --- build.gradle.kts | 2 +- modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- modules/events-server/docker/.env | 2 +- modules/infra-factorio-server/src/.env | 2 +- modules/infra-kafka-cluster/src/.env | 2 +- modules/infra-kafka-pipe/src/.env | 2 +- modules/web-map/docker/.env | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 5ca67e0..e9957a8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.7.1" +version = "0.8.0" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 8337468..fe903b7 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.7.1", + "version": "0.8.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 6a5d159..bc5da72 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.7.1", + "version": "0.8.0", "private": true, "scripts": { "build": "tstl", diff --git a/modules/events-server/docker/.env b/modules/events-server/docker/.env index 45177a6..74562e0 100644 --- a/modules/events-server/docker/.env +++ b/modules/events-server/docker/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.7.1 +KAFKATORIO_VERSION=0.8.0 diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index f085f4c..4b5add1 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio FACTORIO_VERSION=1.1.61 -KAFKATORIO_VERSION=0.7.1 +KAFKATORIO_VERSION=0.8.0 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index 29cc092..c211275 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,7 +1,7 @@ # Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio GRAFANA_VERSION=8.5.0 -KAFKATORIO_VERSION=0.7.1 +KAFKATORIO_VERSION=0.8.0 KAFKA_DL_URL=https\://dlcdn.apache.org/kafka/3.2.0/kafka_2.13-3.2.0.tgz KAFKA_VERSION=3.2.0 PROMETHEUS_VERSION=v2.34.0 diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index 45177a6..74562e0 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.7.1 +KAFKATORIO_VERSION=0.8.0 diff --git a/modules/web-map/docker/.env b/modules/web-map/docker/.env index 45177a6..74562e0 100644 --- a/modules/web-map/docker/.env +++ b/modules/web-map/docker/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.7.1 +KAFKATORIO_VERSION=0.8.0 From 786b6d52a918563cab1416a6d63687421621b3b8 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 16 Jul 2022 23:31:28 +0200 Subject: [PATCH 476/629] bump Gradle to 7.5 --- build.gradle.kts | 4 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index e9957a8..96f5ecd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { `project-report` `build-dashboard` -// kotlin("multiplatform") apply false // try to stop error 'Projects must be configuring' + kotlin("multiplatform") apply false // try to stop error 'Projects must be configuring' // kotlin("js") apply false // try to stop error 'Projects must be configuring' } @@ -39,7 +39,7 @@ idea { } tasks.wrapper { - gradleVersion = "7.4.2" + gradleVersion = "7.5" distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 92f06b5..2ec77e5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From b4f3fc87e5773d2a1670c6c84474dd88b55caf70 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 17 Jul 2022 10:01:04 +0200 Subject: [PATCH 477/629] bump kvision --- gradle/kotlin-js-store/yarn.lock | 8 ++++---- gradle/libs.versions.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index 0152645..de9a0f5 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -1542,10 +1542,10 @@ import-local@^3.0.2: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" -imports-loader@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-3.1.1.tgz#3e464d9aad1e303b1b34b658eb8f8aae22f96435" - integrity sha512-3QMyGU4RTgxLf0puWkUfT5+7zJvexvB00PI5skDIcxG8O20gZCbQsaRpNBv+cIO6yy/lmlOBwaxc3uH1CV+sww== +imports-loader@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-4.0.0.tgz#c11574247beca48e6549db1eb603f8939884aca1" + integrity sha512-8PPbhk/9CEHd0WWKESw/oYTDhp3So9PWA9OfyIbH3kywIN4uxrWkQ8ux47xpk4yWUKX97Erbws9MFSaBlVvAjg== dependencies: source-map "^0.6.1" strip-comments "^2.0.1" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a026552..2f320db 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ kotlin = "1.7.10" camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" kafka = "3.2.0" # https://kafka.apache.org/downloads -kvision = "5.12.0" +kvision = "5.13.1" log4j2 = "2.17.2" okio = "3.2.0" qosLogback = "1.2.11" From 09b49ae21cd77fb6af395597dce3757d9f9a9764 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 17 Jul 2022 12:12:06 +0200 Subject: [PATCH 478/629] add 'Projects must be configuring' workaround script --- build.gradle.kts | 5 ++++- gradle.properties | 4 ++-- kt52647.gradle.kts | 31 +++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 kt52647.gradle.kts diff --git a/build.gradle.kts b/build.gradle.kts index 96f5ecd..62e7b62 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { `project-report` `build-dashboard` - kotlin("multiplatform") apply false // try to stop error 'Projects must be configuring' +// kotlin("multiplatform") apply false // try to stop error 'Projects must be configuring' // kotlin("js") apply false // try to stop error 'Projects must be configuring' } @@ -101,3 +101,6 @@ val runFactorioClient by tasks.registering { ":modules:infra-factorio-client:processRun", ) } + + +apply(from = "$projectDir/kt52647.gradle.kts") diff --git a/gradle.properties b/gradle.properties index e4be207..7acfe41 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ org.gradle.unsafe.configuration-cache-problems=warn org.gradle.kotlin.dsl.precompiled.accessors.strict=true -#org.gradle.parallel=true # helps with pRoJeCtS mUsT bE cOnFiGuRiNg +org.gradle.parallel=true # pRoJeCtS mUsT bE cOnFiGuRiNg -org.gradle.configureondemand=false +#org.gradle.configureondemand=false diff --git a/kt52647.gradle.kts b/kt52647.gradle.kts new file mode 100644 index 0000000..f610b1e --- /dev/null +++ b/kt52647.gradle.kts @@ -0,0 +1,31 @@ + + +val projectsMustBeConfiguringBuster by tasks.registering { + val buildFile = layout.projectDirectory.file("kt52647.gradle.kts").asFile + doLast { + logger.warn("Applying 'Projects must be configuring' workaround - https://youtrack.jetbrains.com/issue/KT-52647") + + val newLines = buildFile.readText().lines().joinToString("\n") { line -> + if (line.startsWith("// projects must be configuring buster")) { + "// projects must be configuring buster ${System.currentTimeMillis()}" + } else { + line + } + } + + buildFile.writeText(newLines) + } +} + + +allprojects { + tasks + .matching { it.name != projectsMustBeConfiguringBuster.name } + .configureEach { + finalizedBy(projectsMustBeConfiguringBuster) + } +} + + +// projects must be configuring buster +// ^ this line will be edited by projectsMustBeConfiguringBuster From a8784db5b2f31b6c7970e11657c57ec6dc322e8d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 17 Jul 2022 12:15:46 +0200 Subject: [PATCH 479/629] update player state booleans - they default to false now --- .../kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt index 7cd71ab..c659521 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt @@ -149,8 +149,8 @@ sealed interface PlayerProperties { val surfaceIndex = update.surfaceIndex ?: this.surfaceIndex val colour = update.colour ?: this.colour val name = update.name ?: this.name - val isConnected = update.isConnected ?: false - val isShowOnMap = update.isShowOnMap ?: false + val isConnected = update.isConnected + val isShowOnMap = update.isShowOnMap return when { position != null From 394361001fecc8fa7f0166db9f2509290cb940a6 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 17 Jul 2022 12:34:35 +0200 Subject: [PATCH 480/629] Factorio Mod Portal Publish task - reduce logging --- .../portal/FactorioModPortalPublishClient.kt | 29 ++++++++++++------- .../portal/FactorioModPublishTask.kt | 1 - .../kafkatorio/factoriomod/portal/model.kt | 6 ---- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPortalPublishClient.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPortalPublishClient.kt index 7b1aead..6d988d0 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPortalPublishClient.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPortalPublishClient.kt @@ -5,9 +5,6 @@ import io.ktor.client.engine.cio.CIO import io.ktor.client.plugins.contentnegotiation.ContentNegotiation import io.ktor.client.plugins.defaultRequest import io.ktor.client.plugins.logging.LogLevel -import io.ktor.client.plugins.logging.Logger -import io.ktor.client.plugins.logging.Logging -import io.ktor.client.plugins.logging.SIMPLE import io.ktor.client.request.forms.MultiPartFormDataContent import io.ktor.client.request.forms.formData import io.ktor.client.request.forms.submitForm @@ -27,6 +24,10 @@ import kotlinx.coroutines.runBlocking import kotlinx.serialization.json.Json import org.gradle.api.internal.tasks.userinput.UserInputHandler import org.gradle.kotlin.dsl.support.useToRun +import io.ktor.client.plugins.logging.Logger as KtorLogger +import io.ktor.client.plugins.logging.Logging as KtorLogging +import org.gradle.api.logging.Logger as GradleLogger +import org.gradle.api.logging.Logging as GradleLogging class FactorioModPortalPublishClient( @@ -39,9 +40,15 @@ class FactorioModPortalPublishClient( private val modPortalBaseURl: String, ) { + private val logger: GradleLogger = GradleLogging.getLogger(this::class.java) + private fun client() = HttpClient(CIO) { - install(Logging) { - logger = Logger.SIMPLE + install(KtorLogging) { + logger = object : KtorLogger { + override fun log(message: String) { + this@FactorioModPortalPublishClient.logger.debug(message) + } + } level = LogLevel.ALL } install(ContentNegotiation) { @@ -76,7 +83,7 @@ class FactorioModPortalPublishClient( if (confirmed) { upload(initUploadResponse) } else { - println("aborting upload") + logger.lifecycle("aborting mod '$modName' upload") } } } @@ -90,10 +97,10 @@ class FactorioModPortalPublishClient( } ) - println(response) +// println(response) val initUploadResponse: InitUploadResponse = Json.decodeFromString(InitUploadResponse.serializer(), response.bodyAsText()) - println(initUploadResponse) +// println(initUploadResponse) require(response.status.isSuccess()) { "init upload request failed" } @@ -123,11 +130,11 @@ class FactorioModPortalPublishClient( val submitUploadResponse = Json.decodeFromString(SubmitUploadResponse.serializer(), response.bodyAsText()) - println(response) - println(submitUploadResponse) +// logger(response) +// println(submitUploadResponse) require(response.status.isSuccess() && submitUploadResponse is SubmitUploadResponse.Success) { "upload request failed" } - println("Mod uploaded successfully! ${modPortalBaseURl.removeSuffix("/")}/$modName") + logger.lifecycle("Mod '$modName' uploaded successfully! ${modPortalBaseURl.removeSuffix("/")}/$modName") } } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPublishTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPublishTask.kt index d798e32..894feae 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPublishTask.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPublishTask.kt @@ -67,7 +67,6 @@ abstract class FactorioModPublishTask @Inject constructor( @TaskAction fun deploy() = runBlocking { - val userInputHandler = services.get() val portalUploadEndpoint = URLBuilder(portalApiUrl.get()) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/model.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/model.kt index aee2ac6..61f0e61 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/model.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/model.kt @@ -7,12 +7,6 @@ import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.jsonObject -//@Serializable -//data class InitUploadRequest( -// @SerialName("mod") val modName: String, -//) - - @Serializable(with = InitUploadResponse.Serializer::class) sealed interface InitUploadResponse { From e15a7651f4196515bb7af8a4c12430ea7b94f22f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 17 Jul 2022 12:35:12 +0200 Subject: [PATCH 481/629] bump kotlinx libs, and hoplite --- buildSrc/repositories.settings.gradle.kts | 4 ++++ gradle/libs.versions.toml | 24 +++++++++++------------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/buildSrc/repositories.settings.gradle.kts b/buildSrc/repositories.settings.gradle.kts index 874aff0..56eb40e 100644 --- a/buildSrc/repositories.settings.gradle.kts +++ b/buildSrc/repositories.settings.gradle.kts @@ -35,6 +35,10 @@ dependencyResolutionManagement { maven("https://raw.githubusercontent.com/adamko-dev/kotka-streams/artifacts/m2") { content { includeGroup("dev.adamko.kotka") } } + + maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") { + content { includeGroup("org.jetbrains.kotlinx") } + } } pluginManagement { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2f320db..63f4605 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,39 +11,39 @@ kotlin = "1.7.10" ## libs ## camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" -kafka = "3.2.0" # https://kafka.apache.org/downloads +kafka = "3.2.0" # https://kafka.apache.org/downloads kvision = "5.13.1" log4j2 = "2.17.2" -okio = "3.2.0" +okio = "3.2.0" # https://search.maven.org/artifact/com.squareup.okio/okio qosLogback = "1.2.11" -scrimage = "4.0.31" +scrimage = "4.0.31" # https://github.com/sksamuel/scrimage/releases semver = "1.2.0" slf4j = "1.7.36" -kotlinx-serialization = "1.3.3" +kotlinx-serialization = "1.3.3" # https://github.com/Kotlin/kotlinx.serialization/releases kxs-charleskornKaml = "0.44.0" kxs-mamoeYamlkt = "0.12.0" kxs-kxsTsGen = "0.2.1" -kotlinJsWrappers = "1.0.0-pre.351" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom +kotlinJsWrappers = "1.0.0-pre.357" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom kotlinx-cli = "0.3.4" -kotlinx-coroutines = "1.6.3" -kotlinx-datetime = "0.3.3" -kotlinx-html = "0.7.5" +kotlinx-coroutines = "1.6.4" # https://github.com/Kotlin/kotlinx.coroutines/releases +kotlinx-datetime = "0.4.0" # https://github.com/Kotlin/kotlinx-datetime/releases +kotlinx-html = "0.8.0" # https://github.com/Kotlin/kotlinx.html/releases kotlinx-nodejs = "0.0.7" kSvgDsl = "v2.2.0" -ktor = "2.0.3" +ktor = "2.0.3" # https://github.com/ktorio/ktor/releases -hoplite = "2.1.5" +hoplite = "2.3.1" # https://github.com/sksamuel/hoplite/releases -simpleSyslogParser = "0.0.6" +simpleSyslogParser = "0.0.6" # https://search.maven.org/artifact/com.github.palindromicity/simple-syslog kotkaStreams = "dev-SNAPSHOT" -marykRocksDb = "7.3.1" # https://search.maven.org/artifact/io.maryk.rocksdb/rocksdb-multiplatform +marykRocksDb = "7.3.1" # https://search.maven.org/artifact/io.maryk.rocksdb/rocksdb-multiplatform ## test ## junit = "5.8.2" From ddfd14f6d675b0665001ac071abf1d63124d3dbc Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 17 Jul 2022 14:20:28 +0200 Subject: [PATCH 482/629] update readme (better description, TODOs were moved to issue board) --- README.md | 89 ++++++++----------------------------------------------- 1 file changed, 12 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index ea63a00..94fc22c 100644 --- a/README.md +++ b/README.md @@ -1,84 +1,19 @@ # Kafkatorio -1. output events from Factorio into Kafka. - 1. Factorio mod listens to events https://mods.factorio.com/mod/kafkatorio-events - 2. For each event, it emits a log message - 3. A tool (e.g. Kafkatorio Kafka Pipe) reads the logs, and sends the messages to a Kafka cluster -2. Kafkatorio Events Server reads the messages from Kafka - 1. create images of the map - 2. hosts a web map +[Kafkatorio](https://github.com/adamko-dev/kafkatorio) is a platform used for creating +[Factorio](https://www.factorio.com/) mods that require communication with an external server. +It was created to explore the possibilities of using [Apache Kafka](https://kafka.apache.org/) +to process updates from a Factorio server. + +Kafkatorio receives updates from a Factorio server, processes them, and exposes them over a REST +and WebSocket APIs. + +Development is ongoing. At present the only application is a +[live-view web map](https://factorio.adamko.dev), that shows the current status of a Factorio +server, and any connected players. Other possibilities are exposing metrics, and inter-server +communication. ## License While this project is under development, [no license](https://choosealicense.com/no-permission/) is provided. - -## cmds - -`./bin/kafka-streams-application-reset.sh --application-id kafkatorio-events-processor --input-topics factorio-server-log` - -`:screen-fps=60.000000 :live-caching=300 :screen-width=1920 :screen-height=1080 :screen-top=100 :screen-left:20` -`:screen-fps=60.000000 :live-caching=300 --screen-width=1920 --screen-height=1080 :sout=#transcode{vcodec=h264,vb=0,scale=0,acodec=mpga,ab=128,channels=2,samplerate=44100}:file{dst=D:\\savedir.mp4} :sout-keep` - -## todo - -* add settings - * is active - whether files are exported or not - * delete files - clean up all files - * tick-rate - how often reports are generated - * requires on some sort of in-mod cache of map - * also divide by game-speed? to keep ratio the same -* Move to a vector tile supported map. PNGs are slow. - * Maplibre GL JS? https://maplibre.org/maplibre-gl-js-docs/example/ - * Add VectorGrid? https://leaflet.github.io/Leaflet.VectorGrid/vectorgrid-api-docs.html - * https://leaflet.github.io/Leaflet.VectorGrid/vectorgrid-api-docs.html#styling-vectorgrids - -### to investigate: - -* https://github.com/starwing/lua-protobuf -* https://github.com/grafi-tt/lunajson -* http://lua-users.org/wiki/CompressionAndArchiving -* https://luapower.com/zlib -* https://github.com/appgurueu/modlib#bluon -* https://github.com/dingyi222666/lua-table-serialize -* https://github.com/uriid1/lua-serialize -* https://github.com/rxi/lume#lumeserializex -* https://github.com/SwadicalRag/bON - -* https://square.github.io/okio/#communicate-on-a-socket-javakotlin - -* https://github.com/cloudhut/kowl -* https://opensource.expediagroup.com/graphql-kotlin/docs/server/spring-server/spring-subscriptions -* https://github.com/YousefED/typescript-json-schema - -* https://jbrandhorst.com/post/go-protobuf-tips/ - -* https://github.com/bakpakin/binser - -##### wasm - -kt -> wasm -> lua? kt-flatbuffers -> wasm -> lua? - -https://www.npmjs.com/package/wasm2lua?activeTab=readme - -##### Encodings - -* flatbuffers https://github.com/dvidelabs/flatcc -* z85 encoding - * Kotlin https://gist.github.com/ischumacher/b4929f26341ebef62cbce35c65543eda - * Lua https://web-eworks.github.io/lZ85/ -* https://github.com/SafeteeWoW/LibDeflate -* CBOR - * https://www.zash.se/lua-cbor.html - * https://code.zash.se/lua-cbor/archive/68b3a36d0816.tar.gz - -* BSON - * https://github.com/mpaland/bsonfy - * https://github.com/tcoram/bson-lua - -* bebop - https://rainway.com/blog/2020/12/09/bebop-an-efficient-schema-based-binary-serialization-format/ - -* binser - * https://github.com/bakpakin/binser - * https://github.com/maxiy01/tstl-binser From 4cb00febc229346516b8b49f39320eba191752f2 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 17 Jul 2022 23:50:33 +0200 Subject: [PATCH 483/629] rm docs/notes/question.md - not needed --- ...w-to-run-npx-gradle-task-with-kotlin-js.md | 63 ------------------- 1 file changed, 63 deletions(-) delete mode 100644 docs/notes/question-how-to-run-npx-gradle-task-with-kotlin-js.md diff --git a/docs/notes/question-how-to-run-npx-gradle-task-with-kotlin-js.md b/docs/notes/question-how-to-run-npx-gradle-task-with-kotlin-js.md deleted file mode 100644 index 669dfcc..0000000 --- a/docs/notes/question-how-to-run-npx-gradle-task-with-kotlin-js.md +++ /dev/null @@ -1,63 +0,0 @@ -How I can run a npx Gradle task with Kotlin/JS? - -I have a project that includes some dependencies downloaded from NPM and source code in Typescript. - -I want to use [TypeScriptToLua](https://typescripttolua.github.io/) to convert my Typescript files -into Lua. - -I see that Kotlin/JS has two - -https://github.com/JetBrains/kotlin/blob/b76cbdaa41c8cae04d8bd1bd857186d7835045b5/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/NpmProject.kt#L86 - -```kotlin -fun useTool( - exec: ExecSpec, - tool: String, - nodeArgs: List = listOf(), - args: List -) { - exec.workingDir = dir - exec.executable = nodeExecutable - exec.args = nodeArgs + require(tool) + args -} -``` - -https://github.com/JetBrains/kotlin/blob/92d200e093c693b3c06e53a39e0b0973b84c7ec5/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/dukat/DukatRunner.kt#L47 - -```kotlin -npmProject.useTool( - exec, - "dukat/bin/dukat-cli.js", - listOf(), - args -) -``` - -https://github.com/JetBrains/kotlin/blob/711b882e7176060fc7fe2968773a393c7be73cb8/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsExec.kt - -In `build.gradle.kts` I've configured the Kotlin Multiplatform plugin to download -the `typescript-to-lua` dependency - -```kotlin -plugins { - kotlin("multiplatform") -} - -kotlin { - js(IR) { - browser() - } - - sourceSets { - val jsMain: KotlinSourceSet by getting { - dependencies { - implementation(npm("typescript-to-lua", "1.1.1")) - } - } - } -} -``` - -and this correctly downloads the NPM module binaries: -`build/js/packages/data-model/node_modules/.bin/tstl` - From 523f6d5914dbd59a85ad7814d8cde2e5d9d929fa Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 17 Jul 2022 23:51:17 +0200 Subject: [PATCH 484/629] rm old 'projects must be configuring' workarounds that didn't work --- build.gradle.kts | 3 --- gradle.properties | 3 --- 2 files changed, 6 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 62e7b62..e7aa130 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,9 +6,6 @@ plugins { base `project-report` `build-dashboard` - -// kotlin("multiplatform") apply false // try to stop error 'Projects must be configuring' -// kotlin("js") apply false // try to stop error 'Projects must be configuring' } group = "dev.adamko.kafkatorio" diff --git a/gradle.properties b/gradle.properties index 7acfe41..e73b36e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,6 +11,3 @@ org.gradle.unsafe.configuration-cache-problems=warn org.gradle.kotlin.dsl.precompiled.accessors.strict=true org.gradle.parallel=true - -# pRoJeCtS mUsT bE cOnFiGuRiNg -#org.gradle.configureondemand=false From 085776d42bb3d8268443bb0eefdef348fa4f1d19 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 17 Jul 2022 23:54:53 +0200 Subject: [PATCH 485/629] packet size improvements - change structure resource packets - make more booleans default to false - use encode_string - massive decrease in packet size!! --- .../kafkatorio/schema/common/entities.kt | 97 +++++++------------ .../schema/common/factorioPrototypes.kt | 4 +- .../schema/packets/kafkatorioPacketInstant.kt | 4 +- .../schema/packets/kafkatorioPacketKeyed.kt | 23 ++++- .../dev/adamko/kafkatorio/schema/kt2ts2.kt | 2 +- .../lua/main/emitting/PacketEmitter.lua | 3 +- .../generated/lua/main/events/converters.lua | 7 -- .../events/handlers/EntityUpdateHandler.lua | 23 +++-- .../typescript/generated/kafkatorio-schema.ts | 28 +++--- .../typescript/main/emitting/PacketEmitter.ts | 6 +- .../main/typescript/main/events/converters.ts | 15 --- .../events/handlers/EntityUpdateHandler.ts | 20 ++-- .../server/processor/KafkatorioTopology.kt | 9 +- .../topology/factorioServerPackets.kt | 24 ++++- 14 files changed, 131 insertions(+), 134 deletions(-) diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/entities.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/entities.kt index 8bc91fd..d203ad8 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/entities.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/entities.kt @@ -18,41 +18,23 @@ sealed interface FactorioEntityData { /** Non-specific entity data */ @Serializable - @SerialName("kafkatorio.entity.FactorioEntityData") + @SerialName("kafkatorio.entity.FactorioEntityDataStandard") data class Standard( override val protoId: PrototypeId, - val status: Status? = null, - - val unitNumber: UnitNumber? = null, - override val position: MapEntityPosition, + val graphicsVariation: UByte? = null, val health: Float? = null, - val isActive: Boolean? = null, - val isRotatable: Boolean? = null, + val isActive: Boolean = false, + val isRotatable: Boolean = false, val lastUser: UInt? = null, - ) : FactorioEntityData { - constructor( - position: MapEntityPosition, - protoId: PrototypeId, - element: FactorioEntityUpdateElement.Entity - ) : this( - protoId = protoId, - position = position, - - status = element.status, - unitNumber = element.unitNumber, - graphicsVariation = element.graphicsVariation, - health = element.health, - isActive = element.isActive, - isRotatable = element.isRotatable, - lastUser = element.lastUser - ) - } + val status: Status? = null, + val unitNumber: UnitNumber? = null, + ) : FactorioEntityData @Serializable - @SerialName("kafkatorio.entity.FactorioResourceData") + @SerialName("kafkatorio.entity.FactorioEntityDataResource") data class Resource( override val protoId: PrototypeId, @@ -60,19 +42,7 @@ sealed interface FactorioEntityData { val amount: UInt, /** Count of initial resource units contained. `null` if resource is not infinite. */ val initialAmount: UInt? = null, - ) : FactorioEntityData { - constructor( - position: MapEntityPosition, - protoId: PrototypeId, - element: FactorioEntityUpdateElement.Resource - ) : this( - protoId = protoId, - position = position, - - amount = element.amount, - initialAmount = element.initialAmount, - ) - } + ) : FactorioEntityData /** @@ -193,7 +163,7 @@ sealed interface FactorioEntityData { } -sealed interface FactorioEntityUpdateDictionary +sealed interface FactorioEntityUpdateDictionary : Iterable> { val entitiesXY: Map> @@ -203,28 +173,37 @@ sealed interface FactorioEntityUpdateDictionary override fun iterator(): Iterator> = iterator { - entitiesXY.forEach { (x, column) -> - column.forEach { (y, entity) -> - yield( - MapEntityPosition(x.toDouble(), y.toDouble()) to entity - ) + val invalid = mutableListOf() + entitiesXY.forEach { (xString, column) -> + val x = xString.toDoubleOrNull() + column.forEach { (yString, entity) -> + val y = yString.toDoubleOrNull() + if (x == null || y == null) { + invalid += "$xString/$yString" + } else { + yield(MapEntityPosition(x, y) to entity) + } } } + + if (invalid.isNotEmpty()) { + println("WARNING FactorioEntityUpdateDictionary contained invalid x/y coords: ${invalid.joinToString()}") + } } @Serializable - @SerialName("kafkatorio.entity.FactorioEntityUpdateResourceDictionary") + @SerialName("kafkatorio.entity.FactorioEntityUpdateResourceAmountDictionary") @JvmInline - value class Resource( - override val entitiesXY: Map> - ) : FactorioEntityUpdateDictionary + value class ResourceAmounts( + override val entitiesXY: Map> = emptyMap() + ) : FactorioEntityUpdateDictionary @Serializable @SerialName("kafkatorio.entity.FactorioEntityUpdateEntityDictionary") @JvmInline value class Entity( - override val entitiesXY: Map> - ) : FactorioEntityUpdateDictionary + override val entitiesXY: Map> + ) : FactorioEntityUpdateDictionary } @@ -232,24 +211,16 @@ sealed interface FactorioEntityUpdateDictionary sealed interface FactorioEntityUpdateElement { @Serializable - @SerialName("kafkatorio.entity.FactorioEntityUpdateResource") - data class Resource( - val amount: UInt, - /** Count of initial resource units contained. `null` if resource is not infinite. */ - val initialAmount: UInt? = null, - ) : FactorioEntityUpdateElement - - @Serializable - @SerialName("kafkatorio.entity.FactorioEntityUpdateEntity") - data class Entity( + @SerialName("kafkatorio.entity.FactorioEntityUpdateElementStandard") + data class Standard( val status: FactorioEntityData.Status? = null, val unitNumber: UnitNumber? = null, val graphicsVariation: UByte? = null, val health: Float? = null, - val isActive: Boolean? = null, - val isRotatable: Boolean? = null, + val isActive: Boolean = false, + val isRotatable: Boolean = false, val lastUser: UInt? = null, ) : FactorioEntityUpdateElement diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt index 05c15af..fae8cee 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt @@ -24,7 +24,7 @@ sealed interface FactorioPrototype { val collisionMasks: LuaJsonList, val order: String, /** Can the tile be mined for resources? */ - val canBeMined: Boolean, + val canBeMined: Boolean = false, ) : FactorioPrototype @@ -63,7 +63,7 @@ sealed interface FactorioPrototype { @Serializable @SerialName("kafkatorio.prototype.EntityMiningProperties") data class MiningProperties( - val canBeMined: Boolean, + val canBeMined: Boolean = false, // @Contextual val products: LuaJsonList?, ) diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt index a0ee1b5..87203db 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt @@ -23,8 +23,8 @@ data class ConfigurationUpdate( val factorioData: ConfigurationUpdateGameData, // @Contextual val allMods: LuaJsonList, - val modStartupSettingsChange: Boolean, - val migrationApplied: Boolean, + val modStartupSettingsChange: Boolean = false, + val migrationApplied: Boolean = false, ) : KafkatorioInstantPacketData() { @Serializable diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt index 0eb3410..7abb190 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt @@ -7,6 +7,7 @@ import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData import dev.adamko.kafkatorio.schema.common.EventName import dev.adamko.kafkatorio.schema.common.FactorioEntityData import dev.adamko.kafkatorio.schema.common.FactorioEntityUpdateDictionary +import dev.adamko.kafkatorio.schema.common.FactorioEntityUpdateDictionary.ResourceAmounts import dev.adamko.kafkatorio.schema.common.ForceIndex import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapEntityPosition @@ -135,7 +136,7 @@ data class PlayerUpdate( val kickedReason: String? = null, val disconnectReason: String? = null, /** `true` when a player is removed (deleted) from the game */ - val isRemoved: Boolean? = null, + val isRemoved: Boolean = false, ) : KafkatorioKeyedPacketData() @@ -166,7 +167,14 @@ data class MapChunkEntityUpdate( FactorioEntityData.Standard( protoId = key.protoId, position = position, - element = entity, + + status = entity.status, + unitNumber = entity.unitNumber, + graphicsVariation = entity.graphicsVariation, + health = entity.health, + isActive = entity.isActive, + isRotatable = entity.isRotatable, + lastUser = entity.lastUser ) } } @@ -191,15 +199,20 @@ data class MapChunkResourceUpdate( override val events: Map>? = null, - val resourcesXY: FactorioEntityUpdateDictionary.Resource, + // Optimise JSON size by storing amounts separately. + val amounts: ResourceAmounts = ResourceAmounts(), + // Initial amount is only available for infinite resources, and infinite resources (oil) are more + // uncommon, so there are unlikely to be many per chunk + val initialAmounts: ResourceAmounts = ResourceAmounts(), ) : KafkatorioKeyedPacketData() { fun resources(): List = - resourcesXY.map { (position, resource) -> + amounts.map { (position, amount) -> FactorioEntityData.Resource( protoId = key.protoId, position = position, - element = resource, + amount = amount, + initialAmount = initialAmounts[position], ) } } diff --git a/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/schema/kt2ts2.kt b/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/schema/kt2ts2.kt index 6a095a4..19fb33d 100644 --- a/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/schema/kt2ts2.kt +++ b/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/schema/kt2ts2.kt @@ -99,7 +99,7 @@ class MySourceCodeGenerator( (element.typeRef as? TsTypeRef.Literal)?.element is TsLiteral.Custom || element.id.name == "Tick" || element.id.name == "FactorioEntityUpdateEntityDictionary" - || element.id.name == "FactorioEntityUpdateResourceDictionary" + || element.id.name == "FactorioEntityUpdateResourceAmountDictionary" ) { val aliasedRef = generateTypeReference(element.typeRef) """ diff --git a/modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua b/modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua index 1ff529d..0c3d2c8 100644 --- a/modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua +++ b/modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua @@ -15,7 +15,8 @@ function KafkatorioPacketEmitter.prototype.emitKeyedPacket(self, data) end function KafkatorioPacketEmitter.emitPacket(self, packet) local data = game.table_to_json(packet) - localised_print("KafkatorioPacket: " .. data) + local encoded = game.encode_string(data) + print("KafkatorioPacket encoded::: " .. tostring(encoded)) end local PacketEmitter = __TS__New(____exports.KafkatorioPacketEmitter) ____exports.default = PacketEmitter diff --git a/modules/events-mod/src/generated/lua/main/events/converters.lua b/modules/events-mod/src/generated/lua/main/events/converters.lua index 3b3e727..a279047 100644 --- a/modules/events-mod/src/generated/lua/main/events/converters.lua +++ b/modules/events-mod/src/generated/lua/main/events/converters.lua @@ -42,13 +42,6 @@ do end return masks end - function Converters.convertResourceEntity(entity) - if entity.type ~= "resource" then - return nil - else - return {amount = entity.amount, initialAmount = entity.initial_amount} - end - end local function convertEntityStatus(status) if status == nil then return nil diff --git a/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua b/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua index c18c0bb..6f852ca 100644 --- a/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua +++ b/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua @@ -142,16 +142,23 @@ function EntityUpdatesHandler.throttleResourcesUpdate(self, eventName, eventTick local ____data_events_eventName_17 = data.events[eventName] ____data_events_eventName_17[#____data_events_eventName_17 + 1] = eventTick for ____, entity in ipairs(resourceEntities) do - local resourceUpdate = Converters.convertResourceEntity(entity) - if resourceUpdate ~= nil then - if data.resourcesXY == nil then - data.resourcesXY = {} + if data.amounts == nil then + data.amounts = {} + end + local ____data_amounts_18, ____tostring_result_19 = data.amounts, tostring(entity.position.x) + if ____data_amounts_18[____tostring_result_19] == nil then + ____data_amounts_18[____tostring_result_19] = {} + end + data.amounts[tostring(entity.position.x)][tostring(entity.position.y)] = entity.amount + if entity.initial_amount ~= nil then + if data.initialAmounts == nil then + data.initialAmounts = {} end - local ____data_resourcesXY_18, ____tostring_result_19 = data.resourcesXY, tostring(entity.position.x) - if ____data_resourcesXY_18[____tostring_result_19] == nil then - ____data_resourcesXY_18[____tostring_result_19] = {} + local ____data_initialAmounts_20, ____tostring_result_21 = data.initialAmounts, tostring(entity.position.x) + if ____data_initialAmounts_20[____tostring_result_21] == nil then + ____data_initialAmounts_20[____tostring_result_21] = {} end - data.resourcesXY[tostring(entity.position.x)][tostring(entity.position.y)] = resourceUpdate + data.initialAmounts[tostring(entity.position.x)][tostring(entity.position.y)] = entity.initial_amount end end end diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts index a82fefe..d7f02fc 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts @@ -40,8 +40,8 @@ export namespace KafkatorioPacketData { type: KafkatorioPacketData.Type.ConfigurationUpdate; factorioData: ConfigurationUpdateGameData; allMods: ConfigurationUpdateModData[]; - modStartupSettingsChange: boolean; - migrationApplied: boolean; + modStartupSettingsChange?: boolean; + migrationApplied?: boolean; } export interface ConsoleChatUpdate { @@ -94,7 +94,8 @@ export namespace KafkatorioPacketData { type: KafkatorioPacketData.Type.MapChunkResourceUpdate; key: MapChunkResourceUpdateKey; events?: { [key: EventName]: Tick[] } | null; - resourcesXY: FactorioEntityUpdateResourceDictionary; + amounts?: FactorioEntityUpdateResourceAmountDictionary; + initialAmounts?: FactorioEntityUpdateResourceAmountDictionary; } export interface MapChunkTileUpdate { @@ -132,7 +133,7 @@ export namespace KafkatorioPacketData { bannedReason?: string | null; kickedReason?: string | null; disconnectReason?: string | null; - isRemoved?: boolean | null; + isRemoved?: boolean; } export interface Error { @@ -171,7 +172,7 @@ export interface MapChunkEntityUpdateKey { chunkPosition: MapChunkPosition; } -export type FactorioEntityUpdateEntityDictionary = { [key: string]: { [key: string]: FactorioEntityUpdateEntity } }; +export type FactorioEntityUpdateEntityDictionary = { [key: string]: { [key: string]: FactorioEntityUpdateElementStandard } }; export interface MapChunkResourceUpdateKey { protoId: PrototypeId; @@ -179,7 +180,7 @@ export interface MapChunkResourceUpdateKey { chunkPosition: MapChunkPosition; } -export type FactorioEntityUpdateResourceDictionary = { [key: string]: { [key: string]: FactorioEntityUpdateResource } }; +export type FactorioEntityUpdateResourceAmountDictionary = { [key: string]: { [key: string]: UInt } }; export interface MapChunkTileUpdateKey { chunkPosition: MapChunkPosition; @@ -251,7 +252,7 @@ export namespace FactorioPrototype { layer: UInt; collisionMasks: string[]; order: string; - canBeMined: boolean; + canBeMined?: boolean; } } @@ -274,7 +275,7 @@ export interface EntityItemGroup { } export interface EntityMiningProperties { - canBeMined: boolean; + canBeMined?: boolean; products: MinedProduct[] | null; } @@ -293,21 +294,16 @@ export enum ChunkSize { export type PrototypeKey = Int & { __PrototypeKey__: void }; -export interface FactorioEntityUpdateEntity { +export interface FactorioEntityUpdateElementStandard { status?: FactorioEntityStatus | null; unitNumber?: UnitNumber | null; graphicsVariation?: UByte | null; health?: Float | null; - isActive?: boolean | null; - isRotatable?: boolean | null; + isActive?: boolean; + isRotatable?: boolean; lastUser?: UInt | null; } -export interface FactorioEntityUpdateResource { - amount: UInt; - initialAmount?: UInt | null; -} - export type MinedProduct = | MinedProduct.MinedProductFluid | MinedProduct.MinedProductItem; diff --git a/modules/events-mod/src/main/typescript/main/emitting/PacketEmitter.ts b/modules/events-mod/src/main/typescript/main/emitting/PacketEmitter.ts index 5c3b943..c077e94 100644 --- a/modules/events-mod/src/main/typescript/main/emitting/PacketEmitter.ts +++ b/modules/events-mod/src/main/typescript/main/emitting/PacketEmitter.ts @@ -26,8 +26,10 @@ export class KafkatorioPacketEmitter { /** Emit a serialised KafkatorioPacket */ private static emitPacket(packet: T) { - let data = game.table_to_json(packet) - localised_print(`KafkatorioPacket: ${data}`) + const data = game.table_to_json(packet) + // print(`KafkatorioPacket::: ${data}`) + const encoded = game.encode_string(data) + print(`KafkatorioPacket encoded::: ${encoded}`) // rcon.print(`KafkatorioPacket: ${data}`) } diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index b2fb56d..84bda4a 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -5,7 +5,6 @@ import { EntityMiningProperties, EventName, FactorioEntityStatus, - FactorioEntityUpdateResource, KafkatorioPacketData, MapBoundingBox, MapChunkPosition, @@ -76,20 +75,6 @@ export namespace Converters { } - export function convertResourceEntity( - entity: LuaEntity - ): FactorioEntityUpdateResource | null { - if (entity.type != "resource") { - return null - } else { - return { - amount: entity.amount, - initialAmount: entity.initial_amount, - } - } - } - - function convertEntityStatus( status: defines.entity_status | undefined ): FactorioEntityStatus | null { diff --git a/modules/events-mod/src/main/typescript/main/events/handlers/EntityUpdateHandler.ts b/modules/events-mod/src/main/typescript/main/events/handlers/EntityUpdateHandler.ts index 6ccb787..b575d0d 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers/EntityUpdateHandler.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers/EntityUpdateHandler.ts @@ -1,6 +1,6 @@ import { EventName, - FactorioEntityUpdateEntity, + FactorioEntityUpdateElementStandard, KafkatorioPacketData, MapChunkPosition, PrototypeId, @@ -94,7 +94,7 @@ export class EntityUpdatesHandler { chunkPosition: Converters.mapPositionToChunkPosition(entity.position) } - const entityUpdate: FactorioEntityUpdateEntity = { + const entityUpdate: FactorioEntityUpdateElementStandard = { unitNumber: entity.unit_number, graphicsVariation: entity.graphics_variation, health: entity.health, @@ -140,7 +140,7 @@ export class EntityUpdatesHandler { for (const [protoId, resourceEntities] of pairs(entitiesByProtoId)) { - // create an update for each prototype ID + // create a MapChunkResourceUpdate for each prototype ID const entityUpdateKey: KafkatorioPacketData.MapChunkResourceUpdate["key"] = { protoId: protoId, @@ -158,18 +158,20 @@ export class EntityUpdatesHandler { data.events[eventName].push(eventTick) for (const entity of resourceEntities) { - const resourceUpdate = Converters.convertResourceEntity(entity) - if (resourceUpdate != null) { - data.resourcesXY ??= {} - data.resourcesXY[`${entity.position.x}`] ??= {} - data.resourcesXY[`${entity.position.x}`][`${entity.position.y}`] = resourceUpdate + data.amounts ??= {} + data.amounts[`${entity.position.x}`] ??= {} + data.amounts[`${entity.position.x}`][`${entity.position.y}`] = entity.amount + + if (entity.initial_amount != null) { + data.initialAmounts ??= {} + data.initialAmounts[`${entity.position.x}`] ??= {} + data.initialAmounts[`${entity.position.x}`][`${entity.position.y}`] = entity.initial_amount } } } ) } - } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt index 4d05dcf..f2897f8 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt @@ -167,6 +167,7 @@ internal class KafkatorioTopology( } + /** Receive log messages from the syslog socket, and send them to a Kafka topic */ private fun syslogProducer( id: String = "syslog-producer" ) { @@ -187,10 +188,14 @@ internal class KafkatorioTopology( } syslogServer.messages - .filter { it.message?.startsWith("KafkatorioPacket:") == true } + .filter { + (it.message ?: "").run { + startsWith("KafkatorioPacket:::") || startsWith("KafkatorioPacket encoded:::") + } + } .onEach { syslogMsg -> - val kafkatorioMessage = syslogMsg.message?.substringAfter("KafkatorioPacket:") + val kafkatorioMessage = syslogMsg.message?.substringAfter(":::") val record = ProducerRecord( TOPIC_SRC_SERVER_LOG, diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt index cfb4567..bb2b3e9 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt @@ -14,7 +14,13 @@ import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.streams.map import dev.adamko.kotka.extensions.streams.to import dev.adamko.kotka.kxs.serde +import java.util.zip.Inflater import kotlinx.serialization.decodeFromString +import okio.Buffer +import okio.ByteString +import okio.ByteString.Companion.decodeBase64 +import okio.buffer +import okio.inflate import org.apache.kafka.common.serialization.Serdes import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.kstream.KStream @@ -33,7 +39,8 @@ fun factorioServerPacketStream( ) ).map("decode-packets") { serverId: String, value: String -> val packet = runCatching { - jsonMapper.decodeFromString(value) + val decoded = decodeFactorioEncodedString(value) + jsonMapper.decodeFromString(decoded) }.getOrElse { e -> KafkatorioPacket( modVersion = "unknown", @@ -69,3 +76,18 @@ fun splitFactorioServerPacketStream( value.data.topicName } } + + +/** + * Factorio `game.encode_string` zlib encodes a string, then base64's it. Here we do the reverse. + */ +private fun decodeFactorioEncodedString( + source: String +): String { + val bytes: ByteString = source.decodeBase64() ?: error("failed to base64 decode $source") + + return Buffer().write(bytes) + .inflate(Inflater()) + .buffer() + .readString(Charsets.UTF_8) +} From 6fa826baa2ba0a371fd369c140fa20e12982ef7e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 17 Jul 2022 23:55:58 +0200 Subject: [PATCH 486/629] return 304 if a tile doesn't exist (nicer than having the browser spammed with errors) --- .../server/web/rest/factorioServersRoutes.kt | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt index 1a42e16..283d767 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt @@ -61,20 +61,9 @@ private suspend fun PipelineContext.handleTileRequest( ) } } else { - call.respond(HttpStatusCode.NotFound) -// // It's not a client error to request this tile, it just doesn't exist (yet). So return 304? -// call.response.cacheControl(CacheControl.NoStore(null)) -// -// HeadersBuilder(size = 2).apply { -// EntityTagVersion(System.currentTimeMillis().hashCode().toString()) -// .appendHeadersTo(this) -// LastModifiedVersion(System.currentTimeMillis()) -// .appendHeadersTo(this) -// }.build().flattenForEach { name, value -> -// call.response.header(name, value) -// } -// -// call.respond(HttpStatusCode.NotModified) + // It's not a client or server error to request a non-existent tile, it just doesn't exist + // (yet). So return 304. + call.respond(HttpStatusCode.NotModified) } } From d006635e49de72a977fd1df852b91b5662f05007 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 23 Jul 2022 16:26:11 +0200 Subject: [PATCH 487/629] bump tstl, typed-factorio, ks-js-wrappers --- gradle/libs.versions.toml | 2 +- modules/events-mod/package-lock.json | 12 ++--- modules/events-mod/package.json | 4 +- .../src/generated/lua/lualib_bundle.lua | 45 ++++++++++++++++--- 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 63f4605..5fb90e7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -25,7 +25,7 @@ kxs-charleskornKaml = "0.44.0" kxs-mamoeYamlkt = "0.12.0" kxs-kxsTsGen = "0.2.1" -kotlinJsWrappers = "1.0.0-pre.357" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom +kotlinJsWrappers = "1.0.0-pre.359" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom kotlinx-cli = "0.3.4" kotlinx-coroutines = "1.6.4" # https://github.com/Kotlin/kotlinx.coroutines/releases diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index fe903b7..eff221b 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -75,9 +75,9 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.3.2.tgz", - "integrity": "sha512-sAVIDvSSBPWL7trI94SPd2Suq9dLjXmXL1WFKJIYJpFQocNwJUb0ydGRBsvJjZhVAyEZYJC0lHlDWH47RWP/tw==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.4.0.tgz", + "integrity": "sha512-hT5YDtdJk/hVIm83hYlXx2vOSmhElQhHhcI0OIrdx2nmrx18zKEnjGk4abJ6WHjuy4xoVZ+00mjnC3mWclvrzw==" }, "typescript": { "version": "4.7.4", @@ -85,9 +85,9 @@ "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" }, "typescript-to-lua": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.6.3.tgz", - "integrity": "sha512-yfXxGjOwX6453wSgEB37lLdxZZ8m+LH1g3PfebNfKaZHGGtbm9owxE6oRKB3sWcy2CICkfobAjWf3VdhKnEETg==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.7.1.tgz", + "integrity": "sha512-iDjCnel38p3Cxv+Las8rBzd6BaRIE49DQSyFOgupg4gSw36+8H1xtwde3lRdGMPZx19/zVwXEO8UspiACYJc+A==", "requires": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index bc5da72..d9a4fc4 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -12,8 +12,8 @@ "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", - "typescript-to-lua": "1.6.3", - "typed-factorio": "1.3.2", + "typescript-to-lua": "1.7.1", + "typed-factorio": "1.4.0", "typescript": "4.7.4" }, "license": "UNLICENSED", diff --git a/modules/events-mod/src/generated/lua/lualib_bundle.lua b/modules/events-mod/src/generated/lua/lualib_bundle.lua index cdebff7..e118180 100644 --- a/modules/events-mod/src/generated/lua/lualib_bundle.lua +++ b/modules/events-mod/src/generated/lua/lualib_bundle.lua @@ -345,7 +345,11 @@ end local function __TS__ArraySlice(self, first, last) local len = #self - first = first or 0 + local ____first_0 = first + if ____first_0 == nil then + ____first_0 = 0 + end + first = ____first_0 if first < 0 then first = len + first if first < 0 then @@ -356,7 +360,11 @@ local function __TS__ArraySlice(self, first, last) first = len end end - last = last or len + local ____last_1 = last + if ____last_1 == nil then + ____last_1 = len + end + last = ____last_1 if last < 0 then last = len + last if last < 0 then @@ -412,7 +420,11 @@ local function __TS__ArraySplice(self, ...) elseif actualArgumentCount == 1 then actualDeleteCount = len - start else - actualDeleteCount = deleteCount or 0 + local ____deleteCount_0 = deleteCount + if ____deleteCount_0 == nil then + ____deleteCount_0 = 0 + end + actualDeleteCount = ____deleteCount_0 if actualDeleteCount < 0 then actualDeleteCount = 0 end @@ -1175,7 +1187,14 @@ do local args = {...} local argsLength = select("#", ...) return { - ____coroutine = coroutine.create(function() return fn((unpack or table.unpack)(args, 1, argsLength)) end), + ____coroutine = coroutine.create(function() + local ____fn_1 = fn + local ____unpack_0 = unpack + if ____unpack_0 == nil then + ____unpack_0 = table.unpack + end + return ____fn_1(____unpack_0(args, 1, argsLength)) + end), [Symbol.iterator] = generatorIterator, next = generatorNext } @@ -1553,7 +1572,11 @@ local function __TS__ParseFloat(numberString) return ____temp_0 end local number = tonumber(string.match(numberString, "^%s*(-?%d+%.?%d*)")) - return number or 0 / 0 + local ____number_1 = number + if ____number_1 == nil then + ____number_1 = 0 / 0 + end + return ____number_1 end local function __TS__StringSubstr(self, from, length) @@ -1947,7 +1970,11 @@ local function __TS__SparseArrayPush(sparseArray, ...) end local function __TS__SparseArraySpread(sparseArray) - local _unpack = unpack or table.unpack + local ____unpack_0 = unpack + if ____unpack_0 == nil then + ____unpack_0 = table.unpack + end + local _unpack = ____unpack_0 return _unpack(sparseArray, 1, sparseArray.sparseLength) end @@ -2127,7 +2154,11 @@ local function __TS__StringCharCodeAt(self, index) if index < 0 then return 0 / 0 end - return string.byte(self, index + 1) or 0 / 0 + local ____string_byte_result_0 = string.byte(self, index + 1) + if ____string_byte_result_0 == nil then + ____string_byte_result_0 = 0 / 0 + end + return ____string_byte_result_0 end local function __TS__StringEndsWith(self, searchString, endPosition) From 7f95304fa72e98163151af0ad986a1dd3564a8cd Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 23 Jul 2022 16:26:26 +0200 Subject: [PATCH 488/629] fix tests after 'booleans default to false' on DTOs --- .../adamko/kafkatorio/schema/packets/UpdatePacketsTest.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/UpdatePacketsTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/UpdatePacketsTest.kt index 937fd5d..a983c03 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/UpdatePacketsTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/UpdatePacketsTest.kt @@ -75,7 +75,7 @@ class UpdatePacketsTest : FunSpec({ forceIndex = ForceIndex(1u), isAdmin = true, isConnected = true, - isRemoved = null, +// isRemoved = false, isShowOnMap = true, isSpectator = false, kickedReason = null, @@ -116,7 +116,7 @@ class UpdatePacketsTest : FunSpec({ bannedReason = null, kickedReason = null, disconnectReason = null, - isRemoved = null, +// isRemoved = null, ) ) @@ -196,7 +196,7 @@ class UpdatePacketsTest : FunSpec({ key = PlayerUpdateKey(PlayerIndex(1u)), // isAdmin = , isConnected = true, - isRemoved = null, +// isRemoved = null, // isShowOnMap = , // isSpectator = , kickedReason = null, From c5e9e619b56e45359b0b851a5404002bcadbb1d1 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 13 Aug 2022 11:56:07 +0200 Subject: [PATCH 489/629] gradle 7.5.1 --- build.gradle.kts | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 59821 -> 60756 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 6 ++++++ gradlew.bat | 14 ++++++++------ 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index e7aa130..cdec9be 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -36,7 +36,7 @@ idea { } tasks.wrapper { - gradleVersion = "7.5" + gradleVersion = "7.5.1" distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 41d9927a4d4fb3f96a785543079b8df6723c946b..249e5832f090a2944b7473328c07c9755baa3196 100644 GIT binary patch delta 10197 zcmaKS1ymhDwk=#NxVyW%y9U<)A-Dv)xI0|j{UX8L-JRg>5ZnnKAh;%chM6~S-g^K4 z>eZ{yK4;gd>gwvXs=Id8Jk-J}R4pT911;+{Jp9@aiz6!p1Oz9z&_kGLA%J5%3Ih@0 zQ|U}%$)3u|G`jIfPzMVfcWs?jV2BO^*3+q2><~>3j+Z`^Z%=;19VWg0XndJ zwJ~;f4$;t6pBKaWn}UNO-wLCFHBd^1)^v%$P)fJk1PbK5<;Z1K&>k~MUod6d%@Bq9 z>(44uiaK&sdhwTTxFJvC$JDnl;f}*Q-^01T508(8{+!WyquuyB7R!d!J)8Ni0p!cV6$CHsLLy6}7C zYv_$eD;)@L)tLj0GkGpBoa727hs%wH$>EhfuFy{_8Q8@1HI%ZAjlpX$ob{=%g6`Ox zLzM!d^zy`VV1dT9U9(^}YvlTO9Bf8v^wMK37`4wFNFzW?HWDY(U(k6@tp(crHD)X5>8S-# zW1qgdaZa*Sh6i%60e1+hty}34dD%vKgb?QmQiZ=-j+isA4={V_*R$oGN#j|#ia@n6 zuZx4e2Xx?^lUwYFn2&Tmbx0qA3Z8;y+zKoeQu;~k~FZGy!FU_TFxYd!Ck;5QvMx9gj5fI2@BLNp~Ps@ zf@k<&Q2GS5Ia9?_D?v~$I%_CLA4x~eiKIZ>9w^c#r|vB?wXxZ(vXd*vH(Fd%Me8p( z=_0)k=iRh%8i`FYRF>E97uOFTBfajv{IOz(7CU zv0Gd84+o&ciHlVtY)wn6yhZTQQO*4Mvc#dxa>h}82mEKKy7arOqU$enb9sgh#E=Lq zU;_RVm{)30{bw+|056%jMVcZRGEBSJ+JZ@jH#~DvaDQm92^TyUq=bY*+AkEakpK>8 zB{)CkK48&nE5AzTqT;WysOG|!y}5fshxR8Ek(^H6i>|Fd&wu?c&Q@N9ZrJ=?ABHI! z`*z8D`w=~AJ!P-9M=T}f`;76$qZRllB&8#9WgbuO$P7lVqdX1=g*t=7z6!0AQ^ux_ z9rcfUv^t}o_l-ZE+TqvqFsA*~W<^78!k;~!i8(eS+(+@u8FxK+Q7;mHZ<1}|4m<}vh@p`t%|@eM_J(P% zI>M7C)Ir{l|J;$G_EGGEhbP4?6{sYzMqBv+x95N&YWFH6UcE@b}B?q)G*4<4mR@sy1#vPnLMK51tb#ED(8TA1nE zYfhK7bo1!R5WJF$5Y?zG21)6+_(_5oSX9sGIW;(O&S?Rh(nydNQYzKjjJ54aDJ-1F zrJ=np8LsN?%?Rt7f~3aAX!2E{`fh_pb?2(;HOB3W+I*~A>W%iY+v45+^e$cE10fA} zXPvw9=Bd+(;+!rl)pkYj0HGB}+3Z!Mr;zr%gz~c-hFMv8b2VRE2R$8V=_XE zq$3=|Yg05(fmwrJ)QK2ptB4no`Y8Dg_vK2QDc6-6sXRQ5k78-+cPi-fH}vpgs|Ive zE=m*XNVs?EWgiNI!5AcD*3QMW)R`EqT!f0e1%hERO&?AT7HWnSf5@#AR{OGuXG3Zb zCnVWg7h|61lGV3k+>L<#d>)InG>ETn1DbOHCfztqzQ_fBiaUt@q6VMy={Fe-w#~2- z0?*f|z$zgjI9>+JVICObBaK=pU}AEOd@q(8d?j7zQFD@=6t`|KmolTr2MfBI$;EGh zD%W0cA_d#V6Lb$us5yIG(|d>r-QleC4;%hEu5W9hyY zY#+ESY&v`8(&mC~?*|e5WEhC!YU2>m_}`K+q9)a(d$bsS<=YkyZGp}YA%TXw>@abA zS_poVPoN+?<6?DAuCNt&5SHV(hp56PJ})swwVFZFXM->F zc|0c8<$H_OV%DR|y7e+s$12@Ac8SUClPg8_O9sTUjpv%6Jsn5vsZCg>wL+db4c+{+ zsg<#wOuV4jeOq`veckdi-1`dz;gvL)bZeH|D*x=8UwRU5&8W1@l>3$)8WzET0%;1J zM3(X<7tKK&9~kWRI{&FmwY5Gg!b5f4kI_vSm)H1#>l6M+OiReDXC{kPy!`%Ecq-+3yZTk=<` zm)pE6xum5q0Qkd#iny0Q-S}@I0;mDhxf>sX)Oiv)FdsAMnpx%oe8OQ`m%Xeozdzx!C1rQR>m1c_}+J4x)K}k{G zo68;oGG&Ox7w^-m7{g4a7NJu-B|~M;oIH~~#`RyUNm##feZH;E?pf}nshmoiIY52n z%pc%lnU4Q#C=RUz)RU6}E_j4#)jh<&a%JyJj$Fufc#&COaxFHtl}zJUGNLBu3~_@1 zn9F^JO9);Duxo&i@>X(kbYga1i>6p1fca8FzQ0>((Lb-aPUbC*d~a03V$y;*RBY!R ziEJ2IF^FjrvO}0Uy{cMn%u<+P5U!UO>pm9#ZYL5i6|xSC+np7IH$GfXs&uI;y4as@ z&AzJh>(S2?3PKKgab3Z(`xbx(C#46XIvVcW8eG_DjT~}Yz_8PWZ`uf6^Xr=vkvL_` zqmvfgJL+Zc`;iq~iP?%@G7}~fal-zqxa0yNyHBJJ5M)9bI>7S_cg?Ya&p(I)C5Ef4 zZ>YAF6x|U=?ec?g*|f2g5Tw3PgxaM_bi_5Az9MO$;_Byw(2d}2%-|bg4ShdQ;)Z|M z4K|tFv)qx*kKGKoyh!DQY<{n&UmAChq@DJrQP>EY7g1JF(ih*D8wCVWyQ z5Jj^|-NVFSh5T0vd1>hUvPV6?=`90^_)t(L9)XOW7jeP45NyA2lzOn&QAPTl&d#6P zSv%36uaN(9i9WlpcH#}rmiP#=L0q(dfhdxvFVaOwM;pY;KvNQ9wMyUKs6{d}29DZQ z{H3&Sosr6)9Z+C>Q5)iHSW~gGoWGgK-0;k~&dyr-bA3O|3PCNzgC?UKS_B=^i8Ri^ zd_*_qI4B07Cayq|p4{`U_E_P=K`N_~{F|+-+`sCgcNxs`%X!$=(?l2aAW}0M=~COb zf19oe^iuAUuDEf)4tgv<=WRPpK@IjToNNC*#&Ykw!)aqWU4h#|U@(cG_=Qx+&xt~a zvCz~Ds3F71dsjNLkfM%TqdVNu=RNMOzh7?b+%hICbFlOAPphrYy>7D-e7{%o_kPFn z;T!?ilE-LcKM0P(GKMseEeW57Vs`=FF}(y@^pQl;rL3fHs8icmA+!6YJt&8 ztSF?%Un35qkv>drkks&BNTJv~xK?vD;aBkp7eIkDYqn+G0%;sT4FcwAoO+vke{8CO z0d76sgg$CannW5T#q`z~L4id)9BCKRU0A!Z-{HpXr)QJrd9@iJB+l32Ql)Z}*v(St zE)Vp=BB=DDB4Pr}B(UHNe31<@!6d{U?XDoxJ@S)9QM)2L%SA0x^~^fb=bdsBy!uh& zU?M_^kvnt%FZzm+>~bEH{2o?v&Iogs`1t-b+Ml`J!ZPS(46YQJKxWE81O$HE5w;** z|8zM%bp`M7J8)4;%DqH`wVTmM0V@D}xd%tRE3_6>ioMJxyi5Hkb>85muF81&EY!73ei zA3e<#ug||EZJ=1GLXNJ)A z791&ge#lF;GVX6IU?iw0jX^1bYaU?+x{zPlpyX6zijyn*nEdZ$fxxkl!a-~*P3bkf zPd*pzu~3GBYkR_>ET`5UM^>>zTV>5m>)f=az{d0sg6a8VzUtXy$ZS?h#Gk-CA?7)c zI%Vu9DN6XSDQn6;?n9`>l$q&>s?K)R8*OsmI+$L_m z_~E`}w694Z*`Xk3Ne=497Si~=RWRqCM?6=88smrxle#s*W znwhTRsMRmg?37GLJ-)%nDZA7r$YG849j8mJWir1bWBy& zZPneYojSbooC8U@tkO`bWx4%E5*;p#Q^1^S3lsfy7(6A{jL0`A__0vm?>xC%1y8_m z57FfWr^@YG2I1K7MGYuYd>JC}@sT2n^rkrY3w%~$J$Y~HSoOHn?zpR$ zjLj_bq@Yj8kd~DXHh30KVbz@K)0S;hPKm+S&-o%IG+@x@MEcrxW2KFh;z^4dJDZix zGRGe&lQD$p)0JVF4NRgGYuh0bYLy)BCy~sbS3^b3 zHixT<%-Vwbht|25T{3^Hk;qZ^3s!OOgljHs+EIf~C%=_>R5%vQI4mQR9qOXThMXlU zS|oSH>0PjnCakb*js2{ObN`}%HYsT6=%(xA| znpUtG_TJ08kHgm5l@G|t?4E3tG2fq?wNtIp*Vqrb{9@bo^~Rx7+J&OnayrX`LDcF~ zd@0m0ZJ#Z@=T>4kTa5e2FjI&5c(F7S{gnRPoGpu9eIqrtSvnT_tk$8T)r%YwZw!gK zj*k@cG)V&@t+mtDi37#>LhVGTfRA^p%x0d#_P|Mktz3*KOoLIqFm`~KGoDDD4OOxe z?}ag_c08u%vu=5Vx=~uoS8Q;}+R2~?Uh|m-+`-2kDo$d6T!nD*hc#dB(*R{LXV=zo z`PJP0V=O!@3l-bw+d`X6(=@fq=4O#ETa8M^fOvO4qja9o3e8ANc9$sI=A4$zUut~w z4+JryRkI{9qWxU1CCMM$@Aj=6)P+z?vqa=UCv_4XyVNoBD{Xb~Oi4cjjhm8fRD!*U z2)zaS;AI78^Wq+5mDInKiMz|z#K`2emQfNH*U;{9^{NqSMVoq?RSo43<8YpJM^+W$ zxy!A5>5Zl16Vi#?nAYywu3w_=KWnd3*QetocWt`3pK67>)ZVwnT3h zbPdD&MZkD?q=-N`MpCCwpM74L+Tr1aa)zJ)8G;(Pg51@U&5W>aNu9rA`bh{vgfE={ zdJ>aKc|2Ayw_bop+dK?Y5$q--WM*+$9&3Q9BBiwU8L<-`T6E?ZC`mT0b}%HR*LPK} z!MCd_Azd{36?Y_>yN{U1w5yrN8q`z(Vh^RnEF+;4b|2+~lfAvPT!`*{MPiDioiix8 zY*GdCwJ{S(5(HId*I%8XF=pHFz<9tAe;!D5$Z(iN#jzSql4sqX5!7Y?q4_%$lH zz8ehZuyl0K=E&gYhlfFWabnSiGty$>md|PpU1VfaC5~kskDnZX&Yu}?-h;OSav=8u z=e3Yq=mi$4A|sB-J00;1d{Sd1+!v0NtU((Nz2;PFFlC}V{@p&4wGcVhU&nI($RAS! zwXn7)?8~1J3*4+VccRSg5JS<(bBhBM&{ELMD4C_NTpvzboH!{Zr*%HP;{UqxI#g&7 zOAqPSW5Qus$8-xtTvD%h{Tw<2!XR(lU54LZG{)Cah*LZbpJkA=PMawg!O>X@&%+5XiyeIf91n2E*hl$k-Y(3iW*E}Mz-h~H~7S9I1I zR#-j`|Hk?$MqFhE4C@=n!hN*o5+M%NxRqP+aLxDdt=wS6rAu6ECK*;AB%Nyg0uyAv zO^DnbVZZo*|Ef{nsYN>cjZC$OHzR_*g%T#oF zCky9HJS;NCi=7(07tQXq?V8I&OA&kPlJ_dfSRdL2bRUt;tA3yKZRMHMXH&#W@$l%-{vQd7y@~i*^qnj^`Z{)V$6@l&!qP_y zg2oOd!Wit#)2A~w-eqw3*Mbe)U?N|q6sXw~E~&$!!@QYX4b@%;3=>)@Z#K^`8~Aki z+LYKJu~Y$;F5%_0aF9$MsbGS9Bz2~VUG@i@3Fi2q(hG^+Ia44LrfSfqtg$4{%qBDM z_9-O#3V+2~W$dW0G)R7l_R_vw(KSkC--u&%Rs^Io&*?R=`)6BN64>6>)`TxyT_(Rd zUn+aIl1mPa#Jse9B3`!T=|e!pIp$(8ZOe0ao?nS7o?oKlj zypC-fMj1DHIDrh1unUI1vp=-Fln;I9e7Jvs3wj*^_1&W|X} zZSL|S|Bb@CV*YC_-T&2!Ht3b6?)d`tHOP?rA;;t#zaXa0Sc;vGnV0BLIf8f-r{QHh z*Zp`4_ItlOR7{u(K+!p_oLDmaAkNag*l4#29F2b_A*0oz0T|#-&f*;c#<`^)(W@gm z#k9k=t%u8<+C1fNUA{Fh7~wgPrEZZ#(6aBI%6bR4RO(e1(ZocjoDek4#MTgZD>1NG zy9~yoZfWYfwe&S-(zk4o6q6o?2*~DOrJ(%5wSnEJMVOKCzHd z=Yhm+HLzoDl{P*Ybro7@sk1!Ez3`hE+&qr7Rw^2glw^M(b(NS2!F|Q!mi|l~lF94o z!QiV)Q{Z>GO5;l1y!$O)=)got;^)%@v#B!ZEVQy1(BJApHr5%Zh&W|gweD+%Ky%CO ztr45vR*y(@*Dg_Qw5v~PJtm^@Lyh*zRuT6~(K+^HWEF{;R#L$vL2!_ndBxCtUvZ(_ zauI7Qq}ERUWjr&XW9SwMbU>*@p)(cuWXCxRK&?ZoOy>2VESII53iPDP64S1pl{NsC zD;@EGPxs&}$W1;P6BB9THF%xfoLX|4?S;cu@$)9OdFst-!A7T{(LXtdNQSx!*GUSIS_lyI`da8>!y_tpJb3Zuf0O*;2y?HCfH z5QT6@nL|%l3&u4;F!~XG9E%1YwF*Fgs5V&uFsx52*iag(?6O|gYCBY3R{qhxT-Etb zq(E%V=MgQnuDGEKOGsmBj9T0-nmI%zys8NSO>gfJT4bP>tI>|ol@ zDt(&SUKrg%cz>AmqtJKEMUM;f47FEOFc%Bbmh~|*#E zDd!Tl(wa)ZZIFwe^*)4>{T+zuRykc3^-=P1aI%0Mh}*x7%SP6wD{_? zisraq`Las#y-6{`y@CU3Ta$tOl|@>4qXcB;1bb)oH9kD6 zKym@d$ zv&PZSSAV1Gwwzqrc?^_1+-ZGY+3_7~a(L+`-WdcJMo>EWZN3%z4y6JyF4NR^urk`c z?osO|J#V}k_6*9*n2?j+`F{B<%?9cdTQyVNm8D}H~T}?HOCXt%r7#2hz97Gx#X%62hyaLbU z_ZepP0<`<;eABrHrJAc!_m?kmu#7j}{empH@iUIEk^jk}^EFwO)vd7NZB=&uk6JG^ zC>xad8X$h|eCAOX&MaX<$tA1~r|hW?-0{t4PkVygTc`yh39c;&efwY(-#;$W)+4Xb z$XFsdG&;@^X`aynAMxsq)J#KZXX!sI@g~YiJdHI~r z$4mj_?S29sIa4c$z)19JmJ;Uj?>Kq=0XuH#k#};I&-6zZ_&>)j>UR0XetRO!-sjF< zd_6b1A2vfi++?>cf}s{@#BvTD|a%{9si7G}T+8ZnwuA z1k8c%lgE<-7f~H`cqgF;qZ|$>R-xNPA$25N1WI3#n%gj}4Ix}vj|e=x)B^roGQpB) zO+^#nO2 zjzJ9kHI6nI5ni&V_#5> z!?<7Qd9{|xwIf4b0bRc;zb}V4>snRg6*wl$Xz`hRDN8laL5tg&+@Dv>U^IjGQ}*=XBnXWrwTy;2nX?<1rkvOs#u(#qJ=A zBy>W`N!?%@Ay=upXFI}%LS9bjw?$h)7Dry0%d}=v0YcCSXf9nnp0tBKT1eqZ-4LU` zyiXglKRX)gtT0VbX1}w0f2ce8{$WH?BQm@$`ua%YP8G@<$n13D#*(Yd5-bHfI8!on zf5q4CPdgJLl;BqIo#>CIkX)G;rh|bzGuz1N%rr+5seP${mEg$;uQ3jC$;TsR&{IX< z;}7j3LnV+xNn^$F1;QarDf6rNYj7He+VsjJk6R@0MAkcwrsq4?(~`GKy|mgkfkd1msc2>%B!HpZ~HOzj}kl|ZF(IqB=D6ZTVcKe=I7)LlAI=!XU?J*i#9VXeKeaG zwx_l@Z(w`)5Cclw`6kQKlS<;_Knj)^Dh2pL`hQo!=GPOMR0iqEtx12ORLpN(KBOm5 zontAH5X5!9WHS_=tJfbACz@Dnkuw|^7t=l&x8yb2a~q|aqE_W&0M|tI7@ilGXqE)MONI8p67OiQGqKEQWw;LGga=ZM1;{pSw1jJK_y$vhY6 ztFrV7-xf>lbeKH1U)j3R=?w*>(Yh~NNEPVmeQ8n}0x01$-o z2Jyjn+sXhgOz>AzcZ zAbJZ@f}MBS0lLKR=IE{z;Fav%tcb+`Yi*!`HTDPqSCsFr>;yt^^&SI2mhKJ8f*%ji zz%JkZGvOn{JFn;)5jf^21AvO-9nRzsg0&CPz;OEn07`CfT@gK4abFBT$Mu?8fCcscmRkK+ zbAVJZ~#_a z{|(FFX}~8d3;DW8zuY9?r#Dt>!aD>} zlYw>D7y#eDy+PLZ&XKIY&Df0hsLDDi(Yrq8O==d30RchrUw8a=Eex>Dd?)3+k=}Q> z-b85lun-V$I}86Vg#l1S@1%=$2BQD5_waAZKQfJ${3{b2SZ#w1u+jMr{dJMvI|Og= zpQ9D={XK|ggbe04zTUd}iF{`GO1dV%zWK~?sM9OM(= zVK9&y4F^w1WFW{$qi|xQk0F`@HG8oLI5|5$j~ci9xTMT69v5KS-Yym--raU5kn2#C z<~5q^Bf0rTXVhctG2%&MG(cUGaz(gC(rcG~>qgO$W6>!#NOVQJ;pIYe-lLy(S=HgI zPh;lkL$l+FfMHItHnw_^bj8}CKM19t(C_2vSrhX2$K@-gFlH};#C?1;kk&U1L%4S~ zR^h%h+O1WE7DI$~dly?-_C7>(!E`~#REJ~Xa7lyrB$T!`&qYV5QreAa^aKr%toUJR zPWh)J3iD`(P6BI5k$oE$us#%!4$>`iH2p-88?WV0M$-K)JDibvA4 zpef%_*txN$Ei3=Lt(BBxZ&mhl|mUz-z*OD1=r9nfN zc5vOMFWpi>K=!$6f{eb?5Ru4M3o;t9xLpry|C%j~`@$f)OFB5+xo8XM8g&US@UU-sB|dAoc20y(F@=-2Ggp_`SWjEb#>IG^@j zuQK}e^>So#W2%|-)~K!+)wdU#6l>w5wnZt2pRL5Dz#~N`*UyC9tYechBTc2`@(OI# zNvcE*+zZZjU-H`QOITK^tZwOyLo)ZCLk>>Wm+flMsr5X{A<|m`Y281n?8H_2Fkz5}X?i%Rfm5s+n`J zDB&->=U+LtOIJ|jdYXjQWSQZFEs>Rm{`knop4Sq)(}O_@gk{14y51)iOcGQ5J=b#e z2Yx^6^*F^F7q_m-AGFFgx5uqyw6_4w?yKCJKDGGprWyekr;X(!4CnM5_5?KgN=3qCm03 z##6k%kIU5%g!cCL(+aK>`Wd;dZ4h$h_jb7n?nqx5&o9cUJfr%h#m4+Bh)>HodKcDcsXDXwzJ3jR(sSFqWV(OKHC*cV8;;&bH=ZI0YbW3PgIHwTjiWy z?2MXWO2u0RAEEq(zv9e%Rsz|0(OKB?_3*kkXwHxEuazIZ7=JhaNV*P~hv57q55LoebmJpfHXA@yuS{Esg+ z*C}0V-`x^=0nOa@SPUJek>td~tJ{U1T&m)~`FLp*4DF77S^{|0g%|JIqd-=5)p6a` zpJOsEkKT(FPS@t^80V!I-YJbLE@{5KmVXjEq{QbCnir%}3 zB)-J379=wrBNK6rbUL7Mh^tVmQYn-BJJP=n?P&m-7)P#OZjQoK0{5?}XqJScV6>QX zPR>G{xvU_P;q!;S9Y7*07=Z!=wxIUorMQP(m?te~6&Z0PXQ@I=EYhD*XomZ^z;`Os z4>Uh4)Cg2_##mUa>i1Dxi+R~g#!!i{?SMj%9rfaBPlWj_Yk)lCV--e^&3INB>I?lu z9YXCY5(9U`3o?w2Xa5ErMbl5+pDVpu8v+KJzI9{KFk1H?(1`_W>Cu903Hg81vEX32l{nP2vROa1Fi!Wou0+ZX7Rp`g;B$*Ni3MC-vZ`f zFTi7}c+D)!4hz6NH2e%%t_;tkA0nfkmhLtRW%){TpIqD_ev>}#mVc)<$-1GKO_oK8 zy$CF^aV#x7>F4-J;P@tqWKG0|D1+7h+{ZHU5OVjh>#aa8+V;6BQ)8L5k9t`>)>7zr zfIlv77^`Fvm<)_+^z@ac%D&hnlUAFt8!x=jdaUo{)M9Ar;Tz5Dcd_|~Hl6CaRnK3R zYn${wZe8_BZ0l0c%qbP}>($jsNDay>8+JG@F!uV4F;#zGsBP0f$f3HqEHDz_sCr^q z1;1}7KJ9&`AX2Qdav1(nNzz+GPdEk5K3;hGXe{Hq13{)c zZy%fFEEH#nlJoG{f*M^#8yXuW%!9svN8ry-Vi7AOFnN~r&D`%6d#lvMXBgZkX^vFj z;tkent^62jUr$Cc^@y31Lka6hS>F?1tE8JW$iXO*n9CQMk}D*At3U(-W1E~z>tG?> z5f`5R5LbrhRNR8kv&5d9SL7ke2a*Xr)Qp#75 z6?-p035n2<7hK;sb>t9GAwG4{9v~iEIG>}7B5zcCgZhu$M0-z8?eUO^E?g)md^XT_ z2^~-u$yak>LBy(=*GsTj6p<>b5PO&un@5hGCxpBQlOB3DpsItKZRC*oXq-r{u}Wb; z&ko>#fbnl2Z;o@KqS-d6DTeCG?m1 z&E>p}SEc*)SD&QjZbs!Csjx~0+$@ekuzV_wAalnQvX3a^n~3ui)|rDO+9HW|JPEeBGP4 z)?zcZ<8qv47`EWA*_X~H^vr(lP|f%=%cWFM;u)OFHruKT<~?>5Y8l?56>&;=WdZU# zZEK4-C8s-3zPMA^&y~e*9z)!ZJghr3N^pJa2A$??Xqx-BR*TytGYor&l8Q+^^r%Yq02xay^f#;;wO6K7G!v>wRd6531WnDI~h$PN( z+4#08uX?r&zVKsQ;?5eBX=FxsXaGyH4Gth4a&L|{8LnNCHFr1M{KjJ!BfBS_aiy-E zxtmNcXq3}WTwQ7Dq-9YS5o758sT(5b`Sg-NcH>M9OH1oW6&sZ@|GYk|cJI`vm zO<$~q!3_$&GfWetudRc*mp8)M)q7DEY-#@8w=ItkApfq3sa)*GRqofuL7)dafznKf zLuembr#8gm*lIqKH)KMxSDqbik*B(1bFt%3Vv|ypehXLCa&wc7#u!cJNlUfWs8iQ` z$66(F=1fkxwg745-8_eqV>nWGY3DjB9gE23$R5g&w|C{|xvT@7j*@aZNB199scGchI7pINb5iyqYn)O=yJJX)Ca3&Ca+{n<=1w|(|f0)h<9gs$pVSV<<9Og-V z8ki@nKwE)x)^wmHBMk?mpMT=g{S#^8W|>&rI#Ceh;9za}io0k@0JxiCqi-jHlxbt3 zjJA?RihhRvhk6%G5-D{ePh1jare*fQS<328P-DcVAxPTrw=n6k?C6EV75f}cnBRPT zMYDqqKu(ND&aOtc!QRV`vzJSVxx8i~WB#5Ml{b#eQqNnSi7l-bS-`ITW<^zyYQA(b zbj4SuRK>q9o`_v%+C=S?h>2e4!66Ij(P5{7Uz$3u6YJJC$W%EoBa{-(=tQ|y1vov%ZkXVOV z##_UVg4V^4ne#4~<-1DkJqkKqgT+E_=&4Ue&eQ-JC+gi?7G@d6= zximz{zE)WW{b@QCJ!7l&N5x=dXS?$5RBU-VvN4Uec-GHK&jPa&P2z+qDdLhIB+HU) zu0CW&uLvE^4I5xtK-$+oe|58)7m6*PO%Xt<+-XEA%jG_BEachkF3e@pn?tl!`8lOF zbi2QOuNXX)YT*MCYflILO{VZ*9GiC%R4FO20zMK?p+&aCMm2oeMK7(aW=UDzr=AO0 z$5mJ%=qRsR8rZ>_YsL+vi{3*J_9Kzq(;ZwRj+4_f0-*wbkSMPWahX#Fj_a8BnrhJ6 zo^ZZ?Vah1@&6#r=JkuaYDBdp;J3@ii+CHM&@9*er&#P}$@wI$bfrH)&c!*|nkvhf%^*Y6b%dKz%QBSIo@U z{?V^qEs4`q<8@n+u8YiB^sc@6g>TncG<|GsmC3egwE6aO=EwLr~3-2 zNr`+)`i+-83?|1Xy0^8ps&pb}YT?w1eWVnC9Ps1=KM;Rw)bH6O!7Did1NwpnqVPZc z*%Qo~qkDL>@^<^fmIBtx$WUWQiNtAB2x-LO^BB=|w~-zTnJNEdm1Ou(?8PF&U88X@ z#8rdaTd||)dG^uJw~N_-%!XNbuAyh4`>Shea=pSj0TqP+w4!`nxsmVSv02kb`DBr% zyX=e>5IJ3JYPtdbCHvKMdhXUO_*E9jc_?se7%VJF#&ZaBD;7+eFN3x+hER7!u&`Wz z7zMvBPR4y`*$a250KYjFhAKS%*XG&c;R-kS0wNY1=836wL6q02mqx;IPcH(6ThA@2 zXKQF|9H>6AW$KUF#^A%l6y5{fel77_+cR_zZ0(7=6bmNXABv}R!B-{(E^O6Y?ZS)n zs1QEmh_Fm7p}oRyT3zxUNr4UV8NGs+2b8|4shO$OGFj3D&7_e?#yDi=TTe%$2QbG5 zk<;q7aQ;p!M-Osm{vFdmXZ@!z9uWh!;*%>(vTRggufuUGP9Hols@vhx z73pn$3u2;vzRvnXuT&$Os7J@6y12*j!{ix%3B4YU1466ItmJs0NsU(4ZYRYh7wEA6q{b*Hs6@k~ zi7Yq@Ax!et0cUMTvk7P%ym){MHpcliHEI~e3HP0NV=}7;xFv#IC?a<=`>~j_sk{e> z7vg-tK*p83HZ0=QK@ zRIHo^r{D8&Ms-^WZp+6US_Quqjh$Q66W^1}=Uz&XJ8AQE9&2}P zY|FXZzZ|0IiaBd2qdt6dIjQr(ZMIOU%NG1F&fu6Po9m^?BvLhI6T0R!H2d8;U(&p2 zYA|MFscMqcO(ye~Jp?F;0>Ke+5hzVr?aBNe>GsGgr$XrpS9uajN2kNQ3o$V5rp0T( z0$6TJC;3)26SNG#XcX7l^MKTn$ga?6r4Jzfb%ZgA(Zbwit0$kY=avSnI$@Gk%+^pu zS5mHrcRS8LFPC*uVWH4DDD1pY$H8N>X?KIJZuZ2SvTqc5Nr0GHdD8TCJcd$zIhOdC zZX0ErnsozQh;t^==4zTfrZO421AL?)O)l#GSxU#|LTTg4#&yeK=^w#;q63!Nv~1(@ zs^-RNRuF&qgcr+bIzc@7$h9L;_yjdifE*$j0Q&Np=1AuHL--zdkv@}`1 zo~LlDl_YAq*z?vmr4M`GjDkl9?p|-tl(DtX76oZv25_DtZutLS9Ez!5~p?th@4 zyc_uax4W#<(#)LMkvo)yp|5tKsC2=p#6PyhpH|449T<9Zdk|%CAb5cw?fhvQtBO&7 zpQ9$24yLqPHP;$N&fe2wm%8qdctwIna<3SwGtQA3{C77s%CW%LYxtK(SBGustL0<( zu~U9r0UOkr(c{OJxZS0Ntu3+cJlF7R`7k-Bsa&q?9Ae5{{|o~?cM+T7{lB1^#vT8R z?>c9fNWey`1dKDY%F3d2O*8^qYhjlB8*7HMKE<*=(A`{>=1%s1}Pm&#_t1xy!FkPk@%SMEka2@*= zxDuM|vJJ5s+xgDls{>*o!7eOcs|xuVBPWX&+y5vEiADK%hi`#Dbd>;;Pbk2H4*-X&R?_-6ZEutSd8hC+sSjhIo z;D(j4P;2EVpEj#UF7IjM6PC+X$C5T&=nL`*!*hm9U)#O?>wqOgC>jXKN3Slk_yaQX zLf|4D8T4k|wHW`;#ZQVocNF|3izi0sOqXzi7@KlYC3CXBG`94wD;tMI1bj|8Vm zY}9`VI9!plSfhAal$M_HlaYOVNU?9Z#0<$o?lXXbX3O(l_?f)i3_~r+GcO-x#+x^X zfsZl0>Rj2iP1rsT;+b;Mr? z4Vu&O)Q5ru4j;qaSP5gA{az@XTS1NpT0d9Xhl_FkkRpcEGA0(QQ~YMh#&zwDUkNzm z6cgkdgl9W{iL6ArJ1TQHqnQ^SQ1WGu?FT|93$Ba}mPCH~!$3}0Y0g zcoG%bdTd$bmBx9Y<`Jc+=Cp4}c@EUfjiz;Rcz101p z=?#i$wo>gBE9|szaZMt-d4nUIhBnYRuBVyx+p?5#aZQgUe(!ah`J#l1$%bl5avL27 zU2~@V`3Ic&!?FhDX@Cw!R4%xtWark#p8DLT)HCZ?VJxf^yr@AD*!ERK3#L$E^*Yr? zzN&uF9Roh4rP+r`Z#7U$tzl6>k!b~HgM$C<_crP=vC>6=q{j?(I}!9>g3rJU(&){o z`R^E*9%+kEa8H_fkD9VT7(Fks&Y-RcHaUJYf-|B+eMXMaRM;{FKRiTB>1(=Iij4k1(X__|WqAd-~t#2@UQ}Z&<1Th0azdXfoll!dd)6>1miA z!&=6sDJm=e$?L&06+Q3`D-HNSkK-3$3DdZMX-6Xjn;wd#9A{~ur!2NcX>(qY_oZL0~H7dnQ9sgLe!W>~2|RSW7|hWn<({Pg*xF$%B-!rKe^_R_vc z(LO!0agxxP;FWPV({8#lEv$&&GVakGus=@!3YVG`y^AO1m{2%Np;>HNA1e{=?ra1C}H zAwT0sbwG|!am;fl?*_t^^#yLDXZ*Nx)_FqueZi0c-G~omtpHW0Cu)mEJ`Z1X8brq$ z%vK##b~o*^b&Hz!hgrD=^6P8}aW40lhzMLB5T5*v`1QH?+L~-@CDi3+C@nRf2{7UE zyDIe{@LKw`Eu=Z%6<<_=#V|yxJIKiq_N?ZJ_v0$c)N4l07ZV_mIXG}glfBSPivOhw z-~+9GdckSpMBNR9eR`Y|9_)sXS+u_OiQ%!9rE(2AFjoxN8lk16Sb~^Sq6kRoEp3yD(mm`HsYIXcag_EAB8MHc}nahxVVUTts~U9P|f;7Ul$_` zStR4v&P4q_$KXOEni$lkxy8=9w8G&47VY0oDb^+jT+>ARe3NHUg~St`$RDxY)?;_F znqTujR&chZd2qHF7y8D$4&E3+e@J~!X3&BW4BF(Ebp#TEjrd+9SU!)j;qH+ZkL@AW z?J6Mj}v0_+D zH0qlbzCkHf|EZ`6c>5ig5NAFF%|La%M-}g(7&}Vx8K)qg30YD;H!S!??{;YivzrH0 z(M%2*b_S-)yh&Aiqai)GF^c!<1Xemj|13>dZ_M#)41SrP;OEMaRJ)bCeX*ZT7W`4Y zQ|8L@NHpD@Tf(5>1U(s5iW~Zdf7$@pAL`a3X@YUv1J>q-uJ_(Dy5nYTCUHC}1(dlI zt;5>DLcHh&jbysqt?G01MhXI3!8wgf){Hv}=0N|L$t8M#L7d6WscO8Om2|NBz2Ga^ zs86y%x$H18)~akOWD7@em7)ldlWgb?_sRN>-EcYQO_}aX@+b$dR{146>{kXWP4$nN{V0_+|3{Lt|8uX_fhKh~i{(x%cj*PU$i{PO(5$uA? zQzO>a6oPj-TUk&{zq?JD2MNb6Mf~V3g$ra+PB;ujLJ2JM(a7N*b`y{MX--!fAd}5C zF$D_b8S;+Np(!cW)(hnv5b@@|EMt*RLKF*wy>ykFhEhlPN~n_Bj>LT9B^_yj>z#fx z3JuE4H&?Cc!;G@}E*3k`HK#8ag`yE3Z1)5JUlSua%qkF zkTu|<9{w9OSi$qr)WD#7EzITnch=xnR63E*d~WGvi*Co9BBE?ETHud;!Z)7&wz+l6 zuKODYG1>I1U#a%&(GNJ`AqRfg=H!BtSl+_;CEeufF-#+*2EMMz-22@>18=8PH{PHd z);mN=aR0MPF>eutLiS#-AOX>#2%+pTGEOj!j4L(m0~&xR=0+g#HNpno6@veLhJp}e zyNVC$a>4;!9&iGvU_dj&xbKt@^t6r%f^)+}eV^suRTLP52+BVs0kOLwg6n`=NUv50E7My8XQUh?y%mW62OT1pMrKI3Q(r`7vU&@93=G~A?b(^pvC-8x=bSk zZ60BQR96WB1Z@9Df(M1IQh+YrU8sEjB=Tc2;(zBn-pete*icZE|M&Uc+oHg`|1o`g zH~m+k=D$o);{Rs)b<9Zo|9_Z6L6QHLNki(N>Dw^^i1LITprZeeqIaT#+)fw)PlllU zldphHC)t!0Gf(i9zgVm>`*TbmITF zH1FZ4{wrjRCx{t^26VK_2srZuWuY*EMAsMrJYFFCH35Ky7bq8<0K|ey2wHnrFMZyr z&^yEgX{{3i@&iE5>xKZ{Ads36G3a!i50D!C4?^~cLB<<|fc1!XN(HJRM)H^21sEs%vv+Mu0h*HkLHaEffMwc0n6)JhNXY#M5w@iO@dfXY z0c6dM2a4Hd1SA*#qYj@jK}uVgAZdaBj8t6uuhUNe>)ne9vfd#C6qLV9+@Q7{MnF#0 zJ7fd-ivG_~u3bVvOzpcw1u~ZSp8-kl(sunnX>L~*K-ByWDM2E8>;Si6kn^58AZQxI xVa^It*?521mj4+UJO?7%w*+`EfEcU=@KhDx-s^WzP+ae~{CgHDE&XryzW}Nww%-5% diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2ec77e5..8fad3f5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1b6c787..a69d9cb 100755 --- a/gradlew +++ b/gradlew @@ -205,6 +205,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index 107acd3..f127cfd 100755 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal From 2733dc4f624d45d242c926ecedde9d3621d98efa Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 13 Aug 2022 11:56:45 +0200 Subject: [PATCH 490/629] only run docker task if docker is running --- .../kafkatorio/task/DockerComposeExec.kt | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerComposeExec.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerComposeExec.kt index e451896..ba5fb76 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerComposeExec.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerComposeExec.kt @@ -8,6 +8,7 @@ import org.gradle.api.file.RegularFileProperty import org.gradle.api.logging.LogLevel import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.Property +import org.gradle.api.provider.ProviderFactory import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputDirectory @@ -16,15 +17,16 @@ import org.gradle.api.tasks.PathSensitive import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.SkipWhenEmpty import org.gradle.api.tasks.TaskAction +import org.gradle.kotlin.dsl.property import org.gradle.process.ExecOperations -import org.gradle.work.Incremental import org.gradle.work.NormalizeLineEndings import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs @CacheableTask abstract class DockerComposeExec @Inject constructor( private val executor: ExecOperations, - private val objectFactory: ObjectFactory, + private val objects: ObjectFactory, + private val providers: ProviderFactory, ) : DefaultTask() { @get:InputDirectory @@ -36,14 +38,28 @@ abstract class DockerComposeExec @Inject constructor( @get:Input abstract val command: Property + @get:Input + val dockerIsActive: Property = objects.property().convention( + providers.exec { + commandLine = parseSpaceSeparatedArgs("docker info") + isIgnoreExitValue = true + }.result.map { + it.exitValue == 0 + } + ) + @get:OutputFile - val stateFile: RegularFileProperty = objectFactory.fileProperty().convention { + val stateFile: RegularFileProperty = objects.fileProperty().convention { temporaryDir.resolve("docker-files.md5") } init { group = DOCKER_COMPOSE_GROUP logging.captureStandardOutput(LogLevel.LIFECYCLE) + + super.onlyIf { + it is DockerComposeExec && it.dockerIsActive.getOrElse(false) + } } @TaskAction From d9f5d6d46dc79e82f25c0e6f31833992f099f965 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 13 Aug 2022 11:59:30 +0200 Subject: [PATCH 491/629] UpdatePackageJson task is updated based on a json object, and move npm versions to libs.versions.toml --- .../adamko/kafkatorio/lang/node.gradle.kts | 9 +- .../task/JsonPropertiesUpToDateSpec.kt | 33 ++++-- .../kafkatorio/task/UpdatePackageJson.kt | 104 +++++++++++++----- gradle/libs.versions.toml | 9 ++ modules/events-mod/build.gradle.kts | 25 ++++- modules/events-mod/package-lock.json | 24 ++-- modules/events-mod/package.json | 6 +- 7 files changed, 152 insertions(+), 58 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts index a32586f..8e07427 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts @@ -3,12 +3,15 @@ package dev.adamko.kafkatorio.lang import com.github.gradle.node.npm.task.NpmInstallTask import dev.adamko.kafkatorio.Versions import dev.adamko.kafkatorio.task.UpdatePackageJson +import kotlinx.serialization.json.put + plugins { id("com.github.node-gradle.node") id("dev.adamko.kafkatorio.base") } + node { download.set(true) version.set(Versions.node) @@ -23,7 +26,11 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) { // description = "Read the package.json file and update the version and name, based on the project." inputs.property("projectVersion", projectVersion) - propertiesToCheck.put("version", projectVersion) +// propertiesToCheck.put("version", projectVersion) + + updateExpectedJson { + put("version", projectVersion.get()) + } // check to see if the properties are already up-to-date // outputs.upToDateWhen(areJsonPropertiesUpToDate(packageJsonFile, propertiesToCheck)) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt index 30f9ee0..8b61b06 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt @@ -1,15 +1,23 @@ package dev.adamko.kafkatorio.task +import dev.adamko.kafkatorio.task.UpdatePackageJson.Companion.foldParseToJsonObject +import dev.adamko.kafkatorio.task.UpdatePackageJson.Companion.parseToJsonObject +import kotlinx.serialization.json.JsonObject import org.gradle.api.Task import org.gradle.api.internal.specs.ExplainingSpec +import org.gradle.api.logging.Logger +import org.gradle.api.logging.Logging + object JsonPropertiesUpToDateSpec : ExplainingSpec { + private val logger: Logger = Logging.getLogger(this::class.java) + override fun isSatisfiedBy(element: Task?): Boolean { val reason = whyUnsatisfied(element) if (reason != null) { - println("JsonProperties not up to date:\n$reason") + logger.lifecycle("JsonProperties not up to date:\n$reason") } return reason == null @@ -21,26 +29,31 @@ object JsonPropertiesUpToDateSpec : ExplainingSpec { override fun whyUnsatisfied(task: Task?): String? { require(task is UpdatePackageJson) { "$task is not a UpdatePackageJson task" } - val current = task.currentPackageJson() - val updated = task.updatedPackageJson(current) + val current = task.packageJsonFile.asFile.orNull?.parseToJsonObject() + ?: return "no package.json file" - return if (current != updated) { - (current.keys + updated.keys) + val updates = task.expectedJsonUpdates.orNull?.toList()?.foldParseToJsonObject() + ?: return "no package.json updates" + + val expected = JsonObject(current + updates) + + if (current != expected) { + return (current.keys + expected.keys) .asSequence() .distinct() .sorted() .mapNotNull { val currentVal = current[it] - val updatedVal = updated[it] + val expectedVal = expected[it] - if (currentVal == updatedVal) { + if (currentVal == expectedVal) { null } else { - "'$it' - expected:$updatedVal, actual:$currentVal" + "'$it' - expected:$expectedVal, actual:$currentVal" } }.joinToString(separator = "\n\t", prefix = "package.json is not up to date.\n\t") - } else { - null } + + return null } } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt index ddfa6ce..acae0c3 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt @@ -1,15 +1,19 @@ package dev.adamko.kafkatorio.task import com.github.gradle.node.NodePlugin -import dev.adamko.kafkatorio.jsonMapper +import dev.adamko.kafkatorio.* +import java.io.File import javax.inject.Inject import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.JsonObjectBuilder +import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.jsonObject import org.gradle.api.DefaultTask import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.MapProperty +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.Property import org.gradle.api.provider.ProviderFactory import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.Input @@ -18,13 +22,19 @@ import org.gradle.api.tasks.TaskAction import org.gradle.kotlin.dsl.support.useToRun import org.jetbrains.kotlin.util.suffixIfNot + @CacheableTask abstract class UpdatePackageJson @Inject constructor( private val providers: ProviderFactory, -) : DefaultTask() { +) : DefaultTask(), + ProviderFactory by providers { +// @get:Input +// abstract val propertiesToCheck: MapProperty + + /** Cumulative updates */ @get:Input - abstract val propertiesToCheck: MapProperty + internal abstract val expectedJsonUpdates: ListProperty @get:OutputFile abstract val packageJsonFile: RegularFileProperty @@ -32,51 +42,93 @@ abstract class UpdatePackageJson @Inject constructor( init { group = NodePlugin.NPM_GROUP - description = - "Read the package.json file and update the version and name, based on the current project." + description = "Update package.json properties" outputs.upToDateWhen(JsonPropertiesUpToDateSpec) + +// expectedJson.convention("{}") } @TaskAction fun exec() { val packageJsonFile = packageJsonFile.asFile.get() + val expectedJsonUpdates: List = expectedJsonUpdates.get().toList() - logger.lifecycle("updating package.json ${packageJsonFile.canonicalPath}") + logger.lifecycle("updating package.json ${packageJsonFile.canonicalFile}") - val updatedPackageJson = updatedPackageJson() + val expectedJson = expectedJsonUpdates.fold(JsonObject(emptyMap())) { acc, update -> + val updateJson = jsonMapper.parseToJsonElement(update).jsonObject + JsonObject(acc + updateJson) + } - val packageJsonContentUpdated = + val updatedPackageJson = JsonObject( + packageJsonFile.parseToJsonObject() + expectedJson + ) + + val packageJsonContentFormatted = jsonMapper .encodeToString(updatedPackageJson) - // change empty arrays/objects, because `npm install` also formats package.json, but - // slightly differently to kxs. - .replace( ": {\n }", ": {}") - .replace( ": [\n ]", ": []") + // change empty arrays/objects, because `npm install` also formats package.json, + // but slightly differently to kxs. + .replace(": {\n }", ": {}") + .replace(": [\n ]", ": []") .suffixIfNot("\n") - logger.debug(packageJsonContentUpdated) + logger.info(packageJsonContentFormatted) packageJsonFile.writer().useToRun { - write(packageJsonContentUpdated) + write(packageJsonContentFormatted) } } - internal fun currentPackageJson(): JsonObject { - val packageJsonFile = packageJsonFile.get().asFile - return jsonMapper.parseToJsonElement(packageJsonFile.readText()).jsonObject + + /** Update [expectedJson] by merging [updateJsonProvider] with the existing value. */ + fun updateExpectedJson( + expectedJsonUpdate: JsonObjectBuilder.() -> Unit + ) { + val expectedJsonUpdateProvider = provider { + buildJsonObject(expectedJsonUpdate).toString() + } + + expectedJsonUpdates.add(expectedJsonUpdateProvider) + +// val newJson = +// expectedJson.zip(expectedJsonUpdateProvider) { currentJsonString, inputJsonString -> +// val currentJson = jsonMapper.encodeToJsonElement(currentJsonString).jsonObject +// +// val inputJson = jsonMapper.encodeToJsonElement(inputJsonString).jsonObject +// +// val newJson = JsonObject(currentJson + inputJson) +// +// jsonMapper.encodeToString(newJson) +// } +// +// expectedJson.set(newJson) } - internal fun updatedPackageJson( - currentPackageJson: JsonObject = currentPackageJson(), - ): JsonObject { - val propertiesToCheck: Map = propertiesToCheck.get() - val newJsonProps = propertiesToCheck.mapValues { (_, newVal) -> - JsonPrimitive(newVal) + + companion object { + private val jsonMapper = Json { + prettyPrint = true + prettyPrintIndent = " " } - return JsonObject(currentPackageJson + newJsonProps) + + + internal fun File.parseToJsonObject(): JsonObject = + jsonMapper.parseToJsonElement(readText()).jsonObject + + + internal fun Property.parseToJsonObject(): JsonObject = + jsonMapper.parseToJsonElement(get()).jsonObject + + + internal fun List.foldParseToJsonObject(): JsonObject = + fold(JsonObject(emptyMap())) { acc, update -> + val updateJson = jsonMapper.parseToJsonElement(update).jsonObject + JsonObject(acc + updateJson) + } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5fb90e7..9302dc8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -45,6 +45,15 @@ kotkaStreams = "dev-SNAPSHOT" marykRocksDb = "7.3.1" # https://search.maven.org/artifact/io.maryk.rocksdb/rocksdb-multiplatform + +## npm ## + +npm-luaTypes = "2.12.0" +npm-typescriptToLua = "1.8.2" +npm-typedFactorio = "1.6.1" +npm-typescript = "4.7.4" + + ## test ## junit = "5.8.2" kotest = "5.3.1" diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 206b8d8..c3398d7 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -4,6 +4,8 @@ import dev.adamko.kafkatorio.gradle.asProvider import dev.adamko.kafkatorio.gradle.factorioModAttributes import dev.adamko.kafkatorio.gradle.typescriptAttributes import dev.adamko.kafkatorio.task.TypescriptToLuaTask +import kotlinx.serialization.json.put +import kotlinx.serialization.json.putJsonObject import net.swiftzer.semver.SemVer import org.apache.tools.ant.filters.ReplaceTokens import org.gradle.plugins.ide.idea.model.Module as IdeaImlModule @@ -175,15 +177,26 @@ val factorioModProvider by configurations.registering { } -val packageJsonName: Provider = providers.provider { "${rootProject.name}-${project.name}" } -val pjProvider: RegularFileProperty = - objects.fileProperty().convention(layout.projectDirectory.file("package.json")) +val projectPackageJsonName: Provider = + providers.provider { "${rootProject.name}-${project.name}" } +val projectPackageJsonFile: RegularFile = layout.projectDirectory.file("package.json") +val projectVersion: Provider = providers.provider { "${project.version}" } + tasks.updatePackageJson { // mustRunAfter(tasks.npmInstall) - inputs.property("packageJsonName", packageJsonName) - propertiesToCheck.put("name", packageJsonName) - packageJsonFile.set(pjProvider) + + updateExpectedJson { + put("name", projectPackageJsonName.get()) + putJsonObject("dependencies") { + put("lua-types", libs.versions.npm.luaTypes.get()) + put("typescript-to-lua", libs.versions.npm.typescriptToLua.get()) + put("typed-factorio", libs.versions.npm.typedFactorio.get()) + put("typescript", libs.versions.npm.typescript.get()) + } + } + + packageJsonFile.set(projectPackageJsonFile) } diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index eff221b..ac356aa 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -32,17 +32,17 @@ } }, "is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", "requires": { "has": "^1.0.3" } }, "lua-types": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.11.0.tgz", - "integrity": "sha512-J/8qHrOjkZuPBDhnuAg0DWoaJEImqXNzgEnUigCTVrSVCcchM5Y5zpcI3aWAZPhuZlb0QKC/f3nc7VGmZmBg7w==" + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.12.0.tgz", + "integrity": "sha512-s96z1Zcz3KRXfWyNFM3KP2zpNYTfZwgHo8X/yFXveyS8Dux+cUuyT+zA5tFZbmGh8VViwNs9bFbzNevAR/18uw==" }, "path-parse": { "version": "1.0.7", @@ -75,9 +75,9 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.4.0.tgz", - "integrity": "sha512-hT5YDtdJk/hVIm83hYlXx2vOSmhElQhHhcI0OIrdx2nmrx18zKEnjGk4abJ6WHjuy4xoVZ+00mjnC3mWclvrzw==" + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.6.1.tgz", + "integrity": "sha512-ehxUmRUPO4IEhtXIOkwhosDGGEVgRBFVaoNkTOvko/3yLKwese/6IB1/9ItSRNspqOoNh4UBPscjvQWM3SIFBA==" }, "typescript": { "version": "4.7.4", @@ -85,9 +85,9 @@ "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" }, "typescript-to-lua": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.7.1.tgz", - "integrity": "sha512-iDjCnel38p3Cxv+Las8rBzd6BaRIE49DQSyFOgupg4gSw36+8H1xtwde3lRdGMPZx19/zVwXEO8UspiACYJc+A==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.8.2.tgz", + "integrity": "sha512-2ZFJlF9R9HgTryM+Vwk3X3Dexnvpm5vT75Eh66E0rDFZGK+vW70aqkw6s47/ytdJg/9IyN+Oz7ITUzZxXEOxlA==", "requires": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index d9a4fc4..10ea923 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -11,9 +11,9 @@ }, "devDependencies": {}, "dependencies": { - "lua-types": "^2.11.0", - "typescript-to-lua": "1.7.1", - "typed-factorio": "1.4.0", + "lua-types": "2.12.0", + "typescript-to-lua": "1.8.2", + "typed-factorio": "1.6.1", "typescript": "4.7.4" }, "license": "UNLICENSED", From c1542dcb42cf5df0a79b4f360c4251e28b9349f9 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 13 Aug 2022 11:59:54 +0200 Subject: [PATCH 492/629] rm common jsonMapper (it was only used in the UpdatePackJson task) --- buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt index d86f12f..5c14308 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt @@ -2,16 +2,14 @@ package dev.adamko.kafkatorio import io.kvision.gradle.KVisionExtension import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.jsonObject import org.gradle.api.Project import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.findByType import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension -val jsonMapper = Json { - prettyPrint = true - prettyPrintIndent = " " -} - object Versions { const val node = "14.19.1" From c9ae17d418e77a8e7d31efcdbc21ae3937e38a34 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 13 Aug 2022 12:05:17 +0200 Subject: [PATCH 493/629] bump versions (kafka, ktor, hoplite, simple-syslog, factorio, tstl, typed-factorio, kotka, gradle-node) and update code to compile --- gradle/libs.versions.toml | 17 +++++++++-------- .../schema/common/factorioPrototypes.kt | 4 ++-- .../src/generated/lua/lualib_bundle.lua | 11 +++++++++++ .../lua/main/events/prototypeUpdates.lua | 11 ++++------- .../typescript/generated/kafkatorio-schema.ts | 4 ++-- .../main/typescript/main/events/converters.ts | 6 +++--- .../typescript/main/events/prototypeUpdates.ts | 13 ++----------- .../server/socket/SyslogSocketServer.kt | 18 ++++++++++++++---- modules/infra-factorio-server/src/.env | 2 +- modules/infra-kafka-cluster/src/.env | 4 ++-- 10 files changed, 50 insertions(+), 40 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9302dc8..87d39a0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ kotlin = "1.7.10" ## libs ## camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" -kafka = "3.2.0" # https://kafka.apache.org/downloads +kafka = "3.2.1" # https://kafka.apache.org/downloads kvision = "5.13.1" log4j2 = "2.17.2" okio = "3.2.0" # https://search.maven.org/artifact/com.squareup.okio/okio @@ -35,13 +35,14 @@ kotlinx-nodejs = "0.0.7" kSvgDsl = "v2.2.0" -ktor = "2.0.3" # https://github.com/ktorio/ktor/releases +ktor = "2.1.0" # https://github.com/ktorio/ktor/releases -hoplite = "2.3.1" # https://github.com/sksamuel/hoplite/releases +hoplite = "2.5.2" # https://github.com/sksamuel/hoplite/releases -simpleSyslogParser = "0.0.6" # https://search.maven.org/artifact/com.github.palindromicity/simple-syslog +#simpleSyslogParser = "0.0.6" # https://search.maven.org/artifact/com.github.palindromicity/simple-syslog +simpleSyslogParser = "cbf7d86559" # https://jitpack.io/#palindromicity/simple-syslog/ -kotkaStreams = "dev-SNAPSHOT" +kotkaStreams = "22.08.06" marykRocksDb = "7.3.1" # https://search.maven.org/artifact/io.maryk.rocksdb/rocksdb-multiplatform @@ -61,14 +62,14 @@ mockk = "1.12.4" ## infra ## -factorio = "1.1.61" +factorio = "1.1.64" confluent-kafkaConnect = "7.0.1" grafana = "8.5.0" prometheus = "v2.34.0" ## gradle plugins ## -gradleNodePlugin = "3.3.0" # https://github.com/node-gradle/gradle-node-plugin/releases +gradleNodePlugin = "3.4.0" # https://github.com/node-gradle/gradle-node-plugin/releases ######### @@ -213,7 +214,6 @@ kafka-streamsTestUtils = { group = "org.apache.kafka", name = "kafka-streams-tes # kafka helpers #kotka = { group = "com.github.blueanvil", name = "kotka", version = "1.1.1" } -#kafka-kotkaStreams = { group = "com.github.adamko-dev.kotka-streams", name = "kotka-streams", version.ref = "kotkaStreams" } kafka-kotkaStreams = { group = "dev.adamko.kotka", name = "kotka-streams", version.ref = "kotkaStreams" } @@ -236,6 +236,7 @@ hoplite-datetime = { group = "com.sksamuel.hoplite", name = "hoplite-datetime", hoplite-yaml = { group = "com.sksamuel.hoplite", name = "hoplite-yaml", version.ref = "hoplite" } +#simpleSyslogParser = { group = "com.github.palindromicity", name = "simple-syslog", version.ref = "simpleSyslogParser" } simpleSyslogParser = { group = "com.github.palindromicity", name = "simple-syslog", version.ref = "simpleSyslogParser" } diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt index fae8cee..40e136e 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt @@ -71,8 +71,8 @@ sealed interface FactorioPrototype { @Serializable @SerialName("kafkatorio.prototype.EntityItemGroup") data class ItemGroup( - val name: String, - val type: String, + val name: String? = null, + val type: String? = null, val parentName: String? = null, ) diff --git a/modules/events-mod/src/generated/lua/lualib_bundle.lua b/modules/events-mod/src/generated/lua/lualib_bundle.lua index e118180..1902e79 100644 --- a/modules/events-mod/src/generated/lua/lualib_bundle.lua +++ b/modules/events-mod/src/generated/lua/lualib_bundle.lua @@ -1207,6 +1207,16 @@ local function __TS__InstanceOfObject(value) return valueType == "table" or valueType == "function" end +local function __TS__LuaIteratorSpread(self, state, firstKey) + local results = {} + local key, value = self(state, firstKey) + while key do + results[#results + 1] = {key, value} + key, value = self(state, key) + end + return __TS__Unpack(results) +end + local Map do Map = __TS__Class() @@ -2448,6 +2458,7 @@ return { __TS__InstanceOf = __TS__InstanceOf, __TS__InstanceOfObject = __TS__InstanceOfObject, __TS__Iterator = __TS__Iterator, + __TS__LuaIteratorSpread = __TS__LuaIteratorSpread, Map = Map, __TS__MathAtan2 = __TS__MathAtan2, __TS__MathSign = __TS__MathSign, diff --git a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua index 58bdd23..030e7b0 100644 --- a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua @@ -1,5 +1,5 @@ local ____exports = {} -local emit, getMapTilePrototypes, getEntityPrototypes, convertItemGroup, convertItemSubgroup +local emit, getMapTilePrototypes, getEntityPrototypes, convertItemGroup local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") local FactorioPrototype = ____kafkatorio_2Dschema.FactorioPrototype local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData @@ -30,7 +30,7 @@ end function getEntityPrototypes() local protos = {} for ____, entity in pairs(game.entity_prototypes) do - local key = (((entity.group.name .. "/") .. entity.subgroup.name) .. "/") .. entity.type + local key = (((tostring(entity.group.name) .. "/") .. tostring(entity.subgroup.name)) .. "/") .. entity.type if protos[key] == nil then protos[key] = {} end @@ -38,7 +38,7 @@ function getEntityPrototypes() type = FactorioPrototype.Type.Entity, protoId = Converters.prototypeId(entity.type, entity.name), group = convertItemGroup(entity.group), - subgroup = convertItemSubgroup(entity.subgroup), + subgroup = convertItemGroup(entity.subgroup), isBuilding = entity.is_building, isEntityWithOwner = entity.is_entity_with_owner, isMilitaryTarget = entity.is_military_target, @@ -62,16 +62,13 @@ function getEntityPrototypes() return protos end function convertItemGroup(itemGroup) - return {name = itemGroup.name, type = itemGroup.type, parentName = nil} -end -function convertItemSubgroup(itemGroup) local ____itemGroup_name_3 = itemGroup.name local ____itemGroup_type_4 = itemGroup.type local ____itemGroup_group_name_1 = itemGroup.group if ____itemGroup_group_name_1 ~= nil then ____itemGroup_group_name_1 = ____itemGroup_group_name_1.name end - return {name = ____itemGroup_name_3, type = ____itemGroup_type_4, parentName = ____itemGroup_group_name_1} + return {name = ____itemGroup_name_3, type = ____itemGroup_type_4, parentName = ____itemGroup_group_name_1 or nil} end function ____exports.emitPrototypes() local mapTileProtos = getMapTilePrototypes() diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts index d7f02fc..4983c45 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts @@ -269,8 +269,8 @@ export type MapChunkPosition = [ ]; export interface EntityItemGroup { - name: string; - type: string; + name?: string | null; + type?: string | null; parentName?: string | null; } diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index 84bda4a..3abccbc 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -18,13 +18,13 @@ export namespace Converters { import floor = math.floor; - const mapEventIdToName = new LuaTable() + const mapEventIdToName = new LuaTable() for (const [eventName, eventId] of pairs(defines.events)) { mapEventIdToName.set(eventId, eventName) } - export function eventNameString(event: defines.Events): EventName { + export function eventNameString(event: defines.events): EventName { return mapEventIdToName.get(event) as EventName } @@ -165,7 +165,7 @@ export namespace Converters { } - export function collisionBox(collision_box: BoundingBoxRead): MapBoundingBox { + export function collisionBox(collision_box: BoundingBox): MapBoundingBox { return { leftTop: Converters.entityPosition(collision_box.left_top), rightBottom: Converters.entityPosition(collision_box.right_bottom), diff --git a/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts b/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts index 109e32a..a6d7f57 100644 --- a/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts @@ -65,7 +65,7 @@ function getEntityPrototypes(): PrototypesByType { protoId: Converters.prototypeId(entity.type, entity.name), group: convertItemGroup(entity.group), - subgroup: convertItemSubgroup(entity.subgroup), + subgroup: convertItemGroup(entity.subgroup), isBuilding: entity.is_building, isEntityWithOwner: entity.is_entity_with_owner, @@ -96,15 +96,6 @@ function convertItemGroup(itemGroup: LuaGroup): EntityItemGroup { return { name: itemGroup.name, type: itemGroup.type, - parentName: null, - } -} - - -function convertItemSubgroup(itemGroup: LuaGroup): EntityItemGroup { - return { - name: itemGroup.name, - type: itemGroup.type, - parentName: itemGroup.group?.name, + parentName: itemGroup.group?.name ?? null, } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt index 15ad792..5f8e686 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt @@ -1,6 +1,9 @@ package dev.adamko.kafkatorio.server.socket import com.github.palindromicity.syslog.AllowableDeviations +import com.github.palindromicity.syslog.DefaultKeyProvider +import com.github.palindromicity.syslog.Flat5424MessageHandler +import com.github.palindromicity.syslog.NilPolicy import com.github.palindromicity.syslog.SyslogParser import com.github.palindromicity.syslog.SyslogParserBuilder import com.github.palindromicity.syslog.SyslogSpecification @@ -38,10 +41,17 @@ class SyslogSocketServer( ) - private val syslogParser: SyslogParser = SyslogParserBuilder() - .withDeviations(EnumSet.of(AllowableDeviations.PRIORITY, AllowableDeviations.VERSION)) - .forSpecification(SyslogSpecification.RFC_5424) - .build() + private val syslogParser: SyslogParser> = + SyslogParserBuilder>() + .forSpecification(SyslogSpecification.RFC_5424) + .withSyslogBuilder( + Flat5424MessageHandler( + DefaultKeyProvider(), + NilPolicy.OMIT, + EnumSet.of(AllowableDeviations.PRIORITY, AllowableDeviations.VERSION), + ) + ) + .build() private val _messages: MutableSharedFlow = MutableSharedFlow() diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index 4b5add1..b9e9fb3 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio -FACTORIO_VERSION=1.1.61 +FACTORIO_VERSION=1.1.64 KAFKATORIO_VERSION=0.8.0 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index c211275..7b8769d 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -2,6 +2,6 @@ COMPOSE_PROJECT_NAME=kafkatorio GRAFANA_VERSION=8.5.0 KAFKATORIO_VERSION=0.8.0 -KAFKA_DL_URL=https\://dlcdn.apache.org/kafka/3.2.0/kafka_2.13-3.2.0.tgz -KAFKA_VERSION=3.2.0 +KAFKA_DL_URL=https\://dlcdn.apache.org/kafka/3.2.1/kafka_2.13-3.2.1.tgz +KAFKA_VERSION=3.2.1 PROMETHEUS_VERSION=v2.34.0 From babe74b72314db7e243e97b9f1a0b8e922259450 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 28 Aug 2022 13:30:51 +0200 Subject: [PATCH 494/629] buildSrc minor formatting --- buildSrc/build.gradle.kts | 5 +++-- buildSrc/repositories.settings.gradle.kts | 4 +++- .../adamko/kafkatorio/gradle/extensions.kt | 2 +- .../kafkatorio/lang/kotlin-jvm.gradle.kts | 4 ++++ .../kafkatorio/task/UpdatePackageJson.kt | 20 +------------------ 5 files changed, 12 insertions(+), 23 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 8dbc6c5..f844b16 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -13,7 +13,7 @@ val gradleKotlinTarget = "1.6" dependencies { - implementation(enforcedPlatform("org.jetbrains.kotlin:kotlin-bom:${libs.versions.kotlin.get()}")) + implementation(platform(libs.kotlin.bom)) implementation("org.jetbrains.kotlin:kotlin-serialization") implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable") @@ -29,7 +29,8 @@ dependencies { implementation("com.github.node-gradle:gradle-node-plugin:${libs.versions.gradleNodePlugin.get()}") - implementation("io.kotest:kotest-framework-multiplatform-plugin-gradle:${libs.versions.kotest.get()}") + implementation(platform(libs.kotest.bom)) + implementation("io.kotest:kotest-framework-multiplatform-plugin-gradle") implementation("io.kvision:io.kvision.gradle.plugin:${libs.versions.kvision.get()}") diff --git a/buildSrc/repositories.settings.gradle.kts b/buildSrc/repositories.settings.gradle.kts index 56eb40e..67f0f14 100644 --- a/buildSrc/repositories.settings.gradle.kts +++ b/buildSrc/repositories.settings.gradle.kts @@ -39,6 +39,8 @@ dependencyResolutionManagement { maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") { content { includeGroup("org.jetbrains.kotlinx") } } + + sonatypeSnapshot() } pluginManagement { @@ -47,9 +49,9 @@ dependencyResolutionManagement { gradlePluginPortal() mavenCentral() jitpack() + sonatypeSnapshot() } } - } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt index 961f730..7693f66 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt @@ -68,7 +68,7 @@ fun Project.execCapture(spec: ExecSpec.() -> Unit): String { fun Project.yarn(configure: YarnRootExtension.() -> Unit) = with(yarn, configure) -fun Directory.filesChecksum() = asFileTree +fun Directory.filesChecksum(): Long = asFileTree .files .map { it.readBytes() + it.absolutePath.toByteArray() } .fold(byteArrayOf()) { acc, bytes -> acc + bytes } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index eb96e83..dbb4b66 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -22,6 +22,7 @@ dependencies { testImplementation("io.mockk:mockk") } + tasks.withType().configureEach { kotlinOptions { @@ -40,16 +41,19 @@ tasks.withType().configureEach { ) } + tasks.compileTestKotlin { kotlinOptions.freeCompilerArgs += "-opt-in=io.kotest.common.ExperimentalKotest" } + kotlin { jvmToolchain { languageVersion.set(JavaLanguageVersion.of(projectJvmTarget)) } } + tasks.withType().configureEach { useJUnitPlatform() } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt index acae0c3..5674046 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt @@ -29,10 +29,7 @@ abstract class UpdatePackageJson @Inject constructor( ) : DefaultTask(), ProviderFactory by providers { -// @get:Input -// abstract val propertiesToCheck: MapProperty - - /** Cumulative updates */ + /** Cumulative updates - will be combined one by one, then applied to [packageJsonFile] */ @get:Input internal abstract val expectedJsonUpdates: ListProperty @@ -45,8 +42,6 @@ abstract class UpdatePackageJson @Inject constructor( description = "Update package.json properties" outputs.upToDateWhen(JsonPropertiesUpToDateSpec) - -// expectedJson.convention("{}") } @@ -94,19 +89,6 @@ abstract class UpdatePackageJson @Inject constructor( } expectedJsonUpdates.add(expectedJsonUpdateProvider) - -// val newJson = -// expectedJson.zip(expectedJsonUpdateProvider) { currentJsonString, inputJsonString -> -// val currentJson = jsonMapper.encodeToJsonElement(currentJsonString).jsonObject -// -// val inputJson = jsonMapper.encodeToJsonElement(inputJsonString).jsonObject -// -// val newJson = JsonObject(currentJson + inputJson) -// -// jsonMapper.encodeToString(newJson) -// } -// -// expectedJson.set(newJson) } From b1fec349aec6c75051ac8ab6828076e22b28adcf Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 28 Aug 2022 13:32:05 +0200 Subject: [PATCH 495/629] rm unused Gradle report plugins (they warn about config-cache problems) --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index cdec9be..edacbbc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,8 +4,8 @@ import java.time.LocalDate plugins { idea base - `project-report` - `build-dashboard` +// `project-report` +// `build-dashboard` } group = "dev.adamko.kafkatorio" From 3821996eeb8bcc0ffeebbf8492fb1266ac86b914 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 28 Aug 2022 13:37:55 +0200 Subject: [PATCH 496/629] bump some versions (use Kotest in Maven Local b/c plugin isn't available on Sonatype snapshot) add tile width/height (added in new version of Factorio) --- buildSrc/repositories.settings.gradle.kts | 17 +++++++++++--- .../lang/kotlin-multiplatform.gradle.kts | 1 + gradle/libs.versions.toml | 22 +++++++++++-------- modules/events-library/build.gradle.kts | 1 - .../schema/common/factorioPrototypes.kt | 8 ++++--- modules/events-mod/package-lock.json | 12 +++++----- modules/events-mod/package.json | 4 ++-- .../lua/main/events/prototypeUpdates.lua | 4 +++- .../typescript/generated/kafkatorio-schema.ts | 2 ++ .../main/events/prototypeUpdates.ts | 3 +++ 10 files changed, 49 insertions(+), 25 deletions(-) diff --git a/buildSrc/repositories.settings.gradle.kts b/buildSrc/repositories.settings.gradle.kts index 67f0f14..4e357c1 100644 --- a/buildSrc/repositories.settings.gradle.kts +++ b/buildSrc/repositories.settings.gradle.kts @@ -60,14 +60,25 @@ fun RepositoryHandler.jitpack() { } -fun RepositoryHandler.myMavenLocal(enabled: Boolean = false) { +fun RepositoryHandler.myMavenLocal(enabled: Boolean = true) { if (enabled) { logger.lifecycle("Maven local is enabled") mavenLocal { content { - includeGroup("dev.adamko") - includeGroup("dev.adamko.kxtsgen") +// includeGroup("dev.adamko") +// includeGroup("dev.adamko.kxtsgen") + includeGroup("io.kotest") } } } } + + +fun RepositoryHandler.sonatypeSnapshot() { + maven("https://oss.sonatype.org/content/repositories/snapshots") { + mavenContent { + snapshotsOnly() + includeGroup("io.kotest") + } + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts index dc77fd0..2638320 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts @@ -10,6 +10,7 @@ plugins { id("dev.adamko.kafkatorio.base") // id("dev.adamko.kafkatorio.lang.node") kotlin("multiplatform") + id("io.kotest.multiplatform") } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 87d39a0..b8efa0b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,12 +12,12 @@ kotlin = "1.7.10" camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" kafka = "3.2.1" # https://kafka.apache.org/downloads -kvision = "5.13.1" +kvision = "5.13.1" # https://github.com/rjaros/kvision/releases log4j2 = "2.17.2" okio = "3.2.0" # https://search.maven.org/artifact/com.squareup.okio/okio qosLogback = "1.2.11" scrimage = "4.0.31" # https://github.com/sksamuel/scrimage/releases -semver = "1.2.0" +semver = "1.2.0" # https://github.com/swiftzer/semver/releases slf4j = "1.7.36" kotlinx-serialization = "1.3.3" # https://github.com/Kotlin/kotlinx.serialization/releases @@ -25,7 +25,7 @@ kxs-charleskornKaml = "0.44.0" kxs-mamoeYamlkt = "0.12.0" kxs-kxsTsGen = "0.2.1" -kotlinJsWrappers = "1.0.0-pre.359" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom +kotlinJsWrappers = "1.0.0-pre.367" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom kotlinx-cli = "0.3.4" kotlinx-coroutines = "1.6.4" # https://github.com/Kotlin/kotlinx.coroutines/releases @@ -44,21 +44,22 @@ simpleSyslogParser = "cbf7d86559" # https://jitpack.io/#palindromicity/sim kotkaStreams = "22.08.06" -marykRocksDb = "7.3.1" # https://search.maven.org/artifact/io.maryk.rocksdb/rocksdb-multiplatform +marykRocksDb = "7.3.1-1" # https://search.maven.org/artifact/io.maryk.rocksdb/rocksdb-multiplatform ## npm ## npm-luaTypes = "2.12.0" -npm-typescriptToLua = "1.8.2" -npm-typedFactorio = "1.6.1" +npm-typescriptToLua = "1.9.0" +npm-typedFactorio = "1.7.0" npm-typescript = "4.7.4" ## test ## -junit = "5.8.2" -kotest = "5.3.1" -mockk = "1.12.4" +junit = "5.9.0" +#kotest = "5.4.2" +kotest = "5.5.0-LOCAL" +mockk = "1.12.5" ## infra ## @@ -261,6 +262,9 @@ kotest-prop = { group = "io.kotest", name = "kotest-property" kotest-frameworkEngine = { group = "io.kotest", name = "kotest-framework-engine" } kotest-runnerJunit5 = { group = "io.kotest", name = "kotest-runner-junit5" } +kotestPlugin-embeddedCompiler = { group = "io.kotest", name = "kotest-framework-multiplatform-plugin-embeddable-compiler" } +kotestPlugin-multiplatform = { group = "io.kotest", name = "kotest-framework-multiplatform-plugin-gradle" } + ## http4k ## http4k-test-chaos = { group = "org.http4k", name = "http4k-testing-chaos", version.ref = "http4k" } http4k-test-approval = { group = "org.http4k", name = "http4k-testing-approval", version.ref = "http4k" } diff --git a/modules/events-library/build.gradle.kts b/modules/events-library/build.gradle.kts index cf03c93..59053a2 100644 --- a/modules/events-library/build.gradle.kts +++ b/modules/events-library/build.gradle.kts @@ -8,7 +8,6 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { dev.adamko.kafkatorio.lang.`kotlin-multiplatform` - id("io.kotest.multiplatform") kotlin("plugin.serialization") distribution } diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt index 40e136e..6217dec 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt @@ -34,6 +34,8 @@ sealed interface FactorioPrototype { * [friendly][mapColourFriend] or [enemy][mapColourEnemy] colour isn't defined or `null`. * @param[mapColourFriend] The friendly map colour used when charting this entity. * @param[mapColourEnemy] The enemy map colour used when charting this entity. + * @param[tileWidth] Tiling size. If odd, center is the center of the tiles. If even, it's on the tile border. + * @param[tileHeight] Tiling size. If odd, center is the center of the tiles. If even, it's on the tile border. */ @SerialName("kafkatorio.prototype.Entity") @Serializable @@ -55,10 +57,10 @@ sealed interface FactorioPrototype { val miningProperties: MiningProperties? = null, val collisionBox: MapBoundingBox? = null, - ) : FactorioPrototype { - val tileHeight: Int? get() = collisionBox?.tileHeight - val tileWidth: Int? get() = collisionBox?.tileWidth + val tileWidth: Int? = null, + val tileHeight: Int? = null, + ) : FactorioPrototype { @Serializable @SerialName("kafkatorio.prototype.EntityMiningProperties") diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index ac356aa..a88c996 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -75,9 +75,9 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.6.1.tgz", - "integrity": "sha512-ehxUmRUPO4IEhtXIOkwhosDGGEVgRBFVaoNkTOvko/3yLKwese/6IB1/9ItSRNspqOoNh4UBPscjvQWM3SIFBA==" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.7.0.tgz", + "integrity": "sha512-i7MLTRW7vQAWTwHZSbX8m+PQm0hnCW/3nCBQI1b0DAikK9a/nJIZWpy2U3C4cnwhNqyNz5p50mLFQiedb/s+ow==" }, "typescript": { "version": "4.7.4", @@ -85,9 +85,9 @@ "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" }, "typescript-to-lua": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.8.2.tgz", - "integrity": "sha512-2ZFJlF9R9HgTryM+Vwk3X3Dexnvpm5vT75Eh66E0rDFZGK+vW70aqkw6s47/ytdJg/9IyN+Oz7ITUzZxXEOxlA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.9.0.tgz", + "integrity": "sha512-Oj8kutP1u/TSjN9oGUuESfOL+feHMSs7CCxl90C60jWTH+4ZXLtrXlRJTalA3Z2/aHjQXXgPaXQStSXBzAYLow==", "requires": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 10ea923..c913e8b 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -12,8 +12,8 @@ "devDependencies": {}, "dependencies": { "lua-types": "2.12.0", - "typescript-to-lua": "1.8.2", - "typed-factorio": "1.6.1", + "typescript-to-lua": "1.9.0", + "typed-factorio": "1.7.0", "typescript": "4.7.4" }, "license": "UNLICENSED", diff --git a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua index 030e7b0..5cc2334 100644 --- a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua @@ -43,7 +43,9 @@ function getEntityPrototypes() isEntityWithOwner = entity.is_entity_with_owner, isMilitaryTarget = entity.is_military_target, maxHealth = entity.max_health, - collisionBox = Converters.collisionBox(entity.collision_box) + collisionBox = Converters.collisionBox(entity.collision_box), + tileWidth = entity.tile_width, + tileHeight = entity.tile_height } local ____ = entity.infinite_resource if entity.map_color ~= nil then diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts index 4983c45..3a612cb 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts @@ -243,6 +243,8 @@ export namespace FactorioPrototype { isMilitaryTarget?: boolean; miningProperties?: EntityMiningProperties | null; collisionBox?: MapBoundingBox | null; + tileWidth?: Int | null; + tileHeight?: Int | null; } export interface MapTile { diff --git a/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts b/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts index a6d7f57..4ae6ce0 100644 --- a/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts @@ -72,6 +72,9 @@ function getEntityPrototypes(): PrototypesByType { isMilitaryTarget: entity.is_military_target, maxHealth: entity.max_health, collisionBox: Converters.collisionBox(entity.collision_box), + + tileWidth: entity.tile_width, + tileHeight: entity.tile_height, } entity.infinite_resource From 4bc46f97531e5a369b530011bb5ed2ccae92b3d7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 28 Aug 2022 19:37:49 +0200 Subject: [PATCH 497/629] progress towards multi-server handling - bump some versions - validate Factorio server ID & token - --- .../portal/FactorioModPortalPublishClient.kt | 2 +- .../portal/FactorioModPublishTask.kt | 2 +- gradle/libs.versions.toml | 20 +- .../kafkatorio/schema/common/factorioIds.kt | 34 +++- .../kafkatorio/schema/common/mapTile.kt | 2 +- .../kafkatorio/schema/common/secrets.kt | 13 ++ .../schema/packets/kafkatorioPacket.kt | 14 +- modules/events-server/build.gradle.kts | 8 +- .../server/config/ApplicationProperties.kt | 9 +- .../adamko/kafkatorio/server/eventsServer.kt | 4 +- .../KafkatorioPacketKafkaProducer.kt | 172 ++++++++++++++++++ .../server/processor/KafkatorioTopology.kt | 66 +------ .../server/processor/eventProcessor.kt | 6 +- .../server/processor/kafkatorioTopics.kt | 2 + .../topology/factorioServerPackets.kt | 25 +-- .../server/security/Authenticator.kt | 125 +++++++++++++ .../kafkatorio/server/socket/SyslogMsg.kt | 14 +- .../server/socket/SyslogSocketServer.kt | 36 ++-- .../server/web/rest/factorioServersRoutes.kt | 6 +- .../web/websocket/WebmapWebsocketServer.kt | 11 +- .../topology/FactorioServerPacketsTest.kt | 48 +++++ .../server/security/AuthenticatorTest.kt | 61 +++++++ .../infra-factorio-server/build.gradle.kts | 8 +- modules/infra-factorio-server/src/.env | 4 - modules/infra-factorio-server/src/.gitignore | 5 +- .../src/docker-compose.yml | 7 +- modules/web-map/build.gradle.kts | 2 + .../dev/adamko/kafkatorio/webmap/map.kt | 10 +- 28 files changed, 577 insertions(+), 139 deletions(-) create mode 100644 modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/secrets.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioPacketKafkaProducer.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/security/Authenticator.kt create mode 100644 modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/FactorioServerPacketsTest.kt create mode 100644 modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/security/AuthenticatorTest.kt delete mode 100644 modules/infra-factorio-server/src/.env diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPortalPublishClient.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPortalPublishClient.kt index 6d988d0..5d27eda 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPortalPublishClient.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPortalPublishClient.kt @@ -65,7 +65,7 @@ class FactorioModPortalPublishClient( expectSuccess = false } - fun uploadMod() = runBlocking { + fun uploadMod(): Unit = runBlocking { client().useToRun { val initUploadResponse = initUpload() diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPublishTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPublishTask.kt index 894feae..0161949 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPublishTask.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPublishTask.kt @@ -65,7 +65,7 @@ abstract class FactorioModPublishTask @Inject constructor( @TaskAction - fun deploy() = runBlocking { + fun deploy(): Unit = runBlocking { val userInputHandler = services.get() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b8efa0b..0e5f30b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,12 +20,12 @@ scrimage = "4.0.31" # https://github.com/sksamuel/scrimage/r semver = "1.2.0" # https://github.com/swiftzer/semver/releases slf4j = "1.7.36" -kotlinx-serialization = "1.3.3" # https://github.com/Kotlin/kotlinx.serialization/releases +kotlinx-serialization = "1.4.0" # https://github.com/Kotlin/kotlinx.serialization/releases kxs-charleskornKaml = "0.44.0" kxs-mamoeYamlkt = "0.12.0" kxs-kxsTsGen = "0.2.1" -kotlinJsWrappers = "1.0.0-pre.367" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom +kotlinJsWrappers = "1.0.0-pre.378" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom kotlinx-cli = "0.3.4" kotlinx-coroutines = "1.6.4" # https://github.com/Kotlin/kotlinx.coroutines/releases @@ -37,21 +37,22 @@ kSvgDsl = "v2.2.0" ktor = "2.1.0" # https://github.com/ktorio/ktor/releases -hoplite = "2.5.2" # https://github.com/sksamuel/hoplite/releases +hoplite = "2.6.1" # https://github.com/sksamuel/hoplite/releases -#simpleSyslogParser = "0.0.6" # https://search.maven.org/artifact/com.github.palindromicity/simple-syslog -simpleSyslogParser = "cbf7d86559" # https://jitpack.io/#palindromicity/simple-syslog/ +simpleSyslogParser = "1.0.0" # https://search.maven.org/artifact/com.github.palindromicity/simple-syslog kotkaStreams = "22.08.06" marykRocksDb = "7.3.1-1" # https://search.maven.org/artifact/io.maryk.rocksdb/rocksdb-multiplatform +klogging = "0.4.9" ## npm ## npm-luaTypes = "2.12.0" npm-typescriptToLua = "1.9.0" -npm-typedFactorio = "1.7.0" +#npm-typedFactorio = "1.6.1" # https://github.com/GlassBricks/typed-factorio/blob/main/Changelog.md +npm-typedFactorio = "1.7.0" # for factorio 1.1.61 npm-typescript = "4.7.4" @@ -63,7 +64,7 @@ mockk = "1.12.5" ## infra ## -factorio = "1.1.64" +factorio = "1.1.68" confluent-kafkaConnect = "7.0.1" grafana = "8.5.0" prometheus = "v2.34.0" @@ -191,7 +192,6 @@ ktorNetwork-core = { group = "io.ktor", name = "ktor-network" ktorNetwork-tls = { group = "io.ktor", name = "ktor-network-tls" } - ### jackson ## #jackson-bom = { group = " com.fasterxml.jackson.module", name = ":jackson-module-kotlin", version = "2.13.+" } #jackson-kotlin = { group = " com.fasterxml.jackson.module", name = ":jackson-module-kotlin", version = "2.13.+" } @@ -203,6 +203,9 @@ logback-core = { group = "ch.qos.logback", name = "logback-core", logback-classic = { group = "ch.qos.logback", name = "logback-classic", version.ref = "qosLogback" } logback-encoder = { group = "net.logstash.logback", name = "logstash-logback-encoder", version = "6.6" } + +klogging = { group = "io.klogging", name = "klogging-jvm", version.ref = "klogging" } + ## gcp ## #gcp-bom = { group = "com.google.cloud", name = "libraries-bom", version = "23.1.0" } #gcp-pubsub = { group = "com.google.cloud", name = "google-cloud-pubsub" } @@ -237,7 +240,6 @@ hoplite-datetime = { group = "com.sksamuel.hoplite", name = "hoplite-datetime", hoplite-yaml = { group = "com.sksamuel.hoplite", name = "hoplite-yaml", version.ref = "hoplite" } -#simpleSyslogParser = { group = "com.github.palindromicity", name = "simple-syslog", version.ref = "simpleSyslogParser" } simpleSyslogParser = { group = "com.github.palindromicity", name = "simple-syslog", version.ref = "simpleSyslogParser" } diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt index d091e67..65b8f0e 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt @@ -76,9 +76,39 @@ data class EntityIdentifiersData( ) : EntityIdentifiers +/** Friendly identifier, used in URLs. Should be human-readable. */ @Serializable @SerialName("kafkatorio.id.FactorioServerId") @JvmInline -value class FactorioServerId(private val id: String) { - override fun toString() = id +value class FactorioServerId(val id: String) : CharSequence by id { + + init { + require(id.isNotBlank()) { "require FactorioServerId is not blank: '$id'" } + require(id.matches(validIdRegex)) { "require FactorioServerId matches $validIdRegex: '$id'" } + } + + override fun toString(): String = id + + companion object { + val validIdRegex = Regex("""^[a-zA-Z0-9\-_]+""" + "\$") + } +} + + +/** Short identifier, used in tokens. Might not be human-readable. */ +@Serializable +@SerialName("kafkatorio.id.FactorioServerToken") +@JvmInline +value class FactorioServerToken(private val id: String) : CharSequence by id { + + init { + require(id.isNotBlank()) { "require FactorioServerToken is not blank: '$id'" } + require(id.matches(FactorioServerId.validIdRegex)) { "require FactorioServerToken matches ${validIdRegex}: '$id'" } + } + + override fun toString(): String = id + + companion object { + val validIdRegex = Regex("^[a-zA-Z0-9]+\$") + } } diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt index 2661272..964227e 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt @@ -110,7 +110,7 @@ value class ServerMapTilePngFilename(val value: String) { chunkX: Int, chunkY: Int, ) : this( - "servers/${serverId}" + + "servers/${serverId.id}" + "/map" + "/layers/${layer.dir}" + "/s${surfaceIndex}" + diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/secrets.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/secrets.kt new file mode 100644 index 0000000..5e855f6 --- /dev/null +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/secrets.kt @@ -0,0 +1,13 @@ +package dev.adamko.kafkatorio.schema.common + +import kotlin.jvm.JvmInline +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + + +@Serializable +@SerialName("kafkatorio.common.MaskedValue") +@JvmInline +value class MaskedValue(val value: String) { + override fun toString(): String = "Secret(***)" +} diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt index 6ef27b2..fa61913 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt @@ -24,4 +24,16 @@ sealed class KafkatorioPacketData data class KafkatorioPacketDataError( val message: String? = null, val rawValue: String? = null, -) : KafkatorioPacketData() +) : KafkatorioPacketData() { + constructor( + exception: Exception, + rawValue: String? = null + ) : this( + message = """ + ${exception::class.qualifiedName} ${exception.message} + + ${exception.stackTraceToString()} + """.trimIndent(), + rawValue = rawValue, + ) +} diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 01a01fe..5052189 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -40,6 +40,8 @@ dependencies { implementation(libs.ktorSerialization.kotlinxJson) with(libs.ktorServer) { + implementation(auth) + implementation(authJwt) implementation(core) implementation(callId) implementation(callLogging) @@ -59,9 +61,13 @@ dependencies { } // - implementation(libs.simpleSyslogParser) + // https://search.maven.org/artifact/org.bouncycastle/bcprov-jdk15on + implementation("org.bouncycastle:bcprov-jdk15on:1.70") + implementation("com.brendangoldberg:kotlin-jwt:1.1.0") + implementation("com.auth0:java-jwt:4.0.0") + implementation(libs.kafka.kotkaStreams) { isChanging = false } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/ApplicationProperties.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/ApplicationProperties.kt index 1595320..9b7d7a4 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/ApplicationProperties.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/ApplicationProperties.kt @@ -3,6 +3,9 @@ package dev.adamko.kafkatorio.server.config import com.sksamuel.hoplite.ConfigLoaderBuilder import com.sksamuel.hoplite.addEnvironmentSource import com.sksamuel.hoplite.addResourceOrFileSource +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.common.FactorioServerToken +import dev.adamko.kafkatorio.schema.common.MaskedValue import java.nio.file.Path @@ -15,6 +18,10 @@ data class ApplicationProperties( val socketServerHost: String, val socketServerPort: Int, + + val jwtSecret: MaskedValue, + + val kafkatorioServers: Map ) { companion object { @@ -23,7 +30,7 @@ data class ApplicationProperties( ConfigLoaderBuilder.default() .addDefaults() .allowUnresolvedSubstitutions() - .allowEmptyTree() + .allowEmptySources() .addEnvironmentSource() .addResourceOrFileSource("/.secret.config.yml", optional = true) .addResourceOrFileSource("/config.yml", optional = false) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt index b9c9db1..ab6d89a 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt @@ -2,6 +2,7 @@ package dev.adamko.kafkatorio.server import dev.adamko.kafkatorio.server.config.ApplicationProperties import dev.adamko.kafkatorio.server.processor.eventsProcessor +import dev.adamko.kafkatorio.server.security.Authenticator import dev.adamko.kafkatorio.server.socket.SyslogSocketServer import dev.adamko.kafkatorio.server.web.startWebServer import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer @@ -15,6 +16,7 @@ suspend fun main(): Unit = coroutineScope { val websocketServer = WebmapWebsocketServer() val syslogSocketServer = SyslogSocketServer(appProps) + val authenticator = Authenticator(appProps) launch { startWebServer(appProps, websocketServer) @@ -25,6 +27,6 @@ suspend fun main(): Unit = coroutineScope { } launch { - eventsProcessor(appProps, syslogSocketServer, websocketServer) + eventsProcessor(appProps, syslogSocketServer, websocketServer, authenticator) } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioPacketKafkaProducer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioPacketKafkaProducer.kt new file mode 100644 index 0000000..1b0cfa3 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioPacketKafkaProducer.kt @@ -0,0 +1,172 @@ +package dev.adamko.kafkatorio.server.processor + +import com.github.palindromicity.syslog.dsl.SyslogFieldKeys +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.server.config.ApplicationProperties +import dev.adamko.kafkatorio.server.config.jsonMapper +import dev.adamko.kafkatorio.server.security.Authenticator +import dev.adamko.kafkatorio.server.socket.SyslogMsg +import dev.adamko.kafkatorio.server.socket.SyslogSocketServer +import dev.adamko.kotka.kxs.kafkaSerializer +import java.util.Properties +import kotlin.coroutines.coroutineContext +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.job +import org.apache.kafka.clients.producer.KafkaProducer +import org.apache.kafka.clients.producer.ProducerRecord +import org.apache.kafka.common.header.internals.RecordHeader +import org.apache.kafka.common.serialization.Serdes +import org.apache.kafka.streams.StreamsConfig + + +/** + * Consume Syslog messages, verifies each, and forwards them to a Kafka topic. + */ +class KafkatorioPacketKafkaProducer( + private val appProps: ApplicationProperties, + private val syslogServer: SyslogSocketServer, + private val authenticator: Authenticator, +) : AutoCloseable { + + private val props: Properties = appProps.kafkaStreamsConfig.toProperties() + + init { + props.updateValue(StreamsConfig.APPLICATION_ID_CONFIG) { "$it.KafkatorioPacketKafkaProducer" } + } + + private val producer: KafkaProducer = KafkaProducer( + props.apply { + updateValue(StreamsConfig.APPLICATION_ID_CONFIG) { "$it.KafkatorioPacketKafkaProducer" } + }, + jsonMapper.kafkaSerializer(FactorioServerId.serializer()), + Serdes.String().serializer(), + ) + + private val dlqProducer: KafkaProducer = KafkaProducer( + props.apply { + updateValue(StreamsConfig.APPLICATION_ID_CONFIG) { "$it.KafkatorioPacketKafkaProducer.dlq" } + }, + Serdes.String().serializer(), + Serdes.String().serializer(), + ) + + + suspend fun launch() { + coroutineContext.job.invokeOnCompletion { + this@KafkatorioPacketKafkaProducer.close() + } + + syslogServer.messages + .filter { + (it.message ?: "").run { + startsWith("KafkatorioPacket:::") || startsWith("KafkatorioPacket encoded:::") + } + }.onEach { syslog -> + runCatching { + getFactorioServerId(syslog) + }.fold( + onSuccess = { serverId -> produceMessage(serverId, syslog) }, + onFailure = { ex -> + produceDlqMessage(syslog, "${ex::class.java.name}: ${ex.message}") + + if (ex is CancellationException) throw ex + } + ) + }.collect() + } + + + private fun getFactorioServerId(syslog: SyslogMsg): FactorioServerId { + val token = syslog.headerAppName + if (token.isNullOrBlank()) { + error("no token in syslog message. msg: ${syslog.src}") + } + + val serverToken = authenticator.verifyJwt(token) + if (serverToken.isNullOrBlank()) { + error("could not decode token $token. msg: ${syslog.src}") + } + + val serverId = appProps.kafkatorioServers[serverToken] + if (serverId.isNullOrBlank()) { + error("no server ID for token $serverToken. msg: ${syslog.src}") + } + + return serverId + } + + + private fun produceMessage( + serverId: FactorioServerId, + syslog: SyslogMsg, + ) { + val kafkatorioMessage = syslog.message?.substringAfter(":::") + + val record = ProducerRecord( + TOPIC_SRC_SERVER_LOG, + serverId, + kafkatorioMessage, + ) + + syslog.copyHeadersTo(record) + + producer.send(record) + } + + + private fun produceDlqMessage(syslog: SyslogMsg, errorMessage: String) { + log("error: $errorMessage, $syslog") + + val record = ProducerRecord( + TOPIC_SRC_SERVER_LOG_DLQ, + "unknown", + errorMessage, + ) + + syslog.copyHeadersTo(record) + + dlqProducer.send(record) + } + + + override fun close() { + producer.close() + } + + + companion object { + private fun log(msg: String) = println("[KafkatorioPacketKafkaProducer] $msg") + + + private fun Properties.updateValue( + key: String, + update: (oldValue: String) -> String + ) { + val newValue = update(getValue(key) as String) + setProperty(key, newValue) + } + + + private fun SyslogMsg.copyHeadersTo(record: ProducerRecord<*, *>) { + val headers = SyslogFieldKeys.values() + .filter { "HEADER_" in it.name } + .mapNotNull { headerKey -> + val headerValue = src[headerKey.field] + when { + headerValue.isNullOrBlank() -> null + else -> RecordHeader( + headerKey.field, + headerValue.toByteArray() + ) + } + } + + headers.forEach { header -> + record.headers().add(header) + } + } + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt index f2897f8..56c8e25 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt @@ -1,6 +1,5 @@ package dev.adamko.kafkatorio.server.processor -import com.github.palindromicity.syslog.dsl.SyslogFieldKeys import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.PrototypeHashCode import dev.adamko.kafkatorio.schema.common.ServerMapChunkId @@ -31,17 +30,10 @@ import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.cancel import kotlinx.coroutines.currentCoroutineContext -import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.job import kotlinx.coroutines.launch import kotlinx.coroutines.suspendCancellableCoroutine -import org.apache.kafka.clients.producer.KafkaProducer import org.apache.kafka.clients.producer.ProducerConfig -import org.apache.kafka.clients.producer.ProducerRecord -import org.apache.kafka.common.header.internals.RecordHeader -import org.apache.kafka.common.serialization.Serdes import org.apache.kafka.streams.KafkaStreams import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.StreamsConfig @@ -54,6 +46,7 @@ internal class KafkatorioTopology( private val appProps: ApplicationProperties, private val wsServer: WebmapWebsocketServer, private val syslogServer: SyslogSocketServer, + private val kafkatorioPacketKafkaProducer: KafkatorioPacketKafkaProducer, ) { private val builderScope = CoroutineScope(CoroutineName("KafkaTopology")) @@ -168,60 +161,10 @@ internal class KafkatorioTopology( /** Receive log messages from the syslog socket, and send them to a Kafka topic */ - private fun syslogProducer( - id: String = "syslog-producer" - ) { - val props: Properties = appProps.kafkaStreamsConfig.toProperties() - - val appId = props.compute(StreamsConfig.APPLICATION_ID_CONFIG) { _, v -> "$v.$id" } as String - props.setProperty(StreamsConfig.APPLICATION_ID_CONFIG, appId) - - - val producer: KafkaProducer = KafkaProducer( - props, - Serdes.String().serializer(), - Serdes.String().serializer(), - ) - - builderScope.coroutineContext.job.invokeOnCompletion { - producer.close() + private fun syslogProducer() { + builderScope.launch { + kafkatorioPacketKafkaProducer.launch() } - - syslogServer.messages - .filter { - (it.message ?: "").run { - startsWith("KafkatorioPacket:::") || startsWith("KafkatorioPacket encoded:::") - } - } - .onEach { syslogMsg -> - - val kafkatorioMessage = syslogMsg.message?.substringAfter(":::") - - val record = ProducerRecord( - TOPIC_SRC_SERVER_LOG, - "syslog-test", - kafkatorioMessage, - ) - - val headers = SyslogFieldKeys.values() - .filter { "HEADER_" in it.name } - .mapNotNull { headerKey -> - val headerValue = syslogMsg.src[headerKey.field] - when { - headerValue.isNullOrBlank() -> null - else -> RecordHeader( - headerKey.field, - headerValue.toByteArray() - ) - } - } - - headers.forEach { header -> - record.headers().add(header) - } - - producer.send(record) - }.launchIn(builderScope) } @@ -251,6 +194,7 @@ internal class KafkatorioTopology( when (newState) { KafkaStreams.State.NOT_RUNNING, KafkaStreams.State.ERROR -> if (cont.isActive) cont.resume(newState) + else -> Unit // do nothing } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt index b10982a..9c80d9c 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt @@ -3,6 +3,7 @@ package dev.adamko.kafkatorio.server.processor import dev.adamko.kafkatorio.server.config.ApplicationProperties import dev.adamko.kafkatorio.server.processor.admin.KafkatorioKafkaAdmin +import dev.adamko.kafkatorio.server.security.Authenticator import dev.adamko.kafkatorio.server.socket.SyslogSocketServer import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer import kotlinx.coroutines.awaitCancellation @@ -14,12 +15,15 @@ suspend fun eventsProcessor( appProps: ApplicationProperties, syslogServer: SyslogSocketServer, wsServer: WebmapWebsocketServer, + authenticator: Authenticator, ): Unit = coroutineScope { val admin = KafkatorioKafkaAdmin(appProps) admin.createKafkatorioTopics() - val topology = KafkatorioTopology(appProps, wsServer, syslogServer) + val kafkatorioPacketKafkaProducer = KafkatorioPacketKafkaProducer(appProps, syslogServer, authenticator) + + val topology = KafkatorioTopology(appProps, wsServer, syslogServer, kafkatorioPacketKafkaProducer) launch { topology.start() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt index e61f270..b3af92d 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt @@ -18,6 +18,7 @@ import kotlin.reflect.KClass private const val DOMAIN = "kafkatorio" const val TOPIC_SRC_SERVER_LOG = "$DOMAIN.src.server-log" +const val TOPIC_SRC_SERVER_LOG_DLQ = "$DOMAIN.src.server-log.dlq" //const val TOPIC_GROUPED_MAP_CHUNKS_STATE = "$DOMAIN.state.map-chunks.grouped" @@ -41,6 +42,7 @@ const val TOPIC_BROADCAST_TO_WEBSOCKET = "$DOMAIN.broadcast.websocket" fun allTopics(): Set = buildSet { add(TOPIC_SRC_SERVER_LOG) + add(TOPIC_SRC_SERVER_LOG_DLQ) // add(TOPIC_GROUPED_MAP_CHUNKS_STATE) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt index bb2b3e9..20ecdab 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt @@ -11,11 +11,11 @@ import dev.adamko.kotka.extensions.component1 import dev.adamko.kotka.extensions.component2 import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.producedAs -import dev.adamko.kotka.extensions.streams.map +import dev.adamko.kotka.extensions.streams.mapValues import dev.adamko.kotka.extensions.streams.to import dev.adamko.kotka.kxs.serde import java.util.zip.Inflater -import kotlinx.serialization.decodeFromString +import kotlinx.coroutines.CancellationException import okio.Buffer import okio.ByteString import okio.ByteString.Companion.decodeBase64 @@ -34,29 +34,32 @@ fun factorioServerPacketStream( TOPIC_SRC_SERVER_LOG, consumedAs( "read-raw-packets-from-server", - Serdes.String(), + jsonMapper.serde(FactorioServerId.serializer()), Serdes.String(), ) - ).map("decode-packets") { serverId: String, value: String -> - val packet = runCatching { - val decoded = decodeFactorioEncodedString(value) - jsonMapper.decodeFromString(decoded) - }.getOrElse { e -> + ).mapValues("decode-packets") { _: FactorioServerId, value: String? -> + + val packet = try { + val decoded = decodeFactorioEncodedString(value!!) + jsonMapper.decodeFromString(KafkatorioPacket.serializer(), decoded) + } catch (e: Exception) { + if (e is CancellationException) throw e + KafkatorioPacket( modVersion = "unknown", tick = Tick(0u), data = KafkatorioPacketDataError( - message = e.message, + exception = e, rawValue = value, ) ) } if (packet.data is KafkatorioPacketDataError) { - println("error parsing $TOPIC_SRC_SERVER_LOG message: ${packet.data}") + println("error parsing $TOPIC_SRC_SERVER_LOG message: $packet") } - FactorioServerId(serverId) to packet + packet } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/security/Authenticator.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/security/Authenticator.kt new file mode 100644 index 0000000..7c95183 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/security/Authenticator.kt @@ -0,0 +1,125 @@ +package dev.adamko.kafkatorio.server.security + +import com.auth0.jwt.JWT +import com.auth0.jwt.algorithms.Algorithm +import com.auth0.jwt.interfaces.DecodedJWT +import dev.adamko.kafkatorio.schema.common.FactorioServerToken +import dev.adamko.kafkatorio.server.config.ApplicationProperties +import kotlin.reflect.jvm.jvmName +import kotlinx.coroutines.CancellationException +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json +import okio.ByteString.Companion.decodeBase64 + + +class Authenticator( + appProps: ApplicationProperties, +) { + private val algorithm: Algorithm = Algorithm.HMAC256(appProps.jwtSecret.value) + + private val verifier = JWT.require(algorithm).build() + + fun verifyJwt(token: String): FactorioServerToken? { + return runCatching { + val decodedJwt: DecodedJWT? = verifier.verify(token) + + val payloadJson = decodedJwt?.payload?.decodeBase64()?.string(Charsets.UTF_8) ?: "{}" + + jsonMapper.decodeFromString( + KafkatorioJwtPayload.serializer(), + payloadJson, + ).serverToken + + }.onFailure { e -> + if (e is CancellationException) throw e + + println("[Authenticator] Could not decode JWT ${e::class.jvmName}: ${e.message}") + }.getOrNull() + } + + companion object { + private val jsonMapper = Json { + ignoreUnknownKeys = true + } + } +} + + +@Serializable +@SerialName("kafkatorio.auth.KafkatorioJwtPayload") +private data class KafkatorioJwtPayload( + @SerialName("sub") + val serverToken: FactorioServerToken, + /** unix epoch seconds*/ + @SerialName("iat") + val issuedAtTime: Long, +) + + +//// https://github.com/auth0/java-jwt/blob/f799e589c3d43de318c7ca0f0c36e462297db973/lib/src/test/java/com/auth0/jwt/PemUtils.java +//private object PemUtils { +// +// fun readPublicKey(filepath: String, algorithm: String): PublicKey { +// val bytes = parsePemFile(File(filepath)) +// return getPublicKey(bytes, algorithm) +// } +// +//// fun readPublicKey(reader: Reader, algorithm: String): PublicKey { +//// return getPublicKey(bytes, algorithm) +//// } +// +// fun readPrivateKey(filepath: String, algorithm: String): PrivateKey { +// val bytes = parsePemFile(File(filepath)) +// return getPrivateKey(bytes, algorithm) +// } +// +// private fun parsePemFile(pemFile: File): ByteArray { +// return when { +// !pemFile.isFile -> +// throw FileNotFoundException("'${pemFile.absolutePath}' is not a file") +// +// !pemFile.exists() -> +// throw FileNotFoundException("The file '${pemFile.absolutePath}' doesn't exist.") +// +// else -> +// PemReader(FileReader(pemFile)).use { reader -> +// reader.readPemObject().content +// } +// } +// } +// +// private fun getPublicKey(keyBytes: ByteArray, algorithm: String): PublicKey = +// getKey(algorithm) { +// val keySpec: EncodedKeySpec = X509EncodedKeySpec(keyBytes) +// generatePublic(keySpec) +// } +// +// private fun getPrivateKey(keyBytes: ByteArray, algorithm: String): PrivateKey = +// getKey(algorithm) { +// val keySpec: EncodedKeySpec = PKCS8EncodedKeySpec(keyBytes) +// generatePrivate(keySpec) +// } +// +// +// private fun getKey( +// algorithm: String, +// generateKey: KeyFactory.() -> K +// ): K = runCatching { +// val kf = KeyFactory.getInstance(algorithm) +// kf.generateKey() +// }.getOrElse { e -> +// when (e) { +// is NoSuchAlgorithmException -> +// throw IllegalStateException( +// "Could not reconstruct key, algorithm '$algorithm' could not be found.", +// e +// ) +// +// is InvalidKeySpecException -> +// throw IllegalStateException("Could not reconstruct key", e) +// +// else -> throw e +// } +// } +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogMsg.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogMsg.kt index 26325e6..d329352 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogMsg.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogMsg.kt @@ -3,7 +3,7 @@ package dev.adamko.kafkatorio.server.socket import com.github.palindromicity.syslog.dsl.SyslogFieldKeys data class SyslogMsg( - val src: Map + val src: Map, ) { val message: String? @@ -48,16 +48,4 @@ data class SyslogMsg( val structuredElementIdPnamePattern: String? get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_PNAME_PATTERN.field] - - companion object { - fun Map.toSyslogMsg(): SyslogMsg { - val map = entries.mapNotNull { (k, v) -> - when (v) { - is String -> k to v - else -> null - } - }.toMap() - return SyslogMsg(map) - } - } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt index 5f8e686..666d477 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt @@ -8,13 +8,13 @@ import com.github.palindromicity.syslog.SyslogParser import com.github.palindromicity.syslog.SyslogParserBuilder import com.github.palindromicity.syslog.SyslogSpecification import dev.adamko.kafkatorio.server.config.ApplicationProperties -import dev.adamko.kafkatorio.server.socket.SyslogMsg.Companion.toSyslogMsg import io.ktor.network.selector.SelectorManager import io.ktor.network.sockets.Socket import io.ktor.network.sockets.aSocket import io.ktor.network.sockets.openReadChannel import io.ktor.utils.io.readUTF8Line import java.util.EnumSet +import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.MutableSharedFlow @@ -30,10 +30,8 @@ class SyslogSocketServer( appProps: ApplicationProperties, ) { - private val selectorManager: SelectorManager = SelectorManager(Dispatchers.IO) - - - private val serverSocketTcp = aSocket(selectorManager) + /** Incoming messages */ + private val serverSocketTcp = aSocket(SelectorManager(Dispatchers.IO)) .tcp() .bind( appProps.socketServerHost, @@ -50,8 +48,7 @@ class SyslogSocketServer( NilPolicy.OMIT, EnumSet.of(AllowableDeviations.PRIORITY, AllowableDeviations.VERSION), ) - ) - .build() + ).build() private val _messages: MutableSharedFlow = MutableSharedFlow() @@ -74,31 +71,30 @@ class SyslogSocketServer( channel.readUTF8Line() }.fold( onSuccess = { line -> - when (line) { - null -> { - log("received 'null' from ${socket.description()} - closing connection") - socket.close() - } -// else -> log("received '$line' from ${socket.description()}") + if (line == null) { + log("received 'null' from ${socket.description()} - closing connection") + socket.close() } + // log("received '$line' from ${socket.description()}") line }, - onFailure = { e -> - log("reading line from socket failed ${socket.description()}, cause: $e") + onFailure = { ex -> + if (ex is CancellationException) throw ex + + log("reading line from socket failed ${socket.description()}, cause: $ex") null }, ) if (line != null) { - - val syslog = syslogParser.parseLine(line).toSyslogMsg() - + val syslog = SyslogMsg(syslogParser.parseLine(line)) _messages.emit(syslog) } - yield() } } catch (e: Exception) { - log("closing socket ${socket.description()}, cause: $e") + if (e is CancellationException) throw e + log("closing socket ${socket.description()}, cause: ${e::class.java.name} ${e.message}") + e.printStackTrace() withContext(Dispatchers.IO) { socket.close() } } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt index 283d767..3925a33 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt @@ -6,6 +6,7 @@ import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer import dev.adamko.kafkatorio.schema.common.ServerMapTilePngFilename import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.server.config.ApplicationProperties +import dev.adamko.kafkatorio.server.config.jsonMapper import io.ktor.http.HttpStatusCode import io.ktor.http.content.EntityTagVersion import io.ktor.http.content.versions @@ -21,6 +22,7 @@ import io.ktor.util.combineSafe import io.ktor.util.pipeline.PipelineContext import kotlin.io.path.Path import kotlinx.serialization.Serializable +import kotlinx.serialization.json.encodeToJsonElement fun Routing.factorioServersRoutes( @@ -28,7 +30,9 @@ fun Routing.factorioServersRoutes( ) { get { - call.respond(HttpStatusCode.NotImplemented) + val serverIds = appProps.kafkatorioServers.values.toSet().sortedBy { it.id } + val serverIdsJson = jsonMapper.encodeToJsonElement(serverIds) + call.respond(serverIdsJson) } get { tile -> diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt index 6f0e8e3..e672196 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt @@ -7,6 +7,7 @@ import io.ktor.websocket.send import java.util.concurrent.atomic.AtomicInteger import kotlin.time.Duration.Companion.seconds import kotlin.time.TimeSource +import kotlinx.coroutines.CancellationException import kotlinx.coroutines.cancel import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.coroutineScope @@ -57,6 +58,8 @@ class WebmapWebsocketServer { if (client.isActive) { client.outgoing.send(Frame.Text(msg)) } + }.onFailure { e -> + if (e is CancellationException) throw e } }.launchIn(client) @@ -68,6 +71,8 @@ class WebmapWebsocketServer { while (isActive) { runCatching { client.send("elapsed ${startTime.elapsedNow()}") + }.onFailure { e -> + if (e is CancellationException) throw e } delay(10.seconds) yield() @@ -100,7 +105,11 @@ class WebmapWebsocketServer { onSuccess = { // log("sent message to client $name: $frame") }, - onFailure = { e -> log("failed to send message to client $name: $e") } + onFailure = { e -> + if (e is CancellationException) throw e + + log("failed to send message to client $name: $e") + } ) override fun equals(other: Any?): Boolean = name == other diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/FactorioServerPacketsTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/FactorioServerPacketsTest.kt new file mode 100644 index 0000000..0cadcec --- /dev/null +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/FactorioServerPacketsTest.kt @@ -0,0 +1,48 @@ +package dev.adamko.kafkatorio.server.processor.topology + +import dev.adamko.kafkatorio.library.kxsBinary +import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.common.ServerMapChunkId +import dev.adamko.kotka.kxs.serde +import io.kotest.core.spec.style.FunSpec +import kotlin.time.Duration +import kotlin.time.toJavaDuration +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.TestInputTopic +import org.apache.kafka.streams.TopologyTestDriver + +class FactorioServerPacketsTest : FunSpec({ + + +}) + +private class Scenario( + streamsBuilder: StreamsBuilder = StreamsBuilder(), + + groupedMapChunksInputTopicName: String = "kafkatorio.state.map-chunk.terrain.colour", + + val serverId: FactorioServerId = FactorioServerId("test-server-id"), +) : AutoCloseable { + + init { + factorioServerPacketStream(streamsBuilder) + } + + private val testDriver: TopologyTestDriver = TopologyTestDriver(streamsBuilder.build()) + + val groupedMapChunksInputTopic: TestInputTopic> = + testDriver.createInputTopic( + groupedMapChunksInputTopicName, + kxsBinary.serde().serializer(), + kxsBinary.serde>().serializer(), + ) + + operator fun plusAssign(wallClockTime: Duration) { + testDriver.advanceWallClockTime(wallClockTime.toJavaDuration()) + } + + override fun close() { + testDriver.close() + } +} diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/security/AuthenticatorTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/security/AuthenticatorTest.kt new file mode 100644 index 0000000..0241fdb --- /dev/null +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/security/AuthenticatorTest.kt @@ -0,0 +1,61 @@ +package dev.adamko.kafkatorio.server.security + +import dev.adamko.kafkatorio.schema.common.MaskedValue +import dev.adamko.kafkatorio.server.config.ApplicationProperties +import dev.adamko.kafkatorio.server.config.PortVal +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.nulls.shouldBeNull +import io.kotest.matchers.nulls.shouldNotBeNull +import kotlin.io.path.Path + + +class AuthenticatorTest : FunSpec({ + + test("verify correct JWT is verified") { + + val authenticator = Authenticator( + testApplicationProperties( + jwtSecret = "123 456 789" + ) + ) + + val result = authenticator.verifyJwt(jwtMessage) + + result.shouldNotBeNull() + } + + test("verify invalid JWT returns null") { + + val authenticator = Authenticator( + testApplicationProperties( + jwtSecret = "wrong" + ) + ) + + val result = authenticator.verifyJwt(jwtMessage) + + result.shouldBeNull() + } + +}) { + + companion object { + /** Key: `123 465 789` */ + private val jwtMessage = """ + eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.ToFLkPBs_EKF4B2bRQyVPfkKrB-x6WgyAq6KsR9oHwg + """.trimIndent() + + private fun testApplicationProperties( + jwtSecret: String, + ) = ApplicationProperties( + webPort = PortVal.DEFAULT, + serverDataDir = Path(""), + kafkaAdminConfig = emptyMap(), + kafkaStreamsConfig = emptyMap(), + socketServerHost = "", + socketServerPort = 9999, + jwtSecret = MaskedValue(jwtSecret), + kafkatorioServers = emptyMap(), + ) + } +} diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 6e5f8b2..4380489 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -53,8 +53,14 @@ tasks.dockerUp { } +val kafkatorioServerToken: String by project + + tasks.dockerEnvUpdate { - properties("FACTORIO_VERSION" to libs.versions.factorio.get()) + properties( + "FACTORIO_VERSION" to libs.versions.factorio.get(), + "KAFKATORIO_TOKEN" to kafkatorioServerToken, + ) } diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env deleted file mode 100644 index b9e9fb3..0000000 --- a/modules/infra-factorio-server/src/.env +++ /dev/null @@ -1,4 +0,0 @@ -# Do not edit manually. This file was created with task 'dockerEnvUpdate' -COMPOSE_PROJECT_NAME=kafkatorio -FACTORIO_VERSION=1.1.64 -KAFKATORIO_VERSION=0.8.0 diff --git a/modules/infra-factorio-server/src/.gitignore b/modules/infra-factorio-server/src/.gitignore index b09a6cc..545275d 100644 --- a/modules/infra-factorio-server/src/.gitignore +++ b/modules/infra-factorio-server/src/.gitignore @@ -1 +1,4 @@ -factorio-server +factorio-server/ + +# .env contains secret token +.env diff --git a/modules/infra-factorio-server/src/docker-compose.yml b/modules/infra-factorio-server/src/docker-compose.yml index e040f34..499e029 100644 --- a/modules/infra-factorio-server/src/docker-compose.yml +++ b/modules/infra-factorio-server/src/docker-compose.yml @@ -20,12 +20,9 @@ services: driver: syslog options: syslog-address: "tcp://host.docker.internal:12034" # pc -# syslog-address: "tcp://localhost:12034" # nuc + #syslog-address: "tcp://localhost:12034" # nuc syslog-format: "rfc5424" - tag: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyLCJrZXkiOiIwMTIzNDU2Nzg5YWJjZGVmIn0.rozxe6m4HmvQIVtESq2kT_CumIw7cFK2zbeKc5aUwEg" - - -# correct horse battery staple + tag: ${KAFKATORIO_TOKEN} # environment: # RCON_PORT: 27715 diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 4905ccf..3b3d776 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -88,8 +88,10 @@ kotlin { kvision("kvision-state") kvision("kvision-chart") kvision("kvision-maps") + kvision("kvision-rest") kvision("kvision-redux") kvision("kvision-state-flow") + kvision("kvision-routing-navigo-ng") implementation(devNpm("http-proxy-middleware", "^2.0.6")) implementation(dependencies.platform(devNpm("http-proxy-middleware", "^2.0.6"))) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index bff9f1a..adc7782 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -158,7 +158,13 @@ class FactorioMap { companion object { const val DYNAMIC_RELOAD_ATT = "dynamic-reload" - private fun tileLayerUrlTemplate(layer: ServerMapTileLayer): String = - "/kafkatorio/data/servers/syslog-test/map/layers/${layer.dir}/s1/z{z}/x{x}/y{y}.png" + private val serverName: String + get() = window.location.pathname + .substringAfter("kafkatorio/data/servers/") + .substringBefore("/") + + private fun tileLayerUrlTemplate(layer: ServerMapTileLayer): String { + return "/kafkatorio/data/servers/$serverName/map/layers/${layer.dir}/s1/z{z}/x{x}/y{y}.png" + } } } From 5afbbd736d9ea4490ab30e7c6cd9f6f5bbd45557 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 1 Sep 2022 22:57:08 +0200 Subject: [PATCH 498/629] rm unused imports --- buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt index 5c14308..97a009a 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt @@ -1,10 +1,6 @@ package dev.adamko.kafkatorio import io.kvision.gradle.KVisionExtension -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.jsonObject import org.gradle.api.Project import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.findByType From b1cf94a8a8d478e8352a609ea5cbdc811faca5df Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 1 Sep 2022 22:57:40 +0200 Subject: [PATCH 499/629] fix item subgroup mapping --- .../generated/lua/main/events/prototypeUpdates.lua | 7 +++++-- .../main/typescript/main/events/prototypeUpdates.ts | 12 ++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua index 5cc2334..d856e92 100644 --- a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua @@ -1,5 +1,5 @@ local ____exports = {} -local emit, getMapTilePrototypes, getEntityPrototypes, convertItemGroup +local emit, getMapTilePrototypes, getEntityPrototypes, convertItemGroup, convertItemSubgroup local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") local FactorioPrototype = ____kafkatorio_2Dschema.FactorioPrototype local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData @@ -38,7 +38,7 @@ function getEntityPrototypes() type = FactorioPrototype.Type.Entity, protoId = Converters.prototypeId(entity.type, entity.name), group = convertItemGroup(entity.group), - subgroup = convertItemGroup(entity.subgroup), + subgroup = convertItemSubgroup(entity.subgroup), isBuilding = entity.is_building, isEntityWithOwner = entity.is_entity_with_owner, isMilitaryTarget = entity.is_military_target, @@ -64,6 +64,9 @@ function getEntityPrototypes() return protos end function convertItemGroup(itemGroup) + return {name = itemGroup.name, type = itemGroup.type, parentName = nil} +end +function convertItemSubgroup(itemGroup) local ____itemGroup_name_3 = itemGroup.name local ____itemGroup_type_4 = itemGroup.type local ____itemGroup_group_name_1 = itemGroup.group diff --git a/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts b/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts index 4ae6ce0..b5f785d 100644 --- a/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts +++ b/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts @@ -65,7 +65,7 @@ function getEntityPrototypes(): PrototypesByType { protoId: Converters.prototypeId(entity.type, entity.name), group: convertItemGroup(entity.group), - subgroup: convertItemGroup(entity.subgroup), + subgroup: convertItemSubgroup(entity.subgroup), isBuilding: entity.is_building, isEntityWithOwner: entity.is_entity_with_owner, @@ -76,7 +76,6 @@ function getEntityPrototypes(): PrototypesByType { tileWidth: entity.tile_width, tileHeight: entity.tile_height, } - entity.infinite_resource if (entity.map_color != undefined) { entityProto.mapColour = Converters.mapColour(entity.map_color) @@ -96,6 +95,15 @@ function getEntityPrototypes(): PrototypesByType { function convertItemGroup(itemGroup: LuaGroup): EntityItemGroup { + return { + name: itemGroup.name, + type: itemGroup.type, + parentName: null, + } +} + + +function convertItemSubgroup(itemGroup: LuaGroup): EntityItemGroup { return { name: itemGroup.name, type: itemGroup.type, From d3547f5927a9eb62e03a5a9eef83e9fdd18507b6 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 1 Sep 2022 22:58:10 +0200 Subject: [PATCH 500/629] EmptySerializersModule -> EmptySerializersModule() --- .../kotlin/dev/adamko/kafkatorio/library/kxsBinary.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/kxsBinary.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/kxsBinary.kt index 723e2bc..2293971 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/kxsBinary.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/kxsBinary.kt @@ -20,7 +20,7 @@ val kxsBinary: KxsBinary = KxsBinary() /** [`https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/formats.md#efficient-binary-format`](https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/formats.md#efficient-binary-format) */ class KxsBinary( - override val serializersModule: SerializersModule = EmptySerializersModule + override val serializersModule: SerializersModule = EmptySerializersModule() ) : BinaryFormat { override fun encodeToByteArray(serializer: SerializationStrategy, value: T): ByteArray { @@ -44,7 +44,7 @@ private val byteArraySerializer = ByteArraySerializer() class KxsDataOutputEncoder( private val output: BufferedSink, - override val serializersModule: SerializersModule = EmptySerializersModule, + override val serializersModule: SerializersModule = EmptySerializersModule(), ) : AbstractEncoder() { private operator fun BufferedSink.invoke(action: BufferedSink.() -> Unit): Unit = action() @@ -99,7 +99,7 @@ class KxsDataOutputEncoder( class KxsDataInputDecoder( private val input: BufferedSource, - override val serializersModule: SerializersModule = EmptySerializersModule, + override val serializersModule: SerializersModule = EmptySerializersModule(), private var elementsCount: Int = 0, ) : AbstractDecoder() { From 993495745711e278fe538bcfa8fd7d49162f48e2 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 1 Sep 2022 23:00:58 +0200 Subject: [PATCH 501/629] rm ::class.qualifiedName (not available on JS) --- .../dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt index fa61913..0b83f61 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt @@ -30,7 +30,7 @@ data class KafkatorioPacketDataError( rawValue: String? = null ) : this( message = """ - ${exception::class.qualifiedName} ${exception.message} + $exception ${exception.message} ${exception.stackTraceToString()} """.trimIndent(), From 02edffa2e9af7c1acb0fb13f3ec420a2ac52a118 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 1 Sep 2022 23:12:58 +0200 Subject: [PATCH 502/629] version bump to 0.9.0 (just prepping for the next release) --- build.gradle.kts | 2 +- modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- modules/events-server/docker/.env | 2 +- modules/infra-kafka-cluster/src/.env | 2 +- modules/infra-kafka-pipe/src/.env | 2 +- modules/web-map/docker/.env | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index edacbbc..da1e252 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.8.0" +version = "0.9.0" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index a88c996..603ca6d 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.8.0", + "version": "0.9.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index c913e8b..e90030d 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.8.0", + "version": "0.9.0", "private": true, "scripts": { "build": "tstl", diff --git a/modules/events-server/docker/.env b/modules/events-server/docker/.env index 74562e0..1eb5f42 100644 --- a/modules/events-server/docker/.env +++ b/modules/events-server/docker/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.8.0 +KAFKATORIO_VERSION=0.9.0 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index 7b8769d..d5c8942 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,7 +1,7 @@ # Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio GRAFANA_VERSION=8.5.0 -KAFKATORIO_VERSION=0.8.0 +KAFKATORIO_VERSION=0.9.0 KAFKA_DL_URL=https\://dlcdn.apache.org/kafka/3.2.1/kafka_2.13-3.2.1.tgz KAFKA_VERSION=3.2.1 PROMETHEUS_VERSION=v2.34.0 diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index 74562e0..1eb5f42 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.8.0 +KAFKATORIO_VERSION=0.9.0 diff --git a/modules/web-map/docker/.env b/modules/web-map/docker/.env index 74562e0..1eb5f42 100644 --- a/modules/web-map/docker/.env +++ b/modules/web-map/docker/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnvUpdate' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.8.0 +KAFKATORIO_VERSION=0.9.0 From ece583e93ce5f4b1a36b28d161cf08add90ec6a8 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 1 Sep 2022 23:18:47 +0200 Subject: [PATCH 503/629] bump kvision, remove manual npm version settings (I think it's been fixed now) --- .../kafkatorio/lang/kotlin-js.gradle.kts | 42 ++++----- .../lang/kotlin-multiplatform.gradle.kts | 42 ++++----- gradle/kotlin-js-store/yarn.lock | 89 ++++++++++--------- gradle/libs.versions.toml | 2 +- modules/web-map/build.gradle.kts | 7 +- 5 files changed, 94 insertions(+), 88 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts index 36e535b..4ff9e92 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts @@ -1,11 +1,11 @@ package dev.adamko.kafkatorio.lang -import dev.adamko.kafkatorio.Versions +//import dev.adamko.kafkatorio.Versions import dev.adamko.kafkatorio.relocateKotlinJsStore -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin -import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject -import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension +//import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension +//import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin +//import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject +//import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension //import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask @@ -50,21 +50,21 @@ plugins { relocateKotlinJsStore() -plugins.withType { - configure { - nodeVersion = "16.0.0" - } -} +//plugins.withType { +// configure { +// nodeVersion = "16.0.0" +// } +//} -afterEvaluate { - rootProject.extensions.configure { - // https://github.com/rjaros/kvision/issues/410 - versions.webpackCli.version = "4.10.0" - versions.webpackDevServer.version = "4.9.2" - } - - rootProject.extensions.configure { - resolution("http-proxy-middleware", "^2.0.6") - } -} +//afterEvaluate { +// rootProject.extensions.configure { +// // https://github.com/rjaros/kvision/issues/410 +// versions.webpackCli.version = "4.10.0" +// versions.webpackDevServer.version = "4.9.2" +// } +// +// rootProject.extensions.configure { +// resolution("http-proxy-middleware", "^2.0.6") +// } +//} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts index 2638320..46939bc 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts @@ -1,9 +1,9 @@ package dev.adamko.kafkatorio.lang import dev.adamko.kafkatorio.relocateKotlinJsStore -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin -import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension +//import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension +//import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin +//import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension plugins { @@ -17,21 +17,21 @@ plugins { relocateKotlinJsStore() -plugins.withType { - configure { - nodeVersion = "16.0.0" - } -} - - -afterEvaluate { - rootProject.extensions.configure { - // https://github.com/rjaros/kvision/issues/410 - versions.webpackCli.version = "4.10.0" - versions.webpackDevServer.version = "4.9.2" - } - - rootProject.extensions.configure { - resolution("http-proxy-middleware", "^2.0.6") - } -} +//plugins.withType { +// configure { +// nodeVersion = "16.0.0" +// } +//} +// +// +//afterEvaluate { +// rootProject.extensions.configure { +// // https://github.com/rjaros/kvision/issues/410 +// versions.webpackCli.version = "4.10.0" +// versions.webpackDevServer.version = "4.9.2" +// } +// +// rootProject.extensions.configure { +// resolution("http-proxy-middleware", "^2.0.6") +// } +//} diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index de9a0f5..139d7d5 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -19,20 +19,20 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== -"@fortawesome/fontawesome-free@^6.1.1": - version "6.1.1" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.1.1.tgz#bf5d45611ab74890be386712a0e5d998c65ee2a1" - integrity sha512-J/3yg2AIXc9wznaVqpHVX3Wa5jwKovVF0AMYSnbmcXTiL3PpRPfF58pzWucCwEiCJBp+hCNRLWClTomD8SseKg== +"@fortawesome/fontawesome-free@^6.1.2": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.2.0.tgz#ba3510825b332816fe7190f28827f8cb33a298b5" + integrity sha512-CNR7qRIfCwWHNN7FnKUniva94edPdyQzil/zCwk3v6k4R6rR2Fr8i4s3PM7n/lyfPA6Zfko9z5WDzFxG9SW1uQ== "@leichtgewicht/ip-codec@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== -"@popperjs/core@^2.11.4": - version "2.11.5" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64" - integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw== +"@popperjs/core@^2.11.5": + version "2.11.6" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.6.tgz#cee20bd55e68a1720bdab363ecf0c821ded4cd45" + integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw== "@rjaros/gettext.js@^1.1.3": version "1.1.3" @@ -402,11 +402,16 @@ acorn-import-assertions@^1.7.6: resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== -acorn@^8.4.1, acorn@^8.5.0: +acorn@^8.5.0: version "8.7.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== +acorn@^8.7.1: + version "8.8.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" @@ -498,11 +503,6 @@ array-flatten@^2.1.2: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== -awesome-bootstrap-checkbox@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/awesome-bootstrap-checkbox/-/awesome-bootstrap-checkbox-1.0.1.tgz#dab10146b6001129ab0a0ec1e54bb77c6c30457a" - integrity sha1-2rEBRrYAESmrCg7B5Uu3fGwwRXo= - balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -551,15 +551,15 @@ bonjour-service@^1.0.11: fast-deep-equal "^3.1.3" multicast-dns "^7.2.5" -bootstrap-icons@^1.8.3: - version "1.8.3" - resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.8.3.tgz#14c15e26deaddd42af9f88c4d81f7c45bf26aa98" - integrity sha512-s5kmttnbq4BXbx3Bwnj39y+t7Vc3blTtyD77W3aYQ1LlNoS3lNbbGvSYhIbg26Im8KmjScyFpHEevlPOBcIDdA== +bootstrap-icons@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.9.1.tgz#cf22d91a25447645e45c49ebde4e56eafdfe761b" + integrity sha512-d4ZkO30MIkAhQ2nNRJqKXJVEQorALGbLWTuRxyCTJF96lRIV6imcgMehWGJUiJMJhglN0o2tqLIeDnMdiQEE9g== -bootstrap@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.1.3.tgz#ba081b0c130f810fa70900acbc1c6d3c28fa8f34" - integrity sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q== +bootstrap@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.2.0.tgz#838727fb60f1630db370fe57c63cbcf2962bb3d3" + integrity sha512-qlnS9GL6YZE6Wnef46GxGv1UpGGzAwO0aPL1yOjzDIJpeApeMvqV24iL+pjr2kU4dduoBA9fINKWKgMToobx9A== brace-expansion@^1.1.7: version "1.1.11" @@ -649,10 +649,10 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chart.js@^3.8.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.8.0.tgz#c6c14c457b9dc3ce7f1514a59e9b262afd6f1a94" - integrity sha512-cr8xhrXjLIXVLOBZPkBZVF6NDeiVIrPLHcMhnON7UufudL+CNeRrD+wpYanswlm8NpudMdrt3CHoLMQMxJhHRg== +chart.js@^3.9.1: + version "3.9.1" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.9.1.tgz#3abf2c775169c4c71217a107163ac708515924b8" + integrity sha512-Ro2JbLmvg83gXF5F4sniaQ+lTbSv18E+TIf2cOeiH1Iqd2PGFOtem+DUufMZsCJwFE7ywPOpfXFBwRTGq7dh6w== chokidar@3.5.3, chokidar@^3.5.1, chokidar@^3.5.3: version "3.5.3" @@ -1016,10 +1016,10 @@ engine.io@~6.2.0: engine.io-parser "~5.0.3" ws "~8.2.3" -enhanced-resolve@^5.9.3: - version "5.9.3" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz#44a342c012cbc473254af5cc6ae20ebd0aae5d88" - integrity sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow== +enhanced-resolve@^5.10.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" + integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -1795,10 +1795,10 @@ kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -kvision-assets@^5.0.9: - version "5.0.9" - resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-5.0.9.tgz#6f305e4c085a4eab57897f6741c208121e9b035c" - integrity sha512-pMbKmlGbc6FYtJVPbH6oKXWFOp6O6Uljhi6KODs4AGuIiqZxhjXKXwMEhaaLzheuP5/bu0hNYWa4LGSwcvIOJQ== +kvision-assets@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-6.0.0.tgz#de17ec942efd067fc180e7fab4e040c4e41bbe25" + integrity sha512-fjPGTMGiboRnXXwhQFVOsRdDaDFnBfAQBRGhbzjQUp5oJKUnPS303Pua0u5atQdYMXyN/u6fyH6TEHgQzM9Wog== leaflet@^1.8.0: version "1.8.0" @@ -2004,6 +2004,11 @@ nanoid@3.3.3, nanoid@^3.3.1: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== +navigo@^8.11.1: + version "8.11.1" + resolved "https://registry.yarnpkg.com/navigo/-/navigo-8.11.1.tgz#aca756dbca40e2da2ae688a2a247ab4f070fcf4a" + integrity sha512-e3sc1UzakF+bWquC8/dbPCgo7LgPEW1ekgwb4pmEcl8tOc/I7lML8r7HBql+b0VRk7tJWTZqtkeObwJAVR1pxg== + negotiator@0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" @@ -2864,7 +2869,7 @@ void-elements@^2.0.0: resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= -watchpack@^2.3.1: +watchpack@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== @@ -2963,21 +2968,21 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@5.73.0: - version "5.73.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.73.0.tgz#bbd17738f8a53ee5760ea2f59dce7f3431d35d38" - integrity sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA== +webpack@5.74.0: + version "5.74.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" + integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" "@webassemblyjs/ast" "1.11.1" "@webassemblyjs/wasm-edit" "1.11.1" "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.4.1" + acorn "^8.7.1" acorn-import-assertions "^1.7.6" browserslist "^4.14.5" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.9.3" + enhanced-resolve "^5.10.0" es-module-lexer "^0.9.0" eslint-scope "5.1.1" events "^3.2.0" @@ -2990,7 +2995,7 @@ webpack@5.73.0: schema-utils "^3.1.0" tapable "^2.1.1" terser-webpack-plugin "^5.1.3" - watchpack "^2.3.1" + watchpack "^2.4.0" webpack-sources "^3.2.3" websocket-driver@>=0.5.1, websocket-driver@^0.7.4: diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0e5f30b..4489b0e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ kotlin = "1.7.10" camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" kafka = "3.2.1" # https://kafka.apache.org/downloads -kvision = "5.13.1" # https://github.com/rjaros/kvision/releases +kvision = "5.14.0" # https://github.com/rjaros/kvision/releases log4j2 = "2.17.2" okio = "3.2.0" # https://search.maven.org/artifact/com.squareup.okio/okio qosLogback = "1.2.11" diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 3b3d776..0afc693 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -1,3 +1,4 @@ +import dev.adamko.kafkatorio.task.DockerEnvUpdateTask import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig @@ -93,8 +94,8 @@ kotlin { kvision("kvision-state-flow") kvision("kvision-routing-navigo-ng") - implementation(devNpm("http-proxy-middleware", "^2.0.6")) - implementation(dependencies.platform(devNpm("http-proxy-middleware", "^2.0.6"))) +// implementation(devNpm("http-proxy-middleware", "^2.0.6")) +// implementation(dependencies.platform(devNpm("http-proxy-middleware", "^2.0.6"))) // implementation(dependencies.platform(npm("follow-redirects", "^1.14.8"))) // implementation(dependencies.platform(npm("nanoid", "^3.1.31"))) @@ -148,7 +149,7 @@ fun KotlinDependencyHandler.kvision( //} -val dockerEnvUpdate by tasks.registering(dev.adamko.kafkatorio.task.DockerEnvUpdateTask::class) { +val dockerEnvUpdate by tasks.registering(DockerEnvUpdateTask::class) { dotEnvFile.set(layout.projectDirectory.file("docker/.env")) properties( From 60d61752b3ec12f209dc396d656f2cdc6f88a1e9 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 1 Sep 2022 23:19:06 +0200 Subject: [PATCH 504/629] update mod generated code (remove unused var) --- .../src/generated/lua/main/events/prototypeUpdates.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua index d856e92..e066b9f 100644 --- a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua @@ -47,7 +47,6 @@ function getEntityPrototypes() tileWidth = entity.tile_width, tileHeight = entity.tile_height } - local ____ = entity.infinite_resource if entity.map_color ~= nil then entityProto.mapColour = Converters.mapColour(entity.map_color) end From 8a6c49a74bb5500e99a8d5002cb960b67eeeb93e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 1 Sep 2022 23:19:59 +0200 Subject: [PATCH 505/629] initial hacky implementation of multi-server support in the frontend --- .../dev/adamko/kafkatorio/webmap/App.kt | 104 ++++++----- .../{ => config}/ApplicationProperties.kt | 0 .../kafkatorio/webmap/{ => config}/json.kt | 2 +- .../kafkatorio/webmap/layout/headerNav.kt | 16 ++ .../kafkatorio/webmap/layout/homePage.kt | 30 ++++ .../kafkatorio/webmap/layout/serverPage.kt | 26 +++ .../dev/adamko/kafkatorio/webmap/map.kt | 21 ++- .../dev/adamko/kafkatorio/webmap/routing.kt | 161 ++++++++++++++++++ .../webmap/services/EventsServerClient.kt | 25 +++ .../WebsocketService.kt} | 18 +- .../webmap/{ => services}/converters.kt | 2 +- .../webmap/state/PlayerProperties.kt | 82 +++++++++ .../kafkatorio/webmap/state/playerState.kt | 82 +-------- .../adamko/kafkatorio/webmap/state/state.kt | 44 ++--- 14 files changed, 452 insertions(+), 161 deletions(-) rename modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/{ => config}/ApplicationProperties.kt (100%) rename modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/{ => config}/json.kt (82%) create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/headerNav.kt create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/homePage.kt create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/serverPage.kt create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing.kt create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/EventsServerClient.kt rename modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/{websockets.kt => services/WebsocketService.kt} (84%) rename modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/{ => services}/converters.kt (87%) create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/PlayerProperties.kt diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index aab0664..f21d8ad 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -1,9 +1,10 @@ package dev.adamko.kafkatorio.webmap import dev.adamko.kafkatorio.schema.packets.EventServerPacket -import dev.adamko.kafkatorio.webmap.state.FactorioGameState -import dev.adamko.kafkatorio.webmap.state.FactorioUpdate -import dev.adamko.kafkatorio.webmap.state.createFactorioReduxStore +import dev.adamko.kafkatorio.webmap.layout.headerNav +import dev.adamko.kafkatorio.webmap.layout.homePage +import dev.adamko.kafkatorio.webmap.layout.serverPage +import dev.adamko.kafkatorio.webmap.services.WebsocketService import io.kvision.Application import io.kvision.BootstrapCssModule import io.kvision.BootstrapIconsModule @@ -12,17 +13,21 @@ import io.kvision.ChartModule import io.kvision.CoreModule import io.kvision.FontAwesomeModule import io.kvision.html.div -import io.kvision.maps.Maps -import io.kvision.maps.externals.leaflet.layer.tile.GridLayer +import io.kvision.html.header +import io.kvision.html.main import io.kvision.module import io.kvision.panel.root import io.kvision.redux.ReduxStore +import io.kvision.redux.createReduxStore import io.kvision.require +import io.kvision.routing.Routing import io.kvision.startApplication -import kotlin.coroutines.CoroutineContext +import io.kvision.state.bind import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.flow.filterIsInstance @@ -33,54 +38,78 @@ import kotlinx.coroutines.flow.onEach val rootJob = Job() -class App( - reduxStore: ReduxStore, - wsService: WebsocketService, -) : Application(), CoroutineScope { +class App : Application() { - override val coroutineContext: CoroutineContext = CoroutineName("WebMapApp") + private val coroutineScope: CoroutineScope = CoroutineScope( + Dispatchers.Default + + SupervisorJob(rootJob) + + CoroutineName("WebMapApp") + ) private var appState: MutableMap = mutableMapOf() - var reduxStore: ReduxStore by appState - var wsService: WebsocketService by appState + var reduxStore: ReduxStore by appState + private set +// var wsService: WebsocketService by appState +// private set init { - this.reduxStore = reduxStore - this.wsService = wsService + this.reduxStore = createReduxStore(SiteState::plus, SiteState()) +// this.wsService = wsService require("./css/kafkatorio.css") } - private val gameState: FactorioGameState - get() = reduxStore.getState() - - private val kvMaps: Maps - get() = gameState.map.kvMap +// private val gameState: FactorioGameState +// get() = reduxStore.getState() +// private val kvMaps: Maps +// get() = gameState.map.kvMap override fun start(state: Map) { + Routing.init(useHash = false) + this.appState = state.toMutableMap() + val siteRouting = SiteRouting(reduxStore) + val websocketService = WebsocketService(reduxStore) + + siteRouting.init() + root("kvapp") { + + header().bind(siteRouting.siteStateStore) { state -> + headerNav(state) + } + div("Kafkatorio Web Map") - add(kvMaps) - } - kvMaps.leafletMap { - invalidateSize(true) - eachLayer({ - if (it is GridLayer<*>) { - it.redraw() + main().bind(siteRouting.siteStateStore) { state -> + when (state.view) { + SiteView.HOME -> homePage(state) + SiteView.SERVER -> serverPage(state) } - }) + } + +// div("Kafkatorio Web Map") +// add(kvMaps) } - wsService.packetsFlow +// kvMaps.leafletMap { +// invalidateSize(true) +// eachLayer({ +// if (it is GridLayer<*>) { +// it.redraw() +// } +// }) +// } + + websocketService.packetsFlow .filterIsInstance() .onEach { tileSavedEvent -> // println("[packetsFlow] triggering tile refresh ${tileSavedEvent.filename.value}") - gameState.map.refreshUpdatedTilePng(tileSavedEvent.filename) - }.launchIn(this) + reduxStore.dispatch(SiteAction.EventServerUpdate(tileSavedEvent)) +// reduxStore.map.refreshUpdatedTilePng(tileSavedEvent.filename) + }.launchIn(coroutineScope) } @@ -96,14 +125,13 @@ class App( fun main() { startApplication( { - val reduxStore = createFactorioReduxStore() - val wsService = WebsocketService( -// "ws://localhost:9073/ws", // TODO load from config - reduxStore = reduxStore, - ) +// val reduxStore = createFactorioReduxStore() +// val wsService = WebsocketService( +// reduxStore = reduxStore, +// ) App( - reduxStore = reduxStore, - wsService = wsService, +// reduxStore = reduxStore, +// wsService = wsService, ) }, module.hot, diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/ApplicationProperties.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/config/ApplicationProperties.kt similarity index 100% rename from modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/ApplicationProperties.kt rename to modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/config/ApplicationProperties.kt diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/config/json.kt similarity index 82% rename from modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt rename to modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/config/json.kt index 3dd2fba..1b9be5b 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/config/json.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.webmap +package dev.adamko.kafkatorio.webmap.config import dev.adamko.kafkatorio.library.jsonMapperKafkatorio import kotlinx.serialization.json.Json diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/headerNav.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/headerNav.kt new file mode 100644 index 0000000..6ce1bc1 --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/headerNav.kt @@ -0,0 +1,16 @@ +package dev.adamko.kafkatorio.webmap.layout + +import dev.adamko.kafkatorio.webmap.SiteState +import dev.adamko.kafkatorio.webmap.SiteView +import io.kvision.core.Container +import io.kvision.html.div +import io.kvision.html.link +import io.kvision.html.nav + +fun Container.headerNav(state: SiteState) { + nav(className = "navbar") { + div(className = "container") { + link("home", "#${SiteView.HOME.pathMatcher}") + } + } +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/homePage.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/homePage.kt new file mode 100644 index 0000000..a2fd4b8 --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/homePage.kt @@ -0,0 +1,30 @@ +package dev.adamko.kafkatorio.webmap.layout + +import dev.adamko.kafkatorio.webmap.SiteState +import io.kvision.core.Container +import io.kvision.html.div +import io.kvision.html.h5 +import io.kvision.html.link + + +fun Container.homePage(state: SiteState) { + div(className = "home-page") { + servers(state) + } +} + + +private fun Container.servers(state: SiteState) { + div(className = "servers") { + h5("Servers") + if (state.serverIds != null) { + state.serverIds.forEach { serverId -> + div { + link("server", "/servers/$serverId") + } + } + } else { + div("no servers available") + } + } +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/serverPage.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/serverPage.kt new file mode 100644 index 0000000..2c41863 --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/serverPage.kt @@ -0,0 +1,26 @@ +package dev.adamko.kafkatorio.webmap.layout + +import dev.adamko.kafkatorio.webmap.SiteState +import io.kvision.core.Container +import io.kvision.html.div +import io.kvision.maps.externals.leaflet.layer.tile.GridLayer + + +fun Container.serverPage(state: SiteState) { + val factorioGameState = state.factorioGameState + div(className = "server-page") { + if (factorioGameState != null) { + + add(factorioGameState.map.kvMap) + + factorioGameState.map.kvMap.leafletMap { + invalidateSize(true) + eachLayer({ + if (it is GridLayer<*>) { + it.redraw() + } + }) + } + } + } +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index adc7782..621f7ac 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.webmap +import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer import dev.adamko.kafkatorio.schema.common.ServerMapTilePngFilename import dev.adamko.kafkatorio.webmap.externals.TileOnLoadFn @@ -31,7 +32,9 @@ import org.w3c.fetch.RequestInit import org.w3c.fetch.RequestMode -class FactorioMap { +class FactorioMap( + private val serverId: FactorioServerId, +) { val kvMap: Maps = Maps { width = 800.px @@ -155,16 +158,18 @@ class FactorioMap { return baseTileLayer } + private fun tileLayerUrlTemplate(layer: ServerMapTileLayer): String { + return "/kafkatorio/data/servers/${serverId.id}/map/layers/${layer.dir}/s1/z{z}/x{x}/y{y}.png" + } + companion object { const val DYNAMIC_RELOAD_ATT = "dynamic-reload" - private val serverName: String - get() = window.location.pathname - .substringAfter("kafkatorio/data/servers/") - .substringBefore("/") +// private val serverName: String? +// get() = window.location.pathname +// .substringAfter("servers") +// .substringBefore("/") +// .ifBlank { null } - private fun tileLayerUrlTemplate(layer: ServerMapTileLayer): String { - return "/kafkatorio/data/servers/$serverName/map/layers/${layer.dir}/s1/z{z}/x{x}/y{y}.png" - } } } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing.kt new file mode 100644 index 0000000..f1e7043 --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing.kt @@ -0,0 +1,161 @@ +package dev.adamko.kafkatorio.webmap + +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.common.Tick +import dev.adamko.kafkatorio.schema.packets.EventServerPacket +import dev.adamko.kafkatorio.schema.packets.PlayerUpdate +import dev.adamko.kafkatorio.webmap.services.EventsServerClient +import dev.adamko.kafkatorio.webmap.state.FactorioGameState +import io.kvision.navigo.Match +import io.kvision.navigo.Navigo +import io.kvision.redux.RAction +import io.kvision.redux.ReduxStore +import io.kvision.routing.routing +import kotlin.js.RegExp +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.launch + + +class SiteRouting( + val siteStateStore: ReduxStore +) : CoroutineScope by CoroutineScope(Dispatchers.Default + SupervisorJob()) { + + fun init() { + routing + .on(SiteView.HOME) { homepageView() } + .on(SiteView.SERVER) { match -> + serverView(match) + } + .resolve() + } + + private fun homepageView() { + siteStateStore.dispatch(SiteAction.HomePage) + launch { + val serverIds = EventsServerClient.serverIds() + siteStateStore.dispatch(SiteAction.ServerIdsLoaded(serverIds)) + } + } + + private fun serverView(match: Match) { + val serverId = match.data[0] as? String ?: error("invalid server id") + siteStateStore.dispatch(SiteAction.ServerPage(FactorioServerId(serverId))) + } +} + + +data class SiteState( + val view: SiteView = SiteView.HOME, + + val serverIds: List? = null, + + val factorioGameState: FactorioGameState? = null, +) { + + operator fun plus(action: SiteAction): SiteState = when (action) { + is SiteAction.HomePage -> copy(view = SiteView.HOME) + + is SiteAction.ServerPage -> copy( + view = SiteView.SERVER, + factorioGameState = FactorioGameState(action.serverId), + ) + + is SiteAction.ServerIdsLoaded -> copy(serverIds = action.serverIds) + + is SiteAction.FactorioUpdate -> copy( + factorioGameState = factorioGameState?.let { it + action } + ) + + is SiteAction.EventServerUpdate -> copy( + + ) + } +} + + +sealed interface SiteAction : RAction { + object HomePage : SiteAction + data class ServerPage(val serverId: FactorioServerId) : SiteAction + + + data class ServerIdsLoaded(val serverIds: List) : SiteAction + + + /** Updates from `events-server` */ + sealed class FactorioUpdate : SiteAction { + data class Player(val tick: Tick, val data: PlayerUpdate) : FactorioUpdate() + } + + data class EventServerUpdate(val packet: EventServerPacket) : SiteAction +} + + +sealed interface SiteView { + val pathMatcher: Any + + sealed interface StaticPath : SiteView { + override val pathMatcher: String + } + + sealed interface DynamicPath : SiteView { + override val pathMatcher: RegExp + } + + + object HOME : StaticPath { + override val pathMatcher: String = "/" + } + + object SERVER : DynamicPath { + override val pathMatcher: RegExp = RegExp("^servers/${FactorioServerId.validIdRegex}") + } +} + +//val SiteView.urlMatcher: String +// get() = when (this) { +// SiteView.HOME -> "/" +// SiteView.SERVER -> "servers/${FactorioServerId.validIdRegex}" +// } + +private fun Navigo.on(view: SiteView, handler: (Match) -> Unit): Navigo { + return when (view) { + is SiteView.StaticPath -> on(view.pathMatcher, { match: Match -> handler(match) }) + is SiteView.DynamicPath -> on(view.pathMatcher, { match: Match -> handler(match) }) + } +} + +//private fun Navigo.on( +// view: SiteView, +// before: BeforeHook? = null, +// after: AfterHook? = null, +// leave: LeaveHook? = null, +// already: AlreadyHook? = null, +// handler: (Match) -> Unit, +//): Navigo { +// +// val hooks: RouteHooks? = +// if (before != null || after != null || leave != null || already != null) { +// jso { +// if (before != null) this@jso.before = before +// if (after != null) this@jso.after = after +// if (leave != null) this@jso.leave = leave +// if (already != null) this@jso.already = already +// } +// } else { +// null +// } +// +// return when (view) { +// is SiteView.StaticPath -> when (hooks) { +// null -> on(view.pathMatcher, { match: Match -> handler(match) }) +// else -> on(view.pathMatcher, { match: Match -> handler(match) }, hooks) +// } +// +// is SiteView.DynamicPath -> when (hooks) { +// null -> on(view.pathMatcher, { match: Match -> handler(match) }) +// else -> on(view.pathMatcher, { match: Match -> handler(match) }, hooks) +// } +// } +//} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/EventsServerClient.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/EventsServerClient.kt new file mode 100644 index 0000000..bc61491 --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/EventsServerClient.kt @@ -0,0 +1,25 @@ +package dev.adamko.kafkatorio.webmap.services + +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import io.kvision.rest.RestClient +import io.kvision.rest.call +import kotlinx.browser.window +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.await + +object EventsServerClient : + CoroutineScope by CoroutineScope(Dispatchers.Default + SupervisorJob()) { + + private val restClient = RestClient() + + + /** Fetch all possible server IDs. */ + suspend fun serverIds(): List = + restClient + .call>(window.location.origin + "/kafkatorio/data/servers") + .await() + + +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/WebsocketService.kt similarity index 84% rename from modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt rename to modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/WebsocketService.kt index b48f91f..a111a6c 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/WebsocketService.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.webmap +package dev.adamko.kafkatorio.webmap.services import dev.adamko.kafkatorio.schema.packets.ConfigurationUpdate import dev.adamko.kafkatorio.schema.packets.ConsoleChatUpdate @@ -12,8 +12,11 @@ import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate -import dev.adamko.kafkatorio.webmap.state.FactorioGameState -import dev.adamko.kafkatorio.webmap.state.FactorioUpdate +import dev.adamko.kafkatorio.webmap.SiteAction +import dev.adamko.kafkatorio.webmap.SiteState +import dev.adamko.kafkatorio.webmap.config.ApplicationProperties +import dev.adamko.kafkatorio.webmap.config.jsonMapper +import dev.adamko.kafkatorio.webmap.rootJob import io.kvision.redux.ReduxStore import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineName @@ -29,14 +32,13 @@ import org.w3c.dom.events.Event class WebsocketService( - wsUrl: String = Props.websocketServerUrl, - private val reduxStore: ReduxStore, + private val siteStateStore: ReduxStore ) : CoroutineScope { override val coroutineContext: CoroutineContext = CoroutineName("WebsocketService") + Job(rootJob) - private val ws = WebSocket(wsUrl) + private val ws = WebSocket(ApplicationProperties.websocketServerUrl) // private val ws = WebSocket("ws://localhost:12080/ws/foo") private val _packetsFlow = MutableSharedFlow() @@ -78,7 +80,9 @@ class WebsocketService( is EventServerPacket.Kafkatorio -> when (val packetData = packet.packet.data) { is PlayerUpdate -> - reduxStore.dispatch(FactorioUpdate.Player(packet.packet.tick, packetData)) + siteStateStore.dispatch( + SiteAction.FactorioUpdate.Player(packet.packet.tick, packetData) + ) is ConfigurationUpdate, is ConsoleChatUpdate, diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/converters.kt similarity index 87% rename from modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt rename to modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/converters.kt index b47e73b..9b4753a 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/converters.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/converters.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.webmap +package dev.adamko.kafkatorio.webmap.services import dev.adamko.kafkatorio.schema.common.MapEntityPosition import dev.adamko.kafkatorio.schema.packets.PlayerUpdate diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/PlayerProperties.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/PlayerProperties.kt new file mode 100644 index 0000000..94e25d2 --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/PlayerProperties.kt @@ -0,0 +1,82 @@ +package dev.adamko.kafkatorio.webmap.state + + +import dev.adamko.kafkatorio.schema.common.Colour +import dev.adamko.kafkatorio.schema.common.MapEntityPosition +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.common.toHexString +import dev.adamko.kafkatorio.schema.packets.PlayerUpdate +import dev.adamko.kafkatorio.webmap.services.latLng +import io.kvision.maps.externals.leaflet.geo.LatLng + +sealed interface PlayerProperties { + + val position: MapEntityPosition? + val surfaceIndex: SurfaceIndex? + val colour: Colour? + val name: String? + val latLng: LatLng? + val isConnected: Boolean + val isShowOnMap: Boolean + + + data class Partial( + override val position: MapEntityPosition? = null, + override val surfaceIndex: SurfaceIndex? = null, + override val colour: Colour? = null, + override val name: String? = null, + override val isConnected: Boolean = false, + override val isShowOnMap: Boolean = false, + ) : PlayerProperties { + override val latLng: LatLng? = null + } + + + data class Complete( + override val position: MapEntityPosition, + override val surfaceIndex: SurfaceIndex, + override val colour: Colour, + override val name: String, + override val isConnected: Boolean = false, + override val isShowOnMap: Boolean = false, + ) : PlayerProperties { + override val latLng: LatLng = position.latLng() + val hexColour: String = colour.toHexString(false) + } + + + fun update(update: PlayerUpdate): PlayerProperties { + + val position = update.position ?: this.position + val surfaceIndex = update.surfaceIndex ?: this.surfaceIndex + val colour = update.colour ?: this.colour + val name = update.name ?: this.name + val isConnected = update.isConnected + val isShowOnMap = update.isShowOnMap + + return when { + position != null + && surfaceIndex != null + && colour != null + && name != null -> + Complete( + position = position, + surfaceIndex = surfaceIndex, + colour = colour, + name = name, + isConnected = isConnected, + isShowOnMap = isShowOnMap, + ) + + else -> + Partial( + position = position, + surfaceIndex = surfaceIndex, + colour = colour, + name = name, + isConnected = isConnected, + isShowOnMap = isShowOnMap, + ) + } + } +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt index c659521..f627ffb 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt @@ -1,22 +1,17 @@ package dev.adamko.kafkatorio.webmap.state -import dev.adamko.kafkatorio.schema.common.Colour -import dev.adamko.kafkatorio.schema.common.MapEntityPosition import dev.adamko.kafkatorio.schema.common.PlayerIndex -import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.Tick -import dev.adamko.kafkatorio.schema.common.toHexString import dev.adamko.kafkatorio.schema.packets.PlayerUpdate -import dev.adamko.kafkatorio.webmap.latLng +import dev.adamko.kafkatorio.webmap.SiteAction import io.kvision.maps.Maps -import io.kvision.maps.externals.leaflet.geo.LatLng import io.kvision.maps.externals.leaflet.layer.vector.CircleMarker import kotlinx.js.jso fun handlePlayerUpdate( gameState: FactorioGameState, - update: FactorioUpdate.Player, + update: SiteAction.FactorioUpdate.Player, ): FactorioGameState { val previous = gameState.players[update.data.key.index] @@ -105,76 +100,3 @@ data class PlayerState( } } } - - -sealed interface PlayerProperties { - - val position: MapEntityPosition? - val surfaceIndex: SurfaceIndex? - val colour: Colour? - val name: String? - val latLng: LatLng? - val isConnected: Boolean - val isShowOnMap: Boolean - - - data class Partial( - override val position: MapEntityPosition? = null, - override val surfaceIndex: SurfaceIndex? = null, - override val colour: Colour? = null, - override val name: String? = null, - override val isConnected: Boolean = false, - override val isShowOnMap: Boolean = false, - ) : PlayerProperties { - override val latLng: LatLng? = null - } - - - data class Complete( - override val position: MapEntityPosition, - override val surfaceIndex: SurfaceIndex, - override val colour: Colour, - override val name: String, - override val isConnected: Boolean = false, - override val isShowOnMap: Boolean = false, - ) : PlayerProperties { - override val latLng: LatLng = position.latLng() - val hexColour: String = colour.toHexString(false) - } - - - fun update(update: PlayerUpdate): PlayerProperties { - - val position = update.position ?: this.position - val surfaceIndex = update.surfaceIndex ?: this.surfaceIndex - val colour = update.colour ?: this.colour - val name = update.name ?: this.name - val isConnected = update.isConnected - val isShowOnMap = update.isShowOnMap - - return when { - position != null - && surfaceIndex != null - && colour != null - && name != null -> - Complete( - position = position, - surfaceIndex = surfaceIndex, - colour = colour, - name = name, - isConnected = isConnected, - isShowOnMap = isShowOnMap, - ) - - else -> - Partial( - position = position, - surfaceIndex = surfaceIndex, - colour = colour, - name = name, - isConnected = isConnected, - isShowOnMap = isShowOnMap, - ) - } - } -} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt index 1e71ba4..69d0f6b 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt @@ -1,41 +1,33 @@ package dev.adamko.kafkatorio.webmap.state +import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.PlayerIndex -import dev.adamko.kafkatorio.schema.common.Tick -import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.webmap.FactorioMap +import dev.adamko.kafkatorio.webmap.SiteAction import io.kvision.maps.externals.leaflet.layer.LayerGroup -import io.kvision.redux.ReduxStore -import io.kvision.redux.createReduxStore -import redux.RAction -fun createFactorioReduxStore(): ReduxStore = - createReduxStore( - ::factorioGameReducer, - FactorioGameState( - map = FactorioMap(), - players = emptyMap(), - ) - ) +//fun createFactorioReduxStore(): ReduxStore = +// createReduxStore( +// ::factorioGameReducer, +// FactorioGameState( +// map = FactorioMap(), +// players = emptyMap(), +// ) +// ) data class FactorioGameState( - val map: FactorioMap, - val players: Map, + val serverId: FactorioServerId, + val map: FactorioMap = FactorioMap(serverId), + val players: Map = emptyMap(), ) { val playerIconsLayer: LayerGroup get() = map.playerIconsLayer + + operator fun plus(action: SiteAction.FactorioUpdate): FactorioGameState = + when (action) { + is SiteAction.FactorioUpdate.Player -> handlePlayerUpdate(this, action) + } } - - -sealed class FactorioUpdate : RAction { - data class Player(val tick: Tick, val data: PlayerUpdate) : FactorioUpdate() -} - - -fun factorioGameReducer(gameState: FactorioGameState, update: FactorioUpdate): FactorioGameState = - when (update) { - is FactorioUpdate.Player -> handlePlayerUpdate(gameState, update) - } From 3976c3cc1b12af7865fa1bab88ddd18de12f1c01 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 2 Sep 2022 23:22:18 +0200 Subject: [PATCH 506/629] fix webmap after multi-server refactor, and add styling --- gradle/kotlin-js-store/yarn.lock | 2 +- modules/web-map/build.gradle.kts | 15 + .../dev/adamko/kafkatorio/webmap/App.kt | 54 +- .../webmap/config/ApplicationProperties.kt | 9 +- .../kafkatorio/webmap/layout/headerNav.kt | 2 +- .../kafkatorio/webmap/layout/homePage.kt | 35 +- .../webmap/layout/{ => servers}/serverPage.kt | 24 +- .../dev/adamko/kafkatorio/webmap/map.kt | 13 +- .../dev/adamko/kafkatorio/webmap/routing.kt | 61 +- .../webmap/services/WebsocketService.kt | 9 +- .../src/main/resources/css/bootstrap.min.css | 12303 ++++++++++++++++ .../src/main/resources/css/kafkatorio.css | 16 +- .../main/resources/img/kafkatorio-logo.png | Bin 0 -> 52828 bytes modules/web-map/src/main/web/index.html | 14 +- 14 files changed, 12461 insertions(+), 96 deletions(-) rename modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/{ => servers}/serverPage.kt (51%) create mode 100644 modules/web-map/src/main/resources/css/bootstrap.min.css create mode 100644 modules/web-map/src/main/resources/img/kafkatorio-logo.png diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index 139d7d5..8c608d6 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -1490,7 +1490,7 @@ http-parser-js@>=0.5.1: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== -"http-proxy-middleware@>=2.0.6 <3.0.0", http-proxy-middleware@^2.0.3, http-proxy-middleware@^2.0.6: +http-proxy-middleware@^2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 0afc693..347a840 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -158,3 +158,18 @@ val dockerEnvUpdate by tasks.registering(DockerEnvUpdateTask::class) { ) } tasks.assemble { dependsOn(dockerEnvUpdate) } + + +val installThemeCss by tasks.registering(Copy::class) { +// val bootswatchThemeCss = resources.text.fromUri("https://bootswatch.com/5/darkly/bootstrap.css") + val bootswatchThemeMinCss = + resources.text.fromUri("https://bootswatch.com/5/darkly/bootstrap.min.css") + from(bootswatchThemeMinCss) { + rename { "bootstrap.min.css" } + } + into(layout.projectDirectory.dir("src/main/resources/css")) +} + +tasks.assemble { + dependsOn(installThemeCss) +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index f21d8ad..35b0729 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -3,16 +3,16 @@ package dev.adamko.kafkatorio.webmap import dev.adamko.kafkatorio.schema.packets.EventServerPacket import dev.adamko.kafkatorio.webmap.layout.headerNav import dev.adamko.kafkatorio.webmap.layout.homePage -import dev.adamko.kafkatorio.webmap.layout.serverPage +import dev.adamko.kafkatorio.webmap.layout.servers.serverPage import dev.adamko.kafkatorio.webmap.services.WebsocketService import io.kvision.Application -import io.kvision.BootstrapCssModule import io.kvision.BootstrapIconsModule import io.kvision.BootstrapModule import io.kvision.ChartModule import io.kvision.CoreModule import io.kvision.FontAwesomeModule import io.kvision.html.div +import io.kvision.html.h3 import io.kvision.html.header import io.kvision.html.main import io.kvision.module @@ -38,7 +38,7 @@ import kotlinx.coroutines.flow.onEach val rootJob = Job() -class App : Application() { +object App : Application() { private val coroutineScope: CoroutineScope = CoroutineScope( Dispatchers.Default @@ -48,15 +48,23 @@ class App : Application() { private var appState: MutableMap = mutableMapOf() - var reduxStore: ReduxStore by appState + var siteStateStore: ReduxStore by appState private set // var wsService: WebsocketService by appState // private set init { - this.reduxStore = createReduxStore(SiteState::plus, SiteState()) + this.siteStateStore = createReduxStore(SiteState::plus, SiteState()) // this.wsService = wsService require("./css/kafkatorio.css") + + WebsocketService.packetsFlow + .filterIsInstance() + .onEach { tileSavedEvent -> +// println("[packetsFlow] triggering tile refresh ${tileSavedEvent.filename.value}") + siteStateStore.dispatch(SiteAction.EventServerUpdate(tileSavedEvent)) +// reduxStore.map.refreshUpdatedTilePng(tileSavedEvent.filename) + }.launchIn(coroutineScope) } // private val gameState: FactorioGameState @@ -70,23 +78,25 @@ class App : Application() { this.appState = state.toMutableMap() - val siteRouting = SiteRouting(reduxStore) - val websocketService = WebsocketService(reduxStore) +// val siteRouting = SiteRouting(reduxStore) +// val websocketService = WebsocketService(siteStateStore) - siteRouting.init() + SiteRouting.init() root("kvapp") { - header().bind(siteRouting.siteStateStore) { state -> + header().bind(siteStateStore) { state -> headerNav(state) } - div("Kafkatorio Web Map") + h3("Kafkatorio Web Map") - main().bind(siteRouting.siteStateStore) { state -> - when (state.view) { - SiteView.HOME -> homePage(state) - SiteView.SERVER -> serverPage(state) + main().bind(siteStateStore) { state -> + div(className = "container-fluid") { + when (state.view) { + SiteView.HOME -> homePage(state) + SiteView.SERVER -> serverPage(state) + } } } @@ -103,14 +113,6 @@ class App : Application() { // }) // } - websocketService.packetsFlow - .filterIsInstance() - .onEach { tileSavedEvent -> -// println("[packetsFlow] triggering tile refresh ${tileSavedEvent.filename.value}") - reduxStore.dispatch(SiteAction.EventServerUpdate(tileSavedEvent)) -// reduxStore.map.refreshUpdatedTilePng(tileSavedEvent.filename) - }.launchIn(coroutineScope) - } override fun dispose(): Map { @@ -129,14 +131,16 @@ fun main() { // val wsService = WebsocketService( // reduxStore = reduxStore, // ) - App( +// App( // reduxStore = reduxStore, // wsService = wsService, - ) +// ) + + App }, module.hot, BootstrapModule, - BootstrapCssModule, +// BootstrapCssModule, BootstrapIconsModule, FontAwesomeModule, ChartModule, diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/config/ApplicationProperties.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/config/ApplicationProperties.kt index 50fcd59..02485cb 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/config/ApplicationProperties.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/config/ApplicationProperties.kt @@ -1,12 +1,13 @@ -package dev.adamko.kafkatorio.webmap +package dev.adamko.kafkatorio.webmap.config import kotlinx.browser.window -object Props { + +object ApplicationProperties { @Suppress("HttpUrlsUsage") val websocketServerUrl: String - get() = window.location.href + get() = window.location.origin .replace("http://", "ws://") .replace("https://", "wss://") + - "kafkatorio/ws" + "/kafkatorio/ws" } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/headerNav.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/headerNav.kt index 6ce1bc1..5cf782f 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/headerNav.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/headerNav.kt @@ -10,7 +10,7 @@ import io.kvision.html.nav fun Container.headerNav(state: SiteState) { nav(className = "navbar") { div(className = "container") { - link("home", "#${SiteView.HOME.pathMatcher}") + link("home", SiteView.HOME.path) } } } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/homePage.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/homePage.kt index a2fd4b8..2356aa2 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/homePage.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/homePage.kt @@ -1,10 +1,14 @@ package dev.adamko.kafkatorio.webmap.layout +import dev.adamko.kafkatorio.webmap.SiteRouting import dev.adamko.kafkatorio.webmap.SiteState import io.kvision.core.Container +import io.kvision.html.ButtonSize +import io.kvision.html.ButtonStyle +import io.kvision.html.button import io.kvision.html.div import io.kvision.html.h5 -import io.kvision.html.link +import io.kvision.html.span fun Container.homePage(state: SiteState) { @@ -18,9 +22,32 @@ private fun Container.servers(state: SiteState) { div(className = "servers") { h5("Servers") if (state.serverIds != null) { - state.serverIds.forEach { serverId -> - div { - link("server", "/servers/$serverId") + div { + span("Available servers: ${state.serverIds.size}") + } + + div { + state.serverIds.forEach { serverId -> +// div { +// link( +// label = "$serverId", +// dataNavigo = true, +// url = "/servers/$serverId", +// ) { +//// onClick { +//// SiteRouting.serverView(serverId) +//// } +// } +// } + + button(text = "$serverId") { + style = ButtonStyle.PRIMARY + size = ButtonSize.SMALL + + onClick { + SiteRouting.serverView(serverId) + } + } } } } else { diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/serverPage.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/servers/serverPage.kt similarity index 51% rename from modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/serverPage.kt rename to modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/servers/serverPage.kt index 2c41863..7d8d2b3 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/serverPage.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/servers/serverPage.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.webmap.layout +package dev.adamko.kafkatorio.webmap.layout.servers import dev.adamko.kafkatorio.webmap.SiteState import io.kvision.core.Container @@ -8,19 +8,23 @@ import io.kvision.maps.externals.leaflet.layer.tile.GridLayer fun Container.serverPage(state: SiteState) { val factorioGameState = state.factorioGameState + div(className = "server-page") { if (factorioGameState != null) { add(factorioGameState.map.kvMap) - - factorioGameState.map.kvMap.leafletMap { - invalidateSize(true) - eachLayer({ - if (it is GridLayer<*>) { - it.redraw() - } - }) - } } } + + +// TODO figure out how to run this after adding kvMap to the container... +// (doing it now causes an NPE because kvMap isn't added to the DOM yet +// factorioGameState?.map?.kvMap?.leafletMap { +// invalidateSize(true) +// eachLayer({ +// if (it is GridLayer<*>) { +// it.redraw() +// } +// }) +// } } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index 621f7ac..cc661b4 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -37,8 +37,10 @@ class FactorioMap( ) { val kvMap: Maps = Maps { - width = 800.px - height = 800.px + minHeight = 800.px + minWidth = 800.px +// width = 100.vh +// height = 100.vh margin = 10.px } @@ -164,12 +166,5 @@ class FactorioMap( companion object { const val DYNAMIC_RELOAD_ATT = "dynamic-reload" - -// private val serverName: String? -// get() = window.location.pathname -// .substringAfter("servers") -// .substringBefore("/") -// .ifBlank { null } - } } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing.kt index f1e7043..88a4759 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing.kt @@ -9,40 +9,44 @@ import dev.adamko.kafkatorio.webmap.state.FactorioGameState import io.kvision.navigo.Match import io.kvision.navigo.Navigo import io.kvision.redux.RAction -import io.kvision.redux.ReduxStore import io.kvision.routing.routing +import kotlin.coroutines.CoroutineContext import kotlin.js.RegExp +import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch -class SiteRouting( - val siteStateStore: ReduxStore -) : CoroutineScope by CoroutineScope(Dispatchers.Default + SupervisorJob()) { +object SiteRouting : CoroutineScope { + + override val coroutineContext: CoroutineContext = + Dispatchers.Default + SupervisorJob(rootJob) + CoroutineName("SiteRouting") + fun init() { routing .on(SiteView.HOME) { homepageView() } .on(SiteView.SERVER) { match -> - serverView(match) + val serverId = match.data[0] as? String ?: error("invalid server id") + serverView(FactorioServerId(serverId)) } .resolve() } - private fun homepageView() { - siteStateStore.dispatch(SiteAction.HomePage) + fun homepageView() { + App.siteStateStore.dispatch(SiteAction.HomePage) launch { val serverIds = EventsServerClient.serverIds() - siteStateStore.dispatch(SiteAction.ServerIdsLoaded(serverIds)) + App.siteStateStore.dispatch(SiteAction.ServerIdsLoaded(serverIds)) } } - private fun serverView(match: Match) { - val serverId = match.data[0] as? String ?: error("invalid server id") - siteStateStore.dispatch(SiteAction.ServerPage(FactorioServerId(serverId))) + fun serverView(serverId: FactorioServerId) { + App.siteStateStore.dispatch(SiteAction.ServerPage(serverId)) } + } @@ -52,7 +56,10 @@ data class SiteState( val serverIds: List? = null, val factorioGameState: FactorioGameState? = null, -) { +) : CoroutineScope { + + override val coroutineContext: CoroutineContext = + Dispatchers.Default + SupervisorJob(rootJob) + CoroutineName("SiteState") operator fun plus(action: SiteAction): SiteState = when (action) { is SiteAction.HomePage -> copy(view = SiteView.HOME) @@ -68,9 +75,20 @@ data class SiteState( factorioGameState = factorioGameState?.let { it + action } ) - is SiteAction.EventServerUpdate -> copy( + is SiteAction.EventServerUpdate -> when (action.packet) { + is EventServerPacket.ChunkTileSaved -> { + if (factorioGameState?.map != null) { + launch { + factorioGameState.map.refreshUpdatedTilePng(action.packet.filename) + } + } + this + } - ) + is EventServerPacket.Kafkatorio -> { + this + } + } } } @@ -93,19 +111,18 @@ sealed interface SiteAction : RAction { sealed interface SiteView { - val pathMatcher: Any sealed interface StaticPath : SiteView { - override val pathMatcher: String + val path: String } sealed interface DynamicPath : SiteView { - override val pathMatcher: RegExp + val pathMatcher: RegExp } object HOME : StaticPath { - override val pathMatcher: String = "/" + override val path: String = "/" } object SERVER : DynamicPath { @@ -113,19 +130,15 @@ sealed interface SiteView { } } -//val SiteView.urlMatcher: String -// get() = when (this) { -// SiteView.HOME -> "/" -// SiteView.SERVER -> "servers/${FactorioServerId.validIdRegex}" -// } private fun Navigo.on(view: SiteView, handler: (Match) -> Unit): Navigo { return when (view) { - is SiteView.StaticPath -> on(view.pathMatcher, { match: Match -> handler(match) }) + is SiteView.StaticPath -> on(view.path, { match: Match -> handler(match) }) is SiteView.DynamicPath -> on(view.pathMatcher, { match: Match -> handler(match) }) } } + //private fun Navigo.on( // view: SiteView, // before: BeforeHook? = null, diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/WebsocketService.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/WebsocketService.kt index a111a6c..aacb43f 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/WebsocketService.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/WebsocketService.kt @@ -12,12 +12,11 @@ import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate +import dev.adamko.kafkatorio.webmap.App import dev.adamko.kafkatorio.webmap.SiteAction -import dev.adamko.kafkatorio.webmap.SiteState import dev.adamko.kafkatorio.webmap.config.ApplicationProperties import dev.adamko.kafkatorio.webmap.config.jsonMapper import dev.adamko.kafkatorio.webmap.rootJob -import io.kvision.redux.ReduxStore import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope @@ -31,9 +30,7 @@ import org.w3c.dom.WebSocket import org.w3c.dom.events.Event -class WebsocketService( - private val siteStateStore: ReduxStore -) : CoroutineScope { +object WebsocketService : CoroutineScope { override val coroutineContext: CoroutineContext = CoroutineName("WebsocketService") + Job(rootJob) @@ -80,7 +77,7 @@ class WebsocketService( is EventServerPacket.Kafkatorio -> when (val packetData = packet.packet.data) { is PlayerUpdate -> - siteStateStore.dispatch( + App.siteStateStore.dispatch( SiteAction.FactorioUpdate.Player(packet.packet.tick, packetData) ) diff --git a/modules/web-map/src/main/resources/css/bootstrap.min.css b/modules/web-map/src/main/resources/css/bootstrap.min.css new file mode 100644 index 0000000..3c9c553 --- /dev/null +++ b/modules/web-map/src/main/resources/css/bootstrap.min.css @@ -0,0 +1,12303 @@ +@charset "UTF-8"; +/*! + * Bootswatch v5.2.0 (https://bootswatch.com) + * Theme: darkly + * Copyright 2012-2022 Thomas Park + * Licensed under MIT + * Based on Bootstrap +*//*! + * Bootstrap v5.2.0 (https://getbootstrap.com/) + * Copyright 2011-2022 The Bootstrap Authors + * Copyright 2011-2022 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +@import url(https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap); + +:root { + --bs-blue: #375a7f; + --bs-indigo: #6610f2; + --bs-purple: #6f42c1; + --bs-pink: #e83e8c; + --bs-red: #e74c3c; + --bs-orange: #fd7e14; + --bs-yellow: #f39c12; + --bs-green: #00bc8c; + --bs-teal: #20c997; + --bs-cyan: #3498db; + --bs-black: #000; + --bs-white: #fff; + --bs-gray: #888; + --bs-gray-dark: #303030; + --bs-gray-100: #f8f9fa; + --bs-gray-200: #ebebeb; + --bs-gray-300: #dee2e6; + --bs-gray-400: #ced4da; + --bs-gray-500: #adb5bd; + --bs-gray-600: #888; + --bs-gray-700: #444; + --bs-gray-800: #303030; + --bs-gray-900: #222; + --bs-primary: #375a7f; + --bs-secondary: #444; + --bs-success: #00bc8c; + --bs-info: #3498db; + --bs-warning: #f39c12; + --bs-danger: #e74c3c; + --bs-light: #adb5bd; + --bs-dark: #303030; + --bs-primary-rgb: 55, 90, 127; + --bs-secondary-rgb: 68, 68, 68; + --bs-success-rgb: 0, 188, 140; + --bs-info-rgb: 52, 152, 219; + --bs-warning-rgb: 243, 156, 18; + --bs-danger-rgb: 231, 76, 60; + --bs-light-rgb: 173, 181, 189; + --bs-dark-rgb: 48, 48, 48; + --bs-white-rgb: 255, 255, 255; + --bs-black-rgb: 0, 0, 0; + --bs-body-color-rgb: 255, 255, 255; + --bs-body-bg-rgb: 34, 34, 34; + --bs-font-sans-serif: Lato, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); + --bs-body-font-family: var(--bs-font-sans-serif); + --bs-body-font-size: 1rem; + --bs-body-font-weight: 400; + --bs-body-line-height: 1.5; + --bs-body-color: #fff; + --bs-body-bg: #222; + --bs-border-width: 1px; + --bs-border-style: solid; + --bs-border-color: #dee2e6; + --bs-border-color-translucent: rgba(0, 0, 0, 0.175); + --bs-border-radius: 0.375rem; + --bs-border-radius-sm: 0.25rem; + --bs-border-radius-lg: 0.5rem; + --bs-border-radius-xl: 1rem; + --bs-border-radius-2xl: 2rem; + --bs-border-radius-pill: 50rem; + --bs-link-color: #00bc8c; + --bs-link-hover-color: #009670; + --bs-code-color: #e83e8c; + --bs-highlight-bg: #fdebd0 +} + +*, ::after, ::before { + box-sizing: border-box +} + +@media (prefers-reduced-motion: no-preference) { + :root { + scroll-behavior: smooth + } +} + +body { + margin: 0; + font-family: var(--bs-body-font-family); + font-size: var(--bs-body-font-size); + font-weight: var(--bs-body-font-weight); + line-height: var(--bs-body-line-height); + color: var(--bs-body-color); + text-align: var(--bs-body-text-align); + background-color: var(--bs-body-bg); + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: transparent +} + +hr { + margin: 1rem 0; + color: inherit; + border: 0; + border-top: 1px solid; + opacity: .25 +} + +.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: .5rem; + font-weight: 500; + line-height: 1.2 +} + +.h1, h1 { + font-size: calc(1.425rem + 2.1vw) +} + +@media (min-width: 1200px) { + .h1, h1 { + font-size: 3rem + } +} + +.h2, h2 { + font-size: calc(1.375rem + 1.5vw) +} + +@media (min-width: 1200px) { + .h2, h2 { + font-size: 2.5rem + } +} + +.h3, h3 { + font-size: calc(1.325rem + .9vw) +} + +@media (min-width: 1200px) { + .h3, h3 { + font-size: 2rem + } +} + +.h4, h4 { + font-size: calc(1.275rem + .3vw) +} + +@media (min-width: 1200px) { + .h4, h4 { + font-size: 1.5rem + } +} + +.h5, h5 { + font-size: 1.25rem +} + +.h6, h6 { + font-size: 1rem +} + +p { + margin-top: 0; + margin-bottom: 1rem +} + +abbr[title] { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + cursor: help; + -webkit-text-decoration-skip-ink: none; + text-decoration-skip-ink: none +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit +} + +ol, ul { + padding-left: 2rem +} + +dl, ol, ul { + margin-top: 0; + margin-bottom: 1rem +} + +ol ol, ol ul, ul ol, ul ul { + margin-bottom: 0 +} + +dt { + font-weight: 700 +} + +dd { + margin-bottom: .5rem; + margin-left: 0 +} + +blockquote { + margin: 0 0 1rem +} + +b, strong { + font-weight: bolder +} + +.small, small { + font-size: .875em +} + +.mark, mark { + padding: .1875em; + background-color: var(--bs-highlight-bg) +} + +sub, sup { + position: relative; + font-size: .75em; + line-height: 0; + vertical-align: baseline +} + +sub { + bottom: -.25em +} + +sup { + top: -.5em +} + +a { + color: var(--bs-link-color); + text-decoration: underline +} + +a:hover { + color: var(--bs-link-hover-color) +} + +a:not([href]):not([class]), a:not([href]):not([class]):hover { + color: inherit; + text-decoration: none +} + +code, kbd, pre, samp { + font-family: var(--bs-font-monospace); + font-size: 1em +} + +pre { + display: block; + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; + font-size: .875em; + color: inherit +} + +pre code { + font-size: inherit; + color: inherit; + word-break: normal +} + +code { + font-size: .875em; + color: var(--bs-code-color); + word-wrap: break-word +} + +a > code { + color: inherit +} + +kbd { + padding: .1875rem .375rem; + font-size: .875em; + color: var(--bs-body-bg); + background-color: var(--bs-body-color); + border-radius: .25rem +} + +kbd kbd { + padding: 0; + font-size: 1em +} + +figure { + margin: 0 0 1rem +} + +img, svg { + vertical-align: middle +} + +table { + caption-side: bottom; + border-collapse: collapse +} + +caption { + padding-top: .5rem; + padding-bottom: .5rem; + color: #888; + text-align: left +} + +th { + text-align: inherit; + text-align: -webkit-match-parent +} + +tbody, td, tfoot, th, thead, tr { + border-color: inherit; + border-style: solid; + border-width: 0 +} + +label { + display: inline-block +} + +button { + border-radius: 0 +} + +button:focus:not(:focus-visible) { + outline: 0 +} + +button, input, optgroup, select, textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit +} + +button, select { + text-transform: none +} + +[role=button] { + cursor: pointer +} + +select { + word-wrap: normal +} + +select:disabled { + opacity: 1 +} + +[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator { + display: none !important +} + +[type=button], [type=reset], [type=submit], button { + -webkit-appearance: button +} + +[type=button]:not(:disabled), [type=reset]:not(:disabled), [type=submit]:not(:disabled), button:not(:disabled) { + cursor: pointer +} + +::-moz-focus-inner { + padding: 0; + border-style: none +} + +textarea { + resize: vertical +} + +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0 +} + +legend { + float: left; + width: 100%; + padding: 0; + margin-bottom: .5rem; + font-size: calc(1.275rem + .3vw); + line-height: inherit +} + +@media (min-width: 1200px) { + legend { + font-size: 1.5rem + } +} + +legend + * { + clear: left +} + +::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-fields-wrapper, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-text, ::-webkit-datetime-edit-year-field { + padding: 0 +} + +::-webkit-inner-spin-button { + height: auto +} + +[type=search] { + outline-offset: -2px; + -webkit-appearance: textfield +} + +::-webkit-search-decoration { + -webkit-appearance: none +} + +::-webkit-color-swatch-wrapper { + padding: 0 +} + +::-webkit-file-upload-button { + font: inherit; + -webkit-appearance: button +} + +::file-selector-button { + font: inherit; + -webkit-appearance: button +} + +output { + display: inline-block +} + +iframe { + border: 0 +} + +summary { + display: list-item; + cursor: pointer +} + +progress { + vertical-align: baseline +} + +[hidden] { + display: none !important +} + +.lead { + font-size: 1.25rem; + font-weight: 300 +} + +.display-1 { + font-size: calc(1.625rem + 4.5vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width: 1200px) { + .display-1 { + font-size: 5rem + } +} + +.display-2 { + font-size: calc(1.575rem + 3.9vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width: 1200px) { + .display-2 { + font-size: 4.5rem + } +} + +.display-3 { + font-size: calc(1.525rem + 3.3vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width: 1200px) { + .display-3 { + font-size: 4rem + } +} + +.display-4 { + font-size: calc(1.475rem + 2.7vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width: 1200px) { + .display-4 { + font-size: 3.5rem + } +} + +.display-5 { + font-size: calc(1.425rem + 2.1vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width: 1200px) { + .display-5 { + font-size: 3rem + } +} + +.display-6 { + font-size: calc(1.375rem + 1.5vw); + font-weight: 300; + line-height: 1.2 +} + +@media (min-width: 1200px) { + .display-6 { + font-size: 2.5rem + } +} + +.list-unstyled { + padding-left: 0; + list-style: none +} + +.list-inline { + padding-left: 0; + list-style: none +} + +.list-inline-item { + display: inline-block +} + +.list-inline-item:not(:last-child) { + margin-right: .5rem +} + +.initialism { + font-size: .875em; + text-transform: uppercase +} + +.blockquote { + margin-bottom: 1rem; + font-size: 1.25rem +} + +.blockquote > :last-child { + margin-bottom: 0 +} + +.blockquote-footer { + margin-top: -1rem; + margin-bottom: 1rem; + font-size: .875em; + color: #888 +} + +.blockquote-footer::before { + content: "��" +} + +.img-fluid { + max-width: 100%; + height: auto +} + +.img-thumbnail { + padding: .25rem; + background-color: #222; + border: 1px solid var(--bs-border-color); + border-radius: .375rem; + max-width: 100%; + height: auto +} + +.figure { + display: inline-block +} + +.figure-img { + margin-bottom: .5rem; + line-height: 1 +} + +.figure-caption { + font-size: .875em; + color: #888 +} + +.container, .container-fluid, .container-lg, .container-md, .container-sm, .container-xl, .container-xxl { + --bs-gutter-x: 1.5rem; + --bs-gutter-y: 0; + width: 100%; + padding-right: calc(var(--bs-gutter-x) * .5); + padding-left: calc(var(--bs-gutter-x) * .5); + margin-right: auto; + margin-left: auto +} + +@media (min-width: 576px) { + .container, .container-sm { + max-width: 540px + } +} + +@media (min-width: 768px) { + .container, .container-md, .container-sm { + max-width: 720px + } +} + +@media (min-width: 992px) { + .container, .container-lg, .container-md, .container-sm { + max-width: 960px + } +} + +@media (min-width: 1200px) { + .container, .container-lg, .container-md, .container-sm, .container-xl { + max-width: 1140px + } +} + +@media (min-width: 1400px) { + .container, .container-lg, .container-md, .container-sm, .container-xl, .container-xxl { + max-width: 1320px + } +} + +.row { + --bs-gutter-x: 1.5rem; + --bs-gutter-y: 0; + display: flex; + flex-wrap: wrap; + margin-top: calc(-1 * var(--bs-gutter-y)); + margin-right: calc(-.5 * var(--bs-gutter-x)); + margin-left: calc(-.5 * var(--bs-gutter-x)) +} + +.row > * { + flex-shrink: 0; + width: 100%; + max-width: 100%; + padding-right: calc(var(--bs-gutter-x) * .5); + padding-left: calc(var(--bs-gutter-x) * .5); + margin-top: var(--bs-gutter-y) +} + +.col { + flex: 1 0 0% +} + +.row-cols-auto > * { + flex: 0 0 auto; + width: auto +} + +.row-cols-1 > * { + flex: 0 0 auto; + width: 100% +} + +.row-cols-2 > * { + flex: 0 0 auto; + width: 50% +} + +.row-cols-3 > * { + flex: 0 0 auto; + width: 33.3333333333% +} + +.row-cols-4 > * { + flex: 0 0 auto; + width: 25% +} + +.row-cols-5 > * { + flex: 0 0 auto; + width: 20% +} + +.row-cols-6 > * { + flex: 0 0 auto; + width: 16.6666666667% +} + +.col-auto { + flex: 0 0 auto; + width: auto +} + +.col-1 { + flex: 0 0 auto; + width: 8.33333333% +} + +.col-2 { + flex: 0 0 auto; + width: 16.66666667% +} + +.col-3 { + flex: 0 0 auto; + width: 25% +} + +.col-4 { + flex: 0 0 auto; + width: 33.33333333% +} + +.col-5 { + flex: 0 0 auto; + width: 41.66666667% +} + +.col-6 { + flex: 0 0 auto; + width: 50% +} + +.col-7 { + flex: 0 0 auto; + width: 58.33333333% +} + +.col-8 { + flex: 0 0 auto; + width: 66.66666667% +} + +.col-9 { + flex: 0 0 auto; + width: 75% +} + +.col-10 { + flex: 0 0 auto; + width: 83.33333333% +} + +.col-11 { + flex: 0 0 auto; + width: 91.66666667% +} + +.col-12 { + flex: 0 0 auto; + width: 100% +} + +.offset-1 { + margin-left: 8.33333333% +} + +.offset-2 { + margin-left: 16.66666667% +} + +.offset-3 { + margin-left: 25% +} + +.offset-4 { + margin-left: 33.33333333% +} + +.offset-5 { + margin-left: 41.66666667% +} + +.offset-6 { + margin-left: 50% +} + +.offset-7 { + margin-left: 58.33333333% +} + +.offset-8 { + margin-left: 66.66666667% +} + +.offset-9 { + margin-left: 75% +} + +.offset-10 { + margin-left: 83.33333333% +} + +.offset-11 { + margin-left: 91.66666667% +} + +.g-0, .gx-0 { + --bs-gutter-x: 0 +} + +.g-0, .gy-0 { + --bs-gutter-y: 0 +} + +.g-1, .gx-1 { + --bs-gutter-x: 0.25rem +} + +.g-1, .gy-1 { + --bs-gutter-y: 0.25rem +} + +.g-2, .gx-2 { + --bs-gutter-x: 0.5rem +} + +.g-2, .gy-2 { + --bs-gutter-y: 0.5rem +} + +.g-3, .gx-3 { + --bs-gutter-x: 1rem +} + +.g-3, .gy-3 { + --bs-gutter-y: 1rem +} + +.g-4, .gx-4 { + --bs-gutter-x: 1.5rem +} + +.g-4, .gy-4 { + --bs-gutter-y: 1.5rem +} + +.g-5, .gx-5 { + --bs-gutter-x: 3rem +} + +.g-5, .gy-5 { + --bs-gutter-y: 3rem +} + +@media (min-width: 576px) { + .col-sm { + flex: 1 0 0% + } + + .row-cols-sm-auto > * { + flex: 0 0 auto; + width: auto + } + + .row-cols-sm-1 > * { + flex: 0 0 auto; + width: 100% + } + + .row-cols-sm-2 > * { + flex: 0 0 auto; + width: 50% + } + + .row-cols-sm-3 > * { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-sm-4 > * { + flex: 0 0 auto; + width: 25% + } + + .row-cols-sm-5 > * { + flex: 0 0 auto; + width: 20% + } + + .row-cols-sm-6 > * { + flex: 0 0 auto; + width: 16.6666666667% + } + + .col-sm-auto { + flex: 0 0 auto; + width: auto + } + + .col-sm-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-sm-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-sm-3 { + flex: 0 0 auto; + width: 25% + } + + .col-sm-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-sm-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-sm-6 { + flex: 0 0 auto; + width: 50% + } + + .col-sm-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-sm-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-sm-9 { + flex: 0 0 auto; + width: 75% + } + + .col-sm-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-sm-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-sm-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-sm-0 { + margin-left: 0 + } + + .offset-sm-1 { + margin-left: 8.33333333% + } + + .offset-sm-2 { + margin-left: 16.66666667% + } + + .offset-sm-3 { + margin-left: 25% + } + + .offset-sm-4 { + margin-left: 33.33333333% + } + + .offset-sm-5 { + margin-left: 41.66666667% + } + + .offset-sm-6 { + margin-left: 50% + } + + .offset-sm-7 { + margin-left: 58.33333333% + } + + .offset-sm-8 { + margin-left: 66.66666667% + } + + .offset-sm-9 { + margin-left: 75% + } + + .offset-sm-10 { + margin-left: 83.33333333% + } + + .offset-sm-11 { + margin-left: 91.66666667% + } + + .g-sm-0, .gx-sm-0 { + --bs-gutter-x: 0 + } + + .g-sm-0, .gy-sm-0 { + --bs-gutter-y: 0 + } + + .g-sm-1, .gx-sm-1 { + --bs-gutter-x: 0.25rem + } + + .g-sm-1, .gy-sm-1 { + --bs-gutter-y: 0.25rem + } + + .g-sm-2, .gx-sm-2 { + --bs-gutter-x: 0.5rem + } + + .g-sm-2, .gy-sm-2 { + --bs-gutter-y: 0.5rem + } + + .g-sm-3, .gx-sm-3 { + --bs-gutter-x: 1rem + } + + .g-sm-3, .gy-sm-3 { + --bs-gutter-y: 1rem + } + + .g-sm-4, .gx-sm-4 { + --bs-gutter-x: 1.5rem + } + + .g-sm-4, .gy-sm-4 { + --bs-gutter-y: 1.5rem + } + + .g-sm-5, .gx-sm-5 { + --bs-gutter-x: 3rem + } + + .g-sm-5, .gy-sm-5 { + --bs-gutter-y: 3rem + } +} + +@media (min-width: 768px) { + .col-md { + flex: 1 0 0% + } + + .row-cols-md-auto > * { + flex: 0 0 auto; + width: auto + } + + .row-cols-md-1 > * { + flex: 0 0 auto; + width: 100% + } + + .row-cols-md-2 > * { + flex: 0 0 auto; + width: 50% + } + + .row-cols-md-3 > * { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-md-4 > * { + flex: 0 0 auto; + width: 25% + } + + .row-cols-md-5 > * { + flex: 0 0 auto; + width: 20% + } + + .row-cols-md-6 > * { + flex: 0 0 auto; + width: 16.6666666667% + } + + .col-md-auto { + flex: 0 0 auto; + width: auto + } + + .col-md-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-md-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-md-3 { + flex: 0 0 auto; + width: 25% + } + + .col-md-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-md-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-md-6 { + flex: 0 0 auto; + width: 50% + } + + .col-md-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-md-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-md-9 { + flex: 0 0 auto; + width: 75% + } + + .col-md-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-md-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-md-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-md-0 { + margin-left: 0 + } + + .offset-md-1 { + margin-left: 8.33333333% + } + + .offset-md-2 { + margin-left: 16.66666667% + } + + .offset-md-3 { + margin-left: 25% + } + + .offset-md-4 { + margin-left: 33.33333333% + } + + .offset-md-5 { + margin-left: 41.66666667% + } + + .offset-md-6 { + margin-left: 50% + } + + .offset-md-7 { + margin-left: 58.33333333% + } + + .offset-md-8 { + margin-left: 66.66666667% + } + + .offset-md-9 { + margin-left: 75% + } + + .offset-md-10 { + margin-left: 83.33333333% + } + + .offset-md-11 { + margin-left: 91.66666667% + } + + .g-md-0, .gx-md-0 { + --bs-gutter-x: 0 + } + + .g-md-0, .gy-md-0 { + --bs-gutter-y: 0 + } + + .g-md-1, .gx-md-1 { + --bs-gutter-x: 0.25rem + } + + .g-md-1, .gy-md-1 { + --bs-gutter-y: 0.25rem + } + + .g-md-2, .gx-md-2 { + --bs-gutter-x: 0.5rem + } + + .g-md-2, .gy-md-2 { + --bs-gutter-y: 0.5rem + } + + .g-md-3, .gx-md-3 { + --bs-gutter-x: 1rem + } + + .g-md-3, .gy-md-3 { + --bs-gutter-y: 1rem + } + + .g-md-4, .gx-md-4 { + --bs-gutter-x: 1.5rem + } + + .g-md-4, .gy-md-4 { + --bs-gutter-y: 1.5rem + } + + .g-md-5, .gx-md-5 { + --bs-gutter-x: 3rem + } + + .g-md-5, .gy-md-5 { + --bs-gutter-y: 3rem + } +} + +@media (min-width: 992px) { + .col-lg { + flex: 1 0 0% + } + + .row-cols-lg-auto > * { + flex: 0 0 auto; + width: auto + } + + .row-cols-lg-1 > * { + flex: 0 0 auto; + width: 100% + } + + .row-cols-lg-2 > * { + flex: 0 0 auto; + width: 50% + } + + .row-cols-lg-3 > * { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-lg-4 > * { + flex: 0 0 auto; + width: 25% + } + + .row-cols-lg-5 > * { + flex: 0 0 auto; + width: 20% + } + + .row-cols-lg-6 > * { + flex: 0 0 auto; + width: 16.6666666667% + } + + .col-lg-auto { + flex: 0 0 auto; + width: auto + } + + .col-lg-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-lg-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-lg-3 { + flex: 0 0 auto; + width: 25% + } + + .col-lg-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-lg-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-lg-6 { + flex: 0 0 auto; + width: 50% + } + + .col-lg-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-lg-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-lg-9 { + flex: 0 0 auto; + width: 75% + } + + .col-lg-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-lg-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-lg-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-lg-0 { + margin-left: 0 + } + + .offset-lg-1 { + margin-left: 8.33333333% + } + + .offset-lg-2 { + margin-left: 16.66666667% + } + + .offset-lg-3 { + margin-left: 25% + } + + .offset-lg-4 { + margin-left: 33.33333333% + } + + .offset-lg-5 { + margin-left: 41.66666667% + } + + .offset-lg-6 { + margin-left: 50% + } + + .offset-lg-7 { + margin-left: 58.33333333% + } + + .offset-lg-8 { + margin-left: 66.66666667% + } + + .offset-lg-9 { + margin-left: 75% + } + + .offset-lg-10 { + margin-left: 83.33333333% + } + + .offset-lg-11 { + margin-left: 91.66666667% + } + + .g-lg-0, .gx-lg-0 { + --bs-gutter-x: 0 + } + + .g-lg-0, .gy-lg-0 { + --bs-gutter-y: 0 + } + + .g-lg-1, .gx-lg-1 { + --bs-gutter-x: 0.25rem + } + + .g-lg-1, .gy-lg-1 { + --bs-gutter-y: 0.25rem + } + + .g-lg-2, .gx-lg-2 { + --bs-gutter-x: 0.5rem + } + + .g-lg-2, .gy-lg-2 { + --bs-gutter-y: 0.5rem + } + + .g-lg-3, .gx-lg-3 { + --bs-gutter-x: 1rem + } + + .g-lg-3, .gy-lg-3 { + --bs-gutter-y: 1rem + } + + .g-lg-4, .gx-lg-4 { + --bs-gutter-x: 1.5rem + } + + .g-lg-4, .gy-lg-4 { + --bs-gutter-y: 1.5rem + } + + .g-lg-5, .gx-lg-5 { + --bs-gutter-x: 3rem + } + + .g-lg-5, .gy-lg-5 { + --bs-gutter-y: 3rem + } +} + +@media (min-width: 1200px) { + .col-xl { + flex: 1 0 0% + } + + .row-cols-xl-auto > * { + flex: 0 0 auto; + width: auto + } + + .row-cols-xl-1 > * { + flex: 0 0 auto; + width: 100% + } + + .row-cols-xl-2 > * { + flex: 0 0 auto; + width: 50% + } + + .row-cols-xl-3 > * { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-xl-4 > * { + flex: 0 0 auto; + width: 25% + } + + .row-cols-xl-5 > * { + flex: 0 0 auto; + width: 20% + } + + .row-cols-xl-6 > * { + flex: 0 0 auto; + width: 16.6666666667% + } + + .col-xl-auto { + flex: 0 0 auto; + width: auto + } + + .col-xl-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-xl-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-xl-3 { + flex: 0 0 auto; + width: 25% + } + + .col-xl-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-xl-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-xl-6 { + flex: 0 0 auto; + width: 50% + } + + .col-xl-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-xl-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-xl-9 { + flex: 0 0 auto; + width: 75% + } + + .col-xl-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-xl-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-xl-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-xl-0 { + margin-left: 0 + } + + .offset-xl-1 { + margin-left: 8.33333333% + } + + .offset-xl-2 { + margin-left: 16.66666667% + } + + .offset-xl-3 { + margin-left: 25% + } + + .offset-xl-4 { + margin-left: 33.33333333% + } + + .offset-xl-5 { + margin-left: 41.66666667% + } + + .offset-xl-6 { + margin-left: 50% + } + + .offset-xl-7 { + margin-left: 58.33333333% + } + + .offset-xl-8 { + margin-left: 66.66666667% + } + + .offset-xl-9 { + margin-left: 75% + } + + .offset-xl-10 { + margin-left: 83.33333333% + } + + .offset-xl-11 { + margin-left: 91.66666667% + } + + .g-xl-0, .gx-xl-0 { + --bs-gutter-x: 0 + } + + .g-xl-0, .gy-xl-0 { + --bs-gutter-y: 0 + } + + .g-xl-1, .gx-xl-1 { + --bs-gutter-x: 0.25rem + } + + .g-xl-1, .gy-xl-1 { + --bs-gutter-y: 0.25rem + } + + .g-xl-2, .gx-xl-2 { + --bs-gutter-x: 0.5rem + } + + .g-xl-2, .gy-xl-2 { + --bs-gutter-y: 0.5rem + } + + .g-xl-3, .gx-xl-3 { + --bs-gutter-x: 1rem + } + + .g-xl-3, .gy-xl-3 { + --bs-gutter-y: 1rem + } + + .g-xl-4, .gx-xl-4 { + --bs-gutter-x: 1.5rem + } + + .g-xl-4, .gy-xl-4 { + --bs-gutter-y: 1.5rem + } + + .g-xl-5, .gx-xl-5 { + --bs-gutter-x: 3rem + } + + .g-xl-5, .gy-xl-5 { + --bs-gutter-y: 3rem + } +} + +@media (min-width: 1400px) { + .col-xxl { + flex: 1 0 0% + } + + .row-cols-xxl-auto > * { + flex: 0 0 auto; + width: auto + } + + .row-cols-xxl-1 > * { + flex: 0 0 auto; + width: 100% + } + + .row-cols-xxl-2 > * { + flex: 0 0 auto; + width: 50% + } + + .row-cols-xxl-3 > * { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-xxl-4 > * { + flex: 0 0 auto; + width: 25% + } + + .row-cols-xxl-5 > * { + flex: 0 0 auto; + width: 20% + } + + .row-cols-xxl-6 > * { + flex: 0 0 auto; + width: 16.6666666667% + } + + .col-xxl-auto { + flex: 0 0 auto; + width: auto + } + + .col-xxl-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-xxl-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-xxl-3 { + flex: 0 0 auto; + width: 25% + } + + .col-xxl-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-xxl-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-xxl-6 { + flex: 0 0 auto; + width: 50% + } + + .col-xxl-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-xxl-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-xxl-9 { + flex: 0 0 auto; + width: 75% + } + + .col-xxl-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-xxl-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-xxl-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-xxl-0 { + margin-left: 0 + } + + .offset-xxl-1 { + margin-left: 8.33333333% + } + + .offset-xxl-2 { + margin-left: 16.66666667% + } + + .offset-xxl-3 { + margin-left: 25% + } + + .offset-xxl-4 { + margin-left: 33.33333333% + } + + .offset-xxl-5 { + margin-left: 41.66666667% + } + + .offset-xxl-6 { + margin-left: 50% + } + + .offset-xxl-7 { + margin-left: 58.33333333% + } + + .offset-xxl-8 { + margin-left: 66.66666667% + } + + .offset-xxl-9 { + margin-left: 75% + } + + .offset-xxl-10 { + margin-left: 83.33333333% + } + + .offset-xxl-11 { + margin-left: 91.66666667% + } + + .g-xxl-0, .gx-xxl-0 { + --bs-gutter-x: 0 + } + + .g-xxl-0, .gy-xxl-0 { + --bs-gutter-y: 0 + } + + .g-xxl-1, .gx-xxl-1 { + --bs-gutter-x: 0.25rem + } + + .g-xxl-1, .gy-xxl-1 { + --bs-gutter-y: 0.25rem + } + + .g-xxl-2, .gx-xxl-2 { + --bs-gutter-x: 0.5rem + } + + .g-xxl-2, .gy-xxl-2 { + --bs-gutter-y: 0.5rem + } + + .g-xxl-3, .gx-xxl-3 { + --bs-gutter-x: 1rem + } + + .g-xxl-3, .gy-xxl-3 { + --bs-gutter-y: 1rem + } + + .g-xxl-4, .gx-xxl-4 { + --bs-gutter-x: 1.5rem + } + + .g-xxl-4, .gy-xxl-4 { + --bs-gutter-y: 1.5rem + } + + .g-xxl-5, .gx-xxl-5 { + --bs-gutter-x: 3rem + } + + .g-xxl-5, .gy-xxl-5 { + --bs-gutter-y: 3rem + } +} + +.table { + --bs-table-color: var(--bs-body-color); + --bs-table-bg: transparent; + --bs-table-border-color: #444; + --bs-table-accent-bg: transparent; + --bs-table-striped-color: var(--bs-body-color); + --bs-table-striped-bg: rgba(0, 0, 0, 0.05); + --bs-table-active-color: var(--bs-body-color); + --bs-table-active-bg: rgba(0, 0, 0, 0.1); + --bs-table-hover-color: var(--bs-body-color); + --bs-table-hover-bg: rgba(0, 0, 0, 0.075); + width: 100%; + margin-bottom: 1rem; + color: var(--bs-table-color); + vertical-align: top; + border-color: var(--bs-table-border-color) +} + +.table > :not(caption) > * > * { + padding: .5rem .5rem; + background-color: var(--bs-table-bg); + border-bottom-width: 1px; + box-shadow: inset 0 0 0 9999px var(--bs-table-accent-bg) +} + +.table > tbody { + vertical-align: inherit +} + +.table > thead { + vertical-align: bottom +} + +.table-group-divider { + border-top: 2px solid currentcolor +} + +.caption-top { + caption-side: top +} + +.table-sm > :not(caption) > * > * { + padding: .25rem .25rem +} + +.table-bordered > :not(caption) > * { + border-width: 1px 0 +} + +.table-bordered > :not(caption) > * > * { + border-width: 0 1px +} + +.table-borderless > :not(caption) > * > * { + border-bottom-width: 0 +} + +.table-borderless > :not(:first-child) { + border-top-width: 0 +} + +.table-striped > tbody > tr:nth-of-type(odd) > * { + --bs-table-accent-bg: var(--bs-table-striped-bg); + color: var(--bs-table-striped-color) +} + +.table-striped-columns > :not(caption) > tr > :nth-child(even) { + --bs-table-accent-bg: var(--bs-table-striped-bg); + color: var(--bs-table-striped-color) +} + +.table-active { + --bs-table-accent-bg: var(--bs-table-active-bg); + color: var(--bs-table-active-color) +} + +.table-hover > tbody > tr:hover > * { + --bs-table-accent-bg: var(--bs-table-hover-bg); + color: var(--bs-table-hover-color) +} + +.table-primary { + --bs-table-color: #fff; + --bs-table-bg: #375a7f; + --bs-table-border-color: #4b6b8c; + --bs-table-striped-bg: #416285; + --bs-table-striped-color: #fff; + --bs-table-active-bg: #4b6b8c; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #466689; + --bs-table-hover-color: #fff; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color) +} + +.table-secondary { + --bs-table-color: #fff; + --bs-table-bg: #444444; + --bs-table-border-color: #575757; + --bs-table-striped-bg: #4d4d4d; + --bs-table-striped-color: #fff; + --bs-table-active-bg: #575757; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #525252; + --bs-table-hover-color: #fff; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color) +} + +.table-success { + --bs-table-color: #fff; + --bs-table-bg: #00bc8c; + --bs-table-border-color: #1ac398; + --bs-table-striped-bg: #0dbf92; + --bs-table-striped-color: #fff; + --bs-table-active-bg: #1ac398; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #13c195; + --bs-table-hover-color: #fff; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color) +} + +.table-info { + --bs-table-color: #fff; + --bs-table-bg: #3498db; + --bs-table-border-color: #48a2df; + --bs-table-striped-bg: #3e9ddd; + --bs-table-striped-color: #fff; + --bs-table-active-bg: #48a2df; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #43a0de; + --bs-table-hover-color: #fff; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color) +} + +.table-warning { + --bs-table-color: #fff; + --bs-table-bg: #f39c12; + --bs-table-border-color: #f4a62a; + --bs-table-striped-bg: #f4a11e; + --bs-table-striped-color: #fff; + --bs-table-active-bg: #f4a62a; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #f4a324; + --bs-table-hover-color: #fff; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color) +} + +.table-danger { + --bs-table-color: #fff; + --bs-table-bg: #e74c3c; + --bs-table-border-color: #e95e50; + --bs-table-striped-bg: #e85546; + --bs-table-striped-color: #fff; + --bs-table-active-bg: #e95e50; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #e9594b; + --bs-table-hover-color: #fff; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color) +} + +.table-light { + --bs-table-color: #fff; + --bs-table-bg: #adb5bd; + --bs-table-border-color: #b5bcc4; + --bs-table-striped-bg: #b1b9c0; + --bs-table-striped-color: #fff; + --bs-table-active-bg: #b5bcc4; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #b3bbc2; + --bs-table-hover-color: #fff; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color) +} + +.table-dark { + --bs-table-color: #fff; + --bs-table-bg: #303030; + --bs-table-border-color: #454545; + --bs-table-striped-bg: #3a3a3a; + --bs-table-striped-color: #fff; + --bs-table-active-bg: #454545; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #404040; + --bs-table-hover-color: #fff; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color) +} + +.table-responsive { + overflow-x: auto; + -webkit-overflow-scrolling: touch +} + +@media (max-width: 575.98px) { + .table-responsive-sm { + overflow-x: auto; + -webkit-overflow-scrolling: touch + } +} + +@media (max-width: 767.98px) { + .table-responsive-md { + overflow-x: auto; + -webkit-overflow-scrolling: touch + } +} + +@media (max-width: 991.98px) { + .table-responsive-lg { + overflow-x: auto; + -webkit-overflow-scrolling: touch + } +} + +@media (max-width: 1199.98px) { + .table-responsive-xl { + overflow-x: auto; + -webkit-overflow-scrolling: touch + } +} + +@media (max-width: 1399.98px) { + .table-responsive-xxl { + overflow-x: auto; + -webkit-overflow-scrolling: touch + } +} + +.form-label { + margin-bottom: .5rem +} + +.col-form-label { + padding-top: calc(.375rem + 1px); + padding-bottom: calc(.375rem + 1px); + margin-bottom: 0; + font-size: inherit; + line-height: 1.5 +} + +.col-form-label-lg { + padding-top: calc(.5rem + 1px); + padding-bottom: calc(.5rem + 1px); + font-size: 1.25rem +} + +.col-form-label-sm { + padding-top: calc(.25rem + 1px); + padding-bottom: calc(.25rem + 1px); + font-size: .875rem +} + +.form-text { + margin-top: .25rem; + font-size: .875em; + color: #888 +} + +.form-control { + display: block; + width: 100%; + padding: .375rem .75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #303030; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #222; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border-radius: .375rem; + transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .form-control { + transition: none + } +} + +.form-control[type=file] { + overflow: hidden +} + +.form-control[type=file]:not(:disabled):not([readonly]) { + cursor: pointer +} + +.form-control:focus { + color: #303030; + background-color: #fff; + border-color: #9badbf; + outline: 0; + box-shadow: 0 0 0 .25rem rgba(55, 90, 127, .25) +} + +.form-control::-webkit-date-and-time-value { + height: 1.5em +} + +.form-control::-moz-placeholder { + color: #888; + opacity: 1 +} + +.form-control::placeholder { + color: #888; + opacity: 1 +} + +.form-control:disabled { + background-color: #ebebeb; + opacity: 1 +} + +.form-control::-webkit-file-upload-button { + padding: .375rem .75rem; + margin: -.375rem -.75rem; + -webkit-margin-end: .75rem; + margin-inline-end: .75rem; + color: #fff; + background-color: #444; + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: 1px; + border-radius: 0; + -webkit-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; + transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out +} + +.form-control::file-selector-button { + padding: .375rem .75rem; + margin: -.375rem -.75rem; + -webkit-margin-end: .75rem; + margin-inline-end: .75rem; + color: #fff; + background-color: #444; + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: 1px; + border-radius: 0; + transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .form-control::-webkit-file-upload-button { + -webkit-transition: none; + transition: none + } + + .form-control::file-selector-button { + transition: none + } +} + +.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button { + background-color: #414141 +} + +.form-control:hover:not(:disabled):not([readonly])::file-selector-button { + background-color: #414141 +} + +.form-control-plaintext { + display: block; + width: 100%; + padding: .375rem 0; + margin-bottom: 0; + line-height: 1.5; + color: #fff; + background-color: transparent; + border: solid transparent; + border-width: 1px 0 +} + +.form-control-plaintext:focus { + outline: 0 +} + +.form-control-plaintext.form-control-lg, .form-control-plaintext.form-control-sm { + padding-right: 0; + padding-left: 0 +} + +.form-control-sm { + min-height: calc(1.5em + .5rem + 2px); + padding: .25rem .5rem; + font-size: .875rem; + border-radius: .25rem +} + +.form-control-sm::-webkit-file-upload-button { + padding: .25rem .5rem; + margin: -.25rem -.5rem; + -webkit-margin-end: .5rem; + margin-inline-end: .5rem +} + +.form-control-sm::file-selector-button { + padding: .25rem .5rem; + margin: -.25rem -.5rem; + -webkit-margin-end: .5rem; + margin-inline-end: .5rem +} + +.form-control-lg { + min-height: calc(1.5em + 1rem + 2px); + padding: .5rem 1rem; + font-size: 1.25rem; + border-radius: .5rem +} + +.form-control-lg::-webkit-file-upload-button { + padding: .5rem 1rem; + margin: -.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end: 1rem +} + +.form-control-lg::file-selector-button { + padding: .5rem 1rem; + margin: -.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end: 1rem +} + +textarea.form-control { + min-height: calc(1.5em + .75rem + 2px) +} + +textarea.form-control-sm { + min-height: calc(1.5em + .5rem + 2px) +} + +textarea.form-control-lg { + min-height: calc(1.5em + 1rem + 2px) +} + +.form-control-color { + width: 3rem; + height: calc(1.5em + .75rem + 2px); + padding: .375rem +} + +.form-control-color:not(:disabled):not([readonly]) { + cursor: pointer +} + +.form-control-color::-moz-color-swatch { + border: 0 !important; + border-radius: .375rem +} + +.form-control-color::-webkit-color-swatch { + border-radius: .375rem +} + +.form-control-color.form-control-sm { + height: calc(1.5em + .5rem + 2px) +} + +.form-control-color.form-control-lg { + height: calc(1.5em + 1rem + 2px) +} + +.form-select { + display: block; + width: 100%; + padding: .375rem 2.25rem .375rem .75rem; + -moz-padding-start: calc(0.75rem - 3px); + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #303030; + background-color: #fff; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right .75rem center; + background-size: 16px 12px; + border: 1px solid #222; + border-radius: .375rem; + transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none +} + +@media (prefers-reduced-motion: reduce) { + .form-select { + transition: none + } +} + +.form-select:focus { + border-color: #9badbf; + outline: 0; + box-shadow: 0 0 0 .25rem rgba(55, 90, 127, .25) +} + +.form-select[multiple], .form-select[size]:not([size="1"]) { + padding-right: .75rem; + background-image: none +} + +.form-select:disabled { + background-color: #ebebeb +} + +.form-select:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 #303030 +} + +.form-select-sm { + padding-top: .25rem; + padding-bottom: .25rem; + padding-left: .5rem; + font-size: .875rem; + border-radius: .25rem +} + +.form-select-lg { + padding-top: .5rem; + padding-bottom: .5rem; + padding-left: 1rem; + font-size: 1.25rem; + border-radius: .5rem +} + +.form-check { + display: block; + min-height: 1.5rem; + padding-left: 1.5em; + margin-bottom: .125rem +} + +.form-check .form-check-input { + float: left; + margin-left: -1.5em +} + +.form-check-reverse { + padding-right: 1.5em; + padding-left: 0; + text-align: right +} + +.form-check-reverse .form-check-input { + float: right; + margin-right: -1.5em; + margin-left: 0 +} + +.form-check-input { + width: 1em; + height: 1em; + margin-top: .25em; + vertical-align: top; + background-color: #fff; + background-repeat: no-repeat; + background-position: center; + background-size: contain; + border: none; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + -webkit-print-color-adjust: exact; + color-adjust: exact; + print-color-adjust: exact +} + +.form-check-input[type=checkbox] { + border-radius: .25em +} + +.form-check-input[type=radio] { + border-radius: 50% +} + +.form-check-input:active { + filter: brightness(90%) +} + +.form-check-input:focus { + border-color: #9badbf; + outline: 0; + box-shadow: 0 0 0 .25rem rgba(55, 90, 127, .25) +} + +.form-check-input:checked { + background-color: #375a7f; + border-color: #375a7f +} + +.form-check-input:checked[type=checkbox] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e") +} + +.form-check-input:checked[type=radio] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e") +} + +.form-check-input[type=checkbox]:indeterminate { + background-color: #375a7f; + border-color: #375a7f; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e") +} + +.form-check-input:disabled { + pointer-events: none; + filter: none; + opacity: .5 +} + +.form-check-input:disabled ~ .form-check-label, .form-check-input[disabled] ~ .form-check-label { + cursor: default; + opacity: .5 +} + +.form-switch { + padding-left: 2.5em +} + +.form-switch .form-check-input { + width: 2em; + margin-left: -2.5em; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e"); + background-position: left center; + border-radius: 2em; + transition: background-position .15s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .form-switch .form-check-input { + transition: none + } +} + +.form-switch .form-check-input:focus { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%239badbf'/%3e%3c/svg%3e") +} + +.form-switch .form-check-input:checked { + background-position: right center; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e") +} + +.form-switch.form-check-reverse { + padding-right: 2.5em; + padding-left: 0 +} + +.form-switch.form-check-reverse .form-check-input { + margin-right: -2.5em; + margin-left: 0 +} + +.form-check-inline { + display: inline-block; + margin-right: 1rem +} + +.btn-check { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none +} + +.btn-check:disabled + .btn, .btn-check[disabled] + .btn { + pointer-events: none; + filter: none; + opacity: .65 +} + +.form-range { + width: 100%; + height: 1.5rem; + padding: 0; + background-color: transparent; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none +} + +.form-range:focus { + outline: 0 +} + +.form-range:focus::-webkit-slider-thumb { + box-shadow: 0 0 0 1px #222, 0 0 0 .25rem rgba(55, 90, 127, .25) +} + +.form-range:focus::-moz-range-thumb { + box-shadow: 0 0 0 1px #222, 0 0 0 .25rem rgba(55, 90, 127, .25) +} + +.form-range::-moz-focus-outer { + border: 0 +} + +.form-range::-webkit-slider-thumb { + width: 1rem; + height: 1rem; + margin-top: -.25rem; + background-color: #375a7f; + border: 0; + border-radius: 1rem; + -webkit-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; + transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; + -webkit-appearance: none; + appearance: none +} + +@media (prefers-reduced-motion: reduce) { + .form-range::-webkit-slider-thumb { + -webkit-transition: none; + transition: none + } +} + +.form-range::-webkit-slider-thumb:active { + background-color: #c3ced9 +} + +.form-range::-webkit-slider-runnable-track { + width: 100%; + height: .5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem +} + +.form-range::-moz-range-thumb { + width: 1rem; + height: 1rem; + background-color: #375a7f; + border: 0; + border-radius: 1rem; + -moz-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; + transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; + -moz-appearance: none; + appearance: none +} + +@media (prefers-reduced-motion: reduce) { + .form-range::-moz-range-thumb { + -moz-transition: none; + transition: none + } +} + +.form-range::-moz-range-thumb:active { + background-color: #c3ced9 +} + +.form-range::-moz-range-track { + width: 100%; + height: .5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem +} + +.form-range:disabled { + pointer-events: none +} + +.form-range:disabled::-webkit-slider-thumb { + background-color: #adb5bd +} + +.form-range:disabled::-moz-range-thumb { + background-color: #adb5bd +} + +.form-floating { + position: relative +} + +.form-floating > .form-control, .form-floating > .form-control-plaintext, .form-floating > .form-select { + height: calc(3.5rem + 2px); + line-height: 1.25 +} + +.form-floating > label { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + padding: 1rem .75rem; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + pointer-events: none; + border: 1px solid transparent; + transform-origin: 0 0; + transition: opacity .1s ease-in-out, transform .1s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .form-floating > label { + transition: none + } +} + +.form-floating > .form-control, .form-floating > .form-control-plaintext { + padding: 1rem .75rem +} + +.form-floating > .form-control-plaintext::-moz-placeholder, .form-floating > .form-control::-moz-placeholder { + color: transparent +} + +.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder { + color: transparent +} + +.form-floating > .form-control-plaintext:not(:-moz-placeholder-shown), .form-floating > .form-control:not(:-moz-placeholder-shown) { + padding-top: 1.625rem; + padding-bottom: .625rem +} + +.form-floating > .form-control-plaintext:focus, .form-floating > .form-control-plaintext:not(:placeholder-shown), .form-floating > .form-control:focus, .form-floating > .form-control:not(:placeholder-shown) { + padding-top: 1.625rem; + padding-bottom: .625rem +} + +.form-floating > .form-control-plaintext:-webkit-autofill, .form-floating > .form-control:-webkit-autofill { + padding-top: 1.625rem; + padding-bottom: .625rem +} + +.form-floating > .form-select { + padding-top: 1.625rem; + padding-bottom: .625rem +} + +.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label { + opacity: .65; + transform: scale(.85) translateY(-.5rem) translateX(.15rem) +} + +.form-floating > .form-control-plaintext ~ label, .form-floating > .form-control:focus ~ label, .form-floating > .form-control:not(:placeholder-shown) ~ label, .form-floating > .form-select ~ label { + opacity: .65; + transform: scale(.85) translateY(-.5rem) translateX(.15rem) +} + +.form-floating > .form-control:-webkit-autofill ~ label { + opacity: .65; + transform: scale(.85) translateY(-.5rem) translateX(.15rem) +} + +.form-floating > .form-control-plaintext ~ label { + border-width: 1px 0 +} + +.input-group { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: stretch; + width: 100% +} + +.input-group > .form-control, .input-group > .form-floating, .input-group > .form-select { + position: relative; + flex: 1 1 auto; + width: 1%; + min-width: 0 +} + +.input-group > .form-control:focus, .input-group > .form-floating:focus-within, .input-group > .form-select:focus { + z-index: 3 +} + +.input-group .btn { + position: relative; + z-index: 2 +} + +.input-group .btn:focus { + z-index: 3 +} + +.input-group-text { + display: flex; + align-items: center; + padding: .375rem .75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #adb5bd; + text-align: center; + white-space: nowrap; + background-color: #444; + border: 1px solid #222; + border-radius: .375rem +} + +.input-group-lg > .btn, .input-group-lg > .form-control, .input-group-lg > .form-select, .input-group-lg > .input-group-text { + padding: .5rem 1rem; + font-size: 1.25rem; + border-radius: .5rem +} + +.input-group-sm > .btn, .input-group-sm > .form-control, .input-group-sm > .form-select, .input-group-sm > .input-group-text { + padding: .25rem .5rem; + font-size: .875rem; + border-radius: .25rem +} + +.input-group-lg > .form-select, .input-group-sm > .form-select { + padding-right: 3rem +} + +.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3), .input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-control, .input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-select, .input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.input-group.has-validation > .dropdown-toggle:nth-last-child(n+4), .input-group.has-validation > .form-floating:nth-last-child(n+3) > .form-control, .input-group.has-validation > .form-floating:nth-last-child(n+3) > .form-select, .input-group.has-validation > :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.input-group > .form-floating:not(:first-child) > .form-control, .input-group > .form-floating:not(:first-child) > .form-select, .input-group > :not(:first-child):not(.dropdown-menu):not(.form-floating):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) { + margin-left: -1px; + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.valid-feedback { + display: none; + width: 100%; + margin-top: .25rem; + font-size: .875em; + color: #00bc8c +} + +.valid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: .25rem .5rem; + margin-top: .1rem; + font-size: .875rem; + color: #fff; + background-color: rgba(0, 188, 140, .9); + border-radius: .375rem +} + +.is-valid ~ .valid-feedback, .is-valid ~ .valid-tooltip, .was-validated :valid ~ .valid-feedback, .was-validated :valid ~ .valid-tooltip { + display: block +} + +.form-control.is-valid, .was-validated .form-control:valid { + border-color: #00bc8c; + padding-right: calc(1.5em + .75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(.375em + .1875rem) center; + background-size: calc(.75em + .375rem) calc(.75em + .375rem) +} + +.form-control.is-valid:focus, .was-validated .form-control:valid:focus { + border-color: #00bc8c; + box-shadow: 0 0 0 .25rem rgba(0, 188, 140, .25) +} + +.was-validated textarea.form-control:valid, textarea.form-control.is-valid { + padding-right: calc(1.5em + .75rem); + background-position: top calc(.375em + .1875rem) right calc(.375em + .1875rem) +} + +.form-select.is-valid, .was-validated .form-select:valid { + border-color: #00bc8c +} + +.form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size="1"], .was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size="1"] { + padding-right: 4.125rem; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-position: right .75rem center, center right 2.25rem; + background-size: 16px 12px, calc(.75em + .375rem) calc(.75em + .375rem) +} + +.form-select.is-valid:focus, .was-validated .form-select:valid:focus { + border-color: #00bc8c; + box-shadow: 0 0 0 .25rem rgba(0, 188, 140, .25) +} + +.form-control-color.is-valid, .was-validated .form-control-color:valid { + width: calc(3rem + calc(1.5em + .75rem)) +} + +.form-check-input.is-valid, .was-validated .form-check-input:valid { + border-color: #00bc8c +} + +.form-check-input.is-valid:checked, .was-validated .form-check-input:valid:checked { + background-color: #00bc8c +} + +.form-check-input.is-valid:focus, .was-validated .form-check-input:valid:focus { + box-shadow: 0 0 0 .25rem rgba(0, 188, 140, .25) +} + +.form-check-input.is-valid ~ .form-check-label, .was-validated .form-check-input:valid ~ .form-check-label { + color: #00bc8c +} + +.form-check-inline .form-check-input ~ .valid-feedback { + margin-left: .5em +} + +.input-group .form-control.is-valid, .input-group .form-select.is-valid, .was-validated .input-group .form-control:valid, .was-validated .input-group .form-select:valid { + z-index: 1 +} + +.input-group .form-control.is-valid:focus, .input-group .form-select.is-valid:focus, .was-validated .input-group .form-control:valid:focus, .was-validated .input-group .form-select:valid:focus { + z-index: 3 +} + +.invalid-feedback { + display: none; + width: 100%; + margin-top: .25rem; + font-size: .875em; + color: #e74c3c +} + +.invalid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: .25rem .5rem; + margin-top: .1rem; + font-size: .875rem; + color: #fff; + background-color: rgba(231, 76, 60, .9); + border-radius: .375rem +} + +.is-invalid ~ .invalid-feedback, .is-invalid ~ .invalid-tooltip, .was-validated :invalid ~ .invalid-feedback, .was-validated :invalid ~ .invalid-tooltip { + display: block +} + +.form-control.is-invalid, .was-validated .form-control:invalid { + border-color: #e74c3c; + padding-right: calc(1.5em + .75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(.375em + .1875rem) center; + background-size: calc(.75em + .375rem) calc(.75em + .375rem) +} + +.form-control.is-invalid:focus, .was-validated .form-control:invalid:focus { + border-color: #e74c3c; + box-shadow: 0 0 0 .25rem rgba(231, 76, 60, .25) +} + +.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid { + padding-right: calc(1.5em + .75rem); + background-position: top calc(.375em + .1875rem) right calc(.375em + .1875rem) +} + +.form-select.is-invalid, .was-validated .form-select:invalid { + border-color: #e74c3c +} + +.form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size="1"], .was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size="1"] { + padding-right: 4.125rem; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e"); + background-position: right .75rem center, center right 2.25rem; + background-size: 16px 12px, calc(.75em + .375rem) calc(.75em + .375rem) +} + +.form-select.is-invalid:focus, .was-validated .form-select:invalid:focus { + border-color: #e74c3c; + box-shadow: 0 0 0 .25rem rgba(231, 76, 60, .25) +} + +.form-control-color.is-invalid, .was-validated .form-control-color:invalid { + width: calc(3rem + calc(1.5em + .75rem)) +} + +.form-check-input.is-invalid, .was-validated .form-check-input:invalid { + border-color: #e74c3c +} + +.form-check-input.is-invalid:checked, .was-validated .form-check-input:invalid:checked { + background-color: #e74c3c +} + +.form-check-input.is-invalid:focus, .was-validated .form-check-input:invalid:focus { + box-shadow: 0 0 0 .25rem rgba(231, 76, 60, .25) +} + +.form-check-input.is-invalid ~ .form-check-label, .was-validated .form-check-input:invalid ~ .form-check-label { + color: #e74c3c +} + +.form-check-inline .form-check-input ~ .invalid-feedback { + margin-left: .5em +} + +.input-group .form-control.is-invalid, .input-group .form-select.is-invalid, .was-validated .input-group .form-control:invalid, .was-validated .input-group .form-select:invalid { + z-index: 2 +} + +.input-group .form-control.is-invalid:focus, .input-group .form-select.is-invalid:focus, .was-validated .input-group .form-control:invalid:focus, .was-validated .input-group .form-select:invalid:focus { + z-index: 3 +} + +.btn { + --bs-btn-padding-x: 0.75rem; + --bs-btn-padding-y: 0.375rem; + --bs-btn-font-family: ; + --bs-btn-font-size: 1rem; + --bs-btn-font-weight: 400; + --bs-btn-line-height: 1.5; + --bs-btn-color: #fff; + --bs-btn-bg: transparent; + --bs-btn-border-width: 1px; + --bs-btn-border-color: transparent; + --bs-btn-border-radius: 0.375rem; + --bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075); + --bs-btn-disabled-opacity: 0.65; + --bs-btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5); + display: inline-block; + padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x); + font-family: var(--bs-btn-font-family); + font-size: var(--bs-btn-font-size); + font-weight: var(--bs-btn-font-weight); + line-height: var(--bs-btn-line-height); + color: var(--bs-btn-color); + text-align: center; + text-decoration: none; + vertical-align: middle; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + border: var(--bs-btn-border-width) solid var(--bs-btn-border-color); + border-radius: var(--bs-btn-border-radius); + background-color: var(--bs-btn-bg); + transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .btn { + transition: none + } +} + +.btn:hover { + color: var(--bs-btn-hover-color); + background-color: var(--bs-btn-hover-bg); + border-color: var(--bs-btn-hover-border-color) +} + +.btn-check:focus + .btn, .btn:focus { + color: var(--bs-btn-hover-color); + background-color: var(--bs-btn-hover-bg); + border-color: var(--bs-btn-hover-border-color); + outline: 0; + box-shadow: var(--bs-btn-focus-box-shadow) +} + +.btn-check:active + .btn, .btn-check:checked + .btn, .btn.active, .btn.show, .btn:active { + color: var(--bs-btn-active-color); + background-color: var(--bs-btn-active-bg); + border-color: var(--bs-btn-active-border-color) +} + +.btn-check:active + .btn:focus, .btn-check:checked + .btn:focus, .btn.active:focus, .btn.show:focus, .btn:active:focus { + box-shadow: var(--bs-btn-focus-box-shadow) +} + +.btn.disabled, .btn:disabled, fieldset:disabled .btn { + color: var(--bs-btn-disabled-color); + pointer-events: none; + background-color: var(--bs-btn-disabled-bg); + border-color: var(--bs-btn-disabled-border-color); + opacity: var(--bs-btn-disabled-opacity) +} + +.btn-primary { + --bs-btn-color: #fff; + --bs-btn-bg: #375a7f; + --bs-btn-border-color: #375a7f; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #2f4d6c; + --bs-btn-hover-border-color: #2c4866; + --bs-btn-focus-shadow-rgb: 85, 115, 146; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #2c4866; + --bs-btn-active-border-color: #29445f; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #375a7f; + --bs-btn-disabled-border-color: #375a7f +} + +.btn-secondary { + --bs-btn-color: #fff; + --bs-btn-bg: #444; + --bs-btn-border-color: #444; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #3a3a3a; + --bs-btn-hover-border-color: #363636; + --bs-btn-focus-shadow-rgb: 96, 96, 96; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #363636; + --bs-btn-active-border-color: #333333; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #444; + --bs-btn-disabled-border-color: #444 +} + +.btn-success { + --bs-btn-color: #fff; + --bs-btn-bg: #00bc8c; + --bs-btn-border-color: #00bc8c; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #00a077; + --bs-btn-hover-border-color: #009670; + --bs-btn-focus-shadow-rgb: 38, 198, 157; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #009670; + --bs-btn-active-border-color: #008d69; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #00bc8c; + --bs-btn-disabled-border-color: #00bc8c +} + +.btn-info { + --bs-btn-color: #fff; + --bs-btn-bg: #3498db; + --bs-btn-border-color: #3498db; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #2c81ba; + --bs-btn-hover-border-color: #2a7aaf; + --bs-btn-focus-shadow-rgb: 82, 167, 224; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #2a7aaf; + --bs-btn-active-border-color: #2772a4; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #3498db; + --bs-btn-disabled-border-color: #3498db +} + +.btn-warning { + --bs-btn-color: #fff; + --bs-btn-bg: #f39c12; + --bs-btn-border-color: #f39c12; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #cf850f; + --bs-btn-hover-border-color: #c27d0e; + --bs-btn-focus-shadow-rgb: 245, 171, 54; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #c27d0e; + --bs-btn-active-border-color: #b6750e; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #f39c12; + --bs-btn-disabled-border-color: #f39c12 +} + +.btn-danger { + --bs-btn-color: #fff; + --bs-btn-bg: #e74c3c; + --bs-btn-border-color: #e74c3c; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #c44133; + --bs-btn-hover-border-color: #b93d30; + --bs-btn-focus-shadow-rgb: 235, 103, 89; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #b93d30; + --bs-btn-active-border-color: #ad392d; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #e74c3c; + --bs-btn-disabled-border-color: #e74c3c +} + +.btn-light { + --bs-btn-color: #fff; + --bs-btn-bg: #adb5bd; + --bs-btn-border-color: #adb5bd; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #939aa1; + --bs-btn-hover-border-color: #8a9197; + --bs-btn-focus-shadow-rgb: 185, 192, 199; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #8a9197; + --bs-btn-active-border-color: #82888e; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #adb5bd; + --bs-btn-disabled-border-color: #adb5bd +} + +.btn-dark { + --bs-btn-color: #fff; + --bs-btn-bg: #303030; + --bs-btn-border-color: #303030; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #4f4f4f; + --bs-btn-hover-border-color: #454545; + --bs-btn-focus-shadow-rgb: 79, 79, 79; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #595959; + --bs-btn-active-border-color: #454545; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #303030; + --bs-btn-disabled-border-color: #303030 +} + +.btn-outline-primary { + --bs-btn-color: #375a7f; + --bs-btn-border-color: #375a7f; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #375a7f; + --bs-btn-hover-border-color: #375a7f; + --bs-btn-focus-shadow-rgb: 55, 90, 127; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #375a7f; + --bs-btn-active-border-color: #375a7f; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #375a7f; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #375a7f; + --bs-gradient: none +} + +.btn-outline-secondary { + --bs-btn-color: #444; + --bs-btn-border-color: #444; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #444; + --bs-btn-hover-border-color: #444; + --bs-btn-focus-shadow-rgb: 68, 68, 68; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #444; + --bs-btn-active-border-color: #444; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #444; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #444; + --bs-gradient: none +} + +.btn-outline-success { + --bs-btn-color: #00bc8c; + --bs-btn-border-color: #00bc8c; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #00bc8c; + --bs-btn-hover-border-color: #00bc8c; + --bs-btn-focus-shadow-rgb: 0, 188, 140; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #00bc8c; + --bs-btn-active-border-color: #00bc8c; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #00bc8c; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #00bc8c; + --bs-gradient: none +} + +.btn-outline-info { + --bs-btn-color: #3498db; + --bs-btn-border-color: #3498db; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #3498db; + --bs-btn-hover-border-color: #3498db; + --bs-btn-focus-shadow-rgb: 52, 152, 219; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #3498db; + --bs-btn-active-border-color: #3498db; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #3498db; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #3498db; + --bs-gradient: none +} + +.btn-outline-warning { + --bs-btn-color: #f39c12; + --bs-btn-border-color: #f39c12; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #f39c12; + --bs-btn-hover-border-color: #f39c12; + --bs-btn-focus-shadow-rgb: 243, 156, 18; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #f39c12; + --bs-btn-active-border-color: #f39c12; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #f39c12; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #f39c12; + --bs-gradient: none +} + +.btn-outline-danger { + --bs-btn-color: #e74c3c; + --bs-btn-border-color: #e74c3c; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #e74c3c; + --bs-btn-hover-border-color: #e74c3c; + --bs-btn-focus-shadow-rgb: 231, 76, 60; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #e74c3c; + --bs-btn-active-border-color: #e74c3c; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #e74c3c; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #e74c3c; + --bs-gradient: none +} + +.btn-outline-light { + --bs-btn-color: #adb5bd; + --bs-btn-border-color: #adb5bd; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #adb5bd; + --bs-btn-hover-border-color: #adb5bd; + --bs-btn-focus-shadow-rgb: 173, 181, 189; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #adb5bd; + --bs-btn-active-border-color: #adb5bd; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #adb5bd; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #adb5bd; + --bs-gradient: none +} + +.btn-outline-dark { + --bs-btn-color: #303030; + --bs-btn-border-color: #303030; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #303030; + --bs-btn-hover-border-color: #303030; + --bs-btn-focus-shadow-rgb: 48, 48, 48; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #303030; + --bs-btn-active-border-color: #303030; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #303030; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #303030; + --bs-gradient: none +} + +.btn-link { + --bs-btn-font-weight: 400; + --bs-btn-color: var(--bs-link-color); + --bs-btn-bg: transparent; + --bs-btn-border-color: transparent; + --bs-btn-hover-color: var(--bs-link-hover-color); + --bs-btn-hover-border-color: transparent; + --bs-btn-active-color: var(--bs-link-hover-color); + --bs-btn-active-border-color: transparent; + --bs-btn-disabled-color: #888; + --bs-btn-disabled-border-color: transparent; + --bs-btn-box-shadow: none; + --bs-btn-focus-shadow-rgb: 85, 115, 146; + text-decoration: underline +} + +.btn-link:focus { + color: var(--bs-btn-color) +} + +.btn-link:hover { + color: var(--bs-btn-hover-color) +} + +.btn-group-lg > .btn, .btn-lg { + --bs-btn-padding-y: 0.5rem; + --bs-btn-padding-x: 1rem; + --bs-btn-font-size: 1.25rem; + --bs-btn-border-radius: 0.5rem +} + +.btn-group-sm > .btn, .btn-sm { + --bs-btn-padding-y: 0.25rem; + --bs-btn-padding-x: 0.5rem; + --bs-btn-font-size: 0.875rem; + --bs-btn-border-radius: 0.25rem +} + +.fade { + transition: opacity .15s linear +} + +@media (prefers-reduced-motion: reduce) { + .fade { + transition: none + } +} + +.fade:not(.show) { + opacity: 0 +} + +.collapse:not(.show) { + display: none +} + +.collapsing { + height: 0; + overflow: hidden; + transition: height .35s ease +} + +@media (prefers-reduced-motion: reduce) { + .collapsing { + transition: none + } +} + +.collapsing.collapse-horizontal { + width: 0; + height: auto; + transition: width .35s ease +} + +@media (prefers-reduced-motion: reduce) { + .collapsing.collapse-horizontal { + transition: none + } +} + +.dropdown, .dropdown-center, .dropend, .dropstart, .dropup, .dropup-center { + position: relative +} + +.dropdown-toggle { + white-space: nowrap +} + +.dropdown-toggle::after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + border-top: .3em solid; + border-right: .3em solid transparent; + border-bottom: 0; + border-left: .3em solid transparent +} + +.dropdown-toggle:empty::after { + margin-left: 0 +} + +.dropdown-menu { + --bs-dropdown-min-width: 10rem; + --bs-dropdown-padding-x: 0; + --bs-dropdown-padding-y: 0.5rem; + --bs-dropdown-spacer: 0.125rem; + --bs-dropdown-font-size: 1rem; + --bs-dropdown-color: #fff; + --bs-dropdown-bg: #222; + --bs-dropdown-border-color: #444; + --bs-dropdown-border-radius: 0.375rem; + --bs-dropdown-border-width: 1px; + --bs-dropdown-inner-border-radius: calc(0.375rem - 1px); + --bs-dropdown-divider-bg: #444; + --bs-dropdown-divider-margin-y: 0.5rem; + --bs-dropdown-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); + --bs-dropdown-link-color: #fff; + --bs-dropdown-link-hover-color: #fff; + --bs-dropdown-link-hover-bg: #375a7f; + --bs-dropdown-link-active-color: #fff; + --bs-dropdown-link-active-bg: #375a7f; + --bs-dropdown-link-disabled-color: #adb5bd; + --bs-dropdown-item-padding-x: 1rem; + --bs-dropdown-item-padding-y: 0.25rem; + --bs-dropdown-header-color: #888; + --bs-dropdown-header-padding-x: 1rem; + --bs-dropdown-header-padding-y: 0.5rem; + position: absolute; + z-index: 1000; + display: none; + min-width: var(--bs-dropdown-min-width); + padding: var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x); + margin: 0; + font-size: var(--bs-dropdown-font-size); + color: var(--bs-dropdown-color); + text-align: left; + list-style: none; + background-color: var(--bs-dropdown-bg); + background-clip: padding-box; + border: var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color); + border-radius: var(--bs-dropdown-border-radius) +} + +.dropdown-menu[data-bs-popper] { + top: 100%; + left: 0; + margin-top: var(--bs-dropdown-spacer) +} + +.dropdown-menu-start { + --bs-position: start +} + +.dropdown-menu-start[data-bs-popper] { + right: auto; + left: 0 +} + +.dropdown-menu-end { + --bs-position: end +} + +.dropdown-menu-end[data-bs-popper] { + right: 0; + left: auto +} + +@media (min-width: 576px) { + .dropdown-menu-sm-start { + --bs-position: start + } + + .dropdown-menu-sm-start[data-bs-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-sm-end { + --bs-position: end + } + + .dropdown-menu-sm-end[data-bs-popper] { + right: 0; + left: auto + } +} + +@media (min-width: 768px) { + .dropdown-menu-md-start { + --bs-position: start + } + + .dropdown-menu-md-start[data-bs-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-md-end { + --bs-position: end + } + + .dropdown-menu-md-end[data-bs-popper] { + right: 0; + left: auto + } +} + +@media (min-width: 992px) { + .dropdown-menu-lg-start { + --bs-position: start + } + + .dropdown-menu-lg-start[data-bs-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-lg-end { + --bs-position: end + } + + .dropdown-menu-lg-end[data-bs-popper] { + right: 0; + left: auto + } +} + +@media (min-width: 1200px) { + .dropdown-menu-xl-start { + --bs-position: start + } + + .dropdown-menu-xl-start[data-bs-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-xl-end { + --bs-position: end + } + + .dropdown-menu-xl-end[data-bs-popper] { + right: 0; + left: auto + } +} + +@media (min-width: 1400px) { + .dropdown-menu-xxl-start { + --bs-position: start + } + + .dropdown-menu-xxl-start[data-bs-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-xxl-end { + --bs-position: end + } + + .dropdown-menu-xxl-end[data-bs-popper] { + right: 0; + left: auto + } +} + +.dropup .dropdown-menu[data-bs-popper] { + top: auto; + bottom: 100%; + margin-top: 0; + margin-bottom: var(--bs-dropdown-spacer) +} + +.dropup .dropdown-toggle::after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + border-top: 0; + border-right: .3em solid transparent; + border-bottom: .3em solid; + border-left: .3em solid transparent +} + +.dropup .dropdown-toggle:empty::after { + margin-left: 0 +} + +.dropend .dropdown-menu[data-bs-popper] { + top: 0; + right: auto; + left: 100%; + margin-top: 0; + margin-left: var(--bs-dropdown-spacer) +} + +.dropend .dropdown-toggle::after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + border-top: .3em solid transparent; + border-right: 0; + border-bottom: .3em solid transparent; + border-left: .3em solid +} + +.dropend .dropdown-toggle:empty::after { + margin-left: 0 +} + +.dropend .dropdown-toggle::after { + vertical-align: 0 +} + +.dropstart .dropdown-menu[data-bs-popper] { + top: 0; + right: 100%; + left: auto; + margin-top: 0; + margin-right: var(--bs-dropdown-spacer) +} + +.dropstart .dropdown-toggle::after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: "" +} + +.dropstart .dropdown-toggle::after { + display: none +} + +.dropstart .dropdown-toggle::before { + display: inline-block; + margin-right: .255em; + vertical-align: .255em; + content: ""; + border-top: .3em solid transparent; + border-right: .3em solid; + border-bottom: .3em solid transparent +} + +.dropstart .dropdown-toggle:empty::after { + margin-left: 0 +} + +.dropstart .dropdown-toggle::before { + vertical-align: 0 +} + +.dropdown-divider { + height: 0; + margin: var(--bs-dropdown-divider-margin-y) 0; + overflow: hidden; + border-top: 1px solid var(--bs-dropdown-divider-bg); + opacity: 1 +} + +.dropdown-item { + display: block; + width: 100%; + padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x); + clear: both; + font-weight: 400; + color: var(--bs-dropdown-link-color); + text-align: inherit; + text-decoration: none; + white-space: nowrap; + background-color: transparent; + border: 0 +} + +.dropdown-item:focus, .dropdown-item:hover { + color: var(--bs-dropdown-link-hover-color); + background-color: var(--bs-dropdown-link-hover-bg) +} + +.dropdown-item.active, .dropdown-item:active { + color: var(--bs-dropdown-link-active-color); + text-decoration: none; + background-color: var(--bs-dropdown-link-active-bg) +} + +.dropdown-item.disabled, .dropdown-item:disabled { + color: var(--bs-dropdown-link-disabled-color); + pointer-events: none; + background-color: transparent +} + +.dropdown-menu.show { + display: block +} + +.dropdown-header { + display: block; + padding: var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x); + margin-bottom: 0; + font-size: .875rem; + color: var(--bs-dropdown-header-color); + white-space: nowrap +} + +.dropdown-item-text { + display: block; + padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x); + color: var(--bs-dropdown-link-color) +} + +.dropdown-menu-dark { + --bs-dropdown-color: #dee2e6; + --bs-dropdown-bg: #303030; + --bs-dropdown-border-color: #444; + --bs-dropdown-box-shadow: ; + --bs-dropdown-link-color: #dee2e6; + --bs-dropdown-link-hover-color: #fff; + --bs-dropdown-divider-bg: #444; + --bs-dropdown-link-hover-bg: rgba(255, 255, 255, 0.15); + --bs-dropdown-link-active-color: #fff; + --bs-dropdown-link-active-bg: #375a7f; + --bs-dropdown-link-disabled-color: #adb5bd; + --bs-dropdown-header-color: #adb5bd +} + +.btn-group, .btn-group-vertical { + position: relative; + display: inline-flex; + vertical-align: middle +} + +.btn-group-vertical > .btn, .btn-group > .btn { + position: relative; + flex: 1 1 auto +} + +.btn-group-vertical > .btn-check:checked + .btn, .btn-group-vertical > .btn-check:focus + .btn, .btn-group-vertical > .btn.active, .btn-group-vertical > .btn:active, .btn-group-vertical > .btn:focus, .btn-group-vertical > .btn:hover, .btn-group > .btn-check:checked + .btn, .btn-group > .btn-check:focus + .btn, .btn-group > .btn.active, .btn-group > .btn:active, .btn-group > .btn:focus, .btn-group > .btn:hover { + z-index: 1 +} + +.btn-toolbar { + display: flex; + flex-wrap: wrap; + justify-content: flex-start +} + +.btn-toolbar .input-group { + width: auto +} + +.btn-group { + border-radius: .375rem +} + +.btn-group > .btn-group:not(:first-child), .btn-group > .btn:not(:first-child) { + margin-left: -1px +} + +.btn-group > .btn-group:not(:last-child) > .btn, .btn-group > .btn.dropdown-toggle-split:first-child, .btn-group > .btn:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.btn-group > .btn-group:not(:first-child) > .btn, .btn-group > .btn:nth-child(n+3), .btn-group > :not(.btn-check) + .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.dropdown-toggle-split { + padding-right: .5625rem; + padding-left: .5625rem +} + +.dropdown-toggle-split::after, .dropend .dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after { + margin-left: 0 +} + +.dropstart .dropdown-toggle-split::before { + margin-right: 0 +} + +.btn-group-sm > .btn + .dropdown-toggle-split, .btn-sm + .dropdown-toggle-split { + padding-right: .375rem; + padding-left: .375rem +} + +.btn-group-lg > .btn + .dropdown-toggle-split, .btn-lg + .dropdown-toggle-split { + padding-right: .75rem; + padding-left: .75rem +} + +.btn-group-vertical { + flex-direction: column; + align-items: flex-start; + justify-content: center +} + +.btn-group-vertical > .btn, .btn-group-vertical > .btn-group { + width: 100% +} + +.btn-group-vertical > .btn-group:not(:first-child), .btn-group-vertical > .btn:not(:first-child) { + margin-top: -1px +} + +.btn-group-vertical > .btn-group:not(:last-child) > .btn, .btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0 +} + +.btn-group-vertical > .btn-group:not(:first-child) > .btn, .btn-group-vertical > .btn ~ .btn { + border-top-left-radius: 0; + border-top-right-radius: 0 +} + +.nav { + --bs-nav-link-padding-x: 2rem; + --bs-nav-link-padding-y: 0.5rem; + --bs-nav-link-font-weight: ; + --bs-nav-link-color: var(--bs-link-color); + --bs-nav-link-hover-color: var(--bs-link-hover-color); + --bs-nav-link-disabled-color: #adb5bd; + display: flex; + flex-wrap: wrap; + padding-left: 0; + margin-bottom: 0; + list-style: none +} + +.nav-link { + display: block; + padding: var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x); + font-size: var(--bs-nav-link-font-size); + font-weight: var(--bs-nav-link-font-weight); + color: var(--bs-nav-link-color); + text-decoration: none; + transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .nav-link { + transition: none + } +} + +.nav-link:focus, .nav-link:hover { + color: var(--bs-nav-link-hover-color) +} + +.nav-link.disabled { + color: var(--bs-nav-link-disabled-color); + pointer-events: none; + cursor: default +} + +.nav-tabs { + --bs-nav-tabs-border-width: 1px; + --bs-nav-tabs-border-color: #444; + --bs-nav-tabs-border-radius: 0.375rem; + --bs-nav-tabs-link-hover-border-color: #444 #444 transparent; + --bs-nav-tabs-link-active-color: #fff; + --bs-nav-tabs-link-active-bg: #222; + --bs-nav-tabs-link-active-border-color: #444 #444 transparent; + border-bottom: var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color) +} + +.nav-tabs .nav-link { + margin-bottom: calc(var(--bs-nav-tabs-border-width) * -1); + background: 0 0; + border: var(--bs-nav-tabs-border-width) solid transparent; + border-top-left-radius: var(--bs-nav-tabs-border-radius); + border-top-right-radius: var(--bs-nav-tabs-border-radius) +} + +.nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover { + isolation: isolate; + border-color: var(--bs-nav-tabs-link-hover-border-color) +} + +.nav-tabs .nav-link.disabled, .nav-tabs .nav-link:disabled { + color: var(--bs-nav-link-disabled-color); + background-color: transparent; + border-color: transparent +} + +.nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active { + color: var(--bs-nav-tabs-link-active-color); + background-color: var(--bs-nav-tabs-link-active-bg); + border-color: var(--bs-nav-tabs-link-active-border-color) +} + +.nav-tabs .dropdown-menu { + margin-top: calc(var(--bs-nav-tabs-border-width) * -1); + border-top-left-radius: 0; + border-top-right-radius: 0 +} + +.nav-pills { + --bs-nav-pills-border-radius: 0.375rem; + --bs-nav-pills-link-active-color: #fff; + --bs-nav-pills-link-active-bg: #375a7f +} + +.nav-pills .nav-link { + background: 0 0; + border: 0; + border-radius: var(--bs-nav-pills-border-radius) +} + +.nav-pills .nav-link:disabled { + color: var(--bs-nav-link-disabled-color); + background-color: transparent; + border-color: transparent +} + +.nav-pills .nav-link.active, .nav-pills .show > .nav-link { + color: var(--bs-nav-pills-link-active-color); + background-color: var(--bs-nav-pills-link-active-bg) +} + +.nav-fill .nav-item, .nav-fill > .nav-link { + flex: 1 1 auto; + text-align: center +} + +.nav-justified .nav-item, .nav-justified > .nav-link { + flex-basis: 0; + flex-grow: 1; + text-align: center +} + +.nav-fill .nav-item .nav-link, .nav-justified .nav-item .nav-link { + width: 100% +} + +.tab-content > .tab-pane { + display: none +} + +.tab-content > .active { + display: block +} + +.navbar { + --bs-navbar-padding-x: 0; + --bs-navbar-padding-y: 1rem; + --bs-navbar-color: rgba(34, 34, 34, 0.7); + --bs-navbar-hover-color: #222; + --bs-navbar-disabled-color: rgba(0, 0, 0, 0.3); + --bs-navbar-active-color: #222; + --bs-navbar-brand-padding-y: 0.3125rem; + --bs-navbar-brand-margin-end: 1rem; + --bs-navbar-brand-font-size: 1.25rem; + --bs-navbar-brand-color: #222; + --bs-navbar-brand-hover-color: #222; + --bs-navbar-nav-link-padding-x: 0.5rem; + --bs-navbar-toggler-padding-y: 0.25rem; + --bs-navbar-toggler-padding-x: 0.75rem; + --bs-navbar-toggler-font-size: 1.25rem; + --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2834, 34, 34, 0.7%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); + --bs-navbar-toggler-border-color: rgba(34, 34, 34, 0.1); + --bs-navbar-toggler-border-radius: 0.375rem; + --bs-navbar-toggler-focus-width: 0.25rem; + --bs-navbar-toggler-transition: box-shadow 0.15s ease-in-out; + position: relative; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding: var(--bs-navbar-padding-y) var(--bs-navbar-padding-x) +} + +.navbar > .container, .navbar > .container-fluid, .navbar > .container-lg, .navbar > .container-md, .navbar > .container-sm, .navbar > .container-xl, .navbar > .container-xxl { + display: flex; + flex-wrap: inherit; + align-items: center; + justify-content: space-between +} + +.navbar-brand { + padding-top: var(--bs-navbar-brand-padding-y); + padding-bottom: var(--bs-navbar-brand-padding-y); + margin-right: var(--bs-navbar-brand-margin-end); + font-size: var(--bs-navbar-brand-font-size); + color: var(--bs-navbar-brand-color); + text-decoration: none; + white-space: nowrap +} + +.navbar-brand:focus, .navbar-brand:hover { + color: var(--bs-navbar-brand-hover-color) +} + +.navbar-nav { + --bs-nav-link-padding-x: 0; + --bs-nav-link-padding-y: 0.5rem; + --bs-nav-link-font-weight: ; + --bs-nav-link-color: var(--bs-navbar-color); + --bs-nav-link-hover-color: var(--bs-navbar-hover-color); + --bs-nav-link-disabled-color: var(--bs-navbar-disabled-color); + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + list-style: none +} + +.navbar-nav .nav-link.active, .navbar-nav .show > .nav-link { + color: var(--bs-navbar-active-color) +} + +.navbar-nav .dropdown-menu { + position: static +} + +.navbar-text { + padding-top: .5rem; + padding-bottom: .5rem; + color: var(--bs-navbar-color) +} + +.navbar-text a, .navbar-text a:focus, .navbar-text a:hover { + color: var(--bs-navbar-active-color) +} + +.navbar-collapse { + flex-basis: 100%; + flex-grow: 1; + align-items: center +} + +.navbar-toggler { + padding: var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x); + font-size: var(--bs-navbar-toggler-font-size); + line-height: 1; + color: var(--bs-navbar-color); + background-color: transparent; + border: var(--bs-border-width) solid var(--bs-navbar-toggler-border-color); + border-radius: var(--bs-navbar-toggler-border-radius); + transition: var(--bs-navbar-toggler-transition) +} + +@media (prefers-reduced-motion: reduce) { + .navbar-toggler { + transition: none + } +} + +.navbar-toggler:hover { + text-decoration: none +} + +.navbar-toggler:focus { + text-decoration: none; + outline: 0; + box-shadow: 0 0 0 var(--bs-navbar-toggler-focus-width) +} + +.navbar-toggler-icon { + display: inline-block; + width: 1.5em; + height: 1.5em; + vertical-align: middle; + background-image: var(--bs-navbar-toggler-icon-bg); + background-repeat: no-repeat; + background-position: center; + background-size: 100% +} + +.navbar-nav-scroll { + max-height: var(--bs-scroll-height, 75vh); + overflow-y: auto +} + +@media (min-width: 576px) { + .navbar-expand-sm { + flex-wrap: nowrap; + justify-content: flex-start + } + + .navbar-expand-sm .navbar-nav { + flex-direction: row + } + + .navbar-expand-sm .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-sm .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x) + } + + .navbar-expand-sm .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-sm .navbar-collapse { + display: flex !important; + flex-basis: auto + } + + .navbar-expand-sm .navbar-toggler { + display: none + } + + .navbar-expand-sm .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + transition: none + } + + .navbar-expand-sm .offcanvas .offcanvas-header { + display: none + } + + .navbar-expand-sm .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible + } +} + +@media (min-width: 768px) { + .navbar-expand-md { + flex-wrap: nowrap; + justify-content: flex-start + } + + .navbar-expand-md .navbar-nav { + flex-direction: row + } + + .navbar-expand-md .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-md .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x) + } + + .navbar-expand-md .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-md .navbar-collapse { + display: flex !important; + flex-basis: auto + } + + .navbar-expand-md .navbar-toggler { + display: none + } + + .navbar-expand-md .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + transition: none + } + + .navbar-expand-md .offcanvas .offcanvas-header { + display: none + } + + .navbar-expand-md .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible + } +} + +@media (min-width: 992px) { + .navbar-expand-lg { + flex-wrap: nowrap; + justify-content: flex-start + } + + .navbar-expand-lg .navbar-nav { + flex-direction: row + } + + .navbar-expand-lg .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-lg .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x) + } + + .navbar-expand-lg .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-lg .navbar-collapse { + display: flex !important; + flex-basis: auto + } + + .navbar-expand-lg .navbar-toggler { + display: none + } + + .navbar-expand-lg .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + transition: none + } + + .navbar-expand-lg .offcanvas .offcanvas-header { + display: none + } + + .navbar-expand-lg .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible + } +} + +@media (min-width: 1200px) { + .navbar-expand-xl { + flex-wrap: nowrap; + justify-content: flex-start + } + + .navbar-expand-xl .navbar-nav { + flex-direction: row + } + + .navbar-expand-xl .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-xl .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x) + } + + .navbar-expand-xl .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-xl .navbar-collapse { + display: flex !important; + flex-basis: auto + } + + .navbar-expand-xl .navbar-toggler { + display: none + } + + .navbar-expand-xl .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + transition: none + } + + .navbar-expand-xl .offcanvas .offcanvas-header { + display: none + } + + .navbar-expand-xl .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible + } +} + +@media (min-width: 1400px) { + .navbar-expand-xxl { + flex-wrap: nowrap; + justify-content: flex-start + } + + .navbar-expand-xxl .navbar-nav { + flex-direction: row + } + + .navbar-expand-xxl .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-xxl .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x) + } + + .navbar-expand-xxl .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-xxl .navbar-collapse { + display: flex !important; + flex-basis: auto + } + + .navbar-expand-xxl .navbar-toggler { + display: none + } + + .navbar-expand-xxl .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + transition: none + } + + .navbar-expand-xxl .offcanvas .offcanvas-header { + display: none + } + + .navbar-expand-xxl .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible + } +} + +.navbar-expand { + flex-wrap: nowrap; + justify-content: flex-start +} + +.navbar-expand .navbar-nav { + flex-direction: row +} + +.navbar-expand .navbar-nav .dropdown-menu { + position: absolute +} + +.navbar-expand .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x) +} + +.navbar-expand .navbar-nav-scroll { + overflow: visible +} + +.navbar-expand .navbar-collapse { + display: flex !important; + flex-basis: auto +} + +.navbar-expand .navbar-toggler { + display: none +} + +.navbar-expand .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + transition: none +} + +.navbar-expand .offcanvas .offcanvas-header { + display: none +} + +.navbar-expand .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible +} + +.navbar-dark { + --bs-navbar-color: rgba(255, 255, 255, 0.6); + --bs-navbar-hover-color: #fff; + --bs-navbar-disabled-color: rgba(255, 255, 255, 0.25); + --bs-navbar-active-color: #fff; + --bs-navbar-brand-color: #fff; + --bs-navbar-brand-hover-color: #fff; + --bs-navbar-toggler-border-color: rgba(255, 255, 255, 0.1); + --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.6%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") +} + +.card { + --bs-card-spacer-y: 1rem; + --bs-card-spacer-x: 1rem; + --bs-card-title-spacer-y: 0.5rem; + --bs-card-border-width: 1px; + --bs-card-border-color: var(--bs-border-color-translucent); + --bs-card-border-radius: 0.375rem; + --bs-card-box-shadow: ; + --bs-card-inner-border-radius: calc(0.375rem - 1px); + --bs-card-cap-padding-y: 0.5rem; + --bs-card-cap-padding-x: 1rem; + --bs-card-cap-bg: #444; + --bs-card-cap-color: ; + --bs-card-height: ; + --bs-card-color: ; + --bs-card-bg: #303030; + --bs-card-img-overlay-padding: 1rem; + --bs-card-group-margin: 0.75rem; + position: relative; + display: flex; + flex-direction: column; + min-width: 0; + height: var(--bs-card-height); + word-wrap: break-word; + background-color: var(--bs-card-bg); + background-clip: border-box; + border: var(--bs-card-border-width) solid var(--bs-card-border-color); + border-radius: var(--bs-card-border-radius) +} + +.card > hr { + margin-right: 0; + margin-left: 0 +} + +.card > .list-group { + border-top: inherit; + border-bottom: inherit +} + +.card > .list-group:first-child { + border-top-width: 0; + border-top-left-radius: var(--bs-card-inner-border-radius); + border-top-right-radius: var(--bs-card-inner-border-radius) +} + +.card > .list-group:last-child { + border-bottom-width: 0; + border-bottom-right-radius: var(--bs-card-inner-border-radius); + border-bottom-left-radius: var(--bs-card-inner-border-radius) +} + +.card > .card-header + .list-group, .card > .list-group + .card-footer { + border-top: 0 +} + +.card-body { + flex: 1 1 auto; + padding: var(--bs-card-spacer-y) var(--bs-card-spacer-x); + color: var(--bs-card-color) +} + +.card-title { + margin-bottom: var(--bs-card-title-spacer-y) +} + +.card-subtitle { + margin-top: calc(-.5 * var(--bs-card-title-spacer-y)); + margin-bottom: 0 +} + +.card-text:last-child { + margin-bottom: 0 +} + +.card-link + .card-link { + margin-left: var(--bs-card-spacer-x) +} + +.card-header { + padding: var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x); + margin-bottom: 0; + color: var(--bs-card-cap-color); + background-color: var(--bs-card-cap-bg); + border-bottom: var(--bs-card-border-width) solid var(--bs-card-border-color) +} + +.card-header:first-child { + border-radius: var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0 +} + +.card-footer { + padding: var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x); + color: var(--bs-card-cap-color); + background-color: var(--bs-card-cap-bg); + border-top: var(--bs-card-border-width) solid var(--bs-card-border-color) +} + +.card-footer:last-child { + border-radius: 0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) +} + +.card-header-tabs { + margin-right: calc(-.5 * var(--bs-card-cap-padding-x)); + margin-bottom: calc(-1 * var(--bs-card-cap-padding-y)); + margin-left: calc(-.5 * var(--bs-card-cap-padding-x)); + border-bottom: 0 +} + +.card-header-tabs .nav-link.active { + background-color: var(--bs-card-bg); + border-bottom-color: var(--bs-card-bg) +} + +.card-header-pills { + margin-right: calc(-.5 * var(--bs-card-cap-padding-x)); + margin-left: calc(-.5 * var(--bs-card-cap-padding-x)) +} + +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: var(--bs-card-img-overlay-padding); + border-radius: var(--bs-card-inner-border-radius) +} + +.card-img, .card-img-bottom, .card-img-top { + width: 100% +} + +.card-img, .card-img-top { + border-top-left-radius: var(--bs-card-inner-border-radius); + border-top-right-radius: var(--bs-card-inner-border-radius) +} + +.card-img, .card-img-bottom { + border-bottom-right-radius: var(--bs-card-inner-border-radius); + border-bottom-left-radius: var(--bs-card-inner-border-radius) +} + +.card-group > .card { + margin-bottom: var(--bs-card-group-margin) +} + +@media (min-width: 576px) { + .card-group { + display: flex; + flex-flow: row wrap + } + + .card-group > .card { + flex: 1 0 0%; + margin-bottom: 0 + } + + .card-group > .card + .card { + margin-left: 0; + border-left: 0 + } + + .card-group > .card:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 + } + + .card-group > .card:not(:last-child) .card-header, .card-group > .card:not(:last-child) .card-img-top { + border-top-right-radius: 0 + } + + .card-group > .card:not(:last-child) .card-footer, .card-group > .card:not(:last-child) .card-img-bottom { + border-bottom-right-radius: 0 + } + + .card-group > .card:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0 + } + + .card-group > .card:not(:first-child) .card-header, .card-group > .card:not(:first-child) .card-img-top { + border-top-left-radius: 0 + } + + .card-group > .card:not(:first-child) .card-footer, .card-group > .card:not(:first-child) .card-img-bottom { + border-bottom-left-radius: 0 + } +} + +.accordion { + --bs-accordion-color: #fff; + --bs-accordion-bg: #222; + --bs-accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease; + --bs-accordion-border-color: var(--bs-border-color); + --bs-accordion-border-width: 1px; + --bs-accordion-border-radius: 0.375rem; + --bs-accordion-inner-border-radius: calc(0.375rem - 1px); + --bs-accordion-btn-padding-x: 1.25rem; + --bs-accordion-btn-padding-y: 1rem; + --bs-accordion-btn-color: var(--bs-body-color); + --bs-accordion-btn-bg: var(--bs-accordion-bg); + --bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='var%28--bs-body-color%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + --bs-accordion-btn-icon-width: 1.25rem; + --bs-accordion-btn-icon-transform: rotate(-180deg); + --bs-accordion-btn-icon-transition: transform 0.2s ease-in-out; + --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23325172'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + --bs-accordion-btn-focus-border-color: #9badbf; + --bs-accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(55, 90, 127, 0.25); + --bs-accordion-body-padding-x: 1.25rem; + --bs-accordion-body-padding-y: 1rem; + --bs-accordion-active-color: #325172; + --bs-accordion-active-bg: #ebeff2 +} + +.accordion-button { + position: relative; + display: flex; + align-items: center; + width: 100%; + padding: var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x); + font-size: 1rem; + color: var(--bs-accordion-btn-color); + text-align: left; + background-color: var(--bs-accordion-btn-bg); + border: 0; + border-radius: 0; + overflow-anchor: none; + transition: var(--bs-accordion-transition) +} + +@media (prefers-reduced-motion: reduce) { + .accordion-button { + transition: none + } +} + +.accordion-button:not(.collapsed) { + color: var(--bs-accordion-active-color); + background-color: var(--bs-accordion-active-bg); + box-shadow: inset 0 calc(var(--bs-accordion-border-width) * -1) 0 var(--bs-accordion-border-color) +} + +.accordion-button:not(.collapsed)::after { + background-image: var(--bs-accordion-btn-active-icon); + transform: var(--bs-accordion-btn-icon-transform) +} + +.accordion-button::after { + flex-shrink: 0; + width: var(--bs-accordion-btn-icon-width); + height: var(--bs-accordion-btn-icon-width); + margin-left: auto; + content: ""; + background-image: var(--bs-accordion-btn-icon); + background-repeat: no-repeat; + background-size: var(--bs-accordion-btn-icon-width); + transition: var(--bs-accordion-btn-icon-transition) +} + +@media (prefers-reduced-motion: reduce) { + .accordion-button::after { + transition: none + } +} + +.accordion-button:hover { + z-index: 2 +} + +.accordion-button:focus { + z-index: 3; + border-color: var(--bs-accordion-btn-focus-border-color); + outline: 0; + box-shadow: var(--bs-accordion-btn-focus-box-shadow) +} + +.accordion-header { + margin-bottom: 0 +} + +.accordion-item { + color: var(--bs-accordion-color); + background-color: var(--bs-accordion-bg); + border: var(--bs-accordion-border-width) solid var(--bs-accordion-border-color) +} + +.accordion-item:first-of-type { + border-top-left-radius: var(--bs-accordion-border-radius); + border-top-right-radius: var(--bs-accordion-border-radius) +} + +.accordion-item:first-of-type .accordion-button { + border-top-left-radius: var(--bs-accordion-inner-border-radius); + border-top-right-radius: var(--bs-accordion-inner-border-radius) +} + +.accordion-item:not(:first-of-type) { + border-top: 0 +} + +.accordion-item:last-of-type { + border-bottom-right-radius: var(--bs-accordion-border-radius); + border-bottom-left-radius: var(--bs-accordion-border-radius) +} + +.accordion-item:last-of-type .accordion-button.collapsed { + border-bottom-right-radius: var(--bs-accordion-inner-border-radius); + border-bottom-left-radius: var(--bs-accordion-inner-border-radius) +} + +.accordion-item:last-of-type .accordion-collapse { + border-bottom-right-radius: var(--bs-accordion-border-radius); + border-bottom-left-radius: var(--bs-accordion-border-radius) +} + +.accordion-body { + padding: var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x) +} + +.accordion-flush .accordion-collapse { + border-width: 0 +} + +.accordion-flush .accordion-item { + border-right: 0; + border-left: 0; + border-radius: 0 +} + +.accordion-flush .accordion-item:first-child { + border-top: 0 +} + +.accordion-flush .accordion-item:last-child { + border-bottom: 0 +} + +.accordion-flush .accordion-item .accordion-button { + border-radius: 0 +} + +.breadcrumb { + --bs-breadcrumb-padding-x: 0.75rem; + --bs-breadcrumb-padding-y: 0.375rem; + --bs-breadcrumb-margin-bottom: 1rem; + --bs-breadcrumb-bg: #444; + --bs-breadcrumb-border-radius: 0.25rem; + --bs-breadcrumb-divider-color: #888; + --bs-breadcrumb-item-padding-x: 0.5rem; + --bs-breadcrumb-item-active-color: #888; + display: flex; + flex-wrap: wrap; + padding: var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x); + margin-bottom: var(--bs-breadcrumb-margin-bottom); + font-size: var(--bs-breadcrumb-font-size); + list-style: none; + background-color: var(--bs-breadcrumb-bg); + border-radius: var(--bs-breadcrumb-border-radius) +} + +.breadcrumb-item + .breadcrumb-item { + padding-left: var(--bs-breadcrumb-item-padding-x) +} + +.breadcrumb-item + .breadcrumb-item::before { + float: left; + padding-right: var(--bs-breadcrumb-item-padding-x); + color: var(--bs-breadcrumb-divider-color); + content: var(--bs-breadcrumb-divider, "/") +} + +.breadcrumb-item.active { + color: var(--bs-breadcrumb-item-active-color) +} + +.pagination { + --bs-pagination-padding-x: 0.75rem; + --bs-pagination-padding-y: 0.375rem; + --bs-pagination-font-size: 1rem; + --bs-pagination-color: #fff; + --bs-pagination-bg: #00bc8c; + --bs-pagination-border-width: 0; + --bs-pagination-border-color: transparent; + --bs-pagination-border-radius: 0.375rem; + --bs-pagination-hover-color: #fff; + --bs-pagination-hover-bg: #00efb2; + --bs-pagination-hover-border-color: transparent; + --bs-pagination-focus-color: var(--bs-link-hover-color); + --bs-pagination-focus-bg: #ebebeb; + --bs-pagination-focus-box-shadow: 0 0 0 0.25rem rgba(55, 90, 127, 0.25); + --bs-pagination-active-color: #fff; + --bs-pagination-active-bg: #00efb2; + --bs-pagination-active-border-color: transparent; + --bs-pagination-disabled-color: #fff; + --bs-pagination-disabled-bg: #007053; + --bs-pagination-disabled-border-color: transparent; + display: flex; + padding-left: 0; + list-style: none +} + +.page-link { + position: relative; + display: block; + padding: var(--bs-pagination-padding-y) var(--bs-pagination-padding-x); + font-size: var(--bs-pagination-font-size); + color: var(--bs-pagination-color); + text-decoration: none; + background-color: var(--bs-pagination-bg); + border: var(--bs-pagination-border-width) solid var(--bs-pagination-border-color); + transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .page-link { + transition: none + } +} + +.page-link:hover { + z-index: 2; + color: var(--bs-pagination-hover-color); + background-color: var(--bs-pagination-hover-bg); + border-color: var(--bs-pagination-hover-border-color) +} + +.page-link:focus { + z-index: 3; + color: var(--bs-pagination-focus-color); + background-color: var(--bs-pagination-focus-bg); + outline: 0; + box-shadow: var(--bs-pagination-focus-box-shadow) +} + +.active > .page-link, .page-link.active { + z-index: 3; + color: var(--bs-pagination-active-color); + background-color: var(--bs-pagination-active-bg); + border-color: var(--bs-pagination-active-border-color) +} + +.disabled > .page-link, .page-link.disabled { + color: var(--bs-pagination-disabled-color); + pointer-events: none; + background-color: var(--bs-pagination-disabled-bg); + border-color: var(--bs-pagination-disabled-border-color) +} + +.page-item:not(:first-child) .page-link { + margin-left: 0 +} + +.page-item:first-child .page-link { + border-top-left-radius: var(--bs-pagination-border-radius); + border-bottom-left-radius: var(--bs-pagination-border-radius) +} + +.page-item:last-child .page-link { + border-top-right-radius: var(--bs-pagination-border-radius); + border-bottom-right-radius: var(--bs-pagination-border-radius) +} + +.pagination-lg { + --bs-pagination-padding-x: 1.5rem; + --bs-pagination-padding-y: 0.75rem; + --bs-pagination-font-size: 1.25rem; + --bs-pagination-border-radius: 0.5rem +} + +.pagination-sm { + --bs-pagination-padding-x: 0.5rem; + --bs-pagination-padding-y: 0.25rem; + --bs-pagination-font-size: 0.875rem; + --bs-pagination-border-radius: 0.25rem +} + +.badge { + --bs-badge-padding-x: 0.65em; + --bs-badge-padding-y: 0.35em; + --bs-badge-font-size: 0.75em; + --bs-badge-font-weight: 700; + --bs-badge-color: #fff; + --bs-badge-border-radius: 0.375rem; + display: inline-block; + padding: var(--bs-badge-padding-y) var(--bs-badge-padding-x); + font-size: var(--bs-badge-font-size); + font-weight: var(--bs-badge-font-weight); + line-height: 1; + color: var(--bs-badge-color); + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: var(--bs-badge-border-radius) +} + +.badge:empty { + display: none +} + +.btn .badge { + position: relative; + top: -1px +} + +.alert { + --bs-alert-bg: transparent; + --bs-alert-padding-x: 1rem; + --bs-alert-padding-y: 1rem; + --bs-alert-margin-bottom: 1rem; + --bs-alert-color: inherit; + --bs-alert-border-color: transparent; + --bs-alert-border: 1px solid var(--bs-alert-border-color); + --bs-alert-border-radius: 0.375rem; + position: relative; + padding: var(--bs-alert-padding-y) var(--bs-alert-padding-x); + margin-bottom: var(--bs-alert-margin-bottom); + color: var(--bs-alert-color); + background-color: var(--bs-alert-bg); + border: var(--bs-alert-border); + border-radius: var(--bs-alert-border-radius) +} + +.alert-heading { + color: inherit +} + +.alert-link { + font-weight: 700 +} + +.alert-dismissible { + padding-right: 3rem +} + +.alert-dismissible .btn-close { + position: absolute; + top: 0; + right: 0; + z-index: 2; + padding: 1.25rem 1rem +} + +.alert-primary { + --bs-alert-color: #21364c; + --bs-alert-bg: #d7dee5; + --bs-alert-border-color: #c3ced9 +} + +.alert-primary .alert-link { + color: #1a2b3d +} + +.alert-secondary { + --bs-alert-color: #292929; + --bs-alert-bg: #dadada; + --bs-alert-border-color: #c7c7c7 +} + +.alert-secondary .alert-link { + color: #212121 +} + +.alert-success { + --bs-alert-color: #007154; + --bs-alert-bg: #ccf2e8; + --bs-alert-border-color: #b3ebdd +} + +.alert-success .alert-link { + color: #005a43 +} + +.alert-info { + --bs-alert-color: #1f5b83; + --bs-alert-bg: #d6eaf8; + --bs-alert-border-color: #c2e0f4 +} + +.alert-info .alert-link { + color: #194969 +} + +.alert-warning { + --bs-alert-color: #925e0b; + --bs-alert-bg: #fdebd0; + --bs-alert-border-color: #fbe1b8 +} + +.alert-warning .alert-link { + color: #754b09 +} + +.alert-danger { + --bs-alert-color: #8b2e24; + --bs-alert-bg: #fadbd8; + --bs-alert-border-color: #f8c9c5 +} + +.alert-danger .alert-link { + color: #6f251d +} + +.alert-light { + --bs-alert-color: #686d71; + --bs-alert-bg: #eff0f2; + --bs-alert-border-color: #e6e9eb +} + +.alert-light .alert-link { + color: #53575a +} + +.alert-dark { + --bs-alert-color: #1d1d1d; + --bs-alert-bg: #d6d6d6; + --bs-alert-border-color: #c1c1c1 +} + +.alert-dark .alert-link { + color: #171717 +} + +@-webkit-keyframes progress-bar-stripes { + 0% { + background-position-x: 1rem + } +} + +@keyframes progress-bar-stripes { + 0% { + background-position-x: 1rem + } +} + +.progress { + --bs-progress-height: 1rem; + --bs-progress-font-size: 0.75rem; + --bs-progress-bg: #444; + --bs-progress-border-radius: 0.375rem; + --bs-progress-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075); + --bs-progress-bar-color: #fff; + --bs-progress-bar-bg: #375a7f; + --bs-progress-bar-transition: width 0.6s ease; + display: flex; + height: var(--bs-progress-height); + overflow: hidden; + font-size: var(--bs-progress-font-size); + background-color: var(--bs-progress-bg); + border-radius: var(--bs-progress-border-radius) +} + +.progress-bar { + display: flex; + flex-direction: column; + justify-content: center; + overflow: hidden; + color: var(--bs-progress-bar-color); + text-align: center; + white-space: nowrap; + background-color: var(--bs-progress-bar-bg); + transition: var(--bs-progress-bar-transition) +} + +@media (prefers-reduced-motion: reduce) { + .progress-bar { + transition: none + } +} + +.progress-bar-striped { + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-size: var(--bs-progress-height) var(--bs-progress-height) +} + +.progress-bar-animated { + -webkit-animation: 1s linear infinite progress-bar-stripes; + animation: 1s linear infinite progress-bar-stripes +} + +@media (prefers-reduced-motion: reduce) { + .progress-bar-animated { + -webkit-animation: none; + animation: none + } +} + +.list-group { + --bs-list-group-color: #fff; + --bs-list-group-bg: #303030; + --bs-list-group-border-color: #444; + --bs-list-group-border-width: 1px; + --bs-list-group-border-radius: 0.375rem; + --bs-list-group-item-padding-x: 1rem; + --bs-list-group-item-padding-y: 0.5rem; + --bs-list-group-action-color: #444; + --bs-list-group-action-hover-color: #fff; + --bs-list-group-action-hover-bg: #444; + --bs-list-group-action-active-color: #fff; + --bs-list-group-action-active-bg: #222; + --bs-list-group-disabled-color: #888; + --bs-list-group-disabled-bg: #303030; + --bs-list-group-active-color: #fff; + --bs-list-group-active-bg: #375a7f; + --bs-list-group-active-border-color: #375a7f; + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + border-radius: var(--bs-list-group-border-radius) +} + +.list-group-numbered { + list-style-type: none; + counter-reset: section +} + +.list-group-numbered > .list-group-item::before { + content: counters(section, ".") ". "; + counter-increment: section +} + +.list-group-item-action { + width: 100%; + color: var(--bs-list-group-action-color); + text-align: inherit +} + +.list-group-item-action:focus, .list-group-item-action:hover { + z-index: 1; + color: var(--bs-list-group-action-hover-color); + text-decoration: none; + background-color: var(--bs-list-group-action-hover-bg) +} + +.list-group-item-action:active { + color: var(--bs-list-group-action-active-color); + background-color: var(--bs-list-group-action-active-bg) +} + +.list-group-item { + position: relative; + display: block; + padding: var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x); + color: var(--bs-list-group-color); + text-decoration: none; + background-color: var(--bs-list-group-bg); + border: var(--bs-list-group-border-width) solid var(--bs-list-group-border-color) +} + +.list-group-item:first-child { + border-top-left-radius: inherit; + border-top-right-radius: inherit +} + +.list-group-item:last-child { + border-bottom-right-radius: inherit; + border-bottom-left-radius: inherit +} + +.list-group-item.disabled, .list-group-item:disabled { + color: var(--bs-list-group-disabled-color); + pointer-events: none; + background-color: var(--bs-list-group-disabled-bg) +} + +.list-group-item.active { + z-index: 2; + color: var(--bs-list-group-active-color); + background-color: var(--bs-list-group-active-bg); + border-color: var(--bs-list-group-active-border-color) +} + +.list-group-item + .list-group-item { + border-top-width: 0 +} + +.list-group-item + .list-group-item.active { + margin-top: calc(var(--bs-list-group-border-width) * -1); + border-top-width: var(--bs-list-group-border-width) +} + +.list-group-horizontal { + flex-direction: row +} + +.list-group-horizontal > .list-group-item:first-child { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0 +} + +.list-group-horizontal > .list-group-item:last-child { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0 +} + +.list-group-horizontal > .list-group-item.active { + margin-top: 0 +} + +.list-group-horizontal > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0 +} + +.list-group-horizontal > .list-group-item + .list-group-item.active { + margin-left: calc(var(--bs-list-group-border-width) * -1); + border-left-width: var(--bs-list-group-border-width) +} + +@media (min-width: 576px) { + .list-group-horizontal-sm { + flex-direction: row + } + + .list-group-horizontal-sm > .list-group-item:first-child { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0 + } + + .list-group-horizontal-sm > .list-group-item:last-child { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0 + } + + .list-group-horizontal-sm > .list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-sm > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0 + } + + .list-group-horizontal-sm > .list-group-item + .list-group-item.active { + margin-left: calc(var(--bs-list-group-border-width) * -1); + border-left-width: var(--bs-list-group-border-width) + } +} + +@media (min-width: 768px) { + .list-group-horizontal-md { + flex-direction: row + } + + .list-group-horizontal-md > .list-group-item:first-child { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0 + } + + .list-group-horizontal-md > .list-group-item:last-child { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0 + } + + .list-group-horizontal-md > .list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-md > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0 + } + + .list-group-horizontal-md > .list-group-item + .list-group-item.active { + margin-left: calc(var(--bs-list-group-border-width) * -1); + border-left-width: var(--bs-list-group-border-width) + } +} + +@media (min-width: 992px) { + .list-group-horizontal-lg { + flex-direction: row + } + + .list-group-horizontal-lg > .list-group-item:first-child { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0 + } + + .list-group-horizontal-lg > .list-group-item:last-child { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0 + } + + .list-group-horizontal-lg > .list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-lg > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0 + } + + .list-group-horizontal-lg > .list-group-item + .list-group-item.active { + margin-left: calc(var(--bs-list-group-border-width) * -1); + border-left-width: var(--bs-list-group-border-width) + } +} + +@media (min-width: 1200px) { + .list-group-horizontal-xl { + flex-direction: row + } + + .list-group-horizontal-xl > .list-group-item:first-child { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0 + } + + .list-group-horizontal-xl > .list-group-item:last-child { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0 + } + + .list-group-horizontal-xl > .list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-xl > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0 + } + + .list-group-horizontal-xl > .list-group-item + .list-group-item.active { + margin-left: calc(var(--bs-list-group-border-width) * -1); + border-left-width: var(--bs-list-group-border-width) + } +} + +@media (min-width: 1400px) { + .list-group-horizontal-xxl { + flex-direction: row + } + + .list-group-horizontal-xxl > .list-group-item:first-child { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0 + } + + .list-group-horizontal-xxl > .list-group-item:last-child { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0 + } + + .list-group-horizontal-xxl > .list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-xxl > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0 + } + + .list-group-horizontal-xxl > .list-group-item + .list-group-item.active { + margin-left: calc(var(--bs-list-group-border-width) * -1); + border-left-width: var(--bs-list-group-border-width) + } +} + +.list-group-flush { + border-radius: 0 +} + +.list-group-flush > .list-group-item { + border-width: 0 0 var(--bs-list-group-border-width) +} + +.list-group-flush > .list-group-item:last-child { + border-bottom-width: 0 +} + +.list-group-item-primary { + color: #21364c; + background-color: #d7dee5 +} + +.list-group-item-primary.list-group-item-action:focus, .list-group-item-primary.list-group-item-action:hover { + color: #21364c; + background-color: #c2c8ce +} + +.list-group-item-primary.list-group-item-action.active { + color: #fff; + background-color: #21364c; + border-color: #21364c +} + +.list-group-item-secondary { + color: #292929; + background-color: #dadada +} + +.list-group-item-secondary.list-group-item-action:focus, .list-group-item-secondary.list-group-item-action:hover { + color: #292929; + background-color: #c4c4c4 +} + +.list-group-item-secondary.list-group-item-action.active { + color: #fff; + background-color: #292929; + border-color: #292929 +} + +.list-group-item-success { + color: #007154; + background-color: #ccf2e8 +} + +.list-group-item-success.list-group-item-action:focus, .list-group-item-success.list-group-item-action:hover { + color: #007154; + background-color: #b8dad1 +} + +.list-group-item-success.list-group-item-action.active { + color: #fff; + background-color: #007154; + border-color: #007154 +} + +.list-group-item-info { + color: #1f5b83; + background-color: #d6eaf8 +} + +.list-group-item-info.list-group-item-action:focus, .list-group-item-info.list-group-item-action:hover { + color: #1f5b83; + background-color: #c1d3df +} + +.list-group-item-info.list-group-item-action.active { + color: #fff; + background-color: #1f5b83; + border-color: #1f5b83 +} + +.list-group-item-warning { + color: #925e0b; + background-color: #fdebd0 +} + +.list-group-item-warning.list-group-item-action:focus, .list-group-item-warning.list-group-item-action:hover { + color: #925e0b; + background-color: #e4d4bb +} + +.list-group-item-warning.list-group-item-action.active { + color: #fff; + background-color: #925e0b; + border-color: #925e0b +} + +.list-group-item-danger { + color: #8b2e24; + background-color: #fadbd8 +} + +.list-group-item-danger.list-group-item-action:focus, .list-group-item-danger.list-group-item-action:hover { + color: #8b2e24; + background-color: #e1c5c2 +} + +.list-group-item-danger.list-group-item-action.active { + color: #fff; + background-color: #8b2e24; + border-color: #8b2e24 +} + +.list-group-item-light { + color: #686d71; + background-color: #eff0f2 +} + +.list-group-item-light.list-group-item-action:focus, .list-group-item-light.list-group-item-action:hover { + color: #686d71; + background-color: #d7d8da +} + +.list-group-item-light.list-group-item-action.active { + color: #fff; + background-color: #686d71; + border-color: #686d71 +} + +.list-group-item-dark { + color: #1d1d1d; + background-color: #d6d6d6 +} + +.list-group-item-dark.list-group-item-action:focus, .list-group-item-dark.list-group-item-action:hover { + color: #1d1d1d; + background-color: #c1c1c1 +} + +.list-group-item-dark.list-group-item-action.active { + color: #fff; + background-color: #1d1d1d; + border-color: #1d1d1d +} + +.btn-close { + box-sizing: content-box; + width: 1em; + height: 1em; + padding: .25em .25em; + color: #fff; + background: transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat; + border: 0; + border-radius: .375rem; + opacity: .4 +} + +.btn-close:hover { + color: #fff; + text-decoration: none; + opacity: 1 +} + +.btn-close:focus { + outline: 0; + box-shadow: 0 0 0 .25rem rgba(55, 90, 127, .25); + opacity: 1 +} + +.btn-close.disabled, .btn-close:disabled { + pointer-events: none; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + opacity: .25 +} + +.btn-close-white { + filter: invert(1) grayscale(100%) brightness(200%) +} + +.toast { + --bs-toast-padding-x: 0.75rem; + --bs-toast-padding-y: 0.5rem; + --bs-toast-spacing: 1.5rem; + --bs-toast-max-width: 350px; + --bs-toast-font-size: 0.875rem; + --bs-toast-color: ; + --bs-toast-bg: #444; + --bs-toast-border-width: 1px; + --bs-toast-border-color: var(--bs-border-color-translucent); + --bs-toast-border-radius: 0.375rem; + --bs-toast-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); + --bs-toast-header-color: #888; + --bs-toast-header-bg: #303030; + --bs-toast-header-border-color: rgba(0, 0, 0, 0.05); + width: var(--bs-toast-max-width); + max-width: 100%; + font-size: var(--bs-toast-font-size); + color: var(--bs-toast-color); + pointer-events: auto; + background-color: var(--bs-toast-bg); + background-clip: padding-box; + border: var(--bs-toast-border-width) solid var(--bs-toast-border-color); + box-shadow: var(--bs-toast-box-shadow); + border-radius: var(--bs-toast-border-radius) +} + +.toast.showing { + opacity: 0 +} + +.toast:not(.show) { + display: none +} + +.toast-container { + position: absolute; + z-index: 1090; + width: -webkit-max-content; + width: -moz-max-content; + width: max-content; + max-width: 100%; + pointer-events: none +} + +.toast-container > :not(:last-child) { + margin-bottom: var(--bs-toast-spacing) +} + +.toast-header { + display: flex; + align-items: center; + padding: var(--bs-toast-padding-y) var(--bs-toast-padding-x); + color: var(--bs-toast-header-color); + background-color: var(--bs-toast-header-bg); + background-clip: padding-box; + border-bottom: var(--bs-toast-border-width) solid var(--bs-toast-header-border-color); + border-top-left-radius: calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width)); + border-top-right-radius: calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width)) +} + +.toast-header .btn-close { + margin-right: calc(var(--bs-toast-padding-x) * -.5); + margin-left: var(--bs-toast-padding-x) +} + +.toast-body { + padding: var(--bs-toast-padding-x); + word-wrap: break-word +} + +.modal { + --bs-modal-zindex: 1055; + --bs-modal-width: 500px; + --bs-modal-padding: 1rem; + --bs-modal-margin: 0.5rem; + --bs-modal-color: ; + --bs-modal-bg: #303030; + --bs-modal-border-color: #444; + --bs-modal-border-width: 1px; + --bs-modal-border-radius: 0.5rem; + --bs-modal-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); + --bs-modal-inner-border-radius: calc(0.5rem - 1px); + --bs-modal-header-padding-x: 1rem; + --bs-modal-header-padding-y: 1rem; + --bs-modal-header-padding: 1rem 1rem; + --bs-modal-header-border-color: #444; + --bs-modal-header-border-width: 1px; + --bs-modal-title-line-height: 1.5; + --bs-modal-footer-gap: 0.5rem; + --bs-modal-footer-bg: ; + --bs-modal-footer-border-color: #444; + --bs-modal-footer-border-width: 1px; + position: fixed; + top: 0; + left: 0; + z-index: var(--bs-modal-zindex); + display: none; + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + outline: 0 +} + +.modal-dialog { + position: relative; + width: auto; + margin: var(--bs-modal-margin); + pointer-events: none +} + +.modal.fade .modal-dialog { + transition: transform .3s ease-out; + transform: translate(0, -50px) +} + +@media (prefers-reduced-motion: reduce) { + .modal.fade .modal-dialog { + transition: none + } +} + +.modal.show .modal-dialog { + transform: none +} + +.modal.modal-static .modal-dialog { + transform: scale(1.02) +} + +.modal-dialog-scrollable { + height: calc(100% - var(--bs-modal-margin) * 2) +} + +.modal-dialog-scrollable .modal-content { + max-height: 100%; + overflow: hidden +} + +.modal-dialog-scrollable .modal-body { + overflow-y: auto +} + +.modal-dialog-centered { + display: flex; + align-items: center; + min-height: calc(100% - var(--bs-modal-margin) * 2) +} + +.modal-content { + position: relative; + display: flex; + flex-direction: column; + width: 100%; + color: var(--bs-modal-color); + pointer-events: auto; + background-color: var(--bs-modal-bg); + background-clip: padding-box; + border: var(--bs-modal-border-width) solid var(--bs-modal-border-color); + border-radius: var(--bs-modal-border-radius); + outline: 0 +} + +.modal-backdrop { + --bs-backdrop-zindex: 1050; + --bs-backdrop-bg: #000; + --bs-backdrop-opacity: 0.5; + position: fixed; + top: 0; + left: 0; + z-index: var(--bs-backdrop-zindex); + width: 100vw; + height: 100vh; + background-color: var(--bs-backdrop-bg) +} + +.modal-backdrop.fade { + opacity: 0 +} + +.modal-backdrop.show { + opacity: var(--bs-backdrop-opacity) +} + +.modal-header { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: space-between; + padding: var(--bs-modal-header-padding); + border-bottom: var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color); + border-top-left-radius: var(--bs-modal-inner-border-radius); + border-top-right-radius: var(--bs-modal-inner-border-radius) +} + +.modal-header .btn-close { + padding: calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5); + margin: calc(var(--bs-modal-header-padding-y) * -.5) calc(var(--bs-modal-header-padding-x) * -.5) calc(var(--bs-modal-header-padding-y) * -.5) auto +} + +.modal-title { + margin-bottom: 0; + line-height: var(--bs-modal-title-line-height) +} + +.modal-body { + position: relative; + flex: 1 1 auto; + padding: var(--bs-modal-padding) +} + +.modal-footer { + display: flex; + flex-shrink: 0; + flex-wrap: wrap; + align-items: center; + justify-content: flex-end; + padding: calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5); + background-color: var(--bs-modal-footer-bg); + border-top: var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color); + border-bottom-right-radius: var(--bs-modal-inner-border-radius); + border-bottom-left-radius: var(--bs-modal-inner-border-radius) +} + +.modal-footer > * { + margin: calc(var(--bs-modal-footer-gap) * .5) +} + +@media (min-width: 576px) { + .modal { + --bs-modal-margin: 1.75rem; + --bs-modal-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) + } + + .modal-dialog { + max-width: var(--bs-modal-width); + margin-right: auto; + margin-left: auto + } + + .modal-sm { + --bs-modal-width: 300px + } +} + +@media (min-width: 992px) { + .modal-lg, .modal-xl { + --bs-modal-width: 800px + } +} + +@media (min-width: 1200px) { + .modal-xl { + --bs-modal-width: 1140px + } +} + +.modal-fullscreen { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 +} + +.modal-fullscreen .modal-content { + height: 100%; + border: 0; + border-radius: 0 +} + +.modal-fullscreen .modal-footer, .modal-fullscreen .modal-header { + border-radius: 0 +} + +.modal-fullscreen .modal-body { + overflow-y: auto +} + +@media (max-width: 575.98px) { + .modal-fullscreen-sm-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-sm-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-sm-down .modal-footer, .modal-fullscreen-sm-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-sm-down .modal-body { + overflow-y: auto + } +} + +@media (max-width: 767.98px) { + .modal-fullscreen-md-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-md-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-md-down .modal-footer, .modal-fullscreen-md-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-md-down .modal-body { + overflow-y: auto + } +} + +@media (max-width: 991.98px) { + .modal-fullscreen-lg-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-lg-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-lg-down .modal-footer, .modal-fullscreen-lg-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-lg-down .modal-body { + overflow-y: auto + } +} + +@media (max-width: 1199.98px) { + .modal-fullscreen-xl-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-xl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-xl-down .modal-footer, .modal-fullscreen-xl-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-xl-down .modal-body { + overflow-y: auto + } +} + +@media (max-width: 1399.98px) { + .modal-fullscreen-xxl-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-xxl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-xxl-down .modal-footer, .modal-fullscreen-xxl-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-xxl-down .modal-body { + overflow-y: auto + } +} + +.tooltip { + --bs-tooltip-zindex: 1080; + --bs-tooltip-max-width: 200px; + --bs-tooltip-padding-x: 0.5rem; + --bs-tooltip-padding-y: 0.25rem; + --bs-tooltip-margin: ; + --bs-tooltip-font-size: 0.875rem; + --bs-tooltip-color: #fff; + --bs-tooltip-bg: #000; + --bs-tooltip-border-radius: 0.375rem; + --bs-tooltip-opacity: 0.9; + --bs-tooltip-arrow-width: 0.8rem; + --bs-tooltip-arrow-height: 0.4rem; + z-index: var(--bs-tooltip-zindex); + display: block; + padding: var(--bs-tooltip-arrow-height); + margin: var(--bs-tooltip-margin); + font-family: var(--bs-font-sans-serif); + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + white-space: normal; + word-spacing: normal; + line-break: auto; + font-size: var(--bs-tooltip-font-size); + word-wrap: break-word; + opacity: 0 +} + +.tooltip.show { + opacity: var(--bs-tooltip-opacity) +} + +.tooltip .tooltip-arrow { + display: block; + width: var(--bs-tooltip-arrow-width); + height: var(--bs-tooltip-arrow-height) +} + +.tooltip .tooltip-arrow::before { + position: absolute; + content: ""; + border-color: transparent; + border-style: solid +} + +.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow, .bs-tooltip-top .tooltip-arrow { + bottom: 0 +} + +.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before, .bs-tooltip-top .tooltip-arrow::before { + top: -1px; + border-width: var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0; + border-top-color: var(--bs-tooltip-bg) +} + +.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow, .bs-tooltip-end .tooltip-arrow { + left: 0; + width: var(--bs-tooltip-arrow-height); + height: var(--bs-tooltip-arrow-width) +} + +.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before, .bs-tooltip-end .tooltip-arrow::before { + right: -1px; + border-width: calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0; + border-right-color: var(--bs-tooltip-bg) +} + +.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow, .bs-tooltip-bottom .tooltip-arrow { + top: 0 +} + +.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before, .bs-tooltip-bottom .tooltip-arrow::before { + bottom: -1px; + border-width: 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height); + border-bottom-color: var(--bs-tooltip-bg) +} + +.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow, .bs-tooltip-start .tooltip-arrow { + right: 0; + width: var(--bs-tooltip-arrow-height); + height: var(--bs-tooltip-arrow-width) +} + +.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before, .bs-tooltip-start .tooltip-arrow::before { + left: -1px; + border-width: calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height); + border-left-color: var(--bs-tooltip-bg) +} + +.tooltip-inner { + max-width: var(--bs-tooltip-max-width); + padding: var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x); + color: var(--bs-tooltip-color); + text-align: center; + background-color: var(--bs-tooltip-bg); + border-radius: var(--bs-tooltip-border-radius) +} + +.popover { + --bs-popover-zindex: 1070; + --bs-popover-max-width: 276px; + --bs-popover-font-size: 0.875rem; + --bs-popover-bg: #303030; + --bs-popover-border-width: 1px; + --bs-popover-border-color: var(--bs-border-color-translucent); + --bs-popover-border-radius: 0.5rem; + --bs-popover-inner-border-radius: calc(0.5rem - 1px); + --bs-popover-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); + --bs-popover-header-padding-x: 1rem; + --bs-popover-header-padding-y: 0.5rem; + --bs-popover-header-font-size: 1rem; + --bs-popover-header-color: var(--bs-heading-color); + --bs-popover-header-bg: #444; + --bs-popover-body-padding-x: 1rem; + --bs-popover-body-padding-y: 1rem; + --bs-popover-body-color: #fff; + --bs-popover-arrow-width: 1rem; + --bs-popover-arrow-height: 0.5rem; + --bs-popover-arrow-border: var(--bs-popover-border-color); + z-index: var(--bs-popover-zindex); + display: block; + max-width: var(--bs-popover-max-width); + font-family: var(--bs-font-sans-serif); + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + white-space: normal; + word-spacing: normal; + line-break: auto; + font-size: var(--bs-popover-font-size); + word-wrap: break-word; + background-color: var(--bs-popover-bg); + background-clip: padding-box; + border: var(--bs-popover-border-width) solid var(--bs-popover-border-color); + border-radius: var(--bs-popover-border-radius) +} + +.popover .popover-arrow { + display: block; + width: var(--bs-popover-arrow-width); + height: var(--bs-popover-arrow-height) +} + +.popover .popover-arrow::after, .popover .popover-arrow::before { + position: absolute; + display: block; + content: ""; + border-color: transparent; + border-style: solid; + border-width: 0 +} + +.bs-popover-auto[data-popper-placement^=top] > .popover-arrow, .bs-popover-top > .popover-arrow { + bottom: calc(var(--bs-popover-arrow-height) * -1 - var(--bs-popover-border-width)) +} + +.bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before, .bs-popover-top > .popover-arrow::after, .bs-popover-top > .popover-arrow::before { + border-width: var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0 +} + +.bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before, .bs-popover-top > .popover-arrow::before { + bottom: 0; + border-top-color: var(--bs-popover-arrow-border) +} + +.bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after, .bs-popover-top > .popover-arrow::after { + bottom: var(--bs-popover-border-width); + border-top-color: var(--bs-popover-bg) +} + +.bs-popover-auto[data-popper-placement^=right] > .popover-arrow, .bs-popover-end > .popover-arrow { + left: calc(var(--bs-popover-arrow-height) * -1 - var(--bs-popover-border-width)); + width: var(--bs-popover-arrow-height); + height: var(--bs-popover-arrow-width) +} + +.bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before, .bs-popover-end > .popover-arrow::after, .bs-popover-end > .popover-arrow::before { + border-width: calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0 +} + +.bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before, .bs-popover-end > .popover-arrow::before { + left: 0; + border-right-color: var(--bs-popover-arrow-border) +} + +.bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after, .bs-popover-end > .popover-arrow::after { + left: var(--bs-popover-border-width); + border-right-color: var(--bs-popover-bg) +} + +.bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow, .bs-popover-bottom > .popover-arrow { + top: calc(var(--bs-popover-arrow-height) * -1 - var(--bs-popover-border-width)) +} + +.bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before, .bs-popover-bottom > .popover-arrow::after, .bs-popover-bottom > .popover-arrow::before { + border-width: 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) +} + +.bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before, .bs-popover-bottom > .popover-arrow::before { + top: 0; + border-bottom-color: var(--bs-popover-arrow-border) +} + +.bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after, .bs-popover-bottom > .popover-arrow::after { + top: var(--bs-popover-border-width); + border-bottom-color: var(--bs-popover-bg) +} + +.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before, .bs-popover-bottom .popover-header::before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: var(--bs-popover-arrow-width); + margin-left: calc(var(--bs-popover-arrow-width) * -.5); + content: ""; + border-bottom: var(--bs-popover-border-width) solid var(--bs-popover-header-bg) +} + +.bs-popover-auto[data-popper-placement^=left] > .popover-arrow, .bs-popover-start > .popover-arrow { + right: calc(var(--bs-popover-arrow-height) * -1 - var(--bs-popover-border-width)); + width: var(--bs-popover-arrow-height); + height: var(--bs-popover-arrow-width) +} + +.bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before, .bs-popover-start > .popover-arrow::after, .bs-popover-start > .popover-arrow::before { + border-width: calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) +} + +.bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before, .bs-popover-start > .popover-arrow::before { + right: 0; + border-left-color: var(--bs-popover-arrow-border) +} + +.bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after, .bs-popover-start > .popover-arrow::after { + right: var(--bs-popover-border-width); + border-left-color: var(--bs-popover-bg) +} + +.popover-header { + padding: var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x); + margin-bottom: 0; + font-size: var(--bs-popover-header-font-size); + color: var(--bs-popover-header-color); + background-color: var(--bs-popover-header-bg); + border-bottom: var(--bs-popover-border-width) solid var(--bs-popover-border-color); + border-top-left-radius: var(--bs-popover-inner-border-radius); + border-top-right-radius: var(--bs-popover-inner-border-radius) +} + +.popover-header:empty { + display: none +} + +.popover-body { + padding: var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x); + color: var(--bs-popover-body-color) +} + +.carousel { + position: relative +} + +.carousel.pointer-event { + touch-action: pan-y +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden +} + +.carousel-inner::after { + display: block; + clear: both; + content: "" +} + +.carousel-item { + position: relative; + display: none; + float: left; + width: 100%; + margin-right: -100%; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + transition: transform .6s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .carousel-item { + transition: none + } +} + +.carousel-item-next, .carousel-item-prev, .carousel-item.active { + display: block +} + +.active.carousel-item-end, .carousel-item-next:not(.carousel-item-start) { + transform: translateX(100%) +} + +.active.carousel-item-start, .carousel-item-prev:not(.carousel-item-end) { + transform: translateX(-100%) +} + +.carousel-fade .carousel-item { + opacity: 0; + transition-property: opacity; + transform: none +} + +.carousel-fade .carousel-item-next.carousel-item-start, .carousel-fade .carousel-item-prev.carousel-item-end, .carousel-fade .carousel-item.active { + z-index: 1; + opacity: 1 +} + +.carousel-fade .active.carousel-item-end, .carousel-fade .active.carousel-item-start { + z-index: 0; + opacity: 0; + transition: opacity 0s .6s +} + +@media (prefers-reduced-motion: reduce) { + .carousel-fade .active.carousel-item-end, .carousel-fade .active.carousel-item-start { + transition: none + } +} + +.carousel-control-next, .carousel-control-prev { + position: absolute; + top: 0; + bottom: 0; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + width: 15%; + padding: 0; + color: #fff; + text-align: center; + background: 0 0; + border: 0; + opacity: .5; + transition: opacity .15s ease +} + +@media (prefers-reduced-motion: reduce) { + .carousel-control-next, .carousel-control-prev { + transition: none + } +} + +.carousel-control-next:focus, .carousel-control-next:hover, .carousel-control-prev:focus, .carousel-control-prev:hover { + color: #fff; + text-decoration: none; + outline: 0; + opacity: .9 +} + +.carousel-control-prev { + left: 0 +} + +.carousel-control-next { + right: 0 +} + +.carousel-control-next-icon, .carousel-control-prev-icon { + display: inline-block; + width: 2rem; + height: 2rem; + background-repeat: no-repeat; + background-position: 50%; + background-size: 100% 100% +} + +.carousel-control-prev-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e") +} + +.carousel-control-next-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e") +} + +.carousel-indicators { + position: absolute; + right: 0; + bottom: 0; + left: 0; + z-index: 2; + display: flex; + justify-content: center; + padding: 0; + margin-right: 15%; + margin-bottom: 1rem; + margin-left: 15%; + list-style: none +} + +.carousel-indicators [data-bs-target] { + box-sizing: content-box; + flex: 0 1 auto; + width: 30px; + height: 3px; + padding: 0; + margin-right: 3px; + margin-left: 3px; + text-indent: -999px; + cursor: pointer; + background-color: #fff; + background-clip: padding-box; + border: 0; + border-top: 10px solid transparent; + border-bottom: 10px solid transparent; + opacity: .5; + transition: opacity .6s ease +} + +@media (prefers-reduced-motion: reduce) { + .carousel-indicators [data-bs-target] { + transition: none + } +} + +.carousel-indicators .active { + opacity: 1 +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 1.25rem; + left: 15%; + padding-top: 1.25rem; + padding-bottom: 1.25rem; + color: #fff; + text-align: center +} + +.carousel-dark .carousel-control-next-icon, .carousel-dark .carousel-control-prev-icon { + filter: invert(1) grayscale(100) +} + +.carousel-dark .carousel-indicators [data-bs-target] { + background-color: #000 +} + +.carousel-dark .carousel-caption { + color: #000 +} + +.spinner-border, .spinner-grow { + display: inline-block; + width: var(--bs-spinner-width); + height: var(--bs-spinner-height); + vertical-align: var(--bs-spinner-vertical-align); + border-radius: 50%; + -webkit-animation: var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name); + animation: var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name) +} + +@-webkit-keyframes spinner-border { + to { + transform: rotate(360deg) + } +} + +@keyframes spinner-border { + to { + transform: rotate(360deg) + } +} + +.spinner-border { + --bs-spinner-width: 2rem; + --bs-spinner-height: 2rem; + --bs-spinner-vertical-align: -0.125em; + --bs-spinner-border-width: 0.25em; + --bs-spinner-animation-speed: 0.75s; + --bs-spinner-animation-name: spinner-border; + border: var(--bs-spinner-border-width) solid currentcolor; + border-right-color: transparent +} + +.spinner-border-sm { + --bs-spinner-width: 1rem; + --bs-spinner-height: 1rem; + --bs-spinner-border-width: 0.2em +} + +@-webkit-keyframes spinner-grow { + 0% { + transform: scale(0) + } + 50% { + opacity: 1; + transform: none + } +} + +@keyframes spinner-grow { + 0% { + transform: scale(0) + } + 50% { + opacity: 1; + transform: none + } +} + +.spinner-grow { + --bs-spinner-width: 2rem; + --bs-spinner-height: 2rem; + --bs-spinner-vertical-align: -0.125em; + --bs-spinner-animation-speed: 0.75s; + --bs-spinner-animation-name: spinner-grow; + background-color: currentcolor; + opacity: 0 +} + +.spinner-grow-sm { + --bs-spinner-width: 1rem; + --bs-spinner-height: 1rem +} + +@media (prefers-reduced-motion: reduce) { + .spinner-border, .spinner-grow { + --bs-spinner-animation-speed: 1.5s + } +} + +.offcanvas, .offcanvas-lg, .offcanvas-md, .offcanvas-sm, .offcanvas-xl, .offcanvas-xxl { + --bs-offcanvas-width: 400px; + --bs-offcanvas-height: 30vh; + --bs-offcanvas-padding-x: 1rem; + --bs-offcanvas-padding-y: 1rem; + --bs-offcanvas-color: ; + --bs-offcanvas-bg: #303030; + --bs-offcanvas-border-width: 1px; + --bs-offcanvas-border-color: #444; + --bs-offcanvas-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) +} + +@media (max-width: 575.98px) { + .offcanvas-sm { + position: fixed; + bottom: 0; + z-index: 1045; + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + transition: transform .3s ease-in-out + } +} + +@media (max-width: 575.98px) and (prefers-reduced-motion: reduce) { + .offcanvas-sm { + transition: none + } +} + +@media (max-width: 575.98px) { + .offcanvas-sm.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%) + } +} + +@media (max-width: 575.98px) { + .offcanvas-sm.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%) + } +} + +@media (max-width: 575.98px) { + .offcanvas-sm.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%) + } +} + +@media (max-width: 575.98px) { + .offcanvas-sm.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%) + } +} + +@media (max-width: 575.98px) { + .offcanvas-sm.show:not(.hiding), .offcanvas-sm.showing { + transform: none + } +} + +@media (max-width: 575.98px) { + .offcanvas-sm.hiding, .offcanvas-sm.show, .offcanvas-sm.showing { + visibility: visible + } +} + +@media (min-width: 576px) { + .offcanvas-sm { + --bs-offcanvas-height: auto; + --bs-offcanvas-border-width: 0; + background-color: transparent !important + } + + .offcanvas-sm .offcanvas-header { + display: none + } + + .offcanvas-sm .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + background-color: transparent !important + } +} + +@media (max-width: 767.98px) { + .offcanvas-md { + position: fixed; + bottom: 0; + z-index: 1045; + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + transition: transform .3s ease-in-out + } +} + +@media (max-width: 767.98px) and (prefers-reduced-motion: reduce) { + .offcanvas-md { + transition: none + } +} + +@media (max-width: 767.98px) { + .offcanvas-md.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%) + } +} + +@media (max-width: 767.98px) { + .offcanvas-md.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%) + } +} + +@media (max-width: 767.98px) { + .offcanvas-md.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%) + } +} + +@media (max-width: 767.98px) { + .offcanvas-md.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%) + } +} + +@media (max-width: 767.98px) { + .offcanvas-md.show:not(.hiding), .offcanvas-md.showing { + transform: none + } +} + +@media (max-width: 767.98px) { + .offcanvas-md.hiding, .offcanvas-md.show, .offcanvas-md.showing { + visibility: visible + } +} + +@media (min-width: 768px) { + .offcanvas-md { + --bs-offcanvas-height: auto; + --bs-offcanvas-border-width: 0; + background-color: transparent !important + } + + .offcanvas-md .offcanvas-header { + display: none + } + + .offcanvas-md .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + background-color: transparent !important + } +} + +@media (max-width: 991.98px) { + .offcanvas-lg { + position: fixed; + bottom: 0; + z-index: 1045; + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + transition: transform .3s ease-in-out + } +} + +@media (max-width: 991.98px) and (prefers-reduced-motion: reduce) { + .offcanvas-lg { + transition: none + } +} + +@media (max-width: 991.98px) { + .offcanvas-lg.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%) + } +} + +@media (max-width: 991.98px) { + .offcanvas-lg.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%) + } +} + +@media (max-width: 991.98px) { + .offcanvas-lg.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%) + } +} + +@media (max-width: 991.98px) { + .offcanvas-lg.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%) + } +} + +@media (max-width: 991.98px) { + .offcanvas-lg.show:not(.hiding), .offcanvas-lg.showing { + transform: none + } +} + +@media (max-width: 991.98px) { + .offcanvas-lg.hiding, .offcanvas-lg.show, .offcanvas-lg.showing { + visibility: visible + } +} + +@media (min-width: 992px) { + .offcanvas-lg { + --bs-offcanvas-height: auto; + --bs-offcanvas-border-width: 0; + background-color: transparent !important + } + + .offcanvas-lg .offcanvas-header { + display: none + } + + .offcanvas-lg .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + background-color: transparent !important + } +} + +@media (max-width: 1199.98px) { + .offcanvas-xl { + position: fixed; + bottom: 0; + z-index: 1045; + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + transition: transform .3s ease-in-out + } +} + +@media (max-width: 1199.98px) and (prefers-reduced-motion: reduce) { + .offcanvas-xl { + transition: none + } +} + +@media (max-width: 1199.98px) { + .offcanvas-xl.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%) + } +} + +@media (max-width: 1199.98px) { + .offcanvas-xl.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%) + } +} + +@media (max-width: 1199.98px) { + .offcanvas-xl.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%) + } +} + +@media (max-width: 1199.98px) { + .offcanvas-xl.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%) + } +} + +@media (max-width: 1199.98px) { + .offcanvas-xl.show:not(.hiding), .offcanvas-xl.showing { + transform: none + } +} + +@media (max-width: 1199.98px) { + .offcanvas-xl.hiding, .offcanvas-xl.show, .offcanvas-xl.showing { + visibility: visible + } +} + +@media (min-width: 1200px) { + .offcanvas-xl { + --bs-offcanvas-height: auto; + --bs-offcanvas-border-width: 0; + background-color: transparent !important + } + + .offcanvas-xl .offcanvas-header { + display: none + } + + .offcanvas-xl .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + background-color: transparent !important + } +} + +@media (max-width: 1399.98px) { + .offcanvas-xxl { + position: fixed; + bottom: 0; + z-index: 1045; + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + transition: transform .3s ease-in-out + } +} + +@media (max-width: 1399.98px) and (prefers-reduced-motion: reduce) { + .offcanvas-xxl { + transition: none + } +} + +@media (max-width: 1399.98px) { + .offcanvas-xxl.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%) + } +} + +@media (max-width: 1399.98px) { + .offcanvas-xxl.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%) + } +} + +@media (max-width: 1399.98px) { + .offcanvas-xxl.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%) + } +} + +@media (max-width: 1399.98px) { + .offcanvas-xxl.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%) + } +} + +@media (max-width: 1399.98px) { + .offcanvas-xxl.show:not(.hiding), .offcanvas-xxl.showing { + transform: none + } +} + +@media (max-width: 1399.98px) { + .offcanvas-xxl.hiding, .offcanvas-xxl.show, .offcanvas-xxl.showing { + visibility: visible + } +} + +@media (min-width: 1400px) { + .offcanvas-xxl { + --bs-offcanvas-height: auto; + --bs-offcanvas-border-width: 0; + background-color: transparent !important + } + + .offcanvas-xxl .offcanvas-header { + display: none + } + + .offcanvas-xxl .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + background-color: transparent !important + } +} + +.offcanvas { + position: fixed; + bottom: 0; + z-index: 1045; + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + transition: transform .3s ease-in-out +} + +@media (prefers-reduced-motion: reduce) { + .offcanvas { + transition: none + } +} + +.offcanvas.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%) +} + +.offcanvas.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%) +} + +.offcanvas.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%) +} + +.offcanvas.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%) +} + +.offcanvas.show:not(.hiding), .offcanvas.showing { + transform: none +} + +.offcanvas.hiding, .offcanvas.show, .offcanvas.showing { + visibility: visible +} + +.offcanvas-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: 1040; + width: 100vw; + height: 100vh; + background-color: #000 +} + +.offcanvas-backdrop.fade { + opacity: 0 +} + +.offcanvas-backdrop.show { + opacity: .5 +} + +.offcanvas-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x) +} + +.offcanvas-header .btn-close { + padding: calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5); + margin-top: calc(var(--bs-offcanvas-padding-y) * -.5); + margin-right: calc(var(--bs-offcanvas-padding-x) * -.5); + margin-bottom: calc(var(--bs-offcanvas-padding-y) * -.5) +} + +.offcanvas-title { + margin-bottom: 0; + line-height: 1.5 +} + +.offcanvas-body { + flex-grow: 1; + padding: var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x); + overflow-y: auto +} + +.placeholder { + display: inline-block; + min-height: 1em; + vertical-align: middle; + cursor: wait; + background-color: currentcolor; + opacity: .5 +} + +.placeholder.btn::before { + display: inline-block; + content: "" +} + +.placeholder-xs { + min-height: .6em +} + +.placeholder-sm { + min-height: .8em +} + +.placeholder-lg { + min-height: 1.2em +} + +.placeholder-glow .placeholder { + -webkit-animation: placeholder-glow 2s ease-in-out infinite; + animation: placeholder-glow 2s ease-in-out infinite +} + +@-webkit-keyframes placeholder-glow { + 50% { + opacity: .2 + } +} + +@keyframes placeholder-glow { + 50% { + opacity: .2 + } +} + +.placeholder-wave { + -webkit-mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%); + mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%); + -webkit-mask-size: 200% 100%; + mask-size: 200% 100%; + -webkit-animation: placeholder-wave 2s linear infinite; + animation: placeholder-wave 2s linear infinite +} + +@-webkit-keyframes placeholder-wave { + 100% { + -webkit-mask-position: -200% 0%; + mask-position: -200% 0% + } +} + +@keyframes placeholder-wave { + 100% { + -webkit-mask-position: -200% 0%; + mask-position: -200% 0% + } +} + +.clearfix::after { + display: block; + clear: both; + content: "" +} + +.text-bg-primary { + color: #fff !important; + background-color: RGBA(55, 90, 127, var(--bs-bg-opacity, 1)) !important +} + +.text-bg-secondary { + color: #fff !important; + background-color: RGBA(68, 68, 68, var(--bs-bg-opacity, 1)) !important +} + +.text-bg-success { + color: #fff !important; + background-color: RGBA(0, 188, 140, var(--bs-bg-opacity, 1)) !important +} + +.text-bg-info { + color: #fff !important; + background-color: RGBA(52, 152, 219, var(--bs-bg-opacity, 1)) !important +} + +.text-bg-warning { + color: #fff !important; + background-color: RGBA(243, 156, 18, var(--bs-bg-opacity, 1)) !important +} + +.text-bg-danger { + color: #fff !important; + background-color: RGBA(231, 76, 60, var(--bs-bg-opacity, 1)) !important +} + +.text-bg-light { + color: #fff !important; + background-color: RGBA(173, 181, 189, var(--bs-bg-opacity, 1)) !important +} + +.text-bg-dark { + color: #fff !important; + background-color: RGBA(48, 48, 48, var(--bs-bg-opacity, 1)) !important +} + +.link-primary { + color: #375a7f !important +} + +.link-primary:focus, .link-primary:hover { + color: #2c4866 !important +} + +.link-secondary { + color: #444 !important +} + +.link-secondary:focus, .link-secondary:hover { + color: #363636 !important +} + +.link-success { + color: #00bc8c !important +} + +.link-success:focus, .link-success:hover { + color: #009670 !important +} + +.link-info { + color: #3498db !important +} + +.link-info:focus, .link-info:hover { + color: #2a7aaf !important +} + +.link-warning { + color: #f39c12 !important +} + +.link-warning:focus, .link-warning:hover { + color: #c27d0e !important +} + +.link-danger { + color: #e74c3c !important +} + +.link-danger:focus, .link-danger:hover { + color: #b93d30 !important +} + +.link-light { + color: #adb5bd !important +} + +.link-light:focus, .link-light:hover { + color: #8a9197 !important +} + +.link-dark { + color: #303030 !important +} + +.link-dark:focus, .link-dark:hover { + color: #262626 !important +} + +.ratio { + position: relative; + width: 100% +} + +.ratio::before { + display: block; + padding-top: var(--bs-aspect-ratio); + content: "" +} + +.ratio > * { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100% +} + +.ratio-1x1 { + --bs-aspect-ratio: 100% +} + +.ratio-4x3 { + --bs-aspect-ratio: 75% +} + +.ratio-16x9 { + --bs-aspect-ratio: 56.25% +} + +.ratio-21x9 { + --bs-aspect-ratio: 42.8571428571% +} + +.fixed-top { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 1030 +} + +.fixed-bottom { + position: fixed; + right: 0; + bottom: 0; + left: 0; + z-index: 1030 +} + +.sticky-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 +} + +.sticky-bottom { + position: -webkit-sticky; + position: sticky; + bottom: 0; + z-index: 1020 +} + +@media (min-width: 576px) { + .sticky-sm-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 + } + + .sticky-sm-bottom { + position: -webkit-sticky; + position: sticky; + bottom: 0; + z-index: 1020 + } +} + +@media (min-width: 768px) { + .sticky-md-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 + } + + .sticky-md-bottom { + position: -webkit-sticky; + position: sticky; + bottom: 0; + z-index: 1020 + } +} + +@media (min-width: 992px) { + .sticky-lg-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 + } + + .sticky-lg-bottom { + position: -webkit-sticky; + position: sticky; + bottom: 0; + z-index: 1020 + } +} + +@media (min-width: 1200px) { + .sticky-xl-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 + } + + .sticky-xl-bottom { + position: -webkit-sticky; + position: sticky; + bottom: 0; + z-index: 1020 + } +} + +@media (min-width: 1400px) { + .sticky-xxl-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020 + } + + .sticky-xxl-bottom { + position: -webkit-sticky; + position: sticky; + bottom: 0; + z-index: 1020 + } +} + +.hstack { + display: flex; + flex-direction: row; + align-items: center; + align-self: stretch +} + +.vstack { + display: flex; + flex: 1 1 auto; + flex-direction: column; + align-self: stretch +} + +.visually-hidden, .visually-hidden-focusable:not(:focus):not(:focus-within) { + position: absolute !important; + width: 1px !important; + height: 1px !important; + padding: 0 !important; + margin: -1px !important; + overflow: hidden !important; + clip: rect(0, 0, 0, 0) !important; + white-space: nowrap !important; + border: 0 !important +} + +.stretched-link::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1; + content: "" +} + +.text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap +} + +.vr { + display: inline-block; + align-self: stretch; + width: 1px; + min-height: 1em; + background-color: currentcolor; + opacity: .25 +} + +.align-baseline { + vertical-align: baseline !important +} + +.align-top { + vertical-align: top !important +} + +.align-middle { + vertical-align: middle !important +} + +.align-bottom { + vertical-align: bottom !important +} + +.align-text-bottom { + vertical-align: text-bottom !important +} + +.align-text-top { + vertical-align: text-top !important +} + +.float-start { + float: left !important +} + +.float-end { + float: right !important +} + +.float-none { + float: none !important +} + +.opacity-0 { + opacity: 0 !important +} + +.opacity-25 { + opacity: .25 !important +} + +.opacity-50 { + opacity: .5 !important +} + +.opacity-75 { + opacity: .75 !important +} + +.opacity-100 { + opacity: 1 !important +} + +.overflow-auto { + overflow: auto !important +} + +.overflow-hidden { + overflow: hidden !important +} + +.overflow-visible { + overflow: visible !important +} + +.overflow-scroll { + overflow: scroll !important +} + +.d-inline { + display: inline !important +} + +.d-inline-block { + display: inline-block !important +} + +.d-block { + display: block !important +} + +.d-grid { + display: grid !important +} + +.d-table { + display: table !important +} + +.d-table-row { + display: table-row !important +} + +.d-table-cell { + display: table-cell !important +} + +.d-flex { + display: flex !important +} + +.d-inline-flex { + display: inline-flex !important +} + +.d-none { + display: none !important +} + +.shadow { + box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .15) !important +} + +.shadow-sm { + box-shadow: 0 .125rem .25rem rgba(0, 0, 0, .075) !important +} + +.shadow-lg { + box-shadow: 0 1rem 3rem rgba(0, 0, 0, .175) !important +} + +.shadow-none { + box-shadow: none !important +} + +.position-static { + position: static !important +} + +.position-relative { + position: relative !important +} + +.position-absolute { + position: absolute !important +} + +.position-fixed { + position: fixed !important +} + +.position-sticky { + position: -webkit-sticky !important; + position: sticky !important +} + +.top-0 { + top: 0 !important +} + +.top-50 { + top: 50% !important +} + +.top-100 { + top: 100% !important +} + +.bottom-0 { + bottom: 0 !important +} + +.bottom-50 { + bottom: 50% !important +} + +.bottom-100 { + bottom: 100% !important +} + +.start-0 { + left: 0 !important +} + +.start-50 { + left: 50% !important +} + +.start-100 { + left: 100% !important +} + +.end-0 { + right: 0 !important +} + +.end-50 { + right: 50% !important +} + +.end-100 { + right: 100% !important +} + +.translate-middle { + transform: translate(-50%, -50%) !important +} + +.translate-middle-x { + transform: translateX(-50%) !important +} + +.translate-middle-y { + transform: translateY(-50%) !important +} + +.border { + border: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important +} + +.border-0 { + border: 0 !important +} + +.border-top { + border-top: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important +} + +.border-top-0 { + border-top: 0 !important +} + +.border-end { + border-right: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important +} + +.border-end-0 { + border-right: 0 !important +} + +.border-bottom { + border-bottom: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important +} + +.border-bottom-0 { + border-bottom: 0 !important +} + +.border-start { + border-left: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important +} + +.border-start-0 { + border-left: 0 !important +} + +.border-primary { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-primary-rgb), var(--bs-border-opacity)) !important +} + +.border-secondary { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-secondary-rgb), var(--bs-border-opacity)) !important +} + +.border-success { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-success-rgb), var(--bs-border-opacity)) !important +} + +.border-info { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-info-rgb), var(--bs-border-opacity)) !important +} + +.border-warning { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-warning-rgb), var(--bs-border-opacity)) !important +} + +.border-danger { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-danger-rgb), var(--bs-border-opacity)) !important +} + +.border-light { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-light-rgb), var(--bs-border-opacity)) !important +} + +.border-dark { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-dark-rgb), var(--bs-border-opacity)) !important +} + +.border-white { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-white-rgb), var(--bs-border-opacity)) !important +} + +.border-1 { + --bs-border-width: 1px +} + +.border-2 { + --bs-border-width: 2px +} + +.border-3 { + --bs-border-width: 3px +} + +.border-4 { + --bs-border-width: 4px +} + +.border-5 { + --bs-border-width: 5px +} + +.border-opacity-10 { + --bs-border-opacity: 0.1 +} + +.border-opacity-25 { + --bs-border-opacity: 0.25 +} + +.border-opacity-50 { + --bs-border-opacity: 0.5 +} + +.border-opacity-75 { + --bs-border-opacity: 0.75 +} + +.border-opacity-100 { + --bs-border-opacity: 1 +} + +.w-25 { + width: 25% !important +} + +.w-50 { + width: 50% !important +} + +.w-75 { + width: 75% !important +} + +.w-100 { + width: 100% !important +} + +.w-auto { + width: auto !important +} + +.mw-100 { + max-width: 100% !important +} + +.vw-100 { + width: 100vw !important +} + +.min-vw-100 { + min-width: 100vw !important +} + +.h-25 { + height: 25% !important +} + +.h-50 { + height: 50% !important +} + +.h-75 { + height: 75% !important +} + +.h-100 { + height: 100% !important +} + +.h-auto { + height: auto !important +} + +.mh-100 { + max-height: 100% !important +} + +.vh-100 { + height: 100vh !important +} + +.min-vh-100 { + min-height: 100vh !important +} + +.flex-fill { + flex: 1 1 auto !important +} + +.flex-row { + flex-direction: row !important +} + +.flex-column { + flex-direction: column !important +} + +.flex-row-reverse { + flex-direction: row-reverse !important +} + +.flex-column-reverse { + flex-direction: column-reverse !important +} + +.flex-grow-0 { + flex-grow: 0 !important +} + +.flex-grow-1 { + flex-grow: 1 !important +} + +.flex-shrink-0 { + flex-shrink: 0 !important +} + +.flex-shrink-1 { + flex-shrink: 1 !important +} + +.flex-wrap { + flex-wrap: wrap !important +} + +.flex-nowrap { + flex-wrap: nowrap !important +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse !important +} + +.justify-content-start { + justify-content: flex-start !important +} + +.justify-content-end { + justify-content: flex-end !important +} + +.justify-content-center { + justify-content: center !important +} + +.justify-content-between { + justify-content: space-between !important +} + +.justify-content-around { + justify-content: space-around !important +} + +.justify-content-evenly { + justify-content: space-evenly !important +} + +.align-items-start { + align-items: flex-start !important +} + +.align-items-end { + align-items: flex-end !important +} + +.align-items-center { + align-items: center !important +} + +.align-items-baseline { + align-items: baseline !important +} + +.align-items-stretch { + align-items: stretch !important +} + +.align-content-start { + align-content: flex-start !important +} + +.align-content-end { + align-content: flex-end !important +} + +.align-content-center { + align-content: center !important +} + +.align-content-between { + align-content: space-between !important +} + +.align-content-around { + align-content: space-around !important +} + +.align-content-stretch { + align-content: stretch !important +} + +.align-self-auto { + align-self: auto !important +} + +.align-self-start { + align-self: flex-start !important +} + +.align-self-end { + align-self: flex-end !important +} + +.align-self-center { + align-self: center !important +} + +.align-self-baseline { + align-self: baseline !important +} + +.align-self-stretch { + align-self: stretch !important +} + +.order-first { + order: -1 !important +} + +.order-0 { + order: 0 !important +} + +.order-1 { + order: 1 !important +} + +.order-2 { + order: 2 !important +} + +.order-3 { + order: 3 !important +} + +.order-4 { + order: 4 !important +} + +.order-5 { + order: 5 !important +} + +.order-last { + order: 6 !important +} + +.m-0 { + margin: 0 !important +} + +.m-1 { + margin: .25rem !important +} + +.m-2 { + margin: .5rem !important +} + +.m-3 { + margin: 1rem !important +} + +.m-4 { + margin: 1.5rem !important +} + +.m-5 { + margin: 3rem !important +} + +.m-auto { + margin: auto !important +} + +.mx-0 { + margin-right: 0 !important; + margin-left: 0 !important +} + +.mx-1 { + margin-right: .25rem !important; + margin-left: .25rem !important +} + +.mx-2 { + margin-right: .5rem !important; + margin-left: .5rem !important +} + +.mx-3 { + margin-right: 1rem !important; + margin-left: 1rem !important +} + +.mx-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important +} + +.mx-5 { + margin-right: 3rem !important; + margin-left: 3rem !important +} + +.mx-auto { + margin-right: auto !important; + margin-left: auto !important +} + +.my-0 { + margin-top: 0 !important; + margin-bottom: 0 !important +} + +.my-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important +} + +.my-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important +} + +.my-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important +} + +.my-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important +} + +.my-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important +} + +.my-auto { + margin-top: auto !important; + margin-bottom: auto !important +} + +.mt-0 { + margin-top: 0 !important +} + +.mt-1 { + margin-top: .25rem !important +} + +.mt-2 { + margin-top: .5rem !important +} + +.mt-3 { + margin-top: 1rem !important +} + +.mt-4 { + margin-top: 1.5rem !important +} + +.mt-5 { + margin-top: 3rem !important +} + +.mt-auto { + margin-top: auto !important +} + +.me-0 { + margin-right: 0 !important +} + +.me-1 { + margin-right: .25rem !important +} + +.me-2 { + margin-right: .5rem !important +} + +.me-3 { + margin-right: 1rem !important +} + +.me-4 { + margin-right: 1.5rem !important +} + +.me-5 { + margin-right: 3rem !important +} + +.me-auto { + margin-right: auto !important +} + +.mb-0 { + margin-bottom: 0 !important +} + +.mb-1 { + margin-bottom: .25rem !important +} + +.mb-2 { + margin-bottom: .5rem !important +} + +.mb-3 { + margin-bottom: 1rem !important +} + +.mb-4 { + margin-bottom: 1.5rem !important +} + +.mb-5 { + margin-bottom: 3rem !important +} + +.mb-auto { + margin-bottom: auto !important +} + +.ms-0 { + margin-left: 0 !important +} + +.ms-1 { + margin-left: .25rem !important +} + +.ms-2 { + margin-left: .5rem !important +} + +.ms-3 { + margin-left: 1rem !important +} + +.ms-4 { + margin-left: 1.5rem !important +} + +.ms-5 { + margin-left: 3rem !important +} + +.ms-auto { + margin-left: auto !important +} + +.p-0 { + padding: 0 !important +} + +.p-1 { + padding: .25rem !important +} + +.p-2 { + padding: .5rem !important +} + +.p-3 { + padding: 1rem !important +} + +.p-4 { + padding: 1.5rem !important +} + +.p-5 { + padding: 3rem !important +} + +.px-0 { + padding-right: 0 !important; + padding-left: 0 !important +} + +.px-1 { + padding-right: .25rem !important; + padding-left: .25rem !important +} + +.px-2 { + padding-right: .5rem !important; + padding-left: .5rem !important +} + +.px-3 { + padding-right: 1rem !important; + padding-left: 1rem !important +} + +.px-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important +} + +.px-5 { + padding-right: 3rem !important; + padding-left: 3rem !important +} + +.py-0 { + padding-top: 0 !important; + padding-bottom: 0 !important +} + +.py-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important +} + +.py-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important +} + +.py-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important +} + +.py-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important +} + +.py-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important +} + +.pt-0 { + padding-top: 0 !important +} + +.pt-1 { + padding-top: .25rem !important +} + +.pt-2 { + padding-top: .5rem !important +} + +.pt-3 { + padding-top: 1rem !important +} + +.pt-4 { + padding-top: 1.5rem !important +} + +.pt-5 { + padding-top: 3rem !important +} + +.pe-0 { + padding-right: 0 !important +} + +.pe-1 { + padding-right: .25rem !important +} + +.pe-2 { + padding-right: .5rem !important +} + +.pe-3 { + padding-right: 1rem !important +} + +.pe-4 { + padding-right: 1.5rem !important +} + +.pe-5 { + padding-right: 3rem !important +} + +.pb-0 { + padding-bottom: 0 !important +} + +.pb-1 { + padding-bottom: .25rem !important +} + +.pb-2 { + padding-bottom: .5rem !important +} + +.pb-3 { + padding-bottom: 1rem !important +} + +.pb-4 { + padding-bottom: 1.5rem !important +} + +.pb-5 { + padding-bottom: 3rem !important +} + +.ps-0 { + padding-left: 0 !important +} + +.ps-1 { + padding-left: .25rem !important +} + +.ps-2 { + padding-left: .5rem !important +} + +.ps-3 { + padding-left: 1rem !important +} + +.ps-4 { + padding-left: 1.5rem !important +} + +.ps-5 { + padding-left: 3rem !important +} + +.gap-0 { + gap: 0 !important +} + +.gap-1 { + gap: .25rem !important +} + +.gap-2 { + gap: .5rem !important +} + +.gap-3 { + gap: 1rem !important +} + +.gap-4 { + gap: 1.5rem !important +} + +.gap-5 { + gap: 3rem !important +} + +.font-monospace { + font-family: var(--bs-font-monospace) !important +} + +.fs-1 { + font-size: calc(1.425rem + 2.1vw) !important +} + +.fs-2 { + font-size: calc(1.375rem + 1.5vw) !important +} + +.fs-3 { + font-size: calc(1.325rem + .9vw) !important +} + +.fs-4 { + font-size: calc(1.275rem + .3vw) !important +} + +.fs-5 { + font-size: 1.25rem !important +} + +.fs-6 { + font-size: 1rem !important +} + +.fst-italic { + font-style: italic !important +} + +.fst-normal { + font-style: normal !important +} + +.fw-light { + font-weight: 300 !important +} + +.fw-lighter { + font-weight: lighter !important +} + +.fw-normal { + font-weight: 400 !important +} + +.fw-bold { + font-weight: 700 !important +} + +.fw-semibold { + font-weight: 600 !important +} + +.fw-bolder { + font-weight: bolder !important +} + +.lh-1 { + line-height: 1 !important +} + +.lh-sm { + line-height: 1.25 !important +} + +.lh-base { + line-height: 1.5 !important +} + +.lh-lg { + line-height: 2 !important +} + +.text-start { + text-align: left !important +} + +.text-end { + text-align: right !important +} + +.text-center { + text-align: center !important +} + +.text-decoration-none { + text-decoration: none !important +} + +.text-decoration-underline { + text-decoration: underline !important +} + +.text-decoration-line-through { + text-decoration: line-through !important +} + +.text-lowercase { + text-transform: lowercase !important +} + +.text-uppercase { + text-transform: uppercase !important +} + +.text-capitalize { + text-transform: capitalize !important +} + +.text-wrap { + white-space: normal !important +} + +.text-nowrap { + white-space: nowrap !important +} + +.text-break { + word-wrap: break-word !important; + word-break: break-word !important +} + +.text-primary { + --bs-text-opacity: 1; + color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important +} + +.text-secondary { + --bs-text-opacity: 1; + color: rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important +} + +.text-success { + --bs-text-opacity: 1; + color: rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important +} + +.text-info { + --bs-text-opacity: 1; + color: rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important +} + +.text-warning { + --bs-text-opacity: 1; + color: rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important +} + +.text-danger { + --bs-text-opacity: 1; + color: rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important +} + +.text-light { + --bs-text-opacity: 1; + color: rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important +} + +.text-dark { + --bs-text-opacity: 1; + color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important +} + +.text-black { + --bs-text-opacity: 1; + color: rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important +} + +.text-white { + --bs-text-opacity: 1; + color: rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important +} + +.text-body { + --bs-text-opacity: 1; + color: rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important +} + +.text-muted { + --bs-text-opacity: 1; + color: #888 !important +} + +.text-black-50 { + --bs-text-opacity: 1; + color: rgba(0, 0, 0, .5) !important +} + +.text-white-50 { + --bs-text-opacity: 1; + color: rgba(255, 255, 255, .5) !important +} + +.text-reset { + --bs-text-opacity: 1; + color: inherit !important +} + +.text-opacity-25 { + --bs-text-opacity: 0.25 +} + +.text-opacity-50 { + --bs-text-opacity: 0.5 +} + +.text-opacity-75 { + --bs-text-opacity: 0.75 +} + +.text-opacity-100 { + --bs-text-opacity: 1 +} + +.bg-primary { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important +} + +.bg-secondary { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important +} + +.bg-success { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important +} + +.bg-info { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important +} + +.bg-warning { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important +} + +.bg-danger { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important +} + +.bg-light { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important +} + +.bg-dark { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important +} + +.bg-black { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important +} + +.bg-white { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important +} + +.bg-body { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important +} + +.bg-transparent { + --bs-bg-opacity: 1; + background-color: transparent !important +} + +.bg-opacity-10 { + --bs-bg-opacity: 0.1 +} + +.bg-opacity-25 { + --bs-bg-opacity: 0.25 +} + +.bg-opacity-50 { + --bs-bg-opacity: 0.5 +} + +.bg-opacity-75 { + --bs-bg-opacity: 0.75 +} + +.bg-opacity-100 { + --bs-bg-opacity: 1 +} + +.bg-gradient { + background-image: var(--bs-gradient) !important +} + +.user-select-all { + -webkit-user-select: all !important; + -moz-user-select: all !important; + user-select: all !important +} + +.user-select-auto { + -webkit-user-select: auto !important; + -moz-user-select: auto !important; + user-select: auto !important +} + +.user-select-none { + -webkit-user-select: none !important; + -moz-user-select: none !important; + user-select: none !important +} + +.pe-none { + pointer-events: none !important +} + +.pe-auto { + pointer-events: auto !important +} + +.rounded { + border-radius: var(--bs-border-radius) !important +} + +.rounded-0 { + border-radius: 0 !important +} + +.rounded-1 { + border-radius: var(--bs-border-radius-sm) !important +} + +.rounded-2 { + border-radius: var(--bs-border-radius) !important +} + +.rounded-3 { + border-radius: var(--bs-border-radius-lg) !important +} + +.rounded-4 { + border-radius: var(--bs-border-radius-xl) !important +} + +.rounded-5 { + border-radius: var(--bs-border-radius-2xl) !important +} + +.rounded-circle { + border-radius: 50% !important +} + +.rounded-pill { + border-radius: var(--bs-border-radius-pill) !important +} + +.rounded-top { + border-top-left-radius: var(--bs-border-radius) !important; + border-top-right-radius: var(--bs-border-radius) !important +} + +.rounded-end { + border-top-right-radius: var(--bs-border-radius) !important; + border-bottom-right-radius: var(--bs-border-radius) !important +} + +.rounded-bottom { + border-bottom-right-radius: var(--bs-border-radius) !important; + border-bottom-left-radius: var(--bs-border-radius) !important +} + +.rounded-start { + border-bottom-left-radius: var(--bs-border-radius) !important; + border-top-left-radius: var(--bs-border-radius) !important +} + +.visible { + visibility: visible !important +} + +.invisible { + visibility: hidden !important +} + +@media (min-width: 576px) { + .float-sm-start { + float: left !important + } + + .float-sm-end { + float: right !important + } + + .float-sm-none { + float: none !important + } + + .d-sm-inline { + display: inline !important + } + + .d-sm-inline-block { + display: inline-block !important + } + + .d-sm-block { + display: block !important + } + + .d-sm-grid { + display: grid !important + } + + .d-sm-table { + display: table !important + } + + .d-sm-table-row { + display: table-row !important + } + + .d-sm-table-cell { + display: table-cell !important + } + + .d-sm-flex { + display: flex !important + } + + .d-sm-inline-flex { + display: inline-flex !important + } + + .d-sm-none { + display: none !important + } + + .flex-sm-fill { + flex: 1 1 auto !important + } + + .flex-sm-row { + flex-direction: row !important + } + + .flex-sm-column { + flex-direction: column !important + } + + .flex-sm-row-reverse { + flex-direction: row-reverse !important + } + + .flex-sm-column-reverse { + flex-direction: column-reverse !important + } + + .flex-sm-grow-0 { + flex-grow: 0 !important + } + + .flex-sm-grow-1 { + flex-grow: 1 !important + } + + .flex-sm-shrink-0 { + flex-shrink: 0 !important + } + + .flex-sm-shrink-1 { + flex-shrink: 1 !important + } + + .flex-sm-wrap { + flex-wrap: wrap !important + } + + .flex-sm-nowrap { + flex-wrap: nowrap !important + } + + .flex-sm-wrap-reverse { + flex-wrap: wrap-reverse !important + } + + .justify-content-sm-start { + justify-content: flex-start !important + } + + .justify-content-sm-end { + justify-content: flex-end !important + } + + .justify-content-sm-center { + justify-content: center !important + } + + .justify-content-sm-between { + justify-content: space-between !important + } + + .justify-content-sm-around { + justify-content: space-around !important + } + + .justify-content-sm-evenly { + justify-content: space-evenly !important + } + + .align-items-sm-start { + align-items: flex-start !important + } + + .align-items-sm-end { + align-items: flex-end !important + } + + .align-items-sm-center { + align-items: center !important + } + + .align-items-sm-baseline { + align-items: baseline !important + } + + .align-items-sm-stretch { + align-items: stretch !important + } + + .align-content-sm-start { + align-content: flex-start !important + } + + .align-content-sm-end { + align-content: flex-end !important + } + + .align-content-sm-center { + align-content: center !important + } + + .align-content-sm-between { + align-content: space-between !important + } + + .align-content-sm-around { + align-content: space-around !important + } + + .align-content-sm-stretch { + align-content: stretch !important + } + + .align-self-sm-auto { + align-self: auto !important + } + + .align-self-sm-start { + align-self: flex-start !important + } + + .align-self-sm-end { + align-self: flex-end !important + } + + .align-self-sm-center { + align-self: center !important + } + + .align-self-sm-baseline { + align-self: baseline !important + } + + .align-self-sm-stretch { + align-self: stretch !important + } + + .order-sm-first { + order: -1 !important + } + + .order-sm-0 { + order: 0 !important + } + + .order-sm-1 { + order: 1 !important + } + + .order-sm-2 { + order: 2 !important + } + + .order-sm-3 { + order: 3 !important + } + + .order-sm-4 { + order: 4 !important + } + + .order-sm-5 { + order: 5 !important + } + + .order-sm-last { + order: 6 !important + } + + .m-sm-0 { + margin: 0 !important + } + + .m-sm-1 { + margin: .25rem !important + } + + .m-sm-2 { + margin: .5rem !important + } + + .m-sm-3 { + margin: 1rem !important + } + + .m-sm-4 { + margin: 1.5rem !important + } + + .m-sm-5 { + margin: 3rem !important + } + + .m-sm-auto { + margin: auto !important + } + + .mx-sm-0 { + margin-right: 0 !important; + margin-left: 0 !important + } + + .mx-sm-1 { + margin-right: .25rem !important; + margin-left: .25rem !important + } + + .mx-sm-2 { + margin-right: .5rem !important; + margin-left: .5rem !important + } + + .mx-sm-3 { + margin-right: 1rem !important; + margin-left: 1rem !important + } + + .mx-sm-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important + } + + .mx-sm-5 { + margin-right: 3rem !important; + margin-left: 3rem !important + } + + .mx-sm-auto { + margin-right: auto !important; + margin-left: auto !important + } + + .my-sm-0 { + margin-top: 0 !important; + margin-bottom: 0 !important + } + + .my-sm-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important + } + + .my-sm-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important + } + + .my-sm-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important + } + + .my-sm-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important + } + + .my-sm-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important + } + + .my-sm-auto { + margin-top: auto !important; + margin-bottom: auto !important + } + + .mt-sm-0 { + margin-top: 0 !important + } + + .mt-sm-1 { + margin-top: .25rem !important + } + + .mt-sm-2 { + margin-top: .5rem !important + } + + .mt-sm-3 { + margin-top: 1rem !important + } + + .mt-sm-4 { + margin-top: 1.5rem !important + } + + .mt-sm-5 { + margin-top: 3rem !important + } + + .mt-sm-auto { + margin-top: auto !important + } + + .me-sm-0 { + margin-right: 0 !important + } + + .me-sm-1 { + margin-right: .25rem !important + } + + .me-sm-2 { + margin-right: .5rem !important + } + + .me-sm-3 { + margin-right: 1rem !important + } + + .me-sm-4 { + margin-right: 1.5rem !important + } + + .me-sm-5 { + margin-right: 3rem !important + } + + .me-sm-auto { + margin-right: auto !important + } + + .mb-sm-0 { + margin-bottom: 0 !important + } + + .mb-sm-1 { + margin-bottom: .25rem !important + } + + .mb-sm-2 { + margin-bottom: .5rem !important + } + + .mb-sm-3 { + margin-bottom: 1rem !important + } + + .mb-sm-4 { + margin-bottom: 1.5rem !important + } + + .mb-sm-5 { + margin-bottom: 3rem !important + } + + .mb-sm-auto { + margin-bottom: auto !important + } + + .ms-sm-0 { + margin-left: 0 !important + } + + .ms-sm-1 { + margin-left: .25rem !important + } + + .ms-sm-2 { + margin-left: .5rem !important + } + + .ms-sm-3 { + margin-left: 1rem !important + } + + .ms-sm-4 { + margin-left: 1.5rem !important + } + + .ms-sm-5 { + margin-left: 3rem !important + } + + .ms-sm-auto { + margin-left: auto !important + } + + .p-sm-0 { + padding: 0 !important + } + + .p-sm-1 { + padding: .25rem !important + } + + .p-sm-2 { + padding: .5rem !important + } + + .p-sm-3 { + padding: 1rem !important + } + + .p-sm-4 { + padding: 1.5rem !important + } + + .p-sm-5 { + padding: 3rem !important + } + + .px-sm-0 { + padding-right: 0 !important; + padding-left: 0 !important + } + + .px-sm-1 { + padding-right: .25rem !important; + padding-left: .25rem !important + } + + .px-sm-2 { + padding-right: .5rem !important; + padding-left: .5rem !important + } + + .px-sm-3 { + padding-right: 1rem !important; + padding-left: 1rem !important + } + + .px-sm-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important + } + + .px-sm-5 { + padding-right: 3rem !important; + padding-left: 3rem !important + } + + .py-sm-0 { + padding-top: 0 !important; + padding-bottom: 0 !important + } + + .py-sm-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important + } + + .py-sm-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important + } + + .py-sm-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important + } + + .py-sm-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important + } + + .py-sm-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important + } + + .pt-sm-0 { + padding-top: 0 !important + } + + .pt-sm-1 { + padding-top: .25rem !important + } + + .pt-sm-2 { + padding-top: .5rem !important + } + + .pt-sm-3 { + padding-top: 1rem !important + } + + .pt-sm-4 { + padding-top: 1.5rem !important + } + + .pt-sm-5 { + padding-top: 3rem !important + } + + .pe-sm-0 { + padding-right: 0 !important + } + + .pe-sm-1 { + padding-right: .25rem !important + } + + .pe-sm-2 { + padding-right: .5rem !important + } + + .pe-sm-3 { + padding-right: 1rem !important + } + + .pe-sm-4 { + padding-right: 1.5rem !important + } + + .pe-sm-5 { + padding-right: 3rem !important + } + + .pb-sm-0 { + padding-bottom: 0 !important + } + + .pb-sm-1 { + padding-bottom: .25rem !important + } + + .pb-sm-2 { + padding-bottom: .5rem !important + } + + .pb-sm-3 { + padding-bottom: 1rem !important + } + + .pb-sm-4 { + padding-bottom: 1.5rem !important + } + + .pb-sm-5 { + padding-bottom: 3rem !important + } + + .ps-sm-0 { + padding-left: 0 !important + } + + .ps-sm-1 { + padding-left: .25rem !important + } + + .ps-sm-2 { + padding-left: .5rem !important + } + + .ps-sm-3 { + padding-left: 1rem !important + } + + .ps-sm-4 { + padding-left: 1.5rem !important + } + + .ps-sm-5 { + padding-left: 3rem !important + } + + .gap-sm-0 { + gap: 0 !important + } + + .gap-sm-1 { + gap: .25rem !important + } + + .gap-sm-2 { + gap: .5rem !important + } + + .gap-sm-3 { + gap: 1rem !important + } + + .gap-sm-4 { + gap: 1.5rem !important + } + + .gap-sm-5 { + gap: 3rem !important + } + + .text-sm-start { + text-align: left !important + } + + .text-sm-end { + text-align: right !important + } + + .text-sm-center { + text-align: center !important + } +} + +@media (min-width: 768px) { + .float-md-start { + float: left !important + } + + .float-md-end { + float: right !important + } + + .float-md-none { + float: none !important + } + + .d-md-inline { + display: inline !important + } + + .d-md-inline-block { + display: inline-block !important + } + + .d-md-block { + display: block !important + } + + .d-md-grid { + display: grid !important + } + + .d-md-table { + display: table !important + } + + .d-md-table-row { + display: table-row !important + } + + .d-md-table-cell { + display: table-cell !important + } + + .d-md-flex { + display: flex !important + } + + .d-md-inline-flex { + display: inline-flex !important + } + + .d-md-none { + display: none !important + } + + .flex-md-fill { + flex: 1 1 auto !important + } + + .flex-md-row { + flex-direction: row !important + } + + .flex-md-column { + flex-direction: column !important + } + + .flex-md-row-reverse { + flex-direction: row-reverse !important + } + + .flex-md-column-reverse { + flex-direction: column-reverse !important + } + + .flex-md-grow-0 { + flex-grow: 0 !important + } + + .flex-md-grow-1 { + flex-grow: 1 !important + } + + .flex-md-shrink-0 { + flex-shrink: 0 !important + } + + .flex-md-shrink-1 { + flex-shrink: 1 !important + } + + .flex-md-wrap { + flex-wrap: wrap !important + } + + .flex-md-nowrap { + flex-wrap: nowrap !important + } + + .flex-md-wrap-reverse { + flex-wrap: wrap-reverse !important + } + + .justify-content-md-start { + justify-content: flex-start !important + } + + .justify-content-md-end { + justify-content: flex-end !important + } + + .justify-content-md-center { + justify-content: center !important + } + + .justify-content-md-between { + justify-content: space-between !important + } + + .justify-content-md-around { + justify-content: space-around !important + } + + .justify-content-md-evenly { + justify-content: space-evenly !important + } + + .align-items-md-start { + align-items: flex-start !important + } + + .align-items-md-end { + align-items: flex-end !important + } + + .align-items-md-center { + align-items: center !important + } + + .align-items-md-baseline { + align-items: baseline !important + } + + .align-items-md-stretch { + align-items: stretch !important + } + + .align-content-md-start { + align-content: flex-start !important + } + + .align-content-md-end { + align-content: flex-end !important + } + + .align-content-md-center { + align-content: center !important + } + + .align-content-md-between { + align-content: space-between !important + } + + .align-content-md-around { + align-content: space-around !important + } + + .align-content-md-stretch { + align-content: stretch !important + } + + .align-self-md-auto { + align-self: auto !important + } + + .align-self-md-start { + align-self: flex-start !important + } + + .align-self-md-end { + align-self: flex-end !important + } + + .align-self-md-center { + align-self: center !important + } + + .align-self-md-baseline { + align-self: baseline !important + } + + .align-self-md-stretch { + align-self: stretch !important + } + + .order-md-first { + order: -1 !important + } + + .order-md-0 { + order: 0 !important + } + + .order-md-1 { + order: 1 !important + } + + .order-md-2 { + order: 2 !important + } + + .order-md-3 { + order: 3 !important + } + + .order-md-4 { + order: 4 !important + } + + .order-md-5 { + order: 5 !important + } + + .order-md-last { + order: 6 !important + } + + .m-md-0 { + margin: 0 !important + } + + .m-md-1 { + margin: .25rem !important + } + + .m-md-2 { + margin: .5rem !important + } + + .m-md-3 { + margin: 1rem !important + } + + .m-md-4 { + margin: 1.5rem !important + } + + .m-md-5 { + margin: 3rem !important + } + + .m-md-auto { + margin: auto !important + } + + .mx-md-0 { + margin-right: 0 !important; + margin-left: 0 !important + } + + .mx-md-1 { + margin-right: .25rem !important; + margin-left: .25rem !important + } + + .mx-md-2 { + margin-right: .5rem !important; + margin-left: .5rem !important + } + + .mx-md-3 { + margin-right: 1rem !important; + margin-left: 1rem !important + } + + .mx-md-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important + } + + .mx-md-5 { + margin-right: 3rem !important; + margin-left: 3rem !important + } + + .mx-md-auto { + margin-right: auto !important; + margin-left: auto !important + } + + .my-md-0 { + margin-top: 0 !important; + margin-bottom: 0 !important + } + + .my-md-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important + } + + .my-md-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important + } + + .my-md-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important + } + + .my-md-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important + } + + .my-md-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important + } + + .my-md-auto { + margin-top: auto !important; + margin-bottom: auto !important + } + + .mt-md-0 { + margin-top: 0 !important + } + + .mt-md-1 { + margin-top: .25rem !important + } + + .mt-md-2 { + margin-top: .5rem !important + } + + .mt-md-3 { + margin-top: 1rem !important + } + + .mt-md-4 { + margin-top: 1.5rem !important + } + + .mt-md-5 { + margin-top: 3rem !important + } + + .mt-md-auto { + margin-top: auto !important + } + + .me-md-0 { + margin-right: 0 !important + } + + .me-md-1 { + margin-right: .25rem !important + } + + .me-md-2 { + margin-right: .5rem !important + } + + .me-md-3 { + margin-right: 1rem !important + } + + .me-md-4 { + margin-right: 1.5rem !important + } + + .me-md-5 { + margin-right: 3rem !important + } + + .me-md-auto { + margin-right: auto !important + } + + .mb-md-0 { + margin-bottom: 0 !important + } + + .mb-md-1 { + margin-bottom: .25rem !important + } + + .mb-md-2 { + margin-bottom: .5rem !important + } + + .mb-md-3 { + margin-bottom: 1rem !important + } + + .mb-md-4 { + margin-bottom: 1.5rem !important + } + + .mb-md-5 { + margin-bottom: 3rem !important + } + + .mb-md-auto { + margin-bottom: auto !important + } + + .ms-md-0 { + margin-left: 0 !important + } + + .ms-md-1 { + margin-left: .25rem !important + } + + .ms-md-2 { + margin-left: .5rem !important + } + + .ms-md-3 { + margin-left: 1rem !important + } + + .ms-md-4 { + margin-left: 1.5rem !important + } + + .ms-md-5 { + margin-left: 3rem !important + } + + .ms-md-auto { + margin-left: auto !important + } + + .p-md-0 { + padding: 0 !important + } + + .p-md-1 { + padding: .25rem !important + } + + .p-md-2 { + padding: .5rem !important + } + + .p-md-3 { + padding: 1rem !important + } + + .p-md-4 { + padding: 1.5rem !important + } + + .p-md-5 { + padding: 3rem !important + } + + .px-md-0 { + padding-right: 0 !important; + padding-left: 0 !important + } + + .px-md-1 { + padding-right: .25rem !important; + padding-left: .25rem !important + } + + .px-md-2 { + padding-right: .5rem !important; + padding-left: .5rem !important + } + + .px-md-3 { + padding-right: 1rem !important; + padding-left: 1rem !important + } + + .px-md-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important + } + + .px-md-5 { + padding-right: 3rem !important; + padding-left: 3rem !important + } + + .py-md-0 { + padding-top: 0 !important; + padding-bottom: 0 !important + } + + .py-md-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important + } + + .py-md-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important + } + + .py-md-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important + } + + .py-md-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important + } + + .py-md-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important + } + + .pt-md-0 { + padding-top: 0 !important + } + + .pt-md-1 { + padding-top: .25rem !important + } + + .pt-md-2 { + padding-top: .5rem !important + } + + .pt-md-3 { + padding-top: 1rem !important + } + + .pt-md-4 { + padding-top: 1.5rem !important + } + + .pt-md-5 { + padding-top: 3rem !important + } + + .pe-md-0 { + padding-right: 0 !important + } + + .pe-md-1 { + padding-right: .25rem !important + } + + .pe-md-2 { + padding-right: .5rem !important + } + + .pe-md-3 { + padding-right: 1rem !important + } + + .pe-md-4 { + padding-right: 1.5rem !important + } + + .pe-md-5 { + padding-right: 3rem !important + } + + .pb-md-0 { + padding-bottom: 0 !important + } + + .pb-md-1 { + padding-bottom: .25rem !important + } + + .pb-md-2 { + padding-bottom: .5rem !important + } + + .pb-md-3 { + padding-bottom: 1rem !important + } + + .pb-md-4 { + padding-bottom: 1.5rem !important + } + + .pb-md-5 { + padding-bottom: 3rem !important + } + + .ps-md-0 { + padding-left: 0 !important + } + + .ps-md-1 { + padding-left: .25rem !important + } + + .ps-md-2 { + padding-left: .5rem !important + } + + .ps-md-3 { + padding-left: 1rem !important + } + + .ps-md-4 { + padding-left: 1.5rem !important + } + + .ps-md-5 { + padding-left: 3rem !important + } + + .gap-md-0 { + gap: 0 !important + } + + .gap-md-1 { + gap: .25rem !important + } + + .gap-md-2 { + gap: .5rem !important + } + + .gap-md-3 { + gap: 1rem !important + } + + .gap-md-4 { + gap: 1.5rem !important + } + + .gap-md-5 { + gap: 3rem !important + } + + .text-md-start { + text-align: left !important + } + + .text-md-end { + text-align: right !important + } + + .text-md-center { + text-align: center !important + } +} + +@media (min-width: 992px) { + .float-lg-start { + float: left !important + } + + .float-lg-end { + float: right !important + } + + .float-lg-none { + float: none !important + } + + .d-lg-inline { + display: inline !important + } + + .d-lg-inline-block { + display: inline-block !important + } + + .d-lg-block { + display: block !important + } + + .d-lg-grid { + display: grid !important + } + + .d-lg-table { + display: table !important + } + + .d-lg-table-row { + display: table-row !important + } + + .d-lg-table-cell { + display: table-cell !important + } + + .d-lg-flex { + display: flex !important + } + + .d-lg-inline-flex { + display: inline-flex !important + } + + .d-lg-none { + display: none !important + } + + .flex-lg-fill { + flex: 1 1 auto !important + } + + .flex-lg-row { + flex-direction: row !important + } + + .flex-lg-column { + flex-direction: column !important + } + + .flex-lg-row-reverse { + flex-direction: row-reverse !important + } + + .flex-lg-column-reverse { + flex-direction: column-reverse !important + } + + .flex-lg-grow-0 { + flex-grow: 0 !important + } + + .flex-lg-grow-1 { + flex-grow: 1 !important + } + + .flex-lg-shrink-0 { + flex-shrink: 0 !important + } + + .flex-lg-shrink-1 { + flex-shrink: 1 !important + } + + .flex-lg-wrap { + flex-wrap: wrap !important + } + + .flex-lg-nowrap { + flex-wrap: nowrap !important + } + + .flex-lg-wrap-reverse { + flex-wrap: wrap-reverse !important + } + + .justify-content-lg-start { + justify-content: flex-start !important + } + + .justify-content-lg-end { + justify-content: flex-end !important + } + + .justify-content-lg-center { + justify-content: center !important + } + + .justify-content-lg-between { + justify-content: space-between !important + } + + .justify-content-lg-around { + justify-content: space-around !important + } + + .justify-content-lg-evenly { + justify-content: space-evenly !important + } + + .align-items-lg-start { + align-items: flex-start !important + } + + .align-items-lg-end { + align-items: flex-end !important + } + + .align-items-lg-center { + align-items: center !important + } + + .align-items-lg-baseline { + align-items: baseline !important + } + + .align-items-lg-stretch { + align-items: stretch !important + } + + .align-content-lg-start { + align-content: flex-start !important + } + + .align-content-lg-end { + align-content: flex-end !important + } + + .align-content-lg-center { + align-content: center !important + } + + .align-content-lg-between { + align-content: space-between !important + } + + .align-content-lg-around { + align-content: space-around !important + } + + .align-content-lg-stretch { + align-content: stretch !important + } + + .align-self-lg-auto { + align-self: auto !important + } + + .align-self-lg-start { + align-self: flex-start !important + } + + .align-self-lg-end { + align-self: flex-end !important + } + + .align-self-lg-center { + align-self: center !important + } + + .align-self-lg-baseline { + align-self: baseline !important + } + + .align-self-lg-stretch { + align-self: stretch !important + } + + .order-lg-first { + order: -1 !important + } + + .order-lg-0 { + order: 0 !important + } + + .order-lg-1 { + order: 1 !important + } + + .order-lg-2 { + order: 2 !important + } + + .order-lg-3 { + order: 3 !important + } + + .order-lg-4 { + order: 4 !important + } + + .order-lg-5 { + order: 5 !important + } + + .order-lg-last { + order: 6 !important + } + + .m-lg-0 { + margin: 0 !important + } + + .m-lg-1 { + margin: .25rem !important + } + + .m-lg-2 { + margin: .5rem !important + } + + .m-lg-3 { + margin: 1rem !important + } + + .m-lg-4 { + margin: 1.5rem !important + } + + .m-lg-5 { + margin: 3rem !important + } + + .m-lg-auto { + margin: auto !important + } + + .mx-lg-0 { + margin-right: 0 !important; + margin-left: 0 !important + } + + .mx-lg-1 { + margin-right: .25rem !important; + margin-left: .25rem !important + } + + .mx-lg-2 { + margin-right: .5rem !important; + margin-left: .5rem !important + } + + .mx-lg-3 { + margin-right: 1rem !important; + margin-left: 1rem !important + } + + .mx-lg-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important + } + + .mx-lg-5 { + margin-right: 3rem !important; + margin-left: 3rem !important + } + + .mx-lg-auto { + margin-right: auto !important; + margin-left: auto !important + } + + .my-lg-0 { + margin-top: 0 !important; + margin-bottom: 0 !important + } + + .my-lg-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important + } + + .my-lg-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important + } + + .my-lg-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important + } + + .my-lg-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important + } + + .my-lg-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important + } + + .my-lg-auto { + margin-top: auto !important; + margin-bottom: auto !important + } + + .mt-lg-0 { + margin-top: 0 !important + } + + .mt-lg-1 { + margin-top: .25rem !important + } + + .mt-lg-2 { + margin-top: .5rem !important + } + + .mt-lg-3 { + margin-top: 1rem !important + } + + .mt-lg-4 { + margin-top: 1.5rem !important + } + + .mt-lg-5 { + margin-top: 3rem !important + } + + .mt-lg-auto { + margin-top: auto !important + } + + .me-lg-0 { + margin-right: 0 !important + } + + .me-lg-1 { + margin-right: .25rem !important + } + + .me-lg-2 { + margin-right: .5rem !important + } + + .me-lg-3 { + margin-right: 1rem !important + } + + .me-lg-4 { + margin-right: 1.5rem !important + } + + .me-lg-5 { + margin-right: 3rem !important + } + + .me-lg-auto { + margin-right: auto !important + } + + .mb-lg-0 { + margin-bottom: 0 !important + } + + .mb-lg-1 { + margin-bottom: .25rem !important + } + + .mb-lg-2 { + margin-bottom: .5rem !important + } + + .mb-lg-3 { + margin-bottom: 1rem !important + } + + .mb-lg-4 { + margin-bottom: 1.5rem !important + } + + .mb-lg-5 { + margin-bottom: 3rem !important + } + + .mb-lg-auto { + margin-bottom: auto !important + } + + .ms-lg-0 { + margin-left: 0 !important + } + + .ms-lg-1 { + margin-left: .25rem !important + } + + .ms-lg-2 { + margin-left: .5rem !important + } + + .ms-lg-3 { + margin-left: 1rem !important + } + + .ms-lg-4 { + margin-left: 1.5rem !important + } + + .ms-lg-5 { + margin-left: 3rem !important + } + + .ms-lg-auto { + margin-left: auto !important + } + + .p-lg-0 { + padding: 0 !important + } + + .p-lg-1 { + padding: .25rem !important + } + + .p-lg-2 { + padding: .5rem !important + } + + .p-lg-3 { + padding: 1rem !important + } + + .p-lg-4 { + padding: 1.5rem !important + } + + .p-lg-5 { + padding: 3rem !important + } + + .px-lg-0 { + padding-right: 0 !important; + padding-left: 0 !important + } + + .px-lg-1 { + padding-right: .25rem !important; + padding-left: .25rem !important + } + + .px-lg-2 { + padding-right: .5rem !important; + padding-left: .5rem !important + } + + .px-lg-3 { + padding-right: 1rem !important; + padding-left: 1rem !important + } + + .px-lg-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important + } + + .px-lg-5 { + padding-right: 3rem !important; + padding-left: 3rem !important + } + + .py-lg-0 { + padding-top: 0 !important; + padding-bottom: 0 !important + } + + .py-lg-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important + } + + .py-lg-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important + } + + .py-lg-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important + } + + .py-lg-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important + } + + .py-lg-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important + } + + .pt-lg-0 { + padding-top: 0 !important + } + + .pt-lg-1 { + padding-top: .25rem !important + } + + .pt-lg-2 { + padding-top: .5rem !important + } + + .pt-lg-3 { + padding-top: 1rem !important + } + + .pt-lg-4 { + padding-top: 1.5rem !important + } + + .pt-lg-5 { + padding-top: 3rem !important + } + + .pe-lg-0 { + padding-right: 0 !important + } + + .pe-lg-1 { + padding-right: .25rem !important + } + + .pe-lg-2 { + padding-right: .5rem !important + } + + .pe-lg-3 { + padding-right: 1rem !important + } + + .pe-lg-4 { + padding-right: 1.5rem !important + } + + .pe-lg-5 { + padding-right: 3rem !important + } + + .pb-lg-0 { + padding-bottom: 0 !important + } + + .pb-lg-1 { + padding-bottom: .25rem !important + } + + .pb-lg-2 { + padding-bottom: .5rem !important + } + + .pb-lg-3 { + padding-bottom: 1rem !important + } + + .pb-lg-4 { + padding-bottom: 1.5rem !important + } + + .pb-lg-5 { + padding-bottom: 3rem !important + } + + .ps-lg-0 { + padding-left: 0 !important + } + + .ps-lg-1 { + padding-left: .25rem !important + } + + .ps-lg-2 { + padding-left: .5rem !important + } + + .ps-lg-3 { + padding-left: 1rem !important + } + + .ps-lg-4 { + padding-left: 1.5rem !important + } + + .ps-lg-5 { + padding-left: 3rem !important + } + + .gap-lg-0 { + gap: 0 !important + } + + .gap-lg-1 { + gap: .25rem !important + } + + .gap-lg-2 { + gap: .5rem !important + } + + .gap-lg-3 { + gap: 1rem !important + } + + .gap-lg-4 { + gap: 1.5rem !important + } + + .gap-lg-5 { + gap: 3rem !important + } + + .text-lg-start { + text-align: left !important + } + + .text-lg-end { + text-align: right !important + } + + .text-lg-center { + text-align: center !important + } +} + +@media (min-width: 1200px) { + .float-xl-start { + float: left !important + } + + .float-xl-end { + float: right !important + } + + .float-xl-none { + float: none !important + } + + .d-xl-inline { + display: inline !important + } + + .d-xl-inline-block { + display: inline-block !important + } + + .d-xl-block { + display: block !important + } + + .d-xl-grid { + display: grid !important + } + + .d-xl-table { + display: table !important + } + + .d-xl-table-row { + display: table-row !important + } + + .d-xl-table-cell { + display: table-cell !important + } + + .d-xl-flex { + display: flex !important + } + + .d-xl-inline-flex { + display: inline-flex !important + } + + .d-xl-none { + display: none !important + } + + .flex-xl-fill { + flex: 1 1 auto !important + } + + .flex-xl-row { + flex-direction: row !important + } + + .flex-xl-column { + flex-direction: column !important + } + + .flex-xl-row-reverse { + flex-direction: row-reverse !important + } + + .flex-xl-column-reverse { + flex-direction: column-reverse !important + } + + .flex-xl-grow-0 { + flex-grow: 0 !important + } + + .flex-xl-grow-1 { + flex-grow: 1 !important + } + + .flex-xl-shrink-0 { + flex-shrink: 0 !important + } + + .flex-xl-shrink-1 { + flex-shrink: 1 !important + } + + .flex-xl-wrap { + flex-wrap: wrap !important + } + + .flex-xl-nowrap { + flex-wrap: nowrap !important + } + + .flex-xl-wrap-reverse { + flex-wrap: wrap-reverse !important + } + + .justify-content-xl-start { + justify-content: flex-start !important + } + + .justify-content-xl-end { + justify-content: flex-end !important + } + + .justify-content-xl-center { + justify-content: center !important + } + + .justify-content-xl-between { + justify-content: space-between !important + } + + .justify-content-xl-around { + justify-content: space-around !important + } + + .justify-content-xl-evenly { + justify-content: space-evenly !important + } + + .align-items-xl-start { + align-items: flex-start !important + } + + .align-items-xl-end { + align-items: flex-end !important + } + + .align-items-xl-center { + align-items: center !important + } + + .align-items-xl-baseline { + align-items: baseline !important + } + + .align-items-xl-stretch { + align-items: stretch !important + } + + .align-content-xl-start { + align-content: flex-start !important + } + + .align-content-xl-end { + align-content: flex-end !important + } + + .align-content-xl-center { + align-content: center !important + } + + .align-content-xl-between { + align-content: space-between !important + } + + .align-content-xl-around { + align-content: space-around !important + } + + .align-content-xl-stretch { + align-content: stretch !important + } + + .align-self-xl-auto { + align-self: auto !important + } + + .align-self-xl-start { + align-self: flex-start !important + } + + .align-self-xl-end { + align-self: flex-end !important + } + + .align-self-xl-center { + align-self: center !important + } + + .align-self-xl-baseline { + align-self: baseline !important + } + + .align-self-xl-stretch { + align-self: stretch !important + } + + .order-xl-first { + order: -1 !important + } + + .order-xl-0 { + order: 0 !important + } + + .order-xl-1 { + order: 1 !important + } + + .order-xl-2 { + order: 2 !important + } + + .order-xl-3 { + order: 3 !important + } + + .order-xl-4 { + order: 4 !important + } + + .order-xl-5 { + order: 5 !important + } + + .order-xl-last { + order: 6 !important + } + + .m-xl-0 { + margin: 0 !important + } + + .m-xl-1 { + margin: .25rem !important + } + + .m-xl-2 { + margin: .5rem !important + } + + .m-xl-3 { + margin: 1rem !important + } + + .m-xl-4 { + margin: 1.5rem !important + } + + .m-xl-5 { + margin: 3rem !important + } + + .m-xl-auto { + margin: auto !important + } + + .mx-xl-0 { + margin-right: 0 !important; + margin-left: 0 !important + } + + .mx-xl-1 { + margin-right: .25rem !important; + margin-left: .25rem !important + } + + .mx-xl-2 { + margin-right: .5rem !important; + margin-left: .5rem !important + } + + .mx-xl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important + } + + .mx-xl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important + } + + .mx-xl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important + } + + .mx-xl-auto { + margin-right: auto !important; + margin-left: auto !important + } + + .my-xl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important + } + + .my-xl-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important + } + + .my-xl-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important + } + + .my-xl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important + } + + .my-xl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important + } + + .my-xl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important + } + + .my-xl-auto { + margin-top: auto !important; + margin-bottom: auto !important + } + + .mt-xl-0 { + margin-top: 0 !important + } + + .mt-xl-1 { + margin-top: .25rem !important + } + + .mt-xl-2 { + margin-top: .5rem !important + } + + .mt-xl-3 { + margin-top: 1rem !important + } + + .mt-xl-4 { + margin-top: 1.5rem !important + } + + .mt-xl-5 { + margin-top: 3rem !important + } + + .mt-xl-auto { + margin-top: auto !important + } + + .me-xl-0 { + margin-right: 0 !important + } + + .me-xl-1 { + margin-right: .25rem !important + } + + .me-xl-2 { + margin-right: .5rem !important + } + + .me-xl-3 { + margin-right: 1rem !important + } + + .me-xl-4 { + margin-right: 1.5rem !important + } + + .me-xl-5 { + margin-right: 3rem !important + } + + .me-xl-auto { + margin-right: auto !important + } + + .mb-xl-0 { + margin-bottom: 0 !important + } + + .mb-xl-1 { + margin-bottom: .25rem !important + } + + .mb-xl-2 { + margin-bottom: .5rem !important + } + + .mb-xl-3 { + margin-bottom: 1rem !important + } + + .mb-xl-4 { + margin-bottom: 1.5rem !important + } + + .mb-xl-5 { + margin-bottom: 3rem !important + } + + .mb-xl-auto { + margin-bottom: auto !important + } + + .ms-xl-0 { + margin-left: 0 !important + } + + .ms-xl-1 { + margin-left: .25rem !important + } + + .ms-xl-2 { + margin-left: .5rem !important + } + + .ms-xl-3 { + margin-left: 1rem !important + } + + .ms-xl-4 { + margin-left: 1.5rem !important + } + + .ms-xl-5 { + margin-left: 3rem !important + } + + .ms-xl-auto { + margin-left: auto !important + } + + .p-xl-0 { + padding: 0 !important + } + + .p-xl-1 { + padding: .25rem !important + } + + .p-xl-2 { + padding: .5rem !important + } + + .p-xl-3 { + padding: 1rem !important + } + + .p-xl-4 { + padding: 1.5rem !important + } + + .p-xl-5 { + padding: 3rem !important + } + + .px-xl-0 { + padding-right: 0 !important; + padding-left: 0 !important + } + + .px-xl-1 { + padding-right: .25rem !important; + padding-left: .25rem !important + } + + .px-xl-2 { + padding-right: .5rem !important; + padding-left: .5rem !important + } + + .px-xl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important + } + + .px-xl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important + } + + .px-xl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important + } + + .py-xl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important + } + + .py-xl-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important + } + + .py-xl-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important + } + + .py-xl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important + } + + .py-xl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important + } + + .py-xl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important + } + + .pt-xl-0 { + padding-top: 0 !important + } + + .pt-xl-1 { + padding-top: .25rem !important + } + + .pt-xl-2 { + padding-top: .5rem !important + } + + .pt-xl-3 { + padding-top: 1rem !important + } + + .pt-xl-4 { + padding-top: 1.5rem !important + } + + .pt-xl-5 { + padding-top: 3rem !important + } + + .pe-xl-0 { + padding-right: 0 !important + } + + .pe-xl-1 { + padding-right: .25rem !important + } + + .pe-xl-2 { + padding-right: .5rem !important + } + + .pe-xl-3 { + padding-right: 1rem !important + } + + .pe-xl-4 { + padding-right: 1.5rem !important + } + + .pe-xl-5 { + padding-right: 3rem !important + } + + .pb-xl-0 { + padding-bottom: 0 !important + } + + .pb-xl-1 { + padding-bottom: .25rem !important + } + + .pb-xl-2 { + padding-bottom: .5rem !important + } + + .pb-xl-3 { + padding-bottom: 1rem !important + } + + .pb-xl-4 { + padding-bottom: 1.5rem !important + } + + .pb-xl-5 { + padding-bottom: 3rem !important + } + + .ps-xl-0 { + padding-left: 0 !important + } + + .ps-xl-1 { + padding-left: .25rem !important + } + + .ps-xl-2 { + padding-left: .5rem !important + } + + .ps-xl-3 { + padding-left: 1rem !important + } + + .ps-xl-4 { + padding-left: 1.5rem !important + } + + .ps-xl-5 { + padding-left: 3rem !important + } + + .gap-xl-0 { + gap: 0 !important + } + + .gap-xl-1 { + gap: .25rem !important + } + + .gap-xl-2 { + gap: .5rem !important + } + + .gap-xl-3 { + gap: 1rem !important + } + + .gap-xl-4 { + gap: 1.5rem !important + } + + .gap-xl-5 { + gap: 3rem !important + } + + .text-xl-start { + text-align: left !important + } + + .text-xl-end { + text-align: right !important + } + + .text-xl-center { + text-align: center !important + } +} + +@media (min-width: 1400px) { + .float-xxl-start { + float: left !important + } + + .float-xxl-end { + float: right !important + } + + .float-xxl-none { + float: none !important + } + + .d-xxl-inline { + display: inline !important + } + + .d-xxl-inline-block { + display: inline-block !important + } + + .d-xxl-block { + display: block !important + } + + .d-xxl-grid { + display: grid !important + } + + .d-xxl-table { + display: table !important + } + + .d-xxl-table-row { + display: table-row !important + } + + .d-xxl-table-cell { + display: table-cell !important + } + + .d-xxl-flex { + display: flex !important + } + + .d-xxl-inline-flex { + display: inline-flex !important + } + + .d-xxl-none { + display: none !important + } + + .flex-xxl-fill { + flex: 1 1 auto !important + } + + .flex-xxl-row { + flex-direction: row !important + } + + .flex-xxl-column { + flex-direction: column !important + } + + .flex-xxl-row-reverse { + flex-direction: row-reverse !important + } + + .flex-xxl-column-reverse { + flex-direction: column-reverse !important + } + + .flex-xxl-grow-0 { + flex-grow: 0 !important + } + + .flex-xxl-grow-1 { + flex-grow: 1 !important + } + + .flex-xxl-shrink-0 { + flex-shrink: 0 !important + } + + .flex-xxl-shrink-1 { + flex-shrink: 1 !important + } + + .flex-xxl-wrap { + flex-wrap: wrap !important + } + + .flex-xxl-nowrap { + flex-wrap: nowrap !important + } + + .flex-xxl-wrap-reverse { + flex-wrap: wrap-reverse !important + } + + .justify-content-xxl-start { + justify-content: flex-start !important + } + + .justify-content-xxl-end { + justify-content: flex-end !important + } + + .justify-content-xxl-center { + justify-content: center !important + } + + .justify-content-xxl-between { + justify-content: space-between !important + } + + .justify-content-xxl-around { + justify-content: space-around !important + } + + .justify-content-xxl-evenly { + justify-content: space-evenly !important + } + + .align-items-xxl-start { + align-items: flex-start !important + } + + .align-items-xxl-end { + align-items: flex-end !important + } + + .align-items-xxl-center { + align-items: center !important + } + + .align-items-xxl-baseline { + align-items: baseline !important + } + + .align-items-xxl-stretch { + align-items: stretch !important + } + + .align-content-xxl-start { + align-content: flex-start !important + } + + .align-content-xxl-end { + align-content: flex-end !important + } + + .align-content-xxl-center { + align-content: center !important + } + + .align-content-xxl-between { + align-content: space-between !important + } + + .align-content-xxl-around { + align-content: space-around !important + } + + .align-content-xxl-stretch { + align-content: stretch !important + } + + .align-self-xxl-auto { + align-self: auto !important + } + + .align-self-xxl-start { + align-self: flex-start !important + } + + .align-self-xxl-end { + align-self: flex-end !important + } + + .align-self-xxl-center { + align-self: center !important + } + + .align-self-xxl-baseline { + align-self: baseline !important + } + + .align-self-xxl-stretch { + align-self: stretch !important + } + + .order-xxl-first { + order: -1 !important + } + + .order-xxl-0 { + order: 0 !important + } + + .order-xxl-1 { + order: 1 !important + } + + .order-xxl-2 { + order: 2 !important + } + + .order-xxl-3 { + order: 3 !important + } + + .order-xxl-4 { + order: 4 !important + } + + .order-xxl-5 { + order: 5 !important + } + + .order-xxl-last { + order: 6 !important + } + + .m-xxl-0 { + margin: 0 !important + } + + .m-xxl-1 { + margin: .25rem !important + } + + .m-xxl-2 { + margin: .5rem !important + } + + .m-xxl-3 { + margin: 1rem !important + } + + .m-xxl-4 { + margin: 1.5rem !important + } + + .m-xxl-5 { + margin: 3rem !important + } + + .m-xxl-auto { + margin: auto !important + } + + .mx-xxl-0 { + margin-right: 0 !important; + margin-left: 0 !important + } + + .mx-xxl-1 { + margin-right: .25rem !important; + margin-left: .25rem !important + } + + .mx-xxl-2 { + margin-right: .5rem !important; + margin-left: .5rem !important + } + + .mx-xxl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important + } + + .mx-xxl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important + } + + .mx-xxl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important + } + + .mx-xxl-auto { + margin-right: auto !important; + margin-left: auto !important + } + + .my-xxl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important + } + + .my-xxl-1 { + margin-top: .25rem !important; + margin-bottom: .25rem !important + } + + .my-xxl-2 { + margin-top: .5rem !important; + margin-bottom: .5rem !important + } + + .my-xxl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important + } + + .my-xxl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important + } + + .my-xxl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important + } + + .my-xxl-auto { + margin-top: auto !important; + margin-bottom: auto !important + } + + .mt-xxl-0 { + margin-top: 0 !important + } + + .mt-xxl-1 { + margin-top: .25rem !important + } + + .mt-xxl-2 { + margin-top: .5rem !important + } + + .mt-xxl-3 { + margin-top: 1rem !important + } + + .mt-xxl-4 { + margin-top: 1.5rem !important + } + + .mt-xxl-5 { + margin-top: 3rem !important + } + + .mt-xxl-auto { + margin-top: auto !important + } + + .me-xxl-0 { + margin-right: 0 !important + } + + .me-xxl-1 { + margin-right: .25rem !important + } + + .me-xxl-2 { + margin-right: .5rem !important + } + + .me-xxl-3 { + margin-right: 1rem !important + } + + .me-xxl-4 { + margin-right: 1.5rem !important + } + + .me-xxl-5 { + margin-right: 3rem !important + } + + .me-xxl-auto { + margin-right: auto !important + } + + .mb-xxl-0 { + margin-bottom: 0 !important + } + + .mb-xxl-1 { + margin-bottom: .25rem !important + } + + .mb-xxl-2 { + margin-bottom: .5rem !important + } + + .mb-xxl-3 { + margin-bottom: 1rem !important + } + + .mb-xxl-4 { + margin-bottom: 1.5rem !important + } + + .mb-xxl-5 { + margin-bottom: 3rem !important + } + + .mb-xxl-auto { + margin-bottom: auto !important + } + + .ms-xxl-0 { + margin-left: 0 !important + } + + .ms-xxl-1 { + margin-left: .25rem !important + } + + .ms-xxl-2 { + margin-left: .5rem !important + } + + .ms-xxl-3 { + margin-left: 1rem !important + } + + .ms-xxl-4 { + margin-left: 1.5rem !important + } + + .ms-xxl-5 { + margin-left: 3rem !important + } + + .ms-xxl-auto { + margin-left: auto !important + } + + .p-xxl-0 { + padding: 0 !important + } + + .p-xxl-1 { + padding: .25rem !important + } + + .p-xxl-2 { + padding: .5rem !important + } + + .p-xxl-3 { + padding: 1rem !important + } + + .p-xxl-4 { + padding: 1.5rem !important + } + + .p-xxl-5 { + padding: 3rem !important + } + + .px-xxl-0 { + padding-right: 0 !important; + padding-left: 0 !important + } + + .px-xxl-1 { + padding-right: .25rem !important; + padding-left: .25rem !important + } + + .px-xxl-2 { + padding-right: .5rem !important; + padding-left: .5rem !important + } + + .px-xxl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important + } + + .px-xxl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important + } + + .px-xxl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important + } + + .py-xxl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important + } + + .py-xxl-1 { + padding-top: .25rem !important; + padding-bottom: .25rem !important + } + + .py-xxl-2 { + padding-top: .5rem !important; + padding-bottom: .5rem !important + } + + .py-xxl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important + } + + .py-xxl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important + } + + .py-xxl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important + } + + .pt-xxl-0 { + padding-top: 0 !important + } + + .pt-xxl-1 { + padding-top: .25rem !important + } + + .pt-xxl-2 { + padding-top: .5rem !important + } + + .pt-xxl-3 { + padding-top: 1rem !important + } + + .pt-xxl-4 { + padding-top: 1.5rem !important + } + + .pt-xxl-5 { + padding-top: 3rem !important + } + + .pe-xxl-0 { + padding-right: 0 !important + } + + .pe-xxl-1 { + padding-right: .25rem !important + } + + .pe-xxl-2 { + padding-right: .5rem !important + } + + .pe-xxl-3 { + padding-right: 1rem !important + } + + .pe-xxl-4 { + padding-right: 1.5rem !important + } + + .pe-xxl-5 { + padding-right: 3rem !important + } + + .pb-xxl-0 { + padding-bottom: 0 !important + } + + .pb-xxl-1 { + padding-bottom: .25rem !important + } + + .pb-xxl-2 { + padding-bottom: .5rem !important + } + + .pb-xxl-3 { + padding-bottom: 1rem !important + } + + .pb-xxl-4 { + padding-bottom: 1.5rem !important + } + + .pb-xxl-5 { + padding-bottom: 3rem !important + } + + .ps-xxl-0 { + padding-left: 0 !important + } + + .ps-xxl-1 { + padding-left: .25rem !important + } + + .ps-xxl-2 { + padding-left: .5rem !important + } + + .ps-xxl-3 { + padding-left: 1rem !important + } + + .ps-xxl-4 { + padding-left: 1.5rem !important + } + + .ps-xxl-5 { + padding-left: 3rem !important + } + + .gap-xxl-0 { + gap: 0 !important + } + + .gap-xxl-1 { + gap: .25rem !important + } + + .gap-xxl-2 { + gap: .5rem !important + } + + .gap-xxl-3 { + gap: 1rem !important + } + + .gap-xxl-4 { + gap: 1.5rem !important + } + + .gap-xxl-5 { + gap: 3rem !important + } + + .text-xxl-start { + text-align: left !important + } + + .text-xxl-end { + text-align: right !important + } + + .text-xxl-center { + text-align: center !important + } +} + +@media (min-width: 1200px) { + .fs-1 { + font-size: 3rem !important + } + + .fs-2 { + font-size: 2.5rem !important + } + + .fs-3 { + font-size: 2rem !important + } + + .fs-4 { + font-size: 1.5rem !important + } +} + +@media print { + .d-print-inline { + display: inline !important + } + + .d-print-inline-block { + display: inline-block !important + } + + .d-print-block { + display: block !important + } + + .d-print-grid { + display: grid !important + } + + .d-print-table { + display: table !important + } + + .d-print-table-row { + display: table-row !important + } + + .d-print-table-cell { + display: table-cell !important + } + + .d-print-flex { + display: flex !important + } + + .d-print-inline-flex { + display: inline-flex !important + } + + .d-print-none { + display: none !important + } +} + +.blockquote-footer { + color: #888 +} + +.input-group-addon { + color: #fff +} + +.form-floating > label { + color: #444 +} + +.nav-pills .nav-item.open .nav-link, .nav-pills .nav-item.open .nav-link:focus, .nav-pills .nav-item.open .nav-link:hover, .nav-pills .nav-link, .nav-pills .nav-link.active, .nav-pills .nav-link.active:focus, .nav-pills .nav-link.active:hover, .nav-tabs .nav-item.open .nav-link, .nav-tabs .nav-item.open .nav-link:focus, .nav-tabs .nav-item.open .nav-link:hover, .nav-tabs .nav-link, .nav-tabs .nav-link.active, .nav-tabs .nav-link.active:focus, .nav-tabs .nav-link.active:hover { + color: #fff +} + +.breadcrumb a { + color: #fff +} + +.pagination a:hover { + text-decoration: none +} + +.alert { + color: #fff; + border: none +} + +.alert .alert-link, .alert a { + color: #fff; + text-decoration: underline +} + +.alert-primary { + background-color: #375a7f +} + +.alert-secondary { + background-color: #444 +} + +.alert-success { + background-color: #00bc8c +} + +.alert-info { + background-color: #3498db +} + +.alert-warning { + background-color: #f39c12 +} + +.alert-danger { + background-color: #e74c3c +} + +.alert-light { + background-color: #adb5bd +} + +.alert-dark { + background-color: #303030 +} diff --git a/modules/web-map/src/main/resources/css/kafkatorio.css b/modules/web-map/src/main/resources/css/kafkatorio.css index db87d4c..2533785 100644 --- a/modules/web-map/src/main/resources/css/kafkatorio.css +++ b/modules/web-map/src/main/resources/css/kafkatorio.css @@ -7,14 +7,16 @@ image-rendering: pixelated; } -html { - background: #2B2B2BFF; -} +/*html {*/ +/* background: #2B2B2BFF;*/ +/*}*/ -body { - background: #2B2B2BFF; -} +/*body {*/ +/* background: #2B2B2BFF;*/ +/*}*/ .leaflet-container { - background-color: rgba(255, 0, 0, 0.0); + background-color: rgba(255, 0, 0, 0.0) !important; + /*background: rgb(34, 34, 34) !important;*/ + /*background: var(--bs-body-bg-rgb) !important;*/ } diff --git a/modules/web-map/src/main/resources/img/kafkatorio-logo.png b/modules/web-map/src/main/resources/img/kafkatorio-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..a37200e6995c6af2c45ff2670facd04b3d1542b7 GIT binary patch literal 52828 zcmY&=2RxST`~HKBY_j(#J5)xtj14GKlg%fTnR}D!J_>djQgQ09if8(_~7uq8K$n36e;%?x4$KA`?)eht3 zy1UuN24DVwI)Ak^%zUU9`BrKP$Q!`qfKjW;yB1vvr*ot^m$itJe}!##!H_& zv+GB54NqSBbk=YG?s+>$#}g-DW|CsjAfom54GB}?Q+~U@O(DfcIf?fz_vbimOV8=& z$BG1OUHcYlY&LOxu->CoNEtEL`Apcj)Qr2>vN7;*Z}Zv6ZctZkc`;!(VI2N*hRylG z663NAUD2+Tv$y_x@G{3)$vdm*4?W{WaZy({6wz@ArIr`BxF!9ryMu;KW2C~5*BEdDp9sNdvhX2KxB}(>kA6K1E2NTZ>iGG zl#WAHgo$UomOA?92PsAeixEtMr*wYm5gun#+(klmAHe#TVnIcJ8w~Obwbe_ zWVe^n6~53P1mh79kuzBpPEx$uoB!Nj^4xiC@UWp;dXqsvKvx*Rnn=^QRY78tR@L}s z*+NR;!>P}4tkNlgZOQ)4?`O9EelO6;RO}2getjj0M?Hpmb9uZm==kW5LQkI7b5Zje z!*cwNg3lHIaht{s4XnB6&7ilx+VxD|NTtJ2sd>rKvQFB?hkrhuOwJZ?Nb z+Fx!w7Cqd>r>nz%0zele+Gr-Cqlto)bj&tSdAR)g_wm$#GK*j2F|jC47n{7h-4;Xd z;br;bfp$>AvPJzg>DVxemjX&CEDsihJM9BZv$AD9o>-=THwqCJvN9qw`-T5>_-28UwGdKIPMXg&jM8Rs=;naSgMh2C27s4_^!PWw+@{j|M&rgVIxNJuptNk`CfUq6`_*L1hU-OR=<0` z%ez^5f3Vo7b>+ML=T$eb6ic^;qN7kKUt-m6_QLjNt42}^aJ?7aSw!)GE^(N?E)`&F zsM>3J3|TX}y-x(ajR8i-3j+4H{{8x>aY-wGV(5+O`#axQX2z$YQ?|kLwb)!Jks~bm zyZ!9!=PH0JWfK&N#>;}p6 zD?I<9%Ybihp{(&}Z$WHke8_!M`)Hf!y-QJ9_um?PE060r^}gLNj7o02y;-Rl#N3@J z{L3^qs;psezND-{zy7ujZ$!sg6*ClUdVM+Sk7FLrTYk?q?F=-oa+z!iCtFzl-7tOD z;#L=ZNmJYXOLW%u8Wca>3bOO|cTrfgIeW?n9_*}6wf8gUy{P*v++||E`O3p6F=FJw z$;ZYtjzg5w`y3aq=JHW-D*ErNWY3Q~BMZ0I^WTTYWw@E&9xdOtK@r{;VJKy;xz+nR zU%Mn{obUt+YW9ohqaqkl%KV5zx^Hc!>$#X^>CTbAECWj!Pn~bU*MBbuJ|xdg`=p7! z43%PtV=QUfEKR2sc6r*jV^Qym#3ikAt6f8yI#QC;KL#Fq5kcZkK0CTRy;lvyY(M&c z)}q${ux>dqa`<Fqp>0qUmO6kgW_`s->W2wKtjV2!bSqrn22H&>hFJDn4 zFQr}ReVy=ng;(u`gw)QP$pQ*P0p~M^cN9Ht!)NoIPxg0bgYTqRnwXvvHG1t@s5_rhmerIeJ;`I4xG1P% zYT|NdtPYKhs?EaK4_6BWrMI5)>pTBBgn9hp4F_imvlD-Rw%(037|P8(*uDj}weY{ph0TQ_Xri63RLOCyPFi2)LXjyWC)xmYxnG!N&ws)It>?7P^oh3~Kb9FbpI8xzf8#8ezu=RfKO6kyTJ^+ezNV2^Ao zvYE#B0KBpR;Aw3RX-TJ2Q0oDx!C3#{$gj^|B1$@ZezYR*#>C$JKNnq^qG)(8$1-If z>?6Td_{JNiJ`fjuavM`V+me|Tw=%s`4ZM=qL?K0KEV)x!!_4<1_65(yy?*c*{0esV zBVOq}eNdo1bTl$SwKT;bI&A&&Kf>(!u=&IsPDr~2tP&CR_} zfjgWbU*sb|T}0j5w z5}8>tZnIxsUby?U{HpO~Zxk2%yv75zN4>`B59<7P(U8F}>ki`hhsNSu)Cjx8ww}SK zs+Ab@wbR~3wp{+Tm!a2Ff20dN`Y3gdLV9cR4@^(CJKISQLgWBauZREr_0f5}A%H>& zkGJ~0oj)e{xulV!zQ;ejmJt*;Uj!#LavWzWm|UTMn&~}BK@GUdmztm@G`1rFo~Ia% znj@8G40~sDCiliL+?Amz{!dHqeJAIyz5L^z!40cU9@b*n!Fx-qopJeBdjN)xWJgMU zndP3`>mOE0PeU;<-c7FLh|N2dG^yj5^StzgqPQ4CH3CB3YUS25Vg6*Tr#N2mR6Z5m zyYsW$x;290LMWd(4UFI1ddes;5;q6)&AMAsCG<83i}Z^0^E96cWph1Soq28W-<89NBO4q$AiT%d@?cn@eWO!2nYde9(?P5{+4y1dhWQ#VqQ)S3^6R0sJpiAjIu(f1AGsBu+-sJLQHfDiUvRTik@XJU9RGTuZKYOeRJm`eAUQ`plidEGA*AzyI}muPw@YE`eb1w`!r{-3|NTm zuNTN!n6CWo^BB?|s#A-mJ)@b-B@5n)f8$vGcleaOgi~*6eJQEQ z{g5YkHA~8B$kQ|`HWd8sCl+_g5(2Ea&}B*c_j+TjJbO6)jw^I8NYq36KCe9z4g&)w8lfY5B(=Gi#L9Dl5{aC zJp*=t(>e1O!!?l{lxZxz^t;+E(xF6fx&TWQXX^E@3ayJ4hVp_0)ZWB&Eq_^deDf2~ zU>ZAH6fce_RhVjCy@;XuI1CbGY9XYYqB}BT(ua`BmHhoC_`;l#J>uxzZ-A%@Bzw?2 zSM&G-5Ea947ELUnnGP&_3`CTw(wZ}hkcCBSrihqU*j{ZLzXga-Nw}fV8>C{G>3pWf z0q|$;eIAN4dT4syS`>UloScyQMQ@r;y=7)@YA!rGwL1H;;{-~vCGOGcAwdhdZihMw z$i5l%>`@f%40(B?VCep$8f}feY%LH`nsvLLiu~IL3ibu;WhbWF3dHzVUP#@s!3G`e z&SeH2otz;McYhj@;D(P;mA1YN*3XrHWmEGgVqyrauzVC6m9_;55trY*t1NPSfp<*Q z<-n6&_RbI7yVHGu=wyl>ZEkLIuvvw&-)JhzyFwHizbqchhbqKc<2xSXE6MsSjEnovbOFm>s(ij9mAm z@cAnSjuS40gb_~t5j}pbL3@7-G6VNcQkc7=kVpzcK|szPQOdn2q4yy3zP^!&s`l;q zc{(;Wou*!j`&{~E!FAttM>AT{gw&mObpTXqwJfF0rjSELy+Tv!J%jJk?%pAUEDvGy zDLIyNq%bo81$P7{XOlvzBLMZp?%CF-aySH`iigM?vOkx~tm(7R+#Nz>w~kE-rdlJMhcBw}o|m z^q(md6wj6FoZgaK3S?9?JWUWVqFd|F{sW)2|D{Dyeg(d;iQ0>8@Tmlby zHrLhuv@x7=ATKJKyk&}l23J?B0lwlZLEdae!On5VeV`nPa_E&u_)#tSyn*{(4U$j+ zOE<#zOPX{qC?aZ?iq}Aj;Jkmt2J*rDv)RVEO`98QStz)Y%Z7y%YL<#uAqAwaLltkr zY_)zn+X;n@;82Y6HB=tRxRrmSmVK3m)J1|a}C zlLfo#nm3JGTr6I&5C{nAa-sFH?4Yuqx0u1|ncjSt6Jg^%C|!HoK?L(BcZ6Xmv{7HL z?^&vdb3k|qL6)4v`?Ao+#0wjifqIqUll4m&Oc6_6`PaDb4!)rT@(+OCqD`pOUL=`S zD_Y;8dRE-!-7wtzbU{v765*z*4g|XG=3gVFCbt|-_lEC^yN_mlb$oBAB7|pPxD~KZ zD!5S5+N9)IzGl7z31ey@Agdnz2Z|{GExR`AJ$gtzkBAm0IUIw1nzNgKE|k%#M`k;e zbkszcUlp9MXr9Pk%+&V`w{iCau+7T(a-k^h%MvKP%##^)zxN`-6H<)av!(XyPAcva zar!bmMJ28iLBWdbY;lU3C2WP(d$KYTk)D^R6ob@-6nY>@ij_v>gau8_pa}QJ^gqho zEFSeBKAuGc4}{_x9qxDjmT_aDMv-;6?gKtRZW^X$iRB@D16o*+1=cL3Fv%=xCjDGboaqafeBKgQ~nsxTq<^7ZaTQ z_zKK}R}B#+kB|}j`C(Q0Ss+N7je5*rK4Y=?M^r$zb7Ip2Y2d?B`#i4T)dSkk(%a)| zJgZkW?o2f?Sl{8UZz#0gdKBsir9@Fs&Je01&*xD^)ocWjCZ(bsmMOR73Q*KyHZsUo z|Aq)P^%{K|L}BFH^Xw@K8{gdkcyT9H`K~L-qtNBF#`3hzHKA(iGmUI1WjqE^vnm(s zzh|jBS?ysZTC%t72P&I{(BmFNa+r<^QuYu@BrN70d?!;&`{Y%~g~dN;<%3jJw0vZ( z0MWMr481&~W>f@fu3Ir)SB)TNK5u)ane+g++gogz_I*#0Z7H-585{QH$ua|>bb0I~ zML!IW*Xfv16g5a2T%&a$x-%-d*y%=)RoWsL#($VB$jJH?NCAg@dB3Hphu3oTn`Eps9eYga)9pmr{NlwJI`%FH<+I+EA$Px5 z8vS0M>&a9Kve>2|-V}@{Aec%3BiE2>LES_9{`MkZVL38j}@iUg_HVhyAhXFMn=!HvLS7_1r0K}N{Ftcd$fAp5o zPikk}eODQWf5_Cy?u*qE`cDiQ~=YogMFM)iSFE)S79HCFx5ZIM4-(M(?WI?F@8)aly=IVKPQB*d@!&-tIKf-C64HbANTSqMKB62#S^_@T1f1Qsa2cLjx zuaVlJOJEAF;i~Pwu=+vXARGZ9TTF9rbNggr&ME%uNJAs%Xi0c0JM934e-7w`xL@7w z;bcH@c^VM3c;DAzE*$2k-T&P+AJ1_4G%{cEHC0q>q3tt@;!IBXa9>PhwJcJw6bxr;+Jk|=}yDQ(u=8>cG1jf-rRD7>)Nb!u&z?6$?(a-@)a-U$LDL7IV!q^ zH5b)A7P>AoK#PQvBe6hSRY3Hnw7DA!a-EIKpfuwdqgEc%U_0ha3RjF9X7vSXN$}qu z#m514p16XmaNt4I!7(W8%tjk6K^p!`5EhXw9MU@fie;@`XLw?`DCei9bK%5Ow%0W6 zj^{2Lld1Yx(vv9`l+K^KVUSv)yeKJ9qgh^(59CqmsgjBL41>AxX!Y8S*}Bw*Sh!(4wN?I?eDe6blW_NeOfpfH+S~i!`;IepfvdchBNWbFO1F zH|RP0ruWUy{Qmc*u#pfA9_9i0P^+%A3OPA@)Xj5od0It9&G+^LM_6ir;7hNkf+BR+ zee|KzNhbP5;|aj(>(AE{85&#tU}vI#3D8085t2jjY-JS%w=b;dDYn_z6q%L#LZaB< z6^Dihvk(-=*1tQ|K#B>fmjBAi%4W=@0hnYloMi&8x2`ffD*VN=z6;fF z=?yXEc_w;JiP$-Ik{fS1Px==(qgNXF;Is1{*F5f~{akhwqKIpzU}-mO3t??SWtEFA z$_EQjOW*8lY=1wbAJ((Fz;fdO(?vRSL$nvUJf@HXBZox?XQ>P1?SC@wOf{YISInS@ zrbxeAmZv{CGj16um3}9 z33I|u^9xK51>$>1_QSAJZH_)o%>k*zZC@TquTgI#Do%3{3#f7 zucwBtb}>*%8K;He`O+{Roq3rVqNX8=OO3R==MxfD!WvA$kh=uYkmrpTLyvvZ%|_?u zJnnCeb&9?S_Q6*_Zh{>0NQpUj#+9D6IGcqu-scC}^VCkw@wdhXM@40z{PwTGr1NfJ z`saxMC@7E;|8xdG|8TG?+SZxtaX9kxs69Xe<&6$GlZpCYdmIZ6EL9=WUk3mgeWeDA zRsmx-;w}eSDKo`K6)*^58$z1i)W2kvNEsq0$dt7qNJ+TS>6Bb4=>l7^)6&5?4sB4{ zR~rE0@4n{pZq_s=Mid`(U9&<~=|sfE`a#;J4=U~LwE-L~G30h!x(9`?)vW3JYWx3r z0lq=T_V&_H`m>gwLr*KiTR96rcqQ#}((hsvEdyd3ouR+`u#us=z$09BqgoxZu*Y_h z@pTUVSs4CwEtIuYiH{?O28Xji*Y#}pRq+h-=U&op1RqrSE8LieYN7g$1uE+r6|3PA zQFfZR)UoZ*;k=RQ&5xpVW8yXk{on#$2?(Je-6j0=x1!6WdMzv`Xg9B-tfjZI^#_U@ zt8+L}ZS7=Xgl}ZVG%&9F*b2O(wPT zv3YqS-+GYpHP)z}j+_Hi#C)-g>?H9sGQkTrO!An|w`CQKBe9G=a-t82f>e%wNv@!KbPM@JPK z?|XEa5nl&3e!$SQvm5hVR6WE0Nwu5ZJ*QHUnQBGY+aF-+zuRMbZ>TgvUtb}i*LnPN z2jcSx-hDV5E3&yEasCpg^!1dZy^`$ri8eGKmGL3-gq*dSRMN$A?~~vMyN-6;{yUz&DRJz5)+*AL3y!QLWqKLC1&N zWlCnRp*Av7#OT=UWkhJVLX4c3`=%yp+!(Gn(}z|Ew{^}USEbs@>!*122ug4BOHLJr z9>;O_No#f-CZY%lFqoznP>Rwykv&9F>($loH2Q(g-P2U>L*ai3pYZA~0O-*mZ}oz& z=A_%V3saK!3k9+Mv9X6L4i|hdmJgMK4uG_~$=C;bCu;7Hf6oL7Rk8-^g!(M2rg4OV4I22fPqEze>{O1+@bFrx|`3m;JcWvFnX_#KuI+ z;Zq_sP2O|*8$$Mwrc;LoCU|Fh76t9@9*X;ZlFrViH?u?2vZz?||DKU4^g`QB9`ldz z36AeTaz@vETmaw@Gzwd6(H)@S6I}?r4HA7vHLzyQJSG_e!Z-c*5`5MT^y=QJ+F*ix zaJu0sA75YJ`^!#zGP|wGa?7vw*L61ciN+A90oHv^fQu_Efn5<%dYR?a4lKRzr)qox zd-8`Gjv;Y*2LiN=>xX9s!7$D%1Y<>%1#tQ}Wbm#p#)4^*@AW)2 z8kxy=x|XW>m;C74nz}NekRbybpk%3=7!0*%_`g^Y zL4(VqoE7}+n5aiZ_u^N~;dY^W^I~=c&(OF-W_$^FVgd%lFkhoV7t};=ibmEs=q{BD z(@TPXQIApZvOxBk#92&waXBz90fj~b#ws4kuc(1Q4Qg^{Pp~sFSqOW2pimDiBwbb) zMEf{@+LAaiS-E9<+hn|5!7u8dfrHvr8*q$O8ndg&4!n$Q;##@6hik4LXNYi$A>9cw7zqA) zOaLulQl(Xicv(e~ZgFG__EETRLgF5k57wdKfF- zXVAfFJLll`o7b^WfX)Hk?{g~0%WZn&Q1hf8xPalpQoCpIH|#IfE;sDQ3!u7)yqRnd zZj;kgqAmBw3@uOaIEiaf_eY6w-g+Hdn+ueqHR|y(p_G@1iFkmojLF(#Fc0nbEc`e# z^3Dd`6N#J{*IfxS` zfm11?19Wv+b_uz#O;IMG_ofvs1$gM?>B!=ab}g!tD9-)PI8pQzaFXkEKr&NK2EHQU zX&YA*6-!G!>_!b`HCE0ig0l#|NhL;8M2@Zu+eS@?zZ}|B33kUt0v4Q zVRFK1!2Z9FRLx zol>ps%#>fOaErrcfPM z=y}iXFTU?l++V!F{TBL=!V3ezv(D&{_ORwQ{veYm{cP=A?IRQ?rc;aXFA-y+h@35^ zw1bKO2pii|TVDTH{jCLsiVKqgbZF3y!Ud=XT9pea8=gbLvK;N!fj%b*ko$m{c$$Vb z_lDocDBySMP_Sxtc>MF8g+{Tm&Bp(FwjTq78&@%Ozv+o_V=N*tN>%2|M}ce-kIbKh z>Rf<*@_D77@gQ?OJsPUm-5En;a``XO0IneaI5}NdNvRy-(nY<5(8>*IIRX_Sm_#bRtbY^ZlGn zgz_K!xCs$uO&7Xzu_TJxu+w(t#7tsMg6r6#6c9}!a}UVl&NG&Og)HXU09^Sz<7li~ zp{cT-i{OZot5Cw(hk}k_Xyt){HaXI81%T@&X!Q!y2PJG%Lz#+L4XQCLYgA~|JN+i4 zrWOUS5;@G|CfpfR?iToy69W1#Wr>a>wx7J1e?o!88um3v`f$94N9lDZvY-%Gm-YbK zQcaf=K5oEy@}LO9JG%X6efsyLxU@e&6e#CabbGkbfQ`2|qCn|RP}Y{fB8eJ*W5Qlv zA+)H_`;V{3;JA*?s+bLsx?DA=eUi^#IKduDIS}lX`kqV&<9-Q>nc5qO6&W>o{xKgi zxx<#+occ=y6fy5!(xKPK6kYP$Y8J>$SsYQ?(C=`S4k$ZVX7`<5gVAsR3 zVY8#RcI73!5eBQPXLpZ(-C@w`u!AD+o*^!_F`C) z?%O%#!CKlKI0x+dDOWylpG|6NpTjrz{7HqmJdD>wGAc3oO(KGl^NR>5KnIpT$L5LOaVPqF*Bs2db6z`^yJu&*# zipr`Hy2730d%p4R0?XTZb=e*d)YHU&ojMM-QD+SjVt^;=Va^K_On>E#VcYCYUBI6R z{UblvwkJ%2rH^-yB~&C|?x&pj4*)0d>0w8`IW9Z$Y7SXZbr6-2XFQHfpqtqA+KA>E;uo z4%p&Zp#f=zS;zz9>`{H6n2OIA-pFX^rzi-ecwhXFe~z==S$ar;pW2-SY5w3G-6r3O zl%KPg!d|T=b)afoZ(KNHq(|NK{PT!=8{w6D34pi~$+u`x6sTo4= zBd-$r`MG!yMS> z0($d%Lm|b9w1>9k3*-JPh%;z&^9*#|KE9@5RR<6S`0n{nr$o&4aQulKYQ*!$iXeuC z+M{IYZcj=EwZQ!XpZDy}4Fu@Vpk^Q2kU(7-ZgaHimr=0vtgmwrES2LNGXg_k*k$+$ z7S?|ke!F42jO!ugxJ`UMB0^)sL?{fc?52A+o%~OnrHR}?;huw<^6w9JZagx}fOXnS zd(?cJB9fFLKH*(_@1(3hB_3vjXunF@gZu8z&zBAFK-Q;|SE+F6DrovpuFQbJY_#Dr zP~fsTq!u&^@X7u$Hx4Yra}Lx37EHB(uq*;h@Rk2*75ga26uZC0L3izygN06=FCZU{ z6hxo7|t?gw^+<>((8uFdisc0zFrSe^o{Sk?O0o7SW&QJvLq4jB;xI_DlbVT zye5=-*Yu~%-pkSn0~Y_0kh=mKZE!I@-it!Hu{{ZAnEv#Hn$QYM!$A>==fo-CXgQ-6 zX>fwGgq#e;g#*9U0l7v-4V~YR1?eh%BV@Zpz=s$A_9|J%{S?k@*Ip*@tz_0}T?QNW z#-C_ByEVp6x9>joeULU2jr^o0D|?o$r{` zfx|^iyV*sF7a9+@emOTDUZw+udep)B-90WX@fpfk)@#+NQse&X-=xR=Re{W!Y`eGI zrFDvJ+=3YxVHyuqK7g*{$Cih&MIJxJRgm(W9InrTS&H<5zhH)h{ZV{wu}b$fFtig* z?Hb#APK8+ZG$1f>g-~-4V{$SWy*Q35YxKawBi92P?Z2b($I>3}5}ZK0k8`H+*8g8w zP9C#uYJRW0YY>?b^2K@W{0~n7Fw( zNYYHC{@o-A8uWY}R2~#Jk`&&Fvm*vkq=kg@w@a*@6+jV%g>6g5N2%-Y;nO6XXn-H6L&__wJOM)qFckdH+R1RdSL11x z8%2uPtO|8Qu+Su?c8HJRMI%f!*giXnunoh`GXmwMXq@b|Dqa6j!NBkx#Z0sII6jq* z2hb*zg}G;FKIX*SDfG3n5Ann0DcrQdsF&4_^Y!Yf*I0Qa`3O9#z|eSmhlyM@z;3n5 zRE;6OVNndi`FszV#pgcOO?34{mCq?4nskWv!--rR=rBsK+0%LU8dTtGJXFEoq;6U=;4LaGf<^$!@7G8Hcj zZ=g{ArELv;FRU<;-?Xhdu;pArUCFop6Pag3SRj%sE-W&&=}v0Lr9(IITPrpfWLy({ zQAASLz@DsyJYn|g3-5GU3C@LF=&X2Dox;JRHb?ikxI z-%=|++|f1)x(I7V>TtB0f0Ts@CI>gXJ#@8*`)Bdyr`?OMaL!veaJ5E^aSJ`XYI_Go zv4YC6$?0*O_ptfTJJsAcX(bSIc`V=c`psXIG5(4xn{aMM&U(2Ss!fr;guyaRo@J$p zT_+JK=anLcI01?9OnPg{Np%Et>MB^^$21TpWoaj#TVK{^)w{s9C4mckFf!~M2T@!P zDY@|(t%$}fypO>Ui#*dNDaK9tmuG3>L6z!vvN%qVF4d6agt&`Ok`no|DHe2JGXHcN zGQ86_!T6tW)EdBtMo6UIYHdKS`cVzo%F456hqS=x3}Z{BYb0UqFrK(2j(<3^-x;mu z<;PBa{?cz5G`R5uNO7KTsDls>LRKjO({AMvYSZUbG`oW2rU#wK5Lko1PY(KY^nxaD zaX2^-mb?r)Jfr0>*uT-gNTQlXOsK4o2Fvp`U^f~(R%m&Kk8uyL@{9h@@o8SbzEJh_ z`@0o}`&IggYKQd6--%aZf<-64ok3N+z=JC4#zUM@Dt{UmkD6)XaaHf#%z&-oyP4da zc$ks*&`?1OuhaUr`DXta)4f6C<9`B$Tdf)iwng5*#$94hA}t@m7Cr6~Kp*Jel?86S z5pnESJ32+r-evekK&y?6s@Z@tZ4Amgg(OJZB$jMzrNcL$m77ysIVrJ3M&)@Vfz161 z*&-HD)iS6-xrrHP&x?;iyE5V~z5Je8dABU;67!11d>pWQo1=0Zcf0!UeESqgKlary z2h0=DvGutbig|uQ`a>9d0#4zxxU@4L?-ZWKn7w9v`SG z<@UB4C`vJMh-&R#WJkV_i*I}BOMj(p zvSMJ2CZ zY_k>eVoYnZ?Che5*5>l>-^!_fo;r>pWBleDIog!^N7YAE3qQYd&6io!!(I zn;5TwO_lo6e{^_`7X9vcbaovPjHr^putz1=PE82=VEHk_TMevT*Suy2BVyjOYQ_h5 zeJTqm4D>vmz`}XP6`@^shUqgOoiJ)F%E@v|GhY1(=NkXlOEIKIpX^o8xaZM>=I}FH zgJeOyf0OC##zoftCNv&fq!68m+O!AC_uA>COcb0#$Wp?5&w}nIZeLh`00X2Ur=@V% zVU3Ib)<_6|8>g?N)~Ehh|GbJlnEONQ*V zsX?1O=^70tOQG)85p?CyE)>^&JgZ_ zl><9FL25{&_EVVj_vlt6XBtM`5R!goQC;z$im3ZZSJ$drnBazqsnhfN&@prh$_h51 z!)gYJ?rrn9+>eJka$Czvi2JO*4Q+BD875}*6rQr=78tG$+zi@=B<>Wwpgt-YfHx># zaNVlqp={~*=H6Y6%f5UC6LkspVz0SF0(mcxJ)R!9mo+MBA9D*&Ch~~nZrDRN;-l}Bb-Q0-BLhb?>Eb;EO74Q0@+38&?F{b) zm7yK7vp17F+E9cGoJOIxy9^8EC|m&@+Kz33?qI-NM>UWT8U~k!5mTZ4=ggo$YIjPK zf+J6^Yucg5XTT+yubkLHm6*j0Y>>6}+&6pFgF0Fx*@yFVp85u5s?c7+n)vL=qCF^i zr{RiU8pTY+Y>JGvBs>3@I`|1AMKn}Q9TA%SH3Y_smxWLP?A;J5DhfAA89Wr!czJH% z%E>Ea40kea8czoW6DG=quC+KVu8?GmCnPxE1ZDz(go3ZNi_mF_vw85#=+= z9}k1Q)GG`&^ch>W9f?J23V*YvnMoT*B#gj$Y~o90ur5oQoS1_2lvV+D9y+Le=o~$* zbzC7`I=6Nb<97Lb$or8{3v?u>Erz?bx&7Rr_QSmqvR>$`%jUqd>IM$dXxjN>%BTLy zhOhs~Bo4hk-kC~JI@$>XxDMZ`R!$fQ=waPnlG7`ZY~t z%;OZWT}O=o4chOpaR`{0Y99F#q8hwH?sAbQ<;NP>IbK*&gas#u9;}-38@H#l(R6-^ zIH#pyWE;pv967*A{4=QoTKJE9P61)>ZR5VW8Vc;Of+~O>B35@cd$O+R!NICLM#DTX zD8D7~`>+7CRwZ(9j`HnoXqsAhl)O#qGJ>9!630Tb3zVBv9x$FGRTQEYHxWMoAU(3Q ztgU}`vbfq)fQj-wE~(JsnxTask+KahQMHeyG@Eer_vHG@+T5Q!S2HAqT_V2BCxF?d zLT>;s5wAOv)RF(mft~cTJ3&Q`PY_m#d|RfnMb(U#vCV5ICc2s0Y=vKVNIPCRCl>lY z)j$<7)^hB#U7P*G^$?go$)AhCC;M@7sZ3yeSO=k}{>?J(D_1A=`K(}{b5E|@4!e>A zO(!u&8q>IX!KJ$n$|?+@y~xi$!EUb(8!sit`xUD6l=(RhEWmkcbJ%zno=`H+j8T?( z;Y$2xgPekH)?i4bi=8+?>>SK(ITqma_FRLm+r36Hva@8%Ff^C#ZsM9L3(PUF)L=u( zpe)(&DpSKv;{T~bID-c-L386npvv$;50Ui2`U;C1TrAfOVG5)^MEq8W>FOi(mLxw4 z4Sb?q>u+oZ|1dAapqD}o_8^OoDIKuNh7EAo`;~woiZ3fYtttUfjMh{-Mvo~$%uNHl znBYCDPWGry7+ajHBt2}xHD+;{9f=LdbE3`0jRh+fYQpmPG19|8s`gJ+@c5e~s^ULD zbq@9yXMp9}*~#Q^K2s_Gww9Z|Z- zw}hE|K*-WYy0jXa{+&F)`SlbFWqEq}vlSB`Vf7sqjx3s{sKm_s8dW_yt?V4#1<-ko zznc>aJnc%BOw7da01$IX2Wo1?{74N42SuMRfXNkKwP|37i&{g3S}yCGfIVvEfH4x0 z$z$~xIwbp(tZC55-?p(1f<5dgL%tybbqf{cdkzHUX18j zUVlQE`5Y3$!EYaPcVO?dC?oSgu3N)#a-m~iSl2Mqv}xvfTEott$6^gT_?w76A97-n zs2H8q)_TsT32J3yMcSE&q2G@zjt=Rqaf2u--MrRzD&4yRnPnn%@;P@eQ37)^|NrW6 zsED&>PYK=_kPW2Vb#+2#XZWxY zSksk&XD4O+{*!~e{_97@cS;0c9T$Y|=G(u|JJ_z`U>SKP_8rLcELp(%abo342cXY! z0&v=JCv9lJN6i)_7fanH6KZ()L^Ko&UT-)2rm@y>hhEcUuG6pw(rMlW*F=sQ9FicP zr|J3aLLB*=r)rF8;Z7Hv!X}*|bGMc5z|SIsv(YEApKvBc0tH5ZBYLg+!Im8x=m4r3 zqP;_Up~42{t0GmrEj?{>u`m&w;C{||&y83^ug?33WA1swxYqni(Mbk(n{iv5Zb;ft z)As5QG14;J;9K-Jiwuij=`b?Fb-S!jgS?XVX5Vdz7fi*!o=D9IH#64|hn(z{I6ltZ z-S+E)T`_tp5z_Z+8JAa)_B846;d6jKJY^pOr1yxAo2#AjTY|!fY2Cu=9cjee)9cL=^aDJ0wpA!q6T+y%w;o!Lo(44o3&i%wP^ImlS^O93NkURKZm^m`{_@x*6 ztZ%<(YAwAZbGUrvTJ$l|7JGsM3sW}IW3VuVE`*0~w2Y?NCBL*@V1*~0bcm54Jpe4z z*!1Uk+u$lNRus$JLF|TSfV^!VaHK?0=VT1R`93w6$|EK^|AQm!yl}+`d9!Jc(1a>MJuJFJAhoxWvo6wuo7K!<9@zOz0y$+wdM=I{fyxFrpg06 z5*g&_VI<%B(Q2InDhcWm$NM{qh?e-+jvHvS;i4mvIF}F4X%JXwFx}j5x zgCl#MOi|Gj4#8>`uw5Mg2aI>RV%qd-w+No#rd@cTCc`HS4-v}SuLDC-e;y^CuPc#} zK#`0^^97PLzLv?Oeg>CGl^ldhqkNkB$hmNI6wc$E(}N?XOG|L@>Jc*;;!qRk1xGJ* z&{$971|~EuJD#oL%s!iN&Y)%g5DF*n|EBOKU{Z0zmnx#q=1%!_%78jiU)Er_Gv^Hj zoFuXjLe_$PGdM2d7r%r*H2PKS)+uRB{n^e$&mA#+f33jG=R_Jf$BqARF2zzsPcm&D z96FWCf8YfDh|jzI>VrTlo7&xt&|pcK|9{K_=46F6)g)@yP8DmB-8PP1#7u}x2%nk~ zOMqt477`6x&dbvx(`!K&7Tqkz6=(4f+inz`X$#<*o^Rpx9Q%~_;B}reZY;>!_P&sc z)0-8G6Sn{+olB+H{OJET<+U4uv=cKYpsR-KKFq91oFgr%Dc;gb&Z0nBUjKf)zC!m8 zHhvzjo%0Smt--sP2)J6a1@UH z#68`A8jWu zRTDfTAxH6umtOTLn4J>5_QkF4p~qz94cNI#(@7Dkd-)HZR)JU&VtYdvKA?vS)_PLA z7Bz={ZErIS@6mRPR4!Io0)!F69hr!vs@_+SHfLhte>DQH(ECJ+#;k0kcs^Er&&ONZ z6AZOV=v_e(wVPZ3MYxF&-IuvcXyw4Yc;OJ1rpkd#WQ)Cd&|S(61H;Eh-yG|HnciP1 zb+nL0&($O$p;p`m1e6;$8cNuF!N_~IZD9Nq!ks9qp*|T6)p$|Fsk;W(GmQt_j{O1M zxapRk>SYg3-^86s24s-7ml+f9S{ZFtKM*6Itc5oeGFSFpJa;mkGY<26DeU>5+EJYP zhKvp)O}Bjh6?9y_+?rsX3@Ml-;aMA(6)~f|FhtWrt;0y9g8i88XfJgwe$q757ahHwG&Jc&GmkxGl<^89dU88_9LWSm5rj#{kMr_ zA%7B@kK?&WDIeK3DE-Q5&nCofauLS(@MAaPa&Q`03f&#Hi$*8fC8{7%BqNnd=%8=b zB7q~mp*GCOgPdptCy~53_j&&SHv-m&jxb+)nNz#JBICGQH75VwT8N$Jooqzimv6e| z7--U?BX{Cex;@)tYUKzj*r+?ecYEz$W~4dq`#A+qlGh^G>)@0iK~;CSA#wuoHk*=b zUp|CK10aqJ*Nt-)VS|;4!eO}`tLwNlJ!=r;UHsy%IQiLW@&sG@lYC?!b9!V*;(w+= zKTk|S_ggr1?g`e$brKom8PbbOarQ#Pj1umcP2tfwa&QzQ?TKzf_KNB^(jVVt?T(eac%+(8yaz0=%}3#P2ib ziFj70t*?AWk)p*dyq7abQ-pAS)DKl)qgmy^eW<-U+rt^SGa1Pl*lT$>YvYI3aU&1F zP-7fzY4H8eUQ!H{APQeuCIS}4{V_xoKR`(y;hKo(M+d<@}^Q6UW$43Ts{r9MArj5|qU zU686sr*iEM+B{{qvMr^BH85QgXu+lLKGOnH$fJ!62S_v{M$t<3i4CO5PsZFRkn;vQ z61it@iOLV&f*ew7u9|%29tBV+h(fgwSUq)-`WErT>iy(>Hel7`FcCHxaB=nq)Q6Gp z_V!W)-oCGJ^PWwg`wL^Lo@fkIwS-@<%j2feItfv~-$h8{`h7B>$Nc0>P85tk#yfriC}mU>Jlk}9rKef3BIG`9Os)f=iYM5wkZ;8j8RkMY zQ5E@2NJzQO<(uq##qlh{F)k4!6N-@Mm`;ZkU-`Ggg1#k&h6Wt0F~iMiI0J_-G;pt# z$0=~cM!12iL@EqwykLSdHrv`IBYlAX{X0~}I*5&;<53_{3Eigz(DnObGLyieWga(0 z#LEfpDIP8|$?E`NL#ngQp5+nMB^%(Rw1SE?;-rKptKxU6(}3yKiD35(XrU)V42{Tq z4O>w)wF0!L>Wap^fJGGYI`p($aVre&rlZA}VPPV&8sPI+*%iMB(ErO}0vLE7A$H7A z%F|(>Yo6zxF^8W2g-nX+iCzP9)fnXK$c@x|0UH^4+h#bAj!nZ1Em+HZ^+`Uc&i%n2 zuNJ(Q2E17!^>ct3Y4T_S=cQEU8l1o4eg)3pam(BGhZjJ(NQB;GCp@hUrhZuEs=)(V zt@maoz|mDgqjP@X2-E~?F?46zn!;xI>wSO!uc9E!4sERcA6M@kPv!gnf!~Kh%3g(R z85NpF%Aq5nvePiyDaoD@LK$U6Nq8ncGosAwaenu?UYGCV_xs)d zru&?8kL!B9p6k^HW#UZjH|RC^Fo5^qIs-@R)q{X#T>^Xaw$u$wlZsqSqxfgVa=_>p z1!k>t3(PdF>0U`X)TLEZ+CA6~P(G%xhIx=nq6y?>(9WZyyr%+sQ<@@A>MBw6n(h2I z>CcS7SeVoNE>B*^Lv_qB;((dm3{4Q>8q)!LtMM6~1kH}ZSy*)TK5Wft2c6)&&INA? z)8jJ>JaeLdjZQ{zC~XVLwY;%z=Skx)Qzz04{X<8epB8)lB;wDz1JyML{I^mT z7i87Uf~<-6oi?m97o;~t(TCTKqsTlBQ-`mD^E(nMan}x*mEvZb`}Z?ES%B+d* zQ$>rg{I_D&!I|E%hdE=85GJ(P$h#J^Z0;LYwcH+0`ovMxuk^;A<=H!qhQ(ZO z?}igKx}=?vuMsxjD`Vj&k+y`>wiQAOBLgLwp>7Qs5iZB2oibD|%5KCG-1m2k7s$BU zZChHzK%iZG8WenchhiMFt9 zW0MHd?i%VP$;EU$7CU!pi9_ApuRfnFn!W^9=(xViZ%9trZ>fFjszMqh{`t>p4CeNJ zi0My082i2vlw+MbJGq4pZMgAh*VH7|w2TI3gDgC;4=~B5qOR(X zWW`E;sn}KfXkAEFeQm~6IAzseAT#3^h9Ik*OWLj1@ML-m*S1hZ!{1^aEHFZU)l&KWU{1 zrL*LfnS@fFXFU5Hgv_jI`ccVKmmb0|;7lMCV2`P4?z>xGd~$EnKS4BIxyp&o2$OV= z;S3ybvTvreBJZg~9VNqy8D}k`!n+=M!n-qLIy+l_`rkW&KG)Q5$N)XVF^UL%w7d8^ zUbp@Pg29$+c4>Cq^WpYWfjY*_nLM3Qoz#fjx~WOF>$0vVOQl6Y=@^lXB=(*i^N&9- z9dR@Xg>ENj&P4m=liV$T!kl(hJo2ejkE4v!uPGD0ohQwqkN7WV)zyq8GX2p4SB5jT zg4eTYR=g$1B}scIrshXh7N=c}b&Kar(UT_yud`|&^vEr00X}dBmU343a^^&d$#?`E z>-w38tYYP%wxNvycbpa-{Loqp$fMFU^ZZVgWhQis2~8mYP*VQz4-RvE1`_M8|8}m< zgp>ahCGYRquVrITY)i^!5b3mB#4d4KCZITIbVvW3?-biR2r+SwewO?BQM=exoYXQ= zTYLMF;>Ug-!`DTwA$DI?T*w78{Vl>|Y(kf-s$T`kqna5A*6pWm-YxQg{;XWZb8f+> zVP&rxP}z$jmjN+iJ+&EBgZ>JemKc0B>}heyqYd*^N>fltQP zA$C8q>=^x#RUN1@vol)T^cR{bo0&MZNpaT??ix@px$K~m7?a`}eS^OH#nqS8x0!pe z)~NHh1U18JQZ611$~&=MSyJ#9bPP6zIL3hD$BBE;%ir!4^MLU8y9$nA*{PgT(hkflXI>nXqQS#UBBhxc;Ew0ITK9r{RQMj;CBKNN2zdI0MLozHKu8Hd zGg2DsZes>WOGpD_4&s3$FBD@dN$;Hp<;CJe)neKE=f4^yGvBX@0u-H)pYqpRMsU5#{jVT^wd-CKZ| zFMcRdl?FY1f0*lUKv+<@Z#Ww%1`m~cs@i+G_yy<;9@P$nckPKJ?>>=ED{wr_uOD+) zL|D@R3F)gBe1(1rl*Qg&U6;-pv}X?hIn{0Ho9xkXSGpC7@a2rxz&6K0)~@b|?LhqS z#XhK`UJmcj{qKmmIFWEOn|Y|j1v8H~`L@H_O408d6YsB0g}?OFd*l}Pt=X^JZwLU$ z@H}QD^Q_mWiw2?GgeeV(hqir}yV45ZSl_T2=+~QLiwNvF=?)dDX#X-23JOZVR@l1< z!o7CZ|2C?6zS$|-A|O+;XBg6t?M+R>Np$kpIWWZPZ%=q3E%JW5Oi_Sxx-Prv!Rq)8 zD;Dk`7vAeSA~->0Sntbp*REw;T0!6S)zU?QvsQa&_mxX2tvRL2AO)F5B^E(!KN|U5 zm>Q{|8*_5=A3%R-SoH-pn@Sui`fKv}wAB9r!Mv_Ub~B0A-oKhpDTa*V&~OV2AExoi z58E~bFfvVp!k$=EpCkBYG3(d(1^jRRTgd0ruH8^D#Fa%52}0_>kVboAQF$i1Yrnnh zUr1`P+ihd9vQ-7dEq0aDm&k{L`T=kkCFf(wot>fDEds%Y!KQSvot6~Ea$wi=8$qd3 zHRyXCnVo-4me`}tbS)hMPrhv*f+&Wa3FtCKkL~1dHQ5f-)3}%$^yqXl%7}zL&HJHdbxbe;wiHSVjeO%jL*Wrk6O2`y;D+eHJIJ~4LZZ3UAL%X_POPFl^)XunhX zo2zmDrjL3yq*YzQ(G3ou!+bL>a~=fpQ(mJY>Q}QaJMY%GCqamMnEIi65=}$N(Vdm~ zrM*{=6g@J45>;Vt0kp<^?{L^(C|ll(;Q@D%95glMXK}WK;#K=f5+sz9aa{5JkwB1D+0SM9immgSbJ3V({ za2bDF^b5d+6tp0NIBLOnYRdSKIyd>=C$K%c5CEu+oX$S;tm<;}16iDgTrpE&MLD$} zZ=V^?KA4<$E^6S4*r9CL6^3MhY>g1)S5RSeJN#!suc0-+_Q;*=7OokW!t54wL!7U+;cTTFAOiA=+b-Knyk$O9AQ ze0n}4USH4N+0wVo+pe+>2zky&juhUzA=QUTaU zw!h`i8iGx1kOnPj;V>gobbuQmU$?KUgp?k8*iG2^jfciHJ8$Gkt9}BWP@Xm%c>{3@ zSH?IA@`qiDFer#TU)3EZI|ZQ-Mk8r40%YO{x%}P&q$nxW$;8**UEk!=^~oK5ofzyl z92vM;I6&@JYAbhM83L=?SZG3G^*d&CYt`Tu@h86&qABKY^L$b zTOY`nZDTAfD{PkH>1ka=)g=o*HFlS(1r52 z7vRQ~jZnw}!nB-C-@@hXlXDsyxR}3RithZ{qazK1HWP*dMkXE;U>-fbQI~>?z`0+lE>*&erB5iv8F?g zQy4I9ahYIPb#@-=Btey$tYShu*wh{*1P;!N%Fdz zd!yN*fr{?c8&FX@yC^h`WcWK&QOMRru@R7KbH8V`T-(&kV6MPXhw z!AOPEiC#P3a;d2gBOx_64VIkiYI3n4H~Xb0lD4Vrc+-7(6k)*ID@5LfE9Q83k88pu>I%QcZNLLG9G=+W& z5m`Dn>DaLEw?#18?Qim8ZZ6YjY6nDmbi7@+u44tm&cfTh>$&?$vH!6Xm1_q*bE^1e zU_}q&yfWm7MMxzBNe{OEnk#fi=_cVgZaBq&NM}A;7jVGu-J=bgEBE@YZQT@yHhJ1V zAg4QvSnA~DKfgHmhi&!ojN!obOzN{dtS!6kOG5U)_=`J6{IL1e)sEs254ye=f};OG z^F;d6X+G9@^j$gec_*#B<9Dbx3pl@HA(D@S@lr|m$eX0N_+7#TjixjI?|&vb^Oke| zOM#qum6NR3RHGW5GacYw@p-#Qr%qJY)eFGBvVgpnuVyW=*EBb^L`1dZ9mltCl>w1R z0p~Byfw$<`66wxwKd~4WXx$~a$ch6Ldi0{*zH~@e#_nJ0W*{m9ek7_qlJ0GjgkT5q zS>3!WaLBl)>G88kmVD=^>Rs0&X9SruXtaIQuo?OqD=PyWpS%76yvV_5V~$gB`p%2} z;9)vEwaL9>>(Rgqs}c1Cf7WuYt)*$@t==F!VEo;Yx&PY#yw|P+=8^%|O$jar*oUzABT4o3&LSfw=D~;KSgK@RW!t2+YDTS(p6)ka& zJ$uZ&A*pA@F^JUHC?hw_Rx&+{!*+j1Waivf=c`{z8AlJ?%=|a1{QIyEVBTTh0<^!7 zwx;xbIKmkxh8@(okf_XmfhFU@C3YU#{XY+uI)-#XRYlXcZEIxyNB^ zb2clJoK5#H7)KN=nm-}9FCZnI)HIo-@SKD!SKb>INzvhCA6DpYm}a~AK`@cDflgw6nk;aDGa|$tQ9ePjK z96MZ?oB407LYK4;jbBfcS9Wp|YKmQ3pevGp;zKj{rDxlh3^Yd>eLGDjNxN9dePLU@ zo@D-#`0bpp-efvI6H)y>MqmDP)=o6qM$!1cUn(B0r^F-AOu3kSIN0VJPuaH_DaVzf zHmX}&zIzv0&Ar<4e%M?vm9k>Rg0I138YA3jpTvRZojR}2PMu!AzLBKX$fHVxN4hj% zt@5T#`rVJM>GAo5rW?(&wJ=0$XHYinY$I=C(SHTNg;@T{C?4K#x$lm$GCLQ4;{N?~b88XLCFsAH@@tzjhVN#k zY}jde`HC#HS@HXKy4%D#Gfj`o%wJDCsuSKMEk%EszIlE;Df8Da)#LBNjqEI<3EN7` zOey8&Y@x(``{?{)<>;@7%r*O1l9H8`LoU&}v#c0%+gbjZm&V+*8MhuKKgaTl0LWYK^5gBRguIkj-7G|qf`cS2;Cgj68a*3SeX21uo%-2__B+J zqC+3h@H=o2;%!K+KJ)aE_n2cX(u4XC+wiP3bR!yOX{^|Wn1yY0Ac_(c5tkj-2MGYw z?ZR9N_l6nujRwpvYzi_6s&VcbnAPyuZRzz_S=pE2GJYH)Gd5$S z4RaVY2sq!coJc1qo3!olegjSjexJg2u z(;n*1k=1!l`X^64h-B+4Qr6NsWcmGj)>)|%)a(iK?uFbMy@oC5OvKay8vs=1(8nJv}o{&poDZ^=K6S;EDs(Y_iIL0FG3`FN{qDi@w+8Svm(bh>+@WfK zsF+5#S9?(AFZuS3Jar#$2qmhY53knpOnAyUhvwRaoj6Yr$ufw%y3z;KyohKn$`{f8 zzYYZj1cp|j_`;jJ5v9O0POh3nR>+VyP><|%2<$%@kpJ2%qWWmX3Bh#ttzN0scBLh` z{*6#C+$R0HOaY?Ed2I^O_!;_Kedqxd7|m%n)TQSvTi7A7nj*8QRM}(WsY_C?lD$nu9Yw` zY=7C^sZJ+|{^k%=U(kf;Sb?2b?*4t~K|0kkT2x*+-&sUV z*V{`tQD@=6A?N2uQH+jUBuX#cN!|(l_ZGQmyi|x)Z@_7^mhnNDJ?Cq);e?5XcNTwR zm^0U^_~?L#^Yx06ADGFFpw4Y{kWV*UR6lfx?$$|LNRxa!D?q#7*_?71DYce4t^+>G zm4!m>psatk-U#8kyzwE!jptHxZGp|@2Z5O{4Jjk`ja~?Z&~-iPM~lacaj>kTXmW9Y z`Fz)#W~Wpw{GJLd4q95QLy-Nku(P!pmH}Nnmzb{@AVb`<(=aXy>&k{W^i1z4u_u3B zaytr{N|ACyiLL9OdcTQUUR+$t*5^48S^Y6d|73S{q~BWqkm_$=0VZ{&6J_~egN5Vvc$4U7Twi1{D zAv20(he{W}G+_hcVnU>rOU7TKW3pnl0$0~axBg~rCHeKK+ebd>+x=&!MW>gr^+kz9 zRj=A4I4`^vP1HF>XP&zA)+9mD$_39tygYW3*mwm$^C_#*n0*L)pxWqbc-WUwd=TC* z5q-%N3LBmKCFN5=MBWe(%=zDa{6884a)mu6@J&*Kj9Ud6-Et`G3pF}9D^EIu> z=ajk{tx;b&HVq37{QloF%1mVxy`kRBOck561)zuMppgVMcTeezVySx;hXenz>a_7=2gv~Xq#UU~=jWK@X(kxr@R;xy1dno&9 z%n@k+d%(4C39}@RUHG@a4p7rDiby@J%-R>oVliD5k`A|zcEM*2AL^SEsBTU(0 zJWY7#b?(5=opyOo=yo}P8taoU6H98OKm0X6Nci`+4c30vF)j}lW^s>YOH=T_D72Md zWkDnLP#S6+LTAXz!&D*V_U`(U*8cuJ#r~yuY~3n$aYC-EMG(kMr8vYg4dz=k-REkd zWGri3KJc|;>HhB$vmaHMvN_vA<={-ms;80H`W+s}X{2fbr@s;uEijwona+SFC6~9RMOT zYBBls9X8r!IU&S8dl%&ueFra*nFgzYnPSvyRjr`S8rx=ppD@@A)zV!%^8anVMQ2M9 zN|oa#VPklho~gOj%-*Xg{U3U}`QvZ94)U;~Lr(p=aBZCigc5|qSQ}GS@+8Urf%47; z`mDr#?9AhbvC>E0rd&_NPReg6^s1WS3BU@g4DgRQz4-IvKnXJ*)Xc5P0@+}gE!pmn znmCfS{N9n_jNHnnuJ$bLK~g2*#a!)9zq9fk^Cd8$J;FI~2({I^38*K1vhZF3t=qR9 z0LPGXLnW}_sWr@VCkU>&!y44kzNH7^hx-}6i^V4@F=#kPH}{|Y!cvz-EdZ_kFej`ttK;SjGt zf?=gP8UEtOLl>#q*?Xr^8gBb6`AiY=SCj?`(-TEpO^}JO3q@Od4{`)=eP$(`HuKRU z^#1BcmbaJxZO%9cYDDsP__9$^I;b`tY9}im==sKYBVZ=#9SluP;P)OIG{OK2ey{=U zqQO(M!3;DFp#vo9KuA&9gO2S+njF3_?UC#@+AJSrAA&NuoDs#|GpE7r(a04zh|Gcx zpSL?>Q;2loomU=p!@ay|BX4xZ_OPf#orO6fB3c^cd8zY9BexN|uRT2FzTeT1Vhq)M zNA1JxV9i-H6!N!1(?JUrXS@vc1e`zfuqH|;b=y|*e-mV*R;HecG~({RSzY!5Uf*+9 z;wvQFhx#e5@b&;TMmj0XWZo3Q|4K%j`x#d5y~oi-4jp5oc#qUzc_4*ZMg|e9iS})0 zA#01F^g&9vnE&}>#+sXe%UQc3*8)r3xv5n3sez4aw5av|kIboY8i?9kc96Ym4 zLt_y`c2WzBw#`LhpA^YO8O;oblp1#fM`{-DlP3Ue1y`|;)?&;;Bu z4aRIx;!pvz$_zu$1I%KXg%on|w+F%9*vwZA3y}3_+eqFC*l3^5G_uEJ_#v4ZZy{pq zaWvwiwvjfRO8~f|@|N>dR9ZzqX!I&NRaO$Oib-jw9$6XesKM z^yG?_)L$q_N_H;LPzcT1<;7{QGz23_<5&p|RZp~rgIA?`2%%sc5)L&0Qp8bz+AAnix~(0m*>tp-Ttyi z{N~u!5b_TRjyekUI5>+=(SU4l=?H$6G5?T~aTfuL1|VkNDy_!s!YbbgdK0Fr01?ru z2Tg!pBP?G=5*vCM24&n0iqKt!!=A3R=OlZq!oIBsAq8{!2VK~t_R=Bs%y{0LWEPpP zn{rfh1~&YLnVd8@!ma=2U>^X=-gHnwq-KJJhdNJGq43i^H>n=j5XSIs34W(3y#v|4 zPA?`3ET*%bDjFs`B<3!LJ+v z0OWn>qe6lq95lA)D$p3F1<~Coz}{$K7BaZ?s>0yu;pV-CK+ebewqHeEQ5+2g0d!sN z)G{x;SP0zZTi<2yU3!paNgs=4r#Lj(_mexr6Q9u4?QO%pvcHRtq3oMOG-!5cfS(A| z175y%&(o!!{{b(-yBEBq*axr2Zemz#vSSE{VAaK_8^K+niJr=n5SzCL_WX7J&zLf= zmoLN8DxWpSmn6k6*z;e!SYuoMY&m*SsF26^C_YyI@OLqr5wWc!FMC%WwKkF8%cA)A zT8R(wMtugqa-di}FqWk>RWLSjp-A{pYxAm9!?&vmxEovWEETzROXK&Wx|+Kl$;Q(H z`9V;>Ovn90a|h7w`=)ldybngL245URGSt1n1oTC*BgUMcme1N5%`nPYykWdiN4vM?$w(z&^lEa?itj*b)bx)OF4MoFS@g$OCCfOB#a6J1uV`$qm zU6@Py*|n7=sGn-DLny9pozzAwaIynD;Ue+#f{8w5DkWZbSluNGVP*dtfy-vTwGxjy zC*Q=VI`wbd8N_-dyO~MbGvJG|%1DxDioCKji~jKOj!Rm8KTC;1xd z4(QmVb9&7E*Mwz^nay1|{Iwya-0l3Z=hcTT?(BMJ*n93bQOd?~oLg7XQle?(<%ivS zg%U@N)38yOmpQ`4&yU_oNuPq1GlB(GwaX=siby`{Bx3WsZlO|QEKDg`e;kk@0f<57 z3quGlr}`i5`1`*#+PlThfJhtlmZDpXzD^co;&Cj%`)xj|tfFv*UuPk#Sf}-r6Vwvr zjh<7JLAU;!D+Q)BGbvtWd)$`6DMvD?oorIWp-2^%f&2k+RU$SO$zg3ryzepBK2ce~ zf*0is)krYG%c6_)(<0LCxML9vtf-b95ic`9ULgP1`z@MKW!A@G;i!282Wp&!`cp`< z5AcQoJmevgw_uY*aPOlxD_33VY*7@g##5-(7;_E}P^X6n&UXjjQ7j zkCjzpKiEkLhe#^c;KHn~`x`)pkQuu^Ex%A8Ekf3@#q0ts<;Q-Ql46H-gUl_;9Qy~t z_oJ=htaLi-_*-LPJe=(4Z*GOhu*PhQxQgUBrSlhBqX&WS7QUh3%5P~WlYr*qjsM-F zoEllHX|3VSiK+ndyJ?U^M96~%ziacCn~qwolRHpLnTSUR&um?G=I94q-)e20v<&%u zDN7RFp9~MU4z3_fb#DG*Zi~Z0y~@mB3{s&Q4vERUHyuUKxL*n%I$RrEIAt!%U8VVY zyN=!W`3}uk9o%O5p->Iy>A&RMB<6Zg5JsOd-UoTs)C43MP+YPr{h-mSy(vEJpMw35 z&VDog;aVm;1rVxEvD(^t7qNpho`b zDdwR#=n1WSsCf%)uQH!**8L0UE)0p-wj1Sle&FA8ke&I`lGl-nri7f1$=Pc2oqC%! zIsVl9{kO%op;v~EW=goo0HWC)Pzt&=8cZ)p9%caeOvCvnGtcIG$EGk`hv$m8+7flN zDzcg*b*Is+*Xh}Oy)O%rC2r!Cn+9EBwd75aHB!tYsE?egL+;~J8^PzkFl6=DzkTvG zQ61Dnw$NEZYsTmU3_2IU-DF-zPZA$yQ)!W<(x+3L55ZhY$Q>AMON&*?BB&5cIh(@KD^!Q@vplm?ws^4xOi%}lFq)L z28|Hv;rV%+y@r7&|~!GdAI_|MT*`pO{qYpDcs~qnRiiEBMZp z4L@p^aHE5iKW>dfW8+}a)Tn_;Wwgb(ifSj-@5L1oWxGGLt9e@4WkV0G6Wc=^ zkyAdOJyWfR1?}npOOSH?E;1glO2qkgg@w@cyME}=Ea&HwlaQm_oDMYT%}hW|6ku50 zc<6j2*o+&!$;2OS2zyy+hRV(4{^GzA3Bif&n(!J%;BA2p4le6}n6>t*ki}&Bt@&Xt zOt7*KP4k_l8fqxXBo%F!c5dDZx!Ziu?&=ooLs!R?6^O|4YbL0N)i8tD;d*#opZJc) zLm$XHfe@-f9**fO*TdY7bSWoHKe0#nA?J%8I^(tS9% z4h5Q?@!*YrTWQgN#kblhx>q0BTzd+kXGn3oT?I@4nOJ6cC3eff=fK)*Ix3fw!}kVM zVX?UNk?sd^S_HPsHa>h+0Ix|nQdiBXoy=G3l>M~$W;qw-cBW9k_q4ViOVGLwHW0-i zW8~GMQm9KyhUhX|tSqaYUw#49U+)(pog*UIiRmt-VA$Oi>tQ|0Ecr27rZWH z$n(+A_Y+o=U@PGTDeJ+?vOz;=!Ml+NtCV{4{1W?b50pQfMCp2lcSqmQh{jG`+#21f1z^5i$U}- zuPSurx`@Oo9G+FWT}8@Xyw3@S$LT34sWl=ys`N(G)-6oTzWGstg?%*OY}&H#UhZ7l zqfb)R43E?e!DZsqaVGL`|GlBJ7wQ(z(?J@oTfnzOk=w3ZO3AcC?65?Ax16`>iy1DI zJ0Zu3$`iBsjPPXPDtDsBajxm))4(%L4_`QTPLIUr78>^xk02N)OkNs#imy|bj{_E` zFoS2ETzyOZ-LCYd=-nOHhF3TquR!|CzoEb693rwFQTlYEzA+<$XuF5rTa(S;-sLoQ z!aF$~QpXSV5z~+dYtq3e{54k4kEAQ4s`LSL1T#+Zbg2R`yKMYI6tX zL2?U?Q9cvXV9`r-fCqL zqbC`avfUJP&~X3Q&qYLLuONLLMv=|cnh2{F@PvpTl80YVO*PyI$Tx@MH>TupxLtR; zbOE?A!_64EgZX&80DfG|61yq;TRedcKzkWjA#lh67m0153svU058NkIkh@z;M{p6l zB@c{x9bX&~0P{;p%j;*P3gnOf>MGR=3s7|+W52#d4c68zHjf07P@nHA zCaSK3?VJauFtarYs zkKo7K+X$KA{J?Ry$1K@6RZb$|baLD|4w0x=l0qv(iS{%LuIMUU@q zmY4$f4;FuP->AQ}f0!L*lGq!6UE2@wBX>&(>P59n-05%rze<@#($}ZcYLfh4y?a?k zzhj8zT8&;|f^UTHFMXjT=RG+^tdK=+dmE-NUI2c@`6Ge_J&H0HaMTk3A@)a0-Ao6? zEbP|)z)_qqS?y4H@(C5qTYPPO?q80&`pZ^-n*v*3m{@Hi^RPT>G!7LF)dLqDfNFJ4 z1s$tlz^=4=cgdRHMf*kKZ)|j752atPalOJ(nw?Q*g@y0NDzG(MoX9%*Vr*WK422TLI5hovyH*pLndqj=zy z_o8JPg3RHUb^)azV_IcP&$rI1nN*0);N8|RqXvKPP2gd7!*HJMoPT3M|E87=#;ki zKXP0*ZuI>-@VR!aMA@kMEf}-9+q3`LHvfVJA14hH-P77EHEC%NA7CD`yq0Xm{tn3N zkj2lTL)8Oe|344Ec91rX+bVC=iRDVI*1!<~>UrraQ-1n^Qo>+x$w`YtKW;vH3`s?F zX38n4?h)CQJN>F+)-7p@ZP>BB_Fy;GosQqi{cOC{=a-m8JtaNEXW0?d3#=peuPG7n zoZ)b}cpo7i6Q^H~@;haV(rqX!o-M^gvWlz3*tN8~yk%MrRtIh=Z6 zD%r3&dg}(X1dUg+9;0>BDm23khuf+(MA!(BjmHer9V)(v|+!P@7C#Q&|y{4nl={dhv2~=UUNGo@YNi zgfXl}=Ko>dyKD@IjY}Cq^{tEOA;Hj@prHX6oUw=;HeQi~^}LEXjGS3uEd=L(#xfBz z$xdd%_+7oFblBrpjZ+$agT3Xs?SZ54vZ^e8u9OUhCK^NJAb%?)r)OolBANtSEl7ua zC-!maL0BVpE;5@kGLh)e+aBH(@DURJ0vg#9J}t7cypu4%m;Wd1NtvVof(h-2DkB>y zmtlw8s!eFliz$zk7_OA^PF`QKI*j~7vXS2W9ezNBA8#{IZoJT1rSG8T!PJD)jUfdf zBv?)oN6bq>-FZ~9a|qNcf5{U|7VVXsvp_;!HqwH_ygxygt5K0k+aCTH;HY) zMx+#^ZV#`pJZwsnisa4>?2KMceiib8OOM0DSI9Hgoad3^shS@SK*Nphvi#o(vOqRv z%F~JR3CouUAHvj(1yM>!jqHM-0qxoi_-xn=FLW6*ckxG)aZVsb z;KRUECXXvf<(6Y=HHf-AV-o~D3Lv~m|L%^rXAsIRfP)nmpTS`s+*9`J^0$_L|9?m9 zijA`{a04QMeVUm(hHTtSy(?7)Kt-|^f|vFR4&2X#iRk(PyWm2OzsSsi3Y<^O1ZkAsK9)0h zhAYmmT)b$eaw&pbAG#t*mlX3)W%>bZkAUbTMLOtr8)LFMUjD+Nu4oE*;9RhuQWm_D z*D`^KlEZV`xo`{WC>;FTh3`wxu5SAO3#*Z*$0pFdU+`1 z`)>PBEe!fdC$S~v?l|A_<}jqp3BYv;$g)p^Xso-jAsNs_3C8P>nk#syQONCwTtD0< zF&Tz)ydfgZBva(zf2e7e$APTj(1dJnG&UO%Y=JsC0!IHGn4m06hz2C`jsw_egxnm; zCSA=d(2Bcfx|q8*ynU6Tcuq6UCC0I5{f%Pz?!c6D)B~NNDrb@CvAyFK``one1zo$D z6X-%-9ph)hUO_8{x$N+4@T+w}{;tGEGM0!e|M~EnPQz&|JztEGkYcl$Df8gX&64F6 zT1tlrhHK&wK%?1z5`6W-C93-J60vUWA1H-B>B>9eYru#VD$X;faq>T?Y?l8}fV{=3 z!D(N0)*9F6IKu&_Lu%Mlc++J`oZ?t}+|rt}pA8$x5S?pou&GOb@@UWS%*yS#W6%n| z;qZNEg5fec;Bef=>(YIEmMv3t$^^r+<*V!WqNhmrtxmENYqxbsY5TJ9kdb@p^Mss9F+2ICDFGGu&DABU9 zF_-s5-oO&#USz%EH8(vr$Y0PBS;nJLls8^jHz{#I9?9G#s zK+dAzzp9CeK5m-ajX#iDNbGJ1xf_u+v7-3tAKhX`5}MQ?LMjkE>a6tuW~rQ*j7He5 z0!a8}K_AYSYqWC&5ZJ{fS+Bk3$D0w3{Hdy~>>fB3nK#zmKtW+!MR>v4&Mq&AnB-f^ z&OGkfkyu77DSM4{g3DWZNSip={^S>w!`tEzI$~I#c7^pFWcr0Vz`7xrYaeoM*vn44 zJo3c(?Ooo%R&w=pk;ykz;#n{U+EH3k86}Z=4C#sX#v(_!aWx*F9 zMiT1-qgBgFJ5~t+FR|4OF8*FT9qR5ycp~`ry?SfdtKlLET|lfqx8-$2&L`&d+?Q%4YuUj@syVOO&Sjjdu1$-x{Wm^4KQi;Lm3z`g<7#hF@9gwxRk`-n z6PkC1UQb?};QTw(Y!jf3pkMtJgFvX#aMb1urSHLwNQUc690_q?-Bu1Foip++CFmWR zFrp;Qi9$pM=8lOIPmdy^dfy8muofLS1uE4r$S)iZgM#cmlG+UqMU3ETt2m7%9z>leD(|-( zGm}us3i}(CE_)CKRYg@c`Y?_=qyd*>x?)g!X+d$qVj(P6b6{(l1DswcXTs&uBd$oCZ!{xagcZ;^r^{8ie3-~faqE3zExxCuH z{&vU@SWowz0Q}+3Sl8qaKypmIXEjypr*Xc=7lsYgPKF*Zcs`tm6uwhdQ&tlm5+;SE zuxo{*o~MjL2O{F&Y|TTUm4zM;#(>5Jlf?yXb;VdADN|^plJxPu_eGmVH5iNPJqWAG zXwU`fyz~DzYD)TL=MU|yq4W%yRBelMx&xmL5I?yje7-3Ub}^N zgvJH-5+VpGJ@^w4+xuwYknLV|C_6hAHm15|0b%wJG^1x3z9YLe*@pqy5PGRecu+{K zFxd(JV!pU~(#2z)qCCUa8*lAdbKS7l-{)5ftJWn=@_{D5U(lD%M`h*}KVsh4HzAtD zxQ}&ajL##xgqwK9YSBVA)YJjjEzYgG`au95+v@A(HGag&3LWxy#yXr7?{D2icI`|# z5tZd4!W0>I6j9p{rwF*8jr+Qne3n)PeXH%SK%?~YuZa12?)O&Tp~x7XVW*NzB{^wC z50dI=usW!lp};?WGZdzDz2B*-@#keDWt=YQs^i$|wbvTiA?0`>mcV$J`~k{;ft&RS zBXum)LvC3FHst)((MfF>LO(}- zo?UIOY#C)W)f@lsJ4kQM8V4KEjLtL1H#S0c%4(Q|gIeiK?Lzw^MT{dsej!JS^!$+; zo;P9nCo84(S@Fxsy@g-XvOC6lWvabKg~ z&3;Tm?Lg#uk9C93vUXJ`4zcPS==i=I2PS{yv0*Mrhi>*iy|SHICFfOJ zqhlvu_a3{5S01T@ML(^O+(on=vP?`GK~2&z)AtH601NRCJ?xs*!3TXqQ&=xJK5ias z>yUB5fy z;XKEVV54iqd88}YJ3i@rrRM&5wO&5gi@g6quawE~2E*c!=YcMd`zhrh<}ug|L{(P_ zMGEP;sEcQt1v!mcz{?`+{JlOWXOFkgt+W7)<$@s4Us9&%H-Iu!aMVGPvOZFA` z>mm>~Dw-Tf^+Nsvg&CO8cwC0L+JDd*ngaGIA{w2^jE=2ns5;#Em(jiew>PRe@tL~L zN?_^T-`>douU{F{j4RVIa%ZKz?>IW>Kp}*{B+{kN);in)8*rSWEc0O1wfWz$c_^;o z03l#$UP^3k9<$O|x>S#BW4*peeurxu(dyfK$Gg>+T||QTt^$lbpj)At(4wat%Npex z@|EhkVPLAc8^*Kp;VKWmjO!(9VQR-tL8PEk5@zj;dvPP$xOd_G*xZc!h%5y3j!-@V zz3_NpsC%|dH$}2#I3)Q?Ctn_TJi_rr(>DPjrI=?-p0utN%h&*|(rMYR(&S#yB(> z0ZWE!mJQpad_Wn}F?}#@aI&(~P||<+4ZEa2RW9jcw_D+XrMHw!Y@Hp6PWENkWnKTn z8I3gT+VT4pFk|+AVpfOEK6NXzzF3wyS5h%#ZS(gBN)8Xk2>^=VzUupe>H`^^knRU6 zfwvd4=Vqrp@BiM!su4aGVn#+zpaYEQ9CTQ_xaUR4?VT*msZKbs6ig`R#)vP6w2xI% z_BOHa?dExRGb_v1a_MMv$usfL5*U3I=>TYS#d!0UmY4#`KY-;r1*VyYO&0c)Jt><1 z0<&axzkmsPXKTj4VV70O+~`Nu(z)E}c-ih-d-_Xi67AdOUXI4ESs)EJHb8>b1yZQ) ztXkEbM9@1Zw%35|Tpp$cm@`Tw&n@pu&#xvFNd9r z$G;q=0o5)x7?a&GDKf|oQwp5k{xqY`u*m@tY?Y#y>p(Y1Jl_EW?l2)IeL_ZLkdUP51+SMx~@C!dN${G zj(@gd;ops?S-02bI4BjYove7rJa)Nqt|#ISc*G_h8E$lIz4*5b1=I6N(ncH4oll&V z&)4?cF3mi2#dVuKiUiw#dbb5k{`8JO%EpDRc3qN< zC)ZgIO^C90{d*E&13?GERyH->m32MRuJl2imq?$-^J$)w9&`#*p7X`5HNWUSU61H* z-;xUsBsQ`jCTTeGbek(IBv5+De8fH!XJP2NSBq+piE3^IK#ZibP^(el$*i}SKUwEt zHfSk6bb6g5?iiA-Nw*svc*)dEwAk{K3m~eJsaLQ(x$}^_!)nj`harsU(++zegpfuS z>~~GuUy*-GeP5Bam#8~{rxlqYV5o2+mEC&nd1qb;+-U%g3rEIPKMszn0&-aC?? z&^B^{2D^>(SQnlXxNVSfIj>z_7{qTr#mu6FY$$f~iUflIk~hlJaP<)Dr#Idp$oVqY z#f@}@d@-}obnR!n3C-L4JP_wN;8Eao?Cq!+5W$yA?+qRYUwhv^@h2b_EAjx7&6`L| zLgJ}nA3G?AQapxaYyW%&DtJVTbbSX+RFDzira!Qp2So=Y&@55($zBiOKm?#dj<86A z$fL^kp9l=ixX|nbo90i=#gKw2$NykoB+r%`9P8z zv1JK4--3DFnJd9dkb(1Whsxq}X)Ps`b%n{Y{b3I^96ug9;Tcr|65jrOYSuV{loym* zeD_fb&2H69T+s&KIh@E~{lesoWETau(A7jhPY}+AD!(JH%1kzWw`6JuEA=r{$$Z@? zoRr)LeX3u%wGRUGZ^wmjS2{U0cOxB%z0?Gmvk;;aE?7~iBN(R&+@%`v{<=vWfD)z;{R~<|}6sn7c z73{(>oHW+6!3F+K>z2ewfN7qj=-KI(EO>K@qmeL>3`H8 z_4o`r{fwQAdsfQHndj4ckGcNe2T14+0Z*J9SbCq&&GvR@%^F0g(Eg=iZL9Z;?gdBH z;fYWHg%p`rBuJ%ft0R$~hfTWUlZ71nAqoU?Gq}yrZxXIYRKw;#^FIW^701*9l&lxN zGXMl=vh{yAB9obiC>>;8xBF&?N*Uz%M9+t%MU$-;hKeU8%)omvn3C_NW;937*K=Rvt3ihos4}PN$HcN+?#4ePZ28tW^a>u3@{0-Sr)~ z+r>M?_dq+S*=cwvt4D}t7rPn8M{zh8j9}*I!MBE=7Ye@l^codACatT#AqRpfBQ3hN zaH$@>2@LexuAU&3@w4+Ss&F6uWT2KUI!~_Q>GNupq~|#r0HlIbv$)Rkd?@ONa1J4? z37;A&+Ug60qdcUd-F|!Q*lH(m2uML%)D_cfsgl}gY;ibWCo7q)f;NfRB9Ob@z=c^K zG(3$z&koyo{DGuT!5`6_sjvKO4;wQ(&5f=PnE#h*Fp#S>_?686_($YQ!hgVgn#&zTqTqt6;2&_nbxidDoe zRHH5F9T!_r-gRa{o8kZ&>%38ql)99D+>Bh&-`@WZ!ZP{{$j_@A*UbC)ZV4vAkxsbU zP&!u{S6m8!53r6hK{W~`?4+-jEWwWShm!GXVALZ;wK1pBOoNe zZZnB{3cX5`^hJP2UcSO7~K0*0ZnO z<9UT~c~;-JvaLYJmC^MK08%Fz7zioDEE*JDY{|QjA%`~n7XysJv6wZCr=QGwXMoe+ z+2TX+jwH81AD_rf1|ze<=KnS(ge1DDb>)G3f*PA-)PCMc%9^|7Y2}Y6t~%Y{l~Gap zu7J71o4a5p2!x`>w)4$Gk-e1dnuU)U9*Bxi!4vqRq6y-2h^Zd)xTMhqY22BAgOgcB z^R>fLS;d_HJBgkty%$*T29uBYadHF=;gz^|?!4&v0;hiP+Hg1Y-{z> zv->_@Kbza20zfp!0_V_>?#|`fU&%`o%ip^1ZjA~;k7~NSN{ORe+0;{F#yW=b+ZuPF(4kohXnfDcy1K50k zm2V@n5VBq1e3f-8`>9rMe@HBr-iU6R^Yo<4%W(iZE@z^d=7-h|K2S+Dd&6^SD)=gB z!UxH?u%HA8!13@l8(S`tkUBpmRTA_6^mL_BO&wu0?2wdA*#rU<1q1}N%1$jrE4YLx zNF!SS+k*j`M#>U`LTC#f6eLnnYmg=2K|u{7Ph=4a6r+_bp-9?L0pWlP1`sKWNa)MV zYv=dNcP4q6nQ!iQzk4ZE%X7dr&C$swj24F#aI8Qfr zxdX=?^ajB0xt+FHOX)*_V$F46eK`i86f+d*-%<8aS-EJpb?d^S^66i((Ov!+se@^%R;4S~qj_I0ibk)7{D(MnnBdZlpW9Yy$lG zIV&j?1W8l~e)z7Qbh?W9Cbw|Uu!1L=N~nUHe@4fS`0!EU(u~(2Jb|r2?Tt_uuo0If z7{m3gb~;kDnau4}+Qr(4$TtwB(UVp&bpwq>@ndo=t zd8%x8r_ygwsPev1`I2tt+I>-}XQlm(&X8i*fROeqq!<--=mZ;a!A%ZGc9|B}yv?Yg zj~kAoamrs~^$A822e?%(`vn&WY7WrZf#V#Vvxq}^eY-EeH8V0e@cgZX`OM!V4r$?h zYamwss4%HCy)SrhIB%4)vh-R0HAT^(3Ue>`PojiT98OC>B{@Ykw1>}ybrxG(g;7M#T!44!Lwwy(oDI&8^6HKVzFyc!`<=xq0C=W+C%9@rp_5Jpr-f+LHK1 zm&Z2&r+#AFsU-_9>Zt1)Nq;fnGvWs>>tM9SJmQ(9n0|0{b`TT{QFLO40wp7&Vvw<_ zo=z^n{oYrNNGtCirW1)dsq&8nasp?Xw{b=CYxa!6?~p#i?4Q87F!Ad&GrEFcHOpXgrA zjBMM6Y_!8WQQ~G#yU>T!uDX%wtQi9-=i{C?MA#_6!^F32(%<*GqXw1a3V1y-Wop7N z^A2nVyjwQJTSk_+xB8QI zs999AfFfnPnW8?0-WA4VmGuBC$b|`pCu(h?7|(|6r-)={V`-5Azr>weTTx~Hf*?)t zV-LGI+s!?7B;}nKd*O{4+W{NW7Bcqq*NI@RQj64JQoULLI2zR>GpXvigWKiP~hTWt{O(vu0bxKT89Wn(y zX)C(?M)EZx)@RqRXR6VB?UtE6y*a7fM*NapuWOZPQI-<;8~YLs4N2k0wjzavq*d92 z<_+!oBJWFwY!RRP)>giBc6J+w!+#W(24Y_@6`Z5doDr^tmJ|21ogIN8k!>!>(qXi3 zekYfcreE42Zf>N6SX)FWBy}fDk;yq - - - Kafkatorio Web Map - - + + + Kafkatorio Web Map + + + + + +
From de419aeae8b055d56732cdad1d15775141a6beb9 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 3 Sep 2022 11:15:43 +0200 Subject: [PATCH 507/629] web-map tidy up, and add diagram to README --- README.md | 38 ++++++++++++++++++- .../dev/adamko/kafkatorio/webmap/App.kt | 24 ++---------- .../webmap/config/ApplicationProperties.kt | 2 + .../kafkatorio/webmap/layout/headerNav.kt | 13 ++++--- .../kafkatorio/webmap/layout/homePage.kt | 2 +- .../webmap/layout/servers/serverPage.kt | 2 +- .../dev/adamko/kafkatorio/webmap/map.kt | 7 ++-- .../webmap/services/WebsocketService.kt | 10 ++--- .../src/main/resources/css/kafkatorio.css | 11 +----- 9 files changed, 60 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 94fc22c..54c20e7 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,42 @@ and WebSocket APIs. Development is ongoing. At present the only application is a [live-view web map](https://factorio.adamko.dev), that shows the current status of a Factorio -server, and any connected players. Other possibilities are exposing metrics, and inter-server -communication. +server, and any connected players. Other usage possibilities include exposing live metrics, and +inter-server communication. + +### Overview + +```mermaid +sequenceDiagram + +Factorio multiplayer server->>events-mod: in-game events +Note over events-mod: converts events to packets +events-mod->>logs processor: packets logged to console +logs processor->>Kafka: publishes packets
(Requires API key!) + +Kafka->>events-server: + +Note over events-server: Packets are processed + +events-server->>web-map: Web map tiles (REST API) +events-server-)web-map: WebSocket updates
(e.g. player movement) +``` + +1. The Kafkatorio game mod, [`events-mod`](./modules/events-mod), collects event data, de-bouncing + and grouping events, and converts them to JSON packets +2. `events-mod` prints the packets to the Factorio game server logs +3. The Factorio logs are forwarded to a Kafka cluster, either using + * [syslog](https://docs.docker.com/config/containers/logging/syslog/) (using Docker logging + plugin) + * or [Kafka Pipe](./modules/infra-kafka-pipe) (a script that reads the server logs and forwards + them to a Kafka topic) +4. The packets are consumed by [`events-server`](./modules/events-server), which processes the + packets using Kafka Streams, creating and hosting map tiles. + + `events-server` serves the map tiles via a REST API, and produces WebSocket messages regarding + updates (for example, when a player's location has changed). +5. The `web-map` uses Leaflet/JS to display the map, using the tiles and WebSocket messages from + `events-server` ## License diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index 35b0729..f823576 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -50,12 +50,10 @@ object App : Application() { var siteStateStore: ReduxStore by appState private set -// var wsService: WebsocketService by appState -// private set init { this.siteStateStore = createReduxStore(SiteState::plus, SiteState()) -// this.wsService = wsService + require("./css/kafkatorio.css") WebsocketService.packetsFlow @@ -78,9 +76,6 @@ object App : Application() { this.appState = state.toMutableMap() -// val siteRouting = SiteRouting(reduxStore) -// val websocketService = WebsocketService(siteStateStore) - SiteRouting.init() root("kvapp") { @@ -99,9 +94,6 @@ object App : Application() { } } } - -// div("Kafkatorio Web Map") -// add(kvMaps) } // kvMaps.leafletMap { @@ -124,20 +116,10 @@ object App : Application() { } + fun main() { startApplication( - { -// val reduxStore = createFactorioReduxStore() -// val wsService = WebsocketService( -// reduxStore = reduxStore, -// ) -// App( -// reduxStore = reduxStore, -// wsService = wsService, -// ) - - App - }, + { App }, module.hot, BootstrapModule, // BootstrapCssModule, diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/config/ApplicationProperties.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/config/ApplicationProperties.kt index 02485cb..652481c 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/config/ApplicationProperties.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/config/ApplicationProperties.kt @@ -4,6 +4,8 @@ import kotlinx.browser.window object ApplicationProperties { + + /** Determine the WebSocket URL based on the window location URL. */ @Suppress("HttpUrlsUsage") val websocketServerUrl: String get() = window.location.origin diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/headerNav.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/headerNav.kt index 5cf782f..10d6702 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/headerNav.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/headerNav.kt @@ -3,14 +3,15 @@ package dev.adamko.kafkatorio.webmap.layout import dev.adamko.kafkatorio.webmap.SiteState import dev.adamko.kafkatorio.webmap.SiteView import io.kvision.core.Container -import io.kvision.html.div -import io.kvision.html.link -import io.kvision.html.nav +import io.kvision.navbar.nav +import io.kvision.navbar.navLink +import io.kvision.navbar.navbar + fun Container.headerNav(state: SiteState) { - nav(className = "navbar") { - div(className = "container") { - link("home", SiteView.HOME.path) + navbar { + nav { + navLink("Home", SiteView.HOME.path) } } } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/homePage.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/homePage.kt index 2356aa2..91187c7 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/homePage.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/homePage.kt @@ -40,7 +40,7 @@ private fun Container.servers(state: SiteState) { // } // } - button(text = "$serverId") { + button(text = "$serverId", className = "btn btn-link") { style = ButtonStyle.PRIMARY size = ButtonSize.SMALL diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/servers/serverPage.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/servers/serverPage.kt index 7d8d2b3..2319b6a 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/servers/serverPage.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/servers/serverPage.kt @@ -9,7 +9,7 @@ import io.kvision.maps.externals.leaflet.layer.tile.GridLayer fun Container.serverPage(state: SiteState) { val factorioGameState = state.factorioGameState - div(className = "server-page") { + div(className = "server-page container-fluid") { if (factorioGameState != null) { add(factorioGameState.map.kvMap) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index cc661b4..e47c3fe 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -122,6 +122,7 @@ class FactorioMap( } } + private fun createServerTileLayer( layer: ServerMapTileLayer ): TileLayer { @@ -160,11 +161,11 @@ class FactorioMap( return baseTileLayer } - private fun tileLayerUrlTemplate(layer: ServerMapTileLayer): String { - return "/kafkatorio/data/servers/${serverId.id}/map/layers/${layer.dir}/s1/z{z}/x{x}/y{y}.png" - } + private fun tileLayerUrlTemplate(layer: ServerMapTileLayer): String = + "/kafkatorio/data/servers/${serverId.id}/map/layers/${layer.dir}/s1/z{z}/x{x}/y{y}.png" companion object { + /** Add this attribute to `` tiles that need to be dynamically refreshed. */ const val DYNAMIC_RELOAD_ATT = "dynamic-reload" } } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/WebsocketService.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/WebsocketService.kt index aacb43f..8553f08 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/WebsocketService.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/WebsocketService.kt @@ -20,6 +20,7 @@ import dev.adamko.kafkatorio.webmap.rootJob import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow @@ -33,14 +34,13 @@ import org.w3c.dom.events.Event object WebsocketService : CoroutineScope { override val coroutineContext: CoroutineContext = - CoroutineName("WebsocketService") + Job(rootJob) + Dispatchers.Default + CoroutineName("WebsocketService") + Job(rootJob) private val ws = WebSocket(ApplicationProperties.websocketServerUrl) -// private val ws = WebSocket("ws://localhost:12080/ws/foo") - private val _packetsFlow = MutableSharedFlow() + private val packetsMutableFlow = MutableSharedFlow() val packetsFlow: SharedFlow - get() = _packetsFlow.asSharedFlow() + get() = packetsMutableFlow.asSharedFlow() init { ws.onmessage = ::handleMessageEvent @@ -69,7 +69,7 @@ object WebsocketService : CoroutineScope { if (packet != null) { - launch { _packetsFlow.emit(packet) } + launch { packetsMutableFlow.emit(packet) } when (packet) { is EventServerPacket.ChunkTileSaved -> {} diff --git a/modules/web-map/src/main/resources/css/kafkatorio.css b/modules/web-map/src/main/resources/css/kafkatorio.css index 2533785..00e0e43 100644 --- a/modules/web-map/src/main/resources/css/kafkatorio.css +++ b/modules/web-map/src/main/resources/css/kafkatorio.css @@ -7,16 +7,7 @@ image-rendering: pixelated; } -/*html {*/ -/* background: #2B2B2BFF;*/ -/*}*/ - -/*body {*/ -/* background: #2B2B2BFF;*/ -/*}*/ - .leaflet-container { + /* make the Leaflet map background transparent, so it matches the site theme */ background-color: rgba(255, 0, 0, 0.0) !important; - /*background: rgb(34, 34, 34) !important;*/ - /*background: var(--bs-body-bg-rgb) !important;*/ } From a84c4a2f76cb0f3d0aba664f302ccec4aa614962 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 9 Sep 2022 17:21:09 +0200 Subject: [PATCH 508/629] refactor web-map to be SPA --- modules/web-map/build.gradle.kts | 5 + modules/web-map/docker/Dockerfile | 3 + modules/web-map/docker/nginx.conf | 25 +++ .../dev/adamko/kafkatorio/webmap/App.kt | 27 ++- .../kafkatorio/webmap/layout/headerNav.kt | 9 +- .../kafkatorio/webmap/layout/homePage.kt | 116 +++++++++--- .../webmap/layout/servers/serverPage.kt | 2 +- .../dev/adamko/kafkatorio/webmap/routing.kt | 174 ------------------ .../kafkatorio/webmap/routing/SiteRouter.kt | 87 +++++++++ .../kafkatorio/webmap/routing/SiteView.kt | 22 +++ .../webmap/services/WebsocketService.kt | 2 +- .../kafkatorio/webmap/state/SiteAction.kt | 24 +++ .../kafkatorio/webmap/state/SiteState.kt | 55 ++++++ .../kafkatorio/webmap/state/playerState.kt | 1 - .../adamko/kafkatorio/webmap/state/state.kt | 1 - modules/web-map/src/main/web/index.html | 3 +- modules/web-map/webpack.config.d/webpack.js | 40 +--- 17 files changed, 329 insertions(+), 267 deletions(-) create mode 100644 modules/web-map/docker/nginx.conf delete mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing.kt create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing/SiteRouter.kt create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing/SiteView.kt create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/SiteAction.kt create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/SiteState.kt diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 347a840..fc475cd 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -173,3 +173,8 @@ val installThemeCss by tasks.registering(Copy::class) { tasks.assemble { dependsOn(installThemeCss) } + + +tasks.withType().configureEach { + enabled = false +} diff --git a/modules/web-map/docker/Dockerfile b/modules/web-map/docker/Dockerfile index afc3caa..a4d5eb5 100644 --- a/modules/web-map/docker/Dockerfile +++ b/modules/web-map/docker/Dockerfile @@ -1,2 +1,5 @@ FROM nginx + +COPY ./nginx.conf /etc/nginx/nginx.conf + COPY ./build/distributions /usr/share/nginx/html diff --git a/modules/web-map/docker/nginx.conf b/modules/web-map/docker/nginx.conf new file mode 100644 index 0000000..1c37acb --- /dev/null +++ b/modules/web-map/docker/nginx.conf @@ -0,0 +1,25 @@ +http { + # what times to include + # include /etc/nginx/mime.types; + # what is the default one + #default_type application/octet-stream; + + # Sets the path, format, and configuration for a buffered log write + #log_format compression '$remote_addr - $remote_user [$time_local] ' + #'"$request" $status $upstream_addr ' + #'"$http_referer" "$http_user_agent"'; + + server { + listen 80; + + root /usr/share/nginx/html; + + index index.html; + + location / { + # First attempt to serve request as file, then + # as directory, then fall back to redirecting to index.html + try_files $uri $uri/ $uri.html /index.html; + } + } +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index f823576..fdb7f84 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -4,15 +4,19 @@ import dev.adamko.kafkatorio.schema.packets.EventServerPacket import dev.adamko.kafkatorio.webmap.layout.headerNav import dev.adamko.kafkatorio.webmap.layout.homePage import dev.adamko.kafkatorio.webmap.layout.servers.serverPage +import dev.adamko.kafkatorio.webmap.routing.SiteRouter +import dev.adamko.kafkatorio.webmap.routing.SiteView import dev.adamko.kafkatorio.webmap.services.WebsocketService +import dev.adamko.kafkatorio.webmap.state.SiteAction +import dev.adamko.kafkatorio.webmap.state.SiteState import io.kvision.Application import io.kvision.BootstrapIconsModule import io.kvision.BootstrapModule import io.kvision.ChartModule import io.kvision.CoreModule import io.kvision.FontAwesomeModule +import io.kvision.html.Link import io.kvision.html.div -import io.kvision.html.h3 import io.kvision.html.header import io.kvision.html.main import io.kvision.module @@ -20,7 +24,6 @@ import io.kvision.panel.root import io.kvision.redux.ReduxStore import io.kvision.redux.createReduxStore import io.kvision.require -import io.kvision.routing.Routing import io.kvision.startApplication import io.kvision.state.bind import kotlinx.coroutines.CoroutineName @@ -51,6 +54,7 @@ object App : Application() { var siteStateStore: ReduxStore by appState private set + init { this.siteStateStore = createReduxStore(SiteState::plus, SiteState()) @@ -65,27 +69,17 @@ object App : Application() { }.launchIn(coroutineScope) } -// private val gameState: FactorioGameState -// get() = reduxStore.getState() - -// private val kvMaps: Maps -// get() = gameState.map.kvMap override fun start(state: Map) { - Routing.init(useHash = false) + SiteRouter.init() this.appState = state.toMutableMap() - SiteRouting.init() - root("kvapp") { - header().bind(siteStateStore) { state -> headerNav(state) } - h3("Kafkatorio Web Map") - main().bind(siteStateStore) { state -> div(className = "container-fluid") { when (state.view) { @@ -93,6 +87,7 @@ object App : Application() { SiteView.SERVER -> serverPage(state) } } + SiteRouter.updatePageLinks() } } @@ -107,6 +102,7 @@ object App : Application() { } + override fun dispose(): Map { rootJob.cancelChildren() rootJob.cancel("app dispose") @@ -119,7 +115,10 @@ object App : Application() { fun main() { startApplication( - { App }, + { + Link.useDataNavigoForLinks = true + App + }, module.hot, BootstrapModule, // BootstrapCssModule, diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/headerNav.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/headerNav.kt index 10d6702..a419b67 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/headerNav.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/headerNav.kt @@ -1,17 +1,16 @@ package dev.adamko.kafkatorio.webmap.layout -import dev.adamko.kafkatorio.webmap.SiteState -import dev.adamko.kafkatorio.webmap.SiteView +import dev.adamko.kafkatorio.webmap.routing.SiteView +import dev.adamko.kafkatorio.webmap.state.SiteState import io.kvision.core.Container import io.kvision.navbar.nav -import io.kvision.navbar.navLink import io.kvision.navbar.navbar fun Container.headerNav(state: SiteState) { - navbar { + navbar(label = "Kafkatorio", link = SiteView.HOME.path) { nav { - navLink("Home", SiteView.HOME.path) +// navLink("Home", SiteView.HOME.path) } } } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/homePage.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/homePage.kt index 91187c7..799dd7a 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/homePage.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/homePage.kt @@ -1,55 +1,111 @@ package dev.adamko.kafkatorio.webmap.layout -import dev.adamko.kafkatorio.webmap.SiteRouting -import dev.adamko.kafkatorio.webmap.SiteState +import dev.adamko.kafkatorio.webmap.state.SiteState import io.kvision.core.Container -import io.kvision.html.ButtonSize -import io.kvision.html.ButtonStyle -import io.kvision.html.button +import io.kvision.html.ListType import io.kvision.html.div import io.kvision.html.h5 -import io.kvision.html.span +import io.kvision.html.li +import io.kvision.html.link +import io.kvision.html.listTag +import io.kvision.html.p fun Container.homePage(state: SiteState) { div(className = "home-page") { + introduction() servers(state) } } +private fun Container.introduction() { + div { + h5("Introduction") + // Kafkatorio + p( + """ + Kafkatorio is a platform used for creating + Factorio mods that require communication with an external server. + """.trimIndent(), + rich = true, + ) + p( + """ + It was created to explore the possibilities of using + Apache Kafka + to process updates from a Factorio server. + """.trimIndent(), + rich = true, + ) + p("To keep up to date on progress, check out:") + listTag(ListType.UL) { + link( + label = "Factorio Mod Portal", + url = "https://mods.factorio.com/mod/kafkatorio-events", + target = "_blank" + ) + link( + label = "Factorio forum discussion", + url = "https://forums.factorio.com/viewtopic.php?f=190&t=102841&p=570598#p570598", + target = "_blank" + ) + } + p( + """ + Development is ongoing. Presently it used to create a live-updating web-map of a Factorio + server. + """.trimIndent(), + rich = true, + ) + } +} + + private fun Container.servers(state: SiteState) { div(className = "servers") { - h5("Servers") + h5("Factorio Servers Live maps") if (state.serverIds != null) { - div { - span("Available servers: ${state.serverIds.size}") - } - - div { + p("View live-updating maps of the following Factorio servers") + p("Available servers: ${state.serverIds.size}") + listTag(ListType.UL) { state.serverIds.forEach { serverId -> -// div { -// link( -// label = "$serverId", -// dataNavigo = true, -// url = "/servers/$serverId", -// ) { -//// onClick { -//// SiteRouting.serverView(serverId) -//// } -// } -// } - - button(text = "$serverId", className = "btn btn-link") { - style = ButtonStyle.PRIMARY - size = ButtonSize.SMALL - - onClick { - SiteRouting.serverView(serverId) + li { + div { + link( + label = "$serverId", + url = "/servers/$serverId", +// url = routing.link("servers/$serverId"), + ) } } } } + +// div { +// state.serverIds.forEach { serverId -> +// div { +// link( +// label = "$serverId", +// dataNavigo = true, +// url = "/servers/$serverId", +// ) { +//// onClick { +//// SiteRouting.serverView(serverId) +//// } +// } +// } +// +// button(text = "$serverId", className = "btn btn-link") { +// style = ButtonStyle.PRIMARY +// size = ButtonSize.SMALL +// +// onClick { +// SiteRouting.serverView(serverId) +// } +// } +// } +// } } else { div("no servers available") } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/servers/serverPage.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/servers/serverPage.kt index 2319b6a..b377249 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/servers/serverPage.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/layout/servers/serverPage.kt @@ -1,6 +1,6 @@ package dev.adamko.kafkatorio.webmap.layout.servers -import dev.adamko.kafkatorio.webmap.SiteState +import dev.adamko.kafkatorio.webmap.state.SiteState import io.kvision.core.Container import io.kvision.html.div import io.kvision.maps.externals.leaflet.layer.tile.GridLayer diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing.kt deleted file mode 100644 index 88a4759..0000000 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing.kt +++ /dev/null @@ -1,174 +0,0 @@ -package dev.adamko.kafkatorio.webmap - -import dev.adamko.kafkatorio.schema.common.FactorioServerId -import dev.adamko.kafkatorio.schema.common.Tick -import dev.adamko.kafkatorio.schema.packets.EventServerPacket -import dev.adamko.kafkatorio.schema.packets.PlayerUpdate -import dev.adamko.kafkatorio.webmap.services.EventsServerClient -import dev.adamko.kafkatorio.webmap.state.FactorioGameState -import io.kvision.navigo.Match -import io.kvision.navigo.Navigo -import io.kvision.redux.RAction -import io.kvision.routing.routing -import kotlin.coroutines.CoroutineContext -import kotlin.js.RegExp -import kotlinx.coroutines.CoroutineName -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.launch - - -object SiteRouting : CoroutineScope { - - override val coroutineContext: CoroutineContext = - Dispatchers.Default + SupervisorJob(rootJob) + CoroutineName("SiteRouting") - - - fun init() { - routing - .on(SiteView.HOME) { homepageView() } - .on(SiteView.SERVER) { match -> - val serverId = match.data[0] as? String ?: error("invalid server id") - serverView(FactorioServerId(serverId)) - } - .resolve() - } - - fun homepageView() { - App.siteStateStore.dispatch(SiteAction.HomePage) - launch { - val serverIds = EventsServerClient.serverIds() - App.siteStateStore.dispatch(SiteAction.ServerIdsLoaded(serverIds)) - } - } - - fun serverView(serverId: FactorioServerId) { - App.siteStateStore.dispatch(SiteAction.ServerPage(serverId)) - } - -} - - -data class SiteState( - val view: SiteView = SiteView.HOME, - - val serverIds: List? = null, - - val factorioGameState: FactorioGameState? = null, -) : CoroutineScope { - - override val coroutineContext: CoroutineContext = - Dispatchers.Default + SupervisorJob(rootJob) + CoroutineName("SiteState") - - operator fun plus(action: SiteAction): SiteState = when (action) { - is SiteAction.HomePage -> copy(view = SiteView.HOME) - - is SiteAction.ServerPage -> copy( - view = SiteView.SERVER, - factorioGameState = FactorioGameState(action.serverId), - ) - - is SiteAction.ServerIdsLoaded -> copy(serverIds = action.serverIds) - - is SiteAction.FactorioUpdate -> copy( - factorioGameState = factorioGameState?.let { it + action } - ) - - is SiteAction.EventServerUpdate -> when (action.packet) { - is EventServerPacket.ChunkTileSaved -> { - if (factorioGameState?.map != null) { - launch { - factorioGameState.map.refreshUpdatedTilePng(action.packet.filename) - } - } - this - } - - is EventServerPacket.Kafkatorio -> { - this - } - } - } -} - - -sealed interface SiteAction : RAction { - object HomePage : SiteAction - data class ServerPage(val serverId: FactorioServerId) : SiteAction - - - data class ServerIdsLoaded(val serverIds: List) : SiteAction - - - /** Updates from `events-server` */ - sealed class FactorioUpdate : SiteAction { - data class Player(val tick: Tick, val data: PlayerUpdate) : FactorioUpdate() - } - - data class EventServerUpdate(val packet: EventServerPacket) : SiteAction -} - - -sealed interface SiteView { - - sealed interface StaticPath : SiteView { - val path: String - } - - sealed interface DynamicPath : SiteView { - val pathMatcher: RegExp - } - - - object HOME : StaticPath { - override val path: String = "/" - } - - object SERVER : DynamicPath { - override val pathMatcher: RegExp = RegExp("^servers/${FactorioServerId.validIdRegex}") - } -} - - -private fun Navigo.on(view: SiteView, handler: (Match) -> Unit): Navigo { - return when (view) { - is SiteView.StaticPath -> on(view.path, { match: Match -> handler(match) }) - is SiteView.DynamicPath -> on(view.pathMatcher, { match: Match -> handler(match) }) - } -} - - -//private fun Navigo.on( -// view: SiteView, -// before: BeforeHook? = null, -// after: AfterHook? = null, -// leave: LeaveHook? = null, -// already: AlreadyHook? = null, -// handler: (Match) -> Unit, -//): Navigo { -// -// val hooks: RouteHooks? = -// if (before != null || after != null || leave != null || already != null) { -// jso { -// if (before != null) this@jso.before = before -// if (after != null) this@jso.after = after -// if (leave != null) this@jso.leave = leave -// if (already != null) this@jso.already = already -// } -// } else { -// null -// } -// -// return when (view) { -// is SiteView.StaticPath -> when (hooks) { -// null -> on(view.pathMatcher, { match: Match -> handler(match) }) -// else -> on(view.pathMatcher, { match: Match -> handler(match) }, hooks) -// } -// -// is SiteView.DynamicPath -> when (hooks) { -// null -> on(view.pathMatcher, { match: Match -> handler(match) }) -// else -> on(view.pathMatcher, { match: Match -> handler(match) }, hooks) -// } -// } -//} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing/SiteRouter.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing/SiteRouter.kt new file mode 100644 index 0000000..a0108f4 --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing/SiteRouter.kt @@ -0,0 +1,87 @@ +package dev.adamko.kafkatorio.webmap.routing + +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.webmap.App +import dev.adamko.kafkatorio.webmap.state.SiteAction +import dev.adamko.kafkatorio.webmap.rootJob +import dev.adamko.kafkatorio.webmap.services.EventsServerClient +import io.kvision.navigo.Match +import io.kvision.navigo.Navigo +import io.kvision.routing.Routing +import io.kvision.routing.Strategy +import kotlin.coroutines.CoroutineContext +import kotlinx.browser.window +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.launch + + +object SiteRouter : CoroutineScope { + + override val coroutineContext: CoroutineContext = + Dispatchers.Default + SupervisorJob(rootJob) + CoroutineName("SiteRouting") + + + private val navigo: Routing = Routing( + root = "/", + useHash = false, + strategy = Strategy.ONE + ) + + + fun init() { + navigo + .on(SiteView.HOME) { + log("routing.on HOME") + homepageView() + } + .on(SiteView.SERVER) { match -> + println("routing.on SERVER ${JSON.stringify(match)}") + val serverId = match.data["serverId"] as? String ?: error("invalid server id") + println("routing.on SERVER serverId:$serverId") + serverView(FactorioServerId(serverId)) + } + .resolve() + + log("routing.lastResolved(): " + JSON.stringify(navigo.lastResolved())) + } + + + fun updatePageLinks() { + window.setTimeout( + handler = { + log("updating page links") + navigo.updatePageLinks() + }, + timeout = 0, + ) + } + + + fun homepageView() { + App.siteStateStore.dispatch(SiteAction.HomePage) + launch { + val serverIds = EventsServerClient.serverIds() + log("loaded server IDs $serverIds") + App.siteStateStore.dispatch(SiteAction.ServerIdsLoaded(serverIds)) + } + } + + + fun serverView(serverId: FactorioServerId) { + App.siteStateStore.dispatch(SiteAction.ServerPage(serverId)) + } + + + private fun log(message: String) = println("[SiteRouting] $message") +} + + +private fun Navigo.on(view: SiteView, handler: (Match) -> Unit): Navigo { + return when (view) { + is SiteView.StaticPath -> on(view.path, { match: Match -> handler(match) }) + is SiteView.DynamicPath -> on(view.path, { match: Match -> handler(match) }) + } +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing/SiteView.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing/SiteView.kt new file mode 100644 index 0000000..fb4020f --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/routing/SiteView.kt @@ -0,0 +1,22 @@ +package dev.adamko.kafkatorio.webmap.routing + + +sealed interface SiteView { + + sealed interface StaticPath : SiteView { + val path: String + } + + sealed interface DynamicPath : SiteView { + val path: String + } + + + object HOME : StaticPath { + override val path: String = "/" + } + + object SERVER : DynamicPath { + override val path: String = "/servers/:serverId/" + } +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/WebsocketService.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/WebsocketService.kt index 8553f08..64ea1cc 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/WebsocketService.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/services/WebsocketService.kt @@ -13,7 +13,7 @@ import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate import dev.adamko.kafkatorio.webmap.App -import dev.adamko.kafkatorio.webmap.SiteAction +import dev.adamko.kafkatorio.webmap.state.SiteAction import dev.adamko.kafkatorio.webmap.config.ApplicationProperties import dev.adamko.kafkatorio.webmap.config.jsonMapper import dev.adamko.kafkatorio.webmap.rootJob diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/SiteAction.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/SiteAction.kt new file mode 100644 index 0000000..d5dd841 --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/SiteAction.kt @@ -0,0 +1,24 @@ +package dev.adamko.kafkatorio.webmap.state + +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.common.Tick +import dev.adamko.kafkatorio.schema.packets.EventServerPacket +import dev.adamko.kafkatorio.schema.packets.PlayerUpdate +import io.kvision.redux.RAction + + +sealed interface SiteAction : RAction { + object HomePage : SiteAction + data class ServerPage(val serverId: FactorioServerId) : SiteAction + + + data class ServerIdsLoaded(val serverIds: List) : SiteAction + + + /** Updates from `events-server` */ + sealed class FactorioUpdate : SiteAction { + data class Player(val tick: Tick, val data: PlayerUpdate) : FactorioUpdate() + } + + data class EventServerUpdate(val packet: EventServerPacket) : SiteAction +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/SiteState.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/SiteState.kt new file mode 100644 index 0000000..ecb2894 --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/SiteState.kt @@ -0,0 +1,55 @@ +package dev.adamko.kafkatorio.webmap.state + +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.packets.EventServerPacket +import dev.adamko.kafkatorio.webmap.rootJob +import dev.adamko.kafkatorio.webmap.routing.SiteView +import kotlin.coroutines.CoroutineContext +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.launch + + +data class SiteState( + val view: SiteView = SiteView.HOME, + + val serverIds: List? = null, + + val factorioGameState: FactorioGameState? = null, +) : CoroutineScope { + + override val coroutineContext: CoroutineContext = + Dispatchers.Default + SupervisorJob(rootJob) + CoroutineName("SiteState") + + operator fun plus(action: SiteAction): SiteState = when (action) { + is SiteAction.HomePage -> copy(view = SiteView.HOME) + + is SiteAction.ServerPage -> copy( + view = SiteView.SERVER, + factorioGameState = FactorioGameState(action.serverId), + ) + + is SiteAction.ServerIdsLoaded -> copy(serverIds = action.serverIds) + + is SiteAction.FactorioUpdate -> copy( + factorioGameState = factorioGameState?.let { it + action } + ) + + is SiteAction.EventServerUpdate -> when (action.packet) { + is EventServerPacket.ChunkTileSaved -> { + if (factorioGameState?.map != null) { + launch { + factorioGameState.map.refreshUpdatedTilePng(action.packet.filename) + } + } + this + } + + is EventServerPacket.Kafkatorio -> { + this + } + } + } +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt index f627ffb..b46b3b5 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt @@ -3,7 +3,6 @@ package dev.adamko.kafkatorio.webmap.state import dev.adamko.kafkatorio.schema.common.PlayerIndex import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.packets.PlayerUpdate -import dev.adamko.kafkatorio.webmap.SiteAction import io.kvision.maps.Maps import io.kvision.maps.externals.leaflet.layer.vector.CircleMarker import kotlinx.js.jso diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt index 69d0f6b..206d5b3 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt @@ -3,7 +3,6 @@ package dev.adamko.kafkatorio.webmap.state import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.PlayerIndex import dev.adamko.kafkatorio.webmap.FactorioMap -import dev.adamko.kafkatorio.webmap.SiteAction import io.kvision.maps.externals.leaflet.layer.LayerGroup diff --git a/modules/web-map/src/main/web/index.html b/modules/web-map/src/main/web/index.html index 8f019b4..dc31aa7 100644 --- a/modules/web-map/src/main/web/index.html +++ b/modules/web-map/src/main/web/index.html @@ -4,12 +4,11 @@ Kafkatorio Web Map - - +
diff --git a/modules/web-map/webpack.config.d/webpack.js b/modules/web-map/webpack.config.d/webpack.js index 0491c5c..e258913 100644 --- a/modules/web-map/webpack.config.d/webpack.js +++ b/modules/web-map/webpack.config.d/webpack.js @@ -15,41 +15,5 @@ config.performance = { }, }; - -// // dev server -// config.devServer = { -// open: false, -// // devMiddleware: { -// // index: false, // specify to enable root proxying -// // }, -// port: 3000, -// proxy: { -// // context: () => true, -// // target: "http://localhost:12080", -// // secure: false, -// // ws: true, -// // changeOrigin: true, -// -// // "/tiles": { -// // target: "http://localhost:12080", -// // // "pathRewrite": { "^/tiles": "" }, -// // // "logger": "console", -// // // "logLevel": "debug", -// // secure: false, -// // changeOrigin: true, -// // }, -// // "/ws": { -// // target: "http://localhost:12080", -// // // pathRewrite: { "^/ws": "" }, -// // // "logLevel": "debug", -// // // "logger": "console", -// // secure: false, -// // ws: true, -// // changeOrigin: true, -// // }, -// }, -// "static": [ -// // "../../processedResources/js/main", -// "D:\\Users\\Adam\\Projects\\games\\kafkatorio\\modules\\web-map\\build\\processedResources\\frontend\\main", -// ], -// }; +// required for single-page app +config.devServer.historyApiFallback = true From 47c47690a74cfa7bc473a8b511bf0ebbef48d63d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 9 Sep 2022 17:33:48 +0200 Subject: [PATCH 509/629] refactor so files match contents --- .../dev/adamko/kafkatorio/webmap/App.kt | 19 -------- .../webmap/{map.kt => FactorioMap.kt} | 0 .../dev/adamko/kafkatorio/webmap/main.kt | 31 ++++++++++++ .../webmap/state/FactorioGameState.kt | 47 +++++++++++++++++++ .../state/{playerState.kt => PlayerState.kt} | 27 ----------- .../adamko/kafkatorio/webmap/state/state.kt | 32 ------------- 6 files changed, 78 insertions(+), 78 deletions(-) rename modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/{map.kt => FactorioMap.kt} (100%) create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/main.kt create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/FactorioGameState.kt rename modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/{playerState.kt => PlayerState.kt} (71%) delete mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index fdb7f84..532527b 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -38,8 +38,6 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -val rootJob = Job() - object App : Application() { @@ -111,20 +109,3 @@ object App : Application() { } } - - -fun main() { - startApplication( - { - Link.useDataNavigoForLinks = true - App - }, - module.hot, - BootstrapModule, -// BootstrapCssModule, - BootstrapIconsModule, - FontAwesomeModule, - ChartModule, - CoreModule, - ) -} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/FactorioMap.kt similarity index 100% rename from modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt rename to modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/FactorioMap.kt diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/main.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/main.kt new file mode 100644 index 0000000..05fbac7 --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/main.kt @@ -0,0 +1,31 @@ +package dev.adamko.kafkatorio.webmap + +import io.kvision.BootstrapIconsModule +import io.kvision.BootstrapModule +import io.kvision.ChartModule +import io.kvision.CoreModule +import io.kvision.FontAwesomeModule +import io.kvision.html.Link +import io.kvision.module +import io.kvision.startApplication +import kotlinx.coroutines.Job + + +val rootJob = Job() + + +fun main() { + startApplication( + { + Link.useDataNavigoForLinks = true + App + }, + module.hot, + BootstrapModule, +// BootstrapCssModule, + BootstrapIconsModule, + FontAwesomeModule, + ChartModule, + CoreModule, + ) +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/FactorioGameState.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/FactorioGameState.kt new file mode 100644 index 0000000..f4a0946 --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/FactorioGameState.kt @@ -0,0 +1,47 @@ +package dev.adamko.kafkatorio.webmap.state + +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.common.PlayerIndex +import dev.adamko.kafkatorio.webmap.FactorioMap +import io.kvision.maps.externals.leaflet.layer.LayerGroup + + +data class FactorioGameState( + val serverId: FactorioServerId, + val map: FactorioMap = FactorioMap(serverId), + val players: Map = emptyMap(), +) { + + val playerIconsLayer: LayerGroup + get() = map.playerIconsLayer + + operator fun plus(action: SiteAction.FactorioUpdate): FactorioGameState = + when (action) { + is SiteAction.FactorioUpdate.Player -> handlePlayerUpdate(action) + } +} + + +private fun FactorioGameState.handlePlayerUpdate( + update: SiteAction.FactorioUpdate.Player, +): FactorioGameState { + + val previous = players[update.data.key.index] + ?: PlayerState(update.data.key.index, update.tick) + + val updated = previous.update(update.tick, update.data) + + if (previous.mapMarker != updated.mapMarker) { + if (previous.mapMarker != null) { + println("removing player icon ${previous.index}") + playerIconsLayer.removeLayer(previous.mapMarker) + } + if (updated.mapMarker != null) { + println("adding player icon ${updated.index}") + playerIconsLayer.addLayer(updated.mapMarker) + } + } + + val updatedPlayersState = players + (previous.index to updated) + return copy(players = updatedPlayersState) +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/PlayerState.kt similarity index 71% rename from modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt rename to modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/PlayerState.kt index b46b3b5..6c7c399 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/PlayerState.kt @@ -7,33 +7,6 @@ import io.kvision.maps.Maps import io.kvision.maps.externals.leaflet.layer.vector.CircleMarker import kotlinx.js.jso - -fun handlePlayerUpdate( - gameState: FactorioGameState, - update: SiteAction.FactorioUpdate.Player, -): FactorioGameState { - - val previous = gameState.players[update.data.key.index] - ?: PlayerState(update.data.key.index, update.tick) - - val updated = previous.update(update.tick, update.data) - - if (previous.mapMarker != updated.mapMarker) { - if (previous.mapMarker != null) { - println("removing player icon ${previous.index}") - gameState.playerIconsLayer.removeLayer(previous.mapMarker) - } - if (updated.mapMarker != null) { - println("adding player icon ${updated.index}") - gameState.playerIconsLayer.addLayer(updated.mapMarker) - } - } - - val updatedPlayersState = gameState.players + (previous.index to updated) - return gameState.copy(players = updatedPlayersState) -} - - data class PlayerState( val index: PlayerIndex, val lastTick: Tick, diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt deleted file mode 100644 index 206d5b3..0000000 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt +++ /dev/null @@ -1,32 +0,0 @@ -package dev.adamko.kafkatorio.webmap.state - -import dev.adamko.kafkatorio.schema.common.FactorioServerId -import dev.adamko.kafkatorio.schema.common.PlayerIndex -import dev.adamko.kafkatorio.webmap.FactorioMap -import io.kvision.maps.externals.leaflet.layer.LayerGroup - - -//fun createFactorioReduxStore(): ReduxStore = -// createReduxStore( -// ::factorioGameReducer, -// FactorioGameState( -// map = FactorioMap(), -// players = emptyMap(), -// ) -// ) - - -data class FactorioGameState( - val serverId: FactorioServerId, - val map: FactorioMap = FactorioMap(serverId), - val players: Map = emptyMap(), -) { - - val playerIconsLayer: LayerGroup - get() = map.playerIconsLayer - - operator fun plus(action: SiteAction.FactorioUpdate): FactorioGameState = - when (action) { - is SiteAction.FactorioUpdate.Player -> handlePlayerUpdate(this, action) - } -} From 2546877c048ab032b067929dc6a343196b77a265 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 10 Sep 2022 10:05:44 +0200 Subject: [PATCH 510/629] disable Kotest multiplatform --- .../dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts index 46939bc..f9f0d11 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts @@ -10,7 +10,7 @@ plugins { id("dev.adamko.kafkatorio.base") // id("dev.adamko.kafkatorio.lang.node") kotlin("multiplatform") - id("io.kotest.multiplatform") +// id("io.kotest.multiplatform") // disabled because of https://github.com/kotest/kotest/issues/3141 } From 80e8c95bc9cbcab1e9d59eb653da9f486a158833 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 10 Sep 2022 10:07:46 +0200 Subject: [PATCH 511/629] fix webpack dev server, redownload bootstrap.min.css --- .../src/main/resources/css/bootstrap.min.css | 12295 +--------------- modules/web-map/webpack.config.d/webpack.js | 5 +- 2 files changed, 4 insertions(+), 12296 deletions(-) diff --git a/modules/web-map/src/main/resources/css/bootstrap.min.css b/modules/web-map/src/main/resources/css/bootstrap.min.css index 3c9c553..243b81e 100644 --- a/modules/web-map/src/main/resources/css/bootstrap.min.css +++ b/modules/web-map/src/main/resources/css/bootstrap.min.css @@ -1,5 +1,4 @@ -@charset "UTF-8"; -/*! +@charset "UTF-8";/*! * Bootswatch v5.2.0 (https://bootswatch.com) * Theme: darkly * Copyright 2012-2022 Thomas Park @@ -10,12294 +9,4 @@ * Copyright 2011-2022 The Bootstrap Authors * Copyright 2011-2022 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */ -@import url(https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap); - -:root { - --bs-blue: #375a7f; - --bs-indigo: #6610f2; - --bs-purple: #6f42c1; - --bs-pink: #e83e8c; - --bs-red: #e74c3c; - --bs-orange: #fd7e14; - --bs-yellow: #f39c12; - --bs-green: #00bc8c; - --bs-teal: #20c997; - --bs-cyan: #3498db; - --bs-black: #000; - --bs-white: #fff; - --bs-gray: #888; - --bs-gray-dark: #303030; - --bs-gray-100: #f8f9fa; - --bs-gray-200: #ebebeb; - --bs-gray-300: #dee2e6; - --bs-gray-400: #ced4da; - --bs-gray-500: #adb5bd; - --bs-gray-600: #888; - --bs-gray-700: #444; - --bs-gray-800: #303030; - --bs-gray-900: #222; - --bs-primary: #375a7f; - --bs-secondary: #444; - --bs-success: #00bc8c; - --bs-info: #3498db; - --bs-warning: #f39c12; - --bs-danger: #e74c3c; - --bs-light: #adb5bd; - --bs-dark: #303030; - --bs-primary-rgb: 55, 90, 127; - --bs-secondary-rgb: 68, 68, 68; - --bs-success-rgb: 0, 188, 140; - --bs-info-rgb: 52, 152, 219; - --bs-warning-rgb: 243, 156, 18; - --bs-danger-rgb: 231, 76, 60; - --bs-light-rgb: 173, 181, 189; - --bs-dark-rgb: 48, 48, 48; - --bs-white-rgb: 255, 255, 255; - --bs-black-rgb: 0, 0, 0; - --bs-body-color-rgb: 255, 255, 255; - --bs-body-bg-rgb: 34, 34, 34; - --bs-font-sans-serif: Lato, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); - --bs-body-font-family: var(--bs-font-sans-serif); - --bs-body-font-size: 1rem; - --bs-body-font-weight: 400; - --bs-body-line-height: 1.5; - --bs-body-color: #fff; - --bs-body-bg: #222; - --bs-border-width: 1px; - --bs-border-style: solid; - --bs-border-color: #dee2e6; - --bs-border-color-translucent: rgba(0, 0, 0, 0.175); - --bs-border-radius: 0.375rem; - --bs-border-radius-sm: 0.25rem; - --bs-border-radius-lg: 0.5rem; - --bs-border-radius-xl: 1rem; - --bs-border-radius-2xl: 2rem; - --bs-border-radius-pill: 50rem; - --bs-link-color: #00bc8c; - --bs-link-hover-color: #009670; - --bs-code-color: #e83e8c; - --bs-highlight-bg: #fdebd0 -} - -*, ::after, ::before { - box-sizing: border-box -} - -@media (prefers-reduced-motion: no-preference) { - :root { - scroll-behavior: smooth - } -} - -body { - margin: 0; - font-family: var(--bs-body-font-family); - font-size: var(--bs-body-font-size); - font-weight: var(--bs-body-font-weight); - line-height: var(--bs-body-line-height); - color: var(--bs-body-color); - text-align: var(--bs-body-text-align); - background-color: var(--bs-body-bg); - -webkit-text-size-adjust: 100%; - -webkit-tap-highlight-color: transparent -} - -hr { - margin: 1rem 0; - color: inherit; - border: 0; - border-top: 1px solid; - opacity: .25 -} - -.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { - margin-top: 0; - margin-bottom: .5rem; - font-weight: 500; - line-height: 1.2 -} - -.h1, h1 { - font-size: calc(1.425rem + 2.1vw) -} - -@media (min-width: 1200px) { - .h1, h1 { - font-size: 3rem - } -} - -.h2, h2 { - font-size: calc(1.375rem + 1.5vw) -} - -@media (min-width: 1200px) { - .h2, h2 { - font-size: 2.5rem - } -} - -.h3, h3 { - font-size: calc(1.325rem + .9vw) -} - -@media (min-width: 1200px) { - .h3, h3 { - font-size: 2rem - } -} - -.h4, h4 { - font-size: calc(1.275rem + .3vw) -} - -@media (min-width: 1200px) { - .h4, h4 { - font-size: 1.5rem - } -} - -.h5, h5 { - font-size: 1.25rem -} - -.h6, h6 { - font-size: 1rem -} - -p { - margin-top: 0; - margin-bottom: 1rem -} - -abbr[title] { - -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; - cursor: help; - -webkit-text-decoration-skip-ink: none; - text-decoration-skip-ink: none -} - -address { - margin-bottom: 1rem; - font-style: normal; - line-height: inherit -} - -ol, ul { - padding-left: 2rem -} - -dl, ol, ul { - margin-top: 0; - margin-bottom: 1rem -} - -ol ol, ol ul, ul ol, ul ul { - margin-bottom: 0 -} - -dt { - font-weight: 700 -} - -dd { - margin-bottom: .5rem; - margin-left: 0 -} - -blockquote { - margin: 0 0 1rem -} - -b, strong { - font-weight: bolder -} - -.small, small { - font-size: .875em -} - -.mark, mark { - padding: .1875em; - background-color: var(--bs-highlight-bg) -} - -sub, sup { - position: relative; - font-size: .75em; - line-height: 0; - vertical-align: baseline -} - -sub { - bottom: -.25em -} - -sup { - top: -.5em -} - -a { - color: var(--bs-link-color); - text-decoration: underline -} - -a:hover { - color: var(--bs-link-hover-color) -} - -a:not([href]):not([class]), a:not([href]):not([class]):hover { - color: inherit; - text-decoration: none -} - -code, kbd, pre, samp { - font-family: var(--bs-font-monospace); - font-size: 1em -} - -pre { - display: block; - margin-top: 0; - margin-bottom: 1rem; - overflow: auto; - font-size: .875em; - color: inherit -} - -pre code { - font-size: inherit; - color: inherit; - word-break: normal -} - -code { - font-size: .875em; - color: var(--bs-code-color); - word-wrap: break-word -} - -a > code { - color: inherit -} - -kbd { - padding: .1875rem .375rem; - font-size: .875em; - color: var(--bs-body-bg); - background-color: var(--bs-body-color); - border-radius: .25rem -} - -kbd kbd { - padding: 0; - font-size: 1em -} - -figure { - margin: 0 0 1rem -} - -img, svg { - vertical-align: middle -} - -table { - caption-side: bottom; - border-collapse: collapse -} - -caption { - padding-top: .5rem; - padding-bottom: .5rem; - color: #888; - text-align: left -} - -th { - text-align: inherit; - text-align: -webkit-match-parent -} - -tbody, td, tfoot, th, thead, tr { - border-color: inherit; - border-style: solid; - border-width: 0 -} - -label { - display: inline-block -} - -button { - border-radius: 0 -} - -button:focus:not(:focus-visible) { - outline: 0 -} - -button, input, optgroup, select, textarea { - margin: 0; - font-family: inherit; - font-size: inherit; - line-height: inherit -} - -button, select { - text-transform: none -} - -[role=button] { - cursor: pointer -} - -select { - word-wrap: normal -} - -select:disabled { - opacity: 1 -} - -[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator { - display: none !important -} - -[type=button], [type=reset], [type=submit], button { - -webkit-appearance: button -} - -[type=button]:not(:disabled), [type=reset]:not(:disabled), [type=submit]:not(:disabled), button:not(:disabled) { - cursor: pointer -} - -::-moz-focus-inner { - padding: 0; - border-style: none -} - -textarea { - resize: vertical -} - -fieldset { - min-width: 0; - padding: 0; - margin: 0; - border: 0 -} - -legend { - float: left; - width: 100%; - padding: 0; - margin-bottom: .5rem; - font-size: calc(1.275rem + .3vw); - line-height: inherit -} - -@media (min-width: 1200px) { - legend { - font-size: 1.5rem - } -} - -legend + * { - clear: left -} - -::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-fields-wrapper, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-text, ::-webkit-datetime-edit-year-field { - padding: 0 -} - -::-webkit-inner-spin-button { - height: auto -} - -[type=search] { - outline-offset: -2px; - -webkit-appearance: textfield -} - -::-webkit-search-decoration { - -webkit-appearance: none -} - -::-webkit-color-swatch-wrapper { - padding: 0 -} - -::-webkit-file-upload-button { - font: inherit; - -webkit-appearance: button -} - -::file-selector-button { - font: inherit; - -webkit-appearance: button -} - -output { - display: inline-block -} - -iframe { - border: 0 -} - -summary { - display: list-item; - cursor: pointer -} - -progress { - vertical-align: baseline -} - -[hidden] { - display: none !important -} - -.lead { - font-size: 1.25rem; - font-weight: 300 -} - -.display-1 { - font-size: calc(1.625rem + 4.5vw); - font-weight: 300; - line-height: 1.2 -} - -@media (min-width: 1200px) { - .display-1 { - font-size: 5rem - } -} - -.display-2 { - font-size: calc(1.575rem + 3.9vw); - font-weight: 300; - line-height: 1.2 -} - -@media (min-width: 1200px) { - .display-2 { - font-size: 4.5rem - } -} - -.display-3 { - font-size: calc(1.525rem + 3.3vw); - font-weight: 300; - line-height: 1.2 -} - -@media (min-width: 1200px) { - .display-3 { - font-size: 4rem - } -} - -.display-4 { - font-size: calc(1.475rem + 2.7vw); - font-weight: 300; - line-height: 1.2 -} - -@media (min-width: 1200px) { - .display-4 { - font-size: 3.5rem - } -} - -.display-5 { - font-size: calc(1.425rem + 2.1vw); - font-weight: 300; - line-height: 1.2 -} - -@media (min-width: 1200px) { - .display-5 { - font-size: 3rem - } -} - -.display-6 { - font-size: calc(1.375rem + 1.5vw); - font-weight: 300; - line-height: 1.2 -} - -@media (min-width: 1200px) { - .display-6 { - font-size: 2.5rem - } -} - -.list-unstyled { - padding-left: 0; - list-style: none -} - -.list-inline { - padding-left: 0; - list-style: none -} - -.list-inline-item { - display: inline-block -} - -.list-inline-item:not(:last-child) { - margin-right: .5rem -} - -.initialism { - font-size: .875em; - text-transform: uppercase -} - -.blockquote { - margin-bottom: 1rem; - font-size: 1.25rem -} - -.blockquote > :last-child { - margin-bottom: 0 -} - -.blockquote-footer { - margin-top: -1rem; - margin-bottom: 1rem; - font-size: .875em; - color: #888 -} - -.blockquote-footer::before { - content: "��" -} - -.img-fluid { - max-width: 100%; - height: auto -} - -.img-thumbnail { - padding: .25rem; - background-color: #222; - border: 1px solid var(--bs-border-color); - border-radius: .375rem; - max-width: 100%; - height: auto -} - -.figure { - display: inline-block -} - -.figure-img { - margin-bottom: .5rem; - line-height: 1 -} - -.figure-caption { - font-size: .875em; - color: #888 -} - -.container, .container-fluid, .container-lg, .container-md, .container-sm, .container-xl, .container-xxl { - --bs-gutter-x: 1.5rem; - --bs-gutter-y: 0; - width: 100%; - padding-right: calc(var(--bs-gutter-x) * .5); - padding-left: calc(var(--bs-gutter-x) * .5); - margin-right: auto; - margin-left: auto -} - -@media (min-width: 576px) { - .container, .container-sm { - max-width: 540px - } -} - -@media (min-width: 768px) { - .container, .container-md, .container-sm { - max-width: 720px - } -} - -@media (min-width: 992px) { - .container, .container-lg, .container-md, .container-sm { - max-width: 960px - } -} - -@media (min-width: 1200px) { - .container, .container-lg, .container-md, .container-sm, .container-xl { - max-width: 1140px - } -} - -@media (min-width: 1400px) { - .container, .container-lg, .container-md, .container-sm, .container-xl, .container-xxl { - max-width: 1320px - } -} - -.row { - --bs-gutter-x: 1.5rem; - --bs-gutter-y: 0; - display: flex; - flex-wrap: wrap; - margin-top: calc(-1 * var(--bs-gutter-y)); - margin-right: calc(-.5 * var(--bs-gutter-x)); - margin-left: calc(-.5 * var(--bs-gutter-x)) -} - -.row > * { - flex-shrink: 0; - width: 100%; - max-width: 100%; - padding-right: calc(var(--bs-gutter-x) * .5); - padding-left: calc(var(--bs-gutter-x) * .5); - margin-top: var(--bs-gutter-y) -} - -.col { - flex: 1 0 0% -} - -.row-cols-auto > * { - flex: 0 0 auto; - width: auto -} - -.row-cols-1 > * { - flex: 0 0 auto; - width: 100% -} - -.row-cols-2 > * { - flex: 0 0 auto; - width: 50% -} - -.row-cols-3 > * { - flex: 0 0 auto; - width: 33.3333333333% -} - -.row-cols-4 > * { - flex: 0 0 auto; - width: 25% -} - -.row-cols-5 > * { - flex: 0 0 auto; - width: 20% -} - -.row-cols-6 > * { - flex: 0 0 auto; - width: 16.6666666667% -} - -.col-auto { - flex: 0 0 auto; - width: auto -} - -.col-1 { - flex: 0 0 auto; - width: 8.33333333% -} - -.col-2 { - flex: 0 0 auto; - width: 16.66666667% -} - -.col-3 { - flex: 0 0 auto; - width: 25% -} - -.col-4 { - flex: 0 0 auto; - width: 33.33333333% -} - -.col-5 { - flex: 0 0 auto; - width: 41.66666667% -} - -.col-6 { - flex: 0 0 auto; - width: 50% -} - -.col-7 { - flex: 0 0 auto; - width: 58.33333333% -} - -.col-8 { - flex: 0 0 auto; - width: 66.66666667% -} - -.col-9 { - flex: 0 0 auto; - width: 75% -} - -.col-10 { - flex: 0 0 auto; - width: 83.33333333% -} - -.col-11 { - flex: 0 0 auto; - width: 91.66666667% -} - -.col-12 { - flex: 0 0 auto; - width: 100% -} - -.offset-1 { - margin-left: 8.33333333% -} - -.offset-2 { - margin-left: 16.66666667% -} - -.offset-3 { - margin-left: 25% -} - -.offset-4 { - margin-left: 33.33333333% -} - -.offset-5 { - margin-left: 41.66666667% -} - -.offset-6 { - margin-left: 50% -} - -.offset-7 { - margin-left: 58.33333333% -} - -.offset-8 { - margin-left: 66.66666667% -} - -.offset-9 { - margin-left: 75% -} - -.offset-10 { - margin-left: 83.33333333% -} - -.offset-11 { - margin-left: 91.66666667% -} - -.g-0, .gx-0 { - --bs-gutter-x: 0 -} - -.g-0, .gy-0 { - --bs-gutter-y: 0 -} - -.g-1, .gx-1 { - --bs-gutter-x: 0.25rem -} - -.g-1, .gy-1 { - --bs-gutter-y: 0.25rem -} - -.g-2, .gx-2 { - --bs-gutter-x: 0.5rem -} - -.g-2, .gy-2 { - --bs-gutter-y: 0.5rem -} - -.g-3, .gx-3 { - --bs-gutter-x: 1rem -} - -.g-3, .gy-3 { - --bs-gutter-y: 1rem -} - -.g-4, .gx-4 { - --bs-gutter-x: 1.5rem -} - -.g-4, .gy-4 { - --bs-gutter-y: 1.5rem -} - -.g-5, .gx-5 { - --bs-gutter-x: 3rem -} - -.g-5, .gy-5 { - --bs-gutter-y: 3rem -} - -@media (min-width: 576px) { - .col-sm { - flex: 1 0 0% - } - - .row-cols-sm-auto > * { - flex: 0 0 auto; - width: auto - } - - .row-cols-sm-1 > * { - flex: 0 0 auto; - width: 100% - } - - .row-cols-sm-2 > * { - flex: 0 0 auto; - width: 50% - } - - .row-cols-sm-3 > * { - flex: 0 0 auto; - width: 33.3333333333% - } - - .row-cols-sm-4 > * { - flex: 0 0 auto; - width: 25% - } - - .row-cols-sm-5 > * { - flex: 0 0 auto; - width: 20% - } - - .row-cols-sm-6 > * { - flex: 0 0 auto; - width: 16.6666666667% - } - - .col-sm-auto { - flex: 0 0 auto; - width: auto - } - - .col-sm-1 { - flex: 0 0 auto; - width: 8.33333333% - } - - .col-sm-2 { - flex: 0 0 auto; - width: 16.66666667% - } - - .col-sm-3 { - flex: 0 0 auto; - width: 25% - } - - .col-sm-4 { - flex: 0 0 auto; - width: 33.33333333% - } - - .col-sm-5 { - flex: 0 0 auto; - width: 41.66666667% - } - - .col-sm-6 { - flex: 0 0 auto; - width: 50% - } - - .col-sm-7 { - flex: 0 0 auto; - width: 58.33333333% - } - - .col-sm-8 { - flex: 0 0 auto; - width: 66.66666667% - } - - .col-sm-9 { - flex: 0 0 auto; - width: 75% - } - - .col-sm-10 { - flex: 0 0 auto; - width: 83.33333333% - } - - .col-sm-11 { - flex: 0 0 auto; - width: 91.66666667% - } - - .col-sm-12 { - flex: 0 0 auto; - width: 100% - } - - .offset-sm-0 { - margin-left: 0 - } - - .offset-sm-1 { - margin-left: 8.33333333% - } - - .offset-sm-2 { - margin-left: 16.66666667% - } - - .offset-sm-3 { - margin-left: 25% - } - - .offset-sm-4 { - margin-left: 33.33333333% - } - - .offset-sm-5 { - margin-left: 41.66666667% - } - - .offset-sm-6 { - margin-left: 50% - } - - .offset-sm-7 { - margin-left: 58.33333333% - } - - .offset-sm-8 { - margin-left: 66.66666667% - } - - .offset-sm-9 { - margin-left: 75% - } - - .offset-sm-10 { - margin-left: 83.33333333% - } - - .offset-sm-11 { - margin-left: 91.66666667% - } - - .g-sm-0, .gx-sm-0 { - --bs-gutter-x: 0 - } - - .g-sm-0, .gy-sm-0 { - --bs-gutter-y: 0 - } - - .g-sm-1, .gx-sm-1 { - --bs-gutter-x: 0.25rem - } - - .g-sm-1, .gy-sm-1 { - --bs-gutter-y: 0.25rem - } - - .g-sm-2, .gx-sm-2 { - --bs-gutter-x: 0.5rem - } - - .g-sm-2, .gy-sm-2 { - --bs-gutter-y: 0.5rem - } - - .g-sm-3, .gx-sm-3 { - --bs-gutter-x: 1rem - } - - .g-sm-3, .gy-sm-3 { - --bs-gutter-y: 1rem - } - - .g-sm-4, .gx-sm-4 { - --bs-gutter-x: 1.5rem - } - - .g-sm-4, .gy-sm-4 { - --bs-gutter-y: 1.5rem - } - - .g-sm-5, .gx-sm-5 { - --bs-gutter-x: 3rem - } - - .g-sm-5, .gy-sm-5 { - --bs-gutter-y: 3rem - } -} - -@media (min-width: 768px) { - .col-md { - flex: 1 0 0% - } - - .row-cols-md-auto > * { - flex: 0 0 auto; - width: auto - } - - .row-cols-md-1 > * { - flex: 0 0 auto; - width: 100% - } - - .row-cols-md-2 > * { - flex: 0 0 auto; - width: 50% - } - - .row-cols-md-3 > * { - flex: 0 0 auto; - width: 33.3333333333% - } - - .row-cols-md-4 > * { - flex: 0 0 auto; - width: 25% - } - - .row-cols-md-5 > * { - flex: 0 0 auto; - width: 20% - } - - .row-cols-md-6 > * { - flex: 0 0 auto; - width: 16.6666666667% - } - - .col-md-auto { - flex: 0 0 auto; - width: auto - } - - .col-md-1 { - flex: 0 0 auto; - width: 8.33333333% - } - - .col-md-2 { - flex: 0 0 auto; - width: 16.66666667% - } - - .col-md-3 { - flex: 0 0 auto; - width: 25% - } - - .col-md-4 { - flex: 0 0 auto; - width: 33.33333333% - } - - .col-md-5 { - flex: 0 0 auto; - width: 41.66666667% - } - - .col-md-6 { - flex: 0 0 auto; - width: 50% - } - - .col-md-7 { - flex: 0 0 auto; - width: 58.33333333% - } - - .col-md-8 { - flex: 0 0 auto; - width: 66.66666667% - } - - .col-md-9 { - flex: 0 0 auto; - width: 75% - } - - .col-md-10 { - flex: 0 0 auto; - width: 83.33333333% - } - - .col-md-11 { - flex: 0 0 auto; - width: 91.66666667% - } - - .col-md-12 { - flex: 0 0 auto; - width: 100% - } - - .offset-md-0 { - margin-left: 0 - } - - .offset-md-1 { - margin-left: 8.33333333% - } - - .offset-md-2 { - margin-left: 16.66666667% - } - - .offset-md-3 { - margin-left: 25% - } - - .offset-md-4 { - margin-left: 33.33333333% - } - - .offset-md-5 { - margin-left: 41.66666667% - } - - .offset-md-6 { - margin-left: 50% - } - - .offset-md-7 { - margin-left: 58.33333333% - } - - .offset-md-8 { - margin-left: 66.66666667% - } - - .offset-md-9 { - margin-left: 75% - } - - .offset-md-10 { - margin-left: 83.33333333% - } - - .offset-md-11 { - margin-left: 91.66666667% - } - - .g-md-0, .gx-md-0 { - --bs-gutter-x: 0 - } - - .g-md-0, .gy-md-0 { - --bs-gutter-y: 0 - } - - .g-md-1, .gx-md-1 { - --bs-gutter-x: 0.25rem - } - - .g-md-1, .gy-md-1 { - --bs-gutter-y: 0.25rem - } - - .g-md-2, .gx-md-2 { - --bs-gutter-x: 0.5rem - } - - .g-md-2, .gy-md-2 { - --bs-gutter-y: 0.5rem - } - - .g-md-3, .gx-md-3 { - --bs-gutter-x: 1rem - } - - .g-md-3, .gy-md-3 { - --bs-gutter-y: 1rem - } - - .g-md-4, .gx-md-4 { - --bs-gutter-x: 1.5rem - } - - .g-md-4, .gy-md-4 { - --bs-gutter-y: 1.5rem - } - - .g-md-5, .gx-md-5 { - --bs-gutter-x: 3rem - } - - .g-md-5, .gy-md-5 { - --bs-gutter-y: 3rem - } -} - -@media (min-width: 992px) { - .col-lg { - flex: 1 0 0% - } - - .row-cols-lg-auto > * { - flex: 0 0 auto; - width: auto - } - - .row-cols-lg-1 > * { - flex: 0 0 auto; - width: 100% - } - - .row-cols-lg-2 > * { - flex: 0 0 auto; - width: 50% - } - - .row-cols-lg-3 > * { - flex: 0 0 auto; - width: 33.3333333333% - } - - .row-cols-lg-4 > * { - flex: 0 0 auto; - width: 25% - } - - .row-cols-lg-5 > * { - flex: 0 0 auto; - width: 20% - } - - .row-cols-lg-6 > * { - flex: 0 0 auto; - width: 16.6666666667% - } - - .col-lg-auto { - flex: 0 0 auto; - width: auto - } - - .col-lg-1 { - flex: 0 0 auto; - width: 8.33333333% - } - - .col-lg-2 { - flex: 0 0 auto; - width: 16.66666667% - } - - .col-lg-3 { - flex: 0 0 auto; - width: 25% - } - - .col-lg-4 { - flex: 0 0 auto; - width: 33.33333333% - } - - .col-lg-5 { - flex: 0 0 auto; - width: 41.66666667% - } - - .col-lg-6 { - flex: 0 0 auto; - width: 50% - } - - .col-lg-7 { - flex: 0 0 auto; - width: 58.33333333% - } - - .col-lg-8 { - flex: 0 0 auto; - width: 66.66666667% - } - - .col-lg-9 { - flex: 0 0 auto; - width: 75% - } - - .col-lg-10 { - flex: 0 0 auto; - width: 83.33333333% - } - - .col-lg-11 { - flex: 0 0 auto; - width: 91.66666667% - } - - .col-lg-12 { - flex: 0 0 auto; - width: 100% - } - - .offset-lg-0 { - margin-left: 0 - } - - .offset-lg-1 { - margin-left: 8.33333333% - } - - .offset-lg-2 { - margin-left: 16.66666667% - } - - .offset-lg-3 { - margin-left: 25% - } - - .offset-lg-4 { - margin-left: 33.33333333% - } - - .offset-lg-5 { - margin-left: 41.66666667% - } - - .offset-lg-6 { - margin-left: 50% - } - - .offset-lg-7 { - margin-left: 58.33333333% - } - - .offset-lg-8 { - margin-left: 66.66666667% - } - - .offset-lg-9 { - margin-left: 75% - } - - .offset-lg-10 { - margin-left: 83.33333333% - } - - .offset-lg-11 { - margin-left: 91.66666667% - } - - .g-lg-0, .gx-lg-0 { - --bs-gutter-x: 0 - } - - .g-lg-0, .gy-lg-0 { - --bs-gutter-y: 0 - } - - .g-lg-1, .gx-lg-1 { - --bs-gutter-x: 0.25rem - } - - .g-lg-1, .gy-lg-1 { - --bs-gutter-y: 0.25rem - } - - .g-lg-2, .gx-lg-2 { - --bs-gutter-x: 0.5rem - } - - .g-lg-2, .gy-lg-2 { - --bs-gutter-y: 0.5rem - } - - .g-lg-3, .gx-lg-3 { - --bs-gutter-x: 1rem - } - - .g-lg-3, .gy-lg-3 { - --bs-gutter-y: 1rem - } - - .g-lg-4, .gx-lg-4 { - --bs-gutter-x: 1.5rem - } - - .g-lg-4, .gy-lg-4 { - --bs-gutter-y: 1.5rem - } - - .g-lg-5, .gx-lg-5 { - --bs-gutter-x: 3rem - } - - .g-lg-5, .gy-lg-5 { - --bs-gutter-y: 3rem - } -} - -@media (min-width: 1200px) { - .col-xl { - flex: 1 0 0% - } - - .row-cols-xl-auto > * { - flex: 0 0 auto; - width: auto - } - - .row-cols-xl-1 > * { - flex: 0 0 auto; - width: 100% - } - - .row-cols-xl-2 > * { - flex: 0 0 auto; - width: 50% - } - - .row-cols-xl-3 > * { - flex: 0 0 auto; - width: 33.3333333333% - } - - .row-cols-xl-4 > * { - flex: 0 0 auto; - width: 25% - } - - .row-cols-xl-5 > * { - flex: 0 0 auto; - width: 20% - } - - .row-cols-xl-6 > * { - flex: 0 0 auto; - width: 16.6666666667% - } - - .col-xl-auto { - flex: 0 0 auto; - width: auto - } - - .col-xl-1 { - flex: 0 0 auto; - width: 8.33333333% - } - - .col-xl-2 { - flex: 0 0 auto; - width: 16.66666667% - } - - .col-xl-3 { - flex: 0 0 auto; - width: 25% - } - - .col-xl-4 { - flex: 0 0 auto; - width: 33.33333333% - } - - .col-xl-5 { - flex: 0 0 auto; - width: 41.66666667% - } - - .col-xl-6 { - flex: 0 0 auto; - width: 50% - } - - .col-xl-7 { - flex: 0 0 auto; - width: 58.33333333% - } - - .col-xl-8 { - flex: 0 0 auto; - width: 66.66666667% - } - - .col-xl-9 { - flex: 0 0 auto; - width: 75% - } - - .col-xl-10 { - flex: 0 0 auto; - width: 83.33333333% - } - - .col-xl-11 { - flex: 0 0 auto; - width: 91.66666667% - } - - .col-xl-12 { - flex: 0 0 auto; - width: 100% - } - - .offset-xl-0 { - margin-left: 0 - } - - .offset-xl-1 { - margin-left: 8.33333333% - } - - .offset-xl-2 { - margin-left: 16.66666667% - } - - .offset-xl-3 { - margin-left: 25% - } - - .offset-xl-4 { - margin-left: 33.33333333% - } - - .offset-xl-5 { - margin-left: 41.66666667% - } - - .offset-xl-6 { - margin-left: 50% - } - - .offset-xl-7 { - margin-left: 58.33333333% - } - - .offset-xl-8 { - margin-left: 66.66666667% - } - - .offset-xl-9 { - margin-left: 75% - } - - .offset-xl-10 { - margin-left: 83.33333333% - } - - .offset-xl-11 { - margin-left: 91.66666667% - } - - .g-xl-0, .gx-xl-0 { - --bs-gutter-x: 0 - } - - .g-xl-0, .gy-xl-0 { - --bs-gutter-y: 0 - } - - .g-xl-1, .gx-xl-1 { - --bs-gutter-x: 0.25rem - } - - .g-xl-1, .gy-xl-1 { - --bs-gutter-y: 0.25rem - } - - .g-xl-2, .gx-xl-2 { - --bs-gutter-x: 0.5rem - } - - .g-xl-2, .gy-xl-2 { - --bs-gutter-y: 0.5rem - } - - .g-xl-3, .gx-xl-3 { - --bs-gutter-x: 1rem - } - - .g-xl-3, .gy-xl-3 { - --bs-gutter-y: 1rem - } - - .g-xl-4, .gx-xl-4 { - --bs-gutter-x: 1.5rem - } - - .g-xl-4, .gy-xl-4 { - --bs-gutter-y: 1.5rem - } - - .g-xl-5, .gx-xl-5 { - --bs-gutter-x: 3rem - } - - .g-xl-5, .gy-xl-5 { - --bs-gutter-y: 3rem - } -} - -@media (min-width: 1400px) { - .col-xxl { - flex: 1 0 0% - } - - .row-cols-xxl-auto > * { - flex: 0 0 auto; - width: auto - } - - .row-cols-xxl-1 > * { - flex: 0 0 auto; - width: 100% - } - - .row-cols-xxl-2 > * { - flex: 0 0 auto; - width: 50% - } - - .row-cols-xxl-3 > * { - flex: 0 0 auto; - width: 33.3333333333% - } - - .row-cols-xxl-4 > * { - flex: 0 0 auto; - width: 25% - } - - .row-cols-xxl-5 > * { - flex: 0 0 auto; - width: 20% - } - - .row-cols-xxl-6 > * { - flex: 0 0 auto; - width: 16.6666666667% - } - - .col-xxl-auto { - flex: 0 0 auto; - width: auto - } - - .col-xxl-1 { - flex: 0 0 auto; - width: 8.33333333% - } - - .col-xxl-2 { - flex: 0 0 auto; - width: 16.66666667% - } - - .col-xxl-3 { - flex: 0 0 auto; - width: 25% - } - - .col-xxl-4 { - flex: 0 0 auto; - width: 33.33333333% - } - - .col-xxl-5 { - flex: 0 0 auto; - width: 41.66666667% - } - - .col-xxl-6 { - flex: 0 0 auto; - width: 50% - } - - .col-xxl-7 { - flex: 0 0 auto; - width: 58.33333333% - } - - .col-xxl-8 { - flex: 0 0 auto; - width: 66.66666667% - } - - .col-xxl-9 { - flex: 0 0 auto; - width: 75% - } - - .col-xxl-10 { - flex: 0 0 auto; - width: 83.33333333% - } - - .col-xxl-11 { - flex: 0 0 auto; - width: 91.66666667% - } - - .col-xxl-12 { - flex: 0 0 auto; - width: 100% - } - - .offset-xxl-0 { - margin-left: 0 - } - - .offset-xxl-1 { - margin-left: 8.33333333% - } - - .offset-xxl-2 { - margin-left: 16.66666667% - } - - .offset-xxl-3 { - margin-left: 25% - } - - .offset-xxl-4 { - margin-left: 33.33333333% - } - - .offset-xxl-5 { - margin-left: 41.66666667% - } - - .offset-xxl-6 { - margin-left: 50% - } - - .offset-xxl-7 { - margin-left: 58.33333333% - } - - .offset-xxl-8 { - margin-left: 66.66666667% - } - - .offset-xxl-9 { - margin-left: 75% - } - - .offset-xxl-10 { - margin-left: 83.33333333% - } - - .offset-xxl-11 { - margin-left: 91.66666667% - } - - .g-xxl-0, .gx-xxl-0 { - --bs-gutter-x: 0 - } - - .g-xxl-0, .gy-xxl-0 { - --bs-gutter-y: 0 - } - - .g-xxl-1, .gx-xxl-1 { - --bs-gutter-x: 0.25rem - } - - .g-xxl-1, .gy-xxl-1 { - --bs-gutter-y: 0.25rem - } - - .g-xxl-2, .gx-xxl-2 { - --bs-gutter-x: 0.5rem - } - - .g-xxl-2, .gy-xxl-2 { - --bs-gutter-y: 0.5rem - } - - .g-xxl-3, .gx-xxl-3 { - --bs-gutter-x: 1rem - } - - .g-xxl-3, .gy-xxl-3 { - --bs-gutter-y: 1rem - } - - .g-xxl-4, .gx-xxl-4 { - --bs-gutter-x: 1.5rem - } - - .g-xxl-4, .gy-xxl-4 { - --bs-gutter-y: 1.5rem - } - - .g-xxl-5, .gx-xxl-5 { - --bs-gutter-x: 3rem - } - - .g-xxl-5, .gy-xxl-5 { - --bs-gutter-y: 3rem - } -} - -.table { - --bs-table-color: var(--bs-body-color); - --bs-table-bg: transparent; - --bs-table-border-color: #444; - --bs-table-accent-bg: transparent; - --bs-table-striped-color: var(--bs-body-color); - --bs-table-striped-bg: rgba(0, 0, 0, 0.05); - --bs-table-active-color: var(--bs-body-color); - --bs-table-active-bg: rgba(0, 0, 0, 0.1); - --bs-table-hover-color: var(--bs-body-color); - --bs-table-hover-bg: rgba(0, 0, 0, 0.075); - width: 100%; - margin-bottom: 1rem; - color: var(--bs-table-color); - vertical-align: top; - border-color: var(--bs-table-border-color) -} - -.table > :not(caption) > * > * { - padding: .5rem .5rem; - background-color: var(--bs-table-bg); - border-bottom-width: 1px; - box-shadow: inset 0 0 0 9999px var(--bs-table-accent-bg) -} - -.table > tbody { - vertical-align: inherit -} - -.table > thead { - vertical-align: bottom -} - -.table-group-divider { - border-top: 2px solid currentcolor -} - -.caption-top { - caption-side: top -} - -.table-sm > :not(caption) > * > * { - padding: .25rem .25rem -} - -.table-bordered > :not(caption) > * { - border-width: 1px 0 -} - -.table-bordered > :not(caption) > * > * { - border-width: 0 1px -} - -.table-borderless > :not(caption) > * > * { - border-bottom-width: 0 -} - -.table-borderless > :not(:first-child) { - border-top-width: 0 -} - -.table-striped > tbody > tr:nth-of-type(odd) > * { - --bs-table-accent-bg: var(--bs-table-striped-bg); - color: var(--bs-table-striped-color) -} - -.table-striped-columns > :not(caption) > tr > :nth-child(even) { - --bs-table-accent-bg: var(--bs-table-striped-bg); - color: var(--bs-table-striped-color) -} - -.table-active { - --bs-table-accent-bg: var(--bs-table-active-bg); - color: var(--bs-table-active-color) -} - -.table-hover > tbody > tr:hover > * { - --bs-table-accent-bg: var(--bs-table-hover-bg); - color: var(--bs-table-hover-color) -} - -.table-primary { - --bs-table-color: #fff; - --bs-table-bg: #375a7f; - --bs-table-border-color: #4b6b8c; - --bs-table-striped-bg: #416285; - --bs-table-striped-color: #fff; - --bs-table-active-bg: #4b6b8c; - --bs-table-active-color: #fff; - --bs-table-hover-bg: #466689; - --bs-table-hover-color: #fff; - color: var(--bs-table-color); - border-color: var(--bs-table-border-color) -} - -.table-secondary { - --bs-table-color: #fff; - --bs-table-bg: #444444; - --bs-table-border-color: #575757; - --bs-table-striped-bg: #4d4d4d; - --bs-table-striped-color: #fff; - --bs-table-active-bg: #575757; - --bs-table-active-color: #fff; - --bs-table-hover-bg: #525252; - --bs-table-hover-color: #fff; - color: var(--bs-table-color); - border-color: var(--bs-table-border-color) -} - -.table-success { - --bs-table-color: #fff; - --bs-table-bg: #00bc8c; - --bs-table-border-color: #1ac398; - --bs-table-striped-bg: #0dbf92; - --bs-table-striped-color: #fff; - --bs-table-active-bg: #1ac398; - --bs-table-active-color: #fff; - --bs-table-hover-bg: #13c195; - --bs-table-hover-color: #fff; - color: var(--bs-table-color); - border-color: var(--bs-table-border-color) -} - -.table-info { - --bs-table-color: #fff; - --bs-table-bg: #3498db; - --bs-table-border-color: #48a2df; - --bs-table-striped-bg: #3e9ddd; - --bs-table-striped-color: #fff; - --bs-table-active-bg: #48a2df; - --bs-table-active-color: #fff; - --bs-table-hover-bg: #43a0de; - --bs-table-hover-color: #fff; - color: var(--bs-table-color); - border-color: var(--bs-table-border-color) -} - -.table-warning { - --bs-table-color: #fff; - --bs-table-bg: #f39c12; - --bs-table-border-color: #f4a62a; - --bs-table-striped-bg: #f4a11e; - --bs-table-striped-color: #fff; - --bs-table-active-bg: #f4a62a; - --bs-table-active-color: #fff; - --bs-table-hover-bg: #f4a324; - --bs-table-hover-color: #fff; - color: var(--bs-table-color); - border-color: var(--bs-table-border-color) -} - -.table-danger { - --bs-table-color: #fff; - --bs-table-bg: #e74c3c; - --bs-table-border-color: #e95e50; - --bs-table-striped-bg: #e85546; - --bs-table-striped-color: #fff; - --bs-table-active-bg: #e95e50; - --bs-table-active-color: #fff; - --bs-table-hover-bg: #e9594b; - --bs-table-hover-color: #fff; - color: var(--bs-table-color); - border-color: var(--bs-table-border-color) -} - -.table-light { - --bs-table-color: #fff; - --bs-table-bg: #adb5bd; - --bs-table-border-color: #b5bcc4; - --bs-table-striped-bg: #b1b9c0; - --bs-table-striped-color: #fff; - --bs-table-active-bg: #b5bcc4; - --bs-table-active-color: #fff; - --bs-table-hover-bg: #b3bbc2; - --bs-table-hover-color: #fff; - color: var(--bs-table-color); - border-color: var(--bs-table-border-color) -} - -.table-dark { - --bs-table-color: #fff; - --bs-table-bg: #303030; - --bs-table-border-color: #454545; - --bs-table-striped-bg: #3a3a3a; - --bs-table-striped-color: #fff; - --bs-table-active-bg: #454545; - --bs-table-active-color: #fff; - --bs-table-hover-bg: #404040; - --bs-table-hover-color: #fff; - color: var(--bs-table-color); - border-color: var(--bs-table-border-color) -} - -.table-responsive { - overflow-x: auto; - -webkit-overflow-scrolling: touch -} - -@media (max-width: 575.98px) { - .table-responsive-sm { - overflow-x: auto; - -webkit-overflow-scrolling: touch - } -} - -@media (max-width: 767.98px) { - .table-responsive-md { - overflow-x: auto; - -webkit-overflow-scrolling: touch - } -} - -@media (max-width: 991.98px) { - .table-responsive-lg { - overflow-x: auto; - -webkit-overflow-scrolling: touch - } -} - -@media (max-width: 1199.98px) { - .table-responsive-xl { - overflow-x: auto; - -webkit-overflow-scrolling: touch - } -} - -@media (max-width: 1399.98px) { - .table-responsive-xxl { - overflow-x: auto; - -webkit-overflow-scrolling: touch - } -} - -.form-label { - margin-bottom: .5rem -} - -.col-form-label { - padding-top: calc(.375rem + 1px); - padding-bottom: calc(.375rem + 1px); - margin-bottom: 0; - font-size: inherit; - line-height: 1.5 -} - -.col-form-label-lg { - padding-top: calc(.5rem + 1px); - padding-bottom: calc(.5rem + 1px); - font-size: 1.25rem -} - -.col-form-label-sm { - padding-top: calc(.25rem + 1px); - padding-bottom: calc(.25rem + 1px); - font-size: .875rem -} - -.form-text { - margin-top: .25rem; - font-size: .875em; - color: #888 -} - -.form-control { - display: block; - width: 100%; - padding: .375rem .75rem; - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #303030; - background-color: #fff; - background-clip: padding-box; - border: 1px solid #222; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - border-radius: .375rem; - transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out -} - -@media (prefers-reduced-motion: reduce) { - .form-control { - transition: none - } -} - -.form-control[type=file] { - overflow: hidden -} - -.form-control[type=file]:not(:disabled):not([readonly]) { - cursor: pointer -} - -.form-control:focus { - color: #303030; - background-color: #fff; - border-color: #9badbf; - outline: 0; - box-shadow: 0 0 0 .25rem rgba(55, 90, 127, .25) -} - -.form-control::-webkit-date-and-time-value { - height: 1.5em -} - -.form-control::-moz-placeholder { - color: #888; - opacity: 1 -} - -.form-control::placeholder { - color: #888; - opacity: 1 -} - -.form-control:disabled { - background-color: #ebebeb; - opacity: 1 -} - -.form-control::-webkit-file-upload-button { - padding: .375rem .75rem; - margin: -.375rem -.75rem; - -webkit-margin-end: .75rem; - margin-inline-end: .75rem; - color: #fff; - background-color: #444; - pointer-events: none; - border-color: inherit; - border-style: solid; - border-width: 0; - border-inline-end-width: 1px; - border-radius: 0; - -webkit-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; - transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out -} - -.form-control::file-selector-button { - padding: .375rem .75rem; - margin: -.375rem -.75rem; - -webkit-margin-end: .75rem; - margin-inline-end: .75rem; - color: #fff; - background-color: #444; - pointer-events: none; - border-color: inherit; - border-style: solid; - border-width: 0; - border-inline-end-width: 1px; - border-radius: 0; - transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out -} - -@media (prefers-reduced-motion: reduce) { - .form-control::-webkit-file-upload-button { - -webkit-transition: none; - transition: none - } - - .form-control::file-selector-button { - transition: none - } -} - -.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button { - background-color: #414141 -} - -.form-control:hover:not(:disabled):not([readonly])::file-selector-button { - background-color: #414141 -} - -.form-control-plaintext { - display: block; - width: 100%; - padding: .375rem 0; - margin-bottom: 0; - line-height: 1.5; - color: #fff; - background-color: transparent; - border: solid transparent; - border-width: 1px 0 -} - -.form-control-plaintext:focus { - outline: 0 -} - -.form-control-plaintext.form-control-lg, .form-control-plaintext.form-control-sm { - padding-right: 0; - padding-left: 0 -} - -.form-control-sm { - min-height: calc(1.5em + .5rem + 2px); - padding: .25rem .5rem; - font-size: .875rem; - border-radius: .25rem -} - -.form-control-sm::-webkit-file-upload-button { - padding: .25rem .5rem; - margin: -.25rem -.5rem; - -webkit-margin-end: .5rem; - margin-inline-end: .5rem -} - -.form-control-sm::file-selector-button { - padding: .25rem .5rem; - margin: -.25rem -.5rem; - -webkit-margin-end: .5rem; - margin-inline-end: .5rem -} - -.form-control-lg { - min-height: calc(1.5em + 1rem + 2px); - padding: .5rem 1rem; - font-size: 1.25rem; - border-radius: .5rem -} - -.form-control-lg::-webkit-file-upload-button { - padding: .5rem 1rem; - margin: -.5rem -1rem; - -webkit-margin-end: 1rem; - margin-inline-end: 1rem -} - -.form-control-lg::file-selector-button { - padding: .5rem 1rem; - margin: -.5rem -1rem; - -webkit-margin-end: 1rem; - margin-inline-end: 1rem -} - -textarea.form-control { - min-height: calc(1.5em + .75rem + 2px) -} - -textarea.form-control-sm { - min-height: calc(1.5em + .5rem + 2px) -} - -textarea.form-control-lg { - min-height: calc(1.5em + 1rem + 2px) -} - -.form-control-color { - width: 3rem; - height: calc(1.5em + .75rem + 2px); - padding: .375rem -} - -.form-control-color:not(:disabled):not([readonly]) { - cursor: pointer -} - -.form-control-color::-moz-color-swatch { - border: 0 !important; - border-radius: .375rem -} - -.form-control-color::-webkit-color-swatch { - border-radius: .375rem -} - -.form-control-color.form-control-sm { - height: calc(1.5em + .5rem + 2px) -} - -.form-control-color.form-control-lg { - height: calc(1.5em + 1rem + 2px) -} - -.form-select { - display: block; - width: 100%; - padding: .375rem 2.25rem .375rem .75rem; - -moz-padding-start: calc(0.75rem - 3px); - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #303030; - background-color: #fff; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-position: right .75rem center; - background-size: 16px 12px; - border: 1px solid #222; - border-radius: .375rem; - transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none -} - -@media (prefers-reduced-motion: reduce) { - .form-select { - transition: none - } -} - -.form-select:focus { - border-color: #9badbf; - outline: 0; - box-shadow: 0 0 0 .25rem rgba(55, 90, 127, .25) -} - -.form-select[multiple], .form-select[size]:not([size="1"]) { - padding-right: .75rem; - background-image: none -} - -.form-select:disabled { - background-color: #ebebeb -} - -.form-select:-moz-focusring { - color: transparent; - text-shadow: 0 0 0 #303030 -} - -.form-select-sm { - padding-top: .25rem; - padding-bottom: .25rem; - padding-left: .5rem; - font-size: .875rem; - border-radius: .25rem -} - -.form-select-lg { - padding-top: .5rem; - padding-bottom: .5rem; - padding-left: 1rem; - font-size: 1.25rem; - border-radius: .5rem -} - -.form-check { - display: block; - min-height: 1.5rem; - padding-left: 1.5em; - margin-bottom: .125rem -} - -.form-check .form-check-input { - float: left; - margin-left: -1.5em -} - -.form-check-reverse { - padding-right: 1.5em; - padding-left: 0; - text-align: right -} - -.form-check-reverse .form-check-input { - float: right; - margin-right: -1.5em; - margin-left: 0 -} - -.form-check-input { - width: 1em; - height: 1em; - margin-top: .25em; - vertical-align: top; - background-color: #fff; - background-repeat: no-repeat; - background-position: center; - background-size: contain; - border: none; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-print-color-adjust: exact; - color-adjust: exact; - print-color-adjust: exact -} - -.form-check-input[type=checkbox] { - border-radius: .25em -} - -.form-check-input[type=radio] { - border-radius: 50% -} - -.form-check-input:active { - filter: brightness(90%) -} - -.form-check-input:focus { - border-color: #9badbf; - outline: 0; - box-shadow: 0 0 0 .25rem rgba(55, 90, 127, .25) -} - -.form-check-input:checked { - background-color: #375a7f; - border-color: #375a7f -} - -.form-check-input:checked[type=checkbox] { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e") -} - -.form-check-input:checked[type=radio] { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e") -} - -.form-check-input[type=checkbox]:indeterminate { - background-color: #375a7f; - border-color: #375a7f; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e") -} - -.form-check-input:disabled { - pointer-events: none; - filter: none; - opacity: .5 -} - -.form-check-input:disabled ~ .form-check-label, .form-check-input[disabled] ~ .form-check-label { - cursor: default; - opacity: .5 -} - -.form-switch { - padding-left: 2.5em -} - -.form-switch .form-check-input { - width: 2em; - margin-left: -2.5em; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e"); - background-position: left center; - border-radius: 2em; - transition: background-position .15s ease-in-out -} - -@media (prefers-reduced-motion: reduce) { - .form-switch .form-check-input { - transition: none - } -} - -.form-switch .form-check-input:focus { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%239badbf'/%3e%3c/svg%3e") -} - -.form-switch .form-check-input:checked { - background-position: right center; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e") -} - -.form-switch.form-check-reverse { - padding-right: 2.5em; - padding-left: 0 -} - -.form-switch.form-check-reverse .form-check-input { - margin-right: -2.5em; - margin-left: 0 -} - -.form-check-inline { - display: inline-block; - margin-right: 1rem -} - -.btn-check { - position: absolute; - clip: rect(0, 0, 0, 0); - pointer-events: none -} - -.btn-check:disabled + .btn, .btn-check[disabled] + .btn { - pointer-events: none; - filter: none; - opacity: .65 -} - -.form-range { - width: 100%; - height: 1.5rem; - padding: 0; - background-color: transparent; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none -} - -.form-range:focus { - outline: 0 -} - -.form-range:focus::-webkit-slider-thumb { - box-shadow: 0 0 0 1px #222, 0 0 0 .25rem rgba(55, 90, 127, .25) -} - -.form-range:focus::-moz-range-thumb { - box-shadow: 0 0 0 1px #222, 0 0 0 .25rem rgba(55, 90, 127, .25) -} - -.form-range::-moz-focus-outer { - border: 0 -} - -.form-range::-webkit-slider-thumb { - width: 1rem; - height: 1rem; - margin-top: -.25rem; - background-color: #375a7f; - border: 0; - border-radius: 1rem; - -webkit-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; - transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; - -webkit-appearance: none; - appearance: none -} - -@media (prefers-reduced-motion: reduce) { - .form-range::-webkit-slider-thumb { - -webkit-transition: none; - transition: none - } -} - -.form-range::-webkit-slider-thumb:active { - background-color: #c3ced9 -} - -.form-range::-webkit-slider-runnable-track { - width: 100%; - height: .5rem; - color: transparent; - cursor: pointer; - background-color: #dee2e6; - border-color: transparent; - border-radius: 1rem -} - -.form-range::-moz-range-thumb { - width: 1rem; - height: 1rem; - background-color: #375a7f; - border: 0; - border-radius: 1rem; - -moz-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; - transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; - -moz-appearance: none; - appearance: none -} - -@media (prefers-reduced-motion: reduce) { - .form-range::-moz-range-thumb { - -moz-transition: none; - transition: none - } -} - -.form-range::-moz-range-thumb:active { - background-color: #c3ced9 -} - -.form-range::-moz-range-track { - width: 100%; - height: .5rem; - color: transparent; - cursor: pointer; - background-color: #dee2e6; - border-color: transparent; - border-radius: 1rem -} - -.form-range:disabled { - pointer-events: none -} - -.form-range:disabled::-webkit-slider-thumb { - background-color: #adb5bd -} - -.form-range:disabled::-moz-range-thumb { - background-color: #adb5bd -} - -.form-floating { - position: relative -} - -.form-floating > .form-control, .form-floating > .form-control-plaintext, .form-floating > .form-select { - height: calc(3.5rem + 2px); - line-height: 1.25 -} - -.form-floating > label { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - padding: 1rem .75rem; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - pointer-events: none; - border: 1px solid transparent; - transform-origin: 0 0; - transition: opacity .1s ease-in-out, transform .1s ease-in-out -} - -@media (prefers-reduced-motion: reduce) { - .form-floating > label { - transition: none - } -} - -.form-floating > .form-control, .form-floating > .form-control-plaintext { - padding: 1rem .75rem -} - -.form-floating > .form-control-plaintext::-moz-placeholder, .form-floating > .form-control::-moz-placeholder { - color: transparent -} - -.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder { - color: transparent -} - -.form-floating > .form-control-plaintext:not(:-moz-placeholder-shown), .form-floating > .form-control:not(:-moz-placeholder-shown) { - padding-top: 1.625rem; - padding-bottom: .625rem -} - -.form-floating > .form-control-plaintext:focus, .form-floating > .form-control-plaintext:not(:placeholder-shown), .form-floating > .form-control:focus, .form-floating > .form-control:not(:placeholder-shown) { - padding-top: 1.625rem; - padding-bottom: .625rem -} - -.form-floating > .form-control-plaintext:-webkit-autofill, .form-floating > .form-control:-webkit-autofill { - padding-top: 1.625rem; - padding-bottom: .625rem -} - -.form-floating > .form-select { - padding-top: 1.625rem; - padding-bottom: .625rem -} - -.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label { - opacity: .65; - transform: scale(.85) translateY(-.5rem) translateX(.15rem) -} - -.form-floating > .form-control-plaintext ~ label, .form-floating > .form-control:focus ~ label, .form-floating > .form-control:not(:placeholder-shown) ~ label, .form-floating > .form-select ~ label { - opacity: .65; - transform: scale(.85) translateY(-.5rem) translateX(.15rem) -} - -.form-floating > .form-control:-webkit-autofill ~ label { - opacity: .65; - transform: scale(.85) translateY(-.5rem) translateX(.15rem) -} - -.form-floating > .form-control-plaintext ~ label { - border-width: 1px 0 -} - -.input-group { - position: relative; - display: flex; - flex-wrap: wrap; - align-items: stretch; - width: 100% -} - -.input-group > .form-control, .input-group > .form-floating, .input-group > .form-select { - position: relative; - flex: 1 1 auto; - width: 1%; - min-width: 0 -} - -.input-group > .form-control:focus, .input-group > .form-floating:focus-within, .input-group > .form-select:focus { - z-index: 3 -} - -.input-group .btn { - position: relative; - z-index: 2 -} - -.input-group .btn:focus { - z-index: 3 -} - -.input-group-text { - display: flex; - align-items: center; - padding: .375rem .75rem; - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #adb5bd; - text-align: center; - white-space: nowrap; - background-color: #444; - border: 1px solid #222; - border-radius: .375rem -} - -.input-group-lg > .btn, .input-group-lg > .form-control, .input-group-lg > .form-select, .input-group-lg > .input-group-text { - padding: .5rem 1rem; - font-size: 1.25rem; - border-radius: .5rem -} - -.input-group-sm > .btn, .input-group-sm > .form-control, .input-group-sm > .form-select, .input-group-sm > .input-group-text { - padding: .25rem .5rem; - font-size: .875rem; - border-radius: .25rem -} - -.input-group-lg > .form-select, .input-group-sm > .form-select { - padding-right: 3rem -} - -.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3), .input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-control, .input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-select, .input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating) { - border-top-right-radius: 0; - border-bottom-right-radius: 0 -} - -.input-group.has-validation > .dropdown-toggle:nth-last-child(n+4), .input-group.has-validation > .form-floating:nth-last-child(n+3) > .form-control, .input-group.has-validation > .form-floating:nth-last-child(n+3) > .form-select, .input-group.has-validation > :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating) { - border-top-right-radius: 0; - border-bottom-right-radius: 0 -} - -.input-group > .form-floating:not(:first-child) > .form-control, .input-group > .form-floating:not(:first-child) > .form-select, .input-group > :not(:first-child):not(.dropdown-menu):not(.form-floating):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) { - margin-left: -1px; - border-top-left-radius: 0; - border-bottom-left-radius: 0 -} - -.valid-feedback { - display: none; - width: 100%; - margin-top: .25rem; - font-size: .875em; - color: #00bc8c -} - -.valid-tooltip { - position: absolute; - top: 100%; - z-index: 5; - display: none; - max-width: 100%; - padding: .25rem .5rem; - margin-top: .1rem; - font-size: .875rem; - color: #fff; - background-color: rgba(0, 188, 140, .9); - border-radius: .375rem -} - -.is-valid ~ .valid-feedback, .is-valid ~ .valid-tooltip, .was-validated :valid ~ .valid-feedback, .was-validated :valid ~ .valid-tooltip { - display: block -} - -.form-control.is-valid, .was-validated .form-control:valid { - border-color: #00bc8c; - padding-right: calc(1.5em + .75rem); - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-position: right calc(.375em + .1875rem) center; - background-size: calc(.75em + .375rem) calc(.75em + .375rem) -} - -.form-control.is-valid:focus, .was-validated .form-control:valid:focus { - border-color: #00bc8c; - box-shadow: 0 0 0 .25rem rgba(0, 188, 140, .25) -} - -.was-validated textarea.form-control:valid, textarea.form-control.is-valid { - padding-right: calc(1.5em + .75rem); - background-position: top calc(.375em + .1875rem) right calc(.375em + .1875rem) -} - -.form-select.is-valid, .was-validated .form-select:valid { - border-color: #00bc8c -} - -.form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size="1"], .was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size="1"] { - padding-right: 4.125rem; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); - background-position: right .75rem center, center right 2.25rem; - background-size: 16px 12px, calc(.75em + .375rem) calc(.75em + .375rem) -} - -.form-select.is-valid:focus, .was-validated .form-select:valid:focus { - border-color: #00bc8c; - box-shadow: 0 0 0 .25rem rgba(0, 188, 140, .25) -} - -.form-control-color.is-valid, .was-validated .form-control-color:valid { - width: calc(3rem + calc(1.5em + .75rem)) -} - -.form-check-input.is-valid, .was-validated .form-check-input:valid { - border-color: #00bc8c -} - -.form-check-input.is-valid:checked, .was-validated .form-check-input:valid:checked { - background-color: #00bc8c -} - -.form-check-input.is-valid:focus, .was-validated .form-check-input:valid:focus { - box-shadow: 0 0 0 .25rem rgba(0, 188, 140, .25) -} - -.form-check-input.is-valid ~ .form-check-label, .was-validated .form-check-input:valid ~ .form-check-label { - color: #00bc8c -} - -.form-check-inline .form-check-input ~ .valid-feedback { - margin-left: .5em -} - -.input-group .form-control.is-valid, .input-group .form-select.is-valid, .was-validated .input-group .form-control:valid, .was-validated .input-group .form-select:valid { - z-index: 1 -} - -.input-group .form-control.is-valid:focus, .input-group .form-select.is-valid:focus, .was-validated .input-group .form-control:valid:focus, .was-validated .input-group .form-select:valid:focus { - z-index: 3 -} - -.invalid-feedback { - display: none; - width: 100%; - margin-top: .25rem; - font-size: .875em; - color: #e74c3c -} - -.invalid-tooltip { - position: absolute; - top: 100%; - z-index: 5; - display: none; - max-width: 100%; - padding: .25rem .5rem; - margin-top: .1rem; - font-size: .875rem; - color: #fff; - background-color: rgba(231, 76, 60, .9); - border-radius: .375rem -} - -.is-invalid ~ .invalid-feedback, .is-invalid ~ .invalid-tooltip, .was-validated :invalid ~ .invalid-feedback, .was-validated :invalid ~ .invalid-tooltip { - display: block -} - -.form-control.is-invalid, .was-validated .form-control:invalid { - border-color: #e74c3c; - padding-right: calc(1.5em + .75rem); - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-position: right calc(.375em + .1875rem) center; - background-size: calc(.75em + .375rem) calc(.75em + .375rem) -} - -.form-control.is-invalid:focus, .was-validated .form-control:invalid:focus { - border-color: #e74c3c; - box-shadow: 0 0 0 .25rem rgba(231, 76, 60, .25) -} - -.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid { - padding-right: calc(1.5em + .75rem); - background-position: top calc(.375em + .1875rem) right calc(.375em + .1875rem) -} - -.form-select.is-invalid, .was-validated .form-select:invalid { - border-color: #e74c3c -} - -.form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size="1"], .was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size="1"] { - padding-right: 4.125rem; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e"); - background-position: right .75rem center, center right 2.25rem; - background-size: 16px 12px, calc(.75em + .375rem) calc(.75em + .375rem) -} - -.form-select.is-invalid:focus, .was-validated .form-select:invalid:focus { - border-color: #e74c3c; - box-shadow: 0 0 0 .25rem rgba(231, 76, 60, .25) -} - -.form-control-color.is-invalid, .was-validated .form-control-color:invalid { - width: calc(3rem + calc(1.5em + .75rem)) -} - -.form-check-input.is-invalid, .was-validated .form-check-input:invalid { - border-color: #e74c3c -} - -.form-check-input.is-invalid:checked, .was-validated .form-check-input:invalid:checked { - background-color: #e74c3c -} - -.form-check-input.is-invalid:focus, .was-validated .form-check-input:invalid:focus { - box-shadow: 0 0 0 .25rem rgba(231, 76, 60, .25) -} - -.form-check-input.is-invalid ~ .form-check-label, .was-validated .form-check-input:invalid ~ .form-check-label { - color: #e74c3c -} - -.form-check-inline .form-check-input ~ .invalid-feedback { - margin-left: .5em -} - -.input-group .form-control.is-invalid, .input-group .form-select.is-invalid, .was-validated .input-group .form-control:invalid, .was-validated .input-group .form-select:invalid { - z-index: 2 -} - -.input-group .form-control.is-invalid:focus, .input-group .form-select.is-invalid:focus, .was-validated .input-group .form-control:invalid:focus, .was-validated .input-group .form-select:invalid:focus { - z-index: 3 -} - -.btn { - --bs-btn-padding-x: 0.75rem; - --bs-btn-padding-y: 0.375rem; - --bs-btn-font-family: ; - --bs-btn-font-size: 1rem; - --bs-btn-font-weight: 400; - --bs-btn-line-height: 1.5; - --bs-btn-color: #fff; - --bs-btn-bg: transparent; - --bs-btn-border-width: 1px; - --bs-btn-border-color: transparent; - --bs-btn-border-radius: 0.375rem; - --bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075); - --bs-btn-disabled-opacity: 0.65; - --bs-btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5); - display: inline-block; - padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x); - font-family: var(--bs-btn-font-family); - font-size: var(--bs-btn-font-size); - font-weight: var(--bs-btn-font-weight); - line-height: var(--bs-btn-line-height); - color: var(--bs-btn-color); - text-align: center; - text-decoration: none; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - border: var(--bs-btn-border-width) solid var(--bs-btn-border-color); - border-radius: var(--bs-btn-border-radius); - background-color: var(--bs-btn-bg); - transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out -} - -@media (prefers-reduced-motion: reduce) { - .btn { - transition: none - } -} - -.btn:hover { - color: var(--bs-btn-hover-color); - background-color: var(--bs-btn-hover-bg); - border-color: var(--bs-btn-hover-border-color) -} - -.btn-check:focus + .btn, .btn:focus { - color: var(--bs-btn-hover-color); - background-color: var(--bs-btn-hover-bg); - border-color: var(--bs-btn-hover-border-color); - outline: 0; - box-shadow: var(--bs-btn-focus-box-shadow) -} - -.btn-check:active + .btn, .btn-check:checked + .btn, .btn.active, .btn.show, .btn:active { - color: var(--bs-btn-active-color); - background-color: var(--bs-btn-active-bg); - border-color: var(--bs-btn-active-border-color) -} - -.btn-check:active + .btn:focus, .btn-check:checked + .btn:focus, .btn.active:focus, .btn.show:focus, .btn:active:focus { - box-shadow: var(--bs-btn-focus-box-shadow) -} - -.btn.disabled, .btn:disabled, fieldset:disabled .btn { - color: var(--bs-btn-disabled-color); - pointer-events: none; - background-color: var(--bs-btn-disabled-bg); - border-color: var(--bs-btn-disabled-border-color); - opacity: var(--bs-btn-disabled-opacity) -} - -.btn-primary { - --bs-btn-color: #fff; - --bs-btn-bg: #375a7f; - --bs-btn-border-color: #375a7f; - --bs-btn-hover-color: #fff; - --bs-btn-hover-bg: #2f4d6c; - --bs-btn-hover-border-color: #2c4866; - --bs-btn-focus-shadow-rgb: 85, 115, 146; - --bs-btn-active-color: #fff; - --bs-btn-active-bg: #2c4866; - --bs-btn-active-border-color: #29445f; - --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - --bs-btn-disabled-color: #fff; - --bs-btn-disabled-bg: #375a7f; - --bs-btn-disabled-border-color: #375a7f -} - -.btn-secondary { - --bs-btn-color: #fff; - --bs-btn-bg: #444; - --bs-btn-border-color: #444; - --bs-btn-hover-color: #fff; - --bs-btn-hover-bg: #3a3a3a; - --bs-btn-hover-border-color: #363636; - --bs-btn-focus-shadow-rgb: 96, 96, 96; - --bs-btn-active-color: #fff; - --bs-btn-active-bg: #363636; - --bs-btn-active-border-color: #333333; - --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - --bs-btn-disabled-color: #fff; - --bs-btn-disabled-bg: #444; - --bs-btn-disabled-border-color: #444 -} - -.btn-success { - --bs-btn-color: #fff; - --bs-btn-bg: #00bc8c; - --bs-btn-border-color: #00bc8c; - --bs-btn-hover-color: #fff; - --bs-btn-hover-bg: #00a077; - --bs-btn-hover-border-color: #009670; - --bs-btn-focus-shadow-rgb: 38, 198, 157; - --bs-btn-active-color: #fff; - --bs-btn-active-bg: #009670; - --bs-btn-active-border-color: #008d69; - --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - --bs-btn-disabled-color: #fff; - --bs-btn-disabled-bg: #00bc8c; - --bs-btn-disabled-border-color: #00bc8c -} - -.btn-info { - --bs-btn-color: #fff; - --bs-btn-bg: #3498db; - --bs-btn-border-color: #3498db; - --bs-btn-hover-color: #fff; - --bs-btn-hover-bg: #2c81ba; - --bs-btn-hover-border-color: #2a7aaf; - --bs-btn-focus-shadow-rgb: 82, 167, 224; - --bs-btn-active-color: #fff; - --bs-btn-active-bg: #2a7aaf; - --bs-btn-active-border-color: #2772a4; - --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - --bs-btn-disabled-color: #fff; - --bs-btn-disabled-bg: #3498db; - --bs-btn-disabled-border-color: #3498db -} - -.btn-warning { - --bs-btn-color: #fff; - --bs-btn-bg: #f39c12; - --bs-btn-border-color: #f39c12; - --bs-btn-hover-color: #fff; - --bs-btn-hover-bg: #cf850f; - --bs-btn-hover-border-color: #c27d0e; - --bs-btn-focus-shadow-rgb: 245, 171, 54; - --bs-btn-active-color: #fff; - --bs-btn-active-bg: #c27d0e; - --bs-btn-active-border-color: #b6750e; - --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - --bs-btn-disabled-color: #fff; - --bs-btn-disabled-bg: #f39c12; - --bs-btn-disabled-border-color: #f39c12 -} - -.btn-danger { - --bs-btn-color: #fff; - --bs-btn-bg: #e74c3c; - --bs-btn-border-color: #e74c3c; - --bs-btn-hover-color: #fff; - --bs-btn-hover-bg: #c44133; - --bs-btn-hover-border-color: #b93d30; - --bs-btn-focus-shadow-rgb: 235, 103, 89; - --bs-btn-active-color: #fff; - --bs-btn-active-bg: #b93d30; - --bs-btn-active-border-color: #ad392d; - --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - --bs-btn-disabled-color: #fff; - --bs-btn-disabled-bg: #e74c3c; - --bs-btn-disabled-border-color: #e74c3c -} - -.btn-light { - --bs-btn-color: #fff; - --bs-btn-bg: #adb5bd; - --bs-btn-border-color: #adb5bd; - --bs-btn-hover-color: #fff; - --bs-btn-hover-bg: #939aa1; - --bs-btn-hover-border-color: #8a9197; - --bs-btn-focus-shadow-rgb: 185, 192, 199; - --bs-btn-active-color: #fff; - --bs-btn-active-bg: #8a9197; - --bs-btn-active-border-color: #82888e; - --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - --bs-btn-disabled-color: #fff; - --bs-btn-disabled-bg: #adb5bd; - --bs-btn-disabled-border-color: #adb5bd -} - -.btn-dark { - --bs-btn-color: #fff; - --bs-btn-bg: #303030; - --bs-btn-border-color: #303030; - --bs-btn-hover-color: #fff; - --bs-btn-hover-bg: #4f4f4f; - --bs-btn-hover-border-color: #454545; - --bs-btn-focus-shadow-rgb: 79, 79, 79; - --bs-btn-active-color: #fff; - --bs-btn-active-bg: #595959; - --bs-btn-active-border-color: #454545; - --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - --bs-btn-disabled-color: #fff; - --bs-btn-disabled-bg: #303030; - --bs-btn-disabled-border-color: #303030 -} - -.btn-outline-primary { - --bs-btn-color: #375a7f; - --bs-btn-border-color: #375a7f; - --bs-btn-hover-color: #fff; - --bs-btn-hover-bg: #375a7f; - --bs-btn-hover-border-color: #375a7f; - --bs-btn-focus-shadow-rgb: 55, 90, 127; - --bs-btn-active-color: #fff; - --bs-btn-active-bg: #375a7f; - --bs-btn-active-border-color: #375a7f; - --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - --bs-btn-disabled-color: #375a7f; - --bs-btn-disabled-bg: transparent; - --bs-btn-disabled-border-color: #375a7f; - --bs-gradient: none -} - -.btn-outline-secondary { - --bs-btn-color: #444; - --bs-btn-border-color: #444; - --bs-btn-hover-color: #fff; - --bs-btn-hover-bg: #444; - --bs-btn-hover-border-color: #444; - --bs-btn-focus-shadow-rgb: 68, 68, 68; - --bs-btn-active-color: #fff; - --bs-btn-active-bg: #444; - --bs-btn-active-border-color: #444; - --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - --bs-btn-disabled-color: #444; - --bs-btn-disabled-bg: transparent; - --bs-btn-disabled-border-color: #444; - --bs-gradient: none -} - -.btn-outline-success { - --bs-btn-color: #00bc8c; - --bs-btn-border-color: #00bc8c; - --bs-btn-hover-color: #fff; - --bs-btn-hover-bg: #00bc8c; - --bs-btn-hover-border-color: #00bc8c; - --bs-btn-focus-shadow-rgb: 0, 188, 140; - --bs-btn-active-color: #fff; - --bs-btn-active-bg: #00bc8c; - --bs-btn-active-border-color: #00bc8c; - --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - --bs-btn-disabled-color: #00bc8c; - --bs-btn-disabled-bg: transparent; - --bs-btn-disabled-border-color: #00bc8c; - --bs-gradient: none -} - -.btn-outline-info { - --bs-btn-color: #3498db; - --bs-btn-border-color: #3498db; - --bs-btn-hover-color: #fff; - --bs-btn-hover-bg: #3498db; - --bs-btn-hover-border-color: #3498db; - --bs-btn-focus-shadow-rgb: 52, 152, 219; - --bs-btn-active-color: #fff; - --bs-btn-active-bg: #3498db; - --bs-btn-active-border-color: #3498db; - --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - --bs-btn-disabled-color: #3498db; - --bs-btn-disabled-bg: transparent; - --bs-btn-disabled-border-color: #3498db; - --bs-gradient: none -} - -.btn-outline-warning { - --bs-btn-color: #f39c12; - --bs-btn-border-color: #f39c12; - --bs-btn-hover-color: #fff; - --bs-btn-hover-bg: #f39c12; - --bs-btn-hover-border-color: #f39c12; - --bs-btn-focus-shadow-rgb: 243, 156, 18; - --bs-btn-active-color: #fff; - --bs-btn-active-bg: #f39c12; - --bs-btn-active-border-color: #f39c12; - --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - --bs-btn-disabled-color: #f39c12; - --bs-btn-disabled-bg: transparent; - --bs-btn-disabled-border-color: #f39c12; - --bs-gradient: none -} - -.btn-outline-danger { - --bs-btn-color: #e74c3c; - --bs-btn-border-color: #e74c3c; - --bs-btn-hover-color: #fff; - --bs-btn-hover-bg: #e74c3c; - --bs-btn-hover-border-color: #e74c3c; - --bs-btn-focus-shadow-rgb: 231, 76, 60; - --bs-btn-active-color: #fff; - --bs-btn-active-bg: #e74c3c; - --bs-btn-active-border-color: #e74c3c; - --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - --bs-btn-disabled-color: #e74c3c; - --bs-btn-disabled-bg: transparent; - --bs-btn-disabled-border-color: #e74c3c; - --bs-gradient: none -} - -.btn-outline-light { - --bs-btn-color: #adb5bd; - --bs-btn-border-color: #adb5bd; - --bs-btn-hover-color: #fff; - --bs-btn-hover-bg: #adb5bd; - --bs-btn-hover-border-color: #adb5bd; - --bs-btn-focus-shadow-rgb: 173, 181, 189; - --bs-btn-active-color: #fff; - --bs-btn-active-bg: #adb5bd; - --bs-btn-active-border-color: #adb5bd; - --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - --bs-btn-disabled-color: #adb5bd; - --bs-btn-disabled-bg: transparent; - --bs-btn-disabled-border-color: #adb5bd; - --bs-gradient: none -} - -.btn-outline-dark { - --bs-btn-color: #303030; - --bs-btn-border-color: #303030; - --bs-btn-hover-color: #fff; - --bs-btn-hover-bg: #303030; - --bs-btn-hover-border-color: #303030; - --bs-btn-focus-shadow-rgb: 48, 48, 48; - --bs-btn-active-color: #fff; - --bs-btn-active-bg: #303030; - --bs-btn-active-border-color: #303030; - --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - --bs-btn-disabled-color: #303030; - --bs-btn-disabled-bg: transparent; - --bs-btn-disabled-border-color: #303030; - --bs-gradient: none -} - -.btn-link { - --bs-btn-font-weight: 400; - --bs-btn-color: var(--bs-link-color); - --bs-btn-bg: transparent; - --bs-btn-border-color: transparent; - --bs-btn-hover-color: var(--bs-link-hover-color); - --bs-btn-hover-border-color: transparent; - --bs-btn-active-color: var(--bs-link-hover-color); - --bs-btn-active-border-color: transparent; - --bs-btn-disabled-color: #888; - --bs-btn-disabled-border-color: transparent; - --bs-btn-box-shadow: none; - --bs-btn-focus-shadow-rgb: 85, 115, 146; - text-decoration: underline -} - -.btn-link:focus { - color: var(--bs-btn-color) -} - -.btn-link:hover { - color: var(--bs-btn-hover-color) -} - -.btn-group-lg > .btn, .btn-lg { - --bs-btn-padding-y: 0.5rem; - --bs-btn-padding-x: 1rem; - --bs-btn-font-size: 1.25rem; - --bs-btn-border-radius: 0.5rem -} - -.btn-group-sm > .btn, .btn-sm { - --bs-btn-padding-y: 0.25rem; - --bs-btn-padding-x: 0.5rem; - --bs-btn-font-size: 0.875rem; - --bs-btn-border-radius: 0.25rem -} - -.fade { - transition: opacity .15s linear -} - -@media (prefers-reduced-motion: reduce) { - .fade { - transition: none - } -} - -.fade:not(.show) { - opacity: 0 -} - -.collapse:not(.show) { - display: none -} - -.collapsing { - height: 0; - overflow: hidden; - transition: height .35s ease -} - -@media (prefers-reduced-motion: reduce) { - .collapsing { - transition: none - } -} - -.collapsing.collapse-horizontal { - width: 0; - height: auto; - transition: width .35s ease -} - -@media (prefers-reduced-motion: reduce) { - .collapsing.collapse-horizontal { - transition: none - } -} - -.dropdown, .dropdown-center, .dropend, .dropstart, .dropup, .dropup-center { - position: relative -} - -.dropdown-toggle { - white-space: nowrap -} - -.dropdown-toggle::after { - display: inline-block; - margin-left: .255em; - vertical-align: .255em; - content: ""; - border-top: .3em solid; - border-right: .3em solid transparent; - border-bottom: 0; - border-left: .3em solid transparent -} - -.dropdown-toggle:empty::after { - margin-left: 0 -} - -.dropdown-menu { - --bs-dropdown-min-width: 10rem; - --bs-dropdown-padding-x: 0; - --bs-dropdown-padding-y: 0.5rem; - --bs-dropdown-spacer: 0.125rem; - --bs-dropdown-font-size: 1rem; - --bs-dropdown-color: #fff; - --bs-dropdown-bg: #222; - --bs-dropdown-border-color: #444; - --bs-dropdown-border-radius: 0.375rem; - --bs-dropdown-border-width: 1px; - --bs-dropdown-inner-border-radius: calc(0.375rem - 1px); - --bs-dropdown-divider-bg: #444; - --bs-dropdown-divider-margin-y: 0.5rem; - --bs-dropdown-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); - --bs-dropdown-link-color: #fff; - --bs-dropdown-link-hover-color: #fff; - --bs-dropdown-link-hover-bg: #375a7f; - --bs-dropdown-link-active-color: #fff; - --bs-dropdown-link-active-bg: #375a7f; - --bs-dropdown-link-disabled-color: #adb5bd; - --bs-dropdown-item-padding-x: 1rem; - --bs-dropdown-item-padding-y: 0.25rem; - --bs-dropdown-header-color: #888; - --bs-dropdown-header-padding-x: 1rem; - --bs-dropdown-header-padding-y: 0.5rem; - position: absolute; - z-index: 1000; - display: none; - min-width: var(--bs-dropdown-min-width); - padding: var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x); - margin: 0; - font-size: var(--bs-dropdown-font-size); - color: var(--bs-dropdown-color); - text-align: left; - list-style: none; - background-color: var(--bs-dropdown-bg); - background-clip: padding-box; - border: var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color); - border-radius: var(--bs-dropdown-border-radius) -} - -.dropdown-menu[data-bs-popper] { - top: 100%; - left: 0; - margin-top: var(--bs-dropdown-spacer) -} - -.dropdown-menu-start { - --bs-position: start -} - -.dropdown-menu-start[data-bs-popper] { - right: auto; - left: 0 -} - -.dropdown-menu-end { - --bs-position: end -} - -.dropdown-menu-end[data-bs-popper] { - right: 0; - left: auto -} - -@media (min-width: 576px) { - .dropdown-menu-sm-start { - --bs-position: start - } - - .dropdown-menu-sm-start[data-bs-popper] { - right: auto; - left: 0 - } - - .dropdown-menu-sm-end { - --bs-position: end - } - - .dropdown-menu-sm-end[data-bs-popper] { - right: 0; - left: auto - } -} - -@media (min-width: 768px) { - .dropdown-menu-md-start { - --bs-position: start - } - - .dropdown-menu-md-start[data-bs-popper] { - right: auto; - left: 0 - } - - .dropdown-menu-md-end { - --bs-position: end - } - - .dropdown-menu-md-end[data-bs-popper] { - right: 0; - left: auto - } -} - -@media (min-width: 992px) { - .dropdown-menu-lg-start { - --bs-position: start - } - - .dropdown-menu-lg-start[data-bs-popper] { - right: auto; - left: 0 - } - - .dropdown-menu-lg-end { - --bs-position: end - } - - .dropdown-menu-lg-end[data-bs-popper] { - right: 0; - left: auto - } -} - -@media (min-width: 1200px) { - .dropdown-menu-xl-start { - --bs-position: start - } - - .dropdown-menu-xl-start[data-bs-popper] { - right: auto; - left: 0 - } - - .dropdown-menu-xl-end { - --bs-position: end - } - - .dropdown-menu-xl-end[data-bs-popper] { - right: 0; - left: auto - } -} - -@media (min-width: 1400px) { - .dropdown-menu-xxl-start { - --bs-position: start - } - - .dropdown-menu-xxl-start[data-bs-popper] { - right: auto; - left: 0 - } - - .dropdown-menu-xxl-end { - --bs-position: end - } - - .dropdown-menu-xxl-end[data-bs-popper] { - right: 0; - left: auto - } -} - -.dropup .dropdown-menu[data-bs-popper] { - top: auto; - bottom: 100%; - margin-top: 0; - margin-bottom: var(--bs-dropdown-spacer) -} - -.dropup .dropdown-toggle::after { - display: inline-block; - margin-left: .255em; - vertical-align: .255em; - content: ""; - border-top: 0; - border-right: .3em solid transparent; - border-bottom: .3em solid; - border-left: .3em solid transparent -} - -.dropup .dropdown-toggle:empty::after { - margin-left: 0 -} - -.dropend .dropdown-menu[data-bs-popper] { - top: 0; - right: auto; - left: 100%; - margin-top: 0; - margin-left: var(--bs-dropdown-spacer) -} - -.dropend .dropdown-toggle::after { - display: inline-block; - margin-left: .255em; - vertical-align: .255em; - content: ""; - border-top: .3em solid transparent; - border-right: 0; - border-bottom: .3em solid transparent; - border-left: .3em solid -} - -.dropend .dropdown-toggle:empty::after { - margin-left: 0 -} - -.dropend .dropdown-toggle::after { - vertical-align: 0 -} - -.dropstart .dropdown-menu[data-bs-popper] { - top: 0; - right: 100%; - left: auto; - margin-top: 0; - margin-right: var(--bs-dropdown-spacer) -} - -.dropstart .dropdown-toggle::after { - display: inline-block; - margin-left: .255em; - vertical-align: .255em; - content: "" -} - -.dropstart .dropdown-toggle::after { - display: none -} - -.dropstart .dropdown-toggle::before { - display: inline-block; - margin-right: .255em; - vertical-align: .255em; - content: ""; - border-top: .3em solid transparent; - border-right: .3em solid; - border-bottom: .3em solid transparent -} - -.dropstart .dropdown-toggle:empty::after { - margin-left: 0 -} - -.dropstart .dropdown-toggle::before { - vertical-align: 0 -} - -.dropdown-divider { - height: 0; - margin: var(--bs-dropdown-divider-margin-y) 0; - overflow: hidden; - border-top: 1px solid var(--bs-dropdown-divider-bg); - opacity: 1 -} - -.dropdown-item { - display: block; - width: 100%; - padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x); - clear: both; - font-weight: 400; - color: var(--bs-dropdown-link-color); - text-align: inherit; - text-decoration: none; - white-space: nowrap; - background-color: transparent; - border: 0 -} - -.dropdown-item:focus, .dropdown-item:hover { - color: var(--bs-dropdown-link-hover-color); - background-color: var(--bs-dropdown-link-hover-bg) -} - -.dropdown-item.active, .dropdown-item:active { - color: var(--bs-dropdown-link-active-color); - text-decoration: none; - background-color: var(--bs-dropdown-link-active-bg) -} - -.dropdown-item.disabled, .dropdown-item:disabled { - color: var(--bs-dropdown-link-disabled-color); - pointer-events: none; - background-color: transparent -} - -.dropdown-menu.show { - display: block -} - -.dropdown-header { - display: block; - padding: var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x); - margin-bottom: 0; - font-size: .875rem; - color: var(--bs-dropdown-header-color); - white-space: nowrap -} - -.dropdown-item-text { - display: block; - padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x); - color: var(--bs-dropdown-link-color) -} - -.dropdown-menu-dark { - --bs-dropdown-color: #dee2e6; - --bs-dropdown-bg: #303030; - --bs-dropdown-border-color: #444; - --bs-dropdown-box-shadow: ; - --bs-dropdown-link-color: #dee2e6; - --bs-dropdown-link-hover-color: #fff; - --bs-dropdown-divider-bg: #444; - --bs-dropdown-link-hover-bg: rgba(255, 255, 255, 0.15); - --bs-dropdown-link-active-color: #fff; - --bs-dropdown-link-active-bg: #375a7f; - --bs-dropdown-link-disabled-color: #adb5bd; - --bs-dropdown-header-color: #adb5bd -} - -.btn-group, .btn-group-vertical { - position: relative; - display: inline-flex; - vertical-align: middle -} - -.btn-group-vertical > .btn, .btn-group > .btn { - position: relative; - flex: 1 1 auto -} - -.btn-group-vertical > .btn-check:checked + .btn, .btn-group-vertical > .btn-check:focus + .btn, .btn-group-vertical > .btn.active, .btn-group-vertical > .btn:active, .btn-group-vertical > .btn:focus, .btn-group-vertical > .btn:hover, .btn-group > .btn-check:checked + .btn, .btn-group > .btn-check:focus + .btn, .btn-group > .btn.active, .btn-group > .btn:active, .btn-group > .btn:focus, .btn-group > .btn:hover { - z-index: 1 -} - -.btn-toolbar { - display: flex; - flex-wrap: wrap; - justify-content: flex-start -} - -.btn-toolbar .input-group { - width: auto -} - -.btn-group { - border-radius: .375rem -} - -.btn-group > .btn-group:not(:first-child), .btn-group > .btn:not(:first-child) { - margin-left: -1px -} - -.btn-group > .btn-group:not(:last-child) > .btn, .btn-group > .btn.dropdown-toggle-split:first-child, .btn-group > .btn:not(:last-child):not(.dropdown-toggle) { - border-top-right-radius: 0; - border-bottom-right-radius: 0 -} - -.btn-group > .btn-group:not(:first-child) > .btn, .btn-group > .btn:nth-child(n+3), .btn-group > :not(.btn-check) + .btn { - border-top-left-radius: 0; - border-bottom-left-radius: 0 -} - -.dropdown-toggle-split { - padding-right: .5625rem; - padding-left: .5625rem -} - -.dropdown-toggle-split::after, .dropend .dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after { - margin-left: 0 -} - -.dropstart .dropdown-toggle-split::before { - margin-right: 0 -} - -.btn-group-sm > .btn + .dropdown-toggle-split, .btn-sm + .dropdown-toggle-split { - padding-right: .375rem; - padding-left: .375rem -} - -.btn-group-lg > .btn + .dropdown-toggle-split, .btn-lg + .dropdown-toggle-split { - padding-right: .75rem; - padding-left: .75rem -} - -.btn-group-vertical { - flex-direction: column; - align-items: flex-start; - justify-content: center -} - -.btn-group-vertical > .btn, .btn-group-vertical > .btn-group { - width: 100% -} - -.btn-group-vertical > .btn-group:not(:first-child), .btn-group-vertical > .btn:not(:first-child) { - margin-top: -1px -} - -.btn-group-vertical > .btn-group:not(:last-child) > .btn, .btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle) { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0 -} - -.btn-group-vertical > .btn-group:not(:first-child) > .btn, .btn-group-vertical > .btn ~ .btn { - border-top-left-radius: 0; - border-top-right-radius: 0 -} - -.nav { - --bs-nav-link-padding-x: 2rem; - --bs-nav-link-padding-y: 0.5rem; - --bs-nav-link-font-weight: ; - --bs-nav-link-color: var(--bs-link-color); - --bs-nav-link-hover-color: var(--bs-link-hover-color); - --bs-nav-link-disabled-color: #adb5bd; - display: flex; - flex-wrap: wrap; - padding-left: 0; - margin-bottom: 0; - list-style: none -} - -.nav-link { - display: block; - padding: var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x); - font-size: var(--bs-nav-link-font-size); - font-weight: var(--bs-nav-link-font-weight); - color: var(--bs-nav-link-color); - text-decoration: none; - transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out -} - -@media (prefers-reduced-motion: reduce) { - .nav-link { - transition: none - } -} - -.nav-link:focus, .nav-link:hover { - color: var(--bs-nav-link-hover-color) -} - -.nav-link.disabled { - color: var(--bs-nav-link-disabled-color); - pointer-events: none; - cursor: default -} - -.nav-tabs { - --bs-nav-tabs-border-width: 1px; - --bs-nav-tabs-border-color: #444; - --bs-nav-tabs-border-radius: 0.375rem; - --bs-nav-tabs-link-hover-border-color: #444 #444 transparent; - --bs-nav-tabs-link-active-color: #fff; - --bs-nav-tabs-link-active-bg: #222; - --bs-nav-tabs-link-active-border-color: #444 #444 transparent; - border-bottom: var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color) -} - -.nav-tabs .nav-link { - margin-bottom: calc(var(--bs-nav-tabs-border-width) * -1); - background: 0 0; - border: var(--bs-nav-tabs-border-width) solid transparent; - border-top-left-radius: var(--bs-nav-tabs-border-radius); - border-top-right-radius: var(--bs-nav-tabs-border-radius) -} - -.nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover { - isolation: isolate; - border-color: var(--bs-nav-tabs-link-hover-border-color) -} - -.nav-tabs .nav-link.disabled, .nav-tabs .nav-link:disabled { - color: var(--bs-nav-link-disabled-color); - background-color: transparent; - border-color: transparent -} - -.nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active { - color: var(--bs-nav-tabs-link-active-color); - background-color: var(--bs-nav-tabs-link-active-bg); - border-color: var(--bs-nav-tabs-link-active-border-color) -} - -.nav-tabs .dropdown-menu { - margin-top: calc(var(--bs-nav-tabs-border-width) * -1); - border-top-left-radius: 0; - border-top-right-radius: 0 -} - -.nav-pills { - --bs-nav-pills-border-radius: 0.375rem; - --bs-nav-pills-link-active-color: #fff; - --bs-nav-pills-link-active-bg: #375a7f -} - -.nav-pills .nav-link { - background: 0 0; - border: 0; - border-radius: var(--bs-nav-pills-border-radius) -} - -.nav-pills .nav-link:disabled { - color: var(--bs-nav-link-disabled-color); - background-color: transparent; - border-color: transparent -} - -.nav-pills .nav-link.active, .nav-pills .show > .nav-link { - color: var(--bs-nav-pills-link-active-color); - background-color: var(--bs-nav-pills-link-active-bg) -} - -.nav-fill .nav-item, .nav-fill > .nav-link { - flex: 1 1 auto; - text-align: center -} - -.nav-justified .nav-item, .nav-justified > .nav-link { - flex-basis: 0; - flex-grow: 1; - text-align: center -} - -.nav-fill .nav-item .nav-link, .nav-justified .nav-item .nav-link { - width: 100% -} - -.tab-content > .tab-pane { - display: none -} - -.tab-content > .active { - display: block -} - -.navbar { - --bs-navbar-padding-x: 0; - --bs-navbar-padding-y: 1rem; - --bs-navbar-color: rgba(34, 34, 34, 0.7); - --bs-navbar-hover-color: #222; - --bs-navbar-disabled-color: rgba(0, 0, 0, 0.3); - --bs-navbar-active-color: #222; - --bs-navbar-brand-padding-y: 0.3125rem; - --bs-navbar-brand-margin-end: 1rem; - --bs-navbar-brand-font-size: 1.25rem; - --bs-navbar-brand-color: #222; - --bs-navbar-brand-hover-color: #222; - --bs-navbar-nav-link-padding-x: 0.5rem; - --bs-navbar-toggler-padding-y: 0.25rem; - --bs-navbar-toggler-padding-x: 0.75rem; - --bs-navbar-toggler-font-size: 1.25rem; - --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2834, 34, 34, 0.7%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); - --bs-navbar-toggler-border-color: rgba(34, 34, 34, 0.1); - --bs-navbar-toggler-border-radius: 0.375rem; - --bs-navbar-toggler-focus-width: 0.25rem; - --bs-navbar-toggler-transition: box-shadow 0.15s ease-in-out; - position: relative; - display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: space-between; - padding: var(--bs-navbar-padding-y) var(--bs-navbar-padding-x) -} - -.navbar > .container, .navbar > .container-fluid, .navbar > .container-lg, .navbar > .container-md, .navbar > .container-sm, .navbar > .container-xl, .navbar > .container-xxl { - display: flex; - flex-wrap: inherit; - align-items: center; - justify-content: space-between -} - -.navbar-brand { - padding-top: var(--bs-navbar-brand-padding-y); - padding-bottom: var(--bs-navbar-brand-padding-y); - margin-right: var(--bs-navbar-brand-margin-end); - font-size: var(--bs-navbar-brand-font-size); - color: var(--bs-navbar-brand-color); - text-decoration: none; - white-space: nowrap -} - -.navbar-brand:focus, .navbar-brand:hover { - color: var(--bs-navbar-brand-hover-color) -} - -.navbar-nav { - --bs-nav-link-padding-x: 0; - --bs-nav-link-padding-y: 0.5rem; - --bs-nav-link-font-weight: ; - --bs-nav-link-color: var(--bs-navbar-color); - --bs-nav-link-hover-color: var(--bs-navbar-hover-color); - --bs-nav-link-disabled-color: var(--bs-navbar-disabled-color); - display: flex; - flex-direction: column; - padding-left: 0; - margin-bottom: 0; - list-style: none -} - -.navbar-nav .nav-link.active, .navbar-nav .show > .nav-link { - color: var(--bs-navbar-active-color) -} - -.navbar-nav .dropdown-menu { - position: static -} - -.navbar-text { - padding-top: .5rem; - padding-bottom: .5rem; - color: var(--bs-navbar-color) -} - -.navbar-text a, .navbar-text a:focus, .navbar-text a:hover { - color: var(--bs-navbar-active-color) -} - -.navbar-collapse { - flex-basis: 100%; - flex-grow: 1; - align-items: center -} - -.navbar-toggler { - padding: var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x); - font-size: var(--bs-navbar-toggler-font-size); - line-height: 1; - color: var(--bs-navbar-color); - background-color: transparent; - border: var(--bs-border-width) solid var(--bs-navbar-toggler-border-color); - border-radius: var(--bs-navbar-toggler-border-radius); - transition: var(--bs-navbar-toggler-transition) -} - -@media (prefers-reduced-motion: reduce) { - .navbar-toggler { - transition: none - } -} - -.navbar-toggler:hover { - text-decoration: none -} - -.navbar-toggler:focus { - text-decoration: none; - outline: 0; - box-shadow: 0 0 0 var(--bs-navbar-toggler-focus-width) -} - -.navbar-toggler-icon { - display: inline-block; - width: 1.5em; - height: 1.5em; - vertical-align: middle; - background-image: var(--bs-navbar-toggler-icon-bg); - background-repeat: no-repeat; - background-position: center; - background-size: 100% -} - -.navbar-nav-scroll { - max-height: var(--bs-scroll-height, 75vh); - overflow-y: auto -} - -@media (min-width: 576px) { - .navbar-expand-sm { - flex-wrap: nowrap; - justify-content: flex-start - } - - .navbar-expand-sm .navbar-nav { - flex-direction: row - } - - .navbar-expand-sm .navbar-nav .dropdown-menu { - position: absolute - } - - .navbar-expand-sm .navbar-nav .nav-link { - padding-right: var(--bs-navbar-nav-link-padding-x); - padding-left: var(--bs-navbar-nav-link-padding-x) - } - - .navbar-expand-sm .navbar-nav-scroll { - overflow: visible - } - - .navbar-expand-sm .navbar-collapse { - display: flex !important; - flex-basis: auto - } - - .navbar-expand-sm .navbar-toggler { - display: none - } - - .navbar-expand-sm .offcanvas { - position: static; - z-index: auto; - flex-grow: 1; - width: auto !important; - height: auto !important; - visibility: visible !important; - background-color: transparent !important; - border: 0 !important; - transform: none !important; - transition: none - } - - .navbar-expand-sm .offcanvas .offcanvas-header { - display: none - } - - .navbar-expand-sm .offcanvas .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible - } -} - -@media (min-width: 768px) { - .navbar-expand-md { - flex-wrap: nowrap; - justify-content: flex-start - } - - .navbar-expand-md .navbar-nav { - flex-direction: row - } - - .navbar-expand-md .navbar-nav .dropdown-menu { - position: absolute - } - - .navbar-expand-md .navbar-nav .nav-link { - padding-right: var(--bs-navbar-nav-link-padding-x); - padding-left: var(--bs-navbar-nav-link-padding-x) - } - - .navbar-expand-md .navbar-nav-scroll { - overflow: visible - } - - .navbar-expand-md .navbar-collapse { - display: flex !important; - flex-basis: auto - } - - .navbar-expand-md .navbar-toggler { - display: none - } - - .navbar-expand-md .offcanvas { - position: static; - z-index: auto; - flex-grow: 1; - width: auto !important; - height: auto !important; - visibility: visible !important; - background-color: transparent !important; - border: 0 !important; - transform: none !important; - transition: none - } - - .navbar-expand-md .offcanvas .offcanvas-header { - display: none - } - - .navbar-expand-md .offcanvas .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible - } -} - -@media (min-width: 992px) { - .navbar-expand-lg { - flex-wrap: nowrap; - justify-content: flex-start - } - - .navbar-expand-lg .navbar-nav { - flex-direction: row - } - - .navbar-expand-lg .navbar-nav .dropdown-menu { - position: absolute - } - - .navbar-expand-lg .navbar-nav .nav-link { - padding-right: var(--bs-navbar-nav-link-padding-x); - padding-left: var(--bs-navbar-nav-link-padding-x) - } - - .navbar-expand-lg .navbar-nav-scroll { - overflow: visible - } - - .navbar-expand-lg .navbar-collapse { - display: flex !important; - flex-basis: auto - } - - .navbar-expand-lg .navbar-toggler { - display: none - } - - .navbar-expand-lg .offcanvas { - position: static; - z-index: auto; - flex-grow: 1; - width: auto !important; - height: auto !important; - visibility: visible !important; - background-color: transparent !important; - border: 0 !important; - transform: none !important; - transition: none - } - - .navbar-expand-lg .offcanvas .offcanvas-header { - display: none - } - - .navbar-expand-lg .offcanvas .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible - } -} - -@media (min-width: 1200px) { - .navbar-expand-xl { - flex-wrap: nowrap; - justify-content: flex-start - } - - .navbar-expand-xl .navbar-nav { - flex-direction: row - } - - .navbar-expand-xl .navbar-nav .dropdown-menu { - position: absolute - } - - .navbar-expand-xl .navbar-nav .nav-link { - padding-right: var(--bs-navbar-nav-link-padding-x); - padding-left: var(--bs-navbar-nav-link-padding-x) - } - - .navbar-expand-xl .navbar-nav-scroll { - overflow: visible - } - - .navbar-expand-xl .navbar-collapse { - display: flex !important; - flex-basis: auto - } - - .navbar-expand-xl .navbar-toggler { - display: none - } - - .navbar-expand-xl .offcanvas { - position: static; - z-index: auto; - flex-grow: 1; - width: auto !important; - height: auto !important; - visibility: visible !important; - background-color: transparent !important; - border: 0 !important; - transform: none !important; - transition: none - } - - .navbar-expand-xl .offcanvas .offcanvas-header { - display: none - } - - .navbar-expand-xl .offcanvas .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible - } -} - -@media (min-width: 1400px) { - .navbar-expand-xxl { - flex-wrap: nowrap; - justify-content: flex-start - } - - .navbar-expand-xxl .navbar-nav { - flex-direction: row - } - - .navbar-expand-xxl .navbar-nav .dropdown-menu { - position: absolute - } - - .navbar-expand-xxl .navbar-nav .nav-link { - padding-right: var(--bs-navbar-nav-link-padding-x); - padding-left: var(--bs-navbar-nav-link-padding-x) - } - - .navbar-expand-xxl .navbar-nav-scroll { - overflow: visible - } - - .navbar-expand-xxl .navbar-collapse { - display: flex !important; - flex-basis: auto - } - - .navbar-expand-xxl .navbar-toggler { - display: none - } - - .navbar-expand-xxl .offcanvas { - position: static; - z-index: auto; - flex-grow: 1; - width: auto !important; - height: auto !important; - visibility: visible !important; - background-color: transparent !important; - border: 0 !important; - transform: none !important; - transition: none - } - - .navbar-expand-xxl .offcanvas .offcanvas-header { - display: none - } - - .navbar-expand-xxl .offcanvas .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible - } -} - -.navbar-expand { - flex-wrap: nowrap; - justify-content: flex-start -} - -.navbar-expand .navbar-nav { - flex-direction: row -} - -.navbar-expand .navbar-nav .dropdown-menu { - position: absolute -} - -.navbar-expand .navbar-nav .nav-link { - padding-right: var(--bs-navbar-nav-link-padding-x); - padding-left: var(--bs-navbar-nav-link-padding-x) -} - -.navbar-expand .navbar-nav-scroll { - overflow: visible -} - -.navbar-expand .navbar-collapse { - display: flex !important; - flex-basis: auto -} - -.navbar-expand .navbar-toggler { - display: none -} - -.navbar-expand .offcanvas { - position: static; - z-index: auto; - flex-grow: 1; - width: auto !important; - height: auto !important; - visibility: visible !important; - background-color: transparent !important; - border: 0 !important; - transform: none !important; - transition: none -} - -.navbar-expand .offcanvas .offcanvas-header { - display: none -} - -.navbar-expand .offcanvas .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible -} - -.navbar-dark { - --bs-navbar-color: rgba(255, 255, 255, 0.6); - --bs-navbar-hover-color: #fff; - --bs-navbar-disabled-color: rgba(255, 255, 255, 0.25); - --bs-navbar-active-color: #fff; - --bs-navbar-brand-color: #fff; - --bs-navbar-brand-hover-color: #fff; - --bs-navbar-toggler-border-color: rgba(255, 255, 255, 0.1); - --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.6%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") -} - -.card { - --bs-card-spacer-y: 1rem; - --bs-card-spacer-x: 1rem; - --bs-card-title-spacer-y: 0.5rem; - --bs-card-border-width: 1px; - --bs-card-border-color: var(--bs-border-color-translucent); - --bs-card-border-radius: 0.375rem; - --bs-card-box-shadow: ; - --bs-card-inner-border-radius: calc(0.375rem - 1px); - --bs-card-cap-padding-y: 0.5rem; - --bs-card-cap-padding-x: 1rem; - --bs-card-cap-bg: #444; - --bs-card-cap-color: ; - --bs-card-height: ; - --bs-card-color: ; - --bs-card-bg: #303030; - --bs-card-img-overlay-padding: 1rem; - --bs-card-group-margin: 0.75rem; - position: relative; - display: flex; - flex-direction: column; - min-width: 0; - height: var(--bs-card-height); - word-wrap: break-word; - background-color: var(--bs-card-bg); - background-clip: border-box; - border: var(--bs-card-border-width) solid var(--bs-card-border-color); - border-radius: var(--bs-card-border-radius) -} - -.card > hr { - margin-right: 0; - margin-left: 0 -} - -.card > .list-group { - border-top: inherit; - border-bottom: inherit -} - -.card > .list-group:first-child { - border-top-width: 0; - border-top-left-radius: var(--bs-card-inner-border-radius); - border-top-right-radius: var(--bs-card-inner-border-radius) -} - -.card > .list-group:last-child { - border-bottom-width: 0; - border-bottom-right-radius: var(--bs-card-inner-border-radius); - border-bottom-left-radius: var(--bs-card-inner-border-radius) -} - -.card > .card-header + .list-group, .card > .list-group + .card-footer { - border-top: 0 -} - -.card-body { - flex: 1 1 auto; - padding: var(--bs-card-spacer-y) var(--bs-card-spacer-x); - color: var(--bs-card-color) -} - -.card-title { - margin-bottom: var(--bs-card-title-spacer-y) -} - -.card-subtitle { - margin-top: calc(-.5 * var(--bs-card-title-spacer-y)); - margin-bottom: 0 -} - -.card-text:last-child { - margin-bottom: 0 -} - -.card-link + .card-link { - margin-left: var(--bs-card-spacer-x) -} - -.card-header { - padding: var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x); - margin-bottom: 0; - color: var(--bs-card-cap-color); - background-color: var(--bs-card-cap-bg); - border-bottom: var(--bs-card-border-width) solid var(--bs-card-border-color) -} - -.card-header:first-child { - border-radius: var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0 -} - -.card-footer { - padding: var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x); - color: var(--bs-card-cap-color); - background-color: var(--bs-card-cap-bg); - border-top: var(--bs-card-border-width) solid var(--bs-card-border-color) -} - -.card-footer:last-child { - border-radius: 0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) -} - -.card-header-tabs { - margin-right: calc(-.5 * var(--bs-card-cap-padding-x)); - margin-bottom: calc(-1 * var(--bs-card-cap-padding-y)); - margin-left: calc(-.5 * var(--bs-card-cap-padding-x)); - border-bottom: 0 -} - -.card-header-tabs .nav-link.active { - background-color: var(--bs-card-bg); - border-bottom-color: var(--bs-card-bg) -} - -.card-header-pills { - margin-right: calc(-.5 * var(--bs-card-cap-padding-x)); - margin-left: calc(-.5 * var(--bs-card-cap-padding-x)) -} - -.card-img-overlay { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - padding: var(--bs-card-img-overlay-padding); - border-radius: var(--bs-card-inner-border-radius) -} - -.card-img, .card-img-bottom, .card-img-top { - width: 100% -} - -.card-img, .card-img-top { - border-top-left-radius: var(--bs-card-inner-border-radius); - border-top-right-radius: var(--bs-card-inner-border-radius) -} - -.card-img, .card-img-bottom { - border-bottom-right-radius: var(--bs-card-inner-border-radius); - border-bottom-left-radius: var(--bs-card-inner-border-radius) -} - -.card-group > .card { - margin-bottom: var(--bs-card-group-margin) -} - -@media (min-width: 576px) { - .card-group { - display: flex; - flex-flow: row wrap - } - - .card-group > .card { - flex: 1 0 0%; - margin-bottom: 0 - } - - .card-group > .card + .card { - margin-left: 0; - border-left: 0 - } - - .card-group > .card:not(:last-child) { - border-top-right-radius: 0; - border-bottom-right-radius: 0 - } - - .card-group > .card:not(:last-child) .card-header, .card-group > .card:not(:last-child) .card-img-top { - border-top-right-radius: 0 - } - - .card-group > .card:not(:last-child) .card-footer, .card-group > .card:not(:last-child) .card-img-bottom { - border-bottom-right-radius: 0 - } - - .card-group > .card:not(:first-child) { - border-top-left-radius: 0; - border-bottom-left-radius: 0 - } - - .card-group > .card:not(:first-child) .card-header, .card-group > .card:not(:first-child) .card-img-top { - border-top-left-radius: 0 - } - - .card-group > .card:not(:first-child) .card-footer, .card-group > .card:not(:first-child) .card-img-bottom { - border-bottom-left-radius: 0 - } -} - -.accordion { - --bs-accordion-color: #fff; - --bs-accordion-bg: #222; - --bs-accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease; - --bs-accordion-border-color: var(--bs-border-color); - --bs-accordion-border-width: 1px; - --bs-accordion-border-radius: 0.375rem; - --bs-accordion-inner-border-radius: calc(0.375rem - 1px); - --bs-accordion-btn-padding-x: 1.25rem; - --bs-accordion-btn-padding-y: 1rem; - --bs-accordion-btn-color: var(--bs-body-color); - --bs-accordion-btn-bg: var(--bs-accordion-bg); - --bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='var%28--bs-body-color%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); - --bs-accordion-btn-icon-width: 1.25rem; - --bs-accordion-btn-icon-transform: rotate(-180deg); - --bs-accordion-btn-icon-transition: transform 0.2s ease-in-out; - --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23325172'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); - --bs-accordion-btn-focus-border-color: #9badbf; - --bs-accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(55, 90, 127, 0.25); - --bs-accordion-body-padding-x: 1.25rem; - --bs-accordion-body-padding-y: 1rem; - --bs-accordion-active-color: #325172; - --bs-accordion-active-bg: #ebeff2 -} - -.accordion-button { - position: relative; - display: flex; - align-items: center; - width: 100%; - padding: var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x); - font-size: 1rem; - color: var(--bs-accordion-btn-color); - text-align: left; - background-color: var(--bs-accordion-btn-bg); - border: 0; - border-radius: 0; - overflow-anchor: none; - transition: var(--bs-accordion-transition) -} - -@media (prefers-reduced-motion: reduce) { - .accordion-button { - transition: none - } -} - -.accordion-button:not(.collapsed) { - color: var(--bs-accordion-active-color); - background-color: var(--bs-accordion-active-bg); - box-shadow: inset 0 calc(var(--bs-accordion-border-width) * -1) 0 var(--bs-accordion-border-color) -} - -.accordion-button:not(.collapsed)::after { - background-image: var(--bs-accordion-btn-active-icon); - transform: var(--bs-accordion-btn-icon-transform) -} - -.accordion-button::after { - flex-shrink: 0; - width: var(--bs-accordion-btn-icon-width); - height: var(--bs-accordion-btn-icon-width); - margin-left: auto; - content: ""; - background-image: var(--bs-accordion-btn-icon); - background-repeat: no-repeat; - background-size: var(--bs-accordion-btn-icon-width); - transition: var(--bs-accordion-btn-icon-transition) -} - -@media (prefers-reduced-motion: reduce) { - .accordion-button::after { - transition: none - } -} - -.accordion-button:hover { - z-index: 2 -} - -.accordion-button:focus { - z-index: 3; - border-color: var(--bs-accordion-btn-focus-border-color); - outline: 0; - box-shadow: var(--bs-accordion-btn-focus-box-shadow) -} - -.accordion-header { - margin-bottom: 0 -} - -.accordion-item { - color: var(--bs-accordion-color); - background-color: var(--bs-accordion-bg); - border: var(--bs-accordion-border-width) solid var(--bs-accordion-border-color) -} - -.accordion-item:first-of-type { - border-top-left-radius: var(--bs-accordion-border-radius); - border-top-right-radius: var(--bs-accordion-border-radius) -} - -.accordion-item:first-of-type .accordion-button { - border-top-left-radius: var(--bs-accordion-inner-border-radius); - border-top-right-radius: var(--bs-accordion-inner-border-radius) -} - -.accordion-item:not(:first-of-type) { - border-top: 0 -} - -.accordion-item:last-of-type { - border-bottom-right-radius: var(--bs-accordion-border-radius); - border-bottom-left-radius: var(--bs-accordion-border-radius) -} - -.accordion-item:last-of-type .accordion-button.collapsed { - border-bottom-right-radius: var(--bs-accordion-inner-border-radius); - border-bottom-left-radius: var(--bs-accordion-inner-border-radius) -} - -.accordion-item:last-of-type .accordion-collapse { - border-bottom-right-radius: var(--bs-accordion-border-radius); - border-bottom-left-radius: var(--bs-accordion-border-radius) -} - -.accordion-body { - padding: var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x) -} - -.accordion-flush .accordion-collapse { - border-width: 0 -} - -.accordion-flush .accordion-item { - border-right: 0; - border-left: 0; - border-radius: 0 -} - -.accordion-flush .accordion-item:first-child { - border-top: 0 -} - -.accordion-flush .accordion-item:last-child { - border-bottom: 0 -} - -.accordion-flush .accordion-item .accordion-button { - border-radius: 0 -} - -.breadcrumb { - --bs-breadcrumb-padding-x: 0.75rem; - --bs-breadcrumb-padding-y: 0.375rem; - --bs-breadcrumb-margin-bottom: 1rem; - --bs-breadcrumb-bg: #444; - --bs-breadcrumb-border-radius: 0.25rem; - --bs-breadcrumb-divider-color: #888; - --bs-breadcrumb-item-padding-x: 0.5rem; - --bs-breadcrumb-item-active-color: #888; - display: flex; - flex-wrap: wrap; - padding: var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x); - margin-bottom: var(--bs-breadcrumb-margin-bottom); - font-size: var(--bs-breadcrumb-font-size); - list-style: none; - background-color: var(--bs-breadcrumb-bg); - border-radius: var(--bs-breadcrumb-border-radius) -} - -.breadcrumb-item + .breadcrumb-item { - padding-left: var(--bs-breadcrumb-item-padding-x) -} - -.breadcrumb-item + .breadcrumb-item::before { - float: left; - padding-right: var(--bs-breadcrumb-item-padding-x); - color: var(--bs-breadcrumb-divider-color); - content: var(--bs-breadcrumb-divider, "/") -} - -.breadcrumb-item.active { - color: var(--bs-breadcrumb-item-active-color) -} - -.pagination { - --bs-pagination-padding-x: 0.75rem; - --bs-pagination-padding-y: 0.375rem; - --bs-pagination-font-size: 1rem; - --bs-pagination-color: #fff; - --bs-pagination-bg: #00bc8c; - --bs-pagination-border-width: 0; - --bs-pagination-border-color: transparent; - --bs-pagination-border-radius: 0.375rem; - --bs-pagination-hover-color: #fff; - --bs-pagination-hover-bg: #00efb2; - --bs-pagination-hover-border-color: transparent; - --bs-pagination-focus-color: var(--bs-link-hover-color); - --bs-pagination-focus-bg: #ebebeb; - --bs-pagination-focus-box-shadow: 0 0 0 0.25rem rgba(55, 90, 127, 0.25); - --bs-pagination-active-color: #fff; - --bs-pagination-active-bg: #00efb2; - --bs-pagination-active-border-color: transparent; - --bs-pagination-disabled-color: #fff; - --bs-pagination-disabled-bg: #007053; - --bs-pagination-disabled-border-color: transparent; - display: flex; - padding-left: 0; - list-style: none -} - -.page-link { - position: relative; - display: block; - padding: var(--bs-pagination-padding-y) var(--bs-pagination-padding-x); - font-size: var(--bs-pagination-font-size); - color: var(--bs-pagination-color); - text-decoration: none; - background-color: var(--bs-pagination-bg); - border: var(--bs-pagination-border-width) solid var(--bs-pagination-border-color); - transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out -} - -@media (prefers-reduced-motion: reduce) { - .page-link { - transition: none - } -} - -.page-link:hover { - z-index: 2; - color: var(--bs-pagination-hover-color); - background-color: var(--bs-pagination-hover-bg); - border-color: var(--bs-pagination-hover-border-color) -} - -.page-link:focus { - z-index: 3; - color: var(--bs-pagination-focus-color); - background-color: var(--bs-pagination-focus-bg); - outline: 0; - box-shadow: var(--bs-pagination-focus-box-shadow) -} - -.active > .page-link, .page-link.active { - z-index: 3; - color: var(--bs-pagination-active-color); - background-color: var(--bs-pagination-active-bg); - border-color: var(--bs-pagination-active-border-color) -} - -.disabled > .page-link, .page-link.disabled { - color: var(--bs-pagination-disabled-color); - pointer-events: none; - background-color: var(--bs-pagination-disabled-bg); - border-color: var(--bs-pagination-disabled-border-color) -} - -.page-item:not(:first-child) .page-link { - margin-left: 0 -} - -.page-item:first-child .page-link { - border-top-left-radius: var(--bs-pagination-border-radius); - border-bottom-left-radius: var(--bs-pagination-border-radius) -} - -.page-item:last-child .page-link { - border-top-right-radius: var(--bs-pagination-border-radius); - border-bottom-right-radius: var(--bs-pagination-border-radius) -} - -.pagination-lg { - --bs-pagination-padding-x: 1.5rem; - --bs-pagination-padding-y: 0.75rem; - --bs-pagination-font-size: 1.25rem; - --bs-pagination-border-radius: 0.5rem -} - -.pagination-sm { - --bs-pagination-padding-x: 0.5rem; - --bs-pagination-padding-y: 0.25rem; - --bs-pagination-font-size: 0.875rem; - --bs-pagination-border-radius: 0.25rem -} - -.badge { - --bs-badge-padding-x: 0.65em; - --bs-badge-padding-y: 0.35em; - --bs-badge-font-size: 0.75em; - --bs-badge-font-weight: 700; - --bs-badge-color: #fff; - --bs-badge-border-radius: 0.375rem; - display: inline-block; - padding: var(--bs-badge-padding-y) var(--bs-badge-padding-x); - font-size: var(--bs-badge-font-size); - font-weight: var(--bs-badge-font-weight); - line-height: 1; - color: var(--bs-badge-color); - text-align: center; - white-space: nowrap; - vertical-align: baseline; - border-radius: var(--bs-badge-border-radius) -} - -.badge:empty { - display: none -} - -.btn .badge { - position: relative; - top: -1px -} - -.alert { - --bs-alert-bg: transparent; - --bs-alert-padding-x: 1rem; - --bs-alert-padding-y: 1rem; - --bs-alert-margin-bottom: 1rem; - --bs-alert-color: inherit; - --bs-alert-border-color: transparent; - --bs-alert-border: 1px solid var(--bs-alert-border-color); - --bs-alert-border-radius: 0.375rem; - position: relative; - padding: var(--bs-alert-padding-y) var(--bs-alert-padding-x); - margin-bottom: var(--bs-alert-margin-bottom); - color: var(--bs-alert-color); - background-color: var(--bs-alert-bg); - border: var(--bs-alert-border); - border-radius: var(--bs-alert-border-radius) -} - -.alert-heading { - color: inherit -} - -.alert-link { - font-weight: 700 -} - -.alert-dismissible { - padding-right: 3rem -} - -.alert-dismissible .btn-close { - position: absolute; - top: 0; - right: 0; - z-index: 2; - padding: 1.25rem 1rem -} - -.alert-primary { - --bs-alert-color: #21364c; - --bs-alert-bg: #d7dee5; - --bs-alert-border-color: #c3ced9 -} - -.alert-primary .alert-link { - color: #1a2b3d -} - -.alert-secondary { - --bs-alert-color: #292929; - --bs-alert-bg: #dadada; - --bs-alert-border-color: #c7c7c7 -} - -.alert-secondary .alert-link { - color: #212121 -} - -.alert-success { - --bs-alert-color: #007154; - --bs-alert-bg: #ccf2e8; - --bs-alert-border-color: #b3ebdd -} - -.alert-success .alert-link { - color: #005a43 -} - -.alert-info { - --bs-alert-color: #1f5b83; - --bs-alert-bg: #d6eaf8; - --bs-alert-border-color: #c2e0f4 -} - -.alert-info .alert-link { - color: #194969 -} - -.alert-warning { - --bs-alert-color: #925e0b; - --bs-alert-bg: #fdebd0; - --bs-alert-border-color: #fbe1b8 -} - -.alert-warning .alert-link { - color: #754b09 -} - -.alert-danger { - --bs-alert-color: #8b2e24; - --bs-alert-bg: #fadbd8; - --bs-alert-border-color: #f8c9c5 -} - -.alert-danger .alert-link { - color: #6f251d -} - -.alert-light { - --bs-alert-color: #686d71; - --bs-alert-bg: #eff0f2; - --bs-alert-border-color: #e6e9eb -} - -.alert-light .alert-link { - color: #53575a -} - -.alert-dark { - --bs-alert-color: #1d1d1d; - --bs-alert-bg: #d6d6d6; - --bs-alert-border-color: #c1c1c1 -} - -.alert-dark .alert-link { - color: #171717 -} - -@-webkit-keyframes progress-bar-stripes { - 0% { - background-position-x: 1rem - } -} - -@keyframes progress-bar-stripes { - 0% { - background-position-x: 1rem - } -} - -.progress { - --bs-progress-height: 1rem; - --bs-progress-font-size: 0.75rem; - --bs-progress-bg: #444; - --bs-progress-border-radius: 0.375rem; - --bs-progress-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075); - --bs-progress-bar-color: #fff; - --bs-progress-bar-bg: #375a7f; - --bs-progress-bar-transition: width 0.6s ease; - display: flex; - height: var(--bs-progress-height); - overflow: hidden; - font-size: var(--bs-progress-font-size); - background-color: var(--bs-progress-bg); - border-radius: var(--bs-progress-border-radius) -} - -.progress-bar { - display: flex; - flex-direction: column; - justify-content: center; - overflow: hidden; - color: var(--bs-progress-bar-color); - text-align: center; - white-space: nowrap; - background-color: var(--bs-progress-bar-bg); - transition: var(--bs-progress-bar-transition) -} - -@media (prefers-reduced-motion: reduce) { - .progress-bar { - transition: none - } -} - -.progress-bar-striped { - background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); - background-size: var(--bs-progress-height) var(--bs-progress-height) -} - -.progress-bar-animated { - -webkit-animation: 1s linear infinite progress-bar-stripes; - animation: 1s linear infinite progress-bar-stripes -} - -@media (prefers-reduced-motion: reduce) { - .progress-bar-animated { - -webkit-animation: none; - animation: none - } -} - -.list-group { - --bs-list-group-color: #fff; - --bs-list-group-bg: #303030; - --bs-list-group-border-color: #444; - --bs-list-group-border-width: 1px; - --bs-list-group-border-radius: 0.375rem; - --bs-list-group-item-padding-x: 1rem; - --bs-list-group-item-padding-y: 0.5rem; - --bs-list-group-action-color: #444; - --bs-list-group-action-hover-color: #fff; - --bs-list-group-action-hover-bg: #444; - --bs-list-group-action-active-color: #fff; - --bs-list-group-action-active-bg: #222; - --bs-list-group-disabled-color: #888; - --bs-list-group-disabled-bg: #303030; - --bs-list-group-active-color: #fff; - --bs-list-group-active-bg: #375a7f; - --bs-list-group-active-border-color: #375a7f; - display: flex; - flex-direction: column; - padding-left: 0; - margin-bottom: 0; - border-radius: var(--bs-list-group-border-radius) -} - -.list-group-numbered { - list-style-type: none; - counter-reset: section -} - -.list-group-numbered > .list-group-item::before { - content: counters(section, ".") ". "; - counter-increment: section -} - -.list-group-item-action { - width: 100%; - color: var(--bs-list-group-action-color); - text-align: inherit -} - -.list-group-item-action:focus, .list-group-item-action:hover { - z-index: 1; - color: var(--bs-list-group-action-hover-color); - text-decoration: none; - background-color: var(--bs-list-group-action-hover-bg) -} - -.list-group-item-action:active { - color: var(--bs-list-group-action-active-color); - background-color: var(--bs-list-group-action-active-bg) -} - -.list-group-item { - position: relative; - display: block; - padding: var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x); - color: var(--bs-list-group-color); - text-decoration: none; - background-color: var(--bs-list-group-bg); - border: var(--bs-list-group-border-width) solid var(--bs-list-group-border-color) -} - -.list-group-item:first-child { - border-top-left-radius: inherit; - border-top-right-radius: inherit -} - -.list-group-item:last-child { - border-bottom-right-radius: inherit; - border-bottom-left-radius: inherit -} - -.list-group-item.disabled, .list-group-item:disabled { - color: var(--bs-list-group-disabled-color); - pointer-events: none; - background-color: var(--bs-list-group-disabled-bg) -} - -.list-group-item.active { - z-index: 2; - color: var(--bs-list-group-active-color); - background-color: var(--bs-list-group-active-bg); - border-color: var(--bs-list-group-active-border-color) -} - -.list-group-item + .list-group-item { - border-top-width: 0 -} - -.list-group-item + .list-group-item.active { - margin-top: calc(var(--bs-list-group-border-width) * -1); - border-top-width: var(--bs-list-group-border-width) -} - -.list-group-horizontal { - flex-direction: row -} - -.list-group-horizontal > .list-group-item:first-child { - border-bottom-left-radius: var(--bs-list-group-border-radius); - border-top-right-radius: 0 -} - -.list-group-horizontal > .list-group-item:last-child { - border-top-right-radius: var(--bs-list-group-border-radius); - border-bottom-left-radius: 0 -} - -.list-group-horizontal > .list-group-item.active { - margin-top: 0 -} - -.list-group-horizontal > .list-group-item + .list-group-item { - border-top-width: var(--bs-list-group-border-width); - border-left-width: 0 -} - -.list-group-horizontal > .list-group-item + .list-group-item.active { - margin-left: calc(var(--bs-list-group-border-width) * -1); - border-left-width: var(--bs-list-group-border-width) -} - -@media (min-width: 576px) { - .list-group-horizontal-sm { - flex-direction: row - } - - .list-group-horizontal-sm > .list-group-item:first-child { - border-bottom-left-radius: var(--bs-list-group-border-radius); - border-top-right-radius: 0 - } - - .list-group-horizontal-sm > .list-group-item:last-child { - border-top-right-radius: var(--bs-list-group-border-radius); - border-bottom-left-radius: 0 - } - - .list-group-horizontal-sm > .list-group-item.active { - margin-top: 0 - } - - .list-group-horizontal-sm > .list-group-item + .list-group-item { - border-top-width: var(--bs-list-group-border-width); - border-left-width: 0 - } - - .list-group-horizontal-sm > .list-group-item + .list-group-item.active { - margin-left: calc(var(--bs-list-group-border-width) * -1); - border-left-width: var(--bs-list-group-border-width) - } -} - -@media (min-width: 768px) { - .list-group-horizontal-md { - flex-direction: row - } - - .list-group-horizontal-md > .list-group-item:first-child { - border-bottom-left-radius: var(--bs-list-group-border-radius); - border-top-right-radius: 0 - } - - .list-group-horizontal-md > .list-group-item:last-child { - border-top-right-radius: var(--bs-list-group-border-radius); - border-bottom-left-radius: 0 - } - - .list-group-horizontal-md > .list-group-item.active { - margin-top: 0 - } - - .list-group-horizontal-md > .list-group-item + .list-group-item { - border-top-width: var(--bs-list-group-border-width); - border-left-width: 0 - } - - .list-group-horizontal-md > .list-group-item + .list-group-item.active { - margin-left: calc(var(--bs-list-group-border-width) * -1); - border-left-width: var(--bs-list-group-border-width) - } -} - -@media (min-width: 992px) { - .list-group-horizontal-lg { - flex-direction: row - } - - .list-group-horizontal-lg > .list-group-item:first-child { - border-bottom-left-radius: var(--bs-list-group-border-radius); - border-top-right-radius: 0 - } - - .list-group-horizontal-lg > .list-group-item:last-child { - border-top-right-radius: var(--bs-list-group-border-radius); - border-bottom-left-radius: 0 - } - - .list-group-horizontal-lg > .list-group-item.active { - margin-top: 0 - } - - .list-group-horizontal-lg > .list-group-item + .list-group-item { - border-top-width: var(--bs-list-group-border-width); - border-left-width: 0 - } - - .list-group-horizontal-lg > .list-group-item + .list-group-item.active { - margin-left: calc(var(--bs-list-group-border-width) * -1); - border-left-width: var(--bs-list-group-border-width) - } -} - -@media (min-width: 1200px) { - .list-group-horizontal-xl { - flex-direction: row - } - - .list-group-horizontal-xl > .list-group-item:first-child { - border-bottom-left-radius: var(--bs-list-group-border-radius); - border-top-right-radius: 0 - } - - .list-group-horizontal-xl > .list-group-item:last-child { - border-top-right-radius: var(--bs-list-group-border-radius); - border-bottom-left-radius: 0 - } - - .list-group-horizontal-xl > .list-group-item.active { - margin-top: 0 - } - - .list-group-horizontal-xl > .list-group-item + .list-group-item { - border-top-width: var(--bs-list-group-border-width); - border-left-width: 0 - } - - .list-group-horizontal-xl > .list-group-item + .list-group-item.active { - margin-left: calc(var(--bs-list-group-border-width) * -1); - border-left-width: var(--bs-list-group-border-width) - } -} - -@media (min-width: 1400px) { - .list-group-horizontal-xxl { - flex-direction: row - } - - .list-group-horizontal-xxl > .list-group-item:first-child { - border-bottom-left-radius: var(--bs-list-group-border-radius); - border-top-right-radius: 0 - } - - .list-group-horizontal-xxl > .list-group-item:last-child { - border-top-right-radius: var(--bs-list-group-border-radius); - border-bottom-left-radius: 0 - } - - .list-group-horizontal-xxl > .list-group-item.active { - margin-top: 0 - } - - .list-group-horizontal-xxl > .list-group-item + .list-group-item { - border-top-width: var(--bs-list-group-border-width); - border-left-width: 0 - } - - .list-group-horizontal-xxl > .list-group-item + .list-group-item.active { - margin-left: calc(var(--bs-list-group-border-width) * -1); - border-left-width: var(--bs-list-group-border-width) - } -} - -.list-group-flush { - border-radius: 0 -} - -.list-group-flush > .list-group-item { - border-width: 0 0 var(--bs-list-group-border-width) -} - -.list-group-flush > .list-group-item:last-child { - border-bottom-width: 0 -} - -.list-group-item-primary { - color: #21364c; - background-color: #d7dee5 -} - -.list-group-item-primary.list-group-item-action:focus, .list-group-item-primary.list-group-item-action:hover { - color: #21364c; - background-color: #c2c8ce -} - -.list-group-item-primary.list-group-item-action.active { - color: #fff; - background-color: #21364c; - border-color: #21364c -} - -.list-group-item-secondary { - color: #292929; - background-color: #dadada -} - -.list-group-item-secondary.list-group-item-action:focus, .list-group-item-secondary.list-group-item-action:hover { - color: #292929; - background-color: #c4c4c4 -} - -.list-group-item-secondary.list-group-item-action.active { - color: #fff; - background-color: #292929; - border-color: #292929 -} - -.list-group-item-success { - color: #007154; - background-color: #ccf2e8 -} - -.list-group-item-success.list-group-item-action:focus, .list-group-item-success.list-group-item-action:hover { - color: #007154; - background-color: #b8dad1 -} - -.list-group-item-success.list-group-item-action.active { - color: #fff; - background-color: #007154; - border-color: #007154 -} - -.list-group-item-info { - color: #1f5b83; - background-color: #d6eaf8 -} - -.list-group-item-info.list-group-item-action:focus, .list-group-item-info.list-group-item-action:hover { - color: #1f5b83; - background-color: #c1d3df -} - -.list-group-item-info.list-group-item-action.active { - color: #fff; - background-color: #1f5b83; - border-color: #1f5b83 -} - -.list-group-item-warning { - color: #925e0b; - background-color: #fdebd0 -} - -.list-group-item-warning.list-group-item-action:focus, .list-group-item-warning.list-group-item-action:hover { - color: #925e0b; - background-color: #e4d4bb -} - -.list-group-item-warning.list-group-item-action.active { - color: #fff; - background-color: #925e0b; - border-color: #925e0b -} - -.list-group-item-danger { - color: #8b2e24; - background-color: #fadbd8 -} - -.list-group-item-danger.list-group-item-action:focus, .list-group-item-danger.list-group-item-action:hover { - color: #8b2e24; - background-color: #e1c5c2 -} - -.list-group-item-danger.list-group-item-action.active { - color: #fff; - background-color: #8b2e24; - border-color: #8b2e24 -} - -.list-group-item-light { - color: #686d71; - background-color: #eff0f2 -} - -.list-group-item-light.list-group-item-action:focus, .list-group-item-light.list-group-item-action:hover { - color: #686d71; - background-color: #d7d8da -} - -.list-group-item-light.list-group-item-action.active { - color: #fff; - background-color: #686d71; - border-color: #686d71 -} - -.list-group-item-dark { - color: #1d1d1d; - background-color: #d6d6d6 -} - -.list-group-item-dark.list-group-item-action:focus, .list-group-item-dark.list-group-item-action:hover { - color: #1d1d1d; - background-color: #c1c1c1 -} - -.list-group-item-dark.list-group-item-action.active { - color: #fff; - background-color: #1d1d1d; - border-color: #1d1d1d -} - -.btn-close { - box-sizing: content-box; - width: 1em; - height: 1em; - padding: .25em .25em; - color: #fff; - background: transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat; - border: 0; - border-radius: .375rem; - opacity: .4 -} - -.btn-close:hover { - color: #fff; - text-decoration: none; - opacity: 1 -} - -.btn-close:focus { - outline: 0; - box-shadow: 0 0 0 .25rem rgba(55, 90, 127, .25); - opacity: 1 -} - -.btn-close.disabled, .btn-close:disabled { - pointer-events: none; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - opacity: .25 -} - -.btn-close-white { - filter: invert(1) grayscale(100%) brightness(200%) -} - -.toast { - --bs-toast-padding-x: 0.75rem; - --bs-toast-padding-y: 0.5rem; - --bs-toast-spacing: 1.5rem; - --bs-toast-max-width: 350px; - --bs-toast-font-size: 0.875rem; - --bs-toast-color: ; - --bs-toast-bg: #444; - --bs-toast-border-width: 1px; - --bs-toast-border-color: var(--bs-border-color-translucent); - --bs-toast-border-radius: 0.375rem; - --bs-toast-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); - --bs-toast-header-color: #888; - --bs-toast-header-bg: #303030; - --bs-toast-header-border-color: rgba(0, 0, 0, 0.05); - width: var(--bs-toast-max-width); - max-width: 100%; - font-size: var(--bs-toast-font-size); - color: var(--bs-toast-color); - pointer-events: auto; - background-color: var(--bs-toast-bg); - background-clip: padding-box; - border: var(--bs-toast-border-width) solid var(--bs-toast-border-color); - box-shadow: var(--bs-toast-box-shadow); - border-radius: var(--bs-toast-border-radius) -} - -.toast.showing { - opacity: 0 -} - -.toast:not(.show) { - display: none -} - -.toast-container { - position: absolute; - z-index: 1090; - width: -webkit-max-content; - width: -moz-max-content; - width: max-content; - max-width: 100%; - pointer-events: none -} - -.toast-container > :not(:last-child) { - margin-bottom: var(--bs-toast-spacing) -} - -.toast-header { - display: flex; - align-items: center; - padding: var(--bs-toast-padding-y) var(--bs-toast-padding-x); - color: var(--bs-toast-header-color); - background-color: var(--bs-toast-header-bg); - background-clip: padding-box; - border-bottom: var(--bs-toast-border-width) solid var(--bs-toast-header-border-color); - border-top-left-radius: calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width)); - border-top-right-radius: calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width)) -} - -.toast-header .btn-close { - margin-right: calc(var(--bs-toast-padding-x) * -.5); - margin-left: var(--bs-toast-padding-x) -} - -.toast-body { - padding: var(--bs-toast-padding-x); - word-wrap: break-word -} - -.modal { - --bs-modal-zindex: 1055; - --bs-modal-width: 500px; - --bs-modal-padding: 1rem; - --bs-modal-margin: 0.5rem; - --bs-modal-color: ; - --bs-modal-bg: #303030; - --bs-modal-border-color: #444; - --bs-modal-border-width: 1px; - --bs-modal-border-radius: 0.5rem; - --bs-modal-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); - --bs-modal-inner-border-radius: calc(0.5rem - 1px); - --bs-modal-header-padding-x: 1rem; - --bs-modal-header-padding-y: 1rem; - --bs-modal-header-padding: 1rem 1rem; - --bs-modal-header-border-color: #444; - --bs-modal-header-border-width: 1px; - --bs-modal-title-line-height: 1.5; - --bs-modal-footer-gap: 0.5rem; - --bs-modal-footer-bg: ; - --bs-modal-footer-border-color: #444; - --bs-modal-footer-border-width: 1px; - position: fixed; - top: 0; - left: 0; - z-index: var(--bs-modal-zindex); - display: none; - width: 100%; - height: 100%; - overflow-x: hidden; - overflow-y: auto; - outline: 0 -} - -.modal-dialog { - position: relative; - width: auto; - margin: var(--bs-modal-margin); - pointer-events: none -} - -.modal.fade .modal-dialog { - transition: transform .3s ease-out; - transform: translate(0, -50px) -} - -@media (prefers-reduced-motion: reduce) { - .modal.fade .modal-dialog { - transition: none - } -} - -.modal.show .modal-dialog { - transform: none -} - -.modal.modal-static .modal-dialog { - transform: scale(1.02) -} - -.modal-dialog-scrollable { - height: calc(100% - var(--bs-modal-margin) * 2) -} - -.modal-dialog-scrollable .modal-content { - max-height: 100%; - overflow: hidden -} - -.modal-dialog-scrollable .modal-body { - overflow-y: auto -} - -.modal-dialog-centered { - display: flex; - align-items: center; - min-height: calc(100% - var(--bs-modal-margin) * 2) -} - -.modal-content { - position: relative; - display: flex; - flex-direction: column; - width: 100%; - color: var(--bs-modal-color); - pointer-events: auto; - background-color: var(--bs-modal-bg); - background-clip: padding-box; - border: var(--bs-modal-border-width) solid var(--bs-modal-border-color); - border-radius: var(--bs-modal-border-radius); - outline: 0 -} - -.modal-backdrop { - --bs-backdrop-zindex: 1050; - --bs-backdrop-bg: #000; - --bs-backdrop-opacity: 0.5; - position: fixed; - top: 0; - left: 0; - z-index: var(--bs-backdrop-zindex); - width: 100vw; - height: 100vh; - background-color: var(--bs-backdrop-bg) -} - -.modal-backdrop.fade { - opacity: 0 -} - -.modal-backdrop.show { - opacity: var(--bs-backdrop-opacity) -} - -.modal-header { - display: flex; - flex-shrink: 0; - align-items: center; - justify-content: space-between; - padding: var(--bs-modal-header-padding); - border-bottom: var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color); - border-top-left-radius: var(--bs-modal-inner-border-radius); - border-top-right-radius: var(--bs-modal-inner-border-radius) -} - -.modal-header .btn-close { - padding: calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5); - margin: calc(var(--bs-modal-header-padding-y) * -.5) calc(var(--bs-modal-header-padding-x) * -.5) calc(var(--bs-modal-header-padding-y) * -.5) auto -} - -.modal-title { - margin-bottom: 0; - line-height: var(--bs-modal-title-line-height) -} - -.modal-body { - position: relative; - flex: 1 1 auto; - padding: var(--bs-modal-padding) -} - -.modal-footer { - display: flex; - flex-shrink: 0; - flex-wrap: wrap; - align-items: center; - justify-content: flex-end; - padding: calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5); - background-color: var(--bs-modal-footer-bg); - border-top: var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color); - border-bottom-right-radius: var(--bs-modal-inner-border-radius); - border-bottom-left-radius: var(--bs-modal-inner-border-radius) -} - -.modal-footer > * { - margin: calc(var(--bs-modal-footer-gap) * .5) -} - -@media (min-width: 576px) { - .modal { - --bs-modal-margin: 1.75rem; - --bs-modal-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) - } - - .modal-dialog { - max-width: var(--bs-modal-width); - margin-right: auto; - margin-left: auto - } - - .modal-sm { - --bs-modal-width: 300px - } -} - -@media (min-width: 992px) { - .modal-lg, .modal-xl { - --bs-modal-width: 800px - } -} - -@media (min-width: 1200px) { - .modal-xl { - --bs-modal-width: 1140px - } -} - -.modal-fullscreen { - width: 100vw; - max-width: none; - height: 100%; - margin: 0 -} - -.modal-fullscreen .modal-content { - height: 100%; - border: 0; - border-radius: 0 -} - -.modal-fullscreen .modal-footer, .modal-fullscreen .modal-header { - border-radius: 0 -} - -.modal-fullscreen .modal-body { - overflow-y: auto -} - -@media (max-width: 575.98px) { - .modal-fullscreen-sm-down { - width: 100vw; - max-width: none; - height: 100%; - margin: 0 - } - - .modal-fullscreen-sm-down .modal-content { - height: 100%; - border: 0; - border-radius: 0 - } - - .modal-fullscreen-sm-down .modal-footer, .modal-fullscreen-sm-down .modal-header { - border-radius: 0 - } - - .modal-fullscreen-sm-down .modal-body { - overflow-y: auto - } -} - -@media (max-width: 767.98px) { - .modal-fullscreen-md-down { - width: 100vw; - max-width: none; - height: 100%; - margin: 0 - } - - .modal-fullscreen-md-down .modal-content { - height: 100%; - border: 0; - border-radius: 0 - } - - .modal-fullscreen-md-down .modal-footer, .modal-fullscreen-md-down .modal-header { - border-radius: 0 - } - - .modal-fullscreen-md-down .modal-body { - overflow-y: auto - } -} - -@media (max-width: 991.98px) { - .modal-fullscreen-lg-down { - width: 100vw; - max-width: none; - height: 100%; - margin: 0 - } - - .modal-fullscreen-lg-down .modal-content { - height: 100%; - border: 0; - border-radius: 0 - } - - .modal-fullscreen-lg-down .modal-footer, .modal-fullscreen-lg-down .modal-header { - border-radius: 0 - } - - .modal-fullscreen-lg-down .modal-body { - overflow-y: auto - } -} - -@media (max-width: 1199.98px) { - .modal-fullscreen-xl-down { - width: 100vw; - max-width: none; - height: 100%; - margin: 0 - } - - .modal-fullscreen-xl-down .modal-content { - height: 100%; - border: 0; - border-radius: 0 - } - - .modal-fullscreen-xl-down .modal-footer, .modal-fullscreen-xl-down .modal-header { - border-radius: 0 - } - - .modal-fullscreen-xl-down .modal-body { - overflow-y: auto - } -} - -@media (max-width: 1399.98px) { - .modal-fullscreen-xxl-down { - width: 100vw; - max-width: none; - height: 100%; - margin: 0 - } - - .modal-fullscreen-xxl-down .modal-content { - height: 100%; - border: 0; - border-radius: 0 - } - - .modal-fullscreen-xxl-down .modal-footer, .modal-fullscreen-xxl-down .modal-header { - border-radius: 0 - } - - .modal-fullscreen-xxl-down .modal-body { - overflow-y: auto - } -} - -.tooltip { - --bs-tooltip-zindex: 1080; - --bs-tooltip-max-width: 200px; - --bs-tooltip-padding-x: 0.5rem; - --bs-tooltip-padding-y: 0.25rem; - --bs-tooltip-margin: ; - --bs-tooltip-font-size: 0.875rem; - --bs-tooltip-color: #fff; - --bs-tooltip-bg: #000; - --bs-tooltip-border-radius: 0.375rem; - --bs-tooltip-opacity: 0.9; - --bs-tooltip-arrow-width: 0.8rem; - --bs-tooltip-arrow-height: 0.4rem; - z-index: var(--bs-tooltip-zindex); - display: block; - padding: var(--bs-tooltip-arrow-height); - margin: var(--bs-tooltip-margin); - font-family: var(--bs-font-sans-serif); - font-style: normal; - font-weight: 400; - line-height: 1.5; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - letter-spacing: normal; - word-break: normal; - white-space: normal; - word-spacing: normal; - line-break: auto; - font-size: var(--bs-tooltip-font-size); - word-wrap: break-word; - opacity: 0 -} - -.tooltip.show { - opacity: var(--bs-tooltip-opacity) -} - -.tooltip .tooltip-arrow { - display: block; - width: var(--bs-tooltip-arrow-width); - height: var(--bs-tooltip-arrow-height) -} - -.tooltip .tooltip-arrow::before { - position: absolute; - content: ""; - border-color: transparent; - border-style: solid -} - -.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow, .bs-tooltip-top .tooltip-arrow { - bottom: 0 -} - -.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before, .bs-tooltip-top .tooltip-arrow::before { - top: -1px; - border-width: var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0; - border-top-color: var(--bs-tooltip-bg) -} - -.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow, .bs-tooltip-end .tooltip-arrow { - left: 0; - width: var(--bs-tooltip-arrow-height); - height: var(--bs-tooltip-arrow-width) -} - -.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before, .bs-tooltip-end .tooltip-arrow::before { - right: -1px; - border-width: calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0; - border-right-color: var(--bs-tooltip-bg) -} - -.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow, .bs-tooltip-bottom .tooltip-arrow { - top: 0 -} - -.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before, .bs-tooltip-bottom .tooltip-arrow::before { - bottom: -1px; - border-width: 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height); - border-bottom-color: var(--bs-tooltip-bg) -} - -.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow, .bs-tooltip-start .tooltip-arrow { - right: 0; - width: var(--bs-tooltip-arrow-height); - height: var(--bs-tooltip-arrow-width) -} - -.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before, .bs-tooltip-start .tooltip-arrow::before { - left: -1px; - border-width: calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height); - border-left-color: var(--bs-tooltip-bg) -} - -.tooltip-inner { - max-width: var(--bs-tooltip-max-width); - padding: var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x); - color: var(--bs-tooltip-color); - text-align: center; - background-color: var(--bs-tooltip-bg); - border-radius: var(--bs-tooltip-border-radius) -} - -.popover { - --bs-popover-zindex: 1070; - --bs-popover-max-width: 276px; - --bs-popover-font-size: 0.875rem; - --bs-popover-bg: #303030; - --bs-popover-border-width: 1px; - --bs-popover-border-color: var(--bs-border-color-translucent); - --bs-popover-border-radius: 0.5rem; - --bs-popover-inner-border-radius: calc(0.5rem - 1px); - --bs-popover-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); - --bs-popover-header-padding-x: 1rem; - --bs-popover-header-padding-y: 0.5rem; - --bs-popover-header-font-size: 1rem; - --bs-popover-header-color: var(--bs-heading-color); - --bs-popover-header-bg: #444; - --bs-popover-body-padding-x: 1rem; - --bs-popover-body-padding-y: 1rem; - --bs-popover-body-color: #fff; - --bs-popover-arrow-width: 1rem; - --bs-popover-arrow-height: 0.5rem; - --bs-popover-arrow-border: var(--bs-popover-border-color); - z-index: var(--bs-popover-zindex); - display: block; - max-width: var(--bs-popover-max-width); - font-family: var(--bs-font-sans-serif); - font-style: normal; - font-weight: 400; - line-height: 1.5; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - letter-spacing: normal; - word-break: normal; - white-space: normal; - word-spacing: normal; - line-break: auto; - font-size: var(--bs-popover-font-size); - word-wrap: break-word; - background-color: var(--bs-popover-bg); - background-clip: padding-box; - border: var(--bs-popover-border-width) solid var(--bs-popover-border-color); - border-radius: var(--bs-popover-border-radius) -} - -.popover .popover-arrow { - display: block; - width: var(--bs-popover-arrow-width); - height: var(--bs-popover-arrow-height) -} - -.popover .popover-arrow::after, .popover .popover-arrow::before { - position: absolute; - display: block; - content: ""; - border-color: transparent; - border-style: solid; - border-width: 0 -} - -.bs-popover-auto[data-popper-placement^=top] > .popover-arrow, .bs-popover-top > .popover-arrow { - bottom: calc(var(--bs-popover-arrow-height) * -1 - var(--bs-popover-border-width)) -} - -.bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before, .bs-popover-top > .popover-arrow::after, .bs-popover-top > .popover-arrow::before { - border-width: var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0 -} - -.bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before, .bs-popover-top > .popover-arrow::before { - bottom: 0; - border-top-color: var(--bs-popover-arrow-border) -} - -.bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after, .bs-popover-top > .popover-arrow::after { - bottom: var(--bs-popover-border-width); - border-top-color: var(--bs-popover-bg) -} - -.bs-popover-auto[data-popper-placement^=right] > .popover-arrow, .bs-popover-end > .popover-arrow { - left: calc(var(--bs-popover-arrow-height) * -1 - var(--bs-popover-border-width)); - width: var(--bs-popover-arrow-height); - height: var(--bs-popover-arrow-width) -} - -.bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before, .bs-popover-end > .popover-arrow::after, .bs-popover-end > .popover-arrow::before { - border-width: calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0 -} - -.bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before, .bs-popover-end > .popover-arrow::before { - left: 0; - border-right-color: var(--bs-popover-arrow-border) -} - -.bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after, .bs-popover-end > .popover-arrow::after { - left: var(--bs-popover-border-width); - border-right-color: var(--bs-popover-bg) -} - -.bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow, .bs-popover-bottom > .popover-arrow { - top: calc(var(--bs-popover-arrow-height) * -1 - var(--bs-popover-border-width)) -} - -.bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before, .bs-popover-bottom > .popover-arrow::after, .bs-popover-bottom > .popover-arrow::before { - border-width: 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) -} - -.bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before, .bs-popover-bottom > .popover-arrow::before { - top: 0; - border-bottom-color: var(--bs-popover-arrow-border) -} - -.bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after, .bs-popover-bottom > .popover-arrow::after { - top: var(--bs-popover-border-width); - border-bottom-color: var(--bs-popover-bg) -} - -.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before, .bs-popover-bottom .popover-header::before { - position: absolute; - top: 0; - left: 50%; - display: block; - width: var(--bs-popover-arrow-width); - margin-left: calc(var(--bs-popover-arrow-width) * -.5); - content: ""; - border-bottom: var(--bs-popover-border-width) solid var(--bs-popover-header-bg) -} - -.bs-popover-auto[data-popper-placement^=left] > .popover-arrow, .bs-popover-start > .popover-arrow { - right: calc(var(--bs-popover-arrow-height) * -1 - var(--bs-popover-border-width)); - width: var(--bs-popover-arrow-height); - height: var(--bs-popover-arrow-width) -} - -.bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before, .bs-popover-start > .popover-arrow::after, .bs-popover-start > .popover-arrow::before { - border-width: calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) -} - -.bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before, .bs-popover-start > .popover-arrow::before { - right: 0; - border-left-color: var(--bs-popover-arrow-border) -} - -.bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after, .bs-popover-start > .popover-arrow::after { - right: var(--bs-popover-border-width); - border-left-color: var(--bs-popover-bg) -} - -.popover-header { - padding: var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x); - margin-bottom: 0; - font-size: var(--bs-popover-header-font-size); - color: var(--bs-popover-header-color); - background-color: var(--bs-popover-header-bg); - border-bottom: var(--bs-popover-border-width) solid var(--bs-popover-border-color); - border-top-left-radius: var(--bs-popover-inner-border-radius); - border-top-right-radius: var(--bs-popover-inner-border-radius) -} - -.popover-header:empty { - display: none -} - -.popover-body { - padding: var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x); - color: var(--bs-popover-body-color) -} - -.carousel { - position: relative -} - -.carousel.pointer-event { - touch-action: pan-y -} - -.carousel-inner { - position: relative; - width: 100%; - overflow: hidden -} - -.carousel-inner::after { - display: block; - clear: both; - content: "" -} - -.carousel-item { - position: relative; - display: none; - float: left; - width: 100%; - margin-right: -100%; - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - transition: transform .6s ease-in-out -} - -@media (prefers-reduced-motion: reduce) { - .carousel-item { - transition: none - } -} - -.carousel-item-next, .carousel-item-prev, .carousel-item.active { - display: block -} - -.active.carousel-item-end, .carousel-item-next:not(.carousel-item-start) { - transform: translateX(100%) -} - -.active.carousel-item-start, .carousel-item-prev:not(.carousel-item-end) { - transform: translateX(-100%) -} - -.carousel-fade .carousel-item { - opacity: 0; - transition-property: opacity; - transform: none -} - -.carousel-fade .carousel-item-next.carousel-item-start, .carousel-fade .carousel-item-prev.carousel-item-end, .carousel-fade .carousel-item.active { - z-index: 1; - opacity: 1 -} - -.carousel-fade .active.carousel-item-end, .carousel-fade .active.carousel-item-start { - z-index: 0; - opacity: 0; - transition: opacity 0s .6s -} - -@media (prefers-reduced-motion: reduce) { - .carousel-fade .active.carousel-item-end, .carousel-fade .active.carousel-item-start { - transition: none - } -} - -.carousel-control-next, .carousel-control-prev { - position: absolute; - top: 0; - bottom: 0; - z-index: 1; - display: flex; - align-items: center; - justify-content: center; - width: 15%; - padding: 0; - color: #fff; - text-align: center; - background: 0 0; - border: 0; - opacity: .5; - transition: opacity .15s ease -} - -@media (prefers-reduced-motion: reduce) { - .carousel-control-next, .carousel-control-prev { - transition: none - } -} - -.carousel-control-next:focus, .carousel-control-next:hover, .carousel-control-prev:focus, .carousel-control-prev:hover { - color: #fff; - text-decoration: none; - outline: 0; - opacity: .9 -} - -.carousel-control-prev { - left: 0 -} - -.carousel-control-next { - right: 0 -} - -.carousel-control-next-icon, .carousel-control-prev-icon { - display: inline-block; - width: 2rem; - height: 2rem; - background-repeat: no-repeat; - background-position: 50%; - background-size: 100% 100% -} - -.carousel-control-prev-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e") -} - -.carousel-control-next-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e") -} - -.carousel-indicators { - position: absolute; - right: 0; - bottom: 0; - left: 0; - z-index: 2; - display: flex; - justify-content: center; - padding: 0; - margin-right: 15%; - margin-bottom: 1rem; - margin-left: 15%; - list-style: none -} - -.carousel-indicators [data-bs-target] { - box-sizing: content-box; - flex: 0 1 auto; - width: 30px; - height: 3px; - padding: 0; - margin-right: 3px; - margin-left: 3px; - text-indent: -999px; - cursor: pointer; - background-color: #fff; - background-clip: padding-box; - border: 0; - border-top: 10px solid transparent; - border-bottom: 10px solid transparent; - opacity: .5; - transition: opacity .6s ease -} - -@media (prefers-reduced-motion: reduce) { - .carousel-indicators [data-bs-target] { - transition: none - } -} - -.carousel-indicators .active { - opacity: 1 -} - -.carousel-caption { - position: absolute; - right: 15%; - bottom: 1.25rem; - left: 15%; - padding-top: 1.25rem; - padding-bottom: 1.25rem; - color: #fff; - text-align: center -} - -.carousel-dark .carousel-control-next-icon, .carousel-dark .carousel-control-prev-icon { - filter: invert(1) grayscale(100) -} - -.carousel-dark .carousel-indicators [data-bs-target] { - background-color: #000 -} - -.carousel-dark .carousel-caption { - color: #000 -} - -.spinner-border, .spinner-grow { - display: inline-block; - width: var(--bs-spinner-width); - height: var(--bs-spinner-height); - vertical-align: var(--bs-spinner-vertical-align); - border-radius: 50%; - -webkit-animation: var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name); - animation: var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name) -} - -@-webkit-keyframes spinner-border { - to { - transform: rotate(360deg) - } -} - -@keyframes spinner-border { - to { - transform: rotate(360deg) - } -} - -.spinner-border { - --bs-spinner-width: 2rem; - --bs-spinner-height: 2rem; - --bs-spinner-vertical-align: -0.125em; - --bs-spinner-border-width: 0.25em; - --bs-spinner-animation-speed: 0.75s; - --bs-spinner-animation-name: spinner-border; - border: var(--bs-spinner-border-width) solid currentcolor; - border-right-color: transparent -} - -.spinner-border-sm { - --bs-spinner-width: 1rem; - --bs-spinner-height: 1rem; - --bs-spinner-border-width: 0.2em -} - -@-webkit-keyframes spinner-grow { - 0% { - transform: scale(0) - } - 50% { - opacity: 1; - transform: none - } -} - -@keyframes spinner-grow { - 0% { - transform: scale(0) - } - 50% { - opacity: 1; - transform: none - } -} - -.spinner-grow { - --bs-spinner-width: 2rem; - --bs-spinner-height: 2rem; - --bs-spinner-vertical-align: -0.125em; - --bs-spinner-animation-speed: 0.75s; - --bs-spinner-animation-name: spinner-grow; - background-color: currentcolor; - opacity: 0 -} - -.spinner-grow-sm { - --bs-spinner-width: 1rem; - --bs-spinner-height: 1rem -} - -@media (prefers-reduced-motion: reduce) { - .spinner-border, .spinner-grow { - --bs-spinner-animation-speed: 1.5s - } -} - -.offcanvas, .offcanvas-lg, .offcanvas-md, .offcanvas-sm, .offcanvas-xl, .offcanvas-xxl { - --bs-offcanvas-width: 400px; - --bs-offcanvas-height: 30vh; - --bs-offcanvas-padding-x: 1rem; - --bs-offcanvas-padding-y: 1rem; - --bs-offcanvas-color: ; - --bs-offcanvas-bg: #303030; - --bs-offcanvas-border-width: 1px; - --bs-offcanvas-border-color: #444; - --bs-offcanvas-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) -} - -@media (max-width: 575.98px) { - .offcanvas-sm { - position: fixed; - bottom: 0; - z-index: 1045; - display: flex; - flex-direction: column; - max-width: 100%; - color: var(--bs-offcanvas-color); - visibility: hidden; - background-color: var(--bs-offcanvas-bg); - background-clip: padding-box; - outline: 0; - transition: transform .3s ease-in-out - } -} - -@media (max-width: 575.98px) and (prefers-reduced-motion: reduce) { - .offcanvas-sm { - transition: none - } -} - -@media (max-width: 575.98px) { - .offcanvas-sm.offcanvas-start { - top: 0; - left: 0; - width: var(--bs-offcanvas-width); - border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateX(-100%) - } -} - -@media (max-width: 575.98px) { - .offcanvas-sm.offcanvas-end { - top: 0; - right: 0; - width: var(--bs-offcanvas-width); - border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateX(100%) - } -} - -@media (max-width: 575.98px) { - .offcanvas-sm.offcanvas-top { - top: 0; - right: 0; - left: 0; - height: var(--bs-offcanvas-height); - max-height: 100%; - border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateY(-100%) - } -} - -@media (max-width: 575.98px) { - .offcanvas-sm.offcanvas-bottom { - right: 0; - left: 0; - height: var(--bs-offcanvas-height); - max-height: 100%; - border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateY(100%) - } -} - -@media (max-width: 575.98px) { - .offcanvas-sm.show:not(.hiding), .offcanvas-sm.showing { - transform: none - } -} - -@media (max-width: 575.98px) { - .offcanvas-sm.hiding, .offcanvas-sm.show, .offcanvas-sm.showing { - visibility: visible - } -} - -@media (min-width: 576px) { - .offcanvas-sm { - --bs-offcanvas-height: auto; - --bs-offcanvas-border-width: 0; - background-color: transparent !important - } - - .offcanvas-sm .offcanvas-header { - display: none - } - - .offcanvas-sm .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; - background-color: transparent !important - } -} - -@media (max-width: 767.98px) { - .offcanvas-md { - position: fixed; - bottom: 0; - z-index: 1045; - display: flex; - flex-direction: column; - max-width: 100%; - color: var(--bs-offcanvas-color); - visibility: hidden; - background-color: var(--bs-offcanvas-bg); - background-clip: padding-box; - outline: 0; - transition: transform .3s ease-in-out - } -} - -@media (max-width: 767.98px) and (prefers-reduced-motion: reduce) { - .offcanvas-md { - transition: none - } -} - -@media (max-width: 767.98px) { - .offcanvas-md.offcanvas-start { - top: 0; - left: 0; - width: var(--bs-offcanvas-width); - border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateX(-100%) - } -} - -@media (max-width: 767.98px) { - .offcanvas-md.offcanvas-end { - top: 0; - right: 0; - width: var(--bs-offcanvas-width); - border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateX(100%) - } -} - -@media (max-width: 767.98px) { - .offcanvas-md.offcanvas-top { - top: 0; - right: 0; - left: 0; - height: var(--bs-offcanvas-height); - max-height: 100%; - border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateY(-100%) - } -} - -@media (max-width: 767.98px) { - .offcanvas-md.offcanvas-bottom { - right: 0; - left: 0; - height: var(--bs-offcanvas-height); - max-height: 100%; - border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateY(100%) - } -} - -@media (max-width: 767.98px) { - .offcanvas-md.show:not(.hiding), .offcanvas-md.showing { - transform: none - } -} - -@media (max-width: 767.98px) { - .offcanvas-md.hiding, .offcanvas-md.show, .offcanvas-md.showing { - visibility: visible - } -} - -@media (min-width: 768px) { - .offcanvas-md { - --bs-offcanvas-height: auto; - --bs-offcanvas-border-width: 0; - background-color: transparent !important - } - - .offcanvas-md .offcanvas-header { - display: none - } - - .offcanvas-md .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; - background-color: transparent !important - } -} - -@media (max-width: 991.98px) { - .offcanvas-lg { - position: fixed; - bottom: 0; - z-index: 1045; - display: flex; - flex-direction: column; - max-width: 100%; - color: var(--bs-offcanvas-color); - visibility: hidden; - background-color: var(--bs-offcanvas-bg); - background-clip: padding-box; - outline: 0; - transition: transform .3s ease-in-out - } -} - -@media (max-width: 991.98px) and (prefers-reduced-motion: reduce) { - .offcanvas-lg { - transition: none - } -} - -@media (max-width: 991.98px) { - .offcanvas-lg.offcanvas-start { - top: 0; - left: 0; - width: var(--bs-offcanvas-width); - border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateX(-100%) - } -} - -@media (max-width: 991.98px) { - .offcanvas-lg.offcanvas-end { - top: 0; - right: 0; - width: var(--bs-offcanvas-width); - border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateX(100%) - } -} - -@media (max-width: 991.98px) { - .offcanvas-lg.offcanvas-top { - top: 0; - right: 0; - left: 0; - height: var(--bs-offcanvas-height); - max-height: 100%; - border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateY(-100%) - } -} - -@media (max-width: 991.98px) { - .offcanvas-lg.offcanvas-bottom { - right: 0; - left: 0; - height: var(--bs-offcanvas-height); - max-height: 100%; - border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateY(100%) - } -} - -@media (max-width: 991.98px) { - .offcanvas-lg.show:not(.hiding), .offcanvas-lg.showing { - transform: none - } -} - -@media (max-width: 991.98px) { - .offcanvas-lg.hiding, .offcanvas-lg.show, .offcanvas-lg.showing { - visibility: visible - } -} - -@media (min-width: 992px) { - .offcanvas-lg { - --bs-offcanvas-height: auto; - --bs-offcanvas-border-width: 0; - background-color: transparent !important - } - - .offcanvas-lg .offcanvas-header { - display: none - } - - .offcanvas-lg .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; - background-color: transparent !important - } -} - -@media (max-width: 1199.98px) { - .offcanvas-xl { - position: fixed; - bottom: 0; - z-index: 1045; - display: flex; - flex-direction: column; - max-width: 100%; - color: var(--bs-offcanvas-color); - visibility: hidden; - background-color: var(--bs-offcanvas-bg); - background-clip: padding-box; - outline: 0; - transition: transform .3s ease-in-out - } -} - -@media (max-width: 1199.98px) and (prefers-reduced-motion: reduce) { - .offcanvas-xl { - transition: none - } -} - -@media (max-width: 1199.98px) { - .offcanvas-xl.offcanvas-start { - top: 0; - left: 0; - width: var(--bs-offcanvas-width); - border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateX(-100%) - } -} - -@media (max-width: 1199.98px) { - .offcanvas-xl.offcanvas-end { - top: 0; - right: 0; - width: var(--bs-offcanvas-width); - border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateX(100%) - } -} - -@media (max-width: 1199.98px) { - .offcanvas-xl.offcanvas-top { - top: 0; - right: 0; - left: 0; - height: var(--bs-offcanvas-height); - max-height: 100%; - border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateY(-100%) - } -} - -@media (max-width: 1199.98px) { - .offcanvas-xl.offcanvas-bottom { - right: 0; - left: 0; - height: var(--bs-offcanvas-height); - max-height: 100%; - border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateY(100%) - } -} - -@media (max-width: 1199.98px) { - .offcanvas-xl.show:not(.hiding), .offcanvas-xl.showing { - transform: none - } -} - -@media (max-width: 1199.98px) { - .offcanvas-xl.hiding, .offcanvas-xl.show, .offcanvas-xl.showing { - visibility: visible - } -} - -@media (min-width: 1200px) { - .offcanvas-xl { - --bs-offcanvas-height: auto; - --bs-offcanvas-border-width: 0; - background-color: transparent !important - } - - .offcanvas-xl .offcanvas-header { - display: none - } - - .offcanvas-xl .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; - background-color: transparent !important - } -} - -@media (max-width: 1399.98px) { - .offcanvas-xxl { - position: fixed; - bottom: 0; - z-index: 1045; - display: flex; - flex-direction: column; - max-width: 100%; - color: var(--bs-offcanvas-color); - visibility: hidden; - background-color: var(--bs-offcanvas-bg); - background-clip: padding-box; - outline: 0; - transition: transform .3s ease-in-out - } -} - -@media (max-width: 1399.98px) and (prefers-reduced-motion: reduce) { - .offcanvas-xxl { - transition: none - } -} - -@media (max-width: 1399.98px) { - .offcanvas-xxl.offcanvas-start { - top: 0; - left: 0; - width: var(--bs-offcanvas-width); - border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateX(-100%) - } -} - -@media (max-width: 1399.98px) { - .offcanvas-xxl.offcanvas-end { - top: 0; - right: 0; - width: var(--bs-offcanvas-width); - border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateX(100%) - } -} - -@media (max-width: 1399.98px) { - .offcanvas-xxl.offcanvas-top { - top: 0; - right: 0; - left: 0; - height: var(--bs-offcanvas-height); - max-height: 100%; - border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateY(-100%) - } -} - -@media (max-width: 1399.98px) { - .offcanvas-xxl.offcanvas-bottom { - right: 0; - left: 0; - height: var(--bs-offcanvas-height); - max-height: 100%; - border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateY(100%) - } -} - -@media (max-width: 1399.98px) { - .offcanvas-xxl.show:not(.hiding), .offcanvas-xxl.showing { - transform: none - } -} - -@media (max-width: 1399.98px) { - .offcanvas-xxl.hiding, .offcanvas-xxl.show, .offcanvas-xxl.showing { - visibility: visible - } -} - -@media (min-width: 1400px) { - .offcanvas-xxl { - --bs-offcanvas-height: auto; - --bs-offcanvas-border-width: 0; - background-color: transparent !important - } - - .offcanvas-xxl .offcanvas-header { - display: none - } - - .offcanvas-xxl .offcanvas-body { - display: flex; - flex-grow: 0; - padding: 0; - overflow-y: visible; - background-color: transparent !important - } -} - -.offcanvas { - position: fixed; - bottom: 0; - z-index: 1045; - display: flex; - flex-direction: column; - max-width: 100%; - color: var(--bs-offcanvas-color); - visibility: hidden; - background-color: var(--bs-offcanvas-bg); - background-clip: padding-box; - outline: 0; - transition: transform .3s ease-in-out -} - -@media (prefers-reduced-motion: reduce) { - .offcanvas { - transition: none - } -} - -.offcanvas.offcanvas-start { - top: 0; - left: 0; - width: var(--bs-offcanvas-width); - border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateX(-100%) -} - -.offcanvas.offcanvas-end { - top: 0; - right: 0; - width: var(--bs-offcanvas-width); - border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateX(100%) -} - -.offcanvas.offcanvas-top { - top: 0; - right: 0; - left: 0; - height: var(--bs-offcanvas-height); - max-height: 100%; - border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateY(-100%) -} - -.offcanvas.offcanvas-bottom { - right: 0; - left: 0; - height: var(--bs-offcanvas-height); - max-height: 100%; - border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); - transform: translateY(100%) -} - -.offcanvas.show:not(.hiding), .offcanvas.showing { - transform: none -} - -.offcanvas.hiding, .offcanvas.show, .offcanvas.showing { - visibility: visible -} - -.offcanvas-backdrop { - position: fixed; - top: 0; - left: 0; - z-index: 1040; - width: 100vw; - height: 100vh; - background-color: #000 -} - -.offcanvas-backdrop.fade { - opacity: 0 -} - -.offcanvas-backdrop.show { - opacity: .5 -} - -.offcanvas-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x) -} - -.offcanvas-header .btn-close { - padding: calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5); - margin-top: calc(var(--bs-offcanvas-padding-y) * -.5); - margin-right: calc(var(--bs-offcanvas-padding-x) * -.5); - margin-bottom: calc(var(--bs-offcanvas-padding-y) * -.5) -} - -.offcanvas-title { - margin-bottom: 0; - line-height: 1.5 -} - -.offcanvas-body { - flex-grow: 1; - padding: var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x); - overflow-y: auto -} - -.placeholder { - display: inline-block; - min-height: 1em; - vertical-align: middle; - cursor: wait; - background-color: currentcolor; - opacity: .5 -} - -.placeholder.btn::before { - display: inline-block; - content: "" -} - -.placeholder-xs { - min-height: .6em -} - -.placeholder-sm { - min-height: .8em -} - -.placeholder-lg { - min-height: 1.2em -} - -.placeholder-glow .placeholder { - -webkit-animation: placeholder-glow 2s ease-in-out infinite; - animation: placeholder-glow 2s ease-in-out infinite -} - -@-webkit-keyframes placeholder-glow { - 50% { - opacity: .2 - } -} - -@keyframes placeholder-glow { - 50% { - opacity: .2 - } -} - -.placeholder-wave { - -webkit-mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%); - mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%); - -webkit-mask-size: 200% 100%; - mask-size: 200% 100%; - -webkit-animation: placeholder-wave 2s linear infinite; - animation: placeholder-wave 2s linear infinite -} - -@-webkit-keyframes placeholder-wave { - 100% { - -webkit-mask-position: -200% 0%; - mask-position: -200% 0% - } -} - -@keyframes placeholder-wave { - 100% { - -webkit-mask-position: -200% 0%; - mask-position: -200% 0% - } -} - -.clearfix::after { - display: block; - clear: both; - content: "" -} - -.text-bg-primary { - color: #fff !important; - background-color: RGBA(55, 90, 127, var(--bs-bg-opacity, 1)) !important -} - -.text-bg-secondary { - color: #fff !important; - background-color: RGBA(68, 68, 68, var(--bs-bg-opacity, 1)) !important -} - -.text-bg-success { - color: #fff !important; - background-color: RGBA(0, 188, 140, var(--bs-bg-opacity, 1)) !important -} - -.text-bg-info { - color: #fff !important; - background-color: RGBA(52, 152, 219, var(--bs-bg-opacity, 1)) !important -} - -.text-bg-warning { - color: #fff !important; - background-color: RGBA(243, 156, 18, var(--bs-bg-opacity, 1)) !important -} - -.text-bg-danger { - color: #fff !important; - background-color: RGBA(231, 76, 60, var(--bs-bg-opacity, 1)) !important -} - -.text-bg-light { - color: #fff !important; - background-color: RGBA(173, 181, 189, var(--bs-bg-opacity, 1)) !important -} - -.text-bg-dark { - color: #fff !important; - background-color: RGBA(48, 48, 48, var(--bs-bg-opacity, 1)) !important -} - -.link-primary { - color: #375a7f !important -} - -.link-primary:focus, .link-primary:hover { - color: #2c4866 !important -} - -.link-secondary { - color: #444 !important -} - -.link-secondary:focus, .link-secondary:hover { - color: #363636 !important -} - -.link-success { - color: #00bc8c !important -} - -.link-success:focus, .link-success:hover { - color: #009670 !important -} - -.link-info { - color: #3498db !important -} - -.link-info:focus, .link-info:hover { - color: #2a7aaf !important -} - -.link-warning { - color: #f39c12 !important -} - -.link-warning:focus, .link-warning:hover { - color: #c27d0e !important -} - -.link-danger { - color: #e74c3c !important -} - -.link-danger:focus, .link-danger:hover { - color: #b93d30 !important -} - -.link-light { - color: #adb5bd !important -} - -.link-light:focus, .link-light:hover { - color: #8a9197 !important -} - -.link-dark { - color: #303030 !important -} - -.link-dark:focus, .link-dark:hover { - color: #262626 !important -} - -.ratio { - position: relative; - width: 100% -} - -.ratio::before { - display: block; - padding-top: var(--bs-aspect-ratio); - content: "" -} - -.ratio > * { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100% -} - -.ratio-1x1 { - --bs-aspect-ratio: 100% -} - -.ratio-4x3 { - --bs-aspect-ratio: 75% -} - -.ratio-16x9 { - --bs-aspect-ratio: 56.25% -} - -.ratio-21x9 { - --bs-aspect-ratio: 42.8571428571% -} - -.fixed-top { - position: fixed; - top: 0; - right: 0; - left: 0; - z-index: 1030 -} - -.fixed-bottom { - position: fixed; - right: 0; - bottom: 0; - left: 0; - z-index: 1030 -} - -.sticky-top { - position: -webkit-sticky; - position: sticky; - top: 0; - z-index: 1020 -} - -.sticky-bottom { - position: -webkit-sticky; - position: sticky; - bottom: 0; - z-index: 1020 -} - -@media (min-width: 576px) { - .sticky-sm-top { - position: -webkit-sticky; - position: sticky; - top: 0; - z-index: 1020 - } - - .sticky-sm-bottom { - position: -webkit-sticky; - position: sticky; - bottom: 0; - z-index: 1020 - } -} - -@media (min-width: 768px) { - .sticky-md-top { - position: -webkit-sticky; - position: sticky; - top: 0; - z-index: 1020 - } - - .sticky-md-bottom { - position: -webkit-sticky; - position: sticky; - bottom: 0; - z-index: 1020 - } -} - -@media (min-width: 992px) { - .sticky-lg-top { - position: -webkit-sticky; - position: sticky; - top: 0; - z-index: 1020 - } - - .sticky-lg-bottom { - position: -webkit-sticky; - position: sticky; - bottom: 0; - z-index: 1020 - } -} - -@media (min-width: 1200px) { - .sticky-xl-top { - position: -webkit-sticky; - position: sticky; - top: 0; - z-index: 1020 - } - - .sticky-xl-bottom { - position: -webkit-sticky; - position: sticky; - bottom: 0; - z-index: 1020 - } -} - -@media (min-width: 1400px) { - .sticky-xxl-top { - position: -webkit-sticky; - position: sticky; - top: 0; - z-index: 1020 - } - - .sticky-xxl-bottom { - position: -webkit-sticky; - position: sticky; - bottom: 0; - z-index: 1020 - } -} - -.hstack { - display: flex; - flex-direction: row; - align-items: center; - align-self: stretch -} - -.vstack { - display: flex; - flex: 1 1 auto; - flex-direction: column; - align-self: stretch -} - -.visually-hidden, .visually-hidden-focusable:not(:focus):not(:focus-within) { - position: absolute !important; - width: 1px !important; - height: 1px !important; - padding: 0 !important; - margin: -1px !important; - overflow: hidden !important; - clip: rect(0, 0, 0, 0) !important; - white-space: nowrap !important; - border: 0 !important -} - -.stretched-link::after { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1; - content: "" -} - -.text-truncate { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap -} - -.vr { - display: inline-block; - align-self: stretch; - width: 1px; - min-height: 1em; - background-color: currentcolor; - opacity: .25 -} - -.align-baseline { - vertical-align: baseline !important -} - -.align-top { - vertical-align: top !important -} - -.align-middle { - vertical-align: middle !important -} - -.align-bottom { - vertical-align: bottom !important -} - -.align-text-bottom { - vertical-align: text-bottom !important -} - -.align-text-top { - vertical-align: text-top !important -} - -.float-start { - float: left !important -} - -.float-end { - float: right !important -} - -.float-none { - float: none !important -} - -.opacity-0 { - opacity: 0 !important -} - -.opacity-25 { - opacity: .25 !important -} - -.opacity-50 { - opacity: .5 !important -} - -.opacity-75 { - opacity: .75 !important -} - -.opacity-100 { - opacity: 1 !important -} - -.overflow-auto { - overflow: auto !important -} - -.overflow-hidden { - overflow: hidden !important -} - -.overflow-visible { - overflow: visible !important -} - -.overflow-scroll { - overflow: scroll !important -} - -.d-inline { - display: inline !important -} - -.d-inline-block { - display: inline-block !important -} - -.d-block { - display: block !important -} - -.d-grid { - display: grid !important -} - -.d-table { - display: table !important -} - -.d-table-row { - display: table-row !important -} - -.d-table-cell { - display: table-cell !important -} - -.d-flex { - display: flex !important -} - -.d-inline-flex { - display: inline-flex !important -} - -.d-none { - display: none !important -} - -.shadow { - box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .15) !important -} - -.shadow-sm { - box-shadow: 0 .125rem .25rem rgba(0, 0, 0, .075) !important -} - -.shadow-lg { - box-shadow: 0 1rem 3rem rgba(0, 0, 0, .175) !important -} - -.shadow-none { - box-shadow: none !important -} - -.position-static { - position: static !important -} - -.position-relative { - position: relative !important -} - -.position-absolute { - position: absolute !important -} - -.position-fixed { - position: fixed !important -} - -.position-sticky { - position: -webkit-sticky !important; - position: sticky !important -} - -.top-0 { - top: 0 !important -} - -.top-50 { - top: 50% !important -} - -.top-100 { - top: 100% !important -} - -.bottom-0 { - bottom: 0 !important -} - -.bottom-50 { - bottom: 50% !important -} - -.bottom-100 { - bottom: 100% !important -} - -.start-0 { - left: 0 !important -} - -.start-50 { - left: 50% !important -} - -.start-100 { - left: 100% !important -} - -.end-0 { - right: 0 !important -} - -.end-50 { - right: 50% !important -} - -.end-100 { - right: 100% !important -} - -.translate-middle { - transform: translate(-50%, -50%) !important -} - -.translate-middle-x { - transform: translateX(-50%) !important -} - -.translate-middle-y { - transform: translateY(-50%) !important -} - -.border { - border: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important -} - -.border-0 { - border: 0 !important -} - -.border-top { - border-top: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important -} - -.border-top-0 { - border-top: 0 !important -} - -.border-end { - border-right: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important -} - -.border-end-0 { - border-right: 0 !important -} - -.border-bottom { - border-bottom: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important -} - -.border-bottom-0 { - border-bottom: 0 !important -} - -.border-start { - border-left: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important -} - -.border-start-0 { - border-left: 0 !important -} - -.border-primary { - --bs-border-opacity: 1; - border-color: rgba(var(--bs-primary-rgb), var(--bs-border-opacity)) !important -} - -.border-secondary { - --bs-border-opacity: 1; - border-color: rgba(var(--bs-secondary-rgb), var(--bs-border-opacity)) !important -} - -.border-success { - --bs-border-opacity: 1; - border-color: rgba(var(--bs-success-rgb), var(--bs-border-opacity)) !important -} - -.border-info { - --bs-border-opacity: 1; - border-color: rgba(var(--bs-info-rgb), var(--bs-border-opacity)) !important -} - -.border-warning { - --bs-border-opacity: 1; - border-color: rgba(var(--bs-warning-rgb), var(--bs-border-opacity)) !important -} - -.border-danger { - --bs-border-opacity: 1; - border-color: rgba(var(--bs-danger-rgb), var(--bs-border-opacity)) !important -} - -.border-light { - --bs-border-opacity: 1; - border-color: rgba(var(--bs-light-rgb), var(--bs-border-opacity)) !important -} - -.border-dark { - --bs-border-opacity: 1; - border-color: rgba(var(--bs-dark-rgb), var(--bs-border-opacity)) !important -} - -.border-white { - --bs-border-opacity: 1; - border-color: rgba(var(--bs-white-rgb), var(--bs-border-opacity)) !important -} - -.border-1 { - --bs-border-width: 1px -} - -.border-2 { - --bs-border-width: 2px -} - -.border-3 { - --bs-border-width: 3px -} - -.border-4 { - --bs-border-width: 4px -} - -.border-5 { - --bs-border-width: 5px -} - -.border-opacity-10 { - --bs-border-opacity: 0.1 -} - -.border-opacity-25 { - --bs-border-opacity: 0.25 -} - -.border-opacity-50 { - --bs-border-opacity: 0.5 -} - -.border-opacity-75 { - --bs-border-opacity: 0.75 -} - -.border-opacity-100 { - --bs-border-opacity: 1 -} - -.w-25 { - width: 25% !important -} - -.w-50 { - width: 50% !important -} - -.w-75 { - width: 75% !important -} - -.w-100 { - width: 100% !important -} - -.w-auto { - width: auto !important -} - -.mw-100 { - max-width: 100% !important -} - -.vw-100 { - width: 100vw !important -} - -.min-vw-100 { - min-width: 100vw !important -} - -.h-25 { - height: 25% !important -} - -.h-50 { - height: 50% !important -} - -.h-75 { - height: 75% !important -} - -.h-100 { - height: 100% !important -} - -.h-auto { - height: auto !important -} - -.mh-100 { - max-height: 100% !important -} - -.vh-100 { - height: 100vh !important -} - -.min-vh-100 { - min-height: 100vh !important -} - -.flex-fill { - flex: 1 1 auto !important -} - -.flex-row { - flex-direction: row !important -} - -.flex-column { - flex-direction: column !important -} - -.flex-row-reverse { - flex-direction: row-reverse !important -} - -.flex-column-reverse { - flex-direction: column-reverse !important -} - -.flex-grow-0 { - flex-grow: 0 !important -} - -.flex-grow-1 { - flex-grow: 1 !important -} - -.flex-shrink-0 { - flex-shrink: 0 !important -} - -.flex-shrink-1 { - flex-shrink: 1 !important -} - -.flex-wrap { - flex-wrap: wrap !important -} - -.flex-nowrap { - flex-wrap: nowrap !important -} - -.flex-wrap-reverse { - flex-wrap: wrap-reverse !important -} - -.justify-content-start { - justify-content: flex-start !important -} - -.justify-content-end { - justify-content: flex-end !important -} - -.justify-content-center { - justify-content: center !important -} - -.justify-content-between { - justify-content: space-between !important -} - -.justify-content-around { - justify-content: space-around !important -} - -.justify-content-evenly { - justify-content: space-evenly !important -} - -.align-items-start { - align-items: flex-start !important -} - -.align-items-end { - align-items: flex-end !important -} - -.align-items-center { - align-items: center !important -} - -.align-items-baseline { - align-items: baseline !important -} - -.align-items-stretch { - align-items: stretch !important -} - -.align-content-start { - align-content: flex-start !important -} - -.align-content-end { - align-content: flex-end !important -} - -.align-content-center { - align-content: center !important -} - -.align-content-between { - align-content: space-between !important -} - -.align-content-around { - align-content: space-around !important -} - -.align-content-stretch { - align-content: stretch !important -} - -.align-self-auto { - align-self: auto !important -} - -.align-self-start { - align-self: flex-start !important -} - -.align-self-end { - align-self: flex-end !important -} - -.align-self-center { - align-self: center !important -} - -.align-self-baseline { - align-self: baseline !important -} - -.align-self-stretch { - align-self: stretch !important -} - -.order-first { - order: -1 !important -} - -.order-0 { - order: 0 !important -} - -.order-1 { - order: 1 !important -} - -.order-2 { - order: 2 !important -} - -.order-3 { - order: 3 !important -} - -.order-4 { - order: 4 !important -} - -.order-5 { - order: 5 !important -} - -.order-last { - order: 6 !important -} - -.m-0 { - margin: 0 !important -} - -.m-1 { - margin: .25rem !important -} - -.m-2 { - margin: .5rem !important -} - -.m-3 { - margin: 1rem !important -} - -.m-4 { - margin: 1.5rem !important -} - -.m-5 { - margin: 3rem !important -} - -.m-auto { - margin: auto !important -} - -.mx-0 { - margin-right: 0 !important; - margin-left: 0 !important -} - -.mx-1 { - margin-right: .25rem !important; - margin-left: .25rem !important -} - -.mx-2 { - margin-right: .5rem !important; - margin-left: .5rem !important -} - -.mx-3 { - margin-right: 1rem !important; - margin-left: 1rem !important -} - -.mx-4 { - margin-right: 1.5rem !important; - margin-left: 1.5rem !important -} - -.mx-5 { - margin-right: 3rem !important; - margin-left: 3rem !important -} - -.mx-auto { - margin-right: auto !important; - margin-left: auto !important -} - -.my-0 { - margin-top: 0 !important; - margin-bottom: 0 !important -} - -.my-1 { - margin-top: .25rem !important; - margin-bottom: .25rem !important -} - -.my-2 { - margin-top: .5rem !important; - margin-bottom: .5rem !important -} - -.my-3 { - margin-top: 1rem !important; - margin-bottom: 1rem !important -} - -.my-4 { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important -} - -.my-5 { - margin-top: 3rem !important; - margin-bottom: 3rem !important -} - -.my-auto { - margin-top: auto !important; - margin-bottom: auto !important -} - -.mt-0 { - margin-top: 0 !important -} - -.mt-1 { - margin-top: .25rem !important -} - -.mt-2 { - margin-top: .5rem !important -} - -.mt-3 { - margin-top: 1rem !important -} - -.mt-4 { - margin-top: 1.5rem !important -} - -.mt-5 { - margin-top: 3rem !important -} - -.mt-auto { - margin-top: auto !important -} - -.me-0 { - margin-right: 0 !important -} - -.me-1 { - margin-right: .25rem !important -} - -.me-2 { - margin-right: .5rem !important -} - -.me-3 { - margin-right: 1rem !important -} - -.me-4 { - margin-right: 1.5rem !important -} - -.me-5 { - margin-right: 3rem !important -} - -.me-auto { - margin-right: auto !important -} - -.mb-0 { - margin-bottom: 0 !important -} - -.mb-1 { - margin-bottom: .25rem !important -} - -.mb-2 { - margin-bottom: .5rem !important -} - -.mb-3 { - margin-bottom: 1rem !important -} - -.mb-4 { - margin-bottom: 1.5rem !important -} - -.mb-5 { - margin-bottom: 3rem !important -} - -.mb-auto { - margin-bottom: auto !important -} - -.ms-0 { - margin-left: 0 !important -} - -.ms-1 { - margin-left: .25rem !important -} - -.ms-2 { - margin-left: .5rem !important -} - -.ms-3 { - margin-left: 1rem !important -} - -.ms-4 { - margin-left: 1.5rem !important -} - -.ms-5 { - margin-left: 3rem !important -} - -.ms-auto { - margin-left: auto !important -} - -.p-0 { - padding: 0 !important -} - -.p-1 { - padding: .25rem !important -} - -.p-2 { - padding: .5rem !important -} - -.p-3 { - padding: 1rem !important -} - -.p-4 { - padding: 1.5rem !important -} - -.p-5 { - padding: 3rem !important -} - -.px-0 { - padding-right: 0 !important; - padding-left: 0 !important -} - -.px-1 { - padding-right: .25rem !important; - padding-left: .25rem !important -} - -.px-2 { - padding-right: .5rem !important; - padding-left: .5rem !important -} - -.px-3 { - padding-right: 1rem !important; - padding-left: 1rem !important -} - -.px-4 { - padding-right: 1.5rem !important; - padding-left: 1.5rem !important -} - -.px-5 { - padding-right: 3rem !important; - padding-left: 3rem !important -} - -.py-0 { - padding-top: 0 !important; - padding-bottom: 0 !important -} - -.py-1 { - padding-top: .25rem !important; - padding-bottom: .25rem !important -} - -.py-2 { - padding-top: .5rem !important; - padding-bottom: .5rem !important -} - -.py-3 { - padding-top: 1rem !important; - padding-bottom: 1rem !important -} - -.py-4 { - padding-top: 1.5rem !important; - padding-bottom: 1.5rem !important -} - -.py-5 { - padding-top: 3rem !important; - padding-bottom: 3rem !important -} - -.pt-0 { - padding-top: 0 !important -} - -.pt-1 { - padding-top: .25rem !important -} - -.pt-2 { - padding-top: .5rem !important -} - -.pt-3 { - padding-top: 1rem !important -} - -.pt-4 { - padding-top: 1.5rem !important -} - -.pt-5 { - padding-top: 3rem !important -} - -.pe-0 { - padding-right: 0 !important -} - -.pe-1 { - padding-right: .25rem !important -} - -.pe-2 { - padding-right: .5rem !important -} - -.pe-3 { - padding-right: 1rem !important -} - -.pe-4 { - padding-right: 1.5rem !important -} - -.pe-5 { - padding-right: 3rem !important -} - -.pb-0 { - padding-bottom: 0 !important -} - -.pb-1 { - padding-bottom: .25rem !important -} - -.pb-2 { - padding-bottom: .5rem !important -} - -.pb-3 { - padding-bottom: 1rem !important -} - -.pb-4 { - padding-bottom: 1.5rem !important -} - -.pb-5 { - padding-bottom: 3rem !important -} - -.ps-0 { - padding-left: 0 !important -} - -.ps-1 { - padding-left: .25rem !important -} - -.ps-2 { - padding-left: .5rem !important -} - -.ps-3 { - padding-left: 1rem !important -} - -.ps-4 { - padding-left: 1.5rem !important -} - -.ps-5 { - padding-left: 3rem !important -} - -.gap-0 { - gap: 0 !important -} - -.gap-1 { - gap: .25rem !important -} - -.gap-2 { - gap: .5rem !important -} - -.gap-3 { - gap: 1rem !important -} - -.gap-4 { - gap: 1.5rem !important -} - -.gap-5 { - gap: 3rem !important -} - -.font-monospace { - font-family: var(--bs-font-monospace) !important -} - -.fs-1 { - font-size: calc(1.425rem + 2.1vw) !important -} - -.fs-2 { - font-size: calc(1.375rem + 1.5vw) !important -} - -.fs-3 { - font-size: calc(1.325rem + .9vw) !important -} - -.fs-4 { - font-size: calc(1.275rem + .3vw) !important -} - -.fs-5 { - font-size: 1.25rem !important -} - -.fs-6 { - font-size: 1rem !important -} - -.fst-italic { - font-style: italic !important -} - -.fst-normal { - font-style: normal !important -} - -.fw-light { - font-weight: 300 !important -} - -.fw-lighter { - font-weight: lighter !important -} - -.fw-normal { - font-weight: 400 !important -} - -.fw-bold { - font-weight: 700 !important -} - -.fw-semibold { - font-weight: 600 !important -} - -.fw-bolder { - font-weight: bolder !important -} - -.lh-1 { - line-height: 1 !important -} - -.lh-sm { - line-height: 1.25 !important -} - -.lh-base { - line-height: 1.5 !important -} - -.lh-lg { - line-height: 2 !important -} - -.text-start { - text-align: left !important -} - -.text-end { - text-align: right !important -} - -.text-center { - text-align: center !important -} - -.text-decoration-none { - text-decoration: none !important -} - -.text-decoration-underline { - text-decoration: underline !important -} - -.text-decoration-line-through { - text-decoration: line-through !important -} - -.text-lowercase { - text-transform: lowercase !important -} - -.text-uppercase { - text-transform: uppercase !important -} - -.text-capitalize { - text-transform: capitalize !important -} - -.text-wrap { - white-space: normal !important -} - -.text-nowrap { - white-space: nowrap !important -} - -.text-break { - word-wrap: break-word !important; - word-break: break-word !important -} - -.text-primary { - --bs-text-opacity: 1; - color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important -} - -.text-secondary { - --bs-text-opacity: 1; - color: rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important -} - -.text-success { - --bs-text-opacity: 1; - color: rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important -} - -.text-info { - --bs-text-opacity: 1; - color: rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important -} - -.text-warning { - --bs-text-opacity: 1; - color: rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important -} - -.text-danger { - --bs-text-opacity: 1; - color: rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important -} - -.text-light { - --bs-text-opacity: 1; - color: rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important -} - -.text-dark { - --bs-text-opacity: 1; - color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important -} - -.text-black { - --bs-text-opacity: 1; - color: rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important -} - -.text-white { - --bs-text-opacity: 1; - color: rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important -} - -.text-body { - --bs-text-opacity: 1; - color: rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important -} - -.text-muted { - --bs-text-opacity: 1; - color: #888 !important -} - -.text-black-50 { - --bs-text-opacity: 1; - color: rgba(0, 0, 0, .5) !important -} - -.text-white-50 { - --bs-text-opacity: 1; - color: rgba(255, 255, 255, .5) !important -} - -.text-reset { - --bs-text-opacity: 1; - color: inherit !important -} - -.text-opacity-25 { - --bs-text-opacity: 0.25 -} - -.text-opacity-50 { - --bs-text-opacity: 0.5 -} - -.text-opacity-75 { - --bs-text-opacity: 0.75 -} - -.text-opacity-100 { - --bs-text-opacity: 1 -} - -.bg-primary { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important -} - -.bg-secondary { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important -} - -.bg-success { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important -} - -.bg-info { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important -} - -.bg-warning { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important -} - -.bg-danger { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important -} - -.bg-light { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important -} - -.bg-dark { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important -} - -.bg-black { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important -} - -.bg-white { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important -} - -.bg-body { - --bs-bg-opacity: 1; - background-color: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important -} - -.bg-transparent { - --bs-bg-opacity: 1; - background-color: transparent !important -} - -.bg-opacity-10 { - --bs-bg-opacity: 0.1 -} - -.bg-opacity-25 { - --bs-bg-opacity: 0.25 -} - -.bg-opacity-50 { - --bs-bg-opacity: 0.5 -} - -.bg-opacity-75 { - --bs-bg-opacity: 0.75 -} - -.bg-opacity-100 { - --bs-bg-opacity: 1 -} - -.bg-gradient { - background-image: var(--bs-gradient) !important -} - -.user-select-all { - -webkit-user-select: all !important; - -moz-user-select: all !important; - user-select: all !important -} - -.user-select-auto { - -webkit-user-select: auto !important; - -moz-user-select: auto !important; - user-select: auto !important -} - -.user-select-none { - -webkit-user-select: none !important; - -moz-user-select: none !important; - user-select: none !important -} - -.pe-none { - pointer-events: none !important -} - -.pe-auto { - pointer-events: auto !important -} - -.rounded { - border-radius: var(--bs-border-radius) !important -} - -.rounded-0 { - border-radius: 0 !important -} - -.rounded-1 { - border-radius: var(--bs-border-radius-sm) !important -} - -.rounded-2 { - border-radius: var(--bs-border-radius) !important -} - -.rounded-3 { - border-radius: var(--bs-border-radius-lg) !important -} - -.rounded-4 { - border-radius: var(--bs-border-radius-xl) !important -} - -.rounded-5 { - border-radius: var(--bs-border-radius-2xl) !important -} - -.rounded-circle { - border-radius: 50% !important -} - -.rounded-pill { - border-radius: var(--bs-border-radius-pill) !important -} - -.rounded-top { - border-top-left-radius: var(--bs-border-radius) !important; - border-top-right-radius: var(--bs-border-radius) !important -} - -.rounded-end { - border-top-right-radius: var(--bs-border-radius) !important; - border-bottom-right-radius: var(--bs-border-radius) !important -} - -.rounded-bottom { - border-bottom-right-radius: var(--bs-border-radius) !important; - border-bottom-left-radius: var(--bs-border-radius) !important -} - -.rounded-start { - border-bottom-left-radius: var(--bs-border-radius) !important; - border-top-left-radius: var(--bs-border-radius) !important -} - -.visible { - visibility: visible !important -} - -.invisible { - visibility: hidden !important -} - -@media (min-width: 576px) { - .float-sm-start { - float: left !important - } - - .float-sm-end { - float: right !important - } - - .float-sm-none { - float: none !important - } - - .d-sm-inline { - display: inline !important - } - - .d-sm-inline-block { - display: inline-block !important - } - - .d-sm-block { - display: block !important - } - - .d-sm-grid { - display: grid !important - } - - .d-sm-table { - display: table !important - } - - .d-sm-table-row { - display: table-row !important - } - - .d-sm-table-cell { - display: table-cell !important - } - - .d-sm-flex { - display: flex !important - } - - .d-sm-inline-flex { - display: inline-flex !important - } - - .d-sm-none { - display: none !important - } - - .flex-sm-fill { - flex: 1 1 auto !important - } - - .flex-sm-row { - flex-direction: row !important - } - - .flex-sm-column { - flex-direction: column !important - } - - .flex-sm-row-reverse { - flex-direction: row-reverse !important - } - - .flex-sm-column-reverse { - flex-direction: column-reverse !important - } - - .flex-sm-grow-0 { - flex-grow: 0 !important - } - - .flex-sm-grow-1 { - flex-grow: 1 !important - } - - .flex-sm-shrink-0 { - flex-shrink: 0 !important - } - - .flex-sm-shrink-1 { - flex-shrink: 1 !important - } - - .flex-sm-wrap { - flex-wrap: wrap !important - } - - .flex-sm-nowrap { - flex-wrap: nowrap !important - } - - .flex-sm-wrap-reverse { - flex-wrap: wrap-reverse !important - } - - .justify-content-sm-start { - justify-content: flex-start !important - } - - .justify-content-sm-end { - justify-content: flex-end !important - } - - .justify-content-sm-center { - justify-content: center !important - } - - .justify-content-sm-between { - justify-content: space-between !important - } - - .justify-content-sm-around { - justify-content: space-around !important - } - - .justify-content-sm-evenly { - justify-content: space-evenly !important - } - - .align-items-sm-start { - align-items: flex-start !important - } - - .align-items-sm-end { - align-items: flex-end !important - } - - .align-items-sm-center { - align-items: center !important - } - - .align-items-sm-baseline { - align-items: baseline !important - } - - .align-items-sm-stretch { - align-items: stretch !important - } - - .align-content-sm-start { - align-content: flex-start !important - } - - .align-content-sm-end { - align-content: flex-end !important - } - - .align-content-sm-center { - align-content: center !important - } - - .align-content-sm-between { - align-content: space-between !important - } - - .align-content-sm-around { - align-content: space-around !important - } - - .align-content-sm-stretch { - align-content: stretch !important - } - - .align-self-sm-auto { - align-self: auto !important - } - - .align-self-sm-start { - align-self: flex-start !important - } - - .align-self-sm-end { - align-self: flex-end !important - } - - .align-self-sm-center { - align-self: center !important - } - - .align-self-sm-baseline { - align-self: baseline !important - } - - .align-self-sm-stretch { - align-self: stretch !important - } - - .order-sm-first { - order: -1 !important - } - - .order-sm-0 { - order: 0 !important - } - - .order-sm-1 { - order: 1 !important - } - - .order-sm-2 { - order: 2 !important - } - - .order-sm-3 { - order: 3 !important - } - - .order-sm-4 { - order: 4 !important - } - - .order-sm-5 { - order: 5 !important - } - - .order-sm-last { - order: 6 !important - } - - .m-sm-0 { - margin: 0 !important - } - - .m-sm-1 { - margin: .25rem !important - } - - .m-sm-2 { - margin: .5rem !important - } - - .m-sm-3 { - margin: 1rem !important - } - - .m-sm-4 { - margin: 1.5rem !important - } - - .m-sm-5 { - margin: 3rem !important - } - - .m-sm-auto { - margin: auto !important - } - - .mx-sm-0 { - margin-right: 0 !important; - margin-left: 0 !important - } - - .mx-sm-1 { - margin-right: .25rem !important; - margin-left: .25rem !important - } - - .mx-sm-2 { - margin-right: .5rem !important; - margin-left: .5rem !important - } - - .mx-sm-3 { - margin-right: 1rem !important; - margin-left: 1rem !important - } - - .mx-sm-4 { - margin-right: 1.5rem !important; - margin-left: 1.5rem !important - } - - .mx-sm-5 { - margin-right: 3rem !important; - margin-left: 3rem !important - } - - .mx-sm-auto { - margin-right: auto !important; - margin-left: auto !important - } - - .my-sm-0 { - margin-top: 0 !important; - margin-bottom: 0 !important - } - - .my-sm-1 { - margin-top: .25rem !important; - margin-bottom: .25rem !important - } - - .my-sm-2 { - margin-top: .5rem !important; - margin-bottom: .5rem !important - } - - .my-sm-3 { - margin-top: 1rem !important; - margin-bottom: 1rem !important - } - - .my-sm-4 { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important - } - - .my-sm-5 { - margin-top: 3rem !important; - margin-bottom: 3rem !important - } - - .my-sm-auto { - margin-top: auto !important; - margin-bottom: auto !important - } - - .mt-sm-0 { - margin-top: 0 !important - } - - .mt-sm-1 { - margin-top: .25rem !important - } - - .mt-sm-2 { - margin-top: .5rem !important - } - - .mt-sm-3 { - margin-top: 1rem !important - } - - .mt-sm-4 { - margin-top: 1.5rem !important - } - - .mt-sm-5 { - margin-top: 3rem !important - } - - .mt-sm-auto { - margin-top: auto !important - } - - .me-sm-0 { - margin-right: 0 !important - } - - .me-sm-1 { - margin-right: .25rem !important - } - - .me-sm-2 { - margin-right: .5rem !important - } - - .me-sm-3 { - margin-right: 1rem !important - } - - .me-sm-4 { - margin-right: 1.5rem !important - } - - .me-sm-5 { - margin-right: 3rem !important - } - - .me-sm-auto { - margin-right: auto !important - } - - .mb-sm-0 { - margin-bottom: 0 !important - } - - .mb-sm-1 { - margin-bottom: .25rem !important - } - - .mb-sm-2 { - margin-bottom: .5rem !important - } - - .mb-sm-3 { - margin-bottom: 1rem !important - } - - .mb-sm-4 { - margin-bottom: 1.5rem !important - } - - .mb-sm-5 { - margin-bottom: 3rem !important - } - - .mb-sm-auto { - margin-bottom: auto !important - } - - .ms-sm-0 { - margin-left: 0 !important - } - - .ms-sm-1 { - margin-left: .25rem !important - } - - .ms-sm-2 { - margin-left: .5rem !important - } - - .ms-sm-3 { - margin-left: 1rem !important - } - - .ms-sm-4 { - margin-left: 1.5rem !important - } - - .ms-sm-5 { - margin-left: 3rem !important - } - - .ms-sm-auto { - margin-left: auto !important - } - - .p-sm-0 { - padding: 0 !important - } - - .p-sm-1 { - padding: .25rem !important - } - - .p-sm-2 { - padding: .5rem !important - } - - .p-sm-3 { - padding: 1rem !important - } - - .p-sm-4 { - padding: 1.5rem !important - } - - .p-sm-5 { - padding: 3rem !important - } - - .px-sm-0 { - padding-right: 0 !important; - padding-left: 0 !important - } - - .px-sm-1 { - padding-right: .25rem !important; - padding-left: .25rem !important - } - - .px-sm-2 { - padding-right: .5rem !important; - padding-left: .5rem !important - } - - .px-sm-3 { - padding-right: 1rem !important; - padding-left: 1rem !important - } - - .px-sm-4 { - padding-right: 1.5rem !important; - padding-left: 1.5rem !important - } - - .px-sm-5 { - padding-right: 3rem !important; - padding-left: 3rem !important - } - - .py-sm-0 { - padding-top: 0 !important; - padding-bottom: 0 !important - } - - .py-sm-1 { - padding-top: .25rem !important; - padding-bottom: .25rem !important - } - - .py-sm-2 { - padding-top: .5rem !important; - padding-bottom: .5rem !important - } - - .py-sm-3 { - padding-top: 1rem !important; - padding-bottom: 1rem !important - } - - .py-sm-4 { - padding-top: 1.5rem !important; - padding-bottom: 1.5rem !important - } - - .py-sm-5 { - padding-top: 3rem !important; - padding-bottom: 3rem !important - } - - .pt-sm-0 { - padding-top: 0 !important - } - - .pt-sm-1 { - padding-top: .25rem !important - } - - .pt-sm-2 { - padding-top: .5rem !important - } - - .pt-sm-3 { - padding-top: 1rem !important - } - - .pt-sm-4 { - padding-top: 1.5rem !important - } - - .pt-sm-5 { - padding-top: 3rem !important - } - - .pe-sm-0 { - padding-right: 0 !important - } - - .pe-sm-1 { - padding-right: .25rem !important - } - - .pe-sm-2 { - padding-right: .5rem !important - } - - .pe-sm-3 { - padding-right: 1rem !important - } - - .pe-sm-4 { - padding-right: 1.5rem !important - } - - .pe-sm-5 { - padding-right: 3rem !important - } - - .pb-sm-0 { - padding-bottom: 0 !important - } - - .pb-sm-1 { - padding-bottom: .25rem !important - } - - .pb-sm-2 { - padding-bottom: .5rem !important - } - - .pb-sm-3 { - padding-bottom: 1rem !important - } - - .pb-sm-4 { - padding-bottom: 1.5rem !important - } - - .pb-sm-5 { - padding-bottom: 3rem !important - } - - .ps-sm-0 { - padding-left: 0 !important - } - - .ps-sm-1 { - padding-left: .25rem !important - } - - .ps-sm-2 { - padding-left: .5rem !important - } - - .ps-sm-3 { - padding-left: 1rem !important - } - - .ps-sm-4 { - padding-left: 1.5rem !important - } - - .ps-sm-5 { - padding-left: 3rem !important - } - - .gap-sm-0 { - gap: 0 !important - } - - .gap-sm-1 { - gap: .25rem !important - } - - .gap-sm-2 { - gap: .5rem !important - } - - .gap-sm-3 { - gap: 1rem !important - } - - .gap-sm-4 { - gap: 1.5rem !important - } - - .gap-sm-5 { - gap: 3rem !important - } - - .text-sm-start { - text-align: left !important - } - - .text-sm-end { - text-align: right !important - } - - .text-sm-center { - text-align: center !important - } -} - -@media (min-width: 768px) { - .float-md-start { - float: left !important - } - - .float-md-end { - float: right !important - } - - .float-md-none { - float: none !important - } - - .d-md-inline { - display: inline !important - } - - .d-md-inline-block { - display: inline-block !important - } - - .d-md-block { - display: block !important - } - - .d-md-grid { - display: grid !important - } - - .d-md-table { - display: table !important - } - - .d-md-table-row { - display: table-row !important - } - - .d-md-table-cell { - display: table-cell !important - } - - .d-md-flex { - display: flex !important - } - - .d-md-inline-flex { - display: inline-flex !important - } - - .d-md-none { - display: none !important - } - - .flex-md-fill { - flex: 1 1 auto !important - } - - .flex-md-row { - flex-direction: row !important - } - - .flex-md-column { - flex-direction: column !important - } - - .flex-md-row-reverse { - flex-direction: row-reverse !important - } - - .flex-md-column-reverse { - flex-direction: column-reverse !important - } - - .flex-md-grow-0 { - flex-grow: 0 !important - } - - .flex-md-grow-1 { - flex-grow: 1 !important - } - - .flex-md-shrink-0 { - flex-shrink: 0 !important - } - - .flex-md-shrink-1 { - flex-shrink: 1 !important - } - - .flex-md-wrap { - flex-wrap: wrap !important - } - - .flex-md-nowrap { - flex-wrap: nowrap !important - } - - .flex-md-wrap-reverse { - flex-wrap: wrap-reverse !important - } - - .justify-content-md-start { - justify-content: flex-start !important - } - - .justify-content-md-end { - justify-content: flex-end !important - } - - .justify-content-md-center { - justify-content: center !important - } - - .justify-content-md-between { - justify-content: space-between !important - } - - .justify-content-md-around { - justify-content: space-around !important - } - - .justify-content-md-evenly { - justify-content: space-evenly !important - } - - .align-items-md-start { - align-items: flex-start !important - } - - .align-items-md-end { - align-items: flex-end !important - } - - .align-items-md-center { - align-items: center !important - } - - .align-items-md-baseline { - align-items: baseline !important - } - - .align-items-md-stretch { - align-items: stretch !important - } - - .align-content-md-start { - align-content: flex-start !important - } - - .align-content-md-end { - align-content: flex-end !important - } - - .align-content-md-center { - align-content: center !important - } - - .align-content-md-between { - align-content: space-between !important - } - - .align-content-md-around { - align-content: space-around !important - } - - .align-content-md-stretch { - align-content: stretch !important - } - - .align-self-md-auto { - align-self: auto !important - } - - .align-self-md-start { - align-self: flex-start !important - } - - .align-self-md-end { - align-self: flex-end !important - } - - .align-self-md-center { - align-self: center !important - } - - .align-self-md-baseline { - align-self: baseline !important - } - - .align-self-md-stretch { - align-self: stretch !important - } - - .order-md-first { - order: -1 !important - } - - .order-md-0 { - order: 0 !important - } - - .order-md-1 { - order: 1 !important - } - - .order-md-2 { - order: 2 !important - } - - .order-md-3 { - order: 3 !important - } - - .order-md-4 { - order: 4 !important - } - - .order-md-5 { - order: 5 !important - } - - .order-md-last { - order: 6 !important - } - - .m-md-0 { - margin: 0 !important - } - - .m-md-1 { - margin: .25rem !important - } - - .m-md-2 { - margin: .5rem !important - } - - .m-md-3 { - margin: 1rem !important - } - - .m-md-4 { - margin: 1.5rem !important - } - - .m-md-5 { - margin: 3rem !important - } - - .m-md-auto { - margin: auto !important - } - - .mx-md-0 { - margin-right: 0 !important; - margin-left: 0 !important - } - - .mx-md-1 { - margin-right: .25rem !important; - margin-left: .25rem !important - } - - .mx-md-2 { - margin-right: .5rem !important; - margin-left: .5rem !important - } - - .mx-md-3 { - margin-right: 1rem !important; - margin-left: 1rem !important - } - - .mx-md-4 { - margin-right: 1.5rem !important; - margin-left: 1.5rem !important - } - - .mx-md-5 { - margin-right: 3rem !important; - margin-left: 3rem !important - } - - .mx-md-auto { - margin-right: auto !important; - margin-left: auto !important - } - - .my-md-0 { - margin-top: 0 !important; - margin-bottom: 0 !important - } - - .my-md-1 { - margin-top: .25rem !important; - margin-bottom: .25rem !important - } - - .my-md-2 { - margin-top: .5rem !important; - margin-bottom: .5rem !important - } - - .my-md-3 { - margin-top: 1rem !important; - margin-bottom: 1rem !important - } - - .my-md-4 { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important - } - - .my-md-5 { - margin-top: 3rem !important; - margin-bottom: 3rem !important - } - - .my-md-auto { - margin-top: auto !important; - margin-bottom: auto !important - } - - .mt-md-0 { - margin-top: 0 !important - } - - .mt-md-1 { - margin-top: .25rem !important - } - - .mt-md-2 { - margin-top: .5rem !important - } - - .mt-md-3 { - margin-top: 1rem !important - } - - .mt-md-4 { - margin-top: 1.5rem !important - } - - .mt-md-5 { - margin-top: 3rem !important - } - - .mt-md-auto { - margin-top: auto !important - } - - .me-md-0 { - margin-right: 0 !important - } - - .me-md-1 { - margin-right: .25rem !important - } - - .me-md-2 { - margin-right: .5rem !important - } - - .me-md-3 { - margin-right: 1rem !important - } - - .me-md-4 { - margin-right: 1.5rem !important - } - - .me-md-5 { - margin-right: 3rem !important - } - - .me-md-auto { - margin-right: auto !important - } - - .mb-md-0 { - margin-bottom: 0 !important - } - - .mb-md-1 { - margin-bottom: .25rem !important - } - - .mb-md-2 { - margin-bottom: .5rem !important - } - - .mb-md-3 { - margin-bottom: 1rem !important - } - - .mb-md-4 { - margin-bottom: 1.5rem !important - } - - .mb-md-5 { - margin-bottom: 3rem !important - } - - .mb-md-auto { - margin-bottom: auto !important - } - - .ms-md-0 { - margin-left: 0 !important - } - - .ms-md-1 { - margin-left: .25rem !important - } - - .ms-md-2 { - margin-left: .5rem !important - } - - .ms-md-3 { - margin-left: 1rem !important - } - - .ms-md-4 { - margin-left: 1.5rem !important - } - - .ms-md-5 { - margin-left: 3rem !important - } - - .ms-md-auto { - margin-left: auto !important - } - - .p-md-0 { - padding: 0 !important - } - - .p-md-1 { - padding: .25rem !important - } - - .p-md-2 { - padding: .5rem !important - } - - .p-md-3 { - padding: 1rem !important - } - - .p-md-4 { - padding: 1.5rem !important - } - - .p-md-5 { - padding: 3rem !important - } - - .px-md-0 { - padding-right: 0 !important; - padding-left: 0 !important - } - - .px-md-1 { - padding-right: .25rem !important; - padding-left: .25rem !important - } - - .px-md-2 { - padding-right: .5rem !important; - padding-left: .5rem !important - } - - .px-md-3 { - padding-right: 1rem !important; - padding-left: 1rem !important - } - - .px-md-4 { - padding-right: 1.5rem !important; - padding-left: 1.5rem !important - } - - .px-md-5 { - padding-right: 3rem !important; - padding-left: 3rem !important - } - - .py-md-0 { - padding-top: 0 !important; - padding-bottom: 0 !important - } - - .py-md-1 { - padding-top: .25rem !important; - padding-bottom: .25rem !important - } - - .py-md-2 { - padding-top: .5rem !important; - padding-bottom: .5rem !important - } - - .py-md-3 { - padding-top: 1rem !important; - padding-bottom: 1rem !important - } - - .py-md-4 { - padding-top: 1.5rem !important; - padding-bottom: 1.5rem !important - } - - .py-md-5 { - padding-top: 3rem !important; - padding-bottom: 3rem !important - } - - .pt-md-0 { - padding-top: 0 !important - } - - .pt-md-1 { - padding-top: .25rem !important - } - - .pt-md-2 { - padding-top: .5rem !important - } - - .pt-md-3 { - padding-top: 1rem !important - } - - .pt-md-4 { - padding-top: 1.5rem !important - } - - .pt-md-5 { - padding-top: 3rem !important - } - - .pe-md-0 { - padding-right: 0 !important - } - - .pe-md-1 { - padding-right: .25rem !important - } - - .pe-md-2 { - padding-right: .5rem !important - } - - .pe-md-3 { - padding-right: 1rem !important - } - - .pe-md-4 { - padding-right: 1.5rem !important - } - - .pe-md-5 { - padding-right: 3rem !important - } - - .pb-md-0 { - padding-bottom: 0 !important - } - - .pb-md-1 { - padding-bottom: .25rem !important - } - - .pb-md-2 { - padding-bottom: .5rem !important - } - - .pb-md-3 { - padding-bottom: 1rem !important - } - - .pb-md-4 { - padding-bottom: 1.5rem !important - } - - .pb-md-5 { - padding-bottom: 3rem !important - } - - .ps-md-0 { - padding-left: 0 !important - } - - .ps-md-1 { - padding-left: .25rem !important - } - - .ps-md-2 { - padding-left: .5rem !important - } - - .ps-md-3 { - padding-left: 1rem !important - } - - .ps-md-4 { - padding-left: 1.5rem !important - } - - .ps-md-5 { - padding-left: 3rem !important - } - - .gap-md-0 { - gap: 0 !important - } - - .gap-md-1 { - gap: .25rem !important - } - - .gap-md-2 { - gap: .5rem !important - } - - .gap-md-3 { - gap: 1rem !important - } - - .gap-md-4 { - gap: 1.5rem !important - } - - .gap-md-5 { - gap: 3rem !important - } - - .text-md-start { - text-align: left !important - } - - .text-md-end { - text-align: right !important - } - - .text-md-center { - text-align: center !important - } -} - -@media (min-width: 992px) { - .float-lg-start { - float: left !important - } - - .float-lg-end { - float: right !important - } - - .float-lg-none { - float: none !important - } - - .d-lg-inline { - display: inline !important - } - - .d-lg-inline-block { - display: inline-block !important - } - - .d-lg-block { - display: block !important - } - - .d-lg-grid { - display: grid !important - } - - .d-lg-table { - display: table !important - } - - .d-lg-table-row { - display: table-row !important - } - - .d-lg-table-cell { - display: table-cell !important - } - - .d-lg-flex { - display: flex !important - } - - .d-lg-inline-flex { - display: inline-flex !important - } - - .d-lg-none { - display: none !important - } - - .flex-lg-fill { - flex: 1 1 auto !important - } - - .flex-lg-row { - flex-direction: row !important - } - - .flex-lg-column { - flex-direction: column !important - } - - .flex-lg-row-reverse { - flex-direction: row-reverse !important - } - - .flex-lg-column-reverse { - flex-direction: column-reverse !important - } - - .flex-lg-grow-0 { - flex-grow: 0 !important - } - - .flex-lg-grow-1 { - flex-grow: 1 !important - } - - .flex-lg-shrink-0 { - flex-shrink: 0 !important - } - - .flex-lg-shrink-1 { - flex-shrink: 1 !important - } - - .flex-lg-wrap { - flex-wrap: wrap !important - } - - .flex-lg-nowrap { - flex-wrap: nowrap !important - } - - .flex-lg-wrap-reverse { - flex-wrap: wrap-reverse !important - } - - .justify-content-lg-start { - justify-content: flex-start !important - } - - .justify-content-lg-end { - justify-content: flex-end !important - } - - .justify-content-lg-center { - justify-content: center !important - } - - .justify-content-lg-between { - justify-content: space-between !important - } - - .justify-content-lg-around { - justify-content: space-around !important - } - - .justify-content-lg-evenly { - justify-content: space-evenly !important - } - - .align-items-lg-start { - align-items: flex-start !important - } - - .align-items-lg-end { - align-items: flex-end !important - } - - .align-items-lg-center { - align-items: center !important - } - - .align-items-lg-baseline { - align-items: baseline !important - } - - .align-items-lg-stretch { - align-items: stretch !important - } - - .align-content-lg-start { - align-content: flex-start !important - } - - .align-content-lg-end { - align-content: flex-end !important - } - - .align-content-lg-center { - align-content: center !important - } - - .align-content-lg-between { - align-content: space-between !important - } - - .align-content-lg-around { - align-content: space-around !important - } - - .align-content-lg-stretch { - align-content: stretch !important - } - - .align-self-lg-auto { - align-self: auto !important - } - - .align-self-lg-start { - align-self: flex-start !important - } - - .align-self-lg-end { - align-self: flex-end !important - } - - .align-self-lg-center { - align-self: center !important - } - - .align-self-lg-baseline { - align-self: baseline !important - } - - .align-self-lg-stretch { - align-self: stretch !important - } - - .order-lg-first { - order: -1 !important - } - - .order-lg-0 { - order: 0 !important - } - - .order-lg-1 { - order: 1 !important - } - - .order-lg-2 { - order: 2 !important - } - - .order-lg-3 { - order: 3 !important - } - - .order-lg-4 { - order: 4 !important - } - - .order-lg-5 { - order: 5 !important - } - - .order-lg-last { - order: 6 !important - } - - .m-lg-0 { - margin: 0 !important - } - - .m-lg-1 { - margin: .25rem !important - } - - .m-lg-2 { - margin: .5rem !important - } - - .m-lg-3 { - margin: 1rem !important - } - - .m-lg-4 { - margin: 1.5rem !important - } - - .m-lg-5 { - margin: 3rem !important - } - - .m-lg-auto { - margin: auto !important - } - - .mx-lg-0 { - margin-right: 0 !important; - margin-left: 0 !important - } - - .mx-lg-1 { - margin-right: .25rem !important; - margin-left: .25rem !important - } - - .mx-lg-2 { - margin-right: .5rem !important; - margin-left: .5rem !important - } - - .mx-lg-3 { - margin-right: 1rem !important; - margin-left: 1rem !important - } - - .mx-lg-4 { - margin-right: 1.5rem !important; - margin-left: 1.5rem !important - } - - .mx-lg-5 { - margin-right: 3rem !important; - margin-left: 3rem !important - } - - .mx-lg-auto { - margin-right: auto !important; - margin-left: auto !important - } - - .my-lg-0 { - margin-top: 0 !important; - margin-bottom: 0 !important - } - - .my-lg-1 { - margin-top: .25rem !important; - margin-bottom: .25rem !important - } - - .my-lg-2 { - margin-top: .5rem !important; - margin-bottom: .5rem !important - } - - .my-lg-3 { - margin-top: 1rem !important; - margin-bottom: 1rem !important - } - - .my-lg-4 { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important - } - - .my-lg-5 { - margin-top: 3rem !important; - margin-bottom: 3rem !important - } - - .my-lg-auto { - margin-top: auto !important; - margin-bottom: auto !important - } - - .mt-lg-0 { - margin-top: 0 !important - } - - .mt-lg-1 { - margin-top: .25rem !important - } - - .mt-lg-2 { - margin-top: .5rem !important - } - - .mt-lg-3 { - margin-top: 1rem !important - } - - .mt-lg-4 { - margin-top: 1.5rem !important - } - - .mt-lg-5 { - margin-top: 3rem !important - } - - .mt-lg-auto { - margin-top: auto !important - } - - .me-lg-0 { - margin-right: 0 !important - } - - .me-lg-1 { - margin-right: .25rem !important - } - - .me-lg-2 { - margin-right: .5rem !important - } - - .me-lg-3 { - margin-right: 1rem !important - } - - .me-lg-4 { - margin-right: 1.5rem !important - } - - .me-lg-5 { - margin-right: 3rem !important - } - - .me-lg-auto { - margin-right: auto !important - } - - .mb-lg-0 { - margin-bottom: 0 !important - } - - .mb-lg-1 { - margin-bottom: .25rem !important - } - - .mb-lg-2 { - margin-bottom: .5rem !important - } - - .mb-lg-3 { - margin-bottom: 1rem !important - } - - .mb-lg-4 { - margin-bottom: 1.5rem !important - } - - .mb-lg-5 { - margin-bottom: 3rem !important - } - - .mb-lg-auto { - margin-bottom: auto !important - } - - .ms-lg-0 { - margin-left: 0 !important - } - - .ms-lg-1 { - margin-left: .25rem !important - } - - .ms-lg-2 { - margin-left: .5rem !important - } - - .ms-lg-3 { - margin-left: 1rem !important - } - - .ms-lg-4 { - margin-left: 1.5rem !important - } - - .ms-lg-5 { - margin-left: 3rem !important - } - - .ms-lg-auto { - margin-left: auto !important - } - - .p-lg-0 { - padding: 0 !important - } - - .p-lg-1 { - padding: .25rem !important - } - - .p-lg-2 { - padding: .5rem !important - } - - .p-lg-3 { - padding: 1rem !important - } - - .p-lg-4 { - padding: 1.5rem !important - } - - .p-lg-5 { - padding: 3rem !important - } - - .px-lg-0 { - padding-right: 0 !important; - padding-left: 0 !important - } - - .px-lg-1 { - padding-right: .25rem !important; - padding-left: .25rem !important - } - - .px-lg-2 { - padding-right: .5rem !important; - padding-left: .5rem !important - } - - .px-lg-3 { - padding-right: 1rem !important; - padding-left: 1rem !important - } - - .px-lg-4 { - padding-right: 1.5rem !important; - padding-left: 1.5rem !important - } - - .px-lg-5 { - padding-right: 3rem !important; - padding-left: 3rem !important - } - - .py-lg-0 { - padding-top: 0 !important; - padding-bottom: 0 !important - } - - .py-lg-1 { - padding-top: .25rem !important; - padding-bottom: .25rem !important - } - - .py-lg-2 { - padding-top: .5rem !important; - padding-bottom: .5rem !important - } - - .py-lg-3 { - padding-top: 1rem !important; - padding-bottom: 1rem !important - } - - .py-lg-4 { - padding-top: 1.5rem !important; - padding-bottom: 1.5rem !important - } - - .py-lg-5 { - padding-top: 3rem !important; - padding-bottom: 3rem !important - } - - .pt-lg-0 { - padding-top: 0 !important - } - - .pt-lg-1 { - padding-top: .25rem !important - } - - .pt-lg-2 { - padding-top: .5rem !important - } - - .pt-lg-3 { - padding-top: 1rem !important - } - - .pt-lg-4 { - padding-top: 1.5rem !important - } - - .pt-lg-5 { - padding-top: 3rem !important - } - - .pe-lg-0 { - padding-right: 0 !important - } - - .pe-lg-1 { - padding-right: .25rem !important - } - - .pe-lg-2 { - padding-right: .5rem !important - } - - .pe-lg-3 { - padding-right: 1rem !important - } - - .pe-lg-4 { - padding-right: 1.5rem !important - } - - .pe-lg-5 { - padding-right: 3rem !important - } - - .pb-lg-0 { - padding-bottom: 0 !important - } - - .pb-lg-1 { - padding-bottom: .25rem !important - } - - .pb-lg-2 { - padding-bottom: .5rem !important - } - - .pb-lg-3 { - padding-bottom: 1rem !important - } - - .pb-lg-4 { - padding-bottom: 1.5rem !important - } - - .pb-lg-5 { - padding-bottom: 3rem !important - } - - .ps-lg-0 { - padding-left: 0 !important - } - - .ps-lg-1 { - padding-left: .25rem !important - } - - .ps-lg-2 { - padding-left: .5rem !important - } - - .ps-lg-3 { - padding-left: 1rem !important - } - - .ps-lg-4 { - padding-left: 1.5rem !important - } - - .ps-lg-5 { - padding-left: 3rem !important - } - - .gap-lg-0 { - gap: 0 !important - } - - .gap-lg-1 { - gap: .25rem !important - } - - .gap-lg-2 { - gap: .5rem !important - } - - .gap-lg-3 { - gap: 1rem !important - } - - .gap-lg-4 { - gap: 1.5rem !important - } - - .gap-lg-5 { - gap: 3rem !important - } - - .text-lg-start { - text-align: left !important - } - - .text-lg-end { - text-align: right !important - } - - .text-lg-center { - text-align: center !important - } -} - -@media (min-width: 1200px) { - .float-xl-start { - float: left !important - } - - .float-xl-end { - float: right !important - } - - .float-xl-none { - float: none !important - } - - .d-xl-inline { - display: inline !important - } - - .d-xl-inline-block { - display: inline-block !important - } - - .d-xl-block { - display: block !important - } - - .d-xl-grid { - display: grid !important - } - - .d-xl-table { - display: table !important - } - - .d-xl-table-row { - display: table-row !important - } - - .d-xl-table-cell { - display: table-cell !important - } - - .d-xl-flex { - display: flex !important - } - - .d-xl-inline-flex { - display: inline-flex !important - } - - .d-xl-none { - display: none !important - } - - .flex-xl-fill { - flex: 1 1 auto !important - } - - .flex-xl-row { - flex-direction: row !important - } - - .flex-xl-column { - flex-direction: column !important - } - - .flex-xl-row-reverse { - flex-direction: row-reverse !important - } - - .flex-xl-column-reverse { - flex-direction: column-reverse !important - } - - .flex-xl-grow-0 { - flex-grow: 0 !important - } - - .flex-xl-grow-1 { - flex-grow: 1 !important - } - - .flex-xl-shrink-0 { - flex-shrink: 0 !important - } - - .flex-xl-shrink-1 { - flex-shrink: 1 !important - } - - .flex-xl-wrap { - flex-wrap: wrap !important - } - - .flex-xl-nowrap { - flex-wrap: nowrap !important - } - - .flex-xl-wrap-reverse { - flex-wrap: wrap-reverse !important - } - - .justify-content-xl-start { - justify-content: flex-start !important - } - - .justify-content-xl-end { - justify-content: flex-end !important - } - - .justify-content-xl-center { - justify-content: center !important - } - - .justify-content-xl-between { - justify-content: space-between !important - } - - .justify-content-xl-around { - justify-content: space-around !important - } - - .justify-content-xl-evenly { - justify-content: space-evenly !important - } - - .align-items-xl-start { - align-items: flex-start !important - } - - .align-items-xl-end { - align-items: flex-end !important - } - - .align-items-xl-center { - align-items: center !important - } - - .align-items-xl-baseline { - align-items: baseline !important - } - - .align-items-xl-stretch { - align-items: stretch !important - } - - .align-content-xl-start { - align-content: flex-start !important - } - - .align-content-xl-end { - align-content: flex-end !important - } - - .align-content-xl-center { - align-content: center !important - } - - .align-content-xl-between { - align-content: space-between !important - } - - .align-content-xl-around { - align-content: space-around !important - } - - .align-content-xl-stretch { - align-content: stretch !important - } - - .align-self-xl-auto { - align-self: auto !important - } - - .align-self-xl-start { - align-self: flex-start !important - } - - .align-self-xl-end { - align-self: flex-end !important - } - - .align-self-xl-center { - align-self: center !important - } - - .align-self-xl-baseline { - align-self: baseline !important - } - - .align-self-xl-stretch { - align-self: stretch !important - } - - .order-xl-first { - order: -1 !important - } - - .order-xl-0 { - order: 0 !important - } - - .order-xl-1 { - order: 1 !important - } - - .order-xl-2 { - order: 2 !important - } - - .order-xl-3 { - order: 3 !important - } - - .order-xl-4 { - order: 4 !important - } - - .order-xl-5 { - order: 5 !important - } - - .order-xl-last { - order: 6 !important - } - - .m-xl-0 { - margin: 0 !important - } - - .m-xl-1 { - margin: .25rem !important - } - - .m-xl-2 { - margin: .5rem !important - } - - .m-xl-3 { - margin: 1rem !important - } - - .m-xl-4 { - margin: 1.5rem !important - } - - .m-xl-5 { - margin: 3rem !important - } - - .m-xl-auto { - margin: auto !important - } - - .mx-xl-0 { - margin-right: 0 !important; - margin-left: 0 !important - } - - .mx-xl-1 { - margin-right: .25rem !important; - margin-left: .25rem !important - } - - .mx-xl-2 { - margin-right: .5rem !important; - margin-left: .5rem !important - } - - .mx-xl-3 { - margin-right: 1rem !important; - margin-left: 1rem !important - } - - .mx-xl-4 { - margin-right: 1.5rem !important; - margin-left: 1.5rem !important - } - - .mx-xl-5 { - margin-right: 3rem !important; - margin-left: 3rem !important - } - - .mx-xl-auto { - margin-right: auto !important; - margin-left: auto !important - } - - .my-xl-0 { - margin-top: 0 !important; - margin-bottom: 0 !important - } - - .my-xl-1 { - margin-top: .25rem !important; - margin-bottom: .25rem !important - } - - .my-xl-2 { - margin-top: .5rem !important; - margin-bottom: .5rem !important - } - - .my-xl-3 { - margin-top: 1rem !important; - margin-bottom: 1rem !important - } - - .my-xl-4 { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important - } - - .my-xl-5 { - margin-top: 3rem !important; - margin-bottom: 3rem !important - } - - .my-xl-auto { - margin-top: auto !important; - margin-bottom: auto !important - } - - .mt-xl-0 { - margin-top: 0 !important - } - - .mt-xl-1 { - margin-top: .25rem !important - } - - .mt-xl-2 { - margin-top: .5rem !important - } - - .mt-xl-3 { - margin-top: 1rem !important - } - - .mt-xl-4 { - margin-top: 1.5rem !important - } - - .mt-xl-5 { - margin-top: 3rem !important - } - - .mt-xl-auto { - margin-top: auto !important - } - - .me-xl-0 { - margin-right: 0 !important - } - - .me-xl-1 { - margin-right: .25rem !important - } - - .me-xl-2 { - margin-right: .5rem !important - } - - .me-xl-3 { - margin-right: 1rem !important - } - - .me-xl-4 { - margin-right: 1.5rem !important - } - - .me-xl-5 { - margin-right: 3rem !important - } - - .me-xl-auto { - margin-right: auto !important - } - - .mb-xl-0 { - margin-bottom: 0 !important - } - - .mb-xl-1 { - margin-bottom: .25rem !important - } - - .mb-xl-2 { - margin-bottom: .5rem !important - } - - .mb-xl-3 { - margin-bottom: 1rem !important - } - - .mb-xl-4 { - margin-bottom: 1.5rem !important - } - - .mb-xl-5 { - margin-bottom: 3rem !important - } - - .mb-xl-auto { - margin-bottom: auto !important - } - - .ms-xl-0 { - margin-left: 0 !important - } - - .ms-xl-1 { - margin-left: .25rem !important - } - - .ms-xl-2 { - margin-left: .5rem !important - } - - .ms-xl-3 { - margin-left: 1rem !important - } - - .ms-xl-4 { - margin-left: 1.5rem !important - } - - .ms-xl-5 { - margin-left: 3rem !important - } - - .ms-xl-auto { - margin-left: auto !important - } - - .p-xl-0 { - padding: 0 !important - } - - .p-xl-1 { - padding: .25rem !important - } - - .p-xl-2 { - padding: .5rem !important - } - - .p-xl-3 { - padding: 1rem !important - } - - .p-xl-4 { - padding: 1.5rem !important - } - - .p-xl-5 { - padding: 3rem !important - } - - .px-xl-0 { - padding-right: 0 !important; - padding-left: 0 !important - } - - .px-xl-1 { - padding-right: .25rem !important; - padding-left: .25rem !important - } - - .px-xl-2 { - padding-right: .5rem !important; - padding-left: .5rem !important - } - - .px-xl-3 { - padding-right: 1rem !important; - padding-left: 1rem !important - } - - .px-xl-4 { - padding-right: 1.5rem !important; - padding-left: 1.5rem !important - } - - .px-xl-5 { - padding-right: 3rem !important; - padding-left: 3rem !important - } - - .py-xl-0 { - padding-top: 0 !important; - padding-bottom: 0 !important - } - - .py-xl-1 { - padding-top: .25rem !important; - padding-bottom: .25rem !important - } - - .py-xl-2 { - padding-top: .5rem !important; - padding-bottom: .5rem !important - } - - .py-xl-3 { - padding-top: 1rem !important; - padding-bottom: 1rem !important - } - - .py-xl-4 { - padding-top: 1.5rem !important; - padding-bottom: 1.5rem !important - } - - .py-xl-5 { - padding-top: 3rem !important; - padding-bottom: 3rem !important - } - - .pt-xl-0 { - padding-top: 0 !important - } - - .pt-xl-1 { - padding-top: .25rem !important - } - - .pt-xl-2 { - padding-top: .5rem !important - } - - .pt-xl-3 { - padding-top: 1rem !important - } - - .pt-xl-4 { - padding-top: 1.5rem !important - } - - .pt-xl-5 { - padding-top: 3rem !important - } - - .pe-xl-0 { - padding-right: 0 !important - } - - .pe-xl-1 { - padding-right: .25rem !important - } - - .pe-xl-2 { - padding-right: .5rem !important - } - - .pe-xl-3 { - padding-right: 1rem !important - } - - .pe-xl-4 { - padding-right: 1.5rem !important - } - - .pe-xl-5 { - padding-right: 3rem !important - } - - .pb-xl-0 { - padding-bottom: 0 !important - } - - .pb-xl-1 { - padding-bottom: .25rem !important - } - - .pb-xl-2 { - padding-bottom: .5rem !important - } - - .pb-xl-3 { - padding-bottom: 1rem !important - } - - .pb-xl-4 { - padding-bottom: 1.5rem !important - } - - .pb-xl-5 { - padding-bottom: 3rem !important - } - - .ps-xl-0 { - padding-left: 0 !important - } - - .ps-xl-1 { - padding-left: .25rem !important - } - - .ps-xl-2 { - padding-left: .5rem !important - } - - .ps-xl-3 { - padding-left: 1rem !important - } - - .ps-xl-4 { - padding-left: 1.5rem !important - } - - .ps-xl-5 { - padding-left: 3rem !important - } - - .gap-xl-0 { - gap: 0 !important - } - - .gap-xl-1 { - gap: .25rem !important - } - - .gap-xl-2 { - gap: .5rem !important - } - - .gap-xl-3 { - gap: 1rem !important - } - - .gap-xl-4 { - gap: 1.5rem !important - } - - .gap-xl-5 { - gap: 3rem !important - } - - .text-xl-start { - text-align: left !important - } - - .text-xl-end { - text-align: right !important - } - - .text-xl-center { - text-align: center !important - } -} - -@media (min-width: 1400px) { - .float-xxl-start { - float: left !important - } - - .float-xxl-end { - float: right !important - } - - .float-xxl-none { - float: none !important - } - - .d-xxl-inline { - display: inline !important - } - - .d-xxl-inline-block { - display: inline-block !important - } - - .d-xxl-block { - display: block !important - } - - .d-xxl-grid { - display: grid !important - } - - .d-xxl-table { - display: table !important - } - - .d-xxl-table-row { - display: table-row !important - } - - .d-xxl-table-cell { - display: table-cell !important - } - - .d-xxl-flex { - display: flex !important - } - - .d-xxl-inline-flex { - display: inline-flex !important - } - - .d-xxl-none { - display: none !important - } - - .flex-xxl-fill { - flex: 1 1 auto !important - } - - .flex-xxl-row { - flex-direction: row !important - } - - .flex-xxl-column { - flex-direction: column !important - } - - .flex-xxl-row-reverse { - flex-direction: row-reverse !important - } - - .flex-xxl-column-reverse { - flex-direction: column-reverse !important - } - - .flex-xxl-grow-0 { - flex-grow: 0 !important - } - - .flex-xxl-grow-1 { - flex-grow: 1 !important - } - - .flex-xxl-shrink-0 { - flex-shrink: 0 !important - } - - .flex-xxl-shrink-1 { - flex-shrink: 1 !important - } - - .flex-xxl-wrap { - flex-wrap: wrap !important - } - - .flex-xxl-nowrap { - flex-wrap: nowrap !important - } - - .flex-xxl-wrap-reverse { - flex-wrap: wrap-reverse !important - } - - .justify-content-xxl-start { - justify-content: flex-start !important - } - - .justify-content-xxl-end { - justify-content: flex-end !important - } - - .justify-content-xxl-center { - justify-content: center !important - } - - .justify-content-xxl-between { - justify-content: space-between !important - } - - .justify-content-xxl-around { - justify-content: space-around !important - } - - .justify-content-xxl-evenly { - justify-content: space-evenly !important - } - - .align-items-xxl-start { - align-items: flex-start !important - } - - .align-items-xxl-end { - align-items: flex-end !important - } - - .align-items-xxl-center { - align-items: center !important - } - - .align-items-xxl-baseline { - align-items: baseline !important - } - - .align-items-xxl-stretch { - align-items: stretch !important - } - - .align-content-xxl-start { - align-content: flex-start !important - } - - .align-content-xxl-end { - align-content: flex-end !important - } - - .align-content-xxl-center { - align-content: center !important - } - - .align-content-xxl-between { - align-content: space-between !important - } - - .align-content-xxl-around { - align-content: space-around !important - } - - .align-content-xxl-stretch { - align-content: stretch !important - } - - .align-self-xxl-auto { - align-self: auto !important - } - - .align-self-xxl-start { - align-self: flex-start !important - } - - .align-self-xxl-end { - align-self: flex-end !important - } - - .align-self-xxl-center { - align-self: center !important - } - - .align-self-xxl-baseline { - align-self: baseline !important - } - - .align-self-xxl-stretch { - align-self: stretch !important - } - - .order-xxl-first { - order: -1 !important - } - - .order-xxl-0 { - order: 0 !important - } - - .order-xxl-1 { - order: 1 !important - } - - .order-xxl-2 { - order: 2 !important - } - - .order-xxl-3 { - order: 3 !important - } - - .order-xxl-4 { - order: 4 !important - } - - .order-xxl-5 { - order: 5 !important - } - - .order-xxl-last { - order: 6 !important - } - - .m-xxl-0 { - margin: 0 !important - } - - .m-xxl-1 { - margin: .25rem !important - } - - .m-xxl-2 { - margin: .5rem !important - } - - .m-xxl-3 { - margin: 1rem !important - } - - .m-xxl-4 { - margin: 1.5rem !important - } - - .m-xxl-5 { - margin: 3rem !important - } - - .m-xxl-auto { - margin: auto !important - } - - .mx-xxl-0 { - margin-right: 0 !important; - margin-left: 0 !important - } - - .mx-xxl-1 { - margin-right: .25rem !important; - margin-left: .25rem !important - } - - .mx-xxl-2 { - margin-right: .5rem !important; - margin-left: .5rem !important - } - - .mx-xxl-3 { - margin-right: 1rem !important; - margin-left: 1rem !important - } - - .mx-xxl-4 { - margin-right: 1.5rem !important; - margin-left: 1.5rem !important - } - - .mx-xxl-5 { - margin-right: 3rem !important; - margin-left: 3rem !important - } - - .mx-xxl-auto { - margin-right: auto !important; - margin-left: auto !important - } - - .my-xxl-0 { - margin-top: 0 !important; - margin-bottom: 0 !important - } - - .my-xxl-1 { - margin-top: .25rem !important; - margin-bottom: .25rem !important - } - - .my-xxl-2 { - margin-top: .5rem !important; - margin-bottom: .5rem !important - } - - .my-xxl-3 { - margin-top: 1rem !important; - margin-bottom: 1rem !important - } - - .my-xxl-4 { - margin-top: 1.5rem !important; - margin-bottom: 1.5rem !important - } - - .my-xxl-5 { - margin-top: 3rem !important; - margin-bottom: 3rem !important - } - - .my-xxl-auto { - margin-top: auto !important; - margin-bottom: auto !important - } - - .mt-xxl-0 { - margin-top: 0 !important - } - - .mt-xxl-1 { - margin-top: .25rem !important - } - - .mt-xxl-2 { - margin-top: .5rem !important - } - - .mt-xxl-3 { - margin-top: 1rem !important - } - - .mt-xxl-4 { - margin-top: 1.5rem !important - } - - .mt-xxl-5 { - margin-top: 3rem !important - } - - .mt-xxl-auto { - margin-top: auto !important - } - - .me-xxl-0 { - margin-right: 0 !important - } - - .me-xxl-1 { - margin-right: .25rem !important - } - - .me-xxl-2 { - margin-right: .5rem !important - } - - .me-xxl-3 { - margin-right: 1rem !important - } - - .me-xxl-4 { - margin-right: 1.5rem !important - } - - .me-xxl-5 { - margin-right: 3rem !important - } - - .me-xxl-auto { - margin-right: auto !important - } - - .mb-xxl-0 { - margin-bottom: 0 !important - } - - .mb-xxl-1 { - margin-bottom: .25rem !important - } - - .mb-xxl-2 { - margin-bottom: .5rem !important - } - - .mb-xxl-3 { - margin-bottom: 1rem !important - } - - .mb-xxl-4 { - margin-bottom: 1.5rem !important - } - - .mb-xxl-5 { - margin-bottom: 3rem !important - } - - .mb-xxl-auto { - margin-bottom: auto !important - } - - .ms-xxl-0 { - margin-left: 0 !important - } - - .ms-xxl-1 { - margin-left: .25rem !important - } - - .ms-xxl-2 { - margin-left: .5rem !important - } - - .ms-xxl-3 { - margin-left: 1rem !important - } - - .ms-xxl-4 { - margin-left: 1.5rem !important - } - - .ms-xxl-5 { - margin-left: 3rem !important - } - - .ms-xxl-auto { - margin-left: auto !important - } - - .p-xxl-0 { - padding: 0 !important - } - - .p-xxl-1 { - padding: .25rem !important - } - - .p-xxl-2 { - padding: .5rem !important - } - - .p-xxl-3 { - padding: 1rem !important - } - - .p-xxl-4 { - padding: 1.5rem !important - } - - .p-xxl-5 { - padding: 3rem !important - } - - .px-xxl-0 { - padding-right: 0 !important; - padding-left: 0 !important - } - - .px-xxl-1 { - padding-right: .25rem !important; - padding-left: .25rem !important - } - - .px-xxl-2 { - padding-right: .5rem !important; - padding-left: .5rem !important - } - - .px-xxl-3 { - padding-right: 1rem !important; - padding-left: 1rem !important - } - - .px-xxl-4 { - padding-right: 1.5rem !important; - padding-left: 1.5rem !important - } - - .px-xxl-5 { - padding-right: 3rem !important; - padding-left: 3rem !important - } - - .py-xxl-0 { - padding-top: 0 !important; - padding-bottom: 0 !important - } - - .py-xxl-1 { - padding-top: .25rem !important; - padding-bottom: .25rem !important - } - - .py-xxl-2 { - padding-top: .5rem !important; - padding-bottom: .5rem !important - } - - .py-xxl-3 { - padding-top: 1rem !important; - padding-bottom: 1rem !important - } - - .py-xxl-4 { - padding-top: 1.5rem !important; - padding-bottom: 1.5rem !important - } - - .py-xxl-5 { - padding-top: 3rem !important; - padding-bottom: 3rem !important - } - - .pt-xxl-0 { - padding-top: 0 !important - } - - .pt-xxl-1 { - padding-top: .25rem !important - } - - .pt-xxl-2 { - padding-top: .5rem !important - } - - .pt-xxl-3 { - padding-top: 1rem !important - } - - .pt-xxl-4 { - padding-top: 1.5rem !important - } - - .pt-xxl-5 { - padding-top: 3rem !important - } - - .pe-xxl-0 { - padding-right: 0 !important - } - - .pe-xxl-1 { - padding-right: .25rem !important - } - - .pe-xxl-2 { - padding-right: .5rem !important - } - - .pe-xxl-3 { - padding-right: 1rem !important - } - - .pe-xxl-4 { - padding-right: 1.5rem !important - } - - .pe-xxl-5 { - padding-right: 3rem !important - } - - .pb-xxl-0 { - padding-bottom: 0 !important - } - - .pb-xxl-1 { - padding-bottom: .25rem !important - } - - .pb-xxl-2 { - padding-bottom: .5rem !important - } - - .pb-xxl-3 { - padding-bottom: 1rem !important - } - - .pb-xxl-4 { - padding-bottom: 1.5rem !important - } - - .pb-xxl-5 { - padding-bottom: 3rem !important - } - - .ps-xxl-0 { - padding-left: 0 !important - } - - .ps-xxl-1 { - padding-left: .25rem !important - } - - .ps-xxl-2 { - padding-left: .5rem !important - } - - .ps-xxl-3 { - padding-left: 1rem !important - } - - .ps-xxl-4 { - padding-left: 1.5rem !important - } - - .ps-xxl-5 { - padding-left: 3rem !important - } - - .gap-xxl-0 { - gap: 0 !important - } - - .gap-xxl-1 { - gap: .25rem !important - } - - .gap-xxl-2 { - gap: .5rem !important - } - - .gap-xxl-3 { - gap: 1rem !important - } - - .gap-xxl-4 { - gap: 1.5rem !important - } - - .gap-xxl-5 { - gap: 3rem !important - } - - .text-xxl-start { - text-align: left !important - } - - .text-xxl-end { - text-align: right !important - } - - .text-xxl-center { - text-align: center !important - } -} - -@media (min-width: 1200px) { - .fs-1 { - font-size: 3rem !important - } - - .fs-2 { - font-size: 2.5rem !important - } - - .fs-3 { - font-size: 2rem !important - } - - .fs-4 { - font-size: 1.5rem !important - } -} - -@media print { - .d-print-inline { - display: inline !important - } - - .d-print-inline-block { - display: inline-block !important - } - - .d-print-block { - display: block !important - } - - .d-print-grid { - display: grid !important - } - - .d-print-table { - display: table !important - } - - .d-print-table-row { - display: table-row !important - } - - .d-print-table-cell { - display: table-cell !important - } - - .d-print-flex { - display: flex !important - } - - .d-print-inline-flex { - display: inline-flex !important - } - - .d-print-none { - display: none !important - } -} - -.blockquote-footer { - color: #888 -} - -.input-group-addon { - color: #fff -} - -.form-floating > label { - color: #444 -} - -.nav-pills .nav-item.open .nav-link, .nav-pills .nav-item.open .nav-link:focus, .nav-pills .nav-item.open .nav-link:hover, .nav-pills .nav-link, .nav-pills .nav-link.active, .nav-pills .nav-link.active:focus, .nav-pills .nav-link.active:hover, .nav-tabs .nav-item.open .nav-link, .nav-tabs .nav-item.open .nav-link:focus, .nav-tabs .nav-item.open .nav-link:hover, .nav-tabs .nav-link, .nav-tabs .nav-link.active, .nav-tabs .nav-link.active:focus, .nav-tabs .nav-link.active:hover { - color: #fff -} - -.breadcrumb a { - color: #fff -} - -.pagination a:hover { - text-decoration: none -} - -.alert { - color: #fff; - border: none -} - -.alert .alert-link, .alert a { - color: #fff; - text-decoration: underline -} - -.alert-primary { - background-color: #375a7f -} - -.alert-secondary { - background-color: #444 -} - -.alert-success { - background-color: #00bc8c -} - -.alert-info { - background-color: #3498db -} - -.alert-warning { - background-color: #f39c12 -} - -.alert-danger { - background-color: #e74c3c -} - -.alert-light { - background-color: #adb5bd -} - -.alert-dark { - background-color: #303030 -} + */@import url(https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap);:root{--bs-blue:#375a7f;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#e83e8c;--bs-red:#e74c3c;--bs-orange:#fd7e14;--bs-yellow:#f39c12;--bs-green:#00bc8c;--bs-teal:#20c997;--bs-cyan:#3498db;--bs-black:#000;--bs-white:#fff;--bs-gray:#888;--bs-gray-dark:#303030;--bs-gray-100:#f8f9fa;--bs-gray-200:#ebebeb;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#888;--bs-gray-700:#444;--bs-gray-800:#303030;--bs-gray-900:#222;--bs-primary:#375a7f;--bs-secondary:#444;--bs-success:#00bc8c;--bs-info:#3498db;--bs-warning:#f39c12;--bs-danger:#e74c3c;--bs-light:#adb5bd;--bs-dark:#303030;--bs-primary-rgb:55,90,127;--bs-secondary-rgb:68,68,68;--bs-success-rgb:0,188,140;--bs-info-rgb:52,152,219;--bs-warning-rgb:243,156,18;--bs-danger-rgb:231,76,60;--bs-light-rgb:173,181,189;--bs-dark-rgb:48,48,48;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:255,255,255;--bs-body-bg-rgb:34,34,34;--bs-font-sans-serif:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#fff;--bs-body-bg:#222;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#00bc8c;--bs-link-hover-color:#009670;--bs-code-color:#e83e8c;--bs-highlight-bg:#fdebd0}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:1px solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:calc(1.425rem + 2.1vw)}@media (min-width:1200px){.h1,h1{font-size:3rem}}.h2,h2{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h2,h2{font-size:2.5rem}}.h3,h3{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h3,h3{font-size:2rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--bs-link-color);text-decoration:underline}a:hover{color:var(--bs-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em;color:inherit}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#888;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#888}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#222;border:1px solid var(--bs-border-color);border-radius:.375rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#888}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color:var(--bs-body-color);--bs-table-bg:transparent;--bs-table-border-color:#444;--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-body-color);--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:var(--bs-body-color);--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:var(--bs-body-color);--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:var(--bs-table-color);vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:2px solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-striped-columns>:not(caption)>tr>:nth-child(even){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-color:#fff;--bs-table-bg:#375a7f;--bs-table-border-color:#4b6b8c;--bs-table-striped-bg:#416285;--bs-table-striped-color:#fff;--bs-table-active-bg:#4b6b8c;--bs-table-active-color:#fff;--bs-table-hover-bg:#466689;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#fff;--bs-table-bg:#444444;--bs-table-border-color:#575757;--bs-table-striped-bg:#4d4d4d;--bs-table-striped-color:#fff;--bs-table-active-bg:#575757;--bs-table-active-color:#fff;--bs-table-hover-bg:#525252;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#fff;--bs-table-bg:#00bc8c;--bs-table-border-color:#1ac398;--bs-table-striped-bg:#0dbf92;--bs-table-striped-color:#fff;--bs-table-active-bg:#1ac398;--bs-table-active-color:#fff;--bs-table-hover-bg:#13c195;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#fff;--bs-table-bg:#3498db;--bs-table-border-color:#48a2df;--bs-table-striped-bg:#3e9ddd;--bs-table-striped-color:#fff;--bs-table-active-bg:#48a2df;--bs-table-active-color:#fff;--bs-table-hover-bg:#43a0de;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#fff;--bs-table-bg:#f39c12;--bs-table-border-color:#f4a62a;--bs-table-striped-bg:#f4a11e;--bs-table-striped-color:#fff;--bs-table-active-bg:#f4a62a;--bs-table-active-color:#fff;--bs-table-hover-bg:#f4a324;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#fff;--bs-table-bg:#e74c3c;--bs-table-border-color:#e95e50;--bs-table-striped-bg:#e85546;--bs-table-striped-color:#fff;--bs-table-active-bg:#e95e50;--bs-table-active-color:#fff;--bs-table-hover-bg:#e9594b;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#fff;--bs-table-bg:#adb5bd;--bs-table-border-color:#b5bcc4;--bs-table-striped-bg:#b1b9c0;--bs-table-striped-color:#fff;--bs-table-active-bg:#b5bcc4;--bs-table-active-color:#fff;--bs-table-hover-bg:#b3bbc2;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#303030;--bs-table-border-color:#454545;--bs-table-striped-bg:#3a3a3a;--bs-table-striped-color:#fff;--bs-table-active-bg:#454545;--bs-table-active-color:#fff;--bs-table-hover-bg:#404040;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:#888}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#303030;background-color:#fff;background-clip:padding-box;border:1px solid #222;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#303030;background-color:#fff;border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-moz-placeholder{color:#888;opacity:1}.form-control::placeholder{color:#888;opacity:1}.form-control:disabled{background-color:#ebebeb;opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#fff;background-color:#444;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#fff;background-color:#444;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#414141}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#414141}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#fff;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{width:3rem;height:calc(1.5em + .75rem + 2px);padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:.375rem}.form-control-color::-webkit-color-swatch{border-radius:.375rem}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + 2px)}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + 2px)}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:#303030;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #222;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#ebebeb}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #303030}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:.25rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:.5rem}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-check-input:checked{background-color:#375a7f;border-color:#375a7f}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#375a7f;border-color:#375a7f;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%239badbf'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #222,0 0 0 .25rem rgba(55,90,127,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #222,0 0 0 .25rem rgba(55,90,127,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#375a7f;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#c3ced9}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#375a7f;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#c3ced9}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;width:100%;height:100%;padding:1rem .75rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::-moz-placeholder,.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown),.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:1px 0}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#adb5bd;text-align:center;white-space:nowrap;background-color:#444;border:1px solid #222;border-radius:.375rem}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select,.input-group>:not(:first-child):not(.dropdown-menu):not(.form-floating):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#00bc8c}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(0,188,140,.9);border-radius:.375rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#00bc8c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#00bc8c}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#00bc8c}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#00bc8c}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#00bc8c}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group .form-control.is-valid,.input-group .form-select.is-valid,.was-validated .input-group .form-control:valid,.was-validated .input-group .form-select:valid{z-index:1}.input-group .form-control.is-valid:focus,.input-group .form-select.is-valid:focus,.was-validated .input-group .form-control:valid:focus,.was-validated .input-group .form-select:valid:focus{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#e74c3c}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(231,76,60,.9);border-radius:.375rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#e74c3c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#e74c3c}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#e74c3c}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#e74c3c}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#e74c3c}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group .form-control.is-invalid,.input-group .form-select.is-invalid,.was-validated .input-group .form-control:invalid,.was-validated .input-group .form-select:invalid{z-index:2}.input-group .form-control.is-invalid:focus,.input-group .form-select.is-invalid:focus,.was-validated .input-group .form-control:invalid:focus,.was-validated .input-group .form-select:invalid:focus{z-index:3}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#fff;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check:focus+.btn,.btn:focus{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:active+.btn,.btn-check:checked+.btn,.btn.active,.btn.show,.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:active+.btn:focus,.btn-check:checked+.btn:focus,.btn.active:focus,.btn.show:focus,.btn:active:focus{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#375a7f;--bs-btn-border-color:#375a7f;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#2f4d6c;--bs-btn-hover-border-color:#2c4866;--bs-btn-focus-shadow-rgb:85,115,146;--bs-btn-active-color:#fff;--bs-btn-active-bg:#2c4866;--bs-btn-active-border-color:#29445f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#375a7f;--bs-btn-disabled-border-color:#375a7f}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#444;--bs-btn-border-color:#444;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#3a3a3a;--bs-btn-hover-border-color:#363636;--bs-btn-focus-shadow-rgb:96,96,96;--bs-btn-active-color:#fff;--bs-btn-active-bg:#363636;--bs-btn-active-border-color:#333333;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#444;--bs-btn-disabled-border-color:#444}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#00bc8c;--bs-btn-border-color:#00bc8c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#00a077;--bs-btn-hover-border-color:#009670;--bs-btn-focus-shadow-rgb:38,198,157;--bs-btn-active-color:#fff;--bs-btn-active-bg:#009670;--bs-btn-active-border-color:#008d69;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#00bc8c;--bs-btn-disabled-border-color:#00bc8c}.btn-info{--bs-btn-color:#fff;--bs-btn-bg:#3498db;--bs-btn-border-color:#3498db;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#2c81ba;--bs-btn-hover-border-color:#2a7aaf;--bs-btn-focus-shadow-rgb:82,167,224;--bs-btn-active-color:#fff;--bs-btn-active-bg:#2a7aaf;--bs-btn-active-border-color:#2772a4;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#3498db;--bs-btn-disabled-border-color:#3498db}.btn-warning{--bs-btn-color:#fff;--bs-btn-bg:#f39c12;--bs-btn-border-color:#f39c12;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#cf850f;--bs-btn-hover-border-color:#c27d0e;--bs-btn-focus-shadow-rgb:245,171,54;--bs-btn-active-color:#fff;--bs-btn-active-bg:#c27d0e;--bs-btn-active-border-color:#b6750e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#f39c12;--bs-btn-disabled-border-color:#f39c12}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#e74c3c;--bs-btn-border-color:#e74c3c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#c44133;--bs-btn-hover-border-color:#b93d30;--bs-btn-focus-shadow-rgb:235,103,89;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b93d30;--bs-btn-active-border-color:#ad392d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#e74c3c;--bs-btn-disabled-border-color:#e74c3c}.btn-light{--bs-btn-color:#fff;--bs-btn-bg:#adb5bd;--bs-btn-border-color:#adb5bd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#939aa1;--bs-btn-hover-border-color:#8a9197;--bs-btn-focus-shadow-rgb:185,192,199;--bs-btn-active-color:#fff;--bs-btn-active-bg:#8a9197;--bs-btn-active-border-color:#82888e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#adb5bd;--bs-btn-disabled-border-color:#adb5bd}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#303030;--bs-btn-border-color:#303030;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#4f4f4f;--bs-btn-hover-border-color:#454545;--bs-btn-focus-shadow-rgb:79,79,79;--bs-btn-active-color:#fff;--bs-btn-active-bg:#595959;--bs-btn-active-border-color:#454545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#303030;--bs-btn-disabled-border-color:#303030}.btn-outline-primary{--bs-btn-color:#375a7f;--bs-btn-border-color:#375a7f;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#375a7f;--bs-btn-hover-border-color:#375a7f;--bs-btn-focus-shadow-rgb:55,90,127;--bs-btn-active-color:#fff;--bs-btn-active-bg:#375a7f;--bs-btn-active-border-color:#375a7f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#375a7f;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#375a7f;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#444;--bs-btn-border-color:#444;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#444;--bs-btn-hover-border-color:#444;--bs-btn-focus-shadow-rgb:68,68,68;--bs-btn-active-color:#fff;--bs-btn-active-bg:#444;--bs-btn-active-border-color:#444;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#444;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#444;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#00bc8c;--bs-btn-border-color:#00bc8c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#00bc8c;--bs-btn-hover-border-color:#00bc8c;--bs-btn-focus-shadow-rgb:0,188,140;--bs-btn-active-color:#fff;--bs-btn-active-bg:#00bc8c;--bs-btn-active-border-color:#00bc8c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#00bc8c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#00bc8c;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#3498db;--bs-btn-border-color:#3498db;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#3498db;--bs-btn-hover-border-color:#3498db;--bs-btn-focus-shadow-rgb:52,152,219;--bs-btn-active-color:#fff;--bs-btn-active-bg:#3498db;--bs-btn-active-border-color:#3498db;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#3498db;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#3498db;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#f39c12;--bs-btn-border-color:#f39c12;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#f39c12;--bs-btn-hover-border-color:#f39c12;--bs-btn-focus-shadow-rgb:243,156,18;--bs-btn-active-color:#fff;--bs-btn-active-bg:#f39c12;--bs-btn-active-border-color:#f39c12;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f39c12;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f39c12;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#e74c3c;--bs-btn-border-color:#e74c3c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#e74c3c;--bs-btn-hover-border-color:#e74c3c;--bs-btn-focus-shadow-rgb:231,76,60;--bs-btn-active-color:#fff;--bs-btn-active-bg:#e74c3c;--bs-btn-active-border-color:#e74c3c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#e74c3c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#e74c3c;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#adb5bd;--bs-btn-border-color:#adb5bd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#adb5bd;--bs-btn-hover-border-color:#adb5bd;--bs-btn-focus-shadow-rgb:173,181,189;--bs-btn-active-color:#fff;--bs-btn-active-bg:#adb5bd;--bs-btn-active-border-color:#adb5bd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#adb5bd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#adb5bd;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#303030;--bs-btn-border-color:#303030;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#303030;--bs-btn-hover-border-color:#303030;--bs-btn-focus-shadow-rgb:48,48,48;--bs-btn-active-color:#fff;--bs-btn-active-bg:#303030;--bs-btn-active-border-color:#303030;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#303030;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#303030;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#888;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:85,115,146;text-decoration:underline}.btn-link:focus{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:0.5rem}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:0.25rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:#fff;--bs-dropdown-bg:#222;--bs-dropdown-border-color:#444;--bs-dropdown-border-radius:0.375rem;--bs-dropdown-border-width:1px;--bs-dropdown-inner-border-radius:calc(0.375rem - 1px);--bs-dropdown-divider-bg:#444;--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-dropdown-link-color:#fff;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-link-hover-bg:#375a7f;--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#375a7f;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#888;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:1000;display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#303030;--bs-dropdown-border-color:#444;--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:#444;--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#375a7f;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:.375rem}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:2rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#adb5bd;display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#444;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#444 #444 transparent;--bs-nav-tabs-link-active-color:#fff;--bs-nav-tabs-link-active-bg:#222;--bs-nav-tabs-link-active-border-color:#444 #444 transparent;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(var(--bs-nav-tabs-border-width) * -1);background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(var(--bs-nav-tabs-border-width) * -1);border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:0.375rem;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#375a7f}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:1rem;--bs-navbar-color:rgba(34, 34, 34, 0.7);--bs-navbar-hover-color:#222;--bs-navbar-disabled-color:rgba(0, 0, 0, 0.3);--bs-navbar-active-color:#222;--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:#222;--bs-navbar-brand-hover-color:#222;--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2834, 34, 34, 0.7%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(34, 34, 34, 0.1);--bs-navbar-toggler-border-radius:0.375rem;--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .show>.nav-link{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark{--bs-navbar-color:rgba(255, 255, 255, 0.6);--bs-navbar-hover-color:#fff;--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.6%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-border-width:1px;--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:0.375rem;--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(0.375rem - 1px);--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:#444;--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:#303030;--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:#fff;--bs-accordion-bg:#222;--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:1px;--bs-accordion-border-radius:0.375rem;--bs-accordion-inner-border-radius:calc(0.375rem - 1px);--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='var%28--bs-body-color%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23325172'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-focus-border-color:#9badbf;--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(55, 90, 127, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:#325172;--bs-accordion-active-bg:#ebeff2}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(var(--bs-accordion-border-width) * -1) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:var(--bs-accordion-btn-focus-border-color);outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button{border-radius:0}.breadcrumb{--bs-breadcrumb-padding-x:0.75rem;--bs-breadcrumb-padding-y:0.375rem;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg:#444;--bs-breadcrumb-border-radius:0.25rem;--bs-breadcrumb-divider-color:#888;--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:#888;display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:#fff;--bs-pagination-bg:#00bc8c;--bs-pagination-border-width:0;--bs-pagination-border-color:transparent;--bs-pagination-border-radius:0.375rem;--bs-pagination-hover-color:#fff;--bs-pagination-hover-bg:#00efb2;--bs-pagination-hover-border-color:transparent;--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:#ebebeb;--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(55, 90, 127, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#00efb2;--bs-pagination-active-border-color:transparent;--bs-pagination-disabled-color:#fff;--bs-pagination-disabled-bg:#007053;--bs-pagination-disabled-border-color:transparent;display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:0.5rem}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:0.25rem}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:0.375rem;display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:1px solid var(--bs-alert-border-color);--bs-alert-border-radius:0.375rem;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:#21364c;--bs-alert-bg:#d7dee5;--bs-alert-border-color:#c3ced9}.alert-primary .alert-link{color:#1a2b3d}.alert-secondary{--bs-alert-color:#292929;--bs-alert-bg:#dadada;--bs-alert-border-color:#c7c7c7}.alert-secondary .alert-link{color:#212121}.alert-success{--bs-alert-color:#007154;--bs-alert-bg:#ccf2e8;--bs-alert-border-color:#b3ebdd}.alert-success .alert-link{color:#005a43}.alert-info{--bs-alert-color:#1f5b83;--bs-alert-bg:#d6eaf8;--bs-alert-border-color:#c2e0f4}.alert-info .alert-link{color:#194969}.alert-warning{--bs-alert-color:#925e0b;--bs-alert-bg:#fdebd0;--bs-alert-border-color:#fbe1b8}.alert-warning .alert-link{color:#754b09}.alert-danger{--bs-alert-color:#8b2e24;--bs-alert-bg:#fadbd8;--bs-alert-border-color:#f8c9c5}.alert-danger .alert-link{color:#6f251d}.alert-light{--bs-alert-color:#686d71;--bs-alert-bg:#eff0f2;--bs-alert-border-color:#e6e9eb}.alert-light .alert-link{color:#53575a}.alert-dark{--bs-alert-color:#1d1d1d;--bs-alert-bg:#d6d6d6;--bs-alert-border-color:#c1c1c1}.alert-dark .alert-link{color:#171717}@-webkit-keyframes progress-bar-stripes{0%{background-position-x:1rem}}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:#444;--bs-progress-border-radius:0.375rem;--bs-progress-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#375a7f;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.list-group{--bs-list-group-color:#fff;--bs-list-group-bg:#303030;--bs-list-group-border-color:#444;--bs-list-group-border-width:1px;--bs-list-group-border-radius:0.375rem;--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:#444;--bs-list-group-action-hover-color:#fff;--bs-list-group-action-hover-bg:#444;--bs-list-group-action-active-color:#fff;--bs-list-group-action-active-bg:#222;--bs-list-group-disabled-color:#888;--bs-list-group-disabled-bg:#303030;--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#375a7f;--bs-list-group-active-border-color:#375a7f;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(var(--bs-list-group-border-width) * -1);border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(var(--bs-list-group-border-width) * -1);border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(var(--bs-list-group-border-width) * -1);border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(var(--bs-list-group-border-width) * -1);border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(var(--bs-list-group-border-width) * -1);border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(var(--bs-list-group-border-width) * -1);border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(var(--bs-list-group-border-width) * -1);border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#21364c;background-color:#d7dee5}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#21364c;background-color:#c2c8ce}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#21364c;border-color:#21364c}.list-group-item-secondary{color:#292929;background-color:#dadada}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#292929;background-color:#c4c4c4}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#292929;border-color:#292929}.list-group-item-success{color:#007154;background-color:#ccf2e8}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#007154;background-color:#b8dad1}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#007154;border-color:#007154}.list-group-item-info{color:#1f5b83;background-color:#d6eaf8}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#1f5b83;background-color:#c1d3df}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#1f5b83;border-color:#1f5b83}.list-group-item-warning{color:#925e0b;background-color:#fdebd0}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#925e0b;background-color:#e4d4bb}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#925e0b;border-color:#925e0b}.list-group-item-danger{color:#8b2e24;background-color:#fadbd8}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#8b2e24;background-color:#e1c5c2}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#8b2e24;border-color:#8b2e24}.list-group-item-light{color:#686d71;background-color:#eff0f2}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#686d71;background-color:#d7d8da}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#686d71;border-color:#686d71}.list-group-item-dark{color:#1d1d1d;background-color:#d6d6d6}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1d1d1d;background-color:#c1c1c1}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1d1d1d;border-color:#1d1d1d}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#fff;background:transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.375rem;opacity:.4}.btn-close:hover{color:#fff;text-decoration:none;opacity:1}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25);opacity:1}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:#444;--bs-toast-border-width:1px;--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:0.375rem;--bs-toast-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-toast-header-color:#888;--bs-toast-header-bg:#303030;--bs-toast-header-border-color:rgba(0, 0, 0, 0.05);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{position:absolute;z-index:1090;width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(var(--bs-toast-padding-x) * -.5);margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:#303030;--bs-modal-border-color:#444;--bs-modal-border-width:1px;--bs-modal-border-radius:0.5rem;--bs-modal-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-modal-inner-border-radius:calc(0.5rem - 1px);--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:#444;--bs-modal-header-border-width:1px;--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:#444;--bs-modal-footer-border-width:1px;position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin:calc(var(--bs-modal-header-padding-y) * -.5) calc(var(--bs-modal-header-padding-x) * -.5) calc(var(--bs-modal-header-padding-y) * -.5) auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:#fff;--bs-tooltip-bg:#000;--bs-tooltip-border-radius:0.375rem;--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;padding:var(--bs-tooltip-arrow-height);margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:#303030;--bs-popover-border-width:1px;--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:0.5rem;--bs-popover-inner-border-radius:calc(0.5rem - 1px);--bs-popover-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color:var(--bs-heading-color);--bs-popover-header-bg:#444;--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:#fff;--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(var(--bs-popover-arrow-height) * -1 - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(var(--bs-popover-arrow-height) * -1 - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(var(--bs-popover-arrow-height) * -1 - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(var(--bs-popover-arrow-width) * -.5);content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(var(--bs-popover-arrow-height) * -1 - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;-webkit-animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name);animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@-webkit-keyframes spinner-border{to{transform:rotate(360deg)}}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color: ;--bs-offcanvas-bg:#303030;--bs-offcanvas-border-width:1px;--bs-offcanvas-border-color:#444;--bs-offcanvas-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075)}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:1045;display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:575.98px){.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}}@media (max-width:575.98px){.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:1045;display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:767.98px){.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}}@media (max-width:767.98px){.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:1045;display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:991.98px){.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}}@media (max-width:991.98px){.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:1045;display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1199.98px){.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}}@media (max-width:1199.98px){.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:1045;display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}}@media (max-width:1399.98px){.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:1045;display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin-top:calc(var(--bs-offcanvas-padding-y) * -.5);margin-right:calc(var(--bs-offcanvas-padding-x) * -.5);margin-bottom:calc(var(--bs-offcanvas-padding-y) * -.5)}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{-webkit-animation:placeholder-glow 2s ease-in-out infinite;animation:placeholder-glow 2s ease-in-out infinite}@-webkit-keyframes placeholder-glow{50%{opacity:.2}}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;-webkit-animation:placeholder-wave 2s linear infinite;animation:placeholder-wave 2s linear infinite}@-webkit-keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(55,90,127,var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(68,68,68,var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(0,188,140,var(--bs-bg-opacity,1))!important}.text-bg-info{color:#fff!important;background-color:RGBA(52,152,219,var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#fff!important;background-color:RGBA(243,156,18,var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(231,76,60,var(--bs-bg-opacity,1))!important}.text-bg-light{color:#fff!important;background-color:RGBA(173,181,189,var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(48,48,48,var(--bs-bg-opacity,1))!important}.link-primary{color:#375a7f!important}.link-primary:focus,.link-primary:hover{color:#2c4866!important}.link-secondary{color:#444!important}.link-secondary:focus,.link-secondary:hover{color:#363636!important}.link-success{color:#00bc8c!important}.link-success:focus,.link-success:hover{color:#009670!important}.link-info{color:#3498db!important}.link-info:focus,.link-info:hover{color:#2a7aaf!important}.link-warning{color:#f39c12!important}.link-warning:focus,.link-warning:hover{color:#c27d0e!important}.link-danger{color:#e74c3c!important}.link-danger:focus,.link-danger:hover{color:#b93d30!important}.link-light{color:#adb5bd!important}.link-light:focus,.link-light:hover{color:#8a9197!important}.link-dark{color:#303030!important}.link-dark:focus,.link-dark:hover{color:#262626!important}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-1{--bs-border-width:1px}.border-2{--bs-border-width:2px}.border-3{--bs-border-width:3px}.border-4{--bs-border-width:4px}.border-5{--bs-border-width:5px}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.425rem + 2.1vw)!important}.fs-2{font-size:calc(1.375rem + 1.5vw)!important}.fs-3{font-size:calc(1.325rem + .9vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-light{font-weight:300!important}.fw-lighter{font-weight:lighter!important}.fw-normal{font-weight:400!important}.fw-bold{font-weight:700!important}.fw-semibold{font-weight:600!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:#888!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-2xl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:3rem!important}.fs-2{font-size:2.5rem!important}.fs-3{font-size:2rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}}.blockquote-footer{color:#888}.input-group-addon{color:#fff}.form-floating>label{color:#444}.nav-pills .nav-item.open .nav-link,.nav-pills .nav-item.open .nav-link:focus,.nav-pills .nav-item.open .nav-link:hover,.nav-pills .nav-link,.nav-pills .nav-link.active,.nav-pills .nav-link.active:focus,.nav-pills .nav-link.active:hover,.nav-tabs .nav-item.open .nav-link,.nav-tabs .nav-item.open .nav-link:focus,.nav-tabs .nav-item.open .nav-link:hover,.nav-tabs .nav-link,.nav-tabs .nav-link.active,.nav-tabs .nav-link.active:focus,.nav-tabs .nav-link.active:hover{color:#fff}.breadcrumb a{color:#fff}.pagination a:hover{text-decoration:none}.alert{color:#fff;border:none}.alert .alert-link,.alert a{color:#fff;text-decoration:underline}.alert-primary{background-color:#375a7f}.alert-secondary{background-color:#444}.alert-success{background-color:#00bc8c}.alert-info{background-color:#3498db}.alert-warning{background-color:#f39c12}.alert-danger{background-color:#e74c3c}.alert-light{background-color:#adb5bd}.alert-dark{background-color:#303030} \ No newline at end of file diff --git a/modules/web-map/webpack.config.d/webpack.js b/modules/web-map/webpack.config.d/webpack.js index e258913..8369c61 100644 --- a/modules/web-map/webpack.config.d/webpack.js +++ b/modules/web-map/webpack.config.d/webpack.js @@ -4,6 +4,8 @@ if (config.devServer) { config.devServer.hot = true; config.devtool = 'eval-cheap-source-map'; config.devServer.host = "0.0.0.0" + // required for single-page app + config.devServer.historyApiFallback = true } else { config.devtool = undefined; } @@ -14,6 +16,3 @@ config.performance = { return !assetFilename.endsWith('.js'); }, }; - -// required for single-page app -config.devServer.historyApiFallback = true From dadbcdd8d666551a2212f1d9b59beabf2045f25f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 10 Sep 2022 10:13:48 +0200 Subject: [PATCH 512/629] version bumps (scrimage, kotlinJsWrappers, ktor, hoplite, tstl, typed-factorio, typescript) --- gradle/libs.versions.toml | 17 ++-- .../schema/packets/EntityUpdateTest.kt | 3 +- modules/events-mod/package-lock.json | 30 ++++--- modules/events-mod/package.json | 8 +- .../src/generated/lua/lualib_bundle.lua | 90 +++++++++++-------- modules/events-mod/tsconfig.json | 2 +- 6 files changed, 85 insertions(+), 65 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4489b0e..656c391 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,7 +16,7 @@ kvision = "5.14.0" # https://github.com/rjaros/kvision/rele log4j2 = "2.17.2" okio = "3.2.0" # https://search.maven.org/artifact/com.squareup.okio/okio qosLogback = "1.2.11" -scrimage = "4.0.31" # https://github.com/sksamuel/scrimage/releases +scrimage = "4.0.32" # https://github.com/sksamuel/scrimage/releases semver = "1.2.0" # https://github.com/swiftzer/semver/releases slf4j = "1.7.36" @@ -25,7 +25,7 @@ kxs-charleskornKaml = "0.44.0" kxs-mamoeYamlkt = "0.12.0" kxs-kxsTsGen = "0.2.1" -kotlinJsWrappers = "1.0.0-pre.378" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom +kotlinJsWrappers = "1.0.0-pre.383" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom kotlinx-cli = "0.3.4" kotlinx-coroutines = "1.6.4" # https://github.com/Kotlin/kotlinx.coroutines/releases @@ -35,9 +35,9 @@ kotlinx-nodejs = "0.0.7" kSvgDsl = "v2.2.0" -ktor = "2.1.0" # https://github.com/ktorio/ktor/releases +ktor = "2.1.1" # https://github.com/ktorio/ktor/releases -hoplite = "2.6.1" # https://github.com/sksamuel/hoplite/releases +hoplite = "2.6.2" # https://github.com/sksamuel/hoplite/releases simpleSyslogParser = "1.0.0" # https://search.maven.org/artifact/com.github.palindromicity/simple-syslog @@ -49,11 +49,10 @@ klogging = "0.4.9" ## npm ## -npm-luaTypes = "2.12.0" -npm-typescriptToLua = "1.9.0" -#npm-typedFactorio = "1.6.1" # https://github.com/GlassBricks/typed-factorio/blob/main/Changelog.md -npm-typedFactorio = "1.7.0" # for factorio 1.1.61 -npm-typescript = "4.7.4" +npm-luaTypes = "2.13.0" # https://www.npmjs.com/package/lua-types +npm-typescriptToLua = "1.10.0" # https://www.npmjs.com/package/typescript-to-lua +npm-typedFactorio = "1.7.5" # https://www.npmjs.com/package/typed-factorio +npm-typescript = "4.8.3" # https://github.com/microsoft/TypeScript/releases ## test ## diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt index 061ccbb..dd93cdc 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt @@ -37,8 +37,7 @@ class EntityUpdateTest : FunSpec({ """.trimIndent() test("decode") { val entityUpdate: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) - entityUpdate.data - .shouldBeInstanceOf() + entityUpdate.data.shouldBeInstanceOf() // entityUpdate.health.shouldNotBeNull().shouldBeExactly(350f) } diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 603ca6d..411f557 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -4,6 +4,11 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@typescript-to-lua/language-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.0.0.tgz", + "integrity": "sha512-GtmhFqyg+txpGgGLM3mlS3R6AEG9MQhKALxxcbr6SBzg9u7YAXcPKqUBaBYd6nH+Pi/eQLcWz4BNOLhz8v4TjQ==" + }, "enhanced-resolve": { "version": "5.10.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", @@ -40,9 +45,9 @@ } }, "lua-types": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.12.0.tgz", - "integrity": "sha512-s96z1Zcz3KRXfWyNFM3KP2zpNYTfZwgHo8X/yFXveyS8Dux+cUuyT+zA5tFZbmGh8VViwNs9bFbzNevAR/18uw==" + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.0.tgz", + "integrity": "sha512-wra+mIPZlcbm8bYoM6QutEwTOAjZ9KyKMiaidGeZ+QJItIAK9hwG+1I6GCDKnW0T9E/Xv2IoTFtZwxQv4zAIJw==" }, "path-parse": { "version": "1.0.7", @@ -75,20 +80,21 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.7.0.tgz", - "integrity": "sha512-i7MLTRW7vQAWTwHZSbX8m+PQm0hnCW/3nCBQI1b0DAikK9a/nJIZWpy2U3C4cnwhNqyNz5p50mLFQiedb/s+ow==" + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.7.5.tgz", + "integrity": "sha512-3lTeV8FkmLx7mUUhUp1WPhIDviiqPOfibHYIjE58Lt59mN0ujEDbf7q3o9G8YWjmvgBatS9xJ81a+/Tvq20mUw==" }, "typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz", + "integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==" }, "typescript-to-lua": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.9.0.tgz", - "integrity": "sha512-Oj8kutP1u/TSjN9oGUuESfOL+feHMSs7CCxl90C60jWTH+4ZXLtrXlRJTalA3Z2/aHjQXXgPaXQStSXBzAYLow==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.10.0.tgz", + "integrity": "sha512-rt+Bb2hH3FqytqTmTqOL+xPFRcV/r4TZ5X+46vVSfw9luzbu9V6ai5yyU8GePARVcf5hGvCv+DqxBNQtdcJLsA==", "requires": { + "@typescript-to-lua/language-extensions": "1.0.0", "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", "source-map": "^0.7.3" diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index e90030d..a3dbf50 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -11,10 +11,10 @@ }, "devDependencies": {}, "dependencies": { - "lua-types": "2.12.0", - "typescript-to-lua": "1.9.0", - "typed-factorio": "1.7.0", - "typescript": "4.7.4" + "lua-types": "2.13.0", + "typescript-to-lua": "1.10.0", + "typed-factorio": "1.7.5", + "typescript": "4.8.3" }, "license": "UNLICENSED", "peerDependencies": {}, diff --git a/modules/events-mod/src/generated/lua/lualib_bundle.lua b/modules/events-mod/src/generated/lua/lualib_bundle.lua index 1902e79..d72123e 100644 --- a/modules/events-mod/src/generated/lua/lualib_bundle.lua +++ b/modules/events-mod/src/generated/lua/lualib_bundle.lua @@ -255,11 +255,15 @@ local function __TS__ArrayPushArray(self, items) return len end +local function __TS__CountVarargs(...) + return select("#", ...) +end + local function __TS__ArrayReduce(self, callbackFn, ...) local len = #self local k = 0 local accumulator = nil - if select("#", ...) ~= 0 then + if __TS__CountVarargs(...) ~= 0 then accumulator = ... elseif len > 0 then accumulator = self[1] @@ -283,7 +287,7 @@ local function __TS__ArrayReduceRight(self, callbackFn, ...) local len = #self local k = len - 1 local accumulator = nil - if select("#", ...) ~= 0 then + if __TS__CountVarargs(...) ~= 0 then accumulator = ... elseif len > 0 then accumulator = self[k + 1] @@ -399,7 +403,7 @@ end local function __TS__ArraySplice(self, ...) local args = {...} local len = #self - local actualArgumentCount = select("#", ...) + local actualArgumentCount = __TS__CountVarargs(...) local start = args[1] local deleteCount = args[2] if start < 0 then @@ -1016,6 +1020,16 @@ local function __TS__DecorateParam(paramIndex, decorator) return function(____, target, key) return decorator(nil, target, key, paramIndex) end end +local function __TS__StringIncludes(self, searchString, position) + if not position then + position = 1 + else + position = position + 1 + end + local index = string.find(self, searchString, position, true) + return index ~= nil +end + local Error, RangeError, ReferenceError, SyntaxError, TypeError, URIError do local function getErrorStack(self, constructor) @@ -1030,13 +1044,18 @@ do break end end - return debug.traceback(nil, level) + if __TS__StringIncludes(_VERSION, "Lua 5.0") then + return debug.traceback(("[Level " .. tostring(level)) .. "]") + else + return debug.traceback(nil, level) + end end local function wrapErrorToString(self, getDescription) return function(self) local description = getDescription(self) local caller = debug.getinfo(3, "f") - if _VERSION == "Lua 5.1" or caller and caller.func ~= error then + local isClassicLua = __TS__StringIncludes(_VERSION, "Lua 5.0") or _VERSION == "Lua 5.1" + if isClassicLua or caller and caller.func ~= error then return description else return (tostring(description) .. "\n") .. self.stack @@ -1185,16 +1204,9 @@ do function __TS__Generator(fn) return function(...) local args = {...} - local argsLength = select("#", ...) + local argsLength = __TS__CountVarargs(...) return { - ____coroutine = coroutine.create(function() - local ____fn_1 = fn - local ____unpack_0 = unpack - if ____unpack_0 == nil then - ____unpack_0 = table.unpack - end - return ____fn_1(____unpack_0(args, 1, argsLength)) - end), + ____coroutine = coroutine.create(function() return fn(__TS__Unpack(args, 1, argsLength)) end), [Symbol.iterator] = generatorIterator, next = generatorNext } @@ -1358,8 +1370,12 @@ do Map[Symbol.species] = Map end +local __TS__Match = string.match + local __TS__MathAtan2 = math.atan2 or math.atan +local __TS__MathModf = math.modf + local function __TS__MathSign(val) if val > 0 then return 1 @@ -1369,6 +1385,10 @@ local function __TS__MathSign(val) return 0 end +local function __TS__Modulo50(a, b) + return a - math.floor(a / b) * b +end + local function __TS__Number(value) local valueType = type(value) if valueType == "number" then @@ -1415,7 +1435,7 @@ do if radix < 2 or radix > 36 then error("toString() radix argument must be between 2 and 36", 0) end - local integer, fraction = math.modf(math.abs(self)) + local integer, fraction = __TS__MathModf(math.abs(self)) local result = "" if radix == 8 then result = string.format("%o", integer) @@ -1571,7 +1591,7 @@ local function __TS__ObjectValues(obj) end local function __TS__ParseFloat(numberString) - local infinityMatch = string.match(numberString, "^%s*(-?Infinity)") + local infinityMatch = __TS__Match(numberString, "^%s*(-?Infinity)") if infinityMatch then local ____temp_0 if __TS__StringAccess(infinityMatch, 0) == "-" then @@ -1581,7 +1601,7 @@ local function __TS__ParseFloat(numberString) end return ____temp_0 end - local number = tonumber(string.match(numberString, "^%s*(-?%d+%.?%d*)")) + local number = tonumber(__TS__Match(numberString, "^%s*(-?%d+%.?%d*)")) local ____number_1 = number if ____number_1 == nil then ____number_1 = 0 / 0 @@ -1629,16 +1649,16 @@ do function __TS__ParseInt(numberString, base) if base == nil then base = 10 - local hexMatch = string.match(numberString, "^%s*-?0[xX]") + local hexMatch = __TS__Match(numberString, "^%s*-?0[xX]") if hexMatch then base = 16 - local ____string_match_result__0_0 - if string.match(hexMatch, "-") then - ____string_match_result__0_0 = "-" .. __TS__StringSubstr(numberString, #hexMatch) + local ____TS__Match_result__0_0 + if __TS__Match(hexMatch, "-") then + ____TS__Match_result__0_0 = "-" .. __TS__StringSubstr(numberString, #hexMatch) else - ____string_match_result__0_0 = __TS__StringSubstr(numberString, #hexMatch) + ____TS__Match_result__0_0 = __TS__StringSubstr(numberString, #hexMatch) end - numberString = ____string_match_result__0_0 + numberString = ____TS__Match_result__0_0 end end if base < 2 or base > 36 then @@ -1653,7 +1673,7 @@ do local allowedDigits = ____temp_1 local pattern = ("^%s*(-?[" .. allowedDigits) .. "]*)" local number = tonumber( - string.match(numberString, pattern), + __TS__Match(numberString, pattern), base ) if number == nil then @@ -1965,13 +1985,13 @@ end local function __TS__SparseArrayNew(...) local sparseArray = {...} - sparseArray.sparseLength = select("#", ...) + sparseArray.sparseLength = __TS__CountVarargs(...) return sparseArray end local function __TS__SparseArrayPush(sparseArray, ...) local args = {...} - local argsLen = select("#", ...) + local argsLen = __TS__CountVarargs(...) local listLen = sparseArray.sparseLength for i = 1, argsLen do sparseArray[listLen + i] = args[i] @@ -2086,6 +2106,8 @@ local function __TS__SourceMapTraceBack(fileName, sourceMap) local trace if thread == nil and message == nil and level == nil then trace = originalTraceback() + elseif __TS__StringIncludes(_VERSION, "Lua 5.0") then + trace = originalTraceback((("[Level " .. tostring(level)) .. "] ") .. message) else trace = originalTraceback(thread, message, level) end @@ -2111,7 +2133,7 @@ local function __TS__SourceMapTraceBack(fileName, sourceMap) local function stringReplacer(____, file, line) local fileSourceMap = _G.__TS__sourcemap[file] if fileSourceMap and fileSourceMap[line] then - local chunkName = string.match(file, "%[string \"([^\"]+)\"%]") + local chunkName = __TS__Match(file, "%[string \"([^\"]+)\"%]") local sourceName = string.gsub(chunkName, ".lua$", ".ts") local data = fileSourceMap[line] if type(data) == "number" then @@ -2178,16 +2200,6 @@ local function __TS__StringEndsWith(self, searchString, endPosition) return string.sub(self, endPosition - #searchString + 1, endPosition) == searchString end -local function __TS__StringIncludes(self, searchString, position) - if not position then - position = 1 - else - position = position + 1 - end - local index = string.find(self, searchString, position, true) - return index ~= nil -end - local function __TS__StringPadEnd(self, maxLength, fillString) if fillString == nil then fillString = " " @@ -2443,6 +2455,7 @@ return { __TS__Class = __TS__Class, __TS__ClassExtends = __TS__ClassExtends, __TS__CloneDescriptor = __TS__CloneDescriptor, + __TS__CountVarargs = __TS__CountVarargs, __TS__Decorate = __TS__Decorate, __TS__DecorateParam = __TS__DecorateParam, __TS__Delete = __TS__Delete, @@ -2460,8 +2473,11 @@ return { __TS__Iterator = __TS__Iterator, __TS__LuaIteratorSpread = __TS__LuaIteratorSpread, Map = Map, + __TS__Match = __TS__Match, __TS__MathAtan2 = __TS__MathAtan2, + __TS__MathModf = __TS__MathModf, __TS__MathSign = __TS__MathSign, + __TS__Modulo50 = __TS__Modulo50, __TS__New = __TS__New, __TS__Number = __TS__Number, __TS__NumberIsFinite = __TS__NumberIsFinite, diff --git a/modules/events-mod/tsconfig.json b/modules/events-mod/tsconfig.json index 9526305..f230f54 100644 --- a/modules/events-mod/tsconfig.json +++ b/modules/events-mod/tsconfig.json @@ -8,7 +8,7 @@ "module": "commonjs", "moduleResolution": "node", "types": [ - "typescript-to-lua/language-extensions", + "@typescript-to-lua/language-extensions", "lua-types/5.2", "typed-factorio/runtime", "typed-factorio/strict-index-types" From 64cd94f1ce655500f2d630d6c93fb93dbe417c4e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 11 Sep 2022 00:25:58 +0200 Subject: [PATCH 513/629] gradle tweaks --- modules/events-library/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/events-library/build.gradle.kts b/modules/events-library/build.gradle.kts index 59053a2..4fc31c9 100644 --- a/modules/events-library/build.gradle.kts +++ b/modules/events-library/build.gradle.kts @@ -35,7 +35,7 @@ kotlin { sourceSets { - all { + configureEach { languageSettings.apply { optIn("kotlin.ExperimentalStdlibApi") optIn("kotlin.ExperimentalUnsignedTypes") @@ -164,7 +164,7 @@ val schemaTsZip by tasks.registering(Zip::class) { val schemaTsZipTaskArchiveFile: Provider = schemaTsZip.flatMap { it.archiveFile } -val typeScriptModelGenerated: Configuration by configurations.creating { +val typeScriptModelGenerated by configurations.creating { asProvider() typescriptAttributes(objects) From c8815726b112437431998367aa22005ab87b56f4 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 11 Sep 2022 00:48:16 +0200 Subject: [PATCH 514/629] start splitting up events-server --- buildSrc/build.gradle.kts | 6 +- gradle/libs.versions.toml | 26 +++--- modules/events-library/build.gradle.kts | 6 +- .../events-processor-core/build.gradle.kts | 54 +++++++++++++ .../build.gradle.kts | 54 +++++++++++++ .../events-processor-packets/build.gradle.kts | 54 +++++++++++++ .../events-processor-tiles/build.gradle.kts | 54 +++++++++++++ modules/events-server-api/build.gradle.kts | 81 +++++++++++++++++++ modules/events-server-core/build.gradle.kts | 79 ++++++++++++++++++ modules/events-server-syslog/build.gradle.kts | 79 ++++++++++++++++++ modules/events-server/build.gradle.kts | 18 ++--- modules/versions-platform/build.gradle.kts | 8 +- settings.gradle.kts | 12 ++- 13 files changed, 501 insertions(+), 30 deletions(-) create mode 100644 modules/events-processor-core/build.gradle.kts create mode 100644 modules/events-processor-entities/build.gradle.kts create mode 100644 modules/events-processor-packets/build.gradle.kts create mode 100644 modules/events-processor-tiles/build.gradle.kts create mode 100644 modules/events-server-api/build.gradle.kts create mode 100644 modules/events-server-core/build.gradle.kts create mode 100644 modules/events-server-syslog/build.gradle.kts diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index f844b16..de1982b 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -22,9 +22,9 @@ dependencies { implementation(platform(libs.kotlinx.coroutines.bom)) implementation(libs.kotlinx.coroutines.core) - implementation(platform(libs.kotlinx.serialization.bom)) - implementation(libs.kotlinx.serialization.core) - implementation(libs.kotlinx.serialization.json) + implementation(platform(libs.kotlinxSerialization.bom)) + implementation(libs.kotlinxSerialization.core) + implementation(libs.kotlinxSerialization.json) // implementation("com.charleskorn.kaml:kaml:0.37.0") implementation("com.github.node-gradle:gradle-node-plugin:${libs.versions.gradleNodePlugin.get()}") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 656c391..2833d4e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -47,6 +47,8 @@ marykRocksDb = "7.3.1-1" # https://search.maven.org/artifact/io.m klogging = "0.4.9" +nimbusJoseJwt = "9.24.4" # https://search.maven.org/artifact/com.nimbusds/nimbus-jose-jwt + ## npm ## npm-luaTypes = "2.13.0" # https://www.npmjs.com/package/lua-types @@ -99,18 +101,20 @@ kotlinScripting-dependencies = { group = "org.jetbrains.kotlin", name = "ko kotlinScripting-dependenciesMaven = { group = "org.jetbrains.kotlin", name = "kotlin-scripting-dependencies-maven" } -kotlinx-serialization-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-bom", version.ref = "kotlinx-serialization" } -kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core" } -kotlinx-serialization-cbor = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-cbor" } -kotlinx-serialization-hocon = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-hocon" } -kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json" } -kotlinx-serialization-properties = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-properties" } -kotlinx-serialization-protobuf = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-protobuf" } +kotlinxSerialization-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-bom", version.ref = "kotlinx-serialization" } +kotlinxSerialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core" } +kotlinxSerialization-cbor = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-cbor" } +kotlinxSerialization-hocon = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-hocon" } +kotlinxSerialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json" } +kotlinxSerialization-properties = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-properties" } +kotlinxSerialization-protobuf = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-protobuf" } +kotlinxSerialization-jsonOkio = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json-okio" } -kxs-charleskornKaml = { group = "com.charleskorn.kaml", name = "kaml", version.ref = "kxs-charleskornKaml" } -kxs-mamoeYamlkt = { group = "net.mamoe.yamlkt", name = "yamlkt", version.ref = "kxs-mamoeYamlkt" } + +kotlinxSerialization-charleskornKaml = { group = "com.charleskorn.kaml", name = "kaml", version.ref = "kxs-charleskornKaml" } +kotlinxSerialization-mamoeYamlkt = { group = "net.mamoe.yamlkt", name = "yamlkt", version.ref = "kxs-mamoeYamlkt" } #kxs-kxsTsGen = { group = "dev.adamko.kxstsgen", name = "kxs-ts-gen-core", version.ref = "kxs-kxsTsGen" } -kxs-kxsTsGen = { group = "com.github.adamko-dev.kotlinx-serialization-typescript-generator", name = "kxs-ts-gen-core", version.ref = "kxs-kxsTsGen" } +kotlinxSerialization-kxsTsGen = { group = "com.github.adamko-dev.kotlinx-serialization-typescript-generator", name = "kxs-ts-gen-core", version.ref = "kxs-kxsTsGen" } kotlinx-coroutines-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-bom", version.ref = "kotlinx-coroutines" } @@ -242,6 +246,8 @@ hoplite-yaml = { group = "com.sksamuel.hoplite", name = "hoplite-yaml", simpleSyslogParser = { group = "com.github.palindromicity", name = "simple-syslog", version.ref = "simpleSyslogParser" } +nimbusJoseJwt = { group = "com.nimbusds", name = "nimbus-jose-jwt", version.ref = "nimbusJoseJwt" } + ############# ### test ### ############# diff --git a/modules/events-library/build.gradle.kts b/modules/events-library/build.gradle.kts index 4fc31c9..0c5f892 100644 --- a/modules/events-library/build.gradle.kts +++ b/modules/events-library/build.gradle.kts @@ -51,9 +51,9 @@ kotlin { dependencies { implementation(dependencies.platform(projects.modules.versionsPlatform)) - implementation(libs.kotlinx.serialization.core) - implementation(libs.kotlinx.serialization.json) - api(libs.kxs.kxsTsGen) + implementation(libs.kotlinxSerialization.core) + implementation(libs.kotlinxSerialization.json) + api(libs.kotlinxSerialization.kxsTsGen) implementation(libs.okio.core) diff --git a/modules/events-processor-core/build.gradle.kts b/modules/events-processor-core/build.gradle.kts new file mode 100644 index 0000000..7b92be6 --- /dev/null +++ b/modules/events-processor-core/build.gradle.kts @@ -0,0 +1,54 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + + +plugins { + dev.adamko.kafkatorio.lang.`kotlin-jvm` + kotlin("plugin.serialization") + application +} + + +//description = "serves Kafkatorio content over the web" + +val projectId: String by project.extra + +val kafkaStateDir: Directory = layout.projectDirectory.dir("kafka-state") + + +dependencies { + implementation(platform(projects.modules.versionsPlatform)) + + implementation(libs.kafka.streams) + testImplementation(libs.kafka.streamsTestUtils) + + implementation(projects.modules.eventsLibrary) + + implementation(libs.kotlinxSerialization.core) + implementation(libs.kotlinxSerialization.json) + + implementation(libs.kotlinx.coroutines.core) + + implementation(libs.bundles.logging) + + implementation(libs.scrimage.core) + + implementation(libs.okio.core) + + implementation(libs.simpleSyslogParser) + + implementation(libs.kafka.kotkaStreams) +} + + +application { + mainClass.set("dev.adamko.kafkatorio.server.EventsServerKt") +} + + +tasks.withType().configureEach { + kotlinOptions.freeCompilerArgs += listOf( + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlinx.coroutines.FlowPreview", + "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", + ) +} diff --git a/modules/events-processor-entities/build.gradle.kts b/modules/events-processor-entities/build.gradle.kts new file mode 100644 index 0000000..7b92be6 --- /dev/null +++ b/modules/events-processor-entities/build.gradle.kts @@ -0,0 +1,54 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + + +plugins { + dev.adamko.kafkatorio.lang.`kotlin-jvm` + kotlin("plugin.serialization") + application +} + + +//description = "serves Kafkatorio content over the web" + +val projectId: String by project.extra + +val kafkaStateDir: Directory = layout.projectDirectory.dir("kafka-state") + + +dependencies { + implementation(platform(projects.modules.versionsPlatform)) + + implementation(libs.kafka.streams) + testImplementation(libs.kafka.streamsTestUtils) + + implementation(projects.modules.eventsLibrary) + + implementation(libs.kotlinxSerialization.core) + implementation(libs.kotlinxSerialization.json) + + implementation(libs.kotlinx.coroutines.core) + + implementation(libs.bundles.logging) + + implementation(libs.scrimage.core) + + implementation(libs.okio.core) + + implementation(libs.simpleSyslogParser) + + implementation(libs.kafka.kotkaStreams) +} + + +application { + mainClass.set("dev.adamko.kafkatorio.server.EventsServerKt") +} + + +tasks.withType().configureEach { + kotlinOptions.freeCompilerArgs += listOf( + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlinx.coroutines.FlowPreview", + "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", + ) +} diff --git a/modules/events-processor-packets/build.gradle.kts b/modules/events-processor-packets/build.gradle.kts new file mode 100644 index 0000000..7b92be6 --- /dev/null +++ b/modules/events-processor-packets/build.gradle.kts @@ -0,0 +1,54 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + + +plugins { + dev.adamko.kafkatorio.lang.`kotlin-jvm` + kotlin("plugin.serialization") + application +} + + +//description = "serves Kafkatorio content over the web" + +val projectId: String by project.extra + +val kafkaStateDir: Directory = layout.projectDirectory.dir("kafka-state") + + +dependencies { + implementation(platform(projects.modules.versionsPlatform)) + + implementation(libs.kafka.streams) + testImplementation(libs.kafka.streamsTestUtils) + + implementation(projects.modules.eventsLibrary) + + implementation(libs.kotlinxSerialization.core) + implementation(libs.kotlinxSerialization.json) + + implementation(libs.kotlinx.coroutines.core) + + implementation(libs.bundles.logging) + + implementation(libs.scrimage.core) + + implementation(libs.okio.core) + + implementation(libs.simpleSyslogParser) + + implementation(libs.kafka.kotkaStreams) +} + + +application { + mainClass.set("dev.adamko.kafkatorio.server.EventsServerKt") +} + + +tasks.withType().configureEach { + kotlinOptions.freeCompilerArgs += listOf( + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlinx.coroutines.FlowPreview", + "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", + ) +} diff --git a/modules/events-processor-tiles/build.gradle.kts b/modules/events-processor-tiles/build.gradle.kts new file mode 100644 index 0000000..7b92be6 --- /dev/null +++ b/modules/events-processor-tiles/build.gradle.kts @@ -0,0 +1,54 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + + +plugins { + dev.adamko.kafkatorio.lang.`kotlin-jvm` + kotlin("plugin.serialization") + application +} + + +//description = "serves Kafkatorio content over the web" + +val projectId: String by project.extra + +val kafkaStateDir: Directory = layout.projectDirectory.dir("kafka-state") + + +dependencies { + implementation(platform(projects.modules.versionsPlatform)) + + implementation(libs.kafka.streams) + testImplementation(libs.kafka.streamsTestUtils) + + implementation(projects.modules.eventsLibrary) + + implementation(libs.kotlinxSerialization.core) + implementation(libs.kotlinxSerialization.json) + + implementation(libs.kotlinx.coroutines.core) + + implementation(libs.bundles.logging) + + implementation(libs.scrimage.core) + + implementation(libs.okio.core) + + implementation(libs.simpleSyslogParser) + + implementation(libs.kafka.kotkaStreams) +} + + +application { + mainClass.set("dev.adamko.kafkatorio.server.EventsServerKt") +} + + +tasks.withType().configureEach { + kotlinOptions.freeCompilerArgs += listOf( + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlinx.coroutines.FlowPreview", + "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", + ) +} diff --git a/modules/events-server-api/build.gradle.kts b/modules/events-server-api/build.gradle.kts new file mode 100644 index 0000000..63de5d8 --- /dev/null +++ b/modules/events-server-api/build.gradle.kts @@ -0,0 +1,81 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + + +plugins { + dev.adamko.kafkatorio.lang.`kotlin-jvm` + kotlin("plugin.serialization") + application +} + + +//description = "serves Kafkatorio content over the web" + +val projectId: String by project.extra + +val kafkaStateDir: Directory = layout.projectDirectory.dir("kafka-state") + + +dependencies { + implementation(platform(projects.modules.versionsPlatform)) + + implementation(libs.kafka.streams) + testImplementation(libs.kafka.streamsTestUtils) + + implementation(projects.modules.eventsLibrary) + + implementation(libs.kotlinxSerialization.core) + implementation(libs.kotlinxSerialization.json) + + implementation(libs.kotlinx.coroutines.core) + + implementation(libs.bundles.logging) + + implementation(libs.scrimage.core) + + implementation(libs.okio.core) + + // + implementation(libs.ktorSerialization.kotlinxJson) + + with(libs.ktorServer) { + implementation(auth) + implementation(authJwt) + implementation(core) + implementation(callId) + implementation(callLogging) + implementation(contentNegotiaion) + implementation(cio) + implementation(autoHeadResponse) + implementation(partialContent) + implementation(resources) + implementation(statusPages) + implementation(websockets) + implementation(compression) + } + + with(libs.ktorNetwork) { + implementation(core) + implementation(tls) + } + // + + implementation(libs.simpleSyslogParser) + +// implementation(libs.nimbusJoseJwt) + + implementation(libs.kafka.kotkaStreams) +} + + +application { + mainClass.set("dev.adamko.kafkatorio.server.EventsServerKt") +} + + +tasks.withType().configureEach { + kotlinOptions.freeCompilerArgs += listOf( + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlinx.coroutines.FlowPreview", + "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", + ) +} diff --git a/modules/events-server-core/build.gradle.kts b/modules/events-server-core/build.gradle.kts new file mode 100644 index 0000000..1172be0 --- /dev/null +++ b/modules/events-server-core/build.gradle.kts @@ -0,0 +1,79 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + + +plugins { + dev.adamko.kafkatorio.lang.`kotlin-jvm` + kotlin("plugin.serialization") + application +} + + +//description = "serves Kafkatorio content over the web" + +val projectId: String by project.extra + + +dependencies { + implementation(platform(projects.modules.versionsPlatform)) + + implementation(libs.kafka.streams) + testImplementation(libs.kafka.streamsTestUtils) + + implementation(projects.modules.eventsLibrary) + + implementation(libs.kotlinxSerialization.core) + implementation(libs.kotlinxSerialization.json) + + implementation(libs.kotlinx.coroutines.core) + + implementation(libs.bundles.logging) + + implementation(libs.scrimage.core) + + implementation(libs.okio.core) + + // + implementation(libs.ktorSerialization.kotlinxJson) + + with(libs.ktorServer) { + implementation(auth) + implementation(authJwt) + implementation(core) + implementation(callId) + implementation(callLogging) + implementation(contentNegotiaion) + implementation(cio) + implementation(autoHeadResponse) + implementation(partialContent) + implementation(resources) + implementation(statusPages) + implementation(websockets) + implementation(compression) + } + + with(libs.ktorNetwork) { + implementation(core) + implementation(tls) + } + // + + implementation(libs.simpleSyslogParser) + +// implementation(libs.nimbusJoseJwt) + + implementation(libs.kafka.kotkaStreams) +} + + +application { + mainClass.set("dev.adamko.kafkatorio.server.EventsServerKt") +} + + +tasks.withType().configureEach { + kotlinOptions.freeCompilerArgs += listOf( + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlinx.coroutines.FlowPreview", + "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", + ) +} diff --git a/modules/events-server-syslog/build.gradle.kts b/modules/events-server-syslog/build.gradle.kts new file mode 100644 index 0000000..1172be0 --- /dev/null +++ b/modules/events-server-syslog/build.gradle.kts @@ -0,0 +1,79 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + + +plugins { + dev.adamko.kafkatorio.lang.`kotlin-jvm` + kotlin("plugin.serialization") + application +} + + +//description = "serves Kafkatorio content over the web" + +val projectId: String by project.extra + + +dependencies { + implementation(platform(projects.modules.versionsPlatform)) + + implementation(libs.kafka.streams) + testImplementation(libs.kafka.streamsTestUtils) + + implementation(projects.modules.eventsLibrary) + + implementation(libs.kotlinxSerialization.core) + implementation(libs.kotlinxSerialization.json) + + implementation(libs.kotlinx.coroutines.core) + + implementation(libs.bundles.logging) + + implementation(libs.scrimage.core) + + implementation(libs.okio.core) + + // + implementation(libs.ktorSerialization.kotlinxJson) + + with(libs.ktorServer) { + implementation(auth) + implementation(authJwt) + implementation(core) + implementation(callId) + implementation(callLogging) + implementation(contentNegotiaion) + implementation(cio) + implementation(autoHeadResponse) + implementation(partialContent) + implementation(resources) + implementation(statusPages) + implementation(websockets) + implementation(compression) + } + + with(libs.ktorNetwork) { + implementation(core) + implementation(tls) + } + // + + implementation(libs.simpleSyslogParser) + +// implementation(libs.nimbusJoseJwt) + + implementation(libs.kafka.kotkaStreams) +} + + +application { + mainClass.set("dev.adamko.kafkatorio.server.EventsServerKt") +} + + +tasks.withType().configureEach { + kotlinOptions.freeCompilerArgs += listOf( + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlinx.coroutines.FlowPreview", + "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", + ) +} diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 5052189..8613f5c 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -25,8 +25,8 @@ dependencies { implementation(projects.modules.eventsLibrary) - implementation(libs.kotlinx.serialization.core) - implementation(libs.kotlinx.serialization.json) + implementation(libs.kotlinxSerialization.core) + implementation(libs.kotlinxSerialization.json) implementation(libs.kotlinx.coroutines.core) @@ -63,14 +63,14 @@ dependencies { implementation(libs.simpleSyslogParser) - // https://search.maven.org/artifact/org.bouncycastle/bcprov-jdk15on - implementation("org.bouncycastle:bcprov-jdk15on:1.70") - implementation("com.brendangoldberg:kotlin-jwt:1.1.0") - implementation("com.auth0:java-jwt:4.0.0") +// // https://search.maven.org/artifact/org.bouncycastle/bcprov-jdk15on +// implementation("org.bouncycastle:bcprov-jdk15on:1.70") +// implementation("com.brendangoldberg:kotlin-jwt:1.1.0") +// implementation("com.auth0:java-jwt:4.0.0") - implementation(libs.kafka.kotkaStreams) { - isChanging = false - } +// implementation(libs.nimbusJoseJwt) + + implementation(libs.kafka.kotkaStreams) implementation(libs.bundles.hoplite) } diff --git a/modules/versions-platform/build.gradle.kts b/modules/versions-platform/build.gradle.kts index c1f3914..3b2c234 100644 --- a/modules/versions-platform/build.gradle.kts +++ b/modules/versions-platform/build.gradle.kts @@ -11,7 +11,7 @@ javaPlatform { dependencies { api(platform(libs.kotlin.bom)) api(platform(libs.kotlinx.coroutines.bom)) - api(platform(libs.kotlinx.serialization.bom)) + api(platform(libs.kotlinxSerialization.bom)) api(platform(libs.kotlin.jsWrappers.bom)) @@ -28,9 +28,9 @@ dependencies { api(libs.kafka.streams) api(libs.kafka.streamsTestUtils) - api(libs.kxs.charleskornKaml) - api(libs.kxs.mamoeYamlkt) - api(libs.kxs.kxsTsGen) + api(libs.kotlinxSerialization.charleskornKaml) + api(libs.kotlinxSerialization.mamoeYamlkt) + api(libs.kotlinxSerialization.kxsTsGen) api(libs.okio.core) diff --git a/settings.gradle.kts b/settings.gradle.kts index b72e1b1..13ece3e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,9 +1,19 @@ rootProject.name = "kafkatorio" include( - ":modules:events-mod", ":modules:events-library", + + ":modules:events-mod", + + ":modules:events-processor-core", + ":modules:events-processor-entities", + ":modules:events-processor-packets", + ":modules:events-processor-tiles", + ":modules:events-server", + ":modules:events-server-api", + ":modules:events-server-core", + ":modules:events-server-syslog", ":modules:infra-factorio-client", ":modules:infra-factorio-server", From d82f25c6ee062febbaa532280ad6fdf85f822984 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 12 Sep 2022 21:38:01 +0200 Subject: [PATCH 515/629] prep migrating buildSrc plugins to includeBuild plugins --- .../builder-plugins/settings.gradle.kts | 31 ++++++++ .../factorio-mod-manager/settings.gradle.kts | 31 ++++++++ .../settings-plugins/build.gradle.kts | 24 ++++++ .../settings-plugins/settings.gradle.kts | 25 ++++++ .../convention/settings/repositories.kt | 77 +++++++++++++++++++ .../settings/repositories.settings.gradle.kts | 44 +++++++++++ 6 files changed, 232 insertions(+) create mode 100644 gradle-plugins/builder-plugins/settings.gradle.kts create mode 100644 gradle-plugins/factorio-mod-manager/settings.gradle.kts create mode 100644 gradle-plugins/settings-plugins/build.gradle.kts create mode 100644 gradle-plugins/settings-plugins/settings.gradle.kts create mode 100644 gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.kt create mode 100644 gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.settings.gradle.kts diff --git a/gradle-plugins/builder-plugins/settings.gradle.kts b/gradle-plugins/builder-plugins/settings.gradle.kts new file mode 100644 index 0000000..ba1c7f1 --- /dev/null +++ b/gradle-plugins/builder-plugins/settings.gradle.kts @@ -0,0 +1,31 @@ +@file:Suppress("UnstableApiUsage") + +rootProject.name = "builder-plugins" + + +pluginManagement { + includeBuild("../settings-plugins/") +} + + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + + repositories { + mavenCentral() + gradlePluginPortal() + } + + pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + } + } + + versionCatalogs { + create("libs") { + from(files("../../gradle/libs.versions.toml")) + } + } +} diff --git a/gradle-plugins/factorio-mod-manager/settings.gradle.kts b/gradle-plugins/factorio-mod-manager/settings.gradle.kts new file mode 100644 index 0000000..7fafd65 --- /dev/null +++ b/gradle-plugins/factorio-mod-manager/settings.gradle.kts @@ -0,0 +1,31 @@ +@file:Suppress("UnstableApiUsage") + +rootProject.name = "factorio-mod-manager" + + +pluginManagement { + includeBuild("../settings-plugins/") +} + + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + + repositories { + mavenCentral() + gradlePluginPortal() + } + + pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + } + } + + versionCatalogs { + create("libs") { + from(files("../../gradle/libs.versions.toml")) + } + } +} diff --git a/gradle-plugins/settings-plugins/build.gradle.kts b/gradle-plugins/settings-plugins/build.gradle.kts new file mode 100644 index 0000000..67a25ac --- /dev/null +++ b/gradle-plugins/settings-plugins/build.gradle.kts @@ -0,0 +1,24 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + `kotlin-dsl` + kotlin("jvm") version embeddedKotlinVersion +} + +val gradleJvmTarget = "11" + +kotlin { + jvmToolchain { + (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) + } + + kotlinDslPluginOptions { + jvmTarget.set(gradleJvmTarget) + } +} + +tasks.withType().configureEach { + kotlinOptions { + jvmTarget = gradleJvmTarget + } +} diff --git a/gradle-plugins/settings-plugins/settings.gradle.kts b/gradle-plugins/settings-plugins/settings.gradle.kts new file mode 100644 index 0000000..eef7211 --- /dev/null +++ b/gradle-plugins/settings-plugins/settings.gradle.kts @@ -0,0 +1,25 @@ +rootProject.name = "settings-plugins" + + +@Suppress("UnstableApiUsage") // Central declaration of repositories is an incubating feature +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + + repositories { + mavenCentral() + gradlePluginPortal() + } + + pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + } + } + + versionCatalogs { + create("libs") { + from(files("../../gradle/libs.versions.toml")) + } + } +} diff --git a/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.kt b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.kt new file mode 100644 index 0000000..49df5f0 --- /dev/null +++ b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.kt @@ -0,0 +1,77 @@ +@file:Suppress("PackageDirectoryMismatch") + +package org.gradle.kotlin.dsl + +import org.gradle.api.artifacts.dsl.RepositoryHandler + + +fun RepositoryHandler.jitpack() { + maven("https://jitpack.io") +} + + +fun RepositoryHandler.myMavenLocal(enabled: Boolean = true) { + if (enabled) { + println("Maven local is enabled") + mavenLocal { + content { +// includeGroup("dev.adamko") +// includeGroup("dev.adamko.kxtsgen") + includeGroup("io.kotest") + } + } + } +} + + +fun RepositoryHandler.sonatypeSnapshot() { + maven("https://oss.sonatype.org/content/repositories/snapshots") { + mavenContent { + snapshotsOnly() + includeGroup("io.kotest") + } + } + maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") { + mavenContent { + snapshotsOnly() + includeGroup("io.kotest") + } + } +} + + +fun RepositoryHandler.nodeDistributions() { + // Declare the Node.js download repository + ivy("https://nodejs.org/dist/") { + name = "Node Distributions at $url" + patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") } + metadataSources { artifact() } + content { includeModule("org.nodejs", "node") } + } +} + + +fun RepositoryHandler.yarnDistributions() { + ivy("https://github.com/yarnpkg/yarn/releases/download") { + name = "Yarn Distributions at $url" + patternLayout { artifact("v[revision]/[artifact](-v[revision]).[ext]") } + metadataSources { artifact() } + content { includeModule("com.yarnpkg", "yarn") } + } +} + + +// https://stackoverflow.com/a/34327202/4161471 +// example: implementation("jmeter-gradle-plugin:jmeter-gradle-plugin:1.0.3@zip") +fun RepositoryHandler.gitHub() { + ivy("https://github.com/") { + patternLayout { + artifact("/[organisation]/[module]/archive/[revision].[ext]") + } + metadataSources { artifact() } + + content { + includeGroup("jmeter-gradle-plugin") + } + } +} diff --git a/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.settings.gradle.kts b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.settings.gradle.kts new file mode 100644 index 0000000..985683f --- /dev/null +++ b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.settings.gradle.kts @@ -0,0 +1,44 @@ +package kafkatorio.convention.settings + +@Suppress("UnstableApiUsage") // Central declaration of repositories is an incubating feature +dependencyResolutionManagement { + + // https://github.com/gradle/gradle/issues/15754#issuecomment-763614651 + // https://github.com/gradle/gradle/blob/09fcaacc9848f09aa584b4119be9271bee6916e6/build-logic/build-logic-base/settings-plugin/src/main/kotlin/gradlebuild.repositories.settings.gradle.kts#L68 + + // Cannot use 'FAIL_ON_PROJECT_REPOS' because + // - the 'gradle-guides-plugin' adds a repo (which it should not do) + // - the 'kotlin-gradle-plugin' adds a repo (and removes it afterwards) to download NodeJS +// repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + + repositories { + myMavenLocal() + mavenCentral() + jitpack() + gradlePluginPortal() + + // Declare the Node.js download repository + nodeDistributions() + yarnDistributions() + + maven("https://raw.githubusercontent.com/adamko-dev/kotka-streams/artifacts/m2") { + content { includeGroup("dev.adamko.kotka") } + } + + maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") { + content { includeGroup("org.jetbrains.kotlinx") } + } + + sonatypeSnapshot() + } + + pluginManagement { + repositories { + myMavenLocal() + gradlePluginPortal() + mavenCentral() + jitpack() + sonatypeSnapshot() + } + } +} From 873983f9a3fb7eee13aa37d8492e13e8205d1ef2 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 13 Sep 2022 17:56:57 +0200 Subject: [PATCH 516/629] big ol' refactor to split up the events-server and events-processors --- .gitignore | 112 +---- build.gradle.kts | 70 +-- .../dev/adamko/kafkatorio/base.gradle.kts | 2 - .../adamko/kafkatorio/gradle/extensions.kt | 22 + gradle/libs.versions.toml | 2 +- .../events-processor-core/build.gradle.kts | 24 +- .../processor/admin/KafkatorioKafkaAdmin.kt | 8 +- .../adamko/kafkatorio/processor/admin/main.kt | 10 + .../config/ApplicationProperties.kt | 10 +- .../kafkatorio/processor}/config/PortVal.kt | 2 +- .../processor/config}/kafkatorioTopics.kt | 2 +- .../kafkatorio/processor/config/kxsJson.kt | 12 + .../processor/core}/Authenticator.kt | 4 +- .../processor/core}/DebounceProcessor.kt | 2 +- .../core}/StreamsExceptionHandler.kt | 2 +- .../processor/core/topologyLauncher.kt | 88 ++++ .../processor/topology/colourMapChunks.kt | 6 +- .../topology/colourResourceChunks.kt | 6 +- .../topology/factorioServerPackets.kt | 6 +- .../server/processor/topology/model.kt | 0 .../processor/topology/packetDataStreams.kt | 4 +- .../server/processor/topology/prototypes.kt | 0 .../server/processor/topology/saveMapTiles.kt | 14 +- .../topology/websocketBroadcaster.kt | 14 +- .../src/main/resources/config.yml | 6 +- .../kafka/streams/state/annotations.xml | 0 .../src/main/resources/logback.xml | 0 .../processor/core}/AuthenticatorTest.kt | 2 +- .../processor/core}/misc/serdeSize.kt | 0 .../topology/FactorioServerPacketsTest.kt | 2 +- .../core}/topology/GroupMapChunksTest.kt | 2 +- .../core}/topology/SaveMapChunksTest.kt | 2 +- .../build.gradle.kts | 54 --- .../events-processor-packets/build.gradle.kts | 54 --- .../events-processor-tiles/build.gradle.kts | 54 --- modules/events-processors/build.gradle.kts | 91 ++++ .../processors/groupEntitiesMapChunks.kt | 54 +++ .../processors/groupTilesMapChunks.kt | 23 + .../dev/adamko/kafkatorio/processors/main.kt | 36 ++ .../kafkatorio/processors/splitPackets.kt | 17 + modules/events-server-core/build.gradle.kts | 79 ---- modules/events-server-syslog/build.gradle.kts | 13 +- .../events-server-syslog/docker/Dockerfile | 11 + .../syslog}/KafkatorioPacketKafkaProducer.kt | 12 +- .../kafkatorio/processor/syslog}/SyslogMsg.kt | 2 +- .../processor/syslog}/SyslogSocketServer.kt | 4 +- .../processor/syslog/config/kxsJson.kt | 12 + .../kafkatorio/processor/syslog/syslogMain.kt | 20 + .../build.gradle.kts | 16 +- .../kafkatorio/server/web}/config/kxsJson.kt | 4 +- .../dev/adamko/kafkatorio/server/web/main.kt | 61 +++ .../server/web/rest/factorioServersRoutes.kt | 6 +- .../kafkatorio/server/web/rest/restApi.kt | 4 +- .../adamko/kafkatorio/server/web/webServer.kt | 5 +- .../web/websocket/WebmapWebsocketServer.kt | 9 +- .../server/web/websocket/wsServer.kt | 0 modules/events-server/build.gradle.kts | 4 +- modules/events-server/docker/Dockerfile | 2 +- .../adamko/kafkatorio/server/eventsServer.kt | 56 +-- .../server/processor/KafkatorioTopology.kt | 432 +++++++++--------- .../server/processor/eventProcessor.kt | 64 +-- .../infra-factorio-client/build.gradle.kts | 7 + .../infra-factorio-server/build.gradle.kts | 8 +- .../src/docker-compose.yml | 2 +- modules/infra-kafka-cluster/build.gradle.kts | 6 + modules/infra-kafka-cluster/src/.env | 4 +- modules/modules.md | 36 ++ modules/web-map/build.gradle.kts | 7 + .../dev/adamko/kafkatorio/webmap/App.kt | 14 +- .../adamko/kafkatorio/webmap/FactorioMap.kt | 24 + settings.gradle.kts | 27 +- 71 files changed, 1013 insertions(+), 757 deletions(-) rename modules/{events-server/src/main/kotlin/dev/adamko/kafkatorio/server => events-processor-core/src/main/kotlin/dev/adamko/kafkatorio}/processor/admin/KafkatorioKafkaAdmin.kt (90%) create mode 100644 modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/main.kt rename modules/{events-server/src/main/kotlin/dev/adamko/kafkatorio/server => events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor}/config/ApplicationProperties.kt (76%) rename modules/{events-server/src/main/kotlin/dev/adamko/kafkatorio/server => events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor}/config/PortVal.kt (90%) rename modules/{events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor => events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config}/kafkatorioTopics.kt (98%) create mode 100644 modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/kxsJson.kt rename modules/{events-server/src/main/kotlin/dev/adamko/kafkatorio/server/security => events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core}/Authenticator.kt (97%) rename modules/{events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor => events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core}/DebounceProcessor.kt (98%) rename modules/{events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor => events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core}/StreamsExceptionHandler.kt (91%) create mode 100644 modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/topologyLauncher.kt rename modules/{events-server => events-processor-core}/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt (98%) rename modules/{events-server => events-processor-core}/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourResourceChunks.kt (97%) rename modules/{events-server => events-processor-core}/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt (93%) rename modules/{events-server => events-processor-core}/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/model.kt (100%) rename modules/{events-server => events-processor-core}/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/packetDataStreams.kt (91%) rename modules/{events-server => events-processor-core}/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/prototypes.kt (100%) rename modules/{events-server => events-processor-core}/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt (94%) rename modules/{events-server => events-processor-core}/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/websocketBroadcaster.kt (89%) rename modules/{events-server => events-processor-core}/src/main/resources/config.yml (89%) rename modules/{events-server => events-processor-core}/src/main/resources/external-annotations/org/apache/kafka/streams/state/annotations.xml (100%) rename modules/{events-server => events-processor-core}/src/main/resources/logback.xml (100%) rename modules/{events-server/src/test/kotlin/dev/adamko/kafkatorio/server/security => events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core}/AuthenticatorTest.kt (97%) rename modules/{events-server/src/test/kotlin/dev/adamko/kafkatorio/processor => events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core}/misc/serdeSize.kt (100%) rename modules/{events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor => events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core}/topology/FactorioServerPacketsTest.kt (96%) rename modules/{events-server/src/test/kotlin/dev/adamko/kafkatorio/processor => events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core}/topology/GroupMapChunksTest.kt (99%) rename modules/{events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor => events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core}/topology/SaveMapChunksTest.kt (99%) delete mode 100644 modules/events-processor-entities/build.gradle.kts delete mode 100644 modules/events-processor-packets/build.gradle.kts delete mode 100644 modules/events-processor-tiles/build.gradle.kts create mode 100644 modules/events-processors/build.gradle.kts create mode 100644 modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/groupEntitiesMapChunks.kt create mode 100644 modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/groupTilesMapChunks.kt create mode 100644 modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/main.kt create mode 100644 modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/splitPackets.kt delete mode 100644 modules/events-server-core/build.gradle.kts create mode 100644 modules/events-server-syslog/docker/Dockerfile rename modules/{events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor => events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog}/KafkatorioPacketKafkaProducer.kt (92%) rename modules/{events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket => events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog}/SyslogMsg.kt (96%) rename modules/{events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket => events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog}/SyslogSocketServer.kt (96%) create mode 100644 modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/config/kxsJson.kt create mode 100644 modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/syslogMain.kt rename modules/{events-server-api => events-server-web}/build.gradle.kts (81%) rename modules/{events-server/src/main/kotlin/dev/adamko/kafkatorio/server => events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web}/config/kxsJson.kt (70%) create mode 100644 modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/main.kt rename modules/{events-server => events-server-web}/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt (95%) rename modules/{events-server => events-server-web}/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/restApi.kt (92%) rename modules/{events-server => events-server-web}/src/main/kotlin/dev/adamko/kafkatorio/server/web/webServer.kt (85%) rename modules/{events-server => events-server-web}/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt (92%) rename modules/{events-server => events-server-web}/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/wsServer.kt (100%) create mode 100644 modules/modules.md diff --git a/.gitignore b/.gitignore index a9942d5..fc1afcd 100644 --- a/.gitignore +++ b/.gitignore @@ -2,10 +2,12 @@ # ignore any files that start with '.secret' .secret.* -.idea +.state/ + +.idea/ !.idea/icon.svg -node_modules +node_modules/ *.hprof @@ -16,108 +18,13 @@ node_modules # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# AWS User-specific -.idea/**/aws.xml - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -.idea/artifacts -.idea/compiler.xml -.idea/jarRepositories.xml -.idea/modules.xml -.idea/*.iml -.idea/modules +# File-based project format +*.iws *.iml *.ipr -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ out/ -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -### Intellij Patch ### -# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 - -# *.iml -# modules.xml -# .idea/misc.xml -# *.ipr - -# Sonarlint plugin -# https://plugins.jetbrains.com/plugin/7973-sonarlint -.idea/**/sonarlint/ - -# SonarQube Plugin -# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin -.idea/**/sonarIssues.xml - -# Markdown Navigator plugin -# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced -.idea/**/markdown-navigator.xml -.idea/**/markdown-navigator-enh.xml -.idea/**/markdown-navigator/ - -# Cache file creation bug -# See https://youtrack.jetbrains.com/issue/JBR-2257 -.idea/$CACHE_FILE$ - -# CodeStream plugin -# https://plugins.jetbrains.com/plugin/12206-codestream -.idea/codestream.xml - ### Kotlin ### # Compiled class file *.class @@ -125,12 +32,6 @@ fabric.properties # Log file *.log -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - # Package Files # *.jar *.war @@ -198,7 +99,6 @@ Temporary Items # Local History for Visual Studio Code .history/ -### VisualStudioCode Patch ### # Ignore all local history of files .history .ionide diff --git a/build.gradle.kts b/build.gradle.kts index da1e252..51241c3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -41,17 +41,17 @@ tasks.wrapper { } val startInfra by tasks.registering { - group = project.name + group = rootProject.name dependsOn( // ":modules:infra-kafka-pipe:processRun", - runKafkaCluster +// runKafkaCluster // ":modules:infra-kafka-connect:processRun", ) } val runKafkatorio by tasks.registering { - group = project.name + group = rootProject.name dependsOn( ":modules:infra-factorio-client:processRestart", @@ -60,44 +60,44 @@ val runKafkatorio by tasks.registering { ) } -val runEventsServer by tasks.registering { - group = project.name +//val runEventsServer by tasks.registering { +// group = project.name +// +// dependsOn(":modules:events-server:run") +//} - dependsOn(":modules:events-server:run") -} +//val runWebMap by tasks.registering { +// group = project.name +// +// dependsOn(":modules:web-map:browserDevelopmentRun") +//} -val runWebMap by tasks.registering { - group = project.name - - dependsOn(":modules:web-map:browserDevelopmentRun") -} +// +//val runKafkaCluster by tasks.registering { +// group = project.name +// +// dependsOn( +// ":modules:infra-kafka-cluster:processRun", +// ) +//} -val runKafkaCluster by tasks.registering { - group = project.name - - dependsOn( - ":modules:infra-kafka-cluster:processRun", - ) -} +//val runFactorioServer by tasks.registering { +// group = project.name +// +// dependsOn( +// ":modules:infra-factorio-server:processRun", +// ) +//} -val runFactorioServer by tasks.registering { - group = project.name - - dependsOn( - ":modules:infra-factorio-server:processRun", - ) -} - - -val runFactorioClient by tasks.registering { - group = project.name - - dependsOn( - ":modules:infra-factorio-client:processRun", - ) -} +//val runFactorioClient by tasks.registering { +// group = project.name +// +// dependsOn( +// ":modules:infra-factorio-client:processRun", +// ) +//} apply(from = "$projectDir/kt52647.gradle.kts") diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts index 1352a4e..19385e5 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts @@ -1,7 +1,5 @@ package dev.adamko.kafkatorio -import org.gradle.api.internal.tasks.userinput.UserInputHandler -import org.gradle.kotlin.dsl.support.serviceOf plugins { base diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt index 7693f66..f3c0743 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt @@ -7,9 +7,13 @@ import org.gradle.api.file.Directory import org.gradle.api.file.FileCopyDetails import org.gradle.api.file.ProjectLayout import org.gradle.api.file.RelativePath +import org.gradle.api.plugins.JavaPlugin import org.gradle.api.provider.Provider import org.gradle.api.specs.NotSpec import org.gradle.api.specs.Spec +import org.gradle.api.tasks.TaskProvider +import org.gradle.api.tasks.application.CreateStartScripts +import org.gradle.kotlin.dsl.register import org.gradle.plugins.ide.idea.model.IdeaModule import org.gradle.process.ExecSpec import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension @@ -94,3 +98,21 @@ fun Project.taskProvider(taskName: String): Provider = providers.provider const val DOCKER_COMPOSE_TASK_GROUP = "docker-compose" + + +fun Project.registerStartScriptTask( + appName: String, + configureStartScripts: CreateStartScripts.() -> Unit = {}, +): TaskProvider = + tasks.register("startScript$appName") { + + val jarTask = tasks.getByName(JavaPlugin.JAR_TASK_NAME) + val runtimeClasspath = configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME) + dependsOn(jarTask) + dependsOn(runtimeClasspath) + + applicationName = appName + outputDir = layout.buildDirectory.dir("scripts").get().asFile + classpath = jarTask.outputs.files + runtimeClasspath + configureStartScripts() + } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2833d4e..8233f44 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ kotlin = "1.7.10" ## libs ## camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" -kafka = "3.2.1" # https://kafka.apache.org/downloads +kafka = "3.2.2" # https://kafka.apache.org/downloads kvision = "5.14.0" # https://github.com/rjaros/kvision/releases log4j2 = "2.17.2" okio = "3.2.0" # https://search.maven.org/artifact/com.squareup.okio/okio diff --git a/modules/events-processor-core/build.gradle.kts b/modules/events-processor-core/build.gradle.kts index 7b92be6..f681852 100644 --- a/modules/events-processor-core/build.gradle.kts +++ b/modules/events-processor-core/build.gradle.kts @@ -4,15 +4,15 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { dev.adamko.kafkatorio.lang.`kotlin-jvm` kotlin("plugin.serialization") - application +// application } -//description = "serves Kafkatorio content over the web" +description = "Shared Kafkatorio processors functionality" val projectId: String by project.extra -val kafkaStateDir: Directory = layout.projectDirectory.dir("kafka-state") +val kafkaStateDir: Directory = layout.projectDirectory.dir(".state/kafka") dependencies { @@ -37,12 +37,17 @@ dependencies { implementation(libs.simpleSyslogParser) implementation(libs.kafka.kotkaStreams) + + implementation(libs.bundles.hoplite) + + implementation(libs.ktorServer.authJwt) +// implementation(libs.nimbusJoseJwt) } -application { - mainClass.set("dev.adamko.kafkatorio.server.EventsServerKt") -} +//application { +// mainClass.set("dev.adamko.kafkatorio.processor.admin.MainKt") +//} tasks.withType().configureEach { @@ -52,3 +57,10 @@ tasks.withType().configureEach { "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", ) } + + +val createKafkaTopics by tasks.registering(JavaExec::class) { + group = rootProject.name + classpath = sourceSets.main.get().runtimeClasspath + mainClass.set("dev.adamko.kafkatorio.processor.admin.MainKt") +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/admin/KafkatorioKafkaAdmin.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt similarity index 90% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/admin/KafkatorioKafkaAdmin.kt rename to modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt index a052945..889ab1f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/admin/KafkatorioKafkaAdmin.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt @@ -1,7 +1,7 @@ -package dev.adamko.kafkatorio.server.processor.admin +package dev.adamko.kafkatorio.processor.admin -import dev.adamko.kafkatorio.server.config.ApplicationProperties -import dev.adamko.kafkatorio.server.processor.allTopics +import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.processor.config.allTopics import java.util.concurrent.TimeUnit import mu.KotlinLogging import org.apache.kafka.clients.admin.Admin @@ -11,7 +11,7 @@ import org.apache.kafka.clients.admin.TopicListing class KafkatorioKafkaAdmin( - appProps: ApplicationProperties + appProps: ApplicationProperties, ) { private val logger = KotlinLogging.logger {} diff --git a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/main.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/main.kt new file mode 100644 index 0000000..7819a59 --- /dev/null +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/main.kt @@ -0,0 +1,10 @@ +package dev.adamko.kafkatorio.processor.admin + +import dev.adamko.kafkatorio.processor.config.ApplicationProperties + + +fun main() { + val appProps = ApplicationProperties.load() + val admin = KafkatorioKafkaAdmin(appProps) + admin.createKafkatorioTopics() +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/ApplicationProperties.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt similarity index 76% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/ApplicationProperties.kt rename to modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt index 9b7d7a4..7d8a020 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/ApplicationProperties.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt @@ -1,15 +1,16 @@ -package dev.adamko.kafkatorio.server.config +package dev.adamko.kafkatorio.processor.config import com.sksamuel.hoplite.ConfigLoaderBuilder import com.sksamuel.hoplite.addEnvironmentSource import com.sksamuel.hoplite.addResourceOrFileSource +import com.sksamuel.hoplite.sources.UserSettingsPropertySource import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.FactorioServerToken import dev.adamko.kafkatorio.schema.common.MaskedValue import java.nio.file.Path +val appProps = ApplicationProperties.load() -// loaded by hoplite data class ApplicationProperties( val webPort: PortVal, val serverDataDir: Path, @@ -32,8 +33,13 @@ data class ApplicationProperties( .allowUnresolvedSubstitutions() .allowEmptySources() .addEnvironmentSource() + .addResourceOrFileSource( + resourceOrFile = "${System.getProperty("user.home")}/.secret.kafkatorio-config.yml", + optional = true + ) .addResourceOrFileSource("/.secret.config.yml", optional = true) .addResourceOrFileSource("/config.yml", optional = false) + .addPropertySource(UserSettingsPropertySource) .build() .loadConfigOrThrow() } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/PortVal.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt similarity index 90% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/PortVal.kt rename to modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt index a4c48c8..29ebb4f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/PortVal.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.server.config +package dev.adamko.kafkatorio.processor.config /** Improved (slightly) version of http4k's `Port`. */ diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/kafkatorioTopics.kt similarity index 98% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt rename to modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/kafkatorioTopics.kt index b3af92d..36d70ba 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/kafkatorioTopics.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.server.processor +package dev.adamko.kafkatorio.processor.config import dev.adamko.kafkatorio.schema.packets.ConfigurationUpdate import dev.adamko.kafkatorio.schema.packets.ConsoleChatUpdate diff --git a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/kxsJson.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/kxsJson.kt new file mode 100644 index 0000000..364d089 --- /dev/null +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/kxsJson.kt @@ -0,0 +1,12 @@ +package dev.adamko.kafkatorio.processor.config + +import dev.adamko.kafkatorio.library.jsonMapperKafkatorio +import kotlinx.serialization.json.Json + + +@PublishedApi +internal val jsonMapper: Json = Json { + prettyPrint = true + prettyPrintIndent = " " + serializersModule = jsonMapperKafkatorio.serializersModule +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/security/Authenticator.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/Authenticator.kt similarity index 97% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/security/Authenticator.kt rename to modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/Authenticator.kt index 7c95183..dd842d5 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/security/Authenticator.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/Authenticator.kt @@ -1,10 +1,10 @@ -package dev.adamko.kafkatorio.server.security +package dev.adamko.kafkatorio.processor.core import com.auth0.jwt.JWT import com.auth0.jwt.algorithms.Algorithm import com.auth0.jwt.interfaces.DecodedJWT +import dev.adamko.kafkatorio.processor.config.ApplicationProperties import dev.adamko.kafkatorio.schema.common.FactorioServerToken -import dev.adamko.kafkatorio.server.config.ApplicationProperties import kotlin.reflect.jvm.jvmName import kotlinx.coroutines.CancellationException import kotlinx.serialization.SerialName diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/DebounceProcessor.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/DebounceProcessor.kt similarity index 98% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/DebounceProcessor.kt rename to modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/DebounceProcessor.kt index b3cd20f..e7aefda 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/DebounceProcessor.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/DebounceProcessor.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.server.processor +package dev.adamko.kafkatorio.processor.core import dev.adamko.kotka.extensions.component1 import dev.adamko.kotka.extensions.component2 diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/StreamsExceptionHandler.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/StreamsExceptionHandler.kt similarity index 91% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/StreamsExceptionHandler.kt rename to modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/StreamsExceptionHandler.kt index 03f0cc3..f29e953 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/StreamsExceptionHandler.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/StreamsExceptionHandler.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.server.processor +package dev.adamko.kafkatorio.processor.core import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler.StreamThreadExceptionResponse diff --git a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/topologyLauncher.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/topologyLauncher.kt new file mode 100644 index 0000000..03ff1cc --- /dev/null +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/topologyLauncher.kt @@ -0,0 +1,88 @@ +package dev.adamko.kafkatorio.processor.core + +import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import java.util.Properties +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.io.path.Path +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.cancel +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.currentCoroutineContext +import kotlinx.coroutines.job +import kotlinx.coroutines.launch +import kotlinx.coroutines.suspendCancellableCoroutine +import org.apache.kafka.streams.KafkaStreams +import org.apache.kafka.streams.StreamsConfig +import org.apache.kafka.streams.Topology +import org.apache.kafka.streams.TopologyDescription + + +private val appProps = ApplicationProperties.load() + +suspend fun launchTopology( + id: String, + topology: Topology, + additionalProperties: Map = mapOf(), +): Unit = coroutineScope { + + val props: Properties = appProps.kafkaStreamsConfig.toProperties() + + additionalProperties.forEach { (k, v) -> props.setProperty(k, v) } + + val appId = props.compute(StreamsConfig.APPLICATION_ID_CONFIG) { _, v -> "$v.$id" } as String + props.setProperty(StreamsConfig.APPLICATION_ID_CONFIG, appId) + + launch(CoroutineName(appId)) { + + val streamsState: KafkaStreams.State = suspendCancellableCoroutine { cont -> + + val streams = KafkaStreams(topology, props) + streams.setUncaughtExceptionHandler(StreamsExceptionHandler { e -> + cont.resumeWithException(e) + }) + + streams.setStateListener { newState: KafkaStreams.State, _ -> + when (newState) { + KafkaStreams.State.PENDING_SHUTDOWN, + KafkaStreams.State.NOT_RUNNING, + KafkaStreams.State.PENDING_ERROR, + KafkaStreams.State.ERROR -> if (cont.isActive) cont.resume(newState) + + else -> Unit // do nothing + } + } + + cont.invokeOnCancellation { + println("[$appId] coroutine cancelled -> closing. cause:$it") + streams.close() + } + + printTopologyDescription(appId, topology) + streams.start() + println("launched Topology $appId") + } + println("exiting Topology $appId: $streamsState") + currentCoroutineContext().job.cancel("$appId: $streamsState") + } +} + + +private fun printTopologyDescription(appId: String, topology: Topology) { + val description: TopologyDescription = topology.describe() + + val descFile = Path("./build/$appId.txt").toFile().apply { + parentFile.mkdirs() + if (!exists()) createNewFile() + writeText(description.toString()) + } + + println( + """ + |---------------- + |$appId - ${descFile.canonicalPath} + |$description + |---------------- + """.trimMargin() + ) +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt similarity index 98% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt rename to modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt index 9bcf517..8675fec 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt @@ -3,6 +3,7 @@ package dev.adamko.kafkatorio.server.processor.topology import dev.adamko.kafkatorio.library.kxsBinary import dev.adamko.kafkatorio.library.resize import dev.adamko.kafkatorio.library.toMapChunkPosition +import dev.adamko.kafkatorio.processor.core.DebounceProcessor.Companion.addDebounceProcessor import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioServerId @@ -12,9 +13,8 @@ import dev.adamko.kafkatorio.schema.common.ServerMapChunkId import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate -import dev.adamko.kafkatorio.server.processor.DebounceProcessor.Companion.addDebounceProcessor -import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_TERRAIN_COLOURED_032_UPDATES -import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_TERRAIN_COLOURED_STATE +import dev.adamko.kafkatorio.processor.config.TOPIC_MAP_CHUNK_TERRAIN_COLOURED_032_UPDATES +import dev.adamko.kafkatorio.processor.config.TOPIC_MAP_CHUNK_TERRAIN_COLOURED_STATE import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedAs diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourResourceChunks.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourResourceChunks.kt similarity index 97% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourResourceChunks.kt rename to modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourResourceChunks.kt index 96d1835..965a47c 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourResourceChunks.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourResourceChunks.kt @@ -2,6 +2,7 @@ package dev.adamko.kafkatorio.server.processor.topology import dev.adamko.kafkatorio.library.kxsBinary import dev.adamko.kafkatorio.library.toMapTilePosition +import dev.adamko.kafkatorio.processor.core.DebounceProcessor.Companion.addDebounceProcessor import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioPrototype @@ -16,7 +17,6 @@ import dev.adamko.kafkatorio.schema.packets.MapChunkEntityUpdate import dev.adamko.kafkatorio.schema.packets.MapChunkResourceUpdate import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate -import dev.adamko.kafkatorio.server.processor.DebounceProcessor.Companion.addDebounceProcessor import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.stream @@ -27,7 +27,6 @@ import dev.adamko.kotka.extensions.tables.join import dev.adamko.kotka.kxs.serde import kotlin.collections.component1 import kotlin.collections.component2 -import kotlin.math.ceil import kotlin.math.floor import kotlin.time.Duration.Companion.seconds import org.apache.kafka.streams.StreamsBuilder @@ -232,6 +231,9 @@ private fun KTable>.enr private fun MapBoundingBox.iterator(origin: MapTilePosition): Iterator { + // check if tile width/height should be divided by 2. I think I read that it's not divided by 2 + // if it's an odd number? + val xOffset: Int = floor(tileWidth.toDouble() / 2).toInt() val startX = origin.x - xOffset val endX = origin.x + xOffset diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt similarity index 93% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt rename to modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt index 20ecdab..42999ab 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt @@ -4,9 +4,9 @@ import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketDataError -import dev.adamko.kafkatorio.server.config.jsonMapper -import dev.adamko.kafkatorio.server.processor.TOPIC_SRC_SERVER_LOG -import dev.adamko.kafkatorio.server.processor.topicName +import dev.adamko.kafkatorio.processor.config.TOPIC_SRC_SERVER_LOG +import dev.adamko.kafkatorio.processor.config.jsonMapper +import dev.adamko.kafkatorio.processor.config.topicName import dev.adamko.kotka.extensions.component1 import dev.adamko.kotka.extensions.component2 import dev.adamko.kotka.extensions.consumedAs diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/model.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/model.kt similarity index 100% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/model.kt rename to modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/model.kt diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/packetDataStreams.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/packetDataStreams.kt similarity index 91% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/packetDataStreams.kt rename to modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/packetDataStreams.kt index f21625f..3adc34c 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/packetDataStreams.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/packetDataStreams.kt @@ -1,10 +1,10 @@ package dev.adamko.kafkatorio.server.processor.topology +import dev.adamko.kafkatorio.processor.config.jsonMapper import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData -import dev.adamko.kafkatorio.server.config.jsonMapper -import dev.adamko.kafkatorio.server.processor.topicName +import dev.adamko.kafkatorio.processor.config.topicName import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.mapValues diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/prototypes.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/prototypes.kt similarity index 100% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/prototypes.kt rename to modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/prototypes.kt diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt similarity index 94% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt rename to modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt index bff04b3..d0364a5 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt @@ -10,11 +10,11 @@ import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.ServerMapChunkId import dev.adamko.kafkatorio.schema.common.ServerMapTilePngFilename import dev.adamko.kafkatorio.schema.packets.EventServerPacket -import dev.adamko.kafkatorio.server.config.jsonMapper -import dev.adamko.kafkatorio.server.processor.TOPIC_BROADCAST_TO_WEBSOCKET -import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_BUILDING_COLOURED_STATE -import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_RESOURCE_COLOURED_STATE -import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_TERRAIN_COLOURED_STATE +import dev.adamko.kafkatorio.processor.config.TOPIC_BROADCAST_TO_WEBSOCKET +import dev.adamko.kafkatorio.processor.config.TOPIC_MAP_CHUNK_BUILDING_COLOURED_STATE +import dev.adamko.kafkatorio.processor.config.TOPIC_MAP_CHUNK_RESOURCE_COLOURED_STATE +import dev.adamko.kafkatorio.processor.config.TOPIC_MAP_CHUNK_TERRAIN_COLOURED_STATE +import dev.adamko.kafkatorio.processor.config.jsonMapper import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.stream @@ -44,7 +44,7 @@ private const val WEB_MAP_TILE_SIZE_PX = 256 fun saveMapTiles( builder: StreamsBuilder, serverDataDir: Path, -): Topology { +) { val subdividedMapChunkTilesDebounced: KStream> = builder.stream( @@ -64,8 +64,6 @@ fun saveMapTiles( subdividedMapChunkTilesDebounced.saveChunkAsImage(serverDataDir) savedChunkFilenames.broadcastSavedTileUpdates() - - return builder.build() } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/websocketBroadcaster.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/websocketBroadcaster.kt similarity index 89% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/websocketBroadcaster.kt rename to modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/websocketBroadcaster.kt index a173a26..5fc2d85 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/websocketBroadcaster.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/websocketBroadcaster.kt @@ -6,9 +6,8 @@ import dev.adamko.kafkatorio.schema.packets.EventServerPacket import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate -import dev.adamko.kafkatorio.server.processor.TOPIC_BROADCAST_TO_WEBSOCKET -import dev.adamko.kafkatorio.server.processor.topicName -import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer +import dev.adamko.kafkatorio.processor.config.TOPIC_BROADCAST_TO_WEBSOCKET +import dev.adamko.kafkatorio.processor.config.topicName import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.stream @@ -31,8 +30,13 @@ private val jsonMapper: Json = Json { private const val pid = "websocketBroadcast" +interface WebsocketBroadcaster { + suspend fun sendMessageToClients(message: String) +} + + fun broadcastToWebsocket( - websocketServer: WebmapWebsocketServer, + websocketBroadcaster: WebsocketBroadcaster, builder: StreamsBuilder, ) { @@ -45,7 +49,7 @@ fun broadcastToWebsocket( "$pid.websocket-server.send-message" ) { _, esPacket -> runBlocking { - websocketServer.sendMessageToClients(jsonMapper.encodeToString(esPacket)) + websocketBroadcaster.sendMessageToClients(jsonMapper.encodeToString(esPacket)) } } } diff --git a/modules/events-server/src/main/resources/config.yml b/modules/events-processor-core/src/main/resources/config.yml similarity index 89% rename from modules/events-server/src/main/resources/config.yml rename to modules/events-processor-core/src/main/resources/config.yml index c377231..b9f2858 100644 --- a/modules/events-server/src/main/resources/config.yml +++ b/modules/events-processor-core/src/main/resources/config.yml @@ -5,7 +5,7 @@ server-data-dir: ${SERVER_DATA_DIR:-./server-data} socket-server-host: ${SOCKET_SERVER_HOST:-127.0.0.1} -#socket-server-port: ${SOCKET_SERVER_PORT:-12092} +socket-server-port: ${SOCKET_SERVER_PORT:-12092} kafka-admin-config: @@ -16,7 +16,7 @@ kafka-admin-config: kafka-streams-config: application.id: kafkatorio-events-processor bootstrap.servers: ${KAFKA_BOOTSTRAP_SERVERS:-http://localhost:9092} - state.dir: ${KAFKA_STREAMS_STATE_DIR:-./kafka-state} + state.dir: ${KAFKA_STREAMS_STATE_DIR:-.state/kafka} num.stream.threads: 1 processing.guarantee: exactly_once_v2 auto.offset.reset: earliest @@ -65,5 +65,3 @@ kafka-streams-config: # # fetch.message.max.bytes=31457280 # # 100mb 104857600 # -#tileServer: -# webmapTileDir: 'D:\Users\Adam\Projects\games\kafkatorio\modules\events-server\kafkatorio-tiles' diff --git a/modules/events-server/src/main/resources/external-annotations/org/apache/kafka/streams/state/annotations.xml b/modules/events-processor-core/src/main/resources/external-annotations/org/apache/kafka/streams/state/annotations.xml similarity index 100% rename from modules/events-server/src/main/resources/external-annotations/org/apache/kafka/streams/state/annotations.xml rename to modules/events-processor-core/src/main/resources/external-annotations/org/apache/kafka/streams/state/annotations.xml diff --git a/modules/events-server/src/main/resources/logback.xml b/modules/events-processor-core/src/main/resources/logback.xml similarity index 100% rename from modules/events-server/src/main/resources/logback.xml rename to modules/events-processor-core/src/main/resources/logback.xml diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/security/AuthenticatorTest.kt b/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/AuthenticatorTest.kt similarity index 97% rename from modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/security/AuthenticatorTest.kt rename to modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/AuthenticatorTest.kt index 0241fdb..5fb2d4f 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/security/AuthenticatorTest.kt +++ b/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/AuthenticatorTest.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.server.security +package dev.adamko.kafkatorio.processor.core import dev.adamko.kafkatorio.schema.common.MaskedValue import dev.adamko.kafkatorio.server.config.ApplicationProperties diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt b/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/misc/serdeSize.kt similarity index 100% rename from modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt rename to modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/misc/serdeSize.kt diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/FactorioServerPacketsTest.kt b/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/FactorioServerPacketsTest.kt similarity index 96% rename from modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/FactorioServerPacketsTest.kt rename to modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/FactorioServerPacketsTest.kt index 0cadcec..b219310 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/FactorioServerPacketsTest.kt +++ b/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/FactorioServerPacketsTest.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.server.processor.topology +package dev.adamko.kafkatorio.processor.core.topology import dev.adamko.kafkatorio.library.kxsBinary import dev.adamko.kafkatorio.schema.common.ColourHex diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt b/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/GroupMapChunksTest.kt similarity index 99% rename from modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt rename to modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/GroupMapChunksTest.kt index 56cb643..5dc33de 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt +++ b/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/GroupMapChunksTest.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.processor.topology +package dev.adamko.kafkatorio.processor.core.topology //import dev.adamko.kafkatorio.server.processor.TOPIC_GROUPED_MAP_CHUNKS_STATE //import dev.adamko.kafkatorio.processor.config.getJsonMapper diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/SaveMapChunksTest.kt b/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/SaveMapChunksTest.kt similarity index 99% rename from modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/SaveMapChunksTest.kt rename to modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/SaveMapChunksTest.kt index 919bef3..a82ce0e 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/SaveMapChunksTest.kt +++ b/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/SaveMapChunksTest.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.server.processor.topology +package dev.adamko.kafkatorio.processor.core.topology import dev.adamko.kafkatorio.library.iterateTiles import dev.adamko.kafkatorio.library.kxsBinary diff --git a/modules/events-processor-entities/build.gradle.kts b/modules/events-processor-entities/build.gradle.kts deleted file mode 100644 index 7b92be6..0000000 --- a/modules/events-processor-entities/build.gradle.kts +++ /dev/null @@ -1,54 +0,0 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - - -plugins { - dev.adamko.kafkatorio.lang.`kotlin-jvm` - kotlin("plugin.serialization") - application -} - - -//description = "serves Kafkatorio content over the web" - -val projectId: String by project.extra - -val kafkaStateDir: Directory = layout.projectDirectory.dir("kafka-state") - - -dependencies { - implementation(platform(projects.modules.versionsPlatform)) - - implementation(libs.kafka.streams) - testImplementation(libs.kafka.streamsTestUtils) - - implementation(projects.modules.eventsLibrary) - - implementation(libs.kotlinxSerialization.core) - implementation(libs.kotlinxSerialization.json) - - implementation(libs.kotlinx.coroutines.core) - - implementation(libs.bundles.logging) - - implementation(libs.scrimage.core) - - implementation(libs.okio.core) - - implementation(libs.simpleSyslogParser) - - implementation(libs.kafka.kotkaStreams) -} - - -application { - mainClass.set("dev.adamko.kafkatorio.server.EventsServerKt") -} - - -tasks.withType().configureEach { - kotlinOptions.freeCompilerArgs += listOf( - "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-opt-in=kotlinx.coroutines.FlowPreview", - "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", - ) -} diff --git a/modules/events-processor-packets/build.gradle.kts b/modules/events-processor-packets/build.gradle.kts deleted file mode 100644 index 7b92be6..0000000 --- a/modules/events-processor-packets/build.gradle.kts +++ /dev/null @@ -1,54 +0,0 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - - -plugins { - dev.adamko.kafkatorio.lang.`kotlin-jvm` - kotlin("plugin.serialization") - application -} - - -//description = "serves Kafkatorio content over the web" - -val projectId: String by project.extra - -val kafkaStateDir: Directory = layout.projectDirectory.dir("kafka-state") - - -dependencies { - implementation(platform(projects.modules.versionsPlatform)) - - implementation(libs.kafka.streams) - testImplementation(libs.kafka.streamsTestUtils) - - implementation(projects.modules.eventsLibrary) - - implementation(libs.kotlinxSerialization.core) - implementation(libs.kotlinxSerialization.json) - - implementation(libs.kotlinx.coroutines.core) - - implementation(libs.bundles.logging) - - implementation(libs.scrimage.core) - - implementation(libs.okio.core) - - implementation(libs.simpleSyslogParser) - - implementation(libs.kafka.kotkaStreams) -} - - -application { - mainClass.set("dev.adamko.kafkatorio.server.EventsServerKt") -} - - -tasks.withType().configureEach { - kotlinOptions.freeCompilerArgs += listOf( - "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-opt-in=kotlinx.coroutines.FlowPreview", - "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", - ) -} diff --git a/modules/events-processor-tiles/build.gradle.kts b/modules/events-processor-tiles/build.gradle.kts deleted file mode 100644 index 7b92be6..0000000 --- a/modules/events-processor-tiles/build.gradle.kts +++ /dev/null @@ -1,54 +0,0 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - - -plugins { - dev.adamko.kafkatorio.lang.`kotlin-jvm` - kotlin("plugin.serialization") - application -} - - -//description = "serves Kafkatorio content over the web" - -val projectId: String by project.extra - -val kafkaStateDir: Directory = layout.projectDirectory.dir("kafka-state") - - -dependencies { - implementation(platform(projects.modules.versionsPlatform)) - - implementation(libs.kafka.streams) - testImplementation(libs.kafka.streamsTestUtils) - - implementation(projects.modules.eventsLibrary) - - implementation(libs.kotlinxSerialization.core) - implementation(libs.kotlinxSerialization.json) - - implementation(libs.kotlinx.coroutines.core) - - implementation(libs.bundles.logging) - - implementation(libs.scrimage.core) - - implementation(libs.okio.core) - - implementation(libs.simpleSyslogParser) - - implementation(libs.kafka.kotkaStreams) -} - - -application { - mainClass.set("dev.adamko.kafkatorio.server.EventsServerKt") -} - - -tasks.withType().configureEach { - kotlinOptions.freeCompilerArgs += listOf( - "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-opt-in=kotlinx.coroutines.FlowPreview", - "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", - ) -} diff --git a/modules/events-processors/build.gradle.kts b/modules/events-processors/build.gradle.kts new file mode 100644 index 0000000..01ae8d4 --- /dev/null +++ b/modules/events-processors/build.gradle.kts @@ -0,0 +1,91 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + dev.adamko.kafkatorio.lang.`kotlin-jvm` + kotlin("plugin.serialization") + application +} + + +description = "processors for Kafkatorio packets" + +val projectId: String by project.extra + + +dependencies { + implementation(platform(projects.modules.versionsPlatform)) + + implementation(libs.kafka.streams) + + testImplementation(libs.kafka.streamsTestUtils) + + implementation(projects.modules.eventsLibrary) + implementation(projects.modules.eventsProcessorCore) + + implementation(libs.kotlinxSerialization.core) + implementation(libs.kotlinxSerialization.json) + + implementation(libs.kotlinx.coroutines.core) + + implementation(libs.bundles.logging) + + implementation(libs.scrimage.core) + + implementation(libs.okio.core) + + implementation(libs.simpleSyslogParser) + + implementation(libs.kafka.kotkaStreams) +} + + +application { + mainClass.set("dev.adamko.kafkatorio.processors.MainKt") +} + + +tasks.withType().configureEach { + kotlinOptions.freeCompilerArgs += listOf( + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlinx.coroutines.FlowPreview", + "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", + ) +} + + +//val startScriptEntitiesProcessor = registerStartScriptTask("EntitiesProcessor") { +// mainClass.set("dev.adamko.kafkatorio.processors.EntitiesProcessorKt") +//} +// +//val startScriptPacketsProcessor = registerStartScriptTask("PacketsProcessor") { +// mainClass.set("dev.adamko.kafkatorio.processors.PacketsProcessorKt") +//} +// +//val startScriptTilesProcessor = registerStartScriptTask("TilesProcessor") { +// mainClass.set("dev.adamko.kafkatorio.processors.TilesProcessorKt") +//} +// +// +//application.applicationDistribution.into("bin") { +// from(startScriptEntitiesProcessor) +// from(startScriptPacketsProcessor) +// from(startScriptTilesProcessor) +// fileMode = 0b000_111_101_101 // 0755 +// duplicatesStrategy = DuplicatesStrategy.EXCLUDE +//} + +tasks.named("run") { + + val kafkaStateDir: Directory = layout.projectDirectory.dir(".state/kafka/") + + doFirst { + kafkaStateDir.asFile.mkdirs() + } +} + + +val runEventsProcessors by tasks.registering { + group = rootProject.name + + dependsOn(tasks.run) +} diff --git a/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/groupEntitiesMapChunks.kt b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/groupEntitiesMapChunks.kt new file mode 100644 index 0000000..8783592 --- /dev/null +++ b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/groupEntitiesMapChunks.kt @@ -0,0 +1,54 @@ +package dev.adamko.kafkatorio.processors + +import dev.adamko.kafkatorio.processor.core.launchTopology +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.common.PrototypeHashCode +import dev.adamko.kafkatorio.schema.common.ServerMapChunkId +import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer +import dev.adamko.kafkatorio.schema.packets.MapChunkEntityUpdate +import dev.adamko.kafkatorio.schema.packets.MapChunkResourceUpdate +import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate +import dev.adamko.kafkatorio.server.processor.topology.ServerMapChunkTiles +import dev.adamko.kafkatorio.server.processor.topology.colourEntityChunks +import dev.adamko.kafkatorio.server.processor.topology.convertEntityUpdateToServerMapChunkTiles +import dev.adamko.kafkatorio.server.processor.topology.convertResourceUpdateToServerMapChunkTiles +import dev.adamko.kafkatorio.server.processor.topology.streamPacketData +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.kstream.KStream + + +/** Building and resource tiles */ +suspend fun groupEntitiesMapChunks( + layer: ServerMapTileLayer, + colouredUpdatesStreamTopic: String, + colouredChunkStateTopic: String, +) { + val builder = StreamsBuilder() + + val entityChunksStream: KStream> = + when (layer) { + ServerMapTileLayer.TERRAIN -> return + + ServerMapTileLayer.RESOURCE -> + builder.streamPacketData() + .convertResourceUpdateToServerMapChunkTiles("groupEntitiesMapChunks.${layer.dir}") + + ServerMapTileLayer.BUILDING -> + builder.streamPacketData() + .convertEntityUpdateToServerMapChunkTiles("groupEntitiesMapChunks.${layer.dir}") + } + + val protosStream: KStream = + builder.streamPacketData() + + val topology = colourEntityChunks( + builder, + entityChunksStream, + protosStream, + layer, + colouredUpdatesStreamTopic, + colouredChunkStateTopic, + ) + + launchTopology("groupTilesMapChunks.${layer.dir}", topology) +} diff --git a/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/groupTilesMapChunks.kt b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/groupTilesMapChunks.kt new file mode 100644 index 0000000..fd65020 --- /dev/null +++ b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/groupTilesMapChunks.kt @@ -0,0 +1,23 @@ +package dev.adamko.kafkatorio.processors + +import dev.adamko.kafkatorio.processor.core.launchTopology +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer +import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate +import dev.adamko.kafkatorio.server.processor.topology.colourMapChunks +import dev.adamko.kafkatorio.server.processor.topology.streamPacketData +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.kstream.KStream + + +/** Terrain tiles */ +suspend fun groupTilesMapChunks() { + val builder = StreamsBuilder() + + val protosStream: KStream = + builder.streamPacketData() + + val topology = colourMapChunks(builder, protosStream) + + launchTopology("groupTilesMapChunks.${ServerMapTileLayer.TERRAIN.dir}", topology) +} diff --git a/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/main.kt b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/main.kt new file mode 100644 index 0000000..427903f --- /dev/null +++ b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/main.kt @@ -0,0 +1,36 @@ +package dev.adamko.kafkatorio.processors + +import dev.adamko.kafkatorio.processor.config.TOPIC_MAP_CHUNK_BUILDING_COLOURED_032_UPDATES +import dev.adamko.kafkatorio.processor.config.TOPIC_MAP_CHUNK_BUILDING_COLOURED_STATE +import dev.adamko.kafkatorio.processor.config.TOPIC_MAP_CHUNK_RESOURCE_COLOURED_032_UPDATES +import dev.adamko.kafkatorio.processor.config.TOPIC_MAP_CHUNK_RESOURCE_COLOURED_STATE +import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch + + +suspend fun main(): Unit = coroutineScope { + launch { + splitPackets() + } + + launch { + groupTilesMapChunks() + } + + launch { + groupEntitiesMapChunks( + layer = ServerMapTileLayer.BUILDING, + colouredUpdatesStreamTopic = TOPIC_MAP_CHUNK_BUILDING_COLOURED_032_UPDATES, + colouredChunkStateTopic = TOPIC_MAP_CHUNK_BUILDING_COLOURED_STATE, + ) + } + + launch { + groupEntitiesMapChunks( + layer = ServerMapTileLayer.RESOURCE, + colouredUpdatesStreamTopic = TOPIC_MAP_CHUNK_RESOURCE_COLOURED_032_UPDATES, + colouredChunkStateTopic = TOPIC_MAP_CHUNK_RESOURCE_COLOURED_STATE, + ) + } +} diff --git a/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/splitPackets.kt b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/splitPackets.kt new file mode 100644 index 0000000..9373bc2 --- /dev/null +++ b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/splitPackets.kt @@ -0,0 +1,17 @@ +package dev.adamko.kafkatorio.processors + +import dev.adamko.kafkatorio.processor.core.launchTopology +import dev.adamko.kafkatorio.server.processor.topology.factorioServerPacketStream +import dev.adamko.kafkatorio.server.processor.topology.splitFactorioServerPacketStream +import org.apache.kafka.streams.StreamsBuilder + + +suspend fun splitPackets() { + val builder = StreamsBuilder() + val packets = factorioServerPacketStream(builder) + splitFactorioServerPacketStream(packets) + + val topology = builder.build() + + launchTopology("splitPackets", topology) +} diff --git a/modules/events-server-core/build.gradle.kts b/modules/events-server-core/build.gradle.kts deleted file mode 100644 index 1172be0..0000000 --- a/modules/events-server-core/build.gradle.kts +++ /dev/null @@ -1,79 +0,0 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - - -plugins { - dev.adamko.kafkatorio.lang.`kotlin-jvm` - kotlin("plugin.serialization") - application -} - - -//description = "serves Kafkatorio content over the web" - -val projectId: String by project.extra - - -dependencies { - implementation(platform(projects.modules.versionsPlatform)) - - implementation(libs.kafka.streams) - testImplementation(libs.kafka.streamsTestUtils) - - implementation(projects.modules.eventsLibrary) - - implementation(libs.kotlinxSerialization.core) - implementation(libs.kotlinxSerialization.json) - - implementation(libs.kotlinx.coroutines.core) - - implementation(libs.bundles.logging) - - implementation(libs.scrimage.core) - - implementation(libs.okio.core) - - // - implementation(libs.ktorSerialization.kotlinxJson) - - with(libs.ktorServer) { - implementation(auth) - implementation(authJwt) - implementation(core) - implementation(callId) - implementation(callLogging) - implementation(contentNegotiaion) - implementation(cio) - implementation(autoHeadResponse) - implementation(partialContent) - implementation(resources) - implementation(statusPages) - implementation(websockets) - implementation(compression) - } - - with(libs.ktorNetwork) { - implementation(core) - implementation(tls) - } - // - - implementation(libs.simpleSyslogParser) - -// implementation(libs.nimbusJoseJwt) - - implementation(libs.kafka.kotkaStreams) -} - - -application { - mainClass.set("dev.adamko.kafkatorio.server.EventsServerKt") -} - - -tasks.withType().configureEach { - kotlinOptions.freeCompilerArgs += listOf( - "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-opt-in=kotlinx.coroutines.FlowPreview", - "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", - ) -} diff --git a/modules/events-server-syslog/build.gradle.kts b/modules/events-server-syslog/build.gradle.kts index 1172be0..d746d17 100644 --- a/modules/events-server-syslog/build.gradle.kts +++ b/modules/events-server-syslog/build.gradle.kts @@ -8,7 +8,7 @@ plugins { } -//description = "serves Kafkatorio content over the web" +description = "Consumes Syslog Kafkatorio packets and sends them to Kafka" val projectId: String by project.extra @@ -20,6 +20,7 @@ dependencies { testImplementation(libs.kafka.streamsTestUtils) implementation(projects.modules.eventsLibrary) + implementation(projects.modules.eventsProcessorCore) implementation(libs.kotlinxSerialization.core) implementation(libs.kotlinxSerialization.json) @@ -62,11 +63,13 @@ dependencies { // implementation(libs.nimbusJoseJwt) implementation(libs.kafka.kotkaStreams) + + implementation(libs.bundles.hoplite) } application { - mainClass.set("dev.adamko.kafkatorio.server.EventsServerKt") + mainClass.set("dev.adamko.kafkatorio.processor.syslog.SyslogMainKt") } @@ -77,3 +80,9 @@ tasks.withType().configureEach { "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", ) } + + +val runSyslogServer by tasks.registering { + group = rootProject.name + dependsOn(tasks.run) +} diff --git a/modules/events-server-syslog/docker/Dockerfile b/modules/events-server-syslog/docker/Dockerfile new file mode 100644 index 0000000..a196e24 --- /dev/null +++ b/modules/events-server-syslog/docker/Dockerfile @@ -0,0 +1,11 @@ +FROM gradle:7-jdk11 AS build +COPY --chown=gradle:gradle . /home/gradle/src +WORKDIR /home/gradle/src +RUN gradle buildFatJar --no-daemon + + +FROM openjdk:11 +EXPOSE 8080:8080 +RUN mkdir /app +COPY --from=build /home/gradle/src/build/libs/*.jar /app/ktor-docker-sample.jar +ENTRYPOINT ["java","-jar","/app/ktor-docker-sample.jar"] diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioPacketKafkaProducer.kt b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/KafkatorioPacketKafkaProducer.kt similarity index 92% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioPacketKafkaProducer.kt rename to modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/KafkatorioPacketKafkaProducer.kt index 1b0cfa3..d60a436 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioPacketKafkaProducer.kt +++ b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/KafkatorioPacketKafkaProducer.kt @@ -1,12 +1,12 @@ -package dev.adamko.kafkatorio.server.processor +package dev.adamko.kafkatorio.processor.syslog import com.github.palindromicity.syslog.dsl.SyslogFieldKeys +import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.processor.core.Authenticator +import dev.adamko.kafkatorio.processor.syslog.config.jsonMapper import dev.adamko.kafkatorio.schema.common.FactorioServerId -import dev.adamko.kafkatorio.server.config.ApplicationProperties -import dev.adamko.kafkatorio.server.config.jsonMapper -import dev.adamko.kafkatorio.server.security.Authenticator -import dev.adamko.kafkatorio.server.socket.SyslogMsg -import dev.adamko.kafkatorio.server.socket.SyslogSocketServer +import dev.adamko.kafkatorio.processor.config.TOPIC_SRC_SERVER_LOG +import dev.adamko.kafkatorio.processor.config.TOPIC_SRC_SERVER_LOG_DLQ import dev.adamko.kotka.kxs.kafkaSerializer import java.util.Properties import kotlin.coroutines.coroutineContext diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogMsg.kt b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogMsg.kt similarity index 96% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogMsg.kt rename to modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogMsg.kt index d329352..42bb7ea 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogMsg.kt +++ b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogMsg.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.server.socket +package dev.adamko.kafkatorio.processor.syslog import com.github.palindromicity.syslog.dsl.SyslogFieldKeys diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogSocketServer.kt similarity index 96% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt rename to modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogSocketServer.kt index 666d477..12cac26 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt +++ b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogSocketServer.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.server.socket +package dev.adamko.kafkatorio.processor.syslog import com.github.palindromicity.syslog.AllowableDeviations import com.github.palindromicity.syslog.DefaultKeyProvider @@ -7,7 +7,7 @@ import com.github.palindromicity.syslog.NilPolicy import com.github.palindromicity.syslog.SyslogParser import com.github.palindromicity.syslog.SyslogParserBuilder import com.github.palindromicity.syslog.SyslogSpecification -import dev.adamko.kafkatorio.server.config.ApplicationProperties +import dev.adamko.kafkatorio.processor.config.ApplicationProperties import io.ktor.network.selector.SelectorManager import io.ktor.network.sockets.Socket import io.ktor.network.sockets.aSocket diff --git a/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/config/kxsJson.kt b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/config/kxsJson.kt new file mode 100644 index 0000000..6b8797b --- /dev/null +++ b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/config/kxsJson.kt @@ -0,0 +1,12 @@ +package dev.adamko.kafkatorio.processor.syslog.config + +import dev.adamko.kafkatorio.library.jsonMapperKafkatorio +import kotlinx.serialization.json.Json + + +@PublishedApi +internal val jsonMapper: Json = Json { + prettyPrint = true + prettyPrintIndent = " " + serializersModule = jsonMapperKafkatorio.serializersModule +} diff --git a/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/syslogMain.kt b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/syslogMain.kt new file mode 100644 index 0000000..6667561 --- /dev/null +++ b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/syslogMain.kt @@ -0,0 +1,20 @@ +package dev.adamko.kafkatorio.processor.syslog + +import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.processor.core.Authenticator +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch + + +/** Receive log messages from the syslog socket, and send them to a Kafka topic */ +suspend fun main(): Unit = coroutineScope { + + val appProps = ApplicationProperties.load() + val syslogServer = SyslogSocketServer(appProps) + val authenticator = Authenticator(appProps) + + val producer = KafkatorioPacketKafkaProducer(appProps, syslogServer, authenticator) + + launch { syslogServer.start() } + launch { producer.launch() } +} diff --git a/modules/events-server-api/build.gradle.kts b/modules/events-server-web/build.gradle.kts similarity index 81% rename from modules/events-server-api/build.gradle.kts rename to modules/events-server-web/build.gradle.kts index 63de5d8..f65b0ae 100644 --- a/modules/events-server-api/build.gradle.kts +++ b/modules/events-server-web/build.gradle.kts @@ -8,11 +8,11 @@ plugins { } -//description = "serves Kafkatorio content over the web" +description = "serves Kafkatorio content over web APIs" val projectId: String by project.extra -val kafkaStateDir: Directory = layout.projectDirectory.dir("kafka-state") +val kafkaStateDir: Directory = layout.projectDirectory.dir(".state/kafka") dependencies { @@ -22,6 +22,7 @@ dependencies { testImplementation(libs.kafka.streamsTestUtils) implementation(projects.modules.eventsLibrary) + implementation(projects.modules.eventsProcessorCore) implementation(libs.kotlinxSerialization.core) implementation(libs.kotlinxSerialization.json) @@ -64,11 +65,13 @@ dependencies { // implementation(libs.nimbusJoseJwt) implementation(libs.kafka.kotkaStreams) + + implementation(libs.bundles.hoplite) } application { - mainClass.set("dev.adamko.kafkatorio.server.EventsServerKt") + mainClass.set("dev.adamko.kafkatorio.server.web.MainKt") } @@ -79,3 +82,10 @@ tasks.withType().configureEach { "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", ) } + + +val runEventsWebServer by tasks.registering { + group = rootProject.name + + dependsOn(tasks.run) +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/kxsJson.kt b/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/config/kxsJson.kt similarity index 70% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/kxsJson.kt rename to modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/config/kxsJson.kt index 6dab1ed..da63668 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/kxsJson.kt +++ b/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/config/kxsJson.kt @@ -1,10 +1,10 @@ -package dev.adamko.kafkatorio.server.config +package dev.adamko.kafkatorio.server.web.config import dev.adamko.kafkatorio.library.jsonMapperKafkatorio import kotlinx.serialization.json.Json -val jsonMapper: Json = Json { +internal val jsonMapper: Json = Json { prettyPrint = true prettyPrintIndent = " " serializersModule = jsonMapperKafkatorio.serializersModule diff --git a/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/main.kt b/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/main.kt new file mode 100644 index 0000000..4ce5ae0 --- /dev/null +++ b/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/main.kt @@ -0,0 +1,61 @@ +package dev.adamko.kafkatorio.server.web + +import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.processor.core.launchTopology +import dev.adamko.kafkatorio.server.processor.topology.broadcastToWebsocket +import dev.adamko.kafkatorio.server.processor.topology.saveMapTiles +import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch +import org.apache.kafka.clients.producer.ProducerConfig +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.StreamsConfig + +suspend fun main(): Unit = coroutineScope { + val appProps = ApplicationProperties.load() + val wsServer = WebmapWebsocketServer() + + launch { + websocketBroadcaster(wsServer) + } + +// launch { +// broadcastToWebsocket(wsServer, StreamsBuilder()) +// } + + launch { + saveTiles(appProps) + } + + launch { + startWebServer( + appProps = appProps, + wsServer = wsServer, + ) + } +} + +private suspend fun websocketBroadcaster(wsServer: WebmapWebsocketServer) { + val builder = StreamsBuilder() + + broadcastToWebsocket(wsServer, builder) + + val topology = builder.build() + + launchTopology( + "websocketBroadcaster", topology, mapOf( + StreamsConfig.COMMIT_INTERVAL_MS_CONFIG to "${1.seconds.inWholeMilliseconds}", + StreamsConfig.producerPrefix(ProducerConfig.LINGER_MS_CONFIG) to "${1.milliseconds.inWholeMilliseconds}" + ) + ) +} + +private suspend fun saveTiles( + appProps: ApplicationProperties +) { + val builder = StreamsBuilder() + saveMapTiles(builder, appProps.serverDataDir) + launchTopology("saveTiles", builder.build()) +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt b/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt similarity index 95% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt rename to modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt index 3925a33..082fcde 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt +++ b/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt @@ -5,8 +5,8 @@ import dev.adamko.kafkatorio.schema.common.PlayerIndex import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer import dev.adamko.kafkatorio.schema.common.ServerMapTilePngFilename import dev.adamko.kafkatorio.schema.common.SurfaceIndex -import dev.adamko.kafkatorio.server.config.ApplicationProperties -import dev.adamko.kafkatorio.server.config.jsonMapper +import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.server.web.config.jsonMapper import io.ktor.http.HttpStatusCode import io.ktor.http.content.EntityTagVersion import io.ktor.http.content.versions @@ -25,7 +25,7 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.json.encodeToJsonElement -fun Routing.factorioServersRoutes( +internal fun Routing.factorioServersRoutes( appProps: ApplicationProperties, ) { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/restApi.kt b/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/restApi.kt similarity index 92% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/restApi.kt rename to modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/restApi.kt index 0fe7f45..22f8e3e 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/restApi.kt +++ b/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/restApi.kt @@ -1,6 +1,6 @@ package dev.adamko.kafkatorio.server.web.rest -import dev.adamko.kafkatorio.server.config.ApplicationProperties +import dev.adamko.kafkatorio.processor.config.ApplicationProperties import io.ktor.http.ContentType import io.ktor.http.HttpStatusCode import io.ktor.http.isSuccess @@ -22,7 +22,7 @@ import io.ktor.server.response.respondText import io.ktor.server.routing.routing -fun Application.webmapTileServer(appProps: ApplicationProperties) { +internal fun Application.webmapTileServer(appProps: ApplicationProperties) { install(AutoHeadResponse) install(CallLogging) { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/webServer.kt b/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/webServer.kt similarity index 85% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/webServer.kt rename to modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/webServer.kt index 4fe626e..6792e02 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/webServer.kt +++ b/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/webServer.kt @@ -1,6 +1,7 @@ package dev.adamko.kafkatorio.server.web -import dev.adamko.kafkatorio.server.config.ApplicationProperties + +import dev.adamko.kafkatorio.processor.config.ApplicationProperties import dev.adamko.kafkatorio.server.web.rest.webmapTileServer import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer import dev.adamko.kafkatorio.server.web.websocket.webmapWebsocketServer @@ -9,7 +10,7 @@ import io.ktor.server.engine.embeddedServer import kotlinx.coroutines.coroutineScope -suspend fun startWebServer( +internal suspend fun startWebServer( appProps: ApplicationProperties, wsServer: WebmapWebsocketServer, ): Unit = coroutineScope { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt b/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt similarity index 92% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt rename to modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt index e672196..c704411 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt +++ b/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.server.web.websocket +import dev.adamko.kafkatorio.server.processor.topology.WebsocketBroadcaster import io.ktor.websocket.CloseReason import io.ktor.websocket.DefaultWebSocketSession import io.ktor.websocket.Frame @@ -24,7 +25,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.yield -class WebmapWebsocketServer { +class WebmapWebsocketServer : WebsocketBroadcaster { private val startTime = TimeSource.Monotonic.markNow() @@ -88,9 +89,9 @@ class WebmapWebsocketServer { } - suspend fun sendMessageToClients(msg: String) { - log("sending message to clients: $msg") - messagesToClients.emit(msg) + override suspend fun sendMessageToClients(message: String) { + log("sending message to clients: $message") + messagesToClients.emit(message) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/wsServer.kt b/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/wsServer.kt similarity index 100% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/wsServer.kt rename to modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/wsServer.kt diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 8613f5c..c865d61 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -10,11 +10,11 @@ plugins { } -description = "serves Kafkatorio content over the web" +description = "deprecated - this was split up into separate modules" val projectId: String by project.extra -val kafkaStateDir: Directory = layout.projectDirectory.dir("kafka-state") +val kafkaStateDir: Directory = layout.projectDirectory.dir(".state/kafka") dependencies { diff --git a/modules/events-server/docker/Dockerfile b/modules/events-server/docker/Dockerfile index 48e4647..3f7ac14 100644 --- a/modules/events-server/docker/Dockerfile +++ b/modules/events-server/docker/Dockerfile @@ -13,7 +13,7 @@ ENV SOCKET_SERVER_PORT=9002 EXPOSE $SOCKET_SERVER_PORT ENV SERVER_DATA_DIR="/app/data" -ENV KAFKA_STREAMS_STATE_DIR="/app/kafka-state" +ENV KAFKA_STREAMS_STATE_DIR="/app/state/kafka" VOLUME ${SERVER_DATA_DIR} \ ${KAFKA_STREAMS_STATE_DIR} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt index ab6d89a..bc3c1d6 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt @@ -1,32 +1,32 @@ package dev.adamko.kafkatorio.server -import dev.adamko.kafkatorio.server.config.ApplicationProperties -import dev.adamko.kafkatorio.server.processor.eventsProcessor -import dev.adamko.kafkatorio.server.security.Authenticator -import dev.adamko.kafkatorio.server.socket.SyslogSocketServer -import dev.adamko.kafkatorio.server.web.startWebServer -import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch +//import dev.adamko.kafkatorio.server.config.ApplicationProperties +//import dev.adamko.kafkatorio.server.processor.eventsProcessor +//import dev.adamko.kafkatorio.server.security.Authenticator +//import dev.adamko.kafkatorio.server.socket.SyslogSocketServer +//import dev.adamko.kafkatorio.server.web.startWebServer +//import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer +//import kotlinx.coroutines.coroutineScope +//import kotlinx.coroutines.launch -suspend fun main(): Unit = coroutineScope { - - val appProps = ApplicationProperties.load() - - val websocketServer = WebmapWebsocketServer() - val syslogSocketServer = SyslogSocketServer(appProps) - val authenticator = Authenticator(appProps) - - launch { - startWebServer(appProps, websocketServer) - } - - launch { - syslogSocketServer.start() - } - - launch { - eventsProcessor(appProps, syslogSocketServer, websocketServer, authenticator) - } -} +//suspend fun main(): Unit = coroutineScope { +// +// val appProps = ApplicationProperties.load() +// +// val websocketServer = WebmapWebsocketServer() +// val syslogSocketServer = SyslogSocketServer(appProps) +// val authenticator = Authenticator(appProps) +// +// launch { +// startWebServer(appProps, websocketServer) +// } +// +// launch { +// syslogSocketServer.start() +// } +// +// launch { +// eventsProcessor(appProps, syslogSocketServer, websocketServer, authenticator) +// } +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt index 56c8e25..abdc507 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt @@ -1,243 +1,243 @@ package dev.adamko.kafkatorio.server.processor -import dev.adamko.kafkatorio.schema.common.FactorioServerId -import dev.adamko.kafkatorio.schema.common.PrototypeHashCode -import dev.adamko.kafkatorio.schema.common.ServerMapChunkId -import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer -import dev.adamko.kafkatorio.schema.packets.MapChunkEntityUpdate -import dev.adamko.kafkatorio.schema.packets.MapChunkResourceUpdate -import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate -import dev.adamko.kafkatorio.server.config.ApplicationProperties -import dev.adamko.kafkatorio.server.processor.topology.ServerMapChunkTiles -import dev.adamko.kafkatorio.server.processor.topology.broadcastToWebsocket -import dev.adamko.kafkatorio.server.processor.topology.colourEntityChunks -import dev.adamko.kafkatorio.server.processor.topology.colourMapChunks -import dev.adamko.kafkatorio.server.processor.topology.convertEntityUpdateToServerMapChunkTiles -import dev.adamko.kafkatorio.server.processor.topology.convertResourceUpdateToServerMapChunkTiles -import dev.adamko.kafkatorio.server.processor.topology.factorioServerPacketStream -import dev.adamko.kafkatorio.server.processor.topology.saveMapTiles -import dev.adamko.kafkatorio.server.processor.topology.splitFactorioServerPacketStream -import dev.adamko.kafkatorio.server.processor.topology.streamPacketData -import dev.adamko.kafkatorio.server.socket.SyslogSocketServer -import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer -import java.util.Properties -import kotlin.coroutines.resume -import kotlin.coroutines.resumeWithException -import kotlin.io.path.Path -import kotlin.time.Duration.Companion.milliseconds -import kotlin.time.Duration.Companion.seconds -import kotlinx.coroutines.CoroutineName -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.cancel -import kotlinx.coroutines.currentCoroutineContext -import kotlinx.coroutines.job -import kotlinx.coroutines.launch -import kotlinx.coroutines.suspendCancellableCoroutine -import org.apache.kafka.clients.producer.ProducerConfig -import org.apache.kafka.streams.KafkaStreams -import org.apache.kafka.streams.StreamsBuilder -import org.apache.kafka.streams.StreamsConfig -import org.apache.kafka.streams.Topology -import org.apache.kafka.streams.TopologyDescription -import org.apache.kafka.streams.kstream.KStream +//import dev.adamko.kafkatorio.schema.common.FactorioServerId +//import dev.adamko.kafkatorio.schema.common.PrototypeHashCode +//import dev.adamko.kafkatorio.schema.common.ServerMapChunkId +//import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer +//import dev.adamko.kafkatorio.schema.packets.MapChunkEntityUpdate +//import dev.adamko.kafkatorio.schema.packets.MapChunkResourceUpdate +//import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate +//import dev.adamko.kafkatorio.server.config.ApplicationProperties +//import dev.adamko.kafkatorio.server.processor.topology.ServerMapChunkTiles +//import dev.adamko.kafkatorio.server.processor.topology.broadcastToWebsocket +//import dev.adamko.kafkatorio.server.processor.topology.colourEntityChunks +//import dev.adamko.kafkatorio.server.processor.topology.colourMapChunks +//import dev.adamko.kafkatorio.server.processor.topology.convertEntityUpdateToServerMapChunkTiles +//import dev.adamko.kafkatorio.server.processor.topology.convertResourceUpdateToServerMapChunkTiles +//import dev.adamko.kafkatorio.server.processor.topology.factorioServerPacketStream +//import dev.adamko.kafkatorio.server.processor.topology.saveMapTiles +//import dev.adamko.kafkatorio.server.processor.topology.splitFactorioServerPacketStream +//import dev.adamko.kafkatorio.server.processor.topology.streamPacketData +//import dev.adamko.kafkatorio.server.socket.SyslogSocketServer +//import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer +//import java.util.Properties +//import kotlin.coroutines.resume +//import kotlin.coroutines.resumeWithException +//import kotlin.io.path.Path +//import kotlin.time.Duration.Companion.milliseconds +//import kotlin.time.Duration.Companion.seconds +//import kotlinx.coroutines.CoroutineName +//import kotlinx.coroutines.CoroutineScope +//import kotlinx.coroutines.cancel +//import kotlinx.coroutines.currentCoroutineContext +//import kotlinx.coroutines.job +//import kotlinx.coroutines.launch +//import kotlinx.coroutines.suspendCancellableCoroutine +//import org.apache.kafka.clients.producer.ProducerConfig +//import org.apache.kafka.streams.KafkaStreams +//import org.apache.kafka.streams.StreamsBuilder +//import org.apache.kafka.streams.StreamsConfig +//import org.apache.kafka.streams.Topology +//import org.apache.kafka.streams.TopologyDescription +//import org.apache.kafka.streams.kstream.KStream internal class KafkatorioTopology( - private val appProps: ApplicationProperties, - private val wsServer: WebmapWebsocketServer, - private val syslogServer: SyslogSocketServer, - private val kafkatorioPacketKafkaProducer: KafkatorioPacketKafkaProducer, +// private val appProps: ApplicationProperties, +// private val wsServer: WebmapWebsocketServer, +// private val syslogServer: SyslogSocketServer, +// private val kafkatorioPacketKafkaProducer: KafkatorioPacketKafkaProducer, ) { - private val builderScope = CoroutineScope(CoroutineName("KafkaTopology")) +// private val builderScope = CoroutineScope(CoroutineName("KafkaTopology")) - suspend fun start() = builderScope.launch { - splitPackets() - - groupTilesMapChunks() - - groupEntitiesMapChunks( - layer = ServerMapTileLayer.BUILDING, - colouredUpdatesStreamTopic = TOPIC_MAP_CHUNK_BUILDING_COLOURED_032_UPDATES, - colouredChunkStateTopic = TOPIC_MAP_CHUNK_BUILDING_COLOURED_STATE, - ) - - groupEntitiesMapChunks( - layer = ServerMapTileLayer.RESOURCE, - colouredUpdatesStreamTopic = TOPIC_MAP_CHUNK_RESOURCE_COLOURED_032_UPDATES, - colouredChunkStateTopic = TOPIC_MAP_CHUNK_RESOURCE_COLOURED_STATE, - ) - - saveTiles() - - websocketBroadcaster() - - syslogProducer() - } +// suspend fun start() = builderScope.launch { +// splitPackets() +// +// groupTilesMapChunks() +// +//// groupEntitiesMapChunks( +//// layer = ServerMapTileLayer.BUILDING, +//// colouredUpdatesStreamTopic = TOPIC_MAP_CHUNK_BUILDING_COLOURED_032_UPDATES, +//// colouredChunkStateTopic = TOPIC_MAP_CHUNK_BUILDING_COLOURED_STATE, +//// ) +// +//// groupEntitiesMapChunks( +//// layer = ServerMapTileLayer.RESOURCE, +//// colouredUpdatesStreamTopic = TOPIC_MAP_CHUNK_RESOURCE_COLOURED_032_UPDATES, +//// colouredChunkStateTopic = TOPIC_MAP_CHUNK_RESOURCE_COLOURED_STATE, +//// ) +// +// saveTiles() +// +// websocketBroadcaster() +// +// syslogProducer() +// } - private suspend fun splitPackets() { - val builder = StreamsBuilder() - val packets = factorioServerPacketStream(builder) - splitFactorioServerPacketStream(packets) - - val topology = builder.build() - - launchTopology("splitPackets", topology) - } +// private suspend fun splitPackets() { +// val builder = StreamsBuilder() +// val packets = factorioServerPacketStream(builder) +// splitFactorioServerPacketStream(packets) +// +// val topology = builder.build() +// +// launchTopology("splitPackets", topology) +// } - /** Terrain tiles */ - private suspend fun groupTilesMapChunks() { - val builder = StreamsBuilder() +// /** Terrain tiles */ +// private suspend fun groupTilesMapChunks() { +// val builder = StreamsBuilder() +// +// val protosStream: KStream = +// builder.streamPacketData() +// +// val topology = colourMapChunks(builder, protosStream) +// +// launchTopology("groupTilesMapChunks.${ServerMapTileLayer.TERRAIN.dir}", topology) +// } - val protosStream: KStream = - builder.streamPacketData() - - val topology = colourMapChunks(builder, protosStream) - - launchTopology("groupTilesMapChunks.${ServerMapTileLayer.TERRAIN.dir}", topology) - } +// +// /** Building and resource tiles */ +// private suspend fun groupEntitiesMapChunks( +// layer: ServerMapTileLayer, +// colouredUpdatesStreamTopic: String, +// colouredChunkStateTopic: String, +// ) { +// val builder = StreamsBuilder() +// +// val entityChunksStream: KStream> = +// when (layer) { +// ServerMapTileLayer.TERRAIN -> return +// +// ServerMapTileLayer.RESOURCE -> +// builder.streamPacketData() +// .convertResourceUpdateToServerMapChunkTiles("groupEntitiesMapChunks.${layer.dir}") +// +// ServerMapTileLayer.BUILDING -> +// builder.streamPacketData() +// .convertEntityUpdateToServerMapChunkTiles("groupEntitiesMapChunks.${layer.dir}") +// } +// +// val protosStream: KStream = +// builder.streamPacketData() +// +// val topology = colourEntityChunks( +// builder, +// entityChunksStream, +// protosStream, +// layer, +// colouredUpdatesStreamTopic, +// colouredChunkStateTopic, +// ) +// +// launchTopology("groupTilesMapChunks.${layer.dir}", topology) +// } - /** Building and resource tiles */ - private suspend fun groupEntitiesMapChunks( - layer: ServerMapTileLayer, - colouredUpdatesStreamTopic: String, - colouredChunkStateTopic: String, - ) { - val builder = StreamsBuilder() - - val entityChunksStream: KStream> = - when (layer) { - ServerMapTileLayer.TERRAIN -> return - - ServerMapTileLayer.RESOURCE -> - builder.streamPacketData() - .convertResourceUpdateToServerMapChunkTiles("groupEntitiesMapChunks.${layer.dir}") - - ServerMapTileLayer.BUILDING -> - builder.streamPacketData() - .convertEntityUpdateToServerMapChunkTiles("groupEntitiesMapChunks.${layer.dir}") - } - - val protosStream: KStream = - builder.streamPacketData() - - val topology = colourEntityChunks( - builder, - entityChunksStream, - protosStream, - layer, - colouredUpdatesStreamTopic, - colouredChunkStateTopic, - ) - - launchTopology("groupTilesMapChunks.${layer.dir}", topology) - } +// private suspend fun saveTiles() { +// val builder = StreamsBuilder() +// val topology = saveMapTiles(builder, appProps.serverDataDir) +// launchTopology("saveTiles", topology) +// } - private suspend fun saveTiles() { - val builder = StreamsBuilder() - val topology = saveMapTiles(builder, appProps.serverDataDir) - launchTopology("saveTiles", topology) - } +// private suspend fun websocketBroadcaster() { +// val builder = StreamsBuilder() +// broadcastToWebsocket(wsServer, builder) +// +// val topology = builder.build() +// +// launchTopology( +// "websocketBroadcaster", topology, mapOf( +// StreamsConfig.COMMIT_INTERVAL_MS_CONFIG to "${1.seconds.inWholeMilliseconds}", +// StreamsConfig.producerPrefix(ProducerConfig.LINGER_MS_CONFIG) to "${1.milliseconds.inWholeMilliseconds}" +// ) +// ) +// } - private suspend fun websocketBroadcaster() { - val builder = StreamsBuilder() - broadcastToWebsocket(wsServer, builder) - - val topology = builder.build() - - launchTopology( - "websocketBroadcaster", topology, mapOf( - StreamsConfig.COMMIT_INTERVAL_MS_CONFIG to "${1.seconds.inWholeMilliseconds}", - StreamsConfig.producerPrefix(ProducerConfig.LINGER_MS_CONFIG) to "${1.milliseconds.inWholeMilliseconds}" - ) - ) - } +// /** Receive log messages from the syslog socket, and send them to a Kafka topic */ +// private fun syslogProducer() { +// builderScope.launch { +// kafkatorioPacketKafkaProducer.launch() +// } +// } - /** Receive log messages from the syslog socket, and send them to a Kafka topic */ - private fun syslogProducer() { - builderScope.launch { - kafkatorioPacketKafkaProducer.launch() - } - } +// private suspend fun launchTopology( +// id: String, +// topology: Topology, +// additionalProperties: Map = mapOf(), +// ) { +// +// val props: Properties = appProps.kafkaStreamsConfig.toProperties() +// +// additionalProperties.forEach { (k, v) -> props.setProperty(k, v) } +// +// val appId = props.compute(StreamsConfig.APPLICATION_ID_CONFIG) { _, v -> "$v.$id" } as String +// props.setProperty(StreamsConfig.APPLICATION_ID_CONFIG, appId) +// +// builderScope.launch(CoroutineName(appId)) { +// +// val streamsState: KafkaStreams.State = suspendCancellableCoroutine { cont -> +// +// val streams = KafkaStreams(topology, props) +// streams.setUncaughtExceptionHandler(StreamsExceptionHandler { e -> +// cont.resumeWithException(e) +// }) +// +// streams.setStateListener { newState: KafkaStreams.State, _ -> +// when (newState) { +// KafkaStreams.State.NOT_RUNNING, +// KafkaStreams.State.ERROR -> if (cont.isActive) cont.resume(newState) +// +// else -> Unit // do nothing +// } +// } +// +// cont.invokeOnCancellation { +// println("[$appId] coroutine cancelled -> closing. cause:$it") +// streams.close() +// } +// +// printTopologyDescription(appId, topology) +// streams.start() +// println("launched Topology $appId") +// } +// println("exiting Topology $appId: $streamsState") +// currentCoroutineContext().job.cancel("$appId: $streamsState") +// } +// } - private suspend fun launchTopology( - id: String, - topology: Topology, - additionalProperties: Map = mapOf(), - ) { - - val props: Properties = appProps.kafkaStreamsConfig.toProperties() - - additionalProperties.forEach { (k, v) -> props.setProperty(k, v) } - - val appId = props.compute(StreamsConfig.APPLICATION_ID_CONFIG) { _, v -> "$v.$id" } as String - props.setProperty(StreamsConfig.APPLICATION_ID_CONFIG, appId) - - builderScope.launch(CoroutineName(appId)) { - - val streamsState: KafkaStreams.State = suspendCancellableCoroutine { cont -> - - val streams = KafkaStreams(topology, props) - streams.setUncaughtExceptionHandler(StreamsExceptionHandler { e -> - cont.resumeWithException(e) - }) - - streams.setStateListener { newState: KafkaStreams.State, _ -> - when (newState) { - KafkaStreams.State.NOT_RUNNING, - KafkaStreams.State.ERROR -> if (cont.isActive) cont.resume(newState) - - else -> Unit // do nothing - } - } - - cont.invokeOnCancellation { - println("[$appId] coroutine cancelled -> closing. cause:$it") - streams.close() - } - - printTopologyDescription(appId, topology) - streams.start() - println("launched Topology $appId") - } - println("exiting Topology $appId: $streamsState") - currentCoroutineContext().job.cancel("$appId: $streamsState") - } - } +// private fun printTopologyDescription(appId: String, topology: Topology) { +// val description: TopologyDescription = topology.describe() +// +// val descFile = Path("./build/$appId.txt").toFile().apply { +// parentFile.mkdirs() +// if (!exists()) createNewFile() +// writeText(description.toString()) +// } +// +// println( +// """ +// |---------------- +// |$appId - ${descFile.canonicalPath} +// |$description +// |---------------- +// """.trimMargin() +// ) +// } - private fun printTopologyDescription(appId: String, topology: Topology) { - val description: TopologyDescription = topology.describe() - - val descFile = Path("./build/$appId.txt").toFile().apply { - parentFile.mkdirs() - if (!exists()) createNewFile() - writeText(description.toString()) - } - - println( - """ - |---------------- - |$appId - ${descFile.canonicalPath} - |$description - |---------------- - """.trimMargin() - ) - } - - - companion object { - private fun Map.toProperties(): Properties = - entries.fold(Properties()) { props, (k, v) -> - props.apply { setProperty(k, v) } - } - } +// companion object { +// private fun Map.toProperties(): Properties = +// entries.fold(Properties()) { props, (k, v) -> +// props.apply { setProperty(k, v) } +// } +// } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt index 9c80d9c..7e0b2a3 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt @@ -1,35 +1,35 @@ package dev.adamko.kafkatorio.server.processor -import dev.adamko.kafkatorio.server.config.ApplicationProperties -import dev.adamko.kafkatorio.server.processor.admin.KafkatorioKafkaAdmin -import dev.adamko.kafkatorio.server.security.Authenticator -import dev.adamko.kafkatorio.server.socket.SyslogSocketServer -import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer -import kotlinx.coroutines.awaitCancellation -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch - - -suspend fun eventsProcessor( - appProps: ApplicationProperties, - syslogServer: SyslogSocketServer, - wsServer: WebmapWebsocketServer, - authenticator: Authenticator, -): Unit = coroutineScope { - - val admin = KafkatorioKafkaAdmin(appProps) - admin.createKafkatorioTopics() - - val kafkatorioPacketKafkaProducer = KafkatorioPacketKafkaProducer(appProps, syslogServer, authenticator) - - val topology = KafkatorioTopology(appProps, wsServer, syslogServer, kafkatorioPacketKafkaProducer) - - launch { - topology.start() - - println("launched KafkatorioTopology") - - awaitCancellation() - } -} +//import dev.adamko.kafkatorio.server.config.ApplicationProperties +//import dev.adamko.kafkatorio.server.processor.admin.KafkatorioKafkaAdmin +//import dev.adamko.kafkatorio.server.security.Authenticator +//import dev.adamko.kafkatorio.server.socket.SyslogSocketServer +//import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer +//import kotlinx.coroutines.awaitCancellation +//import kotlinx.coroutines.coroutineScope +//import kotlinx.coroutines.launch +// +// +//suspend fun eventsProcessor( +// appProps: ApplicationProperties, +// syslogServer: SyslogSocketServer, +// wsServer: WebmapWebsocketServer, +// authenticator: Authenticator, +//): Unit = coroutineScope { +// +// val admin = KafkatorioKafkaAdmin(appProps) +// admin.createKafkatorioTopics() +// +// val kafkatorioPacketKafkaProducer = KafkatorioPacketKafkaProducer(appProps, syslogServer, authenticator) +// +// val topology = KafkatorioTopology(appProps, wsServer, syslogServer, kafkatorioPacketKafkaProducer) +// +// launch { +// topology.start() +// +// println("launched KafkatorioTopology") +// +// awaitCancellation() +// } +//} diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index 5ecf3ec..4c694a9 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -109,3 +109,10 @@ tasks.processRun { tasks.processKill { dependsOn(clientKill) } + + +val runFactorioClient by tasks.registering { + group = rootProject.name + + dependsOn(tasks.processRun) +} diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 4380489..a97e76b 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -35,7 +35,7 @@ val deployModToLocalServer by tasks.registering(Copy::class) { into(factorioServerDataDir.dir("mods")) doLast { - logger.lifecycle("Copying mods ${source.files} to $destinationDir") + logger.lifecycle("Copying mods ${source.files} into $destinationDir") } } @@ -75,3 +75,9 @@ idea { excludeDirs.add(file("src/factorio-server")) } } + +val runFactorioServer by tasks.registering { + group = rootProject.name + + dependsOn(tasks.processRun) +} diff --git a/modules/infra-factorio-server/src/docker-compose.yml b/modules/infra-factorio-server/src/docker-compose.yml index 499e029..df48a83 100644 --- a/modules/infra-factorio-server/src/docker-compose.yml +++ b/modules/infra-factorio-server/src/docker-compose.yml @@ -20,7 +20,7 @@ services: driver: syslog options: syslog-address: "tcp://host.docker.internal:12034" # pc - #syslog-address: "tcp://localhost:12034" # nuc +# syslog-address: "tcp://localhost:12034" # nuc syslog-format: "rfc5424" tag: ${KAFKATORIO_TOKEN} diff --git a/modules/infra-kafka-cluster/build.gradle.kts b/modules/infra-kafka-cluster/build.gradle.kts index 9341a8e..e5f2040 100644 --- a/modules/infra-kafka-cluster/build.gradle.kts +++ b/modules/infra-kafka-cluster/build.gradle.kts @@ -27,3 +27,9 @@ tasks.dockerEnvUpdate { // "SCHEMA_REGISTRY_MEM_LIMIT" to "256m", ) } + +val runKafkaCluster by tasks.registering { + group = rootProject.name + + dependsOn(tasks.processRun) +} diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index d5c8942..2edf2d3 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -2,6 +2,6 @@ COMPOSE_PROJECT_NAME=kafkatorio GRAFANA_VERSION=8.5.0 KAFKATORIO_VERSION=0.9.0 -KAFKA_DL_URL=https\://dlcdn.apache.org/kafka/3.2.1/kafka_2.13-3.2.1.tgz -KAFKA_VERSION=3.2.1 +KAFKA_DL_URL=https\://dlcdn.apache.org/kafka/3.2.2/kafka_2.13-3.2.2.tgz +KAFKA_VERSION=3.2.2 PROMETHEUS_VERSION=v2.34.0 diff --git a/modules/modules.md b/modules/modules.md new file mode 100644 index 0000000..de6bd3d --- /dev/null +++ b/modules/modules.md @@ -0,0 +1,36 @@ +```mermaid +flowchart TD + +events-library-->events-processors & events-mod & web-map & events-server-web + +kafka[(Kafka)] + + +events-mod-->infra-factorio-client + + +subgraph Kafka Workers +events-processor-core --> events-processor-syslog & events-processors +end + +kafka<==>events-processors + +subgraph infra +subgraph factorio +infra-factorio-client<-->infra-factorio-server +end +infra-factorio-server-->infra-kafka-pipe +infra-kafka-pipe-->kafka +infra-kafka-cluster-->kafka +end + +kafka-->events-server-web + +events-server-web-->web-map + +versions-platform + +subgraph experiments +kt-rcon +end +``` diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index fc475cd..61c10d0 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -178,3 +178,10 @@ tasks.assemble { tasks.withType().configureEach { enabled = false } + + +val runWebMap by tasks.registering { + group = rootProject.name + + dependsOn(tasks.matching { it.name == "browserDevelopmentRun" }) +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index 532527b..f88e2ff 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -58,13 +58,13 @@ object App : Application() { require("./css/kafkatorio.css") - WebsocketService.packetsFlow - .filterIsInstance() - .onEach { tileSavedEvent -> -// println("[packetsFlow] triggering tile refresh ${tileSavedEvent.filename.value}") - siteStateStore.dispatch(SiteAction.EventServerUpdate(tileSavedEvent)) -// reduxStore.map.refreshUpdatedTilePng(tileSavedEvent.filename) - }.launchIn(coroutineScope) +// WebsocketService.packetsFlow +// .filterIsInstance() +// .onEach { tileSavedEvent -> +//// println("[packetsFlow] triggering tile refresh ${tileSavedEvent.filename.value}") +//// siteStateStore.dispatch(SiteAction.EventServerUpdate(tileSavedEvent)) +// siteStateStore.getState().factorioGameState?.map?.refreshUpdatedTilePng(tileSavedEvent.filename) +// }.launchIn(coroutineScope) } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/FactorioMap.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/FactorioMap.kt index e47c3fe..3407a67 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/FactorioMap.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/FactorioMap.kt @@ -3,8 +3,10 @@ package dev.adamko.kafkatorio.webmap import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer import dev.adamko.kafkatorio.schema.common.ServerMapTilePngFilename +import dev.adamko.kafkatorio.schema.packets.EventServerPacket import dev.adamko.kafkatorio.webmap.externals.TileOnLoadFn import dev.adamko.kafkatorio.webmap.externals.tileOnLoad +import dev.adamko.kafkatorio.webmap.services.WebsocketService import io.kvision.maps.Maps import io.kvision.maps.Maps.Companion.L import io.kvision.maps.externals.leaflet.DoneCallback @@ -18,8 +20,15 @@ import io.kvision.maps.externals.leaflet.layer.tile.TileLayer import io.kvision.utils.px import kotlinx.browser.document import kotlinx.browser.window +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.await import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.flow.filterIsInstance +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.js.jso import org.w3c.dom.HTMLElement @@ -36,6 +45,12 @@ class FactorioMap( private val serverId: FactorioServerId, ) { + private val coroutineScope: CoroutineScope = CoroutineScope( + Dispatchers.Default + + SupervisorJob(rootJob) + + CoroutineName("FactorioMap") + ) + val kvMap: Maps = Maps { minHeight = 800.px minWidth = 800.px @@ -90,6 +105,15 @@ class FactorioMap( playerIconsLayer.addTo(this) } + + + WebsocketService.packetsFlow + .filterIsInstance() + .onEach { tileSavedEvent -> +// println("[packetsFlow] triggering tile refresh ${tileSavedEvent.filename.value}") +// siteStateStore.dispatch(SiteAction.EventServerUpdate(tileSavedEvent)) + refreshUpdatedTilePng(tileSavedEvent.filename) + }.launchIn(coroutineScope) } diff --git a/settings.gradle.kts b/settings.gradle.kts index 13ece3e..e16d58a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,18 +1,30 @@ rootProject.name = "kafkatorio" + +@Suppress("UnstableApiUsage") +pluginManagement { + includeBuild("./gradle-plugins/settings-plugins/") +} + + +includeBuild("./gradle-plugins/builder-plugins/") +includeBuild("./gradle-plugins/factorio-mod-manager/") + + include( ":modules:events-library", ":modules:events-mod", ":modules:events-processor-core", - ":modules:events-processor-entities", - ":modules:events-processor-packets", - ":modules:events-processor-tiles", +// ":modules:events-processor-entities", + ":modules:events-processors", +// ":modules:events-processor-tiles", - ":modules:events-server", - ":modules:events-server-api", - ":modules:events-server-core", + +// ":modules:events-server", +// ":modules:events-server-core", + ":modules:events-server-web", ":modules:events-server-syslog", ":modules:infra-factorio-client", @@ -29,10 +41,13 @@ include( ":modules:versions-platform", ) + enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") + apply(from = "./buildSrc/repositories.settings.gradle.kts") + @Suppress("UnstableApiUsage") // Central declaration of repositories is an incubating feature dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) From bb973c7b9bc4cb03c7f84c6db9a2a618743dc452 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 16 Sep 2022 22:31:32 +0200 Subject: [PATCH 517/629] fix tests --- .../kafkatorio/processor/core/AuthenticatorTest.kt | 4 ++-- .../core/topology/FactorioServerPacketsTest.kt | 2 ++ .../processor/core/topology/SaveMapChunksTest.kt | 10 ++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/AuthenticatorTest.kt b/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/AuthenticatorTest.kt index 5fb2d4f..c58ccf1 100644 --- a/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/AuthenticatorTest.kt +++ b/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/AuthenticatorTest.kt @@ -1,8 +1,8 @@ package dev.adamko.kafkatorio.processor.core +import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.processor.config.PortVal import dev.adamko.kafkatorio.schema.common.MaskedValue -import dev.adamko.kafkatorio.server.config.ApplicationProperties -import dev.adamko.kafkatorio.server.config.PortVal import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.nulls.shouldBeNull import io.kotest.matchers.nulls.shouldNotBeNull diff --git a/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/FactorioServerPacketsTest.kt b/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/FactorioServerPacketsTest.kt index b219310..a357b58 100644 --- a/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/FactorioServerPacketsTest.kt +++ b/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/FactorioServerPacketsTest.kt @@ -4,6 +4,8 @@ import dev.adamko.kafkatorio.library.kxsBinary import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.ServerMapChunkId +import dev.adamko.kafkatorio.server.processor.topology.ServerMapChunkTiles +import dev.adamko.kafkatorio.server.processor.topology.factorioServerPacketStream import dev.adamko.kotka.kxs.serde import io.kotest.core.spec.style.FunSpec import kotlin.time.Duration diff --git a/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/SaveMapChunksTest.kt b/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/SaveMapChunksTest.kt index a82ce0e..ff66f41 100644 --- a/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/SaveMapChunksTest.kt +++ b/modules/events-processor-core/src/test/kotlin/dev/adamko/kafkatorio/processor/core/topology/SaveMapChunksTest.kt @@ -11,6 +11,8 @@ import dev.adamko.kafkatorio.schema.common.MapTilePosition import dev.adamko.kafkatorio.schema.common.ServerMapChunkId import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.server.processor.topology.ServerMapChunkTiles +import dev.adamko.kafkatorio.server.processor.topology.saveMapTiles import dev.adamko.kotka.kxs.serde import io.kotest.core.spec.style.FunSpec import io.kotest.property.Arb @@ -81,8 +83,12 @@ class SaveMapChunksTest : FunSpec({ val now = LocalTime.now().format(DateTimeFormatter.ISO_TIME).filter { it.isLetterOrDigit() } Path("build/test/save-map-chunks-${now}") } - private val topology = saveMapTiles(streamsBuilder, outputDir) - private val testDriver: TopologyTestDriver = TopologyTestDriver(topology) + private val testDriver: TopologyTestDriver + + init { + saveMapTiles(streamsBuilder, outputDir) + testDriver = TopologyTestDriver(streamsBuilder.build()) + } val groupedMapChunksInputTopic: TestInputTopic> = testDriver.createInputTopic( From cc6e55984316ff6be938bc475da6e75e87d76caf Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 18 Sep 2022 13:56:02 +0200 Subject: [PATCH 518/629] more prep for included-build Gradle plugins --- buildSrc/build.gradle.kts | 6 ++--- .../builder-plugins/build.gradle.kts | 24 +++++++++++++++++ .../builder-plugins/settings.gradle.kts | 27 +++---------------- .../factorio-mod-manager/build.gradle.kts | 24 +++++++++++++++++ .../factorio-mod-manager/settings.gradle.kts | 25 +++-------------- .../settings-plugins/build.gradle.kts | 12 ++++++--- .../convention/settings/repositories.kt | 9 +++++++ .../settings/repositories.settings.gradle.kts | 13 ++------- 8 files changed, 77 insertions(+), 63 deletions(-) create mode 100644 gradle-plugins/builder-plugins/build.gradle.kts create mode 100644 gradle-plugins/factorio-mod-manager/build.gradle.kts diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index de1982b..4c2e332 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -101,10 +101,10 @@ kotlin { jvmToolchain { (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) } +} - kotlinDslPluginOptions { - jvmTarget.set(gradleJvmTarget) - } +kotlinDslPluginOptions { + jvmTarget.set(gradleJvmTarget) } idea { diff --git a/gradle-plugins/builder-plugins/build.gradle.kts b/gradle-plugins/builder-plugins/build.gradle.kts new file mode 100644 index 0000000..cf30adb --- /dev/null +++ b/gradle-plugins/builder-plugins/build.gradle.kts @@ -0,0 +1,24 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + `kotlin-dsl` + kotlin("jvm") version embeddedKotlinVersion +} + +val gradleJvmTarget = "11" + +kotlin { + jvmToolchain { + (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) + } +} + +kotlinDslPluginOptions { + jvmTarget.set(gradleJvmTarget) +} + +tasks.withType().configureEach { + kotlinOptions { + jvmTarget = gradleJvmTarget + } +} diff --git a/gradle-plugins/builder-plugins/settings.gradle.kts b/gradle-plugins/builder-plugins/settings.gradle.kts index ba1c7f1..c5b5c98 100644 --- a/gradle-plugins/builder-plugins/settings.gradle.kts +++ b/gradle-plugins/builder-plugins/settings.gradle.kts @@ -1,31 +1,10 @@ -@file:Suppress("UnstableApiUsage") - rootProject.name = "builder-plugins" - pluginManagement { + @Suppress("UnstableApiUsage") includeBuild("../settings-plugins/") } - -dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) - - repositories { - mavenCentral() - gradlePluginPortal() - } - - pluginManagement { - repositories { - gradlePluginPortal() - mavenCentral() - } - } - - versionCatalogs { - create("libs") { - from(files("../../gradle/libs.versions.toml")) - } - } +plugins { + id("kafkatorio.convention.settings.repositories") } diff --git a/gradle-plugins/factorio-mod-manager/build.gradle.kts b/gradle-plugins/factorio-mod-manager/build.gradle.kts new file mode 100644 index 0000000..cf30adb --- /dev/null +++ b/gradle-plugins/factorio-mod-manager/build.gradle.kts @@ -0,0 +1,24 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + `kotlin-dsl` + kotlin("jvm") version embeddedKotlinVersion +} + +val gradleJvmTarget = "11" + +kotlin { + jvmToolchain { + (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) + } +} + +kotlinDslPluginOptions { + jvmTarget.set(gradleJvmTarget) +} + +tasks.withType().configureEach { + kotlinOptions { + jvmTarget = gradleJvmTarget + } +} diff --git a/gradle-plugins/factorio-mod-manager/settings.gradle.kts b/gradle-plugins/factorio-mod-manager/settings.gradle.kts index 7fafd65..d95228b 100644 --- a/gradle-plugins/factorio-mod-manager/settings.gradle.kts +++ b/gradle-plugins/factorio-mod-manager/settings.gradle.kts @@ -2,30 +2,11 @@ rootProject.name = "factorio-mod-manager" - pluginManagement { + @Suppress("UnstableApiUsage") includeBuild("../settings-plugins/") } - -dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) - - repositories { - mavenCentral() - gradlePluginPortal() - } - - pluginManagement { - repositories { - gradlePluginPortal() - mavenCentral() - } - } - - versionCatalogs { - create("libs") { - from(files("../../gradle/libs.versions.toml")) - } - } +plugins { + id("kafkatorio.convention.settings.repositories") } diff --git a/gradle-plugins/settings-plugins/build.gradle.kts b/gradle-plugins/settings-plugins/build.gradle.kts index 67a25ac..9e00fd7 100644 --- a/gradle-plugins/settings-plugins/build.gradle.kts +++ b/gradle-plugins/settings-plugins/build.gradle.kts @@ -7,14 +7,20 @@ plugins { val gradleJvmTarget = "11" +dependencies { + // This project should only be providing simple plugins for configuring Gradle without + // dependencies. Try to avoid setting dependencies here, else the Gradle script classpath might + // get polluted and messy. +} + kotlin { jvmToolchain { (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) } +} - kotlinDslPluginOptions { - jvmTarget.set(gradleJvmTarget) - } +kotlinDslPluginOptions { + jvmTarget.set(gradleJvmTarget) } tasks.withType().configureEach { diff --git a/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.kt b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.kt index 49df5f0..5f63f3f 100644 --- a/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.kt +++ b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.kt @@ -75,3 +75,12 @@ fun RepositoryHandler.gitHub() { } } } + + +fun RepositoryHandler.kotlinxHtml() { + maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") { + mavenContent { + includeGroup("org.jetbrains.kotlinx") + } + } +} diff --git a/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.settings.gradle.kts b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.settings.gradle.kts index 985683f..6bca2b5 100644 --- a/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.settings.gradle.kts +++ b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.settings.gradle.kts @@ -2,14 +2,7 @@ package kafkatorio.convention.settings @Suppress("UnstableApiUsage") // Central declaration of repositories is an incubating feature dependencyResolutionManagement { - - // https://github.com/gradle/gradle/issues/15754#issuecomment-763614651 - // https://github.com/gradle/gradle/blob/09fcaacc9848f09aa584b4119be9271bee6916e6/build-logic/build-logic-base/settings-plugin/src/main/kotlin/gradlebuild.repositories.settings.gradle.kts#L68 - - // Cannot use 'FAIL_ON_PROJECT_REPOS' because - // - the 'gradle-guides-plugin' adds a repo (which it should not do) - // - the 'kotlin-gradle-plugin' adds a repo (and removes it afterwards) to download NodeJS -// repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) repositories { myMavenLocal() @@ -25,9 +18,7 @@ dependencyResolutionManagement { content { includeGroup("dev.adamko.kotka") } } - maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") { - content { includeGroup("org.jetbrains.kotlinx") } - } + kotlinxHtml() sonatypeSnapshot() } From 16dc72ae7106f1771937e9c1b8c1253587542afc Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 18 Sep 2022 13:58:19 +0200 Subject: [PATCH 519/629] version bumps (minor bumps) --- gradle/kotlin-js-store/yarn.lock | 60 +++++++++---------- gradle/libs.versions.toml | 11 ++-- modules/web-map/build.gradle.kts | 11 ++-- .../src/main/resources/css/bootstrap.min.css | 6 +- 4 files changed, 46 insertions(+), 42 deletions(-) diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index 8c608d6..13a5eca 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -19,7 +19,7 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== -"@fortawesome/fontawesome-free@^6.1.2": +"@fortawesome/fontawesome-free@^6.2.0": version "6.2.0" resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.2.0.tgz#ba3510825b332816fe7190f28827f8cb33a298b5" integrity sha512-CNR7qRIfCwWHNN7FnKUniva94edPdyQzil/zCwk3v6k4R6rR2Fr8i4s3PM7n/lyfPA6Zfko9z5WDzFxG9SW1uQ== @@ -29,27 +29,11 @@ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== -"@popperjs/core@^2.11.5": +"@popperjs/core@^2.11.6": version "2.11.6" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.6.tgz#cee20bd55e68a1720bdab363ecf0c821ded4cd45" integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw== -"@rjaros/gettext.js@^1.1.3": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@rjaros/gettext.js/-/gettext.js-1.1.3.tgz#8d1109f4a6f8e0c4dadba26281c7fe83de8ab18f" - integrity sha512-FgGWKCN88UE6nOmIjdv+gSnrE3AXjMx7f4uo3brLzKcC9dKzuNNDCzTIbuEDg38Pm1yYUTUH6QG4493T4sUnDg== - dependencies: - "@rjaros/po2json" "^1.0.0-beta-4" - -"@rjaros/po2json@^1.0.0-beta-4": - version "1.0.0-beta-4" - resolved "https://registry.yarnpkg.com/@rjaros/po2json/-/po2json-1.0.0-beta-4.tgz#0bd911af874afa39d868aeb88f6903cfabfbf5dd" - integrity sha512-VhNHrPJtX+caY99UnjCmMB0EWY4EgtZ/pj/Usyj4VUt3TtjHE5nV+fz4bVC0/OO641ncEFFfC3SJ2TurcwEWPw== - dependencies: - commander "^6.0.0" - gettext-parser "2.0.0" - gettext-to-messageformat "0.3.1" - "@rjaros/snabbdom-virtualize@^1.0.0-beta.5": version "1.0.0-beta.5" resolved "https://registry.yarnpkg.com/@rjaros/snabbdom-virtualize/-/snabbdom-virtualize-1.0.0-beta.5.tgz#17f2586beee5e6c130e1b0ae2f589ff9162a86db" @@ -556,10 +540,10 @@ bootstrap-icons@^1.9.1: resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.9.1.tgz#cf22d91a25447645e45c49ebde4e56eafdfe761b" integrity sha512-d4ZkO30MIkAhQ2nNRJqKXJVEQorALGbLWTuRxyCTJF96lRIV6imcgMehWGJUiJMJhglN0o2tqLIeDnMdiQEE9g== -bootstrap@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.2.0.tgz#838727fb60f1630db370fe57c63cbcf2962bb3d3" - integrity sha512-qlnS9GL6YZE6Wnef46GxGv1UpGGzAwO0aPL1yOjzDIJpeApeMvqV24iL+pjr2kU4dduoBA9fINKWKgMToobx9A== +bootstrap@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.2.1.tgz#45f97ff05cbe828bad807b014d8425f3aeb8ec3a" + integrity sha512-UQi3v2NpVPEi1n35dmRRzBJFlgvWHYwyem6yHhuT6afYF+sziEt46McRbT//kVXZ7b1YUYEVGdXEH74Nx3xzGA== brace-expansion@^1.1.7: version "1.1.11" @@ -1371,6 +1355,13 @@ gettext-to-messageformat@0.3.1: dependencies: gettext-parser "^1.4.0" +gettext.js@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gettext.js/-/gettext.js-1.2.0.tgz#783e166c604bc60c4b70f4656391038aa9e950b2" + integrity sha512-qOafHtn/xsXKiBOFO8enhdx8k09ViBYSnckhn4pn/QLCpQMF8S87q9f4cE2pVgbqWD9/9SyGpWRO0nWJsEDmlg== + dependencies: + po2json "^1.0.0-beta-3" + glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -1542,10 +1533,10 @@ import-local@^3.0.2: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" -imports-loader@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-4.0.0.tgz#c11574247beca48e6549db1eb603f8939884aca1" - integrity sha512-8PPbhk/9CEHd0WWKESw/oYTDhp3So9PWA9OfyIbH3kywIN4uxrWkQ8ux47xpk4yWUKX97Erbws9MFSaBlVvAjg== +imports-loader@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-4.0.1.tgz#a3d3067d0c369cd621e2b322b6b6bb2593756be5" + integrity sha512-ZiY+1xH5fqAJ1Qu1CFv+zw54rvPCC92DdYRDe0IIUboOhbJPLfOPbF/paA2iipelvMwjQUKWydcFOJ7f1+ZFcA== dependencies: source-map "^0.6.1" strip-comments "^2.0.1" @@ -2191,6 +2182,15 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +po2json@^1.0.0-beta-3: + version "1.0.0-beta-3" + resolved "https://registry.yarnpkg.com/po2json/-/po2json-1.0.0-beta-3.tgz#f087abeeccdc82c1e5315a749e5f3bcf7e1421e1" + integrity sha512-taS8y6ZEGzPAs0rygW9CuUPY8C3Zgx6cBy31QXxG2JlWS3fLxj/kuD3cbIfXBg30PuYN7J5oyBa/TIRjyqFFtg== + dependencies: + commander "^6.0.0" + gettext-parser "2.0.0" + gettext-to-messageformat "0.3.1" + pofile@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.0.11.tgz#35aff58c17491d127a07336d5522ebc9df57c954" @@ -2913,10 +2913,10 @@ webpack-dev-middleware@^5.3.1: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@4.9.3: - version "4.9.3" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.9.3.tgz#2360a5d6d532acb5410a668417ad549ee3b8a3c9" - integrity sha512-3qp/eoboZG5/6QgiZ3llN8TUzkSpYg1Ko9khWX1h40MIEUNS2mDoIa8aXsPfskER+GbTvs/IJZ1QTBBhhuetSw== +webpack-dev-server@4.11.0: + version "4.11.0" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.11.0.tgz#290ee594765cd8260adfe83b2d18115ea04484e7" + integrity sha512-L5S4Q2zT57SK7tazgzjMiSMBdsw+rGYIX27MgPgx7LDhWO0lViPrHKoLS7jo5In06PWYAhlYu3PbyoC6yAThbw== dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8233f44..af29c20 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ kotlin = "1.7.10" camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" kafka = "3.2.2" # https://kafka.apache.org/downloads -kvision = "5.14.0" # https://github.com/rjaros/kvision/releases +kvision = "5.15.2" # https://github.com/rjaros/kvision/releases log4j2 = "2.17.2" okio = "3.2.0" # https://search.maven.org/artifact/com.squareup.okio/okio qosLogback = "1.2.11" @@ -25,7 +25,7 @@ kxs-charleskornKaml = "0.44.0" kxs-mamoeYamlkt = "0.12.0" kxs-kxsTsGen = "0.2.1" -kotlinJsWrappers = "1.0.0-pre.383" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom +kotlinJsWrappers = "1.0.0-pre.387" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom kotlinx-cli = "0.3.4" kotlinx-coroutines = "1.6.4" # https://github.com/Kotlin/kotlinx.coroutines/releases @@ -47,7 +47,7 @@ marykRocksDb = "7.3.1-1" # https://search.maven.org/artifact/io.m klogging = "0.4.9" -nimbusJoseJwt = "9.24.4" # https://search.maven.org/artifact/com.nimbusds/nimbus-jose-jwt +nimbusJoseJwt = "9.25" # https://search.maven.org/artifact/com.nimbusds/nimbus-jose-jwt ## npm ## @@ -56,12 +56,13 @@ npm-typescriptToLua = "1.10.0" # https://www.npmjs.com/package/typescript-to-l npm-typedFactorio = "1.7.5" # https://www.npmjs.com/package/typed-factorio npm-typescript = "4.8.3" # https://github.com/microsoft/TypeScript/releases +npm-bootswatch = "5.2.1" # https://www.jsdelivr.com/package/npm/bootswatch ## test ## -junit = "5.9.0" +junit = "5.9.0" # https://github.com/junit-team/junit5/releases #kotest = "5.4.2" kotest = "5.5.0-LOCAL" -mockk = "1.12.5" +mockk = "1.12.8" # https://github.com/mockk/mockk/releases/ ## infra ## diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 61c10d0..d82c67a 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -161,16 +161,19 @@ tasks.assemble { dependsOn(dockerEnvUpdate) } val installThemeCss by tasks.registering(Copy::class) { -// val bootswatchThemeCss = resources.text.fromUri("https://bootswatch.com/5/darkly/bootstrap.css") - val bootswatchThemeMinCss = - resources.text.fromUri("https://bootswatch.com/5/darkly/bootstrap.min.css") + val bootswatchThemeMinCss = resources.text.fromUri( + libs.versions.npm.bootswatch.map { bootswatch -> + "https://cdn.jsdelivr.net/npm/bootswatch@$bootswatch/dist/darkly/bootstrap.min.css" + } + ) from(bootswatchThemeMinCss) { rename { "bootstrap.min.css" } } into(layout.projectDirectory.dir("src/main/resources/css")) } -tasks.assemble { + +tasks.matching { it.name == "processResources" }.configureEach { dependsOn(installThemeCss) } diff --git a/modules/web-map/src/main/resources/css/bootstrap.min.css b/modules/web-map/src/main/resources/css/bootstrap.min.css index 243b81e..d58f6c3 100644 --- a/modules/web-map/src/main/resources/css/bootstrap.min.css +++ b/modules/web-map/src/main/resources/css/bootstrap.min.css @@ -1,12 +1,12 @@ @charset "UTF-8";/*! - * Bootswatch v5.2.0 (https://bootswatch.com) + * Bootswatch v5.2.1 (https://bootswatch.com) * Theme: darkly * Copyright 2012-2022 Thomas Park * Licensed under MIT * Based on Bootstrap *//*! - * Bootstrap v5.2.0 (https://getbootstrap.com/) + * Bootstrap v5.2.1 (https://getbootstrap.com/) * Copyright 2011-2022 The Bootstrap Authors * Copyright 2011-2022 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */@import url(https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap);:root{--bs-blue:#375a7f;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#e83e8c;--bs-red:#e74c3c;--bs-orange:#fd7e14;--bs-yellow:#f39c12;--bs-green:#00bc8c;--bs-teal:#20c997;--bs-cyan:#3498db;--bs-black:#000;--bs-white:#fff;--bs-gray:#888;--bs-gray-dark:#303030;--bs-gray-100:#f8f9fa;--bs-gray-200:#ebebeb;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#888;--bs-gray-700:#444;--bs-gray-800:#303030;--bs-gray-900:#222;--bs-primary:#375a7f;--bs-secondary:#444;--bs-success:#00bc8c;--bs-info:#3498db;--bs-warning:#f39c12;--bs-danger:#e74c3c;--bs-light:#adb5bd;--bs-dark:#303030;--bs-primary-rgb:55,90,127;--bs-secondary-rgb:68,68,68;--bs-success-rgb:0,188,140;--bs-info-rgb:52,152,219;--bs-warning-rgb:243,156,18;--bs-danger-rgb:231,76,60;--bs-light-rgb:173,181,189;--bs-dark-rgb:48,48,48;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:255,255,255;--bs-body-bg-rgb:34,34,34;--bs-font-sans-serif:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#fff;--bs-body-bg:#222;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#00bc8c;--bs-link-hover-color:#009670;--bs-code-color:#e83e8c;--bs-highlight-bg:#fdebd0}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:1px solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:calc(1.425rem + 2.1vw)}@media (min-width:1200px){.h1,h1{font-size:3rem}}.h2,h2{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h2,h2{font-size:2.5rem}}.h3,h3{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h3,h3{font-size:2rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--bs-link-color);text-decoration:underline}a:hover{color:var(--bs-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em;color:inherit}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#888;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#888}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#222;border:1px solid var(--bs-border-color);border-radius:.375rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#888}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color:var(--bs-body-color);--bs-table-bg:transparent;--bs-table-border-color:#444;--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-body-color);--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:var(--bs-body-color);--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:var(--bs-body-color);--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:var(--bs-table-color);vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:2px solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-striped-columns>:not(caption)>tr>:nth-child(even){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-color:#fff;--bs-table-bg:#375a7f;--bs-table-border-color:#4b6b8c;--bs-table-striped-bg:#416285;--bs-table-striped-color:#fff;--bs-table-active-bg:#4b6b8c;--bs-table-active-color:#fff;--bs-table-hover-bg:#466689;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#fff;--bs-table-bg:#444444;--bs-table-border-color:#575757;--bs-table-striped-bg:#4d4d4d;--bs-table-striped-color:#fff;--bs-table-active-bg:#575757;--bs-table-active-color:#fff;--bs-table-hover-bg:#525252;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#fff;--bs-table-bg:#00bc8c;--bs-table-border-color:#1ac398;--bs-table-striped-bg:#0dbf92;--bs-table-striped-color:#fff;--bs-table-active-bg:#1ac398;--bs-table-active-color:#fff;--bs-table-hover-bg:#13c195;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#fff;--bs-table-bg:#3498db;--bs-table-border-color:#48a2df;--bs-table-striped-bg:#3e9ddd;--bs-table-striped-color:#fff;--bs-table-active-bg:#48a2df;--bs-table-active-color:#fff;--bs-table-hover-bg:#43a0de;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#fff;--bs-table-bg:#f39c12;--bs-table-border-color:#f4a62a;--bs-table-striped-bg:#f4a11e;--bs-table-striped-color:#fff;--bs-table-active-bg:#f4a62a;--bs-table-active-color:#fff;--bs-table-hover-bg:#f4a324;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#fff;--bs-table-bg:#e74c3c;--bs-table-border-color:#e95e50;--bs-table-striped-bg:#e85546;--bs-table-striped-color:#fff;--bs-table-active-bg:#e95e50;--bs-table-active-color:#fff;--bs-table-hover-bg:#e9594b;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#fff;--bs-table-bg:#adb5bd;--bs-table-border-color:#b5bcc4;--bs-table-striped-bg:#b1b9c0;--bs-table-striped-color:#fff;--bs-table-active-bg:#b5bcc4;--bs-table-active-color:#fff;--bs-table-hover-bg:#b3bbc2;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#303030;--bs-table-border-color:#454545;--bs-table-striped-bg:#3a3a3a;--bs-table-striped-color:#fff;--bs-table-active-bg:#454545;--bs-table-active-color:#fff;--bs-table-hover-bg:#404040;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:#888}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#303030;background-color:#fff;background-clip:padding-box;border:1px solid #222;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#303030;background-color:#fff;border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-moz-placeholder{color:#888;opacity:1}.form-control::placeholder{color:#888;opacity:1}.form-control:disabled{background-color:#ebebeb;opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#fff;background-color:#444;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#fff;background-color:#444;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#414141}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#414141}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#fff;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{width:3rem;height:calc(1.5em + .75rem + 2px);padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:.375rem}.form-control-color::-webkit-color-swatch{border-radius:.375rem}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + 2px)}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + 2px)}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:#303030;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #222;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#ebebeb}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #303030}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:.25rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:.5rem}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-check-input:checked{background-color:#375a7f;border-color:#375a7f}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#375a7f;border-color:#375a7f;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%239badbf'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #222,0 0 0 .25rem rgba(55,90,127,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #222,0 0 0 .25rem rgba(55,90,127,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#375a7f;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#c3ced9}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#375a7f;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#c3ced9}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;width:100%;height:100%;padding:1rem .75rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::-moz-placeholder,.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown),.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:1px 0}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#adb5bd;text-align:center;white-space:nowrap;background-color:#444;border:1px solid #222;border-radius:.375rem}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select,.input-group>:not(:first-child):not(.dropdown-menu):not(.form-floating):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#00bc8c}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(0,188,140,.9);border-radius:.375rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#00bc8c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#00bc8c}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#00bc8c}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#00bc8c}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#00bc8c}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group .form-control.is-valid,.input-group .form-select.is-valid,.was-validated .input-group .form-control:valid,.was-validated .input-group .form-select:valid{z-index:1}.input-group .form-control.is-valid:focus,.input-group .form-select.is-valid:focus,.was-validated .input-group .form-control:valid:focus,.was-validated .input-group .form-select:valid:focus{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#e74c3c}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(231,76,60,.9);border-radius:.375rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#e74c3c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#e74c3c}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#e74c3c}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#e74c3c}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#e74c3c}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group .form-control.is-invalid,.input-group .form-select.is-invalid,.was-validated .input-group .form-control:invalid,.was-validated .input-group .form-select:invalid{z-index:2}.input-group .form-control.is-invalid:focus,.input-group .form-select.is-invalid:focus,.was-validated .input-group .form-control:invalid:focus,.was-validated .input-group .form-select:invalid:focus{z-index:3}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#fff;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check:focus+.btn,.btn:focus{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:active+.btn,.btn-check:checked+.btn,.btn.active,.btn.show,.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:active+.btn:focus,.btn-check:checked+.btn:focus,.btn.active:focus,.btn.show:focus,.btn:active:focus{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#375a7f;--bs-btn-border-color:#375a7f;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#2f4d6c;--bs-btn-hover-border-color:#2c4866;--bs-btn-focus-shadow-rgb:85,115,146;--bs-btn-active-color:#fff;--bs-btn-active-bg:#2c4866;--bs-btn-active-border-color:#29445f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#375a7f;--bs-btn-disabled-border-color:#375a7f}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#444;--bs-btn-border-color:#444;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#3a3a3a;--bs-btn-hover-border-color:#363636;--bs-btn-focus-shadow-rgb:96,96,96;--bs-btn-active-color:#fff;--bs-btn-active-bg:#363636;--bs-btn-active-border-color:#333333;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#444;--bs-btn-disabled-border-color:#444}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#00bc8c;--bs-btn-border-color:#00bc8c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#00a077;--bs-btn-hover-border-color:#009670;--bs-btn-focus-shadow-rgb:38,198,157;--bs-btn-active-color:#fff;--bs-btn-active-bg:#009670;--bs-btn-active-border-color:#008d69;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#00bc8c;--bs-btn-disabled-border-color:#00bc8c}.btn-info{--bs-btn-color:#fff;--bs-btn-bg:#3498db;--bs-btn-border-color:#3498db;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#2c81ba;--bs-btn-hover-border-color:#2a7aaf;--bs-btn-focus-shadow-rgb:82,167,224;--bs-btn-active-color:#fff;--bs-btn-active-bg:#2a7aaf;--bs-btn-active-border-color:#2772a4;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#3498db;--bs-btn-disabled-border-color:#3498db}.btn-warning{--bs-btn-color:#fff;--bs-btn-bg:#f39c12;--bs-btn-border-color:#f39c12;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#cf850f;--bs-btn-hover-border-color:#c27d0e;--bs-btn-focus-shadow-rgb:245,171,54;--bs-btn-active-color:#fff;--bs-btn-active-bg:#c27d0e;--bs-btn-active-border-color:#b6750e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#f39c12;--bs-btn-disabled-border-color:#f39c12}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#e74c3c;--bs-btn-border-color:#e74c3c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#c44133;--bs-btn-hover-border-color:#b93d30;--bs-btn-focus-shadow-rgb:235,103,89;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b93d30;--bs-btn-active-border-color:#ad392d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#e74c3c;--bs-btn-disabled-border-color:#e74c3c}.btn-light{--bs-btn-color:#fff;--bs-btn-bg:#adb5bd;--bs-btn-border-color:#adb5bd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#939aa1;--bs-btn-hover-border-color:#8a9197;--bs-btn-focus-shadow-rgb:185,192,199;--bs-btn-active-color:#fff;--bs-btn-active-bg:#8a9197;--bs-btn-active-border-color:#82888e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#adb5bd;--bs-btn-disabled-border-color:#adb5bd}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#303030;--bs-btn-border-color:#303030;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#4f4f4f;--bs-btn-hover-border-color:#454545;--bs-btn-focus-shadow-rgb:79,79,79;--bs-btn-active-color:#fff;--bs-btn-active-bg:#595959;--bs-btn-active-border-color:#454545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#303030;--bs-btn-disabled-border-color:#303030}.btn-outline-primary{--bs-btn-color:#375a7f;--bs-btn-border-color:#375a7f;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#375a7f;--bs-btn-hover-border-color:#375a7f;--bs-btn-focus-shadow-rgb:55,90,127;--bs-btn-active-color:#fff;--bs-btn-active-bg:#375a7f;--bs-btn-active-border-color:#375a7f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#375a7f;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#375a7f;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#444;--bs-btn-border-color:#444;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#444;--bs-btn-hover-border-color:#444;--bs-btn-focus-shadow-rgb:68,68,68;--bs-btn-active-color:#fff;--bs-btn-active-bg:#444;--bs-btn-active-border-color:#444;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#444;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#444;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#00bc8c;--bs-btn-border-color:#00bc8c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#00bc8c;--bs-btn-hover-border-color:#00bc8c;--bs-btn-focus-shadow-rgb:0,188,140;--bs-btn-active-color:#fff;--bs-btn-active-bg:#00bc8c;--bs-btn-active-border-color:#00bc8c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#00bc8c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#00bc8c;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#3498db;--bs-btn-border-color:#3498db;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#3498db;--bs-btn-hover-border-color:#3498db;--bs-btn-focus-shadow-rgb:52,152,219;--bs-btn-active-color:#fff;--bs-btn-active-bg:#3498db;--bs-btn-active-border-color:#3498db;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#3498db;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#3498db;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#f39c12;--bs-btn-border-color:#f39c12;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#f39c12;--bs-btn-hover-border-color:#f39c12;--bs-btn-focus-shadow-rgb:243,156,18;--bs-btn-active-color:#fff;--bs-btn-active-bg:#f39c12;--bs-btn-active-border-color:#f39c12;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f39c12;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f39c12;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#e74c3c;--bs-btn-border-color:#e74c3c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#e74c3c;--bs-btn-hover-border-color:#e74c3c;--bs-btn-focus-shadow-rgb:231,76,60;--bs-btn-active-color:#fff;--bs-btn-active-bg:#e74c3c;--bs-btn-active-border-color:#e74c3c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#e74c3c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#e74c3c;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#adb5bd;--bs-btn-border-color:#adb5bd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#adb5bd;--bs-btn-hover-border-color:#adb5bd;--bs-btn-focus-shadow-rgb:173,181,189;--bs-btn-active-color:#fff;--bs-btn-active-bg:#adb5bd;--bs-btn-active-border-color:#adb5bd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#adb5bd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#adb5bd;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#303030;--bs-btn-border-color:#303030;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#303030;--bs-btn-hover-border-color:#303030;--bs-btn-focus-shadow-rgb:48,48,48;--bs-btn-active-color:#fff;--bs-btn-active-bg:#303030;--bs-btn-active-border-color:#303030;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#303030;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#303030;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#888;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:85,115,146;text-decoration:underline}.btn-link:focus{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:0.5rem}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:0.25rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:#fff;--bs-dropdown-bg:#222;--bs-dropdown-border-color:#444;--bs-dropdown-border-radius:0.375rem;--bs-dropdown-border-width:1px;--bs-dropdown-inner-border-radius:calc(0.375rem - 1px);--bs-dropdown-divider-bg:#444;--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-dropdown-link-color:#fff;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-link-hover-bg:#375a7f;--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#375a7f;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#888;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:1000;display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#303030;--bs-dropdown-border-color:#444;--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:#444;--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#375a7f;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:.375rem}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:2rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#adb5bd;display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#444;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#444 #444 transparent;--bs-nav-tabs-link-active-color:#fff;--bs-nav-tabs-link-active-bg:#222;--bs-nav-tabs-link-active-border-color:#444 #444 transparent;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(var(--bs-nav-tabs-border-width) * -1);background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(var(--bs-nav-tabs-border-width) * -1);border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:0.375rem;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#375a7f}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:1rem;--bs-navbar-color:rgba(34, 34, 34, 0.7);--bs-navbar-hover-color:#222;--bs-navbar-disabled-color:rgba(0, 0, 0, 0.3);--bs-navbar-active-color:#222;--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:#222;--bs-navbar-brand-hover-color:#222;--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2834, 34, 34, 0.7%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(34, 34, 34, 0.1);--bs-navbar-toggler-border-radius:0.375rem;--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .show>.nav-link{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark{--bs-navbar-color:rgba(255, 255, 255, 0.6);--bs-navbar-hover-color:#fff;--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.6%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-border-width:1px;--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:0.375rem;--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(0.375rem - 1px);--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:#444;--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:#303030;--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:#fff;--bs-accordion-bg:#222;--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:1px;--bs-accordion-border-radius:0.375rem;--bs-accordion-inner-border-radius:calc(0.375rem - 1px);--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='var%28--bs-body-color%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23325172'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-focus-border-color:#9badbf;--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(55, 90, 127, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:#325172;--bs-accordion-active-bg:#ebeff2}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(var(--bs-accordion-border-width) * -1) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:var(--bs-accordion-btn-focus-border-color);outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button{border-radius:0}.breadcrumb{--bs-breadcrumb-padding-x:0.75rem;--bs-breadcrumb-padding-y:0.375rem;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg:#444;--bs-breadcrumb-border-radius:0.25rem;--bs-breadcrumb-divider-color:#888;--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:#888;display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:#fff;--bs-pagination-bg:#00bc8c;--bs-pagination-border-width:0;--bs-pagination-border-color:transparent;--bs-pagination-border-radius:0.375rem;--bs-pagination-hover-color:#fff;--bs-pagination-hover-bg:#00efb2;--bs-pagination-hover-border-color:transparent;--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:#ebebeb;--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(55, 90, 127, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#00efb2;--bs-pagination-active-border-color:transparent;--bs-pagination-disabled-color:#fff;--bs-pagination-disabled-bg:#007053;--bs-pagination-disabled-border-color:transparent;display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:0.5rem}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:0.25rem}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:0.375rem;display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:1px solid var(--bs-alert-border-color);--bs-alert-border-radius:0.375rem;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:#21364c;--bs-alert-bg:#d7dee5;--bs-alert-border-color:#c3ced9}.alert-primary .alert-link{color:#1a2b3d}.alert-secondary{--bs-alert-color:#292929;--bs-alert-bg:#dadada;--bs-alert-border-color:#c7c7c7}.alert-secondary .alert-link{color:#212121}.alert-success{--bs-alert-color:#007154;--bs-alert-bg:#ccf2e8;--bs-alert-border-color:#b3ebdd}.alert-success .alert-link{color:#005a43}.alert-info{--bs-alert-color:#1f5b83;--bs-alert-bg:#d6eaf8;--bs-alert-border-color:#c2e0f4}.alert-info .alert-link{color:#194969}.alert-warning{--bs-alert-color:#925e0b;--bs-alert-bg:#fdebd0;--bs-alert-border-color:#fbe1b8}.alert-warning .alert-link{color:#754b09}.alert-danger{--bs-alert-color:#8b2e24;--bs-alert-bg:#fadbd8;--bs-alert-border-color:#f8c9c5}.alert-danger .alert-link{color:#6f251d}.alert-light{--bs-alert-color:#686d71;--bs-alert-bg:#eff0f2;--bs-alert-border-color:#e6e9eb}.alert-light .alert-link{color:#53575a}.alert-dark{--bs-alert-color:#1d1d1d;--bs-alert-bg:#d6d6d6;--bs-alert-border-color:#c1c1c1}.alert-dark .alert-link{color:#171717}@-webkit-keyframes progress-bar-stripes{0%{background-position-x:1rem}}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:#444;--bs-progress-border-radius:0.375rem;--bs-progress-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#375a7f;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.list-group{--bs-list-group-color:#fff;--bs-list-group-bg:#303030;--bs-list-group-border-color:#444;--bs-list-group-border-width:1px;--bs-list-group-border-radius:0.375rem;--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:#444;--bs-list-group-action-hover-color:#fff;--bs-list-group-action-hover-bg:#444;--bs-list-group-action-active-color:#fff;--bs-list-group-action-active-bg:#222;--bs-list-group-disabled-color:#888;--bs-list-group-disabled-bg:#303030;--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#375a7f;--bs-list-group-active-border-color:#375a7f;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(var(--bs-list-group-border-width) * -1);border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(var(--bs-list-group-border-width) * -1);border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(var(--bs-list-group-border-width) * -1);border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(var(--bs-list-group-border-width) * -1);border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(var(--bs-list-group-border-width) * -1);border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(var(--bs-list-group-border-width) * -1);border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(var(--bs-list-group-border-width) * -1);border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#21364c;background-color:#d7dee5}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#21364c;background-color:#c2c8ce}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#21364c;border-color:#21364c}.list-group-item-secondary{color:#292929;background-color:#dadada}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#292929;background-color:#c4c4c4}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#292929;border-color:#292929}.list-group-item-success{color:#007154;background-color:#ccf2e8}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#007154;background-color:#b8dad1}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#007154;border-color:#007154}.list-group-item-info{color:#1f5b83;background-color:#d6eaf8}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#1f5b83;background-color:#c1d3df}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#1f5b83;border-color:#1f5b83}.list-group-item-warning{color:#925e0b;background-color:#fdebd0}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#925e0b;background-color:#e4d4bb}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#925e0b;border-color:#925e0b}.list-group-item-danger{color:#8b2e24;background-color:#fadbd8}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#8b2e24;background-color:#e1c5c2}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#8b2e24;border-color:#8b2e24}.list-group-item-light{color:#686d71;background-color:#eff0f2}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#686d71;background-color:#d7d8da}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#686d71;border-color:#686d71}.list-group-item-dark{color:#1d1d1d;background-color:#d6d6d6}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1d1d1d;background-color:#c1c1c1}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1d1d1d;border-color:#1d1d1d}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#fff;background:transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.375rem;opacity:.4}.btn-close:hover{color:#fff;text-decoration:none;opacity:1}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25);opacity:1}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:#444;--bs-toast-border-width:1px;--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:0.375rem;--bs-toast-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-toast-header-color:#888;--bs-toast-header-bg:#303030;--bs-toast-header-border-color:rgba(0, 0, 0, 0.05);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{position:absolute;z-index:1090;width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(var(--bs-toast-padding-x) * -.5);margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:#303030;--bs-modal-border-color:#444;--bs-modal-border-width:1px;--bs-modal-border-radius:0.5rem;--bs-modal-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-modal-inner-border-radius:calc(0.5rem - 1px);--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:#444;--bs-modal-header-border-width:1px;--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:#444;--bs-modal-footer-border-width:1px;position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin:calc(var(--bs-modal-header-padding-y) * -.5) calc(var(--bs-modal-header-padding-x) * -.5) calc(var(--bs-modal-header-padding-y) * -.5) auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:#fff;--bs-tooltip-bg:#000;--bs-tooltip-border-radius:0.375rem;--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;padding:var(--bs-tooltip-arrow-height);margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:#303030;--bs-popover-border-width:1px;--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:0.5rem;--bs-popover-inner-border-radius:calc(0.5rem - 1px);--bs-popover-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color:var(--bs-heading-color);--bs-popover-header-bg:#444;--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:#fff;--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(var(--bs-popover-arrow-height) * -1 - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(var(--bs-popover-arrow-height) * -1 - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(var(--bs-popover-arrow-height) * -1 - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(var(--bs-popover-arrow-width) * -.5);content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(var(--bs-popover-arrow-height) * -1 - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;-webkit-animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name);animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@-webkit-keyframes spinner-border{to{transform:rotate(360deg)}}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color: ;--bs-offcanvas-bg:#303030;--bs-offcanvas-border-width:1px;--bs-offcanvas-border-color:#444;--bs-offcanvas-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075)}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:1045;display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:575.98px){.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}}@media (max-width:575.98px){.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:1045;display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:767.98px){.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}}@media (max-width:767.98px){.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:1045;display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:991.98px){.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}}@media (max-width:991.98px){.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:1045;display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1199.98px){.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}}@media (max-width:1199.98px){.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:1045;display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}}@media (max-width:1399.98px){.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:1045;display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin-top:calc(var(--bs-offcanvas-padding-y) * -.5);margin-right:calc(var(--bs-offcanvas-padding-x) * -.5);margin-bottom:calc(var(--bs-offcanvas-padding-y) * -.5)}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{-webkit-animation:placeholder-glow 2s ease-in-out infinite;animation:placeholder-glow 2s ease-in-out infinite}@-webkit-keyframes placeholder-glow{50%{opacity:.2}}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;-webkit-animation:placeholder-wave 2s linear infinite;animation:placeholder-wave 2s linear infinite}@-webkit-keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(55,90,127,var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(68,68,68,var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(0,188,140,var(--bs-bg-opacity,1))!important}.text-bg-info{color:#fff!important;background-color:RGBA(52,152,219,var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#fff!important;background-color:RGBA(243,156,18,var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(231,76,60,var(--bs-bg-opacity,1))!important}.text-bg-light{color:#fff!important;background-color:RGBA(173,181,189,var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(48,48,48,var(--bs-bg-opacity,1))!important}.link-primary{color:#375a7f!important}.link-primary:focus,.link-primary:hover{color:#2c4866!important}.link-secondary{color:#444!important}.link-secondary:focus,.link-secondary:hover{color:#363636!important}.link-success{color:#00bc8c!important}.link-success:focus,.link-success:hover{color:#009670!important}.link-info{color:#3498db!important}.link-info:focus,.link-info:hover{color:#2a7aaf!important}.link-warning{color:#f39c12!important}.link-warning:focus,.link-warning:hover{color:#c27d0e!important}.link-danger{color:#e74c3c!important}.link-danger:focus,.link-danger:hover{color:#b93d30!important}.link-light{color:#adb5bd!important}.link-light:focus,.link-light:hover{color:#8a9197!important}.link-dark{color:#303030!important}.link-dark:focus,.link-dark:hover{color:#262626!important}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-1{--bs-border-width:1px}.border-2{--bs-border-width:2px}.border-3{--bs-border-width:3px}.border-4{--bs-border-width:4px}.border-5{--bs-border-width:5px}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.425rem + 2.1vw)!important}.fs-2{font-size:calc(1.375rem + 1.5vw)!important}.fs-3{font-size:calc(1.325rem + .9vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-light{font-weight:300!important}.fw-lighter{font-weight:lighter!important}.fw-normal{font-weight:400!important}.fw-bold{font-weight:700!important}.fw-semibold{font-weight:600!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:#888!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-2xl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:3rem!important}.fs-2{font-size:2.5rem!important}.fs-3{font-size:2rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}}.blockquote-footer{color:#888}.input-group-addon{color:#fff}.form-floating>label{color:#444}.nav-pills .nav-item.open .nav-link,.nav-pills .nav-item.open .nav-link:focus,.nav-pills .nav-item.open .nav-link:hover,.nav-pills .nav-link,.nav-pills .nav-link.active,.nav-pills .nav-link.active:focus,.nav-pills .nav-link.active:hover,.nav-tabs .nav-item.open .nav-link,.nav-tabs .nav-item.open .nav-link:focus,.nav-tabs .nav-item.open .nav-link:hover,.nav-tabs .nav-link,.nav-tabs .nav-link.active,.nav-tabs .nav-link.active:focus,.nav-tabs .nav-link.active:hover{color:#fff}.breadcrumb a{color:#fff}.pagination a:hover{text-decoration:none}.alert{color:#fff;border:none}.alert .alert-link,.alert a{color:#fff;text-decoration:underline}.alert-primary{background-color:#375a7f}.alert-secondary{background-color:#444}.alert-success{background-color:#00bc8c}.alert-info{background-color:#3498db}.alert-warning{background-color:#f39c12}.alert-danger{background-color:#e74c3c}.alert-light{background-color:#adb5bd}.alert-dark{background-color:#303030} \ No newline at end of file + */@import url(https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap);:root{--bs-blue:#375a7f;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#e83e8c;--bs-red:#e74c3c;--bs-orange:#fd7e14;--bs-yellow:#f39c12;--bs-green:#00bc8c;--bs-teal:#20c997;--bs-cyan:#3498db;--bs-black:#000;--bs-white:#fff;--bs-gray:#888;--bs-gray-dark:#303030;--bs-gray-100:#f8f9fa;--bs-gray-200:#ebebeb;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#888;--bs-gray-700:#444;--bs-gray-800:#303030;--bs-gray-900:#222;--bs-primary:#375a7f;--bs-secondary:#444;--bs-success:#00bc8c;--bs-info:#3498db;--bs-warning:#f39c12;--bs-danger:#e74c3c;--bs-light:#adb5bd;--bs-dark:#303030;--bs-primary-rgb:55,90,127;--bs-secondary-rgb:68,68,68;--bs-success-rgb:0,188,140;--bs-info-rgb:52,152,219;--bs-warning-rgb:243,156,18;--bs-danger-rgb:231,76,60;--bs-light-rgb:173,181,189;--bs-dark-rgb:48,48,48;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:255,255,255;--bs-body-bg-rgb:34,34,34;--bs-font-sans-serif:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#fff;--bs-body-bg:#222;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#00bc8c;--bs-link-hover-color:#009670;--bs-code-color:#e83e8c;--bs-highlight-bg:#fdebd0}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:1px solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:calc(1.425rem + 2.1vw)}@media (min-width:1200px){.h1,h1{font-size:3rem}}.h2,h2{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h2,h2{font-size:2.5rem}}.h3,h3{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h3,h3{font-size:2rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--bs-link-color);text-decoration:underline}a:hover{color:var(--bs-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em;color:inherit}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#888;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#888}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#222;border:1px solid var(--bs-border-color);border-radius:.375rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#888}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color:var(--bs-body-color);--bs-table-bg:transparent;--bs-table-border-color:#444;--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-body-color);--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:var(--bs-body-color);--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:var(--bs-body-color);--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:var(--bs-table-color);vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:2px solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-striped-columns>:not(caption)>tr>:nth-child(even){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-color:#fff;--bs-table-bg:#375a7f;--bs-table-border-color:#4b6b8c;--bs-table-striped-bg:#416285;--bs-table-striped-color:#fff;--bs-table-active-bg:#4b6b8c;--bs-table-active-color:#fff;--bs-table-hover-bg:#466689;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#fff;--bs-table-bg:#444444;--bs-table-border-color:#575757;--bs-table-striped-bg:#4d4d4d;--bs-table-striped-color:#fff;--bs-table-active-bg:#575757;--bs-table-active-color:#fff;--bs-table-hover-bg:#525252;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#fff;--bs-table-bg:#00bc8c;--bs-table-border-color:#1ac398;--bs-table-striped-bg:#0dbf92;--bs-table-striped-color:#fff;--bs-table-active-bg:#1ac398;--bs-table-active-color:#fff;--bs-table-hover-bg:#13c195;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#fff;--bs-table-bg:#3498db;--bs-table-border-color:#48a2df;--bs-table-striped-bg:#3e9ddd;--bs-table-striped-color:#fff;--bs-table-active-bg:#48a2df;--bs-table-active-color:#fff;--bs-table-hover-bg:#43a0de;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#fff;--bs-table-bg:#f39c12;--bs-table-border-color:#f4a62a;--bs-table-striped-bg:#f4a11e;--bs-table-striped-color:#fff;--bs-table-active-bg:#f4a62a;--bs-table-active-color:#fff;--bs-table-hover-bg:#f4a324;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#fff;--bs-table-bg:#e74c3c;--bs-table-border-color:#e95e50;--bs-table-striped-bg:#e85546;--bs-table-striped-color:#fff;--bs-table-active-bg:#e95e50;--bs-table-active-color:#fff;--bs-table-hover-bg:#e9594b;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#fff;--bs-table-bg:#adb5bd;--bs-table-border-color:#b5bcc4;--bs-table-striped-bg:#b1b9c0;--bs-table-striped-color:#fff;--bs-table-active-bg:#b5bcc4;--bs-table-active-color:#fff;--bs-table-hover-bg:#b3bbc2;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#303030;--bs-table-border-color:#454545;--bs-table-striped-bg:#3a3a3a;--bs-table-striped-color:#fff;--bs-table-active-bg:#454545;--bs-table-active-color:#fff;--bs-table-hover-bg:#404040;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:#888}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#303030;background-color:#fff;background-clip:padding-box;border:1px solid #222;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#303030;background-color:#fff;border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-moz-placeholder{color:#888;opacity:1}.form-control::placeholder{color:#888;opacity:1}.form-control:disabled{background-color:#ebebeb;opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#fff;background-color:#444;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#fff;background-color:#444;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#414141}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#414141}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#fff;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{width:3rem;height:calc(1.5em + .75rem + 2px);padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:.375rem}.form-control-color::-webkit-color-swatch{border-radius:.375rem}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + 2px)}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + 2px)}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:#303030;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #222;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#ebebeb}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #303030}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:.25rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:.5rem}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-check-input:checked{background-color:#375a7f;border-color:#375a7f}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#375a7f;border-color:#375a7f;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%239badbf'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #222,0 0 0 .25rem rgba(55,90,127,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #222,0 0 0 .25rem rgba(55,90,127,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#375a7f;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#c3ced9}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#375a7f;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#c3ced9}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;width:100%;height:100%;padding:1rem .75rem;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::-moz-placeholder,.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown),.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:1px 0}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#adb5bd;text-align:center;white-space:nowrap;background-color:#444;border:1px solid #222;border-radius:.375rem}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#00bc8c}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(0,188,140,.9);border-radius:.375rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#00bc8c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#00bc8c}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#00bc8c}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#00bc8c}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#00bc8c}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#e74c3c}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(231,76,60,.9);border-radius:.375rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#e74c3c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#e74c3c}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#e74c3c}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#e74c3c}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#e74c3c}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#fff;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:first-child:hover,:not(.btn-check)+.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#375a7f;--bs-btn-border-color:#375a7f;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#2f4d6c;--bs-btn-hover-border-color:#2c4866;--bs-btn-focus-shadow-rgb:85,115,146;--bs-btn-active-color:#fff;--bs-btn-active-bg:#2c4866;--bs-btn-active-border-color:#29445f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#375a7f;--bs-btn-disabled-border-color:#375a7f}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#444;--bs-btn-border-color:#444;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#3a3a3a;--bs-btn-hover-border-color:#363636;--bs-btn-focus-shadow-rgb:96,96,96;--bs-btn-active-color:#fff;--bs-btn-active-bg:#363636;--bs-btn-active-border-color:#333333;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#444;--bs-btn-disabled-border-color:#444}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#00bc8c;--bs-btn-border-color:#00bc8c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#00a077;--bs-btn-hover-border-color:#009670;--bs-btn-focus-shadow-rgb:38,198,157;--bs-btn-active-color:#fff;--bs-btn-active-bg:#009670;--bs-btn-active-border-color:#008d69;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#00bc8c;--bs-btn-disabled-border-color:#00bc8c}.btn-info{--bs-btn-color:#fff;--bs-btn-bg:#3498db;--bs-btn-border-color:#3498db;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#2c81ba;--bs-btn-hover-border-color:#2a7aaf;--bs-btn-focus-shadow-rgb:82,167,224;--bs-btn-active-color:#fff;--bs-btn-active-bg:#2a7aaf;--bs-btn-active-border-color:#2772a4;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#3498db;--bs-btn-disabled-border-color:#3498db}.btn-warning{--bs-btn-color:#fff;--bs-btn-bg:#f39c12;--bs-btn-border-color:#f39c12;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#cf850f;--bs-btn-hover-border-color:#c27d0e;--bs-btn-focus-shadow-rgb:245,171,54;--bs-btn-active-color:#fff;--bs-btn-active-bg:#c27d0e;--bs-btn-active-border-color:#b6750e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#f39c12;--bs-btn-disabled-border-color:#f39c12}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#e74c3c;--bs-btn-border-color:#e74c3c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#c44133;--bs-btn-hover-border-color:#b93d30;--bs-btn-focus-shadow-rgb:235,103,89;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b93d30;--bs-btn-active-border-color:#ad392d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#e74c3c;--bs-btn-disabled-border-color:#e74c3c}.btn-light{--bs-btn-color:#fff;--bs-btn-bg:#adb5bd;--bs-btn-border-color:#adb5bd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#939aa1;--bs-btn-hover-border-color:#8a9197;--bs-btn-focus-shadow-rgb:185,192,199;--bs-btn-active-color:#fff;--bs-btn-active-bg:#8a9197;--bs-btn-active-border-color:#82888e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#adb5bd;--bs-btn-disabled-border-color:#adb5bd}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#303030;--bs-btn-border-color:#303030;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#4f4f4f;--bs-btn-hover-border-color:#454545;--bs-btn-focus-shadow-rgb:79,79,79;--bs-btn-active-color:#fff;--bs-btn-active-bg:#595959;--bs-btn-active-border-color:#454545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#303030;--bs-btn-disabled-border-color:#303030}.btn-outline-primary{--bs-btn-color:#375a7f;--bs-btn-border-color:#375a7f;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#375a7f;--bs-btn-hover-border-color:#375a7f;--bs-btn-focus-shadow-rgb:55,90,127;--bs-btn-active-color:#fff;--bs-btn-active-bg:#375a7f;--bs-btn-active-border-color:#375a7f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#375a7f;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#375a7f;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#444;--bs-btn-border-color:#444;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#444;--bs-btn-hover-border-color:#444;--bs-btn-focus-shadow-rgb:68,68,68;--bs-btn-active-color:#fff;--bs-btn-active-bg:#444;--bs-btn-active-border-color:#444;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#444;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#444;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#00bc8c;--bs-btn-border-color:#00bc8c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#00bc8c;--bs-btn-hover-border-color:#00bc8c;--bs-btn-focus-shadow-rgb:0,188,140;--bs-btn-active-color:#fff;--bs-btn-active-bg:#00bc8c;--bs-btn-active-border-color:#00bc8c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#00bc8c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#00bc8c;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#3498db;--bs-btn-border-color:#3498db;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#3498db;--bs-btn-hover-border-color:#3498db;--bs-btn-focus-shadow-rgb:52,152,219;--bs-btn-active-color:#fff;--bs-btn-active-bg:#3498db;--bs-btn-active-border-color:#3498db;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#3498db;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#3498db;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#f39c12;--bs-btn-border-color:#f39c12;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#f39c12;--bs-btn-hover-border-color:#f39c12;--bs-btn-focus-shadow-rgb:243,156,18;--bs-btn-active-color:#fff;--bs-btn-active-bg:#f39c12;--bs-btn-active-border-color:#f39c12;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f39c12;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f39c12;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#e74c3c;--bs-btn-border-color:#e74c3c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#e74c3c;--bs-btn-hover-border-color:#e74c3c;--bs-btn-focus-shadow-rgb:231,76,60;--bs-btn-active-color:#fff;--bs-btn-active-bg:#e74c3c;--bs-btn-active-border-color:#e74c3c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#e74c3c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#e74c3c;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#adb5bd;--bs-btn-border-color:#adb5bd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#adb5bd;--bs-btn-hover-border-color:#adb5bd;--bs-btn-focus-shadow-rgb:173,181,189;--bs-btn-active-color:#fff;--bs-btn-active-bg:#adb5bd;--bs-btn-active-border-color:#adb5bd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#adb5bd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#adb5bd;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#303030;--bs-btn-border-color:#303030;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#303030;--bs-btn-hover-border-color:#303030;--bs-btn-focus-shadow-rgb:48,48,48;--bs-btn-active-color:#fff;--bs-btn-active-bg:#303030;--bs-btn-active-border-color:#303030;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#303030;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#303030;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#888;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:85,115,146;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:0.5rem}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:0.25rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:#fff;--bs-dropdown-bg:#222;--bs-dropdown-border-color:#444;--bs-dropdown-border-radius:0.375rem;--bs-dropdown-border-width:1px;--bs-dropdown-inner-border-radius:calc(0.375rem - 1px);--bs-dropdown-divider-bg:#444;--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-dropdown-link-color:#fff;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-link-hover-bg:#375a7f;--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#375a7f;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#888;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#303030;--bs-dropdown-border-color:#444;--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:#444;--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#375a7f;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:.375rem}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:2rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#adb5bd;display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#444;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#444 #444 transparent;--bs-nav-tabs-link-active-color:#fff;--bs-nav-tabs-link-active-bg:#222;--bs-nav-tabs-link-active-border-color:#444 #444 transparent;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:0.375rem;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#375a7f}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:1rem;--bs-navbar-color:rgba(34, 34, 34, 0.7);--bs-navbar-hover-color:#222;--bs-navbar-disabled-color:rgba(0, 0, 0, 0.3);--bs-navbar-active-color:#222;--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:#222;--bs-navbar-brand-hover-color:#222;--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2834, 34, 34, 0.7%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(34, 34, 34, 0.1);--bs-navbar-toggler-border-radius:0.375rem;--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .show>.nav-link{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark{--bs-navbar-color:rgba(255, 255, 255, 0.6);--bs-navbar-hover-color:#fff;--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.6%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-border-width:1px;--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:0.375rem;--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(0.375rem - 1px);--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:#444;--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:#303030;--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:#222;--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:1px;--bs-accordion-border-radius:0.375rem;--bs-accordion-inner-border-radius:calc(0.375rem - 1px);--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='var%28--bs-body-color%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23325172'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-focus-border-color:#9badbf;--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(55, 90, 127, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:#325172;--bs-accordion-active-bg:#ebeff2}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:var(--bs-accordion-btn-focus-border-color);outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button,.accordion-flush .accordion-item .accordion-button.collapsed{border-radius:0}.breadcrumb{--bs-breadcrumb-padding-x:0.75rem;--bs-breadcrumb-padding-y:0.375rem;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg:#444;--bs-breadcrumb-border-radius:0.25rem;--bs-breadcrumb-divider-color:#888;--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:#888;display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:#fff;--bs-pagination-bg:#00bc8c;--bs-pagination-border-width:0;--bs-pagination-border-color:transparent;--bs-pagination-border-radius:0.375rem;--bs-pagination-hover-color:#fff;--bs-pagination-hover-bg:#00efb2;--bs-pagination-hover-border-color:transparent;--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:#ebebeb;--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(55, 90, 127, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#00efb2;--bs-pagination-active-border-color:transparent;--bs-pagination-disabled-color:#fff;--bs-pagination-disabled-bg:#007053;--bs-pagination-disabled-border-color:transparent;display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:0.5rem}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:0.25rem}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:0.375rem;display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:1px solid var(--bs-alert-border-color);--bs-alert-border-radius:0.375rem;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:#21364c;--bs-alert-bg:#d7dee5;--bs-alert-border-color:#c3ced9}.alert-primary .alert-link{color:#1a2b3d}.alert-secondary{--bs-alert-color:#292929;--bs-alert-bg:#dadada;--bs-alert-border-color:#c7c7c7}.alert-secondary .alert-link{color:#212121}.alert-success{--bs-alert-color:#007154;--bs-alert-bg:#ccf2e8;--bs-alert-border-color:#b3ebdd}.alert-success .alert-link{color:#005a43}.alert-info{--bs-alert-color:#1f5b83;--bs-alert-bg:#d6eaf8;--bs-alert-border-color:#c2e0f4}.alert-info .alert-link{color:#194969}.alert-warning{--bs-alert-color:#925e0b;--bs-alert-bg:#fdebd0;--bs-alert-border-color:#fbe1b8}.alert-warning .alert-link{color:#754b09}.alert-danger{--bs-alert-color:#8b2e24;--bs-alert-bg:#fadbd8;--bs-alert-border-color:#f8c9c5}.alert-danger .alert-link{color:#6f251d}.alert-light{--bs-alert-color:#686d71;--bs-alert-bg:#eff0f2;--bs-alert-border-color:#e6e9eb}.alert-light .alert-link{color:#53575a}.alert-dark{--bs-alert-color:#1d1d1d;--bs-alert-bg:#d6d6d6;--bs-alert-border-color:#c1c1c1}.alert-dark .alert-link{color:#171717}@-webkit-keyframes progress-bar-stripes{0%{background-position-x:1rem}}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:#444;--bs-progress-border-radius:0.375rem;--bs-progress-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#375a7f;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.list-group{--bs-list-group-color:#fff;--bs-list-group-bg:#303030;--bs-list-group-border-color:#444;--bs-list-group-border-width:1px;--bs-list-group-border-radius:0.375rem;--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:#444;--bs-list-group-action-hover-color:#fff;--bs-list-group-action-hover-bg:#444;--bs-list-group-action-active-color:#fff;--bs-list-group-action-active-bg:#222;--bs-list-group-disabled-color:#888;--bs-list-group-disabled-bg:#303030;--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#375a7f;--bs-list-group-active-border-color:#375a7f;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#21364c;background-color:#d7dee5}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#21364c;background-color:#c2c8ce}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#21364c;border-color:#21364c}.list-group-item-secondary{color:#292929;background-color:#dadada}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#292929;background-color:#c4c4c4}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#292929;border-color:#292929}.list-group-item-success{color:#007154;background-color:#ccf2e8}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#007154;background-color:#b8dad1}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#007154;border-color:#007154}.list-group-item-info{color:#1f5b83;background-color:#d6eaf8}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#1f5b83;background-color:#c1d3df}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#1f5b83;border-color:#1f5b83}.list-group-item-warning{color:#925e0b;background-color:#fdebd0}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#925e0b;background-color:#e4d4bb}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#925e0b;border-color:#925e0b}.list-group-item-danger{color:#8b2e24;background-color:#fadbd8}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#8b2e24;background-color:#e1c5c2}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#8b2e24;border-color:#8b2e24}.list-group-item-light{color:#686d71;background-color:#eff0f2}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#686d71;background-color:#d7d8da}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#686d71;border-color:#686d71}.list-group-item-dark{color:#1d1d1d;background-color:#d6d6d6}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1d1d1d;background-color:#c1c1c1}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1d1d1d;border-color:#1d1d1d}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#fff;background:transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.375rem;opacity:.4}.btn-close:hover{color:#fff;text-decoration:none;opacity:1}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25);opacity:1}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:#444;--bs-toast-border-width:1px;--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:0.375rem;--bs-toast-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-toast-header-color:#888;--bs-toast-header-bg:#303030;--bs-toast-header-border-color:rgba(0, 0, 0, 0.05);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{position:absolute;z-index:var(--bs-toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:#303030;--bs-modal-border-color:#444;--bs-modal-border-width:1px;--bs-modal-border-radius:0.5rem;--bs-modal-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-modal-inner-border-radius:calc(0.5rem - 1px);--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:#444;--bs-modal-header-border-width:1px;--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:#444;--bs-modal-footer-border-width:1px;position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin:calc(-.5 * var(--bs-modal-header-padding-y)) calc(-.5 * var(--bs-modal-header-padding-x)) calc(-.5 * var(--bs-modal-header-padding-y)) auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:#fff;--bs-tooltip-bg:#000;--bs-tooltip-border-radius:0.375rem;--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;padding:var(--bs-tooltip-arrow-height);margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:#303030;--bs-popover-border-width:1px;--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:0.5rem;--bs-popover-inner-border-radius:calc(0.5rem - 1px);--bs-popover-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color: ;--bs-popover-header-bg:#444;--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:#fff;--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;-webkit-animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name);animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@-webkit-keyframes spinner-border{to{transform:rotate(360deg)}}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color: ;--bs-offcanvas-bg:#303030;--bs-offcanvas-border-width:1px;--bs-offcanvas-border-color:#444;--bs-offcanvas-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075)}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:575.98px){.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}}@media (max-width:575.98px){.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:767.98px){.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}}@media (max-width:767.98px){.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:991.98px){.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}}@media (max-width:991.98px){.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1199.98px){.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}}@media (max-width:1199.98px){.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}}@media (max-width:1399.98px){.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin-top:calc(-.5 * var(--bs-offcanvas-padding-y));margin-right:calc(-.5 * var(--bs-offcanvas-padding-x));margin-bottom:calc(-.5 * var(--bs-offcanvas-padding-y))}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{-webkit-animation:placeholder-glow 2s ease-in-out infinite;animation:placeholder-glow 2s ease-in-out infinite}@-webkit-keyframes placeholder-glow{50%{opacity:.2}}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;-webkit-animation:placeholder-wave 2s linear infinite;animation:placeholder-wave 2s linear infinite}@-webkit-keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(55,90,127,var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(68,68,68,var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(0,188,140,var(--bs-bg-opacity,1))!important}.text-bg-info{color:#fff!important;background-color:RGBA(52,152,219,var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#fff!important;background-color:RGBA(243,156,18,var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(231,76,60,var(--bs-bg-opacity,1))!important}.text-bg-light{color:#fff!important;background-color:RGBA(173,181,189,var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(48,48,48,var(--bs-bg-opacity,1))!important}.link-primary{color:#375a7f!important}.link-primary:focus,.link-primary:hover{color:#2c4866!important}.link-secondary{color:#444!important}.link-secondary:focus,.link-secondary:hover{color:#363636!important}.link-success{color:#00bc8c!important}.link-success:focus,.link-success:hover{color:#009670!important}.link-info{color:#3498db!important}.link-info:focus,.link-info:hover{color:#2a7aaf!important}.link-warning{color:#f39c12!important}.link-warning:focus,.link-warning:hover{color:#c27d0e!important}.link-danger{color:#e74c3c!important}.link-danger:focus,.link-danger:hover{color:#b93d30!important}.link-light{color:#adb5bd!important}.link-light:focus,.link-light:hover{color:#8a9197!important}.link-dark{color:#303030!important}.link-dark:focus,.link-dark:hover{color:#262626!important}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-1{--bs-border-width:1px}.border-2{--bs-border-width:2px}.border-3{--bs-border-width:3px}.border-4{--bs-border-width:4px}.border-5{--bs-border-width:5px}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.425rem + 2.1vw)!important}.fs-2{font-size:calc(1.375rem + 1.5vw)!important}.fs-3{font-size:calc(1.325rem + .9vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-light{font-weight:300!important}.fw-lighter{font-weight:lighter!important}.fw-normal{font-weight:400!important}.fw-bold{font-weight:700!important}.fw-semibold{font-weight:600!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:#888!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-2xl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:3rem!important}.fs-2{font-size:2.5rem!important}.fs-3{font-size:2rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}}:root{color-scheme:dark}.blockquote-footer{color:#888}.input-group-addon{color:#fff}.form-floating>label{color:#444}.nav-pills .nav-item.open .nav-link,.nav-pills .nav-item.open .nav-link:focus,.nav-pills .nav-item.open .nav-link:hover,.nav-pills .nav-link,.nav-pills .nav-link.active,.nav-pills .nav-link.active:focus,.nav-pills .nav-link.active:hover,.nav-tabs .nav-item.open .nav-link,.nav-tabs .nav-item.open .nav-link:focus,.nav-tabs .nav-item.open .nav-link:hover,.nav-tabs .nav-link,.nav-tabs .nav-link.active,.nav-tabs .nav-link.active:focus,.nav-tabs .nav-link.active:hover{color:#fff}.breadcrumb a{color:#fff}.pagination a:hover{text-decoration:none}.alert{color:#fff;border:none}.alert .alert-link,.alert a{color:#fff;text-decoration:underline}.alert-primary{background-color:#375a7f}.alert-secondary{background-color:#444}.alert-success{background-color:#00bc8c}.alert-info{background-color:#3498db}.alert-warning{background-color:#f39c12}.alert-danger{background-color:#e74c3c}.alert-light{background-color:#adb5bd}.alert-dark{background-color:#303030} \ No newline at end of file From 805d4c8170e4c488e387eee09a887d4afc7f36bd Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 18 Sep 2022 17:35:38 +0200 Subject: [PATCH 520/629] pottering about with making a docker-compose plugin --- .../infra/docker-compose.gradle.kts | 6 +- .../kafkatorio/task/DockerComposeExec.kt | 6 +- .../docker-compose/build.gradle.kts | 36 ++++++++++ .../docker-compose/settings.gradle.kts | 18 +++++ .../kotlin/dev/adamko/geedeecee/GDCPlugin.kt | 48 +++++++++++++ .../dev/adamko/geedeecee/GDCSettings.kt | 68 +++++++++++++++++++ settings.gradle.kts | 1 + 7 files changed, 177 insertions(+), 6 deletions(-) create mode 100644 gradle-plugins/docker-compose/build.gradle.kts create mode 100644 gradle-plugins/docker-compose/settings.gradle.kts create mode 100644 gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt create mode 100644 gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCSettings.kt diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts index 261b2fa..58819be 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts @@ -45,10 +45,8 @@ val dockerRemove by tasks.registering(Exec::class) { } -afterEvaluate { - tasks.named("processRun") { dependsOn(dockerUp, dockerEnvUpdate) } - tasks.named("processKill") { dependsOn(dockerDown) } -} +tasks.matching { it.name == "processRun" }.configureEach { dependsOn(dockerUp, dockerEnvUpdate) } +tasks.matching { it.name == "processKill" }.configureEach { dependsOn(dockerDown) } val dockerEnvUpdate by tasks.registering(DockerEnvUpdateTask::class) { diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerComposeExec.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerComposeExec.kt index ba5fb76..1fc0ba4 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerComposeExec.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerComposeExec.kt @@ -23,6 +23,7 @@ import org.gradle.work.NormalizeLineEndings import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs @CacheableTask +@Suppress("UnstableApiUsage") abstract class DockerComposeExec @Inject constructor( private val executor: ExecOperations, private val objects: ObjectFactory, @@ -57,8 +58,9 @@ abstract class DockerComposeExec @Inject constructor( group = DOCKER_COMPOSE_GROUP logging.captureStandardOutput(LogLevel.LIFECYCLE) - super.onlyIf { - it is DockerComposeExec && it.dockerIsActive.getOrElse(false) + super.onlyIf { task -> + require(task is DockerComposeExec) + task.dockerIsActive.getOrElse(false) } } diff --git a/gradle-plugins/docker-compose/build.gradle.kts b/gradle-plugins/docker-compose/build.gradle.kts new file mode 100644 index 0000000..954b7f0 --- /dev/null +++ b/gradle-plugins/docker-compose/build.gradle.kts @@ -0,0 +1,36 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version embeddedKotlinVersion + `kotlin-dsl` + `java-gradle-plugin` +} + +val gradleJvmTarget = "11" + +dependencies { + implementation(platform(libs.kotlin.bom)) + implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable") +} + +kotlin { + jvmToolchain { + (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) + } +} + +tasks.withType().configureEach { + kotlinOptions { + jvmTarget = gradleJvmTarget + } +} + +gradlePlugin { + plugins { + create("geedeecee") { + id = "dev.adamko.geedeecee" + displayName = "geedeecee - Gradle Docker Compose" + implementationClass = "dev.adamko.geedeecee.GDCPlugin" + } + } +} diff --git a/gradle-plugins/docker-compose/settings.gradle.kts b/gradle-plugins/docker-compose/settings.gradle.kts new file mode 100644 index 0000000..f0000bc --- /dev/null +++ b/gradle-plugins/docker-compose/settings.gradle.kts @@ -0,0 +1,18 @@ +rootProject.name = "docker-compose" + +pluginManagement { + @Suppress("UnstableApiUsage") + includeBuild("../settings-plugins/") +} + +plugins { + id("kafkatorio.convention.settings.repositories") +} + + dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../../gradle/libs.versions.toml")) + } + } +} diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt new file mode 100644 index 0000000..d6b0429 --- /dev/null +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt @@ -0,0 +1,48 @@ +package dev.adamko.geedeecee + +import javax.inject.Inject +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.file.ProjectLayout +import org.gradle.api.provider.ProviderFactory +import org.gradle.kotlin.dsl.create +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + + +abstract class GDCPlugin @Inject constructor( + private val providers: ProviderFactory, + private val layout: ProjectLayout, +) : Plugin { + + + override fun apply(target: Project) { + target.createSettings() + } + + + private fun Project.createSettings(): GDCSettings = + extensions.create(GDC_EXTENSION_NAME).apply { + composeProjectName.convention(providers.provider { project.name }) + srcDir.convention(layout.projectDirectory.dir("docker")) + + dotEnv.put("COMPOSE_PROJECT_NAME", composeProjectName) + dotEnv.put("PROJECT_VERSION", providers.provider { project.version.toString() }) + dotEnv.put("REGISTRY_HOST", providers.gradleProperty("dockerContainerRegistryHost")) + + enabled.convention( + providers.exec { + commandLine = parseSpaceSeparatedArgs("docker info") + isIgnoreExitValue = true + }.result.map { + it.exitValue == 0 + } + ) + } + + + companion object { + const val GDC_EXTENSION_NAME = "geedeecee" + const val GCD_TASK_GROUP = "docker-compose" + } + +} diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCSettings.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCSettings.kt new file mode 100644 index 0000000..64300f5 --- /dev/null +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCSettings.kt @@ -0,0 +1,68 @@ +package dev.adamko.geedeecee + +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.provider.MapProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal + +interface GDCSettings { + + @get:Input + val composeProjectName: Property + + @get:Internal + val srcDir: DirectoryProperty + + @get:Input + val dotEnv: MapProperty + + @get:Input + val enabled: Property + +// @Suppress("PropertyName", "FunctionName") +// abstract class DotEnv( +// private val dotEnv: MapProperty, +// private val providers: ProviderFactory, +// ) { +// var COMPOSE_API_VERSION: Provider by dotEnv +// fun COMPOSE_API_VERSION(value: () -> String) { +// COMPOSE_API_VERSION = providers.provider(value) +// } +// // var COMPOSE_CONVERT_WINDOWS_PATHS: String +//// var COMPOSE_FILE: String +//// var COMPOSE_HTTP_TIMEOUT: String +//// var COMPOSE_PROFILES: String +//// var COMPOSE_PROJECT_NAME: String +//// var COMPOSE_TLS_VERSION: String +//// var DOCKER_CERT_PATH: String +//// var DOCKER_HOST: String +//// var DOCKER_TLS_VERIFY: String +// fun setComposeApiVersion(composeApiVersion: String) {} +// fun setComposeConvertWindowsPaths(composeConvertWindowsPaths: String) {} +// fun setComposeFile(composeFile: String) {} +// fun setComposeHttpTimeout(composeHttpTimeout: String) {} +// fun setComposeProfiles(composeProfiles: String) {} +// fun setComposeProjectName(composeProjectName: String) {} +// fun setComposeTlsVersion(composeTlsVersion: String) {} +// fun setDockerCertPath(dockerCertPath: String) {} +// fun setDockerHost(dockerHost: String) {} +// fun setDockerTlsVerify(dockerTlsVerify: String) {} +// } + +} +// +//private operator fun > MapProperty.setValue( +// dotEnv: GDCSettings.DotEnv, +// property: KProperty<*>, +// v: PV +//) { +// put(property.name, v) +//} +// +//private operator fun MapProperty.getValue( +// dotEnv: GDCSettings.DotEnv, +// property: KProperty<*> +//): Provider { +// return getting(property.name) +//} diff --git a/settings.gradle.kts b/settings.gradle.kts index e16d58a..879a691 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -8,6 +8,7 @@ pluginManagement { includeBuild("./gradle-plugins/builder-plugins/") +includeBuild("./gradle-plugins/docker-compose/") includeBuild("./gradle-plugins/factorio-mod-manager/") From f12a505d22141dd533ee7664a738b8d60a24563d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 18 Sep 2022 20:49:32 +0200 Subject: [PATCH 521/629] migrate buildSrc plugins to includedBuild plugins --- .gitignore | 3 ++ build.gradle.kts | 3 +- buildSrc/build.gradle.kts | 4 +- .../builder-plugins/build.gradle.kts | 29 ++++++++++++ .../builder-plugins/settings.gradle.kts | 8 ++++ .../kafkatorio/conventions}/base.gradle.kts | 2 +- .../kotlin/kafkatorio/conventions}/common.kt | 2 +- .../infra/docker-compose.gradle.kts | 9 ++-- .../infra/process-runner.gradle.kts | 7 ++- .../conventions}/lang/kotlin-js.gradle.kts | 6 +-- .../conventions}/lang/kotlin-jvm.gradle.kts | 4 +- .../lang/kotlin-multiplatform.gradle.kts | 6 +-- .../conventions}/lang/node.gradle.kts | 8 ++-- .../distributions}/artifactDistributions.kt | 2 +- .../kotlin/kafkatorio/extensions/gradle.kt | 2 +- .../kafkatorio/tasks}/DockerComposeExec.kt | 4 +- .../kafkatorio/tasks}/DockerEnvUpdateTask.kt | 4 +- .../tasks}/GenerateTypeScriptTask.kt | 2 +- .../tasks}/JsonPropertiesUpToDateSpec.kt | 6 +-- .../tasks}/KafkaConsumerGroupsTask.kt | 4 +- .../kafkatorio/tasks}/ProcessRunningSpec.kt | 3 +- .../kafkatorio/tasks}/TypescriptToLuaTask.kt | 2 +- .../kafkatorio/tasks}/UpdatePackageJson.kt | 4 +- .../docker-compose/settings.gradle.kts | 2 +- .../factorio-mod-manager/build.gradle.kts | 27 +++++++++++ .../factorio-mod-manager/settings.gradle.kts | 8 ++++ modules/events-library/build.gradle.kts | 8 ++-- modules/events-mod/build.gradle.kts | 12 ++--- .../events-processor-core/build.gradle.kts | 2 +- modules/events-processors/build.gradle.kts | 2 +- modules/events-server-syslog/build.gradle.kts | 2 +- modules/events-server-web/build.gradle.kts | 2 +- modules/events-server/build.gradle.kts | 4 +- .../infra-factorio-client/build.gradle.kts | 10 ++-- .../infra-factorio-server/build.gradle.kts | 6 +-- modules/infra-kafka-cluster/build.gradle.kts | 2 +- modules/infra-kafka-pipe/build.gradle.kts | 4 +- modules/kt-rcon/build.gradle.kts | 2 +- modules/web-map/build.gradle.kts | 47 ++----------------- settings.gradle.kts | 7 ++- 40 files changed, 159 insertions(+), 112 deletions(-) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions}/base.gradle.kts (91%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions}/common.kt (96%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions}/infra/docker-compose.gradle.kts (84%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions}/infra/process-runner.gradle.kts (71%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions}/lang/kotlin-js.gradle.kts (93%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions}/lang/kotlin-jvm.gradle.kts (95%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions}/lang/kotlin-multiplatform.gradle.kts (87%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions}/lang/node.gradle.kts (91%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/distributions}/artifactDistributions.kt (97%) rename buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/extensions/gradle.kt (99%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks}/DockerComposeExec.kt (96%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks}/DockerEnvUpdateTask.kt (86%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks}/GenerateTypeScriptTask.kt (95%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks}/JsonPropertiesUpToDateSpec.kt (88%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks}/KafkaConsumerGroupsTask.kt (96%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks}/ProcessRunningSpec.kt (94%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks}/TypescriptToLuaTask.kt (97%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task => gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks}/UpdatePackageJson.kt (98%) diff --git a/.gitignore b/.gitignore index fc1afcd..0ec58ab 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ .state/ +# Docker .env files are generated from a Gradle task +.env + .idea/ !.idea/icon.svg diff --git a/build.gradle.kts b/build.gradle.kts index 51241c3..078d29c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,9 +1,10 @@ -import dev.adamko.kafkatorio.gradle.excludeGeneratedGradleDsl import java.time.LocalDate +import kafkatorio.extensions.excludeGeneratedGradleDsl plugins { idea base + id("kafkatorio.conventions.base") // `project-report` // `build-dashboard` } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 4c2e332..b98a725 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -3,8 +3,8 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { idea `kotlin-dsl` - kotlin("jvm") version "1.6.21" - kotlin("plugin.serialization") version "1.6.21" + kotlin("jvm") version embeddedKotlinVersion + kotlin("plugin.serialization") version embeddedKotlinVersion } val gradleJvmTarget = "11" diff --git a/gradle-plugins/builder-plugins/build.gradle.kts b/gradle-plugins/builder-plugins/build.gradle.kts index cf30adb..0f6d586 100644 --- a/gradle-plugins/builder-plugins/build.gradle.kts +++ b/gradle-plugins/builder-plugins/build.gradle.kts @@ -5,6 +5,35 @@ plugins { kotlin("jvm") version embeddedKotlinVersion } +dependencies { + implementation(platform(libs.kotlin.bom)) + implementation("org.jetbrains.kotlin:kotlin-serialization") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${libs.versions.kotlin.get()}") + + implementation(platform(libs.kotlinx.coroutines.bom)) + implementation(libs.kotlinx.coroutines.core) + + implementation(platform(libs.kotlinxSerialization.bom)) + implementation(libs.kotlinxSerialization.core) + implementation(libs.kotlinxSerialization.json) + + implementation("com.github.node-gradle:gradle-node-plugin:${libs.versions.gradleNodePlugin.get()}") + + implementation(platform(libs.kotest.bom)) + implementation("io.kotest:kotest-framework-multiplatform-plugin-gradle") + + implementation("io.kvision:io.kvision.gradle.plugin:${libs.versions.kvision.get()}") + + implementation("net.swiftzer.semver:semver:${libs.versions.semver.get()}") + + implementation(platform(libs.okio.bom)) + implementation(libs.okio.core) + + implementation(libs.kotlinx.cli) +} + val gradleJvmTarget = "11" kotlin { diff --git a/gradle-plugins/builder-plugins/settings.gradle.kts b/gradle-plugins/builder-plugins/settings.gradle.kts index c5b5c98..fa59505 100644 --- a/gradle-plugins/builder-plugins/settings.gradle.kts +++ b/gradle-plugins/builder-plugins/settings.gradle.kts @@ -8,3 +8,11 @@ pluginManagement { plugins { id("kafkatorio.convention.settings.repositories") } + +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../../gradle/libs.versions.toml")) + } + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/base.gradle.kts similarity index 91% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/base.gradle.kts index 19385e5..1bd1049 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/base.gradle.kts @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio +package kafkatorio.conventions plugins { diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/common.kt similarity index 96% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/common.kt index 97a009a..7956955 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/common.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio +package kafkatorio.conventions import io.kvision.gradle.KVisionExtension import org.gradle.api.Project diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/infra/docker-compose.gradle.kts similarity index 84% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/infra/docker-compose.gradle.kts index 58819be..0de989b 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/infra/docker-compose.gradle.kts @@ -1,12 +1,12 @@ -package dev.adamko.kafkatorio.infra +package kafkatorio.conventions.infra -import dev.adamko.kafkatorio.gradle.DOCKER_COMPOSE_TASK_GROUP -import dev.adamko.kafkatorio.task.DockerEnvUpdateTask +import kafkatorio.tasks.DockerEnvUpdateTask +import kafkatorio.extensions.DOCKER_COMPOSE_TASK_GROUP import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { base - id("dev.adamko.kafkatorio.infra.process-runner") + id("kafkatorio.conventions.infra.process-runner") } @@ -55,6 +55,7 @@ val dockerEnvUpdate by tasks.registering(DockerEnvUpdateTask::class) { properties( "COMPOSE_PROJECT_NAME" to dockerComposeProjectName, "KAFKATORIO_VERSION" to project.version, + "REGISTRY_HOST" to providers.gradleProperty("dockerContainerRegistryHost"), ) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/process-runner.gradle.kts b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/infra/process-runner.gradle.kts similarity index 71% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/process-runner.gradle.kts rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/infra/process-runner.gradle.kts index 25d5231..5b5b04a 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/process-runner.gradle.kts +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/infra/process-runner.gradle.kts @@ -1,7 +1,10 @@ -package dev.adamko.kafkatorio.infra +package kafkatorio.conventions.infra + +import org.gradle.kotlin.dsl.extra +import org.gradle.kotlin.dsl.registering plugins { - id("dev.adamko.kafkatorio.base") + id("kafkatorio.conventions.base") } val processRunnerTaskGroup: String by extra("processes") diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/lang/kotlin-js.gradle.kts similarity index 93% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/lang/kotlin-js.gradle.kts index 4ff9e92..f84a3cb 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/lang/kotlin-js.gradle.kts @@ -1,7 +1,7 @@ -package dev.adamko.kafkatorio.lang +package kafkatorio.conventions.lang //import dev.adamko.kafkatorio.Versions -import dev.adamko.kafkatorio.relocateKotlinJsStore +import kafkatorio.conventions.relocateKotlinJsStore //import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension //import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin //import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject @@ -12,7 +12,7 @@ import dev.adamko.kafkatorio.relocateKotlinJsStore plugins { kotlin("js") - id("dev.adamko.kafkatorio.base") + id("kafkatorio.conventions.base") } //dependencies { diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/lang/kotlin-jvm.gradle.kts similarity index 95% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/lang/kotlin-jvm.gradle.kts index dbb4b66..1393be0 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/lang/kotlin-jvm.gradle.kts @@ -1,9 +1,9 @@ -package dev.adamko.kafkatorio.lang +package kafkatorio.conventions.lang import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - id("dev.adamko.kafkatorio.base") + id("kafkatorio.conventions.base") kotlin("jvm") } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/lang/kotlin-multiplatform.gradle.kts similarity index 87% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/lang/kotlin-multiplatform.gradle.kts index f9f0d11..3b90834 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-multiplatform.gradle.kts +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/lang/kotlin-multiplatform.gradle.kts @@ -1,13 +1,13 @@ -package dev.adamko.kafkatorio.lang +package kafkatorio.conventions.lang -import dev.adamko.kafkatorio.relocateKotlinJsStore +import kafkatorio.conventions.relocateKotlinJsStore //import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension //import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin //import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension plugins { - id("dev.adamko.kafkatorio.base") + id("kafkatorio.conventions.base") // id("dev.adamko.kafkatorio.lang.node") kotlin("multiplatform") // id("io.kotest.multiplatform") // disabled because of https://github.com/kotest/kotest/issues/3141 diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/lang/node.gradle.kts similarity index 91% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/lang/node.gradle.kts index 8e07427..f9128c8 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/lang/node.gradle.kts @@ -1,14 +1,14 @@ -package dev.adamko.kafkatorio.lang +package kafkatorio.conventions.lang import com.github.gradle.node.npm.task.NpmInstallTask -import dev.adamko.kafkatorio.Versions -import dev.adamko.kafkatorio.task.UpdatePackageJson +import kafkatorio.conventions.Versions +import kafkatorio.tasks.UpdatePackageJson import kotlinx.serialization.json.put plugins { id("com.github.node-gradle.node") - id("dev.adamko.kafkatorio.base") + id("kafkatorio.conventions.base") } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistributions.kt b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/distributions/artifactDistributions.kt similarity index 97% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistributions.kt rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/distributions/artifactDistributions.kt index b2f9beb..56ca202 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistributions.kt +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/distributions/artifactDistributions.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.gradle +package kafkatorio.distributions import org.gradle.api.artifacts.Configuration import org.gradle.api.attributes.Bundling diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/extensions/gradle.kt similarity index 99% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/extensions/gradle.kt index f3c0743..e6dc6bb 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/extensions/gradle.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.gradle +package kafkatorio.extensions import java.io.ByteArrayOutputStream import org.gradle.api.Project diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerComposeExec.kt b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/DockerComposeExec.kt similarity index 96% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerComposeExec.kt rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/DockerComposeExec.kt index 1fc0ba4..8bc28eb 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerComposeExec.kt +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/DockerComposeExec.kt @@ -1,6 +1,6 @@ -package dev.adamko.kafkatorio.task +package kafkatorio.tasks -import dev.adamko.kafkatorio.gradle.filesChecksum +import kafkatorio.extensions.filesChecksum import javax.inject.Inject import org.gradle.api.DefaultTask import org.gradle.api.file.DirectoryProperty diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerEnvUpdateTask.kt b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/DockerEnvUpdateTask.kt similarity index 86% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerEnvUpdateTask.kt rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/DockerEnvUpdateTask.kt index cda0978..a5a335f 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/DockerEnvUpdateTask.kt +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/DockerEnvUpdateTask.kt @@ -1,7 +1,7 @@ -package dev.adamko.kafkatorio.task +package kafkatorio.tasks -import dev.adamko.kafkatorio.gradle.DOCKER_COMPOSE_TASK_GROUP import javax.inject.Inject +import kafkatorio.extensions.DOCKER_COMPOSE_TASK_GROUP import org.gradle.api.file.RegularFileProperty import org.gradle.api.logging.LogLevel import org.gradle.api.model.ObjectFactory diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypeScriptTask.kt b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/GenerateTypeScriptTask.kt similarity index 95% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypeScriptTask.kt rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/GenerateTypeScriptTask.kt index 331275b..6cf739a 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypeScriptTask.kt +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/GenerateTypeScriptTask.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.task +package kafkatorio.tasks import javax.inject.Inject import org.gradle.api.file.DirectoryProperty diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/JsonPropertiesUpToDateSpec.kt similarity index 88% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/JsonPropertiesUpToDateSpec.kt index 8b61b06..271cced 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/JsonPropertiesUpToDateSpec.kt @@ -1,7 +1,7 @@ -package dev.adamko.kafkatorio.task +package kafkatorio.tasks -import dev.adamko.kafkatorio.task.UpdatePackageJson.Companion.foldParseToJsonObject -import dev.adamko.kafkatorio.task.UpdatePackageJson.Companion.parseToJsonObject +import kafkatorio.tasks.UpdatePackageJson.Companion.foldParseToJsonObject +import kafkatorio.tasks.UpdatePackageJson.Companion.parseToJsonObject import kotlinx.serialization.json.JsonObject import org.gradle.api.Task import org.gradle.api.internal.specs.ExplainingSpec diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/KafkaConsumerGroupsTask.kt b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/KafkaConsumerGroupsTask.kt similarity index 96% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/KafkaConsumerGroupsTask.kt rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/KafkaConsumerGroupsTask.kt index e9599f3..c4c88b4 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/KafkaConsumerGroupsTask.kt +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/KafkaConsumerGroupsTask.kt @@ -1,6 +1,6 @@ -package dev.adamko.kafkatorio.task +package kafkatorio.tasks -import dev.adamko.kafkatorio.gradle.execCapture +import kafkatorio.extensions.execCapture import org.gradle.api.DefaultTask import org.gradle.api.logging.LogLevel import org.gradle.api.tasks.Input diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/ProcessRunningSpec.kt similarity index 94% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/ProcessRunningSpec.kt index a677735..629c727 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/ProcessRunningSpec.kt @@ -1,7 +1,6 @@ -package dev.adamko.kafkatorio.task +package kafkatorio.tasks import java.io.ByteArrayOutputStream -import javax.inject.Inject import org.gradle.api.Task import org.gradle.api.internal.specs.ExplainingSpec import org.gradle.api.tasks.Exec diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/TypescriptToLuaTask.kt similarity index 97% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/TypescriptToLuaTask.kt index 0624185..d3c090d 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/TypescriptToLuaTask.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.task +package kafkatorio.tasks import com.github.gradle.node.npm.task.NpmTask import javax.inject.Inject diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/UpdatePackageJson.kt similarity index 98% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/UpdatePackageJson.kt index 5674046..bcbd523 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/UpdatePackageJson.kt @@ -1,7 +1,7 @@ -package dev.adamko.kafkatorio.task +package kafkatorio.tasks import com.github.gradle.node.NodePlugin -import dev.adamko.kafkatorio.* +import kafkatorio.* import java.io.File import javax.inject.Inject import kotlinx.serialization.encodeToString diff --git a/gradle-plugins/docker-compose/settings.gradle.kts b/gradle-plugins/docker-compose/settings.gradle.kts index f0000bc..c0f0cd1 100644 --- a/gradle-plugins/docker-compose/settings.gradle.kts +++ b/gradle-plugins/docker-compose/settings.gradle.kts @@ -9,7 +9,7 @@ plugins { id("kafkatorio.convention.settings.repositories") } - dependencyResolutionManagement { +dependencyResolutionManagement { versionCatalogs { create("libs") { from(files("../../gradle/libs.versions.toml")) diff --git a/gradle-plugins/factorio-mod-manager/build.gradle.kts b/gradle-plugins/factorio-mod-manager/build.gradle.kts index cf30adb..ae27420 100644 --- a/gradle-plugins/factorio-mod-manager/build.gradle.kts +++ b/gradle-plugins/factorio-mod-manager/build.gradle.kts @@ -5,6 +5,33 @@ plugins { kotlin("jvm") version embeddedKotlinVersion } +dependencies { + implementation(platform(libs.kotlin.bom)) + + implementation(platform(libs.kotlinx.coroutines.bom)) + implementation(libs.kotlinx.coroutines.core) + + implementation(platform(libs.kotlinxSerialization.bom)) + implementation(libs.kotlinxSerialization.core) + implementation(libs.kotlinxSerialization.json) + + implementation(platform(libs.okio.bom)) + implementation(libs.okio.core) + + implementation(libs.kotlinx.cli) + + implementation(platform(libs.ktor.bom)) + implementation(libs.ktorClient.auth) + implementation(libs.ktorClient.contentNegotiation) + implementation(libs.ktorClient.core) + implementation(libs.ktorClient.encoding) + implementation(libs.ktorClient.logging) + implementation(libs.ktorClient.cio) + implementation(libs.ktorClient.resources) + implementation(libs.ktorSerialization.kotlinxJson) +} + + val gradleJvmTarget = "11" kotlin { diff --git a/gradle-plugins/factorio-mod-manager/settings.gradle.kts b/gradle-plugins/factorio-mod-manager/settings.gradle.kts index d95228b..d6f8766 100644 --- a/gradle-plugins/factorio-mod-manager/settings.gradle.kts +++ b/gradle-plugins/factorio-mod-manager/settings.gradle.kts @@ -10,3 +10,11 @@ pluginManagement { plugins { id("kafkatorio.convention.settings.repositories") } + +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../../gradle/libs.versions.toml")) + } + } +} diff --git a/modules/events-library/build.gradle.kts b/modules/events-library/build.gradle.kts index 0c5f892..ac2a956 100644 --- a/modules/events-library/build.gradle.kts +++ b/modules/events-library/build.gradle.kts @@ -1,13 +1,13 @@ -import dev.adamko.kafkatorio.gradle.asProvider -import dev.adamko.kafkatorio.gradle.typescriptAttributes -import dev.adamko.kafkatorio.task.GenerateTypeScriptTask +import kafkatorio.distributions.asProvider +import kafkatorio.distributions.typescriptAttributes +import kafkatorio.tasks.GenerateTypeScriptTask import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - dev.adamko.kafkatorio.lang.`kotlin-multiplatform` + id("kafkatorio.conventions.lang.kotlin-multiplatform") kotlin("plugin.serialization") distribution } diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index c3398d7..faa546e 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -1,9 +1,9 @@ import dev.adamko.kafkatorio.factoriomod.portal.FactorioModPublishTask -import dev.adamko.kafkatorio.gradle.asConsumer -import dev.adamko.kafkatorio.gradle.asProvider -import dev.adamko.kafkatorio.gradle.factorioModAttributes -import dev.adamko.kafkatorio.gradle.typescriptAttributes -import dev.adamko.kafkatorio.task.TypescriptToLuaTask +import kafkatorio.distributions.asConsumer +import kafkatorio.distributions.asProvider +import kafkatorio.distributions.factorioModAttributes +import kafkatorio.distributions.typescriptAttributes +import kafkatorio.tasks.TypescriptToLuaTask import kotlinx.serialization.json.put import kotlinx.serialization.json.putJsonObject import net.swiftzer.semver.SemVer @@ -12,7 +12,7 @@ import org.gradle.plugins.ide.idea.model.Module as IdeaImlModule import org.gradle.plugins.ide.idea.model.Path as IdeaImlPath plugins { - dev.adamko.kafkatorio.lang.node + id("kafkatorio.conventions.lang.node") distribution } diff --git a/modules/events-processor-core/build.gradle.kts b/modules/events-processor-core/build.gradle.kts index f681852..3a2cab4 100644 --- a/modules/events-processor-core/build.gradle.kts +++ b/modules/events-processor-core/build.gradle.kts @@ -2,7 +2,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - dev.adamko.kafkatorio.lang.`kotlin-jvm` + id("kafkatorio.conventions.lang.kotlin-jvm") kotlin("plugin.serialization") // application } diff --git a/modules/events-processors/build.gradle.kts b/modules/events-processors/build.gradle.kts index 01ae8d4..3134526 100644 --- a/modules/events-processors/build.gradle.kts +++ b/modules/events-processors/build.gradle.kts @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - dev.adamko.kafkatorio.lang.`kotlin-jvm` + id("kafkatorio.conventions.lang.kotlin-jvm") kotlin("plugin.serialization") application } diff --git a/modules/events-server-syslog/build.gradle.kts b/modules/events-server-syslog/build.gradle.kts index d746d17..e46fa72 100644 --- a/modules/events-server-syslog/build.gradle.kts +++ b/modules/events-server-syslog/build.gradle.kts @@ -2,7 +2,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - dev.adamko.kafkatorio.lang.`kotlin-jvm` + id("kafkatorio.conventions.lang.kotlin-jvm") kotlin("plugin.serialization") application } diff --git a/modules/events-server-web/build.gradle.kts b/modules/events-server-web/build.gradle.kts index f65b0ae..d0ebc85 100644 --- a/modules/events-server-web/build.gradle.kts +++ b/modules/events-server-web/build.gradle.kts @@ -2,7 +2,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - dev.adamko.kafkatorio.lang.`kotlin-jvm` + id("kafkatorio.conventions.lang.kotlin-jvm") kotlin("plugin.serialization") application } diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index c865d61..32abda4 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -1,5 +1,5 @@ -import dev.adamko.kafkatorio.task.DockerEnvUpdateTask -import dev.adamko.kafkatorio.task.KafkaConsumerGroupsTask +import kafkatorio.tasks.DockerEnvUpdateTask +import kafkatorio.tasks.KafkaConsumerGroupsTask import org.jetbrains.kotlin.gradle.tasks.KotlinCompile diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index 4c694a9..622ba2b 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -1,13 +1,13 @@ import dev.adamko.kafkatorio.factoriomod.FactorioMod -import dev.adamko.kafkatorio.gradle.asConsumer -import dev.adamko.kafkatorio.gradle.factorioModAttributes -import dev.adamko.kafkatorio.gradle.not -import dev.adamko.kafkatorio.task.ProcessRunningSpec +import kafkatorio.distributions.asConsumer +import kafkatorio.distributions.factorioModAttributes +import kafkatorio.extensions.not +import kafkatorio.tasks.ProcessRunningSpec import org.gradle.kotlin.dsl.support.serviceOf import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { - dev.adamko.kafkatorio.infra.`process-runner` + id("kafkatorio.conventions.infra.process-runner") } description = "Start the Factorio game client" diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index a97e76b..d97aeab 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -1,10 +1,10 @@ import dev.adamko.kafkatorio.factoriomod.FactorioMod -import dev.adamko.kafkatorio.gradle.asConsumer -import dev.adamko.kafkatorio.gradle.factorioModAttributes +import kafkatorio.distributions.asConsumer +import kafkatorio.distributions.factorioModAttributes import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { - dev.adamko.kafkatorio.infra.`docker-compose` + id("kafkatorio.conventions.infra.docker-compose") } diff --git a/modules/infra-kafka-cluster/build.gradle.kts b/modules/infra-kafka-cluster/build.gradle.kts index e5f2040..f56f49f 100644 --- a/modules/infra-kafka-cluster/build.gradle.kts +++ b/modules/infra-kafka-cluster/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - dev.adamko.kafkatorio.infra.`docker-compose` + id("kafkatorio.conventions.infra.docker-compose") } description = "Kafka cluster" diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index 58301f1..4bfb356 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -1,7 +1,7 @@ -import dev.adamko.kafkatorio.task.DockerComposeExec +import kafkatorio.tasks.DockerComposeExec plugins { - dev.adamko.kafkatorio.infra.`docker-compose` + id("kafkatorio.conventions.infra.docker-compose") } description = "Send events from a Factorio server to a Kafka topic " diff --git a/modules/kt-rcon/build.gradle.kts b/modules/kt-rcon/build.gradle.kts index 375e7b6..c25f5b7 100644 --- a/modules/kt-rcon/build.gradle.kts +++ b/modules/kt-rcon/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - dev.adamko.kafkatorio.lang.`kotlin-jvm` + id("kafkatorio.conventions.lang.kotlin-jvm") } dependencies { diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index d82c67a..c83c02f 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -1,11 +1,10 @@ -import dev.adamko.kafkatorio.task.DockerEnvUpdateTask +import kafkatorio.tasks.DockerEnvUpdateTask import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig plugins { - dev.adamko.kafkatorio.lang.`kotlin-js` -// dev.adamko.kafkatorio.lang.`kotlin-multiplatform` + id("kafkatorio.conventions.lang.kotlin-js") id("io.kvision") kotlin("plugin.serialization") } @@ -35,9 +34,7 @@ kotlin { ), "/kafkatorio/ws" to mapOf( "target" to "ws://localhost:12080", -// "secure" to false, "ws" to true, -// "changeOrigin" to true, ), ), // static = mutableListOf("$buildDir/processedResources/frontend/main") @@ -53,15 +50,12 @@ kotlin { } } } -// compilations["main"].packageJson { -// this.devDependencies["webpack-dev-server"] = "4.9.1" -// } } sourceSets { - all { - languageSettings.apply { + configureEach { + languageSettings { optIn("kotlin.RequiresOptIn") optIn("kotlinx.serialization.ExperimentalSerializationApi") } @@ -93,18 +87,6 @@ kotlin { kvision("kvision-redux") kvision("kvision-state-flow") kvision("kvision-routing-navigo-ng") - -// implementation(devNpm("http-proxy-middleware", "^2.0.6")) -// implementation(dependencies.platform(devNpm("http-proxy-middleware", "^2.0.6"))) - -// implementation(dependencies.platform(npm("follow-redirects", "^1.14.8"))) -// implementation(dependencies.platform(npm("nanoid", "^3.1.31"))) -// implementation(dependencies.platform(npm("minimist", "^1.2.6"))) -// implementation(dependencies.platform(npm("async", "^2.6.4"))) -// implementation(dependencies.platform(npm("node-forge", "^1.3.0"))) -// implementation(dependencies.platform(npm("socket.io", "^4.5.1"))) -// implementation(dependencies.platform(devNpm("http-proxy-middleware", "^3.0.0-beta.0"))) -// implementation(dependencies.platform(devNpm("webpack-dev-server", "4.9.1"))) } resources.srcDir("src/main/web") @@ -133,21 +115,6 @@ fun KotlinDependencyHandler.kvision( implementation("io.kvision:$module:${version.get()}", configure) } -////// https://youtrack.jetbrains.com/issue/KT-42420 -//afterEvaluate { -// yarn { -//// resolution("mocha", "9.2.2") -//// resolution("follow-redirects", "1.14.8") -//// resolution("nanoid", "3.1.31") -//// resolution("minimist", "1.2.6") -//// resolution("async", "2.6.4") -//// resolution("node-forge", "1.3.0") -//// resolution("socket.io", "^4.5.1") -//// resolution("http-proxy-middleware", "^3.0.0-beta.0") -// resolution("webpack-dev-server", "4.9.1") -// } -//} - val dockerEnvUpdate by tasks.registering(DockerEnvUpdateTask::class) { dotEnvFile.set(layout.projectDirectory.file("docker/.env")) @@ -155,6 +122,7 @@ val dockerEnvUpdate by tasks.registering(DockerEnvUpdateTask::class) { properties( "COMPOSE_PROJECT_NAME" to rootProject.name, "KAFKATORIO_VERSION" to project.version, + "REGISTRY_HOST" to "dcr.adamko.dev:5000", ) } tasks.assemble { dependsOn(dockerEnvUpdate) } @@ -178,11 +146,6 @@ tasks.matching { it.name == "processResources" }.configureEach { } -tasks.withType().configureEach { - enabled = false -} - - val runWebMap by tasks.registering { group = rootProject.name diff --git a/settings.gradle.kts b/settings.gradle.kts index 879a691..4b7f0b3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -12,6 +12,11 @@ includeBuild("./gradle-plugins/docker-compose/") includeBuild("./gradle-plugins/factorio-mod-manager/") +plugins { + id("kafkatorio.convention.settings.repositories") +} + + include( ":modules:events-library", @@ -46,7 +51,7 @@ include( enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") -apply(from = "./buildSrc/repositories.settings.gradle.kts") +//apply(from = "./buildSrc/repositories.settings.gradle.kts") @Suppress("UnstableApiUsage") // Central declaration of repositories is an incubating feature From 42dab2021090eb180de6cf66122e57c4036b5675 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 18 Sep 2022 23:32:15 +0200 Subject: [PATCH 522/629] start setting up Factorio Gradle mod --- .../factorio_gradle/FactorioModPlugin.kt | 22 +++++++++++++++++++ .../factorio_gradle/FactorioModSettings.kt | 16 ++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/factorio_gradle/FactorioModPlugin.kt create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/factorio_gradle/FactorioModSettings.kt diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/factorio_gradle/FactorioModPlugin.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/factorio_gradle/FactorioModPlugin.kt new file mode 100644 index 0000000..c883d40 --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/factorio_gradle/FactorioModPlugin.kt @@ -0,0 +1,22 @@ +package dev.adamko.factorio_gradle + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.create + +abstract class FactorioModPlugin : Plugin { + + override fun apply(target: Project) { + target.createSettings() + } + + private fun Project.createSettings(): FactorioModSettings { + return extensions.create(FACTORIO_GRADLE_EXTENSION_NAME).apply { + + } + } + + companion object { + const val FACTORIO_GRADLE_EXTENSION_NAME = "factorio" + } +} diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/factorio_gradle/FactorioModSettings.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/factorio_gradle/FactorioModSettings.kt new file mode 100644 index 0000000..c43f697 --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/factorio_gradle/FactorioModSettings.kt @@ -0,0 +1,16 @@ +package dev.adamko.factorio_gradle + +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property + +interface FactorioModSettings { + + val factorioClientModsDirectory: DirectoryProperty + + val steamExe: RegularFileProperty + + val factorioGameSteamId: Property + + val factorioServerDataDirectory: DirectoryProperty +} From 81261512f1a42624d599196dff61d09dca0f0e0f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 18 Sep 2022 23:32:39 +0200 Subject: [PATCH 523/629] rename 'convention' package to 'conventions' --- gradle-plugins/builder-plugins/settings.gradle.kts | 2 +- gradle-plugins/docker-compose/settings.gradle.kts | 2 +- .../build.gradle.kts | 0 .../settings.gradle.kts | 2 +- .../{convention => conventions}/settings/repositories.kt | 0 .../settings/repositories.settings.gradle.kts | 2 +- settings.gradle.kts | 4 ++-- 7 files changed, 6 insertions(+), 6 deletions(-) rename gradle-plugins/{factorio-mod-manager => factorio-gradle}/build.gradle.kts (100%) rename gradle-plugins/{factorio-mod-manager => factorio-gradle}/settings.gradle.kts (85%) rename gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/{convention => conventions}/settings/repositories.kt (100%) rename gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/{convention => conventions}/settings/repositories.settings.gradle.kts (94%) diff --git a/gradle-plugins/builder-plugins/settings.gradle.kts b/gradle-plugins/builder-plugins/settings.gradle.kts index fa59505..039eed3 100644 --- a/gradle-plugins/builder-plugins/settings.gradle.kts +++ b/gradle-plugins/builder-plugins/settings.gradle.kts @@ -6,7 +6,7 @@ pluginManagement { } plugins { - id("kafkatorio.convention.settings.repositories") + id("kafkatorio.conventions.settings.repositories") } dependencyResolutionManagement { diff --git a/gradle-plugins/docker-compose/settings.gradle.kts b/gradle-plugins/docker-compose/settings.gradle.kts index c0f0cd1..2ebeaa3 100644 --- a/gradle-plugins/docker-compose/settings.gradle.kts +++ b/gradle-plugins/docker-compose/settings.gradle.kts @@ -6,7 +6,7 @@ pluginManagement { } plugins { - id("kafkatorio.convention.settings.repositories") + id("kafkatorio.conventions.settings.repositories") } dependencyResolutionManagement { diff --git a/gradle-plugins/factorio-mod-manager/build.gradle.kts b/gradle-plugins/factorio-gradle/build.gradle.kts similarity index 100% rename from gradle-plugins/factorio-mod-manager/build.gradle.kts rename to gradle-plugins/factorio-gradle/build.gradle.kts diff --git a/gradle-plugins/factorio-mod-manager/settings.gradle.kts b/gradle-plugins/factorio-gradle/settings.gradle.kts similarity index 85% rename from gradle-plugins/factorio-mod-manager/settings.gradle.kts rename to gradle-plugins/factorio-gradle/settings.gradle.kts index d6f8766..a417a13 100644 --- a/gradle-plugins/factorio-mod-manager/settings.gradle.kts +++ b/gradle-plugins/factorio-gradle/settings.gradle.kts @@ -8,7 +8,7 @@ pluginManagement { } plugins { - id("kafkatorio.convention.settings.repositories") + id("kafkatorio.conventions.settings.repositories") } dependencyResolutionManagement { diff --git a/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.kt b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/settings/repositories.kt similarity index 100% rename from gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.kt rename to gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/settings/repositories.kt diff --git a/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.settings.gradle.kts b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/settings/repositories.settings.gradle.kts similarity index 94% rename from gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.settings.gradle.kts rename to gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/settings/repositories.settings.gradle.kts index 6bca2b5..e49aed8 100644 --- a/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/convention/settings/repositories.settings.gradle.kts +++ b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/settings/repositories.settings.gradle.kts @@ -1,4 +1,4 @@ -package kafkatorio.convention.settings +package kafkatorio.conventions.settings @Suppress("UnstableApiUsage") // Central declaration of repositories is an incubating feature dependencyResolutionManagement { diff --git a/settings.gradle.kts b/settings.gradle.kts index 4b7f0b3..8cc8ca9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -9,11 +9,11 @@ pluginManagement { includeBuild("./gradle-plugins/builder-plugins/") includeBuild("./gradle-plugins/docker-compose/") -includeBuild("./gradle-plugins/factorio-mod-manager/") +includeBuild("./gradle-plugins/factorio-gradle/") plugins { - id("kafkatorio.convention.settings.repositories") + id("kafkatorio.conventions.settings.repositories") } From 9071148944e993f58c9a4dca9d7fb2c7e76af820 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 18 Sep 2022 23:38:15 +0200 Subject: [PATCH 524/629] start dockerising the modules... --- modules/events-processors/docker/Dockerfile | 25 ++++++++++++ .../docker/docker-compose.yml | 39 +++++++++++++++++++ .../events-server-syslog/docker/Dockerfile | 31 ++++++++++----- .../docker/docker-compose.yml | 39 +++++++++++++++++++ modules/events-server/docker/Dockerfile | 2 +- modules/infra-kafka-cluster/src/.env | 7 ---- modules/infra-kafka-pipe/src/.env | 3 -- modules/web-map/docker/.env | 3 -- modules/web-map/docker/Dockerfile | 2 +- modules/web-map/docker/docker-compose.yml | 2 +- 10 files changed, 127 insertions(+), 26 deletions(-) create mode 100644 modules/events-processors/docker/Dockerfile create mode 100644 modules/events-processors/docker/docker-compose.yml create mode 100644 modules/events-server-syslog/docker/docker-compose.yml delete mode 100644 modules/infra-kafka-cluster/src/.env delete mode 100644 modules/infra-kafka-pipe/src/.env delete mode 100644 modules/web-map/docker/.env diff --git a/modules/events-processors/docker/Dockerfile b/modules/events-processors/docker/Dockerfile new file mode 100644 index 0000000..3f7ac14 --- /dev/null +++ b/modules/events-processors/docker/Dockerfile @@ -0,0 +1,25 @@ +# syntax=docker/dockerfile:1 + +FROM eclipse-temurin:11-jdk-jammy +ARG KAFKATORIO_VERSION=0.5.1 +ARG DIST_DIR="../build/distributions/" + +WORKDIR /app + +ENV SERVER_PORT=8080 +EXPOSE $SERVER_PORT + +ENV SOCKET_SERVER_PORT=9002 +EXPOSE $SOCKET_SERVER_PORT + +ENV SERVER_DATA_DIR="/app/data" +ENV KAFKA_STREAMS_STATE_DIR="/app/state/kafka" +VOLUME ${SERVER_DATA_DIR} \ + ${KAFKA_STREAMS_STATE_DIR} + +COPY ${DIST_DIR}/events-server-${KAFKATORIO_VERSION}.tar events-server.tar + +RUN tar -xf events-server.tar --strip-components=1 \ + && rm events-server.tar + +ENTRYPOINT /app/bin/events-server diff --git a/modules/events-processors/docker/docker-compose.yml b/modules/events-processors/docker/docker-compose.yml new file mode 100644 index 0000000..d3b16f9 --- /dev/null +++ b/modules/events-processors/docker/docker-compose.yml @@ -0,0 +1,39 @@ +version: "3.9" + +services: + + events-server: + image: kafkatorio/events-server:${KAFKATORIO_VERSION} + container_name: events-server + restart: unless-stopped + build: + context: .. + dockerfile: ./docker/Dockerfile + args: + KAFKATORIO_VERSION: ${KAFKATORIO_VERSION} + DIST_DIR: "./build/distributions/" + environment: + KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" + # KAFKA_STREAMS_STATE_DIR: "" + SERVER_PORT: "8080" + SOCKET_SERVER_PORT: "9002" + ports: + - "12080:8080" # http and ws + - "12034:9002" # syslog socket + networks: + - "kafka-nw" + - "kafkatorio-nw" + - "traefik-nw" +# labels: +# - "traefik.enable=true" + +networks: + kafka-nw: + name: "kafka-nw" + external: true + kafkatorio-nw: + name: "kafkatorio-nw" + external: true + traefik-nw: + name: "traefik-nw" + external: true diff --git a/modules/events-server-syslog/docker/Dockerfile b/modules/events-server-syslog/docker/Dockerfile index a196e24..46acc9e 100644 --- a/modules/events-server-syslog/docker/Dockerfile +++ b/modules/events-server-syslog/docker/Dockerfile @@ -1,11 +1,22 @@ -FROM gradle:7-jdk11 AS build -COPY --chown=gradle:gradle . /home/gradle/src -WORKDIR /home/gradle/src -RUN gradle buildFatJar --no-daemon - - FROM openjdk:11 -EXPOSE 8080:8080 -RUN mkdir /app -COPY --from=build /home/gradle/src/build/libs/*.jar /app/ktor-docker-sample.jar -ENTRYPOINT ["java","-jar","/app/ktor-docker-sample.jar"] +ARG KAFKATORIO_VERSION +ARG DIST_DIR="../build/distributions/" +ARG APP_NAME="events-server-syslog" + +WORKDIR /app + +ENV SOCKET_SERVER_PORT=601 +EXPOSE $SYSLOG_PORT + +ENV SERVER_DATA_DIR="/app/data" +ENV KAFKA_STREAMS_STATE_DIR="/app/state/kafka" + +VOLUME ${SERVER_DATA_DIR} \ + ${KAFKA_STREAMS_STATE_DIR} + +COPY ${DIST_DIR}/${APP_NAME}-${KAFKATORIO_VERSION}.tar ${APP_NAME}.tar + +RUN tar -xf ${APP_NAME}.tar --strip-components=1 \ + && rm ${APP_NAME}.tar + +ENTRYPOINT /app/bin/${APP_NAME} diff --git a/modules/events-server-syslog/docker/docker-compose.yml b/modules/events-server-syslog/docker/docker-compose.yml new file mode 100644 index 0000000..d3b16f9 --- /dev/null +++ b/modules/events-server-syslog/docker/docker-compose.yml @@ -0,0 +1,39 @@ +version: "3.9" + +services: + + events-server: + image: kafkatorio/events-server:${KAFKATORIO_VERSION} + container_name: events-server + restart: unless-stopped + build: + context: .. + dockerfile: ./docker/Dockerfile + args: + KAFKATORIO_VERSION: ${KAFKATORIO_VERSION} + DIST_DIR: "./build/distributions/" + environment: + KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" + # KAFKA_STREAMS_STATE_DIR: "" + SERVER_PORT: "8080" + SOCKET_SERVER_PORT: "9002" + ports: + - "12080:8080" # http and ws + - "12034:9002" # syslog socket + networks: + - "kafka-nw" + - "kafkatorio-nw" + - "traefik-nw" +# labels: +# - "traefik.enable=true" + +networks: + kafka-nw: + name: "kafka-nw" + external: true + kafkatorio-nw: + name: "kafkatorio-nw" + external: true + traefik-nw: + name: "traefik-nw" + external: true diff --git a/modules/events-server/docker/Dockerfile b/modules/events-server/docker/Dockerfile index 3f7ac14..8c87699 100644 --- a/modules/events-server/docker/Dockerfile +++ b/modules/events-server/docker/Dockerfile @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1 FROM eclipse-temurin:11-jdk-jammy -ARG KAFKATORIO_VERSION=0.5.1 +ARG KAFKATORIO_VERSION ARG DIST_DIR="../build/distributions/" WORKDIR /app diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env deleted file mode 100644 index 2edf2d3..0000000 --- a/modules/infra-kafka-cluster/src/.env +++ /dev/null @@ -1,7 +0,0 @@ -# Do not edit manually. This file was created with task 'dockerEnvUpdate' -COMPOSE_PROJECT_NAME=kafkatorio -GRAFANA_VERSION=8.5.0 -KAFKATORIO_VERSION=0.9.0 -KAFKA_DL_URL=https\://dlcdn.apache.org/kafka/3.2.2/kafka_2.13-3.2.2.tgz -KAFKA_VERSION=3.2.2 -PROMETHEUS_VERSION=v2.34.0 diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env deleted file mode 100644 index 1eb5f42..0000000 --- a/modules/infra-kafka-pipe/src/.env +++ /dev/null @@ -1,3 +0,0 @@ -# Do not edit manually. This file was created with task 'dockerEnvUpdate' -COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.9.0 diff --git a/modules/web-map/docker/.env b/modules/web-map/docker/.env deleted file mode 100644 index 1eb5f42..0000000 --- a/modules/web-map/docker/.env +++ /dev/null @@ -1,3 +0,0 @@ -# Do not edit manually. This file was created with task 'dockerEnvUpdate' -COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.9.0 diff --git a/modules/web-map/docker/Dockerfile b/modules/web-map/docker/Dockerfile index a4d5eb5..f72c386 100644 --- a/modules/web-map/docker/Dockerfile +++ b/modules/web-map/docker/Dockerfile @@ -1,5 +1,5 @@ FROM nginx -COPY ./nginx.conf /etc/nginx/nginx.conf +COPY ./docker/nginx.conf /etc/nginx/nginx.conf COPY ./build/distributions /usr/share/nginx/html diff --git a/modules/web-map/docker/docker-compose.yml b/modules/web-map/docker/docker-compose.yml index 6b859e1..4527065 100644 --- a/modules/web-map/docker/docker-compose.yml +++ b/modules/web-map/docker/docker-compose.yml @@ -3,7 +3,7 @@ version: "3.9" services: kafkatorio-web-map: - image: adamko-dev/kafkatorio-web-map + image: ${REGISTRY_HOST}/adamko-dev/kafkatorio-web-map:${KAFKATORIO_VERSION} container_name: kafkatorio-web-map restart: unless-stopped build: From fd3b39a839b65337461f863810726f152ea31e16 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 18 Sep 2022 23:53:56 +0200 Subject: [PATCH 525/629] fix factorio-gradle project name --- gradle-plugins/factorio-gradle/settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle-plugins/factorio-gradle/settings.gradle.kts b/gradle-plugins/factorio-gradle/settings.gradle.kts index a417a13..72f93af 100644 --- a/gradle-plugins/factorio-gradle/settings.gradle.kts +++ b/gradle-plugins/factorio-gradle/settings.gradle.kts @@ -1,6 +1,6 @@ @file:Suppress("UnstableApiUsage") -rootProject.name = "factorio-mod-manager" +rootProject.name = "factorio-gradle" pluginManagement { @Suppress("UnstableApiUsage") From 105555bf6c13a7f3c224a41cac4df0d286a5ddf7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 2 Oct 2022 12:06:34 +0200 Subject: [PATCH 526/629] Kotlin 1.7.20 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index af29c20..a301b29 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ ## compilation ## jvm = "11" -kotlin = "1.7.10" +kotlin = "1.7.20" ## libs ## camel-kafkaConnectors = "0.11.0" From f804c39a3b4540a7338cbf94b8f2ee64ee2e2b15 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 2 Oct 2022 12:11:06 +0200 Subject: [PATCH 527/629] migrate docker-compose convention plugin out of buildSrc --- buildSrc/build.gradle.kts | 69 +++++----- .../adamko/kafkatorio/factoriomod/tasks.kt | 12 -- buildSrc/src/main/kotlin/extensions.kt | 25 ++++ .../builder-plugins/build.gradle.kts | 39 +++--- .../modules/common-lib/build.gradle.kts | 24 ++++ .../kotlin/kafkatorio/common/distributions.kt | 17 +++ .../builder-plugins/settings.gradle.kts | 13 ++ .../infra/docker-compose.gradle.kts | 122 +++++++++--------- .../docker-compose/build.gradle.kts | 27 ++-- .../adamko/geedeecee}/DockerComposeExec.kt | 19 ++- .../adamko/geedeecee}/DockerEnvUpdateTask.kt | 8 +- .../dev/adamko/geedeecee/GDCCommandTask.kt | 47 +++++++ .../kotlin/dev/adamko/geedeecee/GDCPlugin.kt | 84 +++++++++--- .../dev/adamko/geedeecee/GDCSettings.kt | 6 + .../factorio-gradle/build.gradle.kts | 52 ++++++-- .../gradle/factorio/FactorioModInstallTask.kt | 43 ++++++ .../factorio}/FactorioModSettings.kt | 2 +- .../FactorioModPortalPublishClient.kt | 2 +- .../mod_portal}/FactorioModPublishTask.kt | 6 +- .../gradle/factorio/mod_portal}/model.kt | 2 +- .../settings-plugins/build.gradle.kts | 5 + .../conventions/kotlin-dsl.gradle.kts | 30 +++++ .../conventions/kotlinDslExtensions.kt | 21 +++ modules/events-library/build.gradle.kts | 9 +- modules/events-mod/build.gradle.kts | 9 +- modules/events-server-syslog/build.gradle.kts | 3 +- modules/events-server-web/build.gradle.kts | 1 + .../infra-factorio-client/build.gradle.kts | 24 ++-- .../infra-factorio-server/build.gradle.kts | 48 +++---- modules/infra-kafka-cluster/build.gradle.kts | 10 +- modules/infra-kafka-pipe/build.gradle.kts | 11 +- modules/web-map/build.gradle.kts | 13 +- 32 files changed, 564 insertions(+), 239 deletions(-) delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/tasks.kt create mode 100644 buildSrc/src/main/kotlin/extensions.kt create mode 100644 gradle-plugins/builder-plugins/modules/common-lib/build.gradle.kts create mode 100644 gradle-plugins/builder-plugins/modules/common-lib/src/main/kotlin/kafkatorio/common/distributions.kt rename gradle-plugins/{builder-plugins/src/main/kotlin/kafkatorio/tasks => docker-compose/src/main/kotlin/dev/adamko/geedeecee}/DockerComposeExec.kt (79%) rename gradle-plugins/{builder-plugins/src/main/kotlin/kafkatorio/tasks => docker-compose/src/main/kotlin/dev/adamko/geedeecee}/DockerEnvUpdateTask.kt (75%) create mode 100644 gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModInstallTask.kt rename gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/{factorio_gradle => gradle/factorio}/FactorioModSettings.kt (91%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal => gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod_portal}/FactorioModPortalPublishClient.kt (98%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal => gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod_portal}/FactorioModPublishTask.kt (95%) rename {buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal => gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod_portal}/model.kt (98%) create mode 100644 gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/kotlin-dsl.gradle.kts create mode 100644 gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/kotlinDslExtensions.kt diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index b98a725..dad2820 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,18 +1,20 @@ +import kafkatorio.conventions.overrideKotlinLanguageVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - idea - `kotlin-dsl` - kotlin("jvm") version embeddedKotlinVersion - kotlin("plugin.serialization") version embeddedKotlinVersion + id("kafkatorio.conventions.kotlin-dsl") +// idea +// `kotlin-dsl` +// kotlin("jvm") //version "1.7.20" // embeddedKotlinVersion + kotlin("plugin.serialization") version embeddedKotlinVersion +// kotlin("plugin.serialization") version "1.7.20" } -val gradleJvmTarget = "11" -val gradleKotlinTarget = "1.6" +//val gradleJvmTarget = "11" +//val gradleKotlinTarget = "1.6" dependencies { - implementation(platform(libs.kotlin.bom)) implementation("org.jetbrains.kotlin:kotlin-serialization") implementation("org.jetbrains.kotlin:kotlin-reflect") @@ -72,9 +74,9 @@ dependencies { tasks.withType().configureEach { kotlinOptions { - jvmTarget = gradleJvmTarget - apiVersion = gradleKotlinTarget - languageVersion = gradleKotlinTarget +// jvmTarget = gradleJvmTarget +// apiVersion = gradleKotlinTarget +// languageVersion = gradleKotlinTarget } kotlinOptions.freeCompilerArgs += listOf( @@ -88,28 +90,29 @@ tasks.withType().configureEach { } -afterEvaluate { - tasks.withType().configureEach { - kotlinOptions { - apiVersion = gradleKotlinTarget - languageVersion = gradleKotlinTarget - } - } -} +overrideKotlinLanguageVersion("1.6") +//afterEvaluate { +// tasks.withType().configureEach { +// kotlinOptions { +// apiVersion = gradleKotlinTarget +// languageVersion = gradleKotlinTarget +// } +// } +//} -kotlin { - jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) - } -} +//kotlin { +// jvmToolchain { +// (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) +// } +//} +// +//kotlinDslPluginOptions { +// jvmTarget.set(gradleJvmTarget) +//} -kotlinDslPluginOptions { - jvmTarget.set(gradleJvmTarget) -} - -idea { - module { - isDownloadSources = true - isDownloadJavadoc = true - } -} +//idea { +// module { +// isDownloadSources = true +// isDownloadJavadoc = true +// } +//} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/tasks.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/tasks.kt deleted file mode 100644 index b657ace..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/tasks.kt +++ /dev/null @@ -1,12 +0,0 @@ -package dev.adamko.kafkatorio.factoriomod - -object FactorioMod { - - const val TASK_GROUP = "factorioMod" - - /** Lifecycle task for publishing the mod locally */ - const val PUBLISH_MOD_LOCAL_TASK_NAME = "publishModLocal" - - const val PUBLISH_MOD_TASK_NAME = "publishMod" - -} diff --git a/buildSrc/src/main/kotlin/extensions.kt b/buildSrc/src/main/kotlin/extensions.kt new file mode 100644 index 0000000..52b96c9 --- /dev/null +++ b/buildSrc/src/main/kotlin/extensions.kt @@ -0,0 +1,25 @@ +import org.gradle.api.artifacts.Configuration +import org.gradle.api.attributes.Usage +import org.gradle.api.model.ObjectFactory +import org.gradle.kotlin.dsl.named + +// to be moved into gradle-plugins/builder-plugins... + + +fun Configuration.asProvider() { + isVisible = false + isCanBeResolved = false + isCanBeConsumed = true +} + + +fun Configuration.asConsumer() { + isVisible = false + isCanBeResolved = true + isCanBeConsumed = false +} + +fun Configuration.typescriptAttributes(objects: ObjectFactory): Configuration = + attributes { + attribute(Usage.USAGE_ATTRIBUTE, objects.named("dev.adamko.gradle.factorio.typescriptFiles")) + } diff --git a/gradle-plugins/builder-plugins/build.gradle.kts b/gradle-plugins/builder-plugins/build.gradle.kts index 0f6d586..bd5b119 100644 --- a/gradle-plugins/builder-plugins/build.gradle.kts +++ b/gradle-plugins/builder-plugins/build.gradle.kts @@ -1,8 +1,9 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - `kotlin-dsl` - kotlin("jvm") version embeddedKotlinVersion + id("kafkatorio.conventions.kotlin-dsl") +// `kotlin-dsl` +// kotlin("jvm") version embeddedKotlinVersion } dependencies { @@ -34,20 +35,20 @@ dependencies { implementation(libs.kotlinx.cli) } -val gradleJvmTarget = "11" - -kotlin { - jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) - } -} - -kotlinDslPluginOptions { - jvmTarget.set(gradleJvmTarget) -} - -tasks.withType().configureEach { - kotlinOptions { - jvmTarget = gradleJvmTarget - } -} +//val gradleJvmTarget = "11" +// +//kotlin { +// jvmToolchain { +// (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) +// } +//} +// +//kotlinDslPluginOptions { +// jvmTarget.set(gradleJvmTarget) +//} +// +//tasks.withType().configureEach { +// kotlinOptions { +// jvmTarget = gradleJvmTarget +// } +//} diff --git a/gradle-plugins/builder-plugins/modules/common-lib/build.gradle.kts b/gradle-plugins/builder-plugins/modules/common-lib/build.gradle.kts new file mode 100644 index 0000000..6d950b3 --- /dev/null +++ b/gradle-plugins/builder-plugins/modules/common-lib/build.gradle.kts @@ -0,0 +1,24 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") +} + +val gradleJvmTarget = "11" + +dependencies { + implementation(platform(kotlin("bom"))) + implementation(gradleApi()) +} + +kotlin { + jvmToolchain { + (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) + } +} + +tasks.withType().configureEach { + kotlinOptions { + jvmTarget = gradleJvmTarget + } +} diff --git a/gradle-plugins/builder-plugins/modules/common-lib/src/main/kotlin/kafkatorio/common/distributions.kt b/gradle-plugins/builder-plugins/modules/common-lib/src/main/kotlin/kafkatorio/common/distributions.kt new file mode 100644 index 0000000..d1ab91f --- /dev/null +++ b/gradle-plugins/builder-plugins/modules/common-lib/src/main/kotlin/kafkatorio/common/distributions.kt @@ -0,0 +1,17 @@ +package kafkatorio.common + +import org.gradle.api.artifacts.Configuration + + +fun Configuration.asProvider() { + isVisible = false + isCanBeResolved = false + isCanBeConsumed = true +} + + +fun Configuration.asConsumer() { + isVisible = false + isCanBeResolved = true + isCanBeConsumed = false +} diff --git a/gradle-plugins/builder-plugins/settings.gradle.kts b/gradle-plugins/builder-plugins/settings.gradle.kts index 039eed3..62dd147 100644 --- a/gradle-plugins/builder-plugins/settings.gradle.kts +++ b/gradle-plugins/builder-plugins/settings.gradle.kts @@ -16,3 +16,16 @@ dependencyResolutionManagement { } } } + +include( + ":modules:common-lib", + + ":modules:build-conventions", + + ":modules:docker-compose", + ":modules:factorio-mod", + ":modules:typescript", +) + + +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") diff --git a/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/infra/docker-compose.gradle.kts b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/infra/docker-compose.gradle.kts index 0de989b..3088121 100644 --- a/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/infra/docker-compose.gradle.kts +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/infra/docker-compose.gradle.kts @@ -1,63 +1,63 @@ package kafkatorio.conventions.infra -import kafkatorio.tasks.DockerEnvUpdateTask -import kafkatorio.extensions.DOCKER_COMPOSE_TASK_GROUP -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs - -plugins { - base - id("kafkatorio.conventions.infra.process-runner") -} - - -val dockerComposeProjectName: String by extra(rootProject.name) -val dockerSrcDir: Directory by extra(layout.projectDirectory.dir("src")) - - -val dockerUp by tasks.registering(Exec::class) { - group = DOCKER_COMPOSE_TASK_GROUP - - dependsOn(tasks.assemble) - logging.captureStandardOutput(LogLevel.LIFECYCLE) - - workingDir = dockerSrcDir.asFile - commandLine = parseSpaceSeparatedArgs(""" docker-compose up -d """) -} - - -val dockerDown by tasks.registering(Exec::class) { - group = DOCKER_COMPOSE_TASK_GROUP - - logging.captureStandardOutput(LogLevel.LIFECYCLE) - - workingDir = dockerSrcDir.asFile - commandLine = parseSpaceSeparatedArgs(""" docker-compose down """) -} - - -val dockerRemove by tasks.registering(Exec::class) { - group = DOCKER_COMPOSE_TASK_GROUP - - logging.captureStandardOutput(LogLevel.LIFECYCLE) - - workingDir = dockerSrcDir.asFile - commandLine = parseSpaceSeparatedArgs(""" docker-compose rm --stop -v -f """) -} - - -tasks.matching { it.name == "processRun" }.configureEach { dependsOn(dockerUp, dockerEnvUpdate) } -tasks.matching { it.name == "processKill" }.configureEach { dependsOn(dockerDown) } - - -val dockerEnvUpdate by tasks.registering(DockerEnvUpdateTask::class) { - dotEnvFile.set(dockerSrcDir.file(".env")) - - properties( - "COMPOSE_PROJECT_NAME" to dockerComposeProjectName, - "KAFKATORIO_VERSION" to project.version, - "REGISTRY_HOST" to providers.gradleProperty("dockerContainerRegistryHost"), - ) -} - - -tasks.assemble { dependsOn(dockerEnvUpdate) } +//import kafkatorio.tasks.DockerEnvUpdateTask +//import kafkatorio.extensions.DOCKER_COMPOSE_TASK_GROUP +//import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs +// +//plugins { +// base +// id("kafkatorio.conventions.infra.process-runner") +//} +// +// +//val dockerComposeProjectName: String by extra(rootProject.name) +//val dockerSrcDir: Directory by extra(layout.projectDirectory.dir("src")) +// +// +//val dockerUp by tasks.registering(Exec::class) { +// group = DOCKER_COMPOSE_TASK_GROUP +// +// dependsOn(tasks.assemble) +// logging.captureStandardOutput(LogLevel.LIFECYCLE) +// +// workingDir = dockerSrcDir.asFile +// commandLine = parseSpaceSeparatedArgs(""" docker-compose up -d """) +//} +// +// +//val dockerDown by tasks.registering(Exec::class) { +// group = DOCKER_COMPOSE_TASK_GROUP +// +// logging.captureStandardOutput(LogLevel.LIFECYCLE) +// +// workingDir = dockerSrcDir.asFile +// commandLine = parseSpaceSeparatedArgs(""" docker-compose down """) +//} +// +// +//val dockerRemove by tasks.registering(Exec::class) { +// group = DOCKER_COMPOSE_TASK_GROUP +// +// logging.captureStandardOutput(LogLevel.LIFECYCLE) +// +// workingDir = dockerSrcDir.asFile +// commandLine = parseSpaceSeparatedArgs(""" docker-compose rm --stop -v -f """) +//} +// +// +//tasks.matching { it.name == "processRun" }.configureEach { dependsOn(dockerUp, dockerEnvUpdate) } +//tasks.matching { it.name == "processKill" }.configureEach { dependsOn(dockerDown) } +// +// +//val dockerEnvUpdate by tasks.registering(DockerEnvUpdateTask::class) { +// dotEnvFile.set(dockerSrcDir.file(".env")) +// +// properties( +// "COMPOSE_PROJECT_NAME" to dockerComposeProjectName, +// "KAFKATORIO_VERSION" to project.version, +// "REGISTRY_HOST" to providers.gradleProperty("dockerContainerRegistryHost"), +// ) +//} +// +// +//tasks.assemble { dependsOn(dockerEnvUpdate) } diff --git a/gradle-plugins/docker-compose/build.gradle.kts b/gradle-plugins/docker-compose/build.gradle.kts index 954b7f0..4108bb7 100644 --- a/gradle-plugins/docker-compose/build.gradle.kts +++ b/gradle-plugins/docker-compose/build.gradle.kts @@ -1,8 +1,9 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - kotlin("jvm") version embeddedKotlinVersion - `kotlin-dsl` + id("kafkatorio.conventions.kotlin-dsl") +// kotlin("jvm") version embeddedKotlinVersion +// `kotlin-dsl` `java-gradle-plugin` } @@ -13,17 +14,17 @@ dependencies { implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable") } -kotlin { - jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) - } -} - -tasks.withType().configureEach { - kotlinOptions { - jvmTarget = gradleJvmTarget - } -} +//kotlin { +// jvmToolchain { +// (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) +// } +//} +// +//tasks.withType().configureEach { +// kotlinOptions { +// jvmTarget = gradleJvmTarget +// } +//} gradlePlugin { plugins { diff --git a/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/DockerComposeExec.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerComposeExec.kt similarity index 79% rename from gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/DockerComposeExec.kt rename to gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerComposeExec.kt index 8bc28eb..8a11714 100644 --- a/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/DockerComposeExec.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerComposeExec.kt @@ -1,8 +1,8 @@ -package kafkatorio.tasks +package dev.adamko.geedeecee -import kafkatorio.extensions.filesChecksum import javax.inject.Inject import org.gradle.api.DefaultTask +import org.gradle.api.file.Directory import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty import org.gradle.api.logging.LogLevel @@ -20,8 +20,16 @@ import org.gradle.api.tasks.TaskAction import org.gradle.kotlin.dsl.property import org.gradle.process.ExecOperations import org.gradle.work.NormalizeLineEndings +import org.jetbrains.kotlin.incremental.md5 import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + +// look into using 'build context' for up-to-date check +// https://stackoverflow.com/questions/38946683/how-to-test-dockerignore-file +// https://github.com/pwaller/docker-show-context +// https://snippets.khromov.se/see-which-files-are-included-in-your-docker-build-context/ + + @CacheableTask @Suppress("UnstableApiUsage") abstract class DockerComposeExec @Inject constructor( @@ -77,5 +85,12 @@ abstract class DockerComposeExec @Inject constructor( companion object { const val DOCKER_COMPOSE_GROUP: String = "docker-compose" + + + private fun Directory.filesChecksum(): Long = asFileTree + .files + .map { it.readBytes() + it.absolutePath.toByteArray() } + .fold(byteArrayOf()) { acc, bytes -> acc + bytes } + .md5() } } diff --git a/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/DockerEnvUpdateTask.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerEnvUpdateTask.kt similarity index 75% rename from gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/DockerEnvUpdateTask.kt rename to gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerEnvUpdateTask.kt index a5a335f..eb730e0 100644 --- a/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/DockerEnvUpdateTask.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerEnvUpdateTask.kt @@ -1,7 +1,6 @@ -package kafkatorio.tasks +package dev.adamko.geedeecee import javax.inject.Inject -import kafkatorio.extensions.DOCKER_COMPOSE_TASK_GROUP import org.gradle.api.file.RegularFileProperty import org.gradle.api.logging.LogLevel import org.gradle.api.model.ObjectFactory @@ -12,14 +11,15 @@ import org.gradle.api.tasks.WriteProperties @CacheableTask open class DockerEnvUpdateTask @Inject constructor( - private val objects: ObjectFactory + objects: ObjectFactory ) : WriteProperties() { @Internal + // internal and not abstract so that it can delegate to `super.outputFile` in `init {}` val dotEnvFile: RegularFileProperty = objects.fileProperty() init { - group = DOCKER_COMPOSE_TASK_GROUP + group = GDCPlugin.GCD_TASK_GROUP super.setOutputFile(dotEnvFile) super.getLogging().captureStandardOutput(LogLevel.LIFECYCLE) } diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt new file mode 100644 index 0000000..68df53f --- /dev/null +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt @@ -0,0 +1,47 @@ +package dev.adamko.geedeecee + +import javax.inject.Inject +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.logging.LogLevel +import org.gradle.api.provider.ListProperty +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.TaskAction +import org.gradle.process.ExecOperations +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + +abstract class GDCCommandTask @Inject constructor( + private val executor: ExecOperations +) : DefaultTask() { + + init { + super.setGroup(GDCPlugin.GCD_TASK_GROUP) + description = "Run a docker-compose command." + + logging.captureStandardOutput(LogLevel.LIFECYCLE) + } + + @get:InputDirectory + abstract val workingDir: DirectoryProperty + + @get:Input + abstract val separatedArgs: ListProperty + + @TaskAction + fun dockerCompose() { + val separatedArgs: List = separatedArgs.get() + + executor.exec { + workingDir(this@GDCCommandTask.workingDir) + commandLine(separatedArgs) + } + } + + @Suppress("FunctionName") + fun `docker-compose`(args: String) { + separatedArgs.addAll( + parseSpaceSeparatedArgs("docker-compose $args") + ) + } +} diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt index d6b0429..ac6d684 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt @@ -1,14 +1,17 @@ package dev.adamko.geedeecee import javax.inject.Inject -import org.gradle.api.Plugin -import org.gradle.api.Project +import org.gradle.api.* import org.gradle.api.file.ProjectLayout -import org.gradle.api.provider.ProviderFactory -import org.gradle.kotlin.dsl.create +import org.gradle.api.logging.* +import org.gradle.api.provider.* +import org.gradle.api.tasks.* +import org.gradle.kotlin.dsl.* +import org.gradle.language.base.plugins.LifecycleBasePlugin import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs +@Suppress("UnstableApiUsage") abstract class GDCPlugin @Inject constructor( private val providers: ProviderFactory, private val layout: ProjectLayout, @@ -16,27 +19,78 @@ abstract class GDCPlugin @Inject constructor( override fun apply(target: Project) { - target.createSettings() + target.plugins.apply(LifecycleBasePlugin::class) + + val gdcSettings = target.createSettings() + + val dockerComposeEnvUpdate by target.tasks.registering(DockerEnvUpdateTask::class) { + dotEnvFile.set(gdcSettings.srcDir.file(".env")) + +// properties( +// "COMPOSE_PROJECT_NAME" to gdcSettings.composeProjectName, +// "KAFKATORIO_VERSION" to gdcSettings.composeProjectVersion, +// "REGISTRY_HOST" to providers.gradleProperty("dockerContainerRegistryHost"), +// ) + } + + val dockerComposeUp by target.tasks.registering(GDCCommandTask::class) { + `docker-compose`("up -d") + } + val dockerComposeDown by target.tasks.registering(GDCCommandTask::class) { + `docker-compose`("down") + } + val dockerComposeStop by target.tasks.registering(GDCCommandTask::class) { + `docker-compose`("stop") + } + val dockerComposeBuild by target.tasks.registering(GDCCommandTask::class) { + `docker-compose`("build") + } + val dockerComposeRemove by target.tasks.registering(GDCCommandTask::class) { + `docker-compose`("rm --stop -v -f") + } + + dockerComposeUp.configure { dependsOn(dockerComposeBuild) } + dockerComposeRemove.configure { dependsOn(dockerComposeDown) } + + target.tasks.withType().configureEach { + workingDir.convention(gdcSettings.srcDir) + dependsOn(dockerComposeEnvUpdate) + } + + val assembleTasks = target.tasks.matching { LifecycleBasePlugin.ASSEMBLE_TASK_NAME == it.name } + + assembleTasks.configureEach { + dependsOn(dockerComposeEnvUpdate) + } + + dockerComposeUp.configure { + dependsOn(assembleTasks) + } + } private fun Project.createSettings(): GDCSettings = extensions.create(GDC_EXTENSION_NAME).apply { composeProjectName.convention(providers.provider { project.name }) + composeProjectVersion.convention(providers.provider { project.name }) + containerRegistryHost.convention(providers.gradleProperty("dockerContainerRegistryHost")) srcDir.convention(layout.projectDirectory.dir("docker")) dotEnv.put("COMPOSE_PROJECT_NAME", composeProjectName) - dotEnv.put("PROJECT_VERSION", providers.provider { project.version.toString() }) - dotEnv.put("REGISTRY_HOST", providers.gradleProperty("dockerContainerRegistryHost")) + dotEnv.put("PROJECT_VERSION", composeProjectVersion) + dotEnv.put("REGISTRY_HOST", containerRegistryHost) - enabled.convention( - providers.exec { - commandLine = parseSpaceSeparatedArgs("docker info") - isIgnoreExitValue = true - }.result.map { - it.exitValue == 0 - } - ) + enabled.convention(isDockerActive()) + } + + + private fun isDockerActive(): Provider = + providers.exec { + commandLine = parseSpaceSeparatedArgs("docker info") + isIgnoreExitValue = true + }.result.map { + it.exitValue == 0 } diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCSettings.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCSettings.kt index 64300f5..238c106 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCSettings.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCSettings.kt @@ -11,6 +11,12 @@ interface GDCSettings { @get:Input val composeProjectName: Property + @get:Input + val composeProjectVersion: Property + + @get:Input + val containerRegistryHost: Property + @get:Internal val srcDir: DirectoryProperty diff --git a/gradle-plugins/factorio-gradle/build.gradle.kts b/gradle-plugins/factorio-gradle/build.gradle.kts index ae27420..9c5d55e 100644 --- a/gradle-plugins/factorio-gradle/build.gradle.kts +++ b/gradle-plugins/factorio-gradle/build.gradle.kts @@ -1,10 +1,12 @@ +import kafkatorio.conventions.overrideKotlinLanguageVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - `kotlin-dsl` - kotlin("jvm") version embeddedKotlinVersion + id("kafkatorio.conventions.kotlin-dsl") + kotlin("plugin.serialization") version embeddedKotlinVersion } + dependencies { implementation(platform(libs.kotlin.bom)) @@ -32,20 +34,42 @@ dependencies { } -val gradleJvmTarget = "11" +//val gradleJvmTarget = 11 +// +//kotlin { +// jvmToolchain(gradleJvmTarget) +//} +// +//kotlinDslPluginOptions { +// jvmTarget.set("$gradleJvmTarget") +//} +// +//tasks.withType().configureEach { +// kotlinOptions { +// jvmTarget = "$gradleJvmTarget" +// } +//} -kotlin { - jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) +gradlePlugin { + plugins { + create("factorioMod") { + displayName = "Factorio Mod" + id = "dev.adamko.factorio-mod" + implementationClass = "dev.adamko.gradle.factorio.FactorioModPlugin" + } } } -kotlinDslPluginOptions { - jvmTarget.set(gradleJvmTarget) -} -tasks.withType().configureEach { - kotlinOptions { - jvmTarget = gradleJvmTarget - } -} +overrideKotlinLanguageVersion("1.6") + +//val gradleKotlinTarget = "1.7" +// +//afterEvaluate { +// tasks.withType().configureEach { +// kotlinOptions { +// apiVersion = gradleKotlinTarget +// languageVersion = gradleKotlinTarget +// } +// } +//} diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModInstallTask.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModInstallTask.kt new file mode 100644 index 0000000..f49ecb9 --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModInstallTask.kt @@ -0,0 +1,43 @@ +package dev.adamko.gradle.factorio + +import javax.inject.Inject +import org.gradle.api.DefaultTask +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.FileSystemOperations +import org.gradle.api.internal.file.FileOperations +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.TaskAction + +abstract class FactorioModInstallTask @Inject constructor( + private val files: FileSystemOperations, +) : DefaultTask() { + + @get:Internal + abstract val clientModDirectory: DirectoryProperty + + @get:InputFiles + abstract val modFiles: ConfigurableFileCollection + + init { + description = "Copy the mod to the Factorio client" + group = FactorioModPlugin.TASK_GROUP + + super.onlyIf { + require(it is FactorioModInstallTask) + it.clientModDirectory.asFile.get().exists() + } + } + + @TaskAction + fun install() { + logger.lifecycle("Copying mod from $modFiles to $clientModDirectory") + + files.copy { + from(modFiles) + into(clientModDirectory) + } + } + +} diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/factorio_gradle/FactorioModSettings.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModSettings.kt similarity index 91% rename from gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/factorio_gradle/FactorioModSettings.kt rename to gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModSettings.kt index c43f697..bc427d2 100644 --- a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/factorio_gradle/FactorioModSettings.kt +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModSettings.kt @@ -1,4 +1,4 @@ -package dev.adamko.factorio_gradle +package dev.adamko.gradle.factorio import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPortalPublishClient.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod_portal/FactorioModPortalPublishClient.kt similarity index 98% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPortalPublishClient.kt rename to gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod_portal/FactorioModPortalPublishClient.kt index 5d27eda..f8d8667 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPortalPublishClient.kt +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod_portal/FactorioModPortalPublishClient.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.factoriomod.portal +package dev.adamko.gradle.factorio.mod_portal import io.ktor.client.HttpClient import io.ktor.client.engine.cio.CIO diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPublishTask.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod_portal/FactorioModPublishTask.kt similarity index 95% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPublishTask.kt rename to gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod_portal/FactorioModPublishTask.kt index 0161949..32e1002 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPublishTask.kt +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod_portal/FactorioModPublishTask.kt @@ -1,6 +1,6 @@ -package dev.adamko.kafkatorio.factoriomod.portal +package dev.adamko.gradle.factorio.mod_portal -import dev.adamko.kafkatorio.factoriomod.FactorioMod +import dev.adamko.gradle.factorio.FactorioModPlugin import io.ktor.http.URLBuilder import io.ktor.http.takeFrom import javax.inject.Inject @@ -60,7 +60,7 @@ abstract class FactorioModPublishTask @Inject constructor( init { - group = FactorioMod.TASK_GROUP + group = FactorioModPlugin.TASK_GROUP } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/model.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod_portal/model.kt similarity index 98% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/model.kt rename to gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod_portal/model.kt index 61f0e61..788c5df 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/model.kt +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod_portal/model.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.factoriomod.portal +package dev.adamko.gradle.factorio.mod_portal import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/gradle-plugins/settings-plugins/build.gradle.kts b/gradle-plugins/settings-plugins/build.gradle.kts index 9e00fd7..a6e6a32 100644 --- a/gradle-plugins/settings-plugins/build.gradle.kts +++ b/gradle-plugins/settings-plugins/build.gradle.kts @@ -1,3 +1,4 @@ +import org.gradle.kotlin.dsl.support.expectedKotlinDslPluginsVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -11,6 +12,10 @@ dependencies { // This project should only be providing simple plugins for configuring Gradle without // dependencies. Try to avoid setting dependencies here, else the Gradle script classpath might // get polluted and messy. + + implementation("org.gradle.kotlin:gradle-kotlin-dsl-plugins:$expectedKotlinDslPluginsVersion") +// implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${embeddedKotlinVersion}") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${libs.versions.kotlin.get()}") } kotlin { diff --git a/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/kotlin-dsl.gradle.kts b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/kotlin-dsl.gradle.kts new file mode 100644 index 0000000..2dadd26 --- /dev/null +++ b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/kotlin-dsl.gradle.kts @@ -0,0 +1,30 @@ +package kafkatorio.conventions + +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + id("org.gradle.kotlin.kotlin-dsl") + kotlin("jvm") +} + +val gradleJvmTarget = 11 + +//kotlin { +// jvmToolchain(gradleJvmTarget) +//} + +kotlin { + jvmToolchain { + (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) + } +} + +kotlinDslPluginOptions { + jvmTarget.set("$gradleJvmTarget") +} + +tasks.withType().configureEach { + kotlinOptions { + jvmTarget = "$gradleJvmTarget" + } +} diff --git a/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/kotlinDslExtensions.kt b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/kotlinDslExtensions.kt new file mode 100644 index 0000000..72d1709 --- /dev/null +++ b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/kotlinDslExtensions.kt @@ -0,0 +1,21 @@ +package kafkatorio.conventions + +import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.gradle.jvm.toolchain.JavaLanguageVersion +import org.gradle.jvm.toolchain.JavaToolchainSpec +import org.gradle.kotlin.dsl.plugins.dsl.* +import org.gradle.kotlin.dsl.withType + +fun Project.overrideKotlinLanguageVersion( + gradleKotlinTarget: String = "1.6" +) { + afterEvaluate { + tasks.withType().configureEach { + kotlinOptions { + apiVersion = gradleKotlinTarget + languageVersion = gradleKotlinTarget + } + } + } +} diff --git a/modules/events-library/build.gradle.kts b/modules/events-library/build.gradle.kts index ac2a956..31ae1c0 100644 --- a/modules/events-library/build.gradle.kts +++ b/modules/events-library/build.gradle.kts @@ -1,5 +1,3 @@ -import kafkatorio.distributions.asProvider -import kafkatorio.distributions.typescriptAttributes import kafkatorio.tasks.GenerateTypeScriptTask import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation @@ -8,6 +6,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("kafkatorio.conventions.lang.kotlin-multiplatform") + id("dev.adamko.factorio-mod") // only needed for 'attributes' - need to split up the mod? kotlin("plugin.serialization") distribution } @@ -28,8 +27,10 @@ kotlin { jvmTarget = "11" } } - testRuns["test"].executionTask.configure { - useJUnitPlatform() + testRuns.configureEach { + executionTask.configure { + useJUnitPlatform() + } } } diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index faa546e..89e2bf6 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -1,8 +1,6 @@ -import dev.adamko.kafkatorio.factoriomod.portal.FactorioModPublishTask -import kafkatorio.distributions.asConsumer -import kafkatorio.distributions.asProvider -import kafkatorio.distributions.factorioModAttributes -import kafkatorio.distributions.typescriptAttributes +import dev.adamko.gradle.factorio.mod_portal.FactorioModPublishTask +import dev.adamko.gradle.factorio.typescriptAttributes +import dev.adamko.gradle.factorio.factorioModAttributes import kafkatorio.tasks.TypescriptToLuaTask import kotlinx.serialization.json.put import kotlinx.serialization.json.putJsonObject @@ -13,6 +11,7 @@ import org.gradle.plugins.ide.idea.model.Path as IdeaImlPath plugins { id("kafkatorio.conventions.lang.node") + id("dev.adamko.factorio-mod") distribution } diff --git a/modules/events-server-syslog/build.gradle.kts b/modules/events-server-syslog/build.gradle.kts index e46fa72..8d1bad2 100644 --- a/modules/events-server-syslog/build.gradle.kts +++ b/modules/events-server-syslog/build.gradle.kts @@ -3,12 +3,13 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("kafkatorio.conventions.lang.kotlin-jvm") + id("dev.adamko.geedeecee") kotlin("plugin.serialization") application } -description = "Consumes Syslog Kafkatorio packets and sends them to Kafka" +description = "Provides a Syslog server that receives Kafkatorio packets and forwards them to Kafka" val projectId: String by project.extra diff --git a/modules/events-server-web/build.gradle.kts b/modules/events-server-web/build.gradle.kts index d0ebc85..a9f506a 100644 --- a/modules/events-server-web/build.gradle.kts +++ b/modules/events-server-web/build.gradle.kts @@ -3,6 +3,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("kafkatorio.conventions.lang.kotlin-jvm") + id("dev.adamko.geedeecee") kotlin("plugin.serialization") application } diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index 622ba2b..0f2f124 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -1,6 +1,5 @@ -import dev.adamko.kafkatorio.factoriomod.FactorioMod -import kafkatorio.distributions.asConsumer -import kafkatorio.distributions.factorioModAttributes +import dev.adamko.gradle.factorio.FactorioModPlugin +import dev.adamko.gradle.factorio.factorioModAttributes import kafkatorio.extensions.not import kafkatorio.tasks.ProcessRunningSpec import org.gradle.kotlin.dsl.support.serviceOf @@ -8,6 +7,7 @@ import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { id("kafkatorio.conventions.infra.process-runner") + id("dev.adamko.factorio-mod") } description = "Start the Factorio game client" @@ -26,10 +26,10 @@ val steamExe: RegularFileProperty = objects.fileProperty().apply { } } -val factorioMod: Configuration by configurations.creating { - asConsumer() - factorioModAttributes(objects) -} +//val factorioMod: Configuration by configurations.creating { +// asConsumer() +// factorioModAttributes(objects) +//} dependencies { factorioMod(projects.modules.eventsMod) @@ -39,7 +39,7 @@ dependencies { // val deployModToLocalClient by tasks.registering(Copy::class) { description = "Copy the mod to the Factorio client" - group = FactorioMod.TASK_GROUP + group = FactorioModPlugin.TASK_GROUP val clientModsDirectory123 = clientModsDirectory @@ -61,7 +61,7 @@ fun ExecOperations.isFactorioRunning(): Spec = ProcessRunningSpec(this, "f val clientLaunch by tasks.registering(Exec::class) { description = "Run local Factorio Steam game client" - group = FactorioMod.TASK_GROUP + group = FactorioModPlugin.TASK_GROUP val steamExe123 = steamExe val clientModsDirectory444 = clientModsDirectory @@ -83,7 +83,7 @@ val clientLaunch by tasks.registering(Exec::class) { val clientKill by tasks.registering(Exec::class) { description = "Stop the local Factorio Steam game client" - group = FactorioMod.TASK_GROUP + group = FactorioModPlugin.TASK_GROUP onlyIf(serviceOf().isFactorioRunning()) @@ -93,8 +93,8 @@ val clientKill by tasks.registering(Exec::class) { // -tasks.register(FactorioMod.PUBLISH_MOD_LOCAL_TASK_NAME) { - group = FactorioMod.TASK_GROUP +tasks.register(FactorioModPlugin.PUBLISH_MOD_LOCAL_TASK_NAME) { + group = FactorioModPlugin.TASK_GROUP dependsOn(deployModToLocalClient) } diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index d97aeab..835bcaf 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -1,21 +1,22 @@ -import dev.adamko.kafkatorio.factoriomod.FactorioMod -import kafkatorio.distributions.asConsumer -import kafkatorio.distributions.factorioModAttributes -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs +import dev.adamko.gradle.factorio.FactorioModPlugin plugins { - id("kafkatorio.conventions.infra.docker-compose") + id("dev.adamko.geedeecee") + id("dev.adamko.factorio-mod") + idea } -val dockerSrcDir: Directory by extra -val factorioServerDataDir: Directory = dockerSrcDir.dir("factorio-server") +//val dockerSrcDir: Directory by extra +//val factorioServerDataDir: Directory = dockerSrcDir.dir("factorio-server") +val factorioServerDataDir: DirectoryProperty = objects.directoryProperty() + .convention(geedeecee.srcDir.dir("factorio-server")) -val factorioMod: Configuration by configurations.creating { - asConsumer() - factorioModAttributes(objects) -} +//val factorioMod: Configuration by configurations.creating { +// asConsumer() +// factorioModAttributes(objects) +//} dependencies { @@ -25,13 +26,14 @@ dependencies { val deployModToLocalServer by tasks.registering(Copy::class) { description = "Copy the mod to the Factorio Docker server" - group = FactorioMod.TASK_GROUP + group = FactorioModPlugin.TASK_GROUP dependsOn(factorioMod) - from( - provider { factorioMod.incoming.artifacts.artifactFiles.files } - ) +// from( +// provider { factorioMod.incoming.artifacts.artifactFiles.files } +// ) + from(configurations.factorioMod.map { it.incoming.artifacts.artifactFiles.files }) into(factorioServerDataDir.dir("mods")) doLast { @@ -40,12 +42,12 @@ val deployModToLocalServer by tasks.registering(Copy::class) { } -tasks.dockerDown { - commandLine = parseSpaceSeparatedArgs(""" docker-compose stop """) -} +//tasks.dockerComposeDown { +// commandLine = parseSpaceSeparatedArgs(""" docker-compose stop """) +//} -tasks.dockerUp { +tasks.dockerComposeUp { dependsOn( deployModToLocalServer, ":modules:infra-kafka-cluster:processRun", @@ -56,7 +58,7 @@ tasks.dockerUp { val kafkatorioServerToken: String by project -tasks.dockerEnvUpdate { +tasks.dockerComposeEnvUpdate { properties( "FACTORIO_VERSION" to libs.versions.factorio.get(), "KAFKATORIO_TOKEN" to kafkatorioServerToken, @@ -64,8 +66,8 @@ tasks.dockerEnvUpdate { } -tasks.register(FactorioMod.PUBLISH_MOD_LOCAL_TASK_NAME) { - group = FactorioMod.TASK_GROUP +tasks.register(FactorioModPlugin.PUBLISH_MOD_LOCAL_TASK_NAME) { + group = FactorioModPlugin.TASK_GROUP dependsOn(deployModToLocalServer) } @@ -79,5 +81,5 @@ idea { val runFactorioServer by tasks.registering { group = rootProject.name - dependsOn(tasks.processRun) + dependsOn(tasks.dockerComposeUp) } diff --git a/modules/infra-kafka-cluster/build.gradle.kts b/modules/infra-kafka-cluster/build.gradle.kts index f56f49f..7f61e81 100644 --- a/modules/infra-kafka-cluster/build.gradle.kts +++ b/modules/infra-kafka-cluster/build.gradle.kts @@ -1,10 +1,14 @@ plugins { - id("kafkatorio.conventions.infra.docker-compose") + id("dev.adamko.geedeecee") } description = "Kafka cluster" -tasks.dockerEnvUpdate { +geedeecee { + srcDir.set(layout.projectDirectory.dir("src")) +} + +tasks.dockerComposeEnvUpdate { properties( "GRAFANA_VERSION" to libs.versions.grafana, "PROMETHEUS_VERSION" to libs.versions.prometheus, @@ -31,5 +35,5 @@ tasks.dockerEnvUpdate { val runKafkaCluster by tasks.registering { group = rootProject.name - dependsOn(tasks.processRun) + dependsOn(tasks.dockerComposeUp) } diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index 4bfb356..132a027 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -1,23 +1,22 @@ -import kafkatorio.tasks.DockerComposeExec +import dev.adamko.geedeecee.DockerComposeExec plugins { - id("kafkatorio.conventions.infra.docker-compose") + id("dev.adamko.geedeecee") } description = "Send events from a Factorio server to a Kafka topic " -val dockerSrcDir: Directory by extra +//val dockerSrcDir: Directory by extra -tasks.dockerUp { +tasks.dockerComposeUp { dependsOn(":modules:infra-kafka-cluster:dockerUp") } val dockerBuildKafkaPipe by tasks.registering(DockerComposeExec::class) { - dependsOn(tasks.dockerEnvUpdate) - dockerComposeDir.set(dockerSrcDir) + dockerComposeDir.set(geedeecee.srcDir) command.set("docker-compose build kafka-pipe") diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index c83c02f..8526f8b 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -1,4 +1,3 @@ -import kafkatorio.tasks.DockerEnvUpdateTask import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig @@ -7,6 +6,7 @@ plugins { id("kafkatorio.conventions.lang.kotlin-js") id("io.kvision") kotlin("plugin.serialization") + id("dev.adamko.geedeecee") } @@ -115,17 +115,18 @@ fun KotlinDependencyHandler.kvision( implementation("io.kvision:$module:${version.get()}", configure) } +geedeecee { + srcDir.set(layout.projectDirectory.dir("docker")) +} -val dockerEnvUpdate by tasks.registering(DockerEnvUpdateTask::class) { - dotEnvFile.set(layout.projectDirectory.file("docker/.env")) - +tasks.dockerComposeEnvUpdate { properties( - "COMPOSE_PROJECT_NAME" to rootProject.name, "KAFKATORIO_VERSION" to project.version, "REGISTRY_HOST" to "dcr.adamko.dev:5000", ) } -tasks.assemble { dependsOn(dockerEnvUpdate) } + +tasks.assemble { dependsOn(tasks.dockerComposeEnvUpdate) } val installThemeCss by tasks.registering(Copy::class) { From c01c19a8e22408d39a9f114862044ea2a0f5aabe Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 2 Oct 2022 12:40:34 +0200 Subject: [PATCH 528/629] kafka 3.2.3 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a301b29..1a52747 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ kotlin = "1.7.20" ## libs ## camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" -kafka = "3.2.2" # https://kafka.apache.org/downloads +kafka = "3.2.3" # https://kafka.apache.org/downloads kvision = "5.15.2" # https://github.com/rjaros/kvision/releases log4j2 = "2.17.2" okio = "3.2.0" # https://search.maven.org/artifact/com.squareup.okio/okio From b171f88435c2fbf5e54fc85d05622880bc46d75b Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 2 Oct 2022 13:57:15 +0200 Subject: [PATCH 529/629] geedeecee: fix DockerEnvUpdateTask --- .../adamko/geedeecee/DockerEnvUpdateTask.kt | 92 ++++++++++++++++--- .../kotlin/dev/adamko/geedeecee/GDCPlugin.kt | 1 + .../infra-factorio-server/build.gradle.kts | 10 +- modules/infra-kafka-cluster/build.gradle.kts | 17 ++-- modules/web-map/build.gradle.kts | 10 +- 5 files changed, 101 insertions(+), 29 deletions(-) diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerEnvUpdateTask.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerEnvUpdateTask.kt index eb730e0..80046ab 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerEnvUpdateTask.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerEnvUpdateTask.kt @@ -1,27 +1,95 @@ package dev.adamko.geedeecee +import java.io.File +import java.nio.charset.Charset +import java.util.Properties import javax.inject.Inject +import org.gradle.api.DefaultTask import org.gradle.api.file.RegularFileProperty -import org.gradle.api.logging.LogLevel -import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.MapProperty +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider import org.gradle.api.tasks.CacheableTask -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.WriteProperties +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction @CacheableTask -open class DockerEnvUpdateTask @Inject constructor( - objects: ObjectFactory -) : WriteProperties() { +abstract class DockerEnvUpdateTask @Inject constructor( +) : DefaultTask() { - @Internal - // internal and not abstract so that it can delegate to `super.outputFile` in `init {}` - val dotEnvFile: RegularFileProperty = objects.fileProperty() + @get:Input + abstract val envProperties: MapProperty + + @get:Input + @get:Optional + abstract val comment: Property + + @get:Input + @get:Optional + abstract val charset: Property + + @get:OutputFile + abstract val dotEnvFile: RegularFileProperty init { group = GDCPlugin.GCD_TASK_GROUP - super.setOutputFile(dotEnvFile) - super.getLogging().captureStandardOutput(LogLevel.LIFECYCLE) } + @TaskAction + fun writeProperties() { + val dotEnvFile: File = dotEnvFile.get().asFile + val charset: Charset = charset.orNull ?: Charsets.UTF_8 + + val comment: String = comment.orNull + ?: " Do not edit manually. This file was created with task '$name'" + + + dotEnvFile.writer(charset).use { writer -> + val properties = Properties() + properties.putAll(envProperties.get()) + properties.store(writer, comment) + } + + // make the file reproducible by sorting and filtering lines in the file + val lines = dotEnvFile.useLines(charset) { lines -> + lines + .filterNot { it.isBlank() } + .sorted() + .toList() + } + + // first comment is our comment + // second comment is the auto generated timestamp - which we will filter out, so the file is reproducible + val parsedComment = lines.firstOrNull { it.isComment() } ?: "" + val parsedLines = lines.filterNot { it.isComment() }.joinToString(separator = "\n") + + dotEnvFile.writeText( + charset = charset, + text = """ + |$parsedComment + | + |$parsedLines + | + """.trimMargin() + ) + } + + fun envProperties(configure: MapProperty.() -> Unit) { + envProperties.configure() + } + + companion object { + @JvmName("putProvider") + fun MapProperty.put(entry: Pair>) = + put(entry.first, entry.second) + + @JvmName("putValue") + fun MapProperty.put(entry: Pair) = + put(entry.first, entry.second) + + private fun String.isComment(): Boolean = trim().startsWith('#') + } } diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt index ac6d684..4261650 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt @@ -26,6 +26,7 @@ abstract class GDCPlugin @Inject constructor( val dockerComposeEnvUpdate by target.tasks.registering(DockerEnvUpdateTask::class) { dotEnvFile.set(gdcSettings.srcDir.file(".env")) + envProperties.convention(gdcSettings.dotEnv) // properties( // "COMPOSE_PROJECT_NAME" to gdcSettings.composeProjectName, // "KAFKATORIO_VERSION" to gdcSettings.composeProjectVersion, diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 835bcaf..f94e4c2 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -59,10 +59,12 @@ val kafkatorioServerToken: String by project tasks.dockerComposeEnvUpdate { - properties( - "FACTORIO_VERSION" to libs.versions.factorio.get(), - "KAFKATORIO_TOKEN" to kafkatorioServerToken, - ) + envProperties.put("FACTORIO_VERSION", libs.versions.factorio) + envProperties.put("KAFKATORIO_TOKEN", kafkatorioServerToken) + envProperties { + put("FACTORIO_VERSION" , libs.versions.factorio) + put("KAFKATORIO_TOKEN" , kafkatorioServerToken) + } } diff --git a/modules/infra-kafka-cluster/build.gradle.kts b/modules/infra-kafka-cluster/build.gradle.kts index 7f61e81..3f6866b 100644 --- a/modules/infra-kafka-cluster/build.gradle.kts +++ b/modules/infra-kafka-cluster/build.gradle.kts @@ -9,15 +9,16 @@ geedeecee { } tasks.dockerComposeEnvUpdate { - properties( - "GRAFANA_VERSION" to libs.versions.grafana, - "PROMETHEUS_VERSION" to libs.versions.prometheus, - "KAFKA_VERSION" to libs.versions.kafka, - "KAFKA_DL_URL" to libs.versions.kafka.map { ver -> + envProperties { + put("GRAFANA_VERSION", libs.versions.grafana) + put("PROMETHEUS_VERSION", libs.versions.prometheus) + put("KAFKA_VERSION", libs.versions.kafka) + put("KAFKA_DL_URL", libs.versions.kafka.map { ver -> "https://dlcdn.apache.org/kafka/$ver/kafka_2.13-$ver.tgz" - } + }) + } - // Limit JVM Heap Size + // Limit JVM Heap Size // "KAFKA_BROKER_HEAP_OPTS" to "-XX:MaxRAMPercentage=70.0", // "KAFKA_CONNECT_HEAP_OPTS" to "-XX:MaxRAMPercentage=70.0", // "SCHEMA_REGISTRY_HEAP_OPTS" to "-XX:MaxRAMPercentage=70.0", @@ -29,7 +30,7 @@ tasks.dockerComposeEnvUpdate { // "KAFKA_CONNECT_MEM_LIMIT" to "512m", // "KAFKA_KSQL_MEM_LIMIT" to "256m", // "SCHEMA_REGISTRY_MEM_LIMIT" to "256m", - ) +// ) } val runKafkaCluster by tasks.registering { diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 8526f8b..821be54 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -1,6 +1,6 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig - +import dev.adamko.geedeecee.DockerEnvUpdateTask.Companion.put plugins { id("kafkatorio.conventions.lang.kotlin-js") @@ -120,10 +120,10 @@ geedeecee { } tasks.dockerComposeEnvUpdate { - properties( - "KAFKATORIO_VERSION" to project.version, - "REGISTRY_HOST" to "dcr.adamko.dev:5000", - ) + envProperties { + put("KAFKATORIO_VERSION" to project.version.toString()) + put("REGISTRY_HOST" to "dcr.adamko.dev:5000") + } } tasks.assemble { dependsOn(tasks.dockerComposeEnvUpdate) } From 71422218aadff56f4017b4581015290ff38e878a Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 2 Oct 2022 13:59:08 +0200 Subject: [PATCH 530/629] move artifactDistributions.kt --- .../kotlin/dev/adamko/gradle/factorio}/artifactDistributions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename gradle-plugins/{builder-plugins/src/main/kotlin/kafkatorio/distributions => factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio}/artifactDistributions.kt (97%) diff --git a/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/distributions/artifactDistributions.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/artifactDistributions.kt similarity index 97% rename from gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/distributions/artifactDistributions.kt rename to gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/artifactDistributions.kt index 56ca202..c4e5ac1 100644 --- a/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/distributions/artifactDistributions.kt +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/artifactDistributions.kt @@ -1,4 +1,4 @@ -package kafkatorio.distributions +package dev.adamko.gradle.factorio import org.gradle.api.artifacts.Configuration import org.gradle.api.attributes.Bundling From c81564ad6ca55ec2481a1a2f06ee0bed1550d67f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 2 Oct 2022 13:59:41 +0200 Subject: [PATCH 531/629] update FactorioModPlugin --- .../factorio_gradle/FactorioModPlugin.kt | 22 ---------- .../gradle/factorio/FactorioModPlugin.kt | 44 +++++++++++++++++++ 2 files changed, 44 insertions(+), 22 deletions(-) delete mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/factorio_gradle/FactorioModPlugin.kt create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModPlugin.kt diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/factorio_gradle/FactorioModPlugin.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/factorio_gradle/FactorioModPlugin.kt deleted file mode 100644 index c883d40..0000000 --- a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/factorio_gradle/FactorioModPlugin.kt +++ /dev/null @@ -1,22 +0,0 @@ -package dev.adamko.factorio_gradle - -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.kotlin.dsl.create - -abstract class FactorioModPlugin : Plugin { - - override fun apply(target: Project) { - target.createSettings() - } - - private fun Project.createSettings(): FactorioModSettings { - return extensions.create(FACTORIO_GRADLE_EXTENSION_NAME).apply { - - } - } - - companion object { - const val FACTORIO_GRADLE_EXTENSION_NAME = "factorio" - } -} diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModPlugin.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModPlugin.kt new file mode 100644 index 0000000..06146b6 --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModPlugin.kt @@ -0,0 +1,44 @@ +package dev.adamko.gradle.factorio + +import javax.inject.Inject +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.model.ObjectFactory +import org.gradle.kotlin.dsl.create + + +abstract class FactorioModPlugin @Inject constructor( + private val objects: ObjectFactory, +) : Plugin { + + override fun apply(target: Project) { + target.createSettings() + + + val factorioModConfiguration = + target.configurations.register(FACTORIO_GRADLE_CONFIGURATION_NAME) { + asConsumer() + factorioModAttributes(objects) + } + + + } + + private fun Project.createSettings(): FactorioModSettings { + return extensions.create(FACTORIO_GRADLE_EXTENSION_NAME).apply { + + } + } + + companion object { + const val FACTORIO_GRADLE_EXTENSION_NAME = "factorioMod" + const val FACTORIO_GRADLE_CONFIGURATION_NAME = "factorioMod" + + const val TASK_GROUP = "factorioMod" + + /** Lifecycle task for publishing the mod locally */ + const val PUBLISH_MOD_LOCAL_TASK_NAME = "publishModLocal" + + const val PUBLISH_MOD_TASK_NAME = "publishMod" + } +} From 46db151f6e37c5aa57cebdd30d75e41510c5e5a6 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 2 Oct 2022 14:03:51 +0200 Subject: [PATCH 532/629] rename SERVER_PORT -> WEB_SERVER_PORT --- modules/events-processor-core/src/main/resources/config.yml | 2 +- modules/events-processors/docker/Dockerfile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/events-processor-core/src/main/resources/config.yml b/modules/events-processor-core/src/main/resources/config.yml index b9f2858..d882d45 100644 --- a/modules/events-processor-core/src/main/resources/config.yml +++ b/modules/events-processor-core/src/main/resources/config.yml @@ -1,6 +1,6 @@ # Factorio Events Processor config -web-port: ${SERVER_PORT:-8080} +web-port: ${WEB_SERVER_PORT:-8080} server-data-dir: ${SERVER_DATA_DIR:-./server-data} diff --git a/modules/events-processors/docker/Dockerfile b/modules/events-processors/docker/Dockerfile index 3f7ac14..7d3a795 100644 --- a/modules/events-processors/docker/Dockerfile +++ b/modules/events-processors/docker/Dockerfile @@ -6,8 +6,8 @@ ARG DIST_DIR="../build/distributions/" WORKDIR /app -ENV SERVER_PORT=8080 -EXPOSE $SERVER_PORT +ENV WEB_SERVER_PORT=8080 +EXPOSE $WEB_SERVER_PORT ENV SOCKET_SERVER_PORT=9002 EXPOSE $SOCKET_SERVER_PORT From f3cab683fc041b378d9663d52c4e2d66e68ca180 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 2 Oct 2022 14:10:11 +0200 Subject: [PATCH 533/629] builder plugin: rename typescript module to typescript-to-lua --- gradle-plugins/builder-plugins/settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle-plugins/builder-plugins/settings.gradle.kts b/gradle-plugins/builder-plugins/settings.gradle.kts index 62dd147..eefa4b4 100644 --- a/gradle-plugins/builder-plugins/settings.gradle.kts +++ b/gradle-plugins/builder-plugins/settings.gradle.kts @@ -24,7 +24,7 @@ include( ":modules:docker-compose", ":modules:factorio-mod", - ":modules:typescript", + ":modules:typescript-to-lua", ) From 6b38cfcea26b2053f3471db30732d24e2557de50 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 2 Oct 2022 14:10:29 +0200 Subject: [PATCH 534/629] update Kotlin jvmToolchain usage --- .../builder-plugins/modules/common-lib/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle-plugins/builder-plugins/modules/common-lib/build.gradle.kts b/gradle-plugins/builder-plugins/modules/common-lib/build.gradle.kts index 6d950b3..b74bf1d 100644 --- a/gradle-plugins/builder-plugins/modules/common-lib/build.gradle.kts +++ b/gradle-plugins/builder-plugins/modules/common-lib/build.gradle.kts @@ -13,7 +13,7 @@ dependencies { kotlin { jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) + languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) } } From 675b0827d6b614568e934317a5d8e1b061028fde Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 2 Oct 2022 14:48:38 +0200 Subject: [PATCH 535/629] add group to attributes usage --- .../dev/adamko/gradle/factorio/artifactDistributions.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/artifactDistributions.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/artifactDistributions.kt index c4e5ac1..38256af 100644 --- a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/artifactDistributions.kt +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/artifactDistributions.kt @@ -28,7 +28,7 @@ fun Configuration.asConsumer() { fun Configuration.factorioModAttributes(objects: ObjectFactory): Configuration = attributes { - attribute(USAGE_ATTRIBUTE, objects.named("factorio")) + attribute(USAGE_ATTRIBUTE, objects.named("dev.adamko.factorio")) attribute(CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) attribute(LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.CLASSES_AND_RESOURCES)) attribute(BUNDLING_ATTRIBUTE, objects.named(Bundling.EMBEDDED)) @@ -37,7 +37,7 @@ fun Configuration.factorioModAttributes(objects: ObjectFactory): Configuration = fun Configuration.typescriptAttributes(objects: ObjectFactory): Configuration = attributes { - attribute(USAGE_ATTRIBUTE, objects.named("typescript")) + attribute(USAGE_ATTRIBUTE, objects.named("dev.adamko.typescript")) attribute(CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) attribute(LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.OBJECTS)) attribute(BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL)) From ae4b122cd4238e1cd0f74865eaaf2c233b4b6ccd Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 2 Oct 2022 14:50:20 +0200 Subject: [PATCH 536/629] geedeecee: add push task, add KAFKATORIO_VERSION, fix composeProjectVersion, set BUILDKIT_PROGRESS=plain --- .../src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt | 1 + .../src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt index 68df53f..1693581 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt @@ -33,6 +33,7 @@ abstract class GDCCommandTask @Inject constructor( val separatedArgs: List = separatedArgs.get() executor.exec { + environment("BUILDKIT_PROGRESS", "plain") workingDir(this@GDCCommandTask.workingDir) commandLine(separatedArgs) } diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt index 4261650..c5d0e15 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt @@ -46,6 +46,10 @@ abstract class GDCPlugin @Inject constructor( val dockerComposeBuild by target.tasks.registering(GDCCommandTask::class) { `docker-compose`("build") } + val dockerComposePush by target.tasks.registering(GDCCommandTask::class) { + dependsOn(dockerComposeBuild) + `docker-compose`("push") + } val dockerComposeRemove by target.tasks.registering(GDCCommandTask::class) { `docker-compose`("rm --stop -v -f") } @@ -74,12 +78,13 @@ abstract class GDCPlugin @Inject constructor( private fun Project.createSettings(): GDCSettings = extensions.create(GDC_EXTENSION_NAME).apply { composeProjectName.convention(providers.provider { project.name }) - composeProjectVersion.convention(providers.provider { project.name }) + composeProjectVersion.convention(providers.provider { project.version.toString() }) containerRegistryHost.convention(providers.gradleProperty("dockerContainerRegistryHost")) srcDir.convention(layout.projectDirectory.dir("docker")) dotEnv.put("COMPOSE_PROJECT_NAME", composeProjectName) dotEnv.put("PROJECT_VERSION", composeProjectVersion) + dotEnv.put("KAFKATORIO_VERSION", composeProjectVersion) dotEnv.put("REGISTRY_HOST", containerRegistryHost) enabled.convention(isDockerActive()) From 99d1f92bbbc57c28b9be527c8edf0b49dab618e7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 2 Oct 2022 14:51:00 +0200 Subject: [PATCH 537/629] update docker image names to include REGISTRY_HOST, and group, and correct image name --- modules/events-processors/docker/docker-compose.yml | 2 +- modules/events-server-syslog/docker/docker-compose.yml | 2 +- modules/events-server/docker/docker-compose.yml | 2 +- modules/infra-kafka-cluster/src/docker-compose.yml | 2 +- modules/infra-kafka-pipe/src/docker-compose.yml | 2 +- modules/web-map/docker/docker-compose.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/events-processors/docker/docker-compose.yml b/modules/events-processors/docker/docker-compose.yml index d3b16f9..e871820 100644 --- a/modules/events-processors/docker/docker-compose.yml +++ b/modules/events-processors/docker/docker-compose.yml @@ -3,7 +3,7 @@ version: "3.9" services: events-server: - image: kafkatorio/events-server:${KAFKATORIO_VERSION} + image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/events-processors:${KAFKATORIO_VERSION} container_name: events-server restart: unless-stopped build: diff --git a/modules/events-server-syslog/docker/docker-compose.yml b/modules/events-server-syslog/docker/docker-compose.yml index d3b16f9..cecaf6d 100644 --- a/modules/events-server-syslog/docker/docker-compose.yml +++ b/modules/events-server-syslog/docker/docker-compose.yml @@ -3,7 +3,7 @@ version: "3.9" services: events-server: - image: kafkatorio/events-server:${KAFKATORIO_VERSION} + image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/events-server-syslog:${KAFKATORIO_VERSION} container_name: events-server restart: unless-stopped build: diff --git a/modules/events-server/docker/docker-compose.yml b/modules/events-server/docker/docker-compose.yml index d3b16f9..9fa071b 100644 --- a/modules/events-server/docker/docker-compose.yml +++ b/modules/events-server/docker/docker-compose.yml @@ -3,7 +3,7 @@ version: "3.9" services: events-server: - image: kafkatorio/events-server:${KAFKATORIO_VERSION} + image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/events-server:${KAFKATORIO_VERSION} container_name: events-server restart: unless-stopped build: diff --git a/modules/infra-kafka-cluster/src/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml index 83124c0..359f741 100644 --- a/modules/infra-kafka-cluster/src/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -3,7 +3,7 @@ version: "3.9" services: kafka: - image: dev-adamko/kafka-kraft:${KAFKA_VERSION} + image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/kafka-kraft:${KAFKA_VERSION} container_name: "kafka" restart: "unless-stopped" build: diff --git a/modules/infra-kafka-pipe/src/docker-compose.yml b/modules/infra-kafka-pipe/src/docker-compose.yml index dd90da2..6f34f3a 100644 --- a/modules/infra-kafka-pipe/src/docker-compose.yml +++ b/modules/infra-kafka-pipe/src/docker-compose.yml @@ -2,7 +2,7 @@ version: "3.9" services: kafka-pipe: - image: dev-adamko/kafka-pipe/${KAFKATORIO_VERSION} + image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/kafka-pipe/${KAFKATORIO_VERSION} container_name: "kafka-pipe" build: dockerfile: "kafka-pipe.Dockerfile" diff --git a/modules/web-map/docker/docker-compose.yml b/modules/web-map/docker/docker-compose.yml index 4527065..f779fde 100644 --- a/modules/web-map/docker/docker-compose.yml +++ b/modules/web-map/docker/docker-compose.yml @@ -3,7 +3,7 @@ version: "3.9" services: kafkatorio-web-map: - image: ${REGISTRY_HOST}/adamko-dev/kafkatorio-web-map:${KAFKATORIO_VERSION} + image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/web-map:${KAFKATORIO_VERSION} container_name: kafkatorio-web-map restart: unless-stopped build: From 3758906bb8b3473ec858d231135e00f3b662423f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 2 Oct 2022 14:51:13 +0200 Subject: [PATCH 538/629] enable pushing of events-server-web docker image --- modules/events-server-web/build.gradle.kts | 4 ++ modules/events-server-web/docker/Dockerfile | 22 +++++++++++ .../docker/docker-compose.yml | 37 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 modules/events-server-web/docker/Dockerfile create mode 100644 modules/events-server-web/docker/docker-compose.yml diff --git a/modules/events-server-web/build.gradle.kts b/modules/events-server-web/build.gradle.kts index a9f506a..57a4d2b 100644 --- a/modules/events-server-web/build.gradle.kts +++ b/modules/events-server-web/build.gradle.kts @@ -90,3 +90,7 @@ val runEventsWebServer by tasks.registering { dependsOn(tasks.run) } + +tasks.dockerComposeBuild { + dependsOn(tasks.distTar) +} diff --git a/modules/events-server-web/docker/Dockerfile b/modules/events-server-web/docker/Dockerfile new file mode 100644 index 0000000..eebdaa0 --- /dev/null +++ b/modules/events-server-web/docker/Dockerfile @@ -0,0 +1,22 @@ +FROM openjdk:11 +ARG KAFKATORIO_VERSION +ARG DIST_DIR="../build/distributions/" +ARG APP_NAME="events-server-web" + +WORKDIR /app + +ENV WEB_SERVER_PORT=80 +EXPOSE $WEB_SERVER_PORT + +ENV SERVER_DATA_DIR="/app/data" +ENV KAFKA_STREAMS_STATE_DIR="/app/state/kafka" + +VOLUME ${SERVER_DATA_DIR} \ + ${KAFKA_STREAMS_STATE_DIR} + +COPY ${DIST_DIR}/${APP_NAME}-${KAFKATORIO_VERSION}.tar ${APP_NAME}.tar + +RUN tar -xf ${APP_NAME}.tar --strip-components=1 \ + && rm ${APP_NAME}.tar + +ENTRYPOINT /app/bin/${APP_NAME} diff --git a/modules/events-server-web/docker/docker-compose.yml b/modules/events-server-web/docker/docker-compose.yml new file mode 100644 index 0000000..c835897 --- /dev/null +++ b/modules/events-server-web/docker/docker-compose.yml @@ -0,0 +1,37 @@ +version: "3.9" + +services: + + events-server-web: + image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/events-server-web:${KAFKATORIO_VERSION} + container_name: events-server-web + restart: unless-stopped + build: + context: .. + dockerfile: ./docker/Dockerfile + args: + KAFKATORIO_VERSION: ${KAFKATORIO_VERSION} + DIST_DIR: "./build/distributions/" + environment: + KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" + # KAFKA_STREAMS_STATE_DIR: "" + WEB_SERVER_PORT: "80" + ports: + - "12080:80" # http and ws + networks: + - "kafka-nw" + - "kafkatorio-nw" + - "traefik-nw" + labels: + - "traefik.enable=true" + +networks: + kafka-nw: + name: "kafka-nw" + external: true + kafkatorio-nw: + name: "kafkatorio-nw" + external: true + traefik-nw: + name: "traefik-nw" + external: true From 0044f0cb9802ef151a3a3515fd76bb48f6060bec Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 4 Oct 2022 22:27:43 +0200 Subject: [PATCH 539/629] create and use APP_NAME, APP_GROUP in docker compose files --- .../src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt | 2 ++ modules/events-processors/docker/Dockerfile | 1 + modules/events-processors/docker/docker-compose.yml | 5 +++-- modules/events-server-syslog/docker/docker-compose.yml | 7 ++++--- modules/events-server-web/docker/docker-compose.yml | 5 +++-- modules/events-server/docker/docker-compose.yml | 5 +++-- modules/infra-kafka-cluster/build.gradle.kts | 1 + modules/infra-kafka-cluster/src/docker-compose.yml | 2 +- modules/infra-kafka-pipe/src/docker-compose.yml | 6 ++++-- modules/web-map/docker/docker-compose.yml | 6 ++++-- 10 files changed, 26 insertions(+), 14 deletions(-) diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt index c5d0e15..9034ad2 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt @@ -83,6 +83,8 @@ abstract class GDCPlugin @Inject constructor( srcDir.convention(layout.projectDirectory.dir("docker")) dotEnv.put("COMPOSE_PROJECT_NAME", composeProjectName) + dotEnv.put("APP_NAME", providers.provider { project.name }) + dotEnv.put("APP_GROUP", providers.provider { project.group.toString() }) dotEnv.put("PROJECT_VERSION", composeProjectVersion) dotEnv.put("KAFKATORIO_VERSION", composeProjectVersion) dotEnv.put("REGISTRY_HOST", containerRegistryHost) diff --git a/modules/events-processors/docker/Dockerfile b/modules/events-processors/docker/Dockerfile index 7d3a795..a081b85 100644 --- a/modules/events-processors/docker/Dockerfile +++ b/modules/events-processors/docker/Dockerfile @@ -3,6 +3,7 @@ FROM eclipse-temurin:11-jdk-jammy ARG KAFKATORIO_VERSION=0.5.1 ARG DIST_DIR="../build/distributions/" +ARG APP_NAME="events-server-web" WORKDIR /app diff --git a/modules/events-processors/docker/docker-compose.yml b/modules/events-processors/docker/docker-compose.yml index e871820..47d753a 100644 --- a/modules/events-processors/docker/docker-compose.yml +++ b/modules/events-processors/docker/docker-compose.yml @@ -3,8 +3,8 @@ version: "3.9" services: events-server: - image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/events-processors:${KAFKATORIO_VERSION} - container_name: events-server + image: ${REGISTRY_HOST}/${APP_GROUP}/${APP_NAME}:${KAFKATORIO_VERSION} + container_name: ${APP_NAME} restart: unless-stopped build: context: .. @@ -12,6 +12,7 @@ services: args: KAFKATORIO_VERSION: ${KAFKATORIO_VERSION} DIST_DIR: "./build/distributions/" + APP_NAME: ${APP_NAME} environment: KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" # KAFKA_STREAMS_STATE_DIR: "" diff --git a/modules/events-server-syslog/docker/docker-compose.yml b/modules/events-server-syslog/docker/docker-compose.yml index cecaf6d..b33295c 100644 --- a/modules/events-server-syslog/docker/docker-compose.yml +++ b/modules/events-server-syslog/docker/docker-compose.yml @@ -2,9 +2,9 @@ version: "3.9" services: - events-server: - image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/events-server-syslog:${KAFKATORIO_VERSION} - container_name: events-server + events-server-syslog: + image: ${REGISTRY_HOST}/${APP_GROUP}/${APP_NAME}:${KAFKATORIO_VERSION} + container_name: ${APP_NAME} restart: unless-stopped build: context: .. @@ -12,6 +12,7 @@ services: args: KAFKATORIO_VERSION: ${KAFKATORIO_VERSION} DIST_DIR: "./build/distributions/" + APP_NAME: ${APP_NAME} environment: KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" # KAFKA_STREAMS_STATE_DIR: "" diff --git a/modules/events-server-web/docker/docker-compose.yml b/modules/events-server-web/docker/docker-compose.yml index c835897..e8ec9a7 100644 --- a/modules/events-server-web/docker/docker-compose.yml +++ b/modules/events-server-web/docker/docker-compose.yml @@ -3,8 +3,8 @@ version: "3.9" services: events-server-web: - image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/events-server-web:${KAFKATORIO_VERSION} - container_name: events-server-web + image: ${REGISTRY_HOST}/${APP_GROUP}/${APP_NAME}:${KAFKATORIO_VERSION} + container_name: ${APP_NAME} restart: unless-stopped build: context: .. @@ -12,6 +12,7 @@ services: args: KAFKATORIO_VERSION: ${KAFKATORIO_VERSION} DIST_DIR: "./build/distributions/" + APP_NAME: ${APP_NAME} environment: KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" # KAFKA_STREAMS_STATE_DIR: "" diff --git a/modules/events-server/docker/docker-compose.yml b/modules/events-server/docker/docker-compose.yml index 9fa071b..47d753a 100644 --- a/modules/events-server/docker/docker-compose.yml +++ b/modules/events-server/docker/docker-compose.yml @@ -3,8 +3,8 @@ version: "3.9" services: events-server: - image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/events-server:${KAFKATORIO_VERSION} - container_name: events-server + image: ${REGISTRY_HOST}/${APP_GROUP}/${APP_NAME}:${KAFKATORIO_VERSION} + container_name: ${APP_NAME} restart: unless-stopped build: context: .. @@ -12,6 +12,7 @@ services: args: KAFKATORIO_VERSION: ${KAFKATORIO_VERSION} DIST_DIR: "./build/distributions/" + APP_NAME: ${APP_NAME} environment: KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" # KAFKA_STREAMS_STATE_DIR: "" diff --git a/modules/infra-kafka-cluster/build.gradle.kts b/modules/infra-kafka-cluster/build.gradle.kts index 3f6866b..e5abad0 100644 --- a/modules/infra-kafka-cluster/build.gradle.kts +++ b/modules/infra-kafka-cluster/build.gradle.kts @@ -16,6 +16,7 @@ tasks.dockerComposeEnvUpdate { put("KAFKA_DL_URL", libs.versions.kafka.map { ver -> "https://dlcdn.apache.org/kafka/$ver/kafka_2.13-$ver.tgz" }) + put("APP_NAME", "kafka-kraft") } // Limit JVM Heap Size diff --git a/modules/infra-kafka-cluster/src/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml index 359f741..10764ad 100644 --- a/modules/infra-kafka-cluster/src/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -3,7 +3,7 @@ version: "3.9" services: kafka: - image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/kafka-kraft:${KAFKA_VERSION} + image: ${REGISTRY_HOST}/${APP_GROUP}/${APP_NAME}:${KAFKATORIO_VERSION} container_name: "kafka" restart: "unless-stopped" build: diff --git a/modules/infra-kafka-pipe/src/docker-compose.yml b/modules/infra-kafka-pipe/src/docker-compose.yml index 6f34f3a..a564e8a 100644 --- a/modules/infra-kafka-pipe/src/docker-compose.yml +++ b/modules/infra-kafka-pipe/src/docker-compose.yml @@ -2,11 +2,13 @@ version: "3.9" services: kafka-pipe: - image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/kafka-pipe/${KAFKATORIO_VERSION} - container_name: "kafka-pipe" + image: ${REGISTRY_HOST}/${APP_GROUP}/${APP_NAME}:${KAFKATORIO_VERSION} + container_name: ${APP_NAME} build: dockerfile: "kafka-pipe.Dockerfile" context: "." + args: + APP_NAME: ${APP_NAME} restart: "unless-stopped" privileged: true networks: diff --git a/modules/web-map/docker/docker-compose.yml b/modules/web-map/docker/docker-compose.yml index f779fde..6e5cf80 100644 --- a/modules/web-map/docker/docker-compose.yml +++ b/modules/web-map/docker/docker-compose.yml @@ -3,12 +3,14 @@ version: "3.9" services: kafkatorio-web-map: - image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/web-map:${KAFKATORIO_VERSION} - container_name: kafkatorio-web-map + image: ${REGISTRY_HOST}/${APP_GROUP}/${APP_NAME}:${KAFKATORIO_VERSION} + container_name: ${APP_NAME} restart: unless-stopped build: context: ".." dockerfile: ./docker/Dockerfile + args: + APP_NAME: ${APP_NAME} ports: - "12081:80" networks: From 562296aa965b4400d9858a7a3d8193a61197da3a Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 4 Oct 2022 22:28:04 +0200 Subject: [PATCH 540/629] Dockerfiles: add syntax=docker header --- modules/events-server-syslog/docker/Dockerfile | 2 ++ modules/events-server-web/docker/Dockerfile | 2 ++ .../factorio-and-kpipe-server/factorioEvents.Dockerfile | 2 ++ modules/infra-kafka-cluster/src/kafka.Dockerfile | 2 ++ modules/infra-kafka-pipe/src/kafka-pipe.Dockerfile | 2 ++ modules/web-map/docker/Dockerfile | 2 ++ 6 files changed, 12 insertions(+) diff --git a/modules/events-server-syslog/docker/Dockerfile b/modules/events-server-syslog/docker/Dockerfile index 46acc9e..0f11857 100644 --- a/modules/events-server-syslog/docker/Dockerfile +++ b/modules/events-server-syslog/docker/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + FROM openjdk:11 ARG KAFKATORIO_VERSION ARG DIST_DIR="../build/distributions/" diff --git a/modules/events-server-web/docker/Dockerfile b/modules/events-server-web/docker/Dockerfile index eebdaa0..e25170b 100644 --- a/modules/events-server-web/docker/Dockerfile +++ b/modules/events-server-web/docker/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + FROM openjdk:11 ARG KAFKATORIO_VERSION ARG DIST_DIR="../build/distributions/" diff --git a/modules/infra-factorio-server/factorio-and-kpipe-server/factorioEvents.Dockerfile b/modules/infra-factorio-server/factorio-and-kpipe-server/factorioEvents.Dockerfile index 7c24909..4e639bd 100644 --- a/modules/infra-factorio-server/factorio-and-kpipe-server/factorioEvents.Dockerfile +++ b/modules/infra-factorio-server/factorio-and-kpipe-server/factorioEvents.Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + ARG factorioVersion=1.1.42 diff --git a/modules/infra-kafka-cluster/src/kafka.Dockerfile b/modules/infra-kafka-cluster/src/kafka.Dockerfile index 7670ec8..0a5e1b7 100644 --- a/modules/infra-kafka-cluster/src/kafka.Dockerfile +++ b/modules/infra-kafka-cluster/src/kafka.Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + ARG KAFKA_DL_URL=https://dlcdn.apache.org/kafka/3.1.0/kafka_2.13-3.1.0.tgz ## builder ## diff --git a/modules/infra-kafka-pipe/src/kafka-pipe.Dockerfile b/modules/infra-kafka-pipe/src/kafka-pipe.Dockerfile index 02f8881..2b6b849 100644 --- a/modules/infra-kafka-pipe/src/kafka-pipe.Dockerfile +++ b/modules/infra-kafka-pipe/src/kafka-pipe.Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + FROM docker:dind-rootless ENV FACTORIO_SERVER_CONTAINER_NAME="factorio-server" diff --git a/modules/web-map/docker/Dockerfile b/modules/web-map/docker/Dockerfile index f72c386..c62fa29 100644 --- a/modules/web-map/docker/Dockerfile +++ b/modules/web-map/docker/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1 + FROM nginx COPY ./docker/nginx.conf /etc/nginx/nginx.conf From 002aa9b5fbcb4ceb0d9a510642b0ddfb93d86461 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 4 Oct 2022 22:32:05 +0200 Subject: [PATCH 541/629] tidy up dockerActive property & check --- .../dev/adamko/geedeecee/GDCCommandTask.kt | 32 +++++++++++++++---- .../kotlin/dev/adamko/geedeecee/GDCPlugin.kt | 3 +- .../dev/adamko/geedeecee/GDCSettings.kt | 2 +- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt index 1693581..4596442 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt @@ -2,9 +2,11 @@ package dev.adamko.geedeecee import javax.inject.Inject import org.gradle.api.DefaultTask +import org.gradle.api.Task import org.gradle.api.file.DirectoryProperty import org.gradle.api.logging.LogLevel import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.Property import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.TaskAction @@ -15,19 +17,26 @@ abstract class GDCCommandTask @Inject constructor( private val executor: ExecOperations ) : DefaultTask() { - init { - super.setGroup(GDCPlugin.GCD_TASK_GROUP) - description = "Run a docker-compose command." - - logging.captureStandardOutput(LogLevel.LIFECYCLE) - } - @get:InputDirectory abstract val workingDir: DirectoryProperty @get:Input abstract val separatedArgs: ListProperty + @get:Input + abstract val dockerActive: Property + + init { + super.setGroup(GDCPlugin.GCD_TASK_GROUP) + description = "Run a docker-compose command." + + enabledIf { + it.dockerActive.orNull == true + } + + logging.captureStandardOutput(LogLevel.LIFECYCLE) + } + @TaskAction fun dockerCompose() { val separatedArgs: List = separatedArgs.get() @@ -45,4 +54,13 @@ abstract class GDCCommandTask @Inject constructor( parseSpaceSeparatedArgs("docker-compose $args") ) } + + companion object { + private inline fun T.enabledIf(crossinline spec: (T) -> Boolean) { + onlyIf { + require(it is T) + spec(it) + } + } + } } diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt index 9034ad2..e1ca252 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt @@ -60,6 +60,7 @@ abstract class GDCPlugin @Inject constructor( target.tasks.withType().configureEach { workingDir.convention(gdcSettings.srcDir) dependsOn(dockerComposeEnvUpdate) + dockerActive.set(gdcSettings.dockerActive) } val assembleTasks = target.tasks.matching { LifecycleBasePlugin.ASSEMBLE_TASK_NAME == it.name } @@ -89,7 +90,7 @@ abstract class GDCPlugin @Inject constructor( dotEnv.put("KAFKATORIO_VERSION", composeProjectVersion) dotEnv.put("REGISTRY_HOST", containerRegistryHost) - enabled.convention(isDockerActive()) + dockerActive.convention(isDockerActive()) } diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCSettings.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCSettings.kt index 238c106..c11c427 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCSettings.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCSettings.kt @@ -24,7 +24,7 @@ interface GDCSettings { val dotEnv: MapProperty @get:Input - val enabled: Property + val dockerActive: Property // @Suppress("PropertyName", "FunctionName") // abstract class DotEnv( From b61ee6bf5c823133f6f816ca6c17a9a3b529455e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 4 Oct 2022 22:38:00 +0200 Subject: [PATCH 542/629] apply geedeecee plugin, or update config. Update kvision dependency helper. --- modules/events-processors/build.gradle.kts | 6 ++- modules/events-server-syslog/build.gradle.kts | 4 ++ modules/web-map/build.gradle.kts | 52 +++++++------------ 3 files changed, 28 insertions(+), 34 deletions(-) diff --git a/modules/events-processors/build.gradle.kts b/modules/events-processors/build.gradle.kts index 3134526..37ea412 100644 --- a/modules/events-processors/build.gradle.kts +++ b/modules/events-processors/build.gradle.kts @@ -2,6 +2,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("kafkatorio.conventions.lang.kotlin-jvm") + id("dev.adamko.geedeecee") kotlin("plugin.serialization") application } @@ -75,7 +76,6 @@ tasks.withType().configureEach { //} tasks.named("run") { - val kafkaStateDir: Directory = layout.projectDirectory.dir(".state/kafka/") doFirst { @@ -89,3 +89,7 @@ val runEventsProcessors by tasks.registering { dependsOn(tasks.run) } + +tasks.dockerComposeBuild { + dependsOn(tasks.distTar) +} diff --git a/modules/events-server-syslog/build.gradle.kts b/modules/events-server-syslog/build.gradle.kts index 8d1bad2..ca3a7ed 100644 --- a/modules/events-server-syslog/build.gradle.kts +++ b/modules/events-server-syslog/build.gradle.kts @@ -87,3 +87,7 @@ val runSyslogServer by tasks.registering { group = rootProject.name dependsOn(tasks.run) } + +tasks.dockerComposeBuild { + dependsOn(tasks.distTar) +} diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 821be54..f2582c3 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -1,6 +1,6 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig -import dev.adamko.geedeecee.DockerEnvUpdateTask.Companion.put + plugins { id("kafkatorio.conventions.lang.kotlin-js") @@ -75,18 +75,18 @@ kotlin { implementation(libs.kotlinx.nodejs) implementation(libs.kotlinx.html) - kvision("kvision") - kvision("kvision-bootstrap") - kvision("kvision-bootstrap-css") - kvision("kvision-bootstrap-icons") - kvision("kvision-fontawesome") - kvision("kvision-state") - kvision("kvision-chart") - kvision("kvision-maps") - kvision("kvision-rest") - kvision("kvision-redux") - kvision("kvision-state-flow") - kvision("kvision-routing-navigo-ng") + implementation(kvision()) + implementation(kvision("bootstrap")) + implementation(kvision("bootstrap-css")) + implementation(kvision("bootstrap-icons")) + implementation(kvision("fontawesome")) + implementation(kvision("state")) + implementation(kvision("chart")) + implementation(kvision("maps")) + implementation(kvision("rest")) + implementation(kvision("redux")) + implementation(kvision("state-flow")) + implementation(kvision("routing-navigo-ng")) } resources.srcDir("src/main/web") @@ -97,7 +97,7 @@ kotlin { dependencies { implementation(kotlin("test")) - kvision("kvision-testutils") + implementation(kvision("testutils")) // implementation(npm("karma", "^6.3.16")) } } @@ -105,29 +105,15 @@ kotlin { } +@Suppress("UnusedReceiverParameter") // just for scoping - this function doesn't need to be used everywhere fun KotlinDependencyHandler.kvision( - module: String, + module: String? = null, version: Provider = libs.versions.kvision, - configure: ExternalModuleDependency.() -> Unit = { -// isChanging = true - } -) { - implementation("io.kvision:$module:${version.get()}", configure) +): String { + val prefixedModule = if (module == null) "kvision" else "kvision-$module" + return "io.kvision:$prefixedModule:${version.get()}" } -geedeecee { - srcDir.set(layout.projectDirectory.dir("docker")) -} - -tasks.dockerComposeEnvUpdate { - envProperties { - put("KAFKATORIO_VERSION" to project.version.toString()) - put("REGISTRY_HOST" to "dcr.adamko.dev:5000") - } -} - -tasks.assemble { dependsOn(tasks.dockerComposeEnvUpdate) } - val installThemeCss by tasks.registering(Copy::class) { val bootswatchThemeMinCss = resources.text.fromUri( From 579c9d1c1a2b2a95027e0d6c1de2bcf43d79332d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 4 Oct 2022 23:00:09 +0200 Subject: [PATCH 543/629] versions bump --- .../builder-plugins/build.gradle.kts | 13 +++++-- gradle/libs.versions.toml | 36 ++++++++++--------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/gradle-plugins/builder-plugins/build.gradle.kts b/gradle-plugins/builder-plugins/build.gradle.kts index bd5b119..9708397 100644 --- a/gradle-plugins/builder-plugins/build.gradle.kts +++ b/gradle-plugins/builder-plugins/build.gradle.kts @@ -25,9 +25,9 @@ dependencies { implementation(platform(libs.kotest.bom)) implementation("io.kotest:kotest-framework-multiplatform-plugin-gradle") - implementation("io.kvision:io.kvision.gradle.plugin:${libs.versions.kvision.get()}") + implementation(libs.gradlePlugin.kvision) - implementation("net.swiftzer.semver:semver:${libs.versions.semver.get()}") + implementation(libs.semver) implementation(platform(libs.okio.bom)) implementation(libs.okio.core) @@ -35,6 +35,15 @@ dependencies { implementation(libs.kotlinx.cli) } + +tasks.withType().configureEach { + kotlinOptions.freeCompilerArgs += listOf( + "-opt-in=kotlin.ExperimentalStdlibApi", + "-opt-in=kotlin.time.ExperimentalTime", + "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", + ) +} + //val gradleJvmTarget = "11" // //kotlin { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1a52747..52dc66c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,8 +11,8 @@ kotlin = "1.7.20" ## libs ## camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" -kafka = "3.2.3" # https://kafka.apache.org/downloads -kvision = "5.15.2" # https://github.com/rjaros/kvision/releases +kafka = "3.3.1" # https://kafka.apache.org/downloads +kvision = "5.15.3" # https://github.com/rjaros/kvision/releases log4j2 = "2.17.2" okio = "3.2.0" # https://search.maven.org/artifact/com.squareup.okio/okio qosLogback = "1.2.11" @@ -25,7 +25,7 @@ kxs-charleskornKaml = "0.44.0" kxs-mamoeYamlkt = "0.12.0" kxs-kxsTsGen = "0.2.1" -kotlinJsWrappers = "1.0.0-pre.387" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom +kotlinJsWrappers = "1.0.0-pre.399" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom kotlinx-cli = "0.3.4" kotlinx-coroutines = "1.6.4" # https://github.com/Kotlin/kotlinx.coroutines/releases @@ -35,38 +35,37 @@ kotlinx-nodejs = "0.0.7" kSvgDsl = "v2.2.0" -ktor = "2.1.1" # https://github.com/ktorio/ktor/releases +ktor = "2.1.2" # https://github.com/ktorio/ktor/releases -hoplite = "2.6.2" # https://github.com/sksamuel/hoplite/releases +hoplite = "2.6.4" # https://github.com/sksamuel/hoplite/releases simpleSyslogParser = "1.0.0" # https://search.maven.org/artifact/com.github.palindromicity/simple-syslog kotkaStreams = "22.08.06" -marykRocksDb = "7.3.1-1" # https://search.maven.org/artifact/io.maryk.rocksdb/rocksdb-multiplatform +marykRocksDb = "7.3.1-2" # https://search.maven.org/artifact/io.maryk.rocksdb/rocksdb-multiplatform klogging = "0.4.9" -nimbusJoseJwt = "9.25" # https://search.maven.org/artifact/com.nimbusds/nimbus-jose-jwt +nimbusJoseJwt = "9.25.4" # https://search.maven.org/artifact/com.nimbusds/nimbus-jose-jwt ## npm ## npm-luaTypes = "2.13.0" # https://www.npmjs.com/package/lua-types -npm-typescriptToLua = "1.10.0" # https://www.npmjs.com/package/typescript-to-lua -npm-typedFactorio = "1.7.5" # https://www.npmjs.com/package/typed-factorio -npm-typescript = "4.8.3" # https://github.com/microsoft/TypeScript/releases +npm-typescriptToLua = "1.10.1" # https://www.npmjs.com/package/typescript-to-lua +npm-typedFactorio = "1.8.1" # https://www.npmjs.com/package/typed-factorio +npm-typescript = "4.8.4" # https://github.com/microsoft/TypeScript/releases -npm-bootswatch = "5.2.1" # https://www.jsdelivr.com/package/npm/bootswatch +npm-bootswatch = "5.2.1" # https://www.jsdelivr.com/package/npm/bootswatch ## test ## -junit = "5.9.0" # https://github.com/junit-team/junit5/releases -#kotest = "5.4.2" -kotest = "5.5.0-LOCAL" -mockk = "1.12.8" # https://github.com/mockk/mockk/releases/ +junit = "5.9.1" # https://github.com/junit-team/junit5/releases +kotest = "5.5.0" # https://github.com/kotest/kotest/releases +mockk = "1.13.2" # https://github.com/mockk/mockk/releases/ ## infra ## -factorio = "1.1.68" +factorio = "1.1.69" # https://www.factorio.com/download confluent-kafkaConnect = "7.0.1" grafana = "8.5.0" prometheus = "v2.34.0" @@ -278,6 +277,11 @@ http4k-test-chaos = { group = "org.http4k", name = "http4k-testing-chaos", http4k-test-approval = { group = "org.http4k", name = "http4k-testing-approval", version.ref = "http4k" } http4k-test-kotest = { group = "org.http4k", name = "http4k-testing-kotest", version.ref = "http4k" } +################ +### plugins ### +################ + +gradlePlugin-kvision = { module = "io.kvision:io.kvision.gradle.plugin", version.ref = "kvision" } ######### [bundles] From d16aedda591b52a28649ebf739951019857e820c Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 4 Oct 2022 23:47:16 +0200 Subject: [PATCH 544/629] fix typescriptAttributes --- buildSrc/src/main/kotlin/extensions.kt | 10 +++++----- modules/events-library/build.gradle.kts | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/buildSrc/src/main/kotlin/extensions.kt b/buildSrc/src/main/kotlin/extensions.kt index 52b96c9..83020f8 100644 --- a/buildSrc/src/main/kotlin/extensions.kt +++ b/buildSrc/src/main/kotlin/extensions.kt @@ -18,8 +18,8 @@ fun Configuration.asConsumer() { isCanBeResolved = true isCanBeConsumed = false } - -fun Configuration.typescriptAttributes(objects: ObjectFactory): Configuration = - attributes { - attribute(Usage.USAGE_ATTRIBUTE, objects.named("dev.adamko.gradle.factorio.typescriptFiles")) - } +// +//fun Configuration.typescriptAttributes(objects: ObjectFactory): Configuration = +// attributes { +// attribute(Usage.USAGE_ATTRIBUTE, objects.named("dev.adamko.gradle.factorio.typescriptFiles")) +// } diff --git a/modules/events-library/build.gradle.kts b/modules/events-library/build.gradle.kts index 31ae1c0..2236884 100644 --- a/modules/events-library/build.gradle.kts +++ b/modules/events-library/build.gradle.kts @@ -2,11 +2,12 @@ import kafkatorio.tasks.GenerateTypeScriptTask import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import dev.adamko.gradle.factorio.typescriptAttributes plugins { id("kafkatorio.conventions.lang.kotlin-multiplatform") - id("dev.adamko.factorio-mod") // only needed for 'attributes' - need to split up the mod? + id("dev.adamko.factorio-mod") apply false // only needed for 'attributes' - need to split up the plugin? kotlin("plugin.serialization") distribution } From 3f49a6504bc373d95ef8bc32b6b176da79572a78 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 4 Oct 2022 23:47:30 +0200 Subject: [PATCH 545/629] fix geedeecee config --- .../src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt | 4 ++++ modules/infra-kafka-pipe/build.gradle.kts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt index e1ca252..19f0579 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt @@ -57,6 +57,10 @@ abstract class GDCPlugin @Inject constructor( dockerComposeUp.configure { dependsOn(dockerComposeBuild) } dockerComposeRemove.configure { dependsOn(dockerComposeDown) } + target.tasks.withType().configureEach { + dependsOn(dockerComposeEnvUpdate) + } + target.tasks.withType().configureEach { workingDir.convention(gdcSettings.srcDir) dependsOn(dockerComposeEnvUpdate) diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index 132a027..26bedde 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -7,6 +7,10 @@ plugins { description = "Send events from a Factorio server to a Kafka topic " +geedeecee { + srcDir.set(layout.projectDirectory.dir("src")) +} + //val dockerSrcDir: Directory by extra tasks.dockerComposeUp { From 144cbba075ab6c439b7e39cea477aaf2d8b046be Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 4 Oct 2022 23:47:51 +0200 Subject: [PATCH 546/629] update package.json versions --- modules/events-mod/package-lock.json | 18 +++++++++--------- modules/events-mod/package.json | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 411f557..419d03c 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -80,19 +80,19 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.7.5.tgz", - "integrity": "sha512-3lTeV8FkmLx7mUUhUp1WPhIDviiqPOfibHYIjE58Lt59mN0ujEDbf7q3o9G8YWjmvgBatS9xJ81a+/Tvq20mUw==" + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.8.1.tgz", + "integrity": "sha512-qqSPGfQawq5e25+cf/rajTeyeQ0zQyyiVbVlBE4NYW7MSzK8ZEKH5JwuJsro8cZAmZMXqvX2V1uzCgnD9orLaw==" }, "typescript": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz", - "integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==" + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==" }, "typescript-to-lua": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.10.0.tgz", - "integrity": "sha512-rt+Bb2hH3FqytqTmTqOL+xPFRcV/r4TZ5X+46vVSfw9luzbu9V6ai5yyU8GePARVcf5hGvCv+DqxBNQtdcJLsA==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.10.1.tgz", + "integrity": "sha512-R6KQc1YzFcejyaZ9tAvVK0MFTlRS1b10vON5sxjtGVSUWl+W4KRLik0LDCgKfI0wnDQH+LNVnKBNUsBfTtEoQQ==", "requires": { "@typescript-to-lua/language-extensions": "1.0.0", "enhanced-resolve": "^5.8.2", diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index a3dbf50..1bc7eb7 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -12,9 +12,9 @@ "devDependencies": {}, "dependencies": { "lua-types": "2.13.0", - "typescript-to-lua": "1.10.0", - "typed-factorio": "1.7.5", - "typescript": "4.8.3" + "typescript-to-lua": "1.10.1", + "typed-factorio": "1.8.1", + "typescript": "4.8.4" }, "license": "UNLICENSED", "peerDependencies": {}, From 989b95e3a079975595a7d4cb79d15a1d07b87b0f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 5 Oct 2022 00:06:46 +0200 Subject: [PATCH 547/629] adjust geedeecee config, so images can be built --- .../src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt | 2 +- modules/infra-factorio-server/build.gradle.kts | 10 ++++++++-- modules/infra-kafka-cluster/build.gradle.kts | 1 + modules/infra-kafka-pipe/build.gradle.kts | 1 + modules/versions-platform/build.gradle.kts | 1 + 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt index 19f0579..2e78878 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt @@ -26,7 +26,7 @@ abstract class GDCPlugin @Inject constructor( val dockerComposeEnvUpdate by target.tasks.registering(DockerEnvUpdateTask::class) { dotEnvFile.set(gdcSettings.srcDir.file(".env")) - envProperties.convention(gdcSettings.dotEnv) + envProperties.putAll(gdcSettings.dotEnv) // properties( // "COMPOSE_PROJECT_NAME" to gdcSettings.composeProjectName, // "KAFKATORIO_VERSION" to gdcSettings.composeProjectVersion, diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index f94e4c2..1aa8bea 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -1,12 +1,18 @@ import dev.adamko.gradle.factorio.FactorioModPlugin plugins { + id("kafkatorio.conventions.base") id("dev.adamko.geedeecee") id("dev.adamko.factorio-mod") idea } +geedeecee { + srcDir.set(layout.projectDirectory.dir("src")) +} + + //val dockerSrcDir: Directory by extra //val factorioServerDataDir: Directory = dockerSrcDir.dir("factorio-server") val factorioServerDataDir: DirectoryProperty = objects.directoryProperty() @@ -62,8 +68,8 @@ tasks.dockerComposeEnvUpdate { envProperties.put("FACTORIO_VERSION", libs.versions.factorio) envProperties.put("KAFKATORIO_TOKEN", kafkatorioServerToken) envProperties { - put("FACTORIO_VERSION" , libs.versions.factorio) - put("KAFKATORIO_TOKEN" , kafkatorioServerToken) + put("FACTORIO_VERSION", libs.versions.factorio) + put("KAFKATORIO_TOKEN", kafkatorioServerToken) } } diff --git a/modules/infra-kafka-cluster/build.gradle.kts b/modules/infra-kafka-cluster/build.gradle.kts index e5abad0..d968456 100644 --- a/modules/infra-kafka-cluster/build.gradle.kts +++ b/modules/infra-kafka-cluster/build.gradle.kts @@ -1,4 +1,5 @@ plugins { + id("kafkatorio.conventions.base") id("dev.adamko.geedeecee") } diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index 26bedde..e7ecb5b 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -1,6 +1,7 @@ import dev.adamko.geedeecee.DockerComposeExec plugins { + id("kafkatorio.conventions.base") id("dev.adamko.geedeecee") } diff --git a/modules/versions-platform/build.gradle.kts b/modules/versions-platform/build.gradle.kts index 3b2c234..7368657 100644 --- a/modules/versions-platform/build.gradle.kts +++ b/modules/versions-platform/build.gradle.kts @@ -1,4 +1,5 @@ plugins { + id("kafkatorio.conventions.base") `java-platform` } From 6507f13462296ceca6e48eab24a756f4f9fa472b Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 5 Oct 2022 08:52:39 +0200 Subject: [PATCH 548/629] fix docker image building --- modules/events-processors/docker/Dockerfile | 16 +++++----------- .../events-processors/docker/docker-compose.yml | 2 +- modules/events-server-syslog/docker/Dockerfile | 2 +- modules/web-map/build.gradle.kts | 4 ++++ 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/modules/events-processors/docker/Dockerfile b/modules/events-processors/docker/Dockerfile index a081b85..fcc32cc 100644 --- a/modules/events-processors/docker/Dockerfile +++ b/modules/events-processors/docker/Dockerfile @@ -3,24 +3,18 @@ FROM eclipse-temurin:11-jdk-jammy ARG KAFKATORIO_VERSION=0.5.1 ARG DIST_DIR="../build/distributions/" -ARG APP_NAME="events-server-web" +ARG APP_NAME="events-processors" WORKDIR /app -ENV WEB_SERVER_PORT=8080 -EXPOSE $WEB_SERVER_PORT - -ENV SOCKET_SERVER_PORT=9002 -EXPOSE $SOCKET_SERVER_PORT - ENV SERVER_DATA_DIR="/app/data" ENV KAFKA_STREAMS_STATE_DIR="/app/state/kafka" VOLUME ${SERVER_DATA_DIR} \ ${KAFKA_STREAMS_STATE_DIR} -COPY ${DIST_DIR}/events-server-${KAFKATORIO_VERSION}.tar events-server.tar +COPY ${DIST_DIR}/${APP_NAME}-${KAFKATORIO_VERSION}.tar ${APP_NAME}.tar -RUN tar -xf events-server.tar --strip-components=1 \ - && rm events-server.tar +RUN tar -xf ${APP_NAME}.tar --strip-components=1 \ + && rm ${APP_NAME}.tar -ENTRYPOINT /app/bin/events-server +ENTRYPOINT /app/bin/${APP_NAME} diff --git a/modules/events-processors/docker/docker-compose.yml b/modules/events-processors/docker/docker-compose.yml index 47d753a..87087e5 100644 --- a/modules/events-processors/docker/docker-compose.yml +++ b/modules/events-processors/docker/docker-compose.yml @@ -2,7 +2,7 @@ version: "3.9" services: - events-server: + events-processors: image: ${REGISTRY_HOST}/${APP_GROUP}/${APP_NAME}:${KAFKATORIO_VERSION} container_name: ${APP_NAME} restart: unless-stopped diff --git a/modules/events-server-syslog/docker/Dockerfile b/modules/events-server-syslog/docker/Dockerfile index 0f11857..acbdf9f 100644 --- a/modules/events-server-syslog/docker/Dockerfile +++ b/modules/events-server-syslog/docker/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -FROM openjdk:11 +FROM eclipse-temurin:11-jdk-jammy ARG KAFKATORIO_VERSION ARG DIST_DIR="../build/distributions/" ARG APP_NAME="events-server-syslog" diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index f2582c3..7c757d6 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -138,3 +138,7 @@ val runWebMap by tasks.registering { dependsOn(tasks.matching { it.name == "browserDevelopmentRun" }) } + +tasks.dockerComposeBuild { + dependsOn(tasks.zip) +} From 4c5ed2dc73b8db62dbf8286460c512f603455b0d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Oct 2022 13:05:24 +0200 Subject: [PATCH 549/629] give +x to docker apps, tidy up docker conf --- modules/events-processors/docker/Dockerfile | 3 ++- modules/events-processors/docker/docker-compose.yml | 5 ----- modules/events-server-syslog/docker/Dockerfile | 3 ++- modules/events-server-syslog/docker/docker-compose.yml | 1 - modules/events-server-web/docker/Dockerfile | 3 ++- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/modules/events-processors/docker/Dockerfile b/modules/events-processors/docker/Dockerfile index fcc32cc..cce46b6 100644 --- a/modules/events-processors/docker/Dockerfile +++ b/modules/events-processors/docker/Dockerfile @@ -15,6 +15,7 @@ VOLUME ${SERVER_DATA_DIR} \ COPY ${DIST_DIR}/${APP_NAME}-${KAFKATORIO_VERSION}.tar ${APP_NAME}.tar RUN tar -xf ${APP_NAME}.tar --strip-components=1 \ - && rm ${APP_NAME}.tar + && rm ${APP_NAME}.tar \ + && chmod +x /app/bin/${APP_NAME} \ ENTRYPOINT /app/bin/${APP_NAME} diff --git a/modules/events-processors/docker/docker-compose.yml b/modules/events-processors/docker/docker-compose.yml index 87087e5..9091b44 100644 --- a/modules/events-processors/docker/docker-compose.yml +++ b/modules/events-processors/docker/docker-compose.yml @@ -16,11 +16,6 @@ services: environment: KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" # KAFKA_STREAMS_STATE_DIR: "" - SERVER_PORT: "8080" - SOCKET_SERVER_PORT: "9002" - ports: - - "12080:8080" # http and ws - - "12034:9002" # syslog socket networks: - "kafka-nw" - "kafkatorio-nw" diff --git a/modules/events-server-syslog/docker/Dockerfile b/modules/events-server-syslog/docker/Dockerfile index acbdf9f..15d499c 100644 --- a/modules/events-server-syslog/docker/Dockerfile +++ b/modules/events-server-syslog/docker/Dockerfile @@ -19,6 +19,7 @@ VOLUME ${SERVER_DATA_DIR} \ COPY ${DIST_DIR}/${APP_NAME}-${KAFKATORIO_VERSION}.tar ${APP_NAME}.tar RUN tar -xf ${APP_NAME}.tar --strip-components=1 \ - && rm ${APP_NAME}.tar + && rm ${APP_NAME}.tar \ + && chmod +x /app/bin/${APP_NAME} ENTRYPOINT /app/bin/${APP_NAME} diff --git a/modules/events-server-syslog/docker/docker-compose.yml b/modules/events-server-syslog/docker/docker-compose.yml index b33295c..855f34b 100644 --- a/modules/events-server-syslog/docker/docker-compose.yml +++ b/modules/events-server-syslog/docker/docker-compose.yml @@ -19,7 +19,6 @@ services: SERVER_PORT: "8080" SOCKET_SERVER_PORT: "9002" ports: - - "12080:8080" # http and ws - "12034:9002" # syslog socket networks: - "kafka-nw" diff --git a/modules/events-server-web/docker/Dockerfile b/modules/events-server-web/docker/Dockerfile index e25170b..af0fafc 100644 --- a/modules/events-server-web/docker/Dockerfile +++ b/modules/events-server-web/docker/Dockerfile @@ -19,6 +19,7 @@ VOLUME ${SERVER_DATA_DIR} \ COPY ${DIST_DIR}/${APP_NAME}-${KAFKATORIO_VERSION}.tar ${APP_NAME}.tar RUN tar -xf ${APP_NAME}.tar --strip-components=1 \ - && rm ${APP_NAME}.tar + && rm ${APP_NAME}.tar \ + && chmod +x /app/bin/${APP_NAME} ENTRYPOINT /app/bin/${APP_NAME} From 8e184def4e5018fbf224093e305d74057642bf19 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Oct 2022 13:05:31 +0200 Subject: [PATCH 550/629] bump version 0.9.1 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 078d29c..9a3d775 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.9.0" +version = "0.9.1" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) From 18bdfb70b1bb5a9f4fbc55eef4ba2561c3c1c612 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Oct 2022 13:50:16 +0200 Subject: [PATCH 551/629] fix dockerfile entrypoint run script --- modules/events-processors/docker/Dockerfile | 5 +++-- modules/events-server-syslog/docker/Dockerfile | 5 +++-- modules/events-server-web/docker/Dockerfile | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/events-processors/docker/Dockerfile b/modules/events-processors/docker/Dockerfile index cce46b6..ab48826 100644 --- a/modules/events-processors/docker/Dockerfile +++ b/modules/events-processors/docker/Dockerfile @@ -16,6 +16,7 @@ COPY ${DIST_DIR}/${APP_NAME}-${KAFKATORIO_VERSION}.tar ${APP_NAME}.tar RUN tar -xf ${APP_NAME}.tar --strip-components=1 \ && rm ${APP_NAME}.tar \ - && chmod +x /app/bin/${APP_NAME} \ + && cp /app/bin/${APP_NAME} /app/bin/run \ + && chmod 775 /app/bin/run -ENTRYPOINT /app/bin/${APP_NAME} +ENTRYPOINT /app/bin/run diff --git a/modules/events-server-syslog/docker/Dockerfile b/modules/events-server-syslog/docker/Dockerfile index 15d499c..2328f45 100644 --- a/modules/events-server-syslog/docker/Dockerfile +++ b/modules/events-server-syslog/docker/Dockerfile @@ -20,6 +20,7 @@ COPY ${DIST_DIR}/${APP_NAME}-${KAFKATORIO_VERSION}.tar ${APP_NAME}.tar RUN tar -xf ${APP_NAME}.tar --strip-components=1 \ && rm ${APP_NAME}.tar \ - && chmod +x /app/bin/${APP_NAME} + && cp /app/bin/${APP_NAME} /app/bin/run \ + && chmod 775 /app/bin/run -ENTRYPOINT /app/bin/${APP_NAME} +ENTRYPOINT /app/bin/run diff --git a/modules/events-server-web/docker/Dockerfile b/modules/events-server-web/docker/Dockerfile index af0fafc..32c34e9 100644 --- a/modules/events-server-web/docker/Dockerfile +++ b/modules/events-server-web/docker/Dockerfile @@ -20,6 +20,7 @@ COPY ${DIST_DIR}/${APP_NAME}-${KAFKATORIO_VERSION}.tar ${APP_NAME}.tar RUN tar -xf ${APP_NAME}.tar --strip-components=1 \ && rm ${APP_NAME}.tar \ - && chmod +x /app/bin/${APP_NAME} + && cp /app/bin/${APP_NAME} /app/bin/run \ + && chmod 775 /app/bin/run -ENTRYPOINT /app/bin/${APP_NAME} +ENTRYPOINT /app/bin/run From 1c9a93b4576c171e4185ae835b3acbfe10e17cd5 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Oct 2022 13:50:33 +0200 Subject: [PATCH 552/629] version 0.9.2 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9a3d775..51f07cb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.9.1" +version = "0.9.2" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) From 6035c2eaa038b5a2683dfbc3ef518de31ad9edc7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Oct 2022 14:16:43 +0200 Subject: [PATCH 553/629] move kafka topics creator into events-processors --- .../dev/adamko/kafkatorio/processor/admin/main.kt | 10 ---------- .../kafkatorio/processor/core/topologyLauncher.kt | 2 +- .../dev/adamko/kafkatorio/processors/createTopics.kt | 11 +++++++++++ .../kafkatorio/processors/groupEntitiesMapChunks.kt | 4 +++- .../kafkatorio/processors/groupTilesMapChunks.kt | 11 +++++++++-- .../kotlin/dev/adamko/kafkatorio/processors/main.kt | 3 +++ .../dev/adamko/kafkatorio/processors/splitPackets.kt | 7 +++++-- 7 files changed, 32 insertions(+), 16 deletions(-) delete mode 100644 modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/main.kt create mode 100644 modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/createTopics.kt diff --git a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/main.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/main.kt deleted file mode 100644 index 7819a59..0000000 --- a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/main.kt +++ /dev/null @@ -1,10 +0,0 @@ -package dev.adamko.kafkatorio.processor.admin - -import dev.adamko.kafkatorio.processor.config.ApplicationProperties - - -fun main() { - val appProps = ApplicationProperties.load() - val admin = KafkatorioKafkaAdmin(appProps) - admin.createKafkatorioTopics() -} diff --git a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/topologyLauncher.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/topologyLauncher.kt index 03ff1cc..a597711 100644 --- a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/topologyLauncher.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/topologyLauncher.kt @@ -18,12 +18,12 @@ import org.apache.kafka.streams.Topology import org.apache.kafka.streams.TopologyDescription -private val appProps = ApplicationProperties.load() suspend fun launchTopology( id: String, topology: Topology, additionalProperties: Map = mapOf(), + appProps: ApplicationProperties, ): Unit = coroutineScope { val props: Properties = appProps.kafkaStreamsConfig.toProperties() diff --git a/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/createTopics.kt b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/createTopics.kt new file mode 100644 index 0000000..535d2ef --- /dev/null +++ b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/createTopics.kt @@ -0,0 +1,11 @@ +package dev.adamko.kafkatorio.processors + +import dev.adamko.kafkatorio.processor.admin.KafkatorioKafkaAdmin +import dev.adamko.kafkatorio.processor.config.ApplicationProperties + +fun createTopics( + appProps: ApplicationProperties = ApplicationProperties.load(), +) { + val admin = KafkatorioKafkaAdmin(appProps) + admin.createKafkatorioTopics() +} diff --git a/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/groupEntitiesMapChunks.kt b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/groupEntitiesMapChunks.kt index 8783592..740b38f 100644 --- a/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/groupEntitiesMapChunks.kt +++ b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/groupEntitiesMapChunks.kt @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.processors +import dev.adamko.kafkatorio.processor.config.ApplicationProperties import dev.adamko.kafkatorio.processor.core.launchTopology import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.PrototypeHashCode @@ -22,6 +23,7 @@ suspend fun groupEntitiesMapChunks( layer: ServerMapTileLayer, colouredUpdatesStreamTopic: String, colouredChunkStateTopic: String, + appProps: ApplicationProperties = ApplicationProperties.load(), ) { val builder = StreamsBuilder() @@ -50,5 +52,5 @@ suspend fun groupEntitiesMapChunks( colouredChunkStateTopic, ) - launchTopology("groupTilesMapChunks.${layer.dir}", topology) + launchTopology("groupTilesMapChunks.${layer.dir}", topology, appProps = appProps) } diff --git a/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/groupTilesMapChunks.kt b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/groupTilesMapChunks.kt index fd65020..e95e026 100644 --- a/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/groupTilesMapChunks.kt +++ b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/groupTilesMapChunks.kt @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.processors +import dev.adamko.kafkatorio.processor.config.ApplicationProperties import dev.adamko.kafkatorio.processor.core.launchTopology import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.ServerMapTileLayer @@ -11,7 +12,9 @@ import org.apache.kafka.streams.kstream.KStream /** Terrain tiles */ -suspend fun groupTilesMapChunks() { +suspend fun groupTilesMapChunks( + appProps: ApplicationProperties = ApplicationProperties.load(), +) { val builder = StreamsBuilder() val protosStream: KStream = @@ -19,5 +22,9 @@ suspend fun groupTilesMapChunks() { val topology = colourMapChunks(builder, protosStream) - launchTopology("groupTilesMapChunks.${ServerMapTileLayer.TERRAIN.dir}", topology) + launchTopology( + id = "groupTilesMapChunks.${ServerMapTileLayer.TERRAIN.dir}", + topology = topology, + appProps = appProps + ) } diff --git a/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/main.kt b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/main.kt index 427903f..c046990 100644 --- a/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/main.kt +++ b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/main.kt @@ -10,6 +10,9 @@ import kotlinx.coroutines.launch suspend fun main(): Unit = coroutineScope { + + createTopics() + launch { splitPackets() } diff --git a/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/splitPackets.kt b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/splitPackets.kt index 9373bc2..7c4dd21 100644 --- a/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/splitPackets.kt +++ b/modules/events-processors/src/main/kotlin/dev/adamko/kafkatorio/processors/splitPackets.kt @@ -1,17 +1,20 @@ package dev.adamko.kafkatorio.processors +import dev.adamko.kafkatorio.processor.config.ApplicationProperties import dev.adamko.kafkatorio.processor.core.launchTopology import dev.adamko.kafkatorio.server.processor.topology.factorioServerPacketStream import dev.adamko.kafkatorio.server.processor.topology.splitFactorioServerPacketStream import org.apache.kafka.streams.StreamsBuilder -suspend fun splitPackets() { +suspend fun splitPackets( + appProps: ApplicationProperties = ApplicationProperties.load(), +) { val builder = StreamsBuilder() val packets = factorioServerPacketStream(builder) splitFactorioServerPacketStream(packets) val topology = builder.build() - launchTopology("splitPackets", topology) + launchTopology("splitPackets", topology, appProps = appProps) } From 4b921666a51937712fcbc0901454de975e59437f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Oct 2022 14:16:57 +0200 Subject: [PATCH 554/629] version 0.9.3 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 51f07cb..c6c1c93 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.9.2" +version = "0.9.3" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) From b0722487a0f1e73ff48fe42874a03e410fd87898 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Oct 2022 14:20:01 +0200 Subject: [PATCH 555/629] fix appProps in events-server-web --- .../processor/config/ApplicationProperties.kt | 2 +- .../dev/adamko/kafkatorio/server/web/main.kt | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt index 7d8a020..f55e2c6 100644 --- a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt @@ -9,7 +9,7 @@ import dev.adamko.kafkatorio.schema.common.FactorioServerToken import dev.adamko.kafkatorio.schema.common.MaskedValue import java.nio.file.Path -val appProps = ApplicationProperties.load() +internal val appProps = ApplicationProperties.load() data class ApplicationProperties( val webPort: PortVal, diff --git a/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/main.kt b/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/main.kt index 4ce5ae0..572a854 100644 --- a/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/main.kt +++ b/modules/events-server-web/src/main/kotlin/dev/adamko/kafkatorio/server/web/main.kt @@ -13,8 +13,9 @@ import org.apache.kafka.clients.producer.ProducerConfig import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.StreamsConfig +internal val appProps = ApplicationProperties.load() + suspend fun main(): Unit = coroutineScope { - val appProps = ApplicationProperties.load() val wsServer = WebmapWebsocketServer() launch { @@ -45,10 +46,13 @@ private suspend fun websocketBroadcaster(wsServer: WebmapWebsocketServer) { val topology = builder.build() launchTopology( - "websocketBroadcaster", topology, mapOf( + id = "websocketBroadcaster", + topology = topology, + additionalProperties = mapOf( StreamsConfig.COMMIT_INTERVAL_MS_CONFIG to "${1.seconds.inWholeMilliseconds}", - StreamsConfig.producerPrefix(ProducerConfig.LINGER_MS_CONFIG) to "${1.milliseconds.inWholeMilliseconds}" - ) + StreamsConfig.producerPrefix(ProducerConfig.LINGER_MS_CONFIG) to "${1.milliseconds.inWholeMilliseconds}", + ), + appProps = appProps, ) } @@ -57,5 +61,9 @@ private suspend fun saveTiles( ) { val builder = StreamsBuilder() saveMapTiles(builder, appProps.serverDataDir) - launchTopology("saveTiles", builder.build()) + launchTopology( + id = "saveTiles", + topology = builder.build(), + appProps = appProps + ) } From 2ef9c548add6aeca960f4951f262b841c64bf751 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Oct 2022 14:20:20 +0200 Subject: [PATCH 556/629] version 0.9.4 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index c6c1c93..3ea72c7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.9.3" +version = "0.9.4" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) From 59dc4ce3364af0d2825bffcef558e12106c46400 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Oct 2022 14:52:40 +0200 Subject: [PATCH 557/629] add nginx events section --- modules/web-map/docker/nginx.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/web-map/docker/nginx.conf b/modules/web-map/docker/nginx.conf index 1c37acb..1dfcfd9 100644 --- a/modules/web-map/docker/nginx.conf +++ b/modules/web-map/docker/nginx.conf @@ -1,3 +1,5 @@ +events {} + http { # what times to include # include /etc/nginx/mime.types; From 5cb9fc0a8898ace35c991433b7f954491a4e8d92 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Oct 2022 15:10:32 +0200 Subject: [PATCH 558/629] version 0.9.5 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3ea72c7..cdaf7e7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.9.4" +version = "0.9.5" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) From 11cca3c8c30e7a0322990f23720d3a373478c852 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Oct 2022 16:04:50 +0200 Subject: [PATCH 559/629] fix gradle task output (zip depends on browserDistribution), add util function for filtering tasks by name --- buildSrc/src/main/kotlin/extensions.kt | 9 ++++++--- modules/web-map/build.gradle.kts | 11 +++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/buildSrc/src/main/kotlin/extensions.kt b/buildSrc/src/main/kotlin/extensions.kt index 83020f8..961642c 100644 --- a/buildSrc/src/main/kotlin/extensions.kt +++ b/buildSrc/src/main/kotlin/extensions.kt @@ -1,7 +1,6 @@ +import org.gradle.api.Task import org.gradle.api.artifacts.Configuration -import org.gradle.api.attributes.Usage -import org.gradle.api.model.ObjectFactory -import org.gradle.kotlin.dsl.named +import org.gradle.api.tasks.TaskCollection // to be moved into gradle-plugins/builder-plugins... @@ -23,3 +22,7 @@ fun Configuration.asConsumer() { // attributes { // attribute(Usage.USAGE_ATTRIBUTE, objects.named("dev.adamko.gradle.factorio.typescriptFiles")) // } + + +fun TaskCollection.withName(name: String): TaskCollection = + matching { it.name == name } diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 7c757d6..0086b70 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -128,7 +128,7 @@ val installThemeCss by tasks.registering(Copy::class) { } -tasks.matching { it.name == "processResources" }.configureEach { +tasks.withName("processResources").configureEach { dependsOn(installThemeCss) } @@ -136,9 +136,16 @@ tasks.matching { it.name == "processResources" }.configureEach { val runWebMap by tasks.registering { group = rootProject.name - dependsOn(tasks.matching { it.name == "browserDevelopmentRun" }) + dependsOn(tasks.withName("browserDevelopmentRun")) + } + +tasks.zip { + dependsOn(tasks.withName("browserDistribution")) +} + + tasks.dockerComposeBuild { dependsOn(tasks.zip) } From f2e67364b8dbf69f2ff6c7719d5b012d853acd53 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Oct 2022 16:05:26 +0200 Subject: [PATCH 560/629] gdc plugin - use rootProject.name for COMPOSE_PROJECT_NAME --- .../src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt index 2e78878..eb46a5d 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt @@ -82,7 +82,7 @@ abstract class GDCPlugin @Inject constructor( private fun Project.createSettings(): GDCSettings = extensions.create(GDC_EXTENSION_NAME).apply { - composeProjectName.convention(providers.provider { project.name }) + composeProjectName.convention(providers.provider { rootProject.name }) composeProjectVersion.convention(providers.provider { project.version.toString() }) containerRegistryHost.convention(providers.gradleProperty("dockerContainerRegistryHost")) srcDir.convention(layout.projectDirectory.dir("docker")) From 32b4bbffe2be2d02170af6b216e9b51fbfe53dee Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Oct 2022 16:05:44 +0200 Subject: [PATCH 561/629] maybe fix webmap nginx css... --- modules/web-map/docker/Dockerfile | 2 ++ modules/web-map/docker/nginx.conf | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/web-map/docker/Dockerfile b/modules/web-map/docker/Dockerfile index c62fa29..1764c56 100644 --- a/modules/web-map/docker/Dockerfile +++ b/modules/web-map/docker/Dockerfile @@ -2,6 +2,8 @@ FROM nginx +EXPOSE 80 + COPY ./docker/nginx.conf /etc/nginx/nginx.conf COPY ./build/distributions /usr/share/nginx/html diff --git a/modules/web-map/docker/nginx.conf b/modules/web-map/docker/nginx.conf index 1dfcfd9..6d57bca 100644 --- a/modules/web-map/docker/nginx.conf +++ b/modules/web-map/docker/nginx.conf @@ -1,10 +1,8 @@ events {} http { - # what times to include - # include /etc/nginx/mime.types; - # what is the default one - #default_type application/octet-stream; + include mime.types; + default_type application/octet-stream; # Sets the path, format, and configuration for a buffered log write #log_format compression '$remote_addr - $remote_user [$time_local] ' @@ -22,6 +20,8 @@ http { # First attempt to serve request as file, then # as directory, then fall back to redirecting to index.html try_files $uri $uri/ $uri.html /index.html; + + include mime.types; } } } From f4b614a56a869e1eabad366c5269c3f8bc9c75a7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Oct 2022 16:06:00 +0200 Subject: [PATCH 562/629] version 0.9.6 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index cdaf7e7..c7587fe 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.9.5" +version = "0.9.6" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) From 467227d965b240bd8a9f17be8ad81e8b6913af5b Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Oct 2022 17:06:04 +0200 Subject: [PATCH 563/629] fix kotlinx-coroutines/kotlinx-serialization dependencies version clash in gradle-plugins --- buildSrc/build.gradle.kts | 3 ++- gradle-plugins/factorio-gradle/build.gradle.kts | 14 ++++++++++++-- gradle-plugins/settings-plugins/build.gradle.kts | 6 +++++- .../conventions/kotlin-serialization.gradle.kts | 8 ++++++++ 4 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/kotlin-serialization.gradle.kts diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index dad2820..1b062d6 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -3,10 +3,11 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("kafkatorio.conventions.kotlin-dsl") + id("kafkatorio.conventions.kotlin-serialization") // idea // `kotlin-dsl` // kotlin("jvm") //version "1.7.20" // embeddedKotlinVersion - kotlin("plugin.serialization") version embeddedKotlinVersion +// kotlin("plugin.serialization") // version embeddedKotlinVersion // kotlin("plugin.serialization") version "1.7.20" } diff --git a/gradle-plugins/factorio-gradle/build.gradle.kts b/gradle-plugins/factorio-gradle/build.gradle.kts index 9c5d55e..6b19f3b 100644 --- a/gradle-plugins/factorio-gradle/build.gradle.kts +++ b/gradle-plugins/factorio-gradle/build.gradle.kts @@ -3,7 +3,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("kafkatorio.conventions.kotlin-dsl") - kotlin("plugin.serialization") version embeddedKotlinVersion + id("kafkatorio.conventions.kotlin-serialization") } @@ -61,7 +61,7 @@ gradlePlugin { } -overrideKotlinLanguageVersion("1.6") +overrideKotlinLanguageVersion("1.7") //val gradleKotlinTarget = "1.7" // @@ -73,3 +73,13 @@ overrideKotlinLanguageVersion("1.6") // } // } //} + + +tasks.withType().configureEach { + kotlinOptions.freeCompilerArgs += listOf( + "-opt-in=kotlin.RequiresOptIn", + "-opt-in=kotlin.ExperimentalStdlibApi", + "-opt-in=kotlin.time.ExperimentalTime", + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + ) +} diff --git a/gradle-plugins/settings-plugins/build.gradle.kts b/gradle-plugins/settings-plugins/build.gradle.kts index a6e6a32..10e849f 100644 --- a/gradle-plugins/settings-plugins/build.gradle.kts +++ b/gradle-plugins/settings-plugins/build.gradle.kts @@ -14,8 +14,12 @@ dependencies { // get polluted and messy. implementation("org.gradle.kotlin:gradle-kotlin-dsl-plugins:$expectedKotlinDslPluginsVersion") -// implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${embeddedKotlinVersion}") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${libs.versions.kotlin.get()}") + + implementation(platform(libs.kotlin.bom)) + implementation("org.jetbrains.kotlin:kotlin-serialization") + + implementation(platform(libs.kotlinx.coroutines.bom)) } kotlin { diff --git a/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/kotlin-serialization.gradle.kts b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/kotlin-serialization.gradle.kts new file mode 100644 index 0000000..ad386e9 --- /dev/null +++ b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/kotlin-serialization.gradle.kts @@ -0,0 +1,8 @@ +package kafkatorio.conventions + +plugins { + kotlin("plugin.serialization") +} + +// No config required or available. This convention plugin is only required because Gradle gets +// confused about the version. From f76eb9ccb3faf90f2de0a0c53d4bb1e014d75ded Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 8 Oct 2022 17:06:23 +0200 Subject: [PATCH 564/629] update events-mod version --- modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 419d03c..04a2244 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.0", + "version": "0.9.6", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 1bc7eb7..e14390e 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.0", + "version": "0.9.6", "private": true, "scripts": { "build": "tstl", From c1408187bee69bd449489085bcfa4f3b8c65e74b Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 15 Oct 2022 20:40:44 +0200 Subject: [PATCH 565/629] make zips reproducible, ignore .env files --- .../src/main/kotlin/kafkatorio/conventions/base.gradle.kts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/base.gradle.kts b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/base.gradle.kts index 1bd1049..4171242 100644 --- a/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/base.gradle.kts +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/conventions/base.gradle.kts @@ -18,5 +18,10 @@ tasks.withType().configureEach { tasks.withType().configureEach { - exclude("**/.secret.*") + exclude( + "**/.secret.*", + "**/.env", + ) + isPreserveFileTimestamps = false + isReproducibleFileOrder = true } From 4ba673f3781bc07011c9efa769413015ad97163d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 15 Oct 2022 20:41:03 +0200 Subject: [PATCH 566/629] kdoc for DockerEnvUpdateTask --- .../main/kotlin/dev/adamko/geedeecee/DockerEnvUpdateTask.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerEnvUpdateTask.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerEnvUpdateTask.kt index 80046ab..18e8130 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerEnvUpdateTask.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerEnvUpdateTask.kt @@ -16,6 +16,9 @@ import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction +/** + * (Based on [org.gradle.api.tasks.WriteProperties], but updated to use [MapProperty]) + */ @CacheableTask abstract class DockerEnvUpdateTask @Inject constructor( ) : DefaultTask() { From 6a439b334d3b3de3782fed522de3b05c620d891a Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 15 Oct 2022 20:41:31 +0200 Subject: [PATCH 567/629] try fixing syslog port to be 9002, and expose it using an env-var --- modules/events-server-syslog/docker/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/events-server-syslog/docker/Dockerfile b/modules/events-server-syslog/docker/Dockerfile index 2328f45..a425858 100644 --- a/modules/events-server-syslog/docker/Dockerfile +++ b/modules/events-server-syslog/docker/Dockerfile @@ -7,8 +7,8 @@ ARG APP_NAME="events-server-syslog" WORKDIR /app -ENV SOCKET_SERVER_PORT=601 -EXPOSE $SYSLOG_PORT +ENV SOCKET_SERVER_PORT=9002 +EXPOSE $SOCKET_SERVER_PORT ENV SERVER_DATA_DIR="/app/data" ENV KAFKA_STREAMS_STATE_DIR="/app/state/kafka" From dbfbc9bbeac4c9479fe6340098a7601c8689a52d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 15 Oct 2022 20:42:28 +0200 Subject: [PATCH 568/629] kafka-pipe: update filter "KafkatorioPacket encoded:::" --- modules/infra-kafka-pipe/readme.md | 2 +- modules/infra-kafka-pipe/src/kafka-pipe.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/infra-kafka-pipe/readme.md b/modules/infra-kafka-pipe/readme.md index 2fc4129..64f2ed8 100644 --- a/modules/infra-kafka-pipe/readme.md +++ b/modules/infra-kafka-pipe/readme.md @@ -49,4 +49,4 @@ curl \ --insecure "http://localhost/v1.41/containers/factorio-server/attach?logs=true&stream=true&stdout=true&follow=true" | tail -c+9 -``` \ No newline at end of file +``` diff --git a/modules/infra-kafka-pipe/src/kafka-pipe.sh b/modules/infra-kafka-pipe/src/kafka-pipe.sh index e6717fd..e0922be 100644 --- a/modules/infra-kafka-pipe/src/kafka-pipe.sh +++ b/modules/infra-kafka-pipe/src/kafka-pipe.sh @@ -17,7 +17,7 @@ KEY="${INSTANCE_ID:-none}" while :; do docker logs --tail 0 -f "$FACTORIO_SERVER_CONTAINER_NAME" | - sed -n -e 's/^KafkatorioPacket: //p' | + sed -n -e 's/^KafkatorioPacket encoded::: //p' | kcat -P \ -b "$KAFKA_HOST" \ -t kafkatorio.src.server-log \ From 2032da903fee4418891cdf5f90e544fd2ffc8308 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 15 Oct 2022 20:42:47 +0200 Subject: [PATCH 569/629] version 0.9.7 --- build.gradle.kts | 2 +- modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- modules/infra-factorio-server/build.gradle.kts | 2 -- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index c7587fe..3dac5e1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.9.6" +version = "0.9.7" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 04a2244..88a1d7b 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.6", + "version": "0.9.7", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index e14390e..57a2bad 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.6", + "version": "0.9.7", "private": true, "scripts": { "build": "tstl", diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 1aa8bea..f3f5184 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -65,8 +65,6 @@ val kafkatorioServerToken: String by project tasks.dockerComposeEnvUpdate { - envProperties.put("FACTORIO_VERSION", libs.versions.factorio) - envProperties.put("KAFKATORIO_TOKEN", kafkatorioServerToken) envProperties { put("FACTORIO_VERSION", libs.versions.factorio) put("KAFKATORIO_TOKEN", kafkatorioServerToken) From 71386ded3b8a1843439801abbc0c2d5dbae39ddb Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 15 Oct 2022 23:53:33 +0200 Subject: [PATCH 570/629] set org.gradle.jvmargs --- gradle.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index e73b36e..4c07fa9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,5 @@ -kotlin.js.compiler=ir +org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xmx4g + kotlin.mpp.stability.nowarn=true #kotlin.mpp.enableGranularSourceSetsMetadata=true #kotlin.native.enableDependencyPropagation=false From 0f9e51df313675798108d012547400dd0eebcbe3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 16 Oct 2022 12:34:07 +0200 Subject: [PATCH 571/629] refactor syslog server to use Dispatchers.IO and SupervisorScope (try to fix connection refused error) --- .../processor/syslog/SyslogSocketServer.kt | 70 +++++++++---------- 1 file changed, 32 insertions(+), 38 deletions(-) diff --git a/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogSocketServer.kt b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogSocketServer.kt index 12cac26..cd9780f 100644 --- a/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogSocketServer.kt +++ b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogSocketServer.kt @@ -16,12 +16,12 @@ import io.ktor.utils.io.readUTF8Line import java.util.EnumSet import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.isActive import kotlinx.coroutines.launch +import kotlinx.coroutines.supervisorScope import kotlinx.coroutines.withContext import kotlinx.coroutines.yield @@ -56,53 +56,47 @@ class SyslogSocketServer( get() = _messages.asSharedFlow() - suspend fun start(): Unit = coroutineScope { + suspend fun start(): Unit = withContext(Dispatchers.IO) { log("started listening: ${serverSocketTcp.localAddress}") while (isActive) { val socket: Socket = serverSocketTcp.accept() - log("new socket ${socket.description()}") - launch { - val channel = socket.openReadChannel() - try { - while (socket.socketContext.isActive && !channel.isClosedForRead) { - val line = runCatching { - channel.readUTF8Line() - }.fold( - onSuccess = { line -> - if (line == null) { - log("received 'null' from ${socket.description()} - closing connection") - socket.close() - } - // log("received '$line' from ${socket.description()}") - line - }, - onFailure = { ex -> - if (ex is CancellationException) throw ex - - log("reading line from socket failed ${socket.description()}, cause: $ex") - null - }, - ) - if (line != null) { - val syslog = SyslogMsg(syslogParser.parseLine(line)) - _messages.emit(syslog) - } - yield() - } - } catch (e: Exception) { - if (e is CancellationException) throw e - log("closing socket ${socket.description()}, cause: ${e::class.java.name} ${e.message}") - e.printStackTrace() - withContext(Dispatchers.IO) { socket.close() } - } + log("new socket ${socket.description()}") + handleConnection(socket) } - yield() } } + + private suspend fun handleConnection( + socket: Socket + ) = supervisorScope { + try { + val channel = socket.openReadChannel() + while (socket.socketContext.isActive && !channel.isClosedForRead) { + + val line = channel.readUTF8Line() + + requireNotNull(line) { + "received 'null' line from ${socket.description()}" + } + + val syslog = SyslogMsg(syslogParser.parseLine(line)) + _messages.emit(syslog) + + yield() + } + } catch (e: Throwable) { + if (e is CancellationException) throw e + log("closing socket ${socket.description()}, cause: ${e::class.java.name} ${e.message}") + e.printStackTrace() + withContext(Dispatchers.IO) { socket.close() } + } + } + + companion object { private fun log(msg: String) = println("[SyslogSocketServer] $msg") From e6ffe4cba536a61747697064c4b4b299263ff56a Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 16 Oct 2022 12:47:45 +0200 Subject: [PATCH 572/629] update bootstrap css (some sort of encoding change with a "-NBSP" --- modules/web-map/build.gradle.kts | 6 ++++-- modules/web-map/src/main/resources/css/bootstrap.min.css | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 0086b70..60ade07 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -1,3 +1,4 @@ +import io.kvision.gradle.KVisionPlugin import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig @@ -115,7 +116,8 @@ fun KotlinDependencyHandler.kvision( } -val installThemeCss by tasks.registering(Copy::class) { +val installBootstrapThemeCss by tasks.registering(Copy::class) { + group = KVisionPlugin.KVISION_TASK_GROUP val bootswatchThemeMinCss = resources.text.fromUri( libs.versions.npm.bootswatch.map { bootswatch -> "https://cdn.jsdelivr.net/npm/bootswatch@$bootswatch/dist/darkly/bootstrap.min.css" @@ -129,7 +131,7 @@ val installThemeCss by tasks.registering(Copy::class) { tasks.withName("processResources").configureEach { - dependsOn(installThemeCss) + dependsOn(installBootstrapThemeCss) } diff --git a/modules/web-map/src/main/resources/css/bootstrap.min.css b/modules/web-map/src/main/resources/css/bootstrap.min.css index d58f6c3..4452fb1 100644 --- a/modules/web-map/src/main/resources/css/bootstrap.min.css +++ b/modules/web-map/src/main/resources/css/bootstrap.min.css @@ -9,4 +9,4 @@ * Copyright 2011-2022 The Bootstrap Authors * Copyright 2011-2022 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */@import url(https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap);:root{--bs-blue:#375a7f;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#e83e8c;--bs-red:#e74c3c;--bs-orange:#fd7e14;--bs-yellow:#f39c12;--bs-green:#00bc8c;--bs-teal:#20c997;--bs-cyan:#3498db;--bs-black:#000;--bs-white:#fff;--bs-gray:#888;--bs-gray-dark:#303030;--bs-gray-100:#f8f9fa;--bs-gray-200:#ebebeb;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#888;--bs-gray-700:#444;--bs-gray-800:#303030;--bs-gray-900:#222;--bs-primary:#375a7f;--bs-secondary:#444;--bs-success:#00bc8c;--bs-info:#3498db;--bs-warning:#f39c12;--bs-danger:#e74c3c;--bs-light:#adb5bd;--bs-dark:#303030;--bs-primary-rgb:55,90,127;--bs-secondary-rgb:68,68,68;--bs-success-rgb:0,188,140;--bs-info-rgb:52,152,219;--bs-warning-rgb:243,156,18;--bs-danger-rgb:231,76,60;--bs-light-rgb:173,181,189;--bs-dark-rgb:48,48,48;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:255,255,255;--bs-body-bg-rgb:34,34,34;--bs-font-sans-serif:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#fff;--bs-body-bg:#222;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#00bc8c;--bs-link-hover-color:#009670;--bs-code-color:#e83e8c;--bs-highlight-bg:#fdebd0}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:1px solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:calc(1.425rem + 2.1vw)}@media (min-width:1200px){.h1,h1{font-size:3rem}}.h2,h2{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h2,h2{font-size:2.5rem}}.h3,h3{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h3,h3{font-size:2rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--bs-link-color);text-decoration:underline}a:hover{color:var(--bs-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em;color:inherit}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#888;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#888}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#222;border:1px solid var(--bs-border-color);border-radius:.375rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#888}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color:var(--bs-body-color);--bs-table-bg:transparent;--bs-table-border-color:#444;--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-body-color);--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:var(--bs-body-color);--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:var(--bs-body-color);--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:var(--bs-table-color);vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:2px solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-striped-columns>:not(caption)>tr>:nth-child(even){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-color:#fff;--bs-table-bg:#375a7f;--bs-table-border-color:#4b6b8c;--bs-table-striped-bg:#416285;--bs-table-striped-color:#fff;--bs-table-active-bg:#4b6b8c;--bs-table-active-color:#fff;--bs-table-hover-bg:#466689;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#fff;--bs-table-bg:#444444;--bs-table-border-color:#575757;--bs-table-striped-bg:#4d4d4d;--bs-table-striped-color:#fff;--bs-table-active-bg:#575757;--bs-table-active-color:#fff;--bs-table-hover-bg:#525252;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#fff;--bs-table-bg:#00bc8c;--bs-table-border-color:#1ac398;--bs-table-striped-bg:#0dbf92;--bs-table-striped-color:#fff;--bs-table-active-bg:#1ac398;--bs-table-active-color:#fff;--bs-table-hover-bg:#13c195;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#fff;--bs-table-bg:#3498db;--bs-table-border-color:#48a2df;--bs-table-striped-bg:#3e9ddd;--bs-table-striped-color:#fff;--bs-table-active-bg:#48a2df;--bs-table-active-color:#fff;--bs-table-hover-bg:#43a0de;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#fff;--bs-table-bg:#f39c12;--bs-table-border-color:#f4a62a;--bs-table-striped-bg:#f4a11e;--bs-table-striped-color:#fff;--bs-table-active-bg:#f4a62a;--bs-table-active-color:#fff;--bs-table-hover-bg:#f4a324;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#fff;--bs-table-bg:#e74c3c;--bs-table-border-color:#e95e50;--bs-table-striped-bg:#e85546;--bs-table-striped-color:#fff;--bs-table-active-bg:#e95e50;--bs-table-active-color:#fff;--bs-table-hover-bg:#e9594b;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#fff;--bs-table-bg:#adb5bd;--bs-table-border-color:#b5bcc4;--bs-table-striped-bg:#b1b9c0;--bs-table-striped-color:#fff;--bs-table-active-bg:#b5bcc4;--bs-table-active-color:#fff;--bs-table-hover-bg:#b3bbc2;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#303030;--bs-table-border-color:#454545;--bs-table-striped-bg:#3a3a3a;--bs-table-striped-color:#fff;--bs-table-active-bg:#454545;--bs-table-active-color:#fff;--bs-table-hover-bg:#404040;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:#888}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#303030;background-color:#fff;background-clip:padding-box;border:1px solid #222;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#303030;background-color:#fff;border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-moz-placeholder{color:#888;opacity:1}.form-control::placeholder{color:#888;opacity:1}.form-control:disabled{background-color:#ebebeb;opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#fff;background-color:#444;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#fff;background-color:#444;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#414141}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#414141}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#fff;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{width:3rem;height:calc(1.5em + .75rem + 2px);padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:.375rem}.form-control-color::-webkit-color-swatch{border-radius:.375rem}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + 2px)}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + 2px)}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:#303030;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #222;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#ebebeb}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #303030}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:.25rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:.5rem}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-check-input:checked{background-color:#375a7f;border-color:#375a7f}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#375a7f;border-color:#375a7f;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%239badbf'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #222,0 0 0 .25rem rgba(55,90,127,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #222,0 0 0 .25rem rgba(55,90,127,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#375a7f;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#c3ced9}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#375a7f;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#c3ced9}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;width:100%;height:100%;padding:1rem .75rem;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::-moz-placeholder,.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown),.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:1px 0}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#adb5bd;text-align:center;white-space:nowrap;background-color:#444;border:1px solid #222;border-radius:.375rem}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#00bc8c}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(0,188,140,.9);border-radius:.375rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#00bc8c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#00bc8c}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#00bc8c}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#00bc8c}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#00bc8c}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#e74c3c}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(231,76,60,.9);border-radius:.375rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#e74c3c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#e74c3c}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#e74c3c}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#e74c3c}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#e74c3c}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#fff;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:first-child:hover,:not(.btn-check)+.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#375a7f;--bs-btn-border-color:#375a7f;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#2f4d6c;--bs-btn-hover-border-color:#2c4866;--bs-btn-focus-shadow-rgb:85,115,146;--bs-btn-active-color:#fff;--bs-btn-active-bg:#2c4866;--bs-btn-active-border-color:#29445f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#375a7f;--bs-btn-disabled-border-color:#375a7f}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#444;--bs-btn-border-color:#444;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#3a3a3a;--bs-btn-hover-border-color:#363636;--bs-btn-focus-shadow-rgb:96,96,96;--bs-btn-active-color:#fff;--bs-btn-active-bg:#363636;--bs-btn-active-border-color:#333333;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#444;--bs-btn-disabled-border-color:#444}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#00bc8c;--bs-btn-border-color:#00bc8c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#00a077;--bs-btn-hover-border-color:#009670;--bs-btn-focus-shadow-rgb:38,198,157;--bs-btn-active-color:#fff;--bs-btn-active-bg:#009670;--bs-btn-active-border-color:#008d69;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#00bc8c;--bs-btn-disabled-border-color:#00bc8c}.btn-info{--bs-btn-color:#fff;--bs-btn-bg:#3498db;--bs-btn-border-color:#3498db;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#2c81ba;--bs-btn-hover-border-color:#2a7aaf;--bs-btn-focus-shadow-rgb:82,167,224;--bs-btn-active-color:#fff;--bs-btn-active-bg:#2a7aaf;--bs-btn-active-border-color:#2772a4;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#3498db;--bs-btn-disabled-border-color:#3498db}.btn-warning{--bs-btn-color:#fff;--bs-btn-bg:#f39c12;--bs-btn-border-color:#f39c12;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#cf850f;--bs-btn-hover-border-color:#c27d0e;--bs-btn-focus-shadow-rgb:245,171,54;--bs-btn-active-color:#fff;--bs-btn-active-bg:#c27d0e;--bs-btn-active-border-color:#b6750e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#f39c12;--bs-btn-disabled-border-color:#f39c12}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#e74c3c;--bs-btn-border-color:#e74c3c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#c44133;--bs-btn-hover-border-color:#b93d30;--bs-btn-focus-shadow-rgb:235,103,89;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b93d30;--bs-btn-active-border-color:#ad392d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#e74c3c;--bs-btn-disabled-border-color:#e74c3c}.btn-light{--bs-btn-color:#fff;--bs-btn-bg:#adb5bd;--bs-btn-border-color:#adb5bd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#939aa1;--bs-btn-hover-border-color:#8a9197;--bs-btn-focus-shadow-rgb:185,192,199;--bs-btn-active-color:#fff;--bs-btn-active-bg:#8a9197;--bs-btn-active-border-color:#82888e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#adb5bd;--bs-btn-disabled-border-color:#adb5bd}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#303030;--bs-btn-border-color:#303030;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#4f4f4f;--bs-btn-hover-border-color:#454545;--bs-btn-focus-shadow-rgb:79,79,79;--bs-btn-active-color:#fff;--bs-btn-active-bg:#595959;--bs-btn-active-border-color:#454545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#303030;--bs-btn-disabled-border-color:#303030}.btn-outline-primary{--bs-btn-color:#375a7f;--bs-btn-border-color:#375a7f;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#375a7f;--bs-btn-hover-border-color:#375a7f;--bs-btn-focus-shadow-rgb:55,90,127;--bs-btn-active-color:#fff;--bs-btn-active-bg:#375a7f;--bs-btn-active-border-color:#375a7f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#375a7f;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#375a7f;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#444;--bs-btn-border-color:#444;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#444;--bs-btn-hover-border-color:#444;--bs-btn-focus-shadow-rgb:68,68,68;--bs-btn-active-color:#fff;--bs-btn-active-bg:#444;--bs-btn-active-border-color:#444;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#444;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#444;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#00bc8c;--bs-btn-border-color:#00bc8c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#00bc8c;--bs-btn-hover-border-color:#00bc8c;--bs-btn-focus-shadow-rgb:0,188,140;--bs-btn-active-color:#fff;--bs-btn-active-bg:#00bc8c;--bs-btn-active-border-color:#00bc8c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#00bc8c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#00bc8c;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#3498db;--bs-btn-border-color:#3498db;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#3498db;--bs-btn-hover-border-color:#3498db;--bs-btn-focus-shadow-rgb:52,152,219;--bs-btn-active-color:#fff;--bs-btn-active-bg:#3498db;--bs-btn-active-border-color:#3498db;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#3498db;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#3498db;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#f39c12;--bs-btn-border-color:#f39c12;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#f39c12;--bs-btn-hover-border-color:#f39c12;--bs-btn-focus-shadow-rgb:243,156,18;--bs-btn-active-color:#fff;--bs-btn-active-bg:#f39c12;--bs-btn-active-border-color:#f39c12;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f39c12;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f39c12;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#e74c3c;--bs-btn-border-color:#e74c3c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#e74c3c;--bs-btn-hover-border-color:#e74c3c;--bs-btn-focus-shadow-rgb:231,76,60;--bs-btn-active-color:#fff;--bs-btn-active-bg:#e74c3c;--bs-btn-active-border-color:#e74c3c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#e74c3c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#e74c3c;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#adb5bd;--bs-btn-border-color:#adb5bd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#adb5bd;--bs-btn-hover-border-color:#adb5bd;--bs-btn-focus-shadow-rgb:173,181,189;--bs-btn-active-color:#fff;--bs-btn-active-bg:#adb5bd;--bs-btn-active-border-color:#adb5bd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#adb5bd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#adb5bd;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#303030;--bs-btn-border-color:#303030;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#303030;--bs-btn-hover-border-color:#303030;--bs-btn-focus-shadow-rgb:48,48,48;--bs-btn-active-color:#fff;--bs-btn-active-bg:#303030;--bs-btn-active-border-color:#303030;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#303030;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#303030;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#888;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:85,115,146;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:0.5rem}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:0.25rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:#fff;--bs-dropdown-bg:#222;--bs-dropdown-border-color:#444;--bs-dropdown-border-radius:0.375rem;--bs-dropdown-border-width:1px;--bs-dropdown-inner-border-radius:calc(0.375rem - 1px);--bs-dropdown-divider-bg:#444;--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-dropdown-link-color:#fff;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-link-hover-bg:#375a7f;--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#375a7f;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#888;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#303030;--bs-dropdown-border-color:#444;--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:#444;--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#375a7f;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:.375rem}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:2rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#adb5bd;display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#444;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#444 #444 transparent;--bs-nav-tabs-link-active-color:#fff;--bs-nav-tabs-link-active-bg:#222;--bs-nav-tabs-link-active-border-color:#444 #444 transparent;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:0.375rem;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#375a7f}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:1rem;--bs-navbar-color:rgba(34, 34, 34, 0.7);--bs-navbar-hover-color:#222;--bs-navbar-disabled-color:rgba(0, 0, 0, 0.3);--bs-navbar-active-color:#222;--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:#222;--bs-navbar-brand-hover-color:#222;--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2834, 34, 34, 0.7%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(34, 34, 34, 0.1);--bs-navbar-toggler-border-radius:0.375rem;--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .show>.nav-link{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark{--bs-navbar-color:rgba(255, 255, 255, 0.6);--bs-navbar-hover-color:#fff;--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.6%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-border-width:1px;--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:0.375rem;--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(0.375rem - 1px);--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:#444;--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:#303030;--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:#222;--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:1px;--bs-accordion-border-radius:0.375rem;--bs-accordion-inner-border-radius:calc(0.375rem - 1px);--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='var%28--bs-body-color%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23325172'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-focus-border-color:#9badbf;--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(55, 90, 127, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:#325172;--bs-accordion-active-bg:#ebeff2}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:var(--bs-accordion-btn-focus-border-color);outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button,.accordion-flush .accordion-item .accordion-button.collapsed{border-radius:0}.breadcrumb{--bs-breadcrumb-padding-x:0.75rem;--bs-breadcrumb-padding-y:0.375rem;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg:#444;--bs-breadcrumb-border-radius:0.25rem;--bs-breadcrumb-divider-color:#888;--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:#888;display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:#fff;--bs-pagination-bg:#00bc8c;--bs-pagination-border-width:0;--bs-pagination-border-color:transparent;--bs-pagination-border-radius:0.375rem;--bs-pagination-hover-color:#fff;--bs-pagination-hover-bg:#00efb2;--bs-pagination-hover-border-color:transparent;--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:#ebebeb;--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(55, 90, 127, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#00efb2;--bs-pagination-active-border-color:transparent;--bs-pagination-disabled-color:#fff;--bs-pagination-disabled-bg:#007053;--bs-pagination-disabled-border-color:transparent;display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:0.5rem}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:0.25rem}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:0.375rem;display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:1px solid var(--bs-alert-border-color);--bs-alert-border-radius:0.375rem;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:#21364c;--bs-alert-bg:#d7dee5;--bs-alert-border-color:#c3ced9}.alert-primary .alert-link{color:#1a2b3d}.alert-secondary{--bs-alert-color:#292929;--bs-alert-bg:#dadada;--bs-alert-border-color:#c7c7c7}.alert-secondary .alert-link{color:#212121}.alert-success{--bs-alert-color:#007154;--bs-alert-bg:#ccf2e8;--bs-alert-border-color:#b3ebdd}.alert-success .alert-link{color:#005a43}.alert-info{--bs-alert-color:#1f5b83;--bs-alert-bg:#d6eaf8;--bs-alert-border-color:#c2e0f4}.alert-info .alert-link{color:#194969}.alert-warning{--bs-alert-color:#925e0b;--bs-alert-bg:#fdebd0;--bs-alert-border-color:#fbe1b8}.alert-warning .alert-link{color:#754b09}.alert-danger{--bs-alert-color:#8b2e24;--bs-alert-bg:#fadbd8;--bs-alert-border-color:#f8c9c5}.alert-danger .alert-link{color:#6f251d}.alert-light{--bs-alert-color:#686d71;--bs-alert-bg:#eff0f2;--bs-alert-border-color:#e6e9eb}.alert-light .alert-link{color:#53575a}.alert-dark{--bs-alert-color:#1d1d1d;--bs-alert-bg:#d6d6d6;--bs-alert-border-color:#c1c1c1}.alert-dark .alert-link{color:#171717}@-webkit-keyframes progress-bar-stripes{0%{background-position-x:1rem}}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:#444;--bs-progress-border-radius:0.375rem;--bs-progress-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#375a7f;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.list-group{--bs-list-group-color:#fff;--bs-list-group-bg:#303030;--bs-list-group-border-color:#444;--bs-list-group-border-width:1px;--bs-list-group-border-radius:0.375rem;--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:#444;--bs-list-group-action-hover-color:#fff;--bs-list-group-action-hover-bg:#444;--bs-list-group-action-active-color:#fff;--bs-list-group-action-active-bg:#222;--bs-list-group-disabled-color:#888;--bs-list-group-disabled-bg:#303030;--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#375a7f;--bs-list-group-active-border-color:#375a7f;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#21364c;background-color:#d7dee5}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#21364c;background-color:#c2c8ce}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#21364c;border-color:#21364c}.list-group-item-secondary{color:#292929;background-color:#dadada}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#292929;background-color:#c4c4c4}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#292929;border-color:#292929}.list-group-item-success{color:#007154;background-color:#ccf2e8}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#007154;background-color:#b8dad1}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#007154;border-color:#007154}.list-group-item-info{color:#1f5b83;background-color:#d6eaf8}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#1f5b83;background-color:#c1d3df}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#1f5b83;border-color:#1f5b83}.list-group-item-warning{color:#925e0b;background-color:#fdebd0}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#925e0b;background-color:#e4d4bb}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#925e0b;border-color:#925e0b}.list-group-item-danger{color:#8b2e24;background-color:#fadbd8}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#8b2e24;background-color:#e1c5c2}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#8b2e24;border-color:#8b2e24}.list-group-item-light{color:#686d71;background-color:#eff0f2}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#686d71;background-color:#d7d8da}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#686d71;border-color:#686d71}.list-group-item-dark{color:#1d1d1d;background-color:#d6d6d6}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1d1d1d;background-color:#c1c1c1}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1d1d1d;border-color:#1d1d1d}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#fff;background:transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.375rem;opacity:.4}.btn-close:hover{color:#fff;text-decoration:none;opacity:1}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25);opacity:1}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:#444;--bs-toast-border-width:1px;--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:0.375rem;--bs-toast-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-toast-header-color:#888;--bs-toast-header-bg:#303030;--bs-toast-header-border-color:rgba(0, 0, 0, 0.05);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{position:absolute;z-index:var(--bs-toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:#303030;--bs-modal-border-color:#444;--bs-modal-border-width:1px;--bs-modal-border-radius:0.5rem;--bs-modal-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-modal-inner-border-radius:calc(0.5rem - 1px);--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:#444;--bs-modal-header-border-width:1px;--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:#444;--bs-modal-footer-border-width:1px;position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin:calc(-.5 * var(--bs-modal-header-padding-y)) calc(-.5 * var(--bs-modal-header-padding-x)) calc(-.5 * var(--bs-modal-header-padding-y)) auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:#fff;--bs-tooltip-bg:#000;--bs-tooltip-border-radius:0.375rem;--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;padding:var(--bs-tooltip-arrow-height);margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:#303030;--bs-popover-border-width:1px;--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:0.5rem;--bs-popover-inner-border-radius:calc(0.5rem - 1px);--bs-popover-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color: ;--bs-popover-header-bg:#444;--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:#fff;--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;-webkit-animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name);animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@-webkit-keyframes spinner-border{to{transform:rotate(360deg)}}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color: ;--bs-offcanvas-bg:#303030;--bs-offcanvas-border-width:1px;--bs-offcanvas-border-color:#444;--bs-offcanvas-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075)}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:575.98px){.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}}@media (max-width:575.98px){.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:767.98px){.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}}@media (max-width:767.98px){.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:991.98px){.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}}@media (max-width:991.98px){.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1199.98px){.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}}@media (max-width:1199.98px){.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}}@media (max-width:1399.98px){.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin-top:calc(-.5 * var(--bs-offcanvas-padding-y));margin-right:calc(-.5 * var(--bs-offcanvas-padding-x));margin-bottom:calc(-.5 * var(--bs-offcanvas-padding-y))}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{-webkit-animation:placeholder-glow 2s ease-in-out infinite;animation:placeholder-glow 2s ease-in-out infinite}@-webkit-keyframes placeholder-glow{50%{opacity:.2}}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;-webkit-animation:placeholder-wave 2s linear infinite;animation:placeholder-wave 2s linear infinite}@-webkit-keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(55,90,127,var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(68,68,68,var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(0,188,140,var(--bs-bg-opacity,1))!important}.text-bg-info{color:#fff!important;background-color:RGBA(52,152,219,var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#fff!important;background-color:RGBA(243,156,18,var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(231,76,60,var(--bs-bg-opacity,1))!important}.text-bg-light{color:#fff!important;background-color:RGBA(173,181,189,var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(48,48,48,var(--bs-bg-opacity,1))!important}.link-primary{color:#375a7f!important}.link-primary:focus,.link-primary:hover{color:#2c4866!important}.link-secondary{color:#444!important}.link-secondary:focus,.link-secondary:hover{color:#363636!important}.link-success{color:#00bc8c!important}.link-success:focus,.link-success:hover{color:#009670!important}.link-info{color:#3498db!important}.link-info:focus,.link-info:hover{color:#2a7aaf!important}.link-warning{color:#f39c12!important}.link-warning:focus,.link-warning:hover{color:#c27d0e!important}.link-danger{color:#e74c3c!important}.link-danger:focus,.link-danger:hover{color:#b93d30!important}.link-light{color:#adb5bd!important}.link-light:focus,.link-light:hover{color:#8a9197!important}.link-dark{color:#303030!important}.link-dark:focus,.link-dark:hover{color:#262626!important}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-1{--bs-border-width:1px}.border-2{--bs-border-width:2px}.border-3{--bs-border-width:3px}.border-4{--bs-border-width:4px}.border-5{--bs-border-width:5px}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.425rem + 2.1vw)!important}.fs-2{font-size:calc(1.375rem + 1.5vw)!important}.fs-3{font-size:calc(1.325rem + .9vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-light{font-weight:300!important}.fw-lighter{font-weight:lighter!important}.fw-normal{font-weight:400!important}.fw-bold{font-weight:700!important}.fw-semibold{font-weight:600!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:#888!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-2xl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:3rem!important}.fs-2{font-size:2.5rem!important}.fs-3{font-size:2rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}}:root{color-scheme:dark}.blockquote-footer{color:#888}.input-group-addon{color:#fff}.form-floating>label{color:#444}.nav-pills .nav-item.open .nav-link,.nav-pills .nav-item.open .nav-link:focus,.nav-pills .nav-item.open .nav-link:hover,.nav-pills .nav-link,.nav-pills .nav-link.active,.nav-pills .nav-link.active:focus,.nav-pills .nav-link.active:hover,.nav-tabs .nav-item.open .nav-link,.nav-tabs .nav-item.open .nav-link:focus,.nav-tabs .nav-item.open .nav-link:hover,.nav-tabs .nav-link,.nav-tabs .nav-link.active,.nav-tabs .nav-link.active:focus,.nav-tabs .nav-link.active:hover{color:#fff}.breadcrumb a{color:#fff}.pagination a:hover{text-decoration:none}.alert{color:#fff;border:none}.alert .alert-link,.alert a{color:#fff;text-decoration:underline}.alert-primary{background-color:#375a7f}.alert-secondary{background-color:#444}.alert-success{background-color:#00bc8c}.alert-info{background-color:#3498db}.alert-warning{background-color:#f39c12}.alert-danger{background-color:#e74c3c}.alert-light{background-color:#adb5bd}.alert-dark{background-color:#303030} \ No newline at end of file + */@import url(https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap);:root{--bs-blue:#375a7f;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#e83e8c;--bs-red:#e74c3c;--bs-orange:#fd7e14;--bs-yellow:#f39c12;--bs-green:#00bc8c;--bs-teal:#20c997;--bs-cyan:#3498db;--bs-black:#000;--bs-white:#fff;--bs-gray:#888;--bs-gray-dark:#303030;--bs-gray-100:#f8f9fa;--bs-gray-200:#ebebeb;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#888;--bs-gray-700:#444;--bs-gray-800:#303030;--bs-gray-900:#222;--bs-primary:#375a7f;--bs-secondary:#444;--bs-success:#00bc8c;--bs-info:#3498db;--bs-warning:#f39c12;--bs-danger:#e74c3c;--bs-light:#adb5bd;--bs-dark:#303030;--bs-primary-rgb:55,90,127;--bs-secondary-rgb:68,68,68;--bs-success-rgb:0,188,140;--bs-info-rgb:52,152,219;--bs-warning-rgb:243,156,18;--bs-danger-rgb:231,76,60;--bs-light-rgb:173,181,189;--bs-dark-rgb:48,48,48;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:255,255,255;--bs-body-bg-rgb:34,34,34;--bs-font-sans-serif:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#fff;--bs-body-bg:#222;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#00bc8c;--bs-link-hover-color:#009670;--bs-code-color:#e83e8c;--bs-highlight-bg:#fdebd0}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:1px solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:calc(1.425rem + 2.1vw)}@media (min-width:1200px){.h1,h1{font-size:3rem}}.h2,h2{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h2,h2{font-size:2.5rem}}.h3,h3{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h3,h3{font-size:2rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--bs-link-color);text-decoration:underline}a:hover{color:var(--bs-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em;color:inherit}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#888;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#888}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#222;border:1px solid var(--bs-border-color);border-radius:.375rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#888}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color:var(--bs-body-color);--bs-table-bg:transparent;--bs-table-border-color:#444;--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-body-color);--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:var(--bs-body-color);--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:var(--bs-body-color);--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:var(--bs-table-color);vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:2px solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-striped-columns>:not(caption)>tr>:nth-child(even){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-color:#fff;--bs-table-bg:#375a7f;--bs-table-border-color:#4b6b8c;--bs-table-striped-bg:#416285;--bs-table-striped-color:#fff;--bs-table-active-bg:#4b6b8c;--bs-table-active-color:#fff;--bs-table-hover-bg:#466689;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#fff;--bs-table-bg:#444444;--bs-table-border-color:#575757;--bs-table-striped-bg:#4d4d4d;--bs-table-striped-color:#fff;--bs-table-active-bg:#575757;--bs-table-active-color:#fff;--bs-table-hover-bg:#525252;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#fff;--bs-table-bg:#00bc8c;--bs-table-border-color:#1ac398;--bs-table-striped-bg:#0dbf92;--bs-table-striped-color:#fff;--bs-table-active-bg:#1ac398;--bs-table-active-color:#fff;--bs-table-hover-bg:#13c195;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#fff;--bs-table-bg:#3498db;--bs-table-border-color:#48a2df;--bs-table-striped-bg:#3e9ddd;--bs-table-striped-color:#fff;--bs-table-active-bg:#48a2df;--bs-table-active-color:#fff;--bs-table-hover-bg:#43a0de;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#fff;--bs-table-bg:#f39c12;--bs-table-border-color:#f4a62a;--bs-table-striped-bg:#f4a11e;--bs-table-striped-color:#fff;--bs-table-active-bg:#f4a62a;--bs-table-active-color:#fff;--bs-table-hover-bg:#f4a324;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#fff;--bs-table-bg:#e74c3c;--bs-table-border-color:#e95e50;--bs-table-striped-bg:#e85546;--bs-table-striped-color:#fff;--bs-table-active-bg:#e95e50;--bs-table-active-color:#fff;--bs-table-hover-bg:#e9594b;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#fff;--bs-table-bg:#adb5bd;--bs-table-border-color:#b5bcc4;--bs-table-striped-bg:#b1b9c0;--bs-table-striped-color:#fff;--bs-table-active-bg:#b5bcc4;--bs-table-active-color:#fff;--bs-table-hover-bg:#b3bbc2;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#303030;--bs-table-border-color:#454545;--bs-table-striped-bg:#3a3a3a;--bs-table-striped-color:#fff;--bs-table-active-bg:#454545;--bs-table-active-color:#fff;--bs-table-hover-bg:#404040;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:#888}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#303030;background-color:#fff;background-clip:padding-box;border:1px solid #222;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#303030;background-color:#fff;border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-moz-placeholder{color:#888;opacity:1}.form-control::placeholder{color:#888;opacity:1}.form-control:disabled{background-color:#ebebeb;opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#fff;background-color:#444;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#fff;background-color:#444;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#414141}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#414141}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#fff;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{width:3rem;height:calc(1.5em + .75rem + 2px);padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:.375rem}.form-control-color::-webkit-color-swatch{border-radius:.375rem}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + 2px)}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + 2px)}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:#303030;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #222;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#ebebeb}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #303030}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:.25rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:.5rem}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-check-input:checked{background-color:#375a7f;border-color:#375a7f}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#375a7f;border-color:#375a7f;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%239badbf'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #222,0 0 0 .25rem rgba(55,90,127,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #222,0 0 0 .25rem rgba(55,90,127,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#375a7f;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#c3ced9}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#375a7f;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#c3ced9}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;width:100%;height:100%;padding:1rem .75rem;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::-moz-placeholder,.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown),.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:1px 0}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#adb5bd;text-align:center;white-space:nowrap;background-color:#444;border:1px solid #222;border-radius:.375rem}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#00bc8c}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(0,188,140,.9);border-radius:.375rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#00bc8c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#00bc8c}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#00bc8c}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#00bc8c}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#00bc8c}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#e74c3c}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(231,76,60,.9);border-radius:.375rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#e74c3c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#e74c3c}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#e74c3c}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#e74c3c}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#e74c3c}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#fff;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:first-child:hover,:not(.btn-check)+.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#375a7f;--bs-btn-border-color:#375a7f;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#2f4d6c;--bs-btn-hover-border-color:#2c4866;--bs-btn-focus-shadow-rgb:85,115,146;--bs-btn-active-color:#fff;--bs-btn-active-bg:#2c4866;--bs-btn-active-border-color:#29445f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#375a7f;--bs-btn-disabled-border-color:#375a7f}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#444;--bs-btn-border-color:#444;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#3a3a3a;--bs-btn-hover-border-color:#363636;--bs-btn-focus-shadow-rgb:96,96,96;--bs-btn-active-color:#fff;--bs-btn-active-bg:#363636;--bs-btn-active-border-color:#333333;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#444;--bs-btn-disabled-border-color:#444}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#00bc8c;--bs-btn-border-color:#00bc8c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#00a077;--bs-btn-hover-border-color:#009670;--bs-btn-focus-shadow-rgb:38,198,157;--bs-btn-active-color:#fff;--bs-btn-active-bg:#009670;--bs-btn-active-border-color:#008d69;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#00bc8c;--bs-btn-disabled-border-color:#00bc8c}.btn-info{--bs-btn-color:#fff;--bs-btn-bg:#3498db;--bs-btn-border-color:#3498db;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#2c81ba;--bs-btn-hover-border-color:#2a7aaf;--bs-btn-focus-shadow-rgb:82,167,224;--bs-btn-active-color:#fff;--bs-btn-active-bg:#2a7aaf;--bs-btn-active-border-color:#2772a4;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#3498db;--bs-btn-disabled-border-color:#3498db}.btn-warning{--bs-btn-color:#fff;--bs-btn-bg:#f39c12;--bs-btn-border-color:#f39c12;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#cf850f;--bs-btn-hover-border-color:#c27d0e;--bs-btn-focus-shadow-rgb:245,171,54;--bs-btn-active-color:#fff;--bs-btn-active-bg:#c27d0e;--bs-btn-active-border-color:#b6750e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#f39c12;--bs-btn-disabled-border-color:#f39c12}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#e74c3c;--bs-btn-border-color:#e74c3c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#c44133;--bs-btn-hover-border-color:#b93d30;--bs-btn-focus-shadow-rgb:235,103,89;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b93d30;--bs-btn-active-border-color:#ad392d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#e74c3c;--bs-btn-disabled-border-color:#e74c3c}.btn-light{--bs-btn-color:#fff;--bs-btn-bg:#adb5bd;--bs-btn-border-color:#adb5bd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#939aa1;--bs-btn-hover-border-color:#8a9197;--bs-btn-focus-shadow-rgb:185,192,199;--bs-btn-active-color:#fff;--bs-btn-active-bg:#8a9197;--bs-btn-active-border-color:#82888e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#adb5bd;--bs-btn-disabled-border-color:#adb5bd}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#303030;--bs-btn-border-color:#303030;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#4f4f4f;--bs-btn-hover-border-color:#454545;--bs-btn-focus-shadow-rgb:79,79,79;--bs-btn-active-color:#fff;--bs-btn-active-bg:#595959;--bs-btn-active-border-color:#454545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#303030;--bs-btn-disabled-border-color:#303030}.btn-outline-primary{--bs-btn-color:#375a7f;--bs-btn-border-color:#375a7f;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#375a7f;--bs-btn-hover-border-color:#375a7f;--bs-btn-focus-shadow-rgb:55,90,127;--bs-btn-active-color:#fff;--bs-btn-active-bg:#375a7f;--bs-btn-active-border-color:#375a7f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#375a7f;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#375a7f;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#444;--bs-btn-border-color:#444;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#444;--bs-btn-hover-border-color:#444;--bs-btn-focus-shadow-rgb:68,68,68;--bs-btn-active-color:#fff;--bs-btn-active-bg:#444;--bs-btn-active-border-color:#444;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#444;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#444;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#00bc8c;--bs-btn-border-color:#00bc8c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#00bc8c;--bs-btn-hover-border-color:#00bc8c;--bs-btn-focus-shadow-rgb:0,188,140;--bs-btn-active-color:#fff;--bs-btn-active-bg:#00bc8c;--bs-btn-active-border-color:#00bc8c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#00bc8c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#00bc8c;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#3498db;--bs-btn-border-color:#3498db;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#3498db;--bs-btn-hover-border-color:#3498db;--bs-btn-focus-shadow-rgb:52,152,219;--bs-btn-active-color:#fff;--bs-btn-active-bg:#3498db;--bs-btn-active-border-color:#3498db;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#3498db;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#3498db;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#f39c12;--bs-btn-border-color:#f39c12;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#f39c12;--bs-btn-hover-border-color:#f39c12;--bs-btn-focus-shadow-rgb:243,156,18;--bs-btn-active-color:#fff;--bs-btn-active-bg:#f39c12;--bs-btn-active-border-color:#f39c12;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f39c12;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f39c12;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#e74c3c;--bs-btn-border-color:#e74c3c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#e74c3c;--bs-btn-hover-border-color:#e74c3c;--bs-btn-focus-shadow-rgb:231,76,60;--bs-btn-active-color:#fff;--bs-btn-active-bg:#e74c3c;--bs-btn-active-border-color:#e74c3c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#e74c3c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#e74c3c;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#adb5bd;--bs-btn-border-color:#adb5bd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#adb5bd;--bs-btn-hover-border-color:#adb5bd;--bs-btn-focus-shadow-rgb:173,181,189;--bs-btn-active-color:#fff;--bs-btn-active-bg:#adb5bd;--bs-btn-active-border-color:#adb5bd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#adb5bd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#adb5bd;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#303030;--bs-btn-border-color:#303030;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#303030;--bs-btn-hover-border-color:#303030;--bs-btn-focus-shadow-rgb:48,48,48;--bs-btn-active-color:#fff;--bs-btn-active-bg:#303030;--bs-btn-active-border-color:#303030;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#303030;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#303030;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#888;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:85,115,146;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:0.5rem}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:0.25rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:#fff;--bs-dropdown-bg:#222;--bs-dropdown-border-color:#444;--bs-dropdown-border-radius:0.375rem;--bs-dropdown-border-width:1px;--bs-dropdown-inner-border-radius:calc(0.375rem - 1px);--bs-dropdown-divider-bg:#444;--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-dropdown-link-color:#fff;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-link-hover-bg:#375a7f;--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#375a7f;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#888;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#303030;--bs-dropdown-border-color:#444;--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:#444;--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#375a7f;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:.375rem}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:2rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#adb5bd;display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#444;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#444 #444 transparent;--bs-nav-tabs-link-active-color:#fff;--bs-nav-tabs-link-active-bg:#222;--bs-nav-tabs-link-active-border-color:#444 #444 transparent;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:0.375rem;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#375a7f}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:1rem;--bs-navbar-color:rgba(34, 34, 34, 0.7);--bs-navbar-hover-color:#222;--bs-navbar-disabled-color:rgba(0, 0, 0, 0.3);--bs-navbar-active-color:#222;--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:#222;--bs-navbar-brand-hover-color:#222;--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2834, 34, 34, 0.7%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(34, 34, 34, 0.1);--bs-navbar-toggler-border-radius:0.375rem;--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .show>.nav-link{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark{--bs-navbar-color:rgba(255, 255, 255, 0.6);--bs-navbar-hover-color:#fff;--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.6%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-border-width:1px;--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:0.375rem;--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(0.375rem - 1px);--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:#444;--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:#303030;--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:#222;--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:1px;--bs-accordion-border-radius:0.375rem;--bs-accordion-inner-border-radius:calc(0.375rem - 1px);--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='var%28--bs-body-color%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23325172'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-focus-border-color:#9badbf;--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(55, 90, 127, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:#325172;--bs-accordion-active-bg:#ebeff2}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:var(--bs-accordion-btn-focus-border-color);outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button,.accordion-flush .accordion-item .accordion-button.collapsed{border-radius:0}.breadcrumb{--bs-breadcrumb-padding-x:0.75rem;--bs-breadcrumb-padding-y:0.375rem;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg:#444;--bs-breadcrumb-border-radius:0.25rem;--bs-breadcrumb-divider-color:#888;--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:#888;display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:#fff;--bs-pagination-bg:#00bc8c;--bs-pagination-border-width:0;--bs-pagination-border-color:transparent;--bs-pagination-border-radius:0.375rem;--bs-pagination-hover-color:#fff;--bs-pagination-hover-bg:#00efb2;--bs-pagination-hover-border-color:transparent;--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:#ebebeb;--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(55, 90, 127, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#00efb2;--bs-pagination-active-border-color:transparent;--bs-pagination-disabled-color:#fff;--bs-pagination-disabled-bg:#007053;--bs-pagination-disabled-border-color:transparent;display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:0.5rem}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:0.25rem}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:0.375rem;display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:1px solid var(--bs-alert-border-color);--bs-alert-border-radius:0.375rem;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:#21364c;--bs-alert-bg:#d7dee5;--bs-alert-border-color:#c3ced9}.alert-primary .alert-link{color:#1a2b3d}.alert-secondary{--bs-alert-color:#292929;--bs-alert-bg:#dadada;--bs-alert-border-color:#c7c7c7}.alert-secondary .alert-link{color:#212121}.alert-success{--bs-alert-color:#007154;--bs-alert-bg:#ccf2e8;--bs-alert-border-color:#b3ebdd}.alert-success .alert-link{color:#005a43}.alert-info{--bs-alert-color:#1f5b83;--bs-alert-bg:#d6eaf8;--bs-alert-border-color:#c2e0f4}.alert-info .alert-link{color:#194969}.alert-warning{--bs-alert-color:#925e0b;--bs-alert-bg:#fdebd0;--bs-alert-border-color:#fbe1b8}.alert-warning .alert-link{color:#754b09}.alert-danger{--bs-alert-color:#8b2e24;--bs-alert-bg:#fadbd8;--bs-alert-border-color:#f8c9c5}.alert-danger .alert-link{color:#6f251d}.alert-light{--bs-alert-color:#686d71;--bs-alert-bg:#eff0f2;--bs-alert-border-color:#e6e9eb}.alert-light .alert-link{color:#53575a}.alert-dark{--bs-alert-color:#1d1d1d;--bs-alert-bg:#d6d6d6;--bs-alert-border-color:#c1c1c1}.alert-dark .alert-link{color:#171717}@-webkit-keyframes progress-bar-stripes{0%{background-position-x:1rem}}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:#444;--bs-progress-border-radius:0.375rem;--bs-progress-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#375a7f;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.list-group{--bs-list-group-color:#fff;--bs-list-group-bg:#303030;--bs-list-group-border-color:#444;--bs-list-group-border-width:1px;--bs-list-group-border-radius:0.375rem;--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:#444;--bs-list-group-action-hover-color:#fff;--bs-list-group-action-hover-bg:#444;--bs-list-group-action-active-color:#fff;--bs-list-group-action-active-bg:#222;--bs-list-group-disabled-color:#888;--bs-list-group-disabled-bg:#303030;--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#375a7f;--bs-list-group-active-border-color:#375a7f;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#21364c;background-color:#d7dee5}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#21364c;background-color:#c2c8ce}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#21364c;border-color:#21364c}.list-group-item-secondary{color:#292929;background-color:#dadada}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#292929;background-color:#c4c4c4}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#292929;border-color:#292929}.list-group-item-success{color:#007154;background-color:#ccf2e8}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#007154;background-color:#b8dad1}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#007154;border-color:#007154}.list-group-item-info{color:#1f5b83;background-color:#d6eaf8}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#1f5b83;background-color:#c1d3df}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#1f5b83;border-color:#1f5b83}.list-group-item-warning{color:#925e0b;background-color:#fdebd0}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#925e0b;background-color:#e4d4bb}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#925e0b;border-color:#925e0b}.list-group-item-danger{color:#8b2e24;background-color:#fadbd8}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#8b2e24;background-color:#e1c5c2}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#8b2e24;border-color:#8b2e24}.list-group-item-light{color:#686d71;background-color:#eff0f2}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#686d71;background-color:#d7d8da}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#686d71;border-color:#686d71}.list-group-item-dark{color:#1d1d1d;background-color:#d6d6d6}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1d1d1d;background-color:#c1c1c1}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1d1d1d;border-color:#1d1d1d}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#fff;background:transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.375rem;opacity:.4}.btn-close:hover{color:#fff;text-decoration:none;opacity:1}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25);opacity:1}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:#444;--bs-toast-border-width:1px;--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:0.375rem;--bs-toast-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-toast-header-color:#888;--bs-toast-header-bg:#303030;--bs-toast-header-border-color:rgba(0, 0, 0, 0.05);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{position:absolute;z-index:var(--bs-toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:#303030;--bs-modal-border-color:#444;--bs-modal-border-width:1px;--bs-modal-border-radius:0.5rem;--bs-modal-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-modal-inner-border-radius:calc(0.5rem - 1px);--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:#444;--bs-modal-header-border-width:1px;--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:#444;--bs-modal-footer-border-width:1px;position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin:calc(-.5 * var(--bs-modal-header-padding-y)) calc(-.5 * var(--bs-modal-header-padding-x)) calc(-.5 * var(--bs-modal-header-padding-y)) auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:#fff;--bs-tooltip-bg:#000;--bs-tooltip-border-radius:0.375rem;--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;padding:var(--bs-tooltip-arrow-height);margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:#303030;--bs-popover-border-width:1px;--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:0.5rem;--bs-popover-inner-border-radius:calc(0.5rem - 1px);--bs-popover-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color: ;--bs-popover-header-bg:#444;--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:#fff;--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;-webkit-animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name);animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@-webkit-keyframes spinner-border{to{transform:rotate(360deg)}}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color: ;--bs-offcanvas-bg:#303030;--bs-offcanvas-border-width:1px;--bs-offcanvas-border-color:#444;--bs-offcanvas-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075)}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:575.98px){.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}}@media (max-width:575.98px){.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:767.98px){.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}}@media (max-width:767.98px){.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:991.98px){.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}}@media (max-width:991.98px){.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1199.98px){.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}}@media (max-width:1199.98px){.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}}@media (max-width:1399.98px){.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin-top:calc(-.5 * var(--bs-offcanvas-padding-y));margin-right:calc(-.5 * var(--bs-offcanvas-padding-x));margin-bottom:calc(-.5 * var(--bs-offcanvas-padding-y))}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{-webkit-animation:placeholder-glow 2s ease-in-out infinite;animation:placeholder-glow 2s ease-in-out infinite}@-webkit-keyframes placeholder-glow{50%{opacity:.2}}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;-webkit-animation:placeholder-wave 2s linear infinite;animation:placeholder-wave 2s linear infinite}@-webkit-keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(55,90,127,var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(68,68,68,var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(0,188,140,var(--bs-bg-opacity,1))!important}.text-bg-info{color:#fff!important;background-color:RGBA(52,152,219,var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#fff!important;background-color:RGBA(243,156,18,var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(231,76,60,var(--bs-bg-opacity,1))!important}.text-bg-light{color:#fff!important;background-color:RGBA(173,181,189,var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(48,48,48,var(--bs-bg-opacity,1))!important}.link-primary{color:#375a7f!important}.link-primary:focus,.link-primary:hover{color:#2c4866!important}.link-secondary{color:#444!important}.link-secondary:focus,.link-secondary:hover{color:#363636!important}.link-success{color:#00bc8c!important}.link-success:focus,.link-success:hover{color:#009670!important}.link-info{color:#3498db!important}.link-info:focus,.link-info:hover{color:#2a7aaf!important}.link-warning{color:#f39c12!important}.link-warning:focus,.link-warning:hover{color:#c27d0e!important}.link-danger{color:#e74c3c!important}.link-danger:focus,.link-danger:hover{color:#b93d30!important}.link-light{color:#adb5bd!important}.link-light:focus,.link-light:hover{color:#8a9197!important}.link-dark{color:#303030!important}.link-dark:focus,.link-dark:hover{color:#262626!important}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-1{--bs-border-width:1px}.border-2{--bs-border-width:2px}.border-3{--bs-border-width:3px}.border-4{--bs-border-width:4px}.border-5{--bs-border-width:5px}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.425rem + 2.1vw)!important}.fs-2{font-size:calc(1.375rem + 1.5vw)!important}.fs-3{font-size:calc(1.325rem + .9vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-light{font-weight:300!important}.fw-lighter{font-weight:lighter!important}.fw-normal{font-weight:400!important}.fw-bold{font-weight:700!important}.fw-semibold{font-weight:600!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:#888!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-2xl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:3rem!important}.fs-2{font-size:2.5rem!important}.fs-3{font-size:2rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}}:root{color-scheme:dark}.blockquote-footer{color:#888}.input-group-addon{color:#fff}.form-floating>label{color:#444}.nav-pills .nav-item.open .nav-link,.nav-pills .nav-item.open .nav-link:focus,.nav-pills .nav-item.open .nav-link:hover,.nav-pills .nav-link,.nav-pills .nav-link.active,.nav-pills .nav-link.active:focus,.nav-pills .nav-link.active:hover,.nav-tabs .nav-item.open .nav-link,.nav-tabs .nav-item.open .nav-link:focus,.nav-tabs .nav-item.open .nav-link:hover,.nav-tabs .nav-link,.nav-tabs .nav-link.active,.nav-tabs .nav-link.active:focus,.nav-tabs .nav-link.active:hover{color:#fff}.breadcrumb a{color:#fff}.pagination a:hover{text-decoration:none}.alert{color:#fff;border:none}.alert .alert-link,.alert a{color:#fff;text-decoration:underline}.alert-primary{background-color:#375a7f}.alert-secondary{background-color:#444}.alert-success{background-color:#00bc8c}.alert-info{background-color:#3498db}.alert-warning{background-color:#f39c12}.alert-danger{background-color:#e74c3c}.alert-light{background-color:#adb5bd}.alert-dark{background-color:#303030} \ No newline at end of file From da7b4b6ad1e6e8f7f8a8e8d9cab7a3b984dbfdc2 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 16 Oct 2022 13:07:43 +0200 Subject: [PATCH 573/629] version bumps --- gradle/kotlin-js-store/yarn.lock | 42 +++++++++---------- gradle/libs.versions.toml | 16 +++---- .../src/main/resources/css/bootstrap.min.css | 6 +-- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index 13a5eca..8e776d3 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -540,10 +540,10 @@ bootstrap-icons@^1.9.1: resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.9.1.tgz#cf22d91a25447645e45c49ebde4e56eafdfe761b" integrity sha512-d4ZkO30MIkAhQ2nNRJqKXJVEQorALGbLWTuRxyCTJF96lRIV6imcgMehWGJUiJMJhglN0o2tqLIeDnMdiQEE9g== -bootstrap@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.2.1.tgz#45f97ff05cbe828bad807b014d8425f3aeb8ec3a" - integrity sha512-UQi3v2NpVPEi1n35dmRRzBJFlgvWHYwyem6yHhuT6afYF+sziEt46McRbT//kVXZ7b1YUYEVGdXEH74Nx3xzGA== +bootstrap@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.2.2.tgz#834e053eed584a65e244d8aa112a6959f56e27a0" + integrity sha512-dEtzMTV71n6Fhmbg4fYJzQsw1N29hJKO1js5ackCgIpDcGid2ETMGC6zwSYw09v05Y+oRdQ9loC54zB1La3hHQ== brace-expansion@^1.1.7: version "1.1.11" @@ -1751,10 +1751,10 @@ karma-webpack@5.0.0: minimatch "^3.0.4" webpack-merge "^4.1.5" -karma@6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.0.tgz#82652dfecdd853ec227b74ed718a997028a99508" - integrity sha512-s8m7z0IF5g/bS5ONT7wsOavhW4i4aFkzD4u4wgzAQWT4HGUeWI3i21cK2Yz6jndMAeHETp5XuNsRoyGJZXVd4w== +karma@6.4.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.1.tgz#f2253716dd3a41aaa813fa9f54b6ee047e1127d9" + integrity sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA== dependencies: "@colors/colors" "1.5.0" body-parser "^1.19.0" @@ -1791,10 +1791,10 @@ kvision-assets@^6.0.0: resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-6.0.0.tgz#de17ec942efd067fc180e7fab4e040c4e41bbe25" integrity sha512-fjPGTMGiboRnXXwhQFVOsRdDaDFnBfAQBRGhbzjQUp5oJKUnPS303Pua0u5atQdYMXyN/u6fyH6TEHgQzM9Wog== -leaflet@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.8.0.tgz#4615db4a22a304e8e692cae9270b983b38a2055e" - integrity sha512-gwhMjFCQiYs3x/Sf+d49f10ERXaEFCPr+nVTryhAW8DWbMGqJqt9G4XuIaHmFW08zYvhgdzqXGr8AlW8v8dQkA== +leaflet@^1.9.1: + version "1.9.2" + resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.9.2.tgz#168b6c6ef1d4d1e8409bde2c4ad050c249c4dbe6" + integrity sha512-Kc77HQvWO+y9y2oIs3dn5h5sy2kr3j41ewdqCMEUA4N89lgfUUfOBy7wnnHEstDpefiGFObq12FdopGRMx4J7g== loader-runner@^4.2.0: version "4.3.0" @@ -2443,10 +2443,10 @@ select-hose@^2.0.0: resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== -selfsigned@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" - integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ== +selfsigned@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61" + integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== dependencies: node-forge "^1" @@ -2913,10 +2913,10 @@ webpack-dev-middleware@^5.3.1: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@4.11.0: - version "4.11.0" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.11.0.tgz#290ee594765cd8260adfe83b2d18115ea04484e7" - integrity sha512-L5S4Q2zT57SK7tazgzjMiSMBdsw+rGYIX27MgPgx7LDhWO0lViPrHKoLS7jo5In06PWYAhlYu3PbyoC6yAThbw== +webpack-dev-server@4.11.1: + version "4.11.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz#ae07f0d71ca0438cf88446f09029b92ce81380b5" + integrity sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw== dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5" @@ -2941,7 +2941,7 @@ webpack-dev-server@4.11.0: p-retry "^4.5.0" rimraf "^3.0.2" schema-utils "^4.0.0" - selfsigned "^2.0.1" + selfsigned "^2.1.1" serve-index "^1.9.1" sockjs "^0.3.24" spdy "^4.0.2" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 52dc66c..6dd27ee 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ kotlin = "1.7.20" camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" kafka = "3.3.1" # https://kafka.apache.org/downloads -kvision = "5.15.3" # https://github.com/rjaros/kvision/releases +kvision = "5.16.1" # https://github.com/rjaros/kvision/releases log4j2 = "2.17.2" okio = "3.2.0" # https://search.maven.org/artifact/com.squareup.okio/okio qosLogback = "1.2.11" @@ -20,12 +20,12 @@ scrimage = "4.0.32" # https://github.com/sksamuel/scrimage/r semver = "1.2.0" # https://github.com/swiftzer/semver/releases slf4j = "1.7.36" -kotlinx-serialization = "1.4.0" # https://github.com/Kotlin/kotlinx.serialization/releases +kotlinx-serialization = "1.4.1" # https://github.com/Kotlin/kotlinx.serialization/releases kxs-charleskornKaml = "0.44.0" kxs-mamoeYamlkt = "0.12.0" kxs-kxsTsGen = "0.2.1" -kotlinJsWrappers = "1.0.0-pre.399" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom +kotlinJsWrappers = "1.0.0-pre.407" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom kotlinx-cli = "0.3.4" kotlinx-coroutines = "1.6.4" # https://github.com/Kotlin/kotlinx.coroutines/releases @@ -37,7 +37,7 @@ kSvgDsl = "v2.2.0" ktor = "2.1.2" # https://github.com/ktorio/ktor/releases -hoplite = "2.6.4" # https://github.com/sksamuel/hoplite/releases +hoplite = "2.6.5" # https://github.com/sksamuel/hoplite/releases simpleSyslogParser = "1.0.0" # https://search.maven.org/artifact/com.github.palindromicity/simple-syslog @@ -47,16 +47,16 @@ marykRocksDb = "7.3.1-2" # https://search.maven.org/artifact/io.m klogging = "0.4.9" -nimbusJoseJwt = "9.25.4" # https://search.maven.org/artifact/com.nimbusds/nimbus-jose-jwt +nimbusJoseJwt = "9.25.6" # https://search.maven.org/artifact/com.nimbusds/nimbus-jose-jwt ## npm ## npm-luaTypes = "2.13.0" # https://www.npmjs.com/package/lua-types npm-typescriptToLua = "1.10.1" # https://www.npmjs.com/package/typescript-to-lua -npm-typedFactorio = "1.8.1" # https://www.npmjs.com/package/typed-factorio +npm-typedFactorio = "1.8.1" # https://github.com/GlassBricks/typed-factorio/blob/main/Changelog.md https://www.npmjs.com/package/typed-factorio npm-typescript = "4.8.4" # https://github.com/microsoft/TypeScript/releases -npm-bootswatch = "5.2.1" # https://www.jsdelivr.com/package/npm/bootswatch +npm-bootswatch = "5.2.2" # https://www.jsdelivr.com/package/npm/bootswatch ## test ## junit = "5.9.1" # https://github.com/junit-team/junit5/releases @@ -72,7 +72,7 @@ prometheus = "v2.34.0" ## gradle plugins ## -gradleNodePlugin = "3.4.0" # https://github.com/node-gradle/gradle-node-plugin/releases +gradleNodePlugin = "3.4.0" # https://github.com/node-gradle/gradle-node-plugin/releases ######### diff --git a/modules/web-map/src/main/resources/css/bootstrap.min.css b/modules/web-map/src/main/resources/css/bootstrap.min.css index 4452fb1..daca156 100644 --- a/modules/web-map/src/main/resources/css/bootstrap.min.css +++ b/modules/web-map/src/main/resources/css/bootstrap.min.css @@ -1,12 +1,12 @@ @charset "UTF-8";/*! - * Bootswatch v5.2.1 (https://bootswatch.com) + * Bootswatch v5.2.2 (https://bootswatch.com) * Theme: darkly * Copyright 2012-2022 Thomas Park * Licensed under MIT * Based on Bootstrap *//*! - * Bootstrap v5.2.1 (https://getbootstrap.com/) + * Bootstrap v5.2.2 (https://getbootstrap.com/) * Copyright 2011-2022 The Bootstrap Authors * Copyright 2011-2022 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */@import url(https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap);:root{--bs-blue:#375a7f;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#e83e8c;--bs-red:#e74c3c;--bs-orange:#fd7e14;--bs-yellow:#f39c12;--bs-green:#00bc8c;--bs-teal:#20c997;--bs-cyan:#3498db;--bs-black:#000;--bs-white:#fff;--bs-gray:#888;--bs-gray-dark:#303030;--bs-gray-100:#f8f9fa;--bs-gray-200:#ebebeb;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#888;--bs-gray-700:#444;--bs-gray-800:#303030;--bs-gray-900:#222;--bs-primary:#375a7f;--bs-secondary:#444;--bs-success:#00bc8c;--bs-info:#3498db;--bs-warning:#f39c12;--bs-danger:#e74c3c;--bs-light:#adb5bd;--bs-dark:#303030;--bs-primary-rgb:55,90,127;--bs-secondary-rgb:68,68,68;--bs-success-rgb:0,188,140;--bs-info-rgb:52,152,219;--bs-warning-rgb:243,156,18;--bs-danger-rgb:231,76,60;--bs-light-rgb:173,181,189;--bs-dark-rgb:48,48,48;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:255,255,255;--bs-body-bg-rgb:34,34,34;--bs-font-sans-serif:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#fff;--bs-body-bg:#222;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#00bc8c;--bs-link-hover-color:#009670;--bs-code-color:#e83e8c;--bs-highlight-bg:#fdebd0}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:1px solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:calc(1.425rem + 2.1vw)}@media (min-width:1200px){.h1,h1{font-size:3rem}}.h2,h2{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h2,h2{font-size:2.5rem}}.h3,h3{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h3,h3{font-size:2rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--bs-link-color);text-decoration:underline}a:hover{color:var(--bs-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em;color:inherit}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#888;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#888}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#222;border:1px solid var(--bs-border-color);border-radius:.375rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#888}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color:var(--bs-body-color);--bs-table-bg:transparent;--bs-table-border-color:#444;--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-body-color);--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:var(--bs-body-color);--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:var(--bs-body-color);--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:var(--bs-table-color);vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:2px solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-striped-columns>:not(caption)>tr>:nth-child(even){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-color:#fff;--bs-table-bg:#375a7f;--bs-table-border-color:#4b6b8c;--bs-table-striped-bg:#416285;--bs-table-striped-color:#fff;--bs-table-active-bg:#4b6b8c;--bs-table-active-color:#fff;--bs-table-hover-bg:#466689;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#fff;--bs-table-bg:#444444;--bs-table-border-color:#575757;--bs-table-striped-bg:#4d4d4d;--bs-table-striped-color:#fff;--bs-table-active-bg:#575757;--bs-table-active-color:#fff;--bs-table-hover-bg:#525252;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#fff;--bs-table-bg:#00bc8c;--bs-table-border-color:#1ac398;--bs-table-striped-bg:#0dbf92;--bs-table-striped-color:#fff;--bs-table-active-bg:#1ac398;--bs-table-active-color:#fff;--bs-table-hover-bg:#13c195;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#fff;--bs-table-bg:#3498db;--bs-table-border-color:#48a2df;--bs-table-striped-bg:#3e9ddd;--bs-table-striped-color:#fff;--bs-table-active-bg:#48a2df;--bs-table-active-color:#fff;--bs-table-hover-bg:#43a0de;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#fff;--bs-table-bg:#f39c12;--bs-table-border-color:#f4a62a;--bs-table-striped-bg:#f4a11e;--bs-table-striped-color:#fff;--bs-table-active-bg:#f4a62a;--bs-table-active-color:#fff;--bs-table-hover-bg:#f4a324;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#fff;--bs-table-bg:#e74c3c;--bs-table-border-color:#e95e50;--bs-table-striped-bg:#e85546;--bs-table-striped-color:#fff;--bs-table-active-bg:#e95e50;--bs-table-active-color:#fff;--bs-table-hover-bg:#e9594b;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#fff;--bs-table-bg:#adb5bd;--bs-table-border-color:#b5bcc4;--bs-table-striped-bg:#b1b9c0;--bs-table-striped-color:#fff;--bs-table-active-bg:#b5bcc4;--bs-table-active-color:#fff;--bs-table-hover-bg:#b3bbc2;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#303030;--bs-table-border-color:#454545;--bs-table-striped-bg:#3a3a3a;--bs-table-striped-color:#fff;--bs-table-active-bg:#454545;--bs-table-active-color:#fff;--bs-table-hover-bg:#404040;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:#888}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#303030;background-color:#fff;background-clip:padding-box;border:1px solid #222;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#303030;background-color:#fff;border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-moz-placeholder{color:#888;opacity:1}.form-control::placeholder{color:#888;opacity:1}.form-control:disabled{background-color:#ebebeb;opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#fff;background-color:#444;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#fff;background-color:#444;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#414141}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#414141}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#fff;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{width:3rem;height:calc(1.5em + .75rem + 2px);padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:.375rem}.form-control-color::-webkit-color-swatch{border-radius:.375rem}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + 2px)}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + 2px)}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:#303030;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #222;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#ebebeb}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #303030}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:.25rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:.5rem}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-check-input:checked{background-color:#375a7f;border-color:#375a7f}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#375a7f;border-color:#375a7f;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%239badbf'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #222,0 0 0 .25rem rgba(55,90,127,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #222,0 0 0 .25rem rgba(55,90,127,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#375a7f;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#c3ced9}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#375a7f;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#c3ced9}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;width:100%;height:100%;padding:1rem .75rem;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::-moz-placeholder,.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown),.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:1px 0}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#adb5bd;text-align:center;white-space:nowrap;background-color:#444;border:1px solid #222;border-radius:.375rem}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#00bc8c}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(0,188,140,.9);border-radius:.375rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#00bc8c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#00bc8c}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#00bc8c}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#00bc8c}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#00bc8c}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#e74c3c}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(231,76,60,.9);border-radius:.375rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#e74c3c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#e74c3c}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#e74c3c}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#e74c3c}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#e74c3c}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#fff;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:first-child:hover,:not(.btn-check)+.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#375a7f;--bs-btn-border-color:#375a7f;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#2f4d6c;--bs-btn-hover-border-color:#2c4866;--bs-btn-focus-shadow-rgb:85,115,146;--bs-btn-active-color:#fff;--bs-btn-active-bg:#2c4866;--bs-btn-active-border-color:#29445f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#375a7f;--bs-btn-disabled-border-color:#375a7f}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#444;--bs-btn-border-color:#444;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#3a3a3a;--bs-btn-hover-border-color:#363636;--bs-btn-focus-shadow-rgb:96,96,96;--bs-btn-active-color:#fff;--bs-btn-active-bg:#363636;--bs-btn-active-border-color:#333333;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#444;--bs-btn-disabled-border-color:#444}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#00bc8c;--bs-btn-border-color:#00bc8c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#00a077;--bs-btn-hover-border-color:#009670;--bs-btn-focus-shadow-rgb:38,198,157;--bs-btn-active-color:#fff;--bs-btn-active-bg:#009670;--bs-btn-active-border-color:#008d69;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#00bc8c;--bs-btn-disabled-border-color:#00bc8c}.btn-info{--bs-btn-color:#fff;--bs-btn-bg:#3498db;--bs-btn-border-color:#3498db;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#2c81ba;--bs-btn-hover-border-color:#2a7aaf;--bs-btn-focus-shadow-rgb:82,167,224;--bs-btn-active-color:#fff;--bs-btn-active-bg:#2a7aaf;--bs-btn-active-border-color:#2772a4;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#3498db;--bs-btn-disabled-border-color:#3498db}.btn-warning{--bs-btn-color:#fff;--bs-btn-bg:#f39c12;--bs-btn-border-color:#f39c12;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#cf850f;--bs-btn-hover-border-color:#c27d0e;--bs-btn-focus-shadow-rgb:245,171,54;--bs-btn-active-color:#fff;--bs-btn-active-bg:#c27d0e;--bs-btn-active-border-color:#b6750e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#f39c12;--bs-btn-disabled-border-color:#f39c12}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#e74c3c;--bs-btn-border-color:#e74c3c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#c44133;--bs-btn-hover-border-color:#b93d30;--bs-btn-focus-shadow-rgb:235,103,89;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b93d30;--bs-btn-active-border-color:#ad392d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#e74c3c;--bs-btn-disabled-border-color:#e74c3c}.btn-light{--bs-btn-color:#fff;--bs-btn-bg:#adb5bd;--bs-btn-border-color:#adb5bd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#939aa1;--bs-btn-hover-border-color:#8a9197;--bs-btn-focus-shadow-rgb:185,192,199;--bs-btn-active-color:#fff;--bs-btn-active-bg:#8a9197;--bs-btn-active-border-color:#82888e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#adb5bd;--bs-btn-disabled-border-color:#adb5bd}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#303030;--bs-btn-border-color:#303030;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#4f4f4f;--bs-btn-hover-border-color:#454545;--bs-btn-focus-shadow-rgb:79,79,79;--bs-btn-active-color:#fff;--bs-btn-active-bg:#595959;--bs-btn-active-border-color:#454545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#303030;--bs-btn-disabled-border-color:#303030}.btn-outline-primary{--bs-btn-color:#375a7f;--bs-btn-border-color:#375a7f;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#375a7f;--bs-btn-hover-border-color:#375a7f;--bs-btn-focus-shadow-rgb:55,90,127;--bs-btn-active-color:#fff;--bs-btn-active-bg:#375a7f;--bs-btn-active-border-color:#375a7f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#375a7f;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#375a7f;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#444;--bs-btn-border-color:#444;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#444;--bs-btn-hover-border-color:#444;--bs-btn-focus-shadow-rgb:68,68,68;--bs-btn-active-color:#fff;--bs-btn-active-bg:#444;--bs-btn-active-border-color:#444;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#444;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#444;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#00bc8c;--bs-btn-border-color:#00bc8c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#00bc8c;--bs-btn-hover-border-color:#00bc8c;--bs-btn-focus-shadow-rgb:0,188,140;--bs-btn-active-color:#fff;--bs-btn-active-bg:#00bc8c;--bs-btn-active-border-color:#00bc8c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#00bc8c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#00bc8c;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#3498db;--bs-btn-border-color:#3498db;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#3498db;--bs-btn-hover-border-color:#3498db;--bs-btn-focus-shadow-rgb:52,152,219;--bs-btn-active-color:#fff;--bs-btn-active-bg:#3498db;--bs-btn-active-border-color:#3498db;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#3498db;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#3498db;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#f39c12;--bs-btn-border-color:#f39c12;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#f39c12;--bs-btn-hover-border-color:#f39c12;--bs-btn-focus-shadow-rgb:243,156,18;--bs-btn-active-color:#fff;--bs-btn-active-bg:#f39c12;--bs-btn-active-border-color:#f39c12;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f39c12;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f39c12;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#e74c3c;--bs-btn-border-color:#e74c3c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#e74c3c;--bs-btn-hover-border-color:#e74c3c;--bs-btn-focus-shadow-rgb:231,76,60;--bs-btn-active-color:#fff;--bs-btn-active-bg:#e74c3c;--bs-btn-active-border-color:#e74c3c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#e74c3c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#e74c3c;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#adb5bd;--bs-btn-border-color:#adb5bd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#adb5bd;--bs-btn-hover-border-color:#adb5bd;--bs-btn-focus-shadow-rgb:173,181,189;--bs-btn-active-color:#fff;--bs-btn-active-bg:#adb5bd;--bs-btn-active-border-color:#adb5bd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#adb5bd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#adb5bd;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#303030;--bs-btn-border-color:#303030;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#303030;--bs-btn-hover-border-color:#303030;--bs-btn-focus-shadow-rgb:48,48,48;--bs-btn-active-color:#fff;--bs-btn-active-bg:#303030;--bs-btn-active-border-color:#303030;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#303030;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#303030;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#888;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:85,115,146;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:0.5rem}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:0.25rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:#fff;--bs-dropdown-bg:#222;--bs-dropdown-border-color:#444;--bs-dropdown-border-radius:0.375rem;--bs-dropdown-border-width:1px;--bs-dropdown-inner-border-radius:calc(0.375rem - 1px);--bs-dropdown-divider-bg:#444;--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-dropdown-link-color:#fff;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-link-hover-bg:#375a7f;--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#375a7f;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#888;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#303030;--bs-dropdown-border-color:#444;--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:#444;--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#375a7f;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:.375rem}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:2rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#adb5bd;display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#444;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#444 #444 transparent;--bs-nav-tabs-link-active-color:#fff;--bs-nav-tabs-link-active-bg:#222;--bs-nav-tabs-link-active-border-color:#444 #444 transparent;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:0.375rem;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#375a7f}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:1rem;--bs-navbar-color:rgba(34, 34, 34, 0.7);--bs-navbar-hover-color:#222;--bs-navbar-disabled-color:rgba(0, 0, 0, 0.3);--bs-navbar-active-color:#222;--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:#222;--bs-navbar-brand-hover-color:#222;--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2834, 34, 34, 0.7%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(34, 34, 34, 0.1);--bs-navbar-toggler-border-radius:0.375rem;--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .show>.nav-link{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark{--bs-navbar-color:rgba(255, 255, 255, 0.6);--bs-navbar-hover-color:#fff;--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.6%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-border-width:1px;--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:0.375rem;--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(0.375rem - 1px);--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:#444;--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:#303030;--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:#222;--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:1px;--bs-accordion-border-radius:0.375rem;--bs-accordion-inner-border-radius:calc(0.375rem - 1px);--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='var%28--bs-body-color%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23325172'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-focus-border-color:#9badbf;--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(55, 90, 127, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:#325172;--bs-accordion-active-bg:#ebeff2}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:var(--bs-accordion-btn-focus-border-color);outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button,.accordion-flush .accordion-item .accordion-button.collapsed{border-radius:0}.breadcrumb{--bs-breadcrumb-padding-x:0.75rem;--bs-breadcrumb-padding-y:0.375rem;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg:#444;--bs-breadcrumb-border-radius:0.25rem;--bs-breadcrumb-divider-color:#888;--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:#888;display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:#fff;--bs-pagination-bg:#00bc8c;--bs-pagination-border-width:0;--bs-pagination-border-color:transparent;--bs-pagination-border-radius:0.375rem;--bs-pagination-hover-color:#fff;--bs-pagination-hover-bg:#00efb2;--bs-pagination-hover-border-color:transparent;--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:#ebebeb;--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(55, 90, 127, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#00efb2;--bs-pagination-active-border-color:transparent;--bs-pagination-disabled-color:#fff;--bs-pagination-disabled-bg:#007053;--bs-pagination-disabled-border-color:transparent;display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:0.5rem}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:0.25rem}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:0.375rem;display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:1px solid var(--bs-alert-border-color);--bs-alert-border-radius:0.375rem;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:#21364c;--bs-alert-bg:#d7dee5;--bs-alert-border-color:#c3ced9}.alert-primary .alert-link{color:#1a2b3d}.alert-secondary{--bs-alert-color:#292929;--bs-alert-bg:#dadada;--bs-alert-border-color:#c7c7c7}.alert-secondary .alert-link{color:#212121}.alert-success{--bs-alert-color:#007154;--bs-alert-bg:#ccf2e8;--bs-alert-border-color:#b3ebdd}.alert-success .alert-link{color:#005a43}.alert-info{--bs-alert-color:#1f5b83;--bs-alert-bg:#d6eaf8;--bs-alert-border-color:#c2e0f4}.alert-info .alert-link{color:#194969}.alert-warning{--bs-alert-color:#925e0b;--bs-alert-bg:#fdebd0;--bs-alert-border-color:#fbe1b8}.alert-warning .alert-link{color:#754b09}.alert-danger{--bs-alert-color:#8b2e24;--bs-alert-bg:#fadbd8;--bs-alert-border-color:#f8c9c5}.alert-danger .alert-link{color:#6f251d}.alert-light{--bs-alert-color:#686d71;--bs-alert-bg:#eff0f2;--bs-alert-border-color:#e6e9eb}.alert-light .alert-link{color:#53575a}.alert-dark{--bs-alert-color:#1d1d1d;--bs-alert-bg:#d6d6d6;--bs-alert-border-color:#c1c1c1}.alert-dark .alert-link{color:#171717}@-webkit-keyframes progress-bar-stripes{0%{background-position-x:1rem}}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:#444;--bs-progress-border-radius:0.375rem;--bs-progress-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#375a7f;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.list-group{--bs-list-group-color:#fff;--bs-list-group-bg:#303030;--bs-list-group-border-color:#444;--bs-list-group-border-width:1px;--bs-list-group-border-radius:0.375rem;--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:#444;--bs-list-group-action-hover-color:#fff;--bs-list-group-action-hover-bg:#444;--bs-list-group-action-active-color:#fff;--bs-list-group-action-active-bg:#222;--bs-list-group-disabled-color:#888;--bs-list-group-disabled-bg:#303030;--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#375a7f;--bs-list-group-active-border-color:#375a7f;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#21364c;background-color:#d7dee5}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#21364c;background-color:#c2c8ce}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#21364c;border-color:#21364c}.list-group-item-secondary{color:#292929;background-color:#dadada}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#292929;background-color:#c4c4c4}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#292929;border-color:#292929}.list-group-item-success{color:#007154;background-color:#ccf2e8}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#007154;background-color:#b8dad1}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#007154;border-color:#007154}.list-group-item-info{color:#1f5b83;background-color:#d6eaf8}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#1f5b83;background-color:#c1d3df}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#1f5b83;border-color:#1f5b83}.list-group-item-warning{color:#925e0b;background-color:#fdebd0}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#925e0b;background-color:#e4d4bb}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#925e0b;border-color:#925e0b}.list-group-item-danger{color:#8b2e24;background-color:#fadbd8}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#8b2e24;background-color:#e1c5c2}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#8b2e24;border-color:#8b2e24}.list-group-item-light{color:#686d71;background-color:#eff0f2}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#686d71;background-color:#d7d8da}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#686d71;border-color:#686d71}.list-group-item-dark{color:#1d1d1d;background-color:#d6d6d6}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1d1d1d;background-color:#c1c1c1}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1d1d1d;border-color:#1d1d1d}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#fff;background:transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.375rem;opacity:.4}.btn-close:hover{color:#fff;text-decoration:none;opacity:1}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25);opacity:1}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:#444;--bs-toast-border-width:1px;--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:0.375rem;--bs-toast-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-toast-header-color:#888;--bs-toast-header-bg:#303030;--bs-toast-header-border-color:rgba(0, 0, 0, 0.05);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{position:absolute;z-index:var(--bs-toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:#303030;--bs-modal-border-color:#444;--bs-modal-border-width:1px;--bs-modal-border-radius:0.5rem;--bs-modal-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-modal-inner-border-radius:calc(0.5rem - 1px);--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:#444;--bs-modal-header-border-width:1px;--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:#444;--bs-modal-footer-border-width:1px;position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin:calc(-.5 * var(--bs-modal-header-padding-y)) calc(-.5 * var(--bs-modal-header-padding-x)) calc(-.5 * var(--bs-modal-header-padding-y)) auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:#fff;--bs-tooltip-bg:#000;--bs-tooltip-border-radius:0.375rem;--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;padding:var(--bs-tooltip-arrow-height);margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:#303030;--bs-popover-border-width:1px;--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:0.5rem;--bs-popover-inner-border-radius:calc(0.5rem - 1px);--bs-popover-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color: ;--bs-popover-header-bg:#444;--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:#fff;--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;-webkit-animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name);animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@-webkit-keyframes spinner-border{to{transform:rotate(360deg)}}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color: ;--bs-offcanvas-bg:#303030;--bs-offcanvas-border-width:1px;--bs-offcanvas-border-color:#444;--bs-offcanvas-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075)}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:575.98px){.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}}@media (max-width:575.98px){.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:767.98px){.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}}@media (max-width:767.98px){.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:991.98px){.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}}@media (max-width:991.98px){.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1199.98px){.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}}@media (max-width:1199.98px){.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}}@media (max-width:1399.98px){.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin-top:calc(-.5 * var(--bs-offcanvas-padding-y));margin-right:calc(-.5 * var(--bs-offcanvas-padding-x));margin-bottom:calc(-.5 * var(--bs-offcanvas-padding-y))}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{-webkit-animation:placeholder-glow 2s ease-in-out infinite;animation:placeholder-glow 2s ease-in-out infinite}@-webkit-keyframes placeholder-glow{50%{opacity:.2}}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;-webkit-animation:placeholder-wave 2s linear infinite;animation:placeholder-wave 2s linear infinite}@-webkit-keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(55,90,127,var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(68,68,68,var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(0,188,140,var(--bs-bg-opacity,1))!important}.text-bg-info{color:#fff!important;background-color:RGBA(52,152,219,var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#fff!important;background-color:RGBA(243,156,18,var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(231,76,60,var(--bs-bg-opacity,1))!important}.text-bg-light{color:#fff!important;background-color:RGBA(173,181,189,var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(48,48,48,var(--bs-bg-opacity,1))!important}.link-primary{color:#375a7f!important}.link-primary:focus,.link-primary:hover{color:#2c4866!important}.link-secondary{color:#444!important}.link-secondary:focus,.link-secondary:hover{color:#363636!important}.link-success{color:#00bc8c!important}.link-success:focus,.link-success:hover{color:#009670!important}.link-info{color:#3498db!important}.link-info:focus,.link-info:hover{color:#2a7aaf!important}.link-warning{color:#f39c12!important}.link-warning:focus,.link-warning:hover{color:#c27d0e!important}.link-danger{color:#e74c3c!important}.link-danger:focus,.link-danger:hover{color:#b93d30!important}.link-light{color:#adb5bd!important}.link-light:focus,.link-light:hover{color:#8a9197!important}.link-dark{color:#303030!important}.link-dark:focus,.link-dark:hover{color:#262626!important}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-1{--bs-border-width:1px}.border-2{--bs-border-width:2px}.border-3{--bs-border-width:3px}.border-4{--bs-border-width:4px}.border-5{--bs-border-width:5px}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.425rem + 2.1vw)!important}.fs-2{font-size:calc(1.375rem + 1.5vw)!important}.fs-3{font-size:calc(1.325rem + .9vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-light{font-weight:300!important}.fw-lighter{font-weight:lighter!important}.fw-normal{font-weight:400!important}.fw-bold{font-weight:700!important}.fw-semibold{font-weight:600!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:#888!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-2xl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:3rem!important}.fs-2{font-size:2.5rem!important}.fs-3{font-size:2rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}}:root{color-scheme:dark}.blockquote-footer{color:#888}.input-group-addon{color:#fff}.form-floating>label{color:#444}.nav-pills .nav-item.open .nav-link,.nav-pills .nav-item.open .nav-link:focus,.nav-pills .nav-item.open .nav-link:hover,.nav-pills .nav-link,.nav-pills .nav-link.active,.nav-pills .nav-link.active:focus,.nav-pills .nav-link.active:hover,.nav-tabs .nav-item.open .nav-link,.nav-tabs .nav-item.open .nav-link:focus,.nav-tabs .nav-item.open .nav-link:hover,.nav-tabs .nav-link,.nav-tabs .nav-link.active,.nav-tabs .nav-link.active:focus,.nav-tabs .nav-link.active:hover{color:#fff}.breadcrumb a{color:#fff}.pagination a:hover{text-decoration:none}.alert{color:#fff;border:none}.alert .alert-link,.alert a{color:#fff;text-decoration:underline}.alert-primary{background-color:#375a7f}.alert-secondary{background-color:#444}.alert-success{background-color:#00bc8c}.alert-info{background-color:#3498db}.alert-warning{background-color:#f39c12}.alert-danger{background-color:#e74c3c}.alert-light{background-color:#adb5bd}.alert-dark{background-color:#303030} \ No newline at end of file + */@import url(https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap);:root{--bs-blue:#375a7f;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#e83e8c;--bs-red:#e74c3c;--bs-orange:#fd7e14;--bs-yellow:#f39c12;--bs-green:#00bc8c;--bs-teal:#20c997;--bs-cyan:#3498db;--bs-black:#000;--bs-white:#fff;--bs-gray:#888;--bs-gray-dark:#303030;--bs-gray-100:#f8f9fa;--bs-gray-200:#ebebeb;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#888;--bs-gray-700:#444;--bs-gray-800:#303030;--bs-gray-900:#222;--bs-primary:#375a7f;--bs-secondary:#444;--bs-success:#00bc8c;--bs-info:#3498db;--bs-warning:#f39c12;--bs-danger:#e74c3c;--bs-light:#adb5bd;--bs-dark:#303030;--bs-primary-rgb:55,90,127;--bs-secondary-rgb:68,68,68;--bs-success-rgb:0,188,140;--bs-info-rgb:52,152,219;--bs-warning-rgb:243,156,18;--bs-danger-rgb:231,76,60;--bs-light-rgb:173,181,189;--bs-dark-rgb:48,48,48;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:255,255,255;--bs-body-bg-rgb:34,34,34;--bs-font-sans-serif:Lato,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#fff;--bs-body-bg:#222;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-link-color:#00bc8c;--bs-link-hover-color:#009670;--bs-code-color:#e83e8c;--bs-highlight-bg:#fdebd0}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:1px solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:calc(1.425rem + 2.1vw)}@media (min-width:1200px){.h1,h1{font-size:3rem}}.h2,h2{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h2,h2{font-size:2.5rem}}.h3,h3{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h3,h3{font-size:2rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--bs-link-color);text-decoration:underline}a:hover{color:var(--bs-link-hover-color)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em;color:inherit}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#888;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#888}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#222;border:1px solid var(--bs-border-color);border-radius:.375rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#888}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color:var(--bs-body-color);--bs-table-bg:transparent;--bs-table-border-color:#444;--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-body-color);--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:var(--bs-body-color);--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:var(--bs-body-color);--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:var(--bs-table-color);vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:2px solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-striped-columns>:not(caption)>tr>:nth-child(even){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-color:#fff;--bs-table-bg:#375a7f;--bs-table-border-color:#4b6b8c;--bs-table-striped-bg:#416285;--bs-table-striped-color:#fff;--bs-table-active-bg:#4b6b8c;--bs-table-active-color:#fff;--bs-table-hover-bg:#466689;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#fff;--bs-table-bg:#444444;--bs-table-border-color:#575757;--bs-table-striped-bg:#4d4d4d;--bs-table-striped-color:#fff;--bs-table-active-bg:#575757;--bs-table-active-color:#fff;--bs-table-hover-bg:#525252;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#fff;--bs-table-bg:#00bc8c;--bs-table-border-color:#1ac398;--bs-table-striped-bg:#0dbf92;--bs-table-striped-color:#fff;--bs-table-active-bg:#1ac398;--bs-table-active-color:#fff;--bs-table-hover-bg:#13c195;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#fff;--bs-table-bg:#3498db;--bs-table-border-color:#48a2df;--bs-table-striped-bg:#3e9ddd;--bs-table-striped-color:#fff;--bs-table-active-bg:#48a2df;--bs-table-active-color:#fff;--bs-table-hover-bg:#43a0de;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#fff;--bs-table-bg:#f39c12;--bs-table-border-color:#f4a62a;--bs-table-striped-bg:#f4a11e;--bs-table-striped-color:#fff;--bs-table-active-bg:#f4a62a;--bs-table-active-color:#fff;--bs-table-hover-bg:#f4a324;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#fff;--bs-table-bg:#e74c3c;--bs-table-border-color:#e95e50;--bs-table-striped-bg:#e85546;--bs-table-striped-color:#fff;--bs-table-active-bg:#e95e50;--bs-table-active-color:#fff;--bs-table-hover-bg:#e9594b;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#fff;--bs-table-bg:#adb5bd;--bs-table-border-color:#b5bcc4;--bs-table-striped-bg:#b1b9c0;--bs-table-striped-color:#fff;--bs-table-active-bg:#b5bcc4;--bs-table-active-color:#fff;--bs-table-hover-bg:#b3bbc2;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#303030;--bs-table-border-color:#454545;--bs-table-striped-bg:#3a3a3a;--bs-table-striped-color:#fff;--bs-table-active-bg:#454545;--bs-table-active-color:#fff;--bs-table-hover-bg:#404040;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:#888}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#303030;background-color:#fff;background-clip:padding-box;border:1px solid #222;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#303030;background-color:#fff;border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-moz-placeholder{color:#888;opacity:1}.form-control::placeholder{color:#888;opacity:1}.form-control:disabled{background-color:#ebebeb;opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#fff;background-color:#444;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#fff;background-color:#444;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#414141}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#414141}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#fff;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{width:3rem;height:calc(1.5em + .75rem + 2px);padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:.375rem}.form-control-color::-webkit-color-swatch{border-radius:.375rem}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + 2px)}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + 2px)}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:#303030;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #222;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#ebebeb}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #303030}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:.25rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:.5rem}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#9badbf;outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25)}.form-check-input:checked{background-color:#375a7f;border-color:#375a7f}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#375a7f;border-color:#375a7f;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%239badbf'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #222,0 0 0 .25rem rgba(55,90,127,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #222,0 0 0 .25rem rgba(55,90,127,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#375a7f;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#c3ced9}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#375a7f;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#c3ced9}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;width:100%;height:100%;padding:1rem .75rem;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::-moz-placeholder,.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown),.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:1px 0}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#adb5bd;text-align:center;white-space:nowrap;background-color:#444;border:1px solid #222;border-radius:.375rem}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#00bc8c}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(0,188,140,.9);border-radius:.375rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#00bc8c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#00bc8c}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2300bc8c' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#00bc8c;box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#00bc8c}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#00bc8c}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(0,188,140,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#00bc8c}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#e74c3c}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(231,76,60,.9);border-radius:.375rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#e74c3c;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#e74c3c}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23303030' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23e74c3c'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23e74c3c' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#e74c3c;box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#e74c3c}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#e74c3c}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(231,76,60,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#e74c3c}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#fff;--bs-btn-bg:transparent;--bs-btn-border-width:1px;--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#375a7f;--bs-btn-border-color:#375a7f;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#2f4d6c;--bs-btn-hover-border-color:#2c4866;--bs-btn-focus-shadow-rgb:85,115,146;--bs-btn-active-color:#fff;--bs-btn-active-bg:#2c4866;--bs-btn-active-border-color:#29445f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#375a7f;--bs-btn-disabled-border-color:#375a7f}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#444;--bs-btn-border-color:#444;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#3a3a3a;--bs-btn-hover-border-color:#363636;--bs-btn-focus-shadow-rgb:96,96,96;--bs-btn-active-color:#fff;--bs-btn-active-bg:#363636;--bs-btn-active-border-color:#333333;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#444;--bs-btn-disabled-border-color:#444}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#00bc8c;--bs-btn-border-color:#00bc8c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#00a077;--bs-btn-hover-border-color:#009670;--bs-btn-focus-shadow-rgb:38,198,157;--bs-btn-active-color:#fff;--bs-btn-active-bg:#009670;--bs-btn-active-border-color:#008d69;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#00bc8c;--bs-btn-disabled-border-color:#00bc8c}.btn-info{--bs-btn-color:#fff;--bs-btn-bg:#3498db;--bs-btn-border-color:#3498db;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#2c81ba;--bs-btn-hover-border-color:#2a7aaf;--bs-btn-focus-shadow-rgb:82,167,224;--bs-btn-active-color:#fff;--bs-btn-active-bg:#2a7aaf;--bs-btn-active-border-color:#2772a4;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#3498db;--bs-btn-disabled-border-color:#3498db}.btn-warning{--bs-btn-color:#fff;--bs-btn-bg:#f39c12;--bs-btn-border-color:#f39c12;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#cf850f;--bs-btn-hover-border-color:#c27d0e;--bs-btn-focus-shadow-rgb:245,171,54;--bs-btn-active-color:#fff;--bs-btn-active-bg:#c27d0e;--bs-btn-active-border-color:#b6750e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#f39c12;--bs-btn-disabled-border-color:#f39c12}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#e74c3c;--bs-btn-border-color:#e74c3c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#c44133;--bs-btn-hover-border-color:#b93d30;--bs-btn-focus-shadow-rgb:235,103,89;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b93d30;--bs-btn-active-border-color:#ad392d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#e74c3c;--bs-btn-disabled-border-color:#e74c3c}.btn-light{--bs-btn-color:#fff;--bs-btn-bg:#adb5bd;--bs-btn-border-color:#adb5bd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#939aa1;--bs-btn-hover-border-color:#8a9197;--bs-btn-focus-shadow-rgb:185,192,199;--bs-btn-active-color:#fff;--bs-btn-active-bg:#8a9197;--bs-btn-active-border-color:#82888e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#adb5bd;--bs-btn-disabled-border-color:#adb5bd}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#303030;--bs-btn-border-color:#303030;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#4f4f4f;--bs-btn-hover-border-color:#454545;--bs-btn-focus-shadow-rgb:79,79,79;--bs-btn-active-color:#fff;--bs-btn-active-bg:#595959;--bs-btn-active-border-color:#454545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#303030;--bs-btn-disabled-border-color:#303030}.btn-outline-primary{--bs-btn-color:#375a7f;--bs-btn-border-color:#375a7f;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#375a7f;--bs-btn-hover-border-color:#375a7f;--bs-btn-focus-shadow-rgb:55,90,127;--bs-btn-active-color:#fff;--bs-btn-active-bg:#375a7f;--bs-btn-active-border-color:#375a7f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#375a7f;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#375a7f;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#444;--bs-btn-border-color:#444;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#444;--bs-btn-hover-border-color:#444;--bs-btn-focus-shadow-rgb:68,68,68;--bs-btn-active-color:#fff;--bs-btn-active-bg:#444;--bs-btn-active-border-color:#444;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#444;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#444;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#00bc8c;--bs-btn-border-color:#00bc8c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#00bc8c;--bs-btn-hover-border-color:#00bc8c;--bs-btn-focus-shadow-rgb:0,188,140;--bs-btn-active-color:#fff;--bs-btn-active-bg:#00bc8c;--bs-btn-active-border-color:#00bc8c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#00bc8c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#00bc8c;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#3498db;--bs-btn-border-color:#3498db;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#3498db;--bs-btn-hover-border-color:#3498db;--bs-btn-focus-shadow-rgb:52,152,219;--bs-btn-active-color:#fff;--bs-btn-active-bg:#3498db;--bs-btn-active-border-color:#3498db;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#3498db;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#3498db;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#f39c12;--bs-btn-border-color:#f39c12;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#f39c12;--bs-btn-hover-border-color:#f39c12;--bs-btn-focus-shadow-rgb:243,156,18;--bs-btn-active-color:#fff;--bs-btn-active-bg:#f39c12;--bs-btn-active-border-color:#f39c12;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f39c12;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f39c12;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#e74c3c;--bs-btn-border-color:#e74c3c;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#e74c3c;--bs-btn-hover-border-color:#e74c3c;--bs-btn-focus-shadow-rgb:231,76,60;--bs-btn-active-color:#fff;--bs-btn-active-bg:#e74c3c;--bs-btn-active-border-color:#e74c3c;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#e74c3c;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#e74c3c;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#adb5bd;--bs-btn-border-color:#adb5bd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#adb5bd;--bs-btn-hover-border-color:#adb5bd;--bs-btn-focus-shadow-rgb:173,181,189;--bs-btn-active-color:#fff;--bs-btn-active-bg:#adb5bd;--bs-btn-active-border-color:#adb5bd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#adb5bd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#adb5bd;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#303030;--bs-btn-border-color:#303030;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#303030;--bs-btn-hover-border-color:#303030;--bs-btn-focus-shadow-rgb:48,48,48;--bs-btn-active-color:#fff;--bs-btn-active-bg:#303030;--bs-btn-active-border-color:#303030;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#303030;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#303030;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#888;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:85,115,146;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:0.5rem}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:0.25rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:#fff;--bs-dropdown-bg:#222;--bs-dropdown-border-color:#444;--bs-dropdown-border-radius:0.375rem;--bs-dropdown-border-width:1px;--bs-dropdown-inner-border-radius:calc(0.375rem - 1px);--bs-dropdown-divider-bg:#444;--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-dropdown-link-color:#fff;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-link-hover-bg:#375a7f;--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#375a7f;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#888;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#303030;--bs-dropdown-border-color:#444;--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:#444;--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#375a7f;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:.375rem}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:2rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:#adb5bd;display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:1px;--bs-nav-tabs-border-color:#444;--bs-nav-tabs-border-radius:0.375rem;--bs-nav-tabs-link-hover-border-color:#444 #444 transparent;--bs-nav-tabs-link-active-color:#fff;--bs-nav-tabs-link-active-bg:#222;--bs-nav-tabs-link-active-border-color:#444 #444 transparent;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:0.375rem;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#375a7f}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:1rem;--bs-navbar-color:rgba(34, 34, 34, 0.7);--bs-navbar-hover-color:#222;--bs-navbar-disabled-color:rgba(0, 0, 0, 0.3);--bs-navbar-active-color:#222;--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:#222;--bs-navbar-brand-hover-color:#222;--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2834, 34, 34, 0.7%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(34, 34, 34, 0.1);--bs-navbar-toggler-border-radius:0.375rem;--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .show>.nav-link{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark{--bs-navbar-color:rgba(255, 255, 255, 0.6);--bs-navbar-hover-color:#fff;--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.6%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-border-width:1px;--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:0.375rem;--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(0.375rem - 1px);--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:#444;--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:#303030;--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:#fff;--bs-accordion-bg:#222;--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:1px;--bs-accordion-border-radius:0.375rem;--bs-accordion-inner-border-radius:calc(0.375rem - 1px);--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:#fff;--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23325172'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-focus-border-color:#9badbf;--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(55, 90, 127, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:#325172;--bs-accordion-active-bg:#ebeff2}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:var(--bs-accordion-btn-focus-border-color);outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button,.accordion-flush .accordion-item .accordion-button.collapsed{border-radius:0}.breadcrumb{--bs-breadcrumb-padding-x:0.75rem;--bs-breadcrumb-padding-y:0.375rem;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg:#444;--bs-breadcrumb-border-radius:0.25rem;--bs-breadcrumb-divider-color:#888;--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:#888;display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:#fff;--bs-pagination-bg:#00bc8c;--bs-pagination-border-width:0;--bs-pagination-border-color:transparent;--bs-pagination-border-radius:0.375rem;--bs-pagination-hover-color:#fff;--bs-pagination-hover-bg:#00efb2;--bs-pagination-hover-border-color:transparent;--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:#ebebeb;--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(55, 90, 127, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#00efb2;--bs-pagination-active-border-color:transparent;--bs-pagination-disabled-color:#fff;--bs-pagination-disabled-bg:#007053;--bs-pagination-disabled-border-color:transparent;display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:0}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:0.5rem}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:0.25rem}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:0.375rem;display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:1px solid var(--bs-alert-border-color);--bs-alert-border-radius:0.375rem;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:#21364c;--bs-alert-bg:#d7dee5;--bs-alert-border-color:#c3ced9}.alert-primary .alert-link{color:#1a2b3d}.alert-secondary{--bs-alert-color:#292929;--bs-alert-bg:#dadada;--bs-alert-border-color:#c7c7c7}.alert-secondary .alert-link{color:#212121}.alert-success{--bs-alert-color:#007154;--bs-alert-bg:#ccf2e8;--bs-alert-border-color:#b3ebdd}.alert-success .alert-link{color:#005a43}.alert-info{--bs-alert-color:#1f5b83;--bs-alert-bg:#d6eaf8;--bs-alert-border-color:#c2e0f4}.alert-info .alert-link{color:#194969}.alert-warning{--bs-alert-color:#925e0b;--bs-alert-bg:#fdebd0;--bs-alert-border-color:#fbe1b8}.alert-warning .alert-link{color:#754b09}.alert-danger{--bs-alert-color:#8b2e24;--bs-alert-bg:#fadbd8;--bs-alert-border-color:#f8c9c5}.alert-danger .alert-link{color:#6f251d}.alert-light{--bs-alert-color:#686d71;--bs-alert-bg:#eff0f2;--bs-alert-border-color:#e6e9eb}.alert-light .alert-link{color:#53575a}.alert-dark{--bs-alert-color:#1d1d1d;--bs-alert-bg:#d6d6d6;--bs-alert-border-color:#c1c1c1}.alert-dark .alert-link{color:#171717}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:#444;--bs-progress-border-radius:0.375rem;--bs-progress-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#375a7f;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color:#fff;--bs-list-group-bg:#303030;--bs-list-group-border-color:#444;--bs-list-group-border-width:1px;--bs-list-group-border-radius:0.375rem;--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:#444;--bs-list-group-action-hover-color:#fff;--bs-list-group-action-hover-bg:#444;--bs-list-group-action-active-color:#fff;--bs-list-group-action-active-bg:#222;--bs-list-group-disabled-color:#888;--bs-list-group-disabled-bg:#303030;--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#375a7f;--bs-list-group-active-border-color:#375a7f;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#21364c;background-color:#d7dee5}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#21364c;background-color:#c2c8ce}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#21364c;border-color:#21364c}.list-group-item-secondary{color:#292929;background-color:#dadada}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#292929;background-color:#c4c4c4}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#292929;border-color:#292929}.list-group-item-success{color:#007154;background-color:#ccf2e8}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#007154;background-color:#b8dad1}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#007154;border-color:#007154}.list-group-item-info{color:#1f5b83;background-color:#d6eaf8}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#1f5b83;background-color:#c1d3df}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#1f5b83;border-color:#1f5b83}.list-group-item-warning{color:#925e0b;background-color:#fdebd0}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#925e0b;background-color:#e4d4bb}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#925e0b;border-color:#925e0b}.list-group-item-danger{color:#8b2e24;background-color:#fadbd8}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#8b2e24;background-color:#e1c5c2}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#8b2e24;border-color:#8b2e24}.list-group-item-light{color:#686d71;background-color:#eff0f2}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#686d71;background-color:#d7d8da}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#686d71;border-color:#686d71}.list-group-item-dark{color:#1d1d1d;background-color:#d6d6d6}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1d1d1d;background-color:#c1c1c1}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1d1d1d;border-color:#1d1d1d}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#fff;background:transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.375rem;opacity:.4}.btn-close:hover{color:#fff;text-decoration:none;opacity:1}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(55,90,127,.25);opacity:1}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:#444;--bs-toast-border-width:1px;--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:0.375rem;--bs-toast-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-toast-header-color:#888;--bs-toast-header-bg:#303030;--bs-toast-header-border-color:rgba(0, 0, 0, 0.05);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex:1090;position:absolute;z-index:var(--bs-toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:#303030;--bs-modal-border-color:#444;--bs-modal-border-width:1px;--bs-modal-border-radius:0.5rem;--bs-modal-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-modal-inner-border-radius:calc(0.5rem - 1px);--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:#444;--bs-modal-header-border-width:1px;--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:#444;--bs-modal-footer-border-width:1px;position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin:calc(-.5 * var(--bs-modal-header-padding-y)) calc(-.5 * var(--bs-modal-header-padding-x)) calc(-.5 * var(--bs-modal-header-padding-y)) auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:#fff;--bs-tooltip-bg:#000;--bs-tooltip-border-radius:0.375rem;--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;padding:var(--bs-tooltip-arrow-height);margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:#303030;--bs-popover-border-width:1px;--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:0.5rem;--bs-popover-inner-border-radius:calc(0.5rem - 1px);--bs-popover-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color: ;--bs-popover-header-bg:#444;--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:#fff;--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color: ;--bs-offcanvas-bg:#303030;--bs-offcanvas-border-width:1px;--bs-offcanvas-border-color:#444;--bs-offcanvas-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075)}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:575.98px){.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}}@media (max-width:575.98px){.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:767.98px){.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}}@media (max-width:767.98px){.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:991.98px){.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}}@media (max-width:991.98px){.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1199.98px){.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}}@media (max-width:1199.98px){.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}}@media (max-width:1399.98px){.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin-top:calc(-.5 * var(--bs-offcanvas-padding-y));margin-right:calc(-.5 * var(--bs-offcanvas-padding-x));margin-bottom:calc(-.5 * var(--bs-offcanvas-padding-y))}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(55,90,127,var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(68,68,68,var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(0,188,140,var(--bs-bg-opacity,1))!important}.text-bg-info{color:#fff!important;background-color:RGBA(52,152,219,var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#fff!important;background-color:RGBA(243,156,18,var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(231,76,60,var(--bs-bg-opacity,1))!important}.text-bg-light{color:#fff!important;background-color:RGBA(173,181,189,var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(48,48,48,var(--bs-bg-opacity,1))!important}.link-primary{color:#375a7f!important}.link-primary:focus,.link-primary:hover{color:#2c4866!important}.link-secondary{color:#444!important}.link-secondary:focus,.link-secondary:hover{color:#363636!important}.link-success{color:#00bc8c!important}.link-success:focus,.link-success:hover{color:#009670!important}.link-info{color:#3498db!important}.link-info:focus,.link-info:hover{color:#2a7aaf!important}.link-warning{color:#f39c12!important}.link-warning:focus,.link-warning:hover{color:#c27d0e!important}.link-danger{color:#e74c3c!important}.link-danger:focus,.link-danger:hover{color:#b93d30!important}.link-light{color:#adb5bd!important}.link-light:focus,.link-light:hover{color:#8a9197!important}.link-dark{color:#303030!important}.link-dark:focus,.link-dark:hover{color:#262626!important}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-1{--bs-border-width:1px}.border-2{--bs-border-width:2px}.border-3{--bs-border-width:3px}.border-4{--bs-border-width:4px}.border-5{--bs-border-width:5px}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.425rem + 2.1vw)!important}.fs-2{font-size:calc(1.375rem + 1.5vw)!important}.fs-3{font-size:calc(1.325rem + .9vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-light{font-weight:300!important}.fw-lighter{font-weight:lighter!important}.fw-normal{font-weight:400!important}.fw-bold{font-weight:700!important}.fw-semibold{font-weight:600!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:#888!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-2xl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:3rem!important}.fs-2{font-size:2.5rem!important}.fs-3{font-size:2rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}}:root{color-scheme:dark}.blockquote-footer{color:#888}.input-group-addon{color:#fff}.form-floating>label{color:#444}.nav-pills .nav-item.open .nav-link,.nav-pills .nav-item.open .nav-link:focus,.nav-pills .nav-item.open .nav-link:hover,.nav-pills .nav-link,.nav-pills .nav-link.active,.nav-pills .nav-link.active:focus,.nav-pills .nav-link.active:hover,.nav-tabs .nav-item.open .nav-link,.nav-tabs .nav-item.open .nav-link:focus,.nav-tabs .nav-item.open .nav-link:hover,.nav-tabs .nav-link,.nav-tabs .nav-link.active,.nav-tabs .nav-link.active:focus,.nav-tabs .nav-link.active:hover{color:#fff}.breadcrumb a{color:#fff}.pagination a:hover{text-decoration:none}.alert{color:#fff;border:none}.alert .alert-link,.alert a{color:#fff;text-decoration:underline}.alert-primary{background-color:#375a7f}.alert-secondary{background-color:#444}.alert-success{background-color:#00bc8c}.alert-info{background-color:#3498db}.alert-warning{background-color:#f39c12}.alert-danger{background-color:#e74c3c}.alert-light{background-color:#adb5bd}.alert-dark{background-color:#303030} \ No newline at end of file From 8be1fa5025c6423715773bba533e88398c065b3f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 16 Oct 2022 13:08:04 +0200 Subject: [PATCH 574/629] version 0.9.8 --- build.gradle.kts | 2 +- modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3dac5e1..3c0084b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.9.7" +version = "0.9.8" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 88a1d7b..804af4a 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.7", + "version": "0.9.8", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 57a2bad..34649e2 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.7", + "version": "0.9.8", "private": true, "scripts": { "build": "tstl", From 7f4316065c9e45b16b3e3938f55b3d02fd2a454b Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 16 Oct 2022 13:52:26 +0200 Subject: [PATCH 575/629] rm default KAFKATORIO_VERSION in events-processors dockerfile --- modules/events-processors/docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/events-processors/docker/Dockerfile b/modules/events-processors/docker/Dockerfile index ab48826..b70ab64 100644 --- a/modules/events-processors/docker/Dockerfile +++ b/modules/events-processors/docker/Dockerfile @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1 FROM eclipse-temurin:11-jdk-jammy -ARG KAFKATORIO_VERSION=0.5.1 +ARG KAFKATORIO_VERSION ARG DIST_DIR="../build/distributions/" ARG APP_NAME="events-processors" From 33255f2d1bed32ef10a8998a6e6800936fac8532 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 17 Oct 2022 00:10:21 +0200 Subject: [PATCH 576/629] [syslog-sever] rm unnecessary @PublishedApi from internal jsonMapper --- .../dev/adamko/kafkatorio/processor/syslog/config/kxsJson.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/config/kxsJson.kt b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/config/kxsJson.kt index 6b8797b..f638397 100644 --- a/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/config/kxsJson.kt +++ b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/config/kxsJson.kt @@ -4,7 +4,6 @@ import dev.adamko.kafkatorio.library.jsonMapperKafkatorio import kotlinx.serialization.json.Json -@PublishedApi internal val jsonMapper: Json = Json { prettyPrint = true prettyPrintIndent = " " From 895194d576fbfd55311c62f4434240f9ef0a7ee7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 17 Oct 2022 00:11:45 +0200 Subject: [PATCH 577/629] [mod] add code for writing packets to file (but disable it) --- .../typescript/main/emitting/PacketEmitter.ts | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/emitting/PacketEmitter.ts b/modules/events-mod/src/main/typescript/main/emitting/PacketEmitter.ts index c077e94..eb7b6b5 100644 --- a/modules/events-mod/src/main/typescript/main/emitting/PacketEmitter.ts +++ b/modules/events-mod/src/main/typescript/main/emitting/PacketEmitter.ts @@ -28,11 +28,25 @@ export class KafkatorioPacketEmitter { private static emitPacket(packet: T) { const data = game.table_to_json(packet) // print(`KafkatorioPacket::: ${data}`) - const encoded = game.encode_string(data) - print(`KafkatorioPacket encoded::: ${encoded}`) - // rcon.print(`KafkatorioPacket: ${data}`) + const encodedData = game.encode_string(data) + if (encodedData != null) { + print(`KafkatorioPacket encoded::: ${encodedData}`) + // rcon.print(`KafkatorioPacket: ${data}`) + // this.appendToFile(encodedData) + } } + // private static appendToFile(encodedData: string) { + // // change log files every hour: + // const perHour = game.tick / (60 * 60 * 60) + // game.write_file( + // `kafkatorio/packets_${perHour}.txt`, + // `${encodedData}\n`, + // true, + // 0, // server only + // ) + // } + } From 1cc5afa6e22a12b219aad5625dcf815a2021961c Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 17 Oct 2022 00:12:03 +0200 Subject: [PATCH 578/629] set default socket-server host to 0.0.0.0 --- modules/events-processor-core/src/main/resources/config.yml | 2 +- modules/events-server-syslog/docker/Dockerfile | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/events-processor-core/src/main/resources/config.yml b/modules/events-processor-core/src/main/resources/config.yml index d882d45..ea1d773 100644 --- a/modules/events-processor-core/src/main/resources/config.yml +++ b/modules/events-processor-core/src/main/resources/config.yml @@ -4,7 +4,7 @@ web-port: ${WEB_SERVER_PORT:-8080} server-data-dir: ${SERVER_DATA_DIR:-./server-data} -socket-server-host: ${SOCKET_SERVER_HOST:-127.0.0.1} +socket-server-host: ${SOCKET_SERVER_HOST:-0.0.0.0} socket-server-port: ${SOCKET_SERVER_PORT:-12092} diff --git a/modules/events-server-syslog/docker/Dockerfile b/modules/events-server-syslog/docker/Dockerfile index a425858..7582ce8 100644 --- a/modules/events-server-syslog/docker/Dockerfile +++ b/modules/events-server-syslog/docker/Dockerfile @@ -7,7 +7,8 @@ ARG APP_NAME="events-server-syslog" WORKDIR /app -ENV SOCKET_SERVER_PORT=9002 +ENV SOCKET_SERVER_PORT=0.0.0.0 +ENV SOCKET_SERVER_HOST=9002 EXPOSE $SOCKET_SERVER_PORT ENV SERVER_DATA_DIR="/app/data" From 0216d068c5a17a8efa70fbd701a5dc7f455d4563 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 17 Oct 2022 00:14:27 +0200 Subject: [PATCH 579/629] [syslog-server] ignore, but log, non-syslog messages. Minor logging tweaks. --- .../syslog/KafkatorioPacketKafkaProducer.kt | 6 ++++-- .../processor/syslog/SyslogSocketServer.kt | 18 +++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/KafkatorioPacketKafkaProducer.kt b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/KafkatorioPacketKafkaProducer.kt index d60a436..f69eb9d 100644 --- a/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/KafkatorioPacketKafkaProducer.kt +++ b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/KafkatorioPacketKafkaProducer.kt @@ -2,11 +2,11 @@ package dev.adamko.kafkatorio.processor.syslog import com.github.palindromicity.syslog.dsl.SyslogFieldKeys import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.processor.config.TOPIC_SRC_SERVER_LOG +import dev.adamko.kafkatorio.processor.config.TOPIC_SRC_SERVER_LOG_DLQ import dev.adamko.kafkatorio.processor.core.Authenticator import dev.adamko.kafkatorio.processor.syslog.config.jsonMapper import dev.adamko.kafkatorio.schema.common.FactorioServerId -import dev.adamko.kafkatorio.processor.config.TOPIC_SRC_SERVER_LOG -import dev.adamko.kafkatorio.processor.config.TOPIC_SRC_SERVER_LOG_DLQ import dev.adamko.kotka.kxs.kafkaSerializer import java.util.Properties import kotlin.coroutines.coroutineContext @@ -56,6 +56,8 @@ class KafkatorioPacketKafkaProducer( suspend fun launch() { coroutineContext.job.invokeOnCompletion { + val cause = if (it != null) "(cause: ${it::class.java.name} ${it.message})" else "" + log("Closing $cause") this@KafkatorioPacketKafkaProducer.close() } diff --git a/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogSocketServer.kt b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogSocketServer.kt index cd9780f..49a9fdc 100644 --- a/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogSocketServer.kt +++ b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogSocketServer.kt @@ -7,6 +7,7 @@ import com.github.palindromicity.syslog.NilPolicy import com.github.palindromicity.syslog.SyslogParser import com.github.palindromicity.syslog.SyslogParserBuilder import com.github.palindromicity.syslog.SyslogSpecification +import com.github.palindromicity.syslog.dsl.ParseException import dev.adamko.kafkatorio.processor.config.ApplicationProperties import io.ktor.network.selector.SelectorManager import io.ktor.network.sockets.Socket @@ -83,16 +84,23 @@ class SyslogSocketServer( "received 'null' line from ${socket.description()}" } - val syslog = SyslogMsg(syslogParser.parseLine(line)) - _messages.emit(syslog) + try { + val syslog = SyslogMsg(syslogParser.parseLine(line)) + _messages.emit(syslog) + } catch (ex: ParseException) { + log("ignoring non-syslog message: $line") + } yield() } } catch (e: Throwable) { - if (e is CancellationException) throw e - log("closing socket ${socket.description()}, cause: ${e::class.java.name} ${e.message}") - e.printStackTrace() withContext(Dispatchers.IO) { socket.close() } + if (e is CancellationException) { + throw e + } else { + log("closing socket ${socket.description()}, cause: ${e::class.java.name} ${e.message}") + e.printStackTrace() + } } } From 6fa5c3f488ba2b8f6d299d39c5c1d6acc758c3cb Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 17 Oct 2022 00:17:14 +0200 Subject: [PATCH 580/629] [mod] re-build lua (I need to get rid of the lua code and keep at as generated... --- .../src/generated/lua/main/emitting/PacketEmitter.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua b/modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua index 0c3d2c8..bbc2fb6 100644 --- a/modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua +++ b/modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua @@ -15,8 +15,10 @@ function KafkatorioPacketEmitter.prototype.emitKeyedPacket(self, data) end function KafkatorioPacketEmitter.emitPacket(self, packet) local data = game.table_to_json(packet) - local encoded = game.encode_string(data) - print("KafkatorioPacket encoded::: " .. tostring(encoded)) + local encodedData = game.encode_string(data) + if encodedData ~= nil then + print("KafkatorioPacket encoded::: " .. encodedData) + end end local PacketEmitter = __TS__New(____exports.KafkatorioPacketEmitter) ____exports.default = PacketEmitter From 08f23eebd7b18434221863e88321c6048acd104b Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 17 Oct 2022 00:18:07 +0200 Subject: [PATCH 581/629] [syslog-server] fix server host/port mixup in dockerfile --- modules/events-server-syslog/docker/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/events-server-syslog/docker/Dockerfile b/modules/events-server-syslog/docker/Dockerfile index 7582ce8..0b76d0b 100644 --- a/modules/events-server-syslog/docker/Dockerfile +++ b/modules/events-server-syslog/docker/Dockerfile @@ -7,8 +7,8 @@ ARG APP_NAME="events-server-syslog" WORKDIR /app -ENV SOCKET_SERVER_PORT=0.0.0.0 -ENV SOCKET_SERVER_HOST=9002 +ENV SOCKET_SERVER_HOST=0.0.0.0 +ENV SOCKET_SERVER_PORT=9002 EXPOSE $SOCKET_SERVER_PORT ENV SERVER_DATA_DIR="/app/data" From b2b6da9c3cb244c95a56bad4f3a94938e2c15d88 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 17 Oct 2022 00:18:33 +0200 Subject: [PATCH 582/629] version 0.9.9 --- build.gradle.kts | 2 +- modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3c0084b..7f2db91 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.9.8" +version = "0.9.9" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 804af4a..f3178b1 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.8", + "version": "0.9.9", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 34649e2..3cde420 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.8", + "version": "0.9.9", "private": true, "scripts": { "build": "tstl", From 554da25c3fdbc9b4cc51e99bdb0581ffd6e2034b Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 17 Oct 2022 22:01:22 +0200 Subject: [PATCH 583/629] rm commented out code from root build.gradle.kts --- build.gradle.kts | 50 ------------------------------------------------ 1 file changed, 50 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7f2db91..da10fa1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -41,16 +41,6 @@ tasks.wrapper { distributionType = Wrapper.DistributionType.ALL } -val startInfra by tasks.registering { - group = rootProject.name - - dependsOn( -// ":modules:infra-kafka-pipe:processRun", -// runKafkaCluster -// ":modules:infra-kafka-connect:processRun", - ) -} - val runKafkatorio by tasks.registering { group = rootProject.name @@ -61,44 +51,4 @@ val runKafkatorio by tasks.registering { ) } -//val runEventsServer by tasks.registering { -// group = project.name -// -// dependsOn(":modules:events-server:run") -//} - -//val runWebMap by tasks.registering { -// group = project.name -// -// dependsOn(":modules:web-map:browserDevelopmentRun") -//} - -// -//val runKafkaCluster by tasks.registering { -// group = project.name -// -// dependsOn( -// ":modules:infra-kafka-cluster:processRun", -// ) -//} - - -//val runFactorioServer by tasks.registering { -// group = project.name -// -// dependsOn( -// ":modules:infra-factorio-server:processRun", -// ) -//} - - -//val runFactorioClient by tasks.registering { -// group = project.name -// -// dependsOn( -// ":modules:infra-factorio-client:processRun", -// ) -//} - - apply(from = "$projectDir/kt52647.gradle.kts") From 7cd6c4a47afd6d9a1d5320e513946623d888186f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 18 Oct 2022 19:46:21 +0200 Subject: [PATCH 584/629] revert kotlinx serialization to 1.4.0 https://github.com/Kotlin/kotlinx.serialization/issues/2065 --- gradle/libs.versions.toml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6dd27ee..e73add9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,7 +20,7 @@ scrimage = "4.0.32" # https://github.com/sksamuel/scrimage/r semver = "1.2.0" # https://github.com/swiftzer/semver/releases slf4j = "1.7.36" -kotlinx-serialization = "1.4.1" # https://github.com/Kotlin/kotlinx.serialization/releases +kotlinx-serialization = "1.4.0" # https://github.com/Kotlin/kotlinx.serialization/releases kxs-charleskornKaml = "0.44.0" kxs-mamoeYamlkt = "0.12.0" kxs-kxsTsGen = "0.2.1" @@ -117,8 +117,9 @@ kotlinxSerialization-mamoeYamlkt = { group = "net.mamoe.yamlkt", name = kotlinxSerialization-kxsTsGen = { group = "com.github.adamko-dev.kotlinx-serialization-typescript-generator", name = "kxs-ts-gen-core", version.ref = "kxs-kxsTsGen" } -kotlinx-coroutines-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-bom", version.ref = "kotlinx-coroutines" } -kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core" } +kotlinx-coroutines-bom = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-bom", version.ref = "kotlinx-coroutines" } +kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core" } +kotlinx-coroutines-jdk8 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8" } kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version.ref = "kotlinx-html" } kotlinx-nodejs = { group = "org.jetbrains.kotlinx", name = "kotlinx-nodejs", version.ref = "kotlinx-nodejs" } From 8342a923a80226eb2d305088ef2c5de20585ef44 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 18 Oct 2022 21:22:06 +0200 Subject: [PATCH 585/629] kt2ts2.kt - minor style refactor --- .../kotlin/dev/adamko/kafkatorio/schema/kt2ts2.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/schema/kt2ts2.kt b/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/schema/kt2ts2.kt index 19fb33d..903bc78 100644 --- a/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/schema/kt2ts2.kt +++ b/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/schema/kt2ts2.kt @@ -19,6 +19,7 @@ import org.intellij.lang.annotations.Language fun main(args: Array) { + val outputFilename = args.firstOrNull() val config = KxsTsConfig( typeAliasTyping = BrandTyping @@ -38,7 +39,7 @@ fun main(args: Array) { // ) gen2.descriptorOverrides += mapOf( -//@formatter:off + //@formatter:off Float .serializer().descriptor to TsTypeAlias(TsElementId("kotlin.Float" ), TsTypeRef.Literal(TsLiteral.Custom("float" ), false)), Double.serializer().descriptor to TsTypeAlias(TsElementId("kotlin.Double"), TsTypeRef.Literal(TsLiteral.Custom("double"), false)), Int .serializer().descriptor to TsTypeAlias(TsElementId("kotlin.Int" ), TsTypeRef.Literal(TsLiteral.Custom("int" ), false)), @@ -51,19 +52,18 @@ fun main(args: Array) { PlayerIndex.serializer().descriptor to TsTypeAlias(TsElementId("PlayerIndex" ), TsTypeRef.Literal(TsLiteral.Custom("PlayerIndex"), false)), SurfaceIndex.serializer().descriptor to TsTypeAlias(TsElementId("SurfaceIndex" ), TsTypeRef.Literal(TsLiteral.Custom("SurfaceIndex"), false)), UnitNumber.serializer().descriptor to TsTypeAlias(TsElementId("UnitNumber" ), TsTypeRef.Literal(TsLiteral.Custom("UnitNumber"), false)), -//@formatter:on + //@formatter:on ) val definitions = gen2.generate( KafkatorioPacket.serializer(), -// KafkatorioKeyedPacketKey2.serializer(), ) - when (val filename = args.firstOrNull()) { + when (outputFilename) { null -> println(definitions) else -> { - val outPath = Path(filename) + val outPath = Path(outputFilename) outPath.createDirectories() val outFile = outPath.resolve("kafkatorio-schema.ts").toFile() outFile.printWriter().use { From 557dc97635d15abf01577e5f798d198e334ddfb1 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 18 Oct 2022 21:25:18 +0200 Subject: [PATCH 586/629] [syslog-server] refactor logging and error handling (avoid runCatching) in producer --- .../syslog/KafkatorioPacketKafkaProducer.kt | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/KafkatorioPacketKafkaProducer.kt b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/KafkatorioPacketKafkaProducer.kt index f69eb9d..47a6446 100644 --- a/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/KafkatorioPacketKafkaProducer.kt +++ b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/KafkatorioPacketKafkaProducer.kt @@ -10,7 +10,6 @@ import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kotka.kxs.kafkaSerializer import java.util.Properties import kotlin.coroutines.coroutineContext -import kotlinx.coroutines.CancellationException import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.onEach @@ -57,44 +56,41 @@ class KafkatorioPacketKafkaProducer( suspend fun launch() { coroutineContext.job.invokeOnCompletion { val cause = if (it != null) "(cause: ${it::class.java.name} ${it.message})" else "" - log("Closing $cause") + log("Closing KafkatorioPacketKafkaProducer $cause") this@KafkatorioPacketKafkaProducer.close() } syslogServer.messages .filter { (it.message ?: "").run { - startsWith("KafkatorioPacket:::") || startsWith("KafkatorioPacket encoded:::") + startsWith("KafkatorioPacket:::") } }.onEach { syslog -> - runCatching { - getFactorioServerId(syslog) - }.fold( - onSuccess = { serverId -> produceMessage(serverId, syslog) }, - onFailure = { ex -> - produceDlqMessage(syslog, "${ex::class.java.name}: ${ex.message}") - - if (ex is CancellationException) throw ex - } - ) + val serverId = getFactorioServerId(syslog) + if (serverId != null) { + produceMessage(serverId, syslog) + } }.collect() } - private fun getFactorioServerId(syslog: SyslogMsg): FactorioServerId { + private fun getFactorioServerId(syslog: SyslogMsg): FactorioServerId? { val token = syslog.headerAppName if (token.isNullOrBlank()) { - error("no token in syslog message. msg: ${syslog.src}") + produceDlqMessage(syslog, "no token in syslog message. msg: ${syslog.src}") + return null } val serverToken = authenticator.verifyJwt(token) if (serverToken.isNullOrBlank()) { - error("could not decode token $token. msg: ${syslog.src}") + produceDlqMessage(syslog, "could not decode token $token. msg: ${syslog.src}") + return null } val serverId = appProps.kafkatorioServers[serverToken] if (serverId.isNullOrBlank()) { - error("no server ID for token $serverToken. msg: ${syslog.src}") + produceDlqMessage(syslog, "no server ID for token $serverToken. msg: ${syslog.src}") + return null } return serverId From ecf680d9ce9f9a74c3f2d4846d3e0ed7fc60a338 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 18 Oct 2022 21:26:30 +0200 Subject: [PATCH 587/629] [syslog-server] minor styling --- .../processor/syslog/SyslogSocketServer.kt | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogSocketServer.kt b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogSocketServer.kt index 49a9fdc..38253a4 100644 --- a/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogSocketServer.kt +++ b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/SyslogSocketServer.kt @@ -73,19 +73,18 @@ class SyslogSocketServer( private suspend fun handleConnection( socket: Socket - ) = supervisorScope { + ): Unit = supervisorScope { try { val channel = socket.openReadChannel() while (socket.socketContext.isActive && !channel.isClosedForRead) { val line = channel.readUTF8Line() - requireNotNull(line) { - "received 'null' line from ${socket.description()}" - } + requireNotNull(line) { "received 'null' line from ${socket.description()}" } try { - val syslog = SyslogMsg(syslogParser.parseLine(line)) + val messageContents = syslogParser.parseLine(line) + val syslog = SyslogMsg(messageContents) _messages.emit(syslog) } catch (ex: ParseException) { log("ignoring non-syslog message: $line") @@ -93,13 +92,13 @@ class SyslogSocketServer( yield() } - } catch (e: Throwable) { + } catch (ex: Throwable) { withContext(Dispatchers.IO) { socket.close() } - if (e is CancellationException) { - throw e + if (ex is CancellationException) { + throw ex } else { - log("closing socket ${socket.description()}, cause: ${e::class.java.name} ${e.message}") - e.printStackTrace() + log("closing socket ${socket.description()}, cause: ${ex::class.qualifiedName} ${ex.message}") + ex.printStackTrace() } } } From dda48bac78eb05e87dd011b59c967b677deb2497 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 18 Oct 2022 21:27:16 +0200 Subject: [PATCH 588/629] refactor the KafkatorioPacket tag that the mod logs, and the syslog-server parses --- .../lua/main/emitting/PacketEmitter.lua | 12 ++- .../typescript/main/emitting/PacketEmitter.ts | 16 +++- .../topology/factorioServerPackets.kt | 79 ++++++++++++++----- modules/infra-kafka-pipe/src/kafka-pipe.sh | 2 +- 4 files changed, 84 insertions(+), 25 deletions(-) diff --git a/modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua b/modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua index bbc2fb6..2ec7a8b 100644 --- a/modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua +++ b/modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua @@ -1,5 +1,6 @@ local ____lualib = require("lualib_bundle") local __TS__Class = ____lualib.__TS__Class +local __TS__StringTrim = ____lualib.__TS__StringTrim local __TS__New = ____lualib.__TS__New local ____exports = {} ____exports.KafkatorioPacketEmitter = __TS__Class() @@ -15,9 +16,16 @@ function KafkatorioPacketEmitter.prototype.emitKeyedPacket(self, data) end function KafkatorioPacketEmitter.emitPacket(self, packet) local data = game.table_to_json(packet) + if #__TS__StringTrim(data) <= 0 then + print("[error] table_to_json returned empty string for packet:" .. tostring(packet)) + return + end local encodedData = game.encode_string(data) - if encodedData ~= nil then - print("KafkatorioPacket encoded::: " .. encodedData) + if encodedData == nil or #__TS__StringTrim(encodedData) <= 0 then + print("[error] could not encode packet") + print("KafkatorioPacket:::" .. data) + else + print("KafkatorioPacket:::encoded:" .. encodedData) end end local PacketEmitter = __TS__New(____exports.KafkatorioPacketEmitter) diff --git a/modules/events-mod/src/main/typescript/main/emitting/PacketEmitter.ts b/modules/events-mod/src/main/typescript/main/emitting/PacketEmitter.ts index eb7b6b5..69e36a9 100644 --- a/modules/events-mod/src/main/typescript/main/emitting/PacketEmitter.ts +++ b/modules/events-mod/src/main/typescript/main/emitting/PacketEmitter.ts @@ -27,11 +27,19 @@ export class KafkatorioPacketEmitter { /** Emit a serialised KafkatorioPacket */ private static emitPacket(packet: T) { const data = game.table_to_json(packet) - // print(`KafkatorioPacket::: ${data}`) + + if (data.trim().length <= 0) { + print(`[error] table_to_json returned empty string for packet:${packet}`) + return + } + const encodedData = game.encode_string(data) - if (encodedData != null) { - print(`KafkatorioPacket encoded::: ${encodedData}`) - // rcon.print(`KafkatorioPacket: ${data}`) + + if (encodedData == null || encodedData.trim().length <= 0) { + print(`[error] could not encode packet`) + print(`KafkatorioPacket:::${data}`) + } else { + print(`KafkatorioPacket:::encoded:${encodedData}`) // this.appendToFile(encodedData) } } diff --git a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt index 42999ab..69872ae 100644 --- a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt @@ -1,12 +1,12 @@ package dev.adamko.kafkatorio.server.processor.topology +import dev.adamko.kafkatorio.processor.config.TOPIC_SRC_SERVER_LOG +import dev.adamko.kafkatorio.processor.config.jsonMapper +import dev.adamko.kafkatorio.processor.config.topicName import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketDataError -import dev.adamko.kafkatorio.processor.config.TOPIC_SRC_SERVER_LOG -import dev.adamko.kafkatorio.processor.config.jsonMapper -import dev.adamko.kafkatorio.processor.config.topicName import dev.adamko.kotka.extensions.component1 import dev.adamko.kotka.extensions.component2 import dev.adamko.kotka.extensions.consumedAs @@ -26,6 +26,10 @@ import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.kstream.KStream +private const val PACKET_TAG = "KafkatorioPacket:::" +private const val PACKET_ENCODED_TAG = "${PACKET_TAG}encoded:" + + fun factorioServerPacketStream( builder: StreamsBuilder = StreamsBuilder(), ): KStream { @@ -39,21 +43,7 @@ fun factorioServerPacketStream( ) ).mapValues("decode-packets") { _: FactorioServerId, value: String? -> - val packet = try { - val decoded = decodeFactorioEncodedString(value!!) - jsonMapper.decodeFromString(KafkatorioPacket.serializer(), decoded) - } catch (e: Exception) { - if (e is CancellationException) throw e - - KafkatorioPacket( - modVersion = "unknown", - tick = Tick(0u), - data = KafkatorioPacketDataError( - exception = e, - rawValue = value, - ) - ) - } + val packet = decodeKafkatorioPacket(value) if (packet.data is KafkatorioPacketDataError) { println("error parsing $TOPIC_SRC_SERVER_LOG message: $packet") @@ -81,6 +71,31 @@ fun splitFactorioServerPacketStream( } +private fun decodeKafkatorioPacket(value: String?): KafkatorioPacket = try { + when { + value.isNullOrBlank() -> + createErrorPacket(message = "null/blank message", rawValue = value) + + value.substringAfter(PACKET_TAG).isBlank() -> + createErrorPacket(message = "missing '$PACKET_TAG'", rawValue = value) + + else -> { + val packetJson = if (PACKET_ENCODED_TAG in value) { + val encodedValue = value.substringAfter(PACKET_ENCODED_TAG) + decodeFactorioEncodedString(encodedValue) + } else { + value.substringAfter(PACKET_TAG) + } + + jsonMapper.decodeFromString(KafkatorioPacket.serializer(), packetJson) + } + } +} catch (ex: Exception) { + if (ex is CancellationException) throw ex + errorPacket(exception = ex, rawValue = value) +} + + /** * Factorio `game.encode_string` zlib encodes a string, then base64's it. Here we do the reverse. */ @@ -94,3 +109,31 @@ private fun decodeFactorioEncodedString( .buffer() .readString(Charsets.UTF_8) } + + +private fun createErrorPacket( + message: String, + rawValue: String?, +): KafkatorioPacket = + KafkatorioPacket( + modVersion = "unknown", + tick = Tick(0u), + data = KafkatorioPacketDataError( + message = message, + rawValue = rawValue, + ) + ) + + +private fun errorPacket( + exception: Exception, + rawValue: String?, +): KafkatorioPacket { + val message = """ +${exception::class.qualifiedName} ${exception.message} + +${exception.stackTraceToString()} +""".trimIndent() + + return createErrorPacket(message, rawValue) +} diff --git a/modules/infra-kafka-pipe/src/kafka-pipe.sh b/modules/infra-kafka-pipe/src/kafka-pipe.sh index e0922be..3c16fe8 100644 --- a/modules/infra-kafka-pipe/src/kafka-pipe.sh +++ b/modules/infra-kafka-pipe/src/kafka-pipe.sh @@ -17,7 +17,7 @@ KEY="${INSTANCE_ID:-none}" while :; do docker logs --tail 0 -f "$FACTORIO_SERVER_CONTAINER_NAME" | - sed -n -e 's/^KafkatorioPacket encoded::: //p' | + sed -n -e 's/^KafkatorioPacket::://p' | kcat -P \ -b "$KAFKA_HOST" \ -t kafkatorio.src.server-log \ From 77d0dc27ca630f1d7bdeef328bd12ced2fdfeda0 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 18 Oct 2022 21:36:22 +0200 Subject: [PATCH 589/629] fix local mod deploy Gradle tasks --- modules/infra-factorio-client/build.gradle.kts | 2 +- modules/infra-factorio-server/build.gradle.kts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index 0f2f124..a53c310 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -45,7 +45,7 @@ val deployModToLocalClient by tasks.registering(Copy::class) { onlyIf { clientModsDirectory123.orNull?.asFile?.exists() == true } - from(factorioMod) + from(configurations.factorioMod.map { it.incoming.artifactView { lenient(true) }.files }) into(clientModsDirectory) doLast { diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index f3f5184..ab89991 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -34,12 +34,12 @@ val deployModToLocalServer by tasks.registering(Copy::class) { description = "Copy the mod to the Factorio Docker server" group = FactorioModPlugin.TASK_GROUP - dependsOn(factorioMod) + dependsOn(configurations.factorioMod) // from( // provider { factorioMod.incoming.artifacts.artifactFiles.files } // ) - from(configurations.factorioMod.map { it.incoming.artifacts.artifactFiles.files }) + from(configurations.factorioMod.map { it.incoming.artifactView { lenient(true) }.files }) into(factorioServerDataDir.dir("mods")) doLast { From e0574ea8eb70a9224a0f6e4b35352e93543f68d1 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 18 Oct 2022 21:42:45 +0200 Subject: [PATCH 590/629] version 0.9.10 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index da10fa1..433498d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.9.9" +version = "0.9.10" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) From f99208b5b22077c6b2a7db15da187ccef8c46312 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 18 Oct 2022 23:22:26 +0200 Subject: [PATCH 591/629] more fixing of Kafkatorio packets... --- .../topology/factorioServerPackets.kt | 19 ++++++--------- .../syslog/KafkatorioPacketKafkaProducer.kt | 24 +++++++++++++++++-- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt index 69872ae..1b059a7 100644 --- a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt @@ -26,8 +26,7 @@ import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.kstream.KStream -private const val PACKET_TAG = "KafkatorioPacket:::" -private const val PACKET_ENCODED_TAG = "${PACKET_TAG}encoded:" +private const val ENCODED_TAG = "encoded:" fun factorioServerPacketStream( @@ -43,7 +42,7 @@ fun factorioServerPacketStream( ) ).mapValues("decode-packets") { _: FactorioServerId, value: String? -> - val packet = decodeKafkatorioPacket(value) + val packet = decodeKafkatorioPacket(value?.trim()) if (packet.data is KafkatorioPacketDataError) { println("error parsing $TOPIC_SRC_SERVER_LOG message: $packet") @@ -73,20 +72,16 @@ fun splitFactorioServerPacketStream( private fun decodeKafkatorioPacket(value: String?): KafkatorioPacket = try { when { - value.isNullOrBlank() -> + value.isNullOrBlank() -> createErrorPacket(message = "null/blank message", rawValue = value) - value.substringAfter(PACKET_TAG).isBlank() -> - createErrorPacket(message = "missing '$PACKET_TAG'", rawValue = value) - - else -> { - val packetJson = if (PACKET_ENCODED_TAG in value) { - val encodedValue = value.substringAfter(PACKET_ENCODED_TAG) + else -> { + val packetJson = if (value.startsWith(ENCODED_TAG)) { + val encodedValue = value.substringAfter(ENCODED_TAG) decodeFactorioEncodedString(encodedValue) } else { - value.substringAfter(PACKET_TAG) + value } - jsonMapper.decodeFromString(KafkatorioPacket.serializer(), packetJson) } } diff --git a/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/KafkatorioPacketKafkaProducer.kt b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/KafkatorioPacketKafkaProducer.kt index 47a6446..f75ab4b 100644 --- a/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/KafkatorioPacketKafkaProducer.kt +++ b/modules/events-server-syslog/src/main/kotlin/dev/adamko/kafkatorio/processor/syslog/KafkatorioPacketKafkaProducer.kt @@ -101,9 +101,26 @@ class KafkatorioPacketKafkaProducer( serverId: FactorioServerId, syslog: SyslogMsg, ) { - val kafkatorioMessage = syslog.message?.substringAfter(":::") + val syslogMessage = syslog.message?.trim() - val record = ProducerRecord( + if (syslogMessage.isNullOrBlank()) { + // ignore blank messages + return + } + + if (!syslogMessage.startsWith(KAFKATORIO_MESSAGE_TAG)) { + // ignore non-Kafkatorio message + return + } + + val kafkatorioMessage = syslogMessage.substringAfter(KAFKATORIO_MESSAGE_TAG) + + if (kafkatorioMessage.isBlank()) { + produceDlqMessage(syslog, "error - Kafkatorio message was blank $syslogMessage") + return + } + + val record = ProducerRecord( TOPIC_SRC_SERVER_LOG, serverId, kafkatorioMessage, @@ -136,6 +153,9 @@ class KafkatorioPacketKafkaProducer( companion object { + private const val KAFKATORIO_MESSAGE_TAG = "KafkatorioPacket:::" + + private fun log(msg: String) = println("[KafkatorioPacketKafkaProducer] $msg") From de24a626356b7c5ee728f312a67baed4a4b63f76 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 18 Oct 2022 23:23:09 +0200 Subject: [PATCH 592/629] version 0.9.11 --- build.gradle.kts | 2 +- modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 433498d..1cfdbf4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.9.10" +version = "0.9.11" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index f3178b1..2f01efe 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.9", + "version": "0.9.11", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 3cde420..bdc2390 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.9", + "version": "0.9.11", "private": true, "scripts": { "build": "tstl", From 657d5712f6c581273667e64f987bbf72787d9cf4 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 22 Oct 2022 19:51:18 +0200 Subject: [PATCH 593/629] [geedeecee] improve handling of build-context files, and build-avoidance, and remove old code --- .../kotlin/kafkatorio/extensions/gradle.kt | 6 +- .../docker-compose/build.gradle.kts | 18 ---- .../dev/adamko/geedeecee/DockerComposeExec.kt | 96 ------------------- .../dev/adamko/geedeecee/GDCCommandTask.kt | 66 ------------- .../kotlin/dev/adamko/geedeecee/GDCPlugin.kt | 47 ++++++--- .../dev/adamko/geedeecee/GDCSettings.kt | 5 + .../{ => tasks}/DockerEnvUpdateTask.kt | 3 +- .../adamko/geedeecee/tasks/GDCCommandTask.kt | 90 +++++++++++++++++ 8 files changed, 135 insertions(+), 196 deletions(-) delete mode 100644 gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerComposeExec.kt delete mode 100644 gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt rename gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/{ => tasks}/DockerEnvUpdateTask.kt (97%) create mode 100644 gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/tasks/GDCCommandTask.kt diff --git a/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/extensions/gradle.kt b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/extensions/gradle.kt index e6dc6bb..f9d0046 100644 --- a/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/extensions/gradle.kt +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/extensions/gradle.kt @@ -80,12 +80,12 @@ fun Directory.filesChecksum(): Long = asFileTree /** Drop the first [count] directories from the path */ -fun FileCopyDetails.dropDirectories(count: Int): RelativePath = - RelativePath(true, *relativePath.segments.drop(count).toTypedArray()) +fun RelativePath.dropDirectories(count: Int): RelativePath = + RelativePath(true, *segments.drop(count).toTypedArray()) /** Drop the first directory from the path */ -fun FileCopyDetails.dropDirectory(): RelativePath = +fun RelativePath.dropDirectory(): RelativePath = dropDirectories(1) diff --git a/gradle-plugins/docker-compose/build.gradle.kts b/gradle-plugins/docker-compose/build.gradle.kts index 4108bb7..fe5b17f 100644 --- a/gradle-plugins/docker-compose/build.gradle.kts +++ b/gradle-plugins/docker-compose/build.gradle.kts @@ -1,31 +1,13 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - plugins { id("kafkatorio.conventions.kotlin-dsl") -// kotlin("jvm") version embeddedKotlinVersion -// `kotlin-dsl` `java-gradle-plugin` } -val gradleJvmTarget = "11" - dependencies { implementation(platform(libs.kotlin.bom)) implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable") } -//kotlin { -// jvmToolchain { -// (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) -// } -//} -// -//tasks.withType().configureEach { -// kotlinOptions { -// jvmTarget = gradleJvmTarget -// } -//} - gradlePlugin { plugins { create("geedeecee") { diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerComposeExec.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerComposeExec.kt deleted file mode 100644 index 8a11714..0000000 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerComposeExec.kt +++ /dev/null @@ -1,96 +0,0 @@ -package dev.adamko.geedeecee - -import javax.inject.Inject -import org.gradle.api.DefaultTask -import org.gradle.api.file.Directory -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.logging.LogLevel -import org.gradle.api.model.ObjectFactory -import org.gradle.api.provider.Property -import org.gradle.api.provider.ProviderFactory -import org.gradle.api.tasks.CacheableTask -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.OutputFile -import org.gradle.api.tasks.PathSensitive -import org.gradle.api.tasks.PathSensitivity -import org.gradle.api.tasks.SkipWhenEmpty -import org.gradle.api.tasks.TaskAction -import org.gradle.kotlin.dsl.property -import org.gradle.process.ExecOperations -import org.gradle.work.NormalizeLineEndings -import org.jetbrains.kotlin.incremental.md5 -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs - - -// look into using 'build context' for up-to-date check -// https://stackoverflow.com/questions/38946683/how-to-test-dockerignore-file -// https://github.com/pwaller/docker-show-context -// https://snippets.khromov.se/see-which-files-are-included-in-your-docker-build-context/ - - -@CacheableTask -@Suppress("UnstableApiUsage") -abstract class DockerComposeExec @Inject constructor( - private val executor: ExecOperations, - private val objects: ObjectFactory, - private val providers: ProviderFactory, -) : DefaultTask() { - - @get:InputDirectory - @get:SkipWhenEmpty - @get:PathSensitive(PathSensitivity.RELATIVE) - @get:NormalizeLineEndings - abstract val dockerComposeDir: DirectoryProperty - - @get:Input - abstract val command: Property - - @get:Input - val dockerIsActive: Property = objects.property().convention( - providers.exec { - commandLine = parseSpaceSeparatedArgs("docker info") - isIgnoreExitValue = true - }.result.map { - it.exitValue == 0 - } - ) - - @get:OutputFile - val stateFile: RegularFileProperty = objects.fileProperty().convention { - temporaryDir.resolve("docker-files.md5") - } - - init { - group = DOCKER_COMPOSE_GROUP - logging.captureStandardOutput(LogLevel.LIFECYCLE) - - super.onlyIf { task -> - require(task is DockerComposeExec) - task.dockerIsActive.getOrElse(false) - } - } - - @TaskAction - fun exec() { - executor.exec { - workingDir = dockerComposeDir.asFile.get() - commandLine = parseSpaceSeparatedArgs(command.get()) - } - - val inputChecksum = dockerComposeDir.get().filesChecksum() - stateFile.get().asFile.writeText("$inputChecksum") - } - - companion object { - const val DOCKER_COMPOSE_GROUP: String = "docker-compose" - - - private fun Directory.filesChecksum(): Long = asFileTree - .files - .map { it.readBytes() + it.absolutePath.toByteArray() } - .fold(byteArrayOf()) { acc, bytes -> acc + bytes } - .md5() - } -} diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt deleted file mode 100644 index 4596442..0000000 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCCommandTask.kt +++ /dev/null @@ -1,66 +0,0 @@ -package dev.adamko.geedeecee - -import javax.inject.Inject -import org.gradle.api.DefaultTask -import org.gradle.api.Task -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.logging.LogLevel -import org.gradle.api.provider.ListProperty -import org.gradle.api.provider.Property -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.TaskAction -import org.gradle.process.ExecOperations -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs - -abstract class GDCCommandTask @Inject constructor( - private val executor: ExecOperations -) : DefaultTask() { - - @get:InputDirectory - abstract val workingDir: DirectoryProperty - - @get:Input - abstract val separatedArgs: ListProperty - - @get:Input - abstract val dockerActive: Property - - init { - super.setGroup(GDCPlugin.GCD_TASK_GROUP) - description = "Run a docker-compose command." - - enabledIf { - it.dockerActive.orNull == true - } - - logging.captureStandardOutput(LogLevel.LIFECYCLE) - } - - @TaskAction - fun dockerCompose() { - val separatedArgs: List = separatedArgs.get() - - executor.exec { - environment("BUILDKIT_PROGRESS", "plain") - workingDir(this@GDCCommandTask.workingDir) - commandLine(separatedArgs) - } - } - - @Suppress("FunctionName") - fun `docker-compose`(args: String) { - separatedArgs.addAll( - parseSpaceSeparatedArgs("docker-compose $args") - ) - } - - companion object { - private inline fun T.enabledIf(crossinline spec: (T) -> Boolean) { - onlyIf { - require(it is T) - spec(it) - } - } - } -} diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt index eb46a5d..61710e3 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCPlugin.kt @@ -1,12 +1,19 @@ package dev.adamko.geedeecee +import dev.adamko.geedeecee.tasks.DockerContextFilesPreparation +import dev.adamko.geedeecee.tasks.DockerEnvUpdateTask +import dev.adamko.geedeecee.tasks.GDCCommandTask import javax.inject.Inject -import org.gradle.api.* -import org.gradle.api.file.ProjectLayout -import org.gradle.api.logging.* -import org.gradle.api.provider.* -import org.gradle.api.tasks.* -import org.gradle.kotlin.dsl.* +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.provider.Provider +import org.gradle.api.provider.ProviderFactory +import org.gradle.kotlin.dsl.apply +import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.getValue +import org.gradle.kotlin.dsl.provideDelegate +import org.gradle.kotlin.dsl.registering +import org.gradle.kotlin.dsl.withType import org.gradle.language.base.plugins.LifecycleBasePlugin import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs @@ -14,7 +21,6 @@ import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs @Suppress("UnstableApiUsage") abstract class GDCPlugin @Inject constructor( private val providers: ProviderFactory, - private val layout: ProjectLayout, ) : Plugin { @@ -34,6 +40,14 @@ abstract class GDCPlugin @Inject constructor( // ) } + val dockerContextPrepareFiles by target.tasks.registering(DockerContextFilesPreparation::class) { + into(gdcSettings.dockerBuildContextDir) + includeEmptyDirs = false +// dockerContextDir.set(gdcSettings.dockerBuildContextDir) +// copySpec.convention(target.copySpec()) +// copySpec = Action { } + } + val dockerComposeUp by target.tasks.registering(GDCCommandTask::class) { `docker-compose`("up -d") } @@ -45,6 +59,7 @@ abstract class GDCPlugin @Inject constructor( } val dockerComposeBuild by target.tasks.registering(GDCCommandTask::class) { `docker-compose`("build") + cacheable.set(true) } val dockerComposePush by target.tasks.registering(GDCCommandTask::class) { dependsOn(dockerComposeBuild) @@ -57,14 +72,21 @@ abstract class GDCPlugin @Inject constructor( dockerComposeUp.configure { dependsOn(dockerComposeBuild) } dockerComposeRemove.configure { dependsOn(dockerComposeDown) } - target.tasks.withType().configureEach { - dependsOn(dockerComposeEnvUpdate) - } +// target.tasks.withType().configureEach { +// dependsOn(dockerComposeEnvUpdate) +// dockerIsActive.set(isDockerActive()) +// stateFile.set(temporaryDir.resolve("docker-state.md5")) +// } target.tasks.withType().configureEach { - workingDir.convention(gdcSettings.srcDir) dependsOn(dockerComposeEnvUpdate) + dependsOn(dockerContextPrepareFiles) + + workingDir.convention(gdcSettings.srcDir) dockerActive.set(gdcSettings.dockerActive) + stateFile.set( + gdcSettings.stateDir.file(workingDir.map { "dc_state${name.hashCode()}${it.asFile.hashCode()}.md5" }) + ) } val assembleTasks = target.tasks.matching { LifecycleBasePlugin.ASSEMBLE_TASK_NAME == it.name } @@ -76,7 +98,6 @@ abstract class GDCPlugin @Inject constructor( dockerComposeUp.configure { dependsOn(assembleTasks) } - } @@ -86,6 +107,8 @@ abstract class GDCPlugin @Inject constructor( composeProjectVersion.convention(providers.provider { project.version.toString() }) containerRegistryHost.convention(providers.gradleProperty("dockerContainerRegistryHost")) srcDir.convention(layout.projectDirectory.dir("docker")) + dockerBuildContextDir.convention(srcDir.dir("build")) + stateDir.convention(layout.buildDirectory.dir("geedeecee/state/")) dotEnv.put("COMPOSE_PROJECT_NAME", composeProjectName) dotEnv.put("APP_NAME", providers.provider { project.name }) diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCSettings.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCSettings.kt index c11c427..a2efcdc 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCSettings.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/GDCSettings.kt @@ -26,6 +26,11 @@ interface GDCSettings { @get:Input val dockerActive: Property + @get:Input + val dockerBuildContextDir: DirectoryProperty + + val stateDir: DirectoryProperty + // @Suppress("PropertyName", "FunctionName") // abstract class DotEnv( // private val dotEnv: MapProperty, diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerEnvUpdateTask.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/tasks/DockerEnvUpdateTask.kt similarity index 97% rename from gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerEnvUpdateTask.kt rename to gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/tasks/DockerEnvUpdateTask.kt index 18e8130..13332e5 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/DockerEnvUpdateTask.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/tasks/DockerEnvUpdateTask.kt @@ -1,5 +1,6 @@ -package dev.adamko.geedeecee +package dev.adamko.geedeecee.tasks +import dev.adamko.geedeecee.GDCPlugin import java.io.File import java.nio.charset.Charset import java.util.Properties diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/tasks/GDCCommandTask.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/tasks/GDCCommandTask.kt new file mode 100644 index 0000000..fba14f3 --- /dev/null +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/tasks/GDCCommandTask.kt @@ -0,0 +1,90 @@ +package dev.adamko.geedeecee.tasks + +import dev.adamko.geedeecee.GDCPlugin +import dev.adamko.geedeecee.internal.enabledIf +import dev.adamko.geedeecee.internal.filesChecksum +import javax.inject.Inject +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.logging.LogLevel +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.api.tasks.SkipWhenEmpty +import org.gradle.api.tasks.TaskAction +import org.gradle.process.ExecOperations +import org.gradle.work.NormalizeLineEndings +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + + +// look into using 'build context' for up-to-date check +// https://stackoverflow.com/questions/38946683/how-to-test-dockerignore-file +// https://github.com/pwaller/docker-show-context +// https://snippets.khromov.se/see-which-files-are-included-in-your-docker-build-context/ +// or parsing Dockerfile +// https://github.com/keilerkonzept/dockerfile-json + + +@Suppress("UnstableApiUsage") // NormalizeLineEndings +abstract class GDCCommandTask @Inject constructor( + private val executor: ExecOperations, +) : DefaultTask() { + + @get:InputDirectory + @get:SkipWhenEmpty + @get:PathSensitive(PathSensitivity.RELATIVE) + @get:NormalizeLineEndings + abstract val workingDir: DirectoryProperty + + @get:Input + abstract val separatedArgs: ListProperty + + @get:Input + abstract val dockerActive: Property + + @get:Input + @get:Optional + abstract val cacheable: Property + + @get:OutputFile + abstract val stateFile: RegularFileProperty + + init { + group = GDCPlugin.GCD_TASK_GROUP + description = "Run a docker-compose command." + + enabledIf { it.dockerActive.getOrElse(false) } + + logging.captureStandardOutput(LogLevel.LIFECYCLE) + } + + @TaskAction + fun dockerCompose() { + val separatedArgs: List = separatedArgs.get() + + executor.exec { + environment("BUILDKIT_PROGRESS", "plain") + workingDir(this@GDCCommandTask.workingDir) + commandLine(separatedArgs) + } + + if (cacheable.getOrElse(false)) { + val inputChecksum = workingDir.get().filesChecksum() + stateFile.get().asFile.writeText("$inputChecksum") + } + } + + /** Set the `docker-compose` argument */ + @Suppress("FunctionName") + fun `docker-compose`(args: String) { + separatedArgs.set( + parseSpaceSeparatedArgs("docker-compose $args") + ) + } +} From ce0d4b73787dfc64c6e38864e17a77d8e9f5e3f6 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 22 Oct 2022 19:52:02 +0200 Subject: [PATCH 594/629] [events-processors] change where topo description is written --- .../processor/config/ApplicationProperties.kt | 2 +- .../processor/core/topologyLauncher.kt | 32 +++++++++++-------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt index f55e2c6..8107790 100644 --- a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt @@ -35,7 +35,7 @@ data class ApplicationProperties( .addEnvironmentSource() .addResourceOrFileSource( resourceOrFile = "${System.getProperty("user.home")}/.secret.kafkatorio-config.yml", - optional = true + optional = true, ) .addResourceOrFileSource("/.secret.config.yml", optional = true) .addResourceOrFileSource("/config.yml", optional = false) diff --git a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/topologyLauncher.kt b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/topologyLauncher.kt index a597711..5ead349 100644 --- a/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/topologyLauncher.kt +++ b/modules/events-processor-core/src/main/kotlin/dev/adamko/kafkatorio/processor/core/topologyLauncher.kt @@ -4,7 +4,6 @@ import dev.adamko.kafkatorio.processor.config.ApplicationProperties import java.util.Properties import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException -import kotlin.io.path.Path import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.cancel import kotlinx.coroutines.coroutineScope @@ -18,7 +17,6 @@ import org.apache.kafka.streams.Topology import org.apache.kafka.streams.TopologyDescription - suspend fun launchTopology( id: String, topology: Topology, @@ -58,7 +56,7 @@ suspend fun launchTopology( streams.close() } - printTopologyDescription(appId, topology) + printTopologyDescription(appId, topology, appProps) streams.start() println("launched Topology $appId") } @@ -68,21 +66,27 @@ suspend fun launchTopology( } -private fun printTopologyDescription(appId: String, topology: Topology) { +private fun printTopologyDescription( + appId: String, + topology: Topology, + appProps: ApplicationProperties, +) { val description: TopologyDescription = topology.describe() - val descFile = Path("./build/$appId.txt").toFile().apply { - parentFile.mkdirs() - if (!exists()) createNewFile() - writeText(description.toString()) - } + val descFile = appProps.serverDataDir + .resolve("kafka-streams/$appId.txt") + .toFile().apply { + parentFile.mkdirs() + if (!exists()) createNewFile() + writeText(description.toString()) + } println( """ - |---------------- - |$appId - ${descFile.canonicalPath} - |$description - |---------------- - """.trimMargin() + |---------------- + |$appId - ${descFile.canonicalPath} + |$description + |---------------- + """.trimMargin() ) } From e370cb5ef934172ac634f9a23726efe0dc042cca Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 22 Oct 2022 19:53:10 +0200 Subject: [PATCH 595/629] [geedeecee] add fileChecksum util --- .../dev/adamko/geedeecee/internal/files.kt | 12 ++++ .../dev/adamko/geedeecee/internal/gradle.kt | 14 +++++ .../tasks/DockerContextFilesPreparation.kt | 56 +++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/internal/files.kt create mode 100644 gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/internal/gradle.kt create mode 100644 gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/tasks/DockerContextFilesPreparation.kt diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/internal/files.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/internal/files.kt new file mode 100644 index 0000000..e0ba466 --- /dev/null +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/internal/files.kt @@ -0,0 +1,12 @@ +package dev.adamko.geedeecee.internal + +import org.gradle.api.file.Directory +import org.jetbrains.kotlin.incremental.md5 + +// should be moved to common plugins lib + +internal fun Directory.filesChecksum(): Long = asFileTree + .files + .map { it.readBytes() + it.absolutePath.toByteArray() } + .fold(byteArrayOf()) { acc, bytes -> acc + bytes } + .md5() diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/internal/gradle.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/internal/gradle.kt new file mode 100644 index 0000000..21385e6 --- /dev/null +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/internal/gradle.kt @@ -0,0 +1,14 @@ +package dev.adamko.geedeecee.internal + +import org.gradle.api.Task +import org.gradle.api.file.FileCopyDetails +import org.gradle.api.file.RelativePath + +// move to common-lib + +internal inline fun T.enabledIf(crossinline spec: (T) -> Boolean) { + onlyIf { + require(it is T) + spec(it) + } +} diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/tasks/DockerContextFilesPreparation.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/tasks/DockerContextFilesPreparation.kt new file mode 100644 index 0000000..a400711 --- /dev/null +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/tasks/DockerContextFilesPreparation.kt @@ -0,0 +1,56 @@ +package dev.adamko.geedeecee.tasks + +import dev.adamko.geedeecee.GDCPlugin +import javax.inject.Inject +import org.gradle.api.tasks.Sync + + +// look into using 'build context' for up-to-date check +// https://stackoverflow.com/questions/38946683/how-to-test-dockerignore-file +// https://github.com/pwaller/docker-show-context +// https://snippets.khromov.se/see-which-files-are-included-in-your-docker-build-context/ + + +//@CacheableTask +//@Suppress("UnstableApiUsage") +abstract class DockerContextFilesPreparation @Inject constructor( +// private val files: FileSystemOperations, +) : Sync() { + +// @get:InputFiles +//// @get:SkipWhenEmpty +// @get:PathSensitive(PathSensitivity.RELATIVE) +// @get:NormalizeLineEndings +// abstract val dockerContextFiles: ConfigurableFileCollection + +// @get:Input +// abstract val copySpec: Property +// +// @get:OutputDirectory +// abstract val dockerContextDir: DirectoryProperty + + init { + group = GDCPlugin.GCD_TASK_GROUP + } + +// @TaskAction +// fun exec() { +// files.sync { +// from(dockerContextFiles, copySpec) +// into(dockerContextDir) +//// with(copySpec) +// } +// } + +// /** @see [CopySpec.from] */ +// override fun from(vararg sourcePaths: Any?): CopySpec = +// copySpec.from(sourcePaths) +// +// /** @see [CopySpec.from] */ +// override fun from(sourcePath: Any, configureClosure: Closure<*>): CopySpec = +// copySpec.from(sourcePath, configureClosure) +// +// /** @see [CopySpec.from] */ +// override fun from(sourcePath: Any, configureAction: Action): CopySpec = +// copySpec.from(sourcePath, configureAction) +} From 9b331cc1050212da6933e0c22c3c00bf81917c5e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 22 Oct 2022 19:55:02 +0200 Subject: [PATCH 596/629] update dockerfiles - define user uid/gid - use new geedeecee files (hopefully means smaller images, faster building) --- modules/events-processors/build.gradle.kts | 14 ++++++- modules/events-processors/docker/Dockerfile | 19 ++++------ .../docker/docker-compose.yml | 7 ++-- modules/events-server-syslog/build.gradle.kts | 13 ++++++- .../events-server-syslog/docker/Dockerfile | 24 +++++------- .../docker/docker-compose.yml | 7 ++-- modules/events-server-web/build.gradle.kts | 13 ++++++- modules/events-server-web/docker/Dockerfile | 24 +++++------- .../docker/docker-compose.yml | 7 ++-- modules/events-server/docker/Dockerfile | 25 ++++++------ .../events-server/docker/docker-compose.yml | 7 ++-- modules/infra-kafka-pipe/build.gradle.kts | 38 ------------------- modules/web-map/build.gradle.kts | 4 +- modules/web-map/docker/Dockerfile | 5 ++- modules/web-map/docker/docker-compose.yml | 7 ++-- 15 files changed, 95 insertions(+), 119 deletions(-) diff --git a/modules/events-processors/build.gradle.kts b/modules/events-processors/build.gradle.kts index 37ea412..05835ab 100644 --- a/modules/events-processors/build.gradle.kts +++ b/modules/events-processors/build.gradle.kts @@ -1,3 +1,4 @@ +import kafkatorio.extensions.dropDirectory import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -90,6 +91,15 @@ val runEventsProcessors by tasks.registering { dependsOn(tasks.run) } -tasks.dockerComposeBuild { - dependsOn(tasks.distTar) + +tasks.dockerContextPrepareFiles { + from(zipTree(tasks.distZip.flatMap { it.archiveFile })) { + eachFile { + relativePath = relativePath.dropDirectory() + + if (!isDirectory && relativePath.pathString.matches("""bin\/.+""".toRegex())) { + name = name.replace(file.nameWithoutExtension, "run") + } + } + } } diff --git a/modules/events-processors/docker/Dockerfile b/modules/events-processors/docker/Dockerfile index b70ab64..9868b60 100644 --- a/modules/events-processors/docker/Dockerfile +++ b/modules/events-processors/docker/Dockerfile @@ -2,21 +2,18 @@ FROM eclipse-temurin:11-jdk-jammy ARG KAFKATORIO_VERSION -ARG DIST_DIR="../build/distributions/" -ARG APP_NAME="events-processors" +ARG APP_FILES="build/" +ARG USER_ID=1000 +ARG USER_GID=1000 -WORKDIR /app +USER $USER_ID:$USER_GID + +ENV SERVER_DATA_DIR="/app/data" \ + KAFKA_STREAMS_STATE_DIR="/app/state/kafka" -ENV SERVER_DATA_DIR="/app/data" -ENV KAFKA_STREAMS_STATE_DIR="/app/state/kafka" VOLUME ${SERVER_DATA_DIR} \ ${KAFKA_STREAMS_STATE_DIR} -COPY ${DIST_DIR}/${APP_NAME}-${KAFKATORIO_VERSION}.tar ${APP_NAME}.tar - -RUN tar -xf ${APP_NAME}.tar --strip-components=1 \ - && rm ${APP_NAME}.tar \ - && cp /app/bin/${APP_NAME} /app/bin/run \ - && chmod 775 /app/bin/run +COPY ${APP_FILES} /app/ ENTRYPOINT /app/bin/run diff --git a/modules/events-processors/docker/docker-compose.yml b/modules/events-processors/docker/docker-compose.yml index 9091b44..fc976f6 100644 --- a/modules/events-processors/docker/docker-compose.yml +++ b/modules/events-processors/docker/docker-compose.yml @@ -7,12 +7,11 @@ services: container_name: ${APP_NAME} restart: unless-stopped build: - context: .. - dockerfile: ./docker/Dockerfile + context: . + dockerfile: Dockerfile args: KAFKATORIO_VERSION: ${KAFKATORIO_VERSION} - DIST_DIR: "./build/distributions/" - APP_NAME: ${APP_NAME} + APP_FILES: "./build/" environment: KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" # KAFKA_STREAMS_STATE_DIR: "" diff --git a/modules/events-server-syslog/build.gradle.kts b/modules/events-server-syslog/build.gradle.kts index ca3a7ed..3e9dbf2 100644 --- a/modules/events-server-syslog/build.gradle.kts +++ b/modules/events-server-syslog/build.gradle.kts @@ -1,3 +1,4 @@ +import kafkatorio.extensions.dropDirectory import org.jetbrains.kotlin.gradle.tasks.KotlinCompile @@ -88,6 +89,14 @@ val runSyslogServer by tasks.registering { dependsOn(tasks.run) } -tasks.dockerComposeBuild { - dependsOn(tasks.distTar) +tasks.dockerContextPrepareFiles { + from(zipTree(tasks.distZip.flatMap { it.archiveFile })) { + eachFile { + relativePath = relativePath.dropDirectory() + + if (!isDirectory && relativePath.pathString.matches("""bin\/.+""".toRegex())) { + name = name.replace(file.nameWithoutExtension, "run") + } + } + } } diff --git a/modules/events-server-syslog/docker/Dockerfile b/modules/events-server-syslog/docker/Dockerfile index 0b76d0b..19c0a1a 100644 --- a/modules/events-server-syslog/docker/Dockerfile +++ b/modules/events-server-syslog/docker/Dockerfile @@ -2,26 +2,22 @@ FROM eclipse-temurin:11-jdk-jammy ARG KAFKATORIO_VERSION -ARG DIST_DIR="../build/distributions/" -ARG APP_NAME="events-server-syslog" +ARG APP_FILES="build/" +ARG USER_ID=1000 +ARG USER_GID=1000 -WORKDIR /app +USER $USER_ID:$USER_GID + +ENV SERVER_DATA_DIR="/app/data" \ + KAFKA_STREAMS_STATE_DIR="/app/state/kafka" \ + SOCKET_SERVER_HOST=0.0.0.0 \ + SOCKET_SERVER_PORT=9002 -ENV SOCKET_SERVER_HOST=0.0.0.0 -ENV SOCKET_SERVER_PORT=9002 EXPOSE $SOCKET_SERVER_PORT -ENV SERVER_DATA_DIR="/app/data" -ENV KAFKA_STREAMS_STATE_DIR="/app/state/kafka" - VOLUME ${SERVER_DATA_DIR} \ ${KAFKA_STREAMS_STATE_DIR} -COPY ${DIST_DIR}/${APP_NAME}-${KAFKATORIO_VERSION}.tar ${APP_NAME}.tar - -RUN tar -xf ${APP_NAME}.tar --strip-components=1 \ - && rm ${APP_NAME}.tar \ - && cp /app/bin/${APP_NAME} /app/bin/run \ - && chmod 775 /app/bin/run +COPY ${APP_FILES} /app/ ENTRYPOINT /app/bin/run diff --git a/modules/events-server-syslog/docker/docker-compose.yml b/modules/events-server-syslog/docker/docker-compose.yml index 855f34b..1fc4743 100644 --- a/modules/events-server-syslog/docker/docker-compose.yml +++ b/modules/events-server-syslog/docker/docker-compose.yml @@ -7,12 +7,11 @@ services: container_name: ${APP_NAME} restart: unless-stopped build: - context: .. - dockerfile: ./docker/Dockerfile + context: . + dockerfile: Dockerfile args: KAFKATORIO_VERSION: ${KAFKATORIO_VERSION} - DIST_DIR: "./build/distributions/" - APP_NAME: ${APP_NAME} + APP_FILES: "./build/" environment: KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" # KAFKA_STREAMS_STATE_DIR: "" diff --git a/modules/events-server-web/build.gradle.kts b/modules/events-server-web/build.gradle.kts index 57a4d2b..7b1b8c2 100644 --- a/modules/events-server-web/build.gradle.kts +++ b/modules/events-server-web/build.gradle.kts @@ -1,3 +1,4 @@ +import kafkatorio.extensions.dropDirectory import org.jetbrains.kotlin.gradle.tasks.KotlinCompile @@ -91,6 +92,14 @@ val runEventsWebServer by tasks.registering { dependsOn(tasks.run) } -tasks.dockerComposeBuild { - dependsOn(tasks.distTar) +tasks.dockerContextPrepareFiles { + from(zipTree(tasks.distZip.flatMap { it.archiveFile })) { + eachFile { + relativePath = relativePath.dropDirectory() + + if (!isDirectory && relativePath.pathString.matches("""bin\/.+""".toRegex())) { + name = name.replace(file.nameWithoutExtension, "run") + } + } + } } diff --git a/modules/events-server-web/docker/Dockerfile b/modules/events-server-web/docker/Dockerfile index 32c34e9..e767a17 100644 --- a/modules/events-server-web/docker/Dockerfile +++ b/modules/events-server-web/docker/Dockerfile @@ -1,26 +1,22 @@ # syntax=docker/dockerfile:1 -FROM openjdk:11 +FROM eclipse-temurin:11-jdk-jammy ARG KAFKATORIO_VERSION -ARG DIST_DIR="../build/distributions/" -ARG APP_NAME="events-server-web" +ARG APP_FILES="build/" +ARG USER_ID=1000 +ARG USER_GID=1000 -WORKDIR /app +USER $USER_ID:$USER_GID + +ENV SERVER_DATA_DIR="/app/data" \ + KAFKA_STREAMS_STATE_DIR="/app/state/kafka" \ + WEB_SERVER_PORT=80 -ENV WEB_SERVER_PORT=80 EXPOSE $WEB_SERVER_PORT -ENV SERVER_DATA_DIR="/app/data" -ENV KAFKA_STREAMS_STATE_DIR="/app/state/kafka" - VOLUME ${SERVER_DATA_DIR} \ ${KAFKA_STREAMS_STATE_DIR} -COPY ${DIST_DIR}/${APP_NAME}-${KAFKATORIO_VERSION}.tar ${APP_NAME}.tar - -RUN tar -xf ${APP_NAME}.tar --strip-components=1 \ - && rm ${APP_NAME}.tar \ - && cp /app/bin/${APP_NAME} /app/bin/run \ - && chmod 775 /app/bin/run +COPY ${APP_FILES} /app/ ENTRYPOINT /app/bin/run diff --git a/modules/events-server-web/docker/docker-compose.yml b/modules/events-server-web/docker/docker-compose.yml index e8ec9a7..59abd6c 100644 --- a/modules/events-server-web/docker/docker-compose.yml +++ b/modules/events-server-web/docker/docker-compose.yml @@ -7,12 +7,11 @@ services: container_name: ${APP_NAME} restart: unless-stopped build: - context: .. - dockerfile: ./docker/Dockerfile + context: . + dockerfile: Dockerfile args: KAFKATORIO_VERSION: ${KAFKATORIO_VERSION} - DIST_DIR: "./build/distributions/" - APP_NAME: ${APP_NAME} + APP_FILES: "./build/" environment: KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" # KAFKA_STREAMS_STATE_DIR: "" diff --git a/modules/events-server/docker/Dockerfile b/modules/events-server/docker/Dockerfile index 8c87699..c8e9492 100644 --- a/modules/events-server/docker/Dockerfile +++ b/modules/events-server/docker/Dockerfile @@ -2,24 +2,23 @@ FROM eclipse-temurin:11-jdk-jammy ARG KAFKATORIO_VERSION -ARG DIST_DIR="../build/distributions/" +ARG APP_FILES="build/" +ARG USER_ID=1000 +ARG USER_GID=1000 -WORKDIR /app +USER $USER_ID:$USER_GID -ENV SERVER_PORT=8080 -EXPOSE $SERVER_PORT +ENV SERVER_DATA_DIR="/app/data" \ + KAFKA_STREAMS_STATE_DIR="/app/state/kafka" \ + SERVER_PORT=8080 \ + SOCKET_SERVER_PORT=9002 -ENV SOCKET_SERVER_PORT=9002 -EXPOSE $SOCKET_SERVER_PORT +EXPOSE $SERVER_PORT \ + $SOCKET_SERVER_PORT -ENV SERVER_DATA_DIR="/app/data" -ENV KAFKA_STREAMS_STATE_DIR="/app/state/kafka" VOLUME ${SERVER_DATA_DIR} \ ${KAFKA_STREAMS_STATE_DIR} -COPY ${DIST_DIR}/events-server-${KAFKATORIO_VERSION}.tar events-server.tar +COPY ${APP_FILES} /app/ -RUN tar -xf events-server.tar --strip-components=1 \ - && rm events-server.tar - -ENTRYPOINT /app/bin/events-server +ENTRYPOINT /app/bin/run diff --git a/modules/events-server/docker/docker-compose.yml b/modules/events-server/docker/docker-compose.yml index 47d753a..b4400f0 100644 --- a/modules/events-server/docker/docker-compose.yml +++ b/modules/events-server/docker/docker-compose.yml @@ -7,12 +7,11 @@ services: container_name: ${APP_NAME} restart: unless-stopped build: - context: .. - dockerfile: ./docker/Dockerfile + context: . + dockerfile: Dockerfile args: KAFKATORIO_VERSION: ${KAFKATORIO_VERSION} - DIST_DIR: "./build/distributions/" - APP_NAME: ${APP_NAME} + APP_FILES: "./build/" environment: KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" # KAFKA_STREAMS_STATE_DIR: "" diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index e7ecb5b..e0380dd 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -1,5 +1,3 @@ -import dev.adamko.geedeecee.DockerComposeExec - plugins { id("kafkatorio.conventions.base") id("dev.adamko.geedeecee") @@ -17,39 +15,3 @@ geedeecee { tasks.dockerComposeUp { dependsOn(":modules:infra-kafka-cluster:dockerUp") } - - -val dockerBuildKafkaPipe by tasks.registering(DockerComposeExec::class) { - - dockerComposeDir.set(geedeecee.srcDir) - command.set("docker-compose build kafka-pipe") - - -// inputs.property("dockerSrcDirChecksum") { dockerSrcDir.filesChecksum() } -// -// outputs.upToDateWhen { -// it.inputs.properties["dockerSrcDirChecksum"] as? Long? == dockerSrcDir.filesChecksum() -// } - -// val imageIdFile = file("$temporaryDir/docker-image-id.txt") -// outputs.file(imageIdFile) - -// workingDir = dockerSrcDir.asFile -// commandLine = parseSpaceSeparatedArgs(""" docker-compose build kafka-pipe """) - -// doLast { -// sync { -// from(dockerSrcDir) -// into(temporaryDir) -// } -// imageIdFile.outputStream().use { os -> -// exec { -// workingDir = dockerSrcDir.asFile -// commandLine = parseSpaceSeparatedArgs(""" docker-compose images -q kafka-pipe """) -// standardOutput = os -// } -// } -//} -} - -tasks.assemble { dependsOn(dockerBuildKafkaPipe) } diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 60ade07..54e26f7 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -148,6 +148,6 @@ tasks.zip { } -tasks.dockerComposeBuild { - dependsOn(tasks.zip) +tasks.dockerContextPrepareFiles { + from(zipTree(tasks.zip.flatMap { it.archiveFile })) } diff --git a/modules/web-map/docker/Dockerfile b/modules/web-map/docker/Dockerfile index 1764c56..3cae269 100644 --- a/modules/web-map/docker/Dockerfile +++ b/modules/web-map/docker/Dockerfile @@ -1,9 +1,10 @@ # syntax=docker/dockerfile:1 FROM nginx +ARG APP_FILES="build/" EXPOSE 80 -COPY ./docker/nginx.conf /etc/nginx/nginx.conf +COPY ./nginx.conf /etc/nginx/nginx.conf -COPY ./build/distributions /usr/share/nginx/html +COPY $APP_FILES /usr/share/nginx/html diff --git a/modules/web-map/docker/docker-compose.yml b/modules/web-map/docker/docker-compose.yml index 6e5cf80..1170228 100644 --- a/modules/web-map/docker/docker-compose.yml +++ b/modules/web-map/docker/docker-compose.yml @@ -7,10 +7,11 @@ services: container_name: ${APP_NAME} restart: unless-stopped build: - context: ".." - dockerfile: ./docker/Dockerfile + context: . + dockerfile: Dockerfile args: - APP_NAME: ${APP_NAME} + KAFKATORIO_VERSION: ${KAFKATORIO_VERSION} + APP_FILES: "./build/" ports: - "12081:80" networks: From bb5e98f740081cbd1b20d1df628a723ca992e0ff Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 22 Oct 2022 19:55:18 +0200 Subject: [PATCH 597/629] version 0.9.12 --- build.gradle.kts | 2 +- modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 1cfdbf4..faf84af 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.9.11" +version = "0.9.12" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 2f01efe..f4c37f1 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.11", + "version": "0.9.12", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index bdc2390..dd27870 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.11", + "version": "0.9.12", "private": true, "scripts": { "build": "tstl", From c9d21fa25abbf9f43586761678d9c1d82c382dcd Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 22 Oct 2022 20:24:27 +0200 Subject: [PATCH 598/629] try fixing user permissions in containers --- modules/events-processors/docker/Dockerfile | 17 ++++++++++++++--- .../events-server-syslog/docker/Dockerfile | 18 +++++++++++++++--- modules/events-server-web/docker/Dockerfile | 18 +++++++++++++++--- modules/events-server/docker/Dockerfile | 19 +++++++++++++++---- 4 files changed, 59 insertions(+), 13 deletions(-) diff --git a/modules/events-processors/docker/Dockerfile b/modules/events-processors/docker/Dockerfile index 9868b60..f04efbf 100644 --- a/modules/events-processors/docker/Dockerfile +++ b/modules/events-processors/docker/Dockerfile @@ -3,17 +3,28 @@ FROM eclipse-temurin:11-jdk-jammy ARG KAFKATORIO_VERSION ARG APP_FILES="build/" -ARG USER_ID=1000 -ARG USER_GID=1000 +ARG USER_NAME="container_user" +ARG USER_UID=1000 +ARG USER_GID=$USER_ID -USER $USER_ID:$USER_GID ENV SERVER_DATA_DIR="/app/data" \ KAFKA_STREAMS_STATE_DIR="/app/state/kafka" + VOLUME ${SERVER_DATA_DIR} \ ${KAFKA_STREAMS_STATE_DIR} + COPY ${APP_FILES} /app/ + +RUN groupadd --gid $USER_GID $USERNAME \ + && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \ + && chown -R $USER_UID:$USER_GID /app/ + + +USER $USER_ID:$USER_GID + + ENTRYPOINT /app/bin/run diff --git a/modules/events-server-syslog/docker/Dockerfile b/modules/events-server-syslog/docker/Dockerfile index 19c0a1a..1ad7691 100644 --- a/modules/events-server-syslog/docker/Dockerfile +++ b/modules/events-server-syslog/docker/Dockerfile @@ -3,21 +3,33 @@ FROM eclipse-temurin:11-jdk-jammy ARG KAFKATORIO_VERSION ARG APP_FILES="build/" -ARG USER_ID=1000 -ARG USER_GID=1000 +ARG USER_NAME="container_user" +ARG USER_UID=1000 +ARG USER_GID=$USER_ID -USER $USER_ID:$USER_GID ENV SERVER_DATA_DIR="/app/data" \ KAFKA_STREAMS_STATE_DIR="/app/state/kafka" \ SOCKET_SERVER_HOST=0.0.0.0 \ SOCKET_SERVER_PORT=9002 + EXPOSE $SOCKET_SERVER_PORT + VOLUME ${SERVER_DATA_DIR} \ ${KAFKA_STREAMS_STATE_DIR} + COPY ${APP_FILES} /app/ + +RUN groupadd --gid $USER_GID $USERNAME \ + && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \ + && chown -R $USER_UID:$USER_GID /app/ + + +USER $USER_ID:$USER_GID + + ENTRYPOINT /app/bin/run diff --git a/modules/events-server-web/docker/Dockerfile b/modules/events-server-web/docker/Dockerfile index e767a17..b706a83 100644 --- a/modules/events-server-web/docker/Dockerfile +++ b/modules/events-server-web/docker/Dockerfile @@ -3,20 +3,32 @@ FROM eclipse-temurin:11-jdk-jammy ARG KAFKATORIO_VERSION ARG APP_FILES="build/" -ARG USER_ID=1000 -ARG USER_GID=1000 +ARG USER_NAME="container_user" +ARG USER_UID=1000 +ARG USER_GID=$USER_ID -USER $USER_ID:$USER_GID ENV SERVER_DATA_DIR="/app/data" \ KAFKA_STREAMS_STATE_DIR="/app/state/kafka" \ WEB_SERVER_PORT=80 + EXPOSE $WEB_SERVER_PORT + VOLUME ${SERVER_DATA_DIR} \ ${KAFKA_STREAMS_STATE_DIR} + COPY ${APP_FILES} /app/ + +RUN groupadd --gid $USER_GID $USERNAME \ + && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \ + && chown -R $USER_UID:$USER_GID /app/ + + +USER $USER_ID:$USER_GID + + ENTRYPOINT /app/bin/run diff --git a/modules/events-server/docker/Dockerfile b/modules/events-server/docker/Dockerfile index c8e9492..44fe964 100644 --- a/modules/events-server/docker/Dockerfile +++ b/modules/events-server/docker/Dockerfile @@ -2,23 +2,34 @@ FROM eclipse-temurin:11-jdk-jammy ARG KAFKATORIO_VERSION -ARG APP_FILES="build/" -ARG USER_ID=1000 -ARG USER_GID=1000 +ARG USER_NAME="container_user" +ARG USER_UID=1000 +ARG USER_GID=$USER_ID -USER $USER_ID:$USER_GID ENV SERVER_DATA_DIR="/app/data" \ KAFKA_STREAMS_STATE_DIR="/app/state/kafka" \ SERVER_PORT=8080 \ SOCKET_SERVER_PORT=9002 + EXPOSE $SERVER_PORT \ $SOCKET_SERVER_PORT + VOLUME ${SERVER_DATA_DIR} \ ${KAFKA_STREAMS_STATE_DIR} + COPY ${APP_FILES} /app/ + +RUN groupadd --gid $USER_GID $USERNAME \ + && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \ + && chown -R $USER_UID:$USER_GID /app/ + + +USER $USER_ID:$USER_GID + + ENTRYPOINT /app/bin/run From 45691a049b4435d9a8b743a70e4d26b08502a333 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 22 Oct 2022 20:27:17 +0200 Subject: [PATCH 599/629] [dockerfiles] fix user name/id variables --- modules/events-processors/docker/Dockerfile | 8 ++++---- modules/events-server-syslog/docker/Dockerfile | 8 ++++---- modules/events-server-web/docker/Dockerfile | 8 ++++---- modules/events-server/docker/Dockerfile | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/modules/events-processors/docker/Dockerfile b/modules/events-processors/docker/Dockerfile index f04efbf..26572b8 100644 --- a/modules/events-processors/docker/Dockerfile +++ b/modules/events-processors/docker/Dockerfile @@ -5,7 +5,7 @@ ARG KAFKATORIO_VERSION ARG APP_FILES="build/" ARG USER_NAME="container_user" ARG USER_UID=1000 -ARG USER_GID=$USER_ID +ARG USER_GID=$USER_UID ENV SERVER_DATA_DIR="/app/data" \ @@ -19,12 +19,12 @@ VOLUME ${SERVER_DATA_DIR} \ COPY ${APP_FILES} /app/ -RUN groupadd --gid $USER_GID $USERNAME \ - && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \ +RUN groupadd --gid $USER_GID $USER_NAME \ + && useradd --uid $USER_UID --gid $USER_GID -m $USER_NAME \ && chown -R $USER_UID:$USER_GID /app/ -USER $USER_ID:$USER_GID +USER $USER_UID:$USER_GID ENTRYPOINT /app/bin/run diff --git a/modules/events-server-syslog/docker/Dockerfile b/modules/events-server-syslog/docker/Dockerfile index 1ad7691..c297549 100644 --- a/modules/events-server-syslog/docker/Dockerfile +++ b/modules/events-server-syslog/docker/Dockerfile @@ -5,7 +5,7 @@ ARG KAFKATORIO_VERSION ARG APP_FILES="build/" ARG USER_NAME="container_user" ARG USER_UID=1000 -ARG USER_GID=$USER_ID +ARG USER_GID=$USER_UID ENV SERVER_DATA_DIR="/app/data" \ @@ -24,12 +24,12 @@ VOLUME ${SERVER_DATA_DIR} \ COPY ${APP_FILES} /app/ -RUN groupadd --gid $USER_GID $USERNAME \ - && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \ +RUN groupadd --gid $USER_GID $USER_NAME \ + && useradd --uid $USER_UID --gid $USER_GID -m $USER_NAME \ && chown -R $USER_UID:$USER_GID /app/ -USER $USER_ID:$USER_GID +USER $USER_UID:$USER_GID ENTRYPOINT /app/bin/run diff --git a/modules/events-server-web/docker/Dockerfile b/modules/events-server-web/docker/Dockerfile index b706a83..497a834 100644 --- a/modules/events-server-web/docker/Dockerfile +++ b/modules/events-server-web/docker/Dockerfile @@ -5,7 +5,7 @@ ARG KAFKATORIO_VERSION ARG APP_FILES="build/" ARG USER_NAME="container_user" ARG USER_UID=1000 -ARG USER_GID=$USER_ID +ARG USER_GID=$USER_UID ENV SERVER_DATA_DIR="/app/data" \ @@ -23,12 +23,12 @@ VOLUME ${SERVER_DATA_DIR} \ COPY ${APP_FILES} /app/ -RUN groupadd --gid $USER_GID $USERNAME \ - && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \ +RUN groupadd --gid $USER_GID $USER_NAME \ + && useradd --uid $USER_UID --gid $USER_GID -m $USER_NAME \ && chown -R $USER_UID:$USER_GID /app/ -USER $USER_ID:$USER_GID +USER $USER_UID:$USER_GID ENTRYPOINT /app/bin/run diff --git a/modules/events-server/docker/Dockerfile b/modules/events-server/docker/Dockerfile index 44fe964..697c11e 100644 --- a/modules/events-server/docker/Dockerfile +++ b/modules/events-server/docker/Dockerfile @@ -4,7 +4,7 @@ FROM eclipse-temurin:11-jdk-jammy ARG KAFKATORIO_VERSION ARG USER_NAME="container_user" ARG USER_UID=1000 -ARG USER_GID=$USER_ID +ARG USER_GID=$USER_UID ENV SERVER_DATA_DIR="/app/data" \ @@ -24,12 +24,12 @@ VOLUME ${SERVER_DATA_DIR} \ COPY ${APP_FILES} /app/ -RUN groupadd --gid $USER_GID $USERNAME \ - && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \ +RUN groupadd --gid $USER_GID $USER_NAME \ + && useradd --uid $USER_UID --gid $USER_GID -m $USER_NAME \ && chown -R $USER_UID:$USER_GID /app/ -USER $USER_ID:$USER_GID +USER $USER_UID:$USER_GID ENTRYPOINT /app/bin/run From 14e204d197bc0f4961f0a1edb762f7abd525dc7c Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 22 Oct 2022 20:28:22 +0200 Subject: [PATCH 600/629] version 0.9.13 --- build.gradle.kts | 2 +- modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index faf84af..2b171c7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.9.12" +version = "0.9.13" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index f4c37f1..706248a 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.12", + "version": "0.9.13", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index dd27870..75edaa2 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.12", + "version": "0.9.13", "private": true, "scripts": { "build": "tstl", From 82c681e320d1a780ad9ba4ea3708a4e357b0deab Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 22 Oct 2022 20:35:52 +0200 Subject: [PATCH 601/629] [dockerfiles] remove volumes --- modules/events-processors/docker/Dockerfile | 4 ---- modules/events-server-syslog/docker/Dockerfile | 4 ---- modules/events-server-web/docker/Dockerfile | 4 ---- modules/events-server/docker/Dockerfile | 4 ---- 4 files changed, 16 deletions(-) diff --git a/modules/events-processors/docker/Dockerfile b/modules/events-processors/docker/Dockerfile index 26572b8..be49eec 100644 --- a/modules/events-processors/docker/Dockerfile +++ b/modules/events-processors/docker/Dockerfile @@ -12,10 +12,6 @@ ENV SERVER_DATA_DIR="/app/data" \ KAFKA_STREAMS_STATE_DIR="/app/state/kafka" -VOLUME ${SERVER_DATA_DIR} \ - ${KAFKA_STREAMS_STATE_DIR} - - COPY ${APP_FILES} /app/ diff --git a/modules/events-server-syslog/docker/Dockerfile b/modules/events-server-syslog/docker/Dockerfile index c297549..7936c2b 100644 --- a/modules/events-server-syslog/docker/Dockerfile +++ b/modules/events-server-syslog/docker/Dockerfile @@ -17,10 +17,6 @@ ENV SERVER_DATA_DIR="/app/data" \ EXPOSE $SOCKET_SERVER_PORT -VOLUME ${SERVER_DATA_DIR} \ - ${KAFKA_STREAMS_STATE_DIR} - - COPY ${APP_FILES} /app/ diff --git a/modules/events-server-web/docker/Dockerfile b/modules/events-server-web/docker/Dockerfile index 497a834..6140d70 100644 --- a/modules/events-server-web/docker/Dockerfile +++ b/modules/events-server-web/docker/Dockerfile @@ -16,10 +16,6 @@ ENV SERVER_DATA_DIR="/app/data" \ EXPOSE $WEB_SERVER_PORT -VOLUME ${SERVER_DATA_DIR} \ - ${KAFKA_STREAMS_STATE_DIR} - - COPY ${APP_FILES} /app/ diff --git a/modules/events-server/docker/Dockerfile b/modules/events-server/docker/Dockerfile index 697c11e..d49ea67 100644 --- a/modules/events-server/docker/Dockerfile +++ b/modules/events-server/docker/Dockerfile @@ -17,10 +17,6 @@ EXPOSE $SERVER_PORT \ $SOCKET_SERVER_PORT -VOLUME ${SERVER_DATA_DIR} \ - ${KAFKA_STREAMS_STATE_DIR} - - COPY ${APP_FILES} /app/ From 51f44f1fd222303172a335342306e3ef4d21c87e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 22 Oct 2022 20:36:19 +0200 Subject: [PATCH 602/629] version 0.9.14 --- build.gradle.kts | 2 +- modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 2b171c7..378b76b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.9.13" +version = "0.9.14" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 706248a..8f4d91c 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.13", + "version": "0.9.14", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 75edaa2..865d96f 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.13", + "version": "0.9.14", "private": true, "scripts": { "build": "tstl", From e05557c97c164ac108c43f929b3c4fd9d875c8ad Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 22 Oct 2022 20:54:40 +0200 Subject: [PATCH 603/629] [web-map] fix missing css/image in dockerfile --- modules/web-map/build.gradle.kts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 54e26f7..2166dcb 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -144,7 +144,8 @@ val runWebMap by tasks.registering { tasks.zip { - dependsOn(tasks.withName("browserDistribution")) + dependsOn(tasks.withName("browserWebpack")) + from(layout.buildDirectory.dir("distributions")) } From 5562e86f09bfb6daae3d97f76be844cbe5de7781 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 22 Oct 2022 23:36:00 +0200 Subject: [PATCH 604/629] [docker-files] remove user config --- modules/events-processors/docker/Dockerfile | 11 ----------- modules/events-server-syslog/docker/Dockerfile | 11 ----------- modules/events-server-web/docker/Dockerfile | 11 ----------- modules/events-server/docker/Dockerfile | 11 ----------- 4 files changed, 44 deletions(-) diff --git a/modules/events-processors/docker/Dockerfile b/modules/events-processors/docker/Dockerfile index be49eec..265c100 100644 --- a/modules/events-processors/docker/Dockerfile +++ b/modules/events-processors/docker/Dockerfile @@ -3,9 +3,6 @@ FROM eclipse-temurin:11-jdk-jammy ARG KAFKATORIO_VERSION ARG APP_FILES="build/" -ARG USER_NAME="container_user" -ARG USER_UID=1000 -ARG USER_GID=$USER_UID ENV SERVER_DATA_DIR="/app/data" \ @@ -15,12 +12,4 @@ ENV SERVER_DATA_DIR="/app/data" \ COPY ${APP_FILES} /app/ -RUN groupadd --gid $USER_GID $USER_NAME \ - && useradd --uid $USER_UID --gid $USER_GID -m $USER_NAME \ - && chown -R $USER_UID:$USER_GID /app/ - - -USER $USER_UID:$USER_GID - - ENTRYPOINT /app/bin/run diff --git a/modules/events-server-syslog/docker/Dockerfile b/modules/events-server-syslog/docker/Dockerfile index 7936c2b..350fa3a 100644 --- a/modules/events-server-syslog/docker/Dockerfile +++ b/modules/events-server-syslog/docker/Dockerfile @@ -3,9 +3,6 @@ FROM eclipse-temurin:11-jdk-jammy ARG KAFKATORIO_VERSION ARG APP_FILES="build/" -ARG USER_NAME="container_user" -ARG USER_UID=1000 -ARG USER_GID=$USER_UID ENV SERVER_DATA_DIR="/app/data" \ @@ -20,12 +17,4 @@ EXPOSE $SOCKET_SERVER_PORT COPY ${APP_FILES} /app/ -RUN groupadd --gid $USER_GID $USER_NAME \ - && useradd --uid $USER_UID --gid $USER_GID -m $USER_NAME \ - && chown -R $USER_UID:$USER_GID /app/ - - -USER $USER_UID:$USER_GID - - ENTRYPOINT /app/bin/run diff --git a/modules/events-server-web/docker/Dockerfile b/modules/events-server-web/docker/Dockerfile index 6140d70..5a0c7f7 100644 --- a/modules/events-server-web/docker/Dockerfile +++ b/modules/events-server-web/docker/Dockerfile @@ -3,9 +3,6 @@ FROM eclipse-temurin:11-jdk-jammy ARG KAFKATORIO_VERSION ARG APP_FILES="build/" -ARG USER_NAME="container_user" -ARG USER_UID=1000 -ARG USER_GID=$USER_UID ENV SERVER_DATA_DIR="/app/data" \ @@ -19,12 +16,4 @@ EXPOSE $WEB_SERVER_PORT COPY ${APP_FILES} /app/ -RUN groupadd --gid $USER_GID $USER_NAME \ - && useradd --uid $USER_UID --gid $USER_GID -m $USER_NAME \ - && chown -R $USER_UID:$USER_GID /app/ - - -USER $USER_UID:$USER_GID - - ENTRYPOINT /app/bin/run diff --git a/modules/events-server/docker/Dockerfile b/modules/events-server/docker/Dockerfile index d49ea67..ccfdae5 100644 --- a/modules/events-server/docker/Dockerfile +++ b/modules/events-server/docker/Dockerfile @@ -2,9 +2,6 @@ FROM eclipse-temurin:11-jdk-jammy ARG KAFKATORIO_VERSION -ARG USER_NAME="container_user" -ARG USER_UID=1000 -ARG USER_GID=$USER_UID ENV SERVER_DATA_DIR="/app/data" \ @@ -20,12 +17,4 @@ EXPOSE $SERVER_PORT \ COPY ${APP_FILES} /app/ -RUN groupadd --gid $USER_GID $USER_NAME \ - && useradd --uid $USER_UID --gid $USER_GID -m $USER_NAME \ - && chown -R $USER_UID:$USER_GID /app/ - - -USER $USER_UID:$USER_GID - - ENTRYPOINT /app/bin/run From ccd08c87c85936ab20b9999a3ac7c8bbcd27ad4b Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 22 Oct 2022 23:37:15 +0200 Subject: [PATCH 605/629] version 0.9.15 --- build.gradle.kts | 2 +- modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 378b76b..031cb4f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.9.14" +version = "0.9.15" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 8f4d91c..4c7a5b1 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.14", + "version": "0.9.15", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 865d96f..025c52c 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.14", + "version": "0.9.15", "private": true, "scripts": { "build": "tstl", From 3f771f9838194a80e31a9e3f850bcea89e5b960e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 23 Oct 2022 21:54:38 +0200 Subject: [PATCH 606/629] fix bootstrap server, remove http:// --- modules/events-processor-core/src/main/resources/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/events-processor-core/src/main/resources/config.yml b/modules/events-processor-core/src/main/resources/config.yml index ea1d773..c74f9b5 100644 --- a/modules/events-processor-core/src/main/resources/config.yml +++ b/modules/events-processor-core/src/main/resources/config.yml @@ -10,12 +10,12 @@ socket-server-port: ${SOCKET_SERVER_PORT:-12092} kafka-admin-config: client.id: kafkatorio.events-server-admin - bootstrap.servers: ${KAFKA_BOOTSTRAP_SERVERS:-http://localhost:9092} + bootstrap.servers: ${KAFKA_BOOTSTRAP_SERVERS:-localhost:9092} kafka-streams-config: application.id: kafkatorio-events-processor - bootstrap.servers: ${KAFKA_BOOTSTRAP_SERVERS:-http://localhost:9092} + bootstrap.servers: ${KAFKA_BOOTSTRAP_SERVERS:-localhost:9092} state.dir: ${KAFKA_STREAMS_STATE_DIR:-.state/kafka} num.stream.threads: 1 processing.guarantee: exactly_once_v2 From aaca52a3e145f12e31c2bb760bcb138be035a790 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 23 Oct 2022 22:24:30 +0200 Subject: [PATCH 607/629] update kvision, kotlinx-cli, kotlinJsWrappers, kotest --- gradle/libs.versions.toml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e73add9..dab8d4c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ kotlin = "1.7.20" camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" kafka = "3.3.1" # https://kafka.apache.org/downloads -kvision = "5.16.1" # https://github.com/rjaros/kvision/releases +kvision = "5.16.2" # https://github.com/rjaros/kvision/releases log4j2 = "2.17.2" okio = "3.2.0" # https://search.maven.org/artifact/com.squareup.okio/okio qosLogback = "1.2.11" @@ -25,9 +25,9 @@ kxs-charleskornKaml = "0.44.0" kxs-mamoeYamlkt = "0.12.0" kxs-kxsTsGen = "0.2.1" -kotlinJsWrappers = "1.0.0-pre.407" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom +kotlinJsWrappers = "1.0.0-pre.413" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom -kotlinx-cli = "0.3.4" +kotlinx-cli = "0.3.5" # https://github.com/Kotlin/kotlinx-cli/releases kotlinx-coroutines = "1.6.4" # https://github.com/Kotlin/kotlinx.coroutines/releases kotlinx-datetime = "0.4.0" # https://github.com/Kotlin/kotlinx-datetime/releases kotlinx-html = "0.8.0" # https://github.com/Kotlin/kotlinx.html/releases @@ -60,7 +60,7 @@ npm-bootswatch = "5.2.2" # https://www.jsdelivr.com/package/npm/bootswat ## test ## junit = "5.9.1" # https://github.com/junit-team/junit5/releases -kotest = "5.5.0" # https://github.com/kotest/kotest/releases +kotest = "5.5.2" # https://github.com/kotest/kotest/releases mockk = "1.13.2" # https://github.com/mockk/mockk/releases/ @@ -262,13 +262,13 @@ junit-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine" junit-launcher = { group = "org.junit.platform", name = "junit-platform-launcher" } # version = "1.7.2" } ## kotest ## -kotest-bom = { group = "io.kotest", name = "kotest-bom", version.ref = "kotest" } -kotest-core = { group = "io.kotest", name = "kotest-assertions-core" } -kotest-datatest = { group = "io.kotest", name = "kotest-framework-datatest" } -kotest-json = { group = "io.kotest", name = "kotest-assertions-json" } -kotest-prop = { group = "io.kotest", name = "kotest-property" } -kotest-frameworkEngine = { group = "io.kotest", name = "kotest-framework-engine" } -kotest-runnerJunit5 = { group = "io.kotest", name = "kotest-runner-junit5" } +kotest-bom = { module = "io.kotest:kotest-bom", version.ref = "kotest" } +kotest-core = { module = "io.kotest:kotest-assertions-core" } +kotest-datatest = { module = "io.kotest:kotest-framework-datatest" } +kotest-json = { module = "io.kotest:kotest-assertions-json" } +kotest-prop = { module = "io.kotest:kotest-property" } +kotest-frameworkEngine = { module = "io.kotest:kotest-framework-engine" } +kotest-runnerJunit5 = { module = "io.kotest:kotest-runner-junit5" } kotestPlugin-embeddedCompiler = { group = "io.kotest", name = "kotest-framework-multiplatform-plugin-embeddable-compiler" } kotestPlugin-multiplatform = { group = "io.kotest", name = "kotest-framework-multiplatform-plugin-gradle" } From 531b8e193e2a4bf4629f7e83891b877bfcf94080 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 30 Oct 2022 17:13:03 +0100 Subject: [PATCH 608/629] tidy up gradle plugins (mostly removing comments) --- .../builder-plugins/build.gradle.kts | 20 ------------ .../factorio-gradle/build.gradle.kts | 32 +------------------ .../gradle/factorio/FactorioModPlugin.kt | 3 -- .../settings-plugins/build.gradle.kts | 2 ++ modules/web-map/build.gradle.kts | 2 -- 5 files changed, 3 insertions(+), 56 deletions(-) diff --git a/gradle-plugins/builder-plugins/build.gradle.kts b/gradle-plugins/builder-plugins/build.gradle.kts index 9708397..ee54055 100644 --- a/gradle-plugins/builder-plugins/build.gradle.kts +++ b/gradle-plugins/builder-plugins/build.gradle.kts @@ -2,8 +2,6 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("kafkatorio.conventions.kotlin-dsl") -// `kotlin-dsl` -// kotlin("jvm") version embeddedKotlinVersion } dependencies { @@ -43,21 +41,3 @@ tasks.withType().configureEach { "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", ) } - -//val gradleJvmTarget = "11" -// -//kotlin { -// jvmToolchain { -// (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) -// } -//} -// -//kotlinDslPluginOptions { -// jvmTarget.set(gradleJvmTarget) -//} -// -//tasks.withType().configureEach { -// kotlinOptions { -// jvmTarget = gradleJvmTarget -// } -//} diff --git a/gradle-plugins/factorio-gradle/build.gradle.kts b/gradle-plugins/factorio-gradle/build.gradle.kts index 6b19f3b..77a630f 100644 --- a/gradle-plugins/factorio-gradle/build.gradle.kts +++ b/gradle-plugins/factorio-gradle/build.gradle.kts @@ -33,23 +33,6 @@ dependencies { implementation(libs.ktorSerialization.kotlinxJson) } - -//val gradleJvmTarget = 11 -// -//kotlin { -// jvmToolchain(gradleJvmTarget) -//} -// -//kotlinDslPluginOptions { -// jvmTarget.set("$gradleJvmTarget") -//} -// -//tasks.withType().configureEach { -// kotlinOptions { -// jvmTarget = "$gradleJvmTarget" -// } -//} - gradlePlugin { plugins { create("factorioMod") { @@ -60,20 +43,7 @@ gradlePlugin { } } - -overrideKotlinLanguageVersion("1.7") - -//val gradleKotlinTarget = "1.7" -// -//afterEvaluate { -// tasks.withType().configureEach { -// kotlinOptions { -// apiVersion = gradleKotlinTarget -// languageVersion = gradleKotlinTarget -// } -// } -//} - +overrideKotlinLanguageVersion("1.7") // required for Kotlinx Serialization tasks.withType().configureEach { kotlinOptions.freeCompilerArgs += listOf( diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModPlugin.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModPlugin.kt index 06146b6..920a7d6 100644 --- a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModPlugin.kt +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModPlugin.kt @@ -14,14 +14,11 @@ abstract class FactorioModPlugin @Inject constructor( override fun apply(target: Project) { target.createSettings() - val factorioModConfiguration = target.configurations.register(FACTORIO_GRADLE_CONFIGURATION_NAME) { asConsumer() factorioModAttributes(objects) } - - } private fun Project.createSettings(): FactorioModSettings { diff --git a/gradle-plugins/settings-plugins/build.gradle.kts b/gradle-plugins/settings-plugins/build.gradle.kts index 10e849f..667932d 100644 --- a/gradle-plugins/settings-plugins/build.gradle.kts +++ b/gradle-plugins/settings-plugins/build.gradle.kts @@ -8,6 +8,8 @@ plugins { val gradleJvmTarget = "11" +description = "Provide Gradle settings plugins, used to configure base Gradle behaviour" + dependencies { // This project should only be providing simple plugins for configuring Gradle without // dependencies. Try to avoid setting dependencies here, else the Gradle script classpath might diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 2166dcb..e8175a8 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -38,7 +38,6 @@ kotlin { "ws" to true, ), ), -// static = mutableListOf("$buildDir/processedResources/frontend/main") static = mutableListOf("$buildDir/processedResources/js/main") ) } @@ -139,7 +138,6 @@ val runWebMap by tasks.registering { group = rootProject.name dependsOn(tasks.withName("browserDevelopmentRun")) - } From b9ad7e246612cf5363b7cfb028dda7a5e29bbaf1 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 30 Oct 2022 17:13:12 +0100 Subject: [PATCH 609/629] update yarn.lock --- gradle/kotlin-js-store/yarn.lock | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index 8e776d3..b4568f5 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -215,11 +215,6 @@ dependencies: "@types/node" "*" -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - "@webassemblyjs/ast@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" @@ -1791,7 +1786,7 @@ kvision-assets@^6.0.0: resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-6.0.0.tgz#de17ec942efd067fc180e7fab4e040c4e41bbe25" integrity sha512-fjPGTMGiboRnXXwhQFVOsRdDaDFnBfAQBRGhbzjQUp5oJKUnPS303Pua0u5atQdYMXyN/u6fyH6TEHgQzM9Wog== -leaflet@^1.9.1: +leaflet@^1.9.2: version "1.9.2" resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.9.2.tgz#168b6c6ef1d4d1e8409bde2c4ad050c249c4dbe6" integrity sha512-Kc77HQvWO+y9y2oIs3dn5h5sy2kr3j41ewdqCMEUA4N89lgfUUfOBy7wnnHEstDpefiGFObq12FdopGRMx4J7g== @@ -1939,12 +1934,11 @@ mkdirp@^0.5.5: dependencies: minimist "^1.2.6" -mocha@10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.0.0.tgz#205447d8993ec755335c4b13deba3d3a13c4def9" - integrity sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA== +mocha@10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.1.0.tgz#dbf1114b7c3f9d0ca5de3133906aea3dfc89ef7a" + integrity sha512-vUF7IYxEoN7XhQpFLxQAEMtE4W91acW4B6En9l97MwE9stL1A9gusXfoHZCLVHDUJ/7V5+lbCM6yMqzo5vNymg== dependencies: - "@ungap/promise-all-settled" "1.1.2" ansi-colors "4.1.1" browser-stdout "1.3.1" chokidar "3.5.3" From 5bb8cc789cdbcc407d7f39166ce01d8c4a3fb32a Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 30 Oct 2022 17:21:32 +0100 Subject: [PATCH 610/629] add/update docs --- README.md | 33 +++-- docs/guide.md | 52 +++++++ .../config/kafka-server.properties | 130 ++++++++++++++++ docs/kafkatorio-platform/docker-compose.yml | 140 ++++++++++++++++++ docs/kafkatorio-platform/example.env | 10 ++ .../example.secret.kafkatorio-config.yml | 10 ++ gradle/libs.versions.toml | 2 +- 7 files changed, 361 insertions(+), 16 deletions(-) create mode 100644 docs/guide.md create mode 100644 docs/kafkatorio-platform/config/kafka-server.properties create mode 100644 docs/kafkatorio-platform/docker-compose.yml create mode 100644 docs/kafkatorio-platform/example.env create mode 100644 docs/kafkatorio-platform/example.secret.kafkatorio-config.yml diff --git a/README.md b/README.md index 54c20e7..e0c3d07 100644 --- a/README.md +++ b/README.md @@ -15,21 +15,8 @@ inter-server communication. ### Overview -```mermaid -sequenceDiagram - -Factorio multiplayer server->>events-mod: in-game events -Note over events-mod: converts events to packets -events-mod->>logs processor: packets logged to console -logs processor->>Kafka: publishes packets
(Requires API key!) - -Kafka->>events-server: - -Note over events-server: Packets are processed - -events-server->>web-map: Web map tiles (REST API) -events-server-)web-map: WebSocket updates
(e.g. player movement) -``` +This is a brief overview of how Kafkatorio gathers data, processes it, and uses it to create the +live web-map. 1. The Kafkatorio game mod, [`events-mod`](./modules/events-mod), collects event data, de-bouncing and grouping events, and converts them to JSON packets @@ -47,6 +34,22 @@ events-server-)web-map: WebSocket updates
(e.g. player movement) 5. The `web-map` uses Leaflet/JS to display the map, using the tiles and WebSocket messages from `events-server` +```mermaid +sequenceDiagram + +Factorio multiplayer server->>events-mod: in-game events +Note over events-mod: converts events to packets +events-mod->>logs processor: packets logged to console +logs processor->>Kafka: publishes packets
(Requires API key!) + +Kafka->>events-server: + +Note over events-server: Packets are processed + +events-server->>web-map: Web map tiles (REST API) +events-server-)web-map: WebSocket updates
(e.g. player movement) +``` + ## License While this project is under development, [no license](https://choosealicense.com/no-permission/) diff --git a/docs/guide.md b/docs/guide.md new file mode 100644 index 0000000..8fd2a94 --- /dev/null +++ b/docs/guide.md @@ -0,0 +1,52 @@ +# Running Kafkatorio + +### Building the project + +#### Requirements + +* Docker +* Docker Compose +* Java 11 + +Kafkatorio uses [Gradle](https://docs.gradle.org/current/userguide/getting_started.html) to +build the project, and Docker Compose to create images. + +* `./gradlew build` - build and test the project +* `./gradlew runKafkatorio` - run locally (if Docker is running, a Kafka instance will start) +* `./gradlew dockerComposeBuild` - build, test, and create Kafkatorio Docker images + +### Server set up + +> See [./kafkatorio-platform/docker-compose.yml](kafkatorio-platform/docker-compose.yml) for a +> complete example + +1. Copy the [kafkatorio-platform](./kafkatorio-platform) directory to your computer +2. Rename + [`example.secret.kafkatorio-config.yml`](./kafkatorio-platform/example.secret.kafkatorio-config.yml) + to `.secret.kafkatorio-config.yml` + + In it, define both + * a JWT secret password (a long alphanumeric string is best, you won't need to type this + password manually) + * a Factorio server, with a short-ID and a description. +3. Rename [`example.env`](./kafkatorio-platform/example.env) to `.env` +4. Create a JWT for your Factorio server, by going to https://jwt.io/ + + * In 'PAYLOAD: DATA', set `sub` to your Factorio server's short ID. + ```json + { + "sub": "", + "iat": ... + } + ``` + (`iat`, 'issued-at-time', should update automatically to be the current time.) + * Replace `your-256-bit-secret` with your JWT secret password + + Copy the 'Encoded' token (it should start with `ey`). + + In the `.env` file, set `KAFKATORIO_TOKEN` to equal the token. +5. In `kafkatorio-platform`, start the docker containers + + ```terminal + docker-compose up -d; docker-compose logs -f + ``` diff --git a/docs/kafkatorio-platform/config/kafka-server.properties b/docs/kafkatorio-platform/config/kafka-server.properties new file mode 100644 index 0000000..dd3de1f --- /dev/null +++ b/docs/kafkatorio-platform/config/kafka-server.properties @@ -0,0 +1,130 @@ +# This configuration file is intended for use in KRaft mode, where +# Apache ZooKeeper is not present. See config/kraft/README.md for details. + +############################# Server Basics ############################# + +# The role of this server. Setting this puts us in KRaft mode +process.roles=broker,controller + +# The node id associated with this instance's roles +node.id=1 + +# The connect string for the controller quorum +controller.quorum.voters=1@localhost:9093 + +############################# Socket Server Settings ############################# + +# The address the socket server listens on. It will get the value returned from +# java.net.InetAddress.getCanonicalHostName() if not configured. +# FORMAT: +# listeners = listener_name://host_name:port +# EXAMPLE: +# listeners = PLAINTEXT://your.host.name:9092 +#listeners=PLAINTEXT://:9092,CONTROLLER://:9093 +#listeners=PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092,CONTROLLER://localhost:9093 +listeners=PLAINTEXT://:29092,PLAINTEXT_HOST://:9092,CONTROLLER://:9093 + +inter.broker.listener.name=PLAINTEXT +#KAFKA_INTER_BROKER_LISTENER_NAME: "PLAINTEXT" + +# Hostname and port the broker will advertise to producers and consumers. If not set, +# it uses the value for "listeners" if configured. Otherwise, it will use the value +# returned from java.net.InetAddress.getCanonicalHostName(). +#advertised.listeners=PLAINTEXT://localhost:9092 +advertised.listeners=PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092 + +# Listener, host name, and port for the controller to advertise to the brokers. If +# this server is a controller, this listener must be configured. +controller.listener.names=CONTROLLER + +# Maps listener names to security protocols, the default is for them to be the same. See the config documentation for more details +#listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,SSL:SSL,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSL +listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT +# ,SSL:SSL,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSL + +# The number of threads that the server uses for receiving requests from the network and sending responses to the network +num.network.threads=3 + +# The number of threads that the server uses for processing requests, which may include disk I/O +num.io.threads=8 + +# The send buffer (SO_SNDBUF) used by the socket server +socket.send.buffer.bytes=102400 + +# The receive buffer (SO_RCVBUF) used by the socket server +socket.receive.buffer.bytes=102400 + +# The maximum size of a request that the socket server will accept (protection against OOM) +socket.request.max.bytes=104857600 + + +############################# Log Basics ############################# + +# A comma separated list of directories under which to store log files +log.dirs=/tmp/kraft-combined-logs + +# The default number of log partitions per topic. More partitions allow greater +# parallelism for consumption, but this will also result in more files across +# the brokers. +num.partitions=3 + +# The number of threads per data directory to be used for log recovery at startup and flushing at shutdown. +# This value is recommended to be increased for installations with data dirs located in RAID array. +num.recovery.threads.per.data.dir=1 + +############################# Internal Topic Settings ############################# +# The replication factor for the group metadata internal topics "__consumer_offsets" and "__transaction_state" +# For anything other than development testing, a value greater than 1 is recommended to ensure availability such as 3. +offsets.topic.replication.factor=1 +transaction.state.log.replication.factor=1 +transaction.state.log.min.isr=1 + +############################# Log Flush Policy ############################# + +# Messages are immediately written to the filesystem but by default we only fsync() to sync +# the OS cache lazily. The following configurations control the flush of data to disk. +# There are a few important trade-offs here: +# 1. Durability: Unflushed data may be lost if you are not using replication. +# 2. Latency: Very large flush intervals may lead to latency spikes when the flush does occur as there will be a lot of data to flush. +# 3. Throughput: The flush is generally the most expensive operation, and a small flush interval may lead to excessive seeks. +# The settings below allow one to configure the flush policy to flush data after a period of time or +# every N messages (or both). This can be done globally and overridden on a per-topic basis. + +# The number of messages to accept before forcing a flush of data to disk +#log.flush.interval.messages=10000 + +# The maximum amount of time a message can sit in a log before we force a flush +#log.flush.interval.ms=1000 + +############################# Log Retention Policy ############################# + +# The following configurations control the disposal of log segments. The policy can +# be set to delete segments after a period of time, or after a given size has accumulated. +# A segment will be deleted whenever *either* of these criteria are met. Deletion always happens +# from the end of the log. + +# The minimum age of a log file to be eligible for deletion due to age +log.retention.hours=168 + +# A size-based retention policy for logs. Segments are pruned from the log unless the remaining +# segments drop below log.retention.bytes. Functions independently of log.retention.hours. +#log.retention.bytes=1073741824 + +# The maximum size of a log segment file. When this size is reached a new log segment will be created. +log.segment.bytes=1073741824 + +# The interval at which log segments are checked to see if they can be deleted according +# to the retention policies +log.retention.check.interval.ms=300000 + +### Compression ### +#compression.type=snappy +#linger.ms=5 + + +### record size ### +message.max.bytes=10485760 +replica.fetch.max.bytes=10485760 + +#log.cleanup.policy=compact +#auto.create.topics.enable=false diff --git a/docs/kafkatorio-platform/docker-compose.yml b/docs/kafkatorio-platform/docker-compose.yml new file mode 100644 index 0000000..5826700 --- /dev/null +++ b/docs/kafkatorio-platform/docker-compose.yml @@ -0,0 +1,140 @@ +version: "3.9" + +services: + + ## Factorio game server that players will connect to + factorio-server: + image: factoriotools/factorio:${FACTORIO_VERSION} + container_name: "factorio-server" + restart: unless-stopped + profiles: [ "factorio", "kafkatorio" ] + networks: + - kafkatorio-infra-nw + ports: + - "34198:34197/udp" # factorio + - "27016:27015/tcp" # rcon + volumes: + - "./factorio-server:/factorio" + logging: + # set up syslog, so logs can be forwarded to Kafkatorio + driver: syslog + options: + syslog-address: ${SYSLOG_ADDRESS} + syslog-format: "rfc5424" + # set the tag to be a JWT, containing the server short-ID + tag: ${KAFKATORIO_TOKEN} + + + ## Kafkatorio Web Map host + web-map: + image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/web-map:${KAFKATORIO_VERSION} + container_name: web-map + profiles: [ "infra", "kafkatorio" ] + restart: unless-stopped + networks: + - kafkatorio-infra-nw + + + ## Process Kafkatorio events + events-processors: + image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/events-processors:${KAFKATORIO_VERSION} + container_name: events-processors + restart: unless-stopped + profiles: [ "infra", "kafkatorio" ] + environment: + KAFKA_BOOTSTRAP_SERVERS: "kafka:29092" + networks: + - kafkatorio-infra-nw + depends_on: + - infra-kafka + secrets: + - source: kafkatorio_config + target: /.secret.config.yml + + + ## Receives packets from the Factorio Server, forwarded via Docker syslog-plugin + events-server-syslog: + image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/events-server-syslog:${KAFKATORIO_VERSION} + container_name: events-server-syslog + restart: unless-stopped + profiles: [ "infra", "kafkatorio" ] + environment: + KAFKA_BOOTSTRAP_SERVERS: "kafka:29092" + SOCKET_SERVER_HOST: "0.0.0.0" + SOCKET_SERVER_PORT: "9002" + ports: + - "12035:9002" # syslog socket + networks: + - kafkatorio-infra-nw + depends_on: + - infra-kafka + - events-processors + secrets: + - source: kafkatorio_config + target: /.secret.config.yml + + + ## Hosts map-tiles and forwards websocket messages to the web-map browsers + events-server-web: + image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/events-server-web:${KAFKATORIO_VERSION} + container_name: events-server-web + restart: unless-stopped + profiles: [ "infra", "kafkatorio" ] + environment: + KAFKA_BOOTSTRAP_SERVERS: "kafka:29092" + WEB_SERVER_PORT: "80" + ports: + - "12080:80" # http and ws + networks: + - kafkatorio-infra-nw + depends_on: + - infra-kafka + - events-processors + secrets: + - source: kafkatorio_config + target: /.secret.config.yml + + + ## An instance of Kafka + infra-kafka: + image: ${REGISTRY_HOST}/dev.adamko.kafkatorio/kafka-kraft:${KAFKATORIO_VERSION} + container_name: infra-kafka + restart: unless-stopped + profiles: [ "infra", "kafka" ] + networks: + kafkatorio-infra-nw: + aliases: [ kafka ] + volumes: + - "./config/kafka-server.properties:/kafka/server.properties" + ports: + # note: other Docker containers should use 29092 + - "9092:9092" + - "9093:9093" + + + ## web-based GUI for Kafka + infra-kafka-ui: + image: provectuslabs/kafka-ui:v0.4.0 + container_name: infra-kafka-ui + restart: unless-stopped + profiles: [ "infra", "kafka" ] + networks: + - kafkatorio-infra-nw + ports: + - "18090:8080" + depends_on: + - infra-kafka + environment: + KAFKA_CLUSTERS_0_NAME: "${COMPOSE_PROJECT_NAME}" + KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: "kafka:29092" + + + +secrets: + kafkatorio_config: + file: ./.secret.kafkatorio-config.yml + + +networks: + kafkatorio-infra-nw: + kafkatorio-game-nw: diff --git a/docs/kafkatorio-platform/example.env b/docs/kafkatorio-platform/example.env new file mode 100644 index 0000000..4339796 --- /dev/null +++ b/docs/kafkatorio-platform/example.env @@ -0,0 +1,10 @@ +# Docker Compose containers config + +COMPOSE_PROJECT_NAME=Kafkatorio + +KAFKATORIO_TOKEN= +KAFKATORIO_VERSION=0.9.15 + +REGISTRY_HOST=localhost + +SYSLOG_ADDRESS=tcp://www.my-website.com:12345 diff --git a/docs/kafkatorio-platform/example.secret.kafkatorio-config.yml b/docs/kafkatorio-platform/example.secret.kafkatorio-config.yml new file mode 100644 index 0000000..4e5237b --- /dev/null +++ b/docs/kafkatorio-platform/example.secret.kafkatorio-config.yml @@ -0,0 +1,10 @@ +# Kafkatorio server config + +jwt-secret: "correct horse battery staple" + +# Define the servers that have the Kafkatorio Mod installed. +kafkatorio-servers: + # The key is the short ID, used to uniquely identify a server (used in URLs). + # The value is a description. + short-id-123: "Name of server" + another-id-456: "Name of another server" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index dab8d4c..9fb61b9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -47,7 +47,7 @@ marykRocksDb = "7.3.1-2" # https://search.maven.org/artifact/io.m klogging = "0.4.9" -nimbusJoseJwt = "9.25.6" # https://search.maven.org/artifact/com.nimbusds/nimbus-jose-jwt +nimbusJoseJwt = "9.25.6" # https://search.maven.org/artifact/com.nimbusds/nimbus-jose-jwt ## npm ## From f0b080a7fed14fcec1e8db04b71e5a5c2a649376 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 30 Oct 2022 18:44:11 +0100 Subject: [PATCH 611/629] optimise logo --- .../src/main/resources/kafkatorio-logo.svg | 9513 +---------------- 1 file changed, 48 insertions(+), 9465 deletions(-) diff --git a/modules/events-mod/src/main/resources/kafkatorio-logo.svg b/modules/events-mod/src/main/resources/kafkatorio-logo.svg index 77c43d2..1bd35cd 100644 --- a/modules/events-mod/src/main/resources/kafkatorio-logo.svg +++ b/modules/events-mod/src/main/resources/kafkatorio-logo.svg @@ -1,9488 +1,71 @@ + id="kafkatorio-logo" + version="1.1" + viewBox="0 0 132.29166 132.29167" + height="500" + width="500" + xmlns="http://www.w3.org/2000/svg"> - + id="defs887"> + id="linearGradient24276"> - + style="stop-color:#ffffff;stop-opacity:1;" + offset="0" + id="stop24274" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + id="path7756" + style="color:#000000;fill:#2f2f2f;stroke:none;stroke-width:0.277019;-inkscape-stroke:none;paint-order:markers stroke fill;fill-opacity:1;font-variation-settings:normal;vector-effect:none;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;stop-color:#000000;stop-opacity:1" + d="m 50.246826,94.1604 c -0.533535,0.0031 -1.076759,0.05108 -1.62419,0.14211 l -0.145727,0.02532 0.02481,0.102836 -0.582909,2.810165 c -1.466601,0.297805 -2.828065,0.864653 -4.035414,1.644344 l -2.322857,-1.584916 -0.0031,0.0026 -0.06563,-0.105421 -0.117306,0.077 c -0.985745,0.638295 -1.849646,1.509846 -2.567802,2.5554 l -0.08268,0.123505 0.09147,0.0537 1.591636,2.32544 c -0.787769,1.19724 -1.362,2.54273 -1.673293,3.98012 l -2.732132,0.53589 v 0.004 l -0.123508,-0.0279 -0.02687,0.13694 c -0.23695,1.15021 -0.221318,2.3777 0.01964,3.62304 l 0.02894,0.14572 0.103354,-0.0279 2.703711,0.48628 c 0.29917,1.46982 0.868,2.83457 1.651061,4.04368 l -1.603518,2.28152 0.001,0.001 -0.107487,0.0646 0.07441,0.11885 c 0.624089,0.99479 1.485112,1.87036 2.52026,2.60346 l 0.121441,0.0868 0.05633,-0.0935 2.395201,-1.5875 c 1.194732,0.7829 2.536923,1.35366 3.969785,1.66294 l 0.515731,2.77193 h 0.0031 l -0.02894,0.12299 0.138493,0.0295 c 1.147731,0.24864 2.373717,0.2441 3.621484,0.0155 l 0.147794,-0.0269 -0.02739,-0.1049 0.531749,-2.79053 c 1.458415,-0.30131 2.812471,-0.86864 4.013192,-1.64693 l 2.35748,1.59267 0.0021,-0.002 0.06615,0.1049 0.117306,-0.0765 c 0.98248,-0.64331 1.842571,-1.52118 2.555401,-2.57039 l 0.0827,-0.1235 -0.093,-0.0537 -1.612312,-2.33268 c 0.757187,-1.15709 1.315212,-2.4521 1.629882,-3.83387 L 64.554,110.96448 v -0.002 l 0.12144,0.03 0.031,-0.13642 c 0.26059,-1.14508 0.27002,-2.3735 0.0548,-3.62355 l -0.0269,-0.1478 -0.10645,0.0263 -2.746088,-0.55294 c -0.28086,-1.44734 -0.823273,-2.79784 -1.576674,-4.00124 l 1.626254,-2.2443 -10e-4,-10e-4 0.10749,-0.063 -0.0724,-0.12093 c -0.609755,-1.00363 -1.457459,-1.891273 -2.482,-2.639112 l -0.120406,-0.08837 -0.05839,0.09405 -2.397786,1.539958 c -1.220102,-0.827343 -2.60214,-1.431347 -4.086572,-1.756605 l -0.465605,-2.746602 h -0.0031 l 0.03049,-0.120923 -0.135911,-0.03307 c -0.643239,-0.150323 -1.313386,-0.220572 -1.999361,-0.216524 z m 0.09974,9.9937 c 0.839637,0.0112 1.627074,0.24374 2.305286,0.64337 0,0 5.16e-4,0 5.16e-4,0 1.294561,0.76299 2.190752,2.13424 2.289265,3.73414 0.158403,2.57207 -1.795772,4.78221 -4.367176,4.94285 -0.0012,8e-5 -0.0029,4.4e-4 -0.0041,5.2e-4 -1.206166,0.0743 -2.332545,-0.31584 -3.20549,-1.01596 0,0 -5.16e-4,0 -5.16e-4,0 -0.116398,-0.0934 -0.227899,-0.19258 -0.334862,-0.29662 -0.106966,-0.10404 -0.209219,-0.21313 -0.305924,-0.32711 -0.62859,-0.7409 -1.031664,-1.68408 -1.096058,-2.72955 -0.02475,-0.40193 0.0023,-0.79525 0.07493,-1.17306 0,0 0,-5.1e-4 0,-5.1e-4 0.392531,-2.041 2.122953,-3.63554 4.294312,-3.76928 0.116091,-0.007 0.233547,-0.0103 0.34985,-0.009 z" /> From 76a661e4444aed56f71f572034751331a3c3921f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 30 Oct 2022 18:44:47 +0100 Subject: [PATCH 612/629] move logo, add function to auto-init the project logo --- build.gradle.kts | 3 +++ docs/media/img/kafkatorio-logo.png | Bin 0 -> 52828 bytes .../media/img}/kafkatorio-logo.svg | 0 .../kafkatorio/extensions/ideProjectLogo.kt | 21 ++++++++++++++++++ 4 files changed, 24 insertions(+) create mode 100644 docs/media/img/kafkatorio-logo.png rename {modules/events-mod/src/main/resources => docs/media/img}/kafkatorio-logo.svg (100%) create mode 100644 gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/extensions/ideProjectLogo.kt diff --git a/build.gradle.kts b/build.gradle.kts index 031cb4f..fc6db37 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,6 @@ import java.time.LocalDate import kafkatorio.extensions.excludeGeneratedGradleDsl +import kafkatorio.extensions.initIdeProjectLogo plugins { idea @@ -52,3 +53,5 @@ val runKafkatorio by tasks.registering { } apply(from = "$projectDir/kt52647.gradle.kts") + +initIdeProjectLogo() diff --git a/docs/media/img/kafkatorio-logo.png b/docs/media/img/kafkatorio-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..a37200e6995c6af2c45ff2670facd04b3d1542b7 GIT binary patch literal 52828 zcmY&=2RxST`~HKBY_j(#J5)xtj14GKlg%fTnR}D!J_>djQgQ09if8(_~7uq8K$n36e;%?x4$KA`?)eht3 zy1UuN24DVwI)Ak^%zUU9`BrKP$Q!`qfKjW;yB1vvr*ot^m$itJe}!##!H_& zv+GB54NqSBbk=YG?s+>$#}g-DW|CsjAfom54GB}?Q+~U@O(DfcIf?fz_vbimOV8=& z$BG1OUHcYlY&LOxu->CoNEtEL`Apcj)Qr2>vN7;*Z}Zv6ZctZkc`;!(VI2N*hRylG z663NAUD2+Tv$y_x@G{3)$vdm*4?W{WaZy({6wz@ArIr`BxF!9ryMu;KW2C~5*BEdDp9sNdvhX2KxB}(>kA6K1E2NTZ>iGG zl#WAHgo$UomOA?92PsAeixEtMr*wYm5gun#+(klmAHe#TVnIcJ8w~Obwbe_ zWVe^n6~53P1mh79kuzBpPEx$uoB!Nj^4xiC@UWp;dXqsvKvx*Rnn=^QRY78tR@L}s z*+NR;!>P}4tkNlgZOQ)4?`O9EelO6;RO}2getjj0M?Hpmb9uZm==kW5LQkI7b5Zje z!*cwNg3lHIaht{s4XnB6&7ilx+VxD|NTtJ2sd>rKvQFB?hkrhuOwJZ?Nb z+Fx!w7Cqd>r>nz%0zele+Gr-Cqlto)bj&tSdAR)g_wm$#GK*j2F|jC47n{7h-4;Xd z;br;bfp$>AvPJzg>DVxemjX&CEDsihJM9BZv$AD9o>-=THwqCJvN9qw`-T5>_-28UwGdKIPMXg&jM8Rs=;naSgMh2C27s4_^!PWw+@{j|M&rgVIxNJuptNk`CfUq6`_*L1hU-OR=<0` z%ez^5f3Vo7b>+ML=T$eb6ic^;qN7kKUt-m6_QLjNt42}^aJ?7aSw!)GE^(N?E)`&F zsM>3J3|TX}y-x(ajR8i-3j+4H{{8x>aY-wGV(5+O`#axQX2z$YQ?|kLwb)!Jks~bm zyZ!9!=PH0JWfK&N#>;}p6 zD?I<9%Ybihp{(&}Z$WHke8_!M`)Hf!y-QJ9_um?PE060r^}gLNj7o02y;-Rl#N3@J z{L3^qs;psezND-{zy7ujZ$!sg6*ClUdVM+Sk7FLrTYk?q?F=-oa+z!iCtFzl-7tOD z;#L=ZNmJYXOLW%u8Wca>3bOO|cTrfgIeW?n9_*}6wf8gUy{P*v++||E`O3p6F=FJw z$;ZYtjzg5w`y3aq=JHW-D*ErNWY3Q~BMZ0I^WTTYWw@E&9xdOtK@r{;VJKy;xz+nR zU%Mn{obUt+YW9ohqaqkl%KV5zx^Hc!>$#X^>CTbAECWj!Pn~bU*MBbuJ|xdg`=p7! z43%PtV=QUfEKR2sc6r*jV^Qym#3ikAt6f8yI#QC;KL#Fq5kcZkK0CTRy;lvyY(M&c z)}q${ux>dqa`<Fqp>0qUmO6kgW_`s->W2wKtjV2!bSqrn22H&>hFJDn4 zFQr}ReVy=ng;(u`gw)QP$pQ*P0p~M^cN9Ht!)NoIPxg0bgYTqRnwXvvHG1t@s5_rhmerIeJ;`I4xG1P% zYT|NdtPYKhs?EaK4_6BWrMI5)>pTBBgn9hp4F_imvlD-Rw%(037|P8(*uDj}weY{ph0TQ_Xri63RLOCyPFi2)LXjyWC)xmYxnG!N&ws)It>?7P^oh3~Kb9FbpI8xzf8#8ezu=RfKO6kyTJ^+ezNV2^Ao zvYE#B0KBpR;Aw3RX-TJ2Q0oDx!C3#{$gj^|B1$@ZezYR*#>C$JKNnq^qG)(8$1-If z>?6Td_{JNiJ`fjuavM`V+me|Tw=%s`4ZM=qL?K0KEV)x!!_4<1_65(yy?*c*{0esV zBVOq}eNdo1bTl$SwKT;bI&A&&Kf>(!u=&IsPDr~2tP&CR_} zfjgWbU*sb|T}0j5w z5}8>tZnIxsUby?U{HpO~Zxk2%yv75zN4>`B59<7P(U8F}>ki`hhsNSu)Cjx8ww}SK zs+Ab@wbR~3wp{+Tm!a2Ff20dN`Y3gdLV9cR4@^(CJKISQLgWBauZREr_0f5}A%H>& zkGJ~0oj)e{xulV!zQ;ejmJt*;Uj!#LavWzWm|UTMn&~}BK@GUdmztm@G`1rFo~Ia% znj@8G40~sDCiliL+?Amz{!dHqeJAIyz5L^z!40cU9@b*n!Fx-qopJeBdjN)xWJgMU zndP3`>mOE0PeU;<-c7FLh|N2dG^yj5^StzgqPQ4CH3CB3YUS25Vg6*Tr#N2mR6Z5m zyYsW$x;290LMWd(4UFI1ddes;5;q6)&AMAsCG<83i}Z^0^E96cWph1Soq28W-<89NBO4q$AiT%d@?cn@eWO!2nYde9(?P5{+4y1dhWQ#VqQ)S3^6R0sJpiAjIu(f1AGsBu+-sJLQHfDiUvRTik@XJU9RGTuZKYOeRJm`eAUQ`plidEGA*AzyI}muPw@YE`eb1w`!r{-3|NTm zuNTN!n6CWo^BB?|s#A-mJ)@b-B@5n)f8$vGcleaOgi~*6eJQEQ z{g5YkHA~8B$kQ|`HWd8sCl+_g5(2Ea&}B*c_j+TjJbO6)jw^I8NYq36KCe9z4g&)w8lfY5B(=Gi#L9Dl5{aC zJp*=t(>e1O!!?l{lxZxz^t;+E(xF6fx&TWQXX^E@3ayJ4hVp_0)ZWB&Eq_^deDf2~ zU>ZAH6fce_RhVjCy@;XuI1CbGY9XYYqB}BT(ua`BmHhoC_`;l#J>uxzZ-A%@Bzw?2 zSM&G-5Ea947ELUnnGP&_3`CTw(wZ}hkcCBSrihqU*j{ZLzXga-Nw}fV8>C{G>3pWf z0q|$;eIAN4dT4syS`>UloScyQMQ@r;y=7)@YA!rGwL1H;;{-~vCGOGcAwdhdZihMw z$i5l%>`@f%40(B?VCep$8f}feY%LH`nsvLLiu~IL3ibu;WhbWF3dHzVUP#@s!3G`e z&SeH2otz;McYhj@;D(P;mA1YN*3XrHWmEGgVqyrauzVC6m9_;55trY*t1NPSfp<*Q z<-n6&_RbI7yVHGu=wyl>ZEkLIuvvw&-)JhzyFwHizbqchhbqKc<2xSXE6MsSjEnovbOFm>s(ij9mAm z@cAnSjuS40gb_~t5j}pbL3@7-G6VNcQkc7=kVpzcK|szPQOdn2q4yy3zP^!&s`l;q zc{(;Wou*!j`&{~E!FAttM>AT{gw&mObpTXqwJfF0rjSELy+Tv!J%jJk?%pAUEDvGy zDLIyNq%bo81$P7{XOlvzBLMZp?%CF-aySH`iigM?vOkx~tm(7R+#Nz>w~kE-rdlJMhcBw}o|m z^q(md6wj6FoZgaK3S?9?JWUWVqFd|F{sW)2|D{Dyeg(d;iQ0>8@Tmlby zHrLhuv@x7=ATKJKyk&}l23J?B0lwlZLEdae!On5VeV`nPa_E&u_)#tSyn*{(4U$j+ zOE<#zOPX{qC?aZ?iq}Aj;Jkmt2J*rDv)RVEO`98QStz)Y%Z7y%YL<#uAqAwaLltkr zY_)zn+X;n@;82Y6HB=tRxRrmSmVK3m)J1|a}C zlLfo#nm3JGTr6I&5C{nAa-sFH?4Yuqx0u1|ncjSt6Jg^%C|!HoK?L(BcZ6Xmv{7HL z?^&vdb3k|qL6)4v`?Ao+#0wjifqIqUll4m&Oc6_6`PaDb4!)rT@(+OCqD`pOUL=`S zD_Y;8dRE-!-7wtzbU{v765*z*4g|XG=3gVFCbt|-_lEC^yN_mlb$oBAB7|pPxD~KZ zD!5S5+N9)IzGl7z31ey@Agdnz2Z|{GExR`AJ$gtzkBAm0IUIw1nzNgKE|k%#M`k;e zbkszcUlp9MXr9Pk%+&V`w{iCau+7T(a-k^h%MvKP%##^)zxN`-6H<)av!(XyPAcva zar!bmMJ28iLBWdbY;lU3C2WP(d$KYTk)D^R6ob@-6nY>@ij_v>gau8_pa}QJ^gqho zEFSeBKAuGc4}{_x9qxDjmT_aDMv-;6?gKtRZW^X$iRB@D16o*+1=cL3Fv%=xCjDGboaqafeBKgQ~nsxTq<^7ZaTQ z_zKK}R}B#+kB|}j`C(Q0Ss+N7je5*rK4Y=?M^r$zb7Ip2Y2d?B`#i4T)dSkk(%a)| zJgZkW?o2f?Sl{8UZz#0gdKBsir9@Fs&Je01&*xD^)ocWjCZ(bsmMOR73Q*KyHZsUo z|Aq)P^%{K|L}BFH^Xw@K8{gdkcyT9H`K~L-qtNBF#`3hzHKA(iGmUI1WjqE^vnm(s zzh|jBS?ysZTC%t72P&I{(BmFNa+r<^QuYu@BrN70d?!;&`{Y%~g~dN;<%3jJw0vZ( z0MWMr481&~W>f@fu3Ir)SB)TNK5u)ane+g++gogz_I*#0Z7H-585{QH$ua|>bb0I~ zML!IW*Xfv16g5a2T%&a$x-%-d*y%=)RoWsL#($VB$jJH?NCAg@dB3Hphu3oTn`Eps9eYga)9pmr{NlwJI`%FH<+I+EA$Px5 z8vS0M>&a9Kve>2|-V}@{Aec%3BiE2>LES_9{`MkZVL38j}@iUg_HVhyAhXFMn=!HvLS7_1r0K}N{Ftcd$fAp5o zPikk}eODQWf5_Cy?u*qE`cDiQ~=YogMFM)iSFE)S79HCFx5ZIM4-(M(?WI?F@8)aly=IVKPQB*d@!&-tIKf-C64HbANTSqMKB62#S^_@T1f1Qsa2cLjx zuaVlJOJEAF;i~Pwu=+vXARGZ9TTF9rbNggr&ME%uNJAs%Xi0c0JM934e-7w`xL@7w z;bcH@c^VM3c;DAzE*$2k-T&P+AJ1_4G%{cEHC0q>q3tt@;!IBXa9>PhwJcJw6bxr;+Jk|=}yDQ(u=8>cG1jf-rRD7>)Nb!u&z?6$?(a-@)a-U$LDL7IV!q^ zH5b)A7P>AoK#PQvBe6hSRY3Hnw7DA!a-EIKpfuwdqgEc%U_0ha3RjF9X7vSXN$}qu z#m514p16XmaNt4I!7(W8%tjk6K^p!`5EhXw9MU@fie;@`XLw?`DCei9bK%5Ow%0W6 zj^{2Lld1Yx(vv9`l+K^KVUSv)yeKJ9qgh^(59CqmsgjBL41>AxX!Y8S*}Bw*Sh!(4wN?I?eDe6blW_NeOfpfH+S~i!`;IepfvdchBNWbFO1F zH|RP0ruWUy{Qmc*u#pfA9_9i0P^+%A3OPA@)Xj5od0It9&G+^LM_6ir;7hNkf+BR+ zee|KzNhbP5;|aj(>(AE{85&#tU}vI#3D8085t2jjY-JS%w=b;dDYn_z6q%L#LZaB< z6^Dihvk(-=*1tQ|K#B>fmjBAi%4W=@0hnYloMi&8x2`ffD*VN=z6;fF z=?yXEc_w;JiP$-Ik{fS1Px==(qgNXF;Is1{*F5f~{akhwqKIpzU}-mO3t??SWtEFA z$_EQjOW*8lY=1wbAJ((Fz;fdO(?vRSL$nvUJf@HXBZox?XQ>P1?SC@wOf{YISInS@ zrbxeAmZv{CGj16um3}9 z33I|u^9xK51>$>1_QSAJZH_)o%>k*zZC@TquTgI#Do%3{3#f7 zucwBtb}>*%8K;He`O+{Roq3rVqNX8=OO3R==MxfD!WvA$kh=uYkmrpTLyvvZ%|_?u zJnnCeb&9?S_Q6*_Zh{>0NQpUj#+9D6IGcqu-scC}^VCkw@wdhXM@40z{PwTGr1NfJ z`saxMC@7E;|8xdG|8TG?+SZxtaX9kxs69Xe<&6$GlZpCYdmIZ6EL9=WUk3mgeWeDA zRsmx-;w}eSDKo`K6)*^58$z1i)W2kvNEsq0$dt7qNJ+TS>6Bb4=>l7^)6&5?4sB4{ zR~rE0@4n{pZq_s=Mid`(U9&<~=|sfE`a#;J4=U~LwE-L~G30h!x(9`?)vW3JYWx3r z0lq=T_V&_H`m>gwLr*KiTR96rcqQ#}((hsvEdyd3ouR+`u#us=z$09BqgoxZu*Y_h z@pTUVSs4CwEtIuYiH{?O28Xji*Y#}pRq+h-=U&op1RqrSE8LieYN7g$1uE+r6|3PA zQFfZR)UoZ*;k=RQ&5xpVW8yXk{on#$2?(Je-6j0=x1!6WdMzv`Xg9B-tfjZI^#_U@ zt8+L}ZS7=Xgl}ZVG%&9F*b2O(wPT zv3YqS-+GYpHP)z}j+_Hi#C)-g>?H9sGQkTrO!An|w`CQKBe9G=a-t82f>e%wNv@!KbPM@JPK z?|XEa5nl&3e!$SQvm5hVR6WE0Nwu5ZJ*QHUnQBGY+aF-+zuRMbZ>TgvUtb}i*LnPN z2jcSx-hDV5E3&yEasCpg^!1dZy^`$ri8eGKmGL3-gq*dSRMN$A?~~vMyN-6;{yUz&DRJz5)+*AL3y!QLWqKLC1&N zWlCnRp*Av7#OT=UWkhJVLX4c3`=%yp+!(Gn(}z|Ew{^}USEbs@>!*122ug4BOHLJr z9>;O_No#f-CZY%lFqoznP>Rwykv&9F>($loH2Q(g-P2U>L*ai3pYZA~0O-*mZ}oz& z=A_%V3saK!3k9+Mv9X6L4i|hdmJgMK4uG_~$=C;bCu;7Hf6oL7Rk8-^g!(M2rg4OV4I22fPqEze>{O1+@bFrx|`3m;JcWvFnX_#KuI+ z;Zq_sP2O|*8$$Mwrc;LoCU|Fh76t9@9*X;ZlFrViH?u?2vZz?||DKU4^g`QB9`ldz z36AeTaz@vETmaw@Gzwd6(H)@S6I}?r4HA7vHLzyQJSG_e!Z-c*5`5MT^y=QJ+F*ix zaJu0sA75YJ`^!#zGP|wGa?7vw*L61ciN+A90oHv^fQu_Efn5<%dYR?a4lKRzr)qox zd-8`Gjv;Y*2LiN=>xX9s!7$D%1Y<>%1#tQ}Wbm#p#)4^*@AW)2 z8kxy=x|XW>m;C74nz}NekRbybpk%3=7!0*%_`g^Y zL4(VqoE7}+n5aiZ_u^N~;dY^W^I~=c&(OF-W_$^FVgd%lFkhoV7t};=ibmEs=q{BD z(@TPXQIApZvOxBk#92&waXBz90fj~b#ws4kuc(1Q4Qg^{Pp~sFSqOW2pimDiBwbb) zMEf{@+LAaiS-E9<+hn|5!7u8dfrHvr8*q$O8ndg&4!n$Q;##@6hik4LXNYi$A>9cw7zqA) zOaLulQl(Xicv(e~ZgFG__EETRLgF5k57wdKfF- zXVAfFJLll`o7b^WfX)Hk?{g~0%WZn&Q1hf8xPalpQoCpIH|#IfE;sDQ3!u7)yqRnd zZj;kgqAmBw3@uOaIEiaf_eY6w-g+Hdn+ueqHR|y(p_G@1iFkmojLF(#Fc0nbEc`e# z^3Dd`6N#J{*IfxS` zfm11?19Wv+b_uz#O;IMG_ofvs1$gM?>B!=ab}g!tD9-)PI8pQzaFXkEKr&NK2EHQU zX&YA*6-!G!>_!b`HCE0ig0l#|NhL;8M2@Zu+eS@?zZ}|B33kUt0v4Q zVRFK1!2Z9FRLx zol>ps%#>fOaErrcfPM z=y}iXFTU?l++V!F{TBL=!V3ezv(D&{_ORwQ{veYm{cP=A?IRQ?rc;aXFA-y+h@35^ zw1bKO2pii|TVDTH{jCLsiVKqgbZF3y!Ud=XT9pea8=gbLvK;N!fj%b*ko$m{c$$Vb z_lDocDBySMP_Sxtc>MF8g+{Tm&Bp(FwjTq78&@%Ozv+o_V=N*tN>%2|M}ce-kIbKh z>Rf<*@_D77@gQ?OJsPUm-5En;a``XO0IneaI5}NdNvRy-(nY<5(8>*IIRX_Sm_#bRtbY^ZlGn zgz_K!xCs$uO&7Xzu_TJxu+w(t#7tsMg6r6#6c9}!a}UVl&NG&Og)HXU09^Sz<7li~ zp{cT-i{OZot5Cw(hk}k_Xyt){HaXI81%T@&X!Q!y2PJG%Lz#+L4XQCLYgA~|JN+i4 zrWOUS5;@G|CfpfR?iToy69W1#Wr>a>wx7J1e?o!88um3v`f$94N9lDZvY-%Gm-YbK zQcaf=K5oEy@}LO9JG%X6efsyLxU@e&6e#CabbGkbfQ`2|qCn|RP}Y{fB8eJ*W5Qlv zA+)H_`;V{3;JA*?s+bLsx?DA=eUi^#IKduDIS}lX`kqV&<9-Q>nc5qO6&W>o{xKgi zxx<#+occ=y6fy5!(xKPK6kYP$Y8J>$SsYQ?(C=`S4k$ZVX7`<5gVAsR3 zVY8#RcI73!5eBQPXLpZ(-C@w`u!AD+o*^!_F`C) z?%O%#!CKlKI0x+dDOWylpG|6NpTjrz{7HqmJdD>wGAc3oO(KGl^NR>5KnIpT$L5LOaVPqF*Bs2db6z`^yJu&*# zipr`Hy2730d%p4R0?XTZb=e*d)YHU&ojMM-QD+SjVt^;=Va^K_On>E#VcYCYUBI6R z{UblvwkJ%2rH^-yB~&C|?x&pj4*)0d>0w8`IW9Z$Y7SXZbr6-2XFQHfpqtqA+KA>E;uo z4%p&Zp#f=zS;zz9>`{H6n2OIA-pFX^rzi-ecwhXFe~z==S$ar;pW2-SY5w3G-6r3O zl%KPg!d|T=b)afoZ(KNHq(|NK{PT!=8{w6D34pi~$+u`x6sTo4= zBd-$r`MG!yMS> z0($d%Lm|b9w1>9k3*-JPh%;z&^9*#|KE9@5RR<6S`0n{nr$o&4aQulKYQ*!$iXeuC z+M{IYZcj=EwZQ!XpZDy}4Fu@Vpk^Q2kU(7-ZgaHimr=0vtgmwrES2LNGXg_k*k$+$ z7S?|ke!F42jO!ugxJ`UMB0^)sL?{fc?52A+o%~OnrHR}?;huw<^6w9JZagx}fOXnS zd(?cJB9fFLKH*(_@1(3hB_3vjXunF@gZu8z&zBAFK-Q;|SE+F6DrovpuFQbJY_#Dr zP~fsTq!u&^@X7u$Hx4Yra}Lx37EHB(uq*;h@Rk2*75ga26uZC0L3izygN06=FCZU{ z6hxo7|t?gw^+<>((8uFdisc0zFrSe^o{Sk?O0o7SW&QJvLq4jB;xI_DlbVT zye5=-*Yu~%-pkSn0~Y_0kh=mKZE!I@-it!Hu{{ZAnEv#Hn$QYM!$A>==fo-CXgQ-6 zX>fwGgq#e;g#*9U0l7v-4V~YR1?eh%BV@Zpz=s$A_9|J%{S?k@*Ip*@tz_0}T?QNW z#-C_ByEVp6x9>joeULU2jr^o0D|?o$r{` zfx|^iyV*sF7a9+@emOTDUZw+udep)B-90WX@fpfk)@#+NQse&X-=xR=Re{W!Y`eGI zrFDvJ+=3YxVHyuqK7g*{$Cih&MIJxJRgm(W9InrTS&H<5zhH)h{ZV{wu}b$fFtig* z?Hb#APK8+ZG$1f>g-~-4V{$SWy*Q35YxKawBi92P?Z2b($I>3}5}ZK0k8`H+*8g8w zP9C#uYJRW0YY>?b^2K@W{0~n7Fw( zNYYHC{@o-A8uWY}R2~#Jk`&&Fvm*vkq=kg@w@a*@6+jV%g>6g5N2%-Y;nO6XXn-H6L&__wJOM)qFckdH+R1RdSL11x z8%2uPtO|8Qu+Su?c8HJRMI%f!*giXnunoh`GXmwMXq@b|Dqa6j!NBkx#Z0sII6jq* z2hb*zg}G;FKIX*SDfG3n5Ann0DcrQdsF&4_^Y!Yf*I0Qa`3O9#z|eSmhlyM@z;3n5 zRE;6OVNndi`FszV#pgcOO?34{mCq?4nskWv!--rR=rBsK+0%LU8dTtGJXFEoq;6U=;4LaGf<^$!@7G8Hcj zZ=g{ArELv;FRU<;-?Xhdu;pArUCFop6Pag3SRj%sE-W&&=}v0Lr9(IITPrpfWLy({ zQAASLz@DsyJYn|g3-5GU3C@LF=&X2Dox;JRHb?ikxI z-%=|++|f1)x(I7V>TtB0f0Ts@CI>gXJ#@8*`)Bdyr`?OMaL!veaJ5E^aSJ`XYI_Go zv4YC6$?0*O_ptfTJJsAcX(bSIc`V=c`psXIG5(4xn{aMM&U(2Ss!fr;guyaRo@J$p zT_+JK=anLcI01?9OnPg{Np%Et>MB^^$21TpWoaj#TVK{^)w{s9C4mckFf!~M2T@!P zDY@|(t%$}fypO>Ui#*dNDaK9tmuG3>L6z!vvN%qVF4d6agt&`Ok`no|DHe2JGXHcN zGQ86_!T6tW)EdBtMo6UIYHdKS`cVzo%F456hqS=x3}Z{BYb0UqFrK(2j(<3^-x;mu z<;PBa{?cz5G`R5uNO7KTsDls>LRKjO({AMvYSZUbG`oW2rU#wK5Lko1PY(KY^nxaD zaX2^-mb?r)Jfr0>*uT-gNTQlXOsK4o2Fvp`U^f~(R%m&Kk8uyL@{9h@@o8SbzEJh_ z`@0o}`&IggYKQd6--%aZf<-64ok3N+z=JC4#zUM@Dt{UmkD6)XaaHf#%z&-oyP4da zc$ks*&`?1OuhaUr`DXta)4f6C<9`B$Tdf)iwng5*#$94hA}t@m7Cr6~Kp*Jel?86S z5pnESJ32+r-evekK&y?6s@Z@tZ4Amgg(OJZB$jMzrNcL$m77ysIVrJ3M&)@Vfz161 z*&-HD)iS6-xrrHP&x?;iyE5V~z5Je8dABU;67!11d>pWQo1=0Zcf0!UeESqgKlary z2h0=DvGutbig|uQ`a>9d0#4zxxU@4L?-ZWKn7w9v`SG z<@UB4C`vJMh-&R#WJkV_i*I}BOMj(p zvSMJ2CZ zY_k>eVoYnZ?Che5*5>l>-^!_fo;r>pWBleDIog!^N7YAE3qQYd&6io!!(I zn;5TwO_lo6e{^_`7X9vcbaovPjHr^putz1=PE82=VEHk_TMevT*Suy2BVyjOYQ_h5 zeJTqm4D>vmz`}XP6`@^shUqgOoiJ)F%E@v|GhY1(=NkXlOEIKIpX^o8xaZM>=I}FH zgJeOyf0OC##zoftCNv&fq!68m+O!AC_uA>COcb0#$Wp?5&w}nIZeLh`00X2Ur=@V% zVU3Ib)<_6|8>g?N)~Ehh|GbJlnEONQ*V zsX?1O=^70tOQG)85p?CyE)>^&JgZ_ zl><9FL25{&_EVVj_vlt6XBtM`5R!goQC;z$im3ZZSJ$drnBazqsnhfN&@prh$_h51 z!)gYJ?rrn9+>eJka$Czvi2JO*4Q+BD875}*6rQr=78tG$+zi@=B<>Wwpgt-YfHx># zaNVlqp={~*=H6Y6%f5UC6LkspVz0SF0(mcxJ)R!9mo+MBA9D*&Ch~~nZrDRN;-l}Bb-Q0-BLhb?>Eb;EO74Q0@+38&?F{b) zm7yK7vp17F+E9cGoJOIxy9^8EC|m&@+Kz33?qI-NM>UWT8U~k!5mTZ4=ggo$YIjPK zf+J6^Yucg5XTT+yubkLHm6*j0Y>>6}+&6pFgF0Fx*@yFVp85u5s?c7+n)vL=qCF^i zr{RiU8pTY+Y>JGvBs>3@I`|1AMKn}Q9TA%SH3Y_smxWLP?A;J5DhfAA89Wr!czJH% z%E>Ea40kea8czoW6DG=quC+KVu8?GmCnPxE1ZDz(go3ZNi_mF_vw85#=+= z9}k1Q)GG`&^ch>W9f?J23V*YvnMoT*B#gj$Y~o90ur5oQoS1_2lvV+D9y+Le=o~$* zbzC7`I=6Nb<97Lb$or8{3v?u>Erz?bx&7Rr_QSmqvR>$`%jUqd>IM$dXxjN>%BTLy zhOhs~Bo4hk-kC~JI@$>XxDMZ`R!$fQ=waPnlG7`ZY~t z%;OZWT}O=o4chOpaR`{0Y99F#q8hwH?sAbQ<;NP>IbK*&gas#u9;}-38@H#l(R6-^ zIH#pyWE;pv967*A{4=QoTKJE9P61)>ZR5VW8Vc;Of+~O>B35@cd$O+R!NICLM#DTX zD8D7~`>+7CRwZ(9j`HnoXqsAhl)O#qGJ>9!630Tb3zVBv9x$FGRTQEYHxWMoAU(3Q ztgU}`vbfq)fQj-wE~(JsnxTask+KahQMHeyG@Eer_vHG@+T5Q!S2HAqT_V2BCxF?d zLT>;s5wAOv)RF(mft~cTJ3&Q`PY_m#d|RfnMb(U#vCV5ICc2s0Y=vKVNIPCRCl>lY z)j$<7)^hB#U7P*G^$?go$)AhCC;M@7sZ3yeSO=k}{>?J(D_1A=`K(}{b5E|@4!e>A zO(!u&8q>IX!KJ$n$|?+@y~xi$!EUb(8!sit`xUD6l=(RhEWmkcbJ%zno=`H+j8T?( z;Y$2xgPekH)?i4bi=8+?>>SK(ITqma_FRLm+r36Hva@8%Ff^C#ZsM9L3(PUF)L=u( zpe)(&DpSKv;{T~bID-c-L386npvv$;50Ui2`U;C1TrAfOVG5)^MEq8W>FOi(mLxw4 z4Sb?q>u+oZ|1dAapqD}o_8^OoDIKuNh7EAo`;~woiZ3fYtttUfjMh{-Mvo~$%uNHl znBYCDPWGry7+ajHBt2}xHD+;{9f=LdbE3`0jRh+fYQpmPG19|8s`gJ+@c5e~s^ULD zbq@9yXMp9}*~#Q^K2s_Gww9Z|Z- zw}hE|K*-WYy0jXa{+&F)`SlbFWqEq}vlSB`Vf7sqjx3s{sKm_s8dW_yt?V4#1<-ko zznc>aJnc%BOw7da01$IX2Wo1?{74N42SuMRfXNkKwP|37i&{g3S}yCGfIVvEfH4x0 z$z$~xIwbp(tZC55-?p(1f<5dgL%tybbqf{cdkzHUX18j zUVlQE`5Y3$!EYaPcVO?dC?oSgu3N)#a-m~iSl2Mqv}xvfTEott$6^gT_?w76A97-n zs2H8q)_TsT32J3yMcSE&q2G@zjt=Rqaf2u--MrRzD&4yRnPnn%@;P@eQ37)^|NrW6 zsED&>PYK=_kPW2Vb#+2#XZWxY zSksk&XD4O+{*!~e{_97@cS;0c9T$Y|=G(u|JJ_z`U>SKP_8rLcELp(%abo342cXY! z0&v=JCv9lJN6i)_7fanH6KZ()L^Ko&UT-)2rm@y>hhEcUuG6pw(rMlW*F=sQ9FicP zr|J3aLLB*=r)rF8;Z7Hv!X}*|bGMc5z|SIsv(YEApKvBc0tH5ZBYLg+!Im8x=m4r3 zqP;_Up~42{t0GmrEj?{>u`m&w;C{||&y83^ug?33WA1swxYqni(Mbk(n{iv5Zb;ft z)As5QG14;J;9K-Jiwuij=`b?Fb-S!jgS?XVX5Vdz7fi*!o=D9IH#64|hn(z{I6ltZ z-S+E)T`_tp5z_Z+8JAa)_B846;d6jKJY^pOr1yxAo2#AjTY|!fY2Cu=9cjee)9cL=^aDJ0wpA!q6T+y%w;o!Lo(44o3&i%wP^ImlS^O93NkURKZm^m`{_@x*6 ztZ%<(YAwAZbGUrvTJ$l|7JGsM3sW}IW3VuVE`*0~w2Y?NCBL*@V1*~0bcm54Jpe4z z*!1Uk+u$lNRus$JLF|TSfV^!VaHK?0=VT1R`93w6$|EK^|AQm!yl}+`d9!Jc(1a>MJuJFJAhoxWvo6wuo7K!<9@zOz0y$+wdM=I{fyxFrpg06 z5*g&_VI<%B(Q2InDhcWm$NM{qh?e-+jvHvS;i4mvIF}F4X%JXwFx}j5x zgCl#MOi|Gj4#8>`uw5Mg2aI>RV%qd-w+No#rd@cTCc`HS4-v}SuLDC-e;y^CuPc#} zK#`0^^97PLzLv?Oeg>CGl^ldhqkNkB$hmNI6wc$E(}N?XOG|L@>Jc*;;!qRk1xGJ* z&{$971|~EuJD#oL%s!iN&Y)%g5DF*n|EBOKU{Z0zmnx#q=1%!_%78jiU)Er_Gv^Hj zoFuXjLe_$PGdM2d7r%r*H2PKS)+uRB{n^e$&mA#+f33jG=R_Jf$BqARF2zzsPcm&D z96FWCf8YfDh|jzI>VrTlo7&xt&|pcK|9{K_=46F6)g)@yP8DmB-8PP1#7u}x2%nk~ zOMqt477`6x&dbvx(`!K&7Tqkz6=(4f+inz`X$#<*o^Rpx9Q%~_;B}reZY;>!_P&sc z)0-8G6Sn{+olB+H{OJET<+U4uv=cKYpsR-KKFq91oFgr%Dc;gb&Z0nBUjKf)zC!m8 zHhvzjo%0Smt--sP2)J6a1@UH z#68`A8jWu zRTDfTAxH6umtOTLn4J>5_QkF4p~qz94cNI#(@7Dkd-)HZR)JU&VtYdvKA?vS)_PLA z7Bz={ZErIS@6mRPR4!Io0)!F69hr!vs@_+SHfLhte>DQH(ECJ+#;k0kcs^Er&&ONZ z6AZOV=v_e(wVPZ3MYxF&-IuvcXyw4Yc;OJ1rpkd#WQ)Cd&|S(61H;Eh-yG|HnciP1 zb+nL0&($O$p;p`m1e6;$8cNuF!N_~IZD9Nq!ks9qp*|T6)p$|Fsk;W(GmQt_j{O1M zxapRk>SYg3-^86s24s-7ml+f9S{ZFtKM*6Itc5oeGFSFpJa;mkGY<26DeU>5+EJYP zhKvp)O}Bjh6?9y_+?rsX3@Ml-;aMA(6)~f|FhtWrt;0y9g8i88XfJgwe$q757ahHwG&Jc&GmkxGl<^89dU88_9LWSm5rj#{kMr_ zA%7B@kK?&WDIeK3DE-Q5&nCofauLS(@MAaPa&Q`03f&#Hi$*8fC8{7%BqNnd=%8=b zB7q~mp*GCOgPdptCy~53_j&&SHv-m&jxb+)nNz#JBICGQH75VwT8N$Jooqzimv6e| z7--U?BX{Cex;@)tYUKzj*r+?ecYEz$W~4dq`#A+qlGh^G>)@0iK~;CSA#wuoHk*=b zUp|CK10aqJ*Nt-)VS|;4!eO}`tLwNlJ!=r;UHsy%IQiLW@&sG@lYC?!b9!V*;(w+= zKTk|S_ggr1?g`e$brKom8PbbOarQ#Pj1umcP2tfwa&QzQ?TKzf_KNB^(jVVt?T(eac%+(8yaz0=%}3#P2ib ziFj70t*?AWk)p*dyq7abQ-pAS)DKl)qgmy^eW<-U+rt^SGa1Pl*lT$>YvYI3aU&1F zP-7fzY4H8eUQ!H{APQeuCIS}4{V_xoKR`(y;hKo(M+d<@}^Q6UW$43Ts{r9MArj5|qU zU686sr*iEM+B{{qvMr^BH85QgXu+lLKGOnH$fJ!62S_v{M$t<3i4CO5PsZFRkn;vQ z61it@iOLV&f*ew7u9|%29tBV+h(fgwSUq)-`WErT>iy(>Hel7`FcCHxaB=nq)Q6Gp z_V!W)-oCGJ^PWwg`wL^Lo@fkIwS-@<%j2feItfv~-$h8{`h7B>$Nc0>P85tk#yfriC}mU>Jlk}9rKef3BIG`9Os)f=iYM5wkZ;8j8RkMY zQ5E@2NJzQO<(uq##qlh{F)k4!6N-@Mm`;ZkU-`Ggg1#k&h6Wt0F~iMiI0J_-G;pt# z$0=~cM!12iL@EqwykLSdHrv`IBYlAX{X0~}I*5&;<53_{3Eigz(DnObGLyieWga(0 z#LEfpDIP8|$?E`NL#ngQp5+nMB^%(Rw1SE?;-rKptKxU6(}3yKiD35(XrU)V42{Tq z4O>w)wF0!L>Wap^fJGGYI`p($aVre&rlZA}VPPV&8sPI+*%iMB(ErO}0vLE7A$H7A z%F|(>Yo6zxF^8W2g-nX+iCzP9)fnXK$c@x|0UH^4+h#bAj!nZ1Em+HZ^+`Uc&i%n2 zuNJ(Q2E17!^>ct3Y4T_S=cQEU8l1o4eg)3pam(BGhZjJ(NQB;GCp@hUrhZuEs=)(V zt@maoz|mDgqjP@X2-E~?F?46zn!;xI>wSO!uc9E!4sERcA6M@kPv!gnf!~Kh%3g(R z85NpF%Aq5nvePiyDaoD@LK$U6Nq8ncGosAwaenu?UYGCV_xs)d zru&?8kL!B9p6k^HW#UZjH|RC^Fo5^qIs-@R)q{X#T>^Xaw$u$wlZsqSqxfgVa=_>p z1!k>t3(PdF>0U`X)TLEZ+CA6~P(G%xhIx=nq6y?>(9WZyyr%+sQ<@@A>MBw6n(h2I z>CcS7SeVoNE>B*^Lv_qB;((dm3{4Q>8q)!LtMM6~1kH}ZSy*)TK5Wft2c6)&&INA? z)8jJ>JaeLdjZQ{zC~XVLwY;%z=Skx)Qzz04{X<8epB8)lB;wDz1JyML{I^mT z7i87Uf~<-6oi?m97o;~t(TCTKqsTlBQ-`mD^E(nMan}x*mEvZb`}Z?ES%B+d* zQ$>rg{I_D&!I|E%hdE=85GJ(P$h#J^Z0;LYwcH+0`ovMxuk^;A<=H!qhQ(ZO z?}igKx}=?vuMsxjD`Vj&k+y`>wiQAOBLgLwp>7Qs5iZB2oibD|%5KCG-1m2k7s$BU zZChHzK%iZG8WenchhiMFt9 zW0MHd?i%VP$;EU$7CU!pi9_ApuRfnFn!W^9=(xViZ%9trZ>fFjszMqh{`t>p4CeNJ zi0My082i2vlw+MbJGq4pZMgAh*VH7|w2TI3gDgC;4=~B5qOR(X zWW`E;sn}KfXkAEFeQm~6IAzseAT#3^h9Ik*OWLj1@ML-m*S1hZ!{1^aEHFZU)l&KWU{1 zrL*LfnS@fFXFU5Hgv_jI`ccVKmmb0|;7lMCV2`P4?z>xGd~$EnKS4BIxyp&o2$OV= z;S3ybvTvreBJZg~9VNqy8D}k`!n+=M!n-qLIy+l_`rkW&KG)Q5$N)XVF^UL%w7d8^ zUbp@Pg29$+c4>Cq^WpYWfjY*_nLM3Qoz#fjx~WOF>$0vVOQl6Y=@^lXB=(*i^N&9- z9dR@Xg>ENj&P4m=liV$T!kl(hJo2ejkE4v!uPGD0ohQwqkN7WV)zyq8GX2p4SB5jT zg4eTYR=g$1B}scIrshXh7N=c}b&Kar(UT_yud`|&^vEr00X}dBmU343a^^&d$#?`E z>-w38tYYP%wxNvycbpa-{Loqp$fMFU^ZZVgWhQis2~8mYP*VQz4-RvE1`_M8|8}m< zgp>ahCGYRquVrITY)i^!5b3mB#4d4KCZITIbVvW3?-biR2r+SwewO?BQM=exoYXQ= zTYLMF;>Ug-!`DTwA$DI?T*w78{Vl>|Y(kf-s$T`kqna5A*6pWm-YxQg{;XWZb8f+> zVP&rxP}z$jmjN+iJ+&EBgZ>JemKc0B>}heyqYd*^N>fltQP zA$C8q>=^x#RUN1@vol)T^cR{bo0&MZNpaT??ix@px$K~m7?a`}eS^OH#nqS8x0!pe z)~NHh1U18JQZ611$~&=MSyJ#9bPP6zIL3hD$BBE;%ir!4^MLU8y9$nA*{PgT(hkflXI>nXqQS#UBBhxc;Ew0ITK9r{RQMj;CBKNN2zdI0MLozHKu8Hd zGg2DsZes>WOGpD_4&s3$FBD@dN$;Hp<;CJe)neKE=f4^yGvBX@0u-H)pYqpRMsU5#{jVT^wd-CKZ| zFMcRdl?FY1f0*lUKv+<@Z#Ww%1`m~cs@i+G_yy<;9@P$nckPKJ?>>=ED{wr_uOD+) zL|D@R3F)gBe1(1rl*Qg&U6;-pv}X?hIn{0Ho9xkXSGpC7@a2rxz&6K0)~@b|?LhqS z#XhK`UJmcj{qKmmIFWEOn|Y|j1v8H~`L@H_O408d6YsB0g}?OFd*l}Pt=X^JZwLU$ z@H}QD^Q_mWiw2?GgeeV(hqir}yV45ZSl_T2=+~QLiwNvF=?)dDX#X-23JOZVR@l1< z!o7CZ|2C?6zS$|-A|O+;XBg6t?M+R>Np$kpIWWZPZ%=q3E%JW5Oi_Sxx-Prv!Rq)8 zD;Dk`7vAeSA~->0Sntbp*REw;T0!6S)zU?QvsQa&_mxX2tvRL2AO)F5B^E(!KN|U5 zm>Q{|8*_5=A3%R-SoH-pn@Sui`fKv}wAB9r!Mv_Ub~B0A-oKhpDTa*V&~OV2AExoi z58E~bFfvVp!k$=EpCkBYG3(d(1^jRRTgd0ruH8^D#Fa%52}0_>kVboAQF$i1Yrnnh zUr1`P+ihd9vQ-7dEq0aDm&k{L`T=kkCFf(wot>fDEds%Y!KQSvot6~Ea$wi=8$qd3 zHRyXCnVo-4me`}tbS)hMPrhv*f+&Wa3FtCKkL~1dHQ5f-)3}%$^yqXl%7}zL&HJHdbxbe;wiHSVjeO%jL*Wrk6O2`y;D+eHJIJ~4LZZ3UAL%X_POPFl^)XunhX zo2zmDrjL3yq*YzQ(G3ou!+bL>a~=fpQ(mJY>Q}QaJMY%GCqamMnEIi65=}$N(Vdm~ zrM*{=6g@J45>;Vt0kp<^?{L^(C|ll(;Q@D%95glMXK}WK;#K=f5+sz9aa{5JkwB1D+0SM9immgSbJ3V({ za2bDF^b5d+6tp0NIBLOnYRdSKIyd>=C$K%c5CEu+oX$S;tm<;}16iDgTrpE&MLD$} zZ=V^?KA4<$E^6S4*r9CL6^3MhY>g1)S5RSeJN#!suc0-+_Q;*=7OokW!t54wL!7U+;cTTFAOiA=+b-Knyk$O9AQ ze0n}4USH4N+0wVo+pe+>2zky&juhUzA=QUTaU zw!h`i8iGx1kOnPj;V>gobbuQmU$?KUgp?k8*iG2^jfciHJ8$Gkt9}BWP@Xm%c>{3@ zSH?IA@`qiDFer#TU)3EZI|ZQ-Mk8r40%YO{x%}P&q$nxW$;8**UEk!=^~oK5ofzyl z92vM;I6&@JYAbhM83L=?SZG3G^*d&CYt`Tu@h86&qABKY^L$b zTOY`nZDTAfD{PkH>1ka=)g=o*HFlS(1r52 z7vRQ~jZnw}!nB-C-@@hXlXDsyxR}3RithZ{qazK1HWP*dMkXE;U>-fbQI~>?z`0+lE>*&erB5iv8F?g zQy4I9ahYIPb#@-=Btey$tYShu*wh{*1P;!N%Fdz zd!yN*fr{?c8&FX@yC^h`WcWK&QOMRru@R7KbH8V`T-(&kV6MPXhw z!AOPEiC#P3a;d2gBOx_64VIkiYI3n4H~Xb0lD4Vrc+-7(6k)*ID@5LfE9Q83k88pu>I%QcZNLLG9G=+W& z5m`Dn>DaLEw?#18?Qim8ZZ6YjY6nDmbi7@+u44tm&cfTh>$&?$vH!6Xm1_q*bE^1e zU_}q&yfWm7MMxzBNe{OEnk#fi=_cVgZaBq&NM}A;7jVGu-J=bgEBE@YZQT@yHhJ1V zAg4QvSnA~DKfgHmhi&!ojN!obOzN{dtS!6kOG5U)_=`J6{IL1e)sEs254ye=f};OG z^F;d6X+G9@^j$gec_*#B<9Dbx3pl@HA(D@S@lr|m$eX0N_+7#TjixjI?|&vb^Oke| zOM#qum6NR3RHGW5GacYw@p-#Qr%qJY)eFGBvVgpnuVyW=*EBb^L`1dZ9mltCl>w1R z0p~Byfw$<`66wxwKd~4WXx$~a$ch6Ldi0{*zH~@e#_nJ0W*{m9ek7_qlJ0GjgkT5q zS>3!WaLBl)>G88kmVD=^>Rs0&X9SruXtaIQuo?OqD=PyWpS%76yvV_5V~$gB`p%2} z;9)vEwaL9>>(Rgqs}c1Cf7WuYt)*$@t==F!VEo;Yx&PY#yw|P+=8^%|O$jar*oUzABT4o3&LSfw=D~;KSgK@RW!t2+YDTS(p6)ka& zJ$uZ&A*pA@F^JUHC?hw_Rx&+{!*+j1Waivf=c`{z8AlJ?%=|a1{QIyEVBTTh0<^!7 zwx;xbIKmkxh8@(okf_XmfhFU@C3YU#{XY+uI)-#XRYlXcZEIxyNB^ zb2clJoK5#H7)KN=nm-}9FCZnI)HIo-@SKD!SKb>INzvhCA6DpYm}a~AK`@cDflgw6nk;aDGa|$tQ9ePjK z96MZ?oB407LYK4;jbBfcS9Wp|YKmQ3pevGp;zKj{rDxlh3^Yd>eLGDjNxN9dePLU@ zo@D-#`0bpp-efvI6H)y>MqmDP)=o6qM$!1cUn(B0r^F-AOu3kSIN0VJPuaH_DaVzf zHmX}&zIzv0&Ar<4e%M?vm9k>Rg0I138YA3jpTvRZojR}2PMu!AzLBKX$fHVxN4hj% zt@5T#`rVJM>GAo5rW?(&wJ=0$XHYinY$I=C(SHTNg;@T{C?4K#x$lm$GCLQ4;{N?~b88XLCFsAH@@tzjhVN#k zY}jde`HC#HS@HXKy4%D#Gfj`o%wJDCsuSKMEk%EszIlE;Df8Da)#LBNjqEI<3EN7` zOey8&Y@x(``{?{)<>;@7%r*O1l9H8`LoU&}v#c0%+gbjZm&V+*8MhuKKgaTl0LWYK^5gBRguIkj-7G|qf`cS2;Cgj68a*3SeX21uo%-2__B+J zqC+3h@H=o2;%!K+KJ)aE_n2cX(u4XC+wiP3bR!yOX{^|Wn1yY0Ac_(c5tkj-2MGYw z?ZR9N_l6nujRwpvYzi_6s&VcbnAPyuZRzz_S=pE2GJYH)Gd5$S z4RaVY2sq!coJc1qo3!olegjSjexJg2u z(;n*1k=1!l`X^64h-B+4Qr6NsWcmGj)>)|%)a(iK?uFbMy@oC5OvKay8vs=1(8nJv}o{&poDZ^=K6S;EDs(Y_iIL0FG3`FN{qDi@w+8Svm(bh>+@WfK zsF+5#S9?(AFZuS3Jar#$2qmhY53knpOnAyUhvwRaoj6Yr$ufw%y3z;KyohKn$`{f8 zzYYZj1cp|j_`;jJ5v9O0POh3nR>+VyP><|%2<$%@kpJ2%qWWmX3Bh#ttzN0scBLh` z{*6#C+$R0HOaY?Ed2I^O_!;_Kedqxd7|m%n)TQSvTi7A7nj*8QRM}(WsY_C?lD$nu9Yw` zY=7C^sZJ+|{^k%=U(kf;Sb?2b?*4t~K|0kkT2x*+-&sUV z*V{`tQD@=6A?N2uQH+jUBuX#cN!|(l_ZGQmyi|x)Z@_7^mhnNDJ?Cq);e?5XcNTwR zm^0U^_~?L#^Yx06ADGFFpw4Y{kWV*UR6lfx?$$|LNRxa!D?q#7*_?71DYce4t^+>G zm4!m>psatk-U#8kyzwE!jptHxZGp|@2Z5O{4Jjk`ja~?Z&~-iPM~lacaj>kTXmW9Y z`Fz)#W~Wpw{GJLd4q95QLy-Nku(P!pmH}Nnmzb{@AVb`<(=aXy>&k{W^i1z4u_u3B zaytr{N|ACyiLL9OdcTQUUR+$t*5^48S^Y6d|73S{q~BWqkm_$=0VZ{&6J_~egN5Vvc$4U7Twi1{D zAv20(he{W}G+_hcVnU>rOU7TKW3pnl0$0~axBg~rCHeKK+ebd>+x=&!MW>gr^+kz9 zRj=A4I4`^vP1HF>XP&zA)+9mD$_39tygYW3*mwm$^C_#*n0*L)pxWqbc-WUwd=TC* z5q-%N3LBmKCFN5=MBWe(%=zDa{6884a)mu6@J&*Kj9Ud6-Et`G3pF}9D^EIu> z=ajk{tx;b&HVq37{QloF%1mVxy`kRBOck561)zuMppgVMcTeezVySx;hXenz>a_7=2gv~Xq#UU~=jWK@X(kxr@R;xy1dno&9 z%n@k+d%(4C39}@RUHG@a4p7rDiby@J%-R>oVliD5k`A|zcEM*2AL^SEsBTU(0 zJWY7#b?(5=opyOo=yo}P8taoU6H98OKm0X6Nci`+4c30vF)j}lW^s>YOH=T_D72Md zWkDnLP#S6+LTAXz!&D*V_U`(U*8cuJ#r~yuY~3n$aYC-EMG(kMr8vYg4dz=k-REkd zWGri3KJc|;>HhB$vmaHMvN_vA<={-ms;80H`W+s}X{2fbr@s;uEijwona+SFC6~9RMOT zYBBls9X8r!IU&S8dl%&ueFra*nFgzYnPSvyRjr`S8rx=ppD@@A)zV!%^8anVMQ2M9 zN|oa#VPklho~gOj%-*Xg{U3U}`QvZ94)U;~Lr(p=aBZCigc5|qSQ}GS@+8Urf%47; z`mDr#?9AhbvC>E0rd&_NPReg6^s1WS3BU@g4DgRQz4-IvKnXJ*)Xc5P0@+}gE!pmn znmCfS{N9n_jNHnnuJ$bLK~g2*#a!)9zq9fk^Cd8$J;FI~2({I^38*K1vhZF3t=qR9 z0LPGXLnW}_sWr@VCkU>&!y44kzNH7^hx-}6i^V4@F=#kPH}{|Y!cvz-EdZ_kFej`ttK;SjGt zf?=gP8UEtOLl>#q*?Xr^8gBb6`AiY=SCj?`(-TEpO^}JO3q@Od4{`)=eP$(`HuKRU z^#1BcmbaJxZO%9cYDDsP__9$^I;b`tY9}im==sKYBVZ=#9SluP;P)OIG{OK2ey{=U zqQO(M!3;DFp#vo9KuA&9gO2S+njF3_?UC#@+AJSrAA&NuoDs#|GpE7r(a04zh|Gcx zpSL?>Q;2loomU=p!@ay|BX4xZ_OPf#orO6fB3c^cd8zY9BexN|uRT2FzTeT1Vhq)M zNA1JxV9i-H6!N!1(?JUrXS@vc1e`zfuqH|;b=y|*e-mV*R;HecG~({RSzY!5Uf*+9 z;wvQFhx#e5@b&;TMmj0XWZo3Q|4K%j`x#d5y~oi-4jp5oc#qUzc_4*ZMg|e9iS})0 zA#01F^g&9vnE&}>#+sXe%UQc3*8)r3xv5n3sez4aw5av|kIboY8i?9kc96Ym4 zLt_y`c2WzBw#`LhpA^YO8O;oblp1#fM`{-DlP3Ue1y`|;)?&;;Bu z4aRIx;!pvz$_zu$1I%KXg%on|w+F%9*vwZA3y}3_+eqFC*l3^5G_uEJ_#v4ZZy{pq zaWvwiwvjfRO8~f|@|N>dR9ZzqX!I&NRaO$Oib-jw9$6XesKM z^yG?_)L$q_N_H;LPzcT1<;7{QGz23_<5&p|RZp~rgIA?`2%%sc5)L&0Qp8bz+AAnix~(0m*>tp-Ttyi z{N~u!5b_TRjyekUI5>+=(SU4l=?H$6G5?T~aTfuL1|VkNDy_!s!YbbgdK0Fr01?ru z2Tg!pBP?G=5*vCM24&n0iqKt!!=A3R=OlZq!oIBsAq8{!2VK~t_R=Bs%y{0LWEPpP zn{rfh1~&YLnVd8@!ma=2U>^X=-gHnwq-KJJhdNJGq43i^H>n=j5XSIs34W(3y#v|4 zPA?`3ET*%bDjFs`B<3!LJ+v z0OWn>qe6lq95lA)D$p3F1<~Coz}{$K7BaZ?s>0yu;pV-CK+ebewqHeEQ5+2g0d!sN z)G{x;SP0zZTi<2yU3!paNgs=4r#Lj(_mexr6Q9u4?QO%pvcHRtq3oMOG-!5cfS(A| z175y%&(o!!{{b(-yBEBq*axr2Zemz#vSSE{VAaK_8^K+niJr=n5SzCL_WX7J&zLf= zmoLN8DxWpSmn6k6*z;e!SYuoMY&m*SsF26^C_YyI@OLqr5wWc!FMC%WwKkF8%cA)A zT8R(wMtugqa-di}FqWk>RWLSjp-A{pYxAm9!?&vmxEovWEETzROXK&Wx|+Kl$;Q(H z`9V;>Ovn90a|h7w`=)ldybngL245URGSt1n1oTC*BgUMcme1N5%`nPYykWdiN4vM?$w(z&^lEa?itj*b)bx)OF4MoFS@g$OCCfOB#a6J1uV`$qm zU6@Py*|n7=sGn-DLny9pozzAwaIynD;Ue+#f{8w5DkWZbSluNGVP*dtfy-vTwGxjy zC*Q=VI`wbd8N_-dyO~MbGvJG|%1DxDioCKji~jKOj!Rm8KTC;1xd z4(QmVb9&7E*Mwz^nay1|{Iwya-0l3Z=hcTT?(BMJ*n93bQOd?~oLg7XQle?(<%ivS zg%U@N)38yOmpQ`4&yU_oNuPq1GlB(GwaX=siby`{Bx3WsZlO|QEKDg`e;kk@0f<57 z3quGlr}`i5`1`*#+PlThfJhtlmZDpXzD^co;&Cj%`)xj|tfFv*UuPk#Sf}-r6Vwvr zjh<7JLAU;!D+Q)BGbvtWd)$`6DMvD?oorIWp-2^%f&2k+RU$SO$zg3ryzepBK2ce~ zf*0is)krYG%c6_)(<0LCxML9vtf-b95ic`9ULgP1`z@MKW!A@G;i!282Wp&!`cp`< z5AcQoJmevgw_uY*aPOlxD_33VY*7@g##5-(7;_E}P^X6n&UXjjQ7j zkCjzpKiEkLhe#^c;KHn~`x`)pkQuu^Ex%A8Ekf3@#q0ts<;Q-Ql46H-gUl_;9Qy~t z_oJ=htaLi-_*-LPJe=(4Z*GOhu*PhQxQgUBrSlhBqX&WS7QUh3%5P~WlYr*qjsM-F zoEllHX|3VSiK+ndyJ?U^M96~%ziacCn~qwolRHpLnTSUR&um?G=I94q-)e20v<&%u zDN7RFp9~MU4z3_fb#DG*Zi~Z0y~@mB3{s&Q4vERUHyuUKxL*n%I$RrEIAt!%U8VVY zyN=!W`3}uk9o%O5p->Iy>A&RMB<6Zg5JsOd-UoTs)C43MP+YPr{h-mSy(vEJpMw35 z&VDog;aVm;1rVxEvD(^t7qNpho`b zDdwR#=n1WSsCf%)uQH!**8L0UE)0p-wj1Sle&FA8ke&I`lGl-nri7f1$=Pc2oqC%! zIsVl9{kO%op;v~EW=goo0HWC)Pzt&=8cZ)p9%caeOvCvnGtcIG$EGk`hv$m8+7flN zDzcg*b*Is+*Xh}Oy)O%rC2r!Cn+9EBwd75aHB!tYsE?egL+;~J8^PzkFl6=DzkTvG zQ61Dnw$NEZYsTmU3_2IU-DF-zPZA$yQ)!W<(x+3L55ZhY$Q>AMON&*?BB&5cIh(@KD^!Q@vplm?ws^4xOi%}lFq)L z28|Hv;rV%+y@r7&|~!GdAI_|MT*`pO{qYpDcs~qnRiiEBMZp z4L@p^aHE5iKW>dfW8+}a)Tn_;Wwgb(ifSj-@5L1oWxGGLt9e@4WkV0G6Wc=^ zkyAdOJyWfR1?}npOOSH?E;1glO2qkgg@w@cyME}=Ea&HwlaQm_oDMYT%}hW|6ku50 zc<6j2*o+&!$;2OS2zyy+hRV(4{^GzA3Bif&n(!J%;BA2p4le6}n6>t*ki}&Bt@&Xt zOt7*KP4k_l8fqxXBo%F!c5dDZx!Ziu?&=ooLs!R?6^O|4YbL0N)i8tD;d*#opZJc) zLm$XHfe@-f9**fO*TdY7bSWoHKe0#nA?J%8I^(tS9% z4h5Q?@!*YrTWQgN#kblhx>q0BTzd+kXGn3oT?I@4nOJ6cC3eff=fK)*Ix3fw!}kVM zVX?UNk?sd^S_HPsHa>h+0Ix|nQdiBXoy=G3l>M~$W;qw-cBW9k_q4ViOVGLwHW0-i zW8~GMQm9KyhUhX|tSqaYUw#49U+)(pog*UIiRmt-VA$Oi>tQ|0Ecr27rZWH z$n(+A_Y+o=U@PGTDeJ+?vOz;=!Ml+NtCV{4{1W?b50pQfMCp2lcSqmQh{jG`+#21f1z^5i$U}- zuPSurx`@Oo9G+FWT}8@Xyw3@S$LT34sWl=ys`N(G)-6oTzWGstg?%*OY}&H#UhZ7l zqfb)R43E?e!DZsqaVGL`|GlBJ7wQ(z(?J@oTfnzOk=w3ZO3AcC?65?Ax16`>iy1DI zJ0Zu3$`iBsjPPXPDtDsBajxm))4(%L4_`QTPLIUr78>^xk02N)OkNs#imy|bj{_E` zFoS2ETzyOZ-LCYd=-nOHhF3TquR!|CzoEb693rwFQTlYEzA+<$XuF5rTa(S;-sLoQ z!aF$~QpXSV5z~+dYtq3e{54k4kEAQ4s`LSL1T#+Zbg2R`yKMYI6tX zL2?U?Q9cvXV9`r-fCqL zqbC`avfUJP&~X3Q&qYLLuONLLMv=|cnh2{F@PvpTl80YVO*PyI$Tx@MH>TupxLtR; zbOE?A!_64EgZX&80DfG|61yq;TRedcKzkWjA#lh67m0153svU058NkIkh@z;M{p6l zB@c{x9bX&~0P{;p%j;*P3gnOf>MGR=3s7|+W52#d4c68zHjf07P@nHA zCaSK3?VJauFtarYs zkKo7K+X$KA{J?Ry$1K@6RZb$|baLD|4w0x=l0qv(iS{%LuIMUU@q zmY4$f4;FuP->AQ}f0!L*lGq!6UE2@wBX>&(>P59n-05%rze<@#($}ZcYLfh4y?a?k zzhj8zT8&;|f^UTHFMXjT=RG+^tdK=+dmE-NUI2c@`6Ge_J&H0HaMTk3A@)a0-Ao6? zEbP|)z)_qqS?y4H@(C5qTYPPO?q80&`pZ^-n*v*3m{@Hi^RPT>G!7LF)dLqDfNFJ4 z1s$tlz^=4=cgdRHMf*kKZ)|j752atPalOJ(nw?Q*g@y0NDzG(MoX9%*Vr*WK422TLI5hovyH*pLndqj=zy z_o8JPg3RHUb^)azV_IcP&$rI1nN*0);N8|RqXvKPP2gd7!*HJMoPT3M|E87=#;ki zKXP0*ZuI>-@VR!aMA@kMEf}-9+q3`LHvfVJA14hH-P77EHEC%NA7CD`yq0Xm{tn3N zkj2lTL)8Oe|344Ec91rX+bVC=iRDVI*1!<~>UrraQ-1n^Qo>+x$w`YtKW;vH3`s?F zX38n4?h)CQJN>F+)-7p@ZP>BB_Fy;GosQqi{cOC{=a-m8JtaNEXW0?d3#=peuPG7n zoZ)b}cpo7i6Q^H~@;haV(rqX!o-M^gvWlz3*tN8~yk%MrRtIh=Z6 zD%r3&dg}(X1dUg+9;0>BDm23khuf+(MA!(BjmHer9V)(v|+!P@7C#Q&|y{4nl={dhv2~=UUNGo@YNi zgfXl}=Ko>dyKD@IjY}Cq^{tEOA;Hj@prHX6oUw=;HeQi~^}LEXjGS3uEd=L(#xfBz z$xdd%_+7oFblBrpjZ+$agT3Xs?SZ54vZ^e8u9OUhCK^NJAb%?)r)OolBANtSEl7ua zC-!maL0BVpE;5@kGLh)e+aBH(@DURJ0vg#9J}t7cypu4%m;Wd1NtvVof(h-2DkB>y zmtlw8s!eFliz$zk7_OA^PF`QKI*j~7vXS2W9ezNBA8#{IZoJT1rSG8T!PJD)jUfdf zBv?)oN6bq>-FZ~9a|qNcf5{U|7VVXsvp_;!HqwH_ygxygt5K0k+aCTH;HY) zMx+#^ZV#`pJZwsnisa4>?2KMceiib8OOM0DSI9Hgoad3^shS@SK*Nphvi#o(vOqRv z%F~JR3CouUAHvj(1yM>!jqHM-0qxoi_-xn=FLW6*ckxG)aZVsb z;KRUECXXvf<(6Y=HHf-AV-o~D3Lv~m|L%^rXAsIRfP)nmpTS`s+*9`J^0$_L|9?m9 zijA`{a04QMeVUm(hHTtSy(?7)Kt-|^f|vFR4&2X#iRk(PyWm2OzsSsi3Y<^O1ZkAsK9)0h zhAYmmT)b$eaw&pbAG#t*mlX3)W%>bZkAUbTMLOtr8)LFMUjD+Nu4oE*;9RhuQWm_D z*D`^KlEZV`xo`{WC>;FTh3`wxu5SAO3#*Z*$0pFdU+`1 z`)>PBEe!fdC$S~v?l|A_<}jqp3BYv;$g)p^Xso-jAsNs_3C8P>nk#syQONCwTtD0< zF&Tz)ydfgZBva(zf2e7e$APTj(1dJnG&UO%Y=JsC0!IHGn4m06hz2C`jsw_egxnm; zCSA=d(2Bcfx|q8*ynU6Tcuq6UCC0I5{f%Pz?!c6D)B~NNDrb@CvAyFK``one1zo$D z6X-%-9ph)hUO_8{x$N+4@T+w}{;tGEGM0!e|M~EnPQz&|JztEGkYcl$Df8gX&64F6 zT1tlrhHK&wK%?1z5`6W-C93-J60vUWA1H-B>B>9eYru#VD$X;faq>T?Y?l8}fV{=3 z!D(N0)*9F6IKu&_Lu%Mlc++J`oZ?t}+|rt}pA8$x5S?pou&GOb@@UWS%*yS#W6%n| z;qZNEg5fec;Bef=>(YIEmMv3t$^^r+<*V!WqNhmrtxmENYqxbsY5TJ9kdb@p^Mss9F+2ICDFGGu&DABU9 zF_-s5-oO&#USz%EH8(vr$Y0PBS;nJLls8^jHz{#I9?9G#s zK+dAzzp9CeK5m-ajX#iDNbGJ1xf_u+v7-3tAKhX`5}MQ?LMjkE>a6tuW~rQ*j7He5 z0!a8}K_AYSYqWC&5ZJ{fS+Bk3$D0w3{Hdy~>>fB3nK#zmKtW+!MR>v4&Mq&AnB-f^ z&OGkfkyu77DSM4{g3DWZNSip={^S>w!`tEzI$~I#c7^pFWcr0Vz`7xrYaeoM*vn44 zJo3c(?Ooo%R&w=pk;ykz;#n{U+EH3k86}Z=4C#sX#v(_!aWx*F9 zMiT1-qgBgFJ5~t+FR|4OF8*FT9qR5ycp~`ry?SfdtKlLET|lfqx8-$2&L`&d+?Q%4YuUj@syVOO&Sjjdu1$-x{Wm^4KQi;Lm3z`g<7#hF@9gwxRk`-n z6PkC1UQb?};QTw(Y!jf3pkMtJgFvX#aMb1urSHLwNQUc690_q?-Bu1Foip++CFmWR zFrp;Qi9$pM=8lOIPmdy^dfy8muofLS1uE4r$S)iZgM#cmlG+UqMU3ETt2m7%9z>leD(|-( zGm}us3i}(CE_)CKRYg@c`Y?_=qyd*>x?)g!X+d$qVj(P6b6{(l1DswcXTs&uBd$oCZ!{xagcZ;^r^{8ie3-~faqE3zExxCuH z{&vU@SWowz0Q}+3Sl8qaKypmIXEjypr*Xc=7lsYgPKF*Zcs`tm6uwhdQ&tlm5+;SE zuxo{*o~MjL2O{F&Y|TTUm4zM;#(>5Jlf?yXb;VdADN|^plJxPu_eGmVH5iNPJqWAG zXwU`fyz~DzYD)TL=MU|yq4W%yRBelMx&xmL5I?yje7-3Ub}^N zgvJH-5+VpGJ@^w4+xuwYknLV|C_6hAHm15|0b%wJG^1x3z9YLe*@pqy5PGRecu+{K zFxd(JV!pU~(#2z)qCCUa8*lAdbKS7l-{)5ftJWn=@_{D5U(lD%M`h*}KVsh4HzAtD zxQ}&ajL##xgqwK9YSBVA)YJjjEzYgG`au95+v@A(HGag&3LWxy#yXr7?{D2icI`|# z5tZd4!W0>I6j9p{rwF*8jr+Qne3n)PeXH%SK%?~YuZa12?)O&Tp~x7XVW*NzB{^wC z50dI=usW!lp};?WGZdzDz2B*-@#keDWt=YQs^i$|wbvTiA?0`>mcV$J`~k{;ft&RS zBXum)LvC3FHst)((MfF>LO(}- zo?UIOY#C)W)f@lsJ4kQM8V4KEjLtL1H#S0c%4(Q|gIeiK?Lzw^MT{dsej!JS^!$+; zo;P9nCo84(S@Fxsy@g-XvOC6lWvabKg~ z&3;Tm?Lg#uk9C93vUXJ`4zcPS==i=I2PS{yv0*Mrhi>*iy|SHICFfOJ zqhlvu_a3{5S01T@ML(^O+(on=vP?`GK~2&z)AtH601NRCJ?xs*!3TXqQ&=xJK5ias z>yUB5fy z;XKEVV54iqd88}YJ3i@rrRM&5wO&5gi@g6quawE~2E*c!=YcMd`zhrh<}ug|L{(P_ zMGEP;sEcQt1v!mcz{?`+{JlOWXOFkgt+W7)<$@s4Us9&%H-Iu!aMVGPvOZFA` z>mm>~Dw-Tf^+Nsvg&CO8cwC0L+JDd*ngaGIA{w2^jE=2ns5;#Em(jiew>PRe@tL~L zN?_^T-`>douU{F{j4RVIa%ZKz?>IW>Kp}*{B+{kN);in)8*rSWEc0O1wfWz$c_^;o z03l#$UP^3k9<$O|x>S#BW4*peeurxu(dyfK$Gg>+T||QTt^$lbpj)At(4wat%Npex z@|EhkVPLAc8^*Kp;VKWmjO!(9VQR-tL8PEk5@zj;dvPP$xOd_G*xZc!h%5y3j!-@V zz3_NpsC%|dH$}2#I3)Q?Ctn_TJi_rr(>DPjrI=?-p0utN%h&*|(rMYR(&S#yB(> z0ZWE!mJQpad_Wn}F?}#@aI&(~P||<+4ZEa2RW9jcw_D+XrMHw!Y@Hp6PWENkWnKTn z8I3gT+VT4pFk|+AVpfOEK6NXzzF3wyS5h%#ZS(gBN)8Xk2>^=VzUupe>H`^^knRU6 zfwvd4=Vqrp@BiM!su4aGVn#+zpaYEQ9CTQ_xaUR4?VT*msZKbs6ig`R#)vP6w2xI% z_BOHa?dExRGb_v1a_MMv$usfL5*U3I=>TYS#d!0UmY4#`KY-;r1*VyYO&0c)Jt><1 z0<&axzkmsPXKTj4VV70O+~`Nu(z)E}c-ih-d-_Xi67AdOUXI4ESs)EJHb8>b1yZQ) ztXkEbM9@1Zw%35|Tpp$cm@`Tw&n@pu&#xvFNd9r z$G;q=0o5)x7?a&GDKf|oQwp5k{xqY`u*m@tY?Y#y>p(Y1Jl_EW?l2)IeL_ZLkdUP51+SMx~@C!dN${G zj(@gd;ops?S-02bI4BjYove7rJa)Nqt|#ISc*G_h8E$lIz4*5b1=I6N(ncH4oll&V z&)4?cF3mi2#dVuKiUiw#dbb5k{`8JO%EpDRc3qN< zC)ZgIO^C90{d*E&13?GERyH->m32MRuJl2imq?$-^J$)w9&`#*p7X`5HNWUSU61H* z-;xUsBsQ`jCTTeGbek(IBv5+De8fH!XJP2NSBq+piE3^IK#ZibP^(el$*i}SKUwEt zHfSk6bb6g5?iiA-Nw*svc*)dEwAk{K3m~eJsaLQ(x$}^_!)nj`harsU(++zegpfuS z>~~GuUy*-GeP5Bam#8~{rxlqYV5o2+mEC&nd1qb;+-U%g3rEIPKMszn0&-aC?? z&^B^{2D^>(SQnlXxNVSfIj>z_7{qTr#mu6FY$$f~iUflIk~hlJaP<)Dr#Idp$oVqY z#f@}@d@-}obnR!n3C-L4JP_wN;8Eao?Cq!+5W$yA?+qRYUwhv^@h2b_EAjx7&6`L| zLgJ}nA3G?AQapxaYyW%&DtJVTbbSX+RFDzira!Qp2So=Y&@55($zBiOKm?#dj<86A z$fL^kp9l=ixX|nbo90i=#gKw2$NykoB+r%`9P8z zv1JK4--3DFnJd9dkb(1Whsxq}X)Ps`b%n{Y{b3I^96ug9;Tcr|65jrOYSuV{loym* zeD_fb&2H69T+s&KIh@E~{lesoWETau(A7jhPY}+AD!(JH%1kzWw`6JuEA=r{$$Z@? zoRr)LeX3u%wGRUGZ^wmjS2{U0cOxB%z0?Gmvk;;aE?7~iBN(R&+@%`v{<=vWfD)z;{R~<|}6sn7c z73{(>oHW+6!3F+K>z2ewfN7qj=-KI(EO>K@qmeL>3`H8 z_4o`r{fwQAdsfQHndj4ckGcNe2T14+0Z*J9SbCq&&GvR@%^F0g(Eg=iZL9Z;?gdBH z;fYWHg%p`rBuJ%ft0R$~hfTWUlZ71nAqoU?Gq}yrZxXIYRKw;#^FIW^701*9l&lxN zGXMl=vh{yAB9obiC>>;8xBF&?N*Uz%M9+t%MU$-;hKeU8%)omvn3C_NW;937*K=Rvt3ihos4}PN$HcN+?#4ePZ28tW^a>u3@{0-Sr)~ z+r>M?_dq+S*=cwvt4D}t7rPn8M{zh8j9}*I!MBE=7Ye@l^codACatT#AqRpfBQ3hN zaH$@>2@LexuAU&3@w4+Ss&F6uWT2KUI!~_Q>GNupq~|#r0HlIbv$)Rkd?@ONa1J4? z37;A&+Ug60qdcUd-F|!Q*lH(m2uML%)D_cfsgl}gY;ibWCo7q)f;NfRB9Ob@z=c^K zG(3$z&koyo{DGuT!5`6_sjvKO4;wQ(&5f=PnE#h*Fp#S>_?686_($YQ!hgVgn#&zTqTqt6;2&_nbxidDoe zRHH5F9T!_r-gRa{o8kZ&>%38ql)99D+>Bh&-`@WZ!ZP{{$j_@A*UbC)ZV4vAkxsbU zP&!u{S6m8!53r6hK{W~`?4+-jEWwWShm!GXVALZ;wK1pBOoNe zZZnB{3cX5`^hJP2UcSO7~K0*0ZnO z<9UT~c~;-JvaLYJmC^MK08%Fz7zioDEE*JDY{|QjA%`~n7XysJv6wZCr=QGwXMoe+ z+2TX+jwH81AD_rf1|ze<=KnS(ge1DDb>)G3f*PA-)PCMc%9^|7Y2}Y6t~%Y{l~Gap zu7J71o4a5p2!x`>w)4$Gk-e1dnuU)U9*Bxi!4vqRq6y-2h^Zd)xTMhqY22BAgOgcB z^R>fLS;d_HJBgkty%$*T29uBYadHF=;gz^|?!4&v0;hiP+Hg1Y-{z> zv->_@Kbza20zfp!0_V_>?#|`fU&%`o%ip^1ZjA~;k7~NSN{ORe+0;{F#yW=b+ZuPF(4kohXnfDcy1K50k zm2V@n5VBq1e3f-8`>9rMe@HBr-iU6R^Yo<4%W(iZE@z^d=7-h|K2S+Dd&6^SD)=gB z!UxH?u%HA8!13@l8(S`tkUBpmRTA_6^mL_BO&wu0?2wdA*#rU<1q1}N%1$jrE4YLx zNF!SS+k*j`M#>U`LTC#f6eLnnYmg=2K|u{7Ph=4a6r+_bp-9?L0pWlP1`sKWNa)MV zYv=dNcP4q6nQ!iQzk4ZE%X7dr&C$swj24F#aI8Qfr zxdX=?^ajB0xt+FHOX)*_V$F46eK`i86f+d*-%<8aS-EJpb?d^S^66i((Ov!+se@^%R;4S~qj_I0ibk)7{D(MnnBdZlpW9Yy$lG zIV&j?1W8l~e)z7Qbh?W9Cbw|Uu!1L=N~nUHe@4fS`0!EU(u~(2Jb|r2?Tt_uuo0If z7{m3gb~;kDnau4}+Qr(4$TtwB(UVp&bpwq>@ndo=t zd8%x8r_ygwsPev1`I2tt+I>-}XQlm(&X8i*fROeqq!<--=mZ;a!A%ZGc9|B}yv?Yg zj~kAoamrs~^$A822e?%(`vn&WY7WrZf#V#Vvxq}^eY-EeH8V0e@cgZX`OM!V4r$?h zYamwss4%HCy)SrhIB%4)vh-R0HAT^(3Ue>`PojiT98OC>B{@Ykw1>}ybrxG(g;7M#T!44!Lwwy(oDI&8^6HKVzFyc!`<=xq0C=W+C%9@rp_5Jpr-f+LHK1 zm&Z2&r+#AFsU-_9>Zt1)Nq;fnGvWs>>tM9SJmQ(9n0|0{b`TT{QFLO40wp7&Vvw<_ zo=z^n{oYrNNGtCirW1)dsq&8nasp?Xw{b=CYxa!6?~p#i?4Q87F!Ad&GrEFcHOpXgrA zjBMM6Y_!8WQQ~G#yU>T!uDX%wtQi9-=i{C?MA#_6!^F32(%<*GqXw1a3V1y-Wop7N z^A2nVyjwQJTSk_+xB8QI zs999AfFfnPnW8?0-WA4VmGuBC$b|`pCu(h?7|(|6r-)={V`-5Azr>weTTx~Hf*?)t zV-LGI+s!?7B;}nKd*O{4+W{NW7Bcqq*NI@RQj64JQoULLI2zR>GpXvigWKiP~hTWt{O(vu0bxKT89Wn(y zX)C(?M)EZx)@RqRXR6VB?UtE6y*a7fM*NapuWOZPQI-<;8~YLs4N2k0wjzavq*d92 z<_+!oBJWFwY!RRP)>giBc6J+w!+#W(24Y_@6`Z5doDr^tmJ|21ogIN8k!>!>(qXi3 zekYfcreE42Zf>N6SX)FWBy}fDk;yq Date: Sun, 30 Oct 2022 18:53:21 +0100 Subject: [PATCH 613/629] readme tweaks --- README.md | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index e0c3d07..cf17e0d 100644 --- a/README.md +++ b/README.md @@ -2,22 +2,30 @@ [Kafkatorio](https://github.com/adamko-dev/kafkatorio) is a platform used for creating [Factorio](https://www.factorio.com/) mods that require communication with an external server. -It was created to explore the possibilities of using [Apache Kafka](https://kafka.apache.org/) -to process updates from a Factorio server. -Kafkatorio receives updates from a Factorio server, processes them, and exposes them over a REST -and WebSocket APIs. +Development is ongoing. -Development is ongoing. At present the only application is a -[live-view web map](https://factorio.adamko.dev), that shows the current status of a Factorio -server, and any connected players. Other usage possibilities include exposing live metrics, and -inter-server communication. +At present Kafkatorio is used to create a [live-view web map](https://factorio.adamko.dev), that +shows the current status of a Factorio server, and any connected players. + +However, Kafkatorio can be used for more than this. It has the potential to export metrics, and +allow for inter-server communication. + +Kafkatorio was created to explore the possibilities of using +[Apache Kafka](https://kafka.apache.org/) to process updates from a Factorio server. + +### Running + +[Instructions for running a Kafkatorio instance are available in the docs](./docs/guide.md). ### Overview This is a brief overview of how Kafkatorio gathers data, processes it, and uses it to create the live web-map. +Kafkatorio receives updates from a Factorio server, processes them, and exposes them over a REST +and WebSocket APIs. + 1. The Kafkatorio game mod, [`events-mod`](./modules/events-mod), collects event data, de-bouncing and grouping events, and converts them to JSON packets 2. `events-mod` prints the packets to the Factorio game server logs From 30d5a67a2ab9ae8a5cf9dad2bedc51f4f07ae4d3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 30 Oct 2022 18:57:30 +0100 Subject: [PATCH 614/629] update license to be gpl-3.0 --- LICENSE | 676 +++++++++++++++++++++++++++++++- README.md | 4 +- modules/events-mod/package.json | 2 +- 3 files changed, 675 insertions(+), 7 deletions(-) diff --git a/LICENSE b/LICENSE index d867f51..f288702 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,674 @@ -Copyright (C) 2021 adam@adamko.dev + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 -This file is part of the Kafkatorio project. + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. -The Kafkatorio project cannot be copied and/or distributed -without the express permission of the author - adam@adamko.dev + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README.md b/README.md index cf17e0d..005f182 100644 --- a/README.md +++ b/README.md @@ -60,5 +60,5 @@ events-server-)web-map: WebSocket updates
(e.g. player movement) ## License -While this project is under development, [no license](https://choosealicense.com/no-permission/) -is provided. +Because I care about sharing improvements, Kafkatorio is licensed under the +[**GNU General Public License v3.0**](https://choosealicense.com/licenses/gpl-3.0/). diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 025c52c..592ddd0 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -16,7 +16,7 @@ "typed-factorio": "1.8.1", "typescript": "4.8.4" }, - "license": "UNLICENSED", + "license": "GPL-3.0-only", "peerDependencies": {}, "optionalDependencies": {}, "bundledDependencies": [] From 84931f10e80638367cf4b9371b30aa78c221c7a3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 30 Oct 2022 19:19:25 +0100 Subject: [PATCH 615/629] improve exclusion of Gradle generated src dirs --- .../kotlin/kafkatorio/extensions/gradle.kt | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/extensions/gradle.kt b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/extensions/gradle.kt index f9d0046..ebfbcdc 100644 --- a/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/extensions/gradle.kt +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/extensions/gradle.kt @@ -4,7 +4,6 @@ import java.io.ByteArrayOutputStream import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.file.Directory -import org.gradle.api.file.FileCopyDetails import org.gradle.api.file.ProjectLayout import org.gradle.api.file.RelativePath import org.gradle.api.plugins.JavaPlugin @@ -37,19 +36,20 @@ operator fun Spec.not(): NotSpec = NotSpec(this) /** exclude generated Gradle code, so it doesn't clog up search results */ fun IdeaModule.excludeGeneratedGradleDsl(layout: ProjectLayout) { + + val generatedSrcDirs = listOf( + "kotlin-dsl-accessors", + "kotlin-dsl-external-plugin-spec-builders", + "kotlin-dsl-plugins", + ) + excludeDirs.addAll( - layout.files( - "buildSrc/build/generated-sources/kotlin-dsl-accessors", - "buildSrc/build/generated-sources/kotlin-dsl-accessors/kotlin", - "buildSrc/build/generated-sources/kotlin-dsl-accessors/kotlin/gradle", - "buildSrc/build/generated-sources/kotlin-dsl-external-plugin-spec-builders", - "buildSrc/build/generated-sources/kotlin-dsl-external-plugin-spec-builders/kotlin", - "buildSrc/build/generated-sources/kotlin-dsl-external-plugin-spec-builders/kotlin/gradle", - "buildSrc/build/generated-sources/kotlin-dsl-plugins", - "buildSrc/build/generated-sources/kotlin-dsl-plugins/kotlin", - "buildSrc/build/generated-sources/kotlin-dsl-plugins/kotlin/dev", - "buildSrc/build/pluginUnderTestMetadata", - ) + layout.projectDirectory.asFile.walk() + .filter { it.isDirectory } + .filter { it.parentFile.name in generatedSrcDirs } + .flatMap { file -> + file.walk().maxDepth(1).filter { it.isDirectory }.toList() + } ) } From 394acc5ca03c31ad0aa572ef9e24c6bf77e2fba4 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 30 Oct 2022 19:22:38 +0100 Subject: [PATCH 616/629] version 0.10.0 --- build.gradle.kts | 2 +- modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index fc6db37..597f39c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.9.15" +version = "0.10.0" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 4c7a5b1..0fe86ce 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.15", + "version": "0.10.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 592ddd0..29a45ed 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.9.15", + "version": "0.10.0", "private": true, "scripts": { "build": "tstl", From ce4df2081a90a92a6af4810718deed190e08fabf Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 30 Oct 2022 19:26:02 +0100 Subject: [PATCH 617/629] bump versions: factorio, typed-factorio --- gradle/libs.versions.toml | 4 ++-- modules/events-mod/package-lock.json | 6 +++--- modules/events-mod/package.json | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9fb61b9..0dbb334 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -53,7 +53,7 @@ nimbusJoseJwt = "9.25.6" # https://search.maven.org/artifact/com. npm-luaTypes = "2.13.0" # https://www.npmjs.com/package/lua-types npm-typescriptToLua = "1.10.1" # https://www.npmjs.com/package/typescript-to-lua -npm-typedFactorio = "1.8.1" # https://github.com/GlassBricks/typed-factorio/blob/main/Changelog.md https://www.npmjs.com/package/typed-factorio +npm-typedFactorio = "1.9.0" # https://github.com/GlassBricks/typed-factorio/blob/main/Changelog.md https://www.npmjs.com/package/typed-factorio npm-typescript = "4.8.4" # https://github.com/microsoft/TypeScript/releases npm-bootswatch = "5.2.2" # https://www.jsdelivr.com/package/npm/bootswatch @@ -65,7 +65,7 @@ mockk = "1.13.2" # https://github.com/mockk/mockk/releases/ ## infra ## -factorio = "1.1.69" # https://www.factorio.com/download +factorio = "1.1.70" # https://www.factorio.com/download confluent-kafkaConnect = "7.0.1" grafana = "8.5.0" prometheus = "v2.34.0" diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 0fe86ce..f39b824 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -80,9 +80,9 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.8.1.tgz", - "integrity": "sha512-qqSPGfQawq5e25+cf/rajTeyeQ0zQyyiVbVlBE4NYW7MSzK8ZEKH5JwuJsro8cZAmZMXqvX2V1uzCgnD9orLaw==" + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.9.0.tgz", + "integrity": "sha512-k3qVo5ehUYgJItQp4BT4MtAodzeUgLk3Wzf3TG53SNdce1vYfIdmlNMjfG17wkOpoCBCA1p6XvMQxkWcbk23ZA==" }, "typescript": { "version": "4.8.4", diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 29a45ed..20dc2a7 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -13,7 +13,7 @@ "dependencies": { "lua-types": "2.13.0", "typescript-to-lua": "1.10.1", - "typed-factorio": "1.8.1", + "typed-factorio": "1.9.0", "typescript": "4.8.4" }, "license": "GPL-3.0-only", From 76d553a6bf63031a84c894499d2633121c6019b6 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 30 Oct 2022 19:27:11 +0100 Subject: [PATCH 618/629] version 0.10.1 --- build.gradle.kts | 2 +- modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 597f39c..60ddb51 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.10.0" +version = "0.10.1" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index f39b824..7cafafb 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.10.0", + "version": "0.10.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 20dc2a7..a204e60 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.10.0", + "version": "0.10.1", "private": true, "scripts": { "build": "tstl", From 65ae4677336946527b58d7d9cc3c15b4bb1c9c3c Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 30 Oct 2022 20:32:21 +0100 Subject: [PATCH 619/629] add some nice shields --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 005f182..646a4eb 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +[![Mod Portal](https://img.shields.io/badge/dynamic/json?label=Mod%20Portal&query=%24.releases%5B-1%3A%5D.version&url=https%3A%2F%2Fmods.factorio.com%2Fapi%2Fmods%2Fkafkatorio-events&style=flat-square&color=%23600401)](https://mods.factorio.com/mod/kafkatorio-events) +[![Factorio Version](https://img.shields.io/badge/dynamic/json?label=Factorio%20Version&query=%24.releases%5B-1%3A%5D.info_json.factorio_version&url=https%3A%2F%2Fmods.factorio.com%2Fapi%2Fmods%2Fkafkatorio-events&style=flat-square&color=%23d7cdf6)](https://mods.factorio.com/mod/kafkatorio-events) + # Kafkatorio [Kafkatorio](https://github.com/adamko-dev/kafkatorio) is a platform used for creating From 2bbfd3cc57ff0965875342fbd6630ff994beeb3e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 5 Nov 2022 16:32:31 +0100 Subject: [PATCH 620/629] bump kvision --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0dbb334..a4c7004 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ kotlin = "1.7.20" camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" kafka = "3.3.1" # https://kafka.apache.org/downloads -kvision = "5.16.2" # https://github.com/rjaros/kvision/releases +kvision = "5.17.0" # https://github.com/rjaros/kvision/releases log4j2 = "2.17.2" okio = "3.2.0" # https://search.maven.org/artifact/com.squareup.okio/okio qosLogback = "1.2.11" From deefafe255ce823a9b8f505cb89cae168fab3116 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 5 Dec 2022 23:18:00 +0100 Subject: [PATCH 621/629] Gradle 7.6 --- build.gradle.kts | 4 ++-- buildSrc/build.gradle.kts | 6 +++--- .../docker-compose/build.gradle.kts | 2 +- .../settings-plugins/build.gradle.kts | 8 +++++--- .../conventions/kotlin-dsl.gradle.kts | 3 +-- gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 61574 bytes gradle/wrapper/gradle-wrapper.properties | 3 ++- gradlew | 12 ++++++++---- gradlew.bat | 1 + 9 files changed, 23 insertions(+), 16 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 60ddb51..9cb7b6b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -38,8 +38,8 @@ idea { } tasks.wrapper { - gradleVersion = "7.5.1" - distributionType = Wrapper.DistributionType.ALL + gradleVersion = "7.6" + distributionType = Wrapper.DistributionType.BIN } val runKafkatorio by tasks.registering { diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 1b062d6..304fee0 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -17,9 +17,9 @@ plugins { dependencies { implementation(platform(libs.kotlin.bom)) - implementation("org.jetbrains.kotlin:kotlin-serialization") - implementation("org.jetbrains.kotlin:kotlin-reflect") - implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable") + implementation("org.jetbrains.kotlin:kotlin-serialization:${libs.versions.kotlin.get()}") + implementation("org.jetbrains.kotlin:kotlin-reflect:${libs.versions.kotlin.get()}") + implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:${libs.versions.kotlin.get()}") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${libs.versions.kotlin.get()}") implementation(platform(libs.kotlinx.coroutines.bom)) diff --git a/gradle-plugins/docker-compose/build.gradle.kts b/gradle-plugins/docker-compose/build.gradle.kts index fe5b17f..1c4ca45 100644 --- a/gradle-plugins/docker-compose/build.gradle.kts +++ b/gradle-plugins/docker-compose/build.gradle.kts @@ -5,7 +5,7 @@ plugins { dependencies { implementation(platform(libs.kotlin.bom)) - implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable") + implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:${libs.versions.kotlin.get()}") } gradlePlugin { diff --git a/gradle-plugins/settings-plugins/build.gradle.kts b/gradle-plugins/settings-plugins/build.gradle.kts index 667932d..f7fdd89 100644 --- a/gradle-plugins/settings-plugins/build.gradle.kts +++ b/gradle-plugins/settings-plugins/build.gradle.kts @@ -3,7 +3,6 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { `kotlin-dsl` - kotlin("jvm") version embeddedKotlinVersion } val gradleJvmTarget = "11" @@ -18,15 +17,18 @@ dependencies { implementation("org.gradle.kotlin:gradle-kotlin-dsl-plugins:$expectedKotlinDslPluginsVersion") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${libs.versions.kotlin.get()}") + // https://github.com/gradle/gradle/issues/22510 + implementation("org.jetbrains.kotlin:kotlin-sam-with-receiver:${libs.versions.kotlin.get()}") + implementation(platform(libs.kotlin.bom)) - implementation("org.jetbrains.kotlin:kotlin-serialization") + implementation("org.jetbrains.kotlin:kotlin-serialization:${libs.versions.kotlin.get()}") implementation(platform(libs.kotlinx.coroutines.bom)) } kotlin { jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) + languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) } } diff --git a/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/kotlin-dsl.gradle.kts b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/kotlin-dsl.gradle.kts index 2dadd26..22d4998 100644 --- a/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/kotlin-dsl.gradle.kts +++ b/gradle-plugins/settings-plugins/src/main/kotlin/kafkatorio/conventions/kotlin-dsl.gradle.kts @@ -4,7 +4,6 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("org.gradle.kotlin.kotlin-dsl") - kotlin("jvm") } val gradleJvmTarget = 11 @@ -15,7 +14,7 @@ val gradleJvmTarget = 11 kotlin { jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) + languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e5832f090a2944b7473328c07c9755baa3196..943f0cbfa754578e88a3dae77fce6e3dea56edbf 100644 GIT binary patch delta 36524 zcmZ6yQ*&aJ*i+pKn$=zKxk7ICNNX(G9gnUwow3iT2Ov?s|4Q$^qH|&1~>6K_f6Q@z)!W6o~05E1}7HS1}Bv=ef%?3Rc##Sb1)XzucCDxr#(Nfxotv ze%V_W`66|_=BK{+dN$WOZ#V$@kI(=7e7*Y3BMEum`h#%BJi{7P9=hz5ij2k_KbUm( zhz-iBt4RTzAPma)PhcHhjxYjxR6q^N4p+V6h&tZxbs!p4m8noJ?|i)9ATc@)IUzb~ zw2p)KDi7toTFgE%JA2d_9aWv7{xD{EzTGPb{V6+C=+O-u@I~*@9Q;(P9sE>h-v@&g ztSnY;?gI0q;XWPTrOm!4!5|uwJYJVPNluyu5}^SCc1ns-U#GrGqZ1B#qCcJbqoMAc zF$xB#F!(F?RcUqZtueR`*#i7DQ2CF?hhYV&goK!o`U?+H{F-15he}`xQ!)+H>0!QM z`)D&7s@{0}iVkz$(t{mqBKP?~W4b@KcuDglktFy&<2_z)F8Q~73;QcP`+pO=L}4yjlzNuLzuvnVAO``skBd=rV%VWQTd0x6_%ddY*G(AJt06`GHq zJVxl`G*RiYAeT=`Cf(SUN$kUEju!>SqwEd8RWUIk$|8A& zAvW|Uo<=TWC~u}V?SNFv`Fq9OeF_VpfyXHPIIay@Pu5J6$$pg{;xE9D7CROVYV>5c zv^IYXPo_Z4)bg5h?JSUX!K`q_u{>F%FzrG>*!Db_^7*7(F@f%i34Ps`JBAH6{s=ygSr^CVO)voP`v=SO z7v;4cFM_D>iVl{&X*N7pe4_^YKV%`5J774`5!DC}g;D@50h?VA!;fU1?Hf%%`N8R1 zSg@hZ8%Dq^eYV1!g8;`6vCSJoK+V1Q6N8ImtfE3iXs!s~B>js)sLHB9w$r+6Q>Oh#Ig&awvm%OBLg!7alaf}9Cuf;M4%Ig9 zx4K}IQfPr&u?k8xWp!wI4{CP#GTs#qR0b+G{&+=vL}I{b-Pha43^%8=K3997~* z>A|oxYE%Vo4~DiOih`87u|{8!Ql5|9Y+(ZY2nRP+oLdGErjV&YeVKw>A$JyPPAL+C zA36S!dNVf z;xJ)YR;^VPE1?`h-5>{~gwY2pY8RqhrsiIBmJ}n3G@Zs!!fD6y&KWPq&i8HEm*ZAx`G} zjq2CD5U==ID^we8k?=geue4Y>_+%u3$-TzVS6QMlb4NoS%_V>;E2hQ)+1Q@v(reC5 zLeK*f%%{PNO-mtrBVl|-!WaiKAkZv-?wnOwmZ=Tv57k=4PX=C?=I4V*THRFRE8a_{ zb>5YwDf4o>>$o{XYlLN{PZ^Ff?0FJl4>A9C-q9A$$&44l122Qsc|6Fd6aTam{=JO3 zBFfFe9seUPSUeyXQc*RA>2{WoKIYVltA&@5spdIW;rzOOqoQo`CN;~UNgU{{m9^c1 zTrN|8w_7+Nws4}Z-4eS9WMpF3h<@81a)oK9njh;-TB74vR;u{vE?>6FDG7<%GVXFL zUR9l{z*eEND6pp)+hpNT$VVM^Pw*S;#NrbCmH{dhBm?%6D|k)0C@Z9H>T|kby1^)# zOPmJ8Hq`8waoEK(9}IfP_q4yr(s?ME+T%UV-ikxW!XFb^6w02t30j$n_VSwevg;{9 zx0OXK_uGBFej=gbG>G^pEv^`I8&_a@t9>Nr;#r?XNKquD&Ho|`)qK6C^-7SCdo=S& z)vUi;m5*qIePEIbL=wJ|WCBNY;zCm2F-+@N2i{I^uR9UVZm$o`I|@<&2}w)C`h)vV zW{)yGJ3?GCZNtFe53Kb#uzrC7v-{JygKZUiXDV5mR z5la_vAFOvoh#yn)B`$^ZN*Dxp5Uo~_k8G9skn2)Tb>Kw#Vgxi`bti)^(z--X9F~oR zZ6=^_x@mDT~=h_@GGVcgBtLzssB1|Xy(xc(lUYJ#_ zgwc&ajE%^cCYW7d;xAxi{#LN*1}s>{K79MZrq!tYMpRA{T!#^tgXP=J5FvkbZ@gx~ ztq-E&c$`|KX8GS2a_voZHf=y8C{6~f~`DpC- zjQfrt2OGi-WGx}Y4>vM`8<4frU*!bq*NJ*Tyn0cqk=zpDdYth-PJIfz5>pLF@qnai zzj2FEhuOa-7$JR=U!L{UWWJBA%~SW-6Nh&3;<}iQO)DvOI&VKi1L8rmICePWqoY^F z-dC8X8~1T}=C9m&yb1kZzbKd2;29_Pm*Cs=y{Z06QZDlT7Poci>1@hFa%t0<`1()UTxcQ}e`fAh6K`<5C_SG`dw$IqzwEYNKvIH3VWlhz z_#^(T53W}jeWF#WIhj^U7AdIB~3feC--5iUiiT4Qyu81 z;Xa^8#~M@p%6B`LCKWWTa7I+35BLP=EOa&Gp2pbTWw5HOIjrx;2J(KI$$HT|w8}R-8fbp9sot&LiLs7ILlyZc8 zWbss7=*Ah|X$LEt1O|T?ABkIn-0NN`I8+ipfoBZcW>(WiaASG_khBtKM{hfkm5VBS zy0Q`4*G6HRRa#9G)10Ik3$C3|nQbFzmU-dA`LjKQY8icnx?2OE40%z852{OJH=?mbvwr9 zhlx0RDo^D;p*xKx?yT(`s7wj7BHA~rHF2yxnL<1PcU7FM57;?g^ z&CyPh9W4KvZ;T8w;AuNMn|nQ-xJ~CvVT7gAPAGi7w8udw_LOp+p4eZiI`JEC@Mq9F z#dA2AM_};CnL=y0#tZALdB(P~Rz*KqGqjwec%Fy?K(PGoO0tfskWw-aGhd7$ zTi~x1G>4h5q>ek=tIoT(VBQxrq)&#`_0UHC(j*ZO%%}%C)|EzTWEpvYDqCYXLexR9 zlww1ESB+IiO}=oq)8WZj%cY_FTQcEJ`JdABa=_S;O|kLhX*|5|D>0c{12DoC?K95f ztNxm(sTU6cWWd$tv`5X(=x?yAo)IYQ3G*2+o#|EfXko6erF;M4Pc;G0)pUDY)t`H9 z76Z8V9HqbWA@!`BelAT&ErrGTz7}%M*605PEY@3{gv+`yEhr{=EVp_tU%`b54Pn4a zz8nN7`eNx=*`f1t#^7>7G07IEnbnn&`RWZ}4Cp8W_DFDs-5)GU`bw}uBmOQfKmi2@ z(cWWmvHFTUNInRH!0y_ZtuI9Eh@O3+64wy-_2DF~E@KF3abM`0gC%|kHi@&hP_#B$ zLN{Z?$V_;+h?%2zEC{2ITyWOup*w*K?~vpwB(DX1i6oY+F)??;nyHpzaPLIt6G$4; z6>iAsB+&&NN0;ObWVOL+-^ZwD?nHgY>0k>0I3iA7o)f# zN&aX$lM@r_Iu|nSdPjoF{#QD9M6>|JSNPLxX^T2!jCKjS5mwNaO+SmBfOY z;6ZdwfzhO6Vs|9u81f4e%7*mU%8K>A7QWO0;QcX7W@|NSUVl)_>7VEf#&N6E~ zn9Wv88@Suo9P+M_G2(f+JFf#Q^GV#7QQ`qH#$N1y{A*_t^`5H1=V^u?Ec|EF6W+6B z(@Q8ChIUyq;+I5CmjEa1*v%d5{WHyhcHSjQuwzQq?;^BmfV#okq3v8bp7dBdk z54B+%D3=JWd-2w$)puXxZyZH>-$O-?tbSIlGc{em9xHN!44iaCr}6uZ^FpN7IvNh8 zbp!%4xR9np`>AOEd1e2_y}xW#v@@h3wYc?WiwL6Q>fxPQA81V^J)XtGs|Z&er6w~M z!1Ph~85TMG>R&ixNUnevc(w>fgb%+X#Wds6Yl+wH29aE%;RuDeZz5dEt%#p&2VK1n zKkqgl&*_YwnO%9`0<6MVP=O3{02EcR7PvvZPbL2KMuoRsU|Y%zw38qeOL#!YFp#_~+rtNJVl>lJSh_*B0A6n3XkE5po z9RpE_h=pnmDJFX*n6wmsWJ9GLu2=L8y!_R;;Aa2Jl|)I}Qff&`Fy@iOhop8>Y2{F} zbVk3rNMi$XX(q1JrgcIhC08@d5Zc>wLUL3wYm}hzS^!5d&Mec$Sp^$DUS1lD1>KAt z|Efof3nJ4^k(WKL_t-u8ud4L(t>q#9ECj?v#W~W#2zTt>|MCh&*H8Wh1_I&^2Li&M zq9j0`(zk~P7}dB`+15b*j%VPGr$;@4MBQ5AT>-y?0Fxfr2nC1kM2D(y7qMN+p-0yo zOlND}ImY;a_K$HZCrD=P{byToyC7*@;Y$v6wL!c*DfeH#$QS6|3)pJe68d>R#{zNn zB0r*Es<6^ZWeH`M)Cdoyz`@Z&Fu_^pu8*089j{gbbd!jV@s7`eI5_X5J3|poVGlq` zDo9}G;CsjW!hgN2O9=1|GpE;RpQvrBc+&dF)L>V&>9kd6^YIL?+*WDmcQlvwnq`Lf z&N$gF>3+E*NcJojXXI^}B(B-;@ebpVY}l#EcDWles7s;Ft+KZ@m+6FWaD^oYPBXVw z3sq|aKIDh1x5Ff=tW$(LO|!e&G?Xvh^H!GfiA(emluL!LmD=EV@|u|8S7w6ibUePJ z>{sOC6L27R+b&}e?VH;KvV3a;O3G=gwG}YzrkSTV6(&=;o)EV~2OD(Eh4mu@K0G)i z3#44IZhqN6+Hb2h#3R8YwJW7LesDA9=n)75u#46_ZmSh@6Q-4oHvGxFPY8x;Q+)d@ z*-SDqhVeyPGkoD)iq;z0r*M)IhY5I>gMA@RS&EIYPq}Z{$Q4Jbfd76EVhSF-sR^TO z!=o?>V(^bx!pG$26J~Z>Tvu&Uu+0;>m+pg(fmbu(97^(OHBH4;J8WIfv-f5}VP#VS z$Y$}SHKdphDUHlbdIVW!k$L6T{LY)|H}MT=l$22kIl>|46FK9dt$?3Fjk2RA-~AX7 z1|Xe`n)%h~e-O_qLpoFXJ$%gmocq`v0%hRw1k_6nh|+3pvJDy}m)V|xjL&!Z6?%pU z+m)r2*pWjEl!etAYxdzWb0{mGc;#$>rE%)b z@Rnj78P;$lrzY!XCa0&x+8a^YF*G|Q|C}bGeczz(5m_gq08wJHIH`WqHH?A}!~_3{ zQEvMXmL<*nThl^pL58nbHgQ1n9cYmN{C8J^6AKS%?~>1DCt70Q2Vp0;E@`GF%Tzkc zSUt&LJ=wHI6@#8_%=2s=j^4VBd1-h_)3 zeozYua!|{x(qk#z;tavf28rj_5Oen-cYG%;R6I}Hz$yMXeg^)_$OUUXx1r^qrl!DG zYXkAXKBMrVM-rJwAo<5J{NW1XJhW;Nh*&`nFV-Z;Vd({KSkMxV#cn|bXJ z50GtvFE##sqGhV#lv2s6?^yeBShlhR%XaPIo)iXOue}jwZ;Zq#dgDn8H?74Y+$Z?C z2Y5mCC66>dp%sVMecUzCirWq99Ea(TDwClZxtEB~4N-2JmlH#>Z2jOcaNaw4tn?P->BBGNHxUHez7>C@TZNT5Z zHerlG0a4~06L%>tn!~$s^L5`~{ueLZ5?`$46nHvwKxM0V9VQ(k{A40xDVw{+Qt)RV zQ)T2Df)cp0nv!lUFt3D=i~k!V|7dUjpz?K2ZiynO)$d{2*YT$N^CQ{t=luZ>WcE!> zg25p}If9RTho%G@PZp;5zBwv`n+e9iO=6dx1V^|4Ty%`oE=f7O&QC^s!4MJ+lMG>^ za!mgpz*^SHT+M_zm;{H#E~SaU^Kn*y)nTAF*2@t5mF+l)bte+a+goaA*zXJ4P)H|y z{4OwbJnIPtMp4E~=64gM-Y{#o{x)+8YCg$C7Yy=;9hdyBgRFIY2_L9DL3*B@%$5#m z8P}+)glf*}UPD$C;_yntx}9VPmSSnY9`Thd09nfoR;3`kar*FRfS)`+as*t2l*USWgmaZ!qFubr1DegTGZspyYMgic{inI0dSt+rJR z((jjMrdq^?VSZ8FCO;0NW@>O_b67gDHP%W*^O?J z91NQ7ZFODMSvHj3cvT#6RJUF7x=-BJFQ^6<&mOd15Z&M!?b+3Tg!UcgldD9tOAt5K z3X>MlE-a=sj;K&}sSng48jQ7sp|&u3;@e>V4Cuf(!s@9lZ0Cg^DKWmki%>$<85tOG zU;e{%zHU~KREBUg?FbcseK{lmK-`*S1p9j_4hF=F$y)NB;HsHwuf_A0Zhy395eU7o8^A zi2t7Ch|KVprUn03N0T2XshT!g$HTErcQBBG=TWaHkYtaI2CJY7ajI%yr&9 zVC^zJ3WW03bjwGNx{l}#+D&Ml_uI4PQhV}qZPXOP7ffSv(O;hX{Ff1|HoA~v)V!4y{CdALyi2YPjrRVmRYilRv z5PSkj*Z_8Fa*sCqGN?7YTnkr9=i9X`qcw7nqz#{bj?B7NiV9fWF+%~Rb1X@MuS^Mw zC)d#K{(-9!?xStM2K5x%x~ogWxgIK>s5r_RT1jU_lxdTtIEFWvi4eJSAiGec&HXQ( z5t7!J1b#SL|8s4)u147PWQUq_e33!5Z#f$Ja&az)(Htl`Z0@Ez)0d74BzNHHfH|<-8q*ZMf?%eJzoGS!0S6Y zSU7y^1+;V$Je9F027>1eN#_tz+2t}Y^N zYfi9}J!N^SU1CYoNBDbD39@84xLroY@0f%%c^(5CE+}!b5-Mt3oXe2nBdyicgGIL+rzTTKv`}Pp%fG1f^s?sgNH8=Q}s4Z>0ZCZ8ZYF z4og8nK%OA~zZMJX01uFtrmwhcgg*XbiMP9kfkPYFASbp7*Bk^5ZBzV)dL)JhPwDkM zkgdHeKw)orJcj4^)a^wQC2|->G=OBzuc-SskRrrf+H-E%HQ==Ex}d*504#GbIUXIB zcZs@Oo0i61MG}&0bu%@2N?MMJMRXyTVb8@3wF5eY3G6-1NdT~{{~YFs8f&SNebdaq zKmP>XqCQ@iaamuvY2m%xJ~gdSLSj~DBhB`NCj_c}NbSjB{r(E`_-+6a#vx*|S>-GU zHsw^dxxu`e)q1HbH==rLFap?cebKumnTo=iJQ zJD1#=o>0%Y@&jP?^)Q5bTV!pzrf=FoHq2c_59pq@my{D4AW8VU*7LVp;LF-qESV;L zClRfyQ6CcD$sd84K@e@p_ALH%j(Pz@Em@QFyY`AG&(|!(cG8!oV#ejr`y(LolX}Iu zL$)G)8^y4sUAYCWprzVR?`#OJ%NU)9U^B!OGSj>Ly;<)<(nNh`?z*GvJ|ZBKfZ`0 z=q_yGHWPp~R+J+{{@APVwmp8`=%N!L7AT^l^oaM|JrCFu7J#@frf=z(vGq2>sQ^@u zk=^d#gDf}ME!~9PaLfw44~rsG!)T7h8~dY^VcZQa+ueWPGG$mWXB|H2$$0BT(QAIu|=DJXPQDNes3Q>-|Mh=Ih zy{WR)QmhL5rQbBYPBa+e7)8Vo;_aKrg`}izmN>#ATuSDu!QUFA zsgM|Kv@W(S}Ag^6e8)9pQc@JLj_2ZIkO=8)#ARm#mU=NncWbmd-SbO;ad=y|k`shy3b z*8o0@EJo3b$#zSgmnlT7KAp)U!qI2M`hiC@Gp0)pNGHYMe1$MBNE}Hd{Sv^`wI7>MzNwgVv1ZzL zttmyv!=TKuPH$b>r7$lgP5?vho;#Ks4+zLzaz-1b{p-Fn6dWy1Agg7O2{&VQ5@s3A zAqzC9QokRD59!@ex#k>xy61kq6h~O$lb;lB;Q|chv&wzR+N zgXdIo%?q1Y$TzsdCo+n$^NODN7yd}cAv+rkG|u-(wTp?zUSUxaA-W3dwqikdrokwz) z68)Gn$Nwc1zB$F9`#(af|C3v;|2$bo7fU8f7h^NK6h&@xi2m`)g4mW$?l@5JEc*VV z6d67@Fl2w6mO;MYUl2U>R996gQUX$d>$D>)TNGq*arz}f21yh^uvIM!3u$H{_CH5! zrjt9L^&J8UqEV_lLn&}nc|Q=MDei6t=vL_>X-i8B%f5FDi)|qQ;2V-T!qOi*uqq{U zElET6#2cb>Z_6p_vw44&mN!;T&~ubi&p`XGepCNAfa0-T zC84V@VN^R6%z({m=$%iXrbiggxvMiBpww~ktD&=9-JPK3kPCOGCJNQj8+l9k#!QeS zv3h$Ej>@j<-zBW0Qr`5tNQVRfYK_$3>nWUzf&c*tCpl@aYwa%b;JNeTX10OevcxY7 zqnLgKU-X9G8~&?Dr)`*7GryqhN#;9v`D_c=_xBcD{j-cLop~pSnM?&7HggX6gb++ftBq$idM1|>5t+68sWf{ixREbMkZesmpjJsAFPQ#2+8Uek z$BPbu3cQuNDQq+^M}&ZuSHjxUgxOjF<^%4 z*8lc$CgA<$n=DYg_DsrHB7zYM0Ro|gS8ZnUq$u3GQ+{owv9RdB$wG%d-;R+I>?i?b z+r_mu{IL6WTYftdz?0#pbHkmQP31LvXcMK6;mAP+;q^L@q}v~TD}Ni>f7@QYcbM!T zX5kShHv3X1U=>B!2*si9=AEJCBt~GIH7DL4^+gHj+q}tk0F_?Q-=z{JY%77nkw>$F zG}6ROaL_)3t$jX=ZtFG{Q=LZfNjNb2LK=m9l|7iaB++N|S$vAr1 z_gf3JpIB|?dptfQ{sOZGlhyj~D;T#hjaNh0X5(o&7)87^t@@Hteh{0DOM{tCu$l#& z&NhA&V4VR}nzZP{7i(5bGB17<7bu+RJ1}k}=ffSg%=+213Oy@Aj1vv2U>U>8tRhKM z=*e<21)u6SSb{CC&We%#6X@duqLWGJ>O)Ls`uM98``34g11;D}*7>c3+^c|Os&;t}`(BWMD zfbyr~$j%{6%DZ`kR-}s~p?0#&-5a}b?6tDqwtqY%ep0ypSRIB54G@|0J5E#LkxQk# z_&xE=d(U}q?*Rh7L7f8AM5{qdGpC<&t~9YI!%j2G@nUPoLPSiWHjCVP{JAe?cBjQ zTqI=R{nv5c@|R)8Oi3cTL{&6%XdTgDP4CNYT}q2f5|Xf_hID#;83kd+v0RRyNKYn} zyPahwd=4ncDORLvatBc~KzT+jiiD{tzd3d*T(f7ayS;J&I1X!xaL2~POrw2ST=Pr5 zu*c}fb@)0P6jv))kNl38C7gmnWGmlL@{PWOVYt9se*cS0w#@W=N+dY#V08ci=Zmg9 z+${f#Qfs5)hOPxC;q{(J{Kx4HF)2QMzlVtXz0-O&h2$VxtT;ROvZ13nN{IG>Asv{% zHuDqgZ{R2(X*hkO+!HYHHWvRYrvN9fl-1?x6b)oseZY)@dQ6O>9Y#8*23~%bzN~Nf zpHGMdS-G|%F^v3Gnlsc$s4Wl=ZEu+J6y~*Ih2tpmHfO56JXKjldm$BxDvW6ZH>JrU zdRo}=^466lAq6!qY_@nQ}5ETUEoF;`>7b8W910_Z17!r`D?QNvC z+WF%@IkPi43n4;0Ks`M{x*0-^GK7oCAp?pFK1`~RoMSe@jAlV8vQruCUNyQ_7wk?` zSKe*|!4ar@VSA}!ThlIB*Qa5){pu&HS!a)-{lWL2@o1486ZK_!!}FSZ>vyUPIOX#+ z5d3~J24Op?!f!oNytub~egnkB`}h?eh!QyX6&^LbNuA#9vH#N_7IL|#6kIDhLL=be zEg3Cwmw{A(cm{&T zPg>XIWX24$Mj_#^k2I91C@h;b$8WNVr&MLjEwgAUtSeJ2W0)6Fit}PF!K&1j=*+6g zL{XOUrqhNyPLemIF4C&hThR8fie9^fYg$yl$m!1|YgcPlO>TB-(X{lkN~X}R=GA!Q zou<9ZJV6*}SN_4WRsqzRGI&p$;9DxDFTlyPw6Q9rlo@E3tMN&Wo4eFs{1=RCUij$V z`8)kmh0fhTTiEyvRl90B%q2(Moh$jg7{NeQiy> ze!H{zbG7<3BcK}XE&V_1kFfGA7D^ODxn*@nqlp!{LhYb47zIUlV^m+7kZh^a7L1^D zvI?m^9PECMnnN$0hi^Ur0b-~QgEORanrv|`dd;ek$4rAgEEof3HyvuYoZ)H*;+TgO z8CJY~4YDI^7RD7O)m&2h2K`-4e-I$1zcZ*K>Cd7~sSxEXc{d7-;f z5Ykr56Nkie%=z4_LIA}H>c81e$%ey=2hjqzTxoO0MDe!J&PE@EmX49jQJJg?HNw;B zHRHr)3do7CGDa3lPAZ4LAnpT)spnk8(ZiFz$|F$1m*A@!qCPug>Isp|MPI24i>jp~ z((9EQ9W#Rz)0AYT&ZWOWKBNtdNYYm2QytK$o-_|W5j7Abr&73(MG+Ar4K!Ij=nKu# z;SNkveY?Oc!I|Vta2{rb@c50#p_byn|_tu>Pv}6YDydl|}X#4oZW2 zvq)Y@8iG5@6c3?uu4vdLSBq23P&qUSvtGcu_qgH*?KfaT)@QueLx6apA97FI7sXP=foe zmrEu7;%Z=yTTGUsHsjR(wU54xNPI$hLFZUOwh=uhZ&rLammOQ?w*)}?Ah#%&K~OZc zl#Owj1OCEeXt!ALV7LgJ=MVbCo}<%92WX$wCS~Ins}%5+sb*C{WoOT5*2%sgjya;~ z|A#;k?j~J9qB)Tku1BGX=MrZ}<%Z4}i$OvCHv_3vtH_NZoK zjJljjt(~Yh%aI@gFnM*e*@_*N190p^@w5?SjRMb66N_^3EZ#Yoh<8FM>Yx$+mTbp$ zjQQS7(rs2j^54CJXdkH|$1&$wPOGDvm^@1o1pl9~!5&B+I=U-f_M-M&r3zfp2%TH%Ib3lz-^t)+Z9E+>W1Bt1`B}rZ$hZ3{0n|nZKM9O z$?_1+y}fB2$zEzE$zC#46=0E_4x7-VXY5}<+d!g2+Kg$gvU-Xm-A9DBZz+bZ*zDTx z$Wfb93))oLQf;wKi5JBJ%$yq}m42lacy`bC9PjFg*}pCnqn@dv{k9WiwCC07;6n#e zJ499v3YGQ^WyYY=x*s`q*;@R_ai1NKNA}<6=F8IvJArr{-YbdY#{l1K{(4l$7^7We zo~>}l=+L8IJ`BhgR&b$J3hW!ljy5F`+4NA06g$&4oC-`oGb@e5aw-1dSDL}GOnUuy z)z1W)8W9t(7w%OCn_~#0;^F)xic6It5)3h);vuLAKFS4b)G;Z$n-R&{b6h@yGxGo> zT-cq0W7~n+qN10;1OS+*c>H$(GoKq4hGG% zL&XJG$PDQ6K^BD#s_MsnlGPE+$W^B`&a+Z+4;`*nyKil99^E(wW?t>#V_xYWHLl2} zIV`uiR-__g+<&m#Z*4E|wjKY1R2mCm%k2ayMSDw`Rz_KA!3P$uIbB`dl`3&A zmT@gMT@ZpAxBys8zRtgoH+ebSaVA)maP?G1=G4x^Nw3mV0?qehWL35vMI~p$y0hGL z6@vHf-50P~uoe6yY&*D)Ekmi06LF!Jqz9#7kMvWexYMbAn{}`{3ZBsd6$5jBCujDp z<0N?b*1%T<-_Nxh`lKtla|FFqs7RZMtjHAwZ0Ck&s{x`#^S?36BNQN1JU^0f&TRoC z$}c)LW7)-n$CmAg&n(96AycC4!4_*D(~HvXyLW>HORuI0;ny$f9h{!Ud0=X0x%{l6NH$ z?lttWn}DQL521;-r~Kf$N_YPo)7H>3gI@Ivt}GnR=8W~Nn7_PE_3{sRNn`R~bs`g1 zoTh`7o4H*TRp7VBp=%>&t&Cd*Ny~@;{C)P;62d^dipuJYUV3-Dh<#a&AIxtrmX42( zYEH-8F3|^nY-=yw(?^d!hTojNxr~A!n$Ao+2mq*kZ&>Zm+BDC*sul=~!LUtWiokIB zxc(dNwyk&5o;>WRt)Q-Wj;fvuvJO&DLPe%mt@t!Oq^VsoIN0iTh%fh#`-{Ha?a8gf zj^yA3`=_NEONO0Z?}YVP*dL{T}v|A&cE7$_0G=g;1s*WDQuRcq>cJ?z=8b5&i<)=3ELSW%Kff zs=my9Q%8?aMxZeDq=RBHg*&HnIeQ_}X@oh=f#?C^HSg?1dwLn#wu(o^uANrRZD;H; zYbOec$#wJB(u?w22{gV+zb~pv|Ag!q$N@^|6n+FV5-X=lR$jajjeRh$1tjht$URz1 zhw)(ksAr2;QBXH9T#A$6V4PsR7K)){JQb?79o6&*IwDPZknNqySIa6pwcs)~xN81I zKc-GmzZ$i(8RaU==$Dx{tD@4nph-V*=W{Ln97*VEN^F+u0!F<%$l=K`ikIp#<^Yt} z{rx1gk>;rVccPIo6hD=xPQ$PxVwl6Cl;YI6iLf3!aevhsyXXZovK#TOv0|*T+^ii5 z+YO`u(SO3@ybv-DG)w)E;@+ULoj_+<;mc#iW8{9Y!99vE`HdAK=Utac&Eq1uy!TLgOS-C1E90Am)B{Tiw z$>$Er{s{snLEaO5@u&zqxE@v;p6D&?u@40t{#VNA&7SZael};kGEwnHgD4V5RNM@g z(EL~B=A8&?pPPW-fTja0Oi6SVtI_(3ME!qWLg-uK2afWhBn(C2PAmUyu^2h?Y402i z9P03g5$1#etGdUUo?#skjQ|$*()ybRGMXM`-2?jjThnTcPV==7sg$k{GxYdF+S*zz z%dtBo(R9!7SW6Utq|wFpsKMSAH-x{WB|Cz62A8!p8!kHz1tM=9I=M&xqQG zz17xBW7t?Q?C%@4YC`p*za(>hOrK&ELyDQu{5ACOg9noZS1SGh{-FcLy_W;nf$N`N zGYxdIzy7mL3K@Kw65DmvPH0@&;T{y&jP^AsaYENi}q|A z3}l}5V?z_VvpHf%CkpN@IK`czOuLPY=yBUf8Q3b9$X|kEiYROV$`T8T7ZjFPvKhbK zDYxzz99JRNzsx0f1Y>IrIQq9o+W(TsB(ZtN@4*)DMGr3?4~Jt|37IBI|7oQknQI3X zAWs`45xiCHga9;8+W{|!Yy>tic?%SNq=3EX@z2Mk!P0dKG0NCHNz0*F-a z`7K?6d*D4ri*=>wyQyQt{_t=t95*gB1|tdTg45fR{KmKD|3ZuM$QlkX{-tUkq@3Qd z-6X|jEyZa@tuxB}qrdlJdc0{8``%3M$xl8$9pUzkFa$Ww{Jocp9>;5~oNC8o`3GK& zy7_X8YoQDCO1TU_a%#Q+rC?Rr`r)W8CdpEe=>uMYDx6^46V_1DthgX`6CnF*E+%bY z=GYih(DizXEVFDuQRPQY&dc2p;Pwo7L{I2r3;QV8IEPg1McP{PchEUDf} zbtSAoBMPt?&Q@{fG_3a7gzHl58O7e(h_F6^rKgU=a&(^WpgH3U%`tpj3CMVRA-uol z(hA)(VF{4@`k@PREUQJ_8w6CcMW4Pm06{fw^*>aMH%#ik6lD{{j~nT}Vw=wZ(;Ct& zi1nt}RmOGrVHP++5;Z@eE*lkdw~?>AJL_Yg!~p*adS_s1`_oT1B26S zt&1-4twO45pMl<5B9T;SLH9Q?E>dBXcy@5k-{YQ5K!A`=YMYMlLOYc(+LdC<@@UIZ zxq%vI<;6P)=W4nRb7nxQ9KGzXsOjWs_3V-2*V+r}?dAZA7{7f*>^PxEw|6+WS0wAs zen2zj2cFKIr`~Ai`YU|OR4%DQw8uM=|g2B{;1Ho`mx@??e)rX!p$MSlA70pKVcvZ@|fYLpEV~s7G z>#?88yv{ekJpeJL<-?FY7wf10XpS{B4}jy{uc)7esm&J1)ZYt5LI_{)0BkN8Nc}ep zg%SYD0Cub3?KXLY*-dYntrghE|}%?RY5i3yVcPFlheiJUMLIr=Xp=U-^siywr8MF^JAEwl2uQ$VIfuDFPisd}4W2ZxY$C`2`tBTA~ zG2P62@*~(9gYmO6#Ya<1TG#3rQd0BwVyNP@Ayt7B(h%z<@N>Iz;|2VkT8T3`anW@3 z03^F>TCLS9Y*sY)#=BX5!LYD9Z;z4QSOL2^Zw~0e;OutRfp)Xu83Yz~srLh8rR}fp z=#yHH{&=!mHgDg!b;9K@Ux99VmQ*K2Xn%gV6YWHHw(<_uA&($p}$2U2TIs7y+ zM7X5Yk#^wpDE4kQZmN3&VC{!nno7wD2`bEeAwS;W6>$oUt#~E57Imre?b54{c$`tHdB6GMC`IZWLL(%j20Bh zW@}9_@4EsYT$u1Q3ZPWkvYxUX{6AcsV{;{1w60^@wv!dJW7}rOw!LE8wrwXJr(>&Q z+xFe(e7mP=RLy@dYSfEoS{pC8KXH4kGf zd``z`=z(*mSdLiXj&Y{>&akI{IMzo@tD>a^<(r*Ssf6Nz;ZsaLra9mcD`MN8$2`!w zj#+BZCrV}b_c=qEqt7{oF$>wI5*0B0kP{DNQ5_-V9dZ<9u;vm!(L2I_#p*nprX%tU z!{;Gb7IuVBg7pdB2!{X!ZgHqp5+?drImJ(UE6~P2|C?+`E9th5QSv!}?=L}=tvcFMQuyE`=pek1zbRxBAFdgqqB#0~EkA_CpTe0`e$i(eyMD!C!D0SjSaixQMIl zQ>-Dj?K($9qMGwhRqIt28n$`*FH_6v*JjZRnIMxz-qVe_KzSGY5Ph0$(^e$r-hLD4T4m@eV#69bG7_fQ>o`!yu97p=$)>fb; z&!>)wS*Fj!ag#iKWRWiC735;`@XxXFT)nniSe~^1r0v?bQ6_Fokmx~(-O5D{7$d>R z#Us$PxL8^}t1rpnJ@#E}+O?`@a4wB;n{#!lX6WlOwo}C3TgP%?N=BT*FrxR=JR(g$ zJn3EhTI~xj_mVxhFImqt22JE`CI;B~Pb~*cFE>{uL*2mnfeKb_aYO6sDC{Khp%ba`v>+M4WqY2KK4@w{=P~Tzx42!1yHniJT#~*CHF5|TVC_n_ z&;r3b9d!f0;?+iQ8rT1N>MM-D(HQrU-WWU9=w|>nbeG#luD0;ayPj`4=&7Ik$Z{Z3~ z!oob~d$cMHx9;vjAfJ{XC6R@pzkLW4q1ak{?IimWUVBKithq`vKQD14&60gGKCCale{X}Ft0By269l*P6r zuTm0E33lN!&zezRh=5l@mQP_RAR5sr^}&4j;(eFAj2@K*7>|(4IdGb4yB%g88|TKZ z^M@nOtS|f?{!z}s#}S=w{R0`LbVP{k5xhlw?;F>N1tIByWsnp`Bg)hb4sZR>Y12=3 z!#Anh?EEZFm==f$1I@Zw1Y6-%6aE;!l&t#!4vB-%4AfB{X;!sT(jBKx*-5qZn|89Z zK%Is6JLf#w>eauBET9VUE&>aD*^+~!ilaiM?p&mM&kqY3D1*5QUGBbUOI)=eY1dMv zJ=ybPA_VaWPE1+MDhiYq4$DfAeVIv!IP-*#v53?V-c^a) zG6p$+O#_1{V`nNcS`{^%iBn8Oi4fO$#Q7x-$tp2dRs-etYmui-mt@P{hh?ldJJP!? z`!i88d>h`9rIRd6=^pZVuo5}3zUbAX>~uzA4C%servKlplCW0(Ta+B&Eey1CQ5DDV zf2Mk*YRAVjE>){hi_9poOCsx=BU4gQV)kovP|^v!npW_>^LFUzYHx;MKo!BEj7Xy9Xg-A6>kWs*$)aMAWh^_0Fnx;eR|2;L0ZjLl*+F1Moh4?D&8h6H6jJQ+OxgwJV51#)zSmqvRnQ5 zz~62JXPCCiwK9W;yo9-%7Xka%OtQeVDK5SGr51}$q@i)OE>BHgfOFiV%SZ5E(VC*q zYujoHFnnF^qs^WhZG}uBRIs4{4xGP&Tbtr=RJ?=4?;IaVA9Yzp!}H z9QDT#L{7Y?)r=m^ucWOjUuJh*FSmqL?!<1x{iOcP?l7BCorp91#(gUNGIQf@1)d1lXx(RAI zhm*TFNYgXZn_A}FPfh;WMHE%oCs8d+1emobQCt@YTjxcWoK81LeXY~+9)^+UOmeCk z)#LMg9G1`jWr;WZrrR$Gwve9&X+lKpB~*OkxAEnRpO&^BwsOm&TDeQBlvTv^nuju5 zyB8jH2{_Xtz=1n}8hD4nhhZvyxynbGz%2iKM-8|$N`wX8O-Toi=&@x087+joKHd4@ zsx+@?mPB(R?mMWCIeejm^dhs63ARzdm}jsA(O)QqT|m}QRWm-(Hzh#M1)wVV%1iJL zg(a=;b~-ZkGDk#mk1~G*z!7zGrRGL-8}=VILi|%;0knSAjJX1jZXYa@^cU6K|NAIP zkrpm_?r8?!`$D^>c>@hwX{b1l4f&cY;wwU&Q2vPM9oGB`Uj2&haf>bY84LFfn>4P} zUwt~VVTwui2oj$uGt#`OH>|MYjm8`R#n z{C%^u?$@fW&NV}iCuMF`&DU3gT0TNA(vM@&mV$M7yWD^p3 zN996Z8he29k4NFCg+9PbnZ$<&>5-W0fbtK7!ePTkfP37tvtUFQiW$|1%XoEZO`#0Q z2^XjxY40!DruxCn-p%m|j1RfInIaROco}Cf&3zhkkBHj&Rt=WZ_VkNJdliOb-H{>p z4n>c+XW~q#1M6<*boFS%=vdUE3ndU*iM+EFUvAM1=)%}A49e~^iF9Tr^(nqF(J^n~ z49*I<-WXCZ`1EG0hYOd%nsoM{LT8_q$a&QSBz;#S3YCwj?)0mjn_saa@O3c^sMqwF z!ZcWHQHCT~S|SVe5eVTt=z64&T=nI)wG<+4e2@}Gp9#uWEM+p-{L1PUC zM9N-bN73qWRRpT*YCLuK_D+uRgFcwsV}^odrD$A zI~cJDK#5qb8UPL(A_=P(=)Z0U`Aq`WLGuPhE^-isi?g-0`OZ?4kK^MyAsY+mxqt5G z-B14#h=^(sGv*CF8}cd}Xwl*_z1KEt!uP`_(wPBT8=FmK<+VOOk}fZ4Gj*{W-MSmu zygps+?d@%?tx#Fn|0(KF86C^QEgcz^1&!sUz|u||p8_`(gR(h#GELI8FrjSjfNCc zYJ9BHx9555<@$3ttNMYtIMa?NQe?V&_luijx2?!gBJ8tg}l4R@z5x73q4 zfZVtX0lZOzVV%@yTg!w5oMcYuMfGrD!RFwqChHhY`G22|vNLn!6a7VRi4gD!@Ae2K zT6A|%SwkYp{k$!ki4db&5nZ!Hg{8dj)h57Z<$r$9=s?;uzmx54DcKt)m0_ow(XjO@ z{}vbrW9)Fk2;8-9>tkzX!IEOW7lMb$gf~wwZgu2{whBB$YvW7BQSPQZQDy~)5Wh@8*P!VrB-YNi~zFb27ia7UtoAd`4C|JS~iU%&Qw1UMjN zC(CRqwMFj@{DT5Q%Z!g{RpCq?CpzVQqdKjxHQ1xa=u_EKr1ec5)TH;7hvWIn?hs@&K~48_$RK3+ zdu{2({Eh&7HD%B{)|+9CYaV^V1<$`JDFoj0UB!kwzCp*vlO(9kJe-Iv4aj7J^fJER zTEQS`H@RGhfs9w?M)S`;LliZ`Qvu3g2?r)nr?wT^cRJy(wBCr0MDqtRFHm$E%-!6g zMLRw$2+YPDN~0`{Vm}H&to@Nr&fF{~L0>m}Ghn>Vj81s`EIQnE@l@Jse`#}N0!!DL zkzs?x4I;fLH-LS+=E9Vl88}Td=@l&5&xyb1KaYf^1>c=cC+$#bcr7(`-gQsjD7Tws zxszZy^8Sv(2%nbY|4UVV<}>Y_l1lTjrKy;Y5${ej*V%OT0+D~Ec3-9;X zs?8%af6+X@s}jQO+NREG?W&1rhl(x1!Yfpt@?JLkH~UV_9l*DG6qvuakx_O+bAq=s z({A;t{jPMtJAA3|O@KE~J3M!)@g5`5KHrMBrNC_Vh4B|&pimlm=+i4!K-R<3m20bD zzS$Ki+QfH%hnUo)1S~{GWomug`!{WD(v+ zuvqIy(f7nrv3AgZ=8rf6?es-84@=OK6qbY0wJ-G zL(2?kPhb zZ{|(D3#69jUn8s@S7FY>F%&HMCc-%c24`6k2TkwB}T>7a66k$Rk>2x3dp&D-EP;6vCr%iE>GKFx;(izH3Le$SQsp0A%5 zm-Se9<@jb?{00JSx_;^KuDtmei!?oLZDoJ59(**b_6Y`2ZP$kvK4#2^Lk;B5oCirY zRlPg?{iEPr_J_ES2=O`sJ_qloEFsXBDQ+Z4sZubH45vc)72Y|~@)oVTzXL$U?w#*n zclYx8f%j*|f#eOo&_;}Am3`vA@XpB}-9L>H4kiQkO%r&~{%W@YWSeD_%B5+F67d*j z?Utu*W~cd#8x`Co76I~a0hZ}GzEOX;;hDT#z2m$G4zcHYIefxJIe3HizO!1pDziPE z*|lfM&rHZW`dhSY#7rpieqo!w>m&7!e)!(++5So5!vv0pL0Wxlkw z;_!rN(U5yR9=>CNO_J%S#)QEl@X^i< z$-v~-byW{BRXav4GT1VHt3jrFK9-@DZunt&iHnR->YIe?0!h%8oHlN&$VawG{+?<< zoY3lysffn`42Anr(od87p_%kBvtEl~1Jq51oU>0Cs?E%&n0t{t#)ExsgW$H{YuO*? z(`4X_deFhMU*%36&*Y&?o78sAOZl$&98gl@b9zEa>Ul`Eht&~4&@b1AzPD7{!Ati$ zwXVr7)>u0Sv&p#{4{|Qcx56H> zF?_X1-NV9Zi{jD!EQY!op(nLS=XU(DmJtXhf;wDL&4dvd`O>zAaBzN(?%law3sn1p z_#_Z!M+Gw0@Qk>REY&5+l&ECBG20Y4{6#618u0a_FxP38r-^@-!(PFvJl*UdjdBDn z11S4BYW3AgDE#Gc`TX_x<1XiTCER)+z?$_X z7n&6Ev$hKOggBsrg&CpBUpqPE1~%I*WKQW)@&B^`ZW5)SBHYAX27S#;6vo)8c5BcH z!iREPvmG%-xk%IahqAZVSke7KH%Rm!>V_tpH`>bSS4Y|tT-m!g!=Ni9VbK>Rx}WE8 z1ss1w(!|#dy?b|&w)Q0+&&lInD4O`WjJ{*tN3GHw8{8SD?rdB!ZRgxa1F<=81)1({ z2JvQ>m?i8VI<$}9MmtE)MyKN(H%%Ec)=3jmP)K#QS&7qL0o;%>!jhlVO3 z&jsJtdo5DnGgt&A^6{Y8a8ne9+lmC2B)oq7mWC?KoKbd`r)Uj|vMQx$o%)qPrk?b_ zW1Nh}Mw*Y_&LN|blw(R7 zFqMcuihIjBcSQDyLEoxd@%w52JEp%6+H?S#HPt_I1T@F@jW@935OmoG zE^SH~5V5=!n&E+yvOEFgM<8j%Fift}(j53d3V%1r9NT`}I%2p0$%QVx!#G2{NyO0x+|GF&XFcta601En$nx7I1 zQqAX}hG!*oND@sdrvXZQ=WU5MOE7QtKbgX45%?B?waqj`sNjDd- zUTH|{!iKvo{j~L-X=^?Us9D+2O!SG>$w%in^7zGGy+BMpnFr)#L4Zc0>7HJeEGS(u z(RiPD!>0L<(^-m_3%r!)MMdobk+T+6rOX^H>@PRjP^E3Fvx;U$0pz%a=(m-W6LZ}U zX2QnW7lPQm!-pgsRh$Rxq+tS|LfE_T9hZ*a3%%5EE8!rlmCi9s zC%T&Q39zQ(krY&I&{y3pYWA%5nHIL{j;9dmcaU{*@}l1i1fbF-HD&(6I+spEHr?l5 z6XUR+=CRY)I%wupKQI4-`6@A*Z2p1C5}Q+EOD4Yb@LB`10Ghl=YqM}RO`lWgijdXcY?-_PlpTe z5*pPp$8~kOI0r-}EJwDCeZBX!`~Vja_Xl`%VEZe$l0N#Q`pQFV5Kk9_nkJD}iNtEl z0C^Kr-ATPgZ(oeg!%ExcVXg|I_d=BoM=ZHAT`5PDZJr04Ur3RdN~zCSJui+P?cOm? zZ_4uvSbO6q9^3ohA?X&NT{--uRs)j1^n_QP0Q$3&rxFIzTz7O`nX?jRXhg1DeB#5) z(GfV1DF?0?JQ|Qk@MriD8NQBaWeKv2Q%Q{4hBkh-u_vne>zF%J~@`u;J25*=?$ zdhu8F1#*^Vel)g8@`n!4w}b9O5MZ9mGr6l(IoOWq9%{A1u0kLk75}< z&VTouJCQe<1WILdAsGA2MManwFz@+UBd8q0t~Z?>7i9wlMSc4rIngyRBL7^uYc7hA zBHUFVhg$Uoyx@ss=>vt^E5y7o;$7KRvv{t|CpAnB&qk`W5$c_mfC9N(b79uh8{1b@ z`%f{Lmb-*Z{$${zz}Myib@*kI7yMEizc6;Irq>h1)$KEnLBTf!E}{B15VVoV)p+aT z76}rh#zlkeIT-ez_6b@mR`!5_WT}T{kciOQ8yX_<@OT6_PmxrmJyWnWqxT>-Aho3b*pIl1(z(06k|pbILiK8h1e<%dkjsXB~8Vf{m4 z;ClZn{kzSkl4$w-j^Qx`(3BIce`g>_bgmJy8*cgJ=8Ty6LZs*o(tJ?TUi$1Et5WlE zPm1hE>IZ@-G>o3sf#8sEAr@8W4+aYgQTPkDDhUV$hNQpvpEmwC*qRWQY}4A92_0DZ zmPs>)&dZ8l5)X-zicS159QB4{Zwz=3=NVHv+vF*NB9 z1yz|msvE4PVio9vx4?D z{ZQdbB!aR@k>T3)149tjYac!k9CIDV$2WZDZLI0o-b>X4G9HSuePIX}6fDMrw_{k4w^WTJKctikHje-7u zn7gF^^f9vkrII_IBPZA9zyVn%O~I^a3h^!RY1?E;v_(46klc%M2I=TV%+aGbx1n_|{GwNit$QzspH)ZRKc+9Ky0a-Mj~~W; z9=1QW{@mQWZ0CL4h$4e)g#u@U;Tecj_=E}U`TnGM7>o{0dU4MT*|8>hhQ`?UB!zFB>>~9<{V@O>aC9U~Une3IWIR5R z_5_;sDvxI0ns0l_QeF?}X5QNM`1(*9drDI7dr~8llWtCKyo`HdZv%?+Yo+%2`Fb=5 zKSVr%FvKu>!KA)Y5&sPD zuJbS|=5`k){vruC`iTofuv9tp)kTGFd-$o@dfQ&XgVVImF;1#Xx#`I3vul#F$qWYb z%LOU(SbQDVH4RnT>9}Wa7hO`?yKvd%M<7B)^-9gvI0d9NpIMkS zRT00KAyowFDZ=SlDLo`s`r?978R0T>hJCU9`HXoWFBuyu7Ifhz-OU9hFUQuonGfWr zokmWPK)otgYn@!v?`Dtcubl8K1%*k2j$mrp>~SkW z=^_So$+T1|P2fC#QyVCNlVUHq?y@pBngYPoosbeTuE5F>N&Y)$kL=WDpkyH~cO!1J zMU8RHS*10ceS^H7l>?Ax-ySAEq;fFak>8M}foyYCs-;Rmzg$T;k1$Bi^ZQD=+=cv~ zbPGjC8@KD2%G>R7`kXxj(wO;v?YYy^+8h$cQIphb3NS8{p_AkYO+3 z@r-QEvcg|3shClf+$g=3b_M|nrQ|lu+E$yX&=MQ;_k3cF{6!0wx6Dg;;-oBc9EN>k zD#NH0R)&||qCZOZwIv9erOFWBUabK&8^iW^&#Oat0LxZ=F3cTrBau=&v4cK^>5k@gj#zWtyXj%YL_X!h>bYx@JNuVPpBwJE56w;HXl zZ1;k@d>8+2?a%T+rZv`KSlm|ckXJH62?JJAR z7ldHyEgPiZ7!yX$7!&3vTs-Y7hkx;Id(DrB6cEMyABU(*M((X7YWt-L#i`S$!5}fl zC#oXNEBbfMF4HSLYC0$tY1Q-u&Ykz7^Eumbt#?%(T*Y>yC7L`~p}oAkt~tH*7e4Q& z$EWB(at2C8c9em~sOw`1CvA#}IOF9Z2~%FBmb4G8IYeC!Dm&P!zH#Jna-NO;Qd{(7 zATVoYNg}*h`Jn02H$^WRu1L+psWjwYMr~!BZZ{afjMr|Rh^JQYjck*m8ZE0?)~vqw zSAykMDOKwNT}~IGR-3e435!bEmBPlvKn{**+>sru9y;ynv+RdQX`cNo_%uiQyM~gY zkNXTcZ~J38fc(I+Tg@T>ta#K|CyTKv73iu?Y3>J!+07C?lcTyZWvw|?(w33jJN{5- zynWxvFsqw231<32Aj^xVe zS{qBm^{P2re~|C%4rPHF|F>PqE#D4Gqy(PQqW(YSb36aV+ngr7;Z^rsa`1CFOVGl|5mBdB0*q*?%XBXPjPm^A~cwh}`D~ z?6gO&d^<6m>+l5?;>v6BSph|=1uthK(GEITC3RddQQ6I%I8e=$ZwLj#N5a1>8ivCg zc9PxY9k%zK80_2>^XcdCV4!Dqbplas_v^F62wKZCbfyb7Wbkyg+t5R?jVp_p=87)rAsVG;p?@}0DhfjF2KY=ur_sDRN5Z@ zBoczZ8+*l`4CNsWF7`5M9V-hSSKJz^0xO62%BvUldB37t{XX4Ba8~4nB7(_iRUV7C zZ;UVO848`?$wGFpL>#F1+QXS!7Eecu#h!577tuSg z6^-(>A_N+VK1MVMP=Fhb(cBTDWU#U9m4gz0I*3`Ekeu#d_-kiPg!qv3`67kym=Gc@ z4AmeEJ6{D5GT9l)0Nt?D)UZ!J6$_sfK%VCX&4dy{lH3oNgOFQ2La|}=(_+;?BPZhJ zbklwJ?_h@!#;1t8lY{2DbWMd63lRBe~A zUI018Hx{L;2 zP!4pmu_b}ynHxga0}8?m18nj=$kLnve9s^Ie^-H@{|7@7h%5N$^Is(t_dm!303><- zFJ^N8IbO0tDI&&}NbSz6da0ByoGx4z$_S2h1eJKQLn#puSq70^es*d-_l4(XJ#*_n zK*J}P(truL6NXuaq7uz`1IeN|p&1V&u2eyhN#=m1r|%dhlWusBQB&9Kj?1K#Hhvs^ z-dw2ubqArME!@rtqD~^LMn}(jgSFkP6{lq?QJpdKZ;mfckF6(uBjSn{+8(#`kG@;n zm3xcjQ0qycjaDG+MetaBT!=+z$|gzdx#dMIAswr_Th_kYiKDKk!&_UmUaRf(O6SR6 zzMcwVclitdu{K&Gt?B%0$DH%Ka)m`JL6Z#Jpcu<41@jFbBz1!FpuJbOJ)Z8kHKT}Q z_!}IRR?c>0&Nt&Qj;h!jwPEdQD`+lYT-#aWIWB5Cq~_MoaCWl~Jf%0pW3b z-Ku(nGC90fjj`rXh7Cc(Xf)$}yt?d+VM=r=6)FS@`OQ&6LV5%jY**8LDEo=q2-2;W zXLFz5Yj$C0KPF35%Za62bizyq5V&Un=D1ejqYy`jNUkEZx`7gG{jZU)SoHqE-`bUo zsxgy5URx|pOM9qlM|Bp2^+Otw#8?sx1ynFD)OACtwIT+Y1B}#snwfkd`ZNWUuZ1Dg z3J5J&JYAt6fN_#GTqdGv#wb8&nj)t%)0R_2(EHvf6Pta)r*dD@@=u{net~%WnTTt@ zjak199mId#cZ9@4m$bZo{wloNngnd}jm87j!n|hi9Gq)eq)1}J2NY6a=#-LWMACKc?Fn0eJgkvFVwzHPJSCda^P{jTCuDdIo7gYl<=sY)}+_Q3T%^*<8y46+?f*t zH^<~z8%7i-y{g&sZx`Wx(?%_9eB=1?F3Q=~ZWpcXS2{)%Z9?Cz?VlQHnd}xq*zI2y zC9dbVFHaskv)NGv?a~q}@_}vlro>|<@v`XmF4Xxq2O;^%wnr{e?a?y4zMGVO?J%x^ zqr6{Bq#9Sdib%!nZ>kG=6?f%d7)P_OZ)Dq)iWU>+(HwnZ2ea?AwD@Sgm6u&|?0uVx zHxW#~O1#4B=U!!E>x~yKjHM?d#H@c!rP-Zxm{VDkNw8W`WrERLYXUVKYIYoFqPj*A zFD}v?HkI1j_Hx{o@ika5m+~!ax#-9xYI>XIWkO7@)a8b3_C=V??O4fZ7soW&yvXmK z-Ps1%D+Tf_>unWrYEhe=B?nJ0+0j#f@%V`N7WrAJ=nVTZJE zu||VpNVe*I9}B7xo>6jqrpD3elbe=GMt4c$PzD=N*o1C^{TEqP{ol-`R~MW*V!kQ% zn+%OSPE%}dn?Wye?nKP0-xm5TJ80J_9&2daEWBpADhIPefDBt{al>tbKt)<2snTIu zZ=8K+!iMD>YoHCf*0G)b%;7n6H#1R~!v@As4^5D1lst)5TM3#`b+OnbI8 ze2bnPSnwdjYL}M91Q_*VgiH&E$IwTZ8S_za4*+yAgj5BfnG{is4=6UmO(6JZKUR5SgyC~B8+P%s38NFVIE@Q6rfXPzmilun?o|)VM7f+` zBdcF#M3FbOR$Q@j4_G#;NQenj3gRkK>d0ZD3{BN3G>@?AF2^t#o1j%e<=&-KcS+6# zm6Eq30rjfpO$--s?Bj7Y=s=H~<(V?^04ns*QVD^CIxlO0hb~rThyP*JH%;Os3o-J4%j@DjkQ* zLeNu35%fvejsqOEvSa^M)%+~Sb>V1HspK+y1Fw_zI1{Y*=POV}KhLx<6ibQ~4s47T z9GzXb!%Psmx}s#;glavT22gg7+Otqq7wiTH1hgtBRnI*GQ#>D9U4?Q(U=8Ef&r_)N z0=gyY`$sC*AdM`2lT31sy!%Z?Ys5TOU?=+5bRrov=-JL8B#s+Yvyd!I7ej~T!?yqB z0G*_hL^v2o@bg96In$!D)){V8(7HmoIrS38vkt=Hk`(G)a-;#YyjiDcdB0a)e+l(c zZm;JipJkXo>r!!n|Drb)#WeSzW$q%|2m4c~$7Z)uqb+w8Cuw%9_w^&^?xo*ck_nj3 z@uxkG#F&A0mw=OGT>nKcYT1XP=j~}ze zn><9CpZC;te(7Psr&pm%h}d%@$tGvUmk74-*flv?d+qOAVh6;i))(ag1T^!K6{7w~ue z!|EGUtV7CwfxW&=hxs>+K1hz!@B+U!ly3QxjW>KHQcY2c$WirWOqv|mZz>>sCYc8( zb%Zcz*FDj9+sw}1&G{$)chro>?Mq@q&LmDOu;2mtO(FN?UjNt5^ovxp;t5fo@QHzU z;@Re6YR|x?3ORQ%4G;Mm9#`^!7H|`;Xumbak->7ftC1n_fQOOC(Y%4vPXoHvvjLG> zc8D~=@;n6U(W)GDu&xX|!V_A-YIzVVtZDOu0=ci9mBwRhz zFqbia8@GeR7L*&w&8f2`d^!*4v5n9uA^pY1j~onD8Uz=Xti(&Y5Vt=jP7-gF6G4=5qf>o$TuBF<{bDQW z0b?DoR%bxUoO?s<1AS5!>{}@}*5I}_zrca*l2lfIwAeWp8$3sC3 ztEe~-=&EHrxI++EdY}cv7fZKqiMa;iYSBl>2Oym1mZ4f5e0y;F2GSZMs^!hUS$x*a z2x9lgyVN0Mf+2;s^Orv`y{3ztYA$?w2dJ!1D4*;^h;JGzMmFu3ry}jIu)6VTR`}{ypXCA07t@KT>O#Gs%@vd7>me@^RA7eN=#Q>CzXb-L%&MZzWdOV}12D8!Qm# z!NxL)Cak9k8f)TR!7r3e|{Z$-S|MS9FN8DrR3$qkh}! z<`ucgSNcmAQP!FnVJ+dIMQmR>##46@b&ruT(WY`9yt%YXg3x?K^J#|)6Kj>n_;2)0 zm3y_Qk*;Ud)nT%?iqrJm(>i>`eX-3+%cjK$o3rJfDbTKEad5T1T|O7#9NrqHu~rmt zN#ozS^(SDrA zsv(RB8@C1~R?f8Zekms{TPVD5IM3Z5td7{^#dnE0>oo=gjzot0pc|W2-CS6Sq_xY2 zKMDYyz&m62bzH&UjDIx#Y3dY%4v<=hB-68UFkV`UdO2n=$ z#L&BUcq-2)V8}*ybjF?kFjFJjt1T<@KGe!$-^(q=N1LgKCHaX=4v=|7;o~<0rzSEhRMu+*`oOKW z5?SX<;N?sF@l6-Kc}=7kTvS>_d~#^UkwD#!5W!16`VLA}O#fomaSk+2EKlne)J(XWzpHxYn7?p-1nR=c# zTBjb)7n*)FYNEN|o3!YkmYQ&hI$^e|!bc*!!0>rekNz!DNYZ#$6A^S^LvoH_P$Rlp7@a zv#OyyvAiwaMX5Am9pv?V@u_5A0mA!KU|3&r8 zpROC7?dY#2mr0fJZOR46^c1;}+FVaQ9q~Ysb}-iX@Fj05!hZBw3NZdz=k&|W(w7ht zbW%mADXI^t)}f#^V80V&k3;4+rO}GH9b8#W9#VgsSAjF*maJdH`dPzgJo81_2Xj6B zJ?M*!zA#+fIE5N^f$!-N9dpW~a%ubr zd_d2GxJYsVk4Ts)vAZiCi+n{SDW=MO5zSQ=ui$AD&S~!p9(aku@VF^KE&Dp%D0f|I?$O6l|8FC5g+$-iz8m9mo|L&C8{W5`2ds*u}tmk?Njg-NH$ zuYOT^Z6+X4k3hP4;z6TETdvNR=lR#Nrl9yIl_xy=)8Zrf?T?DGarFi;1Ez}5*}eDF z*k0GJ++IymAM%H#tFlzTmafY98Ox-XcLSY8SwvFPht`ItUu$z4q86N?zTuX>LiAb= zlK=f#yCxc&orpOyjF0y`XPSLU#kcRfrbv8KNQJvbMg)Z051D(nq^I#O+N~k_rE3^b z7d~@V=<*_xEmBf5X;pk)FMi%&)Db#b=!dc5kMQgRc5;-gb;nNfstPyH)^Ix8@L!5{ zlF1VP3$6U7zVU~d<_qiWn#c2qxq?4l>5EY05pwrj9OV5a;9Pd1I5*(JJPX!(wjzNZ ztk+_oHW*koHw&sj%v}q8^&1R8`YYHU@|{TOdBLH70I};=UY@EUkS01XT#dOHO5)we zAg~vu^3FrMVKr&i1H#u2m-wJuqWB1}w_x5H(JExSxDp4Qq{9U}k>OtiWp+5U@H6vL zBilZ%XL1Ifs^Mk%ad$;&xX#5S+!T>@H@Oek$1*TUQ21Cg<@w+eVAbh%`sIUJ;&s28 z&b|j-P)*TP#fmBIGS^y9D=0=;SE@SUw34e=<)|rOh7_X)eQ7I@l7#=2=zL~?Q_zyY-NH*)p__8 zXl=T?l&$Mk;T~zeH{2`IHP5}e<7FBv*>4~b*qco{T4Fe{QmTwndm8vgt**DfC7CYj^x4(3e#4BnUZyCm>k zsypku(lIZ7|KRtdLkDg0(`D|@fP#}ehZPFpUFrPB%_3QBQU4Pv^DH7{W{U;8ceoPy zV~^F5{ZZp<93x z9h#!%4@8_||RJ`FEIb~EFW}a)A)E--&5iii? z%}-rwtJHPYM=>hb??##Q1)hIGlDOZ+-FDeHJ%>og3OCN~H?Z~H=Cn>dYeGTf&^G!HJ;=j{ObHef}gi_Ld zJJ5hmjNqRtez^0*hgfd>{R0Zxyw&rJ0*4)#u8s9yzg-C?d25;-n4+(`D1;FQ>!(sUC3!(_REC? zbP^_^zyPg9hK;2vAV8PR6|A__<*1qLq6$Eq8l4S6miweXq5?a-nHN^HdIY!f_-o@u zp>Y<5g14Q{Vq)T-cj+<(iSIn49(9+qkL2C3?9iuc1&4aE89IqL*f&6a^^zfQ!1XvI zfXQM>34_t9t82$vL;XRil9PbsK+TGPzDy#&S3cjbOdEm~NI6t9>84uAq4u_*#>l9q z>VI>bQwUr-2dEYXydv#&S)X**ktfYGV57CIm05Omhc}Jl(!cnjYr1cFV7GftkGncB z&Hn2ZS{d3RwD9IFW43<+gepDlSxb;sKMd4%92<=IMHrjqXOhMtmgBT~)AzY1_Q_Nj zw@j(JDHekRvv=jqG7SP@l9|N~)7YfFU*pUw<#ReCAH21<$J61cB~wM-4wnZuf?!x8 z&@&FDqPxuKW1#{Qs|nwITE(P<^g=KYP1JZt=8t1#dyQx~P)ChKLSV$ir527yem+}C z&!-)ct4_`<5j}3Z5e_5){UC0`%OIs5&V!TEOyxa5zGJiDegY_wdbk620d=Q*!#?^i z2(l5VjooD9Z%&w*U%NHIDy}RGVS6`mlYp4y-LVW1;yhH5ADCa|jvjb^77b)wd5-wz zEa)Y94>QRui~kZH!G|4I!~88=%0&5G0eO<-nmHrap#K1XR^grjSe|Z|icAjz75nrP zACVIcUvi7-|NNp!+-;Hwr2EQhS0&}q%-04`%he-MLZ%u)DE3(ue zxb}WfOasYLv|TI5YXcSpqy`fNgeG}+nlPF93JI91>1BvY--xvJTv2LSv#U(gM20pcy6m*!qT-REi98kj;igw`RKd( zC~Lj(W4oNOhm!qSdy9MN+v(nUxk~==dUOJzzjMH4O1xV@F(@m5V@h|b4a{J?WriGBkzCCt>v1AD;OO~ud zS+hiL*0B>p#vMeuS<-!EH+B=*GRP8IgoH@h#@K0WF;|rG%kOEr_vJO6f6jBx^PclP zbLRXpXXg8SK7qpH#M2sM(~zwCG;wtNyn?vMWGJEWiqBj0IAtfzk9VBXz_y~AHU6~9 zecjKYtN>+acdRx@uVVO?`NcJ&LhT1VM{@&HtRG3?=|2^Z60B~K*p@boc23}r-TbaD z!>XBP(u5m`S#SH_8J3gct?H5V^cvy_&#begx)Yl6h2xK*oRO@Z_Bk#4%g%EXE^a;b zkdlQ0F~ST`@j9*Ukp#&{yF1LU&!?+q4-voEIiw6U1cY^&#p3_)YP{yLY(Agqbw4*} z8(ZHtUQ70I_%0rD;mz}WmdC+0xKo3QFeYCmLt{d-lfmT;q-hFyBwF=F%k9>_`t!PruazqK8B3CmUW_dDa zB)FO$wiBn55}KS%KJ)C|1^w#z0|)Q6S9)z{ffONO7hcJN5)R|W9vdu zoyY?Fc{jh}d(4(E0)-LvT6x;Xw+t|wZ!NgmE6k&T#;PUpagBt@kH>C#&)1QC7t?o_ zAGL6{))=~`ebD+i!0lx%G|ZSqFsmA;M>fkEdtL1C89?>1IG+_kb(Cs5{gGC1!-(ON zM}(4=p|PQTfWwU^_usPnyyi7ADZw^bJ=~J+bw8SzTDySd=E@>hxg8&3{L`~}(y3Z% zTbEOv62Z1^`_1$_4C`-6(Z~G7_vh=SAG#x|65B2UCPq!?^i5{&D_Tm_eSWw1uIHig zn@TUk&u!KYG7rm4?ApX8yR0$1&ey!0O9w)5rKNLOWZR)+LC!X^mE!XjZypOQMFo== zmvnO_yf}T-26K4YI!MOfmLivK-8F#=<~6fxyZh< zDenbKj-#aen^9$u0nf~#{nX>NLw5e4-uETs@zK<|UKD6Yl2Ed0Icys!G>* z`dZe_AfCIqLx1P1+N6?X{7YMGtt7VEB{zz~#I=XoGkH}LvBRHap207-`iz$gn{&4{ zh&b+cohV1@otped*^G;Fg|p-3hRt5gX+$C`FV>nOxo6+yY`w>cwW2^NMP27@_Lw}y zeaVVqMbe^?%#osXsOgU-hFW-hvZ9_)GLOA;>wpBC`+#W8jq)h_D@5#SkY(|uF!^Be zvpDxpLH;k;0&3`IV|#nk1OM7EvmXh2`2Dis?iDd54f*uw}jI5THWNIpIqj#NNJ0^2-^Wl*XFz;=xU8n9fv&FLCRIMSj7Q{ZWQ@hZc50(s; z3m6Qr;uqSO66T^?IXs83+G)5t6Sk}PG{2s=Wk-sPcMR5+`7w%`ajV|Oy3(43TSu+C zM~-Zmxa(}^%;=3m237SDD%R~xy8}xO5~CNQrV)Ltrk&z;N6jZt9)3}| z@p0saOnkL#elg?UO_@Ig`wP$CW^}0K&8wf#eIy++_>C90jd2LruH+s%w`}ihw92os zil}cNBDANCIN?G$uC+&?1()6!CWQzL*!D=s5W4p6HKG=QYwh{gCf&{3AST zrcNN5Ph~ju9%GXq_H!sthKqWX%||#6QQ)I!eFR95MgKL%q5H-4IkR`d3zHeeKHiFy z(u>-81|;aIADIjbIk)%244uctVlG#1_LwwztihjJ%A5%KqOMyC2rvu|l#eN|91lN5 z=Nt%}c-$Ej=SrDJCxNO7n}28o!M0qw?(~+_vJ6vZYt6Tye z6T%7!VXP5SO7V$#{fL1jMC{}K@z(d_t)^>op*uwbQ*~aco^uJ0YYm$`n&-3CT0M4^ zFXv+7eDBVP03x6O-dE>vRE;nbk$iI7r0?Z}g>Ni#E!lJJj2W&fiz6x=Nh+D04r|@# zfX;@vAkD%`Z1>BilpnVOI0lkfdtaiv2ozv;#fqmZm`>4^9_7-NWrc7gB~{=VO0r|6 zi%rTpc9bR18A3{*7gMjq+3UOVpKWMM)QH+;&%Km}>K;^!mqB|X7TOYb9#>(mT>XWq4gBjFX0woPN(1n^o!XP zq~rFHG`l8OKHGr&=M^G~PMXO+(xsUFhg$FK8?}<)`m7;V2eyLo#pS zkX&aXT3)!$R%e?x&V7=z5>efncx|Ql+l*CJ5z3#j#p$}#Gqc4tP0QJgNXW1p`S}VFsL_g(d*5kcnN{R|e&8PrW zKTs&SOM>;#Ax#=6M1~6G&d35Z&T2GJkrEZ6pOpa)9IJjGsXzsSkdS{BB;hyeOv! zKFJJDEwaGMyunY48gwI|%#ti{pmXrs)Mit$ZQHhO+qP}J;Tzko*tRRSU9oMal2ljs=<)aX`hJabHP3$5o@<>0 z+y`6!4c0*S13}rfE2|m?1cU(-1cWwa-VZZH@dqxz8+{Dp8!E4*e5J^>D2lW|f-j0x zo<(~QnFNO1pI8`Gd=Dh1B^mL?ab$;(Lh-=8JXtcDpd5?J1y(UPr2%wU(aZOC<-9lL zfcxF*)xE2UIN)87z5VfIhVHN5;|_d+;QhP>h}{S&#GHB~#GGp3!G^1MJbr%lo)4`o zc_%nvPRltX1nccyRLGDVhDq}twP!iOEwD#^U`j(>W|X!^l(A2Bq}thVpjupbJb$tJs_GSbRy=NhT>;2vm1Jp_7P7}k!J11JV$6$a@ojwipW`qx8>vXJJ zJ?zdA<96Wd;j-7&y8wUZb`0vX<7W{%()c?7O2Z!-sp^ecl~$6a?0}R|mAP(@jFxjh zIhxOTBZ1C!Nb1X5dw}fW(aiP!kXA5QDScnJ7E8 zW{-~6^Pn2k&Fjj}2Ckjx{MvEXtEAXY>rYahfIyx>Hw5VZ;Rj7GOVwBeZnpy+Dv>P! zGjqds6s?W0{q=I8gany>eP?xNX%WZKX==PuvH9xy+WvMz8S6wDjx)_Zewge9Gq_0k zEAWR=HIJ|Z#=i8{dR{C6TMglt_Hv?R_Lr}FzoWzvzrxeTP*T{hrUn}X4n&;~;bm)n zhjTJA;7Z3(7NN6M_mgz4;=Ac5MkX47SN*K1*q|LqUH{umM_55_r&15}m{Drjev2>) zSD%5XQJ(QP3Kf{R!Uun#|9FREeI%^-Jz|lJy~g+~DJU z@}jhnz%n*4U3{jH#O4aLo;oZ~;-*?!?e`q^m&_*lUsR@Vuugr{mlw7#;AMPBJq!28 zFJVD=aoQsXXU9xeE7pV7LVn#q{p!VZ3%Y7}jE47Oc_kZjN{$2I_Ih`Hid_gb!z77k zLEPp?R;<|(jHShvV>3q;6{-VZbkCCwhse5}9x5_xyKM(xnjv^V-XBsASA(EHumh^r zu4uRPY+C7=BU8QW{OGSZAfm^B!Ait0-jY>*sG>$R-+;7@n-8id2AU2mHkJf0=Ox7L z3wA>N`?)k>o~;OBOg*l9-c&2Ax>sd#(g1YY--PWe-tT@R^ihOGFOUaF!s{7t|8@Ch z_a_pXzZ3hE9!TK$1W#azp-gEOQ-WuU#0`utpn2;A8trA^l6q$YQF51^@s+gh=n(ox zoxo50I#y^dUD+qqZWwdRChW+6_RmN-hX4{Bk=n^oC1Z8WWcqd|_FqA#1Txzjttspk z$qnVX*9wL95^mN zFaghCQlK}=ONlTTi^uzFqhx1MtD@5q52vJ+NFxQ!u7FgleEERVM{9Q0KxyV+k(#!U zjP{AHSQz$~(Idp)Q>buZc_HZTh*;6r2LVj?1C+I;u46gWXMuJCdyY<=&+h zm4(^0&>UeXB@WOkTUHnuLdRJ}V^~#YwH&^#l%E<;i*sXUO>N1{m4ma@FJx=_#Nw;< z>DuvrnXPe9bTKX@WWBobWN|7oK=)Lm*uH{jQz)jjk}-j>shi7zn|@FwV-hX@U0v25h!EE-T`2>;fbnoybY~s9BLR+`KF%Q zDzbQ>Qv(mtg1L{<#PeylU~f84G=c~OVgw9kph^bB%mbG$j0Gi*<7%^`biLCi$6A3Ua2o<@&WZB%x_Qab`4f8RYu2zo&RGMRxDj1!RG($dfM3s(BZguTy zLQ~Oa_37Ex6x&lHa@^$nGLNS@^H2-MXqXBgn+7g$+NPHtFwcLI4Xtep*>ku19Ga^p zp#I$0_;mELs}quj#0<%t{k44%{7sS|V3?G1-3ZXqJ$R|-W>adjIc-=-Eg~5@2km53 z@Xnl(UkDbZjcc2EDxRKDmzlg3g;+`NXn<32Cs&Gr8M9>iNKNBkYED;3NV$c>%@2(7 zGuZSz;-4HW^C9IKoKie9{tDcJelMU3LgIin!vgno;{>zF^|F}Zn0+;$q2u1o;iwNQ z*ah^oyIql#CiRE(k02Ch-UkgWPBjjbKsFW>pRn$MumX$j zqFLTNU8r{i;*{D$hD+hOUa3_r7*l8 zv!m^zk9RI`jl^J^vt>t_yJad>q#1C=@BvNJ3MPiI931*tyGN(dfE8@a@$)+PFz%6ktHtd^7EFEspL&_D^Xzo&X6_DQ78wf zz1psXF}CZ($`6(2F%C09Pw5W0$pQWGyoi+#B$=AsBzZ;_@JF(*yWu_ba8?#NS)qv3 zq)8|X$tO8<*Cm-6pLzt=@HH~~Whyl@SnX7DTU)W*f~rdggk(W%Z<}b!YT6ltALyJV z&W{eSCYIj#IUky_2kCU`3+UF0CXWJ{R8hft0T~UY^%aGF@Oo1BC3Im`#{kkc7=7sS z8CyJwKM+!`5Ng(Bjw7C=YqBjR4pZ2q^G&dX1t1Bk9B9@gNUD)hE_4oC1LkMMj*Bml z!1|Cs$=oA49A5dB(J*y(pS)A`;qu&G&y}CmAx;G$aS6rh0|Wz#;j$XWiYE!A`t z-nl(heIYdB4%$A?#G8lH%12=MhxWT30nM>+I;h~}7?yr1=LE_C8i57|Wo6{sNQ^>; z76_DvAknlKbXXCYyWKW}OVJIAO$mR9f1kA z`gr)*`~ttfA25CqYm&2*ElP{2i^7qjnqohhLcekYd2ZllD!}7e;-T;lQF}5|iT6py z$l_@r6W(PRz>DAk+cMkZ60X498M-8S!#MJ%S_YjdN(}{_^tcey;R#>;6?L~{leV>u zPbWCJT!zM&*IJeiG+#{cHEvY+ z+Lzy+60#``hEJ4SM{BO+Om>~)RW=p6jE0QoZkC2X1^f$hGAhP8_=LV(#|^Z~1k`J`5Y4{&kph&!7&$xsda&#_|163LJY#sev-!dySjv~soVP|ZwnwS8hqE7eW=?jZIr zi|q0V2R4CbUK!WWlN?7FFNm=IV8vl((EGk<62$xUXcUio))$cnA|RzW;>9U(Bnp6*3SvPm@L)RUplH%j@jDW74248VZ*?j*TrNov+S$c>Dg~fOE1Sik8ABjAeJthLGdbJHnAQl>~+P~ z#8EO}Y7Or4mzgHx>OH=BF}4#ZoI}bJDIC?5J}a%Y(U;mvo%ZW1r2&8f2;ee-6!*6Q zFsae|^`2GCb)p)TzZ{-!^I1Vp@Gyr_M=`Yr)@w?iR~9Kw1~6sAY<}DOF4BFc>oH<+*sWy5S1`mn zF_U-HR381t#PQ`v5doZKTAbNU&Q!FVsUhGIj1!oSU@eSlp5BJPTk$s@L7bUstn`sLU5{#Kyg$T}jmaPaIaQUY)z>ik7Gtj+=Nj;AU=gg&6F~`6+*>>bh zaKRIBVV{_t+a0vt?L;AJae1#NN3)b4T4J^{&oTSdK$>TA&jL2srV0Bw&K~20G=K|j zcmh{_ur7h{M7$gy0P9R^qHnt{2bc55gi`-njR>CF3==d!!^0k-~D{^(9K>;EN-H(QO zcZVNtB+4?UGKW*dGw=#54>WJ8zmpFY%WPBA)rS~ zPf*sTprcOzJg7evUSu! zamXo{%o5}g-xEvC$qkF|h4Yc;6zl5`G@*CeNRuDYY_Il}tj5jasMb`Qx$ZH!@Y3k6 z+vHg^XC|{@Ma$u!yS5RwTtFrB_OZi>IH14e>hHj(Hr+h7{XhjbX zmagNjzDdLH2|so87G^T9=ht^OPok%n@-B7JZd+EBohHA~h|rvTnJWJ-cH5wU9a3e0 zvh1;5>}1vXA)efRhiI*5y=m#|(c|RZ5MCv^G^Vm~bPhcT-P#6llM1*B)Q=|}n#G%- z`-^P3y#>dghcZ-yeS&?^yJeObqdBxnZ6z*>=yfI!cY~2T5*cEWyWcUED2Q2p@DKoz z^OkzZ20>xZGW_|beg{&(M*r^H<#dy|iqOg^qS$Jzp;gQ?*iK&xyqwoSNqVV9;-wY>Bspr8Ti;34;h$o4MC1^b+y{g*55ZzjeWc6f)u8Ng9YEkK>jNC-{Gs}VJgcq(_Z-0ggT3-5t0G)sPE93~qXib;- z5LBi{NKsUJY%s)ymtC2A6uR|VkQQsmlZ8kUrOP}~K7(I=^oSkGxQw1GjA0^MV%;%L z0MBEeSY!ch`*juR$+7!jxlX!YaQFf2)qaVx6X=@~yOIY|;Q7Tu&urcxOemAGWQ(_% z&%;!GQtn8uG%}mcAx~*me%RC!O0xY2>NJ^*f>P#Kp-eBx45d;fTDndGZeXa&yJQ*0 za^P$+D(OSmdXmuwlJN$mZO$v0QWU^gG(CY-0dir%z;;(1zsS?Q1AKQj86wg$o7 ztaYCK?g)FeF_ehxGfp3bBUXIuApba`PhLixgH}sI7BA?5T!650fhsDPJussQVzT~L zP5z4y@!x}?g|=E(0Tcw}790dbGQ|XgAO(pKDn<8@0#K@EpoAuZF5va2QMp}pDk7RR zQo~vV)0?F%tU^IPdpV&b?6r{KV$U;U+A#_+^7mH^Q|6no{|gb${o(8lWT=GQf!OKn z7SHRJpQ4oz;O`yEFG^0h1{E6PX?mV5jwt~=Im%x9VoS4;QCgDzQhy8wG}fsV1JO1V zcM6lDQh@)v|NL%>uhf-KE=_w#{GDgG=1DGP^8y_P>Ioics)A5zUA;TspE3o<7$qF=&{j!*nQi@J1H*qy&fRj5}9W1>v(;&Vb7tAwk0(9 zX1sh-ItRzL-7*><-FadFS0C!q8K!i%5?|hQ67tW-8Q|}R+f@|t;Ic$CbWHI!seIY3 zIe^OgvEl}gt)2MvJ z;gtLYk>PVo4kG_^Iw>~XrqR+p-OR`089eK{vweJqASd7@vpFlX(jNH;^z~{Ws{A6+fmmO=-OL;THV; zus@QT@>O?g;0>5_oN7s6A7PvE~9pb-ae#N05e%sWJJtWYNI&ELSq4mldQ2=9# z`vU(jc>Y(av-6N3Ae1N|AOimb-s~ZM${Za5pr%El7L$$7&vy&yFYxq@%bWY6mo25l0o3OGDC2c!%j@--0`U3x+zz69A0F$wMN$02 zORhsol7=%CP5jV;jLF3iwdX9hOGcD6I_cCYPwEqhIezA^T%Q<77F`*0GiNr`~`L^B*Mo>e6ZO63)@J@Fqo>rU@%4g zBQ>m?f}iZCwpg7>R&Sj{rVPv+iupA-bbx1enWI+;``7|Oa603ZVjH;wL(-z&0Znn~ z5H9}mw0MTe1(!`*@n#Iwq7e=93k5VifES@sNo*bC9=`!3ii(saI8k~MU(3w{W)7{j zUX%$8JUix+_eX&S!K$iFTT_!=GiOa}i2>Qlq6IhOcG@ehjGEgLCyOEfv2W?$yv1pA zIb$!pW<8rs;3lQ>&p@Cd-A&~|d{)*yLI7wXBAv);-Uzk8`9NG(Ky@37L}C>qfUd6e zgMD-F76jWB3f@)Y8FvYnC7_nl=kLP-EIK8{+(i0@Bh^x9*Ey`dUcv1SFbl|8Wbv+X z+>Dkf5qZzB{ae|1+de+rvRmLoGeaFkTUW>|t2w31FZASyo~G8RV~8!DIzpA#uX0+B zXHtKPVE(#Qq>@_9kejW*=R5@qa7|1{-a~8>5rzd3_~-AbzRQ(`p<%kc!Q>RHp{|e4 z>=bO>kc~5O#H+3iU!9SYvvKvKb2bkFx_(qz&lP%RPW6rF=4zWu)Z>aAEaQj;Y>~C* zd`Ky5dZEUEtA5d*WDQDWo^GBzYRzxlwa^Miq`Dkc_xcY5)mpuSg>3PXOZ9jr@1l63yCA+^HtdWt8pJ@|jO!LFGFVy}u}e z`9~i8`sn_Hh=0)wWZv|J88rD}5%(K@m0GQ%LFkt2%%nt~pa*fxR4_oZ&z6)y*p{zV zRUn*J)hw+z%(U9$zKy`?{&d8xow>zdcD6xKtAXOU=+D5)B){w~17M;fWPpO18Wz$F zPpfrhxkK^mad29hK&^B(9#oyT-bQm*N)ngJ+l_Z0NGuDw{ zp-TM`@@k|JAodN{0HDOHmUqiSZjMZv*}sq(&f21cTnsw7^9vEr-tqJd5DV08SVD{1 zDi$GWtahLiXqnw(&tZ%5tDgmLru-2(yb4vjZ(qv5W3bNpeGw|#&y9OFCXZ9)J-kpE zU7p*%^z+d(+ha%34Ov~uopAsIdP(*$g;)#4oa*b1rnr}r77$-V?h9Y~C56Hp(qw%F zJ-9GRmRO`9g&Z|YW&CcEAca>8NAkmzX>yoQJ$j8rsV5k>5eX~uOPh3OcqOcP@HE!W znPD$aTWvp2dkyt=_;I>RMQkU?8!MSxIJ-YV*9F<(K+HWl zfgi3a;9LjJw*hu7#j*MvUvvTj?%W@Y7tDdn`!|@JbUr(@HCM^e?U%fAWYDIa&pXU9bBOn4OH)GDN@ z!C859;_}Q9pQ>Btil0}X`c44zc{qF2d0_zX_hEycusnBiKQCvX`r0HMy7gwSAF$ZS zf4Z#M1i(MwK8bchM%z_W2mBH^kcy2gXpsAiRk?@jO%5D#x#tT+1?*|L3_fb5`ZvWq zwB;P=M;{(_5>Bem&Y=Y(Z8m_}xu_*Vz#+%y9Z{{#P^mEPr}wM4p+l^Ba! z^ZK?EMLCCHGQ9UQ=|*cl&?WM3mGivfZtrv-tEkKkF~T?3@IW)kyU>5Lj(oVUsPtcx z_4F_A`2Q#Cc#iM@d1($xOUmeDf4%UwS21vCBNODsH^7<@l1M6GW+SkvvW=Msw6IpE zvu`k+_=@i1oSv56L{YwJaQt!9grhmvmP9@*uZn_1YHeMI>_XmPyjwHu}yYeQF zQ_0X$d+18Ra;isQFq1C8Dugvb=j^7A;-)T z8Kw>?m8MpJmwyhH10(K;hEnpTs$(9>q=neA*AeB=PclT})o$W0;XjvwlPGlY>qu$5 z%)3zAuD1jy#z8G)yz+!myes)LwIeKJcV+cauP-!z^ibZFRWn$Jj$HJypESxTxMs%E ze>(K3yoRkWh{Z1(r;RdLwaI*MJ@*htv`fr3Y+B?*Tk zPDkcp8W}1Y(Fcpzh&?}(5E+Ov{KJUC0zOyyw!#U|cpQBM6$~RJmDIz_zt>A?e1Af~ z|6Cl#{$l=BDx%hbDN2}Z!EU`yxISBGo=t!u;mK*g=+u*3cL+3ENWIM}%?^ecw&te5 zW_gC7GXcN&qcMoFNQF+E_xAt!FLiJ^!K!~m5C0?j|8;M>92CSQE(aatshs+g6eTnY z+j75!X?mS$FeESvi6JCto$$s|$T=AR!@b<75zp6Sfx(qnco*g)2L$0em0$*S%hbZ z`hR{Vo>@$__3*(XJr3L%zu&`(nXgo;G|8N=TXR&Gd5=~jJiw>ohjP*CYcIY4@=&rE z#Xct5tax4~5wZGoHx3C$T0J&7M{Gm8>ts5@f6=@3W}O+RDSWrtCR6kTzz-?+Jw^AQ zghRGphBr~sclWV>=aNiI7*K9ul%#XN0L_Sy$>YiW`mqe0N2Qjo%HtZJGoAims7@)$ zVV`7E#JR7X+f-JNM5O|kGMDB732L~GrrHBNKs{~ch6)pyDR{TwteT!X`9@2aHM;hy zz)X{d485vt%S>Lv)4<+}VBK;W9_yDArFAvn1fa4uq#NFBz%4(=Va{dR6{#y12G{=r zw|<4N=N`QNPIBsV%3PzXvTM0=e~VduZDwX>o`Fzcv^N#4``PH`*2NCcyi@AwT4&G9 zm|QqlDoM1640-GiR+*aX{SbyyNP-J8gwrG&2ECNMNaZ=;{(?ag;EJ`c^sO_m6WvU& z&KW{JWfJLc6TN_=I|p{1w+xMP3IYFTI>ua1UA^EfWIRHwk9uU_fq;KOET5Y30Cfb1 zk?ipC>Sui%?L`3!WtAX6cY{lOm!ucULQR)dG;3^!tTW=R%&CfK(}|8lW8zmCve^`iz7gS6@&q+I{Bt&^)2la;H9xqXTQ2Fm}r=k9Vqrd)7KLHr%9Fp6vDyI_5UvX;1dCZ4Zv>} z$ryCl=d0hZ1NyKUXwe#Ps)wBY*-M@Z=iYd)UZvQHuDZ1>wM;%h{+pgbM z)wWWm6In6A*7gjrvMBF64|94eJB^eNp6T@<>=JdtS@E8V!;aO+YJd^DfZO#Nj2wE6RN-CJ?_k8a;F8f z02oeQBD8u)&aFG<5~D*;8i7#oOmpg9UV#=Hc*jdM$QC3g*sfMlW@m?O*WxO5{6cd3 zX`ejZ3ysbJ4C^osr=4^_<}DyInJB!z@Tf3ms3<=>a}YcWQyM(IagxaqV5^+3PRm0S zETO@Ck9QOso5yG%6F3H6>UM8A{s|Z|+TQZKdP_YYw=42PI*Tz6EO+ZmT3cr0cyVA^y%#9?eYNQ2o-rbVekn1#E|tto40;x zKcvM&tt1g8<&8v4kVLh!d^QxbXF|0dDGpU)vO-C0#it~lciKZ0=teFhq38x5LHsW3 zmVFmKm-vu)H3_ccBrwtdF@;CkT(u*-lG9TC+)?U`%n}V%SHy4%WbPm557IYD&Mb8X(*P4x^A(SGZECio_ z*s4!Y947&NIu%xz8-5lJC+fEw@NF3@KZF}VwjNyT!HaQhw&u6R177I=cCNcov*|zL z4sKxdF&uJN0--#AC2sH_I?UBZ^j&k(?JP9jNu0gIORjh@^dCeLH$b;*K7N*MJdO03 zWg(1l!uXMI1#Dbp-GNQb85mVg|Kuo&%$_~6i#QO^jCanlgwna0MXz!njj2i_|HJs} z_=PkI8Q(iln)~HJ3Lw0pE`T1Vr8Mlqf1NhU=NF+#M(tAP-M(s9~Q+LW5xZ)iOJ z1(#je@5p6<(pG|a2{2uPbr}1k+3|h7!c&*6_haZcaoBWik=N?>@fi;aP7S7@xAUHE z*hn#x0M}eWpyz53`!jsehk_=6+;mtHtYVJ6*#Bs${WS;Y4k*=@q6a2jE}Ldvd@0RS zxX`!b5Q@(M9e0b9np0*xXq zOmUzs5|0}@2Q>f4|3$1sI>jOXD0tKvk4p3lRY@W&oln6`bg?^p6J>&7izET9lOlGX zab=n`!tbc^C|HpyPT>Uu^0LO)H)a$kVN8djN0gI8?-Sf1KJfI+?yp3OdW5L%Xo^b` zM-xA0ssWRA8Cb_r!LI=Mg}x9d6v2pyq`XmuCbQIADUu&UM+(y3T?u70KO-A&|4XT{ zLZAkCO1+p6VAp9;8U0(41|7~VXmgnd1BDA4Z>1L}mJ(G#e%vx-V`ztQzJc+0b<0!o zFO`x1!Z6fdkiXQ2oeVkK#3I=(r&9fodAGTn-`|gqSV3Sd4(2M&Nn#8MW1JV>rY2*e zp^1L`GEBZQfJHdqpb+Nd(mlJ4WVxXMC9@+r12TU!qw#5sgwj-wc}Q4jdCPPT{ETF?@Uj>Nt8%IAvk(o0faQv<++d z^?{2ephHKDBrzhm2lOkIhqLVJ^fhW2TD{@?xA_z1IGCgR-Mf!ATb5BBTW z<>EuEG9#_MtNM2?NFkdi`!x|invBmdf}BIi01*t0GdJHs_i+SZoI-BAG8E|ROq3vP z)j<=o%JEUO_Grn7S~%HV8Wa8z@6Wh1y7J9Q!l>En-QgU_Xmy8*^8Q#kxl~)->TA(v zef4ykvNXkEO(it9N^k|u9A#!R=ozZMO&PvT-a!#AIvk@yg9>dq<99g@HJO}R_J^FC zBn${l$A3ZpONaA}Hp2G5WVV9>0TKG2WM-Dsf=RQmWE$xFjS!((M_MX8>^?*%zX2k@Xy$a~*t`>n;%zt)IZVEq<~ z$RxOMPxD>j_Q8hmw|rme{S85It?&?zz~@bM$b^9G{?s3TV8Q=tjAaFXEeu^N=8ZyX z40~c_xY(@6`|CihpJU|>Ln1%kpy&^U(F}GKPNAjbhXuMv5@>(yYKiigyZ>OGMJ%P6 zN9rD0KLEWk!=(zRo}03Q@+Ww1$x(hyc9g7A%x$VaKU2#3UIk@}$Fg)IW%)%Wof>;q z)dV}iqeWM|E{}rB?0kv%n5nObtjBU?8ZOOJiT;=?#hpXeQ3kB91nr7!no-pXBb$a> z7i04gJV$ozM6Q2LI&Ob%<%B**Zh2eH^OS$-D*&{gUcDd7rb%0h4Ppuv|5*CM8+@|H z5~qGbwVz(ilVPn-I!lIP%bdt88T^TJug8iaNclGU|UAFJt|9q z96;UBx%57ZCC@F?B!Ie&(}=YOZsx+anhH%RudwPi=BCupCc^yN;saDfMU0y8boIs7 zpk`aQh{3}FhRt$rl*0xyw$*YLcH|(c?8af)PKtR^_J`a|oAvZ`_L{lbdYNPFr*2X%M5x^>k$K`6R_9iuS%>}$6YR!#e*x(9F^Y)fT zFJ8NQ5QCBlJJ?pKkf;nIXHUd&=BF(MGOOXAI9`0fqW_X z;!=^x<^JJaZOxT6?Q(J8R_XS*_D(i!;4!rv3WyX(?eL!^JdCE1GIXA;nG^FHq?vlj zk{WZ5s?kVJd_$`1_cg{ZiIR$V=z!DI12(eSSO-FRfl%V?SoULOtY-@HdHbTJ2|SON zSp-@bvu$}3baxB7TUSy?$P3Kk6b}utoD7@wj_IJYb6LpnoG}AYeTX|~Si6l`^agE? zPUQyM^{XM?;R!Gr(MV@dYC|j>=}a4nQ1H(1dPf-DnNK@BNBHh2obBYi34l?apkiBj zQ3xy+A}Y!pcrGQI2#}4{3KJemmHleLygC|QHAH2zN-TxjXuigz$H+A2C3G?ygw13v>_}Q)=jIGy(J;k;GZ)u$c9OXKm!Zk4L{=it zOtz-}!cADTgcd@Ua}TknHh?>i=Ah>2U!GV}D;)Qje1rwu#P2Z_|vpx0h50+0zWP@{TNcP;s0?A5KD4E$zWB(1)gq8MCVzJTr2npH)Wk9bQYzkJ0{|s zfSgN(g&S=+JF@WcLr9q_Raf|}Xg&C?AUuSv8p+*(Yw?O;hFO?VzK%Fb24G9H&7NO} zk}^N~6=L#03rmRt;CE-Jdj+sveP_3Vq$BS;uyy=h{ocMJ=^Ot%dEH;=h@gb8IW-IB*TzqHV`{AfTZAvjsWQMAAOx zrK8>Xt0X!Oi*?q+V4B^hE@UY}2NQvxD%I{*c_t6IMd3vi=ib29v~BMJnxMlYzrT@y zE!Ic%YM!YIz>0zJLuX|pr;SGF2?a2lx9c+nk@y`MiuEzQTDukma~(qgw+cq`LG8o{ zmG@7w2nz@&B6;zCAiNjq+mDAnAirig5-cQOOWYrrju?**(TNszhb!$iEKz`Z;n+LWu zM3sRu6IuFr$w7e;h6QO->}chMx_INTlVMSY5e5SOMoge~?tSG;Q&%lpRUfPI_0Zap zi`WZ*PJ%Ms-q8R3q;BeBFx79QY`MbqGQCMvEI*Oze3`^7isChyBns#+IESY?9A&sT z6y^2m)n>f92FQbl3RAk1EMViOCwMX^aul=@+Je9^I`v`2ZWlVuCYzn}(n4CvyE+on+*XzbWTn({Mq&|Lh!8xIr6BWqd4Y`+e(;ED! z8}OY%YYdEKpz)y7h4TdWYpcv~rcd%u#YpQ&4aHmW`#!ia=FXQ$k<}R8A9V=i7a-r@I|I}1Cc2k z$Hr64_0FCw9RBM@Yp*q6;_q^1fy4P z(bpznR@&%Kclg7aE87k#9EDJzM=(NYXL?PS6m%!s!P8 zt=)MxPIKMf7}{!W6SJd~s_shuy$C;q9?PW)AF(x#TrcHdIgSkro4 zahz;Q+4qLXxHZRNVdh4*uK=JD{PrYdb?~euzuzcniLv0(g_gGwGYE^SvMQq(|5*~a zM``!z@O|HDALpbIFaZACba;zWvX7U2?e%Vl;>vU2y79w%@?+mY5M-Ba+-LBhC$x5! zFcS>veT<7Aqj-Lc%i2_M#QP&@Z40Tl^UCJviNwemWb{X@_1W0?NfRtjkV@Qf z0QDZ+AlluNNsDoNPn~3VNdI7_u9L;D&6vjSB*~}X_~?M1gFOf zyGLns1g)gx_sIJxX9|0&nusXS)pfO3V_YTlcVb{ylxhIaP@laOTXBOyLN<&V z0}8fXRSSA4TB+swnqR~xi?rXWo)~KvS)?9PCHbg2E8Y(ISA5?Gg7jsK$#r$jeMn0Y zi*hLEt4TBVTVD2-7EFru>rN7p(dASs126pY#;EcVXcrBLbS{FM&(Nk|ZHJ&wKXJ57 z$(D@K%pBMVM==5Xad7u*>(NGsq&;$zuMG$V#Smi)v}DGU-YpX}))}Vm(lors^7a{& zVHRkf(o{u@;f$T2SW^m-6NbabD&K*Se8)Ub<5L~#JHuQ@V)`_IUmOoObtyuJzC1uY zH`mN`+83e`>x<(dBxj+`Zf2Z+YoYi8u_~*%k~8prXrVh``3XKSVW@?^J@^79zF=4l5r1YsRur~&`VroB>cy&XzE=IajU9avpDm28 zj?_Fcl8^d85er3&g)_fVA~K`RE_bu$?gYe=Bb7^&urdPA|y#{y*qP-Bnd!Gf@yZk>oc?|SUZ1E4fJcD>O|q7 za>m?fsDnGse3uJ6-GJS`hbSXZY5s#`Mw*4V53xznIp@qb*zj3J_g=+I`L|{AQdrWAXd}y3 zXs4q$<%((|qq6JC8WPVXH5ta?+pl4KsQVHAN)6gY$o+7}48I;a3O+6xm>PS9{0z4u z8s^ywr(LFNWFp&5?uF9bmsRuz_4(0@bP713{r52%w8v15Dkt5wKP@i(HDzT|ah~Rp z#xKnPWCRYw(Fju;{OQFsQ=QtL`3Mfo?$-ASjPO&R{ITCB`mOWi))ynZxa{?$HgoUn zrIFU1ea@i{sa&Bw8;8;@I0?Jc+&z0y>hOk>9VBK1CRdIG zzr2tP`Yw)=jVb&)7os6i>9}tF$P7SKXg2JsxuNruT+gWTYzo#rmv^2Ha$@;C-NUJA z`c@2=Hm^^`{iAn^&S`6t(}Cj-mO&i*a8)zq2N#G9Y5n#CFdwhw-*qGxZZ zNnM(8zlmYGE%88jxU7}B9R>4}Pb%bmOYjSKHY&Il~N#SFlVf}YJQ zEPU+9AOPD9{rANMT9aCS!066cpoLI24l5oWf6Sy&aJ}G;prH5R4ct54 zv;}C%13Kdhn%DLscVV*2`d8L}HwNH#CotTsmd~xeqwHd>;uu#x?lu{^uA_34rE%FR zynUIf6dY*pz}Pb`BjB_o0*+*i7sCp{#4z!^di6|YLhID}TojNXwggC0aI1~*8j1U= zu+dz3_z{LnOTRAH&r7LMCOm9*eq1SSI_Ia!k!t7D50ntNBN;s)+o2?CR{kp>@Csx1 zQ)vMxbl_TN5GTYkC1@275IK5J_VMHPfHhk%*`_tDi*I<4-lmOEZJ#7L)$B~Os(fJZ ziLf5qYiEontFR1G6a>Up8vXJ^m(XNqBQM8%yT5%yI<>5`tVdMrZ?Ma18!WMXUbM(oKC z;dZB286@@4LBTktO`7{TPx=n60%s?MqGVF3J!YkkRp5-(oFLp-Fef-GIMA1Kz-ZE+ z^2PWfK$zE)*Ad%4*4&@_g>ls{GC{UsH1VBtRsV2w*TUz5a9(c#AUM}VqcOZc{t{}Q z)l))30Q)YS{P-uKsQ!(IC{ylj@l$@CBLKqH_0*Px(ZAC%QDr+I)X|44h>=_GVQDL< z4_ZUmo>_k~$>~g*W-pu59pngseFrfKRv?X^Ros44k2M#HuFPge2y~ym1e`8@zrDZX z1+it${6rbTxf+Q4u{P`iM#ahuniH>J0GIE^&45qp9n{#r-B^*?(iTG^2_GN|*gYBPo&T~Vlmu#} z*|gG|0m(Xlf9)vPgRI#p;iaZG3%9(OdnP7<3dU73W$IDw?eD<2KgJ zgs$dS;DxRo#X3Co78@wp8O1S^s%D;SGmJHnA*{?c`?z&>9W-!U%;UfK;Q&jx83Jb3 zb3lHt80xjzvpFLl&juOp9VuGlG$B>*4XVP8auhtDuO8 zkdxIMcVp72m|D}oJ`=-EkpdQN+6j_vQy9uRIr%4Vuhim#wc9F~vFf6&qsKVtbT8G) zx$(=4bjY4EAeZb!t&n>8lVi<`|G-><8Q?Y)%$A97go3&2ZX%vZ5KUO(ivu{k5hYD8 zz1rs+;`5oLXEx5CwAg1$w>~km1qa@4`lu4rlUw7+t%=~_RqG0~uK-`%;1Ngr!x_&g z@D45*CkRQ4ie@*I(+Iil*Cz_*oXmT_874~CT5Aw@rquZ|{(`3OhTiU%FWrJ(XI|Icw^M z(FAMEe#t9+)LvXHG-_UOG=WC&Y0>+|{%_lO{hyx|`S-&Cq7>rGf7`|yyJ~nE=--Z< zIpG#)s?yZxy26{dpcEQ(ur_vj#JIS!6zJmBvlN{On~dEZ8^V8qf^W+ieP=04SVp{L zq8?=dOIhD!-@Xetc?&L*0q^L4>Q`fa2m6*Z6}RwJ85h* zww-*jZQE93+qTWdR&%;9&c)vUVLi`WbBr0WJ$0(TxqLxS^PB(X3S47h2m_CvjB zB7?Uy=zA>A7`#0RX!R2 z;o7Nr!cluI)=i!ozV4x|SQ56Da&V@1u$d0BagE$bBP#08#J&lWbU)&!rc7e3I~{2p zv>JsLOVU5L%K0_>gq*5Ae$T{uIB)?>`=$!3b6 zTBrT0a5kLQ{}wuon7oC4YIu}NA+T$WH1WB9m@J^_w9R9wH!9dFjqL{|-}QX`l~Cqh zn3l`wDa!&IM_uY*vogsvuKP^?d#mjpm=4Dc@jtCVC0q1*SB`!Yjhs9C?}@n`Bt1Fp zV*T}kFyfM_3%2|Uu2jB~*Q?mAgIp_l{N=_`YnkiB@F>4nE!Io3cK)#Tp1hpwR^E8& zT?YWh!J(*VRBJrQ#MaIz|88r^64~8Sf%j9(dW31rMA=;Cqxnz1x874+v$66THzFs? z!>mmj$Zc>4#u}6J=kL*yd?vE@kl`P%9rj6onBH0hFL0v6AGkHz0fhXAUYw?;=8zjO z^d-4w1n#wK>L)1HeTl&vRN_xr_q^N)2}U5M@`63zK0QO~5NWEMsa;7=N$n)3-j=$*Wn9dn+^T7noK(ucN@W9% z47Md5UMq809N9y}eC0a>Qbri^=ec`jhgpjp1}K*=;i2ZRh78$@XK2@j9-?26bFbfh z@asnq(O!^{o6ec_1i{t-BvJ{?!ebL+_4Fhe>?3E%7gxBrt9P`#0#IO-(?Y&j{5p?zJ- zoyysAuntO>Ym}of{o_W6edLMd73CSc8TRBgfo^1GKkPqlyF2|l6F6ky&M27V3#Ts@2vRIH*{iygOb~`f|oexMToOL4dkot;ZCLlfShXg?hY3*`P zTPqH5L{fWfRTDiz{0lCUolF#xtkXAcM2ktfHj6s;R%@uDQE#%2H2!*o^r=V~dxjJ1 z*vlm3mzr}qwm%(ZJYWoF$kB!uSiyQpxu?wIMjE1nUQT&lbxnl>89fa6JIuk?p70+P z2a>f0k(R0`6gy|9hk8(GZh+=nqjC41XK@MNgbS8@$^1~qzE!+aQSJtzD1j0Bk(-$| zIr8diKlRD6&y3?Zcm&d@o7{?N805=PMbXQz`|ck-X(-7=>iD_LI;WHRBk&Snp1-|3 z*rJ%TI6{JcYq$S+T?WWqsw-Zc81u)EL(2|Qe zE*ENq>O|eRvg$TDIrS~W6eq@WWJy@}de}C{sV=?BxxQjmts0_MjZPrh&%mFq+Db0j z*{`b?#d`s44Rzg7b12!*45f?JVHY3XgBpKIG8)Eh@9}$9YVy|DB1;jQpZ`>%?2%u` zo@dR7o}5LTW!8rFk;w@8hSLEJ#ygD5dMC(k4{A4urO9-M_Op%TXtJ zULnG0+8z1?5+54IVAqFLQOMJ0QAYYi`rYaUf=?M3=rOV;)aXQK=exsgN0BHYB&p}+ z{W(IbecGka*X=1FDGA{f(M{ERjkb^a=EqxXH_MVWM5r;8+Zxzouy3bwqYx(>0;(s* zxJ^-slyA3(pMbR%MJkp+QnW0|Cif+g#}`^&X!ib0=#DqIrx@rj#SBf|%`BpA@P5zH z8g0(csXG5dH4tJRx1cRVzR>=Rks$x(?T1hO*ZpJPMb zKvq;rmqeaa;-vxGL|5#bA5=U$i^A0>m`4xeb!P4Sbk>wj%`(~TYJTzextmh6Az11p z^E%V}*5^6L>#FS}=RViz>bL&aloKP$9L--P>Lp+fa6c6|>)}29Y%%vOpZ#(l6(e*% zb$Clo^_A#I(ZJque1c6pR9G~+y#=BW<@0c__ zx(vWc^}G8i0>8rE{m?V$93Ar1&pEpL+04$(fu&AiRyNp`3Z0YuC7o-M+uDG@mVm^Gfm67L>0tdcME^L5M z9;aNzjLZbb!1&JJd3U$HiOXnkax~9&ScvZWdV6uJvD#~8`Dt6Rt`yfg+v~x{^Os62 z0!PTCF&X>jq{=czY_Tk#sqIpsg*k@VUGtOO>g;w0E!yVx^q>%w5*yRh`sRj{s+|{A zQ)M++1AhOn*_!Ioj*hNsM4mtAaIV1b=ZELZb68hbNRi7lO~U^DBXrrn+fObRk<35Z z3UBue9b$sBZx8Jc?0+IkL=S&T@x}j0h|YFI$)Lee_5jU5^sQ?RWrBlNO2JOS3IWRNUR~Uz;ewb>#+%A(%H) z#f*>}gUf$=h7{&RH=%2%XW87=5vxQGMqNFe+LEr7UdQ0{&)o{~wW}(K53W*hPsKxj zcb%4P_K&!SJgE1n6E@F~N>M+__H-=p7-Cg!0~t6J^4_Sv-V}}@Pk`rFAW`sEbvXNh z(+Tkc7ZdOcU)DHwSx45lTiFwEy=H=(IzB_&OKONKN4y&1rk2|a>R+LS$8yQu@}F6M z=a@Nt*nwy;Ydk=!h3@6O`zq_z)RHP|gGR!OfG3?VIcCGYiLvY}3bEOW3$PX#f^V$v z;V_?w9>nDkEeJ^}JKd|BC6ua)Lmy+XE}E2_OyR4vrzcwXHJFtQlcED^Mz64=(#4re zBnG-HT5O@I4>W&2w5fYf>KjuTj^$+H?#7Pes4$85vIQ523WC{t$(+TdR!d#gX z>-!e<5Cs^`etP%!OIM=fG2glrVR4w*`Rp9I(FixK(tP5TNORc#=_E7$4h-Y=y*W+k zl9@j`^J9(L$xtRBXiR~?`VT4cVnpoEu~W2nmxA3AGe{9FXooD*^SyXgoG8In2vd zwy_A~#_d(@k~Q>d9JC<_3tCBkm?z^obvlV+87<(&>a`2mpnQR;xJgaDAsh<0%7*M@ z15=@nR?4*+%0lEmHjY@@9pMBA8-haZ0@!R1586ZB0%iGLlhM&+$)dosGFzNaE}1O- zP3_>3l$6LZnkot+XMi_+;RSYZ%-$eFSyv@MVzwElzOJ>%z1m-QoR+fGk=2dY1pRZ~ zohG-Hfs2#G78D2!gia-=W$cVA&o}p+SZY3VsW=2t^ANsucAQ1JjnRrbvPJ5|*%H%N ze1VJ>80N5iF!7Wu^g5H$R+9M{nuFud%5>W_%yByfyHjvW+^u>LdvAjS1R(xf(0}H# z{v{(^eo=nN8P3J%nz=D!d&Be5D~}~ z46>pkz{LOCYFPjB5(-TtFD{Z{yJlG|oT*Va6{vwiTo3rR;sK<~^omr5wp?OsMEhAS?(=bMc_|KrgcSOILA8 zal2i)CmrS5n){rG?08?f=u$>bE)8nzRS zR-At7_(`6UW1gH6x&I;!gFBtPfoR=zgHE7E-#}R2iNMPO<^9rraRAwDXbvg1Xq==uFW(SZ8Z|vW8mc9X6 zWX&%j|2~>q!a_GRuh~-5CidJIch{5EuLZaYx!fq2H4^_^XYBC*Vf|F^ zZ4%GMQ&K&a%6$3C_cd^A5G84?@6Gt(W`X?cPZ~B)8#o>Ovgd44&nTU%@a;sN*pdy) zo_wCs9orQ_1f_(FQv{$U_WdhA%(mpdEC$}F-JkccRQnX^tp!C1#wQD7*5)C6^X12I z?j$Y%d!TR|3i-8_@I^2`+mqTI_9T<{hlqpg zmcF+9sQnF9#W4Wy*P*vK^G@h;Amf}EYoyx3=joEhp9c^=sxLrGg`vf44HY(NG)J+| z|F?U2U_kV$f4xSVN0tuQufwaVu{g&Bm6DqFM3r%*Zb*E@1)0OknrZfV29iRO0Y;K6h1VcKwT!0*Za171EDtI+fsc@_|X>g|s zNk=>k9ZiZ0E6-{Lz%bU&j#34iXzzv_W z2D_9C?6=D=)@M#tf14cpSP_CZZ%J}Xf0&xQpY15NS`vU$89J3k;ZakLWw|a+-q1Sf zNppMF#yOe1wDEPAbLJ@w6t{^&-U#_r;o65=9~Hwp-A@0E@GGYUMy)A2`cmpuC`d$*xH`Q(~S z)I#_{A-VTwlQ$upw&Un*STJ3R3SNO8*A%K2k*2wUtpq|}{&)nn0b`9yM^+?Z1=mk+ zO0_MZYB0qslkYW?8q|d4XFKz1B7EPGyaoaeW=>7tV37Vg8P7eR5q*+wfymh&iaDd^ zN^smWa}TmP({jw(bfT=O865K){6a@r$6BUd<&vX>eueAMk(u!?Mavj8$KykMSd*Dq zfD8K~Hh(7ZG~pb<<_I*)x@IPgFAbF0CNnd; z(AwglQw8@c1&g4g+(vo)r^eALl*>f&SI|6l^EuEwmGfJSL19sOkmpcAzGQXi+8D|* z{O+Wc_>+=gvg!>I{!pu(M$`%0DGK?7GHTj zQvM5soNUybecue#S5)q-U*Q?+5f8Y)E2RhP-d<;d%}&V27sTGyiLYMIM_Ih#lyo*G8-5Tx!Q7JQc&3id{kCsLB(^v-K>GYyTAh6-=qBd9_d;JZ> zf|;n9nCRSF-K@|Igh^RhKzyTmRfs!n(k~K%ND*t3YMS8BZm`-tNGyn;8y9eXYW!$3 zMqZPmvu~L%04^w9_lELDnm!!7{bRXy6mDjEY|V)+ZM&FI`{|I19X)vuda{{RWW{;u z)z$P=YlmS3&RI9);fj05mWjaGhjL{;JR~GT$G3DRSn5}=(gp7HEHqY# zUco3+)h4Z)IGp-hwoX*X7&WlPM#D_;p-Qswh{4%|nePeLof2(nfGsRpS@+jFDH~EH zKqfw?rT2RmbS5(RG(G2ewd8ug-byd%ec$cK17+N-U+=r}Lss6T1j>t(yFEC2vw2Iw z_6Ni#xo4LoD-fL1I~t!=9V^+f9}+IJu5enLUsz{PpDb(O6&l0@dJ2@1Kt9QW@J-{v zfJ+S}3LwCUT&l7%`BDvy^JvapD zziav5dg)nrpE`uWB6jd`6s<(S(66{zrF~Ap@p)5d-_=;V0v58xzu-S^X$nr+&V?D) zrR*dloi#@4=zqp6e!9&MM81h=aa6S51#7|hzeg<};xhTy+7Tt*a=$F?L`3lPE z5H1EvfO`Cmu-Y(5j{>RS&4gCgYomh#AQ?AxwrA{VM=5(SdRmGQ^{@XdSD81*w>!Ao zE^Iu#f9$gk8367-I&tF11y18ZLNXl87dg^F33_)NFZ86ZA1}T`Sgeh4zuZK0>;FEvO*+*?-w{r=VKv zy7I4~fa>CoovB-6hvrWs{@hNE>#m*8_rJc^mup|V4?p}|UPefo`uBPiQ&|kcp#H2B)??6YgN!qdayMyd(4{)tV2>`Tya0;=&-t@O8~@_9dy#jKm0ZU&?FpfQpZ56ReK>*O==^LBb3jF>gc#o7LY<_t-5SNGmbo;#^< z0hOu}01(w}@f87R7!)t5SyWgst|&oS#Nof0i7M1+($=*nr7*CZm4);ytB1u;_bn7)KJ5|?g(C%K>6`(zmZ?%^{mh2B?bZO%s^QyQxX+2dmPhU)yY0WbPh@r!f=_dzI7$TRK=V)q~n=*Jbhb1Z;Z^k}pL; zKq3kOk(E;kC3zM~D=V%nM{Y^chcv==$Jj}_i}rEcmIc@uiubpmdqeG@Q`yOvH5cxB zz3^ivLx7ys7zPW(-H1R47}XFSP@?!&?3%r_1vtF~2k7rJLBt-Y!}?CW0fAVCK#4L7 zYv>vbfaWm4FCCE6Ye)Ve-*ydPG*7GdYk?XF8T#5@o`qrrGLmFj_(1N!tfB;7_4`@D*F!R7SYcyAU~V9b#XjE=5$ z#UzF>JWxE1bTbD z-*lGJM!zNQiL&BcMOAj91x@fRywj@hG2 zmB&N?8>X<41q^;r5qK?p|9!(x$$W6Af=xxL^h)Wn+^$-(?#icC?yce9!H7Za`z=b# z)fc%;dBskfHbX`X8gRWpcALR5nA>SUKNV^SdM292pk1e}FpZV4O zctIFCXlNo*(R!)pj?LUeLmAyYar<8S6oXODyF2uG+i*)K`xoy9Qn)ydQexLS^0|%g zLUse>W-lZw{h(j|{AGuV+ryjGUoWa_DGp3M+_jWU#{LxVL48?ZVuHrp1S0eAwOJEw z1l~EZrezdtl~J=4J!^!wguA+YE&H@~S-w8E4beMNS;c-SlHmRFq%0zdTM0)z&qCv9 z_Su$b53XnfD{{7um;S{+(3PN+@U|^rC{0 zryteC4KEJZAmTjm;Ej{IKp-W^;rZ=3l5H+9AQ#+O+|#=yKkG4R%nS*y3P3WkpyLMf zu!lw8mX<1P@MJ=;pi3`sW4wHuZ#4$R#how95rngW-hTL=B7ZQSGi*VZDHvCBM5$m1 zF_l`3O!AftmNR?)PV^c(aJ?aH^~I|8Sd-Jc+DTD0ojwa3Bfhc}46-uJ#Hr~Efy-Iw zNQqi3x`(RQzr=m9<{XKPUQ2a&5?S4{E;qH6&S03+A|~e!vw@q zZh0_Cp@#rq?^l=W#fom)@r25FtwLk>=LBI4Pd1aPoU4nkj}}^U?&^Jeb+dQ_5duG4 z*3fLz{E?tUb;wRfI(LQ^w^}2HT^CVowPAj51#S5D&+`jk{K%&g=Q%j-W9nbZ4yre;4{s(izp^_8u3ncj-&05|+T-Qp7?0}(k3(Z$P zV<^h|O_w)Z=~f{s{QifoEMb7`x>|h5R?seL&;y@}u5ZGYU)KXVk<`1?4u3yeK6l`! z)-5OGnTmnVrp)i(x$d#yUiNURMTiRFmYWe^WJh>7x?@MJ(XD6&&(q(3lBuj)_$s7r~F>yb<2`0!y$wYI-N6LbZfxQ%fR90m+Y)T>EyXtRccO$(u;y)?G zWg!cz?hVF|Gz3D!fmv8M5;~svg;%_g1ALLnL7u0T8Bbb!pO1640*7DU{@b6PJ5oCL z`WFqu{zoOC|9>h$B26h9U=6oy_W@EYOS(tP1zGHc5t_dX|k?eqS5gb{?CmmNt$KBO2txD$SYnf{b& z+~J?uOpad(FFtkPRpY+Ki2+|;E%G-JX49;f}=MDE2}}s>+49uOIu{@ zX`v!P%kfk;x|pJjS*tzL(eE|krh8Oj=+rXKCvm(d_StHq^{m}22Q%Q=+%w=%F_O#e zQu-QY=nKMJR8Er)*bs24IAp2ybozReiLTcesMW>cex`M z6@z6I7vtlgCMELB!W3I0;7oxWQ10{4JtMrC6}QVWF?L%^KX1yJlj&U2>L2i@GQrQolHhqp* z6Wce)ZKPo^(z@jLX@C~SeMJ1Pmk9~dzU9ZdoVZ&~2WY`~>!>aXP_m?RczA5hmz>Q8 zf6HLETIh2A8DWtzpTtTphq*9*m(WQD);O5XVFOB|7_X~@9Pfi%O+o{a(F9Hv)&P4I zLA4uz3%VbYH{|{0v@>a(&^f=nv!d^L?d8VxO!w8;naO*<14T$&5d2Xik9mV;5mB5@ zBNxuP0Km?I7jen!m0qY!v#{oz5&yj{kFE5mne~+S9q0GmaxRO|` z$sku2_ua8NSKZt@Lbi7CjMTdV-nVzgWxjU44aiY{Zxb?IhJG#`>;KK2Y+snWA_cS$ z%W=~mJmPR%G~taH+6S`Y7ITT5S|?P~`)<>bYO`)v+_DP*voqDqb-Jahogx{CXAda3 z<+qwRx%9Cor_S7&+|>u{(Hk!7M2jm9p}F)PXGs)A4yp3mt=b25(Q&UFxd$W#C@sbH4~!y6E2<-)^qezJl?^>>XzQ!xHscWi#=mg@adE8sVxNK{Lpu4^}x1GZ91rp#(>t=Brs9hOq2qH!~3wl!Kj=#`Zg z+K%NLDU62OEw%oLaxSY*u-5Q1JQzKxu_QEnc(WxkqFkRhpvW#{?uXZ8)C8>|*IT-h zPv#KNDlHUI)GzEH@1RExPJJ)Yw1vY}FFiR*B3QVp0gIe#4pZcxvl$rPWLtI40+u!i zq{s(&s@e9!R9Cib$rCT8(#qW{9SUddR}qL#w2@oA=t5vQY`)}5cXVbE!4B1bpLKtrBWKasWkkb>ukCNS0V7NwsdXoRD*a=bgYCz)8R zn+)Oh_G*>b&X?I8Jdd}LiWY!qG-%*M_xE(d;;*+ROLpYAHmsY7?p4#S02-AI(p!F^ zCzfuU54mGCU#dVIi|vuI;Dbt4@+CuW_^@60%L_WWv`$E`=N+A)VWF8R*hD=RS!Wri zE8R9X^K0xh$(4Y{xp5j~u!mHtMxZh|N7^*!wru}V;#_#ai594yBZw9lV09@?hIV^8 zvb0y`{cfDiFMVDw+_6s{4J@p+)x*#w9R?WwPPSGE^1{RQ;^~Kxeppj zkSDi)`5>LeDMSDvw^&2y>dm2t-83gJ*fajg3&PKtfdf8;N+&-N!;{y*&8}%0iYlAv z`cKn0yRC@PLsbx!+fak+La69{Ytk8pYO+&u-k+ z%x(qzE@TQJMJ*?w0{GmF@T_Vxu zShGX8L*T0oCfH}%&mm%1jwMMm?xNWJeXxMG!k;pqSRX^X&`!&ziICf%BVW#E zN_N=(%P?ax;B|zK!S#ZkMx@Axt;;rtj^&igb30F9&I*!GIu`rE>MdGGVKx!cCxC(N z^uRe>2&`!*ukz)d^Chi9Z_T+&NPRXLQdd0H>H{Ls4%o#-=nl7Ae!=i)TiV@taSgoQ z-B1ebMqI~)uIEAcOR@uj>_{#eXRfKO9^F5-%XpiLOzmjql!b*xM0>qgi}j(}y|G(+ zdxFp%+7sh3U>noVy1NnSE1&KIID|?bv@`7-jg45SlJl571 z)0zxF4D7oiq1W1k{1ReW4mE)(I%ys3_2>(6uKB)xYe2~?G%dUm{=8Y}rP!$7zW{)SaWc@brYM+LuuJn_wlShyIMFH=dU?=Xw z8dWP-o`xTzwZ<);bw#a$J}}q95dY)f=Nk8ewae&+<)f-^C%N>*K+sduTi6b6WZst! zJVyfEp%vB|yq!fK{q=Hdj#HXqrh!}r9{5Y(jiAzPcZ2v63i%}oBCyoOYz*5PgP33zGw zs2J{Hd3pYT3j7)c`X3ldyIEh@{x9CD-T*yD+-mP?U+2o&)bhJ{*4=qw!-R&+TjnvS+{zEIL#HRMsiBfk5~* zI~}7`ysPbIRp6YZS)F1+E7{`h9q^Vs*(YzQn#^x%<3Zjz@)nOF)LhD2{wJc4!lx*2 zG0Qp7N-d=ZC0(0DN6&XqPhPr06x*ko#3uO~X}+FbBwG|>9O-DtQag1OKodw^%bF2R zxXgb!b11V$*gWbcquad{h>x`YVVffVa_VFMX(d6Q^N@aYPHSE?z_KSw z-6064WZJ)w^a^UJ(y1w?h>l7*$N4=QQ;Xj%N5f#{JQRnxqpIuL(%+m#-JYm$erEFc zYsHK)ui`sn_J(5*{>)8&Fp!8aM}Vu}(=DHjy@j~=^W|Elp;gs4itPO3|YQrda-r3bnTmHw)5e;1RfLe0<&*@yO<-5|h!^0EhR~E?i@s82|vL{{~05FxrMq-Bec&b>9o|g|7 z<}4-$VUX2a90_e6I&btO`U z^Y5WwAG)J*7}>okw%FGzpP#yqIJ3A?J*R6RH4&Zn!V=vYwcF z;V0QP11JO|@V15yrlQCs>1n03N9Jki7v;lRQ{YHwfv);Ks;<-(JAAE5=?#17a46CN z!eeC)OAn41X^uf(l4uU28<-9oO5u~iFH)2fM5(6GubShD(#?zYNv9i$yk{zKR+O)= zxu$@+T$sM9a|;qZGEfx9v3prspxEu4D8e5V3-?fYiDQ6+Ek zM9d@-A2=%3K-AKjb7u=v&X-5b{GPVZQ-{Q{Ji~WsZ7DQ9#UbB~iS)YFRpiDX zdO%UHatl%h-SNrz40ZcG$MabHCBuPrkMxP;Z_bs6xA<0_D}T2wAMF1Te*bRq)GXKy zpKRMPIN}wOlX`Hx2}eOG$WL)5z(i81CaK%wR;jDR^iosp`D z5e{`n=1*>|x-hZj>BE6>476?-Y_q2|Lk(Yo9Wp?!*7UBj<&csb7aEnevR1z4bLv%%gGXA~-ZcCgw8 zQA2@9jVOf(vgp6m`a#@hRwB;oKoXRoC3_H-+^H$3PWV==DkMJ}mB8Mfv&*W+=G@`s zd3b<_!Dc)wPbF%w0*fT+8uqpOLe@+`DD12+hNC`QxPXKZNF(TMRWUB{qg>OsI9{lX zHu14a&dKvC<-Vk)g>R?qh$_?hP!>qsJO~*8bfcap)_ur))g)g4*W4EP9bQ46I8-c; zXk$JfN;jd*`xy(T2Cqmcn%A!Ft1 zB12n8V-#`+Wua+B1pK>=Y~_gLmYC=1o6}W+epmR$3|e=Nr{RqJme{vKgLRE_RL0+V z@j#E>3u}SR7efid{iu0%akfG8V?2@5BFFPB#_{-F<@E5&&!DC)H;-}w<$FHnj4p@d z#GVx~jQDSkSy*S<4C2QEOQt=5R0bcDZn`H?9_d;8v~`=BBTfl@_WSHOucOY@QNAYn*^DNHBd8VsGU8pPc7{+H83=K&a?n5R(xmos6g zoFmTdnkczR4a3L4?|j+mo~YXLkx%xqI;UW%&Ql4@`ujqy1$N#-)@c{U9BzE+Eukf#nUC?)*PiJwf(J%01@TLN}m{9N!`p?A%1SKVv&NdIk zDf>~|A=0}6-!}t+-{ZZ2YrP^8wlHoHe%?!d0n7Utoj-BAFLy`o^ctK+1ab{SDSbr` zM*e{Ro@++Lla%>8_31VC;e=WJK9}H)2khK)-rV)COT=9|fr9&gc!q9)p}(nuXAp-g zxdSwe{_By@8a;kqe^FXJu?>776hD7Am?Q4CM<4soKPOKl2P`834q6;j;6su2$0Y0E z?E>Glgq^v|zTlhNP^|PpTo_Mr+&z{2KX2(E3Dl>faImKD;2@rif`;`?`?dvrzmTRM z&8(wxJ)_ku9umYaSc8zcMH_!m2;LkskZ3kR$TUa81^k&n8VV09J&^OZbc}DyUB4=P z@;x`Nplf(5zt6D-AeWaC)cfwQlOB|_=`FeuMn7qfiahQ%Qd##Th%3Px)}@c6;O1Pa zYdr(T`Do45h*z=|^X=8yoQVB61og%;IevDZ@u*U0! zHg@^%pUGkEF|ra~%bZ*O-36wpm(kmdbd%7bDl~Co{4L~b)+lP+O)i-X1pJC(*$RVprFj3^ys{3g5 zpJ<`(#JQahL^)v!-dLxAX&j1uwy{+&hu{-Pv9MNf1)(cs)3Ro|W zvs2HkRZ0^;)Snj|7RkA**MoAXR~hvRKa^01?^-V)X5`&*r zN<>(F)cvW-lOmXx1-;|BD?^?n z#+Hw0h4=-!FfXN-CBMmz%^=knvAO`oVnaZO=6w+vJt8=-5ghD091i>ym2Tjgl7#F-V`!H}0^6wx zgFa{tkI;bTF4Ew!_fwno6aJQI^yk@BzB4#*SDrEH(}HU6t*Pl9Lzk!A+m4HW%{L-h zilpdx>98I9tIjVgF$@K zN#OW1nrh^bD2TG3Q8%gYstK_We*Az$b0+cZ7wj28;%1#`8){$geLPsTqFO3`-MfVNZOMVoK8(fk}W*P-c zBg=j6=jGMo%#MD~w>;1Z?xNoLT|?001Oq{_KnWOk**)HL2xf&*Uh>AWz68h_EG(!P zLU;K>R8E`JK0xs@3^-1)f?9rBhFoUZdStuWfNxMzi0qK7jA3h`e(pNyBMuaHtMDDA zy@z|8W&*pcbV89UpgNCcv=>*M-B4<&~!k%d}nZdn-;flQwz% zW1(-0!=QUbyqv{K!>#q#dh^I?{I%j(_{_4_(%D)4E{ckWeWpOSe|_x%pzL zx@#rV4yc4QHc0DB6K>yo`)2nWt7w|}A^8>3*l^X4Hyt#cSQ0m`kXrfcRh4LDh}4=r z=FcYx#Z7HO|Cc)6n>mTNPY}ji)eYC)eLtpfE~xm41W!Pv?j*|t$5d|br1jUo>I>@+ zw5A{OK@N9bRD@#MLEoA@!VHTJ;^0jqe}o7K<^lFdI-$6y*y1gN6d0Zr2x$U>U#|Rg z4B(ji{!X_xSeX0hf36B`o!-zM;L!Lc<@1i^IrFhx!eP+nx@Lz_R~^vFC<0|^gs%Ge z&?RLdsSAhyd=o|#!BwCUV#PKVhjG+LC>SGhDl2~g8H0_ZCLhg%XRZaOE*F9{i4$9- zdsGA&gNbWEAtMgtRS!tBj0=Kqh{*U&K;-d_xf)z*oJf^?6pT&sC*+#oR3-rt#5ZPC zOVj_gqa;4c5YhkjzvH2SfKdIX|2^RbD$#fW33vujPq4po=wA;HG?*c+;gN^^;;iAp zp=pa&)ApA|ep`nTS98gjy$dc=m!j^XWz5Yx7tz{e#9cYhrl(<8<8b7ot~+0My_+2_ zJb7&M6eV&}eF|NB<~+auIpOQNyT;Uqtb_PUxDAVv5OJ3kLf@u2uz?NWEEVkEcs+E$ z2Ckv^vYEGwcj33I^Dq>s(n6h>w+ju3r9=A>MwV<$9;7 zD}>&_&zyL;vj@fAd?-->QR;+;F@@1qpv-`$d;GALTJiuTP*3egpeBU+%_EXt(rjH1 z4;Sa`78C30)(!_V>nuwG)~SLs0{nLw=x4kYdCN;|dYQ0+9x0ACU; zC%IWV*H!}pAERM;p=TdE^JVxxS9wp~piA#)++R36`2p(_K8MAk$vQ{hFX*t48OJ`fLxBf(AZ2x9Rs{ zxE}q7hUE}7q)^z$@W85ZQLZVWQJ7up3S8QrMi*U1(AoPTJ-@c5)tKbmh zs3i&|>=+mXifkF0WrtIj4Kvu!N{>9*nq?ZTw@@5l&6hbfwNFR`lYZby!pOCtQW=hw zA^xQw?^j2MjT>;C%_7S@i3i^QVX1AZBDbqHAq9L?TZ~HISjE@&oUY~L=ik!QMmJA& zc&?$(!WdOX=LzW)^GnOAVkDt+j3u$vscWg~*DA@xFnE5q78Q`NH$cNo zeRa5w!rIkKhpFB0Y_Pj^)GuDC!0%`NUsqQi4rTX-^V+vDVaE0*W*TWi6Jabxk;qa+ ziI6QMvX+!4Ava#W*!veJZ|DFrqm=YzLK^wAE`r^z!=>U~OV3Vv_FfD>7J8*YHm%~! z{i2$(ys;3Q^6zJ3svhgcPcu)kzU!`Qa=1Y|cNDv)#f3atToQJP{ONW=!LxkU$Mcld ztLW?k?N7SYmd#;_m4=1Os%ApHx^Ba8;NHH+fy$_A^FXcpJylG%!WgOJf=U^g?f>xJ zXqy#?(DU%4a$^l-_A&!L?_MkfS(|DMT}8TY-Hu{hU4LxZJBW~e)tV{BJt}ZZU8(2q zut_g)!eT95b;k+g?hh01YAv;vLQUutuWJj;O*@3h|bZ*~>T+4tI=&sxe|5=m9Q4zZ8i6EnieuRfWb5(|$n zPd$}$I}g)N;`a$d+11?-_^bj23!vKak6}MnT$rSGxE_h+NiGf+Jc(|vlvajPC`Qn^o zxxQ26T3fy=U-IksLSv<7*>^);AEfAbolc9zY1mK0T6(d*Jno6X54&_6H@@z2F?7!j zsN-u84LoJkqvCdGOZtzs`Y~SU&~@#RySMq{e7o9L7_aPitz^iJi+S?&DBtRd4-#WU z@Xs_@S-45bGyH4l*U^jp`ZEk+$(85;*9(j0fda8H=G2LLlET3$Q?pXCQ86Xj{CYmi zfXBwN7FZKH=?60lLYis%$;h3ERO0QgIL0{JSaA29&Pio2wLE`5zmNxML0){*o%1%P zbvX5$=<4;$f*lqgB~py*gFXuls_9?QPIoS~6nInOeXVImyF<;8ihmhVdb^2xPz1*_ zFn3Gl#4{8D+qW%IHFhlE%RP#{e-7heb1RF0`MQ6P&=qyx%94v&hePEvgec?H>bXid z#|J^Ep4cYtFAMdKUiYHT>uoWd7F`D44mX+wBX+zp@-Y z(uK!`I8GcR)5xTx3Z4SfGe)*;iU>uIX>i;^W`2$PLctdPDpXZ_YgY^<+xCOq;f4l% zd4Wgrmq}c8Pnk1)VjsUZw+!8EsT~{{A`g5e8u9V!EZ$97=zR?N&GR)UZI?+|jnv3YA|K-``Z|OL|#yprTm(2Gyx`%v(yb(pbhK zru@vIzZ3&RHAN#Qx_kv5TG8}VyX~{Z!ySl(Kn>SOlB9+8>99CNnN)?GI1+XvePV6C z!RWlZx%KsH`D&_VYELq8Jd5u5J_|3dG!LO-m)-XD8AnwEb5z4Mb`pGAt1^x8kG03O z9t^B`_aphC^T73n?ehLa)|+7#Zb0?o%D@T)w)Vm0KD{zrLi>YiGD?tplqwb^^?5^R zVQ^cR0OXiN=z=hi7TJuLFi2sdpeA8(lc@(S34_Zb8UWQ#grZQ0DFe2NZ9rT!i0zk! zwn=~iWf;)=cS6mQY*T(f2O?tGW*=4r$j+g`R~RjV6cDkW!pHy^3F1NffE2tc{%(%w zm(Y>*=>0|@ZDFM2IyNYEkQZzoB*3dO*7?XAjS|Aeqrm}OQTPSK!EEhdBwMI3qF%)T z`iN(P<_0(OvUNm(!Vm^BMgFiTn*z!Z8s^Y=qOh!OD>@{%cx%@^TZDAx?4|M410{SqTm#yXk zaz`+b=5}`aRS}nw5iBoT5F>pQ18p_@)vqMSmLEVitr{UQQs>C103t_s%W)9UbHqcy zz^Dz(!8^|pFEd3p00#ocNRWUdU^yy-mN6oPaYsxXkQvwF(gFL&y&zFP&x%v8 z2tZGupne~qFrm+d22K+yavbDi921x!@l`4^Z79|cbezQi6w3rkKKaX(1QZqt`Vs=} zvov82nkJ4U-Ju9x9${_LgxOpx$k8~DoS$tRAir=BIB5d^p>tTXMv((>^gNPf9hjRW zL5-KeK)MDvjhubYDOspG4Ma}4K=d2zWm$0{aynBxpr|aiYcstb{1^|PEdhwm5+T3ZU#=){oFze(jcj+Sc^#n7qTxTE3w{>*{h6KdY89A1M}#@vzJ3Fc VwlMN}`%er%aGR6olj~j${vQ;P=LY}) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8fad3f5..f398c33 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index a69d9cb..65dcd68 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,10 +80,10 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' @@ -143,12 +143,16 @@ fi if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac diff --git a/gradlew.bat b/gradlew.bat index f127cfd..93e3f59 100755 --- a/gradlew.bat +++ b/gradlew.bat @@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% From dd9c9500d341314c35bd537ac59acf2c31dcdb04 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 5 Dec 2022 23:20:54 +0100 Subject: [PATCH 622/629] lenient Docker Env properties --- .../dev/adamko/geedeecee/tasks/DockerEnvUpdateTask.kt | 4 +++- modules/infra-factorio-server/build.gradle.kts | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/tasks/DockerEnvUpdateTask.kt b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/tasks/DockerEnvUpdateTask.kt index 13332e5..6fddbd6 100644 --- a/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/tasks/DockerEnvUpdateTask.kt +++ b/gradle-plugins/docker-compose/src/main/kotlin/dev/adamko/geedeecee/tasks/DockerEnvUpdateTask.kt @@ -25,6 +25,7 @@ abstract class DockerEnvUpdateTask @Inject constructor( ) : DefaultTask() { @get:Input + @get:Optional abstract val envProperties: MapProperty @get:Input @@ -50,10 +51,11 @@ abstract class DockerEnvUpdateTask @Inject constructor( val comment: String = comment.orNull ?: " Do not edit manually. This file was created with task '$name'" + val envProperties = envProperties.getOrElse(emptyMap()) dotEnvFile.writer(charset).use { writer -> val properties = Properties() - properties.putAll(envProperties.get()) + properties.putAll(envProperties) properties.store(writer, comment) } diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index ab89991..2093c80 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -61,13 +61,15 @@ tasks.dockerComposeUp { } -val kafkatorioServerToken: String by project +val kafkatorioServerToken: String? by project tasks.dockerComposeEnvUpdate { envProperties { put("FACTORIO_VERSION", libs.versions.factorio) - put("KAFKATORIO_TOKEN", kafkatorioServerToken) + kafkatorioServerToken?.let { token -> + put("KAFKATORIO_TOKEN", token) + } } } From c015e9c4784a7722ebfb9dca42c5e7b78873948c Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 5 Dec 2022 23:21:29 +0100 Subject: [PATCH 623/629] add 'skip worktree' example command --- kt52647.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/kt52647.gradle.kts b/kt52647.gradle.kts index f610b1e..2923b90 100644 --- a/kt52647.gradle.kts +++ b/kt52647.gradle.kts @@ -1,4 +1,5 @@ +// git update-index --skip-worktree kt52647.gradle.kts val projectsMustBeConfiguringBuster by tasks.registering { val buildFile = layout.projectDirectory.file("kt52647.gradle.kts").asFile From fcb870072a174d00775481b940ba223f84fc0a7e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 6 Dec 2022 00:23:52 +0100 Subject: [PATCH 624/629] version bumps --- gradle/kotlin-js-store/yarn.lock | 184 +++++++++--------- gradle/libs.versions.toml | 26 +-- modules/events-mod/package-lock.json | 36 ++-- modules/events-mod/package.json | 8 +- .../src/generated/lua/lualib_bundle.lua | 46 ++--- .../adamko/kafkatorio/webmap/FactorioMap.kt | 2 +- .../kafkatorio/webmap/state/PlayerState.kt | 2 +- 7 files changed, 151 insertions(+), 153 deletions(-) diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index b4568f5..43a23de 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -19,10 +19,10 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== -"@fortawesome/fontawesome-free@^6.2.0": - version "6.2.0" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.2.0.tgz#ba3510825b332816fe7190f28827f8cb33a298b5" - integrity sha512-CNR7qRIfCwWHNN7FnKUniva94edPdyQzil/zCwk3v6k4R6rR2Fr8i4s3PM7n/lyfPA6Zfko9z5WDzFxG9SW1uQ== +"@fortawesome/fontawesome-free@^6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.2.1.tgz#344baf6ff9eaad7a73cff067d8c56bfc11ae5304" + integrity sha512-viouXhegu/TjkvYQoiRZK3aax69dGXxgEjpvZW81wIJdxm5Fnvp3VVIP4VHKqX4SvFw6qpmkILkD4RJWAdrt7A== "@leichtgewicht/ip-codec@^2.0.1": version "2.0.4" @@ -126,10 +126,10 @@ "@types/qs" "*" "@types/serve-static" "*" -"@types/geojson@7946.0.8": - version "7946.0.8" - resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" - integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA== +"@types/geojson@7946.0.10": + version "7946.0.10" + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.10.tgz#6dfbf5ea17142f7f9a043809f1cd4c448cb68249" + integrity sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA== "@types/glob@5 - 7": version "7.2.0" @@ -336,22 +336,20 @@ "@webassemblyjs/ast" "1.11.1" "@xtuc/long" "4.2.2" -"@webpack-cli/configtest@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" - integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== +"@webpack-cli/configtest@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-2.0.1.tgz#a69720f6c9bad6aef54a8fa6ba9c3533e7ef4c7f" + integrity sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A== -"@webpack-cli/info@^1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" - integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== - dependencies: - envinfo "^7.7.3" +"@webpack-cli/info@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-2.0.1.tgz#eed745799c910d20081e06e5177c2b2569f166c0" + integrity sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA== -"@webpack-cli/serve@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" - integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== +"@webpack-cli/serve@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.1.tgz#34bdc31727a1889198855913db2f270ace6d7bf8" + integrity sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw== "@xtuc/ieee754@^1.2.0": version "1.2.0" @@ -530,15 +528,15 @@ bonjour-service@^1.0.11: fast-deep-equal "^3.1.3" multicast-dns "^7.2.5" -bootstrap-icons@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.9.1.tgz#cf22d91a25447645e45c49ebde4e56eafdfe761b" - integrity sha512-d4ZkO30MIkAhQ2nNRJqKXJVEQorALGbLWTuRxyCTJF96lRIV6imcgMehWGJUiJMJhglN0o2tqLIeDnMdiQEE9g== +bootstrap-icons@^1.10.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.10.2.tgz#6a5729e0475e007ed82d752225645e4e6fec48d7" + integrity sha512-PTPYadRn1AMGr+QTSxe4ZCc+Wzv9DGZxbi3lNse/dajqV31n2/wl/7NX78ZpkvFgRNmH4ogdIQPQmxAfhEV6nA== -bootstrap@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.2.2.tgz#834e053eed584a65e244d8aa112a6959f56e27a0" - integrity sha512-dEtzMTV71n6Fhmbg4fYJzQsw1N29hJKO1js5ackCgIpDcGid2ETMGC6zwSYw09v05Y+oRdQ9loC54zB1La3hHQ== +bootstrap@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.2.3.tgz#54739f4414de121b9785c5da3c87b37ff008322b" + integrity sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ== brace-expansion@^1.1.7: version "1.1.11" @@ -715,10 +713,10 @@ commander@^6.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== -commander@^7.0.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== +commander@^9.4.1: + version "9.4.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd" + integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw== component-emitter@~1.3.0: version "1.3.0" @@ -814,19 +812,19 @@ cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -css-loader@^6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.1.tgz#e98106f154f6e1baf3fc3bc455cb9981c1d5fd2e" - integrity sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw== +css-loader@^6.7.2: + version "6.7.2" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.2.tgz#26bc22401b5921686a10fbeba75d124228302304" + integrity sha512-oqGbbVcBJkm8QwmnNzrFrWTnudnRZC+1eXikLJl0n4ljcfotgRifpg2a1lKy8jTrc4/d9A/ap1GFq1jDKG7J+Q== dependencies: icss-utils "^5.1.0" - postcss "^8.4.7" + postcss "^8.4.18" postcss-modules-extract-imports "^3.0.0" postcss-modules-local-by-default "^4.0.0" postcss-modules-scope "^3.0.0" postcss-modules-values "^4.0.0" postcss-value-parser "^4.2.0" - semver "^7.3.5" + semver "^7.3.8" css-selector-parser@^1.3: version "1.4.1" @@ -1554,10 +1552,10 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== -interpret@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" - integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== +interpret@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4" + integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ== ipaddr.js@1.9.1: version "1.9.1" @@ -1576,10 +1574,10 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-core-module@^2.8.1: - version "2.9.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" - integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== +is-core-module@^2.9.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" + integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== dependencies: has "^1.0.3" @@ -1781,15 +1779,15 @@ kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -kvision-assets@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-6.0.0.tgz#de17ec942efd067fc180e7fab4e040c4e41bbe25" - integrity sha512-fjPGTMGiboRnXXwhQFVOsRdDaDFnBfAQBRGhbzjQUp5oJKUnPS303Pua0u5atQdYMXyN/u6fyH6TEHgQzM9Wog== +kvision-assets@^7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-7.0.4.tgz#59c62f38b15b44db10699305159be63828a5e645" + integrity sha512-DY2j6Wm3vaMWwBSjnhutOKZQA6pzOvL40hAkUUc52QkrRn4K2E7GHdWR1qGIR4/YyraWvzkVWasr6R4vg8l9mQ== -leaflet@^1.9.2: - version "1.9.2" - resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.9.2.tgz#168b6c6ef1d4d1e8409bde2c4ad050c249c4dbe6" - integrity sha512-Kc77HQvWO+y9y2oIs3dn5h5sy2kr3j41ewdqCMEUA4N89lgfUUfOBy7wnnHEstDpefiGFObq12FdopGRMx4J7g== +leaflet@^1.9.3: + version "1.9.3" + resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.9.3.tgz#52ec436954964e2d3d39e0d433da4b2500d74414" + integrity sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ== loader-runner@^4.2.0: version "4.3.0" @@ -1984,11 +1982,16 @@ multicast-dns@^7.2.5: dns-packet "^5.2.2" thunky "^1.0.2" -nanoid@3.3.3, nanoid@^3.3.1: +nanoid@3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== +nanoid@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" + integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== + navigo@^8.11.1: version "8.11.1" resolved "https://registry.yarnpkg.com/navigo/-/navigo-8.11.1.tgz#aca756dbca40e2da2ae688a2a247ab4f070fcf4a" @@ -2231,12 +2234,12 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8.4.7: - version "8.4.12" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.12.tgz#1e7de78733b28970fa4743f7da6f3763648b1905" - integrity sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg== +postcss@^8.4.18: + version "8.4.19" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.19.tgz#61178e2add236b17351897c8bcc0b4c8ecab56fc" + integrity sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA== dependencies: - nanoid "^3.3.1" + nanoid "^3.3.4" picocolors "^1.0.0" source-map-js "^1.0.2" @@ -2321,12 +2324,12 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -rechoir@^0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" - integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== +rechoir@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" + integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== dependencies: - resolve "^1.9.0" + resolve "^1.20.0" redux-thunk@^2.4.1: version "2.4.1" @@ -2372,12 +2375,12 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve@^1.9.0: - version "1.22.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" - integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== +resolve@^1.20.0: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== dependencies: - is-core-module "^2.8.1" + is-core-module "^2.9.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -2444,10 +2447,10 @@ selfsigned@^2.1.1: dependencies: node-forge "^1" -semver@^7.3.5: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== +semver@^7.3.8: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== dependencies: lru-cache "^6.0.0" @@ -2878,22 +2881,23 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" -webpack-cli@4.10.0: - version "4.10.0" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" - integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== +webpack-cli@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.0.0.tgz#bd380a9653e0cd1a08916c4ff1adea17201ef68f" + integrity sha512-AACDTo20yG+xn6HPW5xjbn2Be4KUzQPebWXsDMHwPPyKh9OnTOJgZN2Nc+g/FZKV3ObRTYsGvibAvc+5jAUrVA== dependencies: "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.2.0" - "@webpack-cli/info" "^1.5.0" - "@webpack-cli/serve" "^1.7.0" + "@webpack-cli/configtest" "^2.0.0" + "@webpack-cli/info" "^2.0.0" + "@webpack-cli/serve" "^2.0.0" colorette "^2.0.14" - commander "^7.0.0" + commander "^9.4.1" cross-spawn "^7.0.3" + envinfo "^7.7.3" fastest-levenshtein "^1.0.12" import-local "^3.0.2" - interpret "^2.2.0" - rechoir "^0.7.0" + interpret "^3.1.1" + rechoir "^0.8.0" webpack-merge "^5.7.3" webpack-dev-middleware@^5.3.1: @@ -2962,10 +2966,10 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@5.74.0: - version "5.74.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" - integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== +webpack@5.75.0: + version "5.75.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.75.0.tgz#1e440468647b2505860e94c9ff3e44d5b582c152" + integrity sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0dbb334..0223be4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,13 +6,13 @@ ## compilation ## jvm = "11" -kotlin = "1.7.20" +kotlin = "1.7.22" ## libs ## camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" kafka = "3.3.1" # https://kafka.apache.org/downloads -kvision = "5.16.2" # https://github.com/rjaros/kvision/releases +kvision = "5.18.1" # https://github.com/rjaros/kvision/releases log4j2 = "2.17.2" okio = "3.2.0" # https://search.maven.org/artifact/com.squareup.okio/okio qosLogback = "1.2.11" @@ -25,7 +25,7 @@ kxs-charleskornKaml = "0.44.0" kxs-mamoeYamlkt = "0.12.0" kxs-kxsTsGen = "0.2.1" -kotlinJsWrappers = "1.0.0-pre.413" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom +kotlinJsWrappers = "1.0.0-pre.456" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom kotlinx-cli = "0.3.5" # https://github.com/Kotlin/kotlinx-cli/releases kotlinx-coroutines = "1.6.4" # https://github.com/Kotlin/kotlinx.coroutines/releases @@ -35,9 +35,9 @@ kotlinx-nodejs = "0.0.7" kSvgDsl = "v2.2.0" -ktor = "2.1.2" # https://github.com/ktorio/ktor/releases +ktor = "2.1.3" # https://github.com/ktorio/ktor/releases -hoplite = "2.6.5" # https://github.com/sksamuel/hoplite/releases +hoplite = "2.7.0" # https://github.com/sksamuel/hoplite/releases simpleSyslogParser = "1.0.0" # https://search.maven.org/artifact/com.github.palindromicity/simple-syslog @@ -51,28 +51,28 @@ nimbusJoseJwt = "9.25.6" # https://search.maven.org/artifact/com. ## npm ## -npm-luaTypes = "2.13.0" # https://www.npmjs.com/package/lua-types -npm-typescriptToLua = "1.10.1" # https://www.npmjs.com/package/typescript-to-lua -npm-typedFactorio = "1.9.0" # https://github.com/GlassBricks/typed-factorio/blob/main/Changelog.md https://www.npmjs.com/package/typed-factorio -npm-typescript = "4.8.4" # https://github.com/microsoft/TypeScript/releases +npm-luaTypes = "2.13.1" # https://www.npmjs.com/package/lua-types +npm-typescriptToLua = "1.11.1" # https://www.npmjs.com/package/typescript-to-lua +npm-typedFactorio = "1.11.0" # https://github.com/GlassBricks/typed-factorio/blob/main/Changelog.md https://www.npmjs.com/package/typed-factorio +npm-typescript = "4.9" # https://github.com/microsoft/TypeScript/releases npm-bootswatch = "5.2.2" # https://www.jsdelivr.com/package/npm/bootswatch ## test ## junit = "5.9.1" # https://github.com/junit-team/junit5/releases -kotest = "5.5.2" # https://github.com/kotest/kotest/releases -mockk = "1.13.2" # https://github.com/mockk/mockk/releases/ +kotest = "5.5.4" # https://github.com/kotest/kotest/releases +mockk = "1.13.3" # https://github.com/mockk/mockk/releases/ ## infra ## -factorio = "1.1.70" # https://www.factorio.com/download +factorio = "1.1.72" # https://www.factorio.com/download confluent-kafkaConnect = "7.0.1" grafana = "8.5.0" prometheus = "v2.34.0" ## gradle plugins ## -gradleNodePlugin = "3.4.0" # https://github.com/node-gradle/gradle-node-plugin/releases +gradleNodePlugin = "3.5.0" # https://github.com/node-gradle/gradle-node-plugin/releases ######### diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 7cafafb..b9f4330 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -10,9 +10,9 @@ "integrity": "sha512-GtmhFqyg+txpGgGLM3mlS3R6AEG9MQhKALxxcbr6SBzg9u7YAXcPKqUBaBYd6nH+Pi/eQLcWz4BNOLhz8v4TjQ==" }, "enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", + "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", "requires": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -37,17 +37,17 @@ } }, "is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "requires": { "has": "^1.0.3" } }, "lua-types": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.0.tgz", - "integrity": "sha512-wra+mIPZlcbm8bYoM6QutEwTOAjZ9KyKMiaidGeZ+QJItIAK9hwG+1I6GCDKnW0T9E/Xv2IoTFtZwxQv4zAIJw==" + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.1.tgz", + "integrity": "sha512-rRwtvX6kS+5MpuO3xpvKsnYjdSDDI064Qq1OqX8gY+r+0l7m3dFLiZPDFoHqH22jaBpEvcHcPs6+WD7qkdmFsA==" }, "path-parse": { "version": "1.0.7", @@ -80,19 +80,19 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.9.0.tgz", - "integrity": "sha512-k3qVo5ehUYgJItQp4BT4MtAodzeUgLk3Wzf3TG53SNdce1vYfIdmlNMjfG17wkOpoCBCA1p6XvMQxkWcbk23ZA==" + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.11.0.tgz", + "integrity": "sha512-RYCEpcECiQ2dw1tj03bPv6fRXCevuAP89ipMBv67FsY09+W7ApZkfjXIJq9RaxoIMtbGkqPUql33O/DYVMtAng==" }, "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==" + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", + "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==" }, "typescript-to-lua": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.10.1.tgz", - "integrity": "sha512-R6KQc1YzFcejyaZ9tAvVK0MFTlRS1b10vON5sxjtGVSUWl+W4KRLik0LDCgKfI0wnDQH+LNVnKBNUsBfTtEoQQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.11.1.tgz", + "integrity": "sha512-XxGOf0zBRrMocGr4BbVaJdnvnk4yTrUs0BCdamfb/Qg94hKZg8ydRUy17ZtHZfYmnwFupR88R5DZXIpHYP0S5g==", "requires": { "@typescript-to-lua/language-extensions": "1.0.0", "enhanced-resolve": "^5.8.2", diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index a204e60..302c099 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -11,10 +11,10 @@ }, "devDependencies": {}, "dependencies": { - "lua-types": "2.13.0", - "typescript-to-lua": "1.10.1", - "typed-factorio": "1.9.0", - "typescript": "4.8.4" + "lua-types": "2.13.1", + "typescript-to-lua": "1.11.1", + "typed-factorio": "1.11.0", + "typescript": "4.9" }, "license": "GPL-3.0-only", "peerDependencies": {}, diff --git a/modules/events-mod/src/generated/lua/lualib_bundle.lua b/modules/events-mod/src/generated/lua/lualib_bundle.lua index d72123e..43359d6 100644 --- a/modules/events-mod/src/generated/lua/lualib_bundle.lua +++ b/modules/events-mod/src/generated/lua/lualib_bundle.lua @@ -972,8 +972,7 @@ do if not rawget(metatable, "_descriptors") then metatable._descriptors = {} end - local descriptor = __TS__CloneDescriptor(desc) - metatable._descriptors[key] = descriptor + metatable._descriptors[key] = __TS__CloneDescriptor(desc) metatable.__index = descriptorIndex metatable.__newindex = descriptorNewIndex end @@ -1385,10 +1384,6 @@ local function __TS__MathSign(val) return 0 end -local function __TS__Modulo50(a, b) - return a - math.floor(a / b) * b -end - local function __TS__Number(value) local valueType = type(value) if valueType == "number" then @@ -1609,22 +1604,6 @@ local function __TS__ParseFloat(numberString) return ____number_1 end -local function __TS__StringSubstr(self, from, length) - if from ~= from then - from = 0 - end - if length ~= nil then - if length ~= length or length <= 0 then - return "" - end - length = length + from - end - if from >= 0 then - from = from + 1 - end - return string.sub(self, from, length) -end - local function __TS__StringSubstring(self, start, ____end) if ____end ~= ____end then ____end = 0 @@ -1654,9 +1633,9 @@ do base = 16 local ____TS__Match_result__0_0 if __TS__Match(hexMatch, "-") then - ____TS__Match_result__0_0 = "-" .. __TS__StringSubstr(numberString, #hexMatch) + ____TS__Match_result__0_0 = "-" .. __TS__StringSubstring(numberString, #hexMatch) else - ____TS__Match_result__0_0 = __TS__StringSubstr(numberString, #hexMatch) + ____TS__Match_result__0_0 = __TS__StringSubstring(numberString, #hexMatch) end numberString = ____TS__Match_result__0_0 end @@ -1668,7 +1647,7 @@ do if base <= 10 then ____temp_1 = __TS__StringSubstring(parseIntBasePattern, 0, base) else - ____temp_1 = __TS__StringSubstr(parseIntBasePattern, 0, 10 + 2 * (base - 10)) + ____temp_1 = __TS__StringSubstring(parseIntBasePattern, 0, 10 + 2 * (base - 10)) end local allowedDigits = ____temp_1 local pattern = ("^%s*(-?[" .. allowedDigits) .. "]*)" @@ -2378,6 +2357,22 @@ local function __TS__StringStartsWith(self, searchString, position) return string.sub(self, position + 1, #searchString + position) == searchString end +local function __TS__StringSubstr(self, from, length) + if from ~= from then + from = 0 + end + if length ~= nil then + if length ~= length or length <= 0 then + return "" + end + length = length + from + end + if from >= 0 then + from = from + 1 + end + return string.sub(self, from, length) +end + local function __TS__StringTrim(self) local result = string.gsub(self, "^[%s ]*(.-)[%s ]*$", "%1") return result @@ -2477,7 +2472,6 @@ return { __TS__MathAtan2 = __TS__MathAtan2, __TS__MathModf = __TS__MathModf, __TS__MathSign = __TS__MathSign, - __TS__Modulo50 = __TS__Modulo50, __TS__New = __TS__New, __TS__Number = __TS__Number, __TS__NumberIsFinite = __TS__NumberIsFinite, diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/FactorioMap.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/FactorioMap.kt index 3407a67..de99c9d 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/FactorioMap.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/FactorioMap.kt @@ -18,6 +18,7 @@ import io.kvision.maps.externals.leaflet.geo.LatLng import io.kvision.maps.externals.leaflet.layer.LayerGroup import io.kvision.maps.externals.leaflet.layer.tile.TileLayer import io.kvision.utils.px +import js.core.jso import kotlinx.browser.document import kotlinx.browser.window import kotlinx.coroutines.CoroutineName @@ -30,7 +31,6 @@ import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import kotlinx.js.jso import org.w3c.dom.HTMLElement import org.w3c.dom.Image import org.w3c.dom.asList diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/PlayerState.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/PlayerState.kt index 6c7c399..8497df7 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/PlayerState.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/PlayerState.kt @@ -5,7 +5,7 @@ import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import io.kvision.maps.Maps import io.kvision.maps.externals.leaflet.layer.vector.CircleMarker -import kotlinx.js.jso +import js.core.jso data class PlayerState( val index: PlayerIndex, From 2c9c442595895ff0cb164d06e854ede09f838ace Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 6 Dec 2022 00:24:17 +0100 Subject: [PATCH 625/629] typo dequed -> dequeued --- .../src/generated/lua/main/events/registerEventListeners.lua | 2 +- .../src/main/typescript/main/events/registerEventListeners.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua b/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua index 16e8d02..b2599b7 100644 --- a/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua +++ b/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua @@ -45,7 +45,7 @@ script.on_event( for ____, event in ipairs(events) do if isEventType(event, defines.events.on_chunk_generated) then local eName = Converters.eventNameString(event.name) - log((((("[on_tick:" .. tostring(event.tick)) .. "] dequed event ") .. eName) .. ", delay ") .. tostring(i)) + log((((("[on_tick:" .. tostring(event.tick)) .. "] dequeued event ") .. eName) .. ", delay ") .. tostring(i)) MapChunkUpdate:handleChunkGeneratedEvent(event, i) i = i + 1 end diff --git a/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts index 4bc1d43..cc50397 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerEventListeners.ts @@ -40,7 +40,7 @@ script.on_event(defines.events.on_tick, (event: OnTickEvent) => { if (isEventType(event, defines.events.on_chunk_generated)) { let eName = Converters.eventNameString(event.name) - log(`[on_tick:${event.tick}] dequed event ${eName}, delay ${i}`) + log(`[on_tick:${event.tick}] dequeued event ${eName}, delay ${i}`) MapChunkUpdate.handleChunkGeneratedEvent(event, i) i += 1 } From 9f2b9cbd5c39c2dedd6f772717de70a484f67922 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 18 Dec 2022 01:40:40 +0100 Subject: [PATCH 626/629] big ol' refactor of the Gradle Factorio Mod - handle launching in multiple OSes - specific tasks for specific mod operations - extension object for settings - ground work for multiple mods --- ...iptToLuaTask.kt => TypeScriptToLuaTask.kt} | 20 +- .../factorio-gradle/build.gradle.kts | 9 + .../factorio/FactorioModConfigurations.kt | 9 + .../gradle/factorio/FactorioModInstallTask.kt | 43 ---- .../factorio/FactorioModLibraryPlugin.kt | 48 ++++ .../gradle/factorio/FactorioModPlugin.kt | 91 ++++++- .../gradle/factorio/FactorioModSettings.kt | 63 ++++- .../gradle/factorio/FactorioModSourceSet.kt | 38 +++ .../gradle/factorio/artifactDistributions.kt | 8 +- .../gradle/factorio/configureDistribution.kt | 42 ++++ .../adamko/gradle/factorio/configureIdea.kt | 66 +++++ .../gradle/factorio/configureModSettings.kt | 99 ++++++++ .../adamko/gradle/factorio/configureTasks.kt | 137 +++++++++++ .../factorio/mod/FactorioModProperties.kt | 19 ++ .../FactorioModPortalPublishClient.kt | 15 +- .../tasks/AssembleFactorioModContents.kt | 40 +++ .../tasks/GenerateFactorioModInfoTask.kt | 132 ++++++++++ .../tasks/LaunchFactorioClientTask.kt | 89 +++++++ .../tasks/LocalPublishFactorioModTask.kt | 40 +++ .../factorio/tasks/PackageFactorioModTask.kt | 6 + gradle/libs.versions.toml | 1 + modules/events-library/build.gradle.kts | 2 +- modules/events-mod/build.gradle.kts | 228 +++++++++--------- .../main/resources/mod-data => }/info.json | 0 .../main/resources => }/kafkatorio-logo.png | Bin .../resources => }/mod-portal-description.md | 0 .../resources/{mod-data => }/changelog.txt | 0 .../{mod-data => }/locale/en/locale.cfg | 0 .../resources/{mod-data => }/thumbnail.png | Bin modules/events-processors/build.gradle.kts | 1 + .../infra-factorio-client/build.gradle.kts | 92 +++---- .../infra-factorio-server/build.gradle.kts | 2 +- settings.gradle.kts | 2 + 33 files changed, 1098 insertions(+), 244 deletions(-) rename gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/{TypescriptToLuaTask.kt => TypeScriptToLuaTask.kt} (63%) create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModConfigurations.kt delete mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModInstallTask.kt create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModLibraryPlugin.kt create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModSourceSet.kt create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureDistribution.kt create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureIdea.kt create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureModSettings.kt create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureTasks.kt create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod/FactorioModProperties.kt create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/AssembleFactorioModContents.kt create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/GenerateFactorioModInfoTask.kt create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/LaunchFactorioClientTask.kt create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/LocalPublishFactorioModTask.kt create mode 100644 gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/PackageFactorioModTask.kt rename modules/events-mod/{src/main/resources/mod-data => }/info.json (100%) rename modules/events-mod/{src/main/resources => }/kafkatorio-logo.png (100%) rename modules/events-mod/{src/main/resources => }/mod-portal-description.md (100%) rename modules/events-mod/src/main/resources/{mod-data => }/changelog.txt (100%) rename modules/events-mod/src/main/resources/{mod-data => }/locale/en/locale.cfg (100%) rename modules/events-mod/src/main/resources/{mod-data => }/thumbnail.png (100%) diff --git a/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/TypescriptToLuaTask.kt b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/TypeScriptToLuaTask.kt similarity index 63% rename from gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/TypescriptToLuaTask.kt rename to gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/TypeScriptToLuaTask.kt index d3c090d..a057288 100644 --- a/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/TypescriptToLuaTask.kt +++ b/gradle-plugins/builder-plugins/src/main/kotlin/kafkatorio/tasks/TypeScriptToLuaTask.kt @@ -2,40 +2,32 @@ package kafkatorio.tasks import com.github.gradle.node.npm.task.NpmTask import javax.inject.Inject -import org.gradle.api.file.ConfigurableFileTree +import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.FileSystemOperations import org.gradle.api.plugins.BasePlugin -import org.gradle.api.tasks.CacheableTask -import org.gradle.api.tasks.IgnoreEmptyDirectories -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.PathSensitive -import org.gradle.api.tasks.PathSensitivity -import org.gradle.api.tasks.SkipWhenEmpty -import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.* import org.gradle.work.NormalizeLineEndings import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs @CacheableTask -abstract class TypescriptToLuaTask @Inject constructor( +abstract class TypeScriptToLuaTask @Inject constructor( private val fs: FileSystemOperations ) : NpmTask() { - @get:InputDirectory + @get:InputFiles @get:SkipWhenEmpty @get:PathSensitive(PathSensitivity.RELATIVE) @get:NormalizeLineEndings @get:IgnoreEmptyDirectories - abstract val sourceFiles: DirectoryProperty + abstract val sourceFiles: ConfigurableFileCollection @get:OutputDirectory abstract val outputDirectory: DirectoryProperty init { super.setGroup(BasePlugin.BUILD_GROUP) - super.setDescription("Convert Typescript To Lua") + super.setDescription("Convert TypeScript To Lua") super.execOverrides { standardOutput = System.out } super.npmCommand.set(listOf("run", "build")) super.ignoreExitValue.set(false) diff --git a/gradle-plugins/factorio-gradle/build.gradle.kts b/gradle-plugins/factorio-gradle/build.gradle.kts index 77a630f..ea4c623 100644 --- a/gradle-plugins/factorio-gradle/build.gradle.kts +++ b/gradle-plugins/factorio-gradle/build.gradle.kts @@ -31,6 +31,8 @@ dependencies { implementation(libs.ktorClient.cio) implementation(libs.ktorClient.resources) implementation(libs.ktorSerialization.kotlinxJson) + + implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:${libs.versions.kotlin.get()}") } gradlePlugin { @@ -41,6 +43,13 @@ gradlePlugin { implementationClass = "dev.adamko.gradle.factorio.FactorioModPlugin" } } + plugins { + create("factorioModLibrary") { + displayName = "Factorio Mod Library" + id = "dev.adamko.factorio-mod-library" + implementationClass = "dev.adamko.gradle.factorio.FactorioModLibraryPlugin" + } + } } overrideKotlinLanguageVersion("1.7") // required for Kotlinx Serialization diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModConfigurations.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModConfigurations.kt new file mode 100644 index 0000000..ab13cee --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModConfigurations.kt @@ -0,0 +1,9 @@ +package dev.adamko.gradle.factorio + +import org.gradle.api.NamedDomainObjectProvider +import org.gradle.api.artifacts.Configuration + +internal data class FactorioModConfigurations( + val factorioMod: NamedDomainObjectProvider, + val factorioModProvider: NamedDomainObjectProvider, + ) diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModInstallTask.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModInstallTask.kt deleted file mode 100644 index f49ecb9..0000000 --- a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModInstallTask.kt +++ /dev/null @@ -1,43 +0,0 @@ -package dev.adamko.gradle.factorio - -import javax.inject.Inject -import org.gradle.api.DefaultTask -import org.gradle.api.file.ConfigurableFileCollection -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.file.FileSystemOperations -import org.gradle.api.internal.file.FileOperations -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.TaskAction - -abstract class FactorioModInstallTask @Inject constructor( - private val files: FileSystemOperations, -) : DefaultTask() { - - @get:Internal - abstract val clientModDirectory: DirectoryProperty - - @get:InputFiles - abstract val modFiles: ConfigurableFileCollection - - init { - description = "Copy the mod to the Factorio client" - group = FactorioModPlugin.TASK_GROUP - - super.onlyIf { - require(it is FactorioModInstallTask) - it.clientModDirectory.asFile.get().exists() - } - } - - @TaskAction - fun install() { - logger.lifecycle("Copying mod from $modFiles to $clientModDirectory") - - files.copy { - from(modFiles) - into(clientModDirectory) - } - } - -} diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModLibraryPlugin.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModLibraryPlugin.kt new file mode 100644 index 0000000..0e96e2f --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModLibraryPlugin.kt @@ -0,0 +1,48 @@ +package dev.adamko.gradle.factorio + +import javax.inject.Inject +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.slf4j.LoggerFactory + +/** + * Configure a [Project] to produce components that will be used in a Factorio mod, but no tasks + * that will create a Factorio mod. + */ +abstract class FactorioModLibraryPlugin @Inject constructor( +// private val objects: ObjectFactory, +// private val providers: ProviderFactory, +// private val layout: ProjectLayout, +// private val files: FileSystemOperations, +) : Plugin { + + internal val logger = LoggerFactory.getLogger(this::class.java) + + internal var factorioModConfigurations: FactorioModConfigurations? = null + private set + + override fun apply(target: Project) { + factorioModConfigurations = target.createConfigurations() + } + + private fun Project.createConfigurations(): FactorioModConfigurations { + return FactorioModConfigurations( + factorioMod = project.configurations.register(CONFIGURATION_NAME__FACTORIO_MOD) { + asConsumer() + factorioModAttributes(objects) + }, + + factorioModProvider = project.configurations.register( + CONFIGURATION_NAME__FACTORIO_MOD_PROVIDER + ) { + asProvider() + factorioModAttributes(objects) + }, + ) + } + + companion object { + const val CONFIGURATION_NAME__FACTORIO_MOD = "factorioMod" + const val CONFIGURATION_NAME__FACTORIO_MOD_PROVIDER = "factorioModProvider" + } +} diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModPlugin.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModPlugin.kt index 920a7d6..aee6ba0 100644 --- a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModPlugin.kt +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModPlugin.kt @@ -1,37 +1,104 @@ package dev.adamko.gradle.factorio +import dev.adamko.gradle.factorio.tasks.AssembleFactorioModContents +import dev.adamko.gradle.factorio.tasks.GenerateFactorioModInfoTask +import dev.adamko.gradle.factorio.tasks.LaunchFactorioClientTask +import dev.adamko.gradle.factorio.tasks.LocalPublishFactorioModTask +import dev.adamko.gradle.factorio.tasks.PackageFactorioModTask import javax.inject.Inject import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.api.file.FileSystemOperations +import org.gradle.api.file.ProjectLayout import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.ProviderFactory +import org.gradle.api.tasks.TaskProvider import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.newInstance +import org.gradle.kotlin.dsl.register +import org.slf4j.LoggerFactory abstract class FactorioModPlugin @Inject constructor( private val objects: ObjectFactory, + private val providers: ProviderFactory, + private val layout: ProjectLayout, + private val files: FileSystemOperations, ) : Plugin { + internal val logger = LoggerFactory.getLogger(this::class.java) + override fun apply(target: Project) { - target.createSettings() - val factorioModConfiguration = - target.configurations.register(FACTORIO_GRADLE_CONFIGURATION_NAME) { - asConsumer() - factorioModAttributes(objects) - } + val settings = target.extensions.create(FACTORIO_GRADLE_EXTENSION_NAME) + + val factorioModLibraryPlugin = objects.newInstance() + factorioModLibraryPlugin.apply(target) + val factorioModConfigurations = factorioModLibraryPlugin.factorioModConfigurations + ?: error("Could not create Factorio Mod Configurations") + + val context = PluginContext( + target, + + settings, + target.createTasks(), + factorioModConfigurations, + + objects, + providers, + layout, + files, + ) + + context.configureModSettings() + + context.configureTasks() + + context.configureIdea() + +// context.configureDistribution() } - private fun Project.createSettings(): FactorioModSettings { - return extensions.create(FACTORIO_GRADLE_EXTENSION_NAME).apply { - - } + private fun Project.createTasks(): PluginContext.Tasks { + return PluginContext.Tasks( + launchFactorioClient = project.tasks.register("launchFactorioClient"), + assembleModContents = project.tasks.register("assembleFactorioModContents"), + packageMod = project.tasks.register("packageFactorioMod"), + publishModToLocalClient = project.tasks.register("publishFactorioModToLocalClient"), + generateModInfoJson = project.tasks.register("generateFactorioModInfoJson"), + ) } + internal class PluginContext( + val project: Project, + val settings: FactorioModSettings, + val tasks: Tasks, + val configurations: FactorioModConfigurations, + + val objects: ObjectFactory, + val providers: ProviderFactory, + val layout: ProjectLayout, + val files: FileSystemOperations, + ) { + internal val logger = LoggerFactory.getLogger(this::class.java) + + data class Tasks( + val launchFactorioClient: TaskProvider, + val assembleModContents: TaskProvider, + val packageMod: TaskProvider, + val publishModToLocalClient: TaskProvider, + val generateModInfoJson: TaskProvider, + ) + } + + companion object { const val FACTORIO_GRADLE_EXTENSION_NAME = "factorioMod" - const val FACTORIO_GRADLE_CONFIGURATION_NAME = "factorioMod" - const val TASK_GROUP = "factorioMod" + const val CONFIGURATION_NAME__FACTORIO_MOD = "factorioMod" + const val CONFIGURATION_NAME__FACTORIO_MOD_PROVIDER = "factorioModProvider" + + const val TASK_GROUP = "factorio mod" /** Lifecycle task for publishing the mod locally */ const val PUBLISH_MOD_LOCAL_TASK_NAME = "publishModLocal" diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModSettings.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModSettings.kt index bc427d2..1acb4f2 100644 --- a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModSettings.kt +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModSettings.kt @@ -1,16 +1,69 @@ package dev.adamko.gradle.factorio +import javax.inject.Inject import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.ProjectLayout import org.gradle.api.file.RegularFileProperty +import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property +import org.gradle.api.provider.ProviderFactory +import org.gradle.kotlin.dsl.newInstance -interface FactorioModSettings { +abstract class FactorioModSettings @Inject constructor( + internal val objects: ObjectFactory, + internal val providers: ProviderFactory, + internal val layout: ProjectLayout, +) { - val factorioClientModsDirectory: DirectoryProperty + abstract val modName: Property + abstract val modTitle: Property + abstract val modDescription: Property + abstract val modAuthor: Property + abstract val modVersion: Property + abstract val modDependencies: ListProperty - val steamExe: RegularFileProperty + // version of Factorio that the mod is compatible with (must only be "major.minor" - patch causes error) + abstract val factorioCompatibility: Property - val factorioGameSteamId: Property + abstract val distributionZipName: Property - val factorioServerDataDirectory: DirectoryProperty + val mainSources: FactorioModSourceSet.WithResources = objects.newInstance("Main") + val testSources: FactorioModSourceSet.WithResources = objects.newInstance("Test") + val generatedSources: FactorioModSourceSet = objects.newInstance("Generated") + + +// abstract val typescriptSrcDir: DirectoryProperty +// abstract val resourcesDir: DirectoryProperty +// abstract val modDataResourcesDir: DirectoryProperty +// abstract val generatedLuaSrcDir: DirectoryProperty + + + abstract val factorioServerDataDirectory: DirectoryProperty + + + val localDev: LocalDev = objects.newInstance() + + fun localDev(configure: LocalDev.() -> Unit) { + localDev.configure() + } + + interface LocalDev { + val currentOs: Property + + val windowsSteamExe: Property + + val factorioSteamId: Property + + val serverConnectHost: Property + + val clientModsDirectory: RegularFileProperty + + val macApplicationSupportDir: RegularFileProperty + + val macFactorioApp: RegularFileProperty + + /** Supported local dev OSes */ + enum class OS { WINDOWS, MAC_OS, UNSUPPORTED } + } } diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModSourceSet.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModSourceSet.kt new file mode 100644 index 0000000..fcf4849 --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/FactorioModSourceSet.kt @@ -0,0 +1,38 @@ +package dev.adamko.gradle.factorio + +import javax.inject.Inject +import org.gradle.api.Named +import org.gradle.api.file.SourceDirectorySet +import org.gradle.api.model.ObjectFactory + +abstract class FactorioModSourceSet @Inject constructor( + private val named: String, + objects: ObjectFactory, +) : Named { + + val typescript: SourceDirectorySet = objects + .sourceDirectorySet("ts${named}", "TypeScript $named source files") + .apply { + include("**/*.d.ts", "**/*.ts") + } + + val lua: SourceDirectorySet = objects + .sourceDirectorySet("lua${named}", "Lua $named source files") + .apply { + include("**/*.lua") + } + + override fun getName(): String = named + + abstract class WithResources @Inject constructor( + type: String, + objects: ObjectFactory, + ) : FactorioModSourceSet(type, objects) { + + val resources: SourceDirectorySet = objects + .sourceDirectorySet("resources${type}", "$type resources") + .apply { + exclude("**/*.d.ts", "**/*.ts", "**/*.lua") + } + } +} diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/artifactDistributions.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/artifactDistributions.kt index 38256af..bcb7e5c 100644 --- a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/artifactDistributions.kt +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/artifactDistributions.kt @@ -12,15 +12,15 @@ import org.gradle.api.model.ObjectFactory import org.gradle.kotlin.dsl.named -fun Configuration.asProvider() { - isVisible = false +fun Configuration.asProvider(visible: Boolean = false) { + isVisible = visible isCanBeResolved = false isCanBeConsumed = true } -fun Configuration.asConsumer() { - isVisible = false +fun Configuration.asConsumer(visible: Boolean = false) { + isVisible = visible isCanBeResolved = true isCanBeConsumed = false } diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureDistribution.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureDistribution.kt new file mode 100644 index 0000000..72f4c81 --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureDistribution.kt @@ -0,0 +1,42 @@ +package dev.adamko.gradle.factorio + +import org.gradle.api.distribution.DistributionContainer +import org.gradle.api.distribution.plugins.DistributionPlugin +import org.gradle.api.tasks.bundling.Zip +import org.gradle.kotlin.dsl.apply +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.named + +internal fun FactorioModPlugin.PluginContext.configureDistribution() { + + project.plugins.apply(DistributionPlugin::class) + + val distributions = project.extensions.getByType() + + distributions.named(DistributionPlugin.MAIN_DISTRIBUTION_NAME) { + + distributionBaseName.set(settings.modName) + + contents { + includeEmptyDirs = false + + from(settings.mainSources.resources) { + include("**/**") + } + + exclude { + // exclude empty files + it.file.run { + isFile && useLines { lines -> lines.all { line -> line.isBlank() } } + } + } + } + } + + val distZipTask = project.tasks.named("distZip") + + configurations.factorioModProvider.configure { + outgoing.artifact(distZipTask.flatMap { it.archiveFile }) + } + +} diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureIdea.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureIdea.kt new file mode 100644 index 0000000..15b63ee --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureIdea.kt @@ -0,0 +1,66 @@ +package dev.adamko.gradle.factorio + +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.withType +import org.gradle.plugins.ide.idea.IdeaPlugin +import org.gradle.plugins.ide.idea.model.IdeaModel +import org.gradle.plugins.ide.idea.model.Module + +internal fun FactorioModPlugin.PluginContext.configureIdea() { + project.plugins.withType().configureEach { + +// project.afterEvaluate { + project.extensions.configure { + module { +// this.scopes["MAIN"]?.plusAssign(mutableMapOf("plus" to listOf(project.configurations.create("main")))) +// + sourceDirs.plusAssign(settings.mainSources.typescript.srcDirs) + sourceDirs.plusAssign(settings.mainSources.lua.srcDirs) + sourceDirs.plusAssign(settings.generatedSources.lua.srcDirs) + + testSources.from(settings.testSources.typescript) + testSources.from(settings.testSources.lua) + + resourceDirs.plusAssign(settings.mainSources.resources.srcDirs) + testResources.from(settings.testSources.resources) + + generatedSourceDirs.plusAssign(settings.generatedSources.lua.srcDirs) + generatedSourceDirs.plusAssign(settings.generatedSources.typescript.srcDirs) + +// sourceDirs.plusAssign( +// listOf( +// settings.typescriptSrcDir.get().asFile, +// settings.generatedLuaSrcDir.get().asFile, +// ) +// ) +//// sourceDirs = sourceDirs + file("src/main/lua") +// resourceDirs = resourceDirs + settings.modDataResourcesDir +// testSources.from(typescriptTestSrcDir) +//// testSourceDirs = testSourceDirs + typescriptTestSrcDir +// +// generatedSourceDirs = generatedSourceDirs + generatedSrcDir +//// excludeDirs = excludeDirs + generatedSrcDir + + iml { + whenMerged { + require(this is Module) + +// sourceDirs.plusAssign(settings.mainSources.typescript.srcDirs) +// sourceDirs.plusAssign(settings.mainSources.lua.srcDirs) +// sourceDirs.plusAssign(settings.generatedSources.lua.srcDirs) +// +// testSources.from(settings.testSources.typescript) +// testSources.from(settings.testSources.lua) +// +// resourceDirs.plusAssign(settings.mainSources.resources.srcDirs) +// testResources.from(settings.testSources.resources) +// +// generatedSourceDirs.plusAssign(settings.generatedSources.lua.srcDirs) +// generatedSourceDirs.plusAssign(settings.generatedSources.typescript.srcDirs) + } + } +// } + } + } + } +} diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureModSettings.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureModSettings.kt new file mode 100644 index 0000000..a587b30 --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureModSettings.kt @@ -0,0 +1,99 @@ +package dev.adamko.gradle.factorio + +import dev.adamko.gradle.factorio.FactorioModSettings.LocalDev.OS +import java.io.File +import org.gradle.api.internal.provider.Providers +import org.gradle.api.provider.ProviderFactory + + +internal fun FactorioModPlugin.PluginContext.configureModSettings() = with(settings) { + modName.convention(providers.provider { project.name }) + modTitle.convention(modName) + modDescription.convention(providers.provider { project.description ?: "" }) + modVersion.convention(providers.provider { project.version.toString() }) + + distributionZipName.convention(providers.zip(modName, modVersion) { name, version -> + "${name}_${version}.zip" + }) + + val srcBaseMain = layout.projectDirectory.dir("src/main") + mainSources.lua.srcDir(srcBaseMain.dir("lua")) + mainSources.typescript.srcDir(srcBaseMain.dir("typescript")) + mainSources.resources.srcDir(srcBaseMain.dir("resources")) + + + val srcBaseTest = layout.projectDirectory.dir("src/test") + testSources.lua.srcDir(srcBaseTest.dir("lua")) + testSources.typescript.srcDir(srcBaseTest.dir("typescript")) + testSources.resources.srcDir(srcBaseTest.dir("resources")) + + + val srcBaseGenerated = layout.buildDirectory.dir("generated-src").get() + generatedSources.lua.srcDir(srcBaseGenerated.dir("lua")) + generatedSources.typescript.srcDir(srcBaseGenerated.dir("typescript")) + + mainSources.typescript.destinationDirectory.convention(srcBaseGenerated.dir("lua")) + + configureLocalDev() +} + + +private fun FactorioModPlugin.PluginContext.configureLocalDev() = with(settings) { + + val userHome = providers.systemProperty("user.home") + .map { home -> File(home) } + + + localDev { + + currentOs.convention(providers.systemProperty("os.name").map { osName -> + val currentOS = osName.lowercase() + when { + "windows" in currentOS -> OS.WINDOWS + "mac" in currentOS -> OS.MAC_OS + else -> { + logger.warn("cannot select OS for Factorio local dev - '${osName}' is unsupported") + OS.UNSUPPORTED + } + } + }) + + windowsSteamExe.convention("""C:\Program Files (x86)\Steam\steam.exe""") + factorioSteamId.convention("427520") +// serverConnectHost.convention("localhost") + + macApplicationSupportDir.convention(layout.file(userHome.map { home -> + home.resolve("""Library/Application Support/""") + })) + + macFactorioApp.convention(layout.file(macApplicationSupportDir.map { appSupport -> + appSupport.asFile.resolve("""Steam/steamapps/common/Factorio/factorio.app/Contents/MacOS/factorio""") + })) + + clientModsDirectory.convention(layout.file( + currentOs.flatMap { os -> + when (os) { + OS.WINDOWS -> userHome.map { home -> + home.resolve("""AppData/Roaming/Factorio/mods""") + } + + OS.MAC_OS -> macApplicationSupportDir.map { appSupport -> + appSupport.asFile.resolve("""factorio/mods""") + + } + + OS.UNSUPPORTED -> { + logger.warn("cannot automatically determine Factorio client mod directory, $os is unsupported") + Providers.notDefined() // https://github.com/gradle/gradle/issues/12388 + } + } + } + )) + } +} + + +private fun ProviderFactory.factorioModProp(name: String) { + environmentVariable("FACTORIO_MOD_$name") + .orElse(gradleProperty("factorioMod_$name")) +} diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureTasks.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureTasks.kt new file mode 100644 index 0000000..5876803 --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureTasks.kt @@ -0,0 +1,137 @@ +package dev.adamko.gradle.factorio + +import dev.adamko.gradle.factorio.tasks.AssembleFactorioModContents +import dev.adamko.gradle.factorio.tasks.GenerateFactorioModInfoTask +import dev.adamko.gradle.factorio.tasks.LaunchFactorioClientTask +import dev.adamko.gradle.factorio.tasks.LocalPublishFactorioModTask +import dev.adamko.gradle.factorio.tasks.PackageFactorioModTask +import org.gradle.kotlin.dsl.withType + +internal fun FactorioModPlugin.PluginContext.configureTasks() { + + tasks.launchFactorioClient.configure { + + } + tasks.assembleModContents.configure { + modFiles.apply { + from(settings.mainSources.typescript.destinationDirectory) + from(tasks.generateModInfoJson) + from(settings.mainSources.resources) + } + } + tasks.packageMod.configure { + from(tasks.assembleModContents) + } + tasks.publishModToLocalClient.configure { + dependsOn(tasks.packageMod) + } + tasks.generateModInfoJson.configure { + + } + + + project.tasks.withType().configureEach { + description = "Copy the mod to the Factorio client" + group = FactorioModPlugin.TASK_GROUP + + onlyIf { + require(it is LocalPublishFactorioModTask) + it.clientModDirectory.asFile.get().exists() + } + + modFiles.from( + configurations.factorioMod.map { + it.incoming + .artifactView { lenient(true) } + .files + } + ) + + doLast { + logger.lifecycle("Published Factorio Mod to '${clientModDirectory.asFile.get()}'") + } + } + + configureLaunchFactorioClientTasks() + + project.tasks.withType().configureEach { + description = "Generate info.json (required for Factorio Mods)" + group = FactorioModPlugin.TASK_GROUP + + modName.convention(settings.modName) + modTitle.convention(settings.modTitle) + modDescription.convention(settings.modDescription) + modAuthor.convention(settings.modAuthor) + modVersion.convention(settings.modVersion) + factorioCompatibility.convention(settings.factorioCompatibility) + modDependencies.convention(settings.modDependencies) + infoJson.convention( + layout.file( + providers.provider { + temporaryDir.resolve("info.json") + } + ) + ) + } + + project.tasks.withType().configureEach { + description = "Gather the mod files that will be packaged into the mod zip" + group = FactorioModPlugin.TASK_GROUP + + modName.convention(settings.modName) + modVersion.convention(settings.modVersion) + + destination.convention(layout.dir(providers.provider { temporaryDir })) + } + + project.tasks.withType().configureEach { + description = "Package the Factorio mod" + group = FactorioModPlugin.TASK_GROUP + + archiveFileName.convention(settings.distributionZipName) + + includeEmptyDirs = false + + exclude { + // exclude empty files + it.file.run { + isFile && useLines { lines -> lines.all { line -> line.isBlank() } } + } + } + } + + project.tasks.withType().configureEach { + description = "Launch local Factorio Steam game client" + group = FactorioModPlugin.TASK_GROUP + + modFiles.from(project.tasks.withType()) + clientModDirectory.convention(layout.dir(settings.localDev.clientModsDirectory.asFile)) + } +} + + +private fun FactorioModPlugin.PluginContext.configureLaunchFactorioClientTasks() { + + val localDev = settings.localDev + +// // convert to local props -> try to comply with Gradle config cache +// val localDevCurrentOs = localDev.currentOs +// val localDevWindowsSteamExe = localDev.windowsSteamExe +// val localDevFactorioSteamId = localDev.factorioSteamId +// val localDevServerConnectHost = localDev.serverConnectHost +// val localDevClientModDirectory = localDev.clientModDirectory +// val localDevMacApplicationSupportDir = localDev.macApplicationSupportDir +// val localDevMacFactorioApp = localDev.macFactorioApp + + project.tasks.withType().configureEach { + description = "Launch local Factorio Steam game client" + group = FactorioModPlugin.TASK_GROUP + + currentOs.convention(localDev.currentOs) + windowsSteamExe.convention(localDev.windowsSteamExe) + factorioSteamId.convention(localDev.factorioSteamId) + serverConnectHost.convention(localDev.serverConnectHost) + clientModsPath.convention(localDev.clientModsDirectory.map { it.asFile.canonicalPath }) + macFactorioApp.convention(localDev.macFactorioApp) + } +} diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod/FactorioModProperties.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod/FactorioModProperties.kt new file mode 100644 index 0000000..8c73c13 --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod/FactorioModProperties.kt @@ -0,0 +1,19 @@ +package dev.adamko.gradle.factorio.mod + +// to be used in a NamedDomainObject container? + +//import org.gradle.api.Named +//import org.gradle.api.provider.Property +// +//abstract class FactorioModProperties : Named { +// +// abstract val modName: Property +// abstract val modTitle: Property +// abstract val modDescription: Property +// abstract val modVersion: Property +// +// // version of Factorio that the mod is compatible with (must only be "major.minor" - patch causes error) +// abstract val factorioCompatibility: Property +// +// abstract val distributionZipName: Property +//} diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod_portal/FactorioModPortalPublishClient.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod_portal/FactorioModPortalPublishClient.kt index f8d8667..b382bc3 100644 --- a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod_portal/FactorioModPortalPublishClient.kt +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/mod_portal/FactorioModPortalPublishClient.kt @@ -69,14 +69,13 @@ class FactorioModPortalPublishClient( client().useToRun { val initUploadResponse = initUpload() - val enteredVersion = userInputHandler - .askQuestion( - """ - |Are you sure you want to publish $modName:$modVersion? - |Enter the version number to confirm: - """.trimMargin(), - "", - ) + val enteredVersion = userInputHandler.askQuestion( + """ + |Are you sure you want to publish $modName:$modVersion? + |Enter the version number to confirm: + """.trimMargin(), + "", + ) val confirmed = enteredVersion.trim().equals(modVersion.trim(), ignoreCase = true) diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/AssembleFactorioModContents.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/AssembleFactorioModContents.kt new file mode 100644 index 0000000..d1ca05c --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/AssembleFactorioModContents.kt @@ -0,0 +1,40 @@ +package dev.adamko.gradle.factorio.tasks + +import javax.inject.Inject +import org.gradle.api.* +import org.gradle.api.file.* +import org.gradle.api.internal.file.* +import org.gradle.api.provider.Property +import org.gradle.api.tasks.* + +abstract class AssembleFactorioModContents @Inject constructor( + private val files: FileSystemOperations, +) : DefaultTask() { + + @get:Input + abstract val modName: Property + + @get:Input + abstract val modVersion: Property + + @get:InputFiles + @get:SkipWhenEmpty + @get:PathSensitive(PathSensitivity.NAME_ONLY) + @get:IgnoreEmptyDirectories + abstract val modFiles: ConfigurableFileCollection + + @get:OutputDirectory + abstract val destination: DirectoryProperty + + @TaskAction + fun assemble() { + val modName = modName.get() + val modVersion = modVersion.get() + val modDirectory = "${modName}_${modVersion}" + + files.sync { + from(modFiles) + into(destination.dir(modDirectory)) + } + } +} diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/GenerateFactorioModInfoTask.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/GenerateFactorioModInfoTask.kt new file mode 100644 index 0000000..e01dab0 --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/GenerateFactorioModInfoTask.kt @@ -0,0 +1,132 @@ +package dev.adamko.gradle.factorio.tasks + +import javax.inject.Inject +import kotlinx.serialization.* +import kotlinx.serialization.json.* +import org.gradle.api.DefaultTask +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction + +abstract class GenerateFactorioModInfoTask @Inject constructor( + +) : DefaultTask() { + + /** + * Mandatory field. The internal name of mod. The game accepts anything as a mod name, however the mod portal restricts mod names to only consist of alphanumeric characters, dashes and underscores. Note that the mod folder or mod zip file name has to contain the mod name, where the restrictions of the file system apply. + * + * The game accepts mod names with a maximum length of 100 characters. The mod portal only accepts mods with names that are longer than 3 characters and shorter than 50 characters. + */ + @get:Input + abstract val modName: Property + + /** + * Mandatory field. The display name of the mod, so it is not recommended to use someUgly_pRoGrAmMeR-name here. Can be overwritten with a locale entry in the mod-name category, using the internal mod name as the key. + * + * The game will reject a title field that is longer than 100 characters. However, this can be worked around by using the locale entry. The mod portal does not restrict mod title length. + */ + @get:Input + abstract val modTitle: Property + + /** + * Optional field. A short description of what your mod does. This is all that people get to see in-game. Can be overwritten with a locale entry in the mod-description category, using the internal mod name as the key. + */ + @get:Input + @get:Optional + abstract val modDescription: Property + + /** + * Optional field. Where the mod can be found on the internet. Note that the in-game mod browser shows the mod portal link additionally to this field. Please don't put "None" here, it makes the field on the mod portal website look ugly. Just leave the field empty if the mod doesn't have a website/forum thread/discord. + */ + @get:Input + @get:Optional + abstract val modHomepage: Property + + /** + * Mandatory field. The author of the mod. This field does not have restrictions, it can also be a list of authors etc. The mod portal ignores this field, it will simply display the uploader's name as the author. + */ + @get:Input + abstract val modAuthor: Property + + /** + * Mandatory field. Defines the version of the mod in the format `number.number.number` for `Major.Middle.Minor`, for example `0.6.4`. Each number can range from 0 to 65535. + */ + @get:Input + abstract val modVersion: Property + + /** + * Optional field in the format "major.minor". The Factorio version that this mod supports. This can only be one Factorio version, not multiple. However, it includes all .sub versions. While the field is optional, usually mods are developed for versions higher than the default 0.12, so the field has to be added anyway. + * + * Adding a sub part, e.g. "0.18.27" will make the mod portal reject the mod and the game act weirdly. That means this shouldn't be done; use only the major and minor components "major.minor", for example "1.0". + * + * Mods with the factorio_version "0.18" can also be loaded in 1.0 and the mod portal will return them when queried for factorio_version 1.0 mods. + */ + @get:Input + @get:Optional + abstract val factorioCompatibility: Property + + /** + * Optional field. Mods that this mod depends on or is incompatible with. + * If this mod depends on another, the other mod will load first, see Data-Lifecycle. + * An empty array allows get around the default and have no dependencies at all. + * + * Example: + * + * `"dependencies": ["mod-a", "? mod-c > 0.4.3", "! mod-g"]` + * + * Each dependency is a string that consists of up to three parts: ` internal-mod-name `, for example `? some-mod-everyone-loves >= 4.2.0`. + * + * The equality operator (`<`, `<=`, `=`, `>=` or `>`) combined with the version allows to define dependencies that require certain mod versions, but it is not required. + * + * Incompatibility does not support versions; if incompatibility is used, version is ignored. + * + * The possible prefixes are: + * * `!` for incompatibility + * * `?` for an optional dependency + * * `(?)` for a hidden optional dependency + * * `~` for a dependency that does not affect load order + * * no prefix for a hard requirement for the other mod. + */ + @get:Input + @get:Optional + abstract val modDependencies: ListProperty + + @get:OutputFile + abstract val infoJson: RegularFileProperty + + @TaskAction + fun generate() { + val infoJsonObject = buildJsonObject { + put("name", modName.get()) + put("title", modTitle.get()) + put("version", modVersion.get()) + put("author", modAuthor.get()) + + modDescription.orNull?.let { put("description", it) } + modHomepage.orNull?.let { put("homepage", it) } + factorioCompatibility.orNull?.let { put("factorio_version", it) } + modDependencies.orNull?.let { + putJsonArray("dependencies") { it.forEach(::add) } + } + } + + val infoJsonContent = encoder.encodeToString(infoJsonObject) + .replace("[\n ]", "[]") + + val infoJson = infoJson.get().asFile + infoJson.parentFile.mkdirs() + infoJson.writeText(infoJsonContent + "\n") + } + + companion object { + @OptIn(ExperimentalSerializationApi::class) + private val encoder = Json { + prettyPrint = true + prettyPrintIndent = " " + } + } +} diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/LaunchFactorioClientTask.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/LaunchFactorioClientTask.kt new file mode 100644 index 0000000..04d4ae7 --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/LaunchFactorioClientTask.kt @@ -0,0 +1,89 @@ +package dev.adamko.gradle.factorio.tasks + +import dev.adamko.gradle.factorio.FactorioModSettings +import javax.inject.Inject +import org.gradle.api.DefaultTask +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.TaskAction +import org.gradle.process.ExecOperations +import org.gradle.work.DisableCachingByDefault +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs + +@DisableCachingByDefault(because = "Not a cacheable task") +abstract class LaunchFactorioClientTask @Inject constructor( + private val executor: ExecOperations +) : DefaultTask() { + + @get:Input + abstract val currentOs: Property + + @get:Input + @get:Optional + abstract val windowsSteamExe: Property + + @get:Input + @get:Optional + abstract val factorioSteamId: Property + + @get:Input + @get:Optional + abstract val serverConnectHost: Property + + @get:Input + @get:Optional + abstract val clientModsPath: Property + + @get:InputFile + @get:Optional + abstract val macFactorioApp: RegularFileProperty + + @get:Input + @get:Optional + abstract val launchFactorioCommand: Property + + @TaskAction + fun launch() { + val launchCommand = + launchFactorioCommand.orNull ?: when (currentOs.orNull) { + FactorioModSettings.LocalDev.OS.WINDOWS -> windowsCmd() + FactorioModSettings.LocalDev.OS.MAC_OS -> macOSCmd() + null, FactorioModSettings.LocalDev.OS.UNSUPPORTED -> error("no can do, unsupported OS") + } + + logger.lifecycle("Launching Factorio client\n > $launchCommand") + + executor.exec { + commandLine = parseSpaceSeparatedArgs(launchCommand) + } + } + + private fun windowsCmd(): String { + val steamExe = windowsSteamExe.orNull ?: error("missing Steam exe") + val factorioId = factorioSteamId.orNull ?: error("missing Factorio Steam ID") + val modsDirFlag = clientModsPath.map { """--mod-directory "$it"""" }.getOrElse("") + val mpConnectFlag = serverConnectHost.map { "--mp-connect $it" }.getOrElse("") + + return """ + $steamExe --applaunch $factorioId $modsDirFlag $mpConnectFlag + """.trimIndent() + } + + private fun macOSCmd(): String { +// val factorioApp = macFactorioApp.orNull ?: error("missing Factorio app") + + val modsDirFlag = "" //clientModsPath.map { """--mod-directory "$it"""" }.getOrElse("") + val mpConnectFlag = serverConnectHost.map { "-mp-connect $it" }.getOrElse("") + + return """ + /Applications/Steam.app/Contents/MacOS/steam_osx -applaunch 427520 $modsDirFlag $mpConnectFlag + """.trimIndent() + +// return """ +// open -a "$factorioApp" --args $modsDirFlag $mpConnectFlag +// """.trimIndent() + } +} diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/LocalPublishFactorioModTask.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/LocalPublishFactorioModTask.kt new file mode 100644 index 0000000..51aaae5 --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/LocalPublishFactorioModTask.kt @@ -0,0 +1,40 @@ +package dev.adamko.gradle.factorio.tasks + +import javax.inject.Inject +import org.gradle.api.DefaultTask +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.FileSystemOperations +import org.gradle.api.tasks.IgnoreEmptyDirectories +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.api.tasks.SkipWhenEmpty +import org.gradle.api.tasks.TaskAction + +abstract class LocalPublishFactorioModTask @Inject constructor( + private val files: FileSystemOperations, +) : DefaultTask() { + + @get:OutputDirectory + abstract val clientModDirectory: DirectoryProperty + + @get:InputFiles + @get:SkipWhenEmpty + @get:PathSensitive(PathSensitivity.NAME_ONLY) + @get:IgnoreEmptyDirectories + abstract val modFiles: ConfigurableFileCollection + + @TaskAction + fun install() { + logger.lifecycle("Copying mod from ${modFiles.files} to ${clientModDirectory.asFile.get()}") + + files.copy { + from(modFiles) { + include("*.zip") + } + into(clientModDirectory) + } + } +} diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/PackageFactorioModTask.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/PackageFactorioModTask.kt new file mode 100644 index 0000000..13586e8 --- /dev/null +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/PackageFactorioModTask.kt @@ -0,0 +1,6 @@ +package dev.adamko.gradle.factorio.tasks + +import org.gradle.api.tasks.bundling.Zip + + +abstract class PackageFactorioModTask : Zip() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0223be4..9e54ae4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -93,6 +93,7 @@ loggingCapabilities = { id = "dev.jacomet.logging-capabilities", vers ## kotlin ## kotlin-bom = { group = "org.jetbrains.kotlin", name = "kotlin-bom", version.ref = "kotlin" } +kotlin-embeddableCompiler = { module = "org.jetbrains.kotlin:kotlin-compiler-embeddable" } kotlinScripting-common = { group = "org.jetbrains.kotlin", name = "kotlin-scripting-common" } kotlinScripting-jvm = { group = "org.jetbrains.kotlin", name = "kotlin-scripting-jvm" } diff --git a/modules/events-library/build.gradle.kts b/modules/events-library/build.gradle.kts index 2236884..96d4725 100644 --- a/modules/events-library/build.gradle.kts +++ b/modules/events-library/build.gradle.kts @@ -7,7 +7,7 @@ import dev.adamko.gradle.factorio.typescriptAttributes plugins { id("kafkatorio.conventions.lang.kotlin-multiplatform") - id("dev.adamko.factorio-mod") apply false // only needed for 'attributes' - need to split up the plugin? + id("dev.adamko.factorio-mod-library") // only needed for 'attributes' - need to split up the plugin? kotlin("plugin.serialization") distribution } diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 89e2bf6..f4d466f 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -1,38 +1,40 @@ import dev.adamko.gradle.factorio.mod_portal.FactorioModPublishTask import dev.adamko.gradle.factorio.typescriptAttributes -import dev.adamko.gradle.factorio.factorioModAttributes -import kafkatorio.tasks.TypescriptToLuaTask +import kafkatorio.tasks.TypeScriptToLuaTask import kotlinx.serialization.json.put import kotlinx.serialization.json.putJsonObject -import net.swiftzer.semver.SemVer -import org.apache.tools.ant.filters.ReplaceTokens -import org.gradle.plugins.ide.idea.model.Module as IdeaImlModule -import org.gradle.plugins.ide.idea.model.Path as IdeaImlPath plugins { id("kafkatorio.conventions.lang.node") id("dev.adamko.factorio-mod") distribution + idea } description = "Sends in-game information to a server over the internet (requires additional setup)" +factorioMod { + modName.set("kafkatorio-events") + modTitle.set("Kafkatorio Events") + modAuthor.set("adam@adamko.dev") + factorioCompatibility.set(libs.versions.factorio.map { it.substringBeforeLast(".") }) +} + // Factorio required format is: // - filename: `mod-name_version.zip` // - zip contains one directory, `mod-name` //val modName: String by extra { "${rootProject.name}-events" } -extra.set("modName", "kafkatorio-events") -val modName = extra.get("modName") as String +//extra.set("modName", "kafkatorio-events") +//val modName = extra.get("modName") as String -val modDescription: String by project.extra { project.description ?: "" } - -val distributionZipName: String by extra { "${modName}_${rootProject.version}.zip" } +//val modDescription: String by project.extra { project.description ?: "" } // version of Factorio that the mod is compatible with (must only be "major.minor" - patch causes error) -val modFactorioCompatibility: Provider = - libs.versions.factorio.map { SemVer.parse(it).run { "$major.$minor" } } +//val modFactorioCompatibility: Provider = +// libs.versions.factorio.map { SemVer.parse(it).run { "$major.$minor" } } +//rootProject.layout.projectDirectory.file("LICENSE") val licenseFile: RegularFile by rootProject.extra @Suppress("UNCHECKED_CAST") @@ -42,13 +44,13 @@ val projectTokens: MapProperty = //val projectTokens: MapProperty by rootProject.extra val projectTokensX1 = projectTokens.apply { - put("mod.name", modName) - put("mod.title", "Kafkatorio Events") - put("mod.description", modDescription) - put("factorio.version", modFactorioCompatibility) + put("mod.name", factorioMod.modName) + put("mod.title", factorioMod.modTitle) + put("mod.description", factorioMod.modDescription) + put("factorio.version", factorioMod.factorioCompatibility) } -val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") +//val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") node { @@ -68,7 +70,7 @@ dependencies { } -val typescriptToLua by tasks.registering(TypescriptToLuaTask::class) { +val typescriptToLua by tasks.registering(TypeScriptToLuaTask::class) { dependsOn( tasks.npmInstall, installEventsTsSchema, @@ -77,21 +79,18 @@ val typescriptToLua by tasks.registering(TypescriptToLuaTask::class) { inputs.file(tasks.updatePackageJson.map { it.packageJsonFile }) - sourceFiles.set(tsSrcDir) + sourceFiles.from(factorioMod.mainSources.typescript.sourceDirectories) - outputDirectory.set(layout.projectDirectory.dir("src/generated/lua")) + outputDirectory.set(factorioMod.mainSources.typescript.destinationDirectory) } val installEventsTsSchema by tasks.registering(Sync::class) { - description = "Fetch the latest shared data-model" + description = "Fetch the latest shared TypeScript data-model" group = project.name dependsOn(typescriptEventsSchema) - val outputDir = layout.projectDirectory.dir("src/main/typescript/generated/") - outputs.dir(outputDir) - from( provider { typescriptEventsSchema } .map { eventsSchema -> @@ -107,73 +106,80 @@ val installEventsTsSchema by tasks.registering(Sync::class) { // eachFile { relativePath = dropDirectory() } includeEmptyDirs = false } - into(outputDir) + into(layout.projectDirectory.dir("src/main/typescript/generated")) } -val zipNameProvider = provider { distributionZipName } +//val zipNameProvider = provider { distributionZipName } tasks.distZip { - val projectTokensXX22 = projectTokensX1 +// val projectTokensXX22 = projectTokensX1 - inputs.property("zipNameProvider", zipNameProvider) - inputs.property("projectTokens", projectTokensXX22) - - archiveFileName.set(zipNameProvider) +// inputs.property("zipNameProvider", zipNameProvider) +// inputs.property("projectTokens", projectTokensXX22) + val distributionZipName = factorioMod.distributionZipName + archiveFileName.set(distributionZipName) } - val publishModToPortal by tasks.registering(FactorioModPublishTask::class) { dependsOn(tasks.check) distributionZip.set(tasks.distZip.flatMap { it.archiveFile }) - val projectModName = project.extra.get("modName") as String - modName.set(projectModName) - modVersion.set(project.version.toString()) +// val projectModName = project.extra.get("modName") as String + modName.set(factorioMod.modName) + modVersion.set(factorioMod.modVersion) +// modVersion.set(project.version.toString()) } - -distributions { - main { - - distributionBaseName.set(modName) - val tokens333: MutableMap = projectTokensX1.get() - - contents { - from(layout.projectDirectory.dir("src/main/resources/mod-data")) { - include("**/**") - } - from(licenseFile) - from(typescriptToLua.map { it.outputDirectory }) - filesNotMatching("**/*.png") { - // maybe make a bug report for projectTokensX1 causing null$null$null error? - // val tokens333: MutableMap = projectTokensX1.get() - filter("tokens" to tokens333) - } - includeEmptyDirs = false - exclude { - // exclude empty files - it.file.run { - isFile && useLines { lines -> lines.all { line -> line.isBlank() } } - } - } - } +tasks.assembleFactorioModContents { + modFiles.apply { + from(typescriptToLua.map { it.outputDirectory }) + from(licenseFile) } } +//distributions { +// main { +// +//// distributionBaseName.set(factorioMod.modName) +// val tokens333: MutableMap = projectTokensX1.get() +// +// contents { +//// from(factorioMod.mainSources.resources) { +//// include("**/**") +//// } +// from(licenseFile) +// from(typescriptToLua.map { it.outputDirectory }) +// filesNotMatching("**/*.png") { +// // maybe make a bug report for projectTokensX1 causing null$null$null error? +// // val tokens333: MutableMap = projectTokensX1.get() +// filter("tokens" to tokens333) +// } +//// includeEmptyDirs = false +//// exclude { +//// // exclude empty files +//// it.file.run { +//// isFile && useLines { lines -> lines.all { line -> line.isBlank() } } +//// } +//// } +// } +// } +//} + + tasks.withType().configureEach { val projectTokensXX444 = projectTokensX1 inputs.property("projectTokens", projectTokensXX444) } -val factorioModProvider by configurations.registering { - asProvider() - factorioModAttributes(objects) - outgoing.artifact(tasks.distZip.flatMap { it.archiveFile }) -} +//val factorioModProvider by configurations.registering { +// asProvider() +// factorioModAttributes(objects) +// outgoing.artifact(tasks.distZip.flatMap { it.archiveFile }) +//} val projectPackageJsonName: Provider = @@ -202,49 +208,51 @@ tasks.updatePackageJson { tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) } -val typescriptSrcDir: File = file("src/main/typescript") -val luaSrcDir: File = file("src/generated/lua") -val resourcesDir: File = file("src/main/resources") -val typescriptTestSrcDir: File = file("src/test/typescript") -val generatedSrcDir: File = file("src/generated") - - -idea { - module { - sourceDirs.plusAssign( - listOf( - typescriptSrcDir, - luaSrcDir, - ) - ) -// sourceDirs = sourceDirs + file("src/main/lua") - resourceDirs = resourceDirs + resourcesDir - testSourceDirs = testSourceDirs + typescriptTestSrcDir - - generatedSourceDirs = generatedSourceDirs + generatedSrcDir -// excludeDirs = excludeDirs + generatedSrcDir - - iml { - whenMerged { - require(this is IdeaImlModule) - - sourceDirs.plusAssign( - listOf( - typescriptSrcDir, - luaSrcDir, - ) - ) - - generatedSourceFolders.plusAssign( - IdeaImlPath(luaSrcDir.toURI().toString()) - ) - resourceDirs = resourceDirs + resourcesDir - testSourceDirs = testSourceDirs + typescriptTestSrcDir -// excludeDirs = excludeDirs + generatedSrcDir - } - } - } -} +//val typescriptSrcDir: File = file("src/main/typescript") +//val luaSrcDir: File = file("src/generated/lua") +//val resourcesDir: File = file("src/main/resources") +//val typescriptTestSrcDir: File = file("src/test/typescript") +//val generatedSrcDir: File = file("src/generated") +// +// +//idea { +// module { +// sourceDirs.plusAssign( +// listOf( +// typescriptSrcDir, +// luaSrcDir, +// ) +// ) +//// sourceDirs = sourceDirs + file("src/main/lua") +// resourceDirs = resourceDirs + resourcesDir +// testSources.from(typescriptTestSrcDir) +//// testSourceDirs = testSourceDirs + typescriptTestSrcDir +// +// generatedSourceDirs = generatedSourceDirs + generatedSrcDir +//// excludeDirs = excludeDirs + generatedSrcDir +// +// iml { +// whenMerged { +// require(this is IdeaImlModule) +// +// sourceDirs.plusAssign( +// listOf( +// typescriptSrcDir, +// luaSrcDir, +// ) +// ) +// +// generatedSourceFolders.plusAssign( +// IdeaImlPath(luaSrcDir.toURI().toString()) +// ) +// resourceDirs = resourceDirs + resourcesDir +// testSources.from(typescriptTestSrcDir) +//// testSourceDirs = testSourceDirs + typescriptTestSrcDir +//// excludeDirs = excludeDirs + generatedSrcDir +// } +// } +// } +//} // trying to get Gradle+idea to recognise the ts-src... diff --git a/modules/events-mod/src/main/resources/mod-data/info.json b/modules/events-mod/info.json similarity index 100% rename from modules/events-mod/src/main/resources/mod-data/info.json rename to modules/events-mod/info.json diff --git a/modules/events-mod/src/main/resources/kafkatorio-logo.png b/modules/events-mod/kafkatorio-logo.png similarity index 100% rename from modules/events-mod/src/main/resources/kafkatorio-logo.png rename to modules/events-mod/kafkatorio-logo.png diff --git a/modules/events-mod/src/main/resources/mod-portal-description.md b/modules/events-mod/mod-portal-description.md similarity index 100% rename from modules/events-mod/src/main/resources/mod-portal-description.md rename to modules/events-mod/mod-portal-description.md diff --git a/modules/events-mod/src/main/resources/mod-data/changelog.txt b/modules/events-mod/src/main/resources/changelog.txt similarity index 100% rename from modules/events-mod/src/main/resources/mod-data/changelog.txt rename to modules/events-mod/src/main/resources/changelog.txt diff --git a/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg b/modules/events-mod/src/main/resources/locale/en/locale.cfg similarity index 100% rename from modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg rename to modules/events-mod/src/main/resources/locale/en/locale.cfg diff --git a/modules/events-mod/src/main/resources/mod-data/thumbnail.png b/modules/events-mod/src/main/resources/thumbnail.png similarity index 100% rename from modules/events-mod/src/main/resources/mod-data/thumbnail.png rename to modules/events-mod/src/main/resources/thumbnail.png diff --git a/modules/events-processors/build.gradle.kts b/modules/events-processors/build.gradle.kts index 05835ab..fff7f2c 100644 --- a/modules/events-processors/build.gradle.kts +++ b/modules/events-processors/build.gradle.kts @@ -18,6 +18,7 @@ dependencies { implementation(platform(projects.modules.versionsPlatform)) implementation(libs.kafka.streams) + implementation(kotlin("reflect")) testImplementation(libs.kafka.streamsTestUtils) diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index a53c310..61ed6ae 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -18,13 +18,13 @@ val clientModsDirectory: DirectoryProperty = objects.directoryProperty().apply { set(modDir) } } -val factorioGameId = "427520" -val steamExe: RegularFileProperty = objects.fileProperty().apply { - val steam = File("""C:\Program Files (x86)\Steam\steam.exe""") - if (steam.exists()) { - set(steam) - } -} +//val factorioGameId = "427520" +//val steamExe: RegularFileProperty = objects.fileProperty().apply { +// val steam = File("""C:\Program Files (x86)\Steam\steam.exe""") +// if (steam.exists()) { +// set(steam) +// } +//} //val factorioMod: Configuration by configurations.creating { // asConsumer() @@ -37,21 +37,21 @@ dependencies { // -val deployModToLocalClient by tasks.registering(Copy::class) { - description = "Copy the mod to the Factorio client" - group = FactorioModPlugin.TASK_GROUP - - val clientModsDirectory123 = clientModsDirectory - - onlyIf { clientModsDirectory123.orNull?.asFile?.exists() == true } - - from(configurations.factorioMod.map { it.incoming.artifactView { lenient(true) }.files }) - into(clientModsDirectory) - - doLast { - logger.lifecycle("Copying mod from ${source.files} to $destinationDir") - } -} +//val deployModToLocalClient by tasks.registering(Copy::class) { +// description = "Copy the mod to the Factorio client" +// group = FactorioModPlugin.TASK_GROUP +// +// val clientModsDirectory123 = clientModsDirectory +// +// onlyIf { clientModsDirectory123.orNull?.asFile?.exists() == true } +// +// from(configurations.factorioMod.map { it.incoming.artifactView { lenient(true) }.files }) +// into(clientModsDirectory) +// +// doLast { +// logger.lifecycle("Copying mod from ${source.files} to $destinationDir") +// } +//} // @@ -59,27 +59,27 @@ val deployModToLocalClient by tasks.registering(Copy::class) { fun ExecOperations.isFactorioRunning(): Spec = ProcessRunningSpec(this, "factorio.exe") -val clientLaunch by tasks.registering(Exec::class) { - description = "Run local Factorio Steam game client" - group = FactorioModPlugin.TASK_GROUP - - val steamExe123 = steamExe - val clientModsDirectory444 = clientModsDirectory - - onlyIf(!serviceOf().isFactorioRunning()) - onlyIf { steamExe123.orNull?.asFile?.exists() == true } - onlyIf { clientModsDirectory444.orNull?.asFile?.exists() == true } - - dependsOn(deployModToLocalClient) - mustRunAfter(clientKill, ":modules:infra-factorio-server:processRun") - - commandLine = parseSpaceSeparatedArgs( -// """explorer "steam://rungameid/$factorioGameId// --mp-connect localhost/" """ // not working -// """explorer "steam://run/$factorioGameId//--mp-connect localhost/" """ // works! But has annoying pop-up - """ ${steamExe.asFile.orNull?.canonicalPath} -applaunch $factorioGameId --mp-connect localhost --mod-directory ${clientModsDirectory.asFile.orNull?.canonicalPath} """ - ) - doFirst { logger.lifecycle("Launching factorio.exe") } -} +//val clientLaunch by tasks.registering(Exec::class) { +// description = "Run local Factorio Steam game client" +// group = FactorioModPlugin.TASK_GROUP +// +// val steamExe123 = steamExe +// val clientModsDirectory444 = clientModsDirectory +// +// onlyIf(!serviceOf().isFactorioRunning()) +// onlyIf { steamExe123.orNull?.asFile?.exists() == true } +// onlyIf { clientModsDirectory444.orNull?.asFile?.exists() == true } +// +// dependsOn(deployModToLocalClient) +// mustRunAfter(clientKill, ":modules:infra-factorio-server:processRun") +// +// commandLine = parseSpaceSeparatedArgs( +//// """explorer "steam://rungameid/$factorioGameId// --mp-connect localhost/" """ // not working +//// """explorer "steam://run/$factorioGameId//--mp-connect localhost/" """ // works! But has annoying pop-up +// """ ${steamExe.asFile.orNull?.canonicalPath} -applaunch $factorioGameId --mp-connect localhost --mod-directory ${clientModsDirectory.asFile.orNull?.canonicalPath} """ +// ) +// doFirst { logger.lifecycle("Launching factorio.exe") } +//} val clientKill by tasks.registering(Exec::class) { description = "Stop the local Factorio Steam game client" @@ -95,14 +95,14 @@ val clientKill by tasks.registering(Exec::class) { tasks.register(FactorioModPlugin.PUBLISH_MOD_LOCAL_TASK_NAME) { group = FactorioModPlugin.TASK_GROUP - dependsOn(deployModToLocalClient) +// dependsOn(deployModToLocalClient) } tasks.processRun { dependsOn( - deployModToLocalClient, - clientLaunch, +// deployModToLocalClient, + tasks.launchFactorioClient, ) } diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 2093c80..8b40fe3 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -3,7 +3,7 @@ import dev.adamko.gradle.factorio.FactorioModPlugin plugins { id("kafkatorio.conventions.base") id("dev.adamko.geedeecee") - id("dev.adamko.factorio-mod") + id("dev.adamko.factorio-mod-library") idea } diff --git a/settings.gradle.kts b/settings.gradle.kts index 8cc8ca9..04b6e42 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -48,7 +48,9 @@ include( ) +//enableFeaturePreview(org.gradle.api.internal.FeaturePreviews.Feature.TYPESAFE_PROJECT_ACCESSORS.name) enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") +enableFeaturePreview("STABLE_CONFIGURATION_CACHE") //apply(from = "./buildSrc/repositories.settings.gradle.kts") From a99ed5bb85799b7bb2eb37cfd200d6a96f9fd867 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 19 Dec 2022 16:52:49 +0100 Subject: [PATCH 627/629] remove generated lua (it's stable - moved it to temp dir) --- .../events-mod/src/generated/lua/control.lua | 15 - .../lua/generated/kafkatorio-schema.lua | 82 - .../src/generated/lua/lualib_bundle.lua | 2528 ----------------- .../lua/main/commands/kafkatorioCommands.lua | 76 - .../lua/main/emitting/EventDataCache.lua | 141 - .../lua/main/emitting/EventDataQueue.lua | 87 - .../main/emitting/KafkatorioPacketQueue.lua | 48 - .../lua/main/emitting/PacketEmitter.lua | 33 - .../lua/main/events/configurationUpdate.lua | 13 - .../lua/main/events/consoleUpdates.lua | 20 - .../generated/lua/main/events/converters.lua | 162 -- .../lua/main/events/entityUpdates.lua | 32 - .../lua/main/events/eventTypeCheck.lua | 6 - .../handlers/ConfigurationUpdateHandler.lua | 62 - .../events/handlers/EntityUpdateHandler.lua | 176 -- .../events/handlers/MapChunkUpdateHandler.lua | 208 -- .../events/handlers/PlayerUpdateHandler.lua | 60 - .../lua/main/events/mapChunkUpdates.lua | 57 - .../lua/main/events/playerUpdates.lua | 129 - .../lua/main/events/prototypeUpdates.lua | 83 - .../main/events/registerEventListeners.lua | 57 - .../lua/main/events/settingsUpdate.lua | 6 - .../lua/main/events/surfaceUpdates.lua | 11 - .../src/generated/lua/main/global-init.lua | 17 - .../lua/main/settings/KafkatorioSettings.lua | 46 - .../events-mod/src/generated/lua/settings.lua | 5 - 26 files changed, 4160 deletions(-) delete mode 100644 modules/events-mod/src/generated/lua/control.lua delete mode 100644 modules/events-mod/src/generated/lua/generated/kafkatorio-schema.lua delete mode 100644 modules/events-mod/src/generated/lua/lualib_bundle.lua delete mode 100644 modules/events-mod/src/generated/lua/main/commands/kafkatorioCommands.lua delete mode 100644 modules/events-mod/src/generated/lua/main/emitting/EventDataCache.lua delete mode 100644 modules/events-mod/src/generated/lua/main/emitting/EventDataQueue.lua delete mode 100644 modules/events-mod/src/generated/lua/main/emitting/KafkatorioPacketQueue.lua delete mode 100644 modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua delete mode 100644 modules/events-mod/src/generated/lua/main/events/configurationUpdate.lua delete mode 100644 modules/events-mod/src/generated/lua/main/events/consoleUpdates.lua delete mode 100644 modules/events-mod/src/generated/lua/main/events/converters.lua delete mode 100644 modules/events-mod/src/generated/lua/main/events/entityUpdates.lua delete mode 100644 modules/events-mod/src/generated/lua/main/events/eventTypeCheck.lua delete mode 100644 modules/events-mod/src/generated/lua/main/events/handlers/ConfigurationUpdateHandler.lua delete mode 100644 modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua delete mode 100644 modules/events-mod/src/generated/lua/main/events/handlers/MapChunkUpdateHandler.lua delete mode 100644 modules/events-mod/src/generated/lua/main/events/handlers/PlayerUpdateHandler.lua delete mode 100644 modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua delete mode 100644 modules/events-mod/src/generated/lua/main/events/playerUpdates.lua delete mode 100644 modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua delete mode 100644 modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua delete mode 100644 modules/events-mod/src/generated/lua/main/events/settingsUpdate.lua delete mode 100644 modules/events-mod/src/generated/lua/main/events/surfaceUpdates.lua delete mode 100644 modules/events-mod/src/generated/lua/main/global-init.lua delete mode 100644 modules/events-mod/src/generated/lua/main/settings/KafkatorioSettings.lua delete mode 100644 modules/events-mod/src/generated/lua/settings.lua diff --git a/modules/events-mod/src/generated/lua/control.lua b/modules/events-mod/src/generated/lua/control.lua deleted file mode 100644 index a2839ec..0000000 --- a/modules/events-mod/src/generated/lua/control.lua +++ /dev/null @@ -1,15 +0,0 @@ -local ____exports = {} -local ____global_2Dinit = require("main.global-init") -local initGlobal = ____global_2Dinit.initGlobal -local ____prototypeUpdates = require("main.events.prototypeUpdates") -local emitPrototypes = ____prototypeUpdates.emitPrototypes -require("main.events.registerEventListeners") -require("main.events.mapChunkUpdates") -require("main.events.playerUpdates") -require("main.events.entityUpdates") -require("main.commands.kafkatorioCommands") -script.on_init(function() - initGlobal(true) - emitPrototypes() -end) -return ____exports diff --git a/modules/events-mod/src/generated/lua/generated/kafkatorio-schema.lua b/modules/events-mod/src/generated/lua/generated/kafkatorio-schema.lua deleted file mode 100644 index dba2989..0000000 --- a/modules/events-mod/src/generated/lua/generated/kafkatorio-schema.lua +++ /dev/null @@ -1,82 +0,0 @@ -local ____exports = {} -____exports.KafkatorioPacketData = {} -local KafkatorioPacketData = ____exports.KafkatorioPacketData -do - KafkatorioPacketData.Type = Type or ({}) - KafkatorioPacketData.Type.ConfigurationUpdate = "kafkatorio.packet.instant.ConfigurationUpdate" - KafkatorioPacketData.Type.ConsoleChatUpdate = "kafkatorio.packet.instant.ConsoleChatUpdate" - KafkatorioPacketData.Type.ConsoleCommandUpdate = "kafkatorio.packet.instant.ConsoleCommandUpdate" - KafkatorioPacketData.Type.PrototypesUpdate = "kafkatorio.packet.instant.PrototypesUpdate" - KafkatorioPacketData.Type.SurfaceUpdate = "kafkatorio.packet.instant.SurfaceUpdate" - KafkatorioPacketData.Type.EntityUpdate = "kafkatorio.packet.keyed.EntityUpdate" - KafkatorioPacketData.Type.MapChunkEntityUpdate = "kafkatorio.packet.keyed.MapChunkEntityUpdate" - KafkatorioPacketData.Type.MapChunkResourceUpdate = "kafkatorio.packet.keyed.MapChunkResourceUpdate" - KafkatorioPacketData.Type.MapChunkTileUpdate = "kafkatorio.packet.keyed.MapChunkTileUpdate" - KafkatorioPacketData.Type.PlayerUpdate = "kafkatorio.packet.keyed.PlayerUpdate" - KafkatorioPacketData.Type.Error = "kafkatorio.packet.KafkatorioPacketData.Error" -end -____exports.FactorioPrototype = {} -local FactorioPrototype = ____exports.FactorioPrototype -do - FactorioPrototype.Type = Type or ({}) - FactorioPrototype.Type.Entity = "kafkatorio.prototype.Entity" - FactorioPrototype.Type.MapTile = "kafkatorio.prototype.MapTile" -end -____exports.ChunkSize = ChunkSize or ({}) -____exports.ChunkSize.CHUNK_512 = "CHUNK_512" -____exports.ChunkSize.CHUNK_256 = "CHUNK_256" -____exports.ChunkSize.CHUNK_128 = "CHUNK_128" -____exports.ChunkSize.CHUNK_064 = "CHUNK_064" -____exports.ChunkSize.CHUNK_032 = "CHUNK_032" -____exports.MinedProduct = {} -local MinedProduct = ____exports.MinedProduct -do - MinedProduct.Type = Type or ({}) - MinedProduct.Type.MinedProductFluid = "kafkatorio.resource.MinedProduct.MinedProductFluid" - MinedProduct.Type.MinedProductItem = "kafkatorio.resource.MinedProduct.MinedProductItem" -end -____exports.FactorioEntityStatus = FactorioEntityStatus or ({}) -____exports.FactorioEntityStatus.WORKING = "WORKING" -____exports.FactorioEntityStatus.NORMAL = "NORMAL" -____exports.FactorioEntityStatus.NO_POWER = "NO_POWER" -____exports.FactorioEntityStatus.LOW_POWER = "LOW_POWER" -____exports.FactorioEntityStatus.NO_FUEL = "NO_FUEL" -____exports.FactorioEntityStatus.DISABLED_BY_CONTROL_BEHAVIOR = "DISABLED_BY_CONTROL_BEHAVIOR" -____exports.FactorioEntityStatus.OPENED_BY_CIRCUIT_NETWORK = "OPENED_BY_CIRCUIT_NETWORK" -____exports.FactorioEntityStatus.CLOSED_BY_CIRCUIT_NETWORK = "CLOSED_BY_CIRCUIT_NETWORK" -____exports.FactorioEntityStatus.DISABLED_BY_SCRIPT = "DISABLED_BY_SCRIPT" -____exports.FactorioEntityStatus.MARKED_FOR_DECONSTRUCTION = "MARKED_FOR_DECONSTRUCTION" -____exports.FactorioEntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK = "NOT_PLUGGED_IN_ELECTRIC_NETWORK" -____exports.FactorioEntityStatus.NETWORKS_CONNECTED = "NETWORKS_CONNECTED" -____exports.FactorioEntityStatus.NETWORKS_DISCONNECTED = "NETWORKS_DISCONNECTED" -____exports.FactorioEntityStatus.CHARGING = "CHARGING" -____exports.FactorioEntityStatus.DISCHARGING = "DISCHARGING" -____exports.FactorioEntityStatus.FULLY_CHARGED = "FULLY_CHARGED" -____exports.FactorioEntityStatus.OUT_OF_LOGISTIC_NETWORK = "OUT_OF_LOGISTIC_NETWORK" -____exports.FactorioEntityStatus.NO_RECIPE = "NO_RECIPE" -____exports.FactorioEntityStatus.NO_INGREDIENTS = "NO_INGREDIENTS" -____exports.FactorioEntityStatus.NO_INPUT_FLUID = "NO_INPUT_FLUID" -____exports.FactorioEntityStatus.NO_RESEARCH_IN_PROGRESS = "NO_RESEARCH_IN_PROGRESS" -____exports.FactorioEntityStatus.NO_MINABLE_RESOURCES = "NO_MINABLE_RESOURCES" -____exports.FactorioEntityStatus.LOW_INPUT_FLUID = "LOW_INPUT_FLUID" -____exports.FactorioEntityStatus.FLUID_INGREDIENT_SHORTAGE = "FLUID_INGREDIENT_SHORTAGE" -____exports.FactorioEntityStatus.FULL_OUTPUT = "FULL_OUTPUT" -____exports.FactorioEntityStatus.ITEM_INGREDIENT_SHORTAGE = "ITEM_INGREDIENT_SHORTAGE" -____exports.FactorioEntityStatus.MISSING_REQUIRED_FLUID = "MISSING_REQUIRED_FLUID" -____exports.FactorioEntityStatus.MISSING_SCIENCE_PACKS = "MISSING_SCIENCE_PACKS" -____exports.FactorioEntityStatus.WAITING_FOR_SOURCE_ITEMS = "WAITING_FOR_SOURCE_ITEMS" -____exports.FactorioEntityStatus.WAITING_FOR_SPACE_IN_DESTINATION = "WAITING_FOR_SPACE_IN_DESTINATION" -____exports.FactorioEntityStatus.PREPARING_ROCKET_FOR_LAUNCH = "PREPARING_ROCKET_FOR_LAUNCH" -____exports.FactorioEntityStatus.WAITING_TO_LAUNCH_ROCKET = "WAITING_TO_LAUNCH_ROCKET" -____exports.FactorioEntityStatus.LAUNCHING_ROCKET = "LAUNCHING_ROCKET" -____exports.FactorioEntityStatus.NO_MODULES_TO_TRANSMIT = "NO_MODULES_TO_TRANSMIT" -____exports.FactorioEntityStatus.RECHARGING_AFTER_POWER_OUTAGE = "RECHARGING_AFTER_POWER_OUTAGE" -____exports.FactorioEntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT = "WAITING_FOR_TARGET_TO_BE_BUILT" -____exports.FactorioEntityStatus.WAITING_FOR_TRAIN = "WAITING_FOR_TRAIN" -____exports.FactorioEntityStatus.NO_AMMO = "NO_AMMO" -____exports.FactorioEntityStatus.LOW_TEMPERATURE = "LOW_TEMPERATURE" -____exports.FactorioEntityStatus.DISABLED = "DISABLED" -____exports.FactorioEntityStatus.TURNED_OFF_DURING_DAYTIME = "TURNED_OFF_DURING_DAYTIME" -____exports.FactorioEntityStatus.NOT_CONNECTED_TO_RAIL = "NOT_CONNECTED_TO_RAIL" -____exports.FactorioEntityStatus.CANT_DIVIDE_SEGMENTS = "CANT_DIVIDE_SEGMENTS" -return ____exports diff --git a/modules/events-mod/src/generated/lua/lualib_bundle.lua b/modules/events-mod/src/generated/lua/lualib_bundle.lua deleted file mode 100644 index 43359d6..0000000 --- a/modules/events-mod/src/generated/lua/lualib_bundle.lua +++ /dev/null @@ -1,2528 +0,0 @@ -local function __TS__ArrayIsArray(value) - return type(value) == "table" and (value[1] ~= nil or next(value) == nil) -end - -local function __TS__ArrayConcat(self, ...) - local items = {...} - local result = {} - local len = 0 - for i = 1, #self do - len = len + 1 - result[len] = self[i] - end - for i = 1, #items do - local item = items[i] - if __TS__ArrayIsArray(item) then - for j = 1, #item do - len = len + 1 - result[len] = item[j] - end - else - len = len + 1 - result[len] = item - end - end - return result -end - -local __TS__Symbol, Symbol -do - local symbolMetatable = {__tostring = function(self) - return ("Symbol(" .. (self.description or "")) .. ")" - end} - function __TS__Symbol(description) - return setmetatable({description = description}, symbolMetatable) - end - Symbol = { - iterator = __TS__Symbol("Symbol.iterator"), - hasInstance = __TS__Symbol("Symbol.hasInstance"), - species = __TS__Symbol("Symbol.species"), - toStringTag = __TS__Symbol("Symbol.toStringTag") - } -end - -local function __TS__ArrayEntries(array) - local key = 0 - return { - [Symbol.iterator] = function(self) - return self - end, - next = function(self) - local result = {done = array[key + 1] == nil, value = {key, array[key + 1]}} - key = key + 1 - return result - end - } -end - -local function __TS__ArrayEvery(self, callbackfn, thisArg) - for i = 1, #self do - if not callbackfn(thisArg, self[i], i - 1, self) then - return false - end - end - return true -end - -local function __TS__ArrayFilter(self, callbackfn, thisArg) - local result = {} - local len = 0 - for i = 1, #self do - if callbackfn(thisArg, self[i], i - 1, self) then - len = len + 1 - result[len] = self[i] - end - end - return result -end - -local function __TS__ArrayForEach(self, callbackFn, thisArg) - for i = 1, #self do - callbackFn(thisArg, self[i], i - 1, self) - end -end - -local function __TS__ArrayFind(self, predicate, thisArg) - for i = 1, #self do - local elem = self[i] - if predicate(thisArg, elem, i - 1, self) then - return elem - end - end - return nil -end - -local function __TS__ArrayFindIndex(self, callbackFn, thisArg) - for i = 1, #self do - if callbackFn(thisArg, self[i], i - 1, self) then - return i - 1 - end - end - return -1 -end - -local __TS__Iterator -do - local function iteratorGeneratorStep(self) - local co = self.____coroutine - local status, value = coroutine.resume(co) - if not status then - error(value, 0) - end - if coroutine.status(co) == "dead" then - return - end - return true, value - end - local function iteratorIteratorStep(self) - local result = self:next() - if result.done then - return - end - return true, result.value - end - local function iteratorStringStep(self, index) - index = index + 1 - if index > #self then - return - end - return index, string.sub(self, index, index) - end - function __TS__Iterator(iterable) - if type(iterable) == "string" then - return iteratorStringStep, iterable, 0 - elseif iterable.____coroutine ~= nil then - return iteratorGeneratorStep, iterable - elseif iterable[Symbol.iterator] then - local iterator = iterable[Symbol.iterator](iterable) - return iteratorIteratorStep, iterator - else - return ipairs(iterable) - end - end -end - -local __TS__ArrayFrom -do - local function arrayLikeStep(self, index) - index = index + 1 - if index > self.length then - return - end - return index, self[index] - end - local function arrayLikeIterator(arr) - if type(arr.length) == "number" then - return arrayLikeStep, arr, 0 - end - return __TS__Iterator(arr) - end - function __TS__ArrayFrom(arrayLike, mapFn, thisArg) - local result = {} - if mapFn == nil then - for ____, v in arrayLikeIterator(arrayLike) do - result[#result + 1] = v - end - else - for i, v in arrayLikeIterator(arrayLike) do - result[#result + 1] = mapFn(thisArg, v, i - 1) - end - end - return result - end -end - -local function __TS__ArrayIncludes(self, searchElement, fromIndex) - if fromIndex == nil then - fromIndex = 0 - end - local len = #self - local k = fromIndex - if fromIndex < 0 then - k = len + fromIndex - end - if k < 0 then - k = 0 - end - for i = k + 1, len do - if self[i] == searchElement then - return true - end - end - return false -end - -local function __TS__ArrayIndexOf(self, searchElement, fromIndex) - if fromIndex == nil then - fromIndex = 0 - end - local len = #self - if len == 0 then - return -1 - end - if fromIndex >= len then - return -1 - end - if fromIndex < 0 then - fromIndex = len + fromIndex - if fromIndex < 0 then - fromIndex = 0 - end - end - for i = fromIndex + 1, len do - if self[i] == searchElement then - return i - 1 - end - end - return -1 -end - -local function __TS__ArrayJoin(self, separator) - if separator == nil then - separator = "," - end - local parts = {} - for i = 1, #self do - parts[i] = tostring(self[i]) - end - return table.concat(parts, separator) -end - -local function __TS__ArrayMap(self, callbackfn, thisArg) - local result = {} - for i = 1, #self do - result[i] = callbackfn(thisArg, self[i], i - 1, self) - end - return result -end - -local function __TS__ArrayPush(self, ...) - local items = {...} - local len = #self - for i = 1, #items do - len = len + 1 - self[len] = items[i] - end - return len -end - -local function __TS__ArrayPushArray(self, items) - local len = #self - for i = 1, #items do - len = len + 1 - self[len] = items[i] - end - return len -end - -local function __TS__CountVarargs(...) - return select("#", ...) -end - -local function __TS__ArrayReduce(self, callbackFn, ...) - local len = #self - local k = 0 - local accumulator = nil - if __TS__CountVarargs(...) ~= 0 then - accumulator = ... - elseif len > 0 then - accumulator = self[1] - k = 1 - else - error("Reduce of empty array with no initial value", 0) - end - for i = k + 1, len do - accumulator = callbackFn( - nil, - accumulator, - self[i], - i - 1, - self - ) - end - return accumulator -end - -local function __TS__ArrayReduceRight(self, callbackFn, ...) - local len = #self - local k = len - 1 - local accumulator = nil - if __TS__CountVarargs(...) ~= 0 then - accumulator = ... - elseif len > 0 then - accumulator = self[k + 1] - k = k - 1 - else - error("Reduce of empty array with no initial value", 0) - end - for i = k + 1, 1, -1 do - accumulator = callbackFn( - nil, - accumulator, - self[i], - i - 1, - self - ) - end - return accumulator -end - -local function __TS__ArrayReverse(self) - local i = 1 - local j = #self - while i < j do - local temp = self[j] - self[j] = self[i] - self[i] = temp - i = i + 1 - j = j - 1 - end - return self -end - -local function __TS__ArrayUnshift(self, ...) - local items = {...} - local numItemsToInsert = #items - if numItemsToInsert == 0 then - return #self - end - for i = #self, 1, -1 do - self[i + numItemsToInsert] = self[i] - end - for i = 1, numItemsToInsert do - self[i] = items[i] - end - return #self -end - -local function __TS__ArraySort(self, compareFn) - if compareFn ~= nil then - table.sort( - self, - function(a, b) return compareFn(nil, a, b) < 0 end - ) - else - table.sort(self) - end - return self -end - -local function __TS__ArraySlice(self, first, last) - local len = #self - local ____first_0 = first - if ____first_0 == nil then - ____first_0 = 0 - end - first = ____first_0 - if first < 0 then - first = len + first - if first < 0 then - first = 0 - end - else - if first > len then - first = len - end - end - local ____last_1 = last - if ____last_1 == nil then - ____last_1 = len - end - last = ____last_1 - if last < 0 then - last = len + last - if last < 0 then - last = 0 - end - else - if last > len then - last = len - end - end - local out = {} - first = first + 1 - last = last + 1 - local n = 1 - while first < last do - out[n] = self[first] - first = first + 1 - n = n + 1 - end - return out -end - -local function __TS__ArraySome(self, callbackfn, thisArg) - for i = 1, #self do - if callbackfn(thisArg, self[i], i - 1, self) then - return true - end - end - return false -end - -local function __TS__ArraySplice(self, ...) - local args = {...} - local len = #self - local actualArgumentCount = __TS__CountVarargs(...) - local start = args[1] - local deleteCount = args[2] - if start < 0 then - start = len + start - if start < 0 then - start = 0 - end - elseif start > len then - start = len - end - local itemCount = actualArgumentCount - 2 - if itemCount < 0 then - itemCount = 0 - end - local actualDeleteCount - if actualArgumentCount == 0 then - actualDeleteCount = 0 - elseif actualArgumentCount == 1 then - actualDeleteCount = len - start - else - local ____deleteCount_0 = deleteCount - if ____deleteCount_0 == nil then - ____deleteCount_0 = 0 - end - actualDeleteCount = ____deleteCount_0 - if actualDeleteCount < 0 then - actualDeleteCount = 0 - end - if actualDeleteCount > len - start then - actualDeleteCount = len - start - end - end - local out = {} - for k = 1, actualDeleteCount do - local from = start + k - if self[from] ~= nil then - out[k] = self[from] - end - end - if itemCount < actualDeleteCount then - for k = start + 1, len - actualDeleteCount do - local from = k + actualDeleteCount - local to = k + itemCount - if self[from] then - self[to] = self[from] - else - self[to] = nil - end - end - for k = len - actualDeleteCount + itemCount + 1, len do - self[k] = nil - end - elseif itemCount > actualDeleteCount then - for k = len - actualDeleteCount, start + 1, -1 do - local from = k + actualDeleteCount - local to = k + itemCount - if self[from] then - self[to] = self[from] - else - self[to] = nil - end - end - end - local j = start + 1 - for i = 3, actualArgumentCount do - self[j] = args[i] - j = j + 1 - end - for k = #self, len - actualDeleteCount + itemCount + 1, -1 do - self[k] = nil - end - return out -end - -local function __TS__ArrayToObject(self) - local object = {} - for i = 1, #self do - object[i - 1] = self[i] - end - return object -end - -local function __TS__ArrayFlat(self, depth) - if depth == nil then - depth = 1 - end - local result = {} - local len = 0 - for i = 1, #self do - local value = self[i] - if depth > 0 and __TS__ArrayIsArray(value) then - local toAdd - if depth == 1 then - toAdd = value - else - toAdd = __TS__ArrayFlat(value, depth - 1) - end - for j = 1, #toAdd do - local val = toAdd[j] - len = len + 1 - result[len] = val - end - else - len = len + 1 - result[len] = value - end - end - return result -end - -local function __TS__ArrayFlatMap(self, callback, thisArg) - local result = {} - local len = 0 - for i = 1, #self do - local value = callback(thisArg, self[i], i - 1, self) - if __TS__ArrayIsArray(value) then - for j = 1, #value do - len = len + 1 - result[len] = value[j] - end - else - len = len + 1 - result[len] = value - end - end - return result -end - -local function __TS__ArraySetLength(self, length) - if length < 0 or length ~= length or length == math.huge or math.floor(length) ~= length then - error( - "invalid array length: " .. tostring(length), - 0 - ) - end - for i = length + 1, #self do - self[i] = nil - end - return length -end - -local function __TS__InstanceOf(obj, classTbl) - if type(classTbl) ~= "table" then - error("Right-hand side of 'instanceof' is not an object", 0) - end - if classTbl[Symbol.hasInstance] ~= nil then - return not not classTbl[Symbol.hasInstance](classTbl, obj) - end - if type(obj) == "table" then - local luaClass = obj.constructor - while luaClass ~= nil do - if luaClass == classTbl then - return true - end - luaClass = luaClass.____super - end - end - return false -end - -local function __TS__New(target, ...) - local instance = setmetatable({}, target.prototype) - instance:____constructor(...) - return instance -end - -local function __TS__Class(self) - local c = {prototype = {}} - c.prototype.__index = c.prototype - c.prototype.constructor = c - return c -end - -local __TS__Unpack = table.unpack or unpack - -local function __TS__FunctionBind(fn, ...) - local boundArgs = {...} - return function(____, ...) - local args = {...} - __TS__ArrayUnshift( - args, - __TS__Unpack(boundArgs) - ) - return fn(__TS__Unpack(args)) - end -end - -local __TS__Promise -do - local function promiseDeferred(self) - local resolve - local reject - local promise = __TS__New( - __TS__Promise, - function(____, res, rej) - resolve = res - reject = rej - end - ) - return {promise = promise, resolve = resolve, reject = reject} - end - local function isPromiseLike(self, thing) - return __TS__InstanceOf(thing, __TS__Promise) - end - __TS__Promise = __TS__Class() - __TS__Promise.name = "__TS__Promise" - function __TS__Promise.prototype.____constructor(self, executor) - self.state = 0 - self.fulfilledCallbacks = {} - self.rejectedCallbacks = {} - self.finallyCallbacks = {} - do - local function ____catch(e) - self:reject(e) - end - local ____try, ____hasReturned = pcall(function() - executor( - nil, - __TS__FunctionBind(self.resolve, self), - __TS__FunctionBind(self.reject, self) - ) - end) - if not ____try then - ____catch(____hasReturned) - end - end - end - function __TS__Promise.resolve(data) - local promise = __TS__New( - __TS__Promise, - function() - end - ) - promise.state = 1 - promise.value = data - return promise - end - function __TS__Promise.reject(reason) - local promise = __TS__New( - __TS__Promise, - function() - end - ) - promise.state = 2 - promise.rejectionReason = reason - return promise - end - __TS__Promise.prototype["then"] = function(self, onFulfilled, onRejected) - local ____promiseDeferred_result_0 = promiseDeferred(nil) - local promise = ____promiseDeferred_result_0.promise - local resolve = ____promiseDeferred_result_0.resolve - local reject = ____promiseDeferred_result_0.reject - local isFulfilled = self.state == 1 - local isRejected = self.state == 2 - if onFulfilled then - local internalCallback = self:createPromiseResolvingCallback(onFulfilled, resolve, reject) - local ____self_fulfilledCallbacks_1 = self.fulfilledCallbacks - ____self_fulfilledCallbacks_1[#____self_fulfilledCallbacks_1 + 1] = internalCallback - if isFulfilled then - internalCallback(nil, self.value) - end - else - local ____self_fulfilledCallbacks_2 = self.fulfilledCallbacks - ____self_fulfilledCallbacks_2[#____self_fulfilledCallbacks_2 + 1] = function(____, v) return resolve(nil, v) end - end - if onRejected then - local internalCallback = self:createPromiseResolvingCallback(onRejected, resolve, reject) - local ____self_rejectedCallbacks_3 = self.rejectedCallbacks - ____self_rejectedCallbacks_3[#____self_rejectedCallbacks_3 + 1] = internalCallback - if isRejected then - internalCallback(nil, self.rejectionReason) - end - else - local ____self_rejectedCallbacks_4 = self.rejectedCallbacks - ____self_rejectedCallbacks_4[#____self_rejectedCallbacks_4 + 1] = function(____, err) return reject(nil, err) end - end - if isFulfilled then - resolve(nil, self.value) - end - if isRejected then - reject(nil, self.rejectionReason) - end - return promise - end - function __TS__Promise.prototype.catch(self, onRejected) - return self["then"](self, nil, onRejected) - end - function __TS__Promise.prototype.finally(self, onFinally) - if onFinally then - local ____self_finallyCallbacks_5 = self.finallyCallbacks - ____self_finallyCallbacks_5[#____self_finallyCallbacks_5 + 1] = onFinally - if self.state ~= 0 then - onFinally(nil) - end - end - return self - end - function __TS__Promise.prototype.resolve(self, data) - if __TS__InstanceOf(data, __TS__Promise) then - data["then"]( - data, - function(____, v) return self:resolve(v) end, - function(____, err) return self:reject(err) end - ) - return - end - if self.state == 0 then - self.state = 1 - self.value = data - for ____, callback in ipairs(self.fulfilledCallbacks) do - callback(nil, data) - end - for ____, callback in ipairs(self.finallyCallbacks) do - callback(nil) - end - end - end - function __TS__Promise.prototype.reject(self, reason) - if self.state == 0 then - self.state = 2 - self.rejectionReason = reason - for ____, callback in ipairs(self.rejectedCallbacks) do - callback(nil, reason) - end - for ____, callback in ipairs(self.finallyCallbacks) do - callback(nil) - end - end - end - function __TS__Promise.prototype.createPromiseResolvingCallback(self, f, resolve, reject) - return function(____, value) - do - local function ____catch(e) - reject(nil, e) - end - local ____try, ____hasReturned = pcall(function() - self:handleCallbackData( - f(nil, value), - resolve, - reject - ) - end) - if not ____try then - ____catch(____hasReturned) - end - end - end - end - function __TS__Promise.prototype.handleCallbackData(self, data, resolve, reject) - if isPromiseLike(nil, data) then - local nextpromise = data - if nextpromise.state == 1 then - resolve(nil, nextpromise.value) - elseif nextpromise.state == 2 then - reject(nil, nextpromise.rejectionReason) - else - data["then"](data, resolve, reject) - end - else - resolve(nil, data) - end - end -end - -local function __TS__AsyncAwaiter(generator) - return __TS__New( - __TS__Promise, - function(____, resolve, reject) - local adopt, fulfilled, step, resolved, asyncCoroutine - function adopt(self, value) - local ____temp_0 - if __TS__InstanceOf(value, __TS__Promise) then - ____temp_0 = value - else - ____temp_0 = __TS__Promise.resolve(value) - end - return ____temp_0 - end - function fulfilled(self, value) - local success, resultOrError = coroutine.resume(asyncCoroutine, value) - if success then - step(nil, resultOrError) - else - reject(nil, resultOrError) - end - end - function step(self, result) - if resolved then - return - end - if coroutine.status(asyncCoroutine) == "dead" then - resolve(nil, result) - else - local ____self_1 = adopt(nil, result) - ____self_1["then"](____self_1, fulfilled, reject) - end - end - resolved = false - asyncCoroutine = coroutine.create(generator) - local success, resultOrError = coroutine.resume( - asyncCoroutine, - function(____, v) - resolved = true - local ____self_2 = adopt(nil, v) - ____self_2["then"](____self_2, resolve, reject) - end - ) - if success then - step(nil, resultOrError) - else - reject(nil, resultOrError) - end - end - ) -end -local function __TS__Await(thing) - return coroutine.yield(thing) -end - -local function __TS__ClassExtends(target, base) - target.____super = base - local staticMetatable = setmetatable({__index = base}, base) - setmetatable(target, staticMetatable) - local baseMetatable = getmetatable(base) - if baseMetatable then - if type(baseMetatable.__index) == "function" then - staticMetatable.__index = baseMetatable.__index - end - if type(baseMetatable.__newindex) == "function" then - staticMetatable.__newindex = baseMetatable.__newindex - end - end - setmetatable(target.prototype, base.prototype) - if type(base.prototype.__index) == "function" then - target.prototype.__index = base.prototype.__index - end - if type(base.prototype.__newindex) == "function" then - target.prototype.__newindex = base.prototype.__newindex - end - if type(base.prototype.__tostring) == "function" then - target.prototype.__tostring = base.prototype.__tostring - end -end - -local function __TS__CloneDescriptor(____bindingPattern0) - local value - local writable - local set - local get - local configurable - local enumerable - enumerable = ____bindingPattern0.enumerable - configurable = ____bindingPattern0.configurable - get = ____bindingPattern0.get - set = ____bindingPattern0.set - writable = ____bindingPattern0.writable - value = ____bindingPattern0.value - local descriptor = {enumerable = enumerable == true, configurable = configurable == true} - local hasGetterOrSetter = get ~= nil or set ~= nil - local hasValueOrWritableAttribute = writable ~= nil or value ~= nil - if hasGetterOrSetter and hasValueOrWritableAttribute then - error("Invalid property descriptor. Cannot both specify accessors and a value or writable attribute.", 0) - end - if get or set then - descriptor.get = get - descriptor.set = set - else - descriptor.value = value - descriptor.writable = writable == true - end - return descriptor -end - -local function __TS__ObjectAssign(target, ...) - local sources = {...} - for i = 1, #sources do - local source = sources[i] - for key in pairs(source) do - target[key] = source[key] - end - end - return target -end - -local function __TS__ObjectGetOwnPropertyDescriptor(object, key) - local metatable = getmetatable(object) - if not metatable then - return - end - if not rawget(metatable, "_descriptors") then - return - end - return rawget(metatable, "_descriptors")[key] -end - -local __TS__SetDescriptor -do - local function descriptorIndex(self, key) - local value = rawget(self, key) - if value ~= nil then - return value - end - local metatable = getmetatable(self) - while metatable do - local rawResult = rawget(metatable, key) - if rawResult ~= nil then - return rawResult - end - local descriptors = rawget(metatable, "_descriptors") - if descriptors then - local descriptor = descriptors[key] - if descriptor then - if descriptor.get then - return descriptor.get(self) - end - return descriptor.value - end - end - metatable = getmetatable(metatable) - end - end - local function descriptorNewIndex(self, key, value) - local metatable = getmetatable(self) - while metatable do - local descriptors = rawget(metatable, "_descriptors") - if descriptors then - local descriptor = descriptors[key] - if descriptor then - if descriptor.set then - descriptor.set(self, value) - else - if descriptor.writable == false then - error( - ((("Cannot assign to read only property '" .. key) .. "' of object '") .. tostring(self)) .. "'", - 0 - ) - end - descriptor.value = value - end - return - end - end - metatable = getmetatable(metatable) - end - rawset(self, key, value) - end - function __TS__SetDescriptor(target, key, desc, isPrototype) - if isPrototype == nil then - isPrototype = false - end - local ____isPrototype_0 - if isPrototype then - ____isPrototype_0 = target - else - ____isPrototype_0 = getmetatable(target) - end - local metatable = ____isPrototype_0 - if not metatable then - metatable = {} - setmetatable(target, metatable) - end - local value = rawget(target, key) - if value ~= nil then - rawset(target, key, nil) - end - if not rawget(metatable, "_descriptors") then - metatable._descriptors = {} - end - metatable._descriptors[key] = __TS__CloneDescriptor(desc) - metatable.__index = descriptorIndex - metatable.__newindex = descriptorNewIndex - end -end - -local function __TS__Decorate(decorators, target, key, desc) - local result = target - do - local i = #decorators - while i >= 0 do - local decorator = decorators[i + 1] - if decorator then - local oldResult = result - if key == nil then - result = decorator(nil, result) - elseif desc == true then - local value = rawget(target, key) - local descriptor = __TS__ObjectGetOwnPropertyDescriptor(target, key) or ({configurable = true, writable = true, value = value}) - local desc = decorator(nil, target, key, descriptor) or descriptor - local isSimpleValue = desc.configurable == true and desc.writable == true and not desc.get and not desc.set - if isSimpleValue then - rawset(target, key, desc.value) - else - __TS__SetDescriptor( - target, - key, - __TS__ObjectAssign({}, descriptor, desc) - ) - end - elseif desc == false then - result = decorator(nil, target, key, desc) - else - result = decorator(nil, target, key) - end - result = result or oldResult - end - i = i - 1 - end - end - return result -end - -local function __TS__DecorateParam(paramIndex, decorator) - return function(____, target, key) return decorator(nil, target, key, paramIndex) end -end - -local function __TS__StringIncludes(self, searchString, position) - if not position then - position = 1 - else - position = position + 1 - end - local index = string.find(self, searchString, position, true) - return index ~= nil -end - -local Error, RangeError, ReferenceError, SyntaxError, TypeError, URIError -do - local function getErrorStack(self, constructor) - local level = 1 - while true do - local info = debug.getinfo(level, "f") - level = level + 1 - if not info then - level = 1 - break - elseif info.func == constructor then - break - end - end - if __TS__StringIncludes(_VERSION, "Lua 5.0") then - return debug.traceback(("[Level " .. tostring(level)) .. "]") - else - return debug.traceback(nil, level) - end - end - local function wrapErrorToString(self, getDescription) - return function(self) - local description = getDescription(self) - local caller = debug.getinfo(3, "f") - local isClassicLua = __TS__StringIncludes(_VERSION, "Lua 5.0") or _VERSION == "Lua 5.1" - if isClassicLua or caller and caller.func ~= error then - return description - else - return (tostring(description) .. "\n") .. self.stack - end - end - end - local function initErrorClass(self, Type, name) - Type.name = name - return setmetatable( - Type, - {__call = function(____, _self, message) return __TS__New(Type, message) end} - ) - end - local ____initErrorClass_2 = initErrorClass - local ____class_0 = __TS__Class() - ____class_0.name = "" - function ____class_0.prototype.____constructor(self, message) - if message == nil then - message = "" - end - self.message = message - self.name = "Error" - self.stack = getErrorStack(nil, self.constructor.new) - local metatable = getmetatable(self) - if not metatable.__errorToStringPatched then - metatable.__errorToStringPatched = true - metatable.__tostring = wrapErrorToString(nil, metatable.__tostring) - end - end - function ____class_0.prototype.__tostring(self) - local ____temp_1 - if self.message ~= "" then - ____temp_1 = (self.name .. ": ") .. self.message - else - ____temp_1 = self.name - end - return ____temp_1 - end - Error = ____initErrorClass_2(nil, ____class_0, "Error") - local function createErrorClass(self, name) - local ____initErrorClass_4 = initErrorClass - local ____class_3 = __TS__Class() - ____class_3.name = ____class_3.name - __TS__ClassExtends(____class_3, Error) - function ____class_3.prototype.____constructor(self, ...) - ____class_3.____super.prototype.____constructor(self, ...) - self.name = name - end - return ____initErrorClass_4(nil, ____class_3, name) - end - RangeError = createErrorClass(nil, "RangeError") - ReferenceError = createErrorClass(nil, "ReferenceError") - SyntaxError = createErrorClass(nil, "SyntaxError") - TypeError = createErrorClass(nil, "TypeError") - URIError = createErrorClass(nil, "URIError") -end - -local function __TS__ObjectGetOwnPropertyDescriptors(object) - local metatable = getmetatable(object) - if not metatable then - return {} - end - return rawget(metatable, "_descriptors") or ({}) -end - -local function __TS__Delete(target, key) - local descriptors = __TS__ObjectGetOwnPropertyDescriptors(target) - local descriptor = descriptors[key] - if descriptor then - if not descriptor.configurable then - error( - __TS__New( - TypeError, - ((("Cannot delete property " .. tostring(key)) .. " of ") .. tostring(target)) .. "." - ), - 0 - ) - end - descriptors[key] = nil - return true - end - target[key] = nil - return true -end - -local function __TS__StringAccess(self, index) - if index >= 0 and index < #self then - return string.sub(self, index + 1, index + 1) - end -end - -local function __TS__DelegatedYield(iterable) - if type(iterable) == "string" then - for index = 0, #iterable - 1 do - coroutine.yield(__TS__StringAccess(iterable, index)) - end - elseif iterable.____coroutine ~= nil then - local co = iterable.____coroutine - while true do - local status, value = coroutine.resume(co) - if not status then - error(value, 0) - end - if coroutine.status(co) == "dead" then - return value - else - coroutine.yield(value) - end - end - elseif iterable[Symbol.iterator] then - local iterator = iterable[Symbol.iterator](iterable) - while true do - local result = iterator:next() - if result.done then - return result.value - else - coroutine.yield(result.value) - end - end - else - for ____, value in ipairs(iterable) do - coroutine.yield(value) - end - end -end - -local __TS__Generator -do - local function generatorIterator(self) - return self - end - local function generatorNext(self, ...) - local co = self.____coroutine - if coroutine.status(co) == "dead" then - return {done = true} - end - local status, value = coroutine.resume(co, ...) - if not status then - error(value, 0) - end - return { - value = value, - done = coroutine.status(co) == "dead" - } - end - function __TS__Generator(fn) - return function(...) - local args = {...} - local argsLength = __TS__CountVarargs(...) - return { - ____coroutine = coroutine.create(function() return fn(__TS__Unpack(args, 1, argsLength)) end), - [Symbol.iterator] = generatorIterator, - next = generatorNext - } - end - end -end - -local function __TS__InstanceOfObject(value) - local valueType = type(value) - return valueType == "table" or valueType == "function" -end - -local function __TS__LuaIteratorSpread(self, state, firstKey) - local results = {} - local key, value = self(state, firstKey) - while key do - results[#results + 1] = {key, value} - key, value = self(state, key) - end - return __TS__Unpack(results) -end - -local Map -do - Map = __TS__Class() - Map.name = "Map" - function Map.prototype.____constructor(self, entries) - self[Symbol.toStringTag] = "Map" - self.items = {} - self.size = 0 - self.nextKey = {} - self.previousKey = {} - if entries == nil then - return - end - local iterable = entries - if iterable[Symbol.iterator] then - local iterator = iterable[Symbol.iterator](iterable) - while true do - local result = iterator:next() - if result.done then - break - end - local value = result.value - self:set(value[1], value[2]) - end - else - local array = entries - for ____, kvp in ipairs(array) do - self:set(kvp[1], kvp[2]) - end - end - end - function Map.prototype.clear(self) - self.items = {} - self.nextKey = {} - self.previousKey = {} - self.firstKey = nil - self.lastKey = nil - self.size = 0 - end - function Map.prototype.delete(self, key) - local contains = self:has(key) - if contains then - self.size = self.size - 1 - local next = self.nextKey[key] - local previous = self.previousKey[key] - if next and previous then - self.nextKey[previous] = next - self.previousKey[next] = previous - elseif next then - self.firstKey = next - self.previousKey[next] = nil - elseif previous then - self.lastKey = previous - self.nextKey[previous] = nil - else - self.firstKey = nil - self.lastKey = nil - end - self.nextKey[key] = nil - self.previousKey[key] = nil - end - self.items[key] = nil - return contains - end - function Map.prototype.forEach(self, callback) - for ____, key in __TS__Iterator(self:keys()) do - callback(nil, self.items[key], key, self) - end - end - function Map.prototype.get(self, key) - return self.items[key] - end - function Map.prototype.has(self, key) - return self.nextKey[key] ~= nil or self.lastKey == key - end - function Map.prototype.set(self, key, value) - local isNewValue = not self:has(key) - if isNewValue then - self.size = self.size + 1 - end - self.items[key] = value - if self.firstKey == nil then - self.firstKey = key - self.lastKey = key - elseif isNewValue then - self.nextKey[self.lastKey] = key - self.previousKey[key] = self.lastKey - self.lastKey = key - end - return self - end - Map.prototype[Symbol.iterator] = function(self) - return self:entries() - end - function Map.prototype.entries(self) - local items = self.items - local nextKey = self.nextKey - local key = self.firstKey - return { - [Symbol.iterator] = function(self) - return self - end, - next = function(self) - local result = {done = not key, value = {key, items[key]}} - key = nextKey[key] - return result - end - } - end - function Map.prototype.keys(self) - local nextKey = self.nextKey - local key = self.firstKey - return { - [Symbol.iterator] = function(self) - return self - end, - next = function(self) - local result = {done = not key, value = key} - key = nextKey[key] - return result - end - } - end - function Map.prototype.values(self) - local items = self.items - local nextKey = self.nextKey - local key = self.firstKey - return { - [Symbol.iterator] = function(self) - return self - end, - next = function(self) - local result = {done = not key, value = items[key]} - key = nextKey[key] - return result - end - } - end - Map[Symbol.species] = Map -end - -local __TS__Match = string.match - -local __TS__MathAtan2 = math.atan2 or math.atan - -local __TS__MathModf = math.modf - -local function __TS__MathSign(val) - if val > 0 then - return 1 - elseif val < 0 then - return -1 - end - return 0 -end - -local function __TS__Number(value) - local valueType = type(value) - if valueType == "number" then - return value - elseif valueType == "string" then - local numberValue = tonumber(value) - if numberValue then - return numberValue - end - if value == "Infinity" then - return math.huge - end - if value == "-Infinity" then - return -math.huge - end - local stringWithoutSpaces = string.gsub(value, "%s", "") - if stringWithoutSpaces == "" then - return 0 - end - return 0 / 0 - elseif valueType == "boolean" then - return value and 1 or 0 - else - return 0 / 0 - end -end - -local function __TS__NumberIsFinite(value) - return type(value) == "number" and value == value and value ~= math.huge and value ~= -math.huge -end - -local function __TS__NumberIsNaN(value) - return value ~= value -end - -local __TS__NumberToString -do - local radixChars = "0123456789abcdefghijklmnopqrstuvwxyz" - function __TS__NumberToString(self, radix) - if radix == nil or radix == 10 or self == math.huge or self == -math.huge or self ~= self then - return tostring(self) - end - radix = math.floor(radix) - if radix < 2 or radix > 36 then - error("toString() radix argument must be between 2 and 36", 0) - end - local integer, fraction = __TS__MathModf(math.abs(self)) - local result = "" - if radix == 8 then - result = string.format("%o", integer) - elseif radix == 16 then - result = string.format("%x", integer) - else - repeat - do - result = __TS__StringAccess(radixChars, integer % radix) .. result - integer = math.floor(integer / radix) - end - until not (integer ~= 0) - end - if fraction ~= 0 then - result = result .. "." - local delta = 1e-16 - repeat - do - fraction = fraction * radix - delta = delta * radix - local digit = math.floor(fraction) - result = result .. __TS__StringAccess(radixChars, digit) - fraction = fraction - digit - end - until not (fraction >= delta) - end - if self < 0 then - result = "-" .. result - end - return result - end -end - -local function __TS__ObjectDefineProperty(target, key, desc) - local ____temp_0 - if type(key) == "number" then - ____temp_0 = key + 1 - else - ____temp_0 = key - end - local luaKey = ____temp_0 - local value = rawget(target, luaKey) - local hasGetterOrSetter = desc.get ~= nil or desc.set ~= nil - local descriptor - if hasGetterOrSetter then - if value ~= nil then - error( - "Cannot redefine property: " .. tostring(key), - 0 - ) - end - descriptor = desc - else - local valueExists = value ~= nil - local ____desc_set_5 = desc.set - local ____desc_get_6 = desc.get - local ____temp_1 - if desc.configurable ~= nil then - ____temp_1 = desc.configurable - else - ____temp_1 = valueExists - end - local ____temp_2 - if desc.enumerable ~= nil then - ____temp_2 = desc.enumerable - else - ____temp_2 = valueExists - end - local ____temp_3 - if desc.writable ~= nil then - ____temp_3 = desc.writable - else - ____temp_3 = valueExists - end - local ____temp_4 - if desc.value ~= nil then - ____temp_4 = desc.value - else - ____temp_4 = value - end - descriptor = { - set = ____desc_set_5, - get = ____desc_get_6, - configurable = ____temp_1, - enumerable = ____temp_2, - writable = ____temp_3, - value = ____temp_4 - } - end - __TS__SetDescriptor(target, luaKey, descriptor) - return target -end - -local function __TS__ObjectEntries(obj) - local result = {} - local len = 0 - for key in pairs(obj) do - len = len + 1 - result[len] = {key, obj[key]} - end - return result -end - -local function __TS__ObjectFromEntries(entries) - local obj = {} - local iterable = entries - if iterable[Symbol.iterator] then - local iterator = iterable[Symbol.iterator](iterable) - while true do - local result = iterator:next() - if result.done then - break - end - local value = result.value - obj[value[1]] = value[2] - end - else - for ____, entry in ipairs(entries) do - obj[entry[1]] = entry[2] - end - end - return obj -end - -local function __TS__ObjectKeys(obj) - local result = {} - local len = 0 - for key in pairs(obj) do - len = len + 1 - result[len] = key - end - return result -end - -local function __TS__ObjectRest(target, usedProperties) - local result = {} - for property in pairs(target) do - if not usedProperties[property] then - result[property] = target[property] - end - end - return result -end - -local function __TS__ObjectValues(obj) - local result = {} - local len = 0 - for key in pairs(obj) do - len = len + 1 - result[len] = obj[key] - end - return result -end - -local function __TS__ParseFloat(numberString) - local infinityMatch = __TS__Match(numberString, "^%s*(-?Infinity)") - if infinityMatch then - local ____temp_0 - if __TS__StringAccess(infinityMatch, 0) == "-" then - ____temp_0 = -math.huge - else - ____temp_0 = math.huge - end - return ____temp_0 - end - local number = tonumber(__TS__Match(numberString, "^%s*(-?%d+%.?%d*)")) - local ____number_1 = number - if ____number_1 == nil then - ____number_1 = 0 / 0 - end - return ____number_1 -end - -local function __TS__StringSubstring(self, start, ____end) - if ____end ~= ____end then - ____end = 0 - end - if ____end ~= nil and start > ____end then - start, ____end = ____end, start - end - if start >= 0 then - start = start + 1 - else - start = 1 - end - if ____end ~= nil and ____end < 0 then - ____end = 0 - end - return string.sub(self, start, ____end) -end - -local __TS__ParseInt -do - local parseIntBasePattern = "0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTvVwWxXyYzZ" - function __TS__ParseInt(numberString, base) - if base == nil then - base = 10 - local hexMatch = __TS__Match(numberString, "^%s*-?0[xX]") - if hexMatch then - base = 16 - local ____TS__Match_result__0_0 - if __TS__Match(hexMatch, "-") then - ____TS__Match_result__0_0 = "-" .. __TS__StringSubstring(numberString, #hexMatch) - else - ____TS__Match_result__0_0 = __TS__StringSubstring(numberString, #hexMatch) - end - numberString = ____TS__Match_result__0_0 - end - end - if base < 2 or base > 36 then - return 0 / 0 - end - local ____temp_1 - if base <= 10 then - ____temp_1 = __TS__StringSubstring(parseIntBasePattern, 0, base) - else - ____temp_1 = __TS__StringSubstring(parseIntBasePattern, 0, 10 + 2 * (base - 10)) - end - local allowedDigits = ____temp_1 - local pattern = ("^%s*(-?[" .. allowedDigits) .. "]*)" - local number = tonumber( - __TS__Match(numberString, pattern), - base - ) - if number == nil then - return 0 / 0 - end - if number >= 0 then - return math.floor(number) - else - return math.ceil(number) - end - end -end - -local function __TS__PromiseAll(iterable) - local results = {} - local toResolve = {} - local numToResolve = 0 - local i = 0 - for ____, item in __TS__Iterator(iterable) do - if __TS__InstanceOf(item, __TS__Promise) then - if item.state == 1 then - results[i + 1] = item.value - elseif item.state == 2 then - return __TS__Promise.reject(item.rejectionReason) - else - numToResolve = numToResolve + 1 - toResolve[i] = item - end - else - results[i + 1] = item - end - i = i + 1 - end - if numToResolve == 0 then - return __TS__Promise.resolve(results) - end - return __TS__New( - __TS__Promise, - function(____, resolve, reject) - for index, promise in pairs(toResolve) do - promise["then"]( - promise, - function(____, data) - results[index + 1] = data - numToResolve = numToResolve - 1 - if numToResolve == 0 then - resolve(nil, results) - end - end, - function(____, reason) - reject(nil, reason) - end - ) - end - end - ) -end - -local function __TS__PromiseAllSettled(iterable) - local results = {} - local toResolve = {} - local numToResolve = 0 - local i = 0 - for ____, item in __TS__Iterator(iterable) do - if __TS__InstanceOf(item, __TS__Promise) then - if item.state == 1 then - results[i + 1] = {status = "fulfilled", value = item.value} - elseif item.state == 2 then - results[i + 1] = {status = "rejected", reason = item.rejectionReason} - else - numToResolve = numToResolve + 1 - toResolve[i] = item - end - else - results[i + 1] = {status = "fulfilled", value = item} - end - i = i + 1 - end - if numToResolve == 0 then - return __TS__Promise.resolve(results) - end - return __TS__New( - __TS__Promise, - function(____, resolve) - for index, promise in pairs(toResolve) do - promise["then"]( - promise, - function(____, data) - results[index + 1] = {status = "fulfilled", value = data} - numToResolve = numToResolve - 1 - if numToResolve == 0 then - resolve(nil, results) - end - end, - function(____, reason) - results[index + 1] = {status = "rejected", reason = reason} - numToResolve = numToResolve - 1 - if numToResolve == 0 then - resolve(nil, results) - end - end - ) - end - end - ) -end - -local function __TS__PromiseAny(iterable) - local rejections = {} - local pending = {} - for ____, item in __TS__Iterator(iterable) do - if __TS__InstanceOf(item, __TS__Promise) then - if item.state == 1 then - return __TS__Promise.resolve(item.value) - elseif item.state == 2 then - rejections[#rejections + 1] = item.rejectionReason - else - pending[#pending + 1] = item - end - else - return __TS__Promise.resolve(item) - end - end - if #pending == 0 then - return __TS__Promise.reject("No promises to resolve with .any()") - end - local numResolved = 0 - return __TS__New( - __TS__Promise, - function(____, resolve, reject) - for ____, promise in ipairs(pending) do - promise["then"]( - promise, - function(____, data) - resolve(nil, data) - end, - function(____, reason) - rejections[#rejections + 1] = reason - numResolved = numResolved + 1 - if numResolved == #pending then - reject(nil, {name = "AggregateError", message = "All Promises rejected", errors = rejections}) - end - end - ) - end - end - ) -end - -local function __TS__PromiseRace(iterable) - local pending = {} - for ____, item in __TS__Iterator(iterable) do - if __TS__InstanceOf(item, __TS__Promise) then - if item.state == 1 then - return __TS__Promise.resolve(item.value) - elseif item.state == 2 then - return __TS__Promise.reject(item.rejectionReason) - else - pending[#pending + 1] = item - end - else - return __TS__Promise.resolve(item) - end - end - return __TS__New( - __TS__Promise, - function(____, resolve, reject) - for ____, promise in ipairs(pending) do - promise["then"]( - promise, - function(____, value) return resolve(nil, value) end, - function(____, reason) return reject(nil, reason) end - ) - end - end - ) -end - -local Set -do - Set = __TS__Class() - Set.name = "Set" - function Set.prototype.____constructor(self, values) - self[Symbol.toStringTag] = "Set" - self.size = 0 - self.nextKey = {} - self.previousKey = {} - if values == nil then - return - end - local iterable = values - if iterable[Symbol.iterator] then - local iterator = iterable[Symbol.iterator](iterable) - while true do - local result = iterator:next() - if result.done then - break - end - self:add(result.value) - end - else - local array = values - for ____, value in ipairs(array) do - self:add(value) - end - end - end - function Set.prototype.add(self, value) - local isNewValue = not self:has(value) - if isNewValue then - self.size = self.size + 1 - end - if self.firstKey == nil then - self.firstKey = value - self.lastKey = value - elseif isNewValue then - self.nextKey[self.lastKey] = value - self.previousKey[value] = self.lastKey - self.lastKey = value - end - return self - end - function Set.prototype.clear(self) - self.nextKey = {} - self.previousKey = {} - self.firstKey = nil - self.lastKey = nil - self.size = 0 - end - function Set.prototype.delete(self, value) - local contains = self:has(value) - if contains then - self.size = self.size - 1 - local next = self.nextKey[value] - local previous = self.previousKey[value] - if next and previous then - self.nextKey[previous] = next - self.previousKey[next] = previous - elseif next then - self.firstKey = next - self.previousKey[next] = nil - elseif previous then - self.lastKey = previous - self.nextKey[previous] = nil - else - self.firstKey = nil - self.lastKey = nil - end - self.nextKey[value] = nil - self.previousKey[value] = nil - end - return contains - end - function Set.prototype.forEach(self, callback) - for ____, key in __TS__Iterator(self:keys()) do - callback(nil, key, key, self) - end - end - function Set.prototype.has(self, value) - return self.nextKey[value] ~= nil or self.lastKey == value - end - Set.prototype[Symbol.iterator] = function(self) - return self:values() - end - function Set.prototype.entries(self) - local nextKey = self.nextKey - local key = self.firstKey - return { - [Symbol.iterator] = function(self) - return self - end, - next = function(self) - local result = {done = not key, value = {key, key}} - key = nextKey[key] - return result - end - } - end - function Set.prototype.keys(self) - local nextKey = self.nextKey - local key = self.firstKey - return { - [Symbol.iterator] = function(self) - return self - end, - next = function(self) - local result = {done = not key, value = key} - key = nextKey[key] - return result - end - } - end - function Set.prototype.values(self) - local nextKey = self.nextKey - local key = self.firstKey - return { - [Symbol.iterator] = function(self) - return self - end, - next = function(self) - local result = {done = not key, value = key} - key = nextKey[key] - return result - end - } - end - Set[Symbol.species] = Set -end - -local function __TS__SparseArrayNew(...) - local sparseArray = {...} - sparseArray.sparseLength = __TS__CountVarargs(...) - return sparseArray -end - -local function __TS__SparseArrayPush(sparseArray, ...) - local args = {...} - local argsLen = __TS__CountVarargs(...) - local listLen = sparseArray.sparseLength - for i = 1, argsLen do - sparseArray[listLen + i] = args[i] - end - sparseArray.sparseLength = listLen + argsLen -end - -local function __TS__SparseArraySpread(sparseArray) - local ____unpack_0 = unpack - if ____unpack_0 == nil then - ____unpack_0 = table.unpack - end - local _unpack = ____unpack_0 - return _unpack(sparseArray, 1, sparseArray.sparseLength) -end - -local WeakMap -do - WeakMap = __TS__Class() - WeakMap.name = "WeakMap" - function WeakMap.prototype.____constructor(self, entries) - self[Symbol.toStringTag] = "WeakMap" - self.items = {} - setmetatable(self.items, {__mode = "k"}) - if entries == nil then - return - end - local iterable = entries - if iterable[Symbol.iterator] then - local iterator = iterable[Symbol.iterator](iterable) - while true do - local result = iterator:next() - if result.done then - break - end - local value = result.value - self.items[value[1]] = value[2] - end - else - for ____, kvp in ipairs(entries) do - self.items[kvp[1]] = kvp[2] - end - end - end - function WeakMap.prototype.delete(self, key) - local contains = self:has(key) - self.items[key] = nil - return contains - end - function WeakMap.prototype.get(self, key) - return self.items[key] - end - function WeakMap.prototype.has(self, key) - return self.items[key] ~= nil - end - function WeakMap.prototype.set(self, key, value) - self.items[key] = value - return self - end - WeakMap[Symbol.species] = WeakMap -end - -local WeakSet -do - WeakSet = __TS__Class() - WeakSet.name = "WeakSet" - function WeakSet.prototype.____constructor(self, values) - self[Symbol.toStringTag] = "WeakSet" - self.items = {} - setmetatable(self.items, {__mode = "k"}) - if values == nil then - return - end - local iterable = values - if iterable[Symbol.iterator] then - local iterator = iterable[Symbol.iterator](iterable) - while true do - local result = iterator:next() - if result.done then - break - end - self.items[result.value] = true - end - else - for ____, value in ipairs(values) do - self.items[value] = true - end - end - end - function WeakSet.prototype.add(self, value) - self.items[value] = true - return self - end - function WeakSet.prototype.delete(self, value) - local contains = self:has(value) - self.items[value] = nil - return contains - end - function WeakSet.prototype.has(self, value) - return self.items[value] == true - end - WeakSet[Symbol.species] = WeakSet -end - -local function __TS__SourceMapTraceBack(fileName, sourceMap) - _G.__TS__sourcemap = _G.__TS__sourcemap or ({}) - _G.__TS__sourcemap[fileName] = sourceMap - if _G.__TS__originalTraceback == nil then - local originalTraceback = debug.traceback - _G.__TS__originalTraceback = originalTraceback - debug.traceback = function(thread, message, level) - local trace - if thread == nil and message == nil and level == nil then - trace = originalTraceback() - elseif __TS__StringIncludes(_VERSION, "Lua 5.0") then - trace = originalTraceback((("[Level " .. tostring(level)) .. "] ") .. message) - else - trace = originalTraceback(thread, message, level) - end - if type(trace) ~= "string" then - return trace - end - local function replacer(____, file, srcFile, line) - local fileSourceMap = _G.__TS__sourcemap[file] - if fileSourceMap and fileSourceMap[line] then - local data = fileSourceMap[line] - if type(data) == "number" then - return (srcFile .. ":") .. tostring(data) - end - return (tostring(data.file) .. ":") .. tostring(data.line) - end - return (file .. ":") .. line - end - local result = string.gsub( - trace, - "(%S+)%.lua:(%d+)", - function(file, line) return replacer(nil, file .. ".lua", file .. ".ts", line) end - ) - local function stringReplacer(____, file, line) - local fileSourceMap = _G.__TS__sourcemap[file] - if fileSourceMap and fileSourceMap[line] then - local chunkName = __TS__Match(file, "%[string \"([^\"]+)\"%]") - local sourceName = string.gsub(chunkName, ".lua$", ".ts") - local data = fileSourceMap[line] - if type(data) == "number" then - return (sourceName .. ":") .. tostring(data) - end - return (tostring(data.file) .. ":") .. tostring(data.line) - end - return (file .. ":") .. line - end - result = string.gsub( - result, - "(%[string \"[^\"]+\"%]):(%d+)", - function(file, line) return stringReplacer(nil, file, line) end - ) - return result - end - end -end - -local function __TS__Spread(iterable) - local arr = {} - if type(iterable) == "string" then - for i = 0, #iterable - 1 do - arr[i + 1] = __TS__StringAccess(iterable, i) - end - else - local len = 0 - for ____, item in __TS__Iterator(iterable) do - len = len + 1 - arr[len] = item - end - end - return __TS__Unpack(arr) -end - -local function __TS__StringCharAt(self, pos) - if pos ~= pos then - pos = 0 - end - if pos < 0 then - return "" - end - return string.sub(self, pos + 1, pos + 1) -end - -local function __TS__StringCharCodeAt(self, index) - if index ~= index then - index = 0 - end - if index < 0 then - return 0 / 0 - end - local ____string_byte_result_0 = string.byte(self, index + 1) - if ____string_byte_result_0 == nil then - ____string_byte_result_0 = 0 / 0 - end - return ____string_byte_result_0 -end - -local function __TS__StringEndsWith(self, searchString, endPosition) - if endPosition == nil or endPosition > #self then - endPosition = #self - end - return string.sub(self, endPosition - #searchString + 1, endPosition) == searchString -end - -local function __TS__StringPadEnd(self, maxLength, fillString) - if fillString == nil then - fillString = " " - end - if maxLength ~= maxLength then - maxLength = 0 - end - if maxLength == -math.huge or maxLength == math.huge then - error("Invalid string length", 0) - end - if #self >= maxLength or #fillString == 0 then - return self - end - maxLength = maxLength - #self - if maxLength > #fillString then - fillString = fillString .. string.rep( - fillString, - math.floor(maxLength / #fillString) - ) - end - return self .. string.sub( - fillString, - 1, - math.floor(maxLength) - ) -end - -local function __TS__StringPadStart(self, maxLength, fillString) - if fillString == nil then - fillString = " " - end - if maxLength ~= maxLength then - maxLength = 0 - end - if maxLength == -math.huge or maxLength == math.huge then - error("Invalid string length", 0) - end - if #self >= maxLength or #fillString == 0 then - return self - end - maxLength = maxLength - #self - if maxLength > #fillString then - fillString = fillString .. string.rep( - fillString, - math.floor(maxLength / #fillString) - ) - end - return string.sub( - fillString, - 1, - math.floor(maxLength) - ) .. self -end - -local __TS__StringReplace -do - local sub = string.sub - function __TS__StringReplace(source, searchValue, replaceValue) - local startPos, endPos = string.find(source, searchValue, nil, true) - if not startPos then - return source - end - local before = sub(source, 1, startPos - 1) - local ____temp_0 - if type(replaceValue) == "string" then - ____temp_0 = replaceValue - else - ____temp_0 = replaceValue(nil, searchValue, startPos - 1, source) - end - local replacement = ____temp_0 - local after = sub(source, endPos + 1) - return (before .. replacement) .. after - end -end - -local __TS__StringSplit -do - local sub = string.sub - local find = string.find - function __TS__StringSplit(source, separator, limit) - if limit == nil then - limit = 4294967295 - end - if limit == 0 then - return {} - end - local result = {} - local resultIndex = 1 - if separator == nil or separator == "" then - for i = 1, #source do - result[resultIndex] = sub(source, i, i) - resultIndex = resultIndex + 1 - end - else - local currentPos = 1 - while resultIndex <= limit do - local startPos, endPos = find(source, separator, currentPos, true) - if not startPos then - break - end - result[resultIndex] = sub(source, currentPos, startPos - 1) - resultIndex = resultIndex + 1 - currentPos = endPos + 1 - end - if resultIndex <= limit then - result[resultIndex] = sub(source, currentPos) - end - end - return result - end -end - -local __TS__StringReplaceAll -do - local sub = string.sub - local find = string.find - function __TS__StringReplaceAll(source, searchValue, replaceValue) - if type(replaceValue) == "string" then - local concat = table.concat( - __TS__StringSplit(source, searchValue), - replaceValue - ) - if #searchValue == 0 then - return (replaceValue .. concat) .. replaceValue - end - return concat - end - local parts = {} - local partsIndex = 1 - if #searchValue == 0 then - parts[1] = replaceValue(nil, "", 0, source) - partsIndex = 2 - for i = 1, #source do - parts[partsIndex] = sub(source, i, i) - parts[partsIndex + 1] = replaceValue(nil, "", i, source) - partsIndex = partsIndex + 2 - end - else - local currentPos = 1 - while true do - local startPos, endPos = find(source, searchValue, currentPos, true) - if not startPos then - break - end - parts[partsIndex] = sub(source, currentPos, startPos - 1) - parts[partsIndex + 1] = replaceValue(nil, searchValue, startPos - 1, source) - partsIndex = partsIndex + 2 - currentPos = endPos + 1 - end - parts[partsIndex] = sub(source, currentPos) - end - return table.concat(parts) - end -end - -local function __TS__StringSlice(self, start, ____end) - if start == nil or start ~= start then - start = 0 - end - if ____end ~= ____end then - ____end = 0 - end - if start >= 0 then - start = start + 1 - end - if ____end ~= nil and ____end < 0 then - ____end = ____end - 1 - end - return string.sub(self, start, ____end) -end - -local function __TS__StringStartsWith(self, searchString, position) - if position == nil or position < 0 then - position = 0 - end - return string.sub(self, position + 1, #searchString + position) == searchString -end - -local function __TS__StringSubstr(self, from, length) - if from ~= from then - from = 0 - end - if length ~= nil then - if length ~= length or length <= 0 then - return "" - end - length = length + from - end - if from >= 0 then - from = from + 1 - end - return string.sub(self, from, length) -end - -local function __TS__StringTrim(self) - local result = string.gsub(self, "^[%s ]*(.-)[%s ]*$", "%1") - return result -end - -local function __TS__StringTrimEnd(self) - local result = string.gsub(self, "[%s ]*$", "") - return result -end - -local function __TS__StringTrimStart(self) - local result = string.gsub(self, "^[%s ]*", "") - return result -end - -local __TS__SymbolRegistryFor, __TS__SymbolRegistryKeyFor -do - local symbolRegistry = {} - function __TS__SymbolRegistryFor(key) - if not symbolRegistry[key] then - symbolRegistry[key] = __TS__Symbol(key) - end - return symbolRegistry[key] - end - function __TS__SymbolRegistryKeyFor(sym) - for key in pairs(symbolRegistry) do - if symbolRegistry[key] == sym then - return key - end - end - end -end - -local function __TS__TypeOf(value) - local luaType = type(value) - if luaType == "table" then - return "object" - elseif luaType == "nil" then - return "undefined" - else - return luaType - end -end - -return { - __TS__ArrayConcat = __TS__ArrayConcat, - __TS__ArrayEntries = __TS__ArrayEntries, - __TS__ArrayEvery = __TS__ArrayEvery, - __TS__ArrayFilter = __TS__ArrayFilter, - __TS__ArrayForEach = __TS__ArrayForEach, - __TS__ArrayFind = __TS__ArrayFind, - __TS__ArrayFindIndex = __TS__ArrayFindIndex, - __TS__ArrayFrom = __TS__ArrayFrom, - __TS__ArrayIncludes = __TS__ArrayIncludes, - __TS__ArrayIndexOf = __TS__ArrayIndexOf, - __TS__ArrayIsArray = __TS__ArrayIsArray, - __TS__ArrayJoin = __TS__ArrayJoin, - __TS__ArrayMap = __TS__ArrayMap, - __TS__ArrayPush = __TS__ArrayPush, - __TS__ArrayPushArray = __TS__ArrayPushArray, - __TS__ArrayReduce = __TS__ArrayReduce, - __TS__ArrayReduceRight = __TS__ArrayReduceRight, - __TS__ArrayReverse = __TS__ArrayReverse, - __TS__ArrayUnshift = __TS__ArrayUnshift, - __TS__ArraySort = __TS__ArraySort, - __TS__ArraySlice = __TS__ArraySlice, - __TS__ArraySome = __TS__ArraySome, - __TS__ArraySplice = __TS__ArraySplice, - __TS__ArrayToObject = __TS__ArrayToObject, - __TS__ArrayFlat = __TS__ArrayFlat, - __TS__ArrayFlatMap = __TS__ArrayFlatMap, - __TS__ArraySetLength = __TS__ArraySetLength, - __TS__AsyncAwaiter = __TS__AsyncAwaiter, - __TS__Await = __TS__Await, - __TS__Class = __TS__Class, - __TS__ClassExtends = __TS__ClassExtends, - __TS__CloneDescriptor = __TS__CloneDescriptor, - __TS__CountVarargs = __TS__CountVarargs, - __TS__Decorate = __TS__Decorate, - __TS__DecorateParam = __TS__DecorateParam, - __TS__Delete = __TS__Delete, - __TS__DelegatedYield = __TS__DelegatedYield, - Error = Error, - RangeError = RangeError, - ReferenceError = ReferenceError, - SyntaxError = SyntaxError, - TypeError = TypeError, - URIError = URIError, - __TS__FunctionBind = __TS__FunctionBind, - __TS__Generator = __TS__Generator, - __TS__InstanceOf = __TS__InstanceOf, - __TS__InstanceOfObject = __TS__InstanceOfObject, - __TS__Iterator = __TS__Iterator, - __TS__LuaIteratorSpread = __TS__LuaIteratorSpread, - Map = Map, - __TS__Match = __TS__Match, - __TS__MathAtan2 = __TS__MathAtan2, - __TS__MathModf = __TS__MathModf, - __TS__MathSign = __TS__MathSign, - __TS__New = __TS__New, - __TS__Number = __TS__Number, - __TS__NumberIsFinite = __TS__NumberIsFinite, - __TS__NumberIsNaN = __TS__NumberIsNaN, - __TS__NumberToString = __TS__NumberToString, - __TS__ObjectAssign = __TS__ObjectAssign, - __TS__ObjectDefineProperty = __TS__ObjectDefineProperty, - __TS__ObjectEntries = __TS__ObjectEntries, - __TS__ObjectFromEntries = __TS__ObjectFromEntries, - __TS__ObjectGetOwnPropertyDescriptor = __TS__ObjectGetOwnPropertyDescriptor, - __TS__ObjectGetOwnPropertyDescriptors = __TS__ObjectGetOwnPropertyDescriptors, - __TS__ObjectKeys = __TS__ObjectKeys, - __TS__ObjectRest = __TS__ObjectRest, - __TS__ObjectValues = __TS__ObjectValues, - __TS__ParseFloat = __TS__ParseFloat, - __TS__ParseInt = __TS__ParseInt, - __TS__Promise = __TS__Promise, - __TS__PromiseAll = __TS__PromiseAll, - __TS__PromiseAllSettled = __TS__PromiseAllSettled, - __TS__PromiseAny = __TS__PromiseAny, - __TS__PromiseRace = __TS__PromiseRace, - Set = Set, - __TS__SetDescriptor = __TS__SetDescriptor, - __TS__SparseArrayNew = __TS__SparseArrayNew, - __TS__SparseArrayPush = __TS__SparseArrayPush, - __TS__SparseArraySpread = __TS__SparseArraySpread, - WeakMap = WeakMap, - WeakSet = WeakSet, - __TS__SourceMapTraceBack = __TS__SourceMapTraceBack, - __TS__Spread = __TS__Spread, - __TS__StringAccess = __TS__StringAccess, - __TS__StringCharAt = __TS__StringCharAt, - __TS__StringCharCodeAt = __TS__StringCharCodeAt, - __TS__StringEndsWith = __TS__StringEndsWith, - __TS__StringIncludes = __TS__StringIncludes, - __TS__StringPadEnd = __TS__StringPadEnd, - __TS__StringPadStart = __TS__StringPadStart, - __TS__StringReplace = __TS__StringReplace, - __TS__StringReplaceAll = __TS__StringReplaceAll, - __TS__StringSlice = __TS__StringSlice, - __TS__StringSplit = __TS__StringSplit, - __TS__StringStartsWith = __TS__StringStartsWith, - __TS__StringSubstr = __TS__StringSubstr, - __TS__StringSubstring = __TS__StringSubstring, - __TS__StringTrim = __TS__StringTrim, - __TS__StringTrimEnd = __TS__StringTrimEnd, - __TS__StringTrimStart = __TS__StringTrimStart, - __TS__Symbol = __TS__Symbol, - Symbol = Symbol, - __TS__SymbolRegistryFor = __TS__SymbolRegistryFor, - __TS__SymbolRegistryKeyFor = __TS__SymbolRegistryKeyFor, - __TS__TypeOf = __TS__TypeOf, - __TS__Unpack = __TS__Unpack -} diff --git a/modules/events-mod/src/generated/lua/main/commands/kafkatorioCommands.lua b/modules/events-mod/src/generated/lua/main/commands/kafkatorioCommands.lua deleted file mode 100644 index 2608d96..0000000 --- a/modules/events-mod/src/generated/lua/main/commands/kafkatorioCommands.lua +++ /dev/null @@ -1,76 +0,0 @@ -local ____lualib = require("lualib_bundle") -local __TS__StringStartsWith = ____lualib.__TS__StringStartsWith -local __TS__StringSplit = ____lualib.__TS__StringSplit -local __TS__ParseInt = ____lualib.__TS__ParseInt -local ____exports = {} -local ____global_2Dinit = require("main.global-init") -local initGlobal = ____global_2Dinit.initGlobal -local ____prototypeUpdates = require("main.events.prototypeUpdates") -local emitPrototypes = ____prototypeUpdates.emitPrototypes -local ____EventDataQueue = require("main.emitting.EventDataQueue") -local EventDataQueue = ____EventDataQueue.default -commands.add_command( - "kafkatorio", - "kafkatorio innit bruv", - function(e) - local ____temp_0 - if e.player_index ~= nil then - ____temp_0 = game.get_player(e.player_index) - else - ____temp_0 = nil - end - local player = ____temp_0 - if e.parameter == nil then - if player ~= nil then - player.print("no parameter") - end - else - local paramUppercase = string.upper(e.parameter) - if "PROTOTYPES" == paramUppercase then - emitPrototypes() - elseif __TS__StringStartsWith(paramUppercase, "CHUNKS") then - local ____paramUppercase_split_result__1_1 = __TS__StringSplit(paramUppercase, " ") - if ____paramUppercase_split_result__1_1 ~= nil then - ____paramUppercase_split_result__1_1 = ____paramUppercase_split_result__1_1[2] - end - local size = ____paramUppercase_split_result__1_1 or nil - local radius = size ~= nil and __TS__ParseInt(size) or 1 - if e.player_index ~= nil then - local player = game.players[e.player_index] - local chunkPosition = { - x = math.floor(player.position.x / 32), - y = math.floor(player.position.y / 32) - } - local chunkXMin = chunkPosition.x - radius - local chunkXMax = chunkPosition.x + radius - local chunkYMin = chunkPosition.y - radius - local chunkYMax = chunkPosition.y + radius - local chunkCount = 0 - for ____, surface in pairs(game.surfaces) do - for chunk in surface.get_chunks() do - if chunk.x >= chunkXMin and chunk.x <= chunkXMax and (chunk.y >= chunkYMin and chunk.y <= chunkYMax) then - local data = { - name = defines.events.on_chunk_generated, - position = {x = chunk.x, y = chunk.y}, - area = chunk.area, - surface = surface, - tick = e.tick - } - EventDataQueue:enqueue( - (tostring(surface.index) .. tostring(chunk.x)) .. tostring(chunk.y), - data, - 50 - ) - chunkCount = chunkCount + 1 - end - end - end - player.print(((((((((("enqueued " .. tostring(chunkCount)) .. " chunks from [x:") .. tostring(chunkXMin)) .. ", y:") .. tostring(chunkYMin)) .. "] to [x:") .. tostring(chunkXMax)) .. ", y:") .. tostring(chunkYMax)) .. "]") - end - elseif __TS__StringStartsWith(paramUppercase, "INIT_GLOBAL") then - initGlobal(__TS__StringStartsWith(paramUppercase, "INIT_GLOBAL FORCE")) - end - end - end -) -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/emitting/EventDataCache.lua b/modules/events-mod/src/generated/lua/main/emitting/EventDataCache.lua deleted file mode 100644 index 7d4b9be..0000000 --- a/modules/events-mod/src/generated/lua/main/emitting/EventDataCache.lua +++ /dev/null @@ -1,141 +0,0 @@ -local ____lualib = require("lualib_bundle") -local __TS__Class = ____lualib.__TS__Class -local __TS__New = ____lualib.__TS__New -local ____exports = {} -local CacheEntry -local ____KafkatorioSettings = require("main.settings.KafkatorioSettings") -local KafkatorioSettings = ____KafkatorioSettings.default -local ____PacketEmitter = require("main.emitting.PacketEmitter") -local PacketEmitter = ____PacketEmitter.default -____exports.EventUpdatesManager = __TS__Class() -local EventUpdatesManager = ____exports.EventUpdatesManager -EventUpdatesManager.name = "EventUpdatesManager" -function EventUpdatesManager.prototype.____constructor(self) - self:init() -end -function EventUpdatesManager.prototype.init(self, force) - local isAnythingUndefined = global.eventUpdatesManagerCache == nil - log(((("Initialising EventDataCache (force=" .. tostring(force)) .. ", isAnythingUndefined=") .. tostring(isAnythingUndefined)) .. ")...") - if force == true or isAnythingUndefined then - log("Initialising global.cache") - global.eventUpdatesManagerCache = {} - end - log("Finished initialising EventDataCache") -end -function EventUpdatesManager.prototype.throttle(self, key, ____type, mutate, expirationDurationTicks) - self:update( - key, - ____type, - mutate, - false, - expirationDurationTicks - ) -end -function EventUpdatesManager.prototype.debounce(self, key, ____type, mutate, expirationDurationTicks) - self:update( - key, - ____type, - mutate, - true, - expirationDurationTicks - ) -end -function EventUpdatesManager.prototype.update(self, key, ____type, mutate, resetLastUpdated, expirationDurationTicks) - local entry = self:getCacheEntry(key, ____type) or ____exports.EventUpdatesManager:createCacheEntry(key, ____type) - mutate(entry.packet) - if resetLastUpdated then - entry.lastUpdatedTick = game.tick - end - if expirationDurationTicks ~= nil then - entry.expirationDurationTicks = expirationDurationTicks - end - if entry.expirationDurationTicks ~= nil and entry.expirationDurationTicks <= 0 then - self:extractAndEmitExpiredPackets() - end -end -function EventUpdatesManager.prototype.setExpiration(self, key, ____type, expirationDurationTicks) - local entry = self:getCacheEntry(key, ____type) - if entry ~= nil then - entry.expirationDurationTicks = expirationDurationTicks - end -end -function EventUpdatesManager.prototype.extractExpired(self) - local countExpired = 0 - local countTotal = 0 - local expiredData = {} - for key, entry in pairs(global.eventUpdatesManagerCache) do - countTotal = countTotal + 1 - if self:isExpired(entry) then - countExpired = countExpired + 1 - expiredData[#expiredData + 1] = entry.packet - global.eventUpdatesManagerCache[key] = nil - end - end - local hasExpiredItems = countExpired > 0 - local hasAnyItem = countTotal > 0 - if hasExpiredItems or game.tick % 30 == 0 and hasAnyItem then - log((("[extractExpired] expired items: " .. tostring(countExpired)) .. ", total: ") .. tostring(countTotal)) - end - return expiredData -end -function EventUpdatesManager.prototype.extractAndEmitExpiredPackets(self) - local cachedEvents = self:extractExpired() - if #cachedEvents > 0 then - log((("[EventDataCache] emitting " .. tostring(#cachedEvents)) .. " events on tick ") .. tostring(game.tick)) - for ____, event in ipairs(cachedEvents) do - PacketEmitter:emitKeyedPacket(event) - end - end - return #cachedEvents -end -function EventUpdatesManager.prototype.getCacheEntry(self, key, ____type) - local hash = ____exports.EventUpdatesManager:hashKey(key) - if not (global.eventUpdatesManagerCache[hash] ~= nil) then - return nil - end - local value = global.eventUpdatesManagerCache[hash] - if self:isEntryInstanceOf(value, ____type) then - return value - else - return nil - end -end -function EventUpdatesManager.createCacheEntry(self, key, ____type) - local data = {type = ____type, key = key} - local entry = __TS__New(CacheEntry, data) - local hash = ____exports.EventUpdatesManager:hashKey(key) - global.eventUpdatesManagerCache[hash] = entry - return entry -end -function EventUpdatesManager.prototype.isExpired(self, entry) - local expiryDuration = entry.expirationDurationTicks or KafkatorioSettings:getEventCacheExpirationTicks(entry.packet) - if expiryDuration == nil then - return true - else - return game.tick - entry.lastUpdatedTick > expiryDuration - end -end -function EventUpdatesManager.prototype.isEntryInstanceOf(self, entry, ____type) - local ____self_isDataInstanceOf_2 = self.isDataInstanceOf - local ____entry_packet_0 = entry - if ____entry_packet_0 ~= nil then - ____entry_packet_0 = ____entry_packet_0.packet - end - return ____self_isDataInstanceOf_2(self, ____entry_packet_0, ____type) -end -function EventUpdatesManager.prototype.isDataInstanceOf(self, packet, ____type) - return packet ~= nil and packet.type == ____type -end -function EventUpdatesManager.hashKey(self, key) - return game.encode_string(game.table_to_json(key)) -end -local EventUpdates = __TS__New(____exports.EventUpdatesManager) -____exports.default = EventUpdates -CacheEntry = __TS__Class() -CacheEntry.name = "CacheEntry" -function CacheEntry.prototype.____constructor(self, packet, expirationDurationTicks) - self.lastUpdatedTick = game.tick - self.packet = packet - self.expirationDurationTicks = expirationDurationTicks -end -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/emitting/EventDataQueue.lua b/modules/events-mod/src/generated/lua/main/emitting/EventDataQueue.lua deleted file mode 100644 index a8da3b8..0000000 --- a/modules/events-mod/src/generated/lua/main/emitting/EventDataQueue.lua +++ /dev/null @@ -1,87 +0,0 @@ -local ____lualib = require("lualib_bundle") -local __TS__Class = ____lualib.__TS__Class -local __TS__New = ____lualib.__TS__New -local ____exports = {} -local Node -____exports.EventDataQueueManager = __TS__Class() -local EventDataQueueManager = ____exports.EventDataQueueManager -EventDataQueueManager.name = "EventDataQueueManager" -function EventDataQueueManager.prototype.____constructor(self) -end -function EventDataQueueManager.init(self, force) - local isAnythingUndefined = global.store == nil or global.size == nil or global.head == nil or global.tail == nil - log(((("Initialising EventDataQueueManager globals (force=" .. tostring(force)) .. ", isAnythingUndefined=") .. tostring(isAnythingUndefined)) .. ")") - if force == true or isAnythingUndefined then - global.store = {} - global.head = nil - global.tail = nil - global.size = 0 - end - log("Finished initialising EventDataQueueManager") -end -function EventDataQueueManager.prototype.size(self) - return global.size -end -function EventDataQueueManager.prototype.enqueue(self, key, event, weight) - if weight == nil then - weight = 1 - end - if global.store[key] ~= nil then - local node = __TS__New(Node, key, weight) - if global.head == nil then - global.head = node - end - if global.tail ~= nil then - global.tail.next = node - end - global.tail = node - global.size = global.size + 1 - end - global.store[key] = event -end -function EventDataQueueManager.prototype.dequeue(self) - if global.head == nil then - return nil - else - local weight = global.head.weight - local storeKey = global.head.storeKey - global.head = global.head.next - global.size = global.size - 1 - local storedPacket = global.store[storeKey] - global.store[storeKey] = nil - if storedPacket == nil then - return nil - else - return {value = storedPacket, weight = weight} - end - end -end -function EventDataQueueManager.prototype.dequeueValues(self, targetWeight) - if targetWeight == nil then - targetWeight = 50 - end - local values = {} - local weight = 0 - repeat - do - local packet = self:dequeue() - if packet == nil then - break - else - weight = weight + packet.weight - values[#values + 1] = packet.value - end - end - until not (weight <= targetWeight) - return values -end -local EventDataQueue = __TS__New(____exports.EventDataQueueManager) -____exports.default = EventDataQueue -Node = __TS__Class() -Node.name = "Node" -function Node.prototype.____constructor(self, storeKey, weight) - self.next = nil - self.storeKey = storeKey - self.weight = weight -end -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/emitting/KafkatorioPacketQueue.lua b/modules/events-mod/src/generated/lua/main/emitting/KafkatorioPacketQueue.lua deleted file mode 100644 index 972b662..0000000 --- a/modules/events-mod/src/generated/lua/main/emitting/KafkatorioPacketQueue.lua +++ /dev/null @@ -1,48 +0,0 @@ -local ____lualib = require("lualib_bundle") -local __TS__Class = ____lualib.__TS__Class -local __TS__SetDescriptor = ____lualib.__TS__SetDescriptor -local __TS__New = ____lualib.__TS__New -local ____exports = {} ---- Simple ordered queue for {@link KafkatorioPacketData}. --- --- Implemented so printing multiple packets won't flood the output log, causing messages to be --- missed or garbled. -____exports.KafkatorioPacketQueueManager = __TS__Class() -local KafkatorioPacketQueueManager = ____exports.KafkatorioPacketQueueManager -KafkatorioPacketQueueManager.name = "KafkatorioPacketQueueManager" -function KafkatorioPacketQueueManager.prototype.____constructor(self) - self.size = 0 - self.first = nil - self.last = nil -end -__TS__SetDescriptor( - KafkatorioPacketQueueManager.prototype, - "length", - {get = function(self) - return self.size - end}, - true -) -function KafkatorioPacketQueueManager.prototype.enqueue(self, packet) - local last = self.last - self.last = {value = packet} - if last ~= nil then - last.next = self.last - end - if self.first == nil then - self.first = self.last - end - self.size = self.size + 1 -end -function KafkatorioPacketQueueManager.prototype.dequeue(self) - local first = self.first - if first == nil then - return nil - end - self.first = first.next or nil - self.size = self.size - 1 - return first.value -end -local KafkatorioPacketQueue = __TS__New(____exports.KafkatorioPacketQueueManager) -____exports.default = KafkatorioPacketQueue -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua b/modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua deleted file mode 100644 index 2ec7a8b..0000000 --- a/modules/events-mod/src/generated/lua/main/emitting/PacketEmitter.lua +++ /dev/null @@ -1,33 +0,0 @@ -local ____lualib = require("lualib_bundle") -local __TS__Class = ____lualib.__TS__Class -local __TS__StringTrim = ____lualib.__TS__StringTrim -local __TS__New = ____lualib.__TS__New -local ____exports = {} -____exports.KafkatorioPacketEmitter = __TS__Class() -local KafkatorioPacketEmitter = ____exports.KafkatorioPacketEmitter -KafkatorioPacketEmitter.name = "KafkatorioPacketEmitter" -function KafkatorioPacketEmitter.prototype.____constructor(self) -end -function KafkatorioPacketEmitter.prototype.emitInstantPacket(self, data) - ____exports.KafkatorioPacketEmitter:emitPacket({data = data, modVersion = global.MOD_VERSION, tick = game.tick}) -end -function KafkatorioPacketEmitter.prototype.emitKeyedPacket(self, data) - ____exports.KafkatorioPacketEmitter:emitPacket({data = data, modVersion = global.MOD_VERSION, tick = game.tick}) -end -function KafkatorioPacketEmitter.emitPacket(self, packet) - local data = game.table_to_json(packet) - if #__TS__StringTrim(data) <= 0 then - print("[error] table_to_json returned empty string for packet:" .. tostring(packet)) - return - end - local encodedData = game.encode_string(data) - if encodedData == nil or #__TS__StringTrim(encodedData) <= 0 then - print("[error] could not encode packet") - print("KafkatorioPacket:::" .. data) - else - print("KafkatorioPacket:::encoded:" .. encodedData) - end -end -local PacketEmitter = __TS__New(____exports.KafkatorioPacketEmitter) -____exports.default = PacketEmitter -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/configurationUpdate.lua b/modules/events-mod/src/generated/lua/main/events/configurationUpdate.lua deleted file mode 100644 index 6560c95..0000000 --- a/modules/events-mod/src/generated/lua/main/events/configurationUpdate.lua +++ /dev/null @@ -1,13 +0,0 @@ -local ____exports = {} -local ____global_2Dinit = require("main.global-init") -local initGlobal = ____global_2Dinit.initGlobal -local ____prototypeUpdates = require("main.events.prototypeUpdates") -local emitPrototypes = ____prototypeUpdates.emitPrototypes -local ____ConfigurationUpdateHandler = require("main.events.handlers.ConfigurationUpdateHandler") -local ConfigurationUpdates = ____ConfigurationUpdateHandler.default -script.on_configuration_changed(function(data) - initGlobal(true) - ConfigurationUpdates:emitConfigurationUpdate(data) - emitPrototypes() -end) -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/consoleUpdates.lua b/modules/events-mod/src/generated/lua/main/events/consoleUpdates.lua deleted file mode 100644 index b764aa4..0000000 --- a/modules/events-mod/src/generated/lua/main/events/consoleUpdates.lua +++ /dev/null @@ -1,20 +0,0 @@ -local ____exports = {} -local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") -local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData -local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue") -local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default -script.on_event( - defines.events.on_console_chat, - function(event) - local update = {type = KafkatorioPacketData.Type.ConsoleChatUpdate, authorPlayerIndex = event.player_index or nil, content = event.message} - KafkatorioPacketQueue:enqueue(update) - end -) -script.on_event( - defines.events.on_console_command, - function(event) - local update = {type = KafkatorioPacketData.Type.ConsoleCommandUpdate, authorPlayerIndex = event.player_index or nil, command = event.command, parameters = event.parameters} - KafkatorioPacketQueue:enqueue(update) - end -) -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/converters.lua b/modules/events-mod/src/generated/lua/main/events/converters.lua deleted file mode 100644 index a279047..0000000 --- a/modules/events-mod/src/generated/lua/main/events/converters.lua +++ /dev/null @@ -1,162 +0,0 @@ -local ____exports = {} -local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") -local ChunkSize = ____kafkatorio_2Dschema.ChunkSize -local FactorioEntityStatus = ____kafkatorio_2Dschema.FactorioEntityStatus -local MinedProduct = ____kafkatorio_2Dschema.MinedProduct -____exports.Converters = {} -local Converters = ____exports.Converters -do - local EntityStatusRecord - function Converters.prototypeId(____type, name) - return (____type .. "/") .. name - end - local floor = math.floor - local mapEventIdToName = {} - for eventName, eventId in pairs(defines.events) do - mapEventIdToName[eventId] = eventName - end - function Converters.eventNameString(event) - return mapEventIdToName[event] - end - function Converters.mapColour(color) - return {color.r or 0, color.g or 0, color.b or 0, color.a or 0} - end - function Converters.convertPlacedTiles(placedTile, oldTiles) - local converted = {} - for ____, tile in ipairs(oldTiles) do - converted[#converted + 1] = {position = {x = tile.position.x, y = tile.position.y}, name = placedTile.name} - end - return converted - end - function Converters.convertRemovedTiles(surface, oldTiles) - local converted = {} - for ____, tile in ipairs(oldTiles) do - converted[#converted + 1] = surface.get_tile(tile.position.x, tile.position.y) - end - return converted - end - function Converters.convertCollisionMaskToNames(cm) - local masks = {} - for name in pairs(cm) do - masks[#masks + 1] = name - end - return masks - end - local function convertEntityStatus(status) - if status == nil then - return nil - else - return EntityStatusRecord[status] - end - end - function Converters.prototypeIdEntity(entity) - return Converters.prototypeId(entity.type, entity.name) - end - function Converters.tilePositionToChunkPosition(mapPosition) - return { - floor(mapPosition.x / 32), - floor(mapPosition.y / 32), - ChunkSize.CHUNK_032 - } - end - function Converters.mapPositionToChunkPosition(mapPosition) - return { - floor(mapPosition.x / 32), - floor(mapPosition.y / 32), - ChunkSize.CHUNK_032 - } - end - function Converters.entityPosition(position) - return {position.x, position.y} - end - function Converters.chunkPosition(position) - return {position.x, position.y, ChunkSize.CHUNK_032} - end - function Converters.entityStatus(status) - if status == nil then - return nil - else - return EntityStatusRecord[status] - end - end - function Converters.miningProperties(properties) - local products = {} - if properties.products ~= nil then - for ____, product in ipairs(properties.products) do - if product.type == "fluid" then - products[#products + 1] = { - type = MinedProduct.Type.MinedProductFluid, - amount = product.amount, - resultProtoId = ____exports.Converters.prototypeId(product.type, product.name) - } - end - if product.type == "item" then - products[#products + 1] = { - type = MinedProduct.Type.MinedProductItem, - amount = product.amount, - resultProtoId = ____exports.Converters.prototypeId(product.type, product.name) - } - end - end - end - return {canBeMined = properties.minable, products = products} - end - function Converters.playerOnlineInfo(player, data) - data.lastOnline = player.last_online - data.onlineTime = player.online_time - data.afkTime = player.afk_time - data.isConnected = player.connected - end - function Converters.collisionBox(collision_box) - return { - leftTop = ____exports.Converters.entityPosition(collision_box.left_top), - rightBottom = ____exports.Converters.entityPosition(collision_box.right_bottom) - } - end - EntityStatusRecord = { - [defines.entity_status.cant_divide_segments] = FactorioEntityStatus.CANT_DIVIDE_SEGMENTS, - [defines.entity_status.charging] = FactorioEntityStatus.CHARGING, - [defines.entity_status.closed_by_circuit_network] = FactorioEntityStatus.CLOSED_BY_CIRCUIT_NETWORK, - [defines.entity_status.disabled] = FactorioEntityStatus.DISABLED, - [defines.entity_status.disabled_by_control_behavior] = FactorioEntityStatus.DISABLED_BY_CONTROL_BEHAVIOR, - [defines.entity_status.disabled_by_script] = FactorioEntityStatus.DISABLED_BY_SCRIPT, - [defines.entity_status.discharging] = FactorioEntityStatus.DISCHARGING, - [defines.entity_status.fluid_ingredient_shortage] = FactorioEntityStatus.FLUID_INGREDIENT_SHORTAGE, - [defines.entity_status.fully_charged] = FactorioEntityStatus.FULLY_CHARGED, - [defines.entity_status.full_output] = FactorioEntityStatus.FULL_OUTPUT, - [defines.entity_status.item_ingredient_shortage] = FactorioEntityStatus.ITEM_INGREDIENT_SHORTAGE, - [defines.entity_status.launching_rocket] = FactorioEntityStatus.LAUNCHING_ROCKET, - [defines.entity_status.low_input_fluid] = FactorioEntityStatus.LOW_INPUT_FLUID, - [defines.entity_status.low_power] = FactorioEntityStatus.LOW_POWER, - [defines.entity_status.low_temperature] = FactorioEntityStatus.LOW_TEMPERATURE, - [defines.entity_status.marked_for_deconstruction] = FactorioEntityStatus.MARKED_FOR_DECONSTRUCTION, - [defines.entity_status.missing_required_fluid] = FactorioEntityStatus.MISSING_REQUIRED_FLUID, - [defines.entity_status.missing_science_packs] = FactorioEntityStatus.MISSING_SCIENCE_PACKS, - [defines.entity_status.networks_connected] = FactorioEntityStatus.NETWORKS_CONNECTED, - [defines.entity_status.networks_disconnected] = FactorioEntityStatus.NETWORKS_DISCONNECTED, - [defines.entity_status.normal] = FactorioEntityStatus.NORMAL, - [defines.entity_status.not_connected_to_rail] = FactorioEntityStatus.NOT_CONNECTED_TO_RAIL, - [defines.entity_status.not_plugged_in_electric_network] = FactorioEntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK, - [defines.entity_status.no_ammo] = FactorioEntityStatus.NO_AMMO, - [defines.entity_status.no_fuel] = FactorioEntityStatus.NO_FUEL, - [defines.entity_status.no_ingredients] = FactorioEntityStatus.NO_INGREDIENTS, - [defines.entity_status.no_input_fluid] = FactorioEntityStatus.NO_INPUT_FLUID, - [defines.entity_status.no_minable_resources] = FactorioEntityStatus.NO_MINABLE_RESOURCES, - [defines.entity_status.no_modules_to_transmit] = FactorioEntityStatus.NO_MODULES_TO_TRANSMIT, - [defines.entity_status.no_power] = FactorioEntityStatus.NO_POWER, - [defines.entity_status.no_recipe] = FactorioEntityStatus.NO_RECIPE, - [defines.entity_status.no_research_in_progress] = FactorioEntityStatus.NO_RESEARCH_IN_PROGRESS, - [defines.entity_status.opened_by_circuit_network] = FactorioEntityStatus.OPENED_BY_CIRCUIT_NETWORK, - [defines.entity_status.out_of_logistic_network] = FactorioEntityStatus.OUT_OF_LOGISTIC_NETWORK, - [defines.entity_status.preparing_rocket_for_launch] = FactorioEntityStatus.PREPARING_ROCKET_FOR_LAUNCH, - [defines.entity_status.recharging_after_power_outage] = FactorioEntityStatus.RECHARGING_AFTER_POWER_OUTAGE, - [defines.entity_status.turned_off_during_daytime] = FactorioEntityStatus.TURNED_OFF_DURING_DAYTIME, - [defines.entity_status.waiting_for_source_items] = FactorioEntityStatus.WAITING_FOR_SOURCE_ITEMS, - [defines.entity_status.waiting_for_space_in_destination] = FactorioEntityStatus.WAITING_FOR_SPACE_IN_DESTINATION, - [defines.entity_status.waiting_for_target_to_be_built] = FactorioEntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT, - [defines.entity_status.waiting_for_train] = FactorioEntityStatus.WAITING_FOR_TRAIN, - [defines.entity_status.waiting_to_launch_rocket] = FactorioEntityStatus.WAITING_TO_LAUNCH_ROCKET, - [defines.entity_status.working] = FactorioEntityStatus.WORKING - } -end -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/entityUpdates.lua b/modules/events-mod/src/generated/lua/main/events/entityUpdates.lua deleted file mode 100644 index 6f4d323..0000000 --- a/modules/events-mod/src/generated/lua/main/events/entityUpdates.lua +++ /dev/null @@ -1,32 +0,0 @@ -local ____exports = {} -local ____EntityUpdateHandler = require("main.events.handlers.EntityUpdateHandler") -local EntityUpdates = ____EntityUpdateHandler.default -script.on_event( - defines.events.on_built_entity, - function(e) - log("on_built_entity " .. tostring(e.tick)) - EntityUpdates:handleBuiltEntityEvent(e) - end -) -script.on_event( - defines.events.on_robot_built_entity, - function(e) - log("on_robot_built_entity " .. tostring(e.tick)) - EntityUpdates:handleBuiltEntityEvent(e) - end -) -script.on_event( - defines.events.on_player_mined_entity, - function(e) - log("on_player_mined_entity " .. tostring(e.tick)) - EntityUpdates:handleMinedEntityEvent(e) - end -) -script.on_event( - defines.events.on_robot_mined_entity, - function(e) - log("on_robot_mined_entity " .. tostring(e.tick)) - EntityUpdates:handleMinedEntityEvent(e) - end -) -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/eventTypeCheck.lua b/modules/events-mod/src/generated/lua/main/events/eventTypeCheck.lua deleted file mode 100644 index d9cb883..0000000 --- a/modules/events-mod/src/generated/lua/main/events/eventTypeCheck.lua +++ /dev/null @@ -1,6 +0,0 @@ -local ____exports = {} -function ____exports.isEventType(eventData, ____type) - local id = eventData.name - return id == ____type -end -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/handlers/ConfigurationUpdateHandler.lua b/modules/events-mod/src/generated/lua/main/events/handlers/ConfigurationUpdateHandler.lua deleted file mode 100644 index 7463e91..0000000 --- a/modules/events-mod/src/generated/lua/main/events/handlers/ConfigurationUpdateHandler.lua +++ /dev/null @@ -1,62 +0,0 @@ -local ____lualib = require("lualib_bundle") -local __TS__Class = ____lualib.__TS__Class -local __TS__ObjectKeys = ____lualib.__TS__ObjectKeys -local __TS__ArrayConcat = ____lualib.__TS__ArrayConcat -local Set = ____lualib.Set -local __TS__New = ____lualib.__TS__New -local __TS__Spread = ____lualib.__TS__Spread -local __TS__ArrayMap = ____lualib.__TS__ArrayMap -local ____exports = {} -local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") -local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData -local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue") -local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default -____exports.ConfigurationUpdateHandler = __TS__Class() -local ConfigurationUpdateHandler = ____exports.ConfigurationUpdateHandler -ConfigurationUpdateHandler.name = "ConfigurationUpdateHandler" -function ConfigurationUpdateHandler.prototype.____constructor(self) -end -function ConfigurationUpdateHandler.prototype.emitConfigurationUpdate(self, changeData) - local configUpdateData = { - type = KafkatorioPacketData.Type.ConfigurationUpdate, - migrationApplied = changeData.migration_applied, - modStartupSettingsChange = changeData.mod_startup_settings_changed, - allMods = ____exports.ConfigurationUpdateHandler:allMods(changeData), - factorioData = ____exports.ConfigurationUpdateHandler:factorioData(changeData) - } - KafkatorioPacketQueue:enqueue(configUpdateData) -end -function ConfigurationUpdateHandler.factorioData(self, changeData) - return {oldVersion = changeData.old_version or nil, newVersion = changeData.new_version or nil} -end -function ConfigurationUpdateHandler.allMods(self, e) - local namesOfChangedMods = __TS__ObjectKeys(e.mod_changes) - local namesOfCurrentMods = __TS__ObjectKeys(script.active_mods) - local modNames = {__TS__Spread(__TS__New( - Set, - __TS__ArrayConcat(namesOfChangedMods, namesOfCurrentMods) - ))} - return __TS__ArrayMap( - modNames, - function(____, modName) - local ____script_active_mods_modName_2 = script.active_mods[modName] - if ____script_active_mods_modName_2 == nil then - local ____e_mod_changes_modName_new_version_0 = e.mod_changes[modName] - if ____e_mod_changes_modName_new_version_0 ~= nil then - ____e_mod_changes_modName_new_version_0 = ____e_mod_changes_modName_new_version_0.new_version - end - ____script_active_mods_modName_2 = ____e_mod_changes_modName_new_version_0 - end - local currentVer = ____script_active_mods_modName_2 or nil - local ____e_mod_changes_modName_old_version_3 = e.mod_changes[modName] - if ____e_mod_changes_modName_old_version_3 ~= nil then - ____e_mod_changes_modName_old_version_3 = ____e_mod_changes_modName_old_version_3.old_version - end - local previousVer = ____e_mod_changes_modName_old_version_3 or nil - return {modName = modName, currentVersion = currentVer, previousVersion = previousVer} - end - ) -end -local ConfigurationUpdates = __TS__New(____exports.ConfigurationUpdateHandler) -____exports.default = ConfigurationUpdates -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua b/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua deleted file mode 100644 index 6f852ca..0000000 --- a/modules/events-mod/src/generated/lua/main/events/handlers/EntityUpdateHandler.lua +++ /dev/null @@ -1,176 +0,0 @@ -local ____lualib = require("lualib_bundle") -local __TS__Class = ____lualib.__TS__Class -local __TS__New = ____lualib.__TS__New -local ____exports = {} -local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") -local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData -local ____converters = require("main.events.converters") -local Converters = ____converters.Converters -local ____EventDataCache = require("main.emitting.EventDataCache") -local EventDataCache = ____EventDataCache.default -____exports.EntityUpdatesHandler = __TS__Class() -local EntityUpdatesHandler = ____exports.EntityUpdatesHandler -EntityUpdatesHandler.name = "EntityUpdatesHandler" -function EntityUpdatesHandler.prototype.____constructor(self) -end -function EntityUpdatesHandler.prototype.handleMinedTileEvent(self, event) - local surface = game.get_surface(event.surface_index) - if surface == nil then - return - end - local tilesByChunk = {} - for ____, tile in ipairs(event.tiles) do - local chunkPosition = Converters.tilePositionToChunkPosition(tile.position) - if not (tilesByChunk[chunkPosition] ~= nil) then - tilesByChunk[chunkPosition] = {} - end - local tiles = tilesByChunk[chunkPosition] - tiles[#tiles + 1] = tile - tilesByChunk[chunkPosition] = tiles - end - for chunkPos, tiles in pairs(tilesByChunk) do - local entities = {} - for ____, tile in ipairs(tiles) do - local tileEntities = ____exports.EntityUpdatesHandler:getTileResourceEntities(surface, tile.position) - for ____, resource in ipairs(tileEntities) do - entities[#entities + 1] = resource - end - end - ____exports.EntityUpdatesHandler:throttleResourcesUpdate( - Converters.eventNameString(event.name), - event.tick, - event.surface_index, - chunkPos, - entities - ) - end -end -function EntityUpdatesHandler.prototype.handleMinedEntityEvent(self, event) - ____exports.EntityUpdatesHandler:throttleEntityUpdate(event, event.entity) -end -function EntityUpdatesHandler.prototype.handleBuiltEntityEvent(self, event) - ____exports.EntityUpdatesHandler:throttleEntityUpdate(event, event.created_entity) -end -function EntityUpdatesHandler.prototype.handleChunkGeneratedEvent(self, event) - local entities = ____exports.EntityUpdatesHandler:getAreaResourceEntities(event.surface, event.area) - ____exports.EntityUpdatesHandler:throttleResourcesUpdate( - Converters.eventNameString(event.name), - event.tick, - event.surface.index, - Converters.chunkPosition(event.position), - entities - ) -end -function EntityUpdatesHandler.throttleEntityUpdate(self, event, entity) - if entity.unit_number == nil then - return - end - local eventName = Converters.eventNameString(event.name) - local entityUpdateKey = { - protoId = Converters.prototypeIdEntity(entity), - surfaceIndex = entity.surface.index, - chunkPosition = Converters.mapPositionToChunkPosition(entity.position) - } - local ____entity_unit_number_2 = entity.unit_number - local ____entity_graphics_variation_3 = entity.graphics_variation - local ____entity_health_4 = entity.health - local ____entity_active_5 = entity.active - local ____entity_rotatable_6 = entity.rotatable - local ____entity_last_user_index_0 = entity.last_user - if ____entity_last_user_index_0 ~= nil then - ____entity_last_user_index_0 = ____entity_last_user_index_0.index - end - local entityUpdate = { - unitNumber = ____entity_unit_number_2, - graphicsVariation = ____entity_graphics_variation_3, - health = ____entity_health_4, - isActive = ____entity_active_5, - isRotatable = ____entity_rotatable_6, - lastUser = ____entity_last_user_index_0, - status = Converters.entityStatus(entity.status) - } - EventDataCache:throttle( - entityUpdateKey, - KafkatorioPacketData.Type.MapChunkEntityUpdate, - function(data) - if data.events == nil then - data.events = {} - end - local ____data_events_7, ____eventName_8 = data.events, eventName - if ____data_events_7[____eventName_8] == nil then - ____data_events_7[____eventName_8] = {} - end - local ____data_events_eventName_9 = data.events[eventName] - ____data_events_eventName_9[#____data_events_eventName_9 + 1] = event.tick - if data.entitiesXY == nil then - data.entitiesXY = {} - end - local ____data_entitiesXY_10, ____tostring_result_11 = data.entitiesXY, tostring(entity.position.x) - if ____data_entitiesXY_10[____tostring_result_11] == nil then - ____data_entitiesXY_10[____tostring_result_11] = {} - end - local ____data_entitiesXY_tostring_result_12, ____tostring_result_13 = data.entitiesXY[tostring(entity.position.x)], tostring(entity.position.y) - if ____data_entitiesXY_tostring_result_12[____tostring_result_13] == nil then - ____data_entitiesXY_tostring_result_12[____tostring_result_13] = entityUpdate - end - end - ) -end -function EntityUpdatesHandler.throttleResourcesUpdate(self, eventName, eventTick, surfaceIndex, chunkPosition, entities) - local entitiesByProtoId = {} - for ____, entity in ipairs(entities) do - local protoId = Converters.prototypeIdEntity(entity) - if entitiesByProtoId[protoId] == nil then - entitiesByProtoId[protoId] = {} - end - local ____entitiesByProtoId_protoId_14 = entitiesByProtoId[protoId] - ____entitiesByProtoId_protoId_14[#____entitiesByProtoId_protoId_14 + 1] = entity - end - for protoId, resourceEntities in pairs(entitiesByProtoId) do - local entityUpdateKey = {protoId = protoId, surfaceIndex = surfaceIndex, chunkPosition = chunkPosition} - EventDataCache:throttle( - entityUpdateKey, - KafkatorioPacketData.Type.MapChunkResourceUpdate, - function(data) - if data.events == nil then - data.events = {} - end - local ____data_events_15, ____eventName_16 = data.events, eventName - if ____data_events_15[____eventName_16] == nil then - ____data_events_15[____eventName_16] = {} - end - local ____data_events_eventName_17 = data.events[eventName] - ____data_events_eventName_17[#____data_events_eventName_17 + 1] = eventTick - for ____, entity in ipairs(resourceEntities) do - if data.amounts == nil then - data.amounts = {} - end - local ____data_amounts_18, ____tostring_result_19 = data.amounts, tostring(entity.position.x) - if ____data_amounts_18[____tostring_result_19] == nil then - ____data_amounts_18[____tostring_result_19] = {} - end - data.amounts[tostring(entity.position.x)][tostring(entity.position.y)] = entity.amount - if entity.initial_amount ~= nil then - if data.initialAmounts == nil then - data.initialAmounts = {} - end - local ____data_initialAmounts_20, ____tostring_result_21 = data.initialAmounts, tostring(entity.position.x) - if ____data_initialAmounts_20[____tostring_result_21] == nil then - ____data_initialAmounts_20[____tostring_result_21] = {} - end - data.initialAmounts[tostring(entity.position.x)][tostring(entity.position.y)] = entity.initial_amount - end - end - end - ) - end -end -function EntityUpdatesHandler.getTileResourceEntities(self, surface, mapPosition) - return surface.find_entities_filtered({position = mapPosition, collision_mask = "resource-layer"}) -end -function EntityUpdatesHandler.getAreaResourceEntities(self, surface, area) - return surface.find_entities_filtered({area = area, collision_mask = "resource-layer"}) -end -local EntityUpdates = __TS__New(____exports.EntityUpdatesHandler) -____exports.default = EntityUpdates -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/handlers/MapChunkUpdateHandler.lua b/modules/events-mod/src/generated/lua/main/events/handlers/MapChunkUpdateHandler.lua deleted file mode 100644 index 66c8f6e..0000000 --- a/modules/events-mod/src/generated/lua/main/events/handlers/MapChunkUpdateHandler.lua +++ /dev/null @@ -1,208 +0,0 @@ -local ____lualib = require("lualib_bundle") -local __TS__Class = ____lualib.__TS__Class -local Map = ____lualib.Map -local __TS__Iterator = ____lualib.__TS__Iterator -local __TS__New = ____lualib.__TS__New -local ____exports = {} -local ____converters = require("main.events.converters") -local Converters = ____converters.Converters -local ____eventTypeCheck = require("main.events.eventTypeCheck") -local isEventType = ____eventTypeCheck.isEventType -local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") -local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData -local ____EventDataCache = require("main.emitting.EventDataCache") -local EventUpdates = ____EventDataCache.default -local MapChunkUpdateHandler = __TS__Class() -MapChunkUpdateHandler.name = "MapChunkUpdateHandler" -function MapChunkUpdateHandler.prototype.____constructor(self) -end -function MapChunkUpdateHandler.prototype.handleChunkGeneratedEvent(self, event, expirationDurationTicks) - local tiles = event.surface.find_tiles_filtered({area = event.area}) - MapChunkUpdateHandler:mapTilesUpdateDebounce( - event.surface, - Converters.chunkPosition(event.position), - tiles, - event, - nil, - expirationDurationTicks - ) -end -function MapChunkUpdateHandler.prototype.handleBuiltTileEvent(self, event) - local surface = game.get_surface(event.surface_index) - if surface == nil then - local eventName = Converters.eventNameString(event.name) - log("[handleBuiltTileEvent] undefined surface " .. eventName) - return - end - local tiles = Converters.convertPlacedTiles(event.tile, event.tiles) - local groupedTiles = MapChunkUpdateHandler:groupTiles(tiles) - for ____, ____value in __TS__Iterator(groupedTiles) do - local chunkPos = ____value[1] - local tiles = ____value[2] - MapChunkUpdateHandler:mapTilesUpdateDebounce( - surface, - chunkPos, - tiles, - event, - function(data) - if isEventType(event, defines.events.on_player_built_tile) then - data.player = event.player_index - return - end - if isEventType(event, defines.events.on_robot_built_tile) then - local ____data_2 = data - local ____event_robot_unit_number_0 = event.robot - if ____event_robot_unit_number_0 ~= nil then - ____event_robot_unit_number_0 = ____event_robot_unit_number_0.unit_number - end - ____data_2.robot = { - unitNumber = ____event_robot_unit_number_0 or nil, - protoId = Converters.prototypeId(event.robot.type, event.robot.name) - } - return - end - local exhaustiveCheck = event - end - ) - end -end -function MapChunkUpdateHandler.prototype.handleMinedTileEvent(self, event) - local surface = game.get_surface(event.surface_index) - if surface == nil then - local eventName = Converters.eventNameString(event.name) - log("[handleMinedTileEvent] undefined surface " .. eventName) - return - end - local tiles = Converters.convertRemovedTiles(surface, event.tiles) - local groupedTiles = MapChunkUpdateHandler:groupTiles(tiles) - for ____, ____value in __TS__Iterator(groupedTiles) do - local chunkPos = ____value[1] - local tiles = ____value[2] - MapChunkUpdateHandler:mapTilesUpdateDebounce( - surface, - chunkPos, - tiles, - event, - function(data) - if isEventType(event, defines.events.on_player_mined_tile) then - data.player = event.player_index - return - end - if isEventType(event, defines.events.on_robot_mined_tile) then - local ____data_5 = data - local ____event_robot_unit_number_3 = event.robot - if ____event_robot_unit_number_3 ~= nil then - ____event_robot_unit_number_3 = ____event_robot_unit_number_3.unit_number - end - ____data_5.robot = { - unitNumber = ____event_robot_unit_number_3 or nil, - protoId = Converters.prototypeId(event.robot.type, event.robot.name) - } - return - end - local exhaustiveCheck = event - end - ) - end -end -function MapChunkUpdateHandler.prototype.handleScriptSetTilesEvent(self, event) - local surface = game.get_surface(event.surface_index) - if surface == nil then - return - end - local groupedTiles = MapChunkUpdateHandler:groupTiles(event.tiles) - for ____, ____value in __TS__Iterator(groupedTiles) do - local chunkPos = ____value[1] - local tiles = ____value[2] - MapChunkUpdateHandler:mapTilesUpdateDebounce(surface, chunkPos, tiles, event) - end -end -function MapChunkUpdateHandler.prototype.handlePreChunkDeleted(self, event) - local surface = game.get_surface(event.surface_index) - if surface == nil then - return - end - for ____, position in ipairs(event.positions) do - local key = { - surfaceIndex = surface.index, - chunkPosition = Converters.chunkPosition(position) - } - EventUpdates:debounce( - key, - KafkatorioPacketData.Type.MapChunkTileUpdate, - function(data) - data.isDeleted = true - return true - end, - 0 - ) - end -end -function MapChunkUpdateHandler.mapTilesUpdateDebounce(self, surface, chunkPosition, tiles, event, updater, expirationDurationTicks) - if surface == nil then - return - end - local eventName = Converters.eventNameString(event.name) - local key = {surfaceIndex = surface.index, chunkPosition = chunkPosition} - EventUpdates:debounce( - key, - KafkatorioPacketData.Type.MapChunkTileUpdate, - function(data) - if data.tileDictionary == nil then - data.tileDictionary = {tilesXY = {}, protos = {}} - end - local protosCount = table_size(data.tileDictionary.protos) - for ____, tile in ipairs(tiles) do - local protoId = Converters.prototypeId("tile", tile.name) - if data.tileDictionary.protos[protoId] == nil then - end - local ____data_tileDictionary_protos_7, ____protoId_8 = data.tileDictionary.protos, protoId - if ____data_tileDictionary_protos_7[____protoId_8] == nil then - local ____protosCount_6 = protosCount - protosCount = ____protosCount_6 + 1 - ____data_tileDictionary_protos_7[____protoId_8] = ____protosCount_6 - end - local protoKey = data.tileDictionary.protos[protoId] - local xString = tostring(tile.position.x) - local yString = tostring(tile.position.y) - local ____data_tileDictionary_tilesXY_9, ____xString_10 = data.tileDictionary.tilesXY, xString - if ____data_tileDictionary_tilesXY_9[____xString_10] == nil then - ____data_tileDictionary_tilesXY_9[____xString_10] = {} - end - data.tileDictionary.tilesXY[xString][yString] = protoKey - end - if data.events == nil then - data.events = {} - end - local ____data_events_11, ____eventName_12 = data.events, eventName - if ____data_events_11[____eventName_12] == nil then - ____data_events_11[____eventName_12] = {} - end - local ____data_events_eventName_13 = data.events[eventName] - ____data_events_eventName_13[#____data_events_eventName_13 + 1] = event.tick - if updater ~= nil then - updater(data) - end - end, - expirationDurationTicks - ) -end -function MapChunkUpdateHandler.groupTiles(self, tiles) - local mapChunkPositionToTiles = __TS__New(Map) - for ____, tile in ipairs(tiles) do - local chunkPosition = Converters.tilePositionToChunkPosition(tile.position) - if not mapChunkPositionToTiles:has(chunkPosition) then - mapChunkPositionToTiles:set(chunkPosition, {}) - end - local ____mapChunkPositionToTiles_get_result_push_result_14 = mapChunkPositionToTiles:get(chunkPosition) - if ____mapChunkPositionToTiles_get_result_push_result_14 ~= nil then - local ____temp_15 = mapChunkPositionToTiles:get(chunkPosition) - ____temp_15[#____temp_15 + 1] = tile - ____mapChunkPositionToTiles_get_result_push_result_14 = nil - end - end - return mapChunkPositionToTiles -end -local MapChunkUpdate = __TS__New(MapChunkUpdateHandler) -____exports.default = MapChunkUpdate -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/handlers/PlayerUpdateHandler.lua b/modules/events-mod/src/generated/lua/main/events/handlers/PlayerUpdateHandler.lua deleted file mode 100644 index f56b95d..0000000 --- a/modules/events-mod/src/generated/lua/main/events/handlers/PlayerUpdateHandler.lua +++ /dev/null @@ -1,60 +0,0 @@ -local ____lualib = require("lualib_bundle") -local __TS__Class = ____lualib.__TS__Class -local __TS__New = ____lualib.__TS__New -local ____exports = {} -local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") -local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData -local ____converters = require("main.events.converters") -local Converters = ____converters.Converters -local ____EventDataCache = require("main.emitting.EventDataCache") -local EventUpdates = ____EventDataCache.default -____exports.PlayerUpdateHandler = __TS__Class() -local PlayerUpdateHandler = ____exports.PlayerUpdateHandler -PlayerUpdateHandler.name = "PlayerUpdateHandler" -function PlayerUpdateHandler.prototype.____constructor(self) -end -function PlayerUpdateHandler.prototype.handleBannedEvent(self, event) - self:playerUpdateThrottle( - event, - function(player, data) - data.bannedReason = event.reason or nil - Converters.playerOnlineInfo(player, data) - end - ) -end -function PlayerUpdateHandler.prototype.playerUpdateThrottle(self, event, mutate, expirationDurationTicks) - if expirationDurationTicks == nil then - expirationDurationTicks = nil - end - local playerIndex = event.player_index - if playerIndex == nil then - return - end - local eventName = Converters.eventNameString(event.name) - EventUpdates:throttle( - {index = playerIndex}, - KafkatorioPacketData.Type.PlayerUpdate, - function(data) - local player = game.players[playerIndex] - if player ~= nil then - mutate(player, data) - end - if data.events == nil then - data.events = {} - end - local ____data_events_0, ____eventName_1 = data.events, eventName - if ____data_events_0[____eventName_1] == nil then - ____data_events_0[____eventName_1] = {} - end - local ____data_events_eventName_2 = data.events[eventName] - ____data_events_eventName_2[#____data_events_eventName_2 + 1] = event.tick - end, - expirationDurationTicks - ) -end -function PlayerUpdateHandler.prototype.playerUpdateImmediate(self, event, mutate) - self:playerUpdateThrottle(event, mutate, 0) -end -local PlayerUpdates = __TS__New(____exports.PlayerUpdateHandler) -____exports.default = PlayerUpdates -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua b/modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua deleted file mode 100644 index b3c5857..0000000 --- a/modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua +++ /dev/null @@ -1,57 +0,0 @@ -local ____exports = {} -local ____EntityUpdateHandler = require("main.events.handlers.EntityUpdateHandler") -local EntityUpdates = ____EntityUpdateHandler.default -local ____MapChunkUpdateHandler = require("main.events.handlers.MapChunkUpdateHandler") -local MapChunkUpdate = ____MapChunkUpdateHandler.default -script.on_event( - defines.events.on_chunk_generated, - function(e) - log("on_chunk_generated " .. tostring(e.tick)) - MapChunkUpdate:handleChunkGeneratedEvent(e) - EntityUpdates:handleChunkGeneratedEvent(e) - end -) -script.on_event( - defines.events.script_raised_set_tiles, - function(event) - log("script_raised_set_tiles " .. tostring(event.tick)) - MapChunkUpdate:handleScriptSetTilesEvent(event) - end -) -script.on_event( - defines.events.on_player_built_tile, - function(e) - log("on_player_built_tile " .. tostring(e.tick)) - MapChunkUpdate:handleBuiltTileEvent(e) - end -) -script.on_event( - defines.events.on_robot_built_tile, - function(e) - log("on_robot_built_tile " .. tostring(e.tick)) - MapChunkUpdate:handleBuiltTileEvent(e) - end -) -script.on_event( - defines.events.on_player_mined_tile, - function(e) - log("on_player_mined_tile " .. tostring(e.tick)) - MapChunkUpdate:handleMinedTileEvent(e) - EntityUpdates:handleMinedTileEvent(e) - end -) -script.on_event( - defines.events.on_robot_mined_tile, - function(e) - log("on_robot_mined_tile " .. tostring(e.tick)) - MapChunkUpdate:handleMinedTileEvent(e) - end -) -script.on_event( - defines.events.on_pre_chunk_deleted, - function(e) - log("on_pre_chunk_deleted " .. tostring(e.tick)) - MapChunkUpdate:handlePreChunkDeleted(e) - end -) -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/playerUpdates.lua b/modules/events-mod/src/generated/lua/main/events/playerUpdates.lua deleted file mode 100644 index 09e39b7..0000000 --- a/modules/events-mod/src/generated/lua/main/events/playerUpdates.lua +++ /dev/null @@ -1,129 +0,0 @@ -local ____exports = {} -local disconnectReasons -local ____converters = require("main.events.converters") -local Converters = ____converters.Converters -local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") -local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData -local ____PacketEmitter = require("main.emitting.PacketEmitter") -local packetEmitter = ____PacketEmitter.default -local ____PlayerUpdateHandler = require("main.events.handlers.PlayerUpdateHandler") -local PlayerUpdates = ____PlayerUpdateHandler.default -script.on_event( - defines.events.on_player_joined_game, - function(e) - PlayerUpdates:playerUpdateThrottle( - e, - function(player, data) - data.isAdmin = player.admin - local ____data_2 = data - local ____player_character_unit_number_0 = player.character - if ____player_character_unit_number_0 ~= nil then - ____player_character_unit_number_0 = ____player_character_unit_number_0.unit_number - end - ____data_2.characterUnitNumber = ____player_character_unit_number_0 or nil - data.chatColour = Converters.mapColour(player.chat_color) - data.colour = Converters.mapColour(player.color) - data.forceIndex = player.force.index - data.name = player.name - data.isShowOnMap = player.show_on_map - data.isSpectator = player.spectator - data.surfaceIndex = player.surface.index - data.tag = player.tag - Converters.playerOnlineInfo(player, data) - end - ) - end -) -script.on_event( - defines.events.on_player_changed_position, - function(e) - PlayerUpdates:playerUpdateThrottle( - e, - function(player, data) - data.position = {player.position.x, player.position.y} - end - ) - end -) -script.on_event( - defines.events.on_player_changed_surface, - function(e) - PlayerUpdates:playerUpdateThrottle( - e, - function(player, data) - data.position = {player.position.x, player.position.y} - data.surfaceIndex = player.surface.index - end - ) - end -) -script.on_event( - defines.events.on_player_died, - function(e) - PlayerUpdates:playerUpdateThrottle( - e, - function(player, data) - data.ticksToRespawn = player.ticks_to_respawn or nil - Converters.playerOnlineInfo(player, data) - if e.cause ~= nil then - data.diedCause = { - unitNumber = e.cause.unit_number or nil, - protoId = Converters.prototypeId(e.cause.type, e.cause.name) - } - end - end - ) - end -) -script.on_event( - defines.events.on_player_banned, - function(event) - PlayerUpdates:handleBannedEvent(event) - end -) -script.on_event( - defines.events.on_player_unbanned, - function(event) - PlayerUpdates:handleBannedEvent(event) - end -) -script.on_event( - defines.events.on_player_kicked, - function(event) - log((("on_player_kicked " .. tostring(event.tick)) .. " ") .. tostring(event.name)) - PlayerUpdates:playerUpdateImmediate( - event, - function(player, data) - data.kickedReason = event.reason or nil - Converters.playerOnlineInfo(player, data) - end - ) - end -) -script.on_event( - defines.events.on_pre_player_left_game, - function(event) - log((("on_pre_player_left_game " .. tostring(event.tick)) .. " ") .. tostring(event.name)) - local playerUpdateKey = {index = event.player_index} - local playerUpdate = {type = KafkatorioPacketData.Type.PlayerUpdate, key = playerUpdateKey, disconnectReason = disconnectReasons[event.reason]} - packetEmitter:emitKeyedPacket(playerUpdate) - end -) -script.on_event( - defines.events.on_player_removed, - function(event) - log((("on_player_removed " .. tostring(event.tick)) .. " ") .. tostring(event.name)) - PlayerUpdates:playerUpdateImmediate( - event, - function(player, data) - data.isRemoved = true - Converters.playerOnlineInfo(player, data) - end - ) - end -) -disconnectReasons = {} -for name, disconnectId in pairs(defines.disconnect_reason) do - disconnectReasons[disconnectId] = name -end -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua deleted file mode 100644 index e066b9f..0000000 --- a/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua +++ /dev/null @@ -1,83 +0,0 @@ -local ____exports = {} -local emit, getMapTilePrototypes, getEntityPrototypes, convertItemGroup, convertItemSubgroup -local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") -local FactorioPrototype = ____kafkatorio_2Dschema.FactorioPrototype -local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData -local ____converters = require("main.events.converters") -local Converters = ____converters.Converters -local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue") -local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default -function emit(protosByType) - for ____, protos in pairs(protosByType) do - KafkatorioPacketQueue:enqueue({type = KafkatorioPacketData.Type.PrototypesUpdate, prototypes = protos}) - end -end -function getMapTilePrototypes() - local tiles = {} - for ____, tile in pairs(game.tile_prototypes) do - tiles[#tiles + 1] = { - type = FactorioPrototype.Type.MapTile, - protoId = Converters.prototypeId("tile", tile.name), - order = tile.order, - layer = tile.layer, - collisionMasks = Converters.convertCollisionMaskToNames(tile.collision_mask), - mapColour = Converters.mapColour(tile.map_color), - canBeMined = tile.mineable_properties.minable - } - end - return {tiles = tiles} -end -function getEntityPrototypes() - local protos = {} - for ____, entity in pairs(game.entity_prototypes) do - local key = (((tostring(entity.group.name) .. "/") .. tostring(entity.subgroup.name)) .. "/") .. entity.type - if protos[key] == nil then - protos[key] = {} - end - local entityProto = { - type = FactorioPrototype.Type.Entity, - protoId = Converters.prototypeId(entity.type, entity.name), - group = convertItemGroup(entity.group), - subgroup = convertItemSubgroup(entity.subgroup), - isBuilding = entity.is_building, - isEntityWithOwner = entity.is_entity_with_owner, - isMilitaryTarget = entity.is_military_target, - maxHealth = entity.max_health, - collisionBox = Converters.collisionBox(entity.collision_box), - tileWidth = entity.tile_width, - tileHeight = entity.tile_height - } - if entity.map_color ~= nil then - entityProto.mapColour = Converters.mapColour(entity.map_color) - end - if entity.friendly_map_color ~= nil then - entityProto.mapColourFriend = Converters.mapColour(entity.friendly_map_color) - end - if entity.enemy_map_color ~= nil then - entityProto.mapColourEnemy = Converters.mapColour(entity.enemy_map_color) - end - entityProto.miningProperties = Converters.miningProperties(entity.mineable_properties) - local ____protos_key_0 = protos[key] - ____protos_key_0[#____protos_key_0 + 1] = entityProto - end - return protos -end -function convertItemGroup(itemGroup) - return {name = itemGroup.name, type = itemGroup.type, parentName = nil} -end -function convertItemSubgroup(itemGroup) - local ____itemGroup_name_3 = itemGroup.name - local ____itemGroup_type_4 = itemGroup.type - local ____itemGroup_group_name_1 = itemGroup.group - if ____itemGroup_group_name_1 ~= nil then - ____itemGroup_group_name_1 = ____itemGroup_group_name_1.name - end - return {name = ____itemGroup_name_3, type = ____itemGroup_type_4, parentName = ____itemGroup_group_name_1 or nil} -end -function ____exports.emitPrototypes() - local mapTileProtos = getMapTilePrototypes() - emit(mapTileProtos) - local entityProtos = getEntityPrototypes() - emit(entityProtos) -end -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua b/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua deleted file mode 100644 index b2599b7..0000000 --- a/modules/events-mod/src/generated/lua/main/events/registerEventListeners.lua +++ /dev/null @@ -1,57 +0,0 @@ -local ____exports = {} -local ____eventTypeCheck = require("main.events.eventTypeCheck") -local isEventType = ____eventTypeCheck.isEventType -local ____converters = require("main.events.converters") -local Converters = ____converters.Converters -local ____surfaceUpdates = require("main.events.surfaceUpdates") -local handleSurfaceUpdate = ____surfaceUpdates.handleSurfaceUpdate -local ____EventDataCache = require("main.emitting.EventDataCache") -local EventCacheService = ____EventDataCache.default -local ____MapChunkUpdateHandler = require("main.events.handlers.MapChunkUpdateHandler") -local MapChunkUpdate = ____MapChunkUpdateHandler.default -local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue") -local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default -local ____PacketEmitter = require("main.emitting.PacketEmitter") -local PacketEmitter = ____PacketEmitter.default -local ____EventDataQueue = require("main.emitting.EventDataQueue") -local EventDataQueue = ____EventDataQueue.default -script.on_event( - defines.events.on_tick, - function(event) - if event.tick % 1000 == 0 then - for ____, surface in pairs(game.surfaces) do - handleSurfaceUpdate( - event, - Converters.eventNameString(event.name), - surface - ) - end - end - local kPacket = KafkatorioPacketQueue:dequeue() - if kPacket ~= nil then - PacketEmitter:emitInstantPacket(kPacket) - end - if event.tick % 6 == 0 then - local emittedCount = EventCacheService:extractAndEmitExpiredPackets() - if emittedCount > 0 then - log(((("[on_tick:" .. tostring(event.tick)) .. "] emitted ") .. tostring(emittedCount)) .. " events") - end - end - if event.tick % 7 == 0 then - local events = EventDataQueue:dequeueValues(1) - if #events > 0 then - log((((("[on_tick:" .. tostring(event.tick)) .. "] dequeued ") .. tostring(#events)) .. " events, current size: ") .. tostring(EventDataQueue:size())) - local i = 1 - for ____, event in ipairs(events) do - if isEventType(event, defines.events.on_chunk_generated) then - local eName = Converters.eventNameString(event.name) - log((((("[on_tick:" .. tostring(event.tick)) .. "] dequeued event ") .. eName) .. ", delay ") .. tostring(i)) - MapChunkUpdate:handleChunkGeneratedEvent(event, i) - i = i + 1 - end - end - end - end - end -) -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/events/settingsUpdate.lua b/modules/events-mod/src/generated/lua/main/events/settingsUpdate.lua deleted file mode 100644 index e320cd0..0000000 --- a/modules/events-mod/src/generated/lua/main/events/settingsUpdate.lua +++ /dev/null @@ -1,6 +0,0 @@ -script.on_event( - defines.events.on_runtime_mod_setting_changed, - function(e) - print((((((("Settings changed " .. e.setting_type) .. ", ") .. tostring(e.player_index)) .. ", ") .. e.setting) .. ", ") .. tostring(e.mod_name)) - end -) diff --git a/modules/events-mod/src/generated/lua/main/events/surfaceUpdates.lua b/modules/events-mod/src/generated/lua/main/events/surfaceUpdates.lua deleted file mode 100644 index a1ff33a..0000000 --- a/modules/events-mod/src/generated/lua/main/events/surfaceUpdates.lua +++ /dev/null @@ -1,11 +0,0 @@ -local ____exports = {} -local ____PacketEmitter = require("main.emitting.PacketEmitter") -local PacketEmitter = ____PacketEmitter.default -local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") -local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData -local Type = KafkatorioPacketData.Type -function ____exports.handleSurfaceUpdate(event, eventType, surface) - local update = {type = Type.SurfaceUpdate, name = surface.name, index = surface.index, daytime = surface.daytime} - PacketEmitter:emitInstantPacket(update) -end -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/global-init.lua b/modules/events-mod/src/generated/lua/main/global-init.lua deleted file mode 100644 index ff07189..0000000 --- a/modules/events-mod/src/generated/lua/main/global-init.lua +++ /dev/null @@ -1,17 +0,0 @@ -local ____exports = {} -local ____EventDataCache = require("main.emitting.EventDataCache") -local EventUpdates = ____EventDataCache.default -local ____EventDataQueue = require("main.emitting.EventDataQueue") -local EventDataQueueManager = ____EventDataQueue.EventDataQueueManager -function ____exports.initGlobal(force) - if force == nil then - force = false - end - log(("Initialising Kafkatorio Global variables (force=" .. tostring(force)) .. ")...") - global.MOD_VERSION = script.active_mods[script.mod_name] - global.FACTORIO_VERSION = script.active_mods.base - EventDataQueueManager:init(true) - EventUpdates:init(true) - log("Finished initialising Kafkatorio Global variables") -end -return ____exports diff --git a/modules/events-mod/src/generated/lua/main/settings/KafkatorioSettings.lua b/modules/events-mod/src/generated/lua/main/settings/KafkatorioSettings.lua deleted file mode 100644 index 597c9d4..0000000 --- a/modules/events-mod/src/generated/lua/main/settings/KafkatorioSettings.lua +++ /dev/null @@ -1,46 +0,0 @@ -local ____lualib = require("lualib_bundle") -local __TS__Class = ____lualib.__TS__Class -local __TS__StringReplaceAll = ____lualib.__TS__StringReplaceAll -local __TS__New = ____lualib.__TS__New -local ____exports = {} -____exports.KafkatorioSettingsConfig = __TS__Class() -local KafkatorioSettingsConfig = ____exports.KafkatorioSettingsConfig -KafkatorioSettingsConfig.name = "KafkatorioSettingsConfig" -function KafkatorioSettingsConfig.prototype.____constructor(self) -end -function KafkatorioSettingsConfig.prototype.getEventCacheExpirationTicks(self, packet) - local settingName = ____exports.KafkatorioSettingsConfig:cacheDurationSettingName(packet.type) - local seconds = settings.global[settingName].value - return seconds * 60 -end -function KafkatorioSettingsConfig.prototype.initialiseSettings(self, data) - for ____type in pairs(____exports.KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds) do - data:extend({____exports.KafkatorioSettingsConfig:createDefaultCacheDuration(____type)}) - end -end -function KafkatorioSettingsConfig.createDefaultCacheDuration(self, ____type, defaultExpirationSeconds) - if defaultExpirationSeconds == nil then - defaultExpirationSeconds = ____exports.KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[____type] - end - return { - type = "double-setting", - name = ____exports.KafkatorioSettingsConfig:cacheDurationSettingName(____type), - setting_type = "runtime-global", - default_value = defaultExpirationSeconds, - minimum_value = 0.25, - maximum_value = 120 - } -end -function KafkatorioSettingsConfig.cacheDurationSettingName(self, ____type) - return "kafkatorio:cache-expiration-seconds_" .. __TS__StringReplaceAll(____type, ".", "-") -end -KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds = { - ["kafkatorio.packet.keyed.PlayerUpdate"] = 0.5, - ["kafkatorio.packet.keyed.MapChunkTileUpdate"] = 30, - ["kafkatorio.packet.keyed.MapChunkEntityUpdate"] = 30, - ["kafkatorio.packet.keyed.MapChunkResourceUpdate"] = 30, - ["kafkatorio.packet.keyed.EntityUpdate"] = 5 -} -local KafkatorioSettings = __TS__New(____exports.KafkatorioSettingsConfig) -____exports.default = KafkatorioSettings -return ____exports diff --git a/modules/events-mod/src/generated/lua/settings.lua b/modules/events-mod/src/generated/lua/settings.lua deleted file mode 100644 index f01f592..0000000 --- a/modules/events-mod/src/generated/lua/settings.lua +++ /dev/null @@ -1,5 +0,0 @@ -local ____exports = {} -local ____KafkatorioSettings = require("main.settings.KafkatorioSettings") -local KafkatorioSettings = ____KafkatorioSettings.default -KafkatorioSettings:initialiseSettings(data) -return ____exports From 76c47d9756c90fb6555fb4f8aaa9e3d181b2e03d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 19 Dec 2022 16:53:18 +0100 Subject: [PATCH 628/629] tidy up after refactoring Gradle Factorio plugin --- .../adamko/gradle/factorio/configureIdea.kt | 42 +---- .../tasks/LaunchFactorioClientTask.kt | 6 + modules/events-mod/build.gradle.kts | 161 ------------------ modules/events-mod/info.json | 9 - modules/events-mod/kafkatorio-logo.png | Bin 52828 -> 0 bytes .../infra-factorio-client/build.gradle.kts | 59 +------ .../infra-factorio-server/build.gradle.kts | 10 -- 7 files changed, 14 insertions(+), 273 deletions(-) delete mode 100644 modules/events-mod/info.json delete mode 100644 modules/events-mod/kafkatorio-logo.png diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureIdea.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureIdea.kt index 15b63ee..6b9654c 100644 --- a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureIdea.kt +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/configureIdea.kt @@ -4,16 +4,15 @@ import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.withType import org.gradle.plugins.ide.idea.IdeaPlugin import org.gradle.plugins.ide.idea.model.IdeaModel -import org.gradle.plugins.ide.idea.model.Module +//import org.gradle.plugins.ide.idea.model.Module as IdeaModule internal fun FactorioModPlugin.PluginContext.configureIdea() { project.plugins.withType().configureEach { -// project.afterEvaluate { project.extensions.configure { module { -// this.scopes["MAIN"]?.plusAssign(mutableMapOf("plus" to listOf(project.configurations.create("main")))) -// + // scopes["MAIN"] = mapOf("plus" to listOf(configurations.factorioMod.get())) + sourceDirs.plusAssign(settings.mainSources.typescript.srcDirs) sourceDirs.plusAssign(settings.mainSources.lua.srcDirs) sourceDirs.plusAssign(settings.generatedSources.lua.srcDirs) @@ -27,39 +26,12 @@ internal fun FactorioModPlugin.PluginContext.configureIdea() { generatedSourceDirs.plusAssign(settings.generatedSources.lua.srcDirs) generatedSourceDirs.plusAssign(settings.generatedSources.typescript.srcDirs) -// sourceDirs.plusAssign( -// listOf( -// settings.typescriptSrcDir.get().asFile, -// settings.generatedLuaSrcDir.get().asFile, -// ) -// ) -//// sourceDirs = sourceDirs + file("src/main/lua") -// resourceDirs = resourceDirs + settings.modDataResourcesDir -// testSources.from(typescriptTestSrcDir) -//// testSourceDirs = testSourceDirs + typescriptTestSrcDir +// iml { +// whenMerged { +// require(this is IdeaModule) // -// generatedSourceDirs = generatedSourceDirs + generatedSrcDir -//// excludeDirs = excludeDirs + generatedSrcDir - - iml { - whenMerged { - require(this is Module) - -// sourceDirs.plusAssign(settings.mainSources.typescript.srcDirs) -// sourceDirs.plusAssign(settings.mainSources.lua.srcDirs) -// sourceDirs.plusAssign(settings.generatedSources.lua.srcDirs) -// -// testSources.from(settings.testSources.typescript) -// testSources.from(settings.testSources.lua) -// -// resourceDirs.plusAssign(settings.mainSources.resources.srcDirs) -// testResources.from(settings.testSources.resources) -// -// generatedSourceDirs.plusAssign(settings.generatedSources.lua.srcDirs) -// generatedSourceDirs.plusAssign(settings.generatedSources.typescript.srcDirs) - } - } // } +// } } } } diff --git a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/LaunchFactorioClientTask.kt b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/LaunchFactorioClientTask.kt index 04d4ae7..de09e86 100644 --- a/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/LaunchFactorioClientTask.kt +++ b/gradle-plugins/factorio-gradle/src/main/kotlin/dev/adamko/gradle/factorio/tasks/LaunchFactorioClientTask.kt @@ -67,6 +67,12 @@ abstract class LaunchFactorioClientTask @Inject constructor( val modsDirFlag = clientModsPath.map { """--mod-directory "$it"""" }.getOrElse("") val mpConnectFlag = serverConnectHost.map { "--mp-connect $it" }.getOrElse("") +// commandLine = parseSpaceSeparatedArgs( +//// """explorer "steam://rungameid/$factorioGameId// --mp-connect localhost/" """ // not working +//// """explorer "steam://run/$factorioGameId//--mp-connect localhost/" """ // works! But has annoying pop-up +// """ ${steamExe.asFile.orNull?.canonicalPath} -applaunch $factorioGameId --mp-connect localhost --mod-directory ${clientModsDirectory.asFile.orNull?.canonicalPath} """ +// ) + return """ $steamExe --applaunch $factorioId $modsDirFlag $mpConnectFlag """.trimIndent() diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index f4d466f..82de877 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -21,38 +21,8 @@ factorioMod { factorioCompatibility.set(libs.versions.factorio.map { it.substringBeforeLast(".") }) } -// Factorio required format is: -// - filename: `mod-name_version.zip` -// - zip contains one directory, `mod-name` -//val modName: String by extra { "${rootProject.name}-events" } -//extra.set("modName", "kafkatorio-events") -//val modName = extra.get("modName") as String - -//val modDescription: String by project.extra { project.description ?: "" } - -// version of Factorio that the mod is compatible with (must only be "major.minor" - patch causes error) -//val modFactorioCompatibility: Provider = -// libs.versions.factorio.map { SemVer.parse(it).run { "$major.$minor" } } - -//rootProject.layout.projectDirectory.file("LICENSE") val licenseFile: RegularFile by rootProject.extra -@Suppress("UNCHECKED_CAST") -val projectTokens: MapProperty = - rootProject.extra.get("projectTokens") as? MapProperty - ?: error("error getting projectTokens") -//val projectTokens: MapProperty by rootProject.extra - -val projectTokensX1 = projectTokens.apply { - put("mod.name", factorioMod.modName) - put("mod.title", factorioMod.modTitle) - put("mod.description", factorioMod.modDescription) - put("factorio.version", factorioMod.factorioCompatibility) -} - -//val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") - - node { nodeProjectDir.set(layout.projectDirectory) } @@ -102,21 +72,13 @@ val installEventsTsSchema by tasks.registering(Sync::class) { .map { zipTree(it) } } ) { - // drop the first directory inside the zip -// eachFile { relativePath = dropDirectory() } includeEmptyDirs = false } into(layout.projectDirectory.dir("src/main/typescript/generated")) } -//val zipNameProvider = provider { distributionZipName } - tasks.distZip { -// val projectTokensXX22 = projectTokensX1 - -// inputs.property("zipNameProvider", zipNameProvider) -// inputs.property("projectTokens", projectTokensXX22) val distributionZipName = factorioMod.distributionZipName archiveFileName.set(distributionZipName) } @@ -126,10 +88,8 @@ val publishModToPortal by tasks.registering(FactorioModPublishTask::class) { distributionZip.set(tasks.distZip.flatMap { it.archiveFile }) -// val projectModName = project.extra.get("modName") as String modName.set(factorioMod.modName) modVersion.set(factorioMod.modVersion) -// modVersion.set(project.version.toString()) } tasks.assembleFactorioModContents { @@ -139,49 +99,6 @@ tasks.assembleFactorioModContents { } } - -//distributions { -// main { -// -//// distributionBaseName.set(factorioMod.modName) -// val tokens333: MutableMap = projectTokensX1.get() -// -// contents { -//// from(factorioMod.mainSources.resources) { -//// include("**/**") -//// } -// from(licenseFile) -// from(typescriptToLua.map { it.outputDirectory }) -// filesNotMatching("**/*.png") { -// // maybe make a bug report for projectTokensX1 causing null$null$null error? -// // val tokens333: MutableMap = projectTokensX1.get() -// filter("tokens" to tokens333) -// } -//// includeEmptyDirs = false -//// exclude { -//// // exclude empty files -//// it.file.run { -//// isFile && useLines { lines -> lines.all { line -> line.isBlank() } } -//// } -//// } -// } -// } -//} - - -tasks.withType().configureEach { - val projectTokensXX444 = projectTokensX1 - inputs.property("projectTokens", projectTokensXX444) -} - - -//val factorioModProvider by configurations.registering { -// asProvider() -// factorioModAttributes(objects) -// outgoing.artifact(tasks.distZip.flatMap { it.archiveFile }) -//} - - val projectPackageJsonName: Provider = providers.provider { "${rootProject.name}-${project.name}" } val projectPackageJsonFile: RegularFile = layout.projectDirectory.file("package.json") @@ -207,84 +124,6 @@ tasks.updatePackageJson { tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) } - -//val typescriptSrcDir: File = file("src/main/typescript") -//val luaSrcDir: File = file("src/generated/lua") -//val resourcesDir: File = file("src/main/resources") -//val typescriptTestSrcDir: File = file("src/test/typescript") -//val generatedSrcDir: File = file("src/generated") -// -// -//idea { -// module { -// sourceDirs.plusAssign( -// listOf( -// typescriptSrcDir, -// luaSrcDir, -// ) -// ) -//// sourceDirs = sourceDirs + file("src/main/lua") -// resourceDirs = resourceDirs + resourcesDir -// testSources.from(typescriptTestSrcDir) -//// testSourceDirs = testSourceDirs + typescriptTestSrcDir -// -// generatedSourceDirs = generatedSourceDirs + generatedSrcDir -//// excludeDirs = excludeDirs + generatedSrcDir -// -// iml { -// whenMerged { -// require(this is IdeaImlModule) -// -// sourceDirs.plusAssign( -// listOf( -// typescriptSrcDir, -// luaSrcDir, -// ) -// ) -// -// generatedSourceFolders.plusAssign( -// IdeaImlPath(luaSrcDir.toURI().toString()) -// ) -// resourceDirs = resourceDirs + resourcesDir -// testSources.from(typescriptTestSrcDir) -//// testSourceDirs = testSourceDirs + typescriptTestSrcDir -//// excludeDirs = excludeDirs + generatedSrcDir -// } -// } -// } -//} - - -// trying to get Gradle+idea to recognise the ts-src... - -//val typescriptSrcSet = project.objects.sourceDirectorySet("typescript", "TypeScript").apply { -// srcDirs(tsSrcDir) -// compiledBy(typescriptToLua, TypescriptToLuaTask::outputDirectory) -//// destinationDirectory.set(layout.buildDirectory.dir("typescriptToLua")) -//} -// -//val tsSrcConfiguration by configurations.registering { -// asProvider() -// outgoing.artifact(tsSrcDir) -//} -// -//idea { -// module { -// // Not using += due to https://github.com/gradle/gradle/issues/8749 -// sourceDirs = sourceDirs + typescriptSrcSet.sourceDirectories -// resourceDirs.add(file("src/main/resources")) -// excludeDirs.add(layout.projectDirectory.dir("src/main/typescript/node_modules").asFile) -// scopes.compute("MAIN") { _: String, scope: MutableMap>? -> -// val s = (scope ?: mutableMapOf()) -// s.compute("plus") { _, conf -> -// val c = conf ?: mutableListOf() -// c.add(tsSrcConfiguration.get()) -// c -// } -// s -// } -// } -//} //val downloadFactorioApiDocs by tasks.registering { // group = project.name // diff --git a/modules/events-mod/info.json b/modules/events-mod/info.json deleted file mode 100644 index 68f245b..0000000 --- a/modules/events-mod/info.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "@mod.name@", - "version": "@project.version@", - "title": "@mod.title@", - "description": "@mod.description@", - "author": "@author.email@", - "factorio_version": "@factorio.version@", - "dependencies": [] -} diff --git a/modules/events-mod/kafkatorio-logo.png b/modules/events-mod/kafkatorio-logo.png deleted file mode 100644 index a37200e6995c6af2c45ff2670facd04b3d1542b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52828 zcmY&=2RxST`~HKBY_j(#J5)xtj14GKlg%fTnR}D!J_>djQgQ09if8(_~7uq8K$n36e;%?x4$KA`?)eht3 zy1UuN24DVwI)Ak^%zUU9`BrKP$Q!`qfKjW;yB1vvr*ot^m$itJe}!##!H_& zv+GB54NqSBbk=YG?s+>$#}g-DW|CsjAfom54GB}?Q+~U@O(DfcIf?fz_vbimOV8=& z$BG1OUHcYlY&LOxu->CoNEtEL`Apcj)Qr2>vN7;*Z}Zv6ZctZkc`;!(VI2N*hRylG z663NAUD2+Tv$y_x@G{3)$vdm*4?W{WaZy({6wz@ArIr`BxF!9ryMu;KW2C~5*BEdDp9sNdvhX2KxB}(>kA6K1E2NTZ>iGG zl#WAHgo$UomOA?92PsAeixEtMr*wYm5gun#+(klmAHe#TVnIcJ8w~Obwbe_ zWVe^n6~53P1mh79kuzBpPEx$uoB!Nj^4xiC@UWp;dXqsvKvx*Rnn=^QRY78tR@L}s z*+NR;!>P}4tkNlgZOQ)4?`O9EelO6;RO}2getjj0M?Hpmb9uZm==kW5LQkI7b5Zje z!*cwNg3lHIaht{s4XnB6&7ilx+VxD|NTtJ2sd>rKvQFB?hkrhuOwJZ?Nb z+Fx!w7Cqd>r>nz%0zele+Gr-Cqlto)bj&tSdAR)g_wm$#GK*j2F|jC47n{7h-4;Xd z;br;bfp$>AvPJzg>DVxemjX&CEDsihJM9BZv$AD9o>-=THwqCJvN9qw`-T5>_-28UwGdKIPMXg&jM8Rs=;naSgMh2C27s4_^!PWw+@{j|M&rgVIxNJuptNk`CfUq6`_*L1hU-OR=<0` z%ez^5f3Vo7b>+ML=T$eb6ic^;qN7kKUt-m6_QLjNt42}^aJ?7aSw!)GE^(N?E)`&F zsM>3J3|TX}y-x(ajR8i-3j+4H{{8x>aY-wGV(5+O`#axQX2z$YQ?|kLwb)!Jks~bm zyZ!9!=PH0JWfK&N#>;}p6 zD?I<9%Ybihp{(&}Z$WHke8_!M`)Hf!y-QJ9_um?PE060r^}gLNj7o02y;-Rl#N3@J z{L3^qs;psezND-{zy7ujZ$!sg6*ClUdVM+Sk7FLrTYk?q?F=-oa+z!iCtFzl-7tOD z;#L=ZNmJYXOLW%u8Wca>3bOO|cTrfgIeW?n9_*}6wf8gUy{P*v++||E`O3p6F=FJw z$;ZYtjzg5w`y3aq=JHW-D*ErNWY3Q~BMZ0I^WTTYWw@E&9xdOtK@r{;VJKy;xz+nR zU%Mn{obUt+YW9ohqaqkl%KV5zx^Hc!>$#X^>CTbAECWj!Pn~bU*MBbuJ|xdg`=p7! z43%PtV=QUfEKR2sc6r*jV^Qym#3ikAt6f8yI#QC;KL#Fq5kcZkK0CTRy;lvyY(M&c z)}q${ux>dqa`<Fqp>0qUmO6kgW_`s->W2wKtjV2!bSqrn22H&>hFJDn4 zFQr}ReVy=ng;(u`gw)QP$pQ*P0p~M^cN9Ht!)NoIPxg0bgYTqRnwXvvHG1t@s5_rhmerIeJ;`I4xG1P% zYT|NdtPYKhs?EaK4_6BWrMI5)>pTBBgn9hp4F_imvlD-Rw%(037|P8(*uDj}weY{ph0TQ_Xri63RLOCyPFi2)LXjyWC)xmYxnG!N&ws)It>?7P^oh3~Kb9FbpI8xzf8#8ezu=RfKO6kyTJ^+ezNV2^Ao zvYE#B0KBpR;Aw3RX-TJ2Q0oDx!C3#{$gj^|B1$@ZezYR*#>C$JKNnq^qG)(8$1-If z>?6Td_{JNiJ`fjuavM`V+me|Tw=%s`4ZM=qL?K0KEV)x!!_4<1_65(yy?*c*{0esV zBVOq}eNdo1bTl$SwKT;bI&A&&Kf>(!u=&IsPDr~2tP&CR_} zfjgWbU*sb|T}0j5w z5}8>tZnIxsUby?U{HpO~Zxk2%yv75zN4>`B59<7P(U8F}>ki`hhsNSu)Cjx8ww}SK zs+Ab@wbR~3wp{+Tm!a2Ff20dN`Y3gdLV9cR4@^(CJKISQLgWBauZREr_0f5}A%H>& zkGJ~0oj)e{xulV!zQ;ejmJt*;Uj!#LavWzWm|UTMn&~}BK@GUdmztm@G`1rFo~Ia% znj@8G40~sDCiliL+?Amz{!dHqeJAIyz5L^z!40cU9@b*n!Fx-qopJeBdjN)xWJgMU zndP3`>mOE0PeU;<-c7FLh|N2dG^yj5^StzgqPQ4CH3CB3YUS25Vg6*Tr#N2mR6Z5m zyYsW$x;290LMWd(4UFI1ddes;5;q6)&AMAsCG<83i}Z^0^E96cWph1Soq28W-<89NBO4q$AiT%d@?cn@eWO!2nYde9(?P5{+4y1dhWQ#VqQ)S3^6R0sJpiAjIu(f1AGsBu+-sJLQHfDiUvRTik@XJU9RGTuZKYOeRJm`eAUQ`plidEGA*AzyI}muPw@YE`eb1w`!r{-3|NTm zuNTN!n6CWo^BB?|s#A-mJ)@b-B@5n)f8$vGcleaOgi~*6eJQEQ z{g5YkHA~8B$kQ|`HWd8sCl+_g5(2Ea&}B*c_j+TjJbO6)jw^I8NYq36KCe9z4g&)w8lfY5B(=Gi#L9Dl5{aC zJp*=t(>e1O!!?l{lxZxz^t;+E(xF6fx&TWQXX^E@3ayJ4hVp_0)ZWB&Eq_^deDf2~ zU>ZAH6fce_RhVjCy@;XuI1CbGY9XYYqB}BT(ua`BmHhoC_`;l#J>uxzZ-A%@Bzw?2 zSM&G-5Ea947ELUnnGP&_3`CTw(wZ}hkcCBSrihqU*j{ZLzXga-Nw}fV8>C{G>3pWf z0q|$;eIAN4dT4syS`>UloScyQMQ@r;y=7)@YA!rGwL1H;;{-~vCGOGcAwdhdZihMw z$i5l%>`@f%40(B?VCep$8f}feY%LH`nsvLLiu~IL3ibu;WhbWF3dHzVUP#@s!3G`e z&SeH2otz;McYhj@;D(P;mA1YN*3XrHWmEGgVqyrauzVC6m9_;55trY*t1NPSfp<*Q z<-n6&_RbI7yVHGu=wyl>ZEkLIuvvw&-)JhzyFwHizbqchhbqKc<2xSXE6MsSjEnovbOFm>s(ij9mAm z@cAnSjuS40gb_~t5j}pbL3@7-G6VNcQkc7=kVpzcK|szPQOdn2q4yy3zP^!&s`l;q zc{(;Wou*!j`&{~E!FAttM>AT{gw&mObpTXqwJfF0rjSELy+Tv!J%jJk?%pAUEDvGy zDLIyNq%bo81$P7{XOlvzBLMZp?%CF-aySH`iigM?vOkx~tm(7R+#Nz>w~kE-rdlJMhcBw}o|m z^q(md6wj6FoZgaK3S?9?JWUWVqFd|F{sW)2|D{Dyeg(d;iQ0>8@Tmlby zHrLhuv@x7=ATKJKyk&}l23J?B0lwlZLEdae!On5VeV`nPa_E&u_)#tSyn*{(4U$j+ zOE<#zOPX{qC?aZ?iq}Aj;Jkmt2J*rDv)RVEO`98QStz)Y%Z7y%YL<#uAqAwaLltkr zY_)zn+X;n@;82Y6HB=tRxRrmSmVK3m)J1|a}C zlLfo#nm3JGTr6I&5C{nAa-sFH?4Yuqx0u1|ncjSt6Jg^%C|!HoK?L(BcZ6Xmv{7HL z?^&vdb3k|qL6)4v`?Ao+#0wjifqIqUll4m&Oc6_6`PaDb4!)rT@(+OCqD`pOUL=`S zD_Y;8dRE-!-7wtzbU{v765*z*4g|XG=3gVFCbt|-_lEC^yN_mlb$oBAB7|pPxD~KZ zD!5S5+N9)IzGl7z31ey@Agdnz2Z|{GExR`AJ$gtzkBAm0IUIw1nzNgKE|k%#M`k;e zbkszcUlp9MXr9Pk%+&V`w{iCau+7T(a-k^h%MvKP%##^)zxN`-6H<)av!(XyPAcva zar!bmMJ28iLBWdbY;lU3C2WP(d$KYTk)D^R6ob@-6nY>@ij_v>gau8_pa}QJ^gqho zEFSeBKAuGc4}{_x9qxDjmT_aDMv-;6?gKtRZW^X$iRB@D16o*+1=cL3Fv%=xCjDGboaqafeBKgQ~nsxTq<^7ZaTQ z_zKK}R}B#+kB|}j`C(Q0Ss+N7je5*rK4Y=?M^r$zb7Ip2Y2d?B`#i4T)dSkk(%a)| zJgZkW?o2f?Sl{8UZz#0gdKBsir9@Fs&Je01&*xD^)ocWjCZ(bsmMOR73Q*KyHZsUo z|Aq)P^%{K|L}BFH^Xw@K8{gdkcyT9H`K~L-qtNBF#`3hzHKA(iGmUI1WjqE^vnm(s zzh|jBS?ysZTC%t72P&I{(BmFNa+r<^QuYu@BrN70d?!;&`{Y%~g~dN;<%3jJw0vZ( z0MWMr481&~W>f@fu3Ir)SB)TNK5u)ane+g++gogz_I*#0Z7H-585{QH$ua|>bb0I~ zML!IW*Xfv16g5a2T%&a$x-%-d*y%=)RoWsL#($VB$jJH?NCAg@dB3Hphu3oTn`Eps9eYga)9pmr{NlwJI`%FH<+I+EA$Px5 z8vS0M>&a9Kve>2|-V}@{Aec%3BiE2>LES_9{`MkZVL38j}@iUg_HVhyAhXFMn=!HvLS7_1r0K}N{Ftcd$fAp5o zPikk}eODQWf5_Cy?u*qE`cDiQ~=YogMFM)iSFE)S79HCFx5ZIM4-(M(?WI?F@8)aly=IVKPQB*d@!&-tIKf-C64HbANTSqMKB62#S^_@T1f1Qsa2cLjx zuaVlJOJEAF;i~Pwu=+vXARGZ9TTF9rbNggr&ME%uNJAs%Xi0c0JM934e-7w`xL@7w z;bcH@c^VM3c;DAzE*$2k-T&P+AJ1_4G%{cEHC0q>q3tt@;!IBXa9>PhwJcJw6bxr;+Jk|=}yDQ(u=8>cG1jf-rRD7>)Nb!u&z?6$?(a-@)a-U$LDL7IV!q^ zH5b)A7P>AoK#PQvBe6hSRY3Hnw7DA!a-EIKpfuwdqgEc%U_0ha3RjF9X7vSXN$}qu z#m514p16XmaNt4I!7(W8%tjk6K^p!`5EhXw9MU@fie;@`XLw?`DCei9bK%5Ow%0W6 zj^{2Lld1Yx(vv9`l+K^KVUSv)yeKJ9qgh^(59CqmsgjBL41>AxX!Y8S*}Bw*Sh!(4wN?I?eDe6blW_NeOfpfH+S~i!`;IepfvdchBNWbFO1F zH|RP0ruWUy{Qmc*u#pfA9_9i0P^+%A3OPA@)Xj5od0It9&G+^LM_6ir;7hNkf+BR+ zee|KzNhbP5;|aj(>(AE{85&#tU}vI#3D8085t2jjY-JS%w=b;dDYn_z6q%L#LZaB< z6^Dihvk(-=*1tQ|K#B>fmjBAi%4W=@0hnYloMi&8x2`ffD*VN=z6;fF z=?yXEc_w;JiP$-Ik{fS1Px==(qgNXF;Is1{*F5f~{akhwqKIpzU}-mO3t??SWtEFA z$_EQjOW*8lY=1wbAJ((Fz;fdO(?vRSL$nvUJf@HXBZox?XQ>P1?SC@wOf{YISInS@ zrbxeAmZv{CGj16um3}9 z33I|u^9xK51>$>1_QSAJZH_)o%>k*zZC@TquTgI#Do%3{3#f7 zucwBtb}>*%8K;He`O+{Roq3rVqNX8=OO3R==MxfD!WvA$kh=uYkmrpTLyvvZ%|_?u zJnnCeb&9?S_Q6*_Zh{>0NQpUj#+9D6IGcqu-scC}^VCkw@wdhXM@40z{PwTGr1NfJ z`saxMC@7E;|8xdG|8TG?+SZxtaX9kxs69Xe<&6$GlZpCYdmIZ6EL9=WUk3mgeWeDA zRsmx-;w}eSDKo`K6)*^58$z1i)W2kvNEsq0$dt7qNJ+TS>6Bb4=>l7^)6&5?4sB4{ zR~rE0@4n{pZq_s=Mid`(U9&<~=|sfE`a#;J4=U~LwE-L~G30h!x(9`?)vW3JYWx3r z0lq=T_V&_H`m>gwLr*KiTR96rcqQ#}((hsvEdyd3ouR+`u#us=z$09BqgoxZu*Y_h z@pTUVSs4CwEtIuYiH{?O28Xji*Y#}pRq+h-=U&op1RqrSE8LieYN7g$1uE+r6|3PA zQFfZR)UoZ*;k=RQ&5xpVW8yXk{on#$2?(Je-6j0=x1!6WdMzv`Xg9B-tfjZI^#_U@ zt8+L}ZS7=Xgl}ZVG%&9F*b2O(wPT zv3YqS-+GYpHP)z}j+_Hi#C)-g>?H9sGQkTrO!An|w`CQKBe9G=a-t82f>e%wNv@!KbPM@JPK z?|XEa5nl&3e!$SQvm5hVR6WE0Nwu5ZJ*QHUnQBGY+aF-+zuRMbZ>TgvUtb}i*LnPN z2jcSx-hDV5E3&yEasCpg^!1dZy^`$ri8eGKmGL3-gq*dSRMN$A?~~vMyN-6;{yUz&DRJz5)+*AL3y!QLWqKLC1&N zWlCnRp*Av7#OT=UWkhJVLX4c3`=%yp+!(Gn(}z|Ew{^}USEbs@>!*122ug4BOHLJr z9>;O_No#f-CZY%lFqoznP>Rwykv&9F>($loH2Q(g-P2U>L*ai3pYZA~0O-*mZ}oz& z=A_%V3saK!3k9+Mv9X6L4i|hdmJgMK4uG_~$=C;bCu;7Hf6oL7Rk8-^g!(M2rg4OV4I22fPqEze>{O1+@bFrx|`3m;JcWvFnX_#KuI+ z;Zq_sP2O|*8$$Mwrc;LoCU|Fh76t9@9*X;ZlFrViH?u?2vZz?||DKU4^g`QB9`ldz z36AeTaz@vETmaw@Gzwd6(H)@S6I}?r4HA7vHLzyQJSG_e!Z-c*5`5MT^y=QJ+F*ix zaJu0sA75YJ`^!#zGP|wGa?7vw*L61ciN+A90oHv^fQu_Efn5<%dYR?a4lKRzr)qox zd-8`Gjv;Y*2LiN=>xX9s!7$D%1Y<>%1#tQ}Wbm#p#)4^*@AW)2 z8kxy=x|XW>m;C74nz}NekRbybpk%3=7!0*%_`g^Y zL4(VqoE7}+n5aiZ_u^N~;dY^W^I~=c&(OF-W_$^FVgd%lFkhoV7t};=ibmEs=q{BD z(@TPXQIApZvOxBk#92&waXBz90fj~b#ws4kuc(1Q4Qg^{Pp~sFSqOW2pimDiBwbb) zMEf{@+LAaiS-E9<+hn|5!7u8dfrHvr8*q$O8ndg&4!n$Q;##@6hik4LXNYi$A>9cw7zqA) zOaLulQl(Xicv(e~ZgFG__EETRLgF5k57wdKfF- zXVAfFJLll`o7b^WfX)Hk?{g~0%WZn&Q1hf8xPalpQoCpIH|#IfE;sDQ3!u7)yqRnd zZj;kgqAmBw3@uOaIEiaf_eY6w-g+Hdn+ueqHR|y(p_G@1iFkmojLF(#Fc0nbEc`e# z^3Dd`6N#J{*IfxS` zfm11?19Wv+b_uz#O;IMG_ofvs1$gM?>B!=ab}g!tD9-)PI8pQzaFXkEKr&NK2EHQU zX&YA*6-!G!>_!b`HCE0ig0l#|NhL;8M2@Zu+eS@?zZ}|B33kUt0v4Q zVRFK1!2Z9FRLx zol>ps%#>fOaErrcfPM z=y}iXFTU?l++V!F{TBL=!V3ezv(D&{_ORwQ{veYm{cP=A?IRQ?rc;aXFA-y+h@35^ zw1bKO2pii|TVDTH{jCLsiVKqgbZF3y!Ud=XT9pea8=gbLvK;N!fj%b*ko$m{c$$Vb z_lDocDBySMP_Sxtc>MF8g+{Tm&Bp(FwjTq78&@%Ozv+o_V=N*tN>%2|M}ce-kIbKh z>Rf<*@_D77@gQ?OJsPUm-5En;a``XO0IneaI5}NdNvRy-(nY<5(8>*IIRX_Sm_#bRtbY^ZlGn zgz_K!xCs$uO&7Xzu_TJxu+w(t#7tsMg6r6#6c9}!a}UVl&NG&Og)HXU09^Sz<7li~ zp{cT-i{OZot5Cw(hk}k_Xyt){HaXI81%T@&X!Q!y2PJG%Lz#+L4XQCLYgA~|JN+i4 zrWOUS5;@G|CfpfR?iToy69W1#Wr>a>wx7J1e?o!88um3v`f$94N9lDZvY-%Gm-YbK zQcaf=K5oEy@}LO9JG%X6efsyLxU@e&6e#CabbGkbfQ`2|qCn|RP}Y{fB8eJ*W5Qlv zA+)H_`;V{3;JA*?s+bLsx?DA=eUi^#IKduDIS}lX`kqV&<9-Q>nc5qO6&W>o{xKgi zxx<#+occ=y6fy5!(xKPK6kYP$Y8J>$SsYQ?(C=`S4k$ZVX7`<5gVAsR3 zVY8#RcI73!5eBQPXLpZ(-C@w`u!AD+o*^!_F`C) z?%O%#!CKlKI0x+dDOWylpG|6NpTjrz{7HqmJdD>wGAc3oO(KGl^NR>5KnIpT$L5LOaVPqF*Bs2db6z`^yJu&*# zipr`Hy2730d%p4R0?XTZb=e*d)YHU&ojMM-QD+SjVt^;=Va^K_On>E#VcYCYUBI6R z{UblvwkJ%2rH^-yB~&C|?x&pj4*)0d>0w8`IW9Z$Y7SXZbr6-2XFQHfpqtqA+KA>E;uo z4%p&Zp#f=zS;zz9>`{H6n2OIA-pFX^rzi-ecwhXFe~z==S$ar;pW2-SY5w3G-6r3O zl%KPg!d|T=b)afoZ(KNHq(|NK{PT!=8{w6D34pi~$+u`x6sTo4= zBd-$r`MG!yMS> z0($d%Lm|b9w1>9k3*-JPh%;z&^9*#|KE9@5RR<6S`0n{nr$o&4aQulKYQ*!$iXeuC z+M{IYZcj=EwZQ!XpZDy}4Fu@Vpk^Q2kU(7-ZgaHimr=0vtgmwrES2LNGXg_k*k$+$ z7S?|ke!F42jO!ugxJ`UMB0^)sL?{fc?52A+o%~OnrHR}?;huw<^6w9JZagx}fOXnS zd(?cJB9fFLKH*(_@1(3hB_3vjXunF@gZu8z&zBAFK-Q;|SE+F6DrovpuFQbJY_#Dr zP~fsTq!u&^@X7u$Hx4Yra}Lx37EHB(uq*;h@Rk2*75ga26uZC0L3izygN06=FCZU{ z6hxo7|t?gw^+<>((8uFdisc0zFrSe^o{Sk?O0o7SW&QJvLq4jB;xI_DlbVT zye5=-*Yu~%-pkSn0~Y_0kh=mKZE!I@-it!Hu{{ZAnEv#Hn$QYM!$A>==fo-CXgQ-6 zX>fwGgq#e;g#*9U0l7v-4V~YR1?eh%BV@Zpz=s$A_9|J%{S?k@*Ip*@tz_0}T?QNW z#-C_ByEVp6x9>joeULU2jr^o0D|?o$r{` zfx|^iyV*sF7a9+@emOTDUZw+udep)B-90WX@fpfk)@#+NQse&X-=xR=Re{W!Y`eGI zrFDvJ+=3YxVHyuqK7g*{$Cih&MIJxJRgm(W9InrTS&H<5zhH)h{ZV{wu}b$fFtig* z?Hb#APK8+ZG$1f>g-~-4V{$SWy*Q35YxKawBi92P?Z2b($I>3}5}ZK0k8`H+*8g8w zP9C#uYJRW0YY>?b^2K@W{0~n7Fw( zNYYHC{@o-A8uWY}R2~#Jk`&&Fvm*vkq=kg@w@a*@6+jV%g>6g5N2%-Y;nO6XXn-H6L&__wJOM)qFckdH+R1RdSL11x z8%2uPtO|8Qu+Su?c8HJRMI%f!*giXnunoh`GXmwMXq@b|Dqa6j!NBkx#Z0sII6jq* z2hb*zg}G;FKIX*SDfG3n5Ann0DcrQdsF&4_^Y!Yf*I0Qa`3O9#z|eSmhlyM@z;3n5 zRE;6OVNndi`FszV#pgcOO?34{mCq?4nskWv!--rR=rBsK+0%LU8dTtGJXFEoq;6U=;4LaGf<^$!@7G8Hcj zZ=g{ArELv;FRU<;-?Xhdu;pArUCFop6Pag3SRj%sE-W&&=}v0Lr9(IITPrpfWLy({ zQAASLz@DsyJYn|g3-5GU3C@LF=&X2Dox;JRHb?ikxI z-%=|++|f1)x(I7V>TtB0f0Ts@CI>gXJ#@8*`)Bdyr`?OMaL!veaJ5E^aSJ`XYI_Go zv4YC6$?0*O_ptfTJJsAcX(bSIc`V=c`psXIG5(4xn{aMM&U(2Ss!fr;guyaRo@J$p zT_+JK=anLcI01?9OnPg{Np%Et>MB^^$21TpWoaj#TVK{^)w{s9C4mckFf!~M2T@!P zDY@|(t%$}fypO>Ui#*dNDaK9tmuG3>L6z!vvN%qVF4d6agt&`Ok`no|DHe2JGXHcN zGQ86_!T6tW)EdBtMo6UIYHdKS`cVzo%F456hqS=x3}Z{BYb0UqFrK(2j(<3^-x;mu z<;PBa{?cz5G`R5uNO7KTsDls>LRKjO({AMvYSZUbG`oW2rU#wK5Lko1PY(KY^nxaD zaX2^-mb?r)Jfr0>*uT-gNTQlXOsK4o2Fvp`U^f~(R%m&Kk8uyL@{9h@@o8SbzEJh_ z`@0o}`&IggYKQd6--%aZf<-64ok3N+z=JC4#zUM@Dt{UmkD6)XaaHf#%z&-oyP4da zc$ks*&`?1OuhaUr`DXta)4f6C<9`B$Tdf)iwng5*#$94hA}t@m7Cr6~Kp*Jel?86S z5pnESJ32+r-evekK&y?6s@Z@tZ4Amgg(OJZB$jMzrNcL$m77ysIVrJ3M&)@Vfz161 z*&-HD)iS6-xrrHP&x?;iyE5V~z5Je8dABU;67!11d>pWQo1=0Zcf0!UeESqgKlary z2h0=DvGutbig|uQ`a>9d0#4zxxU@4L?-ZWKn7w9v`SG z<@UB4C`vJMh-&R#WJkV_i*I}BOMj(p zvSMJ2CZ zY_k>eVoYnZ?Che5*5>l>-^!_fo;r>pWBleDIog!^N7YAE3qQYd&6io!!(I zn;5TwO_lo6e{^_`7X9vcbaovPjHr^putz1=PE82=VEHk_TMevT*Suy2BVyjOYQ_h5 zeJTqm4D>vmz`}XP6`@^shUqgOoiJ)F%E@v|GhY1(=NkXlOEIKIpX^o8xaZM>=I}FH zgJeOyf0OC##zoftCNv&fq!68m+O!AC_uA>COcb0#$Wp?5&w}nIZeLh`00X2Ur=@V% zVU3Ib)<_6|8>g?N)~Ehh|GbJlnEONQ*V zsX?1O=^70tOQG)85p?CyE)>^&JgZ_ zl><9FL25{&_EVVj_vlt6XBtM`5R!goQC;z$im3ZZSJ$drnBazqsnhfN&@prh$_h51 z!)gYJ?rrn9+>eJka$Czvi2JO*4Q+BD875}*6rQr=78tG$+zi@=B<>Wwpgt-YfHx># zaNVlqp={~*=H6Y6%f5UC6LkspVz0SF0(mcxJ)R!9mo+MBA9D*&Ch~~nZrDRN;-l}Bb-Q0-BLhb?>Eb;EO74Q0@+38&?F{b) zm7yK7vp17F+E9cGoJOIxy9^8EC|m&@+Kz33?qI-NM>UWT8U~k!5mTZ4=ggo$YIjPK zf+J6^Yucg5XTT+yubkLHm6*j0Y>>6}+&6pFgF0Fx*@yFVp85u5s?c7+n)vL=qCF^i zr{RiU8pTY+Y>JGvBs>3@I`|1AMKn}Q9TA%SH3Y_smxWLP?A;J5DhfAA89Wr!czJH% z%E>Ea40kea8czoW6DG=quC+KVu8?GmCnPxE1ZDz(go3ZNi_mF_vw85#=+= z9}k1Q)GG`&^ch>W9f?J23V*YvnMoT*B#gj$Y~o90ur5oQoS1_2lvV+D9y+Le=o~$* zbzC7`I=6Nb<97Lb$or8{3v?u>Erz?bx&7Rr_QSmqvR>$`%jUqd>IM$dXxjN>%BTLy zhOhs~Bo4hk-kC~JI@$>XxDMZ`R!$fQ=waPnlG7`ZY~t z%;OZWT}O=o4chOpaR`{0Y99F#q8hwH?sAbQ<;NP>IbK*&gas#u9;}-38@H#l(R6-^ zIH#pyWE;pv967*A{4=QoTKJE9P61)>ZR5VW8Vc;Of+~O>B35@cd$O+R!NICLM#DTX zD8D7~`>+7CRwZ(9j`HnoXqsAhl)O#qGJ>9!630Tb3zVBv9x$FGRTQEYHxWMoAU(3Q ztgU}`vbfq)fQj-wE~(JsnxTask+KahQMHeyG@Eer_vHG@+T5Q!S2HAqT_V2BCxF?d zLT>;s5wAOv)RF(mft~cTJ3&Q`PY_m#d|RfnMb(U#vCV5ICc2s0Y=vKVNIPCRCl>lY z)j$<7)^hB#U7P*G^$?go$)AhCC;M@7sZ3yeSO=k}{>?J(D_1A=`K(}{b5E|@4!e>A zO(!u&8q>IX!KJ$n$|?+@y~xi$!EUb(8!sit`xUD6l=(RhEWmkcbJ%zno=`H+j8T?( z;Y$2xgPekH)?i4bi=8+?>>SK(ITqma_FRLm+r36Hva@8%Ff^C#ZsM9L3(PUF)L=u( zpe)(&DpSKv;{T~bID-c-L386npvv$;50Ui2`U;C1TrAfOVG5)^MEq8W>FOi(mLxw4 z4Sb?q>u+oZ|1dAapqD}o_8^OoDIKuNh7EAo`;~woiZ3fYtttUfjMh{-Mvo~$%uNHl znBYCDPWGry7+ajHBt2}xHD+;{9f=LdbE3`0jRh+fYQpmPG19|8s`gJ+@c5e~s^ULD zbq@9yXMp9}*~#Q^K2s_Gww9Z|Z- zw}hE|K*-WYy0jXa{+&F)`SlbFWqEq}vlSB`Vf7sqjx3s{sKm_s8dW_yt?V4#1<-ko zznc>aJnc%BOw7da01$IX2Wo1?{74N42SuMRfXNkKwP|37i&{g3S}yCGfIVvEfH4x0 z$z$~xIwbp(tZC55-?p(1f<5dgL%tybbqf{cdkzHUX18j zUVlQE`5Y3$!EYaPcVO?dC?oSgu3N)#a-m~iSl2Mqv}xvfTEott$6^gT_?w76A97-n zs2H8q)_TsT32J3yMcSE&q2G@zjt=Rqaf2u--MrRzD&4yRnPnn%@;P@eQ37)^|NrW6 zsED&>PYK=_kPW2Vb#+2#XZWxY zSksk&XD4O+{*!~e{_97@cS;0c9T$Y|=G(u|JJ_z`U>SKP_8rLcELp(%abo342cXY! z0&v=JCv9lJN6i)_7fanH6KZ()L^Ko&UT-)2rm@y>hhEcUuG6pw(rMlW*F=sQ9FicP zr|J3aLLB*=r)rF8;Z7Hv!X}*|bGMc5z|SIsv(YEApKvBc0tH5ZBYLg+!Im8x=m4r3 zqP;_Up~42{t0GmrEj?{>u`m&w;C{||&y83^ug?33WA1swxYqni(Mbk(n{iv5Zb;ft z)As5QG14;J;9K-Jiwuij=`b?Fb-S!jgS?XVX5Vdz7fi*!o=D9IH#64|hn(z{I6ltZ z-S+E)T`_tp5z_Z+8JAa)_B846;d6jKJY^pOr1yxAo2#AjTY|!fY2Cu=9cjee)9cL=^aDJ0wpA!q6T+y%w;o!Lo(44o3&i%wP^ImlS^O93NkURKZm^m`{_@x*6 ztZ%<(YAwAZbGUrvTJ$l|7JGsM3sW}IW3VuVE`*0~w2Y?NCBL*@V1*~0bcm54Jpe4z z*!1Uk+u$lNRus$JLF|TSfV^!VaHK?0=VT1R`93w6$|EK^|AQm!yl}+`d9!Jc(1a>MJuJFJAhoxWvo6wuo7K!<9@zOz0y$+wdM=I{fyxFrpg06 z5*g&_VI<%B(Q2InDhcWm$NM{qh?e-+jvHvS;i4mvIF}F4X%JXwFx}j5x zgCl#MOi|Gj4#8>`uw5Mg2aI>RV%qd-w+No#rd@cTCc`HS4-v}SuLDC-e;y^CuPc#} zK#`0^^97PLzLv?Oeg>CGl^ldhqkNkB$hmNI6wc$E(}N?XOG|L@>Jc*;;!qRk1xGJ* z&{$971|~EuJD#oL%s!iN&Y)%g5DF*n|EBOKU{Z0zmnx#q=1%!_%78jiU)Er_Gv^Hj zoFuXjLe_$PGdM2d7r%r*H2PKS)+uRB{n^e$&mA#+f33jG=R_Jf$BqARF2zzsPcm&D z96FWCf8YfDh|jzI>VrTlo7&xt&|pcK|9{K_=46F6)g)@yP8DmB-8PP1#7u}x2%nk~ zOMqt477`6x&dbvx(`!K&7Tqkz6=(4f+inz`X$#<*o^Rpx9Q%~_;B}reZY;>!_P&sc z)0-8G6Sn{+olB+H{OJET<+U4uv=cKYpsR-KKFq91oFgr%Dc;gb&Z0nBUjKf)zC!m8 zHhvzjo%0Smt--sP2)J6a1@UH z#68`A8jWu zRTDfTAxH6umtOTLn4J>5_QkF4p~qz94cNI#(@7Dkd-)HZR)JU&VtYdvKA?vS)_PLA z7Bz={ZErIS@6mRPR4!Io0)!F69hr!vs@_+SHfLhte>DQH(ECJ+#;k0kcs^Er&&ONZ z6AZOV=v_e(wVPZ3MYxF&-IuvcXyw4Yc;OJ1rpkd#WQ)Cd&|S(61H;Eh-yG|HnciP1 zb+nL0&($O$p;p`m1e6;$8cNuF!N_~IZD9Nq!ks9qp*|T6)p$|Fsk;W(GmQt_j{O1M zxapRk>SYg3-^86s24s-7ml+f9S{ZFtKM*6Itc5oeGFSFpJa;mkGY<26DeU>5+EJYP zhKvp)O}Bjh6?9y_+?rsX3@Ml-;aMA(6)~f|FhtWrt;0y9g8i88XfJgwe$q757ahHwG&Jc&GmkxGl<^89dU88_9LWSm5rj#{kMr_ zA%7B@kK?&WDIeK3DE-Q5&nCofauLS(@MAaPa&Q`03f&#Hi$*8fC8{7%BqNnd=%8=b zB7q~mp*GCOgPdptCy~53_j&&SHv-m&jxb+)nNz#JBICGQH75VwT8N$Jooqzimv6e| z7--U?BX{Cex;@)tYUKzj*r+?ecYEz$W~4dq`#A+qlGh^G>)@0iK~;CSA#wuoHk*=b zUp|CK10aqJ*Nt-)VS|;4!eO}`tLwNlJ!=r;UHsy%IQiLW@&sG@lYC?!b9!V*;(w+= zKTk|S_ggr1?g`e$brKom8PbbOarQ#Pj1umcP2tfwa&QzQ?TKzf_KNB^(jVVt?T(eac%+(8yaz0=%}3#P2ib ziFj70t*?AWk)p*dyq7abQ-pAS)DKl)qgmy^eW<-U+rt^SGa1Pl*lT$>YvYI3aU&1F zP-7fzY4H8eUQ!H{APQeuCIS}4{V_xoKR`(y;hKo(M+d<@}^Q6UW$43Ts{r9MArj5|qU zU686sr*iEM+B{{qvMr^BH85QgXu+lLKGOnH$fJ!62S_v{M$t<3i4CO5PsZFRkn;vQ z61it@iOLV&f*ew7u9|%29tBV+h(fgwSUq)-`WErT>iy(>Hel7`FcCHxaB=nq)Q6Gp z_V!W)-oCGJ^PWwg`wL^Lo@fkIwS-@<%j2feItfv~-$h8{`h7B>$Nc0>P85tk#yfriC}mU>Jlk}9rKef3BIG`9Os)f=iYM5wkZ;8j8RkMY zQ5E@2NJzQO<(uq##qlh{F)k4!6N-@Mm`;ZkU-`Ggg1#k&h6Wt0F~iMiI0J_-G;pt# z$0=~cM!12iL@EqwykLSdHrv`IBYlAX{X0~}I*5&;<53_{3Eigz(DnObGLyieWga(0 z#LEfpDIP8|$?E`NL#ngQp5+nMB^%(Rw1SE?;-rKptKxU6(}3yKiD35(XrU)V42{Tq z4O>w)wF0!L>Wap^fJGGYI`p($aVre&rlZA}VPPV&8sPI+*%iMB(ErO}0vLE7A$H7A z%F|(>Yo6zxF^8W2g-nX+iCzP9)fnXK$c@x|0UH^4+h#bAj!nZ1Em+HZ^+`Uc&i%n2 zuNJ(Q2E17!^>ct3Y4T_S=cQEU8l1o4eg)3pam(BGhZjJ(NQB;GCp@hUrhZuEs=)(V zt@maoz|mDgqjP@X2-E~?F?46zn!;xI>wSO!uc9E!4sERcA6M@kPv!gnf!~Kh%3g(R z85NpF%Aq5nvePiyDaoD@LK$U6Nq8ncGosAwaenu?UYGCV_xs)d zru&?8kL!B9p6k^HW#UZjH|RC^Fo5^qIs-@R)q{X#T>^Xaw$u$wlZsqSqxfgVa=_>p z1!k>t3(PdF>0U`X)TLEZ+CA6~P(G%xhIx=nq6y?>(9WZyyr%+sQ<@@A>MBw6n(h2I z>CcS7SeVoNE>B*^Lv_qB;((dm3{4Q>8q)!LtMM6~1kH}ZSy*)TK5Wft2c6)&&INA? z)8jJ>JaeLdjZQ{zC~XVLwY;%z=Skx)Qzz04{X<8epB8)lB;wDz1JyML{I^mT z7i87Uf~<-6oi?m97o;~t(TCTKqsTlBQ-`mD^E(nMan}x*mEvZb`}Z?ES%B+d* zQ$>rg{I_D&!I|E%hdE=85GJ(P$h#J^Z0;LYwcH+0`ovMxuk^;A<=H!qhQ(ZO z?}igKx}=?vuMsxjD`Vj&k+y`>wiQAOBLgLwp>7Qs5iZB2oibD|%5KCG-1m2k7s$BU zZChHzK%iZG8WenchhiMFt9 zW0MHd?i%VP$;EU$7CU!pi9_ApuRfnFn!W^9=(xViZ%9trZ>fFjszMqh{`t>p4CeNJ zi0My082i2vlw+MbJGq4pZMgAh*VH7|w2TI3gDgC;4=~B5qOR(X zWW`E;sn}KfXkAEFeQm~6IAzseAT#3^h9Ik*OWLj1@ML-m*S1hZ!{1^aEHFZU)l&KWU{1 zrL*LfnS@fFXFU5Hgv_jI`ccVKmmb0|;7lMCV2`P4?z>xGd~$EnKS4BIxyp&o2$OV= z;S3ybvTvreBJZg~9VNqy8D}k`!n+=M!n-qLIy+l_`rkW&KG)Q5$N)XVF^UL%w7d8^ zUbp@Pg29$+c4>Cq^WpYWfjY*_nLM3Qoz#fjx~WOF>$0vVOQl6Y=@^lXB=(*i^N&9- z9dR@Xg>ENj&P4m=liV$T!kl(hJo2ejkE4v!uPGD0ohQwqkN7WV)zyq8GX2p4SB5jT zg4eTYR=g$1B}scIrshXh7N=c}b&Kar(UT_yud`|&^vEr00X}dBmU343a^^&d$#?`E z>-w38tYYP%wxNvycbpa-{Loqp$fMFU^ZZVgWhQis2~8mYP*VQz4-RvE1`_M8|8}m< zgp>ahCGYRquVrITY)i^!5b3mB#4d4KCZITIbVvW3?-biR2r+SwewO?BQM=exoYXQ= zTYLMF;>Ug-!`DTwA$DI?T*w78{Vl>|Y(kf-s$T`kqna5A*6pWm-YxQg{;XWZb8f+> zVP&rxP}z$jmjN+iJ+&EBgZ>JemKc0B>}heyqYd*^N>fltQP zA$C8q>=^x#RUN1@vol)T^cR{bo0&MZNpaT??ix@px$K~m7?a`}eS^OH#nqS8x0!pe z)~NHh1U18JQZ611$~&=MSyJ#9bPP6zIL3hD$BBE;%ir!4^MLU8y9$nA*{PgT(hkflXI>nXqQS#UBBhxc;Ew0ITK9r{RQMj;CBKNN2zdI0MLozHKu8Hd zGg2DsZes>WOGpD_4&s3$FBD@dN$;Hp<;CJe)neKE=f4^yGvBX@0u-H)pYqpRMsU5#{jVT^wd-CKZ| zFMcRdl?FY1f0*lUKv+<@Z#Ww%1`m~cs@i+G_yy<;9@P$nckPKJ?>>=ED{wr_uOD+) zL|D@R3F)gBe1(1rl*Qg&U6;-pv}X?hIn{0Ho9xkXSGpC7@a2rxz&6K0)~@b|?LhqS z#XhK`UJmcj{qKmmIFWEOn|Y|j1v8H~`L@H_O408d6YsB0g}?OFd*l}Pt=X^JZwLU$ z@H}QD^Q_mWiw2?GgeeV(hqir}yV45ZSl_T2=+~QLiwNvF=?)dDX#X-23JOZVR@l1< z!o7CZ|2C?6zS$|-A|O+;XBg6t?M+R>Np$kpIWWZPZ%=q3E%JW5Oi_Sxx-Prv!Rq)8 zD;Dk`7vAeSA~->0Sntbp*REw;T0!6S)zU?QvsQa&_mxX2tvRL2AO)F5B^E(!KN|U5 zm>Q{|8*_5=A3%R-SoH-pn@Sui`fKv}wAB9r!Mv_Ub~B0A-oKhpDTa*V&~OV2AExoi z58E~bFfvVp!k$=EpCkBYG3(d(1^jRRTgd0ruH8^D#Fa%52}0_>kVboAQF$i1Yrnnh zUr1`P+ihd9vQ-7dEq0aDm&k{L`T=kkCFf(wot>fDEds%Y!KQSvot6~Ea$wi=8$qd3 zHRyXCnVo-4me`}tbS)hMPrhv*f+&Wa3FtCKkL~1dHQ5f-)3}%$^yqXl%7}zL&HJHdbxbe;wiHSVjeO%jL*Wrk6O2`y;D+eHJIJ~4LZZ3UAL%X_POPFl^)XunhX zo2zmDrjL3yq*YzQ(G3ou!+bL>a~=fpQ(mJY>Q}QaJMY%GCqamMnEIi65=}$N(Vdm~ zrM*{=6g@J45>;Vt0kp<^?{L^(C|ll(;Q@D%95glMXK}WK;#K=f5+sz9aa{5JkwB1D+0SM9immgSbJ3V({ za2bDF^b5d+6tp0NIBLOnYRdSKIyd>=C$K%c5CEu+oX$S;tm<;}16iDgTrpE&MLD$} zZ=V^?KA4<$E^6S4*r9CL6^3MhY>g1)S5RSeJN#!suc0-+_Q;*=7OokW!t54wL!7U+;cTTFAOiA=+b-Knyk$O9AQ ze0n}4USH4N+0wVo+pe+>2zky&juhUzA=QUTaU zw!h`i8iGx1kOnPj;V>gobbuQmU$?KUgp?k8*iG2^jfciHJ8$Gkt9}BWP@Xm%c>{3@ zSH?IA@`qiDFer#TU)3EZI|ZQ-Mk8r40%YO{x%}P&q$nxW$;8**UEk!=^~oK5ofzyl z92vM;I6&@JYAbhM83L=?SZG3G^*d&CYt`Tu@h86&qABKY^L$b zTOY`nZDTAfD{PkH>1ka=)g=o*HFlS(1r52 z7vRQ~jZnw}!nB-C-@@hXlXDsyxR}3RithZ{qazK1HWP*dMkXE;U>-fbQI~>?z`0+lE>*&erB5iv8F?g zQy4I9ahYIPb#@-=Btey$tYShu*wh{*1P;!N%Fdz zd!yN*fr{?c8&FX@yC^h`WcWK&QOMRru@R7KbH8V`T-(&kV6MPXhw z!AOPEiC#P3a;d2gBOx_64VIkiYI3n4H~Xb0lD4Vrc+-7(6k)*ID@5LfE9Q83k88pu>I%QcZNLLG9G=+W& z5m`Dn>DaLEw?#18?Qim8ZZ6YjY6nDmbi7@+u44tm&cfTh>$&?$vH!6Xm1_q*bE^1e zU_}q&yfWm7MMxzBNe{OEnk#fi=_cVgZaBq&NM}A;7jVGu-J=bgEBE@YZQT@yHhJ1V zAg4QvSnA~DKfgHmhi&!ojN!obOzN{dtS!6kOG5U)_=`J6{IL1e)sEs254ye=f};OG z^F;d6X+G9@^j$gec_*#B<9Dbx3pl@HA(D@S@lr|m$eX0N_+7#TjixjI?|&vb^Oke| zOM#qum6NR3RHGW5GacYw@p-#Qr%qJY)eFGBvVgpnuVyW=*EBb^L`1dZ9mltCl>w1R z0p~Byfw$<`66wxwKd~4WXx$~a$ch6Ldi0{*zH~@e#_nJ0W*{m9ek7_qlJ0GjgkT5q zS>3!WaLBl)>G88kmVD=^>Rs0&X9SruXtaIQuo?OqD=PyWpS%76yvV_5V~$gB`p%2} z;9)vEwaL9>>(Rgqs}c1Cf7WuYt)*$@t==F!VEo;Yx&PY#yw|P+=8^%|O$jar*oUzABT4o3&LSfw=D~;KSgK@RW!t2+YDTS(p6)ka& zJ$uZ&A*pA@F^JUHC?hw_Rx&+{!*+j1Waivf=c`{z8AlJ?%=|a1{QIyEVBTTh0<^!7 zwx;xbIKmkxh8@(okf_XmfhFU@C3YU#{XY+uI)-#XRYlXcZEIxyNB^ zb2clJoK5#H7)KN=nm-}9FCZnI)HIo-@SKD!SKb>INzvhCA6DpYm}a~AK`@cDflgw6nk;aDGa|$tQ9ePjK z96MZ?oB407LYK4;jbBfcS9Wp|YKmQ3pevGp;zKj{rDxlh3^Yd>eLGDjNxN9dePLU@ zo@D-#`0bpp-efvI6H)y>MqmDP)=o6qM$!1cUn(B0r^F-AOu3kSIN0VJPuaH_DaVzf zHmX}&zIzv0&Ar<4e%M?vm9k>Rg0I138YA3jpTvRZojR}2PMu!AzLBKX$fHVxN4hj% zt@5T#`rVJM>GAo5rW?(&wJ=0$XHYinY$I=C(SHTNg;@T{C?4K#x$lm$GCLQ4;{N?~b88XLCFsAH@@tzjhVN#k zY}jde`HC#HS@HXKy4%D#Gfj`o%wJDCsuSKMEk%EszIlE;Df8Da)#LBNjqEI<3EN7` zOey8&Y@x(``{?{)<>;@7%r*O1l9H8`LoU&}v#c0%+gbjZm&V+*8MhuKKgaTl0LWYK^5gBRguIkj-7G|qf`cS2;Cgj68a*3SeX21uo%-2__B+J zqC+3h@H=o2;%!K+KJ)aE_n2cX(u4XC+wiP3bR!yOX{^|Wn1yY0Ac_(c5tkj-2MGYw z?ZR9N_l6nujRwpvYzi_6s&VcbnAPyuZRzz_S=pE2GJYH)Gd5$S z4RaVY2sq!coJc1qo3!olegjSjexJg2u z(;n*1k=1!l`X^64h-B+4Qr6NsWcmGj)>)|%)a(iK?uFbMy@oC5OvKay8vs=1(8nJv}o{&poDZ^=K6S;EDs(Y_iIL0FG3`FN{qDi@w+8Svm(bh>+@WfK zsF+5#S9?(AFZuS3Jar#$2qmhY53knpOnAyUhvwRaoj6Yr$ufw%y3z;KyohKn$`{f8 zzYYZj1cp|j_`;jJ5v9O0POh3nR>+VyP><|%2<$%@kpJ2%qWWmX3Bh#ttzN0scBLh` z{*6#C+$R0HOaY?Ed2I^O_!;_Kedqxd7|m%n)TQSvTi7A7nj*8QRM}(WsY_C?lD$nu9Yw` zY=7C^sZJ+|{^k%=U(kf;Sb?2b?*4t~K|0kkT2x*+-&sUV z*V{`tQD@=6A?N2uQH+jUBuX#cN!|(l_ZGQmyi|x)Z@_7^mhnNDJ?Cq);e?5XcNTwR zm^0U^_~?L#^Yx06ADGFFpw4Y{kWV*UR6lfx?$$|LNRxa!D?q#7*_?71DYce4t^+>G zm4!m>psatk-U#8kyzwE!jptHxZGp|@2Z5O{4Jjk`ja~?Z&~-iPM~lacaj>kTXmW9Y z`Fz)#W~Wpw{GJLd4q95QLy-Nku(P!pmH}Nnmzb{@AVb`<(=aXy>&k{W^i1z4u_u3B zaytr{N|ACyiLL9OdcTQUUR+$t*5^48S^Y6d|73S{q~BWqkm_$=0VZ{&6J_~egN5Vvc$4U7Twi1{D zAv20(he{W}G+_hcVnU>rOU7TKW3pnl0$0~axBg~rCHeKK+ebd>+x=&!MW>gr^+kz9 zRj=A4I4`^vP1HF>XP&zA)+9mD$_39tygYW3*mwm$^C_#*n0*L)pxWqbc-WUwd=TC* z5q-%N3LBmKCFN5=MBWe(%=zDa{6884a)mu6@J&*Kj9Ud6-Et`G3pF}9D^EIu> z=ajk{tx;b&HVq37{QloF%1mVxy`kRBOck561)zuMppgVMcTeezVySx;hXenz>a_7=2gv~Xq#UU~=jWK@X(kxr@R;xy1dno&9 z%n@k+d%(4C39}@RUHG@a4p7rDiby@J%-R>oVliD5k`A|zcEM*2AL^SEsBTU(0 zJWY7#b?(5=opyOo=yo}P8taoU6H98OKm0X6Nci`+4c30vF)j}lW^s>YOH=T_D72Md zWkDnLP#S6+LTAXz!&D*V_U`(U*8cuJ#r~yuY~3n$aYC-EMG(kMr8vYg4dz=k-REkd zWGri3KJc|;>HhB$vmaHMvN_vA<={-ms;80H`W+s}X{2fbr@s;uEijwona+SFC6~9RMOT zYBBls9X8r!IU&S8dl%&ueFra*nFgzYnPSvyRjr`S8rx=ppD@@A)zV!%^8anVMQ2M9 zN|oa#VPklho~gOj%-*Xg{U3U}`QvZ94)U;~Lr(p=aBZCigc5|qSQ}GS@+8Urf%47; z`mDr#?9AhbvC>E0rd&_NPReg6^s1WS3BU@g4DgRQz4-IvKnXJ*)Xc5P0@+}gE!pmn znmCfS{N9n_jNHnnuJ$bLK~g2*#a!)9zq9fk^Cd8$J;FI~2({I^38*K1vhZF3t=qR9 z0LPGXLnW}_sWr@VCkU>&!y44kzNH7^hx-}6i^V4@F=#kPH}{|Y!cvz-EdZ_kFej`ttK;SjGt zf?=gP8UEtOLl>#q*?Xr^8gBb6`AiY=SCj?`(-TEpO^}JO3q@Od4{`)=eP$(`HuKRU z^#1BcmbaJxZO%9cYDDsP__9$^I;b`tY9}im==sKYBVZ=#9SluP;P)OIG{OK2ey{=U zqQO(M!3;DFp#vo9KuA&9gO2S+njF3_?UC#@+AJSrAA&NuoDs#|GpE7r(a04zh|Gcx zpSL?>Q;2loomU=p!@ay|BX4xZ_OPf#orO6fB3c^cd8zY9BexN|uRT2FzTeT1Vhq)M zNA1JxV9i-H6!N!1(?JUrXS@vc1e`zfuqH|;b=y|*e-mV*R;HecG~({RSzY!5Uf*+9 z;wvQFhx#e5@b&;TMmj0XWZo3Q|4K%j`x#d5y~oi-4jp5oc#qUzc_4*ZMg|e9iS})0 zA#01F^g&9vnE&}>#+sXe%UQc3*8)r3xv5n3sez4aw5av|kIboY8i?9kc96Ym4 zLt_y`c2WzBw#`LhpA^YO8O;oblp1#fM`{-DlP3Ue1y`|;)?&;;Bu z4aRIx;!pvz$_zu$1I%KXg%on|w+F%9*vwZA3y}3_+eqFC*l3^5G_uEJ_#v4ZZy{pq zaWvwiwvjfRO8~f|@|N>dR9ZzqX!I&NRaO$Oib-jw9$6XesKM z^yG?_)L$q_N_H;LPzcT1<;7{QGz23_<5&p|RZp~rgIA?`2%%sc5)L&0Qp8bz+AAnix~(0m*>tp-Ttyi z{N~u!5b_TRjyekUI5>+=(SU4l=?H$6G5?T~aTfuL1|VkNDy_!s!YbbgdK0Fr01?ru z2Tg!pBP?G=5*vCM24&n0iqKt!!=A3R=OlZq!oIBsAq8{!2VK~t_R=Bs%y{0LWEPpP zn{rfh1~&YLnVd8@!ma=2U>^X=-gHnwq-KJJhdNJGq43i^H>n=j5XSIs34W(3y#v|4 zPA?`3ET*%bDjFs`B<3!LJ+v z0OWn>qe6lq95lA)D$p3F1<~Coz}{$K7BaZ?s>0yu;pV-CK+ebewqHeEQ5+2g0d!sN z)G{x;SP0zZTi<2yU3!paNgs=4r#Lj(_mexr6Q9u4?QO%pvcHRtq3oMOG-!5cfS(A| z175y%&(o!!{{b(-yBEBq*axr2Zemz#vSSE{VAaK_8^K+niJr=n5SzCL_WX7J&zLf= zmoLN8DxWpSmn6k6*z;e!SYuoMY&m*SsF26^C_YyI@OLqr5wWc!FMC%WwKkF8%cA)A zT8R(wMtugqa-di}FqWk>RWLSjp-A{pYxAm9!?&vmxEovWEETzROXK&Wx|+Kl$;Q(H z`9V;>Ovn90a|h7w`=)ldybngL245URGSt1n1oTC*BgUMcme1N5%`nPYykWdiN4vM?$w(z&^lEa?itj*b)bx)OF4MoFS@g$OCCfOB#a6J1uV`$qm zU6@Py*|n7=sGn-DLny9pozzAwaIynD;Ue+#f{8w5DkWZbSluNGVP*dtfy-vTwGxjy zC*Q=VI`wbd8N_-dyO~MbGvJG|%1DxDioCKji~jKOj!Rm8KTC;1xd z4(QmVb9&7E*Mwz^nay1|{Iwya-0l3Z=hcTT?(BMJ*n93bQOd?~oLg7XQle?(<%ivS zg%U@N)38yOmpQ`4&yU_oNuPq1GlB(GwaX=siby`{Bx3WsZlO|QEKDg`e;kk@0f<57 z3quGlr}`i5`1`*#+PlThfJhtlmZDpXzD^co;&Cj%`)xj|tfFv*UuPk#Sf}-r6Vwvr zjh<7JLAU;!D+Q)BGbvtWd)$`6DMvD?oorIWp-2^%f&2k+RU$SO$zg3ryzepBK2ce~ zf*0is)krYG%c6_)(<0LCxML9vtf-b95ic`9ULgP1`z@MKW!A@G;i!282Wp&!`cp`< z5AcQoJmevgw_uY*aPOlxD_33VY*7@g##5-(7;_E}P^X6n&UXjjQ7j zkCjzpKiEkLhe#^c;KHn~`x`)pkQuu^Ex%A8Ekf3@#q0ts<;Q-Ql46H-gUl_;9Qy~t z_oJ=htaLi-_*-LPJe=(4Z*GOhu*PhQxQgUBrSlhBqX&WS7QUh3%5P~WlYr*qjsM-F zoEllHX|3VSiK+ndyJ?U^M96~%ziacCn~qwolRHpLnTSUR&um?G=I94q-)e20v<&%u zDN7RFp9~MU4z3_fb#DG*Zi~Z0y~@mB3{s&Q4vERUHyuUKxL*n%I$RrEIAt!%U8VVY zyN=!W`3}uk9o%O5p->Iy>A&RMB<6Zg5JsOd-UoTs)C43MP+YPr{h-mSy(vEJpMw35 z&VDog;aVm;1rVxEvD(^t7qNpho`b zDdwR#=n1WSsCf%)uQH!**8L0UE)0p-wj1Sle&FA8ke&I`lGl-nri7f1$=Pc2oqC%! zIsVl9{kO%op;v~EW=goo0HWC)Pzt&=8cZ)p9%caeOvCvnGtcIG$EGk`hv$m8+7flN zDzcg*b*Is+*Xh}Oy)O%rC2r!Cn+9EBwd75aHB!tYsE?egL+;~J8^PzkFl6=DzkTvG zQ61Dnw$NEZYsTmU3_2IU-DF-zPZA$yQ)!W<(x+3L55ZhY$Q>AMON&*?BB&5cIh(@KD^!Q@vplm?ws^4xOi%}lFq)L z28|Hv;rV%+y@r7&|~!GdAI_|MT*`pO{qYpDcs~qnRiiEBMZp z4L@p^aHE5iKW>dfW8+}a)Tn_;Wwgb(ifSj-@5L1oWxGGLt9e@4WkV0G6Wc=^ zkyAdOJyWfR1?}npOOSH?E;1glO2qkgg@w@cyME}=Ea&HwlaQm_oDMYT%}hW|6ku50 zc<6j2*o+&!$;2OS2zyy+hRV(4{^GzA3Bif&n(!J%;BA2p4le6}n6>t*ki}&Bt@&Xt zOt7*KP4k_l8fqxXBo%F!c5dDZx!Ziu?&=ooLs!R?6^O|4YbL0N)i8tD;d*#opZJc) zLm$XHfe@-f9**fO*TdY7bSWoHKe0#nA?J%8I^(tS9% z4h5Q?@!*YrTWQgN#kblhx>q0BTzd+kXGn3oT?I@4nOJ6cC3eff=fK)*Ix3fw!}kVM zVX?UNk?sd^S_HPsHa>h+0Ix|nQdiBXoy=G3l>M~$W;qw-cBW9k_q4ViOVGLwHW0-i zW8~GMQm9KyhUhX|tSqaYUw#49U+)(pog*UIiRmt-VA$Oi>tQ|0Ecr27rZWH z$n(+A_Y+o=U@PGTDeJ+?vOz;=!Ml+NtCV{4{1W?b50pQfMCp2lcSqmQh{jG`+#21f1z^5i$U}- zuPSurx`@Oo9G+FWT}8@Xyw3@S$LT34sWl=ys`N(G)-6oTzWGstg?%*OY}&H#UhZ7l zqfb)R43E?e!DZsqaVGL`|GlBJ7wQ(z(?J@oTfnzOk=w3ZO3AcC?65?Ax16`>iy1DI zJ0Zu3$`iBsjPPXPDtDsBajxm))4(%L4_`QTPLIUr78>^xk02N)OkNs#imy|bj{_E` zFoS2ETzyOZ-LCYd=-nOHhF3TquR!|CzoEb693rwFQTlYEzA+<$XuF5rTa(S;-sLoQ z!aF$~QpXSV5z~+dYtq3e{54k4kEAQ4s`LSL1T#+Zbg2R`yKMYI6tX zL2?U?Q9cvXV9`r-fCqL zqbC`avfUJP&~X3Q&qYLLuONLLMv=|cnh2{F@PvpTl80YVO*PyI$Tx@MH>TupxLtR; zbOE?A!_64EgZX&80DfG|61yq;TRedcKzkWjA#lh67m0153svU058NkIkh@z;M{p6l zB@c{x9bX&~0P{;p%j;*P3gnOf>MGR=3s7|+W52#d4c68zHjf07P@nHA zCaSK3?VJauFtarYs zkKo7K+X$KA{J?Ry$1K@6RZb$|baLD|4w0x=l0qv(iS{%LuIMUU@q zmY4$f4;FuP->AQ}f0!L*lGq!6UE2@wBX>&(>P59n-05%rze<@#($}ZcYLfh4y?a?k zzhj8zT8&;|f^UTHFMXjT=RG+^tdK=+dmE-NUI2c@`6Ge_J&H0HaMTk3A@)a0-Ao6? zEbP|)z)_qqS?y4H@(C5qTYPPO?q80&`pZ^-n*v*3m{@Hi^RPT>G!7LF)dLqDfNFJ4 z1s$tlz^=4=cgdRHMf*kKZ)|j752atPalOJ(nw?Q*g@y0NDzG(MoX9%*Vr*WK422TLI5hovyH*pLndqj=zy z_o8JPg3RHUb^)azV_IcP&$rI1nN*0);N8|RqXvKPP2gd7!*HJMoPT3M|E87=#;ki zKXP0*ZuI>-@VR!aMA@kMEf}-9+q3`LHvfVJA14hH-P77EHEC%NA7CD`yq0Xm{tn3N zkj2lTL)8Oe|344Ec91rX+bVC=iRDVI*1!<~>UrraQ-1n^Qo>+x$w`YtKW;vH3`s?F zX38n4?h)CQJN>F+)-7p@ZP>BB_Fy;GosQqi{cOC{=a-m8JtaNEXW0?d3#=peuPG7n zoZ)b}cpo7i6Q^H~@;haV(rqX!o-M^gvWlz3*tN8~yk%MrRtIh=Z6 zD%r3&dg}(X1dUg+9;0>BDm23khuf+(MA!(BjmHer9V)(v|+!P@7C#Q&|y{4nl={dhv2~=UUNGo@YNi zgfXl}=Ko>dyKD@IjY}Cq^{tEOA;Hj@prHX6oUw=;HeQi~^}LEXjGS3uEd=L(#xfBz z$xdd%_+7oFblBrpjZ+$agT3Xs?SZ54vZ^e8u9OUhCK^NJAb%?)r)OolBANtSEl7ua zC-!maL0BVpE;5@kGLh)e+aBH(@DURJ0vg#9J}t7cypu4%m;Wd1NtvVof(h-2DkB>y zmtlw8s!eFliz$zk7_OA^PF`QKI*j~7vXS2W9ezNBA8#{IZoJT1rSG8T!PJD)jUfdf zBv?)oN6bq>-FZ~9a|qNcf5{U|7VVXsvp_;!HqwH_ygxygt5K0k+aCTH;HY) zMx+#^ZV#`pJZwsnisa4>?2KMceiib8OOM0DSI9Hgoad3^shS@SK*Nphvi#o(vOqRv z%F~JR3CouUAHvj(1yM>!jqHM-0qxoi_-xn=FLW6*ckxG)aZVsb z;KRUECXXvf<(6Y=HHf-AV-o~D3Lv~m|L%^rXAsIRfP)nmpTS`s+*9`J^0$_L|9?m9 zijA`{a04QMeVUm(hHTtSy(?7)Kt-|^f|vFR4&2X#iRk(PyWm2OzsSsi3Y<^O1ZkAsK9)0h zhAYmmT)b$eaw&pbAG#t*mlX3)W%>bZkAUbTMLOtr8)LFMUjD+Nu4oE*;9RhuQWm_D z*D`^KlEZV`xo`{WC>;FTh3`wxu5SAO3#*Z*$0pFdU+`1 z`)>PBEe!fdC$S~v?l|A_<}jqp3BYv;$g)p^Xso-jAsNs_3C8P>nk#syQONCwTtD0< zF&Tz)ydfgZBva(zf2e7e$APTj(1dJnG&UO%Y=JsC0!IHGn4m06hz2C`jsw_egxnm; zCSA=d(2Bcfx|q8*ynU6Tcuq6UCC0I5{f%Pz?!c6D)B~NNDrb@CvAyFK``one1zo$D z6X-%-9ph)hUO_8{x$N+4@T+w}{;tGEGM0!e|M~EnPQz&|JztEGkYcl$Df8gX&64F6 zT1tlrhHK&wK%?1z5`6W-C93-J60vUWA1H-B>B>9eYru#VD$X;faq>T?Y?l8}fV{=3 z!D(N0)*9F6IKu&_Lu%Mlc++J`oZ?t}+|rt}pA8$x5S?pou&GOb@@UWS%*yS#W6%n| z;qZNEg5fec;Bef=>(YIEmMv3t$^^r+<*V!WqNhmrtxmENYqxbsY5TJ9kdb@p^Mss9F+2ICDFGGu&DABU9 zF_-s5-oO&#USz%EH8(vr$Y0PBS;nJLls8^jHz{#I9?9G#s zK+dAzzp9CeK5m-ajX#iDNbGJ1xf_u+v7-3tAKhX`5}MQ?LMjkE>a6tuW~rQ*j7He5 z0!a8}K_AYSYqWC&5ZJ{fS+Bk3$D0w3{Hdy~>>fB3nK#zmKtW+!MR>v4&Mq&AnB-f^ z&OGkfkyu77DSM4{g3DWZNSip={^S>w!`tEzI$~I#c7^pFWcr0Vz`7xrYaeoM*vn44 zJo3c(?Ooo%R&w=pk;ykz;#n{U+EH3k86}Z=4C#sX#v(_!aWx*F9 zMiT1-qgBgFJ5~t+FR|4OF8*FT9qR5ycp~`ry?SfdtKlLET|lfqx8-$2&L`&d+?Q%4YuUj@syVOO&Sjjdu1$-x{Wm^4KQi;Lm3z`g<7#hF@9gwxRk`-n z6PkC1UQb?};QTw(Y!jf3pkMtJgFvX#aMb1urSHLwNQUc690_q?-Bu1Foip++CFmWR zFrp;Qi9$pM=8lOIPmdy^dfy8muofLS1uE4r$S)iZgM#cmlG+UqMU3ETt2m7%9z>leD(|-( zGm}us3i}(CE_)CKRYg@c`Y?_=qyd*>x?)g!X+d$qVj(P6b6{(l1DswcXTs&uBd$oCZ!{xagcZ;^r^{8ie3-~faqE3zExxCuH z{&vU@SWowz0Q}+3Sl8qaKypmIXEjypr*Xc=7lsYgPKF*Zcs`tm6uwhdQ&tlm5+;SE zuxo{*o~MjL2O{F&Y|TTUm4zM;#(>5Jlf?yXb;VdADN|^plJxPu_eGmVH5iNPJqWAG zXwU`fyz~DzYD)TL=MU|yq4W%yRBelMx&xmL5I?yje7-3Ub}^N zgvJH-5+VpGJ@^w4+xuwYknLV|C_6hAHm15|0b%wJG^1x3z9YLe*@pqy5PGRecu+{K zFxd(JV!pU~(#2z)qCCUa8*lAdbKS7l-{)5ftJWn=@_{D5U(lD%M`h*}KVsh4HzAtD zxQ}&ajL##xgqwK9YSBVA)YJjjEzYgG`au95+v@A(HGag&3LWxy#yXr7?{D2icI`|# z5tZd4!W0>I6j9p{rwF*8jr+Qne3n)PeXH%SK%?~YuZa12?)O&Tp~x7XVW*NzB{^wC z50dI=usW!lp};?WGZdzDz2B*-@#keDWt=YQs^i$|wbvTiA?0`>mcV$J`~k{;ft&RS zBXum)LvC3FHst)((MfF>LO(}- zo?UIOY#C)W)f@lsJ4kQM8V4KEjLtL1H#S0c%4(Q|gIeiK?Lzw^MT{dsej!JS^!$+; zo;P9nCo84(S@Fxsy@g-XvOC6lWvabKg~ z&3;Tm?Lg#uk9C93vUXJ`4zcPS==i=I2PS{yv0*Mrhi>*iy|SHICFfOJ zqhlvu_a3{5S01T@ML(^O+(on=vP?`GK~2&z)AtH601NRCJ?xs*!3TXqQ&=xJK5ias z>yUB5fy z;XKEVV54iqd88}YJ3i@rrRM&5wO&5gi@g6quawE~2E*c!=YcMd`zhrh<}ug|L{(P_ zMGEP;sEcQt1v!mcz{?`+{JlOWXOFkgt+W7)<$@s4Us9&%H-Iu!aMVGPvOZFA` z>mm>~Dw-Tf^+Nsvg&CO8cwC0L+JDd*ngaGIA{w2^jE=2ns5;#Em(jiew>PRe@tL~L zN?_^T-`>douU{F{j4RVIa%ZKz?>IW>Kp}*{B+{kN);in)8*rSWEc0O1wfWz$c_^;o z03l#$UP^3k9<$O|x>S#BW4*peeurxu(dyfK$Gg>+T||QTt^$lbpj)At(4wat%Npex z@|EhkVPLAc8^*Kp;VKWmjO!(9VQR-tL8PEk5@zj;dvPP$xOd_G*xZc!h%5y3j!-@V zz3_NpsC%|dH$}2#I3)Q?Ctn_TJi_rr(>DPjrI=?-p0utN%h&*|(rMYR(&S#yB(> z0ZWE!mJQpad_Wn}F?}#@aI&(~P||<+4ZEa2RW9jcw_D+XrMHw!Y@Hp6PWENkWnKTn z8I3gT+VT4pFk|+AVpfOEK6NXzzF3wyS5h%#ZS(gBN)8Xk2>^=VzUupe>H`^^knRU6 zfwvd4=Vqrp@BiM!su4aGVn#+zpaYEQ9CTQ_xaUR4?VT*msZKbs6ig`R#)vP6w2xI% z_BOHa?dExRGb_v1a_MMv$usfL5*U3I=>TYS#d!0UmY4#`KY-;r1*VyYO&0c)Jt><1 z0<&axzkmsPXKTj4VV70O+~`Nu(z)E}c-ih-d-_Xi67AdOUXI4ESs)EJHb8>b1yZQ) ztXkEbM9@1Zw%35|Tpp$cm@`Tw&n@pu&#xvFNd9r z$G;q=0o5)x7?a&GDKf|oQwp5k{xqY`u*m@tY?Y#y>p(Y1Jl_EW?l2)IeL_ZLkdUP51+SMx~@C!dN${G zj(@gd;ops?S-02bI4BjYove7rJa)Nqt|#ISc*G_h8E$lIz4*5b1=I6N(ncH4oll&V z&)4?cF3mi2#dVuKiUiw#dbb5k{`8JO%EpDRc3qN< zC)ZgIO^C90{d*E&13?GERyH->m32MRuJl2imq?$-^J$)w9&`#*p7X`5HNWUSU61H* z-;xUsBsQ`jCTTeGbek(IBv5+De8fH!XJP2NSBq+piE3^IK#ZibP^(el$*i}SKUwEt zHfSk6bb6g5?iiA-Nw*svc*)dEwAk{K3m~eJsaLQ(x$}^_!)nj`harsU(++zegpfuS z>~~GuUy*-GeP5Bam#8~{rxlqYV5o2+mEC&nd1qb;+-U%g3rEIPKMszn0&-aC?? z&^B^{2D^>(SQnlXxNVSfIj>z_7{qTr#mu6FY$$f~iUflIk~hlJaP<)Dr#Idp$oVqY z#f@}@d@-}obnR!n3C-L4JP_wN;8Eao?Cq!+5W$yA?+qRYUwhv^@h2b_EAjx7&6`L| zLgJ}nA3G?AQapxaYyW%&DtJVTbbSX+RFDzira!Qp2So=Y&@55($zBiOKm?#dj<86A z$fL^kp9l=ixX|nbo90i=#gKw2$NykoB+r%`9P8z zv1JK4--3DFnJd9dkb(1Whsxq}X)Ps`b%n{Y{b3I^96ug9;Tcr|65jrOYSuV{loym* zeD_fb&2H69T+s&KIh@E~{lesoWETau(A7jhPY}+AD!(JH%1kzWw`6JuEA=r{$$Z@? zoRr)LeX3u%wGRUGZ^wmjS2{U0cOxB%z0?Gmvk;;aE?7~iBN(R&+@%`v{<=vWfD)z;{R~<|}6sn7c z73{(>oHW+6!3F+K>z2ewfN7qj=-KI(EO>K@qmeL>3`H8 z_4o`r{fwQAdsfQHndj4ckGcNe2T14+0Z*J9SbCq&&GvR@%^F0g(Eg=iZL9Z;?gdBH z;fYWHg%p`rBuJ%ft0R$~hfTWUlZ71nAqoU?Gq}yrZxXIYRKw;#^FIW^701*9l&lxN zGXMl=vh{yAB9obiC>>;8xBF&?N*Uz%M9+t%MU$-;hKeU8%)omvn3C_NW;937*K=Rvt3ihos4}PN$HcN+?#4ePZ28tW^a>u3@{0-Sr)~ z+r>M?_dq+S*=cwvt4D}t7rPn8M{zh8j9}*I!MBE=7Ye@l^codACatT#AqRpfBQ3hN zaH$@>2@LexuAU&3@w4+Ss&F6uWT2KUI!~_Q>GNupq~|#r0HlIbv$)Rkd?@ONa1J4? z37;A&+Ug60qdcUd-F|!Q*lH(m2uML%)D_cfsgl}gY;ibWCo7q)f;NfRB9Ob@z=c^K zG(3$z&koyo{DGuT!5`6_sjvKO4;wQ(&5f=PnE#h*Fp#S>_?686_($YQ!hgVgn#&zTqTqt6;2&_nbxidDoe zRHH5F9T!_r-gRa{o8kZ&>%38ql)99D+>Bh&-`@WZ!ZP{{$j_@A*UbC)ZV4vAkxsbU zP&!u{S6m8!53r6hK{W~`?4+-jEWwWShm!GXVALZ;wK1pBOoNe zZZnB{3cX5`^hJP2UcSO7~K0*0ZnO z<9UT~c~;-JvaLYJmC^MK08%Fz7zioDEE*JDY{|QjA%`~n7XysJv6wZCr=QGwXMoe+ z+2TX+jwH81AD_rf1|ze<=KnS(ge1DDb>)G3f*PA-)PCMc%9^|7Y2}Y6t~%Y{l~Gap zu7J71o4a5p2!x`>w)4$Gk-e1dnuU)U9*Bxi!4vqRq6y-2h^Zd)xTMhqY22BAgOgcB z^R>fLS;d_HJBgkty%$*T29uBYadHF=;gz^|?!4&v0;hiP+Hg1Y-{z> zv->_@Kbza20zfp!0_V_>?#|`fU&%`o%ip^1ZjA~;k7~NSN{ORe+0;{F#yW=b+ZuPF(4kohXnfDcy1K50k zm2V@n5VBq1e3f-8`>9rMe@HBr-iU6R^Yo<4%W(iZE@z^d=7-h|K2S+Dd&6^SD)=gB z!UxH?u%HA8!13@l8(S`tkUBpmRTA_6^mL_BO&wu0?2wdA*#rU<1q1}N%1$jrE4YLx zNF!SS+k*j`M#>U`LTC#f6eLnnYmg=2K|u{7Ph=4a6r+_bp-9?L0pWlP1`sKWNa)MV zYv=dNcP4q6nQ!iQzk4ZE%X7dr&C$swj24F#aI8Qfr zxdX=?^ajB0xt+FHOX)*_V$F46eK`i86f+d*-%<8aS-EJpb?d^S^66i((Ov!+se@^%R;4S~qj_I0ibk)7{D(MnnBdZlpW9Yy$lG zIV&j?1W8l~e)z7Qbh?W9Cbw|Uu!1L=N~nUHe@4fS`0!EU(u~(2Jb|r2?Tt_uuo0If z7{m3gb~;kDnau4}+Qr(4$TtwB(UVp&bpwq>@ndo=t zd8%x8r_ygwsPev1`I2tt+I>-}XQlm(&X8i*fROeqq!<--=mZ;a!A%ZGc9|B}yv?Yg zj~kAoamrs~^$A822e?%(`vn&WY7WrZf#V#Vvxq}^eY-EeH8V0e@cgZX`OM!V4r$?h zYamwss4%HCy)SrhIB%4)vh-R0HAT^(3Ue>`PojiT98OC>B{@Ykw1>}ybrxG(g;7M#T!44!Lwwy(oDI&8^6HKVzFyc!`<=xq0C=W+C%9@rp_5Jpr-f+LHK1 zm&Z2&r+#AFsU-_9>Zt1)Nq;fnGvWs>>tM9SJmQ(9n0|0{b`TT{QFLO40wp7&Vvw<_ zo=z^n{oYrNNGtCirW1)dsq&8nasp?Xw{b=CYxa!6?~p#i?4Q87F!Ad&GrEFcHOpXgrA zjBMM6Y_!8WQQ~G#yU>T!uDX%wtQi9-=i{C?MA#_6!^F32(%<*GqXw1a3V1y-Wop7N z^A2nVyjwQJTSk_+xB8QI zs999AfFfnPnW8?0-WA4VmGuBC$b|`pCu(h?7|(|6r-)={V`-5Azr>weTTx~Hf*?)t zV-LGI+s!?7B;}nKd*O{4+W{NW7Bcqq*NI@RQj64JQoULLI2zR>GpXvigWKiP~hTWt{O(vu0bxKT89Wn(y zX)C(?M)EZx)@RqRXR6VB?UtE6y*a7fM*NapuWOZPQI-<;8~YLs4N2k0wjzavq*d92 z<_+!oBJWFwY!RRP)>giBc6J+w!+#W(24Y_@6`Z5doDr^tmJ|21ogIN8k!>!>(qXi3 zekYfcreE42Zf>N6SX)FWBy}fDk;yq -//val deployModToLocalClient by tasks.registering(Copy::class) { -// description = "Copy the mod to the Factorio client" -// group = FactorioModPlugin.TASK_GROUP -// -// val clientModsDirectory123 = clientModsDirectory -// -// onlyIf { clientModsDirectory123.orNull?.asFile?.exists() == true } -// -// from(configurations.factorioMod.map { it.incoming.artifactView { lenient(true) }.files }) -// into(clientModsDirectory) -// -// doLast { -// logger.lifecycle("Copying mod from ${source.files} to $destinationDir") -// } -//} -// - - -// fun ExecOperations.isFactorioRunning(): Spec = ProcessRunningSpec(this, "factorio.exe") -//val clientLaunch by tasks.registering(Exec::class) { -// description = "Run local Factorio Steam game client" -// group = FactorioModPlugin.TASK_GROUP -// -// val steamExe123 = steamExe -// val clientModsDirectory444 = clientModsDirectory -// -// onlyIf(!serviceOf().isFactorioRunning()) -// onlyIf { steamExe123.orNull?.asFile?.exists() == true } -// onlyIf { clientModsDirectory444.orNull?.asFile?.exists() == true } -// -// dependsOn(deployModToLocalClient) -// mustRunAfter(clientKill, ":modules:infra-factorio-server:processRun") -// -// commandLine = parseSpaceSeparatedArgs( -//// """explorer "steam://rungameid/$factorioGameId// --mp-connect localhost/" """ // not working -//// """explorer "steam://run/$factorioGameId//--mp-connect localhost/" """ // works! But has annoying pop-up -// """ ${steamExe.asFile.orNull?.canonicalPath} -applaunch $factorioGameId --mp-connect localhost --mod-directory ${clientModsDirectory.asFile.orNull?.canonicalPath} """ -// ) -// doFirst { logger.lifecycle("Launching factorio.exe") } -//} - val clientKill by tasks.registering(Exec::class) { description = "Stop the local Factorio Steam game client" group = FactorioModPlugin.TASK_GROUP @@ -90,7 +34,6 @@ val clientKill by tasks.registering(Exec::class) { commandLine = parseSpaceSeparatedArgs(""" taskkill /im factorio.exe """) doFirst { logger.lifecycle("Killing factorio.exe") } } -// tasks.register(FactorioModPlugin.PUBLISH_MOD_LOCAL_TASK_NAME) { diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 8b40fe3..00d184f 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -12,19 +12,9 @@ geedeecee { srcDir.set(layout.projectDirectory.dir("src")) } - -//val dockerSrcDir: Directory by extra -//val factorioServerDataDir: Directory = dockerSrcDir.dir("factorio-server") val factorioServerDataDir: DirectoryProperty = objects.directoryProperty() .convention(geedeecee.srcDir.dir("factorio-server")) - -//val factorioMod: Configuration by configurations.creating { -// asConsumer() -// factorioModAttributes(objects) -//} - - dependencies { factorioMod(projects.modules.eventsMod) } From f69c55704cb4225195ab11edb13906b57f64c2c0 Mon Sep 17 00:00:00 2001 From: lazzexus Date: Mon, 12 Oct 2026 12:26:56 +0000 Subject: [PATCH 629/629] Initial commit --- LICENSE | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 + 2 files changed, 234 insertions(+) create mode 100644 LICENSE create mode 100644 README.md diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..cf5096f --- /dev/null +++ b/LICENSE @@ -0,0 +1,232 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. + +“This License” refers to version 3 of the GNU General Public License. + +“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. + +To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. + +A “covered work” means either the unmodified Program or a work based on the Program. + +To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. + +A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. + + c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + + a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. + + d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or authors of the material; or + + e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. + +All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. + +A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found. + + Kafkatorio + Copyright (C) 2026 lazzexus + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + +If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: + + Kafkatorio Copyright (C) 2026 lazzexus + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”. + +You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . + +The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . diff --git a/README.md b/README.md new file mode 100644 index 0000000..7883f9f --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Kafkatorio +

You're using Apache Kafka, an open-source distributed and fault-tolerant streaming platform originally built at LinkedIn. For more information, check out the kafka.apache.org", + "gridPos": { + "h": 6, + "w": 5, + "x": 19, + "y": 1 + }, + "id": 46, + "links": [], + "mode": "html", + "title": "", + "transparent": true, + "type": "text" + }, + { + "cacheTimeout": null, + "colorBackground": true, + "colorValue": false, + "colors": [ + "#d44a3a", + "rgba(237, 129, 40, 0.89)", + "#299c46" + ], + "datasource": "Prometheus", + "decimals": 0, + "description": "Total number of brokers with a state running (i.e 3)", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 0, + "y": 4 + }, + "id": 44, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "count((kafka_server_brokerstate{env=\"$env\"}) == 3 or (kafka_server_brokerstate{env=\"$env\"}) == 4)", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "1,3", + "title": "Brokers Running(>=3)", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "decimals": 0, + "description": "Total number of producer requests per second", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 3, + "y": 4 + }, + "id": 39, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kafka_network_request_per_sec{aggregate=~\"OneMinuteRate\",request=~\"Produce\",env=\"$env\"})", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Produce Req Per Sec", + "type": "singlestat", + "valueFontSize": "150%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "decimals": 0, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 7, + "y": 4 + }, + "id": 40, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kafka_network_request_per_sec{aggregate=~\"OneMinuteRate\",request=~\"FetchConsumer\",env=\"$env\"})", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Fetch Consumer Req Per Sec", + "type": "singlestat", + "valueFontSize": "150%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "decimals": 0, + "description": "Number of metadata requests per sec", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 11, + "y": 4 + }, + "id": 41, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kafka_network_request_per_sec{aggregate=~\"OneMinuteRate\",request=~\"Metadata\",env=\"$env\"})", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Metadata Req Per Sec", + "type": "singlestat", + "valueFontSize": "150%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 15, + "y": 4 + }, + "id": 42, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kafka_network_request_per_sec{aggregate=~\"OneMinuteRate\",request=~\"OffsetCommit\",env=\"$env\"})", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Offset Commit Req Per Sec", + "type": "singlestat", + "valueFontSize": "150%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 7 + }, + "id": 27, + "panels": [], + "title": "Throughput In/Out", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Aggregate incoming message rate.", + "fill": 1, + "gridPos": { + "h": 12, + "w": 19, + "x": 0, + "y": 8 + }, + "id": 19, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": 250, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(kafka_server_broker_topic_metrics_messagesinpersec_rate{topic!=\"\"}) by(topic)", + "format": "time_series", + "instant": false, + "intervalFactor": 1, + "legendFormat": "{{topic}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Messages In Per Topics", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "wps", + "label": "Msg/sec", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "decimals": 2, + "description": "Aggregate incoming message rate.", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 5, + "x": 19, + "y": 8 + }, + "id": 37, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kafka_server_broker_topic_metrics_messagesinpersec_rate{topic=\"\"}) by (broker)", + "format": "time_series", + "instant": false, + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Messages In per sec", + "type": "singlestat", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "decimals": 2, + "format": "Bps", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 5, + "x": 19, + "y": 12 + }, + "id": 24, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kafka_server_broker_topic_metrics_bytesinpersec_rate{topic=\"\"}) by (broker)", + "format": "time_series", + "instant": false, + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Bytes In per sec", + "type": "singlestat", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "decimals": 2, + "format": "Bps", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 5, + "x": 19, + "y": 16 + }, + "id": 25, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kafka_server_broker_topic_metrics_bytesoutpersec_rate{topic=\"\"}) by (broker)", + "format": "time_series", + "instant": false, + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Bytes Out per sec", + "type": "singlestat", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 20 + }, + "id": 21, + "panels": [], + "title": "In-Sync Replica / Leaders Election", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "When a broker is brought up after a failure, it starts catching up by reading from the leader. Once it is caught up, it gets added back to the ISR.", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 21 + }, + "id": 11, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_server_replica_manager_isrexpandspersec{aggregate=\"OneMinute\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Broker={{instance}}", + "metric": "kafka_server_replication_isrexpandspersec", + "refId": "A", + "step": 20 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "In-Sync Replica Expands Rate", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "If a broker goes down, ISR for some of the partitions will shrink. When that broker is up again, ISR will be expanded once the replicas are fully caught up. Other than that, the expected value for both ISR shrink rate and expansion rate is 0.", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 21 + }, + "id": 10, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_server_replica_manager_isrshrinkspersec{aggregate=\"OneMinute\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Broker={{instance}}", + "metric": "kafka_server_replication_isrshrinkspersec", + "refId": "A", + "step": 20 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "In-Sync Replica Shrinks Rate", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Leader election rate and latency.", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 28 + }, + "id": 8, + "isNew": true, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_controller_stats_leaderelectionrateandtimems{aggregate=~\"Mean\",env=\"$env\"}", + "format": "time_series", + "hide": true, + "intervalFactor": 2, + "legendFormat": "Broker={{instance}} / {{aggregate}}", + "metric": "kafka_controller_stats_leader_election_rate_and_time_ms", + "refId": "A", + "step": 10 + }, + { + "expr": "kafka_controller_stats_leaderelectionrateandtimems{aggregate=~\"75thPercentile\",env=\"$env\"}", + "format": "time_series", + "hide": true, + "intervalFactor": 2, + "legendFormat": "Broker={{instance}} / {{aggregate}}", + "refId": "B", + "step": 10 + }, + { + "expr": "kafka_controller_stats_leaderelectionrateandtimems{aggregate=~\"99thPercentile\",env=\"$env\"}", + "format": "time_series", + "hide": true, + "intervalFactor": 2, + "legendFormat": "Broker={{instance}} / {{aggregate}}", + "refId": "C", + "step": 10 + }, + { + "expr": "kafka_controller_stats_leaderelectionrateandtimems{aggregate=\"OneMinuteRate\", env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Broker={{instance}} / {{aggregate}}", + "refId": "D", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Leader Election Rate (ms/1MinuteRate)", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 1, + "value_type": "cumulative" + }, + "transparent": false, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 28 + }, + "id": 9, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_controller_stats_uncleanleaderelectionspersec{aggregate=\"OneMinuteRate\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Broker={{instance}} / {{aggregate}}", + "metric": "kafka_controller_stats_unclean_leader_elections_per_sec", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Unclean Leader Election Rate (should be < 0)", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Number of leaders on each broker. This should be mostly even across all brokers. If not, set auto.leader.rebalance.enable to true on all brokers in the cluster.", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 35 + }, + "id": 14, + "isNew": true, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 2, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_server_replica_manager_leadercount{env=\"$env\"}", + "format": "time_series", + "instant": false, + "intervalFactor": 2, + "legendFormat": "Broker={{instance}}", + "metric": "kafka_server_replication_leadercount", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Leader Count Per Broker", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 35 + }, + "id": 15, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 2, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_server_replica_manager_partitioncount{env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Broker={{instance}}", + "metric": "kafka_server_replication_leadercount", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Number of Partitions Per Broker", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "5s", + "schemaVersion": 16, + "style": "dark", + "tags": [ + "kafka", + "broker", + "healthcheck" + ], + "templating": { + "list": [ + { + "allValue": null, + "current": { + "text": "docker", + "value": "docker" + }, + "datasource": "Prometheus", + "hide": 0, + "includeAll": false, + "label": "Environment", + "multi": false, + "name": "env", + "options": [], + "query": "label_values(kafka_server_brokerstate, env)", + "refresh": 1, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "browser", + "title": "Kafka Cluster / Global HealthCheck", + "uid": "e-6AJQOik", + "version": 1 +} \ No newline at end of file diff --git a/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_cluster_replication.json b/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_cluster_replication.json new file mode 100644 index 0000000..97b06fb --- /dev/null +++ b/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_cluster_replication.json @@ -0,0 +1,574 @@ +{ + "__inputs": [ + { + "name": "Prometheus", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "5.2.1" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "5.0.0" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "5.0.0" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "iteration": 1540330422283, + "links": [], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 0 + }, + "id": 1, + "isNew": true, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_server_broker_topic_metrics_replicationbytesinpersec_rate{aggregate=\"OneMinute\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}}", + "refId": "A", + "step": 60 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Replication BytesIn/Sec", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 1, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 0 + }, + "id": 2, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_server_broker_topic_metrics_replicationbytesoutpersec_rate{aggregate=\"OneMinute\",env=\"$env\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{instance}}", + "refId": "A", + "step": 60 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Replication BytesOut/Sec", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 1, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 0 + }, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_server_replica_fetcher_manager_maxlag_value{env=\"$env\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Replication Max Lag Per Broker", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": null, + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 5, + "w": 24, + "x": 0, + "y": 7 + }, + "id": 3, + "isNew": true, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_server_fetcher_stats_bytespersec{env=\"$env\", aggregate=\"OneMinute\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Host {{instance}}, client_id={{client_id}} / {{broker_host}}:{{broker_port}}", + "refId": "A", + "step": 60 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Fetch Bytes/sec Per Replication thread", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": null, + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 5, + "w": 24, + "x": 0, + "y": 12 + }, + "id": 4, + "isNew": true, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_server_fetcher_stats_requestspersec{env=\"$env\", aggregate=\"OneMinute\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Host {{instance}}, client_id={{client_id}} / {{broker_host}}:{{broker_port}}", + "refId": "A", + "step": 60 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Fetch Requests/sec Per Replication thread", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "reqps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "5s", + "schemaVersion": 16, + "style": "dark", + "tags": [ + "kafka", + "broker", + "replication" + ], + "templating": { + "list": [ + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "hide": 0, + "includeAll": false, + "label": "Env", + "multi": false, + "name": "env", + "options": [], + "query": "label_values(kafka_server_brokerstate, env)", + "refresh": 1, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "browser", + "title": "Kafka Cluster / Replication", + "uid": "E9bXmq4ik", + "version": 2 +} \ No newline at end of file diff --git a/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_topics_logs.json b/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_topics_logs.json new file mode 100644 index 0000000..4f91add --- /dev/null +++ b/modules/infra-kafka-cluster/src/config/grafana/dashboards/grafana_dashboard_topics_logs.json @@ -0,0 +1,876 @@ +{ + "__inputs": [ + { + "name": "Prometheus", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "5.2.1" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "5.0.0" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "5.0.0" + }, + { + "type": "panel", + "id": "singlestat", + "name": "Singlestat", + "version": "5.0.0" + }, + { + "type": "panel", + "id": "table", + "name": "Table", + "version": "5.0.0" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "iteration": 1540331963544, + "links": [], + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 4, + "panels": [], + "repeat": "topic", + "title": "$topic", + "type": "row" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "format": "decbytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 0, + "y": 1 + }, + "id": 2, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kafka_log_size{env=\"$env\", topic=\"$topic\"})", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Total Log Size", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 3, + "y": 1 + }, + "id": 11, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "count_values(\"partition\", kafka_log_numlogsegments{topic=\"$topic\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Total Number of Replicas", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "description": "should alert if > 0", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 6, + "y": 1 + }, + "id": 12, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kafka_cluster_partition_underminisr{env=\"$env\", topic=\"$topic\"})", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "1", + "title": "Number of Partitions Under Min ISR", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "description": "should alert if > 0", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 9, + "y": 1 + }, + "id": 13, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(kafka_cluster_partition_underreplicated{env=\"$env\", topic=\"$topic\"})", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "1", + "title": "Under Replicated Partitions", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "columns": [], + "datasource": "Prometheus", + "fontSize": "100%", + "gridPos": { + "h": 4, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 6, + "links": [], + "pageSize": null, + "scroll": true, + "showHeader": true, + "sort": { + "col": 5, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "link": false, + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "Time", + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "__name__", + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "job", + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "topic", + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "service", + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "env", + "thresholds": [], + "type": "hidden", + "unit": "short" + } + ], + "targets": [ + { + "expr": "kafka_log_numlogsegments{topic=\"$topic\", env=\"$env\"}", + "format": "table", + "instant": true, + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "title": "Number of Segment Files Per Broker", + "transform": "table", + "type": "table" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 6, + "w": 8, + "x": 0, + "y": 5 + }, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_server_broker_topic_metrics_messagesinpersec_rate{topic=\"$topic\", env=\"$env\", aggregate=\"OneMinute\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Messages In Per Sec (OneMinuteRate)", + "tooltip": { + "shared": true, + "sort": 1, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "wps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 6, + "w": 8, + "x": 8, + "y": 5 + }, + "id": 10, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_server_broker_topic_metrics_bytesinpersec_rate{topic=\"$topic\", env=\"$env\", aggregate=\"OneMinute\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "BytesInPerSec (OneMinuteRate)", + "tooltip": { + "shared": true, + "sort": 1, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 6, + "w": 8, + "x": 16, + "y": 5 + }, + "id": 9, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "kafka_server_broker_topic_metrics_bytesoutpersec_rate{topic=\"$topic\", env=\"$env\", aggregate=\"OneMinute\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "BytesOutPerSec (OneMinuteRate)", + "tooltip": { + "shared": true, + "sort": 1, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "5s", + "schemaVersion": 16, + "style": "dark", + "tags": [ + "kafka", + "topics" + ], + "templating": { + "list": [ + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "hide": 0, + "includeAll": false, + "label": "Cluster", + "multi": false, + "name": "env", + "options": [], + "query": "label_values(kafka_log_size, env)", + "refresh": 2, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "hide": 0, + "includeAll": false, + "label": "Topics", + "multi": true, + "name": "topic", + "options": [], + "query": "label_values(kafka_log_size, topic)", + "refresh": 2, + "regex": "", + "sort": 5, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Kafka Topics / Logs", + "uid": "1vR8sjAmk", + "version": 1 +} \ No newline at end of file diff --git a/modules/infra-kafka-cluster/src/config/grafana/provisioning/dashboards/kafka.yaml b/modules/infra-kafka-cluster/src/config/grafana/provisioning/dashboards/kafka.yaml new file mode 100644 index 0000000..2053d55 --- /dev/null +++ b/modules/infra-kafka-cluster/src/config/grafana/provisioning/dashboards/kafka.yaml @@ -0,0 +1,12 @@ +apiVersion: 1 + +providers: +- name: 'default' + orgId: 1 + folder: '' + type: file + disableDeletion: false + editable: true + updateIntervalSeconds: 3 #how often Grafana will scan for changed dashboards + options: + path: /var/lib/grafana/dashboards diff --git a/modules/infra-kafka-cluster/src/config/grafana/provisioning/datasources/datasource.yaml b/modules/infra-kafka-cluster/src/config/grafana/provisioning/datasources/datasource.yaml new file mode 100644 index 0000000..a8984ad --- /dev/null +++ b/modules/infra-kafka-cluster/src/config/grafana/provisioning/datasources/datasource.yaml @@ -0,0 +1,50 @@ +# config file version +apiVersion: 1 + +# list of datasources that should be deleted from the database +deleteDatasources: + - name: Prometheus + orgId: 1 + +# list of datasources to insert/update depending +# what's available in the database +datasources: + # name of the datasource. Required +- name: Prometheus + # datasource type. Required + type: prometheus + # access mode. proxy or direct (Server or Browser in the UI). Required + access: proxy + # org id. will default to orgId 1 if not specified + orgId: 1 + # url + url: http://prometheus:9090 +# # database password, if used +# password: +# # database user, if used +# user: +# # database name, if used +# database: +# # enable/disable basic auth +# basicAuth: +# # basic auth username +# basicAuthUser: +# # basic auth password +# basicAuthPassword: +# # enable/disable with credentials headers +# withCredentials: + # mark as default datasource. Max one per org + isDefault: true +# # fields that will be converted to json and stored in json_data +# jsonData: +# graphiteVersion: "1.1" +# tlsAuth: true +# tlsAuthWithCACert: true +# # json object of data that will be encrypted. +# secureJsonData: +# tlsCACert: "..." +# tlsClientCert: "..." +# tlsClientKey: "..." + version: 1 + # allow users to edit datasources from the UI. + editable: true diff --git a/modules/infra-kafka-cluster/src/config/jmx_exporter_kafka_broker.yml b/modules/infra-kafka-cluster/src/config/jmx_exporter_kafka_broker.yml new file mode 100644 index 0000000..da74442 --- /dev/null +++ b/modules/infra-kafka-cluster/src/config/jmx_exporter_kafka_broker.yml @@ -0,0 +1,505 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#--------------------------------------------------------------------------------------------------------- +# Kafka Broker JMX Metrics : +# Compatible with version Apache Kafka v2.x.x / Confluent Platform 5.x.x +#--------------------------------------------------------------------------------------------------------- +hostPort: kafka:9991 +lowercaseOutputName: true +lowercaseOutputLabelNames: true + +#Whitelist is used to reduce scrapping time +whitelistObjectNames: + - java.lang:* + - kafka.cluster:* + - kafka.controller:* + - kafka.log:* + - kafka.server:type=KafkaServer,name=BrokerState + - kafka.server:type=KafkaRequestHandlerPool,* + - kafka.server:type=BrokerTopicMetrics,* +# - kafka.server:type=DelayedFetchMetrics,* +# - kafka.server:type=DelayedOperationPurgatory,* + - kafka.server:type=FetcherLagMetrics,* + - kafka.server:type=FetcherStats,* + - kafka.server:type=Request,* + - kafka.server:type=Fetch,* + - kafka.server:type=Produce,* + - kafka.server:type=ReplicaManager,* + - kafka.server:type=ReplicaFetcherManager,* + - kafka.server:type=SessionExpireListener,* + - kafka.server:type=controller-channel-metrics,* + - kafka.server:type=socket-server-metrics,* + - kafka.network:type=RequestChannel,* + - kafka.network:type=Processor,* + - kafka.network:type=SocketServer,* + - kafka.network:type=RequestMetrics,* +# - kafka.network:type=RequestMetrics,name=*,request=OffsetCommit,version=* +# - kafka.network:type=RequestMetrics,name=*,request=FetchConsumer,version=* +# - kafka.network:type=RequestMetrics,name=*,request=FetchFollower,version=* +# - kafka.network:type=RequestMetrics,name=*,request=Produce,version=* +# - kafka.network:type=RequestMetrics,name=*,request=Metadata,version=* + - kafka.coordinator.group:* +blacklistObjectNames: + - java.lang:type=ClassLoading,* + - java.lang:type=Compilation,* + - java.lang:type=MemoryManager,* + - kafka.utils:* + - kafka.controller:type=ControllerChannelManager,name=QueueSize,* + # Following metrics are exposed per topics + - kafka.log:type=Log,name=LogEndOffset,* + - kafka.log:type=Log,name=LogStartOffset,* + - kafka.cluster:type=Partition,name=InSyncReplicasCount,* + - kafka.cluster:type=Partition,name=LastStableOffsetLag,* + - kafka.cluster:type=Partition,name=ReplicasCounts,* + - kafka.cluster:type=Partition,name=UnderReplicated,* + - kafka.server:type=BrokerTopicMetrics,name=TotalFetchRequestsPerSec,* + - kafka.server:type=BrokerTopicMetrics,name=TotalProduceRequestsPerSec,* + - kafka.server:type=BrokerTopicMetrics,name=FailedProduceRequestsPerSec,* + - kafka.server:type=BrokerTopicMetrics,name=FailedFetchRequestsPerSec,* + - kafka.server:type=BrokerTopicMetrics,name=BytesRejectedPerSec,* + +rules: + #------------------------------------------------------------------------------------------------------- + # KafkaServers : State of broker server + # + # - BrokerState + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.server<>Value + name: kafka_server_brokerstate + labels: + service: kafka-broker + env: kafkatorio + + #------------------------------------------------------------------------------------------------------- + # Partition : Number of partitions for each broker + # - InSyncReplicasCount + # - LastStableOffsetLag + # - ReplicasCount + # - UnderReplicated + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.cluster<>Value + name: kafka_cluster_partition_$1 + labels: + topic: $2 + partition: $3 + service: kafka-broker + env: kafkatorio + #------------------------------------------------------------------------------------------------------- + # KafkaController : + # + # - ActiveControllerCount, OfflinePartitionsCount, PreferredReplicaImbalanceCount + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.controller<>Value + name: kafka_controller_$1 + labels: + service: kafka-broker + env: kafkatorio + + #------------------------------------------------------------------------------------------------------- + # ControllerStats : The event that is currently being processed by the elected broker controller. + # + # - LeaderElectionRateAndtimeMs, UncleanLeaderElectionsPerSec, AutoLeaderBalanceRateAndTimeMs, ManualLeaderBalanceRateAndTimeMs + # - ControllerChangeRateAndTimeMs, + # - TopicChangeRateAndTimeMs, TopicDeletionRateAndTimeMs, PartitionReassignmentRateAndTimeMs + # - IsrChangeRateAndTimeMs + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.controller<>(OneMinuteRate|Mean|75thPercentile|99thPercentile) + name: kafka_controller_stats_$1 + labels: + aggregate: $2 + service: kafka-broker + env: kafkatorio + #------------------------------------------------------------------------------------------------------- + # Coordinator : GroupMetadataManager + # + # - NumGroups, NumOffsets + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.coordinator.group<>(Value) + name: kafka_coordinator_group_metadata_manager_$1 + labels: + service: kafka-broker + env: kafkatorio + #------------------------------------------------------------------------------------------------------- + # Logs : + # + # - LogEndOffset, LogStartOffset, NumLogSegments, Size + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.log<>Value + name: kafka_log_$1 + labels: + topic: $2 + partition: $3 + service: kafka-broker + env: kafkatorio + + #------------------------------------------------------------------------------------------------------- + # LogCleaner : + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.log<>(Value) + name: kafka_log_cleaner_recopy_percent + labels: + service: kafka-broker + env: kafkatorio + + - pattern: kafka.log<>(Value) + name: kafka_log_cleaner_max_clean_time_secs + labels: + service: kafka-broker + env: kafkatorio + + - pattern: kafka.log<>(Value) + name: kafka_log_cleaner_max_buffer_utilization_percent + labels: + service: kafka-broker + env: kafkatorio + + #------------------------------------------------------------------------------------------------------- + # LogCleanerManager : + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.log<>(Value) + name: kafka_log_cleaner_manager_max_dirty_percent + labels: + service: kafka-broker + env: kafkatorio + + #------------------------------------------------------------------------------------------------------- + # LogFlushStats : + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.log<>(\w+) + name: kafka_log_flush_stats_rate_and_time_ms + labels: + aggregate: $1 + service: kafka-broker + env: kafkatorio + #------------------------------------------------------------------------------------------------------- + # KafkaRequestHandlerPool : Latency + # + # - KafkaRequestHandlerPool + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.server<>(\w+) + name: kafka_server_request_handler_avg_idle_percent + labels: + aggregate: $1 + service: kafka-broker + env: kafkatorio + + #------------------------------------------------------------------------------------------------------- + # Network Socket Server : Latency + # + # - NetworkProcessorAvgIdlePercent + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.network<>(Value) + name: kafka_network_socket_server_processor_avg_idle_percent + labels: + service: kafka-broker + env: kafkatorio + + #------------------------------------------------------------------------------------------------------- + # Network Processor : Latency + # + # - IdlePercent + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.network<>(Value) + name: kafka_network_processor_idle_percent + labels: + processor: $1 + service: kafka-broker + env: kafkatorio + + #------------------------------------------------------------------------------------------------------- + # Network KafkaRequestChannel : + # + # - RequestQueueSize, ResponseQueueSize + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.network<>Value + name: kafka_network_request_channel_queue_size + labels: + queue: $1 + service: kafka-broker + env: kafkatorio + + #------------------------------------------------------------------------------------------------------- + # Network KafkaRequest : + # + # - RequestPerSec, + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.network<>(OneMinuteRate|Mean) + name: kafka_network_request_per_sec + labels: + request: $1 + version: $2 + aggregate: $3 + service: kafka-broker + env: kafkatorio + + #------------------------------------------------------------------------------------------------------- + # Network KafkaRequestMetrics : + # + # - LocalTimeMs, RemoteTimeMs, + # - RequestQueueTimeMs, + # - ResponseQueueTimeMs, ResponseSendTimeMs + # - ThrottleTimeMs + # - TotalTimeMs + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.network<>(OneMinuteRate|Mean|75thPercentile|99thPercentile) + name: kafka_network_request_metrics_time_ms + labels: + scope: $1 + request: $2 + aggregate: $3 + service: kafka-broker + env: kafkatorio + + #------------------------------------------------------------------------------------------------------- + # KafkaServer / BrokerTopicMetrics - I/O metrics : + # + # - BytesInPerSec, BytesOutPerSec, BytesRejectedPerSec, + # - FailedFetchRequestsPerSec, FailedProduceRequestsPerSec,MessagesInPerSec, + # - TotalFetchRequestPerSec, TotalProduceRequestPerSec, ReplicationBytesInPerSec, ReplicationBytesOutPerSec + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.server<>(OneMinute)Rate + name: kafka_server_broker_topic_metrics_$1_rate + labels: + aggregate: $2 + service: kafka-broker + env: kafkatorio + + - pattern: kafka.server<>(OneMinute)Rate + name: kafka_server_broker_topic_metrics_$1_rate + labels: + topic: $2 + aggregate: $3 + service: kafka-broker + env: kafkatorio + #------------------------------------------------------------------------------------------------------- + # KafkaServer / DelayedFetchMetrics : + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.server<>([^,]+)Rate + name: kafka_server_delayed_fetch_expires_per_sec + labels: + fetcher_type: $1 + aggregate: $2 + service: kafka-broker + env: kafkatorio + #------------------------------------------------------------------------------------------------------- + # KafkaServer / DelayedOperationPurgatory : + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.server<>Value + name: kafka_server_delayed_operation_purgatory_$1 + labels: + operation: $2 + service: kafka-broker + env: kafkatorio + #------------------------------------------------------------------------------------------------------- + # FetcherLagMetrics : Lag in number of messages per follower replica + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.server<>Value + name: kafka_server_fetcher_lag_$1 + labels: + client_id: $2 + topic: $3 + partition: $4 + service: kafka-broker + env: kafkatorio + #------------------------------------------------------------------------------------------------------- + # FetcherStats : Replica Fetcher Thread stats + # - BytesPerSec / RequestsPerSec + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.server<>([^,]+)Rate + name: kafka_server_fetcher_stats_$1 + labels: + client_id: $2 + broker_host: $3 + broker_port: $4 + aggregate: $5 + service: kafka-broker + env: kafkatorio + #------------------------------------------------------------------------------------------------------- + # KafkaServer Request : + # - request-time - Tracking request-time per user/client-id + # - throttle-time - Tracking average throttle-time per user/client-id + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.server<>(request-time|throttle-time) + name: kafka_server_request_$2 + labels: + client_id: $1 + service: kafka-broker + env: kafkatorio + #------------------------------------------------------------------------------------------------------- + # KafkaServer Fetcher/Producer : + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.server<>(byte-rate|throttle-time) + name: kafka_server_fetch_client_$2 + labels: + client_id: $1 + service: kafka-broker + env: kafkatorio + + - pattern: kafka.server<>(byte-rate|throttle-time) + name: kafka_server_produce_client_$2 + labels: + client_id: $1 + service: kafka-broker + env: kafkatorio + #------------------------------------------------------------------------------------------------------- + # ReplicaManager : + # - IsrExpandsPerSec, IsrShrinksPerSec, FailedIsrUpdatesPerSec + # - LeaderCount, PartitionCount, UnderReplicatedPartitions) + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.server<>([^,]+)Rate + name: kafka_server_replica_manager_$1 + labels: + aggregate: $2 + service: kafka-broker + env: kafkatorio + + - pattern: kafka.server<>(Value) + name: kafka_server_replica_manager_$1 + labels: + service: kafka-broker + env: kafkatorio + + #------------------------------------------------------------------------------------------------------- + # ReplicaFetcherManager : + # - MaxLag, MinFetchRate + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.server<>(Value) + name: kafka_server_replica_fetcher_manager_$1_value + labels: + client_id: $2 + service: kafka-broker + env: kafkatorio + + #------------------------------------------------------------------------------------------------------- + # Zookeeper / SessionExpireListener : + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.server<>([^,]+)Rate + name: kafka_zookeeper_session_expire_listener_$1 + labels: + aggregate: $2 + service: kafka-broker + env: kafkatorio + + #------------------------------------------------------------------------------------------------------- + # ControllerChannelMetrics: + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.server<>(\w*) + name: kafka_server_controller_channel_metrics_$2 + labels: + broker_id: $1 + service: kafka-broker + env: kafkatorio + + #------------------------------------------------------------------------------------------------------- + # KafkaServer / Socket Server Metrics + #------------------------------------------------------------------------------------------------------- + - pattern: kafka.server<>(\w*) + name: kafka_server_socket_server_metrics_$2 + labels: + network_processor: $1 + service: kafka-broker + env: kafkatorio + #------------------------------------------------------------------------------------------------------- + # + # Broker / JVM + #------------------------------------------------------------------------------------------------------- + # JVM GarbageCollector + # + - pattern: 'java.lang<>CollectionCount' + name: kafka_jvm_gc_collection_count + labels: + name: $1 + service: kafka-broker + env: kafkatorio + + - pattern: 'java.lang<>CollectionTime' + name: kafka_jvm_gc_collection_time + labels: + name: $1 + service: kafka-broker + env: kafkatorio + + - pattern: java.lang + name: kafka_jvm_last_gc_duration + labels: + name: $1 + service: kafka-broker + env: kafkatorio + attrNameSnakeCase: true + + - pattern: 'java.lang(\w+)' + name: kafka_jvm_last_gc_memory_usage_$4 + labels: + name: $1 + space: $2 + type: $4 + service: kafka-broker + env: kafkatorio + attrNameSnakeCase: true + + # JVM Memory + - pattern: java.lang(\w*) + name: kafka_jvm_heap_usage + labels: + type: $1 + service: kafka-broker + env: kafkatorio + attrNameSnakeCase: true + + - pattern: java.lang(\w*) + name: kafka_jvm_non_heap_usage + labels: + type: $1 + service: kafka-broker + env: kafkatorio + attrNameSnakeCase: true + + - pattern: 'java.lang(\w*)' + name: kafka_jvm_memory_pool_collection_usage + labels: + name: $1 + type: $2 + service: kafka-broker + env: kafkatorio + - pattern: 'java.lang(\w*)' + name: kafka_jvm_memory_pool_usage + labels: + name: $1 + type: $2 + service: kafka-broker + env: kafkatorio + - pattern: 'java.lang(\w*)' + name: kafka_jvm_memory_pool_peak_usage + labels: + name: $1 + type: $2 + service: kafka-broker + env: kafkatorio + + # JVM Thread + - pattern: java.lang<>(\w*thread_count) + name: kafka_jvm_$1 + labels: + service: kafka-broker + env: kafkatorio + attrNameSnakeCase: true + + # Operating System + - pattern: java.lang<>(\w*) + name: kafka_jvm_os_$1 + labels: + service: kafka-broker + env: kafkatorio diff --git a/modules/infra-kafka-cluster/src/config/prometheus.yml b/modules/infra-kafka-cluster/src/config/prometheus.yml new file mode 100644 index 0000000..dae03d5 --- /dev/null +++ b/modules/infra-kafka-cluster/src/config/prometheus.yml @@ -0,0 +1,29 @@ +# my global config +global: + scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. + evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. + # scrape_timeout is set to the global default (10s). + +# Alertmanager configuration +alerting: + alertmanagers: + - static_configs: + - targets: + # - alertmanager:9093 + +# Load rules once and periodically evaluate them according to the global 'evaluation_interval'. +rule_files: +# - "first_rules.yml" +# - "second_rules.yml" + +# A scrape configuration containing exactly one endpoint to scrape: +# Here it's Prometheus itself. +scrape_configs: + # The job name is added as a label `job=` to any timeseries scraped from this config. + - job_name: 'kafka' + + # metrics_path defaults to '/metrics' + # scheme defaults to 'http'. + + static_configs: + - targets: [ 'jmx-kafka:5556' ] diff --git a/modules/infra-kafka-cluster/src/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml index 1d0d4b5..c881589 100644 --- a/modules/infra-kafka-cluster/src/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -12,6 +12,13 @@ services: target: "kafka-kraft" args: KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/3.1.0/kafka_2.13-3.1.0.tgz" + volumes: + - "./kafka-server.properties:/kafka/server.properties" + environment: + JMX_PORT: "9991" +# KAFKA_JMX_OPTS: "9991" + KAFKA_JMX_OPTS: "-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=kafka -Dcom.sun.management.jmxremote.rmi.port=9991" + networks: - "kafka-nw" - "kafkatorio-nw" @@ -49,6 +56,48 @@ services: # - "8083:8083" # + grafana: + image: "grafana/grafana:${GRAFANA_VERSION}" + container_name: "grafana" + ports: + - "3000:3000" + environment: + GF_PATHS_DATA : /var/lib/grafana + GF_SECURITY_ADMIN_PASSWORD : kafka + volumes: + - "./config/grafana/provisioning:/etc/grafana/provisioning" + - "./config/grafana/dashboards:/var/lib/grafana/dashboards" + depends_on: + - prometheus + networks: + - "kafka-nw" + + prometheus: + image: "prom/prometheus:${PROMETHEUS_VERSION}" + container_name: "prometheus" + ports: + - "9090:9090" + volumes: + - "./config/prometheus.yml:/etc/prometheus/prometheus.yml" + command: "--config.file=/etc/prometheus/prometheus.yml" + networks: + - "kafka-nw" + + jmx-kafka: + image: "sscaling/jmx-prometheus-exporter" + container_name: "jmx-kafka" + ports: + - "5556:5556" + environment: + CONFIG_YML : "/etc/jmx_exporter/config.yml" +# JVM_OPTS: "-XX:MaxRAMPercentage=70.0" + volumes: + - "./config/jmx_exporter_kafka_broker.yml:/etc/jmx_exporter/config.yml" + depends_on: + - kafka + networks: + - "kafka-nw" + networks: kafka-nw: name: "kafka-nw" From ee62f9646ec53cd0a225bf2290ab30429d76c217 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 24 Apr 2022 11:32:15 +0200 Subject: [PATCH 288/629] Kafka Streams working again? --- .../processor/admin/kafkatorioTopics.kt | 1 - .../processor/topology/groupMapChunks.kt | 50 ++++++++++++----- .../processor/topology/packetDataStreams.kt | 9 ++-- .../processor/topology/prototypes.kt | 53 +++++++------------ 4 files changed, 61 insertions(+), 52 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt index 5a7781e..18e483a 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt @@ -14,7 +14,6 @@ import kotlin.reflect.KClass private const val DOMAIN = "kafkatorio" - const val TOPIC_SRC_SERVER_LOG = "$DOMAIN.src.server-log" const val TOPIC_GROUPED_MAP_CHUNKS_STATE = "$DOMAIN.state.map-chunks.grouped" diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt index 0cb62d3..aae4413 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt @@ -13,9 +13,9 @@ import dev.adamko.kafkatorio.schema.common.toMapChunkPosition import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import dev.adamko.kotka.extensions.groupedAs -import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.materializedWith import dev.adamko.kotka.extensions.producedAs +import dev.adamko.kotka.extensions.repartitionedAs import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.flatMap import dev.adamko.kotka.extensions.streams.mapValues @@ -66,21 +66,22 @@ fun groupMapChunks(builder: StreamsBuilder): Topology { tileProtoColourDict, ) + val pid = "grouped-map-chunk-tiles.output" groupedMapChunkTiles - .toStream("stream-grouped-map-tiles") - .filter("stream-grouped-map-tiles.filter-not-null") { _, v -> + .toStream("$pid.to-stream") + .filter("$pid.filter-tiles-not-empty") { _, v -> !v?.map.isNullOrEmpty() } - .mapValues("stream-grouped-map-tiles.map-not-null") { _, v -> + .mapValues("$pid.map-not-null") { _, v -> requireNotNull(v) } - .peek("stream-grouped-map-tiles.peek") { _, v -> + .peek("$pid.print-group-result") { _, v -> println("Grouping map tiles result: ${v.chunkId} / ${v.map.size}") } .to( TOPIC_GROUPED_MAP_CHUNKS_STATE, producedAs( - "produce.grouped-map-chunks", + "$pid.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde>() ) @@ -102,9 +103,12 @@ private fun groupTilesIntoChunksWithColours( }.mapValues("map-chunk-update-packets.convert-to-map-tiles") { _, packet: MapChunkUpdate -> val mapTiles = packet.tileDictionary?.toMapTileList() ?: emptyList() MapTiles(packet.key.surfaceIndex, mapTiles) - }.filter { _, value -> + }.filter("map-chunk-update-packets.filter-out.no-tiles") { _, value -> value.tiles.isNotEmpty() } +// .peek { _, value -> +// println("[${System.currentTimeMillis()}] mapTilesStream: surface:${value.surfaceIndex}, tile count: ${value.tiles.size}") +// } val chunkedTilesTable: KTable> = @@ -115,8 +119,6 @@ private fun groupTilesIntoChunksWithColours( val standardChunkSize = ChunkSize.MAX val flatMappedChunkTiles: List>> = - // println("[${System.currentTimeMillis()}] Flat-mapped ${flatMappedChunkTiles.size} chunk, with ${flatMappedChunkTiles.joinToString { it.second.map.size.toString() }} tiles") - mapTiles .tiles .groupBy { tile -> @@ -145,6 +147,15 @@ private fun groupTilesIntoChunksWithColours( .filter("server-map-data.tiles.filter-not-empty") { _, value -> value.map.isNotEmpty() } + .repartition( + repartitionedAs( + "server-map-data.tiles.pre-table-repartition", + kxsBinary.serde(), + kxsBinary.serde(), + // force, otherwise KTable-KTable FK join doesn't work + numberOfPartitions = 1, + ) + ) .groupByKey( groupedAs( "server-map-data.tiles.group", @@ -155,24 +166,35 @@ private fun groupTilesIntoChunksWithColours( .reduce( "server-map-data.tiles.reduce", materializedWith( +// materializedAs( +// "server-map-data.tiles.reduce.store", kxsBinary.serde(), kxsBinary.serde>(), ) - ) { chunkTiles, other -> chunkTiles + other } - + ) { chunkTiles, other -> +// println( +// "[${System.currentTimeMillis()}] reducing tiles " + +// "chunkTiles:${chunkTiles.chunkId.chunkPosition}, ${chunkTiles.chunkId.chunkSize}, ${chunkTiles.map.size} " + +// "other:${other.chunkId.chunkPosition}, ${other.chunkId.chunkSize}, ${other.map.size}" +// ) + chunkTiles + other + } val colourisedChunkTable: KTable> = chunkedTilesTable .join( other = tileProtoColourDict, tableJoined = tableJoined("server-map-data.join-tiles-with-prototypes"), - materialized = materializedAs( - "server-map-data.join-tiles-with-prototypes.store", + materialized = materializedWith( +// "server-map-data.join-tiles-with-prototypes.store", kxsBinary.serde(), kxsBinary.serde>(), ), - foreignKeyExtractor = { chunkTiles: ServerMapChunkTiles -> chunkTiles.chunkId.serverId } + foreignKeyExtractor = { chunkTiles: ServerMapChunkTiles -> + chunkTiles.chunkId.serverId + } ) { tiles: ServerMapChunkTiles, colourDict: TileColourDict -> +// println("joining tiles:${tiles.map.size} with colourDict:${colourDict.map.size}") val missingProtos = mutableSetOf() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt index 31a1bde..81f7e43 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt @@ -5,6 +5,7 @@ import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData import dev.adamko.kotka.extensions.consumedAs +import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.mapValues import dev.adamko.kotka.kxs.serde import org.apache.kafka.streams.StreamsBuilder @@ -16,12 +17,14 @@ inline fun StreamsBuilder.streamPacketData(): val simpleName = T::class.simpleName!! val topicName = T::class.topicName + val taskName = "consume.${simpleName}" + return stream( topicName, - consumedAs("consume.${simpleName}", jsonMapper.serde(), jsonMapper.serde()) - ).filter { key: FactorioServerId?, value: KafkatorioPacket? -> + consumedAs("$taskName.input", jsonMapper.serde(), jsonMapper.serde()) + ).filter("$taskName.filter-is-instance") { key: FactorioServerId?, value: KafkatorioPacket? -> key != null && value?.data is T - }.mapValues("consume.map-values.${simpleName}") { _: FactorioServerId, packet: KafkatorioPacket -> + }.mapValues("$taskName.map-values") { _: FactorioServerId, packet: KafkatorioPacket -> packet.data as T } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index 4661507..7514753 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -4,9 +4,10 @@ import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.MapTile import dev.adamko.kafkatorio.schema.common.toHex -import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate +import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype import dev.adamko.kotka.extensions.materializedAs +import dev.adamko.kotka.extensions.repartitionedAs import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.mapValues import dev.adamko.kotka.extensions.streams.toTable @@ -34,51 +35,35 @@ value class TileColourDict(val map: Map) fun tileProtoColourDictionary( factorioServerPacketStream: KStream ): KTable { + val pid = "tileProtoColourDictionary" - return factorioServerPacketStream.mapValues("server-map-data.tile-prototypes.map-values") { _, protoPacket: PrototypesUpdate -> + return factorioServerPacketStream.mapValues( + "$pid.map-values" + ) { _, protoPacket: PrototypesUpdate -> val map = protoPacket .prototypes .filterIsInstance() .associate { TileProtoHashCode(it) to it.mapColour.toHex() } TileColourDict(map) - }.filter("server-map-data.tile-prototypes.filterMapTileProtos") { _, dict: TileColourDict -> + }.filter("$pid.filterMapTileProtos") { _, dict: TileColourDict -> dict.map.isNotEmpty() }.peek { serverId, dict: TileColourDict -> - println("server $serverId has TileColourDict[${dict.map.size}]: ${dict.map.entries.joinToString()}") - }.toTable( - "server-map-data.tile-prototypes", + println("$pid: server $serverId has TileColourDict[${dict.map.size}]: ${dict.map.entries.joinToString()}") + }.repartition( + repartitionedAs( + "$pid.pre-table-repartition", + kxsBinary.serde(), + kxsBinary.serde(), + // force, otherwise KTable-KTable FK join doesn't work + numberOfPartitions = 1, + ) + ).toTable( + "$pid.create-table", materializedAs( - "server-map-data.tile-prototypes.store", + "$pid.output-store", kxsBinary.serde(), kxsBinary.serde(), ) ) } - -// get all the prototypes -// return factorioServerPacketStream -// .mapValues("server-map-data.tile-prototypes.mapValues") { _, packet: KafkatorioPacket -> -// val map = when (packet) { -// is FactorioPrototype -> packet -// .prototypes -// .filterIsInstance() -// .associate { TileProtoHashCode(it) to it.mapColour.toHex() } -// else -> mapOf() -// } -// TileColourDict(map) -// }.filter("server-map-data.tile-prototypes.filterMapTileProtos") { _, dict: TileColourDict -> -// dict.map.isNotEmpty() -// }.peek { serverId, dict: TileColourDict -> -// println("server $serverId has TileColourDict[${dict.map.size}]: ${dict.map.entries.joinToString()}") -// } -// .toTable( -// "server-map-data.tile-prototypes", -// materializedAs( -// "server-map-data.tile-prototypes.store", -// kxsBinary.serde(), -// kxsBinary.serde(), -// ) -// ) -// -//} From 4a2c7716034ad634cd26dadb1312ae1572a7a660 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 24 Apr 2022 11:32:34 +0200 Subject: [PATCH 289/629] experiment with optimising map-chunk message --- .../main/events/onMapChunkEventListeners.ts | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts index e30886d..75c9f7c 100644 --- a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts @@ -41,6 +41,43 @@ function mapTilesUpdateDebounce( protos: {}, } + + // let maxX = 0 + // let minX = 0 + // let maxY = 0 + // let minY = 0 + // for (const tile of tiles) { + // //@formatter:off + // if (tile.position.x < minX) minX = tile.position.x + // if (tile.position.x > maxX) maxX = tile.position.x + // if (tile.position.y > minY) minY = tile.position.y + // if (tile.position.y > maxY) maxY = tile.position.y + // //@formatter:on + // } + // + // const noTileProto = 0 + // + // const grid: int[][] = [] + // for (let x = 0; x < maxX; x++) { + // grid[x] = [] + // for (let y = 0; y < maxY; y++) { + // grid[x][y] = noTileProto + // } + // } + // data.tileDictionary.protos["no-tile"] = noTileProto + // + // let protosCount2: uint = 0 + // for (const tile of tiles) { + // const x = tile.position.x - minX + // const y = tile.position.y - minY + // + // data.tileDictionary.protos[tile.name] ??= protosCount2++ + // grid[x][y] = data.tileDictionary.protos[tile.name] + // } + // + // const grid2: string[] = grid.map(row => table.concat(row)) + + let protosCount: uint = 0 for (const tile of tiles) { data.tileDictionary.protos[tile.name] ??= protosCount++ From 12df3b80be8f2c4f10d1da99b0ec5473492d480d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 24 Apr 2022 11:32:56 +0200 Subject: [PATCH 290/629] visual test for map chunk grouper --- .../processor/topology/GroupMapChunksTest.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt index 74e9329..53dd5b4 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt @@ -103,6 +103,26 @@ class GroupMapChunksTest : FunSpec({ }.toSet() ) + val top: Int = value.map.keys.minOf { it.y } + val bottom = value.map.keys.maxOf { it.y } + val left = value.map.keys.minOf { it.x } + val right = value.map.keys.maxOf { it.x } + + val colours: MutableMap = mutableMapOf(null to " ") + + val mapRepresentation = buildString { + (top..bottom).forEach { y -> + (left..right).forEach { x -> + val colour = value.map[MapTilePosition(x, y)] + val a = colours.getOrPut(colour) { "${colours.size}" } + append(a) + } + appendLine() + } + } + println(mapRepresentation) + + // value shouldBeEqualToComparingFields ServerMapChunkTiles( // chunkId = key, // map = mapOf( From 4b5fb7a9441a139e750ac0e50211e6e3d9924f75 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 24 Apr 2022 11:33:18 +0200 Subject: [PATCH 291/629] kafka-streams: experiment with exposing jmx --- modules/events-server/build.gradle.kts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 581dd35..589f272 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -56,6 +56,14 @@ dependencies { application { mainClass.set("dev.adamko.kafkatorio.processor.EventProcessorKt") + +// applicationDefaultJvmArgs += listOf( +// "-Dcom.sun.management.jmxremote.port=9186", +// "-Dcom.sun.management.jmxremote.rmi.port=9186", +// "-Dcom.sun.management.jmxremote.ssl=false", +// "-Dcom.sun.management.jmxremote.local.only=false", +// "-Dcom.sun.management.jmxremote.authenticate=false", +// ) } tasks.withType { From 12a905e8da0fce415f3fa12908a965df43bc721d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 24 Apr 2022 11:33:25 +0200 Subject: [PATCH 292/629] bump kotka-streams version --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ad0931d..fda7746 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -104,7 +104,7 @@ kafka-streamsTestUtils = { group = "org.apache.kafka", name = "kafka-streams-tes # kafka helpers #kotka = { group = "com.github.blueanvil", name = "kotka", version = "1.1.1" } -kafka-kotkaStreams = { group = "com.github.adamko-dev.kotka-streams", name = "kotka-streams", version = "0.0.15" } +kafka-kotkaStreams = { group = "com.github.adamko-dev.kotka-streams", name = "kotka-streams", version = "v22.04.24" } jsoup = { group = "org.jsoup", name = "jsoup", version = "1.14.3" } skrapeit = { group = "it.skrape", name = "skrapeit", version = "1.2.0" } From 3606e512b00528cb8459af8255e733ef4c8b1881 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 24 Apr 2022 18:54:30 +0200 Subject: [PATCH 293/629] try fixing process checker, again --- .../adamko/kafkatorio/task/ProcessRunningSpec.kt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt index 46406a8..57ddf15 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt @@ -1,9 +1,11 @@ package dev.adamko.kafkatorio.task import java.io.ByteArrayOutputStream +import javax.inject.Inject import org.gradle.api.Task import org.gradle.api.internal.specs.ExplainingSpec import org.gradle.api.tasks.Exec +import org.gradle.process.ExecOperations /** Checks if a process is running. Windows only. */ class ProcessRunningSpec( @@ -11,17 +13,21 @@ class ProcessRunningSpec( private val ignoreCase: Boolean = true, ) : ExplainingSpec { + @Inject + fun executor(): ExecOperations { + throw UnsupportedOperationException() + } + override fun isSatisfiedBy(element: Task?): Boolean = whyUnsatisfied(element) == null - override fun whyUnsatisfied(element: Task?): String? = with(element) { - - when (this) { + override fun whyUnsatisfied(element: Task?): String? { + return when (element) { null -> "task is null" !is Exec -> "task ${this::class.simpleName} is not ${Exec::class.simpleName}" else -> { return ByteArrayOutputStream().use { outputStream -> - project.exec { + executor().exec { commandLine("tasklist") // Windows only for now... standardOutput = outputStream } From 041d570aed849f320a622c5adc69ec36ce42d1d6 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 24 Apr 2022 18:55:18 +0200 Subject: [PATCH 294/629] re-implement debounce processor... and then realise it's difficult to integrate with Kafka Streams DSL so don't use it --- .../processor/misc/DebounceProcessor.kt | 313 ++++++++++++------ .../processor/misc/DebounceProcessorTest.kt | 22 +- 2 files changed, 217 insertions(+), 118 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt index 8598c46..d4bf09b 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt @@ -1,29 +1,18 @@ package dev.adamko.kafkatorio.processor.misc -import dev.adamko.kotka.extensions.component1 -import dev.adamko.kotka.extensions.component2 -import dev.adamko.kotka.extensions.state.allAsSequence +import dev.adamko.kotka.extensions.state.useAll import kotlin.coroutines.CoroutineContext import kotlin.time.Duration -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.cancelChildren -import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.cancel import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.asFlow -import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.runningFold import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import org.apache.kafka.common.serialization.Serde -import org.apache.kafka.streams.KeyValue import org.apache.kafka.streams.processor.api.Processor import org.apache.kafka.streams.processor.api.ProcessorContext import org.apache.kafka.streams.processor.api.ProcessorSupplier @@ -37,117 +26,227 @@ import org.apache.kafka.streams.state.ValueAndTimestamp class DebounceProcessor( private val inactivityDuration: Duration, private val recordsTimestampedStoreName: String, - coroutineDispatcher: CoroutineDispatcher = Dispatchers.Default, -) : - Processor, - CoroutineScope { +) : Processor { - override var coroutineContext: CoroutineContext = - SupervisorJob() + - coroutineDispatcher + - CoroutineName("DebounceProcessor") + private var state: State = Uninitialised() - private lateinit var kafkaContext: ProcessorContext - private lateinit var recordsTimestampedStore: TimestampedKeyValueStore - - private val recordsFlow: MutableSharedFlow> = - MutableSharedFlow( - replay = 0, - extraBufferCapacity = Int.MAX_VALUE, - onBufferOverflow = BufferOverflow.DROP_OLDEST, - ) - - override fun init(context: ProcessorContext) { - this.kafkaContext = context - - this.coroutineContext += CoroutineName("DebounceProcessor-${context.applicationId()}-${context.taskId()}") - - recordsTimestampedStore = kafkaContext.getStateStore(recordsTimestampedStoreName) - - // start collecting records - create a debounce-timer for each record - recordsFlow - .runningFold(mapOf()) { acc, (k, createTask) -> - require(coroutineContext.isActive) - - // cancel any previously existing debounce task - acc[k]?.cancel() - - // add a new debounce task - when (createTask) { - true -> acc.plus(k to createDebounceTask(k)) - false -> acc.minus(k) - } - - }.launchIn(this) - - // re-initialise the flow from previously-stored records - launch { - recordsFlow.emitAll( - recordsTimestampedStore - .allAsSequence() - .map { keyValue -> - require(coroutineContext.isActive) - DebounceTaskInitializer(keyValue) - } - .asFlow() - ) - } + override fun init(kafkaContext: ProcessorContext) { + state = Active(kafkaContext) } - private fun createDebounceTask(key: K): Job { - return launch { - delay(inactivityDuration) - val (value, timestamp) = recordsTimestampedStore.get(key) - if (coroutineContext.isActive) { - kafkaContext.forward(Record(key, value, timestamp)) - } - } - } - - override fun process(record: Record) { - launch { - recordsTimestampedStore.put( - record.key(), - ValueAndTimestamp.make(record.value(), record.timestamp()) - ) - recordsFlow.emit(DebounceTaskInitializer(record)) + override fun process(record: Record) { + when (val state = state) { + is Active -> state.addRecord(record) + else -> error("state is not Active (actual: $state)") } } override fun close() { - coroutineContext.cancelChildren(CancellationException("processor go sleepy bye bye")) + (state as? Active)?.close() } -} + private sealed interface State -internal data class DebounceTaskInitializer( - val key: K, - val createTask: Boolean, -) { - constructor(keyValue: KeyValue) : this(keyValue.key, keyValue.value != null) - constructor(record: Record) : this(record.key(), record.value() != null) -} + private class Uninitialised : State + + private class Closed : State + + private inner class Active( + val kafkaContext: ProcessorContext, + ) : State, CoroutineScope { + override val coroutineContext: CoroutineContext = + SupervisorJob() + + Dispatchers.Unconfined + + CoroutineName("DebounceProcessor") + + val recordsTimestampedStore: TimestampedKeyValueStore = + kafkaContext.getStateStore(recordsTimestampedStoreName) + + private val recordJobs = mutableMapOf() + + init { + recordsTimestampedStore.useAll { + forEach { r -> + val record = Record(r.key, r.value.value(), r.value.timestamp()) + addRecord(record) + } + } + } + + fun addRecord(record: Record) { + recordJobs.compute(record.key()) { _, existing -> + if (existing != null && existing.timestamp < record.timestamp()) { + existing.job.cancel("replaced by newer record ${existing.timestamp} < ${record.timestamp()}") + createTimestampedJob(record) + } else { + null + } + } + } + + private fun createTimestampedJob(record: Record): TimestampedJob { + val job = launch { + recordsTimestampedStore.put( + record.key(), + ValueAndTimestamp.make(record.value(), record.timestamp()) + ) + delay(inactivityDuration) + if (isActive) { + kafkaContext.forward(record) + recordsTimestampedStore.delete(record.key()) + } + } + return TimestampedJob(job, record.timestamp()) + } + + fun close(): Closed { + coroutineContext.cancel() + return Closed() + } + } + + private data class TimestampedJob( + val job: Job, + val timestamp: Long, + ) -fun debounceProcessor( - inactivityDuration: Duration, - storeName: String, - keySerde: Serde, - valueSerde: Serde, -): ProcessorSupplier = - object : ProcessorSupplier { + companion object { + class Supplier( + private val inactivityDuration: Duration, + private val storeName: String, + private val keySerde: Serde, + private val valueSerde: Serde, + ) : ProcessorSupplier { - override fun get(): Processor = DebounceProcessor(inactivityDuration, storeName) + override fun get(): Processor = DebounceProcessor(inactivityDuration, storeName) - override fun stores(): Set> = setOf( - Stores.timestampedKeyValueStoreBuilder( - Stores.persistentTimestampedKeyValueStore(storeName), - keySerde, - valueSerde, + override fun stores(): Set> = setOf( + Stores.timestampedKeyValueStoreBuilder( + Stores.persistentTimestampedKeyValueStore(storeName), + keySerde, + valueSerde, + ) ) - ) - + } } +} + + +//class DebounceProcessor( +// private val inactivityDuration: Duration, +// private val recordsTimestampedStoreName: String, +// coroutineDispatcher: CoroutineDispatcher = Dispatchers.Default +//) : +// Processor, +// CoroutineScope { +// +// override var coroutineContext: CoroutineContext = +// SupervisorJob() + +// coroutineDispatcher + +// CoroutineName("DebounceProcessor") +// +// private lateinit var kafkaContext: ProcessorContext +// private lateinit var recordsTimestampedStore: TimestampedKeyValueStore +// +// private val recordsFlow: MutableSharedFlow> = +// MutableSharedFlow( +// replay = 0, +// extraBufferCapacity = Int.MAX_VALUE, +// onBufferOverflow = BufferOverflow.DROP_OLDEST, +// ) +// +// override fun init(context: ProcessorContext) { +// this.kafkaContext = context +// +// this.coroutineContext += CoroutineName("DebounceProcessor-${context.applicationId()}-${context.taskId()}") +// +// recordsTimestampedStore = kafkaContext.getStateStore(recordsTimestampedStoreName) +// +// // start collecting records - create a debounce-timer for each record +// recordsFlow +// .runningFold(mapOf()) { acc, (k, createTask) -> +// require(coroutineContext.isActive) +// +// // cancel any previously existing debounce task +// acc[k]?.cancel() +// +// // add a new debounce task +// when (createTask) { +// true -> acc.plus(k to createDebounceTask(k)) +// false -> acc.minus(k) +// } +// +// }.launchIn(this) +// +// // re-initialise the flow from previously-stored records +// launch { +// recordsFlow.emitAll( +// recordsTimestampedStore +// .allAsSequence() +// .map { keyValue -> +// require(coroutineContext.isActive) +// DebounceTaskInitializer(keyValue) +// } +// .asFlow() +// ) +// } +// } +// +// private fun createDebounceTask(key: K): Job { +// return launch { +// delay(inactivityDuration) +// val (value, timestamp) = recordsTimestampedStore.get(key) +// if (coroutineContext.isActive) { +// kafkaContext.forward(Record(key, value, timestamp)) +// } +// } +// } +// +// override fun process(record: Record) { +// launch { +// recordsTimestampedStore.put( +// record.key(), +// ValueAndTimestamp.make(record.value(), record.timestamp()) +// ) +// recordsFlow.emit(DebounceTaskInitializer(record)) +// } +// } +// +// override fun close() { +// coroutineContext.cancelChildren(CancellationException("processor go sleepy bye bye")) +// } +// +//} +// +//internal data class DebounceTaskInitializer( +// val key: K, +// val createTask: Boolean, +//) { +// constructor(keyValue: KeyValue) : this(keyValue.key, keyValue.value != null) +// constructor(record: Record) : this(record.key(), record.value() != null) +//} +// +// +//fun debounceProcessor( +// inactivityDuration: Duration, +// storeName: String, +// keySerde: Serde, +// valueSerde: Serde, +//): ProcessorSupplier = +// object : ProcessorSupplier { +// +// override fun get(): Processor = DebounceProcessor(inactivityDuration, storeName) +// +// override fun stores(): Set> = setOf( +// Stores.timestampedKeyValueStoreBuilder( +// Stores.persistentTimestampedKeyValueStore(storeName), +// keySerde, +// valueSerde, +// ) +// ) +// +// } //class SuppressProcessor( diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessorTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessorTest.kt index b7ff622..a8d777d 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessorTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessorTest.kt @@ -19,17 +19,17 @@ class DebounceProcessorTest : FunSpec({ fun blah() { - val topology = Topology() - - topology.addProcessor( - "blah", - debounceProcessor( - 1.minutes, - "asdasda", - Serdes.String(), - Serdes.String() - ) - ) +// val topology = Topology() +// +// topology.addProcessor( +// "blah", +// debounceProcessor( +// 1.minutes, +// "asdasda", +// Serdes.String(), +// Serdes.String() +// ) +// ) // val streamsBuilder = StreamsBuilder() From f36e84ddf5ceccf54edc4e7a5c35522ae3bab810 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 24 Apr 2022 18:55:47 +0200 Subject: [PATCH 295/629] webmap: use Ints for player lat/lng --- .../src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt index 050e966..9ff75ab 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt @@ -155,7 +155,10 @@ class PlayerState( options.color = playerColour options.fillColor = playerColour - setTooltipContent("${playerDetails.name} [${playerDetails.latLng}]") + val lat = playerDetails.latLng.lat.toInt() + val lng = playerDetails.latLng.lng.toInt() + + setTooltipContent("${playerDetails.name} [$lat, $lng]") setLatLng(playerDetails.latLng) } From d85815d9e1b949c5ef9c65d8e5c6a91ad4ed98f0 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 24 Apr 2022 18:58:05 +0200 Subject: [PATCH 296/629] disable kafka monitoring containers (I'm not really using them) --- .../src/docker-compose.yml | 82 +++++++++---------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/modules/infra-kafka-cluster/src/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml index c881589..40749ec 100644 --- a/modules/infra-kafka-cluster/src/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -56,47 +56,47 @@ services: # - "8083:8083" # - grafana: - image: "grafana/grafana:${GRAFANA_VERSION}" - container_name: "grafana" - ports: - - "3000:3000" - environment: - GF_PATHS_DATA : /var/lib/grafana - GF_SECURITY_ADMIN_PASSWORD : kafka - volumes: - - "./config/grafana/provisioning:/etc/grafana/provisioning" - - "./config/grafana/dashboards:/var/lib/grafana/dashboards" - depends_on: - - prometheus - networks: - - "kafka-nw" - - prometheus: - image: "prom/prometheus:${PROMETHEUS_VERSION}" - container_name: "prometheus" - ports: - - "9090:9090" - volumes: - - "./config/prometheus.yml:/etc/prometheus/prometheus.yml" - command: "--config.file=/etc/prometheus/prometheus.yml" - networks: - - "kafka-nw" - - jmx-kafka: - image: "sscaling/jmx-prometheus-exporter" - container_name: "jmx-kafka" - ports: - - "5556:5556" - environment: - CONFIG_YML : "/etc/jmx_exporter/config.yml" -# JVM_OPTS: "-XX:MaxRAMPercentage=70.0" - volumes: - - "./config/jmx_exporter_kafka_broker.yml:/etc/jmx_exporter/config.yml" - depends_on: - - kafka - networks: - - "kafka-nw" +# grafana: +# image: "grafana/grafana:${GRAFANA_VERSION}" +# container_name: "grafana" +# ports: +# - "3000:3000" +# environment: +# GF_PATHS_DATA : /var/lib/grafana +# GF_SECURITY_ADMIN_PASSWORD : kafka +# volumes: +# - "./config/grafana/provisioning:/etc/grafana/provisioning" +# - "./config/grafana/dashboards:/var/lib/grafana/dashboards" +# depends_on: +# - prometheus +# networks: +# - "kafka-nw" +# +# prometheus: +# image: "prom/prometheus:${PROMETHEUS_VERSION}" +# container_name: "prometheus" +# ports: +# - "9090:9090" +# volumes: +# - "./config/prometheus.yml:/etc/prometheus/prometheus.yml" +# command: "--config.file=/etc/prometheus/prometheus.yml" +# networks: +# - "kafka-nw" +# +# jmx-kafka: +# image: "sscaling/jmx-prometheus-exporter" +# container_name: "jmx-kafka" +# ports: +# - "5556:5556" +# environment: +# CONFIG_YML : "/etc/jmx_exporter/config.yml" +## JVM_OPTS: "-XX:MaxRAMPercentage=70.0" +# volumes: +# - "./config/jmx_exporter_kafka_broker.yml:/etc/jmx_exporter/config.yml" +# depends_on: +# - kafka +# networks: +# - "kafka-nw" networks: kafka-nw: From e05db4398a78368468ad5aa6e14291003555a1bd Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 24 Apr 2022 18:59:43 +0200 Subject: [PATCH 297/629] re-implement tile saver, without Coroutines or debouncing. It seems to work well. --- .../processor/KafkatorioTopology.kt | 5 +- .../processor/topology/flowMapTiles.kt | 47 ++++++--- .../processor/topology/flowMapTiles2.kt | 99 +++++++++++++++++++ 3 files changed, 135 insertions(+), 16 deletions(-) create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles2.kt diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 5f5b68f..acb614b 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -4,7 +4,7 @@ import dev.adamko.kafkatorio.processor.config.ApplicationProperties import dev.adamko.kafkatorio.processor.topology.factorioServerPacketStream import dev.adamko.kafkatorio.processor.topology.groupMapChunks import dev.adamko.kafkatorio.processor.topology.playerUpdatesToWsServer -import dev.adamko.kafkatorio.processor.topology.saveMapTiles +import dev.adamko.kafkatorio.processor.topology.saveMapTiles2 import dev.adamko.kafkatorio.processor.topology.splitFactorioServerPacketStream import java.time.Duration import java.util.Properties @@ -59,7 +59,8 @@ internal class KafkatorioTopology( private fun saveTiles() { val builder = StreamsBuilder() - val topology = saveMapTiles(builder) +// val topology = saveMapTiles(builder) + val topology = saveMapTiles2(builder) launchTopology("saveTiles", topology) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt index 3909488..ede9b1e 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt @@ -4,12 +4,17 @@ import com.sksamuel.scrimage.ImmutableImage import com.sksamuel.scrimage.ScaleMethod import com.sksamuel.scrimage.color.RGBColor import com.sksamuel.scrimage.nio.PngWriter -import dev.adamko.kafkatorio.schema.common.* import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.MapChunkPosition +import dev.adamko.kafkatorio.schema.common.MapTilePosition +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.common.toMapChunkPosition import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.streams.forEach import dev.adamko.kotka.kxs.serde +import java.awt.Color import java.awt.image.BufferedImage import java.io.File import kotlin.coroutines.CoroutineContext @@ -36,6 +41,7 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.runningFold import kotlinx.coroutines.launch import kotlinx.coroutines.supervisorScope +import kotlinx.serialization.Serializable import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.Topology import org.apache.kafka.streams.kstream.KStream @@ -51,11 +57,12 @@ private val serverMapChunkHandler = ServerMapChunkHandler() fun saveMapTiles( builder: StreamsBuilder, ): Topology { + val pid = "saveMapTiles" val groupedMapChunkTiles: KStream> = builder.stream( TOPIC_GROUPED_MAP_CHUNKS_STATE, - consumedAs("consume.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()) + consumedAs("$pid.consume.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()) ) groupedMapChunkTiles @@ -71,24 +78,24 @@ fun saveMapTiles( @JvmInline -private value class TilePngFilename( +value class TilePngFilename( val value: String, ) { - constructor(cmd: Cmd.CreateImage) : this(buildString { + constructor(id: ServerMapChunkId) : this(buildString { append("src/main/resources/kafkatorio-web-map") - append("/s${cmd.surfaceIndex}") - append("/z${cmd.chunkSize.zoomLevel}") - append("/x${cmd.chunkPosition.x}") - append("/y${cmd.chunkPosition.y}") + append("/s${id.surfaceIndex}") + append("/z${id.chunkSize.zoomLevel}") + append("/x${id.chunkPosition.x}") + append("/y${id.chunkPosition.y}") append(".png") }) } -private val TRANSPARENT_AWT = ColourHex.TRANSPARENT.toRgbColor().awt() +val TRANSPARENT_AWT: Color = ColourHex.TRANSPARENT.toRgbColor().awt() -private fun ColourHex.toRgbColor(): RGBColor { +fun ColourHex.toRgbColor(): RGBColor { return RGBColor( red.toInt(), green.toInt(), @@ -210,15 +217,13 @@ private class ServerMapChunkHandler : CoroutineScope { .asFlow() } .map { createCmd -> - val filename = TilePngFilename(createCmd) - val img = createMapTileImage( createCmd.chunkPosition, createCmd.tiles, createCmd.chunkSize, ) - Cmd.SaveImage(filename, img) + Cmd.SaveImage(createCmd.tilePngFilename, img) } launch { @@ -270,17 +275,31 @@ private class ServerMapChunkHandler : CoroutineScope { private sealed interface Cmd { + @Serializable data class ChunkSubdivide( val chunkId: ServerMapChunkId, val tiles: Map, ) : Cmd + @Serializable data class CreateImage( val surfaceIndex: SurfaceIndex, val chunkSize: ChunkSize, val chunkPosition: MapChunkPosition, val tiles: Map, - ) : Cmd + ) : Cmd { + val tilePngFilename: TilePngFilename by lazy { + TilePngFilename(buildString { + append("src/main/resources/kafkatorio-web-map") + append("/s${surfaceIndex}") + append("/z${chunkSize.zoomLevel}") + append("/x${chunkPosition.x}") + append("/y${chunkPosition.y}") + append(".png") + }) + } + } + data class SaveImage( val filename: TilePngFilename, diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles2.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles2.kt new file mode 100644 index 0000000..5cdd67e --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles2.kt @@ -0,0 +1,99 @@ +package dev.adamko.kafkatorio.processor.topology + +import com.sksamuel.scrimage.ImmutableImage +import com.sksamuel.scrimage.ScaleMethod +import com.sksamuel.scrimage.nio.PngWriter +import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE +import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.toMapChunkPosition +import dev.adamko.kotka.extensions.consumedAs +import dev.adamko.kotka.extensions.streams.flatMap +import dev.adamko.kotka.extensions.streams.forEach +import dev.adamko.kotka.kxs.serde +import java.awt.image.BufferedImage +import java.io.File +import kotlin.io.path.fileSize +import kotlin.math.abs +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.Topology +import org.apache.kafka.streams.kstream.KStream + + +private const val WEB_MAP_TILE_SIZE_PX = 256 + + +fun saveMapTiles2( + builder: StreamsBuilder, +): Topology { + val pid = "saveMapTiles" + + val groupedMapChunkTiles: KStream> = + builder.stream( + TOPIC_GROUPED_MAP_CHUNKS_STATE, + consumedAs("$pid.consume.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()) + ) + + groupedMapChunkTiles.flatMap("$pid.subdivide-chunks") { initialKey, initialChunk -> + ChunkSize.entries.flatMap { chunkSize -> + initialChunk.map.entries + .groupBy( + { (tile, _) -> tile.toMapChunkPosition(chunkSize.tilesPerChunk) } + ) { (tilePosition, colour) -> + tilePosition to colour + } + .map { (chunkPos, tiles) -> + val key = initialKey.copy( + chunkSize = chunkSize, + chunkPosition = chunkPos + ) + + val value = ServerMapChunkTiles(key, tiles.toMap()) + + key to value + } + } + }.forEach("$pid.save-tiles") { key, value -> + val filename = TilePngFilename(key) + val chunkColours = value.map + + val chunkImage = ImmutableImage.filled( + key.chunkSize.tilesPerChunk, + key.chunkSize.tilesPerChunk, + TRANSPARENT_AWT, + BufferedImage.TYPE_INT_ARGB + ) + + val chunkOriginX: Int = key.chunkPosition.x * key.chunkSize.tilesPerChunk + val chunkOriginY: Int = key.chunkPosition.y * key.chunkSize.tilesPerChunk + + chunkColours.forEach { (tilePosition, colour) -> + val rgbColour = colour.toRgbColor() + + val pixelX = abs(abs(tilePosition.x) - abs(chunkOriginX)) + val pixelY = abs(abs(tilePosition.y) - abs(chunkOriginY)) + + chunkImage.setColor(pixelX, pixelY, rgbColour) + } + + val img = chunkImage.scaleTo(WEB_MAP_TILE_SIZE_PX, WEB_MAP_TILE_SIZE_PX, ScaleMethod.FastScale) + + val chunkImageFile = File(filename.value) + if (chunkImageFile.parentFile.mkdirs()) { + println("created new map tile parentFile directory ${chunkImageFile.absolutePath}") + } + + val sizeBefore = chunkImageFile.takeIf { it.exists() }?.toPath()?.fileSize() + + val savedTile = img.output(PngWriter.NoCompression, chunkImageFile) + + val sizeAfter = savedTile.takeIf { it.exists() }?.toPath()?.fileSize() + if (sizeBefore != sizeAfter) { +// println("savedTile $sizeBefore/$sizeAfter: $savedTile") + } else { + println("savedTile NO-SIZE-CHANGE $sizeBefore/$sizeAfter: $savedTile") + } + } + + return builder.build() +} From b4ba87e8e0ddc705eb9d049d4766399a8f07df3f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 24 Apr 2022 19:00:37 +0200 Subject: [PATCH 298/629] try fixing tstl task caching --- .../dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt | 11 ++++++----- modules/events-server/build.gradle.kts | 4 ++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt index e98ddf6..7bf6fb2 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt @@ -6,31 +6,32 @@ import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.FileSystemOperations import org.gradle.api.plugins.BasePlugin import org.gradle.api.tasks.CacheableTask +import org.gradle.api.tasks.IgnoreEmptyDirectories import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.Internal import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.PathSensitive import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.SkipWhenEmpty import org.gradle.api.tasks.TaskAction -import org.gradle.work.Incremental import org.gradle.work.NormalizeLineEndings import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs @CacheableTask -abstract class TypescriptToLuaTask : NpmTask() { +abstract class TypescriptToLuaTask @Inject constructor( + private val fs: FileSystemOperations +) : NpmTask() { @get:InputDirectory @get:SkipWhenEmpty @get:PathSensitive(PathSensitivity.RELATIVE) @get:NormalizeLineEndings + @get:IgnoreEmptyDirectories abstract val sourceFiles: DirectoryProperty @get:OutputDirectory abstract val outputDirectory: DirectoryProperty - @get:Inject - abstract val fs: FileSystemOperations - init { super.setGroup(BasePlugin.BUILD_GROUP) super.setDescription("Convert Typescript To Lua") diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 589f272..eafe6bf 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -94,3 +94,7 @@ idea { excludeDirs = excludeDirs + kafkaStateDir.asFile } } + +//tasks.withType().all { +// notCompatibleWithConfigurationCache("error: Projects must be configuring") +//} From d79a30b1ece70d0f4ff42428d471b837b20d6f8f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 24 Apr 2022 21:01:16 +0200 Subject: [PATCH 299/629] fix factorio running check again?? --- .../dev/adamko/kafkatorio/task/ProcessRunningSpec.kt | 8 ++------ modules/infra-factorio-client/build.gradle.kts | 10 +++++++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt index 57ddf15..a677735 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/ProcessRunningSpec.kt @@ -9,15 +9,11 @@ import org.gradle.process.ExecOperations /** Checks if a process is running. Windows only. */ class ProcessRunningSpec( + private val executor: ExecOperations, private val process: String, private val ignoreCase: Boolean = true, ) : ExplainingSpec { - @Inject - fun executor(): ExecOperations { - throw UnsupportedOperationException() - } - override fun isSatisfiedBy(element: Task?): Boolean = whyUnsatisfied(element) == null override fun whyUnsatisfied(element: Task?): String? { @@ -27,7 +23,7 @@ class ProcessRunningSpec( else -> { return ByteArrayOutputStream().use { outputStream -> - executor().exec { + executor.exec { commandLine("tasklist") // Windows only for now... standardOutput = outputStream } diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index c92ee46..8288025 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -2,6 +2,7 @@ import dev.adamko.kafkatorio.gradle.asConsumer import dev.adamko.kafkatorio.gradle.factorioModAttributes import dev.adamko.kafkatorio.gradle.not import dev.adamko.kafkatorio.task.ProcessRunningSpec +import org.gradle.kotlin.dsl.support.serviceOf import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { @@ -38,13 +39,14 @@ val deployModToClient by tasks.registering(Copy::class) { // // -fun isFactorioRunning(): Spec = ProcessRunningSpec("factorio.exe") +fun ExecOperations.isFactorioRunning(): Spec = ProcessRunningSpec(this, "factorio.exe") + val clientLaunch by tasks.registering(Exec::class) { description = "Run Factorio Steam game client" group = project.name - onlyIf(!isFactorioRunning()) + onlyIf(!serviceOf().isFactorioRunning()) dependsOn(deployModToClient) mustRunAfter(clientKill, ":modules:infra-factorio-server:processRun") @@ -60,7 +62,9 @@ val clientLaunch by tasks.registering(Exec::class) { val clientKill by tasks.registering(Exec::class) { description = "Run Factorio Steam game client" group = project.name - onlyIf(isFactorioRunning()) + + onlyIf(serviceOf().isFactorioRunning()) + commandLine = parseSpaceSeparatedArgs(""" taskkill /im factorio.exe """) doFirst { logger.lifecycle("Killing factorio.exe") } } From bc6574bb7e8a460d8208442d595728e176e65233 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 09:40:23 +0200 Subject: [PATCH 300/629] ignore jvm memory crashes --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 9982af0..a9942d5 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ node_modules +*.hprof + # Created by https://www.toptal.com/developers/gitignore/api/windows,macos,linux,gradle,intellij,visualstudiocode,kotlin # Edit at https://www.toptal.com/developers/gitignore?templates=windows,macos,linux,gradle,intellij,visualstudiocode,kotlin From a78ffb794a5a709feaed72e36733514aab467fbe Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 09:41:49 +0200 Subject: [PATCH 301/629] implement versions platform, tidy up and bump some dependencies --- gradle/libs.versions.toml | 45 ++++++++++++------- modules/events-server/build.gradle.kts | 6 +-- .../build.gradle.kts | 5 +-- modules/infra-kafka-connect/build.gradle.kts | 8 ++-- modules/kt-rcon/build.gradle.kts | 12 ++--- modules/versions-platform/build.gradle.kts | 41 +++++++++++++++++ modules/web-map/build.gradle.kts | 36 +++++++-------- settings.gradle.kts | 2 + 8 files changed, 101 insertions(+), 54 deletions(-) create mode 100644 modules/versions-platform/build.gradle.kts diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fda7746..c112b5e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,16 +10,24 @@ kotlin = "1.6.21" ## libs ## camel-kafkaConnectors = "0.11.0" -http4k = "4.19.1.0" +http4k = "4.25.12.0" kafka = "3.1.0" -kotlinx-serialization = "1.3.2" kvision = "5.9.0" log4j2 = "2.17.2" qosLogback = "1.2.11" slf4j = "1.7.36" okio = "3.1.0" +scrimage = "4.0.31" + +kotlinx-serialization = "1.3.2" +kxs-yaml = "0.43.0" kotlinJsWrappers = "0.0.1-pre.331-kotlin-1.6.20" +kotlinx-html = "0.7.5" +kotlinx-nodejs = "0.0.7" +kotlinx-coroutines = "1.6.1" + +ktor = "2.0.1" ## test ## @@ -52,20 +60,20 @@ dependencyCheck = { id = "com.github.ben-manes.versions", vers ## kotlin ## kotlin-bom = { group = "org.jetbrains.kotlin", name = "kotlin-bom", version.ref = "kotlin" } -kotlinx-serialization-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-bom", version.ref = "kotlinx-serialization" } -kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core" } -kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json" } +kotlinx-serialization-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-bom", version.ref = "kotlinx-serialization" } +kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core" } +kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json" } kotlinx-serialization-protobuf = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-protobuf" } -kotlinx-serialization-yaml = { group = "com.charleskorn.kaml", name = "kaml", version = "0.37.0" } +kotlinx-serialization-yaml = { group = "com.charleskorn.kaml", name = "kaml", version.ref = "kxs-yaml" } -kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.6.1" } +kotlinx-coroutines-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-bom", version.ref = "kotlinx-coroutines" } +kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core" } -kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.7.5" } -kotlinx-nodejs = { group = "org.jetbrains.kotlinx", name = "kotlinx-nodejs", version = "0.0.7" } - -kotlin-jsWrappers-bom = { group = "org.jetbrains.kotlin-wrappers", name = "kotlin-wrappers-bom", version.ref = "kotlinJsWrappers" } +kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version.ref = "kotlinx-html" } +kotlinx-nodejs = { group = "org.jetbrains.kotlinx", name = "kotlinx-nodejs", version.ref = "kotlinx-nodejs" } +kotlin-jsWrappers-bom = { group = "org.jetbrains.kotlin-wrappers", name = "kotlin-wrappers-bom", version.ref = "kotlinJsWrappers" } ## http4k ## http4k-bom = { group = "org.http4k", name = "http4k-bom", version.ref = "http4k" } @@ -81,6 +89,11 @@ http4k-format-yaml = { group = "org.http4k", name = "http4k-format-jackson-y http4k-format-kotlinx = { group = "org.http4k", name = "http4k-format-kotlinx-serialization" } http4k-graphql = { group = "org.http4k", name = "http4k-graphql" } + +## ktor ## +ktor-bom = { group = "io.ktor", name = "ktor-bom", version.ref = "ktor" } + + ### jackson ## #jackson-bom = { group = " com.fasterxml.jackson.module", name = ":jackson-module-kotlin", version = "2.13.+" } #jackson-kotlin = { group = " com.fasterxml.jackson.module", name = ":jackson-module-kotlin", version = "2.13.+" } @@ -106,10 +119,10 @@ kafka-streamsTestUtils = { group = "org.apache.kafka", name = "kafka-streams-tes kafka-kotkaStreams = { group = "com.github.adamko-dev.kotka-streams", name = "kotka-streams", version = "v22.04.24" } -jsoup = { group = "org.jsoup", name = "jsoup", version = "1.14.3" } +jsoup = { group = "org.jsoup", name = "jsoup", version = "1.14.3" } skrapeit = { group = "it.skrape", name = "skrapeit", version = "1.2.0" } -scrimage-core = { group = "com.sksamuel.scrimage", name = "scrimage-core", version = "4.0.31" } +scrimage-core = { group = "com.sksamuel.scrimage", name = "scrimage-core", version.ref = "scrimage" } ## okio ## @@ -125,9 +138,9 @@ mockk = { group = "io.mockk", name = "mockk", version = "1.12.3" } ## junit ## junit-bom = { group = "org.junit", name = "junit-bom", version.ref = "junit" } -junit-api = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junit" } -junit-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine", version.ref = "junit" } -junit-launcher = { group = "org.junit.platform", name = "junit-platform-launcher", version = "1.7.2" } +junit-api = { group = "org.junit.jupiter", name = "junit-jupiter-api" } # version.ref = "junit" } +junit-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine" } # version.ref = "junit" } +junit-launcher = { group = "org.junit.platform", name = "junit-platform-launcher" } # version = "1.7.2" } ## kotest ## kotest-bom = { group = "io.kotest", name = "kotest-bom", version.ref = "kotest" } diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index eafe6bf..6e7d04c 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -18,6 +18,7 @@ val projectId: String by project.extra val kafkaStateDir = layout.projectDirectory.dir("kafka-state") dependencies { + implementation(platform(projects.modules.versionsPlatform)) implementation(libs.kafka.streams) testImplementation(libs.kafka.streamsTestUtils) @@ -26,14 +27,12 @@ dependencies { // implementation("com.ionspin.kotlin:bignum:0.3.3") - implementation(platform(libs.kotlinx.serialization.bom)) implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.json) // implementation("org.jetbrains.kotlinx:kotlinx-serialization-protobuf") - implementation(libs.kotlinx.coroutines) + implementation(libs.kotlinx.coroutines.core) - implementation(platform(libs.http4k.bom)) implementation(libs.bundles.http4k) implementation(libs.http4k.format.kotlinx) @@ -41,7 +40,6 @@ dependencies { implementation(libs.scrimage.core) - implementation(platform(libs.okio.bom)) implementation(libs.okio.core) implementation(libs.kafka.kotkaStreams) { diff --git a/modules/factorio-mod-portal-client/build.gradle.kts b/modules/factorio-mod-portal-client/build.gradle.kts index 0f3cb8d..3475da0 100644 --- a/modules/factorio-mod-portal-client/build.gradle.kts +++ b/modules/factorio-mod-portal-client/build.gradle.kts @@ -8,16 +8,15 @@ plugins { dependencies { + implementation(platform(projects.modules.versionsPlatform)) implementation(projects.modules.eventsServer) - implementation(platform(libs.kotlinx.serialization.bom)) implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.json) - implementation(libs.kotlinx.coroutines) + implementation(libs.kotlinx.coroutines.core) - implementation(platform(libs.http4k.bom)) implementation(libs.bundles.http4k) implementation(libs.http4k.format.kotlinx) diff --git a/modules/infra-kafka-connect/build.gradle.kts b/modules/infra-kafka-connect/build.gradle.kts index 19ce2fa..69b2970 100644 --- a/modules/infra-kafka-connect/build.gradle.kts +++ b/modules/infra-kafka-connect/build.gradle.kts @@ -23,6 +23,8 @@ fun DependencyHandlerScope.kafkaConnector( } dependencies { + implementation(platform(projects.modules.versionsPlatform)) + kotlin("reflect") kafkaConnector("camel-ahc-ws-kafka-connector") @@ -30,12 +32,10 @@ dependencies { implementation("com.github.adamko-dev:json5-kotlin:2.0.3") - implementation(platform(libs.http4k.bom)) implementation(libs.bundles.http4k) - implementation(platform(libs.kotlinx.serialization.bom)) - implementation("org.jetbrains.kotlinx:kotlinx-serialization-core") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json") + implementation(libs.kotlinx.serialization.core) + implementation(libs.kotlinx.serialization.json) } // disabled for now... diff --git a/modules/kt-rcon/build.gradle.kts b/modules/kt-rcon/build.gradle.kts index caa6ded..375e7b6 100644 --- a/modules/kt-rcon/build.gradle.kts +++ b/modules/kt-rcon/build.gradle.kts @@ -2,16 +2,10 @@ plugins { dev.adamko.kafkatorio.lang.`kotlin-jvm` } -//group = "${rootProject.group}.server" -//version = rootProject.version -// - dependencies { + implementation(platform(projects.modules.versionsPlatform)) - implementation(enforcedPlatform(libs.kotlinx.serialization.bom)) - - implementation(libs.kotlinx.coroutines) - - implementation("io.ktor:ktor-network:1.6.4") + implementation(libs.kotlinx.coroutines.core) + implementation("io.ktor:ktor-network") } diff --git a/modules/versions-platform/build.gradle.kts b/modules/versions-platform/build.gradle.kts new file mode 100644 index 0000000..bb93f8c --- /dev/null +++ b/modules/versions-platform/build.gradle.kts @@ -0,0 +1,41 @@ +plugins { + `java-platform` +} + + +javaPlatform { + allowDependencies() +} + + +dependencies { + api(platform(libs.kotlin.bom)) + api(platform(libs.kotlinx.coroutines.bom)) + api(platform(libs.kotlinx.serialization.bom)) + + api(platform(libs.http4k.bom)) + + api(platform(libs.okio.bom)) + + api(platform(libs.ktor.bom)) + + api(platform(libs.kotest.bom)) + + constraints { + api(libs.skrapeit) + api(libs.kotlinx.serialization.yaml) + + + + + + + + + api(libs.kafka.kotkaStreams) + api(libs.kafka.streams) + api(libs.okio.core) + api(libs.scrimage.core) + api(libs.kafka.streamsTestUtils) + } +} diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 189500f..5f125d7 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -1,4 +1,3 @@ -import dev.adamko.kafkatorio.gradle.yarn import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig @@ -66,15 +65,16 @@ kotlin { kvision("kvision-redux") kvision("kvision-state-flow") - implementation(libs.kotlinx.coroutines) - + implementation(dependencies.platform(libs.kotlinx.coroutines.bom)) implementation(dependencies.platform(libs.kotlin.jsWrappers.bom)) -// implementation(dependencies.platform(npm("follow-redirects", "^1.14.8"))) -// implementation(dependencies.platform(npm("nanoid", "^3.1.31"))) -// implementation(dependencies.platform(npm("minimist", "^1.2.6"))) -// implementation(dependencies.platform(npm("async", "^2.6.4"))) -// implementation(dependencies.platform(npm("node-forge", "^1.3.0"))) + implementation(libs.kotlinx.coroutines.core) + + implementation(dependencies.platform(npm("follow-redirects", "^1.14.8"))) + implementation(dependencies.platform(npm("nanoid", "^3.1.31"))) + implementation(dependencies.platform(npm("minimist", "^1.2.6"))) + implementation(dependencies.platform(npm("async", "^2.6.4"))) + implementation(dependencies.platform(npm("node-forge", "^1.3.0"))) } val webDir = file("src/main/web") @@ -104,13 +104,13 @@ fun KotlinDependencyHandler.kvision( } // https://youtrack.jetbrains.com/issue/KT-42420 -afterEvaluate { - yarn { - resolution("mocha", "9.2.2") - resolution("follow-redirects", "1.14.8") - resolution("nanoid", "3.1.31") - resolution("minimist", "1.2.6") - resolution("async", "2.6.4") - resolution("node-forge", "1.3.0") - } -} +//afterEvaluate { +// yarn { +// resolution("mocha", "9.2.2") +// resolution("follow-redirects", "1.14.8") +// resolution("nanoid", "3.1.31") +// resolution("minimist", "1.2.6") +// resolution("async", "2.6.4") +// resolution("node-forge", "1.3.0") +// } +//} diff --git a/settings.gradle.kts b/settings.gradle.kts index 8d88dea..c67af44 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -16,6 +16,8 @@ include( ":modules:web-map", ":modules:factorio-mod-portal-client", + + ":modules:versions-platform", ) enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") From 0b2bd7d10da0ae300d566162a9ce64f4bfb0de8a Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 09:42:38 +0200 Subject: [PATCH 302/629] bump ktor to v2 --- .../kotlin/dev/adamko/ktrcon/KtRconClient.kt | 40 +++++++------------ .../kotlin/dev/adamko/ktrcon/KtRconClient2.kt | 22 ++-------- .../kotlin/dev/adamko/ktrcon/KtRconClient3.kt | 35 ++++------------ .../main/kotlin/dev/adamko/ktrcon/Packet.kt | 37 +++++++++-------- 4 files changed, 45 insertions(+), 89 deletions(-) diff --git a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient.kt b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient.kt index c5f4419..d1d068a 100644 --- a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient.kt +++ b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient.kt @@ -1,14 +1,6 @@ package dev.adamko.ktrcon -import java.io.* import java.net.Socket -import java.net.SocketException -import java.nio.BufferUnderflowException -import java.nio.ByteBuffer -import java.nio.ByteOrder -import java.nio.channels.AsynchronousSocketChannel -import kotlin.coroutines.coroutineContext -import kotlin.coroutines.suspendCoroutine import kotlin.random.Random import kotlin.random.nextUInt import kotlinx.coroutines.CoroutineScope @@ -17,15 +9,13 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.supervisorScope -import kotlinx.coroutines.yield class KtRconClient( - private val host: String, - private val port: Int, - private val password: Password, + private val host: String, + private val port: Int, + private val password: Password, ) : AutoCloseable { private val rconClientScope = CoroutineScope(SupervisorJob()) @@ -46,22 +36,22 @@ class KtRconClient( runCatching { val reader = socket.getInputStream() - .bufferedReader() - .lineSequence() - .asFlow() - .onEach { - println("socket response: [$it]") - } - .launchIn(rconClientScope) + .bufferedReader() + .lineSequence() + .asFlow() + .onEach { + println("socket response: [$it]") + } + .launchIn(rconClientScope) // while (socket.isConnected) { // println("response: ${input.read().toByte().toInt().toChar()}") - println("is listener active? ${reader.isActive}") + println("is listener active? ${reader.isActive}") - reader.invokeOnCompletion { - println("cancelled input stream job") - } + reader.invokeOnCompletion { + println("cancelled input stream job") + } } // } @@ -121,4 +111,4 @@ class KtRconClient( } -} \ No newline at end of file +} diff --git a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient2.kt b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient2.kt index dd79d4e..d74447d 100644 --- a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient2.kt +++ b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient2.kt @@ -1,34 +1,20 @@ package dev.adamko.ktrcon -import java.io.* import java.net.InetSocketAddress -import java.net.Socket -import java.net.SocketException -import java.nio.BufferUnderflowException import java.nio.ByteBuffer -import java.nio.ByteOrder import java.nio.channels.AsynchronousSocketChannel -import java.nio.channels.CompletionHandler -import java.util.concurrent.TimeUnit -import kotlin.coroutines.coroutineContext -import kotlin.coroutines.suspendCoroutine import kotlin.random.Random import kotlin.random.nextUInt import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.asFlow -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking import kotlinx.coroutines.supervisorScope -import kotlinx.coroutines.yield class KtRconClient2( - private val host: String, - private val port: Int, - private val password: Password, + private val host: String, + private val port: Int, + private val password: Password, ) : AutoCloseable { private val rconClientScope = CoroutineScope(SupervisorJob()) @@ -100,4 +86,4 @@ class KtRconClient2( client.close() } -} \ No newline at end of file +} diff --git a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient3.kt b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient3.kt index cdf69d0..04fa2d4 100644 --- a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient3.kt +++ b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient3.kt @@ -1,47 +1,28 @@ package dev.adamko.ktrcon import io.ktor.network.selector.ActorSelectorManager +import io.ktor.network.sockets.InetSocketAddress import io.ktor.network.sockets.aSocket import io.ktor.network.sockets.openReadChannel import io.ktor.network.sockets.openWriteChannel -import io.ktor.util.decodeString import io.ktor.utils.io.ByteReadChannel import io.ktor.utils.io.ByteWriteChannel import io.ktor.utils.io.core.isNotEmpty import io.ktor.utils.io.core.readBytes -import io.ktor.utils.io.readRemaining -import io.ktor.utils.io.readUTF8Line -import io.ktor.utils.io.writeIntLittleEndian -import io.ktor.utils.io.writeStringUtf8 -import java.io.* -import java.net.InetSocketAddress -import java.net.Socket -import java.net.SocketException -import java.nio.BufferUnderflowException -import java.nio.ByteBuffer -import java.nio.ByteOrder -import java.nio.channels.AsynchronousSocketChannel -import java.nio.channels.CompletionHandler -import java.util.concurrent.TimeUnit -import kotlin.coroutines.coroutineContext -import kotlin.coroutines.suspendCoroutine import kotlin.random.Random import kotlin.random.nextUInt import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.asFlow -import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.supervisorScope import kotlinx.coroutines.yield class KtRconClient3( - private val host: String, - private val port: Int, - private val password: Password, + private val host: String, + private val port: Int, + private val password: Password, ) : AutoCloseable { private val rconClientJob = SupervisorJob() @@ -54,8 +35,8 @@ class KtRconClient3( val socket = runBlocking { val selector = ActorSelectorManager(rconClientJob) aSocket(selector) - .tcp() - .connect(InetSocketAddress(host, port)) + .tcp() + .connect(InetSocketAddress(host, port)) } input = socket.openReadChannel() output = socket.openWriteChannel() @@ -74,7 +55,7 @@ class KtRconClient3( while (packet.isNotEmpty) { val bytes = packet.readBytes() println( - "received ${bytes.size} bytes: ${bytes.joinToString { "$it" }} - ${bytes.decodeToString()}" + "received ${bytes.size} bytes: ${bytes.joinToString { "$it" }} - ${bytes.decodeToString()}" ) yield() } @@ -127,4 +108,4 @@ class KtRconClient3( rconClientScope.cancel("Closing ${this::class}") } -} \ No newline at end of file +} diff --git a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/Packet.kt b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/Packet.kt index baa296b..eacc965 100644 --- a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/Packet.kt +++ b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/Packet.kt @@ -1,6 +1,5 @@ package dev.adamko.ktrcon -import io.ktor.utils.io.bits.reverseByteOrder import java.nio.ByteBuffer import java.nio.ByteOrder @@ -28,9 +27,9 @@ import java.nio.ByteOrder * to be executed, or the server's response to a request. */ data class Packet( - val id: UInt, - val type: PacketType, - val bodyRaw: String, + val id: UInt, + val type: PacketType, + val bodyRaw: String, ) { private val bodyTerminator: Byte = NULL_CHAR_BYTE @@ -46,7 +45,7 @@ data class Packet( val packetTerminatorSize = 1 * Byte.SIZE_BYTES val total = idSize + typeSize + bodySize + bodyTerminatorSize + packetTerminatorSize println( - "packetSize: $total = $idSize + $typeSize + $bodySize + $bodyTerminatorSize + $packetTerminatorSize" + "packetSize: $total = $idSize + $typeSize + $bodySize + $bodyTerminatorSize + $packetTerminatorSize" ) total @@ -81,20 +80,20 @@ data class Packet( fun toByteBuffer2(): ByteBuffer { return ByteBuffer - .allocate(totalSize) - .order(ByteOrder.LITTLE_ENDIAN) - // size - .putInt(size) - // ID - .putInt(id.toInt()) - // type - .putInt(type.value) - // body - .put(body) - // body terminator - .put(bodyTerminator) - // packet terminator - .put(RCON_PACKET_TERMINATOR) + .allocate(totalSize) + .order(ByteOrder.LITTLE_ENDIAN) + // size + .putInt(size) + // ID + .putInt(id.toInt()) + // type + .putInt(type.value) + // body + .put(body) + // body terminator + .put(bodyTerminator) + // packet terminator + .put(RCON_PACKET_TERMINATOR) // .asReadOnlyBuffer() From 023fb8b3debf3821d843e53d0c9ecfe30f6e4826 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 09:44:20 +0200 Subject: [PATCH 303/629] mod command: print enqueued chunk count --- .../src/main/typescript/main/commands/kafkatorioCommands.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts index 1443028..7e15a54 100644 --- a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts +++ b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts @@ -42,6 +42,7 @@ commands.add_command( const chunkYMax = chunkPosition.y + radius // let i = 100 + let chunkCount = 0 for (const [, surface] of game.surfaces) { for (const chunk of surface.get_chunks()) { if ( @@ -63,12 +64,13 @@ commands.add_command( data, 50 ) - + chunkCount++ // handleChunkGeneratedEvent(data, i) // i = i + 10 } } } + player.print(`enqueued ${chunkCount} chunks`) } } else if (paramUppercase.startsWith("INIT_GLOBAL")) { initGlobal(paramUppercase.startsWith("INIT_GLOBAL FORCE")) From e5bfc296973671de215a1f01086158bd35479312 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 09:46:53 +0200 Subject: [PATCH 304/629] simplify DebounceProcessor - use for-loop and schedule instead of coroutines --- .../processor/misc/DebounceProcessor.kt | 342 +++++------------- 1 file changed, 87 insertions(+), 255 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt index d4bf09b..2658751 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt @@ -1,18 +1,17 @@ package dev.adamko.kafkatorio.processor.misc +import dev.adamko.kotka.extensions.component1 +import dev.adamko.kotka.extensions.component2 +import dev.adamko.kotka.extensions.component3 +import dev.adamko.kotka.extensions.processor.component1 +import dev.adamko.kotka.extensions.processor.component2 +import dev.adamko.kotka.extensions.processor.component3 import dev.adamko.kotka.extensions.state.useAll -import kotlin.coroutines.CoroutineContext -import kotlin.time.Duration -import kotlinx.coroutines.CoroutineName -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.cancel -import kotlinx.coroutines.delay -import kotlinx.coroutines.isActive -import kotlinx.coroutines.launch +import kotlin.time.toJavaDuration import org.apache.kafka.common.serialization.Serde +import org.apache.kafka.streams.Topology +import org.apache.kafka.streams.processor.Cancellable +import org.apache.kafka.streams.processor.PunctuationType import org.apache.kafka.streams.processor.api.Processor import org.apache.kafka.streams.processor.api.ProcessorContext import org.apache.kafka.streams.processor.api.ProcessorSupplier @@ -21,105 +20,116 @@ import org.apache.kafka.streams.state.StoreBuilder import org.apache.kafka.streams.state.Stores import org.apache.kafka.streams.state.TimestampedKeyValueStore import org.apache.kafka.streams.state.ValueAndTimestamp +import java.time.Duration as DurationJvm +import kotlin.time.Duration as DurationKt class DebounceProcessor( - private val inactivityDuration: Duration, - private val recordsTimestampedStoreName: String, + private val inactivityDuration: DurationKt, + checkInterval: DurationKt, + private val storeName: String, ) : Processor { - private var state: State = Uninitialised() + private val checkInterval: DurationJvm = checkInterval.toJavaDuration() - override fun init(kafkaContext: ProcessorContext) { - state = Active(kafkaContext) + private lateinit var state: State + + override fun init(context: ProcessorContext) { + state = Active(context) } override fun process(record: Record) { - when (val state = state) { - is Active -> state.addRecord(record) - else -> error("state is not Active (actual: $state)") + (state as Active).apply { + val (key, value, _) = record + + val existing: ValueAndTimestamp? = store.get(key) + val newTimestamp = existing?.timestamp() ?: System.currentTimeMillis() + + store.put(key, ValueAndTimestamp.make(value, newTimestamp)) } } override fun close() { - (state as? Active)?.close() + (state as? Active)?.schedule?.cancel() + state = Closed() } private sealed interface State - private class Uninitialised : State - private class Closed : State private inner class Active( - val kafkaContext: ProcessorContext, - ) : State, CoroutineScope { - override val coroutineContext: CoroutineContext = - SupervisorJob() + - Dispatchers.Unconfined + - CoroutineName("DebounceProcessor") + val context: ProcessorContext + ) : State { + val store: TimestampedKeyValueStore = context.getStateStore(storeName) + val schedule: Cancellable = + context.schedule(checkInterval, PunctuationType.WALL_CLOCK_TIME, ::checkRecords) - val recordsTimestampedStore: TimestampedKeyValueStore = - kafkaContext.getStateStore(recordsTimestampedStoreName) - - private val recordJobs = mutableMapOf() - - init { - recordsTimestampedStore.useAll { - forEach { r -> - val record = Record(r.key, r.value.value(), r.value.timestamp()) - addRecord(record) + private fun checkRecords(now: Long) { + store.useAll { + forEach { record -> + val (key, value, timestamp) = record + if ((now - timestamp) > inactivityDuration.inWholeMilliseconds) { + context.forward(Record(key, value, timestamp)) + store.delete(key) + } } } } - - fun addRecord(record: Record) { - recordJobs.compute(record.key()) { _, existing -> - if (existing != null && existing.timestamp < record.timestamp()) { - existing.job.cancel("replaced by newer record ${existing.timestamp} < ${record.timestamp()}") - createTimestampedJob(record) - } else { - null - } - } - } - - private fun createTimestampedJob(record: Record): TimestampedJob { - val job = launch { - recordsTimestampedStore.put( - record.key(), - ValueAndTimestamp.make(record.value(), record.timestamp()) - ) - delay(inactivityDuration) - if (isActive) { - kafkaContext.forward(record) - recordsTimestampedStore.delete(record.key()) - } - } - return TimestampedJob(job, record.timestamp()) - } - - fun close(): Closed { - coroutineContext.cancel() - return Closed() - } } - private data class TimestampedJob( - val job: Job, - val timestamp: Long, - ) - - companion object { + + fun Topology.addDebounceProcessor( + namePrefix: String, + sourceTopic: String, + sinkTopic: String, + + inactivityDuration: DurationKt, + checkInterval: DurationKt = inactivityDuration / 10, + keySerde: Serde, + valueSerde: Serde, + storeName: String = "$namePrefix.debounce-store", + ): Topology { + + val sourceName = "$namePrefix.debounce-source" + val processorName = "$namePrefix.debounce-processor" + val sinkName = "$namePrefix.debounce-sink" + + return addSource( + sourceName, + keySerde.deserializer(), + valueSerde.deserializer(), + sourceTopic, + ).addProcessor( + processorName, + Supplier( + inactivityDuration = inactivityDuration, + checkInterval = checkInterval, + storeName = storeName, + keySerde = keySerde, + valueSerde = valueSerde, + ), + sourceName, + ).addSink( + sinkName, + sinkTopic, + keySerde.serializer(), + valueSerde.serializer(), + processorName, + ) + } + class Supplier( - private val inactivityDuration: Duration, + private val inactivityDuration: DurationKt, + private val checkInterval: DurationKt, private val storeName: String, private val keySerde: Serde, private val valueSerde: Serde, ) : ProcessorSupplier { - override fun get(): Processor = DebounceProcessor(inactivityDuration, storeName) + override fun get(): Processor = + DebounceProcessor(inactivityDuration, checkInterval, storeName) override fun stores(): Set> = setOf( Stores.timestampedKeyValueStoreBuilder( @@ -131,181 +141,3 @@ class DebounceProcessor( } } } - - -//class DebounceProcessor( -// private val inactivityDuration: Duration, -// private val recordsTimestampedStoreName: String, -// coroutineDispatcher: CoroutineDispatcher = Dispatchers.Default -//) : -// Processor, -// CoroutineScope { -// -// override var coroutineContext: CoroutineContext = -// SupervisorJob() + -// coroutineDispatcher + -// CoroutineName("DebounceProcessor") -// -// private lateinit var kafkaContext: ProcessorContext -// private lateinit var recordsTimestampedStore: TimestampedKeyValueStore -// -// private val recordsFlow: MutableSharedFlow> = -// MutableSharedFlow( -// replay = 0, -// extraBufferCapacity = Int.MAX_VALUE, -// onBufferOverflow = BufferOverflow.DROP_OLDEST, -// ) -// -// override fun init(context: ProcessorContext) { -// this.kafkaContext = context -// -// this.coroutineContext += CoroutineName("DebounceProcessor-${context.applicationId()}-${context.taskId()}") -// -// recordsTimestampedStore = kafkaContext.getStateStore(recordsTimestampedStoreName) -// -// // start collecting records - create a debounce-timer for each record -// recordsFlow -// .runningFold(mapOf()) { acc, (k, createTask) -> -// require(coroutineContext.isActive) -// -// // cancel any previously existing debounce task -// acc[k]?.cancel() -// -// // add a new debounce task -// when (createTask) { -// true -> acc.plus(k to createDebounceTask(k)) -// false -> acc.minus(k) -// } -// -// }.launchIn(this) -// -// // re-initialise the flow from previously-stored records -// launch { -// recordsFlow.emitAll( -// recordsTimestampedStore -// .allAsSequence() -// .map { keyValue -> -// require(coroutineContext.isActive) -// DebounceTaskInitializer(keyValue) -// } -// .asFlow() -// ) -// } -// } -// -// private fun createDebounceTask(key: K): Job { -// return launch { -// delay(inactivityDuration) -// val (value, timestamp) = recordsTimestampedStore.get(key) -// if (coroutineContext.isActive) { -// kafkaContext.forward(Record(key, value, timestamp)) -// } -// } -// } -// -// override fun process(record: Record) { -// launch { -// recordsTimestampedStore.put( -// record.key(), -// ValueAndTimestamp.make(record.value(), record.timestamp()) -// ) -// recordsFlow.emit(DebounceTaskInitializer(record)) -// } -// } -// -// override fun close() { -// coroutineContext.cancelChildren(CancellationException("processor go sleepy bye bye")) -// } -// -//} -// -//internal data class DebounceTaskInitializer( -// val key: K, -// val createTask: Boolean, -//) { -// constructor(keyValue: KeyValue) : this(keyValue.key, keyValue.value != null) -// constructor(record: Record) : this(record.key(), record.value() != null) -//} -// -// -//fun debounceProcessor( -// inactivityDuration: Duration, -// storeName: String, -// keySerde: Serde, -// valueSerde: Serde, -//): ProcessorSupplier = -// object : ProcessorSupplier { -// -// override fun get(): Processor = DebounceProcessor(inactivityDuration, storeName) -// -// override fun stores(): Set> = setOf( -// Stores.timestampedKeyValueStoreBuilder( -// Stores.persistentTimestampedKeyValueStore(storeName), -// keySerde, -// valueSerde, -// ) -// ) -// -// } - - -//class SuppressProcessor( -// private val storeName: String, -// private val tickDuration: Duration = 1.seconds, -// private val debounceDuration: Duration, -//) : Processor { -// -// private lateinit var context: ProcessorContext -// -// private lateinit var stateStore: TimestampedKeyValueStore -// -// override fun init(context: ProcessorContext) { -// -// this.context = context -// -// stateStore = context.getStateStore(storeName) as TimestampedKeyValueStore -// -// context.schedule( -// tickDuration.toJavaDuration(), -// PunctuationType.WALL_CLOCK_TIME, -// ::punctuate, -// ) -// } -// -// override fun process(record: Record) { -// -// val (key, newVal) = record -// -// val storedVal: V? = stateStore[key]?.value() -// -// val cachedVal = ValueAndTimestamp.make( -// storedVal ?: newVal, -// System.currentTimeMillis() -// ) -// -// stateStore.put(key, cachedVal) -// -//// val newTimestamp = if (storedVal == null) System.currentTimeMillis() else storedTimestamp -//// stateStore.put(key, ValueAndTimestamp.make(storedVal, newTimestamp)) -// } -// -// private fun punctuate(currentTimestamp: Long) { -// -// stateStore.all().use { iterator -> -// iterator.forEach { record: KeyValue> -> -// -// val (k, v, storedTimestamp) = record -// -// if (currentTimestamp - storedTimestamp > debounceDuration.inWholeMilliseconds) { -// -// context.forward(Record(k, v, storedTimestamp)) -// -// stateStore.delete(k) -// } -// -// } -// } -// } -// -//} -// From ab9e9d4d668416eaba704f9e3cda3a83968b3ad9 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 11:20:54 +0200 Subject: [PATCH 305/629] mod: fix settings names and descriptions --- .../src/main/resources/mod-data/locale/en/locale.cfg | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg b/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg index c8622fd..1415aa5 100644 --- a/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg +++ b/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg @@ -1,15 +1,15 @@ [mod-setting-name] -kafkatorio_event-cache_default-expiration-duration-seconds_PLAYER=Player update rate (seconds) -kafkatorio_event-cache_default-expiration-duration-seconds_MAP_CHUNK=Map update rate (seconds) -kafkatorio_event-cache_default-expiration-duration-seconds_ENTITY=Entity update rate (seconds) +kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-PlayerUpdate=Player update rate (seconds) +kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-MapChunkUpdate=Map update rate (seconds) +kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-EntityUpdate=Entity update rate (seconds) [mod-setting-description] -kafkatorio_event-cache_default-expiration-duration-seconds_PLAYER=How frequently Player updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (0.25 seconds) is probably fine! -kafkatorio_event-cache_default-expiration-duration-seconds_MAP_CHUNK=How frequently Map updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine! -kafkatorio_event-cache_default-expiration-duration-seconds_ENTITY=How frequently Entity updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (5 seconds) is probably fine! +kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-PlayerUpdate=How frequently Player updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (0.25 seconds) is probably fine! +kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-MapChunkUpdate=How frequently Map updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine! +kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-EntityUpdate=How frequently Entity updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (5 seconds) is probably fine! [string-mod-setting] From 153747e39cc1edbcab59d7ea510d8f5a684324af Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 15:43:44 +0200 Subject: [PATCH 306/629] mod: fix checking for existing entries in EventDataCache --- .../typescript/main/cache/EventDataCache.ts | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts index d61e801..4dbaa09 100644 --- a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts +++ b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts @@ -62,7 +62,7 @@ export namespace EventUpdates { resetLastUpdated: boolean, expirationDurationTicks?: uint, ) { - const entry: CacheEntry = this.getCacheEntry(key) ?? + const entry: CacheEntry = this.getCacheEntry(key, type) ?? Manager.createCacheEntry(key, type) mutate(entry.packet) if (resetLastUpdated) { @@ -80,9 +80,10 @@ export namespace EventUpdates { */ public setExpiration( key: PacketKey, + type: PacketType, expirationDurationTicks: uint, ) { - const entry = this.getCacheEntry(key) + const entry = this.getCacheEntry(key, type) if (entry != undefined) { entry.expirationDurationTicks = expirationDurationTicks } @@ -102,22 +103,27 @@ export namespace EventUpdates { global.cache.delete(key) } } - if (countExpired + countTotal > 0) { - log(`cache expired items count: ${countExpired}, total: ${countTotal}`) + + const hasExpiredItems = countExpired > 0 + const hasAnyItem = countTotal > 0 + + if (hasExpiredItems || (game.tick % 30 == 0 && hasAnyItem)) { + log(`[extractExpired] expired items: ${countExpired}, total: ${countTotal}`) } return expiredData } private getCacheEntry( - key: PacketKey + key: EventUpdates.PacketKey, + type: EventUpdates.PacketType, ): CacheEntry | undefined { const hash = Manager.hashKey(key) if (!global.cache.has(hash)) { return undefined } const value: CacheEntry = global.cache.get(hash) - if (this.isEntryInstanceOf(value, key)) { + if (this.isEntryInstanceOf(value, type)) { return value } else { // Type mismatch. This shouldn't happen... @@ -134,7 +140,7 @@ export namespace EventUpdates { type: type, key: key, } - let entry: CacheEntry = new CacheEntry(data) + const entry: CacheEntry = new CacheEntry(data) const hash = Manager.hashKey(key) global.cache.set(hash, entry) return entry @@ -156,17 +162,17 @@ export namespace EventUpdates { isEntryInstanceOf( entry: CacheEntry | undefined, - key: PacketKey, + type: EventUpdates.PacketType, ): entry is CacheEntry { - return this.isDataInstanceOf(entry?.packet, key) + return this.isDataInstanceOf(entry?.packet, type) } isDataInstanceOf( packet: PACKET | undefined, - key: PacketKey, + type: EventUpdates.PacketType, ): packet is PACKET { - return packet != undefined && packet.key == key + return packet != undefined && packet.type == type } private static hashKey( From fb265e39a655fdce4fde519249bf7a556a6033e8 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 15:45:23 +0200 Subject: [PATCH 307/629] event-server: try sharing a job, so server shuts down at the same time --- .../adamko/kafkatorio/processor/KafkatorioTopology.kt | 11 +++++++++-- .../kafkatorio/processor/topology/flowMapTiles.kt | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index acb614b..d69b557 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -15,6 +15,7 @@ import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.job import kotlinx.coroutines.launch import org.apache.kafka.streams.KafkaStreams @@ -30,7 +31,7 @@ internal class KafkatorioTopology( ) : CoroutineScope { override val coroutineContext: CoroutineContext = - Dispatchers.Default + SupervisorJob() + CoroutineName("KafkatorioTopology") + Dispatchers.Default + SupervisorJob(rootJob) + CoroutineName("KafkatorioTopology") fun start() { splitPackets() @@ -76,7 +77,7 @@ internal class KafkatorioTopology( private fun launchTopology( id: String, topology: Topology, - config: Map = mapOf() + config: Map = mapOf(), ) { val props: Properties = appProps.kafkaConfig @@ -112,10 +113,16 @@ internal class KafkatorioTopology( coroutineContext.job.invokeOnCompletion { println("closing $id KafkaStreams") + rootJob.cancelChildren() + rootJob.cancel() streams.close(Duration.ofSeconds(1)) } launch { streams.start() } } + companion object { + val rootJob = SupervisorJob() + } + } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt index ede9b1e..cd4b72e 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt @@ -108,7 +108,7 @@ fun ColourHex.toRgbColor(): RGBColor { private class ServerMapChunkHandler : CoroutineScope { override val coroutineContext: CoroutineContext = - Dispatchers.Default + SupervisorJob() + CoroutineName("ServerMapChunkHandler") + Dispatchers.Default + SupervisorJob(rootJob) + CoroutineName("ServerMapChunkHandler") /** The inbox for this handler. */ From 92e385fbe71fef48206eb189f32c591f08a9f1c3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 15:46:20 +0200 Subject: [PATCH 308/629] gradle config: try fixing config-cache miss with projectTokens --- build.gradle.kts | 17 +++++------ modules/events-mod/build.gradle.kts | 35 ++++++++++++----------- modules/infra-kafka-pipe/build.gradle.kts | 6 ++-- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index f39581b..efda1c4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,5 @@ import dev.adamko.kafkatorio.gradle.excludeGeneratedGradleDsl +import java.time.LocalDate plugins { idea @@ -12,14 +13,14 @@ version = "0.4.0" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) -val projectTokens: MutableMap by extra( - mutableMapOf( - "project.version" to "$version", - "rootProject.name" to rootProject.name, - "date.year" to "${java.time.LocalDate.now().year}", - "author.email" to "adam@adamko.dev", - ) -) +val projectTokens: MapProperty by extra { + objects.mapProperty().apply { + put("project.version", provider { "$version" }) + put("rootProject.name", provider { rootProject.name }) + put("date.year", provider { "${LocalDate.now().year}" }) + put("author.email", "adam@adamko.dev") + } +} idea { module { diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 3c7eee1..5251770 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -18,24 +18,21 @@ description = // Factorio required format is: // - filename: `mod-name_version.zip` // - zip contains one directory, `mod-name` -val modName: String by extra("${rootProject.name}-events") -val distributionZipName: String by extra("${modName}_${project.version}.zip") +val modName: String by extra { "${rootProject.name}-events" } +val distributionZipName: String by extra { "${modName}_${project.version}.zip" } // version of Factorio that the mod is compatible with (must only be "major.minor" - patch causes error) -val modFactorioCompatibility: String by extra( - libs.versions.factorio - .map { SemVer.parse(it).run { "$major.$minor" } } - .get() -) +val modFactorioCompatibility: Provider = + libs.versions.factorio.map { SemVer.parse(it).run { "$major.$minor" } } val licenseFile: RegularFile by rootProject.extra -val projectTokens: MutableMap by rootProject.extra -projectTokens += mapOf( - "mod.name" to modName, - "mod.title" to "Kafkatorio Events", - "mod.description" to (project.description ?: ""), - "factorio.version" to modFactorioCompatibility, -) +val projectTokens: MapProperty by rootProject.extra +projectTokens.apply { + put("mod.name", modName) + put("mod.title", "Kafkatorio Events") + put("mod.description", provider { project.description }.orElse("")) + put("factorio.version", modFactorioCompatibility) +} val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") @@ -95,8 +92,14 @@ val installEventsTsSchema by tasks.registering(Sync::class) { tasks.distZip { - archiveFileName.set(provider { distributionZipName }) + val zipName = distributionZipName + val zipNameProvider = provider { zipName } + val projectTokens = projectTokens + inputs.property("distributionZipName", distributionZipName) + inputs.property("zipNameProvider", zipNameProvider) + inputs.property("projectTokens", projectTokens) + archiveFileName.set(zipNameProvider) } @@ -112,7 +115,7 @@ distributions { from(licenseFile) from(typescriptToLua.map { it.outputDirectory }) filesNotMatching("**/*.png") { - filter("tokens" to projectTokens) + filter("tokens" to projectTokens.get()) } includeEmptyDirs = false exclude { diff --git a/modules/infra-kafka-pipe/build.gradle.kts b/modules/infra-kafka-pipe/build.gradle.kts index 77b8da2..ab7f0a3 100644 --- a/modules/infra-kafka-pipe/build.gradle.kts +++ b/modules/infra-kafka-pipe/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs +import dev.adamko.kafkatorio.task.DockerComposeExec plugins { dev.adamko.kafkatorio.infra.`docker-compose` @@ -14,9 +14,7 @@ tasks.dockerUp { } - -@Suppress("UnstableApiUsage") // normalizeLineEndings is incubating -val dockerBuildKafkaPipe by tasks.registering(dev.adamko.kafkatorio.task.DockerComposeExec::class) { +val dockerBuildKafkaPipe by tasks.registering(DockerComposeExec::class) { dependsOn(tasks.dockerEnv) dockerComposeDir.set(dockerSrcDir) From 609f68408e3ae61b2bd9114c415871e3c9c622b0 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 15:46:35 +0200 Subject: [PATCH 309/629] update yarn.lock --- gradle/kotlin-js-store/yarn.lock | 125 ++++++++++++++++++++++++++----- 1 file changed, 107 insertions(+), 18 deletions(-) diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index 95c25bf..932e3e3 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -539,7 +539,7 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -async@2.6.4, async@^2.6.2: +async@^2.6.2, async@^2.6.4: version "2.6.4" resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== @@ -718,6 +718,21 @@ chart.js@^3.7.1: resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.7.1.tgz#0516f690c6a8680c6c707e31a4c1807a6f400ada" integrity sha512-8knRegQLFnPQAheZV8MjxIXc5gQEfDFD897BJgv/klO/vtIyFFmgMXrNfgrXpbTr/XbTturxRgxIXx/Y+ASJBA== +chokidar@3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + chokidar@3.5.3, chokidar@^3.5.1, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" @@ -940,6 +955,13 @@ debug@2.6.9: dependencies: ms "2.0.0" +debug@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + debug@4.3.3: version "4.3.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" @@ -1385,11 +1407,16 @@ flatted@^3.2.5: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== -follow-redirects@1.14.8, follow-redirects@^1.0.0: +follow-redirects@^1.0.0: version "1.14.8" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc" integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA== +follow-redirects@^1.14.8: + version "1.14.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" + integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== + format-util@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" @@ -1543,6 +1570,18 @@ glob-to-regexp@^0.4.1: once "^1.3.0" path-is-absolute "^1.0.0" +glob@7.1.7: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + globby@^11.0.1: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" @@ -2165,10 +2204,10 @@ minimalistic-assert@^1.0.0: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" - integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== +minimatch@3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" @@ -2179,7 +2218,7 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@1.2.6, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== @@ -2191,10 +2230,40 @@ mkdirp@^0.5.5: dependencies: minimist "^1.2.6" -mocha@9.1.2, mocha@9.2.1, mocha@9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" - integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== +mocha@9.1.2: + version "9.1.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.2.tgz#93f53175b0f0dc4014bd2d612218fccfcf3534d3" + integrity sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.2" + debug "4.3.2" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.1.7" + growl "1.10.5" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "3.0.4" + ms "2.1.3" + nanoid "3.1.25" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + workerpool "6.1.5" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +mocha@9.2.1: + version "9.2.1" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.1.tgz#a1abb675aa9a8490798503af57e8782a78f1338e" + integrity sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ== dependencies: "@ungap/promise-all-settled" "1.1.2" ansi-colors "4.1.1" @@ -2209,9 +2278,9 @@ mocha@9.1.2, mocha@9.2.1, mocha@9.2.2: he "1.2.0" js-yaml "4.1.0" log-symbols "4.1.0" - minimatch "4.2.1" + minimatch "3.0.4" ms "2.1.3" - nanoid "3.3.1" + nanoid "3.2.0" serialize-javascript "6.0.0" strip-json-comments "3.1.1" supports-color "8.1.1" @@ -2249,10 +2318,20 @@ multicast-dns@^6.0.1: dns-packet "^1.3.1" thunky "^1.0.2" -nanoid@3.1.31, nanoid@3.3.1, nanoid@^3.3.1: - version "3.1.31" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.31.tgz#f5b58a1ce1b7604da5f0605757840598d8974dc6" - integrity sha512-ZivnJm0o9bb13p2Ot5CpgC2rQdzB9Uxm/mFZweqm5eMViqOJe3PV6LU2E30SiLgheesmcPrjquqraoolONSA0A== +nanoid@3.1.25: + version "3.1.25" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" + integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== + +nanoid@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" + integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== + +nanoid@^3.1.31, nanoid@^3.3.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== negotiator@0.6.3: version "0.6.3" @@ -2264,11 +2343,16 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -node-forge@1.3.0, node-forge@^1: +node-forge@^1: version "1.3.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.0.tgz#37a874ea723855f37db091e6c186e5b67a01d4b2" integrity sha512-08ARB91bUi6zNKzVmaj3QO7cr397uiDT2nJ63cHjyNtCTWIgvS47j3eT0WfzUwS9+6Z5YshRaoasFkXCKrIYbA== +node-forge@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + node-releases@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" @@ -3377,6 +3461,11 @@ wildcard@^2.0.0: resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== +workerpool@6.1.5: + version "6.1.5" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" + integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== + workerpool@6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" From 403ca0dd2eaaf1ace6b5d5fa21c0795c5309e71f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 15:47:28 +0200 Subject: [PATCH 310/629] mod: clean up onMapChunkEventListeners.ts --- .../main/events/onMapChunkEventListeners.ts | 56 +++++-------------- 1 file changed, 13 insertions(+), 43 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts index 75c9f7c..3d2269d 100644 --- a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts @@ -36,57 +36,26 @@ function mapTilesUpdateDebounce( data => { // tile dictionary update - data.tileDictionary ??= { - tilesXY: {}, - protos: {}, + if (data.tileDictionary == undefined) { + data.tileDictionary = { + tilesXY: {}, + protos: {}, + } } - - // let maxX = 0 - // let minX = 0 - // let maxY = 0 - // let minY = 0 - // for (const tile of tiles) { - // //@formatter:off - // if (tile.position.x < minX) minX = tile.position.x - // if (tile.position.x > maxX) maxX = tile.position.x - // if (tile.position.y > minY) minY = tile.position.y - // if (tile.position.y > maxY) maxY = tile.position.y - // //@formatter:on - // } - // - // const noTileProto = 0 - // - // const grid: int[][] = [] - // for (let x = 0; x < maxX; x++) { - // grid[x] = [] - // for (let y = 0; y < maxY; y++) { - // grid[x][y] = noTileProto - // } - // } - // data.tileDictionary.protos["no-tile"] = noTileProto - // - // let protosCount2: uint = 0 - // for (const tile of tiles) { - // const x = tile.position.x - minX - // const y = tile.position.y - minY - // - // data.tileDictionary.protos[tile.name] ??= protosCount2++ - // grid[x][y] = data.tileDictionary.protos[tile.name] - // } - // - // const grid2: string[] = grid.map(row => table.concat(row)) - - let protosCount: uint = 0 for (const tile of tiles) { - data.tileDictionary.protos[tile.name] ??= protosCount++ + if (data.tileDictionary.protos[tile.name] == undefined) { + data.tileDictionary.protos[tile.name] = protosCount++ + } const protoKey = data.tileDictionary.protos[tile.name] const xString = `${tile.position.x}` const yString = `${tile.position.y}` - data.tileDictionary.tilesXY[xString] ??= {} + if (data.tileDictionary.tilesXY[xString] == undefined) { + data.tileDictionary.tilesXY[xString] = {} + } data.tileDictionary.tilesXY[xString][yString] = protoKey } @@ -222,15 +191,16 @@ function convertOldPosition( function handleBuiltTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) { + const eventName = Converters.eventNameString(event.name) const surface = getSurface(event.surface_index) if (surface == undefined) { + log(`[handleBuiltTileEvent] undefined surface ${eventName}`) return } const tiles: TileRead[] = convertOldPosition(event.tiles, event.tile) const groupedTiles = groupTiles(tiles) - const eventName = Converters.eventNameString(event.name) for (const [chunkPos, tiles] of groupedTiles) { mapTilesUpdateDebounce( From 99d5dec0887ceb109032751383ea22086c72e82a Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 15:47:54 +0200 Subject: [PATCH 311/629] gradle: make kafka-pipe start when launching kafkatorio --- build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle.kts b/build.gradle.kts index efda1c4..8e2e73d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -56,6 +56,7 @@ val runKafkatorio by tasks.registering { dependsOn( ":modules:infra-factorio-client:processRestart", ":modules:infra-factorio-server:processRestart", + ":modules:infra-kafka-pipe:dockerUp", ) } From ee3c7956cd5fd9285b41468da2d8fbb0e80f779f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 15:50:44 +0200 Subject: [PATCH 312/629] events-server: fix tile grouping, chunking, saving - debounce chunk and tile updates - make the tile output-dir configurable - basic test for manual checking --- .../kafkatorio/schema/common/positions.kt | 20 +- .../processor/KafkatorioTopology.kt | 2 +- .../processor/admin/kafkatorioTopics.kt | 7 + .../processor/topology/flowMapTiles.kt | 14 +- .../processor/topology/flowMapTiles2.kt | 167 ++++++++++----- .../processor/topology/groupMapChunks.kt | 32 ++- .../kafkatorio/processor/topology/model.kt | 13 +- .../processor/topology/SaveMapChunksTest.kt | 195 ++++++++++++++++++ 8 files changed, 370 insertions(+), 80 deletions(-) create mode 100644 modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt index f6a4463..16a0739 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt @@ -134,9 +134,27 @@ fun MapChunkPosition.leftTopTile(chunkSize: Int = MAP_CHUNK_SIZE): MapTilePositi y * chunkSize, ) + +fun MapChunkPosition.rightBottomTile(chunkSize: Int = MAP_CHUNK_SIZE): MapTilePosition = + leftTopTile(chunkSize) + (chunkSize - 1) + + +fun MapChunkPosition.iterateTiles(chunkSize: Int = MAP_CHUNK_SIZE): Iterator { + val leftTop = leftTopTile(chunkSize) + val rightBottom = rightBottomTile(chunkSize) + return iterator { + (leftTop.x..rightBottom.x).forEach { x -> + (leftTop.y..rightBottom.y).forEach { y -> + yield(MapTilePosition(x, y)) + } + } + } +} + + //val MapChunkPosition.rightBottomTile: MapTilePosition // get() = leftTopTile + (MAP_CHUNK_SIZE - 1) -// + // //val MapChunkPosition.boundingBox: MapBoundingBox // get() = MapBoundingBox(leftTopTile, rightBottomTile) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index d69b557..dbc940e 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -61,7 +61,7 @@ internal class KafkatorioTopology( private fun saveTiles() { val builder = StreamsBuilder() // val topology = saveMapTiles(builder) - val topology = saveMapTiles2(builder) + val topology = saveMapTiles2(builder, appProps.webmapTileDir) launchTopology("saveTiles", topology) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt index 18e483a..d4c808f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt @@ -17,11 +17,18 @@ private const val DOMAIN = "kafkatorio" const val TOPIC_SRC_SERVER_LOG = "$DOMAIN.src.server-log" const val TOPIC_GROUPED_MAP_CHUNKS_STATE = "$DOMAIN.state.map-chunks.grouped" +const val TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED = "$TOPIC_GROUPED_MAP_CHUNKS_STATE.debounced" + +const val TOPIC_SUBDIVIDED_MAP_TILES = "$DOMAIN.map-tiles.subdivided" +const val TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED = "$TOPIC_SUBDIVIDED_MAP_TILES.debounced" fun allTopics(): Set = buildSet { add(TOPIC_SRC_SERVER_LOG) add(TOPIC_GROUPED_MAP_CHUNKS_STATE) + add(TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED) + add(TOPIC_SUBDIVIDED_MAP_TILES) + add(TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED) addAll(packetTopicNames.values) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt index cd4b72e..e771b0b 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt @@ -4,6 +4,7 @@ import com.sksamuel.scrimage.ImmutableImage import com.sksamuel.scrimage.ScaleMethod import com.sksamuel.scrimage.color.RGBColor import com.sksamuel.scrimage.nio.PngWriter +import dev.adamko.kafkatorio.processor.KafkatorioTopology.Companion.rootJob import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kafkatorio.schema.common.ColourHex @@ -82,8 +83,7 @@ value class TilePngFilename( val value: String, ) { constructor(id: ServerMapChunkId) : this(buildString { - append("src/main/resources/kafkatorio-web-map") - append("/s${id.surfaceIndex}") + append("s${id.surfaceIndex}") append("/z${id.chunkSize.zoomLevel}") append("/x${id.chunkPosition.x}") append("/y${id.chunkPosition.y}") @@ -198,7 +198,7 @@ private class ServerMapChunkHandler : CoroutineScope { .tiles .entries .groupBy( - { (tile, _) -> tile.toMapChunkPosition(chunkSize.tilesPerChunk) } + { (tile, _) -> tile.toMapChunkPosition(chunkSize.lengthInTiles) } ) { (tilePosition, colour) -> tilePosition to colour } @@ -245,14 +245,14 @@ private class ServerMapChunkHandler : CoroutineScope { ): ImmutableImage { val chunkImage = ImmutableImage.filled( - chunkSize.tilesPerChunk, - chunkSize.tilesPerChunk, + chunkSize.lengthInTiles, + chunkSize.lengthInTiles, TRANSPARENT_AWT, BufferedImage.TYPE_INT_ARGB ) - val chunkOriginX: Int = chunkPosition.x * chunkSize.tilesPerChunk - val chunkOriginY: Int = chunkPosition.y * chunkSize.tilesPerChunk + val chunkOriginX: Int = chunkPosition.x * chunkSize.lengthInTiles + val chunkOriginY: Int = chunkPosition.y * chunkSize.lengthInTiles chunkColours.forEach { (tilePosition, colour) -> diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles2.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles2.kt index 5cdd67e..e1aa3f0 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles2.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles2.kt @@ -3,18 +3,25 @@ package dev.adamko.kafkatorio.processor.topology import com.sksamuel.scrimage.ImmutableImage import com.sksamuel.scrimage.ScaleMethod import com.sksamuel.scrimage.nio.PngWriter -import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE +import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED +import dev.adamko.kafkatorio.processor.admin.TOPIC_SUBDIVIDED_MAP_TILES +import dev.adamko.kafkatorio.processor.admin.TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED +import dev.adamko.kafkatorio.processor.misc.DebounceProcessor.Companion.addDebounceProcessor import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.MapTilePosition import dev.adamko.kafkatorio.schema.common.toMapChunkPosition import dev.adamko.kotka.extensions.consumedAs +import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.streams.flatMap import dev.adamko.kotka.extensions.streams.forEach import dev.adamko.kotka.kxs.serde import java.awt.image.BufferedImage -import java.io.File +import java.nio.file.Path import kotlin.io.path.fileSize import kotlin.math.abs +import kotlin.time.Duration.Companion.seconds +import kotlin.time.measureTimedValue import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.Topology import org.apache.kafka.streams.kstream.KStream @@ -22,78 +29,130 @@ import org.apache.kafka.streams.kstream.KStream private const val WEB_MAP_TILE_SIZE_PX = 256 - +/** + * @param[tileDirectory] [dev.adamko.kafkatorio.processor.config.ApplicationProperties.webmapTileDir] + */ fun saveMapTiles2( builder: StreamsBuilder, + tileDirectory: Path, ): Topology { val pid = "saveMapTiles" val groupedMapChunkTiles: KStream> = builder.stream( - TOPIC_GROUPED_MAP_CHUNKS_STATE, - consumedAs("$pid.consume.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()) + TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED, + consumedAs("$pid.consume.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()), ) groupedMapChunkTiles.flatMap("$pid.subdivide-chunks") { initialKey, initialChunk -> - ChunkSize.entries.flatMap { chunkSize -> - initialChunk.map.entries - .groupBy( - { (tile, _) -> tile.toMapChunkPosition(chunkSize.tilesPerChunk) } - ) { (tilePosition, colour) -> - tilePosition to colour - } - .map { (chunkPos, tiles) -> - val key = initialKey.copy( - chunkSize = chunkSize, - chunkPosition = chunkPos - ) - val value = ServerMapChunkTiles(key, tiles.toMap()) + val (chunks, time) = measureTimedValue { + ChunkSize.entries.flatMap { chunkSize -> + initialChunk.map + .entries + .groupingBy { (tilePosition, _) -> + val chunkPosition = tilePosition.toMapChunkPosition(chunkSize.lengthInTiles) +// println("$tilePosition groupingBy $chunkPosition") + initialKey.copy( + chunkSize = chunkSize, + chunkPosition = chunkPosition, + ) + }.fold( + initialValueSelector = { _, _ -> mutableMapOf() } + ) { _, accumulator, (tilePosition, colour) -> +// println("fold $tilePosition $colour") + accumulator[tilePosition] = colour + accumulator + } + .map { (chunkId, tiles) -> +// println("map $chunkId ${tiles.size}") + chunkId to ServerMapChunkTiles(chunkId, tiles) + } + } - key to value - } } - }.forEach("$pid.save-tiles") { key, value -> - val filename = TilePngFilename(key) - val chunkColours = value.map + println("subdivided ${initialKey.chunkPosition} to ${chunks.size} chunks in $time") - val chunkImage = ImmutableImage.filled( - key.chunkSize.tilesPerChunk, - key.chunkSize.tilesPerChunk, - TRANSPARENT_AWT, - BufferedImage.TYPE_INT_ARGB + chunks + }.to( + TOPIC_SUBDIVIDED_MAP_TILES, + producedAs( + "$pid.produce.grouped-map-chunks", + kxsBinary.serde(), + kxsBinary.serde(), + ) + ) + + val subdividedMapChunkTilesDebounced: KStream> = + builder.stream( + TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED, + consumedAs( + "$pid.consume.debounced-subdivided-chunks", + kxsBinary.serde(), + kxsBinary.serde(), + ), ) - val chunkOriginX: Int = key.chunkPosition.x * key.chunkSize.tilesPerChunk - val chunkOriginY: Int = key.chunkPosition.y * key.chunkSize.tilesPerChunk + subdividedMapChunkTilesDebounced + .forEach("$pid.save-tiles") { chunkId: ServerMapChunkId, tileColours: ServerMapChunkTiles -> - chunkColours.forEach { (tilePosition, colour) -> - val rgbColour = colour.toRgbColor() + val chunkImage = ImmutableImage.filled( + chunkId.chunkSize.lengthInTiles, + chunkId.chunkSize.lengthInTiles, + TRANSPARENT_AWT, + BufferedImage.TYPE_INT_ARGB + ) - val pixelX = abs(abs(tilePosition.x) - abs(chunkOriginX)) - val pixelY = abs(abs(tilePosition.y) - abs(chunkOriginY)) + val chunkOriginX: Int = chunkId.chunkPosition.x * chunkId.chunkSize.lengthInTiles + val chunkOriginY: Int = chunkId.chunkPosition.y * chunkId.chunkSize.lengthInTiles - chunkImage.setColor(pixelX, pixelY, rgbColour) + tileColours.map.forEach { (tilePosition, colour) -> + val rgbColour = colour.toRgbColor() + + val pixelX = abs(abs(tilePosition.x) - abs(chunkOriginX)) + val pixelY = abs(abs(tilePosition.y) - abs(chunkOriginY)) + + chunkImage.setColor(pixelX, pixelY, rgbColour) + } + + val scaledImage = + chunkImage.scaleTo(WEB_MAP_TILE_SIZE_PX, WEB_MAP_TILE_SIZE_PX, ScaleMethod.FastScale) + + val filename = TilePngFilename(chunkId) + saveTile(filename, tileDirectory, scaledImage) } - val img = chunkImage.scaleTo(WEB_MAP_TILE_SIZE_PX, WEB_MAP_TILE_SIZE_PX, ScaleMethod.FastScale) - - val chunkImageFile = File(filename.value) - if (chunkImageFile.parentFile.mkdirs()) { - println("created new map tile parentFile directory ${chunkImageFile.absolutePath}") - } - - val sizeBefore = chunkImageFile.takeIf { it.exists() }?.toPath()?.fileSize() - - val savedTile = img.output(PngWriter.NoCompression, chunkImageFile) - - val sizeAfter = savedTile.takeIf { it.exists() }?.toPath()?.fileSize() - if (sizeBefore != sizeAfter) { -// println("savedTile $sizeBefore/$sizeAfter: $savedTile") - } else { - println("savedTile NO-SIZE-CHANGE $sizeBefore/$sizeAfter: $savedTile") - } - } - return builder.build() + .addDebounceProcessor>( + namePrefix = pid, + sourceTopic = TOPIC_SUBDIVIDED_MAP_TILES, + sinkTopic = TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED, + inactivityDuration = 15.seconds, + keySerde = kxsBinary.serde(), + valueSerde = kxsBinary.serde(), + ) +} + +@Synchronized +fun saveTile( + filename: TilePngFilename, + tileDirectory: Path, + img: ImmutableImage, +) { + val chunkImageFile = tileDirectory.resolve(filename.value).toFile() + if (chunkImageFile.parentFile.mkdirs()) { + println("created new map tile parentFile directory ${chunkImageFile.absolutePath}") + } + val sizeBefore = chunkImageFile.takeIf { it.exists() }?.toPath()?.fileSize() + + val savedTile = img.output(PngWriter.NoCompression, chunkImageFile) + + val sizeAfter = savedTile.takeIf { it.exists() }?.toPath()?.fileSize() + + val sizeDescription = if (sizeBefore != sizeAfter && sizeBefore != null) { + "$sizeBefore/$sizeAfter" + } else { + "$sizeAfter" + } + println("savedTile $sizeDescription: $savedTile") } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt index aae4413..319c59f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt @@ -1,6 +1,8 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE +import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED +import dev.adamko.kafkatorio.processor.misc.DebounceProcessor.Companion.addDebounceProcessor import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.MapChunkPosition @@ -13,7 +15,7 @@ import dev.adamko.kafkatorio.schema.common.toMapChunkPosition import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import dev.adamko.kotka.extensions.groupedAs -import dev.adamko.kotka.extensions.materializedWith +import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.repartitionedAs import dev.adamko.kotka.extensions.streams.filter @@ -27,6 +29,7 @@ import dev.adamko.kotka.extensions.tables.toStream import dev.adamko.kotka.kxs.serde import kotlin.collections.component1 import kotlin.collections.component2 +import kotlin.time.Duration.Companion.seconds import kotlinx.serialization.Serializable import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.Topology @@ -82,12 +85,20 @@ fun groupMapChunks(builder: StreamsBuilder): Topology { TOPIC_GROUPED_MAP_CHUNKS_STATE, producedAs( "$pid.grouped-map-chunks", - kxsBinary.serde(), - kxsBinary.serde>() + kxsBinary.serde(), + kxsBinary.serde(), ) ) return builder.build() + .addDebounceProcessor>( + namePrefix = pid, + sourceTopic = TOPIC_GROUPED_MAP_CHUNKS_STATE, + sinkTopic = TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED, + inactivityDuration = 15.seconds, + keySerde = kxsBinary.serde(), + valueSerde = kxsBinary.serde(), + ) } @@ -122,7 +133,7 @@ private fun groupTilesIntoChunksWithColours( mapTiles .tiles .groupBy { tile -> - tile.position.toMapChunkPosition(standardChunkSize.tilesPerChunk) + tile.position.toMapChunkPosition(standardChunkSize.lengthInTiles) } .map { (chunkPos, tiles) -> @@ -165,9 +176,8 @@ private fun groupTilesIntoChunksWithColours( ) .reduce( "server-map-data.tiles.reduce", - materializedWith( -// materializedAs( -// "server-map-data.tiles.reduce.store", + materializedAs( + "server-map-data.tiles.reduce.store", kxsBinary.serde(), kxsBinary.serde>(), ) @@ -185,10 +195,10 @@ private fun groupTilesIntoChunksWithColours( .join( other = tileProtoColourDict, tableJoined = tableJoined("server-map-data.join-tiles-with-prototypes"), - materialized = materializedWith( -// "server-map-data.join-tiles-with-prototypes.store", - kxsBinary.serde(), - kxsBinary.serde>(), + materialized = materializedAs( + "server-map-data.join-tiles-with-prototypes.store", + kxsBinary.serde(), + kxsBinary.serde(), ), foreignKeyExtractor = { chunkTiles: ServerMapChunkTiles -> chunkTiles.chunkId.serverId diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt index 376e63d..1060f56 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt @@ -23,14 +23,15 @@ enum class ChunkSize( CHUNK_032(3), ; - val tilesPerChunk: Int = 2f.pow(8 - zoomLevel).roundToInt() + /** 32, 64, 128, 256, or 512 */ + val lengthInTiles: Int = 2f.pow(8 - zoomLevel).roundToInt() init { - require(tilesPerChunk > 0) { "tilesPerChunk $tilesPerChunk must be positive" } + require(lengthInTiles > 0) { "tilesPerChunk $lengthInTiles must be positive" } // 1000 & 0111 = 0000 => pow^2 // 1001 & 1000 = 1000 => !pow^2 - require(tilesPerChunk and (tilesPerChunk - 1) == 0) { - "tilesPerChunk $tilesPerChunk must be a power-of-two number" + require(lengthInTiles and (lengthInTiles - 1) == 0) { + "tilesPerChunk $lengthInTiles must be a power-of-two number" } } @@ -38,8 +39,8 @@ enum class ChunkSize( // cache values for better performance. KT-48872 val entries: Set = values().toSet() - val MAX: ChunkSize = entries.maxByOrNull { it.tilesPerChunk }!! - val MIN: ChunkSize = entries.minByOrNull { it.tilesPerChunk }!! + val MAX: ChunkSize = entries.maxByOrNull { it.lengthInTiles }!! + val MIN: ChunkSize = entries.minByOrNull { it.lengthInTiles }!! val STANDARD: ChunkSize = entries.first { it.zoomLevel == 0 } } diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt new file mode 100644 index 0000000..3f4eaf2 --- /dev/null +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt @@ -0,0 +1,195 @@ +package dev.adamko.kafkatorio.processor.topology + +import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.MapChunkPosition +import dev.adamko.kafkatorio.schema.common.MapTilePosition +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.common.iterateTiles +import dev.adamko.kafkatorio.schema.common.toMapChunkPosition +import dev.adamko.kotka.kxs.serde +import io.kotest.core.spec.style.FunSpec +import io.kotest.property.Arb +import io.kotest.property.PropTestConfig +import io.kotest.property.RandomSource +import io.kotest.property.arbitrary.arbitrary +import io.kotest.property.arbitrary.int +import io.kotest.property.arbitrary.uByte +import io.kotest.property.checkAll +import java.nio.file.Path +import java.time.LocalTime +import java.time.format.DateTimeFormatter +import kotlin.io.path.Path +import kotlin.io.path.absolutePathString +import kotlin.time.Duration +import kotlin.time.Duration.Companion.minutes +import kotlin.time.Duration.Companion.seconds +import kotlin.time.toJavaDuration +import kotlinx.coroutines.delay +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.TestInputTopic +import org.apache.kafka.streams.TopologyTestDriver + + +class SaveMapChunksTest : FunSpec({ + + test("save tile") { + + + Scenario().use { scenario -> + + val chunkTilesArb = serverMapChunkTilesArb(scenario.serverId) + + checkAll( + config = PropTestConfig(iterations = 1), + chunkTilesArb, + ) { chunkTiles -> + + scenario.groupedMapChunksInputTopic.pipeInput( + chunkTiles.chunkId, + chunkTiles, + ) + + scenario += 1.minutes + delay(5.seconds) + scenario += 1.minutes +// delay(5.seconds) + scenario += 1.minutes +// delay(5.seconds) + scenario += 1.minutes +// delay(5.seconds) + + println("file:///${scenario.outputDir.absolutePathString()}") + } + } + } + +}) { + + class Scenario( + streamsBuilder: StreamsBuilder = StreamsBuilder(), + + groupedMapChunksInputTopicName: String = "kafkatorio.state.map-chunks.grouped.debounced", + + val serverId: FactorioServerId = FactorioServerId("test-server-id"), + ) : AutoCloseable { + + val outputDir: Path = run { + val now = LocalTime.now().format(DateTimeFormatter.ISO_TIME).filter { it.isLetterOrDigit() } + Path("build/test/save-map-chunks-${now}") + } + private val topology = saveMapTiles2(streamsBuilder, outputDir) + val testDriver: TopologyTestDriver = TopologyTestDriver(topology) + + val groupedMapChunksInputTopic: TestInputTopic> = + testDriver.createInputTopic( + groupedMapChunksInputTopicName, + kxsBinary.serde().serializer(), + kxsBinary.serde>().serializer(), + ) + + operator fun plusAssign(wallClockTime: Duration) { + testDriver.advanceWallClockTime(wallClockTime.toJavaDuration()) + } + + override fun close() { + testDriver.close() + } + } + + companion object { + + fun mapTilePositionArb( + xArb: Arb = Arb.int(), + yArb: Arb = Arb.int(), + ): Arb = arbitrary { + MapTilePosition(xArb.bind(), yArb.bind()) + } + + fun mapChunkPositionArb( + xArb: Arb = Arb.int(-10..10), + yArb: Arb = Arb.int(-10..10), + ): Arb = arbitrary { + MapChunkPosition(xArb.bind(), yArb.bind()) + } + + fun colourHexArb( + redArb: Arb = Arb.uByte(), + greenArb: Arb = Arb.uByte(), + blueArb: Arb = Arb.uByte(), + alphaArb: Arb = Arb.uByte(), + ): Arb = arbitrary { + ColourHex( + redArb.bind(), + greenArb.bind(), + blueArb.bind(), +// alphaArb.bind(), + 255u, + ) +// ColourHex( +// 255u, +// 0u, +// 0u, +// 255u, +// ) + } + + fun serverMapChunkIdArb( + serverId: FactorioServerId, + chunkPosition: Arb = mapChunkPositionArb(), + surfaceIndex: SurfaceIndex = SurfaceIndex(1u), + chunkSize: ChunkSize = ChunkSize.MAX, + ): Arb = arbitrary { + ServerMapChunkId( + serverId = serverId, + chunkPosition = chunkPosition.bind(), + surfaceIndex = surfaceIndex, + chunkSize = chunkSize, + ) + } + + fun tilesInChunkArb( + chunkId: ServerMapChunkId + ): Arb> = arbitrary { + + val tileColours = mutableMapOf() + + println("chunk size: ${chunkId.chunkSize} ${chunkId.chunkSize.lengthInTiles}") + + val map = chunkId.chunkPosition + .iterateTiles(chunkId.chunkSize.lengthInTiles) + .asSequence() + .map { tilePos -> + val colour = + tileColours.getOrPut(tilePos.toMapChunkPosition(ChunkSize.MIN.lengthInTiles)) { + colourHexArb().sample(RandomSource.default()).value + } + tilePos to colour + } +// .take(2500) + .toMap() + + println(map.size) + + map + } + + fun serverMapChunkTilesArb( + serverId: FactorioServerId, + ): Arb> { + + val serverMapChunkId = serverMapChunkIdArb(serverId) + + return arbitrary { + val chunkId = serverMapChunkId.bind() + + val tileColoursArb = tilesInChunkArb(serverMapChunkId.bind()) + + ServerMapChunkTiles( + chunkId = chunkId, + map = tileColoursArb.bind() + ) + } + } + } +} From 332bc5ecb6c066e34525a0c92607abdd3efe20c6 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 23:02:45 +0200 Subject: [PATCH 313/629] kafka-pipe: don't use a random server ID --- modules/infra-kafka-pipe/src/docker-compose.yml | 5 ++++- modules/infra-kafka-pipe/src/kafka-pipe.sh | 14 +++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/modules/infra-kafka-pipe/src/docker-compose.yml b/modules/infra-kafka-pipe/src/docker-compose.yml index 31ef1fa..a2f781d 100644 --- a/modules/infra-kafka-pipe/src/docker-compose.yml +++ b/modules/infra-kafka-pipe/src/docker-compose.yml @@ -12,8 +12,11 @@ services: networks: - "kafkatorio-nw" environment: - FACTORIO_SERVER_CONTAINER_NAME: "factorio-server" KAFKATORIO_VERSION: $KAFKATORIO_VERSION + # message IDs + INSTANCE_ID: "test-server" + # name of the docker container + FACTORIO_SERVER_CONTAINER_NAME: "factorio-server" KAFKA_HOST: "kafka:29092" volumes: # Windows (requires privileged/root) diff --git a/modules/infra-kafka-pipe/src/kafka-pipe.sh b/modules/infra-kafka-pipe/src/kafka-pipe.sh index f6273ac..e6717fd 100644 --- a/modules/infra-kafka-pipe/src/kafka-pipe.sh +++ b/modules/infra-kafka-pipe/src/kafka-pipe.sh @@ -12,16 +12,24 @@ endProcess() { } # some random ID, to use as a message key -INSTANCE_ID=$(cat /proc/sys/kernel/random/uuid) +#INSTANCE_ID="${INSTANCE_ID}"$(cat /proc/sys/kernel/random/uuid) +KEY="${INSTANCE_ID:-none}" while :; do docker logs --tail 0 -f "$FACTORIO_SERVER_CONTAINER_NAME" | sed -n -e 's/^KafkatorioPacket: //p' | - kcat -P -T \ + kcat -P \ -b "$KAFKA_HOST" \ -t kafkatorio.src.server-log \ - -k "$INSTANCE_ID" \ + -k "$KEY" \ -H "KAFKA-PIPE-VERSION=$KAFKATORIO_VERSION" +# -T \ + +# -P producer mode +# -T echo to stdout +# -t the topic name +# -k the key of the message +# -H add a header echo "Error - retrying in 10 seconds" sleep 10 From 51cff57f63ea67657ef729936d2d0100c09162d6 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 23:40:41 +0200 Subject: [PATCH 314/629] try fixing gradle config cache warning --- modules/events-mod/build.gradle.kts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 5251770..acd0431 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -91,11 +91,9 @@ val installEventsTsSchema by tasks.registering(Sync::class) { } +val zipNameProvider = provider { distributionZipName } + tasks.distZip { - val zipName = distributionZipName - val zipNameProvider = provider { zipName } - val projectTokens = projectTokens - inputs.property("distributionZipName", distributionZipName) inputs.property("zipNameProvider", zipNameProvider) inputs.property("projectTokens", projectTokens) From 29daff5abcebd968bc6af82f54d316e65ac68c64 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 23:40:56 +0200 Subject: [PATCH 315/629] web map: dark mode --- .../web-map/src/main/resources/css/kafkatorio.css | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/web-map/src/main/resources/css/kafkatorio.css b/modules/web-map/src/main/resources/css/kafkatorio.css index b6b3d9b..af65ac8 100644 --- a/modules/web-map/src/main/resources/css/kafkatorio.css +++ b/modules/web-map/src/main/resources/css/kafkatorio.css @@ -3,3 +3,15 @@ width: 257px !important; height: 257px !important; } + +html { + background: #2B2B2BFF; +} + +body { + background: #2B2B2BFF; +} + +.leaflet-container { + background-color: rgba(255, 0, 0, 0.0); +} From 6c5613b2838220d7dc47ac1fc334280f24ceb2c6 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 1 May 2022 23:41:18 +0200 Subject: [PATCH 316/629] kt-rcon: mucking about --- modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/main.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/main.kt b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/main.kt index 5486877..0852797 100644 --- a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/main.kt +++ b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/main.kt @@ -7,12 +7,12 @@ import kotlinx.coroutines.runBlocking fun main(): Unit = runBlocking { KtRconClient3( "localhost", - 27715, - Password("coh9oongoojahX4") + 27015, + Password("chofeengook8Shu") ).use { client -> // client.send(PacketType.AUTH_REQUEST, "passwrd") - client.send(PacketType.AUTH_REQUEST, "coh9oongoojahX4") + client.send(PacketType.AUTH_REQUEST, "chofeengook8Shu") delay(10.seconds) client.send(PacketType.EXEC_COMMAND, "/help") From df197463eb5fd669428ab6d906d182dd85158de0 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 2 May 2022 23:34:59 +0200 Subject: [PATCH 317/629] remove unused SuppressProcessor.java --- .../processor/misc/SuppressProcessor.java | 89 ------------------- 1 file changed, 89 deletions(-) delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/SuppressProcessor.java diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/SuppressProcessor.java b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/SuppressProcessor.java deleted file mode 100644 index 06d3ec8..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/SuppressProcessor.java +++ /dev/null @@ -1,89 +0,0 @@ -package dev.adamko.kafkatorio.processor.misc; - -import java.time.Duration; -import org.apache.kafka.streams.KeyValue; -import org.apache.kafka.streams.processor.PunctuationType; -import org.apache.kafka.streams.processor.api.Processor; -import org.apache.kafka.streams.processor.api.ProcessorContext; -import org.apache.kafka.streams.processor.api.Record; -import org.apache.kafka.streams.state.TimestampedKeyValueStore; -import org.apache.kafka.streams.state.ValueAndTimestamp; - -/** - * THIS PROCESSOR IS UNTESTED - *
- * This processor mirrors the source, but waits for an inactivity gap before forwarding records. - *
- * The suppression is key based. Newer values will replace previous values, and reset the inactivity - * gap. - */ -public class SuppressProcessor implements Processor { - - private final String storeName; - private final Duration debounceCheckInterval; - private final long suppressTimeoutMillis; - - private TimestampedKeyValueStore stateStore; - private ProcessorContext context; - - /** - * @param storeName The name of the {@link TimestampedKeyValueStore} which will hold - * records while they are being debounced. - * @param suppressTimeout The duration of inactivity before records will be forwarded. - * @param debounceCheckInterval How regularly all records will be checked to see if they are - * eligible to be forwarded. The interval should be shorter than - * {@code suppressTimeout}. - */ - public SuppressProcessor( - String storeName, - Duration suppressTimeout, - Duration debounceCheckInterval - ) { - this.storeName = storeName; - this.suppressTimeoutMillis = suppressTimeout.toMillis(); - this.debounceCheckInterval = debounceCheckInterval; - } - - @Override - public void init(ProcessorContext context) { - this.context = context; - - stateStore = context.getStateStore(storeName); - - context.schedule(debounceCheckInterval, PunctuationType.WALL_CLOCK_TIME, this::punctuate); - } - - @Override - public void process(Record record) { - - final var key = record.key(); - final var value = record.value(); - - final var storedRecord = stateStore.get(key); - - final var isNewRecord = storedRecord == null; - - final var timestamp = isNewRecord ? System.currentTimeMillis() : storedRecord.timestamp(); - - stateStore.put(key, ValueAndTimestamp.make(value, timestamp)); - } - - private void punctuate(long timestamp) { - try (var iterator = stateStore.all()) { - while (iterator.hasNext()) { - KeyValue> storedRecord = iterator.next(); - if (timestamp - storedRecord.value.timestamp() > suppressTimeoutMillis) { - - final var record = new Record<>( - storedRecord.key, - storedRecord.value.value(), - storedRecord.value.timestamp() - ); - - context.forward(record); - stateStore.delete(storedRecord.key); - } - } - } - } -} From afe6a16287bc442ccca070535ff157df1fc103f2 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 2 May 2022 23:35:19 +0200 Subject: [PATCH 318/629] tidy up topology --- .../processor/KafkatorioTopology.kt | 7 +- .../processor/topology/flowMapTiles.kt | 309 ------------------ .../processor/topology/groupMapChunks.kt | 5 - .../kafkatorio/processor/topology/model.kt | 3 + .../{flowMapTiles2.kt => saveMapTiles.kt} | 175 ++++++---- .../processor/topology/SaveMapChunksTest.kt | 2 +- 6 files changed, 114 insertions(+), 387 deletions(-) delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/{flowMapTiles2.kt => saveMapTiles.kt} (65%) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index dbc940e..5bea0c6 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -4,7 +4,7 @@ import dev.adamko.kafkatorio.processor.config.ApplicationProperties import dev.adamko.kafkatorio.processor.topology.factorioServerPacketStream import dev.adamko.kafkatorio.processor.topology.groupMapChunks import dev.adamko.kafkatorio.processor.topology.playerUpdatesToWsServer -import dev.adamko.kafkatorio.processor.topology.saveMapTiles2 +import dev.adamko.kafkatorio.processor.topology.saveMapTiles import dev.adamko.kafkatorio.processor.topology.splitFactorioServerPacketStream import java.time.Duration import java.util.Properties @@ -60,8 +60,7 @@ internal class KafkatorioTopology( private fun saveTiles() { val builder = StreamsBuilder() -// val topology = saveMapTiles(builder) - val topology = saveMapTiles2(builder, appProps.webmapTileDir) + val topology = saveMapTiles(builder, appProps.webmapTileDir) launchTopology("saveTiles", topology) } @@ -87,8 +86,6 @@ internal class KafkatorioTopology( val appId = props.compute(StreamsConfig.APPLICATION_ID_CONFIG) { _, v -> "$v.$id" } as? String props.setProperty(StreamsConfig.APPLICATION_ID_CONFIG, appId) -// props.setProperty(StreamsConfig.MAX_TASK_IDLE_MS_CONFIG, "${30.minutes.inWholeMilliseconds}") - val streams = KafkaStreams(topology, props) streams.setUncaughtExceptionHandler(StreamsExceptionHandler { coroutineContext.job.cancel(CancellationException(cause = it)) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt deleted file mode 100644 index e771b0b..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles.kt +++ /dev/null @@ -1,309 +0,0 @@ -package dev.adamko.kafkatorio.processor.topology - -import com.sksamuel.scrimage.ImmutableImage -import com.sksamuel.scrimage.ScaleMethod -import com.sksamuel.scrimage.color.RGBColor -import com.sksamuel.scrimage.nio.PngWriter -import dev.adamko.kafkatorio.processor.KafkatorioTopology.Companion.rootJob -import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE -import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kafkatorio.schema.common.ColourHex -import dev.adamko.kafkatorio.schema.common.MapChunkPosition -import dev.adamko.kafkatorio.schema.common.MapTilePosition -import dev.adamko.kafkatorio.schema.common.SurfaceIndex -import dev.adamko.kafkatorio.schema.common.toMapChunkPosition -import dev.adamko.kotka.extensions.consumedAs -import dev.adamko.kotka.extensions.streams.forEach -import dev.adamko.kotka.kxs.serde -import java.awt.Color -import java.awt.image.BufferedImage -import java.io.File -import kotlin.coroutines.CoroutineContext -import kotlin.io.path.fileSize -import kotlin.math.abs -import kotlin.time.Duration.Companion.seconds -import kotlinx.coroutines.CoroutineName -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.asFlow -import kotlinx.coroutines.flow.debounce -import kotlinx.coroutines.flow.distinctUntilChangedBy -import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.flatMapConcat -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.runningFold -import kotlinx.coroutines.launch -import kotlinx.coroutines.supervisorScope -import kotlinx.serialization.Serializable -import org.apache.kafka.streams.StreamsBuilder -import org.apache.kafka.streams.Topology -import org.apache.kafka.streams.kstream.KStream - - -private const val WEB_MAP_TILE_SIZE_PX = 256 - - -/** A bridge between Kafka and Kotlin */ -private val serverMapChunkHandler = ServerMapChunkHandler() - - -fun saveMapTiles( - builder: StreamsBuilder, -): Topology { - val pid = "saveMapTiles" - - val groupedMapChunkTiles: KStream> = - builder.stream( - TOPIC_GROUPED_MAP_CHUNKS_STATE, - consumedAs("$pid.consume.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()) - ) - - groupedMapChunkTiles - .forEach("save-chunked-tiles") { _, value -> - if (value != null) { - println("emitting chunkedTiles ${value.chunkId} tiles: ${value.map.size}") - serverMapChunkHandler.emit(value) - } - } - - return builder.build() -} - - -@JvmInline -value class TilePngFilename( - val value: String, -) { - constructor(id: ServerMapChunkId) : this(buildString { - append("s${id.surfaceIndex}") - append("/z${id.chunkSize.zoomLevel}") - append("/x${id.chunkPosition.x}") - append("/y${id.chunkPosition.y}") - append(".png") - }) -} - - -val TRANSPARENT_AWT: Color = ColourHex.TRANSPARENT.toRgbColor().awt() - - -fun ColourHex.toRgbColor(): RGBColor { - return RGBColor( - red.toInt(), - green.toInt(), - blue.toInt(), - alpha.toInt(), - ) -} - - -private class ServerMapChunkHandler : CoroutineScope { - - override val coroutineContext: CoroutineContext = - Dispatchers.Default + SupervisorJob(rootJob) + CoroutineName("ServerMapChunkHandler") - - - /** The inbox for this handler. */ - private val allChunksFlow = MutableSharedFlow>( - replay = 0, - extraBufferCapacity = 10, - onBufferOverflow = BufferOverflow.SUSPEND, - ) - - fun emit(mapChunkTiles: ServerMapChunkTiles) = launch { - allChunksFlow.emit(mapChunkTiles) - } - - /** This flow saves images one-by-one */ - private val saveImagesFlow = MutableSharedFlow( - replay = 0, - extraBufferCapacity = 10, - onBufferOverflow = BufferOverflow.SUSPEND, - ) - - init { - - allChunksFlow - .runningFold(mutableMapOf>()) { acc, src -> - - val flow = acc.getOrPut(src.chunkId) { - println("creating new subdivide-flow for chunkId ${src.chunkId}") - createSubdivisionFlow() - } - - flow.emit(Cmd.ChunkSubdivide(src.chunkId, src.map)) - - acc - } - .distinctUntilChangedBy { it.size } - .onEach { - println("allChunksFlow has ${it.size} subdivide-flows: ${it.keys.joinToString()}") - } - .launchIn(this) - - - saveImagesFlow - .onEach { (filename, img) -> - - val chunkImageFile = File(filename.value) - if (chunkImageFile.parentFile.mkdirs()) { - println("created new map tile parentFile directory ${chunkImageFile.absolutePath}") - } - - val sizeBefore = chunkImageFile.takeIf { it.exists() }?.toPath()?.fileSize() - - val savedTile = img.output(PngWriter.NoCompression, chunkImageFile) - - val sizeAfter = savedTile.takeIf { it.exists() }?.toPath()?.fileSize() - if (sizeBefore != sizeAfter) { -// println("savedTile $sizeBefore/$sizeAfter: $savedTile") - } else { - println("savedTile NO-SIZE-CHANGE $sizeBefore/$sizeAfter: $savedTile") - } - } - .launchIn(this) - - } - - - /** - * Given a chunk, split it into multiple, smaller sub-tiles. - * - * Send each sub-tile to [saveImagesFlow] to be saved as a PNG - */ - private fun createSubdivisionFlow(): MutableSharedFlow { - - val subdivisionFlow = MutableSharedFlow( - replay = 0, - extraBufferCapacity = 10, - onBufferOverflow = BufferOverflow.SUSPEND, - ) - - val saveImgCommands: Flow = - subdivisionFlow - .debounce(30.seconds) - .flatMapConcat { subdivideCmd -> - ChunkSize - .entries - .flatMap { chunkSize -> - subdivideCmd - .tiles - .entries - .groupBy( - { (tile, _) -> tile.toMapChunkPosition(chunkSize.lengthInTiles) } - ) { (tilePosition, colour) -> - tilePosition to colour - } - .map { (chunkPos, tiles) -> - async { - Cmd.CreateImage( - surfaceIndex = subdivideCmd.chunkId.surfaceIndex, - chunkSize = chunkSize, - chunkPosition = chunkPos, - tiles = tiles.toMap() - ) - } - } - } - .awaitAll() - .asFlow() - } - .map { createCmd -> - val img = createMapTileImage( - createCmd.chunkPosition, - createCmd.tiles, - createCmd.chunkSize, - ) - - Cmd.SaveImage(createCmd.tilePngFilename, img) - } - - launch { - supervisorScope { - println("emitting all saveImgCommands to saveImagesFlow") - saveImagesFlow.emitAll(saveImgCommands) - } - } - - return subdivisionFlow - } - - - /** Create (but don't save) a PNG for the given chunk. */ - private fun createMapTileImage( - chunkPosition: MapChunkPosition, - chunkColours: Map, - chunkSize: ChunkSize - ): ImmutableImage { - - val chunkImage = ImmutableImage.filled( - chunkSize.lengthInTiles, - chunkSize.lengthInTiles, - TRANSPARENT_AWT, - BufferedImage.TYPE_INT_ARGB - ) - - val chunkOriginX: Int = chunkPosition.x * chunkSize.lengthInTiles - val chunkOriginY: Int = chunkPosition.y * chunkSize.lengthInTiles - - chunkColours.forEach { (tilePosition, colour) -> - - val rgbColour = colour.toRgbColor() - - val pixelX = abs(abs(tilePosition.x) - abs(chunkOriginX)) - val pixelY = abs(abs(tilePosition.y) - abs(chunkOriginY)) - - chunkImage.setColor( - pixelX, - pixelY, - rgbColour - ) - } - - return chunkImage.scaleTo(WEB_MAP_TILE_SIZE_PX, WEB_MAP_TILE_SIZE_PX, ScaleMethod.FastScale) - } -} - - -private sealed interface Cmd { - - @Serializable - data class ChunkSubdivide( - val chunkId: ServerMapChunkId, - val tiles: Map, - ) : Cmd - - @Serializable - data class CreateImage( - val surfaceIndex: SurfaceIndex, - val chunkSize: ChunkSize, - val chunkPosition: MapChunkPosition, - val tiles: Map, - ) : Cmd { - val tilePngFilename: TilePngFilename by lazy { - TilePngFilename(buildString { - append("src/main/resources/kafkatorio-web-map") - append("/s${surfaceIndex}") - append("/z${chunkSize.zoomLevel}") - append("/x${chunkPosition.x}") - append("/y${chunkPosition.y}") - append(".png") - }) - } - } - - - data class SaveImage( - val filename: TilePngFilename, - val image: ImmutableImage, - ) : Cmd - -} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt index 319c59f..eb87d07 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt @@ -107,7 +107,6 @@ private fun groupTilesIntoChunksWithColours( tileProtoColourDict: KTable, ): KTable> { - val mapTilesStream: KStream = mapChunksStream.filter { _, value -> !value.tileDictionary.isNullOrEmpty() @@ -117,10 +116,6 @@ private fun groupTilesIntoChunksWithColours( }.filter("map-chunk-update-packets.filter-out.no-tiles") { _, value -> value.tiles.isNotEmpty() } -// .peek { _, value -> -// println("[${System.currentTimeMillis()}] mapTilesStream: surface:${value.surfaceIndex}, tile count: ${value.tiles.size}") -// } - val chunkedTilesTable: KTable> = mapTilesStream diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt index 1060f56..44fb966 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt @@ -1,5 +1,8 @@ package dev.adamko.kafkatorio.processor.topology +import com.sksamuel.scrimage.color.RGBColor +import dev.adamko.kafkatorio.schema.common.ColourHex +import java.awt.Color import kotlin.math.pow import kotlin.math.roundToInt import kotlinx.serialization.Serializable diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles2.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt similarity index 65% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles2.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt index e1aa3f0..71f062b 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/flowMapTiles2.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt @@ -2,6 +2,7 @@ package dev.adamko.kafkatorio.processor.topology import com.sksamuel.scrimage.ImmutableImage import com.sksamuel.scrimage.ScaleMethod +import com.sksamuel.scrimage.color.RGBColor import com.sksamuel.scrimage.nio.PngWriter import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED import dev.adamko.kafkatorio.processor.admin.TOPIC_SUBDIVIDED_MAP_TILES @@ -16,6 +17,7 @@ import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.streams.flatMap import dev.adamko.kotka.extensions.streams.forEach import dev.adamko.kotka.kxs.serde +import java.awt.Color import java.awt.image.BufferedImage import java.nio.file.Path import kotlin.io.path.fileSize @@ -27,16 +29,18 @@ import org.apache.kafka.streams.Topology import org.apache.kafka.streams.kstream.KStream +private const val pid = "saveMapTiles" + private const val WEB_MAP_TILE_SIZE_PX = 256 + /** * @param[tileDirectory] [dev.adamko.kafkatorio.processor.config.ApplicationProperties.webmapTileDir] */ -fun saveMapTiles2( +fun saveMapTiles( builder: StreamsBuilder, tileDirectory: Path, ): Topology { - val pid = "saveMapTiles" val groupedMapChunkTiles: KStream> = builder.stream( @@ -44,44 +48,16 @@ fun saveMapTiles2( consumedAs("$pid.consume.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()), ) - groupedMapChunkTiles.flatMap("$pid.subdivide-chunks") { initialKey, initialChunk -> - - val (chunks, time) = measureTimedValue { - ChunkSize.entries.flatMap { chunkSize -> - initialChunk.map - .entries - .groupingBy { (tilePosition, _) -> - val chunkPosition = tilePosition.toMapChunkPosition(chunkSize.lengthInTiles) -// println("$tilePosition groupingBy $chunkPosition") - initialKey.copy( - chunkSize = chunkSize, - chunkPosition = chunkPosition, - ) - }.fold( - initialValueSelector = { _, _ -> mutableMapOf() } - ) { _, accumulator, (tilePosition, colour) -> -// println("fold $tilePosition $colour") - accumulator[tilePosition] = colour - accumulator - } - .map { (chunkId, tiles) -> -// println("map $chunkId ${tiles.size}") - chunkId to ServerMapChunkTiles(chunkId, tiles) - } - } - - } - println("subdivided ${initialKey.chunkPosition} to ${chunks.size} chunks in $time") - - chunks - }.to( - TOPIC_SUBDIVIDED_MAP_TILES, - producedAs( - "$pid.produce.grouped-map-chunks", - kxsBinary.serde(), - kxsBinary.serde(), + groupedMapChunkTiles + .flatMapSubdividedChunk() + .to( + TOPIC_SUBDIVIDED_MAP_TILES, + producedAs( + "$pid.produce.grouped-map-chunks", + kxsBinary.serde(), + kxsBinary.serde(), + ) ) - ) val subdividedMapChunkTilesDebounced: KStream> = builder.stream( @@ -93,34 +69,7 @@ fun saveMapTiles2( ), ) - subdividedMapChunkTilesDebounced - .forEach("$pid.save-tiles") { chunkId: ServerMapChunkId, tileColours: ServerMapChunkTiles -> - - val chunkImage = ImmutableImage.filled( - chunkId.chunkSize.lengthInTiles, - chunkId.chunkSize.lengthInTiles, - TRANSPARENT_AWT, - BufferedImage.TYPE_INT_ARGB - ) - - val chunkOriginX: Int = chunkId.chunkPosition.x * chunkId.chunkSize.lengthInTiles - val chunkOriginY: Int = chunkId.chunkPosition.y * chunkId.chunkSize.lengthInTiles - - tileColours.map.forEach { (tilePosition, colour) -> - val rgbColour = colour.toRgbColor() - - val pixelX = abs(abs(tilePosition.x) - abs(chunkOriginX)) - val pixelY = abs(abs(tilePosition.y) - abs(chunkOriginY)) - - chunkImage.setColor(pixelX, pixelY, rgbColour) - } - - val scaledImage = - chunkImage.scaleTo(WEB_MAP_TILE_SIZE_PX, WEB_MAP_TILE_SIZE_PX, ScaleMethod.FastScale) - - val filename = TilePngFilename(chunkId) - saveTile(filename, tileDirectory, scaledImage) - } + subdividedMapChunkTilesDebounced.forEachChunkSaveImage(tileDirectory) return builder.build() .addDebounceProcessor>( @@ -133,6 +82,71 @@ fun saveMapTiles2( ) } + +private fun KStream>.flatMapSubdividedChunk() = + flatMap("$pid.subdivide-chunks") { initialKey, initialChunk -> + + val (chunks, time) = measureTimedValue { + ChunkSize.entries.flatMap { chunkSize -> + initialChunk.map + .entries + .groupingBy { (tilePosition, _) -> + val chunkPosition = tilePosition.toMapChunkPosition(chunkSize.lengthInTiles) + initialKey.copy( + chunkSize = chunkSize, + chunkPosition = chunkPosition, + ) + }.fold( + initialValueSelector = { _, _ -> mutableMapOf() } + ) { _, accumulator, (tilePosition, colour) -> + accumulator[tilePosition] = colour + accumulator + } + .map { (chunkId, tiles) -> + chunkId to ServerMapChunkTiles(chunkId, tiles) + } + } + } + + println("subdivided ${initialKey.chunkPosition} to ${chunks.size} chunks in $time") + + chunks + } + + +private fun KStream>.forEachChunkSaveImage( + tileDirectory: Path, +) = forEach( + "$pid.save-tiles" +) { chunkId: ServerMapChunkId, tileColours: ServerMapChunkTiles -> + + val chunkImage = ImmutableImage.filled( + chunkId.chunkSize.lengthInTiles, + chunkId.chunkSize.lengthInTiles, + TRANSPARENT_AWT, + BufferedImage.TYPE_INT_ARGB + ) + + val chunkOriginX: Int = chunkId.chunkPosition.x * chunkId.chunkSize.lengthInTiles + val chunkOriginY: Int = chunkId.chunkPosition.y * chunkId.chunkSize.lengthInTiles + + tileColours.map.forEach { (tilePosition, colour) -> + val rgbColour = colour.toRgbColor() + + val pixelX = abs(abs(tilePosition.x) - abs(chunkOriginX)) + val pixelY = abs(abs(tilePosition.y) - abs(chunkOriginY)) + + chunkImage.setColor(pixelX, pixelY, rgbColour) + } + + val scaledImage = + chunkImage.scaleTo(WEB_MAP_TILE_SIZE_PX, WEB_MAP_TILE_SIZE_PX, ScaleMethod.FastScale) + + val filename = TilePngFilename(chunkId) + saveTile(filename, tileDirectory, scaledImage) +} + + @Synchronized fun saveTile( filename: TilePngFilename, @@ -156,3 +170,30 @@ fun saveTile( } println("savedTile $sizeDescription: $savedTile") } + + +@JvmInline +value class TilePngFilename( + val value: String, +) { + constructor(id: ServerMapChunkId) : this(buildString { + append("s${id.surfaceIndex}") + append("/z${id.chunkSize.zoomLevel}") + append("/x${id.chunkPosition.x}") + append("/y${id.chunkPosition.y}") + append(".png") + }) +} + + +val TRANSPARENT_AWT: Color = ColourHex.TRANSPARENT.toRgbColor().awt() + + +fun ColourHex.toRgbColor(): RGBColor { + return RGBColor( + red.toInt(), + green.toInt(), + blue.toInt(), + alpha.toInt(), + ) +} diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt index 3f4eaf2..9ca2067 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt @@ -78,7 +78,7 @@ class SaveMapChunksTest : FunSpec({ val now = LocalTime.now().format(DateTimeFormatter.ISO_TIME).filter { it.isLetterOrDigit() } Path("build/test/save-map-chunks-${now}") } - private val topology = saveMapTiles2(streamsBuilder, outputDir) + private val topology = saveMapTiles(streamsBuilder, outputDir) val testDriver: TopologyTestDriver = TopologyTestDriver(topology) val groupedMapChunksInputTopic: TestInputTopic> = From 24e4cdf329d1dca05b28403ac4fdb3010b10a734 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 2 May 2022 23:35:33 +0200 Subject: [PATCH 319/629] bump kafka-ui version --- modules/infra-kafka-cluster/src/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infra-kafka-cluster/src/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml index 40749ec..2a277ee 100644 --- a/modules/infra-kafka-cluster/src/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -27,7 +27,7 @@ services: - "9093:9093" kafka-ui: - image: provectuslabs/kafka-ui:0.3.3 + image: provectuslabs/kafka-ui:v0.4.0 container_name: "kafka-ui" restart: "unless-stopped" networks: From 5656acd350ed7373686ba6f0ff5fbee6b1ddaf32 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 7 May 2022 20:22:54 +0200 Subject: [PATCH 320/629] try fixing gradle config cache errors --- build.gradle.kts | 4 +- .../adamko/kafkatorio/gradle/extensions.kt | 12 ++- .../adamko/kafkatorio/lang/node.gradle.kts | 5 +- .../kafkatorio/task/GenerateTypescriptTask.kt | 35 ++++++++ .../kafkatorio/task/UpdatePackageJson.kt | 24 +++--- modules/events-mod/build.gradle.kts | 21 +++-- modules/events-schema/build.gradle.kts | 83 ++++++++++++------- 7 files changed, 128 insertions(+), 56 deletions(-) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypescriptTask.kt diff --git a/build.gradle.kts b/build.gradle.kts index 8e2e73d..c802f4b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,6 +6,8 @@ plugins { base `project-report` `build-dashboard` + + kotlin("multiplatform") apply false // try to stop error 'Projects must be configuring' } group = "dev.adamko.kafkatorio" @@ -15,7 +17,7 @@ val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) val projectTokens: MapProperty by extra { objects.mapProperty().apply { - put("project.version", provider { "$version" }) + put("project.version", provider { "${project.version}" }) put("rootProject.name", provider { rootProject.name }) put("date.year", provider { "${LocalDate.now().year}" }) put("author.email", "adam@adamko.dev") diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt index 71a85d1..3bb8f13 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt @@ -3,7 +3,9 @@ package dev.adamko.kafkatorio.gradle import java.io.ByteArrayOutputStream import org.gradle.api.Project import org.gradle.api.file.Directory +import org.gradle.api.file.FileCopyDetails import org.gradle.api.file.ProjectLayout +import org.gradle.api.file.RelativePath import org.gradle.api.specs.NotSpec import org.gradle.api.specs.Spec import org.gradle.plugins.ide.idea.model.IdeaModule @@ -14,8 +16,8 @@ import org.jetbrains.kotlin.incremental.md5 operator fun Spec.not(): NotSpec = NotSpec(this) -// -// + + //fun isProcessRunning(process: String, ignoreCase: Boolean = true): Spec = // Spec { // ByteArrayOutputStream().use { outputStream -> @@ -59,6 +61,7 @@ fun Project.execCapture(spec: ExecSpec.() -> Unit): String { } } + /** https://youtrack.jetbrains.com/issue/KT-50848 */ fun Project.yarn(configure: YarnRootExtension.() -> Unit) = with(yarn, configure) @@ -68,3 +71,8 @@ fun Directory.filesChecksum() = asFileTree .map { it.readBytes() + it.absolutePath.toByteArray() } .fold(byteArrayOf()) { acc, bytes -> acc + bytes } .md5() + + +/** Drop the first [count] directories from the path */ +fun FileCopyDetails.dropDirectories(count: Int = 1): RelativePath = + RelativePath(true, *relativePath.segments.drop(count).toTypedArray()) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts index 4a309db..59c1c21 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts @@ -16,11 +16,14 @@ node { distBaseUrl.set(null as String?) // set by dependencyResolutionManagement } +val projectVersion: Provider = providers.provider { "${project.version}" } + val updatePackageJson by tasks.registering(UpdatePackageJson::class) { // group = NodePlugin.NODE_GROUP // description = "Read the package.json file and update the version and name, based on the project." - propertiesToCheck.put("version", providers.provider { "${project.version}" }) + inputs.property("projectVersion", projectVersion) + propertiesToCheck.put("version", projectVersion) // check to see if the properties are already up-to-date // outputs.upToDateWhen(areJsonPropertiesUpToDate(packageJsonFile, propertiesToCheck)) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypescriptTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypescriptTask.kt new file mode 100644 index 0000000..51b7032 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypescriptTask.kt @@ -0,0 +1,35 @@ +package dev.adamko.kafkatorio.task + +import javax.inject.Inject +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.FileSystemOperations +import org.gradle.api.tasks.JavaExec +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction + + +abstract class GenerateTypescriptTask @Inject constructor( + private val fileOps: FileSystemOperations, +) : JavaExec() { + + @get:OutputDirectory + abstract val output: DirectoryProperty + + init { + group = "kt2ts" + } + + @TaskAction + fun generate() { + fileOps.delete { delete(temporaryDir) } + temporaryDir.mkdirs() + + super.exec() + + fileOps.sync { + from(temporaryDir) + into(output) + include("**/*.ts") + } + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt index 418bfdd..32ebb08 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt @@ -19,7 +19,9 @@ import org.gradle.kotlin.dsl.support.useToRun import org.jetbrains.kotlin.util.suffixIfNot @CacheableTask -abstract class UpdatePackageJson : DefaultTask() { +abstract class UpdatePackageJson @Inject constructor( + private val providers: ProviderFactory +) : DefaultTask() { @get:Input abstract val propertiesToCheck: MapProperty @@ -27,15 +29,10 @@ abstract class UpdatePackageJson : DefaultTask() { @get:OutputFile abstract val packageJsonFile: RegularFileProperty - @get:Inject - abstract val providers: ProviderFactory -// -// @get:Inject -// abstract val fs: FileSystemOperations - init { group = NodePlugin.NODE_GROUP - description = "Read the package.json file and update the version and name, based on the project." + description = + "Read the package.json file and update the version and name, based on the project." outputs.upToDateWhen(JsonPropertiesUpToDateSpec) @@ -47,12 +44,13 @@ abstract class UpdatePackageJson : DefaultTask() { @TaskAction fun exec() { - val pj = packageJsonFile.asFile.get() + val packageJsonFile = packageJsonFile.asFile.get() + val propertiesToCheck = propertiesToCheck.get() - logger.info("updating package.json ${pj.canonicalPath}") - val packageJson = jsonMapper.parseToJsonElement(pj.readText()).jsonObject + logger.info("updating package.json ${packageJsonFile.canonicalPath}") + val packageJson = jsonMapper.parseToJsonElement(packageJsonFile.readText()).jsonObject - val newJsonProps = propertiesToCheck.get().mapValues { (_, newVal) -> JsonPrimitive(newVal) } + val newJsonProps = propertiesToCheck.mapValues { (_, newVal) -> JsonPrimitive(newVal) } val packageJsonUpdate = JsonObject(packageJson + newJsonProps) val packageJsonContentUpdated = @@ -62,7 +60,7 @@ abstract class UpdatePackageJson : DefaultTask() { logger.debug(packageJsonContentUpdated) - packageJsonFile.get().asFile.writer().useToRun { + packageJsonFile.writer().useToRun { write(packageJsonContentUpdated) } } diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index acd0431..b6d4976 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -1,5 +1,6 @@ import dev.adamko.kafkatorio.gradle.asConsumer import dev.adamko.kafkatorio.gradle.asProvider +import dev.adamko.kafkatorio.gradle.dropDirectories import dev.adamko.kafkatorio.gradle.factorioModAttributes import dev.adamko.kafkatorio.gradle.typescriptAttributes import dev.adamko.kafkatorio.task.TypescriptToLuaTask @@ -11,15 +12,15 @@ plugins { distribution } -description = - "Sends in-game information to a server over the internet (requires Kafkatorio Kafka-Pipe)" +description = "Sends in-game information to a server over the internet (requires additional setup)" // Factorio required format is: // - filename: `mod-name_version.zip` // - zip contains one directory, `mod-name` + val modName: String by extra { "${rootProject.name}-events" } -val distributionZipName: String by extra { "${modName}_${project.version}.zip" } +val distributionZipName: String by extra { "${modName}_${rootProject.version}.zip" } // version of Factorio that the mod is compatible with (must only be "major.minor" - patch causes error) val modFactorioCompatibility: Provider = @@ -27,10 +28,11 @@ val modFactorioCompatibility: Provider = val licenseFile: RegularFile by rootProject.extra val projectTokens: MapProperty by rootProject.extra +val modDescription: String by project.extra { project.description ?: "" } projectTokens.apply { put("mod.name", modName) put("mod.title", "Kafkatorio Events") - put("mod.description", provider { project.description }.orElse("")) + put("mod.description", modDescription) put("factorio.version", modFactorioCompatibility) } @@ -41,6 +43,7 @@ node { nodeProjectDir.set(tsSrcDir) } + val typescriptEventsSchema: Configuration by configurations.creating { description = "Fetch the TypeScript schema from the event-schema subproject" asConsumer() @@ -82,9 +85,7 @@ val installEventsTsSchema by tasks.registering(Sync::class) { } ) { // drop the first directory inside the zip - eachFile { - relativePath = RelativePath(true, *relativePath.segments.drop(1).toTypedArray()) - } + eachFile { relativePath = dropDirectories() } includeEmptyDirs = false } into(outputDir) @@ -123,7 +124,6 @@ distributions { } } } - } } @@ -163,8 +163,11 @@ val factorioModProvider by configurations.registering { } +val packageJsonName = providers.provider { "${rootProject.name}-${project.name}" } + tasks.updatePackageJson { - propertiesToCheck.put("name", providers.provider { "${rootProject.name}-${project.name}" }) + inputs.property("packageJsonName", packageJsonName) + propertiesToCheck.put("name", packageJsonName) packageJsonFile.set(layout.projectDirectory.file("src/main/typescript/package.json")) } diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index 4e784c9..3bbfd52 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -1,5 +1,6 @@ import dev.adamko.kafkatorio.gradle.asProvider import dev.adamko.kafkatorio.gradle.typescriptAttributes +import dev.adamko.kafkatorio.task.GenerateTypescriptTask plugins { @@ -106,56 +107,78 @@ kotlin { } } +val jvmJar: TaskProvider = tasks.named(kotlin.jvm().artifactsTaskName) +val mainCompilation: Provider = + kotlin.jvm().compilations.named("main").map { it.runtimeDependencyFiles } -val generateTypescript by tasks.registering(JavaExec::class) { - group = "kt2ts" - val jvmJar = tasks.named(kotlin.jvm().artifactsTaskName) +val generateTypescript by tasks.registering(GenerateTypescriptTask::class) { dependsOn(jvmJar) - - val mainCompilation = kotlin.jvm().compilations.named("main").map { it.runtimeDependencyFiles } -// dependsOn(mainCompilation) - inputs.files(mainCompilation) - classpath( jvmJar, - mainCompilation + mainCompilation, ) - -// mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2tsKt") + output.set(layout.buildDirectory.dir("generated/typescript")) mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2ts2Kt") + args(temporaryDir.canonicalPath) +} - val tempOutputDirectory = file("$temporaryDir") - args(tempOutputDirectory) +//val generateTypescript2 by tasks.registering(JavaExec::class) { +// group = "kt2ts" +// +// dependsOn(jvmJar) +// +// inputs.files(mainCompilation) +// +// classpath( +// jvmJar, +// mainCompilation, +// ) +// mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2ts2Kt") +// +// args(temporaryDir) +// +// val buildOutput = layout.buildDirectory.dir("generated/typescript") +// outputs.dir(buildOutput) +// +// doFirst { +// delete(temporaryDir) +// mkdir(temporaryDir) +// } +// +// doLast { +// sync { +// from(temporaryDir) +// into(buildOutput) +// include("**/*.ts") +// } +// } +//} - val buildOutput = layout.buildDirectory.dir("generated/typescript") - outputs.dir(buildOutput) - - doFirst { - delete(temporaryDir) - mkdir(temporaryDir) - } - - doLast { - sync { - from(temporaryDir) - into(buildOutput) - include("**/*.ts") - } - } +val schemaTsDistributionName = providers.provider { + "${rootProject.name}-${project.name}" } val schemaTs by distributions.registering { - distributionBaseName.set("${rootProject.name}-${project.name}") + distributionBaseName.set(schemaTsDistributionName) contents { from(generateTypescript.map { it.outputs.files.asFileTree }) } } +val schemaTsZipTask = tasks.named("${schemaTs.name}DistZip") + val typescriptModelGenerated: Configuration by configurations.creating { asProvider() typescriptAttributes(objects) - val schemaTsZipTask = tasks.named("${schemaTs.name}DistZip") outgoing.artifact(schemaTsZipTask.flatMap { it.archiveFile }) } + + +tasks.matching { + it.name == "jsGenerateExternalsIntegrated" +}.configureEach { + @Suppress("UnstableApiUsage") + notCompatibleWithConfigurationCache("try to prevent 'Projects must be configuring' error") +} From 688b2c7bcb6471a560d59fd2d42eada153709512 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 7 May 2022 20:29:24 +0200 Subject: [PATCH 321/629] - add tile deconstruction (concrete tiles can be removed) - add @SerialName to all packets - start implementing Entity prototype - start implementing Entity updates - clean up some old commented out code - refactor how debounced events track the triggering events (now include timestamps per event) - bump tstl --- .../resources/mod-data/locale/en/locale.cfg | 12 +- .../events-mod/src/main/typescript/control.ts | 1 + .../kafkatorio-schema/kafkatorio-schema.ts | 26 ++-- .../typescript/main/cache/EventDataCache.ts | 44 ------ .../main/config-update/prototypes.ts | 18 +++ .../typescript/main/events/EntityEvents.ts | 97 ++++++++++++ .../main/typescript/main/events/converters.ts | 121 ++++----------- .../main/typescript/main/events/handlers.ts | 96 ------------ .../main/events/onMapChunkEventListeners.ts | 142 +++++++++++------- .../main/events/onPlayerEventListeners.ts | 85 ++++++----- .../main/events/registerHandlers.ts | 12 +- .../main/settings/KafkatorioSettings.ts | 12 +- .../src/main/typescript/main/types.d.ts | 3 + .../src/main/typescript/package-lock.json | 12 +- .../src/main/typescript/package.json | 15 +- .../kafkatorio/schema/common/colours.kt | 3 + .../kafkatorio/schema/common/factorioIds.kt | 9 ++ .../schema/common/factorioPrototypes.kt | 27 ++++ .../kafkatorio/schema/common/resources.kt | 40 +++++ .../schema/packets/kafkatorioPacket.kt | 3 + .../schema/packets/kafkatorioPacketInstant.kt | 11 +- .../schema/packets/kafkatorioPacketKeyed.kt | 33 ++-- .../schema/prototypes/factorioPrototypes.kt | 23 --- .../events/schema/MapChunkUpdateTest.kt | 15 +- .../events/schema/PrototypesTest.kt | 112 +++++++------- .../events/schema/UpdatePacketsTest.kt | 38 +++-- .../schema/packets/EntityUpdateTest.kt | 50 ++++++ .../processor/topology/prototypes.kt | 2 +- .../processor/topology/GroupMapChunksTest.kt | 114 +++++++------- .../processor/topology/SaveMapChunksTest.kt | 27 +--- 30 files changed, 650 insertions(+), 553 deletions(-) create mode 100644 modules/events-mod/src/main/typescript/main/events/EntityEvents.ts create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt delete mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt create mode 100644 modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt diff --git a/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg b/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg index 1415aa5..66fba27 100644 --- a/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg +++ b/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg @@ -1,15 +1,15 @@ [mod-setting-name] -kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-PlayerUpdate=Player update rate (seconds) -kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-MapChunkUpdate=Map update rate (seconds) -kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-EntityUpdate=Entity update rate (seconds) +kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-PlayerUpdate=Player update rate (seconds) +kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-MapChunkUpdate=Map update rate (seconds) +kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-EntityUpdate=Entity update rate (seconds) [mod-setting-description] -kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-PlayerUpdate=How frequently Player updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (0.25 seconds) is probably fine! -kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-MapChunkUpdate=How frequently Map updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine! -kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-EntityUpdate=How frequently Entity updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (5 seconds) is probably fine! +kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-PlayerUpdate=How frequently Player updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (0.25 seconds) is probably fine! +kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-MapChunkUpdate=How frequently Map updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine! +kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-EntityUpdate=How frequently Entity updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (5 seconds) is probably fine! [string-mod-setting] diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index 6501c36..3933383 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -6,6 +6,7 @@ import KafkatorioSettings from "./main/settings/KafkatorioSettings"; require("./main/events/registerHandlers") require("./main/events/onMapChunkEventListeners") require("./main/events/onPlayerEventListeners") +require("./main/events/EntityEvents") require("./main/commands/kafkatorioCommands") require("./main/cache/cacheChecker") diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts index 741fb77..54893f8 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts @@ -20,14 +20,14 @@ export type KafkatorioPacketData = export namespace KafkatorioPacketData { export enum Type { - ConfigurationUpdate = "dev.adamko.kafkatorio.schema.packets.ConfigurationUpdate", - ConsoleChatUpdate = "dev.adamko.kafkatorio.schema.packets.ConsoleChatUpdate", - ConsoleCommandUpdate = "dev.adamko.kafkatorio.schema.packets.ConsoleCommandUpdate", - PrototypesUpdate = "dev.adamko.kafkatorio.schema.packets.PrototypesUpdate", - SurfaceUpdate = "dev.adamko.kafkatorio.schema.packets.SurfaceUpdate", - EntityUpdate = "dev.adamko.kafkatorio.schema.packets.EntityUpdate", - MapChunkUpdate = "dev.adamko.kafkatorio.schema.packets.MapChunkUpdate", - PlayerUpdate = "dev.adamko.kafkatorio.schema.packets.PlayerUpdate", + ConfigurationUpdate = "kafkatorio.packet.instant.ConfigurationUpdate", + ConsoleChatUpdate = "kafkatorio.packet.instant.ConsoleChatUpdate", + ConsoleCommandUpdate = "kafkatorio.packet.instant.ConsoleCommandUpdate", + PrototypesUpdate = "kafkatorio.packet.instant.PrototypesUpdate", + SurfaceUpdate = "kafkatorio.packet.instant.SurfaceUpdate", + EntityUpdate = "kafkatorio.packet.keyed.EntityUpdate", + MapChunkUpdate = "kafkatorio.packet.keyed.MapChunkUpdate", + PlayerUpdate = "kafkatorio.packet.keyed.PlayerUpdate", } export interface ConfigurationUpdate { @@ -66,7 +66,7 @@ export namespace KafkatorioPacketData { export interface EntityUpdate { type: KafkatorioPacketData.Type.EntityUpdate; key: EntityUpdateKey; - eventCounts?: { [key: string]: UInt } | null; + events?: { [key: EventName]: Tick[] } | null; chunkPosition?: MapChunkPosition | null; graphicsVariation?: UByte | null; health?: Float | null; @@ -81,7 +81,7 @@ export namespace KafkatorioPacketData { export interface MapChunkUpdate { type: KafkatorioPacketData.Type.MapChunkUpdate; key: MapChunkUpdateKey; - eventCounts?: { [key: string]: UInt } | null; + events?: { [key: EventName]: Tick[] } | null; player?: PlayerIndex | null; robot?: EntityIdentifiersData | null; force?: ForceIndex | null; @@ -92,7 +92,7 @@ export namespace KafkatorioPacketData { export interface PlayerUpdate { type: KafkatorioPacketData.Type.PlayerUpdate; key: PlayerUpdateKey; - eventCounts?: { [key: string]: UInt } | null; + events?: { [key: EventName]: Tick[] } | null; characterUnitNumber?: UnitNumber | null; chatColour?: Colour | null; colour?: Colour | null; @@ -196,7 +196,7 @@ export type FactorioPrototype = export namespace FactorioPrototype { export enum Type { - MapTile = "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + MapTile = "kafkatorio.prototype.MapTile", } export interface MapTile { @@ -210,6 +210,8 @@ export namespace FactorioPrototype { } } +export type EventName = string; + export type Byte = int8; export type List = any; diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts index 4dbaa09..e80a90a 100644 --- a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts +++ b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts @@ -181,55 +181,13 @@ export namespace EventUpdates { return game.encode_string(game.table_to_json(key))!! } - - // function isKeyInstanceOf( - // key: CacheKey | undefined, - // updateType: TYPE, - // ): key is CacheKey { - // return key != undefined && key.updateType == updateType - // } - } - - // export type KeyedPacketType = Exclude - - // /** Map a {@link KeyedPacketType} to a {@link KafkatorioPacketData} DTO */ - // type ConvertToUpdate = - // TYPE extends "PLAYER" ? PlayerUpdate : - // TYPE extends "MAP_CHUNK" ? MapChunkUpdate : - // TYPE extends "ENTITY" ? EntityUpdate : - // never - - - // /** Map a {@link KeyedPacketType} to a {@link KafkatorioKeyedPacketKey} */ - // type ConvertToUpdateKey = - // TYPE extends "PLAYER" ? PlayerUpdateKey : - // TYPE extends "MAP_CHUNK" ? MapChunkUpdateKey : - // TYPE extends "ENTITY" ? EntityUpdateKey : - // never - - - // /** Make `updateType` specific */ export type PacketKey = PACKET["key"] export type PacketType = PACKET["type"] - // - // - // /** Make `updateType` specific */ - // export type CacheData = - // CacheTyped - // & Omit, "updateType"> - // - // - // export type CacheTyped = { - // readonly updateType: TYPE - // } - export type CacheDataMutator = (packet: PACKET) => void - class CacheEntry { lastUpdatedTick: uint = game.tick expirationDurationTicks?: uint @@ -245,8 +203,6 @@ export namespace EventUpdates { this.expirationDurationTicks = expirationDurationTicks } } - - } const EventUpdatesManager = new EventUpdates.Manager() diff --git a/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts b/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts index d52776c..85819cd 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts @@ -43,6 +43,24 @@ function getMapTilePrototypes(): FactorioPrototype.MapTile[] { return tiles } + +// function getEntityPrototypes(): FactorioPrototype.MapTile[] { +// let tiles: FactorioPrototype.MapTile[] = [] +// for (let [, tile] of game.tile_prototypes) { +// tiles.push({ +// type: FactorioPrototype.Type.MapTile, +// +// name: tile.name, +// order: tile.order, +// layer: tile.layer, +// collisionMasks: convertCollisionMaskToNames(tile.collision_mask), +// mapColour: Converters.mapColour(tile.map_color), +// canBeMined: tile.mineable_properties.minable, +// }) +// } +// return tiles +// } + function convertCollisionMaskToNames(cm: CollisionMask): string[] { let masks: string[] = [] for (let [name] of pairs(cm)) { diff --git a/modules/events-mod/src/main/typescript/main/events/EntityEvents.ts b/modules/events-mod/src/main/typescript/main/events/EntityEvents.ts new file mode 100644 index 0000000..34c2ff3 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/events/EntityEvents.ts @@ -0,0 +1,97 @@ +import {Converters} from "./converters"; +import EventDataCache from "../cache/EventDataCache"; +import { + EntityUpdateKey, + KafkatorioPacketData +} from "../../generated/kafkatorio-schema/kafkatorio-schema"; + + +script.on_event(defines.events.on_built_entity, (e: OnBuiltEntityEvent) => { + log(`on_built_entity ${e.tick}`) + handleBuiltEntityEvent(e) +}) + + +script.on_event(defines.events.on_robot_built_entity, (e: OnRobotBuiltEntityEvent) => { + log(`on_robot_built_entity ${e.tick}`) + handleBuiltEntityEvent(e) +}) + + +function handleBuiltEntityEvent(event: OnBuiltEntityEvent | OnRobotBuiltEntityEvent) { + const eventName = Converters.eventNameString(event.name) + + if (event.created_entity.unit_number == undefined) { + return + } + + const key: EntityUpdateKey = { + name: event.created_entity.name, + protoType: event.created_entity.prototype.name, + unitNumber: event.created_entity.unit_number + } + + EventDataCache.debounce( + key, + KafkatorioPacketData.Type.EntityUpdate, + data => { + + data.events ??= {} + data.events[eventName] ??= [] + data.events[eventName].push(event.tick) + + data.chunkPosition = Converters.convertMapTablePosition(event.created_entity.position) + data.graphicsVariation = event.created_entity.graphics_variation + data.health = event.created_entity.health + data.isActive = event.created_entity.active + data.isRotatable = event.created_entity.rotatable + data.lastUser = event.created_entity.last_user?.index + data.prototype = event.created_entity.prototype.name + } + ) +} + +script.on_event(defines.events.on_player_mined_entity, (e: OnPlayerMinedEntityEvent) => { + log(`on_player_mined_entity ${e.tick}`) + handleMinedEntityEvent(e) +}) + + +script.on_event(defines.events.on_robot_mined_entity, (e: OnRobotMinedEntityEvent) => { + log(`on_robot_mined_entity ${e.tick}`) + handleMinedEntityEvent(e) +}) + + +function handleMinedEntityEvent(event: OnPlayerMinedEntityEvent | OnRobotMinedEntityEvent) { + const eventName = Converters.eventNameString(event.name) + + if (event.entity.unit_number == undefined) { + return + } + + const key: EntityUpdateKey = { + name: event.entity.name, + protoType: event.entity.prototype.name, + unitNumber: event.entity.unit_number + } + + EventDataCache.debounce( + key, + KafkatorioPacketData.Type.EntityUpdate, + data => { + + data.events ??= {} + data.events[eventName] ??= [] + data.events[eventName].push(event.tick) + + data.chunkPosition = Converters.convertMapTablePosition(event.entity.position) + data.graphicsVariation = event.entity.graphics_variation + data.health = event.entity.health + data.isActive = event.entity.active + data.isRotatable = event.entity.rotatable + data.lastUser = event.entity.last_user?.index + data.prototype = event.entity.prototype.name + } + ) +} diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index 861ec53..81da5f1 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -1,24 +1,8 @@ import {EventName} from "../types"; -import {Colour} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +import {Colour, MapChunkPosition} from "../../generated/kafkatorio-schema/kafkatorio-schema"; export namespace Converters { - // export function playerToTable(player: LuaPlayer): PlayerData { - // let charIds = entitiesToUnitNumbers(player.get_associated_characters()) - // return { - // objectName: player.object_name, - // - // name: player.name, - // characterUnitNumber: player.character?.unit_number ?? null, - // associatedCharactersUnitNumbers: charIds, - // position: mapEntityPosition(player.position), - // colour: mapColour(player.color), - // chatColour: mapColour(player.chat_color), - // lastOnline: player.last_online - // } - // } - - const mapEventIdToName = new LuaTable() for (const [eventName, eventId] of pairs(defines.events)) { mapEventIdToName.set(eventId, eventName) @@ -30,61 +14,6 @@ export namespace Converters { } - // export function entityToTable(entity: LuaEntity): EntityData { - // - // let player: LuaPlayer | null = entity.is_player() ? entity.player!! : null - // - // return { - // objectName: entity.object_name, - // - // // entity data - // name: entity.name, - // type: entity.type, - // active: entity.active, - // health: entity.health ?? null, - // healthRatio: entity.get_health_ratio() ?? null, - // surface: entity.surface.index, - // unitNumber: entity.unit_number ?? null, - // position: mapEntityPosition(entity.position), - // force: entity.force.index, - // - // // player data - // playerIndex: player?.index ?? null - // } - // } - // - // function entitiesToUnitNumbers(entities: LuaEntity[]): uint[] { - // let result: (uint) [] = [] - // for (let entity of entities) { - // if (entity.unit_number != null) { - // result[result.length] = entity.unit_number - // } - // } - // return result - // } - - - // export function mapEntityPosition(mapPos: MapPositionTable): MapEntityPosition { - // return { - // x: mapPos.x, - // y: mapPos.y, - // } - // } - - // export function mapTilePosition(mapPos: MapPositionTable): MapTilePosition { - // return { - // x: mapPos.x, - // y: mapPos.y, - // } - // } - - // export function mapChunkPosition(mapPos: ChunkPositionTable): MapChunkPosition { - // return { - // x: mapPos.x, - // y: mapPos.y, - // } - // } - export function mapColour(color: ColorTable): Colour { return [ color.r ?? 0, @@ -95,23 +24,37 @@ export namespace Converters { } - // export function convertTile(tile: LuaTile): MapTile { - // return { - // x: tile.position.x, - // y: tile.position.y, - // proto: tile.prototype.name, - // } - // } - // - // export function convertTiles(tiles: LuaTile[]): MapTile[] { - // return tiles.map((tile: LuaTile) => convertTile(tile)) - // } + export function convertPlacedTiles( + placedTile: LuaTilePrototype, + oldTiles: OldTileAndPosition[], + ): TileRead[] { + const converted: TileRead[] = [] + for (const [, tile] of ipairs(oldTiles)) { + converted[converted.length] = { + position: {x: tile.position.x, y: tile.position.y}, + name: placedTile.name, + } + } + return converted + } - // export function convertBoundingBox(bb: BoundingBoxRead): MapBoundingBox { - // return { - // topLeft: mapTilePosition(bb.left_top), - // bottomRight: mapTilePosition(bb.right_bottom), - // } - // } + + export function convertRemovedTiles( + surface: LuaSurface, + oldTiles: OldTileAndPosition[], + ): TileRead[] { + const converted: TileRead[] = [] + for (const [, tile] of ipairs(oldTiles)) { + converted[converted.length] = surface.get_tile(tile.position.x, tile.position.y) + } + return converted + } + + + export function convertMapTablePosition( + position: MapPositionTable, + ): MapChunkPosition { + return [position.x, position.y] + } } diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/handlers.ts index fa5cd25..62989b8 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/handlers.ts @@ -2,34 +2,6 @@ import PacketEmitter from "../PacketEmitter"; import {KafkatorioPacketData} from "../../generated/kafkatorio-schema/kafkatorio-schema"; import Type = KafkatorioPacketData.Type; -// export function handlePlayerUpdate(tick: uint, eventType: string, playerIndex: uint) { -// let player: LuaPlayer = game.players[playerIndex] -// let table = Converters.playerToTable(player) -// -// emitEvent(table, tick, eventType) -// -// handleCharactersEvent(tick, eventType, playerIndex) -// } - -// export function handleCharactersEvent(tick: uint, eventType: string, playerIndex: uint) { -// -// let player: LuaPlayer = game.players[playerIndex] -// -// if (player.character != undefined) { -// handleEntityUpdate(tick, eventType, player.character) -// } -// for (const character of player.get_associated_characters()) { -// if (character != undefined) { -// handleEntityUpdate(tick, eventType, character) -// } -// } -// } - -// export function handleEntityUpdate(tick: uint, eventType: string, entity: LuaEntity) { -// let table = Converters.entityToTable(entity) -// emitEvent(table, tick, eventType) -// } - export function handleSurfaceUpdate( event: OnTickEvent, @@ -46,71 +18,3 @@ export function handleSurfaceUpdate( PacketEmitter.emitInstantPacket(update) } - - -// export function handleChunkUpdate( -// tick: uint, -// eventType: string, -// surfaceIndex: uint, -// position: ChunkPositionTable, -// area: BoundingBoxRead, -// ) { -// -// let surface = game.get_surface(surfaceIndex) -// -// let tiles: LuaTile[] = surface?.find_tiles_filtered({ -// area: area, -// collision_mask: ["ground-tile", "water-tile"] -// } -// ) ?? [] -// -// let convertedTiles: MapTile[] = tiles.map((tile: LuaTile) => { -// return Converters.convertTile(tile) -// }) -// -// let mapChunk: MapChunk = { -// objectName: "MapChunk", -// tiles: createMapTiles(surfaceIndex, convertedTiles), -// position: Converters.mapChunkPosition(position), -// area: Converters.convertBoundingBox(area), -// } -// -// emitEvent(mapChunk, tick, eventType) -// } - -// export function handleTilesUpdate( -// tick: uint, -// eventType: string, -// surfaceIndex: uint, -// newTileType: LuaTilePrototype, -// updatedTiles: OldTileAndPosition[], -// ) { -// -// if (!newTileType.collision_mask["ground-tile"] && !newTileType.collision_mask["water-tile"]) { -// return -// } else { -// -// let convertedTiles: MapTile[] = updatedTiles.map((it) => { -// return { -// x: it.position.x, -// y: it.position.y, -// proto: newTileType.name -// } -// }) -// -// let mapTiles: MapTiles = createMapTiles(surfaceIndex, convertedTiles) -// -// emitEvent(mapTiles, tick, eventType) -// } -// } - -// function createMapTiles( -// surfaceIndex: uint, -// tiles: MapTile[], -// ): MapTiles { -// return { -// objectName: "LuaTiles", -// surfaceIndex: surfaceIndex, -// tiles: tiles, -// } -// } diff --git a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts index 3d2269d..9f07508 100644 --- a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts @@ -12,11 +12,22 @@ import Type = KafkatorioPacketData.Type; type MapChunkUpdater = (data: KafkatorioPacketData.MapChunkUpdate) => void +type MapTileUpdateEvent = + | OnChunkGeneratedEvent + | OnPlayerBuiltTileEvent + | OnPlayerMinedEntityEvent + | OnPlayerMinedTileEvent + | OnRobotBuiltTileEvent + | OnRobotMinedEntityEvent + | OnRobotMinedTileEvent + | ScriptRaisedSetTilesEvent + + function mapTilesUpdateDebounce( surface: LuaSurface | undefined, chunkPosition: MapChunkPosition, tiles: TileRead[], - eventName: string, + event: MapTileUpdateEvent, updater?: MapChunkUpdater, expirationDurationTicks?: uint, ) { @@ -25,6 +36,8 @@ function mapTilesUpdateDebounce( return } + const eventName = Converters.eventNameString(event.name) + const key: KafkatorioPacketData.MapChunkUpdate["key"] = { surfaceIndex: surface.index, chunkPosition: chunkPosition, @@ -60,9 +73,9 @@ function mapTilesUpdateDebounce( } // events count update - data.eventCounts ??= {} - data.eventCounts[eventName] ??= 0 - data.eventCounts[eventName]++ + data.events ??= {} + data.events[eventName] ??= [] + data.events[eventName].push(event.tick) // apply mutator if (updater != undefined) { @@ -101,15 +114,15 @@ script.on_event( export function handleChunkGeneratedEvent( - e: OnChunkGeneratedEvent, + event: OnChunkGeneratedEvent, expirationDurationTicks?: uint, ) { - let tiles = getTiles(e.surface, e.area) + let tiles = getTiles(event.surface, event.area) mapTilesUpdateDebounce( - e.surface, - [e.position.x, e.position.y], + event.surface, + Converters.convertMapTablePosition(event.position), tiles, - Converters.eventNameString(e.name), + event, undefined, expirationDurationTicks, ) @@ -136,18 +149,18 @@ export function handleChunkGeneratedEvent( script.on_event( defines.events.script_raised_set_tiles, - (e: ScriptRaisedSetTilesEvent) => { - log(`script_raised_set_tiles ${e.tick}`) + (event: ScriptRaisedSetTilesEvent) => { + log(`script_raised_set_tiles ${event.tick}`) - const surface = getSurface(e.surface_index) + const surface = getSurface(event.surface_index) if (surface == undefined) { return } - const groupedTiles = groupTiles(e.tiles) + const groupedTiles = groupTiles(event.tiles) for (const [chunkPos, tiles] of groupedTiles) { - mapTilesUpdateDebounce(surface, chunkPos, tiles, Converters.eventNameString(e.name)) + mapTilesUpdateDebounce(surface, chunkPos, tiles, event) } } ) @@ -165,41 +178,35 @@ function groupTiles(tiles: TileRead[]): Map { mapChunkPositionToTiles.set(chunkPosition, []) } // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1256 - // mapChunkPositionToTiles.get(chunkPosition)?.push(tile) - const tiles = mapChunkPositionToTiles.get(chunkPosition) - if (tiles != null) { - tiles.push(tile) - } + mapChunkPositionToTiles.get(chunkPosition)?.push(tile) + // const tiles = mapChunkPositionToTiles.get(chunkPosition) + // if (tiles != null) { + // tiles.push(tile) + // } } return mapChunkPositionToTiles } -function convertOldPosition( - oldTiles: OldTileAndPosition[], - placedTile: LuaTilePrototype, -): TileRead[] { - - return oldTiles.map((tile) => { - return { - position: {x: tile.position.x, y: tile.position.y}, - name: placedTile.name, - } - } - ) -} - +script.on_event(defines.events.on_player_built_tile, (e: OnPlayerBuiltTileEvent) => { + log(`on_player_built_tile ${e.tick}`) + handleBuiltTileEvent(e) +}) +script.on_event(defines.events.on_robot_built_tile, (e: OnRobotBuiltTileEvent) => { + log(`on_robot_built_tile ${e.tick}`) + handleBuiltTileEvent(e) +}) function handleBuiltTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) { - const eventName = Converters.eventNameString(event.name) const surface = getSurface(event.surface_index) if (surface == undefined) { + const eventName = Converters.eventNameString(event.name) log(`[handleBuiltTileEvent] undefined surface ${eventName}`) return } - const tiles: TileRead[] = convertOldPosition(event.tiles, event.tile) + const tiles: TileRead[] = Converters.convertPlacedTiles(event.tile, event.tiles) const groupedTiles = groupTiles(tiles) for (const [chunkPos, tiles] of groupedTiles) { @@ -207,7 +214,7 @@ function handleBuiltTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEv surface, chunkPos, tiles, - eventName, + event, (data => { if (isEventType(event, defines.events.on_player_built_tile)) { data.player = event.player_index @@ -231,27 +238,54 @@ function handleBuiltTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEv } -script.on_event(defines.events.on_player_built_tile, (e: OnPlayerBuiltTileEvent) => { - log(`on_player_built_tile ${e.tick}`) - handleBuiltTileEvent(e) -}) -script.on_event(defines.events.on_robot_built_tile, (e: OnRobotBuiltTileEvent) => { - log(`on_robot_built_tile ${e.tick}`) - handleBuiltTileEvent(e) +script.on_event(defines.events.on_player_mined_tile, (e: OnPlayerMinedTileEvent) => { + log(`on_player_mined_tile ${e.tick}`) + handleMinedTileEvent(e) }) +script.on_event(defines.events.on_robot_mined_tile, (e: OnRobotMinedTileEvent) => { + log(`on_robot_mined_tile ${e.tick}`) + handleMinedTileEvent(e) +}) -// function handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) { -// } -// -// script.on_event(defines.events.on_player_mined_tile, (e: OnPlayerMinedTileEvent) => { -// log(`on_player_mined_tile ${e.tick}`) -// handleMinedTileEvent(e) -// }) -// script.on_event(defines.events.on_robot_mined_tile, (e: OnRobotMinedTileEvent) => { -// log(`on_robot_mined_tile ${e.tick}`) -// handleMinedTileEvent(e) -// }) +function handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) { + const surface = getSurface(event.surface_index) + if (surface == undefined) { + const eventName = Converters.eventNameString(event.name) + log(`[handleMinedTileEvent] undefined surface ${eventName}`) + return + } + + const tiles: TileRead[] = Converters.convertRemovedTiles(surface, event.tiles) + const groupedTiles = groupTiles(tiles) + + for (const [chunkPos, tiles] of groupedTiles) { + mapTilesUpdateDebounce( + surface, + chunkPos, + tiles, + event, + (data => { + if (isEventType(event, defines.events.on_player_mined_tile)) { + data.player = event.player_index + return + } + if (isEventType(event, defines.events.on_robot_mined_tile)) { + data.robot = { + unitNumber: event.robot?.unit_number ?? null, + name: event.robot.name, + protoType: event.robot.type, + } + return + } + // this line will not compile if the previous 'if' statements are not exhaustive + // noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols + const exhaustiveCheck: never = event + } + ) + ) + } +} script.on_event( diff --git a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts index bb69d2f..fc3f751 100644 --- a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts @@ -6,11 +6,29 @@ import Type = KafkatorioPacketData.Type; type PlayerUpdater = (player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) => void + +type PlayerUpdateEvent = + | OnPlayerJoinedGameEvent + | OnPlayerChangedPositionEvent + | OnPlayerChangedSurfaceEvent + | OnPlayerDiedEvent + | OnPlayerBannedEvent + | OnPlayerUnbannedEvent + | OnPlayerKickedEvent + | OnPrePlayerLeftGameEvent + | OnPlayerRemovedEvent + + function playerUpdateThrottle( - playerIndex: uint, - eventName: string, + event: PlayerUpdateEvent, mutate: PlayerUpdater, ) { + const playerIndex = event.player_index + if (playerIndex == undefined) { + return + } + + const eventName = Converters.eventNameString(event.name) EventUpdatesManager.throttle( {index: playerIndex}, @@ -21,10 +39,9 @@ function playerUpdateThrottle( mutate(player, data) } - if (data.eventCounts == undefined) { - data.eventCounts = {} - } - data.eventCounts[eventName] = ((data.eventCounts ?? {}) [eventName] ?? 0) + 1 + data.events ??= {} + data.events[eventName] ??= [] + data.events[eventName].push(event.tick) } ) } @@ -50,8 +67,7 @@ script.on_event( defines.events.on_player_joined_game, (e: OnPlayerJoinedGameEvent) => { playerUpdateThrottle( - e.player_index, - Converters.eventNameString(e.name), + e, (player, data) => { data.isAdmin = player.admin data.characterUnitNumber = player.character?.unit_number ?? null @@ -69,12 +85,12 @@ script.on_event( } ) + script.on_event( defines.events.on_player_changed_position, (e: OnPlayerChangedPositionEvent) => { playerUpdateThrottle( - e.player_index, - Converters.eventNameString(e.name), + e, (player, data) => { data.position = [player.position.x, player.position.y] } @@ -82,12 +98,12 @@ script.on_event( } ) + script.on_event( defines.events.on_player_changed_surface, (e: OnPlayerChangedSurfaceEvent) => { playerUpdateThrottle( - e.player_index, - Converters.eventNameString(e.name), + e, (player, data) => { data.position = [player.position.x, player.position.y] data.surfaceIndex = player.surface.index @@ -96,12 +112,12 @@ script.on_event( } ) + script.on_event( defines.events.on_player_died, (e: OnPlayerDiedEvent) => { playerUpdateThrottle( - e.player_index, - Converters.eventNameString(e.name), + e, (player, data) => { data.ticksToRespawn = player.ticks_to_respawn ?? null playerOnlineInfo(player, data) @@ -117,31 +133,28 @@ script.on_event( } ) + script.on_event(defines.events.on_player_banned, handleBannedEvent) script.on_event(defines.events.on_player_unbanned, handleBannedEvent) -function handleBannedEvent(e: OnPlayerBannedEvent | OnPlayerUnbannedEvent) { - - if (e.player_index != undefined) { - playerUpdateThrottle( - e.player_index, - Converters.eventNameString(e.name), - (player, data) => { - data.bannedReason = e.reason ?? null - playerOnlineInfo(player, data) - } - ) - } +function handleBannedEvent(event: OnPlayerBannedEvent | OnPlayerUnbannedEvent) { + playerUpdateThrottle( + event, + (player, data) => { + data.bannedReason = event.reason ?? null + playerOnlineInfo(player, data) + } + ) } + script.on_event( defines.events.on_player_kicked, - (e: OnPlayerKickedEvent) => { + (event: OnPlayerKickedEvent) => { playerUpdateThrottle( - e.player_index, - Converters.eventNameString(e.name), + event, (player, data) => { - data.kickedReason = e.reason ?? null + data.kickedReason = event.reason ?? null playerOnlineInfo(player, data) } ) @@ -156,12 +169,11 @@ for (const [name, disconnectId] of pairs(defines.disconnect_reason)) { script.on_event( defines.events.on_pre_player_left_game, - (e: OnPrePlayerLeftGameEvent) => { + (event: OnPrePlayerLeftGameEvent) => { playerUpdateThrottle( - e.player_index, - Converters.eventNameString(e.name), + event, (player, data) => { - data.disconnectReason = disconnectReasons.get(e.reason) + data.disconnectReason = disconnectReasons.get(event.reason) playerOnlineInfo(player, data) } ) @@ -170,10 +182,9 @@ script.on_event( script.on_event( defines.events.on_player_removed, - (e: OnPlayerRemovedEvent) => { + (event: OnPlayerRemovedEvent) => { playerUpdateThrottle( - e.player_index, - Converters.eventNameString(e.name), + event, (player, data) => { data.isRemoved = true playerOnlineInfo(player, data) diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index 815f196..6e418e5 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -31,25 +31,25 @@ import {handleSurfaceUpdate} from "./handlers"; script.on_event( defines.events.on_tick, - (e: OnTickEvent) => { - if (e.tick % 1000 == 0) { + (event: OnTickEvent) => { + if (event.tick % 1000 == 0) { for (const [, surface] of game.surfaces) { - handleSurfaceUpdate(e, Converters.eventNameString(e.name), surface) + handleSurfaceUpdate(event, Converters.eventNameString(event.name), surface) } } - if (e.tick % 7 == 0) { + if (event.tick % 7 == 0) { const events: EventData[] = Queue.dequeueValues(1) if (events.length > 0) { - log(`[${e.tick}] dequed ${events.length} events, current size: ${Queue.size()}`) + log(`[${event.tick}] dequed ${events.length} events, current size: ${Queue.size()}`) let i = 100 for (const event of events) { if (isEventType(event, defines.events.on_chunk_generated)) { let eName = Converters.eventNameString(event.name) - log(`[${e.tick}] dequed event ${eName}`) + log(`[${event.tick}] dequed event ${eName}`) handleChunkGeneratedEvent(event, i) i += 10 } diff --git a/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts b/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts index 1137513..299e04d 100644 --- a/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts +++ b/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts @@ -6,18 +6,18 @@ export class KafkatorioSettingsConfig { private static eventCacheExpirationDefaultSeconds: Record = { - "dev.adamko.kafkatorio.schema.packets.PlayerUpdate": 0.5, - "dev.adamko.kafkatorio.schema.packets.MapChunkUpdate": 30, - "dev.adamko.kafkatorio.schema.packets.EntityUpdate": 5, + "kafkatorio.packet.keyed.PlayerUpdate": 0.5, + "kafkatorio.packet.keyed.MapChunkUpdate": 30, + "kafkatorio.packet.keyed.EntityUpdate": 5, } private eventCacheExpirationTicks: Record = { - "dev.adamko.kafkatorio.schema.packets.PlayerUpdate": + "kafkatorio.packet.keyed.PlayerUpdate": KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.PlayerUpdate], - "dev.adamko.kafkatorio.schema.packets.MapChunkUpdate": + "kafkatorio.packet.keyed.MapChunkUpdate": KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.MapChunkUpdate], - "dev.adamko.kafkatorio.schema.packets.EntityUpdate": + "kafkatorio.packet.keyed.EntityUpdate": KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.EntityUpdate], } diff --git a/modules/events-mod/src/main/typescript/main/types.d.ts b/modules/events-mod/src/main/typescript/main/types.d.ts index 3259757..7505b54 100644 --- a/modules/events-mod/src/main/typescript/main/types.d.ts +++ b/modules/events-mod/src/main/typescript/main/types.d.ts @@ -24,3 +24,6 @@ type KafkatorioKeyedPacketData = Extract type KafkatorioKeyedPacketTypes = KafkatorioKeyedPacketData["type"]; type KafkatorioKeyedPacketKeys = KafkatorioKeyedPacketData["key"]; + + +type WithRequired = T & { [P in K]-?: T[P] } diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index 3b77285..876ae00 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -32,9 +32,9 @@ } }, "is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", "requires": { "has": "^1.0.3" } @@ -85,9 +85,9 @@ "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==" }, "typescript-to-lua": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.4.3.tgz", - "integrity": "sha512-oGJO1BqXKSxdfwavfOzthelxaQVAc7ykJ4Z/BF96nAWz35nmuLyv9FOSS132TgzLmV02859ndMuTYZtiVnN6jQ==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.4.4.tgz", + "integrity": "sha512-HqXDi0rjYANvVeOJlYAyjwCvLtpXV+RRp9GiknCJrd8+0D9G/2yZ5rO+LsDlY1y09sZ4xmufwsiZ6iNFm+o1GQ==", "requires": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index ea7c2fb..76c3ef4 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -9,16 +9,19 @@ "engines": { "node": "~14.19.1" }, - "devDependencies": {}, + "devDependencies": { + }, "dependencies": { "lua-types": "^2.11.0", - "typescript-to-lua": "1.4.3", + "typescript-to-lua": "1.4.4", "typed-factorio": "1.0.0", "typescript": "4.6.3" }, - "// @types/node": "^12.0.8", "license": "UNLICENSED", - "peerDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": [] + "peerDependencies": { + }, + "optionalDependencies": { + }, + "bundledDependencies": [ + ] } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt index a39baa0..a7b6b54 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt @@ -2,6 +2,7 @@ package dev.adamko.kafkatorio.schema.common import dev.adamko.kxstsgen.core.experiments.TupleSerializer import kotlin.math.roundToInt +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable /** @@ -11,6 +12,7 @@ import kotlinx.serialization.Serializable * All values here are optional. Colour channels default to `0`, the alpha channel defaults to `1`. */ @Serializable(with = Colour.Serializer::class) +@SerialName("kafkatorio.common.Colour") data class Colour( val red: Float = 0f, val green: Float = 0f, @@ -40,6 +42,7 @@ data class Colour( /** Size-efficient version of [Colour] (`4*4` bytes vs `4*1` bytes) */ @Serializable +@SerialName("kafkatorio.common.ColourHex") data class ColourHex( val red: UByte = UByte.MIN_VALUE, val green: UByte = UByte.MIN_VALUE, diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt index c632ee2..5f50aec 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt @@ -8,6 +8,8 @@ import kotlinx.serialization.Serializable @JvmInline value class Tick(val value: UInt) +val UInt.tick + get() = Tick(this) /** * Unique ID associated with this surface @@ -51,6 +53,13 @@ value class PrototypeName(private val id: String) { } +@Serializable +@JvmInline +value class EventName(private val name: String) { + override fun toString(): String = name +} + + interface EntityIdentifiers { val unitNumber: UnitNumber? val name: String diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt new file mode 100644 index 0000000..3a4a7dc --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt @@ -0,0 +1,27 @@ +package dev.adamko.kafkatorio.schema.common + +import kotlinx.serialization.Contextual +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + + +@Serializable +@SerialName("kafkatorio.prototype.FactorioPrototype") +sealed interface FactorioPrototype { + val name: PrototypeName + val mapColour: Colour + + @SerialName("kafkatorio.prototype.MapTile") + @Serializable + data class MapTile( + override val name: PrototypeName, + override val mapColour: Colour, + + val layer: UInt, + @Contextual + val collisionMasks: List, + val order: String, + /** Can the tile be mined for resources? */ + val canBeMined: Boolean, + ) : FactorioPrototype +} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt new file mode 100644 index 0000000..d637494 --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt @@ -0,0 +1,40 @@ +package dev.adamko.kafkatorio.schema.common + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + + +@Serializable +data class MinedProduct( + /** `item` or `fluid`. */ + val type: Type, + + /** Prototype name of the result. */ + @SerialName("name") + val resultPrototype: PrototypeName, + +//Amount of the item or fluid to give. If not specified, amount_min, amount_max and probability must all be specified. + val amount: Double?, + +//Minimal amount of the item or fluid to give. Has no effect when amount is specified. +//amount_min : Uint or double?, + +//Maximum amount of the item or fluid to give. Has no effect when amount is specified. +//amount_max : Uint or double?, + +//A value in range [0, 1]. Item or fluid is only given with this probability; otherwise no product is produced. +//probability : Double?, + +//How much of this product is a catalyst. +//catalyst_amount : Uint or double?, +) { + + @Serializable + enum class Type { + @SerialName("item") + ITEM, + @SerialName("fluid") + FLUID, + } + +} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt index fc08e8f..e1d52fb 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt @@ -1,10 +1,12 @@ package dev.adamko.kafkatorio.schema.packets import dev.adamko.kafkatorio.schema.common.Tick +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable +@SerialName("kafkatorio.packet.KafkatorioPacket") data class KafkatorioPacket( val modVersion: String, val tick: Tick, @@ -13,4 +15,5 @@ data class KafkatorioPacket( @Serializable +@SerialName("kafkatorio.packet.KafkatorioPacketData") sealed class KafkatorioPacketData diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt index f43ecec..b6af82e 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt @@ -1,13 +1,15 @@ package dev.adamko.kafkatorio.schema.packets +import dev.adamko.kafkatorio.schema.common.FactorioPrototype import dev.adamko.kafkatorio.schema.common.PlayerIndex import dev.adamko.kafkatorio.schema.common.SurfaceIndex -import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable /** No key, no caching. Must be sent instantly. */ @Serializable +@SerialName("kafkatorio.packet.KafkatorioPacket") sealed class KafkatorioInstantPacketData : KafkatorioPacketData() @@ -15,6 +17,7 @@ sealed class KafkatorioInstantPacketData : KafkatorioPacketData() @Serializable +@SerialName("kafkatorio.packet.instant.ConfigurationUpdate") data class ConfigurationUpdate( val factorioData: ConfigurationUpdateGameData, val allMods: List, @@ -23,12 +26,14 @@ data class ConfigurationUpdate( ) : KafkatorioInstantPacketData() { @Serializable + @SerialName("kafkatorio.packet.instant.ConfigurationUpdate.ConfigurationUpdateGameData") data class ConfigurationUpdateGameData( val oldVersion: String? = null, val newVersion: String? = null, ) @Serializable + @SerialName("kafkatorio.packet.instant.ConfigurationUpdate.ConfigurationUpdateModData") data class ConfigurationUpdateModData( val modName: String, val currentVersion: String? = null, @@ -38,6 +43,7 @@ data class ConfigurationUpdate( @Serializable +@SerialName("kafkatorio.packet.instant.ConsoleChatUpdate") data class ConsoleChatUpdate( val authorPlayerIndex: PlayerIndex?, val content: String, @@ -45,6 +51,7 @@ data class ConsoleChatUpdate( @Serializable +@SerialName("kafkatorio.packet.instant.ConsoleCommandUpdate") data class ConsoleCommandUpdate( val authorPlayerIndex: PlayerIndex?, val command: String, @@ -53,12 +60,14 @@ data class ConsoleCommandUpdate( @Serializable +@SerialName("kafkatorio.packet.instant.PrototypesUpdate") data class PrototypesUpdate( val prototypes: List, ) : KafkatorioInstantPacketData() @Serializable +@SerialName("kafkatorio.packet.instant.SurfaceUpdate") data class SurfaceUpdate( val index: SurfaceIndex, val daytime: Double, diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt index 6856725..8d93b8a 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt @@ -3,6 +3,7 @@ package dev.adamko.kafkatorio.schema.packets import dev.adamko.kafkatorio.schema.common.Colour import dev.adamko.kafkatorio.schema.common.EntityIdentifiers import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData +import dev.adamko.kafkatorio.schema.common.EventName import dev.adamko.kafkatorio.schema.common.ForceIndex import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapEntityPosition @@ -12,40 +13,46 @@ import dev.adamko.kafkatorio.schema.common.PrototypeName import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.common.UnitNumber +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable /** Has a key, so it can be debounced */ @Serializable +@SerialName("kafkatorio.packet.keyed.KafkatorioKeyedPacketData") sealed class KafkatorioKeyedPacketData : KafkatorioPacketData() { - /** Count how many events this packet is aggregating data from */ - abstract val key: KafkatorioKeyedPacketKey2 - abstract val eventCounts: Map? + abstract val key: KafkatorioKeyedPacketKey + /** A list of all events that have been aggregated into this packet. */ + abstract val events: Map>? } + @Serializable -sealed class KafkatorioKeyedPacketKey2 +@SerialName("kafkatorio.packet.keyed.KafkatorioKeyedPacketKey") +sealed class KafkatorioKeyedPacketKey /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ @Serializable +@SerialName("kafkatorio.packet.keyed.EntityUpdateKey") data class EntityUpdateKey( /** While normally optional, here a [unitNumber] is required for caching */ override val unitNumber: UnitNumber, override val name: String, override val protoType: String, -) : EntityIdentifiers, KafkatorioKeyedPacketKey2() +) : EntityIdentifiers, KafkatorioKeyedPacketKey() @Serializable +@SerialName("kafkatorio.packet.keyed.EntityUpdate") data class EntityUpdate( override val key: EntityUpdateKey, - override val eventCounts: Map? = null, + override val events: Map>? = null, - val chunkPosition: MapChunkPosition? = null, + val chunkPosition: MapEntityPosition? = null, val graphicsVariation: UByte? = null, val health: Float? = null, val isActive: Boolean? = null, @@ -61,17 +68,19 @@ data class EntityUpdate( @Serializable +@SerialName("kafkatorio.packet.keyed.MapChunkUpdateKey") data class MapChunkUpdateKey( val chunkPosition: MapChunkPosition, val surfaceIndex: SurfaceIndex, -) : KafkatorioKeyedPacketKey2() +) : KafkatorioKeyedPacketKey() @Serializable +@SerialName("kafkatorio.packet.keyed.MapChunkUpdate") data class MapChunkUpdate( override val key: MapChunkUpdateKey, - override val eventCounts: Map? = null, + override val events: Map>? = null, val player: PlayerIndex? = null, val robot: EntityIdentifiersData? = null, @@ -85,16 +94,18 @@ data class MapChunkUpdate( /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ @Serializable +@SerialName("kafkatorio.packet.keyed.PlayerUpdateKey") data class PlayerUpdateKey( val index: PlayerIndex, -) : KafkatorioKeyedPacketKey2() +) : KafkatorioKeyedPacketKey() @Serializable +@SerialName("kafkatorio.packet.keyed.PlayerUpdate") data class PlayerUpdate( override val key: PlayerUpdateKey, - override val eventCounts: Map? = null, + override val events: Map>? = null, val characterUnitNumber: UnitNumber? = null, val chatColour: Colour? = null, diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt deleted file mode 100644 index a09c06f..0000000 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/prototypes/factorioPrototypes.kt +++ /dev/null @@ -1,23 +0,0 @@ -package dev.adamko.kafkatorio.schema.prototypes - -import dev.adamko.kafkatorio.schema.common.Colour -import dev.adamko.kafkatorio.schema.common.PrototypeName -import kotlinx.serialization.Contextual -import kotlinx.serialization.Serializable - - -@Serializable -sealed class FactorioPrototype { - - @Serializable - data class MapTile( - val name: PrototypeName, - val layer: UInt, - val mapColour: Colour, - @Contextual - val collisionMasks: List, - val order: String, - /** Can the tile be mined for resources? */ - val canBeMined: Boolean, - ) : FactorioPrototype() -} diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt index 046127a..0039a91 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt @@ -1,10 +1,11 @@ package dev.adamko.kafkatorio.events.schema +import dev.adamko.kafkatorio.schema.common.EventName import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapTileDictionary import dev.adamko.kafkatorio.schema.common.PrototypeName import dev.adamko.kafkatorio.schema.common.SurfaceIndex -import dev.adamko.kafkatorio.schema.common.Tick +import dev.adamko.kafkatorio.schema.common.tick import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate @@ -20,7 +21,7 @@ class MapChunkUpdateTest : FunSpec({ val json = """ { "data": { - "type": "dev.adamko.kafkatorio.schema.packets.MapChunkUpdate", + "type": "kafkatorio.packet.keyed.MapChunkUpdate", "key": { "surfaceIndex": 1, "chunkPosition": [ @@ -46,8 +47,8 @@ class MapChunkUpdateTest : FunSpec({ "grass-3": 32 } }, - "eventCounts": { - "on_chunk_generated": 1 + "events": { + "on_chunk_generated": [1] } }, "modVersion": "0.4.0", @@ -56,14 +57,16 @@ class MapChunkUpdateTest : FunSpec({ """.trimIndent() val expected = KafkatorioPacket( - tick = Tick(36u), + tick = 36u.tick, modVersion = "0.4.0", data = MapChunkUpdate( key = MapChunkUpdateKey( MapChunkPosition(-6, -3), SurfaceIndex(1u), ), - eventCounts = mapOf("on_chunk_generated" to 1u), + events = mapOf( + EventName("on_chunk_generated") to listOf(1u.tick) + ), tileDictionary = MapTileDictionary( tilesXY = mapOf( "-192" to mapOf("-65" to MapTileDictionary.PrototypeKey(2)), diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt index cfb67a8..e4b4387 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt @@ -1,9 +1,9 @@ package dev.adamko.kafkatorio.events.schema import dev.adamko.kafkatorio.schema.common.Colour +import dev.adamko.kafkatorio.schema.common.FactorioPrototype import dev.adamko.kafkatorio.schema.common.PrototypeName import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio -import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import io.kotest.core.spec.style.BehaviorSpec @@ -20,10 +20,10 @@ class PrototypesTest : BehaviorSpec({ "modVersion": "0.2.4", "tick": 534, "data": { - "type": "dev.adamko.kafkatorio.schema.packets.PrototypesUpdate", + "type": "kafkatorio.packet.instant.PrototypesUpdate", "prototypes": [ { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "tile-unknown", "order": "z-a", "layer": 0, @@ -50,10 +50,10 @@ class PrototypesTest : BehaviorSpec({ "modVersion": "0.3.2", "tick": 534, "data": { - "type": "dev.adamko.kafkatorio.schema.packets.PrototypesUpdate", + "type": "kafkatorio.packet.instant.PrototypesUpdate", "prototypes": [ { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "stone-path", "order": "a[artificial]-a[tier-1]-a[stone-path]", "layer": 60, @@ -64,7 +64,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "concrete", "order": "a[artificial]-b[tier-2]-a[concrete]", "layer": 61, @@ -75,7 +75,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "hazard-concrete-left", "order": "a[artificial]-b[tier-2]-b[hazard-concrete-left]", "layer": 62, @@ -86,7 +86,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "hazard-concrete-right", "order": "a[artificial]-b[tier-2]-c[hazard-concrete-right]", "layer": 62, @@ -97,7 +97,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "refined-concrete", "order": "a[artificial]-c[tier-3]-a[refined-concrete]", "layer": 64, @@ -108,7 +108,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "refined-hazard-concrete-left", "order": "a[artificial]-c[tier-3]-b[refined-hazard-concrete-left]", "layer": 65, @@ -119,7 +119,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "refined-hazard-concrete-right", "order": "a[artificial]-c[tier-3]-c[refined-hazard-concrete-right]", "layer": 65, @@ -130,7 +130,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "landfill", "order": "a[artificial]-d[utility]-a[landfill]", "layer": 57, @@ -141,7 +141,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "acid-refined-concrete", "order": "a[artificial]-e[color-concrete]-acid", "layer": 97, @@ -152,7 +152,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "black-refined-concrete", "order": "a[artificial]-e[color-concrete]-black", "layer": 88, @@ -163,7 +163,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "blue-refined-concrete", "order": "a[artificial]-e[color-concrete]-blue", "layer": 73, @@ -174,7 +174,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "brown-refined-concrete", "order": "a[artificial]-e[color-concrete]-brown", "layer": 91, @@ -185,7 +185,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "cyan-refined-concrete", "order": "a[artificial]-e[color-concrete]-cyan", "layer": 94, @@ -196,7 +196,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "green-refined-concrete", "order": "a[artificial]-e[color-concrete]-green", "layer": 70, @@ -207,7 +207,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "orange-refined-concrete", "order": "a[artificial]-e[color-concrete]-orange", "layer": 76, @@ -218,7 +218,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "pink-refined-concrete", "order": "a[artificial]-e[color-concrete]-pink", "layer": 82, @@ -229,7 +229,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "purple-refined-concrete", "order": "a[artificial]-e[color-concrete]-purple", "layer": 85, @@ -240,7 +240,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "red-refined-concrete", "order": "a[artificial]-e[color-concrete]-red", "layer": 67, @@ -251,7 +251,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "yellow-refined-concrete", "order": "a[artificial]-e[color-concrete]-yellow", "layer": 79, @@ -262,7 +262,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "grass-1", "order": "b[natural]-a[grass]-a[grass-1]", "layer": 26, @@ -273,7 +273,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "grass-2", "order": "b[natural]-a[grass]-b[grass-2]", "layer": 28, @@ -284,7 +284,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "grass-3", "order": "b[natural]-a[grass]-c[grass-3]", "layer": 29, @@ -295,7 +295,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "grass-4", "order": "b[natural]-a[grass]-d[grass-4]", "layer": 30, @@ -306,7 +306,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "dry-dirt", "order": "b[natural]-b[dirt]-a[dry-dirt]", "layer": 18, @@ -317,7 +317,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "dirt-1", "order": "b[natural]-b[dirt]-b[dirt-1]", "layer": 19, @@ -328,7 +328,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "dirt-2", "order": "b[natural]-b[dirt]-c[dirt-2]", "layer": 20, @@ -339,7 +339,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "dirt-3", "order": "b[natural]-b[dirt]-d[dirt-3]", "layer": 21, @@ -350,7 +350,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "dirt-4", "order": "b[natural]-b[dirt]-e[dirt-4]", "layer": 22, @@ -361,7 +361,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "dirt-5", "order": "b[natural]-b[dirt]-f[dirt-5]", "layer": 23, @@ -372,7 +372,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "dirt-6", "order": "b[natural]-b[dirt]-g[dirt-6]", "layer": 24, @@ -383,7 +383,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "dirt-7", "order": "b[natural]-b[dirt]-h[dirt-7]", "layer": 25, @@ -394,7 +394,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "sand-1", "order": "b[natural]-c[sand]-a[sand-1]", "layer": 8, @@ -405,7 +405,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "sand-2", "order": "b[natural]-c[sand]-b[sand-2]", "layer": 9, @@ -416,7 +416,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "sand-3", "order": "b[natural]-c[sand]-c[sand-3]", "layer": 10, @@ -427,7 +427,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "red-desert-0", "order": "b[natural]-d[red-desert]-a[red-desert-0]", "layer": 31, @@ -438,7 +438,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "red-desert-1", "order": "b[natural]-d[red-desert]-b[red-desert-1]", "layer": 14, @@ -449,7 +449,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "red-desert-2", "order": "b[natural]-d[red-desert]-c[red-desert-2]", "layer": 15, @@ -460,7 +460,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "red-desert-3", "order": "b[natural]-d[red-desert]-d[red-desert-3]", "layer": 16, @@ -471,7 +471,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "water", "order": "c[water]-a[water]", "layer": 3, @@ -486,7 +486,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "deepwater", "order": "c[water]-b[deep-water]", "layer": 3, @@ -501,7 +501,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "water-green", "order": "c[water]-c[water-green]", "layer": 3, @@ -516,7 +516,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "deepwater-green", "order": "c[water]-d[deepwater-green]", "layer": 3, @@ -531,7 +531,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "water-shallow", "order": "c[water]-e[water-shallow]", "layer": 6, @@ -545,7 +545,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "water-mud", "order": "c[water]-g[water-mud]", "layer": 7, @@ -559,7 +559,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "nuclear-ground", "order": "d[destruction]-a[nuclear]-a[nuclear-ground]", "layer": 33, @@ -570,7 +570,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "water-wube", "order": "x[wube]-a[water-wube]", "layer": 2, @@ -585,7 +585,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "tile-unknown", "order": "z-a", "layer": 0, @@ -595,7 +595,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "out-of-map", "order": "z[other]-a[out-of-map]", "layer": 0, @@ -613,7 +613,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "lab-dark-1", "order": "z[other]-b[lab]-a[lab-dark-1]", "layer": 70, @@ -624,7 +624,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "lab-dark-2", "order": "z[other]-b[lab]-b[lab-dark-2]", "layer": 70, @@ -635,7 +635,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "lab-white", "order": "z[other]-b[lab]-c[lab-white]", "layer": 70, @@ -646,7 +646,7 @@ class PrototypesTest : BehaviorSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "tutorial-grid", "order": "z[other]-c[tutorial]-a[tutorial-grid]", "layer": 55, diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt index 742b234..787c75d 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt @@ -2,13 +2,16 @@ package dev.adamko.kafkatorio.events.schema import dev.adamko.kafkatorio.schema.common.Colour import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData +import dev.adamko.kafkatorio.schema.common.EventName import dev.adamko.kafkatorio.schema.common.ForceIndex import dev.adamko.kafkatorio.schema.common.MapEntityPosition import dev.adamko.kafkatorio.schema.common.PlayerIndex import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.common.UnitNumber +import dev.adamko.kafkatorio.schema.common.tick import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio +import dev.adamko.kafkatorio.schema.packets.KafkatorioKeyedPacketData import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.schema.packets.PlayerUpdateKey @@ -27,14 +30,14 @@ class UpdatePacketsTest : FunSpec({ "tick": 66, "modVersion": "0.3.2", "data": { - "type": "dev.adamko.kafkatorio.schema.packets.PlayerUpdate", + "type": "kafkatorio.packet.keyed.PlayerUpdate", "key": {"index": 1}, "afkTime": 0, "chatColour": [1, 0.4, 0.6, 1], "colour": [0.8, 0.5, 0.2, 0.5], - "eventCounts": { - "on_player_changed_position": 7, - "on_player_joined_game": 1 + "events": { + "on_player_changed_position": [7, 99], + "on_player_joined_game": [14] }, "forceIndex": 1, "isAdmin": true, @@ -68,7 +71,10 @@ class UpdatePacketsTest : FunSpec({ colour = Colour(red = 0.8f, green = 0.5f, blue = 0.2f, alpha = 0.5f), diedCause = null, disconnectReason = null, - eventCounts = mapOf("on_player_changed_position" to 7u, "on_player_joined_game" to 1u), + events = mapOf( + EventName("on_player_changed_position") to listOf(7u.tick, 99u.tick), + EventName("on_player_joined_game") to listOf(14u.tick), + ), forceIndex = ForceIndex(1u), isAdmin = true, isConnected = true, @@ -124,7 +130,7 @@ class UpdatePacketsTest : FunSpec({ "modVersion": "0.3.2", "tick": 66, "data": { - "type": "dev.adamko.kafkatorio.schema.packets.PlayerUpdate", + "type": "kafkatorio.packet.keyed.PlayerUpdate", "key": { "index": 1 }, @@ -151,7 +157,7 @@ class UpdatePacketsTest : FunSpec({ "tick": 227934, "modVersion": "0.3.2", "data": { - "type": "dev.adamko.kafkatorio.schema.packets.PlayerUpdate", + "type": "kafkatorio.packet.keyed.PlayerUpdate", "key": { "index": 1 }, @@ -164,8 +170,8 @@ class UpdatePacketsTest : FunSpec({ "name": "small-biter", "protoType": "unit" }, - "eventCounts": { - "on_player_died": 2 + "events": { + "on_player_died": [2] } } } @@ -176,9 +182,9 @@ class UpdatePacketsTest : FunSpec({ packet shouldBe KafkatorioPacket( modVersion = "0.3.2", - tick = Tick(227934u), + tick = 227934u.tick, data = PlayerUpdate( - afkTime = Tick(324u), + afkTime = 324u.tick, bannedReason = null, characterUnitNumber = null, chatColour = null, @@ -189,7 +195,9 @@ class UpdatePacketsTest : FunSpec({ protoType = "unit", ), disconnectReason = null, - eventCounts = mapOf("on_player_died" to 2u), + events = mapOf( + EventName("on_player_died") to listOf(2u.tick), + ), forceIndex = null, key = PlayerUpdateKey(PlayerIndex(1u)), isAdmin = null, @@ -198,9 +206,9 @@ class UpdatePacketsTest : FunSpec({ isShowOnMap = null, isSpectator = null, kickedReason = null, - lastOnline = Tick(227932u), + lastOnline = 227932u.tick, name = null, - onlineTime = Tick(227888u), + onlineTime = 227888u.tick, position = null, surfaceIndex = null, tag = null, @@ -215,7 +223,7 @@ class UpdatePacketsTest : FunSpec({ val json = """ { "data": { - "type": "dev.adamko.kafkatorio.schema.packets.SurfaceUpdate", + "type": "kafkatorio.packet.instant.SurfaceUpdate", "name": "nauvis", "index": 1, "daytime": 0.73 diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt new file mode 100644 index 0000000..7ab5c32 --- /dev/null +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt @@ -0,0 +1,50 @@ +package dev.adamko.kafkatorio.schema.packets + +import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.types.shouldBeInstanceOf +import kotlinx.serialization.decodeFromString + +class EntityUpdateTest : FunSpec({ + + context("EntityUpdate packet") { + /*language=json*/ + val json = """ + { + "data": { + "type": "kafkatorio.packet.keyed.EntityUpdate", + "key": { + "name": "assembling-machine-2", + "protoType": "assembling-machine-2", + "unitNumber": 4622 + }, + "events": { + "on_built_entity": [ + 38023 + ] + }, + "chunkPosition": [ + -13.5, + 4.5 + ], + "health": 350, + "isActive": true, + "isRotatable": true, + "lastUser": 1, + "prototype": "assembling-machine-2" + }, + "modVersion": "0.4.0", + "tick": 38388 + } + """.trimIndent() + test("decode") { + val entityUpdate: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json) + entityUpdate.data + .shouldBeInstanceOf() + +// entityUpdate.health.shouldNotBeNull().shouldBeExactly(350f) + } + + } + +}) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index 7514753..19d0fba 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -2,10 +2,10 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.FactorioPrototype import dev.adamko.kafkatorio.schema.common.MapTile import dev.adamko.kafkatorio.schema.common.toHex import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate -import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.repartitionedAs import dev.adamko.kotka.extensions.streams.filter diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt index 53dd5b4..c2ad3bf 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt @@ -17,7 +17,7 @@ import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate import dev.adamko.kafkatorio.schema.packets.MapChunkUpdateKey import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate -import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype +import dev.adamko.kafkatorio.schema.common.FactorioPrototype import dev.adamko.kotka.kxs.serde import io.kotest.assertions.withClue import io.kotest.core.spec.style.FunSpec @@ -289,7 +289,7 @@ class GroupMapChunksTest : FunSpec({ "modVersion": "0.4.0", "tick": 36, "data": { - "type": "dev.adamko.kafkatorio.schema.packets.MapChunkUpdate", + "type": "kafkatorio.packet.keyed.MapChunkUpdate", "key": { "chunkPosition": [ -7, @@ -297,8 +297,8 @@ class GroupMapChunksTest : FunSpec({ ], "surfaceIndex": 1 }, - "eventCounts": { - "on_chunk_generated": 1 + "events": { + "on_chunk_generated": [1] }, "tileDictionary": { "tilesXY": { @@ -1407,10 +1407,10 @@ class GroupMapChunksTest : FunSpec({ "modVersion": "0.4.0", "tick": 4352, "data": { - "type": "dev.adamko.kafkatorio.schema.packets.PrototypesUpdate", + "type": "kafkatorio.packet.instant.PrototypesUpdate", "prototypes": [ { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "stone-path", "layer": 60, "mapColour": [ @@ -1426,7 +1426,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "concrete", "layer": 61, "mapColour": [ @@ -1442,7 +1442,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "hazard-concrete-left", "layer": 62, "mapColour": [ @@ -1458,7 +1458,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "hazard-concrete-right", "layer": 62, "mapColour": [ @@ -1474,7 +1474,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "refined-concrete", "layer": 64, "mapColour": [ @@ -1490,7 +1490,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "refined-hazard-concrete-left", "layer": 65, "mapColour": [ @@ -1506,7 +1506,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "refined-hazard-concrete-right", "layer": 65, "mapColour": [ @@ -1522,7 +1522,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": true }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "landfill", "layer": 57, "mapColour": [ @@ -1538,7 +1538,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "acid-refined-concrete", "layer": 97, "mapColour": [ @@ -1554,7 +1554,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "black-refined-concrete", "layer": 88, "mapColour": [ @@ -1570,7 +1570,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "blue-refined-concrete", "layer": 73, "mapColour": [ @@ -1586,7 +1586,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "brown-refined-concrete", "layer": 91, "mapColour": [ @@ -1602,7 +1602,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "cyan-refined-concrete", "layer": 94, "mapColour": [ @@ -1618,7 +1618,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "green-refined-concrete", "layer": 70, "mapColour": [ @@ -1634,7 +1634,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "orange-refined-concrete", "layer": 76, "mapColour": [ @@ -1650,7 +1650,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "pink-refined-concrete", "layer": 82, "mapColour": [ @@ -1666,7 +1666,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "purple-refined-concrete", "layer": 85, "mapColour": [ @@ -1682,7 +1682,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "red-refined-concrete", "layer": 67, "mapColour": [ @@ -1698,7 +1698,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "yellow-refined-concrete", "layer": 79, "mapColour": [ @@ -1714,7 +1714,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "grass-1", "layer": 26, "mapColour": [ @@ -1730,7 +1730,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "grass-2", "layer": 28, "mapColour": [ @@ -1746,7 +1746,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "grass-3", "layer": 29, "mapColour": [ @@ -1762,7 +1762,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "grass-4", "layer": 30, "mapColour": [ @@ -1778,7 +1778,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "dry-dirt", "layer": 18, "mapColour": [ @@ -1794,7 +1794,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "dirt-1", "layer": 19, "mapColour": [ @@ -1810,7 +1810,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "dirt-2", "layer": 20, "mapColour": [ @@ -1826,7 +1826,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "dirt-3", "layer": 21, "mapColour": [ @@ -1842,7 +1842,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "dirt-4", "layer": 22, "mapColour": [ @@ -1858,7 +1858,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "dirt-5", "layer": 23, "mapColour": [ @@ -1874,7 +1874,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "dirt-6", "layer": 24, "mapColour": [ @@ -1890,7 +1890,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "dirt-7", "layer": 25, "mapColour": [ @@ -1906,7 +1906,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "sand-1", "layer": 8, "mapColour": [ @@ -1922,7 +1922,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "sand-2", "layer": 9, "mapColour": [ @@ -1938,7 +1938,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "sand-3", "layer": 10, "mapColour": [ @@ -1954,7 +1954,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "red-desert-0", "layer": 31, "mapColour": [ @@ -1970,7 +1970,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "red-desert-1", "layer": 14, "mapColour": [ @@ -1986,7 +1986,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "red-desert-2", "layer": 15, "mapColour": [ @@ -2002,7 +2002,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "red-desert-3", "layer": 16, "mapColour": [ @@ -2018,7 +2018,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "water", "layer": 3, "mapColour": [ @@ -2038,7 +2038,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "deepwater", "layer": 3, "mapColour": [ @@ -2058,7 +2058,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "water-green", "layer": 3, "mapColour": [ @@ -2078,7 +2078,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "deepwater-green", "layer": 3, "mapColour": [ @@ -2098,7 +2098,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "water-shallow", "layer": 6, "mapColour": [ @@ -2117,7 +2117,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "water-mud", "layer": 7, "mapColour": [ @@ -2136,7 +2136,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "nuclear-ground", "layer": 33, "mapColour": [ @@ -2152,7 +2152,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "water-wube", "layer": 2, "mapColour": [ @@ -2172,7 +2172,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "tile-unknown", "layer": 0, "mapColour": [ @@ -2186,7 +2186,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "out-of-map", "layer": 0, "mapColour": [ @@ -2209,7 +2209,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "lab-dark-1", "layer": 70, "mapColour": [ @@ -2225,7 +2225,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "lab-dark-2", "layer": 70, "mapColour": [ @@ -2241,7 +2241,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "lab-white", "layer": 70, "mapColour": [ @@ -2257,7 +2257,7 @@ class GroupMapChunksTest : FunSpec({ "canBeMined": false }, { - "type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile", + "type": "kafkatorio.prototype.MapTile", "name": "tutorial-grid", "layer": 55, "mapColour": [ diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt index 9ca2067..94ebdc0 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt @@ -35,7 +35,6 @@ class SaveMapChunksTest : FunSpec({ test("save tile") { - Scenario().use { scenario -> val chunkTilesArb = serverMapChunkTilesArb(scenario.serverId) @@ -79,7 +78,7 @@ class SaveMapChunksTest : FunSpec({ Path("build/test/save-map-chunks-${now}") } private val topology = saveMapTiles(streamsBuilder, outputDir) - val testDriver: TopologyTestDriver = TopologyTestDriver(topology) + private val testDriver: TopologyTestDriver = TopologyTestDriver(topology) val groupedMapChunksInputTopic: TestInputTopic> = testDriver.createInputTopic( @@ -99,21 +98,14 @@ class SaveMapChunksTest : FunSpec({ companion object { - fun mapTilePositionArb( - xArb: Arb = Arb.int(), - yArb: Arb = Arb.int(), - ): Arb = arbitrary { - MapTilePosition(xArb.bind(), yArb.bind()) - } - - fun mapChunkPositionArb( + private fun mapChunkPositionArb( xArb: Arb = Arb.int(-10..10), yArb: Arb = Arb.int(-10..10), ): Arb = arbitrary { MapChunkPosition(xArb.bind(), yArb.bind()) } - fun colourHexArb( + private fun colourHexArb( redArb: Arb = Arb.uByte(), greenArb: Arb = Arb.uByte(), blueArb: Arb = Arb.uByte(), @@ -123,18 +115,11 @@ class SaveMapChunksTest : FunSpec({ redArb.bind(), greenArb.bind(), blueArb.bind(), -// alphaArb.bind(), - 255u, + alphaArb.bind(), ) -// ColourHex( -// 255u, -// 0u, -// 0u, -// 255u, -// ) } - fun serverMapChunkIdArb( + private fun serverMapChunkIdArb( serverId: FactorioServerId, chunkPosition: Arb = mapChunkPositionArb(), surfaceIndex: SurfaceIndex = SurfaceIndex(1u), @@ -148,7 +133,7 @@ class SaveMapChunksTest : FunSpec({ ) } - fun tilesInChunkArb( + private fun tilesInChunkArb( chunkId: ServerMapChunkId ): Arb> = arbitrary { From 4cb7d0e1f39018eb1ea15c9e257302754f8840c1 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 7 May 2022 20:29:39 +0200 Subject: [PATCH 322/629] add entity prototype --- .../schema/common/factorioPrototypes.kt | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt index 3a4a7dc..49f8370 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt @@ -24,4 +24,29 @@ sealed interface FactorioPrototype { /** Can the tile be mined for resources? */ val canBeMined: Boolean, ) : FactorioPrototype + + + @SerialName("kafkatorio.prototype.Entity") + @Serializable + data class Entity( + override val name: PrototypeName, + override val mapColour: Colour, + + val type: String, + val objectName: String, + val colour: Colour, + val maxHealth: Float, + val isBuilding: Boolean, + val isEntityWithOwner: Boolean, + val isMilitaryTarget: Boolean, + val miningProperties: MiningProperties + ) : FactorioPrototype { + + @Serializable + data class MiningProperties( + val canBeMined: Boolean, + val products: List?, + ) + + } } From 5a000b9327720f874d22aa5d4da12f13b25064c5 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 7 May 2022 23:02:18 +0200 Subject: [PATCH 323/629] fix entity position type, fix Entity proto property name clash, and update ts-schema --- .../kafkatorio-schema/kafkatorio-schema.ts | 54 +++++++++++++++---- .../schema/common/factorioPrototypes.kt | 2 +- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts index 54893f8..1037ced 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts @@ -67,7 +67,7 @@ export namespace KafkatorioPacketData { type: KafkatorioPacketData.Type.EntityUpdate; key: EntityUpdateKey; events?: { [key: EventName]: Tick[] } | null; - chunkPosition?: MapChunkPosition | null; + chunkPosition?: MapEntityPosition | null; graphicsVariation?: UByte | null; health?: Float | null; isActive?: boolean | null; @@ -136,9 +136,9 @@ export interface EntityUpdateKey { protoType: string; } -export type MapChunkPosition = [ - x: Int, - y: Int, +export type MapEntityPosition = [ + x: Double, + y: Double, ]; export type UByte = uint8; @@ -178,11 +178,6 @@ export type Colour = [ alpha: Float, ]; -export type MapEntityPosition = [ - x: Double, - y: Double, -]; - export type Int = int; export interface ConfigurationUpdateModData { @@ -192,28 +187,65 @@ export interface ConfigurationUpdateModData { } export type FactorioPrototype = + | FactorioPrototype.Entity | FactorioPrototype.MapTile; export namespace FactorioPrototype { export enum Type { MapTile = "kafkatorio.prototype.MapTile", + Entity = "kafkatorio.prototype.Entity", } export interface MapTile { type: FactorioPrototype.Type.MapTile; name: PrototypeName; - layer: UInt; mapColour: Colour; + layer: UInt; collisionMasks: List; order: string; canBeMined: boolean; } + + export interface Entity { + type: FactorioPrototype.Type.Entity; + name: PrototypeName; + mapColour: Colour; + protoType: string; + objectName: string; + colour: Colour; + maxHealth: Float; + isBuilding: boolean; + isEntityWithOwner: boolean; + isMilitaryTarget: boolean; + miningProperties: MiningProperties; + } } export type EventName = string; export type Byte = int8; +export type MapChunkPosition = [ + x: Int, + y: Int, +]; + export type List = any; -export type PrototypeKey = Int; \ No newline at end of file +export interface MiningProperties { + canBeMined: boolean; + products: MinedProduct[] | null; +} + +export type PrototypeKey = Int; + +export interface MinedProduct { + type: Type; + name: PrototypeName; + amount: Double | null; +} + +export enum Type { + item = "item", + fluid = "fluid", +} \ No newline at end of file diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt index 49f8370..5f08e0c 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt @@ -32,7 +32,7 @@ sealed interface FactorioPrototype { override val name: PrototypeName, override val mapColour: Colour, - val type: String, + val protoType: String, val objectName: String, val colour: Colour, val maxHealth: Float, From 436b7ba1d493305327ec51eeaf3b083aa1eb32c1 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 7 May 2022 23:02:51 +0200 Subject: [PATCH 324/629] fix map chunk update prototype clash --- .../main/events/onMapChunkEventListeners.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts index 9f07508..858772a 100644 --- a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts @@ -56,19 +56,16 @@ function mapTilesUpdateDebounce( } } - let protosCount: uint = 0 + let protosCount: uint = table_size(data.tileDictionary.protos) for (const tile of tiles) { - if (data.tileDictionary.protos[tile.name] == undefined) { - data.tileDictionary.protos[tile.name] = protosCount++ - } + data.tileDictionary.protos[tile.name] ??= protosCount++ + const protoKey = data.tileDictionary.protos[tile.name] const xString = `${tile.position.x}` const yString = `${tile.position.y}` - if (data.tileDictionary.tilesXY[xString] == undefined) { - data.tileDictionary.tilesXY[xString] = {} - } + data.tileDictionary.tilesXY[xString] ??= {} data.tileDictionary.tilesXY[xString][yString] = protoKey } From 85ccb87171533717f884ba76e0f189735d0ea6df Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 7 May 2022 23:03:19 +0200 Subject: [PATCH 325/629] try fixing Gradle NPE on projectTokens --- modules/events-mod/build.gradle.kts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index b6d4976..a9b4ade 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -127,6 +127,15 @@ distributions { } } + +tasks.withType().configureEach { + inputs.property("projectTokens", projectTokens) +// if (name.startsWith("dist")) { +// notCompatibleWithConfigurationCache("NPE on projectTokens") +// } +} + + //val downloadFactorioApiDocs by tasks.registering { // group = project.name // From 93444bfe39d3676e3870a18eeeaeef6b60ff9c10 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 7 May 2022 23:03:43 +0200 Subject: [PATCH 326/629] try adding tstl language server plugin (I don't think IntelliJ understands it though) --- modules/events-mod/src/main/typescript/tsconfig.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/events-mod/src/main/typescript/tsconfig.json b/modules/events-mod/src/main/typescript/tsconfig.json index e7fb1ff..5587793 100644 --- a/modules/events-mod/src/main/typescript/tsconfig.json +++ b/modules/events-mod/src/main/typescript/tsconfig.json @@ -12,6 +12,11 @@ "lua-types/5.2", "typed-factorio/runtime" ], + "plugins": [ + { + "name": "typescript-tstl-plugin" + } + ], "allowSyntheticDefaultImports": true, "esModuleInterop": true, "explainFiles": true, From ffe9bcb9a88162526e8d67db0337641f00da0f45 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 12:22:47 +0200 Subject: [PATCH 327/629] bump versions - kotlinx js wrappers - kotest also fix kotest dependencies --- gradle/libs.versions.toml | 11 ++- .../common/MapChunkPositionBoundsTest.kt | 98 +++++++++++++++++++ .../schema/common/MapChunkPositionTest.kt | 81 +++++++++++++++ .../schema/common/MapTilePositionTest.kt | 43 ++++++++ 4 files changed, 228 insertions(+), 5 deletions(-) create mode 100644 modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt create mode 100644 modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionTest.kt create mode 100644 modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTilePositionTest.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c112b5e..e8d0aab 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,8 @@ scrimage = "4.0.31" kotlinx-serialization = "1.3.2" kxs-yaml = "0.43.0" -kotlinJsWrappers = "0.0.1-pre.331-kotlin-1.6.20" +#kotlinJsWrappers = "0.0.1-pre.331-kotlin-1.6.20" +kotlinJsWrappers = "0.0.1-pre.334" kotlinx-html = "0.7.5" kotlinx-nodejs = "0.0.7" kotlinx-coroutines = "1.6.1" @@ -32,7 +33,7 @@ ktor = "2.0.1" ## test ## junit = "5.8.2" -kotest = "5.2.3" +kotest = "5.3.0" ## infra ## factorio = "1.1.57" @@ -144,10 +145,10 @@ junit-launcher = { group = "org.junit.platform", name = "junit-platform-launcher ## kotest ## kotest-bom = { group = "io.kotest", name = "kotest-bom", version.ref = "kotest" } -kotest-core = { group = "io.kotest", name = "kotest-assertions-core-jvm", version.ref = "kotest" } +kotest-core = { group = "io.kotest", name = "kotest-assertions-core", version.ref = "kotest" } kotest-datatest = { group = "io.kotest", name = "kotest-framework-datatest", version.ref = "kotest" } -kotest-runner = { group = "io.kotest", name = "kotest-runner-junit5-jvm", version.ref = "kotest" } -kotest-prop = { group = "io.kotest", name = "kotest-property-jvm", version.ref = "kotest" } +kotest-runner = { group = "io.kotest", name = "kotest-runner-junit5", version.ref = "kotest" } +kotest-prop = { group = "io.kotest", name = "kotest-property", version.ref = "kotest" } kotest-json = { group = "io.kotest", name = "kotest-assertions-json", version.ref = "kotest" } ## http4k ## diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt new file mode 100644 index 0000000..6a2a044 --- /dev/null +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt @@ -0,0 +1,98 @@ +package dev.adamko.kafkatorio.schema.common + +import io.kotest.assertions.asClue +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.ints.shouldBeExactly + +class MapChunkPositionBoundsTest : FunSpec({ + + context("create bounds") { + + context("MapChunkPosition(0, 0)") { + + context("chunk size 32") { + + val chunkPos = MapChunkPosition(0, 0) + val bounds = MapChunkPositionBounds(chunkPos, ChunkSize.CHUNK_032) + + test("leftTop should be 0,0") { + bounds.leftTop.asClue { + it.x shouldBeExactly 0 + it.y shouldBeExactly 0 + } + } + + test("rightBottom should be 31,31") { + bounds.rightBottom.asClue { + it.x shouldBeExactly 31 + it.y shouldBeExactly 31 + } + } + } + } + + context("chunk size 256") { + + val chunkPos = MapChunkPosition(0, 0) + val bounds = MapChunkPositionBounds(chunkPos, ChunkSize.CHUNK_256) + + test("leftTop should be 0,0") { + bounds.leftTop.asClue { + it.x shouldBeExactly 0 + it.y shouldBeExactly 0 + } + } + + test("rightBottom should be 255,255") { + bounds.rightBottom.asClue { + it.x shouldBeExactly 255 + it.y shouldBeExactly 255 + } + } + } + } + + context("MapChunkPosition(-10, -10)") { + + context("chunk size 32") { + + val chunkPos = MapChunkPosition(-10, -10) + val bounds = MapChunkPositionBounds(chunkPos, ChunkSize.CHUNK_032) + + test("leftTop should be -320,-320") { + bounds.leftTop.asClue { + it.x shouldBeExactly -320 + it.y shouldBeExactly -320 + } + } + + test("rightBottom should be -289,-289") { + bounds.rightBottom.asClue { + it.x shouldBeExactly -289 + it.y shouldBeExactly -289 + } + } + } + + context("chunk size 256") { + + val chunkPos = MapChunkPosition(-10, -10) + val bounds = MapChunkPositionBounds(chunkPos, ChunkSize.CHUNK_256) + + test("leftTop should be -2560") { + bounds.leftTop.asClue { + it.x shouldBeExactly -2560 + it.y shouldBeExactly -2560 + } + } + + test("rightBottom should be (-2560 + 255)") { + bounds.rightBottom.asClue { + it.x shouldBeExactly (-2560 + 255) + it.y shouldBeExactly (-2560 + 255) + } + } + } + } + +}) diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionTest.kt new file mode 100644 index 0000000..99cfdc7 --- /dev/null +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionTest.kt @@ -0,0 +1,81 @@ +package dev.adamko.kafkatorio.schema.common + +import io.kotest.core.spec.style.FunSpec +import io.kotest.datatest.withData +import io.kotest.matchers.shouldBe +import io.kotest.property.Arb +import io.kotest.property.arbitrary.arbitrary +import io.kotest.property.arbitrary.int +import io.kotest.property.checkAll + +class MapChunkPositionTest : FunSpec({ + + context("check MapChunkPosition.contains()") { + + context("MapChunkPosition(0, 0)") { + + val chunkPos = MapChunkPosition(0, 0) + + test("should contain tiles from (0,0) to (31,31)") { + checkAll(mapTilePositionArb(0..31)) { tilePos -> + (tilePos in chunkPos) shouldBe true + } + } + + test("should not contain tiles below (0,0)") { + checkAll( + mapTilePositionArb(-1000..-1) + ) { tilePos -> + (tilePos in chunkPos) shouldBe false + } + } + + test("should not contain tiles above (31,31)") { + checkAll( + mapTilePositionArb(32..100) + ) { tilePos -> + (tilePos in chunkPos) shouldBe false + } + } + } + context("MapChunkPosition(-10, -10)") { + + val chunkPos = MapChunkPosition(-10, -10) + + test("should contain tiles from (-320,-320) to (-289,-289)") { + checkAll(mapTilePositionArb(-320..-289)) { tilePos -> + (tilePos in chunkPos) shouldBe true + } + } + + test("should not contain tiles below (-320,-320)") { + checkAll( + mapTilePositionArb(-400..-321) + ) { tilePos -> + (tilePos in chunkPos) shouldBe false + } + } + + test("should not contain tiles above (-289,-289)") { + checkAll( + mapTilePositionArb(-288..100) + ) { tilePos -> + (tilePos in chunkPos) shouldBe false + } + } + } + } + + +}) { + companion object { + fun mapTilePositionArb( + range: IntRange = -1000..1000 + ) = arbitrary { + MapTilePosition( + Arb.int(range).bind(), + Arb.int(range).bind(), + ) + } + } +} diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTilePositionTest.kt b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTilePositionTest.kt new file mode 100644 index 0000000..15dfddc --- /dev/null +++ b/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTilePositionTest.kt @@ -0,0 +1,43 @@ +package dev.adamko.kafkatorio.schema.common + +import dev.adamko.kafkatorio.schema.common.MapChunkPositionTest.Companion.mapTilePositionArb +import io.kotest.core.spec.style.FunSpec +import io.kotest.property.forAll + +class MapTilePositionTest : FunSpec({ + + context("comparison") { + + test("less than <") { + forAll( + mapTilePositionArb(), + mapTilePositionArb(1..100), + ) { tilePos, delta -> + tilePos < (tilePos + delta) + } + } + + test("less than or equal to <=") { + forAll(mapTilePositionArb()) { tilePos -> + tilePos <= (tilePos) + } + } + + test("greater than or equal to >=") { + forAll(mapTilePositionArb()) { tilePos -> + tilePos >= (tilePos) + } + } + + test("greater than >") { + forAll( + mapTilePositionArb(), + mapTilePositionArb(1..100), + ) { tilePos, delta -> + tilePos > (tilePos - delta) + } + } + + } + +}) From 6618a92a66391b53a912f4adab739b97ae8dde16 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 12:23:58 +0200 Subject: [PATCH 328/629] add some hacks to try and stop 'Projects must be configuring' bug --- build.gradle.kts | 29 ++++++++- buildSrc/build.gradle.kts | 7 +++ gradle.properties | 9 +++ modules/events-schema/build.gradle.kts | 35 +++++++---- modules/web-map/build.gradle.kts | 85 ++++++++++++++++++++++++-- 5 files changed, 145 insertions(+), 20 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index c802f4b..ab20ab6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,8 @@ plugins { `project-report` `build-dashboard` - kotlin("multiplatform") apply false // try to stop error 'Projects must be configuring' +// kotlin("multiplatform") apply false // try to stop error 'Projects must be configuring' + kotlin("js") apply false // try to stop error 'Projects must be configuring' } group = "dev.adamko.kafkatorio" @@ -73,3 +74,29 @@ val runWebMap by tasks.registering { dependsOn(":modules:web-map:browserDevelopmentRun") } + +// projects must be configuring hack +val hackLinePrefix = "// projects must be configuring hack " + +gradle.beforeSettings { + + val buildGradleKts: File = +// project.buildFile + layout.projectDirectory.file("buildSrc/build.gradle.kts").asFile + + val hackedLines = buildGradleKts.readText() + .lines() + .joinToString(System.lineSeparator()) { + println("hacking $it") + when { + it.startsWith(hackLinePrefix) -> "$hackLinePrefix ${System.currentTimeMillis()}" + else -> it + } + } + + buildGradleKts.writeText(hackedLines) +} + +tasks.configureEach { + inputs.property("pRoJeCtS-mUsT-bE-cOnFiGuRiNg", System.currentTimeMillis()) +} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index cbac159..571733a 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -102,3 +102,10 @@ idea { isDownloadJavadoc = true } } + +// projects must be configuring hack + + +tasks.configureEach { + inputs.property("pRoJeCtS-mUsT-bE-cOnFiGuRiNg", System.currentTimeMillis()) +} diff --git a/gradle.properties b/gradle.properties index ffa83bb..8e74cde 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,3 +9,12 @@ org.gradle.unsafe.configuration-cache=true org.gradle.unsafe.configuration-cache-problems=warn org.gradle.kotlin.dsl.precompiled.accessors.strict=true + +org.gradle.parallel=true + +io.kvision.plugin.enableGradleTasks=true +io.kvision.plugin.enableWorkerTasks=false +io.kvision.plugin.enableWebpackVersions=false +io.kvision.plugin.enableHiddenKotlinJsStore=false +io.kvision.plugin.enableSecureResolutions=false +io.kvision.plugin.enableBackendTasks=false diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index 3bbfd52..6a01f12 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -77,9 +77,13 @@ kotlin { implementation(project.dependencies.platform(libs.kotest.bom)) implementation("io.kotest:kotest-framework-engine") - implementation("io.kotest:kotest-assertions-core") - implementation("io.kotest:kotest-property") - implementation("io.kotest:kotest-assertions-json") +// implementation("io.kotest:kotest-assertions-core") +// implementation("io.kotest:kotest-property") +// implementation("io.kotest:kotest-assertions-json") + implementation(libs.kotest.core) + implementation(libs.kotest.datatest) + implementation(libs.kotest.prop) + implementation(libs.kotest.json) } } @@ -155,30 +159,35 @@ val generateTypescript by tasks.registering(GenerateTypescriptTask::class) { // } //} -val schemaTsDistributionName = providers.provider { +val schemaTsDistributionName : Provider = providers.provider { "${rootProject.name}-${project.name}" } +val generateTypescriptOutputFiles: Provider = generateTypescript.map { it.outputs.files.asFileTree } + val schemaTs by distributions.registering { distributionBaseName.set(schemaTsDistributionName) contents { - from(generateTypescript.map { it.outputs.files.asFileTree }) + from(generateTypescriptOutputFiles) } } -val schemaTsZipTask = tasks.named("${schemaTs.name}DistZip") +val schemaTsZipTask: TaskProvider = tasks.named("${schemaTs.name}DistZip") +val schemaTsZipTaskArchiveFile: Provider = schemaTsZipTask.flatMap { it.archiveFile } val typescriptModelGenerated: Configuration by configurations.creating { asProvider() typescriptAttributes(objects) - outgoing.artifact(schemaTsZipTask.flatMap { it.archiveFile }) + outgoing.artifact(schemaTsZipTaskArchiveFile) } -tasks.matching { - it.name == "jsGenerateExternalsIntegrated" -}.configureEach { - @Suppress("UnstableApiUsage") - notCompatibleWithConfigurationCache("try to prevent 'Projects must be configuring' error") -} +//tasks.matching { +// it.name == "jsGenerateExternalsIntegrated" +//}.configureEach { +// @Suppress("UnstableApiUsage") +// notCompatibleWithConfigurationCache("try to prevent 'Projects must be configuring' error") +//// outputs.upToDateWhen { true } +// dependsOn(":kotlinNpmInstall") +//} diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 5f125d7..5d1ec15 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -3,13 +3,29 @@ import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig plugins { - dev.adamko.kafkatorio.lang.`kotlin-js` +// dev.adamko.kafkatorio.lang.`kotlin-js` + dev.adamko.kafkatorio.lang.`kotlin-multiplatform` kotlin("plugin.serialization") id("io.kvision") } + +project.ext.set("io.kvision.plugin.enableGradleTasks", false) +project.ext.set("io.kvision.plugin.enableWorkerTasks", false) +project.ext.set("io.kvision.plugin.enableWebpackVersions", false) +project.ext.set("io.kvision.plugin.enableHiddenKotlinJsStore", false) +project.ext.set("io.kvision.plugin.enableSecureResolutions", false) +project.ext.set("io.kvision.plugin.enableBackendTasks", false) + + + kotlin { js(IR) { + browser() + binaries.executable() + } + + js("frontend", IR) { // nodejs() browser { runTask { @@ -22,7 +38,7 @@ kotlin { "/kv/*" to "http://localhost:8080", "/kvws/*" to mapOf("target" to "ws://localhost:8080", "ws" to true) ), - static = mutableListOf("$buildDir/processedResources/js/main") + static = mutableListOf("$buildDir/processedResources/frontend/main") ) } webpackTask { @@ -37,6 +53,10 @@ kotlin { binaries.executable() } + jvm("backend") { + + } + sourceSets { all { @@ -46,7 +66,22 @@ kotlin { } } - main { + val commonMain by getting { + dependencies { + implementation(dependencies.platform(libs.kotlinx.coroutines.bom)) + implementation(dependencies.platform(libs.kotlin.jsWrappers.bom)) + + implementation(libs.kotlinx.coroutines.core) + + implementation(projects.modules.eventsSchema) + + implementation(libs.kotlinx.html) + } + } + + val jsMain by getting { + dependsOn(commonMain) + dependencies { implementation(projects.modules.eventsSchema) @@ -77,11 +112,20 @@ kotlin { implementation(dependencies.platform(npm("node-forge", "^1.3.0"))) } - val webDir = file("src/main/web") - resources.srcDir(webDir) +// val webDir = file("src/main/web") + resources.srcDir("src/main/web") + resources.srcDir("src/main/resources") + + kotlin.srcDir("src/main/kotlin") } - test { + val frontendMain by getting { + dependsOn(jsMain) +// resources.srcDir("src/main/web") +// resources.srcDir("src/main/resources") + } + + val jsTest by getting { dependencies { implementation(kotlin("test-js")) @@ -89,6 +133,8 @@ kotlin { // implementation(npm("karma", "^6.3.16")) } + + kotlin.srcDir("src/test/kotlin") } } } @@ -114,3 +160,30 @@ fun KotlinDependencyHandler.kvision( // resolution("node-forge", "1.3.0") // } //} + +afterEvaluate { + rootProject.tasks.named("rootPackageJson").configure { + outputs.upToDateWhen { false } + inputs.property("cacheBuster", System.currentTimeMillis()) + } + rootProject.tasks.named("kotlinYarnSetup").configure { + outputs.upToDateWhen { false } + inputs.property("cacheBuster", System.currentTimeMillis()) + } + rootProject.tasks.named("kotlinNpmCachesSetup").configure { + outputs.upToDateWhen { false } + inputs.property("cacheBuster", System.currentTimeMillis()) + } + rootProject.tasks.named("kotlinStoreYarnLock").configure { + outputs.upToDateWhen { false } + inputs.property("cacheBuster", System.currentTimeMillis()) + } +} + +tasks.configureEach { + inputs.property("pRoJeCtS-mUsT-bE-cOnFiGuRiNg", System.currentTimeMillis()) +} + +rootProject.tasks.configureEach { + inputs.property("pRoJeCtS-mUsT-bE-cOnFiGuRiNg", System.currentTimeMillis()) +} From 23d77ae26c8d891dd06a6cd269bc872ca578bf48 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 12:24:28 +0200 Subject: [PATCH 329/629] try fixing white lines between web map tiles --- modules/web-map/src/main/resources/css/kafkatorio.css | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/web-map/src/main/resources/css/kafkatorio.css b/modules/web-map/src/main/resources/css/kafkatorio.css index af65ac8..54b756e 100644 --- a/modules/web-map/src/main/resources/css/kafkatorio.css +++ b/modules/web-map/src/main/resources/css/kafkatorio.css @@ -2,6 +2,7 @@ .leaflet-tile { width: 257px !important; height: 257px !important; + box-shadow: 0 0 1px rgba(0, 0, 0, 0.05); } html { From 008c25233ddca5556fb9cab901229c84381ad0fd Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 12:25:10 +0200 Subject: [PATCH 330/629] coroutine based file watcher (supposed to be used for etag stuff, but it's a bit janky) --- .../processor/misc/FileEventsFlow.kt | 195 ++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/FileEventsFlow.kt diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/FileEventsFlow.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/FileEventsFlow.kt new file mode 100644 index 0000000..6b467d3 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/FileEventsFlow.kt @@ -0,0 +1,195 @@ +package dev.adamko.kafkatorio.processor.misc + +import dev.adamko.kafkatorio.processor.KafkatorioTopology +import java.io.File +import java.nio.file.FileSystems +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.StandardWatchEventKinds.ENTRY_CREATE +import java.nio.file.StandardWatchEventKinds.ENTRY_DELETE +import java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY +import java.nio.file.WatchEvent +import java.nio.file.WatchKey +import java.nio.file.WatchService +import kotlin.coroutines.CoroutineContext +import kotlin.io.path.isReadable +import kotlin.time.Duration.Companion.seconds +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.cancellable +import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.flatMapConcat +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.mapNotNull +import kotlinx.coroutines.flow.runningFold +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import kotlinx.coroutines.yield + + +fun File.fileEventsFlow() = FileEventsFlow( + root = this.toPath(), +) + +fun Path.fileEventsFlow() = FileEventsFlow( + root = this, +) + + +/** [SharedFlow] wrapper for Java's [WatchService] */ +class FileEventsFlow private constructor( + private val root: Path, + private val fileEvents: MutableSharedFlow, +) : SharedFlow by fileEvents, CoroutineScope { + + constructor(root: Path) : this(root, MutableSharedFlow(0, Int.MAX_VALUE, BufferOverflow.SUSPEND)) + + override val coroutineContext: CoroutineContext = + CoroutineName("FileEventsFlow") + + KafkatorioTopology.rootJob + + Dispatchers.Unconfined + + CoroutineExceptionHandler { _, e -> + println("handling exception in FileEventsFlow") + e.printStackTrace() + watchService.close() + watchKeys.update { + it.cancelAll() + emptyList() + } + } + + + private val watchService: WatchService = FileSystems.getDefault().newWatchService() + + private val watchKeys: MutableStateFlow> = MutableStateFlow(emptyList()) + + + init { + println("launching FileEventsFlow... $root") + registerPaths() + pollFileEvents() + + launch { + fileEvents.emit(KWatchEvent.Initialized) + } + + println("launched FileEventsFlow $root") + + root.toFile().walk() +// .filter { it.isFile } + .onEach { + launch { + fileEvents.emit(KWatchEvent.Created(it.toPath())) + } + } + .count() + .let { + println("initializing KWatchEvent.Created $it") + } + } + + + /** Watch for any file tree changes and re-register the [watchKeys] */ + private fun registerPaths() = launch { + println("launching registerPaths") + fileEvents +// .onEach { println("file event! $it") } + .filter { event -> + when (event) { + is KWatchEvent.Initialized -> true + + is KWatchEvent.Created -> event.path.isDirectory + is KWatchEvent.Deleted -> event.path.isDirectory + + is KWatchEvent.Modified -> false + } + }.debounce(1.seconds) + .runningFold(emptyList()) { previousKeys, directoryTreeAlteredEvent -> + println("re-registering paths $directoryTreeAlteredEvent") + + previousKeys.cancelAll() + + root.toFile().walk() + .filter { it.isDirectory } + .map { +// println("re-registering watch on $it") + it.toPath().register(watchService, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE) + } + .toList() + .also { + println("${it.count()} registered watches") + } + } + .cancellable() + .collect(watchKeys) + } + + + /** Poll [watchService] for updates while [coroutineContext] is active. */ + private fun pollFileEvents() = launch { + flow { + while (coroutineContext.isActive) { + emit( + withContext(Dispatchers.IO) { watchService.take() } + ) + println("emitted watchService.take()") + yield() + } + }.mapNotNull { monitorKey -> + when (val keyPath = monitorKey.watchable()) { + is Path -> monitorKey to keyPath + else -> null + } + }.filter { it.second.isReadable() } + .flatMapConcat { (monitorKey: WatchKey, keyPath: Path) -> + val events = monitorKey.pollEvents() + monitorKey.reset() + events + .onEach { println("monitorKey event $it") } + .filter { it.context() as? Path != null } + .mapNotNull { event -> + val eventPath = keyPath.resolve(event.context() as Path) + + when (event.kind()) { + ENTRY_CREATE -> KWatchEvent.Created(eventPath) + ENTRY_DELETE -> KWatchEvent.Deleted(eventPath) + ENTRY_MODIFY -> KWatchEvent.Modified(eventPath) + else -> null + } + }.asFlow() + }.cancellable() + .collect(fileEvents) + } + + companion object { + private val Path.isDirectory: Boolean get() = Files.isDirectory(this) + + private fun List.cancelAll() = forEach { it.cancel(); it.pollEvents() } + } +} + +/** Wrapper around [WatchEvent] that comes with properly resolved absolute path */ +sealed interface KWatchEvent { + + object Initialized : KWatchEvent + + sealed interface PathEvent : KWatchEvent { + /** path of modified file or directory */ + val path: Path + } + + data class Created(override val path: Path) : PathEvent + data class Modified(override val path: Path) : PathEvent + data class Deleted(override val path: Path) : PathEvent + +} From aae78dca4d325569a90ce51d695020a4e4d3369e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 12:25:41 +0200 Subject: [PATCH 331/629] bump kotlin wrappers... I need to remove versions from here, they should only be in the libs.toml --- buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt index d443846..2ff5871 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt @@ -18,7 +18,8 @@ object Versions { const val node = "14.19.1" - const val kotlinWrappers = "0.0.1-pre.330-kotlin-1.6.20" + // const val kotlinWrappers = "0.0.1-pre.330-kotlin-1.6.20" + const val kotlinWrappers = "1.0.0-pre.336" const val junit = "5.8.2" const val kotest = "5.2.3" const val mockk = "1.12.1" From 7e267b82b58279fa2c5ba96147d3046067909c0f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 12:25:54 +0200 Subject: [PATCH 332/629] bump yarn lock --- gradle/kotlin-js-store/yarn.lock | 452 +++++++++++++------------------ 1 file changed, 188 insertions(+), 264 deletions(-) diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index 932e3e3..b774c5d 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -68,57 +68,22 @@ dependencies: html-parse-stringify "^3" -"@socket.io/base64-arraybuffer@~1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#568d9beae00b0d835f4f8c53fd55714986492e61" - integrity sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ== - -"@types/body-parser@*": - version "1.19.2" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" - integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/bonjour@^3.5.9": - version "3.5.10" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" - integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== - dependencies: - "@types/node" "*" - "@types/component-emitter@^1.2.10": version "1.2.11" resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== -"@types/connect-history-api-fallback@^1.3.5": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" - integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== - dependencies: - "@types/express-serve-static-core" "*" - "@types/node" "*" - -"@types/connect@*": - version "3.4.35" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" - integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== - dependencies: - "@types/node" "*" - -"@types/cookie@^0.4.1": +"@types/cookie@^0.4.0": version "0.4.1" resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== -"@types/cors@^2.8.12": +"@types/cors@^2.8.8": version "2.8.12" resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== -"@types/eslint-scope@^3.7.3": +"@types/eslint-scope@^3.7.0": version "3.7.3" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224" integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g== @@ -134,29 +99,15 @@ "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*", "@types/estree@^0.0.51": +"@types/estree@*": version "0.0.51" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": - version "4.17.28" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8" - integrity sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - -"@types/express@*", "@types/express@^4.17.13": - version "4.17.13" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" - integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.18" - "@types/qs" "*" - "@types/serve-static" "*" +"@types/estree@^0.0.50": + version "0.0.50" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" + integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== "@types/geojson@*", "@types/geojson@7946.0.8": version "7946.0.8" @@ -190,11 +141,6 @@ dependencies: "@types/geojson" "*" -"@types/mime@^1": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" - integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== - "@types/minimatch@*": version "3.0.5" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" @@ -210,50 +156,11 @@ resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== -"@types/qs@*": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== - -"@types/range-parser@*": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" - integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== - "@types/retry@^0.12.0": version "0.12.1" resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== -"@types/serve-index@^1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" - integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== - dependencies: - "@types/express" "*" - -"@types/serve-static@*": - version "1.13.10" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" - integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== - dependencies: - "@types/mime" "^1" - "@types/node" "*" - -"@types/sockjs@^0.3.33": - version "0.3.33" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" - integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== - dependencies: - "@types/node" "*" - -"@types/ws@^8.2.2": - version "8.5.3" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" - integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== - dependencies: - "@types/node" "*" - "@ungap/promise-all-settled@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" @@ -380,19 +287,19 @@ "@webassemblyjs/ast" "1.11.1" "@xtuc/long" "4.2.2" -"@webpack-cli/configtest@^1.1.1": +"@webpack-cli/configtest@^1.1.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.1.tgz#9f53b1b7946a6efc2a749095a4f450e2932e8356" integrity sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg== -"@webpack-cli/info@^1.4.1": +"@webpack-cli/info@^1.4.0": version "1.4.1" resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.1.tgz#2360ea1710cbbb97ff156a3f0f24556e0fc1ebea" integrity sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA== dependencies: envinfo "^7.7.3" -"@webpack-cli/serve@^1.6.1": +"@webpack-cli/serve@^1.6.0": version "1.6.1" resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.1.tgz#0de2875ac31b46b6c5bb1ae0a7d7f0ba5678dffe" integrity sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw== @@ -556,6 +463,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base64-arraybuffer@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" + integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= + base64id@2.0.0, base64id@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" @@ -733,7 +645,7 @@ chokidar@3.5.2: optionalDependencies: fsevents "~2.3.2" -chokidar@3.5.3, chokidar@^3.5.1, chokidar@^3.5.3: +chokidar@^3.5.1: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -805,7 +717,7 @@ colorette@^2.0.10, colorette@^2.0.14: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== -colors@1.4.0: +colors@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== @@ -943,10 +855,10 @@ custom-event@~1.0.0: resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= -date-format@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.7.tgz#aa1cf4400badfe693c8462bbfcba43ab821d7d14" - integrity sha512-k5xqlzDGIfv2N/DHR/BR8Kc4N9CRy9ReuDkmdxeX/jNfit94QXd36emWMm40ZOEDKNm/c91yV9EO3uGPkR7wWQ== +date-format@^4.0.9: + version "4.0.9" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.9.tgz#4788015ac56dedebe83b03bc361f00c1ddcf1923" + integrity sha512-+8J+BOUpSrlKLQLeF8xJJVTxS8QfRSuJgwxSVvslzgO3E6khbI0F5mMEPf5mTYhCCm4h99knYP6H3W9n3BQFrg== debug@2.6.9: version "2.6.9" @@ -962,13 +874,6 @@ debug@4.3.2: dependencies: ms "2.1.2" -debug@4.3.3: - version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== - dependencies: - ms "2.1.2" - debug@^3.1.1: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -976,7 +881,7 @@ debug@^3.1.1: dependencies: ms "^2.1.1" -debug@^4.1.0, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: +debug@^4.1.0, debug@^4.3.4, debug@~4.3.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -1000,7 +905,7 @@ deep-equal@^1.0.1: object-keys "^1.1.1" regexp.prototype.flags "^1.2.0" -default-gateway@^6.0.3: +default-gateway@^6.0.0: version "6.0.3" resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== @@ -1154,28 +1059,25 @@ encoding@^0.1.12: dependencies: iconv-lite "^0.6.2" -engine.io-parser@~5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.3.tgz#ca1f0d7b11e290b4bfda251803baea765ed89c09" - integrity sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg== +engine.io-parser@~4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-4.0.3.tgz#83d3a17acfd4226f19e721bb22a1ee8f7662d2f6" + integrity sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA== dependencies: - "@socket.io/base64-arraybuffer" "~1.0.2" + base64-arraybuffer "0.1.4" -engine.io@~6.1.0: - version "6.1.3" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.1.3.tgz#f156293d011d99a3df5691ac29d63737c3302e6f" - integrity sha512-rqs60YwkvWTLLnfazqgZqLa/aKo+9cueVfEi/dZ8PyGyaf8TLOxj++4QMIgeG3Gn0AhrWiFXvghsoY9L9h25GA== +engine.io@~4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-4.1.2.tgz#f96ceb56d4b39cc7ca5bd29a20e9c99c1ad1a765" + integrity sha512-t5z6zjXuVLhXDMiFJPYsPOWEER8B0tIsD3ETgw19S1yg9zryvUfY3Vhtk3Gf4sihw/bQGIqQ//gjvVlu+Ca0bQ== dependencies: - "@types/cookie" "^0.4.1" - "@types/cors" "^2.8.12" - "@types/node" ">=10.0.0" accepts "~1.3.4" base64id "2.0.0" cookie "~0.4.1" cors "~2.8.5" debug "~4.3.1" - engine.io-parser "~5.0.3" - ws "~8.2.3" + engine.io-parser "~4.0.0" + ws "~7.4.2" enhanced-resolve@^5.8.3: version "5.9.3" @@ -1432,7 +1334,7 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= -fs-extra@^10.0.1: +fs-extra@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== @@ -1558,7 +1460,7 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -"glob@5 - 7", glob@7.2.0, glob@^7.1.3, glob@^7.1.7: +"glob@5 - 7", glob@^7.1.3, glob@^7.1.7: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== @@ -1599,7 +1501,7 @@ google-protobuf@3.12.2: resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.12.2.tgz#50ce9f9b6281235724eb243d6a83e969a2176e53" integrity sha512-4CZhpuRr1d6HjlyrxoXoocoGFnRYgKULgMtikMddA9ztRyYR59Aondv2FioyxWVamRo0rF2XpYawkTCBEQOSkA== -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== @@ -1807,17 +1709,32 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= +internal-ip@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-6.2.0.tgz#d5541e79716e406b74ac6b07b856ef18dc1621c1" + integrity sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg== + dependencies: + default-gateway "^6.0.0" + ipaddr.js "^1.9.1" + is-ip "^3.1.0" + p-event "^4.2.0" + interpret@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== +ip-regex@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" + integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== + ip@^1.1.0: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= -ipaddr.js@1.9.1: +ipaddr.js@1.9.1, ipaddr.js@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== @@ -1878,6 +1795,13 @@ is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-ip@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8" + integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q== + dependencies: + ip-regex "^4.0.0" + is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -2037,15 +1961,15 @@ karma-webpack@5.0.0: minimatch "^3.0.4" webpack-merge "^4.1.5" -karma@6.3.16: - version "6.3.16" - resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.16.tgz#76d1a705fd1cf864ee5ed85270b572641e0958ef" - integrity sha512-nEU50jLvDe5yvXqkEJRf8IuvddUkOY2x5Xc4WXHz6dxINgGDrgD2uqQWeVrJs4hbfNaotn+HQ1LZJ4yOXrL7xQ== +karma@6.3.4: + version "6.3.4" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.4.tgz#359899d3aab3d6b918ea0f57046fd2a6b68565e6" + integrity sha512-hbhRogUYIulfkBTZT7xoPrCYhRBnBoqbbL4fszWD0ReFGUxU+LYBr3dwKdAluaDQ/ynT9/7C+Lf7pPNW4gSx4Q== dependencies: body-parser "^1.19.0" braces "^3.0.2" chokidar "^3.5.1" - colors "1.4.0" + colors "^1.4.0" connect "^3.7.0" di "^0.0.1" dom-serialize "^2.2.1" @@ -2054,17 +1978,16 @@ karma@6.3.16: http-proxy "^1.18.1" isbinaryfile "^4.0.8" lodash "^4.17.21" - log4js "^6.4.1" + log4js "^6.3.0" mime "^2.5.2" minimatch "^3.0.4" - mkdirp "^0.5.5" qjobs "^1.2.0" range-parser "^1.2.1" rimraf "^3.0.2" - socket.io "^4.2.0" + socket.io "^3.1.0" source-map "^0.6.1" tmp "^0.2.1" - ua-parser-js "^0.7.30" + ua-parser-js "^0.7.28" yargs "^16.1.1" kind-of@^6.0.2: @@ -2114,16 +2037,16 @@ log-symbols@4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -log4js@^6.4.1: - version "6.4.5" - resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.4.5.tgz#5cca31b29ece65a625efbc3df6fcbd9cecb9ee7b" - integrity sha512-43RJcYZ7nfUxpPO2woTl8CJ0t5+gucLJZ43mtp2PlInT+LygCp/bl6hNJtKulCJ+++fQsjIv4EO3Mp611PfeLQ== +log4js@^6.3.0: + version "6.4.6" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.4.6.tgz#1878aa3f09973298ecb441345fe9dd714e355c15" + integrity sha512-1XMtRBZszmVZqPAOOWczH+Q94AI42mtNWjvjA5RduKTSWjEc56uOBbyM1CJnfN4Ym0wSd8cQ43zOojlSHgRDAw== dependencies: - date-format "^4.0.7" + date-format "^4.0.9" debug "^4.3.4" flatted "^3.2.5" rfdc "^1.3.0" - streamroller "^3.0.7" + streamroller "^3.0.8" lru-cache@^6.0.0: version "6.0.0" @@ -2260,36 +2183,6 @@ mocha@9.1.2: yargs-parser "20.2.4" yargs-unparser "2.0.0" -mocha@9.2.1: - version "9.2.1" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.1.tgz#a1abb675aa9a8490798503af57e8782a78f1338e" - integrity sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.3" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" - growl "1.10.5" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "3.0.4" - ms "2.1.3" - nanoid "3.2.0" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - workerpool "6.2.0" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -2323,11 +2216,6 @@ nanoid@3.1.25: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== -nanoid@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" - integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== - nanoid@^3.1.31, nanoid@^3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" @@ -2343,10 +2231,10 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -node-forge@^1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.0.tgz#37a874ea723855f37db091e6c186e5b67a01d4b2" - integrity sha512-08ARB91bUi6zNKzVmaj3QO7cr397uiDT2nJ63cHjyNtCTWIgvS47j3eT0WfzUwS9+6Z5YshRaoasFkXCKrIYbA== +node-forge@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" + integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== node-forge@^1.3.0: version "1.3.1" @@ -2440,6 +2328,18 @@ open@^8.0.9: is-docker "^2.1.1" is-wsl "^2.2.0" +p-event@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" + integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== + dependencies: + p-timeout "^3.1.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -2483,6 +2383,13 @@ p-retry@^4.5.0: "@types/retry" "^0.12.0" retry "^0.13.1" +p-timeout@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -2622,6 +2529,11 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -2644,6 +2556,11 @@ qs@6.9.7: resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe" integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -2847,12 +2764,12 @@ select-hose@^2.0.0: resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= -selfsigned@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" - integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ== +selfsigned@^1.10.11: + version "1.10.14" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.14.tgz#ee51d84d9dcecc61e07e4aba34f229ab525c1574" + integrity sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA== dependencies: - node-forge "^1" + node-forge "^0.10.0" semver@^7.3.5: version "7.3.7" @@ -2963,12 +2880,12 @@ snabbdom@^3.4.0: resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.4.0.tgz#c76ed02643729f84a63875b7894a0fbcdc95c710" integrity sha512-Sr5H1l5QxJa0B/68ZtpWi7MuGIzLWS2Up64QqXe/wzvWOjXvM9rL7+C8GhMmDVtJ7dFWypvyWJHR3nmeZN8YIQ== -socket.io-adapter@~2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz#4d6111e4d42e9f7646e365b4f578269821f13486" - integrity sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ== +socket.io-adapter@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz#edc5dc36602f2985918d631c1399215e97a1b527" + integrity sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg== -socket.io-parser@~4.0.4: +socket.io-parser@~4.0.3: version "4.0.4" resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0" integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g== @@ -2977,17 +2894,20 @@ socket.io-parser@~4.0.4: component-emitter "~1.3.0" debug "~4.3.1" -socket.io@^4.2.0: - version "4.4.1" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.4.1.tgz#cd6de29e277a161d176832bb24f64ee045c56ab8" - integrity sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg== +socket.io@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-3.1.2.tgz#06e27caa1c4fc9617547acfbb5da9bc1747da39a" + integrity sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw== dependencies: + "@types/cookie" "^0.4.0" + "@types/cors" "^2.8.8" + "@types/node" ">=10.0.0" accepts "~1.3.4" base64id "~2.0.0" - debug "~4.3.2" - engine.io "~6.1.0" - socket.io-adapter "~2.3.3" - socket.io-parser "~4.0.4" + debug "~4.3.1" + engine.io "~4.1.0" + socket.io-adapter "~2.1.0" + socket.io-parser "~4.0.3" sockjs@^0.3.21: version "0.3.24" @@ -3081,14 +3001,14 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -streamroller@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.0.7.tgz#d566353d3d8b5d2f3d813d2df557c08083b414cf" - integrity sha512-kh68kwiDGuIPiPDWwRbEC5us+kfARP1e9AsQiaLaSqGrctOvMn0mtL8iNY3r4/o5nIoYi3gPI1jexguZsXDlxw== +streamroller@^3.0.8: + version "3.0.8" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.0.8.tgz#84b190e4080ee311ca1ebe0444e30ac8eedd028d" + integrity sha512-VI+ni3czbFZrd1MrlybxykWZ8sMDCMtTU7YJyhgb9M5X6d1DDxLdJr+gSnmRpXPMnIWxWKMaAE8K0WumBp3lDg== dependencies: - date-format "^4.0.7" + date-format "^4.0.9" debug "^4.3.4" - fs-extra "^10.0.1" + fs-extra "^10.1.0" string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" @@ -3241,7 +3161,7 @@ typescript@3.9.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== -ua-parser-js@^0.7.30: +ua-parser-js@^0.7.28: version "0.7.31" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== @@ -3268,6 +3188,14 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -3283,6 +3211,11 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +v8-compile-cache@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -3298,7 +3231,7 @@ void-elements@^2.0.0: resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= -watchpack@^2.3.1: +watchpack@^2.2.0: version "2.3.1" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25" integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== @@ -3313,15 +3246,15 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" -webpack-cli@4.9.2: - version "4.9.2" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.2.tgz#77c1adaea020c3f9e2db8aad8ea78d235c83659d" - integrity sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ== +webpack-cli@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.0.tgz#dc43e6e0f80dd52e89cbf73d5294bcd7ad6eb343" + integrity sha512-n/jZZBMzVEl4PYIBs+auy2WI0WTQ74EnJDiyD98O2JZY6IVIHJNitkYp/uTXOviIOMfgzrNvC9foKv/8o8KSZw== dependencies: "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.1.1" - "@webpack-cli/info" "^1.4.1" - "@webpack-cli/serve" "^1.6.1" + "@webpack-cli/configtest" "^1.1.0" + "@webpack-cli/info" "^1.4.0" + "@webpack-cli/serve" "^1.6.0" colorette "^2.0.14" commander "^7.0.0" execa "^5.0.0" @@ -3329,9 +3262,10 @@ webpack-cli@4.9.2: import-local "^3.0.2" interpret "^2.2.0" rechoir "^0.7.0" + v8-compile-cache "^2.2.0" webpack-merge "^5.7.3" -webpack-dev-middleware@^5.3.1: +webpack-dev-middleware@^5.2.1: version "5.3.1" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz#aa079a8dedd7e58bfeab358a9af7dab304cee57f" integrity sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg== @@ -3342,41 +3276,36 @@ webpack-dev-middleware@^5.3.1: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@4.7.4: - version "4.7.4" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.7.4.tgz#d0ef7da78224578384e795ac228d8efb63d5f945" - integrity sha512-nfdsb02Zi2qzkNmgtZjkrMOcXnYZ6FLKcQwpxT7MvmHKc+oTtDsBju8j+NMyAygZ9GW1jMEUpy3itHtqgEhe1A== +webpack-dev-server@4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.3.1.tgz#759d3337f0fbea297fbd1e433ab04ccfc000076b" + integrity sha512-qNXQCVYo1kYhH9pgLtm8LRNkXX3XzTfHSj/zqzaqYzGPca+Qjr+81wj1jgPMCHhIhso9WEQ+kX9z23iG9PzQ7w== dependencies: - "@types/bonjour" "^3.5.9" - "@types/connect-history-api-fallback" "^1.3.5" - "@types/express" "^4.17.13" - "@types/serve-index" "^1.9.1" - "@types/sockjs" "^0.3.33" - "@types/ws" "^8.2.2" ansi-html-community "^0.0.8" bonjour "^3.5.0" - chokidar "^3.5.3" + chokidar "^3.5.1" colorette "^2.0.10" compression "^1.7.4" connect-history-api-fallback "^1.6.0" - default-gateway "^6.0.3" del "^6.0.0" express "^4.17.1" graceful-fs "^4.2.6" html-entities "^2.3.2" http-proxy-middleware "^2.0.0" + internal-ip "^6.2.0" ipaddr.js "^2.0.1" open "^8.0.9" p-retry "^4.5.0" portfinder "^1.0.28" - schema-utils "^4.0.0" - selfsigned "^2.0.0" + schema-utils "^3.1.0" + selfsigned "^1.10.11" serve-index "^1.9.1" sockjs "^0.3.21" spdy "^4.0.2" strip-ansi "^7.0.0" - webpack-dev-middleware "^5.3.1" - ws "^8.4.2" + url "^0.11.0" + webpack-dev-middleware "^5.2.1" + ws "^8.1.0" webpack-merge@^4.1.5: version "4.2.2" @@ -3393,18 +3322,18 @@ webpack-merge@^5.7.3: clone-deep "^4.0.1" wildcard "^2.0.0" -webpack-sources@^3.2.3: +webpack-sources@^3.2.0: version "3.2.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@5.69.1: - version "5.69.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.69.1.tgz#8cfd92c192c6a52c99ab00529b5a0d33aa848dc5" - integrity sha512-+VyvOSJXZMT2V5vLzOnDuMz5GxEqLk7hKWQ56YxPW/PQRUuKimPqmEIJOx8jHYeyo65pKbapbW464mvsKbaj4A== +webpack@5.57.1: + version "5.57.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.57.1.tgz#ead5ace2c17ecef2ae8126f143bfeaa7f55eab44" + integrity sha512-kHszukYjTPVfCOEyrUthA3jqJwduY/P3eO8I0gMNOZGIQWKAwZftxmp5hq6paophvwo9NoUrcZOecs9ulOyyTg== dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^0.0.51" + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.50" "@webassemblyjs/ast" "1.11.1" "@webassemblyjs/wasm-edit" "1.11.1" "@webassemblyjs/wasm-parser" "1.11.1" @@ -3417,7 +3346,7 @@ webpack@5.69.1: eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" + graceful-fs "^4.2.4" json-parse-better-errors "^1.0.2" loader-runner "^4.2.0" mime-types "^2.1.27" @@ -3425,8 +3354,8 @@ webpack@5.69.1: schema-utils "^3.1.0" tapable "^2.1.1" terser-webpack-plugin "^5.1.3" - watchpack "^2.3.1" - webpack-sources "^3.2.3" + watchpack "^2.2.0" + webpack-sources "^3.2.0" websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" @@ -3466,11 +3395,6 @@ workerpool@6.1.5: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== -workerpool@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" - integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== - wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -3485,15 +3409,15 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@^8.4.2: - version "8.5.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" - integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== +ws@^8.1.0: + version "8.6.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.6.0.tgz#e5e9f1d9e7ff88083d0c0dd8281ea662a42c9c23" + integrity sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw== -ws@~8.2.3: - version "8.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" - integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== +ws@~7.4.2: + version "7.4.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== y18n@^5.0.5: version "5.0.8" From c48d01b220c355d1919dbbfe8b0b979552b32565 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 12:27:32 +0200 Subject: [PATCH 333/629] dynamically update tiles every 1 second --- .../dev/adamko/kafkatorio/webmap/App.kt | 47 +++++++++++++++++-- .../dev/adamko/kafkatorio/webmap/map.kt | 23 +++++++-- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index 57ae7d8..c7bc5a0 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -9,11 +9,16 @@ import io.kvision.CoreModule import io.kvision.FontAwesomeModule import io.kvision.html.div import io.kvision.maps.Maps +import io.kvision.maps.externals.leaflet.layer.tile.GridLayer import io.kvision.module import io.kvision.panel.root import io.kvision.redux.ReduxStore import io.kvision.require import io.kvision.startApplication +import kotlin.time.Duration.Companion.seconds +import kotlinx.js.timers.setInterval +import org.w3c.dom.Image +import org.w3c.dom.asList class App( @@ -37,10 +42,47 @@ class App( override fun start(state: Map) { this.appState = state.toMutableMap() - root("kvapp") { + val root = root("kvapp") { div("Kafkatorio Web Map") add(kvMaps) } + + kvMaps.leafletMap { + invalidateSize(true) + eachLayer({ + if (it is GridLayer<*>) { + it.redraw() + } + }) +// this.asDynamic()._fadeAnimated = false + } + + setInterval(1.seconds) { + val doc = root.getElement()?.ownerDocument + val window = doc!!.defaultView!! + + doc + .querySelectorAll("img.leaflet-tile-loaded") + .asList() + .filterIsInstance() + .map { img -> + val imgSrc = img.src.substringBeforeLast('?') + println("fetching $imgSrc") + + val newImg = Image() + + newImg.onload = { + + window.requestAnimationFrame { + println("image loaded ${newImg.src}") + img.setAttribute("dynamic-reload", "true") + img.src = newImg.src + Unit + } + } + newImg.src = imgSrc //+ "?t=${currentTimeMillis()}" + } + } } override fun dispose(): Map { @@ -49,7 +91,6 @@ class App( } - fun main() { startApplication( { @@ -69,6 +110,6 @@ fun main() { BootstrapIconsModule, FontAwesomeModule, ChartModule, - CoreModule + CoreModule, ) } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index bd3717e..c614b94 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -2,9 +2,12 @@ package dev.adamko.kafkatorio.webmap import io.kvision.maps.Maps import io.kvision.maps.Maps.Companion.L +import io.kvision.maps.externals.leaflet.DoneCallback import io.kvision.maps.externals.leaflet.geo.CRS import io.kvision.maps.externals.leaflet.geo.LatLng +import io.kvision.maps.externals.leaflet.layer.tile.TileLayer import io.kvision.utils.px +import org.w3c.dom.HTMLElement // //val polyline = Maps.L.polyline( @@ -19,6 +22,8 @@ import io.kvision.utils.px // noClip = true //} +private const val tileUrlTemplate = """http://localhost:9073/tiles/s1/z{z}/x{x}/y{y}.png""" + fun createFactorioMap() = Maps { width = 800.px height = 800.px @@ -27,8 +32,8 @@ fun createFactorioMap() = Maps { configureLeafletMap { setView(center = LatLng(0, 0), zoom = 0) - L.tileLayer( - """http://localhost:9073/tiles/s1/z{z}/x{x}/y{y}.png""" + val baseTileLayer: TileLayer = L.tileLayer( + tileUrlTemplate ) { attribution = "kafkatorio" tileSize = 256 @@ -43,8 +48,19 @@ fun createFactorioMap() = Maps { noWrap = true updateWhenIdle = false updateWhenZooming = true - }.addTo(this) + } + val currentTileOnLoad: (DoneCallback, HTMLElement) -> Unit = + baseTileLayer.asDynamic()._tileOnLoad as (DoneCallback, HTMLElement) -> Unit + baseTileLayer.asDynamic()._tileOnLoad = { done: DoneCallback, tile: HTMLElement -> + if (tile.hasAttribute("dynamic-reload")) { + tile.removeAttribute("dynamic-reload") + } else { + currentTileOnLoad(done, tile) + } + } + + baseTileLayer.addTo(this) L.scale { metric = true @@ -56,5 +72,6 @@ fun createFactorioMap() = Maps { options.zoomSnap = 0 options.zoomDelta = 0.1 +// options.fadeAnimation = false } } From f0590b9df4d08114cd08130771ac17f49a848c88 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 12:50:13 +0200 Subject: [PATCH 334/629] mad wicked sick tile grouping optimisations --- .../kafkatorio/schema/common/positions.kt | 103 +++++- .../processor/KafkatorioTopology.kt | 3 +- .../processor/topology/colourMapChunks.kt | 313 ++++++++++++++++++ .../processor/topology/groupMapChunks.kt | 5 +- .../kafkatorio/processor/topology/model.kt | 35 -- .../processor/topology/playerUpdates.kt | 9 +- .../processor/topology/prototypes.kt | 10 +- .../processor/topology/saveMapTiles.kt | 100 +++--- .../processor/topology/SaveMapChunksTest.kt | 5 +- 9 files changed, 474 insertions(+), 109 deletions(-) create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt index 16a0739..1d63eee 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt @@ -3,6 +3,8 @@ package dev.adamko.kafkatorio.schema.common import dev.adamko.kxstsgen.core.* import dev.adamko.kxstsgen.core.experiments.TupleSerializer import kotlin.math.floor +import kotlin.math.pow +import kotlin.math.roundToInt import kotlinx.serialization.Serializable /** @@ -58,6 +60,33 @@ data class MapChunkPosition( ) } } + + private val bounds: MapChunkPositionBounds by lazy { + MapChunkPositionBounds(this, ChunkSize.CHUNK_032) + } + + operator fun contains(tilePosition: MapTilePosition): Boolean { + return tilePosition in bounds + } +} + + +@Serializable +data class MapChunkPositionBounds( + val leftTop: MapTilePosition, + val rightBottom: MapTilePosition, +) : ClosedRange { + + constructor(chunkPosition: MapChunkPosition, chunkSize: ChunkSize) : this( + chunkPosition.leftTopTile(chunkSize), + chunkPosition.rightBottomTile(chunkSize), + ) + + override val start: MapTilePosition + get() = leftTop + + override val endInclusive: MapTilePosition + get() = rightBottom } @@ -71,7 +100,7 @@ data class MapChunkPosition( data class MapTilePosition( val x: Int, val y: Int, -) { +) : Comparable { object Serializer : TupleSerializer( "MapTilePosition", { @@ -85,6 +114,12 @@ data class MapTilePosition( return MapTilePosition(x, y) } } + + override operator fun compareTo(other: MapTilePosition): Int = + when { + other.x != x -> x.compareTo(other.x) + else -> y.compareTo(other.y) + } } @@ -100,21 +135,28 @@ operator fun MapTilePosition.div(divisor: Int) = operator fun MapTilePosition.plus(addend: Int) = MapTilePosition(x + addend, y + addend) +operator fun MapTilePosition.plus(addend: MapTilePosition) = + MapTilePosition(x + addend.x, y + addend.y) -fun MapTilePosition.toMapChunkPosition(chunkSize: Int = MAP_CHUNK_SIZE) = + +operator fun MapTilePosition.minus(subtrahend: MapTilePosition) = + MapTilePosition(x - subtrahend.x, y - subtrahend.y) + + +fun MapTilePosition.toMapChunkPosition(chunkSize: ChunkSize) = MapChunkPosition( - floor(x.toDouble() / chunkSize.toDouble()).toInt(), - floor(y.toDouble() / chunkSize.toDouble()).toInt(), + floor(x.toDouble() / chunkSize.lengthInTiles.toDouble()).toInt(), + floor(y.toDouble() / chunkSize.lengthInTiles.toDouble()).toInt(), ) fun MapEntityPosition.toMapTilePosition() = MapChunkPosition(floor(x).toInt(), floor(y).toInt()) -fun MapEntityPosition.toMapChunkPosition(chunkSize: Int = MAP_CHUNK_SIZE) = +fun MapEntityPosition.toMapChunkPosition(chunkSize: ChunkSize) = MapChunkPosition( - floor(x / chunkSize.toDouble()).toInt(), - floor(y / chunkSize.toDouble()).toInt(), + floor(x / chunkSize.lengthInTiles.toDouble()).toInt(), + floor(y / chunkSize.lengthInTiles.toDouble()).toInt(), ) @@ -128,18 +170,17 @@ operator fun MapChunkPosition.minus(subtrahend: Int) = MapChunkPosition(x - subtrahend, y - subtrahend) -fun MapChunkPosition.leftTopTile(chunkSize: Int = MAP_CHUNK_SIZE): MapTilePosition = +fun MapChunkPosition.leftTopTile(chunkSize: ChunkSize): MapTilePosition = MapTilePosition( - x * chunkSize, - y * chunkSize, + x * chunkSize.lengthInTiles, + y * chunkSize.lengthInTiles, ) - -fun MapChunkPosition.rightBottomTile(chunkSize: Int = MAP_CHUNK_SIZE): MapTilePosition = - leftTopTile(chunkSize) + (chunkSize - 1) +fun MapChunkPosition.rightBottomTile(chunkSize: ChunkSize): MapTilePosition = + leftTopTile(chunkSize) + (chunkSize.lengthInTiles - 1) -fun MapChunkPosition.iterateTiles(chunkSize: Int = MAP_CHUNK_SIZE): Iterator { +fun MapChunkPosition.iterateTiles(chunkSize: ChunkSize): Iterator { val leftTop = leftTopTile(chunkSize) val rightBottom = rightBottomTile(chunkSize) return iterator { @@ -158,3 +199,37 @@ fun MapChunkPosition.iterateTiles(chunkSize: Int = MAP_CHUNK_SIZE): Iterator { + CHUNK_512(-1), + CHUNK_256(0), + CHUNK_128(1), + CHUNK_064(2), + CHUNK_032(3), + ; + + /** 32, 64, 128, 256, or 512 */ + val lengthInTiles: Int = 2f.pow(8 - zoomLevel).roundToInt() + + init { + require(lengthInTiles > 0) { "tilesPerChunk $lengthInTiles must be positive" } + // 1000 & 0111 = 0000 => pow^2 + // 1001 & 1000 = 1000 => !pow^2 + require(lengthInTiles and (lengthInTiles - 1) == 0) { + "tilesPerChunk $lengthInTiles must be a power-of-two number" + } + } + + companion object { + // cache values for better performance. KT-48872 + val entries: Set = values().toSet() + + val MAX: ChunkSize = entries.maxByOrNull { it.lengthInTiles }!! + val MIN: ChunkSize = entries.minByOrNull { it.lengthInTiles }!! + val STANDARD: ChunkSize = entries.first { it.zoomLevel == 0 } + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 5bea0c6..359ee48 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -1,6 +1,7 @@ package dev.adamko.kafkatorio.processor import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.processor.topology.colourMapChunks import dev.adamko.kafkatorio.processor.topology.factorioServerPacketStream import dev.adamko.kafkatorio.processor.topology.groupMapChunks import dev.adamko.kafkatorio.processor.topology.playerUpdatesToWsServer @@ -54,7 +55,7 @@ internal class KafkatorioTopology( private fun groupTilesMapChunks() { val builder = StreamsBuilder() - val topology = groupMapChunks(builder) + val topology = colourMapChunks(builder) launchTopology("groupTilesMapChunks", topology) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt new file mode 100644 index 0000000..050d3a7 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt @@ -0,0 +1,313 @@ +package dev.adamko.kafkatorio.processor.topology + +import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE +import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.schema.common.ChunkSize +import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.leftTopTile +import dev.adamko.kafkatorio.schema.common.toMapChunkPosition +import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate +import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate +import dev.adamko.kotka.extensions.consumedAs +import dev.adamko.kotka.extensions.groupedAs +import dev.adamko.kotka.extensions.materializedAs +import dev.adamko.kotka.extensions.producedAs +import dev.adamko.kotka.extensions.repartitionedAs +import dev.adamko.kotka.extensions.streams.filter +import dev.adamko.kotka.extensions.streams.map +import dev.adamko.kotka.extensions.streams.mapValues +import dev.adamko.kotka.extensions.streams.peek +import dev.adamko.kotka.extensions.streams.reduce +import dev.adamko.kotka.extensions.tableJoined +import dev.adamko.kotka.extensions.tables.join +import dev.adamko.kotka.extensions.tables.toStream +import dev.adamko.kotka.kxs.serde +import kotlin.collections.component1 +import kotlin.collections.component2 +import org.apache.kafka.streams.StreamsBuilder +import org.apache.kafka.streams.Topology +import org.apache.kafka.streams.kstream.KStream +import org.apache.kafka.streams.kstream.KTable + + +private const val pid: String = "colourMapChunks" + + +/** Add colour to each [MapChunkUpdate] */ +fun colourMapChunks(builder: StreamsBuilder): Topology { + + val mapChunksStream: KStream = builder.streamPacketData() + val protosStream: KStream = builder.streamPacketData() + + val protosTable: KTable = + protosStream.createTilePrototypeTable() + + val chunkTilesColouredTable032: KTable> = + mapChunksStream + .convertToServerMapChunkTiles() + .reduceServerMapChunkTilesToTable() + .enrichWithColourData(protosTable) + + chunkTilesColouredTable032.streamTo(ChunkSize.CHUNK_032, TOPIC_GROUPED_MAP_CHUNKS_STATE) + + val groupedMapChunks = builder.stream( + TOPIC_GROUPED_MAP_CHUNKS_STATE, + consumedAs( + "$pid.consume.grouped-map-chunks", + kxsBinary.serde(), + kxsBinary.serde>(), + ) + ) + + mapOf( + ChunkSize.CHUNK_032 to ChunkSize.CHUNK_064, + ChunkSize.CHUNK_064 to ChunkSize.CHUNK_128, + ChunkSize.CHUNK_128 to ChunkSize.CHUNK_256, + ChunkSize.CHUNK_256 to ChunkSize.CHUNK_512, + ).forEach { (from, to) -> + groupedMapChunks + .filter("$pid.combine-chunks.filter-$from-to-$to") { key, _ -> + key?.chunkSize == from + }.groupByChunkPosition(to) + .streamTo(to, TOPIC_GROUPED_MAP_CHUNKS_STATE) + } + +// val chunkTilesColouredTable064 = +// chunkTilesColouredTable032.groupByChunkPosition(ChunkSize.CHUNK_064) +// chunkTilesColouredTable064.streamTo(ChunkSize.CHUNK_064, TOPIC_GROUPED_MAP_CHUNKS_STATE) +// +// val chunkTilesColouredTable128 = +// chunkTilesColouredTable064.groupByChunkPosition(ChunkSize.CHUNK_128) +// chunkTilesColouredTable128.streamTo(ChunkSize.CHUNK_128, TOPIC_GROUPED_MAP_CHUNKS_STATE) +// +// val chunkTilesColouredTable256 = +// chunkTilesColouredTable128.groupByChunkPosition(ChunkSize.CHUNK_256) +// chunkTilesColouredTable256.streamTo(ChunkSize.CHUNK_256, TOPIC_GROUPED_MAP_CHUNKS_STATE) +// +// val chunkTilesColouredTable512 = +// chunkTilesColouredTable256.groupByChunkPosition(ChunkSize.CHUNK_512) +// chunkTilesColouredTable512.streamTo(ChunkSize.CHUNK_512, TOPIC_GROUPED_MAP_CHUNKS_STATE) + + return builder.build() +} + + +private fun KStream.convertToServerMapChunkTiles() + : KStream> { + + val pid = "$pid.convertToMapTiles" + + return map("$pid.map") { serverId: FactorioServerId, update: MapChunkUpdate -> + + val mapTileList = update.tileDictionary?.toMapTileList() ?: emptyList() + + val (validMapTilesList, invalidMapTilesList) = mapTileList.partition { + it.position in update.key.chunkPosition + } + + if (invalidMapTilesList.isNotEmpty()) { + println("WARNING [reduceMapTilesToTable] MapChunkUpdate contained out-of-bounds tiles $invalidMapTilesList") + } + + val validMapTilesToProtoHashCode = + validMapTilesList.associate { it.position to TileProtoHashCode(it) } + + val chunkId = ServerMapChunkId( + serverId = serverId, + chunkPosition = update.key.chunkPosition, + surfaceIndex = update.key.surfaceIndex, + chunkSize = ChunkSize.CHUNK_032, + ) + + val chunkTiles = ServerMapChunkTiles(chunkId, validMapTilesToProtoHashCode) + + chunkId to chunkTiles + } +} + + +private fun KStream>.reduceServerMapChunkTilesToTable() + : KTable> { + + val pid = "$pid.reduceServerMapChunkTilesToTable" + + return repartition( + repartitionedAs( + "$pid.pre-table-repartition", + kxsBinary.serde(), + kxsBinary.serde>(), + // force, otherwise KTable-KTable FK join doesn't work + numberOfPartitions = 1, + ) + ).groupByKey( + groupedAs( + "$pid.group-by-key", + kxsBinary.serde(), + kxsBinary.serde>(), + ) + ).reduce( + "$pid.reduce", + materializedAs( + "$pid.reduce.store", + kxsBinary.serde(), + kxsBinary.serde>(), + ) + ) { chunkTiles, otherChunkTiles -> + chunkTiles + otherChunkTiles + } +} + + +private fun KTable>.enrichWithColourData( + protosTable: KTable, +): KTable> { + + val pid = "$pid.enrichWithColourData" + + return this.join( + other = protosTable, + tableJoined = tableJoined("$pid.join-tiles-with-prototypes"), + materialized = materializedAs( + "$pid.join-tiles-with-prototypes.store", + kxsBinary.serde(), + kxsBinary.serde(), + ), + foreignKeyExtractor = { chunkTiles: ServerMapChunkTiles -> + chunkTiles.chunkId.serverId + } + ) { tiles: ServerMapChunkTiles, colourDict: TileColourDict -> +// println("joining tiles:${tiles.map.size} with colourDict:${colourDict.map.size}") + + val missingProtos = mutableSetOf() + + val tileColours = tiles.map.mapValues { (_, code) -> + colourDict.map.getOrElse(code) { + missingProtos.add(code) + ColourHex.TRANSPARENT + } + } + + if (missingProtos.isNotEmpty()) { + println("[$pid] missing ${missingProtos.size} tile prototypes: ${missingProtos.joinToString { "${it.code}" }}") + } + + println("[$pid] Set tile colours for chunk ${tiles.chunkId}") + + ServerMapChunkTiles(tiles.chunkId, tileColours) + } +} + + +private fun KTable>.streamTo( + chunkSize: ChunkSize, + outputTopic: String = TOPIC_GROUPED_MAP_CHUNKS_STATE, +) { + val pid = "$pid.output-chunk.${chunkSize.name}" + + toStream("$pid.stream") + .filter("$pid.filter-tiles-not-empty") { _, v -> + !v?.map.isNullOrEmpty() + } + .mapValues("$pid.map-not-null") { _, v -> + requireNotNull(v) + } + .peek("$pid.print-group-result") { _, v -> + println("Grouping map tiles result: ${v.chunkId} / ${v.map.size}") + } + .to( + outputTopic, + producedAs( + "$pid.grouped-map-chunks", + kxsBinary.serde(), + kxsBinary.serde(), + ) + ) +} + + +///** +// * Group [MapChunkUpdate]s by the Chunk position. +// * +// * They should already be grouped, but do it again to make sure, and to filter out empty updates. +// */ +//private fun KTable>.groupByChunkPosition( +// chunkSize: ChunkSize = ChunkSize.CHUNK_032 +//): KTable> { +// +// val pid = "$pid.groupByChunkPosition.${chunkSize.name}" +// +// return toStream("$pid.intake-stream") +// .map("$pid.change-chunk-size") { chunkId: ServerMapChunkId, chunkTiles: ServerMapChunkTiles? -> +// +// val newChunkPosition = chunkId.chunkPosition +// .leftTopTile(chunkId.chunkSize) +// .toMapChunkPosition(chunkSize) +// +// val newId = chunkId.copy( +// chunkSize = chunkSize, +// chunkPosition = newChunkPosition, +// ) +// +// val newChunkTiles = chunkTiles?.map ?: emptyMap() +// +// newId to ServerMapChunkTiles(chunkId = newId, map = newChunkTiles) +// }.groupByKey( +// groupedAs( +// "$pid.group-by-key", +// kxsBinary.serde(), +// kxsBinary.serde>(), +// ) +// ).reduce( +// "$pid.reduce", +// materializedAs( +// "$pid.reduce.store", +// kxsBinary.serde(), +// kxsBinary.serde>(), +// ) +// ) { chunkTiles, otherChunkTiles -> +// chunkTiles + otherChunkTiles +// } +//} + +/** + * Group [MapChunkUpdate]s by the Chunk position. + * + * They should already be grouped, but do it again to make sure, and to filter out empty updates. + */ +private fun KStream>.groupByChunkPosition( + chunkSize: ChunkSize = ChunkSize.CHUNK_032 +): KTable> { + + val pid = "$pid.groupByChunkPosition.${chunkSize.name}" + + return map("$pid.change-chunk-size") { chunkId: ServerMapChunkId, chunkTiles: ServerMapChunkTiles? -> + + val newChunkPosition = chunkId.chunkPosition + .leftTopTile(chunkId.chunkSize) + .toMapChunkPosition(chunkSize) + + val newId = chunkId.copy( + chunkSize = chunkSize, + chunkPosition = newChunkPosition, + ) + + val newChunkTiles = chunkTiles?.map ?: emptyMap() + + newId to ServerMapChunkTiles(chunkId = newId, map = newChunkTiles) + }.groupByKey( + groupedAs( + "$pid.group-by-key", + kxsBinary.serde(), + kxsBinary.serde>(), + ) + ).reduce( + "$pid.reduce", + materializedAs( + "$pid.reduce.store", + kxsBinary.serde(), + kxsBinary.serde>(), + ) + ) { chunkTiles, otherChunkTiles -> + chunkTiles + otherChunkTiles + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt index eb87d07..f0c9e09 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt @@ -4,6 +4,7 @@ import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED import dev.adamko.kafkatorio.processor.misc.DebounceProcessor.Companion.addDebounceProcessor import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapTile @@ -61,7 +62,7 @@ fun groupMapChunks(builder: StreamsBuilder): Topology { val protosStream: KStream = builder.streamPacketData() val tileProtoColourDict: KTable = - tileProtoColourDictionary(protosStream) + protosStream.createTilePrototypeTable() val groupedMapChunkTiles: KTable> = groupTilesIntoChunksWithColours( @@ -128,7 +129,7 @@ private fun groupTilesIntoChunksWithColours( mapTiles .tiles .groupBy { tile -> - tile.position.toMapChunkPosition(standardChunkSize.lengthInTiles) + tile.position.toMapChunkPosition(standardChunkSize) } .map { (chunkPos, tiles) -> diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt index 44fb966..0a70dda 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt @@ -13,38 +13,3 @@ import kotlinx.serialization.Serializable value class FactorioServerId(private val id: String) { override fun toString() = id } - - -@Serializable -enum class ChunkSize( - val zoomLevel: Int, -) : Comparable { - CHUNK_512(-1), - CHUNK_256(0), - CHUNK_128(1), - CHUNK_064(2), - CHUNK_032(3), - ; - - /** 32, 64, 128, 256, or 512 */ - val lengthInTiles: Int = 2f.pow(8 - zoomLevel).roundToInt() - - init { - require(lengthInTiles > 0) { "tilesPerChunk $lengthInTiles must be positive" } - // 1000 & 0111 = 0000 => pow^2 - // 1001 & 1000 = 1000 => !pow^2 - require(lengthInTiles and (lengthInTiles - 1) == 0) { - "tilesPerChunk $lengthInTiles must be a power-of-two number" - } - } - - companion object { - // cache values for better performance. KT-48872 - val entries: Set = values().toSet() - - val MAX: ChunkSize = entries.maxByOrNull { it.lengthInTiles }!! - val MIN: ChunkSize = entries.minByOrNull { it.lengthInTiles }!! - val STANDARD: ChunkSize = entries.first { it.zoomLevel == 0 } - - } -} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt index ef10585..48a910a 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt @@ -2,15 +2,22 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.processor.WebsocketServer import dev.adamko.kafkatorio.processor.admin.topicName -import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.kxs.serde import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json import org.apache.kafka.streams.StreamsBuilder +private val jsonMapper: Json = Json { + prettyPrint = false + serializersModule = jsonMapperKafkatorio.serializersModule +} + + fun playerUpdatesToWsServer( websocketServer: WebsocketServer, builder: StreamsBuilder = StreamsBuilder(), diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index 19d0fba..7716819 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -32,12 +32,12 @@ value class TileColourDict(val map: Map) /** Get the latest map-tile colours per server. */ -fun tileProtoColourDictionary( - factorioServerPacketStream: KStream -): KTable { - val pid = "tileProtoColourDictionary" +fun KStream.createTilePrototypeTable() + : KTable { - return factorioServerPacketStream.mapValues( + val pid = "createTilePrototypeTable" + + return mapValues( "$pid.map-values" ) { _, protoPacket: PrototypesUpdate -> val map = protoPacket diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt index 71f062b..52ca06d 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt @@ -4,11 +4,13 @@ import com.sksamuel.scrimage.ImmutableImage import com.sksamuel.scrimage.ScaleMethod import com.sksamuel.scrimage.color.RGBColor import com.sksamuel.scrimage.nio.PngWriter +import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED import dev.adamko.kafkatorio.processor.admin.TOPIC_SUBDIVIDED_MAP_TILES import dev.adamko.kafkatorio.processor.admin.TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED import dev.adamko.kafkatorio.processor.misc.DebounceProcessor.Companion.addDebounceProcessor import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.MapTilePosition import dev.adamko.kafkatorio.schema.common.toMapChunkPosition @@ -42,28 +44,28 @@ fun saveMapTiles( tileDirectory: Path, ): Topology { - val groupedMapChunkTiles: KStream> = - builder.stream( - TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED, - consumedAs("$pid.consume.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()), - ) - - groupedMapChunkTiles - .flatMapSubdividedChunk() - .to( - TOPIC_SUBDIVIDED_MAP_TILES, - producedAs( - "$pid.produce.grouped-map-chunks", - kxsBinary.serde(), - kxsBinary.serde(), - ) - ) +// val groupedMapChunkTiles: KStream> = +// builder.stream( +// TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED, +// consumedAs("$pid.consume.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()), +// ) +// +// groupedMapChunkTiles +// .flatMapSubdividedChunk() +// .to( +// TOPIC_SUBDIVIDED_MAP_TILES, +// producedAs( +// "$pid.produce.grouped-map-chunks", +// kxsBinary.serde(), +// kxsBinary.serde(), +// ) +// ) val subdividedMapChunkTilesDebounced: KStream> = builder.stream( - TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED, + TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED, consumedAs( - "$pid.consume.debounced-subdivided-chunks", + "$pid.consume.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde(), ), @@ -74,8 +76,8 @@ fun saveMapTiles( return builder.build() .addDebounceProcessor>( namePrefix = pid, - sourceTopic = TOPIC_SUBDIVIDED_MAP_TILES, - sinkTopic = TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED, + sourceTopic = TOPIC_GROUPED_MAP_CHUNKS_STATE, + sinkTopic = TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED, inactivityDuration = 15.seconds, keySerde = kxsBinary.serde(), valueSerde = kxsBinary.serde(), @@ -83,35 +85,35 @@ fun saveMapTiles( } -private fun KStream>.flatMapSubdividedChunk() = - flatMap("$pid.subdivide-chunks") { initialKey, initialChunk -> - - val (chunks, time) = measureTimedValue { - ChunkSize.entries.flatMap { chunkSize -> - initialChunk.map - .entries - .groupingBy { (tilePosition, _) -> - val chunkPosition = tilePosition.toMapChunkPosition(chunkSize.lengthInTiles) - initialKey.copy( - chunkSize = chunkSize, - chunkPosition = chunkPosition, - ) - }.fold( - initialValueSelector = { _, _ -> mutableMapOf() } - ) { _, accumulator, (tilePosition, colour) -> - accumulator[tilePosition] = colour - accumulator - } - .map { (chunkId, tiles) -> - chunkId to ServerMapChunkTiles(chunkId, tiles) - } - } - } - - println("subdivided ${initialKey.chunkPosition} to ${chunks.size} chunks in $time") - - chunks - } +//private fun KStream>.flatMapSubdividedChunk() = +// flatMap("$pid.subdivide-chunks") { initialKey, initialChunk -> +// +// val (chunks, time) = measureTimedValue { +// ChunkSize.entries.flatMap { chunkSize -> +// initialChunk.map +// .entries +// .groupingBy { (tilePosition, _) -> +// val chunkPosition = tilePosition.toMapChunkPosition(chunkSize) +// initialKey.copy( +// chunkSize = chunkSize, +// chunkPosition = chunkPosition, +// ) +// }.fold( +// initialValueSelector = { _, _ -> mutableMapOf() } +// ) { _, accumulator, (tilePosition, colour) -> +// accumulator[tilePosition] = colour +// accumulator +// } +// .map { (chunkId, tiles) -> +// chunkId to ServerMapChunkTiles(chunkId, tiles) +// } +// } +// } +// +// println("subdivided ${initialKey.chunkPosition} to ${chunks.size} chunks in $time") +// +// chunks +// } private fun KStream>.forEachChunkSaveImage( diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt index 94ebdc0..22dd44b 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt @@ -1,6 +1,7 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapTilePosition @@ -142,11 +143,11 @@ class SaveMapChunksTest : FunSpec({ println("chunk size: ${chunkId.chunkSize} ${chunkId.chunkSize.lengthInTiles}") val map = chunkId.chunkPosition - .iterateTiles(chunkId.chunkSize.lengthInTiles) + .iterateTiles(chunkId.chunkSize) .asSequence() .map { tilePos -> val colour = - tileColours.getOrPut(tilePos.toMapChunkPosition(ChunkSize.MIN.lengthInTiles)) { + tileColours.getOrPut(tilePos.toMapChunkPosition(ChunkSize.MIN)) { colourHexArb().sample(RandomSource.default()).value } tilePos to colour From 7c77083c893440a5adc5c181e14d6c82c89048b4 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 12:51:27 +0200 Subject: [PATCH 335/629] handle etags in WebMapTileServer --- .../processor/tileserver/WebMapTileServer.kt | 113 +++++++++++++++++- 1 file changed, 109 insertions(+), 4 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt index db9f440..a61d7d9 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt @@ -1,10 +1,16 @@ package dev.adamko.kafkatorio.processor.tileserver import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import java.security.MessageDigest import kotlin.io.path.absolutePathString +import org.http4k.core.Filter import org.http4k.core.HttpHandler +import org.http4k.core.MemoryBody +import org.http4k.core.Method.GET +import org.http4k.core.Request +import org.http4k.core.Response +import org.http4k.core.Status import org.http4k.core.then -import org.http4k.filter.CachingFilters import org.http4k.routing.ResourceLoader import org.http4k.routing.RoutingHttpHandler import org.http4k.routing.bind @@ -12,15 +18,114 @@ import org.http4k.routing.routes import org.http4k.routing.static internal class WebMapTileServer( - appProps: ApplicationProperties = ApplicationProperties() + private val appProps: ApplicationProperties = ApplicationProperties() ) { + private val tilesLoader = ResourceLoader.Directory(appProps.webmapTileDir.absolutePathString()) + + private val filters = listOf( + ETagChecker()(), + ).reduce(Filter::then) + private val routes: RoutingHttpHandler = routes( - "/tiles" bind CachingFilters.Response.NoCache() - .then(static(ResourceLoader.Directory(appProps.webmapTileDir.absolutePathString()))) + "/tiles" bind GET to + static(tilesLoader).withFilter(filters) ) fun build(): HttpHandler { return routes } + + + inner class ETagChecker +// : CoroutineScope + { + +// private val tagState: MutableStateFlow> = +// MutableStateFlow(mutableMapOf()) +// +// override val coroutineContext: CoroutineContext = +// CoroutineName("ETagChecker") + +// Dispatchers.Unconfined + +// KafkatorioTopology.rootJob + +// init { +// launch { +// appProps.webmapTileDir +// .fileEventsFlow() +// .filterIsInstance() +// .filter { it.path.isRegularFile() } +//// .filter { it.path.extension == "png" } +// .runningFold(mutableMapOf()) { tags, event -> +//// println("[WebMapTileServer] handling file update ${event.path}") +// +// val relativePath = event.path +// .relativeTo(appProps.webmapTileDir) +// .invariantSeparatorsPathString +// +// when (event) { +// is KWatchEvent.Deleted -> tags.remove(relativePath) +// is KWatchEvent.Created, +// is KWatchEvent.Modified -> { +// val md5 = event.path.md5() +// if (md5 != null) { +// tags[relativePath] = md5 +// } else { +// println("null md5 for ${event.path}") +// } +// } +// } +// +// tags +// }.cancellable() +// .collect(tagState) +// } +// } + + + private val Request.etagKey: String get() = uri.path.removePrefix("/tiles/") + + + operator fun invoke() = Filter { next -> + { request -> + val requestedETag = request.header("If-None-Match") + + var response = next(request) + val responseBytes = response.body.stream.readAllBytes() + response.body.stream.close() + val currentETag = responseBytes.md5() + + response = response.body(MemoryBody(responseBytes)) + + when { + currentETag == null -> { +// println("[${request.etagKey}] currentETag is null (requested: $requestedETag), executing request") + response + .header("Cache-Control", "no-cache") + } + requestedETag == currentETag -> { + println("[${request.etagKey}] currentETag == requested, returning 302 $requestedETag") + Response(Status.NOT_MODIFIED) + .header("Cache-Control", "no-cache") + } + else -> { + println("[${request.etagKey}] currentETag != requested, executing request and adding currentETag:$currentETag (requested:$requestedETag)") + response + .header("ETag", currentETag) + .header("Cache-Control", "public, max-age=1, stale-while-revalidate=60, stale-if-error=300") + } + } + } + } + + private fun ByteArray.md5(): String? { + return if (isEmpty()) { + null + } else { + MessageDigest.getInstance("MD5") + .digest(this) + .joinToString("") { "%02x".format(it) } + } + } + } } From 775fd4c5b3a9dbecf0abe2b663d044180cbfb891 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 12:55:33 +0200 Subject: [PATCH 336/629] remove Supervisor jobs, allow exceptions to stop the whole application --- .../dev/adamko/kafkatorio/processor/KafkatorioTopology.kt | 2 +- .../kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 359ee48..6d4e693 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -32,7 +32,7 @@ internal class KafkatorioTopology( ) : CoroutineScope { override val coroutineContext: CoroutineContext = - Dispatchers.Default + SupervisorJob(rootJob) + CoroutineName("KafkatorioTopology") + Dispatchers.Default + rootJob + CoroutineName("KafkatorioTopology") fun start() { splitPackets() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt index 99721bb..aa03266 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt @@ -21,7 +21,7 @@ import org.http4k.websocket.WsStatus class WebsocketServer { // create a scope+job for the server - private val serverJob = SupervisorJob() + private val serverJob = KafkatorioTopology.rootJob private val serverScope = CoroutineScope(serverJob) private val clients: MutableSharedFlow = MutableSharedFlow( From fff143fcc373104f85b24326560fb299a7e4ac69 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 13:10:54 +0200 Subject: [PATCH 337/629] binser for lua encoding? --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index deb2e88..3f70388 100644 --- a/README.md +++ b/README.md @@ -74,3 +74,7 @@ https://www.npmjs.com/package/wasm2lua?activeTab=readme * bebop https://rainway.com/blog/2020/12/09/bebop-an-efficient-schema-based-binary-serialization-format/ + +* binser + * https://github.com/bakpakin/binser + * https://github.com/maxiy01/tstl-binser From 697a00b44391cfc4571c0e49f1639d178205e4e2 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 17:58:14 +0200 Subject: [PATCH 338/629] bump kvision, kotlinx serialization, factorio, and a few others --- buildSrc/build.gradle.kts | 56 ++++++------------- gradle/kotlin-js-store/yarn.lock | 40 +++---------- gradle/libs.versions.toml | 20 ++++--- .../src/main/typescript/package-lock.json | 14 ++--- .../src/main/typescript/package.json | 6 +- 5 files changed, 48 insertions(+), 88 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 571733a..59514df 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -7,50 +7,35 @@ plugins { `project-report` } - -object Versions { - const val jvmTarget = "11" - const val kotlinTarget = "1.6" - - const val kotlin = "1.6.21" - - const val gradleNodePlugin = "3.2.1" - const val gradleDockerComposePlugin = "0.15.2" - - const val kotlinXSerialization = "1.3.2" - const val kvision = "5.8.2" - const val semver = "1.1.2" - const val http4k = "4.19.1.0" - - const val kotest = "5.2.3" -} +val gradleJvmTarget = "11" +val gradleKotlinTarget = "1.6" dependencies { - implementation(enforcedPlatform("org.jetbrains.kotlin:kotlin-bom:${Versions.kotlin}")) + implementation(enforcedPlatform("org.jetbrains.kotlin:kotlin-bom:${libs.versions.kotlin.get()}")) implementation("org.jetbrains.kotlin:kotlin-serialization") implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${libs.versions.kotlin.get()}") - implementation(platform("org.jetbrains.kotlinx:kotlinx-serialization-bom:${Versions.kotlinXSerialization}")) + implementation(platform("org.jetbrains.kotlinx:kotlinx-serialization-bom:${libs.versions.kotlinx.serialization.get()}")) implementation("org.jetbrains.kotlinx:kotlinx-serialization-core") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json") // implementation("com.charleskorn.kaml:kaml:0.37.0") - implementation("com.github.node-gradle:gradle-node-plugin:${Versions.gradleNodePlugin}") + implementation("com.github.node-gradle:gradle-node-plugin:${libs.versions.gradleNodePlugin.get()}") - implementation("io.kotest:kotest-framework-multiplatform-plugin-gradle:${Versions.kotest}") + implementation("io.kotest:kotest-framework-multiplatform-plugin-gradle:${libs.versions.kotest.get()}") - implementation("io.kvision:io.kvision.gradle.plugin:${Versions.kvision}") + implementation("io.kvision:io.kvision.gradle.plugin:${libs.versions.kvision.get()}") - implementation("net.swiftzer.semver:semver:${Versions.semver}") + implementation("net.swiftzer.semver:semver:${libs.versions.semver.get()}") // https://github.com/avast/gradle-docker-compose-plugin - implementation("com.avast.gradle:gradle-docker-compose-plugin:${Versions.gradleDockerComposePlugin}") +// implementation("com.avast.gradle:gradle-docker-compose-plugin:${Versions.gradleDockerComposePlugin}") - implementation(platform("org.http4k:http4k-bom:${Versions.http4k}")) + implementation(platform("org.http4k:http4k-bom:${libs.versions.http4k.get()}")) implementation("org.http4k:http4k-core") implementation("org.http4k:http4k-client-okhttp") @@ -68,12 +53,12 @@ dependencies { // } //} -tasks.withType().all { +tasks.withType().configureEach { kotlinOptions { - jvmTarget = Versions.jvmTarget - apiVersion = Versions.kotlinTarget - languageVersion = Versions.kotlinTarget + jvmTarget = gradleJvmTarget + apiVersion = gradleKotlinTarget + languageVersion = gradleKotlinTarget } kotlinOptions.freeCompilerArgs += listOf( @@ -88,11 +73,11 @@ tasks.withType().all { kotlin { jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(Versions.jvmTarget)) + (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) } kotlinDslPluginOptions { - jvmTarget.set(Versions.jvmTarget) + jvmTarget.set(gradleJvmTarget) } } @@ -102,10 +87,3 @@ idea { isDownloadJavadoc = true } } - -// projects must be configuring hack - - -tasks.configureEach { - inputs.property("pRoJeCtS-mUsT-bE-cOnFiGuRiNg", System.currentTimeMillis()) -} diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index b774c5d..cd65097 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -109,7 +109,7 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== -"@types/geojson@*", "@types/geojson@7946.0.8": +"@types/geojson@7946.0.8": version "7946.0.8" resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA== @@ -134,13 +134,6 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== -"@types/leaflet@^1.7.7": - version "1.7.9" - resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.7.9.tgz#7993d34f14cfa88c45b3d490daba39a3a1be9a2b" - integrity sha512-H8vPgD49HKzqM41ArHGZM70g/tfhp8W+JcPxfnF+5H/Xvp+xiP+KQOUNWU8U89fqS1Jj3cpRY/+nbnaHFzwnFA== - dependencies: - "@types/geojson" "*" - "@types/minimatch@*": version "3.0.5" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" @@ -446,7 +439,7 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -async@^2.6.2, async@^2.6.4: +async@^2.6.2: version "2.6.4" resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== @@ -1037,11 +1030,6 @@ electron-to-chromium@^1.4.84: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.114.tgz#d85ec0808dd50b0cf6e6b262480ffd385f71c873" integrity sha512-gRwLpVYWHGbERPU6o8pKfR168V6enWEXzZc6zQNNXbgJ7UJna+9qzAIHY94+9KOv71D/CH+QebLA9pChD2q8zA== -element-resize-event@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/element-resize-event/-/element-resize-event-3.0.6.tgz#3a18efd4879ad615e979fd8bbf173b014987eb9a" - integrity sha512-sSeXY9rNDp86bJODW68pxLcy3A5FrPZfIgOrJHzqgYzX513Zq6/ytdBigp7KeJEpZZopBBSiO1cVuiRkZpNxLw== - emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -1258,7 +1246,7 @@ faye-websocket@^0.11.3: dependencies: websocket-driver ">=0.5.1" -fecha@^4.2.1: +fecha@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw== @@ -1314,11 +1302,6 @@ follow-redirects@^1.0.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc" integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA== -follow-redirects@^1.14.8: - version "1.14.9" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" - integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== - format-util@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" @@ -2000,7 +1983,7 @@ kvision-assets@^5.0.8: resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-5.0.8.tgz#f2220135a94b1330cb2ac8f1804b53f40a9bd711" integrity sha512-umq47D8z2W7cTYR/6RtJ+048mlsi5X515tcM/PFgDcbaI82Pd9EHv2m9520SxmBH6AD04GTweWNyUcKlPx9oZQ== -leaflet@^1.7.1: +leaflet@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.8.0.tgz#4615db4a22a304e8e692cae9270b983b38a2055e" integrity sha512-gwhMjFCQiYs3x/Sf+d49f10ERXaEFCPr+nVTryhAW8DWbMGqJqt9G4XuIaHmFW08zYvhgdzqXGr8AlW8v8dQkA== @@ -2216,7 +2199,7 @@ nanoid@3.1.25: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== -nanoid@^3.1.31, nanoid@^3.3.1: +nanoid@^3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== @@ -2236,11 +2219,6 @@ node-forge@^0.10.0: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== -node-forge@^1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" - integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== - node-releases@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" @@ -2875,10 +2853,10 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -snabbdom@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.4.0.tgz#c76ed02643729f84a63875b7894a0fbcdc95c710" - integrity sha512-Sr5H1l5QxJa0B/68ZtpWi7MuGIzLWS2Up64QqXe/wzvWOjXvM9rL7+C8GhMmDVtJ7dFWypvyWJHR3nmeZN8YIQ== +snabbdom@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.5.0.tgz#e75acbdedb26ea327c75028a433ba064db0ccf6e" + integrity sha512-Ff5BKG18KrrPuskHJlA9aujPHqEabItaDl96l7ZZndF4zt5AYSczz7ZjjgQAX5IBd5cd25lw9NfgX21yVUJ+9g== socket.io-adapter@~2.1.0: version "2.1.0" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e8d0aab..47bba69 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,18 +12,18 @@ kotlin = "1.6.21" camel-kafkaConnectors = "0.11.0" http4k = "4.25.12.0" kafka = "3.1.0" -kvision = "5.9.0" +kvision = "5.10.0" log4j2 = "2.17.2" qosLogback = "1.2.11" slf4j = "1.7.36" okio = "3.1.0" scrimage = "4.0.31" +semver = "1.2.0" -kotlinx-serialization = "1.3.2" +kotlinx-serialization = "1.3.3" kxs-yaml = "0.43.0" -#kotlinJsWrappers = "0.0.1-pre.331-kotlin-1.6.20" -kotlinJsWrappers = "0.0.1-pre.334" +kotlinJsWrappers = "0.0.1-pre.334" kotlinx-html = "0.7.5" kotlinx-nodejs = "0.0.7" kotlinx-coroutines = "1.6.1" @@ -34,13 +34,17 @@ ktor = "2.0.1" ## test ## junit = "5.8.2" kotest = "5.3.0" +mockk = "1.12.4" ## infra ## -factorio = "1.1.57" +factorio = "1.1.59" confluent-kafkaConnect = "7.0.1" grafana = "8.5.0" prometheus = "v2.34.0" +## gradle plugins ## +gradleNodePlugin = "3.2.1" + ######### [plugins] ######### @@ -50,8 +54,8 @@ kotlinJs = { id = "org.jetbrains.kotlin.js", vers kotlinSerialization = { id = "org.jetbrains.kotlin.kotlin-serialization", version.ref = "kotlin" } loggingCapabilities = { id = "dev.jacomet.logging-capabilities", version = "0.10.0" } -shadowJar = { id = "com.github.jengelman.gradle.plugins.shadow", version = "6.1.0" } -dependencyCheck = { id = "com.github.ben-manes.versions", version = "0.39.0" } +#shadowJar = { id = "com.github.jengelman.gradle.plugins.shadow", version = "6.1.0" } +#dependencyCheck = { id = "com.github.ben-manes.versions", version = "0.39.0" } ########### @@ -135,7 +139,7 @@ okio-core = { group = "com.squareup.okio", name = "okio" } ### test ### ############# -mockk = { group = "io.mockk", name = "mockk", version = "1.12.3" } +mockk = { group = "io.mockk", name = "mockk", version.ref = "mockk" } ## junit ## junit-bom = { group = "org.junit", name = "junit-bom", version.ref = "junit" } diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/src/main/typescript/package-lock.json index 876ae00..5237b02 100644 --- a/modules/events-mod/src/main/typescript/package-lock.json +++ b/modules/events-mod/src/main/typescript/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.4.0", + "version": "0.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -75,14 +75,14 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.0.0.tgz", - "integrity": "sha512-8JYdjizJKMUhEpaZ7SoVLQ+toe0XTebK/Zh/Iwwvs29x8Ml758XACX5Bn71LJK22u3obgu7YN2yn2GxZbQ554g==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.1.0.tgz", + "integrity": "sha512-SiUdkpEDblr0/Ntmj5uNaymC3HIdnw77iDzAsUScT0PZXsEZjDMeRguavhqHsjazYHOYCE/FS4oHoUHS8HMaWA==" }, "typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==" + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", + "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==" }, "typescript-to-lua": { "version": "1.4.4", diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/src/main/typescript/package.json index 76c3ef4..861f812 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/src/main/typescript/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.4.0", + "version": "0.5.0", "private": true, "scripts": { "build": "tstl", @@ -14,8 +14,8 @@ "dependencies": { "lua-types": "^2.11.0", "typescript-to-lua": "1.4.4", - "typed-factorio": "1.0.0", - "typescript": "4.6.3" + "typed-factorio": "1.1.0", + "typescript": "4.6.2" }, "license": "UNLICENSED", "peerDependencies": { From 89b7c772ffc8b3fa53ad8d5e010b5e6fa9de743a Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 17:58:37 +0200 Subject: [PATCH 339/629] try to fix pRoJeCtS mUsT bE cOnFiGuRiNg --- build.gradle.kts | 28 +----------------------- modules/web-map/build.gradle.kts | 37 +++++--------------------------- 2 files changed, 6 insertions(+), 59 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index ab20ab6..36b20a4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { `build-dashboard` // kotlin("multiplatform") apply false // try to stop error 'Projects must be configuring' - kotlin("js") apply false // try to stop error 'Projects must be configuring' +// kotlin("js") apply false // try to stop error 'Projects must be configuring' } group = "dev.adamko.kafkatorio" @@ -74,29 +74,3 @@ val runWebMap by tasks.registering { dependsOn(":modules:web-map:browserDevelopmentRun") } - -// projects must be configuring hack -val hackLinePrefix = "// projects must be configuring hack " - -gradle.beforeSettings { - - val buildGradleKts: File = -// project.buildFile - layout.projectDirectory.file("buildSrc/build.gradle.kts").asFile - - val hackedLines = buildGradleKts.readText() - .lines() - .joinToString(System.lineSeparator()) { - println("hacking $it") - when { - it.startsWith(hackLinePrefix) -> "$hackLinePrefix ${System.currentTimeMillis()}" - else -> it - } - } - - buildGradleKts.writeText(hackedLines) -} - -tasks.configureEach { - inputs.property("pRoJeCtS-mUsT-bE-cOnFiGuRiNg", System.currentTimeMillis()) -} diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 5d1ec15..0ff58e1 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -105,11 +105,11 @@ kotlin { implementation(libs.kotlinx.coroutines.core) - implementation(dependencies.platform(npm("follow-redirects", "^1.14.8"))) - implementation(dependencies.platform(npm("nanoid", "^3.1.31"))) - implementation(dependencies.platform(npm("minimist", "^1.2.6"))) - implementation(dependencies.platform(npm("async", "^2.6.4"))) - implementation(dependencies.platform(npm("node-forge", "^1.3.0"))) +// implementation(dependencies.platform(npm("follow-redirects", "^1.14.8"))) +// implementation(dependencies.platform(npm("nanoid", "^3.1.31"))) +// implementation(dependencies.platform(npm("minimist", "^1.2.6"))) +// implementation(dependencies.platform(npm("async", "^2.6.4"))) +// implementation(dependencies.platform(npm("node-forge", "^1.3.0"))) } // val webDir = file("src/main/web") @@ -160,30 +160,3 @@ fun KotlinDependencyHandler.kvision( // resolution("node-forge", "1.3.0") // } //} - -afterEvaluate { - rootProject.tasks.named("rootPackageJson").configure { - outputs.upToDateWhen { false } - inputs.property("cacheBuster", System.currentTimeMillis()) - } - rootProject.tasks.named("kotlinYarnSetup").configure { - outputs.upToDateWhen { false } - inputs.property("cacheBuster", System.currentTimeMillis()) - } - rootProject.tasks.named("kotlinNpmCachesSetup").configure { - outputs.upToDateWhen { false } - inputs.property("cacheBuster", System.currentTimeMillis()) - } - rootProject.tasks.named("kotlinStoreYarnLock").configure { - outputs.upToDateWhen { false } - inputs.property("cacheBuster", System.currentTimeMillis()) - } -} - -tasks.configureEach { - inputs.property("pRoJeCtS-mUsT-bE-cOnFiGuRiNg", System.currentTimeMillis()) -} - -rootProject.tasks.configureEach { - inputs.property("pRoJeCtS-mUsT-bE-cOnFiGuRiNg", System.currentTimeMillis()) -} From 867e22240b0e3edd5cdd7c6463db1c922a80e910 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 17:59:50 +0200 Subject: [PATCH 340/629] temp fix Type Factorio doc `{@link https}` bug --- modules/events-mod/build.gradle.kts | 55 +++++++++++++++++++ .../src/main/typescript/tsconfig.json | 3 +- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index a9b4ade..daa1985 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -69,6 +69,7 @@ val installEventsTsSchema by tasks.registering(Sync::class) { group = project.name dependsOn(typescriptEventsSchema) + dependsOn(fixLink) val outputDir = layout.projectDirectory.dir("src/main/typescript/generated/kafkatorio-schema") outputs.dir(outputDir) @@ -135,6 +136,60 @@ tasks.withType().configureEach { // } } +tasks.npmInstall { + nodeModulesOutputFilter { + exclude("**/typed-factorio/generated/classes.d.ts") + } +} + +interface ServiceProvider { + @get:Inject + val fs: FileSystemOperations +} + +val fixLink by tasks.registering { + dependsOn(tasks.npmInstall) + + + val badLink = """{@link https://lua-api.factorio.com/latest/Data-Lifecycle.html Data Lifecycle}""" + val goodLink = """https://lua-api.factorio.com/latest/Data-Lifecycle.html""" + + val typedFactorioDir = + layout.projectDirectory.dir("src/main/typescript/node_modules/typed-factorio") + val classesDTS = typedFactorioDir.file("generated/classes.d.ts") + + val services = project.objects.newInstance() + + inputs.file(classesDTS) + outputs.file(classesDTS) + + inputs.property("badLink", badLink) + inputs.property("goodLink", goodLink) + + doLast { + logger.lifecycle("fixing link ${classesDTS.asFile.canonicalPath}") + + services.fs.sync { + from(classesDTS) + into(temporaryDir) + filter { line -> + when { + line.contains(badLink) -> line.replace(badLink, goodLink) + else -> line + } + } + } + + services.fs.copy { + from(temporaryDir.resolve("classes.d.ts").canonicalPath) + into(classesDTS.asFile.parent) + duplicatesStrategy = DuplicatesStrategy.WARN + } + } +} + +tasks.assemble { dependsOn(fixLink) } + //val downloadFactorioApiDocs by tasks.registering { // group = project.name diff --git a/modules/events-mod/src/main/typescript/tsconfig.json b/modules/events-mod/src/main/typescript/tsconfig.json index 5587793..ae83187 100644 --- a/modules/events-mod/src/main/typescript/tsconfig.json +++ b/modules/events-mod/src/main/typescript/tsconfig.json @@ -19,7 +19,7 @@ ], "allowSyntheticDefaultImports": true, "esModuleInterop": true, - "explainFiles": true, + "explainFiles": false, "forceConsistentCasingInFileNames": true, "listEmittedFiles": true, "listFiles": true, @@ -39,6 +39,7 @@ "tstlVerbose": true, "noHeader": true, "noImplicitSelf": true, + "sourceMapTraceback": false, "luaLibImport": "require" } } From a3911560b91a95de94239280c31fde0f0b5f26bb Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 18:00:08 +0200 Subject: [PATCH 341/629] bump project version to 0.5.0 --- build.gradle.kts | 2 +- modules/infra-factorio-server/src/.env | 4 ++-- modules/infra-kafka-cluster/src/.env | 2 +- modules/infra-kafka-pipe/src/.env | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 36b20a4..bf22b84 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.4.0" +version = "0.5.0" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index 3d89e79..ebb5815 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -FACTORIO_VERSION=1.1.57 -KAFKATORIO_VERSION=0.4.0 +FACTORIO_VERSION=1.1.59 +KAFKATORIO_VERSION=0.5.0 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index bb45ded..0a2bf58 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,6 +1,6 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio GRAFANA_VERSION=8.5.0 -KAFKATORIO_VERSION=0.4.0 +KAFKATORIO_VERSION=0.5.0 KAFKA_VERSION=3.1.0 PROMETHEUS_VERSION=v2.34.0 diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index 469b75e..dddbc40 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.4.0 +KAFKATORIO_VERSION=0.5.0 From 28505c10406a7bad295ed73faa0a00f6216617a5 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 18:00:17 +0200 Subject: [PATCH 342/629] rm unused code comment --- .../processor/topology/colourMapChunks.kt | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt index 050d3a7..fc4e31f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt @@ -72,22 +72,6 @@ fun colourMapChunks(builder: StreamsBuilder): Topology { .streamTo(to, TOPIC_GROUPED_MAP_CHUNKS_STATE) } -// val chunkTilesColouredTable064 = -// chunkTilesColouredTable032.groupByChunkPosition(ChunkSize.CHUNK_064) -// chunkTilesColouredTable064.streamTo(ChunkSize.CHUNK_064, TOPIC_GROUPED_MAP_CHUNKS_STATE) -// -// val chunkTilesColouredTable128 = -// chunkTilesColouredTable064.groupByChunkPosition(ChunkSize.CHUNK_128) -// chunkTilesColouredTable128.streamTo(ChunkSize.CHUNK_128, TOPIC_GROUPED_MAP_CHUNKS_STATE) -// -// val chunkTilesColouredTable256 = -// chunkTilesColouredTable128.groupByChunkPosition(ChunkSize.CHUNK_256) -// chunkTilesColouredTable256.streamTo(ChunkSize.CHUNK_256, TOPIC_GROUPED_MAP_CHUNKS_STATE) -// -// val chunkTilesColouredTable512 = -// chunkTilesColouredTable256.groupByChunkPosition(ChunkSize.CHUNK_512) -// chunkTilesColouredTable512.streamTo(ChunkSize.CHUNK_512, TOPIC_GROUPED_MAP_CHUNKS_STATE) - return builder.build() } From f80722c187a54a5c785357ce1b419e622f2edfee Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 23:48:50 +0200 Subject: [PATCH 343/629] try to 'garbage collect' after refreshing tile img src --- .../main/kotlin/dev/adamko/kafkatorio/webmap/App.kt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index c7bc5a0..81cf098 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -69,18 +69,19 @@ class App( val imgSrc = img.src.substringBeforeLast('?') println("fetching $imgSrc") - val newImg = Image() + var newImg : Image? = Image() - newImg.onload = { + newImg!!.onload = { window.requestAnimationFrame { - println("image loaded ${newImg.src}") + println("image loaded ${newImg!!.src}") img.setAttribute("dynamic-reload", "true") - img.src = newImg.src + img.src = newImg!!.src + newImg = null // try to encourage garbage collection Unit } } - newImg.src = imgSrc //+ "?t=${currentTimeMillis()}" + newImg!!.src = imgSrc //+ "?t=${currentTimeMillis()}" } } } From f9b078b5a1e00911f4ac18a39e7016ea5f647398 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 23:49:37 +0200 Subject: [PATCH 344/629] when queuing chunks, print the min/max chunk coords --- .../src/main/typescript/main/commands/kafkatorioCommands.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts index 7e15a54..19a34c5 100644 --- a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts +++ b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts @@ -70,7 +70,7 @@ commands.add_command( } } } - player.print(`enqueued ${chunkCount} chunks`) + player.print(`enqueued ${chunkCount} chunks from [x:${chunkXMin}, y:${chunkYMin}] to [x:${chunkXMax}, y:${chunkYMax}]`) } } else if (paramUppercase.startsWith("INIT_GLOBAL")) { initGlobal(paramUppercase.startsWith("INIT_GLOBAL FORCE")) From 5291ac9484dc3f75bf9050a8874004db3100dd0f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 23:50:00 +0200 Subject: [PATCH 345/629] try to reduce delay when de-queueing events --- .../src/main/typescript/main/events/registerHandlers.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index 6e418e5..b2d9aa3 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -44,14 +44,14 @@ script.on_event( if (events.length > 0) { log(`[${event.tick}] dequed ${events.length} events, current size: ${Queue.size()}`) - let i = 100 + let i = 1 for (const event of events) { if (isEventType(event, defines.events.on_chunk_generated)) { let eName = Converters.eventNameString(event.name) - log(`[${event.tick}] dequed event ${eName}`) + log(`[${event.tick}] dequed event ${eName}, delay ${i}`) handleChunkGeneratedEvent(event, i) - i += 10 + i += 1 } } } From 11a537091e5b27ad96ad5fed30d1972a238d4d87 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 23:50:25 +0200 Subject: [PATCH 346/629] rm unused model MapTiles --- .../kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt index ef2ec02..be80d62 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt @@ -7,12 +7,6 @@ import kotlinx.serialization.Serializable const val MAP_CHUNK_SIZE = 32 -@Serializable -data class MapTiles( - val surfaceIndex: SurfaceIndex, - val tiles: List, -) - @Serializable data class MapTile( From 645a01643483905c1a48e714ea6683b29e94dbd4 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 14 May 2022 23:54:55 +0200 Subject: [PATCH 347/629] tidy up grouping, colouring, saving map chunks --- .../processor/KafkatorioTopology.kt | 1 - .../processor/admin/kafkatorioTopics.kt | 12 +- .../processor/topology/colourMapChunks.kt | 95 +- .../processor/topology/groupMapChunks.kt | 226 - .../kafkatorio/processor/topology/model.kt | 42 +- .../processor/topology/saveMapTiles.kt | 86 +- .../processor/misc/KxsBinaryTests.kt | 2 +- .../kafkatorio/processor/misc/serdeSize.kt | 1 - .../processor/topology/GroupMapChunksTest.kt | 4546 ++++++++--------- 9 files changed, 2359 insertions(+), 2652 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 6d4e693..342a85f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -3,7 +3,6 @@ package dev.adamko.kafkatorio.processor import dev.adamko.kafkatorio.processor.config.ApplicationProperties import dev.adamko.kafkatorio.processor.topology.colourMapChunks import dev.adamko.kafkatorio.processor.topology.factorioServerPacketStream -import dev.adamko.kafkatorio.processor.topology.groupMapChunks import dev.adamko.kafkatorio.processor.topology.playerUpdatesToWsServer import dev.adamko.kafkatorio.processor.topology.saveMapTiles import dev.adamko.kafkatorio.processor.topology.splitFactorioServerPacketStream diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt index d4c808f..bb287e0 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt @@ -17,7 +17,10 @@ private const val DOMAIN = "kafkatorio" const val TOPIC_SRC_SERVER_LOG = "$DOMAIN.src.server-log" const val TOPIC_GROUPED_MAP_CHUNKS_STATE = "$DOMAIN.state.map-chunks.grouped" -const val TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED = "$TOPIC_GROUPED_MAP_CHUNKS_STATE.debounced" + +const val TOPIC_MAP_CHUNK_COLOURED_032_STATE = "$DOMAIN.state.map-chunk-032.colour" + +const val TOPIC_MAP_CHUNK_COLOURED_STATE = "$DOMAIN.state.map-chunk.colour" const val TOPIC_SUBDIVIDED_MAP_TILES = "$DOMAIN.map-tiles.subdivided" const val TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED = "$TOPIC_SUBDIVIDED_MAP_TILES.debounced" @@ -25,8 +28,13 @@ const val TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED = "$TOPIC_SUBDIVIDED_MAP_TILES.de fun allTopics(): Set = buildSet { add(TOPIC_SRC_SERVER_LOG) + add(TOPIC_GROUPED_MAP_CHUNKS_STATE) - add(TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED) + + add(TOPIC_MAP_CHUNK_COLOURED_032_STATE) + + add(TOPIC_MAP_CHUNK_COLOURED_STATE) + add(TOPIC_SUBDIVIDED_MAP_TILES) add(TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt index fc4e31f..e9c7525 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt @@ -1,6 +1,8 @@ package dev.adamko.kafkatorio.processor.topology -import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE +import dev.adamko.kafkatorio.processor.admin.TOPIC_MAP_CHUNK_COLOURED_032_STATE +import dev.adamko.kafkatorio.processor.admin.TOPIC_MAP_CHUNK_COLOURED_STATE +import dev.adamko.kafkatorio.processor.misc.DebounceProcessor.Companion.addDebounceProcessor import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex @@ -24,6 +26,7 @@ import dev.adamko.kotka.extensions.tables.toStream import dev.adamko.kotka.kxs.serde import kotlin.collections.component1 import kotlin.collections.component2 +import kotlin.time.Duration.Companion.seconds import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.Topology import org.apache.kafka.streams.kstream.KStream @@ -48,31 +51,43 @@ fun colourMapChunks(builder: StreamsBuilder): Topology { .reduceServerMapChunkTilesToTable() .enrichWithColourData(protosTable) - chunkTilesColouredTable032.streamTo(ChunkSize.CHUNK_032, TOPIC_GROUPED_MAP_CHUNKS_STATE) - - val groupedMapChunks = builder.stream( - TOPIC_GROUPED_MAP_CHUNKS_STATE, - consumedAs( - "$pid.consume.grouped-map-chunks", - kxsBinary.serde(), - kxsBinary.serde>(), - ) + chunkTilesColouredTable032.streamMapChunkColouredTo( + ChunkSize.CHUNK_032, + TOPIC_MAP_CHUNK_COLOURED_032_STATE ) + val chunkTilesColoured032Debounced: KStream> = + builder.stream( + TOPIC_MAP_CHUNK_COLOURED_STATE, + consumedAs( + "$pid.consume.map-chunks-coloured", + kxsBinary.serde(), + kxsBinary.serde(), + ), + ) + mapOf( ChunkSize.CHUNK_032 to ChunkSize.CHUNK_064, ChunkSize.CHUNK_064 to ChunkSize.CHUNK_128, ChunkSize.CHUNK_128 to ChunkSize.CHUNK_256, ChunkSize.CHUNK_256 to ChunkSize.CHUNK_512, ).forEach { (from, to) -> - groupedMapChunks + chunkTilesColoured032Debounced .filter("$pid.combine-chunks.filter-$from-to-$to") { key, _ -> - key?.chunkSize == from - }.groupByChunkPosition(to) - .streamTo(to, TOPIC_GROUPED_MAP_CHUNKS_STATE) + key.chunkSize == from + }.groupByChunkPosition(to) + .streamMapChunkColouredTo(to, TOPIC_MAP_CHUNK_COLOURED_STATE) } return builder.build() + .addDebounceProcessor( + namePrefix = "groupTilesMapChunks", + sourceTopic = TOPIC_MAP_CHUNK_COLOURED_032_STATE, + sinkTopic = TOPIC_MAP_CHUNK_COLOURED_STATE, + inactivityDuration = 15.seconds, + keySerde = kxsBinary.serde(), + valueSerde = kxsBinary.serde>(), + ) } @@ -182,9 +197,9 @@ private fun KTable>.enr } -private fun KTable>.streamTo( +fun KTable>.streamMapChunkColouredTo( chunkSize: ChunkSize, - outputTopic: String = TOPIC_GROUPED_MAP_CHUNKS_STATE, + outputTopic: String, ) { val pid = "$pid.output-chunk.${chunkSize.name}" @@ -202,57 +217,13 @@ private fun KTable>.streamTo( outputTopic, producedAs( "$pid.grouped-map-chunks", - kxsBinary.serde(), - kxsBinary.serde(), + kxsBinary.serde(), + kxsBinary.serde>(), ) ) } -///** -// * Group [MapChunkUpdate]s by the Chunk position. -// * -// * They should already be grouped, but do it again to make sure, and to filter out empty updates. -// */ -//private fun KTable>.groupByChunkPosition( -// chunkSize: ChunkSize = ChunkSize.CHUNK_032 -//): KTable> { -// -// val pid = "$pid.groupByChunkPosition.${chunkSize.name}" -// -// return toStream("$pid.intake-stream") -// .map("$pid.change-chunk-size") { chunkId: ServerMapChunkId, chunkTiles: ServerMapChunkTiles? -> -// -// val newChunkPosition = chunkId.chunkPosition -// .leftTopTile(chunkId.chunkSize) -// .toMapChunkPosition(chunkSize) -// -// val newId = chunkId.copy( -// chunkSize = chunkSize, -// chunkPosition = newChunkPosition, -// ) -// -// val newChunkTiles = chunkTiles?.map ?: emptyMap() -// -// newId to ServerMapChunkTiles(chunkId = newId, map = newChunkTiles) -// }.groupByKey( -// groupedAs( -// "$pid.group-by-key", -// kxsBinary.serde(), -// kxsBinary.serde>(), -// ) -// ).reduce( -// "$pid.reduce", -// materializedAs( -// "$pid.reduce.store", -// kxsBinary.serde(), -// kxsBinary.serde>(), -// ) -// ) { chunkTiles, otherChunkTiles -> -// chunkTiles + otherChunkTiles -// } -//} - /** * Group [MapChunkUpdate]s by the Chunk position. * diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt index f0c9e09..272d386 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt @@ -1,227 +1 @@ package dev.adamko.kafkatorio.processor.topology - -import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE -import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED -import dev.adamko.kafkatorio.processor.misc.DebounceProcessor.Companion.addDebounceProcessor -import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kafkatorio.schema.common.ChunkSize -import dev.adamko.kafkatorio.schema.common.ColourHex -import dev.adamko.kafkatorio.schema.common.MapChunkPosition -import dev.adamko.kafkatorio.schema.common.MapTile -import dev.adamko.kafkatorio.schema.common.MapTileDictionary.Companion.isNullOrEmpty -import dev.adamko.kafkatorio.schema.common.MapTilePosition -import dev.adamko.kafkatorio.schema.common.MapTiles -import dev.adamko.kafkatorio.schema.common.SurfaceIndex -import dev.adamko.kafkatorio.schema.common.toMapChunkPosition -import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate -import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate -import dev.adamko.kotka.extensions.groupedAs -import dev.adamko.kotka.extensions.materializedAs -import dev.adamko.kotka.extensions.producedAs -import dev.adamko.kotka.extensions.repartitionedAs -import dev.adamko.kotka.extensions.streams.filter -import dev.adamko.kotka.extensions.streams.flatMap -import dev.adamko.kotka.extensions.streams.mapValues -import dev.adamko.kotka.extensions.streams.peek -import dev.adamko.kotka.extensions.streams.reduce -import dev.adamko.kotka.extensions.tableJoined -import dev.adamko.kotka.extensions.tables.join -import dev.adamko.kotka.extensions.tables.toStream -import dev.adamko.kotka.kxs.serde -import kotlin.collections.component1 -import kotlin.collections.component2 -import kotlin.time.Duration.Companion.seconds -import kotlinx.serialization.Serializable -import org.apache.kafka.streams.StreamsBuilder -import org.apache.kafka.streams.Topology -import org.apache.kafka.streams.kstream.KStream -import org.apache.kafka.streams.kstream.KTable - - -@Serializable -data class ServerMapChunkId( - val serverId: FactorioServerId, - val chunkPosition: MapChunkPosition, - val surfaceIndex: SurfaceIndex, - val chunkSize: ChunkSize, -) - - -@Serializable -data class ServerMapChunkTiles( - val chunkId: ServerMapChunkId, - val map: Map, -) { - operator fun plus(other: ServerMapChunkTiles) = copy(map = map + other.map) -} - - -fun groupMapChunks(builder: StreamsBuilder): Topology { - - val mapChunksStream: KStream = builder.streamPacketData() - val protosStream: KStream = builder.streamPacketData() - - val tileProtoColourDict: KTable = - protosStream.createTilePrototypeTable() - - val groupedMapChunkTiles: KTable> = - groupTilesIntoChunksWithColours( - mapChunksStream, - tileProtoColourDict, - ) - - val pid = "grouped-map-chunk-tiles.output" - groupedMapChunkTiles - .toStream("$pid.to-stream") - .filter("$pid.filter-tiles-not-empty") { _, v -> - !v?.map.isNullOrEmpty() - } - .mapValues("$pid.map-not-null") { _, v -> - requireNotNull(v) - } - .peek("$pid.print-group-result") { _, v -> - println("Grouping map tiles result: ${v.chunkId} / ${v.map.size}") - } - .to( - TOPIC_GROUPED_MAP_CHUNKS_STATE, - producedAs( - "$pid.grouped-map-chunks", - kxsBinary.serde(), - kxsBinary.serde(), - ) - ) - - return builder.build() - .addDebounceProcessor>( - namePrefix = pid, - sourceTopic = TOPIC_GROUPED_MAP_CHUNKS_STATE, - sinkTopic = TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED, - inactivityDuration = 15.seconds, - keySerde = kxsBinary.serde(), - valueSerde = kxsBinary.serde(), - ) -} - - -private fun groupTilesIntoChunksWithColours( - mapChunksStream: KStream, - tileProtoColourDict: KTable, -): KTable> { - - val mapTilesStream: KStream = - mapChunksStream.filter { _, value -> - !value.tileDictionary.isNullOrEmpty() - }.mapValues("map-chunk-update-packets.convert-to-map-tiles") { _, packet: MapChunkUpdate -> - val mapTiles = packet.tileDictionary?.toMapTileList() ?: emptyList() - MapTiles(packet.key.surfaceIndex, mapTiles) - }.filter("map-chunk-update-packets.filter-out.no-tiles") { _, value -> - value.tiles.isNotEmpty() - } - - val chunkedTilesTable: KTable> = - mapTilesStream - // group tiles by server & surface & chunk - .flatMap("server-map-data.tiles.flatMapByChunk") { serverId: FactorioServerId, mapTiles: MapTiles -> - - val standardChunkSize = ChunkSize.MAX - - val flatMappedChunkTiles: List>> = - mapTiles - .tiles - .groupBy { tile -> - tile.position.toMapChunkPosition(standardChunkSize) - } - .map { (chunkPos, tiles) -> - - val chunkId = ServerMapChunkId( - serverId = serverId, - chunkPosition = chunkPos, - surfaceIndex = mapTiles.surfaceIndex, - chunkSize = standardChunkSize, - ) - - val tilesMap = tiles.associate { it.position to TileProtoHashCode(it) } - - val chunkTiles = ServerMapChunkTiles(chunkId, tilesMap) - - chunkId to chunkTiles - } - -// println("[${System.currentTimeMillis()}] Flat-mapped ${flatMappedChunkTiles.size} chunk, with ${flatMappedChunkTiles.joinToString { it.second.map.size.toString() }} tiles") - - flatMappedChunkTiles - } - .filter("server-map-data.tiles.filter-not-empty") { _, value -> - value.map.isNotEmpty() - } - .repartition( - repartitionedAs( - "server-map-data.tiles.pre-table-repartition", - kxsBinary.serde(), - kxsBinary.serde(), - // force, otherwise KTable-KTable FK join doesn't work - numberOfPartitions = 1, - ) - ) - .groupByKey( - groupedAs( - "server-map-data.tiles.group", - kxsBinary.serde(), - kxsBinary.serde>(), - ) - ) - .reduce( - "server-map-data.tiles.reduce", - materializedAs( - "server-map-data.tiles.reduce.store", - kxsBinary.serde(), - kxsBinary.serde>(), - ) - ) { chunkTiles, other -> -// println( -// "[${System.currentTimeMillis()}] reducing tiles " + -// "chunkTiles:${chunkTiles.chunkId.chunkPosition}, ${chunkTiles.chunkId.chunkSize}, ${chunkTiles.map.size} " + -// "other:${other.chunkId.chunkPosition}, ${other.chunkId.chunkSize}, ${other.map.size}" -// ) - chunkTiles + other - } - - val colourisedChunkTable: KTable> = - chunkedTilesTable - .join( - other = tileProtoColourDict, - tableJoined = tableJoined("server-map-data.join-tiles-with-prototypes"), - materialized = materializedAs( - "server-map-data.join-tiles-with-prototypes.store", - kxsBinary.serde(), - kxsBinary.serde(), - ), - foreignKeyExtractor = { chunkTiles: ServerMapChunkTiles -> - chunkTiles.chunkId.serverId - } - ) { tiles: ServerMapChunkTiles, colourDict: TileColourDict -> -// println("joining tiles:${tiles.map.size} with colourDict:${colourDict.map.size}") - - val missingProtos = mutableSetOf() - - val tileColours = tiles.map.mapValues { (_, code) -> - colourDict.map.getOrElse(code) { - missingProtos.add(code) - ColourHex.TRANSPARENT - } - } - - if (missingProtos.isNotEmpty()) { - println("missing ${missingProtos.size} tile prototypes: ${missingProtos.joinToString { "${it.code}" }}") - } - - println("Set tile colours for chunk ${tiles.chunkId}") - - ServerMapChunkTiles(tiles.chunkId, tileColours) - } - - return colourisedChunkTable -} - -val MapTile.position - get() = MapTilePosition(x, y) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt index 0a70dda..496a2c4 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt @@ -1,10 +1,13 @@ package dev.adamko.kafkatorio.processor.topology import com.sksamuel.scrimage.color.RGBColor +import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.MapChunkPosition +import dev.adamko.kafkatorio.schema.common.MapTile +import dev.adamko.kafkatorio.schema.common.MapTilePosition +import dev.adamko.kafkatorio.schema.common.SurfaceIndex import java.awt.Color -import kotlin.math.pow -import kotlin.math.roundToInt import kotlinx.serialization.Serializable @@ -13,3 +16,38 @@ import kotlinx.serialization.Serializable value class FactorioServerId(private val id: String) { override fun toString() = id } + + +@Serializable +data class ServerMapChunkId( + val serverId: FactorioServerId, + val chunkPosition: MapChunkPosition, + val surfaceIndex: SurfaceIndex, + val chunkSize: ChunkSize, +) + + +@Serializable +data class ServerMapChunkTiles( + val chunkId: ServerMapChunkId, + val map: Map, +) { + operator fun plus(other: ServerMapChunkTiles) = copy(map = map + other.map) +} + + +val MapTile.position + get() = MapTilePosition(x, y) + + +val TRANSPARENT_AWT: Color = ColourHex.TRANSPARENT.toRgbColor().awt() + + +fun ColourHex.toRgbColor(): RGBColor { + return RGBColor( + red.toInt(), + green.toInt(), + blue.toInt(), + alpha.toInt(), + ) +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt index 52ca06d..348d165 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt @@ -2,30 +2,17 @@ package dev.adamko.kafkatorio.processor.topology import com.sksamuel.scrimage.ImmutableImage import com.sksamuel.scrimage.ScaleMethod -import com.sksamuel.scrimage.color.RGBColor import com.sksamuel.scrimage.nio.PngWriter -import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE -import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED -import dev.adamko.kafkatorio.processor.admin.TOPIC_SUBDIVIDED_MAP_TILES -import dev.adamko.kafkatorio.processor.admin.TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED -import dev.adamko.kafkatorio.processor.misc.DebounceProcessor.Companion.addDebounceProcessor +import dev.adamko.kafkatorio.processor.admin.TOPIC_MAP_CHUNK_COLOURED_STATE import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex -import dev.adamko.kafkatorio.schema.common.MapTilePosition -import dev.adamko.kafkatorio.schema.common.toMapChunkPosition import dev.adamko.kotka.extensions.consumedAs -import dev.adamko.kotka.extensions.producedAs -import dev.adamko.kotka.extensions.streams.flatMap import dev.adamko.kotka.extensions.streams.forEach import dev.adamko.kotka.kxs.serde -import java.awt.Color import java.awt.image.BufferedImage import java.nio.file.Path import kotlin.io.path.fileSize import kotlin.math.abs -import kotlin.time.Duration.Companion.seconds -import kotlin.time.measureTimedValue import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.Topology import org.apache.kafka.streams.kstream.KStream @@ -44,26 +31,9 @@ fun saveMapTiles( tileDirectory: Path, ): Topology { -// val groupedMapChunkTiles: KStream> = -// builder.stream( -// TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED, -// consumedAs("$pid.consume.grouped-map-chunks", kxsBinary.serde(), kxsBinary.serde()), -// ) -// -// groupedMapChunkTiles -// .flatMapSubdividedChunk() -// .to( -// TOPIC_SUBDIVIDED_MAP_TILES, -// producedAs( -// "$pid.produce.grouped-map-chunks", -// kxsBinary.serde(), -// kxsBinary.serde(), -// ) -// ) - val subdividedMapChunkTilesDebounced: KStream> = builder.stream( - TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED, + TOPIC_MAP_CHUNK_COLOURED_STATE, consumedAs( "$pid.consume.grouped-map-chunks", kxsBinary.serde(), @@ -74,48 +44,9 @@ fun saveMapTiles( subdividedMapChunkTilesDebounced.forEachChunkSaveImage(tileDirectory) return builder.build() - .addDebounceProcessor>( - namePrefix = pid, - sourceTopic = TOPIC_GROUPED_MAP_CHUNKS_STATE, - sinkTopic = TOPIC_GROUPED_MAP_CHUNKS_STATE_DEBOUNCED, - inactivityDuration = 15.seconds, - keySerde = kxsBinary.serde(), - valueSerde = kxsBinary.serde(), - ) } -//private fun KStream>.flatMapSubdividedChunk() = -// flatMap("$pid.subdivide-chunks") { initialKey, initialChunk -> -// -// val (chunks, time) = measureTimedValue { -// ChunkSize.entries.flatMap { chunkSize -> -// initialChunk.map -// .entries -// .groupingBy { (tilePosition, _) -> -// val chunkPosition = tilePosition.toMapChunkPosition(chunkSize) -// initialKey.copy( -// chunkSize = chunkSize, -// chunkPosition = chunkPosition, -// ) -// }.fold( -// initialValueSelector = { _, _ -> mutableMapOf() } -// ) { _, accumulator, (tilePosition, colour) -> -// accumulator[tilePosition] = colour -// accumulator -// } -// .map { (chunkId, tiles) -> -// chunkId to ServerMapChunkTiles(chunkId, tiles) -// } -// } -// } -// -// println("subdivided ${initialKey.chunkPosition} to ${chunks.size} chunks in $time") -// -// chunks -// } - - private fun KStream>.forEachChunkSaveImage( tileDirectory: Path, ) = forEach( @@ -186,16 +117,3 @@ value class TilePngFilename( append(".png") }) } - - -val TRANSPARENT_AWT: Color = ColourHex.TRANSPARENT.toRgbColor().awt() - - -fun ColourHex.toRgbColor(): RGBColor { - return RGBColor( - red.toInt(), - green.toInt(), - blue.toInt(), - alpha.toInt(), - ) -} diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt index 26cf707..a2b77f0 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt @@ -1,10 +1,10 @@ package dev.adamko.kafkatorio.processor.misc import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kafkatorio.processor.topology.ChunkSize import dev.adamko.kafkatorio.processor.topology.FactorioServerId import dev.adamko.kafkatorio.processor.topology.ServerMapChunkId import dev.adamko.kafkatorio.processor.topology.ServerMapChunkTiles +import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapTilePosition diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt index f68de10..aee7827 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt @@ -1,7 +1,6 @@ package dev.adamko.kafkatorio.processor.misc import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kafkatorio.processor.topology.ChunkSize import dev.adamko.kafkatorio.processor.topology.FactorioServerId import dev.adamko.kafkatorio.processor.topology.ServerMapChunkId import dev.adamko.kafkatorio.processor.topology.ServerMapChunkTiles diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt index c2ad3bf..98b0138 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt @@ -1,2280 +1,2280 @@ package dev.adamko.kafkatorio.processor.topology -import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE -import dev.adamko.kafkatorio.processor.serdes.jsonMapper -import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kafkatorio.schema.common.Colour -import dev.adamko.kafkatorio.schema.common.ColourHex -import dev.adamko.kafkatorio.schema.common.MapChunkPosition -import dev.adamko.kafkatorio.schema.common.MapTileDictionary -import dev.adamko.kafkatorio.schema.common.MapTileDictionary.PrototypeKey -import dev.adamko.kafkatorio.schema.common.MapTilePosition -import dev.adamko.kafkatorio.schema.common.PrototypeName -import dev.adamko.kafkatorio.schema.common.SurfaceIndex -import dev.adamko.kafkatorio.schema.common.Tick -import dev.adamko.kafkatorio.schema.common.toHex -import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket -import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate -import dev.adamko.kafkatorio.schema.packets.MapChunkUpdateKey -import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate -import dev.adamko.kafkatorio.schema.common.FactorioPrototype -import dev.adamko.kotka.kxs.serde -import io.kotest.assertions.withClue -import io.kotest.core.spec.style.FunSpec -import io.kotest.matchers.collections.shouldContainAnyOf -import io.kotest.matchers.collections.shouldHaveSize -import io.kotest.matchers.equality.shouldBeEqualToComparingFields -import io.kotest.matchers.nulls.shouldNotBeNull -import io.kotest.matchers.should -import kotlinx.serialization.decodeFromString -import org.apache.kafka.streams.StreamsBuilder -import org.apache.kafka.streams.TestInputTopic -import org.apache.kafka.streams.TestOutputTopic -import org.apache.kafka.streams.TopologyTestDriver - - -class GroupMapChunksTest : FunSpec({ - - test("proto, then map chunk") { - - val scenario = Scenario() - - scenario.pipePrototypePacket( - PrototypesUpdate(listOf(testMockTile)) - ) - - scenario.pipeMapChunkPacket(testMapChunkUpdate) - - val records = scenario.mapTilesOutputTopic.readRecordsToList() - - withClue(records) { - records shouldHaveSize 1 - - records.map { it.key to it.value }.first() should { (key, value) -> - key.shouldNotBeNull() - key shouldBeEqualToComparingFields ServerMapChunkId( - serverId = FactorioServerId("test-server-id"), - chunkPosition = MapChunkPosition(0, 0), - surfaceIndex = SurfaceIndex(1u), - chunkSize = ChunkSize.CHUNK_512, - ) - value.shouldNotBeNull() - value shouldBeEqualToComparingFields ServerMapChunkTiles( - chunkId = key, - map = mapOf( - MapTilePosition(1, 2) to ColourHex(76u, 51u, 25u, 255u) - ) - ) - } - } - } - - test("raw actual JSON messages") { - - val scenario = Scenario() - - val prototypesPacket: KafkatorioPacket = jsonMapper.decodeFromString(rawPrototypesJson) - scenario.prototypesInputTopic.pipeInput(scenario.serverId, prototypesPacket) - - val mapChunkPacket: KafkatorioPacket = jsonMapper.decodeFromString(rawMapChunkUpdateJson) - scenario.mapChunkInputTopic.pipeInput(scenario.serverId, mapChunkPacket) - - val records = scenario.mapTilesOutputTopic.readRecordsToList() - - records shouldHaveSize 1 - - records.map { it.key to it.value }.first() should { (key, value) -> - key.shouldNotBeNull() - key shouldBeEqualToComparingFields ServerMapChunkId( - serverId = FactorioServerId("test-server-id"), - chunkPosition = MapChunkPosition(-1, -1), - surfaceIndex = SurfaceIndex(1u), - chunkSize = ChunkSize.CHUNK_512, - ) - value.shouldNotBeNull() - - value.chunkId shouldBeEqualToComparingFields key - - value.map.values.toSet().shouldContainAnyOf( - (prototypesPacket.data as PrototypesUpdate).prototypes - .filterIsInstance() - .map { - it.mapColour.toHex() - }.toSet() - ) - - val top: Int = value.map.keys.minOf { it.y } - val bottom = value.map.keys.maxOf { it.y } - val left = value.map.keys.minOf { it.x } - val right = value.map.keys.maxOf { it.x } - - val colours: MutableMap = mutableMapOf(null to " ") - - val mapRepresentation = buildString { - (top..bottom).forEach { y -> - (left..right).forEach { x -> - val colour = value.map[MapTilePosition(x, y)] - val a = colours.getOrPut(colour) { "${colours.size}" } - append(a) - } - appendLine() - } - } - println(mapRepresentation) - - +//import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE +//import dev.adamko.kafkatorio.processor.serdes.jsonMapper +//import dev.adamko.kafkatorio.processor.serdes.kxsBinary +//import dev.adamko.kafkatorio.schema.common.Colour +//import dev.adamko.kafkatorio.schema.common.ColourHex +//import dev.adamko.kafkatorio.schema.common.MapChunkPosition +//import dev.adamko.kafkatorio.schema.common.MapTileDictionary +//import dev.adamko.kafkatorio.schema.common.MapTileDictionary.PrototypeKey +//import dev.adamko.kafkatorio.schema.common.MapTilePosition +//import dev.adamko.kafkatorio.schema.common.PrototypeName +//import dev.adamko.kafkatorio.schema.common.SurfaceIndex +//import dev.adamko.kafkatorio.schema.common.Tick +//import dev.adamko.kafkatorio.schema.common.toHex +//import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket +//import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate +//import dev.adamko.kafkatorio.schema.packets.MapChunkUpdateKey +//import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate +//import dev.adamko.kafkatorio.schema.common.FactorioPrototype +//import dev.adamko.kotka.kxs.serde +//import io.kotest.assertions.withClue +//import io.kotest.core.spec.style.FunSpec +//import io.kotest.matchers.collections.shouldContainAnyOf +//import io.kotest.matchers.collections.shouldHaveSize +//import io.kotest.matchers.equality.shouldBeEqualToComparingFields +//import io.kotest.matchers.nulls.shouldNotBeNull +//import io.kotest.matchers.should +//import kotlinx.serialization.decodeFromString +//import org.apache.kafka.streams.StreamsBuilder +//import org.apache.kafka.streams.TestInputTopic +//import org.apache.kafka.streams.TestOutputTopic +//import org.apache.kafka.streams.TopologyTestDriver +// +// +//class GroupMapChunksTest : FunSpec({ +// +// test("proto, then map chunk") { +// +// val scenario = Scenario() +// +// scenario.pipePrototypePacket( +// PrototypesUpdate(listOf(testMockTile)) +// ) +// +// scenario.pipeMapChunkPacket(testMapChunkUpdate) +// +// val records = scenario.mapTilesOutputTopic.readRecordsToList() +// +// withClue(records) { +// records shouldHaveSize 1 +// +// records.map { it.key to it.value }.first() should { (key, value) -> +// key.shouldNotBeNull() +// key shouldBeEqualToComparingFields ServerMapChunkId( +// serverId = FactorioServerId("test-server-id"), +// chunkPosition = MapChunkPosition(0, 0), +// surfaceIndex = SurfaceIndex(1u), +// chunkSize = ChunkSize.CHUNK_512, +// ) +// value.shouldNotBeNull() // value shouldBeEqualToComparingFields ServerMapChunkTiles( // chunkId = key, // map = mapOf( -// MapTilePosition(x=-224, y=-224) to ColourHex(red=91u, green=63u, blue=38u, alpha=255u), -// MapTilePosition(x=-224, y=-223) to ColourHex(red=91u, green=63u, blue=38u, alpha=255u), -// MapTilePosition(x=-224, y=-222) to ColourHex(red=91u, green=63u, blue=38u, alpha=255u), -// MapTilePosition(x=-224, y=-221) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), -// MapTilePosition(x=-224, y=-220) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), -// MapTilePosition(x=-224, y=-219) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), -// MapTilePosition(x=-224, y=-218) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), -// MapTilePosition(x=-224, y=-217) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), -// MapTilePosition(x=-224, y=-216) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), -// MapTilePosition(x=-224, y=-215) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), +// MapTilePosition(1, 2) to ColourHex(76u, 51u, 25u, 255u) // ) // ) - } - } - - test("map chunk, then proto") { - - val scenario = Scenario() - - scenario.pipePrototypePacket( - PrototypesUpdate(listOf(testMockTile.copy(mapColour = COLOUR_ONE))) - ) - - scenario.pipeMapChunkPacket(testMapChunkUpdate) - - var records = scenario.mapTilesOutputTopic.readRecordsToList() - - withClue(records) { - records shouldHaveSize 1 - - records.map { it.key to it.value }.first() should { (key, value) -> - key.shouldNotBeNull() - key shouldBeEqualToComparingFields ServerMapChunkId( - serverId = FactorioServerId("test-server-id"), - chunkPosition = MapChunkPosition(0, 0), - surfaceIndex = SurfaceIndex(1u), - chunkSize = ChunkSize.CHUNK_512, - ) - value.shouldNotBeNull() - value shouldBeEqualToComparingFields ServerMapChunkTiles( - chunkId = key, - map = mapOf( - MapTilePosition(1, 2) to ColourHex(25u, 25u, 25u, 25u) - ) - ) - } - } - - scenario.pipePrototypePacket( - PrototypesUpdate(listOf(testMockTile.copy(mapColour = COLOUR_TWO))) - ) - - records = scenario.mapTilesOutputTopic.readRecordsToList() - - withClue(records) { - records shouldHaveSize 1 - - records.map { it.key to it.value }.first() should { (key, value) -> - key.shouldNotBeNull() - key shouldBeEqualToComparingFields ServerMapChunkId( - serverId = FactorioServerId("test-server-id"), - chunkPosition = MapChunkPosition(0, 0), - surfaceIndex = SurfaceIndex(1u), - chunkSize = ChunkSize.CHUNK_512, - ) - value.shouldNotBeNull() - value shouldBeEqualToComparingFields ServerMapChunkTiles( - chunkId = key, - map = mapOf( - MapTilePosition(1, 2) to ColourHex(51u, 51u, 51u, 51u) - ) - ) - } - } - } -}) { - - class Scenario( - streamsBuilder: StreamsBuilder = StreamsBuilder(), - - prototypesTopicName: String = "kafkatorio.packet.prototypes", - mapChunkUpdatesTopicName: String = "kafkatorio.packet.map-chunk", - - val serverId: FactorioServerId = FactorioServerId("test-server-id"), - ) { - private val topology = groupMapChunks(streamsBuilder) - private val testDriver: TopologyTestDriver = TopologyTestDriver(topology) - - val prototypesInputTopic: TestInputTopic = - testDriver.createInputTopic( - prototypesTopicName, - jsonMapper.serde().serializer(), - jsonMapper.serde().serializer(), - ) - - val mapChunkInputTopic: TestInputTopic = - testDriver.createInputTopic( - mapChunkUpdatesTopicName, - jsonMapper.serde().serializer(), - jsonMapper.serde().serializer(), - ) - - val mapTilesOutputTopic: TestOutputTopic> = - testDriver.createOutputTopic( - TOPIC_GROUPED_MAP_CHUNKS_STATE, - kxsBinary.serde().deserializer(), - kxsBinary.serde>().deserializer(), - ) - - fun pipePrototypePacket(prototypeUpdate: PrototypesUpdate) { - prototypesInputTopic.pipeInput( - serverId, - KafkatorioPacket( - modVersion = "1.2.3", - tick = Tick(22u), - data = prototypeUpdate, - ) - ) - } - - fun pipeMapChunkPacket(mapChunkUpdate: MapChunkUpdate) { - mapChunkInputTopic.pipeInput( - serverId, - KafkatorioPacket( - modVersion = "1.2.3", - tick = Tick(44u), - data = mapChunkUpdate - ) - ) - } - } - - companion object { - val COLOUR_ONE = Colour(0.1f, 0.1f, 0.1f, 0.1f) - val COLOUR_TWO = Colour(0.2f, 0.2f, 0.2f, 0.2f) - - val testMockTile = FactorioPrototype.MapTile( - PrototypeName("fake-proto"), - layer = 1u, - mapColour = Colour(0.3f, 0.2f, 0.1f, 1.0f), - collisionMasks = listOf("fake-mask"), - order = "fake-order", - canBeMined = false, - ) - - val testMapChunkUpdate = MapChunkUpdate( - key = MapChunkUpdateKey( - MapChunkPosition(11, 22), - SurfaceIndex(1u), - ), - tileDictionary = MapTileDictionary( - tilesXY = mapOf( - "1" to mapOf("2" to PrototypeKey(33)) - ), - protos = mapOf(PrototypeName("fake-proto") to PrototypeKey(33)) - ) - ) - - const val rawMapChunkUpdateJson = """ - { - "modVersion": "0.4.0", - "tick": 36, - "data": { - "type": "kafkatorio.packet.keyed.MapChunkUpdate", - "key": { - "chunkPosition": [ - -7, - -7 - ], - "surfaceIndex": 1 - }, - "events": { - "on_chunk_generated": [1] - }, - "tileDictionary": { - "tilesXY": { - "-224": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 1, - "-220": 1, - "-219": 1, - "-218": 1, - "-217": 1, - "-216": 1, - "-215": 1, - "-214": 1, - "-213": 1, - "-212": 1, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 2, - "-206": 2, - "-205": 2, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-223": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 1, - "-218": 1, - "-217": 1, - "-216": 1, - "-215": 1, - "-214": 1, - "-213": 1, - "-212": 1, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 2, - "-206": 2, - "-205": 2, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-222": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 1, - "-217": 1, - "-216": 1, - "-215": 1, - "-214": 1, - "-213": 1, - "-212": 1, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 2, - "-206": 2, - "-205": 2, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-221": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 1, - "-216": 1, - "-215": 1, - "-214": 1, - "-213": 1, - "-212": 1, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 2, - "-206": 2, - "-205": 2, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 1 - }, - "-220": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 1, - "-215": 1, - "-214": 1, - "-213": 1, - "-212": 1, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 2, - "-205": 2, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-219": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 0, - "-213": 0, - "-212": 0, - "-211": 0, - "-210": 0, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 2, - "-205": 2, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-218": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 0, - "-213": 0, - "-212": 0, - "-211": 0, - "-210": 0, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 2, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-217": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 0, - "-213": 0, - "-212": 0, - "-211": 0, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-216": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 0, - "-213": 0, - "-212": 0, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-215": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 0, - "-213": 0, - "-212": 0, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-214": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 0, - "-213": 0, - "-212": 0, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 1, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-213": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 0, - "-213": 0, - "-212": 0, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 1, - "-203": 1, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 1 - }, - "-212": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 0, - "-213": 0, - "-212": 0, - "-211": 0, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 1, - "-203": 1, - "-202": 1, - "-201": 1, - "-200": 2, - "-199": 2, - "-198": 0, - "-197": 0, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 1 - }, - "-211": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 0, - "-213": 0, - "-212": 0, - "-211": 0, - "-210": 0, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 1, - "-203": 1, - "-202": 1, - "-201": 1, - "-200": 1, - "-199": 2, - "-198": 0, - "-197": 0, - "-196": 2, - "-195": 1, - "-194": 1, - "-193": 1 - }, - "-210": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 0, - "-213": 0, - "-212": 0, - "-211": 0, - "-210": 0, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 0, - "-205": 0, - "-204": 1, - "-203": 1, - "-202": 1, - "-201": 1, - "-200": 1, - "-199": 1, - "-198": 2, - "-197": 2, - "-196": 1, - "-195": 1, - "-194": 1, - "-193": 1 - }, - "-209": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 0, - "-213": 0, - "-212": 0, - "-211": 0, - "-210": 0, - "-209": 0, - "-208": 1, - "-207": 1, - "-206": 0, - "-205": 0, - "-204": 0, - "-203": 1, - "-202": 1, - "-201": 1, - "-200": 1, - "-199": 1, - "-198": 2, - "-197": 2, - "-196": 1, - "-195": 1, - "-194": 1, - "-193": 1 - }, - "-208": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 0, - "-213": 0, - "-212": 0, - "-211": 0, - "-210": 0, - "-209": 0, - "-208": 1, - "-207": 1, - "-206": 0, - "-205": 0, - "-204": 0, - "-203": 1, - "-202": 1, - "-201": 1, - "-200": 1, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 1, - "-195": 1, - "-194": 1, - "-193": 1 - }, - "-207": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 0, - "-213": 0, - "-212": 0, - "-211": 0, - "-210": 0, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 1, - "-203": 1, - "-202": 1, - "-201": 1, - "-200": 1, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 1, - "-195": 1, - "-194": 1, - "-193": 1 - }, - "-206": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 0, - "-213": 1, - "-212": 1, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 1, - "-203": 1, - "-202": 1, - "-201": 1, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 1, - "-196": 1, - "-195": 1, - "-194": 1, - "-193": 1 - }, - "-205": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 1, - "-213": 1, - "-212": 1, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 1, - "-203": 1, - "-202": 1, - "-201": 1, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 1, - "-196": 1, - "-195": 1, - "-194": 1, - "-193": 2 - }, - "-204": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 1, - "-215": 1, - "-214": 1, - "-213": 1, - "-212": 1, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 1, - "-203": 1, - "-202": 1, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 1, - "-196": 1, - "-195": 1, - "-194": 1, - "-193": 2 - }, - "-203": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 1, - "-216": 1, - "-215": 1, - "-214": 1, - "-213": 1, - "-212": 1, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 1, - "-203": 1, - "-202": 1, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 1, - "-194": 2, - "-193": 2 - }, - "-202": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 1, - "-216": 1, - "-215": 1, - "-214": 1, - "-213": 1, - "-212": 1, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 1, - "-203": 1, - "-202": 1, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-201": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 3, - "-217": 1, - "-216": 1, - "-215": 1, - "-214": 1, - "-213": 1, - "-212": 1, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 1, - "-203": 1, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-200": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 3, - "-218": 3, - "-217": 3, - "-216": 1, - "-215": 1, - "-214": 1, - "-213": 1, - "-212": 1, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 1, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-199": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 3, - "-218": 3, - "-217": 3, - "-216": 1, - "-215": 1, - "-214": 1, - "-213": 1, - "-212": 1, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-198": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 3, - "-218": 3, - "-217": 3, - "-216": 1, - "-215": 1, - "-214": 1, - "-213": 1, - "-212": 1, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 1, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-197": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 3, - "-218": 3, - "-217": 0, - "-216": 0, - "-215": 1, - "-214": 1, - "-213": 1, - "-212": 1, - "-211": 1, - "-210": 1, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 2, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-196": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 1, - "-214": 1, - "-213": 1, - "-212": 2, - "-211": 2, - "-210": 2, - "-209": 1, - "-208": 1, - "-207": 1, - "-206": 1, - "-205": 2, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-195": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 1, - "-213": 1, - "-212": 2, - "-211": 2, - "-210": 2, - "-209": 2, - "-208": 2, - "-207": 2, - "-206": 1, - "-205": 2, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-194": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 1, - "-213": 2, - "-212": 2, - "-211": 2, - "-210": 2, - "-209": 2, - "-208": 2, - "-207": 2, - "-206": 2, - "-205": 2, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - }, - "-193": { - "-224": 0, - "-223": 0, - "-222": 0, - "-221": 0, - "-220": 0, - "-219": 0, - "-218": 0, - "-217": 0, - "-216": 0, - "-215": 0, - "-214": 2, - "-213": 2, - "-212": 2, - "-211": 2, - "-210": 2, - "-209": 2, - "-208": 2, - "-207": 2, - "-206": 2, - "-205": 2, - "-204": 2, - "-203": 2, - "-202": 2, - "-201": 2, - "-200": 2, - "-199": 2, - "-198": 2, - "-197": 2, - "-196": 2, - "-195": 2, - "-194": 2, - "-193": 2 - } - }, - "protos": { - "dirt-5": 0, - "grass-2": 1, - "dirt-6": 2, - "red-desert-0": 3 - } - } - } - } - """ - - const val rawPrototypesJson = """ - { - "modVersion": "0.4.0", - "tick": 4352, - "data": { - "type": "kafkatorio.packet.instant.PrototypesUpdate", - "prototypes": [ - { - "type": "kafkatorio.prototype.MapTile", - "name": "stone-path", - "layer": 60, - "mapColour": [ - 86, - 82, - 74, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-a[tier-1]-a[stone-path]", - "canBeMined": true - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "concrete", - "layer": 61, - "mapColour": [ - 63, - 61, - 59, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-b[tier-2]-a[concrete]", - "canBeMined": true - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "hazard-concrete-left", - "layer": 62, - "mapColour": [ - 176, - 142, - 39, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-b[tier-2]-b[hazard-concrete-left]", - "canBeMined": true - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "hazard-concrete-right", - "layer": 62, - "mapColour": [ - 176, - 142, - 39, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-b[tier-2]-c[hazard-concrete-right]", - "canBeMined": true - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "refined-concrete", - "layer": 64, - "mapColour": [ - 49, - 48, - 45, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-c[tier-3]-a[refined-concrete]", - "canBeMined": true - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "refined-hazard-concrete-left", - "layer": 65, - "mapColour": [ - 116, - 94, - 26, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-c[tier-3]-b[refined-hazard-concrete-left]", - "canBeMined": true - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "refined-hazard-concrete-right", - "layer": 65, - "mapColour": [ - 116, - 94, - 26, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-c[tier-3]-c[refined-hazard-concrete-right]", - "canBeMined": true - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "landfill", - "layer": 57, - "mapColour": [ - 57, - 39, - 26, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-d[utility]-a[landfill]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "acid-refined-concrete", - "layer": 97, - "mapColour": [ - 142, - 194, - 40, - 127 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-e[color-concrete]-acid", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "black-refined-concrete", - "layer": 88, - "mapColour": [ - 25, - 25, - 25, - 127 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-e[color-concrete]-black", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "blue-refined-concrete", - "layer": 73, - "mapColour": [ - 39, - 137, - 228, - 127 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-e[color-concrete]-blue", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "brown-refined-concrete", - "layer": 91, - "mapColour": [ - 76, - 29, - 0, - 127 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-e[color-concrete]-brown", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "cyan-refined-concrete", - "layer": 94, - "mapColour": [ - 70, - 192, - 181, - 127 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-e[color-concrete]-cyan", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "green-refined-concrete", - "layer": 70, - "mapColour": [ - 23, - 195, - 43, - 127 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-e[color-concrete]-green", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "orange-refined-concrete", - "layer": 76, - "mapColour": [ - 221, - 127, - 33, - 127 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-e[color-concrete]-orange", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "pink-refined-concrete", - "layer": 82, - "mapColour": [ - 236, - 98, - 131, - 127 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-e[color-concrete]-pink", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "purple-refined-concrete", - "layer": 85, - "mapColour": [ - 123, - 28, - 168, - 127 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-e[color-concrete]-purple", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "red-refined-concrete", - "layer": 67, - "mapColour": [ - 207, - 6, - 0, - 127 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-e[color-concrete]-red", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "yellow-refined-concrete", - "layer": 79, - "mapColour": [ - 212, - 169, - 19, - 127 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "a[artificial]-e[color-concrete]-yellow", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "grass-1", - "layer": 26, - "mapColour": [ - 55, - 53, - 11, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-a[grass]-a[grass-1]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "grass-2", - "layer": 28, - "mapColour": [ - 66, - 57, - 15, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-a[grass]-b[grass-2]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "grass-3", - "layer": 29, - "mapColour": [ - 65, - 52, - 28, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-a[grass]-c[grass-3]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "grass-4", - "layer": 30, - "mapColour": [ - 59, - 40, - 18, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-a[grass]-d[grass-4]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "dry-dirt", - "layer": 18, - "mapColour": [ - 94, - 66, - 37, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-b[dirt]-a[dry-dirt]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "dirt-1", - "layer": 19, - "mapColour": [ - 141, - 104, - 60, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-b[dirt]-b[dirt-1]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "dirt-2", - "layer": 20, - "mapColour": [ - 136, - 96, - 59, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-b[dirt]-c[dirt-2]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "dirt-3", - "layer": 21, - "mapColour": [ - 133, - 92, - 53, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-b[dirt]-d[dirt-3]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "dirt-4", - "layer": 22, - "mapColour": [ - 103, - 72, - 43, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-b[dirt]-e[dirt-4]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "dirt-5", - "layer": 23, - "mapColour": [ - 91, - 63, - 38, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-b[dirt]-f[dirt-5]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "dirt-6", - "layer": 24, - "mapColour": [ - 80, - 55, - 31, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-b[dirt]-g[dirt-6]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "dirt-7", - "layer": 25, - "mapColour": [ - 80, - 54, - 28, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-b[dirt]-h[dirt-7]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "sand-1", - "layer": 8, - "mapColour": [ - 138, - 103, - 58, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-c[sand]-a[sand-1]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "sand-2", - "layer": 9, - "mapColour": [ - 128, - 93, - 52, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-c[sand]-b[sand-2]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "sand-3", - "layer": 10, - "mapColour": [ - 115, - 83, - 47, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-c[sand]-c[sand-3]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "red-desert-0", - "layer": 31, - "mapColour": [ - 103, - 70, - 32, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-d[red-desert]-a[red-desert-0]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "red-desert-1", - "layer": 14, - "mapColour": [ - 116, - 81, - 39, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-d[red-desert]-b[red-desert-1]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "red-desert-2", - "layer": 15, - "mapColour": [ - 116, - 84, - 43, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-d[red-desert]-c[red-desert-2]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "red-desert-3", - "layer": 16, - "mapColour": [ - 128, - 93, - 52, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "b[natural]-d[red-desert]-d[red-desert-3]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "water", - "layer": 3, - "mapColour": [ - 51, - 83, - 95, - 255 - ], - "collisionMasks": [ - "doodad-layer", - "item-layer", - "player-layer", - "resource-layer", - "water-tile" - ], - "order": "c[water]-a[water]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "deepwater", - "layer": 3, - "mapColour": [ - 38, - 64, - 73, - 255 - ], - "collisionMasks": [ - "doodad-layer", - "item-layer", - "player-layer", - "resource-layer", - "water-tile" - ], - "order": "c[water]-b[deep-water]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "water-green", - "layer": 3, - "mapColour": [ - 31, - 48, - 18, - 255 - ], - "collisionMasks": [ - "doodad-layer", - "item-layer", - "player-layer", - "resource-layer", - "water-tile" - ], - "order": "c[water]-c[water-green]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "deepwater-green", - "layer": 3, - "mapColour": [ - 23, - 37, - 16, - 255 - ], - "collisionMasks": [ - "doodad-layer", - "item-layer", - "player-layer", - "resource-layer", - "water-tile" - ], - "order": "c[water]-d[deepwater-green]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "water-shallow", - "layer": 6, - "mapColour": [ - 82, - 98, - 92, - 255 - ], - "collisionMasks": [ - "item-layer", - "object-layer", - "resource-layer", - "water-tile" - ], - "order": "c[water]-e[water-shallow]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "water-mud", - "layer": 7, - "mapColour": [ - 65, - 89, - 90, - 255 - ], - "collisionMasks": [ - "item-layer", - "object-layer", - "resource-layer", - "water-tile" - ], - "order": "c[water]-g[water-mud]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "nuclear-ground", - "layer": 33, - "mapColour": [ - 48, - 40, - 35, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "d[destruction]-a[nuclear]-a[nuclear-ground]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "water-wube", - "layer": 2, - "mapColour": [ - 0, - 0, - 0, - 255 - ], - "collisionMasks": [ - "doodad-layer", - "item-layer", - "player-layer", - "resource-layer", - "water-tile" - ], - "order": "x[wube]-a[water-wube]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "tile-unknown", - "layer": 0, - "mapColour": [ - 0, - 0, - 0, - 255 - ], - "collisionMasks": {}, - "order": "z-a", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "out-of-map", - "layer": 0, - "mapColour": [ - 0, - 0, - 0, - 255 - ], - "collisionMasks": [ - "doodad-layer", - "floor-layer", - "ground-tile", - "item-layer", - "object-layer", - "player-layer", - "resource-layer", - "water-tile" - ], - "order": "z[other]-a[out-of-map]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "lab-dark-1", - "layer": 70, - "mapColour": [ - 49, - 49, - 49, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "z[other]-b[lab]-a[lab-dark-1]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "lab-dark-2", - "layer": 70, - "mapColour": [ - 0, - 0, - 0, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "z[other]-b[lab]-b[lab-dark-2]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "lab-white", - "layer": 70, - "mapColour": [ - 255, - 255, - 255, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "z[other]-b[lab]-c[lab-white]", - "canBeMined": false - }, - { - "type": "kafkatorio.prototype.MapTile", - "name": "tutorial-grid", - "layer": 55, - "mapColour": [ - 122, - 122, - 122, - 255 - ], - "collisionMasks": [ - "ground-tile" - ], - "order": "z[other]-c[tutorial]-a[tutorial-grid]", - "canBeMined": false - } - ] - } - } - """ - } -} +// } +// } +// } +// +// test("raw actual JSON messages") { +// +// val scenario = Scenario() +// +// val prototypesPacket: KafkatorioPacket = jsonMapper.decodeFromString(rawPrototypesJson) +// scenario.prototypesInputTopic.pipeInput(scenario.serverId, prototypesPacket) +// +// val mapChunkPacket: KafkatorioPacket = jsonMapper.decodeFromString(rawMapChunkUpdateJson) +// scenario.mapChunkInputTopic.pipeInput(scenario.serverId, mapChunkPacket) +// +// val records = scenario.mapTilesOutputTopic.readRecordsToList() +// +// records shouldHaveSize 1 +// +// records.map { it.key to it.value }.first() should { (key, value) -> +// key.shouldNotBeNull() +// key shouldBeEqualToComparingFields ServerMapChunkId( +// serverId = FactorioServerId("test-server-id"), +// chunkPosition = MapChunkPosition(-1, -1), +// surfaceIndex = SurfaceIndex(1u), +// chunkSize = ChunkSize.CHUNK_512, +// ) +// value.shouldNotBeNull() +// +// value.chunkId shouldBeEqualToComparingFields key +// +// value.map.values.toSet().shouldContainAnyOf( +// (prototypesPacket.data as PrototypesUpdate).prototypes +// .filterIsInstance() +// .map { +// it.mapColour.toHex() +// }.toSet() +// ) +// +// val top: Int = value.map.keys.minOf { it.y } +// val bottom = value.map.keys.maxOf { it.y } +// val left = value.map.keys.minOf { it.x } +// val right = value.map.keys.maxOf { it.x } +// +// val colours: MutableMap = mutableMapOf(null to " ") +// +// val mapRepresentation = buildString { +// (top..bottom).forEach { y -> +// (left..right).forEach { x -> +// val colour = value.map[MapTilePosition(x, y)] +// val a = colours.getOrPut(colour) { "${colours.size}" } +// append(a) +// } +// appendLine() +// } +// } +// println(mapRepresentation) +// +// +//// value shouldBeEqualToComparingFields ServerMapChunkTiles( +//// chunkId = key, +//// map = mapOf( +//// MapTilePosition(x=-224, y=-224) to ColourHex(red=91u, green=63u, blue=38u, alpha=255u), +//// MapTilePosition(x=-224, y=-223) to ColourHex(red=91u, green=63u, blue=38u, alpha=255u), +//// MapTilePosition(x=-224, y=-222) to ColourHex(red=91u, green=63u, blue=38u, alpha=255u), +//// MapTilePosition(x=-224, y=-221) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), +//// MapTilePosition(x=-224, y=-220) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), +//// MapTilePosition(x=-224, y=-219) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), +//// MapTilePosition(x=-224, y=-218) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), +//// MapTilePosition(x=-224, y=-217) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), +//// MapTilePosition(x=-224, y=-216) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), +//// MapTilePosition(x=-224, y=-215) to ColourHex(red=66u, green=57u, blue=15u, alpha=255u), +//// ) +//// ) +// } +// } +// +// test("map chunk, then proto") { +// +// val scenario = Scenario() +// +// scenario.pipePrototypePacket( +// PrototypesUpdate(listOf(testMockTile.copy(mapColour = COLOUR_ONE))) +// ) +// +// scenario.pipeMapChunkPacket(testMapChunkUpdate) +// +// var records = scenario.mapTilesOutputTopic.readRecordsToList() +// +// withClue(records) { +// records shouldHaveSize 1 +// +// records.map { it.key to it.value }.first() should { (key, value) -> +// key.shouldNotBeNull() +// key shouldBeEqualToComparingFields ServerMapChunkId( +// serverId = FactorioServerId("test-server-id"), +// chunkPosition = MapChunkPosition(0, 0), +// surfaceIndex = SurfaceIndex(1u), +// chunkSize = ChunkSize.CHUNK_512, +// ) +// value.shouldNotBeNull() +// value shouldBeEqualToComparingFields ServerMapChunkTiles( +// chunkId = key, +// map = mapOf( +// MapTilePosition(1, 2) to ColourHex(25u, 25u, 25u, 25u) +// ) +// ) +// } +// } +// +// scenario.pipePrototypePacket( +// PrototypesUpdate(listOf(testMockTile.copy(mapColour = COLOUR_TWO))) +// ) +// +// records = scenario.mapTilesOutputTopic.readRecordsToList() +// +// withClue(records) { +// records shouldHaveSize 1 +// +// records.map { it.key to it.value }.first() should { (key, value) -> +// key.shouldNotBeNull() +// key shouldBeEqualToComparingFields ServerMapChunkId( +// serverId = FactorioServerId("test-server-id"), +// chunkPosition = MapChunkPosition(0, 0), +// surfaceIndex = SurfaceIndex(1u), +// chunkSize = ChunkSize.CHUNK_512, +// ) +// value.shouldNotBeNull() +// value shouldBeEqualToComparingFields ServerMapChunkTiles( +// chunkId = key, +// map = mapOf( +// MapTilePosition(1, 2) to ColourHex(51u, 51u, 51u, 51u) +// ) +// ) +// } +// } +// } +//}) { +// +// class Scenario( +// streamsBuilder: StreamsBuilder = StreamsBuilder(), +// +// prototypesTopicName: String = "kafkatorio.packet.prototypes", +// mapChunkUpdatesTopicName: String = "kafkatorio.packet.map-chunk", +// +// val serverId: FactorioServerId = FactorioServerId("test-server-id"), +// ) { +// private val topology = groupMapChunks(streamsBuilder) +// private val testDriver: TopologyTestDriver = TopologyTestDriver(topology) +// +// val prototypesInputTopic: TestInputTopic = +// testDriver.createInputTopic( +// prototypesTopicName, +// jsonMapper.serde().serializer(), +// jsonMapper.serde().serializer(), +// ) +// +// val mapChunkInputTopic: TestInputTopic = +// testDriver.createInputTopic( +// mapChunkUpdatesTopicName, +// jsonMapper.serde().serializer(), +// jsonMapper.serde().serializer(), +// ) +// +// val mapTilesOutputTopic: TestOutputTopic> = +// testDriver.createOutputTopic( +// TOPIC_GROUPED_MAP_CHUNKS_STATE, +// kxsBinary.serde().deserializer(), +// kxsBinary.serde>().deserializer(), +// ) +// +// fun pipePrototypePacket(prototypeUpdate: PrototypesUpdate) { +// prototypesInputTopic.pipeInput( +// serverId, +// KafkatorioPacket( +// modVersion = "1.2.3", +// tick = Tick(22u), +// data = prototypeUpdate, +// ) +// ) +// } +// +// fun pipeMapChunkPacket(mapChunkUpdate: MapChunkUpdate) { +// mapChunkInputTopic.pipeInput( +// serverId, +// KafkatorioPacket( +// modVersion = "1.2.3", +// tick = Tick(44u), +// data = mapChunkUpdate +// ) +// ) +// } +// } +// +// companion object { +// val COLOUR_ONE = Colour(0.1f, 0.1f, 0.1f, 0.1f) +// val COLOUR_TWO = Colour(0.2f, 0.2f, 0.2f, 0.2f) +// +// val testMockTile = FactorioPrototype.MapTile( +// PrototypeName("fake-proto"), +// layer = 1u, +// mapColour = Colour(0.3f, 0.2f, 0.1f, 1.0f), +// collisionMasks = listOf("fake-mask"), +// order = "fake-order", +// canBeMined = false, +// ) +// +// val testMapChunkUpdate = MapChunkUpdate( +// key = MapChunkUpdateKey( +// MapChunkPosition(11, 22), +// SurfaceIndex(1u), +// ), +// tileDictionary = MapTileDictionary( +// tilesXY = mapOf( +// "1" to mapOf("2" to PrototypeKey(33)) +// ), +// protos = mapOf(PrototypeName("fake-proto") to PrototypeKey(33)) +// ) +// ) +// +// const val rawMapChunkUpdateJson = """ +// { +// "modVersion": "0.4.0", +// "tick": 36, +// "data": { +// "type": "kafkatorio.packet.keyed.MapChunkUpdate", +// "key": { +// "chunkPosition": [ +// -7, +// -7 +// ], +// "surfaceIndex": 1 +// }, +// "events": { +// "on_chunk_generated": [1] +// }, +// "tileDictionary": { +// "tilesXY": { +// "-224": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 1, +// "-220": 1, +// "-219": 1, +// "-218": 1, +// "-217": 1, +// "-216": 1, +// "-215": 1, +// "-214": 1, +// "-213": 1, +// "-212": 1, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 2, +// "-206": 2, +// "-205": 2, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-223": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 1, +// "-218": 1, +// "-217": 1, +// "-216": 1, +// "-215": 1, +// "-214": 1, +// "-213": 1, +// "-212": 1, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 2, +// "-206": 2, +// "-205": 2, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-222": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 1, +// "-217": 1, +// "-216": 1, +// "-215": 1, +// "-214": 1, +// "-213": 1, +// "-212": 1, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 2, +// "-206": 2, +// "-205": 2, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-221": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 1, +// "-216": 1, +// "-215": 1, +// "-214": 1, +// "-213": 1, +// "-212": 1, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 2, +// "-206": 2, +// "-205": 2, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 1 +// }, +// "-220": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 1, +// "-215": 1, +// "-214": 1, +// "-213": 1, +// "-212": 1, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 2, +// "-205": 2, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-219": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 0, +// "-213": 0, +// "-212": 0, +// "-211": 0, +// "-210": 0, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 2, +// "-205": 2, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-218": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 0, +// "-213": 0, +// "-212": 0, +// "-211": 0, +// "-210": 0, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 2, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-217": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 0, +// "-213": 0, +// "-212": 0, +// "-211": 0, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-216": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 0, +// "-213": 0, +// "-212": 0, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-215": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 0, +// "-213": 0, +// "-212": 0, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-214": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 0, +// "-213": 0, +// "-212": 0, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 1, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-213": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 0, +// "-213": 0, +// "-212": 0, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 1, +// "-203": 1, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 1 +// }, +// "-212": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 0, +// "-213": 0, +// "-212": 0, +// "-211": 0, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 1, +// "-203": 1, +// "-202": 1, +// "-201": 1, +// "-200": 2, +// "-199": 2, +// "-198": 0, +// "-197": 0, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 1 +// }, +// "-211": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 0, +// "-213": 0, +// "-212": 0, +// "-211": 0, +// "-210": 0, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 1, +// "-203": 1, +// "-202": 1, +// "-201": 1, +// "-200": 1, +// "-199": 2, +// "-198": 0, +// "-197": 0, +// "-196": 2, +// "-195": 1, +// "-194": 1, +// "-193": 1 +// }, +// "-210": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 0, +// "-213": 0, +// "-212": 0, +// "-211": 0, +// "-210": 0, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 0, +// "-205": 0, +// "-204": 1, +// "-203": 1, +// "-202": 1, +// "-201": 1, +// "-200": 1, +// "-199": 1, +// "-198": 2, +// "-197": 2, +// "-196": 1, +// "-195": 1, +// "-194": 1, +// "-193": 1 +// }, +// "-209": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 0, +// "-213": 0, +// "-212": 0, +// "-211": 0, +// "-210": 0, +// "-209": 0, +// "-208": 1, +// "-207": 1, +// "-206": 0, +// "-205": 0, +// "-204": 0, +// "-203": 1, +// "-202": 1, +// "-201": 1, +// "-200": 1, +// "-199": 1, +// "-198": 2, +// "-197": 2, +// "-196": 1, +// "-195": 1, +// "-194": 1, +// "-193": 1 +// }, +// "-208": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 0, +// "-213": 0, +// "-212": 0, +// "-211": 0, +// "-210": 0, +// "-209": 0, +// "-208": 1, +// "-207": 1, +// "-206": 0, +// "-205": 0, +// "-204": 0, +// "-203": 1, +// "-202": 1, +// "-201": 1, +// "-200": 1, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 1, +// "-195": 1, +// "-194": 1, +// "-193": 1 +// }, +// "-207": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 0, +// "-213": 0, +// "-212": 0, +// "-211": 0, +// "-210": 0, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 1, +// "-203": 1, +// "-202": 1, +// "-201": 1, +// "-200": 1, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 1, +// "-195": 1, +// "-194": 1, +// "-193": 1 +// }, +// "-206": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 0, +// "-213": 1, +// "-212": 1, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 1, +// "-203": 1, +// "-202": 1, +// "-201": 1, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 1, +// "-196": 1, +// "-195": 1, +// "-194": 1, +// "-193": 1 +// }, +// "-205": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 1, +// "-213": 1, +// "-212": 1, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 1, +// "-203": 1, +// "-202": 1, +// "-201": 1, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 1, +// "-196": 1, +// "-195": 1, +// "-194": 1, +// "-193": 2 +// }, +// "-204": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 1, +// "-215": 1, +// "-214": 1, +// "-213": 1, +// "-212": 1, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 1, +// "-203": 1, +// "-202": 1, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 1, +// "-196": 1, +// "-195": 1, +// "-194": 1, +// "-193": 2 +// }, +// "-203": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 1, +// "-216": 1, +// "-215": 1, +// "-214": 1, +// "-213": 1, +// "-212": 1, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 1, +// "-203": 1, +// "-202": 1, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 1, +// "-194": 2, +// "-193": 2 +// }, +// "-202": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 1, +// "-216": 1, +// "-215": 1, +// "-214": 1, +// "-213": 1, +// "-212": 1, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 1, +// "-203": 1, +// "-202": 1, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-201": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 3, +// "-217": 1, +// "-216": 1, +// "-215": 1, +// "-214": 1, +// "-213": 1, +// "-212": 1, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 1, +// "-203": 1, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-200": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 3, +// "-218": 3, +// "-217": 3, +// "-216": 1, +// "-215": 1, +// "-214": 1, +// "-213": 1, +// "-212": 1, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 1, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-199": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 3, +// "-218": 3, +// "-217": 3, +// "-216": 1, +// "-215": 1, +// "-214": 1, +// "-213": 1, +// "-212": 1, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-198": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 3, +// "-218": 3, +// "-217": 3, +// "-216": 1, +// "-215": 1, +// "-214": 1, +// "-213": 1, +// "-212": 1, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 1, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-197": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 3, +// "-218": 3, +// "-217": 0, +// "-216": 0, +// "-215": 1, +// "-214": 1, +// "-213": 1, +// "-212": 1, +// "-211": 1, +// "-210": 1, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 2, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-196": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 1, +// "-214": 1, +// "-213": 1, +// "-212": 2, +// "-211": 2, +// "-210": 2, +// "-209": 1, +// "-208": 1, +// "-207": 1, +// "-206": 1, +// "-205": 2, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-195": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 1, +// "-213": 1, +// "-212": 2, +// "-211": 2, +// "-210": 2, +// "-209": 2, +// "-208": 2, +// "-207": 2, +// "-206": 1, +// "-205": 2, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-194": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 1, +// "-213": 2, +// "-212": 2, +// "-211": 2, +// "-210": 2, +// "-209": 2, +// "-208": 2, +// "-207": 2, +// "-206": 2, +// "-205": 2, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// }, +// "-193": { +// "-224": 0, +// "-223": 0, +// "-222": 0, +// "-221": 0, +// "-220": 0, +// "-219": 0, +// "-218": 0, +// "-217": 0, +// "-216": 0, +// "-215": 0, +// "-214": 2, +// "-213": 2, +// "-212": 2, +// "-211": 2, +// "-210": 2, +// "-209": 2, +// "-208": 2, +// "-207": 2, +// "-206": 2, +// "-205": 2, +// "-204": 2, +// "-203": 2, +// "-202": 2, +// "-201": 2, +// "-200": 2, +// "-199": 2, +// "-198": 2, +// "-197": 2, +// "-196": 2, +// "-195": 2, +// "-194": 2, +// "-193": 2 +// } +// }, +// "protos": { +// "dirt-5": 0, +// "grass-2": 1, +// "dirt-6": 2, +// "red-desert-0": 3 +// } +// } +// } +// } +// """ +// +// const val rawPrototypesJson = """ +// { +// "modVersion": "0.4.0", +// "tick": 4352, +// "data": { +// "type": "kafkatorio.packet.instant.PrototypesUpdate", +// "prototypes": [ +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "stone-path", +// "layer": 60, +// "mapColour": [ +// 86, +// 82, +// 74, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-a[tier-1]-a[stone-path]", +// "canBeMined": true +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "concrete", +// "layer": 61, +// "mapColour": [ +// 63, +// 61, +// 59, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-b[tier-2]-a[concrete]", +// "canBeMined": true +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "hazard-concrete-left", +// "layer": 62, +// "mapColour": [ +// 176, +// 142, +// 39, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-b[tier-2]-b[hazard-concrete-left]", +// "canBeMined": true +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "hazard-concrete-right", +// "layer": 62, +// "mapColour": [ +// 176, +// 142, +// 39, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-b[tier-2]-c[hazard-concrete-right]", +// "canBeMined": true +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "refined-concrete", +// "layer": 64, +// "mapColour": [ +// 49, +// 48, +// 45, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-c[tier-3]-a[refined-concrete]", +// "canBeMined": true +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "refined-hazard-concrete-left", +// "layer": 65, +// "mapColour": [ +// 116, +// 94, +// 26, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-c[tier-3]-b[refined-hazard-concrete-left]", +// "canBeMined": true +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "refined-hazard-concrete-right", +// "layer": 65, +// "mapColour": [ +// 116, +// 94, +// 26, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-c[tier-3]-c[refined-hazard-concrete-right]", +// "canBeMined": true +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "landfill", +// "layer": 57, +// "mapColour": [ +// 57, +// 39, +// 26, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-d[utility]-a[landfill]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "acid-refined-concrete", +// "layer": 97, +// "mapColour": [ +// 142, +// 194, +// 40, +// 127 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-e[color-concrete]-acid", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "black-refined-concrete", +// "layer": 88, +// "mapColour": [ +// 25, +// 25, +// 25, +// 127 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-e[color-concrete]-black", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "blue-refined-concrete", +// "layer": 73, +// "mapColour": [ +// 39, +// 137, +// 228, +// 127 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-e[color-concrete]-blue", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "brown-refined-concrete", +// "layer": 91, +// "mapColour": [ +// 76, +// 29, +// 0, +// 127 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-e[color-concrete]-brown", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "cyan-refined-concrete", +// "layer": 94, +// "mapColour": [ +// 70, +// 192, +// 181, +// 127 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-e[color-concrete]-cyan", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "green-refined-concrete", +// "layer": 70, +// "mapColour": [ +// 23, +// 195, +// 43, +// 127 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-e[color-concrete]-green", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "orange-refined-concrete", +// "layer": 76, +// "mapColour": [ +// 221, +// 127, +// 33, +// 127 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-e[color-concrete]-orange", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "pink-refined-concrete", +// "layer": 82, +// "mapColour": [ +// 236, +// 98, +// 131, +// 127 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-e[color-concrete]-pink", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "purple-refined-concrete", +// "layer": 85, +// "mapColour": [ +// 123, +// 28, +// 168, +// 127 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-e[color-concrete]-purple", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "red-refined-concrete", +// "layer": 67, +// "mapColour": [ +// 207, +// 6, +// 0, +// 127 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-e[color-concrete]-red", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "yellow-refined-concrete", +// "layer": 79, +// "mapColour": [ +// 212, +// 169, +// 19, +// 127 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "a[artificial]-e[color-concrete]-yellow", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "grass-1", +// "layer": 26, +// "mapColour": [ +// 55, +// 53, +// 11, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-a[grass]-a[grass-1]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "grass-2", +// "layer": 28, +// "mapColour": [ +// 66, +// 57, +// 15, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-a[grass]-b[grass-2]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "grass-3", +// "layer": 29, +// "mapColour": [ +// 65, +// 52, +// 28, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-a[grass]-c[grass-3]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "grass-4", +// "layer": 30, +// "mapColour": [ +// 59, +// 40, +// 18, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-a[grass]-d[grass-4]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "dry-dirt", +// "layer": 18, +// "mapColour": [ +// 94, +// 66, +// 37, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-b[dirt]-a[dry-dirt]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "dirt-1", +// "layer": 19, +// "mapColour": [ +// 141, +// 104, +// 60, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-b[dirt]-b[dirt-1]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "dirt-2", +// "layer": 20, +// "mapColour": [ +// 136, +// 96, +// 59, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-b[dirt]-c[dirt-2]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "dirt-3", +// "layer": 21, +// "mapColour": [ +// 133, +// 92, +// 53, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-b[dirt]-d[dirt-3]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "dirt-4", +// "layer": 22, +// "mapColour": [ +// 103, +// 72, +// 43, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-b[dirt]-e[dirt-4]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "dirt-5", +// "layer": 23, +// "mapColour": [ +// 91, +// 63, +// 38, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-b[dirt]-f[dirt-5]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "dirt-6", +// "layer": 24, +// "mapColour": [ +// 80, +// 55, +// 31, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-b[dirt]-g[dirt-6]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "dirt-7", +// "layer": 25, +// "mapColour": [ +// 80, +// 54, +// 28, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-b[dirt]-h[dirt-7]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "sand-1", +// "layer": 8, +// "mapColour": [ +// 138, +// 103, +// 58, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-c[sand]-a[sand-1]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "sand-2", +// "layer": 9, +// "mapColour": [ +// 128, +// 93, +// 52, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-c[sand]-b[sand-2]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "sand-3", +// "layer": 10, +// "mapColour": [ +// 115, +// 83, +// 47, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-c[sand]-c[sand-3]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "red-desert-0", +// "layer": 31, +// "mapColour": [ +// 103, +// 70, +// 32, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-d[red-desert]-a[red-desert-0]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "red-desert-1", +// "layer": 14, +// "mapColour": [ +// 116, +// 81, +// 39, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-d[red-desert]-b[red-desert-1]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "red-desert-2", +// "layer": 15, +// "mapColour": [ +// 116, +// 84, +// 43, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-d[red-desert]-c[red-desert-2]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "red-desert-3", +// "layer": 16, +// "mapColour": [ +// 128, +// 93, +// 52, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "b[natural]-d[red-desert]-d[red-desert-3]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "water", +// "layer": 3, +// "mapColour": [ +// 51, +// 83, +// 95, +// 255 +// ], +// "collisionMasks": [ +// "doodad-layer", +// "item-layer", +// "player-layer", +// "resource-layer", +// "water-tile" +// ], +// "order": "c[water]-a[water]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "deepwater", +// "layer": 3, +// "mapColour": [ +// 38, +// 64, +// 73, +// 255 +// ], +// "collisionMasks": [ +// "doodad-layer", +// "item-layer", +// "player-layer", +// "resource-layer", +// "water-tile" +// ], +// "order": "c[water]-b[deep-water]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "water-green", +// "layer": 3, +// "mapColour": [ +// 31, +// 48, +// 18, +// 255 +// ], +// "collisionMasks": [ +// "doodad-layer", +// "item-layer", +// "player-layer", +// "resource-layer", +// "water-tile" +// ], +// "order": "c[water]-c[water-green]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "deepwater-green", +// "layer": 3, +// "mapColour": [ +// 23, +// 37, +// 16, +// 255 +// ], +// "collisionMasks": [ +// "doodad-layer", +// "item-layer", +// "player-layer", +// "resource-layer", +// "water-tile" +// ], +// "order": "c[water]-d[deepwater-green]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "water-shallow", +// "layer": 6, +// "mapColour": [ +// 82, +// 98, +// 92, +// 255 +// ], +// "collisionMasks": [ +// "item-layer", +// "object-layer", +// "resource-layer", +// "water-tile" +// ], +// "order": "c[water]-e[water-shallow]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "water-mud", +// "layer": 7, +// "mapColour": [ +// 65, +// 89, +// 90, +// 255 +// ], +// "collisionMasks": [ +// "item-layer", +// "object-layer", +// "resource-layer", +// "water-tile" +// ], +// "order": "c[water]-g[water-mud]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "nuclear-ground", +// "layer": 33, +// "mapColour": [ +// 48, +// 40, +// 35, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "d[destruction]-a[nuclear]-a[nuclear-ground]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "water-wube", +// "layer": 2, +// "mapColour": [ +// 0, +// 0, +// 0, +// 255 +// ], +// "collisionMasks": [ +// "doodad-layer", +// "item-layer", +// "player-layer", +// "resource-layer", +// "water-tile" +// ], +// "order": "x[wube]-a[water-wube]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "tile-unknown", +// "layer": 0, +// "mapColour": [ +// 0, +// 0, +// 0, +// 255 +// ], +// "collisionMasks": {}, +// "order": "z-a", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "out-of-map", +// "layer": 0, +// "mapColour": [ +// 0, +// 0, +// 0, +// 255 +// ], +// "collisionMasks": [ +// "doodad-layer", +// "floor-layer", +// "ground-tile", +// "item-layer", +// "object-layer", +// "player-layer", +// "resource-layer", +// "water-tile" +// ], +// "order": "z[other]-a[out-of-map]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "lab-dark-1", +// "layer": 70, +// "mapColour": [ +// 49, +// 49, +// 49, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "z[other]-b[lab]-a[lab-dark-1]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "lab-dark-2", +// "layer": 70, +// "mapColour": [ +// 0, +// 0, +// 0, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "z[other]-b[lab]-b[lab-dark-2]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "lab-white", +// "layer": 70, +// "mapColour": [ +// 255, +// 255, +// 255, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "z[other]-b[lab]-c[lab-white]", +// "canBeMined": false +// }, +// { +// "type": "kafkatorio.prototype.MapTile", +// "name": "tutorial-grid", +// "layer": 55, +// "mapColour": [ +// 122, +// 122, +// 122, +// 255 +// ], +// "collisionMasks": [ +// "ground-tile" +// ], +// "order": "z[other]-c[tutorial]-a[tutorial-grid]", +// "canBeMined": false +// } +// ] +// } +// } +// """ +// } +//} From 98c585b201530966d8926dd7600db88241ea2f3c Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 15 May 2022 12:24:19 +0200 Subject: [PATCH 348/629] map tiles notes --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 3f70388..ea63a00 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,10 @@ is provided. * tick-rate - how often reports are generated * requires on some sort of in-mod cache of map * also divide by game-speed? to keep ratio the same +* Move to a vector tile supported map. PNGs are slow. + * Maplibre GL JS? https://maplibre.org/maplibre-gl-js-docs/example/ + * Add VectorGrid? https://leaflet.github.io/Leaflet.VectorGrid/vectorgrid-api-docs.html + * https://leaflet.github.io/Leaflet.VectorGrid/vectorgrid-api-docs.html#styling-vectorgrids ### to investigate: From ecc0a24b706ff49d4df00eb171b1e3380644396f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 15 May 2022 13:07:33 +0200 Subject: [PATCH 349/629] disable configure de mand, try to fix 'projects must be configuring' --- gradle.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gradle.properties b/gradle.properties index 8e74cde..34055e9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,3 +18,6 @@ io.kvision.plugin.enableWebpackVersions=false io.kvision.plugin.enableHiddenKotlinJsStore=false io.kvision.plugin.enableSecureResolutions=false io.kvision.plugin.enableBackendTasks=false + +# pRoJeCtS mUsT bE cOnFiGuRiNg +org.gradle.configureondemand=false From d44d4dbd01924bfff9656f7cec41f9bc1911fcd3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 15 May 2022 13:08:36 +0200 Subject: [PATCH 350/629] try to fix project tokens null null null null bug --- modules/events-mod/build.gradle.kts | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index daa1985..d48c960 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -19,7 +19,13 @@ description = "Sends in-game information to a server over the internet (requires // - filename: `mod-name_version.zip` // - zip contains one directory, `mod-name` -val modName: String by extra { "${rootProject.name}-events" } + +//val modName: String by extra { "${rootProject.name}-events" } +extra.set("modName", "kafkatorio-events") +val modName = extra.get("modName") as String + +val modDescription: String by project.extra { project.description ?: "" } + val distributionZipName: String by extra { "${modName}_${rootProject.version}.zip" } // version of Factorio that the mod is compatible with (must only be "major.minor" - patch causes error) @@ -27,13 +33,17 @@ val modFactorioCompatibility: Provider = libs.versions.factorio.map { SemVer.parse(it).run { "$major.$minor" } } val licenseFile: RegularFile by rootProject.extra -val projectTokens: MapProperty by rootProject.extra -val modDescription: String by project.extra { project.description ?: "" } -projectTokens.apply { + +@Suppress("UNCHECKED_CAST") +val projectTokens: MapProperty = + rootProject.extra.get("projectTokens") as? MapProperty ?: error("error getting projectTokens") +//val projectTokens: MapProperty by rootProject.extra + +val projectTokensX = projectTokens.apply { put("mod.name", modName) put("mod.title", "Kafkatorio Events") put("mod.description", modDescription) - put("factorio.version", modFactorioCompatibility) + put("factorio.version", modFactorioCompatibility.get()) } val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") @@ -96,8 +106,10 @@ val installEventsTsSchema by tasks.registering(Sync::class) { val zipNameProvider = provider { distributionZipName } tasks.distZip { + val projectTokensXX = projectTokensX + inputs.property("zipNameProvider", zipNameProvider) - inputs.property("projectTokens", projectTokens) + inputs.property("projectTokens", projectTokensXX) archiveFileName.set(zipNameProvider) } @@ -130,7 +142,8 @@ distributions { tasks.withType().configureEach { - inputs.property("projectTokens", projectTokens) + val projectTokensXX = projectTokensX + inputs.property("projectTokens", projectTokensXX) // if (name.startsWith("dist")) { // notCompatibleWithConfigurationCache("NPE on projectTokens") // } From 6eb99a841c340f19a5e34cafc0ff71d69141c029 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 15 May 2022 13:09:12 +0200 Subject: [PATCH 351/629] close input stream with .use { } --- .../adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt index a61d7d9..d2f63c5 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt @@ -91,8 +91,7 @@ internal class WebMapTileServer( val requestedETag = request.header("If-None-Match") var response = next(request) - val responseBytes = response.body.stream.readAllBytes() - response.body.stream.close() + val responseBytes = response.body.stream.use { it.readAllBytes() } val currentETag = responseBytes.md5() response = response.body(MemoryBody(responseBytes)) From e2781e7bf249ab96a66108cc44b049c8412bf144 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 15 May 2022 13:09:37 +0200 Subject: [PATCH 352/629] make some saveTiles code private --- .../dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt index 348d165..c792940 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt @@ -81,7 +81,7 @@ private fun KStream>.forEachChu @Synchronized -fun saveTile( +private fun saveTile( filename: TilePngFilename, tileDirectory: Path, img: ImmutableImage, @@ -106,7 +106,7 @@ fun saveTile( @JvmInline -value class TilePngFilename( +private value class TilePngFilename( val value: String, ) { constructor(id: ServerMapChunkId) : this(buildString { From 6edf5415d0c65a0162235e07780c3f21fb1239ee Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 15 May 2022 13:10:00 +0200 Subject: [PATCH 353/629] reduce logging in webmap console --- .../src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index 81cf098..889868f 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -67,18 +67,17 @@ class App( .filterIsInstance() .map { img -> val imgSrc = img.src.substringBeforeLast('?') - println("fetching $imgSrc") +// println("fetching $imgSrc") - var newImg : Image? = Image() + var newImg: Image? = Image() newImg!!.onload = { window.requestAnimationFrame { - println("image loaded ${newImg!!.src}") +// println("image loaded ${newImg!!.src}") img.setAttribute("dynamic-reload", "true") img.src = newImg!!.src newImg = null // try to encourage garbage collection - Unit } } newImg!!.src = imgSrc //+ "?t=${currentTimeMillis()}" From 0f08eee56f3f29b5c0333b88b1a44aefa2d96d65 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 15 May 2022 13:10:14 +0200 Subject: [PATCH 354/629] update SaveMapChunksTest after tiles refactor --- .../adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt index 22dd44b..bc427b8 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt @@ -69,7 +69,7 @@ class SaveMapChunksTest : FunSpec({ class Scenario( streamsBuilder: StreamsBuilder = StreamsBuilder(), - groupedMapChunksInputTopicName: String = "kafkatorio.state.map-chunks.grouped.debounced", + groupedMapChunksInputTopicName: String = "kafkatorio.state.map-chunk.colour", val serverId: FactorioServerId = FactorioServerId("test-server-id"), ) : AutoCloseable { @@ -169,7 +169,7 @@ class SaveMapChunksTest : FunSpec({ return arbitrary { val chunkId = serverMapChunkId.bind() - val tileColoursArb = tilesInChunkArb(serverMapChunkId.bind()) + val tileColoursArb = tilesInChunkArb(chunkId) ServerMapChunkTiles( chunkId = chunkId, From b6b874d8f7a5a093553f3f344681f2dcd9d38351 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 18 May 2022 19:32:52 +0200 Subject: [PATCH 355/629] add Gradle task to upload the mod to the portal, and some gradle fixes --- buildSrc/build.gradle.kts | 53 ++++- .../kotlin/dev/adamko/kafkatorio/common.kt | 6 - .../FactorioModPortalPublishClient.kt | 134 +++++++++++ .../factoriomod/FactorioModPublishTask.kt | 101 +++++++++ .../adamko/kafkatorio/factoriomod/model.kt | 91 ++++++++ .../kafkatorio/lang/kotlin-jvm.gradle.kts | 43 ++-- .../adamko/kafkatorio/lang/node.gradle.kts | 2 +- .../task/FactorioModPortalDeploy.kt | 23 -- .../task/JsonPropertiesUpToDateSpec.kt | 2 +- .../kafkatorio/task/TypescriptToLuaTask.kt | 1 + .../kafkatorio/task/UpdatePackageJson.kt | 50 +++-- gradle/libs.versions.toml | 30 ++- modules/events-mod/build.gradle.kts | 12 +- modules/events-server/build.gradle.kts | 4 +- .../build.gradle.kts | 31 ++- .../kafkatorio/ApplicationProperties.kt | 48 ---- .../kafkatorio/FactorioModPortalClient.kt | 210 +++++++++--------- .../FactorioModPortalPublishTask.kt | 83 +++++++ .../dev/adamko/kafkatorio/modUploader.kt | 52 +++-- modules/versions-platform/build.gradle.kts | 10 +- modules/web-map/build.gradle.kts | 8 +- settings.gradle.kts | 2 +- 22 files changed, 723 insertions(+), 273 deletions(-) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPublishTask.kt create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/model.kt delete mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/FactorioModPortalDeploy.kt delete mode 100644 modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/ApplicationProperties.kt create mode 100644 modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalPublishTask.kt diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 59514df..0b83ac0 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -4,7 +4,7 @@ plugins { idea `kotlin-dsl` kotlin("jvm") version "1.6.21" - `project-report` + kotlin("plugin.serialization") version "1.6.21" } val gradleJvmTarget = "11" @@ -19,9 +19,12 @@ dependencies { implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${libs.versions.kotlin.get()}") - implementation(platform("org.jetbrains.kotlinx:kotlinx-serialization-bom:${libs.versions.kotlinx.serialization.get()}")) - implementation("org.jetbrains.kotlinx:kotlinx-serialization-core") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json") + implementation(platform(libs.kotlinx.coroutines.bom)) + implementation(libs.kotlinx.coroutines.core) + + implementation(platform(libs.kotlinx.serialization.bom)) + implementation(libs.kotlinx.serialization.core) + implementation(libs.kotlinx.serialization.json) // implementation("com.charleskorn.kaml:kaml:0.37.0") implementation("com.github.node-gradle:gradle-node-plugin:${libs.versions.gradleNodePlugin.get()}") @@ -32,13 +35,29 @@ dependencies { implementation("net.swiftzer.semver:semver:${libs.versions.semver.get()}") + implementation(platform(libs.okio.bom)) + implementation(libs.okio.core) + + implementation(gradleKotlinDsl()) + + implementation(libs.kotlinx.cli) + + implementation(platform(libs.ktor.bom)) + implementation(libs.ktor.clientAuth) + implementation(libs.ktor.clientContentNegotiation) + implementation(libs.ktor.clientCore) + implementation(libs.ktor.clientEncoding) + implementation(libs.ktor.clientLogging) + implementation(libs.ktor.clientCIO) + implementation(libs.ktor.clientResources) + implementation(libs.ktor.serializationKotlinxJson) + // https://github.com/avast/gradle-docker-compose-plugin // implementation("com.avast.gradle:gradle-docker-compose-plugin:${Versions.gradleDockerComposePlugin}") - implementation(platform("org.http4k:http4k-bom:${libs.versions.http4k.get()}")) - implementation("org.http4k:http4k-core") - implementation("org.http4k:http4k-client-okhttp") - +// implementation(platform("org.http4k:http4k-bom:${libs.versions.http4k.get()}")) +// implementation("org.http4k:http4k-core") +// implementation("org.http4k:http4k-client-okhttp") // https://github.com/gradle/gradle/issues/15383#issuecomment-779893192 // https://youtrack.jetbrains.com/issue/IDEA-262280#focus=Comments-27-5397040.0-0 @@ -63,14 +82,24 @@ tasks.withType().configureEach { kotlinOptions.freeCompilerArgs += listOf( // "-Xcontext-receivers", - "-opt-in=kotlin.RequiresOptIn", - "-opt-in=kotlin.ExperimentalStdlibApi", - "-opt-in=kotlin.time.ExperimentalTime", + "-Xopt-in=kotlin.RequiresOptIn", + "-Xopt-in=kotlin.ExperimentalStdlibApi", + "-Xopt-in=kotlin.time.ExperimentalTime", // "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", + "-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi", ) } + +afterEvaluate { + tasks.withType().configureEach { + kotlinOptions { + apiVersion = gradleKotlinTarget + languageVersion = gradleKotlinTarget + } + } +} + kotlin { jvmToolchain { (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt index 2ff5871..27da996 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt @@ -13,16 +13,10 @@ val jsonMapper = Json { object Versions { - const val kotlinLang = "1.6" - const val jvmTarget = "11" const val node = "14.19.1" - // const val kotlinWrappers = "0.0.1-pre.330-kotlin-1.6.20" const val kotlinWrappers = "1.0.0-pre.336" - const val junit = "5.8.2" - const val kotest = "5.2.3" - const val mockk = "1.12.1" } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt new file mode 100644 index 0000000..5f4264d --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt @@ -0,0 +1,134 @@ +package dev.adamko.kafkatorio.factoriomod + +import io.ktor.client.HttpClient +import io.ktor.client.engine.cio.CIO +import io.ktor.client.plugins.contentnegotiation.ContentNegotiation +import io.ktor.client.plugins.defaultRequest +import io.ktor.client.plugins.logging.LogLevel +import io.ktor.client.plugins.logging.Logger +import io.ktor.client.plugins.logging.Logging +import io.ktor.client.plugins.logging.SIMPLE +import io.ktor.client.request.forms.MultiPartFormDataContent +import io.ktor.client.request.forms.formData +import io.ktor.client.request.forms.submitForm +import io.ktor.client.request.header +import io.ktor.client.request.post +import io.ktor.client.request.setBody +import io.ktor.client.statement.bodyAsText +import io.ktor.http.ContentType +import io.ktor.http.Headers +import io.ktor.http.HttpHeaders +import io.ktor.http.Parameters +import io.ktor.http.append +import io.ktor.http.isSuccess +import io.ktor.serialization.kotlinx.json.json +import java.io.File +import kotlinx.coroutines.runBlocking +import kotlinx.serialization.json.Json +import org.gradle.api.internal.tasks.userinput.UserInputHandler +import org.gradle.kotlin.dsl.support.useToRun +import org.jetbrains.kotlin.cli.common.toBooleanLenient + + +class FactorioModPortalPublishClient( + private val userInputHandler: UserInputHandler, + private val distributionZip: File, + private val modName: String, + private val modVersion: String, + private val portalApiKey: String, + private val portalUploadEndpoint: String, +) { + + private fun client() = HttpClient(CIO) { + install(Logging) { + logger = Logger.SIMPLE + level = LogLevel.ALL + } + install(ContentNegotiation) { + json(Json { + prettyPrint = false + isLenient = true + }) + } + defaultRequest { + header(HttpHeaders.Authorization, "Bearer $portalApiKey") + port = 443 + } + followRedirects = false + expectSuccess = false + } + + fun uploadMod() = runBlocking { + client().useToRun { + val initUploadResponse = initUpload() + + val confirmation = userInputHandler + .askQuestion("Are you sure you want to publish $modName:$modVersion?", "no") + .toBooleanLenient() ?: false + + if (confirmation) { + upload(initUploadResponse) + } else { + println("aborting upload") + } + } + } + + private suspend fun HttpClient.initUpload(): InitUploadResponse.Success { + + val response = submitForm( + url = portalUploadEndpoint, + formParameters = Parameters.build { + append("mod", modName) + } + ) + +// val response = post(portalUploadEndpoint) { +// contentType(ContentType.MultiPart.FormData) +// setBody(Json.encodeToString(InitUploadRequest.serializer(), InitUploadRequest(modName))) +//// setBody(InitUploadRequest(modName)) +// } + println(response) + val initUploadResponse: InitUploadResponse = + Json.decodeFromString(InitUploadResponse.serializer(), response.bodyAsText()) + println(initUploadResponse) + + require(response.status.isSuccess()) { "init upload request failed" } + + return when (initUploadResponse) { + is Failure -> error(initUploadResponse) + is InitUploadResponse.Success -> initUploadResponse + } + } + + private suspend fun HttpClient.upload(initUploadResponse: InitUploadResponse.Success) { + + val requestForm = formData { + append( + "file", + distributionZip.readBytes(), + Headers.build { + append(HttpHeaders.ContentType, ContentType.Application.Zip) + append(HttpHeaders.ContentDisposition, "filename=${distributionZip.name}") + } + ) + } + + + val response = post(initUploadResponse.uploadUrl) { + setBody(MultiPartFormDataContent(requestForm)) + } + + +// val response = submitFormWithBinaryData(initUploadResponse.uploadUrl, requestForm) { +// header(HttpHeaders.Authorization, "Bearer $portalApiKey") +// } + + val submitUploadResponse = + Json.decodeFromString(SubmitUploadResponse.serializer(), response.bodyAsText()) + + println(response) + println(submitUploadResponse) + require(response.status.isSuccess() && submitUploadResponse is SubmitUploadResponse.Success) { "upload request failed" } + } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPublishTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPublishTask.kt new file mode 100644 index 0000000..96cdc58 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPublishTask.kt @@ -0,0 +1,101 @@ +package dev.adamko.kafkatorio.factoriomod + +import io.ktor.http.URLBuilder +import io.ktor.http.takeFrom +import javax.inject.Inject +import kotlinx.coroutines.runBlocking +import org.gradle.api.DefaultTask +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.internal.tasks.userinput.UserInputHandler +import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.Property +import org.gradle.api.provider.ProviderFactory +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.TaskAction +import org.gradle.kotlin.dsl.property +import org.gradle.kotlin.dsl.support.get + + +abstract class FactorioModPublishTask @Inject constructor( + objects: ObjectFactory, + providers: ProviderFactory, +) : DefaultTask() { + + @get:InputFile + abstract val distributionZip: RegularFileProperty + + @get:Input + abstract val modName: Property + + @get:Input + abstract val modVersion: Property + +// @get:Input +// abstract val factorioVersion: Property + + /** Bearer API key */ + @get:Input + val portalApiKey: Property = objects.property().convention( + providers.gradleProperty("FACTORIO_MOD_PORTAL_API_KEY") + ) + + @get:Input + val portalApiUrl: Property = objects.property() + .convention("https://mods.factorio.com/api/v2/") + + @get:Input + val portalUploadEndpoint: Property = objects.property() + .convention("mods/releases/init_upload") + + + init { + group = "factorio" + } + + + @TaskAction + fun deploy() = runBlocking { + + + val userInputHandler = services.get() + + val portalUploadEndpoint = URLBuilder(portalApiUrl.get()) + .takeFrom(portalUploadEndpoint.get()) + .buildString() + + val client = FactorioModPortalPublishClient( + userInputHandler, + distributionZip.get().asFile, + modName.get(), + modVersion.get(), + portalApiKey.get(), + portalUploadEndpoint, + ) + + client.uploadMod() + } + +// private fun validateInfoJson() { +// val modVersion = modVersion.get() +// val factorioVersion = factorioVersion.get() +// +// val distributionZip = distributionZip.get().asFile.toOkioPath() +// +// val zipContents = FileSystem.SYSTEM.openZip(distributionZip) +// +// val infoJson = zipContents.read("info.json".toPath()) { +// generateSequence { readUtf8Line() } +// }.joinToString("\n") +// +// val info: FactorioModInfo = Json.decodeFromString(FactorioModInfo.serializer(), infoJson) +// +// require(info.version == modVersion) { +// "mod version mismatch, ${info.version} vs $modVersion " +// } +// +// require(info.factorioVersion == factorioVersion) { +// "Factorio version mismatch, ${info.factorioVersion} vs $factorioVersion " +// } +// } +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/model.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/model.kt new file mode 100644 index 0000000..3ab3770 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/model.kt @@ -0,0 +1,91 @@ +package dev.adamko.kafkatorio.factoriomod + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonContentPolymorphicSerializer +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.jsonObject + + +//@Serializable +//data class InitUploadRequest( +// @SerialName("mod") val modName: String, +//) + + +@Serializable(with = InitUploadResponse.Serializer::class) +sealed interface InitUploadResponse { + + /** + * @param[uploadUrl] URL the mod zip file should be uploaded to + */ + @Serializable + data class Success( + @SerialName("upload_url") val uploadUrl: String, + ) : InitUploadResponse + + object Serializer : + JsonContentPolymorphicSerializer(InitUploadResponse::class) { + override fun selectDeserializer(element: JsonElement) = when { + "upload_url" in element.jsonObject -> Success.serializer() + else -> Failure.serializer() + } + } +} + + +@Serializable(with = SubmitUploadResponse.Serializer::class) +sealed interface SubmitUploadResponse { + + @Serializable + object Success : SubmitUploadResponse + + object Serializer : JsonContentPolymorphicSerializer( + SubmitUploadResponse::class + ) { + override fun selectDeserializer(element: JsonElement) = when { + "success" in element.jsonObject -> Success.serializer() + else -> Failure.serializer() + } + } +} + + +@Serializable +data class Failure( + val error: String? = null, + val message: String? = null, +) : InitUploadResponse, SubmitUploadResponse { + + private val reason: String? + get() = reasons[error] + + override fun toString() = "Failure(error=$error, message=$message, reason=$reason)" + + companion object { + private val reasons: Map = mapOf( + //@formatter:off + "InvalidApiKey" to "Missing or invalid API key for the current endpoint", + "InvalidRequest" to "Invalid request.", + "InternalError" to "Internal error, please try again later.", + "Forbidden" to "Insufficient permission for current endpoint", + "Unknown" to "Unknown error, please try again later.", + "InvalidModRelease" to "Invalid release data in info.json", + "InvalidModUpload" to "Invalid mod data in zipfile", + "UnknownMod" to "Mod does not exist in mod portal", + //@formatter:on + ) + } +} + + +@Serializable +data class FactorioModInfo( + val name: String, + val version: String, + val title: String, + val description: String, + val author: String, + @SerialName("factorio_version") val factorioVersion: String, + val dependencies: List, +) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index 216378c..4cc560d 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -1,6 +1,5 @@ package dev.adamko.kafkatorio.lang -import dev.adamko.kafkatorio.Versions import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -8,41 +7,45 @@ plugins { kotlin("jvm") } +val projectKotlinTarget = "1.6" +val projectJvmTarget = "11" + + dependencies { - implementation(platform("org.jetbrains.kotlin:kotlin-bom")) +// implementation(platform("org.jetbrains.kotlin:kotlin-bom")) - testImplementation(platform("org.junit:junit-bom:${Versions.junit}")) +// testImplementation(platform("org.junit:junit-bom:${Versions.junit}")) testImplementation("org.junit.jupiter:junit-jupiter") - testRuntimeOnly("org.junit.platform:junit-platform-launcher") { - because("Only needed to run tests in a version of IntelliJ IDEA that bundles older versions") - } +// testRuntimeOnly("org.junit.platform:junit-platform-launcher") { +// because("Only needed to run tests in a version of IntelliJ IDEA that bundles older versions") +// } - testImplementation(platform("io.kotest:kotest-bom:${Versions.kotest}")) +// testImplementation(platform("io.kotest:kotest-bom:${Versions.kotest}")) testImplementation("io.kotest:kotest-runner-junit5") testImplementation("io.kotest:kotest-assertions-core") testImplementation("io.kotest:kotest-property") testImplementation("io.kotest:kotest-assertions-json") - testImplementation("io.mockk:mockk:${Versions.mockk}") - + testImplementation("io.mockk:mockk") } tasks.withType().configureEach { kotlinOptions { - jvmTarget = Versions.jvmTarget - apiVersion = Versions.kotlinLang - languageVersion = Versions.kotlinLang - freeCompilerArgs += listOf( + jvmTarget = projectJvmTarget + apiVersion = projectKotlinTarget + languageVersion = projectKotlinTarget + } + + kotlinOptions.freeCompilerArgs += listOf( // "-Xcontext-receivers", - "-opt-in=kotlin.RequiresOptIn", - "-opt-in=kotlin.ExperimentalStdlibApi", - "-opt-in=kotlin.time.ExperimentalTime", + "-opt-in=kotlin.RequiresOptIn", + "-opt-in=kotlin.ExperimentalStdlibApi", + "-opt-in=kotlin.time.ExperimentalTime", // "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", // "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", - ) - } + ) } tasks.compileTestKotlin { @@ -51,10 +54,10 @@ tasks.compileTestKotlin { kotlin { jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(Versions.jvmTarget)) + (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(projectJvmTarget)) } } -tasks.withType { +tasks.withType().configureEach { useJUnitPlatform() } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts index 59c1c21..a32586f 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/node.gradle.kts @@ -52,6 +52,6 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) { tasks.assemble { dependsOn(updatePackageJson) } -tasks.withType { +tasks.withType().configureEach { dependsOn(updatePackageJson) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/FactorioModPortalDeploy.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/FactorioModPortalDeploy.kt deleted file mode 100644 index 73ca284..0000000 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/FactorioModPortalDeploy.kt +++ /dev/null @@ -1,23 +0,0 @@ -package dev.adamko.kafkatorio.task - -import org.gradle.api.DefaultTask -import org.http4k.client.OkHttp -import org.http4k.core.Method -import org.http4k.core.Request - -abstract class FactorioModPortalDeploy : DefaultTask() { - - init { - super.doFirst { - - val client = OkHttp() - - val request = Request(Method.GET, "https://factorio.com/login?mods=1") - - println(client(request)) - - - } - } - -} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt index ea4c13d..0985fb0 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt @@ -22,7 +22,7 @@ object JsonPropertiesUpToDateSpec : ExplainingSpec { else -> { - val packageJsonContent = packageJsonFile.get().asFile.readText() + val packageJsonContent = packageJsonFile2.get().asFile.readText() val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject val outdatedProperties = propertiesToCheck.get().mapNotNull { (key, expectedVal) -> diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt index 7bf6fb2..0624185 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/TypescriptToLuaTask.kt @@ -2,6 +2,7 @@ package dev.adamko.kafkatorio.task import com.github.gradle.node.npm.task.NpmTask import javax.inject.Inject +import org.gradle.api.file.ConfigurableFileTree import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.FileSystemOperations import org.gradle.api.plugins.BasePlugin diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt index 32ebb08..0c55c92 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt @@ -13,6 +13,7 @@ import org.gradle.api.provider.MapProperty import org.gradle.api.provider.ProviderFactory import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import org.gradle.kotlin.dsl.support.useToRun @@ -20,14 +21,15 @@ import org.jetbrains.kotlin.util.suffixIfNot @CacheableTask abstract class UpdatePackageJson @Inject constructor( - private val providers: ProviderFactory + private val providers: ProviderFactory, ) : DefaultTask() { @get:Input abstract val propertiesToCheck: MapProperty - @get:OutputFile - abstract val packageJsonFile: RegularFileProperty +// @get:OutputFile + @get:Internal + abstract val packageJsonFile2: RegularFileProperty init { group = NodePlugin.NODE_GROUP @@ -36,26 +38,37 @@ abstract class UpdatePackageJson @Inject constructor( outputs.upToDateWhen(JsonPropertiesUpToDateSpec) - super.doFirst { - propertiesToCheck.disallowChanges() - packageJsonFile.disallowChanges() +// super.doFirst { +// propertiesToCheck.disallowChanges() +// packageJsonFile.disallowChanges() +// } + } + + init { + outputs.upToDateWhen { task -> + require(task is UpdatePackageJson) { "$task is not a UpdatePackageJson task" } + + val currentPackageJson = task.currentPackageJson() + val updatedPackageJson = task.updatedPackageJson(currentPackageJson) + + val status = currentPackageJson == updatedPackageJson + logger.lifecycle("package.json is ${if (status) "up to date" else "not up to date"}") + status } } @TaskAction fun exec() { - val packageJsonFile = packageJsonFile.asFile.get() - val propertiesToCheck = propertiesToCheck.get() + val packageJsonFile = packageJsonFile2.asFile.get() - logger.info("updating package.json ${packageJsonFile.canonicalPath}") - val packageJson = jsonMapper.parseToJsonElement(packageJsonFile.readText()).jsonObject + logger.lifecycle("updating package.json ${packageJsonFile.canonicalPath}") - val newJsonProps = propertiesToCheck.mapValues { (_, newVal) -> JsonPrimitive(newVal) } + val currentPackageJson = currentPackageJson() + val updatedPackageJson = updatedPackageJson(currentPackageJson) - val packageJsonUpdate = JsonObject(packageJson + newJsonProps) val packageJsonContentUpdated = jsonMapper - .encodeToString(packageJsonUpdate) + .encodeToString(updatedPackageJson) .suffixIfNot("\n") logger.debug(packageJsonContentUpdated) @@ -64,4 +77,15 @@ abstract class UpdatePackageJson @Inject constructor( write(packageJsonContentUpdated) } } + + private fun currentPackageJson(): JsonObject { + val packageJsonFile = packageJsonFile2.asFile.get() + return jsonMapper.parseToJsonElement(packageJsonFile.readText()).jsonObject + } + + private fun updatedPackageJson(currentPackageJson: JsonObject): JsonObject { + val propertiesToCheck = propertiesToCheck.get() + val newJsonProps = propertiesToCheck.mapValues { (_, newVal) -> JsonPrimitive(newVal) } + return JsonObject(currentPackageJson + newJsonProps) + } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 47bba69..0b1fd4e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -27,6 +27,7 @@ kotlinJsWrappers = "0.0.1-pre.334" kotlinx-html = "0.7.5" kotlinx-nodejs = "0.0.7" kotlinx-coroutines = "1.6.1" +kotlinx-cli = "0.3.4" ktor = "2.0.1" @@ -77,9 +78,12 @@ kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotl kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version.ref = "kotlinx-html" } kotlinx-nodejs = { group = "org.jetbrains.kotlinx", name = "kotlinx-nodejs", version.ref = "kotlinx-nodejs" } +kotlinx-cli = { group = "org.jetbrains.kotlinx", name = "kotlinx-cli", version.ref = "kotlinx-cli" } kotlin-jsWrappers-bom = { group = "org.jetbrains.kotlin-wrappers", name = "kotlin-wrappers-bom", version.ref = "kotlinJsWrappers" } + + ## http4k ## http4k-bom = { group = "org.http4k", name = "http4k-bom", version.ref = "http4k" } http4k-core = { group = "org.http4k", name = "http4k-core" } @@ -88,16 +92,27 @@ http4k-client-okhttp = { group = "org.http4k", name = "http4k-client-okhttp" http4k-client-ws = { group = "org.http4k", name = "http4k-client-websocket" } http4k-server = { group = "org.http4k", name = "http4k-server-undertow" } http4k-cloudnative = { group = "org.http4k", name = "http4k-cloudnative" } -http4k-format-json = { group = "org.http4k", name = "http4k-format-jackson" } -http4k-format-xml = { group = "org.http4k", name = "http4k-format-jackson-xml" } -http4k-format-yaml = { group = "org.http4k", name = "http4k-format-jackson-yaml" } +#http4k-format-jackson-json = { group = "org.http4k", name = "http4k-format-jackson" } +#http4k-format-jackson-xml = { group = "org.http4k", name = "http4k-format-jackson-xml" } +#http4k-format-jackson-yaml = { group = "org.http4k", name = "http4k-format-jackson-yaml" } http4k-format-kotlinx = { group = "org.http4k", name = "http4k-format-kotlinx-serialization" } http4k-graphql = { group = "org.http4k", name = "http4k-graphql" } ## ktor ## -ktor-bom = { group = "io.ktor", name = "ktor-bom", version.ref = "ktor" } +ktor-bom = { group = "io.ktor", name = "ktor-bom", version.ref = "ktor" } +ktor-clientAuth = { group = "io.ktor", name = "ktor-client-auth" } +ktor-clientCIO = { group = "io.ktor", name = "ktor-client-cio" } +ktor-clientContentNegotiation = { group = "io.ktor", name = "ktor-client-content-negotiation" } +ktor-clientCore = { group = "io.ktor", name = "ktor-client-core" } +ktor-clientEncoding = { group = "io.ktor", name = "ktor-client-encoding" } +ktor-clientLogging = { group = "io.ktor", name = "ktor-client-logging" } +ktor-clientResources = { group = "io.ktor", name = "ktor-client-resources" } +ktor-clientWebsockets = { group = "io.ktor", name = "ktor-client-websockets" } +ktor-serializationKotlinxJson = { group = "io.ktor", name = "ktor-serialization-kotlinx-json" } + +ktor-test-clientMock = { group = "io.ktor", name = "ktor-client-mock" } ### jackson ## #jackson-bom = { group = " com.fasterxml.jackson.module", name = ":jackson-module-kotlin", version = "2.13.+" } @@ -129,6 +144,7 @@ skrapeit = { group = "it.skrape", name = "skrapeit", version = "1.2.0" } scrimage-core = { group = "com.sksamuel.scrimage", name = "scrimage-core", version.ref = "scrimage" } +semver = { group = "net.swiftzer.semver", name = "semver", version.ref = "semver" } ## okio ## okio-bom = { group = "com.squareup.okio", name = "okio-bom", version.ref = "okio" } @@ -194,9 +210,9 @@ http4k = [ "http4k-client-ws", "http4k-server", "http4k-cloudnative", - "http4k-format-xml", - "http4k-format-json", - "http4k-format-yaml", +# "http4k-format-jackson-xml", +# "http4k-format-jackson-json", +# "http4k-format-jackson-yaml", "http4k-format-kotlinx", ] diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index d48c960..866c6a2 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -1,3 +1,4 @@ +import dev.adamko.kafkatorio.factoriomod.FactorioModPublishTask import dev.adamko.kafkatorio.gradle.asConsumer import dev.adamko.kafkatorio.gradle.asProvider import dev.adamko.kafkatorio.gradle.dropDirectories @@ -50,7 +51,7 @@ val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") node { - nodeProjectDir.set(tsSrcDir) + nodeProjectDir.set(layout.projectDirectory) } @@ -115,6 +116,15 @@ tasks.distZip { } +val publishMod by tasks.registering(FactorioModPublishTask::class) { + distributionZip.set(tasks.distZip.flatMap { it.archiveFile }) + + val projectModName = project.extra.get("modName") as String + modName.set(projectModName) + modVersion.set(project.version.toString()) +} + + distributions { main { diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 6e7d04c..d0bfdee 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -15,7 +15,7 @@ description = """ val projectId: String by project.extra -val kafkaStateDir = layout.projectDirectory.dir("kafka-state") +val kafkaStateDir: Directory = layout.projectDirectory.dir("kafka-state") dependencies { implementation(platform(projects.modules.versionsPlatform)) @@ -64,7 +64,7 @@ application { // ) } -tasks.withType { +tasks.withType().configureEach { kotlinOptions.freeCompilerArgs += listOf( "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", "-opt-in=kotlinx.coroutines.FlowPreview", diff --git a/modules/factorio-mod-portal-client/build.gradle.kts b/modules/factorio-mod-portal-client/build.gradle.kts index 3475da0..a4700a0 100644 --- a/modules/factorio-mod-portal-client/build.gradle.kts +++ b/modules/factorio-mod-portal-client/build.gradle.kts @@ -3,32 +3,41 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { dev.adamko.kafkatorio.lang.`kotlin-jvm` kotlin("plugin.serialization") - application + `java-gradle-plugin` } dependencies { implementation(platform(projects.modules.versionsPlatform)) - implementation(projects.modules.eventsServer) +// implementation(gradleKotlinDsl()) implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.json) + implementation(libs.kotlinx.cli) implementation(libs.kotlinx.coroutines.core) - implementation(libs.bundles.http4k) - implementation(libs.http4k.format.kotlinx) +// implementation(libs.bundles.http4k) +// implementation(libs.http4k.format.kotlinx) - implementation(libs.skrapeit) +// implementation(libs.skrapeit) + + implementation(libs.okio.core) + + implementation(libs.semver) + + implementation(libs.ktor.clientAuth) + implementation(libs.ktor.clientContentNegotiation) + implementation(libs.ktor.clientCore) + implementation(libs.ktor.clientEncoding) + implementation(libs.ktor.clientLogging) + implementation(libs.ktor.clientCIO) + implementation(libs.ktor.clientResources) + implementation(libs.ktor.serializationKotlinxJson) } -// -//application { -// mainClass.set("dev.adamko.kafkatorio.processor.EventProcessorKt") -//} - -tasks.withType { +tasks.withType().configureEach { kotlinOptions.freeCompilerArgs += listOf( "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", "-opt-in=kotlinx.coroutines.FlowPreview", diff --git a/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/ApplicationProperties.kt b/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/ApplicationProperties.kt deleted file mode 100644 index be38903..0000000 --- a/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/ApplicationProperties.kt +++ /dev/null @@ -1,48 +0,0 @@ -package dev.adamko.kafkatorio - -import dev.adamko.kafkatorio.processor.config.env -import dev.adamko.kafkatorio.processor.config.fromEnvVarPath -import dev.adamko.kafkatorio.processor.config.fromResourcesFile -import java.time.Clock -import org.http4k.cloudnative.env.Environment -import org.http4k.cloudnative.env.EnvironmentKey -import org.http4k.cloudnative.env.Secret -import org.http4k.lens.nonEmptyString -import org.http4k.lens.secret - - -/** - * Load properties, in descending priority order, from - * - * 1. Environment variables - * 2. This app's env file (as defined by the environment variable [Lenses.APPLICATION_PROPERTIES_FILE_PATH]) - * # 3. A resources-dir yaml file - * - */ -internal class ApplicationProperties( - vararg environments: Environment = arrayOf( - Environment.env(), - Environment.fromEnvVarPath(), - Environment.fromResourcesFile(".secret.config.yml") - ) -) { - - private val appProps: Environment = - environments.reduce { acc, environment -> acc.overrides(environment) } - - - fun clock(): Clock = Clock.systemUTC() - - - val factorioModPortalUsername: String - get() = EnvironmentKey - .nonEmptyString() - .required("factorio-mod-portal.username")[appProps] - - - val factorioModPortalPassword: Secret - get() = EnvironmentKey - .secret() - .required("factorio-mod-portal.password")[appProps] - -} diff --git a/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalClient.kt b/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalClient.kt index 55fb5e2..58b6e30 100644 --- a/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalClient.kt +++ b/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalClient.kt @@ -1,107 +1,107 @@ package dev.adamko.kafkatorio -import dev.adamko.kafkatorio.processor.serdes.KXS.asPrettyJsonString -import dev.adamko.kafkatorio.processor.serdes.jsonMapper -import it.skrape.core.htmlDocument -import it.skrape.selects.html5.input -import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.jsonObject -import org.http4k.client.OkHttp -import org.http4k.core.HttpHandler -import org.http4k.core.Method -import org.http4k.core.Request -import org.http4k.core.Response -import org.http4k.core.body.form -import org.http4k.core.cookie.Cookie -import org.http4k.core.cookie.cookie -import org.http4k.core.cookie.cookies -import org.http4k.core.then -import org.http4k.filter.ClientFilters - - -/** - * * https://github.com/shanemadden/factorio-mod-portal-publish/blob/master/entrypoint.sh - * * https://github.com/nicolas-lang/factorio-create-release-action/blob/master/entrypoint.py - * * https://github.com/nicolas-lang/factorio-create-release-action/blob/master/factorioModPortal.py - * * https://github.com/justarandomgeek/vscode-factoriomod-debug/blob/master/src/ModPackageProvider.ts#L530 - * - * - */ -internal class FactorioModPortalClient( - private val appProps: ApplicationProperties = ApplicationProperties(), - private val loginFormUrl: String = "https://factorio.com/login?mods=1", - private val loginUrl: String = "https://factorio.com/login", -) { - - private val client: HttpHandler = - ClientFilters.FollowRedirects() - .then(OkHttp()) - - private val csrfCookie: Cookie by lazy { fetchCsrfToken() } - private val sessionCookie: Cookie by lazy { login() } - - - private fun fetchCsrfToken(): Cookie { - - val request = Request(Method.GET, loginFormUrl) - val response: Response = client(request) - - val csrfToken = htmlDocument(response.bodyString()) { - input { - withId = csrfTokenName - withAttribute = "name" to csrfTokenName - findFirst { attribute("value") } - } - } - - println("csrfToken: $csrfToken") - return Cookie(csrfTokenName, csrfToken) - } - - - private fun login(): Cookie { - - val loginRequest = Request(Method.POST, loginUrl) - .header("Referer", loginFormUrl) -// .cookie(csrfCookie) - .form("csrf_token", csrfCookie.value) - .form("username_or_email", appProps.factorioModPortalUsername) - .form("password", appProps.factorioModPortalPassword.use { it }) - .form("next_url", "/profile") - - val loginResponse = client(loginRequest) - - println(loginResponse.bodyString()) - - val sessionCookie = loginResponse.cookies() - .first { it.name == "session" && it.domain == ".factorio.com" } - - println("sessionCookie: $sessionCookie") - - return sessionCookie - } - - fun getModInfo(modName: String): JsonObject { - val response = client( - Request(Method.GET, "https://mods.factorio.com/api/mods/${modName}/full") - .cookie(csrfCookie) - .cookie(sessionCookie) - ) - return jsonMapper.parseToJsonElement(response.bodyString()).jsonObject - } - - fun fetchModUploadToken(modName: String): String { - val response = client( - Request(Method.GET, "https://mods.factorio.com/mod/${modName}/edit") - .cookie(csrfCookie) - .cookie(sessionCookie) - ) - - return response.bodyString() - } - - companion object { - private const val csrfTokenName = "csrf_token" - } - -} +//import dev.adamko.kafkatorio.processor.serdes.KXS.asPrettyJsonString +//import dev.adamko.kafkatorio.processor.serdes.jsonMapper +//import it.skrape.core.htmlDocument +//import it.skrape.selects.html5.input +//import kotlinx.serialization.json.JsonObject +//import kotlinx.serialization.json.jsonObject +//import org.http4k.client.OkHttp +//import org.http4k.core.HttpHandler +//import org.http4k.core.Method +//import org.http4k.core.Request +//import org.http4k.core.Response +//import org.http4k.core.body.form +//import org.http4k.core.cookie.Cookie +//import org.http4k.core.cookie.cookie +//import org.http4k.core.cookie.cookies +//import org.http4k.core.then +//import org.http4k.filter.ClientFilters +// +// +///* +// * * https://github.com/shanemadden/factorio-mod-portal-publish/blob/master/entrypoint.sh +// * * https://github.com/nicolas-lang/factorio-create-release-action/blob/master/entrypoint.py +// * * https://github.com/nicolas-lang/factorio-create-release-action/blob/master/factorioModPortal.py +// * * https://github.com/justarandomgeek/vscode-factoriomod-debug/blob/master/src/ModPackageProvider.ts#L530 +// * +// * +// */ +//internal class FactorioModPortalClient( +// private val appProps: ApplicationProperties = ApplicationProperties(), +// private val loginFormUrl: String = "https://factorio.com/login?mods=1", +// private val loginUrl: String = "https://factorio.com/login", +//) { +// +// private val client: HttpHandler = +// ClientFilters.FollowRedirects() +// .then(OkHttp()) +// +// private val csrfCookie: Cookie by lazy { fetchCsrfToken() } +// private val sessionCookie: Cookie by lazy { login() } +// +// +// private fun fetchCsrfToken(): Cookie { +// +// val request = Request(Method.GET, loginFormUrl) +// val response: Response = client(request) +// +// val csrfToken = htmlDocument(response.bodyString()) { +// input { +// withId = csrfTokenName +// withAttribute = "name" to csrfTokenName +// findFirst { attribute("value") } +// } +// } +// +// println("csrfToken: $csrfToken") +// return Cookie(csrfTokenName, csrfToken) +// } +// +// +// private fun login(): Cookie { +// +// val loginRequest = Request(Method.POST, loginUrl) +// .header("Referer", loginFormUrl) +//// .cookie(csrfCookie) +// .form("csrf_token", csrfCookie.value) +// .form("username_or_email", appProps.factorioModPortalUsername) +// .form("password", appProps.factorioModPortalPassword.use { it }) +// .form("next_url", "/profile") +// +// val loginResponse = client(loginRequest) +// +// println(loginResponse.bodyString()) +// +// val sessionCookie = loginResponse.cookies() +// .first { it.name == "session" && it.domain == ".factorio.com" } +// +// println("sessionCookie: $sessionCookie") +// +// return sessionCookie +// } +// +// fun getModInfo(modName: String): JsonObject { +// val response = client( +// Request(Method.GET, "https://mods.factorio.com/api/mods/${modName}/full") +// .cookie(csrfCookie) +// .cookie(sessionCookie) +// ) +// return jsonMapper.parseToJsonElement(response.bodyString()).jsonObject +// } +// +// fun fetchModUploadToken(modName: String): String { +// val response = client( +// Request(Method.GET, "https://mods.factorio.com/mod/${modName}/edit") +// .cookie(csrfCookie) +// .cookie(sessionCookie) +// ) +// +// return response.bodyString() +// } +// +// companion object { +// private const val csrfTokenName = "csrf_token" +// } +// +//} diff --git a/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalPublishTask.kt b/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalPublishTask.kt new file mode 100644 index 0000000..4163228 --- /dev/null +++ b/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalPublishTask.kt @@ -0,0 +1,83 @@ +package dev.adamko.kafkatorio + +//import javax.inject.Inject +//import kotlinx.coroutines.runBlocking +//import kotlinx.serialization.json.Json +//import net.swiftzer.semver.SemVer +//import okio.FileSystem +//import okio.Path.Companion.toOkioPath +//import okio.Path.Companion.toPath +//import okio.openZip +//import org.gradle.api.DefaultTask +//import org.gradle.api.file.RegularFileProperty +//import org.gradle.api.model.ObjectFactory +//import org.gradle.api.provider.Property +//import org.gradle.api.provider.ProviderFactory +//import org.gradle.api.tasks.Input +//import org.gradle.api.tasks.InputFile +//import org.gradle.api.tasks.TaskAction +//import org.gradle.kotlin.dsl.property +// +// +//abstract class FactorioModPortalPublishTask @Inject constructor( +// objects: ObjectFactory, +// providers: ProviderFactory, +//) : DefaultTask() { +// +// @get:InputFile +// abstract val distributionZip: RegularFileProperty +// +// @get:Input +// abstract val modVersion: Property +// +// @get:Input +// abstract val modName: Property +// +// @get:Input +// abstract val factorioVersion: Property +// +// /** Bearer API key */ +// @get:Input +// val portalApiKey: Property = objects.property().convention( +// providers.gradleProperty("FACTORIO_MOD_PORTAL_API_KEY") +// ) +// +// @get:Input +// val portalUploadEndpoint: Property = objects.property() +// .convention("https://mods.factorio.com/api/v2/mods/releases/init_upload") +// +// +// @TaskAction +// fun deploy() = runBlocking { +// val modVersion = SemVer.parse(modVersion.get()) +// +// val portalUploadEndpoint = portalUploadEndpoint.get() +// val modName = modName.get() +// val portalApiKey = portalApiKey.get() +// val distributionZip = distributionZip.get().asFile +// +// } +// +// private fun validateInfoJson() { +// val modVersion = modVersion.get() +// val factorioVersion = factorioVersion.get() +// +// val distributionZip = distributionZip.get().asFile.toOkioPath() +// +// val zipContents = FileSystem.SYSTEM.openZip(distributionZip) +// +// val infoJson = zipContents.read("info.json".toPath()) { +// generateSequence { readUtf8Line() } +// }.joinToString("\n") +// +// val info: FactorioModInfo = Json.decodeFromString(FactorioModInfo.serializer(), infoJson) +// +// require(info.version == modVersion) { +// "mod version mismatch, ${info.version} vs $modVersion " +// } +// +// require(info.factorioVersion == factorioVersion) { +// "Factorio version mismatch, ${info.factorioVersion} vs $factorioVersion " +// } +// } +//} diff --git a/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/modUploader.kt b/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/modUploader.kt index 0bb1279..5cba361 100644 --- a/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/modUploader.kt +++ b/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/modUploader.kt @@ -1,14 +1,40 @@ package dev.adamko.kafkatorio - -import dev.adamko.kafkatorio.processor.serdes.KXS.asPrettyJsonString - - -private const val modName = "kafkatorio-events" - - -fun main() { - val client = FactorioModPortalClient() -// val modInfo = client.getModInfo(modName) -// println(modInfo.asPrettyJsonString()) - println(client.fetchModUploadToken(modName)) -} +// +//import java.io.File +//import kotlinx.cli.ArgParser +//import kotlinx.cli.ArgType +//import kotlinx.cli.required +//import kotlinx.coroutines.runBlocking +// +//fun main(args: Array) = runBlocking { +// val parser = ArgParser("example") +// +// val distributionZip: File by parser.option(FileArg).required() +// val modName: String by parser.option(ArgType.String).required() +// val portalApiKey: String by parser.option(ArgType.String).required() +// val portalUploadEndpoint: String by parser.option(ArgType.String).required() +// +// parser.parse(args) +// +// val client = FactorioModPortalPublishClient( +// distributionZip, +// modName, +// portalApiKey, +// portalUploadEndpoint, +// ) +// +// client.uploadMod() +//} +// +// +//object FileArg : ArgType(true) { +// override val description: kotlin.String +// get() = "{ File }" +// +// override fun convert(value: kotlin.String, name: kotlin.String): File { +// return File(value).also { +// require(it.exists()) { "${it.canonicalPath} does not exist" } +// require(it.isFile) { "${it.canonicalPath} is not a file" } +// } +// } +//} diff --git a/modules/versions-platform/build.gradle.kts b/modules/versions-platform/build.gradle.kts index bb93f8c..1e23afc 100644 --- a/modules/versions-platform/build.gradle.kts +++ b/modules/versions-platform/build.gradle.kts @@ -24,18 +24,12 @@ dependencies { constraints { api(libs.skrapeit) api(libs.kotlinx.serialization.yaml) - - - - - - - - api(libs.kafka.kotkaStreams) api(libs.kafka.streams) api(libs.okio.core) api(libs.scrimage.core) api(libs.kafka.streamsTestUtils) + + api(libs.mockk) } } diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 0ff58e1..284b406 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -36,7 +36,10 @@ kotlin { port = 3000, proxy = mutableMapOf( "/kv/*" to "http://localhost:8080", - "/kvws/*" to mapOf("target" to "ws://localhost:8080", "ws" to true) + "/kvws/*" to mapOf( + "target" to "ws://localhost:8080", + "ws" to true, + ) ), static = mutableListOf("$buildDir/processedResources/frontend/main") ) @@ -160,3 +163,6 @@ fun KotlinDependencyHandler.kvision( // resolution("node-forge", "1.3.0") // } //} + +evaluationDependsOn(rootProject.path) +evaluationDependsOn(projects.modules.eventsSchema.dependencyProject.path) diff --git a/settings.gradle.kts b/settings.gradle.kts index c67af44..0380a2c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -15,7 +15,7 @@ include( ":modules:kt-rcon", ":modules:web-map", - ":modules:factorio-mod-portal-client", +// ":modules:factorio-mod-portal-client", ":modules:versions-platform", ) From 6d9f3032262927c8cd902f34193834d92494b9f7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 18 May 2022 19:36:40 +0200 Subject: [PATCH 356/629] mod: move npm root dir so node_modules isn't in the src dir, and fix the hack for the bug https://github.com/GlassBricks/typed-factorio/issues/13 --- modules/events-mod/build.gradle.kts | 114 +++++++++--------- .../main/typescript => }/package-lock.json | 0 .../{src/main/typescript => }/package.json | 12 +- .../{src/main/typescript => }/tsconfig.json | 3 +- 4 files changed, 65 insertions(+), 64 deletions(-) rename modules/events-mod/{src/main/typescript => }/package-lock.json (100%) rename modules/events-mod/{src/main/typescript => }/package.json (74%) rename modules/events-mod/{src/main/typescript => }/tsconfig.json (94%) diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 866c6a2..ef92cbd 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -37,7 +37,8 @@ val licenseFile: RegularFile by rootProject.extra @Suppress("UNCHECKED_CAST") val projectTokens: MapProperty = - rootProject.extra.get("projectTokens") as? MapProperty ?: error("error getting projectTokens") + rootProject.extra.get("projectTokens") as? MapProperty + ?: error("error getting projectTokens") //val projectTokens: MapProperty by rootProject.extra val projectTokensX = projectTokens.apply { @@ -50,6 +51,7 @@ val projectTokensX = projectTokens.apply { val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") + node { nodeProjectDir.set(layout.projectDirectory) } @@ -80,7 +82,7 @@ val installEventsTsSchema by tasks.registering(Sync::class) { group = project.name dependsOn(typescriptEventsSchema) - dependsOn(fixLink) +// dependsOn(fixLink) val outputDir = layout.projectDirectory.dir("src/main/typescript/generated/kafkatorio-schema") outputs.dir(outputDir) @@ -159,59 +161,59 @@ tasks.withType().configureEach { // } } -tasks.npmInstall { - nodeModulesOutputFilter { - exclude("**/typed-factorio/generated/classes.d.ts") - } -} +//tasks.npmInstall { +// nodeModulesOutputFilter { +// exclude("**/typed-factorio/generated/classes.d.ts") +// } +//} -interface ServiceProvider { - @get:Inject - val fs: FileSystemOperations -} - -val fixLink by tasks.registering { - dependsOn(tasks.npmInstall) - - - val badLink = """{@link https://lua-api.factorio.com/latest/Data-Lifecycle.html Data Lifecycle}""" - val goodLink = """https://lua-api.factorio.com/latest/Data-Lifecycle.html""" - - val typedFactorioDir = - layout.projectDirectory.dir("src/main/typescript/node_modules/typed-factorio") - val classesDTS = typedFactorioDir.file("generated/classes.d.ts") - - val services = project.objects.newInstance() - - inputs.file(classesDTS) - outputs.file(classesDTS) - - inputs.property("badLink", badLink) - inputs.property("goodLink", goodLink) - - doLast { - logger.lifecycle("fixing link ${classesDTS.asFile.canonicalPath}") - - services.fs.sync { - from(classesDTS) - into(temporaryDir) - filter { line -> - when { - line.contains(badLink) -> line.replace(badLink, goodLink) - else -> line - } - } - } - - services.fs.copy { - from(temporaryDir.resolve("classes.d.ts").canonicalPath) - into(classesDTS.asFile.parent) - duplicatesStrategy = DuplicatesStrategy.WARN - } - } -} - -tasks.assemble { dependsOn(fixLink) } +//interface ServiceProvider { +// @get:Inject +// val fs: FileSystemOperations +//} +// +//val fixLink by tasks.registering { +// dependsOn(tasks.npmInstall) +// +// +// val badLink = """{@link https://lua-api.factorio.com/latest/Data-Lifecycle.html Data Lifecycle}""" +// val goodLink = """https://lua-api.factorio.com/latest/Data-Lifecycle.html""" +// +// val typedFactorioDir = +// layout.projectDirectory.dir("src/main/typescript/node_modules/typed-factorio") +// val classesDTS = typedFactorioDir.file("generated/classes.d.ts") +// +// val services = project.objects.newInstance() +// +// inputs.file(classesDTS) +// outputs.file(classesDTS) +// +// inputs.property("badLink", badLink) +// inputs.property("goodLink", goodLink) +// +// doLast { +// logger.lifecycle("fixing link ${classesDTS.asFile.canonicalPath}") +// +// services.fs.sync { +// from(classesDTS) +// into(temporaryDir) +// filter { line -> +// when { +// line.contains(badLink) -> line.replace(badLink, goodLink) +// else -> line +// } +// } +// } +// +// services.fs.copy { +// from(temporaryDir.resolve("classes.d.ts").canonicalPath) +// into(classesDTS.asFile.parent) +// duplicatesStrategy = DuplicatesStrategy.WARN +// } +// } +//} +// +//tasks.assemble { dependsOn(fixLink) } //val downloadFactorioApiDocs by tasks.registering { @@ -253,9 +255,11 @@ val factorioModProvider by configurations.registering { val packageJsonName = providers.provider { "${rootProject.name}-${project.name}" } tasks.updatePackageJson { +// mustRunAfter(tasks.npmInstall) inputs.property("packageJsonName", packageJsonName) propertiesToCheck.put("name", packageJsonName) - packageJsonFile.set(layout.projectDirectory.file("src/main/typescript/package.json")) + val pjProvider = layout.projectDirectory.file(provider { "package.json" }) + packageJsonFile2.set(pjProvider) } diff --git a/modules/events-mod/src/main/typescript/package-lock.json b/modules/events-mod/package-lock.json similarity index 100% rename from modules/events-mod/src/main/typescript/package-lock.json rename to modules/events-mod/package-lock.json diff --git a/modules/events-mod/src/main/typescript/package.json b/modules/events-mod/package.json similarity index 74% rename from modules/events-mod/src/main/typescript/package.json rename to modules/events-mod/package.json index 861f812..be98670 100644 --- a/modules/events-mod/src/main/typescript/package.json +++ b/modules/events-mod/package.json @@ -9,8 +9,7 @@ "engines": { "node": "~14.19.1" }, - "devDependencies": { - }, + "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", "typescript-to-lua": "1.4.4", @@ -18,10 +17,7 @@ "typescript": "4.6.2" }, "license": "UNLICENSED", - "peerDependencies": { - }, - "optionalDependencies": { - }, - "bundledDependencies": [ - ] + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] } diff --git a/modules/events-mod/src/main/typescript/tsconfig.json b/modules/events-mod/tsconfig.json similarity index 94% rename from modules/events-mod/src/main/typescript/tsconfig.json rename to modules/events-mod/tsconfig.json index ae83187..7036839 100644 --- a/modules/events-mod/src/main/typescript/tsconfig.json +++ b/modules/events-mod/tsconfig.json @@ -32,7 +32,8 @@ "traceResolution": true, "noImplicitReturns": true, "noImplicitOverride": true, - "noFallthroughCasesInSwitch": true + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true }, "tstl": { "luaTarget": "5.2", From 610d559f79f53c871fc606a9999edf997274bf80 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 18 May 2022 19:38:04 +0200 Subject: [PATCH 357/629] tile server: reduce logging, try no-cache for everything --- .../kafkatorio/processor/tileserver/WebMapTileServer.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt index d2f63c5..a01aaea 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt @@ -18,7 +18,7 @@ import org.http4k.routing.routes import org.http4k.routing.static internal class WebMapTileServer( - private val appProps: ApplicationProperties = ApplicationProperties() + appProps: ApplicationProperties = ApplicationProperties() ) { private val tilesLoader = ResourceLoader.Directory(appProps.webmapTileDir.absolutePathString()) @@ -103,15 +103,16 @@ internal class WebMapTileServer( .header("Cache-Control", "no-cache") } requestedETag == currentETag -> { - println("[${request.etagKey}] currentETag == requested, returning 302 $requestedETag") +// println("[${request.etagKey}] currentETag == requested, returning 304 $requestedETag") Response(Status.NOT_MODIFIED) .header("Cache-Control", "no-cache") } else -> { - println("[${request.etagKey}] currentETag != requested, executing request and adding currentETag:$currentETag (requested:$requestedETag)") +// println("[${request.etagKey}] currentETag != requested, executing request and adding currentETag:$currentETag (requested:$requestedETag)") response .header("ETag", currentETag) - .header("Cache-Control", "public, max-age=1, stale-while-revalidate=60, stale-if-error=300") +// .header("Cache-Control", "no-store") + .header("Cache-Control", "no-cache") } } } From 883ed897f5a251dfc14bed86dd2fb7d6bf322348 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 18 May 2022 19:38:32 +0200 Subject: [PATCH 358/629] mod: try fixing settings not loading --- .../resources/mod-data/locale/en/locale.cfg | 12 ++-- .../events-mod/src/main/typescript/control.ts | 5 +- .../main/events/registerHandlers.ts | 2 +- .../main/settings/KafkatorioSettings.ts | 55 ++++++++++--------- 4 files changed, 39 insertions(+), 35 deletions(-) diff --git a/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg b/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg index 66fba27..491d391 100644 --- a/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg +++ b/modules/events-mod/src/main/resources/mod-data/locale/en/locale.cfg @@ -1,15 +1,15 @@ [mod-setting-name] -kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-PlayerUpdate=Player update rate (seconds) -kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-MapChunkUpdate=Map update rate (seconds) -kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-EntityUpdate=Entity update rate (seconds) +kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-PlayerUpdate=Player update rate (seconds) +kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkUpdate=Map update rate (seconds) +kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-EntityUpdate=Entity update rate (seconds) [mod-setting-description] -kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-PlayerUpdate=How frequently Player updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (0.25 seconds) is probably fine! -kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-MapChunkUpdate=How frequently Map updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine! -kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-EntityUpdate=How frequently Entity updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (5 seconds) is probably fine! +kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-PlayerUpdate=How frequently Player updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (0.25 seconds) is probably fine! +kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkUpdate=How frequently Map updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine! +kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-EntityUpdate=How frequently Entity updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (5 seconds) is probably fine! [string-mod-setting] diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index 3933383..abf359c 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -10,10 +10,11 @@ require("./main/events/EntityEvents") require("./main/commands/kafkatorioCommands") require("./main/cache/cacheChecker") + script.on_configuration_changed((data: ConfigurationChangedData) => { // runs whenever the version of the base game, or a mod, changes initGlobal(true) - KafkatorioSettings.loadSettings() + // KafkatorioSettings.loadSettings() emitConfigurationUpdate(data) emitPrototypes() }) @@ -22,6 +23,6 @@ script.on_configuration_changed((data: ConfigurationChangedData) => { script.on_init(() => { // runs only once (when the mod is first added to the save) initGlobal(true) - KafkatorioSettings.loadSettings() + // KafkatorioSettings.loadSettings() emitPrototypes() }) diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index b2d9aa3..f8b2aa7 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -64,6 +64,6 @@ script.on_event( defines.events.on_runtime_mod_setting_changed, (e: OnRuntimeModSettingChangedEvent) => { print(`Settings changed ${e.setting_type}, ${e.player_index}, ${e.setting}, ${e.mod_name}`) - KafkatorioSettings.loadSettings() + // KafkatorioSettings.loadSettings() } ) diff --git a/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts b/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts index 299e04d..bb90bfb 100644 --- a/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts +++ b/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts @@ -1,6 +1,5 @@ import {Data, DoubleSettingDefinition} from "typed-factorio/settings/types" import {KafkatorioKeyedPacketData, KafkatorioKeyedPacketTypes} from "../types"; -import {KafkatorioPacketData} from "../../generated/kafkatorio-schema/kafkatorio-schema"; export class KafkatorioSettingsConfig { @@ -12,38 +11,42 @@ export class KafkatorioSettingsConfig { } - private eventCacheExpirationTicks: Record = { - "kafkatorio.packet.keyed.PlayerUpdate": - KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.PlayerUpdate], - "kafkatorio.packet.keyed.MapChunkUpdate": - KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.MapChunkUpdate], - "kafkatorio.packet.keyed.EntityUpdate": - KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.EntityUpdate], - } + // private eventCacheExpirationTicks: Record = { + // "kafkatorio.packet.keyed.PlayerUpdate": + // KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.PlayerUpdate], + // "kafkatorio.packet.keyed.MapChunkUpdate": + // KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.MapChunkUpdate], + // "kafkatorio.packet.keyed.EntityUpdate": + // KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.EntityUpdate], + // } public getEventCacheExpirationTicks(packet: KafkatorioKeyedPacketData): uint { - return this.eventCacheExpirationTicks[packet.type] + const settingName = KafkatorioSettingsConfig.cacheDurationSettingName(packet.type) + const seconds: double = settings.global[settingName].value as double + return seconds * 60 // convert ticks to seconds } - private static types: KafkatorioKeyedPacketTypes[] = [ - KafkatorioPacketData.Type.PlayerUpdate, - KafkatorioPacketData.Type.MapChunkUpdate, - KafkatorioPacketData.Type.EntityUpdate, - ] + // private static types: KafkatorioKeyedPacketTypes[] = [ + // KafkatorioPacketData.Type.PlayerUpdate, + // KafkatorioPacketData.Type.MapChunkUpdate, + // KafkatorioPacketData.Type.EntityUpdate, + // ] - public loadSettings(): void { - for (const type of KafkatorioSettingsConfig.types) { - const seconds: double = settings.global[KafkatorioSettingsConfig.cacheDurationSettingName(type)].value as double - this.eventCacheExpirationTicks[type] = seconds * 60 // convert ticks to seconds - } - } + // public loadSettings(): void { + // for (const type of KafkatorioSettingsConfig.types) { + // const settingName = KafkatorioSettingsConfig.cacheDurationSettingName(type) + // const seconds: double = settings.global[settingName].value as double + // this.eventCacheExpirationTicks[type] = seconds * 60 // convert ticks to seconds + // } + // } public initialiseSettings(data: Data): void { - const settings = KafkatorioSettingsConfig.types.map( - type => KafkatorioSettingsConfig.createDefaultCacheDuration(type) - ) - data.extend(settings) + for (const [type,] of pairs(KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds)) { + data.extend( + [ KafkatorioSettingsConfig.createDefaultCacheDuration(type)] + ) + } } @@ -64,7 +67,7 @@ export class KafkatorioSettingsConfig { private static cacheDurationSettingName(type: KafkatorioKeyedPacketTypes): string { - return `kafkatorio_event-cache_default-expiration-duration-seconds_${type.replaceAll(".", "-")}` + return `kafkatorio:cache-expiration-seconds_${type.replaceAll(".", "-")}` } } From e9f96fb0fce0a7ff49f2e8f62921d13e771541fe Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 18 May 2022 20:44:03 +0200 Subject: [PATCH 359/629] bump version --- build.gradle.kts | 2 +- .../factoriomod/FactorioModPortalPublishClient.kt | 15 +++------------ modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- modules/infra-factorio-server/src/.env | 2 +- modules/infra-kafka-cluster/src/.env | 2 +- modules/infra-kafka-pipe/src/.env | 2 +- 7 files changed, 9 insertions(+), 18 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index bf22b84..3be7830 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.5.0" +version = "0.5.1" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt index 5f4264d..f2268b7 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt @@ -83,11 +83,6 @@ class FactorioModPortalPublishClient( } ) -// val response = post(portalUploadEndpoint) { -// contentType(ContentType.MultiPart.FormData) -// setBody(Json.encodeToString(InitUploadRequest.serializer(), InitUploadRequest(modName))) -//// setBody(InitUploadRequest(modName)) -// } println(response) val initUploadResponse: InitUploadResponse = Json.decodeFromString(InitUploadResponse.serializer(), response.bodyAsText()) @@ -114,21 +109,17 @@ class FactorioModPortalPublishClient( ) } - val response = post(initUploadResponse.uploadUrl) { setBody(MultiPartFormDataContent(requestForm)) } - -// val response = submitFormWithBinaryData(initUploadResponse.uploadUrl, requestForm) { -// header(HttpHeaders.Authorization, "Bearer $portalApiKey") -// } - val submitUploadResponse = Json.decodeFromString(SubmitUploadResponse.serializer(), response.bodyAsText()) println(response) println(submitUploadResponse) - require(response.status.isSuccess() && submitUploadResponse is SubmitUploadResponse.Success) { "upload request failed" } + require(response.status.isSuccess() && submitUploadResponse is SubmitUploadResponse.Success) { + "upload request failed" + } } } diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 5237b02..443a0a5 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.5.0", + "version": "0.5.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index be98670..00a1cab 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.5.0", + "version": "0.5.1", "private": true, "scripts": { "build": "tstl", diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index ebb5815..73c834b 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio FACTORIO_VERSION=1.1.59 -KAFKATORIO_VERSION=0.5.0 +KAFKATORIO_VERSION=0.5.1 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index 0a2bf58..0ba8dd3 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,6 +1,6 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio GRAFANA_VERSION=8.5.0 -KAFKATORIO_VERSION=0.5.0 +KAFKATORIO_VERSION=0.5.1 KAFKA_VERSION=3.1.0 PROMETHEUS_VERSION=v2.34.0 diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index dddbc40..db082c3 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.5.0 +KAFKATORIO_VERSION=0.5.1 From 9f48270a0aa82cb3d5b291523c88e618f911bb03 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 19 May 2022 23:12:44 +0200 Subject: [PATCH 360/629] tidy up UpdatePackageJson task, tidy up some Gradle config --- buildSrc/build.gradle.kts | 8 +- .../task/JsonPropertiesUpToDateSpec.kt | 46 +++++------ .../kafkatorio/task/UpdatePackageJson.kt | 45 ++++------- modules/events-mod/build.gradle.kts | 78 +++++-------------- 4 files changed, 58 insertions(+), 119 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 0b83ac0..47649fd 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -82,11 +82,11 @@ tasks.withType().configureEach { kotlinOptions.freeCompilerArgs += listOf( // "-Xcontext-receivers", - "-Xopt-in=kotlin.RequiresOptIn", - "-Xopt-in=kotlin.ExperimentalStdlibApi", - "-Xopt-in=kotlin.time.ExperimentalTime", + "-opt-in=kotlin.RequiresOptIn", + "-opt-in=kotlin.ExperimentalStdlibApi", + "-opt-in=kotlin.time.ExperimentalTime", // "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi", + "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", ) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt index 0985fb0..c180df7 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt @@ -1,8 +1,5 @@ package dev.adamko.kafkatorio.task -import dev.adamko.kafkatorio.jsonMapper -import kotlinx.serialization.json.jsonObject -import kotlinx.serialization.json.jsonPrimitive import org.gradle.api.Task import org.gradle.api.internal.specs.ExplainingSpec @@ -13,34 +10,29 @@ object JsonPropertiesUpToDateSpec : ExplainingSpec { // Returns a description explaining why the task is outdated, // or null if the task is up to date - override fun whyUnsatisfied(element: Task?): String? = with(element) { - when (this) { - null -> "task is null" + override fun whyUnsatisfied(task: Task?): String? { + require(task is UpdatePackageJson) { "$task is not a UpdatePackageJson task" } - !is UpdatePackageJson -> - "task ${this::class.simpleName} is not instance of ${UpdatePackageJson::class.simpleName}" + val current = task.currentPackageJson() + val updated = task.updatedPackageJson(current) - else -> { + return if (current != updated) { + (current.keys + updated.keys) + .asSequence() + .distinct() + .sorted() + .mapNotNull { + val currentVal = current[it] + val updatedVal = updated[it] - val packageJsonContent = packageJsonFile2.get().asFile.readText() - val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject - - val outdatedProperties = propertiesToCheck.get().mapNotNull { (key, expectedVal) -> - val actualVal = packageJson[key]?.jsonPrimitive?.content - when { - expectedVal == actualVal -> null - else -> "'$key' (expected: $expectedVal, actual: $actualVal)" + if (currentVal == updatedVal) { + null + } else { + "'$it' - expected:$updatedVal, actual:$currentVal" } - } - - when { - outdatedProperties.isEmpty() -> null - outdatedProperties.size == 1 -> - "package.json has outdated property: ${outdatedProperties.single()}" - else -> - "package.json has outdated properties: ${outdatedProperties.joinToString(", ")}" - } - } + }.joinToString(prefix = "package.json is not up to date. ") + } else { + null } } } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt index 0c55c92..d4ce73f 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt @@ -4,8 +4,8 @@ import com.github.gradle.node.NodePlugin import dev.adamko.kafkatorio.jsonMapper import javax.inject.Inject import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.jsonObject import org.gradle.api.DefaultTask import org.gradle.api.file.RegularFileProperty @@ -13,7 +13,6 @@ import org.gradle.api.provider.MapProperty import org.gradle.api.provider.ProviderFactory import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.Input -import org.gradle.api.tasks.Internal import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import org.gradle.kotlin.dsl.support.useToRun @@ -27,9 +26,9 @@ abstract class UpdatePackageJson @Inject constructor( @get:Input abstract val propertiesToCheck: MapProperty -// @get:OutputFile - @get:Internal - abstract val packageJsonFile2: RegularFileProperty + @get:OutputFile + abstract val packageJsonFile: RegularFileProperty + init { group = NodePlugin.NODE_GROUP @@ -37,34 +36,16 @@ abstract class UpdatePackageJson @Inject constructor( "Read the package.json file and update the version and name, based on the project." outputs.upToDateWhen(JsonPropertiesUpToDateSpec) - -// super.doFirst { -// propertiesToCheck.disallowChanges() -// packageJsonFile.disallowChanges() -// } } - init { - outputs.upToDateWhen { task -> - require(task is UpdatePackageJson) { "$task is not a UpdatePackageJson task" } - - val currentPackageJson = task.currentPackageJson() - val updatedPackageJson = task.updatedPackageJson(currentPackageJson) - - val status = currentPackageJson == updatedPackageJson - logger.lifecycle("package.json is ${if (status) "up to date" else "not up to date"}") - status - } - } @TaskAction fun exec() { - val packageJsonFile = packageJsonFile2.asFile.get() + val packageJsonFile = packageJsonFile.asFile.get() logger.lifecycle("updating package.json ${packageJsonFile.canonicalPath}") - val currentPackageJson = currentPackageJson() - val updatedPackageJson = updatedPackageJson(currentPackageJson) + val updatedPackageJson = updatedPackageJson() val packageJsonContentUpdated = jsonMapper @@ -78,14 +59,18 @@ abstract class UpdatePackageJson @Inject constructor( } } - private fun currentPackageJson(): JsonObject { - val packageJsonFile = packageJsonFile2.asFile.get() + internal fun currentPackageJson(): JsonObject { + val packageJsonFile = packageJsonFile.get().asFile return jsonMapper.parseToJsonElement(packageJsonFile.readText()).jsonObject } - private fun updatedPackageJson(currentPackageJson: JsonObject): JsonObject { - val propertiesToCheck = propertiesToCheck.get() - val newJsonProps = propertiesToCheck.mapValues { (_, newVal) -> JsonPrimitive(newVal) } + internal fun updatedPackageJson( + currentPackageJson: JsonObject = currentPackageJson(), + ): JsonObject { + val propertiesToCheck: Map = propertiesToCheck.get() + val newJsonProps = propertiesToCheck.mapValues { (_, newVal) -> + jsonMapper.parseToJsonElement(newVal) + } return JsonObject(currentPackageJson + newJsonProps) } } diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index ef92cbd..4277a63 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -119,6 +119,8 @@ tasks.distZip { val publishMod by tasks.registering(FactorioModPublishTask::class) { + dependsOn(tasks.check) + distributionZip.set(tasks.distZip.flatMap { it.archiveFile }) val projectModName = project.extra.get("modName") as String @@ -156,65 +158,8 @@ distributions { tasks.withType().configureEach { val projectTokensXX = projectTokensX inputs.property("projectTokens", projectTokensXX) -// if (name.startsWith("dist")) { -// notCompatibleWithConfigurationCache("NPE on projectTokens") -// } } -//tasks.npmInstall { -// nodeModulesOutputFilter { -// exclude("**/typed-factorio/generated/classes.d.ts") -// } -//} - -//interface ServiceProvider { -// @get:Inject -// val fs: FileSystemOperations -//} -// -//val fixLink by tasks.registering { -// dependsOn(tasks.npmInstall) -// -// -// val badLink = """{@link https://lua-api.factorio.com/latest/Data-Lifecycle.html Data Lifecycle}""" -// val goodLink = """https://lua-api.factorio.com/latest/Data-Lifecycle.html""" -// -// val typedFactorioDir = -// layout.projectDirectory.dir("src/main/typescript/node_modules/typed-factorio") -// val classesDTS = typedFactorioDir.file("generated/classes.d.ts") -// -// val services = project.objects.newInstance() -// -// inputs.file(classesDTS) -// outputs.file(classesDTS) -// -// inputs.property("badLink", badLink) -// inputs.property("goodLink", goodLink) -// -// doLast { -// logger.lifecycle("fixing link ${classesDTS.asFile.canonicalPath}") -// -// services.fs.sync { -// from(classesDTS) -// into(temporaryDir) -// filter { line -> -// when { -// line.contains(badLink) -> line.replace(badLink, goodLink) -// else -> line -// } -// } -// } -// -// services.fs.copy { -// from(temporaryDir.resolve("classes.d.ts").canonicalPath) -// into(classesDTS.asFile.parent) -// duplicatesStrategy = DuplicatesStrategy.WARN -// } -// } -//} -// -//tasks.assemble { dependsOn(fixLink) } - //val downloadFactorioApiDocs by tasks.registering { // group = project.name @@ -259,7 +204,7 @@ tasks.updatePackageJson { inputs.property("packageJsonName", packageJsonName) propertiesToCheck.put("name", packageJsonName) val pjProvider = layout.projectDirectory.file(provider { "package.json" }) - packageJsonFile2.set(pjProvider) + packageJsonFile.set(pjProvider) } @@ -296,3 +241,20 @@ tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) } // } // } //} + +idea { + module { + sourceDirs = sourceDirs + file("src/main/typescript") + resourceDirs = resourceDirs + file("src/main/resources") + testSourceDirs = testSourceDirs + file("src/test/typescript") + iml { + whenMerged { + require(this is org.gradle.plugins.ide.idea.model.Module) + + sourceDirs = sourceDirs + file("src/main/typescript") + resourceDirs = resourceDirs + file("src/main/resources") + testSourceDirs = testSourceDirs + file("src/test/typescript") + } + } + } +} From 227ac276529153f81ffc66d67442f6f1eb7237dd Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 21 May 2022 12:44:51 +0200 Subject: [PATCH 361/629] make gradle zip directory drop helper function nicer --- .../main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt | 7 ++++++- modules/events-mod/build.gradle.kts | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt index 3bb8f13..ba24bdc 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt @@ -74,5 +74,10 @@ fun Directory.filesChecksum() = asFileTree /** Drop the first [count] directories from the path */ -fun FileCopyDetails.dropDirectories(count: Int = 1): RelativePath = +fun FileCopyDetails.dropDirectories(count: Int): RelativePath = RelativePath(true, *relativePath.segments.drop(count).toTypedArray()) + + +/** Drop the first directory from the path */ +fun FileCopyDetails.dropDirectory(): RelativePath = + dropDirectories(1) diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 4277a63..d9819c1 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -1,7 +1,7 @@ import dev.adamko.kafkatorio.factoriomod.FactorioModPublishTask import dev.adamko.kafkatorio.gradle.asConsumer import dev.adamko.kafkatorio.gradle.asProvider -import dev.adamko.kafkatorio.gradle.dropDirectories +import dev.adamko.kafkatorio.gradle.dropDirectory import dev.adamko.kafkatorio.gradle.factorioModAttributes import dev.adamko.kafkatorio.gradle.typescriptAttributes import dev.adamko.kafkatorio.task.TypescriptToLuaTask @@ -99,7 +99,7 @@ val installEventsTsSchema by tasks.registering(Sync::class) { } ) { // drop the first directory inside the zip - eachFile { relativePath = dropDirectories() } + eachFile { relativePath = dropDirectory() } includeEmptyDirs = false } into(outputDir) From c3ac4d022209aba97bfada99e4c0ff536f31c00e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 21 May 2022 12:45:37 +0200 Subject: [PATCH 362/629] add ktor, kotlinx artifacts to libs.versions.toml --- gradle/libs.versions.toml | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0b1fd4e..e6522ec 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -28,6 +28,7 @@ kotlinx-html = "0.7.5" kotlinx-nodejs = "0.0.7" kotlinx-coroutines = "1.6.1" kotlinx-cli = "0.3.4" +kotlinx-datetime = "0.3.3" ktor = "2.0.1" @@ -79,11 +80,12 @@ kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotl kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version.ref = "kotlinx-html" } kotlinx-nodejs = { group = "org.jetbrains.kotlinx", name = "kotlinx-nodejs", version.ref = "kotlinx-nodejs" } kotlinx-cli = { group = "org.jetbrains.kotlinx", name = "kotlinx-cli", version.ref = "kotlinx-cli" } +kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinx-datetime" } + kotlin-jsWrappers-bom = { group = "org.jetbrains.kotlin-wrappers", name = "kotlin-wrappers-bom", version.ref = "kotlinJsWrappers" } - ## http4k ## http4k-bom = { group = "org.http4k", name = "http4k-bom", version.ref = "http4k" } http4k-core = { group = "org.http4k", name = "http4k-core" } @@ -112,7 +114,34 @@ ktor-clientResources = { group = "io.ktor", name = "ktor-client-resour ktor-clientWebsockets = { group = "io.ktor", name = "ktor-client-websockets" } ktor-serializationKotlinxJson = { group = "io.ktor", name = "ktor-serialization-kotlinx-json" } + +ktor-serverCore = { group = "io.ktor", name = "ktor-server-core" } +ktor-serverNetty = { group = "io.ktor", name = "ktor-server-netty" } +ktor-serverContentNegotiaion = { group = "io.ktor", name = "ktor-server-content-negotiation" } +ktor-serverCors = { group = "io.ktor", name = "ktor-server-cors" } +ktor-serverResources = { group = "io.ktor", name = "ktor-server-resources" } +ktor-serverAutoHeadResponse = { group = "io.ktor", name = "ktor-server-auto-head-response" } +ktor-serverStatusPages = { group = "io.ktor", name = "ktor-server-status-pages" } +ktor-serverAuth = { group = "io.ktor", name = "ktor-server-auth" } +ktor-serverAuthJwt = { group = "io.ktor", name = "ktor-server-auth-jwt" } +ktor-serverSessions = { group = "io.ktor", name = "ktor-server-sessions" } +ktor-serverDataConversion = { group = "io.ktor", name = "ktor-server-data-conversion" } +ktor-serverDefaultHeaders = { group = "io.ktor", name = "ktor-server-default-headers" } +ktor-serverCompression = { group = "io.ktor", name = "ktor-server-compression" } +ktor-serverCachingHeaders = { group = "io.ktor", name = "ktor-server-caching-headers" } +ktor-serverConditionalHeaders = { group = "io.ktor", name = "ktor-server-conditional-headers" } +ktor-serverForwardedHeader = { group = "io.ktor", name = "ktor-server-forwarded-header" } +ktor-serverHsts = { group = "io.ktor", name = "ktor-server-hsts" } +ktor-serverHttpRedirect = { group = "io.ktor", name = "ktor-server-http-redirect" } +ktor-serverPartialContent = { group = "io.ktor", name = "ktor-server-partial-content" } +ktor-serverWebsockets = { group = "io.ktor", name = "ktor-server-websockets" } +ktor-serverCallLogging = { group = "io.ktor", name = "ktor-server-call-logging" } +ktor-serverCallId = { group = "io.ktor", name = "ktor-server-call-id" } + +ktor-network = { group = "io.ktor", name = "ktor-network" } + ktor-test-clientMock = { group = "io.ktor", name = "ktor-client-mock" } +ktor-test-serverHost = { group = "io.ktor", name = "ktor-server-test-host" } ### jackson ## #jackson-bom = { group = " com.fasterxml.jackson.module", name = ":jackson-module-kotlin", version = "2.13.+" } @@ -139,6 +168,9 @@ kafka-streamsTestUtils = { group = "org.apache.kafka", name = "kafka-streams-tes kafka-kotkaStreams = { group = "com.github.adamko-dev.kotka-streams", name = "kotka-streams", version = "v22.04.24" } + +rocksdb = { group = "io.maryk.rocksdb", name = "rocksdb-multiplatform", version = "7.0.3" } + jsoup = { group = "org.jsoup", name = "jsoup", version = "1.14.3" } skrapeit = { group = "it.skrape", name = "skrapeit", version = "1.2.0" } From 540d1c9ed3dfd05b709d0edb7ab149be9e2936d5 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 21 May 2022 13:14:59 +0200 Subject: [PATCH 363/629] fix success response for factorio mod upload --- .../main/kotlin/dev/adamko/kafkatorio/factoriomod/model.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/model.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/model.kt index 3ab3770..7143612 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/model.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/model.kt @@ -38,7 +38,9 @@ sealed interface InitUploadResponse { sealed interface SubmitUploadResponse { @Serializable - object Success : SubmitUploadResponse + data class Success( + val success: Boolean + ) : SubmitUploadResponse object Serializer : JsonContentPolymorphicSerializer( SubmitUploadResponse::class From 3416ae27587d67d42caf16e77f6c0dabc8be61dd Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 24 May 2022 17:39:46 +0200 Subject: [PATCH 364/629] webmap: try improving leaflet map, create separate layer for player icons, tidy up redux state store stuff --- .../dev/adamko/kafkatorio/webmap/App.kt | 10 +- .../dev/adamko/kafkatorio/webmap/map.kt | 88 ++++--- .../dev/adamko/kafkatorio/webmap/state.kt | 234 ++++++++++-------- 3 files changed, 187 insertions(+), 145 deletions(-) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index 889868f..dc0d26f 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -9,6 +9,7 @@ import io.kvision.CoreModule import io.kvision.FontAwesomeModule import io.kvision.html.div import io.kvision.maps.Maps +import io.kvision.maps.Maps.Companion.L import io.kvision.maps.externals.leaflet.layer.tile.GridLayer import io.kvision.module import io.kvision.panel.root @@ -23,7 +24,7 @@ import org.w3c.dom.asList class App( reduxStore: ReduxStore, - wsService: WebsocketService + wsService: WebsocketService, ) : Application() { private var appState: MutableMap = mutableMapOf() @@ -37,7 +38,7 @@ class App( } private val kvMaps: Maps - get() = reduxStore.getState().kvMaps + get() = reduxStore.getState().map.kvMap override fun start(state: Map) { this.appState = state.toMutableMap() @@ -54,6 +55,7 @@ class App( it.redraw() } }) + // this.asDynamic()._fadeAnimated = false } @@ -85,9 +87,7 @@ class App( } } - override fun dispose(): Map { - return appState - } + override fun dispose(): Map = appState } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index c614b94..93de604 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -3,36 +3,70 @@ package dev.adamko.kafkatorio.webmap import io.kvision.maps.Maps import io.kvision.maps.Maps.Companion.L import io.kvision.maps.externals.leaflet.DoneCallback +import io.kvision.maps.externals.leaflet.control.Control +import io.kvision.maps.externals.leaflet.control.Layers +import io.kvision.maps.externals.leaflet.control.set import io.kvision.maps.externals.leaflet.geo.CRS import io.kvision.maps.externals.leaflet.geo.LatLng +import io.kvision.maps.externals.leaflet.layer.LayerGroup import io.kvision.maps.externals.leaflet.layer.tile.TileLayer +import io.kvision.utils.obj import io.kvision.utils.px import org.w3c.dom.HTMLElement -// -//val polyline = Maps.L.polyline( -// listOf( -// LatLng(55, 2), -// LatLng(65, 2), -// LatLng(65, 20), -// LatLng(55, 20), -// LatLng(55, 2), -// ) -//) { -// noClip = true -//} -private const val tileUrlTemplate = """http://localhost:9073/tiles/s1/z{z}/x{x}/y{y}.png""" +class FactorioMap( + private val tileUrlTemplate: String = """http://localhost:9073/tiles/s1/z{z}/x{x}/y{y}.png""", +) { -fun createFactorioMap() = Maps { - width = 800.px - height = 800.px - margin = 10.px + val kvMap: Maps = Maps { + width = 800.px + height = 800.px + margin = 10.px + } - configureLeafletMap { - setView(center = LatLng(0, 0), zoom = 0) + val factorioTerrainLayer: TileLayer<*> = buildFactorioTerrainLayer() - val baseTileLayer: TileLayer = L.tileLayer( + val playerIconsLayer: LayerGroup = LayerGroup() + + init { + val baseLayers: Control.LayersObject = obj {} + baseLayers["Terrain"] = factorioTerrainLayer + + val overlays: Control.LayersObject = obj {} + overlays["Players"] = playerIconsLayer + + val layersControl = Layers( + baseLayers = baseLayers, + overlays = overlays, + options = obj { + sortLayers = true + } + ) + + kvMap.configureLeafletMap { + setView(center = LatLng(0, 0), zoom = 0) + + L.scale { + metric = true + imperial = false + }.addTo(this) + + options.crs = CRS.Simple + options.zoomSnap = 0 + options.zoomDelta = 0.1 +// options.fadeAnimation = false + addControl(layersControl) + + factorioTerrainLayer.addTo(this) + playerIconsLayer.addTo(this) + } + } + + + private fun buildFactorioTerrainLayer(): TileLayer { + + val baseTileLayer = L.tileLayer( tileUrlTemplate ) { attribution = "kafkatorio" @@ -60,18 +94,6 @@ fun createFactorioMap() = Maps { } } - baseTileLayer.addTo(this) - - L.scale { - metric = true - imperial = false - }.addTo(this) - - - options.crs = CRS.Simple - options.zoomSnap = 0 - options.zoomDelta = 0.1 - -// options.fadeAnimation = false + return baseTileLayer } } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt index 9ff75ab..52f4191 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt @@ -7,9 +7,9 @@ import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.common.toHexString import dev.adamko.kafkatorio.schema.packets.PlayerUpdate -import io.kvision.maps.Maps import io.kvision.maps.Maps.Companion.L import io.kvision.maps.externals.leaflet.geo.LatLng +import io.kvision.maps.externals.leaflet.layer.LayerGroup import io.kvision.maps.externals.leaflet.layer.overlay.Tooltip import io.kvision.maps.externals.leaflet.layer.vector.CircleMarker import io.kvision.redux.ReduxStore @@ -22,16 +22,26 @@ fun createFactorioReduxStore(): ReduxStore = createReduxStore( ::factorioGameReducer, FactorioGameState( - kvMaps = createFactorioMap(), - players = emptyMap() + map = FactorioMap(), + players = emptyMap(), ) ) data class FactorioGameState( - val kvMaps: Maps, + val map: FactorioMap, val players: Map, -) +) { + + val playerIconsLayer: LayerGroup + get() = map.playerIconsLayer + +// init { +// kvMaps.leafletMap { +// playerIconsLayer.addTo(this) +// } +// } +} sealed class FactorioUpdate : RAction { @@ -39,106 +49,92 @@ sealed class FactorioUpdate : RAction { } -fun factorioGameReducer(state: FactorioGameState, update: FactorioUpdate): FactorioGameState = +fun factorioGameReducer(gameState: FactorioGameState, update: FactorioUpdate): FactorioGameState = when (update) { - is FactorioUpdate.Player -> { - - val playerState = state.players.getOrElse(update.data.key.index) { - PlayerState(update.data.key.index, update.tick) - } - - playerState.update(update.tick, update.data) - - state.kvMaps.leafletMap { - - val playerMarker = playerState.mapMarker - - if (playerMarker != null) { - when (playerState.playerDetails) { - is PlayerDetailsState.Known -> if (!hasLayer(playerMarker)) addLayer(playerMarker) - is PlayerDetailsState.Unknown -> if (hasLayer(playerMarker)) removeLayer(playerMarker) - } - } - } - - val updatedPlayersState = state.players + (playerState.index to playerState) - state.copy(players = updatedPlayersState) - } + is FactorioUpdate.Player -> handlePlayerUpdate(gameState, update) } -class PlayerState( +private fun handlePlayerUpdate( + gameState: FactorioGameState, + update: FactorioUpdate.Player, +): FactorioGameState { + + val previous = gameState.players[update.data.key.index] + ?: PlayerState(update.data.key.index, update.tick) + + val updated = previous.update(update.tick, update.data) + + if (previous.mapMarker != updated.mapMarker) { + if (previous.mapMarker != null) { + println("removing player icon ${previous.index}") + gameState.playerIconsLayer.removeLayer(previous.mapMarker) + } + if (updated.mapMarker != null) { + println("adding player icon ${updated.index}") + gameState.playerIconsLayer.addLayer(updated.mapMarker) + } + } + + val updatedPlayersState = gameState.players + (previous.index to updated) + return gameState.copy(players = updatedPlayersState) +} + + +data class PlayerState( val index: PlayerIndex, - private var lastTick: Tick, + val lastTick: Tick, + val playerDetails: PlayerProperties = PlayerProperties.Partial(), + val mapMarker: CircleMarker? = null, ) { - var playerDetails: PlayerDetailsState = PlayerDetailsState.Unknown(index) - private set - var mapMarker: CircleMarker? = null - private set - - fun update(tick: Tick, update: PlayerUpdate) { + fun update(tick: Tick, update: PlayerUpdate): PlayerState { if (lastTick.value > tick.value) { println("discarding old PlayerUpdate, ${lastTick.value} > ${tick.value}") - return + return this } - this.lastTick = tick - this.playerDetails = updatePlayerDetails(update) - updateMapPosition() - - println("updated PlayerState index:${playerDetails.index}, name:${playerDetails.name}") - } - - private fun updatePlayerDetails(update: PlayerUpdate): PlayerDetailsState { - - val position = update.position ?: playerDetails.position - val surfaceIndex = update.surfaceIndex ?: playerDetails.surfaceIndex - val colour = update.colour ?: playerDetails.colour - val name = update.name ?: playerDetails.name - - return when { - position != null - && surfaceIndex != null - && colour != null - && name != null -> - PlayerDetailsState.Known( - index = playerDetails.index, - position = position, - surfaceIndex = surfaceIndex, - colour = colour, - name = name, - ) - - else -> - PlayerDetailsState.Unknown( - index = playerDetails.index, - position = position, - surfaceIndex = surfaceIndex, - colour = colour, - name = name, - ) - } + val newState = this.copy( + lastTick = tick, + playerDetails = playerDetails.update(update), + mapMarker = updateMapMarker() + ) + println("updated PlayerState index:${newState.index}, name:${newState.playerDetails.name}") + return newState } - private fun updateMapPosition() { + private fun updateMapMarker(): CircleMarker? { + return when (playerDetails) { - when (val details = playerDetails) { - is PlayerDetailsState.Unknown -> { - println("removing player ${details.index} map marker") - mapMarker?.remove() + is PlayerProperties.Partial -> { + println("removing player $index map marker") + null } - is PlayerDetailsState.Known -> updateMapMarker(details) - } + is PlayerProperties.Complete -> { + + val mapMarker = mapMarker ?: createMapMarker(playerDetails) + + mapMarker.apply { + options.color = playerDetails.hexColour + options.fillColor = playerDetails.hexColour + + val lat = playerDetails.latLng.lat.toInt() + val lng = playerDetails.latLng.lng.toInt() + + setTooltipContent("${playerDetails.name} [$lat, $lng]") + setLatLng(playerDetails.latLng) + } + } + } } - private fun updateMapMarker(playerDetails: PlayerDetailsState.Known) { - if (mapMarker == null) { - mapMarker = L.circleMarker(playerDetails.latLng) { + companion object { + private fun createMapMarker(playerDetails: PlayerProperties.Complete): CircleMarker = + L.circleMarker(playerDetails.latLng) { fillOpacity = 1f radius = 10 className = "player-marker" @@ -148,54 +144,78 @@ class PlayerState( // interactive = false }) } - } - - mapMarker?.apply { - val playerColour = playerDetails.colour.toHexString(false) - options.color = playerColour - options.fillColor = playerColour - - val lat = playerDetails.latLng.lat.toInt() - val lng = playerDetails.latLng.lng.toInt() - - setTooltipContent("${playerDetails.name} [$lat, $lng]") - setLatLng(playerDetails.latLng) - } - } } -sealed interface PlayerDetailsState { - - val index: PlayerIndex +sealed interface PlayerProperties { val position: MapEntityPosition? val surfaceIndex: SurfaceIndex? val colour: Colour? val name: String? val latLng: LatLng? + val isConnected: Boolean + val isShowOnMap: Boolean - data class Unknown( - override val index: PlayerIndex, + data class Partial( override val position: MapEntityPosition? = null, override val surfaceIndex: SurfaceIndex? = null, override val colour: Colour? = null, override val name: String? = null, - ) : PlayerDetailsState { + override val isConnected: Boolean = false, + override val isShowOnMap: Boolean = false, + ) : PlayerProperties { override val latLng: LatLng? = null } - data class Known( - override val index: PlayerIndex, + data class Complete( override val position: MapEntityPosition, override val surfaceIndex: SurfaceIndex, override val colour: Colour, override val name: String, - ) : PlayerDetailsState { + override val isConnected: Boolean = false, + override val isShowOnMap: Boolean = false, + ) : PlayerProperties { override val latLng: LatLng = position.latLng() + val hexColour: String = colour.toHexString(false) } + + fun update(update: PlayerUpdate): PlayerProperties { + + val position = update.position ?: this.position + val surfaceIndex = update.surfaceIndex ?: this.surfaceIndex + val colour = update.colour ?: this.colour + val name = update.name ?: this.name + val isConnected = update.isConnected ?: false + val isShowOnMap = update.isShowOnMap ?: false + + return when { + position != null + && surfaceIndex != null + && colour != null + && name != null -> + Complete( + position = position, + surfaceIndex = surfaceIndex, + colour = colour, + name = name, + isConnected = isConnected, + isShowOnMap = isShowOnMap, + ) + + else -> + Partial( + position = position, + surfaceIndex = surfaceIndex, + colour = colour, + name = name, + isConnected = isConnected, + isShowOnMap = isShowOnMap, + ) + } + } } From 9278172412a71fb1903ed3c7564cb858ba81491e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 24 May 2022 17:40:21 +0200 Subject: [PATCH 365/629] mod: try immediately outputting player logoff events --- modules/events-mod/package.json | 12 ++++++++---- .../main/events/onPlayerEventListeners.ts | 19 +++++++++++++++---- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 00a1cab..7116cf1 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -9,7 +9,8 @@ "engines": { "node": "~14.19.1" }, - "devDependencies": {}, + "devDependencies": { + }, "dependencies": { "lua-types": "^2.11.0", "typescript-to-lua": "1.4.4", @@ -17,7 +18,10 @@ "typescript": "4.6.2" }, "license": "UNLICENSED", - "peerDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": [] + "peerDependencies": { + }, + "optionalDependencies": { + }, + "bundledDependencies": [ + ] } diff --git a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts index fc3f751..500bb64 100644 --- a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts @@ -22,6 +22,7 @@ type PlayerUpdateEvent = function playerUpdateThrottle( event: PlayerUpdateEvent, mutate: PlayerUpdater, + expirationDurationTicks: uint | undefined = undefined, ) { const playerIndex = event.player_index if (playerIndex == undefined) { @@ -42,10 +43,20 @@ function playerUpdateThrottle( data.events ??= {} data.events[eventName] ??= [] data.events[eventName].push(event.tick) - } + }, + expirationDurationTicks ) } + +function playerUpdateImmediate( + event: PlayerUpdateEvent, + mutate: PlayerUpdater, +) { + playerUpdateThrottle(event, mutate, 0) +} + + // function playerUpdateDebounce(playerIndex: uint, mutate: PlayerUpdater) { // EventUpdatesManager.debounce<"PLAYER">( // {index: playerIndex, updateType: "PLAYER"}, @@ -151,7 +162,7 @@ function handleBannedEvent(event: OnPlayerBannedEvent | OnPlayerUnbannedEvent) { script.on_event( defines.events.on_player_kicked, (event: OnPlayerKickedEvent) => { - playerUpdateThrottle( + playerUpdateImmediate( event, (player, data) => { data.kickedReason = event.reason ?? null @@ -170,7 +181,7 @@ for (const [name, disconnectId] of pairs(defines.disconnect_reason)) { script.on_event( defines.events.on_pre_player_left_game, (event: OnPrePlayerLeftGameEvent) => { - playerUpdateThrottle( + playerUpdateImmediate( event, (player, data) => { data.disconnectReason = disconnectReasons.get(event.reason) @@ -183,7 +194,7 @@ script.on_event( script.on_event( defines.events.on_player_removed, (event: OnPlayerRemovedEvent) => { - playerUpdateThrottle( + playerUpdateImmediate( event, (player, data) => { data.isRemoved = true From aa4de3fb14103a7c34d954575b27147150216fda Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 24 May 2022 18:07:13 +0200 Subject: [PATCH 366/629] webmap: begin refactoring state classes... --- .../src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt | 3 +++ .../kotlin/dev/adamko/kafkatorio/webmap/{ => state}/state.kt | 4 +++- .../main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt | 5 +++-- 3 files changed, 9 insertions(+), 3 deletions(-) rename modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/{ => state}/state.kt (97%) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index dc0d26f..6d054fd 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -1,5 +1,8 @@ package dev.adamko.kafkatorio.webmap +import dev.adamko.kafkatorio.webmap.state.FactorioGameState +import dev.adamko.kafkatorio.webmap.state.FactorioUpdate +import dev.adamko.kafkatorio.webmap.state.createFactorioReduxStore import io.kvision.Application import io.kvision.BootstrapCssModule import io.kvision.BootstrapIconsModule diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt similarity index 97% rename from modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt rename to modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt index 52f4191..a9cb741 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.webmap +package dev.adamko.kafkatorio.webmap.state import dev.adamko.kafkatorio.schema.common.Colour import dev.adamko.kafkatorio.schema.common.MapEntityPosition @@ -7,6 +7,8 @@ import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.common.toHexString import dev.adamko.kafkatorio.schema.packets.PlayerUpdate +import dev.adamko.kafkatorio.webmap.FactorioMap +import dev.adamko.kafkatorio.webmap.latLng import io.kvision.maps.Maps.Companion.L import io.kvision.maps.externals.leaflet.geo.LatLng import io.kvision.maps.externals.leaflet.layer.LayerGroup diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt index cdeffb9..51e7708 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -9,8 +9,9 @@ import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate +import dev.adamko.kafkatorio.webmap.state.FactorioGameState +import dev.adamko.kafkatorio.webmap.state.FactorioUpdate import io.kvision.redux.ReduxStore -import kotlinx.serialization.decodeFromString import org.w3c.dom.MessageEvent import org.w3c.dom.WebSocket @@ -36,7 +37,7 @@ class WebsocketService( println(data.replace('\n', ' ')) - val packet: KafkatorioPacket = jsonMapper.decodeFromString(data) + val packet = jsonMapper.decodeFromString(KafkatorioPacket.serializer(), data) when (val packetData = packet.data) { From 187fca8b8cf54e1ad9dd8ba120ebda703d2693b2 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 24 May 2022 18:08:32 +0200 Subject: [PATCH 367/629] webmap: refactor state + update handling code, to separate files --- .../kafkatorio/webmap/state/playerState.kt | 181 +++++++++++++++++ .../adamko/kafkatorio/webmap/state/state.kt | 182 ------------------ 2 files changed, 181 insertions(+), 182 deletions(-) create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt new file mode 100644 index 0000000..1488696 --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt @@ -0,0 +1,181 @@ +package dev.adamko.kafkatorio.webmap.state + +import dev.adamko.kafkatorio.schema.common.Colour +import dev.adamko.kafkatorio.schema.common.MapEntityPosition +import dev.adamko.kafkatorio.schema.common.PlayerIndex +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.common.Tick +import dev.adamko.kafkatorio.schema.common.toHexString +import dev.adamko.kafkatorio.schema.packets.PlayerUpdate +import dev.adamko.kafkatorio.webmap.latLng +import io.kvision.maps.Maps +import io.kvision.maps.externals.leaflet.geo.LatLng +import io.kvision.maps.externals.leaflet.layer.overlay.Tooltip +import io.kvision.maps.externals.leaflet.layer.vector.CircleMarker +import io.kvision.utils.obj + + +fun handlePlayerUpdate( + gameState: FactorioGameState, + update: FactorioUpdate.Player, +): FactorioGameState { + + val previous = gameState.players[update.data.key.index] + ?: PlayerState(update.data.key.index, update.tick) + + val updated = previous.update(update.tick, update.data) + + if (previous.mapMarker != updated.mapMarker) { + if (previous.mapMarker != null) { + println("removing player icon ${previous.index}") + gameState.playerIconsLayer.removeLayer(previous.mapMarker) + } + if (updated.mapMarker != null) { + println("adding player icon ${updated.index}") + gameState.playerIconsLayer.addLayer(updated.mapMarker) + } + } + + val updatedPlayersState = gameState.players + (previous.index to updated) + return gameState.copy(players = updatedPlayersState) +} + + +data class PlayerState( + val index: PlayerIndex, + val lastTick: Tick, + val playerDetails: PlayerProperties = PlayerProperties.Partial(), + val mapMarker: CircleMarker? = null, +) { + + fun update(tick: Tick, update: PlayerUpdate): PlayerState { + + if (lastTick.value > tick.value) { + println("discarding old PlayerUpdate, ${lastTick.value} > ${tick.value}") + return this + } + + val newState = this.copy( + lastTick = tick, + playerDetails = playerDetails.update(update), + mapMarker = updateMapMarker() + ) + println("updated PlayerState index:${newState.index}, name:${newState.playerDetails.name}") + return newState + } + + + private fun updateMapMarker(): CircleMarker? { + return when (playerDetails) { + + is PlayerProperties.Partial -> { + println("removing player $index map marker") + null + } + + is PlayerProperties.Complete -> { + + val mapMarker = mapMarker ?: createMapMarker(playerDetails) + + mapMarker.apply { + options.color = playerDetails.hexColour + options.fillColor = playerDetails.hexColour + + val lat = playerDetails.latLng.lat.toInt() + val lng = playerDetails.latLng.lng.toInt() + + setTooltipContent("${playerDetails.name} [$lat, $lng]") + setLatLng(playerDetails.latLng) + } + } + } + } + + + companion object { + private fun createMapMarker(playerDetails: PlayerProperties.Complete): CircleMarker = + Maps.L.circleMarker(playerDetails.latLng) { + fillOpacity = 1f + radius = 10 + className = "player-marker" +// interactive = false + }.also { circle -> + circle.bindTooltip("", obj { +// interactive = false + }) + } + } +} + + +sealed interface PlayerProperties { + + val position: MapEntityPosition? + val surfaceIndex: SurfaceIndex? + val colour: Colour? + val name: String? + val latLng: LatLng? + val isConnected: Boolean + val isShowOnMap: Boolean + + + data class Partial( + override val position: MapEntityPosition? = null, + override val surfaceIndex: SurfaceIndex? = null, + override val colour: Colour? = null, + override val name: String? = null, + override val isConnected: Boolean = false, + override val isShowOnMap: Boolean = false, + ) : PlayerProperties { + override val latLng: LatLng? = null + } + + + data class Complete( + override val position: MapEntityPosition, + override val surfaceIndex: SurfaceIndex, + override val colour: Colour, + override val name: String, + override val isConnected: Boolean = false, + override val isShowOnMap: Boolean = false, + ) : PlayerProperties { + override val latLng: LatLng = position.latLng() + val hexColour: String = colour.toHexString(false) + } + + + fun update(update: PlayerUpdate): PlayerProperties { + + val position = update.position ?: this.position + val surfaceIndex = update.surfaceIndex ?: this.surfaceIndex + val colour = update.colour ?: this.colour + val name = update.name ?: this.name + val isConnected = update.isConnected ?: false + val isShowOnMap = update.isShowOnMap ?: false + + return when { + position != null + && surfaceIndex != null + && colour != null + && name != null -> + Complete( + position = position, + surfaceIndex = surfaceIndex, + colour = colour, + name = name, + isConnected = isConnected, + isShowOnMap = isShowOnMap, + ) + + else -> + Partial( + position = position, + surfaceIndex = surfaceIndex, + colour = colour, + name = name, + isConnected = isConnected, + isShowOnMap = isShowOnMap, + ) + } + } +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt index a9cb741..1e71ba4 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/state.kt @@ -1,22 +1,12 @@ package dev.adamko.kafkatorio.webmap.state -import dev.adamko.kafkatorio.schema.common.Colour -import dev.adamko.kafkatorio.schema.common.MapEntityPosition import dev.adamko.kafkatorio.schema.common.PlayerIndex -import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.Tick -import dev.adamko.kafkatorio.schema.common.toHexString import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.webmap.FactorioMap -import dev.adamko.kafkatorio.webmap.latLng -import io.kvision.maps.Maps.Companion.L -import io.kvision.maps.externals.leaflet.geo.LatLng import io.kvision.maps.externals.leaflet.layer.LayerGroup -import io.kvision.maps.externals.leaflet.layer.overlay.Tooltip -import io.kvision.maps.externals.leaflet.layer.vector.CircleMarker import io.kvision.redux.ReduxStore import io.kvision.redux.createReduxStore -import io.kvision.utils.obj import redux.RAction @@ -37,12 +27,6 @@ data class FactorioGameState( val playerIconsLayer: LayerGroup get() = map.playerIconsLayer - -// init { -// kvMaps.leafletMap { -// playerIconsLayer.addTo(this) -// } -// } } @@ -55,169 +39,3 @@ fun factorioGameReducer(gameState: FactorioGameState, update: FactorioUpdate): F when (update) { is FactorioUpdate.Player -> handlePlayerUpdate(gameState, update) } - - -private fun handlePlayerUpdate( - gameState: FactorioGameState, - update: FactorioUpdate.Player, -): FactorioGameState { - - val previous = gameState.players[update.data.key.index] - ?: PlayerState(update.data.key.index, update.tick) - - val updated = previous.update(update.tick, update.data) - - if (previous.mapMarker != updated.mapMarker) { - if (previous.mapMarker != null) { - println("removing player icon ${previous.index}") - gameState.playerIconsLayer.removeLayer(previous.mapMarker) - } - if (updated.mapMarker != null) { - println("adding player icon ${updated.index}") - gameState.playerIconsLayer.addLayer(updated.mapMarker) - } - } - - val updatedPlayersState = gameState.players + (previous.index to updated) - return gameState.copy(players = updatedPlayersState) -} - - -data class PlayerState( - val index: PlayerIndex, - val lastTick: Tick, - val playerDetails: PlayerProperties = PlayerProperties.Partial(), - val mapMarker: CircleMarker? = null, -) { - - fun update(tick: Tick, update: PlayerUpdate): PlayerState { - - if (lastTick.value > tick.value) { - println("discarding old PlayerUpdate, ${lastTick.value} > ${tick.value}") - return this - } - - val newState = this.copy( - lastTick = tick, - playerDetails = playerDetails.update(update), - mapMarker = updateMapMarker() - ) - println("updated PlayerState index:${newState.index}, name:${newState.playerDetails.name}") - return newState - } - - - private fun updateMapMarker(): CircleMarker? { - return when (playerDetails) { - - is PlayerProperties.Partial -> { - println("removing player $index map marker") - null - } - - is PlayerProperties.Complete -> { - - val mapMarker = mapMarker ?: createMapMarker(playerDetails) - - mapMarker.apply { - options.color = playerDetails.hexColour - options.fillColor = playerDetails.hexColour - - val lat = playerDetails.latLng.lat.toInt() - val lng = playerDetails.latLng.lng.toInt() - - setTooltipContent("${playerDetails.name} [$lat, $lng]") - setLatLng(playerDetails.latLng) - } - } - } - } - - - companion object { - private fun createMapMarker(playerDetails: PlayerProperties.Complete): CircleMarker = - L.circleMarker(playerDetails.latLng) { - fillOpacity = 1f - radius = 10 - className = "player-marker" -// interactive = false - }.also { circle -> - circle.bindTooltip("", obj { -// interactive = false - }) - } - } -} - - -sealed interface PlayerProperties { - - val position: MapEntityPosition? - val surfaceIndex: SurfaceIndex? - val colour: Colour? - val name: String? - val latLng: LatLng? - val isConnected: Boolean - val isShowOnMap: Boolean - - - data class Partial( - override val position: MapEntityPosition? = null, - override val surfaceIndex: SurfaceIndex? = null, - override val colour: Colour? = null, - override val name: String? = null, - override val isConnected: Boolean = false, - override val isShowOnMap: Boolean = false, - ) : PlayerProperties { - override val latLng: LatLng? = null - } - - - data class Complete( - override val position: MapEntityPosition, - override val surfaceIndex: SurfaceIndex, - override val colour: Colour, - override val name: String, - override val isConnected: Boolean = false, - override val isShowOnMap: Boolean = false, - ) : PlayerProperties { - override val latLng: LatLng = position.latLng() - val hexColour: String = colour.toHexString(false) - } - - - fun update(update: PlayerUpdate): PlayerProperties { - - val position = update.position ?: this.position - val surfaceIndex = update.surfaceIndex ?: this.surfaceIndex - val colour = update.colour ?: this.colour - val name = update.name ?: this.name - val isConnected = update.isConnected ?: false - val isShowOnMap = update.isShowOnMap ?: false - - return when { - position != null - && surfaceIndex != null - && colour != null - && name != null -> - Complete( - position = position, - surfaceIndex = surfaceIndex, - colour = colour, - name = name, - isConnected = isConnected, - isShowOnMap = isShowOnMap, - ) - - else -> - Partial( - position = position, - surfaceIndex = surfaceIndex, - colour = colour, - name = name, - isConnected = isConnected, - isShowOnMap = isShowOnMap, - ) - } - } -} From b15382660bfe7f0d18a5d5837fec2ad73cc618d4 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 25 May 2022 12:47:23 +0200 Subject: [PATCH 368/629] bump some versions --- gradle/libs.versions.toml | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e6522ec..853a06e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,8 +10,8 @@ kotlin = "1.6.21" ## libs ## camel-kafkaConnectors = "0.11.0" -http4k = "4.25.12.0" -kafka = "3.1.0" +http4k = "4.25.16.2" +kafka = "3.2.0" kvision = "5.10.0" log4j2 = "2.17.2" qosLogback = "1.2.11" @@ -21,17 +21,18 @@ scrimage = "4.0.31" semver = "1.2.0" kotlinx-serialization = "1.3.3" -kxs-yaml = "0.43.0" +kxs-yaml = "0.44.0" -kotlinJsWrappers = "0.0.1-pre.334" +kotlinJsWrappers = "1.0.0-pre.339" kotlinx-html = "0.7.5" kotlinx-nodejs = "0.0.7" kotlinx-coroutines = "1.6.1" kotlinx-cli = "0.3.4" kotlinx-datetime = "0.3.3" -ktor = "2.0.1" +ktor = "2.0.1" +kotkaStreams = "v22.05.25" ## test ## junit = "5.8.2" @@ -45,7 +46,7 @@ grafana = "8.5.0" prometheus = "v2.34.0" ## gradle plugins ## -gradleNodePlugin = "3.2.1" +gradleNodePlugin = "3.3.0" ######### [plugins] @@ -67,10 +68,12 @@ loggingCapabilities = { id = "dev.jacomet.logging-capabilities", vers ## kotlin ## kotlin-bom = { group = "org.jetbrains.kotlin", name = "kotlin-bom", version.ref = "kotlin" } -kotlinx-serialization-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-bom", version.ref = "kotlinx-serialization" } -kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core" } -kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json" } -kotlinx-serialization-protobuf = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-protobuf" } +kotlinx-serialization-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-bom", version.ref = "kotlinx-serialization" } +kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core" } +kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json" } +kotlinx-serialization-protobuf = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-protobuf" } +kotlinx-serialization-cbor = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-cbor" } +kotlinx-serialization-properties = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-properties" } kotlinx-serialization-yaml = { group = "com.charleskorn.kaml", name = "kaml", version.ref = "kxs-yaml" } @@ -166,7 +169,7 @@ kafka-streamsTestUtils = { group = "org.apache.kafka", name = "kafka-streams-tes # kafka helpers #kotka = { group = "com.github.blueanvil", name = "kotka", version = "1.1.1" } -kafka-kotkaStreams = { group = "com.github.adamko-dev.kotka-streams", name = "kotka-streams", version = "v22.04.24" } +kafka-kotkaStreams = { group = "com.github.adamko-dev.kotka-streams", name = "kotka-streams", version.ref = "kotkaStreams" } rocksdb = { group = "io.maryk.rocksdb", name = "rocksdb-multiplatform", version = "7.0.3" } From 8c37a0cef9afaecb0a4d1dd10b6962ec6488c92d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Wed, 25 May 2022 12:50:34 +0200 Subject: [PATCH 369/629] trigger tile png reload in browser by sending 'saved tile' events over websocket - create new EventServerPacket for websocket packet data - move common models to events-schema --- .../kafkatorio/schema/common/factorioIds.kt | 7 ++ .../kafkatorio/schema/common/mapTile.kt | 26 ++++++- .../schema/packets/eventServerPacket.kt | 27 +++++++ .../processor/KafkatorioTopology.kt | 10 +-- .../processor/admin/kafkatorioTopics.kt | 5 ++ .../processor/tileserver/WebMapTileServer.kt | 6 +- .../processor/topology/colourMapChunks.kt | 2 + .../topology/factorioServerPackets.kt | 1 + .../kafkatorio/processor/topology/model.kt | 20 +----- .../processor/topology/packetDataStreams.kt | 1 + .../processor/topology/playerUpdates.kt | 46 ++++++++++-- .../processor/topology/prototypes.kt | 1 + .../processor/topology/saveMapTiles.kt | 44 ++++++++---- .../processor/misc/KxsBinaryTests.kt | 7 +- .../kafkatorio/processor/misc/serdeSize.kt | 10 ++- .../processor/topology/SaveMapChunksTest.kt | 2 + .../dev/adamko/kafkatorio/webmap/App.kt | 71 ++++++++++--------- .../dev/adamko/kafkatorio/webmap/map.kt | 64 ++++++++++++++++- .../adamko/kafkatorio/webmap/websockets.kt | 61 +++++++++++----- 19 files changed, 303 insertions(+), 108 deletions(-) create mode 100644 modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/eventServerPacket.kt diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt index 5f50aec..9384d90 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt @@ -75,3 +75,10 @@ data class EntityIdentifiersData( override val name: String, override val protoType: String, ) : EntityIdentifiers + + +@JvmInline +@Serializable +value class FactorioServerId(private val id: String) { + override fun toString() = id +} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt index be80d62..360554b 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt @@ -1,10 +1,10 @@ package dev.adamko.kafkatorio.schema.common + import dev.adamko.kafkatorio.schema.common.MapTileDictionary.PrototypeKey import kotlin.jvm.JvmInline import kotlinx.serialization.Serializable - const val MAP_CHUNK_SIZE = 32 @@ -69,3 +69,27 @@ data class MapBoundingBox( val topLeft: MapTilePosition, val bottomRight: MapTilePosition, ) + + +@Serializable +data class ServerMapChunkId( + val serverId: FactorioServerId, + val chunkPosition: MapChunkPosition, + val surfaceIndex: SurfaceIndex, + val chunkSize: ChunkSize, +) + + +@Serializable +@JvmInline +value class TilePngFilename( + val value: String, +) { + constructor(id: ServerMapChunkId) : this(buildString { + append("s${id.surfaceIndex}") + append("/z${id.chunkSize.zoomLevel}") + append("/x${id.chunkPosition.x}") + append("/y${id.chunkPosition.y}") + append(".png") + }) +} diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/eventServerPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/eventServerPacket.kt new file mode 100644 index 0000000..363aded --- /dev/null +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/eventServerPacket.kt @@ -0,0 +1,27 @@ +package dev.adamko.kafkatorio.schema.packets + +import dev.adamko.kafkatorio.schema.common.ServerMapChunkId +import dev.adamko.kafkatorio.schema.common.TilePngFilename +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + + +@Serializable +sealed class EventServerPacket { + + + @Serializable + @SerialName("kafkatorio.event-server-packet.Kafkatorio") + data class Kafkatorio( + val packet: KafkatorioPacket + ) : EventServerPacket() + + + @Serializable + @SerialName("kafkatorio.event-server-packet.ChunkTileSaved") + data class ChunkTileSaved( + val chunkId: ServerMapChunkId, + val filename: TilePngFilename, + ) : EventServerPacket() + +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 342a85f..179863e 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -3,7 +3,7 @@ package dev.adamko.kafkatorio.processor import dev.adamko.kafkatorio.processor.config.ApplicationProperties import dev.adamko.kafkatorio.processor.topology.colourMapChunks import dev.adamko.kafkatorio.processor.topology.factorioServerPacketStream -import dev.adamko.kafkatorio.processor.topology.playerUpdatesToWsServer +import dev.adamko.kafkatorio.processor.topology.broadcastToWebsocket import dev.adamko.kafkatorio.processor.topology.saveMapTiles import dev.adamko.kafkatorio.processor.topology.splitFactorioServerPacketStream import java.time.Duration @@ -39,7 +39,7 @@ internal class KafkatorioTopology( groupTilesMapChunks() saveTiles() - playerUpdates() + websocketBroadcaster() } private fun splitPackets() { @@ -64,13 +64,13 @@ internal class KafkatorioTopology( launchTopology("saveTiles", topology) } - private fun playerUpdates() { + private fun websocketBroadcaster() { val builder = StreamsBuilder() - playerUpdatesToWsServer(websocketServer, builder) + broadcastToWebsocket(websocketServer, builder) val topology = builder.build() - launchTopology("playerUpdates", topology) + launchTopology("websocketBroadcaster", topology) } private fun launchTopology( diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt index bb287e0..1bbfe9e 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt @@ -26,6 +26,9 @@ const val TOPIC_SUBDIVIDED_MAP_TILES = "$DOMAIN.map-tiles.subdivided" const val TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED = "$TOPIC_SUBDIVIDED_MAP_TILES.debounced" +/** Broadcast these events out, via websocket */ +const val TOPIC_BROADCAST_TO_WEBSOCKET = "$DOMAIN.broadcast.websocket" + fun allTopics(): Set = buildSet { add(TOPIC_SRC_SERVER_LOG) @@ -38,6 +41,8 @@ fun allTopics(): Set = buildSet { add(TOPIC_SUBDIVIDED_MAP_TILES) add(TOPIC_SUBDIVIDED_MAP_TILES_DEBOUNCED) + add(TOPIC_BROADCAST_TO_WEBSOCKET) + addAll(packetTopicNames.values) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt index a01aaea..0519684 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt @@ -100,19 +100,19 @@ internal class WebMapTileServer( currentETag == null -> { // println("[${request.etagKey}] currentETag is null (requested: $requestedETag), executing request") response - .header("Cache-Control", "no-cache") + .header("Cache-Control", "no-cache, max-age=0, must-revalidate") } requestedETag == currentETag -> { // println("[${request.etagKey}] currentETag == requested, returning 304 $requestedETag") Response(Status.NOT_MODIFIED) - .header("Cache-Control", "no-cache") + .header("Cache-Control", "no-cache, max-age=0, must-revalidate") } else -> { // println("[${request.etagKey}] currentETag != requested, executing request and adding currentETag:$currentETag (requested:$requestedETag)") response .header("ETag", currentETag) // .header("Cache-Control", "no-store") - .header("Cache-Control", "no-cache") + .header("Cache-Control", "no-cache, max-age=0, must-revalidate") } } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt index e9c7525..2a171f0 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt @@ -6,6 +6,8 @@ import dev.adamko.kafkatorio.processor.misc.DebounceProcessor.Companion.addDebou import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.common.ServerMapChunkId import dev.adamko.kafkatorio.schema.common.leftTopTile import dev.adamko.kafkatorio.schema.common.toMapChunkPosition import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt index 37254c7..df4423e 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt @@ -4,6 +4,7 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.processor.admin.TOPIC_SRC_SERVER_LOG import dev.adamko.kafkatorio.processor.admin.topicName import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.producedAs diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt index 496a2c4..558ecf0 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt @@ -1,32 +1,14 @@ package dev.adamko.kafkatorio.processor.topology import com.sksamuel.scrimage.color.RGBColor -import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex -import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapTile import dev.adamko.kafkatorio.schema.common.MapTilePosition -import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.common.ServerMapChunkId import java.awt.Color import kotlinx.serialization.Serializable -@JvmInline -@Serializable -value class FactorioServerId(private val id: String) { - override fun toString() = id -} - - -@Serializable -data class ServerMapChunkId( - val serverId: FactorioServerId, - val chunkPosition: MapChunkPosition, - val surfaceIndex: SurfaceIndex, - val chunkSize: ChunkSize, -) - - @Serializable data class ServerMapChunkTiles( val chunkId: ServerMapChunkId, diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt index 81f7e43..6ada2be 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt @@ -2,6 +2,7 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.processor.admin.topicName import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData import dev.adamko.kotka.extensions.consumedAs diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt index 48a910a..968a924 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt @@ -1,11 +1,17 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.processor.WebsocketServer +import dev.adamko.kafkatorio.processor.admin.TOPIC_BROADCAST_TO_WEBSOCKET import dev.adamko.kafkatorio.processor.admin.topicName +import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio +import dev.adamko.kafkatorio.schema.packets.EventServerPacket import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kotka.extensions.consumedAs +import dev.adamko.kotka.extensions.producedAs +import dev.adamko.kotka.extensions.streams.forEach +import dev.adamko.kotka.extensions.streams.map import dev.adamko.kotka.kxs.serde import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json @@ -18,15 +24,41 @@ private val jsonMapper: Json = Json { } -fun playerUpdatesToWsServer( +private const val pid = "websocketBroadcast" + + +fun broadcastToWebsocket( websocketServer: WebsocketServer, builder: StreamsBuilder = StreamsBuilder(), ) { - builder.stream( - PlayerUpdate::class.topicName, - consumedAs("EventUpdate.Player-updates-for-ws-server", jsonMapper.serde(), jsonMapper.serde()), - ).foreach { _, value -> -// println("sending ${value.packetType} packet to websocket") - websocketServer.sendMessage(jsonMapper.encodeToString(value)) + + builder.preparePlayerUpdatesBroadcast() + + builder.stream( + TOPIC_BROADCAST_TO_WEBSOCKET, + consumedAs("$pid.packets-to-broadcast.consume", jsonMapper.serde(), jsonMapper.serde()), + ).forEach( + "$pid.websocket-server.send-message" + ) { _, esPacket -> + websocketServer.sendMessage(jsonMapper.encodeToString(esPacket)) } } + + +private fun StreamsBuilder.preparePlayerUpdatesBroadcast() { + stream( + PlayerUpdate::class.topicName, + consumedAs("$pid.player-updates", jsonMapper.serde(), jsonMapper.serde()), + ).map( + "$pid.player-updates.convert" + ) { serverId, playerPacket -> + serverId to EventServerPacket.Kafkatorio(playerPacket) + }.to( + TOPIC_BROADCAST_TO_WEBSOCKET, + producedAs( + "$pid.player-updates.stream", + jsonMapper.serde(FactorioServerId.serializer()), + jsonMapper.serde(EventServerPacket.serializer()), + ) + ) +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index 7716819..56b9e7b 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -3,6 +3,7 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioPrototype +import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.MapTile import dev.adamko.kafkatorio.schema.common.toHex import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt index c792940..970f1d2 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt @@ -3,11 +3,19 @@ package dev.adamko.kafkatorio.processor.topology import com.sksamuel.scrimage.ImmutableImage import com.sksamuel.scrimage.ScaleMethod import com.sksamuel.scrimage.nio.PngWriter +import dev.adamko.kafkatorio.processor.admin.TOPIC_BROADCAST_TO_WEBSOCKET import dev.adamko.kafkatorio.processor.admin.TOPIC_MAP_CHUNK_COLOURED_STATE +import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.common.ServerMapChunkId +import dev.adamko.kafkatorio.schema.common.TilePngFilename +import dev.adamko.kafkatorio.schema.packets.EventServerPacket import dev.adamko.kotka.extensions.consumedAs -import dev.adamko.kotka.extensions.streams.forEach +import dev.adamko.kotka.extensions.producedAs +import dev.adamko.kotka.extensions.streams.map +import dev.adamko.kotka.extensions.streams.mapValues import dev.adamko.kotka.kxs.serde import java.awt.image.BufferedImage import java.nio.file.Path @@ -41,15 +49,18 @@ fun saveMapTiles( ), ) - subdividedMapChunkTilesDebounced.forEachChunkSaveImage(tileDirectory) + val savedChunkFilenames: KStream = + subdividedMapChunkTilesDebounced.saveChunkAsImage(tileDirectory) + + savedChunkFilenames.broadcastSavedTileUpdates() return builder.build() } -private fun KStream>.forEachChunkSaveImage( +private fun KStream>.saveChunkAsImage( tileDirectory: Path, -) = forEach( +): KStream = mapValues( "$pid.save-tiles" ) { chunkId: ServerMapChunkId, tileColours: ServerMapChunkTiles -> @@ -77,6 +88,7 @@ private fun KStream>.forEachChu val filename = TilePngFilename(chunkId) saveTile(filename, tileDirectory, scaledImage) + filename } @@ -105,15 +117,17 @@ private fun saveTile( } -@JvmInline -private value class TilePngFilename( - val value: String, -) { - constructor(id: ServerMapChunkId) : this(buildString { - append("s${id.surfaceIndex}") - append("/z${id.chunkSize.zoomLevel}") - append("/x${id.chunkPosition.x}") - append("/y${id.chunkPosition.y}") - append(".png") - }) +private fun KStream.broadcastSavedTileUpdates() { + map( + "$pid.broadcast.filename-update.convert", + ) { id, filename -> + id.serverId to EventServerPacket.ChunkTileSaved(id, filename) + }.to( + TOPIC_BROADCAST_TO_WEBSOCKET, + producedAs( + "$pid.broadcast.filename-update.send", + jsonMapper.serde(FactorioServerId.serializer()), + jsonMapper.serde(EventServerPacket.serializer()), + ) + ) } diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt index a2b77f0..eb6702c 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt @@ -1,11 +1,11 @@ package dev.adamko.kafkatorio.processor.misc import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kafkatorio.processor.topology.FactorioServerId -import dev.adamko.kafkatorio.processor.topology.ServerMapChunkId +import dev.adamko.kafkatorio.schema.common.ServerMapChunkId import dev.adamko.kafkatorio.processor.topology.ServerMapChunkTiles import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapTilePosition import dev.adamko.kafkatorio.schema.common.SurfaceIndex @@ -134,7 +134,8 @@ class KxsBinaryTests : FunSpec({ test("binary round trip") { val binaryEncoded = kxsBinary.encodeToByteArray(initial) - val binaryDecoded = kxsBinary.decodeFromByteArray>(binaryEncoded) + val binaryDecoded = + kxsBinary.decodeFromByteArray>(binaryEncoded) binaryDecoded shouldBeEqualToComparingFields initial } diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt index aee7827..ec0591e 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt @@ -1,10 +1,14 @@ package dev.adamko.kafkatorio.processor.misc import dev.adamko.kafkatorio.processor.serdes.kxsBinary -import dev.adamko.kafkatorio.processor.topology.FactorioServerId -import dev.adamko.kafkatorio.processor.topology.ServerMapChunkId +import dev.adamko.kafkatorio.schema.common.ServerMapChunkId import dev.adamko.kafkatorio.processor.topology.ServerMapChunkTiles -import dev.adamko.kafkatorio.schema.common.* +import dev.adamko.kafkatorio.schema.common.ChunkSize +import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.common.MapChunkPosition +import dev.adamko.kafkatorio.schema.common.MapTilePosition +import dev.adamko.kafkatorio.schema.common.SurfaceIndex import java.util.UUID import kotlinx.serialization.encodeToByteArray import org.junit.jupiter.api.Test diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt index bc427b8..d1a8fb5 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt @@ -3,8 +3,10 @@ package dev.adamko.kafkatorio.processor.topology import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex +import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapTilePosition +import dev.adamko.kafkatorio.schema.common.ServerMapChunkId import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.iterateTiles import dev.adamko.kafkatorio.schema.common.toMapChunkPosition diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index 6d054fd..f1de35a 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.webmap +import dev.adamko.kafkatorio.schema.packets.EventServerPacket import dev.adamko.kafkatorio.webmap.state.FactorioGameState import dev.adamko.kafkatorio.webmap.state.FactorioUpdate import dev.adamko.kafkatorio.webmap.state.createFactorioReduxStore @@ -12,23 +13,34 @@ import io.kvision.CoreModule import io.kvision.FontAwesomeModule import io.kvision.html.div import io.kvision.maps.Maps -import io.kvision.maps.Maps.Companion.L import io.kvision.maps.externals.leaflet.layer.tile.GridLayer import io.kvision.module import io.kvision.panel.root import io.kvision.redux.ReduxStore import io.kvision.require import io.kvision.startApplication -import kotlin.time.Duration.Companion.seconds -import kotlinx.js.timers.setInterval -import org.w3c.dom.Image -import org.w3c.dom.asList +import kotlin.coroutines.CoroutineContext +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.cancel +import kotlinx.coroutines.cancelChildren +import kotlinx.coroutines.flow.filterIsInstance +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach + + +val rootJob = Job() class App( reduxStore: ReduxStore, wsService: WebsocketService, -) : Application() { +) : Application(), CoroutineScope { + + override val coroutineContext: CoroutineContext = + CoroutineName("WebMapApp") + Job(rootJob) + private var appState: MutableMap = mutableMapOf() var reduxStore: ReduxStore by appState @@ -40,8 +52,12 @@ class App( require("./css/kafkatorio.css") } + private val gameState: FactorioGameState + get() = reduxStore.getState() + private val kvMaps: Maps - get() = reduxStore.getState().map.kvMap + get() = gameState.map.kvMap + override fun start(state: Map) { this.appState = state.toMutableMap() @@ -62,35 +78,24 @@ class App( // this.asDynamic()._fadeAnimated = false } - setInterval(1.seconds) { - val doc = root.getElement()?.ownerDocument - val window = doc!!.defaultView!! + val doc = root.getElement()?.ownerDocument + val window = doc!!.defaultView!! - doc - .querySelectorAll("img.leaflet-tile-loaded") - .asList() - .filterIsInstance() - .map { img -> - val imgSrc = img.src.substringBeforeLast('?') -// println("fetching $imgSrc") + wsService.packetsFlow + .filterIsInstance() + .onEach { + println("[packetsFlow] triggering tile refresh ${it.filename.value}") + gameState.map.refreshUpdatedTilePng(doc, window, it.filename) + }.launchIn(this) - var newImg: Image? = Image() - - newImg!!.onload = { - - window.requestAnimationFrame { -// println("image loaded ${newImg!!.src}") - img.setAttribute("dynamic-reload", "true") - img.src = newImg!!.src - newImg = null // try to encourage garbage collection - } - } - newImg!!.src = imgSrc //+ "?t=${currentTimeMillis()}" - } - } } - override fun dispose(): Map = appState + override fun dispose(): Map { + rootJob.cancelChildren() + rootJob.cancel("app dispose") + rootJob.complete() + return appState + } } @@ -104,7 +109,7 @@ fun main() { ) App( reduxStore = reduxStore, - wsService = wsService + wsService = wsService, ) }, module.hot, diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index 93de604..a0e82f1 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.webmap +import dev.adamko.kafkatorio.schema.common.TilePngFilename import io.kvision.maps.Maps import io.kvision.maps.Maps.Companion.L import io.kvision.maps.externals.leaflet.DoneCallback @@ -12,7 +13,19 @@ import io.kvision.maps.externals.leaflet.layer.LayerGroup import io.kvision.maps.externals.leaflet.layer.tile.TileLayer import io.kvision.utils.obj import io.kvision.utils.px +import kotlinx.coroutines.await +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch +import org.w3c.dom.Document import org.w3c.dom.HTMLElement +import org.w3c.dom.Image +import org.w3c.dom.Window +import org.w3c.dom.asList +import org.w3c.fetch.NO_CORS +import org.w3c.fetch.RELOAD +import org.w3c.fetch.RequestCache +import org.w3c.fetch.RequestInit +import org.w3c.fetch.RequestMode class FactorioMap( @@ -64,6 +77,49 @@ class FactorioMap( } + suspend fun refreshUpdatedTilePng( + document: Document, + window: Window, + tilePngFilename: TilePngFilename, + ): Unit = coroutineScope { + launch { + document + .querySelectorAll("img.leaflet-tile-loaded") + .asList() + .filterIsInstance() + .filter { img -> + tilePngFilename.value in img.src + } + .forEach { img -> + val imgSrc = img.src //.substringBeforeLast('?') + + window.fetch( + imgSrc, + RequestInit( + cache = RequestCache.RELOAD, + mode = RequestMode.NO_CORS, + ) + ).then { + println("[refreshUpdatedTilePng] updating $imgSrc") + img.setAttribute(DYNAMIC_RELOAD_ATT, "true") + img.src = imgSrc + }.await() + } + } + +//// println("fetching $imgSrc") +// val newImg = Image() +// newImg.onload = { +//// window.requestAnimationFrame { +//// println("image loaded ${newImg!!.src}") +// img.setAttribute(DYNAMIC_RELOAD_ATT, "true") +// img.src = newImg.src +// Unit +//// } +// } +// newImg.src = imgSrc //+ "?t=${currentTimeMillis()}" + } + private fun buildFactorioTerrainLayer(): TileLayer { val baseTileLayer = L.tileLayer( @@ -87,8 +143,8 @@ class FactorioMap( val currentTileOnLoad: (DoneCallback, HTMLElement) -> Unit = baseTileLayer.asDynamic()._tileOnLoad as (DoneCallback, HTMLElement) -> Unit baseTileLayer.asDynamic()._tileOnLoad = { done: DoneCallback, tile: HTMLElement -> - if (tile.hasAttribute("dynamic-reload")) { - tile.removeAttribute("dynamic-reload") + if (tile.hasAttribute(DYNAMIC_RELOAD_ATT)) { + tile.removeAttribute(DYNAMIC_RELOAD_ATT) } else { currentTileOnLoad(done, tile) } @@ -96,4 +152,8 @@ class FactorioMap( return baseTileLayer } + + companion object { + const val DYNAMIC_RELOAD_ATT = "dynamic-reload" + } } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt index 51e7708..fc9ca41 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -4,7 +4,7 @@ import dev.adamko.kafkatorio.schema.packets.ConfigurationUpdate import dev.adamko.kafkatorio.schema.packets.ConsoleChatUpdate import dev.adamko.kafkatorio.schema.packets.ConsoleCommandUpdate import dev.adamko.kafkatorio.schema.packets.EntityUpdate -import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket +import dev.adamko.kafkatorio.schema.packets.EventServerPacket import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate @@ -12,45 +12,72 @@ import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate import dev.adamko.kafkatorio.webmap.state.FactorioGameState import dev.adamko.kafkatorio.webmap.state.FactorioUpdate import io.kvision.redux.ReduxStore +import kotlin.coroutines.CoroutineContext +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.launch import org.w3c.dom.MessageEvent import org.w3c.dom.WebSocket class WebsocketService( - private val wsUrl: String, + wsUrl: String, private val reduxStore: ReduxStore, -) { +) : CoroutineScope { + + override val coroutineContext: CoroutineContext = + CoroutineName("WebsocketService") + Job(rootJob) + private val ws = WebSocket(wsUrl) + private val _packetsFlow = MutableSharedFlow() + val packetsFlow: SharedFlow + get() = _packetsFlow.asSharedFlow() + init { ws.onmessage = ::handleMessageEvent } private fun handleMessageEvent(msg: MessageEvent) { - val data = msg.data as? String + val data = (msg.data as? String)?.trim() if ( data != null - && data.trim().run { startsWith("{") && endsWith("}") } + && data.startsWith("{") + && data.endsWith("}") ) { println(data.replace('\n', ' ')) - val packet = jsonMapper.decodeFromString(KafkatorioPacket.serializer(), data) + val packet = jsonMapper.decodeFromString(EventServerPacket.serializer(), data) - when (val packetData = packet.data) { + launch { + _packetsFlow.emit(packet) + } - is PlayerUpdate -> reduxStore.dispatch(FactorioUpdate.Player(packet.tick, packetData)) - is ConfigurationUpdate, - is ConsoleChatUpdate, - is ConsoleCommandUpdate, - is PrototypesUpdate, - is SurfaceUpdate, - is EntityUpdate, - is MapChunkUpdate -> { - // to be continued... - } + when (packet) { + is EventServerPacket.ChunkTileSaved -> {} + + is EventServerPacket.Kafkatorio -> + when (val packetData = packet.packet.data) { + is PlayerUpdate -> reduxStore.dispatch( + FactorioUpdate.Player(packet.packet.tick, packetData) + ) + is ConfigurationUpdate, + is ConsoleChatUpdate, + is ConsoleCommandUpdate, + is PrototypesUpdate, + is SurfaceUpdate, + is EntityUpdate, + is MapChunkUpdate -> { + // to be continued... + } + } } } else { println(data) From e270b05d5800788969694b62edd62b2e9e2749f5 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 30 May 2022 20:43:19 +0200 Subject: [PATCH 370/629] replace runCatching exception swallow --- .../kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient.kt b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient.kt index d1d068a..93f5672 100644 --- a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient.kt +++ b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient.kt @@ -4,6 +4,7 @@ import java.net.Socket import kotlin.random.Random import kotlin.random.nextUInt import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.asFlow @@ -11,6 +12,7 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.runBlocking import kotlinx.coroutines.supervisorScope +import kotlinx.coroutines.withContext class KtRconClient( private val host: String, @@ -88,7 +90,7 @@ class KtRconClient( // put(p.terminator) // } - runCatching { + withContext(Dispatchers.IO) { socket.getOutputStream().use { os -> os.write(bb.array()) os.flush() From 916ddb6cb2251d0a0df88b96df6d5f0a8d2092e6 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 30 May 2022 20:44:01 +0200 Subject: [PATCH 371/629] add lazy gradle task provider --- .../kotlin/dev/adamko/kafkatorio/gradle/extensions.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt index ba24bdc..5f1400c 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/extensions.kt @@ -2,10 +2,12 @@ package dev.adamko.kafkatorio.gradle import java.io.ByteArrayOutputStream import org.gradle.api.Project +import org.gradle.api.Task import org.gradle.api.file.Directory import org.gradle.api.file.FileCopyDetails import org.gradle.api.file.ProjectLayout import org.gradle.api.file.RelativePath +import org.gradle.api.provider.Provider import org.gradle.api.specs.NotSpec import org.gradle.api.specs.Spec import org.gradle.plugins.ide.idea.model.IdeaModule @@ -81,3 +83,11 @@ fun FileCopyDetails.dropDirectories(count: Int): RelativePath = /** Drop the first directory from the path */ fun FileCopyDetails.dropDirectory(): RelativePath = dropDirectories(1) + + +/** https://github.com/gradle/gradle/issues/16543 */ +fun Project.taskProvider(taskName: String): Provider = providers.provider { + taskName +}.flatMap { + tasks.named(it) +} From 8b109f02ec047c539eb853bc3ca94cf8b8e9faea Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 30 May 2022 20:44:32 +0200 Subject: [PATCH 372/629] fix JsonPropertiesUpToDateSpec checker --- .../kafkatorio/task/JsonPropertiesUpToDateSpec.kt | 12 ++++++++++-- .../dev/adamko/kafkatorio/task/UpdatePackageJson.kt | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt index c180df7..30f9ee0 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/JsonPropertiesUpToDateSpec.kt @@ -5,7 +5,15 @@ import org.gradle.api.internal.specs.ExplainingSpec object JsonPropertiesUpToDateSpec : ExplainingSpec { - override fun isSatisfiedBy(element: Task?): Boolean = whyUnsatisfied(element) == null + override fun isSatisfiedBy(element: Task?): Boolean { + val reason = whyUnsatisfied(element) + + if (reason != null) { + println("JsonProperties not up to date:\n$reason") + } + + return reason == null + } // Returns a description explaining why the task is outdated, @@ -30,7 +38,7 @@ object JsonPropertiesUpToDateSpec : ExplainingSpec { } else { "'$it' - expected:$updatedVal, actual:$currentVal" } - }.joinToString(prefix = "package.json is not up to date. ") + }.joinToString(separator = "\n\t", prefix = "package.json is not up to date.\n\t") } else { null } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt index d4ce73f..d074957 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/UpdatePackageJson.kt @@ -4,8 +4,8 @@ import com.github.gradle.node.NodePlugin import dev.adamko.kafkatorio.jsonMapper import javax.inject.Inject import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.jsonObject import org.gradle.api.DefaultTask import org.gradle.api.file.RegularFileProperty @@ -69,7 +69,7 @@ abstract class UpdatePackageJson @Inject constructor( ): JsonObject { val propertiesToCheck: Map = propertiesToCheck.get() val newJsonProps = propertiesToCheck.mapValues { (_, newVal) -> - jsonMapper.parseToJsonElement(newVal) + JsonPrimitive(newVal) } return JsonObject(currentPackageJson + newJsonProps) } From e9a6f99fb81a9b40e3ed39096ad4e537bc74356d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 30 May 2022 20:45:11 +0200 Subject: [PATCH 373/629] add some logs to try and figure out if player disconnection can be sent before server shutdown --- .../src/main/typescript/main/events/onPlayerEventListeners.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts index 500bb64..b6583a3 100644 --- a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts @@ -162,6 +162,7 @@ function handleBannedEvent(event: OnPlayerBannedEvent | OnPlayerUnbannedEvent) { script.on_event( defines.events.on_player_kicked, (event: OnPlayerKickedEvent) => { + log(`on_player_kicked ${event.tick} ${event.name}`) playerUpdateImmediate( event, (player, data) => { @@ -181,6 +182,7 @@ for (const [name, disconnectId] of pairs(defines.disconnect_reason)) { script.on_event( defines.events.on_pre_player_left_game, (event: OnPrePlayerLeftGameEvent) => { + log(`on_pre_player_left_game ${event.tick} ${event.name}`) playerUpdateImmediate( event, (player, data) => { @@ -194,6 +196,7 @@ script.on_event( script.on_event( defines.events.on_player_removed, (event: OnPlayerRemovedEvent) => { + log(`on_player_removed ${event.tick} ${event.name}`) playerUpdateImmediate( event, (player, data) => { From f151027464bf0fe7305290687d6eb5171ce5687d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 19 Jun 2022 10:16:37 +0200 Subject: [PATCH 374/629] webmap - tidy up player layer - no need for smaller web tiles, make the large ones render as pixelated - make tile server and websocket server URL not-hardcoded - tidy up dynamic tile refreshing --- modules/web-map/build.gradle.kts | 170 +++++++++++++----- .../dev/adamko/kafkatorio/webmap/App.kt | 19 +- .../webmap/ApplicationProperties.kt | 12 ++ .../kafkatorio/webmap/externals/leaflet.kt | 33 ++++ .../dev/adamko/kafkatorio/webmap/map.kt | 84 ++++----- .../kafkatorio/webmap/state/playerState.kt | 5 +- .../adamko/kafkatorio/webmap/websockets.kt | 62 ++++--- .../src/main/resources/css/kafkatorio.css | 10 +- modules/web-map/webpack.config.d/webpack.js | 52 +++++- 9 files changed, 312 insertions(+), 135 deletions(-) create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/ApplicationProperties.kt create mode 100644 modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/externals/leaflet.kt diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 284b406..667e1ed 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -1,10 +1,13 @@ +import dev.adamko.kafkatorio.gradle.taskProvider import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig +import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension plugins { -// dev.adamko.kafkatorio.lang.`kotlin-js` - dev.adamko.kafkatorio.lang.`kotlin-multiplatform` + dev.adamko.kafkatorio.lang.`kotlin-js` +// dev.adamko.kafkatorio.lang.`kotlin-multiplatform` kotlin("plugin.serialization") id("io.kvision") } @@ -19,13 +22,42 @@ project.ext.set("io.kvision.plugin.enableBackendTasks", false) -kotlin { - js(IR) { - browser() - binaries.executable() +rootProject.extensions.configure { + // https://github.com/rjaros/kvision/issues/410 + versions.webpackCli.version = "4.10.0" + versions.webpackDevServer.version = "4.9.2" +} + +rootProject.extensions.configure { + resolution("http-proxy-middleware", "^2.0.6") +} + +//rootProject.afterEvaluate { +// extensions.configure { +// // https://github.com/rjaros/kvision/issues/410 +// versions.webpackCli.version = "4.10.0" +// } +//} + +afterEvaluate { + rootProject.extensions.configure { + // https://github.com/rjaros/kvision/issues/410 + versions.webpackCli.version = "4.10.0" + versions.webpackDevServer.version = "4.9.2" } - js("frontend", IR) { + rootProject.extensions.configure { + resolution("http-proxy-middleware", "^2.0.6") + } +} + +kotlin { + js(IR) { +// browser() +// binaries.executable() +// } +// +// js("frontend", IR) { // nodejs() browser { runTask { @@ -35,13 +67,20 @@ kotlin { open = false, port = 3000, proxy = mutableMapOf( - "/kv/*" to "http://localhost:8080", - "/kvws/*" to mapOf( - "target" to "ws://localhost:8080", + "/tiles" to mapOf( + "target" to "http://localhost:12080", + "secure" to false, + "changeOrigin" to true, + ), + "/ws/foo" to mapOf( + "target" to "ws://localhost:12080", +// "secure" to false, "ws" to true, - ) +// "changeOrigin" to true, + ), ), - static = mutableListOf("$buildDir/processedResources/frontend/main") +// static = mutableListOf("$buildDir/processedResources/frontend/main") + static = mutableListOf("$buildDir/processedResources/js/main") ) } webpackTask { @@ -54,11 +93,14 @@ kotlin { } } binaries.executable() +// compilations["main"].packageJson { +// this.devDependencies["webpack-dev-server"] = "4.9.1" +// } } - jvm("backend") { - - } +// jvm("backend") { +// +// } sourceSets { @@ -69,7 +111,8 @@ kotlin { } } - val commonMain by getting { +// val commonMain by getting { + main { dependencies { implementation(dependencies.platform(libs.kotlinx.coroutines.bom)) implementation(dependencies.platform(libs.kotlin.jsWrappers.bom)) @@ -79,13 +122,13 @@ kotlin { implementation(projects.modules.eventsSchema) implementation(libs.kotlinx.html) - } - } +// } +// } - val jsMain by getting { - dependsOn(commonMain) - - dependencies { +// val jsMain by getting { +// dependsOn(commonMain) +// +// dependencies { implementation(projects.modules.eventsSchema) @@ -108,36 +151,52 @@ kotlin { implementation(libs.kotlinx.coroutines.core) + implementation(devNpm("http-proxy-middleware", "^2.0.6")) + implementation(dependencies.platform(devNpm("http-proxy-middleware", "^2.0.6"))) + // implementation(dependencies.platform(npm("follow-redirects", "^1.14.8"))) // implementation(dependencies.platform(npm("nanoid", "^3.1.31"))) // implementation(dependencies.platform(npm("minimist", "^1.2.6"))) // implementation(dependencies.platform(npm("async", "^2.6.4"))) // implementation(dependencies.platform(npm("node-forge", "^1.3.0"))) +// implementation(dependencies.platform(npm("socket.io", "^4.5.1"))) +// implementation(dependencies.platform(devNpm("http-proxy-middleware", "^3.0.0-beta.0"))) +// implementation(dependencies.platform(devNpm("webpack-dev-server", "4.9.1"))) } // val webDir = file("src/main/web") resources.srcDir("src/main/web") - resources.srcDir("src/main/resources") - - kotlin.srcDir("src/main/kotlin") - } - - val frontendMain by getting { - dependsOn(jsMain) -// resources.srcDir("src/main/web") // resources.srcDir("src/main/resources") + +// kotlin.srcDir("src/main/kotlin") } - val jsTest by getting { +// val frontendMain by getting { +// dependsOn(jsMain) +//// resources.srcDir("src/main/web") +//// resources.srcDir("src/main/resources") +// } +// +// val jsTest by getting { +// dependencies { +// implementation(kotlin("test-js")) +// +// kvision("kvision-testutils") +// +//// implementation(npm("karma", "^6.3.16")) +// } +// +// kotlin.srcDir("src/test/kotlin") +// } + + test { dependencies { implementation(kotlin("test-js")) kvision("kvision-testutils") -// implementation(npm("karma", "^6.3.16")) + // implementation(npm("karma", "^6.3.16")) } - - kotlin.srcDir("src/test/kotlin") } } } @@ -152,17 +211,42 @@ fun KotlinDependencyHandler.kvision( implementation("io.kvision:$module:${version.get()}", configure) } -// https://youtrack.jetbrains.com/issue/KT-42420 +////// https://youtrack.jetbrains.com/issue/KT-42420 //afterEvaluate { // yarn { -// resolution("mocha", "9.2.2") -// resolution("follow-redirects", "1.14.8") -// resolution("nanoid", "3.1.31") -// resolution("minimist", "1.2.6") -// resolution("async", "2.6.4") -// resolution("node-forge", "1.3.0") +//// resolution("mocha", "9.2.2") +//// resolution("follow-redirects", "1.14.8") +//// resolution("nanoid", "3.1.31") +//// resolution("minimist", "1.2.6") +//// resolution("async", "2.6.4") +//// resolution("node-forge", "1.3.0") +//// resolution("socket.io", "^4.5.1") +//// resolution("http-proxy-middleware", "^3.0.0-beta.0") +// resolution("webpack-dev-server", "4.9.1") // } //} -evaluationDependsOn(rootProject.path) -evaluationDependsOn(projects.modules.eventsSchema.dependencyProject.path) + +//evaluationDependsOn(rootProject.path) +//evaluationDependsOn(projects.modules.eventsSchema.dependencyProject.path) + + +// stop warnings when building +tasks.configureEach { + when (name) { + "productionExecutableCompileSync" -> + dependsOn(taskProvider("compileProductionExecutableKotlinJs")) + "testTestDevelopmentExecutableCompileSync" -> + dependsOn(taskProvider("compileTestDevelopmentExecutableKotlinJs")) +// "jsTestTestDevelopmentExecutableCompileSync" -> +// dependsOn(taskProvider("compileTestDevelopmentExecutableKotlinFrontend")) +// "jsProductionExecutableCompileSync" -> +// dependsOn(taskProvider("compileProductionExecutableKotlinFrontend")) + "browserDevelopmentRun" -> + dependsOn(taskProvider("browserDevelopmentWebpack")) + "browserDevelopmentWebpack" -> + dependsOn(taskProvider("assemble")) + "browserProductionWebpack" -> + dependsOn(taskProvider("developmentExecutableCompileSync")) + } +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index f1de35a..6d09996 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -38,8 +38,7 @@ class App( wsService: WebsocketService, ) : Application(), CoroutineScope { - override val coroutineContext: CoroutineContext = - CoroutineName("WebMapApp") + Job(rootJob) + override val coroutineContext: CoroutineContext = CoroutineName("WebMapApp") private var appState: MutableMap = mutableMapOf() @@ -62,7 +61,7 @@ class App( override fun start(state: Map) { this.appState = state.toMutableMap() - val root = root("kvapp") { + root("kvapp") { div("Kafkatorio Web Map") add(kvMaps) } @@ -74,18 +73,16 @@ class App( it.redraw() } }) - -// this.asDynamic()._fadeAnimated = false } - val doc = root.getElement()?.ownerDocument - val window = doc!!.defaultView!! - wsService.packetsFlow .filterIsInstance() .onEach { println("[packetsFlow] triggering tile refresh ${it.filename.value}") - gameState.map.refreshUpdatedTilePng(doc, window, it.filename) + gameState.map.refreshUpdatedTilePng( +// doc, window, + it.filename + ) }.launchIn(this) } @@ -104,8 +101,8 @@ fun main() { { val reduxStore = createFactorioReduxStore() val wsService = WebsocketService( - "ws://localhost:9073/ws", - reduxStore, +// "ws://localhost:9073/ws", // TODO load from config + reduxStore = reduxStore, ) App( reduxStore = reduxStore, diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/ApplicationProperties.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/ApplicationProperties.kt new file mode 100644 index 0000000..38d4a7e --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/ApplicationProperties.kt @@ -0,0 +1,12 @@ +package dev.adamko.kafkatorio.webmap + +import kotlinx.browser.window + +object Props { + @Suppress("HttpUrlsUsage") + val websocketServerUrl: String + get() = window.location.href + .replace("http://", "ws://") + .replace("https://", "wss://") + + "ws/foo" +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/externals/leaflet.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/externals/leaflet.kt new file mode 100644 index 0000000..d7a3195 --- /dev/null +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/externals/leaflet.kt @@ -0,0 +1,33 @@ +package dev.adamko.kafkatorio.webmap.externals + +import io.kvision.maps.externals.leaflet.DoneCallback +import io.kvision.maps.externals.leaflet.geo.LatLng +import io.kvision.maps.externals.leaflet.layer.tile.TileLayer +import io.kvision.maps.externals.leaflet.layer.vector.Polyline +import org.w3c.dom.HTMLElement + + +inline var TileLayer.tileOnLoad: TileOnLoadFn? + get() = asDynamic()._tileOnLoad as TileOnLoadFn + set(value) { + asDynamic()._tileOnLoad = value + } + + +typealias TileOnLoadFn = (done: DoneCallback, tile: HTMLElement) -> Unit + + +sealed interface PolylinePathPoints { + value class D1(val points: Array) : PolylinePathPoints + value class D2(val points: Array>) : PolylinePathPoints + value class D3(val points: Array>>) : PolylinePathPoints +} + +inline fun Polyline<*>.getLatLngs2(): PolylinePathPoints? { + return when (val points = this.getLatLngs()) { + is Array -> PolylinePathPoints.D1(points as Array) + is Array> -> PolylinePathPoints.D2(points as Array>) + is Array>> -> PolylinePathPoints.D3(points as Array>>) + else -> null + } +} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index a0e82f1..a124582 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -1,6 +1,8 @@ package dev.adamko.kafkatorio.webmap import dev.adamko.kafkatorio.schema.common.TilePngFilename +import dev.adamko.kafkatorio.webmap.externals.TileOnLoadFn +import dev.adamko.kafkatorio.webmap.externals.tileOnLoad import io.kvision.maps.Maps import io.kvision.maps.Maps.Companion.L import io.kvision.maps.externals.leaflet.DoneCallback @@ -11,15 +13,15 @@ import io.kvision.maps.externals.leaflet.geo.CRS import io.kvision.maps.externals.leaflet.geo.LatLng import io.kvision.maps.externals.leaflet.layer.LayerGroup import io.kvision.maps.externals.leaflet.layer.tile.TileLayer -import io.kvision.utils.obj import io.kvision.utils.px +import kotlinx.browser.document +import kotlinx.browser.window import kotlinx.coroutines.await import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch -import org.w3c.dom.Document +import kotlinx.js.jso import org.w3c.dom.HTMLElement import org.w3c.dom.Image -import org.w3c.dom.Window import org.w3c.dom.asList import org.w3c.fetch.NO_CORS import org.w3c.fetch.RELOAD @@ -29,7 +31,7 @@ import org.w3c.fetch.RequestMode class FactorioMap( - private val tileUrlTemplate: String = """http://localhost:9073/tiles/s1/z{z}/x{x}/y{y}.png""", + private val tileUrlTemplate: String = """/tiles/s1/z{z}/x{x}/y{y}.png""", ) { val kvMap: Maps = Maps { @@ -38,21 +40,24 @@ class FactorioMap( margin = 10.px } - val factorioTerrainLayer: TileLayer<*> = buildFactorioTerrainLayer() + private val factorioTerrainLayer: TileLayer<*> = buildFactorioTerrainLayer() val playerIconsLayer: LayerGroup = LayerGroup() init { - val baseLayers: Control.LayersObject = obj {} - baseLayers["Terrain"] = factorioTerrainLayer - val overlays: Control.LayersObject = obj {} - overlays["Players"] = playerIconsLayer + val baseLayers: Control.LayersObject = jso { + set("Terrain", factorioTerrainLayer) + } + + val overlays: Control.LayersObject = jso { + set("Players", playerIconsLayer) + } val layersControl = Layers( baseLayers = baseLayers, overlays = overlays, - options = obj { + options = jso { sortLayers = true } ) @@ -78,21 +83,19 @@ class FactorioMap( suspend fun refreshUpdatedTilePng( - document: Document, - window: Window, tilePngFilename: TilePngFilename, ): Unit = coroutineScope { - launch { - document - .querySelectorAll("img.leaflet-tile-loaded") - .asList() - .filterIsInstance() - .filter { img -> - tilePngFilename.value in img.src - } - .forEach { img -> - val imgSrc = img.src //.substringBeforeLast('?') + document + .querySelectorAll("img.leaflet-tile-loaded") + .asList() + .filterIsInstance() + .filter { img -> + tilePngFilename.value in img.src + } + .forEach { img -> + val imgSrc = img.src + launch { window.fetch( imgSrc, RequestInit( @@ -100,24 +103,14 @@ class FactorioMap( mode = RequestMode.NO_CORS, ) ).then { - println("[refreshUpdatedTilePng] updating $imgSrc") - img.setAttribute(DYNAMIC_RELOAD_ATT, "true") - img.src = imgSrc + window.requestAnimationFrame { + println("[refreshUpdatedTilePng] updating $imgSrc") + img.setAttribute(DYNAMIC_RELOAD_ATT, "true") + img.src = imgSrc + } }.await() } - } - -//// println("fetching $imgSrc") -// val newImg = Image() -// newImg.onload = { -//// window.requestAnimationFrame { -//// println("image loaded ${newImg!!.src}") -// img.setAttribute(DYNAMIC_RELOAD_ATT, "true") -// img.src = newImg.src -// Unit -//// } -// } -// newImg.src = imgSrc //+ "?t=${currentTimeMillis()}" + } } private fun buildFactorioTerrainLayer(): TileLayer { @@ -132,7 +125,7 @@ class FactorioMap( minZoom = -2 maxZoom = 6 - maxNativeZoom = 3 + maxNativeZoom = -1 minNativeZoom = -1 noWrap = true @@ -140,13 +133,14 @@ class FactorioMap( updateWhenZooming = true } - val currentTileOnLoad: (DoneCallback, HTMLElement) -> Unit = - baseTileLayer.asDynamic()._tileOnLoad as (DoneCallback, HTMLElement) -> Unit - baseTileLayer.asDynamic()._tileOnLoad = { done: DoneCallback, tile: HTMLElement -> - if (tile.hasAttribute(DYNAMIC_RELOAD_ATT)) { + val currentTileOnLoad: TileOnLoadFn? = baseTileLayer.tileOnLoad + + if (currentTileOnLoad != null) { + baseTileLayer.tileOnLoad = { done: DoneCallback, tile: HTMLElement -> + if (!tile.hasAttribute(DYNAMIC_RELOAD_ATT)) { + currentTileOnLoad(done, tile) + } tile.removeAttribute(DYNAMIC_RELOAD_ATT) - } else { - currentTileOnLoad(done, tile) } } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt index 1488696..7cd71ab 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/state/playerState.kt @@ -10,9 +10,8 @@ import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.webmap.latLng import io.kvision.maps.Maps import io.kvision.maps.externals.leaflet.geo.LatLng -import io.kvision.maps.externals.leaflet.layer.overlay.Tooltip import io.kvision.maps.externals.leaflet.layer.vector.CircleMarker -import io.kvision.utils.obj +import kotlinx.js.jso fun handlePlayerUpdate( @@ -100,7 +99,7 @@ data class PlayerState( className = "player-marker" // interactive = false }.also { circle -> - circle.bindTooltip("", obj { + circle.bindTooltip("", jso { // interactive = false }) } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt index fc9ca41..7c0ca27 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -22,10 +22,11 @@ import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.launch import org.w3c.dom.MessageEvent import org.w3c.dom.WebSocket +import org.w3c.dom.events.Event class WebsocketService( - wsUrl: String, + wsUrl: String = Props.websocketServerUrl, private val reduxStore: ReduxStore, ) : CoroutineScope { @@ -33,6 +34,7 @@ class WebsocketService( CoroutineName("WebsocketService") + Job(rootJob) private val ws = WebSocket(wsUrl) +// private val ws = WebSocket("ws://localhost:12080/ws/foo") private val _packetsFlow = MutableSharedFlow() val packetsFlow: SharedFlow @@ -40,6 +42,9 @@ class WebsocketService( init { ws.onmessage = ::handleMessageEvent + ws.onerror = ::handleError + + println("[WebsocketService] init ${ws.url}, ${ws.protocol}") } private fun handleMessageEvent(msg: MessageEvent) { @@ -52,35 +57,46 @@ class WebsocketService( && data.endsWith("}") ) { - println(data.replace('\n', ' ')) + println("[WebsocketService.handleMessageEvent] ${data.replace('\n', ' ')}") - val packet = jsonMapper.decodeFromString(EventServerPacket.serializer(), data) - - launch { - _packetsFlow.emit(packet) + val packet: EventServerPacket? = runCatching { + jsonMapper.decodeFromString(EventServerPacket.serializer(), data) + }.getOrElse { + null } - when (packet) { - is EventServerPacket.ChunkTileSaved -> {} + if (packet != null) { - is EventServerPacket.Kafkatorio -> - when (val packetData = packet.packet.data) { - is PlayerUpdate -> reduxStore.dispatch( - FactorioUpdate.Player(packet.packet.tick, packetData) - ) - is ConfigurationUpdate, - is ConsoleChatUpdate, - is ConsoleCommandUpdate, - is PrototypesUpdate, - is SurfaceUpdate, - is EntityUpdate, - is MapChunkUpdate -> { - // to be continued... + launch { _packetsFlow.emit(packet) } + + when (packet) { + is EventServerPacket.ChunkTileSaved -> {} + + is EventServerPacket.Kafkatorio -> + when (val packetData = packet.packet.data) { + is PlayerUpdate -> reduxStore.dispatch( + FactorioUpdate.Player(packet.packet.tick, packetData) + ) + is ConfigurationUpdate, + is ConsoleChatUpdate, + is ConsoleCommandUpdate, + is PrototypesUpdate, + is SurfaceUpdate, + is EntityUpdate, + is MapChunkUpdate -> { + // to be continued... + } } - } + } + } else { + println("[WebsocketService.handleMessageEvent] unknown json message ${msg.data}") } } else { - println(data) + println("[WebsocketService.handleMessageEvent] non-json message ${msg.data}") } } + + private fun handleError(error: Event) { + println("ws error: ${JSON.stringify(error)}") + } } diff --git a/modules/web-map/src/main/resources/css/kafkatorio.css b/modules/web-map/src/main/resources/css/kafkatorio.css index 54b756e..db87d4c 100644 --- a/modules/web-map/src/main/resources/css/kafkatorio.css +++ b/modules/web-map/src/main/resources/css/kafkatorio.css @@ -1,8 +1,10 @@ -/* https://github.com/Leaflet/Leaflet/issues/3575 */ .leaflet-tile { - width: 257px !important; - height: 257px !important; - box-shadow: 0 0 1px rgba(0, 0, 0, 0.05); + /* https://github.com/Leaflet/Leaflet/issues/3575 */ + /*width: 257px !important;*/ + /*height: 257px !important;*/ + /*box-shadow: 0 0 1px rgba(0, 0, 0, 0.05);*/ + + image-rendering: pixelated; } html { diff --git a/modules/web-map/webpack.config.d/webpack.js b/modules/web-map/webpack.config.d/webpack.js index 4ce4481..0491c5c 100644 --- a/modules/web-map/webpack.config.d/webpack.js +++ b/modules/web-map/webpack.config.d/webpack.js @@ -1,15 +1,55 @@ config.resolve.modules.push("../../processedResources/js/main"); if (config.devServer) { - config.devServer.hot = true; - config.devtool = 'eval-cheap-source-map'; + config.devServer.hot = true; + config.devtool = 'eval-cheap-source-map'; + config.devServer.host = "0.0.0.0" } else { - config.devtool = undefined; + config.devtool = undefined; } // disable bundle size warning config.performance = { - assetFilter: function (assetFilename) { - return !assetFilename.endsWith('.js'); - }, + assetFilter: function (assetFilename) { + return !assetFilename.endsWith('.js'); + }, }; + + +// // dev server +// config.devServer = { +// open: false, +// // devMiddleware: { +// // index: false, // specify to enable root proxying +// // }, +// port: 3000, +// proxy: { +// // context: () => true, +// // target: "http://localhost:12080", +// // secure: false, +// // ws: true, +// // changeOrigin: true, +// +// // "/tiles": { +// // target: "http://localhost:12080", +// // // "pathRewrite": { "^/tiles": "" }, +// // // "logger": "console", +// // // "logLevel": "debug", +// // secure: false, +// // changeOrigin: true, +// // }, +// // "/ws": { +// // target: "http://localhost:12080", +// // // pathRewrite: { "^/ws": "" }, +// // // "logLevel": "debug", +// // // "logger": "console", +// // secure: false, +// // ws: true, +// // changeOrigin: true, +// // }, +// }, +// "static": [ +// // "../../processedResources/js/main", +// "D:\\Users\\Adam\\Projects\\games\\kafkatorio\\modules\\web-map\\build\\processedResources\\frontend\\main", +// ], +// }; From 33d31bfbddd206a541deac2f02d68af0e2b5e4de Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 19 Jun 2022 10:20:48 +0200 Subject: [PATCH 375/629] version bumps. Kotlin 1.7 and yarn.lock and others --- buildSrc/repositories.settings.gradle.kts | 7 +- .../kafkatorio/lang/kotlin-jvm.gradle.kts | 11 +- gradle/kotlin-js-store/yarn.lock | 1051 ++++++----------- gradle/libs.versions.toml | 56 +- modules/events-mod/package.json | 12 +- modules/events-schema/build.gradle.kts | 5 +- modules/events-server/build.gradle.kts | 1 + modules/infra-kafka-cluster/build.gradle.kts | 3 + modules/infra-kafka-cluster/src/.env | 3 +- .../src/docker-compose.yml | 7 +- modules/versions-platform/build.gradle.kts | 3 +- settings.gradle.kts | 9 +- 12 files changed, 450 insertions(+), 718 deletions(-) diff --git a/buildSrc/repositories.settings.gradle.kts b/buildSrc/repositories.settings.gradle.kts index 8e5cd0e..8143698 100644 --- a/buildSrc/repositories.settings.gradle.kts +++ b/buildSrc/repositories.settings.gradle.kts @@ -12,6 +12,9 @@ dependencyResolutionManagement { repositories { myMavenLocal() mavenCentral() + maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") { + mavenContent { snapshotsOnly() } + } jitpack() gradlePluginPortal() @@ -28,6 +31,8 @@ dependencyResolutionManagement { metadataSources { artifact() } content { includeModule("com.yarnpkg", "yarn") } } + + maven("https://raw.githubusercontent.com/adamko-dev/kotka-streams/artifacts/m2") } pluginManagement { @@ -47,7 +52,7 @@ fun RepositoryHandler.jitpack() { } -fun RepositoryHandler.myMavenLocal(enabled: Boolean = true) { +fun RepositoryHandler.myMavenLocal(enabled: Boolean = false) { if (enabled) { logger.lifecycle("Maven local is enabled") mavenLocal { diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index 4cc560d..c0d902b 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -7,7 +7,7 @@ plugins { kotlin("jvm") } -val projectKotlinTarget = "1.6" +val projectKotlinTarget = "1.7" val projectJvmTarget = "11" @@ -54,10 +54,17 @@ tasks.compileTestKotlin { kotlin { jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(projectJvmTarget)) + languageVersion.set(JavaLanguageVersion.of(projectJvmTarget)) } } tasks.withType().configureEach { useJUnitPlatform() } + + +plugins.withType().configureEach { + project.extensions.getByType().apply { + applicationDefaultJvmArgs += listOf("-Dkotlinx.coroutines.debug") + } +} diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index cd65097..54fe4eb 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -19,26 +19,10 @@ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.1.1.tgz#bf5d45611ab74890be386712a0e5d998c65ee2a1" integrity sha512-J/3yg2AIXc9wznaVqpHVX3Wa5jwKovVF0AMYSnbmcXTiL3PpRPfF58pzWucCwEiCJBp+hCNRLWClTomD8SseKg== -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" + integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== "@popperjs/core@^2.11.4": version "2.11.5" @@ -68,22 +52,52 @@ dependencies: html-parse-stringify "^3" +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.10" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" + integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== + dependencies: + "@types/node" "*" + "@types/component-emitter@^1.2.10": version "1.2.11" resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== -"@types/cookie@^0.4.0": +"@types/connect-history-api-fallback@^1.3.5": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" + integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/cookie@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== -"@types/cors@^2.8.8": +"@types/cors@^2.8.12": version "2.8.12" resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== -"@types/eslint-scope@^3.7.0": +"@types/eslint-scope@^3.7.3": version "3.7.3" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224" integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g== @@ -99,15 +113,29 @@ "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*": +"@types/estree@*", "@types/estree@^0.0.51": version "0.0.51" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== -"@types/estree@^0.0.50": - version "0.0.50" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" - integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": + version "4.17.29" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz#2a1795ea8e9e9c91b4a4bbe475034b20c1ec711c" + integrity sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" "@types/geojson@7946.0.8": version "7946.0.8" @@ -134,6 +162,11 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + "@types/minimatch@*": version "3.0.5" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" @@ -149,11 +182,50 @@ resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + "@types/retry@^0.12.0": version "0.12.1" resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== +"@types/serve-index@^1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" + integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== + dependencies: + "@types/express" "*" + +"@types/serve-static@*", "@types/serve-static@^1.13.10": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.33" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" + integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== + dependencies: + "@types/node" "*" + +"@types/ws@^8.5.1": + version "8.5.3" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== + dependencies: + "@types/node" "*" + "@ungap/promise-all-settled@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" @@ -280,22 +352,22 @@ "@webassemblyjs/ast" "1.11.1" "@xtuc/long" "4.2.2" -"@webpack-cli/configtest@^1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.1.tgz#9f53b1b7946a6efc2a749095a4f450e2932e8356" - integrity sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg== +"@webpack-cli/configtest@^1.1.1", "@webpack-cli/configtest@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" + integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== -"@webpack-cli/info@^1.4.0": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.1.tgz#2360ea1710cbbb97ff156a3f0f24556e0fc1ebea" - integrity sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA== +"@webpack-cli/info@^1.4.1", "@webpack-cli/info@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" + integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== dependencies: envinfo "^7.7.3" -"@webpack-cli/serve@^1.6.0": - version "1.6.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.1.tgz#0de2875ac31b46b6c5bb1ae0a7d7f0ba5678dffe" - integrity sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw== +"@webpack-cli/serve@^1.6.1", "@webpack-cli/serve@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" + integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== "@xtuc/ieee754@^1.2.0": version "1.2.0" @@ -330,14 +402,6 @@ acorn@^8.4.1, acorn@^8.5.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" @@ -392,11 +456,6 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -429,23 +488,11 @@ array-flatten@1.1.1: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= -array-flatten@^2.1.0: +array-flatten@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -async@^2.6.2: - version "2.6.4" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" - integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== - dependencies: - lodash "^4.17.14" - awesome-bootstrap-checkbox@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/awesome-bootstrap-checkbox/-/awesome-bootstrap-checkbox-1.0.1.tgz#dab10146b6001129ab0a0ec1e54bb77c6c30457a" @@ -456,11 +503,6 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-arraybuffer@0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" - integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= - base64id@2.0.0, base64id@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" @@ -476,23 +518,7 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -body-parser@1.19.2: - version "1.19.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.2.tgz#4714ccd9c157d44797b8b5607d72c0b89952f26e" - integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw== - dependencies: - bytes "3.1.2" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.2" - http-errors "1.8.1" - iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.9.7" - raw-body "2.4.3" - type-is "~1.6.18" - -body-parser@^1.19.0: +body-parser@1.20.0, body-parser@^1.19.0: version "1.20.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== @@ -510,17 +536,15 @@ body-parser@^1.19.0: type-is "~1.6.18" unpipe "1.0.0" -bonjour@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" - integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= +bonjour-service@^1.0.11: + version "1.0.13" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.13.tgz#4ac003dc1626023252d58adf2946f57e5da450c1" + integrity sha512-LWKRU/7EqDUC9CTAQtuZl5HzBALoCYwtLhffW3et7vZMwv3bWLpJf8bRYlMD5OCcDpTfnPgNCV4yo9ZIaJGMiA== dependencies: - array-flatten "^2.1.0" - deep-equal "^1.0.1" + array-flatten "^2.1.2" dns-equal "^1.0.0" - dns-txt "^2.0.2" - multicast-dns "^6.0.1" - multicast-dns-service-types "^1.1.0" + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.5" bootstrap-icons@^1.8.1: version "1.8.1" @@ -568,11 +592,6 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer-indexof@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" - integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== - bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -583,7 +602,7 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -call-bind@^1.0.0, call-bind@^1.0.2: +call-bind@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== @@ -623,22 +642,7 @@ chart.js@^3.7.1: resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.7.1.tgz#0516f690c6a8680c6c707e31a4c1807a6f400ada" integrity sha512-8knRegQLFnPQAheZV8MjxIXc5gQEfDFD897BJgv/klO/vtIyFFmgMXrNfgrXpbTr/XbTturxRgxIXx/Y+ASJBA== -chokidar@3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" - integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chokidar@^3.5.1: +chokidar@3.5.3, chokidar@^3.5.1, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -658,11 +662,6 @@ chrome-trace-event@^1.0.2: resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -710,7 +709,7 @@ colorette@^2.0.10, colorette@^2.0.14: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== -colors@^1.4.0: +colors@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== @@ -792,7 +791,12 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= -cookie@0.4.2, cookie@~0.4.1: +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +cookie@~0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== @@ -848,10 +852,10 @@ custom-event@~1.0.0: resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" integrity sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU= -date-format@^4.0.9: - version "4.0.9" - resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.9.tgz#4788015ac56dedebe83b03bc361f00c1ddcf1923" - integrity sha512-+8J+BOUpSrlKLQLeF8xJJVTxS8QfRSuJgwxSVvslzgO3E6khbI0F5mMEPf5mTYhCCm4h99knYP6H3W9n3BQFrg== +date-format@^4.0.10: + version "4.0.11" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.11.tgz#ae0d1e069d7f0687938fd06f98c12f3a6276e526" + integrity sha512-VS20KRyorrbMCQmpdl2hg5KaOUsda1RbnsJg461FfrcyCUg+pkd0b40BSW4niQyTheww4DBXQnS7HwSrKkipLw== debug@2.6.9: version "2.6.9" @@ -860,21 +864,14 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== +debug@4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== dependencies: ms "2.1.2" -debug@^3.1.1: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.1.0, debug@^4.3.4, debug@~4.3.1: +debug@^4.1.0, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -886,19 +883,7 @@ decamelize@^4.0.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== -deep-equal@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - -default-gateway@^6.0.0: +default-gateway@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== @@ -910,28 +895,6 @@ define-lazy-prop@^2.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-properties@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -del@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/del/-/del-6.0.0.tgz#0b40d0332cea743f1614f818be4feb717714c952" - integrity sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ== - dependencies: - globby "^11.0.1" - graceful-fs "^4.2.4" - is-glob "^4.0.1" - is-path-cwd "^2.2.0" - is-path-inside "^3.0.2" - p-map "^4.0.0" - rimraf "^3.0.2" - slash "^3.0.0" - depd@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" @@ -947,11 +910,6 @@ destroy@1.2.0: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - detect-node@^2.0.4: version "2.1.0" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" @@ -967,32 +925,17 @@ diff@5.0.0: resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - dns-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= -dns-packet@^1.3.1: - version "1.3.4" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" - integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== +dns-packet@^5.2.2: + version "5.4.0" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.4.0.tgz#1f88477cf9f27e78a213fb6d118ae38e759a879b" + integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g== dependencies: - ip "^1.1.0" - safe-buffer "^5.0.1" - -dns-txt@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" - integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= - dependencies: - buffer-indexof "^1.0.0" + "@leichtgewicht/ip-codec" "^2.0.1" dom-serialize@^2.2.1: version "2.2.1" @@ -1047,25 +990,26 @@ encoding@^0.1.12: dependencies: iconv-lite "^0.6.2" -engine.io-parser@~4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-4.0.3.tgz#83d3a17acfd4226f19e721bb22a1ee8f7662d2f6" - integrity sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA== - dependencies: - base64-arraybuffer "0.1.4" +engine.io-parser@~5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.4.tgz#0b13f704fa9271b3ec4f33112410d8f3f41d0fc0" + integrity sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg== -engine.io@~4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-4.1.2.tgz#f96ceb56d4b39cc7ca5bd29a20e9c99c1ad1a765" - integrity sha512-t5z6zjXuVLhXDMiFJPYsPOWEER8B0tIsD3ETgw19S1yg9zryvUfY3Vhtk3Gf4sihw/bQGIqQ//gjvVlu+Ca0bQ== +engine.io@~6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.2.0.tgz#003bec48f6815926f2b1b17873e576acd54f41d0" + integrity sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg== dependencies: + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" accepts "~1.3.4" base64id "2.0.0" cookie "~0.4.1" cors "~2.8.5" debug "~4.3.1" - engine.io-parser "~4.0.0" - ws "~7.4.2" + engine.io-parser "~5.0.3" + ws "~8.2.3" enhanced-resolve@^5.8.3: version "5.9.3" @@ -1165,38 +1109,39 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -express@^4.17.1: - version "4.17.3" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.3.tgz#f6c7302194a4fb54271b73a1fe7a06478c8f85a1" - integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg== +express@^4.17.3: + version "4.18.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" + integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.19.2" + body-parser "1.20.0" content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.4.2" + cookie "0.5.0" cookie-signature "1.0.6" debug "2.6.9" - depd "~1.1.2" + depd "2.0.0" encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "~1.1.2" + finalhandler "1.2.0" fresh "0.5.2" + http-errors "2.0.0" merge-descriptors "1.0.1" methods "~1.1.2" - on-finished "~2.3.0" + on-finished "2.4.1" parseurl "~1.3.3" path-to-regexp "0.1.7" proxy-addr "~2.0.7" - qs "6.9.7" + qs "6.10.3" range-parser "~1.2.1" safe-buffer "5.2.1" - send "0.17.2" - serve-static "1.14.2" + send "0.18.0" + serve-static "1.15.0" setprototypeof "1.2.0" - statuses "~1.5.0" + statuses "2.0.1" type-is "~1.6.18" utils-merge "1.0.1" vary "~1.1.2" @@ -1211,17 +1156,6 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.9: - version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" - integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -1232,13 +1166,6 @@ fastest-levenshtein@^1.0.12: resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== -fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== - dependencies: - reusify "^1.0.4" - faye-websocket@^0.11.3: version "0.11.4" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" @@ -1258,7 +1185,7 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -finalhandler@1.1.2, finalhandler@~1.1.2: +finalhandler@1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== @@ -1271,6 +1198,19 @@ finalhandler@1.1.2, finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + find-up@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" @@ -1355,11 +1295,6 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -functions-have-names@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - geojson@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/geojson/-/geojson-0.5.0.tgz#3cd6c96399be65b56ee55596116fe9191ce701c0" @@ -1370,7 +1305,7 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: +get-intrinsic@^1.0.2: version "1.1.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== @@ -1431,7 +1366,7 @@ gettext-to-messageformat@0.3.1: dependencies: gettext-parser "^1.4.0" -glob-parent@^5.1.2, glob-parent@~5.1.2: +glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -1443,7 +1378,7 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -"glob@5 - 7", glob@^7.1.3, glob@^7.1.7: +"glob@5 - 7", glob@7.2.0, glob@^7.1.3, glob@^7.1.7: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== @@ -1455,36 +1390,12 @@ glob-to-regexp@^0.4.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globby@^11.0.1: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - google-protobuf@3.12.2: version "3.12.2" resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.12.2.tgz#50ce9f9b6281235724eb243d6a83e969a2176e53" integrity sha512-4CZhpuRr1d6HjlyrxoXoocoGFnRYgKULgMtikMddA9ztRyYR59Aondv2FioyxWVamRo0rF2XpYawkTCBEQOSkA== -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== @@ -1509,25 +1420,11 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" - -has-symbols@^1.0.1, has-symbols@^1.0.2: +has-symbols@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -1567,17 +1464,6 @@ http-deceiver@^1.2.7: resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= -http-errors@1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" - integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.1" - http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -1604,10 +1490,10 @@ http-parser-js@>=0.5.1: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.6.tgz#2e02406ab2df8af8a7abfba62e0da01c62b95afd" integrity sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA== -http-proxy-middleware@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.5.tgz#2d12fb41a414889372643a1f54279a2f6470aa93" - integrity sha512-ORErEaxkjyrhifofwCuQttHPUSestLtiPDwV0qQOFB0ww6695H953wIGRnkakw1K+GAP+t8/RPbfDB75RFL4Fg== +"http-proxy-middleware@>=2.0.6 <3.0.0", http-proxy-middleware@^2.0.3, http-proxy-middleware@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== dependencies: "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" @@ -1636,7 +1522,7 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.6.2: +iconv-lite@^0.6.2, iconv-lite@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== @@ -1648,11 +1534,6 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== - import-local@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" @@ -1669,11 +1550,6 @@ imports-loader@^3.1.1: source-map "^0.6.1" strip-comments "^2.0.1" -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -1692,32 +1568,12 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -internal-ip@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-6.2.0.tgz#d5541e79716e406b74ac6b07b856ef18dc1621c1" - integrity sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg== - dependencies: - default-gateway "^6.0.0" - ipaddr.js "^1.9.1" - is-ip "^3.1.0" - p-event "^4.2.0" - interpret@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== -ip-regex@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" - integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== - -ip@^1.1.0: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= - -ipaddr.js@1.9.1, ipaddr.js@^1.9.1: +ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== @@ -1727,14 +1583,6 @@ ipaddr.js@^2.0.1: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== -is-arguments@^1.0.4: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" - integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -1749,13 +1597,6 @@ is-core-module@^2.8.1: dependencies: has "^1.0.3" -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - is-docker@^2.0.0, is-docker@^2.1.1: version "2.2.1" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" @@ -1778,28 +1619,11 @@ is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-ip@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8" - integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q== - dependencies: - ip-regex "^4.0.0" - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-path-cwd@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - -is-path-inside@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - is-plain-obj@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" @@ -1817,14 +1641,6 @@ is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-regex@^1.0.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - is-stream@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" @@ -1944,15 +1760,15 @@ karma-webpack@5.0.0: minimatch "^3.0.4" webpack-merge "^4.1.5" -karma@6.3.4: - version "6.3.4" - resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.4.tgz#359899d3aab3d6b918ea0f57046fd2a6b68565e6" - integrity sha512-hbhRogUYIulfkBTZT7xoPrCYhRBnBoqbbL4fszWD0ReFGUxU+LYBr3dwKdAluaDQ/ynT9/7C+Lf7pPNW4gSx4Q== +karma@6.3.16: + version "6.3.16" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.16.tgz#76d1a705fd1cf864ee5ed85270b572641e0958ef" + integrity sha512-nEU50jLvDe5yvXqkEJRf8IuvddUkOY2x5Xc4WXHz6dxINgGDrgD2uqQWeVrJs4hbfNaotn+HQ1LZJ4yOXrL7xQ== dependencies: body-parser "^1.19.0" braces "^3.0.2" chokidar "^3.5.1" - colors "^1.4.0" + colors "1.4.0" connect "^3.7.0" di "^0.0.1" dom-serialize "^2.2.1" @@ -1961,16 +1777,17 @@ karma@6.3.4: http-proxy "^1.18.1" isbinaryfile "^4.0.8" lodash "^4.17.21" - log4js "^6.3.0" + log4js "^6.4.1" mime "^2.5.2" minimatch "^3.0.4" + mkdirp "^0.5.5" qjobs "^1.2.0" range-parser "^1.2.1" rimraf "^3.0.2" - socket.io "^3.1.0" + socket.io "^4.2.0" source-map "^0.6.1" tmp "^0.2.1" - ua-parser-js "^0.7.28" + ua-parser-js "^0.7.30" yargs "^16.1.1" kind-of@^6.0.2: @@ -2007,7 +1824,7 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21: +lodash@^4.17.15, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -2020,16 +1837,16 @@ log-symbols@4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -log4js@^6.3.0: - version "6.4.6" - resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.4.6.tgz#1878aa3f09973298ecb441345fe9dd714e355c15" - integrity sha512-1XMtRBZszmVZqPAOOWczH+Q94AI42mtNWjvjA5RduKTSWjEc56uOBbyM1CJnfN4Ym0wSd8cQ43zOojlSHgRDAw== +log4js@^6.4.1: + version "6.5.2" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.5.2.tgz#9ae371e5b3cb3a3a209c24686e5547f8670834e5" + integrity sha512-DXtpNtt+KDOMT7RHUDIur/WsSA3rntlUh9Zg4XCdV42wUuMmbFkl38+LZ92Z5QvQA7mD5kAVkLiBSEH/tvUB8A== dependencies: - date-format "^4.0.9" + date-format "^4.0.10" debug "^4.3.4" flatted "^3.2.5" rfdc "^1.3.0" - streamroller "^3.0.8" + streamroller "^3.1.1" lru-cache@^6.0.0: version "6.0.0" @@ -2043,10 +1860,10 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= -memfs@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.1.tgz#b78092f466a0dce054d63d39275b24c71d3f1305" - integrity sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw== +memfs@^3.4.3: + version "3.4.4" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.4.tgz#e8973cd8060548916adcca58a248e7805c715e89" + integrity sha512-W4gHNUE++1oSJVn8Y68jPXi+mkx3fXR5ITE/Ubz6EQ3xRpCN5k2CQ4AUR8094Z7211F876TyoBACGsIveqgiGA== dependencies: fs-monkey "1.0.3" @@ -2060,17 +1877,12 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -micromatch@^4.0.2, micromatch@^4.0.4: +micromatch@^4.0.2: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -2136,32 +1948,32 @@ mkdirp@^0.5.5: dependencies: minimist "^1.2.6" -mocha@9.1.2: - version "9.1.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.1.2.tgz#93f53175b0f0dc4014bd2d612218fccfcf3534d3" - integrity sha512-ta3LtJ+63RIBP03VBjMGtSqbe6cWXRejF9SyM9Zyli1CKZJZ+vfCTj3oW24V7wAphMJdpOFLoMI3hjJ1LWbs0w== +mocha@9.2.1: + version "9.2.1" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.1.tgz#a1abb675aa9a8490798503af57e8782a78f1338e" + integrity sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ== dependencies: "@ungap/promise-all-settled" "1.1.2" ansi-colors "4.1.1" browser-stdout "1.3.1" - chokidar "3.5.2" - debug "4.3.2" + chokidar "3.5.3" + debug "4.3.3" diff "5.0.0" escape-string-regexp "4.0.0" find-up "5.0.0" - glob "7.1.7" + glob "7.2.0" growl "1.10.5" he "1.2.0" js-yaml "4.1.0" log-symbols "4.1.0" minimatch "3.0.4" ms "2.1.3" - nanoid "3.1.25" + nanoid "3.2.0" serialize-javascript "6.0.0" strip-json-comments "3.1.1" supports-color "8.1.1" which "2.0.2" - workerpool "6.1.5" + workerpool "6.2.0" yargs "16.2.0" yargs-parser "20.2.4" yargs-unparser "2.0.0" @@ -2176,28 +1988,23 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.1.1: +ms@2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -multicast-dns-service-types@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" - integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= - -multicast-dns@^6.0.1: - version "6.2.3" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" - integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== +multicast-dns@^7.2.5: + version "7.2.5" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" + integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== dependencies: - dns-packet "^1.3.1" + dns-packet "^5.2.2" thunky "^1.0.2" -nanoid@3.1.25: - version "3.1.25" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" - integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== +nanoid@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" + integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== nanoid@^3.3.1: version "3.3.3" @@ -2214,10 +2021,10 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -node-forge@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" - integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== node-releases@^2.0.2: version "2.0.3" @@ -2246,19 +2053,6 @@ object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== -object-is@^1.0.1: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - obuf@^1.0.0, obuf@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" @@ -2306,18 +2100,6 @@ open@^8.0.9: is-docker "^2.1.1" is-wsl "^2.2.0" -p-event@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" - integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== - dependencies: - p-timeout "^3.1.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -2346,13 +2128,6 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - p-retry@^4.5.0: version "4.6.1" resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c" @@ -2361,13 +2136,6 @@ p-retry@^4.5.0: "@types/retry" "^0.12.0" retry "^0.13.1" -p-timeout@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" - integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== - dependencies: - p-finally "^1.0.0" - p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -2408,11 +2176,6 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -2435,15 +2198,6 @@ pofile@1.0.x: resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.0.11.tgz#35aff58c17491d127a07336d5522ebc9df57c954" integrity sha512-Vy9eH1dRD9wHjYt/QqXcTz+RnX/zg53xK+KljFSX30PvdDMb2z+c6uDUeblUGqqJgz3QFsdlA0IJvHziPmWtQg== -portfinder@^1.0.28: - version "1.0.28" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" - integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== - dependencies: - async "^2.6.2" - debug "^3.1.1" - mkdirp "^0.5.5" - postcss-modules-extract-imports@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" @@ -2507,11 +2261,6 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -2529,21 +2278,6 @@ qs@6.10.3: dependencies: side-channel "^1.0.4" -qs@6.9.7: - version "6.9.7" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe" - integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -2556,16 +2290,6 @@ range-parser@^1.2.1, range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.3.tgz#8f80305d11c2a0a545c2d9d89d7a0286fcead43c" - integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g== - dependencies: - bytes "3.1.2" - http-errors "1.8.1" - iconv-lite "0.4.24" - unpipe "1.0.0" - raw-body@2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" @@ -2629,15 +2353,6 @@ regenerator-runtime@^0.13.4: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== -regexp.prototype.flags@^1.2.0: - version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -2679,11 +2394,6 @@ retry@^0.13.1: resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - rfdc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" @@ -2696,19 +2406,12 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -2742,12 +2445,12 @@ select-hose@^2.0.0: resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= -selfsigned@^1.10.11: - version "1.10.14" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.14.tgz#ee51d84d9dcecc61e07e4aba34f229ab525c1574" - integrity sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA== +selfsigned@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" + integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ== dependencies: - node-forge "^0.10.0" + node-forge "^1" semver@^7.3.5: version "7.3.7" @@ -2756,24 +2459,24 @@ semver@^7.3.5: dependencies: lru-cache "^6.0.0" -send@0.17.2: - version "0.17.2" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" - integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== dependencies: debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" + depd "2.0.0" + destroy "1.2.0" encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" fresh "0.5.2" - http-errors "1.8.1" + http-errors "2.0.0" mime "1.6.0" ms "2.1.3" - on-finished "~2.3.0" + on-finished "2.4.1" range-parser "~1.2.1" - statuses "~1.5.0" + statuses "2.0.1" serialize-javascript@6.0.0, serialize-javascript@^6.0.0: version "6.0.0" @@ -2795,15 +2498,15 @@ serve-index@^1.9.1: mime-types "~2.1.17" parseurl "~1.3.2" -serve-static@1.14.2: - version "1.14.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" - integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== dependencies: encodeurl "~1.0.2" escape-html "~1.0.3" parseurl "~1.3.3" - send "0.17.2" + send "0.18.0" setprototypeof@1.1.0: version "1.1.0" @@ -2848,22 +2551,17 @@ signal-exit@^3.0.3: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - snabbdom@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.5.0.tgz#e75acbdedb26ea327c75028a433ba064db0ccf6e" integrity sha512-Ff5BKG18KrrPuskHJlA9aujPHqEabItaDl96l7ZZndF4zt5AYSczz7ZjjgQAX5IBd5cd25lw9NfgX21yVUJ+9g== -socket.io-adapter@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz#edc5dc36602f2985918d631c1399215e97a1b527" - integrity sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg== +socket.io-adapter@~2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz#b50a4a9ecdd00c34d4c8c808224daa1a786152a6" + integrity sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg== -socket.io-parser@~4.0.3: +socket.io-parser@~4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0" integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g== @@ -2872,22 +2570,19 @@ socket.io-parser@~4.0.3: component-emitter "~1.3.0" debug "~4.3.1" -socket.io@^3.1.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-3.1.2.tgz#06e27caa1c4fc9617547acfbb5da9bc1747da39a" - integrity sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw== +socket.io@^4.2.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.5.1.tgz#aa7e73f8a6ce20ee3c54b2446d321bbb6b1a9029" + integrity sha512-0y9pnIso5a9i+lJmsCdtmTTgJFFSvNQKDnPQRz28mGNnxbmqYg2QPtJTLFxhymFZhAIn50eHAKzJeiNaKr+yUQ== dependencies: - "@types/cookie" "^0.4.0" - "@types/cors" "^2.8.8" - "@types/node" ">=10.0.0" accepts "~1.3.4" base64id "~2.0.0" - debug "~4.3.1" - engine.io "~4.1.0" - socket.io-adapter "~2.1.0" - socket.io-parser "~4.0.3" + debug "~4.3.2" + engine.io "~6.2.0" + socket.io-adapter "~2.4.0" + socket.io-parser "~4.0.4" -sockjs@^0.3.21: +sockjs@^0.3.24: version "0.3.24" resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== @@ -2896,32 +2591,19 @@ sockjs@^0.3.21: uuid "^8.3.2" websocket-driver "^0.7.4" -source-map-js@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" - integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== - -source-map-js@^1.0.2: +source-map-js@^1.0.1, source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== -source-map-loader@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.0.tgz#f2a04ee2808ad01c774dea6b7d2639839f3b3049" - integrity sha512-GKGWqWvYr04M7tn8dryIWvb0s8YM41z82iQv01yBtIylgxax0CwvSy6gc2Y02iuXwEfGWRlMicH0nvms9UZphw== +source-map-loader@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.1.tgz#9ae5edc7c2d42570934be4c95d1ccc6352eba52d" + integrity sha512-Vp1UsfyPvgujKQzi4pyDiTOnE3E4H+yHvkVRN3c/9PJmQS4CQJExvcDvaX/D+RV+xQben9HJ56jMJS3CgUeWyA== dependencies: abab "^2.0.5" - iconv-lite "^0.6.2" - source-map-js "^0.6.2" - -source-map-support@0.5.20: - version "0.5.20" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" - integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" + iconv-lite "^0.6.3" + source-map-js "^1.0.1" source-map-support@~0.5.20: version "0.5.21" @@ -2974,17 +2656,17 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== -"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: +"statuses@>= 1.4.0 < 2", statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -streamroller@^3.0.8: - version "3.0.8" - resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.0.8.tgz#84b190e4080ee311ca1ebe0444e30ac8eedd028d" - integrity sha512-VI+ni3czbFZrd1MrlybxykWZ8sMDCMtTU7YJyhgb9M5X6d1DDxLdJr+gSnmRpXPMnIWxWKMaAE8K0WumBp3lDg== +streamroller@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.1.1.tgz#679aae10a4703acdf2740755307df0a05ad752e6" + integrity sha512-iPhtd9unZ6zKdWgMeYGfSBuqCngyJy1B/GPi/lTpwGpa3bajuX30GjUVd0/Tn/Xhg0mr4DOSENozz9Y06qyonQ== dependencies: - date-format "^4.0.9" + date-format "^4.0.10" debug "^4.3.4" fs-extra "^10.1.0" @@ -3018,13 +2700,6 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== - dependencies: - ansi-regex "^6.0.1" - strip-comments@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" @@ -3139,7 +2814,7 @@ typescript@3.9.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== -ua-parser-js@^0.7.28: +ua-parser-js@^0.7.30: version "0.7.31" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== @@ -3166,14 +2841,6 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -3189,11 +2856,6 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -v8-compile-cache@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -3209,10 +2871,10 @@ void-elements@^2.0.0: resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w= -watchpack@^2.2.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25" - integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== +watchpack@^2.3.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -3224,15 +2886,33 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" -webpack-cli@4.9.0: - version "4.9.0" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.0.tgz#dc43e6e0f80dd52e89cbf73d5294bcd7ad6eb343" - integrity sha512-n/jZZBMzVEl4PYIBs+auy2WI0WTQ74EnJDiyD98O2JZY6IVIHJNitkYp/uTXOviIOMfgzrNvC9foKv/8o8KSZw== +webpack-cli@4.10.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" + integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== dependencies: "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.1.0" - "@webpack-cli/info" "^1.4.0" - "@webpack-cli/serve" "^1.6.0" + "@webpack-cli/configtest" "^1.2.0" + "@webpack-cli/info" "^1.5.0" + "@webpack-cli/serve" "^1.7.0" + colorette "^2.0.14" + commander "^7.0.0" + cross-spawn "^7.0.3" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + webpack-merge "^5.7.3" + +webpack-cli@4.9.2: + version "4.9.2" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.2.tgz#77c1adaea020c3f9e2db8aad8ea78d235c83659d" + integrity sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.1.1" + "@webpack-cli/info" "^1.4.1" + "@webpack-cli/serve" "^1.6.1" colorette "^2.0.14" commander "^7.0.0" execa "^5.0.0" @@ -3240,50 +2920,53 @@ webpack-cli@4.9.0: import-local "^3.0.2" interpret "^2.2.0" rechoir "^0.7.0" - v8-compile-cache "^2.2.0" webpack-merge "^5.7.3" -webpack-dev-middleware@^5.2.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz#aa079a8dedd7e58bfeab358a9af7dab304cee57f" - integrity sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg== +webpack-dev-middleware@^5.3.1: + version "5.3.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" + integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== dependencies: colorette "^2.0.10" - memfs "^3.4.1" + memfs "^3.4.3" mime-types "^2.1.31" range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.3.1.tgz#759d3337f0fbea297fbd1e433ab04ccfc000076b" - integrity sha512-qNXQCVYo1kYhH9pgLtm8LRNkXX3XzTfHSj/zqzaqYzGPca+Qjr+81wj1jgPMCHhIhso9WEQ+kX9z23iG9PzQ7w== +webpack-dev-server@4.9.2: + version "4.9.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.9.2.tgz#c188db28c7bff12f87deda2a5595679ebbc3c9bc" + integrity sha512-H95Ns95dP24ZsEzO6G9iT+PNw4Q7ltll1GfJHV4fKphuHWgKFzGHWi4alTlTnpk1SPPk41X+l2RB7rLfIhnB9Q== dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/serve-static" "^1.13.10" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.1" ansi-html-community "^0.0.8" - bonjour "^3.5.0" - chokidar "^3.5.1" + bonjour-service "^1.0.11" + chokidar "^3.5.3" colorette "^2.0.10" compression "^1.7.4" connect-history-api-fallback "^1.6.0" - del "^6.0.0" - express "^4.17.1" + default-gateway "^6.0.3" + express "^4.17.3" graceful-fs "^4.2.6" html-entities "^2.3.2" - http-proxy-middleware "^2.0.0" - internal-ip "^6.2.0" + http-proxy-middleware "^2.0.3" ipaddr.js "^2.0.1" open "^8.0.9" p-retry "^4.5.0" - portfinder "^1.0.28" - schema-utils "^3.1.0" - selfsigned "^1.10.11" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.0.1" serve-index "^1.9.1" - sockjs "^0.3.21" + sockjs "^0.3.24" spdy "^4.0.2" - strip-ansi "^7.0.0" - url "^0.11.0" - webpack-dev-middleware "^5.2.1" - ws "^8.1.0" + webpack-dev-middleware "^5.3.1" + ws "^8.4.2" webpack-merge@^4.1.5: version "4.2.2" @@ -3300,18 +2983,18 @@ webpack-merge@^5.7.3: clone-deep "^4.0.1" wildcard "^2.0.0" -webpack-sources@^3.2.0: +webpack-sources@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@5.57.1: - version "5.57.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.57.1.tgz#ead5ace2c17ecef2ae8126f143bfeaa7f55eab44" - integrity sha512-kHszukYjTPVfCOEyrUthA3jqJwduY/P3eO8I0gMNOZGIQWKAwZftxmp5hq6paophvwo9NoUrcZOecs9ulOyyTg== +webpack@5.69.1: + version "5.69.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.69.1.tgz#8cfd92c192c6a52c99ab00529b5a0d33aa848dc5" + integrity sha512-+VyvOSJXZMT2V5vLzOnDuMz5GxEqLk7hKWQ56YxPW/PQRUuKimPqmEIJOx8jHYeyo65pKbapbW464mvsKbaj4A== dependencies: - "@types/eslint-scope" "^3.7.0" - "@types/estree" "^0.0.50" + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^0.0.51" "@webassemblyjs/ast" "1.11.1" "@webassemblyjs/wasm-edit" "1.11.1" "@webassemblyjs/wasm-parser" "1.11.1" @@ -3324,7 +3007,7 @@ webpack@5.57.1: eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" json-parse-better-errors "^1.0.2" loader-runner "^4.2.0" mime-types "^2.1.27" @@ -3332,8 +3015,8 @@ webpack@5.57.1: schema-utils "^3.1.0" tapable "^2.1.1" terser-webpack-plugin "^5.1.3" - watchpack "^2.2.0" - webpack-sources "^3.2.0" + watchpack "^2.3.1" + webpack-sources "^3.2.3" websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" @@ -3368,10 +3051,10 @@ wildcard@^2.0.0: resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== -workerpool@6.1.5: - version "6.1.5" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.5.tgz#0f7cf076b6215fd7e1da903ff6f22ddd1886b581" - integrity sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw== +workerpool@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" + integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== wrap-ansi@^7.0.0: version "7.0.0" @@ -3387,15 +3070,15 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@^8.1.0: - version "8.6.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.6.0.tgz#e5e9f1d9e7ff88083d0c0dd8281ea662a42c9c23" - integrity sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw== +ws@^8.4.2: + version "8.8.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.0.tgz#8e71c75e2f6348dbf8d78005107297056cb77769" + integrity sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ== -ws@~7.4.2: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +ws@~8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== y18n@^5.0.5: version "5.0.8" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 853a06e..d369186 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,13 +6,13 @@ ## compilation ## jvm = "11" -kotlin = "1.6.21" +kotlin = "1.7.0" ## libs ## camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" kafka = "3.2.0" -kvision = "5.10.0" +kvision = "5.10.1" log4j2 = "2.17.2" qosLogback = "1.2.11" slf4j = "1.7.36" @@ -21,7 +21,8 @@ scrimage = "4.0.31" semver = "1.2.0" kotlinx-serialization = "1.3.3" -kxs-yaml = "0.44.0" +kxs-charleskornKaml = "0.44.0" +kxs-mamoeYamlkt = "0.12.0" kotlinJsWrappers = "1.0.0-pre.339" kotlinx-html = "0.7.5" @@ -30,9 +31,11 @@ kotlinx-coroutines = "1.6.1" kotlinx-cli = "0.3.4" kotlinx-datetime = "0.3.3" -ktor = "2.0.1" +ktor = "2.0.2" -kotkaStreams = "v22.05.25" +hoplite = "2.1.5" + +kotkaStreams = "dev-SNAPSHOT" ## test ## junit = "5.8.2" @@ -68,14 +71,25 @@ loggingCapabilities = { id = "dev.jacomet.logging-capabilities", vers ## kotlin ## kotlin-bom = { group = "org.jetbrains.kotlin", name = "kotlin-bom", version.ref = "kotlin" } + +kotlinScripting-common = { group = "org.jetbrains.kotlin", name = "kotlin-scripting-common" } +kotlinScripting-jvm = { group = "org.jetbrains.kotlin", name = "kotlin-scripting-jvm" } +kotlinScripting-jvmHost = { group = "org.jetbrains.kotlin", name = "kotlin-scripting-jvm-host" } +kotlinScripting-dependencies = { group = "org.jetbrains.kotlin", name = "kotlin-scripting-dependencies" } +kotlinScripting-dependenciesMaven = { group = "org.jetbrains.kotlin", name = "kotlin-scripting-dependencies-maven" } + + kotlinx-serialization-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-bom", version.ref = "kotlinx-serialization" } kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core" } -kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json" } -kotlinx-serialization-protobuf = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-protobuf" } kotlinx-serialization-cbor = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-cbor" } +kotlinx-serialization-hocon = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-hocon" } +kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json" } kotlinx-serialization-properties = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-properties" } +kotlinx-serialization-protobuf = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-protobuf" } + +kxs-charleskornKaml = { group = "com.charleskorn.kaml", name = "kaml", version.ref = "kxs-charleskornKaml" } +kxs-mamoeYamlkt = { group = "net.mamoe.yamlkt", name = "yamlkt", version.ref = "kxs-mamoeYamlkt" } -kotlinx-serialization-yaml = { group = "com.charleskorn.kaml", name = "kaml", version.ref = "kxs-yaml" } kotlinx-coroutines-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-bom", version.ref = "kotlinx-coroutines" } kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core" } @@ -169,7 +183,8 @@ kafka-streamsTestUtils = { group = "org.apache.kafka", name = "kafka-streams-tes # kafka helpers #kotka = { group = "com.github.blueanvil", name = "kotka", version = "1.1.1" } -kafka-kotkaStreams = { group = "com.github.adamko-dev.kotka-streams", name = "kotka-streams", version.ref = "kotkaStreams" } +#kafka-kotkaStreams = { group = "com.github.adamko-dev.kotka-streams", name = "kotka-streams", version.ref = "kotkaStreams" } +kafka-kotkaStreams = { group = "dev.adamko.kotka", name = "kotka-streams", version.ref = "kotkaStreams" } rocksdb = { group = "io.maryk.rocksdb", name = "rocksdb-multiplatform", version = "7.0.3" } @@ -186,6 +201,10 @@ okio-bom = { group = "com.squareup.okio", name = "okio-bom", version.ref = "oki okio-core = { group = "com.squareup.okio", name = "okio" } +hoplite-core = { group = "com.sksamuel.hoplite", name = "hoplite-core", version.ref = "hoplite" } +hoplite-datetime = { group = "com.sksamuel.hoplite", name = "hoplite-datetime", version.ref = "hoplite" } +hoplite-yaml = { group = "com.sksamuel.hoplite", name = "hoplite-yaml", version.ref = "hoplite" } + ############# ### test ### ############# @@ -256,3 +275,22 @@ http4k-test = [ "http4k-test-approval", "http4k-test-kotest", ] + +kotlinScripting-def = [ + "kotlinScripting-common", + "kotlinScripting-jvm", + "kotlinScripting-dependencies", + "kotlinScripting-dependenciesMaven", +] + +kotlinScripting-host = [ + "kotlinScripting-common", + "kotlinScripting-jvm", + "kotlinScripting-jvmHost", +] + +hoplite = [ + "hoplite-core", + "hoplite-yaml", + "hoplite-datetime", +] diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 7116cf1..00a1cab 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -9,8 +9,7 @@ "engines": { "node": "~14.19.1" }, - "devDependencies": { - }, + "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", "typescript-to-lua": "1.4.4", @@ -18,10 +17,7 @@ "typescript": "4.6.2" }, "license": "UNLICENSED", - "peerDependencies": { - }, - "optionalDependencies": { - }, - "bundledDependencies": [ - ] + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] } diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index 6a01f12..27f6e3c 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -63,10 +63,7 @@ kotlin { implementation(project.dependencies.platform(libs.kotlinx.serialization.bom)) implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.json) - api("dev.adamko.kxtsgen:kxs-ts-gen-core:dev-SNAPSHOT") -// implementation("com.github.adamko-dev:kotlinx-serialization-typescript-generator:dev-SNAPSHOT") { -// isChanging = true -// } + api("dev.adamko.kxstsgen:kxs-ts-gen-core:0.1.3") } } diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index d0bfdee..25580f9 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -46,6 +46,7 @@ dependencies { isChanging = true } + implementation(libs.bundles.hoplite) } //configurations.all { diff --git a/modules/infra-kafka-cluster/build.gradle.kts b/modules/infra-kafka-cluster/build.gradle.kts index 8f52b7e..dba548c 100644 --- a/modules/infra-kafka-cluster/build.gradle.kts +++ b/modules/infra-kafka-cluster/build.gradle.kts @@ -9,6 +9,9 @@ tasks.dockerEnv { "GRAFANA_VERSION" to libs.versions.grafana, "PROMETHEUS_VERSION" to libs.versions.prometheus, "KAFKA_VERSION" to libs.versions.kafka, + "KAFKA_DL_URL" to libs.versions.kafka.map { ver -> + "https://dlcdn.apache.org/kafka/$ver/kafka_2.13-$ver.tgz" + } // Limit JVM Heap Size // "KAFKA_BROKER_HEAP_OPTS" to "-XX:MaxRAMPercentage=70.0", diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index 0ba8dd3..30f6a99 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -2,5 +2,6 @@ COMPOSE_PROJECT_NAME=kafkatorio GRAFANA_VERSION=8.5.0 KAFKATORIO_VERSION=0.5.1 -KAFKA_VERSION=3.1.0 +KAFKA_DL_URL=https\://dlcdn.apache.org/kafka/3.2.0/kafka_2.13-3.2.0.tgz +KAFKA_VERSION=3.2.0 PROMETHEUS_VERSION=v2.34.0 diff --git a/modules/infra-kafka-cluster/src/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml index 2a277ee..774e776 100644 --- a/modules/infra-kafka-cluster/src/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -3,7 +3,7 @@ version: "3.9" services: kafka: - image: dev-adamko/kafka-kraft + image: dev-adamko/kafka-kraft:${KAFKA_VERSION} container_name: "kafka" restart: "unless-stopped" build: @@ -11,18 +11,19 @@ services: context: "." target: "kafka-kraft" args: - KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/3.1.0/kafka_2.13-3.1.0.tgz" + KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/${KAFKA_VERSION}/kafka_2.13-${KAFKA_VERSION}.tgz" volumes: - "./kafka-server.properties:/kafka/server.properties" environment: JMX_PORT: "9991" -# KAFKA_JMX_OPTS: "9991" + # KAFKA_JMX_OPTS: "9991" KAFKA_JMX_OPTS: "-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=kafka -Dcom.sun.management.jmxremote.rmi.port=9991" networks: - "kafka-nw" - "kafkatorio-nw" ports: + # note: other Docker containers should use 29092 - "9092:9092" - "9093:9093" diff --git a/modules/versions-platform/build.gradle.kts b/modules/versions-platform/build.gradle.kts index 1e23afc..593c4b9 100644 --- a/modules/versions-platform/build.gradle.kts +++ b/modules/versions-platform/build.gradle.kts @@ -23,7 +23,8 @@ dependencies { constraints { api(libs.skrapeit) - api(libs.kotlinx.serialization.yaml) + api(libs.kxs.charleskornKaml) + api(libs.kxs.mamoeYamlkt) api(libs.kafka.kotkaStreams) api(libs.kafka.streams) api(libs.okio.core) diff --git a/settings.gradle.kts b/settings.gradle.kts index 0380a2c..37b5fca 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -30,11 +30,10 @@ dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) // repositories { -// mavenLocal { -// content { -// includeGroup("io.kvision") -// includeGroup("dev.adamko.kotka") -// } +// maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") { +//// content { +//// includeGroup("dev.adamko.kxstsgen") +//// } // } // } } From ea0a6b939d132185fdd2976ed2491c04c01b036e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 19 Jun 2022 10:21:14 +0200 Subject: [PATCH 376/629] tidy up factorio mod publish task --- .../FactorioModPortalPublishClient.kt | 17 +++++++++++++++-- .../dev/adamko/kafkatorio/factoriomod/model.kt | 7 ++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt index f2268b7..142efed 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt @@ -27,7 +27,6 @@ import kotlinx.coroutines.runBlocking import kotlinx.serialization.json.Json import org.gradle.api.internal.tasks.userinput.UserInputHandler import org.gradle.kotlin.dsl.support.useToRun -import org.jetbrains.kotlin.cli.common.toBooleanLenient class FactorioModPortalPublishClient( @@ -91,7 +90,7 @@ class FactorioModPortalPublishClient( require(response.status.isSuccess()) { "init upload request failed" } return when (initUploadResponse) { - is Failure -> error(initUploadResponse) + is Failure -> error(initUploadResponse) is InitUploadResponse.Success -> initUploadResponse } } @@ -122,4 +121,18 @@ class FactorioModPortalPublishClient( "upload request failed" } } + + companion object { + + /** + * @see org.jetbrains.kotlin.cli.common.toBooleanLenient + */ + private fun String?.toBooleanLenient(): Boolean? = when (this?.lowercase()?.trim()) { + null -> false + in listOf("yes", "true", "on", "y") -> true + in listOf("", "no", "false", "off", "n") -> false + else -> null + } + + } } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/model.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/model.kt index 7143612..8fad949 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/model.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/model.kt @@ -21,7 +21,8 @@ sealed interface InitUploadResponse { */ @Serializable data class Success( - @SerialName("upload_url") val uploadUrl: String, + @SerialName("upload_url") + val uploadUrl: String, ) : InitUploadResponse object Serializer : @@ -68,10 +69,10 @@ data class Failure( private val reasons: Map = mapOf( //@formatter:off "InvalidApiKey" to "Missing or invalid API key for the current endpoint", - "InvalidRequest" to "Invalid request.", + "InvalidRequest" to "Invalid request", "InternalError" to "Internal error, please try again later.", "Forbidden" to "Insufficient permission for current endpoint", - "Unknown" to "Unknown error, please try again later.", + "Unknown" to "Unknown error, please try again later", "InvalidModRelease" to "Invalid release data in info.json", "InvalidModUpload" to "Invalid mod data in zipfile", "UnknownMod" to "Mod does not exist in mod portal", From 8f24bfb797761f5bcb661bf96738dd3e260b8fdb Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 19 Jun 2022 10:21:59 +0200 Subject: [PATCH 377/629] make event schema js target browser only, and not executable (faster compilation) --- modules/events-schema/build.gradle.kts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index 27f6e3c..2a1907f 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -14,7 +14,8 @@ plugins { kotlin { js(IR) { - binaries.executable() +// binaries.executable() + browser {} // browser{} causes this error: // Cannot load "webpack", it is not registered! // Perhaps you are missing some plugin? @@ -31,7 +32,7 @@ kotlin { // } // } // } - nodejs() +// nodejs() } jvm { val main by compilations.getting { @@ -156,11 +157,12 @@ val generateTypescript by tasks.registering(GenerateTypescriptTask::class) { // } //} -val schemaTsDistributionName : Provider = providers.provider { +val schemaTsDistributionName: Provider = providers.provider { "${rootProject.name}-${project.name}" } -val generateTypescriptOutputFiles: Provider = generateTypescript.map { it.outputs.files.asFileTree } +val generateTypescriptOutputFiles: Provider = + generateTypescript.map { it.outputs.files.asFileTree } val schemaTs by distributions.registering { distributionBaseName.set(schemaTsDistributionName) From 0c6f2a4bfee44db855373de2371b8731badc0be5 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 19 Jun 2022 10:23:11 +0200 Subject: [PATCH 378/629] refactor websocket/tile server --- modules/events-server/.gitignore | 1 + .../processor/KafkatorioTopology.kt | 103 +++++++----- .../kafkatorio/processor/WebsocketServer.kt | 93 ----------- .../processor/admin/KafkatorioKafkaAdmin.kt | 17 +- .../processor/config/ApplicationProperties.kt | 144 ++++++++++------- .../kafkatorio/processor/config/Lenses.kt | 73 ++++----- .../processor/config/environmentExt.kt | 148 +++++++++--------- .../kafkatorio/processor/eventProcessor.kt | 62 +++++--- .../processor/misc/FileEventsFlow.kt | 2 - .../processor/tileserver/WebMapTileServer.kt | 100 +++--------- .../processor/tileserver/WebServer.kt | 16 ++ .../processor/tileserver/WebsocketServer.kt | 148 ++++++++++++++++++ .../topology/factorioServerPackets.kt | 5 +- .../processor/topology/playerUpdates.kt | 57 +++++-- .../src/main/resources/.gitignore | 1 - 15 files changed, 556 insertions(+), 414 deletions(-) delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebServer.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebsocketServer.kt delete mode 100644 modules/events-server/src/main/resources/.gitignore diff --git a/modules/events-server/.gitignore b/modules/events-server/.gitignore index e7abcfb..fe98be7 100644 --- a/modules/events-server/.gitignore +++ b/modules/events-server/.gitignore @@ -1 +1,2 @@ kafka-state/ +kafkatorio-tiles/ diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 179863e..8da6383 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -1,23 +1,26 @@ package dev.adamko.kafkatorio.processor import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.processor.tileserver.WebsocketServer +import dev.adamko.kafkatorio.processor.topology.broadcastToWebsocket import dev.adamko.kafkatorio.processor.topology.colourMapChunks import dev.adamko.kafkatorio.processor.topology.factorioServerPacketStream -import dev.adamko.kafkatorio.processor.topology.broadcastToWebsocket import dev.adamko.kafkatorio.processor.topology.saveMapTiles import dev.adamko.kafkatorio.processor.topology.splitFactorioServerPacketStream -import java.time.Duration import java.util.Properties -import kotlin.coroutines.CoroutineContext -import kotlin.coroutines.cancellation.CancellationException +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException import kotlin.io.path.Path +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.cancelChildren +import kotlinx.coroutines.cancel +import kotlinx.coroutines.currentCoroutineContext import kotlinx.coroutines.job import kotlinx.coroutines.launch +import kotlinx.coroutines.suspendCancellableCoroutine +import org.apache.kafka.clients.producer.ProducerConfig import org.apache.kafka.streams.KafkaStreams import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.StreamsConfig @@ -27,13 +30,12 @@ import org.apache.kafka.streams.TopologyDescription internal class KafkatorioTopology( private val websocketServer: WebsocketServer, - private val appProps: ApplicationProperties = ApplicationProperties(), -) : CoroutineScope { + private val appProps: ApplicationProperties, +) { - override val coroutineContext: CoroutineContext = - Dispatchers.Default + rootJob + CoroutineName("KafkatorioTopology") + private val builderScope = CoroutineScope(CoroutineName("KafkaTopology")) - fun start() { + suspend fun start() = builderScope.launch { splitPackets() groupTilesMapChunks() @@ -42,7 +44,7 @@ internal class KafkatorioTopology( websocketBroadcaster() } - private fun splitPackets() { + private suspend fun splitPackets() { val builder = StreamsBuilder() val packets = factorioServerPacketStream(builder) splitFactorioServerPacketStream(packets) @@ -52,45 +54,77 @@ internal class KafkatorioTopology( launchTopology("splitPackets", topology) } - private fun groupTilesMapChunks() { + private suspend fun groupTilesMapChunks() { val builder = StreamsBuilder() val topology = colourMapChunks(builder) launchTopology("groupTilesMapChunks", topology) } - private fun saveTiles() { + private suspend fun saveTiles() { val builder = StreamsBuilder() - val topology = saveMapTiles(builder, appProps.webmapTileDir) + val topology = saveMapTiles(builder, appProps.tileDir) launchTopology("saveTiles", topology) } - private fun websocketBroadcaster() { + private suspend fun websocketBroadcaster() { val builder = StreamsBuilder() broadcastToWebsocket(websocketServer, builder) val topology = builder.build() - launchTopology("websocketBroadcaster", topology) + launchTopology( + "websocketBroadcaster", topology, mapOf( + StreamsConfig.COMMIT_INTERVAL_MS_CONFIG to "${1.seconds.inWholeMilliseconds}", + StreamsConfig.producerPrefix(ProducerConfig.LINGER_MS_CONFIG) to "${10.milliseconds.inWholeMilliseconds}" + ) + ) } - private fun launchTopology( + private suspend fun launchTopology( id: String, topology: Topology, - config: Map = mapOf(), + additionalProperties: Map = mapOf(), ) { - val props: Properties = appProps.kafkaConfig + val props: Properties = appProps.kafkaStreamsConfig.toProperties() - config.forEach { (k, v) -> props.setProperty(k, v) } + additionalProperties.forEach { (k, v) -> props.setProperty(k, v) } - val appId = props.compute(StreamsConfig.APPLICATION_ID_CONFIG) { _, v -> "$v.$id" } as? String + val appId = props.compute(StreamsConfig.APPLICATION_ID_CONFIG) { _, v -> "$v.$id" } as String props.setProperty(StreamsConfig.APPLICATION_ID_CONFIG, appId) - val streams = KafkaStreams(topology, props) - streams.setUncaughtExceptionHandler(StreamsExceptionHandler { - coroutineContext.job.cancel(CancellationException(cause = it)) - }) + builderScope.launch(CoroutineName(appId)) { + val streamsState: KafkaStreams.State = suspendCancellableCoroutine { cont -> + + val streams = KafkaStreams(topology, props) + streams.setUncaughtExceptionHandler(StreamsExceptionHandler { e -> + cont.resumeWithException(e) + }) + + streams.setStateListener { newState: KafkaStreams.State, _ -> + when (newState) { + KafkaStreams.State.NOT_RUNNING, + KafkaStreams.State.ERROR -> cont.resume(newState) + else -> Unit // do nothing + } + } + + cont.invokeOnCancellation { + println("[$appId] coroutine cancelled -> closing. cause:$it") + streams.close() + } + + printTopologyDescription(appId, topology) + streams.start() + println("launched Topology $appId") + } + println("exiting Topology $appId: $streamsState") + currentCoroutineContext().job.cancel("$appId: $streamsState") + } + } + + private fun printTopologyDescription(appId: String, topology: Topology) { val description: TopologyDescription = topology.describe() val descFile = Path("./build/$appId.txt").toFile().apply { @@ -107,19 +141,12 @@ internal class KafkatorioTopology( |---------------- """.trimMargin() ) - - coroutineContext.job.invokeOnCompletion { - println("closing $id KafkaStreams") - rootJob.cancelChildren() - rootJob.cancel() - streams.close(Duration.ofSeconds(1)) - } - - launch { streams.start() } } companion object { - val rootJob = SupervisorJob() + private fun Map.toProperties(): Properties = + entries.fold(Properties()) { props, (k, v) -> + props.apply { setProperty(k, v) } + } } - } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt deleted file mode 100644 index aa03266..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/WebsocketServer.kt +++ /dev/null @@ -1,93 +0,0 @@ -package dev.adamko.kafkatorio.processor - -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.withIndex -import kotlinx.coroutines.job -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.supervisorScope -import org.http4k.routing.bind -import org.http4k.routing.websockets -import org.http4k.websocket.Websocket -import org.http4k.websocket.WsHandler -import org.http4k.websocket.WsMessage -import org.http4k.websocket.WsStatus - - -class WebsocketServer { - - // create a scope+job for the server - private val serverJob = KafkatorioTopology.rootJob - private val serverScope = CoroutineScope(serverJob) - - private val clients: MutableSharedFlow = MutableSharedFlow( - replay = 100, - extraBufferCapacity = 100, - BufferOverflow.DROP_OLDEST, - ) - - private val messages: MutableSharedFlow = MutableSharedFlow( - replay = 100, - extraBufferCapacity = 100, - BufferOverflow.DROP_OLDEST, - ) - - private fun bindClient(ws: Websocket) = runBlocking(serverScope.coroutineContext) { - clients.emit(ws) - } - - fun sendMessage(msg: String) = runBlocking(serverScope.coroutineContext) { - messages.emit(msg) - } - - suspend fun build(): WsHandler = supervisorScope builder@{ - - coroutineContext.job.invokeOnCompletion { e -> - e?.let { serverJob.completeExceptionally(it) } ?: serverJob.complete() - } - - clients - .withIndex() - .onEach { (id, ws) -> - // create a scope+job for each client - val clientJob = SupervisorJob(serverJob) - val clientScope = CoroutineScope(clientJob) - - clientJob.invokeOnCompletion { e -> - println("[clientJob.invokeOnCompletion] closing client ws $e") - when (e) { - null -> ws.close(WsStatus.NORMAL) - else -> ws.close(WsStatus.ABNORMAL_CLOSE) - } - } - - ws.onError { e -> - sendMessage("[ws.onError] client $id error [${e}]") - clientJob.completeExceptionally(e) - } - ws.onClose { status -> - sendMessage("[ws.onClose] client $id disconnected [${status}]") - clientJob.complete() - } - ws.onMessage { wsMsg -> - sendMessage("$id says: ${wsMsg.bodyString()}") - } - - sendMessage("new client $id!") - - messages - .onEach { msg -> ws.send(WsMessage(msg)) } - .launchIn(clientScope) - - } - .launchIn(serverScope) - - - return@builder websockets("/ws" bind ::bindClient) - - } -} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt index b0fbb20..02471bb 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.processor.admin +import dev.adamko.kafkatorio.processor.config.ApplicationProperties import java.util.concurrent.TimeUnit import mu.KotlinLogging import org.apache.kafka.clients.admin.Admin @@ -8,17 +9,17 @@ import org.apache.kafka.clients.admin.NewTopic import org.apache.kafka.clients.admin.TopicListing -object KafkatorioKafkaAdmin { +class KafkatorioKafkaAdmin( + appProps: ApplicationProperties +) { private val logger = KotlinLogging.logger {} - private val kafkaAdmin: Admin = - Admin.create( - mapOf( - "bootstrap.servers" to "http://localhost:9092", - "client.id" to "kafkatorio.setup-admin", - ) - ) + init { + println("Creating KafkatorioKafkaAdmin with config: ${appProps.kafkaAdminConfig}") + } + + private val kafkaAdmin: Admin = Admin.create(appProps.kafkaAdminConfig) fun createKafkatorioTopics() { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt index e9ec6e3..6881ecb 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt @@ -1,64 +1,94 @@ package dev.adamko.kafkatorio.processor.config -import dev.adamko.kafkatorio.processor.config.PortVal.Companion.portVal +import com.sksamuel.hoplite.ConfigLoaderBuilder +import com.sksamuel.hoplite.addEnvironmentSource +import com.sksamuel.hoplite.addResourceOrFileSource import java.nio.file.Path -import java.time.Clock -import java.util.Properties -import kotlin.io.path.Path -import org.http4k.cloudnative.env.Environment -import org.http4k.cloudnative.env.EnvironmentKey -import org.http4k.lens.nonEmptyString -/** - * Load properties, in descending priority order, from - * - * 1. Environment variables - * 2. This app's env file (as defined by the environment variable [Lenses.APPLICATION_PROPERTIES_FILE_PATH]) - * # 3. A resources-dir yaml file - * - */ -internal class ApplicationProperties( - vararg environments: Environment = arrayOf( - Environment.env(), - Environment.fromEnvVarPath(), - Environment.fromResourcesFile(".secret.config.yml") - ) + +// loaded by hoplite +data class ApplicationProperties( + val webPort: PortVal, + val tileDir: Path, + val kafkaAdminConfig: Map, + val kafkaStreamsConfig: Map, ) { - - private val appProps: Environment = - environments.reduce { acc, environment -> acc.overrides(environment) } - - - fun clock(): Clock = Clock.systemUTC() - - - /** - * The port of the server - * - * Set by GCP ([docs](https://cloud.google.com/run/docs/reference/container-contract#env-vars)). - */ - val serverPort: PortVal - get() = EnvironmentKey.portVal().defaulted("PORT", PortVal.DEFAULT)[appProps] - - - val kafkaConfig: Properties - get() = EnvironmentKey - .nonEmptyString() - .map { srcString -> - srcString.reader().use { stringReader -> - Properties().also { properties -> - properties.load(stringReader) - } - } - } - .required("kafka.config")[appProps] - - - val webmapTileDir: Path - get() = EnvironmentKey - .nonEmptyString() - .map(::Path) - .required("tileServer.webmapTileDir")[appProps] - + companion object { + /** use Hoplite to load config from environment variables or properties files */ + fun load(): ApplicationProperties = + ConfigLoaderBuilder.default() + .addDefaults() + .allowUnresolvedSubstitutions() + .allowEmptyTree() + .addEnvironmentSource() + .addResourceOrFileSource("/.secret.config.yml", optional = true) + .addResourceOrFileSource("/config.yml", optional = false) + .build() + .loadConfigOrThrow() + } } + + +//import dev.adamko.kafkatorio.processor.config.PortVal.Companion.portVal +//import java.nio.file.Path +//import java.time.Clock +//import java.util.Properties +//import kotlin.io.path.Path +//import org.http4k.cloudnative.env.Environment +//import org.http4k.cloudnative.env.EnvironmentKey +//import org.http4k.lens.nonEmptyString +// +///** +// * Load properties, in descending priority order, from +// * +// * 1. Environment variables +// * 2. This app's env file (as defined by the environment variable [Lenses.APPLICATION_PROPERTIES_FILE_PATH]) +// * # 3. A resources-dir yaml file +// * +// */ +//internal class ApplicationProperties( +// vararg environments: Environment = arrayOf( +// Environment.env(), +// Environment.fromEnvVarPath(), +// Environment.fromResourcesFile(".secret.config.yml") +// ) +//) { +// +// +// private val appProps: Environment = +// environments.reduce { acc, environment -> acc.overrides(environment) } +// +// +// fun clock(): Clock = Clock.systemUTC() +// +// +// /** +// * The port of the server +// * +// * Set by GCP ([docs](https://cloud.google.com/run/docs/reference/container-contract#env-vars)). +// */ +// val serverPort: PortVal +// get() = EnvironmentKey.portVal().defaulted("PORT", PortVal.DEFAULT)[appProps] +// +// +// val kafkaConfig: Properties +// get() = EnvironmentKey +// .nonEmptyString() +// .map { srcString -> +// srcString.reader().use { stringReader -> +// Properties().also { properties -> +// properties.load(stringReader) +// } +// } +// } +// .required("kafka.config")[appProps] +// +// +// val webmapTileDir: Path +// get() = EnvironmentKey +// .nonEmptyString() +// .map(::Path) +// .required("tileServer.webmapTileDir")[appProps] +// +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt index fec46a8..7faeb9c 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt @@ -1,38 +1,39 @@ package dev.adamko.kafkatorio.processor.config -import java.io.File -import org.http4k.cloudnative.env.Environment -import org.http4k.cloudnative.env.EnvironmentKey -import org.http4k.core.Credentials -import org.http4k.lens.BiDiLens -import org.http4k.lens.BiDiMapping - - -internal object Lenses { - - /** The location of this app's env file. */ - val APPLICATION_PROPERTIES_FILE_PATH: BiDiLens = - EnvironmentKey - .map( - { path: String -> File(path) }, - { file: File -> file.canonicalPath }, - ) - .optional("APPLICATION_PROPERTIES_FILE_PATH") - - /** Bidirectional [String] and [Credentials] mapper. */ - val credentialsLens: BiDiMapping = run { - val separator = ":" - BiDiMapping( - // from String to Credentials - { property -> - property.split(separator, limit = 2) - .takeIf { it.size == 2 } - ?.let { (user, pass) -> Credentials(user, pass) } - ?: throw IllegalArgumentException("Credentials are invalid") - }, - // from Credentials to String - { it.user + separator + it.password } - ) - } - -} +//import java.io.File +//import org.http4k.cloudnative.env.Environment +//import org.http4k.cloudnative.env.EnvironmentKey +//import org.http4k.core.Credentials +//import org.http4k.lens.BiDiLens +//import org.http4k.lens.BiDiMapping +// +// +//internal object Lenses { +// +// /** The location of this app's env file. */ +// val APPLICATION_PROPERTIES_FILE_PATH: BiDiLens = +// EnvironmentKey +// .map( +// { path: String -> File(path) }, +// { file: File -> file.canonicalPath }, +// ) +// .optional("APPLICATION_PROPERTIES_FILE_PATH") +// +// +// /** Bidirectional [String] and [Credentials] mapper. */ +// val credentialsLens: BiDiMapping = run { +// val separator = ":" +// BiDiMapping( +// // from String to Credentials +// { property -> +// property.split(separator, limit = 2) +// .takeIf { it.size == 2 } +// ?.let { (user, pass) -> Credentials(user, pass) } +// ?: throw IllegalArgumentException("Credentials are invalid") +// }, +// // from Credentials to String +// { it.user + separator + it.password } +// ) +// } +// +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt index 4bfeec7..3ff3eee 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt @@ -1,74 +1,78 @@ package dev.adamko.kafkatorio.processor.config -import java.io.File -import java.io.FileNotFoundException -import org.http4k.cloudnative.env.Environment -import org.http4k.cloudnative.env.MapEnvironment -import org.http4k.cloudnative.env.fromYaml -import org.http4k.lens.Lens - - -/** - * Load properties from either a `.yaml` or `.env` file. - * - * (An improved version of [Environment.fromResource]) - */ -fun Environment.Companion.fromResourcesFile( - resource: String, - default: Environment = EMPTY -): Environment { - return try { - val file = - this::class.java - .getResource("/${resource.removePrefix("/")}") - ?.file - ?.let { File(it) } - fromFile(file, default) - } catch (e: FileNotFoundException) { - default - } -} - -/** - * Try fetching a properties file the location provided by the - * [`JVM`][jvmProperties] or [`System`][env] environment variable - * [Lenses.APPLICATION_PROPERTIES_FILE_PATH], if it exists. - * - * If it does not exist, return [default]. - */ -fun Environment.Companion.fromEnvVarPath( - location: Lens = Lenses.APPLICATION_PROPERTIES_FILE_PATH, - default: Environment = EMPTY, -): Environment { - val file = (jvmProperties() overrides env())[location] - - return fromFile(file, default) -} - -/** - * Load properties from either a `.yaml` or `.env` file. - * - * (An improved version of [Environment.from]) - */ -internal fun Environment.Companion.fromFile( - file: File?, - default: Environment = EMPTY, -): Environment { - return file - ?.takeIf { it.isFile } - .let { - when (it?.extension) { - "yml", "yaml" -> fromYaml(it) - "env" -> from(it) - else -> default - } - } -} - -/** The same as [Environment.ENV], but refreshes on each invocation (which is useful for testing). */ -fun Environment.Companion.env(): Environment = - MapEnvironment.from(System.getenv().toProperties()) - -/** The same as [Environment.JVM_PROPERTIES], but refreshes on each invocation (which is useful for testing). */ -internal fun Environment.Companion.jvmProperties(): Environment = - MapEnvironment.from(System.getProperties()) +//import java.io.File +//import java.io.FileNotFoundException +//import org.http4k.cloudnative.env.Environment +//import org.http4k.cloudnative.env.MapEnvironment +//import org.http4k.cloudnative.env.fromYaml +//import org.http4k.lens.Lens +// +// +///** +// * Load properties from either a `.yaml` or `.env` file. +// * +// * (An improved version of [Environment.fromResource]) +// */ +//fun Environment.Companion.fromResourcesFile( +// resource: String, +// default: Environment = EMPTY +//): Environment { +// return try { +// val file = +// this::class.java +// .getResource("/${resource.removePrefix("/")}") +// ?.file +// ?.let { File(it) } +// fromFile(file, default) +// } catch (e: FileNotFoundException) { +// default +// } +//} +// +// +///** +// * Try fetching a properties file the location provided by the +// * [`JVM`][jvmProperties] or [`System`][env] environment variable +// * [Lenses.APPLICATION_PROPERTIES_FILE_PATH], if it exists. +// * +// * If it does not exist, return [default]. +// */ +//fun Environment.Companion.fromEnvVarPath( +// location: Lens = Lenses.APPLICATION_PROPERTIES_FILE_PATH, +// default: Environment = EMPTY, +//): Environment { +// val file = (jvmProperties() overrides env())[location] +// +// return fromFile(file, default) +//} +// +// +///** +// * Load properties from either a `.yaml` or `.env` file. +// * +// * (An improved version of [Environment.from]) +// */ +//internal fun Environment.Companion.fromFile( +// file: File?, +// default: Environment = EMPTY, +//): Environment { +// return file +// ?.takeIf { it.isFile } +// .let { +// when (it?.extension) { +// "yml", "yaml" -> fromYaml(it) +// "env" -> from(it) +// else -> default +// } +// } +//} +// +// +///** The same as [Environment.ENV], but refreshes on each invocation (which is useful for testing). */ +//fun Environment.Companion.env(): Environment = +// MapEnvironment.from(System.getenv().toProperties()) +// +// +///** The same as [Environment.JVM_PROPERTIES], but refreshes on each invocation (which is useful for testing). */ +//internal fun Environment.Companion.jvmProperties(): Environment = +// MapEnvironment.from(System.getProperties()) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt index 8d9c6e2..3eceec0 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -2,33 +2,57 @@ package dev.adamko.kafkatorio.processor import dev.adamko.kafkatorio.processor.admin.KafkatorioKafkaAdmin +import dev.adamko.kafkatorio.processor.config.ApplicationProperties import dev.adamko.kafkatorio.processor.tileserver.WebMapTileServer -import kotlinx.coroutines.runBlocking -import org.http4k.server.PolyHandler -import org.http4k.server.Undertow -import org.http4k.server.asServer +import dev.adamko.kafkatorio.processor.tileserver.WebsocketServer +import dev.adamko.kafkatorio.processor.tileserver.webServer +import kotlinx.coroutines.awaitCancellation +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.currentCoroutineContext +import kotlinx.coroutines.job +import kotlinx.coroutines.launch +import kotlinx.serialization.Serializable +import org.http4k.server.Http4kServer -fun main(): Unit = runBlocking { +suspend fun main() { - KafkatorioKafkaAdmin.createKafkatorioTopics() + val appProps = ApplicationProperties.load() + + val admin = KafkatorioKafkaAdmin(appProps) + admin.createKafkatorioTopics() val wsServer = WebsocketServer() - val tileServer = WebMapTileServer() + val tileServer = WebMapTileServer(appProps) - val topology = KafkatorioTopology(wsServer) - topology.start() + coroutineScope { + launch { + val topology = KafkatorioTopology(wsServer, appProps) + topology.start() - val webServer = PolyHandler( - tileServer.build(), - wsServer.build(), - ).asServer(Undertow(9073)) + println("launched KafkatorioTopology") - Runtime.getRuntime().addShutdownHook(Thread { - webServer.stop() - }) -// launch { - webServer.start().block() -// } + awaitCancellation() + } + launch { + val webServer: Http4kServer = webServer(tileServer, wsServer, appProps) + + currentCoroutineContext().job.invokeOnCompletion { + println("webserver stopping. Cause: $it") + webServer.stop() + } + + webServer.start() + println("launched webserver port:${webServer.port()}") + + awaitCancellation() + } + } } +// Runtime.getRuntime().addShutdownHook(Thread { +// webServer.stop() +// }) +// launch { +// } +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/FileEventsFlow.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/FileEventsFlow.kt index 6b467d3..05b79c1 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/FileEventsFlow.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/FileEventsFlow.kt @@ -1,6 +1,5 @@ package dev.adamko.kafkatorio.processor.misc -import dev.adamko.kafkatorio.processor.KafkatorioTopology import java.io.File import java.nio.file.FileSystems import java.nio.file.Files @@ -56,7 +55,6 @@ class FileEventsFlow private constructor( override val coroutineContext: CoroutineContext = CoroutineName("FileEventsFlow") + - KafkatorioTopology.rootJob + Dispatchers.Unconfined + CoroutineExceptionHandler { _, e -> println("handling exception in FileEventsFlow") diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt index 0519684..a599cef 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt @@ -18,18 +18,17 @@ import org.http4k.routing.routes import org.http4k.routing.static internal class WebMapTileServer( - appProps: ApplicationProperties = ApplicationProperties() + appProps: ApplicationProperties ) { - private val tilesLoader = ResourceLoader.Directory(appProps.webmapTileDir.absolutePathString()) + private val tilesLoader = ResourceLoader.Directory(appProps.tileDir.toFile().canonicalPath) private val filters = listOf( - ETagChecker()(), + ETagChecker(), ).reduce(Filter::then) private val routes: RoutingHttpHandler = routes( - "/tiles" bind GET to - static(tilesLoader).withFilter(filters) + "/tiles" bind GET to static(tilesLoader).withFilter(filters) ) fun build(): HttpHandler { @@ -37,87 +36,40 @@ internal class WebMapTileServer( } - inner class ETagChecker -// : CoroutineScope - { + private class ETagChecker : Filter { -// private val tagState: MutableStateFlow> = -// MutableStateFlow(mutableMapOf()) -// -// override val coroutineContext: CoroutineContext = -// CoroutineName("ETagChecker") + -// Dispatchers.Unconfined + -// KafkatorioTopology.rootJob + override fun invoke(next: HttpHandler): HttpHandler = { request: Request -> + val requestedETag = request.header("If-None-Match") -// init { -// launch { -// appProps.webmapTileDir -// .fileEventsFlow() -// .filterIsInstance() -// .filter { it.path.isRegularFile() } -//// .filter { it.path.extension == "png" } -// .runningFold(mutableMapOf()) { tags, event -> -//// println("[WebMapTileServer] handling file update ${event.path}") -// -// val relativePath = event.path -// .relativeTo(appProps.webmapTileDir) -// .invariantSeparatorsPathString -// -// when (event) { -// is KWatchEvent.Deleted -> tags.remove(relativePath) -// is KWatchEvent.Created, -// is KWatchEvent.Modified -> { -// val md5 = event.path.md5() -// if (md5 != null) { -// tags[relativePath] = md5 -// } else { -// println("null md5 for ${event.path}") -// } -// } -// } -// -// tags -// }.cancellable() -// .collect(tagState) -// } -// } + var response = next(request) + val responseBytes = response.body.stream.use { it.readAllBytes() } + val currentETag = responseBytes.md5() + response = response.body(MemoryBody(responseBytes)) - private val Request.etagKey: String get() = uri.path.removePrefix("/tiles/") - - - operator fun invoke() = Filter { next -> - { request -> - val requestedETag = request.header("If-None-Match") - - var response = next(request) - val responseBytes = response.body.stream.use { it.readAllBytes() } - val currentETag = responseBytes.md5() - - response = response.body(MemoryBody(responseBytes)) - - when { - currentETag == null -> { + when { + currentETag == null -> { // println("[${request.etagKey}] currentETag is null (requested: $requestedETag), executing request") - response - .header("Cache-Control", "no-cache, max-age=0, must-revalidate") - } - requestedETag == currentETag -> { + response + .header("Cache-Control", "no-cache, max-age=0, must-revalidate") + } + requestedETag == currentETag -> { // println("[${request.etagKey}] currentETag == requested, returning 304 $requestedETag") - Response(Status.NOT_MODIFIED) - .header("Cache-Control", "no-cache, max-age=0, must-revalidate") - } - else -> { + Response(Status.NOT_MODIFIED) + .header("Cache-Control", "no-cache, max-age=0, must-revalidate") + } + else -> { // println("[${request.etagKey}] currentETag != requested, executing request and adding currentETag:$currentETag (requested:$requestedETag)") - response - .header("ETag", currentETag) + response + .header("ETag", currentETag) // .header("Cache-Control", "no-store") - .header("Cache-Control", "no-cache, max-age=0, must-revalidate") - } + .header("Cache-Control", "no-cache, max-age=0, must-revalidate") } } } + } + companion object { private fun ByteArray.md5(): String? { return if (isEmpty()) { null diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebServer.kt new file mode 100644 index 0000000..e3f5f4c --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebServer.kt @@ -0,0 +1,16 @@ +package dev.adamko.kafkatorio.processor.tileserver + +import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import org.http4k.server.Http4kServer +import org.http4k.server.PolyHandler +import org.http4k.server.Undertow +import org.http4k.server.asServer + +internal suspend fun webServer( + tileServer: WebMapTileServer, + wsServer: WebsocketServer, + appProps: ApplicationProperties, +): Http4kServer = PolyHandler( + tileServer.build(), + wsServer.build(), +).asServer(Undertow(appProps.webPort())) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebsocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebsocketServer.kt new file mode 100644 index 0000000..47ca3de --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebsocketServer.kt @@ -0,0 +1,148 @@ +package dev.adamko.kafkatorio.processor.tileserver + +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.time.Duration.Companion.seconds +import kotlin.time.TimeSource +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.withIndex +import kotlinx.coroutines.isActive +import kotlinx.coroutines.job +import kotlinx.coroutines.launch +import kotlinx.coroutines.supervisorScope +import kotlinx.coroutines.suspendCancellableCoroutine +import org.http4k.routing.bind +import org.http4k.routing.websockets +import org.http4k.websocket.Websocket +import org.http4k.websocket.WsHandler +import org.http4k.websocket.WsMessage +import org.http4k.websocket.WsStatus + + +class WebsocketServer { + + private val serverScope = CoroutineScope( + CoroutineName("WsServer") + + Dispatchers.IO + + SupervisorJob() + + CoroutineExceptionHandler { _, e -> + println("[ws.WsServer] handling exception ${e.message}") + } + ) + + + private val clients: MutableSharedFlow = MutableSharedFlow( + replay = 100, + extraBufferCapacity = 100, + BufferOverflow.DROP_OLDEST, + ) + + + private val messages: MutableSharedFlow = MutableSharedFlow( + replay = 100, + extraBufferCapacity = 100, + BufferOverflow.DROP_OLDEST, + ) + + + private fun bindClient(ws: Websocket) = serverScope.launch { + println("[ws.bindClient] ${ws.upgradeRequest.toMessage()}") + clients.emit(ws) + } + + + fun sendMessage(msg: String) = serverScope.launch { + println("[ws.sendMessage] $msg") + messages.emit(msg) + } + + + fun build(): WsHandler { + val startTime = TimeSource.Monotonic.markNow() + + serverScope.launch { + supervisorScope { + clients + .withIndex() + .onEach { (id, ws) -> + createClient(id, ws) + }.launchIn(serverScope) + } + } + + serverScope.launch { + while (isActive) { + delay(10.seconds) + sendMessage("elapsed ${startTime.elapsedNow()}") + } + } + + return websockets( + "/ws/foo" bind { ws: Websocket -> + serverScope.launch { bindClient(ws) } + } + ) + } + + + private fun createClient(id: Int, ws: Websocket) { + val clientJob = SupervisorJob(serverScope.coroutineContext.job) + + serverScope.launch(CoroutineName("ws-client-$id") + clientJob) { +// return serverScope.launch(CoroutineName("ws-client-$id")) { +// supervisorScope { + launch { + + suspendCancellableCoroutine { cont -> + println("[ws-client] entering suspendCancellableCoroutine") + + cont.invokeOnCancellation { e: Throwable? -> + launch { sendMessage("[ws-client.invokeOnCompletion] closing client ws ${e?.message}") } + when (e) { + null -> ws.close(WsStatus.NORMAL) + else -> ws.close(WsStatus.ABNORMAL_CLOSE) + } + } + + ws.onError { e: Throwable -> + launch { sendMessage("[ws-client.onError] client $id error [${e.message}]") } + if (!cont.isCompleted) { + cont.resumeWithException(e) + } + } + + ws.onClose { status: WsStatus -> + launch { sendMessage("[ws-client.onClose] client $id disconnected [${status}]") } + if (!cont.isCompleted) { + cont.resume(status) + } + } + + ws.onMessage { wsMsg -> + launch { sendMessage("$id says: ${wsMsg.bodyString()}") } + } + } + } + + println("[ws-client] $id listening to messages") + messages + .onEach { msg -> + println("[ws-client] sending message to $id") + ws.send(WsMessage(msg)) + } + .launchIn(this) + } + + +// } + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt index df4423e..f19cfc5 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt @@ -6,6 +6,8 @@ import dev.adamko.kafkatorio.processor.admin.topicName import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket +import dev.adamko.kotka.extensions.component1 +import dev.adamko.kotka.extensions.component2 import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.streams.map @@ -15,7 +17,6 @@ import kotlinx.serialization.decodeFromString import org.apache.kafka.common.serialization.Serdes import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.kstream.KStream -import org.apache.kafka.streams.processor.RecordContext fun factorioServerPacketStream( @@ -46,7 +47,7 @@ fun splitFactorioServerPacketStream( jsonMapper.serde(), jsonMapper.serde(), ) - ) { _: FactorioServerId, value: KafkatorioPacket, _: RecordContext -> + ) { (_: FactorioServerId, value: KafkatorioPacket) -> // println("[$key] sending event:${value.eventType} to topic:${value.data.objectName()}") value.data.topicName } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt index 968a924..d80cb71 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt @@ -1,18 +1,22 @@ package dev.adamko.kafkatorio.processor.topology -import dev.adamko.kafkatorio.processor.WebsocketServer import dev.adamko.kafkatorio.processor.admin.TOPIC_BROADCAST_TO_WEBSOCKET import dev.adamko.kafkatorio.processor.admin.topicName +import dev.adamko.kafkatorio.processor.tileserver.WebsocketServer import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio import dev.adamko.kafkatorio.schema.packets.EventServerPacket import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.PlayerUpdate +import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate import dev.adamko.kotka.extensions.consumedAs import dev.adamko.kotka.extensions.producedAs +import dev.adamko.kotka.extensions.stream import dev.adamko.kotka.extensions.streams.forEach import dev.adamko.kotka.extensions.streams.map +import dev.adamko.kotka.extensions.streams.to import dev.adamko.kotka.kxs.serde +import kotlinx.coroutines.runBlocking import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import org.apache.kafka.streams.StreamsBuilder @@ -32,7 +36,7 @@ fun broadcastToWebsocket( builder: StreamsBuilder = StreamsBuilder(), ) { - builder.preparePlayerUpdatesBroadcast() + builder.broadcastKafkatorioPackets() builder.stream( TOPIC_BROADCAST_TO_WEBSOCKET, @@ -40,25 +44,54 @@ fun broadcastToWebsocket( ).forEach( "$pid.websocket-server.send-message" ) { _, esPacket -> - websocketServer.sendMessage(jsonMapper.encodeToString(esPacket)) + runBlocking { + websocketServer.sendMessage(jsonMapper.encodeToString(esPacket)) + } } } -private fun StreamsBuilder.preparePlayerUpdatesBroadcast() { - stream( +private fun StreamsBuilder.broadcastKafkatorioPackets() { + val playerUpdatesStream = stream( + consumedAs( + "$pid.player-updates", + jsonMapper.serde(FactorioServerId.serializer()), + jsonMapper.serde(KafkatorioPacket.serializer()), + ), PlayerUpdate::class.topicName, - consumedAs("$pid.player-updates", jsonMapper.serde(), jsonMapper.serde()), - ).map( - "$pid.player-updates.convert" - ) { serverId, playerPacket -> - serverId to EventServerPacket.Kafkatorio(playerPacket) + SurfaceUpdate::class.topicName, + ) + + playerUpdatesStream.map( + "$pid.packet-updates.convert" + ) { serverId, packet -> + serverId to EventServerPacket.Kafkatorio(packet) + }.to( + producedAs( + "$pid.event-server-packets.produce", + jsonMapper.serde(FactorioServerId.serializer()), + jsonMapper.serde(EventServerPacket.serializer()), + ) + ) { TOPIC_BROADCAST_TO_WEBSOCKET } +} + + +private fun StreamsBuilder.prepareServerUpdateBroadcast() { + + val surfaceUpdatesStream = stream( + SurfaceUpdate::class.topicName, + consumedAs("$pid.surface-updates", jsonMapper.serde(), jsonMapper.serde()), + ) + + surfaceUpdatesStream.map( + "$pid.surface-updates.convert" + ) { serverId, serverUpdatePacket -> + serverId to EventServerPacket.Kafkatorio(serverUpdatePacket) }.to( - TOPIC_BROADCAST_TO_WEBSOCKET, producedAs( "$pid.player-updates.stream", jsonMapper.serde(FactorioServerId.serializer()), jsonMapper.serde(EventServerPacket.serializer()), ) - ) + ) { TOPIC_BROADCAST_TO_WEBSOCKET } } diff --git a/modules/events-server/src/main/resources/.gitignore b/modules/events-server/src/main/resources/.gitignore deleted file mode 100644 index 46d00ec..0000000 --- a/modules/events-server/src/main/resources/.gitignore +++ /dev/null @@ -1 +0,0 @@ -kafkatorio-web-map/** From 723ff444626d2c609ffff56d18e7ee9dc5df1513 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 19 Jun 2022 10:31:38 +0200 Subject: [PATCH 379/629] exclude .secret prefixed files from archives --- .../src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts index 202f788..b66ec22 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts @@ -17,6 +17,7 @@ tasks.withType().configureEach { comment = " Do not edit manually. This file was created with task '$name'" } + val hardReset by tasks.registering(Delete::class) { group = rootProject.name doFirst("hardResetConfirmation") { @@ -28,3 +29,8 @@ val hardReset by tasks.registering(Delete::class) { } } } + + +tasks.withType().configureEach { + exclude("**/.secret.*") +} From 487d1a91f5423fa67bb672b8fa9d8a9b59199d2a Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 19 Jun 2022 10:32:07 +0200 Subject: [PATCH 380/629] re-gen kafkatorio-schema.ts (no real change, just alphabetically ordered) --- .../kafkatorio-schema/kafkatorio-schema.ts | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts index 1037ced..ae19634 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts @@ -192,18 +192,8 @@ export type FactorioPrototype = export namespace FactorioPrototype { export enum Type { - MapTile = "kafkatorio.prototype.MapTile", Entity = "kafkatorio.prototype.Entity", - } - - export interface MapTile { - type: FactorioPrototype.Type.MapTile; - name: PrototypeName; - mapColour: Colour; - layer: UInt; - collisionMasks: List; - order: string; - canBeMined: boolean; + MapTile = "kafkatorio.prototype.MapTile", } export interface Entity { @@ -219,6 +209,16 @@ export namespace FactorioPrototype { isMilitaryTarget: boolean; miningProperties: MiningProperties; } + + export interface MapTile { + type: FactorioPrototype.Type.MapTile; + name: PrototypeName; + mapColour: Colour; + layer: UInt; + collisionMasks: List; + order: string; + canBeMined: boolean; + } } export type EventName = string; @@ -230,13 +230,13 @@ export type MapChunkPosition = [ y: Int, ]; -export type List = any; - export interface MiningProperties { canBeMined: boolean; products: MinedProduct[] | null; } +export type List = any; + export type PrototypeKey = Int; export interface MinedProduct { From 87ff50ff3247fa55016e512bf3a596b60f07a214 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 19 Jun 2022 10:33:07 +0200 Subject: [PATCH 381/629] committing docker-kafka-logger, so I can delete it next (too much work to implement) --- .../build.gradle.kts | 35 +++++ .../src/main/kotlin/dev/adamko/dokalo/api.kt | 138 ++++++++++++++++++ .../kotlin/dev/adamko/dokalo/logReader.kt | 125 ++++++++++++++++ .../src/main/kotlin/dev/adamko/dokalo/main.kt | 37 +++++ .../main/kotlin/dev/adamko/dokalo/model.kt | 110 ++++++++++++++ .../src/main/resources/application.conf | 9 ++ 6 files changed, 454 insertions(+) create mode 100644 modules/infra-docker-kafka-logger/build.gradle.kts create mode 100644 modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/api.kt create mode 100644 modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/logReader.kt create mode 100644 modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/main.kt create mode 100644 modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/model.kt create mode 100644 modules/infra-docker-kafka-logger/src/main/resources/application.conf diff --git a/modules/infra-docker-kafka-logger/build.gradle.kts b/modules/infra-docker-kafka-logger/build.gradle.kts new file mode 100644 index 0000000..a39813f --- /dev/null +++ b/modules/infra-docker-kafka-logger/build.gradle.kts @@ -0,0 +1,35 @@ +plugins { + dev.adamko.kafkatorio.lang.`kotlin-jvm` + kotlin("plugin.serialization") +} + + +dependencies { + implementation(platform(projects.modules.versionsPlatform)) + +// implementation(gradleKotlinDsl()) + + implementation(libs.kotlinx.serialization.core) + implementation(libs.kotlinx.serialization.json) + implementation(libs.kotlinx.serialization.protobuf) + + implementation(libs.kotlinx.cli) + + implementation(libs.kotlinx.coroutines.core) + + implementation(libs.okio.core) + + implementation(libs.ktor.serverCore) + implementation(libs.ktor.serverNetty) + implementation(libs.ktor.serverContentNegotiaion) + implementation(libs.ktor.serializationKotlinxJson) + implementation(libs.ktor.serverResources) + + implementation(libs.kafka.streams) + implementation(libs.kafka.kotkaStreams) + + implementation(libs.kotlinx.datetime) + + testImplementation(libs.ktor.test.serverHost) + testImplementation(libs.kafka.streamsTestUtils) +} diff --git a/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/api.kt b/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/api.kt new file mode 100644 index 0000000..4abc6e8 --- /dev/null +++ b/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/api.kt @@ -0,0 +1,138 @@ +package dev.adamko.dokalo + +import dev.adamko.dokalo.Capabilities.Response.readLogs +import io.ktor.http.ContentType +import io.ktor.http.HttpStatusCode +import io.ktor.resources.Resource +import io.ktor.server.application.Application +import io.ktor.server.application.call +import io.ktor.server.resources.post +import io.ktor.server.response.respond +import io.ktor.server.response.respondOutputStream +import io.ktor.server.routing.routing +import kotlinx.datetime.LocalDateTime +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + + +fun Application.configureRouting() { + + routing { + + post { request -> + // Signals to the plugin that a container is starting that the plugin should start receiving logs for. + call.respond(StartLogging.Response()) + } + + post { request -> + // Signals to the plugin to stop collecting logs from the defined file. + call.respond(StopLogging.Response()) + } + + post { + // Defines the capabilities of the log driver. + call.respond(Capabilities.Response) + } + + post { request -> + // Reads back logs to the client. This is used when docker logs is called. + + call.respondOutputStream( + ContentType.parse("application/x-json-stream"), + HttpStatusCode.OK, + ) { + + } + } + } +} + + +sealed interface StartLogging { + + @Resource("/LogDriver.StartLogging") + @Serializable + data class Request( + + @SerialName("File") + val file: LogFile, + + @SerialName("Info") + val info: ContainerInfo, + ) : StartLogging + + + @Serializable + data class Response( + @SerialName("Err") + val error: String? = null, + ) : StartLogging +} + + +sealed interface StopLogging { + + @Resource("/LogDriver.StopLogging") + @Serializable + data class Request( + @SerialName("File") + val file: LogFile, + ) : StopLogging + + + @Serializable + data class Response( + @SerialName("Err") + val error: String? = null, + ) : StopLogging +} + + +sealed interface Capabilities { + + @Resource("/LogDriver.Capabilities") + @Serializable + object Request : Capabilities + + /** + * Defines the list of capabilities that a driver can implement. These capabilities are not + * required to be a logging driver, however do determine how a logging driver can be used. + * + * @property[readLogs] Determines if a log driver can read back logs + */ + @Serializable + object Response : Capabilities { + @SerialName("ReadLogs") + val readLogs: Boolean = true + } +} + + +@Resource("/LogDriver.ReadLogs") +@Serializable +data class ReadLogsRequest( + + @SerialName("Info") + val info: ContainerInfo, + + @SerialName("Config") + val config: ReadConfig, +) { + + /** ReadConfig is the configuration passed into ReadLogs. */ + @Serializable + data class ReadConfig( + + @SerialName("Since") + val since: LocalDateTime, + + @SerialName("Until") + val until: LocalDateTime, + + @SerialName("Tail") + val tail: Int, + + @SerialName("Follow") + val follow: Boolean, + ) +} diff --git a/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/logReader.kt b/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/logReader.kt new file mode 100644 index 0000000..4202b29 --- /dev/null +++ b/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/logReader.kt @@ -0,0 +1,125 @@ +package dev.adamko.dokalo + +import kotlin.coroutines.CoroutineContext +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.currentCoroutineContext +import kotlinx.coroutines.flow.* +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.shareIn +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import kotlinx.coroutines.supervisorScope +import kotlinx.coroutines.yield +import okio.BufferedSource +import okio.FileSystem +import okio.Path +import okio.Path.Companion.toPath +import okio.buffer + + +class LogReaderManager : CoroutineScope { + + override val coroutineContext: CoroutineContext = CoroutineName("LogReaderManager") + + private val commands: MutableSharedFlow = + MutableSharedFlow(0, Int.MAX_VALUE, BufferOverflow.SUSPEND) + + private val readers: MutableStateFlow> = MutableStateFlow(emptyMap()) + + init { + launch { + supervisorScope { + commands.runningFold(mapOf()) { readers, cmd -> + when (cmd) { + is LogReaderCmd.Start -> { + if (cmd.file in readers) { + error("can't process 'start' for reader ${cmd.file} it's already registered") + } else { + readers + (cmd.file to LogReader(cmd.file)) + + } + } + + is LogReaderCmd.Stop -> { + if (cmd.file !in readers) { + error("can't process 'stop' for reader ${cmd.file} - it's not registered") + } else { + readers - cmd.file + } + } + } + }.collect(readers) + } + } + } + + suspend fun start(data: StartLogging.Request) { + commands.emit(LogReaderCmd.Start(data.file)) + } + + suspend fun stop(data: StopLogging.Request) { + commands.emit(LogReaderCmd.Stop(data.file)) + } + + +} + +private data class LogReader( + val file: LogFile, +) : CoroutineScope { + private val path: Path = file.file.toPath() + private val source: BufferedSource = FileSystem.SYSTEM.source(path).buffer() + + override val coroutineContext: CoroutineContext = + CoroutineName("LogReader-${file.file.filter { it.isLetterOrDigit() }}") + + CoroutineExceptionHandler { coroutineContext, throwable -> + source.close() + } + + private val _entries: MutableSharedFlow = + MutableSharedFlow(0, Int.MAX_VALUE, BufferOverflow.SUSPEND) + + + init { + launch { + val f = flow { + while (currentCoroutineContext().isActive && source.isOpen) { + val entrySize = source.readInt().toLong() + val entry = source.readString(entrySize, Charsets.UTF_8) + emit(entry) + yield() + } + } + + f.shareIn(this, SharingStarted.Lazily) + f.launchIn(this) + + + } + } +} + +fun logReader(file: LogFile) { + val reader = LogReader(file) + + +} + + +private sealed interface LogReaderCmd { + val file: LogFile + + data class Start(override val file: LogFile) : LogReaderCmd + + data class Stop(override val file: LogFile) : LogReaderCmd +} + + +private sealed interface LogReaderState { + object Active : LogReaderState + object Stopped : LogReaderState + data class Error(val msg: String, val cause: Exception?) : LogReaderState +} diff --git a/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/main.kt b/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/main.kt new file mode 100644 index 0000000..b5345da --- /dev/null +++ b/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/main.kt @@ -0,0 +1,37 @@ +package dev.adamko.dokalo + +import com.typesafe.config.ConfigFactory +import io.ktor.server.application.install +import io.ktor.server.config.HoconApplicationConfig +import io.ktor.server.engine.applicationEngineEnvironment +import io.ktor.server.engine.connector +import io.ktor.server.engine.embeddedServer +import io.ktor.server.netty.Netty +import io.ktor.server.resources.Resources + + +fun main() { + + embeddedServer(Netty, port = 8080) { + + install(Resources) + + configureRouting() + }.start(wait = true) + + +// embeddedServer(Netty, environment = applicationEngineEnvironment { +// +// config = HoconApplicationConfig(ConfigFactory.load()) +// +// module { +// main() +// } +// +// connector { +// port = 8080 +// host = "127.0.0.1" +// } +// }).start(wait = true) + +} diff --git a/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/model.kt b/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/model.kt new file mode 100644 index 0000000..838a8f5 --- /dev/null +++ b/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/model.kt @@ -0,0 +1,110 @@ +@file:OptIn(ExperimentalSerializationApi::class) + +package dev.adamko.dokalo + +import kotlinx.datetime.LocalDateTime +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.protobuf.ProtoNumber + + +@Serializable +@JvmInline +value class ContainerId(private val id: String) + + +@Serializable +@JvmInline +value class LogFile(val file: String) + + +/** Info provides enough information for a logging driver to do its function. */ +@Serializable +data class ContainerInfo( + @SerialName("ContainerID") + val containerId: ContainerId, + + @SerialName("Config") + val config: Map? = null, + + @SerialName("ContainerName") + val containerName: String? = null, + + @SerialName("ContainerEntrypoint") + val containerEntrypoint: String? = null, + + @SerialName("ContainerArgs") + val containerArgs: List? = null, + + @SerialName("ContainerImageID") + val containerImageId: String? = null, + + @SerialName("ContainerImageName") + val containerImageName: String? = null, + + @SerialName("ContainerCreated") + val containerCreated: LocalDateTime? = null, + + @SerialName("ContainerEnv") + val containerEnv: List? = null, + + @SerialName("ContainerLabels") + val containerLabels: Map? = null, + + @SerialName("LogPath") + val logPath: String? = null, + + @SerialName("DaemonName") + val daemonName: String? = null, +) + + +@Serializable +data class LogEntry( + @ProtoNumber(1) + val source: String, + @ProtoNumber(2) + val time_nano: Long, + @ProtoNumber(3) + val line: ByteArray, + @ProtoNumber(4) + val partial: Boolean, + @ProtoNumber(5) + val partial_log_metadata: PartialLogEntryMetadata, +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as LogEntry + + if (source != other.source) return false + if (time_nano != other.time_nano) return false + if (!line.contentEquals(other.line)) return false + if (partial != other.partial) return false + if (partial_log_metadata != other.partial_log_metadata) return false + + return true + } + + override fun hashCode(): Int { + var result = source.hashCode() + result = 31 * result + time_nano.hashCode() + result = 31 * result + line.contentHashCode() + result = 31 * result + partial.hashCode() + result = 31 * result + partial_log_metadata.hashCode() + return result + } +} + + +@Serializable +data class PartialLogEntryMetadata( + @ProtoNumber(1) + val last: Boolean, + @ProtoNumber(2) + val id: String, + @ProtoNumber(3) + val ordinal: Int, +) diff --git a/modules/infra-docker-kafka-logger/src/main/resources/application.conf b/modules/infra-docker-kafka-logger/src/main/resources/application.conf new file mode 100644 index 0000000..08b319b --- /dev/null +++ b/modules/infra-docker-kafka-logger/src/main/resources/application.conf @@ -0,0 +1,9 @@ +ktor { + deployment { + port = 8080 + port = ${?PORT} + } + application { + modules = [ com.example.ApplicationKt.module ] + } +} From b08e33e2eb2dac32baf490139bcefd3bbb1919a5 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 19 Jun 2022 10:33:30 +0200 Subject: [PATCH 382/629] delete docker kafka logger --- .../build.gradle.kts | 35 ----- .../src/main/kotlin/dev/adamko/dokalo/api.kt | 138 ------------------ .../kotlin/dev/adamko/dokalo/logReader.kt | 125 ---------------- .../src/main/kotlin/dev/adamko/dokalo/main.kt | 37 ----- .../main/kotlin/dev/adamko/dokalo/model.kt | 110 -------------- .../src/main/resources/application.conf | 9 -- 6 files changed, 454 deletions(-) delete mode 100644 modules/infra-docker-kafka-logger/build.gradle.kts delete mode 100644 modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/api.kt delete mode 100644 modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/logReader.kt delete mode 100644 modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/main.kt delete mode 100644 modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/model.kt delete mode 100644 modules/infra-docker-kafka-logger/src/main/resources/application.conf diff --git a/modules/infra-docker-kafka-logger/build.gradle.kts b/modules/infra-docker-kafka-logger/build.gradle.kts deleted file mode 100644 index a39813f..0000000 --- a/modules/infra-docker-kafka-logger/build.gradle.kts +++ /dev/null @@ -1,35 +0,0 @@ -plugins { - dev.adamko.kafkatorio.lang.`kotlin-jvm` - kotlin("plugin.serialization") -} - - -dependencies { - implementation(platform(projects.modules.versionsPlatform)) - -// implementation(gradleKotlinDsl()) - - implementation(libs.kotlinx.serialization.core) - implementation(libs.kotlinx.serialization.json) - implementation(libs.kotlinx.serialization.protobuf) - - implementation(libs.kotlinx.cli) - - implementation(libs.kotlinx.coroutines.core) - - implementation(libs.okio.core) - - implementation(libs.ktor.serverCore) - implementation(libs.ktor.serverNetty) - implementation(libs.ktor.serverContentNegotiaion) - implementation(libs.ktor.serializationKotlinxJson) - implementation(libs.ktor.serverResources) - - implementation(libs.kafka.streams) - implementation(libs.kafka.kotkaStreams) - - implementation(libs.kotlinx.datetime) - - testImplementation(libs.ktor.test.serverHost) - testImplementation(libs.kafka.streamsTestUtils) -} diff --git a/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/api.kt b/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/api.kt deleted file mode 100644 index 4abc6e8..0000000 --- a/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/api.kt +++ /dev/null @@ -1,138 +0,0 @@ -package dev.adamko.dokalo - -import dev.adamko.dokalo.Capabilities.Response.readLogs -import io.ktor.http.ContentType -import io.ktor.http.HttpStatusCode -import io.ktor.resources.Resource -import io.ktor.server.application.Application -import io.ktor.server.application.call -import io.ktor.server.resources.post -import io.ktor.server.response.respond -import io.ktor.server.response.respondOutputStream -import io.ktor.server.routing.routing -import kotlinx.datetime.LocalDateTime -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - - -fun Application.configureRouting() { - - routing { - - post { request -> - // Signals to the plugin that a container is starting that the plugin should start receiving logs for. - call.respond(StartLogging.Response()) - } - - post { request -> - // Signals to the plugin to stop collecting logs from the defined file. - call.respond(StopLogging.Response()) - } - - post { - // Defines the capabilities of the log driver. - call.respond(Capabilities.Response) - } - - post { request -> - // Reads back logs to the client. This is used when docker logs is called. - - call.respondOutputStream( - ContentType.parse("application/x-json-stream"), - HttpStatusCode.OK, - ) { - - } - } - } -} - - -sealed interface StartLogging { - - @Resource("/LogDriver.StartLogging") - @Serializable - data class Request( - - @SerialName("File") - val file: LogFile, - - @SerialName("Info") - val info: ContainerInfo, - ) : StartLogging - - - @Serializable - data class Response( - @SerialName("Err") - val error: String? = null, - ) : StartLogging -} - - -sealed interface StopLogging { - - @Resource("/LogDriver.StopLogging") - @Serializable - data class Request( - @SerialName("File") - val file: LogFile, - ) : StopLogging - - - @Serializable - data class Response( - @SerialName("Err") - val error: String? = null, - ) : StopLogging -} - - -sealed interface Capabilities { - - @Resource("/LogDriver.Capabilities") - @Serializable - object Request : Capabilities - - /** - * Defines the list of capabilities that a driver can implement. These capabilities are not - * required to be a logging driver, however do determine how a logging driver can be used. - * - * @property[readLogs] Determines if a log driver can read back logs - */ - @Serializable - object Response : Capabilities { - @SerialName("ReadLogs") - val readLogs: Boolean = true - } -} - - -@Resource("/LogDriver.ReadLogs") -@Serializable -data class ReadLogsRequest( - - @SerialName("Info") - val info: ContainerInfo, - - @SerialName("Config") - val config: ReadConfig, -) { - - /** ReadConfig is the configuration passed into ReadLogs. */ - @Serializable - data class ReadConfig( - - @SerialName("Since") - val since: LocalDateTime, - - @SerialName("Until") - val until: LocalDateTime, - - @SerialName("Tail") - val tail: Int, - - @SerialName("Follow") - val follow: Boolean, - ) -} diff --git a/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/logReader.kt b/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/logReader.kt deleted file mode 100644 index 4202b29..0000000 --- a/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/logReader.kt +++ /dev/null @@ -1,125 +0,0 @@ -package dev.adamko.dokalo - -import kotlin.coroutines.CoroutineContext -import kotlinx.coroutines.CoroutineExceptionHandler -import kotlinx.coroutines.CoroutineName -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.currentCoroutineContext -import kotlinx.coroutines.flow.* -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.shareIn -import kotlinx.coroutines.isActive -import kotlinx.coroutines.launch -import kotlinx.coroutines.supervisorScope -import kotlinx.coroutines.yield -import okio.BufferedSource -import okio.FileSystem -import okio.Path -import okio.Path.Companion.toPath -import okio.buffer - - -class LogReaderManager : CoroutineScope { - - override val coroutineContext: CoroutineContext = CoroutineName("LogReaderManager") - - private val commands: MutableSharedFlow = - MutableSharedFlow(0, Int.MAX_VALUE, BufferOverflow.SUSPEND) - - private val readers: MutableStateFlow> = MutableStateFlow(emptyMap()) - - init { - launch { - supervisorScope { - commands.runningFold(mapOf()) { readers, cmd -> - when (cmd) { - is LogReaderCmd.Start -> { - if (cmd.file in readers) { - error("can't process 'start' for reader ${cmd.file} it's already registered") - } else { - readers + (cmd.file to LogReader(cmd.file)) - - } - } - - is LogReaderCmd.Stop -> { - if (cmd.file !in readers) { - error("can't process 'stop' for reader ${cmd.file} - it's not registered") - } else { - readers - cmd.file - } - } - } - }.collect(readers) - } - } - } - - suspend fun start(data: StartLogging.Request) { - commands.emit(LogReaderCmd.Start(data.file)) - } - - suspend fun stop(data: StopLogging.Request) { - commands.emit(LogReaderCmd.Stop(data.file)) - } - - -} - -private data class LogReader( - val file: LogFile, -) : CoroutineScope { - private val path: Path = file.file.toPath() - private val source: BufferedSource = FileSystem.SYSTEM.source(path).buffer() - - override val coroutineContext: CoroutineContext = - CoroutineName("LogReader-${file.file.filter { it.isLetterOrDigit() }}") + - CoroutineExceptionHandler { coroutineContext, throwable -> - source.close() - } - - private val _entries: MutableSharedFlow = - MutableSharedFlow(0, Int.MAX_VALUE, BufferOverflow.SUSPEND) - - - init { - launch { - val f = flow { - while (currentCoroutineContext().isActive && source.isOpen) { - val entrySize = source.readInt().toLong() - val entry = source.readString(entrySize, Charsets.UTF_8) - emit(entry) - yield() - } - } - - f.shareIn(this, SharingStarted.Lazily) - f.launchIn(this) - - - } - } -} - -fun logReader(file: LogFile) { - val reader = LogReader(file) - - -} - - -private sealed interface LogReaderCmd { - val file: LogFile - - data class Start(override val file: LogFile) : LogReaderCmd - - data class Stop(override val file: LogFile) : LogReaderCmd -} - - -private sealed interface LogReaderState { - object Active : LogReaderState - object Stopped : LogReaderState - data class Error(val msg: String, val cause: Exception?) : LogReaderState -} diff --git a/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/main.kt b/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/main.kt deleted file mode 100644 index b5345da..0000000 --- a/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/main.kt +++ /dev/null @@ -1,37 +0,0 @@ -package dev.adamko.dokalo - -import com.typesafe.config.ConfigFactory -import io.ktor.server.application.install -import io.ktor.server.config.HoconApplicationConfig -import io.ktor.server.engine.applicationEngineEnvironment -import io.ktor.server.engine.connector -import io.ktor.server.engine.embeddedServer -import io.ktor.server.netty.Netty -import io.ktor.server.resources.Resources - - -fun main() { - - embeddedServer(Netty, port = 8080) { - - install(Resources) - - configureRouting() - }.start(wait = true) - - -// embeddedServer(Netty, environment = applicationEngineEnvironment { -// -// config = HoconApplicationConfig(ConfigFactory.load()) -// -// module { -// main() -// } -// -// connector { -// port = 8080 -// host = "127.0.0.1" -// } -// }).start(wait = true) - -} diff --git a/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/model.kt b/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/model.kt deleted file mode 100644 index 838a8f5..0000000 --- a/modules/infra-docker-kafka-logger/src/main/kotlin/dev/adamko/dokalo/model.kt +++ /dev/null @@ -1,110 +0,0 @@ -@file:OptIn(ExperimentalSerializationApi::class) - -package dev.adamko.dokalo - -import kotlinx.datetime.LocalDateTime -import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlinx.serialization.protobuf.ProtoNumber - - -@Serializable -@JvmInline -value class ContainerId(private val id: String) - - -@Serializable -@JvmInline -value class LogFile(val file: String) - - -/** Info provides enough information for a logging driver to do its function. */ -@Serializable -data class ContainerInfo( - @SerialName("ContainerID") - val containerId: ContainerId, - - @SerialName("Config") - val config: Map? = null, - - @SerialName("ContainerName") - val containerName: String? = null, - - @SerialName("ContainerEntrypoint") - val containerEntrypoint: String? = null, - - @SerialName("ContainerArgs") - val containerArgs: List? = null, - - @SerialName("ContainerImageID") - val containerImageId: String? = null, - - @SerialName("ContainerImageName") - val containerImageName: String? = null, - - @SerialName("ContainerCreated") - val containerCreated: LocalDateTime? = null, - - @SerialName("ContainerEnv") - val containerEnv: List? = null, - - @SerialName("ContainerLabels") - val containerLabels: Map? = null, - - @SerialName("LogPath") - val logPath: String? = null, - - @SerialName("DaemonName") - val daemonName: String? = null, -) - - -@Serializable -data class LogEntry( - @ProtoNumber(1) - val source: String, - @ProtoNumber(2) - val time_nano: Long, - @ProtoNumber(3) - val line: ByteArray, - @ProtoNumber(4) - val partial: Boolean, - @ProtoNumber(5) - val partial_log_metadata: PartialLogEntryMetadata, -) { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as LogEntry - - if (source != other.source) return false - if (time_nano != other.time_nano) return false - if (!line.contentEquals(other.line)) return false - if (partial != other.partial) return false - if (partial_log_metadata != other.partial_log_metadata) return false - - return true - } - - override fun hashCode(): Int { - var result = source.hashCode() - result = 31 * result + time_nano.hashCode() - result = 31 * result + line.contentHashCode() - result = 31 * result + partial.hashCode() - result = 31 * result + partial_log_metadata.hashCode() - return result - } -} - - -@Serializable -data class PartialLogEntryMetadata( - @ProtoNumber(1) - val last: Boolean, - @ProtoNumber(2) - val id: String, - @ProtoNumber(3) - val ordinal: Int, -) diff --git a/modules/infra-docker-kafka-logger/src/main/resources/application.conf b/modules/infra-docker-kafka-logger/src/main/resources/application.conf deleted file mode 100644 index 08b319b..0000000 --- a/modules/infra-docker-kafka-logger/src/main/resources/application.conf +++ /dev/null @@ -1,9 +0,0 @@ -ktor { - deployment { - port = 8080 - port = ${?PORT} - } - application { - modules = [ com.example.ApplicationKt.module ] - } -} From 2f921179c4241af127d2205f33536b354535700b Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 19 Jun 2022 10:35:47 +0200 Subject: [PATCH 383/629] events server config file --- .../src/main/resources/config.yml | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 modules/events-server/src/main/resources/config.yml diff --git a/modules/events-server/src/main/resources/config.yml b/modules/events-server/src/main/resources/config.yml new file mode 100644 index 0000000..fa31386 --- /dev/null +++ b/modules/events-server/src/main/resources/config.yml @@ -0,0 +1,63 @@ +# Factorio Events Processor config + +web-port: ${SERVER_PORT:-12080} +tile-dir: ${TILE_DIR:-./tile-dir} + +kafka-admin-config: + client.id: kafkatorio.events-server-admin + bootstrap.servers: ${KAFKA_BOOTSTRAP_SERVERS:-http://localhost:9092} + +kafka-streams-config: + application.id: kafkatorio-events-processor + bootstrap.servers: ${KAFKA_BOOTSTRAP_SERVERS:-http://localhost:9092} + state.dir: ${KAFKA_STREAMS_STATE_DIR:-./kafka-state} + num.stream.threads: 1 + processing.guarantee: exactly_once_v2 + auto.offset.reset: earliest + default.key.serde: org.apache.kafka.common.serialization.Serdes$StringSerde + default.value.serde: org.apache.kafka.common.serialization.Serdes$StringSerde + + # default.deserialization.exception.handler: org.apache.kafka.streams.errors.LogAndContinueExceptionHandler + + #buffered.records.per.partition: 0 + #poll.ms: 10000 + + # 31457280 : 30MB + max.request.size: 31457280 + buffer.memory: 31457280 + + compression.type: snappy + # linger.ms=5 + + # fetch.message.max.bytes=31457280 + # 100mb 104857600 + + +#kafka: +# bootstrap-servers: +# - "http://localhost:9092" +# config: | +# application.id=kafkatorio-events-processor +# bootstrap.servers={{bootstrap-servers}} +# state.dir=./kafka-state +# num.stream.threads=1 +# processing.guarantee=exactly_once_v2 +# auto.offset.reset=earliest +# default.key.serde=org.apache.kafka.common.serialization.Serdes$StringSerde +# default.value.serde=org.apache.kafka.common.serialization.Serdes$StringSerde +# default.deserialization.exception.handler=org.apache.kafka.streams.errors.LogAndContinueExceptionHandler +# #buffered.records.per.partition=0 +# #poll.ms=10000 +# +# # 31457280 = 30MB +# max.request.size=31457280 +# buffer.memory=31457280 +# +# compression.type=snappy +# # linger.ms=5 +# +# # fetch.message.max.bytes=31457280 +# # 100mb 104857600 +# +#tileServer: +# webmapTileDir: 'D:\Users\Adam\Projects\games\kafkatorio\modules\events-server\kafkatorio-tiles' From 1c310272c654bde7749186573154396323afa200 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 19 Jun 2022 10:38:05 +0200 Subject: [PATCH 384/629] rm factorio mod portal client (it was moved to buildSrc) --- .../build.gradle.kts | 45 -------- .../kafkatorio/FactorioModPortalClient.kt | 107 ------------------ .../FactorioModPortalPublishTask.kt | 83 -------------- .../dev/adamko/kafkatorio/modUploader.kt | 40 ------- 4 files changed, 275 deletions(-) delete mode 100644 modules/factorio-mod-portal-client/build.gradle.kts delete mode 100644 modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalClient.kt delete mode 100644 modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalPublishTask.kt delete mode 100644 modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/modUploader.kt diff --git a/modules/factorio-mod-portal-client/build.gradle.kts b/modules/factorio-mod-portal-client/build.gradle.kts deleted file mode 100644 index a4700a0..0000000 --- a/modules/factorio-mod-portal-client/build.gradle.kts +++ /dev/null @@ -1,45 +0,0 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - -plugins { - dev.adamko.kafkatorio.lang.`kotlin-jvm` - kotlin("plugin.serialization") - `java-gradle-plugin` -} - - -dependencies { - implementation(platform(projects.modules.versionsPlatform)) - -// implementation(gradleKotlinDsl()) - - implementation(libs.kotlinx.serialization.core) - implementation(libs.kotlinx.serialization.json) - implementation(libs.kotlinx.cli) - - implementation(libs.kotlinx.coroutines.core) - -// implementation(libs.bundles.http4k) -// implementation(libs.http4k.format.kotlinx) - -// implementation(libs.skrapeit) - - implementation(libs.okio.core) - - implementation(libs.semver) - - implementation(libs.ktor.clientAuth) - implementation(libs.ktor.clientContentNegotiation) - implementation(libs.ktor.clientCore) - implementation(libs.ktor.clientEncoding) - implementation(libs.ktor.clientLogging) - implementation(libs.ktor.clientCIO) - implementation(libs.ktor.clientResources) - implementation(libs.ktor.serializationKotlinxJson) -} - -tasks.withType().configureEach { - kotlinOptions.freeCompilerArgs += listOf( - "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-opt-in=kotlinx.coroutines.FlowPreview", - ) -} diff --git a/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalClient.kt b/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalClient.kt deleted file mode 100644 index 58b6e30..0000000 --- a/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalClient.kt +++ /dev/null @@ -1,107 +0,0 @@ -package dev.adamko.kafkatorio - -//import dev.adamko.kafkatorio.processor.serdes.KXS.asPrettyJsonString -//import dev.adamko.kafkatorio.processor.serdes.jsonMapper -//import it.skrape.core.htmlDocument -//import it.skrape.selects.html5.input -//import kotlinx.serialization.json.JsonObject -//import kotlinx.serialization.json.jsonObject -//import org.http4k.client.OkHttp -//import org.http4k.core.HttpHandler -//import org.http4k.core.Method -//import org.http4k.core.Request -//import org.http4k.core.Response -//import org.http4k.core.body.form -//import org.http4k.core.cookie.Cookie -//import org.http4k.core.cookie.cookie -//import org.http4k.core.cookie.cookies -//import org.http4k.core.then -//import org.http4k.filter.ClientFilters -// -// -///* -// * * https://github.com/shanemadden/factorio-mod-portal-publish/blob/master/entrypoint.sh -// * * https://github.com/nicolas-lang/factorio-create-release-action/blob/master/entrypoint.py -// * * https://github.com/nicolas-lang/factorio-create-release-action/blob/master/factorioModPortal.py -// * * https://github.com/justarandomgeek/vscode-factoriomod-debug/blob/master/src/ModPackageProvider.ts#L530 -// * -// * -// */ -//internal class FactorioModPortalClient( -// private val appProps: ApplicationProperties = ApplicationProperties(), -// private val loginFormUrl: String = "https://factorio.com/login?mods=1", -// private val loginUrl: String = "https://factorio.com/login", -//) { -// -// private val client: HttpHandler = -// ClientFilters.FollowRedirects() -// .then(OkHttp()) -// -// private val csrfCookie: Cookie by lazy { fetchCsrfToken() } -// private val sessionCookie: Cookie by lazy { login() } -// -// -// private fun fetchCsrfToken(): Cookie { -// -// val request = Request(Method.GET, loginFormUrl) -// val response: Response = client(request) -// -// val csrfToken = htmlDocument(response.bodyString()) { -// input { -// withId = csrfTokenName -// withAttribute = "name" to csrfTokenName -// findFirst { attribute("value") } -// } -// } -// -// println("csrfToken: $csrfToken") -// return Cookie(csrfTokenName, csrfToken) -// } -// -// -// private fun login(): Cookie { -// -// val loginRequest = Request(Method.POST, loginUrl) -// .header("Referer", loginFormUrl) -//// .cookie(csrfCookie) -// .form("csrf_token", csrfCookie.value) -// .form("username_or_email", appProps.factorioModPortalUsername) -// .form("password", appProps.factorioModPortalPassword.use { it }) -// .form("next_url", "/profile") -// -// val loginResponse = client(loginRequest) -// -// println(loginResponse.bodyString()) -// -// val sessionCookie = loginResponse.cookies() -// .first { it.name == "session" && it.domain == ".factorio.com" } -// -// println("sessionCookie: $sessionCookie") -// -// return sessionCookie -// } -// -// fun getModInfo(modName: String): JsonObject { -// val response = client( -// Request(Method.GET, "https://mods.factorio.com/api/mods/${modName}/full") -// .cookie(csrfCookie) -// .cookie(sessionCookie) -// ) -// return jsonMapper.parseToJsonElement(response.bodyString()).jsonObject -// } -// -// fun fetchModUploadToken(modName: String): String { -// val response = client( -// Request(Method.GET, "https://mods.factorio.com/mod/${modName}/edit") -// .cookie(csrfCookie) -// .cookie(sessionCookie) -// ) -// -// return response.bodyString() -// } -// -// companion object { -// private const val csrfTokenName = "csrf_token" -// } -// -//} diff --git a/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalPublishTask.kt b/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalPublishTask.kt deleted file mode 100644 index 4163228..0000000 --- a/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/FactorioModPortalPublishTask.kt +++ /dev/null @@ -1,83 +0,0 @@ -package dev.adamko.kafkatorio - -//import javax.inject.Inject -//import kotlinx.coroutines.runBlocking -//import kotlinx.serialization.json.Json -//import net.swiftzer.semver.SemVer -//import okio.FileSystem -//import okio.Path.Companion.toOkioPath -//import okio.Path.Companion.toPath -//import okio.openZip -//import org.gradle.api.DefaultTask -//import org.gradle.api.file.RegularFileProperty -//import org.gradle.api.model.ObjectFactory -//import org.gradle.api.provider.Property -//import org.gradle.api.provider.ProviderFactory -//import org.gradle.api.tasks.Input -//import org.gradle.api.tasks.InputFile -//import org.gradle.api.tasks.TaskAction -//import org.gradle.kotlin.dsl.property -// -// -//abstract class FactorioModPortalPublishTask @Inject constructor( -// objects: ObjectFactory, -// providers: ProviderFactory, -//) : DefaultTask() { -// -// @get:InputFile -// abstract val distributionZip: RegularFileProperty -// -// @get:Input -// abstract val modVersion: Property -// -// @get:Input -// abstract val modName: Property -// -// @get:Input -// abstract val factorioVersion: Property -// -// /** Bearer API key */ -// @get:Input -// val portalApiKey: Property = objects.property().convention( -// providers.gradleProperty("FACTORIO_MOD_PORTAL_API_KEY") -// ) -// -// @get:Input -// val portalUploadEndpoint: Property = objects.property() -// .convention("https://mods.factorio.com/api/v2/mods/releases/init_upload") -// -// -// @TaskAction -// fun deploy() = runBlocking { -// val modVersion = SemVer.parse(modVersion.get()) -// -// val portalUploadEndpoint = portalUploadEndpoint.get() -// val modName = modName.get() -// val portalApiKey = portalApiKey.get() -// val distributionZip = distributionZip.get().asFile -// -// } -// -// private fun validateInfoJson() { -// val modVersion = modVersion.get() -// val factorioVersion = factorioVersion.get() -// -// val distributionZip = distributionZip.get().asFile.toOkioPath() -// -// val zipContents = FileSystem.SYSTEM.openZip(distributionZip) -// -// val infoJson = zipContents.read("info.json".toPath()) { -// generateSequence { readUtf8Line() } -// }.joinToString("\n") -// -// val info: FactorioModInfo = Json.decodeFromString(FactorioModInfo.serializer(), infoJson) -// -// require(info.version == modVersion) { -// "mod version mismatch, ${info.version} vs $modVersion " -// } -// -// require(info.factorioVersion == factorioVersion) { -// "Factorio version mismatch, ${info.factorioVersion} vs $factorioVersion " -// } -// } -//} diff --git a/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/modUploader.kt b/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/modUploader.kt deleted file mode 100644 index 5cba361..0000000 --- a/modules/factorio-mod-portal-client/src/main/kotlin/dev/adamko/kafkatorio/modUploader.kt +++ /dev/null @@ -1,40 +0,0 @@ -package dev.adamko.kafkatorio -// -//import java.io.File -//import kotlinx.cli.ArgParser -//import kotlinx.cli.ArgType -//import kotlinx.cli.required -//import kotlinx.coroutines.runBlocking -// -//fun main(args: Array) = runBlocking { -// val parser = ArgParser("example") -// -// val distributionZip: File by parser.option(FileArg).required() -// val modName: String by parser.option(ArgType.String).required() -// val portalApiKey: String by parser.option(ArgType.String).required() -// val portalUploadEndpoint: String by parser.option(ArgType.String).required() -// -// parser.parse(args) -// -// val client = FactorioModPortalPublishClient( -// distributionZip, -// modName, -// portalApiKey, -// portalUploadEndpoint, -// ) -// -// client.uploadMod() -//} -// -// -//object FileArg : ArgType(true) { -// override val description: kotlin.String -// get() = "{ File }" -// -// override fun convert(value: kotlin.String, name: kotlin.String): File { -// return File(value).also { -// require(it.exists()) { "${it.canonicalPath} does not exist" } -// require(it.isFile) { "${it.canonicalPath} is not a file" } -// } -// } -//} From c870d1f6e0449aacb6db6309b84fcfda2d02de7a Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 19 Jun 2022 10:38:26 +0200 Subject: [PATCH 385/629] provider for package.json (try to fix Gradle warning) --- modules/events-mod/build.gradle.kts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index d9819c1..56d2a44 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -197,13 +197,14 @@ val factorioModProvider by configurations.registering { } -val packageJsonName = providers.provider { "${rootProject.name}-${project.name}" } +val packageJsonName: Provider = providers.provider { "${rootProject.name}-${project.name}" } +val pjProvider: RegularFileProperty = + objects.fileProperty().convention(layout.projectDirectory.file("package.json")) tasks.updatePackageJson { // mustRunAfter(tasks.npmInstall) inputs.property("packageJsonName", packageJsonName) propertiesToCheck.put("name", packageJsonName) - val pjProvider = layout.projectDirectory.file(provider { "package.json" }) packageJsonFile.set(pjProvider) } From a225b65901159246c7f0de94d9ba61a50ac0c7de Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 19 Jun 2022 10:38:50 +0200 Subject: [PATCH 386/629] (minor) make kt function expression --- .../kotlin/dev/adamko/kafkatorio/schema/common/positions.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt index 1d63eee..a9ede2a 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt @@ -65,9 +65,7 @@ data class MapChunkPosition( MapChunkPositionBounds(this, ChunkSize.CHUNK_032) } - operator fun contains(tilePosition: MapTilePosition): Boolean { - return tilePosition in bounds - } + operator fun contains(tilePosition: MapTilePosition): Boolean = tilePosition in bounds } From 0398e2026d204ef65b73dbeea7ab5dd696ffa4dc Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 19 Jun 2022 10:54:37 +0200 Subject: [PATCH 387/629] project version bump to 0.6.0, and bump kotest, tstl, typescript --- build.gradle.kts | 2 +- gradle/libs.versions.toml | 2 +- modules/events-mod/build.gradle.kts | 93 +++++++++---------- modules/events-mod/package-lock.json | 34 +++---- modules/events-mod/package.json | 8 +- .../kafkatorio/processor/eventProcessor.kt | 6 -- .../processor/tileserver/WebServer.kt | 2 +- .../processor/tileserver/WebsocketServer.kt | 9 +- modules/infra-factorio-server/src/.env | 2 +- modules/infra-kafka-cluster/src/.env | 2 +- modules/infra-kafka-pipe/src/.env | 2 +- 11 files changed, 74 insertions(+), 88 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3be7830..80d7379 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ plugins { } group = "dev.adamko.kafkatorio" -version = "0.5.1" +version = "0.6.0" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d369186..279301b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -39,7 +39,7 @@ kotkaStreams = "dev-SNAPSHOT" ## test ## junit = "5.8.2" -kotest = "5.3.0" +kotest = "5.3.1" mockk = "1.12.4" ## infra ## diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 56d2a44..0a37eff 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -19,8 +19,6 @@ description = "Sends in-game information to a server over the internet (requires // Factorio required format is: // - filename: `mod-name_version.zip` // - zip contains one directory, `mod-name` - - //val modName: String by extra { "${rootProject.name}-events" } extra.set("modName", "kafkatorio-events") val modName = extra.get("modName") as String @@ -161,34 +159,6 @@ tasks.withType().configureEach { } -//val downloadFactorioApiDocs by tasks.registering { -// group = project.name -// -// val target = uri("https://lua-api.factorio.com/latest/runtime-api.json") -// val apiFilename = File(target.path).name -// val downloadedFile = file("$temporaryDir/$apiFilename") -// -// val apiFile = layout.buildDirectory.file(apiFilename) -// outputs.file(apiFile) -// -// doLast { -// -// ant.invokeMethod( -// "get", mapOf( -// "src" to target, -// "dest" to downloadedFile, -// "verbose" to true, -// ) -// ) -// -// val json = downloadedFile.readText() -// val prettyJson = JsonOutput.prettyPrint(json) -// -// apiFile.get().asFile.writeText(prettyJson) -// -// logger.lifecycle("Downloaded Factorio API json: $apiFile") -// } -//} val factorioModProvider by configurations.registering { asProvider() @@ -212,6 +182,24 @@ tasks.updatePackageJson { tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) } +idea { + module { + sourceDirs = sourceDirs + file("src/main/typescript") + resourceDirs = resourceDirs + file("src/main/resources") + testSourceDirs = testSourceDirs + file("src/test/typescript") + iml { + whenMerged { + require(this is org.gradle.plugins.ide.idea.model.Module) + + sourceDirs = sourceDirs + file("src/main/typescript") + resourceDirs = resourceDirs + file("src/main/resources") + testSourceDirs = testSourceDirs + file("src/test/typescript") + } + } + } +} + + // trying to get Gradle+idea to recognise the ts-src... //val typescriptSrcSet = project.objects.sourceDirectorySet("typescript", "TypeScript").apply { @@ -242,20 +230,31 @@ tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) } // } // } //} - -idea { - module { - sourceDirs = sourceDirs + file("src/main/typescript") - resourceDirs = resourceDirs + file("src/main/resources") - testSourceDirs = testSourceDirs + file("src/test/typescript") - iml { - whenMerged { - require(this is org.gradle.plugins.ide.idea.model.Module) - - sourceDirs = sourceDirs + file("src/main/typescript") - resourceDirs = resourceDirs + file("src/main/resources") - testSourceDirs = testSourceDirs + file("src/test/typescript") - } - } - } -} +//val downloadFactorioApiDocs by tasks.registering { +// group = project.name +// +// val target = uri("https://lua-api.factorio.com/latest/runtime-api.json") +// val apiFilename = File(target.path).name +// val downloadedFile = file("$temporaryDir/$apiFilename") +// +// val apiFile = layout.buildDirectory.file(apiFilename) +// outputs.file(apiFile) +// +// doLast { +// +// ant.invokeMethod( +// "get", mapOf( +// "src" to target, +// "dest" to downloadedFile, +// "verbose" to true, +// ) +// ) +// +// val json = downloadedFile.readText() +// val prettyJson = JsonOutput.prettyPrint(json) +// +// apiFile.get().asFile.writeText(prettyJson) +// +// logger.lifecycle("Downloaded Factorio API json: $apiFile") +// } +//} diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 443a0a5..7e847ad 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.5.1", + "version": "0.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -50,19 +50,19 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "requires": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } }, "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" }, "supports-preserve-symlinks-flag": { "version": "1.0.0", @@ -75,19 +75,19 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.1.0.tgz", - "integrity": "sha512-SiUdkpEDblr0/Ntmj5uNaymC3HIdnw77iDzAsUScT0PZXsEZjDMeRguavhqHsjazYHOYCE/FS4oHoUHS8HMaWA==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.2.0.tgz", + "integrity": "sha512-6iC5YtJYbR2S12kFujIGzZNhBcQwbaSWIAC7iKbIxh8LhVuIDJoInZOg36DTny5GHDdwi0eSTX/wyCqFAbul0Q==" }, "typescript": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", - "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==" + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" }, "typescript-to-lua": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.4.4.tgz", - "integrity": "sha512-HqXDi0rjYANvVeOJlYAyjwCvLtpXV+RRp9GiknCJrd8+0D9G/2yZ5rO+LsDlY1y09sZ4xmufwsiZ6iNFm+o1GQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.6.0.tgz", + "integrity": "sha512-s0MWAMnjl2h0qzf02/iULHCFdv3k4Qvj9gAA7nejjPbeHg+paYJZ/MwOrk7n2+gQkztGhJxCE15J9KIv6oIIIw==", "requires": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 00a1cab..be60289 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.5.1", + "version": "0.6.0", "private": true, "scripts": { "build": "tstl", @@ -12,9 +12,9 @@ "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", - "typescript-to-lua": "1.4.4", - "typed-factorio": "1.1.0", - "typescript": "4.6.2" + "typescript-to-lua": "1.6.0", + "typed-factorio": "1.2.0", + "typescript": "4.7.4" }, "license": "UNLICENSED", "peerDependencies": {}, diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt index 3eceec0..2515009 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -50,9 +50,3 @@ suspend fun main() { } } } -// Runtime.getRuntime().addShutdownHook(Thread { -// webServer.stop() -// }) -// launch { -// } -//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebServer.kt index e3f5f4c..8533849 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebServer.kt @@ -6,7 +6,7 @@ import org.http4k.server.PolyHandler import org.http4k.server.Undertow import org.http4k.server.asServer -internal suspend fun webServer( +internal fun webServer( tileServer: WebMapTileServer, wsServer: WebsocketServer, appProps: ApplicationProperties, diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebsocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebsocketServer.kt index 47ca3de..d1ab9b6 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebsocketServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebsocketServer.kt @@ -98,10 +98,7 @@ class WebsocketServer { val clientJob = SupervisorJob(serverScope.coroutineContext.job) serverScope.launch(CoroutineName("ws-client-$id") + clientJob) { -// return serverScope.launch(CoroutineName("ws-client-$id")) { -// supervisorScope { launch { - suspendCancellableCoroutine { cont -> println("[ws-client] entering suspendCancellableCoroutine") @@ -138,11 +135,7 @@ class WebsocketServer { .onEach { msg -> println("[ws-client] sending message to $id") ws.send(WsMessage(msg)) - } - .launchIn(this) + }.launchIn(this) } - - -// } } } diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index 73c834b..c532798 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio FACTORIO_VERSION=1.1.59 -KAFKATORIO_VERSION=0.5.1 +KAFKATORIO_VERSION=0.6.0 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index 30f6a99..04f99aa 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,7 +1,7 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio GRAFANA_VERSION=8.5.0 -KAFKATORIO_VERSION=0.5.1 +KAFKATORIO_VERSION=0.6.0 KAFKA_DL_URL=https\://dlcdn.apache.org/kafka/3.2.0/kafka_2.13-3.2.0.tgz KAFKA_VERSION=3.2.0 PROMETHEUS_VERSION=v2.34.0 diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index db082c3..c97ae67 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.5.1 +KAFKATORIO_VERSION=0.6.0 From d2768c3c9ef2fa518a15e56520bc1dbe67abda31 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 19 Jun 2022 11:29:07 +0200 Subject: [PATCH 388/629] factorio mod deploy tweaks (better confirmation and link to the page) --- .../FactorioModPortalPublishClient.kt | 17 ++++++++++---- .../factoriomod/FactorioModPublishTask.kt | 22 ++++++++++++++----- modules/events-mod/package.json | 12 ++++++---- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt index 142efed..07a9e61 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt @@ -36,6 +36,7 @@ class FactorioModPortalPublishClient( private val modVersion: String, private val portalApiKey: String, private val portalUploadEndpoint: String, + private val modPortalBaseURl: String, ) { private fun client() = HttpClient(CIO) { @@ -61,11 +62,18 @@ class FactorioModPortalPublishClient( client().useToRun { val initUploadResponse = initUpload() - val confirmation = userInputHandler - .askQuestion("Are you sure you want to publish $modName:$modVersion?", "no") - .toBooleanLenient() ?: false + val enteredVersion = userInputHandler + .askQuestion( + """ + |Are you sure you want to publish $modName:$modVersion? + |Enter the version number to confirm: + """.trimMargin(), + "", + ) - if (confirmation) { + val confirmed = enteredVersion.trim() == modVersion.trim() + + if (confirmed) { upload(initUploadResponse) } else { println("aborting upload") @@ -120,6 +128,7 @@ class FactorioModPortalPublishClient( require(response.status.isSuccess() && submitUploadResponse is SubmitUploadResponse.Success) { "upload request failed" } + println("Mod uploaded successfully! ${modPortalBaseURl.removeSuffix("/")}/$modName") } companion object { diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPublishTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPublishTask.kt index 96cdc58..3a58751 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPublishTask.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPublishTask.kt @@ -44,6 +44,15 @@ abstract class FactorioModPublishTask @Inject constructor( val portalApiUrl: Property = objects.property() .convention("https://mods.factorio.com/api/v2/") + /** + * Base URL for linking to a mod page in the portal + * + * Example `https://mods.factorio.com/mod/my-mod-name` + */ + @get:Input + val modPortalBaseURl: Property = objects.property() + .convention("https://mods.factorio.com/mod/") + @get:Input val portalUploadEndpoint: Property = objects.property() .convention("mods/releases/init_upload") @@ -65,12 +74,13 @@ abstract class FactorioModPublishTask @Inject constructor( .buildString() val client = FactorioModPortalPublishClient( - userInputHandler, - distributionZip.get().asFile, - modName.get(), - modVersion.get(), - portalApiKey.get(), - portalUploadEndpoint, + userInputHandler = userInputHandler, + distributionZip = distributionZip.get().asFile, + modName = modName.get(), + modVersion = modVersion.get(), + portalApiKey = portalApiKey.get(), + portalUploadEndpoint = portalUploadEndpoint, + modPortalBaseURl = modPortalBaseURl.get(), ) client.uploadMod() diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index be60289..478d60b 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -9,7 +9,8 @@ "engines": { "node": "~14.19.1" }, - "devDependencies": {}, + "devDependencies": { + }, "dependencies": { "lua-types": "^2.11.0", "typescript-to-lua": "1.6.0", @@ -17,7 +18,10 @@ "typescript": "4.7.4" }, "license": "UNLICENSED", - "peerDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": [] + "peerDependencies": { + }, + "optionalDependencies": { + }, + "bundledDependencies": [ + ] } From 4cdbaa9dafc933842613e2974f93654b972fd687 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 20 Jun 2022 23:56:58 +0200 Subject: [PATCH 389/629] factorio mod deploy tweaks (better confirmation and link to the page) --- .../FactorioModPortalPublishClient.kt | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt index 07a9e61..cb920fe 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt @@ -71,7 +71,7 @@ class FactorioModPortalPublishClient( "", ) - val confirmed = enteredVersion.trim() == modVersion.trim() + val confirmed = enteredVersion.trim().equals(modVersion.trim(), ignoreCase = true) if (confirmed) { upload(initUploadResponse) @@ -98,7 +98,7 @@ class FactorioModPortalPublishClient( require(response.status.isSuccess()) { "init upload request failed" } return when (initUploadResponse) { - is Failure -> error(initUploadResponse) + is Failure -> error(initUploadResponse) is InitUploadResponse.Success -> initUploadResponse } } @@ -130,18 +130,4 @@ class FactorioModPortalPublishClient( } println("Mod uploaded successfully! ${modPortalBaseURl.removeSuffix("/")}/$modName") } - - companion object { - - /** - * @see org.jetbrains.kotlin.cli.common.toBooleanLenient - */ - private fun String?.toBooleanLenient(): Boolean? = when (this?.lowercase()?.trim()) { - null -> false - in listOf("yes", "true", "on", "y") -> true - in listOf("", "no", "false", "off", "n") -> false - else -> null - } - - } } From 326f081a5e4c3a08467ae9e482397d6a88bed87b Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 20 Jun 2022 23:57:24 +0200 Subject: [PATCH 390/629] remove node js stuff from gradle (might be causing cache issues?) --- .../kafkatorio/lang/kotlin-js.gradle.kts | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts index 68bf4cf..6d2168b 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-js.gradle.kts @@ -3,7 +3,7 @@ package dev.adamko.kafkatorio.lang import dev.adamko.kafkatorio.Versions import dev.adamko.kafkatorio.relocateKotlinJsStore import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject -import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask +//import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask plugins { @@ -11,15 +11,15 @@ plugins { id("dev.adamko.kafkatorio.base") } -dependencies { - implementation( - project.dependencies.platform( - "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${Versions.kotlinWrappers}" - ) - ) -} +//dependencies { +// implementation( +// project.dependencies.platform( +// "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${Versions.kotlinWrappers}" +// ) +// ) +//} -val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) +//val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) //fun NpmTask.setNodeModulesPath(path: String): Unit = // environment.put("NODE_PATH", path) @@ -30,16 +30,16 @@ val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) // https://github.com/node-gradle/gradle-node-plugin/issues/150 // https://github.com/lamba92/kotlingram/blob/master/examples/js-bot/build.gradle.kts -val nodePath: Directory by extra { - val file = rootPackageJson.rootPackageJson.parentFile.normalize() - logger.info("Kotlin/JS NODE_PATH: $file") - project.layout.dir(project.provider { file }).get() -} +//val nodePath: Directory by extra { +// val file = rootPackageJson.rootPackageJson.parentFile.normalize() +// logger.info("Kotlin/JS NODE_PATH: $file") +// project.layout.dir(project.provider { file }).get() +//} -val nodeModulesDir: Directory by extra { - val file = nodePath.dir(NpmProject.NODE_MODULES) - logger.info("Kotlin/JS NODE_MODULES: $file") - file -} +//val nodeModulesDir: Directory by extra { +// val file = nodePath.dir(NpmProject.NODE_MODULES) +// logger.info("Kotlin/JS NODE_MODULES: $file") +// file +//} relocateKotlinJsStore() From e56ecb7d36379f070cb99c3d84e8c0f60011b0e7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 20 Jun 2022 23:59:22 +0200 Subject: [PATCH 391/629] bump kvision, kt js wrappers --- .../kotlin/dev/adamko/kafkatorio/common.kt | 13 +- gradle.properties | 7 - gradle/kotlin-js-store/yarn.lock | 156 +++++++----------- gradle/libs.versions.toml | 6 +- modules/web-map/build.gradle.kts | 18 +- 5 files changed, 76 insertions(+), 124 deletions(-) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt index 27da996..d86f12f 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt @@ -1,9 +1,10 @@ package dev.adamko.kafkatorio +import io.kvision.gradle.KVisionExtension import kotlinx.serialization.json.Json import org.gradle.api.Project import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.extra +import org.gradle.kotlin.dsl.findByType import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension val jsonMapper = Json { @@ -13,10 +14,7 @@ val jsonMapper = Json { object Versions { - const val node = "14.19.1" - - const val kotlinWrappers = "1.0.0-pre.336" } @@ -38,7 +36,8 @@ fun Project.relocateKotlinJsStore() { // project.rootDir.resolve("gradle/kotlin-js-store") // } - // KVision tries to be clever too - see io.kvision.gradle.KVisionGradleSubplugin - rootProject.extra.set("io.kvision.plugin.enableHiddenKotlinJsStore", "false") - + // KVision tries to be clever too + project.extensions.findByType()?.apply { + enableHiddenKotlinJsStore.set(false) + } } diff --git a/gradle.properties b/gradle.properties index 34055e9..0298688 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,12 +12,5 @@ org.gradle.kotlin.dsl.precompiled.accessors.strict=true org.gradle.parallel=true -io.kvision.plugin.enableGradleTasks=true -io.kvision.plugin.enableWorkerTasks=false -io.kvision.plugin.enableWebpackVersions=false -io.kvision.plugin.enableHiddenKotlinJsStore=false -io.kvision.plugin.enableSecureResolutions=false -io.kvision.plugin.enableBackendTasks=false - # pRoJeCtS mUsT bE cOnFiGuRiNg org.gradle.configureondemand=false diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index 54fe4eb..f458026 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -9,6 +9,11 @@ dependencies: regenerator-runtime "^0.13.4" +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + "@discoveryjs/json-ext@^0.5.0": version "0.5.7" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" @@ -352,19 +357,19 @@ "@webassemblyjs/ast" "1.11.1" "@xtuc/long" "4.2.2" -"@webpack-cli/configtest@^1.1.1", "@webpack-cli/configtest@^1.2.0": +"@webpack-cli/configtest@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== -"@webpack-cli/info@^1.4.1", "@webpack-cli/info@^1.5.0": +"@webpack-cli/info@^1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== dependencies: envinfo "^7.7.3" -"@webpack-cli/serve@^1.6.1", "@webpack-cli/serve@^1.7.0": +"@webpack-cli/serve@^1.7.0": version "1.7.0" resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== @@ -564,6 +569,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -637,10 +649,10 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chart.js@^3.7.1: - version "3.7.1" - resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.7.1.tgz#0516f690c6a8680c6c707e31a4c1807a6f400ada" - integrity sha512-8knRegQLFnPQAheZV8MjxIXc5gQEfDFD897BJgv/klO/vtIyFFmgMXrNfgrXpbTr/XbTturxRgxIXx/Y+ASJBA== +chart.js@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.8.0.tgz#c6c14c457b9dc3ce7f1514a59e9b262afd6f1a94" + integrity sha512-cr8xhrXjLIXVLOBZPkBZVF6NDeiVIrPLHcMhnON7UufudL+CNeRrD+wpYanswlm8NpudMdrt3CHoLMQMxJhHRg== chokidar@3.5.3, chokidar@^3.5.1, chokidar@^3.5.3: version "3.5.3" @@ -709,11 +721,6 @@ colorette@^2.0.10, colorette@^2.0.14: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== -colors@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -864,14 +871,7 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4.3.3: - version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== - dependencies: - ms "2.1.2" - -debug@^4.1.0, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: +debug@4.3.4, debug@^4.1.0, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -1011,7 +1011,7 @@ engine.io@~6.2.0: engine.io-parser "~5.0.3" ws "~8.2.3" -enhanced-resolve@^5.8.3: +enhanced-resolve@^5.9.3: version "5.9.3" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz#44a342c012cbc473254af5cc6ae20ebd0aae5d88" integrity sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow== @@ -1400,11 +1400,6 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - handle-thing@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" @@ -1699,10 +1694,10 @@ js-yaml@4.1.0: dependencies: argparse "^2.0.1" -json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== +json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-schema-traverse@^0.4.1: version "0.4.1" @@ -1760,15 +1755,15 @@ karma-webpack@5.0.0: minimatch "^3.0.4" webpack-merge "^4.1.5" -karma@6.3.16: - version "6.3.16" - resolved "https://registry.yarnpkg.com/karma/-/karma-6.3.16.tgz#76d1a705fd1cf864ee5ed85270b572641e0958ef" - integrity sha512-nEU50jLvDe5yvXqkEJRf8IuvddUkOY2x5Xc4WXHz6dxINgGDrgD2uqQWeVrJs4hbfNaotn+HQ1LZJ4yOXrL7xQ== +karma@6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.0.tgz#82652dfecdd853ec227b74ed718a997028a99508" + integrity sha512-s8m7z0IF5g/bS5ONT7wsOavhW4i4aFkzD4u4wgzAQWT4HGUeWI3i21cK2Yz6jndMAeHETp5XuNsRoyGJZXVd4w== dependencies: + "@colors/colors" "1.5.0" body-parser "^1.19.0" braces "^3.0.2" chokidar "^3.5.1" - colors "1.4.0" connect "^3.7.0" di "^0.0.1" dom-serialize "^2.2.1" @@ -1784,7 +1779,7 @@ karma@6.3.16: qjobs "^1.2.0" range-parser "^1.2.1" rimraf "^3.0.2" - socket.io "^4.2.0" + socket.io "^4.4.1" source-map "^0.6.1" tmp "^0.2.1" ua-parser-js "^0.7.30" @@ -1922,12 +1917,12 @@ minimalistic-assert@^1.0.0: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== dependencies: - brace-expansion "^1.1.7" + brace-expansion "^2.0.1" minimatch@^3.0.4: version "3.1.2" @@ -1948,32 +1943,30 @@ mkdirp@^0.5.5: dependencies: minimist "^1.2.6" -mocha@9.2.1: - version "9.2.1" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.1.tgz#a1abb675aa9a8490798503af57e8782a78f1338e" - integrity sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ== +mocha@10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.0.0.tgz#205447d8993ec755335c4b13deba3d3a13c4def9" + integrity sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA== dependencies: "@ungap/promise-all-settled" "1.1.2" ansi-colors "4.1.1" browser-stdout "1.3.1" chokidar "3.5.3" - debug "4.3.3" + debug "4.3.4" diff "5.0.0" escape-string-regexp "4.0.0" find-up "5.0.0" glob "7.2.0" - growl "1.10.5" he "1.2.0" js-yaml "4.1.0" log-symbols "4.1.0" - minimatch "3.0.4" + minimatch "5.0.1" ms "2.1.3" - nanoid "3.2.0" + nanoid "3.3.3" serialize-javascript "6.0.0" strip-json-comments "3.1.1" supports-color "8.1.1" - which "2.0.2" - workerpool "6.2.0" + workerpool "6.2.1" yargs "16.2.0" yargs-parser "20.2.4" yargs-unparser "2.0.0" @@ -2001,12 +1994,7 @@ multicast-dns@^7.2.5: dns-packet "^5.2.2" thunky "^1.0.2" -nanoid@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" - integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== - -nanoid@^3.3.1: +nanoid@3.3.3, nanoid@^3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== @@ -2570,7 +2558,7 @@ socket.io-parser@~4.0.4: component-emitter "~1.3.0" debug "~4.3.1" -socket.io@^4.2.0: +socket.io@^4.4.1: version "4.5.1" resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.5.1.tgz#aa7e73f8a6ce20ee3c54b2446d321bbb6b1a9029" integrity sha512-0y9pnIso5a9i+lJmsCdtmTTgJFFSvNQKDnPQRz28mGNnxbmqYg2QPtJTLFxhymFZhAIn50eHAKzJeiNaKr+yUQ== @@ -2904,24 +2892,6 @@ webpack-cli@4.10.0: rechoir "^0.7.0" webpack-merge "^5.7.3" -webpack-cli@4.9.2: - version "4.9.2" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.2.tgz#77c1adaea020c3f9e2db8aad8ea78d235c83659d" - integrity sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ== - dependencies: - "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.1.1" - "@webpack-cli/info" "^1.4.1" - "@webpack-cli/serve" "^1.6.1" - colorette "^2.0.14" - commander "^7.0.0" - execa "^5.0.0" - fastest-levenshtein "^1.0.12" - import-local "^3.0.2" - interpret "^2.2.0" - rechoir "^0.7.0" - webpack-merge "^5.7.3" - webpack-dev-middleware@^5.3.1: version "5.3.3" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" @@ -2988,10 +2958,10 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@5.69.1: - version "5.69.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.69.1.tgz#8cfd92c192c6a52c99ab00529b5a0d33aa848dc5" - integrity sha512-+VyvOSJXZMT2V5vLzOnDuMz5GxEqLk7hKWQ56YxPW/PQRUuKimPqmEIJOx8jHYeyo65pKbapbW464mvsKbaj4A== +webpack@5.73.0: + version "5.73.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.73.0.tgz#bbd17738f8a53ee5760ea2f59dce7f3431d35d38" + integrity sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" @@ -3002,13 +2972,13 @@ webpack@5.69.1: acorn-import-assertions "^1.7.6" browserslist "^4.14.5" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.8.3" + enhanced-resolve "^5.9.3" es-module-lexer "^0.9.0" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" graceful-fs "^4.2.9" - json-parse-better-errors "^1.0.2" + json-parse-even-better-errors "^2.3.1" loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" @@ -3032,13 +3002,6 @@ websocket-extensions@>=0.1.1: resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== -which@2.0.2, which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - which@^1.2.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -3046,15 +3009,22 @@ which@^1.2.1: dependencies: isexe "^2.0.0" +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + wildcard@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== -workerpool@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" - integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== wrap-ansi@^7.0.0: version "7.0.0" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 279301b..7cda9a6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ kotlin = "1.7.0" camel-kafkaConnectors = "0.11.0" http4k = "4.25.16.2" kafka = "3.2.0" -kvision = "5.10.1" +kvision = "5.11.0" log4j2 = "2.17.2" qosLogback = "1.2.11" slf4j = "1.7.36" @@ -24,7 +24,7 @@ kotlinx-serialization = "1.3.3" kxs-charleskornKaml = "0.44.0" kxs-mamoeYamlkt = "0.12.0" -kotlinJsWrappers = "1.0.0-pre.339" +kotlinJsWrappers = "1.0.0-pre.346" kotlinx-html = "0.7.5" kotlinx-nodejs = "0.0.7" kotlinx-coroutines = "1.6.1" @@ -49,7 +49,7 @@ grafana = "8.5.0" prometheus = "v2.34.0" ## gradle plugins ## -gradleNodePlugin = "3.3.0" +gradleNodePlugin = "3.3.0" # https://github.com/node-gradle/gradle-node-plugin/releases ######### [plugins] diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 667e1ed..a714375 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -8,19 +8,14 @@ import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension plugins { dev.adamko.kafkatorio.lang.`kotlin-js` // dev.adamko.kafkatorio.lang.`kotlin-multiplatform` - kotlin("plugin.serialization") id("io.kvision") + kotlin("plugin.serialization") } -project.ext.set("io.kvision.plugin.enableGradleTasks", false) -project.ext.set("io.kvision.plugin.enableWorkerTasks", false) -project.ext.set("io.kvision.plugin.enableWebpackVersions", false) -project.ext.set("io.kvision.plugin.enableHiddenKotlinJsStore", false) -project.ext.set("io.kvision.plugin.enableSecureResolutions", false) -project.ext.set("io.kvision.plugin.enableBackendTasks", false) - - +kvision { + enableHiddenKotlinJsStore.set(false) +} rootProject.extensions.configure { // https://github.com/rjaros/kvision/issues/410 @@ -146,11 +141,6 @@ kotlin { kvision("kvision-redux") kvision("kvision-state-flow") - implementation(dependencies.platform(libs.kotlinx.coroutines.bom)) - implementation(dependencies.platform(libs.kotlin.jsWrappers.bom)) - - implementation(libs.kotlinx.coroutines.core) - implementation(devNpm("http-proxy-middleware", "^2.0.6")) implementation(dependencies.platform(devNpm("http-proxy-middleware", "^2.0.6"))) From e0f689c538c942c5d4e2380242f6234799948652 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 20 Jun 2022 23:59:57 +0200 Subject: [PATCH 392/629] gradle docker config tidy up --- buildSrc/repositories.settings.gradle.kts | 6 ++--- buildSrc/settings.gradle.kts | 2 ++ .../dev/adamko/kafkatorio/base.gradle.kts | 14 +---------- .../infra/docker-compose.gradle.kts | 4 ++++ modules/events-mod/package.json | 12 ++++------ .../infra-factorio-server/build.gradle.kts | 14 ----------- .../kafkatorio/webmap/externals/leaflet.kt | 23 ++++++++++++++----- 7 files changed, 31 insertions(+), 44 deletions(-) diff --git a/buildSrc/repositories.settings.gradle.kts b/buildSrc/repositories.settings.gradle.kts index 8143698..3568925 100644 --- a/buildSrc/repositories.settings.gradle.kts +++ b/buildSrc/repositories.settings.gradle.kts @@ -12,9 +12,9 @@ dependencyResolutionManagement { repositories { myMavenLocal() mavenCentral() - maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") { - mavenContent { snapshotsOnly() } - } +// maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") { +// mavenContent { snapshotsOnly() } +// } jitpack() gradlePluginPortal() diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts index f19b951..903a987 100644 --- a/buildSrc/settings.gradle.kts +++ b/buildSrc/settings.gradle.kts @@ -1,3 +1,5 @@ +rootProject.name = "buildSrc" + apply(from = "./repositories.settings.gradle.kts") @Suppress("UnstableApiUsage") // Central declaration of repositories is an incubating feature diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts index b66ec22..1352a4e 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/base.gradle.kts @@ -8,6 +8,7 @@ plugins { idea } + group = rootProject.group version = rootProject.version @@ -18,19 +19,6 @@ tasks.withType().configureEach { } -val hardReset by tasks.registering(Delete::class) { - group = rootProject.name - doFirst("hardResetConfirmation") { - val answer = project.serviceOf() - .askYesNoQuestion("Are you sure you want to permanently delete Kafkatorio data?") - - if (answer != true) { - throw GradleException("Aborting hard reset") - } - } -} - - tasks.withType().configureEach { exclude("**/.secret.*") } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts index 7bb535a..830c9fb 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/infra/docker-compose.gradle.kts @@ -23,6 +23,7 @@ val dockerUp by tasks.registering(Exec::class) { commandLine = parseSpaceSeparatedArgs(""" docker-compose up -d """) } + val dockerDown by tasks.registering(Exec::class) { group = dockerComposeTaskGroup @@ -42,11 +43,13 @@ val dockerRemove by tasks.registering(Exec::class) { commandLine = parseSpaceSeparatedArgs(""" docker-compose rm --stop -v -f """) } + afterEvaluate { tasks.named("processRun") { dependsOn(dockerUp, dockerEnv) } tasks.named("processKill") { dependsOn(dockerDown) } } + val dockerEnv by tasks.registering(WriteProperties::class) { group = dockerComposeTaskGroup @@ -60,4 +63,5 @@ val dockerEnv by tasks.registering(WriteProperties::class) { ) } + tasks.assemble { dependsOn(dockerEnv) } diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 478d60b..be60289 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -9,8 +9,7 @@ "engines": { "node": "~14.19.1" }, - "devDependencies": { - }, + "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", "typescript-to-lua": "1.6.0", @@ -18,10 +17,7 @@ "typescript": "4.7.4" }, "license": "UNLICENSED", - "peerDependencies": { - }, - "optionalDependencies": { - }, - "bundledDependencies": [ - ] + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] } diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 7cff893..7d75285 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -57,17 +57,3 @@ idea { excludeDirs.add(file("src/factorio-server")) } } - - -tasks.hardReset { - - dependsOn(tasks.dockerRemove) - - delete( - factorioServerDataDir.dir("saves"), - factorioServerDataDir.dir("temp"), - factorioServerDataDir.file("factorio-current.log"), - factorioServerDataDir.file("factorio-previous.log"), - factorioServerDataDir.file(".lock"), - ) -} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/externals/leaflet.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/externals/leaflet.kt index d7a3195..0c59e22 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/externals/leaflet.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/externals/leaflet.kt @@ -18,16 +18,27 @@ typealias TileOnLoadFn = (done: DoneCallback, tile: HTMLElement) -> Unit sealed interface PolylinePathPoints { - value class D1(val points: Array) : PolylinePathPoints - value class D2(val points: Array>) : PolylinePathPoints - value class D3(val points: Array>>) : PolylinePathPoints + value class D1(val points: List) : PolylinePathPoints { + constructor(points: Array) + : this(points.toList()) + } + + value class D2(val points: List>) : PolylinePathPoints { + constructor(points: Array>) + : this(points.map { x -> x.toList() }.toList()) + } + + value class D3(val points: List>>) : PolylinePathPoints { + constructor(points: Array>>) + : this(points.map { x -> x.map { y -> y.toList() } }.toList()) + } } inline fun Polyline<*>.getLatLngs2(): PolylinePathPoints? { return when (val points = this.getLatLngs()) { - is Array -> PolylinePathPoints.D1(points as Array) - is Array> -> PolylinePathPoints.D2(points as Array>) - is Array>> -> PolylinePathPoints.D3(points as Array>>) + is Array -> PolylinePathPoints.D1(points.unsafeCast>()) + is Array> -> PolylinePathPoints.D2(points.unsafeCast>>()) + is Array>> -> PolylinePathPoints.D3(points.unsafeCast>>>()) else -> null } } From b56c0df824c15698b050888d3c71a1d2c68e9d03 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 21 Jun 2022 00:00:26 +0200 Subject: [PATCH 393/629] start getting docker images working... --- .dockerignore | 17 +++++++++++ kafkatorio.Dockerfile | 20 +++++++++++++ modules/events-server/docker/.dockerignore | 21 ++++++++++++++ modules/events-server/docker/.env | 3 ++ modules/events-server/docker/Dockerfile | 22 ++++++++++++++ .../events-server/docker/docker-compose.yml | 29 +++++++++++++++++++ modules/web-map/docker/.env | 3 ++ modules/web-map/docker/Dockerfile | 2 ++ modules/web-map/docker/docker-compose.yml | 19 ++++++++++++ 9 files changed, 136 insertions(+) create mode 100644 .dockerignore create mode 100644 kafkatorio.Dockerfile create mode 100644 modules/events-server/docker/.dockerignore create mode 100644 modules/events-server/docker/.env create mode 100644 modules/events-server/docker/Dockerfile create mode 100644 modules/events-server/docker/docker-compose.yml create mode 100644 modules/web-map/docker/.env create mode 100644 modules/web-map/docker/Dockerfile create mode 100644 modules/web-map/docker/docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..c9cb9e5 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,17 @@ + +# exclude hidden dirs .git etc. +.* + +# ignore any files that start with '.secret' +#.secret.* + +### Gradle ### +build/ +gradle +src +#.gradle + +# IntelliJ +#.idea/ +#out/ +#*.iml diff --git a/kafkatorio.Dockerfile b/kafkatorio.Dockerfile new file mode 100644 index 0000000..cc69c2f --- /dev/null +++ b/kafkatorio.Dockerfile @@ -0,0 +1,20 @@ +# syntax=docker/dockerfile:1 + +ARG KAFKATORIO_VERSION + +#FROM gradle:7.4.2-jdk11 as builder +FROM eclipse-temurin:11-jdk-jammy as builder + +WORKDIR /app + +ENV GRADLE_USER_HOME /gradle-home +ENV GRADLE_OPTS "-Dorg.gradle.daemon=false -Dorg.gradle.logging.stacktrace=full -Dorg.gradle.console=plain" + +COPY . . +RUN ./gradlew assemble + + + +FROM builder + +RUN ./gradlew assemble diff --git a/modules/events-server/docker/.dockerignore b/modules/events-server/docker/.dockerignore new file mode 100644 index 0000000..f9f2ef3 --- /dev/null +++ b/modules/events-server/docker/.dockerignore @@ -0,0 +1,21 @@ +# +## exclude hidden dirs .git etc. +#.* +# +## ignore any files that start with '.secret' +##.secret.* +# +#### Gradle ### +#build/ +#!build/distributions +# +#src +# +#kafkatorio-tiles/ +#kafka-state/ +##.gradle +# +## IntelliJ +##.idea/ +##out/ +##*.iml diff --git a/modules/events-server/docker/.env b/modules/events-server/docker/.env new file mode 100644 index 0000000..db082c3 --- /dev/null +++ b/modules/events-server/docker/.env @@ -0,0 +1,3 @@ +# Do not edit manually. This file was created with task 'dockerEnv' +COMPOSE_PROJECT_NAME=kafkatorio +KAFKATORIO_VERSION=0.5.1 diff --git a/modules/events-server/docker/Dockerfile b/modules/events-server/docker/Dockerfile new file mode 100644 index 0000000..9c350df --- /dev/null +++ b/modules/events-server/docker/Dockerfile @@ -0,0 +1,22 @@ +# syntax=docker/dockerfile:1 + +FROM eclipse-temurin:11-jdk-jammy +ARG KAFKATORIO_VERSION=0.5.1 +ARG DIST_DIR="../build/distributions/" + +WORKDIR /app + +ENV SERVER_PORT=8080 +EXPOSE $SERVER_PORT + +ENV TILE_DIR="/app/tiles" +ENV KAFKA_STREAMS_STATE_DIR="/app/kafka-state" +VOLUME ${TILE_DIR} \ + ${KAFKA_STREAMS_STATE_DIR} + +COPY ${DIST_DIR}/events-server-${KAFKATORIO_VERSION}.tar events-server.tar + +RUN tar -xf events-server.tar --strip-components=1 \ + && rm events-server.tar + +ENTRYPOINT /app/bin/events-server diff --git a/modules/events-server/docker/docker-compose.yml b/modules/events-server/docker/docker-compose.yml new file mode 100644 index 0000000..8326de9 --- /dev/null +++ b/modules/events-server/docker/docker-compose.yml @@ -0,0 +1,29 @@ +version: "3.9" + +services: + + events-server: + image: kafkatorio/events-server:${KAFKATORIO_VERSION} + container_name: events-server + build: + context: .. + dockerfile: ./docker/Dockerfile + args: + KAFKATORIO_VERSION: ${KAFKATORIO_VERSION} + DIST_DIR: "./build/distributions/" + environment: + KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" + KAFKA_STREAMS_STATE_DIR: "http://kafka:29092" + SERVER_PORT: "12081" +# ports: +# - "12081:12081" # http and ws + networks: + - "kafka-nw" + +networks: + kafka-nw: + name: "kafka-nw" + external: true + kafkatorio-nw: + name: "kafkatorio-nw" + external: true diff --git a/modules/web-map/docker/.env b/modules/web-map/docker/.env new file mode 100644 index 0000000..db082c3 --- /dev/null +++ b/modules/web-map/docker/.env @@ -0,0 +1,3 @@ +# Do not edit manually. This file was created with task 'dockerEnv' +COMPOSE_PROJECT_NAME=kafkatorio +KAFKATORIO_VERSION=0.5.1 diff --git a/modules/web-map/docker/Dockerfile b/modules/web-map/docker/Dockerfile new file mode 100644 index 0000000..afc3caa --- /dev/null +++ b/modules/web-map/docker/Dockerfile @@ -0,0 +1,2 @@ +FROM nginx +COPY ./build/distributions /usr/share/nginx/html diff --git a/modules/web-map/docker/docker-compose.yml b/modules/web-map/docker/docker-compose.yml new file mode 100644 index 0000000..d1acd28 --- /dev/null +++ b/modules/web-map/docker/docker-compose.yml @@ -0,0 +1,19 @@ +version: "3.9" + +services: + + kafkatorio-web-map: + image: adamko-dev/kafkatorio-web-map + container_name: kafkatorio-web-map + build: + context: ".." + dockerfile: ./docker/Dockerfile + ports: + - "12081:80" + networks: + - "kafkatorio-nw" + +networks: + kafkatorio-nw: + name: "kafkatorio-nw" + external: true From 8a9fea51ebc48a346c98f23c53f43dcbb2fa1c2b Mon Sep 17 00:00:00 2001 From: Adam Semenenko <897017+aSemy@users.noreply.github.com> Date: Mon, 20 Jun 2022 23:11:09 +0100 Subject: [PATCH 394/629] +x gradlew --- gradlew | 0 gradlew.bat | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 gradlew mode change 100644 => 100755 gradlew.bat diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/gradlew.bat b/gradlew.bat old mode 100644 new mode 100755 From b9593e4b4e02e96a91fb771eef915a74951607fa Mon Sep 17 00:00:00 2001 From: Adam Semenenko <897017+aSemy@users.noreply.github.com> Date: Mon, 20 Jun 2022 23:11:26 +0100 Subject: [PATCH 395/629] +x gradlew --- gradlew | 0 gradlew.bat | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 gradlew mode change 100755 => 100644 gradlew.bat diff --git a/gradlew b/gradlew old mode 100755 new mode 100644 diff --git a/gradlew.bat b/gradlew.bat old mode 100755 new mode 100644 From 110bd1c2fcdb3e1fec419e6e31eedb5b3c3b9457 Mon Sep 17 00:00:00 2001 From: Adam Semenenko <897017+aSemy@users.noreply.github.com> Date: Mon, 20 Jun 2022 23:12:05 +0100 Subject: [PATCH 396/629] +x gradlew --- gradlew | 0 gradlew.bat | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 gradlew mode change 100644 => 100755 gradlew.bat diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/gradlew.bat b/gradlew.bat old mode 100644 new mode 100755 From ca53b4dead03d6497de72fea26e55a456364b293 Mon Sep 17 00:00:00 2001 From: Adam Semenenko <897017+aSemy@users.noreply.github.com> Date: Mon, 20 Jun 2022 23:12:30 +0100 Subject: [PATCH 397/629] +x gradlew --- gradlew | 0 gradlew.bat | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 gradlew mode change 100755 => 100644 gradlew.bat diff --git a/gradlew b/gradlew old mode 100755 new mode 100644 diff --git a/gradlew.bat b/gradlew.bat old mode 100755 new mode 100644 From b13bd74c11ce643663e59d86e2e35a4d8280ea43 Mon Sep 17 00:00:00 2001 From: Adam Semenenko <897017+aSemy@users.noreply.github.com> Date: Mon, 20 Jun 2022 23:23:26 +0100 Subject: [PATCH 398/629] changeing permissions --- gradlew | 0 gradlew.bat | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 gradlew mode change 100644 => 100755 gradlew.bat diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/gradlew.bat b/gradlew.bat old mode 100644 new mode 100755 From aeb5d2a69d025358349a71c88fcf53e15a199732 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 23 Jun 2022 23:47:10 +0200 Subject: [PATCH 399/629] rm unused docker file --- .dockerignore | 17 ----------------- kafkatorio.Dockerfile | 20 -------------------- 2 files changed, 37 deletions(-) delete mode 100644 .dockerignore delete mode 100644 kafkatorio.Dockerfile diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index c9cb9e5..0000000 --- a/.dockerignore +++ /dev/null @@ -1,17 +0,0 @@ - -# exclude hidden dirs .git etc. -.* - -# ignore any files that start with '.secret' -#.secret.* - -### Gradle ### -build/ -gradle -src -#.gradle - -# IntelliJ -#.idea/ -#out/ -#*.iml diff --git a/kafkatorio.Dockerfile b/kafkatorio.Dockerfile deleted file mode 100644 index cc69c2f..0000000 --- a/kafkatorio.Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -# syntax=docker/dockerfile:1 - -ARG KAFKATORIO_VERSION - -#FROM gradle:7.4.2-jdk11 as builder -FROM eclipse-temurin:11-jdk-jammy as builder - -WORKDIR /app - -ENV GRADLE_USER_HOME /gradle-home -ENV GRADLE_OPTS "-Dorg.gradle.daemon=false -Dorg.gradle.logging.stacktrace=full -Dorg.gradle.console=plain" - -COPY . . -RUN ./gradlew assemble - - - -FROM builder - -RUN ./gradlew assemble From 3fa4eba4b394c604a3774378cbf90eca1530c583 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Thu, 23 Jun 2022 23:59:48 +0200 Subject: [PATCH 400/629] try making files in build script system independent (temp fix) --- .../infra-factorio-client/build.gradle.kts | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index 8288025..b06d9c9 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -11,9 +11,19 @@ plugins { description = "Start the Factorio game client" -val clientModsDirectory = file("""D:\Users\Adam\AppData\Roaming\Factorio\mods""") +val clientModsDirectory: DirectoryProperty = objects.directoryProperty().apply { + val modDir = File("""D:\Users\Adam\AppData\Roaming\Factorio\mods""") + if (modDir.exists()) { + set(modDir) + } +} val factorioGameId = "427520" -val steamExe = """C:\Program Files (x86)\Steam\steam.exe""" +val steamExe: RegularFileProperty = objects.fileProperty().apply { + val steam = File("""C:\Program Files (x86)\Steam\steam.exe""") + if (steam.exists()) { + set(steam) + } +} val factorioMod: Configuration by configurations.creating { asConsumer() @@ -29,6 +39,8 @@ val deployModToClient by tasks.registering(Copy::class) { description = "Copy the mod to the Factorio client" group = project.name + onlyIf { clientModsDirectory.orNull?.asFile?.exists() == true } + from(factorioMod) into(clientModsDirectory) @@ -47,6 +59,8 @@ val clientLaunch by tasks.registering(Exec::class) { group = project.name onlyIf(!serviceOf().isFactorioRunning()) + onlyIf { steamExe.orNull?.asFile?.exists() == true } + onlyIf { clientModsDirectory.orNull?.asFile?.exists() == true } dependsOn(deployModToClient) mustRunAfter(clientKill, ":modules:infra-factorio-server:processRun") @@ -54,7 +68,7 @@ val clientLaunch by tasks.registering(Exec::class) { commandLine = parseSpaceSeparatedArgs( // """explorer "steam://rungameid/$factorioGameId// --mp-connect localhost/" """ // not working // """explorer "steam://run/$factorioGameId//--mp-connect localhost/" """ // works! But has annoying pop-up - """ $steamExe -applaunch $factorioGameId --mp-connect localhost --mod-directory $clientModsDirectory """ + """ ${steamExe.asFile.get().canonicalPath} -applaunch $factorioGameId --mp-connect localhost --mod-directory ${clientModsDirectory.asFile.get().canonicalPath} """ ) doFirst { logger.lifecycle("Launching factorio.exe") } } From 82c8b9f25b806606e0a00cb2a237a53218be153d Mon Sep 17 00:00:00 2001 From: Adam Semenenko <897017+aSemy@users.noreply.github.com> Date: Thu, 23 Jun 2022 23:00:42 +0100 Subject: [PATCH 401/629] add traefik nw to docker files --- modules/events-server/docker/docker-compose.yml | 4 ++++ modules/infra-kafka-cluster/src/docker-compose.yml | 8 ++++++-- modules/web-map/docker/docker-compose.yml | 4 ++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/modules/events-server/docker/docker-compose.yml b/modules/events-server/docker/docker-compose.yml index 8326de9..28781c3 100644 --- a/modules/events-server/docker/docker-compose.yml +++ b/modules/events-server/docker/docker-compose.yml @@ -19,6 +19,7 @@ services: # - "12081:12081" # http and ws networks: - "kafka-nw" + - "traefik-nw" networks: kafka-nw: @@ -27,3 +28,6 @@ networks: kafkatorio-nw: name: "kafkatorio-nw" external: true + traefik-nw: + name: "traefik-nw" + external: true diff --git a/modules/infra-kafka-cluster/src/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml index 774e776..6c67291 100644 --- a/modules/infra-kafka-cluster/src/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -33,8 +33,9 @@ services: restart: "unless-stopped" networks: - "kafka-nw" - ports: - - "8080:8080" + - "traefik-nw" + # ports: + # - "8080:8080" environment: KAFKA_CLUSTERS_0_NAME: "${COMPOSE_PROJECT_NAME}" KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: "kafka:29092" @@ -104,3 +105,6 @@ networks: name: "kafka-nw" kafkatorio-nw: name: "kafkatorio-nw" + traefik-nw: + name: "traefik-nw" + external: true diff --git a/modules/web-map/docker/docker-compose.yml b/modules/web-map/docker/docker-compose.yml index d1acd28..3673e21 100644 --- a/modules/web-map/docker/docker-compose.yml +++ b/modules/web-map/docker/docker-compose.yml @@ -12,8 +12,12 @@ services: - "12081:80" networks: - "kafkatorio-nw" + - "traefik-nw" networks: kafkatorio-nw: name: "kafkatorio-nw" external: true + traefik-nw: + name: "traefik-nw" + external: true From 4c94a410290996fe53816bbbdf3ef85891b76d51 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 24 Jun 2022 00:04:50 +0200 Subject: [PATCH 402/629] more temp fixes for making files in build script system independent --- modules/infra-factorio-client/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index b06d9c9..779c712 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -68,7 +68,7 @@ val clientLaunch by tasks.registering(Exec::class) { commandLine = parseSpaceSeparatedArgs( // """explorer "steam://rungameid/$factorioGameId// --mp-connect localhost/" """ // not working // """explorer "steam://run/$factorioGameId//--mp-connect localhost/" """ // works! But has annoying pop-up - """ ${steamExe.asFile.get().canonicalPath} -applaunch $factorioGameId --mp-connect localhost --mod-directory ${clientModsDirectory.asFile.get().canonicalPath} """ + """ ${steamExe.asFile.orNull?.canonicalPath} -applaunch $factorioGameId --mp-connect localhost --mod-directory ${clientModsDirectory.asFile.orNull?.canonicalPath} """ ) doFirst { logger.lifecycle("Launching factorio.exe") } } From 62f37353bae748faef79f6100a4266eafa66c2e7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 24 Jun 2022 14:15:22 +0200 Subject: [PATCH 403/629] try fixing kafka kraft dockerfile --- modules/infra-kafka-cluster/src/kafka.Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/infra-kafka-cluster/src/kafka.Dockerfile b/modules/infra-kafka-cluster/src/kafka.Dockerfile index 9dd574d..077cdc5 100644 --- a/modules/infra-kafka-cluster/src/kafka.Dockerfile +++ b/modules/infra-kafka-cluster/src/kafka.Dockerfile @@ -35,14 +35,14 @@ EXPOSE 9092 9093 RUN echo "$(./bin/kafka-storage.sh random-uuid)" > cluster_id \ && echo "Generated a Kafka Cluster ID: $(cat cluster_id)" +COPY ./kafka-server.properties ./server.properties + # Format storage directories RUN ./bin/kafka-storage.sh format \ --ignore-formatted \ - --config ./config/kraft/server.properties \ + --config ./server.properties \ --cluster-id "$(cat cluster_id)" -COPY ./kafka-server.properties ./server.properties - # launch the broker in KRaft mode, which means that it runs without ZooKeeper ENTRYPOINT ["./bin/kafka-server-start.sh", "./server.properties"] From b155bb8bc137f1add70cec36bf28c710631339f4 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 24 Jun 2022 14:49:52 +0200 Subject: [PATCH 404/629] format kafka cluster in entrypoint --- modules/infra-kafka-cluster/src/entrypoint.sh | 6 ++++++ modules/infra-kafka-cluster/src/kafka.Dockerfile | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 modules/infra-kafka-cluster/src/entrypoint.sh diff --git a/modules/infra-kafka-cluster/src/entrypoint.sh b/modules/infra-kafka-cluster/src/entrypoint.sh new file mode 100644 index 0000000..fe91dbe --- /dev/null +++ b/modules/infra-kafka-cluster/src/entrypoint.sh @@ -0,0 +1,6 @@ +./bin/kafka-storage.sh format \ + --ignore-formatted \ + --config ./server.properties \ + --cluster-id "$(cat cluster_id)" + +./bin/kafka-server-start.sh ./server.properties diff --git a/modules/infra-kafka-cluster/src/kafka.Dockerfile b/modules/infra-kafka-cluster/src/kafka.Dockerfile index 077cdc5..60c1507 100644 --- a/modules/infra-kafka-cluster/src/kafka.Dockerfile +++ b/modules/infra-kafka-cluster/src/kafka.Dockerfile @@ -32,10 +32,11 @@ VOLUME /tmp/kraft-combined-logs EXPOSE 9092 9093 # Generate a cluster ID (must use this .sh to generate a UUID) -RUN echo "$(./bin/kafka-storage.sh random-uuid)" > cluster_id \ +RUN ./bin/kafka-storage.sh random-uuid > cluster_id \ && echo "Generated a Kafka Cluster ID: $(cat cluster_id)" COPY ./kafka-server.properties ./server.properties +COPY ./entrypoint.sh ./entrypoint.sh # Format storage directories RUN ./bin/kafka-storage.sh format \ @@ -44,7 +45,7 @@ RUN ./bin/kafka-storage.sh format \ --cluster-id "$(cat cluster_id)" # launch the broker in KRaft mode, which means that it runs without ZooKeeper -ENTRYPOINT ["./bin/kafka-server-start.sh", "./server.properties"] +ENTRYPOINT ["./entrypoint.sh"] ### Kafka Connect ## From 7b78f117fdd7ef32206984d5841ac96f6d358ac3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 24 Jun 2022 14:54:20 +0200 Subject: [PATCH 405/629] bump Kafkatorio version in .env files (still need to make this automatic...) --- modules/events-server/docker/.env | 2 +- modules/web-map/docker/.env | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/events-server/docker/.env b/modules/events-server/docker/.env index db082c3..c97ae67 100644 --- a/modules/events-server/docker/.env +++ b/modules/events-server/docker/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.5.1 +KAFKATORIO_VERSION=0.6.0 diff --git a/modules/web-map/docker/.env b/modules/web-map/docker/.env index db082c3..c97ae67 100644 --- a/modules/web-map/docker/.env +++ b/modules/web-map/docker/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.5.1 +KAFKATORIO_VERSION=0.6.0 From 8ee0cb396cc8646a1e467b12f15cd01028482bcf Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 24 Jun 2022 15:01:24 +0200 Subject: [PATCH 406/629] tidy up kafka cluster entry script --- modules/infra-kafka-cluster/src/entrypoint.sh | 3 ++- modules/infra-kafka-cluster/src/kafka.Dockerfile | 8 +------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/modules/infra-kafka-cluster/src/entrypoint.sh b/modules/infra-kafka-cluster/src/entrypoint.sh index fe91dbe..9a21f3f 100644 --- a/modules/infra-kafka-cluster/src/entrypoint.sh +++ b/modules/infra-kafka-cluster/src/entrypoint.sh @@ -1,4 +1,5 @@ -./bin/kafka-storage.sh format \ +# Format storage directories +RUN ./bin/kafka-storage.sh format \ --ignore-formatted \ --config ./server.properties \ --cluster-id "$(cat cluster_id)" diff --git a/modules/infra-kafka-cluster/src/kafka.Dockerfile b/modules/infra-kafka-cluster/src/kafka.Dockerfile index 60c1507..3927cfa 100644 --- a/modules/infra-kafka-cluster/src/kafka.Dockerfile +++ b/modules/infra-kafka-cluster/src/kafka.Dockerfile @@ -36,13 +36,7 @@ RUN ./bin/kafka-storage.sh random-uuid > cluster_id \ && echo "Generated a Kafka Cluster ID: $(cat cluster_id)" COPY ./kafka-server.properties ./server.properties -COPY ./entrypoint.sh ./entrypoint.sh - -# Format storage directories -RUN ./bin/kafka-storage.sh format \ - --ignore-formatted \ - --config ./server.properties \ - --cluster-id "$(cat cluster_id)" +COPY --chmod=755 ./entrypoint.sh ./entrypoint.sh # launch the broker in KRaft mode, which means that it runs without ZooKeeper ENTRYPOINT ["./entrypoint.sh"] From 4bea4497b4a57a2eb2c9ddf48291f09f7f78a44c Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 24 Jun 2022 15:06:07 +0200 Subject: [PATCH 407/629] kafka cluster entry script, use absolute location --- modules/infra-kafka-cluster/src/kafka.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infra-kafka-cluster/src/kafka.Dockerfile b/modules/infra-kafka-cluster/src/kafka.Dockerfile index 3927cfa..9d09f05 100644 --- a/modules/infra-kafka-cluster/src/kafka.Dockerfile +++ b/modules/infra-kafka-cluster/src/kafka.Dockerfile @@ -39,7 +39,7 @@ COPY ./kafka-server.properties ./server.properties COPY --chmod=755 ./entrypoint.sh ./entrypoint.sh # launch the broker in KRaft mode, which means that it runs without ZooKeeper -ENTRYPOINT ["./entrypoint.sh"] +ENTRYPOINT ["/kafka/entrypoint.sh"] ### Kafka Connect ## From 8910cc571b684f188558214dbcc921434ce20028 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 24 Jun 2022 15:08:46 +0200 Subject: [PATCH 408/629] kafka cluster entry script, add shebang --- modules/infra-kafka-cluster/src/entrypoint.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/infra-kafka-cluster/src/entrypoint.sh b/modules/infra-kafka-cluster/src/entrypoint.sh index 9a21f3f..b89913c 100644 --- a/modules/infra-kafka-cluster/src/entrypoint.sh +++ b/modules/infra-kafka-cluster/src/entrypoint.sh @@ -1,3 +1,5 @@ +#!/bin/bash + # Format storage directories RUN ./bin/kafka-storage.sh format \ --ignore-formatted \ From dfc8b5c91df377a287bc86d14e355ebb71597ec1 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 24 Jun 2022 15:10:40 +0200 Subject: [PATCH 409/629] rm RUN from entrypoint.sh --- modules/infra-kafka-cluster/src/entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/infra-kafka-cluster/src/entrypoint.sh b/modules/infra-kafka-cluster/src/entrypoint.sh index b89913c..7caa39e 100644 --- a/modules/infra-kafka-cluster/src/entrypoint.sh +++ b/modules/infra-kafka-cluster/src/entrypoint.sh @@ -1,7 +1,7 @@ #!/bin/bash # Format storage directories -RUN ./bin/kafka-storage.sh format \ +./bin/kafka-storage.sh format \ --ignore-formatted \ --config ./server.properties \ --cluster-id "$(cat cluster_id)" From 9a7ac19cfae63644d357f0710de288ecedd62326 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 24 Jun 2022 17:52:24 +0200 Subject: [PATCH 410/629] update logo --- .../src/main/resources/kafkatorio-logo.svg | 2564 +++++++++++------ .../src/main/resources/mod-data/thumbnail.png | Bin 10274 -> 8176 bytes 2 files changed, 1710 insertions(+), 854 deletions(-) diff --git a/modules/events-mod/src/main/resources/kafkatorio-logo.svg b/modules/events-mod/src/main/resources/kafkatorio-logo.svg index ae5fec5..77c43d2 100644 --- a/modules/events-mod/src/main/resources/kafkatorio-logo.svg +++ b/modules/events-mod/src/main/resources/kafkatorio-logo.svg @@ -23,7 +23,7 @@ + id="color-profile6421" /> @@ -4840,20 +4840,20 @@ inkscape:pagecheckerboard="true" showgrid="false" inkscape:document-rotation="0" - inkscape:current-layer="layer1" + inkscape:current-layer="layer4" inkscape:document-units="px" - inkscape:cy="183.50283" - inkscape:cx="660.88614" - inkscape:zoom="0.72478445" + inkscape:cy="568.78049" + inkscape:cx="196.09756" + inkscape:zoom="0.5125" inkscape:pageshadow="2" inkscape:pageopacity="0" borderopacity="1.0" bordercolor="#666666" pagecolor="#949494" id="base" - inkscape:window-width="2557" + inkscape:window-width="1277" inkscape:window-height="1528" - inkscape:window-x="0" + inkscape:window-x="1273" inkscape:window-y="0" inkscape:window-maximized="0" fit-margin-top="0" @@ -4875,7 +4875,8 @@ id="layer1" inkscape:groupmode="layer" inkscape:label="Layer 1" - transform="translate(360.42908,-216.74977)"> + transform="translate(360.42908,-216.74977)" + style="display:none"> Kafkatorio + id="tspan7786">Kafkatorio @@ -5636,848 +5637,6 @@ sodipodi:nodetypes="ccccc" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -7260,7 +6419,7 @@ inkscape:groupmode="layer" id="layer2" inkscape:label="cog" - style="display:inline" + style="display:none" transform="translate(360.42908,-216.74977)"> + transform="translate(360.42908,-216.74977)" + style="display:none"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/events-mod/src/main/resources/mod-data/thumbnail.png b/modules/events-mod/src/main/resources/mod-data/thumbnail.png index f816fa546d927c502225e83ddee3a21bc9120df0..693598dbf7c7ca3d25c099b339177c6a4e9f1e97 100644 GIT binary patch literal 8176 zcmX9@WmJ^i7N#VmJ4K|syOBm(L`ph`l{|6aY?*LDE`Fegqsmj>=yK2|mjA!vKE-i9X0y-in zceZ`Q%pk7n0WneEaihL=&jmKpDD)PBCfb#}`P;np-bg7-Oa@=eA(5fqdE3XKL#u+G zpT>ud_bI(zSX&c(r*9@cQHaD@ShtqqPglaz$F@gv>D24|clB?&`~XKDeGjeou%$$y zyOWWdCti)5$PHclW}wh`X^;Z*4&e^2IEmY99W-M!o5q`EcS}b|Nk}5K-lV3@s^X^> z7V24A7R+p@b{Z~hwvw%re`m0!Evl~hiNhEex%<0ke<@9mjFdFWvL?$l8UKd0D4kTu z5pQpA@5WR^f?dzc$v%GcE3|(C8DeQVmgwANr3iZY&}QGIZ=}85`Q4NCPH$EVLUau) zM;mh+4v)G-;`%Ius*%dd%5TEXj~Wg_TAgim^Ca)6s;Er-rAF20$u4$o`^`$)e)CZvTP>`w=l*Rm_ww%$?#g2xY8EHuzm1;KTkxm{%kGDIHQ*(2*^!4>e%>Sya z4CH)yr5u~gidPnzRP*ty;%POaBOB$2O+eE*T%zvEeu*DwbmIw{kl1~NlZ6;#4n{Q1 z)Scbk|9X0GtgNhFsIi=$p7OaHSE`l_zjqm7mz9-8u&ZJWb6Zo8c!l)c*OTjhPRf$o ztFoG!l7enD=tDtC`O3KR^mMh*e4=7ZCyW14wve3~s-N5X3Ehdv&dw$mQrw-HS9=W0 zx1Kqkxj&Q7Zhr+uKrcQp)da_Nhl?xj)79m6o?J*~U7hf{9D7>a{_2p=<(Xf5M~BOF zW3?C`3rkFQ0yX)qTeB5sL3~O>1#+hKj)YVR%SZjo7+$zE`hLs*&bL=*T6|D$1z{=% z_Jes+7du~w{~QJ%1j|L7_FGAMFX6&qb-7%6dV0krC2>hf9AaV_uV1t7?d|=U>yY6w zu5!-M@%It-n343~nh838Q;D&2yU1rWLp6b_*1k7&r4hw{FN=S9e@LNccJ>x*RbO8p zr+`3daq;KHI$1e6gK{J12D9rA`T5zUrE^CsAGVF{xxEiN_qVmP^ZaD=3Zvcg(;k$q zc%^}NOW-bZR8-W-*;y(QdGGP#$1z=)`etTYj~@%Qw6rw0w7eQcKtWek*4W2Ne^`85 z{Nv7m7AzczVp2D0^XHqJo6AP6sAWA6>%!sW_}U{wpvyg2RRv;VKp&c zhMWt}zkmO*u#D)Fxv=wfd(ye?!|XhKO`~@dIIuFbR5dhk1v(B4OZq$Lafyj*jyiH9 zFD@=}M`_eg*GdZ!FEQv6Ipd+mB^w50a&qa)*_qgg9R#dCT8z6n=ff-)H#hmt!wm1= zpKNe_XgAR2`W;c(_PinYPS4TiG#4-Lhnyam86}Ug*RL)-LqkK!@C!+qfGw5Mk;!(w zR95&T&t>b8awX|^IAHg;A%THj(4pAGj24^0fq{~-#J3w|dVJ0fT%gzJ-B)Ly*=Cg| zBqZcW`LHi9FWWmg*$L9PtyndAl&#Lbf}y&@r(| z7#L>C0-EXdt0MUywRV-?FWuSOE3T@ln)=?x&dA81rMksQ-`zj^J#4fy2LUg?wdDn3g&3< z5p?t$R7FlTxZ*ImHkxiN*#-r*%*sCSQK3szGtLQ+iKoK~%A*PU?mS!h1J2aFOAAd7CI@)47-M)B2KH0Ly304Lz%x}@$*&ejt{P?$8evqnx z{pTlmVh`ghYn_LgktoAaZ#8&s(8*$K%kf+Y{UuQVW_)#2#dl{>K%W>!x!{R`tb&5U z4=y8rwapvdXhV)RYJ(!i-#yBa@MQe`HL*lFmWW>gk@F$<(~r(5OewF0NEFdw9686I zky7GUuU>s{9ez|Qt)M_xOY0_} zKwW&#n5bf#|7NzZL;Q$a2hv##!?4`w1&z?>shmc(=dJHY@nEHh+Az>vHYS8FE-%-hkzo}MuwdPW5-t}pvG0HhE#AxVBTw!>?Y3PUt2Q4%N(_}Rdra0n zotQA8;xp^wC=4}pDnLqjdhh;H4Gj(bHZ;V+#`ZLkUP5~G<=eLpekvAo0@NvmhkqPh zMA_Er8yGBl-8WXv*siy%>9H0}&dgM^v3WI{5h68^CzV#Bo@85V0)V>sg;?P=%w{HF zK8!&=H2d@CyD!vAMnCmBi~ic&OjIjz@f*RZzN^Tc5kGDfkq?NLl9QvUsE8KL^u0u# zIQ)E5;+@qe{fCe784}i!NMgVum@h?b2X5|!p8nl@1z(0@6_ohLd^5ir8r>E z3tACu2?+_nF1JC^fX%6l>};Bqp+Y@3H(nsa<(wOcBgy&0@d^8IvlO>jqcOZviEp#@8+L(7;$Hebl*2H z_zy;}+xN@go3$mX_AZ#r_bjLU=nluOCtMJ8VN?XdN49N%4J2X#}r;02D#dD5AWq z%=&n1Hc@DJtr=0I=Cv|FOGZZaea-i}aje2myWd@fmG(ulj!ZPHd`=xZXqLFMS-+tsC|3qbR=UKm9vTcS^}R=Xy)N8H`mD%2#Zju)XPjJIDGy$D zgmQ6l**iG&HdaajOsg39I{!e;t$cYq!%0I$8bJqjf#P$=o}^Gsfd%-Q8VQ4h|rtjX|`8VvX={`BL3{ z<~w(y{`_%WTPoPB3I;%eGsE;<_H>~Q@dPoG9`urz>LvmawG6_lPv zYM0#cOi6Z;Nqj|=ZoYK4YfXpaE%&9>)!*COLwy-MnmRhmuVNW(zdR$8sJw=G7O*nT)>etjfF3O+wxYX$}eF08CP>$Xi{vsNO3(j2>DB_$;# zl565Jco8WqA`;E@aBYZBK)`8zteQdE_j!Zs_*gu; zNm?3*UY*zCXEnm|{{H@3dz7v4&A_D;_2%$PX$g-RYv3os@Wy(0G!?H&=W>5m_5Ab) z7iA9*e&}%|a(ZcKXkfq|=EZCF;dyCcc&l;iq}$5n@jM3?SFcCxY!2}8ZXZw0M1Hvk z7X?d^Q(;(U<-;1Yh&=Nq53zOP8yU=|ADl_CW1@i1&1yxZ31p)k0N zWs8b*57PAHdyAA}IQjUxQK;(wl)C5>ST(CGJ96Ep8}De6!L!)J#f=*Si;Ii1WrMt{ zta4XMiI6)Nf~GpVr4{p0PHrqM3|8!bTgaF z9?wT8OgDKt?Jf0=o#p`9)&aQ(A8nYr4yp~d0iM=IT!r@#dOA|DF_q;pxM|O;SB{cV zQK_k@VC75uA$}~Z0e>j`+f51ubK$!&QEPmyo8*EI%BZTe-WZxXRnN}O4zC}|9(-4R z^7QHA_I6TDjR0Wp((-ajUf#^crJ}ll5xKFY<)HfQu%(?av+7KRi$!7rM%ir3j^NR$ zsFcjiuV5$uZDU8qQlY1Ye!RK2iG2)8ggup&lz~Cp)RY!}1%37P1+DV=(IyNBm8NfE z@(uK66{*YR<>fj9Avd8a9;cAd@M6wl3X8h1>lp9U2bcSv1yI|=<@Y%X!j4SEJ?93X z8R-3-`++-9l{Fu^d1#c?)YKYG9UIJ0_yXnF4~PtLB0j&D zr(j_+ppf!jdcJW1I|7?5EvmJ!9T{j{{ce(&yGj4!doSz$wfvqQid zC(Bt@-v$O)1qI*F6|Dj;fPt)hpsIfV#T!jcO(NBJt7fk|U?|2ac0_v!H z#0Ls(qR}0R%6-R=fq_wxFM;q3E*6W!q4*g$*W_8a(N4~x>-Ijdq8Ylvq&={96mPd@AIiAc`Kf`PUhbdlI|;Do%Cu{9IR8CrCp861rp*!Ntv;Ivcb#QCl*? z5{MVw`8!F0pQomSJZ4KR_mN_gOpMgu%t@ogc^I3~^weTCZuITs4c|7Fj1s30IM~?I z(+p^ntI<-wyZ*=|I#Pe%EOyZ-OM9#6f%;Xpu#KI2Dd62E(md&w*z}O_Mil%PgVRssZf<0BE$8zPdM+;I8$m_M$t0!n=ek9zf9=8F03lzCLbS=r zNpPIn#)Zy3FK^X3B`v=XIrf+g<6%2zZ=#6*Ly3(8&)N&ySy0j~l;2EWrJ|-Dr>`$% zk7g1CLs%+%tb3Of1H=B-GFAplQ&*SDO?-U%Ls`vKlUCnyx58y8qt-J;zakp+?(Xj1 z0+aUOLvEkdLHD1HOMdHPQcFI0g@yChw;k#y2MXjuOge%aHt1>^;OoFIQa?2>$3Oi8 z>Dm5;zXDthD?7XNg>q(QW@>VBCoJ~c;9zFh{NK^a9LdMb2~>Q)fX9D<4Q*PBIrvKN z`QCM$zx({|!&fxu=v_TMGU->Kc|p-Vdr)aSDfeC{m6eD=vh!s3_vTmcMpbWbVW?#X z5Ic3@OD|p!fO6b9I$~#KeG(rZAAI?-$#Z@XSm;|S+r8%r2|j1f>$&u2OleuvU;6$z z$ma%29<)*06L>JJ4%VCx9UYy5nmR2bLluGG27gU7%HaL{#S8o4VpZ|+Kk^ql%JP>7 z_hAeYRnkPY7`2jD5N?2zfu>Z3Lx<9Ln`@_4A^`>P>hH@as%t|UM99{rS^loKI_Rno>xEa5*Fx5%c z%4IQp5^2Ouc`uXq70~6FD?9@b-Xylez`#I<%EYi_cn5I!z0ayHQbrztF>p0MAaK39 zX+tfeDV7BTmPiA>$Z_dg$~CV%dGbU}ZaRnauA)Bek1dqMd=)!$qM9;f5!d0+Y^z`B z`DPQrE$N>wC?pfEii*nhgI5OgdCt|t{+5@Xfas5li+g;M1LenS@;(w2p8xioj*7~Y zM|$d-sQ~7$%gS(L{_8y5Uqy;;HL!4cFbj!@q>WpKB*GTDa?a&`IRlMoTx|yZQ1=Br z4@;@DzdvEFBSZuYg0$b?pPV5PCyO|leCF)^l|tg;nL+z2qpcpIbP&TOKWZY&(0XcI z`35Q$Tw>$%5KUB^N;e)Z_o_ZbhDt_8>9g(B0+#lm4K13zq5!u?rxkGV@k?CC-@Tv{ ziw7-OdQ=YmMk9tuN0|)4itT_l58paDIFOQ)+coWPZg1-WtHKFgtm#D{-lGUrcSVNv z*Ft#JW%Yv?Lq{2pA?@*j7LeYre$>|3>*&|f-tMLwelxnW=XQi!{R@CWknQgLL?J;z z5GBEW-4PdW{O?GbT=iyIgAJr6;%^|37@IMM1i<}fnbS}~)uXntSBbbfiMGaj$(DA*XiMimq9QmD$GZ-{(6`Gt?%Vg<}j=(auXsgaIpkWcrP|GIf? zd;}l=QUN^@Ve*@4ES57~yHI}C(e%cR8#C=eBaQ`cr>16Uzzkr4xU8z;HN}6&p_{h= z60KYWytQEH$xg5;rzV-ay!^rXc#Xl4_>F55^8US`;#{T^;BAXHTZvj?9rlQDjyA7l zdp2m^DL0H8N<~#wFAmqoc@VUi7GXtdLT(d+N89sB-L^`lBL;?swjyIGteO^W{)ymD z&1J^CsUO`?T3GlmCQsTg9(v~|eOZ0WW4tm_6*VXt0AMv^zQsR? zj@VcnfNLODueBd+S&>^59`m@@Qg3af^mH-ycAoJ^CfqSLf|6kkdwbR-xufinK2P3v z^2y|+SW!S3t^S*T)Az336%dkiK9KC>`v0t#s_^$;tP(I!MG8nO4bz6U@x;)kuFekzK_4{|e{O7gtn!?$`N?H*|ujM{UaE@wFFqh}Y0TqNgI+dg(ogka@ z!e5rLYGPqwT?4CRgGCEu+2S5E6U;;Y*wt_GFejQH+oh=_2yk+ijZ=<2bvH|l^q6Zm z8^v@ebh(UZ*BfcbZGQw~{R16EsOEUelwNz=(TWFkm=XQm zv$OfITU%EeffEodaoH=IqCT4T{8a0RqH~Rmf@`Gx zNvFcc0M`(nK6H(-fpnEv{)7oaO^2E0#}J&pd(`$75FXOO8~9Wtw6v3CH9rv`uvkS! zKR9xnsYm8S`kt@0tQMr1@qm*`3qIcBgDXJ|NKJl3qGP^>t{u-Ax2@HHOEZ+4&H56k znRLWotdj`t1=pe}hAT*yKf`?>(qdFc2?zyv4UlTEwY&MF&&mVtjCEE=+UxWQW<8#9 zphuZZ#L#|O!5M!6Q04U?;L;dC0p2< zIYZ__lorPkTt8I*ODkdJk=rW)_f z%j;8~m(PCH1iavzy=Zm517OdZq4nV5{3?OI>z{MnWUH*_FdBc3_S?+x+tjEhobf+k zkNNPT^|Jy8j2eyo_L!N**opxVwN{4;J=X$!hP&(?9kuMfz9_#Z`Jhlte7gP0v25QF z*un*F=6--^GCPxdB$)%**V^@l!IhI++^Tu!R>~B&by%1fDN|5jpay_v#xQ zwfqz^s);Mn?YxXCjg(iUE|RPMRx_oVuc64E!9&JTZjo`4+b942(LaSWV^#$c{(~~O Ptw+;T)m3?S*E;%tZ2&f# literal 10274 zcmXY%2RPJ!9LMj@;p}tv$QIdTryONhPT4Dj>=Cj#dqgB;mL19}GufMD(-1O}otf=_ zzu)~|508h(!`<)q{d_*}_xtmU!Q54&AY~?nKp+$v>bLIUz9s^nNFoRX+B!n%jQa-e zp{${cz!8A3j>dgY;-+rof%`EU_=Nt3&BAa$Wb#xo^t|tC>*;Oz*aqV5?JZ*O;^^_v z(#=N1_3@+3O$BBMgae{+OG($~`-YjXDV-k64QA&wdS+|CkCDzZ2YJj!U`5J$o>NVT+6w{-_-rJsfq_JL8&dK8y5@n0J;~H z(-JlcM~g4CZyXiutZ8mJs+i@wXw)d$wBp~)K=Ai__W^2NC;onOdj;-R=(CDmqFWkB zG*0gac^~kgERHEid6Km8SKYhs;U9x9&d*N%)%_gfrCD9*S)ud$!&zqVXU2c4>EDb$ z$+!151F6C$ZyI@=t0 z^5mQWMgTxkQVQ@s*KKX$+F>vTAaOs_!3Ur|a**z&?s+mDEx=bxkF(Xc70t)1g6CzL zAXa?Oy!KZo-WpWYwz&*-e6MkwDmQcVZ66<;51!R{OCfyG@)UrKlR?C^-tAZD6F&4V zNgtKa#gbo(U4Rd#7uN;Pq5h-kVP(^fp&8`BPdXY|2#Fhfcj6K70uwJbHywyRig za_@$X*SO2u+FDxwy+0%QYE+kEb%J1KA3aw_3!jF(l;s782u>(LvTT(Iz~6ngqB3j9 zJ6yLcJV?@g2qk%b;qr|zCVt{g@_4>Mg?W?Teo_Gz0J8f)HeKD3>d(rA@dVv?Ri^&p zuh+rnN6W8+lSQ$k5yPJd3}~|AZp@X{&G@aA)xE!%4Zb-0Hyhkic&p(f0P6APbc4t8 z7ittWK$~LFk6LHkhgNUP#rerr%f&L=?=DcEhbZ`}t}KY}fsg6KVMFX34s@`(3izRU_wPr30`zI=|#S?cQ_A zyKk9uHgO_$%P8_5to|x(NYGD%REM1(pco29H zFU*dpYxRkl*fwRKfEOBJKVGbpuNse#3qC*fm8_WNXAM!7l6|ZB2iH~J+|4%hgrruM z1seL2A&>nFZ3js7SYqOG&9^YtVsc7CEyCJLgg|IV<=s*5zWswv3dviY@6x}MRaZ1*Qf z=O0{)xB>>MSTFkT#Ps#=Lhn+#lSQdIvGz_kvIRl|sq6zi!gkfA;kq2R~2iMef?p zs$l#N|DRCr$Qcu`rc%8FiH@IS66)_RbjP#ExHy$$ExB{h24;xZQQc0Lu<1{}l5|V3 zUr2@B5gbacq8hm%rwiRZ09yBK0C@egRk`l0I~Y1HJADNzg(9^r$iL&SS)A$)PmHZh zT7lEdC*R%Qg8_xch9F^MHxOR^j;N(JFW%k_jxqJ5CU$WF%T&#;LJ4WV8X5IQo&5D- zwGTgBCKrAp-fwEt_{ey}#m05`*nv!odGj^T8PM4-&gyj6#2hDqMr?HOZu0pu*Pnjl z(Zms_(E<(Jk#xA5^#~kiTYLqd08GzC43EywO_qLPLW*?XU!Kfp;A%g(fL_)++|@pU zX3DtYUZ;mfPUON<(dNVXr=mWggm(f6R>e-q0z<*3M)xe=PbV~{RWPV0exQrc2krdD zx$ftaAI^1svp*Z_C{Z+?fd@u7eS<@plKn=&;a|($Q>3rK%uTB6d&4)WsOMJzG|M)MOxB7r3tkby6Lt$(MzEBv%4l~ zN>^d`^VK1RU2?}aUTIoVcEdSJVMJHRC9l?&ghRhmY*gkx1iRQFtWrm@T=^zL74#tzNLMzu)QwYk<9i^@mDy((f0B ziJ1(vYU&=H(bU|kamdiz?{K$d8Wjxtp1eW@G_;3?HPI_I1%S!BIUOW?IFD>;COEVXLhHDV-QbzznTr(iThpt^=*fZ>g-&k*CNFkz^_K z(HraAl$vEAc7Kf!u_-Cs{o!mjOedPImOkzY z8?tvA_|HxLBt|t36Qz1@5gK;^CWCJLKh-pPUtRY zJ?rv{HY9^-ThJ3l(;9Q>3Jz%`x!~yw`FtSrdU#SBOe%sHC%KT*lnN=Yn1dO*I(fYh# zOT|qY&y{}M%3Qj3^+Rm~nqYwoYOcK@zTVWFdjA?&~s4wJN%j9;N}d9c zTSxxU0Ubo0UiI!}?~xoGQmJKiFei=bsxLc%j_HMv8o3(d2R73*Hf5i)c@M%np(Go5|YsiAzePX3`5bAJt2$QhxP72 zzwEguFhR(;Fz^x(8giU~Zn*a3oo_`;$9Hrz)i#{C>z@Lb>CvQBg?k^zf@I^I>@+=5 z9ep>iXeC1F`9I;3{ZM{)amTfEG0XOF5}NS%1n>A2L+I!jkOfl56b(?9OW zYslA+BAW(JMeyG}I;Q}DS3HTbEx#5FH5r2J!WF^F6qPN>* znS&00MX?7RDka&W?kD|u=h$}gP{@mAQf3B&KizI z@?7P4aK#r}Us*#z0-_nJYbr#;s>S85dGy;y(ewt7W~=<+5x^Ca(HeD0K?|SFhUHiO zn{qvcjVWr$_8dBgCVuX_cc<%SFF!;1J_9YpLyu!p5T3qSfCs(@^pljA94EuSFG7m{+_<@VudQUl!;B zA07!a&6hXW_-To~C95qZ><;(hl$D9Pmpvf`ee4AwwMCT%j-lPd*B*}n?#+r4Cf$Js zx-mvdm|qdB7`a=LLvA7+yP>qsGdBkdXZez82DKG?)vcsfj56Tl|1<1uBN-ouTD zUr`~tsf)zkQY^Z4=#PKg&{Q-G%8!dQZ+lKA-K~-d-O{dRr*(gBUl~`NFr^W`IVe)-rQ?|TTGThInnyC?sC*PDl;s>m;@a6E8*mT zW6Dud#(EOmG_tt=7v}cY;jdg}A>eOtLg09a-~}mulz5*nrx+Su1FbdReoBslv>`R| zy}zm!PN3O4KYFw6PC=V+4MZ@Q?GCX*yd|yJXNJOpYU!+{)AdWl5@it1&9=-&7s(sv zhYJac=V^)hWyZJ(6}vQ9E%D8StbW6m<-OyvwLopwDm`lsIKuv2wg&D%6s4Z1?3`}6 z|1+3$Q>ET!MYpRZ;CQCWFKHRs5ymcV!^0HD+!nS={hw(>9r{1UCQ&tr2T)Oa-KNXy zG+g(p-?zw?dP^j6M}R;>rz|w=F~a;l` zZzt?*pF+r>A7hEx1OB!Vvo8jhR{{(_nPI0&P}u3^PEg>2cYDI%uF=GC7GlhJ>&I~6 zfxl;&NX9Xe#Cv@us5oY%+Lh_JsbppBI^6T>UkvC~%Y((HJ7WNAtgape(0shbdAHDO zQ{ni_-$3)}z7hF{cV6}n|6q^Eu$~t4ylN3JhLaGuJ7qKNo0k>-@&mpNS=9{o9w=^i z(r7De!#T@9Pb|f9&h?0-s&>6|@>=8y9I@LxoVLv0+Svj0Yh2T|rF+`D>DYyZ5)hFy zq7m75tjwVjW<1RMq6Z({iec!|&L04o7fsOs2>rSO12-%vN$c)9S?Uw)i&cTto?PRf zZ51G{<#5uN*eDF`7}2MAE~QG)2c>|-V|CIdVRS)uFsrz!%r~S;~%4#fB%y%S%n{@=KH7bc9s2B zJ9)#n+F_2N)VzP5H4;kjclvRS^=k!afx^@Q4eMA>2rEUUifSCAxK$@&X{bavabZ8O zZ9|479I^suCe=9|qLJi%#o<{i;N@$fb=A@ECL-}}t6(R^@2bd8C!391%_rqH!ORs? zm!#FK0eE(a24Q@hq{mow$?k-ki5!dy#m+pp+^_pYeU^r+*>Qw5(Ui$a^TshtIpD17 zySRu)jwH}|NH@RyO=$8%3&v>FqMYF3t2j2|h}K78U@Vez?msMvWZY}z=A)+pc-T(d zqce~G%8Z$&O!<<3rZ-CKRxz^qA{$`v-W9(P=~syWNa;@1FWs^4ZfH7CQ$lL8CnXsC zyFysIiIh{XgE~;{!rj6j?S?!4INmX^LSSDUHC(1aIbxJ>E$NLd9cz?KUcBx76xT}! z?f9(jcYW>aj<0BZeAu*elGB%Rzt>Vw2R3b0W|E8TbI!pF)ED1KKe=mvGNm!jNb$*F z0pBpUej3qxcu3|CbkPJFpMD1RFtFA%T;8h|gyu_@l`WJwiF2u zhdx}Qk9@-PVZIkkg+|W9|606FT`}fE+h#LRC4;U)+*QN%ln6$oDlQhrbZ5p0*M!9S zgD;F2M~qkWOUa7Oh}vjuRjolwT6HcUhh$=t0k2M489|ZnVz0$bl4(Y~RDFFqF+cyd zpG~jx%NPEg-#Ukxbo@8e0>6L(qxs-Hdf0a?k5mS-yyvOt42&$STu0|?zW_+wno5NT z2Uk1_Gmawr(=oW>DwHvxlSSgFo>a^tL^6&VPJYItWAePOZQs$FM{QH6MV-4j$rA`l z-`tHMGaF0H0(i$GW++S&B}XaB=$m}WY(2hsirS^BA!M41bbH))c6WJ9&->0|BBy7B z(clZ+D)|GyzZ^pS4yjvTvR7h>=rK-DS-AD9J{4k=!o?k3$L zrbRq5LbraF1?O-SPfV?kI%-gMttN|Jbh5-vOrt7Kd4s(mq7xShjCaM;B8xS0K362| z^$S*f+UXZGrlS_(2@ZZXzw-5YdGJ}G{;%QR3hrS}gvR+i8r5y+r2o_4+WSgkaQHfO zv9IO|4-ap77j}C3Ppp8%Qi%gz6NHCH0FcanpNvibcvR!5ZjxJ!Qc35iQ)6kyqP<{? zey>2{q~^NO|H@l}v)2NpiqaP$zoN_R1RR-%dG3($7&a;!12D6+L$ZLtzQMzZu|sAy zV0TbvR;(+(^F4xa9E>G0Kg^iyO$tzR8R!F`cK(mModU!(x8d+T2v0ntmZyhGwU^_i zKcXLvzue1|vtK(oS;J#JsGi=H26GM;DmJ{4Nlk`w@`J(?m`0#Dg)r* zgw|@P|0YI#VP8cCm6!WNC&gW$G0FR54ZpOMBw z#p(Rxxt@=%@g?O16p9PA8eCle;XQ6f?HB;&9*3VGJ(uDlM?b+koFD`VP>%XkLx2R1&};Y zeD-D7L~klXt6zF)Z?FTOmUpfe!vo_nXxL>>aWe3aeqGBUR1)l~VGL32`d@=p8D{Bs zf>cT%%CKt@^5Wu>DKzrPm*^b%kezUx*~eLzFq?cB$R0ZbeUy0@LC#;AhpjcR&c`g$ zK->^kKdTHSkquWS1s&>0Fl+vs7!!X5-S+&byXbn0BG~FZ%$s}v=Wf7e#Hzf2KF6F; zX#|%J;UL%5H%7azG%%3*K$1HqH2y_-l4`tX4%#UX#HcdN3{h!)z}hN- z?T$J=^L0J-RZ_~)Bc#e3fe40tiXd#W1H}lR?Jtf4YhmQu(7d(_YTY-x+u`%nq`ej# zCcBd+u1))sCUM$5I@tD3&YO|sM;FiG7V24GV(nqb$xVfj5H+l{z-24%T2b^FO%N3~ zk0j3x^g7AnIX{FBSCE&{g-#$soIoBDXQ?VhVmIis-No=AU|Xg3LolG&1O7s}l?T8@ zCYLonV!nC~-2z?AC4}!>2r-+_98@}}mw!M-aCj#q)=tS%kQP&8fj|3Jj?M&D`oJ!X zn!1~P_9sAgym-4IgWToYX}DMhu39Y(q~Q09koUk@Qo26Rte1$Gm(8au!<`?QPB61# zRae&lh}k%&TvciB05B3`Dwz2s;$2PBw}mP26bozXdV?z1{0}yj8Eo7d2b6eumD#+NL zBBbhqUaPf%R!Av*rRRE~Pcjl*pE@b*3kYQC5OZ^I&?b`Rn0FWJ^da&n0jE9J_WSJT z95yn-miCrlC>Dce&XJU#G=ABm)0$~fLI=vb6yo=GW+{%zZd*%{s{4~65QGIVMoBP(VYHie zj{;*GOgFVNeNH*A5Wwg9c6oBKTZA=O;AKEahyB2{^3d@@F3h_XG)xwxedcBGKO?aF z?5lQhFw%W#yvSZXG5e!LkmBe7Ai$}WDrEHDIwsNagEB3b0EDjcYoBwWnAkuQ-cH-b z1^Cf%(9YoY<+y3x&ej&SzMQk(K)vfGv6vqL*eK*;Hm6+udN&zvf9AJ`KXCkSK52e)7CxHX~#8!z-%=r=+Op4(vQRArr8 z=vyR-$+z+C&Wc3DgI_`59zZ zeGMI((HEz$mrQe~+8KzKx)m_xBO*ptLKpH}EPOrme_ItV5&1OF0NQ2) zGx#?O&Y#jVS+|H^%xi>2@d!6lJ$DkE9Ihm6ZO0B+35(g&{XDC@)jt66Z5cC5c-Owu zTFl_KYa+9e@@Mb2_C`9EP?B-PZQQTZfWU0gBF)B4J7|6+^db zi9)}m&4i?}_M=WgI?otL)mv#H|7ux_--OIFfx0m&JYp_Z*%$d>;#gNPS5_&u`M}qdHj-)Wm zU@1W)4>@ATu?EYaKvWw+8E&rc!Bmw!I}EO3+Mb4lsa|2z9d9qhOOuCfcO66eO6}z7 zkVug<0?3M`p@I)~UxI>5z3inHv)K`NP`-T+`=-wBjStPj@oFmeL zI+PWLEf{K9C5&FY2awnxfaPNFkM*Q2MSP_r-5*vE;IN@7AIghDN$D`@=MUAY%{WM^yE^{6%f2a~;54Vsy0IU{aVpr()Xz`ALi;M^Nno5MZ3%t0w01UI^^#=%I5fFx|Y2Hv9D_teF`ihC2KM2Iv zPQtO{IRr)$zd{Me@1+Fqr#TQ>-L{*#HC3wf6a$*kd42alch%v6F4P)O-#v%sW3+OBnVzYG>O7i zvEt&JAh);YRC7*PrldFkTAx(Wd8R*%B~TwX1Jz~PK-AZSdmhDDEIqo}^^29;@!mvm z9IJ-G;vFFa`EU18#kLp+j7Hvq15eD(pURY4Hgyzlph2+d>PHQf4HxZ{Q7hx{aM*jc zhM?@LZ$u89KbAkJD0n;UL6FDiA5UNIj9&V1?;Ua5$}j+iqOIjEJyiyV5N8WHBmV-p zDWkxk$9GoVGrIg?H-7+!;)86W7X{$}@Z2LpxC4zoUWRMrv7{S6U7l0=SV}3)aZDik z>>|pp(l`nCAPmlJQM>2E;jB#6I}eiV$aTu{o>$o0>oXgtjW+pI=|_a89LQ>*HlC#v zyaN!@$Q#U@S0zK}^4Xhtl*@)ys*O}USL{$u+iYAfHXub5@uQmMsaFWu~$defzym9zHp!Kl}o k{>Pw$Z~JVC`-kk%93Fwmn28qL^L!8umAkjfl`TU5164+adH?_b From cf5804b42dfcacb8665c6093413c5722f67b6f3e Mon Sep 17 00:00:00 2001 From: Adam Semenenko <897017+aSemy@users.noreply.github.com> Date: Sat, 25 Jun 2022 13:42:50 +0100 Subject: [PATCH 411/629] get traefik working --- modules/events-server/docker/docker-compose.yml | 10 +++++++--- modules/infra-factorio-server/src/docker-compose.yml | 6 ++++++ modules/infra-kafka-cluster/src/docker-compose.yml | 2 ++ modules/infra-kafka-pipe/src/docker-compose.yml | 6 +++++- modules/web-map/docker/docker-compose.yml | 2 ++ 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/modules/events-server/docker/docker-compose.yml b/modules/events-server/docker/docker-compose.yml index 28781c3..02f1f6b 100644 --- a/modules/events-server/docker/docker-compose.yml +++ b/modules/events-server/docker/docker-compose.yml @@ -13,13 +13,17 @@ services: DIST_DIR: "./build/distributions/" environment: KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" - KAFKA_STREAMS_STATE_DIR: "http://kafka:29092" + # KAFKA_STREAMS_STATE_DIR: "http://kafka:29092" SERVER_PORT: "12081" -# ports: -# - "12081:12081" # http and ws + ports: + - "12080:12081" # http and ws networks: - "kafka-nw" + - "kafkatorio-nw" - "traefik-nw" + labels: + - "traefik.enable=true" + - "traefik.http.services.events-server-kafkatorio.loadbalancer.server.port=12081" networks: kafka-nw: diff --git a/modules/infra-factorio-server/src/docker-compose.yml b/modules/infra-factorio-server/src/docker-compose.yml index 680960c..262ca06 100644 --- a/modules/infra-factorio-server/src/docker-compose.yml +++ b/modules/infra-factorio-server/src/docker-compose.yml @@ -10,6 +10,9 @@ services: restart: "no" networks: - "kafkatorio-nw" + - "traefik-nw" + labels: + - "traefik.enable=true" ports: - "34197:34197/udp" # factorio - "27015:27015/tcp" # rcon @@ -35,3 +38,6 @@ networks: kafkatorio-nw: name: "kafkatorio-nw" external: true + traefik-nw: + name: "traefik-nw" + external: true diff --git a/modules/infra-kafka-cluster/src/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml index 6c67291..6757307 100644 --- a/modules/infra-kafka-cluster/src/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -34,6 +34,8 @@ services: networks: - "kafka-nw" - "traefik-nw" + labels: + - "traefik.enable=true" # ports: # - "8080:8080" environment: diff --git a/modules/infra-kafka-pipe/src/docker-compose.yml b/modules/infra-kafka-pipe/src/docker-compose.yml index a2f781d..4536152 100644 --- a/modules/infra-kafka-pipe/src/docker-compose.yml +++ b/modules/infra-kafka-pipe/src/docker-compose.yml @@ -20,7 +20,11 @@ services: KAFKA_HOST: "kafka:29092" volumes: # Windows (requires privileged/root) - - "//var/run/docker.sock:/var/run/docker.sock" +# - "//var/run/docker.sock:/var/run/docker.sock" + + # Rootless: + - "/run/user/1000/docker.sock:/var/run/docker.sock" + # Unix? # - "/var/run/docker.sock:/var/run/docker.sock" diff --git a/modules/web-map/docker/docker-compose.yml b/modules/web-map/docker/docker-compose.yml index 3673e21..ac0793c 100644 --- a/modules/web-map/docker/docker-compose.yml +++ b/modules/web-map/docker/docker-compose.yml @@ -13,6 +13,8 @@ services: networks: - "kafkatorio-nw" - "traefik-nw" + labels: + - "traefik.enable=true" networks: kafkatorio-nw: From f2ae951b1dba8ae900ae8d2c55ca77d526ab73c2 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 26 Jun 2022 12:30:08 +0200 Subject: [PATCH 412/629] remove kafka-connect subproject (unused) --- modules/infra-kafka-connect/build.gradle.kts | 116 ---------------- .../infra-kafka-connect/src/main/docker/.env | 4 - .../src/main/docker/.gitignore | 1 - .../src/main/docker/docker-compose.yml | 55 -------- .../src/main/docker/kafka-connect.Dockerfile | 19 --- .../kafkatorio/kafkaconnect/Resources.kt | 10 -- .../kafkaconnect/kafkaConnectAdmin.kt | 92 ------------- .../kafkaconnect/websocketClient.kt | 41 ------ .../configs/ckc-websocket-lua-objects.json5 | 130 ------------------ .../configs/websocket-async-lua-objects.json5 | 84 ----------- settings.gradle.kts | 1 - 11 files changed, 553 deletions(-) delete mode 100644 modules/infra-kafka-connect/build.gradle.kts delete mode 100644 modules/infra-kafka-connect/src/main/docker/.env delete mode 100644 modules/infra-kafka-connect/src/main/docker/.gitignore delete mode 100644 modules/infra-kafka-connect/src/main/docker/docker-compose.yml delete mode 100644 modules/infra-kafka-connect/src/main/docker/kafka-connect.Dockerfile delete mode 100644 modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/Resources.kt delete mode 100644 modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/kafkaConnectAdmin.kt delete mode 100644 modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/websocketClient.kt delete mode 100644 modules/infra-kafka-connect/src/main/resources/configs/ckc-websocket-lua-objects.json5 delete mode 100644 modules/infra-kafka-connect/src/main/resources/configs/websocket-async-lua-objects.json5 diff --git a/modules/infra-kafka-connect/build.gradle.kts b/modules/infra-kafka-connect/build.gradle.kts deleted file mode 100644 index 69b2970..0000000 --- a/modules/infra-kafka-connect/build.gradle.kts +++ /dev/null @@ -1,116 +0,0 @@ -import dev.adamko.kafkatorio.gradle.asConsumer -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs - -plugins { - dev.adamko.kafkatorio.infra.`docker-compose` - dev.adamko.kafkatorio.lang.`kotlin-jvm` -} - -val dockerSrcDir: Directory by extra(layout.projectDirectory.dir("src/main/docker")) -val connectorJarDir: Directory = dockerSrcDir.dir("camel-kafka-connectors") - -val camelConnectorDependencies: Configuration by configurations.creating { asConsumer() } - -fun DependencyHandlerScope.kafkaConnector( - name: String, - group: String = "org.apache.camel.kafkaconnector", - version: String = libs.versions.camel.kafkaConnectors.get(), - classifier: String = "package", - extension: String = "tar.gz", -) { - camelConnectorDependencies(group, name, version, ext = extension, classifier = classifier) -} - -dependencies { - implementation(platform(projects.modules.versionsPlatform)) - - kotlin("reflect") - - kafkaConnector("camel-ahc-ws-kafka-connector") - kafkaConnector("camel-websocket-kafka-connector") - - implementation("com.github.adamko-dev:json5-kotlin:2.0.3") - - implementation(libs.bundles.http4k) - - implementation(libs.kotlinx.serialization.core) - implementation(libs.kotlinx.serialization.json) -} - -// disabled for now... -val projectEnabled = false - -val dockerBuildKafkaConnect by tasks.registering(Exec::class) { - enabled = projectEnabled - - group = "docker-compose" - dependsOn(downloadCamelConnectors, tasks.dockerEnv) - - logging.captureStandardOutput(LogLevel.LIFECYCLE) - - inputs.dir(dockerSrcDir) - - workingDir = dockerSrcDir.asFile - commandLine = parseSpaceSeparatedArgs(""" docker-compose build connect """) -} -//tasks.assemble { dependsOn(dockerBuildKafkaConnect) } - - -val downloadCamelConnectors by tasks.registering(Sync::class) { - enabled = projectEnabled - - group = project.name - description = "Retrieve Camel Kafka Connectors from Maven, in preparation for the Docker build" - - dependsOn(camelConnectorDependencies) - - from( - provider { camelConnectorDependencies } - .map { eventsSchema -> - eventsSchema.incoming - .artifacts - .artifactFiles - } - ) - into(temporaryDir) - - doLast { - sync { - fileTree(temporaryDir) - .asFileTree - .forEach { zip -> - from(tarTree(zip)) - } - into(connectorJarDir) - } - } -} - -tasks.dockerUp { - enabled = projectEnabled - - dependsOn(":modules:infra-kafka-cluster:dockerUp") - dependsOn(downloadCamelConnectors) -} - -tasks.dockerEnv { - enabled = projectEnabled - - properties( - "CONNECTOR_ID" to "kafkatorio-connect", - "KAFKA_CONNECT_VERSION" to libs.versions.confluent.kafkaConnect.get(), - ) -} - -idea { - module { - excludeDirs.add(file("src/main/docker/camel-kafka-connectors")) - } -} - -tasks.withType().configureEach { - kotlinOptions.freeCompilerArgs += listOf( - "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", - ) -} diff --git a/modules/infra-kafka-connect/src/main/docker/.env b/modules/infra-kafka-connect/src/main/docker/.env deleted file mode 100644 index 3af8d5f..0000000 --- a/modules/infra-kafka-connect/src/main/docker/.env +++ /dev/null @@ -1,4 +0,0 @@ -# Do not edit manually. This file was created with task 'dockerEnv' -COMPOSE_PROJECT_NAME=kafkatorio -CONNECTOR_ID=kafkatorio-connect -KAFKA_CONNECT_VERSION=7.0.1 diff --git a/modules/infra-kafka-connect/src/main/docker/.gitignore b/modules/infra-kafka-connect/src/main/docker/.gitignore deleted file mode 100644 index 664df74..0000000 --- a/modules/infra-kafka-connect/src/main/docker/.gitignore +++ /dev/null @@ -1 +0,0 @@ -camel-kafka-connectors/ diff --git a/modules/infra-kafka-connect/src/main/docker/docker-compose.yml b/modules/infra-kafka-connect/src/main/docker/docker-compose.yml deleted file mode 100644 index 278ba19..0000000 --- a/modules/infra-kafka-connect/src/main/docker/docker-compose.yml +++ /dev/null @@ -1,55 +0,0 @@ -version: "3.9" - -services: - - connect: - image: adamko-dev/kafkatorio-kafka-connect:${KAFKA_CONNECT_VERSION} - hostname: ${CONNECTOR_ID} - container_name: ${CONNECTOR_ID} - build: - context: "." - dockerfile: kafka-connect.Dockerfile - args: - KAFKA_CONNECT_VERSION: ${KAFKA_CONNECT_VERSION} -# FILE_PULSE_VERSION: ${CONNECTOR_FILE_PULSE_VERSION} -# CAMEL_KC_VERSION: ${CONNECTOR_CAMEL_KAFKA_VERSION} -# CAMEL_CONNECTOR: ${CAMEL_FILE_CONNECTOR} - ports: - - "8083:8083" - - "8095:8095" # ws-async (client?) - - "9292:9292" # websocket server(?) -# volumes: -# - "./connect/input:/warehouse/input" -# - "./connect/components:/usr/share/confluent-hub-components" - -# volumes: -# - "./camel-kafka-connectors:/usr/share/java" - networks: - - "kafkatorio-nw" - environment: - CONNECT_BOOTSTRAP_SERVERS: "kafka:29092" -# CONNECT_REST_ADVERTISED_HOST_NAME: ${CONNECTOR_ID} - CONNECT_REST_ADVERTISED_HOST_NAME: connect -# CONNECT_VALUE_CONVERTER_SCHEMA_REGISTRY_URL: "http://${SCHEMA_REGISTRY}:8081" -# CONNECT_REST_PORT: 28083 - CONNECT_REST_PORT: 8083 - CONNECT_GROUP_ID: ${CONNECTOR_ID} - CONNECT_CONFIG_STORAGE_TOPIC: ${CONNECTOR_ID}-configs - CONNECT_CONFIG_STORAGE_REPLICATION_FACTOR: 1 - CONNECT_OFFSET_FLUSH_INTERVAL_MS: 10000 - CONNECT_OFFSET_STORAGE_TOPIC: ${CONNECTOR_ID}-offsets - CONNECT_OFFSET_STORAGE_REPLICATION_FACTOR: 1 - CONNECT_STATUS_STORAGE_TOPIC: ${CONNECTOR_ID}-status - CONNECT_STATUS_STORAGE_REPLICATION_FACTOR: 1 - CONNECT_KEY_CONVERTER: "org.apache.kafka.connect.storage.StringConverter" -# CONNECT_VALUE_CONVERTER: "io.confluent.connect.avro.AvroConverter" - CONNECT_VALUE_CONVERTER: "org.apache.kafka.connect.json.JsonConverter" - CONNECT_PLUGIN_PATH: "/usr/share/java,/usr/share/camel-kafka-connectors" - CONNECT_LOG4J_ROOT_LOGLEVEL: INFO - CONNECT_LOG4J_LOGGERS: "org.apache.zookeeper=INFO,org.I0Itec.zkclient=ERROR,org.reflections=ERROR" -# CONNECT_LISTENERS: "http://localhost:28083" - -networks: - kafkatorio-nw: - name: "kafkatorio-nw" - external: true diff --git a/modules/infra-kafka-connect/src/main/docker/kafka-connect.Dockerfile b/modules/infra-kafka-connect/src/main/docker/kafka-connect.Dockerfile deleted file mode 100644 index 885c292..0000000 --- a/modules/infra-kafka-connect/src/main/docker/kafka-connect.Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -ARG KAFKA_CONNECT_VERSION - - -FROM confluentinc/cp-kafka-connect-base:${KAFKA_CONNECT_VERSION} - -ENV CONNECT_VERSION=${KAFKA_CONNECT_VERSION} - -USER 0:0 - -COPY ./camel-kafka-connectors /usr/share/camel-kafka-connectors - -#WORKDIR /usr/share/java/ -# -##ENV CAMEL_KC_VERSION=0.9.0 -##ENV CAMEL_CONNECTOR=camel-file-kafka-connector -# -#ENV URL=https://repo.maven.apache.org/maven2/org/apache/camel/kafkaconnector/camel-file-kafka-connector/0.9.0/camel-file-kafka-connector-0.9.0-package.tar.gz -# -#RUN curl -L $URL | tar -xzvf - --strip=0 $CAMEL_CONNECTOR diff --git a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/Resources.kt b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/Resources.kt deleted file mode 100644 index 0e6406c..0000000 --- a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/Resources.kt +++ /dev/null @@ -1,10 +0,0 @@ -package dev.adamko.kafkatorio.kafkaconnect - -import java.io.File - -object Resources { - fun loadResource(name: String): File = - File(requireNotNull(Resources::class.java.getResource(name)?.file) { - "could not load resource '$name'" - }) -} diff --git a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/kafkaConnectAdmin.kt b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/kafkaConnectAdmin.kt deleted file mode 100644 index e8eccfb..0000000 --- a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/kafkaConnectAdmin.kt +++ /dev/null @@ -1,92 +0,0 @@ -package dev.adamko.kafkatorio.kafkaconnect - -import at.syntaxerror.json5.Json5Module -import kotlinx.serialization.decodeFromString -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.jsonPrimitive -import org.http4k.client.OkHttp -import org.http4k.core.Method.GET -import org.http4k.core.Method.PUT -import org.http4k.core.Request -import org.http4k.core.Uri - -val jsonMapper = Json { - prettyPrint = true - prettyPrintIndent = " " -} - -val j5 = Json5Module() - -fun main() { - - val connectorHostUrl = Uri.of("http://localhost:8083") - - val configFile = Resources.loadResource("/configs/ckc-websocket-lua-objects.json5") - - val jsonObject: JsonObject = j5.decodeObject(configFile.readText()) - println("json5 connector config: $jsonObject") - val configJson = jsonMapper.encodeToString(jsonObject) - println("json connector config: $configJson") - - val connectorName = jsonObject["name"]!!.jsonPrimitive.content - - val request: Request = - Request(PUT, connectorHostUrl.path("/connectors/$connectorName/config")) - .header("Content-Type", "application/json") - .header("Accept", "application/json") -// .header("Accept-Encoding", "identity") - .body(configJson) - - val client = OkHttp() - - // check the status of KC - val statusResponse = client(Request(GET, connectorHostUrl)) - println(statusResponse.toMessage()) - - val response = client(request) - - println(response.toMessage()) - println( - jsonMapper.encodeToString( - jsonMapper.decodeFromString(response.body.toString()) - ) - ) -} - -//val updateConnectors by tasks.registering { -// group = project.name -// -// val configFile = layout.projectDirectory.file("configs/websocket-async-lua-objects.json5") -// inputs.file(configFile) -// -// doLast { -// val fileText = resources.text.fromFile(configFile) -// -// val jsonObject: JsonObject = j5.decodeObject(fileText.asString()) -// -// logger.lifecycle("out: $jsonObject") -// val configJson = jsonMapper.encodeToString(jsonObject) -// logger.lifecycle("configJson: $configJson") -// -// val request = Request( -// PUT, -// Uri.of("http://localhost:8083").path("/connectors/kafkatorio-ws-connector/config") -// ).header("Content-Type", "application/json") -// .body(configJson) -// -// -// val client = OkHttp() -// val response = client(request) -// -// println(response.toMessage()) -// println( -// jsonMapper.encodeToString( -// jsonMapper.decodeFromString(response.body.toString()) -// ) -// ) -// } -// -//} diff --git a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/websocketClient.kt b/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/websocketClient.kt deleted file mode 100644 index 1763679..0000000 --- a/modules/infra-kafka-connect/src/main/kotlin/dev/adamko/kafkatorio/kafkaconnect/websocketClient.kt +++ /dev/null @@ -1,41 +0,0 @@ -package dev.adamko.kafkatorio.kafkaconnect - -import java.time.Duration -import org.http4k.client.WebsocketClient -import org.http4k.core.Uri -import org.http4k.websocket.WsMessage - -fun main() { - - val client = WebsocketClient.blocking( - uri = Uri.of("ws://localhost:9073/ws"), -// autoReconnection = true, -// timeout = Duration.ofSeconds(30) - ) -// client.send(WsMessage("server sent on connection")) - - client.received() - .take(100) - .forEachIndexed { index, wsMessage -> - println("[$index] ${wsMessage.bodyString()}") - } - - -// val nonBlockingClient = WebsocketClient.nonBlocking( -// uri = Uri.of("ws://localhost:9097/lua-objects"), -// onError = { it.printStackTrace() }, -// onConnect = { ws -> -// println("onConnect, ws.upgradeRequest ${ws.upgradeRequest}") -//// ws.send(WsMessage("client sent on connection")) -// } -// ) -// -// nonBlockingClient.onMessage { msg -> print(msg.bodyString()) } -// nonBlockingClient.onClose { -// println("non-blocking client closing") -// } -//// nonBlockingClient.onError { it.printStackTrace() } -// -// Thread.sleep(Duration.ofMinutes(1).toMillis()) - -} diff --git a/modules/infra-kafka-connect/src/main/resources/configs/ckc-websocket-lua-objects.json5 b/modules/infra-kafka-connect/src/main/resources/configs/ckc-websocket-lua-objects.json5 deleted file mode 100644 index c96e8c8..0000000 --- a/modules/infra-kafka-connect/src/main/resources/configs/ckc-websocket-lua-objects.json5 +++ /dev/null @@ -1,130 +0,0 @@ -{ - "name": "ckc-websocket-lua-objects", - "connector.class": "org.apache.camel.kafkaconnector.websocket.CamelWebsocketSinkConnector", - "topics.regex": "^Lua.*$", - "key.converter": "org.apache.kafka.connect.storage.StringConverter", - "value.converter": "org.apache.kafka.connect.storage.StringConverter", - // The hostname. The default value is 0.0.0.0. Setting this option on the component will use the - // component configured value as default. - "camel.sink.path.host": "0.0.0.0", -// "camel.sink.path.host": "host.docker.internal", - // The port number. The default value is 9292. Setting this option on the component will use the - // component configured value as default. - "camel.sink.path.port": "9292", - // Name of the websocket channel to use - "camel.sink.path.resourceUri": "lua-objects", - "camel.sink.endpoint.sendToAll": "true", - "camel.component.websocket.host":"0.0.0.0", - "camel.component.websocket.port": "8084", - // Can be used to set the size in bytes that the websocket created by the websocketServlet may - // be accept before closing. (Default is -1 - or unlimited) - // "camel.sink.endpoint.maxBinaryMessageSize": -1, - - // Whether the producer should be started lazy (on the first message). By starting lazy you can - // use this to allow CamelContext and routes to startup in situations where a producer may otherwise - // fail during starting and cause the route to fail being started. By deferring this startup to be - // lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. - // Beware that when the first message is processed then creating and starting the producer may take a little - // time and prolong the total processing time of the processing. - // "camel.sink.endpoint.lazyStartProducer": false, - - // Timeout in millis when sending to a websocket channel. The default timeout is 30000 (30 seconds). - // "camel.sink.endpoint.sendTimeout": 30000, - - // To send to all websocket subscribers. Can be used to configure on endpoint level, instead of - // having to use the WebsocketConstants.SEND_TO_ALL header on the message. - // "camel.sink.endpoint.sendToAll": , - - // Set the buffer size of the websocketServlet, which is also the max frame byte size (default - // 8192) - // "camel.sink.endpoint.bufferSize": 8192, - - // Set the time in ms that the websocket created by the websocketServlet may be idle before - // closing. (default is 300000) - // "camel.sink.endpoint.maxIdleTime": 300000, - - // Can be used to set the size in characters that the websocket created by the websocketServlet - // may be accept before closing. - // "camel.sink.endpoint.maxTextMessageSize": , - - // Can be used to set the minimum protocol version accepted for the websocketServlet. - // (Default 13 - the RFC6455 version) - // "camel.sink.endpoint.minVersion": 13, - - // The CORS allowed origins. Use to allow all. - // "camel.sink.endpoint.allowedOrigins": , - - // Whether to enable CORS - // "camel.sink.endpoint.crossOriginFilterOn": false, - - // Context path for filtering CORS - // "camel.sink.endpoint.filterPath": , - - // If this option is true, Jetty JMX support will be enabled for this endpoint. See Jetty JMX - // support for more details. - // "camel.sink.endpoint.enableJmx": false, - - // To configure security using SSLContextParameters - // "camel.sink.endpoint.sslContextParameters": , - - // The hostname. The default value is 0.0.0.0 - // "camel.component.websocket.host": "0.0.0.0", - - // The port number. The default value is 9292 - // "camel.component.websocket.port": 9292, - - // Whether the producer should be started lazy (on the first message). By starting lazy you can - // use this to allow CamelContext and routes to startup in situations where a producer may otherwise - // fail during starting and cause the route to fail being started. By deferring this startup to be - // lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. - // Beware that when the first message is processed then creating and starting the producer may take a little - // time and prolong the total processing time of the processing. - // "camel.component.websocket.lazyStartProducer": false, - - // Whether autowiring is enabled. This is used for automatic autowiring options (the option must - // be marked as autowired) by looking up in the registry to find if there is a single instance - // of matching type, which then gets configured on the component. This can be used for automatic - // configuring JDBC data sources, JMS connection factories, AWS Clients, etc. - // "camel.component.websocket.autowiredEnabled": true, - - // If this option is true, Jetty JMX support will be enabled for this endpoint. See Jetty JMX - // support for more details. - // "camel.component.websocket.enableJmx": false, - - // To set a value for maximum number of threads in server thread pool. MaxThreads\/minThreads - // or threadPool fields are required due to switch to Jetty9. The default values for maxThreads - // is 1 2 noCores. - // "camel.component.websocket.maxThreads": , - - // To set a value for minimum number of threads in server thread pool. MaxThreads\/minThreads - // or threadPool fields are required due to switch to Jetty9. The default values for minThreads - // is 1. - // "camel.component.websocket.minThreads": , - - // This is a comma-separated list of subprotocols that are supported by the application. The list - // is in priority order. The first subprotocol on this list that is proposed by the client is - // the one that will be accepted. If no subprotocol on this list is proposed by the client, then the - // websocket connection is refused. The special value 'any' means that any subprotocol is acceptable. 'any' - // can be used on its own, or as a failsafe at the end of a list of more specific protocols. 'any' will also - // match the case where no subprotocol is proposed by the client. - // "camel.component.websocket.subprotocol": "any", - - // To use a custom thread pool for the server. MaxThreads\/minThreads or threadPool fields are - // required due to switch to Jetty9. - // "camel.component.websocket.threadPool": , - - // To configure security using SSLContextParameters - // "camel.component.websocket.sslContextParameters": , - - // The password for the keystore when using SSL. - // "camel.component.websocket.sslKeyPassword": , - - // The path to the keystore. - // "camel.component.websocket.sslKeystore": , - - // The password when using SSL. - // "camel.component.websocket.sslPassword": , - - // Enable usage of global SSL context parameters. - // "camel.component.websocket.useGlobalSslContextParameters": false, -} diff --git a/modules/infra-kafka-connect/src/main/resources/configs/websocket-async-lua-objects.json5 b/modules/infra-kafka-connect/src/main/resources/configs/websocket-async-lua-objects.json5 deleted file mode 100644 index 19837c3..0000000 --- a/modules/infra-kafka-connect/src/main/resources/configs/websocket-async-lua-objects.json5 +++ /dev/null @@ -1,84 +0,0 @@ -//Exchange data with external Websocket servers using Async Http Client -{ - name: "websocket-async-lua-objects", - "connector.class": "org.apache.camel.kafkaconnector.ahcws.CamelAhcwsSinkConnector", - "tasks.max": 1, - //use the kafka converters that better suit your needs, these are just defaults: - "key.converter": "org.apache.kafka.connect.storage.StringConverter", - "value.converter": "org.apache.kafka.connect.storage.StringConverter", - //https://docs.confluent.io/platform/current/installation/configuration/connect/sink-connect-configs.html#sinkconnectorconfigs_topics - //List of topics to consume, separated by commas - // topics= - "topics.regex": "^Lua.*$", - - // mandatory properties (for a complete properties list see the connector documentation): - - // The URI to use such as http://hostname:port/path - "camel.sink.path.httpUri": "host.docker.internal:8095/ws/lua", - // If the option is true, then the Exchange.HTTP_URI header is ignored, and use the endpoint's - // URI for request. You may also set the throwExceptionOnFailure to be false to let the - // AhcProducer send all the fault response back. - // camel.sink.endpoint.bridgeEndpoint= - - // The initial in-memory buffer size used when transferring data between Camel and AHC Client. - // camel.sink.endpoint.bufferSize= - // To use a custom HeaderFilterStrategy to filter header to and from Camel message. - // camel.sink.endpoint.headerFilterStrategy= - // Option to disable throwing the AhcOperationFailedException in case of failed responses from - // the remote server. This allows you to get all responses regardless of the HTTP status code. - // camel.sink.endpoint.throwExceptionOnFailure= - // If enabled and an Exchange failed processing on the consumer side, and if the caused - - // Exception was send back serialized in the response as a application\/x-java-serialized-object - // content type (for example using Jetty or Servlet Camel components). On the producer side the - // exception will be deserialized and thrown as is, instead of the AhcOperationFailedException. - // The caused exception is required to be serialized. This is by default turned off. - // If you enable this then be aware that Java will deserialize the incoming data from the - // request to Java and that can be a potential security risk. - // camel.sink.endpoint.transferException= - - // Define if the Connection Close header has to be added to HTTP Request. This parameter is false by default - // camel.sink.endpoint.connectionClose= - // Configure a cookie handler to maintain a HTTP session - // camel.sink.endpoint.cookieHandler= - - // Whether the producer should be started lazy (on the first message). By starting lazy you can - // use this to allow CamelContext and routes to startup in situations where a producer - // may otherwise fail during starting and cause the route to fail being started. By deferring - // this startup to be lazy then the startup failure can be handled during routing messages via - // Camel's routing error handlers. Beware that when the first message is processed then creating - // and starting the producer may take a little time and prolong the total processing time of the - // processing. - // camel.sink.endpoint.lazyStartProducer= - - // To enable streaming to send data as multiple text fragments. - // camel.sink.endpoint.useStreaming= - // To use a custom AhcBinding which allows to control how to bind between AHC and Camel. - // camel.sink.endpoint.binding= - // To configure the AsyncHttpClient to use a custom com.ning.http.client.AsyncHttpClientConfig instance. - // camel.sink.endpoint.clientConfig= - // To configure the AsyncHttpClientConfig using the key\/values from the Map. - // camel.sink.endpoint.clientConfigOptions= - // To configure the AsyncHttpClientConfig Realm using the key\/values from the Map. - // camel.sink.endpoint.clientConfigRealmOptions= - // Reference to a org.apache.camel.support.jsse.SSLContextParameters in the Registry. This reference overrides any configured SSLContextParameters at the component level. See Using the JSSE Configuration Utility. Note that configuring this option will override any SSL\/TLS configuration options provided through the clientConfig option at the endpoint or component level. - // camel.sink.endpoint.sslContextParameters= - // Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and starting the producer may take a little time and prolong the total processing time of the processing. - // camel.component.ahc-ws.lazyStartProducer= - // Whether to allow java serialization when a request uses context-type=application\/x-java-serialized-object This is by default turned off. If you enable this then be aware that Java will deserialize the incoming data from the request to Java and that can be a potential security risk. - // camel.component.ahc-ws.allowJavaSerializedObject= - // Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching type, which then gets configured on the component. This can be used for automatic configuring JDBC data sources, JMS connection factories, AWS Clients, etc. - // camel.component.ahc-ws.autowiredEnabled= - // To use a custom AhcBinding which allows to control how to bind between AHC and Camel. - // camel.component.ahc-ws.binding= - // To use a custom AsyncHttpClient - // camel.component.ahc-ws.client= - // To configure the AsyncHttpClient to use a custom com.ning.http.client.AsyncHttpClientConfig instance. - // camel.component.ahc-ws.clientConfig= - // To use a custom org.apache.camel.spi.HeaderFilterStrategy to filter header to and from Camel message. - // camel.component.ahc-ws.headerFilterStrategy= - // Reference to a org.apache.camel.support.jsse.SSLContextParameters in the Registry. Note that configuring this option will override any SSL\/TLS configuration options provided through the clientConfig option at the endpoint or component level. - // camel.component.ahc-ws.sslContextParameters= - // Enable usage of global SSL context parameters. - // camel.component.ahc-ws.useGlobalSslContextParameters= -} diff --git a/settings.gradle.kts b/settings.gradle.kts index 37b5fca..fee9190 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -10,7 +10,6 @@ include( ":modules:infra-kafka-cluster", ":modules:infra-kafka-pipe", - ":modules:infra-kafka-connect", ":modules:kt-rcon", ":modules:web-map", From dacb6f62c488f1c95f116c364f66de831b124ecd Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 26 Jun 2022 14:56:53 +0200 Subject: [PATCH 413/629] tidy up Gradle config, standardise a group for Factorio Mod tasks --- .../FactorioModPortalPublishClient.kt | 4 +- .../{ => portal}/FactorioModPublishTask.kt | 5 +- .../factoriomod/{ => portal}/model.kt | 2 +- .../adamko/kafkatorio/factoriomod/tasks.kt | 12 +++ .../kafkatorio/lang/kotlin-jvm.gradle.kts | 8 -- ...criptTask.kt => GenerateTypeScriptTask.kt} | 2 +- modules/events-mod/build.gradle.kts | 7 +- modules/events-schema/build.gradle.kts | 79 ++---------------- modules/events-server/build.gradle.kts | 10 +-- .../infra-factorio-client/build.gradle.kts | 20 +++-- .../infra-factorio-server/build.gradle.kts | 16 +++- modules/web-map/build.gradle.kts | 83 +++++-------------- settings.gradle.kts | 9 -- 13 files changed, 83 insertions(+), 174 deletions(-) rename buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/{ => portal}/FactorioModPortalPublishClient.kt (97%) rename buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/{ => portal}/FactorioModPublishTask.kt (95%) rename buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/{ => portal}/model.kt (98%) create mode 100644 buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/tasks.kt rename buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/{GenerateTypescriptTask.kt => GenerateTypeScriptTask.kt} (91%) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPortalPublishClient.kt similarity index 97% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt rename to buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPortalPublishClient.kt index cb920fe..7b1aead 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPortalPublishClient.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPortalPublishClient.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.factoriomod +package dev.adamko.kafkatorio.factoriomod.portal import io.ktor.client.HttpClient import io.ktor.client.engine.cio.CIO @@ -98,7 +98,7 @@ class FactorioModPortalPublishClient( require(response.status.isSuccess()) { "init upload request failed" } return when (initUploadResponse) { - is Failure -> error(initUploadResponse) + is Failure -> error(initUploadResponse) is InitUploadResponse.Success -> initUploadResponse } } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPublishTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPublishTask.kt similarity index 95% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPublishTask.kt rename to buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPublishTask.kt index 3a58751..d798e32 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/FactorioModPublishTask.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/FactorioModPublishTask.kt @@ -1,5 +1,6 @@ -package dev.adamko.kafkatorio.factoriomod +package dev.adamko.kafkatorio.factoriomod.portal +import dev.adamko.kafkatorio.factoriomod.FactorioMod import io.ktor.http.URLBuilder import io.ktor.http.takeFrom import javax.inject.Inject @@ -59,7 +60,7 @@ abstract class FactorioModPublishTask @Inject constructor( init { - group = "factorio" + group = FactorioMod.TASK_GROUP } diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/model.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/model.kt similarity index 98% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/model.kt rename to buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/model.kt index 8fad949..aee2ac6 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/model.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/portal/model.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.factoriomod +package dev.adamko.kafkatorio.factoriomod.portal import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/tasks.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/tasks.kt new file mode 100644 index 0000000..b657ace --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/factoriomod/tasks.kt @@ -0,0 +1,12 @@ +package dev.adamko.kafkatorio.factoriomod + +object FactorioMod { + + const val TASK_GROUP = "factorioMod" + + /** Lifecycle task for publishing the mod locally */ + const val PUBLISH_MOD_LOCAL_TASK_NAME = "publishModLocal" + + const val PUBLISH_MOD_TASK_NAME = "publishMod" + +} diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts index c0d902b..eb96e83 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/lang/kotlin-jvm.gradle.kts @@ -12,16 +12,8 @@ val projectJvmTarget = "11" dependencies { - -// implementation(platform("org.jetbrains.kotlin:kotlin-bom")) - -// testImplementation(platform("org.junit:junit-bom:${Versions.junit}")) testImplementation("org.junit.jupiter:junit-jupiter") -// testRuntimeOnly("org.junit.platform:junit-platform-launcher") { -// because("Only needed to run tests in a version of IntelliJ IDEA that bundles older versions") -// } -// testImplementation(platform("io.kotest:kotest-bom:${Versions.kotest}")) testImplementation("io.kotest:kotest-runner-junit5") testImplementation("io.kotest:kotest-assertions-core") testImplementation("io.kotest:kotest-property") diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypescriptTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypeScriptTask.kt similarity index 91% rename from buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypescriptTask.kt rename to buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypeScriptTask.kt index 51b7032..fab29ae 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypescriptTask.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypeScriptTask.kt @@ -8,7 +8,7 @@ import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction -abstract class GenerateTypescriptTask @Inject constructor( +abstract class GenerateTypeScriptTask @Inject constructor( private val fileOps: FileSystemOperations, ) : JavaExec() { diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 0a37eff..567fac2 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -1,4 +1,4 @@ -import dev.adamko.kafkatorio.factoriomod.FactorioModPublishTask +import dev.adamko.kafkatorio.factoriomod.portal.FactorioModPublishTask import dev.adamko.kafkatorio.gradle.asConsumer import dev.adamko.kafkatorio.gradle.asProvider import dev.adamko.kafkatorio.gradle.dropDirectory @@ -43,7 +43,7 @@ val projectTokensX = projectTokens.apply { put("mod.name", modName) put("mod.title", "Kafkatorio Events") put("mod.description", modDescription) - put("factorio.version", modFactorioCompatibility.get()) + put("factorio.version", modFactorioCompatibility) } val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") @@ -139,7 +139,8 @@ distributions { from(licenseFile) from(typescriptToLua.map { it.outputDirectory }) filesNotMatching("**/*.png") { - filter("tokens" to projectTokens.get()) + val tokens: MutableMap = projectTokens.get() + filter("tokens" to tokens) } includeEmptyDirs = false exclude { diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index 2a1907f..31b22fa 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -1,6 +1,6 @@ import dev.adamko.kafkatorio.gradle.asProvider import dev.adamko.kafkatorio.gradle.typescriptAttributes -import dev.adamko.kafkatorio.task.GenerateTypescriptTask +import dev.adamko.kafkatorio.task.GenerateTypeScriptTask plugins { @@ -14,25 +14,8 @@ plugins { kotlin { js(IR) { -// binaries.executable() browser {} - // browser{} causes this error: - // Cannot load "webpack", it is not registered! - // Perhaps you are missing some plugin? - // Cannot load "sourcemap", it is not registered! - // Perhaps you are missing some plugin? - // Server start failed on port 9876: Error: No provider for "framework:mocha"! (Resolving: framework:mocha) - // browser { - // runTask { - // sourceMaps = true - // } - // testTask { - // useKarma { - // useChromeHeadless() - // } - // } - // } -// nodejs() + // this is a library - don't set binaries.executable() } jvm { val main by compilations.getting { @@ -75,9 +58,6 @@ kotlin { implementation(project.dependencies.platform(libs.kotest.bom)) implementation("io.kotest:kotest-framework-engine") -// implementation("io.kotest:kotest-assertions-core") -// implementation("io.kotest:kotest-property") -// implementation("io.kotest:kotest-assertions-json") implementation(libs.kotest.core) implementation(libs.kotest.datatest) implementation(libs.kotest.prop) @@ -88,10 +68,7 @@ kotlin { val jvmMain by getting { dependencies { implementation("com.github.aSemy:ts-generator:v1.2.1") -// implementation("com.github.ntrrgc:ts-generator:1.1.2") implementation(kotlin("reflect")) - -// implementation("com.github.adamko-dev:kotlinx-serialization-typescript-generator:0.0.5") } } @@ -114,7 +91,7 @@ val mainCompilation: Provider = kotlin.jvm().compilations.named("main").map { it.runtimeDependencyFiles } -val generateTypescript by tasks.registering(GenerateTypescriptTask::class) { +val generateTypeScript by tasks.registering(GenerateTypeScriptTask::class) { dependsOn(jvmJar) classpath( jvmJar, @@ -125,68 +102,26 @@ val generateTypescript by tasks.registering(GenerateTypescriptTask::class) { args(temporaryDir.canonicalPath) } -//val generateTypescript2 by tasks.registering(JavaExec::class) { -// group = "kt2ts" -// -// dependsOn(jvmJar) -// -// inputs.files(mainCompilation) -// -// classpath( -// jvmJar, -// mainCompilation, -// ) -// mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2ts2Kt") -// -// args(temporaryDir) -// -// val buildOutput = layout.buildDirectory.dir("generated/typescript") -// outputs.dir(buildOutput) -// -// doFirst { -// delete(temporaryDir) -// mkdir(temporaryDir) -// } -// -// doLast { -// sync { -// from(temporaryDir) -// into(buildOutput) -// include("**/*.ts") -// } -// } -//} - val schemaTsDistributionName: Provider = providers.provider { "${rootProject.name}-${project.name}" } -val generateTypescriptOutputFiles: Provider = - generateTypescript.map { it.outputs.files.asFileTree } +val generateTypeScriptOutputFiles: Provider = + generateTypeScript.map { it.outputs.files.asFileTree } val schemaTs by distributions.registering { distributionBaseName.set(schemaTsDistributionName) contents { - from(generateTypescriptOutputFiles) + from(generateTypeScriptOutputFiles) } } val schemaTsZipTask: TaskProvider = tasks.named("${schemaTs.name}DistZip") val schemaTsZipTaskArchiveFile: Provider = schemaTsZipTask.flatMap { it.archiveFile } -val typescriptModelGenerated: Configuration by configurations.creating { +val typeScriptModelGenerated: Configuration by configurations.creating { asProvider() typescriptAttributes(objects) outgoing.artifact(schemaTsZipTaskArchiveFile) } - - -//tasks.matching { -// it.name == "jsGenerateExternalsIntegrated" -//}.configureEach { -// @Suppress("UnstableApiUsage") -// notCompatibleWithConfigurationCache("try to prevent 'Projects must be configuring' error") -//// outputs.upToDateWhen { true } -// dependsOn(":kotlinNpmInstall") -//} diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 25580f9..7978403 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -1,12 +1,14 @@ import dev.adamko.kafkatorio.task.KafkaConsumerGroupsTask import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { dev.adamko.kafkatorio.lang.`kotlin-jvm` kotlin("plugin.serialization") application } + description = """ Receive raw Factorio Events from Kafka and process them into targeted topics or data formats. @@ -17,6 +19,7 @@ val projectId: String by project.extra val kafkaStateDir: Directory = layout.projectDirectory.dir("kafka-state") + dependencies { implementation(platform(projects.modules.versionsPlatform)) @@ -49,9 +52,6 @@ dependencies { implementation(libs.bundles.hoplite) } -//configurations.all { -// resolutionStrategy.cacheDynamicVersionsFor(1, TimeUnit.MINUTES) -//} application { mainClass.set("dev.adamko.kafkatorio.processor.EventProcessorKt") @@ -93,7 +93,3 @@ idea { excludeDirs = excludeDirs + kafkaStateDir.asFile } } - -//tasks.withType().all { -// notCompatibleWithConfigurationCache("error: Projects must be configuring") -//} diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index 779c712..33d76a1 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -1,3 +1,4 @@ +import dev.adamko.kafkatorio.factoriomod.FactorioMod import dev.adamko.kafkatorio.gradle.asConsumer import dev.adamko.kafkatorio.gradle.factorioModAttributes import dev.adamko.kafkatorio.gradle.not @@ -34,10 +35,11 @@ dependencies { factorioMod(projects.modules.eventsMod) } + // val deployModToClient by tasks.registering(Copy::class) { description = "Copy the mod to the Factorio client" - group = project.name + group = FactorioMod.TASK_GROUP onlyIf { clientModsDirectory.orNull?.asFile?.exists() == true } @@ -50,13 +52,14 @@ val deployModToClient by tasks.registering(Copy::class) { } // + // fun ExecOperations.isFactorioRunning(): Spec = ProcessRunningSpec(this, "factorio.exe") val clientLaunch by tasks.registering(Exec::class) { - description = "Run Factorio Steam game client" - group = project.name + description = "Run local Factorio Steam game client" + group = FactorioMod.TASK_GROUP onlyIf(!serviceOf().isFactorioRunning()) onlyIf { steamExe.orNull?.asFile?.exists() == true } @@ -74,8 +77,8 @@ val clientLaunch by tasks.registering(Exec::class) { } val clientKill by tasks.registering(Exec::class) { - description = "Run Factorio Steam game client" - group = project.name + description = "Stop the local Factorio Steam game client" + group = FactorioMod.TASK_GROUP onlyIf(serviceOf().isFactorioRunning()) @@ -84,7 +87,12 @@ val clientKill by tasks.registering(Exec::class) { } // -tasks.build { dependsOn(deployModToClient) } + +tasks.register(FactorioMod.PUBLISH_MOD_LOCAL_TASK_NAME) { + group = FactorioMod.TASK_GROUP + dependsOn(deployModToClient) +} + tasks.processRun { dependsOn( diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 7d75285..158e151 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -1,3 +1,4 @@ +import dev.adamko.kafkatorio.factoriomod.FactorioMod import dev.adamko.kafkatorio.gradle.asConsumer import dev.adamko.kafkatorio.gradle.factorioModAttributes import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs @@ -6,21 +7,25 @@ plugins { dev.adamko.kafkatorio.infra.`docker-compose` } + val dockerSrcDir: Directory by extra val factorioServerDataDir: Directory = dockerSrcDir.dir("factorio-server") + val factorioMod: Configuration by configurations.creating { asConsumer() factorioModAttributes(objects) } + dependencies { factorioMod(projects.modules.eventsMod) } + val deployModToServer by tasks.registering(Copy::class) { description = "Copy the mod to the Factorio Docker server" - group = project.name + group = FactorioMod.TASK_GROUP dependsOn(factorioMod) @@ -34,10 +39,12 @@ val deployModToServer by tasks.registering(Copy::class) { } } + tasks.dockerDown { commandLine = parseSpaceSeparatedArgs(""" docker-compose stop """) } + tasks.dockerUp { dependsOn( deployModToServer, @@ -45,11 +52,16 @@ tasks.dockerUp { ) } + tasks.dockerEnv { properties("FACTORIO_VERSION" to libs.versions.factorio.get()) } -tasks.build { dependsOn(deployModToServer) } + +tasks.register(FactorioMod.PUBLISH_MOD_LOCAL_TASK_NAME) { + group = FactorioMod.TASK_GROUP + dependsOn(deployModToServer) +} idea { diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index a714375..8a02c87 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -1,4 +1,3 @@ -import dev.adamko.kafkatorio.gradle.taskProvider import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig @@ -17,6 +16,7 @@ kvision { enableHiddenKotlinJsStore.set(false) } + rootProject.extensions.configure { // https://github.com/rjaros/kvision/issues/410 versions.webpackCli.version = "4.10.0" @@ -48,13 +48,9 @@ afterEvaluate { kotlin { js(IR) { -// browser() -// binaries.executable() -// } -// -// js("frontend", IR) { -// nodejs() browser { + binaries.executable() + runTask { outputFileName = "main.bundle.js" sourceMaps = false @@ -87,16 +83,11 @@ kotlin { } } } - binaries.executable() // compilations["main"].packageJson { // this.devDependencies["webpack-dev-server"] = "4.9.1" // } } -// jvm("backend") { -// -// } - sourceSets { all { @@ -106,7 +97,6 @@ kotlin { } } -// val commonMain by getting { main { dependencies { implementation(dependencies.platform(libs.kotlinx.coroutines.bom)) @@ -117,13 +107,6 @@ kotlin { implementation(projects.modules.eventsSchema) implementation(libs.kotlinx.html) -// } -// } - -// val jsMain by getting { -// dependsOn(commonMain) -// -// dependencies { implementation(projects.modules.eventsSchema) @@ -154,37 +137,15 @@ kotlin { // implementation(dependencies.platform(devNpm("webpack-dev-server", "4.9.1"))) } -// val webDir = file("src/main/web") resources.srcDir("src/main/web") -// resources.srcDir("src/main/resources") - -// kotlin.srcDir("src/main/kotlin") } -// val frontendMain by getting { -// dependsOn(jsMain) -//// resources.srcDir("src/main/web") -//// resources.srcDir("src/main/resources") -// } -// -// val jsTest by getting { -// dependencies { -// implementation(kotlin("test-js")) -// -// kvision("kvision-testutils") -// -//// implementation(npm("karma", "^6.3.16")) -// } -// -// kotlin.srcDir("src/test/kotlin") -// } test { dependencies { implementation(kotlin("test-js")) kvision("kvision-testutils") - // implementation(npm("karma", "^6.3.16")) } } @@ -221,22 +182,22 @@ fun KotlinDependencyHandler.kvision( //evaluationDependsOn(projects.modules.eventsSchema.dependencyProject.path) -// stop warnings when building -tasks.configureEach { - when (name) { - "productionExecutableCompileSync" -> - dependsOn(taskProvider("compileProductionExecutableKotlinJs")) - "testTestDevelopmentExecutableCompileSync" -> - dependsOn(taskProvider("compileTestDevelopmentExecutableKotlinJs")) -// "jsTestTestDevelopmentExecutableCompileSync" -> -// dependsOn(taskProvider("compileTestDevelopmentExecutableKotlinFrontend")) -// "jsProductionExecutableCompileSync" -> -// dependsOn(taskProvider("compileProductionExecutableKotlinFrontend")) - "browserDevelopmentRun" -> - dependsOn(taskProvider("browserDevelopmentWebpack")) - "browserDevelopmentWebpack" -> - dependsOn(taskProvider("assemble")) - "browserProductionWebpack" -> - dependsOn(taskProvider("developmentExecutableCompileSync")) - } -} +//// stop warnings when building +//tasks.configureEach { +// when (name) { +// "productionExecutableCompileSync" -> +// dependsOn(taskProvider("compileProductionExecutableKotlinJs")) +// "testTestDevelopmentExecutableCompileSync" -> +// dependsOn(taskProvider("compileTestDevelopmentExecutableKotlinJs")) +//// "jsTestTestDevelopmentExecutableCompileSync" -> +//// dependsOn(taskProvider("compileTestDevelopmentExecutableKotlinFrontend")) +//// "jsProductionExecutableCompileSync" -> +//// dependsOn(taskProvider("compileProductionExecutableKotlinFrontend")) +// "browserDevelopmentRun" -> +// dependsOn(taskProvider("browserDevelopmentWebpack")) +// "browserDevelopmentWebpack" -> +// dependsOn(taskProvider("assemble")) +// "browserProductionWebpack" -> +// dependsOn(taskProvider("developmentExecutableCompileSync")) +// } +//} diff --git a/settings.gradle.kts b/settings.gradle.kts index fee9190..b39fab1 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -25,14 +25,5 @@ apply(from = "./buildSrc/repositories.settings.gradle.kts") @Suppress("UnstableApiUsage") // Central declaration of repositories is an incubating feature dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) - -// repositories { -// maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") { -//// content { -//// includeGroup("dev.adamko.kxstsgen") -//// } -// } -// } } From c9df87e5e0545bcc6ba09f09f1dcc0291eda7a56 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 26 Jun 2022 14:57:14 +0200 Subject: [PATCH 414/629] fix NPE for config update event --- .../typescript/main/config-update/handleConfigurationUpdate.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts index 109d5b7..4808d6c 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts +++ b/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts @@ -38,7 +38,7 @@ function allMods(e: ConfigurationChangedData): ConfigurationUpdateModData[] { return modNames.map((modName) => { - let currentVer = script.active_mods[modName] ?? e.mod_changes[modName].new_version ?? null + let currentVer = script.active_mods[modName] ?? e.mod_changes[modName]?.new_version ?? null let previousVer = e.mod_changes[modName]?.old_version ?? null return { From 82ad2d27639114a1e5fd6e457e4205620966d9b1 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 26 Jun 2022 14:57:43 +0200 Subject: [PATCH 415/629] remove more unused Kafka Connect stuff --- .../src/docker-compose.yml | 14 -------------- .../infra-kafka-cluster/src/kafka.Dockerfile | 19 ------------------- 2 files changed, 33 deletions(-) diff --git a/modules/infra-kafka-cluster/src/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml index 6757307..8840793 100644 --- a/modules/infra-kafka-cluster/src/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -46,20 +46,6 @@ services: KAFKA_CLUSTERS_0_KAFKACONNECT_0_ADDRESS: "http://connect:8083" # - KAFKA_CLUSTERS_0_ZOOKEEPER=kafka:9093 -# kafka-connect: -# image: dev-adamko/kafka-connect -# container_name: "kafka-connect" -# build: -# dockerfile: "kafka.Dockerfile" -# target: "kafka-connect" -# args: -# KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/3.0.0/kafka_2.13-3.0.0.tgz" -# depends_on: -# - kafka-kraft -# ports: -# - "8083:8083" -# - # grafana: # image: "grafana/grafana:${GRAFANA_VERSION}" # container_name: "grafana" diff --git a/modules/infra-kafka-cluster/src/kafka.Dockerfile b/modules/infra-kafka-cluster/src/kafka.Dockerfile index 9d09f05..7670ec8 100644 --- a/modules/infra-kafka-cluster/src/kafka.Dockerfile +++ b/modules/infra-kafka-cluster/src/kafka.Dockerfile @@ -40,22 +40,3 @@ COPY --chmod=755 ./entrypoint.sh ./entrypoint.sh # launch the broker in KRaft mode, which means that it runs without ZooKeeper ENTRYPOINT ["/kafka/entrypoint.sh"] - - -### Kafka Connect ## -#FROM openjdk:11 as kafka-connect -## https://github.com/confluentinc/cp-docker-images/blob/5.3.3-post/debian/kafka-connect-base/Dockerfile -# -#ENV COMPONENT=kafka-connect -# -#WORKDIR /kafka-connect -# -#COPY --from=Kafka-Download /kafka . -# -## Default kafka-connect rest.port -#EXPOSE 8083 -# -#VOLUME ["/etc/${COMPONENT}/jars", "/etc/${COMPONENT}/secrets"] -# -## launch the broker in KRaft mode, which means that it runs without ZooKeeper -#ENTRYPOINT ["./bin/connect-standalone.sh", "./config/connect-standalone.properties"] From 4d0ec1a1a71612248fa8eb87420cd945b8f690b9 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 26 Jun 2022 14:58:19 +0200 Subject: [PATCH 416/629] version bump 0.6.1 --- build.gradle.kts | 4 ++-- modules/events-mod/package-lock.json | 2 +- modules/events-mod/package.json | 2 +- modules/infra-factorio-server/src/.env | 2 +- modules/infra-kafka-cluster/src/.env | 2 +- modules/infra-kafka-pipe/src/.env | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 80d7379..fd9e82d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,11 +8,11 @@ plugins { `build-dashboard` // kotlin("multiplatform") apply false // try to stop error 'Projects must be configuring' -// kotlin("js") apply false // try to stop error 'Projects must be configuring' + kotlin("js") apply false // try to stop error 'Projects must be configuring' } group = "dev.adamko.kafkatorio" -version = "0.6.0" +version = "0.6.1" val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 7e847ad..785e0ba 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.6.0", + "version": "0.6.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index be60289..4b3a926 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -1,6 +1,6 @@ { "name": "kafkatorio-events-mod", - "version": "0.6.0", + "version": "0.6.1", "private": true, "scripts": { "build": "tstl", diff --git a/modules/infra-factorio-server/src/.env b/modules/infra-factorio-server/src/.env index c532798..da16a1f 100644 --- a/modules/infra-factorio-server/src/.env +++ b/modules/infra-factorio-server/src/.env @@ -1,4 +1,4 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio FACTORIO_VERSION=1.1.59 -KAFKATORIO_VERSION=0.6.0 +KAFKATORIO_VERSION=0.6.1 diff --git a/modules/infra-kafka-cluster/src/.env b/modules/infra-kafka-cluster/src/.env index 04f99aa..d33aea8 100644 --- a/modules/infra-kafka-cluster/src/.env +++ b/modules/infra-kafka-cluster/src/.env @@ -1,7 +1,7 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio GRAFANA_VERSION=8.5.0 -KAFKATORIO_VERSION=0.6.0 +KAFKATORIO_VERSION=0.6.1 KAFKA_DL_URL=https\://dlcdn.apache.org/kafka/3.2.0/kafka_2.13-3.2.0.tgz KAFKA_VERSION=3.2.0 PROMETHEUS_VERSION=v2.34.0 diff --git a/modules/infra-kafka-pipe/src/.env b/modules/infra-kafka-pipe/src/.env index c97ae67..4a03adb 100644 --- a/modules/infra-kafka-pipe/src/.env +++ b/modules/infra-kafka-pipe/src/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.6.0 +KAFKATORIO_VERSION=0.6.1 From f4744c728645fc0e1464ee215289c73d9cb20ca4 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 26 Jun 2022 14:58:38 +0200 Subject: [PATCH 417/629] webmap - fix max zoom --- .../web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index a124582..8c40db5 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -125,7 +125,7 @@ class FactorioMap( minZoom = -2 maxZoom = 6 - maxNativeZoom = -1 + maxNativeZoom = 0 minNativeZoom = -1 noWrap = true From 275fb27a292947ef078db5e58b30bf52188f05e2 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 26 Jun 2022 14:59:09 +0200 Subject: [PATCH 418/629] Kafka Stream instance -> stop coroutine only when NOT_RUNNING --- .../dev/adamko/kafkatorio/processor/KafkatorioTopology.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 8da6383..1aa3e53 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -105,8 +105,11 @@ internal class KafkatorioTopology( streams.setStateListener { newState: KafkaStreams.State, _ -> when (newState) { KafkaStreams.State.NOT_RUNNING, - KafkaStreams.State.ERROR -> cont.resume(newState) - else -> Unit // do nothing +// KafkaStreams.State.ERROR, + -> if (cont.isActive) { + cont.resume(newState) + } + else -> Unit // do nothing } } From b8c1c57a17a890fc0ab9e25ca81048c7f65bd61f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 26 Jun 2022 15:30:03 +0200 Subject: [PATCH 419/629] try emitting player disconnects and immediate packet updates immediately (otherwise the server doesn't see the disconnect message and the last player remains online) --- .../typescript/main/cache/EventDataCache.ts | 27 +++++++++++++- .../typescript/main/cache/cacheChecker.ts | 14 +++----- .../main/events/onPlayerEventListeners.ts | 35 ++++++++++++++----- 3 files changed, 56 insertions(+), 20 deletions(-) diff --git a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts index e80a90a..17bcabb 100644 --- a/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts +++ b/modules/events-mod/src/main/typescript/main/cache/EventDataCache.ts @@ -1,5 +1,6 @@ import KafkatorioSettings from "../settings/KafkatorioSettings"; import {KafkatorioKeyedPacketData} from "../types"; +import packetEmitter from "../PacketEmitter"; export namespace EventUpdates { @@ -71,6 +72,10 @@ export namespace EventUpdates { if (expirationDurationTicks != undefined) { entry.expirationDurationTicks = expirationDurationTicks } + + if (entry.expirationDurationTicks != undefined && entry.expirationDurationTicks <= 0) { + this.extractAndEmitExpiredPackets() + } } @@ -90,8 +95,9 @@ export namespace EventUpdates { } + /** Removes all expired entries from the cache, and return them. */ // use in/out v4.7.0 https://github.com/microsoft/TypeScript/pull/48240 - public extractExpired(): Array { + private extractExpired(): Array { let countExpired = 0 let countTotal = 0 const expiredData: Array = [] @@ -114,6 +120,25 @@ export namespace EventUpdates { } + /** + * Removes and emits all expired packets. + * + * @return the number of emitted packets + */ + public extractAndEmitExpiredPackets() { + const cachedEvents: Array = this.extractExpired() + + if (cachedEvents.length > 0) { + log(`[EventDataCache] emitting ${cachedEvents.length} events on tick ${game.tick}`) + for (const event of cachedEvents) { + packetEmitter.emitKeyedPacket(event) + } + } + + return cachedEvents.length + } + + private getCacheEntry( key: EventUpdates.PacketKey, type: EventUpdates.PacketType, diff --git a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts index febd47e..face16a 100644 --- a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts +++ b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts @@ -1,16 +1,10 @@ import EventCacheService from "./EventDataCache"; -import packetEmitter from "../PacketEmitter"; -import {KafkatorioKeyedPacketData} from "../types"; + /** Every 0.1 seconds */ script.on_nth_tick(6, (nthTick: NthTickEventData) => { - const cachedEvents: Array = EventCacheService.extractExpired() - - if (cachedEvents.length > 0) { - log(`nth tick ${nthTick.tick} has ${cachedEvents.length} events`) - - for (const event of cachedEvents) { - packetEmitter.emitKeyedPacket(event) - } + const emittedCount = EventCacheService.extractAndEmitExpiredPackets() + if (emittedCount > 0) { + log(`[on_nth_tick:${nthTick.tick}] emitted ${emittedCount} events`) } }) diff --git a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts index b6583a3..22ad180 100644 --- a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts @@ -1,7 +1,11 @@ import {Converters} from "./converters"; import EventUpdatesManager from "../cache/EventDataCache"; -import {KafkatorioPacketData} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +import { + KafkatorioPacketData, + PlayerUpdateKey +} from "../../generated/kafkatorio-schema/kafkatorio-schema"; import Type = KafkatorioPacketData.Type; +import packetEmitter from "../PacketEmitter"; type PlayerUpdater = (player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) => void @@ -44,7 +48,7 @@ function playerUpdateThrottle( data.events[eventName] ??= [] data.events[eventName].push(event.tick) }, - expirationDurationTicks + expirationDurationTicks, ) } @@ -183,13 +187,26 @@ script.on_event( defines.events.on_pre_player_left_game, (event: OnPrePlayerLeftGameEvent) => { log(`on_pre_player_left_game ${event.tick} ${event.name}`) - playerUpdateImmediate( - event, - (player, data) => { - data.disconnectReason = disconnectReasons.get(event.reason) - playerOnlineInfo(player, data) - } - ) + + const playerUpdateKey: PlayerUpdateKey = { + index: event.player_index + } + + const playerUpdate: KafkatorioPacketData.PlayerUpdate = { + type: KafkatorioPacketData.Type.PlayerUpdate, + key: playerUpdateKey, + disconnectReason: disconnectReasons.get(event.reason) + } + + packetEmitter.emitKeyedPacket(playerUpdate) + + // playerUpdateImmediate( + // event, + // (player, data) => { + // data.disconnectReason = disconnectReasons.get(event.reason) + // playerOnlineInfo(player, data) + // } + // ) } ) From f3f92afd22ee829f037ced97ca36850e1ccafeeb Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 26 Jun 2022 15:30:30 +0200 Subject: [PATCH 420/629] try fixing weird gradle getProjectTokens() null null null bug --- modules/events-mod/build.gradle.kts | 2 +- modules/events-mod/package.json | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 567fac2..c66cc78 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -139,7 +139,7 @@ distributions { from(licenseFile) from(typescriptToLua.map { it.outputDirectory }) filesNotMatching("**/*.png") { - val tokens: MutableMap = projectTokens.get() + val tokens: MutableMap = projectTokensX.get() filter("tokens" to tokens) } includeEmptyDirs = false diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 4b3a926..50840cf 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -9,7 +9,8 @@ "engines": { "node": "~14.19.1" }, - "devDependencies": {}, + "devDependencies": { + }, "dependencies": { "lua-types": "^2.11.0", "typescript-to-lua": "1.6.0", @@ -17,7 +18,10 @@ "typescript": "4.7.4" }, "license": "UNLICENSED", - "peerDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": [] + "peerDependencies": { + }, + "optionalDependencies": { + }, + "bundledDependencies": [ + ] } From acbc15b6d4f3aa7d5868e8831ab67c677fbd0ad6 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 26 Jun 2022 15:31:54 +0200 Subject: [PATCH 421/629] map chunk grouping: reduce the amount of tiles generated (thanks to pixelated css), and reduce debounce duration --- .../processor/misc/DebounceProcessor.kt | 14 +++++++-- .../processor/topology/colourMapChunks.kt | 31 +++++++++++-------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt index 2658751..9502e63 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt @@ -30,14 +30,17 @@ class DebounceProcessor( private val storeName: String, ) : Processor { + private val checkInterval: DurationJvm = checkInterval.toJavaDuration() private lateinit var state: State + override fun init(context: ProcessorContext) { state = Active(context) } + override fun process(record: Record) { (state as Active).apply { val (key, value, _) = record @@ -49,21 +52,28 @@ class DebounceProcessor( } } + override fun close() { (state as? Active)?.schedule?.cancel() state = Closed() } + private sealed interface State + private class Closed : State + private inner class Active( val context: ProcessorContext ) : State { val store: TimestampedKeyValueStore = context.getStateStore(storeName) - val schedule: Cancellable = - context.schedule(checkInterval, PunctuationType.WALL_CLOCK_TIME, ::checkRecords) + val schedule: Cancellable = context.schedule( + checkInterval, + PunctuationType.WALL_CLOCK_TIME, + ::checkRecords + ) private fun checkRecords(now: Long) { store.useAll { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt index 2a171f0..c471d18 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt @@ -17,6 +17,7 @@ import dev.adamko.kotka.extensions.groupedAs import dev.adamko.kotka.extensions.materializedAs import dev.adamko.kotka.extensions.producedAs import dev.adamko.kotka.extensions.repartitionedAs +import dev.adamko.kotka.extensions.stream import dev.adamko.kotka.extensions.streams.filter import dev.adamko.kotka.extensions.streams.map import dev.adamko.kotka.extensions.streams.mapValues @@ -55,26 +56,30 @@ fun colourMapChunks(builder: StreamsBuilder): Topology { chunkTilesColouredTable032.streamMapChunkColouredTo( ChunkSize.CHUNK_032, - TOPIC_MAP_CHUNK_COLOURED_032_STATE + TOPIC_MAP_CHUNK_COLOURED_032_STATE, ) - val chunkTilesColoured032Debounced: KStream> = + val chunkTilesColoured: KStream> = builder.stream( - TOPIC_MAP_CHUNK_COLOURED_STATE, consumedAs( - "$pid.consume.map-chunks-coloured", - kxsBinary.serde(), - kxsBinary.serde(), + "$pid.consume.map-chunks-debounced", + kxsBinary.serde(ServerMapChunkId.serializer()), + kxsBinary.serde(ServerMapChunkTiles.serializer(ColourHex.serializer())), ), + TOPIC_MAP_CHUNK_COLOURED_STATE, ) mapOf( - ChunkSize.CHUNK_032 to ChunkSize.CHUNK_064, - ChunkSize.CHUNK_064 to ChunkSize.CHUNK_128, - ChunkSize.CHUNK_128 to ChunkSize.CHUNK_256, +// ChunkSize.CHUNK_032 to ChunkSize.CHUNK_064, +// ChunkSize.CHUNK_064 to ChunkSize.CHUNK_128, +// ChunkSize.CHUNK_128 to ChunkSize.CHUNK_256, +// ChunkSize.CHUNK_256 to ChunkSize.CHUNK_512, + + ChunkSize.CHUNK_032 to ChunkSize.CHUNK_256, ChunkSize.CHUNK_256 to ChunkSize.CHUNK_512, + ).forEach { (from, to) -> - chunkTilesColoured032Debounced + chunkTilesColoured .filter("$pid.combine-chunks.filter-$from-to-$to") { key, _ -> key.chunkSize == from }.groupByChunkPosition(to) @@ -86,9 +91,9 @@ fun colourMapChunks(builder: StreamsBuilder): Topology { namePrefix = "groupTilesMapChunks", sourceTopic = TOPIC_MAP_CHUNK_COLOURED_032_STATE, sinkTopic = TOPIC_MAP_CHUNK_COLOURED_STATE, - inactivityDuration = 15.seconds, - keySerde = kxsBinary.serde(), - valueSerde = kxsBinary.serde>(), + inactivityDuration = 5.seconds, + keySerde = kxsBinary.serde(ServerMapChunkId.serializer()), + valueSerde = kxsBinary.serde(ServerMapChunkTiles.serializer(ColourHex.serializer())), ) } From 23dbbfee2799c925a8e13f7cbe2a45ebfb70e6a7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 26 Jun 2022 15:32:08 +0200 Subject: [PATCH 422/629] enable local port for Kafka UI --- modules/infra-kafka-cluster/src/docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/infra-kafka-cluster/src/docker-compose.yml b/modules/infra-kafka-cluster/src/docker-compose.yml index 8840793..d60961f 100644 --- a/modules/infra-kafka-cluster/src/docker-compose.yml +++ b/modules/infra-kafka-cluster/src/docker-compose.yml @@ -36,8 +36,8 @@ services: - "traefik-nw" labels: - "traefik.enable=true" - # ports: - # - "8080:8080" + ports: + - "18090:8080" environment: KAFKA_CLUSTERS_0_NAME: "${COMPOSE_PROJECT_NAME}" KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: "kafka:29092" From 6ac89b3db09b9119b77f6376e01af915f0960659 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 26 Jun 2022 15:33:03 +0200 Subject: [PATCH 423/629] events server: change default docker port to 8080 (maybe better Traefik config?) --- modules/events-server/docker/docker-compose.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/events-server/docker/docker-compose.yml b/modules/events-server/docker/docker-compose.yml index 02f1f6b..ee23c47 100644 --- a/modules/events-server/docker/docker-compose.yml +++ b/modules/events-server/docker/docker-compose.yml @@ -14,16 +14,16 @@ services: environment: KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" # KAFKA_STREAMS_STATE_DIR: "http://kafka:29092" - SERVER_PORT: "12081" + SERVER_PORT: "8080" ports: - - "12080:12081" # http and ws + - "12080:8080" # http and ws networks: - "kafka-nw" - "kafkatorio-nw" - "traefik-nw" labels: - "traefik.enable=true" - - "traefik.http.services.events-server-kafkatorio.loadbalancer.server.port=12081" +# - "traefik.http.services.events-server-kafkatorio.loadbalancer.server.port=12081" networks: kafka-nw: From e7abf4583a747d9233b62fcee5549818f897c8aa Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 26 Jun 2022 15:45:59 +0200 Subject: [PATCH 424/629] rename Factorio mod tasks --- modules/events-mod/build.gradle.kts | 2 +- modules/infra-factorio-client/build.gradle.kts | 8 ++++---- modules/infra-factorio-server/build.gradle.kts | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index c66cc78..7feaa3c 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -116,7 +116,7 @@ tasks.distZip { } -val publishMod by tasks.registering(FactorioModPublishTask::class) { +val publishModToPortal by tasks.registering(FactorioModPublishTask::class) { dependsOn(tasks.check) distributionZip.set(tasks.distZip.flatMap { it.archiveFile }) diff --git a/modules/infra-factorio-client/build.gradle.kts b/modules/infra-factorio-client/build.gradle.kts index 33d76a1..4c29a79 100644 --- a/modules/infra-factorio-client/build.gradle.kts +++ b/modules/infra-factorio-client/build.gradle.kts @@ -37,7 +37,7 @@ dependencies { // -val deployModToClient by tasks.registering(Copy::class) { +val deployModToLocalClient by tasks.registering(Copy::class) { description = "Copy the mod to the Factorio client" group = FactorioMod.TASK_GROUP @@ -65,7 +65,7 @@ val clientLaunch by tasks.registering(Exec::class) { onlyIf { steamExe.orNull?.asFile?.exists() == true } onlyIf { clientModsDirectory.orNull?.asFile?.exists() == true } - dependsOn(deployModToClient) + dependsOn(deployModToLocalClient) mustRunAfter(clientKill, ":modules:infra-factorio-server:processRun") commandLine = parseSpaceSeparatedArgs( @@ -90,13 +90,13 @@ val clientKill by tasks.registering(Exec::class) { tasks.register(FactorioMod.PUBLISH_MOD_LOCAL_TASK_NAME) { group = FactorioMod.TASK_GROUP - dependsOn(deployModToClient) + dependsOn(deployModToLocalClient) } tasks.processRun { dependsOn( - deployModToClient, + deployModToLocalClient, clientLaunch, ) } diff --git a/modules/infra-factorio-server/build.gradle.kts b/modules/infra-factorio-server/build.gradle.kts index 158e151..11c61b7 100644 --- a/modules/infra-factorio-server/build.gradle.kts +++ b/modules/infra-factorio-server/build.gradle.kts @@ -23,7 +23,7 @@ dependencies { } -val deployModToServer by tasks.registering(Copy::class) { +val deployModToLocalServer by tasks.registering(Copy::class) { description = "Copy the mod to the Factorio Docker server" group = FactorioMod.TASK_GROUP @@ -47,7 +47,7 @@ tasks.dockerDown { tasks.dockerUp { dependsOn( - deployModToServer, + deployModToLocalServer, ":modules:infra-kafka-cluster:processRun", ) } @@ -60,7 +60,7 @@ tasks.dockerEnv { tasks.register(FactorioMod.PUBLISH_MOD_LOCAL_TASK_NAME) { group = FactorioMod.TASK_GROUP - dependsOn(deployModToServer) + dependsOn(deployModToLocalServer) } From e078e6316dd98753d4941c4fd02cc21a828ecca3 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 26 Jun 2022 23:50:30 +0200 Subject: [PATCH 425/629] manually bump Kafkatorio versions for events-server and web-map (I still need to automate that...) --- modules/events-mod/package.json | 12 ++++-------- modules/events-server/docker/.env | 2 +- modules/web-map/docker/.env | 2 +- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 50840cf..4b3a926 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -9,8 +9,7 @@ "engines": { "node": "~14.19.1" }, - "devDependencies": { - }, + "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", "typescript-to-lua": "1.6.0", @@ -18,10 +17,7 @@ "typescript": "4.7.4" }, "license": "UNLICENSED", - "peerDependencies": { - }, - "optionalDependencies": { - }, - "bundledDependencies": [ - ] + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] } diff --git a/modules/events-server/docker/.env b/modules/events-server/docker/.env index c97ae67..4a03adb 100644 --- a/modules/events-server/docker/.env +++ b/modules/events-server/docker/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.6.0 +KAFKATORIO_VERSION=0.6.1 diff --git a/modules/web-map/docker/.env b/modules/web-map/docker/.env index c97ae67..4a03adb 100644 --- a/modules/web-map/docker/.env +++ b/modules/web-map/docker/.env @@ -1,3 +1,3 @@ # Do not edit manually. This file was created with task 'dockerEnv' COMPOSE_PROJECT_NAME=kafkatorio -KAFKATORIO_VERSION=0.6.0 +KAFKATORIO_VERSION=0.6.1 From e9a4ee4c48dfa41465262ca0eb75dbb996531307 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 27 Jun 2022 22:07:42 +0200 Subject: [PATCH 426/629] set up syslog docker parser (remove need for Kafka Pipe script) --- build.gradle.kts | 2 +- gradle/libs.versions.toml | 8 + .../schema/packets/kafkatorioPacket.kt | 11 +- modules/events-server/build.gradle.kts | 5 + .../processor/KafkatorioTopology.kt | 85 ++++++++- .../processor/admin/kafkatorioTopics.kt | 18 +- .../processor/config/ApplicationProperties.kt | 3 + .../kafkatorio/processor/eventProcessor.kt | 10 +- .../tileserver/SyslogSocketServer.kt | 168 ++++++++++++++++++ .../topology/factorioServerPackets.kt | 22 ++- .../src/main/resources/config.yml | 6 + .../src/docker-compose.yml | 13 +- .../adamko/kafkatorio/webmap/websockets.kt | 6 +- 13 files changed, 327 insertions(+), 30 deletions(-) create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/SyslogSocketServer.kt diff --git a/build.gradle.kts b/build.gradle.kts index fd9e82d..ae6a2ff 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { `build-dashboard` // kotlin("multiplatform") apply false // try to stop error 'Projects must be configuring' - kotlin("js") apply false // try to stop error 'Projects must be configuring' +// kotlin("js") apply false // try to stop error 'Projects must be configuring' } group = "dev.adamko.kafkatorio" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7cda9a6..9d174aa 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -35,6 +35,8 @@ ktor = "2.0.2" hoplite = "2.1.5" +simpleSyslogParser = "0.0.6" + kotkaStreams = "dev-SNAPSHOT" ## test ## @@ -156,10 +158,12 @@ ktor-serverCallLogging = { group = "io.ktor", name = "ktor-server-call-l ktor-serverCallId = { group = "io.ktor", name = "ktor-server-call-id" } ktor-network = { group = "io.ktor", name = "ktor-network" } +ktor-networkTls = { group = "io.ktor", name = "ktor-network-tls" } ktor-test-clientMock = { group = "io.ktor", name = "ktor-client-mock" } ktor-test-serverHost = { group = "io.ktor", name = "ktor-server-test-host" } + ### jackson ## #jackson-bom = { group = " com.fasterxml.jackson.module", name = ":jackson-module-kotlin", version = "2.13.+" } #jackson-kotlin = { group = " com.fasterxml.jackson.module", name = ":jackson-module-kotlin", version = "2.13.+" } @@ -205,6 +209,10 @@ hoplite-core = { group = "com.sksamuel.hoplite", name = "hoplite-core", hoplite-datetime = { group = "com.sksamuel.hoplite", name = "hoplite-datetime", version.ref = "hoplite" } hoplite-yaml = { group = "com.sksamuel.hoplite", name = "hoplite-yaml", version.ref = "hoplite" } + +simpleSyslogParser = { group = "com.github.palindromicity", name = "simple-syslog", version.ref = "simpleSyslogParser" } + + ############# ### test ### ############# diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt index e1d52fb..b3f2a53 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt @@ -16,4 +16,13 @@ data class KafkatorioPacket( @Serializable @SerialName("kafkatorio.packet.KafkatorioPacketData") -sealed class KafkatorioPacketData +sealed class KafkatorioPacketData { + + @Serializable + @SerialName("kafkatorio.packet.KafkatorioPacketData.Error") + data class Error( + val message: String? = null, + val rawValue: String? = null, + ) : KafkatorioPacketData() + +} diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 7978403..58084d5 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -45,6 +45,11 @@ dependencies { implementation(libs.okio.core) + implementation(libs.ktor.network) + implementation(libs.ktor.networkTls) + + implementation(libs.simpleSyslogParser) + implementation(libs.kafka.kotkaStreams) { isChanging = true } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index 1aa3e53..d86e259 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -1,6 +1,9 @@ package dev.adamko.kafkatorio.processor +import com.github.palindromicity.syslog.dsl.SyslogFieldKeys +import dev.adamko.kafkatorio.processor.admin.TOPIC_SRC_SERVER_LOG import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.processor.tileserver.SyslogSocketServer import dev.adamko.kafkatorio.processor.tileserver.WebsocketServer import dev.adamko.kafkatorio.processor.topology.broadcastToWebsocket import dev.adamko.kafkatorio.processor.topology.colourMapChunks @@ -17,10 +20,17 @@ import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.cancel import kotlinx.coroutines.currentCoroutineContext +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.job import kotlinx.coroutines.launch import kotlinx.coroutines.suspendCancellableCoroutine +import org.apache.kafka.clients.producer.KafkaProducer import org.apache.kafka.clients.producer.ProducerConfig +import org.apache.kafka.clients.producer.ProducerRecord +import org.apache.kafka.common.header.internals.RecordHeader +import org.apache.kafka.common.serialization.Serdes import org.apache.kafka.streams.KafkaStreams import org.apache.kafka.streams.StreamsBuilder import org.apache.kafka.streams.StreamsConfig @@ -29,12 +39,14 @@ import org.apache.kafka.streams.TopologyDescription internal class KafkatorioTopology( - private val websocketServer: WebsocketServer, private val appProps: ApplicationProperties, + private val websocketServer: WebsocketServer, + private val syslogServer: SyslogSocketServer, ) { private val builderScope = CoroutineScope(CoroutineName("KafkaTopology")) + suspend fun start() = builderScope.launch { splitPackets() @@ -42,8 +54,11 @@ internal class KafkatorioTopology( saveTiles() websocketBroadcaster() + + syslogProducer() } + private suspend fun splitPackets() { val builder = StreamsBuilder() val packets = factorioServerPacketStream(builder) @@ -54,18 +69,21 @@ internal class KafkatorioTopology( launchTopology("splitPackets", topology) } + private suspend fun groupTilesMapChunks() { val builder = StreamsBuilder() val topology = colourMapChunks(builder) launchTopology("groupTilesMapChunks", topology) } + private suspend fun saveTiles() { val builder = StreamsBuilder() val topology = saveMapTiles(builder, appProps.tileDir) launchTopology("saveTiles", topology) } + private suspend fun websocketBroadcaster() { val builder = StreamsBuilder() broadcastToWebsocket(websocketServer, builder) @@ -75,11 +93,65 @@ internal class KafkatorioTopology( launchTopology( "websocketBroadcaster", topology, mapOf( StreamsConfig.COMMIT_INTERVAL_MS_CONFIG to "${1.seconds.inWholeMilliseconds}", - StreamsConfig.producerPrefix(ProducerConfig.LINGER_MS_CONFIG) to "${10.milliseconds.inWholeMilliseconds}" + StreamsConfig.producerPrefix(ProducerConfig.LINGER_MS_CONFIG) to "${1.milliseconds.inWholeMilliseconds}" ) ) } + + private fun syslogProducer( + id: String = "syslog-producer" + ) { + val props: Properties = appProps.kafkaStreamsConfig.toProperties() + + val appId = props.compute(StreamsConfig.APPLICATION_ID_CONFIG) { _, v -> "$v.$id" } as String + props.setProperty(StreamsConfig.APPLICATION_ID_CONFIG, appId) + + + val producer: KafkaProducer = KafkaProducer( + props, + Serdes.String().serializer(), + Serdes.String().serializer(), + ) + + builderScope.coroutineContext.job.invokeOnCompletion { + producer.close() + } + + syslogServer.messages + .filter { it.message?.startsWith("KafkatorioPacket:") == true } + .onEach { syslogMsg -> + + val kafkatorioMessage = syslogMsg.message?.substringAfter("KafkatorioPacket:") + + val record = ProducerRecord( + TOPIC_SRC_SERVER_LOG, + "syslog-test", + kafkatorioMessage, + ) + + val headers = SyslogFieldKeys.values() + .filter { "HEADER_" in it.name } + .mapNotNull { headerKey -> + val headerValue = syslogMsg.src[headerKey.field] + when { + headerValue.isNullOrBlank() -> null + else -> RecordHeader( + headerKey.field, + headerValue.toByteArray() + ) + } + } + + headers.forEach { header -> + record.headers().add(header) + } + + producer.send(record) + }.launchIn(builderScope) + } + + private suspend fun launchTopology( id: String, topology: Topology, @@ -105,11 +177,8 @@ internal class KafkatorioTopology( streams.setStateListener { newState: KafkaStreams.State, _ -> when (newState) { KafkaStreams.State.NOT_RUNNING, -// KafkaStreams.State.ERROR, - -> if (cont.isActive) { - cont.resume(newState) - } - else -> Unit // do nothing + KafkaStreams.State.ERROR -> if (cont.isActive) cont.resume(newState) + else -> Unit // do nothing } } @@ -127,6 +196,7 @@ internal class KafkatorioTopology( } } + private fun printTopologyDescription(appId: String, topology: Topology) { val description: TopologyDescription = topology.describe() @@ -146,6 +216,7 @@ internal class KafkatorioTopology( ) } + companion object { private fun Map.toProperties(): Properties = entries.fold(Properties()) { props, (k, v) -> diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt index 1bbfe9e..41c0206 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt @@ -48,14 +48,15 @@ fun allTopics(): Set = buildSet { val KafkatorioPacketData.topicName: String get() = when (this) { - is ConfigurationUpdate -> packetTopicNames.getValue(ConfigurationUpdate::class) - is ConsoleChatUpdate -> packetTopicNames.getValue(ConsoleChatUpdate::class) - is ConsoleCommandUpdate -> packetTopicNames.getValue(ConsoleCommandUpdate::class) - is PrototypesUpdate -> packetTopicNames.getValue(PrototypesUpdate::class) - is SurfaceUpdate -> packetTopicNames.getValue(SurfaceUpdate::class) - is EntityUpdate -> packetTopicNames.getValue(EntityUpdate::class) - is MapChunkUpdate -> packetTopicNames.getValue(MapChunkUpdate::class) - is PlayerUpdate -> packetTopicNames.getValue(PlayerUpdate::class) + is ConfigurationUpdate -> packetTopicNames.getValue(ConfigurationUpdate::class) + is ConsoleChatUpdate -> packetTopicNames.getValue(ConsoleChatUpdate::class) + is ConsoleCommandUpdate -> packetTopicNames.getValue(ConsoleCommandUpdate::class) + is PrototypesUpdate -> packetTopicNames.getValue(PrototypesUpdate::class) + is SurfaceUpdate -> packetTopicNames.getValue(SurfaceUpdate::class) + is EntityUpdate -> packetTopicNames.getValue(EntityUpdate::class) + is MapChunkUpdate -> packetTopicNames.getValue(MapChunkUpdate::class) + is PlayerUpdate -> packetTopicNames.getValue(PlayerUpdate::class) + is KafkatorioPacketData.Error -> packetTopicNames.getValue(KafkatorioPacketData.Error::class) } @@ -68,6 +69,7 @@ private val packetTopicNames: Map, String> = ma EntityUpdate::class to "entity", MapChunkUpdate::class to "map-chunk", PlayerUpdate::class to "player", + KafkatorioPacketData.Error::class to "error", ).mapValues { (_, v) -> "$DOMAIN.packet.$v" } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt index 6881ecb..85ac987 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt @@ -12,6 +12,9 @@ data class ApplicationProperties( val tileDir: Path, val kafkaAdminConfig: Map, val kafkaStreamsConfig: Map, + + val socketServerHost: String, + val socketServerPort: Int, ) { companion object { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt index 2515009..ae1e860 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt @@ -3,6 +3,7 @@ package dev.adamko.kafkatorio.processor import dev.adamko.kafkatorio.processor.admin.KafkatorioKafkaAdmin import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.processor.tileserver.SyslogSocketServer import dev.adamko.kafkatorio.processor.tileserver.WebMapTileServer import dev.adamko.kafkatorio.processor.tileserver.WebsocketServer import dev.adamko.kafkatorio.processor.tileserver.webServer @@ -11,7 +12,6 @@ import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.currentCoroutineContext import kotlinx.coroutines.job import kotlinx.coroutines.launch -import kotlinx.serialization.Serializable import org.http4k.server.Http4kServer @@ -22,12 +22,18 @@ suspend fun main() { val admin = KafkatorioKafkaAdmin(appProps) admin.createKafkatorioTopics() + + val syslogServer = SyslogSocketServer(appProps) val wsServer = WebsocketServer() val tileServer = WebMapTileServer(appProps) + val topology = KafkatorioTopology(appProps, wsServer, syslogServer) coroutineScope { launch { - val topology = KafkatorioTopology(wsServer, appProps) + syslogServer.start() + } + + launch { topology.start() println("launched KafkatorioTopology") diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/SyslogSocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/SyslogSocketServer.kt new file mode 100644 index 0000000..3bf3731 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/SyslogSocketServer.kt @@ -0,0 +1,168 @@ +package dev.adamko.kafkatorio.processor.tileserver + +import com.github.palindromicity.syslog.AllowableDeviations +import com.github.palindromicity.syslog.SyslogParser +import com.github.palindromicity.syslog.SyslogParserBuilder +import com.github.palindromicity.syslog.SyslogSpecification +import com.github.palindromicity.syslog.dsl.SyslogFieldKeys +import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.processor.tileserver.SyslogMsg.Companion.toSyslogMsg +import io.ktor.network.selector.SelectorManager +import io.ktor.network.sockets.aSocket +import io.ktor.network.sockets.awaitClosed +import io.ktor.network.sockets.openReadChannel +import io.ktor.utils.io.readUTF8Line +import java.util.EnumSet +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import kotlinx.coroutines.yield + + +class SyslogSocketServer( + appProps: ApplicationProperties, + dispatcher: CoroutineDispatcher = Dispatchers.IO, +) { + + private val selectorManager: SelectorManager = SelectorManager(dispatcher) + + + private val serverSocketTcp = aSocket(selectorManager) + .tcp() + .bind( + appProps.socketServerHost, + appProps.socketServerPortTcp, + ) + + +// private val serverSocketUdp: BoundDatagramSocket = aSocket(selectorManager) +// .udp() +// .bind( +// localAddress = InetSocketAddress( +// appProps.socketServerHost, +// appProps.socketServerPortUdp, +// ), +// ) + + + private val syslogParser: SyslogParser = SyslogParserBuilder() + .withDeviations(EnumSet.of(AllowableDeviations.PRIORITY, AllowableDeviations.VERSION)) + .forSpecification(SyslogSpecification.RFC_5424) + .build() + + + private val _messages: MutableSharedFlow = MutableSharedFlow() + val messages: SharedFlow + get() = _messages.asSharedFlow() + + + suspend fun start() { +// udp() + tcp() + } + +// private suspend fun udp() { +// println("[SyslogSocketServer] started listening: ${serverSocketUdp.localAddress}") +// +// serverSocketUdp.incoming +// .receiveAsFlow() +// .map {udpPacket: Datagram -> +// val msg = udpPacket.packet.readText() +// println("[SyslogSocketServer] received msg: $msg") +// syslogParser.parseLine(msg).toSyslogMsg() +// }.collect(_messages) +// } + + private suspend fun tcp() = coroutineScope { + println("[SyslogSocketServer] started listening: ${serverSocketTcp.localAddress}") + + while (isActive) { + val socket = serverSocketTcp.accept() + + launch { + val channel = socket.openReadChannel() + try { + while (socket.socketContext.isActive) { + val line = channel.readUTF8Line() + println("[SyslogSocketServer] received: $line") + + val syslog = syslogParser.parseLine(line).toSyslogMsg() + + _messages.emit(syslog) + + yield() + } + } catch (e: Exception) { + socket.awaitClosed() + } + } + } + + yield() + } +} + + +data class SyslogMsg( + val src: Map +) { + + val message: String? + get() = src[SyslogFieldKeys.MESSAGE.field] + + val headerAppName: String? + get() = src[SyslogFieldKeys.HEADER_APPNAME.field] + + val headerHostName: String? + get() = src[SyslogFieldKeys.HEADER_HOSTNAME.field] + + val headerPri: String? + get() = src[SyslogFieldKeys.HEADER_PRI.field] + + val headerPriSeverity: String? + get() = src[SyslogFieldKeys.HEADER_PRI_SEVERITY.field] + + val headerPriFacility: String? + get() = src[SyslogFieldKeys.HEADER_PRI_FACILITY.field] + + val headerProcId: String? + get() = src[SyslogFieldKeys.HEADER_PROCID.field] + + val headerTimestamp: String? + get() = src[SyslogFieldKeys.HEADER_TIMESTAMP.field] + + val headerMsgId: String? + get() = src[SyslogFieldKeys.HEADER_MSGID.field] + + val headerVersion: String? + get() = src[SyslogFieldKeys.HEADER_VERSION.field] + + val structuredBase: String? + get() = src[SyslogFieldKeys.STRUCTURED_BASE.field] + + val structuredElementIdFmt: String? + get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_FMT.field] + + val structuredElementIdPnameFmt: String? + get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_PNAME_FMT.field] + + val structuredElementIdPnamePattern: String? + get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_PNAME_PATTERN.field] + + companion object { + fun Map.toSyslogMsg(): SyslogMsg { + val map = entries.mapNotNull { (k, v) -> + when (v) { + is String -> k to v + else -> null + } + }.toMap() + return SyslogMsg(map) + } + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt index f19cfc5..283f062 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt @@ -5,7 +5,9 @@ import dev.adamko.kafkatorio.processor.admin.TOPIC_SRC_SERVER_LOG import dev.adamko.kafkatorio.processor.admin.topicName import dev.adamko.kafkatorio.processor.serdes.jsonMapper import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket +import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData import dev.adamko.kotka.extensions.component1 import dev.adamko.kotka.extensions.component2 import dev.adamko.kotka.extensions.consumedAs @@ -31,8 +33,26 @@ fun factorioServerPacketStream( Serdes.String(), ) ).map("decode-packets") { serverId: String, value: String -> - val packet = jsonMapper.decodeFromString(value) + val packet = runCatching { + jsonMapper.decodeFromString(value) + }.getOrElse { e -> + KafkatorioPacket( + modVersion = "unknown", + tick = Tick(0u), + data = KafkatorioPacketData.Error( + message = e.message, + rawValue = value, + ) + ) + } + + if (packet.data is KafkatorioPacketData.Error) { + println("error parsing $TOPIC_SRC_SERVER_LOG message: ${packet.data}") + } + FactorioServerId(serverId) to packet + }.filter { _, value -> + value.data !is KafkatorioPacketData.Error } } diff --git a/modules/events-server/src/main/resources/config.yml b/modules/events-server/src/main/resources/config.yml index fa31386..9b8eb5c 100644 --- a/modules/events-server/src/main/resources/config.yml +++ b/modules/events-server/src/main/resources/config.yml @@ -3,10 +3,16 @@ web-port: ${SERVER_PORT:-12080} tile-dir: ${TILE_DIR:-./tile-dir} + +socket-server-host: ${SOCKET_SERVER_HOST:-127.0.0.1} +socket-server-port: ${SOCKET_SERVER_PORT:-9002} + + kafka-admin-config: client.id: kafkatorio.events-server-admin bootstrap.servers: ${KAFKA_BOOTSTRAP_SERVERS:-http://localhost:9092} + kafka-streams-config: application.id: kafkatorio-events-processor bootstrap.servers: ${KAFKA_BOOTSTRAP_SERVERS:-http://localhost:9092} diff --git a/modules/infra-factorio-server/src/docker-compose.yml b/modules/infra-factorio-server/src/docker-compose.yml index 262ca06..3b12252 100644 --- a/modules/infra-factorio-server/src/docker-compose.yml +++ b/modules/infra-factorio-server/src/docker-compose.yml @@ -4,8 +4,6 @@ services: factorio-server: image: factoriotools/factorio:${FACTORIO_VERSION} - # logging: - # driver: "json-file" container_name: "factorio-server" restart: "no" networks: @@ -18,12 +16,11 @@ services: - "27015:27015/tcp" # rcon volumes: - "./factorio-server:/factorio" - # logging: - # driver: "mickyg/kafka-logdriver:latest" - # options: - # KAFKA_BROKER_ADDR: "kafka-kraft" - # LOG_TOPIC: "dockerlogs-factorio-server" - # LOG_TAG: "factorio-server" + logging: + driver: syslog + options: + syslog-address: "tcp://host.docker.internal:9002" + syslog-format: "rfc5424" # environment: # RCON_PORT: 27715 diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt index 7c0ca27..077472f 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/websockets.kt @@ -5,6 +5,7 @@ import dev.adamko.kafkatorio.schema.packets.ConsoleChatUpdate import dev.adamko.kafkatorio.schema.packets.ConsoleCommandUpdate import dev.adamko.kafkatorio.schema.packets.EntityUpdate import dev.adamko.kafkatorio.schema.packets.EventServerPacket +import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate @@ -74,7 +75,7 @@ class WebsocketService( is EventServerPacket.Kafkatorio -> when (val packetData = packet.packet.data) { - is PlayerUpdate -> reduxStore.dispatch( + is PlayerUpdate -> reduxStore.dispatch( FactorioUpdate.Player(packet.packet.tick, packetData) ) is ConfigurationUpdate, @@ -83,7 +84,8 @@ class WebsocketService( is PrototypesUpdate, is SurfaceUpdate, is EntityUpdate, - is MapChunkUpdate -> { + is MapChunkUpdate, + is KafkatorioPacketData.Error -> { // to be continued... } } From fc758030fd7c26e6f2f31380a17a159c21afd412 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 27 Jun 2022 22:08:39 +0200 Subject: [PATCH 427/629] event-server tidy up (improve value class, rm unused class, rename websocket broadcaster) --- .../kafkatorio/processor/topology/colourMapChunks.kt | 2 +- .../kafkatorio/processor/topology/groupMapChunks.kt | 1 - .../adamko/kafkatorio/processor/topology/prototypes.kt | 8 +++++--- .../topology/{playerUpdates.kt => websocketBroadcast.kt} | 0 4 files changed, 6 insertions(+), 5 deletions(-) delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/{playerUpdates.kt => websocketBroadcast.kt} (100%) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt index c471d18..b790ffc 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt @@ -187,7 +187,7 @@ private fun KTable>.enr val missingProtos = mutableSetOf() val tileColours = tiles.map.mapValues { (_, code) -> - colourDict.map.getOrElse(code) { + colourDict.getOrElse(code) { missingProtos.add(code) ColourHex.TRANSPARENT } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt deleted file mode 100644 index 272d386..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/groupMapChunks.kt +++ /dev/null @@ -1 +0,0 @@ -package dev.adamko.kafkatorio.processor.topology diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt index 56b9e7b..85401e5 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt @@ -29,7 +29,9 @@ value class TileProtoHashCode private constructor(val code: Int) { @JvmInline @Serializable -value class TileColourDict(val map: Map) +value class TileColourDict( + private val map: Map +) : Map by map /** Get the latest map-tile colours per server. */ @@ -48,9 +50,9 @@ fun KStream.createTilePrototypeTable() TileColourDict(map) }.filter("$pid.filterMapTileProtos") { _, dict: TileColourDict -> - dict.map.isNotEmpty() + dict.isNotEmpty() }.peek { serverId, dict: TileColourDict -> - println("$pid: server $serverId has TileColourDict[${dict.map.size}]: ${dict.map.entries.joinToString()}") + println("$pid: server $serverId has TileColourDict[${dict.size}]: ${dict.entries.joinToString()}") }.repartition( repartitionedAs( "$pid.pre-table-repartition", diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/websocketBroadcast.kt similarity index 100% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/playerUpdates.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/websocketBroadcast.kt From a2e8ab61d7ca732224bdaebd74b32b6fc0aefd70 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 27 Jun 2022 22:08:58 +0200 Subject: [PATCH 428/629] change default port to 8080 (works better with Traefik defaults) --- modules/events-server/src/main/resources/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/events-server/src/main/resources/config.yml b/modules/events-server/src/main/resources/config.yml index 9b8eb5c..0e12ff8 100644 --- a/modules/events-server/src/main/resources/config.yml +++ b/modules/events-server/src/main/resources/config.yml @@ -1,6 +1,6 @@ # Factorio Events Processor config -web-port: ${SERVER_PORT:-12080} +web-port: ${SERVER_PORT:-8080} tile-dir: ${TILE_DIR:-./tile-dir} From 5f1187f9a8ec59c8817264e0ca3781a8b50cbb4f Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 27 Jun 2022 22:09:48 +0200 Subject: [PATCH 429/629] rename: socketServerPortTcp -> socketServerPort --- .../kafkatorio/processor/tileserver/SyslogSocketServer.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/SyslogSocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/SyslogSocketServer.kt index 3bf3731..4a1da1c 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/SyslogSocketServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/SyslogSocketServer.kt @@ -36,7 +36,7 @@ class SyslogSocketServer( .tcp() .bind( appProps.socketServerHost, - appProps.socketServerPortTcp, + appProps.socketServerPort, ) From 1d0b2b8eaa5b273478db504794b6b89c79b55db9 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 27 Jun 2022 22:57:57 +0200 Subject: [PATCH 430/629] refactor typescript files (mostly moving&renaming for consistency) --- modules/events-mod/package.json | 12 +++-- .../events-mod/src/main/typescript/control.ts | 20 ++------ .../kafkatorio-schema.ts | 8 +++ .../src/main/typescript/main/PacketEmitter.ts | 3 +- .../typescript/main/cache/cacheChecker.ts | 10 ---- .../main/commands/kafkatorioCommands.ts | 9 ++-- .../configurationUpdate.ts} | 18 ++++++- ...soleEventHandlers.ts => consoleUpdates.ts} | 4 +- .../main/typescript/main/events/converters.ts | 11 +++- .../{EntityEvents.ts => entityUpdates.ts} | 2 +- ...nkEventListeners.ts => mapChunkUpdates.ts} | 2 +- ...ayerEventListeners.ts => playerUpdates.ts} | 2 +- .../prototypeUpdates.ts} | 26 +++------- .../main/events/registerHandlers.ts | 50 +++++-------------- .../typescript/main/events/settingsUpdate.ts | 7 +++ .../events/{handlers.ts => surfaceUpdates.ts} | 2 +- .../main/settings/KafkatorioSettings.ts | 23 --------- .../src/main/typescript/main/types.d.ts | 2 +- .../infra-kafka-pipe/src/docker-compose.yml | 6 +-- 19 files changed, 91 insertions(+), 126 deletions(-) rename modules/events-mod/src/main/typescript/generated/{kafkatorio-schema => }/kafkatorio-schema.ts (96%) delete mode 100644 modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts rename modules/events-mod/src/main/typescript/main/{config-update/handleConfigurationUpdate.ts => events/configurationUpdate.ts} (75%) rename modules/events-mod/src/main/typescript/main/events/{onConsoleEventHandlers.ts => consoleUpdates.ts} (97%) rename modules/events-mod/src/main/typescript/main/events/{EntityEvents.ts => entityUpdates.ts} (97%) rename modules/events-mod/src/main/typescript/main/events/{onMapChunkEventListeners.ts => mapChunkUpdates.ts} (99%) rename modules/events-mod/src/main/typescript/main/events/{onPlayerEventListeners.ts => playerUpdates.ts} (98%) rename modules/events-mod/src/main/typescript/main/{config-update/prototypes.ts => events/prototypeUpdates.ts} (70%) create mode 100644 modules/events-mod/src/main/typescript/main/events/settingsUpdate.ts rename modules/events-mod/src/main/typescript/main/events/{handlers.ts => surfaceUpdates.ts} (94%) diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 4b3a926..50840cf 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -9,7 +9,8 @@ "engines": { "node": "~14.19.1" }, - "devDependencies": {}, + "devDependencies": { + }, "dependencies": { "lua-types": "^2.11.0", "typescript-to-lua": "1.6.0", @@ -17,7 +18,10 @@ "typescript": "4.7.4" }, "license": "UNLICENSED", - "peerDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": [] + "peerDependencies": { + }, + "optionalDependencies": { + }, + "bundledDependencies": [ + ] } diff --git a/modules/events-mod/src/main/typescript/control.ts b/modules/events-mod/src/main/typescript/control.ts index abf359c..3800be5 100644 --- a/modules/events-mod/src/main/typescript/control.ts +++ b/modules/events-mod/src/main/typescript/control.ts @@ -1,23 +1,11 @@ -import {emitConfigurationUpdate} from "./main/config-update/handleConfigurationUpdate"; -import {emitPrototypes} from "./main/config-update/prototypes"; import {initGlobal} from "./main/global-init"; -import KafkatorioSettings from "./main/settings/KafkatorioSettings"; +import {emitPrototypes} from "./main/events/prototypeUpdates"; require("./main/events/registerHandlers") -require("./main/events/onMapChunkEventListeners") -require("./main/events/onPlayerEventListeners") -require("./main/events/EntityEvents") +require("./main/events/mapChunkUpdates") +require("./main/events/playerUpdates") +require("./main/events/entityUpdates") require("./main/commands/kafkatorioCommands") -require("./main/cache/cacheChecker") - - -script.on_configuration_changed((data: ConfigurationChangedData) => { - // runs whenever the version of the base game, or a mod, changes - initGlobal(true) - // KafkatorioSettings.loadSettings() - emitConfigurationUpdate(data) - emitPrototypes() -}) script.on_init(() => { diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts similarity index 96% rename from modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts rename to modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts index ae19634..f0559a9 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema/kafkatorio-schema.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts @@ -13,6 +13,7 @@ export type KafkatorioPacketData = | KafkatorioPacketData.ConsoleChatUpdate | KafkatorioPacketData.ConsoleCommandUpdate | KafkatorioPacketData.EntityUpdate + | KafkatorioPacketData.Error | KafkatorioPacketData.MapChunkUpdate | KafkatorioPacketData.PlayerUpdate | KafkatorioPacketData.PrototypesUpdate @@ -28,6 +29,7 @@ export namespace KafkatorioPacketData { EntityUpdate = "kafkatorio.packet.keyed.EntityUpdate", MapChunkUpdate = "kafkatorio.packet.keyed.MapChunkUpdate", PlayerUpdate = "kafkatorio.packet.keyed.PlayerUpdate", + Error = "kafkatorio.packet.KafkatorioPacketData.Error", } export interface ConfigurationUpdate { @@ -115,6 +117,12 @@ export namespace KafkatorioPacketData { disconnectReason?: string | null; isRemoved?: boolean | null; } + + export interface Error { + type: KafkatorioPacketData.Type.Error; + message?: string | null; + rawValue?: string | null; + } } export type UInt = uint; diff --git a/modules/events-mod/src/main/typescript/main/PacketEmitter.ts b/modules/events-mod/src/main/typescript/main/PacketEmitter.ts index 55a1ba7..a566499 100644 --- a/modules/events-mod/src/main/typescript/main/PacketEmitter.ts +++ b/modules/events-mod/src/main/typescript/main/PacketEmitter.ts @@ -1,9 +1,10 @@ import { KafkatorioPacket, KafkatorioPacketData -} from "../generated/kafkatorio-schema/kafkatorio-schema"; +} from "../generated/kafkatorio-schema"; import {KafkatorioKeyedPacketData} from "./types"; + export class KafkatorioPacketEmitter { emitInstantPacket( diff --git a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts b/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts deleted file mode 100644 index face16a..0000000 --- a/modules/events-mod/src/main/typescript/main/cache/cacheChecker.ts +++ /dev/null @@ -1,10 +0,0 @@ -import EventCacheService from "./EventDataCache"; - - -/** Every 0.1 seconds */ -script.on_nth_tick(6, (nthTick: NthTickEventData) => { - const emittedCount = EventCacheService.extractAndEmitExpiredPackets() - if (emittedCount > 0) { - log(`[on_nth_tick:${nthTick.tick}] emitted ${emittedCount} events`) - } -}) diff --git a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts index 19a34c5..c9bdcc0 100644 --- a/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts +++ b/modules/events-mod/src/main/typescript/main/commands/kafkatorioCommands.ts @@ -1,7 +1,6 @@ -import {emitPrototypes} from "../config-update/prototypes"; import {initGlobal} from "../global-init"; -import floor = math.floor; import {Queue} from "../queue/queue"; +import {emitPrototypes} from "../events/prototypeUpdates"; commands.add_command( @@ -32,8 +31,8 @@ commands.add_command( let player = game.players[e.player_index] const chunkPosition: ChunkPosition = { - x: floor(player.position.x / 32), - y: floor(player.position.y / 32), + x: math.floor(player.position.x / 32), + y: math.floor(player.position.y / 32), } const chunkXMin = chunkPosition.x - radius @@ -56,7 +55,7 @@ commands.add_command( position: {x: chunk.x, y: chunk.y}, area: chunk.area, surface: surface, - tick: e.tick + tick: e.tick, } Queue.enqueue( diff --git a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts b/modules/events-mod/src/main/typescript/main/events/configurationUpdate.ts similarity index 75% rename from modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts rename to modules/events-mod/src/main/typescript/main/events/configurationUpdate.ts index 4808d6c..b11863f 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/handleConfigurationUpdate.ts +++ b/modules/events-mod/src/main/typescript/main/events/configurationUpdate.ts @@ -3,11 +3,23 @@ import { ConfigurationUpdateGameData, ConfigurationUpdateModData, KafkatorioPacketData -} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +} from "../../generated/kafkatorio-schema"; +import {initGlobal} from "../global-init"; +import {emitPrototypes} from "./prototypeUpdates"; import Type = KafkatorioPacketData.Type; import ConfigurationUpdate = KafkatorioPacketData.ConfigurationUpdate; -export function emitConfigurationUpdate(changeData: ConfigurationChangedData) { + +script.on_configuration_changed((data: ConfigurationChangedData) => { + // runs whenever the version of the base game, or a mod, changes + initGlobal(true) + // KafkatorioSettings.loadSettings() + emitConfigurationUpdate(data) + emitPrototypes() +}) + + +function emitConfigurationUpdate(changeData: ConfigurationChangedData) { const configUpdateData: ConfigurationUpdate = { type: Type.ConfigurationUpdate, @@ -20,6 +32,7 @@ export function emitConfigurationUpdate(changeData: ConfigurationChangedData) { PacketEmitter.emitInstantPacket(configUpdateData) } + function factorioData(changeData: ConfigurationChangedData): ConfigurationUpdateGameData { return { oldVersion: changeData.old_version ?? null, @@ -27,6 +40,7 @@ function factorioData(changeData: ConfigurationChangedData): ConfigurationUpdate } } + function allMods(e: ConfigurationChangedData): ConfigurationUpdateModData[] { let namesOfChangedMods: string[] = Object.keys(e.mod_changes) diff --git a/modules/events-mod/src/main/typescript/main/events/onConsoleEventHandlers.ts b/modules/events-mod/src/main/typescript/main/events/consoleUpdates.ts similarity index 97% rename from modules/events-mod/src/main/typescript/main/events/onConsoleEventHandlers.ts rename to modules/events-mod/src/main/typescript/main/events/consoleUpdates.ts index c76b673..08b2c48 100644 --- a/modules/events-mod/src/main/typescript/main/events/onConsoleEventHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/consoleUpdates.ts @@ -1,7 +1,8 @@ import PacketEmitter from "../PacketEmitter"; -import {KafkatorioPacketData} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +import {KafkatorioPacketData} from "../../generated/kafkatorio-schema"; import Type = KafkatorioPacketData.Type; + script.on_event( defines.events.on_console_chat, (event: OnConsoleChatEvent) => { @@ -15,6 +16,7 @@ script.on_event( } ) + script.on_event( defines.events.on_console_command, (event: OnConsoleCommandEvent) => { diff --git a/modules/events-mod/src/main/typescript/main/events/converters.ts b/modules/events-mod/src/main/typescript/main/events/converters.ts index 81da5f1..db6fe3e 100644 --- a/modules/events-mod/src/main/typescript/main/events/converters.ts +++ b/modules/events-mod/src/main/typescript/main/events/converters.ts @@ -1,5 +1,5 @@ import {EventName} from "../types"; -import {Colour, MapChunkPosition} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +import {Colour, MapChunkPosition} from "../../generated/kafkatorio-schema"; export namespace Converters { @@ -57,4 +57,13 @@ export namespace Converters { return [position.x, position.y] } + + export function convertCollisionMaskToNames(cm: CollisionMask): string[] { + let masks: string[] = [] + for (let [name] of pairs(cm)) { + masks.push(name) + } + return masks + } + } diff --git a/modules/events-mod/src/main/typescript/main/events/EntityEvents.ts b/modules/events-mod/src/main/typescript/main/events/entityUpdates.ts similarity index 97% rename from modules/events-mod/src/main/typescript/main/events/EntityEvents.ts rename to modules/events-mod/src/main/typescript/main/events/entityUpdates.ts index 34c2ff3..791f3e6 100644 --- a/modules/events-mod/src/main/typescript/main/events/EntityEvents.ts +++ b/modules/events-mod/src/main/typescript/main/events/entityUpdates.ts @@ -3,7 +3,7 @@ import EventDataCache from "../cache/EventDataCache"; import { EntityUpdateKey, KafkatorioPacketData -} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +} from "../../generated/kafkatorio-schema"; script.on_event(defines.events.on_built_entity, (e: OnBuiltEntityEvent) => { diff --git a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/mapChunkUpdates.ts similarity index 99% rename from modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts rename to modules/events-mod/src/main/typescript/main/events/mapChunkUpdates.ts index 858772a..509afc5 100644 --- a/modules/events-mod/src/main/typescript/main/events/onMapChunkEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/mapChunkUpdates.ts @@ -4,7 +4,7 @@ import EventUpdatesManager, {EventUpdates} from "../cache/EventDataCache"; import { KafkatorioPacketData, MapChunkPosition -} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +} from "../../generated/kafkatorio-schema"; import CacheKey = EventUpdates.PacketKey; import Type = KafkatorioPacketData.Type; diff --git a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts b/modules/events-mod/src/main/typescript/main/events/playerUpdates.ts similarity index 98% rename from modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts rename to modules/events-mod/src/main/typescript/main/events/playerUpdates.ts index 22ad180..da55741 100644 --- a/modules/events-mod/src/main/typescript/main/events/onPlayerEventListeners.ts +++ b/modules/events-mod/src/main/typescript/main/events/playerUpdates.ts @@ -3,7 +3,7 @@ import EventUpdatesManager from "../cache/EventDataCache"; import { KafkatorioPacketData, PlayerUpdateKey -} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +} from "../../generated/kafkatorio-schema"; import Type = KafkatorioPacketData.Type; import packetEmitter from "../PacketEmitter"; diff --git a/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts b/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts similarity index 70% rename from modules/events-mod/src/main/typescript/main/config-update/prototypes.ts rename to modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts index 85819cd..8c71f9b 100644 --- a/modules/events-mod/src/main/typescript/main/config-update/prototypes.ts +++ b/modules/events-mod/src/main/typescript/main/events/prototypeUpdates.ts @@ -1,24 +1,21 @@ -import {Converters} from "../events/converters"; import PacketEmitter from "../PacketEmitter"; -import { - FactorioPrototype, - KafkatorioPacketData -} from "../../generated/kafkatorio-schema/kafkatorio-schema"; -import Type = KafkatorioPacketData.Type; +import {FactorioPrototype, KafkatorioPacketData} from "../../generated/kafkatorio-schema"; +import {Converters} from "./converters"; import PrototypesUpdate = KafkatorioPacketData.PrototypesUpdate; export function emitPrototypes() { const data: PrototypesUpdate = { - prototypes: prototypes(), - type: Type.PrototypesUpdate, + prototypes: prototypeUpdates(), + type: KafkatorioPacketData.Type.PrototypesUpdate, } PacketEmitter.emitInstantPacket(data) } -function prototypes(): FactorioPrototype[] { + +function prototypeUpdates(): FactorioPrototype[] { let prototypes: FactorioPrototype[] = [] prototypes.push(...getMapTilePrototypes()) @@ -26,6 +23,7 @@ function prototypes(): FactorioPrototype[] { return prototypes } + function getMapTilePrototypes(): FactorioPrototype.MapTile[] { let tiles: FactorioPrototype.MapTile[] = [] for (let [, tile] of game.tile_prototypes) { @@ -35,7 +33,7 @@ function getMapTilePrototypes(): FactorioPrototype.MapTile[] { name: tile.name, order: tile.order, layer: tile.layer, - collisionMasks: convertCollisionMaskToNames(tile.collision_mask), + collisionMasks: Converters.convertCollisionMaskToNames(tile.collision_mask), mapColour: Converters.mapColour(tile.map_color), canBeMined: tile.mineable_properties.minable, }) @@ -60,11 +58,3 @@ function getMapTilePrototypes(): FactorioPrototype.MapTile[] { // } // return tiles // } - -function convertCollisionMaskToNames(cm: CollisionMask): string[] { - let masks: string[] = [] - for (let [name] of pairs(cm)) { - masks.push(name) - } - return masks -} diff --git a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts index f8b2aa7..d3758c7 100644 --- a/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/registerHandlers.ts @@ -1,34 +1,11 @@ import {Queue} from "../queue/queue"; import {isEventType} from "./eventTypeCheck"; import {Converters} from "./converters"; -import KafkatorioSettings from "../settings/KafkatorioSettings"; -import {handleChunkGeneratedEvent} from "./onMapChunkEventListeners"; -import {handleSurfaceUpdate} from "./handlers"; +import {handleChunkGeneratedEvent} from "./mapChunkUpdates"; +import {handleSurfaceUpdate} from "./surfaceUpdates"; +import EventCacheService from "../cache/EventDataCache"; -// script.on_event( -// defines.events.on_player_mined_entity, -// (e: OnPlayerMinedEntityEvent) => { -// let eventName = Converters.eventNameString(e.name) -// // handlePlayerUpdate(e.tick, eventName, e.player_index) -// handleEntityUpdate(e.tick, eventName, e.entity) -// } -// ) - -// script.on_event( -// defines.events.on_player_joined_game, -// (e: OnPlayerJoinedGameEvent) => { -// handlePlayerUpdate(e.tick, mapEventIdToName.get(e.name), e.player_index) -// } -// ) - -// script.on_event( -// defines.events.on_player_changed_position, -// (e: OnPlayerChangedPositionEvent) => { -// handlePlayerUpdate(e.tick, mapEventIdToName.get(e.name), e.player_index) -// } -// ) - script.on_event( defines.events.on_tick, (event: OnTickEvent) => { @@ -38,18 +15,26 @@ script.on_event( } } + if (event.tick % 6 == 0) { + // Every 0.1 seconds + const emittedCount = EventCacheService.extractAndEmitExpiredPackets() + if (emittedCount > 0) { + log(`[on_tick:${event.tick}] emitted ${emittedCount} events`) + } + } + if (event.tick % 7 == 0) { const events: EventData[] = Queue.dequeueValues(1) if (events.length > 0) { - log(`[${event.tick}] dequed ${events.length} events, current size: ${Queue.size()}`) + log(`[on_tick:${event.tick}] dequeued ${events.length} events, current size: ${Queue.size()}`) let i = 1 for (const event of events) { if (isEventType(event, defines.events.on_chunk_generated)) { let eName = Converters.eventNameString(event.name) - log(`[${event.tick}] dequed event ${eName}, delay ${i}`) + log(`[on_tick:${event.tick}] dequed event ${eName}, delay ${i}`) handleChunkGeneratedEvent(event, i) i += 1 } @@ -58,12 +43,3 @@ script.on_event( } } ) - - -script.on_event( - defines.events.on_runtime_mod_setting_changed, - (e: OnRuntimeModSettingChangedEvent) => { - print(`Settings changed ${e.setting_type}, ${e.player_index}, ${e.setting}, ${e.mod_name}`) - // KafkatorioSettings.loadSettings() - } -) diff --git a/modules/events-mod/src/main/typescript/main/events/settingsUpdate.ts b/modules/events-mod/src/main/typescript/main/events/settingsUpdate.ts new file mode 100644 index 0000000..93e3593 --- /dev/null +++ b/modules/events-mod/src/main/typescript/main/events/settingsUpdate.ts @@ -0,0 +1,7 @@ +script.on_event( + defines.events.on_runtime_mod_setting_changed, + (e: OnRuntimeModSettingChangedEvent) => { + print(`Settings changed ${e.setting_type}, ${e.player_index}, ${e.setting}, ${e.mod_name}`) + // KafkatorioSettings.loadSettings() + } +) diff --git a/modules/events-mod/src/main/typescript/main/events/handlers.ts b/modules/events-mod/src/main/typescript/main/events/surfaceUpdates.ts similarity index 94% rename from modules/events-mod/src/main/typescript/main/events/handlers.ts rename to modules/events-mod/src/main/typescript/main/events/surfaceUpdates.ts index 62989b8..9c90da5 100644 --- a/modules/events-mod/src/main/typescript/main/events/handlers.ts +++ b/modules/events-mod/src/main/typescript/main/events/surfaceUpdates.ts @@ -1,5 +1,5 @@ import PacketEmitter from "../PacketEmitter"; -import {KafkatorioPacketData} from "../../generated/kafkatorio-schema/kafkatorio-schema"; +import {KafkatorioPacketData} from "../../generated/kafkatorio-schema"; import Type = KafkatorioPacketData.Type; diff --git a/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts b/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts index bb90bfb..618554a 100644 --- a/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts +++ b/modules/events-mod/src/main/typescript/main/settings/KafkatorioSettings.ts @@ -11,35 +11,12 @@ export class KafkatorioSettingsConfig { } - // private eventCacheExpirationTicks: Record = { - // "kafkatorio.packet.keyed.PlayerUpdate": - // KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.PlayerUpdate], - // "kafkatorio.packet.keyed.MapChunkUpdate": - // KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.MapChunkUpdate], - // "kafkatorio.packet.keyed.EntityUpdate": - // KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.EntityUpdate], - // } - public getEventCacheExpirationTicks(packet: KafkatorioKeyedPacketData): uint { const settingName = KafkatorioSettingsConfig.cacheDurationSettingName(packet.type) const seconds: double = settings.global[settingName].value as double return seconds * 60 // convert ticks to seconds } - // private static types: KafkatorioKeyedPacketTypes[] = [ - // KafkatorioPacketData.Type.PlayerUpdate, - // KafkatorioPacketData.Type.MapChunkUpdate, - // KafkatorioPacketData.Type.EntityUpdate, - // ] - - // public loadSettings(): void { - // for (const type of KafkatorioSettingsConfig.types) { - // const settingName = KafkatorioSettingsConfig.cacheDurationSettingName(type) - // const seconds: double = settings.global[settingName].value as double - // this.eventCacheExpirationTicks[type] = seconds * 60 // convert ticks to seconds - // } - // } - public initialiseSettings(data: Data): void { for (const [type,] of pairs(KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds)) { diff --git a/modules/events-mod/src/main/typescript/main/types.d.ts b/modules/events-mod/src/main/typescript/main/types.d.ts index 7505b54..fcdc914 100644 --- a/modules/events-mod/src/main/typescript/main/types.d.ts +++ b/modules/events-mod/src/main/typescript/main/types.d.ts @@ -1,4 +1,4 @@ -import {KafkatorioPacketData} from "../generated/kafkatorio-schema/kafkatorio-schema"; +import {KafkatorioPacketData} from "../generated/kafkatorio-schema"; export type EventName = keyof typeof defines.events diff --git a/modules/infra-kafka-pipe/src/docker-compose.yml b/modules/infra-kafka-pipe/src/docker-compose.yml index 4536152..dd90da2 100644 --- a/modules/infra-kafka-pipe/src/docker-compose.yml +++ b/modules/infra-kafka-pipe/src/docker-compose.yml @@ -20,10 +20,10 @@ services: KAFKA_HOST: "kafka:29092" volumes: # Windows (requires privileged/root) -# - "//var/run/docker.sock:/var/run/docker.sock" - + - "//var/run/docker.sock:/var/run/docker.sock" + # Rootless: - - "/run/user/1000/docker.sock:/var/run/docker.sock" +# - "/run/user/1000/docker.sock:/var/run/docker.sock" # Unix? # - "/var/run/docker.sock:/var/run/docker.sock" From 23a2ecb0d446aa92509a8f461e86f7334ab9b758 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 27 Jun 2022 22:59:52 +0200 Subject: [PATCH 431/629] set serial name for MinedProduct and MinedProduct.Type --- .../src/main/typescript/generated/kafkatorio-schema.ts | 4 ++-- .../kotlin/dev/adamko/kafkatorio/schema/common/resources.kt | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts index f0559a9..e01e826 100644 --- a/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts +++ b/modules/events-mod/src/main/typescript/generated/kafkatorio-schema.ts @@ -248,12 +248,12 @@ export type List = any; export type PrototypeKey = Int; export interface MinedProduct { - type: Type; + type: MinedProductType; name: PrototypeName; amount: Double | null; } -export enum Type { +export enum MinedProductType { item = "item", fluid = "fluid", } \ No newline at end of file diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt index d637494..d21a750 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt @@ -5,6 +5,7 @@ import kotlinx.serialization.Serializable @Serializable +@SerialName("kafkatorio.resource.MinedProduct") data class MinedProduct( /** `item` or `fluid`. */ val type: Type, @@ -30,6 +31,7 @@ data class MinedProduct( ) { @Serializable + @SerialName("kafkatorio.resource.MinedProductType") enum class Type { @SerialName("item") ITEM, From 68adff29a85629945a9de9528914243d1e8b20c9 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Mon, 27 Jun 2022 23:00:11 +0200 Subject: [PATCH 432/629] try to diagnose weird getProjectTokens() null null null bug --- modules/events-mod/build.gradle.kts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 7feaa3c..1f9084d 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -39,7 +39,7 @@ val projectTokens: MapProperty = ?: error("error getting projectTokens") //val projectTokens: MapProperty by rootProject.extra -val projectTokensX = projectTokens.apply { +val projectTokensX1 = projectTokens.apply { put("mod.name", modName) put("mod.title", "Kafkatorio Events") put("mod.description", modDescription) @@ -82,7 +82,7 @@ val installEventsTsSchema by tasks.registering(Sync::class) { dependsOn(typescriptEventsSchema) // dependsOn(fixLink) - val outputDir = layout.projectDirectory.dir("src/main/typescript/generated/kafkatorio-schema") + val outputDir = layout.projectDirectory.dir("src/main/typescript/generated/") outputs.dir(outputDir) from( @@ -107,10 +107,10 @@ val installEventsTsSchema by tasks.registering(Sync::class) { val zipNameProvider = provider { distributionZipName } tasks.distZip { - val projectTokensXX = projectTokensX + val projectTokensXX22 = projectTokensX1 inputs.property("zipNameProvider", zipNameProvider) - inputs.property("projectTokens", projectTokensXX) + inputs.property("projectTokens", projectTokensXX22) archiveFileName.set(zipNameProvider) } @@ -131,6 +131,7 @@ distributions { main { distributionBaseName.set(modName) + val tokens333: MutableMap = projectTokensX1.get() contents { from(layout.projectDirectory.dir("src/main/resources/mod-data")) { @@ -139,8 +140,7 @@ distributions { from(licenseFile) from(typescriptToLua.map { it.outputDirectory }) filesNotMatching("**/*.png") { - val tokens: MutableMap = projectTokensX.get() - filter("tokens" to tokens) + filter("tokens" to tokens333) } includeEmptyDirs = false exclude { @@ -155,8 +155,8 @@ distributions { tasks.withType().configureEach { - val projectTokensXX = projectTokensX - inputs.property("projectTokens", projectTokensXX) + val projectTokensXX444 = projectTokensX1 + inputs.property("projectTokens", projectTokensXX444) } From 866c3e5c8f1d15574335d939801ff627b2a49b92 Mon Sep 17 00:00:00 2001 From: Adam Semenenko <897017+aSemy@users.noreply.github.com> Date: Mon, 27 Jun 2022 22:04:01 +0100 Subject: [PATCH 433/629] add restart-unless-stopped to containers --- modules/events-server/docker/docker-compose.yml | 1 + modules/web-map/docker/docker-compose.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/modules/events-server/docker/docker-compose.yml b/modules/events-server/docker/docker-compose.yml index 02f1f6b..dc29561 100644 --- a/modules/events-server/docker/docker-compose.yml +++ b/modules/events-server/docker/docker-compose.yml @@ -5,6 +5,7 @@ services: events-server: image: kafkatorio/events-server:${KAFKATORIO_VERSION} container_name: events-server + restart: unless-stopped build: context: .. dockerfile: ./docker/Dockerfile diff --git a/modules/web-map/docker/docker-compose.yml b/modules/web-map/docker/docker-compose.yml index ac0793c..6b859e1 100644 --- a/modules/web-map/docker/docker-compose.yml +++ b/modules/web-map/docker/docker-compose.yml @@ -5,6 +5,7 @@ services: kafkatorio-web-map: image: adamko-dev/kafkatorio-web-map container_name: kafkatorio-web-map + restart: unless-stopped build: context: ".." dockerfile: ./docker/Dockerfile From ae0d95b4cbd21d81e000638ea21ee4b531a39ce0 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 28 Jun 2022 20:44:36 +0200 Subject: [PATCH 434/629] remove old http4k application props --- .../processor/config/ApplicationProperties.kt | 64 --------------- .../kafkatorio/processor/config/Lenses.kt | 39 ---------- .../kafkatorio/processor/config/PortVal.kt | 14 +--- .../processor/config/environmentExt.kt | 78 ------------------- 4 files changed, 3 insertions(+), 192 deletions(-) delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt index 85ac987..5e794ad 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt @@ -31,67 +31,3 @@ data class ApplicationProperties( .loadConfigOrThrow() } } - - -//import dev.adamko.kafkatorio.processor.config.PortVal.Companion.portVal -//import java.nio.file.Path -//import java.time.Clock -//import java.util.Properties -//import kotlin.io.path.Path -//import org.http4k.cloudnative.env.Environment -//import org.http4k.cloudnative.env.EnvironmentKey -//import org.http4k.lens.nonEmptyString -// -///** -// * Load properties, in descending priority order, from -// * -// * 1. Environment variables -// * 2. This app's env file (as defined by the environment variable [Lenses.APPLICATION_PROPERTIES_FILE_PATH]) -// * # 3. A resources-dir yaml file -// * -// */ -//internal class ApplicationProperties( -// vararg environments: Environment = arrayOf( -// Environment.env(), -// Environment.fromEnvVarPath(), -// Environment.fromResourcesFile(".secret.config.yml") -// ) -//) { -// -// -// private val appProps: Environment = -// environments.reduce { acc, environment -> acc.overrides(environment) } -// -// -// fun clock(): Clock = Clock.systemUTC() -// -// -// /** -// * The port of the server -// * -// * Set by GCP ([docs](https://cloud.google.com/run/docs/reference/container-contract#env-vars)). -// */ -// val serverPort: PortVal -// get() = EnvironmentKey.portVal().defaulted("PORT", PortVal.DEFAULT)[appProps] -// -// -// val kafkaConfig: Properties -// get() = EnvironmentKey -// .nonEmptyString() -// .map { srcString -> -// srcString.reader().use { stringReader -> -// Properties().also { properties -> -// properties.load(stringReader) -// } -// } -// } -// .required("kafka.config")[appProps] -// -// -// val webmapTileDir: Path -// get() = EnvironmentKey -// .nonEmptyString() -// .map(::Path) -// .required("tileServer.webmapTileDir")[appProps] -// -//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt deleted file mode 100644 index 7faeb9c..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/Lenses.kt +++ /dev/null @@ -1,39 +0,0 @@ -package dev.adamko.kafkatorio.processor.config - -//import java.io.File -//import org.http4k.cloudnative.env.Environment -//import org.http4k.cloudnative.env.EnvironmentKey -//import org.http4k.core.Credentials -//import org.http4k.lens.BiDiLens -//import org.http4k.lens.BiDiMapping -// -// -//internal object Lenses { -// -// /** The location of this app's env file. */ -// val APPLICATION_PROPERTIES_FILE_PATH: BiDiLens = -// EnvironmentKey -// .map( -// { path: String -> File(path) }, -// { file: File -> file.canonicalPath }, -// ) -// .optional("APPLICATION_PROPERTIES_FILE_PATH") -// -// -// /** Bidirectional [String] and [Credentials] mapper. */ -// val credentialsLens: BiDiMapping = run { -// val separator = ":" -// BiDiMapping( -// // from String to Credentials -// { property -> -// property.split(separator, limit = 2) -// .takeIf { it.size == 2 } -// ?.let { (user, pass) -> Credentials(user, pass) } -// ?: throw IllegalArgumentException("Credentials are invalid") -// }, -// // from Credentials to String -// { it.user + separator + it.password } -// ) -// } -// -//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt index de0f49a..1418447 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt @@ -1,13 +1,9 @@ package dev.adamko.kafkatorio.processor.config import org.http4k.cloudnative.env.Port -import org.http4k.lens.BiDiLensSpec -import org.http4k.lens.StringBiDiMappings.int -import org.http4k.lens.map -/** - * Improved (slightly) version of http4k's [Port]. - */ + +/** Improved (slightly) version of http4k's [Port]. */ @JvmInline value class PortVal(val value: Int) { @@ -21,10 +17,6 @@ value class PortVal(val value: Int) { companion object { val DEFAULT = PortVal(8080) - val VALID_RANGE: IntRange - get() = (1..65535) - - fun BiDiLensSpec.portVal(): BiDiLensSpec = - map(int().map(::PortVal, PortVal::value)) + val VALID_RANGE: IntRange = 1..65535 } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt deleted file mode 100644 index 3ff3eee..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/environmentExt.kt +++ /dev/null @@ -1,78 +0,0 @@ -package dev.adamko.kafkatorio.processor.config - -//import java.io.File -//import java.io.FileNotFoundException -//import org.http4k.cloudnative.env.Environment -//import org.http4k.cloudnative.env.MapEnvironment -//import org.http4k.cloudnative.env.fromYaml -//import org.http4k.lens.Lens -// -// -///** -// * Load properties from either a `.yaml` or `.env` file. -// * -// * (An improved version of [Environment.fromResource]) -// */ -//fun Environment.Companion.fromResourcesFile( -// resource: String, -// default: Environment = EMPTY -//): Environment { -// return try { -// val file = -// this::class.java -// .getResource("/${resource.removePrefix("/")}") -// ?.file -// ?.let { File(it) } -// fromFile(file, default) -// } catch (e: FileNotFoundException) { -// default -// } -//} -// -// -///** -// * Try fetching a properties file the location provided by the -// * [`JVM`][jvmProperties] or [`System`][env] environment variable -// * [Lenses.APPLICATION_PROPERTIES_FILE_PATH], if it exists. -// * -// * If it does not exist, return [default]. -// */ -//fun Environment.Companion.fromEnvVarPath( -// location: Lens = Lenses.APPLICATION_PROPERTIES_FILE_PATH, -// default: Environment = EMPTY, -//): Environment { -// val file = (jvmProperties() overrides env())[location] -// -// return fromFile(file, default) -//} -// -// -///** -// * Load properties from either a `.yaml` or `.env` file. -// * -// * (An improved version of [Environment.from]) -// */ -//internal fun Environment.Companion.fromFile( -// file: File?, -// default: Environment = EMPTY, -//): Environment { -// return file -// ?.takeIf { it.isFile } -// .let { -// when (it?.extension) { -// "yml", "yaml" -> fromYaml(it) -// "env" -> from(it) -// else -> default -// } -// } -//} -// -// -///** The same as [Environment.ENV], but refreshes on each invocation (which is useful for testing). */ -//fun Environment.Companion.env(): Environment = -// MapEnvironment.from(System.getenv().toProperties()) -// -// -///** The same as [Environment.JVM_PROPERTIES], but refreshes on each invocation (which is useful for testing). */ -//internal fun Environment.Companion.jvmProperties(): Environment = -// MapEnvironment.from(System.getProperties()) From b0452881bc5d7586aca1eb5b4480d480cd67513d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 28 Jun 2022 21:59:54 +0200 Subject: [PATCH 435/629] commit generated lua code (I'm not 100% sure it's generated stably - this way I can see changes) --- modules/events-mod/build.gradle.kts | 31 +- modules/events-mod/src/main/lua/control.lua | 15 + .../main/lua/generated/kafkatorio-schema.lua | 26 + .../events-mod/src/main/lua/lualib_bundle.lua | 2475 +++++++++++++++++ .../src/main/lua/main/PacketEmitter.lua | 22 + .../main/lua/main/cache/EventDataCache.lua | 145 + .../lua/main/commands/kafkatorioCommands.lua | 76 + .../lua/main/events/configurationUpdate.lua | 65 + .../main/lua/main/events/consoleUpdates.lua | 21 + .../src/main/lua/main/events/converters.lua | 40 + .../main/lua/main/events/entityUpdates.lua | 105 + .../main/lua/main/events/eventTypeCheck.lua | 6 + .../main/lua/main/events/mapChunkUpdates.lua | 248 ++ .../main/lua/main/events/playerUpdates.lua | 165 ++ .../main/lua/main/events/prototypeUpdates.lua | 42 + .../main/lua/main/events/registerHandlers.lua | 49 + .../main/lua/main/events/settingsUpdate.lua | 6 + .../main/lua/main/events/surfaceUpdates.lua | 11 + .../src/main/lua/main/global-init.lua | 17 + .../src/main/lua/main/queue/queue.lua | 84 + .../lua/main/settings/KafkatorioSettings.lua | 40 + modules/events-mod/src/main/lua/settings.lua | 5 + 22 files changed, 3689 insertions(+), 5 deletions(-) create mode 100644 modules/events-mod/src/main/lua/control.lua create mode 100644 modules/events-mod/src/main/lua/generated/kafkatorio-schema.lua create mode 100644 modules/events-mod/src/main/lua/lualib_bundle.lua create mode 100644 modules/events-mod/src/main/lua/main/PacketEmitter.lua create mode 100644 modules/events-mod/src/main/lua/main/cache/EventDataCache.lua create mode 100644 modules/events-mod/src/main/lua/main/commands/kafkatorioCommands.lua create mode 100644 modules/events-mod/src/main/lua/main/events/configurationUpdate.lua create mode 100644 modules/events-mod/src/main/lua/main/events/consoleUpdates.lua create mode 100644 modules/events-mod/src/main/lua/main/events/converters.lua create mode 100644 modules/events-mod/src/main/lua/main/events/entityUpdates.lua create mode 100644 modules/events-mod/src/main/lua/main/events/eventTypeCheck.lua create mode 100644 modules/events-mod/src/main/lua/main/events/mapChunkUpdates.lua create mode 100644 modules/events-mod/src/main/lua/main/events/playerUpdates.lua create mode 100644 modules/events-mod/src/main/lua/main/events/prototypeUpdates.lua create mode 100644 modules/events-mod/src/main/lua/main/events/registerHandlers.lua create mode 100644 modules/events-mod/src/main/lua/main/events/settingsUpdate.lua create mode 100644 modules/events-mod/src/main/lua/main/events/surfaceUpdates.lua create mode 100644 modules/events-mod/src/main/lua/main/global-init.lua create mode 100644 modules/events-mod/src/main/lua/main/queue/queue.lua create mode 100644 modules/events-mod/src/main/lua/main/settings/KafkatorioSettings.lua create mode 100644 modules/events-mod/src/main/lua/settings.lua diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 1f9084d..bbfb92e 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -71,7 +71,8 @@ val typescriptToLua by tasks.registering(TypescriptToLuaTask::class) { dependsOn(tasks.npmInstall, installEventsTsSchema, tasks.updatePackageJson) sourceFiles.set(tsSrcDir) - outputDirectory.set(layout.buildDirectory.dir("typescriptToLua")) +// outputDirectory.set(layout.buildDirectory.dir("typescriptToLua")) + outputDirectory.set(layout.projectDirectory.dir("src/main/lua")) } @@ -80,7 +81,6 @@ val installEventsTsSchema by tasks.registering(Sync::class) { group = project.name dependsOn(typescriptEventsSchema) -// dependsOn(fixLink) val outputDir = layout.projectDirectory.dir("src/main/typescript/generated/") outputs.dir(outputDir) @@ -140,6 +140,8 @@ distributions { from(licenseFile) from(typescriptToLua.map { it.outputDirectory }) filesNotMatching("**/*.png") { + // maybe make a bug report for projectTokensX1 causing null$null$null error? + // val tokens333: MutableMap = projectTokensX1.get() filter("tokens" to tokens333) } includeEmptyDirs = false @@ -160,7 +162,6 @@ tasks.withType().configureEach { } - val factorioModProvider by configurations.registering { asProvider() factorioModAttributes(objects) @@ -185,14 +186,34 @@ tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) } idea { module { - sourceDirs = sourceDirs + file("src/main/typescript") + sourceDirs.plusAssign( + listOf( + file("src/main/typescript"), + file("src/main/lua"), + ) + ) +// sourceDirs = sourceDirs + file("src/main/lua") resourceDirs = resourceDirs + file("src/main/resources") testSourceDirs = testSourceDirs + file("src/test/typescript") + + generatedSourceDirs = generatedSourceDirs + listOf( + file("src/main/lua") + ) iml { whenMerged { require(this is org.gradle.plugins.ide.idea.model.Module) - sourceDirs = sourceDirs + file("src/main/typescript") + sourceDirs.plusAssign( + listOf( + file("src/main/typescript"), + file("src/main/lua"), + ) + ) + + generatedSourceFolders.plusAssign( + org.gradle.plugins.ide.idea.model.Path(file("src/main/lua").toURI().toString()) + ) +// sourceDirs = sourceDirs + file("src/main/typescript") resourceDirs = resourceDirs + file("src/main/resources") testSourceDirs = testSourceDirs + file("src/test/typescript") } diff --git a/modules/events-mod/src/main/lua/control.lua b/modules/events-mod/src/main/lua/control.lua new file mode 100644 index 0000000..0bd8e16 --- /dev/null +++ b/modules/events-mod/src/main/lua/control.lua @@ -0,0 +1,15 @@ +local ____exports = {} +local ____global_2Dinit = require("main.global-init") +local initGlobal = ____global_2Dinit.initGlobal +local ____prototypeUpdates = require("main.events.prototypeUpdates") +local emitPrototypes = ____prototypeUpdates.emitPrototypes +require("main.events.registerHandlers") +require("main.events.mapChunkUpdates") +require("main.events.playerUpdates") +require("main.events.entityUpdates") +require("main.commands.kafkatorioCommands") +script.on_init(function() + initGlobal(true) + emitPrototypes() +end) +return ____exports diff --git a/modules/events-mod/src/main/lua/generated/kafkatorio-schema.lua b/modules/events-mod/src/main/lua/generated/kafkatorio-schema.lua new file mode 100644 index 0000000..65df7de --- /dev/null +++ b/modules/events-mod/src/main/lua/generated/kafkatorio-schema.lua @@ -0,0 +1,26 @@ +local ____exports = {} +____exports.KafkatorioPacketData = {} +local KafkatorioPacketData = ____exports.KafkatorioPacketData +do + KafkatorioPacketData.Type = Type or ({}) + KafkatorioPacketData.Type.ConfigurationUpdate = "kafkatorio.packet.instant.ConfigurationUpdate" + KafkatorioPacketData.Type.ConsoleChatUpdate = "kafkatorio.packet.instant.ConsoleChatUpdate" + KafkatorioPacketData.Type.ConsoleCommandUpdate = "kafkatorio.packet.instant.ConsoleCommandUpdate" + KafkatorioPacketData.Type.PrototypesUpdate = "kafkatorio.packet.instant.PrototypesUpdate" + KafkatorioPacketData.Type.SurfaceUpdate = "kafkatorio.packet.instant.SurfaceUpdate" + KafkatorioPacketData.Type.EntityUpdate = "kafkatorio.packet.keyed.EntityUpdate" + KafkatorioPacketData.Type.MapChunkUpdate = "kafkatorio.packet.keyed.MapChunkUpdate" + KafkatorioPacketData.Type.PlayerUpdate = "kafkatorio.packet.keyed.PlayerUpdate" + KafkatorioPacketData.Type.Error = "kafkatorio.packet.KafkatorioPacketData.Error" +end +____exports.FactorioPrototype = {} +local FactorioPrototype = ____exports.FactorioPrototype +do + FactorioPrototype.Type = Type or ({}) + FactorioPrototype.Type.Entity = "kafkatorio.prototype.Entity" + FactorioPrototype.Type.MapTile = "kafkatorio.prototype.MapTile" +end +____exports.MinedProductType = MinedProductType or ({}) +____exports.MinedProductType.item = "item" +____exports.MinedProductType.fluid = "fluid" +return ____exports diff --git a/modules/events-mod/src/main/lua/lualib_bundle.lua b/modules/events-mod/src/main/lua/lualib_bundle.lua new file mode 100644 index 0000000..e76c793 --- /dev/null +++ b/modules/events-mod/src/main/lua/lualib_bundle.lua @@ -0,0 +1,2475 @@ +local function __TS__ArrayIsArray(value) + return type(value) == "table" and (value[1] ~= nil or next(value) == nil) +end + +local function __TS__ArrayConcat(self, ...) + local items = {...} + local result = {} + local len = 0 + for i = 1, #self do + len = len + 1 + result[len] = self[i] + end + for i = 1, #items do + local item = items[i] + if __TS__ArrayIsArray(item) then + for j = 1, #item do + len = len + 1 + result[len] = item[j] + end + else + len = len + 1 + result[len] = item + end + end + return result +end + +local __TS__Symbol, Symbol +do + local symbolMetatable = {__tostring = function(self) + return ("Symbol(" .. (self.description or "")) .. ")" + end} + function __TS__Symbol(description) + return setmetatable({description = description}, symbolMetatable) + end + Symbol = { + iterator = __TS__Symbol("Symbol.iterator"), + hasInstance = __TS__Symbol("Symbol.hasInstance"), + species = __TS__Symbol("Symbol.species"), + toStringTag = __TS__Symbol("Symbol.toStringTag") + } +end + +local function __TS__ArrayEntries(array) + local key = 0 + return { + [Symbol.iterator] = function(self) + return self + end, + next = function(self) + local result = {done = array[key + 1] == nil, value = {key, array[key + 1]}} + key = key + 1 + return result + end + } +end + +local function __TS__ArrayEvery(self, callbackfn, thisArg) + for i = 1, #self do + if not callbackfn(thisArg, self[i], i - 1, self) then + return false + end + end + return true +end + +local function __TS__ArrayFilter(self, callbackfn, thisArg) + local result = {} + local len = 0 + for i = 1, #self do + if callbackfn(thisArg, self[i], i - 1, self) then + len = len + 1 + result[len] = self[i] + end + end + return result +end + +local function __TS__ArrayForEach(self, callbackFn, thisArg) + for i = 1, #self do + callbackFn(thisArg, self[i], i - 1, self) + end +end + +local function __TS__ArrayFind(self, predicate, thisArg) + for i = 1, #self do + local elem = self[i] + if predicate(thisArg, elem, i - 1, self) then + return elem + end + end + return nil +end + +local function __TS__ArrayFindIndex(self, callbackFn, thisArg) + for i = 1, #self do + if callbackFn(thisArg, self[i], i - 1, self) then + return i - 1 + end + end + return -1 +end + +local __TS__Iterator +do + local function iteratorGeneratorStep(self) + local co = self.____coroutine + local status, value = coroutine.resume(co) + if not status then + error(value, 0) + end + if coroutine.status(co) == "dead" then + return + end + return true, value + end + local function iteratorIteratorStep(self) + local result = self:next() + if result.done then + return + end + return true, result.value + end + local function iteratorStringStep(self, index) + index = index + 1 + if index > #self then + return + end + return index, string.sub(self, index, index) + end + function __TS__Iterator(iterable) + if type(iterable) == "string" then + return iteratorStringStep, iterable, 0 + elseif iterable.____coroutine ~= nil then + return iteratorGeneratorStep, iterable + elseif iterable[Symbol.iterator] then + local iterator = iterable[Symbol.iterator](iterable) + return iteratorIteratorStep, iterator + else + return ipairs(iterable) + end + end +end + +local __TS__ArrayFrom +do + local function arrayLikeStep(self, index) + index = index + 1 + if index > self.length then + return + end + return index, self[index] + end + local function arrayLikeIterator(arr) + if type(arr.length) == "number" then + return arrayLikeStep, arr, 0 + end + return __TS__Iterator(arr) + end + function __TS__ArrayFrom(arrayLike, mapFn, thisArg) + local result = {} + if mapFn == nil then + for ____, v in arrayLikeIterator(arrayLike) do + result[#result + 1] = v + end + else + for i, v in arrayLikeIterator(arrayLike) do + result[#result + 1] = mapFn(thisArg, v, i - 1) + end + end + return result + end +end + +local function __TS__ArrayIncludes(self, searchElement, fromIndex) + if fromIndex == nil then + fromIndex = 0 + end + local len = #self + local k = fromIndex + if fromIndex < 0 then + k = len + fromIndex + end + if k < 0 then + k = 0 + end + for i = k + 1, len do + if self[i] == searchElement then + return true + end + end + return false +end + +local function __TS__ArrayIndexOf(self, searchElement, fromIndex) + if fromIndex == nil then + fromIndex = 0 + end + local len = #self + if len == 0 then + return -1 + end + if fromIndex >= len then + return -1 + end + if fromIndex < 0 then + fromIndex = len + fromIndex + if fromIndex < 0 then + fromIndex = 0 + end + end + for i = fromIndex + 1, len do + if self[i] == searchElement then + return i - 1 + end + end + return -1 +end + +local function __TS__ArrayJoin(self, separator) + if separator == nil then + separator = "," + end + local parts = {} + for i = 1, #self do + parts[i] = tostring(self[i]) + end + return table.concat(parts, separator) +end + +local function __TS__ArrayMap(self, callbackfn, thisArg) + local result = {} + for i = 1, #self do + result[i] = callbackfn(thisArg, self[i], i - 1, self) + end + return result +end + +local function __TS__ArrayPush(self, ...) + local items = {...} + local len = #self + for i = 1, #items do + len = len + 1 + self[len] = items[i] + end + return len +end + +local function __TS__ArrayPushArray(self, items) + local len = #self + for i = 1, #items do + len = len + 1 + self[len] = items[i] + end + return len +end + +local function __TS__ArrayReduce(self, callbackFn, ...) + local len = #self + local k = 0 + local accumulator = nil + if select("#", ...) ~= 0 then + accumulator = ... + elseif len > 0 then + accumulator = self[1] + k = 1 + else + error("Reduce of empty array with no initial value", 0) + end + for i = k + 1, len do + accumulator = callbackFn( + nil, + accumulator, + self[i], + i - 1, + self + ) + end + return accumulator +end + +local function __TS__ArrayReduceRight(self, callbackFn, ...) + local len = #self + local k = len - 1 + local accumulator = nil + if select("#", ...) ~= 0 then + accumulator = ... + elseif len > 0 then + accumulator = self[k + 1] + k = k - 1 + else + error("Reduce of empty array with no initial value", 0) + end + for i = k + 1, 1, -1 do + accumulator = callbackFn( + nil, + accumulator, + self[i], + i - 1, + self + ) + end + return accumulator +end + +local function __TS__ArrayReverse(self) + local i = 1 + local j = #self + while i < j do + local temp = self[j] + self[j] = self[i] + self[i] = temp + i = i + 1 + j = j - 1 + end + return self +end + +local function __TS__ArrayUnshift(self, ...) + local items = {...} + local numItemsToInsert = #items + if numItemsToInsert == 0 then + return #self + end + for i = #self, 1, -1 do + self[i + numItemsToInsert] = self[i] + end + for i = 1, numItemsToInsert do + self[i] = items[i] + end + return #self +end + +local function __TS__ArraySort(self, compareFn) + if compareFn ~= nil then + table.sort( + self, + function(a, b) return compareFn(nil, a, b) < 0 end + ) + else + table.sort(self) + end + return self +end + +local function __TS__ArraySlice(self, first, last) + local len = #self + first = first or 0 + if first < 0 then + first = len + first + if first < 0 then + first = 0 + end + else + if first > len then + first = len + end + end + last = last or len + if last < 0 then + last = len + last + if last < 0 then + last = 0 + end + else + if last > len then + last = len + end + end + local out = {} + first = first + 1 + last = last + 1 + local n = 1 + while first < last do + out[n] = self[first] + first = first + 1 + n = n + 1 + end + return out +end + +local function __TS__ArraySome(self, callbackfn, thisArg) + for i = 1, #self do + if callbackfn(thisArg, self[i], i - 1, self) then + return true + end + end + return false +end + +local function __TS__ArraySplice(self, ...) + local args = {...} + local len = #self + local actualArgumentCount = select("#", ...) + local start = args[1] + local deleteCount = args[2] + if start < 0 then + start = len + start + if start < 0 then + start = 0 + end + elseif start > len then + start = len + end + local itemCount = actualArgumentCount - 2 + if itemCount < 0 then + itemCount = 0 + end + local actualDeleteCount + if actualArgumentCount == 0 then + actualDeleteCount = 0 + elseif actualArgumentCount == 1 then + actualDeleteCount = len - start + else + actualDeleteCount = deleteCount or 0 + if actualDeleteCount < 0 then + actualDeleteCount = 0 + end + if actualDeleteCount > len - start then + actualDeleteCount = len - start + end + end + local out = {} + for k = 1, actualDeleteCount do + local from = start + k + if self[from] ~= nil then + out[k] = self[from] + end + end + if itemCount < actualDeleteCount then + for k = start + 1, len - actualDeleteCount do + local from = k + actualDeleteCount + local to = k + itemCount + if self[from] then + self[to] = self[from] + else + self[to] = nil + end + end + for k = len - actualDeleteCount + itemCount + 1, len do + self[k] = nil + end + elseif itemCount > actualDeleteCount then + for k = len - actualDeleteCount, start + 1, -1 do + local from = k + actualDeleteCount + local to = k + itemCount + if self[from] then + self[to] = self[from] + else + self[to] = nil + end + end + end + local j = start + 1 + for i = 3, actualArgumentCount do + self[j] = args[i] + j = j + 1 + end + for k = #self, len - actualDeleteCount + itemCount + 1, -1 do + self[k] = nil + end + return out +end + +local function __TS__ArrayToObject(self) + local object = {} + for i = 1, #self do + object[i - 1] = self[i] + end + return object +end + +local function __TS__ArrayFlat(self, depth) + if depth == nil then + depth = 1 + end + local result = {} + local len = 0 + for i = 1, #self do + local value = self[i] + if depth > 0 and __TS__ArrayIsArray(value) then + local toAdd + if depth == 1 then + toAdd = value + else + toAdd = __TS__ArrayFlat(value, depth - 1) + end + for j = 1, #toAdd do + local val = toAdd[j] + len = len + 1 + result[len] = val + end + else + len = len + 1 + result[len] = value + end + end + return result +end + +local function __TS__ArrayFlatMap(self, callback, thisArg) + local result = {} + local len = 0 + for i = 1, #self do + local value = callback(thisArg, self[i], i - 1, self) + if __TS__ArrayIsArray(value) then + for j = 1, #value do + len = len + 1 + result[len] = value[j] + end + else + len = len + 1 + result[len] = value + end + end + return result +end + +local function __TS__ArraySetLength(self, length) + if length < 0 or length ~= length or length == math.huge or math.floor(length) ~= length then + error( + "invalid array length: " .. tostring(length), + 0 + ) + end + for i = length + 1, #self do + self[i] = nil + end + return length +end + +local function __TS__InstanceOf(obj, classTbl) + if type(classTbl) ~= "table" then + error("Right-hand side of 'instanceof' is not an object", 0) + end + if classTbl[Symbol.hasInstance] ~= nil then + return not not classTbl[Symbol.hasInstance](classTbl, obj) + end + if type(obj) == "table" then + local luaClass = obj.constructor + while luaClass ~= nil do + if luaClass == classTbl then + return true + end + luaClass = luaClass.____super + end + end + return false +end + +local function __TS__New(target, ...) + local instance = setmetatable({}, target.prototype) + instance:____constructor(...) + return instance +end + +local function __TS__Class(self) + local c = {prototype = {}} + c.prototype.__index = c.prototype + c.prototype.constructor = c + return c +end + +local __TS__Unpack = table.unpack or unpack + +local function __TS__FunctionBind(fn, ...) + local boundArgs = {...} + return function(____, ...) + local args = {...} + __TS__ArrayUnshift( + args, + __TS__Unpack(boundArgs) + ) + return fn(__TS__Unpack(args)) + end +end + +local __TS__Promise +do + local function promiseDeferred(self) + local resolve + local reject + local promise = __TS__New( + __TS__Promise, + function(____, res, rej) + resolve = res + reject = rej + end + ) + return {promise = promise, resolve = resolve, reject = reject} + end + local function isPromiseLike(self, thing) + return __TS__InstanceOf(thing, __TS__Promise) + end + __TS__Promise = __TS__Class() + __TS__Promise.name = "__TS__Promise" + function __TS__Promise.prototype.____constructor(self, executor) + self.state = 0 + self.fulfilledCallbacks = {} + self.rejectedCallbacks = {} + self.finallyCallbacks = {} + do + local function ____catch(e) + self:reject(e) + end + local ____try, ____hasReturned = pcall(function() + executor( + nil, + __TS__FunctionBind(self.resolve, self), + __TS__FunctionBind(self.reject, self) + ) + end) + if not ____try then + ____catch(____hasReturned) + end + end + end + function __TS__Promise.resolve(data) + local promise = __TS__New( + __TS__Promise, + function() + end + ) + promise.state = 1 + promise.value = data + return promise + end + function __TS__Promise.reject(reason) + local promise = __TS__New( + __TS__Promise, + function() + end + ) + promise.state = 2 + promise.rejectionReason = reason + return promise + end + __TS__Promise.prototype["then"] = function(self, onFulfilled, onRejected) + local ____promiseDeferred_result_0 = promiseDeferred(nil) + local promise = ____promiseDeferred_result_0.promise + local resolve = ____promiseDeferred_result_0.resolve + local reject = ____promiseDeferred_result_0.reject + local isFulfilled = self.state == 1 + local isRejected = self.state == 2 + if onFulfilled then + local internalCallback = self:createPromiseResolvingCallback(onFulfilled, resolve, reject) + local ____self_fulfilledCallbacks_1 = self.fulfilledCallbacks + ____self_fulfilledCallbacks_1[#____self_fulfilledCallbacks_1 + 1] = internalCallback + if isFulfilled then + internalCallback(nil, self.value) + end + else + local ____self_fulfilledCallbacks_2 = self.fulfilledCallbacks + ____self_fulfilledCallbacks_2[#____self_fulfilledCallbacks_2 + 1] = function() return resolve(nil, nil) end + end + if onRejected then + local internalCallback = self:createPromiseResolvingCallback(onRejected, resolve, reject) + local ____self_rejectedCallbacks_3 = self.rejectedCallbacks + ____self_rejectedCallbacks_3[#____self_rejectedCallbacks_3 + 1] = internalCallback + if isRejected then + internalCallback(nil, self.rejectionReason) + end + end + if isFulfilled then + resolve(nil, self.value) + end + if isRejected then + reject(nil, self.rejectionReason) + end + return promise + end + function __TS__Promise.prototype.catch(self, onRejected) + return self["then"](self, nil, onRejected) + end + function __TS__Promise.prototype.finally(self, onFinally) + if onFinally then + local ____self_finallyCallbacks_4 = self.finallyCallbacks + ____self_finallyCallbacks_4[#____self_finallyCallbacks_4 + 1] = onFinally + if self.state ~= 0 then + onFinally(nil) + end + end + return self + end + function __TS__Promise.prototype.resolve(self, data) + if __TS__InstanceOf(data, __TS__Promise) then + data["then"]( + data, + function(____, v) return self:resolve(v) end, + function(____, err) return self:reject(err) end + ) + return + end + if self.state == 0 then + self.state = 1 + self.value = data + for ____, callback in ipairs(self.fulfilledCallbacks) do + callback(nil, data) + end + for ____, callback in ipairs(self.finallyCallbacks) do + callback(nil) + end + end + end + function __TS__Promise.prototype.reject(self, reason) + if self.state == 0 then + self.state = 2 + self.rejectionReason = reason + for ____, callback in ipairs(self.rejectedCallbacks) do + callback(nil, reason) + end + for ____, callback in ipairs(self.finallyCallbacks) do + callback(nil) + end + end + end + function __TS__Promise.prototype.createPromiseResolvingCallback(self, f, resolve, reject) + return function(____, value) + do + local function ____catch(e) + reject(nil, e) + end + local ____try, ____hasReturned = pcall(function() + self:handleCallbackData( + f(nil, value), + resolve, + reject + ) + end) + if not ____try then + ____catch(____hasReturned) + end + end + end + end + function __TS__Promise.prototype.handleCallbackData(self, data, resolve, reject) + if isPromiseLike(nil, data) then + local nextpromise = data + if nextpromise.state == 1 then + resolve(nil, nextpromise.value) + elseif nextpromise.state == 2 then + reject(nil, nextpromise.rejectionReason) + else + data["then"](data, resolve, reject) + end + else + resolve(nil, data) + end + end +end + +local function __TS__AsyncAwaiter(generator) + return __TS__New( + __TS__Promise, + function(____, resolve, reject) + local adopt, fulfilled, step, resolved, asyncCoroutine + function adopt(self, value) + local ____temp_0 + if __TS__InstanceOf(value, __TS__Promise) then + ____temp_0 = value + else + ____temp_0 = __TS__Promise.resolve(value) + end + return ____temp_0 + end + function fulfilled(self, value) + local success, resultOrError = coroutine.resume(asyncCoroutine, value) + if success then + step(nil, resultOrError) + else + reject(nil, resultOrError) + end + end + function step(self, result) + if resolved then + return + end + if coroutine.status(asyncCoroutine) == "dead" then + resolve(nil, result) + else + local ____self_1 = adopt(nil, result) + ____self_1["then"](____self_1, fulfilled, reject) + end + end + resolved = false + asyncCoroutine = coroutine.create(generator) + local success, resultOrError = coroutine.resume( + asyncCoroutine, + function(____, v) + resolved = true + local ____self_2 = adopt(nil, v) + ____self_2["then"](____self_2, resolve, reject) + end + ) + if success then + step(nil, resultOrError) + else + reject(nil, resultOrError) + end + end + ) +end +local function __TS__Await(thing) + return coroutine.yield(thing) +end + +local function __TS__ClassExtends(target, base) + target.____super = base + local staticMetatable = setmetatable({__index = base}, base) + setmetatable(target, staticMetatable) + local baseMetatable = getmetatable(base) + if baseMetatable then + if type(baseMetatable.__index) == "function" then + staticMetatable.__index = baseMetatable.__index + end + if type(baseMetatable.__newindex) == "function" then + staticMetatable.__newindex = baseMetatable.__newindex + end + end + setmetatable(target.prototype, base.prototype) + if type(base.prototype.__index) == "function" then + target.prototype.__index = base.prototype.__index + end + if type(base.prototype.__newindex) == "function" then + target.prototype.__newindex = base.prototype.__newindex + end + if type(base.prototype.__tostring) == "function" then + target.prototype.__tostring = base.prototype.__tostring + end +end + +local function __TS__CloneDescriptor(____bindingPattern0) + local value + local writable + local set + local get + local configurable + local enumerable + enumerable = ____bindingPattern0.enumerable + configurable = ____bindingPattern0.configurable + get = ____bindingPattern0.get + set = ____bindingPattern0.set + writable = ____bindingPattern0.writable + value = ____bindingPattern0.value + local descriptor = {enumerable = enumerable == true, configurable = configurable == true} + local hasGetterOrSetter = get ~= nil or set ~= nil + local hasValueOrWritableAttribute = writable ~= nil or value ~= nil + if hasGetterOrSetter and hasValueOrWritableAttribute then + error("Invalid property descriptor. Cannot both specify accessors and a value or writable attribute.", 0) + end + if get or set then + descriptor.get = get + descriptor.set = set + else + descriptor.value = value + descriptor.writable = writable == true + end + return descriptor +end + +local function __TS__ObjectAssign(target, ...) + local sources = {...} + for i = 1, #sources do + local source = sources[i] + for key in pairs(source) do + target[key] = source[key] + end + end + return target +end + +local function __TS__ObjectGetOwnPropertyDescriptor(object, key) + local metatable = getmetatable(object) + if not metatable then + return + end + if not rawget(metatable, "_descriptors") then + return + end + return rawget(metatable, "_descriptors")[key] +end + +local __TS__SetDescriptor +do + local function descriptorIndex(self, key) + local value = rawget(self, key) + if value ~= nil then + return value + end + local metatable = getmetatable(self) + while metatable do + local rawResult = rawget(metatable, key) + if rawResult ~= nil then + return rawResult + end + local descriptors = rawget(metatable, "_descriptors") + if descriptors then + local descriptor = descriptors[key] + if descriptor then + if descriptor.get then + return descriptor.get(self) + end + return descriptor.value + end + end + metatable = getmetatable(metatable) + end + end + local function descriptorNewIndex(self, key, value) + local metatable = getmetatable(self) + while metatable do + local descriptors = rawget(metatable, "_descriptors") + if descriptors then + local descriptor = descriptors[key] + if descriptor then + if descriptor.set then + descriptor.set(self, value) + else + if descriptor.writable == false then + error( + ((("Cannot assign to read only property '" .. key) .. "' of object '") .. tostring(self)) .. "'", + 0 + ) + end + descriptor.value = value + end + return + end + end + metatable = getmetatable(metatable) + end + rawset(self, key, value) + end + function __TS__SetDescriptor(target, key, desc, isPrototype) + if isPrototype == nil then + isPrototype = false + end + local ____isPrototype_0 + if isPrototype then + ____isPrototype_0 = target + else + ____isPrototype_0 = getmetatable(target) + end + local metatable = ____isPrototype_0 + if not metatable then + metatable = {} + setmetatable(target, metatable) + end + local value = rawget(target, key) + if value ~= nil then + rawset(target, key, nil) + end + if not rawget(metatable, "_descriptors") then + metatable._descriptors = {} + end + local descriptor = __TS__CloneDescriptor(desc) + metatable._descriptors[key] = descriptor + metatable.__index = descriptorIndex + metatable.__newindex = descriptorNewIndex + end +end + +local function __TS__Decorate(decorators, target, key, desc) + local result = target + do + local i = #decorators + while i >= 0 do + local decorator = decorators[i + 1] + if decorator then + local oldResult = result + if key == nil then + result = decorator(nil, result) + elseif desc == true then + local value = rawget(target, key) + local descriptor = __TS__ObjectGetOwnPropertyDescriptor(target, key) or ({configurable = true, writable = true, value = value}) + local desc = decorator(nil, target, key, descriptor) or descriptor + local isSimpleValue = desc.configurable == true and desc.writable == true and not desc.get and not desc.set + if isSimpleValue then + rawset(target, key, desc.value) + else + __TS__SetDescriptor( + target, + key, + __TS__ObjectAssign({}, descriptor, desc) + ) + end + elseif desc == false then + result = decorator(nil, target, key, desc) + else + result = decorator(nil, target, key) + end + result = result or oldResult + end + i = i - 1 + end + end + return result +end + +local function __TS__DecorateParam(paramIndex, decorator) + return function(____, target, key) return decorator(nil, target, key, paramIndex) end +end + +local Error, RangeError, ReferenceError, SyntaxError, TypeError, URIError +do + local function getErrorStack(self, constructor) + local level = 1 + while true do + local info = debug.getinfo(level, "f") + level = level + 1 + if not info then + level = 1 + break + elseif info.func == constructor then + break + end + end + return debug.traceback(nil, level) + end + local function wrapErrorToString(self, getDescription) + return function(self) + local description = getDescription(self) + local caller = debug.getinfo(3, "f") + if _VERSION == "Lua 5.1" or caller and caller.func ~= error then + return description + else + return (tostring(description) .. "\n") .. self.stack + end + end + end + local function initErrorClass(self, Type, name) + Type.name = name + return setmetatable( + Type, + {__call = function(____, _self, message) return __TS__New(Type, message) end} + ) + end + local ____initErrorClass_2 = initErrorClass + local ____class_0 = __TS__Class() + ____class_0.name = "" + function ____class_0.prototype.____constructor(self, message) + if message == nil then + message = "" + end + self.message = message + self.name = "Error" + self.stack = getErrorStack(nil, self.constructor.new) + local metatable = getmetatable(self) + if not metatable.__errorToStringPatched then + metatable.__errorToStringPatched = true + metatable.__tostring = wrapErrorToString(nil, metatable.__tostring) + end + end + function ____class_0.prototype.__tostring(self) + local ____temp_1 + if self.message ~= "" then + ____temp_1 = (self.name .. ": ") .. self.message + else + ____temp_1 = self.name + end + return ____temp_1 + end + Error = ____initErrorClass_2(nil, ____class_0, "Error") + local function createErrorClass(self, name) + local ____initErrorClass_4 = initErrorClass + local ____class_3 = __TS__Class() + ____class_3.name = ____class_3.name + __TS__ClassExtends(____class_3, Error) + function ____class_3.prototype.____constructor(self, ...) + ____class_3.____super.prototype.____constructor(self, ...) + self.name = name + end + return ____initErrorClass_4(nil, ____class_3, name) + end + RangeError = createErrorClass(nil, "RangeError") + ReferenceError = createErrorClass(nil, "ReferenceError") + SyntaxError = createErrorClass(nil, "SyntaxError") + TypeError = createErrorClass(nil, "TypeError") + URIError = createErrorClass(nil, "URIError") +end + +local function __TS__ObjectGetOwnPropertyDescriptors(object) + local metatable = getmetatable(object) + if not metatable then + return {} + end + return rawget(metatable, "_descriptors") or ({}) +end + +local function __TS__Delete(target, key) + local descriptors = __TS__ObjectGetOwnPropertyDescriptors(target) + local descriptor = descriptors[key] + if descriptor then + if not descriptor.configurable then + error( + __TS__New( + TypeError, + ((("Cannot delete property " .. tostring(key)) .. " of ") .. tostring(target)) .. "." + ), + 0 + ) + end + descriptors[key] = nil + return true + end + target[key] = nil + return true +end + +local function __TS__StringAccess(self, index) + if index >= 0 and index < #self then + return string.sub(self, index + 1, index + 1) + end +end + +local function __TS__DelegatedYield(iterable) + if type(iterable) == "string" then + for index = 0, #iterable - 1 do + coroutine.yield(__TS__StringAccess(iterable, index)) + end + elseif iterable.____coroutine ~= nil then + local co = iterable.____coroutine + while true do + local status, value = coroutine.resume(co) + if not status then + error(value, 0) + end + if coroutine.status(co) == "dead" then + return value + else + coroutine.yield(value) + end + end + elseif iterable[Symbol.iterator] then + local iterator = iterable[Symbol.iterator](iterable) + while true do + local result = iterator:next() + if result.done then + return result.value + else + coroutine.yield(result.value) + end + end + else + for ____, value in ipairs(iterable) do + coroutine.yield(value) + end + end +end + +local __TS__Generator +do + local function generatorIterator(self) + return self + end + local function generatorNext(self, ...) + local co = self.____coroutine + if coroutine.status(co) == "dead" then + return {done = true} + end + local status, value = coroutine.resume(co, ...) + if not status then + error(value, 0) + end + return { + value = value, + done = coroutine.status(co) == "dead" + } + end + function __TS__Generator(fn) + return function(...) + local args = {...} + local argsLength = select("#", ...) + return { + ____coroutine = coroutine.create(function() return fn((unpack or table.unpack)(args, 1, argsLength)) end), + [Symbol.iterator] = generatorIterator, + next = generatorNext + } + end + end +end + +local function __TS__InstanceOfObject(value) + local valueType = type(value) + return valueType == "table" or valueType == "function" +end + +local Map +do + Map = __TS__Class() + Map.name = "Map" + function Map.prototype.____constructor(self, entries) + self[Symbol.toStringTag] = "Map" + self.items = {} + self.size = 0 + self.nextKey = {} + self.previousKey = {} + if entries == nil then + return + end + local iterable = entries + if iterable[Symbol.iterator] then + local iterator = iterable[Symbol.iterator](iterable) + while true do + local result = iterator:next() + if result.done then + break + end + local value = result.value + self:set(value[1], value[2]) + end + else + local array = entries + for ____, kvp in ipairs(array) do + self:set(kvp[1], kvp[2]) + end + end + end + function Map.prototype.clear(self) + self.items = {} + self.nextKey = {} + self.previousKey = {} + self.firstKey = nil + self.lastKey = nil + self.size = 0 + end + function Map.prototype.delete(self, key) + local contains = self:has(key) + if contains then + self.size = self.size - 1 + local next = self.nextKey[key] + local previous = self.previousKey[key] + if next and previous then + self.nextKey[previous] = next + self.previousKey[next] = previous + elseif next then + self.firstKey = next + self.previousKey[next] = nil + elseif previous then + self.lastKey = previous + self.nextKey[previous] = nil + else + self.firstKey = nil + self.lastKey = nil + end + self.nextKey[key] = nil + self.previousKey[key] = nil + end + self.items[key] = nil + return contains + end + function Map.prototype.forEach(self, callback) + for ____, key in __TS__Iterator(self:keys()) do + callback(nil, self.items[key], key, self) + end + end + function Map.prototype.get(self, key) + return self.items[key] + end + function Map.prototype.has(self, key) + return self.nextKey[key] ~= nil or self.lastKey == key + end + function Map.prototype.set(self, key, value) + local isNewValue = not self:has(key) + if isNewValue then + self.size = self.size + 1 + end + self.items[key] = value + if self.firstKey == nil then + self.firstKey = key + self.lastKey = key + elseif isNewValue then + self.nextKey[self.lastKey] = key + self.previousKey[key] = self.lastKey + self.lastKey = key + end + return self + end + Map.prototype[Symbol.iterator] = function(self) + return self:entries() + end + function Map.prototype.entries(self) + local ____temp_0 = self + local items = ____temp_0.items + local nextKey = ____temp_0.nextKey + local key = self.firstKey + return { + [Symbol.iterator] = function(self) + return self + end, + next = function(self) + local result = {done = not key, value = {key, items[key]}} + key = nextKey[key] + return result + end + } + end + function Map.prototype.keys(self) + local nextKey = self.nextKey + local key = self.firstKey + return { + [Symbol.iterator] = function(self) + return self + end, + next = function(self) + local result = {done = not key, value = key} + key = nextKey[key] + return result + end + } + end + function Map.prototype.values(self) + local ____temp_1 = self + local items = ____temp_1.items + local nextKey = ____temp_1.nextKey + local key = self.firstKey + return { + [Symbol.iterator] = function(self) + return self + end, + next = function(self) + local result = {done = not key, value = items[key]} + key = nextKey[key] + return result + end + } + end + Map[Symbol.species] = Map +end + +local __TS__MathAtan2 = math.atan2 or math.atan + +local function __TS__MathSign(val) + if val > 0 then + return 1 + elseif val < 0 then + return -1 + end + return 0 +end + +local function __TS__Number(value) + local valueType = type(value) + if valueType == "number" then + return value + elseif valueType == "string" then + local numberValue = tonumber(value) + if numberValue then + return numberValue + end + if value == "Infinity" then + return math.huge + end + if value == "-Infinity" then + return -math.huge + end + local stringWithoutSpaces = string.gsub(value, "%s", "") + if stringWithoutSpaces == "" then + return 0 + end + return 0 / 0 + elseif valueType == "boolean" then + return value and 1 or 0 + else + return 0 / 0 + end +end + +local function __TS__NumberIsFinite(value) + return type(value) == "number" and value == value and value ~= math.huge and value ~= -math.huge +end + +local function __TS__NumberIsNaN(value) + return value ~= value +end + +local __TS__NumberToString +do + local radixChars = "0123456789abcdefghijklmnopqrstuvwxyz" + function __TS__NumberToString(self, radix) + if radix == nil or radix == 10 or self == math.huge or self == -math.huge or self ~= self then + return tostring(self) + end + radix = math.floor(radix) + if radix < 2 or radix > 36 then + error("toString() radix argument must be between 2 and 36", 0) + end + local integer, fraction = math.modf(math.abs(self)) + local result = "" + if radix == 8 then + result = string.format("%o", integer) + elseif radix == 16 then + result = string.format("%x", integer) + else + repeat + do + result = __TS__StringAccess(radixChars, integer % radix) .. result + integer = math.floor(integer / radix) + end + until not (integer ~= 0) + end + if fraction ~= 0 then + result = result .. "." + local delta = 1e-16 + repeat + do + fraction = fraction * radix + delta = delta * radix + local digit = math.floor(fraction) + result = result .. __TS__StringAccess(radixChars, digit) + fraction = fraction - digit + end + until not (fraction >= delta) + end + if self < 0 then + result = "-" .. result + end + return result + end +end + +local function __TS__ObjectDefineProperty(target, key, desc) + local ____temp_0 + if type(key) == "number" then + ____temp_0 = key + 1 + else + ____temp_0 = key + end + local luaKey = ____temp_0 + local value = rawget(target, luaKey) + local hasGetterOrSetter = desc.get ~= nil or desc.set ~= nil + local descriptor + if hasGetterOrSetter then + if value ~= nil then + error( + "Cannot redefine property: " .. tostring(key), + 0 + ) + end + descriptor = desc + else + local valueExists = value ~= nil + local ____desc_set_5 = desc.set + local ____desc_get_6 = desc.get + local ____temp_1 + if desc.configurable ~= nil then + ____temp_1 = desc.configurable + else + ____temp_1 = valueExists + end + local ____temp_2 + if desc.enumerable ~= nil then + ____temp_2 = desc.enumerable + else + ____temp_2 = valueExists + end + local ____temp_3 + if desc.writable ~= nil then + ____temp_3 = desc.writable + else + ____temp_3 = valueExists + end + local ____temp_4 + if desc.value ~= nil then + ____temp_4 = desc.value + else + ____temp_4 = value + end + descriptor = { + set = ____desc_set_5, + get = ____desc_get_6, + configurable = ____temp_1, + enumerable = ____temp_2, + writable = ____temp_3, + value = ____temp_4 + } + end + __TS__SetDescriptor(target, luaKey, descriptor) + return target +end + +local function __TS__ObjectEntries(obj) + local result = {} + local len = 0 + for key in pairs(obj) do + len = len + 1 + result[len] = {key, obj[key]} + end + return result +end + +local function __TS__ObjectFromEntries(entries) + local obj = {} + local iterable = entries + if iterable[Symbol.iterator] then + local iterator = iterable[Symbol.iterator](iterable) + while true do + local result = iterator:next() + if result.done then + break + end + local value = result.value + obj[value[1]] = value[2] + end + else + for ____, entry in ipairs(entries) do + obj[entry[1]] = entry[2] + end + end + return obj +end + +local function __TS__ObjectKeys(obj) + local result = {} + local len = 0 + for key in pairs(obj) do + len = len + 1 + result[len] = key + end + return result +end + +local function __TS__ObjectRest(target, usedProperties) + local result = {} + for property in pairs(target) do + if not usedProperties[property] then + result[property] = target[property] + end + end + return result +end + +local function __TS__ObjectValues(obj) + local result = {} + local len = 0 + for key in pairs(obj) do + len = len + 1 + result[len] = obj[key] + end + return result +end + +local function __TS__ParseFloat(numberString) + local infinityMatch = string.match(numberString, "^%s*(-?Infinity)") + if infinityMatch then + local ____temp_0 + if __TS__StringAccess(infinityMatch, 0) == "-" then + ____temp_0 = -math.huge + else + ____temp_0 = math.huge + end + return ____temp_0 + end + local number = tonumber(string.match(numberString, "^%s*(-?%d+%.?%d*)")) + return number or 0 / 0 +end + +local function __TS__StringSubstr(self, from, length) + if from ~= from then + from = 0 + end + if length ~= nil then + if length ~= length or length <= 0 then + return "" + end + length = length + from + end + if from >= 0 then + from = from + 1 + end + return string.sub(self, from, length) +end + +local function __TS__StringSubstring(self, start, ____end) + if ____end ~= ____end then + ____end = 0 + end + if ____end ~= nil and start > ____end then + start, ____end = ____end, start + end + if start >= 0 then + start = start + 1 + else + start = 1 + end + if ____end ~= nil and ____end < 0 then + ____end = 0 + end + return string.sub(self, start, ____end) +end + +local __TS__ParseInt +do + local parseIntBasePattern = "0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTvVwWxXyYzZ" + function __TS__ParseInt(numberString, base) + if base == nil then + base = 10 + local hexMatch = string.match(numberString, "^%s*-?0[xX]") + if hexMatch then + base = 16 + local ____string_match_result__0_0 + if string.match(hexMatch, "-") then + ____string_match_result__0_0 = "-" .. __TS__StringSubstr(numberString, #hexMatch) + else + ____string_match_result__0_0 = __TS__StringSubstr(numberString, #hexMatch) + end + numberString = ____string_match_result__0_0 + end + end + if base < 2 or base > 36 then + return 0 / 0 + end + local ____temp_1 + if base <= 10 then + ____temp_1 = __TS__StringSubstring(parseIntBasePattern, 0, base) + else + ____temp_1 = __TS__StringSubstr(parseIntBasePattern, 0, 10 + 2 * (base - 10)) + end + local allowedDigits = ____temp_1 + local pattern = ("^%s*(-?[" .. allowedDigits) .. "]*)" + local number = tonumber( + string.match(numberString, pattern), + base + ) + if number == nil then + return 0 / 0 + end + if number >= 0 then + return math.floor(number) + else + return math.ceil(number) + end + end +end + +local function __TS__PromiseAll(iterable) + local results = {} + local toResolve = {} + local numToResolve = 0 + local i = 0 + for ____, item in __TS__Iterator(iterable) do + if __TS__InstanceOf(item, __TS__Promise) then + if item.state == 1 then + results[i + 1] = item.value + elseif item.state == 2 then + return __TS__Promise.reject(item.rejectionReason) + else + numToResolve = numToResolve + 1 + toResolve[i] = item + end + else + results[i + 1] = item + end + i = i + 1 + end + if numToResolve == 0 then + return __TS__Promise.resolve(results) + end + return __TS__New( + __TS__Promise, + function(____, resolve, reject) + for index, promise in pairs(toResolve) do + promise["then"]( + promise, + function(____, data) + results[index + 1] = data + numToResolve = numToResolve - 1 + if numToResolve == 0 then + resolve(nil, results) + end + end, + function(____, reason) + reject(nil, reason) + end + ) + end + end + ) +end + +local function __TS__PromiseAllSettled(iterable) + local results = {} + local toResolve = {} + local numToResolve = 0 + local i = 0 + for ____, item in __TS__Iterator(iterable) do + if __TS__InstanceOf(item, __TS__Promise) then + if item.state == 1 then + results[i + 1] = {status = "fulfilled", value = item.value} + elseif item.state == 2 then + results[i + 1] = {status = "rejected", reason = item.rejectionReason} + else + numToResolve = numToResolve + 1 + toResolve[i] = item + end + else + results[i + 1] = {status = "fulfilled", value = item} + end + i = i + 1 + end + if numToResolve == 0 then + return __TS__Promise.resolve(results) + end + return __TS__New( + __TS__Promise, + function(____, resolve) + for index, promise in pairs(toResolve) do + promise["then"]( + promise, + function(____, data) + results[index + 1] = {status = "fulfilled", value = data} + numToResolve = numToResolve - 1 + if numToResolve == 0 then + resolve(nil, results) + end + end, + function(____, reason) + results[index + 1] = {status = "rejected", reason = reason} + numToResolve = numToResolve - 1 + if numToResolve == 0 then + resolve(nil, results) + end + end + ) + end + end + ) +end + +local function __TS__PromiseAny(iterable) + local rejections = {} + local pending = {} + for ____, item in __TS__Iterator(iterable) do + if __TS__InstanceOf(item, __TS__Promise) then + if item.state == 1 then + return __TS__Promise.resolve(item.value) + elseif item.state == 2 then + rejections[#rejections + 1] = item.rejectionReason + else + pending[#pending + 1] = item + end + else + return __TS__Promise.resolve(item) + end + end + if #pending == 0 then + return __TS__Promise.reject("No promises to resolve with .any()") + end + local numResolved = 0 + return __TS__New( + __TS__Promise, + function(____, resolve, reject) + for ____, promise in ipairs(pending) do + promise["then"]( + promise, + function(____, data) + resolve(nil, data) + end, + function(____, reason) + rejections[#rejections + 1] = reason + numResolved = numResolved + 1 + if numResolved == #pending then + reject(nil, {name = "AggregateError", message = "All Promises rejected", errors = rejections}) + end + end + ) + end + end + ) +end + +local function __TS__PromiseRace(iterable) + local pending = {} + for ____, item in __TS__Iterator(iterable) do + if __TS__InstanceOf(item, __TS__Promise) then + if item.state == 1 then + return __TS__Promise.resolve(item.value) + elseif item.state == 2 then + return __TS__Promise.reject(item.rejectionReason) + else + pending[#pending + 1] = item + end + else + return __TS__Promise.resolve(item) + end + end + return __TS__New( + __TS__Promise, + function(____, resolve, reject) + for ____, promise in ipairs(pending) do + promise["then"]( + promise, + function(____, value) return resolve(nil, value) end, + function(____, reason) return reject(nil, reason) end + ) + end + end + ) +end + +local Set +do + Set = __TS__Class() + Set.name = "Set" + function Set.prototype.____constructor(self, values) + self[Symbol.toStringTag] = "Set" + self.size = 0 + self.nextKey = {} + self.previousKey = {} + if values == nil then + return + end + local iterable = values + if iterable[Symbol.iterator] then + local iterator = iterable[Symbol.iterator](iterable) + while true do + local result = iterator:next() + if result.done then + break + end + self:add(result.value) + end + else + local array = values + for ____, value in ipairs(array) do + self:add(value) + end + end + end + function Set.prototype.add(self, value) + local isNewValue = not self:has(value) + if isNewValue then + self.size = self.size + 1 + end + if self.firstKey == nil then + self.firstKey = value + self.lastKey = value + elseif isNewValue then + self.nextKey[self.lastKey] = value + self.previousKey[value] = self.lastKey + self.lastKey = value + end + return self + end + function Set.prototype.clear(self) + self.nextKey = {} + self.previousKey = {} + self.firstKey = nil + self.lastKey = nil + self.size = 0 + end + function Set.prototype.delete(self, value) + local contains = self:has(value) + if contains then + self.size = self.size - 1 + local next = self.nextKey[value] + local previous = self.previousKey[value] + if next and previous then + self.nextKey[previous] = next + self.previousKey[next] = previous + elseif next then + self.firstKey = next + self.previousKey[next] = nil + elseif previous then + self.lastKey = previous + self.nextKey[previous] = nil + else + self.firstKey = nil + self.lastKey = nil + end + self.nextKey[value] = nil + self.previousKey[value] = nil + end + return contains + end + function Set.prototype.forEach(self, callback) + for ____, key in __TS__Iterator(self:keys()) do + callback(nil, key, key, self) + end + end + function Set.prototype.has(self, value) + return self.nextKey[value] ~= nil or self.lastKey == value + end + Set.prototype[Symbol.iterator] = function(self) + return self:values() + end + function Set.prototype.entries(self) + local nextKey = self.nextKey + local key = self.firstKey + return { + [Symbol.iterator] = function(self) + return self + end, + next = function(self) + local result = {done = not key, value = {key, key}} + key = nextKey[key] + return result + end + } + end + function Set.prototype.keys(self) + local nextKey = self.nextKey + local key = self.firstKey + return { + [Symbol.iterator] = function(self) + return self + end, + next = function(self) + local result = {done = not key, value = key} + key = nextKey[key] + return result + end + } + end + function Set.prototype.values(self) + local nextKey = self.nextKey + local key = self.firstKey + return { + [Symbol.iterator] = function(self) + return self + end, + next = function(self) + local result = {done = not key, value = key} + key = nextKey[key] + return result + end + } + end + Set[Symbol.species] = Set +end + +local function __TS__SparseArrayNew(...) + local sparseArray = {...} + sparseArray.sparseLength = select("#", ...) + return sparseArray +end + +local function __TS__SparseArrayPush(sparseArray, ...) + local args = {...} + local argsLen = select("#", ...) + local listLen = sparseArray.sparseLength + for i = 1, argsLen do + sparseArray[listLen + i] = args[i] + end + sparseArray.sparseLength = listLen + argsLen +end + +local function __TS__SparseArraySpread(sparseArray) + local _unpack = unpack or table.unpack + return _unpack(sparseArray, 1, sparseArray.sparseLength) +end + +local WeakMap +do + WeakMap = __TS__Class() + WeakMap.name = "WeakMap" + function WeakMap.prototype.____constructor(self, entries) + self[Symbol.toStringTag] = "WeakMap" + self.items = {} + setmetatable(self.items, {__mode = "k"}) + if entries == nil then + return + end + local iterable = entries + if iterable[Symbol.iterator] then + local iterator = iterable[Symbol.iterator](iterable) + while true do + local result = iterator:next() + if result.done then + break + end + local value = result.value + self.items[value[1]] = value[2] + end + else + for ____, kvp in ipairs(entries) do + self.items[kvp[1]] = kvp[2] + end + end + end + function WeakMap.prototype.delete(self, key) + local contains = self:has(key) + self.items[key] = nil + return contains + end + function WeakMap.prototype.get(self, key) + return self.items[key] + end + function WeakMap.prototype.has(self, key) + return self.items[key] ~= nil + end + function WeakMap.prototype.set(self, key, value) + self.items[key] = value + return self + end + WeakMap[Symbol.species] = WeakMap +end + +local WeakSet +do + WeakSet = __TS__Class() + WeakSet.name = "WeakSet" + function WeakSet.prototype.____constructor(self, values) + self[Symbol.toStringTag] = "WeakSet" + self.items = {} + setmetatable(self.items, {__mode = "k"}) + if values == nil then + return + end + local iterable = values + if iterable[Symbol.iterator] then + local iterator = iterable[Symbol.iterator](iterable) + while true do + local result = iterator:next() + if result.done then + break + end + self.items[result.value] = true + end + else + for ____, value in ipairs(values) do + self.items[value] = true + end + end + end + function WeakSet.prototype.add(self, value) + self.items[value] = true + return self + end + function WeakSet.prototype.delete(self, value) + local contains = self:has(value) + self.items[value] = nil + return contains + end + function WeakSet.prototype.has(self, value) + return self.items[value] == true + end + WeakSet[Symbol.species] = WeakSet +end + +local function __TS__SourceMapTraceBack(fileName, sourceMap) + _G.__TS__sourcemap = _G.__TS__sourcemap or ({}) + _G.__TS__sourcemap[fileName] = sourceMap + if _G.__TS__originalTraceback == nil then + local originalTraceback = debug.traceback + _G.__TS__originalTraceback = originalTraceback + debug.traceback = function(thread, message, level) + local trace + if thread == nil and message == nil and level == nil then + trace = originalTraceback() + else + trace = originalTraceback(thread, message, level) + end + if type(trace) ~= "string" then + return trace + end + local function replacer(____, file, srcFile, line) + local fileSourceMap = _G.__TS__sourcemap[file] + if fileSourceMap and fileSourceMap[line] then + local data = fileSourceMap[line] + if type(data) == "number" then + return (srcFile .. ":") .. tostring(data) + end + return (tostring(data.file) .. ":") .. tostring(data.line) + end + return (file .. ":") .. line + end + local result = string.gsub( + trace, + "(%S+)%.lua:(%d+)", + function(file, line) return replacer(nil, file .. ".lua", file .. ".ts", line) end + ) + local function stringReplacer(____, file, line) + local fileSourceMap = _G.__TS__sourcemap[file] + if fileSourceMap and fileSourceMap[line] then + local chunkName = string.match(file, "%[string \"([^\"]+)\"%]") + local sourceName = string.gsub(chunkName, ".lua$", ".ts") + local data = fileSourceMap[line] + if type(data) == "number" then + return (sourceName .. ":") .. tostring(data) + end + return (tostring(data.file) .. ":") .. tostring(data.line) + end + return (file .. ":") .. line + end + result = string.gsub( + result, + "(%[string \"[^\"]+\"%]):(%d+)", + function(file, line) return stringReplacer(nil, file, line) end + ) + return result + end + end +end + +local function __TS__Spread(iterable) + local arr = {} + if type(iterable) == "string" then + for i = 0, #iterable - 1 do + arr[i + 1] = __TS__StringAccess(iterable, i) + end + else + local len = 0 + for ____, item in __TS__Iterator(iterable) do + len = len + 1 + arr[len] = item + end + end + return __TS__Unpack(arr) +end + +local function __TS__StringCharAt(self, pos) + if pos ~= pos then + pos = 0 + end + if pos < 0 then + return "" + end + return string.sub(self, pos + 1, pos + 1) +end + +local function __TS__StringCharCodeAt(self, index) + if index ~= index then + index = 0 + end + if index < 0 then + return 0 / 0 + end + return string.byte(self, index + 1) or 0 / 0 +end + +local function __TS__StringEndsWith(self, searchString, endPosition) + if endPosition == nil or endPosition > #self then + endPosition = #self + end + return string.sub(self, endPosition - #searchString + 1, endPosition) == searchString +end + +local function __TS__StringIncludes(self, searchString, position) + if not position then + position = 1 + else + position = position + 1 + end + local index = string.find(self, searchString, position, true) + return index ~= nil +end + +local function __TS__StringPadEnd(self, maxLength, fillString) + if fillString == nil then + fillString = " " + end + if maxLength ~= maxLength then + maxLength = 0 + end + if maxLength == -math.huge or maxLength == math.huge then + error("Invalid string length", 0) + end + if #self >= maxLength or #fillString == 0 then + return self + end + maxLength = maxLength - #self + if maxLength > #fillString then + fillString = fillString .. string.rep( + fillString, + math.floor(maxLength / #fillString) + ) + end + return self .. string.sub( + fillString, + 1, + math.floor(maxLength) + ) +end + +local function __TS__StringPadStart(self, maxLength, fillString) + if fillString == nil then + fillString = " " + end + if maxLength ~= maxLength then + maxLength = 0 + end + if maxLength == -math.huge or maxLength == math.huge then + error("Invalid string length", 0) + end + if #self >= maxLength or #fillString == 0 then + return self + end + maxLength = maxLength - #self + if maxLength > #fillString then + fillString = fillString .. string.rep( + fillString, + math.floor(maxLength / #fillString) + ) + end + return string.sub( + fillString, + 1, + math.floor(maxLength) + ) .. self +end + +local __TS__StringReplace +do + local sub = string.sub + function __TS__StringReplace(source, searchValue, replaceValue) + local startPos, endPos = string.find(source, searchValue, nil, true) + if not startPos then + return source + end + local before = sub(source, 1, startPos - 1) + local ____temp_0 + if type(replaceValue) == "string" then + ____temp_0 = replaceValue + else + ____temp_0 = replaceValue(nil, searchValue, startPos - 1, source) + end + local replacement = ____temp_0 + local after = sub(source, endPos + 1) + return (before .. replacement) .. after + end +end + +local __TS__StringSplit +do + local sub = string.sub + local find = string.find + function __TS__StringSplit(source, separator, limit) + if limit == nil then + limit = 4294967295 + end + if limit == 0 then + return {} + end + local result = {} + local resultIndex = 1 + if separator == nil or separator == "" then + for i = 1, #source do + result[resultIndex] = sub(source, i, i) + resultIndex = resultIndex + 1 + end + else + local currentPos = 1 + while resultIndex <= limit do + local startPos, endPos = find(source, separator, currentPos, true) + if not startPos then + break + end + result[resultIndex] = sub(source, currentPos, startPos - 1) + resultIndex = resultIndex + 1 + currentPos = endPos + 1 + end + if resultIndex <= limit then + result[resultIndex] = sub(source, currentPos) + end + end + return result + end +end + +local __TS__StringReplaceAll +do + local sub = string.sub + local find = string.find + function __TS__StringReplaceAll(source, searchValue, replaceValue) + if type(replaceValue) == "string" then + local concat = table.concat( + __TS__StringSplit(source, searchValue), + replaceValue + ) + if #searchValue == 0 then + return (replaceValue .. concat) .. replaceValue + end + return concat + end + local parts = {} + local partsIndex = 1 + if #searchValue == 0 then + parts[1] = replaceValue(nil, "", 0, source) + partsIndex = 2 + for i = 1, #source do + parts[partsIndex] = sub(source, i, i) + parts[partsIndex + 1] = replaceValue(nil, "", i, source) + partsIndex = partsIndex + 2 + end + else + local currentPos = 1 + while true do + local startPos, endPos = find(source, searchValue, currentPos, true) + if not startPos then + break + end + parts[partsIndex] = sub(source, currentPos, startPos - 1) + parts[partsIndex + 1] = replaceValue(nil, searchValue, startPos - 1, source) + partsIndex = partsIndex + 2 + currentPos = endPos + 1 + end + parts[partsIndex] = sub(source, currentPos) + end + return table.concat(parts) + end +end + +local function __TS__StringSlice(self, start, ____end) + if start == nil or start ~= start then + start = 0 + end + if ____end ~= ____end then + ____end = 0 + end + if start >= 0 then + start = start + 1 + end + if ____end ~= nil and ____end < 0 then + ____end = ____end - 1 + end + return string.sub(self, start, ____end) +end + +local function __TS__StringStartsWith(self, searchString, position) + if position == nil or position < 0 then + position = 0 + end + return string.sub(self, position + 1, #searchString + position) == searchString +end + +local function __TS__StringTrim(self) + local result = string.gsub(self, "^[%s ]*(.-)[%s ]*$", "%1") + return result +end + +local function __TS__StringTrimEnd(self) + local result = string.gsub(self, "[%s ]*$", "") + return result +end + +local function __TS__StringTrimStart(self) + local result = string.gsub(self, "^[%s ]*", "") + return result +end + +local __TS__SymbolRegistryFor, __TS__SymbolRegistryKeyFor +do + local symbolRegistry = {} + function __TS__SymbolRegistryFor(key) + if not symbolRegistry[key] then + symbolRegistry[key] = __TS__Symbol(key) + end + return symbolRegistry[key] + end + function __TS__SymbolRegistryKeyFor(sym) + for key in pairs(symbolRegistry) do + if symbolRegistry[key] == sym then + return key + end + end + end +end + +local function __TS__TypeOf(value) + local luaType = type(value) + if luaType == "table" then + return "object" + elseif luaType == "nil" then + return "undefined" + else + return luaType + end +end + +return { + __TS__ArrayConcat = __TS__ArrayConcat, + __TS__ArrayEntries = __TS__ArrayEntries, + __TS__ArrayEvery = __TS__ArrayEvery, + __TS__ArrayFilter = __TS__ArrayFilter, + __TS__ArrayForEach = __TS__ArrayForEach, + __TS__ArrayFind = __TS__ArrayFind, + __TS__ArrayFindIndex = __TS__ArrayFindIndex, + __TS__ArrayFrom = __TS__ArrayFrom, + __TS__ArrayIncludes = __TS__ArrayIncludes, + __TS__ArrayIndexOf = __TS__ArrayIndexOf, + __TS__ArrayIsArray = __TS__ArrayIsArray, + __TS__ArrayJoin = __TS__ArrayJoin, + __TS__ArrayMap = __TS__ArrayMap, + __TS__ArrayPush = __TS__ArrayPush, + __TS__ArrayPushArray = __TS__ArrayPushArray, + __TS__ArrayReduce = __TS__ArrayReduce, + __TS__ArrayReduceRight = __TS__ArrayReduceRight, + __TS__ArrayReverse = __TS__ArrayReverse, + __TS__ArrayUnshift = __TS__ArrayUnshift, + __TS__ArraySort = __TS__ArraySort, + __TS__ArraySlice = __TS__ArraySlice, + __TS__ArraySome = __TS__ArraySome, + __TS__ArraySplice = __TS__ArraySplice, + __TS__ArrayToObject = __TS__ArrayToObject, + __TS__ArrayFlat = __TS__ArrayFlat, + __TS__ArrayFlatMap = __TS__ArrayFlatMap, + __TS__ArraySetLength = __TS__ArraySetLength, + __TS__AsyncAwaiter = __TS__AsyncAwaiter, + __TS__Await = __TS__Await, + __TS__Class = __TS__Class, + __TS__ClassExtends = __TS__ClassExtends, + __TS__CloneDescriptor = __TS__CloneDescriptor, + __TS__Decorate = __TS__Decorate, + __TS__DecorateParam = __TS__DecorateParam, + __TS__Delete = __TS__Delete, + __TS__DelegatedYield = __TS__DelegatedYield, + Error = Error, + RangeError = RangeError, + ReferenceError = ReferenceError, + SyntaxError = SyntaxError, + TypeError = TypeError, + URIError = URIError, + __TS__FunctionBind = __TS__FunctionBind, + __TS__Generator = __TS__Generator, + __TS__InstanceOf = __TS__InstanceOf, + __TS__InstanceOfObject = __TS__InstanceOfObject, + __TS__Iterator = __TS__Iterator, + Map = Map, + __TS__MathAtan2 = __TS__MathAtan2, + __TS__MathSign = __TS__MathSign, + __TS__New = __TS__New, + __TS__Number = __TS__Number, + __TS__NumberIsFinite = __TS__NumberIsFinite, + __TS__NumberIsNaN = __TS__NumberIsNaN, + __TS__NumberToString = __TS__NumberToString, + __TS__ObjectAssign = __TS__ObjectAssign, + __TS__ObjectDefineProperty = __TS__ObjectDefineProperty, + __TS__ObjectEntries = __TS__ObjectEntries, + __TS__ObjectFromEntries = __TS__ObjectFromEntries, + __TS__ObjectGetOwnPropertyDescriptor = __TS__ObjectGetOwnPropertyDescriptor, + __TS__ObjectGetOwnPropertyDescriptors = __TS__ObjectGetOwnPropertyDescriptors, + __TS__ObjectKeys = __TS__ObjectKeys, + __TS__ObjectRest = __TS__ObjectRest, + __TS__ObjectValues = __TS__ObjectValues, + __TS__ParseFloat = __TS__ParseFloat, + __TS__ParseInt = __TS__ParseInt, + __TS__Promise = __TS__Promise, + __TS__PromiseAll = __TS__PromiseAll, + __TS__PromiseAllSettled = __TS__PromiseAllSettled, + __TS__PromiseAny = __TS__PromiseAny, + __TS__PromiseRace = __TS__PromiseRace, + Set = Set, + __TS__SetDescriptor = __TS__SetDescriptor, + __TS__SparseArrayNew = __TS__SparseArrayNew, + __TS__SparseArrayPush = __TS__SparseArrayPush, + __TS__SparseArraySpread = __TS__SparseArraySpread, + WeakMap = WeakMap, + WeakSet = WeakSet, + __TS__SourceMapTraceBack = __TS__SourceMapTraceBack, + __TS__Spread = __TS__Spread, + __TS__StringAccess = __TS__StringAccess, + __TS__StringCharAt = __TS__StringCharAt, + __TS__StringCharCodeAt = __TS__StringCharCodeAt, + __TS__StringEndsWith = __TS__StringEndsWith, + __TS__StringIncludes = __TS__StringIncludes, + __TS__StringPadEnd = __TS__StringPadEnd, + __TS__StringPadStart = __TS__StringPadStart, + __TS__StringReplace = __TS__StringReplace, + __TS__StringReplaceAll = __TS__StringReplaceAll, + __TS__StringSlice = __TS__StringSlice, + __TS__StringSplit = __TS__StringSplit, + __TS__StringStartsWith = __TS__StringStartsWith, + __TS__StringSubstr = __TS__StringSubstr, + __TS__StringSubstring = __TS__StringSubstring, + __TS__StringTrim = __TS__StringTrim, + __TS__StringTrimEnd = __TS__StringTrimEnd, + __TS__StringTrimStart = __TS__StringTrimStart, + __TS__Symbol = __TS__Symbol, + Symbol = Symbol, + __TS__SymbolRegistryFor = __TS__SymbolRegistryFor, + __TS__SymbolRegistryKeyFor = __TS__SymbolRegistryKeyFor, + __TS__TypeOf = __TS__TypeOf, + __TS__Unpack = __TS__Unpack +} diff --git a/modules/events-mod/src/main/lua/main/PacketEmitter.lua b/modules/events-mod/src/main/lua/main/PacketEmitter.lua new file mode 100644 index 0000000..1ff529d --- /dev/null +++ b/modules/events-mod/src/main/lua/main/PacketEmitter.lua @@ -0,0 +1,22 @@ +local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local __TS__New = ____lualib.__TS__New +local ____exports = {} +____exports.KafkatorioPacketEmitter = __TS__Class() +local KafkatorioPacketEmitter = ____exports.KafkatorioPacketEmitter +KafkatorioPacketEmitter.name = "KafkatorioPacketEmitter" +function KafkatorioPacketEmitter.prototype.____constructor(self) +end +function KafkatorioPacketEmitter.prototype.emitInstantPacket(self, data) + ____exports.KafkatorioPacketEmitter:emitPacket({data = data, modVersion = global.MOD_VERSION, tick = game.tick}) +end +function KafkatorioPacketEmitter.prototype.emitKeyedPacket(self, data) + ____exports.KafkatorioPacketEmitter:emitPacket({data = data, modVersion = global.MOD_VERSION, tick = game.tick}) +end +function KafkatorioPacketEmitter.emitPacket(self, packet) + local data = game.table_to_json(packet) + localised_print("KafkatorioPacket: " .. data) +end +local PacketEmitter = __TS__New(____exports.KafkatorioPacketEmitter) +____exports.default = PacketEmitter +return ____exports diff --git a/modules/events-mod/src/main/lua/main/cache/EventDataCache.lua b/modules/events-mod/src/main/lua/main/cache/EventDataCache.lua new file mode 100644 index 0000000..71b961b --- /dev/null +++ b/modules/events-mod/src/main/lua/main/cache/EventDataCache.lua @@ -0,0 +1,145 @@ +local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local __TS__New = ____lualib.__TS__New +local ____exports = {} +local ____KafkatorioSettings = require("main.settings.KafkatorioSettings") +local KafkatorioSettings = ____KafkatorioSettings.default +local ____PacketEmitter = require("main.PacketEmitter") +local packetEmitter = ____PacketEmitter.default +____exports.EventUpdates = {} +local EventUpdates = ____exports.EventUpdates +do + local CacheEntry + EventUpdates.Manager = __TS__Class() + local Manager = EventUpdates.Manager + Manager.name = "Manager" + function Manager.prototype.____constructor(self) + end + function Manager.prototype.init(self, force) + local isAnythingUndefined = global.cache == nil + log(((("Initialising EventDataCache (force=" .. tostring(force)) .. ", isAnythingUndefined=") .. tostring(isAnythingUndefined)) .. ")...") + if force == true or isAnythingUndefined then + log("Initialising global.cache") + global.cache = {} + end + log("Finished initialising EventDataCache") + end + function Manager.prototype.throttle(self, key, ____type, mutate, expirationDurationTicks) + self:update( + key, + ____type, + mutate, + false, + expirationDurationTicks + ) + end + function Manager.prototype.debounce(self, key, ____type, mutate, expirationDurationTicks) + self:update( + key, + ____type, + mutate, + true, + expirationDurationTicks + ) + end + function Manager.prototype.update(self, key, ____type, mutate, resetLastUpdated, expirationDurationTicks) + local entry = self:getCacheEntry(key, ____type) or EventUpdates.Manager:createCacheEntry(key, ____type) + mutate(entry.packet) + if resetLastUpdated then + entry.lastUpdatedTick = game.tick + end + if expirationDurationTicks ~= nil then + entry.expirationDurationTicks = expirationDurationTicks + end + if entry.expirationDurationTicks ~= nil and entry.expirationDurationTicks <= 0 then + self:extractAndEmitExpiredPackets() + end + end + function Manager.prototype.setExpiration(self, key, ____type, expirationDurationTicks) + local entry = self:getCacheEntry(key, ____type) + if entry ~= nil then + entry.expirationDurationTicks = expirationDurationTicks + end + end + function Manager.prototype.extractExpired(self) + local countExpired = 0 + local countTotal = 0 + local expiredData = {} + for key, entry in pairs(global.cache) do + countTotal = countTotal + 1 + if self:isExpired(entry) then + countExpired = countExpired + 1 + expiredData[#expiredData + 1] = entry.packet + global.cache[key] = nil + end + end + local hasExpiredItems = countExpired > 0 + local hasAnyItem = countTotal > 0 + if hasExpiredItems or game.tick % 30 == 0 and hasAnyItem then + log((("[extractExpired] expired items: " .. tostring(countExpired)) .. ", total: ") .. tostring(countTotal)) + end + return expiredData + end + function Manager.prototype.extractAndEmitExpiredPackets(self) + local cachedEvents = self:extractExpired() + if #cachedEvents > 0 then + log((("[EventDataCache] emitting " .. tostring(#cachedEvents)) .. " events on tick ") .. tostring(game.tick)) + for ____, event in ipairs(cachedEvents) do + packetEmitter:emitKeyedPacket(event) + end + end + return #cachedEvents + end + function Manager.prototype.getCacheEntry(self, key, ____type) + local hash = EventUpdates.Manager:hashKey(key) + if not (global.cache[hash] ~= nil) then + return nil + end + local value = global.cache[hash] + if self:isEntryInstanceOf(value, ____type) then + return value + else + return nil + end + end + function Manager.createCacheEntry(self, key, ____type) + local data = {type = ____type, key = key} + local entry = __TS__New(CacheEntry, data) + local hash = EventUpdates.Manager:hashKey(key) + global.cache[hash] = entry + return entry + end + function Manager.prototype.isExpired(self, entry) + local expiryDuration = entry.expirationDurationTicks or KafkatorioSettings:getEventCacheExpirationTicks(entry.packet) + if expiryDuration == nil then + return true + else + return game.tick - entry.lastUpdatedTick > expiryDuration + end + end + function Manager.prototype.isEntryInstanceOf(self, entry, ____type) + local ____self_2 = self + local ____self_isDataInstanceOf_3 = self.isDataInstanceOf + local ____entry_packet_0 = entry + if ____entry_packet_0 ~= nil then + ____entry_packet_0 = ____entry_packet_0.packet + end + return ____self_isDataInstanceOf_3(____self_2, ____entry_packet_0, ____type) + end + function Manager.prototype.isDataInstanceOf(self, packet, ____type) + return packet ~= nil and packet.type == ____type + end + function Manager.hashKey(self, key) + return game.encode_string(game.table_to_json(key)) + end + CacheEntry = __TS__Class() + CacheEntry.name = "CacheEntry" + function CacheEntry.prototype.____constructor(self, packet, expirationDurationTicks) + self.lastUpdatedTick = game.tick + self.packet = packet + self.expirationDurationTicks = expirationDurationTicks + end +end +local EventUpdatesManager = __TS__New(____exports.EventUpdates.Manager) +____exports.default = EventUpdatesManager +return ____exports diff --git a/modules/events-mod/src/main/lua/main/commands/kafkatorioCommands.lua b/modules/events-mod/src/main/lua/main/commands/kafkatorioCommands.lua new file mode 100644 index 0000000..e9939d2 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/commands/kafkatorioCommands.lua @@ -0,0 +1,76 @@ +local ____lualib = require("lualib_bundle") +local __TS__StringStartsWith = ____lualib.__TS__StringStartsWith +local __TS__StringSplit = ____lualib.__TS__StringSplit +local __TS__ParseInt = ____lualib.__TS__ParseInt +local ____exports = {} +local ____global_2Dinit = require("main.global-init") +local initGlobal = ____global_2Dinit.initGlobal +local ____queue = require("main.queue.queue") +local Queue = ____queue.Queue +local ____prototypeUpdates = require("main.events.prototypeUpdates") +local emitPrototypes = ____prototypeUpdates.emitPrototypes +commands.add_command( + "kafkatorio", + "kafkatorio innit bruv", + function(e) + local ____temp_0 + if e.player_index ~= nil then + ____temp_0 = game.get_player(e.player_index) + else + ____temp_0 = nil + end + local player = ____temp_0 + if e.parameter == nil then + if player ~= nil then + player.print("no parameter") + end + else + local paramUppercase = string.upper(e.parameter) + if "PROTOTYPES" == paramUppercase then + emitPrototypes() + elseif __TS__StringStartsWith(paramUppercase, "CHUNKS") then + local ____paramUppercase_split_result__1_1 = __TS__StringSplit(paramUppercase, " ") + if ____paramUppercase_split_result__1_1 ~= nil then + ____paramUppercase_split_result__1_1 = ____paramUppercase_split_result__1_1[2] + end + local size = ____paramUppercase_split_result__1_1 or nil + local radius = size ~= nil and __TS__ParseInt(size) or 1 + if e.player_index ~= nil then + local player = game.players[e.player_index] + local chunkPosition = { + x = math.floor(player.position.x / 32), + y = math.floor(player.position.y / 32) + } + local chunkXMin = chunkPosition.x - radius + local chunkXMax = chunkPosition.x + radius + local chunkYMin = chunkPosition.y - radius + local chunkYMax = chunkPosition.y + radius + local chunkCount = 0 + for ____, surface in pairs(game.surfaces) do + for chunk in surface.get_chunks() do + if chunk.x >= chunkXMin and chunk.x <= chunkXMax and (chunk.y >= chunkYMin and chunk.y <= chunkYMax) then + local data = { + name = defines.events.on_chunk_generated, + position = {x = chunk.x, y = chunk.y}, + area = chunk.area, + surface = surface, + tick = e.tick + } + Queue.enqueue( + (tostring(surface.index) .. tostring(chunk.x)) .. tostring(chunk.y), + data, + 50 + ) + chunkCount = chunkCount + 1 + end + end + end + player.print(((((((((("enqueued " .. tostring(chunkCount)) .. " chunks from [x:") .. tostring(chunkXMin)) .. ", y:") .. tostring(chunkYMin)) .. "] to [x:") .. tostring(chunkXMax)) .. ", y:") .. tostring(chunkYMax)) .. "]") + end + elseif __TS__StringStartsWith(paramUppercase, "INIT_GLOBAL") then + initGlobal(__TS__StringStartsWith(paramUppercase, "INIT_GLOBAL FORCE")) + end + end + end +) +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/configurationUpdate.lua b/modules/events-mod/src/main/lua/main/events/configurationUpdate.lua new file mode 100644 index 0000000..e548e73 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/configurationUpdate.lua @@ -0,0 +1,65 @@ +local ____lualib = require("lualib_bundle") +local __TS__ObjectKeys = ____lualib.__TS__ObjectKeys +local __TS__ArrayConcat = ____lualib.__TS__ArrayConcat +local Set = ____lualib.Set +local __TS__New = ____lualib.__TS__New +local __TS__Spread = ____lualib.__TS__Spread +local __TS__ArrayMap = ____lualib.__TS__ArrayMap +local ____exports = {} +local emitConfigurationUpdate, factorioData, allMods, Type +local ____PacketEmitter = require("main.PacketEmitter") +local PacketEmitter = ____PacketEmitter.default +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +local ____global_2Dinit = require("main.global-init") +local initGlobal = ____global_2Dinit.initGlobal +local ____prototypeUpdates = require("main.events.prototypeUpdates") +local emitPrototypes = ____prototypeUpdates.emitPrototypes +function emitConfigurationUpdate(changeData) + local configUpdateData = { + type = Type.ConfigurationUpdate, + migrationApplied = changeData.migration_applied, + modStartupSettingsChange = changeData.mod_startup_settings_changed, + allMods = allMods(changeData), + factorioData = factorioData(changeData) + } + PacketEmitter:emitInstantPacket(configUpdateData) +end +function factorioData(changeData) + return {oldVersion = changeData.old_version or nil, newVersion = changeData.new_version or nil} +end +function allMods(e) + local namesOfChangedMods = __TS__ObjectKeys(e.mod_changes) + local namesOfCurrentMods = __TS__ObjectKeys(script.active_mods) + local modNames = {__TS__Spread(__TS__New( + Set, + __TS__ArrayConcat(namesOfChangedMods, namesOfCurrentMods) + ))} + return __TS__ArrayMap( + modNames, + function(modName) + local ____script_active_mods_modName_2 = script.active_mods[modName] + if ____script_active_mods_modName_2 == nil then + local ____e_mod_changes_modName_new_version_0 = e.mod_changes[modName] + if ____e_mod_changes_modName_new_version_0 ~= nil then + ____e_mod_changes_modName_new_version_0 = ____e_mod_changes_modName_new_version_0.new_version + end + ____script_active_mods_modName_2 = ____e_mod_changes_modName_new_version_0 + end + local currentVer = ____script_active_mods_modName_2 or nil + local ____e_mod_changes_modName_old_version_3 = e.mod_changes[modName] + if ____e_mod_changes_modName_old_version_3 ~= nil then + ____e_mod_changes_modName_old_version_3 = ____e_mod_changes_modName_old_version_3.old_version + end + local previousVer = ____e_mod_changes_modName_old_version_3 or nil + return {modName = modName, currentVersion = currentVer, previousVersion = previousVer} + end + ) +end +Type = KafkatorioPacketData.Type +script.on_configuration_changed(function(data) + initGlobal(true) + emitConfigurationUpdate(data) + emitPrototypes() +end) +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/consoleUpdates.lua b/modules/events-mod/src/main/lua/main/events/consoleUpdates.lua new file mode 100644 index 0000000..daf3956 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/consoleUpdates.lua @@ -0,0 +1,21 @@ +local ____exports = {} +local ____PacketEmitter = require("main.PacketEmitter") +local PacketEmitter = ____PacketEmitter.default +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +local Type = KafkatorioPacketData.Type +script.on_event( + defines.events.on_console_chat, + function(event) + local update = {type = Type.ConsoleChatUpdate, authorPlayerIndex = event.player_index or nil, content = event.message} + PacketEmitter:emitInstantPacket(update) + end +) +script.on_event( + defines.events.on_console_command, + function(event) + local update = {type = Type.ConsoleCommandUpdate, authorPlayerIndex = event.player_index or nil, command = event.command, parameters = event.parameters} + PacketEmitter:emitInstantPacket(update) + end +) +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/converters.lua b/modules/events-mod/src/main/lua/main/events/converters.lua new file mode 100644 index 0000000..4dcc755 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/converters.lua @@ -0,0 +1,40 @@ +local ____exports = {} +____exports.Converters = {} +local Converters = ____exports.Converters +do + local mapEventIdToName = {} + for eventName, eventId in pairs(defines.events) do + mapEventIdToName[eventId] = eventName + end + function Converters.eventNameString(event) + return mapEventIdToName[event] + end + function Converters.mapColour(color) + return {color.r or 0, color.g or 0, color.b or 0, color.a or 0} + end + function Converters.convertPlacedTiles(placedTile, oldTiles) + local converted = {} + for ____, tile in ipairs(oldTiles) do + converted[#converted + 1] = {position = {x = tile.position.x, y = tile.position.y}, name = placedTile.name} + end + return converted + end + function Converters.convertRemovedTiles(surface, oldTiles) + local converted = {} + for ____, tile in ipairs(oldTiles) do + converted[#converted + 1] = surface.get_tile(tile.position.x, tile.position.y) + end + return converted + end + function Converters.convertMapTablePosition(position) + return {position.x, position.y} + end + function Converters.convertCollisionMaskToNames(cm) + local masks = {} + for name in pairs(cm) do + masks[#masks + 1] = name + end + return masks + end +end +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/entityUpdates.lua b/modules/events-mod/src/main/lua/main/events/entityUpdates.lua new file mode 100644 index 0000000..c5fd3ee --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/entityUpdates.lua @@ -0,0 +1,105 @@ +local ____exports = {} +local handleBuiltEntityEvent, handleMinedEntityEvent +local ____converters = require("main.events.converters") +local Converters = ____converters.Converters +local ____EventDataCache = require("main.cache.EventDataCache") +local EventDataCache = ____EventDataCache.default +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +function handleBuiltEntityEvent(event) + local eventName = Converters.eventNameString(event.name) + if event.created_entity.unit_number == nil then + return + end + local key = {name = event.created_entity.name, protoType = event.created_entity.prototype.name, unitNumber = event.created_entity.unit_number} + EventDataCache:debounce( + key, + KafkatorioPacketData.Type.EntityUpdate, + function(data) + if data.events == nil then + data.events = {} + end + local ____data_events_0, ____eventName_1 = data.events, eventName + if ____data_events_0[____eventName_1] == nil then + ____data_events_0[____eventName_1] = {} + end + local ____data_events_eventName_2 = data.events[eventName] + ____data_events_eventName_2[#____data_events_eventName_2 + 1] = event.tick + data.chunkPosition = Converters.convertMapTablePosition(event.created_entity.position) + data.graphicsVariation = event.created_entity.graphics_variation + data.health = event.created_entity.health + data.isActive = event.created_entity.active + data.isRotatable = event.created_entity.rotatable + local ____data_5 = data + local ____event_created_entity_last_user_index_3 = event.created_entity.last_user + if ____event_created_entity_last_user_index_3 ~= nil then + ____event_created_entity_last_user_index_3 = ____event_created_entity_last_user_index_3.index + end + ____data_5.lastUser = ____event_created_entity_last_user_index_3 + data.prototype = event.created_entity.prototype.name + end + ) +end +function handleMinedEntityEvent(event) + local eventName = Converters.eventNameString(event.name) + if event.entity.unit_number == nil then + return + end + local key = {name = event.entity.name, protoType = event.entity.prototype.name, unitNumber = event.entity.unit_number} + EventDataCache:debounce( + key, + KafkatorioPacketData.Type.EntityUpdate, + function(data) + if data.events == nil then + data.events = {} + end + local ____data_events_6, ____eventName_7 = data.events, eventName + if ____data_events_6[____eventName_7] == nil then + ____data_events_6[____eventName_7] = {} + end + local ____data_events_eventName_8 = data.events[eventName] + ____data_events_eventName_8[#____data_events_eventName_8 + 1] = event.tick + data.chunkPosition = Converters.convertMapTablePosition(event.entity.position) + data.graphicsVariation = event.entity.graphics_variation + data.health = event.entity.health + data.isActive = event.entity.active + data.isRotatable = event.entity.rotatable + local ____data_11 = data + local ____event_entity_last_user_index_9 = event.entity.last_user + if ____event_entity_last_user_index_9 ~= nil then + ____event_entity_last_user_index_9 = ____event_entity_last_user_index_9.index + end + ____data_11.lastUser = ____event_entity_last_user_index_9 + data.prototype = event.entity.prototype.name + end + ) +end +script.on_event( + defines.events.on_built_entity, + function(e) + log("on_built_entity " .. tostring(e.tick)) + handleBuiltEntityEvent(e) + end +) +script.on_event( + defines.events.on_robot_built_entity, + function(e) + log("on_robot_built_entity " .. tostring(e.tick)) + handleBuiltEntityEvent(e) + end +) +script.on_event( + defines.events.on_player_mined_entity, + function(e) + log("on_player_mined_entity " .. tostring(e.tick)) + handleMinedEntityEvent(e) + end +) +script.on_event( + defines.events.on_robot_mined_entity, + function(e) + log("on_robot_mined_entity " .. tostring(e.tick)) + handleMinedEntityEvent(e) + end +) +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/eventTypeCheck.lua b/modules/events-mod/src/main/lua/main/events/eventTypeCheck.lua new file mode 100644 index 0000000..d9cb883 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/eventTypeCheck.lua @@ -0,0 +1,6 @@ +local ____exports = {} +function ____exports.isEventType(eventData, ____type) + local id = eventData.name + return id == ____type +end +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/mapChunkUpdates.lua b/modules/events-mod/src/main/lua/main/events/mapChunkUpdates.lua new file mode 100644 index 0000000..7c24f25 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/mapChunkUpdates.lua @@ -0,0 +1,248 @@ +local ____lualib = require("lualib_bundle") +local Map = ____lualib.Map +local __TS__Iterator = ____lualib.__TS__Iterator +local __TS__New = ____lualib.__TS__New +local ____exports = {} +local mapTilesUpdateDebounce, getTiles, getSurface, groupTiles, handleBuiltTileEvent, handleMinedTileEvent, Type +local ____eventTypeCheck = require("main.events.eventTypeCheck") +local isEventType = ____eventTypeCheck.isEventType +local ____converters = require("main.events.converters") +local Converters = ____converters.Converters +local ____EventDataCache = require("main.cache.EventDataCache") +local EventUpdatesManager = ____EventDataCache.default +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +function mapTilesUpdateDebounce(surface, chunkPosition, tiles, event, updater, expirationDurationTicks) + if surface == nil then + return + end + local eventName = Converters.eventNameString(event.name) + local key = {surfaceIndex = surface.index, chunkPosition = chunkPosition} + EventUpdatesManager:debounce( + key, + Type.MapChunkUpdate, + function(data) + if data.tileDictionary == nil then + data.tileDictionary = {tilesXY = {}, protos = {}} + end + local protosCount = table_size(data.tileDictionary.protos) + for ____, tile in ipairs(tiles) do + local ____data_tileDictionary_protos_1, ____tile_name_2 = data.tileDictionary.protos, tile.name + if ____data_tileDictionary_protos_1[____tile_name_2] == nil then + local ____protosCount_0 = protosCount + protosCount = ____protosCount_0 + 1 + ____data_tileDictionary_protos_1[____tile_name_2] = ____protosCount_0 + end + local protoKey = data.tileDictionary.protos[tile.name] + local xString = tostring(tile.position.x) + local yString = tostring(tile.position.y) + local ____data_tileDictionary_tilesXY_3, ____xString_4 = data.tileDictionary.tilesXY, xString + if ____data_tileDictionary_tilesXY_3[____xString_4] == nil then + ____data_tileDictionary_tilesXY_3[____xString_4] = {} + end + data.tileDictionary.tilesXY[xString][yString] = protoKey + end + if data.events == nil then + data.events = {} + end + local ____data_events_5, ____eventName_6 = data.events, eventName + if ____data_events_5[____eventName_6] == nil then + ____data_events_5[____eventName_6] = {} + end + local ____data_events_eventName_7 = data.events[eventName] + ____data_events_eventName_7[#____data_events_eventName_7 + 1] = event.tick + if updater ~= nil then + updater(data) + end + end, + expirationDurationTicks + ) +end +function getTiles(surface, area) + local ____surface_find_tiles_filtered_result_8 = surface + if ____surface_find_tiles_filtered_result_8 ~= nil then + ____surface_find_tiles_filtered_result_8 = ____surface_find_tiles_filtered_result_8.find_tiles_filtered({area = area}) + end + return ____surface_find_tiles_filtered_result_8 or ({}) +end +function getSurface(surfaceIndex) + return game.surfaces[surfaceIndex] +end +function ____exports.handleChunkGeneratedEvent(event, expirationDurationTicks) + local tiles = getTiles(event.surface, event.area) + mapTilesUpdateDebounce( + event.surface, + Converters.convertMapTablePosition(event.position), + tiles, + event, + nil, + expirationDurationTicks + ) +end +function groupTiles(tiles) + local mapChunkPositionToTiles = __TS__New(Map) + for ____, tile in ipairs(tiles) do + local chunkPosition = { + math.floor(tile.position.x / 32), + math.floor(tile.position.y / 32) + } + if not mapChunkPositionToTiles:has(chunkPosition) then + mapChunkPositionToTiles:set(chunkPosition, {}) + end + local ____mapChunkPositionToTiles_get_result_push_result_10 = mapChunkPositionToTiles:get(chunkPosition) + if ____mapChunkPositionToTiles_get_result_push_result_10 ~= nil then + local ____temp_11 = mapChunkPositionToTiles:get(chunkPosition) + ____temp_11[#____temp_11 + 1] = tile + ____mapChunkPositionToTiles_get_result_push_result_10 = nil + end + end + return mapChunkPositionToTiles +end +function handleBuiltTileEvent(event) + local surface = getSurface(event.surface_index) + if surface == nil then + local eventName = Converters.eventNameString(event.name) + log("[handleBuiltTileEvent] undefined surface " .. eventName) + return + end + local tiles = Converters.convertPlacedTiles(event.tile, event.tiles) + local groupedTiles = groupTiles(tiles) + for ____, ____value in __TS__Iterator(groupedTiles) do + local chunkPos = ____value[1] + local tiles = ____value[2] + mapTilesUpdateDebounce( + surface, + chunkPos, + tiles, + event, + function(data) + if isEventType(event, defines.events.on_player_built_tile) then + data.player = event.player_index + return + end + if isEventType(event, defines.events.on_robot_built_tile) then + local ____data_15 = data + local ____event_robot_unit_number_13 = event.robot + if ____event_robot_unit_number_13 ~= nil then + ____event_robot_unit_number_13 = ____event_robot_unit_number_13.unit_number + end + ____data_15.robot = {unitNumber = ____event_robot_unit_number_13 or nil, name = event.robot.name, protoType = event.robot.type} + return + end + local exhaustiveCheck = event + end + ) + end +end +function handleMinedTileEvent(event) + local surface = getSurface(event.surface_index) + if surface == nil then + local eventName = Converters.eventNameString(event.name) + log("[handleMinedTileEvent] undefined surface " .. eventName) + return + end + local tiles = Converters.convertRemovedTiles(surface, event.tiles) + local groupedTiles = groupTiles(tiles) + for ____, ____value in __TS__Iterator(groupedTiles) do + local chunkPos = ____value[1] + local tiles = ____value[2] + mapTilesUpdateDebounce( + surface, + chunkPos, + tiles, + event, + function(data) + if isEventType(event, defines.events.on_player_mined_tile) then + data.player = event.player_index + return + end + if isEventType(event, defines.events.on_robot_mined_tile) then + local ____data_18 = data + local ____event_robot_unit_number_16 = event.robot + if ____event_robot_unit_number_16 ~= nil then + ____event_robot_unit_number_16 = ____event_robot_unit_number_16.unit_number + end + ____data_18.robot = {unitNumber = ____event_robot_unit_number_16 or nil, name = event.robot.name, protoType = event.robot.type} + return + end + local exhaustiveCheck = event + end + ) + end +end +Type = KafkatorioPacketData.Type +script.on_event( + defines.events.on_chunk_generated, + function(e) + log("on_chunk_generated " .. tostring(e.tick)) + ____exports.handleChunkGeneratedEvent(e) + end +) +script.on_event( + defines.events.script_raised_set_tiles, + function(event) + log("script_raised_set_tiles " .. tostring(event.tick)) + local surface = getSurface(event.surface_index) + if surface == nil then + return + end + local groupedTiles = groupTiles(event.tiles) + for ____, ____value in __TS__Iterator(groupedTiles) do + local chunkPos = ____value[1] + local tiles = ____value[2] + mapTilesUpdateDebounce(surface, chunkPos, tiles, event) + end + end +) +script.on_event( + defines.events.on_player_built_tile, + function(e) + log("on_player_built_tile " .. tostring(e.tick)) + handleBuiltTileEvent(e) + end +) +script.on_event( + defines.events.on_robot_built_tile, + function(e) + log("on_robot_built_tile " .. tostring(e.tick)) + handleBuiltTileEvent(e) + end +) +script.on_event( + defines.events.on_player_mined_tile, + function(e) + log("on_player_mined_tile " .. tostring(e.tick)) + handleMinedTileEvent(e) + end +) +script.on_event( + defines.events.on_robot_mined_tile, + function(e) + log("on_robot_mined_tile " .. tostring(e.tick)) + handleMinedTileEvent(e) + end +) +script.on_event( + defines.events.on_pre_chunk_deleted, + function(e) + log("on_pre_chunk_deleted " .. tostring(e.tick)) + local surface = getSurface(e.surface_index) + if surface == nil then + return + end + for ____, position in ipairs(e.positions) do + local key = {surfaceIndex = surface.index, chunkPosition = {position.x, position.y}} + EventUpdatesManager:debounce( + key, + Type.MapChunkUpdate, + function(data) + local ____temp_19 = true + data.isDeleted = ____temp_19 + return ____temp_19 + end, + 0 + ) + end + end +) +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/playerUpdates.lua b/modules/events-mod/src/main/lua/main/events/playerUpdates.lua new file mode 100644 index 0000000..3cfa307 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/playerUpdates.lua @@ -0,0 +1,165 @@ +local ____exports = {} +local playerUpdateThrottle, playerOnlineInfo, handleBannedEvent, Type +local ____converters = require("main.events.converters") +local Converters = ____converters.Converters +local ____EventDataCache = require("main.cache.EventDataCache") +local EventUpdatesManager = ____EventDataCache.default +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +local ____PacketEmitter = require("main.PacketEmitter") +local packetEmitter = ____PacketEmitter.default +function playerUpdateThrottle(event, mutate, expirationDurationTicks) + if expirationDurationTicks == nil then + expirationDurationTicks = nil + end + local playerIndex = event.player_index + if playerIndex == nil then + return + end + local eventName = Converters.eventNameString(event.name) + EventUpdatesManager:throttle( + {index = playerIndex}, + Type.PlayerUpdate, + function(data) + local player = game.players[playerIndex] + if player ~= nil then + mutate(player, data) + end + if data.events == nil then + data.events = {} + end + local ____data_events_0, ____eventName_1 = data.events, eventName + if ____data_events_0[____eventName_1] == nil then + ____data_events_0[____eventName_1] = {} + end + local ____data_events_eventName_2 = data.events[eventName] + ____data_events_eventName_2[#____data_events_eventName_2 + 1] = event.tick + end, + expirationDurationTicks + ) +end +function playerOnlineInfo(player, data) + data.lastOnline = player.last_online + data.onlineTime = player.online_time + data.afkTime = player.afk_time + data.isConnected = player.connected +end +function handleBannedEvent(event) + playerUpdateThrottle( + event, + function(player, data) + data.bannedReason = event.reason or nil + playerOnlineInfo(player, data) + end + ) +end +Type = KafkatorioPacketData.Type +local function playerUpdateImmediate(event, mutate) + playerUpdateThrottle(event, mutate, 0) +end +script.on_event( + defines.events.on_player_joined_game, + function(e) + playerUpdateThrottle( + e, + function(player, data) + data.isAdmin = player.admin + local ____data_5 = data + local ____player_character_unit_number_3 = player.character + if ____player_character_unit_number_3 ~= nil then + ____player_character_unit_number_3 = ____player_character_unit_number_3.unit_number + end + ____data_5.characterUnitNumber = ____player_character_unit_number_3 or nil + data.chatColour = Converters.mapColour(player.chat_color) + data.colour = Converters.mapColour(player.color) + data.forceIndex = player.force.index + data.name = player.name + data.isShowOnMap = player.show_on_map + data.isSpectator = player.spectator + data.surfaceIndex = player.surface.index + data.tag = player.tag + playerOnlineInfo(player, data) + end + ) + end +) +script.on_event( + defines.events.on_player_changed_position, + function(e) + playerUpdateThrottle( + e, + function(player, data) + data.position = {player.position.x, player.position.y} + end + ) + end +) +script.on_event( + defines.events.on_player_changed_surface, + function(e) + playerUpdateThrottle( + e, + function(player, data) + data.position = {player.position.x, player.position.y} + data.surfaceIndex = player.surface.index + end + ) + end +) +script.on_event( + defines.events.on_player_died, + function(e) + playerUpdateThrottle( + e, + function(player, data) + data.ticksToRespawn = player.ticks_to_respawn or nil + playerOnlineInfo(player, data) + if e.cause ~= nil then + data.diedCause = {unitNumber = e.cause.unit_number or nil, name = e.cause.name, protoType = e.cause.type} + end + end + ) + end +) +script.on_event(defines.events.on_player_banned, handleBannedEvent) +script.on_event(defines.events.on_player_unbanned, handleBannedEvent) +script.on_event( + defines.events.on_player_kicked, + function(event) + log((("on_player_kicked " .. tostring(event.tick)) .. " ") .. tostring(event.name)) + playerUpdateImmediate( + event, + function(player, data) + data.kickedReason = event.reason or nil + playerOnlineInfo(player, data) + end + ) + end +) +local disconnectReasons = {} +for name, disconnectId in pairs(defines.disconnect_reason) do + disconnectReasons[disconnectId] = name +end +script.on_event( + defines.events.on_pre_player_left_game, + function(event) + log((("on_pre_player_left_game " .. tostring(event.tick)) .. " ") .. tostring(event.name)) + local playerUpdateKey = {index = event.player_index} + local playerUpdate = {type = KafkatorioPacketData.Type.PlayerUpdate, key = playerUpdateKey, disconnectReason = disconnectReasons[event.reason]} + packetEmitter:emitKeyedPacket(playerUpdate) + end +) +script.on_event( + defines.events.on_player_removed, + function(event) + log((("on_player_removed " .. tostring(event.tick)) .. " ") .. tostring(event.name)) + playerUpdateImmediate( + event, + function(player, data) + data.isRemoved = true + playerOnlineInfo(player, data) + end + ) + end +) +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/prototypeUpdates.lua b/modules/events-mod/src/main/lua/main/events/prototypeUpdates.lua new file mode 100644 index 0000000..1daa787 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/prototypeUpdates.lua @@ -0,0 +1,42 @@ +local ____lualib = require("lualib_bundle") +local __TS__ArrayPushArray = ____lualib.__TS__ArrayPushArray +local ____exports = {} +local prototypeUpdates, getMapTilePrototypes +local ____PacketEmitter = require("main.PacketEmitter") +local PacketEmitter = ____PacketEmitter.default +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local FactorioPrototype = ____kafkatorio_2Dschema.FactorioPrototype +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +local ____converters = require("main.events.converters") +local Converters = ____converters.Converters +function prototypeUpdates() + local prototypes = {} + __TS__ArrayPushArray( + prototypes, + getMapTilePrototypes() + ) + return prototypes +end +function getMapTilePrototypes() + local tiles = {} + for ____, tile in pairs(game.tile_prototypes) do + tiles[#tiles + 1] = { + type = FactorioPrototype.Type.MapTile, + name = tile.name, + order = tile.order, + layer = tile.layer, + collisionMasks = Converters.convertCollisionMaskToNames(tile.collision_mask), + mapColour = Converters.mapColour(tile.map_color), + canBeMined = tile.mineable_properties.minable + } + end + return tiles +end +function ____exports.emitPrototypes() + local data = { + prototypes = prototypeUpdates(), + type = KafkatorioPacketData.Type.PrototypesUpdate + } + PacketEmitter:emitInstantPacket(data) +end +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/registerHandlers.lua b/modules/events-mod/src/main/lua/main/events/registerHandlers.lua new file mode 100644 index 0000000..65aacb2 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/registerHandlers.lua @@ -0,0 +1,49 @@ +local ____exports = {} +local ____queue = require("main.queue.queue") +local Queue = ____queue.Queue +local ____eventTypeCheck = require("main.events.eventTypeCheck") +local isEventType = ____eventTypeCheck.isEventType +local ____converters = require("main.events.converters") +local Converters = ____converters.Converters +local ____mapChunkUpdates = require("main.events.mapChunkUpdates") +local handleChunkGeneratedEvent = ____mapChunkUpdates.handleChunkGeneratedEvent +local ____surfaceUpdates = require("main.events.surfaceUpdates") +local handleSurfaceUpdate = ____surfaceUpdates.handleSurfaceUpdate +local ____EventDataCache = require("main.cache.EventDataCache") +local EventCacheService = ____EventDataCache.default +script.on_event( + defines.events.on_tick, + function(event) + if event.tick % 1000 == 0 then + for ____, surface in pairs(game.surfaces) do + handleSurfaceUpdate( + event, + Converters.eventNameString(event.name), + surface + ) + end + end + if event.tick % 6 == 0 then + local emittedCount = EventCacheService:extractAndEmitExpiredPackets() + if emittedCount > 0 then + log(((("[on_tick:" .. tostring(event.tick)) .. "] emitted ") .. tostring(emittedCount)) .. " events") + end + end + if event.tick % 7 == 0 then + local events = Queue.dequeueValues(1) + if #events > 0 then + log((((("[on_tick:" .. tostring(event.tick)) .. "] dequeued ") .. tostring(#events)) .. " events, current size: ") .. tostring(Queue.size())) + local i = 1 + for ____, event in ipairs(events) do + if isEventType(event, defines.events.on_chunk_generated) then + local eName = Converters.eventNameString(event.name) + log((((("[on_tick:" .. tostring(event.tick)) .. "] dequed event ") .. eName) .. ", delay ") .. tostring(i)) + handleChunkGeneratedEvent(event, i) + i = i + 1 + end + end + end + end + end +) +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/settingsUpdate.lua b/modules/events-mod/src/main/lua/main/events/settingsUpdate.lua new file mode 100644 index 0000000..e320cd0 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/settingsUpdate.lua @@ -0,0 +1,6 @@ +script.on_event( + defines.events.on_runtime_mod_setting_changed, + function(e) + print((((((("Settings changed " .. e.setting_type) .. ", ") .. tostring(e.player_index)) .. ", ") .. e.setting) .. ", ") .. tostring(e.mod_name)) + end +) diff --git a/modules/events-mod/src/main/lua/main/events/surfaceUpdates.lua b/modules/events-mod/src/main/lua/main/events/surfaceUpdates.lua new file mode 100644 index 0000000..3e2f804 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/surfaceUpdates.lua @@ -0,0 +1,11 @@ +local ____exports = {} +local ____PacketEmitter = require("main.PacketEmitter") +local PacketEmitter = ____PacketEmitter.default +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +local Type = KafkatorioPacketData.Type +function ____exports.handleSurfaceUpdate(event, eventType, surface) + local update = {type = Type.SurfaceUpdate, name = surface.name, index = surface.index, daytime = surface.daytime} + PacketEmitter:emitInstantPacket(update) +end +return ____exports diff --git a/modules/events-mod/src/main/lua/main/global-init.lua b/modules/events-mod/src/main/lua/main/global-init.lua new file mode 100644 index 0000000..5f21c61 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/global-init.lua @@ -0,0 +1,17 @@ +local ____exports = {} +local ____queue = require("main.queue.queue") +local Queue = ____queue.Queue +local ____EventDataCache = require("main.cache.EventDataCache") +local EventUpdatesManager = ____EventDataCache.default +function ____exports.initGlobal(force) + if force == nil then + force = false + end + log(("Initialising Kafkatorio Global variables (force=" .. tostring(force)) .. ")...") + global.MOD_VERSION = script.active_mods[script.mod_name] + global.FACTORIO_VERSION = script.active_mods.base + Queue.init(true) + EventUpdatesManager:init(true) + log("Finished initialising Kafkatorio Global variables") +end +return ____exports diff --git a/modules/events-mod/src/main/lua/main/queue/queue.lua b/modules/events-mod/src/main/lua/main/queue/queue.lua new file mode 100644 index 0000000..2dcf0ca --- /dev/null +++ b/modules/events-mod/src/main/lua/main/queue/queue.lua @@ -0,0 +1,84 @@ +local ____lualib = require("lualib_bundle") +local __TS__New = ____lualib.__TS__New +local __TS__Class = ____lualib.__TS__Class +local ____exports = {} +____exports.Queue = {} +local Queue = ____exports.Queue +do + local Node + function Queue.init(force) + local isAnythingUndefined = global.store == nil or global.size == nil or global.head == nil or global.tail == nil + log(((("Initialising EventQueue globals (force=" .. tostring(force)) .. ", isAnythingUndefined=") .. tostring(isAnythingUndefined)) .. ")") + if force == true or isAnythingUndefined then + global.store = {} + global.head = nil + global.tail = nil + global.size = 0 + end + log("Finished initialising EventQueue") + end + function Queue.size() + return global.size + end + function Queue.enqueue(key, event, weight) + if weight == nil then + weight = 1 + end + if global.store[key] ~= nil then + local node = __TS__New(Node, key, weight) + if global.head == nil then + global.head = node + end + if global.tail ~= nil then + global.tail.next = node + end + global.tail = node + global.size = global.size + 1 + end + global.store[key] = event + end + function Queue.dequeue() + if global.head == nil then + return nil + else + local weight = global.head.weight + local storeKey = global.head.storeKey + global.head = global.head.next + global.size = global.size - 1 + local storedPacket = global.store[storeKey] + global.store[storeKey] = nil + if storedPacket == nil then + return nil + else + return {value = storedPacket, weight = weight} + end + end + end + function Queue.dequeueValues(targetWeight) + if targetWeight == nil then + targetWeight = 50 + end + local values = {} + local weight = 0 + repeat + do + local packet = Queue.dequeue() + if packet == nil then + break + else + weight = weight + packet.weight + values[#values + 1] = packet.value + end + end + until not (weight <= targetWeight) + return values + end + Node = __TS__Class() + Node.name = "Node" + function Node.prototype.____constructor(self, storeKey, weight) + self.next = nil + self.storeKey = storeKey + self.weight = weight + end +end +return ____exports diff --git a/modules/events-mod/src/main/lua/main/settings/KafkatorioSettings.lua b/modules/events-mod/src/main/lua/main/settings/KafkatorioSettings.lua new file mode 100644 index 0000000..aa8a574 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/settings/KafkatorioSettings.lua @@ -0,0 +1,40 @@ +local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local __TS__StringReplaceAll = ____lualib.__TS__StringReplaceAll +local __TS__New = ____lualib.__TS__New +local ____exports = {} +____exports.KafkatorioSettingsConfig = __TS__Class() +local KafkatorioSettingsConfig = ____exports.KafkatorioSettingsConfig +KafkatorioSettingsConfig.name = "KafkatorioSettingsConfig" +function KafkatorioSettingsConfig.prototype.____constructor(self) +end +function KafkatorioSettingsConfig.prototype.getEventCacheExpirationTicks(self, packet) + local settingName = ____exports.KafkatorioSettingsConfig:cacheDurationSettingName(packet.type) + local seconds = settings.global[settingName].value + return seconds * 60 +end +function KafkatorioSettingsConfig.prototype.initialiseSettings(self, data) + for ____type in pairs(____exports.KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds) do + data:extend({____exports.KafkatorioSettingsConfig:createDefaultCacheDuration(____type)}) + end +end +function KafkatorioSettingsConfig.createDefaultCacheDuration(self, ____type, defaultExpirationSeconds) + if defaultExpirationSeconds == nil then + defaultExpirationSeconds = ____exports.KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[____type] + end + return { + type = "double-setting", + name = ____exports.KafkatorioSettingsConfig:cacheDurationSettingName(____type), + setting_type = "runtime-global", + default_value = defaultExpirationSeconds, + minimum_value = 0.25, + maximum_value = 120 + } +end +function KafkatorioSettingsConfig.cacheDurationSettingName(self, ____type) + return "kafkatorio:cache-expiration-seconds_" .. __TS__StringReplaceAll(____type, ".", "-") +end +KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds = {["kafkatorio.packet.keyed.PlayerUpdate"] = 0.5, ["kafkatorio.packet.keyed.MapChunkUpdate"] = 30, ["kafkatorio.packet.keyed.EntityUpdate"] = 5} +local KafkatorioSettings = __TS__New(____exports.KafkatorioSettingsConfig) +____exports.default = KafkatorioSettings +return ____exports diff --git a/modules/events-mod/src/main/lua/settings.lua b/modules/events-mod/src/main/lua/settings.lua new file mode 100644 index 0000000..f01f592 --- /dev/null +++ b/modules/events-mod/src/main/lua/settings.lua @@ -0,0 +1,5 @@ +local ____exports = {} +local ____KafkatorioSettings = require("main.settings.KafkatorioSettings") +local KafkatorioSettings = ____KafkatorioSettings.default +KafkatorioSettings:initialiseSettings(data) +return ____exports From ae9ecc24f5c59d1e310828c7f911bd18f6b4890e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 28 Jun 2022 22:10:39 +0200 Subject: [PATCH 436/629] bump tstl and typed-factorio --- modules/events-mod/package-lock.json | 18 +++++++++--------- modules/events-mod/package.json | 16 ++++++---------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/modules/events-mod/package-lock.json b/modules/events-mod/package-lock.json index 785e0ba..d3a6fbd 100644 --- a/modules/events-mod/package-lock.json +++ b/modules/events-mod/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "enhanced-resolve": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz", - "integrity": "sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", + "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", "requires": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -75,9 +75,9 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.2.0.tgz", - "integrity": "sha512-6iC5YtJYbR2S12kFujIGzZNhBcQwbaSWIAC7iKbIxh8LhVuIDJoInZOg36DTny5GHDdwi0eSTX/wyCqFAbul0Q==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.3.0.tgz", + "integrity": "sha512-qBHKjE+m9Im7vDhsGvl0uwaSFzJ5asqyfw414gF0owZwmSax2CIjdLx367qUgdD4flsB0n9HecBaZ0Yzt9zMPQ==" }, "typescript": { "version": "4.7.4", @@ -85,9 +85,9 @@ "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" }, "typescript-to-lua": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.6.0.tgz", - "integrity": "sha512-s0MWAMnjl2h0qzf02/iULHCFdv3k4Qvj9gAA7nejjPbeHg+paYJZ/MwOrk7n2+gQkztGhJxCE15J9KIv6oIIIw==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.6.1.tgz", + "integrity": "sha512-ekF9U9GhfaoyJcBYiw4uHkT1I9d7Gcoo38N1Aiv/csylodwzNYnThUv/ae+aDhtSD8A4L6uwxMS/OJn5uLbohw==", "requires": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", diff --git a/modules/events-mod/package.json b/modules/events-mod/package.json index 50840cf..41f214b 100644 --- a/modules/events-mod/package.json +++ b/modules/events-mod/package.json @@ -9,19 +9,15 @@ "engines": { "node": "~14.19.1" }, - "devDependencies": { - }, + "devDependencies": {}, "dependencies": { "lua-types": "^2.11.0", - "typescript-to-lua": "1.6.0", - "typed-factorio": "1.2.0", + "typescript-to-lua": "1.6.1", + "typed-factorio": "1.3.0", "typescript": "4.7.4" }, "license": "UNLICENSED", - "peerDependencies": { - }, - "optionalDependencies": { - }, - "bundledDependencies": [ - ] + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [] } From 8a90c4fb5e4a121a3559c04cf66bb12535264b91 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Fri, 1 Jul 2022 13:14:32 +0200 Subject: [PATCH 437/629] - start migrating tile-server to use Ktor - start splitting up Kafka processor and tile-server to two subprojects --- build.gradle.kts | 2 +- buildSrc/build.gradle.kts | 16 +- gradle/kotlin-js-store/yarn.lock | 811 +----------------- gradle/libs.versions.toml | 77 +- modules/events-processor/build.gradle.kts | 125 +++ modules/events-schema/build.gradle.kts | 3 + .../kafkatorio/schema/common/mapTile.kt | 27 +- modules/events-server/build.gradle.kts | 40 +- modules/events-server/docker/Dockerfile | 2 +- .../events-server/docker/docker-compose.yml | 2 +- .../processor/KafkatorioTopology.kt | 2 +- .../processor/config/ApplicationProperties.kt | 2 +- .../kafkatorio/processor/config/PortVal.kt | 3 +- .../kafkatorio/processor/serdes/kxsJson.kt | 11 - .../processor/tileserver/WebMapTileServer.kt | 7 +- .../processor/topology/saveMapTiles.kt | 10 +- .../server/kafkatorioEventsServer.kt | 38 + .../kafkatorio/server/syslogSocketServer.kt | 152 ++++ .../kafkatorio/server/webmapTileServer.kt | 148 ++++ .../server/webmapWebsocketServer.kt | 130 +++ .../src/main/resources/config.yml | 2 +- settings.gradle.kts | 1 + 22 files changed, 735 insertions(+), 876 deletions(-) create mode 100644 modules/events-processor/build.gradle.kts create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/kafkatorioEventsServer.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/syslogSocketServer.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/webmapTileServer.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/webmapWebsocketServer.kt diff --git a/build.gradle.kts b/build.gradle.kts index ae6a2ff..b957525 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { `project-report` `build-dashboard` -// kotlin("multiplatform") apply false // try to stop error 'Projects must be configuring' + kotlin("multiplatform") apply false // try to stop error 'Projects must be configuring' // kotlin("js") apply false // try to stop error 'Projects must be configuring' } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 47649fd..d1f2d38 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -43,14 +43,14 @@ dependencies { implementation(libs.kotlinx.cli) implementation(platform(libs.ktor.bom)) - implementation(libs.ktor.clientAuth) - implementation(libs.ktor.clientContentNegotiation) - implementation(libs.ktor.clientCore) - implementation(libs.ktor.clientEncoding) - implementation(libs.ktor.clientLogging) - implementation(libs.ktor.clientCIO) - implementation(libs.ktor.clientResources) - implementation(libs.ktor.serializationKotlinxJson) + implementation(libs.ktorClient.auth) + implementation(libs.ktorClient.contentNegotiation) + implementation(libs.ktorClient.core) + implementation(libs.ktorClient.encoding) + implementation(libs.ktorClient.logging) + implementation(libs.ktorClient.cio) + implementation(libs.ktorClient.resources) + implementation(libs.ktorSerialization.kotlinxJson) // https://github.com/avast/gradle-docker-compose-plugin // implementation("com.avast.gradle:gradle-docker-compose-plugin:${Versions.gradleDockerComposePlugin}") diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index f458026..e117ebe 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -24,11 +24,6 @@ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.1.1.tgz#bf5d45611ab74890be386712a0e5d998c65ee2a1" integrity sha512-J/3yg2AIXc9wznaVqpHVX3Wa5jwKovVF0AMYSnbmcXTiL3PpRPfF58pzWucCwEiCJBp+hCNRLWClTomD8SseKg== -"@leichtgewicht/ip-codec@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" - integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== - "@popperjs/core@^2.11.4": version "2.11.5" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64" @@ -57,41 +52,11 @@ dependencies: html-parse-stringify "^3" -"@types/body-parser@*": - version "1.19.2" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" - integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/bonjour@^3.5.9": - version "3.5.10" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" - integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== - dependencies: - "@types/node" "*" - "@types/component-emitter@^1.2.10": version "1.2.11" resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== -"@types/connect-history-api-fallback@^1.3.5": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" - integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== - dependencies: - "@types/express-serve-static-core" "*" - "@types/node" "*" - -"@types/connect@*": - version "3.4.35" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" - integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== - dependencies: - "@types/node" "*" - "@types/cookie@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" @@ -123,25 +88,6 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": - version "4.17.29" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz#2a1795ea8e9e9c91b4a4bbe475034b20c1ec711c" - integrity sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - -"@types/express@*", "@types/express@^4.17.13": - version "4.17.13" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" - integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.18" - "@types/qs" "*" - "@types/serve-static" "*" - "@types/geojson@7946.0.8": version "7946.0.8" resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" @@ -162,16 +108,11 @@ dependencies: "@types/node" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.8": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== -"@types/mime@^1": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" - integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== - "@types/minimatch@*": version "3.0.5" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" @@ -187,50 +128,6 @@ resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== -"@types/qs@*": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== - -"@types/range-parser@*": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" - integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== - -"@types/retry@^0.12.0": - version "0.12.1" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" - integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== - -"@types/serve-index@^1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" - integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== - dependencies: - "@types/express" "*" - -"@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.13.10" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" - integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== - dependencies: - "@types/mime" "^1" - "@types/node" "*" - -"@types/sockjs@^0.3.33": - version "0.3.33" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" - integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== - dependencies: - "@types/node" "*" - -"@types/ws@^8.5.1": - version "8.5.3" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" - integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== - dependencies: - "@types/node" "*" - "@ungap/promise-all-settled@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" @@ -389,7 +286,7 @@ abab@^2.0.5: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: +accepts@~1.3.4: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== @@ -407,25 +304,11 @@ acorn@^8.4.1, acorn@^8.5.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== -ajv-formats@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" - integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== - dependencies: - ajv "^8.0.0" - ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv-keywords@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" - integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== - dependencies: - fast-deep-equal "^3.1.3" - ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -436,26 +319,11 @@ ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.8.0: - version "8.11.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" - integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - ansi-colors@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== -ansi-html-community@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" - integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== - ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -488,16 +356,6 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - -array-flatten@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - awesome-bootstrap-checkbox@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/awesome-bootstrap-checkbox/-/awesome-bootstrap-checkbox-1.0.1.tgz#dab10146b6001129ab0a0ec1e54bb77c6c30457a" @@ -513,17 +371,12 @@ base64id@2.0.0, base64id@~2.0.0: resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== -batch@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= - binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -body-parser@1.20.0, body-parser@^1.19.0: +body-parser@^1.19.0: version "1.20.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== @@ -541,16 +394,6 @@ body-parser@1.20.0, body-parser@^1.19.0: type-is "~1.6.18" unpipe "1.0.0" -bonjour-service@^1.0.11: - version "1.0.13" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.13.tgz#4ac003dc1626023252d58adf2946f57e5da450c1" - integrity sha512-LWKRU/7EqDUC9CTAQtuZl5HzBALoCYwtLhffW3et7vZMwv3bWLpJf8bRYlMD5OCcDpTfnPgNCV4yo9ZIaJGMiA== - dependencies: - array-flatten "^2.1.2" - dns-equal "^1.0.0" - fast-deep-equal "^3.1.3" - multicast-dns "^7.2.5" - bootstrap-icons@^1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.8.1.tgz#773c1625bcbf3e86090ea9da4386c2c6459c5582" @@ -604,11 +447,6 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= - bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" @@ -654,7 +492,7 @@ chart.js@^3.8.0: resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.8.0.tgz#c6c14c457b9dc3ce7f1514a59e9b262afd6f1a94" integrity sha512-cr8xhrXjLIXVLOBZPkBZVF6NDeiVIrPLHcMhnON7UufudL+CNeRrD+wpYanswlm8NpudMdrt3CHoLMQMxJhHRg== -chokidar@3.5.3, chokidar@^3.5.1, chokidar@^3.5.3: +chokidar@3.5.3, chokidar@^3.5.1: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -716,7 +554,7 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -colorette@^2.0.10, colorette@^2.0.14: +colorette@^2.0.14: version "2.0.16" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== @@ -741,36 +579,11 @@ component-emitter@~1.3.0: resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== -compressible@~2.0.16: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== - dependencies: - mime-db ">= 1.43.0 < 2" - -compression@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" - concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -connect-history-api-fallback@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" - integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== - connect@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" @@ -781,38 +594,16 @@ connect@^3.7.0: parseurl "~1.3.3" utils-merge "1.0.1" -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== - cookie@~0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - cors@~2.8.5: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" @@ -871,7 +662,7 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4.3.4, debug@^4.1.0, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: +debug@4.3.4, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -883,38 +674,16 @@ decamelize@^4.0.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== -default-gateway@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" - integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== - dependencies: - execa "^5.0.0" - -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - depd@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== -detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - di@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" @@ -925,18 +694,6 @@ diff@5.0.0: resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= - -dns-packet@^5.2.2: - version "5.4.0" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.4.0.tgz#1f88477cf9f27e78a213fb6d118ae38e759a879b" - integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g== - dependencies: - "@leichtgewicht/ip-codec" "^2.0.1" - dom-serialize@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" @@ -1079,11 +836,6 @@ estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - eventemitter3@^4.0.0: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -1094,64 +846,12 @@ events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -express@^4.17.3: - version "4.18.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" - integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.0" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.5.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.2.0" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "2.4.1" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.7" - qs "6.10.3" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" - setprototypeof "1.2.0" - statuses "2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - extend@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: +fast-deep-equal@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== @@ -1166,13 +866,6 @@ fastest-levenshtein@^1.0.12: resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== -faye-websocket@^0.11.3: - version "0.11.4" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" - integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== - dependencies: - websocket-driver ">=0.5.1" - fecha@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" @@ -1198,19 +891,6 @@ finalhandler@1.1.2: statuses "~1.5.0" unpipe "~1.0.0" -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "2.4.1" - parseurl "~1.3.3" - statuses "2.0.1" - unpipe "~1.0.0" - find-up@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" @@ -1247,16 +927,6 @@ format-util@1.0.5: resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - fs-extra@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" @@ -1275,11 +945,6 @@ fs-extra@^8.0.1: jsonfile "^4.0.0" universalify "^0.1.0" -fs-monkey@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" - integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -1314,11 +979,6 @@ get-intrinsic@^1.0.2: has "^1.0.3" has-symbols "^1.0.1" -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - gettext-extract@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/gettext-extract/-/gettext-extract-2.0.1.tgz#4ade7e3d7c1c247d95a81f28059ca1923c355886" @@ -1400,11 +1060,6 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== -handle-thing@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" - integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -1432,21 +1087,6 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -html-entities@^2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" - integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== - html-parse-stringify@^3: version "3.0.1" resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2" @@ -1454,11 +1094,6 @@ html-parse-stringify@^3: dependencies: void-elements "3.1.0" -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= - http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -1470,22 +1105,7 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-parser-js@>=0.5.1: - version "0.5.6" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.6.tgz#2e02406ab2df8af8a7abfba62e0da01c62b95afd" - integrity sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA== - -"http-proxy-middleware@>=2.0.6 <3.0.0", http-proxy-middleware@^2.0.3, http-proxy-middleware@^2.0.6: +"http-proxy-middleware@>=2.0.6 <3.0.0", http-proxy-middleware@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== @@ -1505,11 +1125,6 @@ http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -1553,31 +1168,16 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: +inherits@2, inherits@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - interpret@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -ipaddr.js@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" - integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== - is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -1592,11 +1192,6 @@ is-core-module@^2.8.1: dependencies: has "^1.0.3" -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -1636,28 +1231,11 @@ is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - is-unicode-supported@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - isbinaryfile@^4.0.8: version "4.0.10" resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" @@ -1704,11 +1282,6 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -1855,28 +1428,11 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= -memfs@^3.4.3: - version "3.4.4" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.4.tgz#e8973cd8060548916adcca58a248e7805c715e89" - integrity sha512-W4gHNUE++1oSJVn8Y68jPXi+mkx3fXR5ITE/Ubz6EQ3xRpCN5k2CQ4AUR8094Z7211F876TyoBACGsIveqgiGA== - dependencies: - fs-monkey "1.0.3" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= - merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - micromatch@^4.0.2: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" @@ -1885,38 +1441,23 @@ micromatch@^4.0.2: braces "^3.0.2" picomatch "^2.3.1" -mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": +mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - mime@^2.5.2: version "2.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimalistic-assert@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - minimatch@5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" @@ -1986,14 +1527,6 @@ ms@2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -multicast-dns@^7.2.5: - version "7.2.5" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" - integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== - dependencies: - dns-packet "^5.2.2" - thunky "^1.0.2" - nanoid@3.3.3, nanoid@^3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" @@ -2009,11 +1542,6 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -node-forge@^1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" - integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== - node-releases@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" @@ -2024,13 +1552,6 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - object-assign@^4: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -2041,11 +1562,6 @@ object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - on-finished@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -2060,11 +1576,6 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" -on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== - once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -2072,22 +1583,6 @@ once@^1.3.0: dependencies: wrappy "1" -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -open@^8.0.9: - version "8.4.0" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" - integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -2116,14 +1611,6 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" -p-retry@^4.5.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c" - integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA== - dependencies: - "@types/retry" "^0.12.0" - retry "^0.13.1" - p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -2134,7 +1621,7 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== -parseurl@~1.3.2, parseurl@~1.3.3: +parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== @@ -2149,7 +1636,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-key@^3.0.0, path-key@^3.1.0: +path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== @@ -2159,11 +1646,6 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -2236,19 +1718,6 @@ postcss@^8.4.7: picocolors "^1.0.0" source-map-js "^1.0.2" -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -2273,7 +1742,7 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -range-parser@^1.2.1, range-parser@~1.2.1: +range-parser@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== @@ -2288,28 +1757,6 @@ raw-body@2.5.1: iconv-lite "0.4.24" unpipe "1.0.0" -readable-stream@^2.0.1: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -2346,11 +1793,6 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" @@ -2377,11 +1819,6 @@ resolve@^1.9.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -retry@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - rfdc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" @@ -2394,12 +1831,7 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: +safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -2418,28 +1850,6 @@ schema-utils@^3.1.0, schema-utils@^3.1.1: ajv "^6.12.5" ajv-keywords "^3.5.2" -schema-utils@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" - integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== - dependencies: - "@types/json-schema" "^7.0.9" - ajv "^8.8.0" - ajv-formats "^2.1.1" - ajv-keywords "^5.0.0" - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= - -selfsigned@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" - integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ== - dependencies: - node-forge "^1" - semver@^7.3.5: version "7.3.7" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" @@ -2447,25 +1857,6 @@ semver@^7.3.5: dependencies: lru-cache "^6.0.0" -send@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" - mime "1.6.0" - ms "2.1.3" - on-finished "2.4.1" - range-parser "~1.2.1" - statuses "2.0.1" - serialize-javascript@6.0.0, serialize-javascript@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -2473,34 +1864,6 @@ serialize-javascript@6.0.0, serialize-javascript@^6.0.0: dependencies: randombytes "^2.1.0" -serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.18.0" - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" @@ -2534,11 +1897,6 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.3: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - snabbdom@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.5.0.tgz#e75acbdedb26ea327c75028a433ba064db0ccf6e" @@ -2570,15 +1928,6 @@ socket.io@^4.4.1: socket.io-adapter "~2.4.0" socket.io-parser "~4.0.4" -sockjs@^0.3.24: - version "0.3.24" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" - integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== - dependencies: - faye-websocket "^0.11.3" - uuid "^8.3.2" - websocket-driver "^0.7.4" - source-map-js@^1.0.1, source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" @@ -2611,29 +1960,6 @@ source-map@~0.7.2: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - split.js@^1.6.5: version "1.6.5" resolved "https://registry.yarnpkg.com/split.js/-/split.js-1.6.5.tgz#f7f61da1044c9984cb42947df4de4fadb5a3f300" @@ -2644,7 +1970,7 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== -"statuses@>= 1.4.0 < 2", statuses@~1.5.0: +statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= @@ -2667,20 +1993,6 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -2693,11 +2005,6 @@ strip-comments@^2.0.1: resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - strip-json-comments@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" @@ -2760,11 +2067,6 @@ terser@^5.7.2: source-map "~0.7.2" source-map-support "~0.5.20" -thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" - integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== - tmp@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" @@ -2829,7 +2131,7 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: +util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= @@ -2839,12 +2141,7 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -vary@^1, vary@~1.1.2: +vary@^1: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= @@ -2867,13 +2164,6 @@ watchpack@^2.3.1: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - webpack-cli@4.10.0: version "4.10.0" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" @@ -2892,52 +2182,6 @@ webpack-cli@4.10.0: rechoir "^0.7.0" webpack-merge "^5.7.3" -webpack-dev-middleware@^5.3.1: - version "5.3.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" - integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== - dependencies: - colorette "^2.0.10" - memfs "^3.4.3" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - -webpack-dev-server@4.9.2: - version "4.9.2" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.9.2.tgz#c188db28c7bff12f87deda2a5595679ebbc3c9bc" - integrity sha512-H95Ns95dP24ZsEzO6G9iT+PNw4Q7ltll1GfJHV4fKphuHWgKFzGHWi4alTlTnpk1SPPk41X+l2RB7rLfIhnB9Q== - dependencies: - "@types/bonjour" "^3.5.9" - "@types/connect-history-api-fallback" "^1.3.5" - "@types/express" "^4.17.13" - "@types/serve-index" "^1.9.1" - "@types/serve-static" "^1.13.10" - "@types/sockjs" "^0.3.33" - "@types/ws" "^8.5.1" - ansi-html-community "^0.0.8" - bonjour-service "^1.0.11" - chokidar "^3.5.3" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^1.6.0" - default-gateway "^6.0.3" - express "^4.17.3" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.3" - ipaddr.js "^2.0.1" - open "^8.0.9" - p-retry "^4.5.0" - rimraf "^3.0.2" - schema-utils "^4.0.0" - selfsigned "^2.0.1" - serve-index "^1.9.1" - sockjs "^0.3.24" - spdy "^4.0.2" - webpack-dev-middleware "^5.3.1" - ws "^8.4.2" - webpack-merge@^4.1.5: version "4.2.2" resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" @@ -2988,20 +2232,6 @@ webpack@5.73.0: watchpack "^2.3.1" webpack-sources "^3.2.3" -websocket-driver@>=0.5.1, websocket-driver@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" - integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.4" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" - integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== - which@^1.2.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -3040,11 +2270,6 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@^8.4.2: - version "8.8.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.0.tgz#8e71c75e2f6348dbf8d78005107297056cb77769" - integrity sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ== - ws@~8.2.3: version "8.2.3" resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9d174aa..fab0a54 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -31,7 +31,7 @@ kotlinx-coroutines = "1.6.1" kotlinx-cli = "0.3.4" kotlinx-datetime = "0.3.3" -ktor = "2.0.2" +ktor = "2.0.3" hoplite = "2.1.5" @@ -123,45 +123,50 @@ http4k-graphql = { group = "org.http4k", name = "http4k-graphql" ## ktor ## ktor-bom = { group = "io.ktor", name = "ktor-bom", version.ref = "ktor" } -ktor-clientAuth = { group = "io.ktor", name = "ktor-client-auth" } -ktor-clientCIO = { group = "io.ktor", name = "ktor-client-cio" } -ktor-clientContentNegotiation = { group = "io.ktor", name = "ktor-client-content-negotiation" } -ktor-clientCore = { group = "io.ktor", name = "ktor-client-core" } -ktor-clientEncoding = { group = "io.ktor", name = "ktor-client-encoding" } -ktor-clientLogging = { group = "io.ktor", name = "ktor-client-logging" } -ktor-clientResources = { group = "io.ktor", name = "ktor-client-resources" } -ktor-clientWebsockets = { group = "io.ktor", name = "ktor-client-websockets" } -ktor-serializationKotlinxJson = { group = "io.ktor", name = "ktor-serialization-kotlinx-json" } +ktorSerialization-kotlinxJson = { group = "io.ktor", name = "ktor-serialization-kotlinx-json" } + +ktorClient-core = { group = "io.ktor", name = "ktor-client-core" } +ktorClient-auth = { group = "io.ktor", name = "ktor-client-auth" } +ktorClient-cio = { group = "io.ktor", name = "ktor-client-cio" } +ktorClient-contentNegotiation = { group = "io.ktor", name = "ktor-client-content-negotiation" } +ktorClient-encoding = { group = "io.ktor", name = "ktor-client-encoding" } +ktorClient-logging = { group = "io.ktor", name = "ktor-client-logging" } +ktorClient-resources = { group = "io.ktor", name = "ktor-client-resources" } +ktorClient-websockets = { group = "io.ktor", name = "ktor-client-websockets" } + +ktorClient-testMock = { group = "io.ktor", name = "ktor-client-mock" } -ktor-serverCore = { group = "io.ktor", name = "ktor-server-core" } -ktor-serverNetty = { group = "io.ktor", name = "ktor-server-netty" } -ktor-serverContentNegotiaion = { group = "io.ktor", name = "ktor-server-content-negotiation" } -ktor-serverCors = { group = "io.ktor", name = "ktor-server-cors" } -ktor-serverResources = { group = "io.ktor", name = "ktor-server-resources" } -ktor-serverAutoHeadResponse = { group = "io.ktor", name = "ktor-server-auto-head-response" } -ktor-serverStatusPages = { group = "io.ktor", name = "ktor-server-status-pages" } -ktor-serverAuth = { group = "io.ktor", name = "ktor-server-auth" } -ktor-serverAuthJwt = { group = "io.ktor", name = "ktor-server-auth-jwt" } -ktor-serverSessions = { group = "io.ktor", name = "ktor-server-sessions" } -ktor-serverDataConversion = { group = "io.ktor", name = "ktor-server-data-conversion" } -ktor-serverDefaultHeaders = { group = "io.ktor", name = "ktor-server-default-headers" } -ktor-serverCompression = { group = "io.ktor", name = "ktor-server-compression" } -ktor-serverCachingHeaders = { group = "io.ktor", name = "ktor-server-caching-headers" } -ktor-serverConditionalHeaders = { group = "io.ktor", name = "ktor-server-conditional-headers" } -ktor-serverForwardedHeader = { group = "io.ktor", name = "ktor-server-forwarded-header" } -ktor-serverHsts = { group = "io.ktor", name = "ktor-server-hsts" } -ktor-serverHttpRedirect = { group = "io.ktor", name = "ktor-server-http-redirect" } -ktor-serverPartialContent = { group = "io.ktor", name = "ktor-server-partial-content" } -ktor-serverWebsockets = { group = "io.ktor", name = "ktor-server-websockets" } -ktor-serverCallLogging = { group = "io.ktor", name = "ktor-server-call-logging" } -ktor-serverCallId = { group = "io.ktor", name = "ktor-server-call-id" } +ktorServer-core = { group = "io.ktor", name = "ktor-server-core" } +ktorServer-auth = { group = "io.ktor", name = "ktor-server-auth" } +ktorServer-authJwt = { group = "io.ktor", name = "ktor-server-auth-jwt" } +ktorServer-autoHeadResponse = { group = "io.ktor", name = "ktor-server-auto-head-response" } +ktorServer-cachingHeaders = { group = "io.ktor", name = "ktor-server-caching-headers" } +ktorServer-callId = { group = "io.ktor", name = "ktor-server-call-id" } +ktorServer-callLogging = { group = "io.ktor", name = "ktor-server-call-logging" } +ktorServer-compression = { group = "io.ktor", name = "ktor-server-compression" } +ktorServer-conditionalHeaders = { group = "io.ktor", name = "ktor-server-conditional-headers" } +ktorServer-contentNegotiaion = { group = "io.ktor", name = "ktor-server-content-negotiation" } +ktorServer-cors = { group = "io.ktor", name = "ktor-server-cors" } +ktorServer-dataConversion = { group = "io.ktor", name = "ktor-server-data-conversion" } +ktorServer-defaultHeaders = { group = "io.ktor", name = "ktor-server-default-headers" } +ktorServer-forwardedHeader = { group = "io.ktor", name = "ktor-server-forwarded-header" } +ktorServer-hsts = { group = "io.ktor", name = "ktor-server-hsts" } +ktorServer-httpRedirect = { group = "io.ktor", name = "ktor-server-http-redirect" } +#ktorServer-netty = { group = "io.ktor", name = "ktor-server-netty" } +ktorServer-cio = { group = "io.ktor", name = "ktor-server-cio" } +ktorServer-partialContent = { group = "io.ktor", name = "ktor-server-partial-content" } +ktorServer-resources = { group = "io.ktor", name = "ktor-server-resources" } +ktorServer-sessions = { group = "io.ktor", name = "ktor-server-sessions" } +ktorServer-statusPages = { group = "io.ktor", name = "ktor-server-status-pages" } +ktorServer-websockets = { group = "io.ktor", name = "ktor-server-websockets" } -ktor-network = { group = "io.ktor", name = "ktor-network" } -ktor-networkTls = { group = "io.ktor", name = "ktor-network-tls" } +ktorServer-testHost = { group = "io.ktor", name = "ktor-server-test-host" } + + +ktorNetwork-core = { group = "io.ktor", name = "ktor-network" } +ktorNetwork-tls = { group = "io.ktor", name = "ktor-network-tls" } -ktor-test-clientMock = { group = "io.ktor", name = "ktor-client-mock" } -ktor-test-serverHost = { group = "io.ktor", name = "ktor-server-test-host" } ### jackson ## diff --git a/modules/events-processor/build.gradle.kts b/modules/events-processor/build.gradle.kts new file mode 100644 index 0000000..6ccc2d3 --- /dev/null +++ b/modules/events-processor/build.gradle.kts @@ -0,0 +1,125 @@ +import dev.adamko.kafkatorio.task.KafkaConsumerGroupsTask +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + + +plugins { + dev.adamko.kafkatorio.lang.`kotlin-jvm` + kotlin("plugin.serialization") + application +} + + +description = """ + Receive raw Factorio Events from Kafka and process them into targeted topics or data formats. + + Factorio events -> Mod -> Kafka -> ***Factorio Events Processor*** -> processed events + """.trimIndent() + +val projectId: String by project.extra + +val kafkaStateDir: Directory = layout.projectDirectory.dir("kafka-state") + + +dependencies { + implementation(platform(projects.modules.versionsPlatform)) + + implementation(libs.kafka.streams) + testImplementation(libs.kafka.streamsTestUtils) + + implementation(projects.modules.eventsSchema) + +// implementation("com.ionspin.kotlin:bignum:0.3.3") + + implementation(libs.kotlinx.serialization.core) + implementation(libs.kotlinx.serialization.json) +// implementation("org.jetbrains.kotlinx:kotlinx-serialization-protobuf") + + implementation(libs.kotlinx.coroutines.core) + + implementation(libs.bundles.http4k) + implementation(libs.http4k.format.kotlinx) + + + implementation(libs.bundles.logging) + + implementation(libs.scrimage.core) + + implementation(libs.okio.core) + + + // + implementation(libs.ktorSerialization.kotlinxJson) + + with(libs.ktorServer) { + implementation(core) + implementation(callId) + implementation(callLogging) + implementation(contentNegotiaion) + implementation(cio) +// implementation(netty) + implementation(autoHeadResponse) + implementation(partialContent) + implementation(resources) + implementation(statusPages) + implementation(websockets) + implementation(compression) + } + + with(libs.ktorNetwork) { + implementation(core) + implementation(tls) + } + + // + + + implementation(libs.simpleSyslogParser) + + implementation(libs.kafka.kotkaStreams) { + isChanging = false + } + + implementation(libs.bundles.hoplite) +} + + +application { + mainClass.set("dev.adamko.kafkatorio.processor.EventProcessorKt") + +// applicationDefaultJvmArgs += listOf( +// "-Dcom.sun.management.jmxremote.port=9186", +// "-Dcom.sun.management.jmxremote.rmi.port=9186", +// "-Dcom.sun.management.jmxremote.ssl=false", +// "-Dcom.sun.management.jmxremote.local.only=false", +// "-Dcom.sun.management.jmxremote.authenticate=false", +// ) +} + +tasks.withType().configureEach { + kotlinOptions.freeCompilerArgs += listOf( + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlinx.coroutines.FlowPreview", + "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", + ) +} + + +val kafkaStateDirDelete by tasks.registering(Delete::class) { + group = project.name + mustRunAfter(kafkaConsumersDelete) + delete(kafkaStateDir) +} + +val kafkaConsumersDelete by tasks.registering(KafkaConsumerGroupsTask.DeleteAll::class) { + group = project.name +} + +//tasks.run.configure { +// dependsOn(kafkatorioEventsServerKafkaForceReset) +//} + +idea { + module { + excludeDirs = excludeDirs + kafkaStateDir.asFile + } +} diff --git a/modules/events-schema/build.gradle.kts b/modules/events-schema/build.gradle.kts index 31b22fa..161fa87 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-schema/build.gradle.kts @@ -11,6 +11,9 @@ plugins { } +description = "shared data structures and utilities" + + kotlin { js(IR) { diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt index 360554b..20f41af 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt +++ b/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt @@ -80,16 +80,33 @@ data class ServerMapChunkId( ) +/** `${serverDataDir}/servers/{serverId}/map/tiles/s{surfaceIndex}/z{zoomLevel}/x{chunkX}/y{chunkY}.png` */ @Serializable @JvmInline value class TilePngFilename( val value: String, ) { - constructor(id: ServerMapChunkId) : this(buildString { - append("s${id.surfaceIndex}") - append("/z${id.chunkSize.zoomLevel}") - append("/x${id.chunkPosition.x}") - append("/y${id.chunkPosition.y}") + constructor(id: ServerMapChunkId) : this( + id.serverId, + id.surfaceIndex, + id.chunkSize.zoomLevel, + id.chunkPosition.x, + id.chunkPosition.y, + ) + + constructor( + serverId: FactorioServerId, + surfaceIndex: SurfaceIndex, + zoomLevel: Int, + chunkX: Int, + chunkY: Int, + ) : this(buildString { + append("servers/${serverId}") + append("/map/tiles") + append("/s${surfaceIndex}") + append("/z${zoomLevel}") + append("/x${chunkX}") + append("/y${chunkY}") append(".png") }) } diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 58084d5..5cf21e9 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -9,11 +9,7 @@ plugins { } -description = """ - Receive raw Factorio Events from Kafka and process them into targeted topics or data formats. - - Factorio events -> Mod -> Kafka -> ***Factorio Events Processor*** -> processed events - """.trimIndent() +description = "serves Kafkatorio content over the web" val projectId: String by project.extra @@ -39,19 +35,44 @@ dependencies { implementation(libs.bundles.http4k) implementation(libs.http4k.format.kotlinx) + implementation(libs.bundles.logging) implementation(libs.scrimage.core) implementation(libs.okio.core) - implementation(libs.ktor.network) - implementation(libs.ktor.networkTls) + + // + implementation(libs.ktorSerialization.kotlinxJson) + + with(libs.ktorServer) { + implementation(core) + implementation(callId) + implementation(callLogging) + implementation(contentNegotiaion) + implementation(cio) +// implementation(netty) + implementation(autoHeadResponse) + implementation(partialContent) + implementation(resources) + implementation(statusPages) + implementation(websockets) + implementation(compression) + } + + with(libs.ktorNetwork) { + implementation(core) + implementation(tls) + } + + // + implementation(libs.simpleSyslogParser) implementation(libs.kafka.kotkaStreams) { - isChanging = true + isChanging = false } implementation(libs.bundles.hoplite) @@ -59,7 +80,8 @@ dependencies { application { - mainClass.set("dev.adamko.kafkatorio.processor.EventProcessorKt") +// mainClass.set("dev.adamko.kafkatorio.processor.EventProcessorKt") + mainClass.set("dev.adamko.kafkatorio.server.KafkatorioEventsServerKt") // applicationDefaultJvmArgs += listOf( // "-Dcom.sun.management.jmxremote.port=9186", diff --git a/modules/events-server/docker/Dockerfile b/modules/events-server/docker/Dockerfile index 9c350df..2bad738 100644 --- a/modules/events-server/docker/Dockerfile +++ b/modules/events-server/docker/Dockerfile @@ -9,7 +9,7 @@ WORKDIR /app ENV SERVER_PORT=8080 EXPOSE $SERVER_PORT -ENV TILE_DIR="/app/tiles" +ENV SERVER_DATA_DIR="/app/data" ENV KAFKA_STREAMS_STATE_DIR="/app/kafka-state" VOLUME ${TILE_DIR} \ ${KAFKA_STREAMS_STATE_DIR} diff --git a/modules/events-server/docker/docker-compose.yml b/modules/events-server/docker/docker-compose.yml index 85d941c..c410cc2 100644 --- a/modules/events-server/docker/docker-compose.yml +++ b/modules/events-server/docker/docker-compose.yml @@ -14,7 +14,7 @@ services: DIST_DIR: "./build/distributions/" environment: KAFKA_BOOTSTRAP_SERVERS: "http://kafka:29092" - # KAFKA_STREAMS_STATE_DIR: "http://kafka:29092" + # KAFKA_STREAMS_STATE_DIR: "" SERVER_PORT: "8080" ports: - "12080:8080" # http and ws diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt index d86e259..7df00b0 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt @@ -79,7 +79,7 @@ internal class KafkatorioTopology( private suspend fun saveTiles() { val builder = StreamsBuilder() - val topology = saveMapTiles(builder, appProps.tileDir) + val topology = saveMapTiles(builder, appProps.serverDataDir) launchTopology("saveTiles", topology) } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt index 5e794ad..204c74a 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt @@ -9,7 +9,7 @@ import java.nio.file.Path // loaded by hoplite data class ApplicationProperties( val webPort: PortVal, - val tileDir: Path, + val serverDataDir: Path, val kafkaAdminConfig: Map, val kafkaStreamsConfig: Map, diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt index 1418447..e2f880d 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt @@ -17,6 +17,7 @@ value class PortVal(val value: Int) { companion object { val DEFAULT = PortVal(8080) - val VALID_RANGE: IntRange = 1..65535 + val VALID_RANGE: IntRange + get() = (1..65535) // get() is required to prevent init ordering causing NPE } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt index bf6becd..e534e69 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt @@ -2,20 +2,9 @@ package dev.adamko.kafkatorio.processor.serdes import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio import kotlinx.serialization.json.Json -import org.http4k.format.ConfigurableKotlinxSerialization -import org.http4k.format.asConfigurable -import org.http4k.format.withStandardMappings val jsonMapper: Json = Json { prettyPrint = true prettyPrintIndent = " " serializersModule = jsonMapperKafkatorio.serializersModule } - -object KXS : ConfigurableKotlinxSerialization({ - ignoreUnknownKeys = true - prettyPrint = true - prettyPrintIndent = " " - asConfigurable().withStandardMappings().done() - serializersModule = jsonMapperKafkatorio.serializersModule -}) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt index a599cef..e64335f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt @@ -2,7 +2,6 @@ package dev.adamko.kafkatorio.processor.tileserver import dev.adamko.kafkatorio.processor.config.ApplicationProperties import java.security.MessageDigest -import kotlin.io.path.absolutePathString import org.http4k.core.Filter import org.http4k.core.HttpHandler import org.http4k.core.MemoryBody @@ -21,16 +20,19 @@ internal class WebMapTileServer( appProps: ApplicationProperties ) { - private val tilesLoader = ResourceLoader.Directory(appProps.tileDir.toFile().canonicalPath) + private val tilesLoader = ResourceLoader.Directory(appProps.serverDataDir.toFile().canonicalPath) + private val filters = listOf( ETagChecker(), ).reduce(Filter::then) + private val routes: RoutingHttpHandler = routes( "/tiles" bind GET to static(tilesLoader).withFilter(filters) ) + fun build(): HttpHandler { return routes } @@ -69,6 +71,7 @@ internal class WebMapTileServer( } } + companion object { private fun ByteArray.md5(): String? { return if (isEmpty()) { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt index 970f1d2..b0da8d4 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt @@ -32,11 +32,11 @@ private const val WEB_MAP_TILE_SIZE_PX = 256 /** - * @param[tileDirectory] [dev.adamko.kafkatorio.processor.config.ApplicationProperties.webmapTileDir] + * @param[serverDataDir] [dev.adamko.kafkatorio.processor.config.ApplicationProperties.serverDataDir] */ fun saveMapTiles( builder: StreamsBuilder, - tileDirectory: Path, + serverDataDir: Path, ): Topology { val subdividedMapChunkTilesDebounced: KStream> = @@ -50,7 +50,7 @@ fun saveMapTiles( ) val savedChunkFilenames: KStream = - subdividedMapChunkTilesDebounced.saveChunkAsImage(tileDirectory) + subdividedMapChunkTilesDebounced.saveChunkAsImage(serverDataDir) savedChunkFilenames.broadcastSavedTileUpdates() @@ -95,10 +95,10 @@ private fun KStream>.saveChunkA @Synchronized private fun saveTile( filename: TilePngFilename, - tileDirectory: Path, + serverDataDir: Path, img: ImmutableImage, ) { - val chunkImageFile = tileDirectory.resolve(filename.value).toFile() + val chunkImageFile = serverDataDir.resolve(filename.value).toFile() if (chunkImageFile.parentFile.mkdirs()) { println("created new map tile parentFile directory ${chunkImageFile.absolutePath}") } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/kafkatorioEventsServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/kafkatorioEventsServer.kt new file mode 100644 index 0000000..a8cd36c --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/kafkatorioEventsServer.kt @@ -0,0 +1,38 @@ +package dev.adamko.kafkatorio.server + +import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import io.ktor.http.HttpStatusCode +import io.ktor.server.application.Application +import io.ktor.server.application.install +import io.ktor.server.cio.CIO +import io.ktor.server.engine.embeddedServer +import io.ktor.server.plugins.callloging.CallLogging +import io.ktor.server.plugins.statuspages.StatusPages +import io.ktor.server.response.respondText + + +fun main() { + val appProps = ApplicationProperties.load() + + embeddedServer(CIO, port = appProps.webPort.value) { + + common() + + webmapWebsocketServer() + + webmapTileServer(appProps) + + syslogSocketServer(appProps) + + }.start(wait = true) +} + + +fun Application.common() { + install(StatusPages) { + exception { call, cause -> + call.respondText(text = "500: $cause", status = HttpStatusCode.InternalServerError) + } + } + install(CallLogging) +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/syslogSocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/syslogSocketServer.kt new file mode 100644 index 0000000..ff78865 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/syslogSocketServer.kt @@ -0,0 +1,152 @@ +package dev.adamko.kafkatorio.server + +import com.github.palindromicity.syslog.AllowableDeviations +import com.github.palindromicity.syslog.SyslogParser +import com.github.palindromicity.syslog.SyslogParserBuilder +import com.github.palindromicity.syslog.SyslogSpecification +import com.github.palindromicity.syslog.dsl.SyslogFieldKeys +import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.server.SyslogMsg.Companion.toSyslogMsg +import io.ktor.network.selector.SelectorManager +import io.ktor.network.sockets.aSocket +import io.ktor.network.sockets.awaitClosed +import io.ktor.network.sockets.openReadChannel +import io.ktor.server.application.Application +import io.ktor.utils.io.readUTF8Line +import java.util.EnumSet +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import kotlinx.coroutines.yield + + +fun Application.syslogSocketServer(appProps: ApplicationProperties) { + val server = SyslogSocketServer(appProps) + + launch { + server.start() + } +} + + +class SyslogSocketServer( + appProps: ApplicationProperties, +) { + + private val selectorManager: SelectorManager = SelectorManager(Dispatchers.IO) + + + private val serverSocketTcp = aSocket(selectorManager) + .tcp() + .bind( + appProps.socketServerHost, + appProps.socketServerPort, + ) + + + private val syslogParser: SyslogParser = SyslogParserBuilder() + .withDeviations(EnumSet.of(AllowableDeviations.PRIORITY, AllowableDeviations.VERSION)) + .forSpecification(SyslogSpecification.RFC_5424) + .build() + + + private val _messages: MutableSharedFlow = MutableSharedFlow() + val messages: SharedFlow + get() = _messages.asSharedFlow() + + + suspend fun start(): Unit = coroutineScope { + println("[SyslogSocketServer] started listening: ${serverSocketTcp.localAddress}") + + while (isActive) { + val socket = serverSocketTcp.accept() + + launch { + val channel = socket.openReadChannel() + try { + while (socket.socketContext.isActive) { + val line = runCatching { channel.readUTF8Line() }.getOrNull() + if (line != null) { + + println("[SyslogSocketServer] received: $line") + + val syslog = syslogParser.parseLine(line).toSyslogMsg() + + _messages.emit(syslog) + } + + yield() + } + } catch (e: Exception) { + socket.awaitClosed() + } + } + + yield() + } + } +} + + +data class SyslogMsg( + val src: Map +) { + + val message: String? + get() = src[SyslogFieldKeys.MESSAGE.field] + + val headerAppName: String? + get() = src[SyslogFieldKeys.HEADER_APPNAME.field] + + val headerHostName: String? + get() = src[SyslogFieldKeys.HEADER_HOSTNAME.field] + + val headerPri: String? + get() = src[SyslogFieldKeys.HEADER_PRI.field] + + val headerPriSeverity: String? + get() = src[SyslogFieldKeys.HEADER_PRI_SEVERITY.field] + + val headerPriFacility: String? + get() = src[SyslogFieldKeys.HEADER_PRI_FACILITY.field] + + val headerProcId: String? + get() = src[SyslogFieldKeys.HEADER_PROCID.field] + + val headerTimestamp: String? + get() = src[SyslogFieldKeys.HEADER_TIMESTAMP.field] + + val headerMsgId: String? + get() = src[SyslogFieldKeys.HEADER_MSGID.field] + + val headerVersion: String? + get() = src[SyslogFieldKeys.HEADER_VERSION.field] + + val structuredBase: String? + get() = src[SyslogFieldKeys.STRUCTURED_BASE.field] + + val structuredElementIdFmt: String? + get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_FMT.field] + + val structuredElementIdPnameFmt: String? + get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_PNAME_FMT.field] + + val structuredElementIdPnamePattern: String? + get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_PNAME_PATTERN.field] + + companion object { + fun Map.toSyslogMsg(): SyslogMsg { + val map = entries.mapNotNull { (k, v) -> + when (v) { + is String -> k to v + else -> null + } + }.toMap() + return SyslogMsg(map) + } + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/webmapTileServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/webmapTileServer.kt new file mode 100644 index 0000000..05853b7 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/webmapTileServer.kt @@ -0,0 +1,148 @@ +package dev.adamko.kafkatorio.server + +import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.common.PlayerIndex +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.common.TilePngFilename +import io.ktor.http.ContentType +import io.ktor.http.HttpStatusCode +import io.ktor.http.content.EntityTagVersion +import io.ktor.http.content.versions +import io.ktor.resources.Resource +import io.ktor.serialization.kotlinx.json.json +import io.ktor.server.application.Application +import io.ktor.server.application.ApplicationCall +import io.ktor.server.application.call +import io.ktor.server.application.install +import io.ktor.server.http.content.LastModifiedVersion +import io.ktor.server.plugins.autohead.AutoHeadResponse +import io.ktor.server.plugins.compression.Compression +import io.ktor.server.plugins.compression.excludeContentType +import io.ktor.server.plugins.compression.minimumSize +import io.ktor.server.plugins.conditionalheaders.ConditionalHeaders +import io.ktor.server.plugins.contentnegotiation.ContentNegotiation +import io.ktor.server.plugins.partialcontent.PartialContent +import io.ktor.server.resources.Resources +import io.ktor.server.resources.get +import io.ktor.server.response.respond +import io.ktor.server.response.respondFile +import io.ktor.server.routing.routing +import io.ktor.util.combineSafe +import io.ktor.util.pipeline.PipelineContext +import kotlin.io.path.Path +import kotlinx.serialization.Serializable + + +fun Application.webmapTileServer(appProps: ApplicationProperties) { + + install(AutoHeadResponse) + install(Compression) { + default() + minimumSize(1024) + excludeContentType(ContentType.Video.Any) + } + install(ConditionalHeaders) + install(ContentNegotiation) { + json() + } + install(PartialContent) + install(Resources) + + val server = WebmapTileServer(appProps) + + routing { + with(server) { + + get { tile -> + handleTileRequest(tile) + } + + get { + + } + } + } +} + + +private class WebmapTileServer( + private val appProps: ApplicationProperties +) { + private val serverDataDir by appProps::serverDataDir + + suspend fun PipelineContext.handleTileRequest( + tile: FactorioServers.FactorioServer.MapData.Tile + ) { + + val tileFilename = TilePngFilename( + tile.serverId, + tile.surfaceIndex, + tile.zoomLevel, + tile.chunkX, + tile.chunkY, + ) + + val tileFile = serverDataDir.combineSafe(Path(tileFilename.value)) + + if (tileFile.exists()) { + call.respondFile(tileFile) { + versions = versions + listOf( + EntityTagVersion(tileFile.lastModified().hashCode().toString()), + LastModifiedVersion(tileFile.lastModified()), + ) + } + } else { + call.respond(HttpStatusCode.NotFound) + } + } +} + + +@Serializable +@Resource("servers") +private class FactorioServers { + + @Serializable + @Resource("{factorioServerId}") + data class FactorioServer( + val factorioServerId: FactorioServerId, + ) { + + @Serializable + @Resource("map") + class MapData { + + @Serializable + @Resource("tiles/s{surfaceIndex}/z{zoomLevel}/x{chunkX}/y{chunkY}.png") + data class Tile( + val parent: FactorioServer, + val surfaceIndex: SurfaceIndex, + val zoomLevel: Int, + val chunkX: Int, + val chunkY: Int, + ) { + val serverId: FactorioServerId by parent::factorioServerId + } + + @Serializable + @Resource("buildings/s{surfaceIndex}") + data class Buildings( + val surfaceIndex: SurfaceIndex, + // a list of buildings... (Sealed interface, different types?) + ) + + } + + @Serializable + @Resource("players") + class Players { + + @Serializable + @Resource("{playerId}") + data class Id( + val playerIndex: PlayerIndex, + ) + } + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/webmapWebsocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/webmapWebsocketServer.kt new file mode 100644 index 0000000..0ae3f8c --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/webmapWebsocketServer.kt @@ -0,0 +1,130 @@ +package dev.adamko.kafkatorio.server + +import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import io.ktor.server.application.Application +import io.ktor.server.application.install +import io.ktor.server.routing.routing +import io.ktor.server.websocket.WebSockets +import io.ktor.server.websocket.webSocket +import io.ktor.websocket.DefaultWebSocketSession +import io.ktor.websocket.Frame +import io.ktor.websocket.WebSocketDeflateExtension +import io.ktor.websocket.send +import java.util.concurrent.atomic.AtomicInteger +import java.util.zip.Deflater +import kotlin.time.Duration.Companion.seconds +import kotlin.time.TimeSource +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.isActive +import kotlinx.coroutines.job +import kotlinx.coroutines.launch + + +fun Application.webmapWebsocketServer() { + install(WebSockets) { + extensions { + install(WebSocketDeflateExtension) { + // Compression level to use for java.util.zip.Deflater + compressionLevel = Deflater.DEFAULT_COMPRESSION + + // Prevent compressing small outgoing frames + compressIfBiggerThan(bytes = 4 * 1024) + } + } + } + + val wsServer = WebmapWebsocketServer() + + routing { + + webSocket("/ws") { + wsServer.bindClient(this) + } + } +} + + +private class WebmapWebsocketServer { + + private val startTime = TimeSource.Monotonic.markNow() + + private val clients: MutableStateFlow> = MutableStateFlow(emptySet()) + + private val messagesToClients: MutableSharedFlow = MutableSharedFlow( + extraBufferCapacity = Int.MAX_VALUE, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + + private val messagesFromClients: MutableSharedFlow = MutableSharedFlow( + extraBufferCapacity = Int.MAX_VALUE, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + + suspend fun bindClient(session: DefaultWebSocketSession) { + val client = WSConnection(session) + + clients.update { clients -> clients + client } + + messagesToClients.onEach { msg -> + runCatching { + client.send(msg) + } + }.launchIn(client) + + client.launch { + client.incoming.receiveAsFlow() + .collect(messagesFromClients) + } + + client.launch { + while (isActive) { + runCatching { + client.send("elapsed ${startTime.elapsedNow()}") + } + delay(10.seconds) + } + } + + client.coroutineContext.job.invokeOnCompletion { + log("client ${client.name} completed") + clients.update { clients -> clients - client } + } + } + + + suspend fun sendMessageToClients(msg: String) { + log("sending message to clients: $msg") + messagesToClients.emit(msg) + } +} + + +private data class WSConnection( + private val session: DefaultWebSocketSession, +) : DefaultWebSocketSession by session { + val name: String = "user${lastId.getAndIncrement()}" + + override suspend fun send(frame: Frame): Unit = runCatching { + super.send(frame) + }.fold( + onSuccess = { log("sent message to client $name: $frame") }, + onFailure = { log("failed to send message to client $name: $frame") } + ) + + override fun equals(other: Any?): Boolean = name == other + override fun hashCode(): Int = name.hashCode() + + companion object { + private val lastId = AtomicInteger(0) + } +} + + +private fun log(msg: String) = println("[WebmapWebsocketServer] $msg") diff --git a/modules/events-server/src/main/resources/config.yml b/modules/events-server/src/main/resources/config.yml index 0e12ff8..5c95abf 100644 --- a/modules/events-server/src/main/resources/config.yml +++ b/modules/events-server/src/main/resources/config.yml @@ -1,7 +1,7 @@ # Factorio Events Processor config web-port: ${SERVER_PORT:-8080} -tile-dir: ${TILE_DIR:-./tile-dir} +servers-data-dir: ${SERVER_DATA_DIR:-./server-data} socket-server-host: ${SOCKET_SERVER_HOST:-127.0.0.1} diff --git a/settings.gradle.kts b/settings.gradle.kts index b39fab1..80c5d2c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -3,6 +3,7 @@ rootProject.name = "kafkatorio" include( ":modules:events-mod", ":modules:events-schema", + ":modules:events-processor", ":modules:events-server", ":modules:infra-factorio-client", From c0c82e7c9c1963a97ebfd1d4d3e2be15463ac342 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 2 Jul 2022 08:45:21 +0200 Subject: [PATCH 438/629] finish migrating to ktor! - remove http4k - renamed 'schema' subproject to 'library', because it contains more than just data models - tiles are now hosted per factorio-server - changed api base to `kafkatorio/data` - tidied up some Gradle conf - remove 'events-processor' subproject - I don't want to set up loads of microservices right now --- gradle/kotlin-js-store/yarn.lock | 814 +++++++++++++++++- gradle/libs.versions.toml | 2 +- .../build.gradle.kts | 6 + .../dev/adamko/kafkatorio/library}/json.kt | 3 +- .../adamko/kafkatorio/library}/kxsBinary.kt | 2 +- .../kafkatorio/schema/common/colours.kt | 0 .../kafkatorio/schema/common/factorioIds.kt | 0 .../schema/common/factorioPrototypes.kt | 0 .../kafkatorio/schema/common/mapTile.kt | 0 .../kafkatorio/schema/common/positions.kt | 0 .../kafkatorio/schema/common/resources.kt | 0 .../schema/packets/eventServerPacket.kt | 0 .../schema/packets/kafkatorioPacket.kt | 0 .../schema/packets/kafkatorioPacketInstant.kt | 0 .../schema/packets/kafkatorioPacketKeyed.kt | 0 .../kafkatorio/events/schema/ColourHexTest.kt | 3 +- .../events/schema/MapChunkUpdateTest.kt | 0 .../events/schema/PrototypesTest.kt | 0 .../events/schema/UpdatePacketsTest.kt | 0 .../common/MapChunkPositionBoundsTest.kt | 0 .../schema/common/MapChunkPositionTest.kt | 0 .../schema/common/MapTileDictionaryTest.kt | 0 .../schema/common/MapTilePositionTest.kt | 0 .../schema/packets/EntityUpdateTest.kt | 0 .../events/schema/ValueClassTransformer.kt | 0 .../adamko/kafkatorio/events/schema/kt2ts.kt | 0 .../adamko/kafkatorio/events/schema/kt2ts2.kt | 0 .../kafkatorio/library}/FileEventsFlow.kt | 0 .../kafkatorio/library}/KxsBinaryTests.kt | 19 +- .../schema/common}/MapTileDictionaryTest.kt | 5 +- modules/events-mod/build.gradle.kts | 2 +- modules/events-processor/build.gradle.kts | 125 --- modules/events-server/.gitignore | 2 +- modules/events-server/build.gradle.kts | 23 +- .../kafkatorio/processor/eventProcessor.kt | 58 -- .../tileserver/SyslogSocketServer.kt | 328 +++---- .../processor/tileserver/WebMapTileServer.kt | 168 ++-- .../processor/tileserver/WebServer.kt | 30 +- .../processor/tileserver/WebsocketServer.kt | 280 +++--- .../config/ApplicationProperties.kt | 2 +- .../{processor => server}/config/PortVal.kt | 6 +- .../serdes => server/config}/kxsJson.kt | 5 +- .../adamko/kafkatorio/server/eventsServer.kt | 32 + .../server/kafkatorioEventsServer.kt | 38 - .../processor}/DebounceProcessor.kt | 2 +- .../processor/KafkatorioTopology.kt | 21 +- .../processor/StreamsExceptionHandler.kt | 2 +- .../processor/admin/KafkatorioKafkaAdmin.kt | 5 +- .../server/processor/eventProcessor.kt | 37 + .../processor}/kafkatorioTopics.kt | 2 +- .../processor/topology/colourMapChunks.kt | 10 +- .../topology/factorioServerPackets.kt | 9 +- .../{ => server}/processor/topology/model.kt | 2 +- .../processor/topology/packetDataStreams.kt | 6 +- .../processor/topology/prototypes.kt | 4 +- .../processor/topology/saveMapTiles.kt | 10 +- .../topology/websocketBroadcaster.kt} | 15 +- .../kafkatorio/server/socket/SyslogMsg.kt | 63 ++ .../server/socket/SyslogSocketServer.kt | 99 +++ .../kafkatorio/server/syslogSocketServer.kt | 152 ---- .../server/web/rest/factorioServersRoutes.kt | 121 +++ .../kafkatorio/server/web/rest/restApi.kt | 50 ++ .../adamko/kafkatorio/server/web/webServer.kt | 27 + .../web/websocket/WebmapWebsocketServer.kt | 112 +++ .../server/web/websocket/wsServer.kt | 34 + .../kafkatorio/server/webmapTileServer.kt | 148 ---- .../server/webmapWebsocketServer.kt | 130 --- .../src/main/resources/config.yml | 4 +- .../processor/misc/DebounceProcessorTest.kt | 49 -- .../kafkatorio/processor/misc/serdeSize.kt | 6 +- .../processor/topology/GroupMapChunksTest.kt | 6 +- .../processor/topology/SaveMapChunksTest.kt | 4 +- .../src/docker-compose.yml | 2 +- modules/web-map/build.gradle.kts | 50 +- .../dev/adamko/kafkatorio/webmap/App.kt | 9 +- .../webmap/ApplicationProperties.kt | 2 +- .../kafkatorio/webmap/externals/leaflet.kt | 1 + .../dev/adamko/kafkatorio/webmap/json.kt | 2 +- .../dev/adamko/kafkatorio/webmap/map.kt | 6 +- settings.gradle.kts | 3 +- 80 files changed, 1878 insertions(+), 1280 deletions(-) rename modules/{events-schema => events-library}/build.gradle.kts (93%) rename modules/{events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema => events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library}/json.kt (98%) rename modules/{events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes => events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library}/kxsBinary.kt (99%) rename modules/{events-schema => events-library}/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt (100%) rename modules/{events-schema => events-library}/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt (100%) rename modules/{events-schema => events-library}/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt (100%) rename modules/{events-schema => events-library}/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt (100%) rename modules/{events-schema => events-library}/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt (100%) rename modules/{events-schema => events-library}/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt (100%) rename modules/{events-schema => events-library}/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/eventServerPacket.kt (100%) rename modules/{events-schema => events-library}/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt (100%) rename modules/{events-schema => events-library}/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt (100%) rename modules/{events-schema => events-library}/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt (100%) rename modules/{events-schema => events-library}/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt (97%) rename modules/{events-schema => events-library}/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt (100%) rename modules/{events-schema => events-library}/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt (100%) rename modules/{events-schema => events-library}/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt (100%) rename modules/{events-schema => events-library}/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt (100%) rename modules/{events-schema => events-library}/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionTest.kt (100%) rename modules/{events-schema => events-library}/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt (100%) rename modules/{events-schema => events-library}/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTilePositionTest.kt (100%) rename modules/{events-schema => events-library}/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt (100%) rename modules/{events-schema => events-library}/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt (100%) rename modules/{events-schema => events-library}/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt (100%) rename modules/{events-schema => events-library}/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt (100%) rename modules/{events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc => events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/library}/FileEventsFlow.kt (100%) rename modules/{events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc => events-library/src/jvmTest/kotlin/dev/adamko/kafkatorio/library}/KxsBinaryTests.kt (97%) rename modules/{events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/serdes => events-library/src/jvmTest/kotlin/dev/adamko/kafkatorio/schema/common}/MapTileDictionaryTest.kt (89%) delete mode 100644 modules/events-processor/build.gradle.kts delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/{processor => server}/config/ApplicationProperties.kt (95%) rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/{processor => server}/config/PortVal.kt (72%) rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/{processor/serdes => server/config}/kxsJson.kt (63%) create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/kafkatorioEventsServer.kt rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/{processor/misc => server/processor}/DebounceProcessor.kt (98%) rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/{ => server}/processor/KafkatorioTopology.kt (89%) rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/{ => server}/processor/StreamsExceptionHandler.kt (91%) rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/{ => server}/processor/admin/KafkatorioKafkaAdmin.kt (91%) create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/{processor/admin => server/processor}/kafkatorioTopics.kt (98%) rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/{ => server}/processor/topology/colourMapChunks.kt (96%) rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/{ => server}/processor/topology/factorioServerPackets.kt (90%) rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/{ => server}/processor/topology/model.kt (93%) rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/{ => server}/processor/topology/packetDataStreams.kt (86%) rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/{ => server}/processor/topology/prototypes.kt (95%) rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/{ => server}/processor/topology/saveMapTiles.kt (92%) rename modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/{processor/topology/websocketBroadcast.kt => server/processor/topology/websocketBroadcaster.kt} (86%) create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogMsg.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/syslogSocketServer.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/restApi.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/webServer.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt create mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/wsServer.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/webmapTileServer.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/webmapWebsocketServer.kt delete mode 100644 modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessorTest.kt rename modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/{ => server}/processor/topology/SaveMapChunksTest.kt (98%) diff --git a/gradle/kotlin-js-store/yarn.lock b/gradle/kotlin-js-store/yarn.lock index e117ebe..bc40042 100644 --- a/gradle/kotlin-js-store/yarn.lock +++ b/gradle/kotlin-js-store/yarn.lock @@ -24,6 +24,11 @@ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.1.1.tgz#bf5d45611ab74890be386712a0e5d998c65ee2a1" integrity sha512-J/3yg2AIXc9wznaVqpHVX3Wa5jwKovVF0AMYSnbmcXTiL3PpRPfF58pzWucCwEiCJBp+hCNRLWClTomD8SseKg== +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" + integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== + "@popperjs/core@^2.11.4": version "2.11.5" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64" @@ -52,11 +57,41 @@ dependencies: html-parse-stringify "^3" +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.10" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" + integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== + dependencies: + "@types/node" "*" + "@types/component-emitter@^1.2.10": version "1.2.11" resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== +"@types/connect-history-api-fallback@^1.3.5": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" + integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + "@types/cookie@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" @@ -88,6 +123,25 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": + version "4.17.29" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz#2a1795ea8e9e9c91b4a4bbe475034b20c1ec711c" + integrity sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + "@types/geojson@7946.0.8": version "7946.0.8" resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" @@ -108,11 +162,16 @@ dependencies: "@types/node" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.8": +"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + "@types/minimatch@*": version "3.0.5" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" @@ -128,6 +187,50 @@ resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/retry@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + +"@types/serve-index@^1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" + integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== + dependencies: + "@types/express" "*" + +"@types/serve-static@*", "@types/serve-static@^1.13.10": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.33" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" + integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== + dependencies: + "@types/node" "*" + +"@types/ws@^8.5.1": + version "8.5.3" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== + dependencies: + "@types/node" "*" + "@ungap/promise-all-settled@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" @@ -286,7 +389,7 @@ abab@^2.0.5: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== -accepts@~1.3.4: +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== @@ -304,11 +407,25 @@ acorn@^8.4.1, acorn@^8.5.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== +ajv-keywords@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -319,11 +436,26 @@ ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^8.0.0, ajv@^8.8.0: + version "8.11.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" + integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + ansi-colors@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -356,6 +488,16 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-flatten@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + awesome-bootstrap-checkbox@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/awesome-bootstrap-checkbox/-/awesome-bootstrap-checkbox-1.0.1.tgz#dab10146b6001129ab0a0ec1e54bb77c6c30457a" @@ -371,12 +513,17 @@ base64id@2.0.0, base64id@~2.0.0: resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -body-parser@^1.19.0: +body-parser@1.20.0, body-parser@^1.19.0: version "1.20.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== @@ -394,6 +541,16 @@ body-parser@^1.19.0: type-is "~1.6.18" unpipe "1.0.0" +bonjour-service@^1.0.11: + version "1.0.13" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.13.tgz#4ac003dc1626023252d58adf2946f57e5da450c1" + integrity sha512-LWKRU/7EqDUC9CTAQtuZl5HzBALoCYwtLhffW3et7vZMwv3bWLpJf8bRYlMD5OCcDpTfnPgNCV4yo9ZIaJGMiA== + dependencies: + array-flatten "^2.1.2" + dns-equal "^1.0.0" + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.5" + bootstrap-icons@^1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.8.1.tgz#773c1625bcbf3e86090ea9da4386c2c6459c5582" @@ -447,6 +604,11 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" @@ -492,7 +654,7 @@ chart.js@^3.8.0: resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.8.0.tgz#c6c14c457b9dc3ce7f1514a59e9b262afd6f1a94" integrity sha512-cr8xhrXjLIXVLOBZPkBZVF6NDeiVIrPLHcMhnON7UufudL+CNeRrD+wpYanswlm8NpudMdrt3CHoLMQMxJhHRg== -chokidar@3.5.3, chokidar@^3.5.1: +chokidar@3.5.3, chokidar@^3.5.1, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -554,6 +716,11 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +colorette@^2.0.10: + version "2.0.19" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" + integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + colorette@^2.0.14: version "2.0.16" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" @@ -579,11 +746,36 @@ component-emitter@~1.3.0: resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + connect@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" @@ -594,16 +786,38 @@ connect@^3.7.0: parseurl "~1.3.3" utils-merge "1.0.1" +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + cookie@~0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + cors@~2.8.5: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" @@ -662,7 +876,7 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4.3.4, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: +debug@4.3.4, debug@^4.1.0, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -674,16 +888,38 @@ decamelize@^4.0.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + depd@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + di@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" @@ -694,6 +930,18 @@ diff@5.0.0: resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== + +dns-packet@^5.2.2: + version "5.4.0" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.4.0.tgz#1f88477cf9f27e78a213fb6d118ae38e759a879b" + integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g== + dependencies: + "@leichtgewicht/ip-codec" "^2.0.1" + dom-serialize@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" @@ -836,6 +1084,11 @@ estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + eventemitter3@^4.0.0: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -846,12 +1099,64 @@ events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +express@^4.17.3: + version "4.18.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" + integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.0" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.10.3" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + extend@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -fast-deep-equal@^3.1.1: +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== @@ -866,6 +1171,13 @@ fastest-levenshtein@^1.0.12: resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + fecha@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" @@ -891,6 +1203,19 @@ finalhandler@1.1.2: statuses "~1.5.0" unpipe "~1.0.0" +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + find-up@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" @@ -927,6 +1252,16 @@ format-util@1.0.5: resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + fs-extra@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" @@ -945,6 +1280,11 @@ fs-extra@^8.0.1: jsonfile "^4.0.0" universalify "^0.1.0" +fs-monkey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" + integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -979,6 +1319,11 @@ get-intrinsic@^1.0.2: has "^1.0.3" has-symbols "^1.0.1" +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + gettext-extract@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/gettext-extract/-/gettext-extract-2.0.1.tgz#4ade7e3d7c1c247d95a81f28059ca1923c355886" @@ -1060,6 +1405,11 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -1087,6 +1437,21 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" + integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== + html-parse-stringify@^3: version "3.0.1" resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2" @@ -1094,6 +1459,11 @@ html-parse-stringify@^3: dependencies: void-elements "3.1.0" +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== + http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -1105,7 +1475,22 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" -"http-proxy-middleware@>=2.0.6 <3.0.0", http-proxy-middleware@^2.0.6: +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + +"http-proxy-middleware@>=2.0.6 <3.0.0", http-proxy-middleware@^2.0.3, http-proxy-middleware@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== @@ -1125,6 +1510,11 @@ http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -1168,16 +1558,31 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + interpret@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -1192,6 +1597,11 @@ is-core-module@^2.8.1: dependencies: has "^1.0.3" +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -1231,11 +1641,28 @@ is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + is-unicode-supported@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + isbinaryfile@^4.0.8: version "4.0.10" resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" @@ -1282,6 +1709,11 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -1428,11 +1860,28 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= +memfs@^3.4.3: + version "3.4.7" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.7.tgz#e5252ad2242a724f938cb937e3c4f7ceb1f70e5a" + integrity sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw== + dependencies: + fs-monkey "^1.0.3" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + micromatch@^4.0.2: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" @@ -1441,23 +1890,38 @@ micromatch@^4.0.2: braces "^3.0.2" picomatch "^2.3.1" -mime-db@1.52.0: +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + mime@^2.5.2: version "2.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + minimatch@5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" @@ -1527,6 +1991,14 @@ ms@2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +multicast-dns@^7.2.5: + version "7.2.5" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" + integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== + dependencies: + dns-packet "^5.2.2" + thunky "^1.0.2" + nanoid@3.3.3, nanoid@^3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" @@ -1542,6 +2014,11 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + node-releases@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" @@ -1552,6 +2029,13 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + object-assign@^4: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -1562,6 +2046,11 @@ object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + on-finished@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -1576,6 +2065,11 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -1583,6 +2077,22 @@ once@^1.3.0: dependencies: wrappy "1" +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@^8.0.9: + version "8.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" + integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -1611,6 +2121,14 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-retry@^4.5.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" + integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== + dependencies: + "@types/retry" "0.12.0" + retry "^0.13.1" + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -1621,7 +2139,7 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== -parseurl@~1.3.3: +parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== @@ -1636,7 +2154,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-key@^3.1.0: +path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== @@ -1646,6 +2164,11 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -1718,6 +2241,19 @@ postcss@^8.4.7: picocolors "^1.0.0" source-map-js "^1.0.2" +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -1742,7 +2278,7 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -range-parser@^1.2.1: +range-parser@^1.2.1, range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== @@ -1757,6 +2293,28 @@ raw-body@2.5.1: iconv-lite "0.4.24" unpipe "1.0.0" +readable-stream@^2.0.1: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -1793,6 +2351,11 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" @@ -1819,6 +2382,11 @@ resolve@^1.9.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + rfdc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" @@ -1831,7 +2399,12 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" -safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2: +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -1850,6 +2423,28 @@ schema-utils@^3.1.0, schema-utils@^3.1.1: ajv "^6.12.5" ajv-keywords "^3.5.2" +schema-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" + integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.8.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.0.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== + +selfsigned@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" + integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ== + dependencies: + node-forge "^1" + semver@^7.3.5: version "7.3.7" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" @@ -1857,6 +2452,25 @@ semver@^7.3.5: dependencies: lru-cache "^6.0.0" +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + serialize-javascript@6.0.0, serialize-javascript@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -1864,6 +2478,34 @@ serialize-javascript@6.0.0, serialize-javascript@^6.0.0: dependencies: randombytes "^2.1.0" +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" @@ -1897,6 +2539,11 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" +signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + snabbdom@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/snabbdom/-/snabbdom-3.5.0.tgz#e75acbdedb26ea327c75028a433ba064db0ccf6e" @@ -1928,6 +2575,15 @@ socket.io@^4.4.1: socket.io-adapter "~2.4.0" socket.io-parser "~4.0.4" +sockjs@^0.3.24: + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + source-map-js@^1.0.1, source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" @@ -1960,6 +2616,29 @@ source-map@~0.7.2: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + split.js@^1.6.5: version "1.6.5" resolved "https://registry.yarnpkg.com/split.js/-/split.js-1.6.5.tgz#f7f61da1044c9984cb42947df4de4fadb5a3f300" @@ -1970,7 +2649,7 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== -statuses@~1.5.0: +"statuses@>= 1.4.0 < 2", statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= @@ -1993,6 +2672,20 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -2005,6 +2698,11 @@ strip-comments@^2.0.1: resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + strip-json-comments@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" @@ -2067,6 +2765,11 @@ terser@^5.7.2: source-map "~0.7.2" source-map-support "~0.5.20" +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + tmp@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" @@ -2131,7 +2834,7 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -util-deprecate@^1.0.2: +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= @@ -2141,7 +2844,12 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -vary@^1: +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= @@ -2164,6 +2872,13 @@ watchpack@^2.3.1: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + webpack-cli@4.10.0: version "4.10.0" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" @@ -2182,6 +2897,52 @@ webpack-cli@4.10.0: rechoir "^0.7.0" webpack-merge "^5.7.3" +webpack-dev-middleware@^5.3.1: + version "5.3.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" + integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== + dependencies: + colorette "^2.0.10" + memfs "^3.4.3" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@4.9.2: + version "4.9.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.9.2.tgz#c188db28c7bff12f87deda2a5595679ebbc3c9bc" + integrity sha512-H95Ns95dP24ZsEzO6G9iT+PNw4Q7ltll1GfJHV4fKphuHWgKFzGHWi4alTlTnpk1SPPk41X+l2RB7rLfIhnB9Q== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/serve-static" "^1.13.10" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.1" + ansi-html-community "^0.0.8" + bonjour-service "^1.0.11" + chokidar "^3.5.3" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + default-gateway "^6.0.3" + express "^4.17.3" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.3" + ipaddr.js "^2.0.1" + open "^8.0.9" + p-retry "^4.5.0" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.0.1" + serve-index "^1.9.1" + sockjs "^0.3.24" + spdy "^4.0.2" + webpack-dev-middleware "^5.3.1" + ws "^8.4.2" + webpack-merge@^4.1.5: version "4.2.2" resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" @@ -2232,6 +2993,20 @@ webpack@5.73.0: watchpack "^2.3.1" webpack-sources "^3.2.3" +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + which@^1.2.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -2270,6 +3045,11 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +ws@^8.4.2: + version "8.8.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.0.tgz#8e71c75e2f6348dbf8d78005107297056cb77769" + integrity sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ== + ws@~8.2.3: version "8.2.3" resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fab0a54..10449f7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -153,7 +153,7 @@ ktorServer-defaultHeaders = { group = "io.ktor", name = "ktor-server-defaul ktorServer-forwardedHeader = { group = "io.ktor", name = "ktor-server-forwarded-header" } ktorServer-hsts = { group = "io.ktor", name = "ktor-server-hsts" } ktorServer-httpRedirect = { group = "io.ktor", name = "ktor-server-http-redirect" } -#ktorServer-netty = { group = "io.ktor", name = "ktor-server-netty" } +ktorServer-netty = { group = "io.ktor", name = "ktor-server-netty" } ktorServer-cio = { group = "io.ktor", name = "ktor-server-cio" } ktorServer-partialContent = { group = "io.ktor", name = "ktor-server-partial-content" } ktorServer-resources = { group = "io.ktor", name = "ktor-server-resources" } diff --git a/modules/events-schema/build.gradle.kts b/modules/events-library/build.gradle.kts similarity index 93% rename from modules/events-schema/build.gradle.kts rename to modules/events-library/build.gradle.kts index 161fa87..e7ac840 100644 --- a/modules/events-schema/build.gradle.kts +++ b/modules/events-library/build.gradle.kts @@ -51,6 +51,12 @@ kotlin { implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.json) api("dev.adamko.kxstsgen:kxs-ts-gen-core:0.1.3") + + implementation(dependencies.platform(libs.okio.bom)) + implementation(libs.okio.core) + + implementation(dependencies.platform(libs.kotlinx.coroutines.bom)) + implementation(libs.kotlinx.coroutines.core) } } diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/json.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/json.kt similarity index 98% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/json.kt rename to modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/json.kt index ea57da1..ee63cc1 100644 --- a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/json.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/json.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.schema +package dev.adamko.kafkatorio.library import kotlin.reflect.KClass import kotlinx.serialization.DeserializationStrategy @@ -24,7 +24,6 @@ val jsonMapperKafkatorio = Json { serializersModule = SerializersModule { contextual(List::class) { args -> FactorioJsonListSerializer(args[0]) } } - } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/kxsBinary.kt similarity index 99% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt rename to modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/kxsBinary.kt index f474a85..723e2bc 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsBinary.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/library/kxsBinary.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.processor.serdes +package dev.adamko.kafkatorio.library import kotlinx.serialization.BinaryFormat import kotlinx.serialization.DeserializationStrategy diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt similarity index 100% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt rename to modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt similarity index 100% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt rename to modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt similarity index 100% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt rename to modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt similarity index 100% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt rename to modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt similarity index 100% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt rename to modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/positions.kt diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt similarity index 100% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt rename to modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/resources.kt diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/eventServerPacket.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/eventServerPacket.kt similarity index 100% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/eventServerPacket.kt rename to modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/eventServerPacket.kt diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt similarity index 100% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt rename to modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacket.kt diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt similarity index 100% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt rename to modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketInstant.kt diff --git a/modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt similarity index 100% rename from modules/events-schema/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt rename to modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/packets/kafkatorioPacketKeyed.kt diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt similarity index 97% rename from modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt rename to modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt index 935ca93..3279283 100644 --- a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/ColourHexTest.kt @@ -1,10 +1,10 @@ package dev.adamko.kafkatorio.events.schema +import dev.adamko.kafkatorio.library.jsonMapperKafkatorio import dev.adamko.kafkatorio.schema.common.Colour import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.toHex import dev.adamko.kafkatorio.schema.common.toPercentile -import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio import io.kotest.assertions.withClue import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.floats.shouldBeWithinPercentageOf @@ -13,6 +13,7 @@ import io.kotest.matchers.shouldBe import io.kotest.property.checkAll import kotlinx.serialization.decodeFromString + class ColourHexTest : BehaviorSpec({ Given("colour json") { diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt similarity index 100% rename from modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt rename to modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt similarity index 100% rename from modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt rename to modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt similarity index 100% rename from modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt rename to modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt similarity index 100% rename from modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt rename to modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionTest.kt similarity index 100% rename from modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionTest.kt rename to modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionTest.kt diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt similarity index 100% rename from modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt rename to modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTilePositionTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTilePositionTest.kt similarity index 100% rename from modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTilePositionTest.kt rename to modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTilePositionTest.kt diff --git a/modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt similarity index 100% rename from modules/events-schema/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt rename to modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt b/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt similarity index 100% rename from modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt rename to modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt similarity index 100% rename from modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt rename to modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt diff --git a/modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt b/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt similarity index 100% rename from modules/events-schema/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt rename to modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts2.kt diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/FileEventsFlow.kt b/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/library/FileEventsFlow.kt similarity index 100% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/FileEventsFlow.kt rename to modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/library/FileEventsFlow.kt diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt b/modules/events-library/src/jvmTest/kotlin/dev/adamko/kafkatorio/library/KxsBinaryTests.kt similarity index 97% rename from modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt rename to modules/events-library/src/jvmTest/kotlin/dev/adamko/kafkatorio/library/KxsBinaryTests.kt index eb6702c..541f243 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/KxsBinaryTests.kt +++ b/modules/events-library/src/jvmTest/kotlin/dev/adamko/kafkatorio/library/KxsBinaryTests.kt @@ -1,15 +1,12 @@ -package dev.adamko.kafkatorio.processor.misc +package dev.adamko.kafkatorio.library -import dev.adamko.kafkatorio.processor.serdes.kxsBinary import dev.adamko.kafkatorio.schema.common.ServerMapChunkId -import dev.adamko.kafkatorio.processor.topology.ServerMapChunkTiles import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapTilePosition import dev.adamko.kafkatorio.schema.common.SurfaceIndex -import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio import io.kotest.assertions.withClue import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.collections.shouldContainExactly @@ -42,6 +39,7 @@ import io.kotest.property.arbitrary.uInt import io.kotest.property.arbitrary.uLong import io.kotest.property.arbitrary.uShort import io.kotest.property.checkAll +import kotlinx.serialization.Serializable import kotlinx.serialization.builtins.serializer import kotlinx.serialization.decodeFromByteArray import kotlinx.serialization.decodeFromString @@ -316,4 +314,15 @@ class KxsBinaryTests : FunSpec({ } } } -}) +}) { + + @Serializable + data class ServerMapChunkTiles( + val chunkId: ServerMapChunkId, + val map: Map, + ) { + operator fun plus(other: ServerMapChunkTiles) = copy(map = map + other.map) + } + + +} diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/serdes/MapTileDictionaryTest.kt b/modules/events-library/src/jvmTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt similarity index 89% rename from modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/serdes/MapTileDictionaryTest.kt rename to modules/events-library/src/jvmTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt index 31addee..fdf6545 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/serdes/MapTileDictionaryTest.kt +++ b/modules/events-library/src/jvmTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt @@ -1,7 +1,6 @@ -package dev.adamko.kafkatorio.processor.serdes +package dev.adamko.kafkatorio.schema.common -import dev.adamko.kafkatorio.schema.common.MapTileDictionary -import dev.adamko.kafkatorio.schema.common.PrototypeName +import dev.adamko.kafkatorio.library.kxsBinary import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.equality.shouldBeEqualToComparingFields import kotlinx.serialization.decodeFromByteArray diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index bbfb92e..59dc28b 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -63,7 +63,7 @@ val typescriptEventsSchema: Configuration by configurations.creating { dependencies { - typescriptEventsSchema(projects.modules.eventsSchema) + typescriptEventsSchema(projects.modules.eventsLibrary) } diff --git a/modules/events-processor/build.gradle.kts b/modules/events-processor/build.gradle.kts deleted file mode 100644 index 6ccc2d3..0000000 --- a/modules/events-processor/build.gradle.kts +++ /dev/null @@ -1,125 +0,0 @@ -import dev.adamko.kafkatorio.task.KafkaConsumerGroupsTask -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - - -plugins { - dev.adamko.kafkatorio.lang.`kotlin-jvm` - kotlin("plugin.serialization") - application -} - - -description = """ - Receive raw Factorio Events from Kafka and process them into targeted topics or data formats. - - Factorio events -> Mod -> Kafka -> ***Factorio Events Processor*** -> processed events - """.trimIndent() - -val projectId: String by project.extra - -val kafkaStateDir: Directory = layout.projectDirectory.dir("kafka-state") - - -dependencies { - implementation(platform(projects.modules.versionsPlatform)) - - implementation(libs.kafka.streams) - testImplementation(libs.kafka.streamsTestUtils) - - implementation(projects.modules.eventsSchema) - -// implementation("com.ionspin.kotlin:bignum:0.3.3") - - implementation(libs.kotlinx.serialization.core) - implementation(libs.kotlinx.serialization.json) -// implementation("org.jetbrains.kotlinx:kotlinx-serialization-protobuf") - - implementation(libs.kotlinx.coroutines.core) - - implementation(libs.bundles.http4k) - implementation(libs.http4k.format.kotlinx) - - - implementation(libs.bundles.logging) - - implementation(libs.scrimage.core) - - implementation(libs.okio.core) - - - // - implementation(libs.ktorSerialization.kotlinxJson) - - with(libs.ktorServer) { - implementation(core) - implementation(callId) - implementation(callLogging) - implementation(contentNegotiaion) - implementation(cio) -// implementation(netty) - implementation(autoHeadResponse) - implementation(partialContent) - implementation(resources) - implementation(statusPages) - implementation(websockets) - implementation(compression) - } - - with(libs.ktorNetwork) { - implementation(core) - implementation(tls) - } - - // - - - implementation(libs.simpleSyslogParser) - - implementation(libs.kafka.kotkaStreams) { - isChanging = false - } - - implementation(libs.bundles.hoplite) -} - - -application { - mainClass.set("dev.adamko.kafkatorio.processor.EventProcessorKt") - -// applicationDefaultJvmArgs += listOf( -// "-Dcom.sun.management.jmxremote.port=9186", -// "-Dcom.sun.management.jmxremote.rmi.port=9186", -// "-Dcom.sun.management.jmxremote.ssl=false", -// "-Dcom.sun.management.jmxremote.local.only=false", -// "-Dcom.sun.management.jmxremote.authenticate=false", -// ) -} - -tasks.withType().configureEach { - kotlinOptions.freeCompilerArgs += listOf( - "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", - "-opt-in=kotlinx.coroutines.FlowPreview", - "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", - ) -} - - -val kafkaStateDirDelete by tasks.registering(Delete::class) { - group = project.name - mustRunAfter(kafkaConsumersDelete) - delete(kafkaStateDir) -} - -val kafkaConsumersDelete by tasks.registering(KafkaConsumerGroupsTask.DeleteAll::class) { - group = project.name -} - -//tasks.run.configure { -// dependsOn(kafkatorioEventsServerKafkaForceReset) -//} - -idea { - module { - excludeDirs = excludeDirs + kafkaStateDir.asFile - } -} diff --git a/modules/events-server/.gitignore b/modules/events-server/.gitignore index fe98be7..09eceef 100644 --- a/modules/events-server/.gitignore +++ b/modules/events-server/.gitignore @@ -1,2 +1,2 @@ kafka-state/ -kafkatorio-tiles/ +server-data/ diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 5cf21e9..769882a 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -1,5 +1,6 @@ import dev.adamko.kafkatorio.task.KafkaConsumerGroupsTask import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.jetbrains.kotlin.utils.addToStdlib.applyIf plugins { @@ -22,9 +23,7 @@ dependencies { implementation(libs.kafka.streams) testImplementation(libs.kafka.streamsTestUtils) - implementation(projects.modules.eventsSchema) - -// implementation("com.ionspin.kotlin:bignum:0.3.3") + implementation(projects.modules.eventsLibrary) implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.json) @@ -32,17 +31,12 @@ dependencies { implementation(libs.kotlinx.coroutines.core) - implementation(libs.bundles.http4k) - implementation(libs.http4k.format.kotlinx) - - implementation(libs.bundles.logging) implementation(libs.scrimage.core) implementation(libs.okio.core) - // implementation(libs.ktorSerialization.kotlinxJson) @@ -81,15 +75,7 @@ dependencies { application { // mainClass.set("dev.adamko.kafkatorio.processor.EventProcessorKt") - mainClass.set("dev.adamko.kafkatorio.server.KafkatorioEventsServerKt") - -// applicationDefaultJvmArgs += listOf( -// "-Dcom.sun.management.jmxremote.port=9186", -// "-Dcom.sun.management.jmxremote.rmi.port=9186", -// "-Dcom.sun.management.jmxremote.ssl=false", -// "-Dcom.sun.management.jmxremote.local.only=false", -// "-Dcom.sun.management.jmxremote.authenticate=false", -// ) + mainClass.set("dev.adamko.kafkatorio.server.EventsServerKt") } tasks.withType().configureEach { @@ -111,9 +97,6 @@ val kafkaConsumersDelete by tasks.registering(KafkaConsumerGroupsTask.DeleteAll: group = project.name } -//tasks.run.configure { -// dependsOn(kafkatorioEventsServerKafkaForceReset) -//} idea { module { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt deleted file mode 100644 index ae1e860..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/eventProcessor.kt +++ /dev/null @@ -1,58 +0,0 @@ -package dev.adamko.kafkatorio.processor - - -import dev.adamko.kafkatorio.processor.admin.KafkatorioKafkaAdmin -import dev.adamko.kafkatorio.processor.config.ApplicationProperties -import dev.adamko.kafkatorio.processor.tileserver.SyslogSocketServer -import dev.adamko.kafkatorio.processor.tileserver.WebMapTileServer -import dev.adamko.kafkatorio.processor.tileserver.WebsocketServer -import dev.adamko.kafkatorio.processor.tileserver.webServer -import kotlinx.coroutines.awaitCancellation -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.currentCoroutineContext -import kotlinx.coroutines.job -import kotlinx.coroutines.launch -import org.http4k.server.Http4kServer - - -suspend fun main() { - - val appProps = ApplicationProperties.load() - - val admin = KafkatorioKafkaAdmin(appProps) - admin.createKafkatorioTopics() - - - val syslogServer = SyslogSocketServer(appProps) - val wsServer = WebsocketServer() - val tileServer = WebMapTileServer(appProps) - val topology = KafkatorioTopology(appProps, wsServer, syslogServer) - - coroutineScope { - launch { - syslogServer.start() - } - - launch { - topology.start() - - println("launched KafkatorioTopology") - - awaitCancellation() - } - - launch { - val webServer: Http4kServer = webServer(tileServer, wsServer, appProps) - - currentCoroutineContext().job.invokeOnCompletion { - println("webserver stopping. Cause: $it") - webServer.stop() - } - - webServer.start() - println("launched webserver port:${webServer.port()}") - - awaitCancellation() - } - } -} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/SyslogSocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/SyslogSocketServer.kt index 4a1da1c..3c4a87a 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/SyslogSocketServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/SyslogSocketServer.kt @@ -1,168 +1,168 @@ package dev.adamko.kafkatorio.processor.tileserver -import com.github.palindromicity.syslog.AllowableDeviations -import com.github.palindromicity.syslog.SyslogParser -import com.github.palindromicity.syslog.SyslogParserBuilder -import com.github.palindromicity.syslog.SyslogSpecification -import com.github.palindromicity.syslog.dsl.SyslogFieldKeys -import dev.adamko.kafkatorio.processor.config.ApplicationProperties -import dev.adamko.kafkatorio.processor.tileserver.SyslogMsg.Companion.toSyslogMsg -import io.ktor.network.selector.SelectorManager -import io.ktor.network.sockets.aSocket -import io.ktor.network.sockets.awaitClosed -import io.ktor.network.sockets.openReadChannel -import io.ktor.utils.io.readUTF8Line -import java.util.EnumSet -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.SharedFlow -import kotlinx.coroutines.flow.asSharedFlow -import kotlinx.coroutines.isActive -import kotlinx.coroutines.launch -import kotlinx.coroutines.yield - - -class SyslogSocketServer( - appProps: ApplicationProperties, - dispatcher: CoroutineDispatcher = Dispatchers.IO, -) { - - private val selectorManager: SelectorManager = SelectorManager(dispatcher) - - - private val serverSocketTcp = aSocket(selectorManager) - .tcp() - .bind( - appProps.socketServerHost, - appProps.socketServerPort, - ) - - -// private val serverSocketUdp: BoundDatagramSocket = aSocket(selectorManager) -// .udp() -// .bind( -// localAddress = InetSocketAddress( -// appProps.socketServerHost, -// appProps.socketServerPortUdp, -// ), -// ) - - - private val syslogParser: SyslogParser = SyslogParserBuilder() - .withDeviations(EnumSet.of(AllowableDeviations.PRIORITY, AllowableDeviations.VERSION)) - .forSpecification(SyslogSpecification.RFC_5424) - .build() - - - private val _messages: MutableSharedFlow = MutableSharedFlow() - val messages: SharedFlow - get() = _messages.asSharedFlow() - - - suspend fun start() { -// udp() - tcp() - } - -// private suspend fun udp() { -// println("[SyslogSocketServer] started listening: ${serverSocketUdp.localAddress}") +//import com.github.palindromicity.syslog.AllowableDeviations +//import com.github.palindromicity.syslog.SyslogParser +//import com.github.palindromicity.syslog.SyslogParserBuilder +//import com.github.palindromicity.syslog.SyslogSpecification +//import com.github.palindromicity.syslog.dsl.SyslogFieldKeys +//import dev.adamko.kafkatorio.server.config.ApplicationProperties +//import dev.adamko.kafkatorio.processor.tileserver.SyslogMsg.Companion.toSyslogMsg +//import io.ktor.network.selector.SelectorManager +//import io.ktor.network.sockets.aSocket +//import io.ktor.network.sockets.awaitClosed +//import io.ktor.network.sockets.openReadChannel +//import io.ktor.utils.io.readUTF8Line +//import java.util.EnumSet +//import kotlinx.coroutines.CoroutineDispatcher +//import kotlinx.coroutines.Dispatchers +//import kotlinx.coroutines.coroutineScope +//import kotlinx.coroutines.flow.MutableSharedFlow +//import kotlinx.coroutines.flow.SharedFlow +//import kotlinx.coroutines.flow.asSharedFlow +//import kotlinx.coroutines.isActive +//import kotlinx.coroutines.launch +//import kotlinx.coroutines.yield // -// serverSocketUdp.incoming -// .receiveAsFlow() -// .map {udpPacket: Datagram -> -// val msg = udpPacket.packet.readText() -// println("[SyslogSocketServer] received msg: $msg") -// syslogParser.parseLine(msg).toSyslogMsg() -// }.collect(_messages) +// +//class SyslogSocketServer( +// appProps: ApplicationProperties, +// dispatcher: CoroutineDispatcher = Dispatchers.IO, +//) { +// +// private val selectorManager: SelectorManager = SelectorManager(dispatcher) +// +// +// private val serverSocketTcp = aSocket(selectorManager) +// .tcp() +// .bind( +// appProps.socketServerHost, +// appProps.socketServerPort, +// ) +// +// +//// private val serverSocketUdp: BoundDatagramSocket = aSocket(selectorManager) +//// .udp() +//// .bind( +//// localAddress = InetSocketAddress( +//// appProps.socketServerHost, +//// appProps.socketServerPortUdp, +//// ), +//// ) +// +// +// private val syslogParser: SyslogParser = SyslogParserBuilder() +// .withDeviations(EnumSet.of(AllowableDeviations.PRIORITY, AllowableDeviations.VERSION)) +// .forSpecification(SyslogSpecification.RFC_5424) +// .build() +// +// +// private val _messages: MutableSharedFlow = MutableSharedFlow() +// val messages: SharedFlow +// get() = _messages.asSharedFlow() +// +// +// suspend fun start() { +//// udp() +// tcp() // } - - private suspend fun tcp() = coroutineScope { - println("[SyslogSocketServer] started listening: ${serverSocketTcp.localAddress}") - - while (isActive) { - val socket = serverSocketTcp.accept() - - launch { - val channel = socket.openReadChannel() - try { - while (socket.socketContext.isActive) { - val line = channel.readUTF8Line() - println("[SyslogSocketServer] received: $line") - - val syslog = syslogParser.parseLine(line).toSyslogMsg() - - _messages.emit(syslog) - - yield() - } - } catch (e: Exception) { - socket.awaitClosed() - } - } - } - - yield() - } -} - - -data class SyslogMsg( - val src: Map -) { - - val message: String? - get() = src[SyslogFieldKeys.MESSAGE.field] - - val headerAppName: String? - get() = src[SyslogFieldKeys.HEADER_APPNAME.field] - - val headerHostName: String? - get() = src[SyslogFieldKeys.HEADER_HOSTNAME.field] - - val headerPri: String? - get() = src[SyslogFieldKeys.HEADER_PRI.field] - - val headerPriSeverity: String? - get() = src[SyslogFieldKeys.HEADER_PRI_SEVERITY.field] - - val headerPriFacility: String? - get() = src[SyslogFieldKeys.HEADER_PRI_FACILITY.field] - - val headerProcId: String? - get() = src[SyslogFieldKeys.HEADER_PROCID.field] - - val headerTimestamp: String? - get() = src[SyslogFieldKeys.HEADER_TIMESTAMP.field] - - val headerMsgId: String? - get() = src[SyslogFieldKeys.HEADER_MSGID.field] - - val headerVersion: String? - get() = src[SyslogFieldKeys.HEADER_VERSION.field] - - val structuredBase: String? - get() = src[SyslogFieldKeys.STRUCTURED_BASE.field] - - val structuredElementIdFmt: String? - get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_FMT.field] - - val structuredElementIdPnameFmt: String? - get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_PNAME_FMT.field] - - val structuredElementIdPnamePattern: String? - get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_PNAME_PATTERN.field] - - companion object { - fun Map.toSyslogMsg(): SyslogMsg { - val map = entries.mapNotNull { (k, v) -> - when (v) { - is String -> k to v - else -> null - } - }.toMap() - return SyslogMsg(map) - } - } -} +// +//// private suspend fun udp() { +//// println("[SyslogSocketServer] started listening: ${serverSocketUdp.localAddress}") +//// +//// serverSocketUdp.incoming +//// .receiveAsFlow() +//// .map {udpPacket: Datagram -> +//// val msg = udpPacket.packet.readText() +//// println("[SyslogSocketServer] received msg: $msg") +//// syslogParser.parseLine(msg).toSyslogMsg() +//// }.collect(_messages) +//// } +// +// private suspend fun tcp() = coroutineScope { +// println("[SyslogSocketServer] started listening: ${serverSocketTcp.localAddress}") +// +// while (isActive) { +// val socket = serverSocketTcp.accept() +// +// launch { +// val channel = socket.openReadChannel() +// try { +// while (socket.socketContext.isActive) { +// val line = channel.readUTF8Line() +// println("[SyslogSocketServer] received: $line") +// +// val syslog = syslogParser.parseLine(line).toSyslogMsg() +// +// _messages.emit(syslog) +// +// yield() +// } +// } catch (e: Exception) { +// socket.awaitClosed() +// } +// } +// } +// +// yield() +// } +//} +// +// +//data class SyslogMsg( +// val src: Map +//) { +// +// val message: String? +// get() = src[SyslogFieldKeys.MESSAGE.field] +// +// val headerAppName: String? +// get() = src[SyslogFieldKeys.HEADER_APPNAME.field] +// +// val headerHostName: String? +// get() = src[SyslogFieldKeys.HEADER_HOSTNAME.field] +// +// val headerPri: String? +// get() = src[SyslogFieldKeys.HEADER_PRI.field] +// +// val headerPriSeverity: String? +// get() = src[SyslogFieldKeys.HEADER_PRI_SEVERITY.field] +// +// val headerPriFacility: String? +// get() = src[SyslogFieldKeys.HEADER_PRI_FACILITY.field] +// +// val headerProcId: String? +// get() = src[SyslogFieldKeys.HEADER_PROCID.field] +// +// val headerTimestamp: String? +// get() = src[SyslogFieldKeys.HEADER_TIMESTAMP.field] +// +// val headerMsgId: String? +// get() = src[SyslogFieldKeys.HEADER_MSGID.field] +// +// val headerVersion: String? +// get() = src[SyslogFieldKeys.HEADER_VERSION.field] +// +// val structuredBase: String? +// get() = src[SyslogFieldKeys.STRUCTURED_BASE.field] +// +// val structuredElementIdFmt: String? +// get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_FMT.field] +// +// val structuredElementIdPnameFmt: String? +// get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_PNAME_FMT.field] +// +// val structuredElementIdPnamePattern: String? +// get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_PNAME_PATTERN.field] +// +// companion object { +// fun Map.toSyslogMsg(): SyslogMsg { +// val map = entries.mapNotNull { (k, v) -> +// when (v) { +// is String -> k to v +// else -> null +// } +// }.toMap() +// return SyslogMsg(map) +// } +// } +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt index e64335f..3f488e5 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt @@ -1,86 +1,86 @@ package dev.adamko.kafkatorio.processor.tileserver -import dev.adamko.kafkatorio.processor.config.ApplicationProperties -import java.security.MessageDigest -import org.http4k.core.Filter -import org.http4k.core.HttpHandler -import org.http4k.core.MemoryBody -import org.http4k.core.Method.GET -import org.http4k.core.Request -import org.http4k.core.Response -import org.http4k.core.Status -import org.http4k.core.then -import org.http4k.routing.ResourceLoader -import org.http4k.routing.RoutingHttpHandler -import org.http4k.routing.bind -import org.http4k.routing.routes -import org.http4k.routing.static - -internal class WebMapTileServer( - appProps: ApplicationProperties -) { - - private val tilesLoader = ResourceLoader.Directory(appProps.serverDataDir.toFile().canonicalPath) - - - private val filters = listOf( - ETagChecker(), - ).reduce(Filter::then) - - - private val routes: RoutingHttpHandler = routes( - "/tiles" bind GET to static(tilesLoader).withFilter(filters) - ) - - - fun build(): HttpHandler { - return routes - } - - - private class ETagChecker : Filter { - - override fun invoke(next: HttpHandler): HttpHandler = { request: Request -> - val requestedETag = request.header("If-None-Match") - - var response = next(request) - val responseBytes = response.body.stream.use { it.readAllBytes() } - val currentETag = responseBytes.md5() - - response = response.body(MemoryBody(responseBytes)) - - when { - currentETag == null -> { -// println("[${request.etagKey}] currentETag is null (requested: $requestedETag), executing request") - response - .header("Cache-Control", "no-cache, max-age=0, must-revalidate") - } - requestedETag == currentETag -> { -// println("[${request.etagKey}] currentETag == requested, returning 304 $requestedETag") - Response(Status.NOT_MODIFIED) - .header("Cache-Control", "no-cache, max-age=0, must-revalidate") - } - else -> { -// println("[${request.etagKey}] currentETag != requested, executing request and adding currentETag:$currentETag (requested:$requestedETag)") - response - .header("ETag", currentETag) -// .header("Cache-Control", "no-store") - .header("Cache-Control", "no-cache, max-age=0, must-revalidate") - } - } - } - } - - - companion object { - private fun ByteArray.md5(): String? { - return if (isEmpty()) { - null - } else { - MessageDigest.getInstance("MD5") - .digest(this) - .joinToString("") { "%02x".format(it) } - } - } - } -} +//import dev.adamko.kafkatorio.processor.config.ApplicationProperties +//import java.security.MessageDigest +//import org.http4k.core.Filter +//import org.http4k.core.HttpHandler +//import org.http4k.core.MemoryBody +//import org.http4k.core.Method.GET +//import org.http4k.core.Request +//import org.http4k.core.Response +//import org.http4k.core.Status +//import org.http4k.core.then +//import org.http4k.routing.ResourceLoader +//import org.http4k.routing.RoutingHttpHandler +//import org.http4k.routing.bind +//import org.http4k.routing.routes +//import org.http4k.routing.static +// +//internal class WebMapTileServer( +// appProps: ApplicationProperties +//) { +// +// private val tilesLoader = ResourceLoader.Directory(appProps.serverDataDir.toFile().canonicalPath) +// +// +// private val filters = listOf( +// ETagChecker(), +// ).reduce(Filter::then) +// +// +// private val routes: RoutingHttpHandler = routes( +// "/tiles" bind GET to static(tilesLoader).withFilter(filters) +// ) +// +// +// fun build(): HttpHandler { +// return routes +// } +// +// +// private class ETagChecker : Filter { +// +// override fun invoke(next: HttpHandler): HttpHandler = { request: Request -> +// val requestedETag = request.header("If-None-Match") +// +// var response = next(request) +// val responseBytes = response.body.stream.use { it.readAllBytes() } +// val currentETag = responseBytes.md5() +// +// response = response.body(MemoryBody(responseBytes)) +// +// when { +// currentETag == null -> { +//// println("[${request.etagKey}] currentETag is null (requested: $requestedETag), executing request") +// response +// .header("Cache-Control", "no-cache, max-age=0, must-revalidate") +// } +// requestedETag == currentETag -> { +//// println("[${request.etagKey}] currentETag == requested, returning 304 $requestedETag") +// Response(Status.NOT_MODIFIED) +// .header("Cache-Control", "no-cache, max-age=0, must-revalidate") +// } +// else -> { +//// println("[${request.etagKey}] currentETag != requested, executing request and adding currentETag:$currentETag (requested:$requestedETag)") +// response +// .header("ETag", currentETag) +//// .header("Cache-Control", "no-store") +// .header("Cache-Control", "no-cache, max-age=0, must-revalidate") +// } +// } +// } +// } +// +// +// companion object { +// private fun ByteArray.md5(): String? { +// return if (isEmpty()) { +// null +// } else { +// MessageDigest.getInstance("MD5") +// .digest(this) +// .joinToString("") { "%02x".format(it) } +// } +// } +// } +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebServer.kt index 8533849..d72dc27 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebServer.kt @@ -1,16 +1,16 @@ package dev.adamko.kafkatorio.processor.tileserver - -import dev.adamko.kafkatorio.processor.config.ApplicationProperties -import org.http4k.server.Http4kServer -import org.http4k.server.PolyHandler -import org.http4k.server.Undertow -import org.http4k.server.asServer - -internal fun webServer( - tileServer: WebMapTileServer, - wsServer: WebsocketServer, - appProps: ApplicationProperties, -): Http4kServer = PolyHandler( - tileServer.build(), - wsServer.build(), -).asServer(Undertow(appProps.webPort())) +// +//import dev.adamko.kafkatorio.processor.config.ApplicationProperties +//import org.http4k.server.Http4kServer +//import org.http4k.server.PolyHandler +//import org.http4k.server.Undertow +//import org.http4k.server.asServer +// +//internal fun webServer( +// tileServer: WebMapTileServer, +// wsServer: WebsocketServer, +// appProps: ApplicationProperties, +//): Http4kServer = PolyHandler( +// tileServer.build(), +// wsServer.build(), +//).asServer(Undertow(appProps.webPort())) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebsocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebsocketServer.kt index d1ab9b6..dcf7bd3 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebsocketServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebsocketServer.kt @@ -1,141 +1,141 @@ package dev.adamko.kafkatorio.processor.tileserver - -import kotlin.coroutines.resume -import kotlin.coroutines.resumeWithException -import kotlin.time.Duration.Companion.seconds -import kotlin.time.TimeSource -import kotlinx.coroutines.CoroutineExceptionHandler -import kotlinx.coroutines.CoroutineName -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.withIndex -import kotlinx.coroutines.isActive -import kotlinx.coroutines.job -import kotlinx.coroutines.launch -import kotlinx.coroutines.supervisorScope -import kotlinx.coroutines.suspendCancellableCoroutine -import org.http4k.routing.bind -import org.http4k.routing.websockets -import org.http4k.websocket.Websocket -import org.http4k.websocket.WsHandler -import org.http4k.websocket.WsMessage -import org.http4k.websocket.WsStatus - - -class WebsocketServer { - - private val serverScope = CoroutineScope( - CoroutineName("WsServer") + - Dispatchers.IO + - SupervisorJob() + - CoroutineExceptionHandler { _, e -> - println("[ws.WsServer] handling exception ${e.message}") - } - ) - - - private val clients: MutableSharedFlow = MutableSharedFlow( - replay = 100, - extraBufferCapacity = 100, - BufferOverflow.DROP_OLDEST, - ) - - - private val messages: MutableSharedFlow = MutableSharedFlow( - replay = 100, - extraBufferCapacity = 100, - BufferOverflow.DROP_OLDEST, - ) - - - private fun bindClient(ws: Websocket) = serverScope.launch { - println("[ws.bindClient] ${ws.upgradeRequest.toMessage()}") - clients.emit(ws) - } - - - fun sendMessage(msg: String) = serverScope.launch { - println("[ws.sendMessage] $msg") - messages.emit(msg) - } - - - fun build(): WsHandler { - val startTime = TimeSource.Monotonic.markNow() - - serverScope.launch { - supervisorScope { - clients - .withIndex() - .onEach { (id, ws) -> - createClient(id, ws) - }.launchIn(serverScope) - } - } - - serverScope.launch { - while (isActive) { - delay(10.seconds) - sendMessage("elapsed ${startTime.elapsedNow()}") - } - } - - return websockets( - "/ws/foo" bind { ws: Websocket -> - serverScope.launch { bindClient(ws) } - } - ) - } - - - private fun createClient(id: Int, ws: Websocket) { - val clientJob = SupervisorJob(serverScope.coroutineContext.job) - - serverScope.launch(CoroutineName("ws-client-$id") + clientJob) { - launch { - suspendCancellableCoroutine { cont -> - println("[ws-client] entering suspendCancellableCoroutine") - - cont.invokeOnCancellation { e: Throwable? -> - launch { sendMessage("[ws-client.invokeOnCompletion] closing client ws ${e?.message}") } - when (e) { - null -> ws.close(WsStatus.NORMAL) - else -> ws.close(WsStatus.ABNORMAL_CLOSE) - } - } - - ws.onError { e: Throwable -> - launch { sendMessage("[ws-client.onError] client $id error [${e.message}]") } - if (!cont.isCompleted) { - cont.resumeWithException(e) - } - } - - ws.onClose { status: WsStatus -> - launch { sendMessage("[ws-client.onClose] client $id disconnected [${status}]") } - if (!cont.isCompleted) { - cont.resume(status) - } - } - - ws.onMessage { wsMsg -> - launch { sendMessage("$id says: ${wsMsg.bodyString()}") } - } - } - } - - println("[ws-client] $id listening to messages") - messages - .onEach { msg -> - println("[ws-client] sending message to $id") - ws.send(WsMessage(msg)) - }.launchIn(this) - } - } -} +// +//import kotlin.coroutines.resume +//import kotlin.coroutines.resumeWithException +//import kotlin.time.Duration.Companion.seconds +//import kotlin.time.TimeSource +//import kotlinx.coroutines.CoroutineExceptionHandler +//import kotlinx.coroutines.CoroutineName +//import kotlinx.coroutines.CoroutineScope +//import kotlinx.coroutines.Dispatchers +//import kotlinx.coroutines.SupervisorJob +//import kotlinx.coroutines.channels.BufferOverflow +//import kotlinx.coroutines.delay +//import kotlinx.coroutines.flow.MutableSharedFlow +//import kotlinx.coroutines.flow.launchIn +//import kotlinx.coroutines.flow.onEach +//import kotlinx.coroutines.flow.withIndex +//import kotlinx.coroutines.isActive +//import kotlinx.coroutines.job +//import kotlinx.coroutines.launch +//import kotlinx.coroutines.supervisorScope +//import kotlinx.coroutines.suspendCancellableCoroutine +//import org.http4k.routing.bind +//import org.http4k.routing.websockets +//import org.http4k.websocket.Websocket +//import org.http4k.websocket.WsHandler +//import org.http4k.websocket.WsMessage +//import org.http4k.websocket.WsStatus +// +// +//class WebsocketServer { +// +// private val serverScope = CoroutineScope( +// CoroutineName("WsServer") + +// Dispatchers.IO + +// SupervisorJob() + +// CoroutineExceptionHandler { _, e -> +// println("[ws.WsServer] handling exception ${e.message}") +// } +// ) +// +// +// private val clients: MutableSharedFlow = MutableSharedFlow( +// replay = 100, +// extraBufferCapacity = 100, +// BufferOverflow.DROP_OLDEST, +// ) +// +// +// private val messages: MutableSharedFlow = MutableSharedFlow( +// replay = 100, +// extraBufferCapacity = 100, +// BufferOverflow.DROP_OLDEST, +// ) +// +// +// private fun bindClient(ws: Websocket) = serverScope.launch { +// println("[ws.bindClient] ${ws.upgradeRequest.toMessage()}") +// clients.emit(ws) +// } +// +// +// fun sendMessage(msg: String) = serverScope.launch { +// println("[ws.sendMessage] $msg") +// messages.emit(msg) +// } +// +// +// fun build(): WsHandler { +// val startTime = TimeSource.Monotonic.markNow() +// +// serverScope.launch { +// supervisorScope { +// clients +// .withIndex() +// .onEach { (id, ws) -> +// createClient(id, ws) +// }.launchIn(serverScope) +// } +// } +// +// serverScope.launch { +// while (isActive) { +// delay(10.seconds) +// sendMessage("elapsed ${startTime.elapsedNow()}") +// } +// } +// +// return websockets( +// "/ws/foo" bind { ws: Websocket -> +// serverScope.launch { bindClient(ws) } +// } +// ) +// } +// +// +// private fun createClient(id: Int, ws: Websocket) { +// val clientJob = SupervisorJob(serverScope.coroutineContext.job) +// +// serverScope.launch(CoroutineName("ws-client-$id") + clientJob) { +// launch { +// suspendCancellableCoroutine { cont -> +// println("[ws-client] entering suspendCancellableCoroutine") +// +// cont.invokeOnCancellation { e: Throwable? -> +// launch { sendMessage("[ws-client.invokeOnCompletion] closing client ws ${e?.message}") } +// when (e) { +// null -> ws.close(WsStatus.NORMAL) +// else -> ws.close(WsStatus.ABNORMAL_CLOSE) +// } +// } +// +// ws.onError { e: Throwable -> +// launch { sendMessage("[ws-client.onError] client $id error [${e.message}]") } +// if (!cont.isCompleted) { +// cont.resumeWithException(e) +// } +// } +// +// ws.onClose { status: WsStatus -> +// launch { sendMessage("[ws-client.onClose] client $id disconnected [${status}]") } +// if (!cont.isCompleted) { +// cont.resume(status) +// } +// } +// +// ws.onMessage { wsMsg -> +// launch { sendMessage("$id says: ${wsMsg.bodyString()}") } +// } +// } +// } +// +// println("[ws-client] $id listening to messages") +// messages +// .onEach { msg -> +// println("[ws-client] sending message to $id") +// ws.send(WsMessage(msg)) +// }.launchIn(this) +// } +// } +//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/ApplicationProperties.kt similarity index 95% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/ApplicationProperties.kt index 204c74a..1595320 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/ApplicationProperties.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/ApplicationProperties.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.processor.config +package dev.adamko.kafkatorio.server.config import com.sksamuel.hoplite.ConfigLoaderBuilder import com.sksamuel.hoplite.addEnvironmentSource diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/PortVal.kt similarity index 72% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/PortVal.kt index e2f880d..a4c48c8 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/config/PortVal.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/PortVal.kt @@ -1,9 +1,7 @@ -package dev.adamko.kafkatorio.processor.config - -import org.http4k.cloudnative.env.Port +package dev.adamko.kafkatorio.server.config -/** Improved (slightly) version of http4k's [Port]. */ +/** Improved (slightly) version of http4k's `Port`. */ @JvmInline value class PortVal(val value: Int) { diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/kxsJson.kt similarity index 63% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/kxsJson.kt index e534e69..6dab1ed 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/serdes/kxsJson.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/config/kxsJson.kt @@ -1,8 +1,9 @@ -package dev.adamko.kafkatorio.processor.serdes +package dev.adamko.kafkatorio.server.config -import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio +import dev.adamko.kafkatorio.library.jsonMapperKafkatorio import kotlinx.serialization.json.Json + val jsonMapper: Json = Json { prettyPrint = true prettyPrintIndent = " " diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt new file mode 100644 index 0000000..681afde --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt @@ -0,0 +1,32 @@ +package dev.adamko.kafkatorio.server + +import dev.adamko.kafkatorio.server.config.ApplicationProperties +import dev.adamko.kafkatorio.server.socket.SyslogSocketServer +import dev.adamko.kafkatorio.server.web.startWebServer +import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch + + +suspend fun main(): Unit = coroutineScope { + + val appProps = ApplicationProperties.load() + + val websocketServer = WebmapWebsocketServer() + val syslogSocketServer = SyslogSocketServer(appProps) + + launch { + startWebServer(appProps, websocketServer) + } + + + launch { + syslogSocketServer.start() + } + + +// launch(Dispatchers.Default.limitedParallelism(2)) { +// eventsProcessor(appProps, syslogSocketServer, websocketServer) +// } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/kafkatorioEventsServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/kafkatorioEventsServer.kt deleted file mode 100644 index a8cd36c..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/kafkatorioEventsServer.kt +++ /dev/null @@ -1,38 +0,0 @@ -package dev.adamko.kafkatorio.server - -import dev.adamko.kafkatorio.processor.config.ApplicationProperties -import io.ktor.http.HttpStatusCode -import io.ktor.server.application.Application -import io.ktor.server.application.install -import io.ktor.server.cio.CIO -import io.ktor.server.engine.embeddedServer -import io.ktor.server.plugins.callloging.CallLogging -import io.ktor.server.plugins.statuspages.StatusPages -import io.ktor.server.response.respondText - - -fun main() { - val appProps = ApplicationProperties.load() - - embeddedServer(CIO, port = appProps.webPort.value) { - - common() - - webmapWebsocketServer() - - webmapTileServer(appProps) - - syslogSocketServer(appProps) - - }.start(wait = true) -} - - -fun Application.common() { - install(StatusPages) { - exception { call, cause -> - call.respondText(text = "500: $cause", status = HttpStatusCode.InternalServerError) - } - } - install(CallLogging) -} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/DebounceProcessor.kt similarity index 98% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/DebounceProcessor.kt index 9502e63..de17abb 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessor.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/DebounceProcessor.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.processor.misc +package dev.adamko.kafkatorio.server.processor import dev.adamko.kotka.extensions.component1 import dev.adamko.kotka.extensions.component2 diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt similarity index 89% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt index 7df00b0..facbf6d 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/KafkatorioTopology.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/KafkatorioTopology.kt @@ -1,15 +1,12 @@ -package dev.adamko.kafkatorio.processor +package dev.adamko.kafkatorio.server.processor import com.github.palindromicity.syslog.dsl.SyslogFieldKeys -import dev.adamko.kafkatorio.processor.admin.TOPIC_SRC_SERVER_LOG -import dev.adamko.kafkatorio.processor.config.ApplicationProperties -import dev.adamko.kafkatorio.processor.tileserver.SyslogSocketServer -import dev.adamko.kafkatorio.processor.tileserver.WebsocketServer -import dev.adamko.kafkatorio.processor.topology.broadcastToWebsocket -import dev.adamko.kafkatorio.processor.topology.colourMapChunks -import dev.adamko.kafkatorio.processor.topology.factorioServerPacketStream -import dev.adamko.kafkatorio.processor.topology.saveMapTiles -import dev.adamko.kafkatorio.processor.topology.splitFactorioServerPacketStream +import dev.adamko.kafkatorio.server.config.ApplicationProperties +import dev.adamko.kafkatorio.server.processor.topology.colourMapChunks +import dev.adamko.kafkatorio.server.processor.topology.* +import dev.adamko.kafkatorio.server.socket.SyslogSocketServer +import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer +import dev.adamko.kafkatorio.server.web.websocket.broadcastToWebsocket import java.util.Properties import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException @@ -40,7 +37,7 @@ import org.apache.kafka.streams.TopologyDescription internal class KafkatorioTopology( private val appProps: ApplicationProperties, - private val websocketServer: WebsocketServer, + private val wsServer: WebmapWebsocketServer, private val syslogServer: SyslogSocketServer, ) { @@ -86,7 +83,7 @@ internal class KafkatorioTopology( private suspend fun websocketBroadcaster() { val builder = StreamsBuilder() - broadcastToWebsocket(websocketServer, builder) + broadcastToWebsocket(wsServer, builder) val topology = builder.build() diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/StreamsExceptionHandler.kt similarity index 91% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/StreamsExceptionHandler.kt index a80dd72..03f0cc3 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/StreamsExceptionHandler.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/StreamsExceptionHandler.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.processor +package dev.adamko.kafkatorio.server.processor import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler.StreamThreadExceptionResponse diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/admin/KafkatorioKafkaAdmin.kt similarity index 91% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/admin/KafkatorioKafkaAdmin.kt index 02471bb..071a52f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/KafkatorioKafkaAdmin.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/admin/KafkatorioKafkaAdmin.kt @@ -1,6 +1,7 @@ -package dev.adamko.kafkatorio.processor.admin +package dev.adamko.kafkatorio.server.processor.admin -import dev.adamko.kafkatorio.processor.config.ApplicationProperties +import dev.adamko.kafkatorio.server.processor.allTopics +import dev.adamko.kafkatorio.server.config.ApplicationProperties import java.util.concurrent.TimeUnit import mu.KotlinLogging import org.apache.kafka.clients.admin.Admin diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt new file mode 100644 index 0000000..8dc6cf1 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/eventProcessor.kt @@ -0,0 +1,37 @@ +package dev.adamko.kafkatorio.server.processor + + +import dev.adamko.kafkatorio.server.socket.SyslogSocketServer +import dev.adamko.kafkatorio.server.processor.admin.KafkatorioKafkaAdmin +import dev.adamko.kafkatorio.server.config.ApplicationProperties +import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer +import kotlinx.coroutines.awaitCancellation +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch + + +suspend fun eventsProcessor( + appProps: ApplicationProperties, + syslogServer: SyslogSocketServer, + wsServer: WebmapWebsocketServer, +): Unit = coroutineScope { + + + val admin = KafkatorioKafkaAdmin(appProps) + admin.createKafkatorioTopics() + + +// val syslogServer = SyslogSocketServer(appProps) +// val wsServer = WebsocketServer() +// val tileServer = WebMapTileServer(appProps) + val topology = KafkatorioTopology(appProps, wsServer, syslogServer) + + + launch { + topology.start() + + println("launched KafkatorioTopology") + + awaitCancellation() + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt similarity index 98% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt index 41c0206..e25ee8f 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/admin/kafkatorioTopics.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/kafkatorioTopics.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.processor.admin +package dev.adamko.kafkatorio.server.processor import dev.adamko.kafkatorio.schema.packets.ConfigurationUpdate import dev.adamko.kafkatorio.schema.packets.ConsoleChatUpdate diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt similarity index 96% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt index b790ffc..5800e33 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/colourMapChunks.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/colourMapChunks.kt @@ -1,9 +1,9 @@ -package dev.adamko.kafkatorio.processor.topology +package dev.adamko.kafkatorio.server.processor.topology -import dev.adamko.kafkatorio.processor.admin.TOPIC_MAP_CHUNK_COLOURED_032_STATE -import dev.adamko.kafkatorio.processor.admin.TOPIC_MAP_CHUNK_COLOURED_STATE -import dev.adamko.kafkatorio.processor.misc.DebounceProcessor.Companion.addDebounceProcessor -import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_032_STATE +import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_STATE +import dev.adamko.kafkatorio.server.processor.DebounceProcessor.Companion.addDebounceProcessor +import dev.adamko.kafkatorio.library.kxsBinary import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioServerId diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt similarity index 90% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt index 283f062..013f635 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/factorioServerPackets.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/factorioServerPackets.kt @@ -1,9 +1,8 @@ -package dev.adamko.kafkatorio.processor.topology +package dev.adamko.kafkatorio.server.processor.topology - -import dev.adamko.kafkatorio.processor.admin.TOPIC_SRC_SERVER_LOG -import dev.adamko.kafkatorio.processor.admin.topicName -import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.server.processor.TOPIC_SRC_SERVER_LOG +import dev.adamko.kafkatorio.server.processor.topicName +import dev.adamko.kafkatorio.server.config.jsonMapper import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/model.kt similarity index 93% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/model.kt index 558ecf0..72aa0ca 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/model.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/model.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.processor.topology +package dev.adamko.kafkatorio.server.processor.topology import com.sksamuel.scrimage.color.RGBColor import dev.adamko.kafkatorio.schema.common.ColourHex diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/packetDataStreams.kt similarity index 86% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/packetDataStreams.kt index 6ada2be..67a882a 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/packetDataStreams.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/packetDataStreams.kt @@ -1,7 +1,7 @@ -package dev.adamko.kafkatorio.processor.topology +package dev.adamko.kafkatorio.server.processor.topology -import dev.adamko.kafkatorio.processor.admin.topicName -import dev.adamko.kafkatorio.processor.serdes.jsonMapper +import dev.adamko.kafkatorio.server.processor.topicName +import dev.adamko.kafkatorio.server.config.jsonMapper import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/prototypes.kt similarity index 95% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/prototypes.kt index 85401e5..f74fab9 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/prototypes.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/prototypes.kt @@ -1,6 +1,6 @@ -package dev.adamko.kafkatorio.processor.topology +package dev.adamko.kafkatorio.server.processor.topology -import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.library.kxsBinary import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioPrototype import dev.adamko.kafkatorio.schema.common.FactorioServerId diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt similarity index 92% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt index b0da8d4..3d986dc 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/saveMapTiles.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/saveMapTiles.kt @@ -1,12 +1,12 @@ -package dev.adamko.kafkatorio.processor.topology +package dev.adamko.kafkatorio.server.processor.topology import com.sksamuel.scrimage.ImmutableImage import com.sksamuel.scrimage.ScaleMethod import com.sksamuel.scrimage.nio.PngWriter -import dev.adamko.kafkatorio.processor.admin.TOPIC_BROADCAST_TO_WEBSOCKET -import dev.adamko.kafkatorio.processor.admin.TOPIC_MAP_CHUNK_COLOURED_STATE -import dev.adamko.kafkatorio.processor.serdes.jsonMapper -import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.server.processor.TOPIC_BROADCAST_TO_WEBSOCKET +import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_STATE +import dev.adamko.kafkatorio.server.config.jsonMapper +import dev.adamko.kafkatorio.library.kxsBinary import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.ServerMapChunkId diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/websocketBroadcast.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/websocketBroadcaster.kt similarity index 86% rename from modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/websocketBroadcast.kt rename to modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/websocketBroadcaster.kt index d80cb71..6783dd1 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/topology/websocketBroadcast.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/processor/topology/websocketBroadcaster.kt @@ -1,10 +1,9 @@ -package dev.adamko.kafkatorio.processor.topology +package dev.adamko.kafkatorio.server.web.websocket -import dev.adamko.kafkatorio.processor.admin.TOPIC_BROADCAST_TO_WEBSOCKET -import dev.adamko.kafkatorio.processor.admin.topicName -import dev.adamko.kafkatorio.processor.tileserver.WebsocketServer +import dev.adamko.kafkatorio.library.jsonMapperKafkatorio +import dev.adamko.kafkatorio.server.processor.TOPIC_BROADCAST_TO_WEBSOCKET +import dev.adamko.kafkatorio.server.processor.topicName import dev.adamko.kafkatorio.schema.common.FactorioServerId -import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio import dev.adamko.kafkatorio.schema.packets.EventServerPacket import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.PlayerUpdate @@ -32,8 +31,8 @@ private const val pid = "websocketBroadcast" fun broadcastToWebsocket( - websocketServer: WebsocketServer, - builder: StreamsBuilder = StreamsBuilder(), + websocketServer: WebmapWebsocketServer, + builder: StreamsBuilder, ) { builder.broadcastKafkatorioPackets() @@ -45,7 +44,7 @@ fun broadcastToWebsocket( "$pid.websocket-server.send-message" ) { _, esPacket -> runBlocking { - websocketServer.sendMessage(jsonMapper.encodeToString(esPacket)) + websocketServer.sendMessageToClients(jsonMapper.encodeToString(esPacket)) } } } diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogMsg.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogMsg.kt new file mode 100644 index 0000000..26325e6 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogMsg.kt @@ -0,0 +1,63 @@ +package dev.adamko.kafkatorio.server.socket + +import com.github.palindromicity.syslog.dsl.SyslogFieldKeys + +data class SyslogMsg( + val src: Map +) { + + val message: String? + get() = src[SyslogFieldKeys.MESSAGE.field] + + val headerAppName: String? + get() = src[SyslogFieldKeys.HEADER_APPNAME.field] + + val headerHostName: String? + get() = src[SyslogFieldKeys.HEADER_HOSTNAME.field] + + val headerPri: String? + get() = src[SyslogFieldKeys.HEADER_PRI.field] + + val headerPriSeverity: String? + get() = src[SyslogFieldKeys.HEADER_PRI_SEVERITY.field] + + val headerPriFacility: String? + get() = src[SyslogFieldKeys.HEADER_PRI_FACILITY.field] + + val headerProcId: String? + get() = src[SyslogFieldKeys.HEADER_PROCID.field] + + val headerTimestamp: String? + get() = src[SyslogFieldKeys.HEADER_TIMESTAMP.field] + + val headerMsgId: String? + get() = src[SyslogFieldKeys.HEADER_MSGID.field] + + val headerVersion: String? + get() = src[SyslogFieldKeys.HEADER_VERSION.field] + + val structuredBase: String? + get() = src[SyslogFieldKeys.STRUCTURED_BASE.field] + + val structuredElementIdFmt: String? + get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_FMT.field] + + val structuredElementIdPnameFmt: String? + get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_PNAME_FMT.field] + + val structuredElementIdPnamePattern: String? + get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_PNAME_PATTERN.field] + + + companion object { + fun Map.toSyslogMsg(): SyslogMsg { + val map = entries.mapNotNull { (k, v) -> + when (v) { + is String -> k to v + else -> null + } + }.toMap() + return SyslogMsg(map) + } + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt new file mode 100644 index 0000000..7b518d5 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/socket/SyslogSocketServer.kt @@ -0,0 +1,99 @@ +package dev.adamko.kafkatorio.server.socket + +import com.github.palindromicity.syslog.AllowableDeviations +import com.github.palindromicity.syslog.SyslogParser +import com.github.palindromicity.syslog.SyslogParserBuilder +import com.github.palindromicity.syslog.SyslogSpecification +import dev.adamko.kafkatorio.server.config.ApplicationProperties +import dev.adamko.kafkatorio.server.socket.SyslogMsg.Companion.toSyslogMsg +import io.ktor.network.selector.SelectorManager +import io.ktor.network.sockets.Socket +import io.ktor.network.sockets.aSocket +import io.ktor.network.sockets.openReadChannel +import io.ktor.utils.io.readUTF8Line +import java.util.EnumSet +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import kotlinx.coroutines.yield + + +class SyslogSocketServer( + appProps: ApplicationProperties, +) { + + private val selectorManager: SelectorManager = SelectorManager(Dispatchers.IO) + + + private val serverSocketTcp = aSocket(selectorManager) + .tcp() + .bind( + appProps.socketServerHost, + appProps.socketServerPort, + ) + + + private val syslogParser: SyslogParser = SyslogParserBuilder() + .withDeviations(EnumSet.of(AllowableDeviations.PRIORITY, AllowableDeviations.VERSION)) + .forSpecification(SyslogSpecification.RFC_5424) + .build() + + + private val _messages: MutableSharedFlow = MutableSharedFlow() + val messages: SharedFlow + get() = _messages.asSharedFlow() + + + suspend fun start(): Unit = coroutineScope { + log("started listening: ${serverSocketTcp.localAddress}") + + while (isActive) { + val socket: Socket = serverSocketTcp.accept() + log("new socket ${socket.description()}") + + launch { + val channel = socket.openReadChannel() + try { + while (socket.socketContext.isActive) { + val line = runCatching { + channel.readUTF8Line() + }.fold( + onSuccess = { line -> + log("received '$line' from $socket") + line + }, + onFailure = { e -> + log("reading line from socket failed ${socket.description()}, cause: $e") + null + }, + ) + if (line != null) { + + val syslog = syslogParser.parseLine(line).toSyslogMsg() + + _messages.emit(syslog) + } + + yield() + } + } catch (e: Exception) { + log("closing socket ${socket.description()}, cause: $e") + withContext(Dispatchers.IO) { socket.close() } + } + } + + yield() + } + } + + companion object { + private fun log(msg: String) = println("[SyslogSocketServer] $msg") + + private fun Socket.description(): String = "Socket[local:$localAddress, remote:$remoteAddress]" + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/syslogSocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/syslogSocketServer.kt deleted file mode 100644 index ff78865..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/syslogSocketServer.kt +++ /dev/null @@ -1,152 +0,0 @@ -package dev.adamko.kafkatorio.server - -import com.github.palindromicity.syslog.AllowableDeviations -import com.github.palindromicity.syslog.SyslogParser -import com.github.palindromicity.syslog.SyslogParserBuilder -import com.github.palindromicity.syslog.SyslogSpecification -import com.github.palindromicity.syslog.dsl.SyslogFieldKeys -import dev.adamko.kafkatorio.processor.config.ApplicationProperties -import dev.adamko.kafkatorio.server.SyslogMsg.Companion.toSyslogMsg -import io.ktor.network.selector.SelectorManager -import io.ktor.network.sockets.aSocket -import io.ktor.network.sockets.awaitClosed -import io.ktor.network.sockets.openReadChannel -import io.ktor.server.application.Application -import io.ktor.utils.io.readUTF8Line -import java.util.EnumSet -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.SharedFlow -import kotlinx.coroutines.flow.asSharedFlow -import kotlinx.coroutines.isActive -import kotlinx.coroutines.launch -import kotlinx.coroutines.yield - - -fun Application.syslogSocketServer(appProps: ApplicationProperties) { - val server = SyslogSocketServer(appProps) - - launch { - server.start() - } -} - - -class SyslogSocketServer( - appProps: ApplicationProperties, -) { - - private val selectorManager: SelectorManager = SelectorManager(Dispatchers.IO) - - - private val serverSocketTcp = aSocket(selectorManager) - .tcp() - .bind( - appProps.socketServerHost, - appProps.socketServerPort, - ) - - - private val syslogParser: SyslogParser = SyslogParserBuilder() - .withDeviations(EnumSet.of(AllowableDeviations.PRIORITY, AllowableDeviations.VERSION)) - .forSpecification(SyslogSpecification.RFC_5424) - .build() - - - private val _messages: MutableSharedFlow = MutableSharedFlow() - val messages: SharedFlow - get() = _messages.asSharedFlow() - - - suspend fun start(): Unit = coroutineScope { - println("[SyslogSocketServer] started listening: ${serverSocketTcp.localAddress}") - - while (isActive) { - val socket = serverSocketTcp.accept() - - launch { - val channel = socket.openReadChannel() - try { - while (socket.socketContext.isActive) { - val line = runCatching { channel.readUTF8Line() }.getOrNull() - if (line != null) { - - println("[SyslogSocketServer] received: $line") - - val syslog = syslogParser.parseLine(line).toSyslogMsg() - - _messages.emit(syslog) - } - - yield() - } - } catch (e: Exception) { - socket.awaitClosed() - } - } - - yield() - } - } -} - - -data class SyslogMsg( - val src: Map -) { - - val message: String? - get() = src[SyslogFieldKeys.MESSAGE.field] - - val headerAppName: String? - get() = src[SyslogFieldKeys.HEADER_APPNAME.field] - - val headerHostName: String? - get() = src[SyslogFieldKeys.HEADER_HOSTNAME.field] - - val headerPri: String? - get() = src[SyslogFieldKeys.HEADER_PRI.field] - - val headerPriSeverity: String? - get() = src[SyslogFieldKeys.HEADER_PRI_SEVERITY.field] - - val headerPriFacility: String? - get() = src[SyslogFieldKeys.HEADER_PRI_FACILITY.field] - - val headerProcId: String? - get() = src[SyslogFieldKeys.HEADER_PROCID.field] - - val headerTimestamp: String? - get() = src[SyslogFieldKeys.HEADER_TIMESTAMP.field] - - val headerMsgId: String? - get() = src[SyslogFieldKeys.HEADER_MSGID.field] - - val headerVersion: String? - get() = src[SyslogFieldKeys.HEADER_VERSION.field] - - val structuredBase: String? - get() = src[SyslogFieldKeys.STRUCTURED_BASE.field] - - val structuredElementIdFmt: String? - get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_FMT.field] - - val structuredElementIdPnameFmt: String? - get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_PNAME_FMT.field] - - val structuredElementIdPnamePattern: String? - get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_PNAME_PATTERN.field] - - companion object { - fun Map.toSyslogMsg(): SyslogMsg { - val map = entries.mapNotNull { (k, v) -> - when (v) { - is String -> k to v - else -> null - } - }.toMap() - return SyslogMsg(map) - } - } -} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt new file mode 100644 index 0000000..01035d2 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/factorioServersRoutes.kt @@ -0,0 +1,121 @@ +package dev.adamko.kafkatorio.server.web.rest + +import dev.adamko.kafkatorio.schema.common.FactorioServerId +import dev.adamko.kafkatorio.schema.common.PlayerIndex +import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.schema.common.TilePngFilename +import dev.adamko.kafkatorio.server.config.ApplicationProperties +import io.ktor.http.HttpStatusCode +import io.ktor.http.content.EntityTagVersion +import io.ktor.http.content.versions +import io.ktor.resources.Resource +import io.ktor.server.application.ApplicationCall +import io.ktor.server.application.application +import io.ktor.server.application.call +import io.ktor.server.application.log +import io.ktor.server.http.content.LastModifiedVersion +import io.ktor.server.resources.get +import io.ktor.server.response.respond +import io.ktor.server.response.respondFile +import io.ktor.server.routing.Routing +import io.ktor.util.combineSafe +import io.ktor.util.pipeline.PipelineContext +import kotlin.io.path.Path +import kotlinx.serialization.Serializable + + +fun Routing.factorioServersRoutes( + appProps: ApplicationProperties, +) { + + get { + call.respond(HttpStatusCode.NotImplemented) + } + + get { tile -> + handleTileRequest(tile, appProps) + } +} + + +private suspend fun PipelineContext.handleTileRequest( + tile: FactorioServer.MapData.Tile, + appProps: ApplicationProperties, +) { + + val tileFilename = TilePngFilename( + tile.serverId, + tile.surfaceIndex, + tile.zoomLevel, + tile.chunkX, + tile.chunkY, + ) + + val tileFile = appProps.serverDataDir.combineSafe(Path(tileFilename.value)) + + if (tileFile.exists()) { + call.respondFile(tileFile) { + versions = versions + listOf( + EntityTagVersion(tileFile.lastModified().hashCode().toString()), + LastModifiedVersion(tileFile.lastModified()), + ) + } + } else { + call.respond(HttpStatusCode.NotFound) + } +} + + +@Serializable +@Resource("kafkatorio/data/servers") +private class FactorioServers + + +@Serializable +@Resource("kafkatorio/data/servers/{factorioServerId}") +data class FactorioServer( + val factorioServerId: FactorioServerId, +) { + + @Serializable + @Resource("map") + data class MapData( + val server: FactorioServer, + ) { + + @Serializable + @Resource("tiles/s{surfaceIndex}/z{zoomLevel}/x{chunkX}/y{chunkY}.png") + data class Tile( + val mapData: MapData, + val surfaceIndex: SurfaceIndex, + val zoomLevel: Int, + val chunkX: Int, + val chunkY: Int, + ) + + @Serializable + @Resource("buildings/s{surfaceIndex}") + data class Buildings( + val mapData: MapData, + val surfaceIndex: SurfaceIndex, + // a list of buildings... (Sealed interface, different types?) + ) + } + + @Serializable + @Resource("players") + data class Players( + val server: FactorioServer, + ) + + @Serializable + @Resource("{playerId}") + data class Player( + val server: FactorioServer, + val playerIndex: PlayerIndex, + ) +} + + +private val FactorioServer.MapData.Tile.serverId: FactorioServerId + get() = mapData.server.factorioServerId diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/restApi.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/restApi.kt new file mode 100644 index 0000000..8aef3a3 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/rest/restApi.kt @@ -0,0 +1,50 @@ +package dev.adamko.kafkatorio.server.web.rest + +import dev.adamko.kafkatorio.server.config.ApplicationProperties +import io.ktor.http.ContentType +import io.ktor.http.HttpStatusCode +import io.ktor.serialization.kotlinx.json.json +import io.ktor.server.application.Application +import io.ktor.server.application.install +import io.ktor.server.application.log +import io.ktor.server.plugins.autohead.AutoHeadResponse +import io.ktor.server.plugins.callloging.CallLogging +import io.ktor.server.plugins.compression.Compression +import io.ktor.server.plugins.compression.excludeContentType +import io.ktor.server.plugins.compression.minimumSize +import io.ktor.server.plugins.conditionalheaders.ConditionalHeaders +import io.ktor.server.plugins.contentnegotiation.ContentNegotiation +import io.ktor.server.plugins.partialcontent.PartialContent +import io.ktor.server.plugins.statuspages.StatusPages +import io.ktor.server.resources.Resources +import io.ktor.server.response.respondText +import io.ktor.server.routing.routing + + +fun Application.webmapTileServer(appProps: ApplicationProperties) { + + install(AutoHeadResponse) + install(CallLogging) + install(Compression) { + default() + minimumSize(1024) + excludeContentType(ContentType.Video.Any) + } + install(ConditionalHeaders) + install(ContentNegotiation) { + json() + } + install(PartialContent) + install(Resources) + + install(StatusPages) { + exception { call, cause -> + this@webmapTileServer.log.error("$call caused exception - returning 500", cause) + call.respondText(text = "500: $cause", status = HttpStatusCode.InternalServerError) + } + } + + routing { + factorioServersRoutes(appProps) + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/webServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/webServer.kt new file mode 100644 index 0000000..4fe626e --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/webServer.kt @@ -0,0 +1,27 @@ +package dev.adamko.kafkatorio.server.web + +import dev.adamko.kafkatorio.server.config.ApplicationProperties +import dev.adamko.kafkatorio.server.web.rest.webmapTileServer +import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer +import dev.adamko.kafkatorio.server.web.websocket.webmapWebsocketServer +import io.ktor.server.cio.CIO +import io.ktor.server.engine.embeddedServer +import kotlinx.coroutines.coroutineScope + + +suspend fun startWebServer( + appProps: ApplicationProperties, + wsServer: WebmapWebsocketServer, +): Unit = coroutineScope { + + embeddedServer( + factory = CIO, + port = appProps.webPort.value, + ) { + + webmapWebsocketServer(wsServer) + + webmapTileServer(appProps) + + }.start(wait = true) +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt new file mode 100644 index 0000000..560ba57 --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt @@ -0,0 +1,112 @@ +package dev.adamko.kafkatorio.server.web.websocket + +import io.ktor.websocket.DefaultWebSocketSession +import io.ktor.websocket.Frame +import io.ktor.websocket.send +import java.util.concurrent.atomic.AtomicInteger +import kotlin.time.Duration.Companion.seconds +import kotlin.time.TimeSource +import kotlinx.coroutines.awaitCancellation +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.isActive +import kotlinx.coroutines.job +import kotlinx.coroutines.launch +import kotlinx.coroutines.yield + + +class WebmapWebsocketServer { + + private val startTime = TimeSource.Monotonic.markNow() + + private val clients: MutableStateFlow> = MutableStateFlow(emptyList()) + + private val messagesToClients: MutableSharedFlow = MutableSharedFlow( + extraBufferCapacity = Int.MAX_VALUE, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + + private val messagesFromClients: MutableSharedFlow = MutableSharedFlow( + extraBufferCapacity = Int.MAX_VALUE, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + + + suspend fun bindClient(session: DefaultWebSocketSession): Unit = coroutineScope { + val client = WSConnection(session) + + clients.update { clients -> clients + client } + + client.coroutineContext.job.invokeOnCompletion { e -> + log("client ${client.name} completed ${e ?: "successfully"}") + clients.update { clients -> + (clients - client).filter { it.isActive } + } + } + + messagesToClients.onEach { msg -> + runCatching { + if (client.isActive) { + client.outgoing.send(Frame.Text(msg)) + } + } + }.launchIn(client) + + client.launch { + client.incoming.receiveAsFlow().collect(messagesFromClients) + } + +// client.launch { + while (isActive) { + runCatching { + client.send("elapsed ${startTime.elapsedNow()}") + } + delay(10.seconds) + yield() + } +// } + +// awaitCancellation() + } + + + suspend fun sendMessageToClients(msg: String) { + log("sending message to clients: $msg") + messagesToClients.emit(msg) + } + + + private data class WSConnection( + private val session: DefaultWebSocketSession, + ) : DefaultWebSocketSession by session { + val name: String = "user${lastId.getAndIncrement()}" + + override suspend fun send(frame: Frame): Unit = runCatching { + super.send(frame) + }.fold( + onSuccess = { log("sent message to client $name: $frame") }, + onFailure = { e -> log("failed to send message to client $name: $e") } + ) + + override fun equals(other: Any?): Boolean = name == other + override fun hashCode(): Int = name.hashCode() + + companion object { + private val lastId = AtomicInteger(0) + } + } + + + companion object { + + private fun log(msg: String) = println("[WebmapWebsocketServer] $msg") + + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/wsServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/wsServer.kt new file mode 100644 index 0000000..ea2b51e --- /dev/null +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/wsServer.kt @@ -0,0 +1,34 @@ +package dev.adamko.kafkatorio.server.web.websocket + +import io.ktor.server.application.Application +import io.ktor.server.application.install +import io.ktor.server.routing.routing +import io.ktor.server.websocket.WebSockets +import io.ktor.server.websocket.webSocket +import io.ktor.websocket.WebSocketDeflateExtension +import java.util.zip.Deflater + + +fun Application.webmapWebsocketServer( + wsServer: WebmapWebsocketServer, +) { + install(WebSockets) { + extensions { + install(WebSocketDeflateExtension) { + // Compression level to use for java.util.zip.Deflater + compressionLevel = Deflater.DEFAULT_COMPRESSION + + // Prevent compressing small outgoing frames + compressIfBiggerThan(bytes = 4 * 1024) + } + } + } + + routing { + // TODO only send a ws client message for a single Factorio-sever. Make the URL server specific. + // /kafkatorio/data/servers/{serverId}/ws + webSocket("kafkatorio/ws") { + wsServer.bindClient(this) + } + } +} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/webmapTileServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/webmapTileServer.kt deleted file mode 100644 index 05853b7..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/webmapTileServer.kt +++ /dev/null @@ -1,148 +0,0 @@ -package dev.adamko.kafkatorio.server - -import dev.adamko.kafkatorio.processor.config.ApplicationProperties -import dev.adamko.kafkatorio.schema.common.FactorioServerId -import dev.adamko.kafkatorio.schema.common.PlayerIndex -import dev.adamko.kafkatorio.schema.common.SurfaceIndex -import dev.adamko.kafkatorio.schema.common.TilePngFilename -import io.ktor.http.ContentType -import io.ktor.http.HttpStatusCode -import io.ktor.http.content.EntityTagVersion -import io.ktor.http.content.versions -import io.ktor.resources.Resource -import io.ktor.serialization.kotlinx.json.json -import io.ktor.server.application.Application -import io.ktor.server.application.ApplicationCall -import io.ktor.server.application.call -import io.ktor.server.application.install -import io.ktor.server.http.content.LastModifiedVersion -import io.ktor.server.plugins.autohead.AutoHeadResponse -import io.ktor.server.plugins.compression.Compression -import io.ktor.server.plugins.compression.excludeContentType -import io.ktor.server.plugins.compression.minimumSize -import io.ktor.server.plugins.conditionalheaders.ConditionalHeaders -import io.ktor.server.plugins.contentnegotiation.ContentNegotiation -import io.ktor.server.plugins.partialcontent.PartialContent -import io.ktor.server.resources.Resources -import io.ktor.server.resources.get -import io.ktor.server.response.respond -import io.ktor.server.response.respondFile -import io.ktor.server.routing.routing -import io.ktor.util.combineSafe -import io.ktor.util.pipeline.PipelineContext -import kotlin.io.path.Path -import kotlinx.serialization.Serializable - - -fun Application.webmapTileServer(appProps: ApplicationProperties) { - - install(AutoHeadResponse) - install(Compression) { - default() - minimumSize(1024) - excludeContentType(ContentType.Video.Any) - } - install(ConditionalHeaders) - install(ContentNegotiation) { - json() - } - install(PartialContent) - install(Resources) - - val server = WebmapTileServer(appProps) - - routing { - with(server) { - - get { tile -> - handleTileRequest(tile) - } - - get { - - } - } - } -} - - -private class WebmapTileServer( - private val appProps: ApplicationProperties -) { - private val serverDataDir by appProps::serverDataDir - - suspend fun PipelineContext.handleTileRequest( - tile: FactorioServers.FactorioServer.MapData.Tile - ) { - - val tileFilename = TilePngFilename( - tile.serverId, - tile.surfaceIndex, - tile.zoomLevel, - tile.chunkX, - tile.chunkY, - ) - - val tileFile = serverDataDir.combineSafe(Path(tileFilename.value)) - - if (tileFile.exists()) { - call.respondFile(tileFile) { - versions = versions + listOf( - EntityTagVersion(tileFile.lastModified().hashCode().toString()), - LastModifiedVersion(tileFile.lastModified()), - ) - } - } else { - call.respond(HttpStatusCode.NotFound) - } - } -} - - -@Serializable -@Resource("servers") -private class FactorioServers { - - @Serializable - @Resource("{factorioServerId}") - data class FactorioServer( - val factorioServerId: FactorioServerId, - ) { - - @Serializable - @Resource("map") - class MapData { - - @Serializable - @Resource("tiles/s{surfaceIndex}/z{zoomLevel}/x{chunkX}/y{chunkY}.png") - data class Tile( - val parent: FactorioServer, - val surfaceIndex: SurfaceIndex, - val zoomLevel: Int, - val chunkX: Int, - val chunkY: Int, - ) { - val serverId: FactorioServerId by parent::factorioServerId - } - - @Serializable - @Resource("buildings/s{surfaceIndex}") - data class Buildings( - val surfaceIndex: SurfaceIndex, - // a list of buildings... (Sealed interface, different types?) - ) - - } - - @Serializable - @Resource("players") - class Players { - - @Serializable - @Resource("{playerId}") - data class Id( - val playerIndex: PlayerIndex, - ) - } - } -} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/webmapWebsocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/webmapWebsocketServer.kt deleted file mode 100644 index 0ae3f8c..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/webmapWebsocketServer.kt +++ /dev/null @@ -1,130 +0,0 @@ -package dev.adamko.kafkatorio.server - -import dev.adamko.kafkatorio.processor.config.ApplicationProperties -import io.ktor.server.application.Application -import io.ktor.server.application.install -import io.ktor.server.routing.routing -import io.ktor.server.websocket.WebSockets -import io.ktor.server.websocket.webSocket -import io.ktor.websocket.DefaultWebSocketSession -import io.ktor.websocket.Frame -import io.ktor.websocket.WebSocketDeflateExtension -import io.ktor.websocket.send -import java.util.concurrent.atomic.AtomicInteger -import java.util.zip.Deflater -import kotlin.time.Duration.Companion.seconds -import kotlin.time.TimeSource -import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.receiveAsFlow -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.isActive -import kotlinx.coroutines.job -import kotlinx.coroutines.launch - - -fun Application.webmapWebsocketServer() { - install(WebSockets) { - extensions { - install(WebSocketDeflateExtension) { - // Compression level to use for java.util.zip.Deflater - compressionLevel = Deflater.DEFAULT_COMPRESSION - - // Prevent compressing small outgoing frames - compressIfBiggerThan(bytes = 4 * 1024) - } - } - } - - val wsServer = WebmapWebsocketServer() - - routing { - - webSocket("/ws") { - wsServer.bindClient(this) - } - } -} - - -private class WebmapWebsocketServer { - - private val startTime = TimeSource.Monotonic.markNow() - - private val clients: MutableStateFlow> = MutableStateFlow(emptySet()) - - private val messagesToClients: MutableSharedFlow = MutableSharedFlow( - extraBufferCapacity = Int.MAX_VALUE, - onBufferOverflow = BufferOverflow.DROP_OLDEST - ) - - private val messagesFromClients: MutableSharedFlow = MutableSharedFlow( - extraBufferCapacity = Int.MAX_VALUE, - onBufferOverflow = BufferOverflow.DROP_OLDEST - ) - - suspend fun bindClient(session: DefaultWebSocketSession) { - val client = WSConnection(session) - - clients.update { clients -> clients + client } - - messagesToClients.onEach { msg -> - runCatching { - client.send(msg) - } - }.launchIn(client) - - client.launch { - client.incoming.receiveAsFlow() - .collect(messagesFromClients) - } - - client.launch { - while (isActive) { - runCatching { - client.send("elapsed ${startTime.elapsedNow()}") - } - delay(10.seconds) - } - } - - client.coroutineContext.job.invokeOnCompletion { - log("client ${client.name} completed") - clients.update { clients -> clients - client } - } - } - - - suspend fun sendMessageToClients(msg: String) { - log("sending message to clients: $msg") - messagesToClients.emit(msg) - } -} - - -private data class WSConnection( - private val session: DefaultWebSocketSession, -) : DefaultWebSocketSession by session { - val name: String = "user${lastId.getAndIncrement()}" - - override suspend fun send(frame: Frame): Unit = runCatching { - super.send(frame) - }.fold( - onSuccess = { log("sent message to client $name: $frame") }, - onFailure = { log("failed to send message to client $name: $frame") } - ) - - override fun equals(other: Any?): Boolean = name == other - override fun hashCode(): Int = name.hashCode() - - companion object { - private val lastId = AtomicInteger(0) - } -} - - -private fun log(msg: String) = println("[WebmapWebsocketServer] $msg") diff --git a/modules/events-server/src/main/resources/config.yml b/modules/events-server/src/main/resources/config.yml index 5c95abf..a5117f3 100644 --- a/modules/events-server/src/main/resources/config.yml +++ b/modules/events-server/src/main/resources/config.yml @@ -1,11 +1,11 @@ # Factorio Events Processor config web-port: ${SERVER_PORT:-8080} -servers-data-dir: ${SERVER_DATA_DIR:-./server-data} +server-data-dir: ${SERVER_DATA_DIR:-./server-data} socket-server-host: ${SOCKET_SERVER_HOST:-127.0.0.1} -socket-server-port: ${SOCKET_SERVER_PORT:-9002} +socket-server-port: ${SOCKET_SERVER_PORT:-12092} kafka-admin-config: diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessorTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessorTest.kt deleted file mode 100644 index a8d777d..0000000 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/DebounceProcessorTest.kt +++ /dev/null @@ -1,49 +0,0 @@ -package dev.adamko.kafkatorio.processor.misc - -import io.kotest.core.spec.style.FunSpec -import io.kotest.core.spec.style.Test -import io.mockk.every -import io.mockk.mockk -import kotlin.time.Duration.Companion.minutes -import org.apache.kafka.common.serialization.Serdes -import org.apache.kafka.streams.StreamsBuilder -import org.apache.kafka.streams.Topology -import org.apache.kafka.streams.state.KeyValueIterator -import org.apache.kafka.streams.state.TimestampedKeyValueStore - -class DebounceProcessorTest : FunSpec({ - - -}) { - @Test - fun blah() { - - -// val topology = Topology() -// -// topology.addProcessor( -// "blah", -// debounceProcessor( -// 1.minutes, -// "asdasda", -// Serdes.String(), -// Serdes.String() -// ) -// ) - - -// val streamsBuilder = StreamsBuilder() -// -// streamsBuilder -// .stream("input-topic") -// .process( -// debounceProcessor( -// 1.minutes, -// "input-topic-debounce-store", -// Serdes.String(), -// Serdes.String(), -// ), -// ) - - } -} diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt index ec0591e..502ed3e 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/misc/serdeSize.kt @@ -1,14 +1,14 @@ package dev.adamko.kafkatorio.processor.misc -import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.library.kxsBinary import dev.adamko.kafkatorio.schema.common.ServerMapChunkId -import dev.adamko.kafkatorio.processor.topology.ServerMapChunkTiles import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioServerId import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapTilePosition import dev.adamko.kafkatorio.schema.common.SurfaceIndex +import dev.adamko.kafkatorio.server.processor.topology.ServerMapChunkTiles import java.util.UUID import kotlinx.serialization.encodeToByteArray import org.junit.jupiter.api.Test @@ -24,7 +24,7 @@ class Blah { serverId = FactorioServerId(UUID.randomUUID().toString()), chunkPosition = MapChunkPosition(Int.MAX_VALUE, Int.MAX_VALUE), surfaceIndex = SurfaceIndex(UInt.MAX_VALUE), - chunkSize = ChunkSize.MAX + chunkSize = ChunkSize.MAX, ), buildMap { repeat(512) { x -> diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt index 98b0138..56cb643 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/GroupMapChunksTest.kt @@ -1,8 +1,8 @@ package dev.adamko.kafkatorio.processor.topology -//import dev.adamko.kafkatorio.processor.admin.TOPIC_GROUPED_MAP_CHUNKS_STATE -//import dev.adamko.kafkatorio.processor.serdes.jsonMapper -//import dev.adamko.kafkatorio.processor.serdes.kxsBinary +//import dev.adamko.kafkatorio.server.processor.TOPIC_GROUPED_MAP_CHUNKS_STATE +//import dev.adamko.kafkatorio.processor.config.getJsonMapper +//import dev.adamko.kafkatorio.library.getKxsBinary //import dev.adamko.kafkatorio.schema.common.Colour //import dev.adamko.kafkatorio.schema.common.ColourHex //import dev.adamko.kafkatorio.schema.common.MapChunkPosition diff --git a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/SaveMapChunksTest.kt similarity index 98% rename from modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt rename to modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/SaveMapChunksTest.kt index d1a8fb5..d7a07fa 100644 --- a/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/processor/topology/SaveMapChunksTest.kt +++ b/modules/events-server/src/test/kotlin/dev/adamko/kafkatorio/server/processor/topology/SaveMapChunksTest.kt @@ -1,6 +1,6 @@ -package dev.adamko.kafkatorio.processor.topology +package dev.adamko.kafkatorio.server.processor.topology -import dev.adamko.kafkatorio.processor.serdes.kxsBinary +import dev.adamko.kafkatorio.library.kxsBinary import dev.adamko.kafkatorio.schema.common.ChunkSize import dev.adamko.kafkatorio.schema.common.ColourHex import dev.adamko.kafkatorio.schema.common.FactorioServerId diff --git a/modules/infra-factorio-server/src/docker-compose.yml b/modules/infra-factorio-server/src/docker-compose.yml index 3b12252..34fd329 100644 --- a/modules/infra-factorio-server/src/docker-compose.yml +++ b/modules/infra-factorio-server/src/docker-compose.yml @@ -19,7 +19,7 @@ services: logging: driver: syslog options: - syslog-address: "tcp://host.docker.internal:9002" + syslog-address: "tcp://host.docker.internal:12092" syslog-format: "rfc5424" # environment: diff --git a/modules/web-map/build.gradle.kts b/modules/web-map/build.gradle.kts index 8a02c87..ef2b535 100644 --- a/modules/web-map/build.gradle.kts +++ b/modules/web-map/build.gradle.kts @@ -17,23 +17,6 @@ kvision { } -rootProject.extensions.configure { - // https://github.com/rjaros/kvision/issues/410 - versions.webpackCli.version = "4.10.0" - versions.webpackDevServer.version = "4.9.2" -} - -rootProject.extensions.configure { - resolution("http-proxy-middleware", "^2.0.6") -} - -//rootProject.afterEvaluate { -// extensions.configure { -// // https://github.com/rjaros/kvision/issues/410 -// versions.webpackCli.version = "4.10.0" -// } -//} - afterEvaluate { rootProject.extensions.configure { // https://github.com/rjaros/kvision/issues/410 @@ -58,12 +41,12 @@ kotlin { open = false, port = 3000, proxy = mutableMapOf( - "/tiles" to mapOf( + "/kafkatorio/data/servers" to mapOf( "target" to "http://localhost:12080", "secure" to false, "changeOrigin" to true, ), - "/ws/foo" to mapOf( + "/kafkatorio/ws" to mapOf( "target" to "ws://localhost:12080", // "secure" to false, "ws" to true, @@ -104,12 +87,10 @@ kotlin { implementation(libs.kotlinx.coroutines.core) - implementation(projects.modules.eventsSchema) + implementation(projects.modules.eventsLibrary) implementation(libs.kotlinx.html) - implementation(projects.modules.eventsSchema) - implementation(libs.kotlinx.nodejs) implementation(libs.kotlinx.html) @@ -176,28 +157,3 @@ fun KotlinDependencyHandler.kvision( // resolution("webpack-dev-server", "4.9.1") // } //} - - -//evaluationDependsOn(rootProject.path) -//evaluationDependsOn(projects.modules.eventsSchema.dependencyProject.path) - - -//// stop warnings when building -//tasks.configureEach { -// when (name) { -// "productionExecutableCompileSync" -> -// dependsOn(taskProvider("compileProductionExecutableKotlinJs")) -// "testTestDevelopmentExecutableCompileSync" -> -// dependsOn(taskProvider("compileTestDevelopmentExecutableKotlinJs")) -//// "jsTestTestDevelopmentExecutableCompileSync" -> -//// dependsOn(taskProvider("compileTestDevelopmentExecutableKotlinFrontend")) -//// "jsProductionExecutableCompileSync" -> -//// dependsOn(taskProvider("compileProductionExecutableKotlinFrontend")) -// "browserDevelopmentRun" -> -// dependsOn(taskProvider("browserDevelopmentWebpack")) -// "browserDevelopmentWebpack" -> -// dependsOn(taskProvider("assemble")) -// "browserProductionWebpack" -> -// dependsOn(taskProvider("developmentExecutableCompileSync")) -// } -//} diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt index 6d09996..03ac670 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/App.kt @@ -77,12 +77,9 @@ class App( wsService.packetsFlow .filterIsInstance() - .onEach { - println("[packetsFlow] triggering tile refresh ${it.filename.value}") - gameState.map.refreshUpdatedTilePng( -// doc, window, - it.filename - ) + .onEach { tileSavedEvent -> + println("[packetsFlow] triggering tile refresh ${tileSavedEvent.filename.value}") + gameState.map.refreshUpdatedTilePng(tileSavedEvent.filename) }.launchIn(this) } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/ApplicationProperties.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/ApplicationProperties.kt index 38d4a7e..50fcd59 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/ApplicationProperties.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/ApplicationProperties.kt @@ -8,5 +8,5 @@ object Props { get() = window.location.href .replace("http://", "ws://") .replace("https://", "wss://") + - "ws/foo" + "kafkatorio/ws" } diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/externals/leaflet.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/externals/leaflet.kt index 0c59e22..b72d539 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/externals/leaflet.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/externals/leaflet.kt @@ -14,6 +14,7 @@ inline var TileLayer.tileOnLoad: TileOnLoadFn? } +/** @see [tileOnLoad] */ typealias TileOnLoadFn = (done: DoneCallback, tile: HTMLElement) -> Unit diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt index 7acdff3..3dd2fba 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/json.kt @@ -1,6 +1,6 @@ package dev.adamko.kafkatorio.webmap -import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio +import dev.adamko.kafkatorio.library.jsonMapperKafkatorio import kotlinx.serialization.json.Json val jsonMapper = Json { diff --git a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt index 8c40db5..9ee6b7c 100644 --- a/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt +++ b/modules/web-map/src/main/kotlin/dev/adamko/kafkatorio/webmap/map.kt @@ -31,7 +31,7 @@ import org.w3c.fetch.RequestMode class FactorioMap( - private val tileUrlTemplate: String = """/tiles/s1/z{z}/x{x}/y{y}.png""", + private val tileUrlTemplate: String = """/kafkatorio/data/servers/syslog-test/map/tiles/s1/z{z}/x{x}/y{y}.png""", ) { val kvMap: Maps = Maps { @@ -89,9 +89,7 @@ class FactorioMap( .querySelectorAll("img.leaflet-tile-loaded") .asList() .filterIsInstance() - .filter { img -> - tilePngFilename.value in img.src - } + .filter { img -> tilePngFilename.value in img.src } .forEach { img -> val imgSrc = img.src diff --git a/settings.gradle.kts b/settings.gradle.kts index 80c5d2c..b72e1b1 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,8 +2,7 @@ rootProject.name = "kafkatorio" include( ":modules:events-mod", - ":modules:events-schema", - ":modules:events-processor", + ":modules:events-library", ":modules:events-server", ":modules:infra-factorio-client", From 8c9d8e40c25176b6a830e8219a0fccf2857f553c Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 2 Jul 2022 08:54:02 +0200 Subject: [PATCH 439/629] fix websocket connection --- .../server/web/websocket/WebmapWebsocketServer.kt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt index 560ba57..3d99524 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/web/websocket/WebmapWebsocketServer.kt @@ -1,12 +1,13 @@ package dev.adamko.kafkatorio.server.web.websocket +import io.ktor.websocket.CloseReason import io.ktor.websocket.DefaultWebSocketSession import io.ktor.websocket.Frame import io.ktor.websocket.send import java.util.concurrent.atomic.AtomicInteger import kotlin.time.Duration.Companion.seconds import kotlin.time.TimeSource -import kotlinx.coroutines.awaitCancellation +import kotlinx.coroutines.cancel import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay @@ -63,7 +64,7 @@ class WebmapWebsocketServer { client.incoming.receiveAsFlow().collect(messagesFromClients) } -// client.launch { + client.launch { while (isActive) { runCatching { client.send("elapsed ${startTime.elapsedNow()}") @@ -71,9 +72,14 @@ class WebmapWebsocketServer { delay(10.seconds) yield() } -// } + } -// awaitCancellation() + log("client ${client.name} is up and running...") + val closedReason: CloseReason? = client.closeReason.await() + + log("client ${client.name} closed ${closedReason ?: "successfully"}") + + coroutineContext.cancel() } From db4350a927b6852c32996ea9b3e0764f25b7bc02 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 2 Jul 2022 08:54:38 +0200 Subject: [PATCH 440/629] re-enable kafka processor --- .../kotlin/dev/adamko/kafkatorio/server/eventsServer.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt index 681afde..1df2ddf 100644 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt +++ b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/server/eventsServer.kt @@ -1,10 +1,10 @@ package dev.adamko.kafkatorio.server import dev.adamko.kafkatorio.server.config.ApplicationProperties +import dev.adamko.kafkatorio.server.processor.eventsProcessor import dev.adamko.kafkatorio.server.socket.SyslogSocketServer import dev.adamko.kafkatorio.server.web.startWebServer import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch @@ -26,7 +26,7 @@ suspend fun main(): Unit = coroutineScope { } -// launch(Dispatchers.Default.limitedParallelism(2)) { -// eventsProcessor(appProps, syslogSocketServer, websocketServer) -// } + launch { + eventsProcessor(appProps, syslogSocketServer, websocketServer) + } } From a381e01886bbf6e7653264e7da0989e24d3b9c54 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 2 Jul 2022 09:50:11 +0200 Subject: [PATCH 441/629] move lua to src/generated, and tweak IntelliJ 'mark as excluded/src' --- modules/events-mod/build.gradle.kts | 41 +++++++++++-------- .../src/{main => generated}/lua/control.lua | 0 .../lua/generated/kafkatorio-schema.lua | 0 .../{main => generated}/lua/lualib_bundle.lua | 0 .../lua/main/PacketEmitter.lua | 0 .../lua/main/cache/EventDataCache.lua | 0 .../lua/main/commands/kafkatorioCommands.lua | 0 .../lua/main/events/configurationUpdate.lua | 0 .../lua/main/events/consoleUpdates.lua | 0 .../lua/main/events/converters.lua | 0 .../lua/main/events/entityUpdates.lua | 0 .../lua/main/events/eventTypeCheck.lua | 0 .../lua/main/events/mapChunkUpdates.lua | 0 .../lua/main/events/playerUpdates.lua | 0 .../lua/main/events/prototypeUpdates.lua | 0 .../lua/main/events/registerHandlers.lua | 0 .../lua/main/events/settingsUpdate.lua | 0 .../lua/main/events/surfaceUpdates.lua | 0 .../lua/main/global-init.lua | 0 .../lua/main/queue/queue.lua | 0 .../lua/main/settings/KafkatorioSettings.lua | 0 .../src/{main => generated}/lua/settings.lua | 0 modules/events-server/build.gradle.kts | 9 ++-- 23 files changed, 31 insertions(+), 19 deletions(-) rename modules/events-mod/src/{main => generated}/lua/control.lua (100%) rename modules/events-mod/src/{main => generated}/lua/generated/kafkatorio-schema.lua (100%) rename modules/events-mod/src/{main => generated}/lua/lualib_bundle.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/PacketEmitter.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/cache/EventDataCache.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/commands/kafkatorioCommands.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/events/configurationUpdate.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/events/consoleUpdates.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/events/converters.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/events/entityUpdates.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/events/eventTypeCheck.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/events/mapChunkUpdates.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/events/playerUpdates.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/events/prototypeUpdates.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/events/registerHandlers.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/events/settingsUpdate.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/events/surfaceUpdates.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/global-init.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/queue/queue.lua (100%) rename modules/events-mod/src/{main => generated}/lua/main/settings/KafkatorioSettings.lua (100%) rename modules/events-mod/src/{main => generated}/lua/settings.lua (100%) diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 59dc28b..6be5d7d 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -7,6 +7,8 @@ import dev.adamko.kafkatorio.gradle.typescriptAttributes import dev.adamko.kafkatorio.task.TypescriptToLuaTask import net.swiftzer.semver.SemVer import org.apache.tools.ant.filters.ReplaceTokens +import org.gradle.plugins.ide.idea.model.Module as IdeaImlModule +import org.gradle.plugins.ide.idea.model.Path as IdeaImlPath plugins { dev.adamko.kafkatorio.lang.node @@ -71,8 +73,8 @@ val typescriptToLua by tasks.registering(TypescriptToLuaTask::class) { dependsOn(tasks.npmInstall, installEventsTsSchema, tasks.updatePackageJson) sourceFiles.set(tsSrcDir) -// outputDirectory.set(layout.buildDirectory.dir("typescriptToLua")) - outputDirectory.set(layout.projectDirectory.dir("src/main/lua")) + + outputDirectory.set(layout.projectDirectory.dir("src/generated/lua")) } @@ -184,38 +186,45 @@ tasks.updatePackageJson { tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) } +val typescriptSrcDir: File = file("src/main/typescript") +val luaSrcDir: File = file("src/generated/lua") +val resourcesDir: File = file("src/main/resources") +val typescriptTestSrcDir: File = file("src/test/typescript") +val generatedSrcDir: File = file("src/generated") + + idea { module { sourceDirs.plusAssign( listOf( - file("src/main/typescript"), - file("src/main/lua"), + typescriptSrcDir, + luaSrcDir, ) ) // sourceDirs = sourceDirs + file("src/main/lua") - resourceDirs = resourceDirs + file("src/main/resources") - testSourceDirs = testSourceDirs + file("src/test/typescript") + resourceDirs = resourceDirs + resourcesDir + testSourceDirs = testSourceDirs + typescriptTestSrcDir + + generatedSourceDirs = generatedSourceDirs + generatedSrcDir +// excludeDirs = excludeDirs + generatedSrcDir - generatedSourceDirs = generatedSourceDirs + listOf( - file("src/main/lua") - ) iml { whenMerged { - require(this is org.gradle.plugins.ide.idea.model.Module) + require(this is IdeaImlModule) sourceDirs.plusAssign( listOf( - file("src/main/typescript"), - file("src/main/lua"), + typescriptSrcDir, + luaSrcDir, ) ) generatedSourceFolders.plusAssign( - org.gradle.plugins.ide.idea.model.Path(file("src/main/lua").toURI().toString()) + IdeaImlPath(luaSrcDir.toURI().toString()) ) -// sourceDirs = sourceDirs + file("src/main/typescript") - resourceDirs = resourceDirs + file("src/main/resources") - testSourceDirs = testSourceDirs + file("src/test/typescript") + resourceDirs = resourceDirs + resourcesDir + testSourceDirs = testSourceDirs + typescriptTestSrcDir +// excludeDirs = excludeDirs + generatedSrcDir } } } diff --git a/modules/events-mod/src/main/lua/control.lua b/modules/events-mod/src/generated/lua/control.lua similarity index 100% rename from modules/events-mod/src/main/lua/control.lua rename to modules/events-mod/src/generated/lua/control.lua diff --git a/modules/events-mod/src/main/lua/generated/kafkatorio-schema.lua b/modules/events-mod/src/generated/lua/generated/kafkatorio-schema.lua similarity index 100% rename from modules/events-mod/src/main/lua/generated/kafkatorio-schema.lua rename to modules/events-mod/src/generated/lua/generated/kafkatorio-schema.lua diff --git a/modules/events-mod/src/main/lua/lualib_bundle.lua b/modules/events-mod/src/generated/lua/lualib_bundle.lua similarity index 100% rename from modules/events-mod/src/main/lua/lualib_bundle.lua rename to modules/events-mod/src/generated/lua/lualib_bundle.lua diff --git a/modules/events-mod/src/main/lua/main/PacketEmitter.lua b/modules/events-mod/src/generated/lua/main/PacketEmitter.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/PacketEmitter.lua rename to modules/events-mod/src/generated/lua/main/PacketEmitter.lua diff --git a/modules/events-mod/src/main/lua/main/cache/EventDataCache.lua b/modules/events-mod/src/generated/lua/main/cache/EventDataCache.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/cache/EventDataCache.lua rename to modules/events-mod/src/generated/lua/main/cache/EventDataCache.lua diff --git a/modules/events-mod/src/main/lua/main/commands/kafkatorioCommands.lua b/modules/events-mod/src/generated/lua/main/commands/kafkatorioCommands.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/commands/kafkatorioCommands.lua rename to modules/events-mod/src/generated/lua/main/commands/kafkatorioCommands.lua diff --git a/modules/events-mod/src/main/lua/main/events/configurationUpdate.lua b/modules/events-mod/src/generated/lua/main/events/configurationUpdate.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/events/configurationUpdate.lua rename to modules/events-mod/src/generated/lua/main/events/configurationUpdate.lua diff --git a/modules/events-mod/src/main/lua/main/events/consoleUpdates.lua b/modules/events-mod/src/generated/lua/main/events/consoleUpdates.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/events/consoleUpdates.lua rename to modules/events-mod/src/generated/lua/main/events/consoleUpdates.lua diff --git a/modules/events-mod/src/main/lua/main/events/converters.lua b/modules/events-mod/src/generated/lua/main/events/converters.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/events/converters.lua rename to modules/events-mod/src/generated/lua/main/events/converters.lua diff --git a/modules/events-mod/src/main/lua/main/events/entityUpdates.lua b/modules/events-mod/src/generated/lua/main/events/entityUpdates.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/events/entityUpdates.lua rename to modules/events-mod/src/generated/lua/main/events/entityUpdates.lua diff --git a/modules/events-mod/src/main/lua/main/events/eventTypeCheck.lua b/modules/events-mod/src/generated/lua/main/events/eventTypeCheck.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/events/eventTypeCheck.lua rename to modules/events-mod/src/generated/lua/main/events/eventTypeCheck.lua diff --git a/modules/events-mod/src/main/lua/main/events/mapChunkUpdates.lua b/modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/events/mapChunkUpdates.lua rename to modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua diff --git a/modules/events-mod/src/main/lua/main/events/playerUpdates.lua b/modules/events-mod/src/generated/lua/main/events/playerUpdates.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/events/playerUpdates.lua rename to modules/events-mod/src/generated/lua/main/events/playerUpdates.lua diff --git a/modules/events-mod/src/main/lua/main/events/prototypeUpdates.lua b/modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/events/prototypeUpdates.lua rename to modules/events-mod/src/generated/lua/main/events/prototypeUpdates.lua diff --git a/modules/events-mod/src/main/lua/main/events/registerHandlers.lua b/modules/events-mod/src/generated/lua/main/events/registerHandlers.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/events/registerHandlers.lua rename to modules/events-mod/src/generated/lua/main/events/registerHandlers.lua diff --git a/modules/events-mod/src/main/lua/main/events/settingsUpdate.lua b/modules/events-mod/src/generated/lua/main/events/settingsUpdate.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/events/settingsUpdate.lua rename to modules/events-mod/src/generated/lua/main/events/settingsUpdate.lua diff --git a/modules/events-mod/src/main/lua/main/events/surfaceUpdates.lua b/modules/events-mod/src/generated/lua/main/events/surfaceUpdates.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/events/surfaceUpdates.lua rename to modules/events-mod/src/generated/lua/main/events/surfaceUpdates.lua diff --git a/modules/events-mod/src/main/lua/main/global-init.lua b/modules/events-mod/src/generated/lua/main/global-init.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/global-init.lua rename to modules/events-mod/src/generated/lua/main/global-init.lua diff --git a/modules/events-mod/src/main/lua/main/queue/queue.lua b/modules/events-mod/src/generated/lua/main/queue/queue.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/queue/queue.lua rename to modules/events-mod/src/generated/lua/main/queue/queue.lua diff --git a/modules/events-mod/src/main/lua/main/settings/KafkatorioSettings.lua b/modules/events-mod/src/generated/lua/main/settings/KafkatorioSettings.lua similarity index 100% rename from modules/events-mod/src/main/lua/main/settings/KafkatorioSettings.lua rename to modules/events-mod/src/generated/lua/main/settings/KafkatorioSettings.lua diff --git a/modules/events-mod/src/main/lua/settings.lua b/modules/events-mod/src/generated/lua/settings.lua similarity index 100% rename from modules/events-mod/src/main/lua/settings.lua rename to modules/events-mod/src/generated/lua/settings.lua diff --git a/modules/events-server/build.gradle.kts b/modules/events-server/build.gradle.kts index 769882a..a2a99f3 100644 --- a/modules/events-server/build.gradle.kts +++ b/modules/events-server/build.gradle.kts @@ -1,6 +1,5 @@ import dev.adamko.kafkatorio.task.KafkaConsumerGroupsTask import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import org.jetbrains.kotlin.utils.addToStdlib.applyIf plugins { @@ -74,10 +73,10 @@ dependencies { application { -// mainClass.set("dev.adamko.kafkatorio.processor.EventProcessorKt") mainClass.set("dev.adamko.kafkatorio.server.EventsServerKt") } + tasks.withType().configureEach { kotlinOptions.freeCompilerArgs += listOf( "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", @@ -93,6 +92,7 @@ val kafkaStateDirDelete by tasks.registering(Delete::class) { delete(kafkaStateDir) } + val kafkaConsumersDelete by tasks.registering(KafkaConsumerGroupsTask.DeleteAll::class) { group = project.name } @@ -100,6 +100,9 @@ val kafkaConsumersDelete by tasks.registering(KafkaConsumerGroupsTask.DeleteAll: idea { module { - excludeDirs = excludeDirs + kafkaStateDir.asFile + excludeDirs = excludeDirs + listOf( + kafkaStateDir.asFile, + file("server-data"), + ) } } From 79447b5936f3c8688f5a55f21a381f7e845defc0 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 2 Jul 2022 10:20:32 +0200 Subject: [PATCH 442/629] fix tests after events-lib & events-server refactor --- .../events/schema/MapChunkUpdateTest.kt | 2 +- .../events/schema/PrototypesTest.kt | 2 +- .../events/schema/UpdatePacketsTest.kt | 3 +- .../common/MapChunkPositionBoundsTest.kt | 39 ++++++++++++++++++ .../schema/packets/EntityUpdateTest.kt | 2 +- .../schema/common/MapTileDictionaryTest.kt | 40 ------------------- 6 files changed, 43 insertions(+), 45 deletions(-) delete mode 100644 modules/events-library/src/jvmTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt index 0039a91..9a3aaf9 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/MapChunkUpdateTest.kt @@ -1,12 +1,12 @@ package dev.adamko.kafkatorio.events.schema +import dev.adamko.kafkatorio.library.jsonMapperKafkatorio import dev.adamko.kafkatorio.schema.common.EventName import dev.adamko.kafkatorio.schema.common.MapChunkPosition import dev.adamko.kafkatorio.schema.common.MapTileDictionary import dev.adamko.kafkatorio.schema.common.PrototypeName import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.tick -import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate import dev.adamko.kafkatorio.schema.packets.MapChunkUpdateKey diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt index e4b4387..17387a2 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/PrototypesTest.kt @@ -1,9 +1,9 @@ package dev.adamko.kafkatorio.events.schema +import dev.adamko.kafkatorio.library.jsonMapperKafkatorio import dev.adamko.kafkatorio.schema.common.Colour import dev.adamko.kafkatorio.schema.common.FactorioPrototype import dev.adamko.kafkatorio.schema.common.PrototypeName -import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate import io.kotest.core.spec.style.BehaviorSpec diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt index 787c75d..b6249c6 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/events/schema/UpdatePacketsTest.kt @@ -1,5 +1,6 @@ package dev.adamko.kafkatorio.events.schema +import dev.adamko.kafkatorio.library.jsonMapperKafkatorio import dev.adamko.kafkatorio.schema.common.Colour import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData import dev.adamko.kafkatorio.schema.common.EventName @@ -10,8 +11,6 @@ import dev.adamko.kafkatorio.schema.common.SurfaceIndex import dev.adamko.kafkatorio.schema.common.Tick import dev.adamko.kafkatorio.schema.common.UnitNumber import dev.adamko.kafkatorio.schema.common.tick -import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio -import dev.adamko.kafkatorio.schema.packets.KafkatorioKeyedPacketData import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.schema.packets.PlayerUpdateKey diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt index 6a2a044..565818b 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/common/MapChunkPositionBoundsTest.kt @@ -1,8 +1,13 @@ package dev.adamko.kafkatorio.schema.common +import dev.adamko.kafkatorio.library.kxsBinary import io.kotest.assertions.asClue import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.collections.shouldContainExactly import io.kotest.matchers.ints.shouldBeExactly +import io.kotest.matchers.maps.shouldContainExactly +import kotlinx.serialization.decodeFromByteArray +import kotlinx.serialization.encodeToByteArray class MapChunkPositionBoundsTest : FunSpec({ @@ -95,4 +100,38 @@ class MapChunkPositionBoundsTest : FunSpec({ } } + + context("encode MapTileDictionary") { + val actual = MapTileDictionary( + tilesXY = mapOf( + "-192" to mapOf("-65" to MapTileDictionary.PrototypeKey(2)), + "161" to mapOf( + "-96" to MapTileDictionary.PrototypeKey(1), + "-95" to MapTileDictionary.PrototypeKey(2), + "94" to MapTileDictionary.PrototypeKey(2), + "93" to MapTileDictionary.PrototypeKey(32), + ), + + // unknown prototype + "44" to mapOf("1" to MapTileDictionary.PrototypeKey(44)), + ), + protos = mapOf( + PrototypeName("water") to MapTileDictionary.PrototypeKey(1), + PrototypeName("grass-4") to MapTileDictionary.PrototypeKey(2), + PrototypeName("grass-3") to MapTileDictionary.PrototypeKey(32), + + PrototypeName("not-used") to MapTileDictionary.PrototypeKey(99), + ) + ) + + test("binary round trip") { + val encoded: ByteArray = kxsBinary.encodeToByteArray(actual) + val decoded: MapTileDictionary = kxsBinary.decodeFromByteArray(encoded) + + decoded.tilesXY shouldContainExactly actual.tilesXY + decoded.protos shouldContainExactly actual.protos + + decoded.toMapTileList() shouldContainExactly actual.toMapTileList() + } + } }) diff --git a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt index 7ab5c32..47c3552 100644 --- a/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt +++ b/modules/events-library/src/commonTest/kotlin/dev/adamko/kafkatorio/schema/packets/EntityUpdateTest.kt @@ -1,6 +1,6 @@ package dev.adamko.kafkatorio.schema.packets -import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio +import dev.adamko.kafkatorio.library.jsonMapperKafkatorio import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.types.shouldBeInstanceOf import kotlinx.serialization.decodeFromString diff --git a/modules/events-library/src/jvmTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt b/modules/events-library/src/jvmTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt deleted file mode 100644 index fdf6545..0000000 --- a/modules/events-library/src/jvmTest/kotlin/dev/adamko/kafkatorio/schema/common/MapTileDictionaryTest.kt +++ /dev/null @@ -1,40 +0,0 @@ -package dev.adamko.kafkatorio.schema.common - -import dev.adamko.kafkatorio.library.kxsBinary -import io.kotest.core.spec.style.FunSpec -import io.kotest.matchers.equality.shouldBeEqualToComparingFields -import kotlinx.serialization.decodeFromByteArray -import kotlinx.serialization.encodeToByteArray - -class MapTileDictionaryTest : FunSpec({ - - context("encode MapTileDictionary") { - val actual = MapTileDictionary( - tilesXY = mapOf( - "-192" to mapOf("-65" to MapTileDictionary.PrototypeKey(2)), - "161" to mapOf( - "-96" to MapTileDictionary.PrototypeKey(1), - "-95" to MapTileDictionary.PrototypeKey(2), - "94" to MapTileDictionary.PrototypeKey(2), - "93" to MapTileDictionary.PrototypeKey(32), - ), - - // unknown prototype - "44" to mapOf("1" to MapTileDictionary.PrototypeKey(44)), - ), - protos = mapOf( - PrototypeName("water") to MapTileDictionary.PrototypeKey(1), - PrototypeName("grass-4") to MapTileDictionary.PrototypeKey(2), - PrototypeName("grass-3") to MapTileDictionary.PrototypeKey(32), - - PrototypeName("not-used") to MapTileDictionary.PrototypeKey(99), - ) - ) - - test("binary round trip") { - val encoded: ByteArray = kxsBinary.encodeToByteArray(actual) - val decoded: MapTileDictionary = kxsBinary.decodeFromByteArray(encoded) - decoded.shouldBeEqualToComparingFields(actual) - } - } -}) From b14adfb810c82d84cf7243121d30a62ec8f78890 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 2 Jul 2022 10:21:13 +0200 Subject: [PATCH 443/629] delete unused code (bye bye http4k!) --- modules/events-library/build.gradle.kts | 14 +- .../events/schema/ValueClassTransformer.kt | 94 ---------- .../adamko/kafkatorio/events/schema/kt2ts.kt | 147 --------------- .../kafkatorio/library/FileEventsFlow.kt | 2 +- .../tileserver/SyslogSocketServer.kt | 168 ------------------ .../processor/tileserver/WebMapTileServer.kt | 86 --------- .../processor/tileserver/WebServer.kt | 16 -- .../processor/tileserver/WebsocketServer.kt | 141 --------------- 8 files changed, 11 insertions(+), 657 deletions(-) delete mode 100644 modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt delete mode 100644 modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/SyslogSocketServer.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebServer.kt delete mode 100644 modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebsocketServer.kt diff --git a/modules/events-library/build.gradle.kts b/modules/events-library/build.gradle.kts index e7ac840..8a716fa 100644 --- a/modules/events-library/build.gradle.kts +++ b/modules/events-library/build.gradle.kts @@ -35,11 +35,12 @@ kotlin { all { languageSettings.apply { - optIn("kotlin.RequiresOptIn") optIn("kotlin.ExperimentalStdlibApi") - optIn("kotlin.time.ExperimentalTime") - optIn("kotlinx.serialization.ExperimentalSerializationApi") + optIn("kotlin.RequiresOptIn") optIn("kotlin.js.ExperimentalJsExport") + optIn("kotlin.time.ExperimentalTime") + optIn("kotlinx.coroutines.FlowPreview") + optIn("kotlinx.serialization.ExperimentalSerializationApi") } } @@ -76,7 +77,6 @@ kotlin { val jvmMain by getting { dependencies { - implementation("com.github.aSemy:ts-generator:v1.2.1") implementation(kotlin("reflect")) } } @@ -95,6 +95,7 @@ kotlin { } } + val jvmJar: TaskProvider = tasks.named(kotlin.jvm().artifactsTaskName) val mainCompilation: Provider = kotlin.jvm().compilations.named("main").map { it.runtimeDependencyFiles } @@ -111,13 +112,16 @@ val generateTypeScript by tasks.registering(GenerateTypeScriptTask::class) { args(temporaryDir.canonicalPath) } + val schemaTsDistributionName: Provider = providers.provider { "${rootProject.name}-${project.name}" } + val generateTypeScriptOutputFiles: Provider = generateTypeScript.map { it.outputs.files.asFileTree } + val schemaTs by distributions.registering { distributionBaseName.set(schemaTsDistributionName) contents { @@ -125,9 +129,11 @@ val schemaTs by distributions.registering { } } + val schemaTsZipTask: TaskProvider = tasks.named("${schemaTs.name}DistZip") val schemaTsZipTaskArchiveFile: Provider = schemaTsZipTask.flatMap { it.archiveFile } + val typeScriptModelGenerated: Configuration by configurations.creating { asProvider() typescriptAttributes(objects) diff --git a/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt b/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt deleted file mode 100644 index daedc28..0000000 --- a/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/ValueClassTransformer.kt +++ /dev/null @@ -1,94 +0,0 @@ -package dev.adamko.kafkatorio.events.schema - -import kotlin.contracts.ExperimentalContracts -import kotlin.contracts.contract -import kotlin.reflect.KClass -import kotlin.reflect.KClassifier -import kotlin.reflect.KProperty -import kotlin.reflect.KType -import kotlin.reflect.KTypeProjection -import kotlin.reflect.full.createType -import kotlin.reflect.full.declaredMemberProperties -import kotlin.reflect.full.starProjectedType -import kotlin.reflect.full.withNullability -import me.ntrrgc.tsGenerator.ClassTransformer - -/** - * 'Unwrap' value classes - */ -object ValueClassTransformer : ClassTransformer { - - private val mappedValueClasses: MutableMap = mutableMapOf( - // don't unwrap unsigned numbers - they're mapped to Factorio types - UInt::class.starProjectedType to UInt::class.starProjectedType, - UByte::class.starProjectedType to UByte::class.starProjectedType, - UShort::class.starProjectedType to UShort::class.starProjectedType, - ULong::class.starProjectedType to ULong::class.starProjectedType, - ) - - override fun transformPropertyType(type: KType, property: KProperty<*>, klass: KClass<*>): KType { - val unwrappedType = - unwrapValueClassType(type, property, klass) - ?: unwrapArgs(type, property, klass) - return when (unwrappedType) { - null -> super.transformPropertyType(type, property, klass) - else -> super.transformPropertyType(unwrappedType, property, klass) - } - } - - private fun unwrapArgs(type: KType, property: KProperty<*>, klass: KClass<*>): KType? { - - val classifier: KClassifier = type.classifier ?: return type - - return if (type.arguments.isNotEmpty()) { - println("unwrapping args for $type - ${type.arguments}") - - val args = type.arguments.map { arg: KTypeProjection -> - // recursively map each argument - val argType = arg.type!! - val converted = transformPropertyType(argType, property, klass) - KTypeProjection(arg.variance, converted.withNullability(argType.isMarkedNullable)) - } - - classifier.createType( - arguments = args, - nullable = type.isMarkedNullable, - annotations = type.annotations, - ) - } else { - null - } - } - - private fun unwrapValueClassType(type: KType, property: KProperty<*>, klass: KClass<*>): KType? { - - val valueKlass: KClass<*> = type.classifier as? KClass<*> ?: return null - - return if (isValueClass(type)) { - val mappedType = mappedValueClasses.getOrPut(type.withNullability(false)) { - - val result = valueKlass - .declaredMemberProperties - .first() - .returnType - .withNullability(type.isMarkedNullable) - - println("unwrapping value class $type -> $result") - - // recursively unwrap... - val transformed = transformPropertyType(result, property, klass) - transformed.withNullability(false) - } - mappedType.withNullability(type.isMarkedNullable) - } else { - null - } - } - - @OptIn(ExperimentalContracts::class) - private fun isValueClass(type: KType?): Boolean { - contract { returnsNotNull() implies (type != null) } - return (type?.classifier as? KClass<*>)?.isValue == true - } - -} diff --git a/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt b/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt deleted file mode 100644 index eaf55a8..0000000 --- a/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/events/schema/kt2ts.kt +++ /dev/null @@ -1,147 +0,0 @@ -package dev.adamko.kafkatorio.events.schema - -//import dev.adamko.kafkatorio.schema.events.KafkatorioInstantPacketData -//import dev.adamko.kafkatorio.schema.events.KafkatorioKeyedPacketData -//import dev.adamko.kafkatorio.schema.events.KafkatorioKeyedPacketKey -////import dev.adamko.kafkatorio.schema.events.KafkatorioPacket -//import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype -//import kotlin.io.path.Path -//import kotlin.io.path.createDirectories -//import me.ntrrgc.tsGenerator.TypeScriptGenerator -//import org.intellij.lang.annotations.Language -// -///** -// * Convert Kotlin classes to Typescript classes, using [TypeScriptGenerator] -// */ -//fun main(args: Array) { -// -// val gen = TypeScriptGenerator( -// rootClasses = buildSet { -//// add(KafkatorioPacket::class) -//// addAll(KafkatorioPacket::class.sealedSubclasses) -// -// add(KafkatorioInstantPacketData::class) -// addAll(KafkatorioInstantPacketData::class.sealedSubclasses) -// -// add(KafkatorioKeyedPacketData::class) -// addAll(KafkatorioKeyedPacketData::class.sealedSubclasses) -// addAll(KafkatorioKeyedPacketKey::class.sealedSubclasses) -// -// add(FactorioPrototype::class) -// addAll(FactorioPrototype::class.sealedSubclasses) -// }, -// mappings = mapOf( -// // builtin Factorio numeric types > `typed-factorio/generated/builtin-types.d.ts` -// Float::class to "float", -// Double::class to "double", -// Int::class to "int", -// Byte::class to "int8", -// UInt::class to "uint", -// UByte::class to "uint8", -// UShort::class to "uint16", -// ULong::class to "uint64", -// ), -// classTransformers = listOf( -// ValueClassTransformer, -//// PropertyNameTransformer, -// ), -//// voidType = VoidType.UNDEFINED, -// ) -// -// val definitions = gen.definitionsText -// -// when (val filename = args.firstOrNull()) { -// null -> println(definitions) -// else -> { -// val outPath = Path(filename) -// outPath.createDirectories() -// -// splitDefinitions(definitions) -// .forEach { (defFile, def) -> -// val outFile = outPath.resolve(defFile).toFile() -// outFile.printWriter().use { -// it.println(kt2tsHeader) -// it.print(def) -// } -// println("Generated file: $outFile") -// } -// -// } -// } -//} -// -// -///** Split the TypeScript interfaces into different files */ -//private fun splitDefinitions(definitions: String): Map { -// return definitions -// .split("\n\n") -// .groupBy { def -> -// -// when { -// def isInterface "KafkatorioPacket" -// || def extendsAny listOf("KafkatorioPacket") -// || def isType "KafkatorioPacketDataType" -// -> "kafkatorio-packet.d.ts" -// -// def isInterface "KafkatorioInstantPacketData" -// || def extends "KafkatorioInstantPacketData" -// || def isType "KafkatorioInstantPacketDataType" -// -// || def isInterface "ConfigurationUpdateGameData" -// || def isInterface "ConfigurationUpdateModData" -// -> "kafkatorio-instant-packet.d.ts" -// -// def isInterface "KafkatorioKeyedPacket" -// || def isInterface "KafkatorioKeyedPacketData" -// || def extends "KafkatorioKeyedPacket" -// || def isType "KafkatorioKeyedPacketDataType" -// -// || def isInterface "KafkatorioKeyedPacketKey" -// -> "kafkatorio-keyed-packet.d.ts" -// -// def isInterface "FactorioPrototypes" -// || def isInterface "FactorioPrototype" -// || def extends "FactorioPrototype" -// || def isType "PrototypeObjectName" -// -> "prototype.d.ts" -// -// else -> "schema.d.ts" -// } -// } -// .mapValues { (_, def) -> -// def -// .sorted() -// .joinToString("\n\n", postfix = "\n") -// .replace(" ", " ") -// } -//} -// -//@Language("TypeScript") -//val kt2tsHeader = """ -// |// Generated by TypeScriptGenerator - do not edit this file manually -// | -//""".trimMargin() -// -//private infix fun String.extends(types: String): Boolean = -// contains(Regex(".+extends.*(${types})")) -// -//private infix fun String.extendsAny(types: List): Boolean = -// extends(types.joinToString("|") { "$it,".replaceAfterLast(',', "") }) -// -//private infix fun String.isInterface(type: String): Boolean = -// contains(Regex("interface $type.*")) -// -// -//private infix fun String.isType(type: String): Boolean = -// contains(Regex("type $type.*")) -// -// -////object PropertyNameTransformer : ClassTransformer { -//// override fun transformPropertyName( -//// propertyName: String, -//// property: KProperty<*>, -//// klass: KClass<*> -//// ): String { -//// return camelCaseToSnakeCase(propertyName) -//// } -////} diff --git a/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/library/FileEventsFlow.kt b/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/library/FileEventsFlow.kt index 05b79c1..2502da5 100644 --- a/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/library/FileEventsFlow.kt +++ b/modules/events-library/src/jvmMain/kotlin/dev/adamko/kafkatorio/library/FileEventsFlow.kt @@ -1,4 +1,4 @@ -package dev.adamko.kafkatorio.processor.misc +package dev.adamko.kafkatorio.library import java.io.File import java.nio.file.FileSystems diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/SyslogSocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/SyslogSocketServer.kt deleted file mode 100644 index 3c4a87a..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/SyslogSocketServer.kt +++ /dev/null @@ -1,168 +0,0 @@ -package dev.adamko.kafkatorio.processor.tileserver - -//import com.github.palindromicity.syslog.AllowableDeviations -//import com.github.palindromicity.syslog.SyslogParser -//import com.github.palindromicity.syslog.SyslogParserBuilder -//import com.github.palindromicity.syslog.SyslogSpecification -//import com.github.palindromicity.syslog.dsl.SyslogFieldKeys -//import dev.adamko.kafkatorio.server.config.ApplicationProperties -//import dev.adamko.kafkatorio.processor.tileserver.SyslogMsg.Companion.toSyslogMsg -//import io.ktor.network.selector.SelectorManager -//import io.ktor.network.sockets.aSocket -//import io.ktor.network.sockets.awaitClosed -//import io.ktor.network.sockets.openReadChannel -//import io.ktor.utils.io.readUTF8Line -//import java.util.EnumSet -//import kotlinx.coroutines.CoroutineDispatcher -//import kotlinx.coroutines.Dispatchers -//import kotlinx.coroutines.coroutineScope -//import kotlinx.coroutines.flow.MutableSharedFlow -//import kotlinx.coroutines.flow.SharedFlow -//import kotlinx.coroutines.flow.asSharedFlow -//import kotlinx.coroutines.isActive -//import kotlinx.coroutines.launch -//import kotlinx.coroutines.yield -// -// -//class SyslogSocketServer( -// appProps: ApplicationProperties, -// dispatcher: CoroutineDispatcher = Dispatchers.IO, -//) { -// -// private val selectorManager: SelectorManager = SelectorManager(dispatcher) -// -// -// private val serverSocketTcp = aSocket(selectorManager) -// .tcp() -// .bind( -// appProps.socketServerHost, -// appProps.socketServerPort, -// ) -// -// -//// private val serverSocketUdp: BoundDatagramSocket = aSocket(selectorManager) -//// .udp() -//// .bind( -//// localAddress = InetSocketAddress( -//// appProps.socketServerHost, -//// appProps.socketServerPortUdp, -//// ), -//// ) -// -// -// private val syslogParser: SyslogParser = SyslogParserBuilder() -// .withDeviations(EnumSet.of(AllowableDeviations.PRIORITY, AllowableDeviations.VERSION)) -// .forSpecification(SyslogSpecification.RFC_5424) -// .build() -// -// -// private val _messages: MutableSharedFlow = MutableSharedFlow() -// val messages: SharedFlow -// get() = _messages.asSharedFlow() -// -// -// suspend fun start() { -//// udp() -// tcp() -// } -// -//// private suspend fun udp() { -//// println("[SyslogSocketServer] started listening: ${serverSocketUdp.localAddress}") -//// -//// serverSocketUdp.incoming -//// .receiveAsFlow() -//// .map {udpPacket: Datagram -> -//// val msg = udpPacket.packet.readText() -//// println("[SyslogSocketServer] received msg: $msg") -//// syslogParser.parseLine(msg).toSyslogMsg() -//// }.collect(_messages) -//// } -// -// private suspend fun tcp() = coroutineScope { -// println("[SyslogSocketServer] started listening: ${serverSocketTcp.localAddress}") -// -// while (isActive) { -// val socket = serverSocketTcp.accept() -// -// launch { -// val channel = socket.openReadChannel() -// try { -// while (socket.socketContext.isActive) { -// val line = channel.readUTF8Line() -// println("[SyslogSocketServer] received: $line") -// -// val syslog = syslogParser.parseLine(line).toSyslogMsg() -// -// _messages.emit(syslog) -// -// yield() -// } -// } catch (e: Exception) { -// socket.awaitClosed() -// } -// } -// } -// -// yield() -// } -//} -// -// -//data class SyslogMsg( -// val src: Map -//) { -// -// val message: String? -// get() = src[SyslogFieldKeys.MESSAGE.field] -// -// val headerAppName: String? -// get() = src[SyslogFieldKeys.HEADER_APPNAME.field] -// -// val headerHostName: String? -// get() = src[SyslogFieldKeys.HEADER_HOSTNAME.field] -// -// val headerPri: String? -// get() = src[SyslogFieldKeys.HEADER_PRI.field] -// -// val headerPriSeverity: String? -// get() = src[SyslogFieldKeys.HEADER_PRI_SEVERITY.field] -// -// val headerPriFacility: String? -// get() = src[SyslogFieldKeys.HEADER_PRI_FACILITY.field] -// -// val headerProcId: String? -// get() = src[SyslogFieldKeys.HEADER_PROCID.field] -// -// val headerTimestamp: String? -// get() = src[SyslogFieldKeys.HEADER_TIMESTAMP.field] -// -// val headerMsgId: String? -// get() = src[SyslogFieldKeys.HEADER_MSGID.field] -// -// val headerVersion: String? -// get() = src[SyslogFieldKeys.HEADER_VERSION.field] -// -// val structuredBase: String? -// get() = src[SyslogFieldKeys.STRUCTURED_BASE.field] -// -// val structuredElementIdFmt: String? -// get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_FMT.field] -// -// val structuredElementIdPnameFmt: String? -// get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_PNAME_FMT.field] -// -// val structuredElementIdPnamePattern: String? -// get() = src[SyslogFieldKeys.STRUCTURED_ELEMENT_ID_PNAME_PATTERN.field] -// -// companion object { -// fun Map.toSyslogMsg(): SyslogMsg { -// val map = entries.mapNotNull { (k, v) -> -// when (v) { -// is String -> k to v -// else -> null -// } -// }.toMap() -// return SyslogMsg(map) -// } -// } -//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt deleted file mode 100644 index 3f488e5..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebMapTileServer.kt +++ /dev/null @@ -1,86 +0,0 @@ -package dev.adamko.kafkatorio.processor.tileserver - -//import dev.adamko.kafkatorio.processor.config.ApplicationProperties -//import java.security.MessageDigest -//import org.http4k.core.Filter -//import org.http4k.core.HttpHandler -//import org.http4k.core.MemoryBody -//import org.http4k.core.Method.GET -//import org.http4k.core.Request -//import org.http4k.core.Response -//import org.http4k.core.Status -//import org.http4k.core.then -//import org.http4k.routing.ResourceLoader -//import org.http4k.routing.RoutingHttpHandler -//import org.http4k.routing.bind -//import org.http4k.routing.routes -//import org.http4k.routing.static -// -//internal class WebMapTileServer( -// appProps: ApplicationProperties -//) { -// -// private val tilesLoader = ResourceLoader.Directory(appProps.serverDataDir.toFile().canonicalPath) -// -// -// private val filters = listOf( -// ETagChecker(), -// ).reduce(Filter::then) -// -// -// private val routes: RoutingHttpHandler = routes( -// "/tiles" bind GET to static(tilesLoader).withFilter(filters) -// ) -// -// -// fun build(): HttpHandler { -// return routes -// } -// -// -// private class ETagChecker : Filter { -// -// override fun invoke(next: HttpHandler): HttpHandler = { request: Request -> -// val requestedETag = request.header("If-None-Match") -// -// var response = next(request) -// val responseBytes = response.body.stream.use { it.readAllBytes() } -// val currentETag = responseBytes.md5() -// -// response = response.body(MemoryBody(responseBytes)) -// -// when { -// currentETag == null -> { -//// println("[${request.etagKey}] currentETag is null (requested: $requestedETag), executing request") -// response -// .header("Cache-Control", "no-cache, max-age=0, must-revalidate") -// } -// requestedETag == currentETag -> { -//// println("[${request.etagKey}] currentETag == requested, returning 304 $requestedETag") -// Response(Status.NOT_MODIFIED) -// .header("Cache-Control", "no-cache, max-age=0, must-revalidate") -// } -// else -> { -//// println("[${request.etagKey}] currentETag != requested, executing request and adding currentETag:$currentETag (requested:$requestedETag)") -// response -// .header("ETag", currentETag) -//// .header("Cache-Control", "no-store") -// .header("Cache-Control", "no-cache, max-age=0, must-revalidate") -// } -// } -// } -// } -// -// -// companion object { -// private fun ByteArray.md5(): String? { -// return if (isEmpty()) { -// null -// } else { -// MessageDigest.getInstance("MD5") -// .digest(this) -// .joinToString("") { "%02x".format(it) } -// } -// } -// } -//} diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebServer.kt deleted file mode 100644 index d72dc27..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebServer.kt +++ /dev/null @@ -1,16 +0,0 @@ -package dev.adamko.kafkatorio.processor.tileserver -// -//import dev.adamko.kafkatorio.processor.config.ApplicationProperties -//import org.http4k.server.Http4kServer -//import org.http4k.server.PolyHandler -//import org.http4k.server.Undertow -//import org.http4k.server.asServer -// -//internal fun webServer( -// tileServer: WebMapTileServer, -// wsServer: WebsocketServer, -// appProps: ApplicationProperties, -//): Http4kServer = PolyHandler( -// tileServer.build(), -// wsServer.build(), -//).asServer(Undertow(appProps.webPort())) diff --git a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebsocketServer.kt b/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebsocketServer.kt deleted file mode 100644 index dcf7bd3..0000000 --- a/modules/events-server/src/main/kotlin/dev/adamko/kafkatorio/processor/tileserver/WebsocketServer.kt +++ /dev/null @@ -1,141 +0,0 @@ -package dev.adamko.kafkatorio.processor.tileserver -// -//import kotlin.coroutines.resume -//import kotlin.coroutines.resumeWithException -//import kotlin.time.Duration.Companion.seconds -//import kotlin.time.TimeSource -//import kotlinx.coroutines.CoroutineExceptionHandler -//import kotlinx.coroutines.CoroutineName -//import kotlinx.coroutines.CoroutineScope -//import kotlinx.coroutines.Dispatchers -//import kotlinx.coroutines.SupervisorJob -//import kotlinx.coroutines.channels.BufferOverflow -//import kotlinx.coroutines.delay -//import kotlinx.coroutines.flow.MutableSharedFlow -//import kotlinx.coroutines.flow.launchIn -//import kotlinx.coroutines.flow.onEach -//import kotlinx.coroutines.flow.withIndex -//import kotlinx.coroutines.isActive -//import kotlinx.coroutines.job -//import kotlinx.coroutines.launch -//import kotlinx.coroutines.supervisorScope -//import kotlinx.coroutines.suspendCancellableCoroutine -//import org.http4k.routing.bind -//import org.http4k.routing.websockets -//import org.http4k.websocket.Websocket -//import org.http4k.websocket.WsHandler -//import org.http4k.websocket.WsMessage -//import org.http4k.websocket.WsStatus -// -// -//class WebsocketServer { -// -// private val serverScope = CoroutineScope( -// CoroutineName("WsServer") + -// Dispatchers.IO + -// SupervisorJob() + -// CoroutineExceptionHandler { _, e -> -// println("[ws.WsServer] handling exception ${e.message}") -// } -// ) -// -// -// private val clients: MutableSharedFlow = MutableSharedFlow( -// replay = 100, -// extraBufferCapacity = 100, -// BufferOverflow.DROP_OLDEST, -// ) -// -// -// private val messages: MutableSharedFlow = MutableSharedFlow( -// replay = 100, -// extraBufferCapacity = 100, -// BufferOverflow.DROP_OLDEST, -// ) -// -// -// private fun bindClient(ws: Websocket) = serverScope.launch { -// println("[ws.bindClient] ${ws.upgradeRequest.toMessage()}") -// clients.emit(ws) -// } -// -// -// fun sendMessage(msg: String) = serverScope.launch { -// println("[ws.sendMessage] $msg") -// messages.emit(msg) -// } -// -// -// fun build(): WsHandler { -// val startTime = TimeSource.Monotonic.markNow() -// -// serverScope.launch { -// supervisorScope { -// clients -// .withIndex() -// .onEach { (id, ws) -> -// createClient(id, ws) -// }.launchIn(serverScope) -// } -// } -// -// serverScope.launch { -// while (isActive) { -// delay(10.seconds) -// sendMessage("elapsed ${startTime.elapsedNow()}") -// } -// } -// -// return websockets( -// "/ws/foo" bind { ws: Websocket -> -// serverScope.launch { bindClient(ws) } -// } -// ) -// } -// -// -// private fun createClient(id: Int, ws: Websocket) { -// val clientJob = SupervisorJob(serverScope.coroutineContext.job) -// -// serverScope.launch(CoroutineName("ws-client-$id") + clientJob) { -// launch { -// suspendCancellableCoroutine { cont -> -// println("[ws-client] entering suspendCancellableCoroutine") -// -// cont.invokeOnCancellation { e: Throwable? -> -// launch { sendMessage("[ws-client.invokeOnCompletion] closing client ws ${e?.message}") } -// when (e) { -// null -> ws.close(WsStatus.NORMAL) -// else -> ws.close(WsStatus.ABNORMAL_CLOSE) -// } -// } -// -// ws.onError { e: Throwable -> -// launch { sendMessage("[ws-client.onError] client $id error [${e.message}]") } -// if (!cont.isCompleted) { -// cont.resumeWithException(e) -// } -// } -// -// ws.onClose { status: WsStatus -> -// launch { sendMessage("[ws-client.onClose] client $id disconnected [${status}]") } -// if (!cont.isCompleted) { -// cont.resume(status) -// } -// } -// -// ws.onMessage { wsMsg -> -// launch { sendMessage("$id says: ${wsMsg.bodyString()}") } -// } -// } -// } -// -// println("[ws-client] $id listening to messages") -// messages -// .onEach { msg -> -// println("[ws-client] sending message to $id") -// ws.send(WsMessage(msg)) -// }.launchIn(this) -// } -// } -//} From 6c6526eda9682b2473b36931d53006cc01dd44c7 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 2 Jul 2022 10:21:38 +0200 Subject: [PATCH 444/629] regenerate mod lua (I guess it didn't happen before?) --- modules/events-mod/src/generated/lua/lualib_bundle.lua | 10 ++++------ .../src/generated/lua/main/cache/EventDataCache.lua | 5 ++--- .../generated/lua/main/events/configurationUpdate.lua | 2 +- .../src/generated/lua/main/events/mapChunkUpdates.lua | 5 ++--- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/modules/events-mod/src/generated/lua/lualib_bundle.lua b/modules/events-mod/src/generated/lua/lualib_bundle.lua index e76c793..93c797b 100644 --- a/modules/events-mod/src/generated/lua/lualib_bundle.lua +++ b/modules/events-mod/src/generated/lua/lualib_bundle.lua @@ -1280,9 +1280,8 @@ do return self:entries() end function Map.prototype.entries(self) - local ____temp_0 = self - local items = ____temp_0.items - local nextKey = ____temp_0.nextKey + local items = self.items + local nextKey = self.nextKey local key = self.firstKey return { [Symbol.iterator] = function(self) @@ -1310,9 +1309,8 @@ do } end function Map.prototype.values(self) - local ____temp_1 = self - local items = ____temp_1.items - local nextKey = ____temp_1.nextKey + local items = self.items + local nextKey = self.nextKey local key = self.firstKey return { [Symbol.iterator] = function(self) diff --git a/modules/events-mod/src/generated/lua/main/cache/EventDataCache.lua b/modules/events-mod/src/generated/lua/main/cache/EventDataCache.lua index 71b961b..610cf57 100644 --- a/modules/events-mod/src/generated/lua/main/cache/EventDataCache.lua +++ b/modules/events-mod/src/generated/lua/main/cache/EventDataCache.lua @@ -118,13 +118,12 @@ do end end function Manager.prototype.isEntryInstanceOf(self, entry, ____type) - local ____self_2 = self - local ____self_isDataInstanceOf_3 = self.isDataInstanceOf + local ____self_isDataInstanceOf_2 = self.isDataInstanceOf local ____entry_packet_0 = entry if ____entry_packet_0 ~= nil then ____entry_packet_0 = ____entry_packet_0.packet end - return ____self_isDataInstanceOf_3(____self_2, ____entry_packet_0, ____type) + return ____self_isDataInstanceOf_2(self, ____entry_packet_0, ____type) end function Manager.prototype.isDataInstanceOf(self, packet, ____type) return packet ~= nil and packet.type == ____type diff --git a/modules/events-mod/src/generated/lua/main/events/configurationUpdate.lua b/modules/events-mod/src/generated/lua/main/events/configurationUpdate.lua index e548e73..1e49bb7 100644 --- a/modules/events-mod/src/generated/lua/main/events/configurationUpdate.lua +++ b/modules/events-mod/src/generated/lua/main/events/configurationUpdate.lua @@ -37,7 +37,7 @@ function allMods(e) ))} return __TS__ArrayMap( modNames, - function(modName) + function(____, modName) local ____script_active_mods_modName_2 = script.active_mods[modName] if ____script_active_mods_modName_2 == nil then local ____e_mod_changes_modName_new_version_0 = e.mod_changes[modName] diff --git a/modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua b/modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua index 7c24f25..146ade2 100644 --- a/modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua +++ b/modules/events-mod/src/generated/lua/main/events/mapChunkUpdates.lua @@ -236,9 +236,8 @@ script.on_event( key, Type.MapChunkUpdate, function(data) - local ____temp_19 = true - data.isDeleted = ____temp_19 - return ____temp_19 + data.isDeleted = true + return true end, 0 ) From 88982d818a489d9f513b177a78bb5d70549b2a49 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sat, 2 Jul 2022 10:24:02 +0200 Subject: [PATCH 445/629] make tstl explicitly depend on package.json --- build.gradle.kts | 2 +- modules/events-mod/build.gradle.kts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index b957525..ae6a2ff 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { `project-report` `build-dashboard` - kotlin("multiplatform") apply false // try to stop error 'Projects must be configuring' +// kotlin("multiplatform") apply false // try to stop error 'Projects must be configuring' // kotlin("js") apply false // try to stop error 'Projects must be configuring' } diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 6be5d7d..9380d84 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -72,6 +72,8 @@ dependencies { val typescriptToLua by tasks.registering(TypescriptToLuaTask::class) { dependsOn(tasks.npmInstall, installEventsTsSchema, tasks.updatePackageJson) + inputs.file(tasks.updatePackageJson.map { it.packageJsonFile }) + sourceFiles.set(tsSrcDir) outputDirectory.set(layout.projectDirectory.dir("src/generated/lua")) From 90dc520d22d4b27b1141880fb2953b381a5eb616 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 5 Jul 2022 23:44:23 +0200 Subject: [PATCH 446/629] massive refactor to export entities (buildings and resources) - minor version bumps - new Factorio version - use both prototype name and type to identify a prototype - kxs-ts-gen: use BrandTyping, but exclude some identifiers - kxs-ts-gen: manually create zip dist, so it can run after the project compiles - mod: use typed-factorio strict types - mod: refactor event handlers to be a little more consistent and object-oriented --- .../gradle/artifactDistributions.kt | 3 + .../kafkatorio/task/GenerateTypeScriptTask.kt | 2 + gradle/libs.versions.toml | 24 +- modules/events-library/build.gradle.kts | 59 +- .../kafkatorio/schema/common/colours.kt | 1 + .../kafkatorio/schema/common/entities.kt | 191 ++++ .../kafkatorio/schema/common/factorioIds.kt | 26 +- .../schema/common/factorioPrototypes.kt | 7 +- .../kafkatorio/schema/common/mapTile.kt | 15 +- .../kafkatorio/schema/common/prototypeIds.kt | 817 ++++++++++++++++++ .../kafkatorio/schema/common/resources.kt | 38 +- .../schema/packets/kafkatorioPacketKeyed.kt | 49 +- .../events/schema/MapChunkUpdateTest.kt | 16 +- .../events/schema/PrototypesTest.kt | 5 +- .../events/schema/UpdatePacketsTest.kt | 4 +- .../schema/common/MapTileDictionaryTest.kt | 18 +- .../adamko/kafkatorio/events/schema/kt2ts2.kt | 48 +- modules/events-mod/build.gradle.kts | 2 +- modules/events-mod/package-lock.json | 6 +- modules/events-mod/package.json | 14 +- .../events-mod/src/generated/lua/control.lua | 2 +- .../lua/generated/kafkatorio-schema.lua | 64 +- .../generated/lua/main/events/converters.lua | 96 ++ .../lua/main/events/entityUpdates.lua | 216 +++-- .../lua/main/events/mapChunkUpdates.lua | 271 +++--- .../lua/main/events/playerUpdates.lua | 5 +- .../lua/main/events/prototypeUpdates.lua | 2 +- ...andlers.lua => registerEventListeners.lua} | 6 +- .../lua/main/events/resourceEntityUpdates.lua | 0 .../lua/main/settings/KafkatorioSettings.lua | 2 +- .../resources/mod-data/locale/en/locale.cfg | 6 +- .../events-mod/src/main/typescript/control.ts | 2 +- .../typescript/generated/kafkatorio-schema.ts | 164 +++- .../typescript/main/cache/EventDataCache.ts | 2 +- .../typescript/main/events/consoleUpdates.ts | 2 +- .../main/typescript/main/events/converters.ts | 124 ++- .../typescript/main/events/entityUpdates.ts | 311 +++++-- .../typescript/main/events/mapChunkUpdates.ts | 470 +++++----- .../typescript/main/events/playerUpdates.ts | 16 +- .../main/events/prototypeUpdates.ts | 6 +- ...rHandlers.ts => registerEventListeners.ts} | 4 +- .../main/events/resourceEntityUpdates.ts | 99 +++ .../typescript/main/events/surfaceUpdates.ts | 2 +- .../main/settings/KafkatorioSettings.ts | 5 +- .../src/main/typescript/main/types.d.ts | 2 +- modules/events-mod/tsconfig.json | 6 +- .../server/processor/KafkatorioTopology.kt | 6 +- .../processor/admin/KafkatorioKafkaAdmin.kt | 2 +- .../server/processor/eventProcessor.kt | 14 +- .../server/processor/kafkatorioTopics.kt | 10 +- .../processor/topology/colourMapChunks.kt | 22 +- .../topology/factorioServerPackets.kt | 8 +- .../processor/topology/packetDataStreams.kt | 4 +- .../server/processor/topology/prototypes.kt | 4 +- .../server/processor/topology/saveMapTiles.kt | 8 +- .../topology/websocketBroadcaster.kt | 7 +- .../server/socket/SyslogSocketServer.kt | 6 +- .../server/web/rest/factorioServersRoutes.kt | 2 - .../infra-factorio-client/build.gradle.kts | 11 +- modules/infra-factorio-server/src/.env | 2 +- .../src/docker-compose.yml | 2 +- .../adamko/kafkatorio/webmap/websockets.kt | 4 +- 62 files changed, 2629 insertions(+), 713 deletions(-) create mode 100644 modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/entities.kt create mode 100644 modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/prototypeIds.kt rename modules/events-mod/src/generated/lua/main/events/{registerHandlers.lua => registerEventListeners.lua} (93%) create mode 100644 modules/events-mod/src/generated/lua/main/events/resourceEntityUpdates.lua rename modules/events-mod/src/main/typescript/main/events/{registerHandlers.ts => registerEventListeners.ts} (92%) create mode 100644 modules/events-mod/src/main/typescript/main/events/resourceEntityUpdates.ts diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistributions.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistributions.kt index 02bf554..b2f9beb 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistributions.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/gradle/artifactDistributions.kt @@ -18,12 +18,14 @@ fun Configuration.asProvider() { isCanBeConsumed = true } + fun Configuration.asConsumer() { isVisible = false isCanBeResolved = true isCanBeConsumed = false } + fun Configuration.factorioModAttributes(objects: ObjectFactory): Configuration = attributes { attribute(USAGE_ATTRIBUTE, objects.named("factorio")) @@ -32,6 +34,7 @@ fun Configuration.factorioModAttributes(objects: ObjectFactory): Configuration = attribute(BUNDLING_ATTRIBUTE, objects.named(Bundling.EMBEDDED)) } + fun Configuration.typescriptAttributes(objects: ObjectFactory): Configuration = attributes { attribute(USAGE_ATTRIBUTE, objects.named("typescript")) diff --git a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypeScriptTask.kt b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypeScriptTask.kt index fab29ae..331275b 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypeScriptTask.kt +++ b/buildSrc/src/main/kotlin/dev/adamko/kafkatorio/task/GenerateTypeScriptTask.kt @@ -6,8 +6,10 @@ import org.gradle.api.file.FileSystemOperations import org.gradle.api.tasks.JavaExec import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction +import org.gradle.work.DisableCachingByDefault +@DisableCachingByDefault(because = "caching makes regenerating more difficult") abstract class GenerateTypeScriptTask @Inject constructor( private val fileOps: FileSystemOperations, ) : JavaExec() { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 10449f7..a4a42ab 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,20 +16,22 @@ kvision = "5.11.0" log4j2 = "2.17.2" qosLogback = "1.2.11" slf4j = "1.7.36" -okio = "3.1.0" +okio = "3.2.0" scrimage = "4.0.31" semver = "1.2.0" kotlinx-serialization = "1.3.3" kxs-charleskornKaml = "0.44.0" kxs-mamoeYamlkt = "0.12.0" +kxs-kxsTsGen = "0.2.1" -kotlinJsWrappers = "1.0.0-pre.346" +kotlinJsWrappers = "1.0.0-pre.349" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom + +kotlinx-cli = "0.3.4" +kotlinx-coroutines = "1.6.3" +kotlinx-datetime = "0.3.3" kotlinx-html = "0.7.5" kotlinx-nodejs = "0.0.7" -kotlinx-coroutines = "1.6.1" -kotlinx-cli = "0.3.4" -kotlinx-datetime = "0.3.3" ktor = "2.0.3" @@ -39,20 +41,24 @@ simpleSyslogParser = "0.0.6" kotkaStreams = "dev-SNAPSHOT" + ## test ## junit = "5.8.2" kotest = "5.3.1" mockk = "1.12.4" + ## infra ## -factorio = "1.1.59" +factorio = "1.1.61" confluent-kafkaConnect = "7.0.1" grafana = "8.5.0" prometheus = "v2.34.0" + ## gradle plugins ## gradleNodePlugin = "3.3.0" # https://github.com/node-gradle/gradle-node-plugin/releases + ######### [plugins] ######### @@ -89,8 +95,10 @@ kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "ko kotlinx-serialization-properties = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-properties" } kotlinx-serialization-protobuf = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-protobuf" } -kxs-charleskornKaml = { group = "com.charleskorn.kaml", name = "kaml", version.ref = "kxs-charleskornKaml" } -kxs-mamoeYamlkt = { group = "net.mamoe.yamlkt", name = "yamlkt", version.ref = "kxs-mamoeYamlkt" } +kxs-charleskornKaml = { group = "com.charleskorn.kaml", name = "kaml", version.ref = "kxs-charleskornKaml" } +kxs-mamoeYamlkt = { group = "net.mamoe.yamlkt", name = "yamlkt", version.ref = "kxs-mamoeYamlkt" } +#kxs-kxsTsGen = { group = "dev.adamko.kxstsgen", name = "kxs-ts-gen-core", version.ref = "kxs-kxsTsGen" } +kxs-kxsTsGen = { group = "com.github.adamko-dev.kotlinx-serialization-typescript-generator", name = "kxs-ts-gen-core", version.ref = "kxs-kxsTsGen" } kotlinx-coroutines-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-bom", version.ref = "kotlinx-coroutines" } diff --git a/modules/events-library/build.gradle.kts b/modules/events-library/build.gradle.kts index 8a716fa..b99515a 100644 --- a/modules/events-library/build.gradle.kts +++ b/modules/events-library/build.gradle.kts @@ -1,6 +1,9 @@ import dev.adamko.kafkatorio.gradle.asProvider import dev.adamko.kafkatorio.gradle.typescriptAttributes import dev.adamko.kafkatorio.task.GenerateTypeScriptTask +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -36,6 +39,7 @@ kotlin { all { languageSettings.apply { optIn("kotlin.ExperimentalStdlibApi") + optIn("kotlin.ExperimentalUnsignedTypes") optIn("kotlin.RequiresOptIn") optIn("kotlin.js.ExperimentalJsExport") optIn("kotlin.time.ExperimentalTime") @@ -51,7 +55,7 @@ kotlin { implementation(project.dependencies.platform(libs.kotlinx.serialization.bom)) implementation(libs.kotlinx.serialization.core) implementation(libs.kotlinx.serialization.json) - api("dev.adamko.kxstsgen:kxs-ts-gen-core:0.1.3") + api(libs.kxs.kxsTsGen) implementation(dependencies.platform(libs.okio.bom)) implementation(libs.okio.core) @@ -96,16 +100,34 @@ kotlin { } +val kotlinJvmMainCompilation: NamedDomainObjectProvider = + kotlin.jvm().compilations.named(KotlinCompilation.MAIN_COMPILATION_NAME) + + val jvmJar: TaskProvider = tasks.named(kotlin.jvm().artifactsTaskName) -val mainCompilation: Provider = - kotlin.jvm().compilations.named("main").map { it.runtimeDependencyFiles } + +val kotlinMainRuntimeDependencies: Provider = + kotlinJvmMainCompilation.map { it.runtimeDependencyFiles } + +val kotlinMainCompileDependencies: Provider = + kotlinJvmMainCompilation.map { it.compileDependencyFiles } + +val kotlinMainCompileTask: Provider = + kotlinJvmMainCompilation.map { it.compileKotlinTask } val generateTypeScript by tasks.registering(GenerateTypeScriptTask::class) { dependsOn(jvmJar) +// dependsOn(kotlinMainCompileTask) + +// inputs.files(jvmJar.map { it.outputs.files }) +// inputs.files(kotlinMainCompileTask.map { it.javaSources }) + classpath( jvmJar, - mainCompilation, + kotlinMainRuntimeDependencies, +// kotlinMainCompileTask.map { it.libraries } +// kotlinMainDependencies, ) output.set(layout.buildDirectory.dir("generated/typescript")) mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2ts2Kt") @@ -122,16 +144,26 @@ val generateTypeScriptOutputFiles: Provider = generateTypeScript.map { it.outputs.files.asFileTree } -val schemaTs by distributions.registering { - distributionBaseName.set(schemaTsDistributionName) - contents { - from(generateTypeScriptOutputFiles) - } +//val schemaTs by distributions.registering { +// distributionBaseName.set(schemaTsDistributionName) +// contents { +// from(generateTypeScriptOutputFiles) +// } +//} + + +//val schemaTsZipTask: TaskProvider = tasks.named("${schemaTs.name}DistZip") +//val schemaTsZipTaskArchiveFile: Provider = schemaTsZipTask.flatMap { it.archiveFile } + + +val schemaTsZip by tasks.registering(Zip::class) { + group = "kt2ts" + + archiveBaseName.set("schema-ts") + from(generateTypeScriptOutputFiles) + destinationDirectory.set(layout.buildDirectory.dir("distributions/kt2ts")) } - - -val schemaTsZipTask: TaskProvider = tasks.named("${schemaTs.name}DistZip") -val schemaTsZipTaskArchiveFile: Provider = schemaTsZipTask.flatMap { it.archiveFile } +val schemaTsZipTaskArchiveFile: Provider = schemaTsZip.flatMap { it.archiveFile } val typeScriptModelGenerated: Configuration by configurations.creating { @@ -139,4 +171,5 @@ val typeScriptModelGenerated: Configuration by configurations.creating { typescriptAttributes(objects) outgoing.artifact(schemaTsZipTaskArchiveFile) +// outgoing.artifact(schemaTsZipTaskArchiveFile) } diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt index a7b6b54..6aa4cae 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/colours.kt @@ -5,6 +5,7 @@ import kotlin.math.roundToInt import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable + /** * Red, green, blue and alpha values, all in range `[0, 1]` or all in range `[0, 255]` if any * value is > 1. diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/entities.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/entities.kt new file mode 100644 index 0000000..2a101a2 --- /dev/null +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/entities.kt @@ -0,0 +1,191 @@ +package dev.adamko.kafkatorio.schema.common + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + + +@Serializable +@SerialName("kafkatorio.entity.FactorioEntityData") +sealed interface FactorioEntityData { + + val protoId: PrototypeId + val status: Status? + + val position: MapEntityPosition + + /** Non-specific entity data */ + @Serializable + @SerialName("kafkatorio.entity.FactorioEntityData.Standard") + data class Standard( + override val protoId: PrototypeId, + override val status: Status? = null, + + override val position: MapEntityPosition, + val graphicsVariation: UByte? = null, + val health: Float? = null, + val isActive: Boolean? = null, + val isRotatable: Boolean? = null, + val lastUser: UInt? = null, + val localisedDescription: String? = null, + val localisedName: String? = null, + ) : FactorioEntityData + + + @Serializable + @SerialName("kafkatorio.entity.FactorioEntityData.Resource") + data class Resource( + override val protoId: PrototypeId, + override val status: Status? = null, + + override val position: MapEntityPosition, + val amount: UInt, + /** Count of initial resource units contained. `null` if resource is not infinite. */ + val initialAmount: UInt? = null, + ) : FactorioEntityData + + + @Serializable + @SerialName("kafkatorio.entity.FactorioEntityData.EntityStatus") + enum class Status { + CANT_DIVIDE_SEGMENTS, + CHARGING, + CLOSED_BY_CIRCUIT_NETWORK, + DISABLED, + DISABLED_BY_CONTROL_BEHAVIOR, + DISABLED_BY_SCRIPT, + DISCHARGING, + FLUID_INGREDIENT_SHORTAGE, + FULLY_CHARGED, + FULL_OUTPUT, + ITEM_INGREDIENT_SHORTAGE, + LAUNCHING_ROCKET, + LOW_INPUT_FLUID, + LOW_POWER, + LOW_TEMPERATURE, + MARKED_FOR_DECONSTRUCTION, + MISSING_REQUIRED_FLUID, + MISSING_SCIENCE_PACKS, + NETWORKS_CONNECTED, + NETWORKS_DISCONNECTED, + NORMAL, + NOT_CONNECTED_TO_RAIL, + NOT_PLUGGED_IN_ELECTRIC_NETWORK, + NO_AMMO, + NO_FUEL, + NO_INGREDIENTS, + NO_INPUT_FLUID, + NO_MINABLE_RESOURCES, + NO_MODULES_TO_TRANSMIT, + NO_POWER, + NO_RECIPE, + NO_RESEARCH_IN_PROGRESS, + OPENED_BY_CIRCUIT_NETWORK, + OUT_OF_LOGISTIC_NETWORK, + PREPARING_ROCKET_FOR_LAUNCH, + RECHARGING_AFTER_POWER_OUTAGE, + TURNED_OFF_DURING_DAYTIME, + WAITING_FOR_SOURCE_ITEMS, + WAITING_FOR_SPACE_IN_DESTINATION, + WAITING_FOR_TARGET_TO_BE_BUILT, + WAITING_FOR_TRAIN, + WAITING_TO_LAUNCH_ROCKET, + WORKING, + } + +} +/* + enum entity_status { + working, + normal, + no_power, + low_power, + no_fuel, + disabled_by_control_behavior, + opened_by_circuit_network, + closed_by_circuit_network, + disabled_by_script, + marked_for_deconstruction, + not_plugged_in_electric_network, + networks_connected, + networks_disconnected, + charging, + discharging, + fully_charged, + out_of_logistic_network, + no_recipe, + no_ingredients, + no_input_fluid, + no_research_in_progress, + no_minable_resources, + low_input_fluid, + fluid_ingredient_shortage, + full_output, + item_ingredient_shortage, + missing_required_fluid, + missing_science_packs, + waiting_for_source_items, + waiting_for_space_in_destination, + preparing_rocket_for_launch, + waiting_to_launch_rocket, + launching_rocket, + no_modules_to_transmit, + recharging_after_power_outage, + waiting_for_target_to_be_built, + waiting_for_train, + no_ammo, + low_temperature, + disabled, + turned_off_during_daytime, + not_connected_to_rail, + cant_divide_segments, + } + + */ + +/* +AssemblingMachine +Beam +Car +Character +CharacterCorpse +CraftingMachine +ElectricEnergyInterface +ElectricPole +EntityGhost +EntityWithHealth +EntityWithOwner +FlyingText +Furnace +Gate +Generator +Ghost +HeatInterface +HighlightBox +InfinityContainer +InfinityPipe +Inserter +ItemEntity +LandMine +LinkedBelt +Loader +Market +MiningDrill +ProgrammableSpeaker +Pump +Radar +Rail +RailChainSignal +RailSignal +Reactor +ResourceEntity +RocketSilo +SmokeWithTrigger +SpiderVehicle +Splitter +TrainStop +TransportBeltConnectable +TransportBeltToGround +Turret +Unit +Vehicle + */ diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt index 9384d90..d091e67 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioIds.kt @@ -1,10 +1,12 @@ package dev.adamko.kafkatorio.schema.common import kotlin.jvm.JvmInline +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable +@SerialName("kafkatorio.id.Tick") @JvmInline value class Tick(val value: UInt) @@ -17,6 +19,7 @@ val UInt.tick * See [`LuaSurface.index`](https://lua-api.factorio.com/latest/LuaSurface.html#LuaSurface.index) */ @Serializable +@SerialName("kafkatorio.id.SurfaceIndex") @JvmInline value class SurfaceIndex(private val id: UInt) { override fun toString(): String = "$id" @@ -24,6 +27,7 @@ value class SurfaceIndex(private val id: UInt) { @Serializable +@SerialName("kafkatorio.id.ForceIndex") @JvmInline value class ForceIndex(private val id: UInt) { override fun toString(): String = "$id" @@ -32,6 +36,7 @@ value class ForceIndex(private val id: UInt) { /** The player's index in `LuaGameScript::players` */ @Serializable +@SerialName("kafkatorio.id.PlayerIndex") @JvmInline value class PlayerIndex(private val id: UInt) { override fun toString(): String = "$id" @@ -40,6 +45,7 @@ value class PlayerIndex(private val id: UInt) { /** > This is universally unique for every entity that has one, for the lifetime of a whole game. */ @Serializable +@SerialName("kafkatorio.id.UnitNumber") @JvmInline value class UnitNumber(private val id: UInt) { override fun toString(): String = "$id" @@ -47,13 +53,7 @@ value class UnitNumber(private val id: UInt) { @Serializable -@JvmInline -value class PrototypeName(private val id: String) { - override fun toString(): String = id -} - - -@Serializable +@SerialName("kafkatorio.id.EventName") @JvmInline value class EventName(private val name: String) { override fun toString(): String = name @@ -62,23 +62,23 @@ value class EventName(private val name: String) { interface EntityIdentifiers { val unitNumber: UnitNumber? - val name: String - /** The prototype-type of the entity. */ - val protoType: String + /** The 'prototype type' and 'prototype name' of the entity. */ + val protoId: PrototypeId } // instant of EntityIdentifiers, because kxs needs a concrete instance @Serializable +@SerialName("kafkatorio.id.EntityIdentifiersData") data class EntityIdentifiersData( override val unitNumber: UnitNumber? = null, - override val name: String, - override val protoType: String, + override val protoId: PrototypeId, ) : EntityIdentifiers -@JvmInline @Serializable +@SerialName("kafkatorio.id.FactorioServerId") +@JvmInline value class FactorioServerId(private val id: String) { override fun toString() = id } diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt index 5f08e0c..393ad8a 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/factorioPrototypes.kt @@ -8,13 +8,14 @@ import kotlinx.serialization.Serializable @Serializable @SerialName("kafkatorio.prototype.FactorioPrototype") sealed interface FactorioPrototype { - val name: PrototypeName + val protoId: PrototypeId val mapColour: Colour + @SerialName("kafkatorio.prototype.MapTile") @Serializable data class MapTile( - override val name: PrototypeName, + override val protoId: PrototypeId, override val mapColour: Colour, val layer: UInt, @@ -29,7 +30,7 @@ sealed interface FactorioPrototype { @SerialName("kafkatorio.prototype.Entity") @Serializable data class Entity( - override val name: PrototypeName, + override val protoId: PrototypeId, override val mapColour: Colour, val protoType: String, diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt index 20f41af..c7b98b8 100644 --- a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/mapTile.kt @@ -12,16 +12,16 @@ const val MAP_CHUNK_SIZE = 32 data class MapTile( val x: Int, val y: Int, - val proto: PrototypeName, + val protoId: PrototypeId, ) /** * 2D map of x/y tile positions and prototype-name, optimised for JSON size. * - * [protos] is a one-to-one map between a [PrototypeName] and [PrototypeKey]. + * [protos] is a one-to-one map between a prototype[PrototypeId] and [PrototypeKey]. * - * [PrototypeKey] is an arbitrary integer value, which maps to one [PrototypeName] only for a + * [PrototypeKey] is an arbitrary integer value, which maps to one [PrototypeId] only for a * specific instance of [MapTileDictionary]. * * Each X/Y coordinate in [tilesXY] maps to a [PrototypeKey]. @@ -30,9 +30,10 @@ data class MapTile( data class MapTileDictionary( /** Map an X,Y coordinate a prototype name */ val tilesXY: Map>, - val protos: Map, + val protos: Map, ) { - private val protosIndexToName: Map by lazy { + + private val protosIndexToId: Map by lazy { protos.entries.associate { (name, key) -> key to name } } @@ -41,11 +42,11 @@ data class MapTileDictionary( row.forEach { (yString, protoIndex) -> val x = xString.toIntOrNull() val y = yString.toIntOrNull() - val protoName = protosIndexToName[protoIndex] + val protoName = protosIndexToId[protoIndex] if (x != null && y != null && protoName != null) { add(MapTile(x, y, protoName)) } else if (protoName == null) { - println("warning: no prototype name found for index:$protoIndex. $protosIndexToName") + println("warning: no prototype name found for index:$protoIndex. $protosIndexToId") } } } diff --git a/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/prototypeIds.kt b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/prototypeIds.kt new file mode 100644 index 0000000..9cc98ba --- /dev/null +++ b/modules/events-library/src/commonMain/kotlin/dev/adamko/kafkatorio/schema/common/prototypeIds.kt @@ -0,0 +1,817 @@ +package dev.adamko.kafkatorio.schema.common + +import kotlin.jvm.JvmInline +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + + +/** + * Both a [name] and [type] are required to unique identify a [prototype][FactorioPrototype]. + * + * + * @property[name] The name of the prototype, which is unique per specific Prototype [type] + */ +// * Each subclass of [PrototypeId] is equivalent to a Prototype `type`. +//sealed interface PrototypeId { +// +// val name: String +// +// @Serializable +// @JvmInline +// @SerialName("kafkatorio.prototype.id.PrototypeIdMapTile") +// value class MapTile(override val name: String) : PrototypeId { +// override fun toString(): String = name +// } +// +// @Serializable +// @JvmInline +// @SerialName("kafkatorio.prototype.id.PrototypeIdEntity") +// value class Entity(override val name: String) : PrototypeId { +// override fun toString(): String = name +// } +// +// @Serializable +// @JvmInline +// @SerialName("kafkatorio.prototype.id.PrototypeIdResourceEntity") +// value class ResourceEntity(override val name: String) : PrototypeId { +// override fun toString(): String = name +// } +// +// @Serializable +// @JvmInline +// @SerialName("kafkatorio.prototype.id.PrototypeIdFluid") +// value class Fluid(override val name: String) : PrototypeId { +// override fun toString(): String = name +// } +// +// @Serializable +// @JvmInline +// @SerialName("kafkatorio.prototype.id.PrototypeIdItem") +// value class Item(override val name: String) : PrototypeId { +// override fun toString(): String = name +// } +// +//} + +@Serializable +@JvmInline +@SerialName("kafkatorio.id.PrototypeId") +value class PrototypeId private constructor( + private val typeNameConcat: String, +) { + + val type: Type get() = Type(typeNameConcat.substringBefore(delim, "")) + val name: Name get() = Name(typeNameConcat.substringAfter(delim, "")) + + + operator fun component1(): Type = type + operator fun component2(): Name = name + + + constructor( + type: String, + name: String, + ) : this("${type}${delim}${name}") + + + /** Denotes the class of the Prototype */ + @Serializable + @JvmInline + @SerialName("kafkatorio.id.PrototypeIdType") + value class Type(private val id: String) { + override fun toString(): String = id + } + + + /** A specific implementation of a [type]. Unique per prototype 'super class' */ + @Serializable + @JvmInline + @SerialName("kafkatorio.id.PrototypeIdName") + value class Name(private val name: String) { + override fun toString(): String = name + } + + + companion object { + private const val delim = '/' + } +} + + +//@Suppress("unused") +//enum class PrototypeTypeId( +// val id: String +//) { +// AmbientSound("ambient-sound"), +// Animation("animation"), +// EditorController("editor-controller"), +// Font("font"), +// GodController("god-controller"), +// MapGenPresets("map-gen-presets"), +// MapSettings("map-settings"), +// MouseCursor("mouse-cursor"), +// Sound("sound"), +// SpectatorController("spectator-controller"), +// Sprite("sprite"), +// TileEffect("tile-effect"), +// TipsAndTricksItemCategory("tips-and-tricks-item-category"), +// TriggerTargetType("trigger-target-type"), +// WindSound("wind-sound"), +// Achievement("achievement"), +// BuildEntityAchievement("build-entity-achievement"), +// CombatRobotCountAchievement("combat-robot-count"), +// ConstructWithRobotsAchievement("construct-with-robots-achievement"), +// DeconstructWithRobotsAchievement("deconstruct-with-robots-achievement"), +// DeliverByRobotsAchievement("deliver-by-robots-achievement"), +// DontBuildEntityAchievement("dont-build-entity-achievement"), +// DontCraftManuallyAchievement("dont-craft-manually-achievement"), +// DontUseEntityInEnergyProductionAchievement("dont-use-entity-in-energy-production-achievement"), +// FinishTheGameAchievement("finish-the-game-achievement"), +// GroupAttackAchievement("group-attack-achievement"), +// KillAchievement("kill-achievement"), +// PlayerDamagedAchievement("player-damaged-achievement"), +// ProduceAchievement("produce-achievement"), +// ProducePerHourAchievement("produce-per-hour-achievement"), +// ResearchAchievement("research-achievement"), +// TrainPathAchievement("train-path-achievement"), +// AmmoCategory("ammo-category"), +// AutoplaceControl("autoplace-control"), +// CustomInput("custom-input"), +// DamageType("damage-type"), +// Decorative("optimized-decorative"), +// Entity(""), +// Arrow("arrow"), +// ArtilleryFlare("artillery-flare"), +// ArtilleryProjectile("artillery-projectile"), +// Beam("beam"), +// CharacterCorpse("character-corpse"), +// Cliff("cliff"), +// Corpse("corpse"), +// RailRemnants("rail-remnants"), +// DeconstructibleTileProxy("deconstructible-tile-proxy"), +// EntityGhost("entity-ghost"), +// /** for migration, cannot be used */ +// EntityParticle("particle"), +// /** for migration, cannot be used */ +// LeafParticle("leaf-particle"), +// EntityWithHealth(""), +// EntityWithOwner(""), +// Accumulator("accumulator"), +// ArtilleryTurret("artillery-turret"), +// Beacon("beacon"), +// Boiler("boiler"), +// BurnerGenerator("burner-generator"), +// Character("character"), +// Combinator(""), +// ArithmeticCombinator("arithmetic-combinator"), +// DeciderCombinator("decider-combinator"), +// ConstantCombinator("constant-combinator"), +// Container("container"), +// LogisticContainer("logistic-container"), +// InfinityContainer("infinity-container"), +// CraftingMachine(""), +// AssemblingMachine("assembling-machine"), +// RocketSilo("rocket-silo"), +// Furnace("furnace"), +// ElectricEnergyInterface("electric-energy-interface"), +// ElectricPole("electric-pole"), +// EnemySpawner("unit-spawner"), +// FlyingRobot(""), +// CombatRobot("combat-robot"), +// RobotWithLogisticInterface(""), +// ConstructionRobot("construction-robot"), +// LogisticRobot("logistic-robot"), +// Gate("gate"), +// Generator("generator"), +// HeatInterface("heat-interface"), +// HeatPipe("heat-pipe"), +// Inserter("inserter"), +// Lab("lab"), +// Lamp("lamp"), +// LandMine("land-mine"), +// LinkedContainer("linked-container"), +// Market("market"), +// MiningDrill("mining-drill"), +// OffshorePump("offshore-pump"), +// Pipe("pipe"), +// InfinityPipe("infinity-pipe"), +// PipeToGround("pipe-to-ground"), +// PlayerPort("player-port"), +// PowerSwitch("power-switch"), +// ProgrammableSpeaker("programmable-speaker"), +// Pump("pump"), +// Radar("radar"), +// Rail(""), +// CurvedRail("curved-rail"), +// StraightRail("straight-rail"), +// RailSignalBase(""), +// RailChainSignal("rail-chain-signal"), +// RailSignal("rail-signal"), +// Reactor("reactor"), +// Roboport("roboport"), +// SimpleEntityWithOwner("simple-entity-with-owner"), +// SimpleEntityWithForce("simple-entity-with-force"), +// SolarPanel("solar-panel"), +// StorageTank("storage-tank"), +// TrainStop("train-stop"), +// TransportBeltConnectable(""), +// LinkedBelt("linked-belt"), +// Loader1x1("loader-1x1"), +// Loader1x2("loader"), +// Splitter("splitter"), +// TransportBelt("transport-belt"), +// UndergroundBelt("underground-belt"), +// Turret("turret"), +// AmmoTurret("ammo-turret"), +// ElectricTurret("electric-turret"), +// FluidTurret("fluid-turret"), +// Unit("unit"), +// Vehicle(""), +// Car("car"), +// RollingStock(""), +// ArtilleryWagon("artillery-wagon"), +// CargoWagon("cargo-wagon"), +// FluidWagon("fluid-wagon"), +// Locomotive("locomotive"), +// SpiderVehicle("spider-vehicle"), +// Wall("wall"), +// Fish("fish"), +// SimpleEntity("simple-entity"), +// SpiderLeg("spider-leg"), +// Tree("tree"), +// Explosion("explosion"), +// FlameThrowerExplosion("flame-thrower-explosion"), +// FireFlame("fire"), +// FluidStream("stream"), +// FlyingText("flying-text"), +// HighlightBoxEntity("highlight-box"), +// ItemEntity("item-entity"), +// ItemRequestProxy("item-request-proxy"), +// ParticleSource("particle-source"), +// Projectile("projectile"), +// ResourceEntity("resource"), +// RocketSiloRocket("rocket-silo-rocket"), +// RocketSiloRocketShadow("rocket-silo-rocket-shadow"), +// Smoke(""), +// /** for migration, cannot be used */ +// SimpleSmoke("smoke"), +// SmokeWithTrigger("smoke-with-trigger"), +// SpeechBubble("speech-bubble"), +// Sticker("sticker"), +// TileGhost("tile-ghost"), +// Equipment(""), +// ActiveDefenseEquipment("active-defense-equipment"), +// BatteryEquipment("battery-equipment"), +// BeltImmunityEquipment("belt-immunity-equipment"), +// EnergyShieldEquipment("energy-shield-equipment"), +// GeneratorEquipment("generator-equipment"), +// MovementBonusEquipment("movement-bonus-equipment"), +// NightVisionEquipment("night-vision-equipment"), +// RoboportEquipment("roboport-equipment"), +// SolarPanelEquipment("solar-panel-equipment"), +// EquipmentCategory("equipment-category"), +// EquipmentGrid("equipment-grid"), +// Fluid("fluid"), +// FuelCategory("fuel-category"), +// GuiStyle("gui-style"), +// Item("item"), +// AmmoItem("ammo"), +// Capsule("capsule"), +// Gun("gun"), +// ItemWithEntityData("item-with-entity-data"), +// ItemWithLabel("item-with-label"), +// ItemWithInventory("item-with-inventory"), +// BlueprintBook("blueprint-book"), +// ItemWithTags("item-with-tags"), +// SelectionTool("selection-tool"), +// BlueprintItem("blueprint"), +// CopyPasteTool("copy-paste-tool"), +// DeconstructionItem("deconstruction-item"), +// UpgradeItem("upgrade-item"), +// Module("module"), +// RailPlanner("rail-planner"), +// SpidertronRemote("spidertron-remote"), +// Tool("tool"), +// Armor("armor"), +// /** for migration, cannot be used */ +// MiningTool("mining-tool"), +// RepairTool("repair-tool"), +// ItemGroup("item-group"), +// ItemSubGroup("item-subgroup"), +// ModuleCategory("module-category"), +// NamedNoiseExpression("noise-expression"), +// NoiseLayer("noise-layer"), +// Particle("optimized-particle"), +// Recipe("recipe"), +// RecipeCategory("recipe-category"), +// ResourceCategory("resource-category"), +// Shortcut("shortcut"), +// Technology("technology"), +// Tile("tile"), +// TipsAndTricksItem("tips-and-tricks-item"), +// TrivialSmoke("trivial-smoke"), +// Tutorial("tutorial"), +// UtilityConstants("utility-constants"), +// UtilitySounds("utility-sounds"), +// UtilitySprites("utility-sprites"), +// VirtualSignal("virtual-signal"), +// ; +// +// fun named(protoName: String): PrototypeId = PrototypeId(this, protoName) +// +// companion object { +// val entries: Set = values().toSet() +// } +// +//} + +//@Suppress("unused") +//sealed class PrototypeType( +// val id: String +//) { +// +// object AmbientSound : PrototypeType("ambient-sound") +// object Animation : PrototypeType("animation") +// object EditorController : PrototypeType("editor-controller") +// object Font : PrototypeType("font") +// object GodController : PrototypeType("god-controller") +// object MapGenPresets : PrototypeType("map-gen-presets") +// object MapSettings : PrototypeType("map-settings") +// object MouseCursor : PrototypeType("mouse-cursor") +// object Sound : PrototypeType("sound") +// object SpectatorController : PrototypeType("spectator-controller") +// object Sprite : PrototypeType("sprite") +// object TileEffect : PrototypeType("tile-effect") +// object TipsAndTricksItemCategory : PrototypeType("tips-and-tricks-item-category") +// object TriggerTargetType : PrototypeType("trigger-target-type") +// object WindSound : PrototypeType("wind-sound") +// +// +// object Achievement : PrototypeType("achievement") +// object BuildEntityAchievement : PrototypeType("build-entity-achievement") +// object CombatRobotCountAchievement : PrototypeType("combat-robot-count") +// object ConstructWithRobotsAchievement : PrototypeType("construct-with-robots-achievement") +// object DeconstructWithRobotsAchievement : PrototypeType("deconstruct-with-robots-achievement") +// object DeliverByRobotsAchievement : PrototypeType("deliver-by-robots-achievement") +// object DontBuildEntityAchievement : PrototypeType("dont-build-entity-achievement") +// object DontCraftManuallyAchievement : PrototypeType("dont-craft-manually-achievement") +// object DontUseEntityInEnergyProductionAchievement : PrototypeType("dont-use-entity-in-energy-production-achievement") +// +// +// object FinishTheGameAchievement : PrototypeType("finish-the-game-achievement") +// object GroupAttackAchievement : PrototypeType("group-attack-achievement") +// object KillAchievement : PrototypeType("kill-achievement") +// object PlayerDamagedAchievement : PrototypeType("player-damaged-achievement") +// object ProduceAchievement : PrototypeType("produce-achievement") +// object ProducePerHourAchievement : PrototypeType("produce-per-hour-achievement") +// object ResearchAchievement : PrototypeType("research-achievement") +// object TrainPathAchievement : PrototypeType("train-path-achievement") +// object AmmoCategory : PrototypeType("ammo-category") +// object AutoplaceControl : PrototypeType("autoplace-control") +// object CustomInput : PrototypeType("custom-input") +// object DamageType : PrototypeType("damage-type") +// object Decorative : PrototypeType("optimized-decorative") +// +// +// object Entity : PrototypeType("stract>") +// object Arrow : PrototypeType("arrow") +// object ArtilleryFlare : PrototypeType("artillery-flare") +// object ArtilleryProjectile : PrototypeType("artillery-projectile") +// object Beam : PrototypeType("beam") +// object CharacterCorpse : PrototypeType("character-corpse") +// object Cliff : PrototypeType("cliff") +// object Corpse : PrototypeType("corpse") +// object RailRemnants : PrototypeType("rail-remnants") +// object DeconstructibleTileProxy : PrototypeType("deconstructible-tile-proxy") +// object EntityGhost : PrototypeType("entity-ghost") +// /** for migration, cannot be used */ +// object EntityParticle : PrototypeType("particle") +// /** for migration, cannot be used */ +// object LeafParticle : PrototypeType("leaf-particle") +// +// +// object EntityWithOwner : PrototypeType("stract>") +// object Accumulator : PrototypeType("accumulator") +// object ArtilleryTurret : PrototypeType("artillery-turret") +// object Beacon : PrototypeType("beacon") +// object Boiler : PrototypeType("boiler") +// object BurnerGenerator : PrototypeType("burner-generator") +// object Character : PrototypeType("character") +// +// +// object Combinator : PrototypeType("stract>") +// object ArithmeticCombinator : PrototypeType("arithmetic-combinator") +// object DeciderCombinator : PrototypeType("decider-combinator") +// object ConstantCombinator : PrototypeType("constant-combinator") +// object Container : PrototypeType("container") +// object LogisticContainer : PrototypeType("logistic-container") +// object InfinityContainer : PrototypeType("infinity-container") +// +// +// object CraftingMachine : PrototypeType("stract>") +// object AssemblingMachine : PrototypeType("assembling-machine") +// object RocketSilo : PrototypeType("rocket-silo") +// object Furnace : PrototypeType("furnace") +// object ElectricEnergyInterface : PrototypeType("electric-energy-interface") +// object ElectricPole : PrototypeType("electric-pole") +// object EnemySpawner : PrototypeType("unit-spawner") +// +// +// object FlyingRobot : PrototypeType("stract>") +// object CombatRobot : PrototypeType("combat-robot") , PrototypeAbstract.FlyingRobot +// +// +// object RobotWithLogisticInterface : PrototypeType("stract>") +// object ConstructionRobot : PrototypeType("construction-robot") +// object LogisticRobot : PrototypeType("logistic-robot") +// object Gate : PrototypeType("gate") +// object Generator : PrototypeType("generator") +// object HeatInterface : PrototypeType("heat-interface") +// object HeatPipe : PrototypeType("heat-pipe") +// object Inserter : PrototypeType("inserter") +// object Lab : PrototypeType("lab") +// object Lamp : PrototypeType("lamp") +// object LandMine : PrototypeType("land-mine") +// object LinkedContainer : PrototypeType("linked-container") +// object Market : PrototypeType("market") +// object MiningDrill : PrototypeType("mining-drill") +// object OffshorePump : PrototypeType("offshore-pump") +// object Pipe : PrototypeType("pipe") +// object InfinityPipe : PrototypeType("infinity-pipe") +// object PipeToGround : PrototypeType("pipe-to-ground") +// object PlayerPort : PrototypeType("player-port") +// object PowerSwitch : PrototypeType("power-switch") +// object ProgrammableSpeaker : PrototypeType("programmable-speaker") +// object Pump : PrototypeType("pump") +// object Radar : PrototypeType("radar") +// +// object CurvedRail : PrototypeType("curved-rail"), PrototypeAbstract.Rail +// object StraightRail : PrototypeType("straight-rail"), PrototypeAbstract.Rail +// +// object RailSignalBase : PrototypeType("stract>") +// object RailChainSignal : PrototypeType("rail-chain-signal") +// object RailSignal : PrototypeType("rail-signal") +// object Reactor : PrototypeType("reactor") +// object Roboport : PrototypeType("roboport") +// object SimpleEntityWithOwner : PrototypeType("simple-entity-with-owner") +// object SimpleEntityWithForce : PrototypeType("simple-entity-with-force") +// object SolarPanel : PrototypeType("solar-panel") +// object StorageTank : PrototypeType("storage-tank") +// object TrainStop : PrototypeType("train-stop") +// +// +// object TransportBeltConnectable : PrototypeType("stract>") +// object LinkedBelt : PrototypeType("linked-belt") +// object Loader1x1 : PrototypeType("loader-1x1") +// object Loader1x2 : PrototypeType("loader") +// object Splitter : PrototypeType("splitter") +// object TransportBelt : PrototypeType("transport-belt") +// object UndergroundBelt : PrototypeType("underground-belt") +// object Turret : PrototypeType("turret") +// object AmmoTurret : PrototypeType("ammo-turret") +// object ElectricTurret : PrototypeType("electric-turret") +// object FluidTurret : PrototypeType("fluid-turret") +// object Unit : PrototypeType("unit") +// +// +// object Car : PrototypeType("car>"), PrototypeAbstract.Vehicle +// object SpiderVehicle : PrototypeType("spider-vehicle"), PrototypeAbstract.Vehicle +// +// +// object ArtilleryWagon : PrototypeType("artillery-wagon"), PrototypeAbstract.RollingStock +// object CargoWagon : PrototypeType("cargo-wagon"), PrototypeAbstract.RollingStock +// object FluidWagon : PrototypeType("fluid-wagon"), PrototypeAbstract.RollingStock +// object Locomotive : PrototypeType("locomotive"), PrototypeAbstract.RollingStock +// +// object Wall : PrototypeType("wall") +// +// +// object Fish : PrototypeType("fish"), PrototypeAbstract.EntityWithHealth +// object SimpleEntity : PrototypeType("simple-entity"), PrototypeAbstract.EntityWithHealth +// object SpiderLeg : PrototypeType("spider-leg"), PrototypeAbstract.EntityWithHealth +// object Tree : PrototypeType("tree"), PrototypeAbstract.EntityWithHealth +// +// +// object Explosion : PrototypeType("explosion"), +// object FlameThrowerExplosion : PrototypeType("flame-thrower-explosion"), +// object FireFlame : PrototypeType("fire"), +// object FluidStream : PrototypeType("stream"), +// object FlyingText : PrototypeType("flying-text"), +// object HighlightBoxEntity : PrototypeType("highlight-box"), +// object ItemEntity : PrototypeType("item-entity"), +// object ItemRequestProxy : PrototypeType("item-request-proxy"), +// object ParticleSource : PrototypeType("particle-source"), +// object Projectile : PrototypeType("projectile"), +// object ResourceEntity : PrototypeType("resource"), +// object RocketSiloRocket : PrototypeType("rocket-silo-rocket"), +// object RocketSiloRocketShadow : PrototypeType("rocket-silo-rocket-shadow"), +// +// /** for migration, cannot be used */ +// object SimpleSmoke : PrototypeType("smoke"), PrototypeAbstract.Smoke +// object SmokeWithTrigger : PrototypeType("smoke-with-trigger"), PrototypeAbstract.Smoke +// object SpeechBubble : PrototypeType("speech-bubble"), PrototypeAbstract.Smoke +// object Sticker : PrototypeType("sticker"), PrototypeAbstract.Smoke +// object TileGhost : PrototypeType("tile-ghost"), PrototypeAbstract.Smoke +// +// object Equipment : PrototypeType("abstract>") +// object ActiveDefenseEquipment : PrototypeType("active-defense-equipment") +// object BatteryEquipment : PrototypeType("battery-equipment") +// object BeltImmunityEquipment : PrototypeType("belt-immunity-equipment") +// object EnergyShieldEquipment : PrototypeType("energy-shield-equipment") +// object GeneratorEquipment : PrototypeType("generator-equipment") +// object MovementBonusEquipment : PrototypeType("movement-bonus-equipment") +// object NightVisionEquipment : PrototypeType("night-vision-equipment") +// object RoboportEquipment : PrototypeType("roboport-equipment") +// object SolarPanelEquipment : PrototypeType("solar-panel-equipment") +// object EquipmentCategory : PrototypeType("equipment-category") +// object EquipmentGrid : PrototypeType("equipment-grid") +// object Fluid : PrototypeType("fluid") +// object FuelCategory : PrototypeType("fuel-category") +// object GuiStyle : PrototypeType("gui-style") +// object Item : PrototypeType("item") +// object AmmoItem : PrototypeType("ammo") +// object Capsule : PrototypeType("capsule") +// object Gun : PrototypeType("gun") +// object ItemWithEntityData : PrototypeType("item-with-entity-data") +// object ItemWithLabel : PrototypeType("item-with-label") +// object ItemWithInventory : PrototypeType("item-with-inventory") +// object BlueprintBook : PrototypeType("blueprint-book") +// object ItemWithTags : PrototypeType("item-with-tags") +// object SelectionTool : PrototypeType("selection-tool") +// object BlueprintItem : PrototypeType("blueprint") +// object CopyPasteTool : PrototypeType("copy-paste-tool") +// object DeconstructionItem : PrototypeType("deconstruction-item") +// object UpgradeItem : PrototypeType("upgrade-item") +// object Module : PrototypeType("module") +// object RailPlanner : PrototypeType("rail-planner") +// object SpidertronRemote : PrototypeType("spidertron-remote") +// object Tool : PrototypeType("tool") +// object Armor : PrototypeType("armor") +// /** for migration, cannot be used */ +// object MiningTool : PrototypeType("mining-tool") +// object RepairTool : PrototypeType("repair-tool") +// object ItemGroup : PrototypeType("item-group") +// object ItemSubGroup : PrototypeType("item-subgroup") +// object ModuleCategory : PrototypeType("module-category") +// object NamedNoiseExpression : PrototypeType("noise-expression") +// object NoiseLayer : PrototypeType("noise-layer") +// object Particle : PrototypeType("optimized-particle") +// object Recipe : PrototypeType("recipe") +// object RecipeCategory : PrototypeType("recipe-category") +// object ResourceCategory : PrototypeType("resource-category") +// object Shortcut : PrototypeType("shortcut") +// object Technology : PrototypeType("technology") +// object Tile : PrototypeType("tile") +// object TipsAndTricksItem : PrototypeType("tips-and-tricks-item") +// object TrivialSmoke : PrototypeType("trivial-smoke") +// object Tutorial : PrototypeType("tutorial") +// object UtilityConstants : PrototypeType("utility-constants") +// object UtilitySounds : PrototypeType("utility-sounds") +// object UtilitySprites : PrototypeType("utility-sprites") +// object VirtualSignal : PrototypeType("virtual-signal") +// +//} +// +//@Suppress("unused") +//sealed interface PrototypeAbstract { +// //@formatter:off +// sealed interface PrototypeBase : PrototypeAbstract +// sealed interface Entity : PrototypeAbstract +// sealed interface EntityWithHealth : Entity +// +// sealed interface EntityWithOwner : EntityWithHealth +// +// sealed interface Combinator : EntityWithOwner +// sealed interface CraftingMachine : EntityWithOwner +// sealed interface FlyingRobot : EntityWithOwner +// +// sealed interface RobotWithLogisticInterface : FlyingRobot +// +// sealed interface Rail : EntityWithOwner +// +// sealed interface RailSignalBase : EntityWithOwner +// sealed interface TransportBeltConnectable : EntityWithOwner +// sealed interface Vehicle : EntityWithOwner +// sealed interface RollingStock : Vehicle +// sealed interface Smoke : Entity +// sealed interface Equipment : PrototypeAbstract +// //@formatter:on +//} + + +/* + + +* [[Prototype/AmbientSound]] '''ambient-sound''' +* [[Prototype/Animation]] '''animation''' +* [[Prototype/EditorController]] '''editor-controller''' +* [[Prototype/Font]] '''font''' +* [[Prototype/GodController]] '''god-controller''' +* [[Prototype/MapGenPresets]] '''map-gen-presets''' +* [[Prototype/MapSettings]] '''map-settings''' +* [[Prototype/MouseCursor]] '''mouse-cursor''' +* [[Prototype/Sound]] '''sound''' +* [[Prototype/SpectatorController]] '''spectator-controller''' +* [[Prototype/Sprite]] '''sprite''' +* [[Prototype/TileEffect]] '''tile-effect''' +* [[Prototype/TipsAndTricksItemCategory]] '''tips-and-tricks-item-category''' +* [[Prototype/TriggerTargetType]] '''trigger-target-type''' +* [[Prototype/WindSound]] '''wind-sound''' +* [[PrototypeBase]] +

): T - fun defineProperties(o: T, properties: dynamic): T - fun seal(o: T): T - fun freeze(o: T): R - fun preventExtensions(o: T): T - fun isSealed(o: Any): Boolean - fun isFrozen(o: Any): Boolean - fun isExtensible(o: Any): Boolean - fun keys(o: Any): Array - fun assign(dest: R, vararg src: T?): R - } -} diff --git a/modules/mod2/dukat-custom/classes.module_typed-factorio.kt b/modules/mod2/dukat-custom/classes.module_typed-factorio.kt deleted file mode 100644 index 6522dd4..0000000 --- a/modules/mod2/dukat-custom/classes.module_typed-factorio.kt +++ /dev/null @@ -1,5729 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import tsstdlib.Omit -import tsstdlib.Record -import defines.wire_type -import defines.circuit_connector_id -import tsstdlib.Position -import defines.inventory -import defines.direction -import defines.shooting -import defines.gui_type -import defines.control_behavior.type -import defines.rail_direction -import defines.rail_connection_direction -import defines.logistic_member_index -import defines.signal_state -import defines.chain_signal_state -import defines.entity_status -import defines.flow_precision_index -import defines.difficulty -import tsstdlib.Extract -import defines.control_behavior.inserter.circuit_mode_of_operation -import defines.control_behavior.inserter.hand_read_mode -import defines.deconstruction_item.entity_filter_mode -import defines.deconstruction_item.tile_filter_mode -import defines.deconstruction_item.tile_selection_mode -import defines.control_behavior.logistic_container.circuit_mode_of_operation as _defines_control_behavior_logistic_container_circuit_mode_of_operation -import defines.logistic_mode -import defines.control_behavior.mining_drill.resource_read_mode -import defines.input_action -import defines.controllers -import defines.alert_type -import defines.render_mode -import defines.rich_text_setting -import defines.build_check_type -import defines.chunk_generated_status -import defines.train_state -import defines.control_behavior.transport_belt.content_read_mode -import defines.group_state - -external interface LuaAISettings { - var allow_destroy_when_commands_fail: Boolean? - var allow_try_return_to_spawner: Boolean? - var do_separation: Boolean? - var path_resolution_modifier: int8 - var valid: Boolean? - var object_name: String /* "LuaAISettings" */ - fun help(): String -} - -external interface LuaAccumulatorControlBehavior : LuaControlBehavior { - var output_signal: SignalID - var valid: Boolean? - var object_name: String /* "LuaAccumulatorControlBehavior" */ - fun help(): String -} - -external interface LuaAchievementPrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var allowed_without_fight: Boolean? - var hidden: Boolean? - var valid: Boolean? - var object_name: String /* "LuaAchievementPrototype" */ - fun help(): String -} - -external interface LuaAmmoCategoryPrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var bonus_gui_order: String - var valid: Boolean? - var object_name: String /* "LuaAmmoCategoryPrototype" */ - fun help(): String -} - -external interface LuaArithmeticCombinatorControlBehavior : LuaCombinatorControlBehavior { - var parameters: ArithmeticCombinatorParameters - var valid: Boolean? - var object_name: String /* "LuaArithmeticCombinatorControlBehavior" */ - fun help(): String -} - -external interface LuaAutoplaceControlPrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var richness: Boolean? - var control_order: String - var category: String - var valid: Boolean? - var object_name: String /* "LuaAutoplaceControlPrototype" */ - fun help(): String -} - -external interface `T$0` { - var player_index: uint - var message: String -} - -external interface `T$1` { - var item_stack: LuaItemStack - var player_index: uint - var recipe: LuaRecipe -} - -external interface `T$2` { - var player_index: uint - var entity: LuaEntity - var from_player: Boolean? -} - -external interface `T$3` { - var entity: LuaEntity -} - -external interface `T$4` { - var player_index: uint - var market: LuaEntity - var offer_index: uint - var count: uint -} - -external interface `T$5` { - var entity: LuaEntity - var tags: Tags? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$6` { - var surface_index: uint - var tiles: Array -} - -external interface `T$7` { - var is_simulation: Boolean? - get() = definedExternally - set(value) = definedExternally - var is_tutorial: Boolean? - get() = definedExternally - set(value) = definedExternally - var campaign_name: String? - get() = definedExternally - set(value) = definedExternally - var level_name: String - var mod_name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface LuaBootstrap { - fun on_init(f: (() -> Unit)?) - fun on_load(f: (() -> Unit)?) - fun on_configuration_changed(f: ((param1: ConfigurationChangedData) -> Unit)?) - fun on_event(event: E, f: ((data: E) -> Unit)?, filters: Array = definedExternally) - fun on_event(event: E, f: ((data: E) -> Unit)?) - fun on_event(event: Array, f: ((data: Any) -> Unit)?) - fun on_event(event: String, f: ((data: CustomInputEvent) -> Unit)?) - fun on_nth_tick(tick: uint?, f: ((param1: NthTickEventData) -> Unit)?) - fun on_nth_tick(tick: Array?, f: ((param1: NthTickEventData) -> Unit)?) - fun register_on_entity_destroyed(entity: LuaEntity): uint64 - fun generate_event_name(): uint /* uint & `T$93` */ - fun get_event_handler(event: E): (data: Any) -> Unit - fun get_event_handler(event: String): (data: CustomInputEvent) -> Unit - fun get_event_order(): String - fun set_event_filter(event: E, filters: Array?) - fun get_event_filter(event: E): Array? - fun raise_event(event: E, data: Omit) - fun raise_console_chat(params: `T$0`) - fun raise_player_crafted_item(params: `T$1`) - fun raise_player_fast_transferred(params: `T$2`) - fun raise_biter_base_built(params: `T$3`) - fun raise_market_item_purchased(params: `T$4`) - fun raise_script_built(params: `T$3`) - fun raise_script_destroy(params: `T$3`) - fun raise_script_revive(params: `T$5`) - fun raise_script_set_tiles(params: `T$6`) - var mod_name: String - var level: `T$7` - var active_mods: Record - var object_name: String /* "LuaBootstrap" */ -} - -external interface LuaBurner { - var owner: dynamic /* LuaEntity | LuaEquipment */ - get() = definedExternally - set(value) = definedExternally - var inventory: LuaInventory - var burnt_result_inventory: LuaInventory - var heat: double - var heat_capacity: double - var remaining_burning_fuel: double - var currently_burning: LuaItemPrototype - var fuel_categories: Record - var valid: Boolean? - var object_name: String /* "LuaBurner" */ - fun help(): String -} - -external interface `T$8` { - var minimum_intensity: float - var maximum_intensity: float - var derivation_change_frequency: float - var derivation_change_deviation: float - var border_fix_speed: float - var minimum_light_size: float - var light_intensity_to_size_coefficient: float - var color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally -} - -external interface LuaBurnerPrototype { - var emissions: double - var render_no_network_icon: Boolean? - var render_no_power_icon: Boolean? - var effectivity: double - var fuel_inventory_size: uint - var burnt_inventory_size: uint - var smoke: Array - var light_flicker: `T$8` - var fuel_categories: Record - var valid: Boolean? - var object_name: String /* "LuaBurnerPrototype" */ - fun help(): String -} - -external interface LuaIterable : - tsstdlib.Iterable, - LuaIterator -// , -// LuaExtension - -external interface LuaChunkIterator : LuaIterable { - @nativeInvoke - operator fun invoke(): ChunkPositionAndArea? - var valid: Boolean? - var object_name: String /* "LuaChunkIterator" */ - fun help(): String -} - -external interface LuaCircuitNetwork { - fun get_signal(signal: SignalID): int - var entity: LuaEntity - var wire_type: wire_type - var circuit_connector_id: circuit_connector_id - var signals: Array? - var network_id: uint - var connected_circuit_count: uint - var valid: Boolean? - var object_name: String /* "LuaCircuitNetwork" */ - fun help(): String -} - -external interface LuaCombinatorControlBehavior : LuaControlBehavior { - fun get_signal_last_tick(signal: SignalID): int? - var signals_last_tick: Array -} - -external interface LuaCommandProcessor { - fun add_command(name: String, help: Any /* JsTuple */, _function: (param1: CustomCommandData) -> Unit) - fun add_command(name: String, help: String, _function: (param1: CustomCommandData) -> Unit) - fun add_command(name: String, help: Number, _function: (param1: CustomCommandData) -> Unit) - fun remove_command(name: String): Boolean? - var commands: Record | String | Number */> - var game_commands: Record | String | Number */> - var object_name: String /* "LuaCommandProcessor" */ -} - -external interface LuaConstantCombinatorControlBehavior : LuaControlBehavior { - fun set_signal(index: uint, signal: Signal) - fun get_signal(index: uint): Signal - var parameters: Array - var enabled: Boolean? - var signals_count: uint - var valid: Boolean? - var object_name: String /* "LuaConstantCombinatorControlBehavior" */ - fun help(): String -} - -external interface LuaContainerControlBehavior : LuaControlBehavior { - var valid: Boolean? - var object_name: String /* "LuaContainerControlBehavior" */ - fun help(): String -} - -external interface BaseControlSetGuiArrow { - var type: String /* "nowhere" | "goal" | "entity_info" | "active_window" | "entity" | "position" | "crafting_queue" | "item_stack" */ -} - -external interface EntityControlSetGuiArrow : BaseControlSetGuiArrow { - override var type: String /* "entity" */ - var entity: LuaEntity -} - -external interface PositionControlSetGuiArrow : BaseControlSetGuiArrow { - override var type: String /* "position" */ - var position: Position -} - -external interface CraftingQueueControlSetGuiArrow : BaseControlSetGuiArrow { - override var type: String /* "crafting_queue" */ - var crafting_queueindex: uint -} - -external interface ItemStackControlSetGuiArrow : BaseControlSetGuiArrow { - override var type: String /* "item_stack" */ - var inventory_index: inventory - var item_stack_index: uint - var source: String /* "player" | "target" */ -} - -external interface OtherControlSetGuiArrow : BaseControlSetGuiArrow { - override var type: String /* "nowhere" | "goal" | "entity_info" | "active_window" */ -} - -external interface `T$9` { - var count: uint - var recipe: dynamic /* String | LuaRecipe */ - get() = definedExternally - set(value) = definedExternally - var silent: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$10` { - var index: uint - var count: uint -} - -external interface `T$11` { - var walking: Boolean? - var direction: direction -} - -external interface `T$12` { - var mining: Boolean? - var position: Position? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$13` { - var state: shooting - var position: Position -} - -external interface `T$14` { - var repairing: Boolean? - var position: Position -} - -external interface LuaControl { - fun get_inventory(inventory: inventory): LuaInventory? - fun get_main_inventory(): LuaInventory? - fun can_insert(items: String): Boolean? - fun can_insert(items: ItemStackDefinition): Boolean? - fun can_insert(items: LuaItemStack): Boolean? - fun insert(items: String): uint - fun insert(items: ItemStackDefinition): uint - fun insert(items: LuaItemStack): uint - fun set_gui_arrow(params: EntityControlSetGuiArrow) - fun set_gui_arrow(params: PositionControlSetGuiArrow) - fun set_gui_arrow(params: CraftingQueueControlSetGuiArrow) - fun set_gui_arrow(params: ItemStackControlSetGuiArrow) - fun set_gui_arrow(params: OtherControlSetGuiArrow) - fun clear_gui_arrow() - fun get_item_count(item: String = definedExternally): uint - fun has_items_inside(): Boolean? - fun can_reach_entity(entity: LuaEntity): Boolean? - fun clear_items_inside() - fun remove_item(items: String): uint - fun remove_item(items: ItemStackDefinition): uint - fun remove_item(items: LuaItemStack): uint - fun teleport(position: Position, surface: uint = definedExternally): Boolean? - fun teleport(position: Position): Boolean? - fun teleport(position: Position, surface: String = definedExternally): Boolean? - fun teleport(position: Position, surface: LuaSurface = definedExternally): Boolean? - fun update_selected_entity(position: Position) - fun clear_selected_entity() - fun disable_flashlight() - fun enable_flashlight() - fun is_flashlight_enabled() - fun get_craftable_count(recipe: String): uint - fun get_craftable_count(recipe: LuaRecipe): uint - fun begin_crafting(params: `T$9`): uint - fun cancel_crafting(params: `T$10`) - fun mine_entity(entity: LuaEntity, force: Boolean = definedExternally): Boolean? - fun mine_tile(tile: LuaTile): Boolean? - fun is_player(): Boolean? - fun open_technology_gui(technology: String = definedExternally) - fun open_technology_gui() - fun open_technology_gui(technology: LuaTechnology = definedExternally) - fun open_technology_gui(technology: LuaTechnologyPrototype = definedExternally) - fun set_personal_logistic_slot(slot_index: uint, value: PersonalLogisticParameters): Boolean? - fun set_vehicle_logistic_slot(slot_index: uint, value: PersonalLogisticParameters): Boolean? - fun get_personal_logistic_slot(slot_index: uint): PersonalLogisticParameters - fun get_vehicle_logistic_slot(slot_index: uint): PersonalLogisticParameters - fun clear_personal_logistic_slot(slot_index: uint) - fun clear_vehicle_logistic_slot(slot_index: uint) - fun is_cursor_blueprint(): Boolean? - fun get_blueprint_entities(): Array? - fun is_cursor_empty(): Boolean? - var surface: LuaSurface - var position: PositionTable - var vehicle: LuaEntity? - var force: dynamic /* String | LuaForce */ - get() = definedExternally - set(value) = definedExternally - var selected: LuaEntity? - var opened: dynamic /* LuaEntity? | LuaItemStack? | LuaEquipment? | LuaEquipmentGrid? | LuaPlayer? | ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers | defines.gui_type? */ - get() = definedExternally - set(value) = definedExternally - var crafting_queue_size: uint - var crafting_queue_progress: double - var walking_state: `T$11` - var riding_state: RidingState - var mining_state: `T$12` - var shooting_state: `T$13` - var picking_state: Boolean? - var repair_state: `T$14` - var cursor_stack: LuaItemStack? - var cursor_ghost: dynamic /* LuaItemStack | LuaItemPrototype | String */ - get() = definedExternally - set(value) = definedExternally - var driving: Boolean? - var crafting_queue: Array - var following_robots: Array - var cheat_mode: Boolean? - var character_crafting_speed_modifier: double - var character_mining_speed_modifier: double - var character_additional_mining_categories: Array - var character_running_speed_modifier: double - var character_build_distance_bonus: uint - var character_item_drop_distance_bonus: uint - var character_reach_distance_bonus: uint - var character_resource_reach_distance_bonus: uint - var character_item_pickup_distance_bonus: uint - var character_loot_pickup_distance_bonus: uint - var character_inventory_slots_bonus: uint - var character_trash_slot_count_bonus: uint - var character_maximum_following_robot_count_bonus: uint - var character_health_bonus: float - var character_personal_logistic_requests_enabled: Boolean? - var vehicle_logistic_requests_enabled: Boolean? - var opened_gui_type: gui_type? - var build_distance: uint - var drop_item_distance: uint - var reach_distance: uint - var item_pickup_distance: double - var loot_pickup_distance: double - var resource_reach_distance: double - var in_combat: Boolean? - var character_running_speed: double - var character_mining_progress: double -} - -external interface LuaControlBehavior { - fun get_circuit_network(wire: wire_type, circuit_connector: circuit_connector_id = definedExternally): LuaCircuitNetwork? - var type: type - var entity: LuaEntity -} - -external interface LuaCustomChartTag { - fun destroy() - var icon: SignalID? - var last_user: LuaPlayer - var position: PositionTable - var text: String - var tag_number: uint - var force: LuaForce - var surface: LuaSurface - var valid: Boolean? - var object_name: String /* "LuaCustomChartTag" */ - fun help(): String -} - -external interface LuaCustomInputPrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var key_sequence: String - var alternative_key_sequence: String? - var linked_game_control: String? - var consuming: String /* "none" | "game-only" */ - var action: String - var enabled: Boolean? - var enabled_while_spectating: Boolean? - var enabled_while_in_cutscene: Boolean? - var include_selected_prototype: Boolean? - var item_to_spawn: LuaItemPrototype? - var valid: Boolean? - var object_name: String /* "LuaCustomInputPrototype" */ - fun help(): String -} - -typealias CustomTableIndex = Any - -external interface LuaCustomTableMembers { - var length: () -> uint /* () -> uint & LuaExtension */ - var valid: Boolean? - var object_name: String /* "LuaCustomTable" */ - fun help(): String -} - -external interface LuaDamagePrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var hidden: Boolean? - var valid: Boolean? - var object_name: String /* "LuaDamagePrototype" */ - fun help(): String -} - -external interface LuaDeciderCombinatorControlBehavior : LuaCombinatorControlBehavior { - var parameters: DeciderCombinatorParameters - var valid: Boolean? - var object_name: String /* "LuaDeciderCombinatorControlBehavior" */ - fun help(): String -} - -external interface LuaDecorativePrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var collision_box: BoundingBoxTable - var collision_mask: CollisionMask - var collision_mask_with_flags: CollisionMaskWithFlags - var autoplace_specification: AutoplaceSpecification? - var valid: Boolean? - var object_name: String /* "LuaDecorativePrototype" */ - fun help(): String -} - -external interface LuaElectricEnergySourcePrototype { - var buffer_capacity: double - var usage_priority: String - var input_flow_limit: double - var output_flow_limit: double - var drain: double - var emissions: double - var render_no_network_icon: Boolean? - var render_no_power_icon: Boolean? - var valid: Boolean? - var object_name: String /* "LuaElectricEnergySourcePrototype" */ - fun help(): String -} - -external interface `T$15` { - var do_cliff_correction: Boolean? - get() = definedExternally - set(value) = definedExternally - var raise_destroy: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$16` { - var force: dynamic /* String | LuaForce */ - get() = definedExternally - set(value) = definedExternally - var target: dynamic /* LuaEntity | LuaEntityPrototype | String */ - get() = definedExternally - set(value) = definedExternally - var player: dynamic /* uint? | String? | LuaPlayer? */ - get() = definedExternally - set(value) = definedExternally - var direction: direction? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$17` { - var return_item_request_proxy: Boolean? - get() = definedExternally - set(value) = definedExternally - var raise_revive: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$18` { - var rail_direction: rail_direction - var rail_connection_direction: rail_connection_direction -} - -external interface `T$19` { - var reverse: Boolean? - get() = definedExternally - set(value) = definedExternally - var by_player: dynamic /* uint? | String? | LuaPlayer? */ - get() = definedExternally - set(value) = definedExternally - var spill_items: Boolean? - get() = definedExternally - set(value) = definedExternally - var enable_looted: Boolean? - get() = definedExternally - set(value) = definedExternally - var force: dynamic /* LuaForce? | String? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$20` { - var position: Position - var surface: LuaSurface? - get() = definedExternally - set(value) = definedExternally - var force: dynamic /* String? | LuaForce? */ - get() = definedExternally - set(value) = definedExternally - var create_build_effect_smoke: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$21` { - var name: String - var amount: double - var minimum_temperature: double? - get() = definedExternally - set(value) = definedExternally - var maximum_temperature: double? - get() = definedExternally - set(value) = definedExternally - var temperature: double? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$22` { - var inventory: LuaInventory? - get() = definedExternally - set(value) = definedExternally - var force: Boolean? - get() = definedExternally - set(value) = definedExternally - var raise_destroyed: Boolean? - get() = definedExternally - set(value) = definedExternally - var ignore_minable: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$23` { - var red: Array - var green: Array -} - -external interface LuaEntity : LuaControl { - fun get_output_inventory(): LuaInventory - fun get_module_inventory(): LuaInventory? - fun get_fuel_inventory(): LuaInventory? - fun get_burnt_result_inventory(): LuaInventory? - fun damage(damage: float, force: String, type: String = definedExternally, dealer: LuaEntity = definedExternally): float - fun damage(damage: float, force: String): float - fun damage(damage: float, force: String, type: String = definedExternally): float - fun damage(damage: float, force: LuaForce, type: String = definedExternally, dealer: LuaEntity = definedExternally): float - fun damage(damage: float, force: LuaForce): float - fun damage(damage: float, force: LuaForce, type: String = definedExternally): float - fun can_be_destroyed(): Boolean? - fun destroy(params: `T$15` = definedExternally): Boolean? - fun set_command(command: AttackCommand) - fun set_command(command: GoToLocationCommand) - fun set_command(command: CompoundCommand) - fun set_command(command: GroupCommand) - fun set_command(command: AttackAreaCommand) - fun set_command(command: WanderCommand) - fun set_command(command: StopCommand) - fun set_command(command: FleeCommand) - fun set_command(command: BuildBaseCommand) - fun set_distraction_command(command: AttackCommand) - fun set_distraction_command(command: GoToLocationCommand) - fun set_distraction_command(command: CompoundCommand) - fun set_distraction_command(command: GroupCommand) - fun set_distraction_command(command: AttackAreaCommand) - fun set_distraction_command(command: WanderCommand) - fun set_distraction_command(command: StopCommand) - fun set_distraction_command(command: FleeCommand) - fun set_distraction_command(command: BuildBaseCommand) - fun has_command(): Boolean? - fun die(force: String = definedExternally, cause: LuaEntity = definedExternally): Boolean? - fun die(): Boolean? - fun die(force: String = definedExternally): Boolean? - fun die(force: LuaForce = definedExternally, cause: LuaEntity = definedExternally): Boolean? - fun die(force: LuaForce = definedExternally): Boolean? - fun has_flag(flag: String): Boolean? - fun ghost_has_flag(flag: String): Boolean? - fun add_market_item(offer: Offer) - fun remove_market_item(offer: uint): Boolean? - fun get_market_items(): Array - fun clear_market_items() - fun connect_neighbour(target: LuaEntity): Boolean? - fun connect_neighbour(target: WireConnectionDefinition): Boolean? - fun disconnect_neighbour(target: wire_type = definedExternally) - fun disconnect_neighbour() - fun disconnect_neighbour(target: LuaEntity = definedExternally) - fun disconnect_neighbour(target: WireConnectionDefinition = definedExternally) - fun order_deconstruction(force: String, player: uint = definedExternally): Boolean? - fun order_deconstruction(force: String): Boolean? - fun order_deconstruction(force: String, player: String = definedExternally): Boolean? - fun order_deconstruction(force: String, player: LuaPlayer = definedExternally): Boolean? - fun order_deconstruction(force: LuaForce, player: uint = definedExternally): Boolean? - fun order_deconstruction(force: LuaForce): Boolean? - fun order_deconstruction(force: LuaForce, player: String = definedExternally): Boolean? - fun order_deconstruction(force: LuaForce, player: LuaPlayer = definedExternally): Boolean? - fun cancel_deconstruction(force: String, player: uint = definedExternally) - fun cancel_deconstruction(force: String) - fun cancel_deconstruction(force: String, player: String = definedExternally) - fun cancel_deconstruction(force: String, player: LuaPlayer = definedExternally) - fun cancel_deconstruction(force: LuaForce, player: uint = definedExternally) - fun cancel_deconstruction(force: LuaForce) - fun cancel_deconstruction(force: LuaForce, player: String = definedExternally) - fun cancel_deconstruction(force: LuaForce, player: LuaPlayer = definedExternally) - fun to_be_deconstructed(): Boolean? - fun order_upgrade(params: `T$16`): Boolean? - fun cancel_upgrade(force: String, player: uint = definedExternally): Boolean? - fun cancel_upgrade(force: String): Boolean? - fun cancel_upgrade(force: String, player: String = definedExternally): Boolean? - fun cancel_upgrade(force: String, player: LuaPlayer = definedExternally): Boolean? - fun cancel_upgrade(force: LuaForce, player: uint = definedExternally): Boolean? - fun cancel_upgrade(force: LuaForce): Boolean? - fun cancel_upgrade(force: LuaForce, player: String = definedExternally): Boolean? - fun cancel_upgrade(force: LuaForce, player: LuaPlayer = definedExternally): Boolean? - fun to_be_upgraded(): Boolean? - fun get_request_slot(slot: uint): dynamic /* String? | ItemStackDefinition? */ - fun set_request_slot(request: String, slot: uint): Boolean? - fun set_request_slot(request: ItemStackDefinition, slot: uint): Boolean? - fun set_request_slot(request: LuaItemStack, slot: uint): Boolean? - fun clear_request_slot(slot: uint) - fun is_crafting() - fun is_opened(): Boolean? - fun is_opening(): Boolean? - fun is_closed(): Boolean? - fun is_closing(): Boolean? - fun request_to_open(force: String, extra_time: uint = definedExternally) - fun request_to_open(force: String) - fun request_to_open(force: LuaForce, extra_time: uint = definedExternally) - fun request_to_open(force: LuaForce) - fun request_to_close(force: String) - fun request_to_close(force: LuaForce) - fun get_transport_line(index: uint): LuaTransportLine - fun get_max_transport_line_index(): uint - fun launch_rocket(): Boolean? - fun revive(params: `T$17` = definedExternally): dynamic /* JsTuple | JsTuple, LuaEntity, LuaEntity?> */ - fun silent_revive(params: `T$17` = definedExternally): dynamic /* JsTuple | JsTuple, LuaEntity, LuaEntity?> */ - fun get_connected_rail(params: `T$18`): LuaEntity - fun get_connected_rails(): Array - fun get_rail_segment_entity(direction: rail_direction, in_else_out: Boolean): LuaEntity? - fun get_rail_segment_end(direction: rail_direction): dynamic /* JsTuple */ - fun get_rail_segment_length(): double - fun get_rail_segment_overlaps(): Array - fun get_filter(slot_index: uint): String? - fun set_filter(slot_index: uint, item: String) - fun get_infinity_container_filter(index: uint): InfinityInventoryFilter? - fun set_infinity_container_filter(index: uint, filter: InfinityInventoryFilter?) - fun get_infinity_pipe_filter(): InfinityPipeFilter? - fun set_infinity_pipe_filter(filter: InfinityPipeFilter?) - fun get_heat_setting(): HeatSetting - fun set_heat_setting(filter: HeatSetting) - fun get_control_behavior(): LuaControlBehavior? - fun get_or_create_control_behavior(): LuaControlBehavior? - fun get_circuit_network(wire: wire_type, circuit_connector: circuit_connector_id = definedExternally): LuaCircuitNetwork? - fun get_merged_signal(signal: SignalID, circuit_connector: circuit_connector_id = definedExternally): int - fun get_merged_signals(circuit_connector: circuit_connector_id = definedExternally): Array? - fun supports_backer_name(): Boolean? - fun copy_settings(entity: LuaEntity, by_player: uint = definedExternally): Record - fun copy_settings(entity: LuaEntity): Record - fun copy_settings(entity: LuaEntity, by_player: String = definedExternally): Record - fun copy_settings(entity: LuaEntity, by_player: LuaPlayer = definedExternally): Record - fun get_logistic_point(index: logistic_member_index = definedExternally): dynamic /* LuaLogisticPoint | Array */ - fun play_note(instrument: uint, note: uint): Boolean? - fun connect_rolling_stock(direction: rail_direction): Boolean? - fun disconnect_rolling_stock(direction: rail_direction): Boolean? - fun update_connections() - fun get_recipe(): LuaRecipe? - fun set_recipe(recipe: String?): Record - fun set_recipe(recipe: LuaRecipe?): Record - fun rotate(params: `T$19` = definedExternally): Boolean? - fun get_driver(): dynamic /* LuaEntity? | LuaPlayer? */ - fun set_driver(driver: LuaEntity?) - fun set_driver(driver: uint?) - fun set_driver(driver: String?) - fun set_driver(driver: LuaPlayer?) - fun get_passenger(): dynamic /* LuaEntity? | LuaPlayer? */ - fun set_passenger(passenger: LuaEntity) - fun set_passenger(passenger: uint) - fun set_passenger(passenger: String) - fun set_passenger(passenger: LuaPlayer) - fun is_connected_to_electric_network(): Boolean? - fun get_train_stop_trains(): Array - fun get_stopped_train(): LuaTrain? - fun clone(params: `T$20`): LuaEntity? - fun get_fluid_count(fluid: String = definedExternally): double - fun get_fluid_contents(): Record - fun remove_fluid(params: `T$21`): double - fun insert_fluid(fluid: Fluid): double - fun clear_fluid_inside() - fun get_beam_source(): BeamTarget - fun set_beam_source(source: LuaEntity) - fun set_beam_source(source: Position) - fun get_beam_target(): BeamTarget - fun set_beam_target(target: LuaEntity) - fun set_beam_target(target: Position) - fun get_radius(): double - fun get_health_ratio(): float - fun create_build_effect_smoke() - fun release_from_spawner() - fun toggle_equipment_movement_bonus() - fun can_shoot(target: LuaEntity, position: Position): Boolean? - fun start_fading_out() - fun get_upgrade_target(): LuaEntityPrototype? - fun get_upgrade_direction(): direction? - fun get_damage_to_be_taken(): float - fun deplete() - fun mine(params: `T$22` = definedExternally): Boolean? - fun spawn_decorations() - fun can_wires_reach(entity: LuaEntity): Boolean? - fun get_connected_rolling_stock(direction: rail_direction): LuaEntity - fun is_registered_for_construction(): Boolean? - fun is_registered_for_deconstruction(force: String): Boolean? - fun is_registered_for_deconstruction(force: LuaForce): Boolean? - fun is_registered_for_upgrade(): Boolean? - fun is_registered_for_repair(): Boolean? - fun add_autopilot_destination(position: Position) - fun connect_linked_belts(neighbour: LuaEntity?) - fun disconnect_linked_belts() - var name: String /* "inserter" | "filter-inserter" */ - var ghost_name: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var ghost_localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var ghost_localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var type: String - var ghost_type: String - var active: Boolean? - var destructible: Boolean? - var minable: Boolean? - var rotatable: Boolean? - var operable: Boolean? - var health: float? - var direction: direction - var supports_direction: Boolean? - var orientation: RealOrientation - var cliff_orientation: String /* "west-to-east" | "north-to-south" | "east-to-west" | "south-to-north" | "west-to-north" | "north-to-east" | "east-to-south" | "south-to-west" | "west-to-south" | "north-to-west" | "east-to-north" | "south-to-east" | "west-to-none" | "none-to-east" | "east-to-none" | "none-to-west" | "north-to-none" | "none-to-south" | "south-to-none" | "none-to-north" */ - var relative_turret_orientation: RealOrientation? - var torso_orientation: RealOrientation - var amount: uint - var initial_amount: uint? - var effectivity_modifier: float - var consumption_modifier: float - var friction_modifier: float - var driver_is_gunner: Boolean? - var vehicle_automatic_targeting_parameters: VehicleAutomaticTargetingParameters - var speed: float - var effective_speed: float - var stack: LuaItemStack - var prototype: LuaEntityPrototype - var ghost_prototype: dynamic /* LuaEntityPrototype | LuaTilePrototype */ - get() = definedExternally - set(value) = definedExternally - var drop_position: Position - var pickup_position: Position - var drop_target: LuaEntity? - var pickup_target: LuaEntity - var selected_gun_index: uint? - var energy: double - var temperature: double? - var previous_recipe: LuaRecipe? - var held_stack: LuaItemStack - var held_stack_position: PositionTable - var train: LuaTrain? - var neighbours: dynamic /* Record>? | Array>? | LuaEntity? */ - get() = definedExternally - set(value) = definedExternally - var belt_neighbours: Record> - var fluidbox: LuaFluidBox - var backer_name: String? - var entity_label: String? - var time_to_live: uint - var color: dynamic /* ColorTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var text: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var signal_state: signal_state - var chain_signal_state: chain_signal_state - var to_be_looted: Boolean? - var crafting_speed: double - var crafting_progress: float - var bonus_progress: double - var productivity_bonus: double - var pollution_bonus: double - var speed_bonus: double - var consumption_bonus: double - var belt_to_ground_type: String /* "input" | "output" */ - var loader_type: String /* "input" | "output" */ - var rocket_parts: uint - var logistic_network: LuaLogisticNetwork - var logistic_cell: LuaLogisticCell? - var item_requests: Record - var player: LuaPlayer? - var unit_group: LuaUnitGroup? - var damage_dealt: double - var kills: uint - var last_user: LuaPlayer? - var electric_buffer_size: double? - var electric_input_flow_limit: double? - var electric_output_flow_limit: double? - var electric_drain: double? - var electric_emissions: double? - var unit_number: uint? - var ghost_unit_number: uint? - var mining_progress: double? - var bonus_mining_progress: double? - var power_production: double - var power_usage: double - var bounding_box: BoundingBoxTable - var secondary_bounding_box: BoundingBoxTable? - var selection_box: BoundingBoxTable - var secondary_selection_box: BoundingBoxTable? - var mining_target: LuaEntity? - var circuit_connected_entities: `T$23` - var circuit_connection_definitions: Array - var request_slot_count: uint - var filter_slot_count: uint - var loader_container: LuaEntity - var grid: LuaEquipmentGrid? - var graphics_variation: uint8? - var tree_color_index: uint8 - var tree_color_index_max: uint8 - var tree_stage_index: uint8 - var tree_stage_index_max: uint8 - var tree_gray_stage_index: uint8 - var tree_gray_stage_index_max: uint8 - var burner: LuaBurner? - var shooting_target: LuaEntity? - var proxy_target: LuaEntity? - var stickers: Array? - var sticked_to: LuaEntity - var parameters: ProgrammableSpeakerParameters - var alert_parameters: ProgrammableSpeakerAlertParameters - var electric_network_statistics: LuaFlowStatistics - var inserter_stack_size_override: uint - var products_finished: uint - var spawner: LuaEntity? - var units: Array - var power_switch_state: Boolean? - var effects: ModuleEffects? - var infinity_container_filters: Array - var remove_unfiltered_items: Boolean? - var character_corpse_player_index: uint - var character_corpse_tick_of_death: uint - var character_corpse_death_cause: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var associated_player: LuaPlayer? - var tick_of_last_attack: uint - var tick_of_last_damage: uint - var splitter_filter: LuaItemPrototype? - var inserter_filter_mode: String /* "whitelist" | "blacklist" */ - var splitter_input_priority: String /* "left" | "none" | "right" */ - var splitter_output_priority: String /* "left" | "none" | "right" */ - var armed: Boolean? - var recipe_locked: Boolean? - var connected_rail: LuaEntity? - var trains_in_block: uint - var timeout: uint - var neighbour_bonus: double - var ai_settings: LuaAISettings - var highlight_box_type: String - var highlight_box_blink_interval: uint - var status: entity_status? - var enable_logistics_while_moving: Boolean? - var render_player: LuaPlayer? - var render_to_forces: Array? - var pump_rail_target: LuaEntity? - var moving: Boolean? - var electric_network_id: uint? - var allow_dispatching_robots: Boolean? - var auto_launch: Boolean? - var energy_generated_last_tick: double - var storage_filter: LuaItemPrototype - var request_from_buffers: Boolean? - var corpse_expires: Boolean? - var corpse_immune_to_entity_placement: Boolean? - var tags: Tags? - var command: dynamic /* AttackCommand? | GoToLocationCommand? | CompoundCommand? | GroupCommand? | AttackAreaCommand? | WanderCommand? | StopCommand? | FleeCommand? | BuildBaseCommand? */ - get() = definedExternally - set(value) = definedExternally - var distraction_command: dynamic /* AttackCommand? | GoToLocationCommand? | CompoundCommand? | GroupCommand? | AttackAreaCommand? | WanderCommand? | StopCommand? | FleeCommand? | BuildBaseCommand? */ - get() = definedExternally - set(value) = definedExternally - var time_to_next_effect: uint - var autopilot_destination: Position? - var autopilot_destinations: Array - var trains_count: uint? - var trains_limit: uint - var is_entity_with_force: Boolean? - var is_entity_with_owner: Boolean? - var is_entity_with_health: Boolean? - var combat_robot_owner: LuaEntity - var link_id: uint - var follow_target: LuaEntity - var follow_offset: Position? - var linked_belt_type: String /* "input" | "output" */ - var linked_belt_neighbour: LuaEntity? - var valid: Boolean? - var object_name: String /* "LuaEntity" */ - fun help(): String -} - -external interface `T$24` { - var minable: Boolean? - var mining_time: double - var mining_particle: String? - get() = definedExternally - set(value) = definedExternally - var products: Array? - get() = definedExternally - set(value) = definedExternally - var fluid_amount: double? - get() = definedExternally - set(value) = definedExternally - var required_fluid: String? - get() = definedExternally - set(value) = definedExternally - var mining_trigger: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$25` { - var min: double - var max: double -} - -external interface `T$26` { - var smoke_name: String - var offsets: Array - var offset_deviation: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var initial_height: float - var max_radius: float? - get() = definedExternally - set(value) = definedExternally - var speed: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var speed_multiplier: float - var speed_multiplier_deviation: float - var starting_frame: float - var starting_frame_deviation: float - var starting_frame_speed: float - var starting_frame_speed_deviation: float - var speed_from_center: float - var speed_from_center_deviation: float -} - -external interface LuaEntityPrototype { - fun has_flag(flag: String /* "not-rotatable" | "placeable-neutral" | "placeable-player" | "placeable-enemy" | "placeable-off-grid" | "player-creation" | "filter-directions" | "fast-replaceable-no-build-while-moving" | "breaths-air" | "not-repairable" | "not-on-map" | "not-deconstructable" | "not-blueprintable" | "hide-from-bonus-gui" | "hide-alt-info" | "fast-replaceable-no-cross-type-while-moving" | "no-gap-fill-while-building" | "not-flammable" | "no-automated-item-removal" | "no-automated-item-insertion" | "not-upgradable" */): Boolean? - fun get_inventory_size(index: inventory): uint? - var type: String - var name: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var max_health: float - var infinite_resource: Boolean? - var minimum_resource_amount: uint? - var normal_resource_amount: uint? - var infinite_depletion_resource_amount: uint? - var resource_category: String? - var mineable_properties: `T$24` - var items_to_place_this: Array? - var collision_box: BoundingBoxTable - var secondary_collision_box: BoundingBoxTable? - var map_generator_bounding_box: BoundingBoxTable - var selection_box: BoundingBoxTable - var drawing_box: BoundingBoxTable - var sticker_box: BoundingBoxTable - var collision_mask: CollisionMask - var collision_mask_with_flags: CollisionMaskWithFlags - var default_collision_mask_with_flags: CollisionMaskWithFlags - var order: String - var group: LuaGroup - var subgroup: LuaGroup - var healing_per_tick: float - var emissions_per_second: double - var corpses: Record - var selectable_in_game: Boolean? - var selection_priority: uint - var weight: double? - var resistances: Record - var fast_replaceable_group: String? - var next_upgrade: LuaEntityPrototype? - var loot: Array? - var repair_speed_modifier: uint? - var turret_range: uint? - var autoplace_specification: AutoplaceSpecification? - var belt_speed: double? - var result_units: Array - var attack_result: Array? - var final_attack_result: Array? - var attack_parameters: dynamic /* ProjectileAttackParameters? | StreamAttackParameters? | OtherAttackParameters? */ - get() = definedExternally - set(value) = definedExternally - var spawn_cooldown: `T$25`? - var mining_drill_radius: double? - var mining_speed: double? - var logistic_mode: String /* "requester" | "active-provider" | "passive-provider" | "buffer" | "storage" | "none" */ - var max_underground_distance: uint8? - var flags: EntityPrototypeFlags - var remains_when_mined: Array - var additional_pastable_entities: Array - var allow_copy_paste: Boolean? - var shooting_cursor_size: double - var created_smoke: `T$26`? - var created_effect: Array? - var map_color: ColorTable? - var friendly_map_color: ColorTable - var enemy_map_color: ColorTable - var build_base_evolution_requirement: double - var instruments: Array? - var max_polyphony: uint? - var module_inventory_size: uint? - var ingredient_count: uint? - var crafting_speed: double? - var crafting_categories: Record - var resource_categories: Record? - var supply_area_distance: double? - var max_wire_distance: double - var max_circuit_wire_distance: double - var energy_usage: double? - var max_energy_usage: double - var max_energy_production: double - var effectivity: double? - var consumption: double? - var friction_force: double? - var braking_force: double? - var air_resistance: double? - var tank_driving: Boolean? - var rotation_speed: double? - var turret_rotation_speed: double? - var guns: Record? - var speed: double? - var speed_multiplier_when_out_of_energy: float? - var max_payload_size: uint? - var draw_cargo: Boolean? - var energy_per_move: double? - var energy_per_tick: double? - var max_energy: double? - var min_to_charge: float? - var max_to_charge: float? - var burner_prototype: LuaBurnerPrototype? - var electric_energy_source_prototype: LuaElectricEnergySourcePrototype? - var heat_energy_source_prototype: LuaHeatEnergySourcePrototype? - var fluid_energy_source_prototype: LuaFluidEnergySourcePrototype? - var void_energy_source_prototype: LuaVoidEnergySourcePrototype? - var building_grid_bit_shift: uint - var fluid_usage_per_tick: double? - var maximum_temperature: double? - var target_temperature: double? - var fluid: LuaFluidPrototype? - var fluid_capacity: double - var pumping_speed: double? - var stack: Boolean? - var allow_custom_vectors: Boolean? - var allow_burner_leech: Boolean? - var inserter_extension_speed: double? - var inserter_rotation_speed: double? - var inserter_pickup_position: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var inserter_drop_position: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var inserter_chases_belt_items: Boolean? - var count_as_rock_for_filtered_deconstruction: Boolean? - var filter_count: uint? - var time_to_live: uint - var distribution_effectivity: double? - var explosion_beam: double? - var explosion_rotate: double? - var tree_color_count: uint8? - var alert_when_damaged: Boolean? - var alert_when_attacking: Boolean? - var color: ColorTable? - var collision_mask_collides_with_self: Boolean? - var collision_mask_collides_with_tiles_only: Boolean? - var collision_mask_considers_tile_transitions: Boolean? - var allowed_effects: Record? - var rocket_parts_required: uint? - var rocket_rising_delay: uint8? - var launch_wait_time: uint8? - var light_blinking_speed: double? - var door_opening_speed: double? - var rising_speed: double? - var engine_starting_speed: double? - var flying_speed: double? - var flying_acceleration: double? - var fixed_recipe: String? - var construction_radius: double? - var logistic_radius: double? - var energy_per_hit_point: double? - var create_ghost_on_death: Boolean? - var timeout: uint - var fluidbox_prototypes: Array - var neighbour_bonus: double - var neighbour_collision_increase: double - var container_distance: double - var belt_distance: double - var belt_length: double - var is_building: Boolean? - var automated_ammo_count: uint? - var max_speed: double? - var darkness_for_all_lamps_on: float? - var darkness_for_all_lamps_off: float? - var always_on: Boolean? - var min_darkness_to_spawn: float - var max_darkness_to_spawn: float - var call_for_help_radius: double - var max_count_of_owned_units: double - var max_friends_around_to_spawn: double - var spawning_radius: double - var spawning_spacing: double - var radius: double - var cliff_explosive_prototype: String? - var rocket_entity_prototype: LuaEntityPrototype? - var has_belt_immunity: Boolean? - var vision_distance: double? - var pollution_to_join_attack: float? - var min_pursue_time: uint? - var max_pursue_distance: double? - var radar_range: uint? - var move_while_shooting: Boolean? - var can_open_gates: Boolean? - var affected_by_tiles: Boolean? - var distraction_cooldown: uint? - var spawning_time_modifier: double? - var alert_icon_shift: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var lab_inputs: Array? - var researching_speed: double? - var item_slot_count: uint? - var base_productivity: double? - var allow_access_to_all_forces: Boolean? - var supports_direction: Boolean? - var terrain_friction_modifier: float - var allow_passengers: Boolean? - var max_distance_of_sector_revealed: uint - var max_distance_of_nearby_sector_revealed: uint - var adjacent_tile_collision_box: BoundingBoxTable - var adjacent_tile_collision_mask: CollisionMask - var adjacent_tile_collision_test: CollisionMask - var center_collision_mask: CollisionMask - var grid_prototype: LuaEquipmentGridPrototype? - var remove_decoratives: String - var related_underground_belt: LuaEntityPrototype - var running_speed: double - var maximum_corner_sliding_distance: double - var build_distance: uint - var drop_item_distance: uint - var reach_distance: uint - var reach_resource_distance: double - var item_pickup_distance: double - var loot_pickup_distance: double - var enter_vehicle_distance: double - var ticks_to_keep_gun: uint - var ticks_to_keep_aiming_direction: uint - var ticks_to_stay_in_combat: uint - var respawn_time: uint - var damage_hit_tint: ColorTable - var character_corpse: LuaEntityPrototype - var valid: Boolean? - var object_name: String /* "LuaEntityPrototype" */ - fun help(): String -} - -external interface `T$27` { - var width: uint - var height: uint -} - -external interface LuaEquipment { - var name: String - var type: String - var position: PositionTable - var shape: `T$27` - var shield: double - var max_shield: double - var max_solar_power: double - var movement_bonus: double - var generator_power: double - var energy: double - var max_energy: double - var prototype: LuaEquipmentPrototype - var burner: LuaBurner? - var valid: Boolean? - var object_name: String /* "LuaEquipment" */ - fun help(): String -} - -external interface LuaEquipmentCategoryPrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var valid: Boolean? - var object_name: String /* "LuaEquipmentCategoryPrototype" */ - fun help(): String -} - -external interface `T$28` { - var position: Position? - get() = definedExternally - set(value) = definedExternally - var equipment: LuaEquipment? - get() = definedExternally - set(value) = definedExternally - var by_player: dynamic /* uint? | String? | LuaPlayer? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$29` { - var name: String - var position: Position? - get() = definedExternally - set(value) = definedExternally - var by_player: dynamic /* uint? | String? | LuaPlayer? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$30` { - var equipment: LuaEquipment - var position: Position -} - -external interface LuaEquipmentGrid { - fun take(params: `T$28`): dynamic /* String? | ItemStackDefinition? */ - fun take_all(by_player: uint = definedExternally): Record - fun take_all(): Record - fun take_all(by_player: String = definedExternally): Record - fun take_all(by_player: LuaPlayer = definedExternally): Record - fun clear(by_player: uint = definedExternally) - fun clear() - fun clear(by_player: String = definedExternally) - fun clear(by_player: LuaPlayer = definedExternally) - fun put(params: `T$29`): LuaEquipment? - fun can_move(params: `T$30`): Boolean? - fun move(params: `T$30`): Boolean? - fun get(position: Position): LuaEquipment? - fun get_contents(): Record - var prototype: LuaEquipmentGridPrototype - var width: uint - var height: uint - var equipment: Array - var generator_energy: double - var max_solar_energy: double - var available_in_batteries: double - var battery_capacity: double - var shield: float - var max_shield: float - var inhibit_movement_bonus: Boolean? - var valid: Boolean? - var object_name: String /* "LuaEquipmentGrid" */ - fun help(): String -} - -external interface LuaEquipmentGridPrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var equipment_categories: Array - var width: uint - var height: uint - var locked: Boolean? - var valid: Boolean? - var object_name: String /* "LuaEquipmentGridPrototype" */ - fun help(): String -} - -external interface `T$31` { - var width: uint - var height: uint - var points: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$32` { - var spawn_and_station_height: float - var spawn_and_station_shadow_height_offset: float - var charge_approach_distance: float - var logistic_radius: float - var construction_radius: float - var charging_station_count: uint - var charging_distance: float - var charging_station_shift: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var charging_energy: double - var charging_threshold_distance: float - var robot_vertical_acceleration: float - var stationing_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var robot_limit: uint - var logistics_connection_distance: float - var robots_shrink_when_entering_and_exiting: Boolean? -} - -external interface LuaEquipmentPrototype { - var name: String - var type: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var shape: `T$31` - var take_result: LuaItemPrototype? - var energy_production: double - var shield: float - var energy_per_shield: double - var logistic_parameters: `T$32` - var energy_consumption: double - var movement_bonus: float - var energy_source: LuaElectricEnergySourcePrototype - var equipment_categories: Array - var burner_prototype: LuaBurnerPrototype? - var electric_energy_source_prototype: LuaElectricEnergySourcePrototype? - var background_color: ColorTable - var attack_parameters: dynamic /* ProjectileAttackParameters? | StreamAttackParameters? | OtherAttackParameters? */ - get() = definedExternally - set(value) = definedExternally - var automatic: Boolean? - var valid: Boolean? - var object_name: String /* "LuaEquipmentPrototype" */ - fun help(): String -} - -external interface `T$33` { - var name: String - var input: Boolean? - var precision_index: flow_precision_index - var count: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface LuaFlowStatistics { - fun get_input_count(name: String): dynamic /* uint64 | double */ - fun set_input_count(name: String, count: uint64) - fun get_output_count(name: String): dynamic /* uint64 | double */ - fun set_output_count(name: String, count: uint64) - fun get_flow_count(params: `T$33`): double - fun on_flow(name: String, count: float) - fun clear() - var input_counts: Record - var output_counts: Record - var force: LuaForce? - var valid: Boolean? - var object_name: String /* "LuaFlowStatistics" */ - fun help(): String -} - -typealias LuaFluidBox = Array - -external interface LuaFluidBoxPrototype { - var entity: LuaEntityPrototype - var index: uint - var pipe_connections: Array - var production_type: String /* "input" | "output" | "input-output" | "none" */ - var base_area: double - var base_level: double - var height: double - var volume: double - var filter: LuaFluidPrototype? - var minimum_temperature: double? - var maximum_temperature: double? - var secondary_draw_orders: Array - var render_layer: String - var valid: Boolean? - var object_name: String /* "LuaFluidBoxPrototype" */ - fun help(): String -} - -external interface LuaFluidEnergySourcePrototype { - var emissions: double - var render_no_network_icon: Boolean? - var render_no_power_icon: Boolean? - var effectivity: double - var burns_fluid: Boolean? - var scale_fluid_usage: Boolean? - var fluid_usage_per_tick: double - var smoke: Array - var maximum_temperature: double - var fluid_box: LuaFluidBoxPrototype - var valid: Boolean? - var object_name: String /* "LuaFluidEnergySourcePrototype" */ - fun help(): String -} - -external interface LuaFluidPrototype { - var name: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var default_temperature: double - var max_temperature: double - var heat_capacity: double - var order: String - var group: LuaGroup - var subgroup: LuaGroup - var base_color: ColorTable - var flow_color: ColorTable - var gas_temperature: double - var emissions_multiplier: double - var fuel_value: double - var hidden: Boolean? - var valid: Boolean? - var object_name: String /* "LuaFluidPrototype" */ - fun help(): String -} - -external interface LuaFontPrototype { - var name: String - var from: String - var size: int - var spacing: float - var border: Boolean? - var filtered: Boolean? - var border_color: ColorTable? - var valid: Boolean? - var object_name: String /* "LuaFontPrototype" */ - fun help(): String -} - -external interface `T$34` { - var path: dynamic /* String | */ - get() = definedExternally - set(value) = definedExternally - var position: Position? - get() = definedExternally - set(value) = definedExternally - var volume_modifier: double? - get() = definedExternally - set(value) = definedExternally - var override_sound_type: String? /* "game-effect" | "gui-effect" | "ambient" | "environment" | "walking" | "alert" | "wind" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$35` { - var name: dynamic /* String? | Array? */ - get() = definedExternally - set(value) = definedExternally - var surface: dynamic /* uint? | String? | LuaSurface? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface LuaForce { - fun get_entity_count(name: String): uint - fun disable_research() - fun enable_research() - fun disable_all_prototypes() - fun enable_all_prototypes() - fun reset_recipes() - fun enable_all_recipes() - fun enable_all_technologies() - fun research_all_technologies(include_disabled_prototypes: Boolean = definedExternally) - fun reset_technologies() - fun reset() - fun reset_technology_effects() - fun chart(surface: uint, area: BoundingBoxTable) - fun chart(surface: uint, area: Any /* JsTuple */) - fun chart(surface: String, area: BoundingBoxTable) - fun chart(surface: String, area: Any /* JsTuple */) - fun chart(surface: LuaSurface, area: BoundingBoxTable) - fun chart(surface: LuaSurface, area: Any /* JsTuple */) - fun clear_chart(surface: uint = definedExternally) - fun clear_chart() - fun clear_chart(surface: String = definedExternally) - fun clear_chart(surface: LuaSurface = definedExternally) - fun rechart() - fun chart_all(surface: uint = definedExternally) - fun chart_all() - fun chart_all(surface: String = definedExternally) - fun chart_all(surface: LuaSurface = definedExternally) - fun is_chunk_charted(surface: uint, position: ChunkPositionTable): Boolean? - fun is_chunk_charted(surface: uint, position: Any /* JsTuple */): Boolean? - fun is_chunk_charted(surface: String, position: ChunkPositionTable): Boolean? - fun is_chunk_charted(surface: String, position: Any /* JsTuple */): Boolean? - fun is_chunk_charted(surface: LuaSurface, position: ChunkPositionTable): Boolean? - fun is_chunk_charted(surface: LuaSurface, position: Any /* JsTuple */): Boolean? - fun is_chunk_visible(surface: uint, position: ChunkPositionTable): Boolean? - fun is_chunk_visible(surface: uint, position: Any /* JsTuple */): Boolean? - fun is_chunk_visible(surface: String, position: ChunkPositionTable): Boolean? - fun is_chunk_visible(surface: String, position: Any /* JsTuple */): Boolean? - fun is_chunk_visible(surface: LuaSurface, position: ChunkPositionTable): Boolean? - fun is_chunk_visible(surface: LuaSurface, position: Any /* JsTuple */): Boolean? - fun cancel_charting(surface: uint = definedExternally) - fun cancel_charting() - fun cancel_charting(surface: String = definedExternally) - fun cancel_charting(surface: LuaSurface = definedExternally) - fun get_ammo_damage_modifier(ammo: String): double - fun set_ammo_damage_modifier(ammo: String, modifier: double) - fun get_gun_speed_modifier(ammo: String): double - fun set_gun_speed_modifier(ammo: String, modifier: double) - fun get_turret_attack_modifier(turret: String): double - fun set_turret_attack_modifier(turret: String, modifier: double) - fun set_cease_fire(other: String, cease_fire: Boolean) - fun set_cease_fire(other: LuaForce, cease_fire: Boolean) - fun get_cease_fire(other: String): Boolean? - fun get_cease_fire(other: LuaForce): Boolean? - fun set_friend(other: String, friend: Boolean) - fun set_friend(other: LuaForce, friend: Boolean) - fun get_friend(other: String): Boolean? - fun get_friend(other: LuaForce): Boolean? - fun is_pathfinder_busy(): Boolean? - fun kill_all_units() - fun find_logistic_network_by_position(position: Position, surface: uint): LuaLogisticNetwork? - fun find_logistic_network_by_position(position: Position, surface: String): LuaLogisticNetwork? - fun find_logistic_network_by_position(position: Position, surface: LuaSurface): LuaLogisticNetwork? - fun set_spawn_position(position: Position, surface: uint) - fun set_spawn_position(position: Position, surface: String) - fun set_spawn_position(position: Position, surface: LuaSurface) - fun get_spawn_position(surface: uint): PositionTable - fun get_spawn_position(surface: String): PositionTable - fun get_spawn_position(surface: LuaSurface): PositionTable - fun unchart_chunk(position: ChunkPositionTable, surface: uint) - fun unchart_chunk(position: ChunkPositionTable, surface: String) - fun unchart_chunk(position: ChunkPositionTable, surface: LuaSurface) - fun unchart_chunk(position: Any /* JsTuple */, surface: uint) - fun unchart_chunk(position: Any /* JsTuple */, surface: String) - fun unchart_chunk(position: Any /* JsTuple */, surface: LuaSurface) - fun get_item_launched(item: String): uint - fun set_item_launched(item: String, count: uint) - fun print(message: Any /* JsTuple */, color: ColorTable = definedExternally) - fun print(message: Any /* JsTuple */) - fun print(message: Any /* JsTuple */, color: Any /* JsTuple */ = definedExternally) - fun print(message: String, color: ColorTable = definedExternally) - fun print(message: String) - fun print(message: String, color: Any /* JsTuple */ = definedExternally) - fun print(message: Number, color: ColorTable = definedExternally) - fun print(message: Number) - fun print(message: Number, color: Any /* JsTuple */ = definedExternally) - fun get_trains(surface: uint = definedExternally): Array - fun get_trains(): Array - fun get_trains(surface: String = definedExternally): Array - fun get_trains(surface: LuaSurface = definedExternally): Array - fun add_chart_tag(surface: uint, tag: ChartTagSpec): LuaCustomChartTag? - fun add_chart_tag(surface: String, tag: ChartTagSpec): LuaCustomChartTag? - fun add_chart_tag(surface: LuaSurface, tag: ChartTagSpec): LuaCustomChartTag? - fun find_chart_tags(surface: uint, area: BoundingBoxTable = definedExternally): Array - fun find_chart_tags(surface: uint): Array - fun find_chart_tags(surface: uint, area: Any /* JsTuple */ = definedExternally): Array - fun find_chart_tags(surface: String, area: BoundingBoxTable = definedExternally): Array - fun find_chart_tags(surface: String): Array - fun find_chart_tags(surface: String, area: Any /* JsTuple */ = definedExternally): Array - fun find_chart_tags(surface: LuaSurface, area: BoundingBoxTable = definedExternally): Array - fun find_chart_tags(surface: LuaSurface): Array - fun find_chart_tags(surface: LuaSurface, area: Any /* JsTuple */ = definedExternally): Array - fun get_saved_technology_progress(technology: String): double? - fun get_saved_technology_progress(technology: LuaTechnology): double? - fun get_saved_technology_progress(technology: LuaTechnologyPrototype): double? - fun set_saved_technology_progress(technology: String, progress: double?) - fun set_saved_technology_progress(technology: LuaTechnology, progress: double?) - fun set_saved_technology_progress(technology: LuaTechnologyPrototype, progress: double?) - fun reset_evolution() - fun play_sound(params: `T$34`) - fun get_train_stops(params: `T$35` = definedExternally): Array - fun get_hand_crafting_disabled_for_recipe(recipe: String): Boolean? - fun get_hand_crafting_disabled_for_recipe(recipe: LuaRecipe): Boolean? - fun set_hand_crafting_disabled_for_recipe(recipe: String, hand_crafting_disabled: Boolean) - fun set_hand_crafting_disabled_for_recipe(recipe: LuaRecipe, hand_crafting_disabled: Boolean) - fun add_research(technology: String): Boolean? - fun add_research(technology: LuaTechnology): Boolean? - fun add_research(technology: LuaTechnologyPrototype): Boolean? - fun cancel_current_research() - fun get_linked_inventory(prototype: LuaEntity, link_id: uint): LuaInventory? - fun get_linked_inventory(prototype: LuaEntityPrototype, link_id: uint): LuaInventory? - fun get_linked_inventory(prototype: String, link_id: uint): LuaInventory? - fun is_friend(other: String): Boolean? - fun is_friend(other: LuaForce): Boolean? - fun is_enemy(other: String): Boolean? - fun is_enemy(other: LuaForce): Boolean? - var name: String - var technologies: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var recipes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var manual_mining_speed_modifier: double - var manual_crafting_speed_modifier: double - var laboratory_speed_modifier: double - var laboratory_productivity_bonus: double - var worker_robots_speed_modifier: double - var worker_robots_battery_modifier: double - var worker_robots_storage_bonus: double - var current_research: LuaTechnology? - var research_progress: double - var previous_research: LuaTechnology - var inserter_stack_size_bonus: double - var stack_inserter_capacity_bonus: uint - var character_trash_slot_count: double - var maximum_following_robot_count: uint - var following_robots_lifetime_modifier: double - var ghost_time_to_live: uint - var players: Array - var ai_controllable: Boolean? - var logistic_networks: Record> - var item_production_statistics: LuaFlowStatistics - var fluid_production_statistics: LuaFlowStatistics - var kill_count_statistics: LuaFlowStatistics - var entity_build_count_statistics: LuaFlowStatistics - var character_running_speed_modifier: double - var artillery_range_modifier: double - var character_build_distance_bonus: uint - var character_item_drop_distance_bonus: uint - var character_reach_distance_bonus: uint - var character_resource_reach_distance_bonus: double - var character_item_pickup_distance_bonus: double - var character_loot_pickup_distance_bonus: double - var character_inventory_slots_bonus: uint - var deconstruction_time_to_live: uint - var character_health_bonus: double - var max_successful_attempts_per_tick_per_construction_queue: uint - var max_failed_attempts_per_tick_per_construction_queue: uint - var zoom_to_world_enabled: Boolean? - var zoom_to_world_ghost_building_enabled: Boolean? - var zoom_to_world_blueprint_enabled: Boolean? - var zoom_to_world_deconstruction_planner_enabled: Boolean? - var zoom_to_world_selection_tool_enabled: Boolean? - var character_logistic_requests: Boolean? - var rockets_launched: uint - var items_launched: Record - var connected_players: Array - var mining_drill_productivity_bonus: double - var train_braking_force_bonus: double - var evolution_factor: double - var evolution_factor_by_pollution: double - var evolution_factor_by_time: double - var evolution_factor_by_killing_spawners: double - var friendly_fire: Boolean? - var share_chart: Boolean? - var research_queue_enabled: Boolean? - var index: uint - var research_queue: Array? - var research_enabled: Boolean? - var valid: Boolean? - var object_name: String /* "LuaForce" */ - fun help(): String -} - -external interface LuaFuelCategoryPrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var valid: Boolean? - var object_name: String /* "LuaFuelCategoryPrototype" */ - fun help(): String -} - -external interface `T$36` { - var game_finished: Boolean? - var player_won: Boolean? - var next_level: String - var can_continue: Boolean? - var victorious_force: dynamic /* String | LuaForce */ - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$37` { - var text: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var image: String? - get() = definedExternally - set(value) = definedExternally - var point_to: dynamic /* EntityGuiArrowSpecification? | PositionGuiArrowSpecification? | CraftingQueueGuiArrowSpecification? | ItemStackGuiArrowSpecification? | OtherGuiArrowSpecification? */ - get() = definedExternally - set(value) = definedExternally - var style: String? - get() = definedExternally - set(value) = definedExternally - var wrapper_frame_style: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$38` { - var player: dynamic /* uint? | String? | LuaPlayer? */ - get() = definedExternally - set(value) = definedExternally - var by_player: dynamic /* uint? | String? | LuaPlayer? */ - get() = definedExternally - set(value) = definedExternally - var surface: dynamic /* uint? | String? | LuaSurface? */ - get() = definedExternally - set(value) = definedExternally - var position: Position? - get() = definedExternally - set(value) = definedExternally - var resolution: Position? - get() = definedExternally - set(value) = definedExternally - var zoom: double? - get() = definedExternally - set(value) = definedExternally - var path: String? - get() = definedExternally - set(value) = definedExternally - var show_gui: Boolean? - get() = definedExternally - set(value) = definedExternally - var show_entity_info: Boolean? - get() = definedExternally - set(value) = definedExternally - var show_cursor_building_preview: Boolean? - get() = definedExternally - set(value) = definedExternally - var anti_alias: Boolean? - get() = definedExternally - set(value) = definedExternally - var quality: int? - get() = definedExternally - set(value) = definedExternally - var allow_in_replay: Boolean? - get() = definedExternally - set(value) = definedExternally - var daytime: double? - get() = definedExternally - set(value) = definedExternally - var water_tick: uint? - get() = definedExternally - set(value) = definedExternally - var force_render: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$39` { - var force: dynamic /* String? | LuaForce? */ - get() = definedExternally - set(value) = definedExternally - var path: String? - get() = definedExternally - set(value) = definedExternally - var by_player: dynamic /* uint? | String? | LuaPlayer? */ - get() = definedExternally - set(value) = definedExternally - var selected_technology: dynamic /* String? | LuaTechnology? | LuaTechnologyPrototype? */ - get() = definedExternally - set(value) = definedExternally - var skip_disabled: Boolean? - get() = definedExternally - set(value) = definedExternally - var quality: int? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$40` { - var name: dynamic /* String? | Array? */ - get() = definedExternally - set(value) = definedExternally - var surface: dynamic /* uint? | String? | LuaSurface? */ - get() = definedExternally - set(value) = definedExternally - var force: dynamic /* String? | LuaForce? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface LuaGameScript { - fun set_game_state(params: `T$36`) - fun get_entity_by_tag(tag: String): LuaEntity - fun show_message_dialog(params: `T$37`) - fun is_demo(): Boolean? - fun reload_script() - fun reload_mods() - fun save_atlas() - fun check_consistency() - fun regenerate_entity(entities: String) - fun regenerate_entity(entities: Array) - fun take_screenshot(params: `T$38`) - fun set_wait_for_screenshots_to_finish() - fun take_technology_screenshot(params: `T$39`) - fun table_to_json(data: table): String - fun json_to_table(json: String): dynamic /* String? | Number? | Boolean? | table? */ - fun write_file(filename: String, data: Any /* JsTuple */, append: Boolean = definedExternally, for_player: uint = definedExternally) - fun write_file(filename: String, data: Any /* JsTuple */) - fun write_file(filename: String, data: Any /* JsTuple */, append: Boolean = definedExternally) - fun write_file(filename: String, data: String, append: Boolean = definedExternally, for_player: uint = definedExternally) - fun write_file(filename: String, data: String) - fun write_file(filename: String, data: String, append: Boolean = definedExternally) - fun write_file(filename: String, data: Number, append: Boolean = definedExternally, for_player: uint = definedExternally) - fun write_file(filename: String, data: Number) - fun write_file(filename: String, data: Number, append: Boolean = definedExternally) - fun remove_path(path: String) - fun remove_offline_players(players: Array = definedExternally) - fun force_crc() - fun create_force(force: String): LuaForce - fun merge_forces(source: String, destination: String) - fun merge_forces(source: String, destination: LuaForce) - fun merge_forces(source: LuaForce, destination: String) - fun merge_forces(source: LuaForce, destination: LuaForce) - fun create_surface(name: String, settings: MapGenSettings = definedExternally): LuaSurface - fun server_save(name: String = definedExternally) - fun auto_save(name: String = definedExternally) - fun delete_surface(surface: String) - fun delete_surface(surface: LuaSurface) - fun disable_replay() - fun disable_tutorial_triggers() - fun direction_to_string(direction: direction) - fun print(message: Any /* JsTuple */, color: ColorTable = definedExternally) - fun print(message: Any /* JsTuple */) - fun print(message: Any /* JsTuple */, color: Any /* JsTuple */ = definedExternally) - fun print(message: String, color: ColorTable = definedExternally) - fun print(message: String) - fun print(message: String, color: Any /* JsTuple */ = definedExternally) - fun print(message: Number, color: ColorTable = definedExternally) - fun print(message: Number) - fun print(message: Number, color: Any /* JsTuple */ = definedExternally) - fun create_random_generator(seed: uint = definedExternally): LuaRandomGenerator - fun check_prototype_translations() - fun play_sound(params: `T$34`) - fun is_valid_sound_path(sound_path: String): Boolean? -// fun is_valid_sound_path(sound_path: String): Boolean? - fun is_valid_sprite_path(sprite_path: String): Boolean? -// fun is_valid_sprite_path(sprite_path: String): Boolean? - fun kick_player(player: uint, reason: Any /* JsTuple */ = definedExternally) - fun kick_player(player: uint) - fun kick_player(player: uint, reason: String = definedExternally) - fun kick_player(player: uint, reason: Number = definedExternally) - fun kick_player(player: String, reason: Any /* JsTuple */ = definedExternally) - fun kick_player(player: String) - fun kick_player(player: String, reason: String = definedExternally) - fun kick_player(player: String, reason: Number = definedExternally) - fun kick_player(player: LuaPlayer, reason: Any /* JsTuple */ = definedExternally) - fun kick_player(player: LuaPlayer) - fun kick_player(player: LuaPlayer, reason: String = definedExternally) - fun kick_player(player: LuaPlayer, reason: Number = definedExternally) - fun ban_player(player: uint, reason: Any /* JsTuple */ = definedExternally) - fun ban_player(player: uint) - fun ban_player(player: uint, reason: String = definedExternally) - fun ban_player(player: uint, reason: Number = definedExternally) - fun ban_player(player: String, reason: Any /* JsTuple */ = definedExternally) - fun ban_player(player: String) - fun ban_player(player: String, reason: String = definedExternally) - fun ban_player(player: String, reason: Number = definedExternally) - fun ban_player(player: LuaPlayer, reason: Any /* JsTuple */ = definedExternally) - fun ban_player(player: LuaPlayer) - fun ban_player(player: LuaPlayer, reason: String = definedExternally) - fun ban_player(player: LuaPlayer, reason: Number = definedExternally) - fun unban_player(player: uint) - fun unban_player(player: String) - fun unban_player(player: LuaPlayer) - fun purge_player(player: uint) - fun purge_player(player: String) - fun purge_player(player: LuaPlayer) - fun mute_player(player: uint) - fun mute_player(player: String) - fun mute_player(player: LuaPlayer) - fun unmute_player(player: uint) - fun unmute_player(player: String) - fun unmute_player(player: LuaPlayer) - fun count_pipe_groups() - fun is_multiplayer(): Boolean? - fun get_active_entities_count(surface: uint = definedExternally): uint - fun get_active_entities_count(): uint - fun get_active_entities_count(surface: String = definedExternally): uint - fun get_active_entities_count(surface: LuaSurface = definedExternally): uint - fun get_map_exchange_string(): String - fun parse_map_exchange_string(map_exchange_string: String): MapExchangeStringData - fun get_train_stops(params: `T$40` = definedExternally): Array - fun get_player(player: uint): LuaPlayer? - fun get_player(player: String): LuaPlayer? - fun get_surface(surface: uint): LuaSurface? - fun get_surface(surface: String): LuaSurface? - fun create_profiler(stopped: Boolean = definedExternally): LuaProfiler - fun evaluate_expression(expression: String, variables: Record = definedExternally): double - fun get_filtered_entity_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - fun get_filtered_item_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - fun get_filtered_equipment_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - fun get_filtered_mod_setting_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - fun get_filtered_achievement_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - fun get_filtered_tile_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - fun get_filtered_decorative_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - fun get_filtered_fluid_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - fun get_filtered_recipe_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - fun get_filtered_technology_prototypes(filters: Array): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - fun create_inventory(size: uint16): LuaInventory - fun get_script_inventories(mod: String = definedExternally): Record> - fun reset_time_played() - fun encode_string(string: String): String? - fun decode_string(string: String): String? - var player: LuaPlayer? - var players: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var map_settings: MapSettings - var difficulty_settings: DifficultySettings - var difficulty: difficulty - var forces: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var entity_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var item_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var fluid_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var tile_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var equipment_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var damage_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var virtual_signal_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var equipment_grid_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var recipe_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var technology_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var decorative_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var particle_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var autoplace_control_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var noise_layer_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var mod_setting_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var custom_input_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var ammo_category_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var named_noise_expressions: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var item_subgroup_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var item_group_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var fuel_category_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var resource_category_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var achievement_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var module_category_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var equipment_category_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var trivial_smoke_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var shortcut_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var recipe_category_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var font_prototypes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var map_gen_presets: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var styles: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var tick: uint - var ticks_played: uint - var tick_paused: Boolean? - var ticks_to_run: uint - var finished: Boolean? - var speed: float - var surfaces: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var active_mods: Record - var connected_players: Array - var permissions: LuaPermissionGroups - var backer_names: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var default_map_gen_settings: MapGenSettings - var enemy_has_vision_on_land_mines: Boolean? - var autosave_enabled: Boolean? - var draw_resource_selection: Boolean? - var pollution_statistics: LuaFlowStatistics - var max_force_distraction_distance: double - var max_force_distraction_chunk_distance: uint - var max_electric_pole_supply_area_distance: float - var max_electric_pole_connection_distance: double - var max_beacon_supply_area_distance: double - var max_gate_activation_distance: double - var max_inserter_reach_distance: double - var max_pipe_to_ground_distance: uint8 - var max_underground_belt_distance: uint8 - var object_name: String /* "LuaGameScript" */ -} - -external interface LuaGenericOnOffControlBehavior : LuaControlBehavior { - var disabled: Boolean? - var circuit_condition: CircuitConditionDefinition - var logistic_condition: CircuitConditionDefinition - var connect_to_logistic_network: Boolean? - var valid: Boolean? - var object_name: String - fun help(): String -} - -external interface LuaGroup { - var name: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var type: String - var group: LuaGroup? - var subgroups: Array - var order_in_recipe: String - var order: String - var valid: Boolean? - var object_name: String /* "LuaGroup" */ - fun help(): String -} - -external interface LuaGui { - fun is_valid_sprite_path(sprite_path: String): Boolean? -// fun is_valid_sprite_path(sprite_path: ): Boolean? - var player: LuaPlayer - var children: Record - var top: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var left: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var center: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var goal: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var screen: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var relative: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var valid: Boolean? - var object_name: String /* "LuaGui" */ - fun help(): String -} - -external interface BaseGuiSpec { - var type: String /* "choose-elem-button" | "drop-down" | "empty-widget" | "entity-preview" | "list-box" | "scroll-pane" | "sprite-button" | "tabbed-pane" | "text-box" | "button" | "camera" | "checkbox" | "flow" | "frame" | "label" | "line" | "minimap" | "progressbar" | "radiobutton" | "slider" | "sprite" | "switch" | "tab" | "table" | "textfield" */ - var name: String? - get() = definedExternally - set(value) = definedExternally - var caption: dynamic /* JsTuple | String? | Number? */ - get() = definedExternally - set(value) = definedExternally - var tooltip: dynamic /* JsTuple | String? | Number? */ - get() = definedExternally - set(value) = definedExternally - var enabled: Boolean? - get() = definedExternally - set(value) = definedExternally - var visible: Boolean? - get() = definedExternally - set(value) = definedExternally - var ignored_by_interaction: Boolean? - get() = definedExternally - set(value) = definedExternally - var style: String? - get() = definedExternally - set(value) = definedExternally - var tags: Tags? - get() = definedExternally - set(value) = definedExternally - var index: uint? - get() = definedExternally - set(value) = definedExternally - var anchor: GuiAnchor? - get() = definedExternally - set(value) = definedExternally -} - -external interface ButtonGuiSpec : BaseGuiSpec { - override var type: String /* "button" */ - var mouse_button_filter: dynamic /* MouseButtonFlagsTable? | MouseButtonFlagsArray? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowGuiSpec : BaseGuiSpec { - override var type: String /* "flow" */ - var direction: String? /* "horizontal" | "vertical" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FrameGuiSpec : BaseGuiSpec { - override var type: String /* "frame" */ - var direction: String? /* "horizontal" | "vertical" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface TableGuiSpec : BaseGuiSpec { - override var type: String /* "table" */ - var column_count: uint - var draw_vertical_lines: Boolean? - get() = definedExternally - set(value) = definedExternally - var draw_horizontal_lines: Boolean? - get() = definedExternally - set(value) = definedExternally - var draw_horizontal_line_after_headers: Boolean? - get() = definedExternally - set(value) = definedExternally - var vertical_centering: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TextfieldGuiSpec : BaseGuiSpec { - override var type: String /* "textfield" */ - var text: String? - get() = definedExternally - set(value) = definedExternally - var numeric: Boolean? - get() = definedExternally - set(value) = definedExternally - var allow_decimal: Boolean? - get() = definedExternally - set(value) = definedExternally - var allow_negative: Boolean? - get() = definedExternally - set(value) = definedExternally - var is_password: Boolean? - get() = definedExternally - set(value) = definedExternally - var lose_focus_on_confirm: Boolean? - get() = definedExternally - set(value) = definedExternally - var clear_and_focus_on_right_click: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ProgressbarGuiSpec : BaseGuiSpec { - override var type: String /* "progressbar" */ - var value: double? - get() = definedExternally - set(value) = definedExternally -} - -external interface CheckboxGuiSpec : BaseGuiSpec { - override var type: String /* "checkbox" */ - var state: Boolean? -} - -external interface RadiobuttonGuiSpec : BaseGuiSpec { - override var type: String /* "radiobutton" */ - var state: Boolean? -} - -external interface SpriteButtonGuiSpec : BaseGuiSpec { - override var type: String /* "sprite-button" */ - var sprite: dynamic /* String? | ? */ - get() = definedExternally - set(value) = definedExternally - var hovered_sprite: dynamic /* String? | ? */ - get() = definedExternally - set(value) = definedExternally - var clicked_sprite: dynamic /* String? | ? */ - get() = definedExternally - set(value) = definedExternally - var number: double? - get() = definedExternally - set(value) = definedExternally - var show_percent_for_small_numbers: Boolean? - get() = definedExternally - set(value) = definedExternally - var mouse_button_filter: dynamic /* MouseButtonFlagsTable? | MouseButtonFlagsArray? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface SpriteGuiSpec : BaseGuiSpec { - override var type: String /* "sprite" */ - var sprite: dynamic /* String? | ? */ - get() = definedExternally - set(value) = definedExternally - var resize_to_sprite: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ScrollPaneGuiSpec : BaseGuiSpec { - override var type: String /* "scroll-pane" */ - var horizontal_scroll_policy: String? /* "auto" | "never" | "always" | "auto-and-reserve-space" | "dont-show-but-allow-scrolling" */ - get() = definedExternally - set(value) = definedExternally - var vertical_scroll_policy: String? /* "auto" | "never" | "always" | "auto-and-reserve-space" | "dont-show-but-allow-scrolling" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface DropDownGuiSpec : BaseGuiSpec { - override var type: String /* "drop-down" */ - var items: Array | String | Number */>? - get() = definedExternally - set(value) = definedExternally - var selected_index: uint? - get() = definedExternally - set(value) = definedExternally -} - -external interface LineGuiSpec : BaseGuiSpec { - override var type: String /* "line" */ - var direction: String? /* "horizontal" | "vertical" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ListBoxGuiSpec : BaseGuiSpec { - override var type: String /* "list-box" */ - var items: Array | String | Number */>? - get() = definedExternally - set(value) = definedExternally - var selected_index: uint? - get() = definedExternally - set(value) = definedExternally -} - -external interface CameraGuiSpec : BaseGuiSpec { - override var type: String /* "camera" */ - var position: Position - var surface_index: uint? - get() = definedExternally - set(value) = definedExternally - var zoom: double? - get() = definedExternally - set(value) = definedExternally -} - -external interface ChooseElemButtonFilters { - @nativeGetter - operator fun get(key: String): Any? - @nativeSetter - operator fun set(key: String, value: Any) - var item: Array - var tile: Array - var entity: Array - var signal: Any - var fluid: Array - var recipe: Array - var decorative: Array - var achievement: Array - var equipment: Array - var technology: Array -} - -external interface BaseChooseElemButtonSpec : BaseGuiSpec { - override var type: String /* "choose-elem-button" */ - var elem_type: String /* "item" | "tile" | "entity" | "signal" | "fluid" | "recipe" | "decorative" | "item-group" | "achievement" | "equipment" | "technology" */ - var filters: Any? - get() = definedExternally - set(value) = definedExternally -} - -external interface ItemChooseElemButtonSpec : BaseChooseElemButtonSpec { - override var elem_type: String /* "item" */ - var item: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface TileChooseElemButtonSpec : BaseChooseElemButtonSpec { - override var elem_type: String /* "tile" */ - var tile: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface EntityChooseElemButtonSpec : BaseChooseElemButtonSpec { - override var elem_type: String /* "entity" */ - var entity: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignalChooseElemButtonSpec : BaseChooseElemButtonSpec { - override var elem_type: String /* "signal" */ - var signal: SignalID? - get() = definedExternally - set(value) = definedExternally -} - -external interface FluidChooseElemButtonSpec : BaseChooseElemButtonSpec { - override var elem_type: String /* "fluid" */ - var fluid: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface RecipeChooseElemButtonSpec : BaseChooseElemButtonSpec { - override var elem_type: String /* "recipe" */ - var recipe: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface DecorativeChooseElemButtonSpec : BaseChooseElemButtonSpec { - override var elem_type: String /* "decorative" */ - var decorative: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface ItemGroupChooseElemButtonSpec : BaseChooseElemButtonSpec { - @nativeGetter - operator fun get(key: String): String? - @nativeSetter - operator fun set(key: String, value: String?) - override var elem_type: String /* "item-group" */ -} - -external interface AchievementChooseElemButtonSpec : BaseChooseElemButtonSpec { - override var elem_type: String /* "achievement" */ - var achievement: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface EquipmentChooseElemButtonSpec : BaseChooseElemButtonSpec { - override var elem_type: String /* "equipment" */ - var equipment: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface TechnologyChooseElemButtonSpec : BaseChooseElemButtonSpec { - override var elem_type: String /* "technology" */ - var technology: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface TextBoxGuiSpec : BaseGuiSpec { - override var type: String /* "text-box" */ - var text: String? - get() = definedExternally - set(value) = definedExternally - var clear_and_focus_on_right_click: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface SliderGuiSpec : BaseGuiSpec { - override var type: String /* "slider" */ - var minimum_value: double? - get() = definedExternally - set(value) = definedExternally - var maximum_value: double? - get() = definedExternally - set(value) = definedExternally - var value: double? - get() = definedExternally - set(value) = definedExternally - var value_step: double? - get() = definedExternally - set(value) = definedExternally - var discrete_slider: Boolean? - get() = definedExternally - set(value) = definedExternally - var discrete_values: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface MinimapGuiSpec : BaseGuiSpec { - override var type: String /* "minimap" */ - var position: Position? - get() = definedExternally - set(value) = definedExternally - var surface_index: uint? - get() = definedExternally - set(value) = definedExternally - var chart_player_index: uint? - get() = definedExternally - set(value) = definedExternally - var force: String? - get() = definedExternally - set(value) = definedExternally - var zoom: double? - get() = definedExternally - set(value) = definedExternally -} - -external interface TabGuiSpec : BaseGuiSpec { - override var type: String /* "tab" */ - var badge_text: dynamic /* JsTuple | String? | Number? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface SwitchGuiSpec : BaseGuiSpec { - override var type: String /* "switch" */ - var switch_state: String? /* "left" | "right" | "none" */ - get() = definedExternally - set(value) = definedExternally - var allow_none_state: Boolean? - get() = definedExternally - set(value) = definedExternally - var left_label_caption: dynamic /* JsTuple | String? | Number? */ - get() = definedExternally - set(value) = definedExternally - var left_label_tooltip: dynamic /* JsTuple | String? | Number? */ - get() = definedExternally - set(value) = definedExternally - var right_label_caption: dynamic /* JsTuple | String? | Number? */ - get() = definedExternally - set(value) = definedExternally - var right_label_tooltip: dynamic /* JsTuple | String? | Number? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface OtherGuiSpec : BaseGuiSpec { - override var type: String /* "empty-widget" | "entity-preview" | "tabbed-pane" | "label" */ -} - -external interface GuiElementIndex { - @nativeGetter - operator fun get(name: String): dynamic /* ChooseElemButtonGuiElementMembers? | DropDownGuiElementMembers? | EmptyWidgetGuiElementMembers? | EntityPreviewGuiElementMembers? | ListBoxGuiElementMembers? | ScrollPaneGuiElementMembers? | SpriteButtonGuiElementMembers? | TabbedPaneGuiElementMembers? | TextBoxGuiElementMembers? | ButtonGuiElementMembers? | CameraGuiElementMembers? | CheckboxGuiElementMembers? | FlowGuiElementMembers? | FrameGuiElementMembers? | LabelGuiElementMembers? | LineGuiElementMembers? | MinimapGuiElementMembers? | ProgressbarGuiElementMembers? | RadiobuttonGuiElementMembers? | SliderGuiElementMembers? | SpriteGuiElementMembers? | SwitchGuiElementMembers? | TabGuiElementMembers? | TableGuiElementMembers? | TextfieldGuiElementMembers? */ - @nativeSetter - operator fun set(name: String, value: ChooseElemButtonGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: DropDownGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: EmptyWidgetGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: EntityPreviewGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: ListBoxGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: ScrollPaneGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: SpriteButtonGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: TabbedPaneGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: TextBoxGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: ButtonGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: CameraGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: CheckboxGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: FlowGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: FrameGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: LabelGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: LineGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: MinimapGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: ProgressbarGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: RadiobuttonGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: SliderGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: SpriteGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: SwitchGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: TabGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: TableGuiElementMembers) - @nativeSetter - operator fun set(name: String, value: TextfieldGuiElementMembers) -} - -external interface `T$41` { - var type: Type -} - -external interface BaseGuiElement { - fun add(element: Any /* ButtonGuiSpec | FlowGuiSpec | FrameGuiSpec | TableGuiSpec | TextfieldGuiSpec | ProgressbarGuiSpec | CheckboxGuiSpec | RadiobuttonGuiSpec | SpriteButtonGuiSpec | SpriteGuiSpec | ScrollPaneGuiSpec | DropDownGuiSpec | LineGuiSpec | ListBoxGuiSpec | CameraGuiSpec | ItemChooseElemButtonSpec | TileChooseElemButtonSpec | EntityChooseElemButtonSpec | SignalChooseElemButtonSpec | FluidChooseElemButtonSpec | RecipeChooseElemButtonSpec | DecorativeChooseElemButtonSpec | ItemGroupChooseElemButtonSpec | AchievementChooseElemButtonSpec | EquipmentChooseElemButtonSpec | TechnologyChooseElemButtonSpec | TextBoxGuiSpec | SliderGuiSpec | MinimapGuiSpec | TabGuiSpec | SwitchGuiSpec | OtherGuiSpec */): Extract> - fun clear() - fun destroy() - fun get_mod(): String? - fun get_index_in_parent(): uint - fun clear_items() - fun get_item(index: uint): dynamic /* JsTuple | String | Number */ - fun set_item(index: uint, string: Any /* JsTuple */) - fun set_item(index: uint, string: String) - fun set_item(index: uint, string: Number) - fun add_item(string: Any /* JsTuple */, index: uint = definedExternally) - fun add_item(string: Any /* JsTuple */) - fun add_item(string: String, index: uint = definedExternally) - fun add_item(string: String) - fun add_item(string: Number, index: uint = definedExternally) - fun add_item(string: Number) - fun remove_item(index: uint) - fun get_slider_minimum(): double - fun get_slider_maximum(): double - fun set_slider_minimum_maximum(minimum: double, maximum: double) - fun get_slider_value_step(): double - fun get_slider_discrete_slider(): Boolean? - fun get_slider_discrete_values(): Boolean? - fun set_slider_value_step(value: double) - fun set_slider_discrete_slider(value: Boolean) - fun set_slider_discrete_values(value: Boolean) - fun focus() - fun bring_to_front() - var index: uint - var gui: LuaGui - var parent: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var name: String - var caption: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var style: dynamic /* LuaStyle | String */ - get() = definedExternally - set(value) = definedExternally - var visible: Boolean? - var children_names: Array - var player_index: uint - var sprite: dynamic /* String | */ - get() = definedExternally - set(value) = definedExternally - var resize_to_sprite: Boolean? - var clicked_sprite: dynamic /* String | */ - get() = definedExternally - set(value) = definedExternally - var tooltip: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var type: String /* "choose-elem-button" | "drop-down" | "empty-widget" | "entity-preview" | "list-box" | "scroll-pane" | "sprite-button" | "tabbed-pane" | "text-box" | "button" | "camera" | "checkbox" | "flow" | "frame" | "label" | "line" | "minimap" | "progressbar" | "radiobutton" | "slider" | "sprite" | "switch" | "tab" | "table" | "textfield" */ - var children: Array - var items: Array | String | Number */> - var selected_index: uint - var number: double? - var show_percent_for_small_numbers: Boolean? - var location: dynamic /* GuiLocationTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var position: Position - var surface_index: uint - var zoom: double - var force: String? - var enabled: Boolean? - var ignored_by_interaction: Boolean? - var mouse_button_filter: dynamic /* MouseButtonFlagsTable | MouseButtonFlagsArray */ - get() = definedExternally - set(value) = definedExternally - var drag_target: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var tabs: Array - var entity: LuaEntity? - var anchor: GuiAnchor? - var tags: Tags - var valid: Boolean? - var object_name: String /* "LuaGuiElement" */ - fun help(): String -} - -external interface ChooseElemButtonGuiElementMembers : BaseGuiElement { - override var type: String /* "choose-elem-button" */ - var elem_type: String /* "item" | "tile" | "entity" | "signal" | "fluid" | "recipe" | "decorative" | "item-group" | "achievement" | "equipment" | "technology" */ - var elem_value: Any? - var elem_filters: Any - var locked: Boolean? -} - -external interface DropDownGuiElementMembers : BaseGuiElement { - override var type: String /* "drop-down" */ -} - -external interface EmptyWidgetGuiElementMembers : BaseGuiElement { - override var type: String /* "empty-widget" */ -} - -external interface EntityPreviewGuiElementMembers : BaseGuiElement { - override var type: String /* "entity-preview" */ -} - -external interface ListBoxGuiElementMembers : BaseGuiElement { - override var type: String /* "list-box" */ - fun scroll_to_item(index: int, scroll_mode: String /* "in-view" | "top-third" */ = definedExternally) -} - -external interface ScrollPaneGuiElementMembers : BaseGuiElement { - override var type: String /* "scroll-pane" */ - fun scroll_to_top() - fun scroll_to_bottom() - fun scroll_to_left() - fun scroll_to_right() - fun scroll_to_element(element: Any /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */, scroll_mode: String /* "in-view" | "top-third" */ = definedExternally) - var horizontal_scroll_policy: String /* "auto" | "never" | "always" | "auto-and-reserve-space" | "dont-show-but-allow-scrolling" */ - var vertical_scroll_policy: String /* "auto" | "never" | "always" | "auto-and-reserve-space" | "dont-show-but-allow-scrolling" */ -} - -external interface SpriteButtonGuiElementMembers : BaseGuiElement { - override var type: String /* "sprite-button" */ - var hovered_sprite: dynamic /* String | */ - get() = definedExternally - set(value) = definedExternally -} - -external interface TabbedPaneGuiElementMembers : BaseGuiElement { - override var type: String /* "tabbed-pane" */ - fun add_tab(tab: Any /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */, content: Any /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */) - fun remove_tab(tab: Any /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */) - var selected_tab_index: uint? -} - -external interface TextBoxGuiElementMembers : BaseGuiElement { - override var type: String /* "text-box" */ - fun scroll_to_top() - fun scroll_to_bottom() - fun scroll_to_left() - fun scroll_to_right() - fun select_all() - fun select(start: int, end: int) - var text: String - var selectable: Boolean? - var word_wrap: Boolean? - var read_only: Boolean? - var clear_and_focus_on_right_click: Boolean? -} - -external interface ButtonGuiElementMembers : BaseGuiElement { - override var type: String /* "button" */ -} - -external interface CameraGuiElementMembers : BaseGuiElement { - override var type: String /* "camera" */ -} - -external interface CheckboxGuiElementMembers : BaseGuiElement { - override var type: String /* "checkbox" */ - var state: Boolean? -} - -external interface FlowGuiElementMembers : BaseGuiElement { - override var type: String /* "flow" */ - var direction: String /* "horizontal" | "vertical" */ -} - -external interface FrameGuiElementMembers : BaseGuiElement { - override var type: String /* "frame" */ - fun force_auto_center() - var direction: String /* "horizontal" | "vertical" */ - var auto_center: Boolean? -} - -external interface LabelGuiElementMembers : BaseGuiElement { - override var type: String /* "label" */ -} - -external interface LineGuiElementMembers : BaseGuiElement { - override var type: String /* "line" */ - var direction: String /* "horizontal" | "vertical" */ -} - -external interface MinimapGuiElementMembers : BaseGuiElement { - override var type: String /* "minimap" */ - var minimap_player_index: uint -} - -external interface ProgressbarGuiElementMembers : BaseGuiElement { - override var type: String /* "progressbar" */ - var value: double -} - -external interface RadiobuttonGuiElementMembers : BaseGuiElement { - override var type: String /* "radiobutton" */ - var state: Boolean? -} - -external interface SliderGuiElementMembers : BaseGuiElement { - override var type: String /* "slider" */ - var slider_value: double -} - -external interface SpriteGuiElementMembers : BaseGuiElement { - override var type: String /* "sprite" */ -} - -external interface SwitchGuiElementMembers : BaseGuiElement { - override var type: String /* "switch" */ - var switch_state: String - var allow_none_state: Boolean? - var left_label_caption: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var left_label_tooltip: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var right_label_caption: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var right_label_tooltip: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally -} - -external interface TabGuiElementMembers : BaseGuiElement { - override var type: String /* "tab" */ - var badge_text: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally -} - -external interface TableGuiElementMembers : BaseGuiElement { - override var type: String /* "table" */ - var draw_vertical_lines: Boolean? - var draw_horizontal_lines: Boolean? - var draw_horizontal_line_after_headers: Boolean? - var column_count: uint - var vertical_centering: Boolean? -} - -external interface TextfieldGuiElementMembers : BaseGuiElement { - override var type: String /* "textfield" */ - fun select_all() - fun select(start: int, end: int) - var text: String - var numeric: Boolean? - var allow_decimal: Boolean? - var allow_negative: Boolean? - var is_password: Boolean? - var lose_focus_on_confirm: Boolean? - var clear_and_focus_on_right_click: Boolean? -} - -external interface LuaHeatEnergySourcePrototype { - var emissions: double - var render_no_network_icon: Boolean? - var render_no_power_icon: Boolean? - var max_temperature: double - var default_temperature: double - var specific_heat: double - var max_transfer: double - var min_temperature_gradient: double - var min_working_temperature: double - var minimum_glow_temperature: double - var connections: Array - var valid: Boolean? - var object_name: String /* "LuaHeatEnergySourcePrototype" */ - fun help(): String -} - -external interface LuaInserterControlBehavior : LuaGenericOnOffControlBehavior { - var circuit_read_hand_contents: Boolean? - var circuit_mode_of_operation: circuit_mode_of_operation - var circuit_hand_read_mode: hand_read_mode - var circuit_set_stack_size: Boolean? - var circuit_stack_control_signal: SignalID - override var valid: Boolean? - override var object_name: String /* "LuaInserterControlBehavior" */ - override fun help(): String -} - -typealias LuaInventory = Array - -external interface LuaItemPrototype { - fun has_flag(flag: String): Boolean? - fun get_ammo_type(ammo_source_type: String /* "default" | "player" | "turret" | "vehicle" */ = definedExternally): AmmoType? - var type: String /* "gun" | "mining-tool" */ - var name: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var order: String - var place_result: LuaEntityPrototype? - var place_as_equipment_result: LuaEquipmentPrototype? - var place_as_tile_result: PlaceAsTileResult? - var stackable: Boolean? - var default_request_amount: uint - var stack_size: uint - var wire_count: uint - var fuel_category: String? - var burnt_result: LuaItemPrototype? - var fuel_value: float - var fuel_acceleration_multiplier: double - var fuel_top_speed_multiplier: double - var fuel_emissions_multiplier: double - var subgroup: LuaGroup - var group: LuaGroup - var flags: ItemPrototypeFlags - var rocket_launch_products: Array - var can_be_mod_opened: Boolean? - var magazine_size: float? - var reload_time: float? - var equipment_grid: LuaEquipmentGridPrototype? - var resistances: Record? - var inventory_size_bonus: uint? - var capsule_action: CapsuleAction? - var attack_parameters: dynamic /* ProjectileAttackParameters? | StreamAttackParameters? | OtherAttackParameters? */ - get() = definedExternally - set(value) = definedExternally - var inventory_size: uint? - var item_filters: Record - var item_group_filters: Record - var item_subgroup_filters: Record - var filter_mode: String - var insertion_priority_mode: String - var localised_filter_message: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var extend_inventory_by_default: Boolean? - var default_label_color: ColorTable? - var draw_label_for_cursor_render: Boolean? - var speed: float? - var module_effects: ModuleEffects? - var category: String - var tier: uint - var limitations: Array - var limitation_message_key: String - var straight_rail: LuaEntityPrototype - var curved_rail: LuaEntityPrototype - var repair_result: Array? - var selection_border_color: ColorTable - var alt_selection_border_color: ColorTable - var selection_mode_flags: SelectionModeFlags - var alt_selection_mode_flags: SelectionModeFlags - var selection_cursor_box_type: String - var alt_selection_cursor_box_type: String - var always_include_tiles: Boolean? - var entity_filter_mode: String - var alt_entity_filter_mode: String - var tile_filter_mode: String - var alt_tile_filter_mode: String - var entity_filters: Record - var alt_entity_filters: Record - var entity_type_filters: Record - var alt_entity_type_filters: Record - var tile_filters: Record - var alt_tile_filters: Record - var entity_filter_slots: uint? - var tile_filter_slots: uint? - var durability_description_key: String - var durability: double? - var infinite: Boolean? - var mapper_count: uint? - var valid: Boolean? - var object_name: String /* "LuaItemPrototype" */ - fun help(): String -} - -external interface `T$42` { - var surface: dynamic /* uint | String | LuaSurface */ - get() = definedExternally - set(value) = definedExternally - var force: dynamic /* String | LuaForce */ - get() = definedExternally - set(value) = definedExternally - var position: Position - var force_build: Boolean? - get() = definedExternally - set(value) = definedExternally - var direction: direction? - get() = definedExternally - set(value) = definedExternally - var skip_fog_of_war: Boolean? - get() = definedExternally - set(value) = definedExternally - var by_player: dynamic /* uint? | String? | LuaPlayer? */ - get() = definedExternally - set(value) = definedExternally - var raise_built: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$43` { - var surface: dynamic /* uint | String | LuaSurface */ - get() = definedExternally - set(value) = definedExternally - var force: dynamic /* String | LuaForce */ - get() = definedExternally - set(value) = definedExternally - var area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var skip_fog_of_war: Boolean? - get() = definedExternally - set(value) = definedExternally - var by_player: dynamic /* uint? | String? | LuaPlayer? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$44` { - var surface: dynamic /* uint | String | LuaSurface */ - get() = definedExternally - set(value) = definedExternally - var force: dynamic /* String | LuaForce */ - get() = definedExternally - set(value) = definedExternally - var area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var always_include_tiles: Boolean? - get() = definedExternally - set(value) = definedExternally - var include_entities: Boolean? - get() = definedExternally - set(value) = definedExternally - var include_modules: Boolean? - get() = definedExternally - set(value) = definedExternally - var include_station_names: Boolean? - get() = definedExternally - set(value) = definedExternally - var include_trains: Boolean? - get() = definedExternally - set(value) = definedExternally - var include_fuel: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface LuaItemStack { - fun is_blueprint_setup(): Boolean? - fun get_blueprint_entities(): Array - fun set_blueprint_entities(entities: Array) - fun add_ammo(amount: float) - fun drain_ammo(amount: float) - fun add_durability(amount: double) - fun drain_durability(amount: double) - fun can_set_stack(stack: String = definedExternally): Boolean? - fun can_set_stack(): Boolean? - fun can_set_stack(stack: ItemStackDefinition = definedExternally): Boolean? - fun can_set_stack(stack: LuaItemStack = definedExternally): Boolean? - fun set_stack(stack: String = definedExternally): Boolean? - fun set_stack(): Boolean? - fun set_stack(stack: ItemStackDefinition = definedExternally): Boolean? - fun set_stack(stack: LuaItemStack = definedExternally): Boolean? - fun transfer_stack(stack: String): Boolean? - fun transfer_stack(stack: ItemStackDefinition): Boolean? - fun transfer_stack(stack: LuaItemStack): Boolean? - fun export_stack(): String - fun import_stack(data: String): int - fun swap_stack(stack: LuaItemStack): Boolean? - fun clear() - fun get_blueprint_tiles(): Array - fun set_blueprint_tiles(tiles: Array) - fun get_inventory(inventory: inventory): LuaInventory? - fun build_blueprint(params: `T$42`): Array - fun deconstruct_area(params: `T$43`) - fun cancel_deconstruct_area(params: `T$43`) - fun create_blueprint(params: `T$44`): Record - fun get_tag(tag_name: String): dynamic /* String? | Number? | Boolean? | table? */ - fun set_tag(tag_name: String, tag: String): dynamic /* String | Number | Boolean | table */ - fun set_tag(tag_name: String, tag: Number): dynamic /* String | Number | Boolean | table */ - fun set_tag(tag_name: String, tag: Boolean): dynamic /* String | Number | Boolean | table */ - fun set_tag(tag_name: String, tag: table): dynamic /* String | Number | Boolean | table */ - fun remove_tag(tag: String): Boolean? - fun clear_blueprint() - fun get_entity_filter(index: uint): String - fun set_entity_filter(index: uint, filter: String?): Boolean? - fun set_entity_filter(index: uint, filter: LuaEntityPrototype?): Boolean? - fun set_entity_filter(index: uint, filter: LuaEntity?): Boolean? - fun get_tile_filter(index: uint): String - fun set_tile_filter(index: uint, filter: String?): Boolean? - fun set_tile_filter(index: uint, filter: LuaTilePrototype?): Boolean? - fun set_tile_filter(index: uint, filter: LuaTile?): Boolean? - fun clear_deconstruction_item() - fun clear_upgrade_item() - fun get_mapper(index: uint, type: String /* "from" | "to" */): UpgradeFilter - fun set_mapper(index: uint, type: String, filter: UpgradeFilter?) - fun get_blueprint_entity_count(): uint - fun get_blueprint_entity_tags(index: uint): Tags - fun set_blueprint_entity_tags(index: uint, tags: Tags) - fun get_blueprint_entity_tag(index: uint, tag: String): dynamic /* String | Number | Boolean | table */ - fun set_blueprint_entity_tag(index: uint, tag: String, value: String?) - fun set_blueprint_entity_tag(index: uint, tag: String, value: Number?) - fun set_blueprint_entity_tag(index: uint, tag: String, value: Boolean?) - fun set_blueprint_entity_tag(index: uint, tag: String, value: table?) - fun create_grid(): LuaEquipmentGrid - var valid_for_read: Boolean? - var prototype: LuaItemPrototype - var name: String - var type: String - var count: uint - var grid: LuaEquipmentGrid? - var health: float - var durability: double? - var ammo: uint - var blueprint_icons: Array? - var blueprint_snap_to_grid: Position? - var blueprint_position_relative_to_grid: Position? - var blueprint_absolute_snapping: Boolean? - var label: String? - var label_color: dynamic /* ColorTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var allow_manual_label_change: Boolean? - var cost_to_build: Record - var extends_inventory: Boolean? - var prioritize_insertion_mode: String - var default_icons: Array - var tags: Tags - var custom_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var entity_filters: Array - var tile_filters: Array - var entity_filter_mode: entity_filter_mode - var tile_filter_mode: tile_filter_mode - var tile_selection_mode: tile_selection_mode - var trees_and_rocks_only: Boolean? - var entity_filter_count: uint - var tile_filter_count: uint - var active_index: uint? - var item_number: uint? - var connected_entity: LuaEntity? - var is_blueprint: Boolean? - var is_blueprint_book: Boolean? - var is_module: Boolean? - var is_tool: Boolean? - var is_mining_tool: Boolean? - var is_armor: Boolean? - var is_repair_tool: Boolean? - var is_item_with_label: Boolean? - var is_item_with_inventory: Boolean? - var is_item_with_entity_data: Boolean? - var is_selection_tool: Boolean? - var is_item_with_tags: Boolean? - var is_deconstruction_item: Boolean? - var is_upgrade_item: Boolean? - var valid: Boolean? - var object_name: String /* "LuaItemStack" */ - fun help(): String -} - -external interface LuaLampControlBehavior : LuaGenericOnOffControlBehavior { - var use_colors: Boolean? - var color: ColorTable? - override var valid: Boolean? - override var object_name: String /* "LuaLampControlBehavior" */ - override fun help(): String -} - -external interface LuaLazyLoadedValue { - fun get(): T - var valid: Boolean? - var object_name: String /* "LuaLazyLoadedValue" */ - fun help(): String -} - -external interface LuaLogisticCell { - fun is_in_logistic_range(position: Position): Boolean? - fun is_in_construction_range(position: Position): Boolean? - fun is_neighbour_with(other: LuaLogisticCell): Boolean? - var logistic_radius: float - var logistics_connection_distance: float - var construction_radius: float - var stationed_logistic_robot_count: uint - var stationed_construction_robot_count: uint - var mobile: Boolean? - var transmitting: Boolean? - var charge_approach_distance: float - var charging_robot_count: uint - var to_charge_robot_count: uint - var owner: LuaEntity - var logistic_network: LuaLogisticNetwork? - var neighbours: Array - var charging_robots: Array - var to_charge_robots: Array - var valid: Boolean? - var object_name: String /* "LuaLogisticCell" */ - fun help(): String -} - -external interface LuaLogisticContainerControlBehavior : LuaControlBehavior { - var circuit_mode_of_operation: _defines_control_behavior_logistic_container_circuit_mode_of_operation - var valid: Boolean? - var object_name: String /* "LuaLogisticContainerControlBehavior" */ - fun help(): String -} - -external interface `T$45` { - var name: String - var position: Position? - get() = definedExternally - set(value) = definedExternally - var include_buffers: Boolean? - get() = definedExternally - set(value) = definedExternally - var members: String? /* "storage" | "passive-provider" | "buffer" | "active-provider" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$46` { - var stack: dynamic /* String | ItemStackDefinition | LuaItemStack */ - get() = definedExternally - set(value) = definedExternally - var members: String? /* "storage" | "storage-empty" | "storage-empty-slot" | "requester" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface LuaLogisticNetwork { - fun get_item_count(item: String = definedExternally, member: String /* "storage" | "providers" */ = definedExternally): int - fun get_contents(): Record - fun remove_item(item: String, members: String /* "storage" | "passive-provider" | "buffer" | "active-provider" */ = definedExternally): uint - fun remove_item(item: String): uint - fun remove_item(item: ItemStackDefinition, members: String /* "storage" | "passive-provider" | "buffer" | "active-provider" */ = definedExternally): uint - fun remove_item(item: ItemStackDefinition): uint - fun remove_item(item: LuaItemStack, members: String /* "storage" | "passive-provider" | "buffer" | "active-provider" */ = definedExternally): uint - fun remove_item(item: LuaItemStack): uint - fun insert(item: String, members: String /* "storage" | "storage-empty" | "storage-empty-slot" | "requester" */ = definedExternally): uint - fun insert(item: String): uint - fun insert(item: ItemStackDefinition, members: String /* "storage" | "storage-empty" | "storage-empty-slot" | "requester" */ = definedExternally): uint - fun insert(item: ItemStackDefinition): uint - fun insert(item: LuaItemStack, members: String /* "storage" | "storage-empty" | "storage-empty-slot" | "requester" */ = definedExternally): uint - fun insert(item: LuaItemStack): uint - fun find_cell_closest_to(position: Position): LuaLogisticCell? - fun select_pickup_point(params: `T$45`): LuaLogisticPoint? - fun select_drop_point(params: `T$46`): LuaLogisticPoint? - var force: LuaForce - var available_logistic_robots: uint - var all_logistic_robots: uint - var available_construction_robots: uint - var all_construction_robots: uint - var robot_limit: uint - var cells: Array - var providers: Array - var empty_providers: Array - var requesters: Array - var storages: Array - var logistic_members: Array - var provider_points: Array - var passive_provider_points: Array - var active_provider_points: Array - var empty_provider_points: Array - var requester_points: Array - var storage_points: Array - var robots: Array - var construction_robots: Array - var logistic_robots: Array - var valid: Boolean? - var object_name: String /* "LuaLogisticNetwork" */ - fun help(): String -} - -external interface LuaLogisticPoint { - var owner: LuaEntity - var logistic_network: LuaLogisticNetwork - var logistic_member_index: uint - var filters: Array? - var mode: logistic_mode - var force: LuaForce - var targeted_items_pickup: Record - var targeted_items_deliver: Record - var exact: Boolean? - var valid: Boolean? - var object_name: String /* "LuaLogisticPoint" */ - fun help(): String -} - -external interface LuaMiningDrillControlBehavior : LuaGenericOnOffControlBehavior { - var circuit_enable_disable: Boolean? - var circuit_read_resources: Boolean? - var resource_read_mode: resource_read_mode - var resource_read_targets: Array - override var valid: Boolean? - override var object_name: String /* "LuaMiningDrillControlBehavior" */ - override fun help(): String -} - -external interface LuaModSettingPrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var mod: String - var setting_type: String - var default_value: dynamic /* Boolean | double | int | String */ - get() = definedExternally - set(value) = definedExternally - var minimum_value: dynamic /* double? | int? */ - get() = definedExternally - set(value) = definedExternally - var maximum_value: dynamic /* double? | int? */ - get() = definedExternally - set(value) = definedExternally - var allowed_values: dynamic /* Array? | Array? | Array? */ - get() = definedExternally - set(value) = definedExternally - var allow_blank: Boolean? - var auto_trim: Boolean? - var hidden: Boolean? - var valid: Boolean? - var object_name: String /* "LuaModSettingPrototype" */ - fun help(): String -} - -external interface LuaModuleCategoryPrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var valid: Boolean? - var object_name: String /* "LuaModuleCategoryPrototype" */ - fun help(): String -} - -external interface LuaNamedNoiseExpression { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var intended_property: String - var expression: NoiseExpression - var valid: Boolean? - var object_name: String /* "LuaNamedNoiseExpression" */ - fun help(): String -} - -external interface LuaNoiseLayerPrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var valid: Boolean? - var object_name: String /* "LuaNoiseLayerPrototype" */ - fun help(): String -} - -external interface LuaParticlePrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var regular_trigger_effect: TriggerEffectItem - var ended_in_water_trigger_effect: TriggerEffectItem - var render_layer: dynamic /* Number | */ - get() = definedExternally - set(value) = definedExternally - var render_layer_when_on_ground: dynamic /* Number | */ - get() = definedExternally - set(value) = definedExternally - var life_time: uint - var regular_trigger_effect_frequency: uint - var movement_modifier_when_on_ground: float - var movement_modifier: float - var mining_particle_frame_speed: float - var valid: Boolean? - var object_name: String /* "LuaParticlePrototype" */ - fun help(): String -} - -external interface LuaPermissionGroup { - fun add_player(player: uint): Boolean? - fun add_player(player: String): Boolean? - fun add_player(player: LuaPlayer): Boolean? - fun remove_player(player: uint): Boolean? - fun remove_player(player: String): Boolean? - fun remove_player(player: LuaPlayer): Boolean? - fun allows_action(action: input_action): Boolean? - fun set_allows_action(action: input_action, allow_action: Boolean): Boolean? - fun destroy(): Boolean? - var name: String - var players: Array - var group_id: uint - var valid: Boolean? - var object_name: String /* "LuaPermissionGroup" */ - fun help(): String -} - -external interface LuaPermissionGroups { - fun create_group(name: String = definedExternally): LuaPermissionGroup? - fun get_group(group: String): LuaPermissionGroup? - fun get_group(group: uint): LuaPermissionGroup? - var groups: Array - var valid: Boolean? - var object_name: String /* "LuaPermissionGroups" */ - fun help(): String -} - -external interface `T$47` { - var type: controllers - var character: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var waypoints: CutsceneWaypoint? - get() = definedExternally - set(value) = definedExternally - var start_position: Position? - get() = definedExternally - set(value) = definedExternally - var start_zoom: double? - get() = definedExternally - set(value) = definedExternally - var final_transition_time: uint? - get() = definedExternally - set(value) = definedExternally - var chart_mode_cutoff: double? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$48` { - var position: Position -} - -external interface `T$49` { - var entity: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var prototype: LuaEntityPrototype? - get() = definedExternally - set(value) = definedExternally - var position: Position? - get() = definedExternally - set(value) = definedExternally - var type: alert_type? - get() = definedExternally - set(value) = definedExternally - var surface: dynamic /* uint? | String? | LuaSurface? */ - get() = definedExternally - set(value) = definedExternally - var icon: SignalID? - get() = definedExternally - set(value) = definedExternally - var message: dynamic /* JsTuple | String? | Number? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$50` { - var entity: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var prototype: LuaEntityPrototype? - get() = definedExternally - set(value) = definedExternally - var position: Position? - get() = definedExternally - set(value) = definedExternally - var type: alert_type? - get() = definedExternally - set(value) = definedExternally - var surface: dynamic /* uint? | String? | LuaSurface? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$51` { - var name: String - var position: Position - var direction: direction? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$52` { - var position: Position - var direction: direction? - get() = definedExternally - set(value) = definedExternally - var alt: Boolean? - get() = definedExternally - set(value) = definedExternally - var terrain_building_size: uint? - get() = definedExternally - set(value) = definedExternally - var skip_fog_of_war: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$53` { - var text: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var position: Position? - get() = definedExternally - set(value) = definedExternally - var create_at_cursor: Boolean? - get() = definedExternally - set(value) = definedExternally - var color: dynamic /* ColorTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var time_to_live: uint? - get() = definedExternally - set(value) = definedExternally - var speed: double? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$54` { - var address: String - var name: dynamic /* JsTuple | String? | Number? */ - get() = definedExternally - set(value) = definedExternally - var description: dynamic /* JsTuple | String? | Number? */ - get() = definedExternally - set(value) = definedExternally - var password: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface LuaPlayer : LuaControl { - fun set_ending_screen_data(message: Any /* JsTuple */, file: String = definedExternally) - fun set_ending_screen_data(message: Any /* JsTuple */) - fun set_ending_screen_data(message: String, file: String = definedExternally) - fun set_ending_screen_data(message: String) - fun set_ending_screen_data(message: Number, file: String = definedExternally) - fun set_ending_screen_data(message: Number) - fun print(message: Any /* JsTuple */, color: ColorTable = definedExternally) - fun print(message: Any /* JsTuple */) - fun print(message: Any /* JsTuple */, color: Any /* JsTuple */ = definedExternally) - fun print(message: String, color: ColorTable = definedExternally) - fun print(message: String) - fun print(message: String, color: Any /* JsTuple */ = definedExternally) - fun print(message: Number, color: ColorTable = definedExternally) - fun print(message: Number) - fun print(message: Number, color: Any /* JsTuple */ = definedExternally) - fun clear_console() - fun get_goal_description(): dynamic /* JsTuple | String | Number */ - fun set_goal_description(text: Any /* JsTuple */ = definedExternally, only_update: Boolean = definedExternally) - fun set_goal_description() - fun set_goal_description(text: Any /* JsTuple */ = definedExternally) - fun set_goal_description(text: String = definedExternally, only_update: Boolean = definedExternally) - fun set_goal_description(text: String = definedExternally) - fun set_goal_description(text: Number = definedExternally, only_update: Boolean = definedExternally) - fun set_goal_description(text: Number = definedExternally) - fun set_controller(params: `T$47`) - fun drag_wire(params: `T$48`): Boolean? - fun disable_recipe_groups() - fun enable_recipe_groups() - fun disable_recipe_subgroups() - fun enable_recipe_subgroups() - fun print_entity_statistics(entities: Array = definedExternally) - fun print_robot_jobs() - fun print_lua_object_statistics() - fun log_active_entity_chunk_counts() - fun log_active_entity_counts() - fun unlock_achievement(name: String) - fun clear_cursor(): Boolean? - fun create_character(character: String = definedExternally): Boolean? - fun add_alert(entity: LuaEntity, type: alert_type) - fun add_custom_alert(entity: LuaEntity, icon: SignalID, message: Any /* JsTuple */, show_on_map: Boolean) - fun add_custom_alert(entity: LuaEntity, icon: SignalID, message: String, show_on_map: Boolean) - fun add_custom_alert(entity: LuaEntity, icon: SignalID, message: Number, show_on_map: Boolean) - fun remove_alert(params: `T$49`) - fun get_alerts(params: `T$50`): Record>> - fun mute_alert(alert_type: alert_type): Boolean? - fun unmute_alert(alert_type: alert_type): Boolean? - fun is_alert_muted(alert_type: alert_type): Boolean? - fun enable_alert(alert_type: alert_type): Boolean? - fun disable_alert(alert_type: alert_type): Boolean? - fun is_alert_enabled(alert_type: alert_type): Boolean? - fun pipette_entity(entity: String): Boolean? - fun pipette_entity(entity: LuaEntity): Boolean? - fun pipette_entity(entity: LuaEntityPrototype): Boolean? - fun can_place_entity(params: `T$51`): Boolean? - fun can_build_from_cursor(params: `T$52`): Boolean? - fun build_from_cursor(params: `T$52`) - fun use_from_cursor(position: Position) - fun play_sound(params: `T$34`) - fun get_associated_characters(): Array - fun associate_character(character: LuaEntity) - fun disassociate_character(character: LuaEntity) - fun create_local_flying_text(params: `T$53`) - fun get_quick_bar_slot(index: uint): LuaItemPrototype? - fun set_quick_bar_slot(index: uint, filter: String?) - fun set_quick_bar_slot(index: uint, filter: LuaItemPrototype?) - fun set_quick_bar_slot(index: uint, filter: LuaItemStack?) - fun get_active_quick_bar_page(index: uint): uint8? - fun set_active_quick_bar_page(screen_index: uint, page_index: uint) - fun jump_to_cutscene_waypoint(waypoint_index: uint) - fun exit_cutscene() - fun open_map(position: Position, scale: double = definedExternally) - fun zoom_to_world(position: Position, scale: double = definedExternally) - fun close_map() - fun is_shortcut_toggled(prototype_name: String): Boolean? - fun is_shortcut_available(prototype_name: String): Boolean? - fun set_shortcut_toggled(prototype_name: String, toggled: Boolean) - fun set_shortcut_available(prototype_name: String, available: Boolean) - fun connect_to_server(params: `T$54`) - fun toggle_map_editor() - fun request_translation(localised_string: Any /* JsTuple */): Boolean? - fun request_translation(localised_string: String): Boolean? - fun request_translation(localised_string: Number): Boolean? - fun get_infinity_inventory_filter(index: uint): InfinityInventoryFilter? - fun set_infinity_inventory_filter(index: uint, filter: InfinityInventoryFilter?) - fun clear_recipe_notifications() - fun add_recipe_notification(recipe: String) - fun add_to_clipboard(blueprint: LuaItemStack) - fun activate_paste() - fun start_selection(position: Position, selection_mode: String) - fun clear_selection() - var character: LuaEntity? - var cutscene_character: LuaEntity? - var index: uint - var gui: LuaGui - var opened_self: Boolean? - var controller_type: controllers - var stashed_controller_type: controllers? - var game_view_settings: GameViewSettings - var minimap_enabled: Boolean? - var color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var chat_color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var name: String - var tag: String - var connected: Boolean? - var admin: Boolean? - var entity_copy_source: LuaEntity? - var afk_time: uint - var online_time: uint - var last_online: uint - var permission_group: LuaPermissionGroup? - var mod_settings: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var ticks_to_respawn: uint? - var display_resolution: DisplayResolution - var display_scale: double - var blueprint_to_setup: LuaItemStack - var render_mode: render_mode - var spectator: Boolean? - var remove_unfiltered_items: Boolean? - var infinity_inventory_filters: Array - var auto_sort_main_inventory: Boolean? - var hand_location: ItemStackLocation -} - -external interface LuaProfiler { - fun reset() - fun stop() - fun restart() - fun add(other: LuaProfiler) - fun divide(number: double) - var valid: Boolean? - var object_name: String /* "LuaProfiler" */ - fun help(): String -} - -external interface LuaProgrammableSpeakerControlBehavior : LuaControlBehavior { - var circuit_parameters: ProgrammableSpeakerCircuitParameters - var circuit_condition: CircuitConditionDefinition - var valid: Boolean? - var object_name: String /* "LuaProgrammableSpeakerControlBehavior" */ - fun help(): String -} - -external interface LuaRCON { - fun print(message: Any /* JsTuple */) - fun print(message: String) - fun print(message: Number) - var object_name: String /* "LuaRCON" */ -} - -external interface LuaRailChainSignalControlBehavior : LuaControlBehavior { - var red_signal: SignalID - var orange_signal: SignalID - var green_signal: SignalID - var blue_signal: SignalID - var valid: Boolean? - var object_name: String /* "LuaRailChainSignalControlBehavior" */ - fun help(): String -} - -external interface LuaRailPath { - var size: uint - var current: uint - var total_distance: double - var travelled_distance: double - var rails: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var valid: Boolean? - var object_name: String /* "LuaRailPath" */ - fun help(): String -} - -external interface LuaRailSignalControlBehavior : LuaControlBehavior { - var red_signal: SignalID - var orange_signal: SignalID - var green_signal: SignalID - var close_signal: Boolean? - var read_signal: Boolean? - var circuit_condition: CircuitConditionDefinition - var valid: Boolean? - var object_name: String /* "LuaRailSignalControlBehavior" */ - fun help(): String -} - -external interface LuaRandomGenerator { - fun re_seed(seed: uint) - @nativeInvoke - operator fun invoke(lower: int = definedExternally, upper: int = definedExternally): double - var valid: Boolean? - var object_name: String /* "LuaRandomGenerator" */ - fun help(): String -} - -external interface LuaRecipe { - fun reload() - var name: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var prototype: LuaRecipePrototype - var enabled: Boolean? - var category: String - var ingredients: Array - var products: Array - var hidden: Boolean? - var hidden_from_flow_stats: Boolean? - var energy: double - var order: String - var group: LuaGroup - var subgroup: LuaGroup - var force: LuaForce - var valid: Boolean? - var object_name: String /* "LuaRecipe" */ - fun help(): String -} - -external interface LuaRecipeCategoryPrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var valid: Boolean? - var object_name: String /* "LuaRecipeCategoryPrototype" */ - fun help(): String -} - -external interface LuaRecipePrototype { - var enabled: Boolean? - var name: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var category: String - var ingredients: Array - var products: Array - var main_product: dynamic /* FluidProduct? | OtherProduct? */ - get() = definedExternally - set(value) = definedExternally - var hidden: Boolean? - var hidden_from_flow_stats: Boolean? - var hidden_from_player_crafting: Boolean? - var always_show_made_in: Boolean? - var energy: double - var order: String - var group: LuaGroup - var subgroup: LuaGroup - var request_paste_multiplier: uint - var overload_multiplier: uint - var allow_inserter_overload: Boolean? - var allow_as_intermediate: Boolean? - var allow_intermediates: Boolean? - var show_amount_in_title: Boolean? - var always_show_products: Boolean? - var emissions_multiplier: double - var allow_decomposition: Boolean? - var unlock_results: Boolean? - var valid: Boolean? - var object_name: String /* "LuaRecipePrototype" */ - fun help(): String -} - -external interface LuaRemote { - fun add_interface(name: String, functions: Record Unit>) - fun remove_interface(name: String): Boolean? - fun call(_interface: String, _function: String, vararg args: Any): Any - var interfaces: Record> - var object_name: String /* "LuaRemote" */ -} - -external interface `T$55` { - var color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var width: float - var gap_length: double? - get() = definedExternally - set(value) = definedExternally - var dash_length: double? - get() = definedExternally - set(value) = definedExternally - var from: dynamic /* Position | LuaEntity */ - get() = definedExternally - set(value) = definedExternally - var from_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var to: dynamic /* Position | LuaEntity */ - get() = definedExternally - set(value) = definedExternally - var to_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var surface: dynamic /* uint | String | LuaSurface */ - get() = definedExternally - set(value) = definedExternally - var time_to_live: uint? - get() = definedExternally - set(value) = definedExternally - var forces: Array? - get() = definedExternally - set(value) = definedExternally - var players: Array? - get() = definedExternally - set(value) = definedExternally - var visible: Boolean? - get() = definedExternally - set(value) = definedExternally - var draw_on_ground: Boolean? - get() = definedExternally - set(value) = definedExternally - var only_in_alt_mode: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$56` { - var text: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var surface: dynamic /* uint | String | LuaSurface */ - get() = definedExternally - set(value) = definedExternally - var target: dynamic /* Position | LuaEntity */ - get() = definedExternally - set(value) = definedExternally - var target_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var scale: double? - get() = definedExternally - set(value) = definedExternally - var font: String? - get() = definedExternally - set(value) = definedExternally - var time_to_live: uint? - get() = definedExternally - set(value) = definedExternally - var forces: Array? - get() = definedExternally - set(value) = definedExternally - var players: Array? - get() = definedExternally - set(value) = definedExternally - var visible: Boolean? - get() = definedExternally - set(value) = definedExternally - var draw_on_ground: Boolean? - get() = definedExternally - set(value) = definedExternally - var orientation: RealOrientation? - get() = definedExternally - set(value) = definedExternally - var alignment: String? /* "left" | "right" | "center" */ - get() = definedExternally - set(value) = definedExternally - var vertical_alignment: String? /* "top" | "middle" | "baseline" | "bottom" */ - get() = definedExternally - set(value) = definedExternally - var scale_with_zoom: Boolean? - get() = definedExternally - set(value) = definedExternally - var only_in_alt_mode: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$57` { - var color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var radius: double - var width: float? - get() = definedExternally - set(value) = definedExternally - var filled: Boolean? - var target: dynamic /* Position | LuaEntity */ - get() = definedExternally - set(value) = definedExternally - var target_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var surface: dynamic /* uint | String | LuaSurface */ - get() = definedExternally - set(value) = definedExternally - var time_to_live: uint? - get() = definedExternally - set(value) = definedExternally - var forces: Array? - get() = definedExternally - set(value) = definedExternally - var players: Array? - get() = definedExternally - set(value) = definedExternally - var visible: Boolean? - get() = definedExternally - set(value) = definedExternally - var draw_on_ground: Boolean? - get() = definedExternally - set(value) = definedExternally - var only_in_alt_mode: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$58` { - var color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var width: float? - get() = definedExternally - set(value) = definedExternally - var filled: Boolean? - var left_top: dynamic /* Position | LuaEntity */ - get() = definedExternally - set(value) = definedExternally - var left_top_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var right_bottom: dynamic /* Position | LuaEntity */ - get() = definedExternally - set(value) = definedExternally - var right_bottom_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var surface: dynamic /* uint | String | LuaSurface */ - get() = definedExternally - set(value) = definedExternally - var time_to_live: uint? - get() = definedExternally - set(value) = definedExternally - var forces: Array? - get() = definedExternally - set(value) = definedExternally - var players: Array? - get() = definedExternally - set(value) = definedExternally - var visible: Boolean? - get() = definedExternally - set(value) = definedExternally - var draw_on_ground: Boolean? - get() = definedExternally - set(value) = definedExternally - var only_in_alt_mode: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$59` { - var color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var max_radius: double - var min_radius: double - var start_angle: float - var angle: float - var target: dynamic /* Position | LuaEntity */ - get() = definedExternally - set(value) = definedExternally - var target_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var surface: dynamic /* uint | String | LuaSurface */ - get() = definedExternally - set(value) = definedExternally - var time_to_live: uint? - get() = definedExternally - set(value) = definedExternally - var forces: Array? - get() = definedExternally - set(value) = definedExternally - var players: Array? - get() = definedExternally - set(value) = definedExternally - var visible: Boolean? - get() = definedExternally - set(value) = definedExternally - var draw_on_ground: Boolean? - get() = definedExternally - set(value) = definedExternally - var only_in_alt_mode: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$60` { - var color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var vertices: Array - var target: dynamic /* Position? | LuaEntity? */ - get() = definedExternally - set(value) = definedExternally - var target_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var orientation: RealOrientation? - get() = definedExternally - set(value) = definedExternally - var orientation_target: dynamic /* Position? | LuaEntity? */ - get() = definedExternally - set(value) = definedExternally - var orientation_target_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var surface: dynamic /* uint | String | LuaSurface */ - get() = definedExternally - set(value) = definedExternally - var time_to_live: uint? - get() = definedExternally - set(value) = definedExternally - var forces: Array? - get() = definedExternally - set(value) = definedExternally - var players: Array? - get() = definedExternally - set(value) = definedExternally - var visible: Boolean? - get() = definedExternally - set(value) = definedExternally - var draw_on_ground: Boolean? - get() = definedExternally - set(value) = definedExternally - var only_in_alt_mode: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$61` { - var sprite: dynamic /* String | */ - get() = definedExternally - set(value) = definedExternally - var orientation: RealOrientation? - get() = definedExternally - set(value) = definedExternally - var x_scale: double? - get() = definedExternally - set(value) = definedExternally - var y_scale: double? - get() = definedExternally - set(value) = definedExternally - var tint: dynamic /* ColorTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var render_layer: dynamic /* Number? | ? */ - get() = definedExternally - set(value) = definedExternally - var orientation_target: dynamic /* Position? | LuaEntity? */ - get() = definedExternally - set(value) = definedExternally - var orientation_target_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var oriented_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var target: dynamic /* Position | LuaEntity */ - get() = definedExternally - set(value) = definedExternally - var target_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var surface: dynamic /* uint | String | LuaSurface */ - get() = definedExternally - set(value) = definedExternally - var time_to_live: uint? - get() = definedExternally - set(value) = definedExternally - var forces: Array? - get() = definedExternally - set(value) = definedExternally - var players: Array? - get() = definedExternally - set(value) = definedExternally - var visible: Boolean? - get() = definedExternally - set(value) = definedExternally - var only_in_alt_mode: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$62` { - var sprite: dynamic /* String | */ - get() = definedExternally - set(value) = definedExternally - var orientation: RealOrientation? - get() = definedExternally - set(value) = definedExternally - var scale: float? - get() = definedExternally - set(value) = definedExternally - var intensity: float? - get() = definedExternally - set(value) = definedExternally - var minimum_darkness: float? - get() = definedExternally - set(value) = definedExternally - var oriented: Boolean? - get() = definedExternally - set(value) = definedExternally - var color: dynamic /* ColorTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var target: dynamic /* Position | LuaEntity */ - get() = definedExternally - set(value) = definedExternally - var target_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var surface: dynamic /* uint | String | LuaSurface */ - get() = definedExternally - set(value) = definedExternally - var time_to_live: uint? - get() = definedExternally - set(value) = definedExternally - var forces: Array? - get() = definedExternally - set(value) = definedExternally - var players: Array? - get() = definedExternally - set(value) = definedExternally - var visible: Boolean? - get() = definedExternally - set(value) = definedExternally - var only_in_alt_mode: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$63` { - var animation: String - var orientation: RealOrientation? - get() = definedExternally - set(value) = definedExternally - var x_scale: double? - get() = definedExternally - set(value) = definedExternally - var y_scale: double? - get() = definedExternally - set(value) = definedExternally - var tint: dynamic /* ColorTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var render_layer: dynamic /* Number? | ? */ - get() = definedExternally - set(value) = definedExternally - var animation_speed: double? - get() = definedExternally - set(value) = definedExternally - var animation_offset: double? - get() = definedExternally - set(value) = definedExternally - var orientation_target: dynamic /* Position? | LuaEntity? */ - get() = definedExternally - set(value) = definedExternally - var orientation_target_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var oriented_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var target: dynamic /* Position | LuaEntity */ - get() = definedExternally - set(value) = definedExternally - var target_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var surface: dynamic /* uint | String | LuaSurface */ - get() = definedExternally - set(value) = definedExternally - var time_to_live: uint? - get() = definedExternally - set(value) = definedExternally - var forces: Array? - get() = definedExternally - set(value) = definedExternally - var players: Array? - get() = definedExternally - set(value) = definedExternally - var visible: Boolean? - get() = definedExternally - set(value) = definedExternally - var only_in_alt_mode: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface LuaRendering { - fun draw_line(params: `T$55`): uint64 - fun draw_text(params: `T$56`): uint64 - fun draw_circle(params: `T$57`): uint64 - fun draw_rectangle(params: `T$58`): uint64 - fun draw_arc(params: `T$59`): uint64 - fun draw_polygon(params: `T$60`): uint64 - fun draw_sprite(params: `T$61`): uint64 - fun draw_light(params: `T$62`): uint64 - fun draw_animation(params: `T$63`): uint64 - fun destroy(id: uint64) - fun is_font_valid(font_name: String): Boolean? - fun is_valid(id: uint64): Boolean? - fun get_all_ids(mod_name: String = definedExternally): Array - fun clear(mod_name: String = definedExternally) - fun get_type(id: uint64): String /* "text" | "line" | "circle" | "rectangle" | "arc" | "polygon" | "sprite" | "light" | "animation" */ - fun bring_to_front(id: uint64) - fun get_surface(id: uint64): LuaSurface - fun get_time_to_live(id: uint64): uint - fun set_time_to_live(id: uint64, time_to_live: uint) - fun get_forces(id: uint64): Array? - fun set_forces(id: uint64, forces: Array) - fun get_players(id: uint64): Array? - fun set_players(id: uint64, players: Array) - fun get_visible(id: uint64): Boolean? - fun set_visible(id: uint64, visible: Boolean) - fun get_draw_on_ground(id: uint64): Boolean? - fun set_draw_on_ground(id: uint64, draw_on_ground: Boolean) - fun get_only_in_alt_mode(id: uint64): Boolean? - fun set_only_in_alt_mode(id: uint64, only_in_alt_mode: Boolean) - fun get_color(id: uint64): ColorTable? - fun set_color(id: uint64, color: ColorTable) - fun set_color(id: uint64, color: Any /* JsTuple */) - fun get_width(id: uint64): float? - fun set_width(id: uint64, width: float) - fun get_from(id: uint64): ScriptRenderTarget? - fun set_from(id: uint64, from: Position, from_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) - fun set_from(id: uint64, from: Position) - fun set_from(id: uint64, from: LuaEntity, from_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) - fun set_from(id: uint64, from: LuaEntity) - fun get_to(id: uint64): ScriptRenderTarget? - fun set_to(id: uint64, to: Position, to_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) - fun set_to(id: uint64, to: Position) - fun set_to(id: uint64, to: LuaEntity, to_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) - fun set_to(id: uint64, to: LuaEntity) - fun get_dash_length(id: uint64): double? - fun set_dash_length(id: uint64, dash_length: double) - fun get_gap_length(id: uint64): double? - fun set_gap_length(id: uint64, gap_length: double) - fun set_dashes(id: uint64, dash_length: double, gap_length: double) - fun get_target(id: uint64): ScriptRenderTarget? - fun set_target(id: uint64, target: Position, target_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) - fun set_target(id: uint64, target: Position) - fun set_target(id: uint64, target: LuaEntity, target_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) - fun set_target(id: uint64, target: LuaEntity) - fun get_orientation(id: uint64): RealOrientation? - fun set_orientation(id: uint64, orientation: RealOrientation) - fun get_scale(id: uint64): double? - fun set_scale(id: uint64, scale: double) - fun get_text(id: uint64): dynamic /* JsTuple | String? | Number? */ - fun set_text(id: uint64, text: Any /* JsTuple */) - fun set_text(id: uint64, text: String) - fun set_text(id: uint64, text: Number) - fun get_font(id: uint64): String? - fun set_font(id: uint64, font: String) - fun get_alignment(id: uint64): String? - fun set_alignment(id: uint64, alignment: String /* "left" | "right" | "center" */) - fun get_vertical_alignment(id: uint64): String? - fun set_vertical_alignment(id: uint64, alignment: String /* "top" | "middle" | "baseline" | "bottom" */) - fun get_scale_with_zoom(id: uint64): Boolean? - fun set_scale_with_zoom(id: uint64, scale_with_zoom: Boolean) - fun get_filled(id: uint64): Boolean? - fun set_filled(id: uint64, filled: Boolean) - fun get_radius(id: uint64): double? - fun set_radius(id: uint64, radius: double) - fun get_left_top(id: uint64): ScriptRenderTarget? - fun set_left_top(id: uint64, left_top: Position, left_top_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) - fun set_left_top(id: uint64, left_top: Position) - fun set_left_top(id: uint64, left_top: LuaEntity, left_top_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) - fun set_left_top(id: uint64, left_top: LuaEntity) - fun get_right_bottom(id: uint64): ScriptRenderTarget? - fun set_right_bottom(id: uint64, right_bottom: Position, right_bottom_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) - fun set_right_bottom(id: uint64, right_bottom: Position) - fun set_right_bottom(id: uint64, right_bottom: LuaEntity, right_bottom_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) - fun set_right_bottom(id: uint64, right_bottom: LuaEntity) - fun set_corners(id: uint64, left_top: Position, left_top_offset: dynamic /* typealias Vector = dynamic */, right_bottom: Position, right_bottom_offset: dynamic /* typealias Vector = dynamic */) - fun set_corners(id: uint64, left_top: Position, left_top_offset: dynamic /* typealias Vector = dynamic */, right_bottom: LuaEntity, right_bottom_offset: dynamic /* typealias Vector = dynamic */) - fun set_corners(id: uint64, left_top: LuaEntity, left_top_offset: dynamic /* typealias Vector = dynamic */, right_bottom: Position, right_bottom_offset: dynamic /* typealias Vector = dynamic */) - fun set_corners(id: uint64, left_top: LuaEntity, left_top_offset: dynamic /* typealias Vector = dynamic */, right_bottom: LuaEntity, right_bottom_offset: dynamic /* typealias Vector = dynamic */) - fun get_max_radius(id: uint64): double? - fun set_max_radius(id: uint64, max_radius: double) - fun get_min_radius(id: uint64): double? - fun set_min_radius(id: uint64, min_radius: double) - fun get_start_angle(id: uint64): float? - fun set_start_angle(id: uint64, start_angle: float) - fun get_angle(id: uint64): float? - fun set_angle(id: uint64, angle: float) - fun get_vertices(id: uint64): Array? - fun set_vertices(id: uint64, vertices: Array) - fun get_sprite(id: uint64): dynamic /* String? | ? */ - fun set_sprite(id: uint64, sprite: String) -// fun set_sprite(id: uint64, sprite: ) - fun get_x_scale(id: uint64): double? - fun set_x_scale(id: uint64, x_scale: double) - fun get_y_scale(id: uint64): double? - fun set_y_scale(id: uint64, y_scale: double) - fun get_render_layer(id: uint64): dynamic /* Number? | ? */ - fun set_render_layer(id: uint64, render_layer: Number) - fun set_render_layer(id: uint64, render_layer: String) - fun get_orientation_target(id: uint64): ScriptRenderTarget? - fun set_orientation_target(id: uint64, orientation_target: Position, orientation_target_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) - fun set_orientation_target(id: uint64, orientation_target: Position) - fun set_orientation_target(id: uint64, orientation_target: LuaEntity, orientation_target_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) - fun set_orientation_target(id: uint64, orientation_target: LuaEntity) - fun get_oriented_offset(id: uint64): dynamic /* typealias Vector = dynamic */ - fun set_oriented_offset(id: uint64, oriented_offset: dynamic /* typealias Vector = dynamic */) - fun get_intensity(id: uint64): float? - fun set_intensity(id: uint64, intensity: float) - fun get_minimum_darkness(id: uint64): float? - fun set_minimum_darkness(id: uint64, minimum_darkness: float) - fun get_oriented(id: uint64): Boolean? - fun set_oriented(id: uint64, oriented: Boolean) - fun get_animation(id: uint64): String? - fun set_animation(id: uint64, animation: String) - fun get_animation_speed(id: uint64): double? - fun set_animation_speed(id: uint64, animation_speed: double) - fun get_animation_offset(id: uint64): double? - fun set_animation_offset(id: uint64, animation_offset: double) - var object_name: String /* "LuaRendering" */ -} - -external interface LuaResourceCategoryPrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var valid: Boolean? - var object_name: String /* "LuaResourceCategoryPrototype" */ - fun help(): String -} - -external interface LuaRoboportControlBehavior : LuaControlBehavior { - var read_logistics: Boolean? - var read_robot_stats: Boolean? - var available_logistic_output_signal: SignalID - var total_logistic_output_signal: SignalID - var available_construction_output_signal: SignalID - var total_construction_output_signal: SignalID - var valid: Boolean? - var object_name: String /* "LuaRoboportControlBehavior" */ - fun help(): String -} - -external interface LuaSettings { - fun get_player_settings(player: uint): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - fun get_player_settings(player: String): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - fun get_player_settings(player: LuaPlayer): LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var startup: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var global: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var player: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var object_name: String /* "LuaSettings" */ -} - -external interface LuaShortcutPrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var action: String - var item_to_spawn: LuaItemPrototype - var technology_to_unlock: LuaTechnologyPrototype - var toggleable: Boolean? - var associated_control_input: String - var valid: Boolean? - var object_name: String /* "LuaShortcutPrototype" */ - fun help(): String -} - -external interface LuaStorageTankControlBehavior : LuaControlBehavior { - var valid: Boolean? - var object_name: String /* "LuaStorageTankControlBehavior" */ - fun help(): String -} - -external interface LuaStyle { - var gui: LuaGui - var name: String - var minimal_width: int - var maximal_width: int - var minimal_height: int - var maximal_height: int - var natural_width: int - var natural_height: int - var top_padding: int - var right_padding: int - var bottom_padding: int - var left_padding: int - var top_margin: int - var right_margin: int - var bottom_margin: int - var left_margin: int - var horizontal_align: String /* "left" | "center" | "right" */ - var vertical_align: String /* "top" | "center" | "bottom" */ - var font_color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var font: String - var top_cell_padding: int - var right_cell_padding: int - var bottom_cell_padding: int - var left_cell_padding: int - var horizontally_stretchable: Boolean? - var vertically_stretchable: Boolean? - var horizontally_squashable: Boolean? - var vertically_squashable: Boolean? - var rich_text_setting: rich_text_setting - var hovered_font_color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var clicked_font_color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var disabled_font_color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var pie_progress_color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var clicked_vertical_offset: int - var selected_font_color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var selected_hovered_font_color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var selected_clicked_font_color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var strikethrough_color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var horizontal_spacing: int - var vertical_spacing: int - var use_header_filler: Boolean? - var color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var column_alignments: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var single_line: Boolean? - var extra_top_padding_when_activated: int - var extra_bottom_padding_when_activated: int - var extra_left_padding_when_activated: int - var extra_right_padding_when_activated: int - var extra_top_margin_when_activated: int - var extra_bottom_margin_when_activated: int - var extra_left_margin_when_activated: int - var extra_right_margin_when_activated: int - var stretch_image_to_widget_size: Boolean? - var badge_font: String - var badge_horizontal_spacing: int - var default_badge_font_color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var selected_badge_font_color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var disabled_badge_font_color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally -} - -external interface BaseSurfaceCreateEntity { - var name: String - var position: Position - var direction: direction? - get() = definedExternally - set(value) = definedExternally - var force: dynamic /* String? | LuaForce? */ - get() = definedExternally - set(value) = definedExternally - var target: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var source: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var fast_replace: Boolean? - get() = definedExternally - set(value) = definedExternally - var player: dynamic /* uint? | String? | LuaPlayer? */ - get() = definedExternally - set(value) = definedExternally - var spill: Boolean? - get() = definedExternally - set(value) = definedExternally - var raise_built: Boolean? - get() = definedExternally - set(value) = definedExternally - var create_build_effect_smoke: Boolean? - get() = definedExternally - set(value) = definedExternally - var spawn_decorations: Boolean? - get() = definedExternally - set(value) = definedExternally - var move_stuck_players: Boolean? - get() = definedExternally - set(value) = definedExternally - var item: LuaItemStack? - get() = definedExternally - set(value) = definedExternally -} - -external interface AssemblingMachineSurfaceCreateEntity : BaseSurfaceCreateEntity { - var recipe: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface BeamSurfaceCreateEntity : BaseSurfaceCreateEntity { - var target_position: Position? - get() = definedExternally - set(value) = definedExternally - var source_position: Position? - get() = definedExternally - set(value) = definedExternally - var max_length: uint? - get() = definedExternally - set(value) = definedExternally - var duration: uint? - get() = definedExternally - set(value) = definedExternally - var source_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ContainerSurfaceCreateEntity : BaseSurfaceCreateEntity { - var bar: uint? - get() = definedExternally - set(value) = definedExternally -} - -external interface CliffSurfaceCreateEntity : BaseSurfaceCreateEntity { - var cliff_orientation: String? /* "west-to-east" | "north-to-south" | "east-to-west" | "south-to-north" | "west-to-north" | "north-to-east" | "east-to-south" | "south-to-west" | "west-to-south" | "north-to-west" | "east-to-north" | "south-to-east" | "west-to-none" | "none-to-east" | "east-to-none" | "none-to-west" | "north-to-none" | "none-to-south" | "south-to-none" | "none-to-north" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlyingTextSurfaceCreateEntity : BaseSurfaceCreateEntity { - var text: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var color: dynamic /* ColorTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var render_player_index: uint? - get() = definedExternally - set(value) = definedExternally -} - -external interface EntityGhostSurfaceCreateEntity : BaseSurfaceCreateEntity { - var inner_name: String - var expires: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface FireSurfaceCreateEntity : BaseSurfaceCreateEntity { - var initial_ground_flame_count: uint8? - get() = definedExternally - set(value) = definedExternally -} - -external interface InserterSurfaceCreateEntity : BaseSurfaceCreateEntity { - var conditions: InserterCircuitConditions - var filters: Array -} - -external interface ItemEntitySurfaceCreateEntity : BaseSurfaceCreateEntity { - var stack: dynamic /* String | ItemStackDefinition */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ItemRequestProxySurfaceCreateEntity : BaseSurfaceCreateEntity { - var modules: Record -} - -external interface RollingStockSurfaceCreateEntity : BaseSurfaceCreateEntity { - var orientation: RealOrientation? - get() = definedExternally - set(value) = definedExternally - var color: dynamic /* ColorTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally -} - -external interface LocomotiveSurfaceCreateEntity : BaseSurfaceCreateEntity { - var snap_to_train_stop: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface LogisticContainerSurfaceCreateEntity : BaseSurfaceCreateEntity { - var request_filters: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface ParticleSurfaceCreateEntity : BaseSurfaceCreateEntity { - var movement: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var height: float - var vertical_speed: float - var frame_speed: float -} - -external interface ArtilleryFlareSurfaceCreateEntity : BaseSurfaceCreateEntity { - var movement: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var height: float - var vertical_speed: float - var frame_speed: float -} - -external interface ProjectileSurfaceCreateEntity : BaseSurfaceCreateEntity { - var speed: double - var max_range: double -} - -external interface ResourceSurfaceCreateEntity : BaseSurfaceCreateEntity { - var amount: uint - var enable_tree_removal: Boolean? - get() = definedExternally - set(value) = definedExternally - var enable_cliff_removal: Boolean? - get() = definedExternally - set(value) = definedExternally - var snap_to_tile_center: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface UndergroundBeltSurfaceCreateEntity : BaseSurfaceCreateEntity { - var type: String? /* "output" | "input" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ProgrammableSpeakerSurfaceCreateEntity : BaseSurfaceCreateEntity { - var parameters: ProgrammableSpeakerParameters? - get() = definedExternally - set(value) = definedExternally - var alert_parameters: ProgrammableSpeakerAlertParameters? - get() = definedExternally - set(value) = definedExternally -} - -external interface CharacterCorpseSurfaceCreateEntity : BaseSurfaceCreateEntity { - var inventory_size: uint? - get() = definedExternally - set(value) = definedExternally - var player_index: uint? - get() = definedExternally - set(value) = definedExternally -} - -external interface HighlightBoxSurfaceCreateEntity : BaseSurfaceCreateEntity { - var bounding_box: dynamic /* BoundingBoxTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var box_type: String? /* "entity" | "not-allowed" | "electricity" | "pair" | "copy" | "train-visualization" | "logistics" | "blueprint-snap-rectangle" */ - get() = definedExternally - set(value) = definedExternally - var render_player_index: uint? - get() = definedExternally - set(value) = definedExternally - var blink_interval: uint? - get() = definedExternally - set(value) = definedExternally - var time_to_live: uint? - get() = definedExternally - set(value) = definedExternally -} - -external interface SpeechBubbleSurfaceCreateEntity : BaseSurfaceCreateEntity { - var text: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var lifetime: uint? - get() = definedExternally - set(value) = definedExternally -} - -external interface SimpleEntityWithOwnerSurfaceCreateEntity : BaseSurfaceCreateEntity { - var render_player_index: uint? - get() = definedExternally - set(value) = definedExternally -} - -external interface SimpleEntityWithForceSurfaceCreateEntity : BaseSurfaceCreateEntity { - var render_player_index: uint? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$64` { - var name: String - var position: Position - var direction: direction? - get() = definedExternally - set(value) = definedExternally - var force: dynamic /* String? | LuaForce? */ - get() = definedExternally - set(value) = definedExternally - var build_check_type: build_check_type? - get() = definedExternally - set(value) = definedExternally - var forced: Boolean? - get() = definedExternally - set(value) = definedExternally - var inner_name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$65` { - var name: String - var position: Position - var direction: direction? - get() = definedExternally - set(value) = definedExternally - var force: dynamic /* String? | LuaForce? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$66` { - var area: dynamic /* BoundingBoxTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var position: Position? - get() = definedExternally - set(value) = definedExternally - var radius: double? - get() = definedExternally - set(value) = definedExternally - var name: dynamic /* String? | Array? */ - get() = definedExternally - set(value) = definedExternally - var type: dynamic /* String? | Array? */ - get() = definedExternally - set(value) = definedExternally - var ghost_name: dynamic /* String? | Array? */ - get() = definedExternally - set(value) = definedExternally - var ghost_type: dynamic /* String? | Array? */ - get() = definedExternally - set(value) = definedExternally - var direction: dynamic /* defines.direction? | Array? */ - get() = definedExternally - set(value) = definedExternally - var collision_mask: dynamic /* "ground-tile" | "water-tile" | "resource-layer" | "doodad-layer" | "floor-layer" | "item-layer" | "ghost-layer" | "object-layer" | "player-layer" | "train-layer" | "rail-layer" | "transport-belt-layer" | "not-setup" | ? | Array? */ - get() = definedExternally - set(value) = definedExternally - var force: dynamic /* String? | LuaForce? | Array? */ - get() = definedExternally - set(value) = definedExternally - var to_be_deconstructed: Boolean? - get() = definedExternally - set(value) = definedExternally - var to_be_upgraded: Boolean? - get() = definedExternally - set(value) = definedExternally - var limit: uint? - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$67` { - var area: dynamic /* BoundingBoxTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var position: Position? - get() = definedExternally - set(value) = definedExternally - var radius: double? - get() = definedExternally - set(value) = definedExternally - var name: dynamic /* String? | Array? */ - get() = definedExternally - set(value) = definedExternally - var limit: uint? - get() = definedExternally - set(value) = definedExternally - var has_hidden_tile: Boolean? - get() = definedExternally - set(value) = definedExternally - var collision_mask: dynamic /* "ground-tile" | "water-tile" | "resource-layer" | "doodad-layer" | "floor-layer" | "item-layer" | "ghost-layer" | "object-layer" | "player-layer" | "train-layer" | "rail-layer" | "transport-belt-layer" | "not-setup" | ? | Array? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$68` { - var area: dynamic /* BoundingBoxTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var position: Position? - get() = definedExternally - set(value) = definedExternally - var radius: double? - get() = definedExternally - set(value) = definedExternally - var name: dynamic /* String? | Array? */ - get() = definedExternally - set(value) = definedExternally - var type: dynamic /* String? | Array? */ - get() = definedExternally - set(value) = definedExternally - var ghost_name: dynamic /* String? | Array? */ - get() = definedExternally - set(value) = definedExternally - var ghost_type: dynamic /* String? | Array? */ - get() = definedExternally - set(value) = definedExternally - var direction: dynamic /* defines.direction? | Array? */ - get() = definedExternally - set(value) = definedExternally - var collision_mask: dynamic /* "ground-tile" | "water-tile" | "resource-layer" | "doodad-layer" | "floor-layer" | "item-layer" | "ghost-layer" | "object-layer" | "player-layer" | "train-layer" | "rail-layer" | "transport-belt-layer" | "not-setup" | ? | Array? */ - get() = definedExternally - set(value) = definedExternally - var force: dynamic /* String? | LuaForce? | Array? */ - get() = definedExternally - set(value) = definedExternally - var to_be_deconstructed: Boolean? - get() = definedExternally - set(value) = definedExternally - var to_be_upgraded: Boolean? - get() = definedExternally - set(value) = definedExternally - var limit: uint? - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$69` { - var area: dynamic /* BoundingBoxTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var position: Position? - get() = definedExternally - set(value) = definedExternally - var radius: double? - get() = definedExternally - set(value) = definedExternally - var name: dynamic /* String? | Array? */ - get() = definedExternally - set(value) = definedExternally - var limit: uint? - get() = definedExternally - set(value) = definedExternally - var has_hidden_tile: Boolean? - get() = definedExternally - set(value) = definedExternally - var collision_mask: dynamic /* "ground-tile" | "water-tile" | "resource-layer" | "doodad-layer" | "floor-layer" | "item-layer" | "ghost-layer" | "object-layer" | "player-layer" | "train-layer" | "rail-layer" | "transport-belt-layer" | "not-setup" | ? | Array? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$70` { - var area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var force: dynamic /* LuaForce | String */ - get() = definedExternally - set(value) = definedExternally - var condition: String /* "all" | "enemy" | "ally" | "friend" | "not-friend" | "same" | "not-same" */ -} - -external interface `T$71` { - var position: Position - var max_distance: double - var force: dynamic /* String? | LuaForce? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$72` { - var command: dynamic /* AttackCommand | GoToLocationCommand | CompoundCommand | GroupCommand | AttackAreaCommand | WanderCommand | StopCommand | FleeCommand | BuildBaseCommand */ - get() = definedExternally - set(value) = definedExternally - var unit_count: uint - var force: dynamic /* String? | LuaForce? */ - get() = definedExternally - set(value) = definedExternally - var unit_search_distance: uint? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$73` { - var name: String - var position: Position -} - -external interface `T$74` { - var name: String - var position: Position - var movement: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var height: float - var vertical_speed: float - var frame_speed: float -} - -external interface `T$75` { - var position: Position - var force: dynamic /* String? | LuaForce? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$76` { - var area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var force: dynamic /* String | LuaForce */ - get() = definedExternally - set(value) = definedExternally - var player: dynamic /* uint? | String? | LuaPlayer? */ - get() = definedExternally - set(value) = definedExternally - var skip_fog_of_war: Boolean? - get() = definedExternally - set(value) = definedExternally - var item: LuaItemStack? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$77` { - var area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var force: dynamic /* String | LuaForce */ - get() = definedExternally - set(value) = definedExternally - var player: dynamic /* uint? | String? | LuaPlayer? */ - get() = definedExternally - set(value) = definedExternally - var skip_fog_of_war: Boolean? - get() = definedExternally - set(value) = definedExternally - var item: LuaItemStack -} - -external interface `T$78` { - var area: dynamic /* BoundingBoxTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var position: dynamic /* TilePositionTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var name: dynamic /* String? | Array? | LuaDecorativePrototype? | Array? */ - get() = definedExternally - set(value) = definedExternally - var limit: uint? - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$79` { - var check_collision: Boolean? - get() = definedExternally - set(value) = definedExternally - var decoratives: Array -} - -external interface `T$80` { - var area: dynamic /* BoundingBoxTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var position: dynamic /* TilePositionTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var name: dynamic /* String? | Array? | LuaDecorativePrototype? | Array? */ - get() = definedExternally - set(value) = definedExternally - var limit: uint? - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$81` { - var source_area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var destination_area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var destination_surface: dynamic /* uint? | String? | LuaSurface? */ - get() = definedExternally - set(value) = definedExternally - var destination_force: dynamic /* LuaForce? | String? */ - get() = definedExternally - set(value) = definedExternally - var clone_tiles: Boolean? - get() = definedExternally - set(value) = definedExternally - var clone_entities: Boolean? - get() = definedExternally - set(value) = definedExternally - var clone_decoratives: Boolean? - get() = definedExternally - set(value) = definedExternally - var clear_destination_entities: Boolean? - get() = definedExternally - set(value) = definedExternally - var clear_destination_decoratives: Boolean? - get() = definedExternally - set(value) = definedExternally - var expand_map: Boolean? - get() = definedExternally - set(value) = definedExternally - var create_build_effect_smoke: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$82` { - var source_offset: dynamic /* TilePositionTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var destination_offset: dynamic /* TilePositionTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var source_positions: Array */> - var destination_surface: dynamic /* uint? | String? | LuaSurface? */ - get() = definedExternally - set(value) = definedExternally - var destination_force: dynamic /* LuaForce? | String? */ - get() = definedExternally - set(value) = definedExternally - var clone_tiles: Boolean? - get() = definedExternally - set(value) = definedExternally - var clone_entities: Boolean? - get() = definedExternally - set(value) = definedExternally - var clone_decoratives: Boolean? - get() = definedExternally - set(value) = definedExternally - var clear_destination_entities: Boolean? - get() = definedExternally - set(value) = definedExternally - var clear_destination_decoratives: Boolean? - get() = definedExternally - set(value) = definedExternally - var expand_map: Boolean? - get() = definedExternally - set(value) = definedExternally - var manual_collision_mode: Boolean? - get() = definedExternally - set(value) = definedExternally - var create_build_effect_smoke: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$83` { - var entities: Array - var destination_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var destination_surface: dynamic /* uint? | String? | LuaSurface? */ - get() = definedExternally - set(value) = definedExternally - var destination_force: dynamic /* String? | LuaForce? */ - get() = definedExternally - set(value) = definedExternally - var snap_to_grid: Boolean? - get() = definedExternally - set(value) = definedExternally - var create_build_effect_smoke: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$84` { - var bounding_box: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var collision_mask: dynamic /* CollisionMask | Array */ - get() = definedExternally - set(value) = definedExternally - var start: Position - var goal: Position - var force: dynamic /* String | LuaForce */ - get() = definedExternally - set(value) = definedExternally - var radius: double? - get() = definedExternally - set(value) = definedExternally - var pathfind_flags: PathfinderFlags? - get() = definedExternally - set(value) = definedExternally - var can_open_gates: Boolean? - get() = definedExternally - set(value) = definedExternally - var path_resolution_modifier: int? - get() = definedExternally - set(value) = definedExternally - var entity_to_ignore: LuaEntity? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$85` { - var name: dynamic /* String? | Array? */ - get() = definedExternally - set(value) = definedExternally - var force: dynamic /* String? | LuaForce? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface LuaSurface { - fun get_pollution(position: Position): double - fun can_place_entity(params: `T$64`): Boolean? - fun can_fast_replace(params: `T$65`): Boolean? - fun find_entity(entity: String, position: Position): LuaEntity? - fun find_entities(area: BoundingBoxTable = definedExternally): Array - fun find_entities(): Array - fun find_entities(area: Any /* JsTuple */ = definedExternally): Array - fun find_entities_filtered(params: `T$66`): Array - fun find_tiles_filtered(params: `T$67`): Array - fun count_entities_filtered(params: `T$68`): uint - fun count_tiles_filtered(params: `T$69`): uint - fun find_non_colliding_position(name: String, center: Position, radius: double, precision: double, force_to_tile_center: Boolean = definedExternally): PositionTable? - fun find_non_colliding_position_in_box(name: String, search_space: BoundingBoxTable, precision: double, force_to_tile_center: Boolean = definedExternally): PositionTable? - fun find_non_colliding_position_in_box(name: String, search_space: BoundingBoxTable, precision: double): PositionTable? - fun find_non_colliding_position_in_box(name: String, search_space: Any /* JsTuple */, precision: double, force_to_tile_center: Boolean = definedExternally): PositionTable? - fun find_non_colliding_position_in_box(name: String, search_space: Any /* JsTuple */, precision: double): PositionTable? - fun spill_item_stack(position: Position, items: String, enable_looted: Boolean = definedExternally, force: LuaForce = definedExternally, allow_belts: Boolean = definedExternally): Array - fun spill_item_stack(position: Position, items: String): Array - fun spill_item_stack(position: Position, items: String, enable_looted: Boolean = definedExternally): Array - fun spill_item_stack(position: Position, items: String, enable_looted: Boolean = definedExternally, force: LuaForce = definedExternally): Array - fun spill_item_stack(position: Position, items: String, enable_looted: Boolean = definedExternally, force: String = definedExternally, allow_belts: Boolean = definedExternally): Array - fun spill_item_stack(position: Position, items: String, enable_looted: Boolean = definedExternally, force: String = definedExternally): Array - fun spill_item_stack(position: Position, items: ItemStackDefinition, enable_looted: Boolean = definedExternally, force: LuaForce = definedExternally, allow_belts: Boolean = definedExternally): Array - fun spill_item_stack(position: Position, items: ItemStackDefinition): Array - fun spill_item_stack(position: Position, items: ItemStackDefinition, enable_looted: Boolean = definedExternally): Array - fun spill_item_stack(position: Position, items: ItemStackDefinition, enable_looted: Boolean = definedExternally, force: LuaForce = definedExternally): Array - fun spill_item_stack(position: Position, items: ItemStackDefinition, enable_looted: Boolean = definedExternally, force: String = definedExternally, allow_belts: Boolean = definedExternally): Array - fun spill_item_stack(position: Position, items: ItemStackDefinition, enable_looted: Boolean = definedExternally, force: String = definedExternally): Array - fun spill_item_stack(position: Position, items: LuaItemStack, enable_looted: Boolean = definedExternally, force: LuaForce = definedExternally, allow_belts: Boolean = definedExternally): Array - fun spill_item_stack(position: Position, items: LuaItemStack): Array - fun spill_item_stack(position: Position, items: LuaItemStack, enable_looted: Boolean = definedExternally): Array - fun spill_item_stack(position: Position, items: LuaItemStack, enable_looted: Boolean = definedExternally, force: LuaForce = definedExternally): Array - fun spill_item_stack(position: Position, items: LuaItemStack, enable_looted: Boolean = definedExternally, force: String = definedExternally, allow_belts: Boolean = definedExternally): Array - fun spill_item_stack(position: Position, items: LuaItemStack, enable_looted: Boolean = definedExternally, force: String = definedExternally): Array - fun find_enemy_units(center: Position, radius: double, force: LuaForce = definedExternally): Array - fun find_enemy_units(center: Position, radius: double): Array - fun find_enemy_units(center: Position, radius: double, force: String = definedExternally): Array - fun find_units(params: `T$70`): Array - fun find_nearest_enemy(params: `T$71`): LuaEntity? - fun find_nearest_enemy_entity_with_owner(params: `T$71`): LuaEntity? - fun set_multi_command(params: `T$72`): uint - fun create_entity(params: Any /* AssemblingMachineSurfaceCreateEntity | BeamSurfaceCreateEntity | ContainerSurfaceCreateEntity | CliffSurfaceCreateEntity | FlyingTextSurfaceCreateEntity | EntityGhostSurfaceCreateEntity | FireSurfaceCreateEntity | InserterSurfaceCreateEntity | ItemEntitySurfaceCreateEntity | ItemRequestProxySurfaceCreateEntity | RollingStockSurfaceCreateEntity | LocomotiveSurfaceCreateEntity | LogisticContainerSurfaceCreateEntity | ParticleSurfaceCreateEntity | ArtilleryFlareSurfaceCreateEntity | ProjectileSurfaceCreateEntity | ResourceSurfaceCreateEntity | UndergroundBeltSurfaceCreateEntity | ProgrammableSpeakerSurfaceCreateEntity | CharacterCorpseSurfaceCreateEntity | HighlightBoxSurfaceCreateEntity | SpeechBubbleSurfaceCreateEntity | SimpleEntityWithOwnerSurfaceCreateEntity | SimpleEntityWithForceSurfaceCreateEntity */): LuaEntity? - fun create_trivial_smoke(params: `T$73`) - fun create_particle(params: `T$74`) - fun create_unit_group(params: `T$75`): LuaUnitGroup - fun build_enemy_base(position: Position, unit_count: uint, force: String = definedExternally) - fun build_enemy_base(position: Position, unit_count: uint) - fun build_enemy_base(position: Position, unit_count: uint, force: LuaForce = definedExternally) - fun get_tile(x: int, y: int): LuaTile - fun set_tiles(tiles: Array, correct_tiles: Boolean = definedExternally, remove_colliding_entities: Boolean = definedExternally, remove_colliding_decoratives: Boolean = definedExternally, raise_event: Boolean = definedExternally) - fun set_tiles(tiles: Array) - fun set_tiles(tiles: Array, correct_tiles: Boolean = definedExternally) - fun set_tiles(tiles: Array, correct_tiles: Boolean = definedExternally, remove_colliding_entities: Boolean = definedExternally) - fun set_tiles(tiles: Array, correct_tiles: Boolean = definedExternally, remove_colliding_entities: Boolean = definedExternally, remove_colliding_decoratives: Boolean = definedExternally) - fun set_tiles(tiles: Array, correct_tiles: Boolean = definedExternally, remove_colliding_entities: String = definedExternally, remove_colliding_decoratives: Boolean = definedExternally, raise_event: Boolean = definedExternally) - fun set_tiles(tiles: Array, correct_tiles: Boolean = definedExternally, remove_colliding_entities: String = definedExternally) - fun set_tiles(tiles: Array, correct_tiles: Boolean = definedExternally, remove_colliding_entities: String = definedExternally, remove_colliding_decoratives: Boolean = definedExternally) - fun pollute(source: Position, amount: double) - fun get_chunks(): LuaChunkIterator - fun is_chunk_generated(position: ChunkPositionTable): Boolean? - fun is_chunk_generated(position: Any /* JsTuple */): Boolean? - fun request_to_generate_chunks(position: Position, radius: uint) - fun force_generate_chunk_requests() - fun set_chunk_generated_status(position: ChunkPositionTable, status: chunk_generated_status) - fun set_chunk_generated_status(position: Any /* JsTuple */, status: chunk_generated_status) - fun find_logistic_network_by_position(position: Position, force: String): LuaLogisticNetwork? - fun find_logistic_network_by_position(position: Position, force: LuaForce): LuaLogisticNetwork? - fun find_logistic_networks_by_construction_area(position: Position, force: String): Array - fun find_logistic_networks_by_construction_area(position: Position, force: LuaForce): Array - fun deconstruct_area(params: `T$76`) - fun cancel_deconstruct_area(params: `T$76`) - fun upgrade_area(params: `T$77`) - fun cancel_upgrade_area(params: `T$76`) - fun get_hidden_tile(position: TilePositionTable): String? - fun get_hidden_tile(position: Any /* JsTuple */): String? - fun set_hidden_tile(position: TilePositionTable, tile: String?) - fun set_hidden_tile(position: TilePositionTable, tile: LuaTilePrototype?) - fun set_hidden_tile(position: Any /* JsTuple */, tile: String?) - fun set_hidden_tile(position: Any /* JsTuple */, tile: LuaTilePrototype?) - fun get_connected_tiles(position: Position, tiles: Array): Array - fun delete_chunk(position: ChunkPositionTable) - fun delete_chunk(position: Any /* JsTuple */) - fun regenerate_entity(entities: String = definedExternally, chunks: Array */> = definedExternally) - fun regenerate_entity() - fun regenerate_entity(entities: String = definedExternally) - fun regenerate_entity(entities: Array = definedExternally, chunks: Array */> = definedExternally) - fun regenerate_entity(entities: Array = definedExternally) - fun regenerate_decorative(decoratives: String = definedExternally, chunks: Array */> = definedExternally) - fun regenerate_decorative() - fun regenerate_decorative(decoratives: String = definedExternally) - fun regenerate_decorative(decoratives: Array = definedExternally, chunks: Array */> = definedExternally) - fun regenerate_decorative(decoratives: Array = definedExternally) - fun print(message: Any /* JsTuple */, color: ColorTable = definedExternally) - fun print(message: Any /* JsTuple */) - fun print(message: Any /* JsTuple */, color: Any /* JsTuple */ = definedExternally) - fun print(message: String, color: ColorTable = definedExternally) - fun print(message: String) - fun print(message: String, color: Any /* JsTuple */ = definedExternally) - fun print(message: Number, color: ColorTable = definedExternally) - fun print(message: Number) - fun print(message: Number, color: Any /* JsTuple */ = definedExternally) - fun destroy_decoratives(params: `T$78`) - fun create_decoratives(params: `T$79`) - fun find_decoratives_filtered(params: `T$80`): Array - fun get_trains(force: String = definedExternally): Array - fun get_trains(): Array - fun get_trains(force: LuaForce = definedExternally): Array - fun clear_pollution() - fun play_sound(params: `T$34`) - fun get_resource_counts(): Record - fun get_random_chunk(): ChunkPositionTable - fun clone_area(params: `T$81`) - fun clone_brush(params: `T$82`) - fun clone_entities(params: `T$83`) - fun clear(ignore_characters: Boolean = definedExternally) - fun request_path(params: `T$84`): uint - fun get_script_areas(name: String = definedExternally): Array - fun get_script_area(key: String = definedExternally): ScriptArea - fun get_script_area(): ScriptArea - fun get_script_area(key: uint = definedExternally): ScriptArea - fun edit_script_area(id: uint, area: ScriptArea) - fun add_script_area(area: ScriptArea): uint - fun remove_script_area(id: uint): Boolean? - fun get_script_positions(name: String = definedExternally): Array - fun get_script_position(key: String = definedExternally): ScriptPosition - fun get_script_position(): ScriptPosition - fun get_script_position(key: uint = definedExternally): ScriptPosition - fun edit_script_position(id: uint, area: ScriptPosition) - fun add_script_position(area: ScriptPosition): uint - fun remove_script_position(id: uint): Boolean? - fun get_map_exchange_string(): String - fun get_starting_area_radius(): double - fun get_closest(position: Position, entities: Array): LuaEntity - fun get_train_stops(params: `T$85` = definedExternally): Array - fun get_total_pollution(): double - fun entity_prototype_collides(prototype: LuaEntity, position: Position, use_map_generation_bounding_box: Boolean, direction: direction = definedExternally) - fun entity_prototype_collides(prototype: LuaEntity, position: Position, use_map_generation_bounding_box: Boolean) - fun entity_prototype_collides(prototype: LuaEntityPrototype, position: Position, use_map_generation_bounding_box: Boolean, direction: direction = definedExternally) - fun entity_prototype_collides(prototype: LuaEntityPrototype, position: Position, use_map_generation_bounding_box: Boolean) - fun entity_prototype_collides(prototype: String, position: Position, use_map_generation_bounding_box: Boolean, direction: direction = definedExternally) - fun entity_prototype_collides(prototype: String, position: Position, use_map_generation_bounding_box: Boolean) - fun decorative_prototype_collides(prototype: String, position: Position) - fun calculate_tile_properties(property_names: Array, positions: Array): Record> - fun get_entities_with_force(position: ChunkPositionTable, force: LuaForce): Array - fun get_entities_with_force(position: ChunkPositionTable, force: String): Array - fun get_entities_with_force(position: Any /* JsTuple */, force: LuaForce): Array - fun get_entities_with_force(position: Any /* JsTuple */, force: String): Array - fun build_checkerboard(area: BoundingBoxTable) - fun build_checkerboard(area: Any /* JsTuple */) - var name: String - var index: uint - var map_gen_settings: MapGenSettings - var generate_with_lab_tiles: Boolean? - var always_day: Boolean? - var daytime: float - var darkness: float - var wind_speed: double - var wind_orientation: RealOrientation - var wind_orientation_change: double - var peaceful_mode: Boolean? - var freeze_daytime: Boolean? - var ticks_per_day: uint - var dusk: double - var dawn: double - var evening: double - var morning: double - var solar_power_multiplier: double - var min_brightness: double - var brightness_visual_weights: dynamic /* ColorModifierTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var show_clouds: Boolean? - var valid: Boolean? - var object_name: String /* "LuaSurface" */ - fun help(): String -} - -external interface LuaTechnology { - fun reload() - var force: LuaForce - var name: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var prototype: LuaTechnologyPrototype - var enabled: Boolean? - var visible_when_disabled: Boolean? - var upgrade: Boolean? - var researched: Boolean? - var prerequisites: Record - var research_unit_ingredients: Array - var effects: Array - var research_unit_count: uint - var research_unit_energy: double - var order: String - var level: uint - var research_unit_count_formula: String? - var valid: Boolean? - var object_name: String /* "LuaTechnology" */ - fun help(): String -} - -external interface LuaTechnologyPrototype { - var name: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var enabled: Boolean? - var hidden: Boolean? - var visible_when_disabled: Boolean? - var ignore_tech_cost_multiplier: Boolean? - var upgrade: Boolean? - var prerequisites: Record - var research_unit_ingredients: Array - var effects: Array - var research_unit_count: uint - var research_unit_energy: double - var order: String - var level: uint - var max_level: uint - var research_unit_count_formula: String? - var valid: Boolean? - var object_name: String /* "LuaTechnologyPrototype" */ - fun help(): String -} - -external interface LuaTile { - fun collides_with(layer: String /* "ground-tile" | "water-tile" | "resource-layer" | "doodad-layer" | "floor-layer" | "item-layer" | "ghost-layer" | "object-layer" | "player-layer" | "train-layer" | "rail-layer" | "transport-belt-layer" | "not-setup" */): Boolean? -// fun collides_with(layer: ): Boolean? - fun to_be_deconstructed(): Boolean? - fun order_deconstruction(force: String, player: uint = definedExternally): LuaEntity? - fun order_deconstruction(force: String): LuaEntity? - fun order_deconstruction(force: String, player: String = definedExternally): LuaEntity? - fun order_deconstruction(force: String, player: LuaPlayer = definedExternally): LuaEntity? - fun order_deconstruction(force: LuaForce, player: uint = definedExternally): LuaEntity? - fun order_deconstruction(force: LuaForce): LuaEntity? - fun order_deconstruction(force: LuaForce, player: String = definedExternally): LuaEntity? - fun order_deconstruction(force: LuaForce, player: LuaPlayer = definedExternally): LuaEntity? - fun cancel_deconstruction(force: String, player: uint = definedExternally) - fun cancel_deconstruction(force: String) - fun cancel_deconstruction(force: String, player: String = definedExternally) - fun cancel_deconstruction(force: String, player: LuaPlayer = definedExternally) - fun cancel_deconstruction(force: LuaForce, player: uint = definedExternally) - fun cancel_deconstruction(force: LuaForce) - fun cancel_deconstruction(force: LuaForce, player: String = definedExternally) - fun cancel_deconstruction(force: LuaForce, player: LuaPlayer = definedExternally) - var name: String - var prototype: LuaTilePrototype - var position: PositionTable - var hidden_tile: String? - var surface: LuaSurface - var valid: Boolean? - var object_name: String /* "LuaTile" */ - fun help(): String -} - -external interface `T$86` { - var minable: Boolean? - var miningtime: double - var miningparticle: String? - get() = definedExternally - set(value) = definedExternally - var products: Array -} - -external interface LuaTilePrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var collision_mask: CollisionMask - var collision_mask_with_flags: CollisionMaskWithFlags - var layer: uint - var autoplace_specification: AutoplaceSpecification? - var walking_speed_modifier: float - var vehicle_friction_modifier: float - var map_color: ColorTable - var decorative_removal_probability: float - var automatic_neighbors: Boolean? - var allowed_neighbors: Record - var needs_correction: Boolean? - var mineable_properties: `T$86` - var next_direction: LuaTilePrototype? - var items_to_place_this: Array - var can_be_part_of_blueprint: Boolean? - var emissions_per_second: double - var valid: Boolean? - var object_name: String /* "LuaTilePrototype" */ - fun help(): String -} - -external interface LuaTrain { - fun get_item_count(item: String = definedExternally): uint - fun get_contents(): Record - fun remove_item(stack: String): uint - fun remove_item(stack: ItemStackDefinition): uint - fun remove_item(stack: LuaItemStack): uint - fun insert(stack: String) - fun insert(stack: ItemStackDefinition) - fun insert(stack: LuaItemStack) - fun clear_items_inside() - fun recalculate_path(force: Boolean = definedExternally): Boolean? - fun get_fluid_count(fluid: String = definedExternally): double - fun get_fluid_contents(): Record - fun remove_fluid(fluid: Fluid): double - fun insert_fluid(fluid: Fluid): double - fun clear_fluids_inside() - fun go_to_station(index: uint) - fun get_rails(): Array - var manual_mode: Boolean? - var speed: double - var max_forward_speed: double - var max_backward_speed: double - var weight: double - var carriages: Array - var locomotives: Record> - var cargo_wagons: Array - var fluid_wagons: Array - var schedule: TrainSchedule? - var state: train_state - var front_rail: LuaEntity? - var back_rail: LuaEntity? - var rail_direction_from_front_rail: rail_direction - var rail_direction_from_back_rail: rail_direction - var front_stock: LuaEntity? - var back_stock: LuaEntity? - var station: LuaEntity? - var has_path: Boolean? - var path_end_rail: LuaEntity? - var path_end_stop: LuaEntity? - var id: uint - var passengers: Array - var riding_state: RidingState - var killed_players: Record - var kill_count: uint - var path: LuaRailPath? - var signal: LuaEntity? - var valid: Boolean? - var object_name: String /* "LuaTrain" */ - fun help(): String -} - -external interface LuaTrainStopControlBehavior : LuaGenericOnOffControlBehavior { - var send_to_train: Boolean? - var read_from_train: Boolean? - var read_stopped_train: Boolean? - var set_trains_limit: Boolean? - var read_trains_count: Boolean? - var enable_disable: Boolean? - var stopped_train_signal: SignalID - var trains_count_signal: SignalID - var trains_limit_signal: SignalID - override var valid: Boolean? - override var object_name: String /* "LuaTrainStopControlBehavior" */ - override fun help(): String -} - -external interface LuaTransportBeltControlBehavior : LuaGenericOnOffControlBehavior { - var enable_disable: Boolean? - var read_contents: Boolean? - var read_contents_mode: content_read_mode - override var valid: Boolean? - override var object_name: String /* "LuaTransportBeltControlBehavior" */ - override fun help(): String -} - -typealias LuaTransportLine = Array - -external interface LuaTrivialSmokePrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var color: ColorTable - var start_scale: double - var end_scale: double - var movement_slow_down_factor: double - var duration: uint - var spread_duration: uint - var fade_away_duration: uint - var fade_in_duration: uint - var glow_fade_away_duration: uint - var cyclic: Boolean? - var affected_by_wind: Boolean? - var show_when_smoke_off: Boolean? - var glow_animation: Boolean? - var render_layer: dynamic /* Number | */ - get() = definedExternally - set(value) = definedExternally - var valid: Boolean? - var object_name: String /* "LuaTrivialSmokePrototype" */ - fun help(): String -} - -external interface LuaUnitGroup { - fun add_member(unit: LuaEntity) - fun set_command(command: AttackCommand) - fun set_command(command: GoToLocationCommand) - fun set_command(command: CompoundCommand) - fun set_command(command: GroupCommand) - fun set_command(command: AttackAreaCommand) - fun set_command(command: WanderCommand) - fun set_command(command: StopCommand) - fun set_command(command: FleeCommand) - fun set_command(command: BuildBaseCommand) - fun set_distraction_command(command: AttackCommand) - fun set_distraction_command(command: GoToLocationCommand) - fun set_distraction_command(command: CompoundCommand) - fun set_distraction_command(command: GroupCommand) - fun set_distraction_command(command: AttackAreaCommand) - fun set_distraction_command(command: WanderCommand) - fun set_distraction_command(command: StopCommand) - fun set_distraction_command(command: FleeCommand) - fun set_distraction_command(command: BuildBaseCommand) - fun set_autonomous() - fun start_moving() - fun destroy() - var members: Array - var position: PositionTable - var state: group_state - var force: LuaForce - var surface: LuaSurface - var group_number: uint - var is_script_driven: Boolean? - var command: dynamic /* AttackCommand? | GoToLocationCommand? | CompoundCommand? | GroupCommand? | AttackAreaCommand? | WanderCommand? | StopCommand? | FleeCommand? | BuildBaseCommand? */ - get() = definedExternally - set(value) = definedExternally - var distraction_command: dynamic /* AttackCommand? | GoToLocationCommand? | CompoundCommand? | GroupCommand? | AttackAreaCommand? | WanderCommand? | StopCommand? | FleeCommand? | BuildBaseCommand? */ - get() = definedExternally - set(value) = definedExternally - var valid: Boolean? - var object_name: String /* "LuaUnitGroup" */ - fun help(): String -} - -external interface LuaVirtualSignalPrototype { - var name: String - var order: String - var localised_name: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var localised_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var special: Boolean? - var subgroup: LuaGroup - var valid: Boolean? - var object_name: String /* "LuaVirtualSignalPrototype" */ - fun help(): String -} - -external interface LuaVoidEnergySourcePrototype { - var emissions: double - var render_no_network_icon: Boolean? - var render_no_power_icon: Boolean? - var valid: Boolean? - var object_name: String /* "LuaVoidEnergySourcePrototype" */ - fun help(): String -} - -external interface LuaWallControlBehavior : LuaControlBehavior { - var circuit_condition: CircuitConditionDefinition - var open_gate: Boolean? - var read_sensor: Boolean? - var output_signal: SignalID - var valid: Boolean? - var object_name: String /* "LuaWallControlBehavior" */ - fun help(): String -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/concepts.module_typed-factorio.kt b/modules/mod2/dukat-custom/concepts.module_typed-factorio.kt deleted file mode 100644 index b30c7c9..0000000 --- a/modules/mod2/dukat-custom/concepts.module_typed-factorio.kt +++ /dev/null @@ -1,2924 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import defines.relative_gui_type -import defines.relative_gui_position -import tsstdlib.Record -import tsstdlib.Position -import defines.difficulty_settings.recipe_difficulty -import defines.difficulty_settings.technology_difficulty -import defines.circuit_connector_id -import defines.direction -import defines.wire_type -import defines.command -import defines.distraction -import defines.compound_command -import defines.inventory -import defines.riding.acceleration -import defines.riding.direction as _defines_riding_direction -import defines.control_behavior.mining_drill.resource_read_mode -import defines.control_behavior.inserter.hand_read_mode -import defines.control_behavior.transport_belt.content_read_mode - -external interface DisplayResolution { - var width: uint - var height: uint -} - -external interface PersonalLogisticParameters { - var name: String? - get() = definedExternally - set(value) = definedExternally - var min: uint? - get() = definedExternally - set(value) = definedExternally - var max: uint? - get() = definedExternally - set(value) = definedExternally -} - -typealias RealOrientation = float - -external interface PositionTable { - var x: int - var y: int -} - -external interface ChunkPositionTable { - var x: int - var y: int -} - -external interface TilePositionTable { - var x: int - var y: int -} - -external interface GuiLocationTable { - var x: int - var y: int -} - -external interface ChunkPositionAndArea { - var x: int - var y: int - var area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally -} - -external interface EquipmentPoint { - var x: uint - var y: uint -} - -external interface GuiAnchor { - var gui: relative_gui_type - var position: relative_gui_position - var type: String? - get() = definedExternally - set(value) = definedExternally - var name: String? - get() = definedExternally - set(value) = definedExternally - var names: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface TabAndContent { - var tab: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var content: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally -} - -external interface OldTileAndPosition { - var old_tile: LuaTilePrototype - var position: dynamic /* TilePositionTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally -} - -typealias Tags = Record - -external interface SmokeSource { - var name: String - var frequency: double - var offset: double - var position: PositionTable? - get() = definedExternally - set(value) = definedExternally - var north_position: PositionTable? - get() = definedExternally - set(value) = definedExternally - var east_position: PositionTable? - get() = definedExternally - set(value) = definedExternally - var south_position: PositionTable? - get() = definedExternally - set(value) = definedExternally - var west_position: PositionTable? - get() = definedExternally - set(value) = definedExternally - var deviation: Position? - get() = definedExternally - set(value) = definedExternally - var starting_frame_speed: uint16 - var starting_frame_speed_deviation: double - var starting_frame: uint16 - var starting_frame_deviation: double - var slow_down_factor: uint8 - var height: float - var height_deviation: float - var starting_vertical_speed: float - var starting_vertical_speed_deviation: float - var vertical_speed_slowdown: float -} - -external interface BoundingBoxTable { - var left_top: Position - var right_bottom: Position - var orientation: RealOrientation? - get() = definedExternally - set(value) = definedExternally -} - -external interface ScriptArea { - var area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var name: String - var color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var id: uint -} - -external interface ScriptPosition { - var position: Position - var name: String - var color: dynamic /* ColorTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var id: uint -} - -external interface ColorTable { - var r: float? - get() = definedExternally - set(value) = definedExternally - var g: float? - get() = definedExternally - set(value) = definedExternally - var b: float? - get() = definedExternally - set(value) = definedExternally - var a: float? - get() = definedExternally - set(value) = definedExternally -} - -external interface ColorModifierTable { - var r: float? - get() = definedExternally - set(value) = definedExternally - var g: float? - get() = definedExternally - set(value) = definedExternally - var b: float? - get() = definedExternally - set(value) = definedExternally - var a: float? - get() = definedExternally - set(value) = definedExternally -} - -external interface CraftingQueueItem { - var index: uint - var recipe: String - var count: uint -} - -external interface Alert { - var tick: uint - var target: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var prototype: LuaEntityPrototype? - get() = definedExternally - set(value) = definedExternally - var position: Position? - get() = definedExternally - set(value) = definedExternally - var icon: SignalID? - get() = definedExternally - set(value) = definedExternally - var message: dynamic /* JsTuple | String? | Number? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ScriptRenderVertexTarget { - var target: dynamic /* Position | LuaEntity */ - get() = definedExternally - set(value) = definedExternally - var target_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally -} - -external interface PathfinderWaypoint { - var position: Position - var needs_destroy_to_reach: Boolean -} - -external interface CutsceneWaypoint { - var position: Position? - get() = definedExternally - set(value) = definedExternally - var target: dynamic /* LuaEntity? | LuaUnitGroup? */ - get() = definedExternally - set(value) = definedExternally - var transition_time: uint - var time_to_wait: uint - var zoom: double? - get() = definedExternally - set(value) = definedExternally -} - -external interface Decorative { - var name: String - var position: Position - var amount: uint8 -} - -external interface DecorativeResult { - var position: dynamic /* TilePositionTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var decorative: LuaDecorativePrototype - var amount: uint -} - -external interface ChartTagSpec { - var position: Position - var icon: SignalID? - get() = definedExternally - set(value) = definedExternally - var text: String? - get() = definedExternally - set(value) = definedExternally - var last_user: dynamic /* uint? | String? | LuaPlayer? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface GameViewSettings { - var show_controller_gui: Boolean - var show_minimap: Boolean - var show_research_info: Boolean - var show_entity_info: Boolean - var show_alert_gui: Boolean - var update_entity_selection: Boolean - var show_rail_block_visualisation: Boolean - var show_side_menu: Boolean - var show_map_view_options: Boolean - var show_quickbar: Boolean - var show_shortcut_bar: Boolean -} - -external interface MapViewSettings { - @nativeGetter - operator fun get(key: String): Boolean? - @nativeSetter - operator fun set(key: String, value: Boolean?) -} - -external interface PollutionMapSettings { - var enabled: Boolean - var diffusion_ratio: double - var min_to_diffuse: double - var aeging: double - var expected_max_per_chunk: double - var min_to_show_per_chunk: double - var min_pollution_to_damage_trees: double - var pollution_with_max_forest_damage: double - var pollution_per_tree_damage: double - var pollution_restored_per_tree_damage: double - var max_pollution_to_restore_trees: double - var enemy_attack_pollution_consumption_modifier: double -} - -external interface EnemyEvolutionMapSettings { - var enabled: Boolean - var time_factor: double - var destroy_factor: double - var pollution_factor: double -} - -external interface EnemyExpansionMapSettings { - var enabled: Boolean - var max_expansion_distance: uint - var friendly_base_influence_radius: uint - var enemy_building_influence_radius: uint - var building_coefficient: double - var other_base_coefficient: double - var neighbouring_chunk_coefficient: double - var neighbouring_base_chunk_coefficient: double - var max_colliding_tiles_coefficient: double - var settler_group_min_size: uint - var settler_group_max_size: uint - var min_expansion_cooldown: uint - var max_expansion_cooldown: uint -} - -external interface UnitGroupMapSettings { - var min_group_gathering_time: uint - var max_group_gathering_time: uint - var max_wait_time_for_late_members: uint - var min_group_radius: double - var max_group_radius: double - var max_member_speedup_when_behind: double - var max_member_slowdown_when_ahead: double - var max_group_slowdown_factor: double - var max_group_member_fallback_factor: double - var member_disown_distance: double - var tick_tolerance_when_member_arrives: uint - var max_gathering_unit_groups: uint - var max_unit_group_size: uint -} - -external interface SteeringMapSetting { - var radius: double - var separation_factor: double - var separation_force: double - var force_unit_fuzzy_goto_behavior: Boolean -} - -external interface SteeringMapSettings { - var default: SteeringMapSetting - var moving: SteeringMapSetting -} - -external interface PathFinderMapSettings { - var fwd2bwd_ratio: uint - var goal_pressure_ratio: double - var max_steps_worked_per_tick: double - var max_work_done_per_tick: uint - var use_path_cache: Boolean - var short_cache_size: uint - var long_cache_size: uint - var short_cache_min_cacheable_distance: double - var short_cache_min_algo_steps_to_cache: uint - var long_cache_min_cacheable_distance: double - var cache_max_connect_to_cache_steps_multiplier: uint - var cache_accept_path_start_distance_ratio: double - var cache_accept_path_end_distance_ratio: double - var negative_cache_accept_path_start_distance_ratio: double - var negative_cache_accept_path_end_distance_ratio: double - var cache_path_start_distance_rating_multiplier: double - var cache_path_end_distance_rating_multiplier: double - var stale_enemy_with_same_destination_collision_penalty: double - var ignore_moving_enemy_collision_distance: double - var enemy_with_different_destination_collision_penalty: double - var general_entity_collision_penalty: double - var general_entity_subsequent_collision_penalty: double - var extended_collision_penalty: double - var max_clients_to_accept_any_new_request: uint - var max_clients_to_accept_short_new_request: uint - var direct_distance_to_consider_short_request: uint - var short_request_max_steps: uint - var short_request_ratio: double - var min_steps_to_check_path_find_termination: uint - var start_to_goal_cost_multiplier_to_terminate_path_find: double - var overload_levels: Array - var overload_multipliers: Array - var negative_path_cache_delay_interval: uint -} - -external interface MapSettings { - var pollution: PollutionMapSettings - var enemy_evolution: EnemyEvolutionMapSettings - var enemy_expansion: EnemyExpansionMapSettings - var unit_group: UnitGroupMapSettings - var steering: SteeringMapSettings - var path_finder: PathFinderMapSettings - var max_failed_behavior_count: uint -} - -external interface DifficultySettings { - var recipe_difficulty: recipe_difficulty - var technology_difficulty: technology_difficulty - var technology_price_multiplier: double - var research_queue_setting: String /* "after-victory" | "always" | "never" */ -} - -external interface MapExchangeStringData { - var map_settings: MapSettings - var map_gen_settings: MapGenSettings -} - -external interface BlueprintItemIcon { - var name: String - var index: uint -} - -external interface BlueprintSignalIcon { - var signal: SignalID - var index: uint -} - -external interface BlueprintConnectionData { - var entity_id: uint - var circuit_id: circuit_connector_id? - get() = definedExternally - set(value) = definedExternally -} - -external interface BlueprintConnectionPoint { - var red: Array? - get() = definedExternally - set(value) = definedExternally - var green: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface BlueprintCircuitConnection { - @nativeGetter - operator fun get(key: String): BlueprintConnectionPoint? - @nativeSetter - operator fun set(key: String, value: BlueprintConnectionPoint?) -} - -external interface BlueprintEntity { - var entity_number: uint - var name: String - var position: Position - var direction: direction? - get() = definedExternally - set(value) = definedExternally - var tags: Tags? - get() = definedExternally - set(value) = definedExternally - var items: Record? - get() = definedExternally - set(value) = definedExternally - var connections: BlueprintCircuitConnection? - get() = definedExternally - set(value) = definedExternally - var control_behavior: BlueprintControlBehavior? - get() = definedExternally - set(value) = definedExternally - var schedule: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface Tile { - var position: Position - var name: String -} - -external interface Fluid { - var name: String - var amount: double - var temperature: double? - get() = definedExternally - set(value) = definedExternally -} - -external interface BaseIngredient { - var type: String /* "item" | "fluid" */ - var name: String - var amount: double - var catalyst_amount: dynamic /* uint? | double? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FluidIngredient : BaseIngredient { - override var type: String /* "fluid" */ - var minimum_temperature: double? - get() = definedExternally - set(value) = definedExternally - var maximum_temperature: double? - get() = definedExternally - set(value) = definedExternally -} - -external interface OtherIngredient : BaseIngredient { - override var type: String /* "item" */ -} - -external interface BaseProduct { - var type: String /* "item" | "fluid" */ - var name: String - var amount: double? - get() = definedExternally - set(value) = definedExternally - var amount_min: dynamic /* uint? | double? */ - get() = definedExternally - set(value) = definedExternally - var amount_max: dynamic /* uint? | double? */ - get() = definedExternally - set(value) = definedExternally - var probability: double? - get() = definedExternally - set(value) = definedExternally - var catalyst_amount: dynamic /* uint? | double? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FluidProduct : BaseProduct { - override var type: String /* "fluid" */ - var temperature: double? - get() = definedExternally - set(value) = definedExternally -} - -external interface OtherProduct : BaseProduct { - override var type: String /* "item" */ -} - -external interface Loot { - var item: String - var probability: double - var count_min: double - var count_max: double -} - -external interface BaseTechnologyModifier { - var type: String /* "inserter-stack-size-bonus" | "stack-inserter-capacity-bonus" | "laboratory-speed" | "character-logistic-trash-slots" | "maximum-following-robots-count" | "worker-robot-speed" | "worker-robot-storage" | "ghost-time-to-live" | "turret-attack" | "ammo-damage" | "give-item" | "gun-speed" | "unlock-recipe" | "character-crafting-speed" | "character-mining-speed" | "character-running-speed" | "character-build-distance" | "character-item-drop-distance" | "character-reach-distance" | "character-resource-reach-distance" | "character-item-pickup-distance" | "character-loot-pickup-distance" | "character-inventory-slots-bonus" | "deconstruction-time-to-live" | "max-failed-attempts-per-tick-per-construction-queue" | "max-successful-attempts-per-tick-per-construction-queue" | "character-health-bonus" | "mining-drill-productivity-bonus" | "train-braking-force-bonus" | "zoom-to-world-enabled" | "zoom-to-world-ghost-building-enabled" | "zoom-to-world-blueprint-enabled" | "zoom-to-world-deconstruction-planner-enabled" | "zoom-to-world-upgrade-planner-enabled" | "zoom-to-world-selection-tool-enabled" | "worker-robot-battery" | "laboratory-productivity" | "follower-robot-lifetime" | "artillery-range" | "nothing" | "character-additional-mining-categories" | "character-logistic-requests" */ -} - -external interface GunSpeedTechnologyModifier : BaseTechnologyModifier { - override var type: String /* "gun-speed" */ - var ammo_category: String - var modifier: double -} - -external interface AmmoDamageTechnologyModifier : BaseTechnologyModifier { - override var type: String /* "ammo-damage" */ - var ammo_category: String - var modifier: double -} - -external interface GiveItemTechnologyModifier : BaseTechnologyModifier { - override var type: String /* "give-item" */ - var item: String - var count: uint? - get() = definedExternally - set(value) = definedExternally -} - -external interface TurretAttackTechnologyModifier : BaseTechnologyModifier { - override var type: String /* "turret-attack" */ - var turret_id: String - var modifier: double -} - -external interface UnlockRecipeTechnologyModifier : BaseTechnologyModifier { - override var type: String /* "unlock-recipe" */ - var recipe: String -} - -external interface NothingTechnologyModifier : BaseTechnologyModifier { - override var type: String /* "nothing" */ - var effect_description: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally -} - -external interface OtherTechnologyModifier : BaseTechnologyModifier { - override var type: String /* "inserter-stack-size-bonus" | "stack-inserter-capacity-bonus" | "laboratory-speed" | "character-logistic-trash-slots" | "maximum-following-robots-count" | "worker-robot-speed" | "worker-robot-storage" | "ghost-time-to-live" | "character-crafting-speed" | "character-mining-speed" | "character-running-speed" | "character-build-distance" | "character-item-drop-distance" | "character-reach-distance" | "character-resource-reach-distance" | "character-item-pickup-distance" | "character-loot-pickup-distance" | "character-inventory-slots-bonus" | "deconstruction-time-to-live" | "max-failed-attempts-per-tick-per-construction-queue" | "max-successful-attempts-per-tick-per-construction-queue" | "character-health-bonus" | "mining-drill-productivity-bonus" | "train-braking-force-bonus" | "zoom-to-world-enabled" | "zoom-to-world-ghost-building-enabled" | "zoom-to-world-blueprint-enabled" | "zoom-to-world-deconstruction-planner-enabled" | "zoom-to-world-upgrade-planner-enabled" | "zoom-to-world-selection-tool-enabled" | "worker-robot-battery" | "laboratory-productivity" | "follower-robot-lifetime" | "artillery-range" | "character-additional-mining-categories" | "character-logistic-requests" */ - var modifier: double -} - -external interface Offer { - var price: Array - var offer: dynamic /* GunSpeedTechnologyModifier | AmmoDamageTechnologyModifier | GiveItemTechnologyModifier | TurretAttackTechnologyModifier | UnlockRecipeTechnologyModifier | NothingTechnologyModifier | OtherTechnologyModifier */ - get() = definedExternally - set(value) = definedExternally -} - -external interface AutoplaceSpecification { - var probability_expression: NoiseExpression - var richness_expression: NoiseExpression - var coverage: double - var sharpness: double - var max_probability: double - var placement_density: uint - var richness_base: double - var richness_multiplier: double - var richness_multiplier_distance_bonus: double - var starting_area_size: uint - var order: String - var default_enabled: Boolean - var peaks: Array? - get() = definedExternally - set(value) = definedExternally - var control: String? - get() = definedExternally - set(value) = definedExternally - var tile_restriction: Array? - get() = definedExternally - set(value) = definedExternally - var force: String - var random_probability_penalty: double -} - -external interface NoiseExpression { - var type: String -} - -external interface AutoplaceSpecificationPeak { - var influence: double - var max_influence: double - var min_influence: double - var richness_influence: double - var noisePersistence: double - var noise_layer: String? - get() = definedExternally - set(value) = definedExternally - var noise_octaves_difference: double - var water_optimal: double - var water_range: double - var water_max_range: double - var water_top_property_limit: double - var elevation_optimal: double - var elevation_range: double - var elevation_max_range: double - var elevation_top_property_limit: double - var temperature_optimal: double - var temperature_range: double - var temperature_max_range: double - var temperature_top_property_limit: double - var starting_area_weight_optimal: double - var starting_area_weight_range: double - var starting_area_weight_max_range: double - var starting_area_weight_top_property_limit: double - var tier_from_start_optimal: double - var tier_from_start_range: double - var tier_from_start_max_range: double - var tier_from_start_top_property_limit: double - var distance_optimal: double - var distance_range: double - var distance_max_range: double - var distance_top_property_limit: double - var aux_optimal: double - var aux_range: double - var aux_max_range: double - var aux_top_property_limit: double -} - -external interface AutoplaceSpecificationRestriction { - var first: String? - get() = definedExternally - set(value) = definedExternally - var second: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface Resistance { - var decrease: float - var percent: float -} - -external interface AutoplaceSetting { - var frequency: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ - get() = definedExternally - set(value) = definedExternally - var size: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ - get() = definedExternally - set(value) = definedExternally - var richness: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface AutoplaceSettings { - var treat_missing_as_default: Boolean - var settings: Record -} - -external interface AutoplaceControl { - var frequency: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ - get() = definedExternally - set(value) = definedExternally - var size: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ - get() = definedExternally - set(value) = definedExternally - var richness: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface CliffPlacementSettings { - var name: String - var cliff_elevation_0: float - var cliff_elevation_interval: float - var richness: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface MapGenSettings { - var terrain_segmentation: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ - get() = definedExternally - set(value) = definedExternally - var water: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ - get() = definedExternally - set(value) = definedExternally - var autoplace_controls: Record - var default_enable_all_autoplace_controls: Boolean - var autoplace_settings: Record - var cliff_settings: CliffPlacementSettings - var seed: uint - var width: uint - var height: uint - var starting_area: dynamic /* Number | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ - get() = definedExternally - set(value) = definedExternally - var starting_points: Array - var peaceful_mode: Boolean - var property_expression_names: Record -} - -external interface MapGenSettingsPartial { - var terrain_segmentation: dynamic /* Number? | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ - get() = definedExternally - set(value) = definedExternally - var water: dynamic /* Number? | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ - get() = definedExternally - set(value) = definedExternally - var autoplace_controls: Record? - get() = definedExternally - set(value) = definedExternally - var default_enable_all_autoplace_controls: Boolean? - get() = definedExternally - set(value) = definedExternally - var autoplace_settings: Record? - get() = definedExternally - set(value) = definedExternally - var cliff_settings: CliffPlacementSettings? - get() = definedExternally - set(value) = definedExternally - var seed: uint? - get() = definedExternally - set(value) = definedExternally - var width: uint? - get() = definedExternally - set(value) = definedExternally - var height: uint? - get() = definedExternally - set(value) = definedExternally - var starting_area: dynamic /* Number? | "none" | "very-low" | "very-small" | "very-poor" | "low" | "small" | "poor" | "normal" | "medium" | "regular" | "high" | "big" | "good" | "very-high" | "very-big" | "very-good" */ - get() = definedExternally - set(value) = definedExternally - var starting_points: Array? - get() = definedExternally - set(value) = definedExternally - var peaceful_mode: Boolean? - get() = definedExternally - set(value) = definedExternally - var property_expression_names: Record? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignalID { - var type: String /* "item" | "fluid" | "virtual" */ - var name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface Signal { - var signal: SignalID - var count: int -} - -external interface UpgradeFilter { - var type: String /* "item" | "entity" */ - var name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface InfinityInventoryFilter { - var name: String - var count: uint? - get() = definedExternally - set(value) = definedExternally - var mode: String? /* "at-least" | "at-most" | "exactly" */ - get() = definedExternally - set(value) = definedExternally - var index: uint -} - -external interface InfinityPipeFilter { - var name: String - var percentage: double? - get() = definedExternally - set(value) = definedExternally - var temperature: double? - get() = definedExternally - set(value) = definedExternally - var mode: String? /* "at-least" | "at-most" | "exactly" | "add" | "remove" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FluidBoxFilter { - var name: String - var minimum_temperature: double - var maximum_temperature: double -} - -external interface FluidBoxFilterSpec { - var name: String - var minimum_temperature: double? - get() = definedExternally - set(value) = definedExternally - var maximum_temperature: double? - get() = definedExternally - set(value) = definedExternally - var force: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface HeatSetting { - var temperature: double? - get() = definedExternally - set(value) = definedExternally - var mode: String? /* "at-least" | "at-most" | "exactly" | "add" | "remove" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface HeatConnection { - var position: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var direction: direction -} - -external interface FluidBoxConnection { - var type: String /* "input" | "output" | "input-output" */ - var positions: Array - var max_underground_distance: uint? - get() = definedExternally - set(value) = definedExternally -} - -external interface ArithmeticCombinatorParameters { - var first_signal: SignalID? - get() = definedExternally - set(value) = definedExternally - var second_signal: SignalID? - get() = definedExternally - set(value) = definedExternally - var first_constant: int? - get() = definedExternally - set(value) = definedExternally - var second_constant: int? - get() = definedExternally - set(value) = definedExternally - var operation: String? /* "*" | "/" | "+" | "-" | "%" | "^" | "<<" | ">>" | "AND" | "OR" | "XOR" */ - get() = definedExternally - set(value) = definedExternally - var output_signal: SignalID? - get() = definedExternally - set(value) = definedExternally -} - -external interface ConstantCombinatorParameters { - var signal: SignalID - var count: int - var index: uint -} - -external interface DeciderCombinatorParameters { - var first_signal: SignalID? - get() = definedExternally - set(value) = definedExternally - var second_signal: SignalID? - get() = definedExternally - set(value) = definedExternally - var constant: uint? - get() = definedExternally - set(value) = definedExternally - var comparator: String? /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - get() = definedExternally - set(value) = definedExternally - var output_signal: SignalID? - get() = definedExternally - set(value) = definedExternally - var copy_count_from_input: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface InserterCircuitConditions { - var circuit: CircuitCondition? - get() = definedExternally - set(value) = definedExternally - var logistics: CircuitCondition? - get() = definedExternally - set(value) = definedExternally -} - -external interface CircuitCondition { - var comparator: String? /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - get() = definedExternally - set(value) = definedExternally - var first_signal: SignalID? - get() = definedExternally - set(value) = definedExternally - var second_signal: SignalID? - get() = definedExternally - set(value) = definedExternally - var constant: int? - get() = definedExternally - set(value) = definedExternally -} - -external interface CircuitConditionDefinition { - var condition: CircuitCondition - var fulfilled: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface CircuitConnectionDefinition { - var wire: wire_type - var target_entity: LuaEntity - var source_circuit_id: circuit_connector_id - var target_circuit_id: circuit_connector_id -} - -external interface WireConnectionDefinition { - var wire: wire_type - var target_entity: LuaEntity - var source_circuit_id: circuit_connector_id? - get() = definedExternally - set(value) = definedExternally - var target_circuit_id: circuit_connector_id? - get() = definedExternally - set(value) = definedExternally - var source_wire_id: circuit_connector_id? - get() = definedExternally - set(value) = definedExternally - var target_wire_id: circuit_connector_id? - get() = definedExternally - set(value) = definedExternally -} - -external interface InventoryFilter { - var index: uint - var name: String -} - -external interface PlaceAsTileResult { - var result: LuaTilePrototype - var condition_size: uint - var condition: CollisionMask -} - -external interface BaseCommand { - var type: command -} - -external interface AttackCommand : BaseCommand { - var target: LuaEntity - var distraction: distraction? - get() = definedExternally - set(value) = definedExternally -} - -external interface GoToLocationCommand : BaseCommand { - var destination: Position? - get() = definedExternally - set(value) = definedExternally - var destination_entity: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var distraction: distraction? - get() = definedExternally - set(value) = definedExternally - var pathfind_flags: PathfinderFlags? - get() = definedExternally - set(value) = definedExternally - var radius: double? - get() = definedExternally - set(value) = definedExternally -} - -external interface CompoundCommand : BaseCommand { - var structure_type: compound_command - var commands: Array -} - -external interface GroupCommand : BaseCommand { - var group: LuaUnitGroup - var distraction: distraction? - get() = definedExternally - set(value) = definedExternally - var use_group_distraction: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface AttackAreaCommand : BaseCommand { - var destination: Position - var radius: double - var distraction: distraction? - get() = definedExternally - set(value) = definedExternally -} - -external interface WanderCommand : BaseCommand { - var distraction: distraction? - get() = definedExternally - set(value) = definedExternally - var radius: double? - get() = definedExternally - set(value) = definedExternally - var wander_in_group: Boolean? - get() = definedExternally - set(value) = definedExternally - var ticks_to_wait: uint? - get() = definedExternally - set(value) = definedExternally -} - -external interface StopCommand : BaseCommand { - var distraction: distraction? - get() = definedExternally - set(value) = definedExternally - var ticks_to_wait: uint? - get() = definedExternally - set(value) = definedExternally -} - -external interface FleeCommand : BaseCommand { - var from: LuaEntity - var distraction: distraction? - get() = definedExternally - set(value) = definedExternally -} - -external interface BuildBaseCommand : BaseCommand { - var destination: Position - var distraction: distraction? - get() = definedExternally - set(value) = definedExternally - var ignore_planner: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface PathfinderFlags { - var allow_destroy_friendly_entities: Boolean? - get() = definedExternally - set(value) = definedExternally - var allow_paths_through_own_entities: Boolean? - get() = definedExternally - set(value) = definedExternally - var cache: Boolean? - get() = definedExternally - set(value) = definedExternally - var prefer_straight_paths: Boolean? - get() = definedExternally - set(value) = definedExternally - var low_priority: Boolean? - get() = definedExternally - set(value) = definedExternally - var no_break: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface UnitSpawnDefinition { - var unit: String - var spawn_points: Array -} - -external interface SpawnPointDefinition { - var evolution_factor: double - var weight: double -} - -external interface ItemStackDefinition { - var name: String - var count: uint? - get() = definedExternally - set(value) = definedExternally - var health: float? - get() = definedExternally - set(value) = definedExternally - var durability: double? - get() = definedExternally - set(value) = definedExternally - var ammo: double? - get() = definedExternally - set(value) = definedExternally - var tags: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface WaitCondition { - var type: String /* "time" | "inactivity" | "full" | "empty" | "item_count" | "circuit" | "robots_inactive" | "fluid_count" | "passenger_present" | "passenger_not_present" */ - var compare_type: String /* "and" | "or" */ - var ticks: uint? - get() = definedExternally - set(value) = definedExternally - var condition: CircuitCondition? - get() = definedExternally - set(value) = definedExternally -} - -external interface TrainScheduleRecord { - var station: String? - get() = definedExternally - set(value) = definedExternally - var rail: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var wait_conditions: Array? - get() = definedExternally - set(value) = definedExternally - var temporary: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TrainSchedule { - var current: uint - var records: Array -} - -external interface BaseGuiArrowSpecification { - var type: String /* "nowhere" | "goal" | "entity_info" | "active_window" | "entity" | "position" | "crafting_queue" | "item_stack" */ -} - -external interface EntityGuiArrowSpecification : BaseGuiArrowSpecification { - override var type: String /* "entity" */ - var entity: LuaEntity -} - -external interface PositionGuiArrowSpecification : BaseGuiArrowSpecification { - override var type: String /* "position" */ - var position: Position -} - -external interface CraftingQueueGuiArrowSpecification : BaseGuiArrowSpecification { - override var type: String /* "crafting_queue" */ - var crafting_queueindex: uint -} - -external interface ItemStackGuiArrowSpecification : BaseGuiArrowSpecification { - override var type: String /* "item_stack" */ - var inventory_index: inventory - var item_stack_index: uint - var source: String /* "player" | "target" | "player-quickbar" | "player-equipment-bar" */ -} - -external interface OtherGuiArrowSpecification : BaseGuiArrowSpecification { - override var type: String /* "nowhere" | "goal" | "entity_info" | "active_window" */ -} - -external interface AmmoType { - var action: Array? - get() = definedExternally - set(value) = definedExternally - var target_type: String /* "entity" | "position" | "direction" */ - var clamp_position: Boolean? - get() = definedExternally - set(value) = definedExternally - var category: String - var energy_consumption: double? - get() = definedExternally - set(value) = definedExternally -} - -external interface BeamTarget { - var entity: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var position: Position? - get() = definedExternally - set(value) = definedExternally -} - -external interface RidingState { - var acceleration: acceleration - var direction: _defines_riding_direction -} - -external interface ModuleEffectValue { - var bonus: float -} - -external interface ModuleEffects { - var consumption: ModuleEffectValue? - get() = definedExternally - set(value) = definedExternally - var speed: ModuleEffectValue? - get() = definedExternally - set(value) = definedExternally - var productivity: ModuleEffectValue? - get() = definedExternally - set(value) = definedExternally - var pollution: ModuleEffectValue? - get() = definedExternally - set(value) = definedExternally -} - -external interface EntityPrototypeFlags { - @nativeGetter - operator fun get(key: String): Boolean? - @nativeSetter - operator fun set(key: String, value: Boolean?) - var hidden: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ItemPrototypeFlags { - @nativeGetter - operator fun get(key: String): Boolean? - @nativeSetter - operator fun set(key: String, value: Boolean?) - var hidden: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -typealias CollisionMask = Any - -typealias CollisionMaskWithFlags = Any - -typealias TriggerTargetMask = Any - -external interface TriggerEffectItem { - var type: String /* "damage" | "create-entity" | "create-explosion" | "create-fire" | "create-smoke" | "create-trivial-smoke" | "create-particle" | "create-sticker" | "nested-result" | "play-sound" | "push-back" | "destroy-cliffs" | "show-explosion-on-chart" | "insert-item" | "script" */ - var repeat_count: uint - var affects_target: Boolean - var show_in_tooltip: Boolean -} - -external interface TriggerDelivery { - var type: String /* "instant" | "projectile" | "flame-thrower" | "beam" | "stream" | "artillery" */ - var source_effects: Array - var target_effects: Array -} - -external interface TriggerItem { - var type: String /* "direct" | "area" | "line" | "cluster" */ - var action_delivery: Array? - get() = definedExternally - set(value) = definedExternally - var entity_flags: EntityPrototypeFlags? - get() = definedExternally - set(value) = definedExternally - var ignore_collision_condition: Boolean - var collision_mask: CollisionMask - var trigger_target_mask: TriggerTargetMask - var force: String /* "all" | "enemy" | "ally" | "friend" | "not-friend" | "same" | "not-same" */ - var repeat_count: uint -} - -external interface CircularParticleCreationSpecification { - var name: String - var direction: float - var direction_deviation: float - var speed: float - var speed_deviation: float - var starting_frame_speed: float - var starting_frame_speed_deviation: float - var height: float - var height_deviation: float - var vertical_speed: float - var vertical_speed_deviation: float - var center: PositionTable - var creation_distance: double - var creation_distance_orientation: double - var use_source_position: Boolean -} - -external interface AttackParameterFluid { - var type: String - var damage_modifier: double -} - -external interface BaseAttackParameters { - var type: String /* "projectile" | "stream" | "beam" */ - var range: float - var min_range: float - var range_mode: String /* "center-to-center" | "bounding-box-to-bounding-box" */ - var fire_penalty: float - var rotate_penalty: float - var health_penalty: float - var min_attack_distance: float - var turn_range: float - var damage_modifier: float - var ammo_consumption_modifier: float - var cooldown: float - var warmup: uint - var movement_slow_down_factor: double - var movement_slow_down_cooldown: float - var ammo_type: AmmoType? - get() = definedExternally - set(value) = definedExternally - var ammo_categories: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface ProjectileAttackParameters : BaseAttackParameters { - override var type: String /* "projectile" */ - var projectile_center: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var projectile_creation_distance: float - var projectile_orientation_offset: float - var shell_particle: CircularParticleCreationSpecification? - get() = definedExternally - set(value) = definedExternally - var projectile_creation_parameters: Array */>? - get() = definedExternally - set(value) = definedExternally -} - -external interface StreamAttackParameters : BaseAttackParameters { - override var type: String /* "stream" */ - var gun_barrel_length: float - var gun_center_shift: Record - var fluid_consumption: float - var fluids: Array? - get() = definedExternally - set(value) = definedExternally - var projectile_creation_parameters: Array */>? - get() = definedExternally - set(value) = definedExternally -} - -external interface OtherAttackParameters : BaseAttackParameters { - override var type: String /* "beam" */ -} - -external interface CapsuleAction { - var type: String /* "throw" | "equipment-remote" | "use-on-self" */ - var attack_parameters: dynamic /* ProjectileAttackParameters? | StreamAttackParameters? | OtherAttackParameters? */ - get() = definedExternally - set(value) = definedExternally - var equipment: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface SelectionModeFlags { - @nativeGetter - operator fun get(key: String): Boolean? - @nativeSetter - operator fun set(key: String, value: Boolean?) - var blueprint: Boolean? - get() = definedExternally - set(value) = definedExternally - var deconstruct: Boolean? - get() = definedExternally - set(value) = definedExternally - var items: Boolean? - get() = definedExternally - set(value) = definedExternally - var trees: Boolean? - get() = definedExternally - set(value) = definedExternally - var nothing: Boolean? - get() = definedExternally - set(value) = definedExternally - var friend: Boolean? - get() = definedExternally - set(value) = definedExternally - var enemy: Boolean? - get() = definedExternally - set(value) = definedExternally - var upgrade: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface LogisticFilter { - var index: uint - var name: String - var count: uint -} - -external interface ModSetting { - var value: dynamic /* uint | double | Boolean | String */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ProgrammableSpeakerParameters { - var playback_volume: double - var playback_globally: Boolean - var allow_polyphony: Boolean -} - -external interface ProgrammableSpeakerAlertParameters { - var show_alert: Boolean - var show_on_map: Boolean - var icon_signal_id: SignalID - var alert_message: String -} - -external interface ProgrammableSpeakerCircuitParameters { - var signal_value_is_pitch: Boolean - var instrument_id: uint - var note_id: uint -} - -external interface ProgrammableSpeakerInstrument { - var name: String - var notes: Array -} - -external interface EventData { - var name: uint /* uint & `T$93` */ - var tick: uint - var mod_name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface NthTickEventData { - var tick: uint - var nth_tick: uint -} - -external interface ModChangeData { - var old_version: String? - var new_version: String? -} - -external interface ConfigurationChangedData { - var old_version: String? - get() = definedExternally - set(value) = definedExternally - var new_version: String? - get() = definedExternally - set(value) = definedExternally - var mod_changes: Record - var mod_startup_settings_changed: Boolean - var migration_applied: Boolean -} - -external interface CustomCommandData { - var name: String - var tick: uint - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var parameter: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface SelectedPrototypeData { - var base_type: String - var derived_type: String - var name: String -} - -external interface ScriptRenderTarget { - var entity: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var entity_offset: dynamic /* typealias Vector = dynamic */ - get() = definedExternally - set(value) = definedExternally - var position: Position? - get() = definedExternally - set(value) = definedExternally -} - -typealias MouseButtonFlagsTable = Any - -typealias MouseButtonFlagsArray = Array - -external interface ItemStackLocation { - var inventory: inventory - var slot: uint -} - -external interface VehicleAutomaticTargetingParameters { - var auto_target_without_gunner: Boolean - var auto_target_with_gunner: Boolean -} - -external interface BaseItemPrototypeFilter { - var filter: String /* "tool" | "mergeable" | "item-with-inventory" | "selection-tool" | "item-with-label" | "has-rocket-launch-products" | "fuel" | "place-result" | "burnt-result" | "place-as-tile" | "placed-as-equipment-result" | "name" | "type" | "flag" | "subgroup" | "fuel-category" | "stack-size" | "default-request-amount" | "wire-count" | "fuel-value" | "fuel-acceleration-multiplier" | "fuel-top-speed-multiplier" | "fuel-emissions-multiplier" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface PlaceResultItemPrototypeFilter : BaseItemPrototypeFilter { - override var filter: String /* "place-result" */ - var elem_filters: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface BurntResultItemPrototypeFilter : BaseItemPrototypeFilter { - override var filter: String /* "burnt-result" */ - var elem_filters: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface PlaceAsTileItemPrototypeFilter : BaseItemPrototypeFilter { - override var filter: String /* "place-as-tile" */ - var elem_filters: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface PlacedAsEquipmentResultItemPrototypeFilter : BaseItemPrototypeFilter { - override var filter: String /* "placed-as-equipment-result" */ - var elem_filters: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface NameItemPrototypeFilter : BaseItemPrototypeFilter { - override var filter: String /* "name" */ - var name: dynamic /* String | Array */ - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeItemPrototypeFilter : BaseItemPrototypeFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface FlagItemPrototypeFilter : BaseItemPrototypeFilter { - override var filter: String /* "flag" */ - var flag: String -} - -external interface SubgroupItemPrototypeFilter : BaseItemPrototypeFilter { - override var filter: String /* "subgroup" */ - var subgroup: String -} - -external interface FuelCategoryItemPrototypeFilter : BaseItemPrototypeFilter { - @nativeGetter - operator fun get(key: String): String? - @nativeSetter - operator fun set(key: String, value: String) - override var filter: String /* "fuel-category" */ -} - -external interface StackSizeItemPrototypeFilter : BaseItemPrototypeFilter { - override var filter: String /* "stack-size" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: uint -} - -external interface DefaultRequestAmountItemPrototypeFilter : BaseItemPrototypeFilter { - override var filter: String /* "default-request-amount" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: uint -} - -external interface WireCountItemPrototypeFilter : BaseItemPrototypeFilter { - override var filter: String /* "wire-count" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: uint -} - -external interface FuelValueItemPrototypeFilter : BaseItemPrototypeFilter { - override var filter: String /* "fuel-value" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface FuelAccelerationMultiplierItemPrototypeFilter : BaseItemPrototypeFilter { - override var filter: String /* "fuel-acceleration-multiplier" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface FuelTopSpeedMultiplierItemPrototypeFilter : BaseItemPrototypeFilter { - override var filter: String /* "fuel-top-speed-multiplier" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface FuelEmissionsMultiplierItemPrototypeFilter : BaseItemPrototypeFilter { - override var filter: String /* "fuel-emissions-multiplier" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface OtherItemPrototypeFilter : BaseItemPrototypeFilter { - override var filter: String /* "tool" | "mergeable" | "item-with-inventory" | "selection-tool" | "item-with-label" | "has-rocket-launch-products" | "fuel" */ -} - -external interface BaseModSettingPrototypeFilter { - var filter: String /* "type" | "mod" | "setting-type" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeModSettingPrototypeFilter : BaseModSettingPrototypeFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface ModModSettingPrototypeFilter : BaseModSettingPrototypeFilter { - override var filter: String /* "mod" */ - var mod: String -} - -external interface SettingTypeModSettingPrototypeFilter : BaseModSettingPrototypeFilter { - override var filter: String /* "setting-type" */ - var type: String -} - -external interface BaseTechnologyPrototypeFilter { - var filter: String /* "enabled" | "hidden" | "upgrade" | "visible-when-disabled" | "has-effects" | "has-prerequisites" | "research-unit-ingredient" | "level" | "max-level" | "time" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResearchUnitIngredientTechnologyPrototypeFilter : BaseTechnologyPrototypeFilter { - override var filter: String /* "research-unit-ingredient" */ - var ingredient: String -} - -external interface LevelTechnologyPrototypeFilter : BaseTechnologyPrototypeFilter { - override var filter: String /* "level" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: uint -} - -external interface MaxLevelTechnologyPrototypeFilter : BaseTechnologyPrototypeFilter { - override var filter: String /* "max-level" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: uint -} - -external interface TimeTechnologyPrototypeFilter : BaseTechnologyPrototypeFilter { - override var filter: String /* "time" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: uint -} - -external interface OtherTechnologyPrototypeFilter : BaseTechnologyPrototypeFilter { - override var filter: String /* "enabled" | "hidden" | "upgrade" | "visible-when-disabled" | "has-effects" | "has-prerequisites" */ -} - -external interface BaseDecorativePrototypeFilter { - var filter: String /* "decal" | "autoplace" | "collision-mask" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface CollisionMaskDecorativePrototypeFilter : BaseDecorativePrototypeFilter { - override var filter: String /* "collision-mask" */ - var mask: dynamic /* CollisionMask | CollisionMaskWithFlags */ - get() = definedExternally - set(value) = definedExternally - var mask_mode: String /* "collides" | "layers-equals" */ -} - -external interface OtherDecorativePrototypeFilter : BaseDecorativePrototypeFilter { - override var filter: String /* "decal" | "autoplace" */ -} - -external interface BaseAchievementPrototypeFilter { - var filter: String /* "allowed-without-fight" | "type" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeAchievementPrototypeFilter : BaseAchievementPrototypeFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface OtherAchievementPrototypeFilter : BaseAchievementPrototypeFilter { - override var filter: String /* "allowed-without-fight" */ -} - -external interface BaseFluidPrototypeFilter { - var filter: String /* "hidden" | "name" | "subgroup" | "default-temperature" | "max-temperature" | "heat-capacity" | "fuel-value" | "emissions-multiplier" | "gas-temperature" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface NameFluidPrototypeFilter : BaseFluidPrototypeFilter { - override var filter: String /* "name" */ - var name: dynamic /* String | Array */ - get() = definedExternally - set(value) = definedExternally -} - -external interface SubgroupFluidPrototypeFilter : BaseFluidPrototypeFilter { - override var filter: String /* "subgroup" */ - var subgroup: String -} - -external interface DefaultTemperatureFluidPrototypeFilter : BaseFluidPrototypeFilter { - override var filter: String /* "default-temperature" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface MaxTemperatureFluidPrototypeFilter : BaseFluidPrototypeFilter { - override var filter: String /* "max-temperature" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface HeatCapacityFluidPrototypeFilter : BaseFluidPrototypeFilter { - override var filter: String /* "heat-capacity" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface FuelValueFluidPrototypeFilter : BaseFluidPrototypeFilter { - override var filter: String /* "fuel-value" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface EmissionsMultiplierFluidPrototypeFilter : BaseFluidPrototypeFilter { - override var filter: String /* "emissions-multiplier" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface GasTemperatureFluidPrototypeFilter : BaseFluidPrototypeFilter { - override var filter: String /* "gas-temperature" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface OtherFluidPrototypeFilter : BaseFluidPrototypeFilter { - override var filter: String /* "hidden" */ -} - -external interface BaseEquipmentPrototypeFilter { - var filter: String /* "item-to-place" | "type" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeEquipmentPrototypeFilter : BaseEquipmentPrototypeFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface OtherEquipmentPrototypeFilter : BaseEquipmentPrototypeFilter { - override var filter: String /* "item-to-place" */ -} - -external interface BaseTilePrototypeFilter { - var filter: String /* "minable" | "autoplace" | "blueprintable" | "item-to-place" | "collision-mask" | "walking-speed-modifier" | "vehicle-friction-modifier" | "decorative-removal-probability" | "emissions" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface CollisionMaskTilePrototypeFilter : BaseTilePrototypeFilter { - override var filter: String /* "collision-mask" */ - var mask: dynamic /* CollisionMask | CollisionMaskWithFlags */ - get() = definedExternally - set(value) = definedExternally - var mask_mode: String /* "collides" | "layers-equals" */ -} - -external interface WalkingSpeedModifierTilePrototypeFilter : BaseTilePrototypeFilter { - override var filter: String /* "walking-speed-modifier" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface VehicleFrictionModifierTilePrototypeFilter : BaseTilePrototypeFilter { - override var filter: String /* "vehicle-friction-modifier" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface DecorativeRemovalProbabilityTilePrototypeFilter : BaseTilePrototypeFilter { - override var filter: String /* "decorative-removal-probability" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: float -} - -external interface EmissionsTilePrototypeFilter : BaseTilePrototypeFilter { - override var filter: String /* "emissions" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface OtherTilePrototypeFilter : BaseTilePrototypeFilter { - override var filter: String /* "minable" | "autoplace" | "blueprintable" | "item-to-place" */ -} - -external interface BaseRecipePrototypeFilter { - var filter: String /* "enabled" | "hidden" | "hidden-from-flow-stats" | "hidden-from-player-crafting" | "allow-as-intermediate" | "allow-intermediates" | "allow-decomposition" | "always-show-made-in" | "always-show-products" | "show-amount-in-title" | "has-ingredients" | "has-products" | "has-ingredient-item" | "has-ingredient-fluid" | "has-product-item" | "has-product-fluid" | "subgroup" | "category" | "energy" | "emissions-multiplier" | "request-paste-multiplier" | "overload-multiplier" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface HasIngredientItemRecipePrototypeFilter : BaseRecipePrototypeFilter { - override var filter: String /* "has-ingredient-item" */ - var elem_filters: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface HasIngredientFluidRecipePrototypeFilter : BaseRecipePrototypeFilter { - override var filter: String /* "has-ingredient-fluid" */ - var elem_filters: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface HasProductItemRecipePrototypeFilter : BaseRecipePrototypeFilter { - override var filter: String /* "has-product-item" */ - var elem_filters: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface HasProductFluidRecipePrototypeFilter : BaseRecipePrototypeFilter { - override var filter: String /* "has-product-fluid" */ - var elem_filters: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface SubgroupRecipePrototypeFilter : BaseRecipePrototypeFilter { - override var filter: String /* "subgroup" */ - var subgroup: String -} - -external interface CategoryRecipePrototypeFilter : BaseRecipePrototypeFilter { - override var filter: String /* "category" */ - var category: String -} - -external interface EnergyRecipePrototypeFilter : BaseRecipePrototypeFilter { - override var filter: String /* "energy" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface EmissionsMultiplierRecipePrototypeFilter : BaseRecipePrototypeFilter { - override var filter: String /* "emissions-multiplier" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface RequestPasteMultiplierRecipePrototypeFilter : BaseRecipePrototypeFilter { - override var filter: String /* "request-paste-multiplier" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: uint -} - -external interface OverloadMultiplierRecipePrototypeFilter : BaseRecipePrototypeFilter { - override var filter: String /* "overload-multiplier" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: uint -} - -external interface OtherRecipePrototypeFilter : BaseRecipePrototypeFilter { - override var filter: String /* "enabled" | "hidden" | "hidden-from-flow-stats" | "hidden-from-player-crafting" | "allow-as-intermediate" | "allow-intermediates" | "allow-decomposition" | "always-show-made-in" | "always-show-products" | "show-amount-in-title" | "has-ingredients" | "has-products" */ -} - -external interface BaseEntityPrototypeFilter { - var filter: String /* "flying-robot" | "robot-with-logistics-interface" | "rail" | "ghost" | "explosion" | "vehicle" | "crafting-machine" | "rolling-stock" | "turret" | "transport-belt-connectable" | "wall-connectable" | "buildable" | "placable-in-editor" | "clonable" | "selectable" | "hidden" | "entity-with-health" | "building" | "fast-replaceable" | "uses-direction" | "minable" | "circuit-connectable" | "autoplace" | "blueprintable" | "item-to-place" | "name" | "type" | "collision-mask" | "flag" | "build-base-evolution-requirement" | "selection-priority" | "emissions" | "crafting-category" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface NameEntityPrototypeFilter : BaseEntityPrototypeFilter { - override var filter: String /* "name" */ - var name: dynamic /* String | Array */ - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeEntityPrototypeFilter : BaseEntityPrototypeFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface CollisionMaskEntityPrototypeFilter : BaseEntityPrototypeFilter { - override var filter: String /* "collision-mask" */ - var mask: dynamic /* CollisionMask | CollisionMaskWithFlags */ - get() = definedExternally - set(value) = definedExternally - var mask_mode: String /* "collides" | "layers-equals" */ -} - -external interface FlagEntityPrototypeFilter : BaseEntityPrototypeFilter { - override var filter: String /* "flag" */ - var flag: String -} - -external interface BuildBaseEvolutionRequirementEntityPrototypeFilter : BaseEntityPrototypeFilter { - override var filter: String /* "build-base-evolution-requirement" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface SelectionPriorityEntityPrototypeFilter : BaseEntityPrototypeFilter { - override var filter: String /* "selection-priority" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: uint8 -} - -external interface EmissionsEntityPrototypeFilter : BaseEntityPrototypeFilter { - override var filter: String /* "emissions" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: double -} - -external interface CraftingCategoryEntityPrototypeFilter : BaseEntityPrototypeFilter { - override var filter: String /* "crafting-category" */ - var crafting_category: String -} - -external interface OtherEntityPrototypeFilter : BaseEntityPrototypeFilter { - override var filter: String /* "flying-robot" | "robot-with-logistics-interface" | "rail" | "ghost" | "explosion" | "vehicle" | "crafting-machine" | "rolling-stock" | "turret" | "transport-belt-connectable" | "wall-connectable" | "buildable" | "placable-in-editor" | "clonable" | "selectable" | "hidden" | "entity-with-health" | "building" | "fast-replaceable" | "uses-direction" | "minable" | "circuit-connectable" | "autoplace" | "blueprintable" | "item-to-place" */ -} - -external interface BaseScriptRaisedReviveEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeScriptRaisedReviveEventFilter : BaseScriptRaisedReviveEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NameScriptRaisedReviveEventFilter : BaseScriptRaisedReviveEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypeScriptRaisedReviveEventFilter : BaseScriptRaisedReviveEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNameScriptRaisedReviveEventFilter : BaseScriptRaisedReviveEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OtherScriptRaisedReviveEventFilter : BaseScriptRaisedReviveEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BaseEntityDiedEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeEntityDiedEventFilter : BaseEntityDiedEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NameEntityDiedEventFilter : BaseEntityDiedEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypeEntityDiedEventFilter : BaseEntityDiedEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNameEntityDiedEventFilter : BaseEntityDiedEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OtherEntityDiedEventFilter : BaseEntityDiedEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BaseEntityMarkedForDeconstructionEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeEntityMarkedForDeconstructionEventFilter : BaseEntityMarkedForDeconstructionEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NameEntityMarkedForDeconstructionEventFilter : BaseEntityMarkedForDeconstructionEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypeEntityMarkedForDeconstructionEventFilter : BaseEntityMarkedForDeconstructionEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNameEntityMarkedForDeconstructionEventFilter : BaseEntityMarkedForDeconstructionEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OtherEntityMarkedForDeconstructionEventFilter : BaseEntityMarkedForDeconstructionEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BasePreGhostDeconstructedEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypePreGhostDeconstructedEventFilter : BasePreGhostDeconstructedEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NamePreGhostDeconstructedEventFilter : BasePreGhostDeconstructedEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypePreGhostDeconstructedEventFilter : BasePreGhostDeconstructedEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNamePreGhostDeconstructedEventFilter : BasePreGhostDeconstructedEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OtherPreGhostDeconstructedEventFilter : BasePreGhostDeconstructedEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BaseScriptRaisedDestroyEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeScriptRaisedDestroyEventFilter : BaseScriptRaisedDestroyEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NameScriptRaisedDestroyEventFilter : BaseScriptRaisedDestroyEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypeScriptRaisedDestroyEventFilter : BaseScriptRaisedDestroyEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNameScriptRaisedDestroyEventFilter : BaseScriptRaisedDestroyEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OtherScriptRaisedDestroyEventFilter : BaseScriptRaisedDestroyEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BaseUpgradeCancelledEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeUpgradeCancelledEventFilter : BaseUpgradeCancelledEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NameUpgradeCancelledEventFilter : BaseUpgradeCancelledEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypeUpgradeCancelledEventFilter : BaseUpgradeCancelledEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNameUpgradeCancelledEventFilter : BaseUpgradeCancelledEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OtherUpgradeCancelledEventFilter : BaseUpgradeCancelledEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BasePlayerRepairedEntityEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypePlayerRepairedEntityEventFilter : BasePlayerRepairedEntityEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NamePlayerRepairedEntityEventFilter : BasePlayerRepairedEntityEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypePlayerRepairedEntityEventFilter : BasePlayerRepairedEntityEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNamePlayerRepairedEntityEventFilter : BasePlayerRepairedEntityEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OtherPlayerRepairedEntityEventFilter : BasePlayerRepairedEntityEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BaseEntityMarkedForUpgradeEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeEntityMarkedForUpgradeEventFilter : BaseEntityMarkedForUpgradeEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NameEntityMarkedForUpgradeEventFilter : BaseEntityMarkedForUpgradeEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypeEntityMarkedForUpgradeEventFilter : BaseEntityMarkedForUpgradeEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNameEntityMarkedForUpgradeEventFilter : BaseEntityMarkedForUpgradeEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OtherEntityMarkedForUpgradeEventFilter : BaseEntityMarkedForUpgradeEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BasePostEntityDiedEventFilter { - var filter: String /* "type" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypePostEntityDiedEventFilter : BasePostEntityDiedEventFilter { - override var filter: String /* "type" */ - var type: String -} - -typealias LuaPostEntityDiedEventFilter = TypePostEntityDiedEventFilter - -external interface BasePreRobotMinedEntityEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypePreRobotMinedEntityEventFilter : BasePreRobotMinedEntityEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NamePreRobotMinedEntityEventFilter : BasePreRobotMinedEntityEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypePreRobotMinedEntityEventFilter : BasePreRobotMinedEntityEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNamePreRobotMinedEntityEventFilter : BasePreRobotMinedEntityEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OtherPreRobotMinedEntityEventFilter : BasePreRobotMinedEntityEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BaseEntityClonedEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeEntityClonedEventFilter : BaseEntityClonedEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NameEntityClonedEventFilter : BaseEntityClonedEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypeEntityClonedEventFilter : BaseEntityClonedEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNameEntityClonedEventFilter : BaseEntityClonedEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OtherEntityClonedEventFilter : BaseEntityClonedEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BaseScriptRaisedBuiltEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeScriptRaisedBuiltEventFilter : BaseScriptRaisedBuiltEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NameScriptRaisedBuiltEventFilter : BaseScriptRaisedBuiltEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypeScriptRaisedBuiltEventFilter : BaseScriptRaisedBuiltEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNameScriptRaisedBuiltEventFilter : BaseScriptRaisedBuiltEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OtherScriptRaisedBuiltEventFilter : BaseScriptRaisedBuiltEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BaseRobotMinedEntityEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeRobotMinedEntityEventFilter : BaseRobotMinedEntityEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NameRobotMinedEntityEventFilter : BaseRobotMinedEntityEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypeRobotMinedEntityEventFilter : BaseRobotMinedEntityEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNameRobotMinedEntityEventFilter : BaseRobotMinedEntityEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OtherRobotMinedEntityEventFilter : BaseRobotMinedEntityEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BasePrePlayerMinedEntityEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypePrePlayerMinedEntityEventFilter : BasePrePlayerMinedEntityEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NamePrePlayerMinedEntityEventFilter : BasePrePlayerMinedEntityEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypePrePlayerMinedEntityEventFilter : BasePrePlayerMinedEntityEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNamePrePlayerMinedEntityEventFilter : BasePrePlayerMinedEntityEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OtherPrePlayerMinedEntityEventFilter : BasePrePlayerMinedEntityEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BaseRobotBuiltEntityEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" | "force" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeRobotBuiltEntityEventFilter : BaseRobotBuiltEntityEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NameRobotBuiltEntityEventFilter : BaseRobotBuiltEntityEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypeRobotBuiltEntityEventFilter : BaseRobotBuiltEntityEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNameRobotBuiltEntityEventFilter : BaseRobotBuiltEntityEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface ForceRobotBuiltEntityEventFilter : BaseRobotBuiltEntityEventFilter { - override var filter: String /* "force" */ - var force: String -} - -external interface OtherRobotBuiltEntityEventFilter : BaseRobotBuiltEntityEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BaseEntityDeconstructionCancelledEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeEntityDeconstructionCancelledEventFilter : BaseEntityDeconstructionCancelledEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NameEntityDeconstructionCancelledEventFilter : BaseEntityDeconstructionCancelledEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypeEntityDeconstructionCancelledEventFilter : BaseEntityDeconstructionCancelledEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNameEntityDeconstructionCancelledEventFilter : BaseEntityDeconstructionCancelledEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OtherEntityDeconstructionCancelledEventFilter : BaseEntityDeconstructionCancelledEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BasePlayerBuiltEntityEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" | "force" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypePlayerBuiltEntityEventFilter : BasePlayerBuiltEntityEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NamePlayerBuiltEntityEventFilter : BasePlayerBuiltEntityEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypePlayerBuiltEntityEventFilter : BasePlayerBuiltEntityEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNamePlayerBuiltEntityEventFilter : BasePlayerBuiltEntityEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface ForcePlayerBuiltEntityEventFilter : BasePlayerBuiltEntityEventFilter { - override var filter: String /* "force" */ - var force: String -} - -external interface OtherPlayerBuiltEntityEventFilter : BasePlayerBuiltEntityEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BasePlayerMinedEntityEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypePlayerMinedEntityEventFilter : BasePlayerMinedEntityEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NamePlayerMinedEntityEventFilter : BasePlayerMinedEntityEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypePlayerMinedEntityEventFilter : BasePlayerMinedEntityEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNamePlayerMinedEntityEventFilter : BasePlayerMinedEntityEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OtherPlayerMinedEntityEventFilter : BasePlayerMinedEntityEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BaseEntityDamagedEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" | "original-damage-amount" | "final-damage-amount" | "damage-type" | "final-health" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeEntityDamagedEventFilter : BaseEntityDamagedEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NameEntityDamagedEventFilter : BaseEntityDamagedEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypeEntityDamagedEventFilter : BaseEntityDamagedEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNameEntityDamagedEventFilter : BaseEntityDamagedEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OriginalDamageAmountEntityDamagedEventFilter : BaseEntityDamagedEventFilter { - override var filter: String /* "original-damage-amount" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: float -} - -external interface FinalDamageAmountEntityDamagedEventFilter : BaseEntityDamagedEventFilter { - override var filter: String /* "final-damage-amount" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: float -} - -external interface DamageTypeEntityDamagedEventFilter : BaseEntityDamagedEventFilter { - override var filter: String /* "damage-type" */ - var type: String -} - -external interface FinalHealthEntityDamagedEventFilter : BaseEntityDamagedEventFilter { - override var filter: String /* "final-health" */ - var comparison: String /* "=" | ">" | "<" | "≥" | ">=" | "≤" | "<=" | "≠" | "!=" */ - var value: float -} - -external interface OtherEntityDamagedEventFilter : BaseEntityDamagedEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface BaseSectorScannedEventFilter { - var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" | "type" | "name" | "ghost_type" | "ghost_name" */ - var mode: String? /* "or" | "and" */ - get() = definedExternally - set(value) = definedExternally - var invert: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeSectorScannedEventFilter : BaseSectorScannedEventFilter { - override var filter: String /* "type" */ - var type: String -} - -external interface NameSectorScannedEventFilter : BaseSectorScannedEventFilter { - override var filter: String /* "name" */ - var name: String -} - -external interface GhostTypeSectorScannedEventFilter : BaseSectorScannedEventFilter { - override var filter: String /* "ghost_type" */ - var type: String -} - -external interface GhostNameSectorScannedEventFilter : BaseSectorScannedEventFilter { - override var filter: String /* "ghost_name" */ - var name: String -} - -external interface OtherSectorScannedEventFilter : BaseSectorScannedEventFilter { - override var filter: String /* "ghost" | "rail" | "rail-signal" | "rolling-stock" | "robot-with-logistics-interface" | "vehicle" | "turret" | "crafting-machine" | "wall-connectable" | "transport-belt-connectable" | "circuit-network-connectable" */ -} - -external interface `T$87` { - var enabled: Boolean? - get() = definedExternally - set(value) = definedExternally - var diffusion_ratio: double? - get() = definedExternally - set(value) = definedExternally - var ageing: double? - get() = definedExternally - set(value) = definedExternally - var enemy_attack_pollution_consumption_modifier: double? - get() = definedExternally - set(value) = definedExternally - var min_pollution_to_damage_trees: double? - get() = definedExternally - set(value) = definedExternally - var pollution_restored_per_tree_damage: double? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$88` { - var enabled: Boolean? - get() = definedExternally - set(value) = definedExternally - var time_factor: double? - get() = definedExternally - set(value) = definedExternally - var destroy_factor: double? - get() = definedExternally - set(value) = definedExternally - var pollution_factor: double? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$89` { - var enabled: Boolean? - get() = definedExternally - set(value) = definedExternally - var max_expansion_distance: double? - get() = definedExternally - set(value) = definedExternally - var settler_group_min_size: double? - get() = definedExternally - set(value) = definedExternally - var settler_group_max_size: double? - get() = definedExternally - set(value) = definedExternally - var min_expansion_cooldown: double? - get() = definedExternally - set(value) = definedExternally - var max_expansion_cooldown: double? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$90` { - var recipe_difficulty: recipe_difficulty? - get() = definedExternally - set(value) = definedExternally - var technology_difficulty: technology_difficulty? - get() = definedExternally - set(value) = definedExternally - var technology_price_multiplier: double? - get() = definedExternally - set(value) = definedExternally - var research_queue_setting: String? /* "after-victory" | "always" | "never" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$91` { - var pollution: `T$87`? - get() = definedExternally - set(value) = definedExternally - var enemy_evolution: `T$88`? - get() = definedExternally - set(value) = definedExternally - var enemy_expansion: `T$89`? - get() = definedExternally - set(value) = definedExternally - var difficulty_settings: `T$90`? - get() = definedExternally - set(value) = definedExternally -} - -external interface MapGenPreset { - var order: String - var default: Boolean? - get() = definedExternally - set(value) = definedExternally - var basic_settings: MapGenSettingsPartial - var advanced_settings: `T$91` -} - -external interface BlueprintControlBehavior { - var condition: CircuitCondition? - get() = definedExternally - set(value) = definedExternally - var circuit_condition: CircuitCondition? - get() = definedExternally - set(value) = definedExternally - var filters: Array? - get() = definedExternally - set(value) = definedExternally - var is_on: Boolean? - get() = definedExternally - set(value) = definedExternally - var arithmetic_conditions: ArithmeticCombinatorParameters? - get() = definedExternally - set(value) = definedExternally - var decider_conditions: DeciderCombinatorParameters? - get() = definedExternally - set(value) = definedExternally - var circuit_enable_disable: Boolean? - get() = definedExternally - set(value) = definedExternally - var circuit_read_resources: Boolean? - get() = definedExternally - set(value) = definedExternally - var circuit_resource_read_mode: resource_read_mode? - get() = definedExternally - set(value) = definedExternally - var read_stopped_train: Boolean? - get() = definedExternally - set(value) = definedExternally - var train_stopped_signal: SignalID? - get() = definedExternally - set(value) = definedExternally - var read_from_train: Boolean? - get() = definedExternally - set(value) = definedExternally - var send_to_train: Boolean? - get() = definedExternally - set(value) = definedExternally - var circuit_mode_of_operation: Number? - get() = definedExternally - set(value) = definedExternally - var circuit_read_hand_contents: Boolean? - get() = definedExternally - set(value) = definedExternally - var circuit_hand_read_mode: hand_read_mode? - get() = definedExternally - set(value) = definedExternally - var circuit_set_stack_size: Boolean? - get() = definedExternally - set(value) = definedExternally - var stack_control_input_signal: SignalID? - get() = definedExternally - set(value) = definedExternally - var use_colors: Boolean? - get() = definedExternally - set(value) = definedExternally - var read_robot_stats: Boolean? - get() = definedExternally - set(value) = definedExternally - var read_logistics: Boolean? - get() = definedExternally - set(value) = definedExternally - var available_logistic_output_signal: Boolean? - get() = definedExternally - set(value) = definedExternally - var total_logistic_output_signal: Boolean? - get() = definedExternally - set(value) = definedExternally - var available_construction_output_signal: Boolean? - get() = definedExternally - set(value) = definedExternally - var total_construction_output_signal: Boolean? - get() = definedExternally - set(value) = definedExternally - var circuit_contents_read_mode: content_read_mode? - get() = definedExternally - set(value) = definedExternally - var output_signal: SignalID? - get() = definedExternally - set(value) = definedExternally - var circuit_close_signal: Boolean? - get() = definedExternally - set(value) = definedExternally - var circuit_read_signal: Boolean? - get() = definedExternally - set(value) = definedExternally - var red_output_signal: SignalID? - get() = definedExternally - set(value) = definedExternally - var orange_output_signal: SignalID? - get() = definedExternally - set(value) = definedExternally - var green_output_signal: SignalID? - get() = definedExternally - set(value) = definedExternally - var blue_output_signal: SignalID? - get() = definedExternally - set(value) = definedExternally - var circuit_open_gate: Boolean? - get() = definedExternally - set(value) = definedExternally - var circuit_read_sensor: Boolean? - get() = definedExternally - set(value) = definedExternally - var circuit_parameters: ProgrammableSpeakerCircuitParameters? - get() = definedExternally - set(value) = definedExternally -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/coroutine/coroutine.coroutine.module_lua-types.kt b/modules/mod2/dukat-custom/coroutine/coroutine.coroutine.module_lua-types.kt deleted file mode 100644 index 2228c85..0000000 --- a/modules/mod2/dukat-custom/coroutine/coroutine.coroutine.module_lua-types.kt +++ /dev/null @@ -1,30 +0,0 @@ -@file:JsQualifier("coroutine") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package coroutine - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import LuaThread - -external fun create(f: (args: Any) -> Any): LuaThread - -external fun resume(co: LuaThread, vararg param_val: Any): dynamic /* JsTuple | JsTuple */ - -external fun status(co: LuaThread): String /* "running" | "suspended" | "normal" | "dead" */ - -external fun wrap(f: (args: Any) -> Any): (args: Any) -> Array - -external fun yield(vararg args: Any): Array /* Array & LuaExtension */ - -external fun running(): dynamic /* JsTuple */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/debug/debug.debug.module_lua-types.kt b/modules/mod2/dukat-custom/debug/debug.debug.module_lua-types.kt deleted file mode 100644 index fd5215e..0000000 --- a/modules/mod2/dukat-custom/debug/debug.debug.module_lua-types.kt +++ /dev/null @@ -1,162 +0,0 @@ -@file:JsQualifier("debug") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package debug - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import LuaThread -import LuaMetatable__1 -import tsstdlib.Record -import LuaUserdata -import LuaMetatable - -external fun debug() - -external fun gethook(thread: LuaThread = definedExternally): dynamic /* JsTuple | JsTuple, Number, Any> */ - -external interface FunctionInfo> { - var nparams: Number - var isvararg: Boolean? - var istailcall: Boolean? - var func: T - var name: String? - get() = definedExternally - set(value) = definedExternally - var namewhat: String /* "global" | "local" | "method" | "field" | "" */ - var source: String - var short_src: String - var linedefined: Number - var lastlinedefined: Number - var what: String /* "Lua" | "C" | "main" */ - var currentline: Number - var nups: Number -} - -external interface FunctionInfoPartial> { - var nparams: Number? - get() = definedExternally - set(value) = definedExternally - var isvararg: Boolean? - get() = definedExternally - set(value) = definedExternally - var istailcall: Boolean? - get() = definedExternally - set(value) = definedExternally - var func: T? - get() = definedExternally - set(value) = definedExternally - var name: String? - get() = definedExternally - set(value) = definedExternally - var namewhat: String? /* "global" | "local" | "method" | "field" | "" */ - get() = definedExternally - set(value) = definedExternally - var source: String? - get() = definedExternally - set(value) = definedExternally - var short_src: String? - get() = definedExternally - set(value) = definedExternally - var linedefined: Number? - get() = definedExternally - set(value) = definedExternally - var lastlinedefined: Number? - get() = definedExternally - set(value) = definedExternally - var what: String? /* "Lua" | "C" | "main" */ - get() = definedExternally - set(value) = definedExternally - var currentline: Number? - get() = definedExternally - set(value) = definedExternally - var nups: Number? - get() = definedExternally - set(value) = definedExternally -} - -external interface FunctionInfo__0 : FunctionInfo> - -external interface FunctionInfo__0Partial : FunctionInfoPartial> - -external fun > getinfo(f: T): FunctionInfo - -external fun > getinfo(f: T, what: String): FunctionInfoPartial - -external fun > getinfo(thread: LuaThread, f: T): FunctionInfo - -external fun > getinfo(thread: LuaThread, f: T, what: String): FunctionInfoPartial - -external fun getinfo(f: Number): FunctionInfo__0? - -external fun getinfo(f: Number, what: String): FunctionInfo__0Partial? - -external fun getinfo(thread: LuaThread, f: Number): FunctionInfo__0? - -external fun getinfo(thread: LuaThread, f: Number, what: String): FunctionInfo__0Partial? - -external fun getmetatable(value: T): LuaMetatable__1? - -external fun getregistry(): Record - -external fun getupvalue(f: Function<*>, up: Number): dynamic /* JsTuple | JsTuple<> */ - -external fun getuservalue(u: LuaUserdata): Any - -external fun sethook() - -external fun sethook(hook: (event: String /* "call" | "return" | "line" | "count" */, line: Number) -> Any, mask: String, count: Number = definedExternally) - -external fun sethook(hook: (event: String /* "call" | "return" | "line" | "count" */, line: Number) -> Any, mask: String) - -external fun sethook(thread: LuaThread, hook: (event: String /* "call" | "return" | "line" | "count" */, line: Number) -> Any, mask: String, count: Number = definedExternally) - -external fun sethook(thread: LuaThread, hook: (event: String /* "call" | "return" | "line" | "count" */, line: Number) -> Any, mask: String) - -external fun setlocal(level: Number, local: Number, value: Any): String? - -external fun setlocal(thread: LuaThread, level: Number, local: Number, value: Any): String? - -external fun setmetatable(value: T, table: LuaMetatable? = definedExternally): Any - -external fun setupvalue(f: Function<*>, up: Number, value: Any): String? - -external fun setuservalue(udata: LuaUserdata, value: Any): LuaUserdata - -external fun traceback(message: String? = definedExternally, level: Number? = definedExternally): String - -external fun traceback(): String - -external fun traceback(message: String? = definedExternally): String - -external fun traceback(thread: LuaThread = definedExternally, message: String? = definedExternally, level: Number? = definedExternally): String - -external fun traceback(thread: LuaThread = definedExternally): String - -external fun traceback(thread: LuaThread = definedExternally, message: String? = definedExternally): String - -external fun traceback(message: T): T - -external fun traceback(thread: LuaThread, message: T): T - -external fun getlocal(f: Function<*>, local: Number): dynamic /* JsTuple */ - -external fun getlocal(f: Number, local: Number): dynamic /* JsTuple */ - -external fun getlocal(thread: LuaThread, f: Function<*>, local: Number): dynamic /* JsTuple */ - -external fun getlocal(thread: LuaThread, f: Number, local: Number): dynamic /* JsTuple */ - -external fun upvalueid(f: Function<*>, n: Number): LuaUserdata - -external fun upvaluejoin(f1: Function<*>, n1: Number, f2: Function<*>, n2: Number) \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines/control_behavior/defines.defines.control_behavior.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/control_behavior/defines.defines.control_behavior.module_typed-factorio.kt deleted file mode 100644 index 4c0ec5b..0000000 --- a/modules/mod2/dukat-custom/defines/control_behavior/defines.defines.control_behavior.module_typed-factorio.kt +++ /dev/null @@ -1,38 +0,0 @@ -@file:JsQualifier("defines.control_behavior") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package defines.control_behavior - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external enum class type { - container, - generic_on_off, - inserter, - lamp, - logistic_container, - roboport, - storage_tank, - train_stop, - decider_combinator, - arithmetic_combinator, - constant_combinator, - transport_belt, - accumulator, - rail_signal, - rail_chain_signal, - wall, - mining_drill, - programmable_speaker -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines/control_behavior/inserter/defines.defines.control_behavior.inserter.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/control_behavior/inserter/defines.defines.control_behavior.inserter.module_typed-factorio.kt deleted file mode 100644 index 9a91be8..0000000 --- a/modules/mod2/dukat-custom/defines/control_behavior/inserter/defines.defines.control_behavior.inserter.module_typed-factorio.kt +++ /dev/null @@ -1,30 +0,0 @@ -@file:JsQualifier("defines.control_behavior.inserter") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package defines.control_behavior.inserter - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external enum class circuit_mode_of_operation { - none, - enable_disable, - set_filters, - read_hand_contents, - set_stack_size -} - -external enum class hand_read_mode { - hold, - pulse -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines/control_behavior/lamp/defines.defines.control_behavior.lamp.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/control_behavior/lamp/defines.defines.control_behavior.lamp.module_typed-factorio.kt deleted file mode 100644 index 4688694..0000000 --- a/modules/mod2/dukat-custom/defines/control_behavior/lamp/defines.defines.control_behavior.lamp.module_typed-factorio.kt +++ /dev/null @@ -1,21 +0,0 @@ -@file:JsQualifier("defines.control_behavior.lamp") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package defines.control_behavior.lamp - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external enum class circuit_mode_of_operation { - use_colors -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines/control_behavior/logistic_container/defines.defines.control_behavior.logistic_container.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/control_behavior/logistic_container/defines.defines.control_behavior.logistic_container.module_typed-factorio.kt deleted file mode 100644 index e9a2d7a..0000000 --- a/modules/mod2/dukat-custom/defines/control_behavior/logistic_container/defines.defines.control_behavior.logistic_container.module_typed-factorio.kt +++ /dev/null @@ -1,22 +0,0 @@ -@file:JsQualifier("defines.control_behavior.logistic_container") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package defines.control_behavior.logistic_container - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external enum class circuit_mode_of_operation { - send_contents, - set_requests -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines/control_behavior/mining_drill/defines.defines.control_behavior.mining_drill.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/control_behavior/mining_drill/defines.defines.control_behavior.mining_drill.module_typed-factorio.kt deleted file mode 100644 index 86c2231..0000000 --- a/modules/mod2/dukat-custom/defines/control_behavior/mining_drill/defines.defines.control_behavior.mining_drill.module_typed-factorio.kt +++ /dev/null @@ -1,22 +0,0 @@ -@file:JsQualifier("defines.control_behavior.mining_drill") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package defines.control_behavior.mining_drill - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external enum class resource_read_mode { - this_miner, - entire_patch -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines/control_behavior/transport_belt/defines.defines.control_behavior.transport_belt.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/control_behavior/transport_belt/defines.defines.control_behavior.transport_belt.module_typed-factorio.kt deleted file mode 100644 index c78e4e7..0000000 --- a/modules/mod2/dukat-custom/defines/control_behavior/transport_belt/defines.defines.control_behavior.transport_belt.module_typed-factorio.kt +++ /dev/null @@ -1,22 +0,0 @@ -@file:JsQualifier("defines.control_behavior.transport_belt") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package defines.control_behavior.transport_belt - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external enum class content_read_mode { - pulse, - hold -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines/deconstruction_item/defines.defines.deconstruction_item.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/deconstruction_item/defines.defines.deconstruction_item.module_typed-factorio.kt deleted file mode 100644 index 26ee0cc..0000000 --- a/modules/mod2/dukat-custom/defines/deconstruction_item/defines.defines.deconstruction_item.module_typed-factorio.kt +++ /dev/null @@ -1,34 +0,0 @@ -@file:JsQualifier("defines.deconstruction_item") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package defines.deconstruction_item - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external enum class entity_filter_mode { - whitelist, - blacklist -} - -external enum class tile_filter_mode { - whitelist, - blacklist -} - -external enum class tile_selection_mode { - normal, - always, - never, - only -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines/defines.defines.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/defines.defines.module_typed-factorio.kt deleted file mode 100644 index 0c4e085..0000000 --- a/modules/mod2/dukat-custom/defines/defines.defines.module_typed-factorio.kt +++ /dev/null @@ -1,668 +0,0 @@ -@file:JsQualifier("defines") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package defines - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external enum class alert_type { - entity_destroyed, - entity_under_attack, - not_enough_construction_robots, - no_material_for_construction, - not_enough_repair_packs, - turret_fire, - custom, - no_storage, - train_out_of_fuel -} - -external enum class behavior_result { - in_progress, - fail, - success, - deleted -} - -external enum class build_check_type { - script, - manual, - manual_ghost, - script_ghost, - blueprint_ghost, - ghost_revive -} - -external enum class chain_signal_state { - none, - all_open, - partially_open, - none_open -} - -external enum class chunk_generated_status { - nothing, - custom_tiles, - basic_tiles, - corrected_tiles, - tiles, - entities -} - -external enum class circuit_condition_index { - inserter_circuit, - inserter_logistic, - lamp, - arithmetic_combinator, - decider_combinator, - constant_combinator, - offshore_pump, - pump -} - -external enum class circuit_connector_id { - accumulator, - constant_combinator, - container, - programmable_speaker, - rail_signal, - rail_chain_signal, - roboport, - storage_tank, - wall, - electric_pole, - inserter, - lamp, - combinator_input, - combinator_output, - offshore_pump, - pump -} - -external enum class command { - attack /* = 0 */, - go_to_location /* = 1 */, - compound /* = 2 */, - group /* = 3 */, - attack_area /* = 4 */, - wander /* = 5 */, - flee /* = 6 */, - stop /* = 7 */, - build_base /* = 8 */ -} - -external enum class compound_command { - logical_and, - logical_or, - return_last -} - -external enum class controllers { - ghost, - character, - god, - editor, - cutscene, - spectator -} - -external enum class difficulty { - easy, - normal, - hard -} - -external enum class direction { - north /* = 0 */, - northeast /* = 1 */, - east /* = 2 */, - southeast /* = 3 */, - south /* = 4 */, - southwest /* = 5 */, - west /* = 6 */, - northwest /* = 7 */ -} - -external enum class disconnect_reason { - quit, - dropped, - reconnect, - wrong_input, - desync_limit_reached, - cannot_keep_up, - afk, - kicked, - kicked_and_deleted, - banned, - switching_servers -} - -external enum class distraction { - none, - by_enemy, - by_anything, - by_damage -} - -external enum class entity_status { - working, - normal, - no_power, - low_power, - no_fuel, - disabled_by_control_behavior, - opened_by_circuit_network, - closed_by_circuit_network, - disabled_by_script, - marked_for_deconstruction, - not_plugged_in_electric_network, - networks_connected, - networks_disconnected, - charging, - discharging, - fully_charged, - out_of_logistic_network, - no_recipe, - no_ingredients, - no_input_fluid, - no_research_in_progress, - no_minable_resources, - low_input_fluid, - fluid_ingredient_shortage, - full_output, - item_ingredient_shortage, - missing_required_fluid, - missing_science_packs, - waiting_for_source_items, - waiting_for_space_in_destination, - preparing_rocket_for_launch, - waiting_to_launch_rocket, - launching_rocket, - no_modules_to_transmit, - recharging_after_power_outage, - waiting_for_target_to_be_built, - waiting_for_train, - no_ammo, - low_temperature, - disabled, - turned_off_during_daytime, - not_connected_to_rail, - cant_divide_segments -} - -external enum class flow_precision_index { - five_seconds, - one_minute, - ten_minutes, - one_hour, - ten_hours, - fifty_hours, - two_hundred_fifty_hours, - one_thousand_hours -} - -external enum class group_state { - gathering, - moving, - attacking_distraction, - attacking_target, - finished, - pathfinding, - wander_in_group -} - -external enum class gui_type { - none, - entity, - research, - controller, - production, - item, - bonus, - trains, - achievement, - blueprint_library, - equipment, - logistic, - other_player, - permissions, - tutorials, - custom, - server_management, - player_management, - tile -} - -external enum class input_action { - activate_copy, - activate_cut, - activate_paste, - add_permission_group, - add_train_station, - admin_action, - alt_select_area, - alt_select_blueprint_entities, - alternative_copy, - begin_mining, - begin_mining_terrain, - build, - build_rail, - build_terrain, - cancel_craft, - cancel_deconstruct, - cancel_new_blueprint, - cancel_research, - cancel_upgrade, - change_active_character_tab, - change_active_item_group_for_crafting, - change_active_item_group_for_filters, - change_active_quick_bar, - change_arithmetic_combinator_parameters, - change_decider_combinator_parameters, - change_entity_label, - change_item_description, - change_item_label, - change_multiplayer_config, - change_picking_state, - change_programmable_speaker_alert_parameters, - change_programmable_speaker_circuit_parameters, - change_programmable_speaker_parameters, - change_riding_state, - change_shooting_state, - change_train_stop_station, - change_train_wait_condition, - change_train_wait_condition_data, - clear_cursor, - connect_rolling_stock, - copy, - copy_entity_settings, - copy_opened_blueprint, - copy_opened_item, - craft, - cursor_split, - cursor_transfer, - custom_input, - cycle_blueprint_book_backwards, - cycle_blueprint_book_forwards, - deconstruct, - delete_blueprint_library, - delete_blueprint_record, - delete_custom_tag, - delete_permission_group, - destroy_item, - destroy_opened_item, - disconnect_rolling_stock, - drag_train_schedule, - drag_train_wait_condition, - drop_blueprint_record, - drop_item, - edit_blueprint_tool_preview, - edit_custom_tag, - edit_permission_group, - export_blueprint, - fast_entity_split, - fast_entity_transfer, - flush_opened_entity_fluid, - flush_opened_entity_specific_fluid, - go_to_train_station, - grab_blueprint_record, - gui_checked_state_changed, - gui_click, - gui_confirmed, - gui_elem_changed, - gui_location_changed, - gui_selected_tab_changed, - gui_selection_state_changed, - gui_switch_state_changed, - gui_text_changed, - gui_value_changed, - import_blueprint, - import_blueprint_string, - import_blueprints_filtered, - import_permissions_string, - inventory_split, - inventory_transfer, - launch_rocket, - lua_shortcut, - map_editor_action, - market_offer, - mod_settings_changed, - open_achievements_gui, - open_blueprint_library_gui, - open_blueprint_record, - open_bonus_gui, - open_character_gui, - open_current_vehicle_gui, - open_equipment, - open_gui, - open_item, - open_logistic_gui, - open_mod_item, - open_parent_of_opened_item, - open_production_gui, - open_technology_gui, - open_tips_and_tricks_gui, - open_train_gui, - open_train_station_gui, - open_trains_gui, - paste_entity_settings, - place_equipment, - quick_bar_pick_slot, - quick_bar_set_selected_page, - quick_bar_set_slot, - reassign_blueprint, - remove_cables, - remove_train_station, - reset_assembling_machine, - reset_item, - rotate_entity, - select_area, - select_blueprint_entities, - select_entity_slot, - select_item, - select_mapper_slot, - select_next_valid_gun, - select_tile_slot, - send_spidertron, - set_auto_launch_rocket, - set_autosort_inventory, - set_behavior_mode, - set_car_weapons_control, - set_circuit_condition, - set_circuit_mode_of_operation, - set_controller_logistic_trash_filter_item, - set_deconstruction_item_tile_selection_mode, - set_deconstruction_item_trees_and_rocks_only, - set_entity_color, - set_entity_energy_property, - set_entity_logistic_trash_filter_item, - set_filter, - set_flat_controller_gui, - set_heat_interface_mode, - set_heat_interface_temperature, - set_infinity_container_filter_item, - set_infinity_container_remove_unfiltered_items, - set_infinity_pipe_filter, - set_inserter_max_stack_size, - set_inventory_bar, - set_linked_container_link_i_d, - set_logistic_filter_item, - set_logistic_filter_signal, - set_player_color, - set_recipe_notifications, - set_request_from_buffers, - set_research_finished_stops_game, - set_signal, - set_splitter_priority, - set_train_stopped, - set_trains_limit, - set_vehicle_automatic_targeting_parameters, - setup_assembling_machine, - setup_blueprint, - setup_single_blueprint_record, - smart_pipette, - spawn_item, - stack_split, - stack_transfer, - start_repair, - start_research, - start_walking, - stop_building_by_moving, - switch_connect_to_logistic_network, - switch_constant_combinator_state, - switch_inserter_filter_mode_state, - switch_power_switch_state, - switch_to_rename_stop_gui, - take_equipment, - toggle_deconstruction_item_entity_filter_mode, - toggle_deconstruction_item_tile_filter_mode, - toggle_driving, - toggle_enable_vehicle_logistics_while_moving, - toggle_entity_logistic_requests, - toggle_equipment_movement_bonus, - toggle_map_editor, - toggle_personal_logistic_requests, - toggle_personal_roboport, - toggle_show_entity_info, - translate_string, - undo, - upgrade, - upgrade_opened_blueprint_by_item, - upgrade_opened_blueprint_by_record, - use_artillery_remote, - use_item, - wire_dragging, - write_to_console -} - -external enum class inventory { - fuel, - burnt_result, - chest, - furnace_source, - furnace_result, - furnace_modules, - character_main, - character_guns, - character_ammo, - character_armor, - character_vehicle, - character_trash, - god_main, - editor_main, - editor_guns, - editor_ammo, - editor_armor, - roboport_robot, - roboport_material, - robot_cargo, - robot_repair, - assembling_machine_input, - assembling_machine_output, - assembling_machine_modules, - lab_input, - lab_modules, - mining_drill_modules, - item_main, - rocket_silo_rocket, - rocket_silo_result, - rocket, - car_trunk, - car_ammo, - cargo_wagon, - turret_ammo, - beacon_modules, - character_corpse, - artillery_turret_ammo, - artillery_wagon_ammo, - spider_trunk, - spider_ammo, - spider_trash -} - -external enum class logistic_member_index { - logistic_container, - vehicle_storage, - character_requester, - character_storage, - character_provider, - generic_on_off_behavior -} - -external enum class logistic_mode { - none, - active_provider, - storage, - requester, - passive_provider, - buffer -} - -external enum class mouse_button_type { - none, - left, - right, - middle -} - -external var prototypes: Any - -external enum class rail_connection_direction { - left, - straight, - right, - none -} - -external enum class rail_direction { - front, - back -} - -external enum class relative_gui_position { - top, - bottom, - left, - right -} - -external enum class relative_gui_type { - accumulator_gui, - achievement_gui, - additional_entity_info_gui, - admin_gui, - arithmetic_combinator_gui, - armor_gui, - assembling_machine_gui, - assembling_machine_select_recipe_gui, - beacon_gui, - blueprint_book_gui, - blueprint_library_gui, - blueprint_setup_gui, - bonus_gui, - burner_equipment_gui, - car_gui, - constant_combinator_gui, - container_gui, - controller_gui, - decider_combinator_gui, - deconstruction_item_gui, - electric_energy_interface_gui, - electric_network_gui, - entity_variations_gui, - entity_with_energy_source_gui, - equipment_grid_gui, - furnace_gui, - generic_on_off_entity_gui, - heat_interface_gui, - infinity_pipe_gui, - inserter_gui, - item_with_inventory_gui, - lab_gui, - lamp_gui, - linked_container_gui, - loader_gui, - logistic_gui, - market_gui, - mining_drill_gui, - other_player_gui, - permissions_gui, - pipe_gui, - power_switch_gui, - production_gui, - programmable_speaker_gui, - rail_chain_signal_gui, - rail_signal_gui, - reactor_gui, - rename_stop_gui, - resource_entity_gui, - roboport_gui, - rocket_silo_gui, - server_config_gui, - spider_vehicle_gui, - splitter_gui, - standalone_character_gui, - storage_tank_gui, - tile_variations_gui, - train_gui, - train_stop_gui, - trains_gui, - transport_belt_gui, - upgrade_item_gui, - wall_gui -} - -external enum class render_mode { - game, - chart, - chart_zoomed_in -} - -external enum class rich_text_setting { - enabled, - disabled, - highlight -} - -external enum class shooting { - not_shooting, - shooting_enemies, - shooting_selected -} - -external enum class signal_state { - open, - closed, - reserved, - reserved_by_circuit_network -} - -external enum class train_state { - on_the_path, - path_lost, - no_schedule, - no_path, - arrive_signal, - wait_signal, - arrive_station, - wait_station, - manual_control_stop, - manual_control, - destination_full -} - -external enum class transport_line { - left_line, - right_line, - left_underground_line, - right_underground_line, - secondary_left_line, - secondary_right_line, - left_split_line, - right_split_line, - secondary_left_split_line, - secondary_right_split_line -} - -external enum class wire_connection_id { - electric_pole, - power_switch_left, - power_switch_right -} - -external enum class wire_type { - red, - green, - copper -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines/difficulty_settings/defines.defines.difficulty_settings.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/difficulty_settings/defines.defines.difficulty_settings.module_typed-factorio.kt deleted file mode 100644 index bc978a6..0000000 --- a/modules/mod2/dukat-custom/defines/difficulty_settings/defines.defines.difficulty_settings.module_typed-factorio.kt +++ /dev/null @@ -1,27 +0,0 @@ -@file:JsQualifier("defines.difficulty_settings") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package defines.difficulty_settings - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external enum class recipe_difficulty { - normal, - expensive -} - -external enum class technology_difficulty { - normal, - expensive -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines/events/defines.defines.events.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/events/defines.defines.events.module_typed-factorio.kt deleted file mode 100644 index cccc0aa..0000000 --- a/modules/mod2/dukat-custom/defines/events/defines.defines.events.module_typed-factorio.kt +++ /dev/null @@ -1,366 +0,0 @@ -@file:JsQualifier("defines.events") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package defines.events - -import EventId -import OnTickEvent -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import uint - -external var on_tick: EventId /* uint & `T$93` */ - -external var on_gui_click: uint /* uint & `T$93` */ - -external var on_gui_confirmed: uint /* uint & `T$93` */ - -external var on_gui_text_changed: uint /* uint & `T$93` */ - -external var on_gui_checked_state_changed: uint /* uint & `T$93` */ - -external var on_entity_died: uint /* uint & `T$93` */ - -external var on_post_entity_died: uint /* uint & `T$93` */ - -external var on_entity_damaged: uint /* uint & `T$93` */ - -external var on_picked_up_item: uint /* uint & `T$93` */ - -external var on_built_entity: uint /* uint & `T$93` */ - -external var on_sector_scanned: uint /* uint & `T$93` */ - -external var on_player_mined_item: uint /* uint & `T$93` */ - -external var on_pre_build: uint /* uint & `T$93` */ - -external var on_rocket_launched: uint /* uint & `T$93` */ - -external var on_pre_player_mined_item: uint /* uint & `T$93` */ - -external var on_chunk_generated: uint /* uint & `T$93` */ - -external var on_player_crafted_item: uint /* uint & `T$93` */ - -external var on_robot_built_entity: uint /* uint & `T$93` */ - -external var on_robot_pre_mined: uint /* uint & `T$93` */ - -external var on_robot_mined: uint /* uint & `T$93` */ - -external var on_research_started: uint /* uint & `T$93` */ - -external var on_research_finished: uint /* uint & `T$93` */ - -external var on_research_reversed: uint /* uint & `T$93` */ - -external var on_player_rotated_entity: uint /* uint & `T$93` */ - -external var on_marked_for_deconstruction: uint /* uint & `T$93` */ - -external var on_cancelled_deconstruction: uint /* uint & `T$93` */ - -external var on_trigger_created_entity: uint /* uint & `T$93` */ - -external var on_trigger_fired_artillery: uint /* uint & `T$93` */ - -external var on_train_changed_state: uint /* uint & `T$93` */ - -external var on_player_created: uint /* uint & `T$93` */ - -external var on_resource_depleted: uint /* uint & `T$93` */ - -external var on_player_driving_changed_state: uint /* uint & `T$93` */ - -external var on_force_created: uint /* uint & `T$93` */ - -external var on_forces_merging: uint /* uint & `T$93` */ - -external var on_player_cursor_stack_changed: uint /* uint & `T$93` */ - -external var on_pre_entity_settings_pasted: uint /* uint & `T$93` */ - -external var on_entity_settings_pasted: uint /* uint & `T$93` */ - -external var on_player_main_inventory_changed: uint /* uint & `T$93` */ - -external var on_player_armor_inventory_changed: uint /* uint & `T$93` */ - -external var on_player_ammo_inventory_changed: uint /* uint & `T$93` */ - -external var on_player_gun_inventory_changed: uint /* uint & `T$93` */ - -external var on_player_placed_equipment: uint /* uint & `T$93` */ - -external var on_player_removed_equipment: uint /* uint & `T$93` */ - -external var on_pre_player_died: uint /* uint & `T$93` */ - -external var on_player_died: uint /* uint & `T$93` */ - -external var on_player_respawned: uint /* uint & `T$93` */ - -external var on_player_joined_game: uint /* uint & `T$93` */ - -external var on_player_left_game: uint /* uint & `T$93` */ - -external var on_player_built_tile: uint /* uint & `T$93` */ - -external var on_player_mined_tile: uint /* uint & `T$93` */ - -external var on_robot_built_tile: uint /* uint & `T$93` */ - -external var on_robot_mined_tile: uint /* uint & `T$93` */ - -external var on_player_selected_area: uint /* uint & `T$93` */ - -external var on_player_alt_selected_area: uint /* uint & `T$93` */ - -external var on_player_changed_surface: uint /* uint & `T$93` */ - -external var on_selected_entity_changed: uint /* uint & `T$93` */ - -external var on_market_item_purchased: uint /* uint & `T$93` */ - -external var on_player_dropped_item: uint /* uint & `T$93` */ - -external var on_biter_base_built: uint /* uint & `T$93` */ - -external var on_player_changed_force: uint /* uint & `T$93` */ - -external var on_entity_renamed: uint /* uint & `T$93` */ - -external var on_gui_selection_state_changed: uint /* uint & `T$93` */ - -external var on_runtime_mod_setting_changed: uint /* uint & `T$93` */ - -external var on_difficulty_settings_changed: uint /* uint & `T$93` */ - -external var on_surface_created: uint /* uint & `T$93` */ - -external var on_surface_deleted: uint /* uint & `T$93` */ - -external var on_pre_surface_deleted: uint /* uint & `T$93` */ - -external var on_player_mined_entity: uint /* uint & `T$93` */ - -external var on_robot_mined_entity: uint /* uint & `T$93` */ - -external var on_train_created: uint /* uint & `T$93` */ - -external var on_gui_elem_changed: uint /* uint & `T$93` */ - -external var on_player_setup_blueprint: uint /* uint & `T$93` */ - -external var on_player_deconstructed_area: uint /* uint & `T$93` */ - -external var on_player_configured_blueprint: uint /* uint & `T$93` */ - -external var on_console_chat: uint /* uint & `T$93` */ - -external var on_console_command: uint /* uint & `T$93` */ - -external var on_player_removed: uint /* uint & `T$93` */ - -external var on_pre_player_removed: uint /* uint & `T$93` */ - -external var on_player_used_capsule: uint /* uint & `T$93` */ - -external var script_raised_built: uint /* uint & `T$93` */ - -external var script_raised_destroy: uint /* uint & `T$93` */ - -external var script_raised_revive: uint /* uint & `T$93` */ - -external var script_raised_set_tiles: uint /* uint & `T$93` */ - -external var on_player_promoted: uint /* uint & `T$93` */ - -external var on_player_demoted: uint /* uint & `T$93` */ - -external var on_combat_robot_expired: uint /* uint & `T$93` */ - -external var on_worker_robot_expired: uint /* uint & `T$93` */ - -external var on_player_changed_position: uint /* uint & `T$93` */ - -external var on_mod_item_opened: uint /* uint & `T$93` */ - -external var on_gui_opened: uint /* uint & `T$93` */ - -external var on_gui_closed: uint /* uint & `T$93` */ - -external var on_gui_value_changed: uint /* uint & `T$93` */ - -external var on_player_muted: uint /* uint & `T$93` */ - -external var on_player_unmuted: uint /* uint & `T$93` */ - -external var on_player_cheat_mode_enabled: uint /* uint & `T$93` */ - -external var on_player_cheat_mode_disabled: uint /* uint & `T$93` */ - -external var on_character_corpse_expired: uint /* uint & `T$93` */ - -external var on_pre_ghost_deconstructed: uint /* uint & `T$93` */ - -external var on_player_pipette: uint /* uint & `T$93` */ - -external var on_player_display_resolution_changed: uint /* uint & `T$93` */ - -external var on_player_display_scale_changed: uint /* uint & `T$93` */ - -external var on_pre_player_crafted_item: uint /* uint & `T$93` */ - -external var on_player_cancelled_crafting: uint /* uint & `T$93` */ - -external var on_chunk_charted: uint /* uint & `T$93` */ - -external var on_technology_effects_reset: uint /* uint & `T$93` */ - -external var on_force_reset: uint /* uint & `T$93` */ - -external var on_land_mine_armed: uint /* uint & `T$93` */ - -external var on_forces_merged: uint /* uint & `T$93` */ - -external var on_player_trash_inventory_changed: uint /* uint & `T$93` */ - -external var on_pre_player_left_game: uint /* uint & `T$93` */ - -external var on_pre_surface_cleared: uint /* uint & `T$93` */ - -external var on_surface_cleared: uint /* uint & `T$93` */ - -external var on_chunk_deleted: uint /* uint & `T$93` */ - -external var on_pre_chunk_deleted: uint /* uint & `T$93` */ - -external var on_train_schedule_changed: uint /* uint & `T$93` */ - -external var on_player_banned: uint /* uint & `T$93` */ - -external var on_player_kicked: uint /* uint & `T$93` */ - -external var on_player_unbanned: uint /* uint & `T$93` */ - -external var on_rocket_launch_ordered: uint /* uint & `T$93` */ - -external var on_script_path_request_finished: uint /* uint & `T$93` */ - -external var on_ai_command_completed: uint /* uint & `T$93` */ - -external var on_marked_for_upgrade: uint /* uint & `T$93` */ - -external var on_cancelled_upgrade: uint /* uint & `T$93` */ - -external var on_player_toggled_map_editor: uint /* uint & `T$93` */ - -external var on_entity_cloned: uint /* uint & `T$93` */ - -external var on_area_cloned: uint /* uint & `T$93` */ - -external var on_brush_cloned: uint /* uint & `T$93` */ - -external var on_game_created_from_scenario: uint /* uint & `T$93` */ - -external var on_surface_imported: uint /* uint & `T$93` */ - -external var on_surface_renamed: uint /* uint & `T$93` */ - -external var on_player_toggled_alt_mode: uint /* uint & `T$93` */ - -external var on_player_repaired_entity: uint /* uint & `T$93` */ - -external var on_player_fast_transferred: uint /* uint & `T$93` */ - -external var on_pre_robot_exploded_cliff: uint /* uint & `T$93` */ - -external var on_robot_exploded_cliff: uint /* uint & `T$93` */ - -external var on_entity_spawned: uint /* uint & `T$93` */ - -external var on_cutscene_waypoint_reached: uint /* uint & `T$93` */ - -external var on_unit_group_created: uint /* uint & `T$93` */ - -external var on_unit_added_to_group: uint /* uint & `T$93` */ - -external var on_unit_removed_from_group: uint /* uint & `T$93` */ - -external var on_unit_group_finished_gathering: uint /* uint & `T$93` */ - -external var on_build_base_arrived: uint /* uint & `T$93` */ - -external var on_chart_tag_added: uint /* uint & `T$93` */ - -external var on_chart_tag_modified: uint /* uint & `T$93` */ - -external var on_chart_tag_removed: uint /* uint & `T$93` */ - -external var on_lua_shortcut: uint /* uint & `T$93` */ - -external var on_gui_location_changed: uint /* uint & `T$93` */ - -external var on_gui_selected_tab_changed: uint /* uint & `T$93` */ - -external var on_gui_switch_state_changed: uint /* uint & `T$93` */ - -external var on_force_cease_fire_changed: uint /* uint & `T$93` */ - -external var on_force_friends_changed: uint /* uint & `T$93` */ - -external var on_string_translated: uint /* uint & `T$93` */ - -external var on_script_trigger_effect: uint /* uint & `T$93` */ - -external var on_player_set_quick_bar_slot: uint /* uint & `T$93` */ - -external var on_pre_player_toggled_map_editor: uint /* uint & `T$93` */ - -external var on_pre_script_inventory_resized: uint /* uint & `T$93` */ - -external var on_script_inventory_resized: uint /* uint & `T$93` */ - -external var on_entity_destroyed: uint /* uint & `T$93` */ - -external var on_player_clicked_gps_tag: uint /* uint & `T$93` */ - -external var on_player_flushed_fluid: uint /* uint & `T$93` */ - -external var on_permission_group_edited: uint /* uint & `T$93` */ - -external var on_pre_permission_string_imported: uint /* uint & `T$93` */ - -external var on_permission_string_imported: uint /* uint & `T$93` */ - -external var on_pre_permission_group_deleted: uint /* uint & `T$93` */ - -external var on_permission_group_deleted: uint /* uint & `T$93` */ - -external var on_permission_group_added: uint /* uint & `T$93` */ - -external var on_cutscene_cancelled: uint /* uint & `T$93` */ - -external var on_player_configured_spider_remote: uint /* uint & `T$93` */ - -external var on_player_used_spider_remote: uint /* uint & `T$93` */ - -external var on_spider_command_completed: uint /* uint & `T$93` */ - -external var on_entity_logistic_slot_changed: uint /* uint & `T$93` */ - -external var on_equipment_inserted: uint /* uint & `T$93` */ - -external var on_equipment_removed: uint /* uint & `T$93` */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/defines/riding/defines.defines.riding.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/riding/defines.defines.riding.module_typed-factorio.kt deleted file mode 100644 index 936be1e..0000000 --- a/modules/mod2/dukat-custom/defines/riding/defines.defines.riding.module_typed-factorio.kt +++ /dev/null @@ -1,30 +0,0 @@ -@file:JsQualifier("defines.riding") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package defines.riding - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external enum class acceleration { - nothing, - accelerating, - braking, - reversing -} - -external enum class direction { - left, - straight, - right -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/eventId.kt b/modules/mod2/dukat-custom/eventId.kt deleted file mode 100644 index b4cd976..0000000 --- a/modules/mod2/dukat-custom/eventId.kt +++ /dev/null @@ -1,11 +0,0 @@ - -external class TsUInt : tsstdlib.Number - -external class EventId { - @JsName("_eventData") - val eventData: DataT - - @JsName("_filter") - val filter: FilterT - -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/events.module_typed-factorio.kt b/modules/mod2/dukat-custom/events.module_typed-factorio.kt deleted file mode 100644 index 497a8ff..0000000 --- a/modules/mod2/dukat-custom/events.module_typed-factorio.kt +++ /dev/null @@ -1,1574 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import tsstdlib.Position -import defines.behavior_result -import defines.mouse_button_type -import defines.gui_type -import defines.direction -import defines.input_action -import defines.disconnect_reason -import tsstdlib.Record -import defines.train_state - -external interface CustomInputEvent { - var player_index: uint - var input_name: String - var cursor_position: Position - var selected_prototype: SelectedPrototypeData? - get() = definedExternally - set(value) = definedExternally - var name: String - var tick: uint -} - -external interface OnAiCommandCompletedEvent { - var unit_number: uint - var result: behavior_result - var was_distracted: Boolean? - var name: Any - var tick: uint -} - -external interface OnAreaClonedEvent { - var source_surface: LuaSurface - var source_area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var destination_surface: LuaSurface - var destination_area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var destination_force: LuaForce? - get() = definedExternally - set(value) = definedExternally - var clone_tiles: Boolean? - var clone_entities: Boolean? - var clone_decoratives: Boolean? - var clear_destination_entities: Boolean? - var clear_destination_decoratives: Boolean? - var name: Any - var tick: uint -} - -external interface OnBiterBaseBuiltEvent { - var entity: LuaEntity - var name: Any - var tick: uint -} - -external interface OnBrushClonedEvent { - var source_offset: dynamic /* TilePositionTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var destination_offset: dynamic /* TilePositionTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var source_surface: LuaSurface - var source_positions: Array */> - var destination_surface: LuaSurface - var destination_force: LuaForce? - get() = definedExternally - set(value) = definedExternally - var clone_tiles: Boolean? - var clone_entities: Boolean? - var clone_decoratives: Boolean? - var clear_destination_entities: Boolean? - var clear_destination_decoratives: Boolean? - var name: Any - var tick: uint -} - -external interface OnBuildBaseArrivedEvent { - var unit: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var group: LuaUnitGroup? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnBuiltEntityEvent { - var created_entity: LuaEntity - var player_index: uint - var stack: LuaItemStack - var item: LuaItemPrototype? - get() = definedExternally - set(value) = definedExternally - var tags: Tags? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnCancelledDeconstructionEvent { - var entity: LuaEntity - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnCancelledUpgradeEvent { - var entity: LuaEntity - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnCharacterCorpseExpiredEvent { - var corpse: LuaEntity - var name: Any - var tick: uint -} - -external interface OnChartTagAddedEvent { - var tag: LuaCustomChartTag - var force: LuaForce - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnChartTagModifiedEvent { - var tag: LuaCustomChartTag - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var force: LuaForce - var old_text: String - var old_icon: SignalID? - get() = definedExternally - set(value) = definedExternally - var old_player: uint? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnChartTagRemovedEvent { - var tag: LuaCustomChartTag - var force: LuaForce - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnChunkChartedEvent { - var surface_index: uint - var position: dynamic /* ChunkPositionTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var force: LuaForce - var name: Any - var tick: uint -} - -external interface OnChunkDeletedEvent { - var surface_index: uint - var positions: Array */> - var name: Any - var tick: uint -} - -external interface OnChunkGeneratedEvent { - var area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var position: dynamic /* ChunkPositionTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var surface: LuaSurface - var name: Any - var tick: uint -} - -external interface OnCombatRobotExpiredEvent { - var robot: LuaEntity - var owner: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnConsoleChatEvent { - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var message: String - var name: Any - var tick: uint -} - -external interface OnConsoleCommandEvent { - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var command: String - var parameters: String - var name: Any - var tick: uint -} - -external interface OnCutsceneCancelledEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnCutsceneWaypointReachedEvent { - var player_index: uint - var waypoint_index: uint - var name: Any - var tick: uint -} - -external interface OnDifficultySettingsChangedEvent { - var old_recipe_difficulty: uint - var old_technology_difficulty: uint - var name: Any - var tick: uint -} - -external interface OnEntityClonedEvent { - var source: LuaEntity - var destination: LuaEntity - var name: Any - var tick: uint -} - -external interface OnEntityDamagedEvent { - var entity: LuaEntity - var damage_type: LuaDamagePrototype - var original_damage_amount: float - var final_damage_amount: float - var final_health: float - var cause: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var force: LuaForce? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnEntityDestroyedEvent { - var registration_number: uint64 - var unit_number: uint? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnEntityDiedEvent { - var entity: LuaEntity - var cause: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var loot: LuaInventory - var force: LuaForce? - get() = definedExternally - set(value) = definedExternally - var damage_type: LuaDamagePrototype? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnEntityLogisticSlotChangedEvent { - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var entity: LuaEntity - var slot_index: uint - var name: Any - var tick: uint -} - -external interface OnEntityRenamedEvent { - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var by_script: Boolean? - var entity: LuaEntity - var old_name: String - var name: Any - var tick: uint -} - -external interface OnEntitySettingsPastedEvent { - var player_index: uint - var source: LuaEntity - var destination: LuaEntity - var name: Any - var tick: uint -} - -external interface OnEntitySpawnedEvent { - var spawner: LuaEntity - var entity: LuaEntity - var name: Any - var tick: uint -} - -external interface OnEquipmentInsertedEvent { - var grid: LuaEquipmentGrid - var equipment: LuaEquipment - var name: Any - var tick: uint -} - -external interface OnEquipmentRemovedEvent { - var grid: LuaEquipmentGrid - var equipment: String - var count: uint - var name: Any - var tick: uint -} - -external interface OnForceCeaseFireChangedEvent { - var force: LuaForce - var other_force: LuaForce - var added: Boolean? - var name: Any - var tick: uint -} - -external interface OnForceCreatedEvent { - var force: LuaForce - var name: Any - var tick: uint -} - -external interface OnForceFriendsChangedEvent { - var force: LuaForce - var other_force: LuaForce - var added: Boolean? - var name: Any - var tick: uint -} - -external interface OnForceResetEvent { - var force: LuaForce - var name: Any - var tick: uint -} - -external interface OnForcesMergedEvent { - var source_name: String - var source_index: uint - var destination: LuaForce - var name: Any - var tick: uint -} - -external interface OnForcesMergingEvent { - var source: LuaForce - var destination: LuaForce - var name: Any - var tick: uint -} - -external interface OnGameCreatedFromScenarioEvent { - var name: Any - var tick: uint -} - -external interface OnGuiCheckedStateChangedEvent { - var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnGuiClickEvent { - var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var player_index: uint - var button: mouse_button_type - var alt: Boolean? - var control: Boolean? - var shift: Boolean? - var name: Any - var tick: uint -} - -external interface OnGuiClosedEvent { - var player_index: uint - var gui_type: gui_type - var entity: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var item: LuaItemStack? - get() = definedExternally - set(value) = definedExternally - var equipment: LuaEquipment? - get() = definedExternally - set(value) = definedExternally - var other_player: LuaPlayer? - get() = definedExternally - set(value) = definedExternally - var element: dynamic /* ChooseElemButtonGuiElementMembers? | DropDownGuiElementMembers? | EmptyWidgetGuiElementMembers? | EntityPreviewGuiElementMembers? | ListBoxGuiElementMembers? | ScrollPaneGuiElementMembers? | SpriteButtonGuiElementMembers? | TabbedPaneGuiElementMembers? | TextBoxGuiElementMembers? | ButtonGuiElementMembers? | CameraGuiElementMembers? | CheckboxGuiElementMembers? | FlowGuiElementMembers? | FrameGuiElementMembers? | LabelGuiElementMembers? | LineGuiElementMembers? | MinimapGuiElementMembers? | ProgressbarGuiElementMembers? | RadiobuttonGuiElementMembers? | SliderGuiElementMembers? | SpriteGuiElementMembers? | SwitchGuiElementMembers? | TabGuiElementMembers? | TableGuiElementMembers? | TextfieldGuiElementMembers? */ - get() = definedExternally - set(value) = definedExternally - var technology: LuaTechnology? - get() = definedExternally - set(value) = definedExternally - var tile_position: dynamic /* TilePositionTable? | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnGuiConfirmedEvent { - var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var player_index: uint - var alt: Boolean? - var control: Boolean? - var shift: Boolean? - var name: Any - var tick: uint -} - -external interface OnGuiElemChangedEvent { - var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnGuiLocationChangedEvent { - var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnGuiOpenedEvent { - var player_index: uint - var gui_type: gui_type - var entity: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var item: LuaItemStack? - get() = definedExternally - set(value) = definedExternally - var equipment: LuaEquipment? - get() = definedExternally - set(value) = definedExternally - var other_player: LuaPlayer? - get() = definedExternally - set(value) = definedExternally - var element: dynamic /* ChooseElemButtonGuiElementMembers? | DropDownGuiElementMembers? | EmptyWidgetGuiElementMembers? | EntityPreviewGuiElementMembers? | ListBoxGuiElementMembers? | ScrollPaneGuiElementMembers? | SpriteButtonGuiElementMembers? | TabbedPaneGuiElementMembers? | TextBoxGuiElementMembers? | ButtonGuiElementMembers? | CameraGuiElementMembers? | CheckboxGuiElementMembers? | FlowGuiElementMembers? | FrameGuiElementMembers? | LabelGuiElementMembers? | LineGuiElementMembers? | MinimapGuiElementMembers? | ProgressbarGuiElementMembers? | RadiobuttonGuiElementMembers? | SliderGuiElementMembers? | SpriteGuiElementMembers? | SwitchGuiElementMembers? | TabGuiElementMembers? | TableGuiElementMembers? | TextfieldGuiElementMembers? */ - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnGuiSelectedTabChangedEvent { - var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnGuiSelectionStateChangedEvent { - var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnGuiSwitchStateChangedEvent { - var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnGuiTextChangedEvent { - var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var player_index: uint - var text: String - var name: Any - var tick: uint -} - -external interface OnGuiValueChangedEvent { - var element: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ - get() = definedExternally - set(value) = definedExternally - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnLandMineArmedEvent { - var mine: LuaEntity - var name: Any - var tick: uint -} - -external interface OnLuaShortcutEvent { - var player_index: uint - var prototype_name: String - var name: Any - var tick: uint -} - -external interface OnMarkedForDeconstructionEvent { - var entity: LuaEntity - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnMarkedForUpgradeEvent { - var entity: LuaEntity - var target: LuaEntityPrototype - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var direction: direction? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnMarketItemPurchasedEvent { - var player_index: uint - var market: LuaEntity - var offer_index: uint - var count: uint - var name: Any - var tick: uint -} - -external interface OnModItemOpenedEvent { - var player_index: uint - var item: LuaItemPrototype - var name: Any - var tick: uint -} - -external interface OnPermissionGroupAddedEvent { - var player_index: uint - var group: LuaPermissionGroup - var name: Any - var tick: uint -} - -external interface OnPermissionGroupDeletedEvent { - var player_index: uint - var group_name: String - var id: uint - var name: Any - var tick: uint -} - -external interface OnPermissionGroupEditedEvent { - var player_index: uint - var group: LuaPermissionGroup - var type: String /* "add-permission" | "remove-permission" | "enable-all" | "disable-all" | "add-player" | "remove-player" | "rename" */ - var action: input_action - var other_player_index: uint - var old_name: String - var new_name: String - var name: Any - var tick: uint -} - -external interface OnPermissionStringImportedEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPickedUpItemEvent { - var item_stack: dynamic /* String | ItemStackDefinition */ - get() = definedExternally - set(value) = definedExternally - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerAltSelectedAreaEvent { - var player_index: uint - var surface: LuaSurface - var area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var item: String - var entities: Array - var tiles: Array - var name: Any - var tick: uint -} - -external interface OnPlayerAmmoInventoryChangedEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerArmorInventoryChangedEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerBannedEvent { - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var player_name: String - var by_player: uint? - get() = definedExternally - set(value) = definedExternally - var reason: String? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnPlayerBuiltTileEvent { - var player_index: uint - var surface_index: uint - var tiles: Array - var tile: LuaTilePrototype - var item: LuaItemPrototype? - get() = definedExternally - set(value) = definedExternally - var stack: LuaItemStack? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnPlayerCancelledCraftingEvent { - var player_index: uint - var items: LuaInventory - var recipe: LuaRecipe - var cancel_count: uint - var name: Any - var tick: uint -} - -external interface OnPlayerChangedForceEvent { - var player_index: uint - var force: LuaForce - var name: Any - var tick: uint -} - -external interface OnPlayerChangedPositionEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerChangedSurfaceEvent { - var player_index: uint - var surface_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerCheatModeDisabledEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerCheatModeEnabledEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerClickedGpsTagEvent { - var player_index: uint - var position: Position - var surface: String - var name: Any - var tick: uint -} - -external interface OnPlayerConfiguredBlueprintEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerConfiguredSpiderRemoteEvent { - var player_index: uint - var vehicle: LuaEntity - var name: Any - var tick: uint -} - -external interface OnPlayerCraftedItemEvent { - var item_stack: LuaItemStack - var player_index: uint - var recipe: LuaRecipe - var name: Any - var tick: uint -} - -external interface OnPlayerCreatedEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerCursorStackChangedEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerDeconstructedAreaEvent { - var player_index: uint - var surface: LuaSurface - var area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var item: String - var alt: Boolean? - var name: Any - var tick: uint -} - -external interface OnPlayerDemotedEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerDiedEvent { - var player_index: uint - var cause: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnPlayerDisplayResolutionChangedEvent { - var player_index: uint - var old_resolution: DisplayResolution - var name: Any - var tick: uint -} - -external interface OnPlayerDisplayScaleChangedEvent { - var player_index: uint - var old_scale: double - var name: Any - var tick: uint -} - -external interface OnPlayerDrivingChangedStateEvent { - var player_index: uint - var entity: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnPlayerDroppedItemEvent { - var player_index: uint - var entity: LuaEntity - var name: Any - var tick: uint -} - -external interface OnPlayerFastTransferredEvent { - var player_index: uint - var entity: LuaEntity - var from_player: Boolean? - var name: Any - var tick: uint -} - -external interface OnPlayerFlushedFluidEvent { - var player_index: uint - var fluid: String - var amount: double - var entity: LuaEntity - var only_this_entity: Boolean? - var name: Any - var tick: uint -} - -external interface OnPlayerGunInventoryChangedEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerJoinedGameEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerKickedEvent { - var player_index: uint - var by_player: uint? - get() = definedExternally - set(value) = definedExternally - var reason: String? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnPlayerLeftGameEvent { - var player_index: uint - var reason: disconnect_reason - var name: Any - var tick: uint -} - -external interface OnPlayerMainInventoryChangedEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerMinedEntityEvent { - var player_index: uint - var entity: LuaEntity - var buffer: LuaInventory - var name: Any - var tick: uint -} - -external interface OnPlayerMinedItemEvent { - var item_stack: dynamic /* String | ItemStackDefinition */ - get() = definedExternally - set(value) = definedExternally - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerMinedTileEvent { - var player_index: uint - var surface_index: uint - var tiles: Array - var name: Any - var tick: uint -} - -external interface OnPlayerMutedEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerPipetteEvent { - var player_index: uint - var item: LuaItemPrototype - var used_cheat_mode: Boolean? - var name: Any - var tick: uint -} - -external interface OnPlayerPlacedEquipmentEvent { - var player_index: uint - var equipment: LuaEquipment - var grid: LuaEquipmentGrid - var name: Any - var tick: uint -} - -external interface OnPlayerPromotedEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerRemovedEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerRemovedEquipmentEvent { - var player_index: uint - var grid: LuaEquipmentGrid - var equipment: String - var count: uint - var name: Any - var tick: uint -} - -external interface OnPlayerRepairedEntityEvent { - var player_index: uint - var entity: LuaEntity - var name: Any - var tick: uint -} - -external interface OnPlayerRespawnedEvent { - var player_index: uint - var player_port: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnPlayerRotatedEntityEvent { - var entity: LuaEntity - var previous_direction: direction - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerSelectedAreaEvent { - var player_index: uint - var surface: LuaSurface - var area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var item: String - var entities: Array - var tiles: Array - var name: Any - var tick: uint -} - -external interface OnPlayerSetQuickBarSlotEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerSetupBlueprintEvent { - var player_index: uint - var surface: LuaSurface - var area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var item: String - var alt: Boolean? - var mapping: LuaLazyLoadedValue> - var name: Any - var tick: uint -} - -external interface OnPlayerToggledAltModeEvent { - var player_index: uint - var alt_mode: Boolean? - var name: Any - var tick: uint -} - -external interface OnPlayerToggledMapEditorEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerTrashInventoryChangedEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerUnbannedEvent { - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var player_name: String - var by_player: uint? - get() = definedExternally - set(value) = definedExternally - var reason: String? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnPlayerUnmutedEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPlayerUsedCapsuleEvent { - var player_index: uint - var item: LuaItemPrototype - var position: Position - var name: Any - var tick: uint -} - -external interface OnPlayerUsedSpiderRemoteEvent { - var player_index: uint - var vehicle: LuaEntity - var position: Position - var success: Boolean? - var name: Any - var tick: uint -} - -external interface OnPostEntityDiedEvent { - var ghost: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var force: LuaForce? - get() = definedExternally - set(value) = definedExternally - var position: Position - var prototype: LuaEntityPrototype - var damage_type: LuaDamagePrototype? - get() = definedExternally - set(value) = definedExternally - var corpses: Array - var surface_index: uint - var unit_number: uint? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnPreBuildEvent { - var player_index: uint - var position: Position - var shift_build: Boolean? - var direction: direction - var flip_horizontal: Boolean? - var flip_vertical: Boolean? - var created_by_moving: Boolean? - var name: Any - var tick: uint -} - -external interface OnPreChunkDeletedEvent { - var surface_index: uint - var positions: Array */> - var name: Any - var tick: uint -} - -external interface OnPreEntitySettingsPastedEvent { - var player_index: uint - var source: LuaEntity - var destination: LuaEntity - var name: Any - var tick: uint -} - -external interface OnPreGhostDeconstructedEvent { - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var ghost: LuaEntity - var name: Any - var tick: uint -} - -external interface OnPrePermissionGroupDeletedEvent { - var player_index: uint - var group: LuaPermissionGroup - var name: Any - var tick: uint -} - -external interface OnPrePermissionStringImportedEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPrePlayerCraftedItemEvent { - var player_index: uint - var recipe: LuaRecipe - var items: LuaInventory - var queued_count: uint - var name: Any - var tick: uint -} - -external interface OnPrePlayerDiedEvent { - var player_index: uint - var cause: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnPrePlayerLeftGameEvent { - var player_index: uint - var reason: disconnect_reason - var name: Any - var tick: uint -} - -external interface OnPrePlayerMinedItemEvent { - var entity: LuaEntity - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPrePlayerRemovedEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPrePlayerToggledMapEditorEvent { - var player_index: uint - var name: Any - var tick: uint -} - -external interface OnPreRobotExplodedCliffEvent { - var robot: LuaEntity - var cliff: LuaEntity - var item: LuaItemPrototype - var name: Any - var tick: uint -} - -external interface OnPreScriptInventoryResizedEvent { - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var mod: String - var inventory: LuaInventory - var old_size: uint - var new_size: uint - var name: Any - var tick: uint -} - -external interface OnPreSurfaceClearedEvent { - var surface_index: uint - var name: Any - var tick: uint -} - -external interface OnPreSurfaceDeletedEvent { - var surface_index: uint - var name: Any - var tick: uint -} - -external interface OnResearchFinishedEvent { - var research: LuaTechnology - var by_script: Boolean? - var name: Any - var tick: uint -} - -external interface OnResearchReversedEvent { - var research: LuaTechnology - var by_script: Boolean? - var name: Any - var tick: uint -} - -external interface OnResearchStartedEvent { - var research: LuaTechnology - var last_research: LuaTechnology? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnResourceDepletedEvent { - var entity: LuaEntity - var name: Any - var tick: uint -} - -external interface OnRobotBuiltEntityEvent { - var robot: LuaEntity - var created_entity: LuaEntity - var stack: LuaItemStack - var tags: Tags? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnRobotBuiltTileEvent { - var robot: LuaEntity - var tiles: Array - var tile: LuaTilePrototype - var item: LuaItemPrototype - var stack: LuaItemStack - var surface_index: uint - var name: Any - var tick: uint -} - -external interface OnRobotExplodedCliffEvent { - var robot: LuaEntity - var item: LuaItemPrototype - var name: Any - var tick: uint -} - -external interface OnRobotMinedEvent { - var robot: LuaEntity - var item_stack: dynamic /* String | ItemStackDefinition */ - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnRobotMinedEntityEvent { - var robot: LuaEntity - var entity: LuaEntity - var buffer: LuaInventory - var name: Any - var tick: uint -} - -external interface OnRobotMinedTileEvent { - var robot: LuaEntity - var tiles: Array - var surface_index: uint - var name: Any - var tick: uint -} - -external interface OnRobotPreMinedEvent { - var robot: LuaEntity - var entity: LuaEntity - var name: Any - var tick: uint -} - -external interface OnRocketLaunchOrderedEvent { - var rocket: LuaEntity - var rocket_silo: LuaEntity - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnRocketLaunchedEvent { - var rocket: LuaEntity - var rocket_silo: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnRuntimeModSettingChangedEvent { - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var setting: String - var setting_type: String /* "runtime-per-user" | "runtime-global" */ - var name: Any - var tick: uint -} - -external interface OnScriptInventoryResizedEvent { - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var mod: String - var inventory: LuaInventory - var old_size: uint - var new_size: uint - var overflow_inventory: LuaInventory - var name: Any - var tick: uint -} - -external interface OnScriptPathRequestFinishedEvent { - var path: Array? - get() = definedExternally - set(value) = definedExternally - var id: uint - var try_again_later: Boolean? - var name: Any - var tick: uint -} - -external interface OnScriptTriggerEffectEvent { - var effect_id: String - var surface_index: uint - var source_position: Position? - get() = definedExternally - set(value) = definedExternally - var source_entity: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var target_position: Position? - get() = definedExternally - set(value) = definedExternally - var target_entity: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnSectorScannedEvent { - var radar: LuaEntity - var chunk_position: dynamic /* ChunkPositionTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var area: dynamic /* BoundingBoxTable | JsTuple */ - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnSelectedEntityChangedEvent { - var player_index: uint - var last_entity: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnSpiderCommandCompletedEvent { - var vehicle: LuaEntity - var name: Any - var tick: uint -} - -external interface OnStringTranslatedEvent { - var player_index: uint - var localised_string: dynamic /* JsTuple | String | Number */ - get() = definedExternally - set(value) = definedExternally - var result: String - var translated: Boolean? - var name: Any - var tick: uint -} - -external interface OnSurfaceClearedEvent { - var surface_index: uint - var name: Any - var tick: uint -} - -external interface OnSurfaceCreatedEvent { - var surface_index: uint - var name: Any - var tick: uint -} - -external interface OnSurfaceDeletedEvent { - var surface_index: uint - var name: Any - var tick: uint -} - -external interface OnSurfaceImportedEvent { - var surface_index: uint - var original_name: String - var name: Any - var tick: uint -} - -external interface OnSurfaceRenamedEvent { - var surface_index: uint - var old_name: String - var new_name: String - var name: Any - var tick: uint -} - -external interface OnTechnologyEffectsResetEvent { - var force: LuaForce - var name: Any - var tick: uint -} - -external interface OnTickEvent { - var name: Any - var tick: uint -} - -external interface OnTrainChangedStateEvent { - var train: LuaTrain - var old_state: train_state - var name: Any - var tick: uint -} - -external interface OnTrainCreatedEvent { - var train: LuaTrain - var old_train_id_1: uint? - get() = definedExternally - set(value) = definedExternally - var old_train_id_2: uint? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnTrainScheduleChangedEvent { - var train: LuaTrain - var player_index: uint? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnTriggerCreatedEntityEvent { - var entity: LuaEntity - var source: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnTriggerFiredArtilleryEvent { - var entity: LuaEntity - var source: LuaEntity? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface OnUnitAddedToGroupEvent { - var unit: LuaEntity - var group: LuaUnitGroup - var name: Any - var tick: uint -} - -external interface OnUnitGroupCreatedEvent { - var group: LuaUnitGroup - var name: Any - var tick: uint -} - -external interface OnUnitGroupFinishedGatheringEvent { - var group: LuaUnitGroup - var name: Any - var tick: uint -} - -external interface OnUnitRemovedFromGroupEvent { - var unit: LuaEntity - var group: LuaUnitGroup - var name: Any - var tick: uint -} - -external interface OnWorkerRobotExpiredEvent { - var robot: LuaEntity - var name: Any - var tick: uint -} - -external interface ScriptRaisedBuiltEvent { - var entity: LuaEntity - var name: Any - var tick: uint -} - -external interface ScriptRaisedDestroyEvent { - var entity: LuaEntity - var name: Any - var tick: uint -} - -external interface ScriptRaisedReviveEvent { - var entity: LuaEntity - var tags: Tags? - get() = definedExternally - set(value) = definedExternally - var name: Any - var tick: uint -} - -external interface ScriptRaisedSetTilesEvent { - var surface_index: uint - var tiles: Array - var name: Any - var tick: uint -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/global-objects.module_typed-factorio.kt b/modules/mod2/dukat-custom/global-objects.module_typed-factorio.kt deleted file mode 100644 index 5eaab96..0000000 --- a/modules/mod2/dukat-custom/global-objects.module_typed-factorio.kt +++ /dev/null @@ -1,29 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external var game: LuaGameScript - -external var script: LuaBootstrap - -external var remote: LuaRemote - -external var commands: LuaCommandProcessor - -external var settings: LuaSettings - -external var rcon: LuaRCON - -external var rendering: LuaRendering \ No newline at end of file diff --git a/modules/mod2/dukat-custom/global.module_lua-types.kt b/modules/mod2/dukat-custom/global.module_lua-types.kt deleted file mode 100644 index 470dcc5..0000000 --- a/modules/mod2/dukat-custom/global.module_lua-types.kt +++ /dev/null @@ -1,95 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", - "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import tsstdlib.Record -import tsstdlib.Iterable - -external interface LuaThread { - var __internal__: Any -} - -external interface LuaUserdata { - var __internal__: Any -} - -external var _VERSION: String /* "Lua 5.1" | "Lua 5.2" | "Lua 5.3" | "Lua 5.4" */ - -external var _G: Any - -external fun assert(v: V): Any - -external fun > assert(v: V, - vararg args: A): dynamic /* JsTuple, Any> */ - -external fun collectgarbage(opt: String /* "collect" | "stop" | "restart" */ = definedExternally) - -external fun collectgarbage() - -external fun collectgarbage(opt: String /* "setpause" | "setstepmul" | "step" */, - arg: Number): dynamic /* Number | Boolean */ - -external fun dofile(filename: String = definedExternally): Any - -external fun error(message: String, level: Number = definedExternally): Any - -external fun getmetatable(obj: T): LuaMetatable__1? - -external fun ipairs( - t: kotlinext.js.Record): - Iterable> */> -/* Iterable> */> & LuaIterator> */, undefined> & LuaExtension */ - -external fun next(table: Any?, - index: Any = definedExternally): dynamic /* JsTuple | JsTuple<> */ - -external fun pairs( - t: LuaTable): Iterable> */> /* Iterable> */> & LuaIterator> */, undefined> & LuaExtension */ - -external fun pairs( - t: T): Iterable> */> /* Iterable> */> & LuaIterator> */, undefined> & LuaExtension */ - -external fun , R> pcall(f: (self: This, args: Args) -> R, context: This, - vararg args: Args): dynamic /* JsTuple | JsTuple */ - -external fun , R> pcall(f: (self: Unit, args: A) -> R, - vararg args: A): dynamic /* JsTuple | JsTuple */ - -external fun print(vararg args: Any) - -external fun rawequal(v1: T, v2: T): Boolean - -external fun rawget(table: T, index: K): Any - -external fun rawlen(v: Any?): Number - -external fun rawlen(v: String?): Number - -external fun rawset(table: T, index: K, value: Any): T - -external fun select(index: Number, - vararg args: T): Array /* Array & LuaExtension */ - -external fun select(index: String /* "#" */, vararg args: T): Number - -external fun setmetatable(table: T, - metatable: LuaMetatable? = definedExternally): Any - -external fun tonumber(e: Any, base: Number = definedExternally): Number? - -external fun tostring(v: Any): String - -external fun type( - v: Any): String /* "nil" | "number" | "string" | "boolean" | "table" | "function" | "thread" | "userdata" */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/index.module_typescript-to-lua.kt b/modules/mod2/dukat-custom/index.module_typescript-to-lua.kt deleted file mode 100644 index cb772bd..0000000 --- a/modules/mod2/dukat-custom/index.module_typescript-to-lua.kt +++ /dev/null @@ -1,43 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import tsstdlib.Record -import tsstdlib.Iterable - -typealias AnyTable = Record - -external interface AnyNotNil - -typealias LuaExtension = Any - -//external var `$multi`: (values: T) -> T /* (values: T) -> T & LuaExtension */ -external fun `$multi`(values: T): T /* (values: T) -> T & LuaExtension */ - -external var `$range`: (start: Number, limit: Number, step: Number) -> Iterable /* (start: Number, limit: Number, step: Number) -> Iterable & LuaExtension */ - -external var `$vararg`: Array /* Array & LuaExtension */ - -typealias LuaIterator = Any - -@Suppress("EXTERNAL_DELEGATION", "NESTED_CLASS_IN_EXTERNAL_INTERFACE") -external interface LuaTable { - var length: () -> Number /* () -> Number & LuaExtension */ - var get: (key: TKey) -> TValue /* (key: TKey) -> TValue & LuaExtension */ - var set: (key: TKey, value: TValue) -> Unit /* (key: TKey, value: TValue) -> Unit & LuaExtension */ - var has: (key: TKey) -> Boolean /* (key: TKey) -> Boolean & LuaExtension */ - var delete: (key: TKey) -> Boolean /* (key: TKey) -> Boolean & LuaExtension */ - -// companion object : Any by definedExternally -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/io.module_lua-types.kt b/modules/mod2/dukat-custom/io.module_lua-types.kt deleted file mode 100644 index af58374..0000000 --- a/modules/mod2/dukat-custom/io.module_lua-types.kt +++ /dev/null @@ -1,28 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import tsstdlib.Iterable -import io.FileReadFormatToType - -external interface LuaFile { - fun close(): Boolean - fun flush(): Boolean - fun > lines(vararg formats: T): Iterable */> /* Iterable */> & LuaIterator */, undefined> & LuaExtension */ - fun read(): FileReadFormatToType? - fun read(format: T): FileReadFormatToType? /* Any & LuaExtension */ - fun seek(whence: String /* "set" | "cur" | "end" */ = definedExternally, offset: Number = definedExternally): dynamic /* JsTuple | JsTuple */ - fun setvbuf(mode: String /* "no" | "full" | "line" */, size: Number = definedExternally) - fun write(vararg args: Any /* String | Number */): dynamic /* JsTuple | JsTuple */ -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/io/io.io.module_lua-types.kt b/modules/mod2/dukat-custom/io/io.io.module_lua-types.kt deleted file mode 100644 index 87ba8d5..0000000 --- a/modules/mod2/dukat-custom/io/io.io.module_lua-types.kt +++ /dev/null @@ -1,57 +0,0 @@ -@file:JsQualifier("io") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package io - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import LuaFile -import tsstdlib.Iterable - -external fun close(file: LuaFile = definedExternally): Boolean - -external fun flush(): Boolean - -external fun input(file: String = definedExternally): LuaFile - -external fun input(): LuaFile - -external fun input(file: LuaFile = definedExternally): LuaFile - -external fun > lines(filename: String = definedExternally, vararg formats: T): Iterable */> /* Iterable */> & LuaIterator */, undefined> & LuaExtension */ - -external fun open(filename: String, mode: String = definedExternally): dynamic /* JsTuple | JsTuple */ - -external fun output(file: String = definedExternally): LuaFile - -external fun output(): LuaFile - -external fun output(file: LuaFile = definedExternally): LuaFile - -external fun popen(prog: String, mode: String /* "r" | "w" */ = definedExternally): dynamic /* JsTuple | JsTuple */ - -external fun read(): FileReadFormatToType? - -external fun read(format: T): FileReadFormatToType? /* Any & LuaExtension */ - -external var stderr: LuaFile - -external var stdin: LuaFile - -external var stdout: LuaFile - -external fun tmpfile(): LuaFile - -external fun type(obj: Any): String /* "file" | "closed file" */ - -external fun write(vararg args: Any /* String | Number */): dynamic /* JsTuple | JsTuple */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/io/nonDeclarations.io.kt b/modules/mod2/dukat-custom/io/nonDeclarations.io.kt deleted file mode 100644 index 3fc06db..0000000 --- a/modules/mod2/dukat-custom/io/nonDeclarations.io.kt +++ /dev/null @@ -1,18 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package io - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -typealias FileReadFormatToType = Any \ No newline at end of file diff --git a/modules/mod2/dukat-custom/librariesAndFunctions.module_typed-factorio.kt b/modules/mod2/dukat-custom/librariesAndFunctions.module_typed-factorio.kt deleted file mode 100644 index dec76ff..0000000 --- a/modules/mod2/dukat-custom/librariesAndFunctions.module_typed-factorio.kt +++ /dev/null @@ -1,135 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface `T$95` { - var tag: String - var head: String - var body: String - var tail: String - var level: Number -} - -external interface SerpentOptions { - var indent: String - var comment: dynamic /* Boolean | Number */ - get() = definedExternally - set(value) = definedExternally - var sortkeys: dynamic /* Boolean | (this: Unit, keys: Array, table: Any) -> Unit */ - get() = definedExternally - set(value) = definedExternally - var sparse: Boolean? - var compact: Boolean? - var fatal: Boolean? - var nocode: Boolean? - var nohuge: Boolean? - var maxlevel: Number - var maxnum: Number - var maxlength: Number - var metatostring: Boolean? - var numformat: String - var valignore: Array - var keyallow: Array - var keyignore: Array - var valtypeignore: Array - fun custom(opts: `T$95`): String - var name: String - var refcomment: dynamic /* Boolean | Number */ - get() = definedExternally - set(value) = definedExternally - var tablecomment: dynamic /* Boolean | Number */ - get() = definedExternally - set(value) = definedExternally -} - -external interface SerpentOptionsPartial { - var indent: String? - get() = definedExternally - set(value) = definedExternally - var comment: dynamic /* Boolean? | Number? */ - get() = definedExternally - set(value) = definedExternally - var sortkeys: dynamic /* Boolean? | ((this: Unit, keys: Array, table: Any) -> Unit)? */ - get() = definedExternally - set(value) = definedExternally - var sparse: Boolean? - get() = definedExternally - set(value) = definedExternally - var compact: Boolean? - get() = definedExternally - set(value) = definedExternally - var fatal: Boolean? - get() = definedExternally - set(value) = definedExternally - var nocode: Boolean? - get() = definedExternally - set(value) = definedExternally - var nohuge: Boolean? - get() = definedExternally - set(value) = definedExternally - var maxlevel: Number? - get() = definedExternally - set(value) = definedExternally - var maxnum: Number? - get() = definedExternally - set(value) = definedExternally - var maxlength: Number? - get() = definedExternally - set(value) = definedExternally - var metatostring: Boolean? - get() = definedExternally - set(value) = definedExternally - var numformat: String? - get() = definedExternally - set(value) = definedExternally - var valignore: Array? - get() = definedExternally - set(value) = definedExternally - var keyallow: Array? - get() = definedExternally - set(value) = definedExternally - var keyignore: Array? - get() = definedExternally - set(value) = definedExternally - var valtypeignore: Array? - get() = definedExternally - set(value) = definedExternally - var custom: ((opts: `T$95`) -> String)? - get() = definedExternally - set(value) = definedExternally - var name: String? - get() = definedExternally - set(value) = definedExternally - var refcomment: dynamic /* Boolean? | Number? */ - get() = definedExternally - set(value) = definedExternally - var tablecomment: dynamic /* Boolean? | Number? */ - get() = definedExternally - set(value) = definedExternally -} - -external fun log(ls: Any /* JsTuple */) - -external fun log(ls: String) - -external fun log(ls: Number) - -external fun localised_print(ls: Any /* JsTuple */) - -external fun localised_print(ls: String) - -external fun localised_print(ls: Number) - -external fun table_size(tbl: table): Number \ No newline at end of file diff --git a/modules/mod2/dukat-custom/math/math.math.module_lua-types.kt b/modules/mod2/dukat-custom/math/math.math.module_lua-types.kt deleted file mode 100644 index 8012ac2..0000000 --- a/modules/mod2/dukat-custom/math/math.math.module_lua-types.kt +++ /dev/null @@ -1,75 +0,0 @@ -@file:JsQualifier("math") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package math - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external fun abs(x: Number): Number - -external fun acos(x: Number): Number - -external fun asin(x: Number): Number - -external fun ceil(x: Number): Number - -external fun cos(x: Number): Number - -external fun deg(x: Number): Number - -external fun exp(x: Number): Number - -external fun floor(x: Number): Number - -external fun fmod(x: Number, y: Number): Number - -external var huge: Number - -external fun max(x: Number, vararg numbers: Number): Number - -external fun min(x: Number, vararg numbers: Number): Number - -external fun modf(x: Number): dynamic /* JsTuple */ - -external var pi: Number - -external fun rad(x: Number): Number - -external fun sin(x: Number): Number - -external fun sqrt(x: Number): Number - -external fun tan(x: Number): Number - -external fun log(x: Number, base: Number = definedExternally): Number - -external fun atan(x: Number): Number - -external fun atan2(y: Number, x: Number): Number - -external fun cosh(x: Number): Number - -external fun frexp(x: Number): Number - -external fun ldexp(m: Number, e: Number): Number - -external fun pow(x: Number, y: Number): Number - -external fun sinh(x: Number): Number - -external fun tanh(x: Number): Number - -external fun random(m: Number = definedExternally, n: Number = definedExternally): Number - -external fun randomseed(x: Number): Number \ No newline at end of file diff --git a/modules/mod2/dukat-custom/metatable.module_lua-types.kt b/modules/mod2/dukat-custom/metatable.module_lua-types.kt deleted file mode 100644 index 654ca6c..0000000 --- a/modules/mod2/dukat-custom/metatable.module_lua-types.kt +++ /dev/null @@ -1,51 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface LuaMetatable { -// val __pairs: ((t: T) -> dynamic)? -// val __ipairs: ((t: T) -> dynamic)? - fun __pairs(t: T): dynamic - fun __ipairs(t: T): dynamic - val __add: ((operand: Any) -> Any)? - val __sub: ((operand: Any) -> Any)? - val __mul: ((operand: Any) -> Any)? - val __div: ((operand: Any) -> Any)? - val __mod: ((operand: Any) -> Any)? - val __pow: ((operand: Any) -> Any)? - val __unm: ((operand: Any) -> Any)? - val __concat: ((operand: Any) -> Any)? - val __len: (() -> Any)? - val __eq: ((operand: Any) -> Boolean)? - val __lt: ((operand: Any) -> Boolean)? - val __le: ((operand: Any) -> Boolean)? - var __index: TIndex? - get() = definedExternally - set(value) = definedExternally - var __newindex: dynamic /* Any? | ((this: T, key: Any, value: Any) -> Unit)? */ - get() = definedExternally - set(value) = definedExternally - val __call: ((args: Any) -> Any)? - val __tostring: (() -> String)? - var __mode: String? /* "k" | "v" | "kv" */ - get() = definedExternally - set(value) = definedExternally - var __metatable: Any? - get() = definedExternally - set(value) = definedExternally - val __gc: (() -> Unit)? -} - -external interface LuaMetatable__1 : LuaMetatable Any)? */> \ No newline at end of file diff --git a/modules/mod2/dukat-custom/mod_gui/mod-gui.mod_gui.module_typed-factorio.kt b/modules/mod2/dukat-custom/mod_gui/mod-gui.mod_gui.module_typed-factorio.kt deleted file mode 100644 index 64f0b7b..0000000 --- a/modules/mod2/dukat-custom/mod_gui/mod-gui.mod_gui.module_typed-factorio.kt +++ /dev/null @@ -1,29 +0,0 @@ -@file:JsModule("mod-gui") -@file:JsNonModule -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package mod_gui - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import LuaPlayer -import FrameGuiElementMembers -import FlowGuiElementMembers - -external var button_style: String - -external var frame_style: String - -external fun get_button_flow(player: LuaPlayer): FrameGuiElementMembers /* FrameGuiElementMembers & GuiElementIndex */ - -external fun get_frame_flow(player: LuaPlayer): FlowGuiElementMembers /* FlowGuiElementMembers & GuiElementIndex */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/modules.module_lua-types.kt b/modules/mod2/dukat-custom/modules.module_lua-types.kt deleted file mode 100644 index b4ffe28..0000000 --- a/modules/mod2/dukat-custom/modules.module_lua-types.kt +++ /dev/null @@ -1,17 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external fun require(modname: String): Any \ No newline at end of file diff --git a/modules/mod2/dukat-custom/os.module_lua-types.kt b/modules/mod2/dukat-custom/os.module_lua-types.kt deleted file mode 100644 index 8f6fe7b..0000000 --- a/modules/mod2/dukat-custom/os.module_lua-types.kt +++ /dev/null @@ -1,45 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface LuaDateInfo { - var year: Number - var month: Number - var day: Number - var hour: Number? - get() = definedExternally - set(value) = definedExternally - var min: Number? - get() = definedExternally - set(value) = definedExternally - var sec: Number? - get() = definedExternally - set(value) = definedExternally - var isdst: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface LuaDateInfoResult { - var year: Number - var month: Number - var day: Number - var hour: Number - var min: Number - var sec: Number - var isdst: Boolean? - var yday: Number - var wday: Number -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/os/os.os.module_lua-types.kt b/modules/mod2/dukat-custom/os/os.os.module_lua-types.kt deleted file mode 100644 index 9fc56e1..0000000 --- a/modules/mod2/dukat-custom/os/os.os.module_lua-types.kt +++ /dev/null @@ -1,56 +0,0 @@ -@file:JsQualifier("os") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package os - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import LuaDateInfo - -external fun clock(): Number - -external fun date(format: String /* "*t" */ = definedExternally, time: Number = definedExternally): dynamic /* String | LuaDateInfoResult */ - -external fun date(): String - -external fun date(format: String /* "*t" */ = definedExternally): dynamic /* String | LuaDateInfoResult */ - -external fun difftime(t1: Number, t2: Number): Number - -external fun getenv(varname: String): String? - -external fun remove(filename: String): dynamic /* JsTuple | JsTuple */ - -external fun rename(oldname: String, newname: String): dynamic /* JsTuple | JsTuple */ - -external fun setlocale(locale: String = definedExternally, category: String /* "all" | "collate" | "ctype" | "monetary" | "numeric" | "time" */ = definedExternally): String? - -external fun time(): Number - -external fun time(table: LuaDateInfo): Number - -external fun tmpname(): String - -external fun execute(): Boolean - -external fun execute(command: String): dynamic /* JsTuple */ - -external fun exit(code: Boolean = definedExternally, close: Boolean = definedExternally): Any - -external fun exit(): Any - -external fun exit(code: Boolean = definedExternally): Any - -external fun exit(code: Number = definedExternally, close: Boolean = definedExternally): Any - -external fun exit(code: Number = definedExternally): Any \ No newline at end of file diff --git a/modules/mod2/dukat-custom/package/modules.package.module_lua-types.kt b/modules/mod2/dukat-custom/package/modules.package.module_lua-types.kt deleted file mode 100644 index fefc008..0000000 --- a/modules/mod2/dukat-custom/package/modules.package.module_lua-types.kt +++ /dev/null @@ -1,34 +0,0 @@ -@file:JsQualifier("package") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package `package` - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import tsstdlib.Record - -external var config: String - -external var cpath: String - -external var loaded: Record - -external fun loadlib(libname: String, funcname: String): dynamic /* JsTuple> | JsTuple */ - -external var path: String - -external var preload: Record Any> - -external fun searchpath(name: String, path: String, sep: String = definedExternally, rep: String = definedExternally): String - -external var searchers: Array dynamic | (modname: String) -> dynamic | String */> \ No newline at end of file diff --git a/modules/mod2/dukat-custom/pairs.module_typed-factorio.kt b/modules/mod2/dukat-custom/pairs.module_typed-factorio.kt deleted file mode 100644 index 18d966d..0000000 --- a/modules/mod2/dukat-custom/pairs.module_typed-factorio.kt +++ /dev/null @@ -1,22 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import tsstdlib.Iterable - -external fun pairs(table: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */): Iterable */> /* Iterable */> & LuaIterator */, undefined> & LuaExtension */ - -external fun pairs(table: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */): Iterable */> /* Iterable */> & LuaIterator */, undefined> & LuaExtension */ - -external fun ipairs(table: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */): Any \ No newline at end of file diff --git a/modules/mod2/dukat-custom/serpent/librariesAndFunctions.serpent.module_typed-factorio.kt b/modules/mod2/dukat-custom/serpent/librariesAndFunctions.serpent.module_typed-factorio.kt deleted file mode 100644 index 223480e..0000000 --- a/modules/mod2/dukat-custom/serpent/librariesAndFunctions.serpent.module_typed-factorio.kt +++ /dev/null @@ -1,32 +0,0 @@ -@file:JsQualifier("serpent") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package serpent - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import SerpentOptionsPartial - -external fun dump(tbl: Any, options: SerpentOptionsPartial = definedExternally): String - -external fun line(tbl: Any, options: SerpentOptionsPartial = definedExternally): String - -external fun block(tbl: Any, options: SerpentOptionsPartial = definedExternally): String - -external interface `T$96` { - var safe: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external fun load(str: String, options: `T$96` = definedExternally): dynamic /* JsTuple | JsTuple */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/string/string.string.module_lua-types.kt b/modules/mod2/dukat-custom/string/string.string.module_lua-types.kt deleted file mode 100644 index 8910e62..0000000 --- a/modules/mod2/dukat-custom/string/string.string.module_lua-types.kt +++ /dev/null @@ -1,63 +0,0 @@ -@file:JsQualifier("string") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package string - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import tsstdlib.Iterable -import tsstdlib.Record - -external fun byte(s: String, i: Number = definedExternally): dynamic /* Number | Array */ - -external fun byte(s: String): dynamic /* Number | Array */ - -external fun byte(s: String, i: Number = definedExternally, j: Number = definedExternally): Array /* Array & LuaExtension */ - -external fun char(vararg args: Number): String - -external fun dump(func: Function<*>): String - -external fun find(s: String, pattern: String, init: Number = definedExternally, plain: Boolean = definedExternally): dynamic /* JsTuple | JsTuple<> */ - -external fun format(formatstring: String, vararg args: Any): String - -external fun gmatch(s: String, pattern: String): Iterable /* Array & LuaExtension */> /* Iterable /* Array & LuaExtension */> & LuaIterator /* Array & LuaExtension */, undefined> & LuaExtension */ - -external fun gsub(s: String, pattern: String, repl: String, n: Number = definedExternally): dynamic /* JsTuple */ - -external fun gsub(s: String, pattern: String, repl: String): dynamic /* JsTuple */ - -external fun gsub(s: String, pattern: String, repl: Record, n: Number = definedExternally): dynamic /* JsTuple */ - -external fun gsub(s: String, pattern: String, repl: Record): dynamic /* JsTuple */ - -external fun gsub(s: String, pattern: String, repl: (matches: String) -> String, n: Number = definedExternally): dynamic /* JsTuple */ - -external fun gsub(s: String, pattern: String, repl: (matches: String) -> String): dynamic /* JsTuple */ - -external fun len(s: String): Number - -external fun lower(s: String): String - -external fun match(s: String, pattern: String, init: Number = definedExternally): Array /* Array & LuaExtension */ - -external fun rep(s: String, n: Number): String - -external fun reverse(s: String): String - -external fun sub(s: String, i: Number, j: Number = definedExternally): String - -external fun upper(s: String): String - -external fun rep(s: String, n: Number, sep: String = definedExternally): String \ No newline at end of file diff --git a/modules/mod2/dukat-custom/table/table.table.module_lua-types.kt b/modules/mod2/dukat-custom/table/table.table.module_lua-types.kt deleted file mode 100644 index f39ea86..0000000 --- a/modules/mod2/dukat-custom/table/table.table.module_lua-types.kt +++ /dev/null @@ -1,39 +0,0 @@ -@file:JsQualifier("table") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package table2 - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external fun concat(list: Array, sep: String = definedExternally, i: Number = definedExternally, j: Number = definedExternally): String - -external fun insert(list: Array, value: T) - -external fun insert(list: Array, pos: Number, value: T) - -external fun remove(list: Array, pos: Number = definedExternally): T? - -external fun sort(list: Array, comp: (a: T, b: T) -> Boolean = definedExternally) - -external fun > unpack(list: T): T /* T & LuaExtension */ - -external fun unpack(list: Array, i: Number, j: Number = definedExternally): Array /* Array & LuaExtension */ - -external fun unpack(list: Array, i: Number): Array /* Array & LuaExtension */ - -external interface `T$92` { - var n: Number -} - -external fun > pack(vararg args: T): T /* T & `T$92` */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/tsstdlib/lib.dom.kt b/modules/mod2/dukat-custom/tsstdlib/lib.dom.kt deleted file mode 100644 index 09e0f80..0000000 --- a/modules/mod2/dukat-custom/tsstdlib/lib.dom.kt +++ /dev/null @@ -1,31 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface Coordinates { - var accuracy: Number - var altitude: Number? - var altitudeAccuracy: Number? - var heading: Number? - var latitude: Number - var longitude: Number - var speed: Number? -} - -external interface Position { - var coords: Coordinates - var timestamp: Number -} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/tsstdlib/lib.es2015.iterable.kt b/modules/mod2/dukat-custom/tsstdlib/lib.es2015.iterable.kt deleted file mode 100644 index 41ccc71..0000000 --- a/modules/mod2/dukat-custom/tsstdlib/lib.es2015.iterable.kt +++ /dev/null @@ -1,40 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface IteratorYieldResult { - var done: Boolean? - get() = definedExternally - set(value) = definedExternally - var value: TYield -} - -external interface IteratorReturnResult { - var done: Boolean? - var value: TReturn -} - -external interface Iterator { - fun next(vararg args: Any /* JsTuple<> | JsTuple */): dynamic /* IteratorYieldResult | IteratorReturnResult */ - val `return`: ((value: TReturn) -> dynamic)? - val `throw`: ((e: Any) -> dynamic)? -} - -typealias Iterator__1 = Iterator - -external interface Iterable - -external interface IterableIterator : Iterator__1 \ No newline at end of file diff --git a/modules/mod2/dukat-custom/tsstdlib/lib.es5.kt b/modules/mod2/dukat-custom/tsstdlib/lib.es5.kt deleted file mode 100644 index a96c4b5..0000000 --- a/modules/mod2/dukat-custom/tsstdlib/lib.es5.kt +++ /dev/null @@ -1,76 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface FunctionConstructor { - @nativeInvoke - operator fun invoke(vararg args: String): Function<*> - var prototype: Function<*> -} - -external interface ConcatArray { - var length: Number - @nativeGetter - operator fun get(n: Number): T? - @nativeSetter - operator fun set(n: Number, value: T) - fun join(separator: String = definedExternally): String - fun slice(start: Number = definedExternally, end: Number = definedExternally): Array -} - -external interface ArrayConstructor { - fun from(iterable: Iterable): Array - fun from(iterable: ArrayLike): Array - fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array - fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U): Array - fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array - fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U): Array - fun of(vararg items: T): Array - @nativeInvoke - operator fun invoke(arrayLength: Number = definedExternally): Array - @nativeInvoke - operator fun invoke(): Array - @nativeInvoke - operator fun invoke(arrayLength: Number): Array - @nativeInvoke - operator fun invoke(vararg items: T): Array - fun isArray(arg: Any): Boolean - var prototype: Array -} - -external interface ArrayLike { - var length: Number - @nativeGetter - operator fun get(n: Number): T? - @nativeSetter - operator fun set(n: Number, value: T) -} - -typealias Partial = Any - -typealias Pick = Any - -@Deprecated("use Kotlin Wrapper", ReplaceWith("kotlinext.js.Record")) -typealias Record = kotlinext.js.Record - - -typealias Exclude = Any - -typealias Extract = Any - -typealias Omit = Any - -typealias NonNullable = Any \ No newline at end of file diff --git a/modules/mod2/dukat-custom/types.module_typed-factorio.kt b/modules/mod2/dukat-custom/types.module_typed-factorio.kt deleted file mode 100644 index 3b00bbe..0000000 --- a/modules/mod2/dukat-custom/types.module_typed-factorio.kt +++ /dev/null @@ -1,91 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import tsstdlib.Record - -external interface BaseSettingDefinition { - var type: String /* "bool-setting" | "int-setting" | "double-setting" | "string-setting" */ - var name: String - var localized_name: dynamic /* JsTuple | String? | Number? */ - get() = definedExternally - set(value) = definedExternally - var localized_description: dynamic /* JsTuple | String? | Number? */ - get() = definedExternally - set(value) = definedExternally - var order: String? - get() = definedExternally - set(value) = definedExternally - var hidden: Boolean? - get() = definedExternally - set(value) = definedExternally - var setting_type: String /* "startup" | "runtime-global" | "runtime-per-user" */ -} - -external interface BoolSettingDefinition : BaseSettingDefinition { - override var type: String /* "bool-setting" */ - var default_value: Boolean? - var forced_value: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface IntSettingDefinition : BaseSettingDefinition { - override var type: String /* "int-setting" */ - var default_value: Number - var minimum_value: Number? - get() = definedExternally - set(value) = definedExternally - var maximum_value: Number? - get() = definedExternally - set(value) = definedExternally - var allowed_values: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface DoubleSettingDefinition : BaseSettingDefinition { - override var type: String /* "double-setting" */ - var default_value: Number - var minimum_value: Number? - get() = definedExternally - set(value) = definedExternally - var maximum_value: Number? - get() = definedExternally - set(value) = definedExternally - var allowed_values: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface StringSettingDefinition : BaseSettingDefinition { - override var type: String /* "string-setting" */ - var default_value: String - var allow_blank: Boolean? - get() = definedExternally - set(value) = definedExternally - var auto_trim: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowed_values: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface Data { - var raw: Any - fun extend(prototypes: Array) -} - -typealias Mods = Record \ No newline at end of file diff --git a/modules/mod2/dukat-custom/util/table/util.util.table.module_typed-factorio.kt b/modules/mod2/dukat-custom/util/table/util.util.table.module_typed-factorio.kt deleted file mode 100644 index bd20fee..0000000 --- a/modules/mod2/dukat-custom/util/table/util.util.table.module_typed-factorio.kt +++ /dev/null @@ -1,21 +0,0 @@ -@file:JsQualifier("util.table") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package util.table - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external fun deepcopy(table: T): T - -external fun compare(tb1: T, tb2: T): Boolean \ No newline at end of file diff --git a/modules/mod2/dukat-custom/util/util.util.module_typed-factorio.kt b/modules/mod2/dukat-custom/util/util.util.module_typed-factorio.kt deleted file mode 100644 index ed78e1c..0000000 --- a/modules/mod2/dukat-custom/util/util.util.module_typed-factorio.kt +++ /dev/null @@ -1,110 +0,0 @@ -@file:JsModule("util") -@file:JsNonModule -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package util - -import AnyNotNil -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import tsstdlib.Position -import ColorTable -import defines.direction -import LuaEntity -import tsstdlib.Record -import LuaTable - -external fun copy(table: T): T - -external fun distance(position1: Position, position2: Position): Number - -external fun positiontostr(position: Position): String - -external fun formattime(ticks: Number): String - -external fun color(hex: String): ColorTable - -external fun premul_color(color: ColorTable): ColorTable - -external fun premul_color(color: Any /* JsTuple */): ColorTable - -external fun mix_color(c1: ColorTable, c2: ColorTable): dynamic /* JsTuple */ - -external fun mix_color(c1: ColorTable, c2: Any /* JsTuple */): dynamic /* JsTuple */ - -external fun mix_color(c1: Any /* JsTuple */, c2: ColorTable): dynamic /* JsTuple */ - -external fun mix_color(c1: Any /* JsTuple */, c2: Any /* JsTuple */): dynamic /* JsTuple */ - -external fun multiply_color(c1: ColorTable, n: Number): dynamic /* JsTuple */ - -external fun multiply_color(c1: Any /* JsTuple */, n: Number): dynamic /* JsTuple */ - -external fun moveposition(position: Position, direction: defines.direction, distance: Number): Position? -//external fun moveposition(position: Position, direction: defines.direction.north, distance: Number): Position -//external fun moveposition(position: Position, direction: defines.direction.east, distance: Number): Position -//external fun moveposition(position: Position, direction: defines.direction.south, distance: Number): Position -//external fun moveposition(position: Position, direction: defines.direction.west, distance: Number): Position - -//external fun moveposition(position: Position, direction: direction, distance: Number): Position? - -external fun oppositedirection(direction: direction): direction - -external fun multiplystripes(count: Number, stripes: Array): Array - -external fun by_pixel(x: Number, y: Number): Position - -external fun by_pixel_hr(x: Number, y: Number): Position - -external fun add_shift(a: Any /* JsTuple */, b: Any /* JsTuple */): dynamic /* JsTuple */ - -external fun mul_shift(shift: Any /* JsTuple */, scale: Number?): dynamic /* JsTuple */ - -external fun format_number(amount: Number, append_suffix: Boolean = definedExternally): String - -external fun increment(t: Array, index: Number, v: Number = definedExternally) - -external fun merge(tables: Array): T - -external fun insert_safe(entity: LuaEntity?, item_dict: Record?) - -external fun remove_safe(entity: LuaEntity?, item_dict: Record?) - -external fun split_whitespace(string: String): Array - -external fun clamp(x: Number, lower: Number, upper: Number): Number - -external fun parse_energy(energy: String): Number - -external interface `T$97` { - var probability: Number -} - -external interface `T$98` { - var amount: Number -} - -external interface `T$99` { - var amount_min: Number - var amount_max: Number -} - -external fun product_amount(product: `T$97` /* `T$97` & dynamic */): Number - -external fun empty_sprite(): Any? - -external fun remove_from_list(list: Array, value: T): Boolean - -external fun list_to_map(list: Array): dynamic /* Record | LuaTable */ - -external fun list_to_map(list: T): LuaTable \ No newline at end of file diff --git a/modules/mod2/externals/CompilerOptions.module_typescript-to-lua.kt b/modules/mod2/externals/CompilerOptions.module_typescript-to-lua.kt deleted file mode 100644 index a6740d0..0000000 --- a/modules/mod2/externals/CompilerOptions.module_typescript-to-lua.kt +++ /dev/null @@ -1,75 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.CompilerOptions -import ts.Diagnostic - -typealias OmitIndexSignature = Any - -external interface TransformerImport { - var transform: String - var import: String? - get() = definedExternally - set(value) = definedExternally - var after: Boolean? - get() = definedExternally - set(value) = definedExternally - var afterDeclarations: Boolean? - get() = definedExternally - set(value) = definedExternally - var type: String? /* "program" | "config" | "checker" | "raw" | "compilerOptions" */ - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): Any? - @nativeSetter - operator fun set(option: String, value: Any) -} - -external interface LuaPluginImport { - var name: String - var import: String? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): Any? - @nativeSetter - operator fun set(option: String, value: Any) -} - -external enum class LuaLibImportKind { - None /* = "none" */, - Always /* = "always" */, - Inline /* = "inline" */, - Require /* = "require" */ -} - -external enum class LuaTarget { - Universal /* = "universal" */, - Lua51 /* = "5.1" */, - Lua52 /* = "5.2" */, - Lua53 /* = "5.3" */, - Lua54 /* = "5.4" */, - LuaJIT /* = "JIT" */ -} - -external enum class BuildMode { - Default /* = "default" */, - Library /* = "library" */ -} - -external var isBundleEnabled: (options: OmitIndexSignature /* OmitIndexSignature & `T$0` */) -> Boolean - -external fun validateOptions(options: OmitIndexSignature /* OmitIndexSignature & `T$0` */): Array \ No newline at end of file diff --git a/modules/mod2/externals/LuaAST.module_typescript-to-lua.kt b/modules/mod2/externals/LuaAST.module_typescript-to-lua.kt deleted file mode 100644 index 079e37f..0000000 --- a/modules/mod2/externals/LuaAST.module_typescript-to-lua.kt +++ /dev/null @@ -1,485 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import tsstdlib.Set - -external enum class SyntaxKind { - File /* = 0 */, - Block /* = 1 */, - DoStatement /* = 2 */, - VariableDeclarationStatement /* = 3 */, - AssignmentStatement /* = 4 */, - IfStatement /* = 5 */, - WhileStatement /* = 6 */, - RepeatStatement /* = 7 */, - ForStatement /* = 8 */, - ForInStatement /* = 9 */, - GotoStatement /* = 10 */, - LabelStatement /* = 11 */, - ReturnStatement /* = 12 */, - BreakStatement /* = 13 */, - ExpressionStatement /* = 14 */, - StringLiteral /* = 15 */, - NumericLiteral /* = 16 */, - NilKeyword /* = 17 */, - DotsKeyword /* = 18 */, - TrueKeyword /* = 19 */, - FalseKeyword /* = 20 */, - FunctionExpression /* = 21 */, - TableFieldExpression /* = 22 */, - TableExpression /* = 23 */, - UnaryExpression /* = 24 */, - BinaryExpression /* = 25 */, - CallExpression /* = 26 */, - MethodCallExpression /* = 27 */, - Identifier /* = 28 */, - TableIndexExpression /* = 29 */, - AdditionOperator /* = 30 */, - SubtractionOperator /* = 31 */, - MultiplicationOperator /* = 32 */, - DivisionOperator /* = 33 */, - FloorDivisionOperator /* = 34 */, - ModuloOperator /* = 35 */, - PowerOperator /* = 36 */, - NegationOperator /* = 37 */, - ConcatOperator /* = 38 */, - LengthOperator /* = 39 */, - EqualityOperator /* = 40 */, - InequalityOperator /* = 41 */, - LessThanOperator /* = 42 */, - LessEqualOperator /* = 43 */, - GreaterThanOperator /* = 44 */, - GreaterEqualOperator /* = 45 */, - AndOperator /* = 46 */, - OrOperator /* = 47 */, - NotOperator /* = 48 */, - BitwiseAndOperator /* = 49 */, - BitwiseOrOperator /* = 50 */, - BitwiseExclusiveOrOperator /* = 51 */, - BitwiseRightShiftOperator /* = 52 */, - BitwiseLeftShiftOperator /* = 53 */, - BitwiseNotOperator /* = 54 */ -} - -typealias UnaryBitwiseOperator = SyntaxKind.BitwiseNotOperator - -external interface TextRange { - var line: Number? - get() = definedExternally - set(value) = definedExternally - var column: Number? - get() = definedExternally - set(value) = definedExternally -} - -external interface Node : TextRange { - var kind: SyntaxKind -} - -external fun createNode(kind: SyntaxKind, tsOriginal: ts.Node = definedExternally): Node - -external fun cloneNode(node: T): T - -external fun setNodePosition(node: T, position: TextRange): T - -external fun setNodeOriginal(node: T, tsOriginal: ts.Node): T - -external fun setNodeOriginal(node: T?, tsOriginal: ts.Node): T? - -external fun getOriginalPos(node: Node): TextRange - -external interface File : Node { - var statements: Array - var luaLibFeatures: Set - var trivia: String -} - -external fun isFile(node: Node): Boolean - -external fun createFile(statements: Array, luaLibFeatures: Set, trivia: String, tsOriginal: ts.Node = definedExternally): File - -external interface Block : Node { - var statements: Array -} - -external fun isBlock(node: Node): Boolean - -external fun createBlock(statements: Array, tsOriginal: ts.Node = definedExternally): Block - -external interface Statement : Node { - var _statementBrand: Any - var leadingComments: Array */>? - get() = definedExternally - set(value) = definedExternally - var trailingComments: Array */>? - get() = definedExternally - set(value) = definedExternally -} - -external interface DoStatement : Statement { - var statements: Array -} - -external fun isDoStatement(node: Node): Boolean - -external fun createDoStatement(statements: Array, tsOriginal: ts.Node = definedExternally): DoStatement - -external interface VariableDeclarationStatement : Statement { - var left: Array - var right: Array? - get() = definedExternally - set(value) = definedExternally -} - -external fun isVariableDeclarationStatement(node: Node): Boolean - -external fun createVariableDeclarationStatement(left: Identifier, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Identifier): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Identifier, right: Expression = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Identifier, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Identifier, right: Array = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array, right: Expression = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): VariableDeclarationStatement - -external fun createVariableDeclarationStatement(left: Array, right: Array = definedExternally): VariableDeclarationStatement - -external interface AssignmentStatement : Statement { - var left: Array - var right: Array -} - -external fun isAssignmentStatement(node: Node): Boolean - -external fun createAssignmentStatement(left: Identifier, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Identifier): AssignmentStatement - -external fun createAssignmentStatement(left: Identifier, right: Expression = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Identifier, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Identifier, right: Array = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression, right: Expression = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: TableIndexExpression, right: Array = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Array, right: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Array): AssignmentStatement - -external fun createAssignmentStatement(left: Array, right: Expression = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Array, right: Array = definedExternally, tsOriginal: ts.Node = definedExternally): AssignmentStatement - -external fun createAssignmentStatement(left: Array, right: Array = definedExternally): AssignmentStatement - -external interface IfStatement : Statement { - var condition: Expression - var ifBlock: Block - var elseBlock: dynamic /* Block? | IfStatement? */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isIfStatement(node: Node): Boolean - -external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: Block = definedExternally, tsOriginal: ts.Node = definedExternally): IfStatement - -external fun createIfStatement(condition: Expression, ifBlock: Block): IfStatement - -external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: Block = definedExternally): IfStatement - -external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: IfStatement = definedExternally, tsOriginal: ts.Node = definedExternally): IfStatement - -external fun createIfStatement(condition: Expression, ifBlock: Block, elseBlock: IfStatement = definedExternally): IfStatement - -external interface IterationStatement : Statement { - var body: Block -} - -external fun isIterationStatement(node: Node): Boolean - -external interface WhileStatement : IterationStatement { - var condition: Expression -} - -external fun isWhileStatement(node: Node): Boolean - -external fun createWhileStatement(body: Block, condition: Expression, tsOriginal: ts.Node = definedExternally): WhileStatement - -external interface RepeatStatement : IterationStatement { - var condition: Expression -} - -external fun isRepeatStatement(node: Node): Boolean - -external fun createRepeatStatement(body: Block, condition: Expression, tsOriginal: ts.Node = definedExternally): RepeatStatement - -external interface ForStatement : IterationStatement { - var controlVariable: Identifier - var controlVariableInitializer: Expression - var limitExpression: Expression - var stepExpression: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external fun isForStatement(node: Node): Boolean - -external fun createForStatement(body: Block, controlVariable: Identifier, controlVariableInitializer: Expression, limitExpression: Expression, stepExpression: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): ForStatement - -external interface ForInStatement : IterationStatement { - var names: Array - var expressions: Array -} - -external fun isForInStatement(node: Node): Boolean - -external fun createForInStatement(body: Block, names: Array, expressions: Array, tsOriginal: ts.Node = definedExternally): ForInStatement - -external interface GotoStatement : Statement { - var label: String -} - -external fun isGotoStatement(node: Node): Boolean - -external fun createGotoStatement(label: String, tsOriginal: ts.Node = definedExternally): GotoStatement - -external interface LabelStatement : Statement { - var name: String -} - -external fun isLabelStatement(node: Node): Boolean - -external fun createLabelStatement(name: String, tsOriginal: ts.Node = definedExternally): LabelStatement - -external interface ReturnStatement : Statement { - var expressions: Array -} - -external fun isReturnStatement(node: Node): Boolean - -external fun createReturnStatement(expressions: Array, tsOriginal: ts.Node = definedExternally): ReturnStatement - -external interface BreakStatement : Statement - -external fun isBreakStatement(node: Node): Boolean - -external fun createBreakStatement(tsOriginal: ts.Node = definedExternally): BreakStatement - -external interface ExpressionStatement : Statement { - var expression: Expression -} - -external fun isExpressionStatement(node: Node): Boolean - -external fun createExpressionStatement(expressions: Expression, tsOriginal: ts.Node = definedExternally): ExpressionStatement - -external interface Expression : Node { - var _expressionBrand: Any -} - -external interface NilLiteral : Expression - -external fun isNilLiteral(node: Node): Boolean - -external fun createNilLiteral(tsOriginal: ts.Node = definedExternally): NilLiteral - -external interface BooleanLiteral : Expression { - override var kind: dynamic /* SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isBooleanLiteral(node: Node): Boolean - -external fun createBooleanLiteral(value: Boolean, tsOriginal: ts.Node = definedExternally): BooleanLiteral - -external interface DotsLiteral : Expression - -external fun isDotsLiteral(node: Node): Boolean - -external fun createDotsLiteral(tsOriginal: ts.Node = definedExternally): DotsLiteral - -external interface NumericLiteral : Expression { - var value: Number -} - -external fun isNumericLiteral(node: Node): Boolean - -external fun createNumericLiteral(value: Number, tsOriginal: ts.Node = definedExternally): NumericLiteral - -external interface StringLiteral : Expression { - var value: String -} - -external fun isStringLiteral(node: Node): Boolean - -external fun createStringLiteral(value: String, tsOriginal: ts.Node = definedExternally): StringLiteral - -external enum class FunctionExpressionFlags { - None /* = 1 */, - Inline /* = 2 */, - Declaration /* = 4 */ -} - -external interface FunctionExpression : Expression { - var params: Array? - get() = definedExternally - set(value) = definedExternally - var dots: DotsLiteral? - get() = definedExternally - set(value) = definedExternally - var body: Block - var flags: FunctionExpressionFlags -} - -external fun isFunctionExpression(node: Node): Boolean - -external fun createFunctionExpression(body: Block, params: Array = definedExternally, dots: DotsLiteral = definedExternally, flags: FunctionExpressionFlags = definedExternally, tsOriginal: ts.Node = definedExternally): FunctionExpression - -external interface TableFieldExpression : Expression { - var value: Expression - var key: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external fun isTableFieldExpression(node: Node): Boolean - -external fun createTableFieldExpression(value: Expression, key: Expression = definedExternally, tsOriginal: ts.Node = definedExternally): TableFieldExpression - -external interface TableExpression : Expression { - var fields: Array -} - -external fun isTableExpression(node: Node): Boolean - -external fun createTableExpression(fields: Array = definedExternally, tsOriginal: ts.Node = definedExternally): TableExpression - -external interface UnaryExpression : Expression { - var operand: Expression - var operator: dynamic /* SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isUnaryExpression(node: Node): Boolean - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NegationOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NegationOperator): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.LengthOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.LengthOperator): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NotOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: SyntaxKind.NotOperator): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: UnaryBitwiseOperator, tsOriginal: ts.Node = definedExternally): UnaryExpression - -external fun createUnaryExpression(operand: Expression, operator: UnaryBitwiseOperator): UnaryExpression - -external interface BinaryExpression : Expression { - var operator: dynamic /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */ - get() = definedExternally - set(value) = definedExternally - var left: Expression - var right: Expression -} - -external fun isBinaryExpression(node: Node): Boolean - -external fun createBinaryExpression(left: Expression, right: Expression, operator: Any /* SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */, tsOriginal: ts.Node = definedExternally): BinaryExpression - -external interface CallExpression : Expression { - var expression: Expression - var params: Array -} - -external fun isCallExpression(node: Node): Boolean - -external fun createCallExpression(expression: Expression, params: Array, tsOriginal: ts.Node = definedExternally): CallExpression - -external interface MethodCallExpression : Expression { - var prefixExpression: Expression - var name: Identifier - var params: Array -} - -external fun isMethodCallExpression(node: Node): Boolean - -external fun createMethodCallExpression(prefixExpression: Expression, name: Identifier, params: Array, tsOriginal: ts.Node = definedExternally): MethodCallExpression - -external interface Identifier : Expression { - var exportable: Boolean - var text: String - var originalName: String? - get() = definedExternally - set(value) = definedExternally - var symbolId: Number? /* Number? & `T$14`? */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isIdentifier(node: Node): Boolean - -external fun createIdentifier(text: String, tsOriginal: ts.Node = definedExternally, symbolId: Number /* Number & `T$14` */ = definedExternally, originalName: String = definedExternally): Identifier - -external fun cloneIdentifier(identifier: Identifier, tsOriginal: ts.Node = definedExternally): Identifier - -external fun createAnonymousIdentifier(tsOriginal: ts.Node = definedExternally): Identifier - -external interface TableIndexExpression : Expression { - var table: Expression - var index: Expression -} - -external fun isTableIndexExpression(node: Node): Boolean - -external fun createTableIndexExpression(table: Expression, index: Expression, tsOriginal: ts.Node = definedExternally): TableIndexExpression - -external fun isAssignmentLeftHandSideExpression(node: Node): Boolean - -external fun isFunctionDefinition(statement: VariableDeclarationStatement): Boolean - -external fun isFunctionDefinition(statement: AssignmentStatement): Boolean - -external interface `T$17` { - var statements: dynamic /* JsTuple */ - get() = definedExternally - set(value) = definedExternally -} - -external fun isInlineFunctionExpression(expression: FunctionExpression): Boolean \ No newline at end of file diff --git a/modules/mod2/externals/LuaLib.module_typescript-to-lua.kt b/modules/mod2/externals/LuaLib.module_typescript-to-lua.kt deleted file mode 100644 index f00c242..0000000 --- a/modules/mod2/externals/LuaLib.module_typescript-to-lua.kt +++ /dev/null @@ -1,111 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external enum class LuaLibFeature { - ArrayConcat /* = "ArrayConcat" */, - ArrayEntries /* = "ArrayEntries" */, - ArrayEvery /* = "ArrayEvery" */, - ArrayFilter /* = "ArrayFilter" */, - ArrayForEach /* = "ArrayForEach" */, - ArrayFind /* = "ArrayFind" */, - ArrayFindIndex /* = "ArrayFindIndex" */, - ArrayIncludes /* = "ArrayIncludes" */, - ArrayIndexOf /* = "ArrayIndexOf" */, - ArrayIsArray /* = "ArrayIsArray" */, - ArrayJoin /* = "ArrayJoin" */, - ArrayMap /* = "ArrayMap" */, - ArrayPush /* = "ArrayPush" */, - ArrayReduce /* = "ArrayReduce" */, - ArrayReduceRight /* = "ArrayReduceRight" */, - ArrayReverse /* = "ArrayReverse" */, - ArrayShift /* = "ArrayShift" */, - ArrayUnshift /* = "ArrayUnshift" */, - ArraySort /* = "ArraySort" */, - ArraySlice /* = "ArraySlice" */, - ArraySome /* = "ArraySome" */, - ArraySplice /* = "ArraySplice" */, - ArrayToObject /* = "ArrayToObject" */, - ArrayFlat /* = "ArrayFlat" */, - ArrayFlatMap /* = "ArrayFlatMap" */, - ArraySetLength /* = "ArraySetLength" */, - Await /* = "Await" */, - Class /* = "Class" */, - ClassExtends /* = "ClassExtends" */, - CloneDescriptor /* = "CloneDescriptor" */, - Decorate /* = "Decorate" */, - DecorateParam /* = "DecorateParam" */, - Delete /* = "Delete" */, - DelegatedYield /* = "DelegatedYield" */, - Error /* = "Error" */, - FunctionBind /* = "FunctionBind" */, - Generator /* = "Generator" */, - InstanceOf /* = "InstanceOf" */, - InstanceOfObject /* = "InstanceOfObject" */, - Iterator /* = "Iterator" */, - Map /* = "Map" */, - MathAtan2 /* = "MathAtan2" */, - New /* = "New" */, - Number /* = "Number" */, - NumberIsFinite /* = "NumberIsFinite" */, - NumberIsNaN /* = "NumberIsNaN" */, - NumberToString /* = "NumberToString" */, - ObjectAssign /* = "ObjectAssign" */, - ObjectDefineProperty /* = "ObjectDefineProperty" */, - ObjectEntries /* = "ObjectEntries" */, - ObjectFromEntries /* = "ObjectFromEntries" */, - ObjectGetOwnPropertyDescriptor /* = "ObjectGetOwnPropertyDescriptor" */, - ObjectGetOwnPropertyDescriptors /* = "ObjectGetOwnPropertyDescriptors" */, - ObjectKeys /* = "ObjectKeys" */, - ObjectRest /* = "ObjectRest" */, - ObjectValues /* = "ObjectValues" */, - OptionalChainAccess /* = "OptionalChainAccess" */, - OptionalFunctionCall /* = "OptionalFunctionCall" */, - OptionalMethodCall /* = "OptionalMethodCall" */, - ParseFloat /* = "ParseFloat" */, - ParseInt /* = "ParseInt" */, - Promise /* = "Promise" */, - PromiseAll /* = "PromiseAll" */, - PromiseAllSettled /* = "PromiseAllSettled" */, - PromiseAny /* = "PromiseAny" */, - PromiseRace /* = "PromiseRace" */, - Set /* = "Set" */, - SetDescriptor /* = "SetDescriptor" */, - WeakMap /* = "WeakMap" */, - WeakSet /* = "WeakSet" */, - SourceMapTraceBack /* = "SourceMapTraceBack" */, - Spread /* = "Spread" */, - StringAccess /* = "StringAccess" */, - StringCharAt /* = "StringCharAt" */, - StringCharCodeAt /* = "StringCharCodeAt" */, - StringConcat /* = "StringConcat" */, - StringEndsWith /* = "StringEndsWith" */, - StringIncludes /* = "StringIncludes" */, - StringPadEnd /* = "StringPadEnd" */, - StringPadStart /* = "StringPadStart" */, - StringReplace /* = "StringReplace" */, - StringSlice /* = "StringSlice" */, - StringSplit /* = "StringSplit" */, - StringStartsWith /* = "StringStartsWith" */, - StringSubstr /* = "StringSubstr" */, - StringSubstring /* = "StringSubstring" */, - StringTrim /* = "StringTrim" */, - StringTrimEnd /* = "StringTrimEnd" */, - StringTrimStart /* = "StringTrimStart" */, - Symbol /* = "Symbol" */, - SymbolRegistry /* = "SymbolRegistry" */, - TypeOf /* = "TypeOf" */, - Unpack /* = "Unpack" */ -} \ No newline at end of file diff --git a/modules/mod2/externals/LuaPrinter.module_typescript-to-lua.kt b/modules/mod2/externals/LuaPrinter.module_typescript-to-lua.kt deleted file mode 100644 index 6428653..0000000 --- a/modules/mod2/externals/LuaPrinter.module_typescript-to-lua.kt +++ /dev/null @@ -1,101 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.Program - -external var escapeString: (value: String) -> String - -external var tstlHeader: Any - -typealias Printer = (program: Program, emitHost: EmitHost, fileName: String, file: File) -> PrintResult - -external interface PrintResult { - var code: String - var sourceMap: String - var sourceMapNode: SourceNode -} - -external fun createPrinter(printers: Array): Printer - -external open class LuaPrinter(emitHost: EmitHost, program: Program, fileName: String) { - open var emitHost: Any - open var currentIndent: Any - open var sourceFile: Any - open var options: Any - open fun print(file: File): PrintResult - open var printInlineSourceMap: Any - open var printStackTraceOverride: Any - open var printFile: Any - open fun pushIndent() - open fun popIndent() - open fun indent(input: String = definedExternally): dynamic /* String | SourceNode */ - open fun indent(): dynamic /* String | SourceNode */ - open fun indent(input: SourceNode = definedExternally): dynamic /* String | SourceNode */ - open fun createSourceNode(node: Node, chunks: String, name: String = definedExternally): SourceNode - open fun createSourceNode(node: Node, chunks: String): SourceNode - open fun createSourceNode(node: Node, chunks: SourceNode, name: String = definedExternally): SourceNode - open fun createSourceNode(node: Node, chunks: SourceNode): SourceNode - open fun createSourceNode(node: Node, chunks: Array, name: String = definedExternally): SourceNode - open fun createSourceNode(node: Node, chunks: Array): SourceNode - open fun concatNodes(vararg chunks: Any /* String | SourceNode */): SourceNode - open fun printBlock(block: Block): SourceNode - open var statementMayRequireSemiColon: Any - open var nodeStartsWithParenthesis: Any - open fun printStatementArray(statements: Array): Array - open fun printStatement(statement: Statement): SourceNode - open fun printComment(comment: String): dynamic /* String | SourceNode */ - open fun printComment(comment: Array): dynamic /* String | SourceNode */ - open fun printStatementExcludingComments(statement: Statement): SourceNode - open fun printDoStatement(statement: DoStatement): SourceNode - open fun printVariableDeclarationStatement(statement: VariableDeclarationStatement): SourceNode - open fun printVariableAssignmentStatement(statement: AssignmentStatement): SourceNode - open fun printIfStatement(statement: IfStatement, isElseIf: Boolean = definedExternally): SourceNode - open fun printWhileStatement(statement: WhileStatement): SourceNode - open fun printRepeatStatement(statement: RepeatStatement): SourceNode - open fun printForStatement(statement: ForStatement): SourceNode - open fun printForInStatement(statement: ForInStatement): SourceNode - open fun printGotoStatement(statement: GotoStatement): SourceNode - open fun printLabelStatement(statement: LabelStatement): SourceNode - open fun printReturnStatement(statement: ReturnStatement): SourceNode - open fun printBreakStatement(statement: BreakStatement): SourceNode - open fun printExpressionStatement(statement: ExpressionStatement): SourceNode - open fun printExpression(expression: Expression): SourceNode - open fun printStringLiteral(expression: StringLiteral): SourceNode - open fun printNumericLiteral(expression: NumericLiteral): SourceNode - open fun printNilLiteral(expression: NilLiteral): SourceNode - open fun printDotsLiteral(expression: DotsLiteral): SourceNode - open fun printBooleanLiteral(expression: BooleanLiteral): SourceNode - open var printFunctionParameters: Any - open fun printFunctionExpression(expression: FunctionExpression): SourceNode - open fun printFunctionDefinition(statement: Any /* VariableDeclarationStatement | AssignmentStatement */): SourceNode - open fun printTableFieldExpression(expression: TableFieldExpression): SourceNode - open fun printTableExpression(expression: TableExpression): SourceNode - open fun printUnaryExpression(expression: UnaryExpression): SourceNode - open fun printBinaryExpression(expression: BinaryExpression): SourceNode - open var printExpressionInParenthesesIfNeeded: Any - open var needsParenthesis: Any - open fun printCallExpression(expression: CallExpression): SourceNode - open fun printMethodCallExpression(expression: MethodCallExpression): SourceNode - open fun printIdentifier(expression: Identifier): SourceNode - open fun printTableIndexExpression(expression: TableIndexExpression): SourceNode - open fun printOperator(kind: Any /* SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator | SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator | SyntaxKind.OrOperator | SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator */): SourceNode - open fun joinChunksWithComma(chunks: Array): Array - open fun printExpressionList(expressions: Array): Array - open var buildSourceMap: Any - - companion object { - var operatorMap: Any - } -} \ No newline at end of file diff --git a/modules/mod2/externals/context.module_typescript-to-lua.kt b/modules/mod2/externals/context.module_typescript-to-lua.kt deleted file mode 100644 index 3c6d078..0000000 --- a/modules/mod2/externals/context.module_typescript-to-lua.kt +++ /dev/null @@ -1,80 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.GetAccessorDeclaration -import ts.SetAccessorDeclaration -import ts.Node -import ts.ImportEqualsDeclaration -import ts.Expression -import ts.SourceFile -import ts.CancellationToken -import ts.TypeChecker -import ts.Program -import ts.Diagnostic -import ts.CompilerOptions -import Node as _Node -import Expression as _Expression -import ts.QualifiedName -import ts.ExternalModuleReference - -external interface AllAccessorDeclarations { - var firstAccessor: dynamic /* GetAccessorDeclaration | SetAccessorDeclaration */ - get() = definedExternally - set(value) = definedExternally - var secondAccessor: dynamic /* GetAccessorDeclaration? | SetAccessorDeclaration? */ - get() = definedExternally - set(value) = definedExternally - var getAccessor: GetAccessorDeclaration? - var setAccessor: SetAccessorDeclaration? -} - -external interface EmitResolver { - fun isValueAliasDeclaration(node: Node): Boolean - fun isReferencedAliasDeclaration(node: Node, checkChildren: Boolean = definedExternally): Boolean - fun isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): Boolean - fun moduleExportsSomeValue(moduleReferenceExpression: Expression): Boolean - fun getAllAccessorDeclarations(declaration: GetAccessorDeclaration): AllAccessorDeclarations - fun getAllAccessorDeclarations(declaration: SetAccessorDeclaration): AllAccessorDeclarations -} - -external interface DiagnosticsProducingTypeChecker : TypeChecker { - fun getEmitResolver(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): EmitResolver -} - -external open class TransformationContext(program: Program, sourceFile: SourceFile, visitorMap: VisitorMap) { - open var program: Program - open var sourceFile: SourceFile - open var visitorMap: Any - open var diagnostics: Array - open var checker: DiagnosticsProducingTypeChecker - open var resolver: EmitResolver - open var options: OmitIndexSignature /* OmitIndexSignature & `T$0` */ - open var luaTarget: LuaTarget - open var isModule: Boolean - open var isStrict: Boolean - open var currentNodeVisitors: Any - open fun transformNode(node: Node): Array<_Node> - open fun superTransformNode(node: Node): Array<_Node> - open fun transformExpression(node: Expression): _Expression - open fun transformExpression(node: QualifiedName): _Expression - open fun transformExpression(node: ExternalModuleReference): _Expression - open fun superTransformExpression(node: Expression): _Expression - open fun superTransformExpression(node: QualifiedName): _Expression - open fun superTransformExpression(node: ExternalModuleReference): _Expression - open fun transformStatements(node: StatementLikeNode): Array - open fun transformStatements(node: Array): Array - open fun superTransformStatements(node: StatementLikeNode): Array - open fun superTransformStatements(node: Array): Array -} \ No newline at end of file diff --git a/modules/mod2/externals/index.module_typescript-to-lua.kt b/modules/mod2/externals/index.module_typescript-to-lua.kt deleted file mode 100644 index 0de0447..0000000 --- a/modules/mod2/externals/index.module_typescript-to-lua.kt +++ /dev/null @@ -1,39 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.CompilerOptions -import ts.WriteFileCallback -import ts.Diagnostic -import tsstdlib.Record - -external fun transpileFiles(rootNames: Array, options: OmitIndexSignature /* OmitIndexSignature & `T$0` */ = definedExternally, writeFile: WriteFileCallback = definedExternally): EmitResult - -external fun transpileProject(configFileName: String, optionsToExtend: OmitIndexSignature /* OmitIndexSignature & `T$0` */ = definedExternally, writeFile: WriteFileCallback = definedExternally): EmitResult - -external interface TranspileVirtualProjectResult { - var diagnostics: Array - var transpiledFiles: Array -} - -external fun transpileVirtualProject(files: Record, options: OmitIndexSignature /* OmitIndexSignature & `T$0` */ = definedExternally): TranspileVirtualProjectResult - -external interface TranspileStringResult { - var diagnostics: Array - var file: TranspiledFile? - get() = definedExternally - set(value) = definedExternally -} - -external fun transpileString(main: String, options: OmitIndexSignature /* OmitIndexSignature & `T$0` */ = definedExternally): TranspileStringResult \ No newline at end of file diff --git a/modules/mod2/externals/lib.es2015.collection.kt b/modules/mod2/externals/lib.es2015.collection.kt deleted file mode 100644 index 8d138d8..0000000 --- a/modules/mod2/externals/lib.es2015.collection.kt +++ /dev/null @@ -1,49 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface Map { - fun entries(): IterableIterator */> - fun keys(): IterableIterator - fun values(): IterableIterator - fun clear() - fun delete(key: K): Boolean - fun forEach(callbackfn: (value: V, key: K, map: Map) -> Unit, thisArg: Any = definedExternally) - fun get(key: K): V? - fun has(key: K): Boolean - fun set(key: K, value: V): Map /* this */ - var size: Number -} - -external interface MapConstructor { - var prototype: Map -} - -external interface Set { - fun entries(): IterableIterator */> - fun keys(): IterableIterator - fun values(): IterableIterator - fun add(value: T): Set /* this */ - fun clear() - fun delete(value: T): Boolean - fun forEach(callbackfn: (value: T, value2: T, set: Set) -> Unit, thisArg: Any = definedExternally) - fun has(value: T): Boolean - var size: Number -} - -external interface SetConstructor { - var prototype: Set -} \ No newline at end of file diff --git a/modules/mod2/externals/lib.es2015.iterable.kt b/modules/mod2/externals/lib.es2015.iterable.kt deleted file mode 100644 index 57fb640..0000000 --- a/modules/mod2/externals/lib.es2015.iterable.kt +++ /dev/null @@ -1,54 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface IteratorYieldResult { - var done: Boolean? - get() = definedExternally - set(value) = definedExternally - var value: TYield -} - -external interface IteratorReturnResult { - var done: Boolean - var value: TReturn -} - -external interface Iterator { - fun next(vararg args: Any /* JsTuple<> | JsTuple */): dynamic /* IteratorYieldResult | IteratorReturnResult */ - val `return`: ((value: TReturn) -> dynamic)? - val `throw`: ((e: Any) -> dynamic)? -} - -typealias Iterator__1 = Iterator - -external interface Iterable - -external interface IterableIterator : Iterator__1 - -external interface PromiseConstructor { - var prototype: Promise - fun all(values: Any /* JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple */): Promise | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple | JsTuple */> - fun all(values: Array */>): Promise> - fun race(values: Array): Promise - fun reject(reason: Any = definedExternally): Promise - fun resolve(value: T): Promise - fun resolve(value: PromiseLike): Promise - fun resolve(): Promise - fun all(values: Iterable */>): Promise> - fun race(values: Iterable): Promise - fun race(values: Iterable */>): Promise -} \ No newline at end of file diff --git a/modules/mod2/externals/lib.es5.Intl.module_dukat.kt b/modules/mod2/externals/lib.es5.Intl.module_dukat.kt deleted file mode 100644 index 62cbcc7..0000000 --- a/modules/mod2/externals/lib.es5.Intl.module_dukat.kt +++ /dev/null @@ -1,220 +0,0 @@ -@file:JsQualifier("tsstdlib.Intl") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib.Intl - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface CollatorOptions { - var usage: String? - get() = definedExternally - set(value) = definedExternally - var localeMatcher: String? - get() = definedExternally - set(value) = definedExternally - var numeric: Boolean? - get() = definedExternally - set(value) = definedExternally - var caseFirst: String? - get() = definedExternally - set(value) = definedExternally - var sensitivity: String? - get() = definedExternally - set(value) = definedExternally - var ignorePunctuation: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedCollatorOptions { - var locale: String - var usage: String - var sensitivity: String - var ignorePunctuation: Boolean - var collation: String - var caseFirst: String - var numeric: Boolean -} - -@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") -external interface Collator { - fun compare(x: String, y: String): Number - fun resolvedOptions(): ResolvedCollatorOptions - - companion object { - @nativeInvoke - operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: CollatorOptions = definedExternally): Collator - fun supportedLocalesOf(locales: Any /* String | Array */, options: CollatorOptions = definedExternally): Array - } -} - -external interface NumberFormatOptions { - var localeMatcher: String? - get() = definedExternally - set(value) = definedExternally - var style: String? - get() = definedExternally - set(value) = definedExternally - var currency: String? - get() = definedExternally - set(value) = definedExternally - var currencyDisplay: String? - get() = definedExternally - set(value) = definedExternally - var useGrouping: Boolean? - get() = definedExternally - set(value) = definedExternally - var minimumIntegerDigits: Number? - get() = definedExternally - set(value) = definedExternally - var minimumFractionDigits: Number? - get() = definedExternally - set(value) = definedExternally - var maximumFractionDigits: Number? - get() = definedExternally - set(value) = definedExternally - var minimumSignificantDigits: Number? - get() = definedExternally - set(value) = definedExternally - var maximumSignificantDigits: Number? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedNumberFormatOptions { - var locale: String - var numberingSystem: String - var style: String - var currency: String? - get() = definedExternally - set(value) = definedExternally - var currencyDisplay: String? - get() = definedExternally - set(value) = definedExternally - var minimumIntegerDigits: Number - var minimumFractionDigits: Number - var maximumFractionDigits: Number - var minimumSignificantDigits: Number? - get() = definedExternally - set(value) = definedExternally - var maximumSignificantDigits: Number? - get() = definedExternally - set(value) = definedExternally - var useGrouping: Boolean -} - -@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") -external interface NumberFormat { - fun format(value: Number): String - fun resolvedOptions(): ResolvedNumberFormatOptions - - companion object { - @nativeInvoke - operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: NumberFormatOptions = definedExternally): NumberFormat - fun supportedLocalesOf(locales: Any /* String | Array */, options: NumberFormatOptions = definedExternally): Array - } -} - -external interface DateTimeFormatOptions { - var localeMatcher: String? - get() = definedExternally - set(value) = definedExternally - var weekday: String? - get() = definedExternally - set(value) = definedExternally - var era: String? - get() = definedExternally - set(value) = definedExternally - var year: String? - get() = definedExternally - set(value) = definedExternally - var month: String? - get() = definedExternally - set(value) = definedExternally - var day: String? - get() = definedExternally - set(value) = definedExternally - var hour: String? - get() = definedExternally - set(value) = definedExternally - var minute: String? - get() = definedExternally - set(value) = definedExternally - var second: String? - get() = definedExternally - set(value) = definedExternally - var timeZoneName: String? - get() = definedExternally - set(value) = definedExternally - var formatMatcher: String? - get() = definedExternally - set(value) = definedExternally - var hour12: Boolean? - get() = definedExternally - set(value) = definedExternally - var timeZone: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedDateTimeFormatOptions { - var locale: String - var calendar: String - var numberingSystem: String - var timeZone: String - var hour12: Boolean? - get() = definedExternally - set(value) = definedExternally - var weekday: String? - get() = definedExternally - set(value) = definedExternally - var era: String? - get() = definedExternally - set(value) = definedExternally - var year: String? - get() = definedExternally - set(value) = definedExternally - var month: String? - get() = definedExternally - set(value) = definedExternally - var day: String? - get() = definedExternally - set(value) = definedExternally - var hour: String? - get() = definedExternally - set(value) = definedExternally - var minute: String? - get() = definedExternally - set(value) = definedExternally - var second: String? - get() = definedExternally - set(value) = definedExternally - var timeZoneName: String? - get() = definedExternally - set(value) = definedExternally -} - -@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") -external interface DateTimeFormat { - fun format(date: Date = definedExternally): String - fun format(): String - fun format(date: Number = definedExternally): String - fun resolvedOptions(): ResolvedDateTimeFormatOptions - - companion object { - @nativeInvoke - operator fun invoke(locales: Any /* String | Array */ = definedExternally, options: DateTimeFormatOptions = definedExternally): DateTimeFormat - fun supportedLocalesOf(locales: Any /* String | Array */, options: DateTimeFormatOptions = definedExternally): Array - } -} \ No newline at end of file diff --git a/modules/mod2/externals/lib.es5.kt b/modules/mod2/externals/lib.es5.kt deleted file mode 100644 index a143da0..0000000 --- a/modules/mod2/externals/lib.es5.kt +++ /dev/null @@ -1,69 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface DateConstructor { - @nativeInvoke - operator fun invoke(): String - var prototype: Date - fun parse(s: String): Number - fun UTC(year: Number, month: Number, date: Number = definedExternally, hours: Number = definedExternally, minutes: Number = definedExternally, seconds: Number = definedExternally, ms: Number = definedExternally): Number - fun now(): Number -} - -external interface ConcatArray { - var length: Number - @nativeGetter - operator fun get(n: Number): T? - @nativeSetter - operator fun set(n: Number, value: T) - fun join(separator: String = definedExternally): String - fun slice(start: Number = definedExternally, end: Number = definedExternally): Array -} - -external interface ArrayConstructor { - fun from(iterable: Iterable): Array - fun from(iterable: ArrayLike): Array - fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array - fun from(iterable: Iterable, mapfn: (v: T, k: Number) -> U): Array - fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U, thisArg: Any = definedExternally): Array - fun from(iterable: ArrayLike, mapfn: (v: T, k: Number) -> U): Array - fun of(vararg items: T): Array - @nativeInvoke - operator fun invoke(arrayLength: Number = definedExternally): Array - @nativeInvoke - operator fun invoke(): Array - @nativeInvoke - operator fun invoke(arrayLength: Number): Array - @nativeInvoke - operator fun invoke(vararg items: T): Array - fun isArray(arg: Any): Boolean - var prototype: Array -} - -external interface PromiseLike { - fun then(onfulfilled: ((value: T) -> Any?)? = definedExternally, onrejected: ((reason: Any) -> Any?)? = definedExternally): PromiseLike -} - -external interface ArrayLike { - var length: Number - @nativeGetter - operator fun get(n: Number): T? - @nativeSetter - operator fun set(n: Number, value: T) -} - -typealias Record = Any \ No newline at end of file diff --git a/modules/mod2/externals/lib.scripthost.kt b/modules/mod2/externals/lib.scripthost.kt deleted file mode 100644 index 809347e..0000000 --- a/modules/mod2/externals/lib.scripthost.kt +++ /dev/null @@ -1,20 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package tsstdlib - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external open class VarDate { - open var VarDate_typekey: VarDate -} \ No newline at end of file diff --git a/modules/mod2/externals/nonDeclarations.ts.kt b/modules/mod2/externals/nonDeclarations.ts.kt deleted file mode 100644 index 3650dca..0000000 --- a/modules/mod2/externals/nonDeclarations.ts.kt +++ /dev/null @@ -1,114 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package ts - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -typealias SortedReadonlyArray = Array - -typealias SortedArray = Array - -typealias NodeArray = Array - -typealias DotToken = PunctuationToken - -typealias DotDotDotToken = PunctuationToken - -typealias QuestionToken = PunctuationToken - -typealias ExclamationToken = PunctuationToken - -typealias ColonToken = PunctuationToken - -typealias EqualsToken = PunctuationToken - -typealias AsteriskToken = PunctuationToken - -typealias EqualsGreaterThanToken = PunctuationToken - -typealias PlusToken = PunctuationToken - -typealias MinusToken = PunctuationToken - -typealias QuestionDotToken = PunctuationToken - -typealias AssertsKeyword = KeywordToken - -typealias AwaitKeyword = KeywordToken - -typealias AwaitKeywordToken = AwaitKeyword - -typealias AssertsToken = AssertsKeyword - -typealias AbstractKeyword = ModifierToken - -typealias AsyncKeyword = ModifierToken - -typealias ConstKeyword = ModifierToken - -typealias DeclareKeyword = ModifierToken - -typealias DefaultKeyword = ModifierToken - -typealias ExportKeyword = ModifierToken - -typealias PrivateKeyword = ModifierToken - -typealias ProtectedKeyword = ModifierToken - -typealias PublicKeyword = ModifierToken - -typealias ReadonlyKeyword = ModifierToken - -typealias OverrideKeyword = ModifierToken - -typealias StaticKeyword = ModifierToken - -typealias ReadonlyToken = ReadonlyKeyword - -typealias ModifiersArray = NodeArray - -typealias IncrementExpression = UpdateExpression - -typealias ExponentiationOperator = SyntaxKind.AsteriskAsteriskToken - -typealias BinaryOperatorToken = Token - -typealias AssignmentOperatorToken = Token - -typealias FunctionBody = Block - -typealias WriteFileCallback = (fileName: String, data: String, writeByteOrderMark: Boolean, onError: (message: String) -> Unit, sourceFiles: Array) -> Unit - -typealias CustomTransformerFactory = (context: TransformationContext) -> CustomTransformer - -typealias SymbolTable = UnderscoreEscapedMap - -typealias JsFileExtensionInfo = FileExtensionInfo - -typealias EmitHelperUniqueNameCallback = (name: String) -> String - -typealias TransformerFactory = (context: TransformationContext) -> Transformer - -typealias Transformer = (node: T) -> T - -typealias Visitor = (node: Node) -> dynamic - -typealias FileWatcherCallback = (fileName: String, eventKind: FileWatcherEventKind) -> Unit - -typealias DirectoryWatcherCallback = (fileName: String) -> Unit - -typealias DiagnosticReporter = (diagnostic: Diagnostic) -> Unit - -typealias CodeActionCommand = InstallPackageAction \ No newline at end of file diff --git a/modules/mod2/externals/output-collector.module_typescript-to-lua.kt b/modules/mod2/externals/output-collector.module_typescript-to-lua.kt deleted file mode 100644 index 0c57eac..0000000 --- a/modules/mod2/externals/output-collector.module_typescript-to-lua.kt +++ /dev/null @@ -1,33 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.SourceFile - -external interface TranspiledFile { - var outPath: String - var sourceFiles: Array - var lua: String? - get() = definedExternally - set(value) = definedExternally - var luaSourceMap: String? - get() = definedExternally - set(value) = definedExternally - var declaration: String? - get() = definedExternally - set(value) = definedExternally - var declarationMap: String? - get() = definedExternally - set(value) = definedExternally -} \ No newline at end of file diff --git a/modules/mod2/externals/parse.module_typescript-to-lua.kt b/modules/mod2/externals/parse.module_typescript-to-lua.kt deleted file mode 100644 index 052faf7..0000000 --- a/modules/mod2/externals/parse.module_typescript-to-lua.kt +++ /dev/null @@ -1,21 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface ParsedCommandLine : ts.ParsedCommandLine - -external fun updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine - -external fun parseCommandLine(args: Array): ParsedCommandLine \ No newline at end of file diff --git a/modules/mod2/externals/plugins.module_typescript-to-lua.kt b/modules/mod2/externals/plugins.module_typescript-to-lua.kt deleted file mode 100644 index 24d3ea4..0000000 --- a/modules/mod2/externals/plugins.module_typescript-to-lua.kt +++ /dev/null @@ -1,24 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external interface Plugin { - var visitors: Visitors? - get() = definedExternally - set(value) = definedExternally - var printer: Printer? - get() = definedExternally - set(value) = definedExternally -} \ No newline at end of file diff --git a/modules/mod2/externals/report.module_typescript-to-lua.kt b/modules/mod2/externals/report.module_typescript-to-lua.kt deleted file mode 100644 index f1582a6..0000000 --- a/modules/mod2/externals/report.module_typescript-to-lua.kt +++ /dev/null @@ -1,48 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.DiagnosticRelatedInformation -import ts.DiagnosticCategory -import ts.SourceFile -import ts.Diagnostic -import ts.System -import ts.DiagnosticReporter - -external interface `T$13` { - var code: Any - var reportsUnnecessary: Any? - get() = definedExternally - set(value) = definedExternally - var reportsDeprecated: Any? - get() = definedExternally - set(value) = definedExternally - var source: String? - get() = definedExternally - set(value) = definedExternally - var relatedInformation: Array? - get() = definedExternally - set(value) = definedExternally - var category: DiagnosticCategory - var file: SourceFile? - var start: Number? - var length: Number? - var messageText: dynamic /* String | ts.DiagnosticMessageChain */ - get() = definedExternally - set(value) = definedExternally -} - -external var prepareDiagnosticForFormatting: (diagnostic: Diagnostic) -> `T$13` - -external fun createDiagnosticReporter(pretty: Boolean, system: System = definedExternally): DiagnosticReporter \ No newline at end of file diff --git a/modules/mod2/externals/source-map.module_source-map.kt b/modules/mod2/externals/source-map.module_source-map.kt deleted file mode 100644 index 6880a36..0000000 --- a/modules/mod2/externals/source-map.module_source-map.kt +++ /dev/null @@ -1,192 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -typealias SourceMapUrl = String - -external interface StartOfSourceMap { - var file: String? - get() = definedExternally - set(value) = definedExternally - var sourceRoot: String? - get() = definedExternally - set(value) = definedExternally - var skipValidation: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface RawSourceMap { - var version: Number - var sources: Array - var names: Array - var sourceRoot: String? - get() = definedExternally - set(value) = definedExternally - var sourcesContent: Array? - get() = definedExternally - set(value) = definedExternally - var mappings: String - var file: String -} - -external interface RawIndexMap : StartOfSourceMap { - var version: Number - var sections: Array -} - -external interface RawSection { - var offset: Position - var map: RawSourceMap -} - -external interface Position { - var line: Number - var column: Number -} - -external interface NullablePosition { - var line: Number? - var column: Number? - var lastColumn: Number? -} - -external interface MappedPosition { - var source: String - var line: Number - var column: Number - var name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface NullableMappedPosition { - var source: String? - var line: Number? - var column: Number? - var name: String? -} - -external interface MappingItem { - var source: String - var generatedLine: Number - var generatedColumn: Number - var originalLine: Number - var originalColumn: Number - var name: String -} - -external interface Mapping { - var generated: Position - var original: Position - var source: String - var name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface CodeWithSourceMap { - var code: String - var map: SourceMapGenerator -} - -external interface SourceMapConsumer { - fun computeColumnSpans() - fun originalPositionFor(generatedPosition: Position /* Position & `T$19` */): NullableMappedPosition - fun generatedPositionFor(originalPosition: MappedPosition /* MappedPosition & `T$19` */): NullablePosition - fun allGeneratedPositionsFor(originalPosition: MappedPosition): Array - fun hasContentsOfAllSources(): Boolean - fun sourceContentFor(source: String, returnNullOnMissing: Boolean = definedExternally): String? - fun eachMapping(callback: (mapping: MappingItem) -> Unit, context: Any = definedExternally, order: Number = definedExternally) - fun destroy() -} - -external interface SourceMapConsumerConstructor { - var prototype: SourceMapConsumer - var GENERATED_ORDER: Number - var ORIGINAL_ORDER: Number - var GREATEST_LOWER_BOUND: Number - var LEAST_UPPER_BOUND: Number - fun fromSourceMap(sourceMap: SourceMapGenerator, sourceMapUrl: SourceMapUrl = definedExternally): Promise - fun with(rawSourceMap: RawSourceMap, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise - fun with(rawSourceMap: RawIndexMap, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise - fun with(rawSourceMap: String, sourceMapUrl: SourceMapUrl?, callback: (consumer: Any /* BasicSourceMapConsumer | IndexedSourceMapConsumer */) -> Any?): Promise -} - -external interface BasicSourceMapConsumer : SourceMapConsumer { - var file: String - var sourceRoot: String - var sources: Array - var sourcesContent: Array -} - -external interface BasicSourceMapConsumerConstructor { - var prototype: BasicSourceMapConsumer - fun fromSourceMap(sourceMap: SourceMapGenerator): Promise -} - -external interface IndexedSourceMapConsumer : SourceMapConsumer { - var sources: Array -} - -external interface IndexedSourceMapConsumerConstructor { - var prototype: IndexedSourceMapConsumer -} - -external open class SourceMapGenerator(startOfSourceMap: StartOfSourceMap = definedExternally) { - open fun addMapping(mapping: Mapping) - open fun setSourceContent(sourceFile: String, sourceContent: String) - open fun applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile: String = definedExternally, sourceMapPath: String = definedExternally) - override fun toString(): String - open fun toJSON(): RawSourceMap - - companion object { - fun fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator - } -} - -external open class SourceNode { - open var children: Array - open var sourceContents: Any - open var line: Number - open var column: Number - open var source: String - open var name: String - constructor() - constructor(line: Number?, column: Number?, source: String?, chunks: Array = definedExternally, name: String = definedExternally) - constructor(line: Number?, column: Number?, source: String?) - constructor(line: Number?, column: Number?, source: String?, chunks: Array = definedExternally) - constructor(line: Number?, column: Number?, source: String?, chunks: SourceNode = definedExternally, name: String = definedExternally) - constructor(line: Number?, column: Number?, source: String?, chunks: SourceNode = definedExternally) - constructor(line: Number?, column: Number?, source: String?, chunks: String = definedExternally, name: String = definedExternally) - constructor(line: Number?, column: Number?, source: String?, chunks: String = definedExternally) - open fun add(chunk: Array): SourceNode - open fun add(chunk: SourceNode): SourceNode - open fun add(chunk: String): SourceNode - open fun prepend(chunk: Array): SourceNode - open fun prepend(chunk: SourceNode): SourceNode - open fun prepend(chunk: String): SourceNode - open fun setSourceContent(sourceFile: String, sourceContent: String) - open fun walk(fn: (chunk: String, mapping: MappedPosition) -> Unit) - open fun walkSourceContents(fn: (file: String, content: String) -> Unit) - open fun join(sep: String): SourceNode - open fun replaceRight(pattern: String, replacement: String): SourceNode - override fun toString(): String - open fun toStringWithSourceMap(startOfSourceMap: StartOfSourceMap = definedExternally): CodeWithSourceMap - - companion object { - fun fromStringWithSourceMap(code: String, sourceMapConsumer: SourceMapConsumer, relativePath: String = definedExternally): SourceNode - } -} \ No newline at end of file diff --git a/modules/mod2/externals/transpile.module_typescript-to-lua.kt b/modules/mod2/externals/transpile.module_typescript-to-lua.kt deleted file mode 100644 index 8681706..0000000 --- a/modules/mod2/externals/transpile.module_typescript-to-lua.kt +++ /dev/null @@ -1,40 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.Program -import ts.SourceFile -import ts.CustomTransformers -import ts.Diagnostic -import ts.WriteFileCallback - -external interface TranspileOptions { - var program: Program - var sourceFiles: Array? - get() = definedExternally - set(value) = definedExternally - var customTransformers: CustomTransformers? - get() = definedExternally - set(value) = definedExternally - var plugins: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface TranspileResult { - var diagnostics: Array - var transpiledFiles: Array -} - -external fun getProgramTranspileResult(emitHost: EmitHost, writeFileResult: WriteFileCallback, __2: TranspileOptions): TranspileResult \ No newline at end of file diff --git a/modules/mod2/externals/transpiler.module_typescript-to-lua.kt b/modules/mod2/externals/transpiler.module_typescript-to-lua.kt deleted file mode 100644 index 16b18b0..0000000 --- a/modules/mod2/externals/transpiler.module_typescript-to-lua.kt +++ /dev/null @@ -1,55 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.WriteFileCallback -import ts.Diagnostic -import ts.Program - -external interface TranspilerOptions { - var emitHost: EmitHost? - get() = definedExternally - set(value) = definedExternally -} - -external interface EmitOptions : TranspileOptions { - var writeFile: WriteFileCallback? - get() = definedExternally - set(value) = definedExternally -} - -external interface EmitResult { - var emitSkipped: Boolean - var diagnostics: Array -} - -external interface `T$20` { - var emitPlan: Array -} - -external open class Transpiler(__0: TranspilerOptions = definedExternally) { - open var emitHost: EmitHost - open fun emit(emitOptions: EmitOptions): EmitResult - open fun getEmitPlan(program: Program, diagnostics: Array, files: Array): `T$20` -} - -external fun getEmitPath(file: String, program: Program): String - -external fun getEmitPathRelativeToOutDir(fileName: String, program: Program): String - -external fun getSourceDir(program: Program): String - -external fun getEmitOutDir(program: Program): String - -external fun getProjectRoot(program: Program): String \ No newline at end of file diff --git a/modules/mod2/externals/tsconfig.module_typescript-to-lua.kt b/modules/mod2/externals/tsconfig.module_typescript-to-lua.kt deleted file mode 100644 index 8eadae2..0000000 --- a/modules/mod2/externals/tsconfig.module_typescript-to-lua.kt +++ /dev/null @@ -1,19 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.CompilerOptions -import ts.System - -external fun parseConfigFileWithSystem(configFileName: String, commandLineOptions: OmitIndexSignature /* OmitIndexSignature & `T$0` */ = definedExternally, system: System = definedExternally): ParsedCommandLine \ No newline at end of file diff --git a/modules/mod2/externals/typescript.module_typescript.kt b/modules/mod2/externals/typescript.module_typescript.kt deleted file mode 100644 index 83261af..0000000 --- a/modules/mod2/externals/typescript.module_typescript.kt +++ /dev/null @@ -1,19 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external fun setTimeout(handler: (args: Any) -> Unit, timeout: Number): Any - -external fun clearTimeout(handle: Any) \ No newline at end of file diff --git a/modules/mod2/externals/typescript.ts.ScriptSnapshot.module_typescript.kt b/modules/mod2/externals/typescript.ts.ScriptSnapshot.module_typescript.kt deleted file mode 100644 index acab3da..0000000 --- a/modules/mod2/externals/typescript.ts.ScriptSnapshot.module_typescript.kt +++ /dev/null @@ -1,20 +0,0 @@ -@file:JsQualifier("ts.ScriptSnapshot") -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package ts.ScriptSnapshot - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.IScriptSnapshot - -external fun fromString(text: String): IScriptSnapshot \ No newline at end of file diff --git a/modules/mod2/externals/typescript.ts.module_typescript.kt b/modules/mod2/externals/typescript.ts.module_typescript.kt deleted file mode 100644 index 73cc27f..0000000 --- a/modules/mod2/externals/typescript.ts.module_typescript.kt +++ /dev/null @@ -1,8487 +0,0 @@ -@file:JsModule("typescript") -@file:JsNonModule -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package ts - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* - -external var versionMajorMinor: Any - -external var version: String - -external interface MapLike { - @nativeGetter - operator fun get(index: String): T? - @nativeSetter - operator fun set(index: String, value: T) -} - -external interface ReadonlyCollection { - var size: Number - fun has(key: K): Boolean - fun keys(): Iterator -} - -external interface Collection : ReadonlyCollection { - fun delete(key: K): Boolean - fun clear() -} - -external interface ReadonlyESMap : ReadonlyCollection { - fun get(key: K): V? - fun values(): Iterator - fun entries(): Iterator */> - fun forEach(action: (value: V, key: K) -> Unit) -} - -external interface ReadonlyMap : ReadonlyESMap - -external interface ESMap : ReadonlyESMap, Collection { - fun set(key: K, value: V): ESMap /* this */ -} - -external interface Map : ESMap - -external interface ReadonlySet : ReadonlyCollection { - override fun has(value: T): Boolean - fun values(): Iterator - fun entries(): Iterator */> - fun forEach(action: (value: T, key: T) -> Unit) -} - -external interface Set : ReadonlySet, Collection { - fun add(value: T): Set /* this */ - override fun delete(value: T): Boolean -} - -external interface Iterator { - fun next(): dynamic /* `T$1` | `T$2` */ -} - -external interface Push { - fun push(vararg values: T) -} - -external interface TextRange { - var pos: Number - var end: Number -} - -external interface ReadonlyTextRange { - var pos: Number - var end: Number -} - -external enum class SyntaxKind { - Unknown /* = 0 */, - EndOfFileToken /* = 1 */, - SingleLineCommentTrivia /* = 2 */, - MultiLineCommentTrivia /* = 3 */, - NewLineTrivia /* = 4 */, - WhitespaceTrivia /* = 5 */, - ShebangTrivia /* = 6 */, - ConflictMarkerTrivia /* = 7 */, - NumericLiteral /* = 8 */, - BigIntLiteral /* = 9 */, - StringLiteral /* = 10 */, - JsxText /* = 11 */, - JsxTextAllWhiteSpaces /* = 12 */, - RegularExpressionLiteral /* = 13 */, - NoSubstitutionTemplateLiteral /* = 14 */, - TemplateHead /* = 15 */, - TemplateMiddle /* = 16 */, - TemplateTail /* = 17 */, - OpenBraceToken /* = 18 */, - CloseBraceToken /* = 19 */, - OpenParenToken /* = 20 */, - CloseParenToken /* = 21 */, - OpenBracketToken /* = 22 */, - CloseBracketToken /* = 23 */, - DotToken /* = 24 */, - DotDotDotToken /* = 25 */, - SemicolonToken /* = 26 */, - CommaToken /* = 27 */, - QuestionDotToken /* = 28 */, - LessThanToken /* = 29 */, - LessThanSlashToken /* = 30 */, - GreaterThanToken /* = 31 */, - LessThanEqualsToken /* = 32 */, - GreaterThanEqualsToken /* = 33 */, - EqualsEqualsToken /* = 34 */, - ExclamationEqualsToken /* = 35 */, - EqualsEqualsEqualsToken /* = 36 */, - ExclamationEqualsEqualsToken /* = 37 */, - EqualsGreaterThanToken /* = 38 */, - PlusToken /* = 39 */, - MinusToken /* = 40 */, - AsteriskToken /* = 41 */, - AsteriskAsteriskToken /* = 42 */, - SlashToken /* = 43 */, - PercentToken /* = 44 */, - PlusPlusToken /* = 45 */, - MinusMinusToken /* = 46 */, - LessThanLessThanToken /* = 47 */, - GreaterThanGreaterThanToken /* = 48 */, - GreaterThanGreaterThanGreaterThanToken /* = 49 */, - AmpersandToken /* = 50 */, - BarToken /* = 51 */, - CaretToken /* = 52 */, - ExclamationToken /* = 53 */, - TildeToken /* = 54 */, - AmpersandAmpersandToken /* = 55 */, - BarBarToken /* = 56 */, - QuestionToken /* = 57 */, - ColonToken /* = 58 */, - AtToken /* = 59 */, - QuestionQuestionToken /* = 60 */, - BacktickToken /* = 61 */, - HashToken /* = 62 */, - EqualsToken /* = 63 */, - PlusEqualsToken /* = 64 */, - MinusEqualsToken /* = 65 */, - AsteriskEqualsToken /* = 66 */, - AsteriskAsteriskEqualsToken /* = 67 */, - SlashEqualsToken /* = 68 */, - PercentEqualsToken /* = 69 */, - LessThanLessThanEqualsToken /* = 70 */, - GreaterThanGreaterThanEqualsToken /* = 71 */, - GreaterThanGreaterThanGreaterThanEqualsToken /* = 72 */, - AmpersandEqualsToken /* = 73 */, - BarEqualsToken /* = 74 */, - BarBarEqualsToken /* = 75 */, - AmpersandAmpersandEqualsToken /* = 76 */, - QuestionQuestionEqualsToken /* = 77 */, - CaretEqualsToken /* = 78 */, - Identifier /* = 79 */, - PrivateIdentifier /* = 80 */, - BreakKeyword /* = 81 */, - CaseKeyword /* = 82 */, - CatchKeyword /* = 83 */, - ClassKeyword /* = 84 */, - ConstKeyword /* = 85 */, - ContinueKeyword /* = 86 */, - DebuggerKeyword /* = 87 */, - DefaultKeyword /* = 88 */, - DeleteKeyword /* = 89 */, - DoKeyword /* = 90 */, - ElseKeyword /* = 91 */, - EnumKeyword /* = 92 */, - ExportKeyword /* = 93 */, - ExtendsKeyword /* = 94 */, - FalseKeyword /* = 95 */, - FinallyKeyword /* = 96 */, - ForKeyword /* = 97 */, - FunctionKeyword /* = 98 */, - IfKeyword /* = 99 */, - ImportKeyword /* = 100 */, - InKeyword /* = 101 */, - InstanceOfKeyword /* = 102 */, - NewKeyword /* = 103 */, - NullKeyword /* = 104 */, - ReturnKeyword /* = 105 */, - SuperKeyword /* = 106 */, - SwitchKeyword /* = 107 */, - ThisKeyword /* = 108 */, - ThrowKeyword /* = 109 */, - TrueKeyword /* = 110 */, - TryKeyword /* = 111 */, - TypeOfKeyword /* = 112 */, - VarKeyword /* = 113 */, - VoidKeyword /* = 114 */, - WhileKeyword /* = 115 */, - WithKeyword /* = 116 */, - ImplementsKeyword /* = 117 */, - InterfaceKeyword /* = 118 */, - LetKeyword /* = 119 */, - PackageKeyword /* = 120 */, - PrivateKeyword /* = 121 */, - ProtectedKeyword /* = 122 */, - PublicKeyword /* = 123 */, - StaticKeyword /* = 124 */, - YieldKeyword /* = 125 */, - AbstractKeyword /* = 126 */, - AsKeyword /* = 127 */, - AssertsKeyword /* = 128 */, - AnyKeyword /* = 129 */, - AsyncKeyword /* = 130 */, - AwaitKeyword /* = 131 */, - BooleanKeyword /* = 132 */, - ConstructorKeyword /* = 133 */, - DeclareKeyword /* = 134 */, - GetKeyword /* = 135 */, - InferKeyword /* = 136 */, - IntrinsicKeyword /* = 137 */, - IsKeyword /* = 138 */, - KeyOfKeyword /* = 139 */, - ModuleKeyword /* = 140 */, - NamespaceKeyword /* = 141 */, - NeverKeyword /* = 142 */, - ReadonlyKeyword /* = 143 */, - RequireKeyword /* = 144 */, - NumberKeyword /* = 145 */, - ObjectKeyword /* = 146 */, - SetKeyword /* = 147 */, - StringKeyword /* = 148 */, - SymbolKeyword /* = 149 */, - TypeKeyword /* = 150 */, - UndefinedKeyword /* = 151 */, - UniqueKeyword /* = 152 */, - UnknownKeyword /* = 153 */, - FromKeyword /* = 154 */, - GlobalKeyword /* = 155 */, - BigIntKeyword /* = 156 */, - OverrideKeyword /* = 157 */, - OfKeyword /* = 158 */, - QualifiedName /* = 159 */, - ComputedPropertyName /* = 160 */, - TypeParameter /* = 161 */, - Parameter /* = 162 */, - Decorator /* = 163 */, - PropertySignature /* = 164 */, - PropertyDeclaration /* = 165 */, - MethodSignature /* = 166 */, - MethodDeclaration /* = 167 */, - ClassStaticBlockDeclaration /* = 168 */, - Constructor /* = 169 */, - GetAccessor /* = 170 */, - SetAccessor /* = 171 */, - CallSignature /* = 172 */, - ConstructSignature /* = 173 */, - IndexSignature /* = 174 */, - TypePredicate /* = 175 */, - TypeReference /* = 176 */, - FunctionType /* = 177 */, - ConstructorType /* = 178 */, - TypeQuery /* = 179 */, - TypeLiteral /* = 180 */, - ArrayType /* = 181 */, - TupleType /* = 182 */, - OptionalType /* = 183 */, - RestType /* = 184 */, - UnionType /* = 185 */, - IntersectionType /* = 186 */, - ConditionalType /* = 187 */, - InferType /* = 188 */, - ParenthesizedType /* = 189 */, - ThisType /* = 190 */, - TypeOperator /* = 191 */, - IndexedAccessType /* = 192 */, - MappedType /* = 193 */, - LiteralType /* = 194 */, - NamedTupleMember /* = 195 */, - TemplateLiteralType /* = 196 */, - TemplateLiteralTypeSpan /* = 197 */, - ImportType /* = 198 */, - ObjectBindingPattern /* = 199 */, - ArrayBindingPattern /* = 200 */, - BindingElement /* = 201 */, - ArrayLiteralExpression /* = 202 */, - ObjectLiteralExpression /* = 203 */, - PropertyAccessExpression /* = 204 */, - ElementAccessExpression /* = 205 */, - CallExpression /* = 206 */, - NewExpression /* = 207 */, - TaggedTemplateExpression /* = 208 */, - TypeAssertionExpression /* = 209 */, - ParenthesizedExpression /* = 210 */, - FunctionExpression /* = 211 */, - ArrowFunction /* = 212 */, - DeleteExpression /* = 213 */, - TypeOfExpression /* = 214 */, - VoidExpression /* = 215 */, - AwaitExpression /* = 216 */, - PrefixUnaryExpression /* = 217 */, - PostfixUnaryExpression /* = 218 */, - BinaryExpression /* = 219 */, - ConditionalExpression /* = 220 */, - TemplateExpression /* = 221 */, - YieldExpression /* = 222 */, - SpreadElement /* = 223 */, - ClassExpression /* = 224 */, - OmittedExpression /* = 225 */, - ExpressionWithTypeArguments /* = 226 */, - AsExpression /* = 227 */, - NonNullExpression /* = 228 */, - MetaProperty /* = 229 */, - SyntheticExpression /* = 230 */, - TemplateSpan /* = 231 */, - SemicolonClassElement /* = 232 */, - Block /* = 233 */, - EmptyStatement /* = 234 */, - VariableStatement /* = 235 */, - ExpressionStatement /* = 236 */, - IfStatement /* = 237 */, - DoStatement /* = 238 */, - WhileStatement /* = 239 */, - ForStatement /* = 240 */, - ForInStatement /* = 241 */, - ForOfStatement /* = 242 */, - ContinueStatement /* = 243 */, - BreakStatement /* = 244 */, - ReturnStatement /* = 245 */, - WithStatement /* = 246 */, - SwitchStatement /* = 247 */, - LabeledStatement /* = 248 */, - ThrowStatement /* = 249 */, - TryStatement /* = 250 */, - DebuggerStatement /* = 251 */, - VariableDeclaration /* = 252 */, - VariableDeclarationList /* = 253 */, - FunctionDeclaration /* = 254 */, - ClassDeclaration /* = 255 */, - InterfaceDeclaration /* = 256 */, - TypeAliasDeclaration /* = 257 */, - EnumDeclaration /* = 258 */, - ModuleDeclaration /* = 259 */, - ModuleBlock /* = 260 */, - CaseBlock /* = 261 */, - NamespaceExportDeclaration /* = 262 */, - ImportEqualsDeclaration /* = 263 */, - ImportDeclaration /* = 264 */, - ImportClause /* = 265 */, - NamespaceImport /* = 266 */, - NamedImports /* = 267 */, - ImportSpecifier /* = 268 */, - ExportAssignment /* = 269 */, - ExportDeclaration /* = 270 */, - NamedExports /* = 271 */, - NamespaceExport /* = 272 */, - ExportSpecifier /* = 273 */, - MissingDeclaration /* = 274 */, - ExternalModuleReference /* = 275 */, - JsxElement /* = 276 */, - JsxSelfClosingElement /* = 277 */, - JsxOpeningElement /* = 278 */, - JsxClosingElement /* = 279 */, - JsxFragment /* = 280 */, - JsxOpeningFragment /* = 281 */, - JsxClosingFragment /* = 282 */, - JsxAttribute /* = 283 */, - JsxAttributes /* = 284 */, - JsxSpreadAttribute /* = 285 */, - JsxExpression /* = 286 */, - CaseClause /* = 287 */, - DefaultClause /* = 288 */, - HeritageClause /* = 289 */, - CatchClause /* = 290 */, - PropertyAssignment /* = 291 */, - ShorthandPropertyAssignment /* = 292 */, - SpreadAssignment /* = 293 */, - EnumMember /* = 294 */, - UnparsedPrologue /* = 295 */, - UnparsedPrepend /* = 296 */, - UnparsedText /* = 297 */, - UnparsedInternalText /* = 298 */, - UnparsedSyntheticReference /* = 299 */, - SourceFile /* = 300 */, - Bundle /* = 301 */, - UnparsedSource /* = 302 */, - InputFiles /* = 303 */, - JSDocTypeExpression /* = 304 */, - JSDocNameReference /* = 305 */, - JSDocMemberName /* = 306 */, - JSDocAllType /* = 307 */, - JSDocUnknownType /* = 308 */, - JSDocNullableType /* = 309 */, - JSDocNonNullableType /* = 310 */, - JSDocOptionalType /* = 311 */, - JSDocFunctionType /* = 312 */, - JSDocVariadicType /* = 313 */, - JSDocNamepathType /* = 314 */, - JSDocComment /* = 315 */, - JSDocText /* = 316 */, - JSDocTypeLiteral /* = 317 */, - JSDocSignature /* = 318 */, - JSDocLink /* = 319 */, - JSDocLinkCode /* = 320 */, - JSDocLinkPlain /* = 321 */, - JSDocTag /* = 322 */, - JSDocAugmentsTag /* = 323 */, - JSDocImplementsTag /* = 324 */, - JSDocAuthorTag /* = 325 */, - JSDocDeprecatedTag /* = 326 */, - JSDocClassTag /* = 327 */, - JSDocPublicTag /* = 328 */, - JSDocPrivateTag /* = 329 */, - JSDocProtectedTag /* = 330 */, - JSDocReadonlyTag /* = 331 */, - JSDocOverrideTag /* = 332 */, - JSDocCallbackTag /* = 333 */, - JSDocEnumTag /* = 334 */, - JSDocParameterTag /* = 335 */, - JSDocReturnTag /* = 336 */, - JSDocThisTag /* = 337 */, - JSDocTypeTag /* = 338 */, - JSDocTemplateTag /* = 339 */, - JSDocTypedefTag /* = 340 */, - JSDocSeeTag /* = 341 */, - JSDocPropertyTag /* = 342 */, - SyntaxList /* = 343 */, - NotEmittedStatement /* = 344 */, - PartiallyEmittedExpression /* = 345 */, - CommaListExpression /* = 346 */, - MergeDeclarationMarker /* = 347 */, - EndOfDeclarationMarker /* = 348 */, - SyntheticReferenceExpression /* = 349 */, - Count /* = 350 */, - FirstAssignment /* = 63 */, - LastAssignment /* = 78 */, - FirstCompoundAssignment /* = 64 */, - LastCompoundAssignment /* = 78 */, - FirstReservedWord /* = 81 */, - LastReservedWord /* = 116 */, - FirstKeyword /* = 81 */, - LastKeyword /* = 158 */, - FirstFutureReservedWord /* = 117 */, - LastFutureReservedWord /* = 125 */, - FirstTypeNode /* = 175 */, - LastTypeNode /* = 198 */, - FirstPunctuation /* = 18 */, - LastPunctuation /* = 78 */, - FirstToken /* = 0 */, - LastToken /* = 158 */, - FirstTriviaToken /* = 2 */, - LastTriviaToken /* = 7 */, - FirstLiteralToken /* = 8 */, - LastLiteralToken /* = 14 */, - FirstTemplateToken /* = 14 */, - LastTemplateToken /* = 17 */, - FirstBinaryOperator /* = 29 */, - LastBinaryOperator /* = 78 */, - FirstStatement /* = 235 */, - LastStatement /* = 251 */, - FirstNode /* = 159 */, - FirstJSDocNode /* = 304 */, - LastJSDocNode /* = 342 */, - FirstJSDocTagNode /* = 322 */, - LastJSDocTagNode /* = 342 */ -} - -external enum class NodeFlags { - None /* = 0 */, - Let /* = 1 */, - Const /* = 2 */, - NestedNamespace /* = 4 */, - Synthesized /* = 8 */, - Namespace /* = 16 */, - OptionalChain /* = 32 */, - ExportContext /* = 64 */, - ContainsThis /* = 128 */, - HasImplicitReturn /* = 256 */, - HasExplicitReturn /* = 512 */, - GlobalAugmentation /* = 1024 */, - HasAsyncFunctions /* = 2048 */, - DisallowInContext /* = 4096 */, - YieldContext /* = 8192 */, - DecoratorContext /* = 16384 */, - AwaitContext /* = 32768 */, - ThisNodeHasError /* = 65536 */, - JavaScriptFile /* = 131072 */, - ThisNodeOrAnySubNodesHasError /* = 262144 */, - HasAggregatedChildData /* = 524288 */, - JSDoc /* = 4194304 */, - JsonFile /* = 33554432 */, - BlockScoped /* = 3 */, - ReachabilityCheckFlags /* = 768 */, - ReachabilityAndEmitFlags /* = 2816 */, - ContextFlags /* = 25358336 */, - TypeExcludesFlags /* = 40960 */ -} - -external enum class ModifierFlags { - None /* = 0 */, - Export /* = 1 */, - Ambient /* = 2 */, - Public /* = 4 */, - Private /* = 8 */, - Protected /* = 16 */, - Static /* = 32 */, - Readonly /* = 64 */, - Abstract /* = 128 */, - Async /* = 256 */, - Default /* = 512 */, - Const /* = 2048 */, - HasComputedJSDocModifiers /* = 4096 */, - Deprecated /* = 8192 */, - Override /* = 16384 */, - HasComputedFlags /* = 536870912 */, - AccessibilityModifier /* = 28 */, - ParameterPropertyModifier /* = 16476 */, - NonPublicAccessibilityModifier /* = 24 */, - TypeScriptModifier /* = 18654 */, - ExportDefault /* = 513 */, - All /* = 27647 */ -} - -external enum class JsxFlags { - None /* = 0 */, - IntrinsicNamedElement /* = 1 */, - IntrinsicIndexedElement /* = 2 */, - IntrinsicElement /* = 3 */ -} - -external interface Node : ReadonlyTextRange { - fun getSourceFile(): SourceFile - fun getChildCount(sourceFile: SourceFile = definedExternally): Number - fun getChildAt(index: Number, sourceFile: SourceFile = definedExternally): Node - fun getChildren(sourceFile: SourceFile = definedExternally): Array - fun getStart(sourceFile: SourceFile = definedExternally, includeJsDocComment: Boolean = definedExternally): Number - fun getFullStart(): Number - fun getEnd(): Number - fun getWidth(sourceFile: SourceFileLike = definedExternally): Number - fun getFullWidth(): Number - fun getLeadingTriviaWidth(sourceFile: SourceFile = definedExternally): Number - fun getFullText(sourceFile: SourceFile = definedExternally): String - fun getText(sourceFile: SourceFile = definedExternally): String - fun getFirstToken(sourceFile: SourceFile = definedExternally): Node? - fun getLastToken(sourceFile: SourceFile = definedExternally): Node? - fun forEachChild(cbNode: (node: Node) -> T?, cbNodeArray: (nodes: NodeArray) -> T? = definedExternally): T? - var kind: SyntaxKind - var flags: NodeFlags - var decorators: NodeArray? - get() = definedExternally - set(value) = definedExternally - var modifiers: ModifiersArray? - get() = definedExternally - set(value) = definedExternally - var parent: Node -} - -external interface JSDocContainer - -external interface Token : Node { - override var kind: TKind -} - -external interface PunctuationToken : Token - -external interface KeywordToken : Token - -external interface ModifierToken : KeywordToken - -external enum class GeneratedIdentifierFlags { - None /* = 0 */, - ReservedInNestedScopes /* = 8 */, - Optimistic /* = 16 */, - FileLevel /* = 32 */, - AllowNameSubstitution /* = 64 */ -} - -external interface Identifier : PrimaryExpression, Declaration { - var text: String - var escapedText: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - get() = definedExternally - set(value) = definedExternally - var originalKeywordKind: SyntaxKind? - get() = definedExternally - set(value) = definedExternally - var isInJSDocNamespace: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TransientIdentifier : Identifier { - var resolvedSymbol: Symbol -} - -external interface QualifiedName : Node { - var left: dynamic /* Identifier | QualifiedName */ - get() = definedExternally - set(value) = definedExternally - var right: Identifier -} - -external interface Declaration : Node { - var _declarationBrand: Any -} - -external interface NamedDeclaration : Declaration { - var name: dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface DeclarationStatement : NamedDeclaration, Statement { - override var name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ComputedPropertyName : Node { - override var parent: Declaration - var expression: Expression -} - -external interface PrivateIdentifier : Node { - var text: String - var escapedText: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - get() = definedExternally - set(value) = definedExternally -} - -external interface Decorator : Node { - override var parent: NamedDeclaration - var expression: LeftHandSideExpression -} - -external interface TypeParameterDeclaration : NamedDeclaration { - override var parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | InferTypeNode */ - get() = definedExternally - set(value) = definedExternally - override var name: Identifier - var constraint: TypeNode? - get() = definedExternally - set(value) = definedExternally - var default: TypeNode? - get() = definedExternally - set(value) = definedExternally - var expression: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureDeclarationBase : NamedDeclaration, JSDocContainer { - override var name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - set(value) = definedExternally - var typeParameters: NodeArray? - get() = definedExternally - set(value) = definedExternally - var parameters: NodeArray - var type: TypeNode? - get() = definedExternally - set(value) = definedExternally -} - -external interface CallSignatureDeclaration : SignatureDeclarationBase, TypeElement { - override var kind: Any - override var name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ConstructSignatureDeclaration : SignatureDeclarationBase, TypeElement { - override var kind: Any - override var name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface VariableDeclaration : NamedDeclaration, JSDocContainer { - override var parent: dynamic /* VariableDeclarationList | CatchClause */ - get() = definedExternally - set(value) = definedExternally - override var name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ - get() = definedExternally - set(value) = definedExternally - var exclamationToken: ExclamationToken? - get() = definedExternally - set(value) = definedExternally - var type: TypeNode? - get() = definedExternally - set(value) = definedExternally - var initializer: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface VariableDeclarationList : Node { - override var parent: dynamic /* VariableStatement | ForStatement | ForOfStatement | ForInStatement */ - get() = definedExternally - set(value) = definedExternally - var declarations: NodeArray -} - -external interface ParameterDeclaration : NamedDeclaration, JSDocContainer { - override var parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ - get() = definedExternally - set(value) = definedExternally - var dotDotDotToken: DotDotDotToken? - get() = definedExternally - set(value) = definedExternally - override var name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ - get() = definedExternally - set(value) = definedExternally - var questionToken: QuestionToken? - get() = definedExternally - set(value) = definedExternally - var type: TypeNode? - get() = definedExternally - set(value) = definedExternally - var initializer: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface BindingElement : NamedDeclaration { - override var parent: dynamic /* ObjectBindingPattern | ArrayBindingPattern */ - get() = definedExternally - set(value) = definedExternally - var propertyName: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - set(value) = definedExternally - var dotDotDotToken: DotDotDotToken? - get() = definedExternally - set(value) = definedExternally - override var name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */ - get() = definedExternally - set(value) = definedExternally - var initializer: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface PropertySignature : TypeElement, JSDocContainer { - override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - set(value) = definedExternally - override var questionToken: QuestionToken? - get() = definedExternally - set(value) = definedExternally - var type: TypeNode? - get() = definedExternally - set(value) = definedExternally - var initializer: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface PropertyDeclaration : ClassElement, JSDocContainer { - override var parent: dynamic /* ClassDeclaration | ClassExpression */ - get() = definedExternally - set(value) = definedExternally - override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - set(value) = definedExternally - var questionToken: QuestionToken? - get() = definedExternally - set(value) = definedExternally - var exclamationToken: ExclamationToken? - get() = definedExternally - set(value) = definedExternally - var type: TypeNode? - get() = definedExternally - set(value) = definedExternally - var initializer: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface ObjectLiteralElement : NamedDeclaration { - var _objectLiteralBrand: Any - override var name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface PropertyAssignment : ObjectLiteralElement, JSDocContainer { - override var parent: ObjectLiteralExpression - override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - set(value) = definedExternally - var questionToken: QuestionToken? - get() = definedExternally - set(value) = definedExternally - var exclamationToken: ExclamationToken? - get() = definedExternally - set(value) = definedExternally - var initializer: Expression -} - -external interface ShorthandPropertyAssignment : ObjectLiteralElement, JSDocContainer { - override var parent: ObjectLiteralExpression - override var name: Identifier - var questionToken: QuestionToken? - get() = definedExternally - set(value) = definedExternally - var exclamationToken: ExclamationToken? - get() = definedExternally - set(value) = definedExternally - var equalsToken: EqualsToken? - get() = definedExternally - set(value) = definedExternally - var objectAssignmentInitializer: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface SpreadAssignment : ObjectLiteralElement, JSDocContainer { - override var parent: ObjectLiteralExpression - var expression: Expression -} - -external interface PropertyLikeDeclaration : NamedDeclaration { - override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ObjectBindingPattern : Node { - override var parent: dynamic /* VariableDeclaration | ParameterDeclaration | BindingElement */ - get() = definedExternally - set(value) = definedExternally - var elements: NodeArray -} - -external interface ArrayBindingPattern : Node { - override var parent: dynamic /* VariableDeclaration | ParameterDeclaration | BindingElement */ - get() = definedExternally - set(value) = definedExternally - var elements: NodeArray -} - -external interface FunctionLikeDeclarationBase : SignatureDeclarationBase { - var _functionLikeDeclarationBrand: Any - var asteriskToken: AsteriskToken? - get() = definedExternally - set(value) = definedExternally - var questionToken: QuestionToken? - get() = definedExternally - set(value) = definedExternally - var exclamationToken: ExclamationToken? - get() = definedExternally - set(value) = definedExternally - var body: dynamic /* Block? | Expression? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FunctionDeclaration : FunctionLikeDeclarationBase, DeclarationStatement { - override var kind: Any - override var name: Identifier? - get() = definedExternally - set(value) = definedExternally - override var body: FunctionBody? - get() = definedExternally - set(value) = definedExternally -} - -external interface MethodSignature : SignatureDeclarationBase, TypeElement { - override var kind: Any - override var parent: dynamic /* ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode */ - get() = definedExternally - set(value) = definedExternally - override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - set(value) = definedExternally -} - -external interface MethodDeclaration : FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer { - override var kind: Any - override var parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression */ - get() = definedExternally - set(value) = definedExternally - override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - set(value) = definedExternally - override var body: FunctionBody? - get() = definedExternally - set(value) = definedExternally -} - -external interface ConstructorDeclaration : FunctionLikeDeclarationBase, ClassElement, JSDocContainer { - override var kind: Any - override var parent: dynamic /* ClassDeclaration | ClassExpression */ - get() = definedExternally - set(value) = definedExternally - override var body: FunctionBody? - get() = definedExternally - set(value) = definedExternally -} - -external interface SemicolonClassElement : ClassElement { - override var parent: dynamic /* ClassDeclaration | ClassExpression */ - get() = definedExternally - set(value) = definedExternally -} - -external interface GetAccessorDeclaration : FunctionLikeDeclarationBase, ClassElement, TypeElement, ObjectLiteralElement, JSDocContainer { - override var kind: Any - override var parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression | TypeLiteralNode | InterfaceDeclaration */ - get() = definedExternally - set(value) = definedExternally - override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - set(value) = definedExternally - override var body: FunctionBody? - get() = definedExternally - set(value) = definedExternally - override var questionToken: QuestionToken? - get() = definedExternally - set(value) = definedExternally -} - -external interface SetAccessorDeclaration : FunctionLikeDeclarationBase, ClassElement, TypeElement, ObjectLiteralElement, JSDocContainer { - override var kind: Any - override var parent: dynamic /* ClassDeclaration | ClassExpression | ObjectLiteralExpression | TypeLiteralNode | InterfaceDeclaration */ - get() = definedExternally - set(value) = definedExternally - override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - set(value) = definedExternally - override var body: FunctionBody? - get() = definedExternally - set(value) = definedExternally - override var questionToken: QuestionToken? - get() = definedExternally - set(value) = definedExternally -} - -external interface IndexSignatureDeclaration : SignatureDeclarationBase, ClassElement, TypeElement { - override var kind: Any - override var parent: dynamic /* ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode */ - get() = definedExternally - set(value) = definedExternally - override var name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ClassStaticBlockDeclaration : ClassElement, JSDocContainer { - override var parent: dynamic /* ClassDeclaration | ClassExpression */ - get() = definedExternally - set(value) = definedExternally - var body: Block -} - -external interface TypeNode : Node { - var _typeNodeBrand: Any -} - -external interface KeywordTypeNode : KeywordToken, TypeNode { - override var kind: TKind -} - -external interface ImportTypeNode : NodeWithTypeArguments { - var isTypeOf: Boolean - var argument: TypeNode - var qualifier: dynamic /* Identifier? | QualifiedName? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ThisTypeNode : TypeNode - -external interface FunctionOrConstructorTypeNodeBase : TypeNode, SignatureDeclarationBase { - override var kind: dynamic /* SyntaxKind.FunctionType | SyntaxKind.ConstructorType */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FunctionTypeNode : FunctionOrConstructorTypeNodeBase { - override var kind: Any -} - -external interface ConstructorTypeNode : FunctionOrConstructorTypeNodeBase { - override var kind: Any -} - -external interface NodeWithTypeArguments : TypeNode { - var typeArguments: NodeArray? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeReferenceNode : NodeWithTypeArguments { - var typeName: dynamic /* Identifier | QualifiedName */ - get() = definedExternally - set(value) = definedExternally -} - -external interface TypePredicateNode : TypeNode { - override var parent: dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | JSDocTypeExpression */ - get() = definedExternally - set(value) = definedExternally - var assertsModifier: AssertsToken? - get() = definedExternally - set(value) = definedExternally - var parameterName: dynamic /* Identifier | ThisTypeNode */ - get() = definedExternally - set(value) = definedExternally - var type: TypeNode? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeQueryNode : TypeNode { - var exprName: dynamic /* Identifier | QualifiedName */ - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeLiteralNode : TypeNode, Declaration { - var members: NodeArray -} - -external interface ArrayTypeNode : TypeNode { - var elementType: TypeNode -} - -external interface TupleTypeNode : TypeNode { - var elements: NodeArray -} - -external interface NamedTupleMember : TypeNode, JSDocContainer, Declaration { - var dotDotDotToken: Token? - get() = definedExternally - set(value) = definedExternally - var name: Identifier - var questionToken: Token? - get() = definedExternally - set(value) = definedExternally - var type: TypeNode -} - -external interface OptionalTypeNode : TypeNode { - var type: TypeNode -} - -external interface RestTypeNode : TypeNode { - var type: TypeNode -} - -external interface UnionTypeNode : TypeNode { - var types: NodeArray -} - -external interface IntersectionTypeNode : TypeNode { - var types: NodeArray -} - -external interface ConditionalTypeNode : TypeNode { - var checkType: TypeNode - var extendsType: TypeNode - var trueType: TypeNode - var falseType: TypeNode -} - -external interface InferTypeNode : TypeNode { - var typeParameter: TypeParameterDeclaration -} - -external interface ParenthesizedTypeNode : TypeNode { - var type: TypeNode -} - -external interface TypeOperatorNode : TypeNode { - var operator: dynamic /* SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword */ - get() = definedExternally - set(value) = definedExternally - var type: TypeNode -} - -external interface IndexedAccessTypeNode : TypeNode { - var objectType: TypeNode - var indexType: TypeNode -} - -external interface MappedTypeNode : TypeNode, Declaration { - var readonlyToken: dynamic /* ReadonlyToken? | PlusToken? | MinusToken? */ - get() = definedExternally - set(value) = definedExternally - var typeParameter: TypeParameterDeclaration - var nameType: TypeNode? - get() = definedExternally - set(value) = definedExternally - var questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */ - get() = definedExternally - set(value) = definedExternally - var type: TypeNode? - get() = definedExternally - set(value) = definedExternally -} - -external interface LiteralTypeNode : TypeNode { - var literal: dynamic /* NullLiteral | TrueLiteral | FalseLiteral | LiteralExpression | PrefixUnaryExpression */ - get() = definedExternally - set(value) = definedExternally -} - -external interface StringLiteral : LiteralExpression, Declaration - -external interface TemplateLiteralTypeNode : TypeNode { - var head: TemplateHead - var templateSpans: NodeArray -} - -external interface TemplateLiteralTypeSpan : TypeNode { - override var parent: TemplateLiteralTypeNode - var type: TypeNode - var literal: dynamic /* TemplateMiddle | TemplateTail */ - get() = definedExternally - set(value) = definedExternally -} - -external interface Expression : Node { - var _expressionBrand: Any -} - -external interface OmittedExpression : Expression - -external interface PartiallyEmittedExpression : LeftHandSideExpression { - var expression: Expression -} - -external interface UnaryExpression : Expression { - var _unaryExpressionBrand: Any -} - -external interface UpdateExpression : UnaryExpression { - var _updateExpressionBrand: Any -} - -external interface PrefixUnaryExpression : UpdateExpression { - var operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken | SyntaxKind.ExclamationToken */ - get() = definedExternally - set(value) = definedExternally - var operand: UnaryExpression -} - -external interface PostfixUnaryExpression : UpdateExpression { - var operand: LeftHandSideExpression - var operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken */ - get() = definedExternally - set(value) = definedExternally -} - -external interface LeftHandSideExpression : UpdateExpression { - var _leftHandSideExpressionBrand: Any -} - -external interface MemberExpression : LeftHandSideExpression { - var _memberExpressionBrand: Any -} - -external interface PrimaryExpression : MemberExpression { - var _primaryExpressionBrand: Any -} - -external interface NullLiteral : PrimaryExpression - -external interface TrueLiteral : PrimaryExpression - -external interface FalseLiteral : PrimaryExpression - -external interface ThisExpression : PrimaryExpression - -external interface SuperExpression : PrimaryExpression - -external interface ImportExpression : PrimaryExpression - -external interface DeleteExpression : UnaryExpression { - var expression: UnaryExpression -} - -external interface TypeOfExpression : UnaryExpression { - var expression: UnaryExpression -} - -external interface VoidExpression : UnaryExpression { - var expression: UnaryExpression -} - -external interface AwaitExpression : UnaryExpression { - var expression: UnaryExpression -} - -external interface YieldExpression : Expression { - var asteriskToken: AsteriskToken? - get() = definedExternally - set(value) = definedExternally - var expression: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface SyntheticExpression : Expression { - var isSpread: Boolean - var type: Type - var tupleNameSource: dynamic /* ParameterDeclaration? | NamedTupleMember? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface BinaryExpression : Expression, Declaration { - var left: Expression - var operatorToken: BinaryOperatorToken - var right: Expression -} - -external interface AssignmentExpression : BinaryExpression { - override var left: LeftHandSideExpression - override var operatorToken: TOperator -} - -external interface ObjectDestructuringAssignment : AssignmentExpression { - override var left: ObjectLiteralExpression -} - -external interface ArrayDestructuringAssignment : AssignmentExpression { - override var left: ArrayLiteralExpression -} - -external interface ConditionalExpression : Expression { - var condition: Expression - var questionToken: QuestionToken - var whenTrue: Expression - var colonToken: ColonToken - var whenFalse: Expression -} - -external interface FunctionExpression : PrimaryExpression, FunctionLikeDeclarationBase, JSDocContainer { - override var kind: Any - override var name: Identifier? - get() = definedExternally - set(value) = definedExternally - override var body: FunctionBody -} - -external interface ArrowFunction : Expression, FunctionLikeDeclarationBase, JSDocContainer { - override var kind: Any - var equalsGreaterThanToken: EqualsGreaterThanToken - override var body: dynamic /* FunctionBody | Expression */ - get() = definedExternally - set(value) = definedExternally - override var name: Any -} - -external interface LiteralLikeNode : Node { - var text: String - var isUnterminated: Boolean? - get() = definedExternally - set(value) = definedExternally - var hasExtendedUnicodeEscape: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TemplateLiteralLikeNode : LiteralLikeNode { - var rawText: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface LiteralExpression : LiteralLikeNode, PrimaryExpression { - var _literalExpressionBrand: Any -} - -external interface RegularExpressionLiteral : LiteralExpression - -external interface NoSubstitutionTemplateLiteral : LiteralExpression, TemplateLiteralLikeNode, Declaration - -external enum class TokenFlags { - None /* = 0 */, - Scientific /* = 16 */, - Octal /* = 32 */, - HexSpecifier /* = 64 */, - BinarySpecifier /* = 128 */, - OctalSpecifier /* = 256 */ -} - -external interface NumericLiteral : LiteralExpression, Declaration - -external interface BigIntLiteral : LiteralExpression - -external interface TemplateHead : TemplateLiteralLikeNode { - override var parent: dynamic /* TemplateExpression | TemplateLiteralTypeNode */ - get() = definedExternally - set(value) = definedExternally -} - -external interface TemplateMiddle : TemplateLiteralLikeNode { - override var parent: dynamic /* TemplateSpan | TemplateLiteralTypeSpan */ - get() = definedExternally - set(value) = definedExternally -} - -external interface TemplateTail : TemplateLiteralLikeNode { - override var parent: dynamic /* TemplateSpan | TemplateLiteralTypeSpan */ - get() = definedExternally - set(value) = definedExternally -} - -external interface TemplateExpression : PrimaryExpression { - var head: TemplateHead - var templateSpans: NodeArray -} - -external interface TemplateSpan : Node { - override var parent: TemplateExpression - var expression: Expression - var literal: dynamic /* TemplateMiddle | TemplateTail */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ParenthesizedExpression : PrimaryExpression, JSDocContainer { - var expression: Expression -} - -external interface ArrayLiteralExpression : PrimaryExpression { - var elements: NodeArray -} - -external interface SpreadElement : Expression { - override var parent: dynamic /* ArrayLiteralExpression | CallExpression | NewExpression */ - get() = definedExternally - set(value) = definedExternally - var expression: Expression -} - -external interface ObjectLiteralExpressionBase : PrimaryExpression, Declaration { - var properties: NodeArray -} - -external interface ObjectLiteralExpression : ObjectLiteralExpressionBase - -external interface PropertyAccessExpression : MemberExpression, NamedDeclaration { - var expression: LeftHandSideExpression - var questionDotToken: QuestionDotToken? - get() = definedExternally - set(value) = definedExternally - override var name: dynamic /* Identifier | PrivateIdentifier */ - get() = definedExternally - set(value) = definedExternally -} - -external interface PropertyAccessChain : PropertyAccessExpression { - var _optionalChainBrand: Any - override var name: dynamic /* Identifier | PrivateIdentifier */ - get() = definedExternally - set(value) = definedExternally -} - -external interface SuperPropertyAccessExpression : PropertyAccessExpression { - override var expression: SuperExpression -} - -external interface PropertyAccessEntityNameExpression : PropertyAccessExpression { - var _propertyAccessExpressionLikeQualifiedNameBrand: Any? - get() = definedExternally - set(value) = definedExternally - override var expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ - get() = definedExternally - set(value) = definedExternally - override var name: Identifier -} - -external interface ElementAccessExpression : MemberExpression { - var expression: LeftHandSideExpression - var questionDotToken: QuestionDotToken? - get() = definedExternally - set(value) = definedExternally - var argumentExpression: Expression -} - -external interface ElementAccessChain : ElementAccessExpression { - var _optionalChainBrand: Any -} - -external interface SuperElementAccessExpression : ElementAccessExpression { - override var expression: SuperExpression -} - -external interface CallExpression : LeftHandSideExpression, Declaration { - var expression: LeftHandSideExpression - var questionDotToken: QuestionDotToken? - get() = definedExternally - set(value) = definedExternally - var typeArguments: NodeArray? - get() = definedExternally - set(value) = definedExternally - var arguments: NodeArray -} - -external interface CallChain : CallExpression { - var _optionalChainBrand: Any -} - -external interface SuperCall : CallExpression { - override var expression: SuperExpression -} - -external interface ImportCall : CallExpression { - override var expression: ImportExpression -} - -external interface ExpressionWithTypeArguments : NodeWithTypeArguments { - override var parent: dynamic /* HeritageClause | JSDocAugmentsTag | JSDocImplementsTag */ - get() = definedExternally - set(value) = definedExternally - var expression: LeftHandSideExpression -} - -external interface NewExpression : PrimaryExpression, Declaration { - var expression: LeftHandSideExpression - var typeArguments: NodeArray? - get() = definedExternally - set(value) = definedExternally - var arguments: NodeArray? - get() = definedExternally - set(value) = definedExternally -} - -external interface TaggedTemplateExpression : MemberExpression { - var tag: LeftHandSideExpression - var typeArguments: NodeArray? - get() = definedExternally - set(value) = definedExternally - var template: dynamic /* TemplateExpression | NoSubstitutionTemplateLiteral */ - get() = definedExternally - set(value) = definedExternally -} - -external interface AsExpression : Expression { - var expression: Expression - var type: TypeNode -} - -external interface TypeAssertion : UnaryExpression { - var type: TypeNode - var expression: UnaryExpression -} - -external interface NonNullExpression : LeftHandSideExpression { - var expression: Expression -} - -external interface NonNullChain : NonNullExpression { - var _optionalChainBrand: Any -} - -external interface MetaProperty : PrimaryExpression { - var keywordToken: dynamic /* SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword */ - get() = definedExternally - set(value) = definedExternally - var name: Identifier -} - -external interface JsxElement : PrimaryExpression { - var openingElement: JsxOpeningElement - var children: NodeArray - var closingElement: JsxClosingElement -} - -external interface JsxTagNamePropertyAccess : PropertyAccessExpression { - override var expression: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ - get() = definedExternally - set(value) = definedExternally -} - -external interface JsxAttributes : ObjectLiteralExpressionBase { - override var parent: dynamic /* JsxSelfClosingElement | JsxOpeningElement */ - get() = definedExternally - set(value) = definedExternally -} - -external interface JsxOpeningElement : Expression { - override var parent: JsxElement - var tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ - get() = definedExternally - set(value) = definedExternally - var typeArguments: NodeArray? - get() = definedExternally - set(value) = definedExternally - var attributes: JsxAttributes -} - -external interface JsxSelfClosingElement : PrimaryExpression { - var tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ - get() = definedExternally - set(value) = definedExternally - var typeArguments: NodeArray? - get() = definedExternally - set(value) = definedExternally - var attributes: JsxAttributes -} - -external interface JsxFragment : PrimaryExpression { - var openingFragment: JsxOpeningFragment - var children: NodeArray - var closingFragment: JsxClosingFragment -} - -external interface JsxOpeningFragment : Expression { - override var parent: JsxFragment -} - -external interface JsxClosingFragment : Expression { - override var parent: JsxFragment -} - -external interface JsxAttribute : ObjectLiteralElement { - override var parent: JsxAttributes - override var name: Identifier - var initializer: dynamic /* StringLiteral? | JsxExpression? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface JsxSpreadAttribute : ObjectLiteralElement { - override var parent: JsxAttributes - var expression: Expression -} - -external interface JsxClosingElement : Node { - override var parent: JsxElement - var tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */ - get() = definedExternally - set(value) = definedExternally -} - -external interface JsxExpression : Expression { - override var parent: dynamic /* JsxElement | JsxAttribute | JsxSpreadAttribute */ - get() = definedExternally - set(value) = definedExternally - var dotDotDotToken: Token? - get() = definedExternally - set(value) = definedExternally - var expression: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface JsxText : LiteralLikeNode { - override var parent: JsxElement - var containsOnlyTriviaWhiteSpaces: Boolean -} - -external interface Statement : Node, JSDocContainer { - var _statementBrand: Any -} - -external interface NotEmittedStatement : Statement - -external interface CommaListExpression : Expression { - var elements: NodeArray -} - -external interface EmptyStatement : Statement - -external interface DebuggerStatement : Statement - -external interface MissingDeclaration : DeclarationStatement { - override var name: Identifier? - get() = definedExternally - set(value) = definedExternally -} - -external interface Block : Statement { - var statements: NodeArray -} - -external interface VariableStatement : Statement { - var declarationList: VariableDeclarationList -} - -external interface ExpressionStatement : Statement { - var expression: Expression -} - -external interface IfStatement : Statement { - var expression: Expression - var thenStatement: Statement - var elseStatement: Statement? - get() = definedExternally - set(value) = definedExternally -} - -external interface IterationStatement : Statement { - var statement: Statement -} - -external interface DoStatement : IterationStatement { - var expression: Expression -} - -external interface WhileStatement : IterationStatement { - var expression: Expression -} - -external interface ForStatement : IterationStatement { - var initializer: dynamic /* VariableDeclarationList? | Expression? */ - get() = definedExternally - set(value) = definedExternally - var condition: Expression? - get() = definedExternally - set(value) = definedExternally - var incrementor: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface ForInStatement : IterationStatement { - var initializer: dynamic /* VariableDeclarationList | Expression */ - get() = definedExternally - set(value) = definedExternally - var expression: Expression -} - -external interface ForOfStatement : IterationStatement { - var awaitModifier: AwaitKeywordToken? - get() = definedExternally - set(value) = definedExternally - var initializer: dynamic /* VariableDeclarationList | Expression */ - get() = definedExternally - set(value) = definedExternally - var expression: Expression -} - -external interface BreakStatement : Statement { - var label: Identifier? - get() = definedExternally - set(value) = definedExternally -} - -external interface ContinueStatement : Statement { - var label: Identifier? - get() = definedExternally - set(value) = definedExternally -} - -external interface ReturnStatement : Statement { - var expression: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface WithStatement : Statement { - var expression: Expression - var statement: Statement -} - -external interface SwitchStatement : Statement { - var expression: Expression - var caseBlock: CaseBlock - var possiblyExhaustive: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface CaseBlock : Node { - override var parent: SwitchStatement - var clauses: NodeArray -} - -external interface CaseClause : Node { - override var parent: CaseBlock - var expression: Expression - var statements: NodeArray -} - -external interface DefaultClause : Node { - override var parent: CaseBlock - var statements: NodeArray -} - -external interface LabeledStatement : Statement { - var label: Identifier - var statement: Statement -} - -external interface ThrowStatement : Statement { - var expression: Expression -} - -external interface TryStatement : Statement { - var tryBlock: Block - var catchClause: CatchClause? - get() = definedExternally - set(value) = definedExternally - var finallyBlock: Block? - get() = definedExternally - set(value) = definedExternally -} - -external interface CatchClause : Node { - override var parent: TryStatement - var variableDeclaration: VariableDeclaration? - get() = definedExternally - set(value) = definedExternally - var block: Block -} - -external interface ClassLikeDeclarationBase : NamedDeclaration, JSDocContainer { - override var kind: dynamic /* SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression */ - get() = definedExternally - set(value) = definedExternally - override var name: Identifier? - get() = definedExternally - set(value) = definedExternally - var typeParameters: NodeArray? - get() = definedExternally - set(value) = definedExternally - var heritageClauses: NodeArray? - get() = definedExternally - set(value) = definedExternally - var members: NodeArray -} - -external interface ClassDeclaration : ClassLikeDeclarationBase, DeclarationStatement { - override var kind: Any - override var name: Identifier? - get() = definedExternally - set(value) = definedExternally -} - -external interface ClassExpression : ClassLikeDeclarationBase, PrimaryExpression { - override var kind: Any -} - -external interface ClassElement : NamedDeclaration { - var _classElementBrand: Any - override var name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeElement : NamedDeclaration { - var _typeElementBrand: Any - override var name: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */ - get() = definedExternally - set(value) = definedExternally - var questionToken: QuestionToken? - get() = definedExternally - set(value) = definedExternally -} - -external interface InterfaceDeclaration : DeclarationStatement, JSDocContainer { - override var name: Identifier - var typeParameters: NodeArray? - get() = definedExternally - set(value) = definedExternally - var heritageClauses: NodeArray? - get() = definedExternally - set(value) = definedExternally - var members: NodeArray -} - -external interface HeritageClause : Node { - override var parent: dynamic /* InterfaceDeclaration | ClassDeclaration | ClassExpression */ - get() = definedExternally - set(value) = definedExternally - var token: dynamic /* SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword */ - get() = definedExternally - set(value) = definedExternally - var types: NodeArray -} - -external interface TypeAliasDeclaration : DeclarationStatement, JSDocContainer { - override var name: Identifier - var typeParameters: NodeArray? - get() = definedExternally - set(value) = definedExternally - var type: TypeNode -} - -external interface EnumMember : NamedDeclaration, JSDocContainer { - override var parent: EnumDeclaration - override var name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */ - get() = definedExternally - set(value) = definedExternally - var initializer: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface EnumDeclaration : DeclarationStatement, JSDocContainer { - override var name: Identifier - var members: NodeArray -} - -external interface ModuleDeclaration : DeclarationStatement, JSDocContainer { - override var parent: dynamic /* ModuleBlock | NamespaceDeclaration | Identifier | JSDocNamespaceDeclaration | SourceFile */ - get() = definedExternally - set(value) = definedExternally - override var name: dynamic /* Identifier | StringLiteral */ - get() = definedExternally - set(value) = definedExternally - var body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface NamespaceDeclaration : ModuleDeclaration { - override var name: Identifier - override var body: dynamic /* ModuleBlock | NamespaceDeclaration */ - get() = definedExternally - set(value) = definedExternally -} - -external interface JSDocNamespaceDeclaration : ModuleDeclaration { - override var name: Identifier - override var body: dynamic /* Identifier? | JSDocNamespaceDeclaration? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ModuleBlock : Node, Statement { - override var parent: ModuleDeclaration - var statements: NodeArray -} - -external interface ImportEqualsDeclaration : DeclarationStatement, JSDocContainer { - override var parent: dynamic /* SourceFile | ModuleBlock */ - get() = definedExternally - set(value) = definedExternally - override var name: Identifier - var isTypeOnly: Boolean - var moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ExternalModuleReference : Node { - override var parent: ImportEqualsDeclaration - var expression: Expression -} - -external interface ImportDeclaration : Statement { - override var parent: dynamic /* SourceFile | ModuleBlock */ - get() = definedExternally - set(value) = definedExternally - var importClause: ImportClause? - get() = definedExternally - set(value) = definedExternally - var moduleSpecifier: Expression -} - -external interface ImportClause : NamedDeclaration { - override var parent: ImportDeclaration - var isTypeOnly: Boolean - override var name: Identifier? - get() = definedExternally - set(value) = definedExternally - var namedBindings: dynamic /* NamespaceImport? | NamedImports? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface NamespaceImport : NamedDeclaration { - override var parent: ImportClause - override var name: Identifier -} - -external interface NamespaceExport : NamedDeclaration { - override var parent: ExportDeclaration - override var name: Identifier -} - -external interface NamespaceExportDeclaration : DeclarationStatement, JSDocContainer { - override var name: Identifier -} - -external interface ExportDeclaration : DeclarationStatement, JSDocContainer { - override var parent: dynamic /* SourceFile | ModuleBlock */ - get() = definedExternally - set(value) = definedExternally - var isTypeOnly: Boolean - var exportClause: dynamic /* NamespaceExport? | NamedExports? */ - get() = definedExternally - set(value) = definedExternally - var moduleSpecifier: Expression? - get() = definedExternally - set(value) = definedExternally -} - -external interface NamedImports : Node { - override var parent: ImportClause - var elements: NodeArray -} - -external interface NamedExports : Node { - override var parent: ExportDeclaration - var elements: NodeArray -} - -external interface ImportSpecifier : NamedDeclaration { - override var parent: NamedImports - var propertyName: Identifier? - get() = definedExternally - set(value) = definedExternally - override var name: Identifier -} - -external interface ExportSpecifier : NamedDeclaration { - override var parent: NamedExports - var propertyName: Identifier? - get() = definedExternally - set(value) = definedExternally - override var name: Identifier -} - -external interface ExportAssignment : DeclarationStatement, JSDocContainer { - override var parent: SourceFile - var isExportEquals: Boolean? - get() = definedExternally - set(value) = definedExternally - var expression: Expression -} - -external interface FileReference : TextRange { - var fileName: String -} - -external interface CheckJsDirective : TextRange { - var enabled: Boolean -} - -external interface CommentRange : TextRange { - var hasTrailingNewLine: Boolean? - get() = definedExternally - set(value) = definedExternally - var kind: dynamic /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */ - get() = definedExternally - set(value) = definedExternally -} - -external interface SynthesizedComment : CommentRange { - var text: String - var hasLeadingNewline: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface JSDocTypeExpression : TypeNode { - var type: TypeNode -} - -external interface JSDocNameReference : Node { - var name: dynamic /* Identifier | QualifiedName | JSDocMemberName */ - get() = definedExternally - set(value) = definedExternally -} - -external interface JSDocMemberName : Node { - var left: dynamic /* Identifier | QualifiedName | JSDocMemberName */ - get() = definedExternally - set(value) = definedExternally - var right: Identifier -} - -external interface JSDocType : TypeNode { - var _jsDocTypeBrand: Any -} - -external interface JSDocAllType : JSDocType - -external interface JSDocUnknownType : JSDocType - -external interface JSDocNonNullableType : JSDocType { - var type: TypeNode -} - -external interface JSDocNullableType : JSDocType { - var type: TypeNode -} - -external interface JSDocOptionalType : JSDocType { - var type: TypeNode -} - -external interface JSDocFunctionType : JSDocType, SignatureDeclarationBase { - override var kind: Any -} - -external interface JSDocVariadicType : JSDocType { - var type: TypeNode -} - -external interface JSDocNamepathType : JSDocType { - var type: TypeNode -} - -external interface JSDoc : Node { - override var parent: dynamic /* ParameterDeclaration | CallSignatureDeclaration | ClassStaticBlockDeclaration | ConstructSignatureDeclaration | MethodSignature | PropertySignature | ArrowFunction | ParenthesizedExpression | SpreadAssignment | ShorthandPropertyAssignment | PropertyAssignment | FunctionExpression | EmptyStatement | DebuggerStatement | Block | VariableStatement | ExpressionStatement | IfStatement | DoStatement | WhileStatement | ForStatement | ForInStatement | ForOfStatement | BreakStatement | ContinueStatement | ReturnStatement | WithStatement | SwitchStatement | LabeledStatement | ThrowStatement | TryStatement | FunctionDeclaration | ConstructorDeclaration | MethodDeclaration | VariableDeclaration | PropertyDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | EnumMember | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | NamespaceExportDeclaration | ExportAssignment | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | ExportDeclaration | NamedTupleMember | Token & JSDocContainer */ - get() = definedExternally - set(value) = definedExternally - var tags: NodeArray? - get() = definedExternally - set(value) = definedExternally - var comment: dynamic /* String? | NodeArray? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface JSDocTag : Node { - override var parent: dynamic /* JSDoc | JSDocTypeLiteral */ - get() = definedExternally - set(value) = definedExternally - var tagName: Identifier - var comment: dynamic /* String? | NodeArray? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface JSDocLink : Node { - var name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ - get() = definedExternally - set(value) = definedExternally - var text: String -} - -external interface JSDocLinkCode : Node { - var name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ - get() = definedExternally - set(value) = definedExternally - var text: String -} - -external interface JSDocLinkPlain : Node { - var name: dynamic /* Identifier? | QualifiedName? | JSDocMemberName? */ - get() = definedExternally - set(value) = definedExternally - var text: String -} - -external interface JSDocText : Node { - var text: String -} - -external interface JSDocUnknownTag : JSDocTag - -external interface `T$21` { - var expression: dynamic /* Identifier | PropertyAccessEntityNameExpression */ - get() = definedExternally - set(value) = definedExternally -} - -external interface JSDocAugmentsTag : JSDocTag { - var `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */ -} - -external interface JSDocImplementsTag : JSDocTag { - var `class`: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */ -} - -external interface JSDocAuthorTag : JSDocTag - -external interface JSDocDeprecatedTag : JSDocTag - -external interface JSDocClassTag : JSDocTag - -external interface JSDocPublicTag : JSDocTag - -external interface JSDocPrivateTag : JSDocTag - -external interface JSDocProtectedTag : JSDocTag - -external interface JSDocReadonlyTag : JSDocTag - -external interface JSDocOverrideTag : JSDocTag - -external interface JSDocEnumTag : JSDocTag, Declaration { - override var parent: JSDoc - var typeExpression: JSDocTypeExpression -} - -external interface JSDocThisTag : JSDocTag { - var typeExpression: JSDocTypeExpression -} - -external interface JSDocTemplateTag : JSDocTag { - var constraint: JSDocTypeExpression? - var typeParameters: NodeArray -} - -external interface JSDocSeeTag : JSDocTag { - var name: JSDocNameReference? - get() = definedExternally - set(value) = definedExternally -} - -external interface JSDocReturnTag : JSDocTag { - var typeExpression: JSDocTypeExpression? - get() = definedExternally - set(value) = definedExternally -} - -external interface JSDocTypeTag : JSDocTag { - var typeExpression: JSDocTypeExpression -} - -external interface JSDocTypedefTag : JSDocTag, NamedDeclaration { - override var parent: JSDoc - var fullName: dynamic /* JSDocNamespaceDeclaration? | Identifier? */ - get() = definedExternally - set(value) = definedExternally - override var name: Identifier? - get() = definedExternally - set(value) = definedExternally - var typeExpression: dynamic /* JSDocTypeExpression? | JSDocTypeLiteral? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface JSDocCallbackTag : JSDocTag, NamedDeclaration { - override var parent: JSDoc - var fullName: dynamic /* JSDocNamespaceDeclaration? | Identifier? */ - get() = definedExternally - set(value) = definedExternally - override var name: Identifier? - get() = definedExternally - set(value) = definedExternally - var typeExpression: JSDocSignature -} - -external interface JSDocSignature : JSDocType, Declaration { - var typeParameters: Array? - get() = definedExternally - set(value) = definedExternally - var parameters: Array - var type: JSDocReturnTag? -} - -external interface JSDocPropertyLikeTag : JSDocTag, Declaration { - override var parent: JSDoc - var name: dynamic /* Identifier | QualifiedName */ - get() = definedExternally - set(value) = definedExternally - var typeExpression: JSDocTypeExpression? - get() = definedExternally - set(value) = definedExternally - var isNameFirst: Boolean - var isBracketed: Boolean -} - -external interface JSDocPropertyTag : JSDocPropertyLikeTag - -external interface JSDocParameterTag : JSDocPropertyLikeTag - -external interface JSDocTypeLiteral : JSDocType { - var jsDocPropertyTags: Array? - get() = definedExternally - set(value) = definedExternally - var isArrayType: Boolean -} - -external enum class FlowFlags { - Unreachable /* = 1 */, - Start /* = 2 */, - BranchLabel /* = 4 */, - LoopLabel /* = 8 */, - Assignment /* = 16 */, - TrueCondition /* = 32 */, - FalseCondition /* = 64 */, - SwitchClause /* = 128 */, - ArrayMutation /* = 256 */, - Call /* = 512 */, - ReduceLabel /* = 1024 */, - Referenced /* = 2048 */, - Shared /* = 4096 */, - Label /* = 12 */, - Condition /* = 96 */ -} - -external interface FlowNodeBase { - var flags: FlowFlags - var id: Number? - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowStart : FlowNodeBase { - var node: dynamic /* FunctionExpression? | ArrowFunction? | MethodDeclaration? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowLabel : FlowNodeBase { - var antecedents: Array? -} - -external interface FlowAssignment : FlowNodeBase { - var node: dynamic /* Expression | VariableDeclaration | BindingElement */ - get() = definedExternally - set(value) = definedExternally - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowCall : FlowNodeBase { - var node: CallExpression - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowCondition : FlowNodeBase { - var node: Expression - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowSwitchClause : FlowNodeBase { - var switchStatement: SwitchStatement - var clauseStart: Number - var clauseEnd: Number - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowArrayMutation : FlowNodeBase { - var node: dynamic /* CallExpression | BinaryExpression */ - get() = definedExternally - set(value) = definedExternally - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface FlowReduceLabel : FlowNodeBase { - var target: FlowLabel - var antecedents: Array - var antecedent: dynamic /* FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation | FlowReduceLabel */ - get() = definedExternally - set(value) = definedExternally -} - -external interface IncompleteType { - var flags: TypeFlags - var type: Type -} - -external interface AmdDependency { - var path: String - var name: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface SourceFile : Declaration { - fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter - fun getLineEndOfPosition(pos: Number): Number - fun getLineStarts(): Array - fun getPositionOfLineAndCharacter(line: Number, character: Number): Number - fun update(newText: String, textChangeRange: TextChangeRange): SourceFile - var statements: NodeArray - var endOfFileToken: Token - var fileName: String - var text: String - var amdDependencies: Array - var moduleName: String? - get() = definedExternally - set(value) = definedExternally - var referencedFiles: Array - var typeReferenceDirectives: Array - var libReferenceDirectives: Array - var languageVariant: LanguageVariant - var isDeclarationFile: Boolean - var hasNoDefaultLib: Boolean - var languageVersion: ScriptTarget -} - -external interface Bundle : Node { - var prepends: Array - var sourceFiles: Array -} - -external interface InputFiles : Node { - var javascriptPath: String? - get() = definedExternally - set(value) = definedExternally - var javascriptText: String - var javascriptMapPath: String? - get() = definedExternally - set(value) = definedExternally - var javascriptMapText: String? - get() = definedExternally - set(value) = definedExternally - var declarationPath: String? - get() = definedExternally - set(value) = definedExternally - var declarationText: String - var declarationMapPath: String? - get() = definedExternally - set(value) = definedExternally - var declarationMapText: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface UnparsedSource : Node { - var fileName: String - var text: String - var prologues: Array - var helpers: Array? - var referencedFiles: Array - var typeReferenceDirectives: Array? - var libReferenceDirectives: Array - var hasNoDefaultLib: Boolean? - get() = definedExternally - set(value) = definedExternally - var sourceMapPath: String? - get() = definedExternally - set(value) = definedExternally - var sourceMapText: String? - get() = definedExternally - set(value) = definedExternally - var syntheticReferences: Array? - get() = definedExternally - set(value) = definedExternally - var texts: Array -} - -external interface UnparsedSection : Node { - override var kind: SyntaxKind - override var parent: UnparsedSource - var data: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface UnparsedPrologue : UnparsedSection { - override var parent: UnparsedSource -} - -external interface UnparsedPrepend : UnparsedSection { - override var parent: UnparsedSource - var texts: Array -} - -external interface UnparsedTextLike : UnparsedSection { - override var kind: dynamic /* SyntaxKind.UnparsedText | SyntaxKind.UnparsedInternalText */ - get() = definedExternally - set(value) = definedExternally - override var parent: UnparsedSource -} - -external interface UnparsedSyntheticReference : UnparsedSection { - override var parent: UnparsedSource -} - -external interface JsonSourceFile : SourceFile { - override var statements: NodeArray -} - -external interface TsConfigSourceFile : JsonSourceFile { - var extendedSourceFiles: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface JsonMinusNumericLiteral : PrefixUnaryExpression { - override var kind: Any - override var operator: Any - override var operand: NumericLiteral -} - -external interface JsonObjectExpressionStatement : ExpressionStatement { - override var expression: dynamic /* ObjectLiteralExpression | ArrayLiteralExpression | JsonMinusNumericLiteral | NumericLiteral | StringLiteral | TrueLiteral | FalseLiteral | NullLiteral */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ScriptReferenceHost { - fun getCompilerOptions(): CompilerOptions - fun getSourceFile(fileName: String): SourceFile? - fun getSourceFileByPath(path: String /* String & `T$3` */): SourceFile? - fun getCurrentDirectory(): String -} - -external interface ParseConfigHost { - var useCaseSensitiveFileNames: Boolean - fun readDirectory(rootDir: String, extensions: Array, excludes: Array?, includes: Array, depth: Number = definedExternally): Array - fun fileExists(path: String): Boolean - fun readFile(path: String): String? - val trace: ((s: String) -> Unit)? -} - -external open class OperationCanceledException - -external interface CancellationToken { - fun isCancellationRequested(): Boolean - fun throwIfCancellationRequested() -} - -external interface Program : ScriptReferenceHost { - override fun getCurrentDirectory(): String - fun getRootFileNames(): Array - fun getSourceFiles(): Array - fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult - fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getDeclarationDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getConfigFileParsingDiagnostics(): Array - fun getTypeChecker(): TypeChecker - fun getNodeCount(): Number - fun getIdentifierCount(): Number - fun getSymbolCount(): Number - fun getTypeCount(): Number - fun getInstantiationCount(): Number - fun getRelationCacheSizes(): `T$6` - fun isSourceFileFromExternalLibrary(file: SourceFile): Boolean - fun isSourceFileDefaultLibrary(file: SourceFile): Boolean - fun getProjectReferences(): Array? - fun getResolvedProjectReferences(): Array? -} - -external interface ResolvedProjectReference { - var commandLine: ParsedCommandLine - var sourceFile: SourceFile - var references: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface CustomTransformer { - fun transformSourceFile(node: SourceFile): SourceFile - fun transformBundle(node: Bundle): Bundle -} - -external interface CustomTransformers { - var before: Array | CustomTransformerFactory */>? - get() = definedExternally - set(value) = definedExternally - var after: Array | CustomTransformerFactory */>? - get() = definedExternally - set(value) = definedExternally - var afterDeclarations: Array | CustomTransformerFactory */>? - get() = definedExternally - set(value) = definedExternally -} - -external interface SourceMapSpan { - var emittedLine: Number - var emittedColumn: Number - var sourceLine: Number - var sourceColumn: Number - var nameIndex: Number? - get() = definedExternally - set(value) = definedExternally - var sourceIndex: Number -} - -external enum class ExitStatus { - Success /* = 0 */, - DiagnosticsPresent_OutputsSkipped /* = 1 */, - DiagnosticsPresent_OutputsGenerated /* = 2 */, - InvalidProject_OutputsSkipped /* = 3 */, - ProjectReferenceCycle_OutputsSkipped /* = 4 */, - ProjectReferenceCycle_OutputsSkupped /* = 4 */ -} - -external interface EmitResult { - var emitSkipped: Boolean - var diagnostics: Array - var emittedFiles: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface `T$22` { - var typeArguments: NodeArray? - get() = definedExternally - set(value) = definedExternally -} - -external interface TypeChecker { - fun getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type - fun getDeclaredTypeOfSymbol(symbol: Symbol): Type - fun getPropertiesOfType(type: Type): Array - fun getPropertyOfType(type: Type, propertyName: String): Symbol? - fun getPrivateIdentifierPropertyOfType(leftType: Type, name: String, location: Node): Symbol? - fun getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo? - fun getIndexInfosOfType(type: Type): Array - fun getSignaturesOfType(type: Type, kind: SignatureKind): Array - fun getIndexTypeOfType(type: Type, kind: IndexKind): Type? - fun getBaseTypes(type: InterfaceType): Array - fun getBaseTypeOfLiteralType(type: Type): Type - fun getWidenedType(type: Type): Type - fun getReturnTypeOfSignature(signature: Signature): Type - fun getNullableType(type: Type, flags: TypeFlags): Type - fun getNonNullableType(type: Type): Type - fun getTypeArguments(type: TypeReference): Array - fun typeToTypeNode(type: Type, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeNode? - fun signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ - fun indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): IndexSignatureDeclaration? - fun symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): dynamic /* Identifier? | QualifiedName? */ - fun symbolToExpression(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): Expression? - fun symbolToTypeParameterDeclarations(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): NodeArray? - fun symbolToParameterDeclaration(symbol: Symbol, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): ParameterDeclaration? - fun typeParameterToDeclaration(parameter: TypeParameter, enclosingDeclaration: Node?, flags: NodeBuilderFlags?): TypeParameterDeclaration? - fun getSymbolsInScope(location: Node, meaning: SymbolFlags): Array - fun getSymbolAtLocation(node: Node): Symbol? - fun getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: String): Array - fun getShorthandAssignmentValueSymbol(location: Node?): Symbol? - fun getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol? - fun getExportSpecifierLocalTargetSymbol(location: Identifier): Symbol? - fun getExportSymbolOfSymbol(symbol: Symbol): Symbol - fun getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol? - fun getTypeOfAssignmentPattern(pattern: ObjectLiteralExpression): Type - fun getTypeOfAssignmentPattern(pattern: ArrayLiteralExpression): Type - fun getTypeAtLocation(node: Node): Type - fun getTypeFromTypeNode(node: TypeNode): Type - fun signatureToString(signature: Signature, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally, kind: SignatureKind = definedExternally): String - fun typeToString(type: Type, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun symbolToString(symbol: Symbol, enclosingDeclaration: Node = definedExternally, meaning: SymbolFlags = definedExternally, flags: SymbolFormatFlags = definedExternally): String - fun typePredicateToString(predicate: ThisTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun typePredicateToString(predicate: ThisTypePredicate): String - fun typePredicateToString(predicate: ThisTypePredicate, enclosingDeclaration: Node = definedExternally): String - fun typePredicateToString(predicate: IdentifierTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun typePredicateToString(predicate: IdentifierTypePredicate): String - fun typePredicateToString(predicate: IdentifierTypePredicate, enclosingDeclaration: Node = definedExternally): String - fun typePredicateToString(predicate: AssertsThisTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun typePredicateToString(predicate: AssertsThisTypePredicate): String - fun typePredicateToString(predicate: AssertsThisTypePredicate, enclosingDeclaration: Node = definedExternally): String - fun typePredicateToString(predicate: AssertsIdentifierTypePredicate, enclosingDeclaration: Node = definedExternally, flags: TypeFormatFlags = definedExternally): String - fun typePredicateToString(predicate: AssertsIdentifierTypePredicate): String - fun typePredicateToString(predicate: AssertsIdentifierTypePredicate, enclosingDeclaration: Node = definedExternally): String - fun getFullyQualifiedName(symbol: Symbol): String - fun getAugmentedPropertiesOfType(type: Type): Array - fun getRootSymbols(symbol: Symbol): Array - fun getSymbolOfExpando(node: Node, allowDeclaration: Boolean): Symbol? - fun getContextualType(node: Expression): Type? - fun getResolvedSignature(node: CallExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: CallExpression): Signature? - fun getResolvedSignature(node: CallExpression, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: NewExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: NewExpression): Signature? - fun getResolvedSignature(node: NewExpression, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: TaggedTemplateExpression, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: TaggedTemplateExpression): Signature? - fun getResolvedSignature(node: TaggedTemplateExpression, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: Decorator, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: Decorator): Signature? - fun getResolvedSignature(node: Decorator, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: JsxSelfClosingElement, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: JsxSelfClosingElement): Signature? - fun getResolvedSignature(node: JsxSelfClosingElement, candidatesOutArray: Array = definedExternally): Signature? - fun getResolvedSignature(node: JsxOpeningElement, candidatesOutArray: Array = definedExternally, argumentCount: Number = definedExternally): Signature? - fun getResolvedSignature(node: JsxOpeningElement): Signature? - fun getResolvedSignature(node: JsxOpeningElement, candidatesOutArray: Array = definedExternally): Signature? - fun getSignatureFromDeclaration(declaration: CallSignatureDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: ConstructSignatureDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: MethodSignature): Signature? - fun getSignatureFromDeclaration(declaration: IndexSignatureDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: FunctionTypeNode): Signature? - fun getSignatureFromDeclaration(declaration: ConstructorTypeNode): Signature? - fun getSignatureFromDeclaration(declaration: JSDocFunctionType): Signature? - fun getSignatureFromDeclaration(declaration: FunctionDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: MethodDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: ConstructorDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: GetAccessorDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: SetAccessorDeclaration): Signature? - fun getSignatureFromDeclaration(declaration: FunctionExpression): Signature? - fun getSignatureFromDeclaration(declaration: ArrowFunction): Signature? - fun isImplementationOfOverload(node: CallSignatureDeclaration): Boolean? - fun isImplementationOfOverload(node: ConstructSignatureDeclaration): Boolean? - fun isImplementationOfOverload(node: MethodSignature): Boolean? - fun isImplementationOfOverload(node: IndexSignatureDeclaration): Boolean? - fun isImplementationOfOverload(node: FunctionTypeNode): Boolean? - fun isImplementationOfOverload(node: ConstructorTypeNode): Boolean? - fun isImplementationOfOverload(node: JSDocFunctionType): Boolean? - fun isImplementationOfOverload(node: FunctionDeclaration): Boolean? - fun isImplementationOfOverload(node: MethodDeclaration): Boolean? - fun isImplementationOfOverload(node: ConstructorDeclaration): Boolean? - fun isImplementationOfOverload(node: GetAccessorDeclaration): Boolean? - fun isImplementationOfOverload(node: SetAccessorDeclaration): Boolean? - fun isImplementationOfOverload(node: FunctionExpression): Boolean? - fun isImplementationOfOverload(node: ArrowFunction): Boolean? - fun isUndefinedSymbol(symbol: Symbol): Boolean - fun isArgumentsSymbol(symbol: Symbol): Boolean - fun isUnknownSymbol(symbol: Symbol): Boolean - fun getConstantValue(node: EnumMember): dynamic /* String? | Number? */ - fun getConstantValue(node: PropertyAccessExpression): dynamic /* String? | Number? */ - fun getConstantValue(node: ElementAccessExpression): dynamic /* String? | Number? */ - fun isValidPropertyAccess(node: PropertyAccessExpression, propertyName: String): Boolean - fun isValidPropertyAccess(node: QualifiedName, propertyName: String): Boolean - fun isValidPropertyAccess(node: ImportTypeNode, propertyName: String): Boolean - fun getAliasedSymbol(symbol: Symbol): Symbol - fun getImmediateAliasedSymbol(symbol: Symbol): Symbol? - fun getExportsOfModule(moduleSymbol: Symbol): Array - fun getJsxIntrinsicTagNamesAt(location: Node): Array - fun isOptionalParameter(node: ParameterDeclaration): Boolean - fun getAmbientModules(): Array - fun tryGetMemberInModuleExports(memberName: String, moduleSymbol: Symbol): Symbol? - fun getApparentType(type: Type): Type - fun getBaseConstraintOfType(type: Type): Type? - fun getDefaultFromTypeParameter(type: Type): Type? - fun runWithCancellationToken(token: CancellationToken, cb: (checker: TypeChecker) -> T): T -} - -external enum class NodeBuilderFlags { - None /* = 0 */, - NoTruncation /* = 1 */, - WriteArrayAsGenericType /* = 2 */, - GenerateNamesForShadowedTypeParams /* = 4 */, - UseStructuralFallback /* = 8 */, - ForbidIndexedAccessSymbolReferences /* = 16 */, - WriteTypeArgumentsOfSignature /* = 32 */, - UseFullyQualifiedType /* = 64 */, - UseOnlyExternalAliasing /* = 128 */, - SuppressAnyReturnType /* = 256 */, - WriteTypeParametersInQualifiedName /* = 512 */, - MultilineObjectLiterals /* = 1024 */, - WriteClassExpressionAsTypeLiteral /* = 2048 */, - UseTypeOfFunction /* = 4096 */, - OmitParameterModifiers /* = 8192 */, - UseAliasDefinedOutsideCurrentScope /* = 16384 */, - UseSingleQuotesForStringLiteralType /* = 268435456 */, - NoTypeReduction /* = 536870912 */, - NoUndefinedOptionalParameterType /* = 1073741824 */, - AllowThisInObjectLiteral /* = 32768 */, - AllowQualifiedNameInPlaceOfIdentifier /* = 65536 */, - AllowQualifedNameInPlaceOfIdentifier /* = 65536 */, - AllowAnonymousIdentifier /* = 131072 */, - AllowEmptyUnionOrIntersection /* = 262144 */, - AllowEmptyTuple /* = 524288 */, - AllowUniqueESSymbolType /* = 1048576 */, - AllowEmptyIndexInfoType /* = 2097152 */, - AllowNodeModulesRelativePaths /* = 67108864 */, - IgnoreErrors /* = 70221824 */, - InObjectTypeLiteral /* = 4194304 */, - InTypeAlias /* = 8388608 */, - InInitialEntityName /* = 16777216 */ -} - -external enum class TypeFormatFlags { - None /* = 0 */, - NoTruncation /* = 1 */, - WriteArrayAsGenericType /* = 2 */, - UseStructuralFallback /* = 8 */, - WriteTypeArgumentsOfSignature /* = 32 */, - UseFullyQualifiedType /* = 64 */, - SuppressAnyReturnType /* = 256 */, - MultilineObjectLiterals /* = 1024 */, - WriteClassExpressionAsTypeLiteral /* = 2048 */, - UseTypeOfFunction /* = 4096 */, - OmitParameterModifiers /* = 8192 */, - UseAliasDefinedOutsideCurrentScope /* = 16384 */, - UseSingleQuotesForStringLiteralType /* = 268435456 */, - NoTypeReduction /* = 536870912 */, - AllowUniqueESSymbolType /* = 1048576 */, - AddUndefined /* = 131072 */, - WriteArrowStyleSignature /* = 262144 */, - InArrayType /* = 524288 */, - InElementType /* = 2097152 */, - InFirstTypeArgument /* = 4194304 */, - InTypeAlias /* = 8388608 */, - WriteOwnNameForAnyLike /* = 0 */, - NodeBuilderFlagsMask /* = 814775659 */ -} - -external enum class SymbolFormatFlags { - None /* = 0 */, - WriteTypeParametersOrArguments /* = 1 */, - UseOnlyExternalAliasing /* = 2 */, - AllowAnyNodeKind /* = 4 */, - UseAliasDefinedOutsideCurrentScope /* = 8 */ -} - -external enum class TypePredicateKind { - This /* = 0 */, - Identifier /* = 1 */, - AssertsThis /* = 2 */, - AssertsIdentifier /* = 3 */ -} - -external interface TypePredicateBase { - var kind: TypePredicateKind - var type: Type? -} - -external interface ThisTypePredicate : TypePredicateBase { - var parameterName: Any? - var parameterIndex: Any? -} - -external interface IdentifierTypePredicate : TypePredicateBase { - var parameterName: String - var parameterIndex: Number -} - -external interface AssertsThisTypePredicate : TypePredicateBase { - var parameterName: Any? - var parameterIndex: Any? - override var type: Type? -} - -external interface AssertsIdentifierTypePredicate : TypePredicateBase { - var parameterName: String - var parameterIndex: Number - override var type: Type? -} - -external enum class SymbolFlags { - None /* = 0 */, - FunctionScopedVariable /* = 1 */, - BlockScopedVariable /* = 2 */, - Property /* = 4 */, - EnumMember /* = 8 */, - Function /* = 16 */, - Class /* = 32 */, - Interface /* = 64 */, - ConstEnum /* = 128 */, - RegularEnum /* = 256 */, - ValueModule /* = 512 */, - NamespaceModule /* = 1024 */, - TypeLiteral /* = 2048 */, - ObjectLiteral /* = 4096 */, - Method /* = 8192 */, - Constructor /* = 16384 */, - GetAccessor /* = 32768 */, - SetAccessor /* = 65536 */, - Signature /* = 131072 */, - TypeParameter /* = 262144 */, - TypeAlias /* = 524288 */, - ExportValue /* = 1048576 */, - Alias /* = 2097152 */, - Prototype /* = 4194304 */, - ExportStar /* = 8388608 */, - Optional /* = 16777216 */, - Transient /* = 33554432 */, - Assignment /* = 67108864 */, - ModuleExports /* = 134217728 */, - Enum /* = 384 */, - Variable /* = 3 */, - Value /* = 111551 */, - Type /* = 788968 */, - Namespace /* = 1920 */, - Module /* = 1536 */, - Accessor /* = 98304 */, - FunctionScopedVariableExcludes /* = 111550 */, - BlockScopedVariableExcludes /* = 111551 */, - ParameterExcludes /* = 111551 */, - PropertyExcludes /* = 0 */, - EnumMemberExcludes /* = 900095 */, - FunctionExcludes /* = 110991 */, - ClassExcludes /* = 899503 */, - InterfaceExcludes /* = 788872 */, - RegularEnumExcludes /* = 899327 */, - ConstEnumExcludes /* = 899967 */, - ValueModuleExcludes /* = 110735 */, - NamespaceModuleExcludes /* = 0 */, - MethodExcludes /* = 103359 */, - GetAccessorExcludes /* = 46015 */, - SetAccessorExcludes /* = 78783 */, - TypeParameterExcludes /* = 526824 */, - TypeAliasExcludes /* = 788968 */, - AliasExcludes /* = 2097152 */, - ModuleMember /* = 2623475 */, - ExportHasLocal /* = 944 */, - BlockScoped /* = 418 */, - PropertyOrAccessor /* = 98308 */, - ClassMember /* = 106500 */ -} - -external interface Symbol { - var name: String - fun getFlags(): SymbolFlags - fun getEscapedName(): dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - fun getName(): String - fun getDeclarations(): Array? - fun getDocumentationComment(typeChecker: TypeChecker?): Array - fun getJsDocTags(checker: TypeChecker = definedExternally): Array - var flags: SymbolFlags - var escapedName: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - get() = definedExternally - set(value) = definedExternally - var declarations: Array? - get() = definedExternally - set(value) = definedExternally - var valueDeclaration: Declaration? - get() = definedExternally - set(value) = definedExternally - var members: SymbolTable? - get() = definedExternally - set(value) = definedExternally - var exports: SymbolTable? - get() = definedExternally - set(value) = definedExternally - var globalExports: SymbolTable? - get() = definedExternally - set(value) = definedExternally -} - -external enum class InternalSymbolName { - Call /* = "__call" */, - Constructor /* = "__constructor" */, - New /* = "__new" */, - Index /* = "__index" */, - ExportStar /* = "__export" */, - Global /* = "__global" */, - Missing /* = "__missing" */, - Type /* = "__type" */, - Object /* = "__object" */, - JSXAttributes /* = "__jsxAttributes" */, - Class /* = "__class" */, - Function /* = "__function" */, - Computed /* = "__computed" */, - Resolving /* = "__resolving__" */, - ExportEquals /* = "export=" */, - Default /* = "default" */, - This /* = "this" */ -} - -external interface ReadonlyUnderscoreEscapedMap : ReadonlyESMap - -external interface UnderscoreEscapedMap : ESMap, ReadonlyUnderscoreEscapedMap - -external enum class TypeFlags { - Any /* = 1 */, - Unknown /* = 2 */, - String /* = 4 */, - Number /* = 8 */, - Boolean /* = 16 */, - Enum /* = 32 */, - BigInt /* = 64 */, - StringLiteral /* = 128 */, - NumberLiteral /* = 256 */, - BooleanLiteral /* = 512 */, - EnumLiteral /* = 1024 */, - BigIntLiteral /* = 2048 */, - ESSymbol /* = 4096 */, - UniqueESSymbol /* = 8192 */, - Void /* = 16384 */, - Undefined /* = 32768 */, - Null /* = 65536 */, - Never /* = 131072 */, - TypeParameter /* = 262144 */, - Object /* = 524288 */, - Union /* = 1048576 */, - Intersection /* = 2097152 */, - Index /* = 4194304 */, - IndexedAccess /* = 8388608 */, - Conditional /* = 16777216 */, - Substitution /* = 33554432 */, - NonPrimitive /* = 67108864 */, - TemplateLiteral /* = 134217728 */, - StringMapping /* = 268435456 */, - Literal /* = 2944 */, - Unit /* = 109440 */, - StringOrNumberLiteral /* = 384 */, - PossiblyFalsy /* = 117724 */, - StringLike /* = 402653316 */, - NumberLike /* = 296 */, - BigIntLike /* = 2112 */, - BooleanLike /* = 528 */, - EnumLike /* = 1056 */, - ESSymbolLike /* = 12288 */, - VoidLike /* = 49152 */, - UnionOrIntersection /* = 3145728 */, - StructuredType /* = 3670016 */, - TypeVariable /* = 8650752 */, - InstantiableNonPrimitive /* = 58982400 */, - InstantiablePrimitive /* = 406847488 */, - Instantiable /* = 465829888 */, - StructuredOrInstantiable /* = 469499904 */, - Narrowable /* = 536624127 */ -} - -external interface Type { - fun getFlags(): TypeFlags - fun getSymbol(): Symbol? - fun getProperties(): Array - fun getProperty(propertyName: String): Symbol? - fun getApparentProperties(): Array - fun getCallSignatures(): Array - fun getConstructSignatures(): Array - fun getStringIndexType(): Type? - fun getNumberIndexType(): Type? - fun getBaseTypes(): Array? - fun getNonNullableType(): Type - fun getConstraint(): Type? - fun getDefault(): Type? - fun isUnion(): Boolean - fun isIntersection(): Boolean - fun isUnionOrIntersection(): Boolean - fun isLiteral(): Boolean - fun isStringLiteral(): Boolean - fun isNumberLiteral(): Boolean - fun isTypeParameter(): Boolean - fun isClassOrInterface(): Boolean - fun isClass(): Boolean - var flags: TypeFlags - var symbol: Symbol - var pattern: dynamic /* ObjectBindingPattern? | ArrayBindingPattern? | ObjectLiteralExpression? | ArrayLiteralExpression? */ - get() = definedExternally - set(value) = definedExternally - var aliasSymbol: Symbol? - get() = definedExternally - set(value) = definedExternally - var aliasTypeArguments: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface LiteralType : Type { - var value: dynamic /* String | Number | PseudoBigInt */ - get() = definedExternally - set(value) = definedExternally - var freshType: LiteralType - var regularType: LiteralType -} - -external interface UniqueESSymbolType : Type { - override var symbol: Symbol - var escapedName: dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - get() = definedExternally - set(value) = definedExternally -} - -external interface StringLiteralType : LiteralType { - override var value: String -} - -external interface NumberLiteralType : LiteralType { - override var value: Number -} - -external interface BigIntLiteralType : LiteralType { - override var value: PseudoBigInt -} - -external interface EnumType : Type - -external enum class ObjectFlags { - Class /* = 1 */, - Interface /* = 2 */, - Reference /* = 4 */, - Tuple /* = 8 */, - Anonymous /* = 16 */, - Mapped /* = 32 */, - Instantiated /* = 64 */, - ObjectLiteral /* = 128 */, - EvolvingArray /* = 256 */, - ObjectLiteralPatternWithComputedProperties /* = 512 */, - ReverseMapped /* = 1024 */, - JsxAttributes /* = 2048 */, - MarkerType /* = 4096 */, - JSLiteral /* = 8192 */, - FreshLiteral /* = 16384 */, - ArrayLiteral /* = 32768 */, - ClassOrInterface /* = 3 */, - ContainsSpread /* = 4194304 */, - ObjectRestType /* = 8388608 */ -} - -external interface ObjectType : Type { - var objectFlags: ObjectFlags -} - -external interface InterfaceType : ObjectType { - var typeParameters: Array? - var outerTypeParameters: Array? - var localTypeParameters: Array? - var thisType: TypeParameter? -} - -external interface InterfaceTypeWithDeclaredMembers : InterfaceType { - var declaredProperties: Array - var declaredCallSignatures: Array - var declaredConstructSignatures: Array - var declaredIndexInfos: Array -} - -external interface TypeReference : ObjectType { - var typeArguments: Array? - get() = definedExternally - set(value) = definedExternally - var target: GenericType - var node: dynamic /* TypeReferenceNode? | ArrayTypeNode? | TupleTypeNode? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface DeferredTypeReference : TypeReference - -external interface GenericType : InterfaceType, TypeReference - -external enum class ElementFlags { - Required /* = 1 */, - Optional /* = 2 */, - Rest /* = 4 */, - Variadic /* = 8 */, - Fixed /* = 3 */, - Variable /* = 12 */, - NonRequired /* = 14 */, - NonRest /* = 11 */ -} - -external interface TupleType : GenericType { - var elementFlags: Array - var minLength: Number - var fixedLength: Number - var hasRestElement: Boolean - var combinedFlags: ElementFlags - var readonly: Boolean - var labeledElementDeclarations: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface TupleTypeReference : TypeReference { - override var target: TupleType -} - -external interface UnionOrIntersectionType : Type { - var types: Array -} - -external interface UnionType : UnionOrIntersectionType - -external interface IntersectionType : UnionOrIntersectionType - -external interface EvolvingArrayType : ObjectType { - var elementType: Type - var finalArrayType: Type? - get() = definedExternally - set(value) = definedExternally -} - -external interface InstantiableType : Type - -external interface TypeParameter : InstantiableType - -external interface IndexedAccessType : InstantiableType { - var objectType: Type - var indexType: Type - var constraint: Type? - get() = definedExternally - set(value) = definedExternally - var simplifiedForReading: Type? - get() = definedExternally - set(value) = definedExternally - var simplifiedForWriting: Type? - get() = definedExternally - set(value) = definedExternally -} - -external interface IndexType : InstantiableType { - var type: dynamic /* InstantiableType | UnionOrIntersectionType */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ConditionalRoot { - var node: ConditionalTypeNode - var checkType: Type - var extendsType: Type - var isDistributive: Boolean - var inferTypeParameters: Array? - get() = definedExternally - set(value) = definedExternally - var outerTypeParameters: Array? - get() = definedExternally - set(value) = definedExternally - var instantiations: Map? - get() = definedExternally - set(value) = definedExternally - var aliasSymbol: Symbol? - get() = definedExternally - set(value) = definedExternally - var aliasTypeArguments: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface ConditionalType : InstantiableType { - var root: ConditionalRoot - var checkType: Type - var extendsType: Type - var resolvedTrueType: Type - var resolvedFalseType: Type -} - -external interface TemplateLiteralType : InstantiableType { - var texts: Array - var types: Array -} - -external interface StringMappingType : InstantiableType { - override var symbol: Symbol - var type: Type -} - -external interface SubstitutionType : InstantiableType { - var objectFlags: ObjectFlags - var baseType: Type - var substitute: Type -} - -external enum class SignatureKind { - Call /* = 0 */, - Construct /* = 1 */ -} - -external interface Signature { - fun getDeclaration(): dynamic /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction */ - fun getTypeParameters(): Array? - fun getParameters(): Array - fun getReturnType(): Type - fun getDocumentationComment(typeChecker: TypeChecker?): Array - fun getJsDocTags(): Array - var declaration: dynamic /* CallSignatureDeclaration? | ConstructSignatureDeclaration? | MethodSignature? | IndexSignatureDeclaration? | FunctionTypeNode? | ConstructorTypeNode? | JSDocFunctionType? | FunctionDeclaration? | MethodDeclaration? | ConstructorDeclaration? | GetAccessorDeclaration? | SetAccessorDeclaration? | FunctionExpression? | ArrowFunction? | JSDocSignature? */ - get() = definedExternally - set(value) = definedExternally - var typeParameters: Array? - get() = definedExternally - set(value) = definedExternally - var parameters: Array -} - -external enum class IndexKind { - String /* = 0 */, - Number /* = 1 */ -} - -external interface IndexInfo { - var keyType: Type - var type: Type - var isReadonly: Boolean - var declaration: IndexSignatureDeclaration? - get() = definedExternally - set(value) = definedExternally -} - -external enum class InferencePriority { - NakedTypeVariable /* = 1 */, - SpeculativeTuple /* = 2 */, - SubstituteSource /* = 4 */, - HomomorphicMappedType /* = 8 */, - PartialHomomorphicMappedType /* = 16 */, - MappedTypeConstraint /* = 32 */, - ContravariantConditional /* = 64 */, - ReturnType /* = 128 */, - LiteralKeyof /* = 256 */, - NoConstraints /* = 512 */, - AlwaysStrict /* = 1024 */, - MaxValue /* = 2048 */, - PriorityImpliesCombination /* = 416 */, - Circularity /* = -1 */ -} - -external interface FileExtensionInfo { - var extension: String - var isMixedContent: Boolean - var scriptKind: ScriptKind? - get() = definedExternally - set(value) = definedExternally -} - -external interface DiagnosticMessage { - var key: String - var category: DiagnosticCategory - var code: Number - var message: String - var reportsUnnecessary: Any? - get() = definedExternally - set(value) = definedExternally - var reportsDeprecated: Any? - get() = definedExternally - set(value) = definedExternally -} - -external interface DiagnosticMessageChain { - var messageText: String - var category: DiagnosticCategory - var code: Number - var next: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface Diagnostic : DiagnosticRelatedInformation { - var reportsUnnecessary: Any? - get() = definedExternally - set(value) = definedExternally - var reportsDeprecated: Any? - get() = definedExternally - set(value) = definedExternally - var source: String? - get() = definedExternally - set(value) = definedExternally - var relatedInformation: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface DiagnosticRelatedInformation { - var category: DiagnosticCategory - var code: Number - var file: SourceFile? - var start: Number? - var length: Number? - var messageText: dynamic /* String | DiagnosticMessageChain */ - get() = definedExternally - set(value) = definedExternally -} - -external interface DiagnosticWithLocation : Diagnostic - -external enum class DiagnosticCategory { - Warning /* = 0 */, - Error /* = 1 */, - Suggestion /* = 2 */, - Message /* = 3 */ -} - -external enum class ModuleResolutionKind { - Classic /* = 1 */, - NodeJs /* = 2 */ -} - -external interface PluginImport { - var name: String -} - -external interface ProjectReference { - var path: String - var originalPath: String? - get() = definedExternally - set(value) = definedExternally - var prepend: Boolean? - get() = definedExternally - set(value) = definedExternally - var circular: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external enum class WatchFileKind { - FixedPollingInterval /* = 0 */, - PriorityPollingInterval /* = 1 */, - DynamicPriorityPolling /* = 2 */, - FixedChunkSizePolling /* = 3 */, - UseFsEvents /* = 4 */, - UseFsEventsOnParentDirectory /* = 5 */ -} - -external enum class WatchDirectoryKind { - UseFsEvents /* = 0 */, - FixedPollingInterval /* = 1 */, - DynamicPriorityPolling /* = 2 */, - FixedChunkSizePolling /* = 3 */ -} - -external enum class PollingWatchKind { - FixedInterval /* = 0 */, - PriorityInterval /* = 1 */, - DynamicPriority /* = 2 */, - FixedChunkSize /* = 3 */ -} - -external interface CompilerOptions { - var allowJs: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowSyntheticDefaultImports: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowUmdGlobalAccess: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowUnreachableCode: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowUnusedLabels: Boolean? - get() = definedExternally - set(value) = definedExternally - var alwaysStrict: Boolean? - get() = definedExternally - set(value) = definedExternally - var baseUrl: String? - get() = definedExternally - set(value) = definedExternally - var charset: String? - get() = definedExternally - set(value) = definedExternally - var checkJs: Boolean? - get() = definedExternally - set(value) = definedExternally - var declaration: Boolean? - get() = definedExternally - set(value) = definedExternally - var declarationMap: Boolean? - get() = definedExternally - set(value) = definedExternally - var emitDeclarationOnly: Boolean? - get() = definedExternally - set(value) = definedExternally - var declarationDir: String? - get() = definedExternally - set(value) = definedExternally - var disableSizeLimit: Boolean? - get() = definedExternally - set(value) = definedExternally - var disableSourceOfProjectReferenceRedirect: Boolean? - get() = definedExternally - set(value) = definedExternally - var disableSolutionSearching: Boolean? - get() = definedExternally - set(value) = definedExternally - var disableReferencedProjectLoad: Boolean? - get() = definedExternally - set(value) = definedExternally - var downlevelIteration: Boolean? - get() = definedExternally - set(value) = definedExternally - var emitBOM: Boolean? - get() = definedExternally - set(value) = definedExternally - var emitDecoratorMetadata: Boolean? - get() = definedExternally - set(value) = definedExternally - var exactOptionalPropertyTypes: Boolean? - get() = definedExternally - set(value) = definedExternally - var experimentalDecorators: Boolean? - get() = definedExternally - set(value) = definedExternally - var forceConsistentCasingInFileNames: Boolean? - get() = definedExternally - set(value) = definedExternally - var importHelpers: Boolean? - get() = definedExternally - set(value) = definedExternally - var importsNotUsedAsValues: ImportsNotUsedAsValues? - get() = definedExternally - set(value) = definedExternally - var inlineSourceMap: Boolean? - get() = definedExternally - set(value) = definedExternally - var inlineSources: Boolean? - get() = definedExternally - set(value) = definedExternally - var isolatedModules: Boolean? - get() = definedExternally - set(value) = definedExternally - var jsx: JsxEmit? - get() = definedExternally - set(value) = definedExternally - var keyofStringsOnly: Boolean? - get() = definedExternally - set(value) = definedExternally - var lib: Array? - get() = definedExternally - set(value) = definedExternally - var locale: String? - get() = definedExternally - set(value) = definedExternally - var mapRoot: String? - get() = definedExternally - set(value) = definedExternally - var maxNodeModuleJsDepth: Number? - get() = definedExternally - set(value) = definedExternally - var module: ModuleKind? - get() = definedExternally - set(value) = definedExternally - var moduleResolution: ModuleResolutionKind? - get() = definedExternally - set(value) = definedExternally - var newLine: NewLineKind? - get() = definedExternally - set(value) = definedExternally - var noEmit: Boolean? - get() = definedExternally - set(value) = definedExternally - var noEmitHelpers: Boolean? - get() = definedExternally - set(value) = definedExternally - var noEmitOnError: Boolean? - get() = definedExternally - set(value) = definedExternally - var noErrorTruncation: Boolean? - get() = definedExternally - set(value) = definedExternally - var noFallthroughCasesInSwitch: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitAny: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitReturns: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitThis: Boolean? - get() = definedExternally - set(value) = definedExternally - var noStrictGenericChecks: Boolean? - get() = definedExternally - set(value) = definedExternally - var noUnusedLocals: Boolean? - get() = definedExternally - set(value) = definedExternally - var noUnusedParameters: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitUseStrict: Boolean? - get() = definedExternally - set(value) = definedExternally - var noPropertyAccessFromIndexSignature: Boolean? - get() = definedExternally - set(value) = definedExternally - var assumeChangesOnlyAffectDirectDependencies: Boolean? - get() = definedExternally - set(value) = definedExternally - var noLib: Boolean? - get() = definedExternally - set(value) = definedExternally - var noResolve: Boolean? - get() = definedExternally - set(value) = definedExternally - var noUncheckedIndexedAccess: Boolean? - get() = definedExternally - set(value) = definedExternally - var out: String? - get() = definedExternally - set(value) = definedExternally - var outDir: String? - get() = definedExternally - set(value) = definedExternally - var outFile: String? - get() = definedExternally - set(value) = definedExternally - var paths: MapLike>? - get() = definedExternally - set(value) = definedExternally - var preserveConstEnums: Boolean? - get() = definedExternally - set(value) = definedExternally - var noImplicitOverride: Boolean? - get() = definedExternally - set(value) = definedExternally - var preserveSymlinks: Boolean? - get() = definedExternally - set(value) = definedExternally - var project: String? - get() = definedExternally - set(value) = definedExternally - var reactNamespace: String? - get() = definedExternally - set(value) = definedExternally - var jsxFactory: String? - get() = definedExternally - set(value) = definedExternally - var jsxFragmentFactory: String? - get() = definedExternally - set(value) = definedExternally - var jsxImportSource: String? - get() = definedExternally - set(value) = definedExternally - var composite: Boolean? - get() = definedExternally - set(value) = definedExternally - var incremental: Boolean? - get() = definedExternally - set(value) = definedExternally - var tsBuildInfoFile: String? - get() = definedExternally - set(value) = definedExternally - var removeComments: Boolean? - get() = definedExternally - set(value) = definedExternally - var rootDir: String? - get() = definedExternally - set(value) = definedExternally - var rootDirs: Array? - get() = definedExternally - set(value) = definedExternally - var skipLibCheck: Boolean? - get() = definedExternally - set(value) = definedExternally - var skipDefaultLibCheck: Boolean? - get() = definedExternally - set(value) = definedExternally - var sourceMap: Boolean? - get() = definedExternally - set(value) = definedExternally - var sourceRoot: String? - get() = definedExternally - set(value) = definedExternally - var strict: Boolean? - get() = definedExternally - set(value) = definedExternally - var strictFunctionTypes: Boolean? - get() = definedExternally - set(value) = definedExternally - var strictBindCallApply: Boolean? - get() = definedExternally - set(value) = definedExternally - var strictNullChecks: Boolean? - get() = definedExternally - set(value) = definedExternally - var strictPropertyInitialization: Boolean? - get() = definedExternally - set(value) = definedExternally - var stripInternal: Boolean? - get() = definedExternally - set(value) = definedExternally - var suppressExcessPropertyErrors: Boolean? - get() = definedExternally - set(value) = definedExternally - var suppressImplicitAnyIndexErrors: Boolean? - get() = definedExternally - set(value) = definedExternally - var target: ScriptTarget? - get() = definedExternally - set(value) = definedExternally - var traceResolution: Boolean? - get() = definedExternally - set(value) = definedExternally - var useUnknownInCatchVariables: Boolean? - get() = definedExternally - set(value) = definedExternally - var resolveJsonModule: Boolean? - get() = definedExternally - set(value) = definedExternally - var types: Array? - get() = definedExternally - set(value) = definedExternally - var typeRoots: Array? - get() = definedExternally - set(value) = definedExternally - var esModuleInterop: Boolean? - get() = definedExternally - set(value) = definedExternally - var useDefineForClassFields: Boolean? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? | TsConfigSourceFile? */ - @nativeSetter - operator fun set(option: String, value: String?) - @nativeSetter - operator fun set(option: String, value: Number?) - @nativeSetter - operator fun set(option: String, value: Boolean?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: MapLike>?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: TsConfigSourceFile?) -} - -external interface WatchOptions { - var watchFile: WatchFileKind? - get() = definedExternally - set(value) = definedExternally - var watchDirectory: WatchDirectoryKind? - get() = definedExternally - set(value) = definedExternally - var fallbackPolling: PollingWatchKind? - get() = definedExternally - set(value) = definedExternally - var synchronousWatchDirectory: Boolean? - get() = definedExternally - set(value) = definedExternally - var excludeDirectories: Array? - get() = definedExternally - set(value) = definedExternally - var excludeFiles: Array? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ - @nativeSetter - operator fun set(option: String, value: String?) - @nativeSetter - operator fun set(option: String, value: Number?) - @nativeSetter - operator fun set(option: String, value: Boolean?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: MapLike>?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) -} - -external interface TypeAcquisition { - var enableAutoDiscovery: Boolean? - get() = definedExternally - set(value) = definedExternally - var enable: Boolean? - get() = definedExternally - set(value) = definedExternally - var include: Array? - get() = definedExternally - set(value) = definedExternally - var exclude: Array? - get() = definedExternally - set(value) = definedExternally - var disableFilenameBasedTypeAcquisition: Boolean? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ - @nativeSetter - operator fun set(option: String, value: String?) - @nativeSetter - operator fun set(option: String, value: Number?) - @nativeSetter - operator fun set(option: String, value: Boolean?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: MapLike>?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) -} - -external enum class ModuleKind { - None /* = 0 */, - CommonJS /* = 1 */, - AMD /* = 2 */, - UMD /* = 3 */, - System /* = 4 */, - ES2015 /* = 5 */, - ES2020 /* = 6 */, - ESNext /* = 99 */ -} - -external enum class JsxEmit { - None /* = 0 */, - Preserve /* = 1 */, - React /* = 2 */, - ReactNative /* = 3 */, - ReactJSX /* = 4 */, - ReactJSXDev /* = 5 */ -} - -external enum class ImportsNotUsedAsValues { - Remove /* = 0 */, - Preserve /* = 1 */, - Error /* = 2 */ -} - -external enum class NewLineKind { - CarriageReturnLineFeed /* = 0 */, - LineFeed /* = 1 */ -} - -external interface LineAndCharacter { - var line: Number - var character: Number -} - -external enum class ScriptKind { - Unknown /* = 0 */, - JS /* = 1 */, - JSX /* = 2 */, - TS /* = 3 */, - TSX /* = 4 */, - External /* = 5 */, - JSON /* = 6 */, - Deferred /* = 7 */ -} - -external enum class ScriptTarget { - ES3 /* = 0 */, - ES5 /* = 1 */, - ES2015 /* = 2 */, - ES2016 /* = 3 */, - ES2017 /* = 4 */, - ES2018 /* = 5 */, - ES2019 /* = 6 */, - ES2020 /* = 7 */, - ES2021 /* = 8 */, - ESNext /* = 99 */, - JSON /* = 100 */, - Latest /* = 99 */ -} - -external enum class LanguageVariant { - Standard /* = 0 */, - JSX /* = 1 */ -} - -external interface ParsedCommandLine { - var options: CompilerOptions - var typeAcquisition: TypeAcquisition? - get() = definedExternally - set(value) = definedExternally - var fileNames: Array - var projectReferences: Array? - get() = definedExternally - set(value) = definedExternally - var watchOptions: WatchOptions? - get() = definedExternally - set(value) = definedExternally - var raw: Any? - get() = definedExternally - set(value) = definedExternally - var errors: Array - var wildcardDirectories: MapLike? - get() = definedExternally - set(value) = definedExternally - var compileOnSave: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external enum class WatchDirectoryFlags { - None /* = 0 */, - Recursive /* = 1 */ -} - -external interface CreateProgramOptions { - var rootNames: Array - var options: CompilerOptions - var projectReferences: Array? - get() = definedExternally - set(value) = definedExternally - var host: CompilerHost? - get() = definedExternally - set(value) = definedExternally - var oldProgram: Program? - get() = definedExternally - set(value) = definedExternally - var configFileParsingDiagnostics: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface ModuleResolutionHost { - fun fileExists(fileName: String): Boolean - fun readFile(fileName: String): String? - val trace: ((s: String) -> Unit)? - val directoryExists: ((directoryName: String) -> Boolean)? - val realpath: ((path: String) -> String)? - val getCurrentDirectory: (() -> String)? - val getDirectories: ((path: String) -> Array)? -} - -external interface ResolvedModule { - var resolvedFileName: String - var isExternalLibraryImport: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedModuleFull : ResolvedModule { - var extension: Extension - var packageId: PackageId? - get() = definedExternally - set(value) = definedExternally -} - -external interface PackageId { - var name: String - var subModuleName: String - var version: String -} - -external enum class Extension { - Ts /* = ".ts" */, - Tsx /* = ".tsx" */, - Dts /* = ".d.ts" */, - Js /* = ".js" */, - Jsx /* = ".jsx" */, - Json /* = ".json" */, - TsBuildInfo /* = ".tsbuildinfo" */ -} - -external interface ResolvedModuleWithFailedLookupLocations { - var resolvedModule: ResolvedModuleFull? -} - -external interface ResolvedTypeReferenceDirective { - var primary: Boolean - var resolvedFileName: String? - var packageId: PackageId? - get() = definedExternally - set(value) = definedExternally - var isExternalLibraryImport: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations { - var resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective? - var failedLookupLocations: Array -} - -external interface CompilerHost : ModuleResolutionHost { - fun getSourceFile(fileName: String, languageVersion: ScriptTarget, onError: (message: String) -> Unit = definedExternally, shouldCreateNewSourceFile: Boolean = definedExternally): SourceFile? - val getSourceFileByPath: ((fileName: String, path: String /* String & `T$3` */, languageVersion: ScriptTarget, onError: (message: String) -> Unit, shouldCreateNewSourceFile: Boolean) -> SourceFile?)? - val getCancellationToken: (() -> CancellationToken)? - fun getDefaultLibFileName(options: CompilerOptions): String - val getDefaultLibLocation: (() -> String)? - var writeFile: WriteFileCallback - override var getCurrentDirectory: () -> String - fun getCanonicalFileName(fileName: String): String - fun useCaseSensitiveFileNames(): Boolean - fun getNewLine(): String - val readDirectory: ((rootDir: String, extensions: Array, excludes: Array?, includes: Array, depth: Number) -> Array)? - val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val getEnvironmentVariable: ((name: String) -> String?)? - val createHash: ((data: String) -> String)? - val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? -} - -external interface SourceMapRange : TextRange { - var source: SourceMapSource? - get() = definedExternally - set(value) = definedExternally -} - -external interface SourceMapSource { - fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter - var fileName: String - var text: String - var skipTrivia: ((pos: Number) -> Number)? - get() = definedExternally - set(value) = definedExternally -} - -external enum class EmitFlags { - None /* = 0 */, - SingleLine /* = 1 */, - AdviseOnEmitNode /* = 2 */, - NoSubstitution /* = 4 */, - CapturesThis /* = 8 */, - NoLeadingSourceMap /* = 16 */, - NoTrailingSourceMap /* = 32 */, - NoSourceMap /* = 48 */, - NoNestedSourceMaps /* = 64 */, - NoTokenLeadingSourceMaps /* = 128 */, - NoTokenTrailingSourceMaps /* = 256 */, - NoTokenSourceMaps /* = 384 */, - NoLeadingComments /* = 512 */, - NoTrailingComments /* = 1024 */, - NoComments /* = 1536 */, - NoNestedComments /* = 2048 */, - HelperName /* = 4096 */, - ExportName /* = 8192 */, - LocalName /* = 16384 */, - InternalName /* = 32768 */, - Indented /* = 65536 */, - NoIndentation /* = 131072 */, - AsyncFunctionBody /* = 262144 */, - ReuseTempVariableScope /* = 524288 */, - CustomPrologue /* = 1048576 */, - NoHoisting /* = 2097152 */, - HasEndOfDeclarationMarker /* = 4194304 */, - Iterator /* = 8388608 */, - NoAsciiEscaping /* = 16777216 */ -} - -external interface EmitHelperBase { - var name: String - var scoped: Boolean - var text: dynamic /* String | (node: EmitHelperUniqueNameCallback) -> String */ - get() = definedExternally - set(value) = definedExternally - var priority: Number? - get() = definedExternally - set(value) = definedExternally - var dependencies: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface ScopedEmitHelper : EmitHelperBase { - override var scoped: Boolean -} - -external interface UnscopedEmitHelper : EmitHelperBase { - override var scoped: Boolean - override var text: String -} - -external enum class EmitHint { - SourceFile /* = 0 */, - Expression /* = 1 */, - IdentifierName /* = 2 */, - MappedTypeParameter /* = 3 */, - Unspecified /* = 4 */, - EmbeddedStatement /* = 5 */, - JsxAttributeValue /* = 6 */ -} - -external enum class OuterExpressionKinds { - Parentheses /* = 1 */, - TypeAssertions /* = 2 */, - NonNullAssertions /* = 4 */, - PartiallyEmittedExpressions /* = 8 */, - Assertions /* = 6 */, - All /* = 15 */ -} - -external interface NodeFactory { - fun createNodeArray(elements: Array = definedExternally, hasTrailingComma: Boolean = definedExternally): NodeArray - fun createNumericLiteral(value: String, numericLiteralFlags: TokenFlags = definedExternally): NumericLiteral - fun createNumericLiteral(value: String): NumericLiteral - fun createNumericLiteral(value: Number, numericLiteralFlags: TokenFlags = definedExternally): NumericLiteral - fun createNumericLiteral(value: Number): NumericLiteral - fun createBigIntLiteral(value: String): BigIntLiteral - fun createBigIntLiteral(value: PseudoBigInt): BigIntLiteral - fun createStringLiteral(text: String, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: Identifier, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: Identifier): StringLiteral - fun createStringLiteralFromNode(sourceNode: StringLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: StringLiteral): StringLiteral - fun createStringLiteralFromNode(sourceNode: NoSubstitutionTemplateLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: NoSubstitutionTemplateLiteral): StringLiteral - fun createStringLiteralFromNode(sourceNode: NumericLiteral, isSingleQuote: Boolean = definedExternally): StringLiteral - fun createStringLiteralFromNode(sourceNode: NumericLiteral): StringLiteral - fun createRegularExpressionLiteral(text: String): RegularExpressionLiteral - fun createIdentifier(text: String): Identifier - fun createTempVariable(recordTempVariable: ((node: Identifier) -> Unit)?, reservedInNestedScopes: Boolean = definedExternally): Identifier - fun createLoopVariable(reservedInNestedScopes: Boolean = definedExternally): Identifier - fun createUniqueName(text: String, flags: GeneratedIdentifierFlags = definedExternally): Identifier - fun getGeneratedNameForNode(node: Node?, flags: GeneratedIdentifierFlags = definedExternally): Identifier - fun createPrivateIdentifier(text: String): PrivateIdentifier - fun createToken(token: SyntaxKind.SuperKeyword): SuperExpression - fun createToken(token: SyntaxKind.ThisKeyword): ThisExpression - fun createToken(token: SyntaxKind.NullKeyword): NullLiteral - fun createToken(token: SyntaxKind.TrueKeyword): TrueLiteral - fun createToken(token: SyntaxKind.FalseKeyword): FalseLiteral - fun createToken(token: TKind): dynamic /* Token */ - fun createSuper(): SuperExpression - fun createThis(): ThisExpression - fun createNull(): NullLiteral - fun createTrue(): TrueLiteral - fun createFalse(): FalseLiteral - fun createModifier(kind: T): ModifierToken - fun createModifiersFromModifierFlags(flags: ModifierFlags): Array - fun createQualifiedName(left: Identifier, right: String): QualifiedName - fun createQualifiedName(left: Identifier, right: Identifier): QualifiedName - fun createQualifiedName(left: QualifiedName, right: String): QualifiedName - fun createQualifiedName(left: QualifiedName, right: Identifier): QualifiedName - fun updateQualifiedName(node: QualifiedName, left: Identifier, right: Identifier): QualifiedName - fun updateQualifiedName(node: QualifiedName, left: QualifiedName, right: Identifier): QualifiedName - fun createComputedPropertyName(expression: Expression): ComputedPropertyName - fun updateComputedPropertyName(node: ComputedPropertyName, expression: Expression): ComputedPropertyName - fun createTypeParameterDeclaration(name: String, constraint: TypeNode = definedExternally, defaultType: TypeNode = definedExternally): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: String): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: String, constraint: TypeNode = definedExternally): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: Identifier, constraint: TypeNode = definedExternally, defaultType: TypeNode = definedExternally): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: Identifier): TypeParameterDeclaration - fun createTypeParameterDeclaration(name: Identifier, constraint: TypeNode = definedExternally): TypeParameterDeclaration - fun updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode?, defaultType: TypeNode?): TypeParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally): ParameterDeclaration - fun createParameterDeclaration(decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken = definedExternally, type: TypeNode = definedExternally): ParameterDeclaration - fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: String, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration - fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration - fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ObjectBindingPattern, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration - fun updateParameterDeclaration(node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: ArrayBindingPattern, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?): ParameterDeclaration - fun createDecorator(expression: Expression): Decorator - fun updateDecorator(node: Decorator, expression: Expression): Decorator - fun createPropertySignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertySignature(modifiers: Array?, name: String, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun updatePropertySignature(node: PropertySignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, type: TypeNode?): PropertySignature - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createPropertyDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: String, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: QuestionToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun updatePropertyDeclaration(node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, questionOrExclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): PropertyDeclaration - fun createMethodSignature(modifiers: Array?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun createMethodSignature(modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: Identifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun updateMethodSignature(node: MethodSignature, modifiers: Array?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): MethodSignature - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createMethodDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: StringLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: NumericLiteral, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: ComputedPropertyName, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun updateMethodDeclaration(node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: PrivateIdentifier, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): MethodDeclaration - fun createConstructorDeclaration(decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration - fun updateConstructorDeclaration(node: ConstructorDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, body: Block?): ConstructorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createGetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun updateGetAccessorDeclaration(node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, type: TypeNode?, body: Block?): GetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: String, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration - fun createSetAccessorDeclaration(decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: NumericLiteral, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: ComputedPropertyName, parameters: Array, body: Block?): SetAccessorDeclaration - fun updateSetAccessorDeclaration(node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: PrivateIdentifier, parameters: Array, body: Block?): SetAccessorDeclaration - fun createCallSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): CallSignatureDeclaration - fun updateCallSignature(node: CallSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): CallSignatureDeclaration - fun createConstructSignature(typeParameters: Array?, parameters: Array, type: TypeNode?): ConstructSignatureDeclaration - fun updateConstructSignature(node: ConstructSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?): ConstructSignatureDeclaration - fun createIndexSignature(decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration - fun updateIndexSignature(node: IndexSignatureDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode): IndexSignatureDeclaration - fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan - fun createTemplateLiteralTypeSpan(type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan - fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateMiddle): TemplateLiteralTypeSpan - fun updateTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, type: TypeNode, literal: TemplateTail): TemplateLiteralTypeSpan - fun createClassStaticBlockDeclaration(decorators: Array?, modifiers: Array?, body: Block): ClassStaticBlockDeclaration - fun updateClassStaticBlockDeclaration(node: ClassStaticBlockDeclaration, decorators: Array?, modifiers: Array?, body: Block): ClassStaticBlockDeclaration - fun createKeywordTypeNode(kind: TKind): KeywordTypeNode - fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode - fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode - fun createTypePredicateNode(assertsModifier: AssertsKeyword?, parameterName: String, type: TypeNode?): TypePredicateNode - fun updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: Identifier, type: TypeNode?): TypePredicateNode - fun updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: ThisTypeNode, type: TypeNode?): TypePredicateNode - fun createTypeReferenceNode(typeName: String, typeArguments: Array = definedExternally): TypeReferenceNode - fun createTypeReferenceNode(typeName: String): TypeReferenceNode - fun createTypeReferenceNode(typeName: Identifier, typeArguments: Array = definedExternally): TypeReferenceNode - fun createTypeReferenceNode(typeName: Identifier): TypeReferenceNode - fun createTypeReferenceNode(typeName: QualifiedName, typeArguments: Array = definedExternally): TypeReferenceNode - fun createTypeReferenceNode(typeName: QualifiedName): TypeReferenceNode - fun updateTypeReferenceNode(node: TypeReferenceNode, typeName: Identifier, typeArguments: NodeArray?): TypeReferenceNode - fun updateTypeReferenceNode(node: TypeReferenceNode, typeName: QualifiedName, typeArguments: NodeArray?): TypeReferenceNode - fun createFunctionTypeNode(typeParameters: Array?, parameters: Array, type: TypeNode): FunctionTypeNode - fun updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): FunctionTypeNode - fun createConstructorTypeNode(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode): ConstructorTypeNode - fun createConstructorTypeNode(typeParameters: Array?, parameters: Array, type: TypeNode): ConstructorTypeNode - fun updateConstructorTypeNode(node: ConstructorTypeNode, modifiers: Array?, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): ConstructorTypeNode - fun updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode): ConstructorTypeNode - fun createTypeQueryNode(exprName: Identifier): TypeQueryNode - fun createTypeQueryNode(exprName: QualifiedName): TypeQueryNode - fun updateTypeQueryNode(node: TypeQueryNode, exprName: Identifier): TypeQueryNode - fun updateTypeQueryNode(node: TypeQueryNode, exprName: QualifiedName): TypeQueryNode - fun createTypeLiteralNode(members: Array?): TypeLiteralNode - fun updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray): TypeLiteralNode - fun createArrayTypeNode(elementType: TypeNode): ArrayTypeNode - fun updateArrayTypeNode(node: ArrayTypeNode, elementType: TypeNode): ArrayTypeNode - fun createTupleTypeNode(elements: Array): TupleTypeNode - fun updateTupleTypeNode(node: TupleTypeNode, elements: Array): TupleTypeNode - fun createNamedTupleMember(dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode): NamedTupleMember - fun updateNamedTupleMember(node: NamedTupleMember, dotDotDotToken: DotDotDotToken?, name: Identifier, questionToken: QuestionToken?, type: TypeNode): NamedTupleMember - fun createOptionalTypeNode(type: TypeNode): OptionalTypeNode - fun updateOptionalTypeNode(node: OptionalTypeNode, type: TypeNode): OptionalTypeNode - fun createRestTypeNode(type: TypeNode): RestTypeNode - fun updateRestTypeNode(node: RestTypeNode, type: TypeNode): RestTypeNode - fun createUnionTypeNode(types: Array): UnionTypeNode - fun updateUnionTypeNode(node: UnionTypeNode, types: NodeArray): UnionTypeNode - fun createIntersectionTypeNode(types: Array): IntersectionTypeNode - fun updateIntersectionTypeNode(node: IntersectionTypeNode, types: NodeArray): IntersectionTypeNode - fun createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode - fun updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode): ConditionalTypeNode - fun createInferTypeNode(typeParameter: TypeParameterDeclaration): InferTypeNode - fun updateInferTypeNode(node: InferTypeNode, typeParameter: TypeParameterDeclaration): InferTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally, typeArguments: Array = definedExternally, isTypeOf: Boolean = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: Identifier = definedExternally, typeArguments: Array = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally, typeArguments: Array = definedExternally, isTypeOf: Boolean = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally): ImportTypeNode - fun createImportTypeNode(argument: TypeNode, qualifier: QualifiedName = definedExternally, typeArguments: Array = definedExternally): ImportTypeNode - fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: Identifier?, typeArguments: Array?, isTypeOf: Boolean = definedExternally): ImportTypeNode - fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: Identifier?, typeArguments: Array?): ImportTypeNode - fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: QualifiedName?, typeArguments: Array?, isTypeOf: Boolean = definedExternally): ImportTypeNode - fun updateImportTypeNode(node: ImportTypeNode, argument: TypeNode, qualifier: QualifiedName?, typeArguments: Array?): ImportTypeNode - fun createParenthesizedType(type: TypeNode): ParenthesizedTypeNode - fun updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode - fun createThisTypeNode(): ThisTypeNode - fun createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword, type: TypeNode): TypeOperatorNode - fun createTypeOperatorNode(operator: SyntaxKind.UniqueKeyword, type: TypeNode): TypeOperatorNode - fun createTypeOperatorNode(operator: SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode - fun updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode - fun createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode - fun updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode - fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun createMappedTypeNode(readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: PlusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: QuestionToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: PlusToken?, type: TypeNode?): MappedTypeNode - fun updateMappedTypeNode(node: MappedTypeNode, readonlyToken: MinusToken?, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: MinusToken?, type: TypeNode?): MappedTypeNode - fun createLiteralTypeNode(literal: NullLiteral): LiteralTypeNode - fun createLiteralTypeNode(literal: TrueLiteral): LiteralTypeNode - fun createLiteralTypeNode(literal: FalseLiteral): LiteralTypeNode - fun createLiteralTypeNode(literal: LiteralExpression): LiteralTypeNode - fun createLiteralTypeNode(literal: PrefixUnaryExpression): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: NullLiteral): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: TrueLiteral): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: FalseLiteral): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralExpression): LiteralTypeNode - fun updateLiteralTypeNode(node: LiteralTypeNode, literal: PrefixUnaryExpression): LiteralTypeNode - fun createTemplateLiteralType(head: TemplateHead, templateSpans: Array): TemplateLiteralTypeNode - fun updateTemplateLiteralType(node: TemplateLiteralTypeNode, head: TemplateHead, templateSpans: Array): TemplateLiteralTypeNode - fun createObjectBindingPattern(elements: Array): ObjectBindingPattern - fun updateObjectBindingPattern(node: ObjectBindingPattern, elements: Array): ObjectBindingPattern - fun createArrayBindingPattern(elements: Array): ArrayBindingPattern - fun updateArrayBindingPattern(node: ArrayBindingPattern, elements: Array): ArrayBindingPattern - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: String?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: String?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression = definedExternally): BindingElement - fun createBindingElement(dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: Identifier?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: StringLiteral?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: NumericLiteral?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: ComputedPropertyName?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: Identifier, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: ObjectBindingPattern, initializer: Expression?): BindingElement - fun updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: PrivateIdentifier?, name: ArrayBindingPattern, initializer: Expression?): BindingElement - fun createArrayLiteralExpression(elements: Array = definedExternally, multiLine: Boolean = definedExternally): ArrayLiteralExpression - fun updateArrayLiteralExpression(node: ArrayLiteralExpression, elements: Array): ArrayLiteralExpression - fun createObjectLiteralExpression(properties: Array = definedExternally, multiLine: Boolean = definedExternally): ObjectLiteralExpression - fun updateObjectLiteralExpression(node: ObjectLiteralExpression, properties: Array): ObjectLiteralExpression - fun createPropertyAccessExpression(expression: Expression, name: String): PropertyAccessExpression - fun createPropertyAccessExpression(expression: Expression, name: Identifier): PropertyAccessExpression - fun createPropertyAccessExpression(expression: Expression, name: PrivateIdentifier): PropertyAccessExpression - fun updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: Identifier): PropertyAccessExpression - fun updatePropertyAccessExpression(node: PropertyAccessExpression, expression: Expression, name: PrivateIdentifier): PropertyAccessExpression - fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: String): PropertyAccessChain - fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: Identifier): PropertyAccessChain - fun createPropertyAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, name: PrivateIdentifier): PropertyAccessChain - fun updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: Identifier): PropertyAccessChain - fun updatePropertyAccessChain(node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: PrivateIdentifier): PropertyAccessChain - fun createElementAccessExpression(expression: Expression, index: Number): ElementAccessExpression - fun createElementAccessExpression(expression: Expression, index: Expression): ElementAccessExpression - fun updateElementAccessExpression(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression - fun createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, index: Number): ElementAccessChain - fun createElementAccessChain(expression: Expression, questionDotToken: QuestionDotToken?, index: Expression): ElementAccessChain - fun updateElementAccessChain(node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, argumentExpression: Expression): ElementAccessChain - fun createCallExpression(expression: Expression, typeArguments: Array?, argumentsArray: Array?): CallExpression - fun updateCallExpression(node: CallExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array): CallExpression - fun createCallChain(expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array?): CallChain - fun updateCallChain(node: CallChain, expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array): CallChain - fun createNewExpression(expression: Expression, typeArguments: Array?, argumentsArray: Array?): NewExpression - fun updateNewExpression(node: NewExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array?): NewExpression - fun createTaggedTemplateExpression(tag: Expression, typeArguments: Array?, template: TemplateExpression): TaggedTemplateExpression - fun createTaggedTemplateExpression(tag: Expression, typeArguments: Array?, template: NoSubstitutionTemplateLiteral): TaggedTemplateExpression - fun updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: TemplateExpression): TaggedTemplateExpression - fun updateTaggedTemplateExpression(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: NoSubstitutionTemplateLiteral): TaggedTemplateExpression - fun createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion - fun updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion - fun createParenthesizedExpression(expression: Expression): ParenthesizedExpression - fun updateParenthesizedExpression(node: ParenthesizedExpression, expression: Expression): ParenthesizedExpression - fun createFunctionExpression(modifiers: Array?, asteriskToken: AsteriskToken?, name: String?, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block): FunctionExpression - fun createFunctionExpression(modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block): FunctionExpression - fun updateFunctionExpression(node: FunctionExpression, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block): FunctionExpression - fun createArrowFunction(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: FunctionBody): ArrowFunction - fun createArrowFunction(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: Expression): ArrowFunction - fun updateArrowFunction(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: FunctionBody): ArrowFunction - fun updateArrowFunction(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: Expression): ArrowFunction - fun createDeleteExpression(expression: Expression): DeleteExpression - fun updateDeleteExpression(node: DeleteExpression, expression: Expression): DeleteExpression - fun createTypeOfExpression(expression: Expression): TypeOfExpression - fun updateTypeOfExpression(node: TypeOfExpression, expression: Expression): TypeOfExpression - fun createVoidExpression(expression: Expression): VoidExpression - fun updateVoidExpression(node: VoidExpression, expression: Expression): VoidExpression - fun createAwaitExpression(expression: Expression): AwaitExpression - fun updateAwaitExpression(node: AwaitExpression, expression: Expression): AwaitExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.PlusPlusToken, operand: Expression): PrefixUnaryExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.MinusMinusToken, operand: Expression): PrefixUnaryExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.PlusToken, operand: Expression): PrefixUnaryExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.MinusToken, operand: Expression): PrefixUnaryExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.TildeToken, operand: Expression): PrefixUnaryExpression - fun createPrefixUnaryExpression(operator: SyntaxKind.ExclamationToken, operand: Expression): PrefixUnaryExpression - fun updatePrefixUnaryExpression(node: PrefixUnaryExpression, operand: Expression): PrefixUnaryExpression - fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind.PlusPlusToken): PostfixUnaryExpression - fun createPostfixUnaryExpression(operand: Expression, operator: SyntaxKind.MinusMinusToken): PostfixUnaryExpression - fun updatePostfixUnaryExpression(node: PostfixUnaryExpression, operand: Expression): PostfixUnaryExpression - fun createBinaryExpression(left: Expression, operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression): BinaryExpression - fun updateBinaryExpression(node: BinaryExpression, left: Expression, operator: Any /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression): BinaryExpression - fun createConditionalExpression(condition: Expression, questionToken: QuestionToken?, whenTrue: Expression, colonToken: ColonToken?, whenFalse: Expression): ConditionalExpression - fun updateConditionalExpression(node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression - fun createTemplateExpression(head: TemplateHead, templateSpans: Array): TemplateExpression - fun updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: Array): TemplateExpression - fun createTemplateHead(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateHead - fun createTemplateHead(text: String): TemplateHead - fun createTemplateHead(text: String, rawText: String = definedExternally): TemplateHead - fun createTemplateHead(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateHead - fun createTemplateHead(text: String?, rawText: String): TemplateHead - fun createTemplateMiddle(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateMiddle - fun createTemplateMiddle(text: String): TemplateMiddle - fun createTemplateMiddle(text: String, rawText: String = definedExternally): TemplateMiddle - fun createTemplateMiddle(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateMiddle - fun createTemplateMiddle(text: String?, rawText: String): TemplateMiddle - fun createTemplateTail(text: String, rawText: String = definedExternally, templateFlags: TokenFlags = definedExternally): TemplateTail - fun createTemplateTail(text: String): TemplateTail - fun createTemplateTail(text: String, rawText: String = definedExternally): TemplateTail - fun createTemplateTail(text: String?, rawText: String, templateFlags: TokenFlags = definedExternally): TemplateTail - fun createTemplateTail(text: String?, rawText: String): TemplateTail - fun createNoSubstitutionTemplateLiteral(text: String, rawText: String = definedExternally): NoSubstitutionTemplateLiteral - fun createNoSubstitutionTemplateLiteral(text: String): NoSubstitutionTemplateLiteral - fun createNoSubstitutionTemplateLiteral(text: String?, rawText: String): NoSubstitutionTemplateLiteral - fun createYieldExpression(asteriskToken: AsteriskToken, expression: Expression): YieldExpression - fun createYieldExpression(asteriskToken: Nothing?, expression: Expression?): YieldExpression - fun updateYieldExpression(node: YieldExpression, asteriskToken: AsteriskToken?, expression: Expression?): YieldExpression - fun createSpreadElement(expression: Expression): SpreadElement - fun updateSpreadElement(node: SpreadElement, expression: Expression): SpreadElement - fun createClassExpression(decorators: Array?, modifiers: Array?, name: String?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression - fun createClassExpression(decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression - fun updateClassExpression(node: ClassExpression, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassExpression - fun createOmittedExpression(): OmittedExpression - fun createExpressionWithTypeArguments(expression: Expression, typeArguments: Array?): ExpressionWithTypeArguments - fun updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, expression: Expression, typeArguments: Array?): ExpressionWithTypeArguments - fun createAsExpression(expression: Expression, type: TypeNode): AsExpression - fun updateAsExpression(node: AsExpression, expression: Expression, type: TypeNode): AsExpression - fun createNonNullExpression(expression: Expression): NonNullExpression - fun updateNonNullExpression(node: NonNullExpression, expression: Expression): NonNullExpression - fun createNonNullChain(expression: Expression): NonNullChain - fun updateNonNullChain(node: NonNullChain, expression: Expression): NonNullChain - fun createMetaProperty(keywordToken: SyntaxKind.NewKeyword, name: Identifier): MetaProperty - fun createMetaProperty(keywordToken: SyntaxKind.ImportKeyword, name: Identifier): MetaProperty - fun updateMetaProperty(node: MetaProperty, name: Identifier): MetaProperty - fun createTemplateSpan(expression: Expression, literal: TemplateMiddle): TemplateSpan - fun createTemplateSpan(expression: Expression, literal: TemplateTail): TemplateSpan - fun updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateMiddle): TemplateSpan - fun updateTemplateSpan(node: TemplateSpan, expression: Expression, literal: TemplateTail): TemplateSpan - fun createSemicolonClassElement(): SemicolonClassElement - fun createBlock(statements: Array, multiLine: Boolean = definedExternally): Block - fun updateBlock(node: Block, statements: Array): Block - fun createVariableStatement(modifiers: Array?, declarationList: VariableDeclarationList): VariableStatement - fun createVariableStatement(modifiers: Array?, declarationList: Array): VariableStatement - fun updateVariableStatement(node: VariableStatement, modifiers: Array?, declarationList: VariableDeclarationList): VariableStatement - fun createEmptyStatement(): EmptyStatement - fun createExpressionStatement(expression: Expression): ExpressionStatement - fun updateExpressionStatement(node: ExpressionStatement, expression: Expression): ExpressionStatement - fun createIfStatement(expression: Expression, thenStatement: Statement, elseStatement: Statement = definedExternally): IfStatement - fun updateIfStatement(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement?): IfStatement - fun createDoStatement(statement: Statement, expression: Expression): DoStatement - fun updateDoStatement(node: DoStatement, statement: Statement, expression: Expression): DoStatement - fun createWhileStatement(expression: Expression, statement: Statement): WhileStatement - fun updateWhileStatement(node: WhileStatement, expression: Expression, statement: Statement): WhileStatement - fun createForStatement(initializer: VariableDeclarationList?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement - fun createForStatement(initializer: Expression?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement - fun updateForStatement(node: ForStatement, initializer: VariableDeclarationList?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement - fun updateForStatement(node: ForStatement, initializer: Expression?, condition: Expression?, incrementor: Expression?, statement: Statement): ForStatement - fun createForInStatement(initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForInStatement - fun createForInStatement(initializer: Expression, expression: Expression, statement: Statement): ForInStatement - fun updateForInStatement(node: ForInStatement, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForInStatement - fun updateForInStatement(node: ForInStatement, initializer: Expression, expression: Expression, statement: Statement): ForInStatement - fun createForOfStatement(awaitModifier: AwaitKeyword?, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForOfStatement - fun createForOfStatement(awaitModifier: AwaitKeyword?, initializer: Expression, expression: Expression, statement: Statement): ForOfStatement - fun updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: VariableDeclarationList, expression: Expression, statement: Statement): ForOfStatement - fun updateForOfStatement(node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: Expression, expression: Expression, statement: Statement): ForOfStatement - fun createContinueStatement(label: String = definedExternally): ContinueStatement - fun createContinueStatement(): ContinueStatement - fun createContinueStatement(label: Identifier = definedExternally): ContinueStatement - fun updateContinueStatement(node: ContinueStatement, label: Identifier?): ContinueStatement - fun createBreakStatement(label: String = definedExternally): BreakStatement - fun createBreakStatement(): BreakStatement - fun createBreakStatement(label: Identifier = definedExternally): BreakStatement - fun updateBreakStatement(node: BreakStatement, label: Identifier?): BreakStatement - fun createReturnStatement(expression: Expression = definedExternally): ReturnStatement - fun updateReturnStatement(node: ReturnStatement, expression: Expression?): ReturnStatement - fun createWithStatement(expression: Expression, statement: Statement): WithStatement - fun updateWithStatement(node: WithStatement, expression: Expression, statement: Statement): WithStatement - fun createSwitchStatement(expression: Expression, caseBlock: CaseBlock): SwitchStatement - fun updateSwitchStatement(node: SwitchStatement, expression: Expression, caseBlock: CaseBlock): SwitchStatement - fun createLabeledStatement(label: String, statement: Statement): LabeledStatement - fun createLabeledStatement(label: Identifier, statement: Statement): LabeledStatement - fun updateLabeledStatement(node: LabeledStatement, label: Identifier, statement: Statement): LabeledStatement - fun createThrowStatement(expression: Expression): ThrowStatement - fun updateThrowStatement(node: ThrowStatement, expression: Expression): ThrowStatement - fun createTryStatement(tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?): TryStatement - fun updateTryStatement(node: TryStatement, tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?): TryStatement - fun createDebuggerStatement(): DebuggerStatement - fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: String): VariableDeclaration - fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: String, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: Identifier): VariableDeclaration - fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: Identifier, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ObjectBindingPattern): VariableDeclaration - fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ObjectBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally, initializer: Expression = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ArrayBindingPattern): VariableDeclaration - fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally): VariableDeclaration - fun createVariableDeclaration(name: ArrayBindingPattern, exclamationToken: ExclamationToken = definedExternally, type: TypeNode = definedExternally): VariableDeclaration - fun updateVariableDeclaration(node: VariableDeclaration, name: Identifier, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration - fun updateVariableDeclaration(node: VariableDeclaration, name: ObjectBindingPattern, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration - fun updateVariableDeclaration(node: VariableDeclaration, name: ArrayBindingPattern, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration - fun createVariableDeclarationList(declarations: Array, flags: NodeFlags = definedExternally): VariableDeclarationList - fun updateVariableDeclarationList(node: VariableDeclarationList, declarations: Array): VariableDeclarationList - fun createFunctionDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: String?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration - fun createFunctionDeclaration(decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration - fun updateFunctionDeclaration(node: FunctionDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?): FunctionDeclaration - fun createClassDeclaration(decorators: Array?, modifiers: Array?, name: String?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration - fun createClassDeclaration(decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration - fun updateClassDeclaration(node: ClassDeclaration, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array): ClassDeclaration - fun createInterfaceDeclaration(decorators: Array?, modifiers: Array?, name: String, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration - fun createInterfaceDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration - fun updateInterfaceDeclaration(node: InterfaceDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array): InterfaceDeclaration - fun createTypeAliasDeclaration(decorators: Array?, modifiers: Array?, name: String, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration - fun createTypeAliasDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration - fun updateTypeAliasDeclaration(node: TypeAliasDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode): TypeAliasDeclaration - fun createEnumDeclaration(decorators: Array?, modifiers: Array?, name: String, members: Array): EnumDeclaration - fun createEnumDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, members: Array): EnumDeclaration - fun updateEnumDeclaration(node: EnumDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, members: Array): EnumDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?, flags: NodeFlags = definedExternally): ModuleDeclaration - fun createModuleDeclaration(decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: ModuleBlock?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: NamespaceDeclaration?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: Identifier?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, body: JSDocNamespaceDeclaration?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: ModuleBlock?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: NamespaceDeclaration?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: Identifier?): ModuleDeclaration - fun updateModuleDeclaration(node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: StringLiteral, body: JSDocNamespaceDeclaration?): ModuleDeclaration - fun createModuleBlock(statements: Array): ModuleBlock - fun updateModuleBlock(node: ModuleBlock, statements: Array): ModuleBlock - fun createCaseBlock(clauses: Array): CaseBlock - fun updateCaseBlock(node: CaseBlock, clauses: Array): CaseBlock - fun createNamespaceExportDeclaration(name: String): NamespaceExportDeclaration - fun createNamespaceExportDeclaration(name: Identifier): NamespaceExportDeclaration - fun updateNamespaceExportDeclaration(node: NamespaceExportDeclaration, name: Identifier): NamespaceExportDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: Identifier): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: QualifiedName): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: String, moduleReference: ExternalModuleReference): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: Identifier): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: QualifiedName): ImportEqualsDeclaration - fun createImportEqualsDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: ExternalModuleReference): ImportEqualsDeclaration - fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: Identifier): ImportEqualsDeclaration - fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: QualifiedName): ImportEqualsDeclaration - fun updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: ExternalModuleReference): ImportEqualsDeclaration - fun createImportDeclaration(decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression): ImportDeclaration - fun updateImportDeclaration(node: ImportDeclaration, decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression): ImportDeclaration - fun createImportClause(isTypeOnly: Boolean, name: Identifier?, namedBindings: NamespaceImport?): ImportClause - fun createImportClause(isTypeOnly: Boolean, name: Identifier?, namedBindings: NamedImports?): ImportClause - fun updateImportClause(node: ImportClause, isTypeOnly: Boolean, name: Identifier?, namedBindings: NamespaceImport?): ImportClause - fun updateImportClause(node: ImportClause, isTypeOnly: Boolean, name: Identifier?, namedBindings: NamedImports?): ImportClause - fun createNamespaceImport(name: Identifier): NamespaceImport - fun updateNamespaceImport(node: NamespaceImport, name: Identifier): NamespaceImport - fun createNamespaceExport(name: Identifier): NamespaceExport - fun updateNamespaceExport(node: NamespaceExport, name: Identifier): NamespaceExport - fun createNamedImports(elements: Array): NamedImports - fun updateNamedImports(node: NamedImports, elements: Array): NamedImports - fun createImportSpecifier(propertyName: Identifier?, name: Identifier): ImportSpecifier - fun updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier?, name: Identifier): ImportSpecifier - fun createExportAssignment(decorators: Array?, modifiers: Array?, isExportEquals: Boolean?, expression: Expression): ExportAssignment - fun updateExportAssignment(node: ExportAssignment, decorators: Array?, modifiers: Array?, expression: Expression): ExportAssignment - fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?, moduleSpecifier: Expression = definedExternally): ExportDeclaration - fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?): ExportDeclaration - fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?, moduleSpecifier: Expression = definedExternally): ExportDeclaration - fun createExportDeclaration(decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?): ExportDeclaration - fun updateExportDeclaration(node: ExportDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamespaceExport?, moduleSpecifier: Expression?): ExportDeclaration - fun updateExportDeclaration(node: ExportDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, exportClause: NamedExports?, moduleSpecifier: Expression?): ExportDeclaration - fun createNamedExports(elements: Array): NamedExports - fun updateNamedExports(node: NamedExports, elements: Array): NamedExports - fun createExportSpecifier(propertyName: String?, name: String): ExportSpecifier - fun createExportSpecifier(propertyName: String?, name: Identifier): ExportSpecifier - fun createExportSpecifier(propertyName: Identifier?, name: String): ExportSpecifier - fun createExportSpecifier(propertyName: Identifier?, name: Identifier): ExportSpecifier - fun updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier?, name: Identifier): ExportSpecifier - fun createExternalModuleReference(expression: Expression): ExternalModuleReference - fun updateExternalModuleReference(node: ExternalModuleReference, expression: Expression): ExternalModuleReference - fun createJSDocAllType(): JSDocAllType - fun createJSDocUnknownType(): JSDocUnknownType - fun createJSDocNonNullableType(type: TypeNode): JSDocNonNullableType - fun updateJSDocNonNullableType(node: JSDocNonNullableType, type: TypeNode): JSDocNonNullableType - fun createJSDocNullableType(type: TypeNode): JSDocNullableType - fun updateJSDocNullableType(node: JSDocNullableType, type: TypeNode): JSDocNullableType - fun createJSDocOptionalType(type: TypeNode): JSDocOptionalType - fun updateJSDocOptionalType(node: JSDocOptionalType, type: TypeNode): JSDocOptionalType - fun createJSDocFunctionType(parameters: Array, type: TypeNode?): JSDocFunctionType - fun updateJSDocFunctionType(node: JSDocFunctionType, parameters: Array, type: TypeNode?): JSDocFunctionType - fun createJSDocVariadicType(type: TypeNode): JSDocVariadicType - fun updateJSDocVariadicType(node: JSDocVariadicType, type: TypeNode): JSDocVariadicType - fun createJSDocNamepathType(type: TypeNode): JSDocNamepathType - fun updateJSDocNamepathType(node: JSDocNamepathType, type: TypeNode): JSDocNamepathType - fun createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression - fun updateJSDocTypeExpression(node: JSDocTypeExpression, type: TypeNode): JSDocTypeExpression - fun createJSDocNameReference(name: Identifier): JSDocNameReference - fun createJSDocNameReference(name: QualifiedName): JSDocNameReference - fun createJSDocNameReference(name: JSDocMemberName): JSDocNameReference - fun updateJSDocNameReference(node: JSDocNameReference, name: Identifier): JSDocNameReference - fun updateJSDocNameReference(node: JSDocNameReference, name: QualifiedName): JSDocNameReference - fun updateJSDocNameReference(node: JSDocNameReference, name: JSDocMemberName): JSDocNameReference - fun createJSDocMemberName(left: Identifier, right: Identifier): JSDocMemberName - fun createJSDocMemberName(left: QualifiedName, right: Identifier): JSDocMemberName - fun createJSDocMemberName(left: JSDocMemberName, right: Identifier): JSDocMemberName - fun updateJSDocMemberName(node: JSDocMemberName, left: Identifier, right: Identifier): JSDocMemberName - fun updateJSDocMemberName(node: JSDocMemberName, left: QualifiedName, right: Identifier): JSDocMemberName - fun updateJSDocMemberName(node: JSDocMemberName, left: JSDocMemberName, right: Identifier): JSDocMemberName - fun createJSDocLink(name: Identifier?, text: String): JSDocLink - fun createJSDocLink(name: QualifiedName?, text: String): JSDocLink - fun createJSDocLink(name: JSDocMemberName?, text: String): JSDocLink - fun updateJSDocLink(node: JSDocLink, name: Identifier?, text: String): JSDocLink - fun updateJSDocLink(node: JSDocLink, name: QualifiedName?, text: String): JSDocLink - fun updateJSDocLink(node: JSDocLink, name: JSDocMemberName?, text: String): JSDocLink - fun createJSDocLinkCode(name: Identifier?, text: String): JSDocLinkCode - fun createJSDocLinkCode(name: QualifiedName?, text: String): JSDocLinkCode - fun createJSDocLinkCode(name: JSDocMemberName?, text: String): JSDocLinkCode - fun updateJSDocLinkCode(node: JSDocLinkCode, name: Identifier?, text: String): JSDocLinkCode - fun updateJSDocLinkCode(node: JSDocLinkCode, name: QualifiedName?, text: String): JSDocLinkCode - fun updateJSDocLinkCode(node: JSDocLinkCode, name: JSDocMemberName?, text: String): JSDocLinkCode - fun createJSDocLinkPlain(name: Identifier?, text: String): JSDocLinkPlain - fun createJSDocLinkPlain(name: QualifiedName?, text: String): JSDocLinkPlain - fun createJSDocLinkPlain(name: JSDocMemberName?, text: String): JSDocLinkPlain - fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: Identifier?, text: String): JSDocLinkPlain - fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: QualifiedName?, text: String): JSDocLinkPlain - fun updateJSDocLinkPlain(node: JSDocLinkPlain, name: JSDocMemberName?, text: String): JSDocLinkPlain - fun createJSDocTypeLiteral(jsDocPropertyTags: Array = definedExternally, isArrayType: Boolean = definedExternally): JSDocTypeLiteral - fun updateJSDocTypeLiteral(node: JSDocTypeLiteral, jsDocPropertyTags: Array?, isArrayType: Boolean?): JSDocTypeLiteral - fun createJSDocSignature(typeParameters: Array?, parameters: Array, type: JSDocReturnTag = definedExternally): JSDocSignature - fun updateJSDocSignature(node: JSDocSignature, typeParameters: Array?, parameters: Array, type: JSDocReturnTag?): JSDocSignature - fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String = definedExternally): JSDocTemplateTag - fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array): JSDocTemplateTag - fun createJSDocTemplateTag(tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray = definedExternally): JSDocTemplateTag - fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: String?): JSDocTemplateTag - fun updateJSDocTemplateTag(node: JSDocTemplateTag, tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: NodeArray?): JSDocTemplateTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocTypedefTag - fun createJSDocTypedefTag(tagName: Identifier?, typeExpression: JSDocTypeLiteral = definedExternally, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: Identifier?, comment: NodeArray?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocTypedefTag - fun updateJSDocTypedefTag(node: JSDocTypedefTag, tagName: Identifier?, typeExpression: JSDocTypeLiteral?, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocTypedefTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocParameterTag - fun createJSDocParameterTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocParameterTag - fun updateJSDocParameterTag(node: JSDocParameterTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocParameterTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: String = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally): JSDocPropertyTag - fun createJSDocPropertyTag(tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression = definedExternally, isNameFirst: Boolean = definedExternally, comment: NodeArray = definedExternally): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: Identifier, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: String?): JSDocPropertyTag - fun updateJSDocPropertyTag(node: JSDocPropertyTag, tagName: Identifier?, name: QualifiedName, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean, comment: NodeArray?): JSDocPropertyTag - fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocTypeTag - fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocTypeTag - fun createJSDocTypeTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocTypeTag - fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocTypeTag - fun updateJSDocTypeTag(node: JSDocTypeTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocTypeTag - fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag - fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag - fun createJSDocSeeTag(tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag - fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: String = definedExternally): JSDocSeeTag - fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?): JSDocSeeTag - fun updateJSDocSeeTag(node: JSDocSeeTag, tagName: Identifier?, nameExpression: JSDocNameReference?, comment: NodeArray = definedExternally): JSDocSeeTag - fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: String = definedExternally): JSDocReturnTag - fun createJSDocReturnTag(tagName: Identifier?): JSDocReturnTag - fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally): JSDocReturnTag - fun createJSDocReturnTag(tagName: Identifier?, typeExpression: JSDocTypeExpression = definedExternally, comment: NodeArray = definedExternally): JSDocReturnTag - fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocReturnTag - fun updateJSDocReturnTag(node: JSDocReturnTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocReturnTag - fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocThisTag - fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocThisTag - fun createJSDocThisTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocThisTag - fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: String?): JSDocThisTag - fun updateJSDocThisTag(node: JSDocThisTag, tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: NodeArray?): JSDocThisTag - fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String = definedExternally): JSDocEnumTag - fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression): JSDocEnumTag - fun createJSDocEnumTag(tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray = definedExternally): JSDocEnumTag - fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: String?): JSDocEnumTag - fun updateJSDocEnumTag(node: JSDocEnumTag, tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: NodeArray?): JSDocEnumTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: String = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: String = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally): JSDocCallbackTag - fun createJSDocCallbackTag(tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration = definedExternally, comment: NodeArray = definedExternally): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: String?): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: Identifier?, comment: NodeArray?): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: String?): JSDocCallbackTag - fun updateJSDocCallbackTag(node: JSDocCallbackTag, tagName: Identifier?, typeExpression: JSDocSignature, fullName: JSDocNamespaceDeclaration?, comment: NodeArray?): JSDocCallbackTag - fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String = definedExternally): JSDocAugmentsTag - fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */): JSDocAugmentsTag - fun createJSDocAugmentsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray = definedExternally): JSDocAugmentsTag - fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String?): JSDocAugmentsTag - fun updateJSDocAugmentsTag(node: JSDocAugmentsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray?): JSDocAugmentsTag - fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String = definedExternally): JSDocImplementsTag - fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */): JSDocImplementsTag - fun createJSDocImplementsTag(tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray = definedExternally): JSDocImplementsTag - fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: String?): JSDocImplementsTag - fun updateJSDocImplementsTag(node: JSDocImplementsTag, tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: NodeArray?): JSDocImplementsTag - fun createJSDocAuthorTag(tagName: Identifier?, comment: String = definedExternally): JSDocAuthorTag - fun createJSDocAuthorTag(tagName: Identifier?): JSDocAuthorTag - fun createJSDocAuthorTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocAuthorTag - fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: String?): JSDocAuthorTag - fun updateJSDocAuthorTag(node: JSDocAuthorTag, tagName: Identifier?, comment: NodeArray?): JSDocAuthorTag - fun createJSDocClassTag(tagName: Identifier?, comment: String = definedExternally): JSDocClassTag - fun createJSDocClassTag(tagName: Identifier?): JSDocClassTag - fun createJSDocClassTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocClassTag - fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: String?): JSDocClassTag - fun updateJSDocClassTag(node: JSDocClassTag, tagName: Identifier?, comment: NodeArray?): JSDocClassTag - fun createJSDocPublicTag(tagName: Identifier?, comment: String = definedExternally): JSDocPublicTag - fun createJSDocPublicTag(tagName: Identifier?): JSDocPublicTag - fun createJSDocPublicTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPublicTag - fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: String?): JSDocPublicTag - fun updateJSDocPublicTag(node: JSDocPublicTag, tagName: Identifier?, comment: NodeArray?): JSDocPublicTag - fun createJSDocPrivateTag(tagName: Identifier?, comment: String = definedExternally): JSDocPrivateTag - fun createJSDocPrivateTag(tagName: Identifier?): JSDocPrivateTag - fun createJSDocPrivateTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocPrivateTag - fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: String?): JSDocPrivateTag - fun updateJSDocPrivateTag(node: JSDocPrivateTag, tagName: Identifier?, comment: NodeArray?): JSDocPrivateTag - fun createJSDocProtectedTag(tagName: Identifier?, comment: String = definedExternally): JSDocProtectedTag - fun createJSDocProtectedTag(tagName: Identifier?): JSDocProtectedTag - fun createJSDocProtectedTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocProtectedTag - fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: String?): JSDocProtectedTag - fun updateJSDocProtectedTag(node: JSDocProtectedTag, tagName: Identifier?, comment: NodeArray?): JSDocProtectedTag - fun createJSDocReadonlyTag(tagName: Identifier?, comment: String = definedExternally): JSDocReadonlyTag - fun createJSDocReadonlyTag(tagName: Identifier?): JSDocReadonlyTag - fun createJSDocReadonlyTag(tagName: Identifier?, comment: NodeArray = definedExternally): JSDocReadonlyTag - fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: String?): JSDocReadonlyTag - fun updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier?, comment: NodeArray?): JSDocReadonlyTag - fun createJSDocUnknownTag(tagName: Identifier, comment: String = definedExternally): JSDocUnknownTag - fun createJSDocUnknownTag(tagName: Identifier): JSDocUnknownTag - fun createJSDocUnknownTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocUnknownTag - fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: String?): JSDocUnknownTag - fun updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: NodeArray?): JSDocUnknownTag - fun createJSDocDeprecatedTag(tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag - fun createJSDocDeprecatedTag(tagName: Identifier): JSDocDeprecatedTag - fun createJSDocDeprecatedTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag - fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: String = definedExternally): JSDocDeprecatedTag - fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier): JSDocDeprecatedTag - fun updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocDeprecatedTag - fun createJSDocOverrideTag(tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag - fun createJSDocOverrideTag(tagName: Identifier): JSDocOverrideTag - fun createJSDocOverrideTag(tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag - fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: String = definedExternally): JSDocOverrideTag - fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier): JSDocOverrideTag - fun updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment: NodeArray = definedExternally): JSDocOverrideTag - fun createJSDocText(text: String): JSDocText - fun updateJSDocText(node: JSDocText, text: String): JSDocText - fun createJSDocComment(comment: String? = definedExternally, tags: Array? = definedExternally): JSDoc - fun createJSDocComment(): JSDoc - fun createJSDocComment(comment: String? = definedExternally): JSDoc - fun createJSDocComment(comment: NodeArray? = definedExternally, tags: Array? = definedExternally): JSDoc - fun createJSDocComment(comment: NodeArray? = definedExternally): JSDoc - fun updateJSDocComment(node: JSDoc, comment: String?, tags: Array?): JSDoc - fun updateJSDocComment(node: JSDoc, comment: NodeArray?, tags: Array?): JSDoc - fun createJsxElement(openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement - fun updateJsxElement(node: JsxElement, openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement): JsxElement - fun createJsxSelfClosingElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun createJsxSelfClosingElement(tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun createJsxSelfClosingElement(tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxSelfClosingElement - fun createJsxOpeningElement(tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun createJsxOpeningElement(tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun createJsxOpeningElement(tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: Identifier, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: ThisExpression, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNamePropertyAccess, typeArguments: Array?, attributes: JsxAttributes): JsxOpeningElement - fun createJsxClosingElement(tagName: Identifier): JsxClosingElement - fun createJsxClosingElement(tagName: ThisExpression): JsxClosingElement - fun createJsxClosingElement(tagName: JsxTagNamePropertyAccess): JsxClosingElement - fun updateJsxClosingElement(node: JsxClosingElement, tagName: Identifier): JsxClosingElement - fun updateJsxClosingElement(node: JsxClosingElement, tagName: ThisExpression): JsxClosingElement - fun updateJsxClosingElement(node: JsxClosingElement, tagName: JsxTagNamePropertyAccess): JsxClosingElement - fun createJsxFragment(openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment): JsxFragment - fun createJsxText(text: String, containsOnlyTriviaWhiteSpaces: Boolean = definedExternally): JsxText - fun updateJsxText(node: JsxText, text: String, containsOnlyTriviaWhiteSpaces: Boolean = definedExternally): JsxText - fun createJsxOpeningFragment(): JsxOpeningFragment - fun createJsxJsxClosingFragment(): JsxClosingFragment - fun updateJsxFragment(node: JsxFragment, openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment): JsxFragment - fun createJsxAttribute(name: Identifier, initializer: StringLiteral?): JsxAttribute - fun createJsxAttribute(name: Identifier, initializer: JsxExpression?): JsxAttribute - fun updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: StringLiteral?): JsxAttribute - fun updateJsxAttribute(node: JsxAttribute, name: Identifier, initializer: JsxExpression?): JsxAttribute - fun createJsxAttributes(properties: Array): JsxAttributes - fun updateJsxAttributes(node: JsxAttributes, properties: Array): JsxAttributes - fun createJsxSpreadAttribute(expression: Expression): JsxSpreadAttribute - fun updateJsxSpreadAttribute(node: JsxSpreadAttribute, expression: Expression): JsxSpreadAttribute - fun createJsxExpression(dotDotDotToken: DotDotDotToken?, expression: Expression?): JsxExpression - fun updateJsxExpression(node: JsxExpression, expression: Expression?): JsxExpression - fun createCaseClause(expression: Expression, statements: Array): CaseClause - fun updateCaseClause(node: CaseClause, expression: Expression, statements: Array): CaseClause - fun createDefaultClause(statements: Array): DefaultClause - fun updateDefaultClause(node: DefaultClause, statements: Array): DefaultClause - fun createHeritageClause(token: SyntaxKind.ExtendsKeyword, types: Array): HeritageClause - fun createHeritageClause(token: SyntaxKind.ImplementsKeyword, types: Array): HeritageClause - fun updateHeritageClause(node: HeritageClause, types: Array): HeritageClause - fun createCatchClause(variableDeclaration: String?, block: Block): CatchClause - fun createCatchClause(variableDeclaration: VariableDeclaration?, block: Block): CatchClause - fun updateCatchClause(node: CatchClause, variableDeclaration: VariableDeclaration?, block: Block): CatchClause - fun createPropertyAssignment(name: String, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: Identifier, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: StringLiteral, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: NumericLiteral, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: ComputedPropertyName, initializer: Expression): PropertyAssignment - fun createPropertyAssignment(name: PrivateIdentifier, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: Identifier, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: StringLiteral, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: NumericLiteral, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: ComputedPropertyName, initializer: Expression): PropertyAssignment - fun updatePropertyAssignment(node: PropertyAssignment, name: PrivateIdentifier, initializer: Expression): PropertyAssignment - fun createShorthandPropertyAssignment(name: String, objectAssignmentInitializer: Expression = definedExternally): ShorthandPropertyAssignment - fun createShorthandPropertyAssignment(name: String): ShorthandPropertyAssignment - fun createShorthandPropertyAssignment(name: Identifier, objectAssignmentInitializer: Expression = definedExternally): ShorthandPropertyAssignment - fun createShorthandPropertyAssignment(name: Identifier): ShorthandPropertyAssignment - fun updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression?): ShorthandPropertyAssignment - fun createSpreadAssignment(expression: Expression): SpreadAssignment - fun updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment - fun createEnumMember(name: String, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: String): EnumMember - fun createEnumMember(name: Identifier, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: Identifier): EnumMember - fun createEnumMember(name: StringLiteral, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: StringLiteral): EnumMember - fun createEnumMember(name: NumericLiteral, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: NumericLiteral): EnumMember - fun createEnumMember(name: ComputedPropertyName, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: ComputedPropertyName): EnumMember - fun createEnumMember(name: PrivateIdentifier, initializer: Expression = definedExternally): EnumMember - fun createEnumMember(name: PrivateIdentifier): EnumMember - fun updateEnumMember(node: EnumMember, name: Identifier, initializer: Expression?): EnumMember - fun updateEnumMember(node: EnumMember, name: StringLiteral, initializer: Expression?): EnumMember - fun updateEnumMember(node: EnumMember, name: NumericLiteral, initializer: Expression?): EnumMember - fun updateEnumMember(node: EnumMember, name: ComputedPropertyName, initializer: Expression?): EnumMember - fun updateEnumMember(node: EnumMember, name: PrivateIdentifier, initializer: Expression?): EnumMember - fun createSourceFile(statements: Array, endOfFileToken: Token /* Token & JSDocContainer */, flags: NodeFlags): SourceFile - fun updateSourceFile(node: SourceFile, statements: Array, isDeclarationFile: Boolean = definedExternally, referencedFiles: Array = definedExternally, typeReferences: Array = definedExternally, hasNoDefaultLib: Boolean = definedExternally, libReferences: Array = definedExternally): SourceFile - fun createNotEmittedStatement(original: Node): NotEmittedStatement - fun createPartiallyEmittedExpression(expression: Expression, original: Node = definedExternally): PartiallyEmittedExpression - fun updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression): PartiallyEmittedExpression - fun createCommaListExpression(elements: Array): CommaListExpression - fun updateCommaListExpression(node: CommaListExpression, elements: Array): CommaListExpression - fun createBundle(sourceFiles: Array, prepends: Array = definedExternally): Bundle - fun updateBundle(node: Bundle, sourceFiles: Array, prepends: Array = definedExternally): Bundle - fun createComma(left: Expression, right: Expression): BinaryExpression - fun createAssignment(left: ObjectLiteralExpression, right: Expression): dynamic /* ObjectDestructuringAssignment | ArrayDestructuringAssignment */ - fun createAssignment(left: ArrayLiteralExpression, right: Expression): dynamic /* ObjectDestructuringAssignment | ArrayDestructuringAssignment */ - fun createAssignment(left: Expression, right: Expression): AssignmentExpression - fun createLogicalOr(left: Expression, right: Expression): BinaryExpression - fun createLogicalAnd(left: Expression, right: Expression): BinaryExpression - fun createBitwiseOr(left: Expression, right: Expression): BinaryExpression - fun createBitwiseXor(left: Expression, right: Expression): BinaryExpression - fun createBitwiseAnd(left: Expression, right: Expression): BinaryExpression - fun createStrictEquality(left: Expression, right: Expression): BinaryExpression - fun createStrictInequality(left: Expression, right: Expression): BinaryExpression - fun createEquality(left: Expression, right: Expression): BinaryExpression - fun createInequality(left: Expression, right: Expression): BinaryExpression - fun createLessThan(left: Expression, right: Expression): BinaryExpression - fun createLessThanEquals(left: Expression, right: Expression): BinaryExpression - fun createGreaterThan(left: Expression, right: Expression): BinaryExpression - fun createGreaterThanEquals(left: Expression, right: Expression): BinaryExpression - fun createLeftShift(left: Expression, right: Expression): BinaryExpression - fun createRightShift(left: Expression, right: Expression): BinaryExpression - fun createUnsignedRightShift(left: Expression, right: Expression): BinaryExpression - fun createAdd(left: Expression, right: Expression): BinaryExpression - fun createSubtract(left: Expression, right: Expression): BinaryExpression - fun createMultiply(left: Expression, right: Expression): BinaryExpression - fun createDivide(left: Expression, right: Expression): BinaryExpression - fun createModulo(left: Expression, right: Expression): BinaryExpression - fun createExponent(left: Expression, right: Expression): BinaryExpression - fun createPrefixPlus(operand: Expression): PrefixUnaryExpression - fun createPrefixMinus(operand: Expression): PrefixUnaryExpression - fun createPrefixIncrement(operand: Expression): PrefixUnaryExpression - fun createPrefixDecrement(operand: Expression): PrefixUnaryExpression - fun createBitwiseNot(operand: Expression): PrefixUnaryExpression - fun createLogicalNot(operand: Expression): PrefixUnaryExpression - fun createPostfixIncrement(operand: Expression): PostfixUnaryExpression - fun createPostfixDecrement(operand: Expression): PostfixUnaryExpression - fun createImmediatelyInvokedFunctionExpression(statements: Array): CallExpression - fun createImmediatelyInvokedFunctionExpression(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression - fun createImmediatelyInvokedArrowFunction(statements: Array): CallExpression - fun createImmediatelyInvokedArrowFunction(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression - fun createVoidZero(): VoidExpression - fun createExportDefault(expression: Expression): ExportAssignment - fun createExternalModuleExport(exportName: Identifier): ExportDeclaration - fun restoreOuterExpressions(outerExpression: Expression?, innerExpression: Expression, kinds: OuterExpressionKinds = definedExternally): Expression -} - -external interface CoreTransformationContext { - var factory: NodeFactory - fun getCompilerOptions(): CompilerOptions - fun startLexicalEnvironment() - fun suspendLexicalEnvironment() - fun resumeLexicalEnvironment() - fun endLexicalEnvironment(): Array? - fun hoistFunctionDeclaration(node: FunctionDeclaration) - fun hoistVariableDeclaration(node: Identifier) -} - -external interface TransformationContext : CoreTransformationContext { - fun requestEmitHelper(helper: ScopedEmitHelper) - fun requestEmitHelper(helper: UnscopedEmitHelper) - fun readEmitHelpers(): Array? - fun enableSubstitution(kind: SyntaxKind) - fun isSubstitutionEnabled(node: Node): Boolean - var onSubstituteNode: (hint: EmitHint, node: Node) -> Node - fun enableEmitNotification(kind: SyntaxKind) - fun isEmitNotificationEnabled(node: Node): Boolean - var onEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) -> Unit -} - -external interface TransformationResult { - var transformed: Array - var diagnostics: Array? - get() = definedExternally - set(value) = definedExternally - fun substituteNode(hint: EmitHint, node: Node): Node - fun emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) - val isEmitNotificationEnabled: ((node: Node) -> Boolean)? - fun dispose() -} - -external interface NodeVisitor { - @nativeInvoke - operator fun invoke(nodes: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T - @nativeInvoke - operator fun invoke(nodes: T, visitor: Visitor?): T - @nativeInvoke - operator fun invoke(nodes: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T - @nativeInvoke - operator fun invoke(nodes: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T? - @nativeInvoke - operator fun invoke(nodes: T?, visitor: Visitor?): T? - @nativeInvoke - operator fun invoke(nodes: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T? -} - -external interface NodesVisitor { - @nativeInvoke - operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray - @nativeInvoke - operator fun invoke(nodes: NodeArray, visitor: Visitor?): NodeArray - @nativeInvoke - operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray - @nativeInvoke - operator fun invoke(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray - @nativeInvoke - operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray? - @nativeInvoke - operator fun invoke(nodes: NodeArray?, visitor: Visitor?): NodeArray? - @nativeInvoke - operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray? - @nativeInvoke - operator fun invoke(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray? -} - -external interface Printer { - fun printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): String - fun printList(format: ListFormat, list: NodeArray, sourceFile: SourceFile): String - fun printFile(sourceFile: SourceFile): String - fun printBundle(bundle: Bundle): String -} - -external interface PrintHandlers { - val hasGlobalName: ((name: String) -> Boolean)? - val onEmitNode: ((hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) -> Unit) -> Unit)? - val isEmitNotificationEnabled: ((node: Node) -> Boolean)? - val substituteNode: ((hint: EmitHint, node: Node) -> Node)? -} - -external interface PrinterOptions { - var removeComments: Boolean? - get() = definedExternally - set(value) = definedExternally - var newLine: NewLineKind? - get() = definedExternally - set(value) = definedExternally - var omitTrailingSemicolon: Boolean? - get() = definedExternally - set(value) = definedExternally - var noEmitHelpers: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface GetEffectiveTypeRootsHost { - val directoryExists: ((directoryName: String) -> Boolean)? - val getCurrentDirectory: (() -> String)? -} - -external interface TextSpan { - var start: Number - var length: Number -} - -external interface TextChangeRange { - var span: TextSpan - var newLength: Number -} - -external interface SyntaxList : Node { - var _children: Array -} - -external enum class ListFormat { - None /* = 0 */, - SingleLine /* = 0 */, - MultiLine /* = 1 */, - PreserveLines /* = 2 */, - LinesMask /* = 3 */, - NotDelimited /* = 0 */, - BarDelimited /* = 4 */, - AmpersandDelimited /* = 8 */, - CommaDelimited /* = 16 */, - AsteriskDelimited /* = 32 */, - DelimitersMask /* = 60 */, - AllowTrailingComma /* = 64 */, - Indented /* = 128 */, - SpaceBetweenBraces /* = 256 */, - SpaceBetweenSiblings /* = 512 */, - Braces /* = 1024 */, - Parenthesis /* = 2048 */, - AngleBrackets /* = 4096 */, - SquareBrackets /* = 8192 */, - BracketsMask /* = 15360 */, - OptionalIfUndefined /* = 16384 */, - OptionalIfEmpty /* = 32768 */, - Optional /* = 49152 */, - PreferNewLine /* = 65536 */, - NoTrailingNewLine /* = 131072 */, - NoInterveningComments /* = 262144 */, - NoSpaceIfEmpty /* = 524288 */, - SingleElement /* = 1048576 */, - SpaceAfterList /* = 2097152 */, - Modifiers /* = 262656 */, - HeritageClauses /* = 512 */, - SingleLineTypeLiteralMembers /* = 768 */, - MultiLineTypeLiteralMembers /* = 32897 */, - SingleLineTupleTypeElements /* = 528 */, - MultiLineTupleTypeElements /* = 657 */, - UnionTypeConstituents /* = 516 */, - IntersectionTypeConstituents /* = 520 */, - ObjectBindingPatternElements /* = 525136 */, - ArrayBindingPatternElements /* = 524880 */, - ObjectLiteralExpressionProperties /* = 526226 */, - ArrayLiteralExpressionElements /* = 8914 */, - CommaListElements /* = 528 */, - CallExpressionArguments /* = 2576 */, - NewExpressionArguments /* = 18960 */, - TemplateExpressionSpans /* = 262144 */, - SingleLineBlockStatements /* = 768 */, - MultiLineBlockStatements /* = 129 */, - VariableDeclarationList /* = 528 */, - SingleLineFunctionBodyStatements /* = 768 */, - MultiLineFunctionBodyStatements /* = 1 */, - ClassHeritageClauses /* = 0 */, - ClassMembers /* = 129 */, - InterfaceMembers /* = 129 */, - EnumMembers /* = 145 */, - CaseBlockClauses /* = 129 */, - NamedImportsOrExportsElements /* = 525136 */, - JsxElementOrFragmentChildren /* = 262144 */, - JsxElementAttributes /* = 262656 */, - CaseOrDefaultClauseStatements /* = 163969 */, - HeritageClauseTypes /* = 528 */, - SourceFileStatements /* = 131073 */, - Decorators /* = 2146305 */, - TypeArguments /* = 53776 */, - TypeParameters /* = 53776 */, - Parameters /* = 2576 */, - IndexSignatureParameters /* = 8848 */, - JSDocComment /* = 33 */ -} - -external interface UserPreferences { - var disableSuggestions: Boolean? - get() = definedExternally - set(value) = definedExternally - var quotePreference: String? /* "auto" | "double" | "single" */ - get() = definedExternally - set(value) = definedExternally - var includeCompletionsForModuleExports: Boolean? - get() = definedExternally - set(value) = definedExternally - var includeCompletionsForImportStatements: Boolean? - get() = definedExternally - set(value) = definedExternally - var includeCompletionsWithSnippetText: Boolean? - get() = definedExternally - set(value) = definedExternally - var includeAutomaticOptionalChainCompletions: Boolean? - get() = definedExternally - set(value) = definedExternally - var includeCompletionsWithInsertText: Boolean? - get() = definedExternally - set(value) = definedExternally - var allowIncompleteCompletions: Boolean? - get() = definedExternally - set(value) = definedExternally - var importModuleSpecifierPreference: String? /* "shortest" | "project-relative" | "relative" | "non-relative" */ - get() = definedExternally - set(value) = definedExternally - var importModuleSpecifierEnding: String? /* "auto" | "minimal" | "index" | "js" */ - get() = definedExternally - set(value) = definedExternally - var allowTextChangesInNewFiles: Boolean? - get() = definedExternally - set(value) = definedExternally - var providePrefixAndSuffixTextForRename: Boolean? - get() = definedExternally - set(value) = definedExternally - var includePackageJsonAutoImports: String? /* "auto" | "on" | "off" */ - get() = definedExternally - set(value) = definedExternally - var provideRefactorNotApplicableReason: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface PseudoBigInt { - var negative: Boolean - var base10Value: String -} - -external enum class FileWatcherEventKind { - Created /* = 0 */, - Changed /* = 1 */, - Deleted /* = 2 */ -} - -external interface System { - var args: Array - var newLine: String - var useCaseSensitiveFileNames: Boolean - fun write(s: String) - val writeOutputIsTTY: (() -> Boolean)? - val getWidthOfTerminal: (() -> Number)? - fun readFile(path: String, encoding: String = definedExternally): String? - val getFileSize: ((path: String) -> Number)? - fun writeFile(path: String, data: String, writeByteOrderMark: Boolean = definedExternally) - val watchFile: ((path: String, callback: FileWatcherCallback, pollingInterval: Number, options: WatchOptions) -> FileWatcher)? - val watchDirectory: ((path: String, callback: DirectoryWatcherCallback, recursive: Boolean, options: WatchOptions) -> FileWatcher)? - fun resolvePath(path: String): String - fun fileExists(path: String): Boolean - fun directoryExists(path: String): Boolean - fun createDirectory(path: String) - fun getExecutingFilePath(): String - fun getCurrentDirectory(): String - fun getDirectories(path: String): Array - fun readDirectory(path: String, extensions: Array = definedExternally, exclude: Array = definedExternally, include: Array = definedExternally, depth: Number = definedExternally): Array - val getModifiedTime: ((path: String) -> Date?)? - val setModifiedTime: ((path: String, time: Date) -> Unit)? - val deleteFile: ((path: String) -> Unit)? - val createHash: ((data: String) -> String)? - val createSHA256Hash: ((data: String) -> String)? - val getMemoryUsage: (() -> Number)? - fun exit(exitCode: Number = definedExternally) - val realpath: ((path: String) -> String)? - val setTimeout: ((callback: (args: Any) -> Unit, ms: Number, args: Any) -> Any)? - val clearTimeout: ((timeoutId: Any) -> Unit)? - val clearScreen: (() -> Unit)? - val base64decode: ((input: String) -> String)? - val base64encode: ((input: String) -> String)? -} - -external interface FileWatcher { - fun close() -} - -external fun getNodeMajorVersion(): Number? - -external var sys: System - -external interface Scanner { - fun getStartPos(): Number - fun getToken(): SyntaxKind - fun getTextPos(): Number - fun getTokenPos(): Number - fun getTokenText(): String - fun getTokenValue(): String - fun hasUnicodeEscape(): Boolean - fun hasExtendedUnicodeEscape(): Boolean - fun hasPrecedingLineBreak(): Boolean - fun isIdentifier(): Boolean - fun isReservedWord(): Boolean - fun isUnterminated(): Boolean - fun reScanGreaterToken(): SyntaxKind - fun reScanSlashToken(): SyntaxKind - fun reScanAsteriskEqualsToken(): SyntaxKind - fun reScanTemplateToken(isTaggedTemplate: Boolean): SyntaxKind - fun reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind - fun scanJsxIdentifier(): SyntaxKind - fun scanJsxAttributeValue(): SyntaxKind - fun reScanJsxAttributeValue(): SyntaxKind - fun reScanJsxToken(allowMultilineJsxText: Boolean = definedExternally): dynamic /* SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken */ - fun reScanLessThanToken(): SyntaxKind - fun reScanHashToken(): SyntaxKind - fun reScanQuestionToken(): SyntaxKind - fun reScanInvalidIdentifier(): SyntaxKind - fun scanJsxToken(): dynamic /* SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken */ - fun scanJsDocToken(): dynamic /* SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.HashToken | SyntaxKind.Unknown | SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IntrinsicKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.OverrideKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword */ - fun scan(): SyntaxKind - fun getText(): String - fun setText(text: String?, start: Number = definedExternally, length: Number = definedExternally) - fun setOnError(onError: ErrorCallback?) - fun setScriptTarget(scriptTarget: ScriptTarget) - fun setLanguageVariant(variant: LanguageVariant) - fun setTextPos(textPos: Number) - fun lookAhead(callback: () -> T): T - fun scanRange(start: Number, length: Number, callback: () -> T): T - fun tryScan(callback: () -> T): T -} - -external fun tokenToString(t: SyntaxKind): String? - -external fun getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: Number, character: Number): Number - -external fun getLineAndCharacterOfPosition(sourceFile: SourceFileLike, position: Number): LineAndCharacter - -external fun isWhiteSpaceLike(ch: Number): Boolean - -external fun isWhiteSpaceSingleLine(ch: Number): Boolean - -external fun isLineBreak(ch: Number): Boolean - -external fun couldStartTrivia(text: String, pos: Number): Boolean - -external fun forEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean) -> U): U? - -external fun forEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T) -> U, state: T): U? - -external fun forEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean) -> U): U? - -external fun forEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T) -> U, state: T): U? - -external fun reduceEachLeadingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T, memo: U) -> U, state: T, initial: U): U? - -external fun reduceEachTrailingCommentRange(text: String, pos: Number, cb: (pos: Number, end: Number, kind: Any /* SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia */, hasTrailingNewLine: Boolean, state: T, memo: U) -> U, state: T, initial: U): U? - -external fun getLeadingCommentRanges(text: String, pos: Number): Array? - -external fun getTrailingCommentRanges(text: String, pos: Number): Array? - -external fun getShebang(text: String): String? - -external fun isIdentifierStart(ch: Number, languageVersion: ScriptTarget?): Boolean - -external fun isIdentifierPart(ch: Number, languageVersion: ScriptTarget?, identifierVariant: LanguageVariant = definedExternally): Boolean - -external fun createScanner(languageVersion: ScriptTarget, skipTrivia: Boolean, languageVariant: LanguageVariant = definedExternally, textInitial: String = definedExternally, onError: ErrorCallback = definedExternally, start: Number = definedExternally, length: Number = definedExternally): Scanner - -external fun isExternalModuleNameRelative(moduleName: String): Boolean - -external fun sortAndDeduplicateDiagnostics(diagnostics: Array): SortedReadonlyArray - -external fun getDefaultLibFileName(options: CompilerOptions): String - -external fun textSpanEnd(span: TextSpan): Number - -external fun textSpanIsEmpty(span: TextSpan): Boolean - -external fun textSpanContainsPosition(span: TextSpan, position: Number): Boolean - -external fun textSpanContainsTextSpan(span: TextSpan, other: TextSpan): Boolean - -external fun textSpanOverlapsWith(span: TextSpan, other: TextSpan): Boolean - -external fun textSpanOverlap(span1: TextSpan, span2: TextSpan): TextSpan? - -external fun textSpanIntersectsWithTextSpan(span: TextSpan, other: TextSpan): Boolean - -external fun textSpanIntersectsWith(span: TextSpan, start: Number, length: Number): Boolean - -external fun decodedTextSpanIntersectsWith(start1: Number, length1: Number, start2: Number, length2: Number): Boolean - -external fun textSpanIntersectsWithPosition(span: TextSpan, position: Number): Boolean - -external fun textSpanIntersection(span1: TextSpan, span2: TextSpan): TextSpan? - -external fun createTextSpan(start: Number, length: Number): TextSpan - -external fun createTextSpanFromBounds(start: Number, end: Number): TextSpan - -external fun textChangeRangeNewSpan(range: TextChangeRange): TextSpan - -external fun textChangeRangeIsUnchanged(range: TextChangeRange): Boolean - -external fun createTextChangeRange(span: TextSpan, newLength: Number): TextChangeRange - -external var unchangedTextChangeRange: TextChangeRange - -external fun collapseTextChangeRangesAcrossMultipleVersions(changes: Array): TextChangeRange - -external fun getTypeParameterOwner(d: Declaration): Declaration? - -external interface `T$23` { - var parent: ConstructorDeclaration - var name: Identifier -} - -external fun isParameterPropertyDeclaration(node: Node, parent: Node): Boolean - -external fun isEmptyBindingPattern(node: Identifier): Boolean - -external fun isEmptyBindingPattern(node: ObjectBindingPattern): Boolean - -external fun isEmptyBindingPattern(node: ArrayBindingPattern): Boolean - -external fun isEmptyBindingElement(node: BindingElement): Boolean - -external fun walkUpBindingElementsAndPatterns(binding: BindingElement): dynamic /* VariableDeclaration | ParameterDeclaration */ - -external fun getCombinedModifierFlags(node: Declaration): ModifierFlags - -external fun getCombinedNodeFlags(node: Node): NodeFlags - -external interface `T$24` { - fun getExecutingFilePath(): String - fun resolvePath(path: String): String - fun fileExists(fileName: String): Boolean - fun readFile(fileName: String): String? -} - -external fun validateLocaleAndSetLanguage(locale: String, sys: `T$24`, errors: Push = definedExternally) - -external fun getOriginalNode(node: Node): Node - -external fun getOriginalNode(node: Node, nodeTest: (node: Node) -> Boolean): T - -external fun getOriginalNode(node: Node?): Node? - -external fun getOriginalNode(node: Node?, nodeTest: (node: Node?) -> Boolean): T? - -external fun findAncestor(node: Node?, callback: (element: Node) -> Boolean): T? - -external fun findAncestor(node: Node?, callback: (element: Node) -> Any): Node? - -external fun isParseTreeNode(node: Node): Boolean - -external fun getParseTreeNode(node: Node?): Node? - -external fun getParseTreeNode(node: T?, nodeTest: (node: Node) -> Boolean = definedExternally): T? - -external fun getParseTreeNode(node: T?): T? - -external fun escapeLeadingUnderscores(identifier: String): dynamic /* String & `T$8` | Unit & `T$8` | InternalSymbolName */ - -external fun unescapeLeadingUnderscores(identifier: String /* String & `T$8` */): String - -external fun unescapeLeadingUnderscores(identifier: Unit /* Unit & `T$8` */): String - -external fun unescapeLeadingUnderscores(identifier: InternalSymbolName): String - -external fun idText(identifierOrPrivateName: Identifier): String - -external fun idText(identifierOrPrivateName: PrivateIdentifier): String - -external fun symbolName(symbol: Symbol): String - -external fun getNameOfJSDocTypedef(declaration: JSDocTypedefTag): dynamic /* Identifier? | PrivateIdentifier? */ - -external fun getNameOfDeclaration(declaration: Declaration?): dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ - -external fun getNameOfDeclaration(declaration: Expression?): dynamic /* Identifier? | PrivateIdentifier? | StringLiteral? | NoSubstitutionTemplateLiteral? | NumericLiteral? | ComputedPropertyName? | ElementAccessExpression? | ObjectBindingPattern? | ArrayBindingPattern? | PropertyAccessEntityNameExpression? */ - -external fun getJSDocParameterTags(param: ParameterDeclaration): Array - -external fun getJSDocTypeParameterTags(param: TypeParameterDeclaration): Array - -external fun hasJSDocParameterTags(node: FunctionDeclaration): Boolean - -external fun hasJSDocParameterTags(node: MethodDeclaration): Boolean - -external fun hasJSDocParameterTags(node: GetAccessorDeclaration): Boolean - -external fun hasJSDocParameterTags(node: SetAccessorDeclaration): Boolean - -external fun hasJSDocParameterTags(node: ConstructorDeclaration): Boolean - -external fun hasJSDocParameterTags(node: FunctionExpression): Boolean - -external fun hasJSDocParameterTags(node: ArrowFunction): Boolean - -external fun hasJSDocParameterTags(node: CallSignatureDeclaration): Boolean - -external fun hasJSDocParameterTags(node: ConstructSignatureDeclaration): Boolean - -external fun hasJSDocParameterTags(node: MethodSignature): Boolean - -external fun hasJSDocParameterTags(node: IndexSignatureDeclaration): Boolean - -external fun hasJSDocParameterTags(node: FunctionTypeNode): Boolean - -external fun hasJSDocParameterTags(node: ConstructorTypeNode): Boolean - -external fun hasJSDocParameterTags(node: JSDocFunctionType): Boolean - -external fun getJSDocAugmentsTag(node: Node): JSDocAugmentsTag? - -external fun getJSDocImplementsTags(node: Node): Array - -external fun getJSDocClassTag(node: Node): JSDocClassTag? - -external fun getJSDocPublicTag(node: Node): JSDocPublicTag? - -external fun getJSDocPrivateTag(node: Node): JSDocPrivateTag? - -external fun getJSDocProtectedTag(node: Node): JSDocProtectedTag? - -external fun getJSDocReadonlyTag(node: Node): JSDocReadonlyTag? - -external fun getJSDocOverrideTagNoCache(node: Node): JSDocOverrideTag? - -external fun getJSDocDeprecatedTag(node: Node): JSDocDeprecatedTag? - -external fun getJSDocEnumTag(node: Node): JSDocEnumTag? - -external fun getJSDocThisTag(node: Node): JSDocThisTag? - -external fun getJSDocReturnTag(node: Node): JSDocReturnTag? - -external fun getJSDocTemplateTag(node: Node): JSDocTemplateTag? - -external fun getJSDocTypeTag(node: Node): JSDocTypeTag? - -external fun getJSDocType(node: Node): TypeNode? - -external fun getJSDocReturnType(node: Node): TypeNode? - -external fun getJSDocTags(node: Node): Array - -external fun getAllJSDocTags(node: Node, predicate: (tag: JSDocTag) -> Boolean): Array - -external fun getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): Array - -external fun getTextOfJSDocComment(comment: String = definedExternally): String? - -external fun getTextOfJSDocComment(): String? - -external fun getTextOfJSDocComment(comment: NodeArray = definedExternally): String? - -external fun getEffectiveTypeParameterDeclarations(node: Any /* CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | JSDocFunctionType | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionExpression | ArrowFunction | ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature */): Array - -external fun getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode? - -external fun isMemberName(node: Node): Boolean - -external fun isPropertyAccessChain(node: Node): Boolean - -external fun isElementAccessChain(node: Node): Boolean - -external fun isCallChain(node: Node): Boolean - -external fun isOptionalChain(node: Node): Boolean - -external fun isNullishCoalesce(node: Node): Boolean - -external fun isConstTypeReference(node: Node): Boolean - -external fun skipPartiallyEmittedExpressions(node: Expression): Expression - -external fun skipPartiallyEmittedExpressions(node: Node): Node - -external fun isNonNullChain(node: Node): Boolean - -external fun isBreakOrContinueStatement(node: Node): Boolean - -external fun isNamedExportBindings(node: Node): Boolean - -external fun isUnparsedTextLike(node: Node): Boolean - -external fun isUnparsedNode(node: Node): Boolean - -external fun isJSDocPropertyLikeTag(node: Node): Boolean - -external fun isTokenKind(kind: SyntaxKind): Boolean - -external fun isToken(n: Node): Boolean - -external fun isLiteralExpression(node: Node): Boolean - -external fun isTemplateLiteralToken(node: Node): Boolean - -external fun isTemplateMiddleOrTemplateTail(node: Node): Boolean - -external fun isImportOrExportSpecifier(node: Node): Boolean - -external fun isTypeOnlyImportOrExportDeclaration(node: Node): Boolean - -external fun isStringTextContainingNode(node: Node): Boolean - -external fun isModifier(node: Node): Boolean - -external fun isEntityName(node: Node): Boolean - -external fun isPropertyName(node: Node): Boolean - -external fun isBindingName(node: Node): Boolean - -external fun isFunctionLike(node: Node?): Boolean - -external fun isClassElement(node: Node): Boolean - -external fun isClassLike(node: Node): Boolean - -external fun isAccessor(node: Node): Boolean - -external fun isTypeElement(node: Node): Boolean - -external fun isClassOrTypeElement(node: Node): Boolean - -external fun isObjectLiteralElementLike(node: Node): Boolean - -external fun isTypeNode(node: Node): Boolean - -external fun isFunctionOrConstructorTypeNode(node: Node): Boolean - -external fun isPropertyAccessOrQualifiedName(node: Node): Boolean - -external fun isCallLikeExpression(node: Node): Boolean - -external fun isCallOrNewExpression(node: Node): Boolean - -external fun isTemplateLiteral(node: Node): Boolean - -external fun isAssertionExpression(node: Node): Boolean - -external fun isIterationStatement(node: Node, lookInLabeledStatements: Boolean): Boolean - -external fun isJsxOpeningLikeElement(node: Node): Boolean - -external fun isCaseOrDefaultClause(node: Node): Boolean - -external fun isJSDocCommentContainingNode(node: Node): Boolean - -external fun isSetAccessor(node: Node): Boolean - -external fun isGetAccessor(node: Node): Boolean - -external fun hasOnlyExpressionInitializer(node: Node): Boolean - -external fun isObjectLiteralElement(node: Node): Boolean - -external fun isStringLiteralLike(node: Node): Boolean - -external fun isJSDocLinkLike(node: Node): Boolean - -external var factory: NodeFactory - -external fun createUnparsedSourceFile(text: String): UnparsedSource - -external fun createUnparsedSourceFile(inputFile: InputFiles, type: String /* "js" | "dts" */, stripInternal: Boolean = definedExternally): UnparsedSource - -external fun createUnparsedSourceFile(inputFile: InputFiles, type: String /* "js" | "dts" */): UnparsedSource - -external fun createUnparsedSourceFile(text: String, mapPath: String?, map: String?): UnparsedSource - -external fun createInputFiles(javascriptText: String, declarationText: String): InputFiles - -external fun createInputFiles(readFileText: (path: String) -> String?, javascriptPath: String, javascriptMapPath: String?, declarationPath: String, declarationMapPath: String?, buildInfoPath: String?): InputFiles - -external fun createInputFiles(javascriptText: String, declarationText: String, javascriptMapPath: String?, javascriptMapText: String?, declarationMapPath: String?, declarationMapText: String?): InputFiles - -external fun createSourceMapSource(fileName: String, text: String, skipTrivia: (pos: Number) -> Number = definedExternally): SourceMapSource - -external fun setOriginalNode(node: T, original: Node?): T - -external fun disposeEmitNodes(sourceFile: SourceFile?) - -external fun setEmitFlags(node: T, emitFlags: EmitFlags): T - -external fun getSourceMapRange(node: Node): SourceMapRange - -external fun setSourceMapRange(node: T, range: SourceMapRange?): T - -external fun getTokenSourceMapRange(node: Node, token: SyntaxKind): SourceMapRange? - -external fun setTokenSourceMapRange(node: T, token: SyntaxKind, range: SourceMapRange?): T - -external fun getCommentRange(node: Node): TextRange - -external fun setCommentRange(node: T, range: TextRange): T - -external fun getSyntheticLeadingComments(node: Node): Array? - -external fun setSyntheticLeadingComments(node: T, comments: Array?): T - -external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T - -external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String): T - -external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T - -external fun addSyntheticLeadingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String): T - -external fun getSyntheticTrailingComments(node: Node): Array? - -external fun setSyntheticTrailingComments(node: T, comments: Array?): T - -external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T - -external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia, text: String): T - -external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String, hasTrailingNewLine: Boolean = definedExternally): T - -external fun addSyntheticTrailingComment(node: T, kind: SyntaxKind.MultiLineCommentTrivia, text: String): T - -external fun moveSyntheticComments(node: T, original: Node): T - -external fun getConstantValue(node: PropertyAccessExpression): dynamic /* String? | Number? */ - -external fun getConstantValue(node: ElementAccessExpression): dynamic /* String? | Number? */ - -external fun setConstantValue(node: PropertyAccessExpression, value: String): dynamic /* PropertyAccessExpression | ElementAccessExpression */ - -external fun setConstantValue(node: PropertyAccessExpression, value: Number): dynamic /* PropertyAccessExpression | ElementAccessExpression */ - -external fun setConstantValue(node: ElementAccessExpression, value: String): dynamic /* PropertyAccessExpression | ElementAccessExpression */ - -external fun setConstantValue(node: ElementAccessExpression, value: Number): dynamic /* PropertyAccessExpression | ElementAccessExpression */ - -external fun addEmitHelper(node: T, helper: ScopedEmitHelper): T - -external fun addEmitHelper(node: T, helper: UnscopedEmitHelper): T - -external fun addEmitHelpers(node: T, helpers: Array?): T - -external fun removeEmitHelper(node: Node, helper: ScopedEmitHelper): Boolean - -external fun removeEmitHelper(node: Node, helper: UnscopedEmitHelper): Boolean - -external fun getEmitHelpers(node: Node): Array? - -external fun moveEmitHelpers(source: Node, target: Node, predicate: (helper: Any /* ScopedEmitHelper | UnscopedEmitHelper */) -> Boolean) - -external fun isNumericLiteral(node: Node): Boolean - -external fun isBigIntLiteral(node: Node): Boolean - -external fun isStringLiteral(node: Node): Boolean - -external fun isJsxText(node: Node): Boolean - -external fun isRegularExpressionLiteral(node: Node): Boolean - -external fun isNoSubstitutionTemplateLiteral(node: Node): Boolean - -external fun isTemplateHead(node: Node): Boolean - -external fun isTemplateMiddle(node: Node): Boolean - -external fun isTemplateTail(node: Node): Boolean - -external fun isDotDotDotToken(node: Node): Boolean - -external fun isPlusToken(node: Node): Boolean - -external fun isMinusToken(node: Node): Boolean - -external fun isAsteriskToken(node: Node): Boolean - -external fun isIdentifier(node: Node): Boolean - -external fun isPrivateIdentifier(node: Node): Boolean - -external fun isQualifiedName(node: Node): Boolean - -external fun isComputedPropertyName(node: Node): Boolean - -external fun isTypeParameterDeclaration(node: Node): Boolean - -external fun isParameter(node: Node): Boolean - -external fun isDecorator(node: Node): Boolean - -external fun isPropertySignature(node: Node): Boolean - -external fun isPropertyDeclaration(node: Node): Boolean - -external fun isMethodSignature(node: Node): Boolean - -external fun isMethodDeclaration(node: Node): Boolean - -external fun isClassStaticBlockDeclaration(node: Node): Boolean - -external fun isConstructorDeclaration(node: Node): Boolean - -external fun isGetAccessorDeclaration(node: Node): Boolean - -external fun isSetAccessorDeclaration(node: Node): Boolean - -external fun isCallSignatureDeclaration(node: Node): Boolean - -external fun isConstructSignatureDeclaration(node: Node): Boolean - -external fun isIndexSignatureDeclaration(node: Node): Boolean - -external fun isTypePredicateNode(node: Node): Boolean - -external fun isTypeReferenceNode(node: Node): Boolean - -external fun isFunctionTypeNode(node: Node): Boolean - -external fun isConstructorTypeNode(node: Node): Boolean - -external fun isTypeQueryNode(node: Node): Boolean - -external fun isTypeLiteralNode(node: Node): Boolean - -external fun isArrayTypeNode(node: Node): Boolean - -external fun isTupleTypeNode(node: Node): Boolean - -external fun isNamedTupleMember(node: Node): Boolean - -external fun isOptionalTypeNode(node: Node): Boolean - -external fun isRestTypeNode(node: Node): Boolean - -external fun isUnionTypeNode(node: Node): Boolean - -external fun isIntersectionTypeNode(node: Node): Boolean - -external fun isConditionalTypeNode(node: Node): Boolean - -external fun isInferTypeNode(node: Node): Boolean - -external fun isParenthesizedTypeNode(node: Node): Boolean - -external fun isThisTypeNode(node: Node): Boolean - -external fun isTypeOperatorNode(node: Node): Boolean - -external fun isIndexedAccessTypeNode(node: Node): Boolean - -external fun isMappedTypeNode(node: Node): Boolean - -external fun isLiteralTypeNode(node: Node): Boolean - -external fun isImportTypeNode(node: Node): Boolean - -external fun isTemplateLiteralTypeSpan(node: Node): Boolean - -external fun isTemplateLiteralTypeNode(node: Node): Boolean - -external fun isObjectBindingPattern(node: Node): Boolean - -external fun isArrayBindingPattern(node: Node): Boolean - -external fun isBindingElement(node: Node): Boolean - -external fun isArrayLiteralExpression(node: Node): Boolean - -external fun isObjectLiteralExpression(node: Node): Boolean - -external fun isPropertyAccessExpression(node: Node): Boolean - -external fun isElementAccessExpression(node: Node): Boolean - -external fun isCallExpression(node: Node): Boolean - -external fun isNewExpression(node: Node): Boolean - -external fun isTaggedTemplateExpression(node: Node): Boolean - -external fun isTypeAssertionExpression(node: Node): Boolean - -external fun isParenthesizedExpression(node: Node): Boolean - -external fun isFunctionExpression(node: Node): Boolean - -external fun isArrowFunction(node: Node): Boolean - -external fun isDeleteExpression(node: Node): Boolean - -external fun isTypeOfExpression(node: Node): Boolean - -external fun isVoidExpression(node: Node): Boolean - -external fun isAwaitExpression(node: Node): Boolean - -external fun isPrefixUnaryExpression(node: Node): Boolean - -external fun isPostfixUnaryExpression(node: Node): Boolean - -external fun isBinaryExpression(node: Node): Boolean - -external fun isConditionalExpression(node: Node): Boolean - -external fun isTemplateExpression(node: Node): Boolean - -external fun isYieldExpression(node: Node): Boolean - -external fun isSpreadElement(node: Node): Boolean - -external fun isClassExpression(node: Node): Boolean - -external fun isOmittedExpression(node: Node): Boolean - -external fun isExpressionWithTypeArguments(node: Node): Boolean - -external fun isAsExpression(node: Node): Boolean - -external fun isNonNullExpression(node: Node): Boolean - -external fun isMetaProperty(node: Node): Boolean - -external fun isSyntheticExpression(node: Node): Boolean - -external fun isPartiallyEmittedExpression(node: Node): Boolean - -external fun isCommaListExpression(node: Node): Boolean - -external fun isTemplateSpan(node: Node): Boolean - -external fun isSemicolonClassElement(node: Node): Boolean - -external fun isBlock(node: Node): Boolean - -external fun isVariableStatement(node: Node): Boolean - -external fun isEmptyStatement(node: Node): Boolean - -external fun isExpressionStatement(node: Node): Boolean - -external fun isIfStatement(node: Node): Boolean - -external fun isDoStatement(node: Node): Boolean - -external fun isWhileStatement(node: Node): Boolean - -external fun isForStatement(node: Node): Boolean - -external fun isForInStatement(node: Node): Boolean - -external fun isForOfStatement(node: Node): Boolean - -external fun isContinueStatement(node: Node): Boolean - -external fun isBreakStatement(node: Node): Boolean - -external fun isReturnStatement(node: Node): Boolean - -external fun isWithStatement(node: Node): Boolean - -external fun isSwitchStatement(node: Node): Boolean - -external fun isLabeledStatement(node: Node): Boolean - -external fun isThrowStatement(node: Node): Boolean - -external fun isTryStatement(node: Node): Boolean - -external fun isDebuggerStatement(node: Node): Boolean - -external fun isVariableDeclaration(node: Node): Boolean - -external fun isVariableDeclarationList(node: Node): Boolean - -external fun isFunctionDeclaration(node: Node): Boolean - -external fun isClassDeclaration(node: Node): Boolean - -external fun isInterfaceDeclaration(node: Node): Boolean - -external fun isTypeAliasDeclaration(node: Node): Boolean - -external fun isEnumDeclaration(node: Node): Boolean - -external fun isModuleDeclaration(node: Node): Boolean - -external fun isModuleBlock(node: Node): Boolean - -external fun isCaseBlock(node: Node): Boolean - -external fun isNamespaceExportDeclaration(node: Node): Boolean - -external fun isImportEqualsDeclaration(node: Node): Boolean - -external fun isImportDeclaration(node: Node): Boolean - -external fun isImportClause(node: Node): Boolean - -external fun isNamespaceImport(node: Node): Boolean - -external fun isNamespaceExport(node: Node): Boolean - -external fun isNamedImports(node: Node): Boolean - -external fun isImportSpecifier(node: Node): Boolean - -external fun isExportAssignment(node: Node): Boolean - -external fun isExportDeclaration(node: Node): Boolean - -external fun isNamedExports(node: Node): Boolean - -external fun isExportSpecifier(node: Node): Boolean - -external fun isMissingDeclaration(node: Node): Boolean - -external fun isNotEmittedStatement(node: Node): Boolean - -external fun isExternalModuleReference(node: Node): Boolean - -external fun isJsxElement(node: Node): Boolean - -external fun isJsxSelfClosingElement(node: Node): Boolean - -external fun isJsxOpeningElement(node: Node): Boolean - -external fun isJsxClosingElement(node: Node): Boolean - -external fun isJsxFragment(node: Node): Boolean - -external fun isJsxOpeningFragment(node: Node): Boolean - -external fun isJsxClosingFragment(node: Node): Boolean - -external fun isJsxAttribute(node: Node): Boolean - -external fun isJsxAttributes(node: Node): Boolean - -external fun isJsxSpreadAttribute(node: Node): Boolean - -external fun isJsxExpression(node: Node): Boolean - -external fun isCaseClause(node: Node): Boolean - -external fun isDefaultClause(node: Node): Boolean - -external fun isHeritageClause(node: Node): Boolean - -external fun isCatchClause(node: Node): Boolean - -external fun isPropertyAssignment(node: Node): Boolean - -external fun isShorthandPropertyAssignment(node: Node): Boolean - -external fun isSpreadAssignment(node: Node): Boolean - -external fun isEnumMember(node: Node): Boolean - -external fun isUnparsedPrepend(node: Node): Boolean - -external fun isSourceFile(node: Node): Boolean - -external fun isBundle(node: Node): Boolean - -external fun isUnparsedSource(node: Node): Boolean - -external fun isJSDocTypeExpression(node: Node): Boolean - -external fun isJSDocNameReference(node: Node): Boolean - -external fun isJSDocMemberName(node: Node): Boolean - -external fun isJSDocLink(node: Node): Boolean - -external fun isJSDocLinkCode(node: Node): Boolean - -external fun isJSDocLinkPlain(node: Node): Boolean - -external fun isJSDocAllType(node: Node): Boolean - -external fun isJSDocUnknownType(node: Node): Boolean - -external fun isJSDocNullableType(node: Node): Boolean - -external fun isJSDocNonNullableType(node: Node): Boolean - -external fun isJSDocOptionalType(node: Node): Boolean - -external fun isJSDocFunctionType(node: Node): Boolean - -external fun isJSDocVariadicType(node: Node): Boolean - -external fun isJSDocNamepathType(node: Node): Boolean - -external fun isJSDoc(node: Node): Boolean - -external fun isJSDocTypeLiteral(node: Node): Boolean - -external fun isJSDocSignature(node: Node): Boolean - -external fun isJSDocAugmentsTag(node: Node): Boolean - -external fun isJSDocAuthorTag(node: Node): Boolean - -external fun isJSDocClassTag(node: Node): Boolean - -external fun isJSDocCallbackTag(node: Node): Boolean - -external fun isJSDocPublicTag(node: Node): Boolean - -external fun isJSDocPrivateTag(node: Node): Boolean - -external fun isJSDocProtectedTag(node: Node): Boolean - -external fun isJSDocReadonlyTag(node: Node): Boolean - -external fun isJSDocOverrideTag(node: Node): Boolean - -external fun isJSDocDeprecatedTag(node: Node): Boolean - -external fun isJSDocSeeTag(node: Node): Boolean - -external fun isJSDocEnumTag(node: Node): Boolean - -external fun isJSDocParameterTag(node: Node): Boolean - -external fun isJSDocReturnTag(node: Node): Boolean - -external fun isJSDocThisTag(node: Node): Boolean - -external fun isJSDocTypeTag(node: Node): Boolean - -external fun isJSDocTemplateTag(node: Node): Boolean - -external fun isJSDocTypedefTag(node: Node): Boolean - -external fun isJSDocUnknownTag(node: Node): Boolean - -external fun isJSDocPropertyTag(node: Node): Boolean - -external fun isJSDocImplementsTag(node: Node): Boolean - -external fun setTextRange(range: T, location: TextRange?): T - -external fun forEachChild(node: Node, cbNode: (node: Node) -> T?, cbNodes: (nodes: NodeArray) -> T? = definedExternally): T? - -external fun createSourceFile(fileName: String, sourceText: String, languageVersion: ScriptTarget, setParentNodes: Boolean = definedExternally, scriptKind: ScriptKind = definedExternally): SourceFile - -external fun parseIsolatedEntityName(text: String, languageVersion: ScriptTarget): dynamic /* Identifier? | QualifiedName? */ - -external fun parseJsonText(fileName: String, sourceText: String): JsonSourceFile - -external fun isExternalModule(file: SourceFile): Boolean - -external fun updateSourceFile(sourceFile: SourceFile, newText: String, textChangeRange: TextChangeRange, aggressiveChecks: Boolean = definedExternally): SourceFile - -external fun parseCommandLine(commandLine: Array, readFile: (path: String) -> String? = definedExternally): ParsedCommandLine - -external interface ConfigFileDiagnosticsReporter { - var onUnRecoverableConfigFileDiagnostic: DiagnosticReporter -} - -external interface ParseConfigFileHost : ParseConfigHost, ConfigFileDiagnosticsReporter { - fun getCurrentDirectory(): String -} - -external fun getParsedCommandLineOfConfigFile(configFileName: String, optionsToExtend: CompilerOptions?, host: ParseConfigFileHost, extendedConfigCache: Map = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): ParsedCommandLine? - -external interface `T$25` { - var config: Any? - get() = definedExternally - set(value) = definedExternally - var error: Diagnostic? - get() = definedExternally - set(value) = definedExternally -} - -external fun readConfigFile(fileName: String, readFile: (path: String) -> String?): `T$25` - -external fun parseConfigFileTextToJson(fileName: String, jsonText: String): `T$25` - -external fun readJsonConfigFile(fileName: String, readFile: (path: String) -> String?): TsConfigSourceFile - -external fun convertToObject(sourceFile: JsonSourceFile, errors: Push): Any - -external fun parseJsonConfigFileContent(json: Any, host: ParseConfigHost, basePath: String, existingOptions: CompilerOptions = definedExternally, configFileName: String = definedExternally, resolutionStack: Array = definedExternally, extraFileExtensions: Array = definedExternally, extendedConfigCache: Map = definedExternally, existingWatchOptions: WatchOptions = definedExternally): ParsedCommandLine - -external fun parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceFile, host: ParseConfigHost, basePath: String, existingOptions: CompilerOptions = definedExternally, configFileName: String = definedExternally, resolutionStack: Array = definedExternally, extraFileExtensions: Array = definedExternally, extendedConfigCache: Map = definedExternally, existingWatchOptions: WatchOptions = definedExternally): ParsedCommandLine - -external interface ParsedTsconfig { - var raw: Any - var options: CompilerOptions? - get() = definedExternally - set(value) = definedExternally - var watchOptions: WatchOptions? - get() = definedExternally - set(value) = definedExternally - var typeAcquisition: TypeAcquisition? - get() = definedExternally - set(value) = definedExternally - var extendedConfigPath: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface ExtendedConfigCacheEntry { - var extendedResult: TsConfigSourceFile - var extendedConfig: ParsedTsconfig? -} - -external interface `T$26` { - var options: CompilerOptions - var errors: Array -} - -external fun convertCompilerOptionsFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$26` - -external interface `T$27` { - var options: TypeAcquisition - var errors: Array -} - -external fun convertTypeAcquisitionFromJson(jsonOptions: Any, basePath: String, configFileName: String = definedExternally): `T$27` - -external fun getEffectiveTypeRoots(options: CompilerOptions, host: GetEffectiveTypeRootsHost): Array? - -external fun resolveTypeReferenceDirective(typeReferenceDirectiveName: String, containingFile: String?, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference: ResolvedProjectReference = definedExternally, cache: TypeReferenceDirectiveResolutionCache = definedExternally): ResolvedTypeReferenceDirectiveWithFailedLookupLocations - -external fun getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): Array - -external interface TypeReferenceDirectiveResolutionCache : PerDirectoryResolutionCache, PackageJsonInfoCache - -external interface PerDirectoryResolutionCache { - fun getOrCreateCacheForDirectory(directoryName: String, redirectedReference: ResolvedProjectReference = definedExternally): Map - fun clear() - fun update(options: CompilerOptions) -} - -external interface ModuleResolutionCache : PerDirectoryResolutionCache, NonRelativeModuleNameResolutionCache, PackageJsonInfoCache { - fun getPackageJsonInfoCache(): PackageJsonInfoCache -} - -external interface NonRelativeModuleNameResolutionCache : PackageJsonInfoCache { - fun getOrCreateCacheForModuleName(nonRelativeModuleName: String, redirectedReference: ResolvedProjectReference = definedExternally): PerModuleNameCache -} - -external interface PackageJsonInfoCache { - fun clear() -} - -external interface PerModuleNameCache { - fun get(directory: String): ResolvedModuleWithFailedLookupLocations? - fun set(directory: String, result: ResolvedModuleWithFailedLookupLocations) -} - -external fun createModuleResolutionCache(currentDirectory: String, getCanonicalFileName: (s: String) -> String, options: CompilerOptions = definedExternally): ModuleResolutionCache - -external fun createTypeReferenceDirectiveResolutionCache(currentDirectory: String, getCanonicalFileName: (s: String) -> String, options: CompilerOptions = definedExternally, packageJsonInfoCache: PackageJsonInfoCache = definedExternally): TypeReferenceDirectiveResolutionCache - -external fun resolveModuleNameFromCache(moduleName: String, containingFile: String, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations? - -external fun resolveModuleName(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations - -external fun nodeModuleNameResolver(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations - -external fun classicNameResolver(moduleName: String, containingFile: String, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: NonRelativeModuleNameResolutionCache = definedExternally, redirectedReference: ResolvedProjectReference = definedExternally): ResolvedModuleWithFailedLookupLocations - -external fun visitNode(node: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T - -external fun visitNode(node: T, visitor: Visitor?): T - -external fun visitNode(node: T, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T - -external fun visitNode(node: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, lift: (node: Array) -> T = definedExternally): T? - -external fun visitNode(node: T?, visitor: Visitor?): T? - -external fun visitNode(node: T?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): T? - -external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray - -external fun visitNodes(nodes: NodeArray, visitor: Visitor?): NodeArray - -external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray - -external fun visitNodes(nodes: NodeArray, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray - -external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally, count: Number = definedExternally): NodeArray? - -external fun visitNodes(nodes: NodeArray?, visitor: Visitor?): NodeArray? - -external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally): NodeArray? - -external fun visitNodes(nodes: NodeArray?, visitor: Visitor?, test: (node: Node) -> Boolean = definedExternally, start: Number = definedExternally): NodeArray? - -external fun visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start: Number = definedExternally, ensureUseStrict: Boolean = definedExternally, nodesVisitor: NodesVisitor = definedExternally): NodeArray - -external fun visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor = definedExternally): NodeArray - -external fun visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext): NodeArray - -external fun visitParameterList(nodes: NodeArray?, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor = definedExternally): NodeArray? - -external fun visitParameterList(nodes: NodeArray?, visitor: Visitor, context: TransformationContext): NodeArray? - -external fun visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): dynamic /* FunctionBody */ - -external fun visitFunctionBody(node: Expression, visitor: Visitor, context: TransformationContext): dynamic /* FunctionBody | Expression */ - -external fun visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement - -external fun visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T - -external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext, nodesVisitor: Any = definedExternally, tokenVisitor: Visitor = definedExternally): T? - -external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext): T? - -external fun visitEachChild(node: T?, visitor: Visitor, context: TransformationContext, nodesVisitor: Any = definedExternally): T? - -external fun getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): String? - -external fun getOutputFileNames(commandLine: ParsedCommandLine, inputFileName: String, ignoreCase: Boolean): Array - -external fun createPrinter(printerOptions: PrinterOptions = definedExternally, handlers: PrintHandlers = definedExternally): Printer - -external fun findConfigFile(searchPath: String, fileExists: (fileName: String) -> Boolean, configName: String = definedExternally): String? - -external fun resolveTripleslashReference(moduleName: String, containingFile: String): String - -external fun createCompilerHost(options: CompilerOptions, setParentNodes: Boolean = definedExternally): CompilerHost - -external fun getPreEmitDiagnostics(program: Program, sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - -external interface FormatDiagnosticsHost { - fun getCurrentDirectory(): String - fun getCanonicalFileName(fileName: String): String - fun getNewLine(): String -} - -external fun formatDiagnostics(diagnostics: Array, host: FormatDiagnosticsHost): String - -external fun formatDiagnostic(diagnostic: Diagnostic, host: FormatDiagnosticsHost): String - -external fun formatDiagnosticsWithColorAndContext(diagnostics: Array, host: FormatDiagnosticsHost): String - -external fun flattenDiagnosticMessageText(diag: String?, newLine: String, indent: Number = definedExternally): String - -external fun flattenDiagnosticMessageText(diag: String?, newLine: String): String - -external fun flattenDiagnosticMessageText(diag: DiagnosticMessageChain?, newLine: String, indent: Number = definedExternally): String - -external fun flattenDiagnosticMessageText(diag: DiagnosticMessageChain?, newLine: String): String - -external fun getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): Array - -external fun createProgram(createProgramOptions: CreateProgramOptions): Program - -external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally, oldProgram: Program = definedExternally, configFileParsingDiagnostics: Array = definedExternally): Program - -external fun createProgram(rootNames: Array, options: CompilerOptions): Program - -external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally): Program - -external fun createProgram(rootNames: Array, options: CompilerOptions, host: CompilerHost = definedExternally, oldProgram: Program = definedExternally): Program - -external interface ResolveProjectReferencePathHost { - fun fileExists(fileName: String): Boolean -} - -external fun resolveProjectReferencePath(ref: ProjectReference): String /* String & `T$5` */ - -external fun resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): String /* String & `T$5` */ - -external interface EmitOutput { - var outputFiles: Array - var emitSkipped: Boolean -} - -external interface OutputFile { - var name: String - var writeByteOrderMark: Boolean - var text: String -} - -external interface `T$28` { - var result: T - var affected: dynamic /* SourceFile | Program */ - get() = definedExternally - set(value) = definedExternally -} - -external interface BuilderProgramHost { - fun useCaseSensitiveFileNames(): Boolean - var createHash: ((data: String) -> String)? - get() = definedExternally - set(value) = definedExternally - var writeFile: WriteFileCallback? - get() = definedExternally - set(value) = definedExternally -} - -external interface BuilderProgram { - fun getProgram(): Program - fun getCompilerOptions(): CompilerOptions - fun getSourceFile(fileName: String): SourceFile? - fun getSourceFiles(): Array - fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getConfigFileParsingDiagnostics(): Array - fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getDeclarationDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getAllDependencies(sourceFile: SourceFile): Array - fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult - fun getCurrentDirectory(): String -} - -external interface SemanticDiagnosticsBuilderProgram : BuilderProgram { - fun getSemanticDiagnosticsOfNextAffectedFile(cancellationToken: CancellationToken = definedExternally, ignoreSourceFile: (sourceFile: SourceFile) -> Boolean = definedExternally): `T$28`>? -} - -external interface EmitAndSemanticDiagnosticsBuilderProgram : SemanticDiagnosticsBuilderProgram { - fun emitNextAffectedFile(writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): `T$28`? -} - -external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: SemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): SemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: EmitAndSemanticDiagnosticsBuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): EmitAndSemanticDiagnosticsBuilderProgram - -external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): BuilderProgram - -external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost): BuilderProgram - -external fun createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram: BuilderProgram = definedExternally): BuilderProgram - -external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally, projectReferences: Array = definedExternally): BuilderProgram - -external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?): BuilderProgram - -external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally): BuilderProgram - -external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally): BuilderProgram - -external fun createAbstractBuilder(rootNames: Array?, options: CompilerOptions?, host: CompilerHost = definedExternally, oldProgram: BuilderProgram = definedExternally, configFileParsingDiagnostics: Array = definedExternally): BuilderProgram - -external interface ReadBuildProgramHost { - fun useCaseSensitiveFileNames(): Boolean - fun getCurrentDirectory(): String - fun readFile(fileName: String): String? -} - -external fun readBuilderProgram(compilerOptions: CompilerOptions, host: ReadBuildProgramHost): EmitAndSemanticDiagnosticsBuilderProgram? - -external fun createIncrementalCompilerHost(options: CompilerOptions, system: System = definedExternally): CompilerHost - -external interface IncrementalProgramOptions { - var rootNames: Array - var options: CompilerOptions - var configFileParsingDiagnostics: Array? - get() = definedExternally - set(value) = definedExternally - var projectReferences: Array? - get() = definedExternally - set(value) = definedExternally - var host: CompilerHost? - get() = definedExternally - set(value) = definedExternally - var createProgram: CreateProgram? - get() = definedExternally - set(value) = definedExternally -} - -external fun createIncrementalProgram(__0: IncrementalProgramOptions): T - -external interface WatchHost { - val onWatchStatusChange: ((diagnostic: Diagnostic, newLine: String, options: CompilerOptions, errorCount: Number) -> Unit)? - fun watchFile(path: String, callback: FileWatcherCallback, pollingInterval: Number = definedExternally, options: CompilerOptions = definedExternally): FileWatcher - fun watchDirectory(path: String, callback: DirectoryWatcherCallback, recursive: Boolean = definedExternally, options: CompilerOptions = definedExternally): FileWatcher - val setTimeout: ((callback: (args: Any) -> Unit, ms: Number, args: Any) -> Any)? - val clearTimeout: ((timeoutId: Any) -> Unit)? -} - -external interface ProgramHost { - var createProgram: CreateProgram - fun useCaseSensitiveFileNames(): Boolean - fun getNewLine(): String - fun getCurrentDirectory(): String - fun getDefaultLibFileName(options: CompilerOptions): String - val getDefaultLibLocation: (() -> String)? - val createHash: ((data: String) -> String)? - fun fileExists(path: String): Boolean - fun readFile(path: String, encoding: String = definedExternally): String? - val directoryExists: ((path: String) -> Boolean)? - val getDirectories: ((path: String) -> Array)? - val readDirectory: ((path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array)? - val realpath: ((path: String) -> String)? - val trace: ((s: String) -> Unit)? - val getEnvironmentVariable: ((name: String) -> String?)? - val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? -} - -external interface WatchCompilerHost : ProgramHost, WatchHost { - val useSourceOfProjectReferenceRedirect: (() -> Boolean)? - val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? - val afterProgramCreate: ((program: T) -> Unit)? -} - -external interface WatchCompilerHostOfFilesAndCompilerOptions : WatchCompilerHost { - var rootFiles: Array - var options: CompilerOptions - var watchOptions: WatchOptions? - get() = definedExternally - set(value) = definedExternally - var projectReferences: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface WatchCompilerHostOfConfigFile : WatchCompilerHost, ConfigFileDiagnosticsReporter { - var configFileName: String - var optionsToExtend: CompilerOptions? - get() = definedExternally - set(value) = definedExternally - var watchOptionsToExtend: WatchOptions? - get() = definedExternally - set(value) = definedExternally - var extraFileExtensions: Array? - get() = definedExternally - set(value) = definedExternally - override var readDirectory: (path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array -} - -external interface Watch { - fun getProgram(): T - fun close() -} - -external interface WatchOfConfigFile : Watch - -external interface WatchOfFilesAndCompilerOptions : Watch { - fun updateRootFileNames(fileNames: Array) -} - -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally, extraFileExtensions: Array = definedExternally): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(configFileName: String, optionsToExtend: CompilerOptions?, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, watchOptionsToExtend: WatchOptions = definedExternally): WatchCompilerHostOfConfigFile - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, projectReferences: Array = definedExternally, watchOptions: WatchOptions = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchCompilerHost(rootFiles: Array, options: CompilerOptions, system: System, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally, projectReferences: Array = definedExternally): WatchCompilerHostOfFilesAndCompilerOptions - -external fun createWatchProgram(host: WatchCompilerHostOfFilesAndCompilerOptions): WatchOfFilesAndCompilerOptions - -external fun createWatchProgram(host: WatchCompilerHostOfConfigFile): WatchOfConfigFile - -external interface BuildOptions { - var dry: Boolean? - get() = definedExternally - set(value) = definedExternally - var force: Boolean? - get() = definedExternally - set(value) = definedExternally - var verbose: Boolean? - get() = definedExternally - set(value) = definedExternally - var incremental: Boolean? - get() = definedExternally - set(value) = definedExternally - var assumeChangesOnlyAffectDirectDependencies: Boolean? - get() = definedExternally - set(value) = definedExternally - var traceResolution: Boolean? - get() = definedExternally - set(value) = definedExternally - @nativeGetter - operator fun get(option: String): dynamic /* String? | Number? | Boolean? | Array? | Array? | MapLike>? | Array? | Array? */ - @nativeSetter - operator fun set(option: String, value: String?) - @nativeSetter - operator fun set(option: String, value: Number?) - @nativeSetter - operator fun set(option: String, value: Boolean?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: MapLike>?) - @nativeSetter - operator fun set(option: String, value: Array?) - @nativeSetter - operator fun set(option: String, value: Array?) -} - -external interface SolutionBuilderHostBase : ProgramHost { - val createDirectory: ((path: String) -> Unit)? - val writeFile: ((path: String, data: String, writeByteOrderMark: Boolean) -> Unit)? - var getCustomTransformers: ((project: String) -> CustomTransformers?)? - get() = definedExternally - set(value) = definedExternally - fun getModifiedTime(fileName: String): Date? - fun setModifiedTime(fileName: String, date: Date) - fun deleteFile(fileName: String) - val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? - var reportDiagnostic: DiagnosticReporter - var reportSolutionBuilderStatus: DiagnosticReporter - val afterProgramEmitAndDiagnostics: ((program: T) -> Unit)? -} - -external interface SolutionBuilderHost : SolutionBuilderHostBase { - var reportErrorSummary: ReportEmitErrorSummary? - get() = definedExternally - set(value) = definedExternally -} - -external interface SolutionBuilderWithWatchHost : SolutionBuilderHostBase, WatchHost - -external interface SolutionBuilder { - fun build(project: String = definedExternally, cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, getCustomTransformers: (project: String) -> CustomTransformers = definedExternally): ExitStatus - fun clean(project: String = definedExternally): ExitStatus - fun buildReferences(project: String, cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, getCustomTransformers: (project: String) -> CustomTransformers = definedExternally): ExitStatus - fun cleanReferences(project: String = definedExternally): ExitStatus - fun getNextInvalidatedProject(cancellationToken: CancellationToken = definedExternally): dynamic /* UpdateOutputFileStampsProject? | BuildInvalidedProject? | UpdateBundleProject? */ -} - -external fun createBuilderStatusReporter(system: System, pretty: Boolean = definedExternally): DiagnosticReporter - -external fun createSolutionBuilderHost(system: System = definedExternally, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportSolutionBuilderStatus: DiagnosticReporter = definedExternally, reportErrorSummary: ReportEmitErrorSummary = definedExternally): SolutionBuilderHost - -external fun createSolutionBuilderWithWatchHost(system: System = definedExternally, createProgram: CreateProgram = definedExternally, reportDiagnostic: DiagnosticReporter = definedExternally, reportSolutionBuilderStatus: DiagnosticReporter = definedExternally, reportWatchStatus: WatchStatusReporter = definedExternally): SolutionBuilderWithWatchHost - -external fun createSolutionBuilder(host: SolutionBuilderHost, rootNames: Array, defaultOptions: BuildOptions): SolutionBuilder - -external fun createSolutionBuilderWithWatch(host: SolutionBuilderWithWatchHost, rootNames: Array, defaultOptions: BuildOptions, baseWatchOptions: WatchOptions = definedExternally): SolutionBuilder - -external enum class InvalidatedProjectKind { - Build /* = 0 */, - UpdateBundle /* = 1 */, - UpdateOutputFileStamps /* = 2 */ -} - -external interface InvalidatedProjectBase { - var kind: InvalidatedProjectKind - var project: String /* String & `T$5` */ - fun done(cancellationToken: CancellationToken = definedExternally, writeFile: WriteFileCallback = definedExternally, customTransformers: CustomTransformers = definedExternally): ExitStatus - fun getCompilerOptions(): CompilerOptions - fun getCurrentDirectory(): String -} - -external interface UpdateOutputFileStampsProject : InvalidatedProjectBase { - fun updateOutputFileStatmps() -} - -external interface BuildInvalidedProject : InvalidatedProjectBase { - fun getBuilderProgram(): T? - fun getProgram(): Program? - fun getSourceFile(fileName: String): SourceFile? - fun getSourceFiles(): Array - fun getOptionsDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getGlobalDiagnostics(cancellationToken: CancellationToken = definedExternally): Array - fun getConfigFileParsingDiagnostics(): Array - fun getSyntacticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getAllDependencies(sourceFile: SourceFile): Array - fun getSemanticDiagnostics(sourceFile: SourceFile = definedExternally, cancellationToken: CancellationToken = definedExternally): Array - fun getSemanticDiagnosticsOfNextAffectedFile(cancellationToken: CancellationToken = definedExternally, ignoreSourceFile: (sourceFile: SourceFile) -> Boolean = definedExternally): `T$28`>? - fun emit(targetSourceFile: SourceFile = definedExternally, writeFile: WriteFileCallback = definedExternally, cancellationToken: CancellationToken = definedExternally, emitOnlyDtsFiles: Boolean = definedExternally, customTransformers: CustomTransformers = definedExternally): EmitResult? -} - -external interface UpdateBundleProject : InvalidatedProjectBase { - fun emit(writeFile: WriteFileCallback = definedExternally, customTransformers: CustomTransformers = definedExternally): dynamic /* EmitResult? | BuildInvalidedProject? */ -} - -external interface SourceFileLike { - fun getLineAndCharacterOfPosition(pos: Number): LineAndCharacter -} - -external interface IScriptSnapshot { - fun getText(start: Number, end: Number): String - fun getLength(): Number - fun getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange? - val dispose: (() -> Unit)? -} - -external interface PreProcessedFileInfo { - var referencedFiles: Array - var typeReferenceDirectives: Array - var libReferenceDirectives: Array - var importedFiles: Array - var ambientExternalModules: Array? - get() = definedExternally - set(value) = definedExternally - var isLibFile: Boolean -} - -external interface HostCancellationToken { - fun isCancellationRequested(): Boolean -} - -external interface InstallPackageOptions { - var fileName: String /* String & `T$3` */ - var packageName: String -} - -external interface PerformanceEvent { - var kind: String /* "UpdateGraph" | "CreatePackageJsonAutoImportProvider" */ - var durationMs: Number -} - -external enum class LanguageServiceMode { - Semantic /* = 0 */, - PartialSemantic /* = 1 */, - Syntactic /* = 2 */ -} - -external interface IncompleteCompletionsCache { - fun get(): CompletionInfo? - fun set(response: CompletionInfo) - fun clear() -} - -external interface LanguageServiceHost : GetEffectiveTypeRootsHost { - fun getCompilationSettings(): CompilerOptions - val getNewLine: (() -> String)? - val getProjectVersion: (() -> String)? - fun getScriptFileNames(): Array - val getScriptKind: ((fileName: String) -> ScriptKind)? - fun getScriptVersion(fileName: String): String - fun getScriptSnapshot(fileName: String): IScriptSnapshot? - val getProjectReferences: (() -> Array?)? - val getLocalizedDiagnosticMessages: (() -> Any)? - val getCancellationToken: (() -> HostCancellationToken)? - override var getCurrentDirectory: () -> String - fun getDefaultLibFileName(options: CompilerOptions): String - val log: ((s: String) -> Unit)? - val trace: ((s: String) -> Unit)? - val error: ((s: String) -> Unit)? - val useCaseSensitiveFileNames: (() -> Boolean)? - val readDirectory: ((path: String, extensions: Array, exclude: Array, include: Array, depth: Number) -> Array)? - val readFile: ((path: String, encoding: String) -> String?)? - val realpath: ((path: String) -> String)? - val fileExists: ((path: String) -> Boolean)? - val getTypeRootsVersion: (() -> Number)? - val resolveModuleNames: ((moduleNames: Array, containingFile: String, reusedNames: Array?, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val getResolvedModuleWithFailedLookupLocationsFromCache: ((modulename: String, containingFile: String) -> ResolvedModuleWithFailedLookupLocations?)? - val resolveTypeReferenceDirectives: ((typeDirectiveNames: Array, containingFile: String, redirectedReference: ResolvedProjectReference?, options: CompilerOptions) -> Array)? - val getDirectories: ((directoryName: String) -> Array)? - val getCustomTransformers: (() -> CustomTransformers?)? - val isKnownTypesPackageName: ((name: String) -> Boolean)? - val installPackage: ((options: InstallPackageOptions) -> Promise)? - val writeFile: ((fileName: String, content: String) -> Unit)? - val getParsedCommandLine: ((fileName: String) -> ParsedCommandLine?)? -} - -external enum class SemanticClassificationFormat { - Original /* = "original" */, - TwentyTwenty /* = "2020" */ -} - -external interface LanguageService { - fun cleanupSemanticCache() - fun getSyntacticDiagnostics(fileName: String): Array - fun getSemanticDiagnostics(fileName: String): Array - fun getSuggestionDiagnostics(fileName: String): Array - fun getCompilerOptionsDiagnostics(): Array - fun getSyntacticClassifications(fileName: String, span: TextSpan): Array - fun getSyntacticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ - fun getSemanticClassifications(fileName: String, span: TextSpan): Array - fun getSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat): dynamic /* Array | Array */ - fun getEncodedSyntacticClassifications(fileName: String, span: TextSpan): Classifications - fun getEncodedSemanticClassifications(fileName: String, span: TextSpan, format: SemanticClassificationFormat = definedExternally): Classifications - fun getCompletionsAtPosition(fileName: String, position: Number, options: GetCompletionsAtPositionOptions?): CompletionInfo /* CompletionInfo & `T$12` */ - fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeOptions?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? - fun getCompletionEntryDetails(fileName: String, position: Number, entryName: String, formatOptions: FormatCodeSettings?, source: String?, preferences: UserPreferences?, data: CompletionEntryData?): CompletionEntryDetails? - fun getCompletionEntrySymbol(fileName: String, position: Number, name: String, source: String?): Symbol? - fun getQuickInfoAtPosition(fileName: String, position: Number): QuickInfo? - fun getNameOrDottedNameSpan(fileName: String, startPos: Number, endPos: Number): TextSpan? - fun getBreakpointStatementAtPosition(fileName: String, position: Number): TextSpan? - fun getSignatureHelpItems(fileName: String, position: Number, options: SignatureHelpItemsOptions?): SignatureHelpItems? - fun getRenameInfo(fileName: String, position: Number, options: RenameInfoOptions = definedExternally): dynamic /* RenameInfoSuccess | RenameInfoFailure */ - fun findRenameLocations(fileName: String, position: Number, findInStrings: Boolean, findInComments: Boolean, providePrefixAndSuffixTextForRename: Boolean = definedExternally): Array? - fun getSmartSelectionRange(fileName: String, position: Number): SelectionRange - fun getDefinitionAtPosition(fileName: String, position: Number): Array? - fun getDefinitionAndBoundSpan(fileName: String, position: Number): DefinitionInfoAndBoundSpan? - fun getTypeDefinitionAtPosition(fileName: String, position: Number): Array? - fun getImplementationAtPosition(fileName: String, position: Number): Array? - fun getReferencesAtPosition(fileName: String, position: Number): Array? - fun findReferences(fileName: String, position: Number): Array? - fun getDocumentHighlights(fileName: String, position: Number, filesToSearch: Array): Array? - fun getFileReferences(fileName: String): Array - fun getOccurrencesAtPosition(fileName: String, position: Number): Array? - fun getNavigateToItems(searchValue: String, maxResultCount: Number = definedExternally, fileName: String = definedExternally, excludeDtsFiles: Boolean = definedExternally): Array - fun getNavigationBarItems(fileName: String): Array - fun getNavigationTree(fileName: String): NavigationTree - fun prepareCallHierarchy(fileName: String, position: Number): dynamic /* CallHierarchyItem? | Array? */ - fun provideCallHierarchyIncomingCalls(fileName: String, position: Number): Array - fun provideCallHierarchyOutgoingCalls(fileName: String, position: Number): Array - fun provideInlayHints(fileName: String, span: TextSpan, preferences: UserPreferences?): Array - fun getOutliningSpans(fileName: String): Array - fun getTodoComments(fileName: String, descriptors: Array): Array - fun getBraceMatchingAtPosition(fileName: String, position: Number): Array - fun getIndentationAtPosition(fileName: String, position: Number, options: EditorOptions): Number - fun getIndentationAtPosition(fileName: String, position: Number, options: EditorSettings): Number - fun getFormattingEditsForRange(fileName: String, start: Number, end: Number, options: FormatCodeOptions): Array - fun getFormattingEditsForRange(fileName: String, start: Number, end: Number, options: FormatCodeSettings): Array - fun getFormattingEditsForDocument(fileName: String, options: FormatCodeOptions): Array - fun getFormattingEditsForDocument(fileName: String, options: FormatCodeSettings): Array - fun getFormattingEditsAfterKeystroke(fileName: String, position: Number, key: String, options: FormatCodeOptions): Array - fun getFormattingEditsAfterKeystroke(fileName: String, position: Number, key: String, options: FormatCodeSettings): Array - fun getDocCommentTemplateAtPosition(fileName: String, position: Number, options: DocCommentTemplateOptions = definedExternally): TextInsertion? - fun isValidBraceCompletionAtPosition(fileName: String, position: Number, openingBrace: Number): Boolean - fun getJsxClosingTagAtPosition(fileName: String, position: Number): JsxClosingTagInfo? - fun getSpanOfEnclosingComment(fileName: String, position: Number, onlyMultiLine: Boolean): TextSpan? - val toLineColumnOffset: ((fileName: String, position: Number) -> LineAndCharacter)? - fun getCodeFixesAtPosition(fileName: String, start: Number, end: Number, errorCodes: Array, formatOptions: FormatCodeSettings, preferences: UserPreferences): Array - fun getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: Any, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions - fun applyCodeActionCommand(action: CodeActionCommand, formatSettings: FormatCodeSettings = definedExternally): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(action: CodeActionCommand): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(action: Array, formatSettings: FormatCodeSettings = definedExternally): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(action: Array): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(fileName: String, action: CodeActionCommand): dynamic /* Promise | Promise */ - fun applyCodeActionCommand(fileName: String, action: Array): dynamic /* Promise | Promise */ - fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally, kind: String = definedExternally): Array - fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?): Array - fun getApplicableRefactors(fileName: String, positionOrRange: Number, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally): Array - fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally, kind: String = definedExternally): Array - fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?): Array - fun getApplicableRefactors(fileName: String, positionOrRange: TextRange, preferences: UserPreferences?, triggerReason: String /* "implicit" | "invoked" */ = definedExternally): Array - fun getEditsForRefactor(fileName: String, formatOptions: FormatCodeSettings, positionOrRange: Number, refactorName: String, actionName: String, preferences: UserPreferences?): RefactorEditInfo? - fun getEditsForRefactor(fileName: String, formatOptions: FormatCodeSettings, positionOrRange: TextRange, refactorName: String, actionName: String, preferences: UserPreferences?): RefactorEditInfo? - fun organizeImports(args: OrganizeImportsArgs, formatOptions: FormatCodeSettings, preferences: UserPreferences?): Array - fun getEditsForFileRename(oldFilePath: String, newFilePath: String, formatOptions: FormatCodeSettings, preferences: UserPreferences?): Array - fun getEmitOutput(fileName: String, emitOnlyDtsFiles: Boolean = definedExternally, forceDtsEmit: Boolean = definedExternally): EmitOutput - fun getProgram(): Program? - fun toggleLineComment(fileName: String, textRange: TextRange): Array - fun toggleMultilineComment(fileName: String, textRange: TextRange): Array - fun commentSelection(fileName: String, textRange: TextRange): Array - fun uncommentSelection(fileName: String, textRange: TextRange): Array - fun dispose() -} - -external interface JsxClosingTagInfo { - var newText: String -} - -external interface CombinedCodeFixScope { - var type: String /* "file" */ - var fileName: String -} - -external interface OrganizeImportsArgs : CombinedCodeFixScope { - var skipDestructiveCodeActions: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external enum class CompletionTriggerKind { - Invoked /* = 1 */, - TriggerCharacter /* = 2 */, - TriggerForIncompleteCompletions /* = 3 */ -} - -external interface GetCompletionsAtPositionOptions : UserPreferences { - var triggerCharacter: String? /* "." | """ | "'" | "`" | "/" | "@" | "<" | "#" | " " */ - get() = definedExternally - set(value) = definedExternally - var triggerKind: CompletionTriggerKind? - get() = definedExternally - set(value) = definedExternally - var includeExternalModuleExports: Boolean? - get() = definedExternally - set(value) = definedExternally - var includeInsertTextCompletions: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface InlayHintsOptions : UserPreferences { - var includeInlayParameterNameHints: String? /* "none" | "literals" | "all" */ - get() = definedExternally - set(value) = definedExternally - var includeInlayParameterNameHintsWhenArgumentMatchesName: Boolean? - get() = definedExternally - set(value) = definedExternally - var includeInlayFunctionParameterTypeHints: Boolean? - get() = definedExternally - set(value) = definedExternally - var includeInlayVariableTypeHints: Boolean? - get() = definedExternally - set(value) = definedExternally - var includeInlayPropertyDeclarationTypeHints: Boolean? - get() = definedExternally - set(value) = definedExternally - var includeInlayFunctionLikeReturnTypeHints: Boolean? - get() = definedExternally - set(value) = definedExternally - var includeInlayEnumMemberValueHints: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureHelpItemsOptions { - var triggerReason: dynamic /* SignatureHelpInvokedReason? | SignatureHelpCharacterTypedReason? | SignatureHelpRetriggeredReason? */ - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureHelpInvokedReason { - var kind: String /* "invoked" */ - var triggerCharacter: Any? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureHelpCharacterTypedReason { - var kind: String /* "characterTyped" */ - var triggerCharacter: String /* "," | "(" | "<" */ -} - -external interface SignatureHelpRetriggeredReason { - var kind: String /* "retrigger" */ - var triggerCharacter: String? /* "," | "(" | "<" | ")" */ - get() = definedExternally - set(value) = definedExternally -} - -external interface ApplyCodeActionCommandResult { - var successMessage: String -} - -external interface Classifications { - var spans: Array - var endOfLineState: EndOfLineState -} - -external interface ClassifiedSpan { - var textSpan: TextSpan - var classificationType: ClassificationTypeNames -} - -external interface ClassifiedSpan2020 { - var textSpan: TextSpan - var classificationType: Number -} - -external interface NavigationBarItem { - var text: String - var kind: ScriptElementKind - var kindModifiers: String - var spans: Array - var childItems: Array - var indent: Number - var bolded: Boolean - var grayed: Boolean -} - -external interface NavigationTree { - var text: String - var kind: ScriptElementKind - var kindModifiers: String - var spans: Array - var nameSpan: TextSpan? - var childItems: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface CallHierarchyItem { - var name: String - var kind: ScriptElementKind - var kindModifiers: String? - get() = definedExternally - set(value) = definedExternally - var file: String - var span: TextSpan - var selectionSpan: TextSpan - var containerName: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface CallHierarchyIncomingCall { - var from: CallHierarchyItem - var fromSpans: Array -} - -external interface CallHierarchyOutgoingCall { - var to: CallHierarchyItem - var fromSpans: Array -} - -external enum class InlayHintKind { - Type /* = "Type" */, - Parameter /* = "Parameter" */, - Enum /* = "Enum" */ -} - -external interface InlayHint { - var text: String - var position: Number - var kind: InlayHintKind - var whitespaceBefore: Boolean? - get() = definedExternally - set(value) = definedExternally - var whitespaceAfter: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface TodoCommentDescriptor { - var text: String - var priority: Number -} - -external interface TodoComment { - var descriptor: TodoCommentDescriptor - var message: String - var position: Number -} - -external interface TextChange { - var span: TextSpan - var newText: String -} - -external interface FileTextChanges { - var fileName: String - var textChanges: Array - var isNewFile: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface CodeAction { - var description: String - var changes: Array - var commands: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface CodeFixAction : CodeAction { - var fixName: String - var fixId: Any? - get() = definedExternally - set(value) = definedExternally - var fixAllDescription: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface CombinedCodeActions { - var changes: Array - var commands: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface InstallPackageAction - -external interface ApplicableRefactorInfo { - var name: String - var description: String - var inlineable: Boolean? - get() = definedExternally - set(value) = definedExternally - var actions: Array -} - -external interface RefactorActionInfo { - var name: String - var description: String - var notApplicableReason: String? - get() = definedExternally - set(value) = definedExternally - var kind: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface RefactorEditInfo { - var edits: Array - var renameFilename: String? - get() = definedExternally - set(value) = definedExternally - var renameLocation: Number? - get() = definedExternally - set(value) = definedExternally - var commands: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface TextInsertion { - var newText: String - var caretOffset: Number -} - -external interface DocumentSpan { - var textSpan: TextSpan - var fileName: String - var originalTextSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var originalFileName: String? - get() = definedExternally - set(value) = definedExternally - var contextSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var originalContextSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally -} - -external interface RenameLocation : DocumentSpan { - var prefixText: String? - get() = definedExternally - set(value) = definedExternally - var suffixText: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface ReferenceEntry : DocumentSpan { - var isWriteAccess: Boolean - var isDefinition: Boolean - var isInString: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface ImplementationLocation : DocumentSpan { - var kind: ScriptElementKind - var displayParts: Array -} - -external enum class HighlightSpanKind { - none /* = "none" */, - definition /* = "definition" */, - reference /* = "reference" */, - writtenReference /* = "writtenReference" */ -} - -external interface HighlightSpan { - var fileName: String? - get() = definedExternally - set(value) = definedExternally - var isInString: Boolean? - get() = definedExternally - set(value) = definedExternally - var textSpan: TextSpan - var contextSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var kind: HighlightSpanKind -} - -external interface NavigateToItem { - var name: String - var kind: ScriptElementKind - var kindModifiers: String - var matchKind: String /* "exact" | "prefix" | "substring" | "camelCase" */ - var isCaseSensitive: Boolean - var fileName: String - var textSpan: TextSpan - var containerName: String - var containerKind: ScriptElementKind -} - -external enum class IndentStyle { - None /* = 0 */, - Block /* = 1 */, - Smart /* = 2 */ -} - -external enum class SemicolonPreference { - Ignore /* = "ignore" */, - Insert /* = "insert" */, - Remove /* = "remove" */ -} - -external interface EditorOptions { - var BaseIndentSize: Number? - get() = definedExternally - set(value) = definedExternally - var IndentSize: Number - var TabSize: Number - var NewLineCharacter: String - var ConvertTabsToSpaces: Boolean - var IndentStyle: IndentStyle -} - -external interface EditorSettings { - var baseIndentSize: Number? - get() = definedExternally - set(value) = definedExternally - var indentSize: Number? - get() = definedExternally - set(value) = definedExternally - var tabSize: Number? - get() = definedExternally - set(value) = definedExternally - var newLineCharacter: String? - get() = definedExternally - set(value) = definedExternally - var convertTabsToSpaces: Boolean? - get() = definedExternally - set(value) = definedExternally - var indentStyle: IndentStyle? - get() = definedExternally - set(value) = definedExternally - var trimTrailingWhitespace: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface FormatCodeOptions : EditorOptions { - var InsertSpaceAfterCommaDelimiter: Boolean - var InsertSpaceAfterSemicolonInForStatements: Boolean - var InsertSpaceBeforeAndAfterBinaryOperators: Boolean - var InsertSpaceAfterConstructor: Boolean? - get() = definedExternally - set(value) = definedExternally - var InsertSpaceAfterKeywordsInControlFlowStatements: Boolean - var InsertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean - var InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean - var InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean - var InsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: Boolean? - get() = definedExternally - set(value) = definedExternally - var InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean - var InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: Boolean? - get() = definedExternally - set(value) = definedExternally - var InsertSpaceAfterTypeAssertion: Boolean? - get() = definedExternally - set(value) = definedExternally - var InsertSpaceBeforeFunctionParenthesis: Boolean? - get() = definedExternally - set(value) = definedExternally - var PlaceOpenBraceOnNewLineForFunctions: Boolean - var PlaceOpenBraceOnNewLineForControlBlocks: Boolean - var insertSpaceBeforeTypeAnnotation: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface FormatCodeSettings : EditorSettings { - var insertSpaceAfterCommaDelimiter: Boolean? - get() = definedExternally - set(value) = definedExternally - var insertSpaceAfterSemicolonInForStatements: Boolean? - get() = definedExternally - set(value) = definedExternally - var insertSpaceBeforeAndAfterBinaryOperators: Boolean? - get() = definedExternally - set(value) = definedExternally - var insertSpaceAfterConstructor: Boolean? - get() = definedExternally - set(value) = definedExternally - var insertSpaceAfterKeywordsInControlFlowStatements: Boolean? - get() = definedExternally - set(value) = definedExternally - var insertSpaceAfterFunctionKeywordForAnonymousFunctions: Boolean? - get() = definedExternally - set(value) = definedExternally - var insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: Boolean? - get() = definedExternally - set(value) = definedExternally - var insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: Boolean? - get() = definedExternally - set(value) = definedExternally - var insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: Boolean? - get() = definedExternally - set(value) = definedExternally - var insertSpaceAfterOpeningAndBeforeClosingEmptyBraces: Boolean? - get() = definedExternally - set(value) = definedExternally - var insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: Boolean? - get() = definedExternally - set(value) = definedExternally - var insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: Boolean? - get() = definedExternally - set(value) = definedExternally - var insertSpaceAfterTypeAssertion: Boolean? - get() = definedExternally - set(value) = definedExternally - var insertSpaceBeforeFunctionParenthesis: Boolean? - get() = definedExternally - set(value) = definedExternally - var placeOpenBraceOnNewLineForFunctions: Boolean? - get() = definedExternally - set(value) = definedExternally - var placeOpenBraceOnNewLineForControlBlocks: Boolean? - get() = definedExternally - set(value) = definedExternally - var insertSpaceBeforeTypeAnnotation: Boolean? - get() = definedExternally - set(value) = definedExternally - var indentMultiLineObjectLiteralBeginningOnBlankLine: Boolean? - get() = definedExternally - set(value) = definedExternally - var semicolons: SemicolonPreference? - get() = definedExternally - set(value) = definedExternally -} - -external fun getDefaultFormatCodeSettings(newLineCharacter: String = definedExternally): FormatCodeSettings - -external interface DefinitionInfo : DocumentSpan { - var kind: ScriptElementKind - var name: String - var containerKind: ScriptElementKind - var containerName: String - var unverified: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface DefinitionInfoAndBoundSpan { - var definitions: Array? - get() = definedExternally - set(value) = definedExternally - var textSpan: TextSpan -} - -external interface ReferencedSymbolDefinitionInfo : DefinitionInfo { - var displayParts: Array -} - -external interface ReferencedSymbol { - var definition: ReferencedSymbolDefinitionInfo - var references: Array -} - -external enum class SymbolDisplayPartKind { - aliasName /* = 0 */, - className /* = 1 */, - enumName /* = 2 */, - fieldName /* = 3 */, - interfaceName /* = 4 */, - keyword /* = 5 */, - lineBreak /* = 6 */, - numericLiteral /* = 7 */, - stringLiteral /* = 8 */, - localName /* = 9 */, - methodName /* = 10 */, - moduleName /* = 11 */, - operator /* = 12 */, - parameterName /* = 13 */, - propertyName /* = 14 */, - punctuation /* = 15 */, - space /* = 16 */, - text /* = 17 */, - typeParameterName /* = 18 */, - enumMemberName /* = 19 */, - functionName /* = 20 */, - regularExpressionLiteral /* = 21 */, - link /* = 22 */, - linkName /* = 23 */, - linkText /* = 24 */ -} - -external interface SymbolDisplayPart { - var text: String - var kind: String -} - -external interface JSDocLinkDisplayPart : SymbolDisplayPart { - var target: DocumentSpan -} - -external interface JSDocTagInfo { - var name: String - var text: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface QuickInfo { - var kind: ScriptElementKind - var kindModifiers: String - var textSpan: TextSpan - var displayParts: Array? - get() = definedExternally - set(value) = definedExternally - var documentation: Array? - get() = definedExternally - set(value) = definedExternally - var tags: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface RenameInfoSuccess { - var canRename: Boolean - var fileToRename: String? - get() = definedExternally - set(value) = definedExternally - var displayName: String - var fullDisplayName: String - var kind: ScriptElementKind - var kindModifiers: String - var triggerSpan: TextSpan -} - -external interface RenameInfoFailure { - var canRename: Boolean - var localizedErrorMessage: String -} - -external interface RenameInfoOptions { - var allowRenameOfImportPath: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface DocCommentTemplateOptions { - var generateReturnInDocTemplate: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureHelpParameter { - var name: String - var documentation: Array - var displayParts: Array - var isOptional: Boolean - var isRest: Boolean? - get() = definedExternally - set(value) = definedExternally -} - -external interface SelectionRange { - var textSpan: TextSpan - var parent: SelectionRange? - get() = definedExternally - set(value) = definedExternally -} - -external interface SignatureHelpItem { - var isVariadic: Boolean - var prefixDisplayParts: Array - var suffixDisplayParts: Array - var separatorDisplayParts: Array - var parameters: Array - var documentation: Array - var tags: Array -} - -external interface SignatureHelpItems { - var items: Array - var applicableSpan: TextSpan - var selectedItemIndex: Number - var argumentIndex: Number - var argumentCount: Number -} - -external interface CompletionInfo { - var isGlobalCompletion: Boolean - var isMemberCompletion: Boolean - var optionalReplacementSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var isNewIdentifierLocation: Boolean - var isIncomplete: Boolean? - get() = definedExternally - set(value) = definedExternally - var entries: Array -} - -external interface CompletionEntryData { - var fileName: String? - get() = definedExternally - set(value) = definedExternally - var ambientModuleName: String? - get() = definedExternally - set(value) = definedExternally - var isPackageJsonImport: Boolean? - get() = definedExternally - set(value) = definedExternally - var exportName: String - var moduleSpecifier: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface CompletionEntry { - var name: String - var kind: ScriptElementKind - var kindModifiers: String? - get() = definedExternally - set(value) = definedExternally - var sortText: String - var insertText: String? - get() = definedExternally - set(value) = definedExternally - var isSnippet: Boolean? - get() = definedExternally - set(value) = definedExternally - var replacementSpan: TextSpan? - get() = definedExternally - set(value) = definedExternally - var hasAction: Boolean? - get() = definedExternally - set(value) = definedExternally - var source: String? - get() = definedExternally - set(value) = definedExternally - var sourceDisplay: Array? - get() = definedExternally - set(value) = definedExternally - var isRecommended: Boolean? - get() = definedExternally - set(value) = definedExternally - var isFromUncheckedFile: Boolean? - get() = definedExternally - set(value) = definedExternally - var isPackageJsonImport: Boolean? - get() = definedExternally - set(value) = definedExternally - var isImportStatementCompletion: Boolean? - get() = definedExternally - set(value) = definedExternally - var data: CompletionEntryData? - get() = definedExternally - set(value) = definedExternally -} - -external interface CompletionEntryDetails { - var name: String - var kind: ScriptElementKind - var kindModifiers: String - var displayParts: Array - var documentation: Array? - get() = definedExternally - set(value) = definedExternally - var tags: Array? - get() = definedExternally - set(value) = definedExternally - var codeActions: Array? - get() = definedExternally - set(value) = definedExternally - var source: Array? - get() = definedExternally - set(value) = definedExternally - var sourceDisplay: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface OutliningSpan { - var textSpan: TextSpan - var hintSpan: TextSpan - var bannerText: String - var autoCollapse: Boolean - var kind: OutliningSpanKind -} - -external enum class OutliningSpanKind { - Comment /* = "comment" */, - Region /* = "region" */, - Code /* = "code" */, - Imports /* = "imports" */ -} - -external enum class OutputFileType { - JavaScript /* = 0 */, - SourceMap /* = 1 */, - Declaration /* = 2 */ -} - -external enum class EndOfLineState { - None /* = 0 */, - InMultiLineCommentTrivia /* = 1 */, - InSingleQuoteStringLiteral /* = 2 */, - InDoubleQuoteStringLiteral /* = 3 */, - InTemplateHeadOrNoSubstitutionTemplate /* = 4 */, - InTemplateMiddleOrTail /* = 5 */, - InTemplateSubstitutionPosition /* = 6 */ -} - -external enum class TokenClass { - Punctuation /* = 0 */, - Keyword /* = 1 */, - Operator /* = 2 */, - Comment /* = 3 */, - Whitespace /* = 4 */, - Identifier /* = 5 */, - NumberLiteral /* = 6 */, - BigIntLiteral /* = 7 */, - StringLiteral /* = 8 */, - RegExpLiteral /* = 9 */ -} - -external interface ClassificationResult { - var finalLexState: EndOfLineState - var entries: Array -} - -external interface ClassificationInfo { - var length: Number - var classification: TokenClass -} - -external interface Classifier { - fun getClassificationsForLine(text: String, lexState: EndOfLineState, syntacticClassifierAbsent: Boolean): ClassificationResult - fun getEncodedLexicalClassifications(text: String, endOfLineState: EndOfLineState, syntacticClassifierAbsent: Boolean): Classifications -} - -external enum class ScriptElementKind { - unknown /* = "" */, - warning /* = "warning" */, - keyword /* = "keyword" */, - scriptElement /* = "script" */, - moduleElement /* = "module" */, - classElement /* = "class" */, - localClassElement /* = "local class" */, - interfaceElement /* = "interface" */, - typeElement /* = "type" */, - enumElement /* = "enum" */, - enumMemberElement /* = "enum member" */, - variableElement /* = "var" */, - localVariableElement /* = "local var" */, - functionElement /* = "function" */, - localFunctionElement /* = "local function" */, - memberFunctionElement /* = "method" */, - memberGetAccessorElement /* = "getter" */, - memberSetAccessorElement /* = "setter" */, - memberVariableElement /* = "property" */, - constructorImplementationElement /* = "constructor" */, - callSignatureElement /* = "call" */, - indexSignatureElement /* = "index" */, - constructSignatureElement /* = "construct" */, - parameterElement /* = "parameter" */, - typeParameterElement /* = "type parameter" */, - primitiveType /* = "primitive type" */, - label /* = "label" */, - alias /* = "alias" */, - constElement /* = "const" */, - letElement /* = "let" */, - directory /* = "directory" */, - externalModuleName /* = "external module name" */, - jsxAttribute /* = "JSX attribute" */, - string /* = "string" */, - link /* = "link" */, - linkName /* = "link name" */, - linkText /* = "link text" */ -} - -external enum class ScriptElementKindModifier { - none /* = "" */, - publicMemberModifier /* = "public" */, - privateMemberModifier /* = "private" */, - protectedMemberModifier /* = "protected" */, - exportedModifier /* = "export" */, - ambientModifier /* = "declare" */, - staticModifier /* = "static" */, - abstractModifier /* = "abstract" */, - optionalModifier /* = "optional" */, - deprecatedModifier /* = "deprecated" */, - dtsModifier /* = ".d.ts" */, - tsModifier /* = ".ts" */, - tsxModifier /* = ".tsx" */, - jsModifier /* = ".js" */, - jsxModifier /* = ".jsx" */, - jsonModifier /* = ".json" */ -} - -external enum class ClassificationTypeNames { - comment /* = "comment" */, - identifier /* = "identifier" */, - keyword /* = "keyword" */, - numericLiteral /* = "number" */, - bigintLiteral /* = "bigint" */, - operator /* = "operator" */, - stringLiteral /* = "string" */, - whiteSpace /* = "whitespace" */, - text /* = "text" */, - punctuation /* = "punctuation" */, - className /* = "class name" */, - enumName /* = "enum name" */, - interfaceName /* = "interface name" */, - moduleName /* = "module name" */, - typeParameterName /* = "type parameter name" */, - typeAliasName /* = "type alias name" */, - parameterName /* = "parameter name" */, - docCommentTagName /* = "doc comment tag name" */, - jsxOpenTagName /* = "jsx open tag name" */, - jsxCloseTagName /* = "jsx close tag name" */, - jsxSelfClosingTagName /* = "jsx self closing tag name" */, - jsxAttribute /* = "jsx attribute" */, - jsxText /* = "jsx text" */, - jsxAttributeStringLiteralValue /* = "jsx attribute string literal value" */ -} - -external enum class ClassificationType { - comment /* = 1 */, - identifier /* = 2 */, - keyword /* = 3 */, - numericLiteral /* = 4 */, - operator /* = 5 */, - stringLiteral /* = 6 */, - regularExpressionLiteral /* = 7 */, - whiteSpace /* = 8 */, - text /* = 9 */, - punctuation /* = 10 */, - className /* = 11 */, - enumName /* = 12 */, - interfaceName /* = 13 */, - moduleName /* = 14 */, - typeParameterName /* = 15 */, - typeAliasName /* = 16 */, - parameterName /* = 17 */, - docCommentTagName /* = 18 */, - jsxOpenTagName /* = 19 */, - jsxCloseTagName /* = 20 */, - jsxSelfClosingTagName /* = 21 */, - jsxAttribute /* = 22 */, - jsxText /* = 23 */, - jsxAttributeStringLiteralValue /* = 24 */, - bigintLiteral /* = 25 */ -} - -external interface InlayHintsContext { - var file: SourceFile - var program: Program - var cancellationToken: CancellationToken - var host: LanguageServiceHost - var span: TextSpan - var preferences: InlayHintsOptions -} - -external fun createClassifier(): Classifier - -external interface DocumentHighlights { - var fileName: String - var highlightSpans: Array -} - -external interface DocumentRegistry { - fun acquireDocument(fileName: String, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile - fun acquireDocumentWithKey(fileName: String, path: String /* String & `T$3` */, compilationSettings: CompilerOptions, key: String /* String & `T$29` */, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile - fun updateDocument(fileName: String, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile - fun updateDocumentWithKey(fileName: String, path: String /* String & `T$3` */, compilationSettings: CompilerOptions, key: String /* String & `T$29` */, scriptSnapshot: IScriptSnapshot, version: String, scriptKind: ScriptKind = definedExternally): SourceFile - fun getKeyForCompilationSettings(settings: CompilerOptions): String /* String & `T$29` */ - fun releaseDocument(fileName: String, compilationSettings: CompilerOptions) - fun releaseDocument(fileName: String, compilationSettings: CompilerOptions, scriptKind: ScriptKind) - fun releaseDocumentWithKey(path: String /* String & `T$3` */, key: String /* String & `T$29` */) - fun releaseDocumentWithKey(path: String /* String & `T$3` */, key: String /* String & `T$29` */, scriptKind: ScriptKind) - fun reportStats(): String -} - -external interface `T$29` { - var __bucketKey: Any -} - -external fun createDocumentRegistry(useCaseSensitiveFileNames: Boolean = definedExternally, currentDirectory: String = definedExternally): DocumentRegistry - -external fun preProcessFile(sourceText: String, readImportFiles: Boolean = definedExternally, detectJavaScriptImports: Boolean = definedExternally): PreProcessedFileInfo - -external interface TranspileOptions { - var compilerOptions: CompilerOptions? - get() = definedExternally - set(value) = definedExternally - var fileName: String? - get() = definedExternally - set(value) = definedExternally - var reportDiagnostics: Boolean? - get() = definedExternally - set(value) = definedExternally - var moduleName: String? - get() = definedExternally - set(value) = definedExternally - var renamedDependencies: MapLike? - get() = definedExternally - set(value) = definedExternally - var transformers: CustomTransformers? - get() = definedExternally - set(value) = definedExternally -} - -external interface TranspileOutput { - var outputText: String - var diagnostics: Array? - get() = definedExternally - set(value) = definedExternally - var sourceMapText: String? - get() = definedExternally - set(value) = definedExternally -} - -external fun transpileModule(input: String, transpileOptions: TranspileOptions): TranspileOutput - -external fun transpile(input: String, compilerOptions: CompilerOptions = definedExternally, fileName: String = definedExternally, diagnostics: Array = definedExternally, moduleName: String = definedExternally): String - -external var servicesVersion: Any - -external fun toEditorSettings(options: EditorOptions): EditorSettings - -external fun toEditorSettings(options: EditorSettings): EditorSettings - -external fun displayPartsToString(displayParts: Array?): String - -external fun getDefaultCompilerOptions(): CompilerOptions - -external fun getSupportedCodeFixes(): Array - -external fun createLanguageServiceSourceFile(fileName: String, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: String, setNodeParents: Boolean, scriptKind: ScriptKind = definedExternally): SourceFile - -external fun updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: String, textChangeRange: TextChangeRange?, aggressiveChecks: Boolean = definedExternally): SourceFile - -external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally, syntaxOnlyOrLanguageServiceMode: Boolean = definedExternally): LanguageService - -external fun createLanguageService(host: LanguageServiceHost): LanguageService - -external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally): LanguageService - -external fun createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry = definedExternally, syntaxOnlyOrLanguageServiceMode: LanguageServiceMode = definedExternally): LanguageService - -external fun getDefaultLibFilePath(options: CompilerOptions): String - -external fun transform(source: T, transformers: Array>, compilerOptions: CompilerOptions = definedExternally): TransformationResult - -external fun transform(source: T, transformers: Array>): TransformationResult - -external fun transform(source: Array, transformers: Array>, compilerOptions: CompilerOptions = definedExternally): TransformationResult - -external fun transform(source: Array, transformers: Array>): TransformationResult - -external var createNodeArray: (elements: Array?, hasTrailingComma: Boolean?) -> NodeArray - -external var createNumericLiteral: (value: dynamic /* String | Number */, numericLiteralFlags: TokenFlags?) -> NumericLiteral - -external var createBigIntLiteral: (value: dynamic /* String | PseudoBigInt */) -> BigIntLiteral - -external object createStringLiteral { - @nativeInvoke - operator fun invoke(text: String, isSingleQuote: Boolean? = definedExternally): StringLiteral - @nativeInvoke - operator fun invoke(text: String, isSingleQuote: Boolean? = definedExternally, hasExtendedUnicodeEscape: Boolean? = definedExternally): StringLiteral -} - -external var createStringLiteralFromNode: (sourceNode: dynamic /* Identifier | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral */, isSingleQuote: Boolean?) -> StringLiteral - -external var createRegularExpressionLiteral: (text: String) -> RegularExpressionLiteral - -external var createLoopVariable: (reservedInNestedScopes: Boolean?) -> Identifier - -external var createUniqueName: (text: String, flags: GeneratedIdentifierFlags?) -> Identifier - -external var createPrivateIdentifier: (text: String) -> PrivateIdentifier - -external var createSuper: () -> SuperExpression - -external var createThis: () -> ThisExpression - -external var createNull: () -> NullLiteral - -external var createTrue: () -> TrueLiteral - -external var createFalse: () -> FalseLiteral - -external var createModifier: (kind: T) -> ModifierToken - -external var createModifiersFromModifierFlags: (flags: ModifierFlags) -> Array - -external var createQualifiedName: (left: dynamic /* Identifier | QualifiedName */, right: dynamic /* String | Identifier */) -> QualifiedName - -external var updateQualifiedName: (node: QualifiedName, left: dynamic /* Identifier | QualifiedName */, right: Identifier) -> QualifiedName - -external var createComputedPropertyName: (expression: Expression) -> ComputedPropertyName - -external var updateComputedPropertyName: (node: ComputedPropertyName, expression: Expression) -> ComputedPropertyName - -external var createTypeParameterDeclaration: (name: dynamic /* String | Identifier */, constraint: TypeNode?, defaultType: TypeNode?) -> TypeParameterDeclaration - -external var updateTypeParameterDeclaration: (node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode?, defaultType: TypeNode?) -> TypeParameterDeclaration - -external var createParameter: (decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> ParameterDeclaration - -external var updateParameter: (node: ParameterDeclaration, decorators: Array?, modifiers: Array?, dotDotDotToken: DotDotDotToken?, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> ParameterDeclaration - -external var createDecorator: (expression: Expression) -> Decorator - -external var updateDecorator: (node: Decorator, expression: Expression) -> Decorator - -external var createProperty: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionOrExclamationToken: dynamic /* QuestionToken? | ExclamationToken? */, type: TypeNode?, initializer: Expression?) -> PropertyDeclaration - -external var updateProperty: (node: PropertyDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionOrExclamationToken: dynamic /* QuestionToken? | ExclamationToken? */, type: TypeNode?, initializer: Expression?) -> PropertyDeclaration - -external var createMethod: (decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> MethodDeclaration - -external var updateMethod: (node: MethodDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> MethodDeclaration - -external var createConstructor: (decorators: Array?, modifiers: Array?, parameters: Array, body: Block?) -> ConstructorDeclaration - -external var updateConstructor: (node: ConstructorDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, body: Block?) -> ConstructorDeclaration - -external var createGetAccessor: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, type: TypeNode?, body: Block?) -> GetAccessorDeclaration - -external var updateGetAccessor: (node: GetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, type: TypeNode?, body: Block?) -> GetAccessorDeclaration - -external var createSetAccessor: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, body: Block?) -> SetAccessorDeclaration - -external var updateSetAccessor: (node: SetAccessorDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, parameters: Array, body: Block?) -> SetAccessorDeclaration - -external var createCallSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?) -> CallSignatureDeclaration - -external var updateCallSignature: (node: CallSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?) -> CallSignatureDeclaration - -external var createConstructSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?) -> ConstructSignatureDeclaration - -external var updateConstructSignature: (node: ConstructSignatureDeclaration, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?) -> ConstructSignatureDeclaration - -external var updateIndexSignature: (node: IndexSignatureDeclaration, decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode) -> IndexSignatureDeclaration - -external var createKeywordTypeNode: (kind: TKind) -> KeywordTypeNode - -external var createTypePredicateNodeWithModifier: (assertsModifier: AssertsKeyword?, parameterName: dynamic /* String | Identifier | ThisTypeNode */, type: TypeNode?) -> TypePredicateNode - -external var updateTypePredicateNodeWithModifier: (node: TypePredicateNode, assertsModifier: AssertsKeyword?, parameterName: dynamic /* Identifier | ThisTypeNode */, type: TypeNode?) -> TypePredicateNode - -external var createTypeReferenceNode: (typeName: dynamic /* String | Identifier | QualifiedName */, typeArguments: Array?) -> TypeReferenceNode - -external var updateTypeReferenceNode: (node: TypeReferenceNode, typeName: dynamic /* Identifier | QualifiedName */, typeArguments: NodeArray?) -> TypeReferenceNode - -external var createFunctionTypeNode: (typeParameters: Array?, parameters: Array, type: TypeNode) -> FunctionTypeNode - -external var updateFunctionTypeNode: (node: FunctionTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode) -> FunctionTypeNode - -external var createConstructorTypeNode: (typeParameters: Array?, parameters: Array, type: TypeNode) -> ConstructorTypeNode - -external var updateConstructorTypeNode: (node: ConstructorTypeNode, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode) -> ConstructorTypeNode - -external var createTypeQueryNode: (exprName: dynamic /* Identifier | QualifiedName */) -> TypeQueryNode - -external var updateTypeQueryNode: (node: TypeQueryNode, exprName: dynamic /* Identifier | QualifiedName */) -> TypeQueryNode - -external var createTypeLiteralNode: (members: Array?) -> TypeLiteralNode - -external var updateTypeLiteralNode: (node: TypeLiteralNode, members: NodeArray) -> TypeLiteralNode - -external var createArrayTypeNode: (elementType: TypeNode) -> ArrayTypeNode - -external var updateArrayTypeNode: (node: ArrayTypeNode, elementType: TypeNode) -> ArrayTypeNode - -external var createTupleTypeNode: (elements: Array) -> TupleTypeNode - -external var updateTupleTypeNode: (node: TupleTypeNode, elements: Array) -> TupleTypeNode - -external var createOptionalTypeNode: (type: TypeNode) -> OptionalTypeNode - -external var updateOptionalTypeNode: (node: OptionalTypeNode, type: TypeNode) -> OptionalTypeNode - -external var createRestTypeNode: (type: TypeNode) -> RestTypeNode - -external var updateRestTypeNode: (node: RestTypeNode, type: TypeNode) -> RestTypeNode - -external var createUnionTypeNode: (types: Array) -> UnionTypeNode - -external var updateUnionTypeNode: (node: UnionTypeNode, types: NodeArray) -> UnionTypeNode - -external var createIntersectionTypeNode: (types: Array) -> IntersectionTypeNode - -external var updateIntersectionTypeNode: (node: IntersectionTypeNode, types: NodeArray) -> IntersectionTypeNode - -external var createConditionalTypeNode: (checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) -> ConditionalTypeNode - -external var updateConditionalTypeNode: (node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) -> ConditionalTypeNode - -external var createInferTypeNode: (typeParameter: TypeParameterDeclaration) -> InferTypeNode - -external var updateInferTypeNode: (node: InferTypeNode, typeParameter: TypeParameterDeclaration) -> InferTypeNode - -external var createImportTypeNode: (argument: TypeNode, qualifier: dynamic /* Identifier? | QualifiedName? */, typeArguments: Array?, isTypeOf: Boolean?) -> ImportTypeNode - -external var updateImportTypeNode: (node: ImportTypeNode, argument: TypeNode, qualifier: dynamic /* Identifier? | QualifiedName? */, typeArguments: Array?, isTypeOf: Boolean?) -> ImportTypeNode - -external var createParenthesizedType: (type: TypeNode) -> ParenthesizedTypeNode - -external var updateParenthesizedType: (node: ParenthesizedTypeNode, type: TypeNode) -> ParenthesizedTypeNode - -external var createThisTypeNode: () -> ThisTypeNode - -external var updateTypeOperatorNode: (node: TypeOperatorNode, type: TypeNode) -> TypeOperatorNode - -external var createIndexedAccessTypeNode: (objectType: TypeNode, indexType: TypeNode) -> IndexedAccessTypeNode - -external var updateIndexedAccessTypeNode: (node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) -> IndexedAccessTypeNode - -external var createMappedTypeNode: (readonlyToken: dynamic /* ReadonlyKeyword? | PlusToken? | MinusToken? */, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */, type: TypeNode?) -> MappedTypeNode - -external var updateMappedTypeNode: (node: MappedTypeNode, readonlyToken: dynamic /* ReadonlyKeyword? | PlusToken? | MinusToken? */, typeParameter: TypeParameterDeclaration, nameType: TypeNode?, questionToken: dynamic /* QuestionToken? | PlusToken? | MinusToken? */, type: TypeNode?) -> MappedTypeNode - -external var createLiteralTypeNode: (literal: dynamic /* LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral */) -> LiteralTypeNode - -external var updateLiteralTypeNode: (node: LiteralTypeNode, literal: dynamic /* LiteralExpression | TrueLiteral | FalseLiteral | PrefixUnaryExpression | NullLiteral */) -> LiteralTypeNode - -external var createObjectBindingPattern: (elements: Array) -> ObjectBindingPattern - -external var updateObjectBindingPattern: (node: ObjectBindingPattern, elements: Array) -> ObjectBindingPattern - -external var createArrayBindingPattern: (elements: Array) -> ArrayBindingPattern - -external var updateArrayBindingPattern: (node: ArrayBindingPattern, elements: Array) -> ArrayBindingPattern - -external var createBindingElement: (dotDotDotToken: DotDotDotToken?, propertyName: dynamic /* String? | Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */, name: dynamic /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression?) -> BindingElement - -external var updateBindingElement: (node: BindingElement, dotDotDotToken: DotDotDotToken?, propertyName: dynamic /* Identifier? | StringLiteral? | NumericLiteral? | ComputedPropertyName? | PrivateIdentifier? */, name: dynamic /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, initializer: Expression?) -> BindingElement - -external var createArrayLiteral: (elements: Array?, multiLine: Boolean?) -> ArrayLiteralExpression - -external var updateArrayLiteral: (node: ArrayLiteralExpression, elements: Array) -> ArrayLiteralExpression - -external var createObjectLiteral: (properties: Array?, multiLine: Boolean?) -> ObjectLiteralExpression - -external var updateObjectLiteral: (node: ObjectLiteralExpression, properties: Array) -> ObjectLiteralExpression - -external var createPropertyAccess: (expression: Expression, name: dynamic /* String | Identifier | PrivateIdentifier */) -> PropertyAccessExpression - -external var updatePropertyAccess: (node: PropertyAccessExpression, expression: Expression, name: dynamic /* Identifier | PrivateIdentifier */) -> PropertyAccessExpression - -external var createPropertyAccessChain: (expression: Expression, questionDotToken: QuestionDotToken?, name: dynamic /* String | Identifier | PrivateIdentifier */) -> PropertyAccessChain - -external var updatePropertyAccessChain: (node: PropertyAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, name: dynamic /* Identifier | PrivateIdentifier */) -> PropertyAccessChain - -external var createElementAccess: (expression: Expression, index: dynamic /* Number | Expression */) -> ElementAccessExpression - -external var updateElementAccess: (node: ElementAccessExpression, expression: Expression, argumentExpression: Expression) -> ElementAccessExpression - -external var createElementAccessChain: (expression: Expression, questionDotToken: QuestionDotToken?, index: dynamic /* Number | Expression */) -> ElementAccessChain - -external var updateElementAccessChain: (node: ElementAccessChain, expression: Expression, questionDotToken: QuestionDotToken?, argumentExpression: Expression) -> ElementAccessChain - -external var createCall: (expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> CallExpression - -external var updateCall: (node: CallExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array) -> CallExpression - -external var createCallChain: (expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array?) -> CallChain - -external var updateCallChain: (node: CallChain, expression: Expression, questionDotToken: QuestionDotToken?, typeArguments: Array?, argumentsArray: Array) -> CallChain - -external var createNew: (expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> NewExpression - -external var updateNew: (node: NewExpression, expression: Expression, typeArguments: Array?, argumentsArray: Array?) -> NewExpression - -external var createTypeAssertion: (type: TypeNode, expression: Expression) -> TypeAssertion - -external var updateTypeAssertion: (node: TypeAssertion, type: TypeNode, expression: Expression) -> TypeAssertion - -external var createParen: (expression: Expression) -> ParenthesizedExpression - -external var updateParen: (node: ParenthesizedExpression, expression: Expression) -> ParenthesizedExpression - -external var createFunctionExpression: (modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, parameters: Array?, type: TypeNode?, body: Block) -> FunctionExpression - -external var updateFunctionExpression: (node: FunctionExpression, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block) -> FunctionExpression - -external var createDelete: (expression: Expression) -> DeleteExpression - -external var updateDelete: (node: DeleteExpression, expression: Expression) -> DeleteExpression - -external var createTypeOf: (expression: Expression) -> TypeOfExpression - -external var updateTypeOf: (node: TypeOfExpression, expression: Expression) -> TypeOfExpression - -external var createVoid: (expression: Expression) -> VoidExpression - -external var updateVoid: (node: VoidExpression, expression: Expression) -> VoidExpression - -external var createAwait: (expression: Expression) -> AwaitExpression - -external var updateAwait: (node: AwaitExpression, expression: Expression) -> AwaitExpression - -external var createPrefix: (operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.TildeToken | SyntaxKind.ExclamationToken */, operand: Expression) -> PrefixUnaryExpression - -external var updatePrefix: (node: PrefixUnaryExpression, operand: Expression) -> PrefixUnaryExpression - -external var createPostfix: (operand: Expression, operator: dynamic /* SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken */) -> PostfixUnaryExpression - -external var updatePostfix: (node: PostfixUnaryExpression, operand: Expression) -> PostfixUnaryExpression - -external var createBinary: (left: Expression, operator: dynamic /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */, right: Expression) -> BinaryExpression - -external var updateConditional: (node: ConditionalExpression, condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression) -> ConditionalExpression - -external var createTemplateExpression: (head: TemplateHead, templateSpans: Array) -> TemplateExpression - -external var updateTemplateExpression: (node: TemplateExpression, head: TemplateHead, templateSpans: Array) -> TemplateExpression - -external object createTemplateHead { - @nativeInvoke - operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateHead - @nativeInvoke - operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateHead -} - -external object createTemplateMiddle { - @nativeInvoke - operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateMiddle - @nativeInvoke - operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateMiddle -} - -external object createTemplateTail { - @nativeInvoke - operator fun invoke(text: String, rawText: String? = definedExternally, templateFlags: TokenFlags? = definedExternally): TemplateTail - @nativeInvoke - operator fun invoke(text: String?, rawText: String, templateFlags: TokenFlags? = definedExternally): TemplateTail -} - -external object createNoSubstitutionTemplateLiteral { - @nativeInvoke - operator fun invoke(text: String, rawText: String? = definedExternally): NoSubstitutionTemplateLiteral - @nativeInvoke - operator fun invoke(text: String?, rawText: String): NoSubstitutionTemplateLiteral -} - -external var updateYield: (node: YieldExpression, asteriskToken: AsteriskToken?, expression: Expression?) -> YieldExpression - -external var createSpread: (expression: Expression) -> SpreadElement - -external var updateSpread: (node: SpreadElement, expression: Expression) -> SpreadElement - -external var createOmittedExpression: () -> OmittedExpression - -external var createAsExpression: (expression: Expression, type: TypeNode) -> AsExpression - -external var updateAsExpression: (node: AsExpression, expression: Expression, type: TypeNode) -> AsExpression - -external var createNonNullExpression: (expression: Expression) -> NonNullExpression - -external var updateNonNullExpression: (node: NonNullExpression, expression: Expression) -> NonNullExpression - -external var createNonNullChain: (expression: Expression) -> NonNullChain - -external var updateNonNullChain: (node: NonNullChain, expression: Expression) -> NonNullChain - -external var createMetaProperty: (keywordToken: dynamic /* SyntaxKind.ImportKeyword | SyntaxKind.NewKeyword */, name: Identifier) -> MetaProperty - -external var updateMetaProperty: (node: MetaProperty, name: Identifier) -> MetaProperty - -external var createTemplateSpan: (expression: Expression, literal: dynamic /* TemplateMiddle | TemplateTail */) -> TemplateSpan - -external var updateTemplateSpan: (node: TemplateSpan, expression: Expression, literal: dynamic /* TemplateMiddle | TemplateTail */) -> TemplateSpan - -external var createSemicolonClassElement: () -> SemicolonClassElement - -external var createBlock: (statements: Array, multiLine: Boolean?) -> Block - -external var updateBlock: (node: Block, statements: Array) -> Block - -external var createVariableStatement: (modifiers: Array?, declarationList: dynamic /* VariableDeclarationList | Array */) -> VariableStatement - -external var updateVariableStatement: (node: VariableStatement, modifiers: Array?, declarationList: VariableDeclarationList) -> VariableStatement - -external var createEmptyStatement: () -> EmptyStatement - -external var createExpressionStatement: (expression: Expression) -> ExpressionStatement - -external var updateExpressionStatement: (node: ExpressionStatement, expression: Expression) -> ExpressionStatement - -external var createStatement: (expression: Expression) -> ExpressionStatement - -external var updateStatement: (node: ExpressionStatement, expression: Expression) -> ExpressionStatement - -external var createIf: (expression: Expression, thenStatement: Statement, elseStatement: Statement?) -> IfStatement - -external var updateIf: (node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement?) -> IfStatement - -external var createDo: (statement: Statement, expression: Expression) -> DoStatement - -external var updateDo: (node: DoStatement, statement: Statement, expression: Expression) -> DoStatement - -external var createWhile: (expression: Expression, statement: Statement) -> WhileStatement - -external var updateWhile: (node: WhileStatement, expression: Expression, statement: Statement) -> WhileStatement - -external var createFor: (initializer: dynamic /* VariableDeclarationList? | Expression? */, condition: Expression?, incrementor: Expression?, statement: Statement) -> ForStatement - -external var updateFor: (node: ForStatement, initializer: dynamic /* VariableDeclarationList? | Expression? */, condition: Expression?, incrementor: Expression?, statement: Statement) -> ForStatement - -external var createForIn: (initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForInStatement - -external var updateForIn: (node: ForInStatement, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForInStatement - -external var createForOf: (awaitModifier: AwaitKeyword?, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForOfStatement - -external var updateForOf: (node: ForOfStatement, awaitModifier: AwaitKeyword?, initializer: dynamic /* VariableDeclarationList | Expression */, expression: Expression, statement: Statement) -> ForOfStatement - -external var createContinue: (label: dynamic /* String? | Identifier? */) -> ContinueStatement - -external var updateContinue: (node: ContinueStatement, label: Identifier?) -> ContinueStatement - -external var createBreak: (label: dynamic /* String? | Identifier? */) -> BreakStatement - -external var updateBreak: (node: BreakStatement, label: Identifier?) -> BreakStatement - -external var createReturn: (expression: Expression?) -> ReturnStatement - -external var updateReturn: (node: ReturnStatement, expression: Expression?) -> ReturnStatement - -external var createWith: (expression: Expression, statement: Statement) -> WithStatement - -external var updateWith: (node: WithStatement, expression: Expression, statement: Statement) -> WithStatement - -external var createSwitch: (expression: Expression, caseBlock: CaseBlock) -> SwitchStatement - -external var updateSwitch: (node: SwitchStatement, expression: Expression, caseBlock: CaseBlock) -> SwitchStatement - -external var createLabel: (label: dynamic /* String | Identifier */, statement: Statement) -> LabeledStatement - -external var updateLabel: (node: LabeledStatement, label: Identifier, statement: Statement) -> LabeledStatement - -external var createThrow: (expression: Expression) -> ThrowStatement - -external var updateThrow: (node: ThrowStatement, expression: Expression) -> ThrowStatement - -external var createTry: (tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?) -> TryStatement - -external var updateTry: (node: TryStatement, tryBlock: Block, catchClause: CatchClause?, finallyBlock: Block?) -> TryStatement - -external var createDebuggerStatement: () -> DebuggerStatement - -external var createVariableDeclarationList: (declarations: Array, flags: NodeFlags?) -> VariableDeclarationList - -external var updateVariableDeclarationList: (node: VariableDeclarationList, declarations: Array) -> VariableDeclarationList - -external var createFunctionDeclaration: (decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> FunctionDeclaration - -external var updateFunctionDeclaration: (node: FunctionDeclaration, decorators: Array?, modifiers: Array?, asteriskToken: AsteriskToken?, name: Identifier?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Block?) -> FunctionDeclaration - -external var createClassDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassDeclaration - -external var updateClassDeclaration: (node: ClassDeclaration, decorators: Array?, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassDeclaration - -external var createInterfaceDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> InterfaceDeclaration - -external var updateInterfaceDeclaration: (node: InterfaceDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, heritageClauses: Array?, members: Array) -> InterfaceDeclaration - -external var createTypeAliasDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, typeParameters: Array?, type: TypeNode) -> TypeAliasDeclaration - -external var updateTypeAliasDeclaration: (node: TypeAliasDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, typeParameters: Array?, type: TypeNode) -> TypeAliasDeclaration - -external var createEnumDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* String | Identifier */, members: Array) -> EnumDeclaration - -external var updateEnumDeclaration: (node: EnumDeclaration, decorators: Array?, modifiers: Array?, name: Identifier, members: Array) -> EnumDeclaration - -external var createModuleDeclaration: (decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral */, body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */, flags: NodeFlags?) -> ModuleDeclaration - -external var updateModuleDeclaration: (node: ModuleDeclaration, decorators: Array?, modifiers: Array?, name: dynamic /* Identifier | StringLiteral */, body: dynamic /* ModuleBlock? | NamespaceDeclaration? | Identifier? | JSDocNamespaceDeclaration? */) -> ModuleDeclaration - -external var createModuleBlock: (statements: Array) -> ModuleBlock - -external var updateModuleBlock: (node: ModuleBlock, statements: Array) -> ModuleBlock - -external var createCaseBlock: (clauses: Array) -> CaseBlock - -external var updateCaseBlock: (node: CaseBlock, clauses: Array) -> CaseBlock - -external var createNamespaceExportDeclaration: (name: dynamic /* String | Identifier */) -> NamespaceExportDeclaration - -external var updateNamespaceExportDeclaration: (node: NamespaceExportDeclaration, name: Identifier) -> NamespaceExportDeclaration - -external var createImportEqualsDeclaration: (decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: dynamic /* String | Identifier */, moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */) -> ImportEqualsDeclaration - -external var updateImportEqualsDeclaration: (node: ImportEqualsDeclaration, decorators: Array?, modifiers: Array?, isTypeOnly: Boolean, name: Identifier, moduleReference: dynamic /* Identifier | QualifiedName | ExternalModuleReference */) -> ImportEqualsDeclaration - -external var createImportDeclaration: (decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression) -> ImportDeclaration - -external var updateImportDeclaration: (node: ImportDeclaration, decorators: Array?, modifiers: Array?, importClause: ImportClause?, moduleSpecifier: Expression) -> ImportDeclaration - -external var createNamespaceImport: (name: Identifier) -> NamespaceImport - -external var updateNamespaceImport: (node: NamespaceImport, name: Identifier) -> NamespaceImport - -external var createNamedImports: (elements: Array) -> NamedImports - -external var updateNamedImports: (node: NamedImports, elements: Array) -> NamedImports - -external var createImportSpecifier: (propertyName: Identifier?, name: Identifier) -> ImportSpecifier - -external var updateImportSpecifier: (node: ImportSpecifier, propertyName: Identifier?, name: Identifier) -> ImportSpecifier - -external var createExportAssignment: (decorators: Array?, modifiers: Array?, isExportEquals: Boolean?, expression: Expression) -> ExportAssignment - -external var updateExportAssignment: (node: ExportAssignment, decorators: Array?, modifiers: Array?, expression: Expression) -> ExportAssignment - -external var createNamedExports: (elements: Array) -> NamedExports - -external var updateNamedExports: (node: NamedExports, elements: Array) -> NamedExports - -external var createExportSpecifier: (propertyName: dynamic /* String? | Identifier? */, name: dynamic /* String | Identifier */) -> ExportSpecifier - -external var updateExportSpecifier: (node: ExportSpecifier, propertyName: Identifier?, name: Identifier) -> ExportSpecifier - -external var createExternalModuleReference: (expression: Expression) -> ExternalModuleReference - -external var updateExternalModuleReference: (node: ExternalModuleReference, expression: Expression) -> ExternalModuleReference - -external var createJSDocTypeExpression: (type: TypeNode) -> JSDocTypeExpression - -external var createJSDocTypeTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocTypeTag - -external var createJSDocReturnTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression?, comment: dynamic /* String? | NodeArray? */) -> JSDocReturnTag - -external var createJSDocThisTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocThisTag - -external var createJSDocComment: (comment: dynamic /* String? | NodeArray? */, tags: Array?) -> JSDoc - -external var createJSDocParameterTag: (tagName: Identifier?, name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean?, comment: dynamic /* String? | NodeArray? */) -> JSDocParameterTag - -external var createJSDocClassTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocClassTag - -external var createJSDocAugmentsTag: (tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: dynamic /* String? | NodeArray? */) -> JSDocAugmentsTag - -external var createJSDocEnumTag: (tagName: Identifier?, typeExpression: JSDocTypeExpression, comment: dynamic /* String? | NodeArray? */) -> JSDocEnumTag - -external var createJSDocTemplateTag: (tagName: Identifier?, constraint: JSDocTypeExpression?, typeParameters: Array, comment: dynamic /* String? | NodeArray? */) -> JSDocTemplateTag - -external var createJSDocTypedefTag: (tagName: Identifier?, typeExpression: dynamic /* JSDocTypeLiteral? | JSDocTypeExpression? */, fullName: dynamic /* Identifier? | JSDocNamespaceDeclaration? */, comment: dynamic /* String? | NodeArray? */) -> JSDocTypedefTag - -external var createJSDocCallbackTag: (tagName: Identifier?, typeExpression: JSDocSignature, fullName: dynamic /* Identifier? | JSDocNamespaceDeclaration? */, comment: dynamic /* String? | NodeArray? */) -> JSDocCallbackTag - -external var createJSDocSignature: (typeParameters: Array?, parameters: Array, type: JSDocReturnTag?) -> JSDocSignature - -external var createJSDocPropertyTag: (tagName: Identifier?, name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, isNameFirst: Boolean?, comment: dynamic /* String? | NodeArray? */) -> JSDocPropertyTag - -external var createJSDocTypeLiteral: (jsDocPropertyTags: Array?, isArrayType: Boolean?) -> JSDocTypeLiteral - -external var createJSDocImplementsTag: (tagName: Identifier?, className: ExpressionWithTypeArguments /* ExpressionWithTypeArguments & `T$21` */, comment: dynamic /* String? | NodeArray? */) -> JSDocImplementsTag - -external var createJSDocAuthorTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocAuthorTag - -external var createJSDocPublicTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocPublicTag - -external var createJSDocPrivateTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocPrivateTag - -external var createJSDocProtectedTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocProtectedTag - -external var createJSDocReadonlyTag: (tagName: Identifier?, comment: dynamic /* String? | NodeArray? */) -> JSDocReadonlyTag - -external var createJSDocTag: (tagName: Identifier, comment: dynamic /* String? | NodeArray? */) -> JSDocUnknownTag - -external var createJsxElement: (openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement) -> JsxElement - -external var updateJsxElement: (node: JsxElement, openingElement: JsxOpeningElement, children: Array, closingElement: JsxClosingElement) -> JsxElement - -external var createJsxSelfClosingElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxSelfClosingElement - -external var updateJsxSelfClosingElement: (node: JsxSelfClosingElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxSelfClosingElement - -external var createJsxOpeningElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxOpeningElement - -external var updateJsxOpeningElement: (node: JsxOpeningElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */, typeArguments: Array?, attributes: JsxAttributes) -> JsxOpeningElement - -external var createJsxClosingElement: (tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */) -> JsxClosingElement - -external var updateJsxClosingElement: (node: JsxClosingElement, tagName: dynamic /* Identifier | ThisExpression | JsxTagNamePropertyAccess */) -> JsxClosingElement - -external var createJsxFragment: (openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment) -> JsxFragment - -external var createJsxText: (text: String, containsOnlyTriviaWhiteSpaces: Boolean?) -> JsxText - -external var updateJsxText: (node: JsxText, text: String, containsOnlyTriviaWhiteSpaces: Boolean?) -> JsxText - -external var createJsxOpeningFragment: () -> JsxOpeningFragment - -external var createJsxJsxClosingFragment: () -> JsxClosingFragment - -external var updateJsxFragment: (node: JsxFragment, openingFragment: JsxOpeningFragment, children: Array, closingFragment: JsxClosingFragment) -> JsxFragment - -external var createJsxAttribute: (name: Identifier, initializer: dynamic /* StringLiteral? | JsxExpression? */) -> JsxAttribute - -external var updateJsxAttribute: (node: JsxAttribute, name: Identifier, initializer: dynamic /* StringLiteral? | JsxExpression? */) -> JsxAttribute - -external var createJsxAttributes: (properties: Array) -> JsxAttributes - -external var updateJsxAttributes: (node: JsxAttributes, properties: Array) -> JsxAttributes - -external var createJsxSpreadAttribute: (expression: Expression) -> JsxSpreadAttribute - -external var updateJsxSpreadAttribute: (node: JsxSpreadAttribute, expression: Expression) -> JsxSpreadAttribute - -external var createJsxExpression: (dotDotDotToken: DotDotDotToken?, expression: Expression?) -> JsxExpression - -external var updateJsxExpression: (node: JsxExpression, expression: Expression?) -> JsxExpression - -external var createCaseClause: (expression: Expression, statements: Array) -> CaseClause - -external var updateCaseClause: (node: CaseClause, expression: Expression, statements: Array) -> CaseClause - -external var createDefaultClause: (statements: Array) -> DefaultClause - -external var updateDefaultClause: (node: DefaultClause, statements: Array) -> DefaultClause - -external var createHeritageClause: (token: dynamic /* SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword */, types: Array) -> HeritageClause - -external var updateHeritageClause: (node: HeritageClause, types: Array) -> HeritageClause - -external var createCatchClause: (variableDeclaration: dynamic /* String? | VariableDeclaration? */, block: Block) -> CatchClause - -external var updateCatchClause: (node: CatchClause, variableDeclaration: VariableDeclaration?, block: Block) -> CatchClause - -external var createPropertyAssignment: (name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression) -> PropertyAssignment - -external var updatePropertyAssignment: (node: PropertyAssignment, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression) -> PropertyAssignment - -external var createShorthandPropertyAssignment: (name: dynamic /* String | Identifier */, objectAssignmentInitializer: Expression?) -> ShorthandPropertyAssignment - -external var updateShorthandPropertyAssignment: (node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression?) -> ShorthandPropertyAssignment - -external var createSpreadAssignment: (expression: Expression) -> SpreadAssignment - -external var updateSpreadAssignment: (node: SpreadAssignment, expression: Expression) -> SpreadAssignment - -external var createEnumMember: (name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression?) -> EnumMember - -external var updateEnumMember: (node: EnumMember, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, initializer: Expression?) -> EnumMember - -external var updateSourceFileNode: (node: SourceFile, statements: Array, isDeclarationFile: Boolean?, referencedFiles: Array?, typeReferences: Array?, hasNoDefaultLib: Boolean?, libReferences: Array?) -> SourceFile - -external var createNotEmittedStatement: (original: Node) -> NotEmittedStatement - -external var createPartiallyEmittedExpression: (expression: Expression, original: Node?) -> PartiallyEmittedExpression - -external var updatePartiallyEmittedExpression: (node: PartiallyEmittedExpression, expression: Expression) -> PartiallyEmittedExpression - -external var createCommaList: (elements: Array) -> CommaListExpression - -external var updateCommaList: (node: CommaListExpression, elements: Array) -> CommaListExpression - -external var createBundle: (sourceFiles: Array, prepends: Array?) -> Bundle - -external var updateBundle: (node: Bundle, sourceFiles: Array, prepends: Array?) -> Bundle - -external object createImmediatelyInvokedFunctionExpression { - @nativeInvoke - operator fun invoke(statements: Array): CallExpression - @nativeInvoke - operator fun invoke(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression -} - -external object createImmediatelyInvokedArrowFunction { - @nativeInvoke - operator fun invoke(statements: Array): CallExpression - @nativeInvoke - operator fun invoke(statements: Array, param: ParameterDeclaration, paramValue: Expression): CallExpression -} - -external var createVoidZero: () -> VoidExpression - -external var createExportDefault: (expression: Expression) -> ExportAssignment - -external var createExternalModuleExport: (exportName: Identifier) -> ExportDeclaration - -external var createNamespaceExport: (name: Identifier) -> NamespaceExport - -external var updateNamespaceExport: (node: NamespaceExport, name: Identifier) -> NamespaceExport - -external var createToken: (kind: TKind) -> Token - -external var createIdentifier: (text: String) -> Identifier - -external var createTempVariable: (recordTempVariable: ((node: Identifier) -> Unit)?) -> Identifier - -external var getGeneratedNameForNode: (node: Node?) -> Identifier - -external var createOptimisticUniqueName: (text: String) -> Identifier - -external var createFileLevelUniqueName: (text: String) -> Identifier - -external var createIndexSignature: (decorators: Array?, modifiers: Array?, parameters: Array, type: TypeNode) -> IndexSignatureDeclaration - -external var createTypePredicateNode: (parameterName: dynamic /* Identifier | ThisTypeNode | String */, type: TypeNode) -> TypePredicateNode - -external var updateTypePredicateNode: (node: TypePredicateNode, parameterName: dynamic /* Identifier | ThisTypeNode */, type: TypeNode) -> TypePredicateNode - -external object createLiteral { - @nativeInvoke - operator fun invoke(value: Any /* String | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier */): StringLiteral - @nativeInvoke - operator fun invoke(value: Any /* Number | PseudoBigInt */): NumericLiteral - @nativeInvoke - operator fun invoke(value: Boolean): dynamic /* TrueLiteral | FalseLiteral */ - @nativeInvoke - operator fun invoke(value: Any /* String | Number | PseudoBigInt | Boolean */): PrimaryExpression -} - -external var createMethodSignature: (typeParameters: Array?, parameters: Array, type: TypeNode?, name: dynamic /* String | Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?) -> MethodSignature - -external var updateMethodSignature: (node: MethodSignature, typeParameters: NodeArray?, parameters: NodeArray, type: TypeNode?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?) -> MethodSignature - -external object createTypeOperatorNode { - @nativeInvoke - operator fun invoke(type: TypeNode): TypeOperatorNode - @nativeInvoke - operator fun invoke(operator: Any /* SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword */, type: TypeNode): TypeOperatorNode -} - -external object createTaggedTemplate { - @nativeInvoke - operator fun invoke(tag: Expression, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression - @nativeInvoke - operator fun invoke(tag: Expression, typeArguments: Array?, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression -} - -external object updateTaggedTemplate { - @nativeInvoke - operator fun invoke(node: TaggedTemplateExpression, tag: Expression, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression - @nativeInvoke - operator fun invoke(node: TaggedTemplateExpression, tag: Expression, typeArguments: Array?, template: Any /* TemplateExpression | NoSubstitutionTemplateLiteral */): TaggedTemplateExpression -} - -external var updateBinary: (node: BinaryExpression, left: Expression, right: Expression, operator: dynamic /* SyntaxKind.QuestionQuestionToken | ExponentiationOperator | SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.InstanceOfKeyword | SyntaxKind.InKeyword | SyntaxKind.EqualsEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.BarBarEqualsToken | SyntaxKind.AmpersandAmpersandEqualsToken | SyntaxKind.QuestionQuestionEqualsToken | SyntaxKind.CommaToken | BinaryOperatorToken */) -> BinaryExpression - -external object createConditional { - @nativeInvoke - operator fun invoke(condition: Expression, whenTrue: Expression, whenFalse: Expression): ConditionalExpression - @nativeInvoke - operator fun invoke(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression): ConditionalExpression -} - -external object createYield { - @nativeInvoke - operator fun invoke(expression: Expression? = definedExternally): YieldExpression - @nativeInvoke - operator fun invoke(asteriskToken: AsteriskToken?, expression: Expression): YieldExpression -} - -external var createClassExpression: (modifiers: Array?, name: dynamic /* String? | Identifier? */, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassExpression - -external var updateClassExpression: (node: ClassExpression, modifiers: Array?, name: Identifier?, typeParameters: Array?, heritageClauses: Array?, members: Array) -> ClassExpression - -external var createPropertySignature: (modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | String */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> PropertySignature - -external var updatePropertySignature: (node: PropertySignature, modifiers: Array?, name: dynamic /* Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier */, questionToken: QuestionToken?, type: TypeNode?, initializer: Expression?) -> PropertySignature - -external var createExpressionWithTypeArguments: (typeArguments: Array?, expression: Expression) -> ExpressionWithTypeArguments - -external var updateExpressionWithTypeArguments: (node: ExpressionWithTypeArguments, typeArguments: Array?, expression: Expression) -> ExpressionWithTypeArguments - -external object createArrowFunction { - @nativeInvoke - operator fun invoke(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken?, body: Any /* FunctionBody | Expression */): ArrowFunction - @nativeInvoke - operator fun invoke(modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Any /* FunctionBody | Expression */): ArrowFunction -} - -external object updateArrowFunction { - @nativeInvoke - operator fun invoke(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, equalsGreaterThanToken: EqualsGreaterThanToken, body: Any /* FunctionBody | Expression */): ArrowFunction - @nativeInvoke - operator fun invoke(node: ArrowFunction, modifiers: Array?, typeParameters: Array?, parameters: Array, type: TypeNode?, body: Any /* FunctionBody | Expression */): ArrowFunction -} - -external object createVariableDeclaration { - @nativeInvoke - operator fun invoke(name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, type: TypeNode? = definedExternally, initializer: Expression? = definedExternally): VariableDeclaration - @nativeInvoke - operator fun invoke(name: Any /* String | Identifier | ObjectBindingPattern | ArrayBindingPattern */, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration -} - -external object updateVariableDeclaration { - @nativeInvoke - operator fun invoke(node: VariableDeclaration, name: Any /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, type: TypeNode?, initializer: Expression?): VariableDeclaration - @nativeInvoke - operator fun invoke(node: VariableDeclaration, name: Any /* Identifier | ObjectBindingPattern | ArrayBindingPattern */, exclamationToken: ExclamationToken?, type: TypeNode?, initializer: Expression?): VariableDeclaration -} - -external var createImportClause: (name: Identifier?, namedBindings: dynamic /* NamespaceImport? | NamedImports? */, isTypeOnly: Any) -> ImportClause - -external var updateImportClause: (node: ImportClause, name: Identifier?, namedBindings: dynamic /* NamespaceImport? | NamedImports? */, isTypeOnly: Boolean) -> ImportClause - -external var createExportDeclaration: (decorators: Array?, modifiers: Array?, exportClause: dynamic /* NamespaceExport? | NamedExports? */, moduleSpecifier: Expression?, isTypeOnly: Any) -> ExportDeclaration - -external var updateExportDeclaration: (node: ExportDeclaration, decorators: Array?, modifiers: Array?, exportClause: dynamic /* NamespaceExport? | NamedExports? */, moduleSpecifier: Expression?, isTypeOnly: Boolean) -> ExportDeclaration - -external var createJSDocParamTag: (name: dynamic /* Identifier | QualifiedName */, isBracketed: Boolean, typeExpression: JSDocTypeExpression?, comment: String?) -> JSDocParameterTag - -external var createComma: (left: Expression, right: Expression) -> Expression - -external var createLessThan: (left: Expression, right: Expression) -> Expression - -external var createAssignment: (left: Expression, right: Expression) -> BinaryExpression - -external var createStrictEquality: (left: Expression, right: Expression) -> BinaryExpression - -external var createStrictInequality: (left: Expression, right: Expression) -> BinaryExpression - -external var createAdd: (left: Expression, right: Expression) -> BinaryExpression - -external var createSubtract: (left: Expression, right: Expression) -> BinaryExpression - -external var createLogicalAnd: (left: Expression, right: Expression) -> BinaryExpression - -external var createLogicalOr: (left: Expression, right: Expression) -> BinaryExpression - -external var createPostfixIncrement: (operand: Expression) -> PostfixUnaryExpression - -external var createLogicalNot: (operand: Expression) -> PrefixUnaryExpression - -external var createNode: (kind: SyntaxKind, pos: Any, end: Any) -> Node - -external var getMutableClone: (node: T) -> T - -external var isTypeAssertion: (node: Node) -> Boolean - -external var isIdentifierOrPrivateIdentifier: (node: Node) -> Boolean \ No newline at end of file diff --git a/modules/mod2/externals/typescript.ts.server.module_typescript.kt b/modules/mod2/externals/typescript.ts.server.module_typescript.kt deleted file mode 100644 index 4ce5432..0000000 --- a/modules/mod2/externals/typescript.ts.server.module_typescript.kt +++ /dev/null @@ -1,104 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package ts.server - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.CompilerOptions -import ts.WatchOptions -import ts.TypeAcquisition -import ts.SortedReadonlyArray - -external interface TypingInstallerResponse { - var kind: String /* "action::set" | "action::invalidate" | "event::typesRegistry" | "action::packageInstalled" | "event::beginInstallTypes" | "event::endInstallTypes" | "event::initializationFailed" */ -} - -external interface TypingInstallerRequestWithProjectName { - var projectName: String -} - -external interface DiscoverTypings : TypingInstallerRequestWithProjectName { - var fileNames: Array - var projectRootPath: String /* String & `T$3` */ - var compilerOptions: CompilerOptions - var watchOptions: WatchOptions? - get() = definedExternally - set(value) = definedExternally - var typeAcquisition: TypeAcquisition - var unresolvedImports: SortedReadonlyArray - var cachePath: String? - get() = definedExternally - set(value) = definedExternally - var kind: String /* "discover" */ -} - -external interface CloseProject : TypingInstallerRequestWithProjectName { - var kind: String /* "closeProject" */ -} - -external interface TypesRegistryRequest { - var kind: String /* "typesRegistry" */ -} - -external interface InstallPackageRequest : TypingInstallerRequestWithProjectName { - var kind: String /* "installPackage" */ - var fileName: String /* String & `T$3` */ - var packageName: String - var projectRootPath: String /* String & `T$3` */ -} - -external interface PackageInstalledResponse : ProjectResponse { - override var kind: String /* "action::packageInstalled" */ - var success: Boolean - var message: String -} - -external interface InitializationFailedResponse : TypingInstallerResponse { - override var kind: String /* "event::initializationFailed" */ - var message: String - var stack: String? - get() = definedExternally - set(value) = definedExternally -} - -external interface ProjectResponse : TypingInstallerResponse { - var projectName: String -} - -external interface InvalidateCachedTypings : ProjectResponse { - override var kind: String /* "action::invalidate" */ -} - -external interface InstallTypes : ProjectResponse { - override var kind: String /* "event::beginInstallTypes" | "event::endInstallTypes" */ - var eventId: Number - var typingsInstallerVersion: String - var packagesToInstall: Array -} - -external interface BeginInstallTypes : InstallTypes { - override var kind: String /* "event::beginInstallTypes" */ -} - -external interface EndInstallTypes : InstallTypes { - override var kind: String /* "event::endInstallTypes" */ - var installSuccess: Boolean -} - -external interface SetTypings : ProjectResponse { - var typeAcquisition: TypeAcquisition - var compilerOptions: CompilerOptions - var typings: Array - var unresolvedImports: SortedReadonlyArray - override var kind: String /* "action::set" */ -} \ No newline at end of file diff --git a/modules/mod2/externals/utils.module_typescript-to-lua.kt b/modules/mod2/externals/utils.module_typescript-to-lua.kt deleted file mode 100644 index 08363d8..0000000 --- a/modules/mod2/externals/utils.module_typescript-to-lua.kt +++ /dev/null @@ -1,46 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.WriteFileCallback -import ts.SourceFile - -external interface EmitHost { - fun directoryExists(path: String): Boolean - fun fileExists(path: String): Boolean - fun getCurrentDirectory(): String - fun readFile(path: String): String? - var writeFile: WriteFileCallback -} - -external interface BaseFile { - var code: String - var sourceMap: String? - get() = definedExternally - set(value) = definedExternally - var sourceFiles: Array? - get() = definedExternally - set(value) = definedExternally -} - -external interface ProcessedFile : BaseFile { - var fileName: String - var luaAst: File? - get() = definedExternally - set(value) = definedExternally -} - -external interface EmitFile : BaseFile { - var outputPath: String -} \ No newline at end of file diff --git a/modules/mod2/externals/visitors.module_typescript-to-lua.kt b/modules/mod2/externals/visitors.module_typescript-to-lua.kt deleted file mode 100644 index 69513ac..0000000 --- a/modules/mod2/externals/visitors.module_typescript-to-lua.kt +++ /dev/null @@ -1,38 +0,0 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") - -import kotlin.js.* -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* -import ts.Statement -import ts.Node -import tsstdlib.Map -import ts.SyntaxKind - -external interface NodesBySyntaxKind - -typealias StatementLikeNode = Statement - -typealias VisitorResult = Any - -typealias FunctionVisitor = (node: T, context: TransformationContext) -> VisitorResult - -external interface ObjectVisitor { - var transform: FunctionVisitor - var priority: Number? - get() = definedExternally - set(value) = definedExternally -} - -typealias Visitors = Any - -typealias VisitorMap = Map>> \ No newline at end of file diff --git a/modules/mod2/src/main/kotlin/events.kt b/modules/mod2/src/main/kotlin/events.kt deleted file mode 100644 index 5684b55..0000000 --- a/modules/mod2/src/main/kotlin/events.kt +++ /dev/null @@ -1,11 +0,0 @@ -fun main() { - - -script.on_event( - defines.events.on_tick -) { event -> - -} - - -} diff --git a/modules/mod2/typed-factorio/README.md b/modules/mod2/typed-factorio/README.md deleted file mode 100644 index 08ae6dc..0000000 --- a/modules/mod2/typed-factorio/README.md +++ /dev/null @@ -1,113 +0,0 @@ -# Typed Factorio - -Complete and featureful typescript definitions for the Factorio modding lua api. This is intended to be used with [TypescriptToLua](https://typescripttolua.github.io/). - -This project aims to provide type definitions for the Factorio API that are as complete as possible. This means minimal `any`s and `unknown`s, correct nullability, and smart types where possible. The generator integrates both the Factorio JSON api docs and manually defined additions and overrides. - -## Installation - -To use in your TypescriptToLua project: - -1. Install this package - -``` -npm install typed-factorio - -or - -yarn add typed-factorio -``` - -2. Add to your `tsconfig.json`: - -```diff -{ - "compilerOptions": { -+ "types": [ "typed-factorio/runtime" ] - } -} -``` - -This will add the types for the runtime stage to your entire project. - -Note: When types are updated, or released for a new factorio version, you will need update your package version to get the types. - -### Settings and data stage - -There are also definitions for the settings/data stage. - -To avoid type conflicts, the global tables for the settings/data stages have to be declared manually where you need them. These types can be imported from `typed-factorio/data/types` or `typed-factorio/settings/types`. - -Example: - -```ts -import { Data, Mods } from "typed-factorio/data/types" -// or -import { Data, Mods } from "typed-factorio/settings/types" - -declare const data: Data -declare const mods: Mods - -data.extend([{ ... }]) -``` - -There are currently full types for settings stage, but only basic types for the data stage. - -### Factorio lualib modules - -Currently, there are types for the following modules: - -- `util` -- `mod-gui` - -If you have a need for types to more lualib modules, feel free to open an issue or pull request on GitHub. - -## Type features - -Typed-factorio has 100% complete types for the runtime stage. Description-only concepts and some not documented types are filled in manually. - -### Lua features - -The types include [TypescriptToLua language extensions](https://typescripttolua.github.io/docs/advanced/language-extensions/) -and [lua-types](https://github.com/TypeScriptToLua/lua-types) (for v5.2) as dependencies. - -This is to use tstl features such as `LuaLengthMethod` and `LuaMultiReturn`. - -### `nil` - -The types consistently use `undefined` to represent `nil`. -`null` is not used, because `undefined` in typescript is much more similar to `nil` in lua, and optional parameters/properties already use `undefined`. - -A class attribute is marked as possibly undefined only if the _read_ type is possibly `nil`. For properties where `nil` is not possible on _read_, but is possible on _write_, you can write `nil` by using `undefined!` or `myNullableValue!`, e.g. `controlBehavior.parameters = undefined!`. - -### Variant parameter types - -Variant parameter types (types with "additional fields can be specified depending on ...") are handled as discriminated unions. This gives proper type checking for individual variants. - -The type for a specific variant is prefixed with the either variant name or "Other" for variants without additional fields, e.g. `AmmoDamageTechnologyModifier`, `OtherTechnologyModifier` - -### Events - -`script.on_event()`, `script.get/set_filters()`, and `script.raise_event()` all have type checking on the event data/filter type, inferred from what is passed as the event name/id. - -You can pass a type parameter to `script.generate_event_name()`, and it will return an `EventId` that holds type info of the event data. Event functions on `script` can then use the type data when the `EventId` is passed. - -### Array-like types - -Classes that have an index operator, a length operator, and have an array-like structure, inherit from `(Readonly)Array`. These are `LuaInventory`, `LuaFluidBox`, `LuaTransportLine`. This allows you to use these classes like arrays, meaning having array methods, and `.length` translating to the lua length operator. However, this also means, like typescript arrays, they are **0-indexed, not 1-indexed**. - -### Table or array types - -For table or array types (e.g. Position), there also are types such as `PositionTable` and `PositionArray` that refer to the table or array form specifically. - -### LuaGuiElement - -`LuaGuiElement` is broken up into a discriminated union for each gui element type (See [here](https://basarat.gitbook.io/typescript/type-system/discriminated-unions) for information on discriminated unions). The type for a specific GuiElement type is `GuiElement`, e.g. `ButtonGuiElement`. - -Similarly, the table passed to `LuaGuiElement.add`, referred to as `GuiSpec`, is also broken up into a discriminated union for each gui element type. The type for a specific GuiSpec type is `GuiSpec`, e.g. `ListBoxGuiSpec`. - -This is done both to provide more accurate types, and for possible integration with [JSX](https://typescripttolua.github.io/docs/jsx/). - -### Examples - -Check out the `test` directory on GitHub for more examples on particular type features. diff --git a/modules/mod2/typed-factorio/data/types.d.ts b/modules/mod2/typed-factorio/data/types.d.ts deleted file mode 100644 index 408f32a..0000000 --- a/modules/mod2/typed-factorio/data/types.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -export interface Data { - readonly raw: Record> - - /** - * The `data` table expects a specific format for each item in the table. Missing properties will either fall back to - * default values or give an error indicating what's missing. Extra properties that the game isn't looking for are - * simply ignored. - */ - extend(prototypes: Record[]): void -} - -/** A mapping of mod names to mod version for all enabled mods. */ -export type Mods = Record diff --git a/modules/mod2/typed-factorio/generated/builtin-types.d.ts b/modules/mod2/typed-factorio/generated/builtin-types.d.ts deleted file mode 100644 index bcd4172..0000000 --- a/modules/mod2/typed-factorio/generated/builtin-types.d.ts +++ /dev/null @@ -1,66 +0,0 @@ -/** @noSelfInFile */ - -/** - * A floating-point number. This is a single-precision floating point number. Whilst Lua only uses double-precision - * numbers, when a function takes a float, the game engine will immediately convert the double-precision number to - * single-precision. - * - * {@link https://lua-api.factorio.com/next/Builtin-Types.html#float View documentation} - */ -type float = number - -/** - * A double-precision floating-point number. This is the same data type as all Lua numbers use. - * - * {@link https://lua-api.factorio.com/next/Builtin-Types.html#double View documentation} - */ -type double = number - -/** - * 32-bit signed integer. Possible values are -2,147,483,648 to 2,147,483,647. - * - * {@link https://lua-api.factorio.com/next/Builtin-Types.html#int View documentation} - */ -type int = number - -/** - * 8-bit signed integer. Possible values are -128 to 127. - * - * {@link https://lua-api.factorio.com/next/Builtin-Types.html#int8 View documentation} - */ -type int8 = number - -/** - * 32-bit unsigned integer. Possible values are 0 to 4,294,967,295. - * - * {@link https://lua-api.factorio.com/next/Builtin-Types.html#uint View documentation} - */ -type uint = number - -/** - * 8-bit unsigned integer. Possible values are 0 to 255. - * - * {@link https://lua-api.factorio.com/next/Builtin-Types.html#uint8 View documentation} - */ -type uint8 = number - -/** - * 16-bit unsigned integer. Possible values are 0 to 65535. - * - * {@link https://lua-api.factorio.com/next/Builtin-Types.html#uint16 View documentation} - */ -type uint16 = number - -/** - * 64-bit unsigned integer. Possible values are 0 to 18,446,744,073,709,551,615. - * - * {@link https://lua-api.factorio.com/next/Builtin-Types.html#uint64 View documentation} - */ -type uint64 = number - -/** - * Tables are enclosed in curly brackets, like this `{}` - * - * {@link https://lua-api.factorio.com/next/Builtin-Types.html#table View documentation} - */ -type table = object diff --git a/modules/mod2/typed-factorio/generated/classes.d.ts b/modules/mod2/typed-factorio/generated/classes.d.ts deleted file mode 100644 index 65469c5..0000000 --- a/modules/mod2/typed-factorio/generated/classes.d.ts +++ /dev/null @@ -1,20023 +0,0 @@ -/** @noSelfInFile */ - -/** - * Collection of settings for overriding default ai behavior. - * - * {@link https://lua-api.factorio.com/next/LuaAISettings.html View documentation} - * - * @noSelf - */ -interface LuaAISettings { - /** - * If enabled, units that repeatedly fail to succeed at commands will be destroyed. - * - * {@link https://lua-api.factorio.com/next/LuaAISettings.html#LuaAISettings.allow_destroy_when_commands_fail View documentation} - */ - allow_destroy_when_commands_fail: boolean - /** - * If enabled, units that have nothing else to do will attempt to return to a spawner. - * - * {@link https://lua-api.factorio.com/next/LuaAISettings.html#LuaAISettings.allow_try_return_to_spawner View documentation} - */ - allow_try_return_to_spawner: boolean - /** - * If enabled, units will try to separate themselves from nearby friendly units. - * - * {@link https://lua-api.factorio.com/next/LuaAISettings.html#LuaAISettings.do_separation View documentation} - */ - do_separation: boolean - /** - * The pathing resolution modifier, must be between -8 and 8. - * - * {@link https://lua-api.factorio.com/next/LuaAISettings.html#LuaAISettings.path_resolution_modifier View documentation} - */ - path_resolution_modifier: int8 - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaAISettings" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Control behavior for accumulators. - * - * {@link https://lua-api.factorio.com/next/LuaAccumulatorControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaAccumulatorControlBehavior extends LuaControlBehavior { - output_signal: SignalID - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaAccumulatorControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a achievement. - * - * {@link https://lua-api.factorio.com/next/LuaAchievementPrototype.html View documentation} - * - * @noSelf - */ -interface LuaAchievementPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaAchievementPrototype.html#LuaAchievementPrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaAchievementPrototype.html#LuaAchievementPrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - readonly allowed_without_fight: boolean - readonly hidden: boolean - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaAchievementPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a ammo category. - * - * {@link https://lua-api.factorio.com/next/LuaAmmoCategoryPrototype.html View documentation} - * - * @noSelf - */ -interface LuaAmmoCategoryPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaAmmoCategoryPrototype.html#LuaAmmoCategoryPrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaAmmoCategoryPrototype.html#LuaAmmoCategoryPrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - readonly bonus_gui_order: string - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaAmmoCategoryPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Control behavior for arithmetic combinators. - * - * {@link https://lua-api.factorio.com/next/LuaArithmeticCombinatorControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaArithmeticCombinatorControlBehavior extends LuaCombinatorControlBehavior { - /** - * The arithmetic combinator parameters. - * - * **Note**: `parameters` may be `nil` in order to clear the parameters. - * - * {@link https://lua-api.factorio.com/next/LuaArithmeticCombinatorControlBehavior.html#LuaArithmeticCombinatorControlBehavior.parameters View documentation} - */ - parameters: ArithmeticCombinatorParameters - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaArithmeticCombinatorControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of an autoplace control. - * - * {@link https://lua-api.factorio.com/next/LuaAutoplaceControlPrototype.html View documentation} - * - * @noSelf - */ -interface LuaAutoplaceControlPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaAutoplaceControlPrototype.html#LuaAutoplaceControlPrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaAutoplaceControlPrototype.html#LuaAutoplaceControlPrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - readonly richness: boolean - readonly control_order: string - /** - * Category name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaAutoplaceControlPrototype.html#LuaAutoplaceControlPrototype.category View documentation} - */ - readonly category: string - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaAutoplaceControlPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -type RaiseableEvents = - | typeof defines.events.on_console_chat - | typeof defines.events.on_player_crafted_item - | typeof defines.events.on_player_fast_transferred - | typeof defines.events.on_biter_base_built - | typeof defines.events.on_market_item_purchased - | typeof defines.events.script_raised_built - | typeof defines.events.script_raised_destroy - | typeof defines.events.script_raised_revive - | typeof defines.events.script_raised_set_tiles - -/** - * Entry point for registering event handlers. It is accessible through the global object named `script`. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html View documentation} - * - * @noSelf - */ -interface LuaBootstrap { - /** - * Register a callback to be run on mod initialization. This is only called when a new save game is created or when - * a save file is loaded that previously didn't contain the mod. During it, the mod gets the chance to set up - * initial values that it will use for its lifetime. It has full access to {@link LuaGameScript} and the `global` - * table and can change anything about them that it deems appropriate. No other events will be raised for the mod - * until it has finished this step. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.on_init View documentation} - * - * @example - * Initialize a `players` table in `global` for later use. - * - * ```lua - * script.on_init(function() - * global.players = {} - * end) - * ``` - * - * @param f - The handler for this event. Passing `nil` will unregister it. - */ - on_init(f: (() => void) | undefined): void - /** - * Register a function to be run on save load. This is only called for mods that have been part of the save - * previously, or for players connecting to a running multiplayer session. It gives the mod the opportunity to do - * some very specific actions, should it need to. Doing anything other than these three will lead to desyncs, which - * breaks multiplayer and replay functionality. Access to {@link LuaGameScript} and {@link LuaRendering} is not - * available. The `global` table can be accessed and is safe to read from, but not write to. - * - * The only legitimate uses of this event are these three: - * - * - Re-setup {@link https://www.lua.org/pil/13.html metatables} as they are not persisted through save-load. - * - Re-setup conditional event handlers. - * - Create local references to data stored in the {@link https://lua-api.factorio.com/next/Global.html global} table. - * - * For all other purposes, {@link LuaBootstrap.on_init LuaBootstrap::on_init}, - * {@link LuaBootstrap.on_configuration_changed LuaBootstrap::on_configuration_changed} or migration scripts should - * be used instead. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.on_load View documentation} - * - * @param f - The handler for this event. Passing `nil` will unregister it. - */ - on_load(f: (() => void) | undefined): void - /** - * Register a function to be run when mod configuration changes. This is called when the game version or any mod - * version changes; when any mod is added or removed; or when prototypes or startup mod settings have changed. It - * allows the mod to make any changes it deems appropriate to both the data structures in its `global` table or to - * the game state through {@link LuaGameScript}. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.on_configuration_changed View documentation} - * - * @param f - The handler for this event. Passing `nil` will unregister it. - */ - on_configuration_changed(f: ((param1: ConfigurationChangedData) => void) | undefined): void - /** - * Register a handler to run on the specified event(s). Each mod can only register once for every event, as any - * additional registration will overwrite the previous one. This holds true even if different filters are used for - * subsequent registrations. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.on_event View documentation} - * - * @example - * Register for the {@link OnTickEvent on_tick} event to print the current tick to console each tick. - * - * ```lua - * script.on_event(defines.events.on_tick, - * function(event) game.print(event.tick) end) - * ``` - * - * @example - * Register for the {@link OnBuiltEntityEvent on_built_entity} event, limiting it to only be received when a `"fast-inserter"` is built. - * - * ```lua - * script.on_event(defines.events.on_built_entity, - * function(event) game.print("Gotta go fast!") end, - * {{filter = "name", name = "fast-inserter"}}) - * ``` - * - * @param event - The event(s) or custom-input to invoke the handler on. - * @param f - The handler for this event. Passing `nil` will unregister it. - * @param filters - The filters for this event. Can only be used when registering for individual events. - */ - on_event>( - event: E, - f: ((data: E["_eventData"]) => void) | undefined, - filters?: E["_filter"][] - ): void - on_event>(event: E | E[], f: ((data: E["_eventData"]) => void) | undefined): void - on_event(event: string, f: ((data: CustomInputEvent) => void) | undefined): void - /** - * Register a handler to run every nth-tick(s). When the game is on tick 0 it will trigger all registered handlers. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.on_nth_tick View documentation} - * - * @param tick - The nth-tick(s) to invoke the handler on. Passing `nil` as the only parameter will unregister all - * nth-tick handlers. - * @param f - The handler to run. Passing `nil` will unregister it for the provided nth-tick(s). - */ - on_nth_tick(tick: uint | uint[] | undefined, f: ((param1: NthTickEventData) => void) | undefined): void - /** - * Registers an entity so that after it's destroyed, {@link OnEntityDestroyedEvent on_entity_destroyed} is called. - * Once an entity is registered, it stays registered until it is actually destroyed, even through save/load cycles. - * The registration is global across all mods, meaning once one mod registers an entity, all mods listening to - * {@link OnEntityDestroyedEvent on_entity_destroyed} will receive the event when it is destroyed. Registering the - * same entity multiple times will still only fire the destruction event once, and will return the same registration number. - * - * **Note**: Depending on when a given entity is destroyed, {@link OnEntityDestroyedEvent on_entity_destroyed} will - * either be fired at the end of the current tick or at the end of the next tick. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.register_on_entity_destroyed View documentation} - * - * @param entity - The entity to register. - * @returns The registration number. It is used to identify the entity in the - * {@link OnEntityDestroyedEvent on_entity_destroyed} event. - */ - register_on_entity_destroyed(entity: LuaEntity): uint64 - /** - * Generate a new, unique event ID that can be used to raise custom events with - * {@link LuaBootstrap.raise_event LuaBootstrap::raise_event}. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.generate_event_name View documentation} - * - * @returns The newly generated event ID. - */ - generate_event_name(): CustomEventId - /** - * Find the event handler for an event. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.get_event_handler View documentation} - * - * @param event - The event identifier to get a handler for. - * @returns Reference to the function currently registered as the handler. - */ - get_event_handler>(event: E): (data: E["_eventData"]) => void - get_event_handler(event: string): (data: CustomInputEvent) => void - /** - * Gets the mod event order as a string. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.get_event_order View documentation} - */ - get_event_order(): string - /** - * Sets the filters for the given event. The filters are only retained when set after the actual event registration, - * because registering for an event with different or no filters will overwrite previously set ones. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.set_event_filter View documentation} - * - * @example - * Limit the {@link OnMarkedForDeconstructionEvent on_marked_for_deconstruction} event to only be received when a non-ghost entity is marked for deconstruction. - * - * ```lua - * script.set_event_filter(defines.events.on_marked_for_deconstruction, {{filter = "ghost", invert = true}}) - * ``` - * - * @example - * Limit the {@link OnBuiltEntityEvent on_built_entity} event to only be received when either a `unit` or a `unit-spawner` is built. - * - * ```lua - * script.set_event_filter(defines.events.on_built_entity, {{filter = "type", type = "unit"}, {filter = "type", type = "unit-spawner"}}) - * ``` - * - * @example - * Limit the {@link OnEntityDamagedEvent on_entity_damaged} event to only be received when a `rail` is damaged by an `acid` attack. - * - * ```lua - * script.set_event_filter(defines.events.on_entity_damaged, {{filter = "rail"}, {filter = "damage-type", type = "acid", mode = "and"}}) - * ``` - * - * @param event - ID of the event to filter. - * @param filters - The filters or `nil` to clear them. - */ - set_event_filter>(event: E, filters: E["_filter"][] | undefined): void - /** - * Gets the filters for the given event. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.get_event_filter View documentation} - * - * @param event - ID of the event to get. - * @returns The filters or `nil` if none are defined. - */ - get_event_filter>(event: E): E["_filter"][] | undefined - /** - * Raise an event. Only events generated with - * {@link LuaBootstrap.generate_event_name LuaBootstrap::generate_event_name} and the following can be raised: - * - * - {@link OnConsoleChatEvent on_console_chat} - * - {@link OnPlayerCraftedItemEvent on_player_crafted_item} - * - {@link OnPlayerFastTransferredEvent on_player_fast_transferred} - * - {@link OnBiterBaseBuiltEvent on_biter_base_built} - * - {@link OnMarketItemPurchasedEvent on_market_item_purchased} - * - {@link ScriptRaisedBuiltEvent script_raised_built} - * - {@link ScriptRaisedDestroyEvent script_raised_destroy} - * - {@link ScriptRaisedReviveEvent script_raised_revive} - * - {@link ScriptRaisedSetTilesEvent script_raised_set_tiles} - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_event View documentation} - * - * @example - * Raise the {@link OnConsoleChatEvent on_console_chat} event with the desired message 'from' the first player. - * - * ```lua - * local data = {player_index = 1, message = "Hello friends!"} - * script.raise_event(defines.events.on_console_chat, data) - * ``` - * - * @param event - ID of the event to raise. - * @param data - Table with extra data that will be passed to the event handler. - */ - raise_event>( - event: E, - data: Omit - ): void - /** - * Raises {@link OnConsoleChatEvent on_console_chat} with the given parameters. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_console_chat View documentation} - */ - raise_console_chat(params: { - /** The player doing the chatting. */ - readonly player_index: uint - /** The chat message to send. */ - readonly message: string - }): void - /** - * Raises {@link OnPlayerCraftedItemEvent on_player_crafted_item} with the given parameters. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_player_crafted_item View documentation} - */ - raise_player_crafted_item(params: { - /** The item that has been crafted. */ - readonly item_stack: LuaItemStack - /** The player doing the crafting. */ - readonly player_index: uint - /** The recipe used to craft this item. */ - readonly recipe: LuaRecipe - }): void - /** - * Raises {@link OnPlayerFastTransferredEvent on_player_fast_transferred} with the given parameters. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_player_fast_transferred View documentation} - */ - raise_player_fast_transferred(params: { - /** The player transferred from or to. */ - readonly player_index: uint - /** The entity transferred from or to. */ - readonly entity: LuaEntity - /** Whether the transfer was from player to entity. If `false`, the transfer was from entity to player. */ - readonly from_player: boolean - }): void - /** - * Raises {@link OnBiterBaseBuiltEvent on_biter_base_built} with the given parameters. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_biter_base_built View documentation} - */ - raise_biter_base_built(params: { - /** The entity that was built. */ - readonly entity: LuaEntity - }): void - /** - * Raises {@link OnMarketItemPurchasedEvent on_market_item_purchased} with the given parameters. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_market_item_purchased View documentation} - */ - raise_market_item_purchased(params: { - /** The player who did the purchasing. */ - readonly player_index: uint - /** The market entity. */ - readonly market: LuaEntity - /** The index of the offer purchased. */ - readonly offer_index: uint - /** The amount of offers purchased. */ - readonly count: uint - }): void - /** - * Raises {@link ScriptRaisedBuiltEvent script_raised_built} with the given parameters. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_script_built View documentation} - */ - raise_script_built(params: { - /** The entity that has been built. */ - readonly entity: LuaEntity - }): void - /** - * Raises {@link ScriptRaisedDestroyEvent script_raised_destroy} with the given parameters. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_script_destroy View documentation} - */ - raise_script_destroy(params: { - /** The entity that was destroyed. */ - readonly entity: LuaEntity - }): void - /** - * Raises {@link ScriptRaisedReviveEvent script_raised_revive} with the given parameters. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_script_revive View documentation} - */ - raise_script_revive(params: { - /** The entity that was revived. */ - readonly entity: LuaEntity - /** The tags associated with this entity, if any. */ - readonly tags?: Tags - }): void - /** - * Raises {@link ScriptRaisedSetTilesEvent script_raised_set_tiles} with the given parameters. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_script_set_tiles View documentation} - */ - raise_script_set_tiles(params: { - /** The surface whose tiles have been changed. */ - readonly surface_index: uint - /** The tiles that have been changed. */ - readonly tiles: Tile[] - }): void - /** - * The name of the mod from the environment this is used in. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.mod_name View documentation} - */ - readonly mod_name: string - /** - * Information about the currently running scenario/campaign/tutorial. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.level View documentation} - */ - readonly level: { - /** Is this level a simulation? (The main menu and 'Tips and tricks' use simulations) */ - readonly is_simulation?: boolean - /** Is this level a tutorial? */ - readonly is_tutorial?: boolean - /** The campaign name if any. */ - readonly campaign_name?: string - /** The level name. */ - readonly level_name: string - /** The mod name if any. */ - readonly mod_name?: string - } - /** - * A dictionary listing the names of all currently active mods and mapping them to their version. - * - * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.active_mods View documentation} - * - * @example - * This will print the names and versions of all active mods to the console. - * - * ```lua - * for name, version in pairs(script.active_mods) do - * game.print(name .. " version " .. version) - * end - * ``` - */ - readonly active_mods: Record - /** This object's name. */ - readonly object_name: "LuaBootstrap" -} - -/** - * A reference to the burner energy source owned by a specific {@link LuaEntity} or {@link LuaEquipment}. - * - * {@link https://lua-api.factorio.com/next/LuaBurner.html View documentation} - * - * @noSelf - */ -interface LuaBurner { - /** - * The owner of this burner energy source - * - * {@link https://lua-api.factorio.com/next/LuaBurner.html#LuaBurner.owner View documentation} - */ - readonly owner: LuaEntity | LuaEquipment - /** - * The fuel inventory. - * - * {@link https://lua-api.factorio.com/next/LuaBurner.html#LuaBurner.inventory View documentation} - */ - readonly inventory: LuaInventory - /** - * The burnt result inventory. - * - * {@link https://lua-api.factorio.com/next/LuaBurner.html#LuaBurner.burnt_result_inventory View documentation} - */ - readonly burnt_result_inventory: LuaInventory - heat: double - readonly heat_capacity: double - /** - * **Note**: Writing will silently do nothing if there's no - * {@link LuaBurner.currently_burning LuaBurner::currently_burning} set. - * - * {@link https://lua-api.factorio.com/next/LuaBurner.html#LuaBurner.remaining_burning_fuel View documentation} - */ - remaining_burning_fuel: double - /** - * **Note**: Writing automatically handles correcting - * {@link LuaBurner.remaining_burning_fuel LuaBurner::remaining_burning_fuel}. - * - * {@link https://lua-api.factorio.com/next/LuaBurner.html#LuaBurner.currently_burning View documentation} - */ - currently_burning: LuaItemPrototype - /** - * The fuel categories this burner uses. - * - * **Note**: The value in the dictionary is meaningless and exists just to allow the dictionary type for easy lookup. - * - * {@link https://lua-api.factorio.com/next/LuaBurner.html#LuaBurner.fuel_categories View documentation} - */ - readonly fuel_categories: Record - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaBurner" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a burner energy source. - * - * {@link https://lua-api.factorio.com/next/LuaBurnerPrototype.html View documentation} - * - * @noSelf - */ -interface LuaBurnerPrototype { - readonly emissions: double - readonly render_no_network_icon: boolean - readonly render_no_power_icon: boolean - readonly effectivity: double - readonly fuel_inventory_size: uint - readonly burnt_inventory_size: uint - /** - * The smoke sources for this burner prototype if any. - * - * {@link https://lua-api.factorio.com/next/LuaBurnerPrototype.html#LuaBurnerPrototype.smoke View documentation} - */ - readonly smoke: SmokeSource[] - /** - * The light flicker definition for this burner prototype if any. - * - * {@link https://lua-api.factorio.com/next/LuaBurnerPrototype.html#LuaBurnerPrototype.light_flicker View documentation} - */ - readonly light_flicker: { - readonly minimum_intensity: float - readonly maximum_intensity: float - readonly derivation_change_frequency: float - readonly derivation_change_deviation: float - readonly border_fix_speed: float - readonly minimum_light_size: float - readonly light_intensity_to_size_coefficient: float - readonly color: Color - } - /** - * **Note**: The value in the dictionary is meaningless and exists just to allow the dictionary type for easy lookup. - * - * {@link https://lua-api.factorio.com/next/LuaBurnerPrototype.html#LuaBurnerPrototype.fuel_categories View documentation} - */ - readonly fuel_categories: Record - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaBurnerPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A chunk iterator can be used for iterating chunks coordinates of a surface. - * - * The returned type is a {@link ChunkPositionAndArea} containing the chunk coordinates and its area. - * - * {@link https://lua-api.factorio.com/next/LuaChunkIterator.html View documentation} - * - * @example - * ```lua - * for chunk in some_surface.get_chunks() do - * game.player.print("x: " .. chunk.x .. ", y: " .. chunk.y) - * game.player.print("area: " .. serpent.line(chunk.area)) - * end - * ``` - * - * @noSelf - */ -interface LuaChunkIterator extends LuaIterable { - /** - * Get the next chunk position or `nil`, and increments the iterator. - * - * {@link https://lua-api.factorio.com/next/LuaChunkIterator.html#LuaChunkIterator.operator%20() View documentation} - */ - (): ChunkPositionAndArea | undefined - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaChunkIterator" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A circuit network associated with a given entity, connector, and wire type. - * - * {@link https://lua-api.factorio.com/next/LuaCircuitNetwork.html View documentation} - * - * @noSelf - */ -interface LuaCircuitNetwork { - /** - * {@link https://lua-api.factorio.com/next/LuaCircuitNetwork.html#LuaCircuitNetwork.get_signal View documentation} - * - * @param signal - The signal to read. - * @returns The current value of the signal. - */ - get_signal(signal: SignalID): int - /** - * The entity this circuit network reference is associated with - * - * {@link https://lua-api.factorio.com/next/LuaCircuitNetwork.html#LuaCircuitNetwork.entity View documentation} - */ - readonly entity: LuaEntity - /** - * The wire type this network is associated with. - * - * {@link https://lua-api.factorio.com/next/LuaCircuitNetwork.html#LuaCircuitNetwork.wire_type View documentation} - */ - readonly wire_type: defines.wire_type - /** - * The circuit connector ID on the associated entity this network was gotten from. - * - * {@link https://lua-api.factorio.com/next/LuaCircuitNetwork.html#LuaCircuitNetwork.circuit_connector_id View documentation} - */ - readonly circuit_connector_id: defines.circuit_connector_id - /** - * The circuit network signals last tick. `nil` if there are no signals. - * - * {@link https://lua-api.factorio.com/next/LuaCircuitNetwork.html#LuaCircuitNetwork.signals View documentation} - */ - readonly signals: Signal[] | undefined - /** - * The circuit networks ID. - * - * {@link https://lua-api.factorio.com/next/LuaCircuitNetwork.html#LuaCircuitNetwork.network_id View documentation} - */ - readonly network_id: uint - /** - * The number of circuits connected to this network. - * - * {@link https://lua-api.factorio.com/next/LuaCircuitNetwork.html#LuaCircuitNetwork.connected_circuit_count View documentation} - */ - readonly connected_circuit_count: uint - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaCircuitNetwork" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * {@link https://lua-api.factorio.com/next/LuaCombinatorControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaCombinatorControlBehavior extends LuaControlBehavior { - /** - * Gets the value of a specific signal sent by this combinator behavior last tick or nil if the signal didn't exist. - * - * {@link https://lua-api.factorio.com/next/LuaCombinatorControlBehavior.html#LuaCombinatorControlBehavior.get_signal_last_tick View documentation} - * - * @param signal - The signal to get - * @returns The value or `nil` if none. - */ - get_signal_last_tick(signal: SignalID): int | undefined - /** - * The circuit network signals sent by this combinator last tick. - * - * {@link https://lua-api.factorio.com/next/LuaCombinatorControlBehavior.html#LuaCombinatorControlBehavior.signals_last_tick View documentation} - */ - readonly signals_last_tick: Signal[] -} - -/** - * Allows for the registration of custom console commands. Similarly to - * {@link LuaBootstrap.on_event event subscriptions}, these don't persist through a save-and-load cycle. - * - * {@link https://lua-api.factorio.com/next/LuaCommandProcessor.html View documentation} - * - * @noSelf - */ -interface LuaCommandProcessor { - /** - * Add a custom console command. - * - * **Note**: Trying to add a command with the `name` of a game command or the name of a custom command that is - * already in use will result in an error. - * - * {@link https://lua-api.factorio.com/next/LuaCommandProcessor.html#LuaCommandProcessor.add_command View documentation} - * - * @example - * This will register a custom event called `print_tick` that prints the current tick to either the player issuing the command or to everyone on the server, depending on the command parameter. It shows the usage of the table that gets passed to any function handling a custom command. This specific example makes use of the `tick` and the optional `player_index` and `parameter` fields. The user is supposed to either call it without any parameter (`"/print_tick"`) or with the `"me"` parameter (`"/print_tick me"`). - * - * ```lua - * commands.add_command("print_tick", nil, function(command) - * if command.player_index ~= nil and command.parameter == "me" then - * game.get_player(command.player_index).print(command.tick) - * else - * game.print(command.tick) - * end - * end) - * ``` - * - * @param name - The desired name of the command (case sensitive). - * @param help - The localised help message. It will be shown to players using the `/help` command. - * @param _function - The function that will be called when this command is invoked. - */ - add_command(name: string, help: LocalisedString, _function: (param1: CustomCommandData) => void): void - /** - * Remove a custom console command. - * - * {@link https://lua-api.factorio.com/next/LuaCommandProcessor.html#LuaCommandProcessor.remove_command View documentation} - * - * @param name - The name of the command to remove (case sensitive). - * @returns Whether the command was successfully removed. Returns `false` if the command didn't exist. - */ - remove_command(name: string): boolean - /** - * Lists the custom commands registered by scripts through `LuaCommandProcessor`. - * - * {@link https://lua-api.factorio.com/next/LuaCommandProcessor.html#LuaCommandProcessor.commands View documentation} - */ - readonly commands: Record - /** - * Lists the built-in commands of the core game. The {@link https://wiki.factorio.com/Console wiki} has an overview of these. - * - * {@link https://lua-api.factorio.com/next/LuaCommandProcessor.html#LuaCommandProcessor.game_commands View documentation} - */ - readonly game_commands: Record - /** This object's name. */ - readonly object_name: "LuaCommandProcessor" -} - -/** - * Control behavior for constant combinators. - * - * {@link https://lua-api.factorio.com/next/LuaConstantCombinatorControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaConstantCombinatorControlBehavior extends LuaControlBehavior { - /** - * Sets the signal at the given index - * - * {@link https://lua-api.factorio.com/next/LuaConstantCombinatorControlBehavior.html#LuaConstantCombinatorControlBehavior.set_signal View documentation} - * - * @param index - * @param signal - */ - set_signal(index: uint, signal: Signal): void - /** - * Gets the signal at the given index. Returned {@link Signal} will not contain signal if none is set for the index. - * - * {@link https://lua-api.factorio.com/next/LuaConstantCombinatorControlBehavior.html#LuaConstantCombinatorControlBehavior.get_signal View documentation} - * - * @param index - */ - get_signal(index: uint): Signal - /** - * The constant combinator parameters - * - * **Note**: Setting to `nil` clears the parameters. - * - * {@link https://lua-api.factorio.com/next/LuaConstantCombinatorControlBehavior.html#LuaConstantCombinatorControlBehavior.parameters View documentation} - */ - parameters: ConstantCombinatorParameters[] - /** - * Turns this constant combinator on and off. - * - * {@link https://lua-api.factorio.com/next/LuaConstantCombinatorControlBehavior.html#LuaConstantCombinatorControlBehavior.enabled View documentation} - */ - enabled: boolean - /** - * The number of signals this constant combinator supports - * - * {@link https://lua-api.factorio.com/next/LuaConstantCombinatorControlBehavior.html#LuaConstantCombinatorControlBehavior.signals_count View documentation} - */ - readonly signals_count: uint - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaConstantCombinatorControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Control behavior for container entities. - * - * {@link https://lua-api.factorio.com/next/LuaContainerControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaContainerControlBehavior extends LuaControlBehavior { - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaContainerControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} - -interface BaseControlSetGuiArrow { - /** - * Where to point to. This field determines what other fields are mandatory. May be `"nowhere"`, `"goal"`, - * `"entity_info"`, `"active_window"`, `"entity"`, `"position"`, `"crafting_queue"`, or `"item_stack"`. - */ - readonly type: - | "nowhere" - | "goal" - | "entity_info" - | "active_window" - | "entity" - | "position" - | "crafting_queue" - | "item_stack" -} - -interface EntityControlSetGuiArrow extends BaseControlSetGuiArrow { - readonly type: "entity" - readonly entity: LuaEntity -} - -interface PositionControlSetGuiArrow extends BaseControlSetGuiArrow { - readonly type: "position" - readonly position: Position -} - -interface CraftingQueueControlSetGuiArrow extends BaseControlSetGuiArrow { - readonly type: "crafting_queue" - readonly crafting_queueindex: uint -} - -interface ItemStackControlSetGuiArrow extends BaseControlSetGuiArrow { - readonly type: "item_stack" - readonly inventory_index: defines.inventory - readonly item_stack_index: uint - /** May be either `"player"` or `"target"`. */ - readonly source: "player" | "target" -} - -interface OtherControlSetGuiArrow extends BaseControlSetGuiArrow { - readonly type: "nowhere" | "goal" | "entity_info" | "active_window" -} - -type ControlSetGuiArrow = - | EntityControlSetGuiArrow - | PositionControlSetGuiArrow - | CraftingQueueControlSetGuiArrow - | ItemStackControlSetGuiArrow - | OtherControlSetGuiArrow - -/** - * This is an abstract base class containing the common functionality between {@link LuaPlayer} and entities (see - * {@link LuaEntity}). When accessing player-related functions through a {@link LuaEntity}, it must refer to a character entity. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html View documentation} - * - * @noSelf - */ -interface LuaControl { - /** - * Get an inventory belonging to this entity. This can be either the "main" inventory or some auxiliary one, like - * the module slots or logistic trash slots. - * - * **Note**: A given {@link defines.inventory} is only meaningful for the corresponding LuaObject type. EG: - * get_inventory(defines.inventory.character_main) is only meaningful if 'this' is a player character. You may get a - * value back but if the type of 'this' isn't the type referred to by the {@link defines.inventory} it's almost - * guaranteed to not be the inventory asked for. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.get_inventory View documentation} - * - * @param inventory - * @returns Or `nil` if this entity doesn't have an inventory with the given index. - */ - get_inventory(inventory: defines.inventory): LuaInventory | undefined - /** - * Gets the main inventory for this character or player if this is a character or player. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.get_main_inventory View documentation} - * - * @returns Or `nil` if this entity is not a character or player. - */ - get_main_inventory(): LuaInventory | undefined - /** - * Can at least some items be inserted? - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.can_insert View documentation} - * - * @param items - Items that would be inserted. - * @returns `true` if at least a part of the given items could be inserted into this inventory. - */ - can_insert(items: ItemStackIdentification): boolean - /** - * Insert items into this entity. This works the same way as inserters or shift-clicking: the "best" inventory is - * chosen automatically. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.insert View documentation} - * - * @param items - Items to insert. - * @returns Number of items actually inserted. - */ - insert(items: ItemStackIdentification): uint - /** - * Create an arrow which points at this entity. This is used in the tutorial. For examples, see `control.lua` in the - * campaign missions. - * - * Other attributes may be specified depending on `type`: - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.set_gui_arrow View documentation} - */ - set_gui_arrow(params: ControlSetGuiArrow): void - /** - * Removes the arrow created by `set_gui_arrow`. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.clear_gui_arrow View documentation} - */ - clear_gui_arrow(): void - /** - * Get the number of all or some items in this entity. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.get_item_count View documentation} - * - * @param item - Prototype name of the item to count. If not specified, count all items. - */ - get_item_count(item?: string): uint - /** - * Does this entity have any item inside it? - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.has_items_inside View documentation} - */ - has_items_inside(): boolean - /** - * Can a given entity be opened or accessed? - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.can_reach_entity View documentation} - * - * @param entity - */ - can_reach_entity(entity: LuaEntity): boolean - /** - * Remove all items from this entity. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.clear_items_inside View documentation} - */ - clear_items_inside(): void - /** - * Remove items from this entity. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.remove_item View documentation} - * - * @param items - Items to remove. - * @returns Number of items actually removed. - */ - remove_item(items: ItemStackIdentification): uint - /** - * Teleport the entity to a given position, possibly on another surface. - * - * **Note**: Some entities may not be teleported. For instance, transport belts won't allow teleportation and this - * method will always return `false` when used on any such entity. - * - * **Note**: You can also pass 1 or 2 numbers as the parameters and they will be used as relative teleport - * coordinates `'teleport(0, 1)'` to move the entity 1 tile positive y. `'teleport(4)'` to move the entity 4 tiles - * to the positive x. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.teleport View documentation} - * - * @param position - Where to teleport to. - * @param surface - Surface to teleport to. If not given, will teleport to the entity's current surface. Only - * players, cars, and spidertrons can be teleported cross-surface. - * @returns `true` when the entity was successfully teleported. - */ - teleport(position: Position, surface?: SurfaceIdentification): boolean - /** - * Select an entity, as if by hovering the mouse above it. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.update_selected_entity View documentation} - * - * @param position - Position of the entity to select - */ - update_selected_entity(position: Position): void - /** - * Unselect any selected entity. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.clear_selected_entity View documentation} - */ - clear_selected_entity(): void - /** - * Disable the flashlight. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.disable_flashlight View documentation} - */ - disable_flashlight(): void - /** - * Enable the flashlight. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.enable_flashlight View documentation} - */ - enable_flashlight(): void - /** - * Is the flashlight enabled. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.is_flashlight_enabled View documentation} - */ - is_flashlight_enabled(): void - /** - * Gets the count of the given recipe that can be crafted. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.get_craftable_count View documentation} - * - * @param recipe - The recipe. - * @returns The count that can be crafted. - */ - get_craftable_count(recipe: string | LuaRecipe): uint - /** - * Begins crafting the given count of the given recipe. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.begin_crafting View documentation} - * - * @returns The count that was actually started crafting. - */ - begin_crafting(params: { - /** The count to craft. */ - readonly count: uint - /** The recipe to craft. */ - readonly recipe: string | LuaRecipe - /** If false and the recipe can't be crafted the requested number of times printing the failure is skipped. */ - readonly silent?: boolean - }): uint - /** - * Cancels crafting the given count of the given crafting queue index. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.cancel_crafting View documentation} - */ - cancel_crafting(params: { - /** The crafting queue index. */ - readonly index: uint - /** The count to cancel crafting. */ - readonly count: uint - }): void - /** - * Mines the given entity as if this player (or character) mined it. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.mine_entity View documentation} - * - * @param entity - The entity to mine - * @param force - Forces mining the entity even if the items can't fit in the player. - * @returns If the mining succeeded. - */ - mine_entity(entity: LuaEntity, force?: boolean): boolean - /** - * Mines the given tile as if this player (or character) mined it. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.mine_tile View documentation} - * - * @param tile - The tile to mine. - * @returns If the mining succeeded. - */ - mine_tile(tile: LuaTile): boolean - /** - * When `true` control adapter is a LuaPlayer object, `false` for entities including characters with players - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.is_player View documentation} - */ - is_player(): boolean - /** - * Open the technology GUI and select a given technology. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.open_technology_gui View documentation} - * - * @param technology - The technology to select after opening the GUI. - */ - open_technology_gui(technology?: TechnologyIdentification): void - /** - * Sets a personal logistic request and auto-trash slot to the given value. - * - * **Note**: This will silently fail if personal logistics are not researched yet. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.set_personal_logistic_slot View documentation} - * - * @param slot_index - The slot to set. - * @param value - The logistic request parameters. - * @returns Whether the slot was set successfully. - */ - set_personal_logistic_slot(slot_index: uint, value: PersonalLogisticParameters): boolean - /** - * Sets a vehicle logistic request and auto-trash slot to the given value. - * - * **Note**: This will silently fail if the vehicle does not use logistics. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.set_vehicle_logistic_slot View documentation} - * - * @param slot_index - The slot to set. - * @param value - The logistic request parameters. - * @returns Whether the slot was set successfully. - */ - set_vehicle_logistic_slot(slot_index: uint, value: PersonalLogisticParameters): boolean - /** - * Gets the parameters of a personal logistic request and auto-trash slot. - * - * **Note**: This will silently return an empty value (`name` will be `nil`) if personal logistics are not researched yet. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.get_personal_logistic_slot View documentation} - * - * @param slot_index - The slot to get. - */ - get_personal_logistic_slot(slot_index: uint): PersonalLogisticParameters - /** - * Gets the parameters of a vehicle logistic request and auto-trash slot. - * - * **Note**: This will silently return an empty value (`name` will be `nil`) if the vehicle does not use logistics. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.get_vehicle_logistic_slot View documentation} - * - * @param slot_index - The slot to get. - */ - get_vehicle_logistic_slot(slot_index: uint): PersonalLogisticParameters - /** - * **Note**: This will silently fail if personal logistics are not researched yet. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.clear_personal_logistic_slot View documentation} - * - * @param slot_index - The slot to clear. - */ - clear_personal_logistic_slot(slot_index: uint): void - /** - * **Note**: This will silently fail if the vehicle does not use logistics. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.clear_vehicle_logistic_slot View documentation} - * - * @param slot_index - The slot to clear. - */ - clear_vehicle_logistic_slot(slot_index: uint): void - /** - * Returns whether the player is holding a blueprint, it takes into account a blueprint as an item as well as - * blueprint from the blueprint record from the blueprint library. Note that the is_cursor_blueprint and - * get_cursor_blueprint_entities refer to the currently selected blueprint, so it returns blueprint related - * information also when holding a blueprint book with a blueprint being selected in it. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.is_cursor_blueprint View documentation} - */ - is_cursor_blueprint(): boolean - /** - * Gets the entities that are part of the currently selected blueprint, regardless of it being in a blueprint book - * or picked from the blueprint library. Returns `nil` if there is no currently selected blueprint. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.get_blueprint_entities View documentation} - */ - get_blueprint_entities(): BlueprintEntity[] | undefined - /** - * Returns whether the player is holding something in the cursor. It takes into account items from the blueprint - * library, as well as items and ghost cursor. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.is_cursor_empty View documentation} - */ - is_cursor_empty(): boolean - /** - * The surface this entity is currently on. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.surface View documentation} - */ - readonly surface: LuaSurface - /** - * Current position of the entity. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.position View documentation} - */ - readonly position: PositionTable - /** - * The vehicle the player is currently sitting in; `nil` if none. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.vehicle View documentation} - */ - readonly vehicle: LuaEntity | undefined - /** - * The force of this entity. Reading will always give a {@link LuaForce}, but it is possible to assign either - * {@link string} or {@link LuaForce} to this attribute to change the force. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.force View documentation} - */ - force: ForceIdentification - /** - * The currently selected entity; `nil` if none. Assigning an entity will select it if selectable otherwise clears selection. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.selected View documentation} - */ - selected: LuaEntity | undefined - /** - * The GUI target the player currently has open; `nil` if none. - * - * **Note**: Write supports any of the types. Read will return the entity, equipment, equipment-grid, player, element or nil. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.opened View documentation} - */ - opened: - | LuaEntity - | LuaItemStack - | LuaEquipment - | LuaEquipmentGrid - | LuaPlayer - | LuaGuiElement - | defines.gui_type - | undefined - /** - * Size of the crafting queue. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.crafting_queue_size View documentation} - */ - readonly crafting_queue_size: uint - /** - * The crafting queue progress [0-1] 0 when no recipe is being crafted. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.crafting_queue_progress View documentation} - */ - readonly crafting_queue_progress: double - /** - * Current walking state. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.walking_state View documentation} - * - * @example - * Make the player go north. Note that a one-shot action like this will only make the player walk for one tick. - * - * ```lua - * game.player.walking_state = {walking = true, direction = defines.direction.north} - * ``` - */ - walking_state: { - /** If `false`, the player is currently not walking; otherwise it's going somewhere */ - readonly walking: boolean - /** Direction where the player is walking */ - readonly direction: defines.direction - } - /** - * Current riding state of this car or the vehicle this player is riding in. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.riding_state View documentation} - */ - riding_state: RidingState - /** - * Current mining state. - * - * **Note**: When the player isn't mining tiles the player will mine what ever entity is currently selected. See - * {@link LuaControl.selected LuaControl::selected} and - * {@link LuaControl.update_selected_entity LuaControl::update_selected_entity}. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.mining_state View documentation} - */ - mining_state: { - /** Whether the player is mining at all */ - readonly mining: boolean - /** What tiles the player is mining; only used when the player is mining tiles (holding a tile in the cursor). */ - readonly position?: Position - } - /** - * Current shooting state. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.shooting_state View documentation} - */ - shooting_state: { - /** The current state */ - readonly state: defines.shooting - /** The position being shot at */ - readonly position: Position - } - /** - * Current item-picking state. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.picking_state View documentation} - */ - picking_state: boolean - /** - * Current repair state. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.repair_state View documentation} - */ - repair_state: { - /** The current state */ - readonly repairing: boolean - /** The position being repaired */ - readonly position: Position - } - /** - * The player's cursor stack, or `nil` if the player controller is a spectator. Even though this property is marked - * as read-only, it returns a {@link LuaItemStack}, meaning it can be manipulated like so: - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.cursor_stack View documentation} - * - * @example - * ```lua - * player.cursor_stack.clear() - * ``` - */ - readonly cursor_stack: LuaItemStack | undefined - /** - * The ghost prototype in the player's cursor. - * - * **Note**: When read, it will be a {@link LuaItemPrototype}. - * - * **Note**: Items in the cursor stack will take priority over the cursor ghost. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.cursor_ghost View documentation} - */ - cursor_ghost: ItemPrototypeIdentification - /** - * `true` if the player is in a vehicle. Writing to this attribute puts the player in or out of a vehicle. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.driving View documentation} - */ - driving: boolean - /** - * Gets the current crafting queue items. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.crafting_queue View documentation} - */ - readonly crafting_queue: CraftingQueueItem[] - /** - * The current combat robots following the character - * - * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character(see - * {@link LuaPlayer.character LuaPlayer::character}). - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.following_robots View documentation} - */ - readonly following_robots: LuaEntity[] - /** - * When `true` hand crafting is free and instant - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.cheat_mode View documentation} - */ - cheat_mode: boolean - /** - * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see - * {@link LuaPlayer.character LuaPlayer::character}). - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_crafting_speed_modifier View documentation} - */ - character_crafting_speed_modifier: double - /** - * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see - * {@link LuaPlayer.character LuaPlayer::character}). - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_mining_speed_modifier View documentation} - */ - character_mining_speed_modifier: double - /** - * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see - * {@link LuaPlayer.character LuaPlayer::character}). - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_additional_mining_categories View documentation} - */ - character_additional_mining_categories: string[] - /** - * Modifies the running speed of this character by the given value as a percentage. Setting the running modifier to - * `0.5` makes the character run 50% faster. The minimum value of `-1` reduces the movement speed by 100%, resulting - * in a speed of `0`. - * - * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see - * {@link LuaPlayer.character LuaPlayer::character}). - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_running_speed_modifier View documentation} - */ - character_running_speed_modifier: double - /** - * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see - * {@link LuaPlayer.character LuaPlayer::character}). - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_build_distance_bonus View documentation} - */ - character_build_distance_bonus: uint - /** - * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see - * {@link LuaPlayer.character LuaPlayer::character}). - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_item_drop_distance_bonus View documentation} - */ - character_item_drop_distance_bonus: uint - /** - * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see - * {@link LuaPlayer.character LuaPlayer::character}). - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_reach_distance_bonus View documentation} - */ - character_reach_distance_bonus: uint - /** - * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see - * {@link LuaPlayer.character LuaPlayer::character}). - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_resource_reach_distance_bonus View documentation} - */ - character_resource_reach_distance_bonus: uint - /** - * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see - * {@link LuaPlayer.character LuaPlayer::character}). - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_item_pickup_distance_bonus View documentation} - */ - character_item_pickup_distance_bonus: uint - /** - * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see - * {@link LuaPlayer.character LuaPlayer::character}). - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_loot_pickup_distance_bonus View documentation} - */ - character_loot_pickup_distance_bonus: uint - /** - * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see - * {@link LuaPlayer.character LuaPlayer::character}). - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_inventory_slots_bonus View documentation} - */ - character_inventory_slots_bonus: uint - /** - * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see - * {@link LuaPlayer.character LuaPlayer::character}). - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_trash_slot_count_bonus View documentation} - */ - character_trash_slot_count_bonus: uint - /** - * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see - * {@link LuaPlayer.character LuaPlayer::character}). - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_maximum_following_robot_count_bonus View documentation} - */ - character_maximum_following_robot_count_bonus: uint - /** - * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see - * {@link LuaPlayer.character LuaPlayer::character}). - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_health_bonus View documentation} - */ - character_health_bonus: float - /** - * If personal logistic requests are enabled for this character or players character. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_personal_logistic_requests_enabled View documentation} - */ - character_personal_logistic_requests_enabled: boolean - /** - * If personal logistic requests are enabled for this vehicle (spidertron). - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.vehicle_logistic_requests_enabled View documentation} - */ - vehicle_logistic_requests_enabled: boolean - /** - * Returns the {@link defines.gui_type} or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.opened_gui_type View documentation} - */ - readonly opened_gui_type: defines.gui_type | undefined - /** - * The build distance of this character or max uint when not a character or player connected to a character. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.build_distance View documentation} - */ - readonly build_distance: uint - /** - * The item drop distance of this character or max uint when not a character or player connected to a character. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.drop_item_distance View documentation} - */ - readonly drop_item_distance: uint - /** - * The reach distance of this character or max uint when not a character or player connected to a character. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.reach_distance View documentation} - */ - readonly reach_distance: uint - /** - * The item pickup distance of this character or max double when not a character or player connected to a character. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.item_pickup_distance View documentation} - */ - readonly item_pickup_distance: double - /** - * The loot pickup distance of this character or max double when not a character or player connected to a character. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.loot_pickup_distance View documentation} - */ - readonly loot_pickup_distance: double - /** - * The resource reach distance of this character or max double when not a character or player connected to a character. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.resource_reach_distance View documentation} - */ - readonly resource_reach_distance: double - /** - * If this character entity is in combat. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.in_combat View documentation} - */ - readonly in_combat: boolean - /** - * Gets the current movement speed of this character, including effects from exoskeletons, tiles, stickers and shooting. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_running_speed View documentation} - */ - readonly character_running_speed: double - /** - * Gets the current mining progress between 0 and 1 of this character, or 0 if they aren't mining. - * - * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_mining_progress View documentation} - */ - readonly character_mining_progress: double -} - -/** - * The control behavior for an entity. Inserters have logistic network and circuit network behavior logic, lamps have - * circuit logic and so on. This is an abstract base class that concrete control behaviors inherit. - * - * **Note**: An control reference becomes invalid once the control behavior is removed or the entity (see - * {@link LuaEntity}) it resides in is destroyed. - * - * {@link https://lua-api.factorio.com/next/LuaControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaControlBehavior { - /** - * {@link https://lua-api.factorio.com/next/LuaControlBehavior.html#LuaControlBehavior.get_circuit_network View documentation} - * - * @param wire - Wire color of the network connected to this entity. - * @param circuit_connector - The connector to get circuit network for. Must be specified for entities with more - * than one circuit network connector. - * @returns The circuit network or nil. - */ - get_circuit_network( - wire: defines.wire_type, - circuit_connector?: defines.circuit_connector_id - ): LuaCircuitNetwork | undefined - /** - * The concrete type of this control behavior. - * - * {@link https://lua-api.factorio.com/next/LuaControlBehavior.html#LuaControlBehavior.type View documentation} - */ - readonly type: defines.control_behavior.type - /** - * The entity this control behavior belongs to. - * - * {@link https://lua-api.factorio.com/next/LuaControlBehavior.html#LuaControlBehavior.entity View documentation} - */ - readonly entity: LuaEntity -} - -/** - * A custom tag that shows on the map view. - * - * {@link https://lua-api.factorio.com/next/LuaCustomChartTag.html View documentation} - * - * @noSelf - */ -interface LuaCustomChartTag { - /** - * Destroys this tag. - * - * {@link https://lua-api.factorio.com/next/LuaCustomChartTag.html#LuaCustomChartTag.destroy View documentation} - */ - destroy(): void - /** - * This tag's icon, if it has one. Writing `nil` removes it. - * - * {@link https://lua-api.factorio.com/next/LuaCustomChartTag.html#LuaCustomChartTag.icon View documentation} - */ - icon: SignalID | undefined - /** - * The player who last edited this tag. - * - * {@link https://lua-api.factorio.com/next/LuaCustomChartTag.html#LuaCustomChartTag.last_user View documentation} - */ - last_user: LuaPlayer - /** - * The position of this tag. - * - * {@link https://lua-api.factorio.com/next/LuaCustomChartTag.html#LuaCustomChartTag.position View documentation} - */ - readonly position: PositionTable - text: string - /** - * The unique ID for this tag on this force. - * - * {@link https://lua-api.factorio.com/next/LuaCustomChartTag.html#LuaCustomChartTag.tag_number View documentation} - */ - readonly tag_number: uint - /** - * The force this tag belongs to. - * - * {@link https://lua-api.factorio.com/next/LuaCustomChartTag.html#LuaCustomChartTag.force View documentation} - */ - readonly force: LuaForce - /** - * The surface this tag belongs to. - * - * {@link https://lua-api.factorio.com/next/LuaCustomChartTag.html#LuaCustomChartTag.surface View documentation} - */ - readonly surface: LuaSurface - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaCustomChartTag" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a custom input. - * - * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html View documentation} - * - * @noSelf - */ -interface LuaCustomInputPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * The default key sequence for this custom input. - * - * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.key_sequence View documentation} - */ - readonly key_sequence: string - /** - * The default alternative key sequence for this custom input. `nil` when not defined. - * - * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.alternative_key_sequence View documentation} - */ - readonly alternative_key_sequence: string | undefined - /** - * The linked game control name or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.linked_game_control View documentation} - */ - readonly linked_game_control: string | undefined - /** - * The consuming type: `"none"` or `"game-only"`. - * - * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.consuming View documentation} - */ - readonly consuming: "none" | "game-only" - /** - * The action that happens when this custom input is triggered. - * - * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.action View documentation} - */ - readonly action: string - /** - * If this custom input is enabled. Disabled custom inputs exist but are not used by the game. - * - * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.enabled View documentation} - */ - readonly enabled: boolean - /** - * If this custom input is enabled while using the spectator controller. - * - * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.enabled_while_spectating View documentation} - */ - readonly enabled_while_spectating: boolean - /** - * If this custom input is enabled while using the cutscene controller. - * - * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.enabled_while_in_cutscene View documentation} - */ - readonly enabled_while_in_cutscene: boolean - /** - * If this custom input will include the selected prototype (if any) when triggered. - * - * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.include_selected_prototype View documentation} - */ - readonly include_selected_prototype: boolean - /** - * The item that gets spawned when this custom input is fired or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.item_to_spawn View documentation} - */ - readonly item_to_spawn: LuaItemPrototype | undefined - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaCustomInputPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -type CustomTableIndex -/** - * Access an element of this custom table. - * - * {@link https://lua-api.factorio.com/next/LuaCustomTable.html#LuaCustomTable.operator%20[] View documentation} - */ = { - [P in K]: V -} - -/** @noSelf */ -interface LuaCustomTableMembers { - /** - * Number of elements in this table. - * - * {@link https://lua-api.factorio.com/next/LuaCustomTable.html#LuaCustomTable.operator%20# View documentation} - */ - readonly length: LuaLengthMethod - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaCustomTable" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Lazily evaluated table. For performance reasons, we sometimes return a custom table-like type instead of a native Lua - * table. This custom type lazily constructs the necessary Lua wrappers of the corresponding C++ objects, therefore - * preventing their unnecessary construction in some cases. - * - * There are some notable consequences to the usage of a custom table type rather than the native Lua table type: - * Iterating a custom table is only possible using the `pairs` Lua function; `ipairs` won't work. Another key difference - * is that custom tables cannot be serialised into a game save file -- if saving the game would require serialisation of - * a custom table, an error will be displayed and the game will not be saved. - * - * {@link https://lua-api.factorio.com/next/LuaCustomTable.html View documentation} - * - * @example - * In previous versions of Factorio, this would create a {@link LuaPlayer} instance for every player in the game, even though only one such wrapper is needed. In the current version, accessing {@link LuaGameScript.players game.players} by itself does not create any {@link LuaPlayer} instances; they are created lazily when accessed. Therefore, this example only constructs one {@link LuaPlayer} instance, no matter how many elements there are in `game.players`. - * - * ```lua - * game.players["Oxyd"].character.die() - * ``` - * - * @example - * Custom tables may be iterated using `pairs`. - * - * ```lua - * for _, p in pairs(game.players) do game.player.print(p.name); end - * ``` - * - * @example - * The following will produce no output because `ipairs` is not supported with custom tables. - * - * ```lua - * for _, p in ipairs(game.players) do game.player.print(p.name); end -- incorrect; use pairs instead - * ``` - * - * @example - * This statement will execute successfully and `global.p` will be useable as one might expect. However, as soon as the user tries to save the game, a "LuaCustomTable cannot be serialized" error will be shown. The game will remain unsaveable so long as `global.p` refers to an instance of a custom table. - * - * ```lua - * global.p = game.players -- This has high potential to make the game unsaveable - * ``` - */ -type LuaCustomTable = LuaCustomTableMembers & CustomTableIndex - -/** - * Prototype of a damage. - * - * {@link https://lua-api.factorio.com/next/LuaDamagePrototype.html View documentation} - * - * @noSelf - */ -interface LuaDamagePrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaDamagePrototype.html#LuaDamagePrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaDamagePrototype.html#LuaDamagePrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * Whether this damage type is hidden from entity tooltips. - * - * {@link https://lua-api.factorio.com/next/LuaDamagePrototype.html#LuaDamagePrototype.hidden View documentation} - */ - readonly hidden: boolean - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaDamagePrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Control behavior for decider combinators. - * - * {@link https://lua-api.factorio.com/next/LuaDeciderCombinatorControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaDeciderCombinatorControlBehavior extends LuaCombinatorControlBehavior { - /** - * The decider combinator parameters - * - * **Note**: Setting to `nil` clears the parameters. - * - * {@link https://lua-api.factorio.com/next/LuaDeciderCombinatorControlBehavior.html#LuaDeciderCombinatorControlBehavior.parameters View documentation} - */ - parameters: DeciderCombinatorParameters - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaDeciderCombinatorControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of an optimized decorative. - * - * {@link https://lua-api.factorio.com/next/LuaDecorativePrototype.html View documentation} - * - * @noSelf - */ -interface LuaDecorativePrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaDecorativePrototype.html#LuaDecorativePrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaDecorativePrototype.html#LuaDecorativePrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * The bounding box used for collision checking. - * - * {@link https://lua-api.factorio.com/next/LuaDecorativePrototype.html#LuaDecorativePrototype.collision_box View documentation} - */ - readonly collision_box: BoundingBoxTable - /** - * The collision masks this decorative uses - * - * {@link https://lua-api.factorio.com/next/LuaDecorativePrototype.html#LuaDecorativePrototype.collision_mask View documentation} - */ - readonly collision_mask: CollisionMask - readonly collision_mask_with_flags: CollisionMaskWithFlags - /** - * Autoplace specification for this decorative prototype. `nil` if none. - * - * {@link https://lua-api.factorio.com/next/LuaDecorativePrototype.html#LuaDecorativePrototype.autoplace_specification View documentation} - */ - readonly autoplace_specification: AutoplaceSpecification | undefined - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaDecorativePrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of an electric energy source. - * - * {@link https://lua-api.factorio.com/next/LuaElectricEnergySourcePrototype.html View documentation} - * - * @noSelf - */ -interface LuaElectricEnergySourcePrototype { - readonly buffer_capacity: double - readonly usage_priority: string - readonly input_flow_limit: double - readonly output_flow_limit: double - readonly drain: double - readonly emissions: double - readonly render_no_network_icon: boolean - readonly render_no_power_icon: boolean - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaElectricEnergySourcePrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * The primary interface for interacting with entities through the Lua API. Entities are everything that exists on the - * map except for tiles (see {@link LuaTile}). - * - * Most functions on LuaEntity also work when the entity is contained in a ghost. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html View documentation} - * - * @noSelf - */ -interface LuaEntity extends LuaControl { - /** - * Gets the entities output inventory if it has one. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_output_inventory View documentation} - * - * @returns A reference to the entities output inventory. - */ - get_output_inventory(): LuaInventory - /** - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_module_inventory View documentation} - * - * @returns Inventory for storing modules of this entity; `nil` if this entity has no module inventory. - */ - get_module_inventory(): LuaInventory | undefined - /** - * The fuel inventory for this entity or `nil` if this entity doesn't have a fuel inventory. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_fuel_inventory View documentation} - */ - get_fuel_inventory(): LuaInventory | undefined - /** - * The burnt result inventory for this entity or `nil` if this entity doesn't have a burnt result inventory. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_burnt_result_inventory View documentation} - */ - get_burnt_result_inventory(): LuaInventory | undefined - /** - * Damages the entity. - * - * *Can only be used if this is EntityWithHealth* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.damage View documentation} - * - * @param damage - The amount of damage to be done - * @param force - The force that will be doing the damage. - * @param type - The type of damage to be done, defaults to "impact". - * @param dealer - The entity to consider as the damage dealer. - * @returns The total damage actually applied after resistances. - */ - damage(damage: float, force: ForceIdentification, type?: string, dealer?: LuaEntity): float - /** - * Checks if the entity can be destroyed - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.can_be_destroyed View documentation} - * - * @returns If the entity can be destroyed. - */ - can_be_destroyed(): boolean - /** - * Destroys the entity. - * - * **Note**: Not all entities can be destroyed - things such as rails under trains cannot be destroyed until the - * train is moved or destroyed. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.destroy View documentation} - * - * @returns Returns `false` if the entity was valid and destruction failed, `true` in all other cases. - */ - destroy(params?: { - /** Whether neighbouring cliffs should be corrected. Defaults to `false`. */ - readonly do_cliff_correction?: boolean - /** If `true`, {@link ScriptRaisedDestroyEvent script_raised_destroy} will be called. Defaults to `false`. */ - readonly raise_destroy?: boolean - }): boolean - /** - * Give the entity a command. - * - * *Can only be used if this is Unit* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_command View documentation} - * - * @param command - */ - set_command(command: Command): void - /** - * Give the entity a distraction command. - * - * *Can only be used if this is Unit* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_distraction_command View documentation} - * - * @param command - */ - set_distraction_command(command: Command): void - /** - * Has this unit been assigned a command? - * - * *Can only be used if this is Unit* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.has_command View documentation} - */ - has_command(): boolean - /** - * Immediately kills the entity. Does nothing if the entity doesn't have health. - * - * Unlike {@link LuaEntity.destroy LuaEntity::destroy}, `die` will trigger the - * {@link OnEntityDiedEvent on_entity_died} event and the entity will produce a corpse and drop loot if it has any. - * - * **Note**: If `force` is not specified, `on_entity_died` will blame the `"neutral"` force. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.die View documentation} - * - * @example - * This function can be called with only the `cause` argument and no `force`: - * - * ```lua - * entity.die(nil, killer_entity) - * ``` - * - * @param force - The force to attribute the kill to. - * @param cause - The cause to attribute the kill to. - * @returns Whether the entity was successfully killed. - */ - die(force?: ForceIdentification, cause?: LuaEntity): boolean - /** - * Test whether this entity's prototype has a flag set. - * - * **Note**: `entity.has_flag(f)` is a shortcut for `entity.prototype.has_flag(f)`. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.has_flag View documentation} - * - * @param flag - The flag to test - * @returns `true` if the entity has the given flag set. - */ - has_flag(flag: string): boolean - /** - * Same as {@link LuaEntity.has_flag LuaEntity::has_flag} but targets the inner entity on a entity ghost. - * - * *Can only be used if this is EntityGhost* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.ghost_has_flag View documentation} - * - * @param flag - The flag to test - * @returns `true` if the entity has the given flag set. - */ - ghost_has_flag(flag: string): boolean - /** - * Offer a thing on the market. - * - * *Can only be used if this is Market* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.add_market_item View documentation} - * - * @example - * Adds market offer, 1 copper ore for 10 iron ore. - * - * ```lua - * market.add_market_item{price={{"iron-ore", 10}}, offer={type="give-item", item="copper-ore"}} - * ``` - * - * @example - * Adds market offer, 1 copper ore for 5 iron ore and 5 stone ore. - * - * ```lua - * market.add_market_item{price={{"iron-ore", 5}, {"stone", 5}}, offer={type="give-item", item="copper-ore"}} - * ``` - * - * @param offer - */ - add_market_item(offer: Offer): void - /** - * Remove an offer from a market. - * - * **Note**: The other offers are moved down to fill the gap created by removing the offer, which decrements the - * overall size of the offer array. - * - * *Can only be used if this is Market* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.remove_market_item View documentation} - * - * @param offer - Index of offer to remove. - * @returns `true` if the offer was successfully removed; `false` when the given index was not valid. - */ - remove_market_item(offer: uint): boolean - /** - * Get all offers in a market as an array. - * - * *Can only be used if this is Market* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_market_items View documentation} - */ - get_market_items(): Offer[] - /** - * Removes all offers from a market. - * - * *Can only be used if this is Market* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.clear_market_items View documentation} - */ - clear_market_items(): void - /** - * Connect two devices with a circuit wire or copper cable. Depending on which type of connection should be made, - * there are different procedures: - * - * - To connect two electric poles, `target` must be a {@link LuaEntity} that specifies another electric pole. This - * will connect them with copper cable. - * - To connect two devices with circuit wire, `target` must be a table of type {@link WireConnectionDefinition}. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.connect_neighbour View documentation} - * - * @param target - The target with which to establish a connection. - * @returns Whether the connection was successfully formed. - */ - connect_neighbour(target: LuaEntity | WireConnectionDefinition): boolean - /** - * Disconnect circuit wires or copper cables between devices. Depending on which type of connection should be cut, - * there are different procedures: - * - * - To remove all copper cables, leave the `target` parameter blank: `pole.disconnect_neighbour()`. - * - To remove all wires of a specific color, set `target` to {@link defines.wire_type.red} or {@link defines.wire_type.green}. - * - To remove a specific copper cable between two electric poles, `target` must be a {@link LuaEntity} that specifies - * the other pole: `pole1.disconnect_neighbour(pole2)`. - * - To remove a specific circuit wire, `target` must be a table of type {@link WireConnectionDefinition}. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.disconnect_neighbour View documentation} - * - * @param target - The target with which to cut a connection. - */ - disconnect_neighbour(target?: defines.wire_type | LuaEntity | WireConnectionDefinition): void - /** - * Sets the entity to be deconstructed by construction robots. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.order_deconstruction View documentation} - * - * @param force - The force whose robots are supposed to do the deconstruction. - * @param player - The player to set the last_user to if any. - * @returns If the entity was marked for deconstruction. - */ - order_deconstruction(force: ForceIdentification, player?: PlayerIdentification): boolean - /** - * Cancels deconstruction if it is scheduled, does nothing otherwise. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.cancel_deconstruction View documentation} - * - * @param force - The force who did the deconstruction order. - * @param player - The player to set the last_user to if any. - */ - cancel_deconstruction(force: ForceIdentification, player?: PlayerIdentification): void - /** - * Is this entity marked for deconstruction? - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.to_be_deconstructed View documentation} - */ - to_be_deconstructed(): boolean - /** - * Sets the entity to be upgraded by construction robots. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.order_upgrade View documentation} - * - * @returns If the entity was marked for upgrade. - */ - order_upgrade(params: { - /** The force whose robots are supposed to do the upgrade. */ - readonly force: ForceIdentification - /** The prototype of the entity to upgrade to. */ - readonly target: EntityPrototypeIdentification - readonly player?: PlayerIdentification - /** The new direction if any. */ - readonly direction?: defines.direction - }): boolean - /** - * Cancels upgrade if it is scheduled, does nothing otherwise. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.cancel_upgrade View documentation} - * - * @param force - The force who did the upgrade order. - * @param player - The player to set the last_user to if any. - * @returns If the cancel was successful. - */ - cancel_upgrade(force: ForceIdentification, player?: PlayerIdentification): boolean - /** - * Is this entity marked for upgrade? - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.to_be_upgraded View documentation} - */ - to_be_upgraded(): boolean - /** - * Get a logistic requester slot. - * - * **Note**: Useable only on entities that have requester slots. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_request_slot View documentation} - * - * @param slot - The slot index. - * @returns Contents of the specified slot; `nil` if the given slot contains no request. - */ - get_request_slot(slot: uint): SimpleItemStack | undefined - /** - * Set a logistic requester slot. - * - * **Note**: Useable only on entities that have requester slots. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_request_slot View documentation} - * - * @param request - What to request. - * @param slot - The slot index. - * @returns If the slot was set. - */ - set_request_slot(request: ItemStackIdentification, slot: uint): boolean - /** - * Clear a logistic requester slot. - * - * **Note**: Useable only on entities that have requester slots. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.clear_request_slot View documentation} - * - * @param slot - The slot index. - */ - clear_request_slot(slot: uint): void - /** - * Returns whether a craft is currently in process. It does not indicate whether progress is currently being made, - * but whether any crafting action has made progress in this machine. - * - * *Can only be used if this is CraftingMachine* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_crafting View documentation} - */ - is_crafting(): void - /** - * *Can only be used if this is Gate* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_opened View documentation} - * - * @returns `true` if this gate is currently opened. - */ - is_opened(): boolean - /** - * *Can only be used if this is Gate* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_opening View documentation} - * - * @returns `true` if this gate is currently opening. - */ - is_opening(): boolean - /** - * *Can only be used if this is Gate* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_closed View documentation} - * - * @returns `true` if this gate is currently closed. - */ - is_closed(): boolean - /** - * *Can only be used if this is Gate* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_closing View documentation} - * - * @returns `true` if this gate is currently closing - */ - is_closing(): boolean - /** - * *Can only be used if this is Gate* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.request_to_open View documentation} - * - * @param force - The force that requests the gate to be open. - * @param extra_time - Extra ticks to stay open. - */ - request_to_open(force: ForceIdentification, extra_time?: uint): void - /** - * *Can only be used if this is Gate* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.request_to_close View documentation} - * - * @param force - The force that requests the gate to be closed. - */ - request_to_close(force: ForceIdentification): void - /** - * Get a transport line of a belt or belt connectable entity. - * - * *Can only be used if this is TransportBeltConnectable* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_transport_line View documentation} - * - * @param index - Index of the requested transport line. - */ - get_transport_line(index: uint): LuaTransportLine - /** - * Get the maximum transport line index of a belt or belt connectable entity. - * - * *Can only be used if this is TransportBeltConnectable* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_max_transport_line_index View documentation} - */ - get_max_transport_line_index(): uint - /** - * *Can only be used if this is RocketSilo* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.launch_rocket View documentation} - * - * @returns `true` if the rocket was successfully launched. Return value of `false` means the silo is not ready for launch. - */ - launch_rocket(): boolean - /** - * Revive a ghost. I.e. turn it from a ghost to a real entity or tile. - * - * **Note**: If this is an entity ghost and it is successfully revived this will also return the revived entity or - * `nil` as a second return value and possibly item request proxy as the third parameter depending on value of - * return_item_request_proxy. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.revive View documentation} - * - * @returns Any items the new real entity collided with or `nil` if the ghost could not be revived. - */ - revive(params?: { - /** If `true` the function will return item request proxy as the third parameter. */ - readonly return_item_request_proxy?: boolean - /** - * If true, and an entity ghost; {@link ScriptRaisedReviveEvent script_raised_revive} will be called. Else if - * true, and a tile ghost; {@link ScriptRaisedSetTilesEvent script_raised_set_tiles} will be called. - */ - readonly raise_revive?: boolean - }): LuaMultiReturn<[undefined] | [Record, LuaEntity, LuaEntity | undefined]> - /** - * Revives a ghost silently. - * - * **Note**: If this is an entity ghost and it is successfully revived this will also return the revived entity or - * `nil` as a second return value and possibly item request proxy as the third parameter depending on value of - * return_item_request_proxy. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.silent_revive View documentation} - * - * @returns Any items the new real entity collided with or `nil` if the ghost could not be revived. - */ - silent_revive(params?: { - /** If `true` the function will return item request proxy as the third parameter. */ - readonly return_item_request_proxy?: boolean - /** - * If true, and an entity ghost; {@link ScriptRaisedReviveEvent script_raised_revive} will be called. Else if - * true, and a tile ghost; {@link ScriptRaisedSetTilesEvent script_raised_set_tiles} will be called. - */ - readonly raise_revive?: boolean - }): LuaMultiReturn<[undefined] | [Record, LuaEntity, LuaEntity | undefined]> - /** - * *Can only be used if this is Rail* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_connected_rail View documentation} - * - * @returns Rail connected in the specified manner to this one. - */ - get_connected_rail(params: { - readonly rail_direction: defines.rail_direction - readonly rail_connection_direction: defines.rail_connection_direction - }): LuaEntity - /** - * Get the rails that this signal is connected to. - * - * *Can only be used if this is RailSignal* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_connected_rails View documentation} - */ - get_connected_rails(): LuaEntity[] - /** - * Get the rail signal or train stop at the start/end of the rail segment this rail is in, or `nil` if the rail - * segment doesn't start/end with a signal nor a train stop. - * - * **Note**: A rail segment is a continuous section of rail with no branches, signals, nor train stops. - * - * *Can only be used if this is Rail* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_rail_segment_entity View documentation} - * - * @param direction - The direction of travel relative to this rail. - * @param in_else_out - If true, gets the entity at the entrance of the rail segment, otherwise gets the entity at - * the exit of the rail segment. - */ - get_rail_segment_entity(direction: defines.rail_direction, in_else_out: boolean): LuaEntity | undefined - /** - * Get the rail at the end of the rail segment this rail is in. - * - * **Note**: A rail segment is a continuous section of rail with no branches, signals, nor train stops. - * - * **Note**: This function has a second return value. A {@link defines.rail_direction} that points out of the rail - * segment from the end rail. - * - * *Can only be used if this is Rail* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_rail_segment_end View documentation} - * - * @param direction - */ - get_rail_segment_end(direction: defines.rail_direction): LuaMultiReturn<[LuaEntity, defines.rail_direction]> - /** - * Get the length of the rail segment this rail is in. - * - * **Note**: A rail segment is a continuous section of rail with no branches, signals, nor train stops. - * - * *Can only be used if this is Rail* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_rail_segment_length View documentation} - */ - get_rail_segment_length(): double - /** - * Get a rail from each rail segment that overlaps with this rail's rail segment. - * - * **Note**: A rail segment is a continuous section of rail with no branches, signals, nor train stops. - * - * *Can only be used if this is Rail* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_rail_segment_overlaps View documentation} - */ - get_rail_segment_overlaps(): LuaEntity[] - /** - * Get the filter for a slot in an inserter, loader, or logistic storage container. - * - * **Note**: The entity must allow filters. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_filter View documentation} - * - * @param slot_index - Index of the slot to get the filter for. - * @returns Prototype name of the item being filtered. `nil` if the given slot has no filter. - */ - get_filter(slot_index: uint): string | undefined - /** - * Set the filter for a slot in an inserter, loader, or logistic storage container. - * - * **Note**: The entity must allow filters. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_filter View documentation} - * - * @param slot_index - Index of the slot to set the filter for. - * @param item - Prototype name of the item to filter. - */ - set_filter(slot_index: uint, item: string): void - /** - * Gets the filter for this infinity container at the given index or `nil` if the filter index doesn't exist or is empty. - * - * *Can only be used if this is InfinityContainer* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_infinity_container_filter View documentation} - * - * @param index - The index to get. - */ - get_infinity_container_filter(index: uint): InfinityInventoryFilter | undefined - /** - * Sets the filter for this infinity container at the given index. - * - * *Can only be used if this is InfinityContainer* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_infinity_container_filter View documentation} - * - * @param index - The index to set. - * @param filter - The new filter or `nil` to clear the filter. - */ - set_infinity_container_filter(index: uint, filter: InfinityInventoryFilter | undefined): void - /** - * Gets the filter for this infinity pipe or `nil` if the filter is empty. - * - * *Can only be used if this is InfinityPipe* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_infinity_pipe_filter View documentation} - */ - get_infinity_pipe_filter(): InfinityPipeFilter | undefined - /** - * Sets the filter for this infinity pipe. - * - * *Can only be used if this is InfinityPipe* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_infinity_pipe_filter View documentation} - * - * @param filter - The new filter or `nil` to clear the filter. - */ - set_infinity_pipe_filter(filter: InfinityPipeFilter | undefined): void - /** - * Gets the heat setting for this heat interface. - * - * *Can only be used if this is HeatInterface* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_heat_setting View documentation} - */ - get_heat_setting(): HeatSetting - /** - * Sets the heat setting for this heat interface. - * - * *Can only be used if this is HeatInterface* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_heat_setting View documentation} - * - * @param filter - The new setting. - */ - set_heat_setting(filter: HeatSetting): void - /** - * Gets the control behavior of the entity (if any). - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_control_behavior View documentation} - * - * @returns The control behavior or nil. - */ - get_control_behavior(): LuaControlBehavior | undefined - /** - * Gets (and or creates if needed) the control behavior of the entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_or_create_control_behavior View documentation} - * - * @returns The control behavior or nil. - */ - get_or_create_control_behavior(): LuaControlBehavior | undefined - /** - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_circuit_network View documentation} - * - * @param wire - Wire color of the network connected to this entity. - * @param circuit_connector - The connector to get circuit network for. Must be specified for entities with more - * than one circuit network connector. - * @returns The circuit network or nil. - */ - get_circuit_network( - wire: defines.wire_type, - circuit_connector?: defines.circuit_connector_id - ): LuaCircuitNetwork | undefined - /** - * Read a single signal from the combined circuit networks. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_merged_signal View documentation} - * - * @param signal - The signal to read. - * @param circuit_connector - The connector to get signals for. Must be specified for entities with more than one - * circuit network connector. - * @returns The current value of the signal. - */ - get_merged_signal(signal: SignalID, circuit_connector?: defines.circuit_connector_id): int - /** - * The merged circuit network signals or `nil` if there are no signals. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_merged_signals View documentation} - * - * @param circuit_connector - The connector to get signals for. Must be specified for entities with more than one - * circuit network connector. - * @returns The sum of signals on both the red and green networks, or nil if it doesn't have a circuit connector. - */ - get_merged_signals(circuit_connector?: defines.circuit_connector_id): Signal[] | undefined - /** - * Whether this entity supports a backer name. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.supports_backer_name View documentation} - */ - supports_backer_name(): boolean - /** - * Copies settings from the given entity onto this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.copy_settings View documentation} - * - * @param entity - * @param by_player - If provided, the copying is done 'as' this player and - * {@link OnEntitySettingsPastedEvent on_entity_settings_pasted} is triggered. - * @returns Any items removed from this entity as a result of copying the settings. - */ - copy_settings(entity: LuaEntity, by_player?: PlayerIdentification): Record - /** - * Gets all the `LuaLogisticPoint`s that this entity owns. Optionally returns only the point specified by the index parameter. - * - * **Note**: When `index` is not given, this will be a single `LuaLogisticPoint` for most entities. For some (such - * as the player character), it can be zero or more. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_logistic_point View documentation} - * - * @param index - If provided, only returns the `LuaLogisticPoint` specified by this index. - */ - get_logistic_point(index?: defines.logistic_member_index): LuaLogisticPoint | LuaLogisticPoint[] - /** - * Plays a note with the given instrument and note. - * - * *Can only be used if this is ProgrammableSpeaker* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.play_note View documentation} - * - * @param instrument - * @param note - * @returns If the request is valid. The sound may or may not be played depending on polyphony settings. - */ - play_note(instrument: uint, note: uint): boolean - /** - * Connects the rolling stock in the given direction. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.connect_rolling_stock View documentation} - * - * @param direction - * @returns If any connection was made - */ - connect_rolling_stock(direction: defines.rail_direction): boolean - /** - * Tries to disconnect this rolling stock in the given direction. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.disconnect_rolling_stock View documentation} - * - * @param direction - * @returns If anything was disconnected - */ - disconnect_rolling_stock(direction: defines.rail_direction): boolean - /** - * Reconnect loader, beacon, cliff and mining drill connections to entities that might have been teleported out or - * in by the script. The game doesn't do this automatically as we don't want to loose performance by checking this - * in normal games. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.update_connections View documentation} - */ - update_connections(): void - /** - * Current recipe being assembled by this machine or `nil` if no recipe is set. - * - * *Can only be used if this is CraftingMachine* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_recipe View documentation} - */ - get_recipe(): LuaRecipe | undefined - /** - * Sets the current recipe in this assembly machine. - * - * *Can only be used if this is CraftingMachine* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_recipe View documentation} - * - * @param recipe - The new recipe or `nil` to clear the recipe. - * @returns Any items removed from this entity as a result of setting the recipe. - */ - set_recipe(recipe: string | LuaRecipe | undefined): Record - /** - * Rotates this entity as if the player rotated it. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.rotate View documentation} - * - * @returns Whether the rotation was successful. - */ - rotate(params?: { - /** If `true`, rotate the entity in the counter-clockwise direction. */ - readonly reverse?: boolean - readonly by_player?: PlayerIdentification - /** If the player is not given should extra items be spilled or returned as a second return value from this. */ - readonly spill_items?: boolean - /** When true, each spilled item will be flagged with the {@link LuaEntity.to_be_looted LuaEntity::to_be_looted} flag. */ - readonly enable_looted?: boolean - /** When provided the spilled items will be marked for deconstruction by this force. */ - readonly force?: LuaForce | string - }): boolean - /** - * Gets the driver of this vehicle if any. - * - * **Note**: May be `nil` if the vehicle contains no driver. To check if there's a passenger see - * {@link LuaEntity.get_passenger LuaEntity::get_passenger}. - * - * *Can only be used if this is Vehicle* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_driver View documentation} - */ - get_driver(): LuaEntity | LuaPlayer | undefined - /** - * Sets the driver of this vehicle. - * - * **Note**: This differs over {@link LuaEntity.set_passenger LuaEntity::set_passenger} in that the passenger can't - * drive the vehicle. - * - * *Can only be used if this is Vehicle* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_driver View documentation} - * - * @param driver - The new driver or `nil` to eject the current driver if any. - */ - set_driver(driver: LuaEntity | PlayerIdentification | undefined): void - /** - * Gets the passenger of this car or spidertron if any. - * - * **Note**: May be `nil` if the vehicle contains no passenger. To check if there's a driver see - * {@link LuaEntity.get_driver LuaEntity::get_driver}. - * - * **Note**: This differs over {@link LuaEntity.get_driver LuaEntity::get_driver} in that the passenger can't drive the car. - * - * *Can only be used if this is Vehicle* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_passenger View documentation} - */ - get_passenger(): LuaEntity | LuaPlayer | undefined - /** - * Sets the passenger of this car or spidertron. - * - * **Note**: This differs over {@link LuaEntity.get_driver LuaEntity::get_driver} in that the passenger can't drive the car. - * - * *Can only be used if this is Vehicle* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_passenger View documentation} - * - * @param passenger - */ - set_passenger(passenger: LuaEntity | PlayerIdentification): void - /** - * Returns true if this entity is connected to an electric network. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_connected_to_electric_network View documentation} - */ - is_connected_to_electric_network(): boolean - /** - * The trains scheduled to stop at this train stop. - * - * *Can only be used if this is TrainStop* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_train_stop_trains View documentation} - */ - get_train_stop_trains(): LuaTrain[] - /** - * The train currently stopped at this train stop or `nil` if none. - * - * *Can only be used if this is TrainStop* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_stopped_train View documentation} - */ - get_stopped_train(): LuaTrain | undefined - /** - * Clones this entity. - * - * **Note**: {@link defines.events.on_entity_cloned} is raised. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.clone View documentation} - * - * @returns The cloned entity or `nil` if this entity can't be cloned/can't be cloned to the given location. - */ - clone(params: { - /** The destination position */ - readonly position: Position - /** The destination surface */ - readonly surface?: LuaSurface - readonly force?: ForceIdentification - /** If false, the building effect smoke will not be shown around the new entity. */ - readonly create_build_effect_smoke?: boolean - }): LuaEntity | undefined - /** - * Get the amount of all or some fluid in this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_fluid_count View documentation} - * - * @param fluid - Prototype name of the fluid to count. If not specified, count all fluids. - */ - get_fluid_count(fluid?: string): double - /** - * Get amounts of all fluids in this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_fluid_contents View documentation} - * - * @returns The amounts, indexed by fluid names. - */ - get_fluid_contents(): Record - /** - * Remove fluid from this entity. - * - * **Note**: If temperature is given only fluid matching that exact temperature is removed. If minimum and maximum - * is given fluid within that range is removed. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.remove_fluid View documentation} - * - * @returns Amount of fluid actually removed. - */ - remove_fluid(params: { - /** Fluid prototype name. */ - readonly name: string - /** Amount to remove */ - readonly amount: double - readonly minimum_temperature?: double - readonly maximum_temperature?: double - readonly temperature?: double - }): double - /** - * Insert fluid into this entity. Fluidbox is chosen automatically. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.insert_fluid View documentation} - * - * @param fluid - Fluid to insert. - * @returns Amount of fluid actually inserted. - */ - insert_fluid(fluid: Fluid): double - /** - * Remove all fluids from this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.clear_fluid_inside View documentation} - */ - clear_fluid_inside(): void - /** - * Get the source of this beam. - * - * *Can only be used if this is Beam* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_beam_source View documentation} - */ - get_beam_source(): BeamTarget - /** - * Set the source of this beam. - * - * *Can only be used if this is Beam* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_beam_source View documentation} - * - * @param source - */ - set_beam_source(source: LuaEntity | Position): void - /** - * Get the target of this beam. - * - * *Can only be used if this is Beam* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_beam_target View documentation} - */ - get_beam_target(): BeamTarget - /** - * Set the target of this beam. - * - * *Can only be used if this is Beam* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_beam_target View documentation} - * - * @param target - */ - set_beam_target(target: LuaEntity | Position): void - /** - * The radius of this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_radius View documentation} - */ - get_radius(): double - /** - * The health ratio of this entity between 1 and 0 (for full health and no health respectively). - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_health_ratio View documentation} - */ - get_health_ratio(): float - /** - * Creates the same smoke that is created when you place a building by hand. You can play the building sound to go - * with it by using {@link LuaSurface.play_sound LuaSurface::play_sound}, eg: - * entity.surface.play_sound{path="entity-build/"..entity.prototype.name, position=entity.position} - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.create_build_effect_smoke View documentation} - */ - create_build_effect_smoke(): void - /** - * Release the unit from the spawner which spawned it. This allows the spawner to continue spawning additional units. - * - * *Can only be used if this is Unit* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.release_from_spawner View documentation} - */ - release_from_spawner(): void - /** - * Toggle this entity's equipment movement bonus. Does nothing if the entity does not have an equipment grid. - * - * **Note**: This property can also be read and written on the equipment grid of this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.toggle_equipment_movement_bonus View documentation} - */ - toggle_equipment_movement_bonus(): void - /** - * If this character can shoot the given entity or position. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.can_shoot View documentation} - * - * @param target - * @param position - */ - can_shoot(target: LuaEntity, position: Position): boolean - /** - * Only works if the entity is a speech-bubble, with an "effect" defined in its wrapper_flow_style. Starts animating - * the opacity of the speech bubble towards zero, and destroys the entity when it hits zero. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.start_fading_out View documentation} - */ - start_fading_out(): void - /** - * Returns the new entity prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_upgrade_target View documentation} - * - * @returns Nil if this entity is not marked for upgrade. - */ - get_upgrade_target(): LuaEntityPrototype | undefined - /** - * Returns the new entity direction after upgrading. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_upgrade_direction View documentation} - * - * @returns Nil if this entity is not marked for upgrade. - */ - get_upgrade_direction(): defines.direction | undefined - /** - * Returns the amount of damage to be taken by this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_damage_to_be_taken View documentation} - */ - get_damage_to_be_taken(): float - /** - * Depletes and destroys this resource entity. - * - * *Can only be used if this is ResourceEntity* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.deplete View documentation} - */ - deplete(): void - /** - * Mines this entity. - * - * **Note**: 'standard' operation is to keep calling mine() with an inventory until all items are transferred and - * the items dealt with. - * - * **Note**: The result of mining the entity (the item(s) it produces when mined) will be dropped on the ground if - * they don't fit into the provided inventory. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.mine View documentation} - * - * @returns Whether mining succeeded. - */ - mine(params?: { - /** - * If provided the item(s) will be transferred into this inventory. If provided, this must be an inventory - * created with {@link LuaGameScript.create_inventory LuaGameScript::create_inventory} or be a basic inventory - * owned by some entity. - */ - readonly inventory?: LuaInventory - /** - * If true, when the item(s) don't fit into the given inventory the entity is force mined. If false, the mining - * operation fails when there isn't enough room to transfer all of the items into the inventory. Defaults to - * false. This is ignored and acts as 'true' if no inventory is provided. - */ - readonly force?: boolean - /** If true, {@link ScriptRaisedDestroyEvent script_raised_destroy} will be raised. Defaults to true. */ - readonly raise_destroyed?: boolean - /** - * If true, the minable state of the entity is ignored. Defaults to false. If false, an entity that isn't - * minable (set as not-minable in the prototype or isn't minable for other reasons) will fail to be mined. - */ - readonly ignore_minable?: boolean - }): boolean - /** - * Triggers spawn_decoration actions defined in the entity prototype or does nothing if entity is not "turret" or - * "unit-spawner". - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.spawn_decorations View documentation} - */ - spawn_decorations(): void - /** - * Can wires reach between these entities. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.can_wires_reach View documentation} - * - * @param entity - */ - can_wires_reach(entity: LuaEntity): boolean - /** - * Gets rolling stock connected to the given end of this stock - * - * **Note**: This will also return {@link defines.rail_direction} of other rolling stock that is connected back to - * this rolling stock - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_connected_rolling_stock View documentation} - * - * @param direction - * @returns One of connected rolling stocks - */ - get_connected_rolling_stock(direction: defines.rail_direction): LuaEntity - /** - * Is this entity or tile ghost or item request proxy registered for construction? If false, it means a construction - * robot has been dispatched to build the entity, or it is not an entity that can be constructed. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_registered_for_construction View documentation} - */ - is_registered_for_construction(): boolean - /** - * Is this entity registered for deconstruction with this force? If false, it means a construction robot has been - * dispatched to deconstruct it, or it is not marked for deconstruction. This is worst-case O(N) complexity where N - * is the current number of things in the deconstruct queue. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_registered_for_deconstruction View documentation} - * - * @param force - The force construction manager to check. - */ - is_registered_for_deconstruction(force: ForceIdentification): boolean - /** - * Is this entity registered for upgrade? If false, it means a construction robot has been dispatched to upgrade it, - * or it is not marked for upgrade. This is worst-case O(N) complexity where N is the current number of things in - * the upgrade queue. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_registered_for_upgrade View documentation} - */ - is_registered_for_upgrade(): boolean - /** - * Is this entity registered for repair? If false, it means a construction robot has been dispatched to upgrade it, - * or it is not damaged. This is worst-case O(N) complexity where N is the current number of things in the repair queue. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_registered_for_repair View documentation} - */ - is_registered_for_repair(): boolean - /** - * Adds the given position to this spidertron's autopilot's queue of destinations. - * - * *Can only be used if this is SpiderVehicle* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.add_autopilot_destination View documentation} - * - * @param position - The position the spidertron should move to. - */ - add_autopilot_destination(position: Position): void - /** - * Connects current linked belt with another one. - * - * Neighbours have to be of different type. If given linked belt is connected to something else it will be - * disconnected first. If provided neighbour is connected to something else it will also be disconnected first. - * Automatically updates neighbour to be connected back to this one. - * - * **Note**: Can also be used on entity ghost if it contains linked-belt - * - * *Can only be used if this is LinkedBelt* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.connect_linked_belts View documentation} - * - * @param neighbour - Another linked belt or entity ghost containing linked belt to connect or nil to disconnect - */ - connect_linked_belts(neighbour: LuaEntity | undefined): void - /** - * Disconnects linked belt from its neighbour. - * - * **Note**: Can also be used on entity ghost if it contains linked-belt - * - * *Can only be used if this is LinkedBelt* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.disconnect_linked_belts View documentation} - */ - disconnect_linked_belts(): void - /** - * Name of the entity prototype. E.g. "inserter" or "filter-inserter". - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.name View documentation} - */ - readonly name: "inserter" | "filter-inserter" - /** - * Name of the entity or tile contained in this ghost - * - * *Can only be used if this is Ghost* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.ghost_name View documentation} - */ - readonly ghost_name: string - /** - * Localised name of the entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.localised_name View documentation} - */ - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * Localised name of the entity or tile contained in this ghost. - * - * *Can only be used if this is Ghost* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.ghost_localised_name View documentation} - */ - readonly ghost_localised_name: LocalisedString - /** - * *Can only be used if this is Ghost* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.ghost_localised_description View documentation} - */ - readonly ghost_localised_description: LocalisedString - /** - * The entity prototype type of this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.type View documentation} - */ - readonly type: string - /** - * The prototype type of the entity or tile contained in this ghost. - * - * *Can only be used if this is Ghost* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.ghost_type View documentation} - */ - readonly ghost_type: string - /** - * Deactivating an entity will stop all its operations (car will stop moving, inserters will stop working, fish will - * stop moving etc). - * - * **Note**: Entities that are not active naturally can't be set to be active (setting it to be active will do nothing) - * - * **Note**: Ghosts, simple smoke, and corpses can't be modified at this time. - * - * **Note**: It is even possible to set the character to not be active, so he can't move and perform most of the tasks. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.active View documentation} - */ - active: boolean - /** - * When the entity is not destructible it can't be damaged. - * - * **Note**: An indestructible entity can still be mined. - * - * **Note**: Entities that are indestructible naturally (they have no health, like smoke, resource etc) can't be set - * to be destructible. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.destructible View documentation} - */ - destructible: boolean - /** - * **Note**: Not minable entities can still be destroyed. - * - * **Note**: Entities that are not minable naturally (like smoke, character, enemy units etc) can't be set to minable. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.minable View documentation} - */ - minable: boolean - /** - * When entity is not to be rotatable (inserter, transport belt etc), it can't be rotated by player using the R key. - * - * **Note**: Entities that are not rotatable naturally (like chest or furnace) can't be set to be rotatable. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.rotatable View documentation} - */ - rotatable: boolean - /** - * Player can't open gui of this entity and he can't quick insert/input stuff in to the entity when it is not operable. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.operable View documentation} - */ - operable: boolean - /** - * The current health of the entity, or `nil` if it doesn't have health. Health is automatically clamped to be - * between `0` and max health (inclusive). Entities with a health of `0` can not be attacked. - * - * **Note**: To get the maximum possible health of this entity, see - * {@link LuaEntityPrototype.max_health LuaEntityPrototype::max_health} on its prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.health View documentation} - */ - health: float | undefined - /** - * The current direction this entity is facing. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.direction View documentation} - */ - direction: defines.direction - /** - * Whether the entity has direction. When it is false for this entity, it will always return north direction when asked for. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.supports_direction View documentation} - */ - readonly supports_direction: boolean - /** - * The smooth orientation of this entity, if it supports orientation. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.orientation View documentation} - */ - orientation: RealOrientation - /** - * The orientation of this cliff. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.cliff_orientation View documentation} - */ - readonly cliff_orientation: CliffOrientation - /** - * The relative orientation of the vehicle turret, artillery turret, artillery wagon or `nil` if this entity isn't a - * vehicle with a vehicle turret or artillery turret/wagon. - * - * **Note**: Writing does nothing if the vehicle doesn't have a turret. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.relative_turret_orientation View documentation} - */ - relative_turret_orientation: RealOrientation | undefined - /** - * The torso orientation of this spider vehicle. - * - * *Can only be used if this is SpiderVehicle* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.torso_orientation View documentation} - */ - torso_orientation: RealOrientation - /** - * Count of resource units contained. - * - * *Can only be used if this is ResourceEntity* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.amount View documentation} - */ - amount: uint - /** - * Count of initial resource units contained. - * - * **Note**: If this is not an infinite resource reading will give `nil` and writing will give an error. - * - * *Can only be used if this is ResourceEntity* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.initial_amount View documentation} - */ - initial_amount: uint | undefined - /** - * Multiplies the acceleration the vehicle can create for one unit of energy. By default is `1`. - * - * *Can only be used if this is Car* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.effectivity_modifier View documentation} - */ - effectivity_modifier: float - /** - * Multiplies the energy consumption. - * - * *Can only be used if this is Car* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.consumption_modifier View documentation} - */ - consumption_modifier: float - /** - * Multiplies the car friction rate. - * - * *Can only be used if this is Car* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.friction_modifier View documentation} - * - * @example - * This will allow the car to go much faster - * - * ```lua - * game.player.vehicle.friction_modifier = 0.5 - * ``` - */ - friction_modifier: float - /** - * Whether the driver of this car or spidertron is the gunner, if false, the passenger is the gunner. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.driver_is_gunner View documentation} - */ - driver_is_gunner: boolean - /** - * Read when this spidertron auto-targets enemies - * - * *Can only be used if this is SpiderVehicle* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.vehicle_automatic_targeting_parameters View documentation} - */ - vehicle_automatic_targeting_parameters: VehicleAutomaticTargetingParameters - /** - * The current speed of this car in tiles per tick, rolling stock, projectile or spider vehicle, or current max - * speed of the unit. Only the speed of units, cars, and projectiles are writable. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.speed View documentation} - */ - speed: float - /** - * The current speed of this unit in tiles per tick, taking into account any walking speed modifier given by the - * tile the unit is standing on. - * - * *Can only be used if this is Unit* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.effective_speed View documentation} - */ - readonly effective_speed: float - /** - * *Can only be used if this is ItemEntity* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.stack View documentation} - */ - readonly stack: LuaItemStack - /** - * The entity prototype of this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.prototype View documentation} - */ - readonly prototype: LuaEntityPrototype - /** - * The prototype of the entity or tile contained in this ghost. - * - * *Can only be used if this is Ghost* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.ghost_prototype View documentation} - */ - readonly ghost_prototype: LuaEntityPrototype | LuaTilePrototype - /** - * Position where the entity puts its stuff. - * - * **Note**: Meaningful only for entities that put stuff somewhere, such as mining drills or inserters. Mining - * drills can't have their drop position changed; inserters must have `allow_custom_vectors` set to true on their - * prototype to allow changing the drop position. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.drop_position View documentation} - */ - drop_position: Position - /** - * Where the inserter will pick up items from. - * - * **Note**: Inserters must have `allow_custom_vectors` set to true on their prototype to allow changing the pickup position. - * - * *Can only be used if this is Inserter* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.pickup_position View documentation} - */ - pickup_position: Position - /** - * The entity this entity is putting its stuff to or `nil` if there is no such entity. - * - * **Note**: Meaningful only for entities that put stuff somewhere, such as mining drills or inserters. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.drop_target View documentation} - */ - drop_target: LuaEntity | undefined - /** - * The entity the inserter will attempt to pick up from. For example, this can be a transport belt or a storage chest. - * - * *Can only be used if this is Inserter* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.pickup_target View documentation} - */ - pickup_target: LuaEntity - /** - * Index of the currently selected weapon slot of this character, car, or spidertron, or `nil` if the car/spidertron - * doesn't have guns. - * - * *Can only be used if this is Character or Car* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.selected_gun_index View documentation} - */ - selected_gun_index: uint | undefined - /** - * Energy stored in the entity (heat in furnace, energy stored in electrical devices etc.). always 0 for entities - * that don't have the concept of energy stored inside. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.energy View documentation} - * - * @example - * ```lua - * game.player.print("Machine energy: " .. game.player.selected.energy .. "J") - * game.player.selected.energy = 3000 - * ``` - */ - energy: double - /** - * The temperature of this entities heat energy source if this entity uses a heat energy source or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.temperature View documentation} - */ - temperature: double | undefined - /** - * The previous recipe this furnace was using or nil if the furnace had no previous recipe. - * - * *Can only be used if this is Furnace* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.previous_recipe View documentation} - */ - readonly previous_recipe: LuaRecipe | undefined - /** - * The item stack currently held in an inserter's hand. - * - * *Can only be used if this is Inserter* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.held_stack View documentation} - */ - readonly held_stack: LuaItemStack - /** - * Current position of the inserter's "hand". - * - * *Can only be used if this is Inserter* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.held_stack_position View documentation} - */ - readonly held_stack_position: PositionTable - /** - * The train this rolling stock belongs to or nil if not rolling stock. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.train View documentation} - */ - readonly train: LuaTrain | undefined - /** - * - When called on an electric pole, this is a dictionary of all connections, indexed by the strings `"copper"`, - * `"red"`, and `"green"`. - * - When called on a pipe-connectable entity, this is an array of entity arrays of all entities a given fluidbox is - * connected to. - * - When called on an underground transport belt, this is the other end of the underground belt connection, or `nil` if none. - * - When called on a wall-connectable entity or reactor, this is a dictionary of all connections indexed by the - * connection direction "north", "south", "east", and "west". - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.neighbours View documentation} - */ - readonly neighbours: Record | LuaEntity[][] | LuaEntity | undefined - /** - * The belt connectable neighbours of this belt connectable entity. Only entities that input to or are outputs of - * this entity. Does not contain the other end of an underground belt, see - * {@link LuaEntity.neighbours LuaEntity::neighbours} for that. This is a dictionary with `"inputs"`, `"outputs"` - * entries that are arrays of transport belt connectable entities, or empty tables if no entities. - * - * *Can only be used if this is TransportBeltConnectable* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.belt_neighbours View documentation} - */ - readonly belt_neighbours: Record - /** - * Fluidboxes of this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.fluidbox View documentation} - */ - fluidbox: LuaFluidBox - /** - * The backer name assigned to this entity, or `nil` if this entity doesn't support backer names. Entities that - * support backer names are labs, locomotives, radars, roboports, and train stops. - * - * **Note**: While train stops get the name of a backer when placed down, players can rename them if they want to. - * In this case, `backer_name` returns the player-given name of the entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.backer_name View documentation} - */ - backer_name: string | undefined - /** - * The label of this entity if it has one or `nil`. Changing the value will trigger on_entity_renamed event - * - * **Note**: only usable on entities that have labels (currently only spider-vehicles). - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.entity_label View documentation} - */ - entity_label: string | undefined - /** - * The ticks left before a ghost, combat robot, highlight box or smoke with trigger is destroyed. - * - * - For ghosts set to uint32 max (4,294,967,295) to never expire. - * - For ghosts Cannot be set higher than {@link LuaForce.ghost_time_to_live LuaForce::ghost_time_to_live} of the entity's force. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.time_to_live View documentation} - */ - time_to_live: uint - /** - * The character, rolling stock, train stop, car, spider-vehicle, flying text, corpse or simple-entity-with-owner - * color. Returns `nil` if this entity doesn't use custom colors. - * - * **Note**: Car color is overridden by the color of the current driver/passenger, if there is one. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.color View documentation} - */ - color: Color | undefined - /** - * The text of this flying-text entity. - * - * *Can only be used if this is FlyingText* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.text View documentation} - */ - text: LocalisedString - /** - * The state of this rail signal. - * - * *Can only be used if this is RailSignal* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.signal_state View documentation} - */ - readonly signal_state: defines.signal_state - /** - * The state of this chain signal. - * - * *Can only be used if this is RailChainSignal* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.chain_signal_state View documentation} - */ - readonly chain_signal_state: defines.chain_signal_state - /** - * Will this entity be picked up automatically when the player walks over it? - * - * *Can only be used if this is ItemEntity* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.to_be_looted View documentation} - */ - to_be_looted: boolean - /** - * The current crafting speed, including speed bonuses from modules and beacons. - * - * *Can only be used if this is CraftingMachine* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.crafting_speed View documentation} - */ - readonly crafting_speed: double - /** - * The current crafting progress, as a number in range [0, 1]. - * - * *Can only be used if this is CraftingMachine* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.crafting_progress View documentation} - */ - crafting_progress: float - /** - * The current productivity bonus progress, as a number in range [0, 1]. - * - * *Can only be used if this is CraftingMachine* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.bonus_progress View documentation} - */ - bonus_progress: double - /** - * The productivity bonus of this entity. - * - * **Note**: This includes force based bonuses as well as beacon/module bonuses. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.productivity_bonus View documentation} - */ - readonly productivity_bonus: double - /** - * The pollution bonus of this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.pollution_bonus View documentation} - */ - readonly pollution_bonus: double - /** - * The speed bonus of this entity. - * - * **Note**: This includes force based bonuses as well as beacon/module bonuses. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.speed_bonus View documentation} - */ - readonly speed_bonus: double - /** - * The consumption bonus of this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.consumption_bonus View documentation} - */ - readonly consumption_bonus: double - /** - * `"input"` or `"output"`, depending on whether this underground belt goes down or up. - * - * *Can only be used if this is TransportBeltToGround* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.belt_to_ground_type View documentation} - */ - readonly belt_to_ground_type: "input" | "output" - /** - * `"input"` or `"output"`, depending on whether this loader puts to or gets from a container. - * - * *Can only be used if this is Loader* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.loader_type View documentation} - */ - loader_type: "input" | "output" - /** - * Number of rocket parts in the silo. - * - * *Can only be used if this is RocketSilo* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.rocket_parts View documentation} - */ - rocket_parts: uint - /** - * The logistic network this entity is a part of. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.logistic_network View documentation} - */ - logistic_network: LuaLogisticNetwork - /** - * The logistic cell this entity is a part of. Will be `nil` if this entity is not a part of any logistic cell. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.logistic_cell View documentation} - */ - readonly logistic_cell: LuaLogisticCell | undefined - /** - * Items this ghost will request when revived or items this item request proxy is requesting. Result is a dictionary - * mapping each item prototype name to the required count. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.item_requests View documentation} - */ - item_requests: Record - /** - * The player connected to this character or `nil` if none. - * - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.player View documentation} - */ - readonly player: LuaPlayer | undefined - /** - * The unit group this unit is a member of, or `nil` if none. - * - * *Can only be used if this is Unit* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.unit_group View documentation} - */ - readonly unit_group: LuaUnitGroup | undefined - /** - * The damage dealt by this turret, artillery turret, or artillery wagon. - * - * *Can only be used if this is Turret* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.damage_dealt View documentation} - */ - damage_dealt: double - /** - * The number of units killed by this turret, artillery turret, or artillery wagon. - * - * *Can only be used if this is Turret* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.kills View documentation} - */ - kills: uint - /** - * The last player that changed any setting on this entity. This includes building the entity, changing its color, - * or configuring its circuit network. Can be `nil` if the last user is not part of the save anymore. Mods can - * overwrite it if desired. - * - * *Can only be used if this is EntityWithOwner* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.last_user View documentation} - */ - last_user: LuaPlayer | undefined - /** - * The buffer size for the electric energy source or nil if the entity doesn't have an electric energy source. - * - * **Note**: Write access is limited to the ElectricEnergyInterface type - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.electric_buffer_size View documentation} - */ - electric_buffer_size: double | undefined - /** - * The input flow limit for the electric energy source or nil if the entity doesn't have an electric energy source. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.electric_input_flow_limit View documentation} - */ - readonly electric_input_flow_limit: double | undefined - /** - * The output flow limit for the electric energy source or nil if the entity doesn't have an electric energy source. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.electric_output_flow_limit View documentation} - */ - readonly electric_output_flow_limit: double | undefined - /** - * The electric drain for the electric energy source or nil if the entity doesn't have an electric energy source. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.electric_drain View documentation} - */ - readonly electric_drain: double | undefined - /** - * The emissions for the electric energy source or nil if the entity doesn't have an electric energy source. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.electric_emissions View documentation} - */ - readonly electric_emissions: double | undefined - /** - * The unit number or nil if the entity doesn't have one. This is universally unique for every entity that has one, - * for the lifetime of a whole game. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.unit_number View documentation} - */ - readonly unit_number: uint | undefined - /** - * The unit number of the entity contained in this ghost or nil if the entity doesn't have one. - * - * *Can only be used if this is EntityGhost* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.ghost_unit_number View documentation} - */ - readonly ghost_unit_number: uint | undefined - /** - * The mining progress for this mining drill or `nil` if this isn't a mining drill. Is a number in range [0, - * mining_target.prototype.mineable_properties.mining_time] - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.mining_progress View documentation} - */ - mining_progress: double | undefined - /** - * The bonus mining progress for this mining drill or `nil` if this isn't a mining drill. Read yields a number in - * range [0, mining_target.prototype.mineable_properties.mining_time] - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.bonus_mining_progress View documentation} - */ - bonus_mining_progress: double | undefined - /** - * The power production specific to the ElectricEnergyInterface entity type. - * - * *Can only be used if this is ElectricEnergyInterface* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.power_production View documentation} - */ - power_production: double - /** - * The power usage specific to the ElectricEnergyInterface entity type. - * - * *Can only be used if this is ElectricEnergyInterface* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.power_usage View documentation} - */ - power_usage: double - /** - * {@link LuaEntityPrototype.collision_box LuaEntityPrototype::collision_box} around entity's given position and - * respecting the current entity orientation. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.bounding_box View documentation} - */ - readonly bounding_box: BoundingBoxTable - /** - * The secondary bounding box of this entity or `nil` if it doesn't have one. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.secondary_bounding_box View documentation} - */ - readonly secondary_bounding_box: BoundingBoxTable | undefined - /** - * {@link LuaEntityPrototype.selection_box LuaEntityPrototype::selection_box} around entity's given position and - * respecting the current entity orientation. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.selection_box View documentation} - */ - readonly selection_box: BoundingBoxTable - /** - * The secondary selection box of this entity or `nil` if it doesn't have one. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.secondary_selection_box View documentation} - */ - readonly secondary_selection_box: BoundingBoxTable | undefined - /** - * The mining target or `nil` if none - * - * *Can only be used if this is MiningDrill* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.mining_target View documentation} - */ - readonly mining_target: LuaEntity | undefined - /** - * Entities that are directly connected to this entity via the circuit network. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.circuit_connected_entities View documentation} - */ - readonly circuit_connected_entities: { - /** Entities connected via the red wire. */ - readonly red: LuaEntity[] - /** Entities connected via the green wire. */ - readonly green: LuaEntity[] - } - /** - * The connection definition for entities that are directly connected to this entity via the circuit network. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.circuit_connection_definitions View documentation} - */ - readonly circuit_connection_definitions: CircuitConnectionDefinition[] - /** - * The index of the configured request with the highest index for this entity. This means 0 if no requests are set - * and e.g. 20 if the 20th request slot is configured. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.request_slot_count View documentation} - */ - readonly request_slot_count: uint - /** - * The number of filter slots this inserter, loader, or logistic storage container has. 0 if not one of those entities. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.filter_slot_count View documentation} - */ - readonly filter_slot_count: uint - /** - * The container entity this loader is pointing at/pulling from depending on the - * {@link LuaEntity.loader_type LuaEntity::loader_type}. - * - * *Can only be used if this is Loader* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.loader_container View documentation} - */ - readonly loader_container: LuaEntity - /** - * The equipment grid or `nil` if this entity doesn't have an equipment grid. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.grid View documentation} - */ - readonly grid: LuaEquipmentGrid | undefined - /** - * The graphics variation for this entity or `nil` if this entity doesn't use graphics variations. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.graphics_variation View documentation} - */ - graphics_variation: uint8 | undefined - /** - * Index of the tree color. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tree_color_index View documentation} - */ - tree_color_index: uint8 - /** - * Maximum index of the tree colors. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tree_color_index_max View documentation} - */ - readonly tree_color_index_max: uint8 - /** - * Index of the tree stage. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tree_stage_index View documentation} - */ - tree_stage_index: uint8 - /** - * Maximum index of the tree stages. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tree_stage_index_max View documentation} - */ - readonly tree_stage_index_max: uint8 - /** - * Index of the tree gray stage - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tree_gray_stage_index View documentation} - */ - tree_gray_stage_index: uint8 - /** - * Maximum index of the tree gray stages. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tree_gray_stage_index_max View documentation} - */ - readonly tree_gray_stage_index_max: uint8 - /** - * The burner energy source for this entity or `nil` if there isn't one. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.burner View documentation} - */ - readonly burner: LuaBurner | undefined - /** - * The shooting target for this turret or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.shooting_target View documentation} - */ - shooting_target: LuaEntity | undefined - /** - * The target entity for this item-request-proxy or `nil` - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.proxy_target View documentation} - */ - readonly proxy_target: LuaEntity | undefined - /** - * The sticker entities attached to this entity or `nil` if none. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.stickers View documentation} - */ - readonly stickers: LuaEntity[] | undefined - /** - * The entity this sticker is sticked to. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.sticked_to View documentation} - */ - readonly sticked_to: LuaEntity - /** - * *Can only be used if this is ProgrammableSpeaker* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.parameters View documentation} - */ - parameters: ProgrammableSpeakerParameters - /** - * *Can only be used if this is ProgrammableSpeaker* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.alert_parameters View documentation} - */ - alert_parameters: ProgrammableSpeakerAlertParameters - /** - * The electric network statistics for this electric pole. - * - * *Can only be used if this is ElectricPole* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.electric_network_statistics View documentation} - */ - readonly electric_network_statistics: LuaFlowStatistics - /** - * Sets the stack size limit on this inserter. If the stack size is > than the force stack size limit the value is ignored. - * - * **Note**: Set to 0 to reset. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.inserter_stack_size_override View documentation} - */ - inserter_stack_size_override: uint - /** - * The number of products this machine finished crafting in its lifetime. - * - * *Can only be used if this is CraftingMachine* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.products_finished View documentation} - */ - products_finished: uint - /** - * The spawner associated with this unit entity or `nil` if the unit has no associated spawner. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.spawner View documentation} - */ - readonly spawner: LuaEntity | undefined - /** - * The units associated with this spawner entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.units View documentation} - */ - readonly units: LuaEntity[] - /** - * The state of this power switch. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.power_switch_state View documentation} - */ - power_switch_state: boolean - /** - * The effects being applied to this entity or `nil`. For beacons this is the effect the beacon is broadcasting. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.effects View documentation} - */ - readonly effects: ModuleEffects | undefined - /** - * The filters for this infinity container. - * - * *Can only be used if this is InfinityContainer* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.infinity_container_filters View documentation} - */ - infinity_container_filters: InfinityInventoryFilter[] - /** - * If items not included in this infinity container filters should be removed from the container. - * - * *Can only be used if this is InfinityContainer* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.remove_unfiltered_items View documentation} - */ - remove_unfiltered_items: boolean - /** - * The player index associated with this character corpse. - * - * **Note**: The index is not guaranteed to be valid so it should always be checked first if a player with that - * index actually exists. - * - * *Can only be used if this is CharacterCorpse* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.character_corpse_player_index View documentation} - */ - character_corpse_player_index: uint - /** - * The tick this character corpse died at. - * - * *Can only be used if this is CharacterCorpse* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.character_corpse_tick_of_death View documentation} - */ - character_corpse_tick_of_death: uint - /** - * The reason this character corpse character died (if any). - * - * *Can only be used if this is CharacterCorpse* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.character_corpse_death_cause View documentation} - */ - character_corpse_death_cause: LocalisedString - /** - * The player this character is associated with or `nil` if none. When the player logs off in multiplayer all of the - * associated characters will be logged off with him. - * - * **Note**: A character associated with a player is not directly controlled by any player. - * - * **Note**: Set to `nil` to clear. The player will be automatically disassociated when a controller is set on the character. - * - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.associated_player View documentation} - */ - associated_player: LuaPlayer | undefined - /** - * The last tick this character entity was attacked. - * - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tick_of_last_attack View documentation} - */ - tick_of_last_attack: uint - /** - * The last tick this character entity was damaged. - * - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tick_of_last_damage View documentation} - */ - tick_of_last_damage: uint - /** - * The filter for this splitter or `nil` if no filter is set. - * - * *Can only be used if this is Splitter* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.splitter_filter View documentation} - */ - splitter_filter: LuaItemPrototype | undefined - /** - * The filter mode for this filter inserter: "whitelist", "blacklist", or `nil` if this inserter doesn't use filters. - * - * *Can only be used if this is Inserter* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.inserter_filter_mode View documentation} - */ - inserter_filter_mode: "whitelist" | "blacklist" | undefined - /** - * The input priority for this splitter : "left", "none", or "right". - * - * *Can only be used if this is Splitter* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.splitter_input_priority View documentation} - */ - splitter_input_priority: "left" | "none" | "right" - /** - * The output priority for this splitter : "left", "none", or "right". - * - * *Can only be used if this is Splitter* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.splitter_output_priority View documentation} - */ - splitter_output_priority: "left" | "none" | "right" - /** - * If this land mine is armed. - * - * *Can only be used if this is LandMine* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.armed View documentation} - */ - readonly armed: boolean - /** - * When locked; the recipe in this assembling machine can't be changed by the player. - * - * *Can only be used if this is AssemblingMachine* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.recipe_locked View documentation} - */ - recipe_locked: boolean - /** - * The rail entity this train stop is connected to or `nil` if there is none. - * - * *Can only be used if this is TrainStop* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.connected_rail View documentation} - */ - readonly connected_rail: LuaEntity | undefined - /** - * The number of trains in this rail block for this rail entity. - * - * *Can only be used if this is Rail* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.trains_in_block View documentation} - */ - readonly trains_in_block: uint - /** - * The timeout that's left on this landmine in ticks. It describes the time between the landmine being placed and it - * being armed. - * - * *Can only be used if this is LandMine* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.timeout View documentation} - */ - timeout: uint - /** - * The current total neighbour bonus of this reactor. - * - * *Can only be used if this is Reactor* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.neighbour_bonus View documentation} - */ - readonly neighbour_bonus: double - /** - * The ai settings of this unit. - * - * *Can only be used if this is Unit* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.ai_settings View documentation} - */ - readonly ai_settings: LuaAISettings - /** - * The hightlight box type of this highlight box entity. - * - * *Can only be used if this is HighlightBox* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.highlight_box_type View documentation} - */ - highlight_box_type: string - /** - * The blink interval of this highlight box entity. 0 indicates no blink. - * - * *Can only be used if this is HighlightBox* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.highlight_box_blink_interval View documentation} - */ - highlight_box_blink_interval: uint - /** - * The status of this entity or `nil` if no status. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.status View documentation} - */ - readonly status: defines.entity_status | undefined - /** - * If equipment grid logistics are enabled while this vehicle is moving. - * - * *Can only be used if this is Vehicle* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.enable_logistics_while_moving View documentation} - */ - enable_logistics_while_moving: boolean - /** - * The player that this `simple-entity-with-owner`, `simple-entity-with-force`, `flying-text`, or `highlight-box` is - * visible to. `nil` means it is rendered for every player. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.render_player View documentation} - */ - render_player: LuaPlayer | undefined - /** - * The forces that this `simple-entity-with-owner`, `simple-entity-with-force`, or `flying-text` is visible to. - * `nil` or an empty array means it is rendered for every force. - * - * **Note**: Reading will always give an array of {@link LuaForce} - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.render_to_forces View documentation} - */ - render_to_forces: ForceIdentification[] | undefined - /** - * The rail target of this pump or `nil`. - * - * *Can only be used if this is Pump* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.pump_rail_target View documentation} - */ - readonly pump_rail_target: LuaEntity | undefined - /** - * Returns true if this unit is moving. - * - * *Can only be used if this is Unit* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.moving View documentation} - */ - readonly moving: boolean - /** - * Returns the id of the electric network that this entity is connected to or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.electric_network_id View documentation} - */ - readonly electric_network_id: uint | undefined - /** - * Whether this character's personal roboports are allowed to dispatch robots. - * - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.allow_dispatching_robots View documentation} - */ - allow_dispatching_robots: boolean - /** - * Whether this rocket silo automatically launches the rocket when cargo is inserted. - * - * *Can only be used if this is RocketSilo* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.auto_launch View documentation} - */ - auto_launch: boolean - /** - * How much energy this generator generated in the last tick. - * - * *Can only be used if this is Generator* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.energy_generated_last_tick View documentation} - */ - readonly energy_generated_last_tick: double - /** - * The storage filter for this logistic storage container. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.storage_filter View documentation} - */ - storage_filter: LuaItemPrototype - /** - * Whether this requester chest is set to also request from buffer chests. - * - * **Note**: Useable only on entities that have requester slots. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.request_from_buffers View documentation} - */ - request_from_buffers: boolean - /** - * Whether this corpse will ever fade away. - * - * **Note**: Useable only on corpses. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.corpse_expires View documentation} - */ - corpse_expires: boolean - /** - * If true, corpse won't be destroyed when entities are placed over it. If false, whether corpse will be removed or - * not depends on value of CorpsePrototype::remove_on_entity_placement. - * - * **Note**: Useable only on corpses. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.corpse_immune_to_entity_placement View documentation} - */ - corpse_immune_to_entity_placement: boolean - /** - * The tags associated with this entity ghost or `nil` if not an entity ghost. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tags View documentation} - */ - tags: Tags | undefined - /** - * The command given to this unit or `nil` is the unit has no command. - * - * *Can only be used if this is Unit* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.command View documentation} - */ - readonly command: Command | undefined - /** - * The distraction command given to this unit or `nil` is the unit currently isn't distracted. - * - * *Can only be used if this is Unit* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.distraction_command View documentation} - */ - readonly distraction_command: Command | undefined - /** - * The ticks until the next trigger effect of this smoke-with-trigger. - * - * *Can only be used if this is SmokeWithTrigger* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.time_to_next_effect View documentation} - */ - time_to_next_effect: uint - /** - * Destination position of spidertron's autopilot. Returns `nil` if autopilot doesn't have destination set. - * - * *Can only be used if this is SpiderVehicle* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.autopilot_destination View documentation} - */ - autopilot_destination: Position | undefined - /** - * The queued destination positions of spidertron's autopilot. - * - * *Can only be used if this is SpiderVehicle* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.autopilot_destinations View documentation} - */ - readonly autopilot_destinations: PositionTable[] - /** - * Amount of trains related to this particular train stop. Includes train stopped at this train stop (until it finds - * a path to next target) and trains having this train stop as goal or waypoint. Writing nil will disable the limit - * (will set a maximum possible value). - * - * **Note**: Train may be included multiple times when braking distance covers this train stop multiple times - * - * **Note**: Value may be read even when train stop has no control behavior - * - * *Can only be used if this is TrainStop* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.trains_count View documentation} - */ - readonly trains_count: uint | undefined - /** - * Amount of trains above which no new trains will be sent to this train stop. - * - * **Note**: When a train stop has a control behavior with wire connected and set_trains_limit enabled, this value - * will be overwritten by it - * - * *Can only be used if this is TrainStop* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.trains_limit View documentation} - */ - trains_limit: uint - /** - * If this entity is EntityWithForce - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_entity_with_force View documentation} - */ - readonly is_entity_with_force: boolean - /** - * If this entity is EntityWithOwner - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_entity_with_owner View documentation} - */ - readonly is_entity_with_owner: boolean - /** - * If this entity is EntityWithHealth - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_entity_with_health View documentation} - */ - readonly is_entity_with_health: boolean - /** - * The owner of this combat robot if any. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.combat_robot_owner View documentation} - */ - combat_robot_owner: LuaEntity - /** - * The link ID this linked container is using. - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.link_id View documentation} - */ - link_id: uint - /** - * The follow target of this spidertron if any. - * - * *Can only be used if this is SpiderVehicle* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.follow_target View documentation} - */ - follow_target: LuaEntity - /** - * The follow offset of this spidertron if any. If it is not following an entity this will be nil. This is - * randomized each time the follow entity is set. - * - * *Can only be used if this is SpiderVehicle* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.follow_offset View documentation} - */ - follow_offset: Position | undefined - /** - * Type of linked belt: it is either `"input"` or `"output"`. Changing type will also flip direction so the belt is - * out of the same side - * - * **Note**: Can only be changed when linked belt is disconnected (has no neighbour set) - * - * **Note**: Can also be used on entity ghost if it contains linked-belt - * - * *Can only be used if this is LinkedBelt* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.linked_belt_type View documentation} - */ - linked_belt_type: "input" | "output" - /** - * Neighbour to which this linked belt is connected to. Returns nil if not connected. - * - * **Note**: Can also be used on entity ghost if it contains linked-belt - * - * **Note**: May return entity ghost which contains linked belt to which connection is made - * - * *Can only be used if this is LinkedBelt* - * - * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.linked_belt_neighbour View documentation} - */ - readonly linked_belt_neighbour: LuaEntity | undefined - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaEntity" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of an entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html View documentation} - * - * @noSelf - */ -interface LuaEntityPrototype { - /** - * Does this prototype have a flag enabled? - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.has_flag View documentation} - * - * @param flag - The flag to check. Must be one of - `"not-rotatable"` - `"placeable-neutral"` - - * `"placeable-player"` - `"placeable-enemy"` - `"placeable-off-grid"` - `"player-creation"` - - * `"building-direction-8-way"` - `"filter-directions"` - `"fast-replaceable-no-build-while-moving"` - - * `"breaths-air"` - `"not-repairable"` - `"not-on-map"` - `"not-deconstructable"` - `"not-blueprintable"` - - * `"hide-from-bonus-gui"` - `"hide-alt-info"` - `"fast-replaceable-no-cross-type-while-moving"` - - * `"no-gap-fill-while-building"` - `"not-flammable"` - `"no-automated-item-removal"` - - * `"no-automated-item-insertion"` - `"not-upgradable"` - */ - has_flag( - flag: - | "not-rotatable" - | "placeable-neutral" - | "placeable-player" - | "placeable-enemy" - | "placeable-off-grid" - | "player-creation" - | "filter-directions" - | "fast-replaceable-no-build-while-moving" - | "breaths-air" - | "not-repairable" - | "not-on-map" - | "not-deconstructable" - | "not-blueprintable" - | "hide-from-bonus-gui" - | "hide-alt-info" - | "fast-replaceable-no-cross-type-while-moving" - | "no-gap-fill-while-building" - | "not-flammable" - | "no-automated-item-removal" - | "no-automated-item-insertion" - | "not-upgradable" - ): boolean - /** - * Gets the base size of the given inventory on this entity or `nil` if the given inventory doesn't exist. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.get_inventory_size View documentation} - * - * @param index - */ - get_inventory_size(index: defines.inventory): uint | undefined - /** - * Type of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.type View documentation} - */ - readonly type: string - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.name View documentation} - */ - readonly name: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * Max health of this entity. Will be `0` if this is not an entity with health. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_health View documentation} - */ - readonly max_health: float - /** - * Is this resource infinite? Will be `nil` when used on a non-resource. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.infinite_resource View documentation} - */ - readonly infinite_resource: boolean | undefined - /** - * Minimum amount of this resource. Will be `nil` when used on a non-resource. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.minimum_resource_amount View documentation} - */ - readonly minimum_resource_amount: uint | undefined - /** - * The normal amount for this resource. `nil` when not a resource. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.normal_resource_amount View documentation} - */ - readonly normal_resource_amount: uint | undefined - /** - * Every time this infinite resource 'ticks' down it is reduced by this amount. `nil` when not a resource. - * Meaningless if this isn't an infinite type resource. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.infinite_depletion_resource_amount View documentation} - */ - readonly infinite_depletion_resource_amount: uint | undefined - /** - * Name of the category of this resource or `nil` when not a resource. - * - * **Note**: During data stage this property is named "category". - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.resource_category View documentation} - */ - readonly resource_category: string | undefined - /** - * Whether this entity is minable and what can be obtained by mining it. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.mineable_properties View documentation} - */ - readonly mineable_properties: { - /** Is this entity mineable at all? */ - readonly minable: boolean - /** Energy required to mine an entity. */ - readonly mining_time: double - /** - * Prototype name of the particle produced when mining this entity. Will only be present if this entity produces - * any particle during mining. - */ - readonly mining_particle?: string - /** Products obtained by mining this entity. */ - readonly products?: Product[] - /** The required fluid amount if any. */ - readonly fluid_amount?: double - /** The prototype name of the required fluid if any. */ - readonly required_fluid?: string - /** The mining trigger if any. */ - readonly mining_trigger?: TriggerItem[] - } - /** - * Items that, when placed, will produce this entity. It is an array of items, or `nil` if no items place this - * entity. Construction bots will always choose the first item in this list to build this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.items_to_place_this View documentation} - */ - readonly items_to_place_this: SimpleItemStack[] | undefined - /** - * The bounding box used for collision checking. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.collision_box View documentation} - */ - readonly collision_box: BoundingBoxTable - /** - * The secondary bounding box used for collision checking, or `nil` if it doesn't have one. This is only used in - * rails and rail remnants. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.secondary_collision_box View documentation} - */ - readonly secondary_collision_box: BoundingBoxTable | undefined - /** - * The bounding box used for map generator collision checking. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.map_generator_bounding_box View documentation} - */ - readonly map_generator_bounding_box: BoundingBoxTable - /** - * The bounding box used for drawing selection. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.selection_box View documentation} - */ - readonly selection_box: BoundingBoxTable - /** - * The bounding box used for drawing the entity icon. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.drawing_box View documentation} - */ - readonly drawing_box: BoundingBoxTable - /** - * The bounding box used to attach sticker type entities. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.sticker_box View documentation} - */ - readonly sticker_box: BoundingBoxTable - /** - * The collision masks this entity uses - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.collision_mask View documentation} - */ - readonly collision_mask: CollisionMask - readonly collision_mask_with_flags: CollisionMaskWithFlags - /** - * The hardcoded default collision mask (with flags) for this entity prototype type. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.default_collision_mask_with_flags View documentation} - */ - readonly default_collision_mask_with_flags: CollisionMaskWithFlags - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.order View documentation} - */ - readonly order: string - /** - * Group of this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.group View documentation} - */ - readonly group: LuaGroup - /** - * Subgroup of this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.subgroup View documentation} - */ - readonly subgroup: LuaGroup - /** - * Amount this entity can heal per tick. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.healing_per_tick View documentation} - */ - readonly healing_per_tick: float - /** - * Amount of pollution emissions per second this entity will create. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.emissions_per_second View documentation} - */ - readonly emissions_per_second: double - /** - * Corpses used when this entity is destroyed. It is a dictionary indexed by the corpse's prototype name. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.corpses View documentation} - */ - readonly corpses: Record - /** - * Is this entity selectable? - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.selectable_in_game View documentation} - */ - readonly selectable_in_game: boolean - /** - * The selection priority of this entity - a value between 0 and 255 - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.selection_priority View documentation} - */ - readonly selection_priority: uint - /** - * The weight of this vehicle prototype or `nil` if not a vehicle prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.weight View documentation} - */ - readonly weight: double | undefined - /** - * List of resistances towards each damage type. It is a dictionary indexed by damage type names (see - * `data/base/prototypes/damage-type.lua`). - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.resistances View documentation} - */ - readonly resistances: Record - /** - * The group of mutually fast-replaceable entities. Possibly `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.fast_replaceable_group View documentation} - */ - readonly fast_replaceable_group: string | undefined - /** - * The next upgrade for this entity or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.next_upgrade View documentation} - */ - readonly next_upgrade: LuaEntityPrototype | undefined - /** - * Loot that will be dropped when this entity is killed. `nil` if there is no loot. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.loot View documentation} - */ - readonly loot: Loot[] | undefined - /** - * Repair-speed modifier for this entity. Actual repair speed will be `tool_repair_speed * - * entity_repair_speed_modifier`. May be `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.repair_speed_modifier View documentation} - */ - readonly repair_speed_modifier: uint | undefined - /** - * The range of this turret or `nil` if this isn't a turret related prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.turret_range View documentation} - */ - readonly turret_range: uint | undefined - /** - * Autoplace specification for this entity prototype. `nil` if none. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.autoplace_specification View documentation} - */ - readonly autoplace_specification: AutoplaceSpecification | undefined - /** - * The speed of this transport belt or `nil` if this isn't a transport belt related prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.belt_speed View documentation} - */ - readonly belt_speed: double | undefined - /** - * The result units and spawn points with weight and evolution factor for a biter spawner entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.result_units View documentation} - */ - readonly result_units: UnitSpawnDefinition[] - /** - * The attack result of this entity if the entity has one, else `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.attack_result View documentation} - */ - readonly attack_result: TriggerItem[] | undefined - /** - * The final attack result for projectiles `nil` if not a projectile - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.final_attack_result View documentation} - */ - readonly final_attack_result: TriggerItem[] | undefined - /** - * The attack parameters for this entity or `nil` if the entity doesn't use attack parameters. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.attack_parameters View documentation} - */ - readonly attack_parameters: AttackParameters | undefined - /** - * The spawning cooldown for this enemy spawner prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.spawn_cooldown View documentation} - */ - readonly spawn_cooldown: - | { - readonly min: double - readonly max: double - } - | undefined - /** - * The mining radius of this mining drill prototype or `nil` if this isn't a mining drill prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.mining_drill_radius View documentation} - */ - readonly mining_drill_radius: double | undefined - /** - * The mining speed of this mining drill/character prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.mining_speed View documentation} - */ - readonly mining_speed: double | undefined - /** - * The logistic mode of this logistic container or `nil` if this isn't a logistic container prototype. One of - * `"requester"`, `"active-provider"`, `"passive-provider"`, `"buffer"`, `"storage"`, `"none"`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.logistic_mode View documentation} - */ - readonly logistic_mode: - | "requester" - | "active-provider" - | "passive-provider" - | "buffer" - | "storage" - | "none" - | undefined - /** - * The max underground distance for underground belts and underground pipes or `nil` if this isn't one of those prototypes. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_underground_distance View documentation} - */ - readonly max_underground_distance: uint8 | undefined - /** - * The entity prototype flags for this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.flags View documentation} - */ - readonly flags: EntityPrototypeFlags - /** - * The remains left behind when this entity is mined. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.remains_when_mined View documentation} - */ - readonly remains_when_mined: LuaEntityPrototype[] - /** - * Entities this entity can be pasted onto in addition to the normal allowed ones. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.additional_pastable_entities View documentation} - */ - readonly additional_pastable_entities: LuaEntityPrototype[] - /** - * When false copy-paste is not allowed for this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.allow_copy_paste View documentation} - */ - readonly allow_copy_paste: boolean - /** - * The cursor size used when shooting at this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.shooting_cursor_size View documentation} - */ - readonly shooting_cursor_size: double - /** - * The smoke trigger run when this entity is built or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.created_smoke View documentation} - */ - readonly created_smoke: - | { - readonly smoke_name: string - readonly offsets: Vector[] - readonly offset_deviation: BoundingBox - readonly initial_height: float - readonly max_radius?: float - readonly speed: Vector - readonly speed_multiplier: float - readonly speed_multiplier_deviation: float - readonly starting_frame: float - readonly starting_frame_deviation: float - readonly starting_frame_speed: float - readonly starting_frame_speed_deviation: float - readonly speed_from_center: float - readonly speed_from_center_deviation: float - } - | undefined - /** - * The trigger run when this entity is created or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.created_effect View documentation} - */ - readonly created_effect: TriggerItem[] | undefined - /** - * The map color used when charting this entity if a friendly or enemy color isn't defined or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.map_color View documentation} - */ - readonly map_color: ColorTable | undefined - /** - * The friendly map color used when charting this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.friendly_map_color View documentation} - */ - readonly friendly_map_color: ColorTable - /** - * The enemy map color used when charting this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.enemy_map_color View documentation} - */ - readonly enemy_map_color: ColorTable - /** - * The evolution requirement to build this entity as a base when expanding enemy bases. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.build_base_evolution_requirement View documentation} - */ - readonly build_base_evolution_requirement: double - /** - * The instruments for this programmable speaker or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.instruments View documentation} - */ - readonly instruments: ProgrammableSpeakerInstrument[] | undefined - /** - * The maximum polyphony for this programmable speaker or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_polyphony View documentation} - */ - readonly max_polyphony: uint | undefined - /** - * The module inventory size or `nil` if this entity doesn't support modules. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.module_inventory_size View documentation} - */ - readonly module_inventory_size: uint | undefined - /** - * The max number of ingredients this crafting-machine prototype supports or `nil` if this isn't a crafting-machine prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.ingredient_count View documentation} - */ - readonly ingredient_count: uint | undefined - /** - * The crafting speed of this crafting-machine or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.crafting_speed View documentation} - */ - readonly crafting_speed: double | undefined - /** - * The crafting categories this entity supports. Only meaningful when this is a crafting-machine or player entity type. - * - * **Note**: The value in the dictionary is meaningless and exists just to allow the dictionary type for easy lookup. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.crafting_categories View documentation} - */ - readonly crafting_categories: Record - /** - * The resource categories this character or mining drill supports, or `nil` if not a character or mining dill. - * - * **Note**: The value in the dictionary is meaningless and exists just to allow the dictionary type for easy lookup. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.resource_categories View documentation} - */ - readonly resource_categories: Record | undefined - /** - * The supply area of this electric pole, beacon, or `nil` if this is neither. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.supply_area_distance View documentation} - */ - readonly supply_area_distance: double | undefined - /** - * The maximum wire distance for this entity. 0 when the entity doesn't support wires. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_wire_distance View documentation} - */ - readonly max_wire_distance: double - /** - * The maximum circuit wire distance for this entity. 0 when the entity doesn't support circuit wires. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_circuit_wire_distance View documentation} - */ - readonly max_circuit_wire_distance: double - /** - * The direct energy usage of this entity or `nil` if this entity doesn't have a direct energy usage. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.energy_usage View documentation} - */ - readonly energy_usage: double | undefined - /** - * The theoretical maximum energy usage for this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_energy_usage View documentation} - */ - readonly max_energy_usage: double - /** - * The theoretical maximum energy production for this this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_energy_production View documentation} - */ - readonly max_energy_production: double - /** - * The effectivity of this car prototype, generator prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.effectivity View documentation} - */ - readonly effectivity: double | undefined - /** - * The energy consumption of this car prototype or `nil` if not a car prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.consumption View documentation} - */ - readonly consumption: double | undefined - /** - * The friction of this vehicle prototype or `nil` if not a vehicle prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.friction_force View documentation} - */ - readonly friction_force: double | undefined - /** - * The braking force of this vehicle prototype or `nil` if not a vehicle prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.braking_force View documentation} - */ - readonly braking_force: double | undefined - /** - * The air resistance of this rolling stock prototype or `nil` if not a rolling stock prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.air_resistance View documentation} - */ - readonly air_resistance: double | undefined - /** - * If this car prototype uses tank controls to drive or `nil` if this is not a car prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.tank_driving View documentation} - */ - readonly tank_driving: boolean | undefined - /** - * The rotation speed of this car prototype or `nil` if not a car prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.rotation_speed View documentation} - */ - readonly rotation_speed: double | undefined - /** - * The turret rotation speed of this car prototype or `nil` if not a car prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.turret_rotation_speed View documentation} - */ - readonly turret_rotation_speed: double | undefined - /** - * The guns this prototype uses or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.guns View documentation} - */ - readonly guns: Record | undefined - /** - * The default speed of this flying robot, rolling stock or unit, `nil` if not one of these. - * - * **Note**: For rolling stocks, this is their `max_speed`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.speed View documentation} - */ - readonly speed: double | undefined - /** - * The speed multiplier when this flying robot is out of energy or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.speed_multiplier_when_out_of_energy View documentation} - */ - readonly speed_multiplier_when_out_of_energy: float | undefined - /** - * The max payload size of this logistics or construction robot or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_payload_size View documentation} - */ - readonly max_payload_size: uint | undefined - /** - * Whether this logistics or construction robot renders its cargo when flying or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.draw_cargo View documentation} - */ - readonly draw_cargo: boolean | undefined - /** - * The energy consumed per tile moved for this flying robot or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.energy_per_move View documentation} - */ - readonly energy_per_move: double | undefined - /** - * The energy consumed per tick for this flying robot or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.energy_per_tick View documentation} - */ - readonly energy_per_tick: double | undefined - /** - * The max energy for this flying robot or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_energy View documentation} - */ - readonly max_energy: double | undefined - /** - * The minimum energy for this flying robot before it tries to recharge or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.min_to_charge View documentation} - */ - readonly min_to_charge: float | undefined - /** - * The maximum energy for this flying robot above which it won't try to recharge when stationing or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_to_charge View documentation} - */ - readonly max_to_charge: float | undefined - /** - * The burner energy source prototype this entity uses or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.burner_prototype View documentation} - */ - readonly burner_prototype: LuaBurnerPrototype | undefined - /** - * The electric energy source prototype this entity uses or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.electric_energy_source_prototype View documentation} - */ - readonly electric_energy_source_prototype: LuaElectricEnergySourcePrototype | undefined - /** - * The heat energy source prototype this entity uses or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.heat_energy_source_prototype View documentation} - */ - readonly heat_energy_source_prototype: LuaHeatEnergySourcePrototype | undefined - /** - * The fluid energy source prototype this entity uses or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.fluid_energy_source_prototype View documentation} - */ - readonly fluid_energy_source_prototype: LuaFluidEnergySourcePrototype | undefined - /** - * The void energy source prototype this entity uses or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.void_energy_source_prototype View documentation} - */ - readonly void_energy_source_prototype: LuaVoidEnergySourcePrototype | undefined - /** - * The log2 of grid size of the building - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.building_grid_bit_shift View documentation} - */ - readonly building_grid_bit_shift: uint - /** - * The fluid usage of this generator prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.fluid_usage_per_tick View documentation} - */ - readonly fluid_usage_per_tick: double | undefined - /** - * The maximum fluid temperature of this generator prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.maximum_temperature View documentation} - */ - readonly maximum_temperature: double | undefined - /** - * The target temperature of this boiler prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.target_temperature View documentation} - */ - readonly target_temperature: double | undefined - /** - * The fluid this offshore pump produces or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.fluid View documentation} - */ - readonly fluid: LuaFluidPrototype | undefined - /** - * The fluid capacity of this entity or 0 if this entity doesn't support fluids. - * - * **Note**: Crafting machines will report 0 due to their fluid capacity being what ever a given recipe needs. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.fluid_capacity View documentation} - */ - readonly fluid_capacity: double - /** - * The pumping speed of this offshore pump, normal pump, or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.pumping_speed View documentation} - */ - readonly pumping_speed: double | undefined - /** - * If this inserter is a stack-type. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.stack View documentation} - */ - readonly stack: boolean - /** - * If this inserter allows custom pickup and drop vectors. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.allow_custom_vectors View documentation} - */ - readonly allow_custom_vectors: boolean - /** - * If this inserter allows burner leeching. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.allow_burner_leech View documentation} - */ - readonly allow_burner_leech: boolean - /** - * The extension speed of this inserter or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.inserter_extension_speed View documentation} - */ - readonly inserter_extension_speed: double | undefined - /** - * The rotation speed of this inserter or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.inserter_rotation_speed View documentation} - */ - readonly inserter_rotation_speed: double | undefined - /** - * The pickup position for this inserter or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.inserter_pickup_position View documentation} - */ - readonly inserter_pickup_position: Vector | undefined - /** - * The drop position for this inserter or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.inserter_drop_position View documentation} - */ - readonly inserter_drop_position: Vector | undefined - /** - * True if this inserter chases items on belts for pickup or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.inserter_chases_belt_items View documentation} - */ - readonly inserter_chases_belt_items: boolean | undefined - /** - * If this simple-entity is counted as a rock for the deconstruction planner "trees and rocks only" filter. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.count_as_rock_for_filtered_deconstruction View documentation} - */ - readonly count_as_rock_for_filtered_deconstruction: boolean - /** - * The filter count of this inserter, loader, or logistic chest or `nil`. For logistic containers, `nil` means no limit. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.filter_count View documentation} - */ - readonly filter_count: uint | undefined - /** - * The time to live for this prototype or `0` if prototype doesn't have time_to_live or time_before_removed. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.time_to_live View documentation} - */ - readonly time_to_live: uint - /** - * The distribution effectivity for this beacon prototype or `nil` if not a beacon prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.distribution_effectivity View documentation} - */ - readonly distribution_effectivity: double | undefined - /** - * Does this explosion have a beam or `nil` if not an explosion prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.explosion_beam View documentation} - */ - readonly explosion_beam: double | undefined - /** - * Does this explosion rotate or `nil` if not an explosion prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.explosion_rotate View documentation} - */ - readonly explosion_rotate: double | undefined - /** - * If it is a tree, return the number of colors it supports. `nil` otherwise. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.tree_color_count View documentation} - */ - readonly tree_color_count: uint8 | undefined - /** - * Does this entity with health prototype alert when damaged? or `nil` if not entity with health prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.alert_when_damaged View documentation} - */ - readonly alert_when_damaged: boolean | undefined - /** - * Does this turret prototype alert when attacking? or `nil` if not turret prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.alert_when_attacking View documentation} - */ - readonly alert_when_attacking: boolean | undefined - /** - * The color of the prototype, or `nil` if the prototype doesn't have color. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.color View documentation} - */ - readonly color: ColorTable | undefined - /** - * Does this prototype collision mask collide with itself? - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.collision_mask_collides_with_self View documentation} - */ - readonly collision_mask_collides_with_self: boolean - /** - * Does this prototype collision mask collide with tiles only? - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.collision_mask_collides_with_tiles_only View documentation} - */ - readonly collision_mask_collides_with_tiles_only: boolean - /** - * Does this prototype collision mask consider tile transitions? - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.collision_mask_considers_tile_transitions View documentation} - */ - readonly collision_mask_considers_tile_transitions: boolean - /** - * The allowed module effects for this entity or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.allowed_effects View documentation} - */ - readonly allowed_effects: Record | undefined - /** - * The rocket parts required for this rocket silo prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.rocket_parts_required View documentation} - */ - readonly rocket_parts_required: uint | undefined - /** - * The rocket rising delay for this rocket silo prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.rocket_rising_delay View documentation} - */ - readonly rocket_rising_delay: uint8 | undefined - /** - * The rocket launch delay for this rocket silo prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.launch_wait_time View documentation} - */ - readonly launch_wait_time: uint8 | undefined - /** - * The light blinking speed for this rocket silo prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.light_blinking_speed View documentation} - */ - readonly light_blinking_speed: double | undefined - /** - * The door opening speed for this rocket silo prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.door_opening_speed View documentation} - */ - readonly door_opening_speed: double | undefined - /** - * The rising speed for this rocket silo rocket prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.rising_speed View documentation} - */ - readonly rising_speed: double | undefined - /** - * The engine starting speed for this rocket silo rocket prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.engine_starting_speed View documentation} - */ - readonly engine_starting_speed: double | undefined - /** - * The flying speed for this rocket silo rocket prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.flying_speed View documentation} - */ - readonly flying_speed: double | undefined - /** - * The flying acceleration for this rocket silo rocket prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.flying_acceleration View documentation} - */ - readonly flying_acceleration: double | undefined - /** - * The fixed recipe name for this assembling machine prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.fixed_recipe View documentation} - */ - readonly fixed_recipe: string | undefined - /** - * The construction radius for this roboport prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.construction_radius View documentation} - */ - readonly construction_radius: double | undefined - /** - * The logistic radius for this roboport prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.logistic_radius View documentation} - */ - readonly logistic_radius: double | undefined - /** - * The energy used per hitpoint taken for this vehicle during collisions or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.energy_per_hit_point View documentation} - */ - readonly energy_per_hit_point: double | undefined - /** - * If this prototype will attempt to create a ghost of itself on death. - * - * **Note**: If this is false then a ghost will never be made, if it's true a ghost may be made. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.create_ghost_on_death View documentation} - */ - readonly create_ghost_on_death: boolean - /** - * The time it takes this land mine to arm. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.timeout View documentation} - */ - readonly timeout: uint - /** - * The fluidbox prototypes for this entity. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.fluidbox_prototypes View documentation} - */ - readonly fluidbox_prototypes: LuaFluidBoxPrototype[] - /** - * *Can only be used if this is Reactor* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.neighbour_bonus View documentation} - */ - readonly neighbour_bonus: double - /** - * Controls how much a reactor extends when connected to other reactors. - * - * *Can only be used if this is Reactor* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.neighbour_collision_increase View documentation} - */ - readonly neighbour_collision_increase: double - /** - * *Can only be used if this is Loader* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.container_distance View documentation} - */ - readonly container_distance: double - /** - * *Can only be used if this is Loader* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.belt_distance View documentation} - */ - readonly belt_distance: double - /** - * *Can only be used if this is Loader* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.belt_length View documentation} - */ - readonly belt_length: double - readonly is_building: boolean - /** - * The amount of ammo that inserters automatically insert into this ammo-turret or artillery-turret or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.automated_ammo_count View documentation} - */ - readonly automated_ammo_count: uint | undefined - /** - * The max speed of this projectile prototype or flying robot prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_speed View documentation} - */ - readonly max_speed: double | undefined - /** - * Value between 0 and 1 darkness where all lamps of this lamp prototype are on or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.darkness_for_all_lamps_on View documentation} - */ - readonly darkness_for_all_lamps_on: float | undefined - /** - * Value between 0 and 1 darkness where all lamps of this lamp prototype are off or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.darkness_for_all_lamps_off View documentation} - */ - readonly darkness_for_all_lamps_off: float | undefined - /** - * Whether the lamp is always on (except when out of power or turned off by the circuit network) or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.always_on View documentation} - */ - readonly always_on: boolean | undefined - /** - * The minimum darkness at which this unit spawner can spawn entities. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.min_darkness_to_spawn View documentation} - */ - readonly min_darkness_to_spawn: float - /** - * The maximum darkness at which this unit spawner can spawn entities. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_darkness_to_spawn View documentation} - */ - readonly max_darkness_to_spawn: float - readonly call_for_help_radius: double - /** - * Count of enemies this spawner can sustain. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_count_of_owned_units View documentation} - */ - readonly max_count_of_owned_units: double - /** - * How many friendly units are required within the spawning_radius of this spawner for it to stop producing more units. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_friends_around_to_spawn View documentation} - */ - readonly max_friends_around_to_spawn: double - /** - * How far from the spawner can the units be spawned. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.spawning_radius View documentation} - */ - readonly spawning_radius: double - /** - * What spaces should be between the spawned units. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.spawning_spacing View documentation} - */ - readonly spawning_spacing: double - /** - * The radius of this entity prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.radius View documentation} - */ - readonly radius: double - /** - * The item prototype name used to destroy this cliff or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.cliff_explosive_prototype View documentation} - */ - readonly cliff_explosive_prototype: string | undefined - /** - * The rocket entity prototype associated with this rocket silo prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.rocket_entity_prototype View documentation} - */ - readonly rocket_entity_prototype: LuaEntityPrototype | undefined - /** - * Whether this unit, car, or character prototype has belt immunity, `nil` if not car, unit, or character prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.has_belt_immunity View documentation} - */ - readonly has_belt_immunity: boolean | undefined - /** - * The vision distance of this unit prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.vision_distance View documentation} - */ - readonly vision_distance: double | undefined - /** - * The amount of pollution that has to be absorbed by the unit's spawner before the unit will leave the spawner and - * attack the source of the pollution. `nil` when prototype is not a unit prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.pollution_to_join_attack View documentation} - */ - readonly pollution_to_join_attack: float | undefined - /** - * The minimum pursue time of this unit prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.min_pursue_time View documentation} - */ - readonly min_pursue_time: uint | undefined - /** - * The maximum pursue distance of this unit prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_pursue_distance View documentation} - */ - readonly max_pursue_distance: double | undefined - /** - * The radar range of this unit prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.radar_range View documentation} - */ - readonly radar_range: uint | undefined - /** - * Whether this unit prototype can move while shooting or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.move_while_shooting View documentation} - */ - readonly move_while_shooting: boolean | undefined - /** - * Whether this unit prototype can open gates or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.can_open_gates View documentation} - */ - readonly can_open_gates: boolean | undefined - /** - * Whether this unit prototype is affected by tile walking speed modifiers or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.affected_by_tiles View documentation} - */ - readonly affected_by_tiles: boolean | undefined - /** - * The distraction cooldown of this unit prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.distraction_cooldown View documentation} - */ - readonly distraction_cooldown: uint | undefined - /** - * The spawning time modifier of this unit prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.spawning_time_modifier View documentation} - */ - readonly spawning_time_modifier: double | undefined - /** - * The alert icon shift of this entity prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.alert_icon_shift View documentation} - */ - readonly alert_icon_shift: Vector - /** - * The item prototype names that are the inputs of this lab prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.lab_inputs View documentation} - */ - readonly lab_inputs: string[] | undefined - /** - * The base researching speed of this lab prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.researching_speed View documentation} - */ - readonly researching_speed: double | undefined - /** - * The item slot count of this constant combinator prototype or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.item_slot_count View documentation} - */ - readonly item_slot_count: uint | undefined - /** - * The base productivity of this crafting machine, lab, or mining drill, or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.base_productivity View documentation} - */ - readonly base_productivity: double | undefined - /** - * If this market allows access to all forces or just friendly ones. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.allow_access_to_all_forces View documentation} - */ - readonly allow_access_to_all_forces: boolean - /** - * If this entity prototype could possibly ever be rotated. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.supports_direction View documentation} - */ - readonly supports_direction: boolean - /** - * The terrain friction modifier for this vehicle. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.terrain_friction_modifier View documentation} - */ - readonly terrain_friction_modifier: float - /** - * If this vehicle allows passengers. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.allow_passengers View documentation} - */ - readonly allow_passengers: boolean - /** - * The radius of the area this radar can chart, in chunks. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_distance_of_sector_revealed View documentation} - */ - readonly max_distance_of_sector_revealed: uint - /** - * The radius of the area constantly revealed by this radar, in chunks. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_distance_of_nearby_sector_revealed View documentation} - */ - readonly max_distance_of_nearby_sector_revealed: uint - /** - * The bounding box that specifies which tiles adjacent to the offshore pump should be checked. - * - * *Can only be used if this is OffshorePump* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.adjacent_tile_collision_box View documentation} - */ - readonly adjacent_tile_collision_box: BoundingBoxTable - /** - * Tiles adjacent to the offshore pump must not collide with this collision mask. - * - * *Can only be used if this is OffshorePump* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.adjacent_tile_collision_mask View documentation} - */ - readonly adjacent_tile_collision_mask: CollisionMask - /** - * If this mask is not empty, tiles adjacent to the offshore pump must not collide with this collision mask. - * - * *Can only be used if this is OffshorePump* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.adjacent_tile_collision_test View documentation} - */ - readonly adjacent_tile_collision_test: CollisionMask - /** - * The collision mask used only for collision test with tile directly at offshore pump position. - * - * *Can only be used if this is OffshorePump* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.center_collision_mask View documentation} - */ - readonly center_collision_mask: CollisionMask - /** - * The equipment grid prototype for this entity or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.grid_prototype View documentation} - */ - readonly grid_prototype: LuaEquipmentGridPrototype | undefined - readonly remove_decoratives: string - /** - * *Can only be used if this is TransportBelt* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.related_underground_belt View documentation} - */ - readonly related_underground_belt: LuaEntityPrototype - /** - * Gets the current movement speed of this character, including effects from exoskeletons, tiles, stickers and shooting. - * - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.running_speed View documentation} - */ - readonly running_speed: double - /** - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.maximum_corner_sliding_distance View documentation} - */ - readonly maximum_corner_sliding_distance: double - /** - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.build_distance View documentation} - */ - readonly build_distance: uint - /** - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.drop_item_distance View documentation} - */ - readonly drop_item_distance: uint - /** - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.reach_distance View documentation} - */ - readonly reach_distance: uint - /** - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.reach_resource_distance View documentation} - */ - readonly reach_resource_distance: double - /** - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.item_pickup_distance View documentation} - */ - readonly item_pickup_distance: double - /** - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.loot_pickup_distance View documentation} - */ - readonly loot_pickup_distance: double - /** - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.enter_vehicle_distance View documentation} - */ - readonly enter_vehicle_distance: double - /** - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.ticks_to_keep_gun View documentation} - */ - readonly ticks_to_keep_gun: uint - /** - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.ticks_to_keep_aiming_direction View documentation} - */ - readonly ticks_to_keep_aiming_direction: uint - /** - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.ticks_to_stay_in_combat View documentation} - */ - readonly ticks_to_stay_in_combat: uint - /** - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.respawn_time View documentation} - */ - readonly respawn_time: uint - /** - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.damage_hit_tint View documentation} - */ - readonly damage_hit_tint: ColorTable - /** - * *Can only be used if this is Character* - * - * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.character_corpse View documentation} - */ - readonly character_corpse: LuaEntityPrototype - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaEntityPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * An item in a {@link LuaEquipmentGrid}, for example one's power armor. - * - * **Note**: An equipment reference becomes invalid once the equipment is removed or the equipment grid it resides in is - * destroyed. - * - * {@link https://lua-api.factorio.com/next/LuaEquipment.html View documentation} - * - * @noSelf - */ -interface LuaEquipment { - /** - * Name of this equipment. - * - * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.name View documentation} - */ - readonly name: string - /** - * Type of this equipment. - * - * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.type View documentation} - */ - readonly type: string - /** - * Position of this equipment in the equipment grid. - * - * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.position View documentation} - */ - readonly position: PositionTable - /** - * Shape of this equipment. - * - * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.shape View documentation} - */ - readonly shape: { - readonly width: uint - readonly height: uint - } - /** - * Current shield value of the equipment. - * - * **Note**: Can't be set higher than {@link LuaEquipment.max_shield LuaEquipment::max_shield}. - * - * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.shield View documentation} - */ - shield: double - /** - * Maximum shield value. - * - * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.max_shield View documentation} - */ - readonly max_shield: double - /** - * Maximum solar power generated. - * - * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.max_solar_power View documentation} - */ - readonly max_solar_power: double - /** - * Movement speed bonus. - * - * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.movement_bonus View documentation} - */ - readonly movement_bonus: double - /** - * Energy generated per tick. - * - * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.generator_power View documentation} - */ - readonly generator_power: double - /** - * Current available energy. - * - * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.energy View documentation} - */ - energy: double - /** - * Maximum amount of energy that can be stored in this equipment. - * - * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.max_energy View documentation} - */ - readonly max_energy: double - readonly prototype: LuaEquipmentPrototype - /** - * The burner energy source for this equipment or `nil` if there isn't one. - * - * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.burner View documentation} - */ - readonly burner: LuaBurner | undefined - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaEquipment" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of an equipment category. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentCategoryPrototype.html View documentation} - * - * @noSelf - */ -interface LuaEquipmentCategoryPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentCategoryPrototype.html#LuaEquipmentCategoryPrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentCategoryPrototype.html#LuaEquipmentCategoryPrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaEquipmentCategoryPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * An equipment grid is for example the inside of a power armor. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html View documentation} - * - * @noSelf - */ -interface LuaEquipmentGrid { - /** - * Remove an equipment from the grid. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.take View documentation} - * - * @returns The removed equipment, or `nil` if no equipment was removed. - */ - take(params: { - /** Take the equipment that contains this position in the grid. */ - readonly position?: Position - /** Take this exact equipment. */ - readonly equipment?: LuaEquipment - /** - * If provided the action is done 'as' this player and - * {@link OnPlayerRemovedEquipmentEvent on_player_removed_equipment} is triggered. - */ - readonly by_player?: PlayerIdentification - }): SimpleItemStack | undefined - /** - * Remove all equipment from the grid. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.take_all View documentation} - * - * @param by_player - If provided, the action is done 'as' this player and - * {@link OnPlayerRemovedEquipmentEvent on_player_removed_equipment} is triggered. - * @returns Count of each removed equipment, indexed by their prototype names. - */ - take_all(by_player?: PlayerIdentification): Record - /** - * Clear all equipment from the grid, removing it without actually returning it. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.clear View documentation} - * - * @param by_player - If provided, the action is done 'as' this player and - * {@link OnPlayerRemovedEquipmentEvent on_player_removed_equipment} is triggered. - */ - clear(by_player?: PlayerIdentification): void - /** - * Insert an equipment into the grid. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.put View documentation} - * - * @returns The newly-added equipment, or `nil` if the equipment could not be added. - */ - put(params: { - /** Equipment prototype name */ - readonly name: string - /** Grid position to put the equipment in. */ - readonly position?: Position - /** - * If provided the action is done 'as' this player and - * {@link OnPlayerPlacedEquipmentEvent on_player_placed_equipment} is triggered. - */ - readonly by_player?: PlayerIdentification - }): LuaEquipment | undefined - /** - * Check whether moving an equipment would succeed. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.can_move View documentation} - */ - can_move(params: { - /** The equipment to move */ - readonly equipment: LuaEquipment - /** Where to put it */ - readonly position: Position - }): boolean - /** - * Move an equipment within this grid. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.move View documentation} - * - * @returns `true` if the equipment was successfully moved. - */ - move(params: { - /** The equipment to move */ - readonly equipment: LuaEquipment - /** Where to put it */ - readonly position: Position - }): boolean - /** - * Find equipment in the Equipment Grid based off a position. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.get View documentation} - * - * @param position - The position - * @returns The found equipment, or `nil` if equipment could not be found at the given position. - */ - get(position: Position): LuaEquipment | undefined - /** - * Get counts of all equipment in this grid. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.get_contents View documentation} - * - * @returns The counts, indexed by equipment names. - */ - get_contents(): Record - readonly prototype: LuaEquipmentGridPrototype - /** - * Width of the equipment grid. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.width View documentation} - */ - readonly width: uint - /** - * Height of the equipment grid. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.height View documentation} - */ - readonly height: uint - /** - * All the equipment in this grid. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.equipment View documentation} - */ - readonly equipment: LuaEquipment[] - /** - * Total energy per tick generated by the equipment inside this grid. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.generator_energy View documentation} - */ - readonly generator_energy: double - /** - * Maximum energy per tick that can be created by any solar panels in the equipment grid. Actual generated energy - * varies depending on the daylight levels. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.max_solar_energy View documentation} - */ - readonly max_solar_energy: double - /** - * The total energy stored in all batteries in the equipment grid. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.available_in_batteries View documentation} - */ - readonly available_in_batteries: double - /** - * Total energy storage capacity of all batteries in the equipment grid. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.battery_capacity View documentation} - */ - readonly battery_capacity: double - /** - * The amount of shields this equipment grid has. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.shield View documentation} - */ - readonly shield: float - /** - * The maximum amount of shields this equipment grid has. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.max_shield View documentation} - */ - readonly max_shield: float - /** - * True if this movement bonus equipment is turned off, otherwise false. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.inhibit_movement_bonus View documentation} - */ - inhibit_movement_bonus: boolean - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaEquipmentGrid" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of an equipment grid. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGridPrototype.html View documentation} - * - * @noSelf - */ -interface LuaEquipmentGridPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGridPrototype.html#LuaEquipmentGridPrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGridPrototype.html#LuaEquipmentGridPrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * Equipment category names for the categories that may be inserted into this equipment grid. The grid will accept - * any equipment that has at least one category in this list. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGridPrototype.html#LuaEquipmentGridPrototype.equipment_categories View documentation} - * - * @see {@link LuaEquipmentPrototype.equipment_categories} - */ - readonly equipment_categories: string[] - readonly width: uint - readonly height: uint - /** - * If the player can move equipment into or out of this grid. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentGridPrototype.html#LuaEquipmentGridPrototype.locked View documentation} - */ - readonly locked: boolean - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaEquipmentGridPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a modular equipment. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html View documentation} - * - * @noSelf - */ -interface LuaEquipmentPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.name View documentation} - */ - readonly name: string - /** - * Type of this equipment prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.type View documentation} - */ - readonly type: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * Shape of this equipment prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.shape View documentation} - */ - readonly shape: { - readonly width: uint - readonly height: uint - /** Only set when the shape is "manual" */ - readonly points?: EquipmentPoint[] - } - /** - * The result item when taking this equipment out of an equipment grid. `nil` if there is no result item. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.take_result View documentation} - */ - readonly take_result: LuaItemPrototype | undefined - /** - * The max power generated by this equipment. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.energy_production View documentation} - */ - readonly energy_production: double - /** - * The shield value of this equipment. 0 for non-shield equipment. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.shield View documentation} - */ - readonly shield: float - /** - * The energy per shield point restored. 0 for non-shield equipment. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.energy_per_shield View documentation} - */ - readonly energy_per_shield: double - /** - * The logistic parameters for this roboport equipment. - * - * **Note**: Both the `charging_station_shift` and `stationing_offset` vectors are tables with `x` and `y` keys - * instead of an array. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.logistic_parameters View documentation} - */ - readonly logistic_parameters: { - readonly spawn_and_station_height: float - readonly spawn_and_station_shadow_height_offset: float - readonly charge_approach_distance: float - readonly logistic_radius: float - readonly construction_radius: float - readonly charging_station_count: uint - readonly charging_distance: float - readonly charging_station_shift: Vector - readonly charging_energy: double - readonly charging_threshold_distance: float - readonly robot_vertical_acceleration: float - readonly stationing_offset: Vector - readonly robot_limit: uint - readonly logistics_connection_distance: float - readonly robots_shrink_when_entering_and_exiting: boolean - } - readonly energy_consumption: double - /** - * *Can only be used if this is MovementBonusEquipmentPrototype* - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.movement_bonus View documentation} - */ - readonly movement_bonus: float - /** - * The energy source prototype for the equipment. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.energy_source View documentation} - */ - readonly energy_source: LuaElectricEnergySourcePrototype - /** - * Category names for this equipment. These categories will be used to determine whether this equipment is allowed - * in a particular equipment grid. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.equipment_categories View documentation} - * - * @see {@link LuaEquipmentGridPrototype.equipment_categories} - */ - readonly equipment_categories: string[] - /** - * The burner energy source prototype this equipment uses or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.burner_prototype View documentation} - */ - readonly burner_prototype: LuaBurnerPrototype | undefined - /** - * The electric energy source prototype this equipment uses or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.electric_energy_source_prototype View documentation} - */ - readonly electric_energy_source_prototype: LuaElectricEnergySourcePrototype | undefined - /** - * The background color of this equipment prototype. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.background_color View documentation} - */ - readonly background_color: ColorTable - /** - * The equipment attack parameters or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.attack_parameters View documentation} - */ - readonly attack_parameters: AttackParameters | undefined - /** - * Is this active defense equipment automatic. Returns false if not active defense equipment. - * - * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.automatic View documentation} - */ - readonly automatic: boolean - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaEquipmentPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Encapsulates statistic data for different parts of the game. In the context of flow statistics, `input` and `output` - * describe on which side of the associated GUI the values are shown. Input values are shown on the left side, output - * values on the right side. - * - * Examples: - * - * - The item production GUI shows "consumption" on the right, thus `output` describes the item consumption numbers. The - * same goes for fluid consumption. - * - The kills gui shows "losses" on the right, so `output` describes how many of the force's entities were killed by enemies. - * - The electric network GUI shows "power consumption" on the left side, so in this case `input` describes the power - * consumption numbers. - * - * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html View documentation} - * - * @noSelf - */ -interface LuaFlowStatistics { - /** - * Gets the total input count for a given prototype. - * - * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.get_input_count View documentation} - * - * @param name - The prototype name. - */ - get_input_count(name: string): uint64 | double - /** - * Sets the total input count for a given prototype. - * - * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.set_input_count View documentation} - * - * @param name - The prototype name. - * @param count - The new count. The type depends on the instance of the statistics. - */ - set_input_count(name: string, count: uint64 | double): void - /** - * Gets the total output count for a given prototype. - * - * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.get_output_count View documentation} - * - * @param name - The prototype name. - */ - get_output_count(name: string): uint64 | double - /** - * Sets the total output count for a given prototype. - * - * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.set_output_count View documentation} - * - * @param name - The prototype name. - * @param count - The new count. The type depends on the instance of the statistics. - */ - set_output_count(name: string, count: uint64 | double): void - /** - * Gets the flow count value for the given time frame. - * - * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.get_flow_count View documentation} - */ - get_flow_count(params: { - /** The prototype name. */ - readonly name: string - /** Read the input values or the output values */ - readonly input: boolean - /** The precision to read. */ - readonly precision_index: defines.flow_precision_index - /** If true, the count is returned instead of the per-time-frame value. */ - readonly count?: boolean - }): double - /** - * Adds a value to this flow statistics. - * - * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.on_flow View documentation} - * - * @param name - The prototype name. - * @param count - The count: positive or negative determines if the value goes in the input or output statistics. - */ - on_flow(name: string, count: float): void - /** - * Reset all the statistics data to 0. - * - * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.clear View documentation} - */ - clear(): void - /** - * List of input counts indexed by prototype name. Represents the data that is shown on the left side of the GUI for - * the given statistics. - * - * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.input_counts View documentation} - */ - readonly input_counts: Record - /** - * List of output counts indexed by prototype name. Represents the data that is shown on the right side of the GUI - * for the given statistics. - * - * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.output_counts View documentation} - */ - readonly output_counts: Record - /** - * The force these statistics belong to or `nil` for pollution statistics. - * - * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.force View documentation} - */ - readonly force: LuaForce | undefined - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaFlowStatistics" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * An array of fluid boxes of an entity. Entities may contain more than one fluid box, and some can change the number of - * fluid boxes -- for instance, an assembling machine will change its number of fluid boxes depending on its active recipe. - * - * See {@link Fluid} - * - * Do note that reading from a {@link LuaFluidBox} creates a new table and writing will copy the given fields from the - * table into the engine's own fluid box structure. Therefore, the correct way to update a fluidbox of an entity is to - * read it first, modify the table, then write the modified table back. Directly accessing the returned table's - * attributes won't have the desired effect. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBox.html View documentation} - * - * @example - * Double the temperature of the fluid in `entity`'s first fluid box. - * - * ```lua - * fluid = entity.fluidbox[1] - * fluid.temperature = fluid.temperature * 2 - * entity.fluidbox[1] = fluid - * ``` - * - * @noSelf - */ -interface LuaFluidBox extends Array { - /** - * The prototype of this fluidbox index. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.get_prototype View documentation} - * - * @param index - */ - get_prototype(index: uint): LuaFluidBoxPrototype - /** - * The capacity of the given fluidbox index. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.get_capacity View documentation} - * - * @param index - */ - get_capacity(index: uint): double - /** - * The fluidbox connections for the given fluidbox index. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.get_connections View documentation} - * - * @param index - */ - get_connections(index: uint): LuaFluidBox[] - /** - * Get a fluid box filter - * - * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.get_filter View documentation} - * - * @param index - The index of the filter to get. - * @returns The filter at the requested index. `nil` if there isn't one. - */ - get_filter(index: uint): FluidBoxFilter | undefined - /** - * Set a fluid box filter. - * - * **Note**: Some entities cannot have their fluidbox filter set, notably fluid wagons and crafting machines. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.set_filter View documentation} - * - * @param index - The index of the filter to set. - * @param filter - The filter to set. Setting `nil` clears the filter. - * @returns Whether the filter was set successfully. - */ - set_filter(index: uint, filter?: FluidBoxFilterSpec): boolean - /** - * Flow through the fluidbox in the last tick. It is the larger of in-flow and out-flow. - * - * **Note**: Fluid wagons do not track it and will return 0. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.get_flow View documentation} - * - * @param index - */ - get_flow(index: uint): double - /** - * Returns the fluid the fluidbox is locked onto Returns 'nil' for no lock - * - * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.get_locked_fluid View documentation} - * - * @param index - */ - get_locked_fluid(index: uint): string | undefined - /** - * Flushes all fluid from this fluidbox and its fluid system. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.flush View documentation} - * - * @param index - * @param fluid - If provided, only this fluid is flushed. - * @returns The fluid removed. - */ - flush(index: uint, fluid?: FluidIdentification): Record - /** - * Number of fluid boxes. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.operator%20# View documentation} - */ - readonly length: uint - /** - * The entity that owns this fluidbox. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.owner View documentation} - */ - readonly owner: LuaEntity - /** - * Access, set or clear a fluid box. The index must always be in bounds (see - * {@link LuaFluidBox.length LuaFluidBox::operator #}). New fluidboxes may not be added or removed using this - * operator. If the given fluid box doesn't contain any fluid, `nil` is returned. Similarly, `nil` can be written to - * a fluid box to remove all fluid from it. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.operator%20[] View documentation} - */ - [index: number]: Fluid | undefined - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaFluidBox" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A prototype of a fluidbox owned by some {@link LuaEntityPrototype}. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html View documentation} - * - * @noSelf - */ -interface LuaFluidBoxPrototype { - /** - * The entity that this belongs to. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.entity View documentation} - */ - readonly entity: LuaEntityPrototype - /** - * The index of this fluidbox prototype in the owning entity. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.index View documentation} - */ - readonly index: uint - /** - * The pipe connection points. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.pipe_connections View documentation} - */ - readonly pipe_connections: FluidBoxConnection[] - /** - * The production type. "input", "output", "input-output", or "none". - * - * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.production_type View documentation} - */ - readonly production_type: "input" | "output" | "input-output" | "none" - readonly base_area: double - readonly base_level: double - readonly height: double - readonly volume: double - /** - * The filter or `nil` if no filter is set. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.filter View documentation} - */ - readonly filter: LuaFluidPrototype | undefined - /** - * The minimum temperature or `nil` if none is set. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.minimum_temperature View documentation} - */ - readonly minimum_temperature: double | undefined - /** - * The maximum temperature or `nil` if none is set. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.maximum_temperature View documentation} - */ - readonly maximum_temperature: double | undefined - /** - * The secondary draw orders for the 4 possible connection directions. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.secondary_draw_orders View documentation} - */ - readonly secondary_draw_orders: int[] - /** - * The render layer. - * - * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.render_layer View documentation} - */ - readonly render_layer: string - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaFluidBoxPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a fluid energy source. - * - * {@link https://lua-api.factorio.com/next/LuaFluidEnergySourcePrototype.html View documentation} - * - * @noSelf - */ -interface LuaFluidEnergySourcePrototype { - readonly emissions: double - readonly render_no_network_icon: boolean - readonly render_no_power_icon: boolean - readonly effectivity: double - readonly burns_fluid: boolean - readonly scale_fluid_usage: boolean - readonly fluid_usage_per_tick: double - /** - * The smoke sources for this prototype if any. - * - * {@link https://lua-api.factorio.com/next/LuaFluidEnergySourcePrototype.html#LuaFluidEnergySourcePrototype.smoke View documentation} - */ - readonly smoke: SmokeSource[] - readonly maximum_temperature: double - /** - * The fluid box for this energy source. - * - * {@link https://lua-api.factorio.com/next/LuaFluidEnergySourcePrototype.html#LuaFluidEnergySourcePrototype.fluid_box View documentation} - */ - readonly fluid_box: LuaFluidBoxPrototype - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaFluidEnergySourcePrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a fluid. - * - * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html View documentation} - * - * @noSelf - */ -interface LuaFluidPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.name View documentation} - */ - readonly name: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * Default temperature of this fluid. - * - * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.default_temperature View documentation} - */ - readonly default_temperature: double - /** - * Maximum temperature this fluid can reach. - * - * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.max_temperature View documentation} - */ - readonly max_temperature: double - /** - * The amount of energy in Joules required to heat one unit of this fluid by 1°C. - * - * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.heat_capacity View documentation} - */ - readonly heat_capacity: double - /** - * Order string for this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.order View documentation} - */ - readonly order: string - /** - * Group of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.group View documentation} - */ - readonly group: LuaGroup - /** - * Subgroup of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.subgroup View documentation} - */ - readonly subgroup: LuaGroup - readonly base_color: ColorTable - readonly flow_color: ColorTable - /** - * The temperature above which this fluid will be shown as gaseous inside tanks and pipes. - * - * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.gas_temperature View documentation} - */ - readonly gas_temperature: double - /** - * A multiplier on the amount of emissions produced when this fluid is burnt in a generator. A value above `1.0` - * increases emissions and vice versa. The multiplier can't be negative. - * - * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.emissions_multiplier View documentation} - */ - readonly emissions_multiplier: double - /** - * The amount of energy in Joules one unit of this fluid will produce when burnt in a generator. A value of `0` - * means this fluid can't be used for energy generation. The value can't be negative. - * - * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.fuel_value View documentation} - */ - readonly fuel_value: double - /** - * Whether this fluid is hidden from the fluid and signal selectors. - * - * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.hidden View documentation} - */ - readonly hidden: boolean - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaFluidPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a font. - * - * {@link https://lua-api.factorio.com/next/LuaFontPrototype.html View documentation} - * - * @noSelf - */ -interface LuaFontPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaFontPrototype.html#LuaFontPrototype.name View documentation} - */ - readonly name: string - readonly from: string - readonly size: int - readonly spacing: float - readonly border: boolean - readonly filtered: boolean - /** - * The border color or `nil` if not set. - * - * {@link https://lua-api.factorio.com/next/LuaFontPrototype.html#LuaFontPrototype.border_color View documentation} - */ - readonly border_color: ColorTable | undefined - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaFontPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * `LuaForce` encapsulates data local to each "force" or "faction" of the game. Default forces are player, enemy and - * neutral. Players and mods can create additional forces (up to 64 total). - * - * {@link https://lua-api.factorio.com/next/LuaForce.html View documentation} - * - * @noSelf - */ -interface LuaForce { - /** - * Count entities of given type. - * - * **Note**: This function has O(1) time complexity as entity counts are kept and maintained in the game engine. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_entity_count View documentation} - * - * @param name - Prototype name of the entity. - * @returns Number of entities of given prototype belonging to this force. - */ - get_entity_count(name: string): uint - /** - * Disable research for this force. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.disable_research View documentation} - */ - disable_research(): void - /** - * Enable research for this force. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.enable_research View documentation} - */ - enable_research(): void - /** - * Disable all recipes and technologies. Only recipes and technologies enabled explicitly will be useable from this point. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.disable_all_prototypes View documentation} - */ - disable_all_prototypes(): void - /** - * Enables all recipes and technologies. The opposite of - * {@link LuaForce.disable_all_prototypes LuaForce::disable_all_prototypes} - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.enable_all_prototypes View documentation} - */ - enable_all_prototypes(): void - /** - * Load the original version of all recipes from the prototypes. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.reset_recipes View documentation} - */ - reset_recipes(): void - /** - * Unlock all recipes. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.enable_all_recipes View documentation} - */ - enable_all_recipes(): void - /** - * Unlock all technologies. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.enable_all_technologies View documentation} - */ - enable_all_technologies(): void - /** - * Research all technologies. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.research_all_technologies View documentation} - * - * @param include_disabled_prototypes - Whether technologies that are explicitly disabled in the prototype should - * also be researched. Defaults to `false`. - */ - research_all_technologies(include_disabled_prototypes?: boolean): void - /** - * Load the original versions of technologies from prototypes. Preserves research state of technologies. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.reset_technologies View documentation} - */ - reset_technologies(): void - /** - * Reset everything. All technologies are set to not researched, all modifiers are set to default values. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.reset View documentation} - */ - reset(): void - /** - * Reapplies all possible research effects, including unlocked recipes. Any custom changes are lost. Preserves - * research state of technologies. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.reset_technology_effects View documentation} - */ - reset_technology_effects(): void - /** - * Chart a portion of the map. The chart for the given area is refreshed; it creates chart for any parts of the - * given area that haven't been charted yet. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.chart View documentation} - * - * @example - * Charts a 2048x2048 rectangle centered around the origin. - * - * ```lua - * game.player.force.chart(game.player.surface, {{x = -1024, y = -1024}, {x = 1024, y = 1024}}) - * ``` - * - * @param surface - * @param area - The area on the given surface to chart. - */ - chart(surface: SurfaceIdentification, area: BoundingBox): void - /** - * Erases chart data for this force. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.clear_chart View documentation} - * - * @param surface - Which surface to erase chart data for or if not provided all surfaces charts are erased. - */ - clear_chart(surface?: SurfaceIdentification): void - /** - * Force a rechart of the whole chart. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.rechart View documentation} - */ - rechart(): void - /** - * Chart all generated chunks. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.chart_all View documentation} - * - * @param surface - Which surface to chart or all if not given. - */ - chart_all(surface?: SurfaceIdentification): void - /** - * Has a chunk been charted? - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.is_chunk_charted View documentation} - * - * @param surface - * @param position - Position of the chunk. - */ - is_chunk_charted(surface: SurfaceIdentification, position: ChunkPosition): boolean - /** - * Is the given chunk currently charted and visible (not covered by fog of war) on the map. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.is_chunk_visible View documentation} - * - * @param surface - * @param position - */ - is_chunk_visible(surface: SurfaceIdentification, position: ChunkPosition): boolean - /** - * Cancels pending chart requests for the given surface or all surfaces. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.cancel_charting View documentation} - * - * @param surface - */ - cancel_charting(surface?: SurfaceIdentification): void - /** - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_ammo_damage_modifier View documentation} - * - * @param ammo - Ammo category - */ - get_ammo_damage_modifier(ammo: string): double - /** - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_ammo_damage_modifier View documentation} - * - * @param ammo - Ammo category - * @param modifier - */ - set_ammo_damage_modifier(ammo: string, modifier: double): void - /** - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_gun_speed_modifier View documentation} - * - * @param ammo - Ammo category - */ - get_gun_speed_modifier(ammo: string): double - /** - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_gun_speed_modifier View documentation} - * - * @param ammo - Ammo category - * @param modifier - */ - set_gun_speed_modifier(ammo: string, modifier: double): void - /** - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_turret_attack_modifier View documentation} - * - * @param turret - Turret prototype name - */ - get_turret_attack_modifier(turret: string): double - /** - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_turret_attack_modifier View documentation} - * - * @param turret - Turret prototype name - * @param modifier - */ - set_turret_attack_modifier(turret: string, modifier: double): void - /** - * Add `other` force to this force's cease fire list. Forces on the cease fire list won't be targeted for attack. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_cease_fire View documentation} - * - * @param other - * @param cease_fire - */ - set_cease_fire(other: ForceIdentification, cease_fire: boolean): void - /** - * Is `other` force in this force's cease fire list? - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_cease_fire View documentation} - * - * @param other - */ - get_cease_fire(other: ForceIdentification): boolean - /** - * Add `other` force to this force's friends list. Friends have unrestricted access to buildings and turrets won't - * fire at them. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_friend View documentation} - * - * @param other - * @param friend - */ - set_friend(other: ForceIdentification, friend: boolean): void - /** - * Is `other` force in this force's friends list. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_friend View documentation} - * - * @param other - */ - get_friend(other: ForceIdentification): boolean - /** - * Is pathfinder busy? When the pathfinder is busy, it won't accept any more pathfinding requests. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.is_pathfinder_busy View documentation} - */ - is_pathfinder_busy(): boolean - /** - * Kill all units and flush the pathfinder. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.kill_all_units View documentation} - */ - kill_all_units(): void - /** - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.find_logistic_network_by_position View documentation} - * - * @param position - Position to find a network for - * @param surface - Surface to search on - * @returns The found network or `nil`. - */ - find_logistic_network_by_position(position: Position, surface: SurfaceIdentification): LuaLogisticNetwork | undefined - /** - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_spawn_position View documentation} - * - * @param position - The new position on the given surface. - * @param surface - Surface to set the spawn position for. - */ - set_spawn_position(position: Position, surface: SurfaceIdentification): void - /** - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_spawn_position View documentation} - * - * @param surface - */ - get_spawn_position(surface: SurfaceIdentification): PositionTable - /** - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.unchart_chunk View documentation} - * - * @param position - The chunk position to unchart. - * @param surface - Surface to unchart on. - */ - unchart_chunk(position: ChunkPosition, surface: SurfaceIdentification): void - /** - * Gets the count of a given item launched in rockets. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_item_launched View documentation} - * - * @param item - The item to get - * @returns The count of the item that has been launched. - */ - get_item_launched(item: string): uint - /** - * Sets the count of a given item launched in rockets. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_item_launched View documentation} - * - * @param item - The item to set - * @param count - The count to set - */ - set_item_launched(item: string, count: uint): void - /** - * Print text to the chat console of all players on this force. - * - * **Note**: Messages that are identical to a message sent in the last 60 ticks are not printed again. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.print View documentation} - * - * @param message - * @param color - */ - print(message: LocalisedString, color?: Color): void - /** - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_trains View documentation} - * - * @param surface - If given only trains on the surface are returned. - */ - get_trains(surface?: SurfaceIdentification): LuaTrain[] - /** - * Adds a custom chart tag to the given surface and returns the new tag or `nil` if the given position isn't valid - * for a chart tag. - * - * **Note**: The chunk must be charted for a tag to be valid at that location. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.add_chart_tag View documentation} - * - * @param surface - Which surface to add the tag to. - * @param tag - The tag to add. - */ - add_chart_tag(surface: SurfaceIdentification, tag: ChartTagSpec): LuaCustomChartTag | undefined - /** - * Finds all custom chart tags within the given bounding box on the given surface. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.find_chart_tags View documentation} - * - * @param surface - * @param area - */ - find_chart_tags(surface: SurfaceIdentification, area?: BoundingBox): LuaCustomChartTag[] - /** - * Gets the saved progress for the given technology or `nil` if there is no saved progress. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_saved_technology_progress View documentation} - * - * @param technology - The technology - * @returns The progress as a percent. - */ - get_saved_technology_progress(technology: TechnologyIdentification): double | undefined - /** - * Sets the saved progress for the given technology. The technology must not be in progress, must not be completed, - * and the new progress must be < 100%. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_saved_technology_progress View documentation} - * - * @param technology - The technology - * @param progress - Progress as a percent. Set to `nil` to remove the saved progress. - */ - set_saved_technology_progress(technology: TechnologyIdentification, progress: double | undefined): void - /** - * Resets evolution for this force to zero. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.reset_evolution View documentation} - */ - reset_evolution(): void - /** - * Play a sound for every player in this force. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.play_sound View documentation} - */ - play_sound(params: { - /** The sound to play. */ - readonly path: SoundPath - /** Where the sound should be played. If not given, it's played at the current position of each player. */ - readonly position?: Position - /** The volume of the sound to play. Must be between 0 and 1 inclusive. */ - readonly volume_modifier?: double - /** The volume mixer to play the sound through. Defaults to the default mixer for the given sound type. */ - readonly override_sound_type?: SoundType - }): void - /** - * Gets train stops matching the given filters. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_train_stops View documentation} - */ - get_train_stops(params?: { readonly name?: string | string[]; readonly surface?: SurfaceIdentification }): LuaEntity[] - /** - * Gets if the given recipe is explicitly disabled from being hand crafted. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_hand_crafting_disabled_for_recipe View documentation} - * - * @param recipe - */ - get_hand_crafting_disabled_for_recipe(recipe: string | LuaRecipe): boolean - /** - * Sets if the given recipe can be hand-crafted. This is used to explicitly disable hand crafting a recipe - it - * won't allow hand-crafting otherwise not hand-craftable recipes. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_hand_crafting_disabled_for_recipe View documentation} - * - * @param recipe - * @param hand_crafting_disabled - */ - set_hand_crafting_disabled_for_recipe(recipe: string | LuaRecipe, hand_crafting_disabled: boolean): void - /** - * Add this technology to the back of the research queue if the queue is enabled. Otherwise, set this technology to - * be researched now. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.add_research View documentation} - * - * @param technology - * @returns If the technology was added. - */ - add_research(technology: TechnologyIdentification): boolean - /** - * Stop the research currently in progress. This will remove any dependent technologies from the research queue. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.cancel_current_research View documentation} - */ - cancel_current_research(): void - /** - * Gets the linked inventory for the given prototype and link ID if it exists or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_linked_inventory View documentation} - * - * @param prototype - * @param link_id - */ - get_linked_inventory(prototype: EntityPrototypeIdentification, link_id: uint): LuaInventory | undefined - /** - * Is this force a friend? This differs from `get_friend` in that it is always true for neutral force. This is - * equivalent to checking the `friend` ForceCondition. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.is_friend View documentation} - * - * @param other - */ - is_friend(other: ForceIdentification): boolean - /** - * Is this force an enemy? This differs from `get_cease_fire` in that it is always false for neutral force. This is - * equivalent to checking the `enemy` ForceCondition. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.is_enemy View documentation} - * - * @param other - */ - is_enemy(other: ForceIdentification): boolean - /** - * Name of the force. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.name View documentation} - * - * @example - * Prints "`player`" - * - * ```lua - * game.player.print(game.player.force.name) - * ``` - */ - readonly name: string - /** - * Technologies owned by this force, indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.technologies View documentation} - * - * @example - * Researches the technology for the player's force - * - * ```lua - * game.player.force.technologies["steel-processing"].researched = true - * ``` - */ - readonly technologies: LuaCustomTable - /** - * Recipes available to this force, indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.recipes View documentation} - * - * @example - * Prints the category of the given recipe - * - * ```lua - * game.player.print(game.player.force.recipes["transport-belt"].category) - * ``` - */ - readonly recipes: LuaCustomTable - /** - * Multiplier of the manual mining speed. Default value is `0`. The actual mining speed will be multiplied by `1 + - * manual_mining_speed_modifier`. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.manual_mining_speed_modifier View documentation} - * - * @example - * Double the player's mining speed - * - * ```lua - * game.player.force.manual_mining_speed_modifier = 1 - * ``` - */ - manual_mining_speed_modifier: double - /** - * Multiplier of the manual crafting speed. Default value is `0`. The actual crafting speed will be multiplied by `1 - * + manual_crafting_speed_modifier`. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.manual_crafting_speed_modifier View documentation} - * - * @example - * Double the player's crafting speed - * - * ```lua - * game.player.force.manual_crafting_speed_modifier = 1 - * ``` - */ - manual_crafting_speed_modifier: double - laboratory_speed_modifier: double - laboratory_productivity_bonus: double - worker_robots_speed_modifier: double - worker_robots_battery_modifier: double - worker_robots_storage_bonus: double - /** - * The current technology in research, or `nil` if no research is currently ongoing. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.current_research View documentation} - */ - readonly current_research: LuaTechnology | undefined - /** - * Progress of current research, as a number in range [0, 1]. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.research_progress View documentation} - */ - research_progress: double - /** - * The previous research if any. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.previous_research View documentation} - */ - previous_research: LuaTechnology - /** - * The inserter stack size bonus for non stack inserters - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.inserter_stack_size_bonus View documentation} - */ - inserter_stack_size_bonus: double - /** - * Number of items that can be transferred by stack inserters. When writing to this value, it must be >= 0 and <= 254. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.stack_inserter_capacity_bonus View documentation} - */ - stack_inserter_capacity_bonus: uint - /** - * Number of character trash slots. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.character_trash_slot_count View documentation} - */ - character_trash_slot_count: double - /** - * Maximum number of follower robots. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.maximum_following_robot_count View documentation} - */ - maximum_following_robot_count: uint - /** - * Additional lifetime for following robots. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.following_robots_lifetime_modifier View documentation} - */ - following_robots_lifetime_modifier: double - /** - * The time, in ticks, before a placed ghost disappears. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.ghost_time_to_live View documentation} - */ - ghost_time_to_live: uint - /** - * Players belonging to this force. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.players View documentation} - */ - readonly players: LuaPlayer[] - /** - * Enables some higher-level AI behaviour for this force. When set to `true`, biters belonging to this force will - * automatically expand into new territories, build new spawners, and form unit groups. By default, this value is - * `true` for the enemy force and `false` for all others. - * - * **Note**: Setting this to `false` does not turn off biters' AI. They will still move around and attack players - * who come close. - * - * **Note**: It is necessary for a force to be AI controllable in order to be able to create unit groups or build - * bases from scripts. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.ai_controllable View documentation} - */ - ai_controllable: boolean - /** - * List of logistic networks, grouped by surface. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.logistic_networks View documentation} - */ - readonly logistic_networks: Record - /** - * The item production statistics for this force. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.item_production_statistics View documentation} - */ - readonly item_production_statistics: LuaFlowStatistics - /** - * The fluid production statistics for this force. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.fluid_production_statistics View documentation} - */ - readonly fluid_production_statistics: LuaFlowStatistics - /** - * The kill counter statistics for this force. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.kill_count_statistics View documentation} - */ - readonly kill_count_statistics: LuaFlowStatistics - /** - * The entity build statistics for this force (built and mined) - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.entity_build_count_statistics View documentation} - */ - readonly entity_build_count_statistics: LuaFlowStatistics - /** - * Modifies the running speed of all characters in this force by the given value as a percentage. Setting the - * running modifier to `0.5` makes the character run 50% faster. The minimum value of `-1` reduces the movement - * speed by 100%, resulting in a speed of `0`. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.character_running_speed_modifier View documentation} - */ - character_running_speed_modifier: double - artillery_range_modifier: double - character_build_distance_bonus: uint - character_item_drop_distance_bonus: uint - character_reach_distance_bonus: uint - character_resource_reach_distance_bonus: double - character_item_pickup_distance_bonus: double - character_loot_pickup_distance_bonus: double - /** - * The number of additional inventory slots the character main inventory has. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.character_inventory_slots_bonus View documentation} - */ - character_inventory_slots_bonus: uint - /** - * The time, in ticks, before a deconstruction order is removed. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.deconstruction_time_to_live View documentation} - */ - deconstruction_time_to_live: uint - character_health_bonus: double - max_successful_attempts_per_tick_per_construction_queue: uint - max_failed_attempts_per_tick_per_construction_queue: uint - /** - * Ability to use zoom-to-world on map. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.zoom_to_world_enabled View documentation} - */ - zoom_to_world_enabled: boolean - /** - * Ability to build ghosts through blueprint or direct ghost placement, or "mine" ghosts when using zoom-to-world. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.zoom_to_world_ghost_building_enabled View documentation} - */ - zoom_to_world_ghost_building_enabled: boolean - /** - * Ability to create new blueprints using empty blueprint item when using zoom-to-world. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.zoom_to_world_blueprint_enabled View documentation} - */ - zoom_to_world_blueprint_enabled: boolean - /** - * Ability to use deconstruction planner when using zoom-to-world. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.zoom_to_world_deconstruction_planner_enabled View documentation} - */ - zoom_to_world_deconstruction_planner_enabled: boolean - /** - * Ability to use custom selection tools when using zoom-to-world. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.zoom_to_world_selection_tool_enabled View documentation} - */ - zoom_to_world_selection_tool_enabled: boolean - /** - * `true` if character requester logistics is enabled. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.character_logistic_requests View documentation} - */ - character_logistic_requests: boolean - /** - * The number of rockets launched. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.rockets_launched View documentation} - */ - rockets_launched: uint - /** - * All of the items that have been launched in rockets. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.items_launched View documentation} - */ - readonly items_launched: Record - /** - * The connected players belonging to this force. - * - * This is primarily useful when you want to do some action against all online players of this force. - * - * **Note**: This does *not* index using player index. See {@link LuaPlayer.index LuaPlayer::index} on each player - * instance for the player index. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.connected_players View documentation} - */ - readonly connected_players: LuaPlayer[] - mining_drill_productivity_bonus: double - train_braking_force_bonus: double - /** - * Evolution factor of this force. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.evolution_factor View documentation} - */ - evolution_factor: double - evolution_factor_by_pollution: double - evolution_factor_by_time: double - evolution_factor_by_killing_spawners: double - /** - * If friendly fire is enabled for this force. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.friendly_fire View documentation} - */ - friendly_fire: boolean - /** - * If sharing chart data is enabled for this force. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.share_chart View documentation} - */ - share_chart: boolean - /** - * Whether the research queue is available for this force. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.research_queue_enabled View documentation} - */ - research_queue_enabled: boolean - /** - * Unique ID associated with this force. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.index View documentation} - */ - readonly index: uint - /** - * The research queue of this force. The first technology in the array is the currently active one. Reading this - * attribute gives an array of {@link LuaTechnology}. - * - * To write to this, the entire table must be written. Providing an empty table or `nil` will empty the research - * queue and cancel the current research. Writing to this when the research queue is disabled will simply set the - * last research in the table as the current research. - * - * **Note**: This only allows mods to queue research that this force is able to research in the first place. As an - * example, an already researched technology or one whose prerequisites are not fulfilled will not be queued, but - * dropped silently instead. - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.research_queue View documentation} - */ - research_queue: TechnologyIdentification[] | undefined - /** - * Whether research is enabled for this force, see {@link LuaForce.enable_research LuaForce::enable_research} and - * {@link LuaForce.disable_research LuaForce::disable_research} - * - * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.research_enabled View documentation} - */ - readonly research_enabled: boolean - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaForce" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a fuel category. - * - * {@link https://lua-api.factorio.com/next/LuaFuelCategoryPrototype.html View documentation} - * - * @noSelf - */ -interface LuaFuelCategoryPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaFuelCategoryPrototype.html#LuaFuelCategoryPrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaFuelCategoryPrototype.html#LuaFuelCategoryPrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaFuelCategoryPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Main toplevel type, provides access to most of the API though its members. An instance of LuaGameScript is available - * as the global object named `game`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html View documentation} - * - * @noSelf - */ -interface LuaGameScript { - /** - * Set scenario state. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.set_game_state View documentation} - */ - set_game_state(params: { - readonly game_finished: boolean - readonly player_won: boolean - readonly next_level: string - readonly can_continue: boolean - readonly victorious_force: ForceIdentification - }): void - /** - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_entity_by_tag View documentation} - * - * @param tag - */ - get_entity_by_tag(tag: string): LuaEntity - /** - * Show an in-game message dialog. - * - * **Note**: Can only be used when the map contains exactly one player. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.show_message_dialog View documentation} - */ - show_message_dialog(params: { - /** What the dialog should say */ - readonly text: LocalisedString - /** Path to an image to show on the dialog */ - readonly image?: string - /** - * If specified, dialog will show an arrow pointing to this place. When not specified, the arrow will point to - * the player's position. (Use `point_to={type="nowhere"}` to remove the arrow entirely.) The dialog itself will - * be placed near the arrow's target. - */ - readonly point_to?: GuiArrowSpecification - /** The gui style to use for this speech bubble. Must be of type speech_bubble. */ - readonly style?: string - /** Must be of type flow_style. */ - readonly wrapper_frame_style?: string - }): void - /** - * Is this the demo version of Factorio? - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.is_demo View documentation} - */ - is_demo(): boolean - /** - * Forces a reload of the scenario script from the original scenario location. - * - * **Note**: This disables the replay if replay is enabled. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.reload_script View documentation} - */ - reload_script(): void - /** - * Forces a reload of all mods. - * - * **Note**: This will act like saving and loading from the mod(s) perspective. - * - * **Note**: This will do nothing if run in multiplayer. - * - * **Note**: This disables the replay if replay is enabled. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.reload_mods View documentation} - */ - reload_mods(): void - /** - * Saves the current configuration of Atlas to a file. This will result in huge file containing all of the game - * graphics moved to as small space as possible. - * - * **Note**: Exists mainly for debugging reasons. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.save_atlas View documentation} - */ - save_atlas(): void - /** - * Run internal consistency checks. Allegedly prints any errors it finds. - * - * **Note**: Exists mainly for debugging reasons. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.check_consistency View documentation} - */ - check_consistency(): void - /** - * Regenerate autoplacement of some entities on all surfaces. This can be used to autoplace newly-added entities. - * - * **Note**: All specified entity prototypes must be autoplacable. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.regenerate_entity View documentation} - * - * @param entities - Prototype names of entity or entities to autoplace. - */ - regenerate_entity(entities: string | string[]): void - /** - * Take a screenshot and save it to a file. - * - * **Note**: If Factorio is running headless, this function will do nothing. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.take_screenshot View documentation} - */ - take_screenshot(params: { - readonly player?: PlayerIdentification - /** If defined, the screenshot will only be taken for this player. */ - readonly by_player?: PlayerIdentification - /** If defined, the screenshot will be taken on this surface. */ - readonly surface?: SurfaceIdentification - /** If defined, the screenshot will be centered on this position. */ - readonly position?: Position - /** - * Maximum allowed resolution is 16384x16384 (resp. 8192x8192 when anti_alias is true), but maximum recommended - * resolution is 4096x4096 (resp. 2048x2048). - */ - readonly resolution?: Position - readonly zoom?: double - /** Path to save the screenshot in */ - readonly path?: string - /** Include game GUI in the screenshot? */ - readonly show_gui?: boolean - /** Include entity info (alt-mode)? */ - readonly show_entity_info?: boolean - /** When true, and player is specified, building preview for item in player's cursor will be rendered also. */ - readonly show_cursor_building_preview?: boolean - /** Render in double resolution and scale down (including GUI)? */ - readonly anti_alias?: boolean - /** The render quality if using jpg format (0-100 inclusive). */ - readonly quality?: int - /** - * If true, the screenshot will be saved even during replay playback, otherwise this function call does nothing - * in replays. - */ - readonly allow_in_replay?: boolean - /** Overrides current surface daytime for duration of screenshot rendering. */ - readonly daytime?: double - /** Overrides tick of water animation (if animated water is enabled). */ - readonly water_tick?: uint - /** - * Screenshot requests are processed in between update and render. The game may skip rendering (drop frames) if - * previous frame has not finished rendering or the game simulation starts to fall under 60 updates per second. - * If force_render is set to true, the game won't drop frames and process the screenshot request at the end of - * the update in which the request was created. This is not honored on multiplayer clients that are catching up - * to server. - */ - readonly force_render?: boolean - }): void - /** - * Forces the screenshot saving system to wait until all queued screenshots have been written to disk. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.set_wait_for_screenshots_to_finish View documentation} - */ - set_wait_for_screenshots_to_finish(): void - take_technology_screenshot(params: { - /** The force to use. If not given the `"player`" force is used. */ - readonly force?: ForceIdentification - /** Path to save the screenshot in. */ - readonly path?: string - /** If defined, the screenshot will only be taken for this player. */ - readonly by_player?: PlayerIdentification - /** The technology to highlight. */ - readonly selected_technology?: TechnologyIdentification - /** - * If `true`, disabled technologies will be skipped. Their successors will be attached to the disabled - * technology's parents. Defaults to `false`. - */ - readonly skip_disabled?: boolean - /** The render quality if using jpg format (0-100 inclusive). */ - readonly quality?: int - }): void - /** - * Convert a table to a JSON string - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.table_to_json View documentation} - * - * @param data - */ - table_to_json(data: table): string - /** - * Convert a JSON string to a table. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.json_to_table View documentation} - * - * @param json - The string to convert. - * @returns The returned object, or `nil` if the json was invalid. - */ - json_to_table(json: string): AnyBasic | undefined - /** - * Write a string to a file. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.write_file View documentation} - * - * @param filename - Path to the file to write to. - * @param data - File content - * @param append - When `true`, this will append to the end of the file. Defaults to `false`, which will overwrite - * any pre-existing file with the new data. - * @param for_player - If given, the file will only be written for this player_index. 0 means only the server if one exists. - */ - write_file(filename: string, data: LocalisedString, append?: boolean, for_player?: uint): void - /** - * Remove file or directory. Given path is taken relative to the script output directory. Can be used to remove - * files created by {@link LuaGameScript.write_file LuaGameScript::write_file}. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.remove_path View documentation} - * - * @param path - Path to remove, relative to the script output directory - */ - remove_path(path: string): void - /** - * Remove players who are currently not connected from the map. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.remove_offline_players View documentation} - * - * @param players - List of players to remove. If not specified, remove all offline players. - */ - remove_offline_players(players?: (LuaPlayer | string)[]): void - /** - * Force a CRC check. Tells all peers to calculate their current map CRC; these CRC are then compared against each - * other. If a mismatch is detected, the game is desynced and some peers are forced to reconnect. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.force_crc View documentation} - */ - force_crc(): void - /** - * Create a new force. - * - * **Note**: The game currently supports a maximum of 64 forces, including the three built-in forces. This means - * that a maximum of 61 new forces may be created. - * - * **Note**: Force names must be unique. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.create_force View documentation} - * - * @param force - Name of the new force - * @returns The force that was just created - */ - create_force(force: string): LuaForce - /** - * Marks two forces to be merge together. All entities in the source force will be reassigned to the target force. - * The source force will then be destroyed. - * - * **Note**: The three built-in forces -- player, enemy and neutral -- can't be destroyed. I.e. they can't be used - * as the source argument to this function. - * - * **Note**: The source force is not merged until the end of the current tick or if called during the - * {@link OnForcesMergingEvent on_forces_merging} event or {@link OnForcesMergedEvent on_forces_merged} event the end - * of the next tick. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.merge_forces View documentation} - * - * @param source - The force to remove - * @param destination - The force to reassign all entities to - */ - merge_forces(source: ForceIdentification, destination: ForceIdentification): void - /** - * Create a new surface - * - * **Note**: The game currently supports a maximum of 4,294,967,295 surfaces, including the default surface. - * - * **Note**: Surface names must be unique - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.create_surface View documentation} - * - * @param name - Name of the new surface - * @param settings - Map generation settings - * @returns The surface that was just created - */ - create_surface(name: string, settings?: MapGenSettings): LuaSurface - /** - * Instruct the server to save the map. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.server_save View documentation} - * - * @param name - Save name. If not specified, writes into the currently-running save. - */ - server_save(name?: string): void - /** - * Instruct the game to perform an auto-save. - * - * **Note**: Only the server will save in multiplayer. In single player a standard auto-save is triggered. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.auto_save View documentation} - * - * @param name - The autosave name if any. Saves will be named _autosave-*name* when provided. - */ - auto_save(name?: string): void - /** - * Deletes the given surface and all entities on it. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.delete_surface View documentation} - * - * @param surface - The surface to be deleted. Currently the primary surface (1, 'nauvis') cannot be deleted. - */ - delete_surface(surface: string | LuaSurface): void - /** - * Disables replay saving for the current save file. Once done there's no way to re-enable replay saving for the - * save file without loading an old save. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.disable_replay View documentation} - */ - disable_replay(): void - /** - * Disables tutorial triggers, that unlock new tutorials and show notices about unlocked tutorials. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.disable_tutorial_triggers View documentation} - */ - disable_tutorial_triggers(): void - /** - * Converts the given direction into the string version of the direction. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.direction_to_string View documentation} - * - * @param direction - */ - direction_to_string(direction: defines.direction): void - /** - * Print text to the chat console all players. - * - * **Note**: Messages that are identical to a message sent in the last 60 ticks are not printed again. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.print View documentation} - * - * @param message - * @param color - */ - print(message: LocalisedString, color?: Color): void - /** - * Creates a deterministic standalone random generator with the given seed or if a seed is not provided the initial - * map seed is used. - * - * **Note**: *Make sure* you actually want to use this over math.random(...) as this provides entirely different - * functionality over math.random(...). - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.create_random_generator View documentation} - * - * @param seed - */ - create_random_generator(seed?: uint): LuaRandomGenerator - /** - * Goes over all items, entities, tiles, recipes, technologies among other things and logs if the locale is incorrect. - * - * **Note**: Also prints true/false if called from the console. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.check_prototype_translations View documentation} - */ - check_prototype_translations(): void - /** - * Play a sound for every player in the game. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.play_sound View documentation} - */ - play_sound(params: { - /** The sound to play. */ - readonly path: SoundPath - /** Where the sound should be played. If not given, it's played at the current position of each player. */ - readonly position?: Position - /** The volume of the sound to play. Must be between 0 and 1 inclusive. */ - readonly volume_modifier?: double - /** The volume mixer to play the sound through. Defaults to the default mixer for the given sound type. */ - readonly override_sound_type?: SoundType - }): void - /** - * Checks if the given SoundPath is valid. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.is_valid_sound_path View documentation} - * - * @param sound_path - Path to the sound. - */ - is_valid_sound_path(sound_path: SoundPath): boolean - /** - * Checks if the given SpritePath is valid and contains a loaded sprite. - * - * **Note**: The existence of the image is not checked for paths of type `file`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.is_valid_sprite_path View documentation} - * - * @param sprite_path - Path to the image. - */ - is_valid_sprite_path(sprite_path: SpritePath): boolean - /** - * Kicks the given player from this multiplayer game. Does nothing if this is a single player game or if the player - * running this isn't an admin. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.kick_player View documentation} - * - * @param player - The player to kick. - * @param reason - The reason given if any. - */ - kick_player(player: PlayerIdentification, reason?: LocalisedString): void - /** - * Bans the given player from this multiplayer game. Does nothing if this is a single player game of if the player - * running this isn't an admin. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.ban_player View documentation} - * - * @param player - The player to ban. - * @param reason - The reason given if any. - */ - ban_player(player: PlayerIdentification, reason?: LocalisedString): void - /** - * Unbans the given player from this multiplayer game. Does nothing if this is a single player game of if the player - * running this isn't an admin. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.unban_player View documentation} - * - * @param player - The player to unban. - */ - unban_player(player: PlayerIdentification): void - /** - * Purges the given players messages from the game. Does nothing if the player running this isn't an admin. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.purge_player View documentation} - * - * @param player - The player to purge. - */ - purge_player(player: PlayerIdentification): void - /** - * Mutes the given player. Does nothing if the player running this isn't an admin. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.mute_player View documentation} - * - * @param player - The player to mute. - */ - mute_player(player: PlayerIdentification): void - /** - * Unmutes the given player. Does nothing if the player running this isn't an admin. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.unmute_player View documentation} - * - * @param player - The player to unmute. - */ - unmute_player(player: PlayerIdentification): void - /** - * Counts how many distinct groups of pipes exist in the world. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.count_pipe_groups View documentation} - */ - count_pipe_groups(): void - /** - * Is the map loaded is multiplayer? - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.is_multiplayer View documentation} - */ - is_multiplayer(): boolean - /** - * Gets the number of entities that are active (updated each tick). - * - * **Note**: This is very expensive to calculate. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_active_entities_count View documentation} - * - * @param surface - If give, only the entities active on this surface are counted. - */ - get_active_entities_count(surface?: SurfaceIdentification): uint - /** - * Gets the map exchange string for the map generation settings that were used to create this map. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_map_exchange_string View documentation} - */ - get_map_exchange_string(): string - /** - * Convert a map exchange string to map gen settings and map settings. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.parse_map_exchange_string View documentation} - * - * @param map_exchange_string - */ - parse_map_exchange_string(map_exchange_string: string): MapExchangeStringData - /** - * Gets train stops matching the given filters. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_train_stops View documentation} - */ - get_train_stops(params?: { - readonly name?: string | string[] - readonly surface?: SurfaceIdentification - readonly force?: ForceIdentification - }): LuaEntity[] - /** - * Gets the given player or returns `nil` if no player is found. - * - * **Note**: This is a shortcut for game.players[...] - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_player View documentation} - * - * @param player - The player index or name. - */ - get_player(player: uint | string): LuaPlayer | undefined - /** - * Gets the given surface or returns `nil` if no surface is found. - * - * **Note**: This is a shortcut for game.surfaces[...] - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_surface View documentation} - * - * @param surface - The surface index or name. - */ - get_surface(surface: uint | string): LuaSurface | undefined - /** - * Creates a {@link LuaProfiler}, which is used for measuring script performance. - * - * **Note**: LuaProfiler cannot be serialized. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.create_profiler View documentation} - * - * @param stopped - Create the timer stopped - */ - create_profiler(stopped?: boolean): LuaProfiler - /** - * Evaluate an expression, substituting variables as provided. For details on the formula, see the relevant page on - * the {@link https://wiki.factorio.com/Prototype/Technology#unit Factorio wiki}. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.evaluate_expression View documentation} - * - * @example - * Calculate the number of research units required to unlock mining productivity level 10. - * - * ```lua - * local formula = game.forces["player"].technologies["mining-productivity-4"].research_unit_count_formula - * local units = game.evaluate_expression(formula, { L = 10, l = 10 }) - * ``` - * - * @param expression - The expression to evaluate. - * @param variables - Variables to be substituted. - */ - evaluate_expression(expression: string, variables?: Record): double - /** - * Returns a dictionary of all LuaEntityPrototypes that fit the given filters. The prototypes are indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_entity_prototypes View documentation} - * - * @example - * Get every entity prototype that can craft recipes involving fluids in the way some assembling machines can. - * - * ```lua - * local prototypes = game.get_filtered_entity_prototypes{{filter="crafting-category", crafting_category="crafting-with-fluid"}} - * ``` - * - * @param filters - */ - get_filtered_entity_prototypes(filters: EntityPrototypeFilter[]): LuaCustomTable - /** - * Returns a dictionary of all LuaItemPrototypes that fit the given filters. The prototypes are indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_item_prototypes View documentation} - * - * @example - * Get every item prototype that, when launched with a rocket, produces a result. - * - * ```lua - * local prototypes = game.get_filtered_item_prototypes{{filter="has-rocket-launch-products"}} - * ``` - * - * @param filters - */ - get_filtered_item_prototypes(filters: ItemPrototypeFilter[]): LuaCustomTable - /** - * Returns a dictionary of all LuaEquipmentPrototypes that fit the given filters. The prototypes are indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_equipment_prototypes View documentation} - * - * @example - * Get every equipment prototype that functions as a battery. - * - * ```lua - * local prototypes = game.get_filtered_equipment_prototypes{{filter="type", type="battery-equipment"}} - * ``` - * - * @param filters - */ - get_filtered_equipment_prototypes(filters: EquipmentPrototypeFilter[]): LuaCustomTable - /** - * Returns a dictionary of all LuaModSettingPrototypes that fit the given filters. The prototypes are indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_mod_setting_prototypes View documentation} - * - * @example - * Get every mod setting prototype that belongs to the specified mod. - * - * ```lua - * local prototypes = game.get_filtered_mod_setting_prototypes{{filter="mod", mod="space-exploration"}} - * ``` - * - * @param filters - */ - get_filtered_mod_setting_prototypes( - filters: ModSettingPrototypeFilter[] - ): LuaCustomTable - /** - * Returns a dictionary of all LuaAchievementPrototypes that fit the given filters. The prototypes are indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_achievement_prototypes View documentation} - * - * @example - * Get every achievement prototype that is not allowed to be completed on the peaceful difficulty setting. - * - * ```lua - * local prototypes = game.get_filtered_achievement_prototypes{{filter="allowed-without-fight", invert=true}} - * ``` - * - * @param filters - */ - get_filtered_achievement_prototypes( - filters: AchievementPrototypeFilter[] - ): LuaCustomTable - /** - * Returns a dictionary of all LuaTilePrototypes that fit the given filters. The prototypes are indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_tile_prototypes View documentation} - * - * @example - * Get every tile prototype that improves a player's walking speed by at least 50%. - * - * ```lua - * local prototypes = game.get_filtered_tile_prototypes{{filter="walking-speed-modifier", comparison="≥", value=1.5}} - * ``` - * - * @param filters - */ - get_filtered_tile_prototypes(filters: TilePrototypeFilter[]): LuaCustomTable - /** - * Returns a dictionary of all LuaDecorativePrototypes that fit the given filters. The prototypes are indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_decorative_prototypes View documentation} - * - * @example - * Get every decorative prototype that is auto-placed. - * - * ```lua - * local prototypes = game.get_filtered_decorative_prototypes{{filter="autoplace"}} - * ``` - * - * @param filters - */ - get_filtered_decorative_prototypes( - filters: DecorativePrototypeFilter[] - ): LuaCustomTable - /** - * Returns a dictionary of all LuaFluidPrototypes that fit the given filters. The prototypes are indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_fluid_prototypes View documentation} - * - * @example - * Get every fluid prototype that has a heat capacity of exactly `100`. - * - * ```lua - * local prototypes = game.get_filtered_fluid_prototypes{{filter="heat-capacity", comparison="=", value=100}} - * ``` - * - * @param filters - */ - get_filtered_fluid_prototypes(filters: FluidPrototypeFilter[]): LuaCustomTable - /** - * Returns a dictionary of all LuaRecipePrototypes that fit the given filters. The prototypes are indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_recipe_prototypes View documentation} - * - * @example - * Get every recipe prototype that takes less than half a second to craft (at crafting speed `1`). - * - * ```lua - * local prototypes = game.get_filtered_recipe_prototypes{{filter="energy", comparison="<", value=0.5}} - * ``` - * - * @param filters - */ - get_filtered_recipe_prototypes(filters: RecipePrototypeFilter[]): LuaCustomTable - /** - * Returns a dictionary of all LuaTechnologyPrototypes that fit the given filters. The prototypes are indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_technology_prototypes View documentation} - * - * @example - * Get every technology prototype that can be researched at the start of the game. - * - * ```lua - * local prototypes = game.get_filtered_technology_prototypes{{filter="has-prerequisites", invert=true}} - * ``` - * - * @param filters - */ - get_filtered_technology_prototypes( - filters: TechnologyPrototypeFilter[] - ): LuaCustomTable - /** - * Creates an inventory that is not owned by any game object. It can be resized later with - * {@link LuaInventory.resize LuaInventory::resize}. - * - * **Note**: Make sure to destroy it when you are done with it with {@link LuaInventory.destroy LuaInventory::destroy}. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.create_inventory View documentation} - * - * @param size - The number of slots the inventory initially has. - */ - create_inventory(size: uint16): LuaInventory - /** - * Gets the inventories created through {@link LuaGameScript.create_inventory LuaGameScript::create_inventory} - * - * **Note**: Inventories created through console commands will be owned by `"core"`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_script_inventories View documentation} - * - * @param mod - The mod who's inventories to get. If not provided all inventories are returned. - * @returns A mapping of mod name to array of inventories owned by that mod. - */ - get_script_inventories(mod?: string): Record - /** - * Resets the amount of time played for this map. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.reset_time_played View documentation} - */ - reset_time_played(): void - /** - * Deflates and base64 encodes the given string. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.encode_string View documentation} - * - * @param string - The string to encode. - * @returns The encoded string or `nil` if the encode failed. - */ - encode_string(string: string): string | undefined - /** - * Base64 decodes and inflates the given string. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.decode_string View documentation} - * - * @param string - The string to decode. - * @returns The decoded string or `nil` if the decode failed. - */ - decode_string(string: string): string | undefined - /** - * The player typing at the console - `nil` in all other instances. See - * {@link LuaGameScript.players LuaGameScript::players} for accessing all players. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.player View documentation} - */ - readonly player: LuaPlayer | undefined - /** - * Get a table of all the players that currently exist. This sparse table allows you to find players by indexing it - * with either their `name` or `index`. Iterating this table with `pairs()` will only iterate the array part of the - * table. Iterating with `ipairs()` will not work at all. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.players View documentation} - */ - readonly players: LuaCustomTable - /** - * The currently active set of map settings. Even though this property is marked as read-only, the members of the - * dictionary that is returned can be modified mid-game. - * - * **Note**: This does not contain difficulty settings, use - * {@link LuaGameScript.difficulty_settings LuaGameScript::difficulty_settings} instead. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.map_settings View documentation} - */ - readonly map_settings: MapSettings - /** - * The currently active set of difficulty settings. Even though this property is marked as read-only, the members of - * the dictionary that is returned can be modified mid-game. This is however not recommended as different - * difficulties can have differing technology and recipe trees, which can cause problems for players. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.difficulty_settings View documentation} - * - * @example - * This will set the technology price multiplier to 12. - * - * ```lua - * game.difficulty_settings.technology_price_multiplier = 12 - * ``` - */ - readonly difficulty_settings: DifficultySettings - /** - * Current scenario difficulty. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.difficulty View documentation} - */ - readonly difficulty: defines.difficulty - /** - * Get a table of all the forces that currently exist. This sparse table allows you to find forces by indexing it - * with either their `name` or `index`. Iterating this table with `pairs()` will only iterate the array part of the - * table. Iterating with `ipairs()` will not work at all. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.forces View documentation} - */ - readonly forces: LuaCustomTable - /** - * A dictionary containing every LuaEntityPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.entity_prototypes View documentation} - */ - readonly entity_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaItemPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.item_prototypes View documentation} - */ - readonly item_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaFluidPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.fluid_prototypes View documentation} - */ - readonly fluid_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaTilePrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.tile_prototypes View documentation} - */ - readonly tile_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaEquipmentPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.equipment_prototypes View documentation} - */ - readonly equipment_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaDamagePrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.damage_prototypes View documentation} - */ - readonly damage_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaVirtualSignalPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.virtual_signal_prototypes View documentation} - */ - readonly virtual_signal_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaEquipmentGridPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.equipment_grid_prototypes View documentation} - */ - readonly equipment_grid_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaRecipePrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.recipe_prototypes View documentation} - */ - readonly recipe_prototypes: LuaCustomTable - /** - * A dictionary containing every {@link LuaTechnologyPrototype} indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.technology_prototypes View documentation} - */ - readonly technology_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaDecorativePrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.decorative_prototypes View documentation} - */ - readonly decorative_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaParticlePrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.particle_prototypes View documentation} - */ - readonly particle_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaAutoplaceControlPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.autoplace_control_prototypes View documentation} - */ - readonly autoplace_control_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaNoiseLayerPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.noise_layer_prototypes View documentation} - */ - readonly noise_layer_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaModSettingPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.mod_setting_prototypes View documentation} - */ - readonly mod_setting_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaCustomInputPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.custom_input_prototypes View documentation} - */ - readonly custom_input_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaAmmoCategoryPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.ammo_category_prototypes View documentation} - */ - readonly ammo_category_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaNamedNoiseExpression indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.named_noise_expressions View documentation} - */ - readonly named_noise_expressions: LuaCustomTable - /** - * A dictionary containing every ItemSubgroup indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.item_subgroup_prototypes View documentation} - */ - readonly item_subgroup_prototypes: LuaCustomTable - /** - * A dictionary containing every ItemGroup indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.item_group_prototypes View documentation} - */ - readonly item_group_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaFuelCategoryPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.fuel_category_prototypes View documentation} - */ - readonly fuel_category_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaResourceCategoryPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.resource_category_prototypes View documentation} - */ - readonly resource_category_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaAchievementPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.achievement_prototypes View documentation} - */ - readonly achievement_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaModuleCategoryPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.module_category_prototypes View documentation} - */ - readonly module_category_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaEquipmentCategoryPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.equipment_category_prototypes View documentation} - */ - readonly equipment_category_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaTrivialSmokePrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.trivial_smoke_prototypes View documentation} - */ - readonly trivial_smoke_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaShortcutPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.shortcut_prototypes View documentation} - */ - readonly shortcut_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaRecipeCategoryPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.recipe_category_prototypes View documentation} - */ - readonly recipe_category_prototypes: LuaCustomTable - /** - * A dictionary containing every LuaFontPrototype indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.font_prototypes View documentation} - */ - readonly font_prototypes: LuaCustomTable - /** - * A dictionary containing every MapGenPreset indexed by `name`. - * - * **Note**: A MapGenPreset is an exact copy of the prototype table provided from the data stage. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.map_gen_presets View documentation} - */ - readonly map_gen_presets: LuaCustomTable - /** - * The styles that {@link LuaGuiElement} can use, indexed by `name`. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.styles View documentation} - */ - readonly styles: LuaCustomTable - /** - * Current map tick. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.tick View documentation} - */ - readonly tick: uint - /** - * The number of ticks since this game was 'created'. A game is 'created' either by using "new game" or "new game - * from scenario". - * - * **Note**: This differs over {@link LuaGameScript.tick LuaGameScript::tick} in that making a game from a scenario - * always starts with ticks_played value at 0 even if the scenario has its own level data where the - * {@link LuaGameScript.tick LuaGameScript::tick} is > 0. - * - * **Note**: This value has no relation with {@link LuaGameScript.tick LuaGameScript::tick} and can be completely - * different values. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.ticks_played View documentation} - */ - readonly ticks_played: uint - /** - * If the tick has been paused. This means that entity update has been paused. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.tick_paused View documentation} - */ - tick_paused: boolean - /** - * The number of ticks to be run while the tick is paused. When - * {@link LuaGameScript.tick_paused LuaGameScript::tick_paused} is true, ticks_to_run behaves the following way: - * While this is > 0, the entity update is running normally and this value is decremented every tick. When this - * reaches 0, the game will pause again. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.ticks_to_run View documentation} - */ - ticks_to_run: uint - /** - * Is the scenario finished? - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.finished View documentation} - */ - readonly finished: boolean - /** - * Speed to update the map at. 1.0 is normal speed -- 60 UPS. - * - * **Note**: Minimum value is 0.01. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.speed View documentation} - */ - speed: float - /** - * Get a table of all the surfaces that currently exist. This sparse table allows you to find surfaces by indexing - * it with either their `name` or `index`. Iterating this table with `pairs()` will only iterate the array part of - * the table. Iterating with `ipairs()` will not work at all. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.surfaces View documentation} - */ - readonly surfaces: LuaCustomTable - /** - * The active mods versions. The keys are mod names, the values are the versions. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.active_mods View documentation} - * - * @example - * This will print the names and versions of active mods to player p's console. - * - * ```lua - * for name, version in pairs(game.active_mods) do - * p.print(name .. " version " .. version) - * end - * ``` - */ - readonly active_mods: Record - /** - * The players that are currently online. - * - * This is primarily useful when you want to do some action against all online players. - * - * **Note**: This does *not* index using player index. See {@link LuaPlayer.index LuaPlayer::index} on each player - * instance for the player index. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.connected_players View documentation} - */ - readonly connected_players: LuaPlayer[] - readonly permissions: LuaPermissionGroups - /** - * Array of the names of all the backers that supported the game development early on. These are used as names for - * labs, locomotives, radars, roboports, and train stops. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.backer_names View documentation} - */ - readonly backer_names: LuaCustomTable - /** - * The default map gen settings for this save. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.default_map_gen_settings View documentation} - */ - readonly default_map_gen_settings: MapGenSettings - /** - * Determines if enemy land mines are completely invisible or not. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.enemy_has_vision_on_land_mines View documentation} - */ - enemy_has_vision_on_land_mines: boolean - /** - * True by default. Can be used to disable autosaving. Make sure to turn it back on soon after. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.autosave_enabled View documentation} - */ - autosave_enabled: boolean - /** - * True by default. Can be used to disable the highlighting of resource patches when they are hovered on the map. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.draw_resource_selection View documentation} - */ - draw_resource_selection: boolean - /** - * The pollution statistics for this map. - * - * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.pollution_statistics View documentation} - */ - readonly pollution_statistics: LuaFlowStatistics - readonly max_force_distraction_distance: double - readonly max_force_distraction_chunk_distance: uint - readonly max_electric_pole_supply_area_distance: float - readonly max_electric_pole_connection_distance: double - readonly max_beacon_supply_area_distance: double - readonly max_gate_activation_distance: double - readonly max_inserter_reach_distance: double - readonly max_pipe_to_ground_distance: uint8 - readonly max_underground_belt_distance: uint8 - /** This object's name. */ - readonly object_name: "LuaGameScript" -} - -/** - * An abstract base class for behaviors that support switching the entity on or off based on some condition. - * - * {@link https://lua-api.factorio.com/next/LuaGenericOnOffControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaGenericOnOffControlBehavior extends LuaControlBehavior { - /** - * If the entity is currently disabled because of the control behavior. - * - * {@link https://lua-api.factorio.com/next/LuaGenericOnOffControlBehavior.html#LuaGenericOnOffControlBehavior.disabled View documentation} - */ - readonly disabled: boolean - /** - * The circuit condition. - * - * **Note**: `condition` may be `nil` in order to clear the circuit condition. - * - * {@link https://lua-api.factorio.com/next/LuaGenericOnOffControlBehavior.html#LuaGenericOnOffControlBehavior.circuit_condition View documentation} - * - * @example - * Tell an entity to be active (e.g. a lamp to be lit) when it receives a circuit signal of more than 4 chain signals. - * - * ```lua - * a_behavior.circuit_condition = {condition={comparator=">", - * first_signal={type="item", name="rail-chain-signal"}, - * constant=4}} - * ``` - */ - circuit_condition: CircuitConditionDefinition - /** - * The logistic condition. - * - * **Note**: `condition` may be `nil` in order to clear the logistic condition. - * - * {@link https://lua-api.factorio.com/next/LuaGenericOnOffControlBehavior.html#LuaGenericOnOffControlBehavior.logistic_condition View documentation} - * - * @example - * Tell an entity to be active (e.g. a lamp to be lit) when the logistics network it's connected to has more than four chain signals. - * - * ```lua - * a_behavior.logistic_condition = {condition={comparator=">", - * first_signal={type="item", name="rail-chain-signal"}, - * constant=4}} - * ``` - */ - logistic_condition: CircuitConditionDefinition - /** - * `true` if this should connect to the logistic network. - * - * {@link https://lua-api.factorio.com/next/LuaGenericOnOffControlBehavior.html#LuaGenericOnOffControlBehavior.connect_to_logistic_network View documentation} - */ - connect_to_logistic_network: boolean - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: string - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Item group or subgroup. - * - * {@link https://lua-api.factorio.com/next/LuaGroup.html View documentation} - * - * @noSelf - */ -interface LuaGroup { - readonly name: string - /** - * Localised name of the group. - * - * {@link https://lua-api.factorio.com/next/LuaGroup.html#LuaGroup.localised_name View documentation} - */ - readonly localised_name: LocalisedString - readonly type: string - /** - * The parent group if any; `nil` if none. - * - * {@link https://lua-api.factorio.com/next/LuaGroup.html#LuaGroup.group View documentation} - */ - readonly group: LuaGroup | undefined - /** - * Subgroups of this group. - * - * **Note**: Can only be used on groups, not on subgroups. - * - * {@link https://lua-api.factorio.com/next/LuaGroup.html#LuaGroup.subgroups View documentation} - */ - readonly subgroups: LuaGroup[] - /** - * The additional order value used in recipe ordering. - * - * **Note**: Can only be used on groups, not on subgroups. - * - * {@link https://lua-api.factorio.com/next/LuaGroup.html#LuaGroup.order_in_recipe View documentation} - */ - readonly order_in_recipe: string - readonly order: string - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaGroup" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * The root of the GUI. This type houses the root elements, `top`, `left`, `center`, `goal`, and `screen`, to which - * other elements can be added to be displayed on screen. - * - * **Note**: Every player can have a different GUI state. - * - * {@link https://lua-api.factorio.com/next/LuaGui.html View documentation} - * - * @noSelf - */ -interface LuaGui { - /** - * Returns `true` if sprite_path is valid and contains loaded sprite, otherwise `false`. Sprite path of type `file` - * doesn't validate if file exists. - * - * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.is_valid_sprite_path View documentation} - * - * @param sprite_path - Path to a image. - */ - is_valid_sprite_path(sprite_path: SpritePath): boolean - /** - * The player who owns this gui. - * - * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.player View documentation} - */ - readonly player: LuaPlayer - /** - * The children GUI elements mapped by name <> element. - * - * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.children View documentation} - */ - readonly children: Record - /** - * The top part of the GUI. It is a flow element inside a scroll pane element. - * - * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.top View documentation} - */ - readonly top: LuaGuiElement - /** - * The left part of the GUI. It is a flow element inside a scroll pane element. - * - * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.left View documentation} - */ - readonly left: LuaGuiElement - /** - * The center part of the GUI. It is a flow element. - * - * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.center View documentation} - */ - readonly center: LuaGuiElement - /** - * The flow used in the objectives window. It is a flow element. The objectives window is only visible when the flow - * is not empty or the objective text is set. - * - * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.goal View documentation} - */ - readonly goal: LuaGuiElement - /** - * For showing a GUI somewhere on the entire screen. It is an empty-widget element. - * - * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.screen View documentation} - */ - readonly screen: LuaGuiElement - /** - * For showing a GUI somewhere relative to one of the game GUIs. It is an empty-widget element. - * - * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.relative View documentation} - */ - readonly relative: LuaGuiElement - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaGui" - /** All methods and properties that this object supports. */ - help(): string -} - -type GuiElementType = - | "choose-elem-button" - | "drop-down" - | "empty-widget" - | "entity-preview" - | "list-box" - | "scroll-pane" - | "sprite-button" - | "tabbed-pane" - | "text-box" - | "button" - | "camera" - | "checkbox" - | "flow" - | "frame" - | "label" - | "line" - | "minimap" - | "progressbar" - | "radiobutton" - | "slider" - | "sprite" - | "switch" - | "tab" - | "table" - | "textfield" - -interface BaseGuiSpec { - /** The kind of element to add. Has to be one of the GUI element types listed at the top of this page. */ - readonly type: GuiElementType - /** Name of the child element. */ - readonly name?: string - /** - * Text displayed on the child element. For frames, this is their title. For other elements, like buttons or labels, - * this is the content. Whilst this attribute may be used on all elements, it doesn't make sense for tables and - * flows as they won't display it. - */ - readonly caption?: LocalisedString - /** Tooltip of the child element. */ - readonly tooltip?: LocalisedString - /** Whether the child element is enabled. Defaults to `true`. */ - readonly enabled?: boolean - /** Whether the child element is visible. Defaults to `true`. */ - readonly visible?: boolean - /** Whether the child element is ignored by interaction. Defaults to `false`. */ - readonly ignored_by_interaction?: boolean - /** Style of the child element. */ - readonly style?: string - /** {@link Tags} associated with the child element. */ - readonly tags?: Tags - /** Location in its parent that the child element should slot into. By default, the child will be appended onto the end. */ - readonly index?: uint - /** Where to position the child element when in the `relative` element. */ - readonly anchor?: GuiAnchor -} - -interface ButtonGuiSpec extends BaseGuiSpec { - readonly type: "button" - /** Which mouse buttons the button responds to. Defaults to `"left-and-right"`. */ - readonly mouse_button_filter?: MouseButtonFlags -} - -interface FlowGuiSpec extends BaseGuiSpec { - readonly type: "flow" - /** - * The initial direction of the flow's layout. See {@link LuaGuiElement.direction LuaGuiElement::direction}. Defaults - * to `"horizontal"`. - */ - readonly direction?: "horizontal" | "vertical" -} - -interface FrameGuiSpec extends BaseGuiSpec { - readonly type: "frame" - /** - * The initial direction of the frame's layout. See {@link LuaGuiElement.direction LuaGuiElement::direction}. - * Defaults to `"horizontal"`. - */ - readonly direction?: "horizontal" | "vertical" -} - -interface TableGuiSpec extends BaseGuiSpec { - readonly type: "table" - /** Number of columns. This can't be changed after the table is created. */ - readonly column_count: uint - /** Whether the table should draw vertical grid lines. Defaults to `false`. */ - readonly draw_vertical_lines?: boolean - /** Whether the table should draw horizontal grid lines. Defaults to `false`. */ - readonly draw_horizontal_lines?: boolean - /** Whether the table should draw a single horizontal grid line after the headers. Defaults to `false`. */ - readonly draw_horizontal_line_after_headers?: boolean - /** Whether the content of the table should be vertically centered. Defaults to `true`. */ - readonly vertical_centering?: boolean -} - -interface TextfieldGuiSpec extends BaseGuiSpec { - readonly type: "textfield" - /** The initial text contained in the textfield. */ - readonly text?: string - /** Defaults to `false`. */ - readonly numeric?: boolean - /** Defaults to `false`. */ - readonly allow_decimal?: boolean - /** Defaults to `false`. */ - readonly allow_negative?: boolean - /** Defaults to `false`. */ - readonly is_password?: boolean - /** Defaults to `false`. */ - readonly lose_focus_on_confirm?: boolean - /** Defaults to `false`. */ - readonly clear_and_focus_on_right_click?: boolean -} - -interface ProgressbarGuiSpec extends BaseGuiSpec { - readonly type: "progressbar" - /** The initial value of the progressbar, in the range [0, 1]. Defaults to `0`. */ - readonly value?: double -} - -interface CheckboxGuiSpec extends BaseGuiSpec { - readonly type: "checkbox" - /** The initial checked-state of the checkbox. */ - readonly state: boolean -} - -interface RadiobuttonGuiSpec extends BaseGuiSpec { - readonly type: "radiobutton" - /** The initial checked-state of the radiobutton. */ - readonly state: boolean -} - -interface SpriteButtonGuiSpec extends BaseGuiSpec { - readonly type: "sprite-button" - /** Path to the image to display on the button. */ - readonly sprite?: SpritePath - /** Path to the image to display on the button when it is hovered. */ - readonly hovered_sprite?: SpritePath - /** Path to the image to display on the button when it is clicked. */ - readonly clicked_sprite?: SpritePath - /** The number shown on the button. */ - readonly number?: double - /** Formats small numbers as percentages. Defaults to `false`. */ - readonly show_percent_for_small_numbers?: boolean - /** The mouse buttons that the button responds to. Defaults to `"left-and-right"`. */ - readonly mouse_button_filter?: MouseButtonFlags -} - -interface SpriteGuiSpec extends BaseGuiSpec { - readonly type: "sprite" - /** Path to the image to display. */ - readonly sprite?: SpritePath - /** Whether the widget should resize according to the sprite in it. Defaults to `true`. */ - readonly resize_to_sprite?: boolean -} - -interface ScrollPaneGuiSpec extends BaseGuiSpec { - readonly type: "scroll-pane" - /** - * Policy of the horizontal scroll bar. Possible values are `"auto"`, `"never"`, `"always"`, - * `"auto-and-reserve-space"`, `"dont-show-but-allow-scrolling"`. Defaults to `"auto"`. - */ - readonly horizontal_scroll_policy?: - | "auto" - | "never" - | "always" - | "auto-and-reserve-space" - | "dont-show-but-allow-scrolling" - /** - * Policy of the vertical scroll bar. Possible values are `"auto"`, `"never"`, `"always"`, - * `"auto-and-reserve-space"`, `"dont-show-but-allow-scrolling"`. Defaults to `"auto"`. - */ - readonly vertical_scroll_policy?: - | "auto" - | "never" - | "always" - | "auto-and-reserve-space" - | "dont-show-but-allow-scrolling" -} - -interface DropDownGuiSpec extends BaseGuiSpec { - readonly type: "drop-down" - /** The initial items in the dropdown. */ - readonly items?: LocalisedString[] - /** The index of the initially selected item. Defaults to 0. */ - readonly selected_index?: uint -} - -interface LineGuiSpec extends BaseGuiSpec { - readonly type: "line" - /** The initial direction of the line. Defaults to `"horizontal"`. */ - readonly direction?: "horizontal" | "vertical" -} - -interface ListBoxGuiSpec extends BaseGuiSpec { - readonly type: "list-box" - /** The initial items in the listbox. */ - readonly items?: LocalisedString[] - /** The index of the initially selected item. Defaults to 0. */ - readonly selected_index?: uint -} - -interface CameraGuiSpec extends BaseGuiSpec { - readonly type: "camera" - /** The position the camera centers on. */ - readonly position: Position - /** The surface that the camera will render. Defaults to the player's current surface. */ - readonly surface_index?: uint - /** The initial camera zoom. Defaults to `0.75`. */ - readonly zoom?: double -} - -type ChooseElemButtonType = - | "item" - | "tile" - | "entity" - | "signal" - | "fluid" - | "recipe" - | "decorative" - | "item-group" - | "achievement" - | "equipment" - | "technology" - -interface ChooseElemButtonFilters { - item: ItemPrototypeFilter[] - tile: TilePrototypeFilter[] - entity: EntityPrototypeFilter[] - signal: never - fluid: FluidPrototypeFilter[] - recipe: RecipePrototypeFilter[] - decorative: DecorativePrototypeFilter[] - "item-group": never - achievement: AchievementPrototypeFilter[] - equipment: EquipmentPrototypeFilter[] - technology: TechnologyPrototypeFilter[] -} - -interface BaseChooseElemButtonSpec extends BaseGuiSpec { - readonly type: "choose-elem-button" - /** The type of the button - one of the following values. */ - readonly elem_type: ChooseElemButtonType - /** Filters describing what to show in the selection window. See {@link LuaGuiElement.elem_filters LuaGuiElement::elem_filters}. */ - readonly filters?: ChooseElemButtonFilters[this["elem_type"]] -} - -interface ItemChooseElemButtonSpec extends BaseChooseElemButtonSpec { - readonly elem_type: "item" - /** If type is `"item"` - the default value for the button. */ - readonly item?: string -} - -interface TileChooseElemButtonSpec extends BaseChooseElemButtonSpec { - readonly elem_type: "tile" - /** If type is `"tile"` - the default value for the button. */ - readonly tile?: string -} - -interface EntityChooseElemButtonSpec extends BaseChooseElemButtonSpec { - readonly elem_type: "entity" - /** If type is `"entity"` - the default value for the button. */ - readonly entity?: string -} - -interface SignalChooseElemButtonSpec extends BaseChooseElemButtonSpec { - readonly elem_type: "signal" - /** If type is `"signal"` - the default value for the button. */ - readonly signal?: SignalID -} - -interface FluidChooseElemButtonSpec extends BaseChooseElemButtonSpec { - readonly elem_type: "fluid" - /** If type is `"fluid"` - the default value for the button. */ - readonly fluid?: string -} - -interface RecipeChooseElemButtonSpec extends BaseChooseElemButtonSpec { - readonly elem_type: "recipe" - /** If type is `"recipe"` - the default value for the button. */ - readonly recipe?: string -} - -interface DecorativeChooseElemButtonSpec extends BaseChooseElemButtonSpec { - readonly elem_type: "decorative" - /** If type is `"decorative"` - the default value for the button. */ - readonly decorative?: string -} - -interface ItemGroupChooseElemButtonSpec extends BaseChooseElemButtonSpec { - readonly elem_type: "item-group" - /** If type is `"item-group"` - the default value for the button. */ - readonly "item-group"?: string -} - -interface AchievementChooseElemButtonSpec extends BaseChooseElemButtonSpec { - readonly elem_type: "achievement" - /** If type is `"achievement"` - the default value for the button. */ - readonly achievement?: string -} - -interface EquipmentChooseElemButtonSpec extends BaseChooseElemButtonSpec { - readonly elem_type: "equipment" - /** If type is `"equipment"` - the default value for the button. */ - readonly equipment?: string -} - -interface TechnologyChooseElemButtonSpec extends BaseChooseElemButtonSpec { - readonly elem_type: "technology" - /** If type is `"technology"` - the default value for the button. */ - readonly technology?: string -} - -type ChooseElemButtonGuiSpec = - | ItemChooseElemButtonSpec - | TileChooseElemButtonSpec - | EntityChooseElemButtonSpec - | SignalChooseElemButtonSpec - | FluidChooseElemButtonSpec - | RecipeChooseElemButtonSpec - | DecorativeChooseElemButtonSpec - | ItemGroupChooseElemButtonSpec - | AchievementChooseElemButtonSpec - | EquipmentChooseElemButtonSpec - | TechnologyChooseElemButtonSpec - -interface TextBoxGuiSpec extends BaseGuiSpec { - readonly type: "text-box" - /** The initial text contained in the text-box. */ - readonly text?: string - /** Defaults to `false`. */ - readonly clear_and_focus_on_right_click?: boolean -} - -interface SliderGuiSpec extends BaseGuiSpec { - readonly type: "slider" - /** The minimum value for the slider. Defaults to `0`. */ - readonly minimum_value?: double - /** The maximum value for the slider. Defaults to `30`. */ - readonly maximum_value?: double - /** The initial value for the slider. Defaults to `minimum_value`. */ - readonly value?: double - /** The minimum value the slider can move. Defaults to `1`. */ - readonly value_step?: double - /** Defaults to `false`. */ - readonly discrete_slider?: boolean - /** Defaults to `true`. */ - readonly discrete_values?: boolean -} - -interface MinimapGuiSpec extends BaseGuiSpec { - readonly type: "minimap" - /** The position the minimap centers on. Defaults to the player's current position. */ - readonly position?: Position - /** The surface the camera will render. Defaults to the player's current surface. */ - readonly surface_index?: uint - /** The player index the map should use. Defaults to the current player. */ - readonly chart_player_index?: uint - /** The force this minimap should use. Defaults to the player's current force. */ - readonly force?: string - /** The initial camera zoom. Defaults to `0.75`. */ - readonly zoom?: double -} - -interface TabGuiSpec extends BaseGuiSpec { - readonly type: "tab" - /** The text to display after the normal tab text (designed to work with numbers). */ - readonly badge_text?: LocalisedString -} - -interface SwitchGuiSpec extends BaseGuiSpec { - readonly type: "switch" - /** - * Possible values are `"left"`, `"right"`, or `"none"`. If set to "none", `allow_none_state` must be `true`. - * Defaults to `"left"`. - */ - readonly switch_state?: "left" | "right" | "none" - /** Whether the switch can be set to a middle state. Defaults to `false`. */ - readonly allow_none_state?: boolean - readonly left_label_caption?: LocalisedString - readonly left_label_tooltip?: LocalisedString - readonly right_label_caption?: LocalisedString - readonly right_label_tooltip?: LocalisedString -} - -interface OtherGuiSpec extends BaseGuiSpec { - readonly type: "empty-widget" | "entity-preview" | "tabbed-pane" | "label" -} - -type GuiSpec = - | ButtonGuiSpec - | FlowGuiSpec - | FrameGuiSpec - | TableGuiSpec - | TextfieldGuiSpec - | ProgressbarGuiSpec - | CheckboxGuiSpec - | RadiobuttonGuiSpec - | SpriteButtonGuiSpec - | SpriteGuiSpec - | ScrollPaneGuiSpec - | DropDownGuiSpec - | LineGuiSpec - | ListBoxGuiSpec - | CameraGuiSpec - | ChooseElemButtonGuiSpec - | TextBoxGuiSpec - | SliderGuiSpec - | MinimapGuiSpec - | TabGuiSpec - | SwitchGuiSpec - | OtherGuiSpec - -interface GuiElementIndex { - /** - * The indexing operator. Gets children by name. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.operator%20[] View documentation} - */ - readonly [name: string]: LuaGuiElement | undefined -} - -/** @noSelf */ -interface BaseGuiElement { - /** - * Add a new child element to this GuiElement. - * - * Other attributes may be specified depending on `type`: - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.add View documentation} - * - * @returns The added GUI element. - */ - add( - element: GuiSpec & { - type: Type - } - ): Extract< - LuaGuiElement, - { - type: Type - } - > - /** - * Remove children of this element. Any {@link LuaGuiElement} objects referring to the destroyed elements become - * invalid after this operation. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.clear View documentation} - * - * @example - * ```lua - * game.player.gui.top.clear() - * ``` - */ - clear(): void - /** - * Remove this element, along with its children. Any {@link LuaGuiElement} objects referring to the destroyed - * elements become invalid after this operation. - * - * **Note**: The top-level GUI elements - {@link LuaGui.top LuaGui::top}, {@link LuaGui.left LuaGui::left}, - * {@link LuaGui.center LuaGui::center} and {@link LuaGui.screen LuaGui::screen} - can't be destroyed. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.destroy View documentation} - * - * @example - * ```lua - * game.player.gui.top.greeting.destroy() - * ``` - */ - destroy(): void - /** - * The mod that owns this Gui element or `nil` if it's owned by the scenario script. - * - * **Note**: This has a not-super-expensive, but non-free cost to get. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.get_mod View documentation} - */ - get_mod(): string | undefined - /** - * Gets the index that this element has in its parent element. - * - * **Note**: This iterates through the children of the parent of this element, meaning this has a non-free cost to - * get, but is faster than doing the equivalent in Lua. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.get_index_in_parent View documentation} - */ - get_index_in_parent(): uint - /** - * Removes the items in this dropdown or listbox. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.clear_items View documentation} - */ - clear_items(): void - /** - * Gets the item at the given index from this dropdown or listbox. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.get_item View documentation} - * - * @param index - The index to get - */ - get_item(index: uint): LocalisedString - /** - * Sets the given string at the given index in this dropdown or listbox. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.set_item View documentation} - * - * @param index - The index whose text to replace. - * @param string - The text to set at the given index. - */ - set_item(index: uint, string: LocalisedString): void - /** - * Inserts a string at the end or at the given index of this dropdown or listbox. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.add_item View documentation} - * - * @param string - The text to insert. - * @param index - The index at which to insert the item. - */ - add_item(string: LocalisedString, index?: uint): void - /** - * Removes the item at the given index from this dropdown or listbox. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.remove_item View documentation} - * - * @param index - The index - */ - remove_item(index: uint): void - /** - * Gets this sliders minimum value. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.get_slider_minimum View documentation} - */ - get_slider_minimum(): double - /** - * Gets this sliders maximum value. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.get_slider_maximum View documentation} - */ - get_slider_maximum(): double - /** - * Sets this sliders minimum and maximum values. - * - * **Note**: The minimum can't be >= the maximum. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.set_slider_minimum_maximum View documentation} - * - * @param minimum - * @param maximum - */ - set_slider_minimum_maximum(minimum: double, maximum: double): void - /** - * Gets the minimum distance this slider can move. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.get_slider_value_step View documentation} - */ - get_slider_value_step(): double - /** - * Returns whether this slider only allows being moved to discrete positions. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.get_slider_discrete_slider View documentation} - */ - get_slider_discrete_slider(): boolean - /** - * Returns whether this slider only allows discrete values. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.get_slider_discrete_values View documentation} - */ - get_slider_discrete_values(): boolean - /** - * Sets the minimum distance this slider can move. - * - * **Note**: The minimum distance can't be > (max - min). - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.set_slider_value_step View documentation} - * - * @param value - */ - set_slider_value_step(value: double): void - /** - * Sets whether this slider only allows being moved to discrete positions. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.set_slider_discrete_slider View documentation} - * - * @param value - */ - set_slider_discrete_slider(value: boolean): void - /** - * Sets whether this slider only allows discrete values. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.set_slider_discrete_values View documentation} - * - * @param value - */ - set_slider_discrete_values(value: boolean): void - /** - * Focuses this GUI element if possible. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.focus View documentation} - */ - focus(): void - /** - * Moves this GUI element to the "front" so it will draw over other elements. - * - * **Note**: Only works for elements in {@link LuaGui.screen LuaGui::screen} - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.bring_to_front View documentation} - */ - bring_to_front(): void - /** - * The index of this GUI element (unique amongst the GUI elements of a LuaPlayer). - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.index View documentation} - */ - readonly index: uint - /** - * The GUI this element is a child of. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.gui View documentation} - */ - readonly gui: LuaGui - /** - * The direct parent of this element; `nil` if this is a top-level element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.parent View documentation} - */ - readonly parent: LuaGuiElement | undefined - /** - * The name of this element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.name View documentation} - * - * @example - * ```lua - * game.player.gui.top.greeting.name == "greeting" - * ``` - */ - name: string - /** - * The text displayed on this element. For frames, this is the "heading". For other elements, like buttons or - * labels, this is the content. - * - * **Note**: Whilst this attribute may be used on all elements without producing an error, it doesn't make sense for - * tables and flows as they won't display it. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.caption View documentation} - */ - caption: LocalisedString - /** - * The style of this element. When read, this evaluates to a {@link LuaStyle}. For writing, it only accepts a string - * that specifies the textual identifier (prototype name) of the desired style. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.style View documentation} - */ - style: LuaStyle | string - /** - * Sets whether this GUI element is visible or completely hidden, taking no space in the layout. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.visible View documentation} - */ - visible: boolean - /** - * Names of all the children of this element. These are the identifiers that can be used to access the child as an - * attribute of this element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.children_names View documentation} - */ - readonly children_names: string[] - /** - * Index into {@link LuaGameScript.players LuaGameScript::players} specifying the player who owns this element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.player_index View documentation} - */ - readonly player_index: uint - /** - * The image to display on this sprite-button or sprite in the default state. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.sprite View documentation} - */ - sprite: SpritePath - /** - * Whether the image widget should resize according to the sprite in it. Defaults to `true`. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.resize_to_sprite View documentation} - */ - resize_to_sprite: boolean - /** - * The image to display on this sprite-button when it is clicked. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.clicked_sprite View documentation} - */ - clicked_sprite: SpritePath - tooltip: LocalisedString - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: GuiElementType - /** - * The child-elements of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.children View documentation} - */ - readonly children: LuaGuiElement[] - /** - * The items in this dropdown or listbox. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.items View documentation} - */ - items: LocalisedString[] - /** - * The selected index for this dropdown or listbox. Returns `0` if none is selected. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.selected_index View documentation} - */ - selected_index: uint - /** - * The number to be shown in the bottom right corner of this sprite-button. Set this to `nil` to show nothing. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.number View documentation} - */ - number: double | undefined - /** - * Related to the number to be shown in the bottom right corner of this sprite-button. When set to `true`, numbers - * that are non-zero and smaller than one are shown as a percentage rather than the value. For example, `0.5` will - * be shown as `50%` instead. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.show_percent_for_small_numbers View documentation} - */ - show_percent_for_small_numbers: boolean - /** - * The location of this widget when stored in {@link LuaGui.screen LuaGui::screen} or `nil` if not not set or not in - * {@link LuaGui.screen LuaGui::screen}. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.location View documentation} - */ - location: GuiLocation | undefined - /** - * The position this camera or minimap is focused on, if any. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.position View documentation} - */ - position: Position - /** - * The surface index this camera or minimap is using. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.surface_index View documentation} - */ - surface_index: uint - /** - * The zoom this camera or minimap is using. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.zoom View documentation} - */ - zoom: double - /** - * The force this minimap is using or `nil` if no force is set. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.force View documentation} - */ - force: string | undefined - /** - * Whether this GUI element is enabled. Disabled GUI elements don't trigger events when clicked. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.enabled View documentation} - */ - enabled: boolean - /** - * Whether this GUI element is ignored by interaction. This makes clicks on this element 'go through' to the GUI - * element or even the game surface below it. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.ignored_by_interaction View documentation} - */ - ignored_by_interaction: boolean - /** - * The mouse button filters for this button or sprite-button. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.mouse_button_filter View documentation} - */ - mouse_button_filter: MouseButtonFlags - /** - * The frame drag target for this flow, frame, label, table, or empty-widget. - * - * **Note**: drag_target can only be set to a frame stored directly in {@link LuaGui.screen LuaGui::screen} or `nil`. - * - * **Note**: drag_target can only be set on child elements in {@link LuaGui.screen LuaGui::screen}. - * - * **Note**: drag_target can only be set to a higher level parent element (this element must be owned at some nested - * level by the drag_target). - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.drag_target View documentation} - */ - drag_target: LuaGuiElement | undefined - /** - * The tabs and contents being shown in this tabbed-pane. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.tabs View documentation} - */ - readonly tabs: TabAndContent[] - /** - * The entity associated with this entity-preview, camera, minimap or `nil` if no entity is associated. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.entity View documentation} - */ - entity: LuaEntity | undefined - /** - * Sets the anchor for this relative widget. Setting `nil` clears the anchor. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.anchor View documentation} - */ - anchor: GuiAnchor | undefined - /** - * The tags associated with this LuaGuiElement. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.tags View documentation} - */ - tags: Tags - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaGuiElement" - /** All methods and properties that this object supports. */ - help(): string -} - -/** @noSelf */ -interface ChooseElemButtonGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "choose-elem-button" - /** - * The elem type of this choose-elem-button. - * - * *Can only be used if this is choose-elem-button* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.elem_type View documentation} - */ - readonly elem_type: ChooseElemButtonType - /** - * The elem value of this choose-elem-button or `nil` if there is no value. - * - * **Note**: The `"signal"` type operates with {@link SignalID}, while all other types use strings. - * - * *Can only be used if this is choose-elem-button* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.elem_value View documentation} - */ - elem_value: (this["elem_type"] extends "signal" ? SignalID : string) | undefined - /** - * The elem filters of this choose-elem-button or `nil` if there are no filters. - * - * The compatible type of filter is determined by elem_type: - * - * - Type `"item"` - {@link ItemPrototypeFilter} - * - Type `"tile"` - {@link TilePrototypeFilter} - * - Type `"entity"` - {@link EntityPrototypeFilter} - * - Type `"signal"` - Does not support filters - * - Type `"fluid"` - {@link FluidPrototypeFilter} - * - Type `"recipe"` - {@link RecipePrototypeFilter} - * - Type `"decorative"` - {@link DecorativePrototypeFilter} - * - Type `"item-group"` - Does not support filters - * - Type `"achievement"` - {@link AchievementPrototypeFilter} - * - Type `"equipment"` - {@link EquipmentPrototypeFilter} - * - Type `"technology"` - {@link TechnologyPrototypeFilter} - * - * **Note**: Writing to this field does not change or clear the currently selected element. - * - * *Can only be used if this is choose-elem-button* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.elem_filters View documentation} - * - * @example - * This will configure a choose-elem-button of type `"entity"` to only show items of type `"furnace"`. - * - * ```lua - * button.elem_filters = {{filter = "type", type = "furnace"}} - * ``` - * - * @example - * Then, there are some types of filters that work on a specific kind of attribute. The following will configure a choose-elem-button of type `"entity"` to only show entities that have their `"hidden"` {@link EntityPrototypeFlags flags} set. - * - * ```lua - * button.elem_filters = {{filter = "hidden"}} - * ``` - * - * @example - * Lastly, these filters can be combined at will, taking care to specify how they should be combined (either `"and"` or `"or"`. The following will filter for any `"entities"` that are `"furnaces"` and that are not `"hidden"`. - * - * ```lua - * button.elem_filters = {{filter = "type", type = "furnace"}, {filter = "hidden", invert = true, mode = "and"}} - * ``` - */ - elem_filters: ChooseElemButtonFilters[this["elem_type"]] | undefined - /** - * Whether this choose-elem-button can be changed by the player. - * - * *Can only be used if this is choose-elem-button* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.locked View documentation} - */ - locked: boolean -} - -type ChooseElemButtonGuiElement = ChooseElemButtonGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface DropDownGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "drop-down" -} - -type DropDownGuiElement = DropDownGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface EmptyWidgetGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "empty-widget" -} - -type EmptyWidgetGuiElement = EmptyWidgetGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface EntityPreviewGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "entity-preview" -} - -type EntityPreviewGuiElement = EntityPreviewGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface ListBoxGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "list-box" - /** - * Scrolls the scroll bar such that the specified listbox item is visible to the player. - * - * *Can only be used if this is list-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_item View documentation} - * - * @param index - The item index to scroll to. - * @param scroll_mode - Where the item should be positioned in the scroll-pane. Must be either `"in-view"` or - * `"top-third"`. Defaults to `"in-view"`. - */ - scroll_to_item(index: int, scroll_mode?: "in-view" | "top-third"): void -} - -type ListBoxGuiElement = ListBoxGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface ScrollPaneGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "scroll-pane" - /** - * Scrolls this scroll bar to the top. - * - * *Can only be used if this is scroll-pane or text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_top View documentation} - */ - scroll_to_top(): void - /** - * Scrolls this scroll bar to the bottom. - * - * *Can only be used if this is scroll-pane or text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_bottom View documentation} - */ - scroll_to_bottom(): void - /** - * Scrolls this scroll bar to the left. - * - * *Can only be used if this is scroll-pane or text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_left View documentation} - */ - scroll_to_left(): void - /** - * Scrolls this scroll bar to the right. - * - * *Can only be used if this is scroll-pane or text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_right View documentation} - */ - scroll_to_right(): void - /** - * Scrolls this scroll bar such that the specified GUI element is visible to the player. - * - * *Can only be used if this is scroll-pane* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_element View documentation} - * - * @param element - The element to scroll to. - * @param scroll_mode - Where the element should be positioned in the scroll-pane. Must be either `"in-view"` or - * `"top-third"`. Defaults to `"in-view"`. - */ - scroll_to_element(element: LuaGuiElement, scroll_mode?: "in-view" | "top-third"): void - /** - * Policy of the horizontal scroll bar. Possible values are `"auto"`, `"never"`, `"always"`, - * `"auto-and-reserve-space"`, `"dont-show-but-allow-scrolling"`. - * - * *Can only be used if this is scroll-pane* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.horizontal_scroll_policy View documentation} - */ - horizontal_scroll_policy: "auto" | "never" | "always" | "auto-and-reserve-space" | "dont-show-but-allow-scrolling" - /** - * Policy of the vertical scroll bar. Possible values are `"auto"`, `"never"`, `"always"`, - * `"auto-and-reserve-space"`, `"dont-show-but-allow-scrolling"`. - * - * *Can only be used if this is scroll-pane* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.vertical_scroll_policy View documentation} - */ - vertical_scroll_policy: "auto" | "never" | "always" | "auto-and-reserve-space" | "dont-show-but-allow-scrolling" -} - -type ScrollPaneGuiElement = ScrollPaneGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface SpriteButtonGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "sprite-button" - /** - * The image to display on this sprite-button when it is hovered. - * - * *Can only be used if this is sprite-button* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.hovered_sprite View documentation} - */ - hovered_sprite: SpritePath -} - -type SpriteButtonGuiElement = SpriteButtonGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface TabbedPaneGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "tabbed-pane" - /** - * Adds the given tab and content widgets to this tabbed pane as a new tab. - * - * *Can only be used if this is tabbed-pane* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.add_tab View documentation} - * - * @param tab - The tab to add, must be a GUI element of type "tab". - * @param content - The content to show when this tab is selected. Can be any type of GUI element. - */ - add_tab(tab: LuaGuiElement, content: LuaGuiElement): void - /** - * Removes the given tab and its associated content from this tabbed pane. - * - * **Note**: Removing a tab does not destroy the tab or the tab contents. It just removes them from the view. - * - * **Note**: When removing tabs, {@link LuaGuiElement.selected_tab_index LuaGuiElement::selected_tab_index} needs to - * be manually updated. - * - * *Can only be used if this is tabbed-pane* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.remove_tab View documentation} - * - * @param tab - The tab to remove. If not given, it removes all tabs. - */ - remove_tab(tab: LuaGuiElement): void - /** - * The selected tab index for this tabbed pane or `nil` if no tab is selected. - * - * *Can only be used if this is tabbed-pane* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.selected_tab_index View documentation} - */ - selected_tab_index: uint | undefined -} - -type TabbedPaneGuiElement = TabbedPaneGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface TextBoxGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "text-box" - /** - * Scrolls this scroll bar to the top. - * - * *Can only be used if this is scroll-pane or text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_top View documentation} - */ - scroll_to_top(): void - /** - * Scrolls this scroll bar to the bottom. - * - * *Can only be used if this is scroll-pane or text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_bottom View documentation} - */ - scroll_to_bottom(): void - /** - * Scrolls this scroll bar to the left. - * - * *Can only be used if this is scroll-pane or text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_left View documentation} - */ - scroll_to_left(): void - /** - * Scrolls this scroll bar to the right. - * - * *Can only be used if this is scroll-pane or text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_right View documentation} - */ - scroll_to_right(): void - /** - * Selects all the text in this textbox. - * - * *Can only be used if this is textfield or text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.select_all View documentation} - */ - select_all(): void - /** - * Selects a range of text in this textbox. - * - * *Can only be used if this is textfield or text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.select View documentation} - * - * @example - * Select the characters `amp` from `example`: - * - * ```lua - * textbox.select(3, 5) - * ``` - * - * @example - * Move the cursor to the start of the text box: - * - * ```lua - * textbox.select(1, 0) - * ``` - * - * @param start - The index of the first character to select - * @param end - The index of the last character to select - */ - select(start: int, end: int): void - /** - * The text contained in this textfield or text-box. - * - * *Can only be used if this is textfield or text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.text View documentation} - */ - text: string - /** - * Whether the contents of this text-box are selectable. Defaults to `true`. - * - * *Can only be used if this is text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.selectable View documentation} - */ - selectable: boolean - /** - * Whether this text-box will word-wrap automatically. Defaults to `false`. - * - * *Can only be used if this is text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.word_wrap View documentation} - */ - word_wrap: boolean - /** - * Whether this text-box is read-only. Defaults to `false`. - * - * *Can only be used if this is text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.read_only View documentation} - */ - read_only: boolean - /** - * Makes it so right-clicking on this textfield clears and focuses it. - * - * *Can only be used if this is textfield or text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.clear_and_focus_on_right_click View documentation} - */ - clear_and_focus_on_right_click: boolean -} - -type TextBoxGuiElement = TextBoxGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface ButtonGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "button" -} - -type ButtonGuiElement = ButtonGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface CameraGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "camera" -} - -type CameraGuiElement = CameraGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface CheckboxGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "checkbox" - /** - * Is this checkbox or radiobutton checked? - * - * *Can only be used if this is CheckBox or RadioButton* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.state View documentation} - */ - state: boolean -} - -type CheckboxGuiElement = CheckboxGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface FlowGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "flow" - /** - * Direction of this element's layout. May be either `"horizontal"` or `"vertical"`. - * - * *Can only be used if this is frame, flow or line* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.direction View documentation} - */ - readonly direction: "horizontal" | "vertical" -} - -type FlowGuiElement = FlowGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface FrameGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "frame" - /** - * Forces this frame to re-auto-center. Only works on frames stored directly in {@link LuaGui.screen LuaGui::screen}. - * - * *Can only be used if this is frame* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.force_auto_center View documentation} - */ - force_auto_center(): void - /** - * Direction of this element's layout. May be either `"horizontal"` or `"vertical"`. - * - * *Can only be used if this is frame, flow or line* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.direction View documentation} - */ - readonly direction: "horizontal" | "vertical" - /** - * Whether this frame auto-centers on window resize when stored in {@link LuaGui.screen LuaGui::screen}. - * - * *Can only be used if this is frame* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.auto_center View documentation} - */ - auto_center: boolean -} - -type FrameGuiElement = FrameGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface LabelGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "label" -} - -type LabelGuiElement = LabelGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface LineGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "line" - /** - * Direction of this element's layout. May be either `"horizontal"` or `"vertical"`. - * - * *Can only be used if this is frame, flow or line* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.direction View documentation} - */ - readonly direction: "horizontal" | "vertical" -} - -type LineGuiElement = LineGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface MinimapGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "minimap" - /** - * The player index this minimap is using. - * - * *Can only be used if this is minimap* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.minimap_player_index View documentation} - */ - minimap_player_index: uint -} - -type MinimapGuiElement = MinimapGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface ProgressbarGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "progressbar" - /** - * How much this progress bar is filled. It is a value in the range [0, 1]. - * - * *Can only be used if this is progressbar* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.value View documentation} - */ - value: double -} - -type ProgressbarGuiElement = ProgressbarGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface RadiobuttonGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "radiobutton" - /** - * Is this checkbox or radiobutton checked? - * - * *Can only be used if this is CheckBox or RadioButton* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.state View documentation} - */ - state: boolean -} - -type RadiobuttonGuiElement = RadiobuttonGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface SliderGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "slider" - /** - * The value of this slider element. - * - * *Can only be used if this is slider* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.slider_value View documentation} - */ - slider_value: double -} - -type SliderGuiElement = SliderGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface SpriteGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "sprite" -} - -type SpriteGuiElement = SpriteGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface SwitchGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "switch" - /** - * The switch state (left, none, right) for this switch. - * - * **Note**: If {@link LuaGuiElement.allow_none_state LuaGuiElement::allow_none_state} is false this can't be set to `"none"`. - * - * *Can only be used if this is switch* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.switch_state View documentation} - */ - switch_state: string - /** - * Whether the `"none"` state is allowed for this switch. - * - * **Note**: This can't be set to false if the current switch_state is 'none'. - * - * *Can only be used if this is switch* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.allow_none_state View documentation} - */ - allow_none_state: boolean - /** - * The text shown for the left switch label. - * - * *Can only be used if this is switch* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.left_label_caption View documentation} - */ - left_label_caption: LocalisedString - /** - * The tooltip shown on the left switch label. - * - * *Can only be used if this is switch* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.left_label_tooltip View documentation} - */ - left_label_tooltip: LocalisedString - /** - * The text shown for the right switch label. - * - * *Can only be used if this is switch* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.right_label_caption View documentation} - */ - right_label_caption: LocalisedString - /** - * The tooltip shown on the right switch label. - * - * *Can only be used if this is switch* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.right_label_tooltip View documentation} - */ - right_label_tooltip: LocalisedString -} - -type SwitchGuiElement = SwitchGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface TabGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "tab" - /** - * The text to display after the normal tab text (designed to work with numbers) - * - * *Can only be used if this is tab* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.badge_text View documentation} - */ - badge_text: LocalisedString -} - -type TabGuiElement = TabGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface TableGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "table" - /** - * Whether this table should draw vertical grid lines. - * - * *Can only be used if this is table* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.draw_vertical_lines View documentation} - */ - draw_vertical_lines: boolean - /** - * Whether this table should draw horizontal grid lines. - * - * *Can only be used if this is table* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.draw_horizontal_lines View documentation} - */ - draw_horizontal_lines: boolean - /** - * Whether this table should draw a horizontal grid line below the first table row. - * - * *Can only be used if this is table* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.draw_horizontal_line_after_headers View documentation} - */ - draw_horizontal_line_after_headers: boolean - /** - * The number of columns in this table. - * - * *Can only be used if this is table* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.column_count View documentation} - */ - readonly column_count: uint - /** - * Whether the content of this table should be vertically centered. Overrides - * {@link LuaStyle.column_alignments LuaStyle::column_alignments}. Defaults to `true`. - * - * *Can only be used if this is table* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.vertical_centering View documentation} - */ - vertical_centering: boolean -} - -type TableGuiElement = TableGuiElementMembers & GuiElementIndex - -/** @noSelf */ -interface TextfieldGuiElementMembers extends BaseGuiElement { - /** - * The type of this GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} - */ - readonly type: "textfield" - /** - * Selects all the text in this textbox. - * - * *Can only be used if this is textfield or text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.select_all View documentation} - */ - select_all(): void - /** - * Selects a range of text in this textbox. - * - * *Can only be used if this is textfield or text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.select View documentation} - * - * @example - * Select the characters `amp` from `example`: - * - * ```lua - * textbox.select(3, 5) - * ``` - * - * @example - * Move the cursor to the start of the text box: - * - * ```lua - * textbox.select(1, 0) - * ``` - * - * @param start - The index of the first character to select - * @param end - The index of the last character to select - */ - select(start: int, end: int): void - /** - * The text contained in this textfield or text-box. - * - * *Can only be used if this is textfield or text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.text View documentation} - */ - text: string - /** - * Whether this textfield is limited to only numberic characters. - * - * *Can only be used if this is textfield* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.numeric View documentation} - */ - numeric: boolean - /** - * Whether this textfield (when in numeric mode) allows decimal numbers. - * - * *Can only be used if this is textfield* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.allow_decimal View documentation} - */ - allow_decimal: boolean - /** - * Whether this textfield (when in numeric mode) allows negative numbers. - * - * *Can only be used if this is textfield* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.allow_negative View documentation} - */ - allow_negative: boolean - /** - * Whether this textfield displays as a password field, which renders all characters as `*`. - * - * *Can only be used if this is textfield* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.is_password View documentation} - */ - is_password: boolean - /** - * Whether this textfield loses focus after {@link defines.events.on_gui_confirmed} is fired. - * - * *Can only be used if this is textfield* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.lose_focus_on_confirm View documentation} - */ - lose_focus_on_confirm: boolean - /** - * Makes it so right-clicking on this textfield clears and focuses it. - * - * *Can only be used if this is textfield or text-box* - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.clear_and_focus_on_right_click View documentation} - */ - clear_and_focus_on_right_click: boolean -} - -type TextfieldGuiElement = TextfieldGuiElementMembers & GuiElementIndex - -type GuiElementMembers = - | ChooseElemButtonGuiElementMembers - | DropDownGuiElementMembers - | EmptyWidgetGuiElementMembers - | EntityPreviewGuiElementMembers - | ListBoxGuiElementMembers - | ScrollPaneGuiElementMembers - | SpriteButtonGuiElementMembers - | TabbedPaneGuiElementMembers - | TextBoxGuiElementMembers - | ButtonGuiElementMembers - | CameraGuiElementMembers - | CheckboxGuiElementMembers - | FlowGuiElementMembers - | FrameGuiElementMembers - | LabelGuiElementMembers - | LineGuiElementMembers - | MinimapGuiElementMembers - | ProgressbarGuiElementMembers - | RadiobuttonGuiElementMembers - | SliderGuiElementMembers - | SpriteGuiElementMembers - | SwitchGuiElementMembers - | TabGuiElementMembers - | TableGuiElementMembers - | TextfieldGuiElementMembers - -/** - * An element of a custom GUI. This type is used to represent any kind of a GUI element - labels, buttons and frames are - * all instances of this type. Just like {@link LuaEntity}, different kinds of elements support different attributes; - * attempting to access an attribute on an element that doesn't support it (for instance, trying to access the - * `column_count` of a `textfield`) will result in a runtime error. - * - * The following types of GUI element are supported: - * - * - `"button"`: A clickable element. Relevant event: {@link OnGuiClickEvent on_gui_click} - * - `"sprite-button"`: A `button` that displays a sprite rather than text. Relevant event: {@link OnGuiClickEvent on_gui_click} - * - `"checkbox"`: A clickable element with a check mark that can be turned off or on. Relevant event: - * {@link OnGuiCheckedStateChangedEvent on_gui_checked_state_changed} - * - `"flow"`: An invisible container that lays out its children either horizontally or vertically. - * - `"frame"`: A non-transparent box that contains other elements. It can have a title (set via the `caption` attribute). - * Just like a `flow`, it lays out its children either horizontally or vertically. Relevant event: - * {@link OnGuiLocationChangedEvent on_gui_location_changed} - * - `"label"`: A piece of text. - * - `"line"`: A horizontal or vertical separation line. - * - `"progressbar"`: A partially filled bar that can be used to indicate progress. - * - `"table"`: An invisible container that lays out its children in a specific number of columns. The width of each - * column is determined by the widest element it contains. - * - `"textfield"`: A single-line box the user can type into. Relevant events: - * {@link OnGuiTextChangedEvent on_gui_text_changed}, {@link OnGuiConfirmedEvent on_gui_confirmed} - * - `"radiobutton"`: A clickable element that is functionally identical to a `checkbox`, but has a circular appearance. - * Relevant event: {@link OnGuiCheckedStateChangedEvent on_gui_checked_state_changed} - * - `"sprite"`: An element that shows an image. - * - `"scroll-pane"`: An invisible element that is similar to a `flow`, but has the ability to show and use scroll bars. - * - `"drop-down"`: A drop-down containing strings of text. Relevant event: - * {@link OnGuiSelectionStateChangedEvent on_gui_selection_state_changed} - * - `"list-box"`: A list of strings, only one of which can be selected at a time. Shows a scroll bar if necessary. - * Relevant event: {@link OnGuiSelectionStateChangedEvent on_gui_selection_state_changed} - * - `"camera"`: A camera that shows the game at the given position on the given surface. It can visually track an - * {@link LuaGuiElement.entity entity} that is set after the element has been created. - * - `"choose-elem-button"`: A button that lets the player pick from a certain kind of prototype, with optional filtering. - * Relevant event: {@link OnGuiElemChangedEvent on_gui_elem_changed} - * - `"text-box"`: A multi-line `textfield`. Relevant event: {@link OnGuiTextChangedEvent on_gui_text_changed} - * - `"slider"`: A horizontal number line which can be used to choose a number. Relevant event: - * {@link OnGuiValueChangedEvent on_gui_value_changed} - * - `"minimap"`: A minimap preview, similar to the normal player minimap. It can visually track an - * {@link LuaGuiElement.entity entity} that is set after the element has been created. - * - `"entity-preview"`: A preview of an entity. The {@link LuaGuiElement.entity entity} has to be set after the element - * has been created. - * - `"empty-widget"`: An empty element that just exists. The root GUI elements `screen` and `relative` are `empty-widget`s. - * - `"tabbed-pane"`: A collection of `tab`s and their contents. Relevant event: - * {@link OnGuiSelectedTabChangedEvent on_gui_selected_tab_changed} - * - `"tab"`: A tab for use in a `tabbed-pane`. - * - `"switch"`: A switch with three possible states. Can have labels attached to either side. Relevant event: - * {@link OnGuiSwitchStateChangedEvent on_gui_switch_state_changed} - * - * Each GUI element allows access to its children by having them as attributes. Thus, one can use the `parent.child` - * syntax to refer to children. Lua also supports the `parent["child"]` syntax to refer to the same element. This can be - * used in cases where the child has a name that isn't a valid Lua identifier. - * - * {@link https://lua-api.factorio.com/next/LuaGuiElement.html View documentation} - * - * @example - * This will add a label called `greeting` to the top flow. Immediately after, it will change its text to illustrate accessing child elements. - * - * ```lua - * game.player.gui.top.add{type="label", name="greeting", caption="Hi"} - * game.player.gui.top.greeting.caption = "Hello there!" - * game.player.gui.top["greeting"].caption = "Actually, never mind, I don't like your face" - * ``` - * - * @example - * This will add a tabbed-pane and 2 tabs with contents. - * - * ```lua - * local tabbed_pane = game.player.gui.top.add{type="tabbed-pane"} - * local tab1 = tabbed_pane.add{type="tab", caption="Tab 1"} - * local tab2 = tabbed_pane.add{type="tab", caption="Tab 2"} - * local label1 = tabbed_pane.add{type="label", caption="Label 1"} - * local label2 = tabbed_pane.add{type="label", caption="Label 2"} - * tabbed_pane.add_tab(tab1, label1) - * tabbed_pane.add_tab(tab2, label2) - * ``` - */ -type LuaGuiElement = GuiElementMembers & GuiElementIndex - -/** - * Prototype of a heat energy source. - * - * {@link https://lua-api.factorio.com/next/LuaHeatEnergySourcePrototype.html View documentation} - * - * @noSelf - */ -interface LuaHeatEnergySourcePrototype { - readonly emissions: double - readonly render_no_network_icon: boolean - readonly render_no_power_icon: boolean - readonly max_temperature: double - readonly default_temperature: double - readonly specific_heat: double - readonly max_transfer: double - readonly min_temperature_gradient: double - readonly min_working_temperature: double - readonly minimum_glow_temperature: double - readonly connections: HeatConnection[] - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaHeatEnergySourcePrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Control behavior for inserters. - * - * {@link https://lua-api.factorio.com/next/LuaInserterControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaInserterControlBehavior extends LuaGenericOnOffControlBehavior { - /** - * `true` if the contents of the inserter hand should be sent to the circuit network - * - * {@link https://lua-api.factorio.com/next/LuaInserterControlBehavior.html#LuaInserterControlBehavior.circuit_read_hand_contents View documentation} - */ - circuit_read_hand_contents: boolean - /** - * The circuit mode of operations for the inserter. - * - * {@link https://lua-api.factorio.com/next/LuaInserterControlBehavior.html#LuaInserterControlBehavior.circuit_mode_of_operation View documentation} - */ - circuit_mode_of_operation: defines.control_behavior.inserter.circuit_mode_of_operation - /** - * The hand read mode for the inserter. - * - * {@link https://lua-api.factorio.com/next/LuaInserterControlBehavior.html#LuaInserterControlBehavior.circuit_hand_read_mode View documentation} - */ - circuit_hand_read_mode: defines.control_behavior.inserter.hand_read_mode - /** - * If the stack size of the inserter is set through the circuit network or not. - * - * {@link https://lua-api.factorio.com/next/LuaInserterControlBehavior.html#LuaInserterControlBehavior.circuit_set_stack_size View documentation} - */ - circuit_set_stack_size: boolean - /** - * The signal used to set the stack size of the inserter. - * - * {@link https://lua-api.factorio.com/next/LuaInserterControlBehavior.html#LuaInserterControlBehavior.circuit_stack_control_signal View documentation} - */ - circuit_stack_control_signal: SignalID - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaInserterControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A storage of item stacks. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html View documentation} - * - * @noSelf - */ -interface LuaInventory extends ReadonlyArray { - /** - * Make this inventory empty. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.clear View documentation} - */ - clear(): void - /** - * Can at least some items be inserted? - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.can_insert View documentation} - * - * @param items - Items that would be inserted. - * @returns `true` if at least a part of the given items could be inserted into this inventory. - */ - can_insert(items: ItemStackIdentification): boolean - /** - * Insert items into this inventory. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.insert View documentation} - * - * @param items - Items to insert. - * @returns Number of items actually inserted. - */ - insert(items: ItemStackIdentification): uint - /** - * Remove items from this inventory. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.remove View documentation} - * - * @param items - Items to remove. - * @returns Number of items actually removed. - */ - remove(items: ItemStackIdentification): uint - /** - * Get the number of all or some items in this inventory. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.get_item_count View documentation} - * - * @param item - Prototype name of the item to count. If not specified, count all items. - */ - get_item_count(item?: string): uint - /** - * Does this inventory contain nothing? - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.is_empty View documentation} - */ - is_empty(): boolean - /** - * Get counts of all items in this inventory. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.get_contents View documentation} - * - * @returns The counts, indexed by item names. - */ - get_contents(): Record - /** - * Does this inventory support a bar? Bar is the draggable red thing, found for example on chests, that limits the - * portion of the inventory that may be manipulated by machines. - * - * **Note**: "Supporting a bar" doesn't mean that the bar is set to some nontrivial value. Supporting a bar means - * the inventory supports having this limit at all. The character's inventory is an example of an inventory without - * a bar; the wooden chest's inventory is an example of one with a bar. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.supports_bar View documentation} - */ - supports_bar(): boolean - /** - * Get the current bar. This is the index at which the red area starts. - * - * **Note**: Only useable if this inventory supports having a bar. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.get_bar View documentation} - */ - get_bar(): uint - /** - * Set the current bar. - * - * **Note**: Only useable if this inventory supports having a bar. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.set_bar View documentation} - * - * @param bar - The new limit. Omitting this parameter will clear the limit. - */ - set_bar(bar?: uint): void - /** - * If this inventory supports filters. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.supports_filters View documentation} - */ - supports_filters(): boolean - /** - * If this inventory supports filters and has at least 1 filter set. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.is_filtered View documentation} - */ - is_filtered(): boolean - /** - * If the given inventory slot filter can be set to the given filter. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.can_set_filter View documentation} - * - * @param index - The item stack index - * @param filter - The item name of the filter - */ - can_set_filter(index: uint, filter: string): boolean - /** - * Gets the filter for the given item stack index. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.get_filter View documentation} - * - * @param index - The item stack index - * @returns The current filter or nil if none. - */ - get_filter(index: uint): string | undefined - /** - * Sets the filter for the given item stack index. - * - * **Note**: Some inventory slots don't allow some filters (gun ammo can't be filtered for non-ammo). - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.set_filter View documentation} - * - * @param index - The item stack index - * @param filter - The new filter or nil to erase the filter - * @returns If the filter was allowed to be set. - */ - set_filter(index: uint, filter: string | undefined): boolean - /** - * Gets the first LuaItemStack in the inventory that matches the given item name. - * - * **Note**: This will also return the stack index if one is found that matches as a second return value. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.find_item_stack View documentation} - * - * @param item - The item name to find - * @returns The first matching stack, or `nil` if none match. - */ - find_item_stack(item: string): LuaMultiReturn<[undefined] | [LuaItemStack, uint]> - /** - * Finds the first empty stack. Filtered slots are excluded unless a filter item is given. - * - * **Note**: This will also return the stack index if one is found that matches as a second return value. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.find_empty_stack View documentation} - * - * @param item - If given, empty stacks that are filtered for this item will be included. - * @returns The first empty stack, or `nil` if there aren't any empty stacks. - */ - find_empty_stack(item?: string): LuaMultiReturn<[undefined] | [LuaItemStack, uint]> - /** - * Counts the number of empty stacks. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.count_empty_stacks View documentation} - * - * @param include_filtered - If true, filtered slots will be included. Defaults to false. - */ - count_empty_stacks(include_filtered?: boolean): uint - /** - * Gets the number of the given item that can be inserted into this inventory. - * - * **Note**: This is a "best guess" number; things like assembling machine filtered slots, module slots, items with - * durability, and items with mixed health will cause the result to be inaccurate. - * - * **Note**: The main use for this is in checking how many of a basic item can fit into a basic inventory. - * - * **Note**: This accounts for the 'bar' on the inventory. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.get_insertable_count View documentation} - * - * @param item - The item to check. - */ - get_insertable_count(item: string): void - /** - * Sorts and merges the items in this inventory. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.sort_and_merge View documentation} - */ - sort_and_merge(): void - /** - * Resizes the inventory. - * - * **Note**: Items in slots beyond the new capacity are deleted. - * - * **Note**: Only inventories created by {@link LuaGameScript.create_inventory LuaGameScript::create_inventory} can be resized. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.resize View documentation} - * - * @param size - New size of a inventory - */ - resize(size: uint16): void - /** - * Destroys this inventory. - * - * **Note**: Only inventories created by {@link LuaGameScript.create_inventory LuaGameScript::create_inventory} can - * be destroyed this way. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.destroy View documentation} - */ - destroy(): void - /** - * Get the number of slots in this inventory. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.operator%20# View documentation} - * - * @example - * Will print the number of slots in the player's main inventory. - * - * ```lua - * game.player.print(#game.player.get_main_inventory()) - * ``` - */ - readonly length: uint - /** - * The inventory index this inventory uses, or `nil` if the inventory doesn't have an index. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.index View documentation} - */ - readonly index: defines.inventory | undefined - /** - * The entity that owns this inventory or `nil` if this isn't owned by an entity. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.entity_owner View documentation} - */ - readonly entity_owner: LuaEntity | undefined - /** - * The player that owns this inventory or `nil` if this isn't owned by a player. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.player_owner View documentation} - */ - readonly player_owner: LuaPlayer | undefined - /** - * The equipment that owns this inventory or `nil` if this isn't owned by an equipment. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.equipment_owner View documentation} - */ - readonly equipment_owner: LuaEquipment | undefined - /** - * The mod that owns this inventory or `nil` if this isn't owned by a mod. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.mod_owner View documentation} - */ - readonly mod_owner: string | undefined - /** - * The indexing operator. - * - * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.operator%20[] View documentation} - * - * @example - * Will get the first item in the player's inventory. - * - * ```lua - * game.player.get_main_inventory()[1] - * ``` - */ - readonly [index: number]: LuaItemStack - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaInventory" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of an item. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html View documentation} - * - * @example - * ```lua - * game.item_prototypes["iron-plate"] - * ``` - * - * @noSelf - */ -interface LuaItemPrototype { - /** - * Does this prototype have a flag enabled? - * - * Any other value will cause an error. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.has_flag View documentation} - * - * @param flag - The flag to check. Can be one of {@link ItemPrototypeFlags} - */ - has_flag(flag: string): boolean - /** - * Type of this ammo prototype or `nil` if this is not an ammo prototype. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.get_ammo_type View documentation} - * - * @param ammo_source_type - "default", "player", "turret", or "vehicle" - */ - get_ammo_type(ammo_source_type?: "default" | "player" | "turret" | "vehicle"): AmmoType | undefined - /** - * Type of this prototype. E.g. `"gun"` or `"mining-tool"`. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.type View documentation} - */ - readonly type: "gun" | "mining-tool" - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.name View documentation} - */ - readonly name: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * Order string. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.order View documentation} - */ - readonly order: string - /** - * Prototype of the entity that will be created by placing this item, or `nil` if there is no such entity. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.place_result View documentation} - */ - readonly place_result: LuaEntityPrototype | undefined - /** - * Prototype of the equipment that will be created by placing this item in an equipment grid or `nil` if there is no - * equipment defined. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.place_as_equipment_result View documentation} - */ - readonly place_as_equipment_result: LuaEquipmentPrototype | undefined - /** - * The place-as-tile result if one is defined, else `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.place_as_tile_result View documentation} - */ - readonly place_as_tile_result: PlaceAsTileResult | undefined - /** - * Is this item allowed to stack at all? - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.stackable View documentation} - */ - readonly stackable: boolean - /** - * The default request value. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.default_request_amount View documentation} - */ - readonly default_request_amount: uint - /** - * Maximum stack size of the item specified by this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.stack_size View documentation} - */ - readonly stack_size: uint - /** - * The number of items needed to connect 2 entities with this as wire. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.wire_count View documentation} - */ - readonly wire_count: uint - /** - * The fuel category or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.fuel_category View documentation} - */ - readonly fuel_category: string | undefined - /** - * The result of burning this item as fuel or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.burnt_result View documentation} - */ - readonly burnt_result: LuaItemPrototype | undefined - /** - * Fuel value when burned. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.fuel_value View documentation} - */ - readonly fuel_value: float - /** - * The acceleration multiplier when this item is used as fuel in a vehicle. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.fuel_acceleration_multiplier View documentation} - */ - readonly fuel_acceleration_multiplier: double - /** - * The fuel top speed multiplier when this item is used as fuel in a vehicle. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.fuel_top_speed_multiplier View documentation} - */ - readonly fuel_top_speed_multiplier: double - /** - * The emissions multiplier if this is used as fuel. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.fuel_emissions_multiplier View documentation} - */ - readonly fuel_emissions_multiplier: double - /** - * The subgroup this prototype belongs to. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.subgroup View documentation} - */ - readonly subgroup: LuaGroup - /** - * The group this prototype belongs to. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.group View documentation} - */ - readonly group: LuaGroup - /** - * The item prototype flags for this item prototype. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.flags View documentation} - */ - readonly flags: ItemPrototypeFlags - /** - * The results from launching this item in a rocket. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.rocket_launch_products View documentation} - */ - readonly rocket_launch_products: Product[] - /** - * If this item can be mod-opened. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.can_be_mod_opened View documentation} - */ - readonly can_be_mod_opened: boolean - /** - * Size of full magazine; `nil` if this is not an ammo item. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.magazine_size View documentation} - */ - readonly magazine_size: float | undefined - /** - * Amount of extra time (in ticks) it takes to reload the weapon after depleting the magazine or `nil` if this is - * not an ammo item. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.reload_time View documentation} - */ - readonly reload_time: float | undefined - /** - * The prototype of this armor equipment grid or `nil` if none or this is not an armor item. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.equipment_grid View documentation} - */ - readonly equipment_grid: LuaEquipmentGridPrototype | undefined - /** - * Resistances of this armour item, indexed by damage type name. `nil` if not an armor or the armor has no resistances. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.resistances View documentation} - */ - readonly resistances: Record | undefined - /** - * The inventory size bonus for this armor prototype. `nil` if this isn't an armor prototype. - * - * *Can only be used if this is ArmorPrototype* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.inventory_size_bonus View documentation} - */ - readonly inventory_size_bonus: uint | undefined - /** - * The capsule action for this capsule item prototype or `nil` if this isn't a capsule item prototype. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.capsule_action View documentation} - */ - readonly capsule_action: CapsuleAction | undefined - /** - * The gun attack parameters or `nil` if not a gun item prototype. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.attack_parameters View documentation} - */ - readonly attack_parameters: AttackParameters | undefined - /** - * The main inventory size for item-with-inventory-prototype. `nil` if not an item-with-inventory-prototype. - * - * *Can only be used if this is ItemWithInventoryPrototype* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.inventory_size View documentation} - */ - readonly inventory_size: uint | undefined - /** - * *Can only be used if this is ItemWithInventory* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.item_filters View documentation} - */ - readonly item_filters: Record - /** - * *Can only be used if this is ItemWithInventory* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.item_group_filters View documentation} - */ - readonly item_group_filters: Record - /** - * *Can only be used if this is ItemWithInventory* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.item_subgroup_filters View documentation} - */ - readonly item_subgroup_filters: Record - /** - * The filter mode used by this item with inventory. - * - * *Can only be used if this is ItemWithInventory* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.filter_mode View documentation} - */ - readonly filter_mode: string - /** - * The insertion priority mode used by this item with inventory. - * - * *Can only be used if this is ItemWithInventory* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.insertion_priority_mode View documentation} - */ - readonly insertion_priority_mode: string - /** - * The localised string used when the player attempts to put items into this item with inventory that aren't allowed. - * - * *Can only be used if this is ItemWithInventory* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.localised_filter_message View documentation} - */ - readonly localised_filter_message: LocalisedString - /** - * If this item with inventory extends the inventory it resides in by default. - * - * *Can only be used if this is ItemWithInventory* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.extend_inventory_by_default View documentation} - */ - readonly extend_inventory_by_default: boolean - /** - * The default label color used for this item with label. `nil` if not defined or if this isn't an item with label. - * - * *Can only be used if this is ItemWithLabel* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.default_label_color View documentation} - */ - readonly default_label_color: ColorTable | undefined - /** - * If true, and this item with label has a label it is drawn in place of the normal number when held in the cursor. - * - * *Can only be used if this is ItemWithLabel* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.draw_label_for_cursor_render View documentation} - */ - readonly draw_label_for_cursor_render: boolean - /** - * The repairing speed if this is a repairing tool; otherwise `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.speed View documentation} - */ - readonly speed: float | undefined - /** - * Effects of this module; `nil` if this is not a module. - * - * *Can only be used if this is ModuleItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.module_effects View documentation} - */ - readonly module_effects: ModuleEffects | undefined - /** - * The name of a {@link LuaModuleCategoryPrototype}. Used when upgrading modules: Ctrl + click modules into an entity - * and it will replace lower tier modules of the same category with higher tier modules. - * - * *Can only be used if this is ModuleItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.category View documentation} - */ - readonly category: string - /** - * Tier of the module inside its category. Used when upgrading modules: Ctrl + click modules into an entity and it - * will replace lower tier modules with higher tier modules if they have the same category. - * - * *Can only be used if this is ModuleItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.tier View documentation} - */ - readonly tier: uint - /** - * An array of recipe names this module is allowed to work with. Empty when all recipes are allowed. - * - * *Can only be used if this is ModuleItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.limitations View documentation} - */ - readonly limitations: string[] - /** - * The limitation message key used when the player attempts to use this modules in some place it's not allowed. - * - * *Can only be used if this is ModuleItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.limitation_message_key View documentation} - */ - readonly limitation_message_key: string - /** - * The straight rail prototype used for this rail planner prototype. - * - * *Can only be used if this is RailPlanner* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.straight_rail View documentation} - */ - readonly straight_rail: LuaEntityPrototype - /** - * The curved rail prototype used for this rail planner prototype. - * - * *Can only be used if this is RailPlanner* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.curved_rail View documentation} - */ - readonly curved_rail: LuaEntityPrototype - /** - * The repair result of this repair tool prototype or `nil` if this isn't a repair tool prototype. - * - * *Can only be used if this is RepairTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.repair_result View documentation} - */ - readonly repair_result: TriggerItem[] | undefined - /** - * The color used when doing normal selection with this selection tool prototype. - * - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.selection_border_color View documentation} - */ - readonly selection_border_color: ColorTable - /** - * The color used when doing alt selection with this selection tool prototype. - * - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.alt_selection_border_color View documentation} - */ - readonly alt_selection_border_color: ColorTable - /** - * Flags that affect which entities will be selected. - * - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.selection_mode_flags View documentation} - */ - readonly selection_mode_flags: SelectionModeFlags - /** - * Flags that affect which entities will be selected during alternate selection. - * - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.alt_selection_mode_flags View documentation} - */ - readonly alt_selection_mode_flags: SelectionModeFlags - /** - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.selection_cursor_box_type View documentation} - */ - readonly selection_cursor_box_type: string - /** - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.alt_selection_cursor_box_type View documentation} - */ - readonly alt_selection_cursor_box_type: string - /** - * If tiles area always included when doing selection with this selection tool prototype. - * - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.always_include_tiles View documentation} - */ - readonly always_include_tiles: boolean - /** - * The entity filter mode used by this selection tool. - * - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.entity_filter_mode View documentation} - */ - readonly entity_filter_mode: string - /** - * The alt entity filter mode used by this selection tool. - * - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.alt_entity_filter_mode View documentation} - */ - readonly alt_entity_filter_mode: string - /** - * The tile filter mode used by this selection tool. - * - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.tile_filter_mode View documentation} - */ - readonly tile_filter_mode: string - /** - * The alt tile filter mode used by this selection tool. - * - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.alt_tile_filter_mode View documentation} - */ - readonly alt_tile_filter_mode: string - /** - * The entity filters used by this selection tool indexed by entity name. - * - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.entity_filters View documentation} - */ - readonly entity_filters: Record - /** - * The alt entity filters used by this selection tool indexed by entity name. - * - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.alt_entity_filters View documentation} - */ - readonly alt_entity_filters: Record - /** - * The entity type filters used by this selection tool indexed by entity type. - * - * **Note**: The boolean value is meaningless and is used to allow easy lookup if a type exists in the dictionary. - * - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.entity_type_filters View documentation} - */ - readonly entity_type_filters: Record - /** - * The alt entity type filters used by this selection tool indexed by entity type. - * - * **Note**: The boolean value is meaningless and is used to allow easy lookup if a type exists in the dictionary. - * - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.alt_entity_type_filters View documentation} - */ - readonly alt_entity_type_filters: Record - /** - * The tile filters used by this selection tool indexed by tile name. - * - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.tile_filters View documentation} - */ - readonly tile_filters: Record - /** - * The alt tile filters used by this selection tool indexed by tile name. - * - * *Can only be used if this is SelectionTool* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.alt_tile_filters View documentation} - */ - readonly alt_tile_filters: Record - /** - * The number of entity filters this deconstruction item has or `nil` if this isn't a deconstruction item prototype. - * - * *Can only be used if this is DeconstructionItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.entity_filter_slots View documentation} - */ - readonly entity_filter_slots: uint | undefined - /** - * The number of tile filters this deconstruction item has or `nil` if this isn't a deconstruction item prototype. - * - * *Can only be used if this is DeconstructionItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.tile_filter_slots View documentation} - */ - readonly tile_filter_slots: uint | undefined - /** - * The durability message key used when displaying the durability of this tool. - * - * *Can only be used if this is ToolItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.durability_description_key View documentation} - */ - readonly durability_description_key: string - /** - * The durability of this tool item or `nil` if not a tool item. - * - * *Can only be used if this is ToolItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.durability View documentation} - */ - readonly durability: double | undefined - /** - * If this tool item has infinite durability. `nil` if not a tool type item. - * - * *Can only be used if this is ToolItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.infinite View documentation} - */ - readonly infinite: boolean | undefined - /** - * How many filters an upgrade item has. `nil` if not a upgrade item. - * - * *Can only be used if this is UpgradeItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.mapper_count View documentation} - */ - readonly mapper_count: uint | undefined - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaItemPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A reference to an item and count owned by some external entity. - * - * **Note**: In most instances this is a simple reference as in: it points at a specific slot in an inventory and not - * the item in the slot. - * - * **Note**: In the instance this references an item on a {@link LuaTransportLine} the reference is only guaranteed to - * stay valid (and refer to the same item) as long as nothing changes the transport line. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html View documentation} - * - * @noSelf - */ -interface LuaItemStack { - /** - * Is this blueprint item setup? I.e. is it a non-empty blueprint? - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_blueprint_setup View documentation} - */ - is_blueprint_setup(): boolean - /** - * The entities in this blueprint. - * - * *Can only be used if this is BlueprintItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_blueprint_entities View documentation} - */ - get_blueprint_entities(): BlueprintEntity[] - /** - * Set new entities to be a part of this blueprint. - * - * *Can only be used if this is BlueprintItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_blueprint_entities View documentation} - * - * @param entities - The new blueprint entities. - */ - set_blueprint_entities(entities: BlueprintEntity[]): void - /** - * Add ammo to this ammo item. - * - * *Can only be used if this is AmmoItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.add_ammo View documentation} - * - * @param amount - Amount of ammo to add. - */ - add_ammo(amount: float): void - /** - * Remove ammo from this ammo item. - * - * *Can only be used if this is AmmoItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.drain_ammo View documentation} - * - * @param amount - Amount of ammo to remove. - */ - drain_ammo(amount: float): void - /** - * Add durability to this tool item. - * - * *Can only be used if this is ToolItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.add_durability View documentation} - * - * @param amount - Amount of durability to add. - */ - add_durability(amount: double): void - /** - * Remove durability from this tool item. - * - * *Can only be used if this is ToolItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.drain_durability View documentation} - * - * @param amount - Amount of durability to remove. - */ - drain_durability(amount: double): void - /** - * Would a call to {@link LuaItemStack.set_stack LuaItemStack::set_stack} succeed? - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.can_set_stack View documentation} - * - * @param stack - Stack that would be set, possibly `nil`. - */ - can_set_stack(stack?: ItemStackIdentification): boolean - /** - * Set this item stack to another item stack. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_stack View documentation} - * - * @param stack - Item stack to set this one to. Omitting this parameter or passing `nil` will clear this item - * stack, as if by calling {@link LuaItemStack.clear LuaItemStack::clear}. - * @returns Was the stack set successfully? - */ - set_stack(stack?: ItemStackIdentification): boolean - /** - * Transfers the given item stack into this item stack. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.transfer_stack View documentation} - * - * @param stack - * @returns True if the full stack was transferred. - */ - transfer_stack(stack: ItemStackIdentification): boolean - /** - * Export a supported item (blueprint, blueprint-book, deconstruction-planner, upgrade-planner, item-with-tags) to a string - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.export_stack View documentation} - * - * @returns The exported string - */ - export_stack(): string - /** - * Import a supported item (blueprint, blueprint-book, deconstruction-planner, upgrade-planner, item-with-tags) from a string - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.import_stack View documentation} - * - * @param data - The string to import - * @returns 0 if the import succeeded with no errors. -1 if the import succeeded with errors. 1 if the import failed. - */ - import_stack(data: string): int - /** - * Swaps this item stack with the given item stack if allowed. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.swap_stack View documentation} - * - * @param stack - * @returns If the 2 stacks were swapped successfully. - */ - swap_stack(stack: LuaItemStack): boolean - /** - * Clear this item stack. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.clear View documentation} - */ - clear(): void - /** - * A list of the tiles in this blueprint. - * - * *Can only be used if this is BlueprintItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_blueprint_tiles View documentation} - */ - get_blueprint_tiles(): Tile[] - /** - * Set specific tiles in this blueprint. - * - * *Can only be used if this is BlueprintItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_blueprint_tiles View documentation} - * - * @param tiles - Tiles to be a part of the blueprint. - */ - set_blueprint_tiles(tiles: Tile[]): void - /** - * Access the inner inventory of an item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_inventory View documentation} - * - * @param inventory - Index of the inventory to access -- currently can only be {@link defines.inventory.item_main}. - * @returns Or `nil` if there is no inventory with the given index. - */ - get_inventory(inventory: defines.inventory): LuaInventory | undefined - /** - * Build this blueprint - * - * **Note**: Built entities can be come invalid between the building of the blueprint and the function returning if - * by_player or raise_built is used and one of those events invalidates the entity. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.build_blueprint View documentation} - * - * @returns Array of created ghosts - */ - build_blueprint(params: { - /** Surface to build on */ - readonly surface: SurfaceIdentification - /** Force to use for the building */ - readonly force: ForceIdentification - /** The position to build at */ - readonly position: Position - /** When true, anything that can be built is else nothing is built if any one thing can't be built */ - readonly force_build?: boolean - /** The direction to use when building */ - readonly direction?: defines.direction - /** If chunks covered by fog-of-war are skipped. */ - readonly skip_fog_of_war?: boolean - /** - * The player to use if any. If provided {@link defines.events.on_built_entity} will also be fired on successful - * entity creation. - */ - readonly by_player?: PlayerIdentification - /** - * If true; {@link defines.events.script_raised_built} will be fired on successful entity creation. Note: this is - * ignored if by_player is provided. - */ - readonly raise_built?: boolean - }): LuaEntity[] - /** - * Deconstruct the given area with this deconstruction item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.deconstruct_area View documentation} - */ - deconstruct_area(params: { - /** Surface to deconstruct on */ - readonly surface: SurfaceIdentification - /** Force to use for the deconstruction */ - readonly force: ForceIdentification - /** The area to deconstruct */ - readonly area: BoundingBox - /** If chunks covered by fog-of-war are skipped. */ - readonly skip_fog_of_war?: boolean - /** The player to use if any. */ - readonly by_player?: PlayerIdentification - }): void - /** - * Cancel deconstruct the given area with this deconstruction item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.cancel_deconstruct_area View documentation} - */ - cancel_deconstruct_area(params: { - /** Surface to cancel deconstruct on */ - readonly surface: SurfaceIdentification - /** Force to use for canceling deconstruction */ - readonly force: ForceIdentification - /** The area to deconstruct */ - readonly area: BoundingBox - /** If chunks covered by fog-of-war are skipped. */ - readonly skip_fog_of_war?: boolean - /** The player to use if any. */ - readonly by_player?: PlayerIdentification - }): void - /** - * Sets up this blueprint using the found blueprintable entities/tiles on the surface. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.create_blueprint View documentation} - * - * @returns The blueprint entity index to source entity mapping. - */ - create_blueprint(params: { - /** Surface to create from */ - readonly surface: SurfaceIdentification - /** Force to use for the creation */ - readonly force: ForceIdentification - /** The bounding box */ - readonly area: BoundingBox - /** - * When true, blueprintable tiles are always included in the blueprint. When false they're only included if no - * entities exist in the setup area. - */ - readonly always_include_tiles?: boolean - /** When true, entities are included in the blueprint. Defaults to true. */ - readonly include_entities?: boolean - /** When true, modules are included in the blueprint. Defaults to true. */ - readonly include_modules?: boolean - /** When true, station names are included in the blueprint. Defaults to false. */ - readonly include_station_names?: boolean - /** When true, trains are included in the blueprint. Defaults to false. */ - readonly include_trains?: boolean - /** When true, train fuel is included in the blueprint, Defaults to true. */ - readonly include_fuel?: boolean - }): Record - /** - * Gets the tag with the given name or returns `nil` if it doesn't exist. - * - * *Can only be used if this is ItemWithTags* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_tag View documentation} - * - * @param tag_name - */ - get_tag(tag_name: string): AnyBasic | undefined - /** - * Sets the tag with the given name and value. - * - * *Can only be used if this is ItemWithTags* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_tag View documentation} - * - * @param tag_name - * @param tag - */ - set_tag(tag_name: string, tag: AnyBasic): AnyBasic - /** - * Removes a tag with the given name. - * - * *Can only be used if this is ItemWithTags* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.remove_tag View documentation} - * - * @param tag - * @returns If the tag existed and was removed. - */ - remove_tag(tag: string): boolean - /** - * Clears this blueprint item. - * - * *Can only be used if this is BlueprintItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.clear_blueprint View documentation} - */ - clear_blueprint(): void - /** - * Gets the entity filter at the given index for this deconstruction item. - * - * *Can only be used if this is DeconstructionItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_entity_filter View documentation} - * - * @param index - */ - get_entity_filter(index: uint): string - /** - * Sets the entity filter at the given index for this deconstruction item. - * - * *Can only be used if this is DeconstructionItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_entity_filter View documentation} - * - * @param index - * @param filter - Setting to nil erases the filter. - * @returns If the new filter was set (was valid.) - */ - set_entity_filter(index: uint, filter: string | LuaEntityPrototype | LuaEntity | undefined): boolean - /** - * Gets the tile filter at the given index for this deconstruction item. - * - * *Can only be used if this is DeconstructionItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_tile_filter View documentation} - * - * @param index - */ - get_tile_filter(index: uint): string - /** - * Sets the tile filter at the given index for this deconstruction item. - * - * *Can only be used if this is DeconstructionItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_tile_filter View documentation} - * - * @param index - * @param filter - Setting to nil erases the filter. - * @returns If the new filter was set (was valid.) - */ - set_tile_filter(index: uint, filter: string | LuaTilePrototype | LuaTile | undefined): boolean - /** - * Clears all settings/filters on this deconstruction item resetting it to default values. - * - * *Can only be used if this is DeconstructionItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.clear_deconstruction_item View documentation} - */ - clear_deconstruction_item(): void - /** - * Clears all settings/filters on this upgrade item resetting it to default values. - * - * *Can only be used if this is UpgradeItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.clear_upgrade_item View documentation} - */ - clear_upgrade_item(): void - /** - * Gets the filter at the given index for this upgrade item. - * - * *Can only be used if this is UpgradeItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_mapper View documentation} - * - * @param index - The index of the mapper to read. - * @param type - 'from' or 'to'. - */ - get_mapper(index: uint, type: "from" | "to"): UpgradeFilter - /** - * Sets the module filter at the given index for this upgrade item. - * - * *Can only be used if this is UpgradeItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_mapper View documentation} - * - * @param index - The index of the mapper to set. - * @param type - `from` or `to`. - * @param filter - The filter to set or `nil` - */ - set_mapper(index: uint, type: string, filter: UpgradeFilter | undefined): void - /** - * Gets the number of entities in this blueprint item. - * - * *Can only be used if this is BlueprintItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_blueprint_entity_count View documentation} - */ - get_blueprint_entity_count(): uint - /** - * Gets the tags for the given blueprint entity index in this blueprint item. - * - * *Can only be used if this is BlueprintItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_blueprint_entity_tags View documentation} - * - * @param index - */ - get_blueprint_entity_tags(index: uint): Tags - /** - * Sets the tags on the given blueprint entity index in this blueprint item. - * - * *Can only be used if this is BlueprintItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_blueprint_entity_tags View documentation} - * - * @param index - The entity index - * @param tags - */ - set_blueprint_entity_tags(index: uint, tags: Tags): void - /** - * Gets the given tag on the given blueprint entity index in this blueprint item. - * - * *Can only be used if this is BlueprintItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_blueprint_entity_tag View documentation} - * - * @param index - The entity index. - * @param tag - The tag to get. - */ - get_blueprint_entity_tag(index: uint, tag: string): AnyBasic - /** - * Sets the given tag on the given blueprint entity index in this blueprint item. - * - * *Can only be used if this is BlueprintItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_blueprint_entity_tag View documentation} - * - * @param index - The entity index. - * @param tag - The tag to set. - * @param value - The tag value to set or `nil` to clear the tag. - */ - set_blueprint_entity_tag(index: uint, tag: string, value: AnyBasic | undefined): void - /** - * Creates the equipment grid for this item if it doesn't exist and this is an item-with-entity-data that supports - * equipment grids. - * - * *Can only be used if this is ItemWithEntityData* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.create_grid View documentation} - */ - create_grid(): LuaEquipmentGrid - /** - * Is this valid for reading? Differs from the usual `valid` in that `valid` will be `true` even if the item stack - * is blank but the entity that holds it is still valid. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.valid_for_read View documentation} - */ - readonly valid_for_read: boolean - /** - * Prototype of the item held in this stack. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.prototype View documentation} - */ - readonly prototype: LuaItemPrototype - /** - * Prototype name of the item held in this stack. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.name View documentation} - */ - readonly name: string - /** - * Type of the item prototype. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.type View documentation} - */ - readonly type: string - /** - * Number of items in this stack. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.count View documentation} - */ - count: uint - /** - * The equipment grid of this item or `nil` if this item doesn't have a grid. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.grid View documentation} - */ - readonly grid: LuaEquipmentGrid | undefined - /** - * How much health the item has, as a number in range [0, 1]. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.health View documentation} - */ - health: float - /** - * Durability of the contained item. Automatically capped at the item's maximum durability. - * - * **Note**: When used on a non-tool item, the value of this attribute is `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.durability View documentation} - */ - durability: double | undefined - /** - * Number of bullets left in the magazine. - * - * *Can only be used if this is AmmoItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.ammo View documentation} - */ - ammo: uint - /** - * Icons of a blueprint item, blueprint book, deconstruction item or upgrade planner. An item that doesn't have - * icons returns nil on read and throws error on write. - * - * *Can only be used if this is BlueprintItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.blueprint_icons View documentation} - */ - blueprint_icons: BlueprintSignalIcon[] | undefined - /** - * The snapping grid size in this blueprint item or nil if snapping is not enabled. - * - * *Can only be used if this is BlueprintItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.blueprint_snap_to_grid View documentation} - */ - blueprint_snap_to_grid: Position | undefined - /** - * The offset from the absolute grid or nil if absolute snapping is not enabled. - * - * *Can only be used if this is BlueprintItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.blueprint_position_relative_to_grid View documentation} - */ - blueprint_position_relative_to_grid: Position | undefined - /** - * If absolute snapping is enabled on this blueprint item. - * - * *Can only be used if this is BlueprintItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.blueprint_absolute_snapping View documentation} - */ - blueprint_absolute_snapping: boolean - /** - * The current label for this item. Nil when none. - * - * *Can only be used if this is ItemWithLabel* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.label View documentation} - */ - label: string | undefined - /** - * The current label color for this item. Nil when none. - * - * *Can only be used if this is ItemWithLabel* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.label_color View documentation} - */ - label_color: Color | undefined - /** - * If the label for this item can be manually changed. When false the label can only be changed through the API. - * - * *Can only be used if this is ItemWithLabel* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.allow_manual_label_change View documentation} - */ - allow_manual_label_change: boolean - /** - * Raw materials required to build this blueprint. Result is a dictionary mapping each item prototype name to the - * required count. - * - * *Can only be used if this is BlueprintItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.cost_to_build View documentation} - */ - readonly cost_to_build: Record - /** - * If this item extends the inventory it resides in (provides its contents for counts, crafting, insertion). Only - * callable on items with inventories. - * - * *Can only be used if this is ItemWithInventory* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.extends_inventory View documentation} - */ - extends_inventory: boolean - /** - * The insertion mode priority this ItemWithInventory uses when items are inserted into an inventory it resides in. - * Only callable on items with inventories. - * - * *Can only be used if this is ItemWithInventory* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.prioritize_insertion_mode View documentation} - */ - prioritize_insertion_mode: string - /** - * The default icons for a blueprint item. - * - * *Can only be used if this is BlueprintItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.default_icons View documentation} - */ - readonly default_icons: BlueprintItemIcon[] - /** - * *Can only be used if this is ItemWithTags* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.tags View documentation} - */ - tags: Tags - /** - * The custom description this item-with-tags. This is shown over the normal item description if this is set to a - * non-empty value. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.custom_description View documentation} - */ - custom_description: LocalisedString - /** - * The entity filters for this deconstruction item. The attribute is a sparse array with the keys representing the - * index of the filter. All strings in this array must be entity prototype names that don't have the - * `"not-deconstructable"` flag set and are either a `cliff` or marked as `minable`. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.entity_filters View documentation} - */ - entity_filters: string[] - /** - * The tile filters for this deconstruction item. The attribute is a sparse array with the keys representing the - * index of the filter. All strings in this array must be tile prototype names. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.tile_filters View documentation} - */ - tile_filters: string[] - /** - * The blacklist/whitelist entity filter mode for this deconstruction item. - * - * *Can only be used if this is DeconstructionItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.entity_filter_mode View documentation} - */ - entity_filter_mode: defines.deconstruction_item.entity_filter_mode - /** - * The blacklist/whitelist tile filter mode for this deconstruction item. - * - * *Can only be used if this is DeconstructionItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.tile_filter_mode View documentation} - */ - tile_filter_mode: defines.deconstruction_item.tile_filter_mode - /** - * The tile selection mode for this deconstruction item. - * - * *Can only be used if this is DeconstructionItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.tile_selection_mode View documentation} - */ - tile_selection_mode: defines.deconstruction_item.tile_selection_mode - /** - * If this deconstruction item is set to allow trees and rocks only. - * - * *Can only be used if this is DeconstructionItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.trees_and_rocks_only View documentation} - */ - trees_and_rocks_only: boolean - /** - * The number of entity filters this deconstruction item supports. - * - * *Can only be used if this is DeconstructionItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.entity_filter_count View documentation} - */ - readonly entity_filter_count: uint - /** - * The number of tile filters this deconstruction item supports. - * - * *Can only be used if this is DeconstructionItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.tile_filter_count View documentation} - */ - readonly tile_filter_count: uint - /** - * The active blueprint index for this blueprint book. May be `nil`. - * - * *Can only be used if this is BlueprintBookItem* - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.active_index View documentation} - */ - active_index: uint | undefined - /** - * The unique identifier for this item if it has one, `nil` otherwise. Note that this ID stays the same no matter - * where the item is moved to. - * - * Only these types of items have unique IDs: - * - * - `"armor"` - * - `"spidertron-remote"` - * - `"selection-tool"` - * - `"copy-paste-tool"` - * - `"upgrade-item"` - * - `"deconstruction-item"` - * - `"blueprint"` - * - `"blueprint-book"` - * - `"item-with-entity-data"` - * - `"item-with-inventory"` - * - `"item-with-tags"` - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.item_number View documentation} - */ - readonly item_number: uint | undefined - /** - * If this item is a spidertron remote that has a spidertron bound to it, it returns the connected spider-vehicle - * entity, `nil` otherwise. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.connected_entity View documentation} - */ - connected_entity: LuaEntity | undefined - /** - * If this is a blueprint item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_blueprint View documentation} - */ - readonly is_blueprint: boolean - /** - * If this is a blueprint book item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_blueprint_book View documentation} - */ - readonly is_blueprint_book: boolean - /** - * If this is a module item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_module View documentation} - */ - readonly is_module: boolean - /** - * If this is a tool item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_tool View documentation} - */ - readonly is_tool: boolean - /** - * If this is a mining tool item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_mining_tool View documentation} - */ - readonly is_mining_tool: boolean - /** - * If this is an armor item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_armor View documentation} - */ - readonly is_armor: boolean - /** - * If this is a repair tool item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_repair_tool View documentation} - */ - readonly is_repair_tool: boolean - /** - * If this is an item with label item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_item_with_label View documentation} - */ - readonly is_item_with_label: boolean - /** - * If this is an item with inventory item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_item_with_inventory View documentation} - */ - readonly is_item_with_inventory: boolean - /** - * If this is an item with entity data item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_item_with_entity_data View documentation} - */ - readonly is_item_with_entity_data: boolean - /** - * If this is a selection tool item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_selection_tool View documentation} - */ - readonly is_selection_tool: boolean - /** - * If this is an item with tags item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_item_with_tags View documentation} - */ - readonly is_item_with_tags: boolean - /** - * If this is a deconstruction tool item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_deconstruction_item View documentation} - */ - readonly is_deconstruction_item: boolean - /** - * If this is a upgrade item. - * - * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_upgrade_item View documentation} - */ - readonly is_upgrade_item: boolean - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaItemStack" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Control behavior for lamps. - * - * {@link https://lua-api.factorio.com/next/LuaLampControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaLampControlBehavior extends LuaGenericOnOffControlBehavior { - /** - * `true` if the lamp should set the color from the circuit network signals. - * - * {@link https://lua-api.factorio.com/next/LuaLampControlBehavior.html#LuaLampControlBehavior.use_colors View documentation} - */ - use_colors: boolean - /** - * The color the lamp is showing or `nil` if not using any color. - * - * {@link https://lua-api.factorio.com/next/LuaLampControlBehavior.html#LuaLampControlBehavior.color View documentation} - */ - readonly color: ColorTable | undefined - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaLampControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A lazily loaded value. For performance reasons, we sometimes return a custom lazily-loaded value type instead of the - * native Lua value. This custom type lazily constructs the necessary value when - * {@link LuaLazyLoadedValue.get LuaLazyLoadedValue::get} is called, therefore preventing its unnecessary construction in - * some cases. - * - * An instance of LuaLazyLoadedValue is only valid during the event it was created from and cannot be saved. - * - * {@link https://lua-api.factorio.com/next/LuaLazyLoadedValue.html View documentation} - * - * @noSelf - */ -interface LuaLazyLoadedValue { - /** - * Gets the value of this lazy loaded value. - * - * {@link https://lua-api.factorio.com/next/LuaLazyLoadedValue.html#LuaLazyLoadedValue.get View documentation} - */ - get(): T - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaLazyLoadedValue" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Logistic cell of a particular {@link LuaEntity}. A "Logistic Cell" is the given name for settings and properties used - * by what would normally be seen as a "Roboport". A logistic cell however doesn't have to be attached to the roboport - * entity (the character has one for the personal roboport). - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html View documentation} - * - * @noSelf - */ -interface LuaLogisticCell { - /** - * Is a given position within the logistic range of this cell? - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.is_in_logistic_range View documentation} - * - * @param position - */ - is_in_logistic_range(position: Position): boolean - /** - * Is a given position within the construction range of this cell? - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.is_in_construction_range View documentation} - * - * @param position - */ - is_in_construction_range(position: Position): boolean - /** - * Are two cells neighbours? - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.is_neighbour_with View documentation} - * - * @param other - */ - is_neighbour_with(other: LuaLogisticCell): boolean - /** - * Logistic radius of this cell. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.logistic_radius View documentation} - */ - readonly logistic_radius: float - /** - * Logistic connection distance of this cell. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.logistics_connection_distance View documentation} - */ - readonly logistics_connection_distance: float - /** - * Construction radius of this cell. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.construction_radius View documentation} - */ - readonly construction_radius: float - /** - * Number of stationed logistic robots in this cell. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.stationed_logistic_robot_count View documentation} - */ - readonly stationed_logistic_robot_count: uint - /** - * Number of stationed construction robots in this cell. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.stationed_construction_robot_count View documentation} - */ - readonly stationed_construction_robot_count: uint - /** - * `true` if this is a mobile cell. In vanilla, only the logistic cell created by a character's personal roboport is mobile. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.mobile View documentation} - */ - readonly mobile: boolean - /** - * `true` if this cell is active. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.transmitting View documentation} - */ - readonly transmitting: boolean - /** - * Radius at which the robots hover when waiting to be charged. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.charge_approach_distance View documentation} - */ - readonly charge_approach_distance: float - /** - * Number of robots currently charging. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.charging_robot_count View documentation} - */ - readonly charging_robot_count: uint - /** - * Number of robots waiting to charge. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.to_charge_robot_count View documentation} - */ - readonly to_charge_robot_count: uint - /** - * This cell's owner. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.owner View documentation} - */ - readonly owner: LuaEntity - /** - * The network that owns this cell or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.logistic_network View documentation} - */ - readonly logistic_network: LuaLogisticNetwork | undefined - /** - * Neighbouring cells. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.neighbours View documentation} - */ - readonly neighbours: LuaLogisticCell[] - /** - * Robots currently being charged. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.charging_robots View documentation} - */ - readonly charging_robots: LuaEntity[] - /** - * Robots waiting to charge. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.to_charge_robots View documentation} - */ - readonly to_charge_robots: LuaEntity[] - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaLogisticCell" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Control behavior for logistic chests. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticContainerControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaLogisticContainerControlBehavior extends LuaControlBehavior { - /** - * The circuit mode of operations for the logistic container. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticContainerControlBehavior.html#LuaLogisticContainerControlBehavior.circuit_mode_of_operation View documentation} - */ - circuit_mode_of_operation: defines.control_behavior.logistic_container.circuit_mode_of_operation - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaLogisticContainerControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A single logistic network of a given force on a given surface. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html View documentation} - * - * @noSelf - */ -interface LuaLogisticNetwork { - /** - * Count given or all items in the network or given members. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.get_item_count View documentation} - * - * @param item - Item name to count. If not given, gives counts of all items in the network. - * @param member - Logistic members to check, must be either `"storage"` or `"providers"`. If not given, gives count - * in the entire network. - */ - get_item_count(item?: string, member?: "storage" | "providers"): int - /** - * Get item counts for the entire network. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.get_contents View documentation} - * - * @returns A mapping of item prototype names to the number available in the network. - * @see {@link LuaInventory.get_contents} - */ - get_contents(): Record - /** - * Remove items from the logistic network. This will actually remove the items from some logistic chests. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.remove_item View documentation} - * - * @param item - What to remove. - * @param members - Which logistic members to remove from. Must be `"storage"`, `"passive-provider"`, `"buffer"`, or - * `"active-provider"`. If not specified, removes from the network in the usual order. - * @returns Number of items removed. - */ - remove_item( - item: ItemStackIdentification, - members?: "storage" | "passive-provider" | "buffer" | "active-provider" - ): uint - /** - * Insert items into the logistic network. This will actually insert the items into some logistic chests. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.insert View documentation} - * - * @param item - What to insert. - * @param members - Which logistic members to insert the items to. Must be `"storage"`, `"storage-empty"` (storage - * chests that are completely empty), `"storage-empty-slot"` (storage chests that have an empty slot), or - * `"requester"`. If not specified, inserts items into the logistic network in the usual order. - * @returns Number of items actually inserted. - */ - insert( - item: ItemStackIdentification, - members?: "storage" | "storage-empty" | "storage-empty-slot" | "requester" - ): uint - /** - * Find logistic cell closest to a given position. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.find_cell_closest_to View documentation} - * - * @param position - * @returns May be `nil` if no cell was found. - */ - find_cell_closest_to(position: Position): LuaLogisticCell | undefined - /** - * Find the 'best' logistic point with this item ID and from the given position or from given chest type. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.select_pickup_point View documentation} - * - * @returns May be `nil` if no point was found. - */ - select_pickup_point(params: { - /** Name of the item to select. */ - readonly name: string - /** When given, it will find the storage 'best' storage point from this position. */ - readonly position?: Position - /** Whether to consider buffer chests or not. Defaults to false. Only considered if selecting with position. */ - readonly include_buffers?: boolean - /** - * When given, it will find from only the specific type of member. Must be `"storage"`, `"passive-provider"`, - * `"buffer"` or `"active-provider"`. If not specified, selects with normal priorities. Not considered if - * position is specified. - */ - readonly members?: "storage" | "passive-provider" | "buffer" | "active-provider" - }): LuaLogisticPoint | undefined - /** - * Find a logistic point to drop the specific item stack. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.select_drop_point View documentation} - * - * @returns May be `nil` if no point was found. - */ - select_drop_point(params: { - /** Name of the item to select. */ - readonly stack: ItemStackIdentification - /** - * When given, it will find from only the specific type of member. Must be `"storage"`, `"storage-empty"`, - * `"storage-empty-slot"` or `"requester"`. If not specified, selects with normal priorities. - */ - readonly members?: "storage" | "storage-empty" | "storage-empty-slot" | "requester" - }): LuaLogisticPoint | undefined - /** - * The force this logistic network belongs to. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.force View documentation} - */ - readonly force: LuaForce - /** - * Number of logistic robots available for a job. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.available_logistic_robots View documentation} - */ - readonly available_logistic_robots: uint - /** - * The total number of logistic robots in the network (idle and active + in roboports). - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.all_logistic_robots View documentation} - */ - readonly all_logistic_robots: uint - /** - * Number of construction robots available for a job. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.available_construction_robots View documentation} - */ - readonly available_construction_robots: uint - /** - * The total number of construction robots in the network (idle and active + in roboports). - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.all_construction_robots View documentation} - */ - readonly all_construction_robots: uint - /** - * Maximum number of robots the network can work with. Currently only used for the personal roboport. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.robot_limit View documentation} - */ - readonly robot_limit: uint - /** - * All cells in this network. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.cells View documentation} - */ - readonly cells: LuaLogisticCell[] - /** - * All entities that have logistic provider points in this network. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.providers View documentation} - */ - readonly providers: LuaEntity[] - /** - * All entities that have empty logistic provider points in this network. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.empty_providers View documentation} - */ - readonly empty_providers: LuaEntity[] - /** - * All entities that have logistic requester points in this network. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.requesters View documentation} - */ - readonly requesters: LuaEntity[] - /** - * All entities that have logistic storage points in this network. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.storages View documentation} - */ - readonly storages: LuaEntity[] - /** - * All other entities that have logistic points in this network (inserters mostly). - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.logistic_members View documentation} - */ - readonly logistic_members: LuaEntity[] - /** - * All things that have provider points in this network. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.provider_points View documentation} - */ - readonly provider_points: LuaLogisticPoint[] - /** - * All passive provider points in this network. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.passive_provider_points View documentation} - */ - readonly passive_provider_points: LuaLogisticPoint[] - /** - * All active provider points in this network. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.active_provider_points View documentation} - */ - readonly active_provider_points: LuaLogisticPoint[] - /** - * All things that have empty provider points in this network. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.empty_provider_points View documentation} - */ - readonly empty_provider_points: LuaLogisticPoint[] - /** - * All things that have requester points in this network. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.requester_points View documentation} - */ - readonly requester_points: LuaLogisticPoint[] - /** - * All things that have storage points in this network. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.storage_points View documentation} - */ - readonly storage_points: LuaLogisticPoint[] - /** - * All robots in this logistic network. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.robots View documentation} - */ - readonly robots: LuaEntity[] - /** - * All construction robots in this logistic network. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.construction_robots View documentation} - */ - readonly construction_robots: LuaEntity[] - /** - * All logistic robots in this logistic network. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.logistic_robots View documentation} - */ - readonly logistic_robots: LuaEntity[] - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaLogisticNetwork" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Logistic point of a particular {@link LuaEntity}. A "Logistic point" is the name given for settings and properties - * used by requester, provider, and storage points in a given logistic network. These "points" don't have to be a - * logistic container but often are. One other entity that can own several points is the "character" character type entity. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html View documentation} - * - * @noSelf - */ -interface LuaLogisticPoint { - /** - * The {@link LuaEntity} owner of this {@link LuaLogisticPoint}. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html#LuaLogisticPoint.owner View documentation} - */ - readonly owner: LuaEntity - readonly logistic_network: LuaLogisticNetwork - /** - * The Logistic member index of this logistic point. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html#LuaLogisticPoint.logistic_member_index View documentation} - */ - readonly logistic_member_index: uint - /** - * The logistic filters for this logistic point or `nil` if this doesn't use logistic filters. - * - * **Note**: The returned array will always have an entry for each filter and will be indexed in sequence when not nil. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html#LuaLogisticPoint.filters View documentation} - */ - readonly filters: LogisticFilter[] | undefined - /** - * The logistic mode. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html#LuaLogisticPoint.mode View documentation} - */ - readonly mode: defines.logistic_mode - /** - * The force of this logistic point. - * - * **Note**: This will always be the same as the {@link LuaLogisticPoint.owner LuaLogisticPoint::owner} force. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html#LuaLogisticPoint.force View documentation} - */ - readonly force: LuaForce - /** - * Items targeted to be picked up from this logistic point by robots. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html#LuaLogisticPoint.targeted_items_pickup View documentation} - */ - readonly targeted_items_pickup: Record - /** - * Items targeted to be dropped off into this logistic point by robots. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html#LuaLogisticPoint.targeted_items_deliver View documentation} - */ - readonly targeted_items_deliver: Record - /** - * If this logistic point is using the exact mode. In exact mode robots never over-deliver requests. - * - * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html#LuaLogisticPoint.exact View documentation} - */ - readonly exact: boolean - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaLogisticPoint" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Control behavior for mining drills. - * - * {@link https://lua-api.factorio.com/next/LuaMiningDrillControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaMiningDrillControlBehavior extends LuaGenericOnOffControlBehavior { - /** - * `true` if this drill is enabled or disabled using the logistics or circuit condition. - * - * {@link https://lua-api.factorio.com/next/LuaMiningDrillControlBehavior.html#LuaMiningDrillControlBehavior.circuit_enable_disable View documentation} - */ - circuit_enable_disable: boolean - /** - * `true` if this drill should send the resources in the field to the circuit network. Which resources depends on - * {@link LuaMiningDrillControlBehavior.resource_read_mode LuaMiningDrillControlBehavior::resource_read_mode} - * - * {@link https://lua-api.factorio.com/next/LuaMiningDrillControlBehavior.html#LuaMiningDrillControlBehavior.circuit_read_resources View documentation} - */ - circuit_read_resources: boolean - /** - * If the mining drill should send just the resources in its area or the entire field it's on to the circuit network. - * - * {@link https://lua-api.factorio.com/next/LuaMiningDrillControlBehavior.html#LuaMiningDrillControlBehavior.resource_read_mode View documentation} - */ - resource_read_mode: defines.control_behavior.mining_drill.resource_read_mode - /** - * The resource entities that the mining drill will send information about to the circuit network or an empty array. - * - * {@link https://lua-api.factorio.com/next/LuaMiningDrillControlBehavior.html#LuaMiningDrillControlBehavior.resource_read_targets View documentation} - */ - readonly resource_read_targets: LuaEntity[] - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaMiningDrillControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a mod setting. - * - * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html View documentation} - * - * @noSelf - */ -interface LuaModSettingPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * The mod that owns this setting. - * - * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.mod View documentation} - */ - readonly mod: string - readonly setting_type: string - /** - * The default value of this setting. - * - * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.default_value View documentation} - */ - readonly default_value: boolean | double | int | string - /** - * The minimum value for this setting or `nil` if this setting type doesn't support a minimum. - * - * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.minimum_value View documentation} - */ - readonly minimum_value: double | int | undefined - /** - * The maximum value for this setting or `nil` if this setting type doesn't support a maximum. - * - * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.maximum_value View documentation} - */ - readonly maximum_value: double | int | undefined - /** - * The allowed values for this setting or `nil` if this setting doesn't use the a fixed set of values. - * - * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.allowed_values View documentation} - */ - readonly allowed_values: string[] | int[] | double[] | undefined - /** - * If this string setting allows blank values or `nil` if not a string setting. - * - * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.allow_blank View documentation} - */ - readonly allow_blank: boolean | undefined - /** - * If this string setting auto-trims values or `nil` if not a string setting. - * - * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.auto_trim View documentation} - */ - readonly auto_trim: boolean | undefined - /** - * If this setting is hidden from the GUI. - * - * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.hidden View documentation} - */ - readonly hidden: boolean - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaModSettingPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a module category. - * - * {@link https://lua-api.factorio.com/next/LuaModuleCategoryPrototype.html View documentation} - * - * @noSelf - */ -interface LuaModuleCategoryPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaModuleCategoryPrototype.html#LuaModuleCategoryPrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaModuleCategoryPrototype.html#LuaModuleCategoryPrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaModuleCategoryPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a named noise expression. - * - * {@link https://lua-api.factorio.com/next/LuaNamedNoiseExpression.html View documentation} - * - * @noSelf - */ -interface LuaNamedNoiseExpression { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaNamedNoiseExpression.html#LuaNamedNoiseExpression.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaNamedNoiseExpression.html#LuaNamedNoiseExpression.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * Name of the property that this expression is intended to provide a value for, if any. - * - * {@link https://lua-api.factorio.com/next/LuaNamedNoiseExpression.html#LuaNamedNoiseExpression.intended_property View documentation} - */ - readonly intended_property: string - /** - * The expression itself. - * - * {@link https://lua-api.factorio.com/next/LuaNamedNoiseExpression.html#LuaNamedNoiseExpression.expression View documentation} - */ - readonly expression: NoiseExpression - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaNamedNoiseExpression" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a noise layer. - * - * {@link https://lua-api.factorio.com/next/LuaNoiseLayerPrototype.html View documentation} - * - * @noSelf - */ -interface LuaNoiseLayerPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaNoiseLayerPrototype.html#LuaNoiseLayerPrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaNoiseLayerPrototype.html#LuaNoiseLayerPrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaNoiseLayerPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of an optimized particle. - * - * {@link https://lua-api.factorio.com/next/LuaParticlePrototype.html View documentation} - * - * @noSelf - */ -interface LuaParticlePrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaParticlePrototype.html#LuaParticlePrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaParticlePrototype.html#LuaParticlePrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - readonly regular_trigger_effect: TriggerEffectItem - readonly ended_in_water_trigger_effect: TriggerEffectItem - readonly render_layer: RenderLayer - readonly render_layer_when_on_ground: RenderLayer - readonly life_time: uint - readonly regular_trigger_effect_frequency: uint - readonly movement_modifier_when_on_ground: float - readonly movement_modifier: float - readonly mining_particle_frame_speed: float - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaParticlePrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A permission group that defines what players in this group are allowed to do. - * - * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html View documentation} - * - * @noSelf - */ -interface LuaPermissionGroup { - /** - * Adds the given player to this group. - * - * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html#LuaPermissionGroup.add_player View documentation} - * - * @param player - * @returns If the player was added. - */ - add_player(player: PlayerIdentification): boolean - /** - * Removes the given player from this group. - * - * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html#LuaPermissionGroup.remove_player View documentation} - * - * @param player - * @returns If the player was removed. - */ - remove_player(player: PlayerIdentification): boolean - /** - * Whether this group allows the given action. - * - * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html#LuaPermissionGroup.allows_action View documentation} - * - * @param action - The action in question. - */ - allows_action(action: defines.input_action): boolean - /** - * Sets whether this group allows the performance the given action. - * - * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html#LuaPermissionGroup.set_allows_action View documentation} - * - * @param action - The action in question. - * @param allow_action - Whether to allow the specified action. - * @returns Whether the value was successfully applied. - */ - set_allows_action(action: defines.input_action, allow_action: boolean): boolean - /** - * Destroys this group. - * - * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html#LuaPermissionGroup.destroy View documentation} - * - * @returns Whether the group was successfully destroyed. - */ - destroy(): boolean - /** - * The name of this group. - * - * **Note**: Setting the name to `nil` or an empty string sets the name to the default value. - * - * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html#LuaPermissionGroup.name View documentation} - */ - name: string - /** - * The players in this group. - * - * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html#LuaPermissionGroup.players View documentation} - */ - readonly players: LuaPlayer[] - /** - * The group ID - * - * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html#LuaPermissionGroup.group_id View documentation} - */ - readonly group_id: uint - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaPermissionGroup" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * All permission groups. - * - * {@link https://lua-api.factorio.com/next/LuaPermissionGroups.html View documentation} - * - * @noSelf - */ -interface LuaPermissionGroups { - /** - * Creates a new permission group. - * - * **Note**: May return nil if the calling player doesn't have permission to make groups. - * - * {@link https://lua-api.factorio.com/next/LuaPermissionGroups.html#LuaPermissionGroups.create_group View documentation} - * - * @param name - */ - create_group(name?: string): LuaPermissionGroup | undefined - /** - * Gets the permission group with the given name or group ID or `nil` if there is no matching group. - * - * {@link https://lua-api.factorio.com/next/LuaPermissionGroups.html#LuaPermissionGroups.get_group View documentation} - * - * @param group - */ - get_group(group: string | uint): LuaPermissionGroup | undefined - /** - * All of the permission groups. - * - * {@link https://lua-api.factorio.com/next/LuaPermissionGroups.html#LuaPermissionGroups.groups View documentation} - */ - readonly groups: LuaPermissionGroup[] - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaPermissionGroups" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A player in the game. Pay attention that a player may or may not have a character, which is the {@link LuaEntity} of - * the little guy running around the world doing things. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html View documentation} - * - * @noSelf - */ -interface LuaPlayer extends LuaControl { - /** - * Setup the screen to be shown when the game is finished. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.set_ending_screen_data View documentation} - * - * @param message - Message to be shown. - * @param file - Path to image to be shown. - */ - set_ending_screen_data(message: LocalisedString, file?: string): void - /** - * Print text to the chat console. - * - * **Note**: Messages that are identical to a message sent in the last 60 ticks are not printed again. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.print View documentation} - * - * @param message - * @param color - */ - print(message: LocalisedString, color?: Color): void - /** - * Clear the chat console. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.clear_console View documentation} - */ - clear_console(): void - /** - * Get the current goal description, as a localised string. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.get_goal_description View documentation} - */ - get_goal_description(): LocalisedString - /** - * Set the text in the goal window (top left). - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.set_goal_description View documentation} - * - * @param text - The text to display. Lines can be delimited with `\n`. Passing an empty string or omitting this - * parameter entirely will make the goal window disappear. - * @param only_update - When `true`, won't play the "goal updated" sound. - */ - set_goal_description(text?: LocalisedString, only_update?: boolean): void - /** - * Set the controller type of the player. - * - * **Note**: Setting a player to {@link defines.controllers.editor} auto promotes the player to admin and enables cheat mode. - * - * **Note**: Setting a player to {@link defines.controllers.editor} also requires the calling player be an admin. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.set_controller View documentation} - */ - set_controller(params: { - /** Which controller to use. */ - readonly type: defines.controllers - /** Entity to control. Mandatory when `type` is {@link defines.controllers.character}, ignored otherwise. */ - readonly character?: LuaEntity - /** - * List of waypoints for the cutscene controller. This parameter is mandatory when `type` is - * {@link defines.controllers.cutscene}. - */ - readonly waypoints?: CutsceneWaypoint - /** - * If specified and `type` is {@link defines.controllers.cutscene}, the cutscene will start at this position. If - * not given the start position will be the player position. - */ - readonly start_position?: Position - /** - * If specified and `type` is {@link defines.controllers.cutscene}, the cutscene will start at this zoom level. - * If not given the start zoom will be the players zoom. - */ - readonly start_zoom?: double - /** - * If specified and `type` is {@link defines.controllers.cutscene}, it is the time in ticks it will take for the - * camera to pan from the final waypoint back to the starting position. If not given the camera will not pan - * back to the start position/zoom. - */ - readonly final_transition_time?: uint - /** - * If specified and `type` is {@link defines.controllers.cutscene}, the game will switch to chart-mode (map - * zoomed out) rendering when the zoom level is less than this value. - */ - readonly chart_mode_cutoff?: double - }): void - /** - * Start/end wire dragging at the specified location, wire type is based on the cursor contents - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.drag_wire View documentation} - * - * @returns `true` if the action did something - */ - drag_wire(params: { - /** - * Position at which cursor was clicked. Used only to decide which side of arithmetic combinator, decider - * combinator or power switch is to be connected. Entity itself to be connected is based on the player's selected entity. - */ - readonly position: Position - }): boolean - /** - * Disable recipe groups. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.disable_recipe_groups View documentation} - */ - disable_recipe_groups(): void - /** - * Enable recipe groups. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.enable_recipe_groups View documentation} - */ - enable_recipe_groups(): void - /** - * Disable recipe subgroups. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.disable_recipe_subgroups View documentation} - */ - disable_recipe_subgroups(): void - /** - * Enable recipe subgroups. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.enable_recipe_subgroups View documentation} - */ - enable_recipe_subgroups(): void - /** - * Print entity statistics to the player's console. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.print_entity_statistics View documentation} - * - * @param entities - Entity prototypes to get statistics for. If not specified or empty, display statistics for all entities. - */ - print_entity_statistics(entities?: string[]): void - /** - * Print construction robot job counts to the players console. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.print_robot_jobs View documentation} - */ - print_robot_jobs(): void - /** - * Print LuaObject counts per mod. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.print_lua_object_statistics View documentation} - */ - print_lua_object_statistics(): void - /** - * Logs a dictionary of chunks -> active entities for the surface this player is on. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.log_active_entity_chunk_counts View documentation} - */ - log_active_entity_chunk_counts(): void - /** - * Logs a dictionary of active entities -> count for the surface this player is on. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.log_active_entity_counts View documentation} - */ - log_active_entity_counts(): void - /** - * Unlock the achievements of the given player. This has any effect only when this is the local player, the - * achievement isn't unlocked so far and the achievement is of the type "achievement". - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.unlock_achievement View documentation} - * - * @param name - Name of the achievement to unlock - */ - unlock_achievement(name: string): void - /** - * Invokes the "clear cursor" action on the player as if the user pressed it. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.clear_cursor View documentation} - * - * @returns If the cursor is now empty. - */ - clear_cursor(): boolean - /** - * Creates and attaches a character entity to this player. - * - * **Note**: The player must not have a character already connected and must be online (see - * {@link LuaPlayer.connected LuaPlayer::connected}). - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.create_character View documentation} - * - * @param character - The character to create else the default is used. - * @returns Whether the character was created. - */ - create_character(character?: string): boolean - /** - * Adds an alert to this player for the given entity of the given alert type. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.add_alert View documentation} - * - * @param entity - * @param type - */ - add_alert(entity: LuaEntity, type: defines.alert_type): void - /** - * Adds a custom alert to this player. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.add_custom_alert View documentation} - * - * @param entity - If the alert is clicked, the map will open at the position of this entity. - * @param icon - * @param message - * @param show_on_map - */ - add_custom_alert(entity: LuaEntity, icon: SignalID, message: LocalisedString, show_on_map: boolean): void - /** - * Removes all alerts matching the given filters or if an empty filters table is given all alerts are removed. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.remove_alert View documentation} - */ - remove_alert(params: { - readonly entity?: LuaEntity - readonly prototype?: LuaEntityPrototype - readonly position?: Position - readonly type?: defines.alert_type - readonly surface?: SurfaceIdentification - readonly icon?: SignalID - readonly message?: LocalisedString - }): void - /** - * Get all alerts matching the given filters, or all alerts if no filters are given. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.get_alerts View documentation} - * - * @returns A mapping of surface index to an array of arrays of {@link Alert alerts} indexed by the - * {@link defines.alert_type alert type}. - */ - get_alerts(params: { - readonly entity?: LuaEntity - readonly prototype?: LuaEntityPrototype - readonly position?: Position - readonly type?: defines.alert_type - readonly surface?: SurfaceIdentification - }): Record> - /** - * Mutes alerts for the given alert category. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.mute_alert View documentation} - * - * @param alert_type - * @returns If the alert type was muted (false if it was already muted). - */ - mute_alert(alert_type: defines.alert_type): boolean - /** - * Unmutes alerts for the given alert category. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.unmute_alert View documentation} - * - * @param alert_type - * @returns If the alert type was unmuted (false if it was wasn't muted). - */ - unmute_alert(alert_type: defines.alert_type): boolean - /** - * If the given alert type is currently muted. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.is_alert_muted View documentation} - * - * @param alert_type - */ - is_alert_muted(alert_type: defines.alert_type): boolean - /** - * Enables alerts for the given alert category. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.enable_alert View documentation} - * - * @param alert_type - * @returns If the alert type was enabled (false if it was already enabled). - */ - enable_alert(alert_type: defines.alert_type): boolean - /** - * Disables alerts for the given alert category. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.disable_alert View documentation} - * - * @param alert_type - * @returns If the alert type was disabled (false if it was already disabled). - */ - disable_alert(alert_type: defines.alert_type): boolean - /** - * If the given alert type is currently enabled. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.is_alert_enabled View documentation} - * - * @param alert_type - */ - is_alert_enabled(alert_type: defines.alert_type): boolean - /** - * Invokes the "smart pipette" action on the player as if the user pressed it. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.pipette_entity View documentation} - * - * @param entity - * @returns If the smart pipette found something to place - */ - pipette_entity(entity: string | LuaEntity | LuaEntityPrototype): boolean - /** - * Checks if this player can build the give entity at the given location on the surface the player is on. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.can_place_entity View documentation} - */ - can_place_entity(params: { - /** Name of the entity to check */ - readonly name: string - /** Where the entity would be placed */ - readonly position: Position - /** Direction the entity would be placed */ - readonly direction?: defines.direction - }): boolean - /** - * Checks if this player can build what ever is in the cursor on the surface the player is on. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.can_build_from_cursor View documentation} - */ - can_build_from_cursor(params: { - /** Where the entity would be placed */ - readonly position: Position - /** Direction the entity would be placed */ - readonly direction?: defines.direction - /** If alt build should be used instead of normal build. Defaults to normal. */ - readonly alt?: boolean - /** The size for building terrain if building terrain. Defaults to 2. */ - readonly terrain_building_size?: uint - /** If chunks covered by fog-of-war are skipped. */ - readonly skip_fog_of_war?: boolean - }): boolean - /** - * Builds what ever is in the cursor on the surface the player is on. - * - * **Note**: Anything built will fire normal player-built events. - * - * **Note**: The cursor stack will automatically be reduced as if the player built normally. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.build_from_cursor View documentation} - */ - build_from_cursor(params: { - /** Where the entity would be placed */ - readonly position: Position - /** Direction the entity would be placed */ - readonly direction?: defines.direction - /** If alt build should be used instead of normal build. Defaults to normal. */ - readonly alt?: boolean - /** The size for building terrain if building terrain. Defaults to 2. */ - readonly terrain_building_size?: uint - /** If chunks covered by fog-of-war are skipped. */ - readonly skip_fog_of_war?: boolean - }): void - /** - * Uses the current item in the cursor if it's a capsule or does nothing if not. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.use_from_cursor View documentation} - * - * @param position - Where the item would be used. - */ - use_from_cursor(position: Position): void - /** - * Play a sound for this player. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.play_sound View documentation} - */ - play_sound(params: { - /** The sound to play. */ - readonly path: SoundPath - /** Where the sound should be played. If not given, it's played at the current position of the player. */ - readonly position?: Position - /** The volume of the sound to play. Must be between 0 and 1 inclusive. */ - readonly volume_modifier?: double - /** The volume mixer to play the sound through. Defaults to the default mixer for the given sound type. */ - readonly override_sound_type?: SoundType - }): void - /** - * The characters associated with this player. - * - * **Note**: The array will always be empty when the player is disconnected (see - * {@link LuaPlayer.connected LuaPlayer::connected}) regardless of there being associated characters. - * - * **Note**: Characters associated with this player will be logged off when this player disconnects but are not - * controlled by any player. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.get_associated_characters View documentation} - */ - get_associated_characters(): LuaEntity[] - /** - * Associates a character with this player. - * - * **Note**: The character must not be connected to any controller. - * - * **Note**: If this player is currently disconnected (see {@link LuaPlayer.connected LuaPlayer::connected}) the - * character will be immediately "logged off". - * - * **Note**: See {@link LuaPlayer.get_associated_characters LuaPlayer::get_associated_characters} for more information. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.associate_character View documentation} - * - * @param character - The character entity. - */ - associate_character(character: LuaEntity): void - /** - * Disassociates a character from this player. This is functionally the same as setting - * {@link LuaEntity.associated_player LuaEntity::associated_player} to `nil`. - * - * **Note**: See {@link LuaPlayer.get_associated_characters LuaPlayer::get_associated_characters} for more information. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.disassociate_character View documentation} - * - * @param character - The character entity - */ - disassociate_character(character: LuaEntity): void - /** - * Spawn flying text that is only visible to this player. Either `position` or `create_at_cursor` are required. When - * `create_at_cursor` is `true`, all parameters other than `text` are ignored. - * - * **Note**: If no custom `speed` is set and the text is longer than 25 characters, its `time_to_live` and `speed` - * are dynamically adjusted to give players more time to read it. - * - * **Note**: Local flying text is not saved, which means it will disappear after a save/load-cycle. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.create_local_flying_text View documentation} - */ - create_local_flying_text(params: { - /** The flying text to show. */ - readonly text: LocalisedString - /** The location on the map at which to show the flying text. */ - readonly position?: Position - /** If `true`, the flying text is created at the player's cursor. Defaults to `false`. */ - readonly create_at_cursor?: boolean - /** The color of the flying text. Defaults to white text. */ - readonly color?: Color - /** The amount of ticks that the flying text will be shown for. Defaults to `80`. */ - readonly time_to_live?: uint - /** The speed at which the text rises upwards in tiles/second. Can't be a negative value. */ - readonly speed?: double - }): void - /** - * Gets the quick bar filter for the given slot or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.get_quick_bar_slot View documentation} - * - * @param index - The slot index. 1 for the first slot of page one, 2 for slot two of page one, 11 for the first - * slot of page 2, etc. - */ - get_quick_bar_slot(index: uint): LuaItemPrototype | undefined - /** - * Sets the quick bar filter for the given slot. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.set_quick_bar_slot View documentation} - * - * @param index - The slot index. 1 for the first slot of page one, 2 for slot two of page one, 11 for the first - * slot of page 2, etc. - * @param filter - The filter or `nil`. - */ - set_quick_bar_slot(index: uint, filter: string | LuaItemPrototype | LuaItemStack | undefined): void - /** - * Gets which quick bar page is being used for the given screen page or `nil` if not known. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.get_active_quick_bar_page View documentation} - * - * @param index - The screen page. Index 1 is the top row in the gui. Index can go beyond the visible number of bars - * on the screen to account for the interface config setting change. - */ - get_active_quick_bar_page(index: uint): uint8 | undefined - /** - * Sets which quick bar page is being used for the given screen page. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.set_active_quick_bar_page View documentation} - * - * @param screen_index - The screen page. Index 1 is the top row in the gui. Index can go beyond the visible number - * of bars on the screen to account for the interface config setting change. - * @param page_index - The new quick bar page. - */ - set_active_quick_bar_page(screen_index: uint, page_index: uint): void - /** - * Jump to the specified cutscene waypoint. Only works when the player is viewing a cutscene. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.jump_to_cutscene_waypoint View documentation} - * - * @param waypoint_index - */ - jump_to_cutscene_waypoint(waypoint_index: uint): void - /** - * Exit the current cutscene. Errors if not in a cutscene. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.exit_cutscene View documentation} - */ - exit_cutscene(): void - /** - * Queues a request to open the map at the specified position. If the map is already opened, the request will simply - * set the position (and scale). Render mode change requests are processed before rendering of the next frame. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.open_map View documentation} - * - * @param position - * @param scale - */ - open_map(position: Position, scale?: double): void - /** - * Queues a request to zoom to world at the specified position. If the player is already zooming to world, the - * request will simply set the position (and scale). Render mode change requests are processed before rendering of - * the next frame. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.zoom_to_world View documentation} - * - * @param position - * @param scale - */ - zoom_to_world(position: Position, scale?: double): void - /** - * Queues request to switch to the normal game view from the map or zoom to world view. Render mode change requests - * are processed before rendering of the next frame. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.close_map View documentation} - */ - close_map(): void - /** - * Is a custom Lua shortcut currently toggled? - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.is_shortcut_toggled View documentation} - * - * @param prototype_name - Prototype name of the custom shortcut. - */ - is_shortcut_toggled(prototype_name: string): boolean - /** - * Is a custom Lua shortcut currently available? - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.is_shortcut_available View documentation} - * - * @param prototype_name - Prototype name of the custom shortcut. - */ - is_shortcut_available(prototype_name: string): boolean - /** - * Toggle or untoggle a custom Lua shortcut - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.set_shortcut_toggled View documentation} - * - * @param prototype_name - Prototype name of the custom shortcut. - * @param toggled - */ - set_shortcut_toggled(prototype_name: string, toggled: boolean): void - /** - * Make a custom Lua shortcut available or unavailable. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.set_shortcut_available View documentation} - * - * @param prototype_name - Prototype name of the custom shortcut. - * @param available - */ - set_shortcut_available(prototype_name: string, available: boolean): void - /** - * Asks the player if they would like to connect to the given server. - * - * **Note**: This only does anything when used on a multiplayer peer. Single player and server hosts will ignore the prompt. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.connect_to_server View documentation} - */ - connect_to_server(params: { - /** The server (address:port) if port is not given the default Factorio port is used. */ - readonly address: string - /** The name of the server. */ - readonly name?: LocalisedString - readonly description?: LocalisedString - /** - * The password if different from the one used to join this game. Note, if the current password is not empty but - * the one required to join the new server is an empty string should be given for this field. - */ - readonly password?: string - }): void - /** - * Toggles this player into or out of the map editor. Does nothing if this player isn't an admin or if the player - * doesn't have permission to use the map editor. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.toggle_map_editor View documentation} - */ - toggle_map_editor(): void - /** - * Requests a translation for the given localised string. If the request is successful the - * {@link OnStringTranslatedEvent on_string_translated} event will be fired at a later time with the results. - * - * **Note**: Does nothing if this player is not connected. (see {@link LuaPlayer.connected LuaPlayer::connected}). - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.request_translation View documentation} - * - * @param localised_string - * @returns If the request was sent or not. - */ - request_translation(localised_string: LocalisedString): boolean - /** - * Gets the filter for this map editor infinity filters at the given index or `nil` if the filter index doesn't - * exist or is empty. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.get_infinity_inventory_filter View documentation} - * - * @param index - The index to get. - */ - get_infinity_inventory_filter(index: uint): InfinityInventoryFilter | undefined - /** - * Sets the filter for this map editor infinity filters at the given index. - * - * *Can only be used if this is InfinityContainer* - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.set_infinity_inventory_filter View documentation} - * - * @param index - The index to set. - * @param filter - The new filter or `nil` to clear the filter. - */ - set_infinity_inventory_filter(index: uint, filter: InfinityInventoryFilter | undefined): void - /** - * Clears all recipe notifications for this player. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.clear_recipe_notifications View documentation} - */ - clear_recipe_notifications(): void - /** - * Adds the given recipe to the list of recipe notifications for this player. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.add_recipe_notification View documentation} - * - * @param recipe - Name of the recipe prototype to add. - */ - add_recipe_notification(recipe: string): void - /** - * Adds the given blueprint to this player's clipboard queue. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.add_to_clipboard View documentation} - * - * @param blueprint - The blueprint to add. - */ - add_to_clipboard(blueprint: LuaItemStack): void - /** - * Gets a copy of the currently selected blueprint in the clipboard queue into the player's cursor, as if the player - * activated Paste. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.activate_paste View documentation} - */ - activate_paste(): void - /** - * Starts selection with selection tool from the specified position. Does nothing if the players cursor is not a - * selection tool. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.start_selection View documentation} - * - * @param position - The position to start selection from. - * @param selection_mode - The type of selection to start. Can be `select`, `alternative-select`, `reverse-select`. - */ - start_selection(position: Position, selection_mode: string): void - /** - * Clears the players selection tool selection position. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.clear_selection View documentation} - */ - clear_selection(): void - /** - * The character attached to this player, or `nil` if no character. - * - * **Note**: Will also return `nil` when the player is disconnected (see {@link LuaPlayer.connected LuaPlayer::connected}). - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.character View documentation} - */ - character: LuaEntity | undefined - /** - * When in a cutscene; the character this player would be using once the cutscene is over. - * - * **Note**: Will also return `nil` when the player is disconnected (see {@link LuaPlayer.connected LuaPlayer::connected}). - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.cutscene_character View documentation} - */ - readonly cutscene_character: LuaEntity | undefined - /** - * This player's index in {@link LuaGameScript.players LuaGameScript::players}. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.index View documentation} - */ - readonly index: uint - readonly gui: LuaGui - /** - * `true` if the player opened itself. I.e. if they opened the character or god-controller GUI. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.opened_self View documentation} - */ - readonly opened_self: boolean - readonly controller_type: defines.controllers - /** - * The stashed controller type or `nil` if no controller is stashed. - * - * **Note**: This is mainly useful when a player is in the map editor. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.stashed_controller_type View documentation} - */ - readonly stashed_controller_type: defines.controllers | undefined - /** - * The player's game view settings. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.game_view_settings View documentation} - */ - game_view_settings: GameViewSettings - /** - * `true` if the minimap is visible. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.minimap_enabled View documentation} - */ - minimap_enabled: boolean - /** - * The color associated with the player. This will be used to tint the player's character as well as their buildings - * and vehicles. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.color View documentation} - */ - color: Color - /** - * The color used when this player talks in game. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.chat_color View documentation} - */ - chat_color: Color - /** - * The player's username. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.name View documentation} - */ - readonly name: string - /** - * The tag that is shown after the player in chat and on the map. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.tag View documentation} - */ - tag: string - /** - * `true` if the player is currently connected to the game. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.connected View documentation} - */ - readonly connected: boolean - /** - * `true` if the player is an admin. - * - * **Note**: Trying to change player admin status from the console when you aren't an admin does nothing. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.admin View documentation} - */ - admin: boolean - /** - * The source entity used during entity settings copy-paste if any. - * - * `nil` if there isn't currently a source entity. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.entity_copy_source View documentation} - */ - readonly entity_copy_source: LuaEntity | undefined - /** - * How many ticks since the last action of this player - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.afk_time View documentation} - */ - readonly afk_time: uint - /** - * How many ticks did this player spend playing this save (all sessions combined) - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.online_time View documentation} - */ - readonly online_time: uint - /** - * At what tick this player was last online. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.last_online View documentation} - */ - readonly last_online: uint - /** - * The permission group this player is part of or `nil` if not part of any group. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.permission_group View documentation} - */ - permission_group: LuaPermissionGroup | undefined - /** - * Gets the current per-player settings for the this player, indexed by prototype name. Returns the same structure - * as {@link LuaSettings.get_player_settings LuaSettings::get_player_settings}. - * - * **Note**: This can become invalid if during operation this player becomes invalid. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.mod_settings View documentation} - */ - readonly mod_settings: LuaCustomTable - /** - * The number of ticks until this player will respawn or `nil` if not waiting to respawn. - * - * **Note**: Set to `nil` to immediately respawn the player. - * - * **Note**: Set to any positive value to trigger the respawn state for this player. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.ticks_to_respawn View documentation} - */ - ticks_to_respawn: uint | undefined - /** - * The display resolution for this player. - * - * **Note**: During {@link OnPlayerCreatedEvent on_player_created}, this attribute will always return a resolution of - * `{width=1920, height=1080}`. To get the actual resolution, listen to the - * {@link OnPlayerDisplayResolutionChangedEvent on_player_display_resolution_changed} event raised shortly afterwards. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.display_resolution View documentation} - */ - readonly display_resolution: DisplayResolution - /** - * The display scale for this player. - * - * **Note**: During {@link OnPlayerCreatedEvent on_player_created}, this attribute will always return a scale of `1`. - * To get the actual scale, listen to the {@link OnPlayerDisplayScaleChangedEvent on_player_display_scale_changed} - * event raised shortly afterwards. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.display_scale View documentation} - */ - readonly display_scale: double - /** - * The item stack containing a blueprint to be setup. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.blueprint_to_setup View documentation} - */ - readonly blueprint_to_setup: LuaItemStack - /** - * The render mode of the player, like map or zoom to world. The render mode can be set using - * {@link LuaPlayer.open_map LuaPlayer::open_map}, {@link LuaPlayer.zoom_to_world LuaPlayer::zoom_to_world} and - * {@link LuaPlayer.close_map LuaPlayer::close_map}. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.render_mode View documentation} - */ - readonly render_mode: defines.render_mode - /** - * If `true`, zoom-to-world noise effect will be disabled and environmental sounds will be based on zoom-to-world - * view instead of position of player's character. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.spectator View documentation} - */ - spectator: boolean - /** - * If items not included in this map editor infinity inventory filters should be removed. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.remove_unfiltered_items View documentation} - */ - remove_unfiltered_items: boolean - /** - * The filters for this map editor infinity inventory settings. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.infinity_inventory_filters View documentation} - */ - infinity_inventory_filters: InfinityInventoryFilter[] - /** - * If the main inventory will be auto sorted. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.auto_sort_main_inventory View documentation} - */ - readonly auto_sort_main_inventory: boolean - /** - * The original location of the item in the cursor, marked with a hand. When writing, the specified inventory slot - * must be empty and the cursor stack must not be empty. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.hand_location View documentation} - */ - hand_location: ItemStackLocation - /** - * The player's zoom-level. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.zoom View documentation} - */ - set zoom(value: double) - /** - * The player's map view settings. To write to this, use a table containing the fields that should be changed. - * - * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.map_view_settings View documentation} - */ - set map_view_settings(value: MapViewSettings) - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaPlayer" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * An object used to measure script performance. - * - * **Note**: Since performance is non-deterministic these objects don't allow reading the raw time values from lua. They - * can be used anywhere a {@link LocalisedString} is used. - * - * {@link https://lua-api.factorio.com/next/LuaProfiler.html View documentation} - * - * @noSelf - */ -interface LuaProfiler { - /** - * Resets the clock, also restarting it. - * - * {@link https://lua-api.factorio.com/next/LuaProfiler.html#LuaProfiler.reset View documentation} - */ - reset(): void - /** - * Stops the clock. - * - * {@link https://lua-api.factorio.com/next/LuaProfiler.html#LuaProfiler.stop View documentation} - */ - stop(): void - /** - * Start the clock again, without resetting it. - * - * {@link https://lua-api.factorio.com/next/LuaProfiler.html#LuaProfiler.restart View documentation} - */ - restart(): void - /** - * Add the duration of another timer to this timer. Useful to reduce start/stop overhead when accumulating time onto - * many timers at once. - * - * **Note**: If other is running, the time to now will be added. - * - * {@link https://lua-api.factorio.com/next/LuaProfiler.html#LuaProfiler.add View documentation} - * - * @param other - The timer to add to this timer. - */ - add(other: LuaProfiler): void - /** - * Divides the current duration by a set value. Useful for calculating the average of many iterations. - * - * **Note**: Does nothing if this isn't stopped. - * - * {@link https://lua-api.factorio.com/next/LuaProfiler.html#LuaProfiler.divide View documentation} - * - * @param number - The number to divide by. Must be > 0. - */ - divide(number: double): void - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaProfiler" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Control behavior for programmable speakers. - * - * {@link https://lua-api.factorio.com/next/LuaProgrammableSpeakerControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaProgrammableSpeakerControlBehavior extends LuaControlBehavior { - circuit_parameters: ProgrammableSpeakerCircuitParameters - circuit_condition: CircuitConditionDefinition - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaProgrammableSpeakerControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * An interface to send messages to the calling RCON interface. - * - * {@link https://lua-api.factorio.com/next/LuaRCON.html View documentation} - * - * @noSelf - */ -interface LuaRCON { - /** - * Print text to the calling RCON interface if any. - * - * {@link https://lua-api.factorio.com/next/LuaRCON.html#LuaRCON.print View documentation} - * - * @param message - */ - print(message: LocalisedString): void - /** This object's name. */ - readonly object_name: "LuaRCON" -} - -/** - * Control behavior for rail chain signals. - * - * {@link https://lua-api.factorio.com/next/LuaRailChainSignalControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaRailChainSignalControlBehavior extends LuaControlBehavior { - red_signal: SignalID - orange_signal: SignalID - green_signal: SignalID - blue_signal: SignalID - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaRailChainSignalControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A rail path. - * - * {@link https://lua-api.factorio.com/next/LuaRailPath.html View documentation} - * - * @noSelf - */ -interface LuaRailPath { - /** - * The total number of rails in this path. - * - * {@link https://lua-api.factorio.com/next/LuaRailPath.html#LuaRailPath.size View documentation} - */ - readonly size: uint - /** - * The current rail index. - * - * {@link https://lua-api.factorio.com/next/LuaRailPath.html#LuaRailPath.current View documentation} - */ - readonly current: uint - /** - * The total path distance. - * - * {@link https://lua-api.factorio.com/next/LuaRailPath.html#LuaRailPath.total_distance View documentation} - */ - readonly total_distance: double - /** - * The total distance travelled. - * - * {@link https://lua-api.factorio.com/next/LuaRailPath.html#LuaRailPath.travelled_distance View documentation} - */ - readonly travelled_distance: double - /** - * Array of the rails that this path travels over. - * - * {@link https://lua-api.factorio.com/next/LuaRailPath.html#LuaRailPath.rails View documentation} - */ - readonly rails: LuaCustomTable - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaRailPath" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Control behavior for rail signals. - * - * {@link https://lua-api.factorio.com/next/LuaRailSignalControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaRailSignalControlBehavior extends LuaControlBehavior { - red_signal: SignalID - orange_signal: SignalID - green_signal: SignalID - /** - * If this will close the rail signal based off the circuit condition. - * - * {@link https://lua-api.factorio.com/next/LuaRailSignalControlBehavior.html#LuaRailSignalControlBehavior.close_signal View documentation} - */ - close_signal: boolean - /** - * If this will read the rail signal state. - * - * {@link https://lua-api.factorio.com/next/LuaRailSignalControlBehavior.html#LuaRailSignalControlBehavior.read_signal View documentation} - */ - read_signal: boolean - /** - * The circuit condition when controlling the signal through the circuit network. - * - * {@link https://lua-api.factorio.com/next/LuaRailSignalControlBehavior.html#LuaRailSignalControlBehavior.circuit_condition View documentation} - */ - circuit_condition: CircuitConditionDefinition - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaRailSignalControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A deterministic random generator independent from the core games random generator that can be seeded and re-seeded at - * will. This random generator can be saved and loaded and will maintain its state. Note this is entirely different from - * calling {@link https://lua-api.factorio.com/next/Libraries.html#math.random math.random}() and you should be sure you - * actually want to use this over calling `math.random()`. If you aren't sure if you need to use this over calling - * `math.random()` then you probably don't need to use this. - * - * {@link https://lua-api.factorio.com/next/LuaRandomGenerator.html View documentation} - * - * @example - * Create a generator and use it to print a random number. - * - * ```lua - * global.generator = game.create_random_generator() - * game.player.print(global.generator()) - * ``` - * - * @noSelf - */ -interface LuaRandomGenerator { - /** - * Re-seeds the random generator with the given value. - * - * **Note**: Seeds that are close together will produce similar results. Seeds from 0 to 341 will produce the same results. - * - * {@link https://lua-api.factorio.com/next/LuaRandomGenerator.html#LuaRandomGenerator.re_seed View documentation} - * - * @param seed - */ - re_seed(seed: uint): void - /** - * Generates a random number. If no parameters are given a number in the [0, 1) range is returned. If a single - * parameter is given a floored number in the [1, N] range is returned. If 2 parameters are given a floored number - * in the [N1, N2] range is returned. - * - * {@link https://lua-api.factorio.com/next/LuaRandomGenerator.html#LuaRandomGenerator.operator%20() View documentation} - * - * @param lower - Inclusive lower bound on the result - * @param upper - Inclusive upper bound on the result - */ - (lower?: int, upper?: int): double - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaRandomGenerator" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A crafting recipe. Recipes belong to forces (see {@link LuaForce}) because some recipes are unlocked by research, and - * researches are per-force. - * - * {@link https://lua-api.factorio.com/next/LuaRecipe.html View documentation} - * - * @noSelf - */ -interface LuaRecipe { - /** - * Reload the recipe from the prototype. - * - * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.reload View documentation} - */ - reload(): void - /** - * Name of the recipe. This can be different than the name of the result items as there could be more recipes to - * make the same item. - * - * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.name View documentation} - */ - readonly name: string - /** - * Localised name of the recipe. - * - * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.localised_name View documentation} - */ - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * The prototype for this recipe. - * - * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.prototype View documentation} - */ - readonly prototype: LuaRecipePrototype - /** - * Can the recipe be used? - * - * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.enabled View documentation} - */ - enabled: boolean - /** - * Category of the recipe. - * - * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.category View documentation} - */ - readonly category: string - /** - * Ingredients for this recipe. - * - * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.ingredients View documentation} - * - * @example - * What the "steel-chest" recipe would return - * - * ```lua - * {{type="item", name="steel-plate", amount=8}} - * ``` - * - * @example - * What the "advanced-oil-processing" recipe would return - * - * ```lua - * {{type="fluid", name="crude-oil", amount=10}, {type="fluid", name="water", amount=5}} - * ``` - */ - readonly ingredients: Ingredient[] - /** - * The results of this recipe. - * - * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.products View documentation} - */ - readonly products: Product[] - /** - * Is the recipe hidden? Hidden recipe don't show up in the crafting menu. - * - * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.hidden View documentation} - */ - readonly hidden: boolean - /** - * Is the recipe hidden from flow statistics? - * - * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.hidden_from_flow_stats View documentation} - */ - hidden_from_flow_stats: boolean - /** - * Energy required to execute this recipe. This directly affects the crafting time: Recipe's energy is exactly its - * crafting time in seconds, when crafted in an assembling machine with crafting speed exactly equal to one. - * - * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.energy View documentation} - */ - readonly energy: double - /** - * Order string. This is used to sort the crafting menu. - * - * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.order View documentation} - */ - readonly order: string - /** - * Group of this recipe. - * - * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.group View documentation} - */ - readonly group: LuaGroup - /** - * Subgroup of this recipe. - * - * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.subgroup View documentation} - */ - readonly subgroup: LuaGroup - /** - * The force that owns this recipe. - * - * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.force View documentation} - */ - readonly force: LuaForce - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaRecipe" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a recipe category. - * - * {@link https://lua-api.factorio.com/next/LuaRecipeCategoryPrototype.html View documentation} - * - * @noSelf - */ -interface LuaRecipeCategoryPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaRecipeCategoryPrototype.html#LuaRecipeCategoryPrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaRecipeCategoryPrototype.html#LuaRecipeCategoryPrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaRecipeCategoryPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A crafting recipe prototype. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html View documentation} - * - * @noSelf - */ -interface LuaRecipePrototype { - /** - * If this recipe prototype is enabled by default (enabled at the beginning of a game). - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.enabled View documentation} - */ - readonly enabled: boolean - /** - * Name of the recipe. This can be different than the name of the result items as there could be more recipes to - * make the same item. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.name View documentation} - */ - readonly name: string - /** - * Localised name of the recipe. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.localised_name View documentation} - */ - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * Category of the recipe. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.category View documentation} - */ - readonly category: string - /** - * Ingredients for this recipe. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.ingredients View documentation} - */ - readonly ingredients: Ingredient[] - /** - * The results of this recipe. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.products View documentation} - */ - readonly products: Product[] - /** - * The main product of this recipe, `nil` if no main product is defined. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.main_product View documentation} - */ - readonly main_product: Product | undefined - /** - * Is the recipe hidden? Hidden recipe don't show up in the crafting menu. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.hidden View documentation} - */ - readonly hidden: boolean - /** - * Is the recipe hidden from flow statistics (item/fluid production statistics)? - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.hidden_from_flow_stats View documentation} - */ - readonly hidden_from_flow_stats: boolean - /** - * Is the recipe hidden from player crafting? The recipe will still show up for selection in machines. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.hidden_from_player_crafting View documentation} - */ - readonly hidden_from_player_crafting: boolean - /** - * Should this recipe always show "Made in" in the tooltip? - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.always_show_made_in View documentation} - */ - readonly always_show_made_in: boolean - /** - * Energy required to execute this recipe. This directly affects the crafting time: Recipe's energy is exactly its - * crafting time in seconds, when crafted in an assembling machine with crafting speed exactly equal to one. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.energy View documentation} - */ - readonly energy: double - /** - * Order string. This is used to sort the crafting menu. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.order View documentation} - */ - readonly order: string - /** - * Group of this recipe. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.group View documentation} - */ - readonly group: LuaGroup - /** - * Subgroup of this recipe. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.subgroup View documentation} - */ - readonly subgroup: LuaGroup - /** - * The multiplier used when this recipe is copied from an assembling machine to a requester chest. For each item in - * the recipe the item count * this value is set in the requester chest. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.request_paste_multiplier View documentation} - */ - readonly request_paste_multiplier: uint - /** - * Used to determine how many extra items are put into an assembling machine before it's considered "full enough". - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.overload_multiplier View documentation} - */ - readonly overload_multiplier: uint - /** - * If the recipe is allowed to have the extra inserter overload bonus applied (4 * stack inserter stack size). - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.allow_inserter_overload View documentation} - */ - readonly allow_inserter_overload: boolean - /** - * If this recipe is enabled for the purpose of intermediate hand-crafting. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.allow_as_intermediate View documentation} - */ - readonly allow_as_intermediate: boolean - /** - * If this recipe is allowed to use intermediate recipes when hand-crafting. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.allow_intermediates View documentation} - */ - readonly allow_intermediates: boolean - /** - * If the amount is shown in the recipe tooltip title when the recipe produces more than 1 product. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.show_amount_in_title View documentation} - */ - readonly show_amount_in_title: boolean - /** - * If the products are always shown in the recipe tooltip. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.always_show_products View documentation} - */ - readonly always_show_products: boolean - /** - * The emissions multiplier for this recipe. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.emissions_multiplier View documentation} - */ - readonly emissions_multiplier: double - /** - * Is this recipe allowed to be broken down for the recipe tooltip "Total raw" calculations? - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.allow_decomposition View documentation} - */ - readonly allow_decomposition: boolean - /** - * Is this recipe unlocks the result item(s) so they're shown in filter-select GUIs. - * - * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.unlock_results View documentation} - */ - readonly unlock_results: boolean - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaRecipePrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Registry of interfaces between scripts. An interface is simply a dictionary mapping names to functions. A script or - * mod can then register an interface with {@link LuaRemote}, after that any script can call the registered functions, - * provided it knows the interface name and the desired function name. An instance of LuaRemote is available through the - * global object named `remote`. - * - * {@link https://lua-api.factorio.com/next/LuaRemote.html View documentation} - * - * @example - * Will register a remote interface containing two functions. Later, it will call these functions through `remote`. - * - * ```lua - * remote.add_interface("human interactor", - * {hello = function() game.player.print("Hi!") end, - * bye = function(name) game.player.print("Bye " .. name) end}) - * -- Some time later, possibly in a different mod... - * remote.call("human interactor", "hello") - * remote.call("human interactor", "bye", "dear reader") - * ``` - * - * @noSelf - */ -interface LuaRemote { - /** - * Add a remote interface. - * - * **Note**: It is an error if the given interface `name` is already registered. - * - * {@link https://lua-api.factorio.com/next/LuaRemote.html#LuaRemote.add_interface View documentation} - * - * @param name - Name of the interface. - * @param functions - List of functions that are members of the new interface. - */ - add_interface(name: string, functions: Record void>): void - /** - * Removes an interface with the given name. - * - * {@link https://lua-api.factorio.com/next/LuaRemote.html#LuaRemote.remove_interface View documentation} - * - * @param name - Name of the interface. - * @returns If the interface was removed. `False` if the interface didn't exist. - */ - remove_interface(name: string): boolean - /** - * Call a function of an interface. - * - * {@link https://lua-api.factorio.com/next/LuaRemote.html#LuaRemote.call View documentation} - * - * @param _interface - Interface to look up `function` in. - * @param _function - Function name that belongs to `interface`. - * @param args - Arguments to pass to the called function. - */ - call(_interface: string, _function: string, ...args: Any[]): Any - /** - * List of all registered interfaces. For each interface name, `remote.interfaces[name]` is a dictionary mapping the - * interface's registered functions to the value `true`. - * - * {@link https://lua-api.factorio.com/next/LuaRemote.html#LuaRemote.interfaces View documentation} - * - * @example - * Assuming the "human interactor" interface is registered as above - * - * ```lua - * game.player.print(tostring(remote.interfaces["human interactor"]["hello"])) -- prints true - * game.player.print(tostring(remote.interfaces["human interactor"]["nonexistent"])) -- prints nil - * ``` - */ - readonly interfaces: Record> - /** This object's name. */ - readonly object_name: "LuaRemote" -} - -/** - * Allows rendering of geometric shapes, text and sprites in the game world. Each render object is identified by an id - * that is universally unique for the lifetime of a whole game. - * - * **Note**: If an entity target of an object is destroyed or changes surface, then the object is also destroyed. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html View documentation} - * - * @noSelf - */ -interface LuaRendering { - /** - * Create a line. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_line View documentation} - * - * @example - * Draw a white and 2 pixel wide line from {0, 0} to {2, 2}. - * - * ```lua - * rendering.draw_line{surface = game.player.surface, from = {0, 0}, to = {2, 2}, color = {1, 1, 1}, width = 2} - * ``` - * - * @example - * Draw a red and 3 pixel wide line from {0, 0} to {0, 5}. The line has 1 tile long dashes and gaps. - * - * ```lua - * rendering.draw_line{surface = game.player.surface, from = {0, 0}, to = {0, 5}, color = {r = 1}, width = 3, gap_length = 1, dash_length = 1} - * ``` - * - * @returns Id of the render object - */ - draw_line(params: { - readonly color: Color - /** In pixels (32 per tile). */ - readonly width: float - /** Length of the gaps that this line has, in tiles. Default is 0. */ - readonly gap_length?: double - /** Length of the dashes that this line has. Used only if gap_length > 0. Default is 0. */ - readonly dash_length?: double - readonly from: Position | LuaEntity - /** Only used if `from` is a LuaEntity. */ - readonly from_offset?: Vector - readonly to: Position | LuaEntity - /** Only used if `to` is a LuaEntity. */ - readonly to_offset?: Vector - readonly surface: SurfaceIdentification - /** In ticks. Defaults to living forever. */ - readonly time_to_live?: uint - /** The forces that this object is rendered to. */ - readonly forces?: ForceIdentification[] - /** The players that this object is rendered to. */ - readonly players?: PlayerIdentification[] - /** If this is rendered to anyone at all. Defaults to true. */ - readonly visible?: boolean - /** If this should be drawn below sprites and entities. */ - readonly draw_on_ground?: boolean - /** If this should only be rendered in alt mode. Defaults to false. */ - readonly only_in_alt_mode?: boolean - }): uint64 - /** - * Create a text. - * - * **Note**: Not all fonts support scaling. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_text View documentation} - * - * @returns Id of the render object - */ - draw_text(params: { - /** The text to display. */ - readonly text: LocalisedString - readonly surface: SurfaceIdentification - readonly target: Position | LuaEntity - /** Only used if `target` is a LuaEntity. */ - readonly target_offset?: Vector - readonly color: Color - readonly scale?: double - /** Name of font to use. Defaults to the same font as flying-text. */ - readonly font?: string - /** In ticks. Defaults to living forever. */ - readonly time_to_live?: uint - /** The forces that this object is rendered to. */ - readonly forces?: ForceIdentification[] - /** The players that this object is rendered to. */ - readonly players?: PlayerIdentification[] - /** If this is rendered to anyone at all. Defaults to true. */ - readonly visible?: boolean - /** If this should be drawn below sprites and entities. */ - readonly draw_on_ground?: boolean - /** The orientation of the text. Default is 0. */ - readonly orientation?: RealOrientation - /** Defaults to "left". Other options are "right" and "center". */ - readonly alignment?: "left" | "right" | "center" - /** Defaults to "top". Other options are "middle", "baseline" and "bottom". */ - readonly vertical_alignment?: "top" | "middle" | "baseline" | "bottom" - /** - * Defaults to false. If true, the text scales with player zoom, resulting in it always being the same size on - * screen, and the size compared to the game world changes. - */ - readonly scale_with_zoom?: boolean - /** If this should only be rendered in alt mode. Defaults to false. */ - readonly only_in_alt_mode?: boolean - }): uint64 - /** - * Create a circle. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_circle View documentation} - * - * @returns Id of the render object - */ - draw_circle(params: { - readonly color: Color - /** In tiles. */ - readonly radius: double - /** Width of the outline, used only if filled = false. Value is in pixels (32 per tile). */ - readonly width?: float - /** If the circle should be filled. */ - readonly filled: boolean - readonly target: Position | LuaEntity - /** Only used if `target` is a LuaEntity. */ - readonly target_offset?: Vector - readonly surface: SurfaceIdentification - /** In ticks. Defaults to living forever. */ - readonly time_to_live?: uint - /** The forces that this object is rendered to. */ - readonly forces?: ForceIdentification[] - /** The players that this object is rendered to. */ - readonly players?: PlayerIdentification[] - /** If this is rendered to anyone at all. Defaults to true. */ - readonly visible?: boolean - /** If this should be drawn below sprites and entities. */ - readonly draw_on_ground?: boolean - /** If this should only be rendered in alt mode. Defaults to false. */ - readonly only_in_alt_mode?: boolean - }): uint64 - /** - * Create a rectangle. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_rectangle View documentation} - * - * @returns Id of the render object - */ - draw_rectangle(params: { - readonly color: Color - /** Width of the outline, used only if filled = false. Value is in pixels (32 per tile). */ - readonly width?: float - /** If the rectangle should be filled. */ - readonly filled: boolean - readonly left_top: Position | LuaEntity - /** Only used if `left_top` is a LuaEntity. */ - readonly left_top_offset?: Vector - readonly right_bottom: Position | LuaEntity - /** Only used if `right_bottom` is a LuaEntity. */ - readonly right_bottom_offset?: Vector - readonly surface: SurfaceIdentification - /** In ticks. Defaults to living forever. */ - readonly time_to_live?: uint - /** The forces that this object is rendered to. */ - readonly forces?: ForceIdentification[] - /** The players that this object is rendered to. */ - readonly players?: PlayerIdentification[] - /** If this is rendered to anyone at all. Defaults to true. */ - readonly visible?: boolean - /** If this should be drawn below sprites and entities. */ - readonly draw_on_ground?: boolean - /** If this should only be rendered in alt mode. Defaults to false. */ - readonly only_in_alt_mode?: boolean - }): uint64 - /** - * Create an arc. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_arc View documentation} - * - * @returns Id of the render object - */ - draw_arc(params: { - readonly color: Color - /** The radius of the outer edge of the arc, in tiles. */ - readonly max_radius: double - /** The radius of the inner edge of the arc, in tiles. */ - readonly min_radius: double - /** Where the arc starts, in radian. */ - readonly start_angle: float - /** The angle of the arc, in radian. */ - readonly angle: float - readonly target: Position | LuaEntity - /** Only used if `target` is a LuaEntity. */ - readonly target_offset?: Vector - readonly surface: SurfaceIdentification - /** In ticks. Defaults to living forever. */ - readonly time_to_live?: uint - /** The forces that this object is rendered to. */ - readonly forces?: ForceIdentification[] - /** The players that this object is rendered to. */ - readonly players?: PlayerIdentification[] - /** If this is rendered to anyone at all. Defaults to true. */ - readonly visible?: boolean - /** If this should be drawn below sprites and entities. */ - readonly draw_on_ground?: boolean - /** If this should only be rendered in alt mode. Defaults to false. */ - readonly only_in_alt_mode?: boolean - }): uint64 - /** - * Create a triangle mesh defined by a triangle strip. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_polygon View documentation} - * - * @returns Id of the render object - */ - draw_polygon(params: { - readonly color: Color - readonly vertices: ScriptRenderVertexTarget[] - /** Acts like an offset applied to all vertices that are not set to an entity. */ - readonly target?: Position | LuaEntity - /** Only used if `target` is a LuaEntity. */ - readonly target_offset?: Vector - /** The orientation applied to all vertices. Default is 0. */ - readonly orientation?: RealOrientation - /** - * If given, the vertices (that are not set to an entity) rotate so that it faces this target. Note that - * `orientation` is still applied. - */ - readonly orientation_target?: Position | LuaEntity - /** Only used if `orientation_target` is a LuaEntity. */ - readonly orientation_target_offset?: Vector - readonly surface: SurfaceIdentification - /** In ticks. Defaults to living forever. */ - readonly time_to_live?: uint - /** The forces that this object is rendered to. */ - readonly forces?: ForceIdentification[] - /** The players that this object is rendered to. */ - readonly players?: PlayerIdentification[] - /** If this is rendered to anyone at all. Defaults to true. */ - readonly visible?: boolean - /** If this should be drawn below sprites and entities. */ - readonly draw_on_ground?: boolean - /** If this should only be rendered in alt mode. Defaults to false. */ - readonly only_in_alt_mode?: boolean - }): uint64 - /** - * Create a sprite. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_sprite View documentation} - * - * @example - * This will draw an iron plate icon at the character's feet. The sprite will move together with the character. - * - * ```lua - * rendering.draw_sprite{sprite = "item.iron-plate", target = game.player.character, surface = game.player.surface} - * ``` - * - * @example - * This will draw an iron plate icon at the character's head. The sprite will move together with the character. - * - * ```lua - * rendering.draw_sprite{sprite = "item.iron-plate", target = game.player.character, target_offset = {0, -2}, surface = game.player.surface} - * ``` - * - * @returns Id of the render object - */ - draw_sprite(params: { - readonly sprite: SpritePath - /** The orientation of the sprite. Default is 0. */ - readonly orientation?: RealOrientation - /** Horizontal scale of the sprite. Default is 1. */ - readonly x_scale?: double - /** Vertical scale of the sprite. Default is 1. */ - readonly y_scale?: double - readonly tint?: Color - readonly render_layer?: RenderLayer - /** If given, the sprite rotates so that it faces this target. Note that `orientation` is still applied to the sprite. */ - readonly orientation_target?: Position | LuaEntity - /** Only used if `orientation_target` is a LuaEntity. */ - readonly orientation_target_offset?: Vector - /** Offsets the center of the sprite if `orientation_target` is given. This offset will rotate together with the sprite. */ - readonly oriented_offset?: Vector - /** Center of the sprite. */ - readonly target: Position | LuaEntity - /** Only used if `target` is a LuaEntity. */ - readonly target_offset?: Vector - readonly surface: SurfaceIdentification - /** In ticks. Defaults to living forever. */ - readonly time_to_live?: uint - /** The forces that this object is rendered to. */ - readonly forces?: ForceIdentification[] - /** The players that this object is rendered to. */ - readonly players?: PlayerIdentification[] - /** If this is rendered to anyone at all. Defaults to true. */ - readonly visible?: boolean - /** If this should only be rendered in alt mode. Defaults to false. */ - readonly only_in_alt_mode?: boolean - }): uint64 - /** - * Create a light. - * - * **Note**: The base game uses the utility sprites `light_medium` and `light_small` for lights. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_light View documentation} - * - * @returns Id of the render object - */ - draw_light(params: { - readonly sprite: SpritePath - /** The orientation of the light. Default is 0. */ - readonly orientation?: RealOrientation - /** Default is 1. */ - readonly scale?: float - /** Default is 1. */ - readonly intensity?: float - /** The minimum darkness at which this light is rendered. Default is 0. */ - readonly minimum_darkness?: float - /** - * If this light has the same orientation as the entity target, default is false. Note that `orientation` is - * still applied to the sprite. - */ - readonly oriented?: boolean - /** Defaults to white (no tint). */ - readonly color?: Color - /** Center of the light. */ - readonly target: Position | LuaEntity - /** Only used if `target` is a LuaEntity. */ - readonly target_offset?: Vector - readonly surface: SurfaceIdentification - /** In ticks. Defaults to living forever. */ - readonly time_to_live?: uint - /** The forces that this object is rendered to. */ - readonly forces?: ForceIdentification[] - /** The players that this object is rendered to. */ - readonly players?: PlayerIdentification[] - /** If this is rendered to anyone at all. Defaults to true. */ - readonly visible?: boolean - /** If this should only be rendered in alt mode. Defaults to false. */ - readonly only_in_alt_mode?: boolean - }): uint64 - /** - * Create an animation. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_animation View documentation} - * - * @returns Id of the render object - */ - draw_animation(params: { - /** Name of an {@link https://wiki.factorio.com/Prototype/Animation animation prototype}. */ - readonly animation: string - /** The orientation of the animation. Default is 0. */ - readonly orientation?: RealOrientation - /** Horizontal scale of the animation. Default is 1. */ - readonly x_scale?: double - /** Vertical scale of the animation. Default is 1. */ - readonly y_scale?: double - readonly tint?: Color - readonly render_layer?: RenderLayer - /** How many frames the animation goes forward per tick. Default is 1. */ - readonly animation_speed?: double - /** Offset of the animation in frames. Default is 0. */ - readonly animation_offset?: double - /** - * If given, the animation rotates so that it faces this target. Note that `orientation` is still applied to the - * animation. - */ - readonly orientation_target?: Position | LuaEntity - /** Only used if `orientation_target` is a LuaEntity. */ - readonly orientation_target_offset?: Vector - /** - * Offsets the center of the animation if `orientation_target` is given. This offset will rotate together with - * the animation. - */ - readonly oriented_offset?: Vector - /** Center of the animation. */ - readonly target: Position | LuaEntity - /** Only used if `target` is a LuaEntity. */ - readonly target_offset?: Vector - readonly surface: SurfaceIdentification - /** In ticks. Defaults to living forever. */ - readonly time_to_live?: uint - /** The forces that this object is rendered to. */ - readonly forces?: ForceIdentification[] - /** The players that this object is rendered to. */ - readonly players?: PlayerIdentification[] - /** If this is rendered to anyone at all. Defaults to true. */ - readonly visible?: boolean - /** If this should only be rendered in alt mode. Defaults to false. */ - readonly only_in_alt_mode?: boolean - }): uint64 - /** - * Destroy the object with the given id. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.destroy View documentation} - * - * @param id - */ - destroy(id: uint64): void - /** - * Does a font with this name exist? - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.is_font_valid View documentation} - * - * @param font_name - */ - is_font_valid(font_name: string): boolean - /** - * Does a valid object with this id exist? - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.is_valid View documentation} - * - * @param id - */ - is_valid(id: uint64): boolean - /** - * Gets an array of all valid object ids. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_all_ids View documentation} - * - * @param mod_name - If provided, get only the render objects created by this mod. - */ - get_all_ids(mod_name?: string): uint64[] - /** - * Destroys all render objects. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.clear View documentation} - * - * @param mod_name - If provided, only the render objects created by this mod are destroyed. - */ - clear(mod_name?: string): void - /** - * Gets the type of the given object. The types are "text", "line", "circle", "rectangle", "arc", "polygon", - * "sprite", "light" and "animation". - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_type View documentation} - * - * @param id - */ - get_type(id: uint64): "text" | "line" | "circle" | "rectangle" | "arc" | "polygon" | "sprite" | "light" | "animation" - /** - * Reorder this object so that it is drawn in front of the already existing objects. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.bring_to_front View documentation} - * - * @param id - */ - bring_to_front(id: uint64): void - /** - * The surface the object with this id is rendered on. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_surface View documentation} - * - * @param id - */ - get_surface(id: uint64): LuaSurface - /** - * Get the time to live of the object with this id. This will be 0 if the object does not expire. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_time_to_live View documentation} - * - * @param id - */ - get_time_to_live(id: uint64): uint - /** - * Set the time to live of the object with this id. Set to 0 if the object should not expire. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_time_to_live View documentation} - * - * @param id - * @param time_to_live - */ - set_time_to_live(id: uint64, time_to_live: uint): void - /** - * Get the forces that the object with this id is rendered to or `nil` if visible to all forces. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_forces View documentation} - * - * @param id - */ - get_forces(id: uint64): LuaForce[] | undefined - /** - * Set the forces that the object with this id is rendered to. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_forces View documentation} - * - * @param id - * @param forces - Providing an empty array will set the object to be visible to all forces. - */ - set_forces(id: uint64, forces: ForceIdentification[]): void - /** - * Get the players that the object with this id is rendered to or `nil` if visible to all players. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_players View documentation} - * - * @param id - */ - get_players(id: uint64): LuaPlayer[] | undefined - /** - * Set the players that the object with this id is rendered to. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_players View documentation} - * - * @param id - * @param players - Providing an empty array will set the object to be visible to all players. - */ - set_players(id: uint64, players: PlayerIdentification[]): void - /** - * Get whether this is rendered to anyone at all. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_visible View documentation} - * - * @param id - */ - get_visible(id: uint64): boolean - /** - * Set whether this is rendered to anyone at all. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_visible View documentation} - * - * @param id - * @param visible - */ - set_visible(id: uint64, visible: boolean): void - /** - * Get whether this is being drawn on the ground, under most entities and sprites. - * - * *Can only be used if this is Text, Line, Circle, Rectangle, Arc or Polygon* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_draw_on_ground View documentation} - * - * @param id - */ - get_draw_on_ground(id: uint64): boolean - /** - * Set whether this is being drawn on the ground, under most entities and sprites. - * - * *Can only be used if this is Text, Line, Circle, Rectangle, Arc or Polygon* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_draw_on_ground View documentation} - * - * @param id - * @param draw_on_ground - */ - set_draw_on_ground(id: uint64, draw_on_ground: boolean): void - /** - * Get whether this is only rendered in alt-mode. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_only_in_alt_mode View documentation} - * - * @param id - */ - get_only_in_alt_mode(id: uint64): boolean - /** - * Set whether this is only rendered in alt-mode. - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_only_in_alt_mode View documentation} - * - * @param id - * @param only_in_alt_mode - */ - set_only_in_alt_mode(id: uint64, only_in_alt_mode: boolean): void - /** - * Get the color or tint of the object with this id. - * - * *Can only be used if this is Text, Line, Circle, Rectangle, Arc, Polygon, Sprite, Light or Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_color View documentation} - * - * @param id - * @returns Or `nil` if the object does not support color. - */ - get_color(id: uint64): ColorTable | undefined - /** - * Set the color or tint of the object with this id. Does nothing if this object does not support color. - * - * *Can only be used if this is Text, Line, Circle, Rectangle, Arc, Polygon, Sprite, Light or Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_color View documentation} - * - * @param id - * @param color - */ - set_color(id: uint64, color: Color): void - /** - * Get the width of the object with this id. Value is in pixels (32 per tile). - * - * *Can only be used if this is Line, Circle or Rectangle* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_width View documentation} - * - * @param id - * @returns Or `nil` if the object does not support width. - */ - get_width(id: uint64): float | undefined - /** - * Set the width of the object with this id. Does nothing if this object does not support width. Value is in pixels - * (32 per tile). - * - * *Can only be used if this is Line, Circle or Rectangle* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_width View documentation} - * - * @param id - * @param width - */ - set_width(id: uint64, width: float): void - /** - * Get from where the line with this id is drawn or `nil` if this object is not a line. - * - * *Can only be used if this is Line* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_from View documentation} - * - * @param id - */ - get_from(id: uint64): ScriptRenderTarget | undefined - /** - * Set from where the line with this id is drawn. Does nothing if the object is not a line. - * - * *Can only be used if this is Line* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_from View documentation} - * - * @param id - * @param from - * @param from_offset - */ - set_from(id: uint64, from: Position | LuaEntity, from_offset?: Vector): void - /** - * Get where the line with this id is drawn to or `nil` if the object is not a line. - * - * *Can only be used if this is Line* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_to View documentation} - * - * @param id - */ - get_to(id: uint64): ScriptRenderTarget | undefined - /** - * Set where the line with this id is drawn to. Does nothing if this object is not a line. - * - * *Can only be used if this is Line* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_to View documentation} - * - * @param id - * @param to - * @param to_offset - */ - set_to(id: uint64, to: Position | LuaEntity, to_offset?: Vector): void - /** - * Get the dash length of the line with this id or `nil` if the object is not a line. - * - * *Can only be used if this is Line* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_dash_length View documentation} - * - * @param id - */ - get_dash_length(id: uint64): double | undefined - /** - * Set the dash length of the line with this id. Does nothing if this object is not a line. - * - * *Can only be used if this is Line* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_dash_length View documentation} - * - * @param id - * @param dash_length - */ - set_dash_length(id: uint64, dash_length: double): void - /** - * Get the length of the gaps in the line with this id or `nil` if the object is not a line. - * - * *Can only be used if this is Line* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_gap_length View documentation} - * - * @param id - */ - get_gap_length(id: uint64): double | undefined - /** - * Set the length of the gaps in the line with this id. Does nothing if this object is not a line. - * - * *Can only be used if this is Line* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_gap_length View documentation} - * - * @param id - * @param gap_length - */ - set_gap_length(id: uint64, gap_length: double): void - /** - * Set the length of the dashes and the length of the gaps in the line with this id. Does nothing if this object is - * not a line. - * - * *Can only be used if this is Line* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_dashes View documentation} - * - * @param id - * @param dash_length - * @param gap_length - */ - set_dashes(id: uint64, dash_length: double, gap_length: double): void - /** - * Get where the object with this id is drawn or `nil` if the object does not support target. - * - * **Note**: Polygon vertices that are set to an entity will ignore this. - * - * *Can only be used if this is Text, Circle, Arc, Polygon, Sprite, Light or Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_target View documentation} - * - * @param id - */ - get_target(id: uint64): ScriptRenderTarget | undefined - /** - * Set where the object with this id is drawn. Does nothing if this object does not support target. - * - * **Note**: Polygon vertices that are set to an entity will ignore this. - * - * *Can only be used if this is Text, Circle, Arc, Polygon, Sprite, Light or Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_target View documentation} - * - * @param id - * @param target - * @param target_offset - */ - set_target(id: uint64, target: Position | LuaEntity, target_offset?: Vector): void - /** - * Get the orientation of the object with this id or `nil` if the object is not a text, polygon, sprite, light or animation. - * - * **Note**: Polygon vertices that are set to an entity will ignore this. - * - * *Can only be used if this is Text, Polygon, Sprite, Light or Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_orientation View documentation} - * - * @param id - */ - get_orientation(id: uint64): RealOrientation | undefined - /** - * Set the orientation of the object with this id. Does nothing if this object is not a text, polygon, sprite, light - * or animation. - * - * **Note**: Polygon vertices that are set to an entity will ignore this. - * - * *Can only be used if this is Text, Polygon, Sprite, Light or Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_orientation View documentation} - * - * @param id - * @param orientation - */ - set_orientation(id: uint64, orientation: RealOrientation): void - /** - * Get the scale of the text or light with this id or `nil` if the object is not a text or light. - * - * *Can only be used if this is Text or Light* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_scale View documentation} - * - * @param id - */ - get_scale(id: uint64): double | undefined - /** - * Set the scale of the text or light with this id. Does nothing if this object is not a text or light. - * - * *Can only be used if this is Text or Light* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_scale View documentation} - * - * @param id - * @param scale - */ - set_scale(id: uint64, scale: double): void - /** - * Get the text that is displayed by the text with this id or `nil` if the object is not a text. - * - * *Can only be used if this is Text* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_text View documentation} - * - * @param id - */ - get_text(id: uint64): LocalisedString | undefined - /** - * Set the text that is displayed by the text with this id. Does nothing if this object is not a text. - * - * *Can only be used if this is Text* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_text View documentation} - * - * @param id - * @param text - */ - set_text(id: uint64, text: LocalisedString): void - /** - * Get the font of the text with this id or `nil` if the object is not a text. - * - * *Can only be used if this is Text* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_font View documentation} - * - * @param id - */ - get_font(id: uint64): string | undefined - /** - * Set the font of the text with this id. Does nothing if this object is not a text. - * - * *Can only be used if this is Text* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_font View documentation} - * - * @param id - * @param font - */ - set_font(id: uint64, font: string): void - /** - * Get the alignment of the text with this id or `nil` if the object is not a text. - * - * *Can only be used if this is Text* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_alignment View documentation} - * - * @param id - */ - get_alignment(id: uint64): string | undefined - /** - * Set the alignment of the text with this id. Does nothing if this object is not a text. - * - * *Can only be used if this is Text* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_alignment View documentation} - * - * @param id - * @param alignment - "left", "right" or "center". - */ - set_alignment(id: uint64, alignment: "left" | "right" | "center"): void - /** - * Get the vertical alignment of the text with this id or `nil` if the object is not a text. - * - * *Can only be used if this is Text* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_vertical_alignment View documentation} - * - * @param id - */ - get_vertical_alignment(id: uint64): string | undefined - /** - * Set the vertical alignment of the text with this id. Does nothing if this object is not a text. - * - * *Can only be used if this is Text* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_vertical_alignment View documentation} - * - * @param id - * @param alignment - "top", "middle", "baseline" or "bottom" - */ - set_vertical_alignment(id: uint64, alignment: "top" | "middle" | "baseline" | "bottom"): void - /** - * Get if the text with this id scales with player zoom or `nil` if the object is not a text. - * - * *Can only be used if this is Text* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_scale_with_zoom View documentation} - * - * @param id - */ - get_scale_with_zoom(id: uint64): boolean | undefined - /** - * Set if the text with this id scales with player zoom, resulting in it always being the same size on screen, and - * the size compared to the game world changes. Does nothing if this object is not a text. - * - * *Can only be used if this is Text* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_scale_with_zoom View documentation} - * - * @param id - * @param scale_with_zoom - */ - set_scale_with_zoom(id: uint64, scale_with_zoom: boolean): void - /** - * Get if the circle or rectangle with this id is filled or `nil` if the object is not a circle or rectangle. - * - * *Can only be used if this is Circle or Rectangle* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_filled View documentation} - * - * @param id - */ - get_filled(id: uint64): boolean | undefined - /** - * Set if the circle or rectangle with this id is filled. Does nothing if this object is not a circle or rectangle. - * - * *Can only be used if this is Circle or Rectangle* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_filled View documentation} - * - * @param id - * @param filled - */ - set_filled(id: uint64, filled: boolean): void - /** - * Get the radius of the circle with this id or `nil` if the object is not a circle. - * - * *Can only be used if this is Circle* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_radius View documentation} - * - * @param id - */ - get_radius(id: uint64): double | undefined - /** - * Set the radius of the circle with this id. Does nothing if this object is not a circle. - * - * *Can only be used if this is Circle* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_radius View documentation} - * - * @param id - * @param radius - */ - set_radius(id: uint64, radius: double): void - /** - * Get where top left corner of the rectangle with this id is drawn or `nil` if the object is not a rectangle. - * - * *Can only be used if this is Rectangle* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_left_top View documentation} - * - * @param id - */ - get_left_top(id: uint64): ScriptRenderTarget | undefined - /** - * Set where top left corner of the rectangle with this id is drawn. Does nothing if this object is not a rectangle. - * - * *Can only be used if this is Rectangle* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_left_top View documentation} - * - * @param id - * @param left_top - * @param left_top_offset - */ - set_left_top(id: uint64, left_top: Position | LuaEntity, left_top_offset?: Vector): void - /** - * Get where bottom right corner of the rectangle with this id is drawn or `nil` if the object is not a rectangle. - * - * *Can only be used if this is Rectangle* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_right_bottom View documentation} - * - * @param id - */ - get_right_bottom(id: uint64): ScriptRenderTarget | undefined - /** - * Set where top bottom right of the rectangle with this id is drawn. Does nothing if this object is not a rectangle. - * - * *Can only be used if this is Rectangle* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_right_bottom View documentation} - * - * @param id - * @param right_bottom - * @param right_bottom_offset - */ - set_right_bottom(id: uint64, right_bottom: Position | LuaEntity, right_bottom_offset?: Vector): void - /** - * Set the corners of the rectangle with this id. Does nothing if this object is not a rectangle. - * - * *Can only be used if this is Rectangle* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_corners View documentation} - * - * @param id - * @param left_top - * @param left_top_offset - * @param right_bottom - * @param right_bottom_offset - */ - set_corners( - id: uint64, - left_top: Position | LuaEntity, - left_top_offset: Vector, - right_bottom: Position | LuaEntity, - right_bottom_offset: Vector - ): void - /** - * Get the radius of the outer edge of the arc with this id or `nil` if the object is not a arc. - * - * *Can only be used if this is Arc* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_max_radius View documentation} - * - * @param id - */ - get_max_radius(id: uint64): double | undefined - /** - * Set the radius of the outer edge of the arc with this id. Does nothing if this object is not a arc. - * - * *Can only be used if this is Arc* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_max_radius View documentation} - * - * @param id - * @param max_radius - */ - set_max_radius(id: uint64, max_radius: double): void - /** - * Get the radius of the inner edge of the arc with this id or `nil` if the object is not a arc. - * - * *Can only be used if this is Arc* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_min_radius View documentation} - * - * @param id - */ - get_min_radius(id: uint64): double | undefined - /** - * Set the radius of the inner edge of the arc with this id. Does nothing if this object is not a arc. - * - * *Can only be used if this is Arc* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_min_radius View documentation} - * - * @param id - * @param min_radius - */ - set_min_radius(id: uint64, min_radius: double): void - /** - * Get where the arc with this id starts or `nil` if the object is not a arc. - * - * *Can only be used if this is Arc* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_start_angle View documentation} - * - * @param id - * @returns Angle in radian - */ - get_start_angle(id: uint64): float | undefined - /** - * Set where the arc with this id starts. Does nothing if this object is not a arc. - * - * *Can only be used if this is Arc* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_start_angle View documentation} - * - * @param id - * @param start_angle - Angle in radian - */ - set_start_angle(id: uint64, start_angle: float): void - /** - * Get the angle of the arc with this id or `nil` if the object is not a arc. - * - * *Can only be used if this is Arc* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_angle View documentation} - * - * @param id - * @returns Angle in radian - */ - get_angle(id: uint64): float | undefined - /** - * Set the angle of the arc with this id. Does nothing if this object is not a arc. - * - * *Can only be used if this is Arc* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_angle View documentation} - * - * @param id - * @param angle - Angle in radian - */ - set_angle(id: uint64, angle: float): void - /** - * Get the vertices of the polygon with this id or `nil` if the object is not a polygon. - * - * *Can only be used if this is Polygon* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_vertices View documentation} - * - * @param id - */ - get_vertices(id: uint64): ScriptRenderTarget[] | undefined - /** - * Set the vertices of the polygon with this id. Does nothing if this object is not a polygon. - * - * *Can only be used if this is Polygon* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_vertices View documentation} - * - * @param id - * @param vertices - */ - set_vertices(id: uint64, vertices: ScriptRenderVertexTarget[]): void - /** - * Get the sprite of the sprite or light with this id or `nil` if the object is not a sprite or light. - * - * *Can only be used if this is Sprite or Light* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_sprite View documentation} - * - * @param id - */ - get_sprite(id: uint64): SpritePath | undefined - /** - * Set the sprite of the sprite or light with this id. Does nothing if this object is not a sprite or light. - * - * *Can only be used if this is Sprite or Light* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_sprite View documentation} - * - * @param id - * @param sprite - */ - set_sprite(id: uint64, sprite: SpritePath): void - /** - * Get the horizontal scale of the sprite or animation with this id or `nil` if the object is not a sprite or animation. - * - * *Can only be used if this is Sprite or Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_x_scale View documentation} - * - * @param id - */ - get_x_scale(id: uint64): double | undefined - /** - * Set the horizontal scale of the sprite or animation with this id. Does nothing if this object is not a sprite or animation. - * - * *Can only be used if this is Sprite or Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_x_scale View documentation} - * - * @param id - * @param x_scale - */ - set_x_scale(id: uint64, x_scale: double): void - /** - * Get the vertical scale of the sprite or animation with this id or `nil` if the object is not a sprite or animation. - * - * *Can only be used if this is Sprite or Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_y_scale View documentation} - * - * @param id - */ - get_y_scale(id: uint64): double | undefined - /** - * Set the vertical scale of the sprite or animation with this id. Does nothing if this object is not a sprite or animation. - * - * *Can only be used if this is Sprite or Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_y_scale View documentation} - * - * @param id - * @param y_scale - */ - set_y_scale(id: uint64, y_scale: double): void - /** - * Get the render layer of the sprite or animation with this id or `nil` if the object is not a sprite or animation. - * - * *Can only be used if this is Sprite or Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_render_layer View documentation} - * - * @param id - */ - get_render_layer(id: uint64): RenderLayer | undefined - /** - * Set the render layer of the sprite or animation with this id. Does nothing if this object is not a sprite or animation. - * - * *Can only be used if this is Sprite or Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_render_layer View documentation} - * - * @param id - * @param render_layer - */ - set_render_layer(id: uint64, render_layer: RenderLayer): void - /** - * The object rotates so that it faces this target. Note that `orientation` is still applied to the object. Get the - * orientation_target of the object with this id or `nil` if no target or if this object is not a polygon, sprite, - * or animation. - * - * **Note**: Polygon vertices that are set to an entity will ignore this. - * - * *Can only be used if this is Polygon, Sprite or Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_orientation_target View documentation} - * - * @param id - */ - get_orientation_target(id: uint64): ScriptRenderTarget | undefined - /** - * The object rotates so that it faces this target. Note that `orientation` is still applied to the object. Set the - * orientation_target of the object with this id. Does nothing if this object is not a polygon, sprite, or - * animation. Set to `nil` if the object should not have an orientation_target. - * - * **Note**: Polygon vertices that are set to an entity will ignore this. - * - * *Can only be used if this is Polygon, Sprite or Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_orientation_target View documentation} - * - * @param id - * @param orientation_target - * @param orientation_target_offset - */ - set_orientation_target(id: uint64, orientation_target: Position | LuaEntity, orientation_target_offset?: Vector): void - /** - * Offsets the center of the sprite or animation if `orientation_target` is given. This offset will rotate together - * with the sprite or animation. Get the oriented_offset of the sprite or animation with this id or `nil` if this - * object is not a sprite or animation. - * - * *Can only be used if this is Sprite or Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_oriented_offset View documentation} - * - * @param id - */ - get_oriented_offset(id: uint64): Vector | undefined - /** - * Offsets the center of the sprite or animation if `orientation_target` is given. This offset will rotate together - * with the sprite or animation. Set the oriented_offset of the sprite or animation with this id. Does nothing if - * this object is not a sprite or animation. - * - * *Can only be used if this is Sprite or Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_oriented_offset View documentation} - * - * @param id - * @param oriented_offset - */ - set_oriented_offset(id: uint64, oriented_offset: Vector): void - /** - * Get the intensity of the light with this id or `nil` if the object is not a light. - * - * *Can only be used if this is Light* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_intensity View documentation} - * - * @param id - */ - get_intensity(id: uint64): float | undefined - /** - * Set the intensity of the light with this id. Does nothing if this object is not a light. - * - * *Can only be used if this is Light* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_intensity View documentation} - * - * @param id - * @param intensity - */ - set_intensity(id: uint64, intensity: float): void - /** - * Get the minimum darkness at which the light with this id is rendered or `nil` if the object is not a light. - * - * *Can only be used if this is Light* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_minimum_darkness View documentation} - * - * @param id - */ - get_minimum_darkness(id: uint64): float | undefined - /** - * Set the minimum darkness at which the light with this id is rendered. Does nothing if this object is not a light. - * - * *Can only be used if this is Light* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_minimum_darkness View documentation} - * - * @param id - * @param minimum_darkness - */ - set_minimum_darkness(id: uint64, minimum_darkness: float): void - /** - * Get if the light with this id is rendered has the same orientation as the target entity or `nil` if the object is - * not a light. Note that `orientation` is still applied to the sprite. - * - * *Can only be used if this is Light* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_oriented View documentation} - * - * @param id - */ - get_oriented(id: uint64): boolean | undefined - /** - * Set if the light with this id is rendered has the same orientation as the target entity. Does nothing if this - * object is not a light. Note that `orientation` is still applied to the sprite. - * - * *Can only be used if this is Light* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_oriented View documentation} - * - * @param id - * @param oriented - */ - set_oriented(id: uint64, oriented: boolean): void - /** - * Get the animation prototype name of the animation with this id or `nil` if the object is not an animation. - * - * *Can only be used if this is Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_animation View documentation} - * - * @param id - */ - get_animation(id: uint64): string | undefined - /** - * Set the animation prototype name of the animation with this id. Does nothing if this object is not an animation. - * - * *Can only be used if this is Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_animation View documentation} - * - * @param id - * @param animation - */ - set_animation(id: uint64, animation: string): void - /** - * Get the animation speed of the animation with this id or `nil` if the object is not an animation. - * - * *Can only be used if this is Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_animation_speed View documentation} - * - * @param id - * @returns Animation speed in frames per tick. - */ - get_animation_speed(id: uint64): double | undefined - /** - * Set the animation speed of the animation with this id. Does nothing if this object is not an animation. - * - * *Can only be used if this is Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_animation_speed View documentation} - * - * @param id - * @param animation_speed - Animation speed in frames per tick. - */ - set_animation_speed(id: uint64, animation_speed: double): void - /** - * Get the animation offset of the animation with this id or `nil` if the object is not an animation. - * - * *Can only be used if this is Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_animation_offset View documentation} - * - * @param id - * @returns Animation offset in frames. - */ - get_animation_offset(id: uint64): double | undefined - /** - * Set the animation offset of the animation with this id. Does nothing if this object is not an animation. - * - * *Can only be used if this is Animation* - * - * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_animation_offset View documentation} - * - * @param id - * @param animation_offset - Animation offset in frames. - */ - set_animation_offset(id: uint64, animation_offset: double): void - /** This object's name. */ - readonly object_name: "LuaRendering" -} - -/** - * Prototype of a resource category. - * - * {@link https://lua-api.factorio.com/next/LuaResourceCategoryPrototype.html View documentation} - * - * @noSelf - */ -interface LuaResourceCategoryPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaResourceCategoryPrototype.html#LuaResourceCategoryPrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaResourceCategoryPrototype.html#LuaResourceCategoryPrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaResourceCategoryPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Control behavior for roboports. - * - * {@link https://lua-api.factorio.com/next/LuaRoboportControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaRoboportControlBehavior extends LuaControlBehavior { - /** - * `true` if the roboport should report the logistics network content to the circuit network. - * - * {@link https://lua-api.factorio.com/next/LuaRoboportControlBehavior.html#LuaRoboportControlBehavior.read_logistics View documentation} - */ - read_logistics: boolean - /** - * `true` if the roboport should report the robot statistics to the circuit network. - * - * {@link https://lua-api.factorio.com/next/LuaRoboportControlBehavior.html#LuaRoboportControlBehavior.read_robot_stats View documentation} - */ - read_robot_stats: boolean - available_logistic_output_signal: SignalID - total_logistic_output_signal: SignalID - available_construction_output_signal: SignalID - total_construction_output_signal: SignalID - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaRoboportControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Object containing mod settings of three distinct types: `startup`, `global`, and `player`. An instance of LuaSettings - * is available through the global object named `settings`. - * - * {@link https://lua-api.factorio.com/next/LuaSettings.html View documentation} - * - * @noSelf - */ -interface LuaSettings { - /** - * Gets the current per-player settings for the given player, indexed by prototype name. Returns the same structure - * as {@link LuaPlayer.mod_settings LuaPlayer::mod_settings}. - * - * **Note**: This can become invalid if during operation if the given player becomes invalid. - * - * {@link https://lua-api.factorio.com/next/LuaSettings.html#LuaSettings.get_player_settings View documentation} - * - * @param player - */ - get_player_settings(player: PlayerIdentification): LuaCustomTable - /** - * The startup mod settings, indexed by prototype name. - * - * {@link https://lua-api.factorio.com/next/LuaSettings.html#LuaSettings.startup View documentation} - */ - readonly startup: LuaCustomTable - /** - * The current global mod settings, indexed by prototype name. - * - * Even though these are marked as read-only, they can be changed by overwriting individual {@link ModSetting} tables - * in the custom table. Mods can only change their own settings. Using the in-game console, all global settings can - * be changed. - * - * {@link https://lua-api.factorio.com/next/LuaSettings.html#LuaSettings.global View documentation} - */ - readonly global: LuaCustomTable - /** - * The default player mod settings for this map, indexed by prototype name. - * - * Even though these are marked as read-only, they can be changed by overwriting individual {@link ModSetting} tables - * in the custom table. Mods can only change their own settings. Using the in-game console, all player settings can - * be changed. - * - * {@link https://lua-api.factorio.com/next/LuaSettings.html#LuaSettings.player View documentation} - */ - readonly player: LuaCustomTable - /** This object's name. */ - readonly object_name: "LuaSettings" -} - -/** - * Prototype of a shortcut. - * - * {@link https://lua-api.factorio.com/next/LuaShortcutPrototype.html View documentation} - * - * @noSelf - */ -interface LuaShortcutPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaShortcutPrototype.html#LuaShortcutPrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaShortcutPrototype.html#LuaShortcutPrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - readonly action: string - readonly item_to_spawn: LuaItemPrototype - readonly technology_to_unlock: LuaTechnologyPrototype - readonly toggleable: boolean - readonly associated_control_input: string - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaShortcutPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Control behavior for storage tanks. - * - * {@link https://lua-api.factorio.com/next/LuaStorageTankControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaStorageTankControlBehavior extends LuaControlBehavior { - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaStorageTankControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Style of a GUI element. All of the attributes listed here may be `nil` if not available for a particular GUI element. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html View documentation} - * - * @noSelf - */ -interface LuaStyle { - /** - * Gui of the {@link LuaGuiElement} of this style. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.gui View documentation} - */ - readonly gui: LuaGui - /** - * Name of this style. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.name View documentation} - */ - readonly name: string - /** - * Minimal width ensures, that the widget will never be smaller than than that size. It can't be squashed to be smaller. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.minimal_width View documentation} - */ - minimal_width: int - /** - * Maximal width ensures, that the widget will never be bigger than than that size. It can't be stretched to be bigger. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.maximal_width View documentation} - */ - maximal_width: int - /** - * Minimal height ensures, that the widget will never be smaller than than that size. It can't be squashed to be smaller. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.minimal_height View documentation} - */ - minimal_height: int - /** - * Maximal height ensures, that the widget will never be bigger than than that size. It can't be stretched to be bigger. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.maximal_height View documentation} - */ - maximal_height: int - /** - * Natural width specifies the width of the element tries to have, but it can still be squashed/stretched to have a - * smaller or bigger size. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.natural_width View documentation} - */ - natural_width: int - /** - * Natural height specifies the height of the element tries to have, but it can still be squashed/stretched to have - * a smaller or bigger size. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.natural_height View documentation} - */ - natural_height: int - top_padding: int - right_padding: int - bottom_padding: int - left_padding: int - top_margin: int - right_margin: int - bottom_margin: int - left_margin: int - /** - * Horizontal align of the inner content of the widget, possible values are "left", "center" or "right" - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.horizontal_align View documentation} - */ - horizontal_align: "left" | "center" | "right" - /** - * Vertical align of the inner content of the widget, possible values are "top", "center" or "bottom" - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.vertical_align View documentation} - */ - vertical_align: "top" | "center" | "bottom" - font_color: Color - font: string - /** - * Space between the table cell contents top and border. - * - * *Can only be used if this is LuaTableStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.top_cell_padding View documentation} - */ - top_cell_padding: int - /** - * Space between the table cell contents right and border. - * - * *Can only be used if this is LuaTableStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.right_cell_padding View documentation} - */ - right_cell_padding: int - /** - * Space between the table cell contents bottom and border. - * - * *Can only be used if this is LuaTableStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.bottom_cell_padding View documentation} - */ - bottom_cell_padding: int - /** - * Space between the table cell contents left and border. - * - * *Can only be used if this is LuaTableStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.left_cell_padding View documentation} - */ - left_cell_padding: int - /** - * If the GUI element stretches its size horizontally to other elements. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.horizontally_stretchable View documentation} - */ - horizontally_stretchable: boolean - /** - * If the GUI element stretches its size vertically to other elements. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.vertically_stretchable View documentation} - */ - vertically_stretchable: boolean - /** - * If the GUI element can be squashed (by maximal width of some parent element) horizontally. This is mainly meant - * to be used for scroll-pane The default value is false. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.horizontally_squashable View documentation} - */ - horizontally_squashable: boolean - /** - * If the GUI element can be squashed (by maximal height of some parent element) vertically. This is mainly meant to - * be used for scroll-pane The default (parent) value for scroll pane is true, false otherwise. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.vertically_squashable View documentation} - */ - vertically_squashable: boolean - /** - * How this GUI element handles rich text. - * - * *Can only be used if this is LuaLabelStyle, LuaTextBoxStyle or LuaTextFieldStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.rich_text_setting View documentation} - */ - rich_text_setting: defines.rich_text_setting - /** - * *Can only be used if this is LuaButtonStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.hovered_font_color View documentation} - */ - hovered_font_color: Color - /** - * *Can only be used if this is LuaButtonStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.clicked_font_color View documentation} - */ - clicked_font_color: Color - /** - * *Can only be used if this is LuaButtonStyle or LuaTabStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.disabled_font_color View documentation} - */ - disabled_font_color: Color - /** - * *Can only be used if this is LuaButtonStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.pie_progress_color View documentation} - */ - pie_progress_color: Color - /** - * *Can only be used if this is LuaButtonStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.clicked_vertical_offset View documentation} - */ - clicked_vertical_offset: int - /** - * *Can only be used if this is LuaButtonStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.selected_font_color View documentation} - */ - selected_font_color: Color - /** - * *Can only be used if this is LuaButtonStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.selected_hovered_font_color View documentation} - */ - selected_hovered_font_color: Color - /** - * *Can only be used if this is LuaButtonStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.selected_clicked_font_color View documentation} - */ - selected_clicked_font_color: Color - /** - * *Can only be used if this is LuaButtonStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.strikethrough_color View documentation} - */ - strikethrough_color: Color - /** - * Horizontal space between individual cells. - * - * *Can only be used if this is LuaTableStyle, LuaFlowStyle or LuaHorizontalFlow* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.horizontal_spacing View documentation} - */ - horizontal_spacing: int - /** - * Vertical space between individual cells. - * - * *Can only be used if this is LuaTableStyle, LuaFlowStyle, LuaVerticalFlowStyle or LuaTabbedPaneStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.vertical_spacing View documentation} - */ - vertical_spacing: int - /** - * *Can only be used if this is LuaFrameStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.use_header_filler View documentation} - */ - use_header_filler: boolean - /** - * *Can only be used if this is LuaProgressBarStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.color View documentation} - */ - color: Color - /** - * Array containing the alignment for every column of this table element. Even though this property is marked as - * read-only, the alignment can be changed by indexing the LuaCustomTable, like so: - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.column_alignments View documentation} - * - * @example - * ```lua - * table_element.style.column_alignments[1] = "center" - * ``` - */ - readonly column_alignments: LuaCustomTable - /** - * *Can only be used if this is LabelStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.single_line View documentation} - */ - single_line: boolean - /** - * *Can only be used if this is ScrollPaneStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_top_padding_when_activated View documentation} - */ - extra_top_padding_when_activated: int - /** - * *Can only be used if this is ScrollPaneStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_bottom_padding_when_activated View documentation} - */ - extra_bottom_padding_when_activated: int - /** - * *Can only be used if this is ScrollPaneStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_left_padding_when_activated View documentation} - */ - extra_left_padding_when_activated: int - /** - * *Can only be used if this is ScrollPaneStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_right_padding_when_activated View documentation} - */ - extra_right_padding_when_activated: int - /** - * *Can only be used if this is ScrollPaneStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_top_margin_when_activated View documentation} - */ - extra_top_margin_when_activated: int - /** - * *Can only be used if this is ScrollPaneStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_bottom_margin_when_activated View documentation} - */ - extra_bottom_margin_when_activated: int - /** - * *Can only be used if this is ScrollPaneStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_left_margin_when_activated View documentation} - */ - extra_left_margin_when_activated: int - /** - * *Can only be used if this is ScrollPaneStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_right_margin_when_activated View documentation} - */ - extra_right_margin_when_activated: int - /** - * *Can only be used if this is ImageStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.stretch_image_to_widget_size View documentation} - */ - stretch_image_to_widget_size: boolean - /** - * *Can only be used if this is TabStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.badge_font View documentation} - */ - badge_font: string - /** - * *Can only be used if this is TabStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.badge_horizontal_spacing View documentation} - */ - badge_horizontal_spacing: int - /** - * *Can only be used if this is TabStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.default_badge_font_color View documentation} - */ - default_badge_font_color: Color - /** - * *Can only be used if this is TabStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.selected_badge_font_color View documentation} - */ - selected_badge_font_color: Color - /** - * *Can only be used if this is TabStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.disabled_badge_font_color View documentation} - */ - disabled_badge_font_color: Color - /** - * Sets both minimal and maximal width to the given value. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.width View documentation} - */ - set width(value: int) - /** - * Sets both minimal and maximal height to the given value. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.height View documentation} - */ - set height(value: int) - /** - * Sets both width and height to the given value. Also accepts an array with two values, setting width to the first - * and height to the second one. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.size View documentation} - */ - set size(value: int | int[]) - /** - * Sets top/right/bottom/left paddings to this value. An array with two values sets top/bottom padding to the first - * value and left/right padding to the second value. An array with four values sets top, right, bottom, left padding - * respectively. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.padding View documentation} - */ - set padding(value: int | int[]) - /** - * Sets top/right/bottom/left margins to this value. An array with two values sets top/bottom margin to the first - * value and left/right margin to the second value. An array with four values sets top, right, bottom, left margin - * respectively. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.margin View documentation} - */ - set margin(value: int | int[]) - /** - * Space between the table cell contents and border. Sets top/right/bottom/left cell paddings to this value. - * - * *Can only be used if this is LuaTableStyle* - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.cell_padding View documentation} - */ - set cell_padding(value: int) - /** - * Sets extra_top/right/bottom/left_padding_when_actived to this value. An array with two values sets top/bottom - * padding to the first value and left/right padding to the second value. An array with four values sets top, right, - * bottom, left padding respectively. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_padding_when_activated View documentation} - */ - set extra_padding_when_activated(value: int | int[]) - /** - * Sets extra_top/right/bottom/left_margin_when_activated to this value. An array with two values sets top/bottom - * margin to the first value and left/right margin to the second value. An array with four values sets top, right, - * bottom, left margin respectively. - * - * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_margin_when_activated View documentation} - */ - set extra_margin_when_activated(value: int | int[]) - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaStyle" - /** All methods and properties that this object supports. */ - help(): string -} - -interface BaseSurfaceCreateEntity { - /** The entity prototype name to create. */ - readonly name: string - /** Where to create the entity. */ - readonly position: Position - /** Desired orientation of the entity after creation. */ - readonly direction?: defines.direction - /** Force of the entity, default is enemy. */ - readonly force?: ForceIdentification - /** Entity with health for the new entity to target. */ - readonly target?: LuaEntity - /** Source entity. Used for beams and highlight-boxes. */ - readonly source?: LuaEntity - /** If true, building will attempt to simulate fast-replace building. */ - readonly fast_replace?: boolean - /** If given set the last_user to this player. If fast_replace is true simulate fast replace using this player. */ - readonly player?: PlayerIdentification - /** - * If false while fast_replace is true and player is nil any items from fast-replacing will be deleted instead of - * dropped on the ground. - */ - readonly spill?: boolean - /** If true; {@link defines.events.script_raised_built} will be fired on successful entity creation. */ - readonly raise_built?: boolean - /** If false, the building effect smoke will not be shown around the new entity. */ - readonly create_build_effect_smoke?: boolean - /** If true, entity types that have spawn_decorations property will apply triggers defined in the property. */ - readonly spawn_decorations?: boolean - /** If true, any characters that are in the way of the entity are teleported out of the way. */ - readonly move_stuck_players?: boolean - /** - * If provided, the entity will attempt to pull stored values from this item (for example; creating a spidertron - * from a previously named and mined spidertron) - */ - readonly item?: LuaItemStack -} - -interface AssemblingMachineSurfaceCreateEntity extends BaseSurfaceCreateEntity { - readonly recipe?: string -} - -interface BeamSurfaceCreateEntity extends BaseSurfaceCreateEntity { - /** - * Absolute target position that can be used instead of target entity (entity has precedence if both entity and - * position are defined). - */ - readonly target_position?: Position - /** - * Absolute source position that can be used instead of source entity (entity has precedence if both entity and - * position are defined). - */ - readonly source_position?: Position - /** If set, beam will be destroyed when distance between source and target is greater than this value. */ - readonly max_length?: uint - /** If set, beam will be destroyed after this value of ticks. */ - readonly duration?: uint - /** Source position will be offset by this value when rendering the beam. */ - readonly source_offset?: Vector -} - -interface ContainerSurfaceCreateEntity extends BaseSurfaceCreateEntity { - /** Inventory index where the red limiting bar should be set. */ - readonly bar?: uint -} - -interface CliffSurfaceCreateEntity extends BaseSurfaceCreateEntity { - /** If not specified, `direction` will be used instead. */ - readonly cliff_orientation?: CliffOrientation -} - -interface FlyingTextSurfaceCreateEntity extends BaseSurfaceCreateEntity { - /** The string to show. */ - readonly text: LocalisedString - /** Color of the displayed text. */ - readonly color?: Color - readonly render_player_index?: uint -} - -interface EntityGhostSurfaceCreateEntity extends BaseSurfaceCreateEntity { - /** The prototype name of the entity contained in the ghost. */ - readonly inner_name: string - /** If `false` the ghost entity will not expire. Default is `false`. */ - readonly expires?: boolean -} - -interface FireSurfaceCreateEntity extends BaseSurfaceCreateEntity { - /** With how many small flames should the fire on ground be created. Defaults to the initial flame count of the prototype. */ - readonly initial_ground_flame_count?: uint8 -} - -interface InserterSurfaceCreateEntity extends BaseSurfaceCreateEntity { - readonly conditions: InserterCircuitConditions - readonly filters: InventoryFilter[] -} - -interface ItemEntitySurfaceCreateEntity extends BaseSurfaceCreateEntity { - /** The stack of items to create. */ - readonly stack: SimpleItemStack -} - -interface ItemRequestProxySurfaceCreateEntity extends BaseSurfaceCreateEntity { - /** The target items are to be delivered to. */ - readonly target: LuaEntity - /** The stacks of items to be delivered to target entity from logistic network. */ - readonly modules: Record -} - -interface RollingStockSurfaceCreateEntity extends BaseSurfaceCreateEntity { - /** The orientation of this rolling stock. */ - readonly orientation?: RealOrientation - /** The color of this rolling stock, if it supports colors. */ - readonly color?: Color -} - -interface LocomotiveSurfaceCreateEntity extends BaseSurfaceCreateEntity { - /** Whether the locomotive should snap to an adjacent train stop. Defaults to true. */ - readonly snap_to_train_stop?: boolean -} - -interface LogisticContainerSurfaceCreateEntity extends BaseSurfaceCreateEntity { - readonly request_filters?: InventoryFilter[] -} - -interface ParticleSurfaceCreateEntity extends BaseSurfaceCreateEntity { - readonly movement: Vector - readonly height: float - readonly vertical_speed: float - readonly frame_speed: float -} - -interface ArtilleryFlareSurfaceCreateEntity extends BaseSurfaceCreateEntity { - readonly movement: Vector - readonly height: float - readonly vertical_speed: float - readonly frame_speed: float -} - -interface ProjectileSurfaceCreateEntity extends BaseSurfaceCreateEntity { - readonly speed: double - readonly max_range: double -} - -interface ResourceSurfaceCreateEntity extends BaseSurfaceCreateEntity { - readonly amount: uint - /** - * If colliding trees are removed normally for this resource entity based off the prototype tree removal values. - * Default is true. - */ - readonly enable_tree_removal?: boolean - /** If colliding cliffs are removed. Default is true. */ - readonly enable_cliff_removal?: boolean - /** - * If true, the resource entity will be placed to center of a tile as map generator would place it, otherwise - * standard non-resource grid alignment rules will apply. Default is true. - */ - readonly snap_to_tile_center?: boolean -} - -interface UndergroundBeltSurfaceCreateEntity extends BaseSurfaceCreateEntity { - /** `"output"` or `"input"`; default is `"input"`. */ - readonly type?: "output" | "input" -} - -interface ProgrammableSpeakerSurfaceCreateEntity extends BaseSurfaceCreateEntity { - readonly parameters?: ProgrammableSpeakerParameters - readonly alert_parameters?: ProgrammableSpeakerAlertParameters -} - -interface CharacterCorpseSurfaceCreateEntity extends BaseSurfaceCreateEntity { - readonly inventory_size?: uint - readonly player_index?: uint -} - -interface HighlightBoxSurfaceCreateEntity extends BaseSurfaceCreateEntity { - /** - * The bounding box defining the highlight box using absolute map coordinates. If specified, the `position` - * parameter is ignored, but needs to be present anyways. If not specified, the game falls back to the `source` - * parameter first, then the `target` parameter second. One of these three parameters need to be specified. - */ - readonly bounding_box?: BoundingBox - /** Specifies the graphical appearance (color) of the highlight box. Defaults to `"electricity"`. */ - readonly box_type?: CursorBoxRenderType - /** The player to render the highlight box for. If not provided, it will be rendered for all players. */ - readonly render_player_index?: uint - /** - * The blink interval for this highlight box. Makes it be shown every `blink_interval` ticks. Defaults to `0` - * (constantly shown). - */ - readonly blink_interval?: uint - /** The amount of time in ticks that the highlight box will exist for. Defaults to existing forever. */ - readonly time_to_live?: uint -} - -interface SpeechBubbleSurfaceCreateEntity extends BaseSurfaceCreateEntity { - readonly text: LocalisedString - readonly lifetime?: uint -} - -interface SimpleEntityWithOwnerSurfaceCreateEntity extends BaseSurfaceCreateEntity { - readonly render_player_index?: uint -} - -interface SimpleEntityWithForceSurfaceCreateEntity extends BaseSurfaceCreateEntity { - readonly render_player_index?: uint -} - -type SurfaceCreateEntity = - | AssemblingMachineSurfaceCreateEntity - | BeamSurfaceCreateEntity - | ContainerSurfaceCreateEntity - | CliffSurfaceCreateEntity - | FlyingTextSurfaceCreateEntity - | EntityGhostSurfaceCreateEntity - | FireSurfaceCreateEntity - | InserterSurfaceCreateEntity - | ItemEntitySurfaceCreateEntity - | ItemRequestProxySurfaceCreateEntity - | RollingStockSurfaceCreateEntity - | LocomotiveSurfaceCreateEntity - | LogisticContainerSurfaceCreateEntity - | ParticleSurfaceCreateEntity - | ArtilleryFlareSurfaceCreateEntity - | ProjectileSurfaceCreateEntity - | ResourceSurfaceCreateEntity - | UndergroundBeltSurfaceCreateEntity - | ProgrammableSpeakerSurfaceCreateEntity - | CharacterCorpseSurfaceCreateEntity - | HighlightBoxSurfaceCreateEntity - | SpeechBubbleSurfaceCreateEntity - | SimpleEntityWithOwnerSurfaceCreateEntity - | SimpleEntityWithForceSurfaceCreateEntity - -/** - * A "domain" of the world. Surfaces can only be created and deleted through the API. Surfaces are uniquely identified - * by their name. Every game contains at least the surface "nauvis". - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html View documentation} - * - * @noSelf - */ -interface LuaSurface { - /** - * Get the pollution for a given position. - * - * **Note**: Pollution is stored per chunk, so this will return the same value for all positions in one chunk. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_pollution View documentation} - * - * @example - * ```lua - * game.surfaces[1].get_pollution({1,2}) - * ``` - * - * @param position - */ - get_pollution(position: Position): double - /** - * Check for collisions with terrain or other entities. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.can_place_entity View documentation} - */ - can_place_entity(params: { - /** Name of the entity prototype to check. */ - readonly name: string - /** Where the entity would be placed. */ - readonly position: Position - /** Direction of the placed entity. */ - readonly direction?: defines.direction - /** The force that would place the entity. If not specified, the enemy force is assumed. */ - readonly force?: ForceIdentification - /** Which type of check should be carried out. */ - readonly build_check_type?: defines.build_check_type - /** - * If `true`, entities that can be marked for deconstruction are ignored. Only used if `build_check_type` is - * either `manual_ghost`, `script_ghost` or `blueprint_ghost`. - */ - readonly forced?: boolean - /** The prototype name of the entity contained in the ghost. Only used if `name` is `entity-ghost`. */ - readonly inner_name?: string - }): boolean - /** - * If there exists an entity at the given location that can be fast-replaced with the given entity parameters. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.can_fast_replace View documentation} - */ - can_fast_replace(params: { - /** Name of the entity to check */ - readonly name: string - /** Where the entity would be placed */ - readonly position: Position - /** Direction the entity would be placed */ - readonly direction?: defines.direction - /** The force that would place the entity. If not specified, the enemy force is assumed. */ - readonly force?: ForceIdentification - }): boolean - /** - * Find a specific entity at a specific position. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_entity View documentation} - * - * @example - * ```lua - * game.player.selected.surface.find_entity('filter-inserter', {0,0}) - * ``` - * - * @param entity - Entity to look for - * @param position - Coordinates to look at - * @returns Will be `nil` if no such entity is found. - */ - find_entity(entity: string, position: Position): LuaEntity | undefined - /** - * Find entities in a given area. - * - * If no area is given all entities on the surface are returned. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_entities View documentation} - * - * @example - * Will evaluate to a list of all entities within given area. - * - * ```lua - * game.surfaces["nauvis"].find_entities({{-10, -10}, {10, 10}}) - * ``` - * - * @param area - */ - find_entities(area?: BoundingBox): LuaEntity[] - /** - * Find entities of given type or name in a given area. - * - * If no filters (`name`, `type`, `force`, etc.) are given, returns all entities in the search area. If multiple - * filters are specified, returns only entities matching all given filters. - * - * If no area or position are given, then the entire surface is searched. If position is given, returns entities - * colliding with that position (i.e the given position is within the entity's collision box). If position and - * radius are given, returns entities in that radius of the position. If area is specified, returns entities - * colliding with that area. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_entities_filtered View documentation} - * - * @example - * ```lua - * game.surfaces[1].find_entities_filtered{area = {{-10, -10}, {10, 10}}, type = "resource"} -- gets all resources in the rectangle - * game.surfaces[1].find_entities_filtered{area = {{-10, -10}, {10, 10}}, name = "iron-ore"} -- gets all iron ores in the rectangle - * game.surfaces[1].find_entities_filtered{area = {{-10, -10}, {10, 10}}, name = {"iron-ore", "copper-ore"}} -- gets all iron ore and copper ore in the rectangle - * game.surfaces[1].find_entities_filtered{area = {{-10, -10}, {10, 10}}, force = "player"} -- gets player owned entities in the rectangle - * game.surfaces[1].find_entities_filtered{area = {{-10, -10}, {10, 10}}, limit = 5} -- gets the first 5 entities in the rectangle - * game.surfaces[1].find_entities_filtered{position = {0, 0}, radius = 10} -- gets all entities within 10 tiles of the position [0,0]. - * ``` - */ - find_entities_filtered(params: { - readonly area?: BoundingBox - /** Has precedence over area field. */ - readonly position?: Position - /** If given with position, will return all entities within the radius of the position. */ - readonly radius?: double - readonly name?: string | string[] - readonly type?: string | string[] - readonly ghost_name?: string | string[] - readonly ghost_type?: string | string[] - readonly direction?: defines.direction | defines.direction[] - readonly collision_mask?: CollisionMaskLayer | CollisionMaskLayer[] - readonly force?: ForceIdentification | ForceIdentification[] - readonly to_be_deconstructed?: boolean - readonly to_be_upgraded?: boolean - readonly limit?: uint - /** - * If the filters should be inverted. These filters are: name, type, ghost_name, ghost_type, direction, - * collision_mask, force. - */ - readonly invert?: boolean - }): LuaEntity[] - /** - * Find tiles of a given name in a given area. - * - * If no filters are given returns all tiles in the search area. - * - * If no area or position and radius is given, then the entire surface is searched. If position and radius are - * given, only tiles within the radius of the position are included. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_tiles_filtered View documentation} - */ - find_tiles_filtered(params: { - readonly area?: BoundingBox - /** Ignored if not given with radius. */ - readonly position?: Position - /** If given with position, will return all entities within the radius of the position. */ - readonly radius?: double - readonly name?: string | string[] - readonly limit?: uint - readonly has_hidden_tile?: boolean - readonly collision_mask?: CollisionMaskLayer | CollisionMaskLayer[] - }): LuaTile[] - /** - * Count entities of given type or name in a given area. Works just like - * {@link LuaSurface.find_entities_filtered LuaSurface::find_entities_filtered}, except this only returns the count. - * As it doesn't construct all the wrapper objects, this is more efficient if one is only interested in the number - * of entities. - * - * If no area or position are given, then the entire surface is searched. If position is given, returns entities - * colliding with that position (i.e the given position is within the entity's collision box). If position and - * radius are given, returns entities in that radius of the position. If area is specified, returns entities - * colliding with that area. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.count_entities_filtered View documentation} - */ - count_entities_filtered(params: { - readonly area?: BoundingBox - readonly position?: Position - /** If given with position, will count all entities within the radius of the position. */ - readonly radius?: double - readonly name?: string | string[] - readonly type?: string | string[] - readonly ghost_name?: string | string[] - readonly ghost_type?: string | string[] - readonly direction?: defines.direction | defines.direction[] - readonly collision_mask?: CollisionMaskLayer | CollisionMaskLayer[] - readonly force?: ForceIdentification | ForceIdentification[] - readonly to_be_deconstructed?: boolean - readonly to_be_upgraded?: boolean - readonly limit?: uint - /** - * If the filters should be inverted. These filters are: name, type, ghost_name, ghost_type, direction, - * collision_mask, force. - */ - readonly invert?: boolean - }): uint - /** - * Count tiles of a given name in a given area. Works just like - * {@link LuaSurface.find_tiles_filtered LuaSurface::find_tiles_filtered}, except this only returns the count. As it - * doesn't construct all the wrapper objects, this is more efficient if one is only interested in the number of tiles. - * - * If no area or position and radius is given, then the entire surface is searched. If position and radius are - * given, only tiles within the radius of the position are included. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.count_tiles_filtered View documentation} - */ - count_tiles_filtered(params: { - readonly area?: BoundingBox - /** Ignored if not given with radius. */ - readonly position?: Position - /** If given with position, will return all entities within the radius of the position. */ - readonly radius?: double - readonly name?: string | string[] - readonly limit?: uint - readonly has_hidden_tile?: boolean - readonly collision_mask?: CollisionMaskLayer | CollisionMaskLayer[] - }): uint - /** - * Find a non-colliding position within a given radius. - * - * **Note**: Special care needs to be taken when using a radius of `0`. The game will not stop searching until it - * finds a suitable position, so it is important to make sure such a position exists. One particular case where it - * would not be able to find a solution is running it before any chunks have been generated. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_non_colliding_position View documentation} - * - * @param name - Prototype name of the entity to find a position for. (The bounding box for the collision checking - * is taken from this prototype.) - * @param center - Center of the search area. - * @param radius - Max distance from `center` to search in. A radius of `0` means an infinitely-large search area. - * @param precision - The step length from the given position as it searches, in tiles. Minimum value is `0.01`. - * @param force_to_tile_center - Will only check tile centers. This can be useful when your intent is to place a - * building at the resulting position, as they must generally be placed at tile centers. Default false. - * @returns The non-colliding position. May be `nil` if no suitable position was found. - */ - find_non_colliding_position( - name: string, - center: Position, - radius: double, - precision: double, - force_to_tile_center?: boolean - ): PositionTable | undefined - /** - * Find a non-colliding position within a given rectangle. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_non_colliding_position_in_box View documentation} - * - * @param name - Prototype name of the entity to find a position for. (The bounding box for the collision checking - * is taken from this prototype.) - * @param search_space - The rectangle to search inside. - * @param precision - The step length from the given position as it searches, in tiles. Minimum value is 0.01. - * @param force_to_tile_center - Will only check tile centers. This can be useful when your intent is to place a - * building at the resulting position, as they must generally be placed at tile centers. Default false. - * @returns The non-colliding position. May be `nil` if no suitable position was found. - */ - find_non_colliding_position_in_box( - name: string, - search_space: BoundingBox, - precision: double, - force_to_tile_center?: boolean - ): PositionTable | undefined - /** - * Spill items on the ground centered at a given location. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.spill_item_stack View documentation} - * - * @param position - Center of the spillage - * @param items - Items to spill - * @param enable_looted - When true, each created item will be flagged with the - * {@link LuaEntity.to_be_looted LuaEntity::to_be_looted} flag. - * @param force - When provided (and not `nil`) the items will be marked for deconstruction by this force. - * @param allow_belts - Whether items can be spilled onto belts. Defaults to `true`. - * @returns The created item-on-ground entities. - */ - spill_item_stack( - position: Position, - items: ItemStackIdentification, - enable_looted?: boolean, - force?: LuaForce | string, - allow_belts?: boolean - ): LuaEntity[] - /** - * Find enemy units (entities with type "unit") of a given force within an area. - * - * **Note**: This is more efficient than {@link LuaSurface.find_entities LuaSurface::find_entities}. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_enemy_units View documentation} - * - * @example - * Find all units who would be interested to attack the player, within 100-tile area. - * - * ```lua - * local enemies = game.player.surface.find_enemy_units(game.player.position, 100) - * ``` - * - * @param center - Center of the search area - * @param radius - Radius of the circular search area - * @param force - Force to find enemies of. If not given, uses the player force. - */ - find_enemy_units(center: Position, radius: double, force?: LuaForce | string): LuaEntity[] - /** - * Find units (entities with type "unit") of a given force and force condition within a given area. - * - * **Note**: This is more efficient than {@link LuaSurface.find_entities LuaSurface::find_entities}. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_units View documentation} - * - * @example - * Find friendly units to "player" force - * - * ```lua - * local friendly_units = game.player.surface.find_units({area = {{-10, -10},{10, 10}}, force = "player", condition = "friend") - * ``` - * - * @example - * Find units of "player" force - * - * ```lua - * local units = game.player.surface.find_units({area = {{-10, -10},{10, 10}}, force = "player", condition = "same"}) - * ``` - */ - find_units(params: { - /** Box to find units within. */ - readonly area: BoundingBox - /** Force performing the search. */ - readonly force: LuaForce | string - /** Only forces which meet the condition will be included in the search. */ - readonly condition: ForceCondition - }): LuaEntity[] - /** - * Find the enemy entity-with-force ({@link https://wiki.factorio.com/Military_units_and_structures military entity}) - * closest to the given position. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_nearest_enemy View documentation} - * - * @returns The nearest enemy entity-with-force or `nil` if no enemy could be found within the given area. - */ - find_nearest_enemy(params: { - /** Center of the search area. */ - readonly position: Position - /** Radius of the circular search area. */ - readonly max_distance: double - /** The force the result will be an enemy of. Uses the player force if not specified. */ - readonly force?: ForceIdentification - }): LuaEntity | undefined - /** - * Find the enemy entity-with-owner closest to the given position. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_nearest_enemy_entity_with_owner View documentation} - * - * @returns The nearest enemy entity-with-owner or `nil` if no enemy could be found within the given area. - */ - find_nearest_enemy_entity_with_owner(params: { - /** Center of the search area. */ - readonly position: Position - /** Radius of the circular search area. */ - readonly max_distance: double - /** The force the result will be an enemy of. Uses the player force if not specified. */ - readonly force?: ForceIdentification - }): LuaEntity | undefined - /** - * Give a command to multiple units. This will automatically select suitable units for the task. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.set_multi_command View documentation} - * - * @returns Number of units actually sent. May be less than `count` if not enough units were available. - */ - set_multi_command(params: { - readonly command: Command - /** Number of units to give the command to. */ - readonly unit_count: uint - /** Force of the units this command is to be given to. If not specified, uses the enemy force. */ - readonly force?: ForceIdentification - /** Radius to search for units. The search area is centered on the destination of the command. */ - readonly unit_search_distance?: uint - }): uint - /** - * Create an entity on this surface. - * - * Other attributes may be specified depending on the type of entity: - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.create_entity View documentation} - * - * @example - * ```lua - * asm = game.surfaces[1].create_entity{name = "assembling-machine-1", position = {15, 3}, force = game.forces.player, recipe = "iron-stick"} - * ``` - * - * @example - * Creates a filter inserter with circuit conditions and a filter - * - * ```lua - * game.surfaces[1].create_entity{ - * name = "filter-inserter", position = {20, 15}, force = game.player.force, - * conditions = {red = {name = "wood", count = 3, operator = ">"}, - * green = {name = "iron-ore", count = 1, operator = "<"}, - * logistics = {name = "wood", count = 3, operator = "="}}, - * filters = {{index = 1, name = "iron-ore"}} - * } - * ``` - * - * @example - * Creates a requester chest already set to request 128 iron plates. - * - * ```lua - * game.surfaces[1].create_entity{ - * name = "logistic-chest-requester", position = {game.player.position.x+3, game.player.position.y}, - * force = game.player.force, request_filters = {{index = 1, name = "iron-plate", count = 128}} - * } - * ``` - * - * @example - * ```lua - * game.surfaces[1].create_entity{name = "big-biter", position = {15, 3}, force = game.forces.player} -- Friendly biter - * game.surfaces[1].create_entity{name = "medium-biter", position = {15, 3}, force = game.forces.enemy} -- Enemy biter - * ``` - * - * @example - * Creates a basic inserter at the player's location facing north - * - * ```lua - * game.surfaces[1].create_entity{name = "inserter", position = game.player.position, direction = defines.direction.north} - * ``` - * - * @returns The created entity or `nil` if the creation failed. - */ - create_entity(params: SurfaceCreateEntity): LuaEntity | undefined - create_trivial_smoke(params: { - /** The smoke prototype name to create. */ - readonly name: string - /** Where to create the smoke. */ - readonly position: Position - }): void - /** - * Creates a particle at the given location - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.create_particle View documentation} - */ - create_particle(params: { - /** The particle name. */ - readonly name: string - /** Where to create the particle. */ - readonly position: Position - readonly movement: Vector - readonly height: float - readonly vertical_speed: float - readonly frame_speed: float - }): void - /** - * Create a new unit group at a given position. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.create_unit_group View documentation} - */ - create_unit_group(params: { - /** Initial position of the new unit group. */ - readonly position: Position - /** Force of the new unit group. Defaults to `"enemy"`. */ - readonly force?: ForceIdentification - }): LuaUnitGroup - /** - * Send a group to build a new base. - * - * **Note**: The specified force must be AI-controlled; i.e. `force.ai_controllable` must be `true`. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.build_enemy_base View documentation} - * - * @param position - Location of the new base. - * @param unit_count - Number of biters to send for the base-building task. - * @param force - Force the new base will belong to. Defaults to enemy. - */ - build_enemy_base(position: Position, unit_count: uint, force?: ForceIdentification): void - /** - * Get the tile at a given position. - * - * **Note**: The input position params can also be a single tile position. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_tile View documentation} - * - * @param x - * @param y - */ - get_tile(x: int, y: int): LuaTile - /** - * Set tiles at specified locations. Can automatically correct the edges around modified tiles. - * - * Placing a {@link LuaTilePrototype.mineable_properties mineable} tile on top of a non-mineable one will turn the - * latter into the {@link LuaTile.hidden_tile LuaTile::hidden_tile} for that tile. Placing a mineable tile on a - * mineable one or a non-mineable tile on a non-mineable one will not modify the hidden tile. This restriction can - * however be circumvented by using {@link LuaSurface.set_hidden_tile LuaSurface::set_hidden_tile}. - * - * **Note**: It is recommended to call this method once for all the tiles you want to change rather than calling it - * individually for every tile. As the tile correction is used after every step, calling it one by one could cause - * the tile correction logic to redo some of the changes. Also, many small API calls are generally more performance - * intensive than one big one. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.set_tiles View documentation} - * - * @param tiles - * @param correct_tiles - If `false`, the correction logic is not applied to the changed tiles. Defaults to `true`. - * @param remove_colliding_entities - `true`, `false`, or `abort_on_collision`. Defaults to `true`. - * @param remove_colliding_decoratives - `true` or `false`. Defaults to `true`. - * @param raise_event - `true` or `false`. Defaults to `false`. - */ - set_tiles( - tiles: Tile[], - correct_tiles?: boolean, - remove_colliding_entities?: boolean | string, - remove_colliding_decoratives?: boolean, - raise_event?: boolean - ): void - /** - * Spawn pollution at the given position. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.pollute View documentation} - * - * @param source - Where to spawn the pollution. - * @param amount - How much pollution to add. - */ - pollute(source: Position, amount: double): void - /** - * Get an iterator going over every chunk on this surface. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_chunks View documentation} - */ - get_chunks(): LuaChunkIterator - /** - * Is a given chunk generated? - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.is_chunk_generated View documentation} - * - * @param position - The chunk's position. - */ - is_chunk_generated(position: ChunkPosition): boolean - /** - * Request that the game's map generator generate chunks at the given position for the given radius on this surface. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.request_to_generate_chunks View documentation} - * - * @param position - Where to generate the new chunks. - * @param radius - The chunk radius from `position` to generate new chunks in. - */ - request_to_generate_chunks(position: Position, radius: uint): void - /** - * Blocks and generates all chunks that have been requested using all available threads. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.force_generate_chunk_requests View documentation} - */ - force_generate_chunk_requests(): void - /** - * Set generated status of a chunk. Useful when copying chunks. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.set_chunk_generated_status View documentation} - * - * @param position - The chunk's position. - * @param status - The chunk's new status. - */ - set_chunk_generated_status(position: ChunkPosition, status: defines.chunk_generated_status): void - /** - * Find the logistic network that covers a given position. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_logistic_network_by_position View documentation} - * - * @param position - * @param force - Force the logistic network should belong to. - * @returns The found network or `nil` if no such network was found. - */ - find_logistic_network_by_position(position: Position, force: ForceIdentification): LuaLogisticNetwork | undefined - /** - * Finds all of the logistics networks whose construction area intersects with the given position. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_logistic_networks_by_construction_area View documentation} - * - * @param position - * @param force - Force the logistic networks should belong to. - */ - find_logistic_networks_by_construction_area(position: Position, force: ForceIdentification): LuaLogisticNetwork[] - /** - * Place a deconstruction request. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.deconstruct_area View documentation} - */ - deconstruct_area(params: { - /** The area to mark for deconstruction. */ - readonly area: BoundingBox - /** The force whose bots should perform the deconstruction. */ - readonly force: ForceIdentification - /** The player to set the last_user to if any. */ - readonly player?: PlayerIdentification - /** If chunks covered by fog-of-war are skipped. */ - readonly skip_fog_of_war?: boolean - /** The deconstruction item to use if any. */ - readonly item?: LuaItemStack - }): void - /** - * Cancel a deconstruction order. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.cancel_deconstruct_area View documentation} - */ - cancel_deconstruct_area(params: { - /** The area to cancel deconstruction orders in. */ - readonly area: BoundingBox - /** The force whose deconstruction orders to cancel. */ - readonly force: ForceIdentification - /** The player to set the last_user to if any. */ - readonly player?: PlayerIdentification - /** If chunks covered by fog-of-war are skipped. */ - readonly skip_fog_of_war?: boolean - /** The deconstruction item to use if any. */ - readonly item?: LuaItemStack - }): void - /** - * Place an upgrade request. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.upgrade_area View documentation} - */ - upgrade_area(params: { - /** The area to mark for upgrade. */ - readonly area: BoundingBox - /** The force whose bots should perform the upgrade. */ - readonly force: ForceIdentification - /** The player to set the last_user to if any. */ - readonly player?: PlayerIdentification - /** If chunks covered by fog-of-war are skipped. */ - readonly skip_fog_of_war?: boolean - /** The upgrade item to use. */ - readonly item: LuaItemStack - }): void - /** - * Cancel a upgrade order. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.cancel_upgrade_area View documentation} - */ - cancel_upgrade_area(params: { - /** The area to cancel upgrade orders in. */ - readonly area: BoundingBox - /** The force whose upgrade orders to cancel. */ - readonly force: ForceIdentification - /** The player to set the last_user to if any. */ - readonly player?: PlayerIdentification - /** If chunks covered by fog-of-war are skipped. */ - readonly skip_fog_of_war?: boolean - /** The upgrade item to use if any. */ - readonly item?: LuaItemStack - }): void - /** - * The hidden tile name or `nil` if there isn't one for the given position. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_hidden_tile View documentation} - * - * @param position - The tile position. - */ - get_hidden_tile(position: TilePosition): string | undefined - /** - * Set the hidden tile for the specified position. While during normal gameplay only - * {@link LuaTilePrototype.mineable_properties non-mineable} tiles can become hidden, this method allows any kind of - * tile to be set as the hidden one. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.set_hidden_tile View documentation} - * - * @param position - The tile position. - * @param tile - The new hidden tile or `nil` to clear the hidden tile. - */ - set_hidden_tile(position: TilePosition, tile: string | LuaTilePrototype | undefined): void - /** - * Gets all tiles of the given types that are connected horizontally or vertically to the given tile position - * including the given tile position. - * - * **Note**: This won't find tiles in non-generated chunks. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_connected_tiles View documentation} - * - * @param position - The tile position to start at. - * @param tiles - The tiles to search for. - * @returns The resulting set of tiles. - */ - get_connected_tiles(position: Position, tiles: string[]): PositionTable[] - /** - * **Note**: This won't delete the chunk immediately. Chunks are deleted at the end of the current tick. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.delete_chunk View documentation} - * - * @param position - The chunk position to delete - */ - delete_chunk(position: ChunkPosition): void - /** - * Regenerate autoplacement of some entities on this surface. This can be used to autoplace newly-added entities. - * - * **Note**: All specified entity prototypes must be autoplacable. If nothing is given all entities are generated on - * all chunks. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.regenerate_entity View documentation} - * - * @param entities - Prototype names of entity or entities to autoplace. When `nil` all entities with an autoplace are used. - * @param chunks - The chunk positions to regenerate the entities on. If not given all chunks are regenerated. Note - * chunks with status < entities are ignored. - */ - regenerate_entity(entities?: string | string[], chunks?: ChunkPosition[]): void - /** - * Regenerate autoplacement of some decoratives on this surface. This can be used to autoplace newly-added decoratives. - * - * **Note**: All specified decorative prototypes must be autoplacable. If nothing is given all decoratives are - * generated on all chunks. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.regenerate_decorative View documentation} - * - * @param decoratives - Prototype names of decorative or decoratives to autoplace. When `nil` all decoratives with - * an autoplace are used. - * @param chunks - The chunk positions to regenerate the entities on. If not given all chunks are regenerated. Note - * chunks with status < entities are ignored. - */ - regenerate_decorative(decoratives?: string | string[], chunks?: ChunkPosition[]): void - /** - * Print text to the chat console of all players on this surface. - * - * **Note**: Messages that are identical to a message sent in the last 60 ticks are not printed again. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.print View documentation} - * - * @param message - * @param color - */ - print(message: LocalisedString, color?: Color): void - /** - * Removes all decoratives from the given area. If no area and no position are given, then the entire surface is searched. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.destroy_decoratives View documentation} - */ - destroy_decoratives(params: { - readonly area?: BoundingBox - readonly position?: TilePosition - readonly name?: string | string[] | LuaDecorativePrototype | LuaDecorativePrototype[] - readonly limit?: uint - /** If the filters should be inverted. */ - readonly invert?: boolean - }): void - /** - * Adds the given decoratives to the surface. - * - * **Note**: This will merge decoratives of the same type that already exist effectively increasing the "amount" field. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.create_decoratives View documentation} - */ - create_decoratives(params: { - /** If collision should be checked against entities/tiles. */ - readonly check_collision?: boolean - readonly decoratives: Decorative[] - }): void - /** - * Find decoratives of a given name in a given area. - * - * If no filters are given, returns all decoratives in the search area. If multiple filters are specified, returns - * only decoratives matching every given filter. If no area and no position are given, the entire surface is searched. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_decoratives_filtered View documentation} - * - * @example - * ```lua - * game.surfaces[1].find_decoratives_filtered{area = {{-10, -10}, {10, 10}}, name = "sand-decal"} -- gets all sand-decals in the rectangle - * game.surfaces[1].find_decoratives_filtered{area = {{-10, -10}, {10, 10}}, limit = 5} -- gets the first 5 decoratives in the rectangle - * ``` - */ - find_decoratives_filtered(params: { - readonly area?: BoundingBox - readonly position?: TilePosition - readonly name?: string | string[] | LuaDecorativePrototype | LuaDecorativePrototype[] - readonly limit?: uint - /** If the filters should be inverted. */ - readonly invert?: boolean - }): DecorativeResult[] - /** - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_trains View documentation} - * - * @param force - If given only trains matching this force are returned. - */ - get_trains(force?: ForceIdentification): LuaTrain[] - /** - * Clears all pollution on this surface. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.clear_pollution View documentation} - */ - clear_pollution(): void - /** - * Play a sound for every player on this surface. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.play_sound View documentation} - */ - play_sound(params: { - /** The sound to play. */ - readonly path: SoundPath - /** Where the sound should be played. If not given, it's played at the current position of each player. */ - readonly position?: Position - /** The volume of the sound to play. Must be between 0 and 1 inclusive. */ - readonly volume_modifier?: double - /** The volume mixer to play the sound through. Defaults to the default mixer for the given sound type. */ - readonly override_sound_type?: SoundType - }): void - /** - * Gets the resource amount of all resources on this surface - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_resource_counts View documentation} - */ - get_resource_counts(): Record - /** - * Gets a random generated chunk position or 0,0 if no chunks have been generated on this surface. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_random_chunk View documentation} - */ - get_random_chunk(): ChunkPositionTable - /** - * Clones the given area. - * - * **Note**: {@link defines.events.on_entity_cloned} is raised for each entity, and then - * {@link defines.events.on_area_cloned} is raised. - * - * **Note**: Entities are cloned in an order such that they can always be created, eg rails before trains. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.clone_area View documentation} - */ - clone_area(params: { - readonly source_area: BoundingBox - readonly destination_area: BoundingBox - readonly destination_surface?: SurfaceIdentification - readonly destination_force?: LuaForce | string - /** If tiles should be cloned */ - readonly clone_tiles?: boolean - /** If entities should be cloned */ - readonly clone_entities?: boolean - /** If decoratives should be cloned */ - readonly clone_decoratives?: boolean - /** If the destination entities should be cleared */ - readonly clear_destination_entities?: boolean - /** If the destination decoratives should be cleared */ - readonly clear_destination_decoratives?: boolean - /** If the destination surface should be expanded when destination_area is outside current bounds. Default false. */ - readonly expand_map?: boolean - /** If true, the building effect smoke will be shown around the new entities. */ - readonly create_build_effect_smoke?: boolean - }): void - /** - * Clones the given area. - * - * **Note**: {@link defines.events.on_entity_cloned} is raised for each entity, and then - * {@link defines.events.on_area_cloned} is raised. - * - * **Note**: Entities are cloned in an order such that they can always be created, eg rails before trains. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.clone_brush View documentation} - */ - clone_brush(params: { - readonly source_offset: TilePosition - readonly destination_offset: TilePosition - readonly source_positions: TilePosition[] - readonly destination_surface?: SurfaceIdentification - readonly destination_force?: LuaForce | string - /** If tiles should be cloned */ - readonly clone_tiles?: boolean - /** If entities should be cloned */ - readonly clone_entities?: boolean - /** If decoratives should be cloned */ - readonly clone_decoratives?: boolean - /** If the destination entities should be cleared */ - readonly clear_destination_entities?: boolean - /** If the destination decoratives should be cleared */ - readonly clear_destination_decoratives?: boolean - /** If the destination surface should be expanded when destination_area is outside current bounds. Default false. */ - readonly expand_map?: boolean - /** If manual-style collision checks should be done. */ - readonly manual_collision_mode?: boolean - /** If true, the building effect smoke will be shown around the new entities. */ - readonly create_build_effect_smoke?: boolean - }): void - /** - * Clones the given entities. - * - * **Note**: {@link defines.events.on_entity_cloned} is raised for each entity. - * - * **Note**: Entities are cloned in an order such that they can always be created, eg rails before trains. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.clone_entities View documentation} - */ - clone_entities(params: { - readonly entities: LuaEntity[] - readonly destination_offset: Vector - readonly destination_surface?: SurfaceIdentification - readonly destination_force?: ForceIdentification - readonly snap_to_grid?: boolean - /** If true, the building effect smoke will be shown around the new entities. */ - readonly create_build_effect_smoke?: boolean - }): void - /** - * Clears this surface deleting all entities and chunks on it. - * - * **Note**: This won't clear the surface immediately. It will be cleared at the end of the current tick. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.clear View documentation} - * - * @param ignore_characters - Whether characters on this surface that are connected to or associated with players - * should be ignored (not destroyed). - */ - clear(ignore_characters?: boolean): void - /** - * Generates a path with the specified constraints (as an array of {@link PathfinderWaypoint PathfinderWaypoints}) - * using the unit pathfinding algorithm. This path can be used to emulate pathing behavior by script for non-unit - * entities. If you want to command actual units to move, use the - * {@link LuaEntity.set_command LuaEntity::set_command} functionality instead. - * - * The resulting path is ultimately returned asynchronously via - * {@link OnScriptPathRequestFinishedEvent on_script_path_request_finished}. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.request_path View documentation} - * - * @returns A unique handle to identify this call when - * {@link OnScriptPathRequestFinishedEvent on_script_path_request_finished} fires. - */ - request_path(params: { - /** The dimensions of the object that's supposed to travel the path. */ - readonly bounding_box: BoundingBox - /** The list of masks the `bounding_box` collides with. */ - readonly collision_mask: CollisionMask | string[] - /** The position from which to start pathfinding. */ - readonly start: Position - /** The position to find a path to. */ - readonly goal: Position - /** The force for which to generate the path, determining which gates can be opened for example. */ - readonly force: ForceIdentification - /** How close the pathfinder needs to get to its `goal` (in tiles). Defaults to `1`. */ - readonly radius?: double - /** Flags that affect pathfinder behavior. */ - readonly pathfind_flags?: PathfinderFlags - /** Whether the path request can open gates. Defaults to `false`. */ - readonly can_open_gates?: boolean - /** - * Defines how coarse the pathfinder's grid is. Smaller values mean a coarser grid (negative numbers allowed). - * Defaults to `0`. - */ - readonly path_resolution_modifier?: int - /** Makes the pathfinder ignore collisions with this entity if it is given. */ - readonly entity_to_ignore?: LuaEntity - }): uint - /** - * Gets the script areas that match the given name or if no name is given all areas are returned. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_script_areas View documentation} - * - * @param name - */ - get_script_areas(name?: string): ScriptArea[] - /** - * Gets the first script area by name or id. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_script_area View documentation} - * - * @param key - The name or id of the area to get. - */ - get_script_area(key?: string | uint): ScriptArea - /** - * Sets the given script area to the new values. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.edit_script_area View documentation} - * - * @param id - The area to edit. - * @param area - */ - edit_script_area(id: uint, area: ScriptArea): void - /** - * Adds the given script area. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.add_script_area View documentation} - * - * @param area - * @returns The id of the created area. - */ - add_script_area(area: ScriptArea): uint - /** - * Removes the given script area. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.remove_script_area View documentation} - * - * @param id - * @returns If the area was actually removed. False when it didn't exist. - */ - remove_script_area(id: uint): boolean - /** - * Gets the script positions that match the given name or if no name is given all positions are returned. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_script_positions View documentation} - * - * @param name - */ - get_script_positions(name?: string): ScriptPosition[] - /** - * Gets the first script position by name or id. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_script_position View documentation} - * - * @param key - The name or id of the position to get. - */ - get_script_position(key?: string | uint): ScriptPosition - /** - * Sets the given script position to the new values. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.edit_script_position View documentation} - * - * @param id - The position to edit. - * @param area - */ - edit_script_position(id: uint, area: ScriptPosition): void - /** - * Adds the given script position. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.add_script_position View documentation} - * - * @param area - * @returns The id of the created position. - */ - add_script_position(area: ScriptPosition): uint - /** - * Removes the given script position. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.remove_script_position View documentation} - * - * @param id - * @returns If the position was actually removed. False when it didn't exist. - */ - remove_script_position(id: uint): boolean - /** - * Gets the map exchange string for the current map generation settings of this surface. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_map_exchange_string View documentation} - */ - get_map_exchange_string(): string - /** - * Gets the starting area radius of this surface. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_starting_area_radius View documentation} - */ - get_starting_area_radius(): double - /** - * Gets the closest entity in the list to this position. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_closest View documentation} - * - * @param position - * @param entities - The Entities to check - */ - get_closest(position: Position, entities: LuaEntity[]): LuaEntity - /** - * Gets train stops matching the given filters. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_train_stops View documentation} - */ - get_train_stops(params?: { readonly name?: string | string[]; readonly force?: ForceIdentification }): LuaEntity[] - /** - * Gets the total amount of pollution on the surface by iterating over all of the chunks containing pollution. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_total_pollution View documentation} - */ - get_total_pollution(): double - /** - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.entity_prototype_collides View documentation} - * - * @param prototype - The entity prototype to check - * @param position - The position to check - * @param use_map_generation_bounding_box - If the map generation bounding box should be used instead of the - * collision bounding box - * @param direction - */ - entity_prototype_collides( - prototype: EntityPrototypeIdentification, - position: Position, - use_map_generation_bounding_box: boolean, - direction?: defines.direction - ): void - /** - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.decorative_prototype_collides View documentation} - * - * @param prototype - The decorative prototype to check - * @param position - The position to check - */ - decorative_prototype_collides(prototype: string, position: Position): void - /** - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.calculate_tile_properties View documentation} - * - * @param property_names - Names of properties (e.g. "elevation") to calculate - * @param positions - Positions for which to calculate property values - * @returns Table of property value lists, keyed by property name - */ - calculate_tile_properties(property_names: string[], positions: Position[]): Record - /** - * Returns all the entities with force on this chunk for the given force. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_entities_with_force View documentation} - * - * @param position - The chunk's position. - * @param force - Entities of this force will be returned. - */ - get_entities_with_force(position: ChunkPosition, force: LuaForce | string): LuaEntity[] - /** - * Sets the given area to the checkerboard lab tiles. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.build_checkerboard View documentation} - * - * @param area - The tile area. - */ - build_checkerboard(area: BoundingBox): void - /** - * The name of this surface. Names are unique among surfaces. - * - * **Note**: the default surface can't be renamed. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.name View documentation} - */ - name: string - /** - * Unique ID associated with this surface. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.index View documentation} - */ - readonly index: uint - /** - * The generation settings for this surface. These can be modified to after surface generation, but note that this - * will not retroactively update the surface. To manually adjust it, - * {@link LuaSurface.regenerate_entity LuaSurface::regenerate_entity}, - * {@link LuaSurface.regenerate_decorative LuaSurface::regenerate_decorative} and - * {@link LuaSurface.delete_chunk LuaSurface::delete_chunk} can be used. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.map_gen_settings View documentation} - */ - map_gen_settings: MapGenSettings - /** - * When set to true, new chunks will be generated with lab tiles, instead of using the surface's map generation settings. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.generate_with_lab_tiles View documentation} - */ - generate_with_lab_tiles: boolean - /** - * When set to true, the sun will always shine. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.always_day View documentation} - */ - always_day: boolean - /** - * Current time of day, as a number in range [0, 1). - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.daytime View documentation} - */ - daytime: float - /** - * Amount of darkness at the current time. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.darkness View documentation} - */ - readonly darkness: float - /** - * Current wind speed. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.wind_speed View documentation} - */ - wind_speed: double - /** - * Current wind direction. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.wind_orientation View documentation} - */ - wind_orientation: RealOrientation - /** - * Change in wind orientation per tick. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.wind_orientation_change View documentation} - */ - wind_orientation_change: double - /** - * Is peaceful mode enabled on this surface? - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.peaceful_mode View documentation} - */ - peaceful_mode: boolean - /** - * True if daytime is currently frozen. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.freeze_daytime View documentation} - */ - freeze_daytime: boolean - /** - * The number of ticks per day for this surface. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.ticks_per_day View documentation} - */ - ticks_per_day: uint - /** - * The daytime when dusk starts. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.dusk View documentation} - */ - dusk: double - /** - * The daytime when dawn starts. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.dawn View documentation} - */ - dawn: double - /** - * The daytime when evening starts. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.evening View documentation} - */ - evening: double - /** - * The daytime when morning starts. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.morning View documentation} - */ - morning: double - /** - * The multiplier of solar power on this surface. Cannot be less than 0. - * - * **Note**: Solar equipment is still limited to its maximum power output. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.solar_power_multiplier View documentation} - */ - solar_power_multiplier: double - /** - * The minimal brightness during the night. Default is `0.15`. The value has an effect on the game simalution only, - * it doesn't have any effect on rendering. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.min_brightness View documentation} - */ - min_brightness: double - /** - * Defines how surface daytime brightness influences each color channel of the current color lookup table (LUT). - * - * The LUT is multiplied by `((1 - weight) + brightness * weight)` and result is clamped to range [0, 1]. - * - * Default is `{0, 0, 0}`, which means no influence. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.brightness_visual_weights View documentation} - * - * @example - * Makes night on the surface pitch black, assuming {@link LuaSurface.min_brightness LuaSurface::min_brightness} being set to default value `0.15`. - * - * ```lua - * game.surfaces[1].brightness_visual_weights = { 1 / 0.85, 1 / 0.85, 1 / 0.85 } - * ``` - */ - brightness_visual_weights: ColorModifier - /** - * If clouds are shown on this surface. - * - * **Note**: If false, clouds are never shown. If true the player must also have clouds enabled in graphics settings - * for them to be shown. - * - * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.show_clouds View documentation} - */ - show_clouds: boolean - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaSurface" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * One research item. - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html View documentation} - * - * @noSelf - */ -interface LuaTechnology { - /** - * Reload this technology from its prototype. - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.reload View documentation} - */ - reload(): void - /** - * The force this technology belongs to. - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.force View documentation} - */ - readonly force: LuaForce - /** - * Name of this technology. - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.name View documentation} - */ - readonly name: string - /** - * Localised name of this technology. - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.localised_name View documentation} - */ - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * The prototype of this technology. - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.prototype View documentation} - */ - readonly prototype: LuaTechnologyPrototype - /** - * Can this technology be researched? - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.enabled View documentation} - */ - enabled: boolean - /** - * If this technology will be visible in the research GUI even though it is disabled. - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.visible_when_disabled View documentation} - */ - visible_when_disabled: boolean - /** - * Is this an upgrade-type research? - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.upgrade View documentation} - */ - readonly upgrade: boolean - /** - * Has this technology been researched? Switching from `false` to `true` will trigger the technology advancement - * perks; switching from `true` to `false` will reverse them. - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.researched View documentation} - */ - researched: boolean - /** - * Prerequisites of this technology. The result maps technology name to the {@link LuaTechnology} object. - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.prerequisites View documentation} - */ - readonly prerequisites: Record - /** - * Ingredients labs will require to research this technology. - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.research_unit_ingredients View documentation} - * - * @see {@link LuaTechnology.research_unit_count} - */ - readonly research_unit_ingredients: Ingredient[] - /** - * Effects applied when this technology is researched. - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.effects View documentation} - */ - readonly effects: TechnologyModifier[] - /** - * Number of research units required for this technology. - * - * **Note**: This is multiplied by the current research cost multiplier, unless - * {@link LuaTechnologyPrototype.ignore_tech_cost_multiplier LuaTechnologyPrototype::ignore_tech_cost_multiplier} is `true`. - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.research_unit_count View documentation} - * - * @see {@link LuaTechnology.research_unit_ingredients} - */ - readonly research_unit_count: uint - /** - * Amount of energy required to finish a unit of research. - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.research_unit_energy View documentation} - */ - readonly research_unit_energy: double - /** - * Order string for this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.order View documentation} - */ - readonly order: string - /** - * The current level of this technology. For level-based technology writing to this is the same as researching the - * technology to the *previous* level. Writing the level will set - * {@link LuaTechnology.enabled LuaTechnology::enabled} to `true`. - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.level View documentation} - */ - level: uint - /** - * The count formula used for this infinite research or nil if this isn't an infinite research. - * - * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.research_unit_count_formula View documentation} - * - * @see {@link LuaGameScript.evaluate_expression} - */ - readonly research_unit_count_formula: string | undefined - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaTechnology" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A Technology prototype. - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html View documentation} - * - * @noSelf - */ -interface LuaTechnologyPrototype { - /** - * Name of this technology. - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.name View documentation} - */ - readonly name: string - /** - * Localised name of this technology. - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.localised_name View documentation} - */ - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * If this technology prototype is enabled by default (enabled at the beginning of a game). - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.enabled View documentation} - */ - readonly enabled: boolean - /** - * If this technology prototype is hidden. - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.hidden View documentation} - */ - readonly hidden: boolean - /** - * If this technology will be visible in the research GUI even though it is disabled. - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.visible_when_disabled View documentation} - */ - readonly visible_when_disabled: boolean - /** - * If this technology ignores the technology cost multiplier setting. - * - * **Note**: {@link LuaTechnologyPrototype.research_unit_count LuaTechnologyPrototype::research_unit_count} will - * already take this setting into account. - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.ignore_tech_cost_multiplier View documentation} - */ - readonly ignore_tech_cost_multiplier: boolean - /** - * If the is technology prototype is an upgrade to some other technology. - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.upgrade View documentation} - */ - readonly upgrade: boolean - /** - * Prerequisites of this technology. The result maps technology name to the {@link LuaTechnologyPrototype} object. - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.prerequisites View documentation} - */ - readonly prerequisites: Record - /** - * Ingredients labs will require to research this technology. - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.research_unit_ingredients View documentation} - * - * @see {@link LuaTechnologyPrototype.research_unit_count} - */ - readonly research_unit_ingredients: Ingredient[] - /** - * Effects applied when this technology is researched. - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.effects View documentation} - */ - readonly effects: TechnologyModifier[] - /** - * Number of research units required for this technology. - * - * **Note**: This is multiplied by the current research cost multiplier, unless - * {@link LuaTechnologyPrototype.ignore_tech_cost_multiplier LuaTechnologyPrototype::ignore_tech_cost_multiplier} is `true`. - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.research_unit_count View documentation} - * - * @see {@link LuaTechnologyPrototype.research_unit_ingredients} - */ - readonly research_unit_count: uint - /** - * Amount of energy required to finish a unit of research. - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.research_unit_energy View documentation} - */ - readonly research_unit_energy: double - /** - * Order string for this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.order View documentation} - */ - readonly order: string - /** - * The level of this research. - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.level View documentation} - */ - readonly level: uint - /** - * The max level of this research. - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.max_level View documentation} - */ - readonly max_level: uint - /** - * The count formula used for this infinite research or nil if this isn't an infinite research. - * - * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.research_unit_count_formula View documentation} - * - * @see {@link LuaGameScript.evaluate_expression} - */ - readonly research_unit_count_formula: string | undefined - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaTechnologyPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A single "square" on the map. - * - * {@link https://lua-api.factorio.com/next/LuaTile.html View documentation} - * - * @noSelf - */ -interface LuaTile { - /** - * What type of things can collide with this tile? - * - * {@link https://lua-api.factorio.com/next/LuaTile.html#LuaTile.collides_with View documentation} - * - * @example - * Check if the character would collide with a tile - * - * ```lua - * game.player.print(tostring(game.player.surface.get_tile(1, 1).collides_with("player-layer"))) - * ``` - * - * @param layer - */ - collides_with(layer: CollisionMaskLayer): boolean - /** - * Is this tile marked for deconstruction? - * - * {@link https://lua-api.factorio.com/next/LuaTile.html#LuaTile.to_be_deconstructed View documentation} - */ - to_be_deconstructed(): boolean - /** - * Orders deconstruction of this tile by the given force. - * - * {@link https://lua-api.factorio.com/next/LuaTile.html#LuaTile.order_deconstruction View documentation} - * - * @param force - The force whose robots are supposed to do the deconstruction. - * @param player - The player to set the last_user to if any. - * @returns The deconstructible tile proxy created if any or `nil`. - */ - order_deconstruction(force: ForceIdentification, player?: PlayerIdentification): LuaEntity | undefined - /** - * Cancels deconstruction if it is scheduled, does nothing otherwise. - * - * {@link https://lua-api.factorio.com/next/LuaTile.html#LuaTile.cancel_deconstruction View documentation} - * - * @param force - The force who did the deconstruction order. - * @param player - The player to set the last_user to if any. - */ - cancel_deconstruction(force: ForceIdentification, player?: PlayerIdentification): void - /** - * Prototype name of this tile. E.g. `"sand-3"` or `"grass-2"`. - * - * {@link https://lua-api.factorio.com/next/LuaTile.html#LuaTile.name View documentation} - */ - readonly name: string - readonly prototype: LuaTilePrototype - /** - * The position this tile references. - * - * {@link https://lua-api.factorio.com/next/LuaTile.html#LuaTile.position View documentation} - */ - readonly position: PositionTable - /** - * The name of the {@link LuaTilePrototype} hidden under this tile or `nil` if there is no hidden tile. During normal - * gameplay, only {@link LuaTilePrototype.mineable_properties non-mineable} tiles can become hidden. This can however - * be circumvented with {@link LuaSurface.set_hidden_tile LuaSurface::set_hidden_tile}. - * - * {@link https://lua-api.factorio.com/next/LuaTile.html#LuaTile.hidden_tile View documentation} - */ - readonly hidden_tile: string | undefined - /** - * The surface this tile is on. - * - * {@link https://lua-api.factorio.com/next/LuaTile.html#LuaTile.surface View documentation} - */ - readonly surface: LuaSurface - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaTile" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a tile. - * - * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html View documentation} - * - * @noSelf - */ -interface LuaTilePrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * The collision mask this tile uses - * - * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.collision_mask View documentation} - */ - readonly collision_mask: CollisionMask - readonly collision_mask_with_flags: CollisionMaskWithFlags - readonly layer: uint - /** - * Autoplace specification for this prototype. `nil` if none. - * - * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.autoplace_specification View documentation} - */ - readonly autoplace_specification: AutoplaceSpecification | undefined - readonly walking_speed_modifier: float - readonly vehicle_friction_modifier: float - readonly map_color: ColorTable - /** - * The probability that decorative entities will be removed from on top of this tile when this tile is generated. - * - * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.decorative_removal_probability View documentation} - */ - readonly decorative_removal_probability: float - readonly automatic_neighbors: boolean - readonly allowed_neighbors: Record - /** - * If this tile needs correction logic applied when it's generated in the world.. - * - * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.needs_correction View documentation} - */ - readonly needs_correction: boolean - readonly mineable_properties: { - /** Is this tile mineable at all? */ - readonly minable: boolean - /** Energy required to mine a tile. */ - readonly miningtime: double - /** - * Prototype name of the particle produced when mining this tile. Will only be present if this tile produces any - * particle during mining. - */ - readonly miningparticle?: string - /** Products obtained by mining this tile. */ - readonly products: Product[] - } - /** - * The next direction of this tile or `nil` - used when a tile has multiple directions (such as hazard concrete) - * - * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.next_direction View documentation} - */ - readonly next_direction: LuaTilePrototype | undefined - /** - * Items that when placed will produce this tile. It is a dictionary indexed by the item prototype name. - * - * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.items_to_place_this View documentation} - */ - readonly items_to_place_this: SimpleItemStack[] - /** - * False if this tile is not allowed in blueprints regardless of the ability to build it. - * - * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.can_be_part_of_blueprint View documentation} - */ - readonly can_be_part_of_blueprint: boolean - /** - * Amount of pollution emissions per second this tile will absorb. - * - * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.emissions_per_second View documentation} - */ - readonly emissions_per_second: double - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaTilePrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A train. Trains are a sequence of connected rolling stocks -- locomotives and wagons. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html View documentation} - * - * @noSelf - */ -interface LuaTrain { - /** - * Get the amount of a particular item stored in the train. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.get_item_count View documentation} - * - * @param item - Item name to count. If not given, counts all items. - */ - get_item_count(item?: string): uint - /** - * Get a mapping of the train's inventory. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.get_contents View documentation} - * - * @returns The counts, indexed by item names. - */ - get_contents(): Record - /** - * Remove some items from the train. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.remove_item View documentation} - * - * @param stack - The amount and type of items to remove - * @returns Number of items actually removed. - */ - remove_item(stack: ItemStackIdentification): uint - /** - * Insert a stack into the train. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.insert View documentation} - * - * @param stack - */ - insert(stack: ItemStackIdentification): void - /** - * Clear all items in this train. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.clear_items_inside View documentation} - */ - clear_items_inside(): void - /** - * Checks if the path is invalid and tries to re-path if it isn't. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.recalculate_path View documentation} - * - * @param force - Forces the train to re-path regardless of the current path being valid or not. - * @returns If the train has a path after the repath attempt. - */ - recalculate_path(force?: boolean): boolean - /** - * Get the amount of a particular fluid stored in the train. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.get_fluid_count View documentation} - * - * @param fluid - Fluid name to count. If not given, counts all fluids. - */ - get_fluid_count(fluid?: string): double - /** - * Gets a mapping of the train's fluid inventory. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.get_fluid_contents View documentation} - * - * @returns The counts, indexed by fluid names. - */ - get_fluid_contents(): Record - /** - * Remove some fluid from the train. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.remove_fluid View documentation} - * - * @param fluid - * @returns The amount of fluid actually removed. - */ - remove_fluid(fluid: Fluid): double - /** - * Inserts the given fluid into the first available location in this train. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.insert_fluid View documentation} - * - * @param fluid - * @returns The amount inserted. - */ - insert_fluid(fluid: Fluid): double - /** - * Clears all fluids in this train. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.clear_fluids_inside View documentation} - */ - clear_fluids_inside(): void - /** - * Go to the station specified by the index in the train's schedule. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.go_to_station View documentation} - * - * @param index - */ - go_to_station(index: uint): void - /** - * Gets all rails under the train. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.get_rails View documentation} - */ - get_rails(): LuaEntity[] - /** - * When `true`, the train is explicitly controlled by the player or script. When `false`, the train moves - * autonomously according to its schedule. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.manual_mode View documentation} - */ - manual_mode: boolean - /** - * Current speed. - * - * **Note**: Changing the speed of the train is potentially an unsafe operation because train uses the speed for its - * internal calculations of break distances, etc. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.speed View documentation} - */ - speed: double - /** - * Current max speed when moving forward, depends on locomotive prototype and fuel. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.max_forward_speed View documentation} - */ - readonly max_forward_speed: double - /** - * Current max speed when moving backwards, depends on locomotive prototype and fuel. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.max_backward_speed View documentation} - */ - readonly max_backward_speed: double - /** - * The weight of this train. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.weight View documentation} - */ - readonly weight: double - /** - * Rolling stocks the train is composed of. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.carriages View documentation} - */ - readonly carriages: LuaEntity[] - /** - * Arrays of locomotives. The result is two arrays, indexed by `"front_movers"` and `"back_movers"` containing the - * locomotives. E.g. `{front_movers={loco1, loco2}, back_movers={loco3}}`. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.locomotives View documentation} - */ - readonly locomotives: Record - /** - * The cargo carriages the train contains. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.cargo_wagons View documentation} - */ - readonly cargo_wagons: LuaEntity[] - /** - * The fluid carriages the train contains. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.fluid_wagons View documentation} - */ - readonly fluid_wagons: LuaEntity[] - /** - * The trains current schedule or `nil` if empty. Set to `nil` to clear. - * - * **Note**: The schedule can't be changed by modifying the returned table. Instead, changes must be made by - * assigning a new table to this attribute. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.schedule View documentation} - */ - schedule: TrainSchedule | undefined - /** - * This train's current state. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.state View documentation} - */ - readonly state: defines.train_state - /** - * The rail at the front end of the train, possibly `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.front_rail View documentation} - */ - readonly front_rail: LuaEntity | undefined - /** - * The rail at the back end of the train, possibly `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.back_rail View documentation} - */ - readonly back_rail: LuaEntity | undefined - readonly rail_direction_from_front_rail: defines.rail_direction - readonly rail_direction_from_back_rail: defines.rail_direction - /** - * The front stock of this train or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.front_stock View documentation} - */ - readonly front_stock: LuaEntity | undefined - /** - * The back stock of this train or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.back_stock View documentation} - */ - readonly back_stock: LuaEntity | undefined - /** - * The train stop this train is stopped at or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.station View documentation} - */ - readonly station: LuaEntity | undefined - /** - * If this train has a path. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.has_path View documentation} - */ - readonly has_path: boolean - /** - * The destination rail this train is currently pathing to or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.path_end_rail View documentation} - */ - readonly path_end_rail: LuaEntity | undefined - /** - * The destination train stop this train is currently pathing to or `nil`. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.path_end_stop View documentation} - */ - readonly path_end_stop: LuaEntity | undefined - /** - * The unique train ID. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.id View documentation} - */ - readonly id: uint - /** - * The player passengers on the train - * - * **Note**: This does *not* index using player index. See {@link LuaPlayer.index LuaPlayer::index} on each player - * instance for the player index. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.passengers View documentation} - */ - readonly passengers: LuaPlayer[] - /** - * The riding state of this train. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.riding_state View documentation} - */ - readonly riding_state: RidingState - /** - * The players killed by this train. - * - * The keys are the player indexes, the values are how often this train killed that player. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.killed_players View documentation} - */ - readonly killed_players: Record - /** - * The total number of kills by this train. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.kill_count View documentation} - */ - readonly kill_count: uint - /** - * The path this train is using or `nil` if none. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.path View documentation} - */ - readonly path: LuaRailPath | undefined - /** - * The signal this train is arriving or waiting at or `nil` if none. - * - * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.signal View documentation} - */ - readonly signal: LuaEntity | undefined - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaTrain" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Control behavior for train stops. - * - * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaTrainStopControlBehavior extends LuaGenericOnOffControlBehavior { - /** - * `true` if the train stop should send the circuit network contents to the train to use. - * - * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.send_to_train View documentation} - */ - send_to_train: boolean - /** - * `true` if the train stop should send the train contents to the circuit network. - * - * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.read_from_train View documentation} - */ - read_from_train: boolean - /** - * `true` if the train stop should send the stopped train id to the circuit network. - * - * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.read_stopped_train View documentation} - */ - read_stopped_train: boolean - /** - * `true` if the trains_limit_signal is used to set a limit of trains incoming for train stop. - * - * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.set_trains_limit View documentation} - */ - set_trains_limit: boolean - /** - * `true` if the train stop should send amount of incoming trains to the circuit network. - * - * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.read_trains_count View documentation} - */ - read_trains_count: boolean - /** - * `true` if the train stop is enabled/disabled through the circuit network. - * - * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.enable_disable View documentation} - */ - enable_disable: boolean - /** - * The signal that will be sent when using the send-train-id option. - * - * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.stopped_train_signal View documentation} - */ - stopped_train_signal: SignalID - /** - * The signal that will be sent when using the read-trains-count option. - * - * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.trains_count_signal View documentation} - */ - trains_count_signal: SignalID - /** - * The signal to be used by set-trains-limit to limit amount of incoming trains - * - * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.trains_limit_signal View documentation} - */ - trains_limit_signal: SignalID - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaTrainStopControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Control behavior for transport belts. - * - * {@link https://lua-api.factorio.com/next/LuaTransportBeltControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaTransportBeltControlBehavior extends LuaGenericOnOffControlBehavior { - /** - * If the belt will be enabled/disabled based off the circuit network. - * - * {@link https://lua-api.factorio.com/next/LuaTransportBeltControlBehavior.html#LuaTransportBeltControlBehavior.enable_disable View documentation} - */ - enable_disable: boolean - /** - * If the belt will read the contents and send them to the circuit network. - * - * {@link https://lua-api.factorio.com/next/LuaTransportBeltControlBehavior.html#LuaTransportBeltControlBehavior.read_contents View documentation} - */ - read_contents: boolean - /** - * The read mode for the belt. - * - * {@link https://lua-api.factorio.com/next/LuaTransportBeltControlBehavior.html#LuaTransportBeltControlBehavior.read_contents_mode View documentation} - */ - read_contents_mode: defines.control_behavior.transport_belt.content_read_mode - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaTransportBeltControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * One line on a transport belt. - * - * {@link https://lua-api.factorio.com/next/LuaTransportLine.html View documentation} - * - * @noSelf - */ -interface LuaTransportLine extends ReadonlyArray { - /** - * Remove all items from this transport line. - * - * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.clear View documentation} - */ - clear(): void - /** - * Count some or all items on this line. - * - * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.get_item_count View documentation} - * - * @param item - Prototype name of the item to count. If not specified, count all items. - * @see {@link LuaInventory.get_item_count} - */ - get_item_count(item?: string): uint - /** - * Remove some items from this line. - * - * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.remove_item View documentation} - * - * @param items - Items to remove. - * @returns Number of items actually removed. - */ - remove_item(items: ItemStackIdentification): uint - /** - * Can an item be inserted at a given position? - * - * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.can_insert_at View documentation} - * - * @param position - Where to insert an item. - */ - can_insert_at(position: float): boolean - /** - * Can an item be inserted at the back of this line? - * - * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.can_insert_at_back View documentation} - */ - can_insert_at_back(): boolean - /** - * Insert items at a given position. - * - * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.insert_at View documentation} - * - * @param position - Where on the line to insert the items. - * @param items - Items to insert. - * @returns Were the items inserted successfully? - */ - insert_at(position: float, items: ItemStackIdentification): boolean - /** - * Insert items at the back of this line. - * - * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.insert_at_back View documentation} - * - * @param items - * @returns Were the items inserted successfully? - */ - insert_at_back(items: ItemStackIdentification): boolean - /** - * Get counts of all items on this line. - * - * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.get_contents View documentation} - * - * @returns The counts, indexed by item names. - * @see {@link LuaInventory.get_contents} - */ - get_contents(): Record - /** - * Returns whether the associated internal transport line of this line is the same as the others associated internal - * transport line. - * - * **Note**: This can return true even when the {@link LuaTransportLine.owner LuaTransportLine::owner}s are different - * (so `this == other` is false), because the internal transport lines can span multiple tiles. - * - * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.line_equals View documentation} - * - * @param other - */ - line_equals(other: LuaTransportLine): boolean - /** - * Get the number of items on this transport line. - * - * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.operator%20# View documentation} - */ - readonly length: uint - /** - * The entity this transport line belongs to. - * - * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.owner View documentation} - */ - readonly owner: LuaEntity - /** - * The transport lines that this transport line outputs items to or an empty table if none. - * - * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.output_lines View documentation} - */ - readonly output_lines: LuaTransportLine[] - /** - * The transport lines that this transport line is fed by or an empty table if none. - * - * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.input_lines View documentation} - */ - readonly input_lines: LuaTransportLine[] - /** - * The indexing operator. - * - * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.operator%20[] View documentation} - */ - readonly [index: number]: LuaItemStack - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaTransportLine" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a trivial smoke. - * - * {@link https://lua-api.factorio.com/next/LuaTrivialSmokePrototype.html View documentation} - * - * @noSelf - */ -interface LuaTrivialSmokePrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaTrivialSmokePrototype.html#LuaTrivialSmokePrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaTrivialSmokePrototype.html#LuaTrivialSmokePrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - readonly color: ColorTable - readonly start_scale: double - readonly end_scale: double - readonly movement_slow_down_factor: double - readonly duration: uint - readonly spread_duration: uint - readonly fade_away_duration: uint - readonly fade_in_duration: uint - readonly glow_fade_away_duration: uint - readonly cyclic: boolean - readonly affected_by_wind: boolean - readonly show_when_smoke_off: boolean - readonly glow_animation: boolean - readonly render_layer: RenderLayer - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaTrivialSmokePrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * A collection of units moving and attacking together. The engine creates autonomous unit groups to attack polluted - * areas. The script can create and control such groups as well. Groups can accept commands in the same manner as regular units. - * - * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html View documentation} - * - * @noSelf - */ -interface LuaUnitGroup { - /** - * Make a unit a member of this group. Has the same effect as giving a `group_command` with this group to the unit. - * - * **Note**: The member must have the same force as the unit group. - * - * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.add_member View documentation} - * - * @param unit - */ - add_member(unit: LuaEntity): void - /** - * Give this group a command. - * - * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.set_command View documentation} - * - * @param command - * @see {@link LuaEntity.set_command} - */ - set_command(command: Command): void - /** - * Give this group a distraction command. - * - * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.set_distraction_command View documentation} - * - * @param command - * @see {@link LuaEntity.set_command} - */ - set_distraction_command(command: Command): void - /** - * Make this group autonomous. Autonomous groups will automatically attack polluted areas. Autonomous groups aren't - * considered to be script driven - * - * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.set_autonomous View documentation} - * - * @see {@link LuaUnitGroup.is_script_driven} - */ - set_autonomous(): void - /** - * Make the group start moving even if some of its members haven't yet arrived. - * - * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.start_moving View documentation} - */ - start_moving(): void - /** - * Dissolve this group. Its members won't be destroyed, they will be merely unlinked from this group. - * - * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.destroy View documentation} - */ - destroy(): void - /** - * Members of this group. - * - * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.members View documentation} - */ - readonly members: LuaEntity[] - /** - * Group position. This can have different meanings depending on the group state. When the group is gathering, the - * position is the place of gathering. When the group is moving, the position is the expected position of its - * members along the path. When the group is attacking, it is the average position of its members. - * - * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.position View documentation} - */ - readonly position: PositionTable - /** - * Whether this group is gathering, moving or attacking. - * - * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.state View documentation} - */ - readonly state: defines.group_state - /** - * The force of this unit group. - * - * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.force View documentation} - */ - readonly force: LuaForce - /** - * The surface of this unit group. - * - * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.surface View documentation} - */ - readonly surface: LuaSurface - /** - * The group number for this unit group. - * - * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.group_number View documentation} - */ - readonly group_number: uint - /** - * Whether this unit group is controlled by a script or by the game engine. - * - * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.is_script_driven View documentation} - * - * @see {@link LuaUnitGroup.set_autonomous} - */ - readonly is_script_driven: boolean - /** - * The command given to this group or `nil` is the group has no command. - * - * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.command View documentation} - */ - readonly command: Command | undefined - /** - * The distraction command given to this group or `nil` is the group currently isn't distracted. - * - * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.distraction_command View documentation} - */ - readonly distraction_command: Command | undefined - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaUnitGroup" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a virtual signal. - * - * {@link https://lua-api.factorio.com/next/LuaVirtualSignalPrototype.html View documentation} - * - * @noSelf - */ -interface LuaVirtualSignalPrototype { - /** - * Name of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaVirtualSignalPrototype.html#LuaVirtualSignalPrototype.name View documentation} - */ - readonly name: string - /** - * Order string of this prototype. - * - * {@link https://lua-api.factorio.com/next/LuaVirtualSignalPrototype.html#LuaVirtualSignalPrototype.order View documentation} - */ - readonly order: string - readonly localised_name: LocalisedString - readonly localised_description: LocalisedString - /** - * If this is a special signal - * - * {@link https://lua-api.factorio.com/next/LuaVirtualSignalPrototype.html#LuaVirtualSignalPrototype.special View documentation} - */ - readonly special: boolean - readonly subgroup: LuaGroup - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaVirtualSignalPrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Prototype of a void energy source. - * - * {@link https://lua-api.factorio.com/next/LuaVoidEnergySourcePrototype.html View documentation} - * - * @noSelf - */ -interface LuaVoidEnergySourcePrototype { - readonly emissions: double - readonly render_no_network_icon: boolean - readonly render_no_power_icon: boolean - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaVoidEnergySourcePrototype" - /** All methods and properties that this object supports. */ - help(): string -} - -/** - * Control behavior for walls. - * - * {@link https://lua-api.factorio.com/next/LuaWallControlBehavior.html View documentation} - * - * @noSelf - */ -interface LuaWallControlBehavior extends LuaControlBehavior { - /** - * The circuit condition. - * - * {@link https://lua-api.factorio.com/next/LuaWallControlBehavior.html#LuaWallControlBehavior.circuit_condition View documentation} - */ - circuit_condition: CircuitConditionDefinition - open_gate: boolean - read_sensor: boolean - output_signal: SignalID - /** - * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that - * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the - * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any - * change to the game state might have occurred between the creation of the Lua object and its access. - */ - readonly valid: boolean - /** - * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be - * suffixed with a dotted path to a member of the struct. - */ - readonly object_name: "LuaWallControlBehavior" - /** All methods and properties that this object supports. */ - help(): string -} diff --git a/modules/mod2/typed-factorio/generated/concepts.d.ts b/modules/mod2/typed-factorio/generated/concepts.d.ts deleted file mode 100644 index e097d47..0000000 --- a/modules/mod2/typed-factorio/generated/concepts.d.ts +++ /dev/null @@ -1,5635 +0,0 @@ -/** @noSelfInFile */ - -/** - * Localised strings are a way to support translation of in-game text. It is an array where the first element is the key - * and the remaining elements are parameters that will be substituted for placeholders in the template designated by the key. - * - * The key identifies the string template. For example, `"gui-alert-tooltip.attack"` (for the template `"__1__ objects - * are being damaged"`; see the file `data/core/locale/en.cfg`). - * - * The template can contain placeholders such as `__1__` or `__2__`. These will be replaced by the respective parameter - * in the LocalisedString. The parameters themselves can be other localised strings, which will be processed recursively - * in the same fashion. Localised strings cannot be recursed deeper than 20 levels and cannot have more than 20 parameters. - * - * As a special case, when the key is just the empty string, all the parameters will be concatenated (after processing, - * if any are localised strings). If there is only one parameter, it will be used as is. - * - * Furthermore, when an API function expects a localised string, it will also accept a regular string (i.e. not a table) - * which will not be translated, or number which will be converted to its textual representation. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LocalisedString View documentation} - * - * @example - * In the English translation, this will print `"No ammo"`; in the Czech translation, it will print `"Bez munice"`: - * - * ```lua - * game.player.print({"description.no-ammo"}) - * ``` The `description.no-ammo` template contains no placeholders, so no further parameters are necessary. - * - * @example - * In the English translation, this will print `"Durability: 5/9"`; in the Japanese one, it will print `"耐久度: 5/9"`: - * - * ```lua - * game.player.print({"description.durability", 5, 9}) - * ``` - * - * @example - * This will print `"hello"` in all translations: - * - * ```lua - * game.player.print({"", "hello"}) - * ``` - * - * @example - * This will print `"Iron plate: 60"` in the English translation and `"Eisenplatte: 60"` in the German translation. - * - * ```lua - * game.print({"", {"item-name.iron-plate"}, ": ", 60}) - * ``` - */ -type LocalisedString = [string, ...LocalisedString[]] | string | number - -interface DisplayResolution { - readonly width: uint - readonly height: uint -} - -interface PersonalLogisticParameters { - /** The item. `nil` clears the filter. */ - readonly name?: string - readonly min?: uint - readonly max?: uint -} - -/** - * The smooth orientation. It is a {@link float} in the range `[0, 1)` that covers a full circle, starting at the top and - * going clockwise. This means a value of `0` indicates "north", a value of `0.5` indicates "south". - * - * For example then, a value of `0.625` would indicate "south-west", and a value of `0.875` would indicate "north-west". - * - * {@link https://lua-api.factorio.com/next/Concepts.html#RealOrientation View documentation} - */ -type RealOrientation = float - -interface PositionTable { - readonly x: int - readonly y: int -} - -type PositionArray = readonly [x: int, y: int] - -/** - * Coordinates of a tile in a map. Positions may be specified either as a dictionary with `x`, `y` as keys, or simply as - * an array with two elements. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#Position View documentation} - * - * @example - * Explicit definition: - * - * ```lua - * {x = 50, y = 20} - * {y = 20, x = 50} - * ``` - * - * @example - * Shorthand: ```lua - * {10, 20} - * ``` - */ -type Position = PositionTable | PositionArray - -interface ChunkPositionTable { - readonly x: int - readonly y: int -} - -type ChunkPositionArray = readonly [x: int, y: int] - -/** - * Coordinates of a chunk in a {@link LuaSurface} where each integer `x`/`y` represents a different chunk. This uses the - * same format as {@link Position}, meaning it can be specified either with or without explicit keys. A {@link Position} - * can be translated to a ChunkPosition by dividing the `x`/`y` values by 32. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#ChunkPosition View documentation} - */ -type ChunkPosition = ChunkPositionTable | ChunkPositionArray - -interface TilePositionTable { - readonly x: int - readonly y: int -} - -type TilePositionArray = readonly [x: int, y: int] - -/** - * Coordinates of a tile in a chunk on a {@link LuaSurface} where each integer `x`/`y` represents a different tile. This - * uses the same format as {@link Position} except it rounds any `x`/`y` down to whole numbers. It can be specified - * either with or without explicit keys. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#TilePosition View documentation} - */ -type TilePosition = TilePositionTable | TilePositionArray - -interface GuiLocationTable { - readonly x: int - readonly y: int -} - -type GuiLocationArray = readonly [x: int, y: int] - -/** - * Screen coordinates of a GUI element in a {@link LuaGui}. This uses the same format as {@link Position} except it rounds - * any `x`/`y` down to whole numbers. It can be specified either with or without explicit keys. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#GuiLocation View documentation} - */ -type GuiLocation = GuiLocationTable | GuiLocationArray - -/** - * A {@link ChunkPosition} with an added bounding box for the area of the chunk. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#ChunkPositionAndArea View documentation} - */ -interface ChunkPositionAndArea { - readonly x: int - readonly y: int - readonly area: BoundingBox -} - -/** - * A table used to define a manual shape for a piece of equipment. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#EquipmentPoint View documentation} - */ -interface EquipmentPoint { - readonly x: uint - readonly y: uint -} - -interface GuiAnchor { - readonly gui: defines.relative_gui_type - readonly position: defines.relative_gui_position - /** If provided, only anchors the GUI element when the opened things type matches the type. */ - readonly type?: string - /** If provided, only anchors the GUI element when the opened thing matches the name. `name` takes precedence over `names`. */ - readonly name?: string - /** - * If provided, only anchors the GUI element when the opened thing matches one of the names. When reading an anchor, - * `names` is always populated. - */ - readonly names?: string[] -} - -interface TabAndContent { - readonly tab: LuaGuiElement - readonly content: LuaGuiElement -} - -interface OldTileAndPosition { - readonly old_tile: LuaTilePrototype - readonly position: TilePosition -} - -/** - * A dictionary of string to the four basic Lua types: `string`, `boolean`, `number`, `table`. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#Tags View documentation} - * - * @example - * ```lua - * {a = 1, b = true, c = "three", d = {e = "f"}} - * ``` - */ -type Tags = Record - -/** - * **Note**: The vectors for all 5 position attributes are a table with `x` and `y` keys instead of an array. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#SmokeSource View documentation} - */ -interface SmokeSource { - readonly name: string - readonly frequency: double - readonly offset: double - readonly position?: PositionTable - readonly north_position?: PositionTable - readonly east_position?: PositionTable - readonly south_position?: PositionTable - readonly west_position?: PositionTable - readonly deviation?: Position - readonly starting_frame_speed: uint16 - readonly starting_frame_speed_deviation: double - readonly starting_frame: uint16 - readonly starting_frame_deviation: double - readonly slow_down_factor: uint8 - readonly height: float - readonly height_deviation: float - readonly starting_vertical_speed: float - readonly starting_vertical_speed_deviation: float - readonly vertical_speed_slowdown: float -} - -/** - * A vector is a two-element array containing the `x` and `y` components. In some specific cases, the vector is a table - * with `x` and `y` keys instead, which the documentation will point out. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#Vector View documentation} - * - * @example - * ```lua - * right = {1.0, 0.0} - * ``` - */ -type Vector = PositionArray - -interface BoundingBoxTable { - readonly left_top: Position - readonly right_bottom: Position - readonly orientation?: RealOrientation -} - -type BoundingBoxArray = readonly [left_top: Position, right_bottom: Position, orientation?: RealOrientation] - -/** - * Two positions, specifying the top-left and bottom-right corner of the box respectively. Like with {@link Position}, - * the names of the members may be omitted. When read from the game, the third member `orientation` is present if it is - * non-zero, however it is ignored when provided to the game. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#BoundingBox View documentation} - * - * @example - * Explicit definition: - * - * ```lua - * {left_top = {-2, -3}, right_bottom = {5, 8}} - * ``` - * - * @example - * Shorthand: ```lua - * {{-2, -3}, {5, 8}} - * ``` - */ -type BoundingBox = BoundingBoxTable | BoundingBoxArray - -/** - * An area defined using the map editor. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#ScriptArea View documentation} - */ -interface ScriptArea { - readonly area: BoundingBox - readonly name: string - readonly color: Color - readonly id: uint -} - -/** - * A position defined using the map editor. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#ScriptPosition View documentation} - */ -interface ScriptPosition { - readonly position: Position - readonly name: string - readonly color: Color - readonly id: uint -} - -interface ColorTable { - readonly r?: float - readonly g?: float - readonly b?: float - readonly a?: float -} - -type ColorArray = readonly [r?: float, g?: float, b?: float, a?: float] - -/** - * Red, green, blue and alpha values, all in range [0, 1] or all in range [0, 255] if any value is > 1. All values here - * are optional. Color channels default to `0`, the alpha channel defaults to `1`. - * - * Similar to {@link Position}, Color allows the short-hand notation of passing an array of exactly 3 or 4 numbers. The - * game usually expects colors to be in pre-multiplied form (color channels are pre-multiplied by alpha). - * - * {@link https://lua-api.factorio.com/next/Concepts.html#Color View documentation} - * - * @example - * ```lua - * red1 = {r = 0.5, g = 0, b = 0, a = 0.5} -- Half-opacity red - * red2 = {r = 0.5, a = 0.5} -- Same color as red1 - * black = {} -- All channels omitted: black - * red1_short = {0.5, 0, 0, 0.5} -- Same color as red1 in short-hand notation - * ``` - */ -type Color = ColorTable | ColorArray - -interface ColorModifierTable { - readonly r?: float - readonly g?: float - readonly b?: float - readonly a?: float -} - -type ColorModifierArray = readonly [r?: float, g?: float, b?: float, a?: float] - -/** - * Same as {@link Color}, but red, green, blue and alpha values can be any floating point number, without any special - * handling of the range [1, 255]. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#ColorModifier View documentation} - */ -type ColorModifier = ColorModifierTable | ColorModifierArray - -interface CraftingQueueItem { - /** The index of the item in the crafting queue. */ - readonly index: uint - /** The recipe being crafted. */ - readonly recipe: string - /** The amount of items being crafted. */ - readonly count: uint -} - -interface Alert { - /** The tick this alert was created. */ - readonly tick: uint - readonly target?: LuaEntity - readonly prototype?: LuaEntityPrototype - readonly position?: Position - /** The SignalID used for a custom alert. Only present for custom alerts. */ - readonly icon?: SignalID - /** The message for a custom alert. Only present for custom alerts. */ - readonly message?: LocalisedString -} - -/** - * One vertex of a ScriptRenderPolygon. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#ScriptRenderVertexTarget View documentation} - */ -interface ScriptRenderVertexTarget { - readonly target: Position | LuaEntity - /** Only used if `target` is a LuaEntity. */ - readonly target_offset?: Vector -} - -interface PathfinderWaypoint { - /** The position of the waypoint on its surface. */ - readonly position: Position - /** `true` if the path from the previous waypoint to this one goes through an entity that must be destroyed. */ - readonly needs_destroy_to_reach: boolean -} - -interface CutsceneWaypoint { - /** Position to pan the camera to. */ - readonly position?: Position - /** Entity or unit group to pan the camera to. */ - readonly target?: LuaEntity | LuaUnitGroup - /** How many ticks it will take to reach this waypoint from the previous one. */ - readonly transition_time: uint - /** Time in ticks to wait before moving to the next waypoint. */ - readonly time_to_wait: uint - /** Zoom level to be set when the waypoint is reached. When not specified, the previous waypoint's zoom is used. */ - readonly zoom?: double -} - -interface Decorative { - /** The name of the decorative prototype. */ - readonly name: string - readonly position: Position - readonly amount: uint8 -} - -interface DecorativeResult { - readonly position: TilePosition - readonly decorative: LuaDecorativePrototype - readonly amount: uint -} - -/** - * **Note**: Either `icon`, `text`, or both must be provided. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#ChartTagSpec View documentation} - */ -interface ChartTagSpec { - readonly position: Position - readonly icon?: SignalID - readonly text?: string - readonly last_user?: PlayerIdentification -} - -/** - * Parameters that affect the look and control of the game. Updating any of the member attributes here will immediately - * take effect in the game engine. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings View documentation} - */ -interface GameViewSettings { - /** - * Show the controller GUI elements. This includes the toolbar, the selected tool slot, the armour slot, and the gun - * and ammunition slots. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_controller_gui View documentation} - */ - show_controller_gui: boolean - /** - * Show the chart in the upper right-hand corner of the screen. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_minimap View documentation} - */ - show_minimap: boolean - /** - * Show research progress and name in the upper right-hand corner of the screen. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_research_info View documentation} - */ - show_research_info: boolean - /** - * Show overlay icons on entities. Also known as "alt-mode". - * - * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_entity_info View documentation} - */ - show_entity_info: boolean - /** - * Show the flashing alert icons next to the player's toolbar. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_alert_gui View documentation} - */ - show_alert_gui: boolean - /** - * When `true` (the default), mousing over an entity will select it. Otherwise, moving the mouse won't update entity - * selection. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.update_entity_selection View documentation} - */ - update_entity_selection: boolean - /** - * When `true` (`false` is default), the rails will always show the rail block visualisation. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_rail_block_visualisation View documentation} - */ - show_rail_block_visualisation: boolean - /** - * Shows or hides the buttons row. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_side_menu View documentation} - */ - show_side_menu: boolean - /** - * Shows or hides the view options when map is opened. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_map_view_options View documentation} - */ - show_map_view_options: boolean - /** - * Shows or hides quickbar of shortcuts. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_quickbar View documentation} - */ - show_quickbar: boolean - /** - * Shows or hides the shortcut bar. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_shortcut_bar View documentation} - */ - show_shortcut_bar: boolean -} - -/** - * What is shown in the map view. If a field is not given, that setting will not be changed. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#MapViewSettings View documentation} - */ -interface MapViewSettings { - readonly "show-logistic-network"?: boolean - readonly "show-electric-network"?: boolean - readonly "show-turret-range"?: boolean - readonly "show-pollution"?: boolean - readonly "show-train-station-names"?: boolean - readonly "show-player-names"?: boolean - readonly "show-networkless-logistic-members"?: boolean - readonly "show-non-standard-map-info"?: boolean -} - -/** - * These values are for the time frame of one second (60 ticks). - * - * {@link https://lua-api.factorio.com/next/Concepts.html#PollutionMapSettings View documentation} - */ -interface PollutionMapSettings { - /** Whether pollution is enabled at all. */ - readonly enabled: boolean - /** The amount that is diffused to a neighboring chunk (possibly repeated for other directions as well). Defaults to `0.02`. */ - readonly diffusion_ratio: double - /** The amount of PUs that need to be in a chunk for it to start diffusing. Defaults to `15`. */ - readonly min_to_diffuse: double - /** The amount of pollution eaten by a chunk's tiles as a percentage of 1. Defaults to `1`. */ - readonly aeging: double - /** Any amount of pollution larger than this value is visualized as this value instead. Defaults to `150`. */ - readonly expected_max_per_chunk: double - /** - * Any amount of pollution smaller than this value (but bigger than zero) is visualized as this value instead. - * Defaults to `50`. - */ - readonly min_to_show_per_chunk: double - /** Defaults to `60`. */ - readonly min_pollution_to_damage_trees: double - /** Defaults to `150`. */ - readonly pollution_with_max_forest_damage: double - /** Defaults to `50`. */ - readonly pollution_per_tree_damage: double - /** Defaults to `10`. */ - readonly pollution_restored_per_tree_damage: double - /** Defaults to `20`. */ - readonly max_pollution_to_restore_trees: double - /** Defaults to `1`. */ - readonly enemy_attack_pollution_consumption_modifier: double -} - -/** - * These values represent a percentual increase in evolution. This means a value of `0.1` would increase evolution by 10%. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#EnemyEvolutionMapSettings View documentation} - */ -interface EnemyEvolutionMapSettings { - /** Whether enemy evolution is enabled at all. */ - readonly enabled: boolean - /** The amount evolution naturally progresses by every second. Defaults to `0.000004`. */ - readonly time_factor: double - /** The amount evolution progresses for every destroyed spawner. Defaults to `0.002`. */ - readonly destroy_factor: double - /** The amount evolution progresses for every unit of pollution. Defaults to `0.0000009`. */ - readonly pollution_factor: double -} - -/** - * Candidate chunks are given scores to determine which one of them should be expanded into. This score takes into - * account various settings noted below. The iteration is over a square region centered around the chunk for which the - * calculation is done, and includes the central chunk as well. Distances are calculated as - * {@link https://en.wikipedia.org/wiki/Taxicab_geometry Manhattan distance}. - * - * The pseudocode algorithm to determine a chunk's score is as follows: - * - * ```lua - * player = 0 - * for neighbour in all chunks within enemy_building_influence_radius from chunk: - * player += number of player buildings on neighbour - * * building_coefficient - * * neighbouring_chunk_coefficient^distance(chunk, neighbour) - * - * base = 0 - * for neighbour in all chunk within friendly_base_influence_radius from chunk: - * base += num of enemy bases on neighbour - * * other_base_coefficient - * * neighbouring_base_chunk_coefficient^distance(chunk, neighbour) - * - * score(chunk) = 1 / (1 + player + base) - * ``` - * - * {@link https://lua-api.factorio.com/next/Concepts.html#EnemyExpansionMapSettings View documentation} - */ -interface EnemyExpansionMapSettings { - /** Whether enemy expansion is enabled at all. */ - readonly enabled: boolean - /** - * Distance in chunks from the furthest base around to prevent expansions from reaching too far into the player's - * territory. Defaults to `7`. - */ - readonly max_expansion_distance: uint - /** Defaults to `2`. */ - readonly friendly_base_influence_radius: uint - /** Defaults to `2`. */ - readonly enemy_building_influence_radius: uint - /** Defaults to `0.1`. */ - readonly building_coefficient: double - /** Defaults to `2.0`. */ - readonly other_base_coefficient: double - /** Defaults to `0.5`. */ - readonly neighbouring_chunk_coefficient: double - /** Defaults to `0.4`. */ - readonly neighbouring_base_chunk_coefficient: double - /** - * A chunk has to have at most this high of a percentage of unbuildable tiles for it to be considered a candidate to - * avoid chunks full of water as candidates. Defaults to `0.9`, or 90%. - */ - readonly max_colliding_tiles_coefficient: double - /** - * The minimum size of a biter group that goes to build a new base. This is multiplied by the evolution factor. - * Defaults to `5`. - */ - readonly settler_group_min_size: uint - /** - * The maximum size of a biter group that goes to build a new base. This is multiplied by the evolution factor. - * Defaults to `20`. - */ - readonly settler_group_max_size: uint - /** - * The minimum time between expansions in ticks. The actual cooldown is adjusted to the current evolution levels. - * Defaults to `4*3,600=14,400` ticks. - */ - readonly min_expansion_cooldown: uint - /** - * The maximum time between expansions in ticks. The actual cooldown is adjusted to the current evolution levels. - * Defaults to `60*3,600=216,000` ticks. - */ - readonly max_expansion_cooldown: uint -} - -interface UnitGroupMapSettings { - /** - * The minimum amount of time in ticks a group will spend gathering before setting off. The actual time is a random - * time between the minimum and maximum times. Defaults to `3,600` ticks. - */ - readonly min_group_gathering_time: uint - /** - * The maximum amount of time in ticks a group will spend gathering before setting off. The actual time is a random - * time between the minimum and maximum times. Defaults to `10*3,600=36,000` ticks. - */ - readonly max_group_gathering_time: uint - /** - * After gathering has finished, the group is allowed to wait this long in ticks for delayed members. New members - * are not accepted anymore however. Defaults to `2*3,600=7,200` ticks. - */ - readonly max_wait_time_for_late_members: uint - /** The minimum group radius in tiles. The actual radius is adjusted based on the number of members. Defaults to `5.0`. */ - readonly min_group_radius: double - /** The maximum group radius in tiles. The actual radius is adjusted based on the number of members. Defaults to `30.0`. */ - readonly max_group_radius: double - /** - * The maximum speed a percentage of its regular speed that a group member can speed up to when catching up with the - * group. Defaults to `1.4`, or 140%. - */ - readonly max_member_speedup_when_behind: double - /** - * The minimum speed a percentage of its regular speed that a group member can slow down to when ahead of the group. - * Defaults to `0.6`, or 60%. - */ - readonly max_member_slowdown_when_ahead: double - /** - * The minimum speed as a percentage of its maximum speed that a group will slow down to so members that fell behind - * can catch up. Defaults to `0.3`, or 30%. - */ - readonly max_group_slowdown_factor: double - /** - * When a member of a group falls back more than this factor times the group radius, the group will slow down to its - * `max_group_slowdown_factor` speed to let them catch up. Defaults to `3`. - */ - readonly max_group_member_fallback_factor: double - /** - * When a member of a group falls back more than this factor times the group radius, it will be dropped from the - * group. Defaults to `10`. - */ - readonly member_disown_distance: double - readonly tick_tolerance_when_member_arrives: uint - /** The maximum number of automatically created unit groups gathering for attack at any time. Defaults to `30`. */ - readonly max_gathering_unit_groups: uint - /** - * The maximum number of members for an attack unit group. This only affects automatically created unit groups, - * manual groups created through the API are unaffected. Defaults to `200`. - */ - readonly max_unit_group_size: uint -} - -interface SteeringMapSetting { - /** Does not include the radius of the unit. */ - readonly radius: double - readonly separation_factor: double - readonly separation_force: double - /** Used to make steering look better for aesthetic purposes. */ - readonly force_unit_fuzzy_goto_behavior: boolean -} - -interface SteeringMapSettings { - readonly default: SteeringMapSetting - readonly moving: SteeringMapSetting -} - -interface PathFinderMapSettings { - /** Determines whether forwards (`>1`), backwards (`<-1`), or symmetrical (`1`) search is preferred. Defaults to `5`. */ - readonly fwd2bwd_ratio: uint - /** - * When looking at which node to check next, their heuristic value is multiplied by this ratio. The higher it is, - * the more the search is directed straight at the goal. Defaults to `2`. - */ - readonly goal_pressure_ratio: double - /** The maximum number of nodes that are expanded per tick. Defaults to `1,000`. */ - readonly max_steps_worked_per_tick: double - /** The maximum amount of work each pathfinding job is allowed to do per tick. Defaults to `8,000`. */ - readonly max_work_done_per_tick: uint - /** Whether to cache paths at all. Defaults to `true`. */ - readonly use_path_cache: boolean - /** Number of elements in the short cache. Defaults to `5`. */ - readonly short_cache_size: uint - /** Number of elements in the long cache. Defaults to `25`. */ - readonly long_cache_size: uint - /** The minimal distance to the goal in tiles required to be searched in the short path cache. Defaults to `10`. */ - readonly short_cache_min_cacheable_distance: double - /** The minimal number of nodes required to be searched in the short path cache. Defaults to `50`. */ - readonly short_cache_min_algo_steps_to_cache: uint - /** The minimal distance to the goal in tiles required to be searched in the long path cache. Defaults to `30`. */ - readonly long_cache_min_cacheable_distance: double - /** - * When looking for a connection to a cached path, search at most for this number of steps times the original - * estimate. Defaults to `100`. - */ - readonly cache_max_connect_to_cache_steps_multiplier: uint - /** - * When looking for a path from cache, make sure it doesn't start too far from the requested start in relative - * terms. Defaults to `0.2`. - */ - readonly cache_accept_path_start_distance_ratio: double - /** - * When looking for a path from cache, make sure it doesn't end too far from the requested end in relative terms. - * This is typically more lenient than the start ratio since the end target could be moving. Defaults to `0.15`. - */ - readonly cache_accept_path_end_distance_ratio: double - /** Same principle as `cache_accept_path_start_distance_ratio`, but used for negative cache queries. Defaults to `0.3`. */ - readonly negative_cache_accept_path_start_distance_ratio: double - /** Same principle as `cache_accept_path_end_distance_ratio`, but used for negative cache queries. Defaults to `0.3`. */ - readonly negative_cache_accept_path_end_distance_ratio: double - /** When assigning a rating to the best path, this multiplier times start distances is considered. Defaults to `10`. */ - readonly cache_path_start_distance_rating_multiplier: double - /** - * When assigning a rating to the best path, this multiplier times end distances is considered. This value is - * typically higher than the start multiplier as this results in better end path quality. Defaults to `20`. - */ - readonly cache_path_end_distance_rating_multiplier: double - /** - * A penalty that is applied for another unit that is on the way to the goal. This is mainly relevant for situations - * where a group of units has arrived at the target they are supposed to attack, making units further back circle - * around to reach the target. Defaults to `30`. - */ - readonly stale_enemy_with_same_destination_collision_penalty: double - /** The distance in tiles after which other moving units are not considered for pathfinding. Defaults to `5`. */ - readonly ignore_moving_enemy_collision_distance: double - /** - * A penalty that is applied for another unit that is too close and either not moving or has a different goal. - * Defaults to `30`. - */ - readonly enemy_with_different_destination_collision_penalty: double - /** The general collision penalty with other units. Defaults to `10`. */ - readonly general_entity_collision_penalty: double - /** The collision penalty for positions that require the destruction of an entity to get to. Defaults to `3`. */ - readonly general_entity_subsequent_collision_penalty: double - /** - * The collision penalty for collisions in the extended bounding box but outside the entity's actual bounding box. - * Defaults to `3`. - */ - readonly extended_collision_penalty: double - /** The amount of path finder requests accepted per tick regardless of the requested path's length. Defaults to `10`. */ - readonly max_clients_to_accept_any_new_request: uint - /** - * When the `max_clients_to_accept_any_new_request` amount is exhausted, only path finder requests with a short - * estimate will be accepted until this amount (per tick) is reached. Defaults to `100`. - */ - readonly max_clients_to_accept_short_new_request: uint - /** The maximum direct distance in tiles before a request is no longer considered short. Defaults to `100`. */ - readonly direct_distance_to_consider_short_request: uint - /** The maximum amount of nodes a short request will traverse before being rescheduled as a long request. Defaults to `1000`. */ - readonly short_request_max_steps: uint - /** - * The amount of steps that are allocated to short requests each tick, as a percentage of all available steps. - * Defaults to `0.5`, or 50%. - */ - readonly short_request_ratio: double - /** The minimum amount of steps that are guaranteed to be performed for every request. Defaults to `2000`. */ - readonly min_steps_to_check_path_find_termination: uint - /** - * If the actual amount of steps is higher than the initial estimate by this factor, pathfinding is terminated. - * Defaults to `2000.0`. - */ - readonly start_to_goal_cost_multiplier_to_terminate_path_find: double - /** - * The thresholds of waiting clients after each of which the per-tick work limit will be increased by the - * corresponding value in `overload_multipliers`. This is to avoid clients having to wait too long. Must have the - * same number of elements as `overload_multipliers`. Defaults to `{0, 100, 500}`. - */ - readonly overload_levels: uint[] - /** - * The multipliers to the amount of per-tick work applied after the corresponding thresholds in `overload_levels` - * have been reached. Must have the same number of elements as `overload_multipliers`. Defaults to `{2, 3, 4}`. - */ - readonly overload_multipliers: double[] - /** The delay in ticks between decrementing the score of all paths in the negative cache by one. Defaults to `20`. */ - readonly negative_path_cache_delay_interval: uint -} - -/** - * Various game-related settings. Updating any of the attributes will immediately take effect in the game engine. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#MapSettings View documentation} - * - * @example - * Increase the number of short paths the pathfinder can cache. - * - * ```lua - * game.map_settings.path_finder.short_cache_size = 15 - * ``` - */ -interface MapSettings { - readonly pollution: PollutionMapSettings - readonly enemy_evolution: EnemyEvolutionMapSettings - readonly enemy_expansion: EnemyExpansionMapSettings - readonly unit_group: UnitGroupMapSettings - readonly steering: SteeringMapSettings - readonly path_finder: PathFinderMapSettings - /** - * If a behavior fails this many times, the enemy (or enemy group) is destroyed. This solves biters getting stuck - * within their own base. - */ - readonly max_failed_behavior_count: uint -} - -/** - * Technology and recipe difficulty settings. Updating any of the attributes will immediately take effect in the game engine. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#DifficultySettings View documentation} - */ -interface DifficultySettings { - readonly recipe_difficulty: defines.difficulty_settings.recipe_difficulty - readonly technology_difficulty: defines.difficulty_settings.technology_difficulty - /** A value in range [0.001, 1000]. */ - readonly technology_price_multiplier: double - /** - * Either `"after-victory"`, `"always"` or `"never"`. Changing this to `"always"` or `"after-victory"` does not - * automatically unlock the research queue. See {@link LuaForce} for that. - */ - readonly research_queue_setting: "after-victory" | "always" | "never" -} - -/** - * The data that can be extracted from a map exchange string, as a plain table. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#MapExchangeStringData View documentation} - */ -interface MapExchangeStringData { - /** - * All the regular map settings plus an additional table called `difficulty_settings` that contains the - * {@link DifficultySettings}. - */ - readonly map_settings: MapSettings - readonly map_gen_settings: MapGenSettings -} - -interface BlueprintItemIcon { - /** Name of the item prototype whose icon should be used. */ - readonly name: string - /** Index of the icon in the blueprint icons slots. Has to be an integer in the range [1, 4]. */ - readonly index: uint -} - -interface BlueprintSignalIcon { - /** The icon to use. It can be any item icon as well as any virtual signal icon. */ - readonly signal: SignalID - /** Index of the icon in the blueprint icons slots. Has to be an integer in the range [1, 4]. */ - readonly index: uint -} - -/** - * Information about a single connection between two connection points. - * - * {@link https://wiki.factorio.com/Blueprint_string_format#Connection_data_object View Documentation} - */ -interface BlueprintConnectionData { - /** ID of the entity this connection is connected with. */ - entity_id: uint - /** The circuit connector id of the entity this connection is connected to, see {@link defines.circuit_connector_id} */ - circuit_id?: defines.circuit_connector_id -} - -/** - * The actual point where a wire is connected to. Contains information about where it is connected to. - * - * {@link https://wiki.factorio.com/Blueprint_string_format#Connection_point_object View Documentation} - */ -interface BlueprintConnectionPoint { - /** - * An array of {@link BlueprintConnectionData Connection data object} containing all the connections from this point - * created by red wire. - */ - red?: BlueprintConnectionData[] - /** - * An array of {@link BlueprintConnectionData Connection data object} containing all the connections from this point - * created by green wire. - */ - green?: BlueprintConnectionData[] -} - -/** - * Object containing information about the connections to other entities formed by red or green wires. - * - * {@link https://wiki.factorio.com/Blueprint_string_format#Connection_object View Documentation} - */ -interface BlueprintCircuitConnection { - /** First connection point. The default for everything that doesn't have multiple connection points. */ - "1"?: BlueprintConnectionPoint - /** Second connection point. For example, the "output" part of an arithmetic combinator. */ - "2"?: BlueprintConnectionPoint -} - -/** - * The representation of an entity inside of a blueprint. It has at least these fields, but can contain additional ones - * depending on the kind of entity. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#BlueprintEntity View documentation} - */ -interface BlueprintEntity { - /** The entity's unique identifier in the blueprint. */ - readonly entity_number: uint - /** The prototype name of the entity. */ - readonly name: string - /** The position of the entity. */ - readonly position: Position - /** - * The direction the entity is facing. Only present for entities that can face in different directions and when the - * entity is not facing north. - */ - readonly direction?: defines.direction - /** The entity tags of the entity, if there are any. Only relevant for entity ghosts. */ - readonly tags?: Tags - /** - * The items that the entity will request when revived, if there are any. It's a mapping of prototype names to - * amounts. Only relevant for entity ghosts. - */ - readonly items?: Record - /** - * The circuit network connections of the entity, if there are any. Only relevant for entities that support circuit - * connections. - */ - readonly connections?: BlueprintCircuitConnection - /** - * The control behavior of the entity, if it has one. The format of the control behavior depends on the entity's - * type. Only relevant for entities that support control behaviors. - */ - readonly control_behavior?: BlueprintControlBehavior - /** The schedule of the entity, if it has one. Only relevant for locomotives. */ - readonly schedule?: TrainScheduleRecord[] -} - -interface Tile { - /** The position of the tile. */ - readonly position: Position - /** The prototype name of the tile. */ - readonly name: string -} - -interface Fluid { - /** Fluid prototype name of the fluid. */ - readonly name: string - /** Amount of the fluid. */ - readonly amount: double - /** - * The temperature. When reading from {@link LuaFluidBox}, this field will always be present. It is not necessary to - * specify it when writing, however. When not specified, the fluid will be set to the fluid's default temperature as - * specified in the fluid's prototype. - */ - readonly temperature?: double -} - -interface BaseIngredient { - /** `"item"` or `"fluid"`. */ - readonly type: "item" | "fluid" - /** Prototype name of the required item or fluid. */ - readonly name: string - /** Amount of the item or fluid. */ - readonly amount: double - /** How much of this ingredient is a catalyst. */ - readonly catalyst_amount?: uint | double -} - -interface FluidIngredient extends BaseIngredient { - readonly type: "fluid" - /** The minimum fluid temperature required. */ - readonly minimum_temperature?: double - /** The maximum fluid temperature allowed. */ - readonly maximum_temperature?: double -} - -interface OtherIngredient extends BaseIngredient { - readonly type: "item" -} - -/** - * Other attributes may be specified depending on `type`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#Ingredient View documentation} - */ -type Ingredient = FluidIngredient | OtherIngredient - -interface BaseProduct { - /** `"item"` or `"fluid"`. */ - readonly type: "item" | "fluid" - /** Prototype name of the result. */ - readonly name: string - /** Amount of the item or fluid to give. If not specified, `amount_min`, `amount_max` and `probability` must all be specified. */ - readonly amount?: double - /** Minimal amount of the item or fluid to give. Has no effect when `amount` is specified. */ - readonly amount_min?: uint | double - /** Maximum amount of the item or fluid to give. Has no effect when `amount` is specified. */ - readonly amount_max?: uint | double - /** A value in range [0, 1]. Item or fluid is only given with this probability; otherwise no product is produced. */ - readonly probability?: double - /** How much of this product is a catalyst. */ - readonly catalyst_amount?: uint | double -} - -interface FluidProduct extends BaseProduct { - readonly type: "fluid" - /** The fluid temperature of this product. */ - readonly temperature?: double -} - -interface OtherProduct extends BaseProduct { - readonly type: "item" -} - -/** - * Other attributes may be specified depending on `type`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#Product View documentation} - * - * @example - * Products of the "steel-chest" recipe (an array of Product): - * - * ```lua - * {{type="item", name="steel-chest", amount=1}} - * ``` - * - * @example - * Products of the "advanced-oil-processing" recipe: - * - * ```lua - * {{type="fluid", name="heavy-oil", amount=1}, - * {type="fluid", name="light-oil", amount=4.5}, - * {type="fluid", name="petroleum-gas", amount=5.5}} - * ``` - * - * @example - * What a custom recipe would look like that had a probability of 0.5 to return a minimum amount of 1 and a maximum amount of 5: - * - * ```lua - * {{type=0, name="custom-item", probability=0.5, amount_min=1, amount_max=5}} - * ``` - * - * @see {@link LuaRecipe.products} - */ -type Product = FluidProduct | OtherProduct - -interface Loot { - /** Item prototype name of the result. */ - readonly item: string - /** Probability that any loot at all will drop, as a number in range [0, 1]. */ - readonly probability: double - /** Minimum amount of loot to drop. */ - readonly count_min: double - /** Maximum amount of loot to drop. */ - readonly count_max: double -} - -interface BaseTechnologyModifier { - /** - * Modifier type. Specifies which of the other fields will be available. Possible values are: - * `"inserter-stack-size-bonus"`, `"stack-inserter-capacity-bonus"`, `"laboratory-speed"`, - * `"character-logistic-trash-slots"`, `"maximum-following-robots-count"`, `"worker-robot-speed"`, - * `"worker-robot-storage"`, `"ghost-time-to-live"`, `"turret-attack"`, `"ammo-damage"`, `"give-item"`, - * `"gun-speed"`, `"unlock-recipe"`, `"character-crafting-speed"`, `"character-mining-speed"`, - * `"character-running-speed"`, `"character-build-distance"`, `"character-item-drop-distance"`, - * `"character-reach-distance"`, `"character-resource-reach-distance"`, `"character-item-pickup-distance"`, - * `"character-loot-pickup-distance"`, `"character-inventory-slots-bonus"`, `"deconstruction-time-to-live"`, - * `"max-failed-attempts-per-tick-per-construction-queue"`, - * `"max-successful-attempts-per-tick-per-construction-queue"`, `"character-health-bonus"`, - * `"mining-drill-productivity-bonus"`, `"train-braking-force-bonus"`, `"zoom-to-world-enabled"`, - * `"zoom-to-world-ghost-building-enabled"`, `"zoom-to-world-blueprint-enabled"`, - * `"zoom-to-world-deconstruction-planner-enabled"`, `"zoom-to-world-upgrade-planner-enabled"`, - * `"zoom-to-world-selection-tool-enabled"`, `"worker-robot-battery"`, `"laboratory-productivity"`, - * `"follower-robot-lifetime"`, `"artillery-range"`, `"nothing"`, `"character-additional-mining-categories"`, - * `"character-logistic-requests"`. - */ - readonly type: - | "inserter-stack-size-bonus" - | "stack-inserter-capacity-bonus" - | "laboratory-speed" - | "character-logistic-trash-slots" - | "maximum-following-robots-count" - | "worker-robot-speed" - | "worker-robot-storage" - | "ghost-time-to-live" - | "turret-attack" - | "ammo-damage" - | "give-item" - | "gun-speed" - | "unlock-recipe" - | "character-crafting-speed" - | "character-mining-speed" - | "character-running-speed" - | "character-build-distance" - | "character-item-drop-distance" - | "character-reach-distance" - | "character-resource-reach-distance" - | "character-item-pickup-distance" - | "character-loot-pickup-distance" - | "character-inventory-slots-bonus" - | "deconstruction-time-to-live" - | "max-failed-attempts-per-tick-per-construction-queue" - | "max-successful-attempts-per-tick-per-construction-queue" - | "character-health-bonus" - | "mining-drill-productivity-bonus" - | "train-braking-force-bonus" - | "zoom-to-world-enabled" - | "zoom-to-world-ghost-building-enabled" - | "zoom-to-world-blueprint-enabled" - | "zoom-to-world-deconstruction-planner-enabled" - | "zoom-to-world-upgrade-planner-enabled" - | "zoom-to-world-selection-tool-enabled" - | "worker-robot-battery" - | "laboratory-productivity" - | "follower-robot-lifetime" - | "artillery-range" - | "nothing" - | "character-additional-mining-categories" - | "character-logistic-requests" -} - -interface GunSpeedTechnologyModifier extends BaseTechnologyModifier { - readonly type: "gun-speed" - /** Prototype name of the ammunition category that is affected */ - readonly ammo_category: string - /** Modification value. This will be added to the current gun speed modifier upon researching. */ - readonly modifier: double -} - -interface AmmoDamageTechnologyModifier extends BaseTechnologyModifier { - readonly type: "ammo-damage" - /** Prototype name of the ammunition category that is affected */ - readonly ammo_category: string - /** Modification value. This will be added to the current ammo damage modifier upon researching. */ - readonly modifier: double -} - -interface GiveItemTechnologyModifier extends BaseTechnologyModifier { - readonly type: "give-item" - /** Item prototype name to give. */ - readonly item: string - /** Number of items to give. Defaults to `1`. */ - readonly count?: uint -} - -interface TurretAttackTechnologyModifier extends BaseTechnologyModifier { - readonly type: "turret-attack" - /** Turret prototype name this modifier will affect. */ - readonly turret_id: string - /** Modification value. This will be added to the current turret damage modifier upon researching. */ - readonly modifier: double -} - -interface UnlockRecipeTechnologyModifier extends BaseTechnologyModifier { - readonly type: "unlock-recipe" - /** Recipe prototype name to unlock. */ - readonly recipe: string -} - -interface NothingTechnologyModifier extends BaseTechnologyModifier { - readonly type: "nothing" - /** Description of this nothing modifier. */ - readonly effect_description: LocalisedString -} - -interface OtherTechnologyModifier extends BaseTechnologyModifier { - readonly type: - | "inserter-stack-size-bonus" - | "stack-inserter-capacity-bonus" - | "laboratory-speed" - | "character-logistic-trash-slots" - | "maximum-following-robots-count" - | "worker-robot-speed" - | "worker-robot-storage" - | "ghost-time-to-live" - | "character-crafting-speed" - | "character-mining-speed" - | "character-running-speed" - | "character-build-distance" - | "character-item-drop-distance" - | "character-reach-distance" - | "character-resource-reach-distance" - | "character-item-pickup-distance" - | "character-loot-pickup-distance" - | "character-inventory-slots-bonus" - | "deconstruction-time-to-live" - | "max-failed-attempts-per-tick-per-construction-queue" - | "max-successful-attempts-per-tick-per-construction-queue" - | "character-health-bonus" - | "mining-drill-productivity-bonus" - | "train-braking-force-bonus" - | "zoom-to-world-enabled" - | "zoom-to-world-ghost-building-enabled" - | "zoom-to-world-blueprint-enabled" - | "zoom-to-world-deconstruction-planner-enabled" - | "zoom-to-world-upgrade-planner-enabled" - | "zoom-to-world-selection-tool-enabled" - | "worker-robot-battery" - | "laboratory-productivity" - | "follower-robot-lifetime" - | "artillery-range" - | "character-additional-mining-categories" - | "character-logistic-requests" - /** Modification value. This value will be added to the variable it modifies. */ - readonly modifier: double -} - -/** - * The effect that is applied when a technology is researched. It is a table that contains at least the field `type`. - * - * Other attributes may be specified depending on `type`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#TechnologyModifier View documentation} - */ -type TechnologyModifier = - | GunSpeedTechnologyModifier - | AmmoDamageTechnologyModifier - | GiveItemTechnologyModifier - | TurretAttackTechnologyModifier - | UnlockRecipeTechnologyModifier - | NothingTechnologyModifier - | OtherTechnologyModifier - -/** - * A single offer on a market entity. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#Offer View documentation} - */ -interface Offer { - /** List of prices. */ - readonly price: Ingredient[] - /** The action that will take place when a player accepts the offer. Usually a `"give-item"` modifier. */ - readonly offer: TechnologyModifier -} - -/** - * Specifies how probability and richness are calculated when placing something on the map. Can be specified either - * using `probability_expression` and `richness_expression` or by using all the other fields. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#AutoplaceSpecification View documentation} - */ -interface AutoplaceSpecification { - readonly probability_expression: NoiseExpression - readonly richness_expression: NoiseExpression - readonly coverage: double - readonly sharpness: double - readonly max_probability: double - readonly placement_density: uint - readonly richness_base: double - readonly richness_multiplier: double - readonly richness_multiplier_distance_bonus: double - readonly starting_area_size: uint - readonly order: string - readonly default_enabled: boolean - readonly peaks?: AutoplaceSpecificationPeak[] - /** Control prototype name. */ - readonly control?: string - readonly tile_restriction?: AutoplaceSpecificationRestriction[] - readonly force: string - readonly random_probability_penalty: double -} - -/** - * A fragment of a functional program used to generate coherent noise, probably for purposes related to terrain - * generation. These can only be meaningfully written/modified during the data load phase. More detailed information is - * found on the {@link https://wiki.factorio.com/Types/NoiseExpression wiki}. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#NoiseExpression View documentation} - */ -interface NoiseExpression { - /** Names the type of the expression and determines what other fields are required. */ - readonly type: string -} - -interface AutoplaceSpecificationPeak { - readonly influence: double - readonly max_influence: double - readonly min_influence: double - readonly richness_influence: double - readonly noisePersistence: double - /** Prototype name of the noise layer. */ - readonly noise_layer?: string - readonly noise_octaves_difference: double - readonly water_optimal: double - readonly water_range: double - readonly water_max_range: double - readonly water_top_property_limit: double - readonly elevation_optimal: double - readonly elevation_range: double - readonly elevation_max_range: double - readonly elevation_top_property_limit: double - readonly temperature_optimal: double - readonly temperature_range: double - readonly temperature_max_range: double - readonly temperature_top_property_limit: double - readonly starting_area_weight_optimal: double - readonly starting_area_weight_range: double - readonly starting_area_weight_max_range: double - readonly starting_area_weight_top_property_limit: double - readonly tier_from_start_optimal: double - readonly tier_from_start_range: double - readonly tier_from_start_max_range: double - readonly tier_from_start_top_property_limit: double - readonly distance_optimal: double - readonly distance_range: double - readonly distance_max_range: double - readonly distance_top_property_limit: double - readonly aux_optimal: double - readonly aux_range: double - readonly aux_max_range: double - readonly aux_top_property_limit: double -} - -interface AutoplaceSpecificationRestriction { - /** Tile prototype name */ - readonly first?: string - /** Second prototype name */ - readonly second?: string -} - -interface Resistance { - /** Absolute damage decrease */ - readonly decrease: float - /** Percentual damage decrease */ - readonly percent: float -} - -/** - * A floating point number specifying an amount. - * - * For backwards compatibility, MapGenSizes can also be specified as one of the following strings, which will be - * converted to a number (when queried, a number will always be returned): - * - * - `"none"` - equivalent to `0` - * - `"very-low"`, `"very-small"`, `"very-poor"` - equivalent to `1/2` - * - `"low"`, `"small"`, `"poor"` - equivalent to `1/sqrt(2)` - * - `"normal"`, `"medium"`, `"regular"` - equivalent to `1` - * - `"high"`, `"big"`, `"good"` - equivalent to `sqrt(2)` - * - `"very-high"`, `"very-big"`, `"very-good"` - equivalent to `2` - * - * **Note**: The map generation algorithm officially supports the range of values the in-game map generation screen - * shows (specifically `0` and values from `1/6` to `6`). Values outside this range are not guaranteed to work as expected. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#MapGenSize View documentation} - */ -type MapGenSize = - | number - | "none" - | "very-low" - | "very-small" - | "very-poor" - | "low" - | "small" - | "poor" - | "normal" - | "medium" - | "regular" - | "high" - | "big" - | "good" - | "very-high" - | "very-big" - | "very-good" - -interface AutoplaceSetting { - readonly frequency: MapGenSize - readonly size: MapGenSize - readonly richness: MapGenSize -} - -interface AutoplaceSettings { - /** Whether missing autoplace names for this type should be default enabled. */ - readonly treat_missing_as_default: boolean - readonly settings: Record -} - -interface AutoplaceControl { - /** - * For things that are placed as spots such as ores and enemy bases, frequency is generally proportional to number - * of spots placed per unit area. For continuous features such as forests, frequency is how compressed the - * probability function is over distance, i.e. the inverse of 'scale' (similar to terrain_segmentation). When the - * {@link LuaAutoplaceControlPrototype} is of the category `"terrain"`, then scale is shown in the map generator GUI - * instead of frequency. - */ - readonly frequency: MapGenSize - /** - * For things that are placed as spots, size is proportional to the area of each spot. For continuous features, size - * affects how much of the map is covered with the thing, and is called 'coverage' in the GUI. - */ - readonly size: MapGenSize - /** - * Has different effects for different things, but generally affects the 'health' or density of a thing that is - * placed without affecting where it is placed. For trees, richness affects tree health. For ores, richness - * multiplies the amount of ore at any given tile in a patch. Metadata about autoplace controls (such as whether or - * not 'richness' does anything for them) can be found in the {@link LuaAutoplaceControlPrototype} by looking up - * `game.autoplace_control_prototypes[(control prototype name)]`, e.g. - * `game.autoplace_control_prototypes["enemy-base"].richness` is false, because enemy base autoplacement doesn't use - * richness. - */ - readonly richness: MapGenSize -} - -interface CliffPlacementSettings { - /** Name of the cliff prototype. */ - readonly name: string - /** - * Elevation at which the first row of cliffs is placed. The default is `10`, and this cannot be set from the map - * generation GUI. - */ - readonly cliff_elevation_0: float - /** - * Elevation difference between successive rows of cliffs. This is inversely proportional to 'frequency' in the map - * generation GUI. Specifically, when set from the GUI the value is `40 / frequency`. - */ - readonly cliff_elevation_interval: float - /** - * Corresponds to 'continuity' in the GUI. This value is not used directly, but is used by the 'cliffiness' noise - * expression, which in combination with elevation and the two cliff elevation properties drives cliff placement - * (cliffs are placed when elevation crosses the elevation contours defined by `cliff_elevation_0` and - * `cliff_elevation_interval` when 'cliffiness' is greater than `0.5`). The default 'cliffiness' expression - * interprets this value such that larger values result in longer unbroken walls of cliffs, and smaller values - * (between `0` and `1`) result in larger gaps in cliff walls. - */ - readonly richness: MapGenSize -} - -/** - * The 'map type' dropdown in the map generation GUI is actually a selector for elevation generator. The base game sets - * `property_expression_names.elevation` to `"0_16-elevation"` to reproduce terrain from 0.16 or to `"0_17-island"` for - * the island preset. If generators are available for other properties, the 'map type' dropdown in the GUI will be - * renamed to 'elevation' and shown along with selectors for the other selectable properties. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#MapGenSettings View documentation} - * - * @example - * Assuming a NamedNoiseExpression with the name "my-alternate-grass1-probability" is defined - * - * ```lua - * local surface = game.player.surface - * local mgs = surface.map_gen_settings - * mgs.property_expression_names["tile:grass1:probability"] = "my-alternate-grass1-probability" - * surface.map_gen_settings = mgs - * ``` would override the probability of grass1 being placed at any given point on the current surface. - * - * @example - * To make there be no deep water on (newly generated chunks) a surface: - * - * ```lua - * local surface = game.player.surface - * local mgs = surface.map_gen_settings - * mgs.property_expression_names["tile:deepwater:probability"] = -1000 - * surface.map_gen_settings = mgs - * ``` This does not require a NamedNoiseExpression to be defined, since literal numbers (and strings naming literal numbers, e.g. `"123"`) are understood to stand for constant value expressions. - */ -interface MapGenSettings { - /** - * The inverse of 'water scale' in the map generator GUI. Lower `terrain_segmentation` increases the scale of - * elevation features (lakes, continents, etc). This behavior can be overridden with alternate elevation generators - * (see `property_expression_names`, below). - */ - readonly terrain_segmentation: MapGenSize - /** - * The equivalent to 'water coverage' in the map generator GUI. Specifically, when this value is non-zero, - * `water_level = 10 * log2` (the value of this field), and the elevation generator subtracts water level from - * elevation before adding starting lakes. If water is set to 'none', elevation is clamped to a small positive value - * before adding starting lakes. This behavior can be overridden with alternate elevation generators (see - * `property_expression_names`, below). - */ - readonly water: MapGenSize - /** Indexed by autoplace control prototype name. */ - readonly autoplace_controls: Record - /** Whether undefined `autoplace_controls` should fall back to the default controls or not. Defaults to `true`. */ - readonly default_enable_all_autoplace_controls: boolean - /** - * Each setting in this dictionary maps the string type to the settings for that type. Valid types are `"entity"`, - * `"tile"` and `"decorative"`. - */ - readonly autoplace_settings: Record - /** Map generation settings for entities of the type "cliff". */ - readonly cliff_settings: CliffPlacementSettings - /** The random seed used to generated this map. */ - readonly seed: uint - /** - * Width in tiles. If `0`, the map has 'infinite' width, with the actual limitation being one million tiles in each - * direction from the center. - */ - readonly width: uint - /** - * Height in tiles. If `0`, the map has 'infinite' height, with the actual limitation being one million tiles in - * each direction from the center. - */ - readonly height: uint - /** Size of the starting area. */ - readonly starting_area: MapGenSize - /** Positions of the starting areas. */ - readonly starting_points: Position[] - /** Whether peaceful mode is enabled for this map. */ - readonly peaceful_mode: boolean - /** - * Overrides for tile property value generators. Values either name a NamedNoiseExpression or can be literal - * numbers, stored as strings (e.g. `"5"`). All other controls can be overridden by a property expression names. - * Notable properties: - * - * - `moisture` - a value between 0 and 1 that determines whether a tile becomes sandy (low moisture) or grassy (high moisture). - * - `aux` - a value between 0 and 1 that determines whether low-moisture tiles become sand or red desert. - * - `temperature` - provides a value (vaguely representing degrees Celsius, varying between -20 and 50) that is used - * (together with moisture and aux) as part of tree and decorative placement. - * - `elevation` - tiles values less than zero become water. Cliffs are placed along certain contours according to - * {@link CliffPlacementSettings}. - * - `cliffiness` - determines whether (when >0.5) or not (when <0.5) a cliff will be placed at an otherwise suitable - * (according to {@link CliffPlacementSettings}) location. - * - `enemy-base-intensity` - a number that is referenced by both `enemy-base-frequency` and `enemy-base-radius`. i.e. - * if this is overridden, enemy base frequency and size will both be affected and do something reasonable. By - * default, this expression returns a value proportional to distance from any starting point, clamped at about 7. - * - `enemy-base-frequency` - a number representing average number of enemy bases per tile for a region, by default in - * terms of `enemy-base-intensity`. - * - `enemy-base-radius` - a number representing the radius of an enemy base, if one were to be placed on the given - * tile, by default proportional to a constant plus `enemy-base-intensity`. Climate controls ('Moisture' and - * 'Terrain type' at the bottom of the Terrain tab in the map generator GUI) don't have their own dedicated - * structures in MapGenSettings. Instead, their values are stored as property expression overrides with long names: - * - `control-setting:moisture:frequency:multiplier` - frequency (inverse of scale) multiplier for moisture noise. Default is 1. - * - `control-setting:moisture:bias` - global bias for moisture (which normally varies between 0 and 1). Default is 0. - * - `control-setting:aux:frequency:multiplier` - frequency (inverse of scale) multiplier for aux (called 'terrain - * type' in the GUI) noise. Default is 1. - * - `control-setting:aux:bias` - global bias for aux/terrain type (which normally varies between 0 and 1). Default is - * 0. All other MapGenSettings feed into named noise expressions, and therefore placement can be overridden by - * including the name of a property in this dictionary. The probability and richness functions for placing - * specific tiles, entities, and decoratives can be overridden by including an entry named - * `{tile|entity|decorative}:(prototype name):{probability|richness}`. - */ - readonly property_expression_names: Record -} - -interface SignalID { - /** `"item"`, `"fluid"`, or `"virtual"`. */ - readonly type: "item" | "fluid" | "virtual" - /** Name of the item, fluid or virtual signal. */ - readonly name?: string -} - -/** - * An actual signal transmitted by the network. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#Signal View documentation} - */ -interface Signal { - /** ID of the signal. */ - readonly signal: SignalID - /** Value of the signal. */ - readonly count: int -} - -interface UpgradeFilter { - /** `"item"`, or `"entity"`. */ - readonly type: "item" | "entity" - /** Name of the item, or entity. */ - readonly name?: string -} - -/** - * A single filter used by an infinity-filters instance. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#InfinityInventoryFilter View documentation} - */ -interface InfinityInventoryFilter { - /** Name of the item. */ - readonly name: string - /** The count of the filter. */ - readonly count?: uint - /** `"at-least"`, `"at-most"`, or `"exactly"`. Defaults to `"at-least"`. */ - readonly mode?: "at-least" | "at-most" | "exactly" - /** The index of this filter in the filters list. */ - readonly index: uint -} - -/** - * A single filter used by an infinity-pipe type entity. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#InfinityPipeFilter View documentation} - */ -interface InfinityPipeFilter { - /** Name of the fluid. */ - readonly name: string - /** The fill percentage the pipe (e.g. 0.5 for 50%). Can't be negative. */ - readonly percentage?: double - /** The temperature of the fluid. Defaults to the default/minimum temperature of the fluid. */ - readonly temperature?: double - /** `"at-least"`, `"at-most"`, `"exactly"`, `"add"`, or `"remove"`. Defaults to `"at-least"`. */ - readonly mode?: "at-least" | "at-most" | "exactly" | "add" | "remove" -} - -interface FluidBoxFilter { - /** Fluid prototype name of the filtered fluid. */ - readonly name: string - /** The minimum temperature allowed into the fluidbox. */ - readonly minimum_temperature: double - /** The maximum temperature allowed into the fluidbox. */ - readonly maximum_temperature: double -} - -interface FluidBoxFilterSpec { - /** Fluid prototype name of the filtered fluid. */ - readonly name: string - /** The minimum temperature allowed into the fluidbox. */ - readonly minimum_temperature?: double - /** The maximum temperature allowed into the fluidbox. */ - readonly maximum_temperature?: double - /** Force the filter to be set, regardless of current fluid content. */ - readonly force?: boolean -} - -/** - * The settings used by a heat-interface type entity. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#HeatSetting View documentation} - */ -interface HeatSetting { - /** The target temperature. Defaults to the minimum temperature of the heat buffer. */ - readonly temperature?: double - /** `"at-least"`, `"at-most"`, `"exactly"`, `"add"`, or `"remove"`. Defaults to `"at-least"`. */ - readonly mode?: "at-least" | "at-most" | "exactly" | "add" | "remove" -} - -interface HeatConnection { - readonly position: Vector - readonly direction: defines.direction -} - -/** - * A definition of a fluidbox connection point. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#FluidBoxConnection View documentation} - */ -interface FluidBoxConnection { - /** The connection type: "input", "output", or "input-output". */ - readonly type: "input" | "output" | "input-output" - /** The 4 cardinal direction connection points for this pipe. This vector is a table with `x` and `y` keys instead of an array. */ - readonly positions: PositionTable[] - /** The maximum tile distance this underground connection can connect at if this is an underground pipe. */ - readonly max_underground_distance?: uint -} - -interface ArithmeticCombinatorParameters { - /** First signal to use in an operation. If not specified, the second argument will be the value of `first_constant`. */ - readonly first_signal?: SignalID - /** Second signal to use in an operation. If not specified, the second argument will be the value of `second_constant`. */ - readonly second_signal?: SignalID - /** Constant to use as the first argument of the operation. Has no effect when `first_signal` is set. Defaults to `0`. */ - readonly first_constant?: int - /** Constant to use as the second argument of the operation. Has no effect when `second_signal` is set. Defaults to `0`. */ - readonly second_constant?: int - /** - * Must be one of `"*"`, `"/"`, `"+"`, `"-"`, `"%"`, `"^"`, `"<<"`, `">>"`, `"AND"`, `"OR"`, `"XOR"`. When not - * specified, defaults to `"*"`. - */ - readonly operation?: "*" | "/" | "+" | "-" | "%" | "^" | "<<" | ">>" | "AND" | "OR" | "XOR" - /** Specifies the signal to output. */ - readonly output_signal?: SignalID -} - -interface ConstantCombinatorParameters { - /** Signal to emit. */ - readonly signal: SignalID - /** Value of the signal to emit. */ - readonly count: int - /** Index of the constant combinator's slot to set this signal to. */ - readonly index: uint -} - -/** - * A {@link string} that specifies how the inputs should be compared. - * - * **Note**: While the API accepts both versions for `"less/greater than or equal to"` and `"not equal"`, it'll always - * return `"≥"`, `"≤"` or `"≠"` respectively when reading them back. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#ComparatorString View documentation} - */ -type ComparatorString /** "equal to" */ = - | "=" /** "greater than" */ - | ">" /** "lesser than" */ - | "<" /** "greater than or equal to" */ - | "\u2265" /** "greater than or equal to" */ - | ">=" /** "lesser than or equal to" */ - | "\u2264" /** "lesser than or equal to" */ - | "<=" /** "not equal to" */ - | "\u2260" /** "not equal to" */ - | "!=" - -interface DeciderCombinatorParameters { - /** Defaults to blank. */ - readonly first_signal?: SignalID - /** - * Second signal to use in an operation, if any. If this is not specified, the second argument to a decider - * combinator's operation is assumed to be the value of `constant`. - */ - readonly second_signal?: SignalID - /** Constant to use as the second argument of operation. Defaults to `0`. */ - readonly constant?: uint - /** Specifies how the inputs should be compared. If not specified, defaults to `"<"`. */ - readonly comparator?: ComparatorString - /** Defaults to blank. */ - readonly output_signal?: SignalID - /** Defaults to `true`. When `false`, will output a value of `1` for the given `output_signal`. */ - readonly copy_count_from_input?: boolean -} - -interface InserterCircuitConditions { - readonly circuit?: CircuitCondition - readonly logistics?: CircuitCondition -} - -interface CircuitCondition { - /** Specifies how the inputs should be compared. If not specified, defaults to `"<"`. */ - readonly comparator?: ComparatorString - /** Defaults to blank */ - readonly first_signal?: SignalID - /** What to compare `first_signal` to. If not specified, `first_signal` will be compared to `constant`. */ - readonly second_signal?: SignalID - /** - * Constant to compare `first_signal` to. Has no effect when `second_signal` is set. When neither `second_signal` - * nor `constant` are specified, the effect is as though `constant` were specified with the value `0`. - */ - readonly constant?: int -} - -interface CircuitConditionDefinition { - readonly condition: CircuitCondition - /** Whether the condition is currently fulfilled */ - readonly fulfilled?: boolean -} - -interface CircuitConnectionDefinition { - /** Wire color, either {@link defines.wire_type.red} or {@link defines.wire_type.green}. */ - readonly wire: defines.wire_type - readonly target_entity: LuaEntity - readonly source_circuit_id: defines.circuit_connector_id - readonly target_circuit_id: defines.circuit_connector_id -} - -interface WireConnectionDefinition { - /** Wire color, either {@link defines.wire_type.red} or {@link defines.wire_type.green}. */ - readonly wire: defines.wire_type - /** The entity to (dis)connect the source entity with. */ - readonly target_entity: LuaEntity - /** Mandatory if the source entity has more than one circuit connection using circuit wire. */ - readonly source_circuit_id?: defines.circuit_connector_id - /** Mandatory if the target entity has more than one circuit connection using circuit wire. */ - readonly target_circuit_id?: defines.circuit_connector_id - /** Mandatory if the source entity has more than one wire connection using copper wire. */ - readonly source_wire_id?: defines.circuit_connector_id - /** Mandatory if the target entity has more than one wire connection using copper wire. */ - readonly target_wire_id?: defines.circuit_connector_id -} - -interface InventoryFilter { - /** Position of the corresponding filter slot. */ - readonly index: uint - /** Item prototype name of the item to filter. */ - readonly name: string -} - -interface PlaceAsTileResult { - /** The tile prototype. */ - readonly result: LuaTilePrototype - readonly condition_size: uint - readonly condition: CollisionMask -} - -interface BaseCommand { - /** Type of command. The remaining fields depend on the value of this field. */ - readonly type: defines.command -} - -interface AttackCommand extends BaseCommand { - readonly type: defines.command.attack - readonly target: LuaEntity - /** Defaults to `defines.distraction.by_enemy`. */ - readonly distraction?: defines.distraction -} - -interface GoToLocationCommand extends BaseCommand { - readonly type: defines.command.go_to_location - /** - * The position to path to. Either this or `destination_entity` need to be specified. If both are, - * `destination_entity` is used. - */ - readonly destination?: Position - /** The entity to path to. Either this or `destination` need to be specified. If both are, `destination_entity` is used. */ - readonly destination_entity?: LuaEntity - /** Defaults to `defines.distraction.by_enemy`. */ - readonly distraction?: defines.distraction - /** Flags that affect pathfinder behavior. */ - readonly pathfind_flags?: PathfinderFlags - /** How close the pathfinder needs to get to its destination (in tiles). Defaults to `3`. */ - readonly radius?: double -} - -interface CompoundCommand extends BaseCommand { - readonly type: defines.command.compound - /** How the commands should be chained together. */ - readonly structure_type: defines.compound_command - /** The sub-commands. */ - readonly commands: Command[] -} - -interface GroupCommand extends BaseCommand { - readonly type: defines.command.group - /** The group whose command to follow. */ - readonly group: LuaUnitGroup - /** Defaults to `defines.distraction.by_enemy`. */ - readonly distraction?: defines.distraction - /** Whether the unit will use the group distraction or the commands distraction. Defaults to true. */ - readonly use_group_distraction?: boolean -} - -interface AttackAreaCommand extends BaseCommand { - readonly type: defines.command.attack_area - /** Center of the attack area. */ - readonly destination: Position - /** Radius of the attack area. */ - readonly radius: double - /** Defaults to `defines.distraction.by_enemy`. */ - readonly distraction?: defines.distraction -} - -interface WanderCommand extends BaseCommand { - readonly type: defines.command.wander - /** Defaults to `defines.distraction.by_enemy`. */ - readonly distraction?: defines.distraction - /** Defaults to 10. Does not apply when `wander_in_group` is `true`. */ - readonly radius?: double - /** - * When commanding a group, defines how the group will wander. When `true`, the units in the group will wander - * around inside the group's radius, just like gathering biters. When `false`, the units will wander as a group, ie - * they will all walk together in the same random direction. Default is true for groups. Passing true for a single - * unit is an error. - */ - readonly wander_in_group?: boolean - /** Ticks to wander before successfully completing the command. Default is max uint, which means wander forever. */ - readonly ticks_to_wait?: uint -} - -interface StopCommand extends BaseCommand { - readonly type: defines.command.stop - /** Defaults to `defines.distraction.by_enemy`. */ - readonly distraction?: defines.distraction - /** Ticks to wander before successfully completing the command. Default is max uint, which means stop forever. */ - readonly ticks_to_wait?: uint -} - -interface FleeCommand extends BaseCommand { - readonly type: defines.command.flee - /** The entity to flee from */ - readonly from: LuaEntity - /** Defaults to `defines.distraction.by_enemy`. */ - readonly distraction?: defines.distraction -} - -interface BuildBaseCommand extends BaseCommand { - readonly type: defines.command.build_base - /** Where to build the base. */ - readonly destination: Position - /** Defaults to `defines.distraction.by_enemy`. */ - readonly distraction?: defines.distraction - /** - * Whether the units should ignore expansion candidate chunks. When `false`, they will obey and not build a base in - * a non-candidate chunk. Defaults to `false`. - */ - readonly ignore_planner?: boolean -} - -/** - * Commands can be given to enemies and unit groups. - * - * Other attributes may be specified depending on `type`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#Command View documentation} - */ -type Command = - | AttackCommand - | GoToLocationCommand - | CompoundCommand - | GroupCommand - | AttackAreaCommand - | WanderCommand - | StopCommand - | FleeCommand - | BuildBaseCommand - -interface PathfinderFlags { - /** Allows pathing through friendly entities. Defaults to `false`. */ - readonly allow_destroy_friendly_entities?: boolean - /** Allows the pathfinder to path through entities of the same force. Defaults to `false`. */ - readonly allow_paths_through_own_entities?: boolean - /** - * Enables path caching. This can be more efficient, but might fail to respond to changes in the environment. - * Defaults to `true`. - */ - readonly cache?: boolean - /** Makes the pathfinder try to path in straight lines. Defaults to `false`. */ - readonly prefer_straight_paths?: boolean - /** - * Sets lower priority on the path request, meaning it might take longer to find a path at the expense of speeding - * up others. Defaults to `false`. - */ - readonly low_priority?: boolean - /** - * Makes the pathfinder not break in the middle of processing this pathfind, no matter how much work is needed. - * Defaults to `false`. - */ - readonly no_break?: boolean -} - -interface UnitSpawnDefinition { - /** Prototype name of the unit that would be spawned. */ - readonly unit: string - /** The points at which to spawn the unit. */ - readonly spawn_points: SpawnPointDefinition[] -} - -interface SpawnPointDefinition { - /** Evolution factor for which this weight applies. */ - readonly evolution_factor: double - /** Probability of spawning this unit at this evolution factor. */ - readonly weight: double -} - -interface ItemStackDefinition { - /** Prototype name of the item the stack holds. */ - readonly name: string - /** Number of items the stack holds. If not specified, defaults to `1`. */ - readonly count?: uint - /** Health of the items in the stack. Defaults to `1.0`. */ - readonly health?: float - /** Durability of the tool items in the stack. */ - readonly durability?: double - /** Amount of ammo in the ammo items in the stack. */ - readonly ammo?: double - /** Tags of the items with tags in the stack. */ - readonly tags?: string[] -} - -/** - * - String: The name of the item, which represents a full stack of that item. - * - ItemStackDefinition: The detailed definition of an item stack. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#SimpleItemStack View documentation} - * - * @example - * Both of these lines specify an item stack of one iron plate: - * - * ```lua - * {name="iron-plate"} - * ``` - * - * ```lua - * {name="iron-plate", count=1} - * ``` - * - * @example - * This is a stack of 47 copper plates: - * - * ```lua - * {name="copper-plate", count=47} - * ``` - * - * @example - * These are both full stacks of iron plates (for iron-plate, a full stack is 100 plates): - * - * ```lua - * "iron-plate" - * ``` - * - * ```lua - * {name="iron-plate", count=100} - * ``` - */ -type SimpleItemStack = string | ItemStackDefinition - -/** - * - String: The fluid name. - * - LuaFluidPrototype: The fluid prototype. - * - Fluid: The fluid. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#FluidIdentification View documentation} - */ -type FluidIdentification = string | LuaFluidPrototype | Fluid - -/** - * - String: The force name. - * - LuaForce: A reference to {@link LuaForce} may be passed directly. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#ForceIdentification View documentation} - */ -type ForceIdentification = string | LuaForce - -/** - * - String: The technology name. - * - LuaTechnology: A reference to {@link LuaTechnology} may be passed directly. - * - LuaTechnologyPrototype: A reference to {@link LuaTechnologyPrototype} may be passed directly. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#TechnologyIdentification View documentation} - */ -type TechnologyIdentification = string | LuaTechnology | LuaTechnologyPrototype - -/** - * - Uint: It will be the index of the surface. `nauvis` has index `1`, the first surface-created surface will have index - * `2` and so on. - * - String: It will be the surface name. E.g. `"nauvis"`. - * - LuaSurface: A reference to {@link LuaSurface} may be passed directly. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#SurfaceIdentification View documentation} - */ -type SurfaceIdentification = uint | string | LuaSurface - -/** - * - Uint: The player index. - * - String: The player name. - * - LuaPlayer: A reference to {@link LuaPlayer} may be passed directly. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#PlayerIdentification View documentation} - */ -type PlayerIdentification = uint | string | LuaPlayer - -type ItemStackIdentification = SimpleItemStack | LuaItemStack - -/** - * - LuaEntity: The entity. - * - LuaEntityPrototype: The entity prototype. - * - String: The prototype name. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#EntityPrototypeIdentification View documentation} - */ -type EntityPrototypeIdentification = LuaEntity | LuaEntityPrototype | string - -/** - * - LuaItemStack: The item. - * - LuaItemPrototype: The item prototype. - * - String: The prototype name. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#ItemPrototypeIdentification View documentation} - */ -type ItemPrototypeIdentification = LuaItemStack | LuaItemPrototype | string - -interface WaitCondition { - /** - * One of `"time"`, `"inactivity"`, `"full"`, `"empty"`, `"item_count"`, `"circuit"`, `"robots_inactive"`, - * `"fluid_count"`, `"passenger_present"`, `"passenger_not_present"`. - */ - readonly type: - | "time" - | "inactivity" - | "full" - | "empty" - | "item_count" - | "circuit" - | "robots_inactive" - | "fluid_count" - | "passenger_present" - | "passenger_not_present" - /** - * Either `"and"`, or `"or"`. Tells how this condition is to be compared with the preceding conditions in the - * corresponding `wait_conditions` array. - */ - readonly compare_type: "and" | "or" - /** Number of ticks to wait or of inactivity. Only present when `type` is `"time"` or `"inactivity"`. */ - readonly ticks?: uint - /** Only present when `type` is `"item_count"`, `"circuit"` or `"fluid_count"`. */ - readonly condition?: CircuitCondition -} - -interface TrainScheduleRecord { - /** Name of the station. */ - readonly station?: string - /** Rail to path to. Ignored if `station` is present. */ - readonly rail?: LuaEntity - readonly wait_conditions?: WaitCondition[] - /** Only present when the station is temporary, the value is then always `true`. */ - readonly temporary?: boolean -} - -interface TrainSchedule { - /** Index of the currently active record */ - readonly current: uint - readonly records: TrainScheduleRecord[] -} - -interface BaseGuiArrowSpecification { - /** - * This determines which of the following fields will be required. Must be one of `"nowhere"` (will remove the arrow - * entirely), `"goal"` (will point to the current goal), `"entity_info"`, `"active_window"`, `"entity"`, - * `"position"`, `"crafting_queue"` or `"item_stack"` (will point to a given item stack in an inventory). Depending - * on this value, other fields may have to be specified. - */ - readonly type: - | "nowhere" - | "goal" - | "entity_info" - | "active_window" - | "entity" - | "position" - | "crafting_queue" - | "item_stack" -} - -interface EntityGuiArrowSpecification extends BaseGuiArrowSpecification { - readonly type: "entity" - readonly entity: LuaEntity -} - -interface PositionGuiArrowSpecification extends BaseGuiArrowSpecification { - readonly type: "position" - readonly position: Position -} - -interface CraftingQueueGuiArrowSpecification extends BaseGuiArrowSpecification { - readonly type: "crafting_queue" - /** Index in the crafting queue to point to. */ - readonly crafting_queueindex: uint -} - -interface ItemStackGuiArrowSpecification extends BaseGuiArrowSpecification { - readonly type: "item_stack" - /** Which inventory the stack is in. */ - readonly inventory_index: defines.inventory - /** Which stack to point to. */ - readonly item_stack_index: uint - /** Must be either `"player"`, `"target"`, `"player-quickbar"` or `"player-equipment-bar"`. */ - readonly source: "player" | "target" | "player-quickbar" | "player-equipment-bar" -} - -interface OtherGuiArrowSpecification extends BaseGuiArrowSpecification { - readonly type: "nowhere" | "goal" | "entity_info" | "active_window" -} - -/** - * Used for specifying where a GUI arrow should point to. - * - * Other attributes may be specified depending on `type`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#GuiArrowSpecification View documentation} - */ -type GuiArrowSpecification = - | EntityGuiArrowSpecification - | PositionGuiArrowSpecification - | CraftingQueueGuiArrowSpecification - | ItemStackGuiArrowSpecification - | OtherGuiArrowSpecification - -interface AmmoType { - readonly action?: TriggerItem[] - /** - * One of `"entity"` (fires at an entity), `"position"` (fires directly at a position), or `"direction"` (fires in a - * direction). - */ - readonly target_type: "entity" | "position" | "direction" - /** - * When `true`, the gun will be able to shoot even when the target is out of range. Only applies when `target_type` - * is `position`. The gun will fire at the maximum range in the direction of the target position. Defaults to `false`. - */ - readonly clamp_position?: boolean - /** Ammo category of this ammo. */ - readonly category: string - /** Energy consumption of a single shot, if applicable. Defaults to `0`. */ - readonly energy_consumption?: double -} - -interface BeamTarget { - /** The target entity. */ - readonly entity?: LuaEntity - /** The target position. */ - readonly position?: Position -} - -interface RidingState { - readonly acceleration: defines.riding.acceleration - readonly direction: defines.riding.direction -} - -type SpriteType = - | "item" - | "entity" - | "technology" - | "recipe" - | "item-group" - | "fluid" - | "tile" - | "virtual-signal" - | "achievement" - | "equipment" - | "file" - | "utility" - -/** - * It is specified by {@link string}. It can be either the name of a - * {@link https://wiki.factorio.com/Prototype/Sprite sprite prototype} defined in the data stage or a path in form "type/name". - * - * The supported types are: - * - * - `"item"` - for example "item/iron-plate" is the icon sprite of iron plate - * - `"entity"` - for example "entity/small-biter" is the icon sprite of the small biter - * - `"technology"` - * - `"recipe"` - * - `"item-group"` - * - `"fluid"` - * - `"tile"` - * - `"virtual-signal"` - * - `"achievement"` - * - `"equipment"` - * - `"file"` - path to an image file located inside the current scenario. This file is not preloaded so it will be - * slower; for frequently used sprites, it is better to define sprite prototype and use it instead. - * - `"utility"` - sprite defined in the utility-sprites object, these are the pictures used by the game internally for the UI. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#SpritePath View documentation} - */ -type SpritePath = string | `${SpriteType}/${string}` - -/** - * A sound defined by a {@link string}. It can be either the name of a - * {@link https://wiki.factorio.com/Prototype/Sound sound prototype} defined in the data stage or a path in the form - * `"type/name"`. The latter option can be sorted into three categories. - * - * The utility and ambient types each contain general use sound prototypes defined by the game itself. - * - * - `"utility"` - Uses the {@link https://wiki.factorio.com/Prototype/UtilitySounds UtilitySounds} prototype. Example: - * `"utility/wire_connect_pole"` - * - `"ambient"` - Uses {@link https://wiki.factorio.com/Prototype/AmbientSound AmbientSound} prototypes. Example: - * `"ambient/resource-deficiency"` - * - * The following types can be combined with any tile name as long as its prototype defines the - * - * corresponding sound. - * - * - `"tile-walking"` - Uses {@link https://wiki.factorio.com/Prototype/Tile#walking_sound Tile::walking_sound}. Example: - * `"tile-walking/concrete"` - * - `"tile-mined"` - Uses {@link https://wiki.factorio.com/Prototype/Tile#mined_sound Tile::mined_sound} - * - `"tile-build-small"` - Uses {@link https://wiki.factorio.com/Prototype/Tile#build_sound Tile::build_sound}. Example: - * `"tile-build-small/concrete"` - * - `"tile-build-medium"` - Uses {@link https://wiki.factorio.com/Prototype/Tile#build_sound Tile::build_sound} - * - `"tile-build-large"` - Uses {@link https://wiki.factorio.com/Prototype/Tile#build_sound Tile::build_sound} - * - * The following types can be combined with any entity name as long as its prototype defines the - * - * corresponding sound. - * - * - `"entity-build"` - Uses {@link https://wiki.factorio.com/Prototype/Entity#build_sound Entity::build_sound}. Example: - * `"entity-build/wooden-chest"` - * - `"entity-mined"` - Uses {@link https://wiki.factorio.com/Prototype/Entity#mined_sound Entity::mined_sound} - * - `"entity-mining"` - Uses {@link https://wiki.factorio.com/Prototype/Entity#mining_sound Entity::mining_sound} - * - `"entity-vehicle_impact"` - Uses - * {@link https://wiki.factorio.com/Prototype/Entity#vehicle_impact_sound Entity::vehicle_impact_sound} - * - `"entity-rotated"` - Uses {@link https://wiki.factorio.com/Prototype/Entity#rotated_sound Entity::rotated_sound} - * - `"entity-open"` - Uses {@link https://wiki.factorio.com/Prototype/Entity#open_sound Entity::open_sound} - * - `"entity-close"` - Uses {@link https://wiki.factorio.com/Prototype/Entity#close_sound Entity::close_sound} - * - * {@link https://lua-api.factorio.com/next/Concepts.html#SoundPath View documentation} - */ -type SoundPath = string | `${SoundType}/${string}` - -interface ModuleEffectValue { - /** The percentual increase of the attribute. A value of `0.6` means a 60% increase. */ - readonly bonus: float -} - -/** - * {@link https://lua-api.factorio.com/next/Concepts.html#ModuleEffects View documentation} - * - * @example - * These are the effects of the vanilla Productivity Module 3 (up to floating point imprecisions): - * - * ```lua - * {consumption={bonus=0.6}, - * speed={bonus=-0.15}, - * productivity={bonus=0.06}, - * pollution={bonus=0.075}} - * ``` - */ -interface ModuleEffects { - readonly consumption?: ModuleEffectValue - readonly speed?: ModuleEffectValue - readonly productivity?: ModuleEffectValue - readonly pollution?: ModuleEffectValue -} - -/** - * This is a set of flags given as a dictionary[{@link string} → {@link boolean}]. When a flag is set, it is present in - * the dictionary with the value `true`. Unset flags aren't present in the dictionary at all. So, the boolean value is - * meaningless and exists just for easy table lookup if a flag is set. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#EntityPrototypeFlags View documentation} - */ -interface EntityPrototypeFlags { - readonly "not-rotatable"?: boolean - readonly "placeable-neutral"?: boolean - readonly "placeable-player"?: boolean - readonly "placeable-enemy"?: boolean - readonly "placeable-off-grid"?: boolean - readonly "player-creation"?: boolean - readonly "building-direction-8-way"?: boolean - readonly "filter-directions"?: boolean - readonly "fast-replaceable-no-build-while-moving"?: boolean - readonly "breaths-air"?: boolean - readonly "not-repairable"?: boolean - readonly "not-on-map"?: boolean - readonly "not-deconstructable"?: boolean - readonly "not-blueprintable"?: boolean - readonly hidden?: boolean - readonly "hide-alt-info"?: boolean - readonly "fast-replaceable-no-cross-type-while-moving"?: boolean - readonly "no-gap-fill-while-building"?: boolean - readonly "not-flammable"?: boolean - readonly "no-automated-item-removal"?: boolean - readonly "no-automated-item-insertion"?: boolean - readonly "no-copy-paste"?: boolean - readonly "not-selectable-in-game"?: boolean - readonly "not-upgradable"?: boolean -} - -/** - * This is a set of flags given as dictionary[{@link string} → {@link boolean}]. When a flag is set, it is present in the - * dictionary with the value `true`. Unset flags aren't present in the dictionary at all. So, the boolean value is - * meaningless and exists just for easy table lookup if a flag is set. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#ItemPrototypeFlags View documentation} - */ -interface ItemPrototypeFlags { - readonly "draw-logistic-overlay"?: boolean - readonly hidden?: boolean - readonly "always-show"?: boolean - readonly "hide-from-bonus-gui"?: boolean - readonly "hide-from-fuel-tooltip"?: boolean - readonly "not-stackable"?: boolean - readonly "can-extend-inventory"?: boolean - readonly "primary-place-result"?: boolean - readonly "mod-openable"?: boolean - readonly "only-in-cursor"?: boolean -} - -/** - * A {@link string} specifying a collision mask layer. - * - * Possible values for the string are: - * - * - `"ground-tile"` - * - `"water-tile"` - * - `"resource-layer"` - * - `"doodad-layer"` - * - `"floor-layer"` - * - `"item-layer"` - * - `"ghost-layer"` - * - `"object-layer"` - * - `"player-layer"` - * - `"train-layer"` - * - `"rail-layer"` - * - `"transport-belt-layer"` - * - `"not-setup"` - * - * Additionally the values `"layer-13"` through `"layer-55"`. These layers are currently unused by the game but may - * change. If a mod is going to use one of the unused layers it's recommended to start at the higher layers because the - * base game will take from the lower ones. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#CollisionMaskLayer View documentation} - */ -type CollisionMaskLayer = - | "ground-tile" - | "water-tile" - | "resource-layer" - | "doodad-layer" - | "floor-layer" - | "item-layer" - | "ghost-layer" - | "object-layer" - | "player-layer" - | "train-layer" - | "rail-layer" - | "transport-belt-layer" - | "not-setup" - | `layer-${number}` - -/** - * This is a set of masks given as a dictionary[{@link CollisionMaskLayer} → {@link boolean}]. Only set masks are present - * in the dictionary and they have the value `true`. Unset flags aren't present at all. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#CollisionMask View documentation} - */ -type CollisionMask = { - readonly [P in CollisionMaskLayer]?: true -} - -/** - * A {@link CollisionMask} but also includes any flags this mask has. - * - * Flags such as: - * - * - `"not-colliding-with-itself"` - * - `"consider-tile-transitions"` - * - `"colliding-with-tiles-only"` - * - * {@link https://lua-api.factorio.com/next/Concepts.html#CollisionMaskWithFlags View documentation} - */ -type CollisionMaskWithFlags = { - readonly [P in - | CollisionMaskLayer - | "not-colliding-with-itself" - | "consider-tile-transitions" - | "colliding-with-tiles-only"]?: true -} - -/** - * This is a set of trigger target masks given as a dictionary[{@link string} → {@link boolean}]. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#TriggerTargetMask View documentation} - */ -type TriggerTargetMask = { - readonly [P in string]?: true -} - -interface TriggerEffectItem { - /** - * One of`"damage"`, `"create-entity"`, `"create-explosion"`, `"create-fire"`, `"create-smoke"`, - * `"create-trivial-smoke"`, `"create-particle"`, `"create-sticker"`, `"nested-result"`, `"play-sound"`, - * `"push-back"`, `"destroy-cliffs"`, `"show-explosion-on-chart"`, `"insert-item"`, `"script"`. - */ - readonly type: - | "damage" - | "create-entity" - | "create-explosion" - | "create-fire" - | "create-smoke" - | "create-trivial-smoke" - | "create-particle" - | "create-sticker" - | "nested-result" - | "play-sound" - | "push-back" - | "destroy-cliffs" - | "show-explosion-on-chart" - | "insert-item" - | "script" - readonly repeat_count: uint - readonly affects_target: boolean - readonly show_in_tooltip: boolean -} - -interface TriggerDelivery { - /** One of `"instant"`, `"projectile"`, `"flame-thrower"`, `"beam"`, `"stream"`, `"artillery"`. */ - readonly type: "instant" | "projectile" | "flame-thrower" | "beam" | "stream" | "artillery" - readonly source_effects: TriggerEffectItem[] - readonly target_effects: TriggerEffectItem[] -} - -interface TriggerItem { - /** One of `"direct"`, `"area"`, `"line"`, `"cluster"`. */ - readonly type: "direct" | "area" | "line" | "cluster" - readonly action_delivery?: TriggerDelivery[] - /** The trigger will only affect entities that contain any of these flags. */ - readonly entity_flags?: EntityPrototypeFlags - readonly ignore_collision_condition: boolean - /** The trigger will only affect entities that would collide with given collision mask. */ - readonly collision_mask: CollisionMask - readonly trigger_target_mask: TriggerTargetMask - /** - * If `"enemy"`, the trigger will only affect entities whose force is different from the attacker's and for which - * there is no cease-fire set. `"ally"` is the opposite of `"enemy"`. - */ - readonly force: ForceCondition - readonly repeat_count: uint -} - -interface CircularParticleCreationSpecification { - /** Name of the {@link LuaEntityPrototype} */ - readonly name: string - readonly direction: float - readonly direction_deviation: float - readonly speed: float - readonly speed_deviation: float - readonly starting_frame_speed: float - readonly starting_frame_speed_deviation: float - readonly height: float - readonly height_deviation: float - readonly vertical_speed: float - readonly vertical_speed_deviation: float - /** This vector is a table with `x` and `y` keys instead of an array. */ - readonly center: PositionTable - readonly creation_distance: double - readonly creation_distance_orientation: double - readonly use_source_position: boolean -} - -/** - * An array with the following members: - * - * - A {@link RealOrientation} - * - A {@link Vector} - * - * {@link https://lua-api.factorio.com/next/Concepts.html#CircularProjectileCreationSpecification View documentation} - */ -type CircularProjectileCreationSpecification = [RealOrientation, Vector] - -interface AttackParameterFluid { - /** Name of the {@link LuaFluidPrototype}. */ - readonly type: string - /** Multiplier applied to the damage of an attack. */ - readonly damage_modifier: double -} - -interface BaseAttackParameters { - /** The type of AttackParameter. One of `'projectile'`, `'stream'` or `'beam'`. */ - readonly type: "projectile" | "stream" | "beam" - /** Maximum range of attack. */ - readonly range: float - /** Minimum range of attack. Used with flamethrower turrets to prevent self-immolation. */ - readonly min_range: float - /** Defines how the range is determined. Either `'center-to-center'` or `'bounding-box-to-bounding-box'`. */ - readonly range_mode: "center-to-center" | "bounding-box-to-bounding-box" - /** When searching for the nearest enemy to attack, `fire_penalty` is added to the enemy's distance if they are on fire. */ - readonly fire_penalty: float - /** - * When searching for an enemy to attack, a higher `rotate_penalty` will discourage targeting enemies that would - * take longer to turn to face. - */ - readonly rotate_penalty: float - /** - * When searching for an enemy to attack, a higher `health_penalty` will discourage targeting enemies with high - * health. A negative penalty will do the opposite. - */ - readonly health_penalty: float - /** - * If less than `range`, the entity will choose a random distance between `range` and `min_attack_distance` and - * attack from that distance. Used for spitters. - */ - readonly min_attack_distance: float - /** The arc that the entity can attack in as a fraction of a circle. A value of `1` means the full 360 degrees. */ - readonly turn_range: float - /** Multiplier applied to the damage of an attack. */ - readonly damage_modifier: float - /** Multiplier applied to the ammo consumption of an attack. */ - readonly ammo_consumption_modifier: float - /** Minimum amount of ticks between shots. If this is less than `1`, multiple shots can be performed per tick. */ - readonly cooldown: float - /** Number of ticks it takes for the weapon to actually shoot after it has been ordered to do so. */ - readonly warmup: uint - readonly movement_slow_down_factor: double - readonly movement_slow_down_cooldown: float - readonly ammo_type?: AmmoType - /** List of the names of compatible {@link LuaAmmoCategoryPrototype LuaAmmoCategoryPrototypes}. */ - readonly ammo_categories?: string[] -} - -interface ProjectileAttackParameters extends BaseAttackParameters { - readonly type: "projectile" - readonly projectile_center: Vector - readonly projectile_creation_distance: float - readonly projectile_orientation_offset: float - readonly shell_particle?: CircularParticleCreationSpecification - readonly projectile_creation_parameters?: CircularProjectileCreationSpecification[] -} - -interface StreamAttackParameters extends BaseAttackParameters { - readonly type: "stream" - readonly gun_barrel_length: float - readonly gun_center_shift: Record - readonly fluid_consumption: float - readonly fluids?: AttackParameterFluid[] - readonly projectile_creation_parameters?: CircularProjectileCreationSpecification[] -} - -interface OtherAttackParameters extends BaseAttackParameters { - readonly type: "beam" -} - -/** - * Other attributes may be specified depending on `type`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#AttackParameters View documentation} - */ -type AttackParameters = ProjectileAttackParameters | StreamAttackParameters | OtherAttackParameters - -interface CapsuleAction { - /** One of `"throw"`, `"equipment-remote"`, `"use-on-self"`. */ - readonly type: "throw" | "equipment-remote" | "use-on-self" - /** Only present when `type` is `"throw"` or `"use-on-self"`. */ - readonly attack_parameters?: AttackParameters - /** Only present when `type` is `"equipment-remote"`. It is the equipment prototype name. */ - readonly equipment?: string -} - -/** - * This is a set of flags given as a dictionary[{@link string} → {@link boolean}]. Set flags are present in the dictionary - * with the value `true`; unset flags aren't present at all. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#SelectionModeFlags View documentation} - */ -interface SelectionModeFlags { - /** Entities that can be selected for blueprint. */ - readonly blueprint?: boolean - /** Entities that can be marked for deconstruction. */ - readonly deconstruct?: boolean - /** Entities that can be marked for deconstruction cancelling. */ - readonly "cancel-deconstruct"?: boolean - readonly items?: boolean - readonly trees?: boolean - /** Buildable entities. */ - readonly "buildable-type"?: boolean - /** Only select an area. */ - readonly nothing?: boolean - /** Entities that can be placed using an item. */ - readonly "items-to-place"?: boolean - readonly "any-entity"?: boolean - readonly "any-tile"?: boolean - /** Entities with the same force as the selector. */ - readonly "same-force"?: boolean - readonly "not-same-force"?: boolean - readonly friend?: boolean - readonly enemy?: boolean - readonly upgrade?: boolean - readonly "cancel-upgrade"?: boolean - readonly "entity-with-health"?: boolean - readonly "entity-with-force"?: boolean - readonly "entity-with-owner"?: boolean -} - -interface LogisticFilter { - /** The index this filter applies to. */ - readonly index: uint - /** The item name for this filter. */ - readonly name: string - /** The count for this filter. */ - readonly count: uint -} - -/** - * **Note**: Runtime settings can be changed through console commands and by the mod that owns the settings by writing a - * new table to the ModSetting. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#ModSetting View documentation} - */ -interface ModSetting { - /** The value of the mod setting. The type depends on the setting. */ - readonly value: uint | double | boolean | string -} - -/** - * Any basic type (string, number, boolean) or table. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#AnyBasic View documentation} - */ -type AnyBasic = string | number | boolean | table - -/** - * Any basic type (string, number, boolean), table, or LuaObject. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#Any View documentation} - */ -type Any = any - -interface ProgrammableSpeakerParameters { - readonly playback_volume: double - readonly playback_globally: boolean - readonly allow_polyphony: boolean -} - -interface ProgrammableSpeakerAlertParameters { - readonly show_alert: boolean - readonly show_on_map: boolean - readonly icon_signal_id: SignalID - readonly alert_message: string -} - -interface ProgrammableSpeakerCircuitParameters { - readonly signal_value_is_pitch: boolean - readonly instrument_id: uint - readonly note_id: uint -} - -interface ProgrammableSpeakerInstrument { - readonly name: string - readonly notes: string[] -} - -/** - * A {@link string} that specifies where a gui element should be. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#Alignment View documentation} - */ -type Alignment = - | "top-left" - | "middle-left" /** The same as `"middle-left"` */ - | "left" - | "bottom-left" - | "top-center" - | "middle-center" /** The same as `"middle-center"` */ - | "center" - | "bottom-center" - | "top-right" /** The same as `"middle-right"` */ - | "right" - | "bottom-right" - -/** - * Information about the event that has been raised. The table can also contain other fields depending on the type of - * event. See {@link https://lua-api.factorio.com/next/events.html the list of Factorio events} for more information on these. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#EventData View documentation} - */ -interface EventData { - /** The identifier of the event this handler was registered to. */ - readonly name: EventId - /** The tick during which the event happened. */ - readonly tick: uint - /** The name of the mod that raised the event if it was raised using {@link LuaBootstrap.raise_event LuaBootstrap::raise_event}. */ - readonly mod_name?: string -} - -interface NthTickEventData { - /** The tick during which the event happened. */ - readonly tick: uint - /** The nth tick this handler was registered to. */ - readonly nth_tick: uint -} - -interface ModChangeData { - /** Old version of the mod. May be `nil` if the mod wasn't previously present (i.e. it was just added). */ - readonly old_version: string | undefined - /** New version of the mod. May be `nil` if the mod is no longer present (i.e. it was just removed). */ - readonly new_version: string | undefined -} - -interface ConfigurationChangedData { - /** Old version of the map. Present only when loading map version other than the current version. */ - readonly old_version?: string - /** New version of the map. Present only when loading map version other than the current version. */ - readonly new_version?: string - /** Dictionary of mod changes. It is indexed by mod name. */ - readonly mod_changes: Record - /** `true` when mod startup settings have changed since the last time this save was loaded. */ - readonly mod_startup_settings_changed: boolean - /** `true` when mod prototype migrations have been applied since the last time this save was loaded. */ - readonly migration_applied: boolean -} - -interface CustomCommandData { - /** The name of the command. */ - readonly name: string - /** The tick the command was used in. */ - readonly tick: uint - /** The player who issued the command, or `nil` if it was issued from the server console. */ - readonly player_index?: uint - /** The parameter passed after the command, if there is one. */ - readonly parameter?: string -} - -interface SelectedPrototypeData { - /** E.g. `"entity"`. */ - readonly base_type: string - /** E.g. `"tree"`. */ - readonly derived_type: string - /** E.g. `"tree-05"`. */ - readonly name: string -} - -interface ScriptRenderTarget { - readonly entity?: LuaEntity - readonly entity_offset?: Vector - readonly position?: Position -} - -type MouseButtonFlag = - | "left" - | "right" - | "middle" - | "button-4" - | "button-5" - | "button-6" - | "button-7" - | "button-8" - | "button-9" - -type MouseButtonFlagsTable = { - readonly [P in MouseButtonFlag]?: true -} - -type MouseButtonFlagsArray = readonly (MouseButtonFlag | "left-and-right")[] - -/** - * This is a set of flags given as a dictionary[{@link string} → {@link boolean}]. When a flag is set, it is present in - * the dictionary with the value `true`. Unset flags aren't present in the dictionary at all. - * - * To write to this, use an array[{@link string}] of the mouse buttons that should be possible to use with on button. - * - * When setting flags, the flag `"left-and-right"` can also be set which will set `"left"` and `"right"` true. - * - * Possible flags when reading are: - * - * - `"left"` - * - `"right"` - * - `"middle"` - * - `"button-4"` - * - `"button-5"` - * - `"button-6"` - * - `"button-7"` - * - `"button-8"` - * - `"button-9"` - * - * {@link https://lua-api.factorio.com/next/Concepts.html#MouseButtonFlags View documentation} - */ -type MouseButtonFlags = MouseButtonFlagsTable | MouseButtonFlagsArray - -/** - * It is specified by {@link string}. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#CursorBoxRenderType View documentation} - */ -type CursorBoxRenderType /** Yellow box. */ = - | "entity" /** Red box. */ - | "not-allowed" /** Light blue box. */ - | "electricity" /** Light blue box. */ - | "pair" /** Green box. */ - | "copy" /** White box. */ - | "train-visualization" /** Light blue box. */ - | "logistics" /** Green box. */ - | "blueprint-snap-rectangle" - -/** - * It is specified by {@link string}. - * - * {@link https://lua-api.factorio.com/next/Concepts.html#ForceCondition View documentation} - */ -type ForceCondition /** All forces pass. */ = - | "all" /** Forces which will attack pass. */ - | "enemy" /** Forces which won't attack pass. */ - | "ally" /** Forces which are friends pass. */ - | "friend" /** Forces which are not friends pass. */ - | "not-friend" /** The same force pass. */ - | "same" /** The non-same forces pass. */ - | "not-same" - -/** - * A value between 0 and 255 inclusive represented by one of the following named {@link string} or string version of the - * value (for example `"27"` and `"decals"` are both valid). Higher values are rendered on top of lower values. - * - * - `"water-tile"`: 15 - * - `"ground-tile"`: 25 - * - `"tile-transition"`: 26 - * - `"decals"`: 27 - * - `"lower-radius-visualization"`: 29 - * - `"radius-visualization"`: 30 - * - `"transport-belt-integration"`: 65 - * - `"resource"`:66 - * - `"building-smoke"`:67 - * - `"decorative"`: 92 - * - `"ground-patch"`: 93 - * - `"ground-patch-higher"`: 94 - * - `"ground-patch-higher2"`: 95 - * - `"remnants"`: 112 - * - `"floor"`: 113 - * - `"transport-belt"`: 114 - * - `"transport-belt-endings"`: 115 - * - `"floor-mechanics-under-corpse"`: 120 - * - `"corpse"`: 121 - * - `"floor-mechanics"`: 122 - * - `"item"`: 123 - * - `"lower-object"`: 124 - * - `"transport-belt-circuit-connector"`: 126 - * - `"lower-object-above-shadow"`: 127 - * - `"object"`: 129 - * - `"higher-object-under"`: 131 - * - `"higher-object-above"`: 132 - * - `"item-in-inserter-hand"`: 134 - * - `"wires"`: 135 - * - `"wires-above"`: 136 - * - `"entity-info-icon"`: 138 - * - `"entity-info-icon-above"`: 139 - * - `"explosion"`: 142 - * - `"projectile"`: 143 - * - `"smoke"`: 144 - * - `"air-object"`: 145 - * - `"air-entity-info-icon"`: 147 - * - `"light-effect"`: 148 - * - `"selection-box"`: 187 - * - `"higher-selection-box"`: 188 - * - `"collision-selection-box"`: 189 - * - `"arrow"`: 190 - * - `"cursor"`: 210 - * - * {@link https://lua-api.factorio.com/next/Concepts.html#RenderLayer View documentation} - */ -type RenderLayer = - | number - | `${number}` - | "water-tile" - | "ground-tile" - | "tile-transition" - | "decals" - | "lower-radius-visualization" - | "radius-visualization" - | "transport-belt-integration" - | "resource" - | "building-smoke" - | "decorative" - | "ground-patch" - | "ground-patch-higher" - | "remnants" - | "floor" - | "transport-belt" - | "transport-belt-endings" - | "floor-mechanics-under-corpse" - | "corpse" - | "floor-mechanics" - | "item" - | "lower-object" - | "transport-belt-circuit-connector" - | "lower-object-above-shadow" - | "object" - | "higher-object-under" - | "higher-object-above" - | "item-in-inserter-hand" - | "wires" - | "wires-above" - | "entity-info-icon" - | "entity-info-icon-above" - | "explosion" - | "projectile" - | "smoke" - | "air-object" - | "air-entity-info-icon" - | "light-effect" - | "selection-box" - | "higher-selection-box" - | "collision-selection-box" - | "arrow" - | "cursor" - -type CliffOrientation = - | "west-to-east" - | "north-to-south" - | "east-to-west" - | "south-to-north" - | "west-to-north" - | "north-to-east" - | "east-to-south" - | "south-to-west" - | "west-to-south" - | "north-to-west" - | "east-to-north" - | "south-to-east" - | "west-to-none" - | "none-to-east" - | "east-to-none" - | "none-to-west" - | "north-to-none" - | "none-to-south" - | "south-to-none" - | "none-to-north" - -interface ItemStackLocation { - readonly inventory: defines.inventory - readonly slot: uint -} - -interface VehicleAutomaticTargetingParameters { - readonly auto_target_without_gunner: boolean - readonly auto_target_with_gunner: boolean -} - -type SoundType = "game-effect" | "gui-effect" | "ambient" | "environment" | "walking" | "alert" | "wind" - -interface BaseItemPrototypeFilter { - /** - * The condition to filter on. One of `"tool"`, `"mergeable"`, `"item-with-inventory"`, `"selection-tool"`, - * `"item-with-label"`, `"has-rocket-launch-products"`, `"fuel"`, `"place-result"`, `"burnt-result"`, - * `"place-as-tile"`, `"placed-as-equipment-result"`, `"name"`, `"type"`, `"flag"`, `"subgroup"`, `"fuel-category"`, - * `"stack-size"`, `"default-request-amount"`, `"wire-count"`, `"fuel-value"`, `"fuel-acceleration-multiplier"`, - * `"fuel-top-speed-multiplier"`, `"fuel-emissions-multiplier"` - */ - readonly filter: - | "tool" - | "mergeable" - | "item-with-inventory" - | "selection-tool" - | "item-with-label" - | "has-rocket-launch-products" - | "fuel" - | "place-result" - | "burnt-result" - | "place-as-tile" - | "placed-as-equipment-result" - | "name" - | "type" - | "flag" - | "subgroup" - | "fuel-category" - | "stack-size" - | "default-request-amount" - | "wire-count" - | "fuel-value" - | "fuel-acceleration-multiplier" - | "fuel-top-speed-multiplier" - | "fuel-emissions-multiplier" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface PlaceResultItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: "place-result" - /** Filters for the place result. */ - readonly elem_filters?: EntityPrototypeFilter[] -} - -interface BurntResultItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: "burnt-result" - /** Filters for the burnt result. */ - readonly elem_filters?: ItemPrototypeFilter[] -} - -interface PlaceAsTileItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: "place-as-tile" - /** Filters for the placed tile. */ - readonly elem_filters?: TilePrototypeFilter[] -} - -interface PlacedAsEquipmentResultItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: "placed-as-equipment-result" - /** Filters for the placed equipment. */ - readonly elem_filters?: EquipmentPrototypeFilter[] -} - -/** - * For use within nested filters such as the `has-product-item` filter of array[{@link RecipePrototypeFilter}]. To get a - * specific prototype by name, see {@link LuaGameScript.item_prototypes LuaGameScript::item_prototypes}. - */ -interface NameItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: "name" - /** The prototype name, or list of acceptable names. */ - readonly name: string | string[] -} - -/** - * Usage example: - * - * ```lua - * game.get_filtered_item_prototypes({{filter = "type", type = "armor"}}) - * ``` - */ -interface TypeItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface FlagItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: "flag" - /** One of the values in {@link ItemPrototypeFlags}. */ - readonly flag: string -} - -interface SubgroupItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: "subgroup" - /** A {@link LuaGroup} (subgroup) name */ - readonly subgroup: string -} - -interface FuelCategoryItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: "fuel-category" - /** A {@link LuaFuelCategoryPrototype} name */ - readonly "fuel-category": string -} - -/** - * Usage example: - * - * ```lua - * game.get_filtered_item_prototypes({{filter = "stack-size", comparison = ">", value = 20}, {filter = "stack-size", comparison = "<", value = 100, mode = "and"}}) - * ``` - */ -interface StackSizeItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: "stack-size" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: uint -} - -interface DefaultRequestAmountItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: "default-request-amount" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: uint -} - -interface WireCountItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: "wire-count" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: uint -} - -interface FuelValueItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: "fuel-value" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface FuelAccelerationMultiplierItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: "fuel-acceleration-multiplier" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface FuelTopSpeedMultiplierItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: "fuel-top-speed-multiplier" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface FuelEmissionsMultiplierItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: "fuel-emissions-multiplier" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface OtherItemPrototypeFilter extends BaseItemPrototypeFilter { - readonly filter: - | "tool" - | "mergeable" - | "item-with-inventory" - | "selection-tool" - | "item-with-label" - | "has-rocket-launch-products" - | "fuel" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#ItemPrototypeFilter View documentation} - */ -type ItemPrototypeFilter = - | PlaceResultItemPrototypeFilter - | BurntResultItemPrototypeFilter - | PlaceAsTileItemPrototypeFilter - | PlacedAsEquipmentResultItemPrototypeFilter - | NameItemPrototypeFilter - | TypeItemPrototypeFilter - | FlagItemPrototypeFilter - | SubgroupItemPrototypeFilter - | FuelCategoryItemPrototypeFilter - | StackSizeItemPrototypeFilter - | DefaultRequestAmountItemPrototypeFilter - | WireCountItemPrototypeFilter - | FuelValueItemPrototypeFilter - | FuelAccelerationMultiplierItemPrototypeFilter - | FuelTopSpeedMultiplierItemPrototypeFilter - | FuelEmissionsMultiplierItemPrototypeFilter - | OtherItemPrototypeFilter - -interface BaseModSettingPrototypeFilter { - /** The condition to filter on. One of `"type"`, `"mod"`, `"setting-type"` */ - readonly filter: "type" | "mod" | "setting-type" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypeModSettingPrototypeFilter extends BaseModSettingPrototypeFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface ModModSettingPrototypeFilter extends BaseModSettingPrototypeFilter { - readonly filter: "mod" - /** The mod name */ - readonly mod: string -} - -interface SettingTypeModSettingPrototypeFilter extends BaseModSettingPrototypeFilter { - readonly filter: "setting-type" - /** The setting scope type (startup, runtime-global, or runtime-per-user) */ - readonly type: string -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#ModSettingPrototypeFilter View documentation} - */ -type ModSettingPrototypeFilter = - | TypeModSettingPrototypeFilter - | ModModSettingPrototypeFilter - | SettingTypeModSettingPrototypeFilter - -interface BaseTechnologyPrototypeFilter { - /** - * The condition to filter on. One of `"enabled"`, `"hidden"`, `"upgrade"`, `"visible-when-disabled"`, - * `"has-effects"`, `"has-prerequisites"`, `"research-unit-ingredient"`, `"level"`, `"max-level"`, `"time"` - */ - readonly filter: - | "enabled" - | "hidden" - | "upgrade" - | "visible-when-disabled" - | "has-effects" - | "has-prerequisites" - | "research-unit-ingredient" - | "level" - | "max-level" - | "time" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface ResearchUnitIngredientTechnologyPrototypeFilter extends BaseTechnologyPrototypeFilter { - readonly filter: "research-unit-ingredient" - /** The research ingredient to check. */ - readonly ingredient: string -} - -interface LevelTechnologyPrototypeFilter extends BaseTechnologyPrototypeFilter { - readonly filter: "level" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: uint -} - -interface MaxLevelTechnologyPrototypeFilter extends BaseTechnologyPrototypeFilter { - readonly filter: "max-level" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: uint -} - -interface TimeTechnologyPrototypeFilter extends BaseTechnologyPrototypeFilter { - readonly filter: "time" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: uint -} - -interface OtherTechnologyPrototypeFilter extends BaseTechnologyPrototypeFilter { - readonly filter: "enabled" | "hidden" | "upgrade" | "visible-when-disabled" | "has-effects" | "has-prerequisites" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#TechnologyPrototypeFilter View documentation} - */ -type TechnologyPrototypeFilter = - | ResearchUnitIngredientTechnologyPrototypeFilter - | LevelTechnologyPrototypeFilter - | MaxLevelTechnologyPrototypeFilter - | TimeTechnologyPrototypeFilter - | OtherTechnologyPrototypeFilter - -interface BaseDecorativePrototypeFilter { - /** The condition to filter on. One of `"decal"`, `"autoplace"`, `"collision-mask"` */ - readonly filter: "decal" | "autoplace" | "collision-mask" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface CollisionMaskDecorativePrototypeFilter extends BaseDecorativePrototypeFilter { - readonly filter: "collision-mask" - readonly mask: CollisionMask | CollisionMaskWithFlags - /** How to filter: `"collides"` or `"layers-equals"` */ - readonly mask_mode: "collides" | "layers-equals" -} - -interface OtherDecorativePrototypeFilter extends BaseDecorativePrototypeFilter { - readonly filter: "decal" | "autoplace" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#DecorativePrototypeFilter View documentation} - */ -type DecorativePrototypeFilter = CollisionMaskDecorativePrototypeFilter | OtherDecorativePrototypeFilter - -interface BaseAchievementPrototypeFilter { - /** The condition to filter on. One of `"allowed-without-fight"`, `"type"` */ - readonly filter: "allowed-without-fight" | "type" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypeAchievementPrototypeFilter extends BaseAchievementPrototypeFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface OtherAchievementPrototypeFilter extends BaseAchievementPrototypeFilter { - readonly filter: "allowed-without-fight" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#AchievementPrototypeFilter View documentation} - */ -type AchievementPrototypeFilter = TypeAchievementPrototypeFilter | OtherAchievementPrototypeFilter - -interface BaseFluidPrototypeFilter { - /** - * The condition to filter on. One of `"hidden"`, `"name"`, `"subgroup"`, `"default-temperature"`, - * `"max-temperature"`, `"heat-capacity"`, `"fuel-value"`, `"emissions-multiplier"`, `"gas-temperature"` - */ - readonly filter: - | "hidden" - | "name" - | "subgroup" - | "default-temperature" - | "max-temperature" - | "heat-capacity" - | "fuel-value" - | "emissions-multiplier" - | "gas-temperature" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -/** - * For use within nested filters such as the `has-product-fluid` filter of array[{@link RecipePrototypeFilter}]. To get a - * specific prototype by name, see {@link LuaGameScript.fluid_prototypes LuaGameScript::fluid_prototypes}. - */ -interface NameFluidPrototypeFilter extends BaseFluidPrototypeFilter { - readonly filter: "name" - /** The prototype name, or list of acceptable names. */ - readonly name: string | string[] -} - -interface SubgroupFluidPrototypeFilter extends BaseFluidPrototypeFilter { - readonly filter: "subgroup" - /** A {@link LuaGroup} (subgroup) name */ - readonly subgroup: string -} - -interface DefaultTemperatureFluidPrototypeFilter extends BaseFluidPrototypeFilter { - readonly filter: "default-temperature" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface MaxTemperatureFluidPrototypeFilter extends BaseFluidPrototypeFilter { - readonly filter: "max-temperature" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface HeatCapacityFluidPrototypeFilter extends BaseFluidPrototypeFilter { - readonly filter: "heat-capacity" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface FuelValueFluidPrototypeFilter extends BaseFluidPrototypeFilter { - readonly filter: "fuel-value" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface EmissionsMultiplierFluidPrototypeFilter extends BaseFluidPrototypeFilter { - readonly filter: "emissions-multiplier" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface GasTemperatureFluidPrototypeFilter extends BaseFluidPrototypeFilter { - readonly filter: "gas-temperature" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface OtherFluidPrototypeFilter extends BaseFluidPrototypeFilter { - readonly filter: "hidden" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#FluidPrototypeFilter View documentation} - */ -type FluidPrototypeFilter = - | NameFluidPrototypeFilter - | SubgroupFluidPrototypeFilter - | DefaultTemperatureFluidPrototypeFilter - | MaxTemperatureFluidPrototypeFilter - | HeatCapacityFluidPrototypeFilter - | FuelValueFluidPrototypeFilter - | EmissionsMultiplierFluidPrototypeFilter - | GasTemperatureFluidPrototypeFilter - | OtherFluidPrototypeFilter - -interface BaseEquipmentPrototypeFilter { - /** The condition to filter on. One of `"item-to-place"`, `"type"` */ - readonly filter: "item-to-place" | "type" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypeEquipmentPrototypeFilter extends BaseEquipmentPrototypeFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface OtherEquipmentPrototypeFilter extends BaseEquipmentPrototypeFilter { - readonly filter: "item-to-place" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#EquipmentPrototypeFilter View documentation} - */ -type EquipmentPrototypeFilter = TypeEquipmentPrototypeFilter | OtherEquipmentPrototypeFilter - -interface BaseTilePrototypeFilter { - /** - * The condition to filter on. One of `"minable"`, `"autoplace"`, `"blueprintable"`, `"item-to-place"`, - * `"collision-mask"`, `"walking-speed-modifier"`, `"vehicle-friction-modifier"`, - * `"decorative-removal-probability"`, `"emissions"` - */ - readonly filter: - | "minable" - | "autoplace" - | "blueprintable" - | "item-to-place" - | "collision-mask" - | "walking-speed-modifier" - | "vehicle-friction-modifier" - | "decorative-removal-probability" - | "emissions" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface CollisionMaskTilePrototypeFilter extends BaseTilePrototypeFilter { - readonly filter: "collision-mask" - readonly mask: CollisionMask | CollisionMaskWithFlags - /** How to filter: `"collides"` or `"layers-equals"` */ - readonly mask_mode: "collides" | "layers-equals" -} - -interface WalkingSpeedModifierTilePrototypeFilter extends BaseTilePrototypeFilter { - readonly filter: "walking-speed-modifier" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface VehicleFrictionModifierTilePrototypeFilter extends BaseTilePrototypeFilter { - readonly filter: "vehicle-friction-modifier" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface DecorativeRemovalProbabilityTilePrototypeFilter extends BaseTilePrototypeFilter { - readonly filter: "decorative-removal-probability" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: float -} - -interface EmissionsTilePrototypeFilter extends BaseTilePrototypeFilter { - readonly filter: "emissions" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface OtherTilePrototypeFilter extends BaseTilePrototypeFilter { - readonly filter: "minable" | "autoplace" | "blueprintable" | "item-to-place" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#TilePrototypeFilter View documentation} - */ -type TilePrototypeFilter = - | CollisionMaskTilePrototypeFilter - | WalkingSpeedModifierTilePrototypeFilter - | VehicleFrictionModifierTilePrototypeFilter - | DecorativeRemovalProbabilityTilePrototypeFilter - | EmissionsTilePrototypeFilter - | OtherTilePrototypeFilter - -interface BaseRecipePrototypeFilter { - /** - * The condition to filter on. One of `"enabled"`, `"hidden"`, `"hidden-from-flow-stats"`, - * `"hidden-from-player-crafting"`, `"allow-as-intermediate"`, `"allow-intermediates"`, `"allow-decomposition"`, - * `"always-show-made-in"`, `"always-show-products"`, `"show-amount-in-title"`, `"has-ingredients"`, - * `"has-products"`, `"has-ingredient-item"`, `"has-ingredient-fluid"`, `"has-product-item"`, `"has-product-fluid"`, - * `"subgroup"`, `"category"`, `"energy"`, `"emissions-multiplier"`, `"request-paste-multiplier"`, `"overload-multiplier"` - */ - readonly filter: - | "enabled" - | "hidden" - | "hidden-from-flow-stats" - | "hidden-from-player-crafting" - | "allow-as-intermediate" - | "allow-intermediates" - | "allow-decomposition" - | "always-show-made-in" - | "always-show-products" - | "show-amount-in-title" - | "has-ingredients" - | "has-products" - | "has-ingredient-item" - | "has-ingredient-fluid" - | "has-product-item" - | "has-product-fluid" - | "subgroup" - | "category" - | "energy" - | "emissions-multiplier" - | "request-paste-multiplier" - | "overload-multiplier" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface HasIngredientItemRecipePrototypeFilter extends BaseRecipePrototypeFilter { - readonly filter: "has-ingredient-item" - /** Matches if at least 1 ingredient is an item that matches these filters. */ - readonly elem_filters?: ItemPrototypeFilter[] -} - -/** - * Usage example: - * - * ```lua - * -- selects recipes that consume sulfuric acid - * {{filter = "has-ingredient-fluid", elem_filters = {{filter = "name", name = "sulfuric-acid"}}}} - * ``` - */ -interface HasIngredientFluidRecipePrototypeFilter extends BaseRecipePrototypeFilter { - readonly filter: "has-ingredient-fluid" - /** Matches if at least 1 ingredient is a fluid that matches these filters. */ - readonly elem_filters?: FluidPrototypeFilter[] -} - -/** - * Usage example: - * - * ```lua - * -- selects recipes that produce an item - * {{filter = "has-product-item"}} - * -- selects recipes that produce iron plates - * {{filter = "has-product-item", elem_filters = {{filter = "name", name = "iron-plate"}}}} - * -- selects recipes that produce items that place furnaces - * {{filter = "has-product-item", elem_filters = {{filter = "place-result", elem_filters = {{filter = "type", type = "furnace"}}}}}} - * ``` - */ -interface HasProductItemRecipePrototypeFilter extends BaseRecipePrototypeFilter { - readonly filter: "has-product-item" - /** Matches if at least 1 product is an item that matches these filters. */ - readonly elem_filters?: ItemPrototypeFilter[] -} - -interface HasProductFluidRecipePrototypeFilter extends BaseRecipePrototypeFilter { - readonly filter: "has-product-fluid" - /** Matches if at least 1 product is a fluid that matches these filters. */ - readonly elem_filters?: FluidPrototypeFilter[] -} - -interface SubgroupRecipePrototypeFilter extends BaseRecipePrototypeFilter { - readonly filter: "subgroup" - /** A {@link LuaGroup} (subgroup) name */ - readonly subgroup: string -} - -interface CategoryRecipePrototypeFilter extends BaseRecipePrototypeFilter { - readonly filter: "category" - /** A {@link LuaRecipeCategoryPrototype} name */ - readonly category: string -} - -interface EnergyRecipePrototypeFilter extends BaseRecipePrototypeFilter { - readonly filter: "energy" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface EmissionsMultiplierRecipePrototypeFilter extends BaseRecipePrototypeFilter { - readonly filter: "emissions-multiplier" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface RequestPasteMultiplierRecipePrototypeFilter extends BaseRecipePrototypeFilter { - readonly filter: "request-paste-multiplier" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: uint -} - -interface OverloadMultiplierRecipePrototypeFilter extends BaseRecipePrototypeFilter { - readonly filter: "overload-multiplier" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: uint -} - -interface OtherRecipePrototypeFilter extends BaseRecipePrototypeFilter { - readonly filter: - | "enabled" - | "hidden" - | "hidden-from-flow-stats" - | "hidden-from-player-crafting" - | "allow-as-intermediate" - | "allow-intermediates" - | "allow-decomposition" - | "always-show-made-in" - | "always-show-products" - | "show-amount-in-title" - | "has-ingredients" - | "has-products" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#RecipePrototypeFilter View documentation} - */ -type RecipePrototypeFilter = - | HasIngredientItemRecipePrototypeFilter - | HasIngredientFluidRecipePrototypeFilter - | HasProductItemRecipePrototypeFilter - | HasProductFluidRecipePrototypeFilter - | SubgroupRecipePrototypeFilter - | CategoryRecipePrototypeFilter - | EnergyRecipePrototypeFilter - | EmissionsMultiplierRecipePrototypeFilter - | RequestPasteMultiplierRecipePrototypeFilter - | OverloadMultiplierRecipePrototypeFilter - | OtherRecipePrototypeFilter - -interface BaseEntityPrototypeFilter { - /** - * The condition to filter on. One of `"flying-robot"`, `"robot-with-logistics-interface"`, `"rail"`, `"ghost"`, - * `"explosion"`, `"vehicle"`, `"crafting-machine"`, `"rolling-stock"`, `"turret"`, `"transport-belt-connectable"`, - * `"wall-connectable"`, `"buildable"`, `"placable-in-editor"`, `"clonable"`, `"selectable"`, `"hidden"`, - * `"entity-with-health"`, `"building"`, `"fast-replaceable"`, `"uses-direction"`, `"minable"`, - * `"circuit-connectable"`, `"autoplace"`, `"blueprintable"`, `"item-to-place"`, `"name"`, `"type"`, - * `"collision-mask"`, `"flag"`, `"build-base-evolution-requirement"`, `"selection-priority"`, `"emissions"`, - * `"crafting-category"` - */ - readonly filter: - | "flying-robot" - | "robot-with-logistics-interface" - | "rail" - | "ghost" - | "explosion" - | "vehicle" - | "crafting-machine" - | "rolling-stock" - | "turret" - | "transport-belt-connectable" - | "wall-connectable" - | "buildable" - | "placable-in-editor" - | "clonable" - | "selectable" - | "hidden" - | "entity-with-health" - | "building" - | "fast-replaceable" - | "uses-direction" - | "minable" - | "circuit-connectable" - | "autoplace" - | "blueprintable" - | "item-to-place" - | "name" - | "type" - | "collision-mask" - | "flag" - | "build-base-evolution-requirement" - | "selection-priority" - | "emissions" - | "crafting-category" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -/** - * For use within nested filters such as the `place-result` filter of array[{@link ItemPrototypeFilter}]. To get a - * specific prototype by name, see {@link LuaGameScript.entity_prototypes LuaGameScript::entity_prototypes}. - */ -interface NameEntityPrototypeFilter extends BaseEntityPrototypeFilter { - readonly filter: "name" - /** The prototype name, or list of acceptable names. */ - readonly name: string | string[] -} - -/** - * Usage example: - * - * ```lua - * game.get_filtered_entity_prototypes({{filter = "type", type = "unit"}}) - * ``` - */ -interface TypeEntityPrototypeFilter extends BaseEntityPrototypeFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -/** - * Usage example: - * - * ```lua - * game.get_filtered_entity_prototypes({{filter = "collision-mask", mask = "player-layer", mask_mode = "collides"}}) - * ``` - */ -interface CollisionMaskEntityPrototypeFilter extends BaseEntityPrototypeFilter { - readonly filter: "collision-mask" - readonly mask: CollisionMask | CollisionMaskWithFlags - /** How to filter: `"collides"` or `"layers-equals"` */ - readonly mask_mode: "collides" | "layers-equals" -} - -/** - * Usage example: - * - * ```lua - * game.get_filtered_entity_prototypes({{filter = "flag", flag = "placeable-player"}, {filter = "flag", flag = "placeable-enemy", mode = "and"}}) - * ``` - */ -interface FlagEntityPrototypeFilter extends BaseEntityPrototypeFilter { - readonly filter: "flag" - /** One of the values in {@link EntityPrototypeFlags}. */ - readonly flag: string -} - -interface BuildBaseEvolutionRequirementEntityPrototypeFilter extends BaseEntityPrototypeFilter { - readonly filter: "build-base-evolution-requirement" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface SelectionPriorityEntityPrototypeFilter extends BaseEntityPrototypeFilter { - readonly filter: "selection-priority" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: uint8 -} - -interface EmissionsEntityPrototypeFilter extends BaseEntityPrototypeFilter { - readonly filter: "emissions" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: double -} - -interface CraftingCategoryEntityPrototypeFilter extends BaseEntityPrototypeFilter { - readonly filter: "crafting-category" - /** Matches if the prototype is for a crafting machine with this crafting category. */ - readonly crafting_category: string -} - -interface OtherEntityPrototypeFilter extends BaseEntityPrototypeFilter { - readonly filter: - | "flying-robot" - | "robot-with-logistics-interface" - | "rail" - | "ghost" - | "explosion" - | "vehicle" - | "crafting-machine" - | "rolling-stock" - | "turret" - | "transport-belt-connectable" - | "wall-connectable" - | "buildable" - | "placable-in-editor" - | "clonable" - | "selectable" - | "hidden" - | "entity-with-health" - | "building" - | "fast-replaceable" - | "uses-direction" - | "minable" - | "circuit-connectable" - | "autoplace" - | "blueprintable" - | "item-to-place" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#EntityPrototypeFilter View documentation} - */ -type EntityPrototypeFilter = - | NameEntityPrototypeFilter - | TypeEntityPrototypeFilter - | CollisionMaskEntityPrototypeFilter - | FlagEntityPrototypeFilter - | BuildBaseEvolutionRequirementEntityPrototypeFilter - | SelectionPriorityEntityPrototypeFilter - | EmissionsEntityPrototypeFilter - | CraftingCategoryEntityPrototypeFilter - | OtherEntityPrototypeFilter - -interface BaseScriptRaisedReviveEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypeScriptRaisedReviveEventFilter extends BaseScriptRaisedReviveEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NameScriptRaisedReviveEventFilter extends BaseScriptRaisedReviveEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypeScriptRaisedReviveEventFilter extends BaseScriptRaisedReviveEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNameScriptRaisedReviveEventFilter extends BaseScriptRaisedReviveEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OtherScriptRaisedReviveEventFilter extends BaseScriptRaisedReviveEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaScriptRaisedReviveEventFilter View documentation} - */ -type LuaScriptRaisedReviveEventFilter = - | TypeScriptRaisedReviveEventFilter - | NameScriptRaisedReviveEventFilter - | GhostTypeScriptRaisedReviveEventFilter - | GhostNameScriptRaisedReviveEventFilter - | OtherScriptRaisedReviveEventFilter - -interface BaseEntityDiedEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypeEntityDiedEventFilter extends BaseEntityDiedEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NameEntityDiedEventFilter extends BaseEntityDiedEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypeEntityDiedEventFilter extends BaseEntityDiedEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNameEntityDiedEventFilter extends BaseEntityDiedEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OtherEntityDiedEventFilter extends BaseEntityDiedEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaEntityDiedEventFilter View documentation} - */ -type LuaEntityDiedEventFilter = - | TypeEntityDiedEventFilter - | NameEntityDiedEventFilter - | GhostTypeEntityDiedEventFilter - | GhostNameEntityDiedEventFilter - | OtherEntityDiedEventFilter - -interface BaseEntityMarkedForDeconstructionEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypeEntityMarkedForDeconstructionEventFilter extends BaseEntityMarkedForDeconstructionEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NameEntityMarkedForDeconstructionEventFilter extends BaseEntityMarkedForDeconstructionEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypeEntityMarkedForDeconstructionEventFilter extends BaseEntityMarkedForDeconstructionEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNameEntityMarkedForDeconstructionEventFilter extends BaseEntityMarkedForDeconstructionEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OtherEntityMarkedForDeconstructionEventFilter extends BaseEntityMarkedForDeconstructionEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaEntityMarkedForDeconstructionEventFilter View documentation} - */ -type LuaEntityMarkedForDeconstructionEventFilter = - | TypeEntityMarkedForDeconstructionEventFilter - | NameEntityMarkedForDeconstructionEventFilter - | GhostTypeEntityMarkedForDeconstructionEventFilter - | GhostNameEntityMarkedForDeconstructionEventFilter - | OtherEntityMarkedForDeconstructionEventFilter - -interface BasePreGhostDeconstructedEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypePreGhostDeconstructedEventFilter extends BasePreGhostDeconstructedEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NamePreGhostDeconstructedEventFilter extends BasePreGhostDeconstructedEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypePreGhostDeconstructedEventFilter extends BasePreGhostDeconstructedEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNamePreGhostDeconstructedEventFilter extends BasePreGhostDeconstructedEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OtherPreGhostDeconstructedEventFilter extends BasePreGhostDeconstructedEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaPreGhostDeconstructedEventFilter View documentation} - */ -type LuaPreGhostDeconstructedEventFilter = - | TypePreGhostDeconstructedEventFilter - | NamePreGhostDeconstructedEventFilter - | GhostTypePreGhostDeconstructedEventFilter - | GhostNamePreGhostDeconstructedEventFilter - | OtherPreGhostDeconstructedEventFilter - -interface BaseScriptRaisedDestroyEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypeScriptRaisedDestroyEventFilter extends BaseScriptRaisedDestroyEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NameScriptRaisedDestroyEventFilter extends BaseScriptRaisedDestroyEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypeScriptRaisedDestroyEventFilter extends BaseScriptRaisedDestroyEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNameScriptRaisedDestroyEventFilter extends BaseScriptRaisedDestroyEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OtherScriptRaisedDestroyEventFilter extends BaseScriptRaisedDestroyEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaScriptRaisedDestroyEventFilter View documentation} - */ -type LuaScriptRaisedDestroyEventFilter = - | TypeScriptRaisedDestroyEventFilter - | NameScriptRaisedDestroyEventFilter - | GhostTypeScriptRaisedDestroyEventFilter - | GhostNameScriptRaisedDestroyEventFilter - | OtherScriptRaisedDestroyEventFilter - -interface BaseUpgradeCancelledEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypeUpgradeCancelledEventFilter extends BaseUpgradeCancelledEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NameUpgradeCancelledEventFilter extends BaseUpgradeCancelledEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypeUpgradeCancelledEventFilter extends BaseUpgradeCancelledEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNameUpgradeCancelledEventFilter extends BaseUpgradeCancelledEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OtherUpgradeCancelledEventFilter extends BaseUpgradeCancelledEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaUpgradeCancelledEventFilter View documentation} - */ -type LuaUpgradeCancelledEventFilter = - | TypeUpgradeCancelledEventFilter - | NameUpgradeCancelledEventFilter - | GhostTypeUpgradeCancelledEventFilter - | GhostNameUpgradeCancelledEventFilter - | OtherUpgradeCancelledEventFilter - -interface BasePlayerRepairedEntityEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypePlayerRepairedEntityEventFilter extends BasePlayerRepairedEntityEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NamePlayerRepairedEntityEventFilter extends BasePlayerRepairedEntityEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypePlayerRepairedEntityEventFilter extends BasePlayerRepairedEntityEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNamePlayerRepairedEntityEventFilter extends BasePlayerRepairedEntityEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OtherPlayerRepairedEntityEventFilter extends BasePlayerRepairedEntityEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaPlayerRepairedEntityEventFilter View documentation} - */ -type LuaPlayerRepairedEntityEventFilter = - | TypePlayerRepairedEntityEventFilter - | NamePlayerRepairedEntityEventFilter - | GhostTypePlayerRepairedEntityEventFilter - | GhostNamePlayerRepairedEntityEventFilter - | OtherPlayerRepairedEntityEventFilter - -interface BaseEntityMarkedForUpgradeEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypeEntityMarkedForUpgradeEventFilter extends BaseEntityMarkedForUpgradeEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NameEntityMarkedForUpgradeEventFilter extends BaseEntityMarkedForUpgradeEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypeEntityMarkedForUpgradeEventFilter extends BaseEntityMarkedForUpgradeEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNameEntityMarkedForUpgradeEventFilter extends BaseEntityMarkedForUpgradeEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OtherEntityMarkedForUpgradeEventFilter extends BaseEntityMarkedForUpgradeEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaEntityMarkedForUpgradeEventFilter View documentation} - */ -type LuaEntityMarkedForUpgradeEventFilter = - | TypeEntityMarkedForUpgradeEventFilter - | NameEntityMarkedForUpgradeEventFilter - | GhostTypeEntityMarkedForUpgradeEventFilter - | GhostNameEntityMarkedForUpgradeEventFilter - | OtherEntityMarkedForUpgradeEventFilter - -interface BasePostEntityDiedEventFilter { - /** The condition to filter on. One of `"type"` */ - readonly filter: "type" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypePostEntityDiedEventFilter extends BasePostEntityDiedEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaPostEntityDiedEventFilter View documentation} - */ -type LuaPostEntityDiedEventFilter = TypePostEntityDiedEventFilter - -interface BasePreRobotMinedEntityEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypePreRobotMinedEntityEventFilter extends BasePreRobotMinedEntityEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NamePreRobotMinedEntityEventFilter extends BasePreRobotMinedEntityEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypePreRobotMinedEntityEventFilter extends BasePreRobotMinedEntityEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNamePreRobotMinedEntityEventFilter extends BasePreRobotMinedEntityEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OtherPreRobotMinedEntityEventFilter extends BasePreRobotMinedEntityEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaPreRobotMinedEntityEventFilter View documentation} - */ -type LuaPreRobotMinedEntityEventFilter = - | TypePreRobotMinedEntityEventFilter - | NamePreRobotMinedEntityEventFilter - | GhostTypePreRobotMinedEntityEventFilter - | GhostNamePreRobotMinedEntityEventFilter - | OtherPreRobotMinedEntityEventFilter - -interface BaseEntityClonedEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypeEntityClonedEventFilter extends BaseEntityClonedEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NameEntityClonedEventFilter extends BaseEntityClonedEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypeEntityClonedEventFilter extends BaseEntityClonedEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNameEntityClonedEventFilter extends BaseEntityClonedEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OtherEntityClonedEventFilter extends BaseEntityClonedEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaEntityClonedEventFilter View documentation} - */ -type LuaEntityClonedEventFilter = - | TypeEntityClonedEventFilter - | NameEntityClonedEventFilter - | GhostTypeEntityClonedEventFilter - | GhostNameEntityClonedEventFilter - | OtherEntityClonedEventFilter - -interface BaseScriptRaisedBuiltEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypeScriptRaisedBuiltEventFilter extends BaseScriptRaisedBuiltEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NameScriptRaisedBuiltEventFilter extends BaseScriptRaisedBuiltEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypeScriptRaisedBuiltEventFilter extends BaseScriptRaisedBuiltEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNameScriptRaisedBuiltEventFilter extends BaseScriptRaisedBuiltEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OtherScriptRaisedBuiltEventFilter extends BaseScriptRaisedBuiltEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaScriptRaisedBuiltEventFilter View documentation} - */ -type LuaScriptRaisedBuiltEventFilter = - | TypeScriptRaisedBuiltEventFilter - | NameScriptRaisedBuiltEventFilter - | GhostTypeScriptRaisedBuiltEventFilter - | GhostNameScriptRaisedBuiltEventFilter - | OtherScriptRaisedBuiltEventFilter - -interface BaseRobotMinedEntityEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypeRobotMinedEntityEventFilter extends BaseRobotMinedEntityEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NameRobotMinedEntityEventFilter extends BaseRobotMinedEntityEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypeRobotMinedEntityEventFilter extends BaseRobotMinedEntityEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNameRobotMinedEntityEventFilter extends BaseRobotMinedEntityEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OtherRobotMinedEntityEventFilter extends BaseRobotMinedEntityEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaRobotMinedEntityEventFilter View documentation} - */ -type LuaRobotMinedEntityEventFilter = - | TypeRobotMinedEntityEventFilter - | NameRobotMinedEntityEventFilter - | GhostTypeRobotMinedEntityEventFilter - | GhostNameRobotMinedEntityEventFilter - | OtherRobotMinedEntityEventFilter - -interface BasePrePlayerMinedEntityEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypePrePlayerMinedEntityEventFilter extends BasePrePlayerMinedEntityEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NamePrePlayerMinedEntityEventFilter extends BasePrePlayerMinedEntityEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypePrePlayerMinedEntityEventFilter extends BasePrePlayerMinedEntityEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNamePrePlayerMinedEntityEventFilter extends BasePrePlayerMinedEntityEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OtherPrePlayerMinedEntityEventFilter extends BasePrePlayerMinedEntityEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaPrePlayerMinedEntityEventFilter View documentation} - */ -type LuaPrePlayerMinedEntityEventFilter = - | TypePrePlayerMinedEntityEventFilter - | NamePrePlayerMinedEntityEventFilter - | GhostTypePrePlayerMinedEntityEventFilter - | GhostNamePrePlayerMinedEntityEventFilter - | OtherPrePlayerMinedEntityEventFilter - -interface BaseRobotBuiltEntityEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, - * `"ghost_name"`, `"force"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - | "force" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypeRobotBuiltEntityEventFilter extends BaseRobotBuiltEntityEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NameRobotBuiltEntityEventFilter extends BaseRobotBuiltEntityEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypeRobotBuiltEntityEventFilter extends BaseRobotBuiltEntityEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNameRobotBuiltEntityEventFilter extends BaseRobotBuiltEntityEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface ForceRobotBuiltEntityEventFilter extends BaseRobotBuiltEntityEventFilter { - readonly filter: "force" - /** The entity force */ - readonly force: string -} - -interface OtherRobotBuiltEntityEventFilter extends BaseRobotBuiltEntityEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaRobotBuiltEntityEventFilter View documentation} - */ -type LuaRobotBuiltEntityEventFilter = - | TypeRobotBuiltEntityEventFilter - | NameRobotBuiltEntityEventFilter - | GhostTypeRobotBuiltEntityEventFilter - | GhostNameRobotBuiltEntityEventFilter - | ForceRobotBuiltEntityEventFilter - | OtherRobotBuiltEntityEventFilter - -interface BaseEntityDeconstructionCancelledEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypeEntityDeconstructionCancelledEventFilter extends BaseEntityDeconstructionCancelledEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NameEntityDeconstructionCancelledEventFilter extends BaseEntityDeconstructionCancelledEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypeEntityDeconstructionCancelledEventFilter extends BaseEntityDeconstructionCancelledEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNameEntityDeconstructionCancelledEventFilter extends BaseEntityDeconstructionCancelledEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OtherEntityDeconstructionCancelledEventFilter extends BaseEntityDeconstructionCancelledEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaEntityDeconstructionCancelledEventFilter View documentation} - */ -type LuaEntityDeconstructionCancelledEventFilter = - | TypeEntityDeconstructionCancelledEventFilter - | NameEntityDeconstructionCancelledEventFilter - | GhostTypeEntityDeconstructionCancelledEventFilter - | GhostNameEntityDeconstructionCancelledEventFilter - | OtherEntityDeconstructionCancelledEventFilter - -interface BasePlayerBuiltEntityEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, - * `"ghost_name"`, `"force"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - | "force" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypePlayerBuiltEntityEventFilter extends BasePlayerBuiltEntityEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NamePlayerBuiltEntityEventFilter extends BasePlayerBuiltEntityEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypePlayerBuiltEntityEventFilter extends BasePlayerBuiltEntityEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNamePlayerBuiltEntityEventFilter extends BasePlayerBuiltEntityEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface ForcePlayerBuiltEntityEventFilter extends BasePlayerBuiltEntityEventFilter { - readonly filter: "force" - /** The entity force */ - readonly force: string -} - -interface OtherPlayerBuiltEntityEventFilter extends BasePlayerBuiltEntityEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaPlayerBuiltEntityEventFilter View documentation} - */ -type LuaPlayerBuiltEntityEventFilter = - | TypePlayerBuiltEntityEventFilter - | NamePlayerBuiltEntityEventFilter - | GhostTypePlayerBuiltEntityEventFilter - | GhostNamePlayerBuiltEntityEventFilter - | ForcePlayerBuiltEntityEventFilter - | OtherPlayerBuiltEntityEventFilter - -interface BasePlayerMinedEntityEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypePlayerMinedEntityEventFilter extends BasePlayerMinedEntityEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NamePlayerMinedEntityEventFilter extends BasePlayerMinedEntityEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypePlayerMinedEntityEventFilter extends BasePlayerMinedEntityEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNamePlayerMinedEntityEventFilter extends BasePlayerMinedEntityEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OtherPlayerMinedEntityEventFilter extends BasePlayerMinedEntityEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaPlayerMinedEntityEventFilter View documentation} - */ -type LuaPlayerMinedEntityEventFilter = - | TypePlayerMinedEntityEventFilter - | NamePlayerMinedEntityEventFilter - | GhostTypePlayerMinedEntityEventFilter - | GhostNamePlayerMinedEntityEventFilter - | OtherPlayerMinedEntityEventFilter - -interface BaseEntityDamagedEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, - * `"ghost_name"`, `"original-damage-amount"`, `"final-damage-amount"`, `"damage-type"`, `"final-health"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - | "original-damage-amount" - | "final-damage-amount" - | "damage-type" - | "final-health" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypeEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NameEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypeEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNameEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OriginalDamageAmountEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { - readonly filter: "original-damage-amount" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: float -} - -interface FinalDamageAmountEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { - readonly filter: "final-damage-amount" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: float -} - -interface DamageTypeEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { - readonly filter: "damage-type" - /** A {@link LuaDamagePrototype} name */ - readonly type: string -} - -interface FinalHealthEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { - readonly filter: "final-health" - readonly comparison: ComparatorString - /** The value to compare against. */ - readonly value: float -} - -interface OtherEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaEntityDamagedEventFilter View documentation} - */ -type LuaEntityDamagedEventFilter = - | TypeEntityDamagedEventFilter - | NameEntityDamagedEventFilter - | GhostTypeEntityDamagedEventFilter - | GhostNameEntityDamagedEventFilter - | OriginalDamageAmountEntityDamagedEventFilter - | FinalDamageAmountEntityDamagedEventFilter - | DamageTypeEntityDamagedEventFilter - | FinalHealthEntityDamagedEventFilter - | OtherEntityDamagedEventFilter - -interface BaseSectorScannedEventFilter { - /** - * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, - * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, - * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` - */ - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" - | "type" - | "name" - | "ghost_type" - | "ghost_name" - /** - * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the - * filters, `"and"` has higher precedence than `"or"`. - */ - readonly mode?: "or" | "and" - /** Inverts the condition. Default is `false`. */ - readonly invert?: boolean -} - -interface TypeSectorScannedEventFilter extends BaseSectorScannedEventFilter { - readonly filter: "type" - /** The prototype type */ - readonly type: string -} - -interface NameSectorScannedEventFilter extends BaseSectorScannedEventFilter { - readonly filter: "name" - /** The prototype name */ - readonly name: string -} - -interface GhostTypeSectorScannedEventFilter extends BaseSectorScannedEventFilter { - readonly filter: "ghost_type" - /** The ghost prototype type */ - readonly type: string -} - -interface GhostNameSectorScannedEventFilter extends BaseSectorScannedEventFilter { - readonly filter: "ghost_name" - /** The ghost prototype name */ - readonly name: string -} - -interface OtherSectorScannedEventFilter extends BaseSectorScannedEventFilter { - readonly filter: - | "ghost" - | "rail" - | "rail-signal" - | "rolling-stock" - | "robot-with-logistics-interface" - | "vehicle" - | "turret" - | "crafting-machine" - | "wall-connectable" - | "transport-belt-connectable" - | "circuit-network-connectable" -} - -/** - * Other attributes may be specified depending on `filter`: - * - * {@link https://lua-api.factorio.com/next/Concepts.html#LuaSectorScannedEventFilter View documentation} - */ -type LuaSectorScannedEventFilter = - | TypeSectorScannedEventFilter - | NameSectorScannedEventFilter - | GhostTypeSectorScannedEventFilter - | GhostNameSectorScannedEventFilter - | OtherSectorScannedEventFilter - -/** - * A map gen preset. Used in {@link https://wiki.factorio.com/Prototype/MapGenPresets Prototype/MapGenPresets}. - * - * {@link https://wiki.factorio.com/Types/MapGenPreset View Documentation} - */ -interface MapGenPreset { - /** Specifies the ordering the map generator gui. */ - order: string - /** - * Whether this is the default preset. If set to boolean, this preset may not have any other properties besides this - * and order. - */ - default?: boolean - /** - * This is a table with the below key/value pairs. All key/value pairs are optional. If not set they will just use - * the default values. - */ - basic_settings: Partial - /** - * This is a table with the below key/value pairs. All key/value pairs are optional, if not set they will just use - * the existing values. - */ - readonly advanced_settings: { - readonly pollution?: { - enabled?: boolean - /** Must be <= 0.25. */ - diffusion_ratio?: double - /** Also known as dissipation rate. Must be >= 0.5. */ - ageing?: double - enemy_attack_pollution_consumption_modifier?: double - min_pollution_to_damage_trees?: double - pollution_restored_per_tree_damage?: double - } - readonly enemy_evolution?: { - enabled?: boolean - time_factor?: double - destroy_factor?: double - pollution_factor?: double - } - readonly enemy_expansion?: { - enabled?: boolean - max_expansion_distance?: double - settler_group_min_size?: double - settler_group_max_size?: double - /** In ticks. */ - min_expansion_cooldown?: double - /** In ticks. */ - max_expansion_cooldown?: double - } - readonly difficulty_settings?: { - recipe_difficulty?: defines.difficulty_settings.recipe_difficulty - technology_difficulty?: defines.difficulty_settings.technology_difficulty - technology_price_multiplier?: double - research_queue_setting?: "after-victory" | "always" | "never" - } - } -} - -interface BlueprintControlBehavior { - readonly condition?: CircuitCondition - readonly circuit_condition?: CircuitCondition - readonly filters?: Signal[] - readonly is_on?: boolean - readonly arithmetic_conditions?: ArithmeticCombinatorParameters - readonly decider_conditions?: DeciderCombinatorParameters - readonly circuit_enable_disable?: boolean - readonly circuit_read_resources?: boolean - readonly circuit_resource_read_mode?: defines.control_behavior.mining_drill.resource_read_mode - readonly read_stopped_train?: boolean - readonly train_stopped_signal?: SignalID - readonly read_from_train?: boolean - readonly send_to_train?: boolean - readonly circuit_mode_of_operation?: number - readonly circuit_read_hand_contents?: boolean - readonly circuit_hand_read_mode?: defines.control_behavior.inserter.hand_read_mode - readonly circuit_set_stack_size?: boolean - readonly stack_control_input_signal?: SignalID - readonly use_colors?: boolean - readonly read_robot_stats?: boolean - readonly read_logistics?: boolean - readonly available_logistic_output_signal?: boolean - readonly total_logistic_output_signal?: boolean - readonly available_construction_output_signal?: boolean - readonly total_construction_output_signal?: boolean - readonly circuit_contents_read_mode?: defines.control_behavior.transport_belt.content_read_mode - readonly output_signal?: SignalID - readonly circuit_close_signal?: boolean - readonly circuit_read_signal?: boolean - readonly red_output_signal?: SignalID - readonly orange_output_signal?: SignalID - readonly green_output_signal?: SignalID - readonly blue_output_signal?: SignalID - readonly circuit_open_gate?: boolean - readonly circuit_read_sensor?: boolean - readonly circuit_parameters?: ProgrammableSpeakerCircuitParameters -} diff --git a/modules/mod2/typed-factorio/generated/defines.d.ts b/modules/mod2/typed-factorio/generated/defines.d.ts deleted file mode 100644 index db30ab0..0000000 --- a/modules/mod2/typed-factorio/generated/defines.d.ts +++ /dev/null @@ -1,1642 +0,0 @@ -/** @noSelfInFile */ - -declare namespace defines { - enum alert_type { - entity_destroyed, - entity_under_attack, - not_enough_construction_robots, - no_material_for_construction, - not_enough_repair_packs, - turret_fire, - custom, - no_storage, - train_out_of_fuel, - } - /** - * AI command exit status. See {@link LuaEntity.set_command LuaEntity::set_command} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.behavior_result View documentation} - */ - enum behavior_result { - in_progress, - fail, - success, - deleted, - } - enum build_check_type { - script, - manual, - manual_ghost, - script_ghost, - blueprint_ghost, - ghost_revive, - } - /** - * State of a chain signal. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.chain_signal_state View documentation} - */ - enum chain_signal_state { - none, - all_open, - partially_open, - none_open, - } - enum chunk_generated_status { - nothing, - custom_tiles, - basic_tiles, - corrected_tiles, - tiles, - entities, - } - enum circuit_condition_index { - inserter_circuit, - inserter_logistic, - lamp, - arithmetic_combinator, - decider_combinator, - constant_combinator, - offshore_pump, - pump, - } - enum circuit_connector_id { - accumulator, - constant_combinator, - container, - programmable_speaker, - rail_signal, - rail_chain_signal, - roboport, - storage_tank, - wall, - electric_pole, - inserter, - lamp, - combinator_input, - combinator_output, - offshore_pump, - pump, - } - /** - * Command given to units describing what they should do. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.command View documentation} - */ - enum command { - /** - * Attack another entity. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.command.attack View documentation} - */ - attack = 0, - /** - * Go to a specific position. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.command.go_to_location View documentation} - */ - go_to_location = 1, - /** - * Chain commands together, see {@link defines.compound_command}. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.command.compound View documentation} - */ - compound = 2, - /** - * Do what your group wants you to do. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.command.group View documentation} - */ - group = 3, - /** - * Go to a place and attack what you see. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.command.attack_area View documentation} - */ - attack_area = 4, - /** - * Chill. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.command.wander View documentation} - */ - wander = 5, - /** - * Flee from another entity. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.command.flee View documentation} - */ - flee = 6, - /** - * Stop moving and stay where you are. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.command.stop View documentation} - */ - stop = 7, - /** - * Go to a position and build a base there. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.command.build_base View documentation} - */ - build_base = 8, - } - /** - * How commands are joined together in a compound command (see {@link defines.command.compound}). - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.compound_command View documentation} - */ - enum compound_command { - /** - * Fail on first failure. Only succeeds if all commands (executed one after another) succeed. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.compound_command.logical_and View documentation} - */ - logical_and, - /** - * Succeed on first success. Only fails if all commands (executed one after another) fail. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.compound_command.logical_or View documentation} - */ - logical_or, - /** - * Execute all commands in sequence and fail or succeed depending on the return status of the last command. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.compound_command.return_last View documentation} - */ - return_last, - } - namespace control_behavior { - namespace inserter { - enum circuit_mode_of_operation { - none, - enable_disable, - set_filters, - read_hand_contents, - set_stack_size, - } - enum hand_read_mode { - hold, - pulse, - } - } - namespace logistic_container { - enum circuit_mode_of_operation { - send_contents, - set_requests, - } - } - namespace lamp { - enum circuit_mode_of_operation { - use_colors, - } - } - namespace mining_drill { - enum resource_read_mode { - this_miner, - entire_patch, - } - } - namespace transport_belt { - enum content_read_mode { - pulse, - hold, - } - } - enum type { - /** - * {@link LuaContainerControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.container View documentation} - */ - container, - /** - * {@link LuaGenericOnOffControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.generic_on_off View documentation} - */ - generic_on_off, - /** - * {@link LuaInserterControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.inserter View documentation} - */ - inserter, - /** - * {@link LuaLampControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.lamp View documentation} - */ - lamp, - /** - * {@link LuaLogisticContainerControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.logistic_container View documentation} - */ - logistic_container, - /** - * {@link LuaRoboportControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.roboport View documentation} - */ - roboport, - /** - * {@link LuaStorageTankControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.storage_tank View documentation} - */ - storage_tank, - /** - * {@link LuaTrainStopControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.train_stop View documentation} - */ - train_stop, - /** - * {@link LuaDeciderCombinatorControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.decider_combinator View documentation} - */ - decider_combinator, - /** - * {@link LuaArithmeticCombinatorControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.arithmetic_combinator View documentation} - */ - arithmetic_combinator, - /** - * {@link LuaConstantCombinatorControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.constant_combinator View documentation} - */ - constant_combinator, - /** - * {@link LuaTransportBeltControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.transport_belt View documentation} - */ - transport_belt, - /** - * {@link LuaAccumulatorControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.accumulator View documentation} - */ - accumulator, - /** - * {@link LuaRailSignalControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.rail_signal View documentation} - */ - rail_signal, - /** - * {@link LuaRailChainSignalControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.rail_chain_signal View documentation} - */ - rail_chain_signal, - /** - * {@link LuaWallControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.wall View documentation} - */ - wall, - /** - * {@link LuaMiningDrillControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.mining_drill View documentation} - */ - mining_drill, - /** - * {@link LuaProgrammableSpeakerControlBehavior} - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.programmable_speaker View documentation} - */ - programmable_speaker, - } - } - enum controllers { - /** - * Can't interact with the world, can only observe. Used in the multiplayer waiting-to-respawn screen. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.controllers.ghost View documentation} - */ - ghost, - /** - * The controller controls a character. This is the default controller in freeplay. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.controllers.character View documentation} - */ - character, - /** - * The controller isn't tied to a character. This is the default controller in sandbox. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.controllers.god View documentation} - */ - god, - /** - * The Editor Controller near ultimate power to do almost anything in the game. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.controllers.editor View documentation} - */ - editor, - /** - * The player can't interact with the world, and the camera pans around in a predefined manner. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.controllers.cutscene View documentation} - */ - cutscene, - /** - * Can't change anything in the world but can view anything. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.controllers.spectator View documentation} - */ - spectator, - } - namespace deconstruction_item { - enum entity_filter_mode { - whitelist, - blacklist, - } - enum tile_filter_mode { - whitelist, - blacklist, - } - enum tile_selection_mode { - normal, - always, - never, - only, - } - } - enum difficulty { - easy, - normal, - hard, - } - namespace difficulty_settings { - enum recipe_difficulty { - normal, - expensive, - } - enum technology_difficulty { - normal, - expensive, - } - } - enum direction { - north = 0, - northeast = 1, - east = 2, - southeast = 3, - south = 4, - southwest = 5, - west = 6, - northwest = 7, - } - enum disconnect_reason { - quit, - dropped, - reconnect, - wrong_input, - desync_limit_reached, - cannot_keep_up, - afk, - kicked, - kicked_and_deleted, - banned, - switching_servers, - } - enum distraction { - /** - * Perform command even if someone attacks the unit. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.distraction.none View documentation} - */ - none, - /** - * Attack closer enemy entities with force. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.distraction.by_enemy View documentation} - */ - by_enemy, - /** - * Attack closer enemy entities, including entities "built" by player (belts, inserters, chests). - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.distraction.by_anything View documentation} - */ - by_anything, - /** - * Attack when attacked. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.distraction.by_damage View documentation} - */ - by_damage, - } - enum entity_status { - working, - normal, - no_power, - low_power, - no_fuel, - disabled_by_control_behavior, - opened_by_circuit_network, - closed_by_circuit_network, - disabled_by_script, - marked_for_deconstruction, - /** - * Used by generators and solar panels. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.not_plugged_in_electric_network View documentation} - */ - not_plugged_in_electric_network, - /** - * Used by power switches. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.networks_connected View documentation} - */ - networks_connected, - /** - * Used by power switches. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.networks_disconnected View documentation} - */ - networks_disconnected, - /** - * Used by accumulators. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.charging View documentation} - */ - charging, - /** - * Used by accumulators. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.discharging View documentation} - */ - discharging, - /** - * Used by accumulators. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.fully_charged View documentation} - */ - fully_charged, - /** - * Used by logistic containers. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.out_of_logistic_network View documentation} - */ - out_of_logistic_network, - /** - * Used by assembling machines. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.no_recipe View documentation} - */ - no_recipe, - /** - * Used by furnaces. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.no_ingredients View documentation} - */ - no_ingredients, - /** - * Used by boilers, fluid turrets and fluid energy sources: Boiler has no fluid to work with. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.no_input_fluid View documentation} - */ - no_input_fluid, - /** - * Used by labs. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.no_research_in_progress View documentation} - */ - no_research_in_progress, - /** - * Used by mining drills. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.no_minable_resources View documentation} - */ - no_minable_resources, - /** - * Used by boilers and fluid turrets: Boiler still has some fluid but is about to run out. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.low_input_fluid View documentation} - */ - low_input_fluid, - /** - * Used by crafting machines. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.fluid_ingredient_shortage View documentation} - */ - fluid_ingredient_shortage, - /** - * Used by crafting machines, boilers, burner energy sources and reactors: Reactor/burner has full burnt result - * inventory, boiler has full output fluidbox. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.full_output View documentation} - */ - full_output, - /** - * Used by crafting machines. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.item_ingredient_shortage View documentation} - */ - item_ingredient_shortage, - /** - * Used by mining drills when the mining fluid is missing. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.missing_required_fluid View documentation} - */ - missing_required_fluid, - /** - * Used by labs. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.missing_science_packs View documentation} - */ - missing_science_packs, - /** - * Used by inserters. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.waiting_for_source_items View documentation} - */ - waiting_for_source_items, - /** - * Used by inserters and mining drills. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.waiting_for_space_in_destination View documentation} - */ - waiting_for_space_in_destination, - /** - * Used by the rocket silo. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.preparing_rocket_for_launch View documentation} - */ - preparing_rocket_for_launch, - /** - * Used by the rocket silo. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.waiting_to_launch_rocket View documentation} - */ - waiting_to_launch_rocket, - /** - * Used by the rocket silo. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.launching_rocket View documentation} - */ - launching_rocket, - /** - * Used by beacons. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.no_modules_to_transmit View documentation} - */ - no_modules_to_transmit, - /** - * Used by roboports. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.recharging_after_power_outage View documentation} - */ - recharging_after_power_outage, - /** - * Used by inserters targeting entity ghosts. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.waiting_for_target_to_be_built View documentation} - */ - waiting_for_target_to_be_built, - /** - * Used by inserters targeting rails. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.waiting_for_train View documentation} - */ - waiting_for_train, - /** - * Used by ammo turrets. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.no_ammo View documentation} - */ - no_ammo, - /** - * Used by heat energy sources. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.low_temperature View documentation} - */ - low_temperature, - /** - * Used by constant combinators: Combinator is turned off via switch in GUI. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.disabled View documentation} - */ - disabled, - /** - * Used by lamps. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.turned_off_during_daytime View documentation} - */ - turned_off_during_daytime, - /** - * Used by rail signals. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.not_connected_to_rail View documentation} - */ - not_connected_to_rail, - /** - * Used by rail signals. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.cant_divide_segments View documentation} - */ - cant_divide_segments, - } - /** - * See the {@link https://lua-api.factorio.com/next/events.html events page} for more info on what events contain and - * when they get raised. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.events View documentation} - */ - namespace events { - /** Event type: {@link OnTickEvent} */ - const on_tick: EventId - /** Event type: {@link OnGuiClickEvent} */ - const on_gui_click: EventId - /** Event type: {@link OnGuiConfirmedEvent} */ - const on_gui_confirmed: EventId - /** Event type: {@link OnGuiTextChangedEvent} */ - const on_gui_text_changed: EventId - /** Event type: {@link OnGuiCheckedStateChangedEvent} */ - const on_gui_checked_state_changed: EventId - /** - * Event type: {@link OnEntityDiedEvent} - * - * Event filter: {@link LuaEntityDiedEventFilter} - */ - const on_entity_died: EventId - /** - * Event type: {@link OnPostEntityDiedEvent} - * - * Event filter: {@link LuaPostEntityDiedEventFilter} - */ - const on_post_entity_died: EventId - /** - * Event type: {@link OnEntityDamagedEvent} - * - * Event filter: {@link LuaEntityDamagedEventFilter} - */ - const on_entity_damaged: EventId - /** Event type: {@link OnPickedUpItemEvent} */ - const on_picked_up_item: EventId - /** - * Event type: {@link OnBuiltEntityEvent} - * - * Event filter: {@link LuaPlayerBuiltEntityEventFilter} - */ - const on_built_entity: EventId - /** - * Event type: {@link OnSectorScannedEvent} - * - * Event filter: {@link LuaSectorScannedEventFilter} - */ - const on_sector_scanned: EventId - /** Event type: {@link OnPlayerMinedItemEvent} */ - const on_player_mined_item: EventId - /** Event type: {@link OnPreBuildEvent} */ - const on_pre_build: EventId - /** Event type: {@link OnRocketLaunchedEvent} */ - const on_rocket_launched: EventId - /** - * Event type: {@link OnPrePlayerMinedItemEvent} - * - * Event filter: {@link LuaPrePlayerMinedEntityEventFilter} - */ - const on_pre_player_mined_item: EventId - /** Event type: {@link OnChunkGeneratedEvent} */ - const on_chunk_generated: EventId - /** Event type: {@link OnPlayerCraftedItemEvent} */ - const on_player_crafted_item: EventId - /** - * Event type: {@link OnRobotBuiltEntityEvent} - * - * Event filter: {@link LuaRobotBuiltEntityEventFilter} - */ - const on_robot_built_entity: EventId - /** - * Event type: {@link OnRobotPreMinedEvent} - * - * Event filter: {@link LuaPreRobotMinedEntityEventFilter} - */ - const on_robot_pre_mined: EventId - /** Event type: {@link OnRobotMinedEvent} */ - const on_robot_mined: EventId - /** Event type: {@link OnResearchStartedEvent} */ - const on_research_started: EventId - /** Event type: {@link OnResearchFinishedEvent} */ - const on_research_finished: EventId - /** Event type: {@link OnResearchReversedEvent} */ - const on_research_reversed: EventId - /** Event type: {@link OnPlayerRotatedEntityEvent} */ - const on_player_rotated_entity: EventId - /** - * Event type: {@link OnMarkedForDeconstructionEvent} - * - * Event filter: {@link LuaEntityMarkedForDeconstructionEventFilter} - */ - const on_marked_for_deconstruction: EventId< - OnMarkedForDeconstructionEvent, - LuaEntityMarkedForDeconstructionEventFilter - > - /** - * Event type: {@link OnCancelledDeconstructionEvent} - * - * Event filter: {@link LuaEntityDeconstructionCancelledEventFilter} - */ - const on_cancelled_deconstruction: EventId< - OnCancelledDeconstructionEvent, - LuaEntityDeconstructionCancelledEventFilter - > - /** Event type: {@link OnTriggerCreatedEntityEvent} */ - const on_trigger_created_entity: EventId - /** Event type: {@link OnTriggerFiredArtilleryEvent} */ - const on_trigger_fired_artillery: EventId - /** Event type: {@link OnTrainChangedStateEvent} */ - const on_train_changed_state: EventId - /** Event type: {@link OnPlayerCreatedEvent} */ - const on_player_created: EventId - /** Event type: {@link OnResourceDepletedEvent} */ - const on_resource_depleted: EventId - /** Event type: {@link OnPlayerDrivingChangedStateEvent} */ - const on_player_driving_changed_state: EventId - /** Event type: {@link OnForceCreatedEvent} */ - const on_force_created: EventId - /** Event type: {@link OnForcesMergingEvent} */ - const on_forces_merging: EventId - /** Event type: {@link OnPlayerCursorStackChangedEvent} */ - const on_player_cursor_stack_changed: EventId - /** Event type: {@link OnPreEntitySettingsPastedEvent} */ - const on_pre_entity_settings_pasted: EventId - /** Event type: {@link OnEntitySettingsPastedEvent} */ - const on_entity_settings_pasted: EventId - /** Event type: {@link OnPlayerMainInventoryChangedEvent} */ - const on_player_main_inventory_changed: EventId - /** Event type: {@link OnPlayerArmorInventoryChangedEvent} */ - const on_player_armor_inventory_changed: EventId - /** Event type: {@link OnPlayerAmmoInventoryChangedEvent} */ - const on_player_ammo_inventory_changed: EventId - /** Event type: {@link OnPlayerGunInventoryChangedEvent} */ - const on_player_gun_inventory_changed: EventId - /** Event type: {@link OnPlayerPlacedEquipmentEvent} */ - const on_player_placed_equipment: EventId - /** Event type: {@link OnPlayerRemovedEquipmentEvent} */ - const on_player_removed_equipment: EventId - /** Event type: {@link OnPrePlayerDiedEvent} */ - const on_pre_player_died: EventId - /** Event type: {@link OnPlayerDiedEvent} */ - const on_player_died: EventId - /** Event type: {@link OnPlayerRespawnedEvent} */ - const on_player_respawned: EventId - /** Event type: {@link OnPlayerJoinedGameEvent} */ - const on_player_joined_game: EventId - /** Event type: {@link OnPlayerLeftGameEvent} */ - const on_player_left_game: EventId - /** Event type: {@link OnPlayerBuiltTileEvent} */ - const on_player_built_tile: EventId - /** Event type: {@link OnPlayerMinedTileEvent} */ - const on_player_mined_tile: EventId - /** Event type: {@link OnRobotBuiltTileEvent} */ - const on_robot_built_tile: EventId - /** Event type: {@link OnRobotMinedTileEvent} */ - const on_robot_mined_tile: EventId - /** Event type: {@link OnPlayerSelectedAreaEvent} */ - const on_player_selected_area: EventId - /** Event type: {@link OnPlayerAltSelectedAreaEvent} */ - const on_player_alt_selected_area: EventId - /** Event type: {@link OnPlayerChangedSurfaceEvent} */ - const on_player_changed_surface: EventId - /** Event type: {@link OnSelectedEntityChangedEvent} */ - const on_selected_entity_changed: EventId - /** Event type: {@link OnMarketItemPurchasedEvent} */ - const on_market_item_purchased: EventId - /** Event type: {@link OnPlayerDroppedItemEvent} */ - const on_player_dropped_item: EventId - /** Event type: {@link OnBiterBaseBuiltEvent} */ - const on_biter_base_built: EventId - /** Event type: {@link OnPlayerChangedForceEvent} */ - const on_player_changed_force: EventId - /** Event type: {@link OnEntityRenamedEvent} */ - const on_entity_renamed: EventId - /** Event type: {@link OnGuiSelectionStateChangedEvent} */ - const on_gui_selection_state_changed: EventId - /** Event type: {@link OnRuntimeModSettingChangedEvent} */ - const on_runtime_mod_setting_changed: EventId - /** Event type: {@link OnDifficultySettingsChangedEvent} */ - const on_difficulty_settings_changed: EventId - /** Event type: {@link OnSurfaceCreatedEvent} */ - const on_surface_created: EventId - /** Event type: {@link OnSurfaceDeletedEvent} */ - const on_surface_deleted: EventId - /** Event type: {@link OnPreSurfaceDeletedEvent} */ - const on_pre_surface_deleted: EventId - /** - * Event type: {@link OnPlayerMinedEntityEvent} - * - * Event filter: {@link LuaPlayerMinedEntityEventFilter} - */ - const on_player_mined_entity: EventId - /** - * Event type: {@link OnRobotMinedEntityEvent} - * - * Event filter: {@link LuaRobotMinedEntityEventFilter} - */ - const on_robot_mined_entity: EventId - /** Event type: {@link OnTrainCreatedEvent} */ - const on_train_created: EventId - /** Event type: {@link OnGuiElemChangedEvent} */ - const on_gui_elem_changed: EventId - /** Event type: {@link OnPlayerSetupBlueprintEvent} */ - const on_player_setup_blueprint: EventId - /** Event type: {@link OnPlayerDeconstructedAreaEvent} */ - const on_player_deconstructed_area: EventId - /** Event type: {@link OnPlayerConfiguredBlueprintEvent} */ - const on_player_configured_blueprint: EventId - /** Event type: {@link OnConsoleChatEvent} */ - const on_console_chat: EventId - /** Event type: {@link OnConsoleCommandEvent} */ - const on_console_command: EventId - /** Event type: {@link OnPlayerRemovedEvent} */ - const on_player_removed: EventId - /** Event type: {@link OnPrePlayerRemovedEvent} */ - const on_pre_player_removed: EventId - /** Event type: {@link OnPlayerUsedCapsuleEvent} */ - const on_player_used_capsule: EventId - /** - * Event type: {@link ScriptRaisedBuiltEvent} - * - * Event filter: {@link LuaScriptRaisedBuiltEventFilter} - */ - const script_raised_built: EventId - /** - * Event type: {@link ScriptRaisedDestroyEvent} - * - * Event filter: {@link LuaScriptRaisedDestroyEventFilter} - */ - const script_raised_destroy: EventId - /** - * Event type: {@link ScriptRaisedReviveEvent} - * - * Event filter: {@link LuaScriptRaisedReviveEventFilter} - */ - const script_raised_revive: EventId - /** Event type: {@link ScriptRaisedSetTilesEvent} */ - const script_raised_set_tiles: EventId - /** Event type: {@link OnPlayerPromotedEvent} */ - const on_player_promoted: EventId - /** Event type: {@link OnPlayerDemotedEvent} */ - const on_player_demoted: EventId - /** Event type: {@link OnCombatRobotExpiredEvent} */ - const on_combat_robot_expired: EventId - /** Event type: {@link OnWorkerRobotExpiredEvent} */ - const on_worker_robot_expired: EventId - /** Event type: {@link OnPlayerChangedPositionEvent} */ - const on_player_changed_position: EventId - /** Event type: {@link OnModItemOpenedEvent} */ - const on_mod_item_opened: EventId - /** Event type: {@link OnGuiOpenedEvent} */ - const on_gui_opened: EventId - /** Event type: {@link OnGuiClosedEvent} */ - const on_gui_closed: EventId - /** Event type: {@link OnGuiValueChangedEvent} */ - const on_gui_value_changed: EventId - /** Event type: {@link OnPlayerMutedEvent} */ - const on_player_muted: EventId - /** Event type: {@link OnPlayerUnmutedEvent} */ - const on_player_unmuted: EventId - /** Event type: {@link OnPlayerCheatModeEnabledEvent} */ - const on_player_cheat_mode_enabled: EventId - /** Event type: {@link OnPlayerCheatModeDisabledEvent} */ - const on_player_cheat_mode_disabled: EventId - /** Event type: {@link OnCharacterCorpseExpiredEvent} */ - const on_character_corpse_expired: EventId - /** - * Event type: {@link OnPreGhostDeconstructedEvent} - * - * Event filter: {@link LuaPreGhostDeconstructedEventFilter} - */ - const on_pre_ghost_deconstructed: EventId - /** Event type: {@link OnPlayerPipetteEvent} */ - const on_player_pipette: EventId - /** Event type: {@link OnPlayerDisplayResolutionChangedEvent} */ - const on_player_display_resolution_changed: EventId - /** Event type: {@link OnPlayerDisplayScaleChangedEvent} */ - const on_player_display_scale_changed: EventId - /** Event type: {@link OnPrePlayerCraftedItemEvent} */ - const on_pre_player_crafted_item: EventId - /** Event type: {@link OnPlayerCancelledCraftingEvent} */ - const on_player_cancelled_crafting: EventId - /** Event type: {@link OnChunkChartedEvent} */ - const on_chunk_charted: EventId - /** Event type: {@link OnTechnologyEffectsResetEvent} */ - const on_technology_effects_reset: EventId - /** Event type: {@link OnForceResetEvent} */ - const on_force_reset: EventId - /** Event type: {@link OnLandMineArmedEvent} */ - const on_land_mine_armed: EventId - /** Event type: {@link OnForcesMergedEvent} */ - const on_forces_merged: EventId - /** Event type: {@link OnPlayerTrashInventoryChangedEvent} */ - const on_player_trash_inventory_changed: EventId - /** Event type: {@link OnPrePlayerLeftGameEvent} */ - const on_pre_player_left_game: EventId - /** Event type: {@link OnPreSurfaceClearedEvent} */ - const on_pre_surface_cleared: EventId - /** Event type: {@link OnSurfaceClearedEvent} */ - const on_surface_cleared: EventId - /** Event type: {@link OnChunkDeletedEvent} */ - const on_chunk_deleted: EventId - /** Event type: {@link OnPreChunkDeletedEvent} */ - const on_pre_chunk_deleted: EventId - /** Event type: {@link OnTrainScheduleChangedEvent} */ - const on_train_schedule_changed: EventId - /** Event type: {@link OnPlayerBannedEvent} */ - const on_player_banned: EventId - /** Event type: {@link OnPlayerKickedEvent} */ - const on_player_kicked: EventId - /** Event type: {@link OnPlayerUnbannedEvent} */ - const on_player_unbanned: EventId - /** Event type: {@link OnRocketLaunchOrderedEvent} */ - const on_rocket_launch_ordered: EventId - /** Event type: {@link OnScriptPathRequestFinishedEvent} */ - const on_script_path_request_finished: EventId - /** Event type: {@link OnAiCommandCompletedEvent} */ - const on_ai_command_completed: EventId - /** - * Event type: {@link OnMarkedForUpgradeEvent} - * - * Event filter: {@link LuaEntityMarkedForUpgradeEventFilter} - */ - const on_marked_for_upgrade: EventId - /** - * Event type: {@link OnCancelledUpgradeEvent} - * - * Event filter: {@link LuaUpgradeCancelledEventFilter} - */ - const on_cancelled_upgrade: EventId - /** Event type: {@link OnPlayerToggledMapEditorEvent} */ - const on_player_toggled_map_editor: EventId - /** - * Event type: {@link OnEntityClonedEvent} - * - * Event filter: {@link LuaEntityClonedEventFilter} - */ - const on_entity_cloned: EventId - /** Event type: {@link OnAreaClonedEvent} */ - const on_area_cloned: EventId - /** Event type: {@link OnBrushClonedEvent} */ - const on_brush_cloned: EventId - /** Event type: {@link OnGameCreatedFromScenarioEvent} */ - const on_game_created_from_scenario: EventId - /** Event type: {@link OnSurfaceImportedEvent} */ - const on_surface_imported: EventId - /** Event type: {@link OnSurfaceRenamedEvent} */ - const on_surface_renamed: EventId - /** Event type: {@link OnPlayerToggledAltModeEvent} */ - const on_player_toggled_alt_mode: EventId - /** - * Event type: {@link OnPlayerRepairedEntityEvent} - * - * Event filter: {@link LuaPlayerRepairedEntityEventFilter} - */ - const on_player_repaired_entity: EventId - /** Event type: {@link OnPlayerFastTransferredEvent} */ - const on_player_fast_transferred: EventId - /** Event type: {@link OnPreRobotExplodedCliffEvent} */ - const on_pre_robot_exploded_cliff: EventId - /** Event type: {@link OnRobotExplodedCliffEvent} */ - const on_robot_exploded_cliff: EventId - /** Event type: {@link OnEntitySpawnedEvent} */ - const on_entity_spawned: EventId - /** Event type: {@link OnCutsceneWaypointReachedEvent} */ - const on_cutscene_waypoint_reached: EventId - /** Event type: {@link OnUnitGroupCreatedEvent} */ - const on_unit_group_created: EventId - /** Event type: {@link OnUnitAddedToGroupEvent} */ - const on_unit_added_to_group: EventId - /** Event type: {@link OnUnitRemovedFromGroupEvent} */ - const on_unit_removed_from_group: EventId - /** Event type: {@link OnUnitGroupFinishedGatheringEvent} */ - const on_unit_group_finished_gathering: EventId - /** Event type: {@link OnBuildBaseArrivedEvent} */ - const on_build_base_arrived: EventId - /** Event type: {@link OnChartTagAddedEvent} */ - const on_chart_tag_added: EventId - /** Event type: {@link OnChartTagModifiedEvent} */ - const on_chart_tag_modified: EventId - /** Event type: {@link OnChartTagRemovedEvent} */ - const on_chart_tag_removed: EventId - /** Event type: {@link OnLuaShortcutEvent} */ - const on_lua_shortcut: EventId - /** Event type: {@link OnGuiLocationChangedEvent} */ - const on_gui_location_changed: EventId - /** Event type: {@link OnGuiSelectedTabChangedEvent} */ - const on_gui_selected_tab_changed: EventId - /** Event type: {@link OnGuiSwitchStateChangedEvent} */ - const on_gui_switch_state_changed: EventId - /** Event type: {@link OnForceCeaseFireChangedEvent} */ - const on_force_cease_fire_changed: EventId - /** Event type: {@link OnForceFriendsChangedEvent} */ - const on_force_friends_changed: EventId - /** Event type: {@link OnStringTranslatedEvent} */ - const on_string_translated: EventId - /** Event type: {@link OnScriptTriggerEffectEvent} */ - const on_script_trigger_effect: EventId - /** Event type: {@link OnPlayerSetQuickBarSlotEvent} */ - const on_player_set_quick_bar_slot: EventId - /** Event type: {@link OnPrePlayerToggledMapEditorEvent} */ - const on_pre_player_toggled_map_editor: EventId - /** Event type: {@link OnPreScriptInventoryResizedEvent} */ - const on_pre_script_inventory_resized: EventId - /** Event type: {@link OnScriptInventoryResizedEvent} */ - const on_script_inventory_resized: EventId - /** Event type: {@link OnEntityDestroyedEvent} */ - const on_entity_destroyed: EventId - /** Event type: {@link OnPlayerClickedGpsTagEvent} */ - const on_player_clicked_gps_tag: EventId - /** Event type: {@link OnPlayerFlushedFluidEvent} */ - const on_player_flushed_fluid: EventId - /** Event type: {@link OnPermissionGroupEditedEvent} */ - const on_permission_group_edited: EventId - /** Event type: {@link OnPrePermissionStringImportedEvent} */ - const on_pre_permission_string_imported: EventId - /** Event type: {@link OnPermissionStringImportedEvent} */ - const on_permission_string_imported: EventId - /** Event type: {@link OnPrePermissionGroupDeletedEvent} */ - const on_pre_permission_group_deleted: EventId - /** Event type: {@link OnPermissionGroupDeletedEvent} */ - const on_permission_group_deleted: EventId - /** Event type: {@link OnPermissionGroupAddedEvent} */ - const on_permission_group_added: EventId - /** Event type: {@link OnCutsceneCancelledEvent} */ - const on_cutscene_cancelled: EventId - /** Event type: {@link OnPlayerConfiguredSpiderRemoteEvent} */ - const on_player_configured_spider_remote: EventId - /** Event type: {@link OnPlayerUsedSpiderRemoteEvent} */ - const on_player_used_spider_remote: EventId - /** Event type: {@link OnSpiderCommandCompletedEvent} */ - const on_spider_command_completed: EventId - /** Event type: {@link OnEntityLogisticSlotChangedEvent} */ - const on_entity_logistic_slot_changed: EventId - /** Event type: {@link OnEquipmentInsertedEvent} */ - const on_equipment_inserted: EventId - /** Event type: {@link OnEquipmentRemovedEvent} */ - const on_equipment_removed: EventId - } - /** - * See the {@link https://lua-api.factorio.com/next/events.html events page} for more info on what events contain and - * when they get raised. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.events View documentation} - */ - type events = typeof events[keyof typeof events] - enum flow_precision_index { - five_seconds, - one_minute, - ten_minutes, - one_hour, - ten_hours, - fifty_hours, - two_hundred_fifty_hours, - one_thousand_hours, - } - enum group_state { - gathering, - moving, - attacking_distraction, - attacking_target, - finished, - pathfinding, - wander_in_group, - } - enum gui_type { - none, - entity, - research, - controller, - production, - item, - bonus, - trains, - achievement, - blueprint_library, - equipment, - logistic, - other_player, - permissions, - tutorials, - custom, - server_management, - player_management, - tile, - } - enum input_action { - activate_copy, - activate_cut, - activate_paste, - add_permission_group, - add_train_station, - admin_action, - alt_select_area, - alt_select_blueprint_entities, - alternative_copy, - begin_mining, - begin_mining_terrain, - build, - build_rail, - build_terrain, - cancel_craft, - cancel_deconstruct, - cancel_new_blueprint, - cancel_research, - cancel_upgrade, - change_active_character_tab, - change_active_item_group_for_crafting, - change_active_item_group_for_filters, - change_active_quick_bar, - change_arithmetic_combinator_parameters, - change_decider_combinator_parameters, - change_entity_label, - change_item_description, - change_item_label, - change_multiplayer_config, - change_picking_state, - change_programmable_speaker_alert_parameters, - change_programmable_speaker_circuit_parameters, - change_programmable_speaker_parameters, - change_riding_state, - change_shooting_state, - change_train_stop_station, - change_train_wait_condition, - change_train_wait_condition_data, - clear_cursor, - connect_rolling_stock, - copy, - copy_entity_settings, - copy_opened_blueprint, - copy_opened_item, - craft, - cursor_split, - cursor_transfer, - custom_input, - cycle_blueprint_book_backwards, - cycle_blueprint_book_forwards, - deconstruct, - delete_blueprint_library, - delete_blueprint_record, - delete_custom_tag, - delete_permission_group, - destroy_item, - destroy_opened_item, - disconnect_rolling_stock, - drag_train_schedule, - drag_train_wait_condition, - drop_blueprint_record, - drop_item, - edit_blueprint_tool_preview, - edit_custom_tag, - edit_permission_group, - export_blueprint, - fast_entity_split, - fast_entity_transfer, - flush_opened_entity_fluid, - flush_opened_entity_specific_fluid, - go_to_train_station, - grab_blueprint_record, - gui_checked_state_changed, - gui_click, - gui_confirmed, - gui_elem_changed, - gui_location_changed, - gui_selected_tab_changed, - gui_selection_state_changed, - gui_switch_state_changed, - gui_text_changed, - gui_value_changed, - import_blueprint, - import_blueprint_string, - import_blueprints_filtered, - import_permissions_string, - inventory_split, - inventory_transfer, - launch_rocket, - lua_shortcut, - map_editor_action, - market_offer, - mod_settings_changed, - open_achievements_gui, - open_blueprint_library_gui, - open_blueprint_record, - open_bonus_gui, - open_character_gui, - open_current_vehicle_gui, - open_equipment, - open_gui, - open_item, - open_logistic_gui, - open_mod_item, - open_parent_of_opened_item, - open_production_gui, - open_technology_gui, - open_tips_and_tricks_gui, - open_train_gui, - open_train_station_gui, - open_trains_gui, - paste_entity_settings, - place_equipment, - quick_bar_pick_slot, - quick_bar_set_selected_page, - quick_bar_set_slot, - reassign_blueprint, - remove_cables, - remove_train_station, - reset_assembling_machine, - reset_item, - rotate_entity, - select_area, - select_blueprint_entities, - select_entity_slot, - select_item, - select_mapper_slot, - select_next_valid_gun, - select_tile_slot, - send_spidertron, - set_auto_launch_rocket, - set_autosort_inventory, - set_behavior_mode, - set_car_weapons_control, - set_circuit_condition, - set_circuit_mode_of_operation, - set_controller_logistic_trash_filter_item, - set_deconstruction_item_tile_selection_mode, - set_deconstruction_item_trees_and_rocks_only, - set_entity_color, - set_entity_energy_property, - set_entity_logistic_trash_filter_item, - set_filter, - set_flat_controller_gui, - set_heat_interface_mode, - set_heat_interface_temperature, - set_infinity_container_filter_item, - set_infinity_container_remove_unfiltered_items, - set_infinity_pipe_filter, - set_inserter_max_stack_size, - set_inventory_bar, - set_linked_container_link_i_d, - set_logistic_filter_item, - set_logistic_filter_signal, - set_player_color, - set_recipe_notifications, - set_request_from_buffers, - set_research_finished_stops_game, - set_signal, - set_splitter_priority, - set_train_stopped, - set_trains_limit, - set_vehicle_automatic_targeting_parameters, - setup_assembling_machine, - setup_blueprint, - setup_single_blueprint_record, - smart_pipette, - spawn_item, - stack_split, - stack_transfer, - start_repair, - start_research, - start_walking, - stop_building_by_moving, - switch_connect_to_logistic_network, - switch_constant_combinator_state, - switch_inserter_filter_mode_state, - switch_power_switch_state, - switch_to_rename_stop_gui, - take_equipment, - toggle_deconstruction_item_entity_filter_mode, - toggle_deconstruction_item_tile_filter_mode, - toggle_driving, - toggle_enable_vehicle_logistics_while_moving, - toggle_entity_logistic_requests, - toggle_equipment_movement_bonus, - toggle_map_editor, - toggle_personal_logistic_requests, - toggle_personal_roboport, - toggle_show_entity_info, - translate_string, - undo, - upgrade, - upgrade_opened_blueprint_by_item, - upgrade_opened_blueprint_by_record, - use_artillery_remote, - use_item, - wire_dragging, - write_to_console, - } - enum inventory { - fuel, - burnt_result, - chest, - furnace_source, - furnace_result, - furnace_modules, - character_main, - character_guns, - character_ammo, - character_armor, - character_vehicle, - character_trash, - god_main, - editor_main, - editor_guns, - editor_ammo, - editor_armor, - roboport_robot, - roboport_material, - robot_cargo, - robot_repair, - assembling_machine_input, - assembling_machine_output, - assembling_machine_modules, - lab_input, - lab_modules, - mining_drill_modules, - item_main, - rocket_silo_rocket, - rocket_silo_result, - rocket, - car_trunk, - car_ammo, - cargo_wagon, - turret_ammo, - beacon_modules, - character_corpse, - artillery_turret_ammo, - artillery_wagon_ammo, - spider_trunk, - spider_ammo, - spider_trash, - } - enum logistic_member_index { - logistic_container, - vehicle_storage, - character_requester, - character_storage, - character_provider, - generic_on_off_behavior, - } - enum logistic_mode { - none, - active_provider, - storage, - requester, - passive_provider, - buffer, - } - enum mouse_button_type { - none, - left, - right, - middle, - } - /** - * A dictionary mapping all top-level prototypes by name to a list of their associated subtypes. This list is - * organized as a lookup table, meaning it maps the sub-prototype names to `0`. As an example, - * `defines.prototypes['entity']` looks like this: `{furnace=0, inserter=0, container=0, ...}`. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.prototypes View documentation} - */ - const prototypes: { - readonly [Type in string]?: { - readonly [Name in string]?: 0 & { - _notFalsyBrand: any - } - } - } - enum rail_connection_direction { - left, - straight, - right, - none, - } - enum rail_direction { - front, - back, - } - enum relative_gui_position { - top, - bottom, - left, - right, - } - enum relative_gui_type { - accumulator_gui, - achievement_gui, - additional_entity_info_gui, - admin_gui, - arithmetic_combinator_gui, - armor_gui, - assembling_machine_gui, - assembling_machine_select_recipe_gui, - beacon_gui, - blueprint_book_gui, - blueprint_library_gui, - blueprint_setup_gui, - bonus_gui, - burner_equipment_gui, - car_gui, - constant_combinator_gui, - container_gui, - controller_gui, - decider_combinator_gui, - deconstruction_item_gui, - electric_energy_interface_gui, - electric_network_gui, - entity_variations_gui, - entity_with_energy_source_gui, - equipment_grid_gui, - furnace_gui, - generic_on_off_entity_gui, - heat_interface_gui, - infinity_pipe_gui, - inserter_gui, - item_with_inventory_gui, - lab_gui, - lamp_gui, - linked_container_gui, - loader_gui, - logistic_gui, - market_gui, - mining_drill_gui, - other_player_gui, - permissions_gui, - pipe_gui, - power_switch_gui, - production_gui, - programmable_speaker_gui, - rail_chain_signal_gui, - rail_signal_gui, - reactor_gui, - rename_stop_gui, - resource_entity_gui, - roboport_gui, - rocket_silo_gui, - server_config_gui, - spider_vehicle_gui, - splitter_gui, - standalone_character_gui, - storage_tank_gui, - tile_variations_gui, - train_gui, - train_stop_gui, - trains_gui, - transport_belt_gui, - upgrade_item_gui, - wall_gui, - } - enum render_mode { - game, - chart, - chart_zoomed_in, - } - enum rich_text_setting { - enabled, - disabled, - highlight, - } - namespace riding { - enum acceleration { - nothing, - accelerating, - braking, - reversing, - } - enum direction { - left, - straight, - right, - } - } - enum shooting { - not_shooting, - shooting_enemies, - shooting_selected, - } - /** - * State of an ordinary rail signal. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.signal_state View documentation} - */ - enum signal_state { - /** - * Green. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.signal_state.open View documentation} - */ - open, - /** - * Red. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.signal_state.closed View documentation} - */ - closed, - /** - * Orange. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.signal_state.reserved View documentation} - */ - reserved, - /** - * Red - From circuit network. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.signal_state.reserved_by_circuit_network View documentation} - */ - reserved_by_circuit_network, - } - enum train_state { - /** - * Normal state -- following the path. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.on_the_path View documentation} - */ - on_the_path, - /** - * Had path and lost it -- must stop. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.path_lost View documentation} - */ - path_lost, - /** - * Doesn't have anywhere to go. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.no_schedule View documentation} - */ - no_schedule, - /** - * Has no path and is stopped. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.no_path View documentation} - */ - no_path, - /** - * Braking before a rail signal. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.arrive_signal View documentation} - */ - arrive_signal, - /** - * Waiting at a signal. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.wait_signal View documentation} - */ - wait_signal, - /** - * Braking before a station. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.arrive_station View documentation} - */ - arrive_station, - /** - * Waiting at a station. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.wait_station View documentation} - */ - wait_station, - /** - * Switched to manual control and has to stop. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.manual_control_stop View documentation} - */ - manual_control_stop, - /** - * Can move if user explicitly sits in and rides the train. - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.manual_control View documentation} - */ - manual_control, - /** - * Same as no_path but all candidate train stops are full - * - * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.destination_full View documentation} - */ - destination_full, - } - enum transport_line { - left_line, - right_line, - left_underground_line, - right_underground_line, - secondary_left_line, - secondary_right_line, - left_split_line, - right_split_line, - secondary_left_split_line, - secondary_right_split_line, - } - enum wire_connection_id { - electric_pole, - power_switch_left, - power_switch_right, - } - enum wire_type { - red, - green, - copper, - } -} diff --git a/modules/mod2/typed-factorio/generated/events.d.ts b/modules/mod2/typed-factorio/generated/events.d.ts deleted file mode 100644 index b65e09a..0000000 --- a/modules/mod2/typed-factorio/generated/events.d.ts +++ /dev/null @@ -1,2976 +0,0 @@ -/** @noSelfInFile */ - -/** - * Called when a {@link https://wiki.factorio.com/Prototype/CustomInput CustomInput} is activated. - * - * {@link https://lua-api.factorio.com/next/Events.html#CustomInputEvent View documentation} - */ -interface CustomInputEvent { - /** The player that activated the custom input. */ - readonly player_index: uint - /** The prototype name of the custom input that was activated. */ - readonly input_name: string - /** The mouse cursor position when the custom input was activated. */ - readonly cursor_position: Position - /** Information about the prototype that is selected when the custom input is used. `nil` if none is selected. */ - readonly selected_prototype?: SelectedPrototypeData - /** Identifier of the event */ - readonly name: string - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a unit/group completes a command. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_ai_command_completed View documentation} - */ -interface OnAiCommandCompletedEvent { - /** Unit_number/group_number of the unit/group which just completed a command. */ - readonly unit_number: uint - readonly result: defines.behavior_result - /** Was this command generated by a distraction. */ - readonly was_distracted: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_ai_command_completed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when an area of the map is cloned. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_area_cloned View documentation} - */ -interface OnAreaClonedEvent { - readonly source_surface: LuaSurface - readonly source_area: BoundingBox - readonly destination_surface: LuaSurface - readonly destination_area: BoundingBox - readonly destination_force?: LuaForce - readonly clone_tiles: boolean - readonly clone_entities: boolean - readonly clone_decoratives: boolean - readonly clear_destination_entities: boolean - readonly clear_destination_decoratives: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_area_cloned - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a biter migration builds a base. - * - * **Note**: This will be called multiple times for each migration, once for every biter that is sacrificed to build - * part of the new base. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_biter_base_built View documentation} - */ -interface OnBiterBaseBuiltEvent { - /** The entity that was built. */ - readonly entity: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_biter_base_built - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a set of positions on the map is cloned. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_brush_cloned View documentation} - */ -interface OnBrushClonedEvent { - readonly source_offset: TilePosition - readonly destination_offset: TilePosition - readonly source_surface: LuaSurface - readonly source_positions: TilePosition[] - readonly destination_surface: LuaSurface - readonly destination_force?: LuaForce - readonly clone_tiles: boolean - readonly clone_entities: boolean - readonly clone_decoratives: boolean - readonly clear_destination_entities: boolean - readonly clear_destination_decoratives: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_brush_cloned - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a {@link defines.command.build_base} command reaches its destination, and before building starts. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_build_base_arrived View documentation} - */ -interface OnBuildBaseArrivedEvent { - /** The unit the command was assigned to. */ - readonly unit?: LuaEntity - /** The unit group the command was assigned to. */ - readonly group?: LuaUnitGroup - /** Identifier of the event */ - readonly name: typeof defines.events.on_build_base_arrived - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when player builds something. Can be filtered using {@link LuaPlayerBuiltEntityEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_built_entity View documentation} - */ -interface OnBuiltEntityEvent { - readonly created_entity: LuaEntity - readonly player_index: uint - readonly stack: LuaItemStack - /** The item prototype used to build the entity. Note this won't exist in some situations (built from blueprint, undo, etc). */ - readonly item?: LuaItemPrototype - /** The tags associated with this entity if any. */ - readonly tags?: Tags - /** Identifier of the event */ - readonly name: typeof defines.events.on_built_entity - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the deconstruction of an entity is canceled. Can be filtered using - * {@link LuaEntityDeconstructionCancelledEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_cancelled_deconstruction View documentation} - */ -interface OnCancelledDeconstructionEvent { - readonly entity: LuaEntity - readonly player_index?: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_cancelled_deconstruction - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the upgrade of an entity is canceled. Can be filtered using {@link LuaUpgradeCancelledEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_cancelled_upgrade View documentation} - */ -interface OnCancelledUpgradeEvent { - readonly entity: LuaEntity - readonly player_index?: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_cancelled_upgrade - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a character corpse expires due to timeout or all of the items being removed from it. - * - * **Note**: this is not called if the corpse is mined. See {@link defines.events.on_pre_player_mined_item} to detect that. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_character_corpse_expired View documentation} - */ -interface OnCharacterCorpseExpiredEvent { - /** The corpse. */ - readonly corpse: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_character_corpse_expired - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a chart tag is created. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_chart_tag_added View documentation} - */ -interface OnChartTagAddedEvent { - readonly tag: LuaCustomChartTag - readonly force: LuaForce - readonly player_index?: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_chart_tag_added - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a chart tag is modified by a player. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_chart_tag_modified View documentation} - */ -interface OnChartTagModifiedEvent { - readonly tag: LuaCustomChartTag - readonly player_index?: uint - readonly force: LuaForce - readonly old_text: string - readonly old_icon?: SignalID - readonly old_player?: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_chart_tag_modified - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called just before a chart tag is deleted. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_chart_tag_removed View documentation} - */ -interface OnChartTagRemovedEvent { - readonly tag: LuaCustomChartTag - readonly force: LuaForce - readonly player_index?: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_chart_tag_removed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a chunk is charted or re-charted. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_chunk_charted View documentation} - */ -interface OnChunkChartedEvent { - readonly surface_index: uint - readonly position: ChunkPosition - /** Area of the chunk. */ - readonly area: BoundingBox - readonly force: LuaForce - /** Identifier of the event */ - readonly name: typeof defines.events.on_chunk_charted - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when one or more chunks are deleted using {@link LuaSurface.delete_chunk LuaSurface::delete_chunk}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_chunk_deleted View documentation} - */ -interface OnChunkDeletedEvent { - readonly surface_index: uint - /** The chunks deleted. */ - readonly positions: ChunkPosition[] - /** Identifier of the event */ - readonly name: typeof defines.events.on_chunk_deleted - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a chunk is generated. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_chunk_generated View documentation} - */ -interface OnChunkGeneratedEvent { - /** Area of the chunk. */ - readonly area: BoundingBox - /** Position of the chunk. */ - readonly position: ChunkPosition - /** The surface the chunk is on. */ - readonly surface: LuaSurface - /** Identifier of the event */ - readonly name: typeof defines.events.on_chunk_generated - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a combat robot expires through a lack of energy, or timeout. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_combat_robot_expired View documentation} - */ -interface OnCombatRobotExpiredEvent { - readonly robot: LuaEntity - /** The entity that owns the robot if any. */ - readonly owner?: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_combat_robot_expired - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a message is sent to the in-game console, either by a player or through the server interface. - * - * **Note**: This event only fires for plain messages, not for any commands (including `/shout` or `/whisper`). - * - * {@link https://lua-api.factorio.com/next/Events.html#on_console_chat View documentation} - */ -interface OnConsoleChatEvent { - /** The player doing the chatting, if any. */ - readonly player_index?: uint - /** The chat message that was sent. */ - readonly message: string - /** Identifier of the event */ - readonly name: typeof defines.events.on_console_chat - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when someone enters a command-like message regardless of it being a valid command. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_console_command View documentation} - */ -interface OnConsoleCommandEvent { - /** The player if any. */ - readonly player_index?: uint - /** The command as typed without the preceding forward slash ('/'). */ - readonly command: string - /** The parameters provided if any. */ - readonly parameters: string - /** Identifier of the event */ - readonly name: typeof defines.events.on_console_command - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a cutscene is cancelled by the player or by script. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_cutscene_cancelled View documentation} - */ -interface OnCutsceneCancelledEvent { - /** The player the cutscene was shown to. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_cutscene_cancelled - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a cutscene is playing, each time it reaches a waypoint in that cutscene. - * - * This refers to an index in the table previously passed to set_controller which started the cutscene. - * - * **Note**: Due to implementation omission, waypoint_index is 0-based. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_cutscene_waypoint_reached View documentation} - */ -interface OnCutsceneWaypointReachedEvent { - /** The player index of the player viewing the cutscene. */ - readonly player_index: uint - /** The index of the waypoint we just completed. */ - readonly waypoint_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_cutscene_waypoint_reached - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the map difficulty settings are changed. - * - * **Note**: It's not guaranteed that both settings are changed - just that at least one has been changed. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_difficulty_settings_changed View documentation} - */ -interface OnDifficultySettingsChangedEvent { - readonly old_recipe_difficulty: uint - readonly old_technology_difficulty: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_difficulty_settings_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when an entity is cloned. Can be filtered for the source entity using {@link LuaEntityClonedEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_entity_cloned View documentation} - */ -interface OnEntityClonedEvent { - readonly source: LuaEntity - readonly destination: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_entity_cloned - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when an entity is damaged. Can be filtered using {@link LuaEntityDamagedEventFilter}. - * - * **Note**: This is not called when an entities health is set directly by another mod. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_entity_damaged View documentation} - */ -interface OnEntityDamagedEvent { - readonly entity: LuaEntity - readonly damage_type: LuaDamagePrototype - /** The damage amount before resistances. */ - readonly original_damage_amount: float - /** The damage amount after resistances. */ - readonly final_damage_amount: float - /** The health of the entity after the damage was applied. */ - readonly final_health: float - /** The entity that did the attacking if available. */ - readonly cause?: LuaEntity - /** The force that did the attacking if any. */ - readonly force?: LuaForce - /** Identifier of the event */ - readonly name: typeof defines.events.on_entity_damaged - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after an entity is destroyed that has been registered with - * {@link LuaBootstrap.register_on_entity_destroyed LuaBootstrap::register_on_entity_destroyed} - * - * **Note**: Depending on when a given entity is destroyed this will be fired at the end of the current tick or end of - * the next tick. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_entity_destroyed View documentation} - */ -interface OnEntityDestroyedEvent { - readonly registration_number: uint64 - readonly unit_number?: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_entity_destroyed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when an entity dies. Can be filtered using {@link LuaEntityDiedEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_entity_died View documentation} - */ -interface OnEntityDiedEvent { - /** The entity that died. */ - readonly entity: LuaEntity - /** The entity that did the killing if available. */ - readonly cause?: LuaEntity - /** The loot generated by this entity if any. */ - readonly loot: LuaInventory - /** The force that did the killing if any. */ - readonly force?: LuaForce - /** The damage type if any. */ - readonly damage_type?: LuaDamagePrototype - /** Identifier of the event */ - readonly name: typeof defines.events.on_entity_died - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when one of an entity's personal logistic slots changes. - * - * **Note**: "Personal logistic slot" refers to a character or vehicle's personal request / auto-trash slots, not the - * request slots on logistic chests. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_entity_logistic_slot_changed View documentation} - */ -interface OnEntityLogisticSlotChangedEvent { - /** The player who changed the slot, or `nil` if changed by script. */ - readonly player_index?: uint - /** The entity for whom a logistic slot was changed. */ - readonly entity: LuaEntity - /** The slot index that was changed. */ - readonly slot_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_entity_logistic_slot_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after an entity has been renamed either by the player or through script. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_entity_renamed View documentation} - */ -interface OnEntityRenamedEvent { - /** If by_script is true this will not be included. */ - readonly player_index?: uint - readonly by_script: boolean - readonly entity: LuaEntity - readonly old_name: string - /** Identifier of the event */ - readonly name: typeof defines.events.on_entity_renamed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after entity copy-paste is done. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_entity_settings_pasted View documentation} - */ -interface OnEntitySettingsPastedEvent { - readonly player_index: uint - /** The source entity settings were copied from. */ - readonly source: LuaEntity - /** The destination entity settings were copied to. */ - readonly destination: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_entity_settings_pasted - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when an entity is spawned by a EnemySpawner - * - * {@link https://lua-api.factorio.com/next/Events.html#on_entity_spawned View documentation} - */ -interface OnEntitySpawnedEvent { - readonly spawner: LuaEntity - readonly entity: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_entity_spawned - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after equipment is inserted into an equipment grid. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_equipment_inserted View documentation} - */ -interface OnEquipmentInsertedEvent { - /** The equipment grid inserted into. */ - readonly grid: LuaEquipmentGrid - /** The equipment inserted. */ - readonly equipment: LuaEquipment - /** Identifier of the event */ - readonly name: typeof defines.events.on_equipment_inserted - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after equipment is removed from an equipment grid. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_equipment_removed View documentation} - */ -interface OnEquipmentRemovedEvent { - /** The equipment grid removed from. */ - readonly grid: LuaEquipmentGrid - /** The equipment removed. */ - readonly equipment: string - /** The count of equipment removed. */ - readonly count: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_equipment_removed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the a forces cease fire values change. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_force_cease_fire_changed View documentation} - */ -interface OnForceCeaseFireChangedEvent { - /** The force who's cease fire changed. */ - readonly force: LuaForce - /** Which force was added or removed. */ - readonly other_force: LuaForce - /** If the other force was added or removed. */ - readonly added: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_force_cease_fire_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a new force is created using `game.create_force()` - * - * **Note**: This is not called when the default forces (`'player'`, `'enemy'`, `'neutral'`) are created as they will - * always exist. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_force_created View documentation} - */ -interface OnForceCreatedEvent { - /** The newly created force. */ - readonly force: LuaForce - /** Identifier of the event */ - readonly name: typeof defines.events.on_force_created - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the a forces friends change. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_force_friends_changed View documentation} - */ -interface OnForceFriendsChangedEvent { - /** The force who's friends changed. */ - readonly force: LuaForce - /** Which force was added or removed. */ - readonly other_force: LuaForce - /** If the other force was added or removed. */ - readonly added: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_force_friends_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when {@link LuaForce.reset LuaForce::reset} is finished. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_force_reset View documentation} - */ -interface OnForceResetEvent { - readonly force: LuaForce - /** Identifier of the event */ - readonly name: typeof defines.events.on_force_reset - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after two forces have been merged using `game.merge_forces()`. - * - * **Note**: The source force is invalidated before this event is called and the name can be re-used in this event if desired. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_forces_merged View documentation} - */ -interface OnForcesMergedEvent { - /** The force destroyed. */ - readonly source_name: string - /** The index of the destroyed force. */ - readonly source_index: uint - /** The force entities where reassigned to. */ - readonly destination: LuaForce - /** Identifier of the event */ - readonly name: typeof defines.events.on_forces_merged - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when two forces are about to be merged using `game.merge_forces()`. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_forces_merging View documentation} - */ -interface OnForcesMergingEvent { - /** The force to be destroyed */ - readonly source: LuaForce - /** The force to reassign entities to. */ - readonly destination: LuaForce - /** Identifier of the event */ - readonly name: typeof defines.events.on_forces_merging - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a game is created from a scenario. This is fired for every mod, even when the scenario's save data - * already includes it. In those cases however, {@link LuaBootstrap.on_init LuaBootstrap::on_init} is not fired. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_game_created_from_scenario View documentation} - */ -interface OnGameCreatedFromScenarioEvent { - /** Identifier of the event */ - readonly name: typeof defines.events.on_game_created_from_scenario - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when {@link LuaGuiElement} checked state is changed (related to checkboxes and radio buttons). - * - * {@link https://lua-api.factorio.com/next/Events.html#on_gui_checked_state_changed View documentation} - */ -interface OnGuiCheckedStateChangedEvent { - /** The element whose checked state changed. */ - readonly element: LuaGuiElement - /** The player who did the change. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_gui_checked_state_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when {@link LuaGuiElement} is clicked. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_gui_click View documentation} - */ -interface OnGuiClickEvent { - /** The clicked element. */ - readonly element: LuaGuiElement - /** The player who did the clicking. */ - readonly player_index: uint - /** The mouse button used if any. */ - readonly button: defines.mouse_button_type - /** If alt was pressed. */ - readonly alt: boolean - /** If control was pressed. */ - readonly control: boolean - /** If shift was pressed. */ - readonly shift: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_gui_click - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the player closes the GUI they have open. - * - * **Note**: This is only called if the player explicitly closed the GUI. - * - * **Note**: It's not advised to open any other GUI during this event because if this is run as a request to open a - * different GUI the game will force close the new opened GUI without notice to ensure the original requested GUI is opened. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_gui_closed View documentation} - */ -interface OnGuiClosedEvent { - /** The player. */ - readonly player_index: uint - /** The GUI type that was open. */ - readonly gui_type: defines.gui_type - /** The entity that was open */ - readonly entity?: LuaEntity - /** The item that was open */ - readonly item?: LuaItemStack - /** The equipment that was open */ - readonly equipment?: LuaEquipment - /** The other player that was open */ - readonly other_player?: LuaPlayer - /** The custom GUI element that was open */ - readonly element?: LuaGuiElement - /** The technology that was automatically selected when opening the research GUI */ - readonly technology?: LuaTechnology - /** The tile position that was open */ - readonly tile_position?: TilePosition - /** Identifier of the event */ - readonly name: typeof defines.events.on_gui_closed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a {@link LuaGuiElement} is confirmed, for example by pressing Enter in a textfield. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_gui_confirmed View documentation} - */ -interface OnGuiConfirmedEvent { - /** The confirmed element. */ - readonly element: LuaGuiElement - /** The player who did the confirming. */ - readonly player_index: uint - /** If alt was pressed. */ - readonly alt: boolean - /** If control was pressed. */ - readonly control: boolean - /** If shift was pressed. */ - readonly shift: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_gui_confirmed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when {@link LuaGuiElement} element value is changed (related to choose element buttons). - * - * {@link https://lua-api.factorio.com/next/Events.html#on_gui_elem_changed View documentation} - */ -interface OnGuiElemChangedEvent { - /** The element whose element value changed. */ - readonly element: LuaGuiElement - /** The player who did the change. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_gui_elem_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when {@link LuaGuiElement} element location is changed (related to frames in `player.gui.screen`). - * - * {@link https://lua-api.factorio.com/next/Events.html#on_gui_location_changed View documentation} - */ -interface OnGuiLocationChangedEvent { - /** The element whose location changed. */ - readonly element: LuaGuiElement - /** The player who did the change. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_gui_location_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the player opens a GUI. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_gui_opened View documentation} - */ -interface OnGuiOpenedEvent { - /** The player. */ - readonly player_index: uint - /** The GUI type that was opened. */ - readonly gui_type: defines.gui_type - /** The entity that was opened */ - readonly entity?: LuaEntity - /** The item that was opened */ - readonly item?: LuaItemStack - /** The equipment that was opened */ - readonly equipment?: LuaEquipment - /** The other player that was opened */ - readonly other_player?: LuaPlayer - /** The custom GUI element that was opened */ - readonly element?: LuaGuiElement - /** Identifier of the event */ - readonly name: typeof defines.events.on_gui_opened - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when {@link LuaGuiElement} selected tab is changed (related to tabbed-panes). - * - * {@link https://lua-api.factorio.com/next/Events.html#on_gui_selected_tab_changed View documentation} - */ -interface OnGuiSelectedTabChangedEvent { - /** The tabbed pane whose selected tab changed. */ - readonly element: LuaGuiElement - /** The player who did the change. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_gui_selected_tab_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when {@link LuaGuiElement} selection state is changed (related to drop-downs and listboxes). - * - * {@link https://lua-api.factorio.com/next/Events.html#on_gui_selection_state_changed View documentation} - */ -interface OnGuiSelectionStateChangedEvent { - /** The element whose selection state changed. */ - readonly element: LuaGuiElement - /** The player who did the change. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_gui_selection_state_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when {@link LuaGuiElement} switch state is changed (related to switches). - * - * {@link https://lua-api.factorio.com/next/Events.html#on_gui_switch_state_changed View documentation} - */ -interface OnGuiSwitchStateChangedEvent { - /** The switch whose switch state changed. */ - readonly element: LuaGuiElement - /** The player who did the change. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_gui_switch_state_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when {@link LuaGuiElement} text is changed by the player. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_gui_text_changed View documentation} - */ -interface OnGuiTextChangedEvent { - /** The edited element. */ - readonly element: LuaGuiElement - /** The player who did the edit. */ - readonly player_index: uint - /** The new text in the element. */ - readonly text: string - /** Identifier of the event */ - readonly name: typeof defines.events.on_gui_text_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when {@link LuaGuiElement} slider value is changed (related to the slider element). - * - * {@link https://lua-api.factorio.com/next/Events.html#on_gui_value_changed View documentation} - */ -interface OnGuiValueChangedEvent { - /** The element whose value changed. */ - readonly element: LuaGuiElement - /** The player who did the change. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_gui_value_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a land mine is armed. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_land_mine_armed View documentation} - */ -interface OnLandMineArmedEvent { - readonly mine: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_land_mine_armed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a custom Lua shortcut is pressed. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_lua_shortcut View documentation} - */ -interface OnLuaShortcutEvent { - readonly player_index: uint - /** Shortcut prototype name of the shortcut that was clicked. */ - readonly prototype_name: string - /** Identifier of the event */ - readonly name: typeof defines.events.on_lua_shortcut - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when an entity is marked for deconstruction with the Deconstruction planner or via script. Can be filtered - * using {@link LuaEntityMarkedForDeconstructionEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_marked_for_deconstruction View documentation} - */ -interface OnMarkedForDeconstructionEvent { - readonly entity: LuaEntity - readonly player_index?: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_marked_for_deconstruction - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when an entity is marked for upgrade with the Upgrade planner or via script. Can be filtered using - * {@link LuaEntityMarkedForUpgradeEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_marked_for_upgrade View documentation} - */ -interface OnMarkedForUpgradeEvent { - readonly entity: LuaEntity - readonly target: LuaEntityPrototype - readonly player_index?: uint - /** The new direction (if any) */ - readonly direction?: defines.direction - /** Identifier of the event */ - readonly name: typeof defines.events.on_marked_for_upgrade - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a player purchases some offer from a `market` entity. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_market_item_purchased View documentation} - */ -interface OnMarketItemPurchasedEvent { - /** The player who did the purchasing. */ - readonly player_index: uint - /** The market entity. */ - readonly market: LuaEntity - /** The index of the offer purchased. */ - readonly offer_index: uint - /** The amount of offers purchased. */ - readonly count: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_market_item_purchased - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the player uses the 'Open item GUI' control on an item defined with the 'mod-openable' flag - * - * {@link https://lua-api.factorio.com/next/Events.html#on_mod_item_opened View documentation} - */ -interface OnModItemOpenedEvent { - /** The player. */ - readonly player_index: uint - /** The item clicked on. */ - readonly item: LuaItemPrototype - /** Identifier of the event */ - readonly name: typeof defines.events.on_mod_item_opened - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called directly after a permission group is added. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_permission_group_added View documentation} - */ -interface OnPermissionGroupAddedEvent { - /** The player that added the group. */ - readonly player_index: uint - /** The group added. */ - readonly group: LuaPermissionGroup - /** Identifier of the event */ - readonly name: typeof defines.events.on_permission_group_added - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called directly after a permission group is deleted. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_permission_group_deleted View documentation} - */ -interface OnPermissionGroupDeletedEvent { - /** The player doing the deletion. */ - readonly player_index: uint - /** The group that was deleted. */ - readonly group_name: string - /** The group id that was deleted. */ - readonly id: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_permission_group_deleted - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called directly after a permission group is edited in some way. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_permission_group_edited View documentation} - */ -interface OnPermissionGroupEditedEvent { - /** The player that did the editing. */ - readonly player_index: uint - /** The group being edited. */ - readonly group: LuaPermissionGroup - /** The edit type: "add-permission", "remove-permission", "enable-all", "disable-all", "add-player", "remove-player", "rename". */ - readonly type: - | "add-permission" - | "remove-permission" - | "enable-all" - | "disable-all" - | "add-player" - | "remove-player" - | "rename" - /** The action when the `type` is "add-permission" or "remove-permission". */ - readonly action: defines.input_action - /** The other player when the `type` is "add-player" or "remove-player". */ - readonly other_player_index: uint - /** The old group name when the `type` is "rename". */ - readonly old_name: string - /** The new group name when the `type` is "rename". */ - readonly new_name: string - /** Identifier of the event */ - readonly name: typeof defines.events.on_permission_group_edited - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called directly after a permission string is imported. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_permission_string_imported View documentation} - */ -interface OnPermissionStringImportedEvent { - /** The player that imported the string. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_permission_string_imported - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player picks up an item. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_picked_up_item View documentation} - */ -interface OnPickedUpItemEvent { - readonly item_stack: SimpleItemStack - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_picked_up_item - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a player alt-selects an area with a selection-tool item. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_alt_selected_area View documentation} - */ -interface OnPlayerAltSelectedAreaEvent { - /** The player doing the selection. */ - readonly player_index: uint - /** The surface selected. */ - readonly surface: LuaSurface - /** The area selected. */ - readonly area: BoundingBox - /** The item used to select the area. */ - readonly item: string - /** The entities selected. */ - readonly entities: LuaEntity[] - /** The tiles selected. */ - readonly tiles: LuaTile[] - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_alt_selected_area - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a players ammo inventory changed in some way. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_ammo_inventory_changed View documentation} - */ -interface OnPlayerAmmoInventoryChangedEvent { - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_ammo_inventory_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a players armor inventory changed in some way. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_armor_inventory_changed View documentation} - */ -interface OnPlayerArmorInventoryChangedEvent { - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_armor_inventory_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player is banned. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_banned View documentation} - */ -interface OnPlayerBannedEvent { - /** The player banned. */ - readonly player_index?: uint - /** The banned player name. */ - readonly player_name: string - /** The player that did the banning if any. */ - readonly by_player?: uint - /** The reason given if any. */ - readonly reason?: string - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_banned - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a player builds tiles. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_built_tile View documentation} - */ -interface OnPlayerBuiltTileEvent { - readonly player_index: uint - /** The surface the tile(s) were built on. */ - readonly surface_index: uint - /** The position data. */ - readonly tiles: OldTileAndPosition[] - /** The tile prototype that was placed. */ - readonly tile: LuaTilePrototype - /** The item type used to build the tiles */ - readonly item?: LuaItemPrototype - /** The stack used to build the tiles (may be empty if all of the items where used to build the tiles). */ - readonly stack?: LuaItemStack - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_built_tile - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player cancels crafting. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_cancelled_crafting View documentation} - */ -interface OnPlayerCancelledCraftingEvent { - /** The player that did the crafting. */ - readonly player_index: uint - /** The crafting items returned to the player's inventory. */ - readonly items: LuaInventory - /** The recipe that has been cancelled. */ - readonly recipe: LuaRecipe - /** The number of crafts that have been cancelled. */ - readonly cancel_count: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_cancelled_crafting - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a player changes forces. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_changed_force View documentation} - */ -interface OnPlayerChangedForceEvent { - /** The player who changed forces. */ - readonly player_index: uint - /** The old force. */ - readonly force: LuaForce - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_changed_force - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the tile position a player is located at changes. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_changed_position View documentation} - */ -interface OnPlayerChangedPositionEvent { - /** The player. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_changed_position - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a player changes surfaces. - * - * **Note**: In the instance a player is moved off a surface due to it being deleted this is not called. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_changed_surface View documentation} - */ -interface OnPlayerChangedSurfaceEvent { - /** The player who changed surfaces. */ - readonly player_index: uint - /** The surface index the player was on. */ - readonly surface_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_changed_surface - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when cheat mode is disabled on a player. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_cheat_mode_disabled View documentation} - */ -interface OnPlayerCheatModeDisabledEvent { - /** The player. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_cheat_mode_disabled - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when cheat mode is enabled on a player. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_cheat_mode_enabled View documentation} - */ -interface OnPlayerCheatModeEnabledEvent { - /** The player. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_cheat_mode_enabled - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player clicks a gps tag - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_clicked_gps_tag View documentation} - */ -interface OnPlayerClickedGpsTagEvent { - /** Index of the player */ - readonly player_index: uint - /** Map position contained in gps tag */ - readonly position: Position - /** Surface name contained in gps tag, even when such surface does not exists */ - readonly surface: string - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_clicked_gps_tag - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player clicks the "confirm" button in the configure Blueprint GUI. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_configured_blueprint View documentation} - */ -interface OnPlayerConfiguredBlueprintEvent { - /** The player. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_configured_blueprint - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player configures spidertron remote to be connected with a given spidertron - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_configured_spider_remote View documentation} - */ -interface OnPlayerConfiguredSpiderRemoteEvent { - /** The player that configured the remote. */ - readonly player_index: uint - /** Spider vehicle to which remote was connected to. */ - readonly vehicle: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_configured_spider_remote - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the player finishes crafting an item. This event fires just before the results are inserted into the - * player's inventory, not when the crafting is queued (see {@link OnPrePlayerCraftedItemEvent on_pre_player_crafted_item}). - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_crafted_item View documentation} - */ -interface OnPlayerCraftedItemEvent { - /** The item that has been crafted. */ - readonly item_stack: LuaItemStack - /** The player doing the crafting. */ - readonly player_index: uint - /** The recipe used to craft this item. */ - readonly recipe: LuaRecipe - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_crafted_item - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after the player was created. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_created View documentation} - */ -interface OnPlayerCreatedEvent { - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_created - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a players cursorstack changed in some way. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_cursor_stack_changed View documentation} - */ -interface OnPlayerCursorStackChangedEvent { - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_cursor_stack_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player selects an area with a deconstruction planner. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_deconstructed_area View documentation} - */ -interface OnPlayerDeconstructedAreaEvent { - /** The player doing the selection. */ - readonly player_index: uint - /** The surface selected. */ - readonly surface: LuaSurface - /** The area selected. */ - readonly area: BoundingBox - /** The item used to select the area. */ - readonly item: string - /** If normal selection or alt selection was used. */ - readonly alt: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_deconstructed_area - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player is demoted. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_demoted View documentation} - */ -interface OnPlayerDemotedEvent { - /** The player. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_demoted - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a player dies. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_died View documentation} - */ -interface OnPlayerDiedEvent { - readonly player_index: uint - readonly cause?: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_died - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the display resolution changes for a given player. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_display_resolution_changed View documentation} - */ -interface OnPlayerDisplayResolutionChangedEvent { - /** The player */ - readonly player_index: uint - /** The old display resolution */ - readonly old_resolution: DisplayResolution - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_display_resolution_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the display scale changes for a given player. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_display_scale_changed View documentation} - */ -interface OnPlayerDisplayScaleChangedEvent { - /** The player */ - readonly player_index: uint - /** The old display scale */ - readonly old_scale: double - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_display_scale_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the player's driving state has changed, this means a player has either entered or left a vehicle. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_driving_changed_state View documentation} - */ -interface OnPlayerDrivingChangedStateEvent { - readonly player_index: uint - /** The vehicle if any. */ - readonly entity?: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_driving_changed_state - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player drops an item on the ground. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_dropped_item View documentation} - */ -interface OnPlayerDroppedItemEvent { - readonly player_index: uint - /** The item-on-ground entity. */ - readonly entity: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_dropped_item - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player fast-transfers something to or from an entity. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_fast_transferred View documentation} - */ -interface OnPlayerFastTransferredEvent { - /** The player transferred from or to. */ - readonly player_index: uint - /** The entity transferred from or to. */ - readonly entity: LuaEntity - /** Whether the transfer was from player to entity. If `false`, the transfer was from entity to player. */ - readonly from_player: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_fast_transferred - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after player flushed fluid - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_flushed_fluid View documentation} - */ -interface OnPlayerFlushedFluidEvent { - /** Index of the player */ - readonly player_index: uint - /** Name of a fluid that was flushed */ - readonly fluid: string - /** Amount of fluid that was removed */ - readonly amount: double - /** Entity from which flush was performed */ - readonly entity: LuaEntity - /** True if flush was requested only on this entity */ - readonly only_this_entity: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_flushed_fluid - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a players gun inventory changed in some way. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_gun_inventory_changed View documentation} - */ -interface OnPlayerGunInventoryChangedEvent { - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_gun_inventory_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a player joins the game. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_joined_game View documentation} - */ -interface OnPlayerJoinedGameEvent { - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_joined_game - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player is kicked. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_kicked View documentation} - */ -interface OnPlayerKickedEvent { - /** The player kicked. */ - readonly player_index: uint - /** The player that did the kicking if any. */ - readonly by_player?: uint - /** The reason given if any. */ - readonly reason?: string - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_kicked - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a player leaves the game. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_left_game View documentation} - */ -interface OnPlayerLeftGameEvent { - readonly player_index: uint - readonly reason: defines.disconnect_reason - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_left_game - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a players main inventory changed in some way. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_main_inventory_changed View documentation} - */ -interface OnPlayerMainInventoryChangedEvent { - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_main_inventory_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after the results of an entity being mined are collected just before the entity is destroyed. After this event - * any items in the buffer will be transferred into the player as if they came from mining the entity. Can be filtered - * using {@link LuaPlayerMinedEntityEventFilter}. - * - * **Note**: The buffer inventory is special in that it's only valid during this event and has a dynamic size expanding - * as more items are transferred into it. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_mined_entity View documentation} - */ -interface OnPlayerMinedEntityEvent { - /** The index of the player doing the mining. */ - readonly player_index: uint - /** The entity that has been mined. */ - readonly entity: LuaEntity - /** The temporary inventory that holds the result of mining the entity. */ - readonly buffer: LuaInventory - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_mined_entity - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the player mines something. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_mined_item View documentation} - */ -interface OnPlayerMinedItemEvent { - /** The item given to the player */ - readonly item_stack: SimpleItemStack - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_mined_item - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a player mines tiles. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_mined_tile View documentation} - */ -interface OnPlayerMinedTileEvent { - readonly player_index: uint - /** The surface the tile(s) were mined from. */ - readonly surface_index: uint - /** The position data. */ - readonly tiles: OldTileAndPosition[] - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_mined_tile - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player is muted. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_muted View documentation} - */ -interface OnPlayerMutedEvent { - /** The player. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_muted - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player invokes the "smart pipette" over an entity. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_pipette View documentation} - */ -interface OnPlayerPipetteEvent { - /** The player */ - readonly player_index: uint - /** The item put in the cursor */ - readonly item: LuaItemPrototype - /** If cheat mode was used to give a free stack of the item. */ - readonly used_cheat_mode: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_pipette - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after the player puts equipment in an equipment grid - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_placed_equipment View documentation} - */ -interface OnPlayerPlacedEquipmentEvent { - readonly player_index: uint - /** The equipment put in the equipment grid. */ - readonly equipment: LuaEquipment - /** The equipment grid the equipment was put in. */ - readonly grid: LuaEquipmentGrid - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_placed_equipment - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player is promoted. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_promoted View documentation} - */ -interface OnPlayerPromotedEvent { - /** The player. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_promoted - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player is removed (deleted) from the game. Not to be confused with the player logging of this is - * different in that the player is deleted as if he never existed in the save file. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_removed View documentation} - */ -interface OnPlayerRemovedEvent { - /** The player index that was removed */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_removed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after the player removes equipment from an equipment grid - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_removed_equipment View documentation} - */ -interface OnPlayerRemovedEquipmentEvent { - readonly player_index: uint - /** The equipment grid removed from. */ - readonly grid: LuaEquipmentGrid - /** The equipment removed. */ - readonly equipment: string - /** The count of equipment removed. */ - readonly count: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_removed_equipment - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player repairs an entity. Can be filtered using {@link LuaPlayerRepairedEntityEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_repaired_entity View documentation} - */ -interface OnPlayerRepairedEntityEvent { - readonly player_index: uint - readonly entity: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_repaired_entity - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a player respawns. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_respawned View documentation} - */ -interface OnPlayerRespawnedEvent { - readonly player_index: uint - /** The player port used to respawn if one was used. */ - readonly player_port?: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_respawned - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the player rotates an entity. This event is only fired when the entity actually changes its orientation - * -- pressing the rotate key on an entity that can't be rotated won't fire this event. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_rotated_entity View documentation} - */ -interface OnPlayerRotatedEntityEvent { - /** The rotated entity. */ - readonly entity: LuaEntity - /** The previous direction */ - readonly previous_direction: defines.direction - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_rotated_entity - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a player selects an area with a selection-tool item. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_selected_area View documentation} - */ -interface OnPlayerSelectedAreaEvent { - /** The player doing the selection. */ - readonly player_index: uint - /** The surface selected. */ - readonly surface: LuaSurface - /** The area selected. */ - readonly area: BoundingBox - /** The item used to select the area. */ - readonly item: string - /** The entities selected. */ - readonly entities: LuaEntity[] - /** The tiles selected. */ - readonly tiles: LuaTile[] - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_selected_area - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player sets a quickbar slot to anything (new value, or set to empty). - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_set_quick_bar_slot View documentation} - */ -interface OnPlayerSetQuickBarSlotEvent { - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_set_quick_bar_slot - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player selects an area with a blueprint. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_setup_blueprint View documentation} - */ -interface OnPlayerSetupBlueprintEvent { - /** The player doing the selection. */ - readonly player_index: uint - /** The surface selected. */ - readonly surface: LuaSurface - /** The area selected. */ - readonly area: BoundingBox - /** The item used to select the area. */ - readonly item: string - /** If normal selection or alt selection was used. */ - readonly alt: boolean - /** The blueprint entity index to source entity mapping. Note: if any mod changes the blueprint this will be incorrect. */ - readonly mapping: LuaLazyLoadedValue> - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_setup_blueprint - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player toggles alt mode, also known as "show entity info". - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_toggled_alt_mode View documentation} - */ -interface OnPlayerToggledAltModeEvent { - readonly player_index: uint - /** - * The new alt mode value. This value is a shortcut for accessing - * {@link GameViewSettings.show_entity_info GameViewSettings::show_entity_info} on the player. - */ - readonly alt_mode: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_toggled_alt_mode - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player toggles the map editor on or off. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_toggled_map_editor View documentation} - */ -interface OnPlayerToggledMapEditorEvent { - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_toggled_map_editor - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a players trash inventory changed in some way. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_trash_inventory_changed View documentation} - */ -interface OnPlayerTrashInventoryChangedEvent { - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_trash_inventory_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player is un-banned. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_unbanned View documentation} - */ -interface OnPlayerUnbannedEvent { - /** The player un-banned. */ - readonly player_index?: uint - /** The player name un-banned. */ - readonly player_name: string - /** The player that did the un-banning if any. */ - readonly by_player?: uint - /** The reason the player was banned if any. */ - readonly reason?: string - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_unbanned - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player is unmuted. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_unmuted View documentation} - */ -interface OnPlayerUnmutedEvent { - /** The player. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_unmuted - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player uses a capsule that results in some game action. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_used_capsule View documentation} - */ -interface OnPlayerUsedCapsuleEvent { - /** The player. */ - readonly player_index: uint - /** The capsule item used. */ - readonly item: LuaItemPrototype - /** The position the capsule was used. */ - readonly position: Position - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_used_capsule - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player uses spidertron remote to send a spidertron to a given position - * - * {@link https://lua-api.factorio.com/next/Events.html#on_player_used_spider_remote View documentation} - */ -interface OnPlayerUsedSpiderRemoteEvent { - /** The player that used the remote. */ - readonly player_index: uint - /** Spider vehicle which was requested to move. */ - readonly vehicle: LuaEntity - /** Goal position to which spidertron was sent to. */ - readonly position: Position - /** If the use was successful. It may fail when spidertron has different driver or when player is on different surface. */ - readonly success: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_player_used_spider_remote - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after an entity dies. Can be filtered using {@link LuaPostEntityDiedEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_post_entity_died View documentation} - */ -interface OnPostEntityDiedEvent { - /** The ghost created by the entity dying if any. */ - readonly ghost?: LuaEntity - /** The force that did the killing if any. */ - readonly force?: LuaForce - /** Position where the entity died. */ - readonly position: Position - /** The entity prototype of the entity that died. */ - readonly prototype: LuaEntityPrototype - /** The damage type if any. */ - readonly damage_type?: LuaDamagePrototype - /** The corpses created by the entity dying if any. */ - readonly corpses: LuaEntity[] - /** The surface the entity was on. */ - readonly surface_index: uint - /** The unit number the entity had if any. */ - readonly unit_number?: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_post_entity_died - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when players uses an item to build something. Called before {@link OnBuiltEntityEvent on_built_entity}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_pre_build View documentation} - */ -interface OnPreBuildEvent { - /** The player who did the placing. */ - readonly player_index: uint - /** Where the item was placed. */ - readonly position: Position - /** Item was placed using shift building. */ - readonly shift_build: boolean - /** The direction the item was facing when placed. */ - readonly direction: defines.direction - /** If building this blueprint was flipped horizontally. */ - readonly flip_horizontal: boolean - /** If building this blueprint was flipped vertically. */ - readonly flip_vertical: boolean - /** Item was placed while moving. */ - readonly created_by_moving: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_pre_build - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called before one or more chunks are deleted using {@link LuaSurface.delete_chunk LuaSurface::delete_chunk}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_pre_chunk_deleted View documentation} - */ -interface OnPreChunkDeletedEvent { - readonly surface_index: uint - /** The chunks to be deleted. */ - readonly positions: ChunkPosition[] - /** Identifier of the event */ - readonly name: typeof defines.events.on_pre_chunk_deleted - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called before entity copy-paste is done. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_pre_entity_settings_pasted View documentation} - */ -interface OnPreEntitySettingsPastedEvent { - readonly player_index: uint - /** The source entity settings will be copied from. */ - readonly source: LuaEntity - /** The destination entity settings will be copied to. */ - readonly destination: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_pre_entity_settings_pasted - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called before a ghost entity is destroyed as a result of being marked for deconstruction. Can be filtered using - * {@link LuaPreGhostDeconstructedEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_pre_ghost_deconstructed View documentation} - */ -interface OnPreGhostDeconstructedEvent { - /** The player that did the deconstruction if any. */ - readonly player_index?: uint - readonly ghost: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_pre_ghost_deconstructed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called directly before a permission group is deleted. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_pre_permission_group_deleted View documentation} - */ -interface OnPrePermissionGroupDeletedEvent { - /** The player doing the deletion. */ - readonly player_index: uint - /** The group to be deleted. */ - readonly group: LuaPermissionGroup - /** Identifier of the event */ - readonly name: typeof defines.events.on_pre_permission_group_deleted - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called directly before a permission string is imported. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_pre_permission_string_imported View documentation} - */ -interface OnPrePermissionStringImportedEvent { - /** The player importing the string. */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_pre_permission_string_imported - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a player queues something to be crafted. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_pre_player_crafted_item View documentation} - */ -interface OnPrePlayerCraftedItemEvent { - /** The player doing the crafting. */ - readonly player_index: uint - /** The recipe being queued. */ - readonly recipe: LuaRecipe - /** The items removed from the players inventory to do the crafting. */ - readonly items: LuaInventory - /** The number of times the recipe is being queued. */ - readonly queued_count: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_pre_player_crafted_item - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called before a players dies. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_pre_player_died View documentation} - */ -interface OnPrePlayerDiedEvent { - readonly player_index: uint - readonly cause?: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_pre_player_died - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called before a player leaves the game. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_pre_player_left_game View documentation} - */ -interface OnPrePlayerLeftGameEvent { - readonly player_index: uint - readonly reason: defines.disconnect_reason - /** Identifier of the event */ - readonly name: typeof defines.events.on_pre_player_left_game - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the player finishes mining an entity, before the entity is removed from map. Can be filtered using - * {@link LuaPrePlayerMinedEntityEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_pre_player_mined_item View documentation} - */ -interface OnPrePlayerMinedItemEvent { - /** The entity being mined */ - readonly entity: LuaEntity - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_pre_player_mined_item - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called before a player is removed (deleted) from the game. Not to be confused with the player logging of this is - * different in that the player is deleted as if he never existed in the save file. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_pre_player_removed View documentation} - */ -interface OnPrePlayerRemovedEvent { - /** The player index that will be removed */ - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_pre_player_removed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called before a player toggles the map editor on or off. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_pre_player_toggled_map_editor View documentation} - */ -interface OnPrePlayerToggledMapEditorEvent { - readonly player_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_pre_player_toggled_map_editor - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called directly before a robot explodes cliffs. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_pre_robot_exploded_cliff View documentation} - */ -interface OnPreRobotExplodedCliffEvent { - readonly robot: LuaEntity - readonly cliff: LuaEntity - /** The cliff explosive used. */ - readonly item: LuaItemPrototype - /** Identifier of the event */ - readonly name: typeof defines.events.on_pre_robot_exploded_cliff - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called just before a script inventory is resized. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_pre_script_inventory_resized View documentation} - */ -interface OnPreScriptInventoryResizedEvent { - /** If done by console command; the player who ran the command. */ - readonly player_index?: uint - /** The mod that did the resizing. This will be `"core"` if done by console command or scenario script. */ - readonly mod: string - readonly inventory: LuaInventory - /** The old inventory size. */ - readonly old_size: uint - /** The new inventory size. */ - readonly new_size: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_pre_script_inventory_resized - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called just before a surface is cleared (all entities removed and all chunks deleted). - * - * {@link https://lua-api.factorio.com/next/Events.html#on_pre_surface_cleared View documentation} - */ -interface OnPreSurfaceClearedEvent { - readonly surface_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_pre_surface_cleared - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called just before a surface is deleted. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_pre_surface_deleted View documentation} - */ -interface OnPreSurfaceDeletedEvent { - readonly surface_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_pre_surface_deleted - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a research finishes. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_research_finished View documentation} - */ -interface OnResearchFinishedEvent { - /** The researched technology */ - readonly research: LuaTechnology - /** If the technology was researched by script. */ - readonly by_script: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_research_finished - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a research is reversed (unresearched). - * - * {@link https://lua-api.factorio.com/next/Events.html#on_research_reversed View documentation} - */ -interface OnResearchReversedEvent { - /** The technology un-researched */ - readonly research: LuaTechnology - /** If the technology was un-researched by script. */ - readonly by_script: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_research_reversed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a technology research starts. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_research_started View documentation} - */ -interface OnResearchStartedEvent { - /** The technology being researched */ - readonly research: LuaTechnology - readonly last_research?: LuaTechnology - /** Identifier of the event */ - readonly name: typeof defines.events.on_research_started - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a resource entity reaches 0 or its minimum yield for infinite resources. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_resource_depleted View documentation} - */ -interface OnResourceDepletedEvent { - readonly entity: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_resource_depleted - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a construction robot builds an entity. Can be filtered using {@link LuaRobotBuiltEntityEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_robot_built_entity View documentation} - */ -interface OnRobotBuiltEntityEvent { - /** The robot that did the building. */ - readonly robot: LuaEntity - /** The entity built. */ - readonly created_entity: LuaEntity - /** The item used to do the building. */ - readonly stack: LuaItemStack - /** The tags associated with this entity if any. */ - readonly tags?: Tags - /** Identifier of the event */ - readonly name: typeof defines.events.on_robot_built_entity - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a robot builds tiles. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_robot_built_tile View documentation} - */ -interface OnRobotBuiltTileEvent { - /** The robot. */ - readonly robot: LuaEntity - /** The position data. */ - readonly tiles: OldTileAndPosition[] - /** The tile prototype that was placed. */ - readonly tile: LuaTilePrototype - /** The item type used to build the tiles. */ - readonly item: LuaItemPrototype - /** The stack used to build the tiles (may be empty if all of the items where used to build the tiles). */ - readonly stack: LuaItemStack - /** The surface the tile(s) are build on. */ - readonly surface_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_robot_built_tile - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called directly after a robot explodes cliffs. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_robot_exploded_cliff View documentation} - */ -interface OnRobotExplodedCliffEvent { - readonly robot: LuaEntity - /** The cliff explosive used. */ - readonly item: LuaItemPrototype - /** Identifier of the event */ - readonly name: typeof defines.events.on_robot_exploded_cliff - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a robot mines an entity. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_robot_mined View documentation} - */ -interface OnRobotMinedEvent { - /** The robot that did the mining. */ - readonly robot: LuaEntity - /** The entity the robot just picked up. */ - readonly item_stack: SimpleItemStack - /** Identifier of the event */ - readonly name: typeof defines.events.on_robot_mined - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after the results of an entity being mined are collected just before the entity is destroyed. After this event - * any items in the buffer will be transferred into the robot as if they came from mining the entity. Can be filtered - * using {@link LuaRobotMinedEntityEventFilter}. - * - * **Note**: The buffer inventory is special in that it's only valid during this event and has a dynamic size expanding - * as more items are transferred into it. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_robot_mined_entity View documentation} - */ -interface OnRobotMinedEntityEvent { - /** The robot doing the mining. */ - readonly robot: LuaEntity - /** The entity that has been mined. */ - readonly entity: LuaEntity - /** The temporary inventory that holds the result of mining the entity. */ - readonly buffer: LuaInventory - /** Identifier of the event */ - readonly name: typeof defines.events.on_robot_mined_entity - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a robot mines tiles. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_robot_mined_tile View documentation} - */ -interface OnRobotMinedTileEvent { - /** The robot. */ - readonly robot: LuaEntity - /** The position data. */ - readonly tiles: OldTileAndPosition[] - /** The surface the tile(s) were mined on. */ - readonly surface_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_robot_mined_tile - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called before a robot mines an entity. Can be filtered using {@link LuaPreRobotMinedEntityEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_robot_pre_mined View documentation} - */ -interface OnRobotPreMinedEvent { - /** The robot that's about to do the mining. */ - readonly robot: LuaEntity - /** The entity which is about to be mined. */ - readonly entity: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_robot_pre_mined - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a rocket silo is ordered to be launched. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_rocket_launch_ordered View documentation} - */ -interface OnRocketLaunchOrderedEvent { - readonly rocket: LuaEntity - readonly rocket_silo: LuaEntity - /** The player that is riding the rocket, if any. */ - readonly player_index?: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_rocket_launch_ordered - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when the rocket is launched. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_rocket_launched View documentation} - */ -interface OnRocketLaunchedEvent { - readonly rocket: LuaEntity - readonly rocket_silo?: LuaEntity - /** The player that is riding the rocket, if any. */ - readonly player_index?: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_rocket_launched - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a runtime mod setting is changed by a player. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_runtime_mod_setting_changed View documentation} - */ -interface OnRuntimeModSettingChangedEvent { - /** - * If the `setting_type` is `"global"` and it was changed through the mod settings GUI, this is the index of the - * player that changed the global setting. If the `setting_type` is `"runtime-per-user"` and it changed a current - * setting of the player, this is the index of the player whose setting was changed. In all other cases, this is `nil`. - */ - readonly player_index?: uint - /** The prototype name of the setting that was changed. */ - readonly setting: string - /** Either "runtime-per-user" or "runtime-global". */ - readonly setting_type: "runtime-per-user" | "runtime-global" - /** Identifier of the event */ - readonly name: typeof defines.events.on_runtime_mod_setting_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called just after a script inventory is resized. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_script_inventory_resized View documentation} - */ -interface OnScriptInventoryResizedEvent { - /** If done by console command; the player who ran the command. */ - readonly player_index?: uint - /** The mod that did the resizing. This will be `"core"` if done by console command or scenario script. */ - readonly mod: string - readonly inventory: LuaInventory - /** The old inventory size. */ - readonly old_size: uint - /** The new inventory size. */ - readonly new_size: uint - /** Any items which didn't fit into the new inventory size. */ - readonly overflow_inventory: LuaInventory - /** Identifier of the event */ - readonly name: typeof defines.events.on_script_inventory_resized - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a {@link LuaSurface.request_path LuaSurface::request_path} call completes. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_script_path_request_finished View documentation} - */ -interface OnScriptPathRequestFinishedEvent { - /** The actual path that the pathfinder has determined. `nil` if pathfinding failed. */ - readonly path?: PathfinderWaypoint[] - /** Handle to associate the callback with a particular call to {@link LuaSurface.request_path LuaSurface::request_path}. */ - readonly id: uint - /** Indicates that the pathfinder failed because it is too busy, and that you can retry later. */ - readonly try_again_later: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_script_path_request_finished - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a script trigger effect is triggered. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_script_trigger_effect View documentation} - */ -interface OnScriptTriggerEffectEvent { - /** The effect_id specified in the trigger effect. */ - readonly effect_id: string - /** The surface the effect happened on. */ - readonly surface_index: uint - readonly source_position?: Position - readonly source_entity?: LuaEntity - readonly target_position?: Position - readonly target_entity?: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_script_trigger_effect - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when an entity of type `radar` finishes scanning a sector. Can be filtered for the radar using - * {@link LuaSectorScannedEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_sector_scanned View documentation} - */ -interface OnSectorScannedEvent { - /** The radar that did the scanning. */ - readonly radar: LuaEntity - /** The chunk scanned. */ - readonly chunk_position: ChunkPosition - /** Area of the scanned chunk. */ - readonly area: BoundingBox - /** Identifier of the event */ - readonly name: typeof defines.events.on_sector_scanned - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after the selected entity changes for a given player. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_selected_entity_changed View documentation} - */ -interface OnSelectedEntityChangedEvent { - /** The player whose selected entity changed. */ - readonly player_index: uint - /** The last selected entity if it still exists and there was one. */ - readonly last_entity?: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_selected_entity_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a spider finishes moving to its autopilot position. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_spider_command_completed View documentation} - */ -interface OnSpiderCommandCompletedEvent { - /** Spider vehicle which was requested to move. */ - readonly vehicle: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_spider_command_completed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a translation request generated through - * {@link LuaPlayer.request_translation LuaPlayer::request_translation} is translated. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_string_translated View documentation} - */ -interface OnStringTranslatedEvent { - /** The player whose locale was used for the translation. */ - readonly player_index: uint - /** The localised string being translated. */ - readonly localised_string: LocalisedString - /** The translated `localised_string`. */ - readonly result: string - /** Whether the requested localised string was valid and could be translated. */ - readonly translated: boolean - /** Identifier of the event */ - readonly name: typeof defines.events.on_string_translated - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called just after a surface is cleared (all entities removed and all chunks deleted). - * - * {@link https://lua-api.factorio.com/next/Events.html#on_surface_cleared View documentation} - */ -interface OnSurfaceClearedEvent { - readonly surface_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_surface_cleared - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a surface is created. - * - * **Note**: This is not called when the default surface is created as it will always exist. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_surface_created View documentation} - */ -interface OnSurfaceCreatedEvent { - readonly surface_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_surface_created - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a surface is deleted. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_surface_deleted View documentation} - */ -interface OnSurfaceDeletedEvent { - readonly surface_index: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_surface_deleted - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called after a surface is imported. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_surface_imported View documentation} - */ -interface OnSurfaceImportedEvent { - readonly surface_index: uint - /** The original surface name. */ - readonly original_name: string - /** Identifier of the event */ - readonly name: typeof defines.events.on_surface_imported - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a surface is renamed. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_surface_renamed View documentation} - */ -interface OnSurfaceRenamedEvent { - readonly surface_index: uint - readonly old_name: string - readonly new_name: string - /** Identifier of the event */ - readonly name: typeof defines.events.on_surface_renamed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when {@link LuaForce.reset_technology_effects LuaForce::reset_technology_effects} is finished. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_technology_effects_reset View documentation} - */ -interface OnTechnologyEffectsResetEvent { - readonly force: LuaForce - /** Identifier of the event */ - readonly name: typeof defines.events.on_technology_effects_reset - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * It is fired once every tick. Since this event is fired every tick, its handler shouldn't include performance heavy code. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_tick View documentation} - */ -interface OnTickEvent { - /** Identifier of the event */ - readonly name: typeof defines.events.on_tick - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a train changes state (started to stopped and vice versa) - * - * {@link https://lua-api.factorio.com/next/Events.html#on_train_changed_state View documentation} - */ -interface OnTrainChangedStateEvent { - readonly train: LuaTrain - readonly old_state: defines.train_state - /** Identifier of the event */ - readonly name: typeof defines.events.on_train_changed_state - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a new train is created either through disconnecting/connecting an existing one or building a new one. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_train_created View documentation} - */ -interface OnTrainCreatedEvent { - readonly train: LuaTrain - /** The first old train id when splitting/merging trains. */ - readonly old_train_id_1?: uint - /** The second old train id when splitting/merging trains. */ - readonly old_train_id_2?: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_train_created - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a trains schedule is changed either by the player or through script. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_train_schedule_changed View documentation} - */ -interface OnTrainScheduleChangedEvent { - readonly train: LuaTrain - /** The player who made the change if any. */ - readonly player_index?: uint - /** Identifier of the event */ - readonly name: typeof defines.events.on_train_schedule_changed - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when an entity with a trigger prototype (such as capsules) create an entity AND that trigger prototype defined - * `trigger_created_entity="true"`. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_trigger_created_entity View documentation} - */ -interface OnTriggerCreatedEntityEvent { - readonly entity: LuaEntity - readonly source?: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_trigger_created_entity - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when an entity with a trigger prototype (such as capsules) fire an artillery projectile AND that trigger - * prototype defined `trigger_fired_artillery="true"`. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_trigger_fired_artillery View documentation} - */ -interface OnTriggerFiredArtilleryEvent { - readonly entity: LuaEntity - readonly source?: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_trigger_fired_artillery - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a unit is added to a unit group. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_unit_added_to_group View documentation} - */ -interface OnUnitAddedToGroupEvent { - readonly unit: LuaEntity - readonly group: LuaUnitGroup - /** Identifier of the event */ - readonly name: typeof defines.events.on_unit_added_to_group - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a new unit group is created, before any members are added to it. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_unit_group_created View documentation} - */ -interface OnUnitGroupCreatedEvent { - readonly group: LuaUnitGroup - /** Identifier of the event */ - readonly name: typeof defines.events.on_unit_group_created - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a unit group finishes gathering and starts executing its command. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_unit_group_finished_gathering View documentation} - */ -interface OnUnitGroupFinishedGatheringEvent { - readonly group: LuaUnitGroup - /** Identifier of the event */ - readonly name: typeof defines.events.on_unit_group_finished_gathering - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a unit is removed from a unit group. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_unit_removed_from_group View documentation} - */ -interface OnUnitRemovedFromGroupEvent { - readonly unit: LuaEntity - readonly group: LuaUnitGroup - /** Identifier of the event */ - readonly name: typeof defines.events.on_unit_removed_from_group - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * Called when a worker (construction or logistic) robot expires through a lack of energy. - * - * {@link https://lua-api.factorio.com/next/Events.html#on_worker_robot_expired View documentation} - */ -interface OnWorkerRobotExpiredEvent { - readonly robot: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.on_worker_robot_expired - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * A static event mods can use to tell other mods they built something by script. This event is only raised if a mod - * does so with {@link LuaBootstrap.raise_event LuaBootstrap::raise_event} or - * {@link LuaBootstrap.raise_script_built LuaBootstrap::raise_script_built}, or when `raise_built` is passed to - * {@link LuaSurface.create_entity LuaSurface::create_entity}. Can be filtered using {@link LuaScriptRaisedBuiltEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#script_raised_built View documentation} - */ -interface ScriptRaisedBuiltEvent { - /** The entity that has been built. */ - readonly entity: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.script_raised_built - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * A static event mods can use to tell other mods they destroyed something by script. This event is only raised if a mod - * does so with {@link LuaBootstrap.raise_event LuaBootstrap::raise_event} or - * {@link LuaBootstrap.raise_script_destroy LuaBootstrap::raise_script_destroy}, or when `raise_destroy` is passed to - * {@link LuaEntity.destroy LuaEntity::destroy}. Can be filtered using {@link LuaScriptRaisedDestroyEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#script_raised_destroy View documentation} - */ -interface ScriptRaisedDestroyEvent { - /** The entity that was destroyed. */ - readonly entity: LuaEntity - /** Identifier of the event */ - readonly name: typeof defines.events.script_raised_destroy - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * A static event mods can use to tell other mods they revived something by script. This event is only raised if a mod - * does so with {@link LuaBootstrap.raise_event LuaBootstrap::raise_event} or - * {@link LuaBootstrap.raise_script_revive LuaBootstrap::raise_script_revive}, or when `raise_revive` is passed to - * {@link LuaEntity.revive LuaEntity::revive}. Can be filtered using {@link LuaScriptRaisedReviveEventFilter}. - * - * {@link https://lua-api.factorio.com/next/Events.html#script_raised_revive View documentation} - */ -interface ScriptRaisedReviveEvent { - /** The entity that was revived. */ - readonly entity: LuaEntity - /** The tags associated with this entity, if any. */ - readonly tags?: Tags - /** Identifier of the event */ - readonly name: typeof defines.events.script_raised_revive - /** Tick the event was generated. */ - readonly tick: uint -} - -/** - * A static event mods can use to tell other mods they changed tiles on a surface by script. This event is only raised - * if a mod does so with {@link LuaBootstrap.raise_event LuaBootstrap::raise_event} or - * {@link LuaBootstrap.raise_script_set_tiles LuaBootstrap::raise_script_set_tiles}, or when `raise_event` is passed to - * {@link LuaSurface.set_tiles LuaSurface::set_tiles}. - * - * {@link https://lua-api.factorio.com/next/Events.html#script_raised_set_tiles View documentation} - */ -interface ScriptRaisedSetTilesEvent { - /** The surface whose tiles were changed. */ - readonly surface_index: uint - /** The tiles that were changed. */ - readonly tiles: Tile[] - /** Identifier of the event */ - readonly name: typeof defines.events.script_raised_set_tiles - /** Tick the event was generated. */ - readonly tick: uint -} - -/** An event id. */ -type EventId = uint & { - readonly _eventData: T - readonly _filter: F -} - -/** - * An event id generated by {@link LuaBootstrap.generate_event_name LuaBootstrap::generate_event_name} and raisable via - * {@link LuaBootstrap.raise_event LuaBootstrap::raise_event}. - */ -type CustomEventId = EventId & { - _customEventIdBrand: any -} diff --git a/modules/mod2/typed-factorio/generated/global-objects.d.ts b/modules/mod2/typed-factorio/generated/global-objects.d.ts deleted file mode 100644 index f4c5a0f..0000000 --- a/modules/mod2/typed-factorio/generated/global-objects.d.ts +++ /dev/null @@ -1,51 +0,0 @@ -/** @noSelfInFile */ - -/** - * This is the main object, through which most of the API is accessed. It is, however, not available inside handlers - * registered with {@link LuaBootstrap.on_load LuaBootstrap::on_load}. - * - * {@link https://lua-api.factorio.com/next/ View documentation} - */ -declare const game: LuaGameScript - -/** - * Provides an interface for registering event handlers. - * - * {@link https://lua-api.factorio.com/next/ View documentation} - */ -declare const script: LuaBootstrap - -/** - * Allows inter-mod communication by way of providing a repository of interfaces that is shared by all mods. - * - * {@link https://lua-api.factorio.com/next/ View documentation} - */ -declare const remote: LuaRemote - -/** - * Allows registering custom commands for the in-game console accessible via the grave key. - * - * {@link https://lua-api.factorio.com/next/ View documentation} - */ -declare const commands: LuaCommandProcessor - -/** - * Allows reading the current mod settings. - * - * {@link https://lua-api.factorio.com/next/ View documentation} - */ -declare const settings: LuaSettings - -/** - * Allows printing messages to the calling RCON instance if any. - * - * {@link https://lua-api.factorio.com/next/ View documentation} - */ -declare const rcon: LuaRCON - -/** - * Allows rendering of geometric shapes, text and sprites in the game world. - * - * {@link https://lua-api.factorio.com/next/ View documentation} - */ -declare const rendering: LuaRendering diff --git a/modules/mod2/typed-factorio/generated/index.d.ts b/modules/mod2/typed-factorio/generated/index.d.ts deleted file mode 100644 index 4a7b7d8..0000000 --- a/modules/mod2/typed-factorio/generated/index.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -/// -/// -/// -/// -/// -/// -/// diff --git a/modules/mod2/typed-factorio/package.json b/modules/mod2/typed-factorio/package.json deleted file mode 100644 index 6a0eb5a..0000000 --- a/modules/mod2/typed-factorio/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "typed-factorio", - "version": "0.7.1", - "description": "Featureful typescript definitions for the the Factorio modding lua api.", - "keywords": [ - "factorio", - "types", - "typescript-to-lua", - "tstl" - ], - "repository": "https://github.com/GlassBricks/typed-factorio", - "license": "MIT", - "files": [ - "**/*.d.ts" - ], - "homepage": "https://github.com/GlassBricks/typed-factorio#readme", - "scripts": { - "generate": "cd ../generator && yarn run check && yarn run gen --in ../definitions/generatorSrc --out ../definitions/generated --warn-as-error", - "generate:dev": "cd ../generator && yarn run gen --in ../definitions/generatorSrc --out ../definitions/generated --no-format", - "clean": "rimraf ./generated", - "pretest": "yarn run generate", - "test": "jest", - "prepublishOnly": "yarn run test", - "download-latest-runtime-api": "ts-node ./scripts/downloadLatest.ts" - }, - "dependencies": { - "lua-types": "^2.10.1", - "typescript": "~4.3.5", - "typescript-to-lua": "^1.0.0" - }, - "devDependencies": { - "@types/jest": "^26.0.24", - "@types/node": "^16.4.13", - "jest": "^27.0.6", - "prettier": "^2.3.2", - "ts-jest": "^27.0.4", - "ts-node": "^10.1.0" - } -} diff --git a/modules/mod2/typed-factorio/runtime/index.d.ts b/modules/mod2/typed-factorio/runtime/index.d.ts deleted file mode 100644 index 43bdc07..0000000 --- a/modules/mod2/typed-factorio/runtime/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -/// - -/// - -/// -/// - -// lualib -/// -/// diff --git a/modules/mod2/typed-factorio/runtime/librariesAndFunctions.d.ts b/modules/mod2/typed-factorio/runtime/librariesAndFunctions.d.ts deleted file mode 100644 index 82a0f31..0000000 --- a/modules/mod2/typed-factorio/runtime/librariesAndFunctions.d.ts +++ /dev/null @@ -1,123 +0,0 @@ -// from https://lua-api.factorio.com/latest/Libraries.html -// last updated for 1.1.35, 1.1.36, 1.1.37 - -/** @noSelfInFile */ - -/** @noSelf */ -interface SerpentOptions { - /** Indentation; triggers long multi-line output. */ - indent: string - /** Provide stringified value in a comment (up to maxlevel of depth). */ - comment: boolean | number - /** Sort keys. */ - sortkeys: boolean | ((this: void, keys: any[], table: any) => void) - /** Force sparse encoding (no nil filling based on #t). */ - sparse: boolean - /** Remove spaces. */ - compact: boolean - /** Raise fatal error on non-serializable values. */ - fatal: boolean - /** Disable bytecode serialization for easy comparison. */ - nocode: boolean - /** Disable checking numbers against undefined and huge values. */ - nohuge: boolean - /** Specify max level up to which to expand nested tables. */ - maxlevel: number - /** Specify max number of elements in a table. */ - maxnum: number - /** Specify max length for all table elements. */ - maxlength: number - /** - * Use __tostring metamethod when serializing tables (v0.29); set to false to disable and serialize the table as is, - * even when __tostring is present. - */ - metatostring: boolean - /** - * Specify format for numeric values as shortest possible round-trippable double (v0.30). Use "%.16g" for better - * readability and "%.17g" (the default value) to preserve floating point precision. - */ - numformat: string - /** Allows to specify a list of values to ignore (as keys). */ - valignore: string[] - /** Allows to specify the list of keys to be serialized. Any keys not in this list are not included in final output (as keys). */ - keyallow: string[] - /** Allows to specity the list of keys to ignore in serialization. */ - keyignore: string[] - /** Allows to specify a list of value types to ignore (as keys). */ - valtypeignore: string[] - /** Provide custom output for tables. */ - custom(opts: { - /** The name of the current element with '=' or an empty string in case of array index, */ - tag: string - /** An opening table bracket { and associated indentation and newline (if any), */ - head: string - /** Table elements concatenated into a string using commas and indentation/newlines (if any), */ - body: string - /** A closing table bracket } and associated indentation and newline (if any), and */ - tail: string - /** The current level. */ - level: number - }): string - /** Name; triggers full serialization with self-ref section. */ - name: string - - refcomment: boolean | number - tablecomment: boolean | number -} - -/** - * Factorio provides the {@link https://github.com/pkulchenko/serpent serpent library} as a global variable `serpent` for - * all mods to use. It allows for easy debugging of tables, because serpent makes it trivial to print them, for example - * by using `serpent.block()`. However, serpent cannot pretty-print LuaObjects such as LuaEntity. The serpent library - * was modified to improve determinism, e.g. comments are turned off by default to avoid returning table addresses. - * Furthermore, two options were added: `refcomment` (true/false/maxlevel) and `tablecomment` (true/false/maxlevel), - * which allow to separately control the self-reference and table value output of the `comment` option. - */ -declare namespace serpent { - /** Full serialization; sets name, compact and sparse options; */ - function dump(tbl: unknown, options?: Partial): string - - /** Single line pretty printing, no self-ref section; sets sortkeys and comment options; */ - function line(tbl: unknown, options?: Partial): string - - /** Multi-line indented pretty printing, no self-ref section; sets indent, sortkeys, and comment options. */ - function block(tbl: unknown, options?: Partial): string - - /** - * For loading serialized fragments, serpent also provides `load` function that adds safety checks and reports an - * error if there is any executable code in the fragment. - */ - function load(str: string, options?: { safe?: boolean }): LuaMultiReturn<[true, T] | [false, string]> -} - -/** - * This function allows to log {@link LocalisedString} to the Factorio - * {@link https://wiki.factorio.com/Log_file log file}. This, in combination with serpent, makes debugging in the data - * stage easier, because it allows to simply inspect entire prototype tables. For example, this allows to see all - * properties of the sulfur item prototype: `log(serpent.block(data.raw["item"]["sulfur"]))` - */ -declare function log(ls: LocalisedString): void - -/** - * This function allows printing {@link LocalisedString}s to stdout without polluting the logfile. This is primarily - * useful for communicating with external tools that launch Factorio as a child process. - */ -declare function localised_print(ls: LocalisedString): void - -/** - * Factorio provides the function `table_size()` as a simple way to find the size of tables with non-continuous keys, - * because the standard `#` does not work correctly for these. The function is a C++-side implementation of the - * following Lua code, thus it is faster than using this code in Lua: - * - * local function size(t) - * local count = 0 - * for k,v in pairs(t) do - * count = count + 1 - * end - * return count - * end - * - * Note that `table_size()` does not work correctly for {@link LuaCustomTable}s, their size has to be determined with - * {@link LuaCustomTable.length LuaCustomTable::operator #} instead. - */ -declare function table_size(tbl: table): number diff --git a/modules/mod2/typed-factorio/runtime/mod-gui.d.ts b/modules/mod2/typed-factorio/runtime/mod-gui.d.ts deleted file mode 100644 index 761a98f..0000000 --- a/modules/mod2/typed-factorio/runtime/mod-gui.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** @noSelfInFile */ - -/** @noResolution */ -declare module "mod-gui" { - const button_style: string - const frame_style: string - - function get_button_flow(player: LuaPlayer): FrameGuiElement - - function get_frame_flow(player: LuaPlayer): FlowGuiElement -} diff --git a/modules/mod2/typed-factorio/runtime/pairs.d.ts b/modules/mod2/typed-factorio/runtime/pairs.d.ts deleted file mode 100644 index 2ec352f..0000000 --- a/modules/mod2/typed-factorio/runtime/pairs.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** @noSelfInFile */ - -/** Iterating with `pairs` will only iterate the array part of a {@link LuaCustomTable}. */ -declare function pairs(table: LuaCustomTable): LuaIterable> - -declare function pairs(table: LuaCustomTable): LuaIterable> - -/** - * {@link LuaCustomTable} cannot be iterated with `ipairs`. Use `pairs` instead. - * - * @deprecated - */ -declare function ipairs(table: LuaCustomTable): never diff --git a/modules/mod2/typed-factorio/runtime/util.d.ts b/modules/mod2/typed-factorio/runtime/util.d.ts deleted file mode 100644 index 08ed5e0..0000000 --- a/modules/mod2/typed-factorio/runtime/util.d.ts +++ /dev/null @@ -1,120 +0,0 @@ -// "util" is declared only as a module, even though it also modifies global variables -// This is both because of limitations in `declare module`, and that modules are much friendlier to tooling. - -/** @noSelfInFile */ - -/** @noResolution */ -declare module "util" { - namespace table { - function deepcopy(table: T): T - - function compare(tb1: T, tb2: T): boolean - } - - function copy(table: T): T - - function distance(position1: Position, position2: Position): number - - function positiontostr(position: Position): string - - function formattime(ticks: number): string - - /** Supports 'rrggbb', 'rgb', 'rrggbbaa', 'rgba', 'ww', 'w' */ - function color(hex: string): ColorTable - - function premul_color(color: Color): ColorTable - - function mix_color(c1: Color, c2: Color): ColorArray - - function multiply_color(c1: Color, n: number): ColorArray - - function moveposition( - position: Position, - direction: defines.direction.north | defines.direction.east | defines.direction.south | defines.direction.west, - distance: number - ): Position - function moveposition( - position: Position, - direction: defines.direction, //todo: cardinal only - distance: number - ): Position | undefined - - function oppositedirection(direction: defines.direction): defines.direction - - /** Creates a new array where each element in `stripes` is duplicated `count` times */ - function multiplystripes(count: number, stripes: T[]): T[] - - /** Gets tile position by pixel */ - function by_pixel(x: number, y: number): Position - - /** Gets tile position by pixel, hr */ - function by_pixel_hr(x: number, y: number): Position - - // omitted: foreach_sprite_definition - - function add_shift(a: PositionArray | undefined, b: PositionArray): PositionArray - function add_shift(a: PositionArray, b: PositionArray | undefined): PositionArray - function add_shift(a: PositionArray | undefined, b: PositionArray | undefined): PositionArray | undefined - - // omitted: add_shift_offset - - function mul_shift(shift: PositionArray, scale: number | undefined): PositionArray - function mul_shift(shift: PositionArray | undefined, scale: number | undefined): PositionArray | undefined - - function format_number(amount: number, append_suffix?: boolean): string - - function increment(t: number[], index: number, v?: number): void - - // omitted: conditional_return - - /** - * Recursively merges and/or deep-copies tables. Entries in later tables override entries in earlier ones, unless both - * entries are themselves tables, in which case they are recursively merged. Non-merged tables are deep-copied, so - * that the result is brand new. - */ - function merge(tables: T[]): T - - function insert_safe(entity: LuaEntity | undefined, item_dict: Record | undefined): void - - function remove_safe(entity: LuaEntity | undefined, item_dict: Record | undefined): void - - function split_whitespace(string: string): string[] - - // omitted: split, string_starts_with. already TS functions for that - - // omitted: online_players. use game.connected_players - - function clamp(x: number, lower: number, upper: number): number - - // omitted: get_walkable_tile - - // omitted: combine_icons - // omitted: technology_icons. Create an issue if you really want to see these - - function parse_energy(energy: string): number - - function product_amount( - product: { - probability: number - } & ( - | { - amount: number - } - | { - amount_min: number - amount_max: number - } - ) - ): number - - function empty_sprite(): object - - // omitted: draw_as_glow - // omitted: remove_tile_references - - function remove_from_list(list: T[], value: T): boolean - - function list_to_map(list: T[]): Record - function list_to_map(list: T[]): LuaTable - function list_to_map(list: T): LuaTable -} diff --git a/modules/mod2/typed-factorio/settings/types.d.ts b/modules/mod2/typed-factorio/settings/types.d.ts deleted file mode 100644 index d11dae2..0000000 --- a/modules/mod2/typed-factorio/settings/types.d.ts +++ /dev/null @@ -1,120 +0,0 @@ -// Based off of https://wiki.factorio.com/Tutorial:Mod_settings - -export type SettingType = "bool-setting" | "int-setting" | "double-setting" | "string-setting" - -export interface BaseSettingDefinition { - type: SettingType - /** - * The name of the settings prototype should be unique to avoid mod conflicts since the mod settings are global across - * all mods. Because of that it is recommended to prefix mod settings with your mod name, - */ - name: string - localized_name?: LocalisedString - localized_description?: LocalisedString - - /** - * The order property can be used to change how the mod settings are ordered in the settings gui. Mod settings are sorted - * - * - First by mod - * - Then by the setting "order" string - * - Then finally by the setting name. - */ - order?: string - /** - * The hidden property can be used to hide mod settings from GUIs, so that they cannot be seen or changed by players. - * However, other mods can still access hidden settings. {@link https://forums.factorio.com/83316} - */ - hidden?: boolean - /** - * There are the overall kinds of settings: - * - * - **startup**: This kind of setting is available in the prototype stage, and can not be changed runtime. They have to - * be set to the same values for all players on a server. - * - **runtime-global**: This kind of setting is global to an entire save game and can be changed runtime. On servers, - * only admins can change these settings. - * - **runtime-per-user**: This kind of setting is only available runtime in the control.lua stage and each player has - * their own instance of this setting. When a player joins a server their local setting of "keep mod settings per - * save" determines if the local settings they have set are synced to the loaded save or if the save's settings are used. - * - * This "setting_type" also determines in which tab the setting is showed in the mod settings menu. - */ - - setting_type: "startup" | "runtime-global" | "runtime-per-user" -} -/** A true/false checkbox */ -export interface BoolSettingDefinition extends BaseSettingDefinition { - type: "bool-setting" - /** Defines the default value of the setting, in this case whether the checkbox is checked or not. */ - default_value: boolean - /** - * Only loaded if `hidden = true`. This forces the setting to be of this value. This can be useful for mod - * compatibility. {@link https://forums.factorio.com/viewtopic.php?p=531322#p531322} - */ - forced_value?: boolean -} -/** A signed 64 bit integer textfield (or selection dropdown) */ -export interface IntSettingDefinition extends BaseSettingDefinition { - type: "int-setting" - /** Defines the default value of the setting. */ - default_value: number - /** Defines the lowest possible number. */ - minimum_value?: number - /** Defines the highest possible number. */ - maximum_value?: number - /** - * Makes it possible to force the player to choose between the defined numbers, creates a dropdown instead of a - * textfield. If only one allowed value is given, the settings is forced to be of that value. - */ - allowed_values?: number[] -} -/** A double precision floating point textfield (or selection dropdown) */ -export interface DoubleSettingDefinition extends BaseSettingDefinition { - type: "double-setting" - /** Defines the default value of the setting. */ - default_value: number - /** Defines the lowest possible number. */ - minimum_value?: number - /** Defines the highest possible number. */ - maximum_value?: number - /** - * Makes it possible to force the player to choose between the defined numbers, creates a dropdown instead of a - * textfield. If only one allowed value is given, the settings is forced to be of that value. - */ - allowed_values?: number[] -} -/** A string textfield (or selection dropdown) */ -export interface StringSettingDefinition extends BaseSettingDefinition { - type: "string-setting" - /** Defines the default value of the setting. */ - default_value: string - /** Defines whether it's possible for the user to set the textfield to empty and apply the setting. */ - allow_blank?: boolean - /** Whether values that are input by the user should have whitespace removed from both ends of the string. */ - auto_trim?: boolean - /** - * Makes it possible to force the player to choose between the defined strings, creates a dropdown instead of a - * textfield. The strings in the dropdown can be localized (translated) and can have a tooltip, see below. If only one - * allowed value is given, the settings is forced to be of that value. - */ - allowed_values?: string[] -} -/** Setting definitions. See {@link https://wiki.factorio.com/Tutorial:Mod_settings} for more info. */ -export type SettingDefinition = - | BoolSettingDefinition - | IntSettingDefinition - | DoubleSettingDefinition - | StringSettingDefinition - -export interface Data { - readonly raw: { - [T in SettingDefinition["type"]]: Record> - } - /** - * The `data` table expects a specific format for each item in the table. Missing properties will either fall back to - * default values or give an error indicating what's missing. Extra properties that the game isn't looking for are - * simply ignored. - */ - extend(prototypes: SettingDefinition[]): void -} -/** A mapping of mod names to mod version for all enabled mods. */ -export type Mods = Record diff --git a/modules/protoc-gradle-plugin/build.gradle.kts b/modules/protoc-gradle-plugin/build.gradle.kts deleted file mode 100644 index 47892e9..0000000 --- a/modules/protoc-gradle-plugin/build.gradle.kts +++ /dev/null @@ -1,77 +0,0 @@ -plugins { - kotlin("jvm") version "1.5.31" - `kotlin-dsl` - `java-gradle-plugin` - `maven-publish` -} - -gradlePlugin { - plugins { - create("ProtobufAndGradle") { - id = "dev.adamko.pb-and-g" - implementationClass = "dev.adamko.gradle.pbandg.ProtocPluginKt" - description = - "Protobuf & Gradle. Wrapper for protoc to generate code from Proto Buffer files." - } - } -} - -group = "dev.adamko.gradle.pbandg" -version = "0.0.1-SNAPSHOT" - - -val protocConfiguration: Configuration by configurations.creating { - // A configuration meant for consumers that need the implementation of this component - isCanBeResolved = true - isCanBeConsumed = false -} - -val protobufVersion = "3.19.1" -val protocVersion = "3.9.2" - -dependencies { - implementation(platform("org.jetbrains.kotlin:kotlin-bom")) - implementation(kotlin("stdlib")) - - implementation(platform("com.google.protobuf:protobuf-bom:$protobufVersion")) - - implementation("com.google.protobuf:protobuf-java:$protobufVersion") - implementation("com.google.protobuf:protobuf-javalite:$protobufVersion") - implementation("com.google.protobuf:protobuf-kotlin-lite:$protobufVersion") - implementation("com.google.protobuf:protobuf-kotlin:$protobufVersion") - implementation("com.google.protobuf:protoc:$protobufVersion") - - implementation(platform("io.grpc:grpc-bom:1.41.0")) - implementation("io.grpc:grpc-stub:1.41.0") - implementation("io.grpc:grpc-protobuf:1.41.0") - - implementation("io.grpc:grpc-kotlin-stub:1.2.0") - implementation("io.grpc:protoc-gen-grpc-kotlin:1.2.0") - - implementation("javax.annotation:javax.annotation-api:1.3.2") - - implementation( - group = "com.google.protobuf", - name = "protoc", - version = "3.9.2", -// configuration = "", - classifier = "windows-x86_64", - ext = "exe", - ) - - protocConfiguration( - group = "com.google.protobuf", - name = "protoc", - version = protocVersion, -// configuration = "", - classifier = "windows-x86_64", - ext = "exe", - ) - - -} - -repositories { - mavenCentral() -} - diff --git a/modules/protoc-gradle-plugin/src/main/kotlin/dev/adamko/gradle/pbandg/ProtocPlugin.kt b/modules/protoc-gradle-plugin/src/main/kotlin/dev/adamko/gradle/pbandg/ProtocPlugin.kt deleted file mode 100644 index 70080a8..0000000 --- a/modules/protoc-gradle-plugin/src/main/kotlin/dev/adamko/gradle/pbandg/ProtocPlugin.kt +++ /dev/null @@ -1,294 +0,0 @@ -package dev.adamko.gradle.pbandg - -import java.io.File -import java.util.function.Supplier -import org.gradle.api.DefaultTask -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.api.artifacts.Configuration -import org.gradle.api.artifacts.ExternalDependency -import org.gradle.api.artifacts.ExternalModuleDependency -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.plugins.ExtensionAware -import org.gradle.api.provider.Property -import org.gradle.api.provider.Provider -import org.gradle.api.tasks.Exec -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.Sync -import org.gradle.api.tasks.TaskAction -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.domainObjectContainer -import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.defaultDependencies -import org.gradle.kotlin.dsl.dependencies -import org.gradle.kotlin.dsl.findByType -import org.gradle.kotlin.dsl.getByType -import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.getValue -import org.gradle.kotlin.dsl.withType -import org.gradle.kotlin.dsl.property -import org.gradle.kotlin.dsl.provideDelegate -import org.gradle.kotlin.dsl.register -import org.gradle.nativeplatform.platform.Architecture -import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform -import org.gradle.nativeplatform.platform.internal.DefaultOperatingSystem -import org.gradle.plugins.ide.idea.GenerateIdeaModule -import org.gradle.plugins.ide.idea.IdeaPlugin -import org.gradle.plugins.ide.idea.model.IdeaModel -import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs - - -open class ProtocPlugin : Plugin { - - override fun apply(project: Project) { - - configureIntelliJ(project) - - val protocConfig = - project.extensions.create("protocPluginConfig", ProtocPluginConfig::class, project) - - val protobufCompiler: Configuration = project.configurations.create("protobufCompiler") { - isVisible = false - isCanBeConsumed = false - isCanBeResolved = true - isTransitive = false - - defaultDependencies { - add(protocConfig.dependency.get()) - } - } - - val protobufLib: Configuration = project.configurations.create("protobufLib") { - isVisible = true - isCanBeConsumed = false - isCanBeResolved = true - isTransitive = false - } - - project.dependencies { - protobufLib("com.google.protobuf:protobuf-javalite:3.19.1") -// implementation("com.google.protobuf:protobuf-javalite:3.19.1") -// implementation("com.google.protobuf:protobuf-kotlin-lite:3.19.1") - } - - /** Download protobuf libs */ - val protoLibsTask = project.tasks.register("protobufLibs") { - group = "protobuf" - description = "Download and extract protobuf libs" - includeEmptyDirs = false - dependsOn(protobufLib) - - val protoLibDir by project.objects.directoryProperty() - .convention(project.layout.buildDirectory.dir("protobuf/libs")) - into(protoLibDir) - - protobufLib - .map { project.zipTree(it) } - .forEach { - logger.lifecycle("protoc lib - $it") - from(it) { - include("**/*.proto") - } - } - } - - // TODO investigate builtBy and sourceDirectorySet? -// project.objects.fileCollection().builtBy() -// val pbSrcSet = project.objects.sourceDirectorySet("protobuf", "protobuf") - - - /** Convert `.proto` files to Kotlin */ - val pbCompileTask = project.tasks.register("protobufCompile") { - group = "protobuf" - dependsOn(protobufCompiler, protoLibsTask) - - standardOutput = System.out - - executable(protobufCompiler.singleFile) - workingDir(temporaryDirFactory) - - val outDir = project.layout.buildDirectory.dir("protobuf/generated-sources") - outputs.dir(outDir) - - val protoLibsDir: Provider = protoLibsTask.map { it.destinationDir } - - val javaOut = workingDir.resolve("java") - val kotlinOut = workingDir.resolve("kotlin") - val protoFile by project.objects.fileProperty() - .convention(project.layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto")) - - val protoFileParent = project.provider { protoFile.asFile.parentFile } - - val isLiteEnabled: Boolean by project.objects.property().convention(true) - - doFirst { - project.delete(workingDir) - - project.mkdir(outDir) - project.mkdir(javaOut) - project.mkdir(kotlinOut) - - val liteOpt: String = when (isLiteEnabled) { - true -> "lite:" - false -> "" - } - - args( - parseSpaceSeparatedArgs( - """ - --proto_path=${protoLibsDir.get()} - --proto_path=${protoFileParent.get()} - --java_out=$liteOpt$javaOut - --kotlin_out=$liteOpt$kotlinOut - $protoFile - """ - ) - ) - } - - doLast { - project.sync { - from(workingDir) - into(outDir) - } - project.delete(workingDir) - } - } - - project.tasks.assemble { dependsOn(pbCompileTask) } - - } - - /** - * IntelliJ requires source dirs are configured first. - * - * https://github.com/google/protobuf-gradle-plugin/blob/master/src/main/groovy/com/google/protobuf/gradle/Utils.groovy#L128 - */ - private fun configureIntelliJ(project: Project) { - - val genSrcDir = project.layout.buildDirectory.dir("protobuf/generated-sources") - val ktGenSrc = genSrcDir.map { it.dir("kotlin") } - val jGenSrc = genSrcDir.map { it.dir("java") } - - project.mkdir(ktGenSrc) - - project.extensions.findByType()?.apply { - project.logger.lifecycle("-------\nadding generated sources $ktGenSrc\n-------") - - project.sourceSets.named("main") { - this.java.srcDir(ktGenSrc) - this.java.srcDir(jGenSrc) - } - -// sourceSets.main.get().kotlin.srcDir(ktGenSrc) - -// sourceSets.main.configure { -// this.kotlin.srcDir(ktGenSrc) -// } - } - - project.plugins.withType { - project.extensions.configure { - this.module.generatedSourceDirs.add(ktGenSrc.get().asFile) - this.module.generatedSourceDirs.add(jGenSrc.get().asFile) - } - } - - project.tasks.withType { - doFirst { - project.mkdir(ktGenSrc) - } - } - } -} - -abstract class ProtocPluginConfig(private val project: Project) { - - val protocWorkingDir: DirectoryProperty = - project.objects.directoryProperty() - .convention(project.rootProject.layout.projectDirectory.dir(".gradle/protoc")) - - val protocVersion: Property = - project.objects.property(String::class).convention("3.19.1") - - val protocGroup: Property = - project.objects.property(String::class).convention("com.google.protobuf") - - val protocArtifactName: Property = - project.objects.property(String::class).convention("protoc") - - val protocArtifactExtension: Property = - project.objects.property(String::class).convention("exe") - - val operatingSystemProvider: Property> = - project.objects.property>() - .convention { DefaultNativePlatform.getCurrentOperatingSystem() } - - /** - * Should return one of - * - * * `linux` - * * `osx` - * * `windows` - */ - val operatingSystemName: Property = - project.objects - .property() - .convention(operatingSystemProvider.map { it.get().toFamilyName() }) - - private val architectureProvider: Provider = - project.provider { DefaultNativePlatform.getCurrentArchitecture() } - - /** - * Should return one of - * - * * `aarch_64` - * * `ppcle_64` - * * `x86_32` - * * `x86_64` - */ - val architectureName: Property = - project.objects - .property() - .convention(architectureProvider.map { it.name.replace("-", "_") }) - - private val classifierProvider: Provider = - project.provider { "${operatingSystemName.get()}-${architectureName.get()}" } - - /** - * Default: concatenate [osFamilyNameProvider] and [architectureProvider] - * - * Should return one of: - * - * * `linux-aarch_64` - * * `linux-ppcle_64` - * * `linux-x86_64` - * * `osx-x86_32` - * * `osx-x86_64` - * * `windows-x86_32` - */ - val classifier: Property = - project.objects - .property() - .convention(classifierProvider) - - - private val dependencyProvider: Provider = - project.provider { - project.dependencies.create( - group = protocGroup.get(), - name = protocArtifactName.get(), - version = protocVersion.get(), - classifier = classifierProvider.get(), - ext = protocArtifactExtension.get(), - ) - } - - val dependency: Property = - project.objects - .property() - .convention(dependencyProvider) - -} diff --git a/modules/server/build.gradle.kts b/modules/server/build.gradle.kts deleted file mode 100644 index f5bde61..0000000 --- a/modules/server/build.gradle.kts +++ /dev/null @@ -1,60 +0,0 @@ -import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig - -plugins { - id("dev.adamko.factoriowebmap.archetype.base") -// kotlin("jvm") - id("io.kvision") version "5.4.1" - kotlin("js") - kotlin("plugin.serialization") -} - -group = "${rootProject.group}.server" -version = rootProject.version - - -val webDir = file("src/main/web") - - -val kvisionVersion = "5.4.1" - -kotlin { - js { - browser { - runTask { - outputFileName = "main.bundle.js" - sourceMaps = false - devServer = KotlinWebpackConfig.DevServer( - open = false, - port = 3000, - proxy = mutableMapOf( - "/kv/*" to "http://localhost:8080", - "/kvws/*" to mapOf("target" to "ws://localhost:8080", "ws" to true) - ), - static = mutableListOf("$buildDir/processedResources/js/main") - ) - } - webpackTask { - outputFileName = "main.bundle.js" - } - testTask { - useKarma { - useChromeHeadless() - } - } - } - binaries.executable() - } - - sourceSets["main"].dependencies { - implementation("io.kvision:kvision:$kvisionVersion") - implementation("io.kvision:kvision-bootstrap:$kvisionVersion") - implementation("io.kvision:kvision-bootstrap-css:$kvisionVersion") - implementation("io.kvision:kvision-i18n:$kvisionVersion") - } - sourceSets["test"].dependencies { - implementation(kotlin("test-js")) - implementation("io.kvision:kvision-testutils:$kvisionVersion") - } - sourceSets["main"].resources.srcDir(webDir) - -} diff --git a/modules/server/src/main/kotlin/com/example/App.kt b/modules/server/src/main/kotlin/com/example/App.kt deleted file mode 100644 index a7c20c1..0000000 --- a/modules/server/src/main/kotlin/com/example/App.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.example - -import io.kvision.Application -import io.kvision.BootstrapCssModule -import io.kvision.BootstrapModule -import io.kvision.CoreModule -import io.kvision.html.div -import io.kvision.i18n.DefaultI18nManager -import io.kvision.i18n.I18n -import io.kvision.i18n.I18n.tr -import io.kvision.module -import io.kvision.panel.root -import io.kvision.require -import io.kvision.startApplication - -class App : Application() { - init { - require("./css/kvapp.css") - } - - override fun start() { - I18n.manager = - DefaultI18nManager( - mapOf( - "pl" to require("./i18n/messages-pl.json"), - "en" to require("./i18n/messages-en.json") - ) - ) - - root("kvapp") { - div(tr("This is a localized message.")) - } - } -} - -fun main() { - startApplication(::App, module.hot, BootstrapModule, BootstrapCssModule, CoreModule) -} diff --git a/modules/server/src/main/resources/css/kvapp.css b/modules/server/src/main/resources/css/kvapp.css deleted file mode 100644 index e69de29..0000000 diff --git a/modules/server/src/main/resources/i18n/messages-en.po b/modules/server/src/main/resources/i18n/messages-en.po deleted file mode 100644 index 520a528..0000000 --- a/modules/server/src/main/resources/i18n/messages-en.po +++ /dev/null @@ -1,23 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the KVision package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: KVision\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-08-18 01:34+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: English\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" - -#: ../src/main/kotlin/com/example/App.kt:20 -msgid "This is a localized message." -msgstr "" diff --git a/modules/server/src/main/resources/i18n/messages-pl.po b/modules/server/src/main/resources/i18n/messages-pl.po deleted file mode 100644 index 2431017..0000000 --- a/modules/server/src/main/resources/i18n/messages-pl.po +++ /dev/null @@ -1,23 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the KVision package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: KVision\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-08-18 01:34+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: Polish\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" - -#: ../src/main/kotlin/com/example/App.kt:20 -msgid "This is a localized message." -msgstr "To jest przetłumaczona wiadomość." diff --git a/modules/server/src/main/resources/i18n/messages.pot b/modules/server/src/main/resources/i18n/messages.pot deleted file mode 100644 index 68feb5b..0000000 --- a/modules/server/src/main/resources/i18n/messages.pot +++ /dev/null @@ -1,8 +0,0 @@ -msgid "" -msgstr "" -"Content-Type: text/plain; charset=UTF-8\n" -"Language: \n" - -#: src/main/kotlin/com/example/App.kt:31 -msgid "This is a localized message." -msgstr "" diff --git a/modules/server/src/main/web/index.html b/modules/server/src/main/web/index.html deleted file mode 100644 index b723f01..0000000 --- a/modules/server/src/main/web/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - KVision App - - - -

): T + fun defineProperties(o: T, properties: dynamic): T + fun seal(o: T): T + fun freeze(o: T): R + fun preventExtensions(o: T): T + fun isSealed(o: Any): Boolean + fun isFrozen(o: Any): Boolean + fun isExtensible(o: Any): Boolean + fun keys(o: Any): Array + fun assign(dest: R, vararg src: T?): R + } +} diff --git a/modules/mod2/dukat-custom/classes.module_typed-factorio.kt b/modules/mod2/dukat-custom/classes.module_typed-factorio.kt index 1f051a8..7b92c6a 100644 --- a/modules/mod2/dukat-custom/classes.module_typed-factorio.kt +++ b/modules/mod2/dukat-custom/classes.module_typed-factorio.kt @@ -52,18 +52,18 @@ import defines.control_behavior.transport_belt.content_read_mode import defines.group_state external interface LuaAISettings { - var allow_destroy_when_commands_fail: Boolean - var allow_try_return_to_spawner: Boolean - var do_separation: Boolean + var allow_destroy_when_commands_fail: Boolean? + var allow_try_return_to_spawner: Boolean? + var do_separation: Boolean? var path_resolution_modifier: int8 - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaAISettings" */ fun help(): String } external interface LuaAccumulatorControlBehavior : LuaControlBehavior { var output_signal: SignalID - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaAccumulatorControlBehavior" */ fun help(): String } @@ -77,9 +77,9 @@ external interface LuaAchievementPrototype { var localised_description: dynamic /* JsTuple | String | Number */ get() = definedExternally set(value) = definedExternally - var allowed_without_fight: Boolean - var hidden: Boolean - var valid: Boolean + var allowed_without_fight: Boolean? + var hidden: Boolean? + var valid: Boolean? var object_name: String /* "LuaAchievementPrototype" */ fun help(): String } @@ -94,14 +94,14 @@ external interface LuaAmmoCategoryPrototype { get() = definedExternally set(value) = definedExternally var bonus_gui_order: String - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaAmmoCategoryPrototype" */ fun help(): String } external interface LuaArithmeticCombinatorControlBehavior : LuaCombinatorControlBehavior { var parameters: ArithmeticCombinatorParameters - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaArithmeticCombinatorControlBehavior" */ fun help(): String } @@ -115,10 +115,10 @@ external interface LuaAutoplaceControlPrototype { var localised_description: dynamic /* JsTuple | String | Number */ get() = definedExternally set(value) = definedExternally - var richness: Boolean + var richness: Boolean? var control_order: String var category: String - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaAutoplaceControlPrototype" */ fun help(): String } @@ -137,7 +137,7 @@ external interface `T$1` { external interface `T$2` { var player_index: uint var entity: LuaEntity - var from_player: Boolean + var from_player: Boolean? } external interface `T$3` { @@ -223,7 +223,7 @@ external interface LuaBurner { var remaining_burning_fuel: double var currently_burning: LuaItemPrototype var fuel_categories: Record - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaBurner" */ fun help(): String } @@ -243,23 +243,29 @@ external interface `T$8` { external interface LuaBurnerPrototype { var emissions: double - var render_no_network_icon: Boolean - var render_no_power_icon: Boolean + var render_no_network_icon: Boolean? + var render_no_power_icon: Boolean? var effectivity: double var fuel_inventory_size: uint var burnt_inventory_size: uint var smoke: Array var light_flicker: `T$8` var fuel_categories: Record - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaBurnerPrototype" */ fun help(): String } -external interface LuaChunkIterator : LuaIterable { +external interface LuaIterable : + tsstdlib.Iterable, + LuaIterator +// , +// LuaExtension + +external interface LuaChunkIterator : LuaIterable { @nativeInvoke operator fun invoke(): ChunkPositionAndArea? - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaChunkIterator" */ fun help(): String } @@ -272,7 +278,7 @@ external interface LuaCircuitNetwork { var signals: Array? var network_id: uint var connected_circuit_count: uint - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaCircuitNetwork" */ fun help(): String } @@ -286,7 +292,7 @@ external interface LuaCommandProcessor { fun add_command(name: String, help: Any /* JsTuple */, _function: (param1: CustomCommandData) -> Unit) fun add_command(name: String, help: String, _function: (param1: CustomCommandData) -> Unit) fun add_command(name: String, help: Number, _function: (param1: CustomCommandData) -> Unit) - fun remove_command(name: String): Boolean + fun remove_command(name: String): Boolean? var commands: Record | String | Number */> var game_commands: Record | String | Number */> var object_name: String /* "LuaCommandProcessor" */ @@ -296,15 +302,15 @@ external interface LuaConstantCombinatorControlBehavior : LuaControlBehavior { fun set_signal(index: uint, signal: Signal) fun get_signal(index: uint): Signal var parameters: Array - var enabled: Boolean + var enabled: Boolean? var signals_count: uint - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaConstantCombinatorControlBehavior" */ fun help(): String } external interface LuaContainerControlBehavior : LuaControlBehavior { - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaContainerControlBehavior" */ fun help(): String } @@ -355,12 +361,12 @@ external interface `T$10` { } external interface `T$11` { - var walking: Boolean + var walking: Boolean? var direction: direction } external interface `T$12` { - var mining: Boolean + var mining: Boolean? var position: Position? get() = definedExternally set(value) = definedExternally @@ -372,16 +378,16 @@ external interface `T$13` { } external interface `T$14` { - var repairing: Boolean + var repairing: Boolean? var position: Position } external interface LuaControl { fun get_inventory(inventory: inventory): LuaInventory? fun get_main_inventory(): LuaInventory? - fun can_insert(items: String): Boolean - fun can_insert(items: ItemStackDefinition): Boolean - fun can_insert(items: LuaItemStack): Boolean + fun can_insert(items: String): Boolean? + fun can_insert(items: ItemStackDefinition): Boolean? + fun can_insert(items: LuaItemStack): Boolean? fun insert(items: String): uint fun insert(items: ItemStackDefinition): uint fun insert(items: LuaItemStack): uint @@ -392,16 +398,16 @@ external interface LuaControl { fun set_gui_arrow(params: OtherControlSetGuiArrow) fun clear_gui_arrow() fun get_item_count(item: String = definedExternally): uint - fun has_items_inside(): Boolean - fun can_reach_entity(entity: LuaEntity): Boolean + fun has_items_inside(): Boolean? + fun can_reach_entity(entity: LuaEntity): Boolean? fun clear_items_inside() fun remove_item(items: String): uint fun remove_item(items: ItemStackDefinition): uint fun remove_item(items: LuaItemStack): uint - fun teleport(position: Position, surface: uint = definedExternally): Boolean - fun teleport(position: Position): Boolean - fun teleport(position: Position, surface: String = definedExternally): Boolean - fun teleport(position: Position, surface: LuaSurface = definedExternally): Boolean + fun teleport(position: Position, surface: uint = definedExternally): Boolean? + fun teleport(position: Position): Boolean? + fun teleport(position: Position, surface: String = definedExternally): Boolean? + fun teleport(position: Position, surface: LuaSurface = definedExternally): Boolean? fun update_selected_entity(position: Position) fun clear_selected_entity() fun disable_flashlight() @@ -411,22 +417,22 @@ external interface LuaControl { fun get_craftable_count(recipe: LuaRecipe): uint fun begin_crafting(params: `T$9`): uint fun cancel_crafting(params: `T$10`) - fun mine_entity(entity: LuaEntity, force: Boolean = definedExternally): Boolean - fun mine_tile(tile: LuaTile): Boolean - fun is_player(): Boolean + fun mine_entity(entity: LuaEntity, force: Boolean = definedExternally): Boolean? + fun mine_tile(tile: LuaTile): Boolean? + fun is_player(): Boolean? fun open_technology_gui(technology: String = definedExternally) fun open_technology_gui() fun open_technology_gui(technology: LuaTechnology = definedExternally) fun open_technology_gui(technology: LuaTechnologyPrototype = definedExternally) - fun set_personal_logistic_slot(slot_index: uint, value: PersonalLogisticParameters): Boolean - fun set_vehicle_logistic_slot(slot_index: uint, value: PersonalLogisticParameters): Boolean + fun set_personal_logistic_slot(slot_index: uint, value: PersonalLogisticParameters): Boolean? + fun set_vehicle_logistic_slot(slot_index: uint, value: PersonalLogisticParameters): Boolean? fun get_personal_logistic_slot(slot_index: uint): PersonalLogisticParameters fun get_vehicle_logistic_slot(slot_index: uint): PersonalLogisticParameters fun clear_personal_logistic_slot(slot_index: uint) fun clear_vehicle_logistic_slot(slot_index: uint) - fun is_cursor_blueprint(): Boolean + fun is_cursor_blueprint(): Boolean? fun get_blueprint_entities(): Array? - fun is_cursor_empty(): Boolean + fun is_cursor_empty(): Boolean? var surface: LuaSurface var position: PositionTable var vehicle: LuaEntity? @@ -443,16 +449,16 @@ external interface LuaControl { var riding_state: RidingState var mining_state: `T$12` var shooting_state: `T$13` - var picking_state: Boolean + var picking_state: Boolean? var repair_state: `T$14` var cursor_stack: LuaItemStack? var cursor_ghost: dynamic /* LuaItemStack | LuaItemPrototype | String */ get() = definedExternally set(value) = definedExternally - var driving: Boolean + var driving: Boolean? var crafting_queue: Array var following_robots: Array - var cheat_mode: Boolean + var cheat_mode: Boolean? var character_crafting_speed_modifier: double var character_mining_speed_modifier: double var character_additional_mining_categories: Array @@ -467,8 +473,8 @@ external interface LuaControl { var character_trash_slot_count_bonus: uint var character_maximum_following_robot_count_bonus: uint var character_health_bonus: float - var character_personal_logistic_requests_enabled: Boolean - var vehicle_logistic_requests_enabled: Boolean + var character_personal_logistic_requests_enabled: Boolean? + var vehicle_logistic_requests_enabled: Boolean? var opened_gui_type: gui_type? var build_distance: uint var drop_item_distance: uint @@ -476,7 +482,7 @@ external interface LuaControl { var item_pickup_distance: double var loot_pickup_distance: double var resource_reach_distance: double - var in_combat: Boolean + var in_combat: Boolean? var character_running_speed: double var character_mining_progress: double } @@ -496,7 +502,7 @@ external interface LuaCustomChartTag { var tag_number: uint var force: LuaForce var surface: LuaSurface - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaCustomChartTag" */ fun help(): String } @@ -515,12 +521,12 @@ external interface LuaCustomInputPrototype { var linked_game_control: String? var consuming: String /* "none" | "game-only" */ var action: String - var enabled: Boolean - var enabled_while_spectating: Boolean - var enabled_while_in_cutscene: Boolean - var include_selected_prototype: Boolean + var enabled: Boolean? + var enabled_while_spectating: Boolean? + var enabled_while_in_cutscene: Boolean? + var include_selected_prototype: Boolean? var item_to_spawn: LuaItemPrototype? - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaCustomInputPrototype" */ fun help(): String } @@ -529,7 +535,7 @@ typealias CustomTableIndex = Any external interface LuaCustomTableMembers { var length: () -> uint /* () -> uint & LuaExtension */ - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaCustomTable" */ fun help(): String } @@ -543,15 +549,15 @@ external interface LuaDamagePrototype { var localised_description: dynamic /* JsTuple | String | Number */ get() = definedExternally set(value) = definedExternally - var hidden: Boolean - var valid: Boolean + var hidden: Boolean? + var valid: Boolean? var object_name: String /* "LuaDamagePrototype" */ fun help(): String } external interface LuaDeciderCombinatorControlBehavior : LuaCombinatorControlBehavior { var parameters: DeciderCombinatorParameters - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaDeciderCombinatorControlBehavior" */ fun help(): String } @@ -569,7 +575,7 @@ external interface LuaDecorativePrototype { var collision_mask: CollisionMask var collision_mask_with_flags: CollisionMaskWithFlags var autoplace_specification: AutoplaceSpecification? - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaDecorativePrototype" */ fun help(): String } @@ -581,9 +587,9 @@ external interface LuaElectricEnergySourcePrototype { var output_flow_limit: double var drain: double var emissions: double - var render_no_network_icon: Boolean - var render_no_power_icon: Boolean - var valid: Boolean + var render_no_network_icon: Boolean? + var render_no_power_icon: Boolean? + var valid: Boolean? var object_name: String /* "LuaElectricEnergySourcePrototype" */ fun help(): String } @@ -702,8 +708,8 @@ external interface LuaEntity : LuaControl { fun damage(damage: float, force: LuaForce, type: String = definedExternally, dealer: LuaEntity = definedExternally): float fun damage(damage: float, force: LuaForce): float fun damage(damage: float, force: LuaForce, type: String = definedExternally): float - fun can_be_destroyed(): Boolean - fun destroy(params: `T$15` = definedExternally): Boolean + fun can_be_destroyed(): Boolean? + fun destroy(params: `T$15` = definedExternally): Boolean? fun set_command(command: AttackCommand) fun set_command(command: GoToLocationCommand) fun set_command(command: CompoundCommand) @@ -722,32 +728,32 @@ external interface LuaEntity : LuaControl { fun set_distraction_command(command: StopCommand) fun set_distraction_command(command: FleeCommand) fun set_distraction_command(command: BuildBaseCommand) - fun has_command(): Boolean - fun die(force: String = definedExternally, cause: LuaEntity = definedExternally): Boolean - fun die(): Boolean - fun die(force: String = definedExternally): Boolean - fun die(force: LuaForce = definedExternally, cause: LuaEntity = definedExternally): Boolean - fun die(force: LuaForce = definedExternally): Boolean - fun has_flag(flag: String): Boolean - fun ghost_has_flag(flag: String): Boolean + fun has_command(): Boolean? + fun die(force: String = definedExternally, cause: LuaEntity = definedExternally): Boolean? + fun die(): Boolean? + fun die(force: String = definedExternally): Boolean? + fun die(force: LuaForce = definedExternally, cause: LuaEntity = definedExternally): Boolean? + fun die(force: LuaForce = definedExternally): Boolean? + fun has_flag(flag: String): Boolean? + fun ghost_has_flag(flag: String): Boolean? fun add_market_item(offer: Offer) - fun remove_market_item(offer: uint): Boolean + fun remove_market_item(offer: uint): Boolean? fun get_market_items(): Array fun clear_market_items() - fun connect_neighbour(target: LuaEntity): Boolean - fun connect_neighbour(target: WireConnectionDefinition): Boolean + fun connect_neighbour(target: LuaEntity): Boolean? + fun connect_neighbour(target: WireConnectionDefinition): Boolean? fun disconnect_neighbour(target: wire_type = definedExternally) fun disconnect_neighbour() fun disconnect_neighbour(target: LuaEntity = definedExternally) fun disconnect_neighbour(target: WireConnectionDefinition = definedExternally) - fun order_deconstruction(force: String, player: uint = definedExternally): Boolean - fun order_deconstruction(force: String): Boolean - fun order_deconstruction(force: String, player: String = definedExternally): Boolean - fun order_deconstruction(force: String, player: LuaPlayer = definedExternally): Boolean - fun order_deconstruction(force: LuaForce, player: uint = definedExternally): Boolean - fun order_deconstruction(force: LuaForce): Boolean - fun order_deconstruction(force: LuaForce, player: String = definedExternally): Boolean - fun order_deconstruction(force: LuaForce, player: LuaPlayer = definedExternally): Boolean + fun order_deconstruction(force: String, player: uint = definedExternally): Boolean? + fun order_deconstruction(force: String): Boolean? + fun order_deconstruction(force: String, player: String = definedExternally): Boolean? + fun order_deconstruction(force: String, player: LuaPlayer = definedExternally): Boolean? + fun order_deconstruction(force: LuaForce, player: uint = definedExternally): Boolean? + fun order_deconstruction(force: LuaForce): Boolean? + fun order_deconstruction(force: LuaForce, player: String = definedExternally): Boolean? + fun order_deconstruction(force: LuaForce, player: LuaPlayer = definedExternally): Boolean? fun cancel_deconstruction(force: String, player: uint = definedExternally) fun cancel_deconstruction(force: String) fun cancel_deconstruction(force: String, player: String = definedExternally) @@ -756,27 +762,27 @@ external interface LuaEntity : LuaControl { fun cancel_deconstruction(force: LuaForce) fun cancel_deconstruction(force: LuaForce, player: String = definedExternally) fun cancel_deconstruction(force: LuaForce, player: LuaPlayer = definedExternally) - fun to_be_deconstructed(): Boolean - fun order_upgrade(params: `T$16`): Boolean - fun cancel_upgrade(force: String, player: uint = definedExternally): Boolean - fun cancel_upgrade(force: String): Boolean - fun cancel_upgrade(force: String, player: String = definedExternally): Boolean - fun cancel_upgrade(force: String, player: LuaPlayer = definedExternally): Boolean - fun cancel_upgrade(force: LuaForce, player: uint = definedExternally): Boolean - fun cancel_upgrade(force: LuaForce): Boolean - fun cancel_upgrade(force: LuaForce, player: String = definedExternally): Boolean - fun cancel_upgrade(force: LuaForce, player: LuaPlayer = definedExternally): Boolean - fun to_be_upgraded(): Boolean + fun to_be_deconstructed(): Boolean? + fun order_upgrade(params: `T$16`): Boolean? + fun cancel_upgrade(force: String, player: uint = definedExternally): Boolean? + fun cancel_upgrade(force: String): Boolean? + fun cancel_upgrade(force: String, player: String = definedExternally): Boolean? + fun cancel_upgrade(force: String, player: LuaPlayer = definedExternally): Boolean? + fun cancel_upgrade(force: LuaForce, player: uint = definedExternally): Boolean? + fun cancel_upgrade(force: LuaForce): Boolean? + fun cancel_upgrade(force: LuaForce, player: String = definedExternally): Boolean? + fun cancel_upgrade(force: LuaForce, player: LuaPlayer = definedExternally): Boolean? + fun to_be_upgraded(): Boolean? fun get_request_slot(slot: uint): dynamic /* String? | ItemStackDefinition? */ - fun set_request_slot(request: String, slot: uint): Boolean - fun set_request_slot(request: ItemStackDefinition, slot: uint): Boolean - fun set_request_slot(request: LuaItemStack, slot: uint): Boolean + fun set_request_slot(request: String, slot: uint): Boolean? + fun set_request_slot(request: ItemStackDefinition, slot: uint): Boolean? + fun set_request_slot(request: LuaItemStack, slot: uint): Boolean? fun clear_request_slot(slot: uint) fun is_crafting() - fun is_opened(): Boolean - fun is_opening(): Boolean - fun is_closed(): Boolean - fun is_closing(): Boolean + fun is_opened(): Boolean? + fun is_opening(): Boolean? + fun is_closed(): Boolean? + fun is_closing(): Boolean? fun request_to_open(force: String, extra_time: uint = definedExternally) fun request_to_open(force: String) fun request_to_open(force: LuaForce, extra_time: uint = definedExternally) @@ -785,7 +791,7 @@ external interface LuaEntity : LuaControl { fun request_to_close(force: LuaForce) fun get_transport_line(index: uint): LuaTransportLine fun get_max_transport_line_index(): uint - fun launch_rocket(): Boolean + fun launch_rocket(): Boolean? fun revive(params: `T$17` = definedExternally): dynamic /* JsTuple | JsTuple, LuaEntity, LuaEntity?> */ fun silent_revive(params: `T$17` = definedExternally): dynamic /* JsTuple | JsTuple, LuaEntity, LuaEntity?> */ fun get_connected_rail(params: `T$18`): LuaEntity @@ -807,20 +813,20 @@ external interface LuaEntity : LuaControl { fun get_circuit_network(wire: wire_type, circuit_connector: circuit_connector_id = definedExternally): LuaCircuitNetwork? fun get_merged_signal(signal: SignalID, circuit_connector: circuit_connector_id = definedExternally): int fun get_merged_signals(circuit_connector: circuit_connector_id = definedExternally): Array? - fun supports_backer_name(): Boolean + fun supports_backer_name(): Boolean? fun copy_settings(entity: LuaEntity, by_player: uint = definedExternally): Record fun copy_settings(entity: LuaEntity): Record fun copy_settings(entity: LuaEntity, by_player: String = definedExternally): Record fun copy_settings(entity: LuaEntity, by_player: LuaPlayer = definedExternally): Record fun get_logistic_point(index: logistic_member_index = definedExternally): dynamic /* LuaLogisticPoint | Array */ - fun play_note(instrument: uint, note: uint): Boolean - fun connect_rolling_stock(direction: rail_direction): Boolean - fun disconnect_rolling_stock(direction: rail_direction): Boolean + fun play_note(instrument: uint, note: uint): Boolean? + fun connect_rolling_stock(direction: rail_direction): Boolean? + fun disconnect_rolling_stock(direction: rail_direction): Boolean? fun update_connections() fun get_recipe(): LuaRecipe? fun set_recipe(recipe: String?): Record fun set_recipe(recipe: LuaRecipe?): Record - fun rotate(params: `T$19` = definedExternally): Boolean + fun rotate(params: `T$19` = definedExternally): Boolean? fun get_driver(): dynamic /* LuaEntity? | LuaPlayer? */ fun set_driver(driver: LuaEntity?) fun set_driver(driver: uint?) @@ -831,7 +837,7 @@ external interface LuaEntity : LuaControl { fun set_passenger(passenger: uint) fun set_passenger(passenger: String) fun set_passenger(passenger: LuaPlayer) - fun is_connected_to_electric_network(): Boolean + fun is_connected_to_electric_network(): Boolean? fun get_train_stop_trains(): Array fun get_stopped_train(): LuaTrain? fun clone(params: `T$20`): LuaEntity? @@ -851,21 +857,21 @@ external interface LuaEntity : LuaControl { fun create_build_effect_smoke() fun release_from_spawner() fun toggle_equipment_movement_bonus() - fun can_shoot(target: LuaEntity, position: Position): Boolean + fun can_shoot(target: LuaEntity, position: Position): Boolean? fun start_fading_out() fun get_upgrade_target(): LuaEntityPrototype? fun get_upgrade_direction(): direction? fun get_damage_to_be_taken(): float fun deplete() - fun mine(params: `T$22` = definedExternally): Boolean + fun mine(params: `T$22` = definedExternally): Boolean? fun spawn_decorations() - fun can_wires_reach(entity: LuaEntity): Boolean + fun can_wires_reach(entity: LuaEntity): Boolean? fun get_connected_rolling_stock(direction: rail_direction): LuaEntity - fun is_registered_for_construction(): Boolean - fun is_registered_for_deconstruction(force: String): Boolean - fun is_registered_for_deconstruction(force: LuaForce): Boolean - fun is_registered_for_upgrade(): Boolean - fun is_registered_for_repair(): Boolean + fun is_registered_for_construction(): Boolean? + fun is_registered_for_deconstruction(force: String): Boolean? + fun is_registered_for_deconstruction(force: LuaForce): Boolean? + fun is_registered_for_upgrade(): Boolean? + fun is_registered_for_repair(): Boolean? fun add_autopilot_destination(position: Position) fun connect_linked_belts(neighbour: LuaEntity?) fun disconnect_linked_belts() @@ -885,14 +891,14 @@ external interface LuaEntity : LuaControl { set(value) = definedExternally var type: String var ghost_type: String - var active: Boolean - var destructible: Boolean - var minable: Boolean - var rotatable: Boolean - var operable: Boolean + var active: Boolean? + var destructible: Boolean? + var minable: Boolean? + var rotatable: Boolean? + var operable: Boolean? var health: float? var direction: direction - var supports_direction: Boolean + var supports_direction: Boolean? var orientation: RealOrientation var cliff_orientation: String /* "west-to-east" | "north-to-south" | "east-to-west" | "south-to-north" | "west-to-north" | "north-to-east" | "east-to-south" | "south-to-west" | "west-to-south" | "north-to-west" | "east-to-north" | "south-to-east" | "west-to-none" | "none-to-east" | "east-to-none" | "none-to-west" | "north-to-none" | "none-to-south" | "south-to-none" | "none-to-north" */ var relative_turret_orientation: RealOrientation? @@ -902,7 +908,7 @@ external interface LuaEntity : LuaControl { var effectivity_modifier: float var consumption_modifier: float var friction_modifier: float - var driver_is_gunner: Boolean + var driver_is_gunner: Boolean? var vehicle_automatic_targeting_parameters: VehicleAutomaticTargetingParameters var speed: float var effective_speed: float @@ -938,7 +944,7 @@ external interface LuaEntity : LuaControl { set(value) = definedExternally var signal_state: signal_state var chain_signal_state: chain_signal_state - var to_be_looted: Boolean + var to_be_looted: Boolean? var crafting_speed: double var crafting_progress: float var bonus_progress: double @@ -998,10 +1004,10 @@ external interface LuaEntity : LuaControl { var products_finished: uint var spawner: LuaEntity? var units: Array - var power_switch_state: Boolean + var power_switch_state: Boolean? var effects: ModuleEffects? var infinity_container_filters: Array - var remove_unfiltered_items: Boolean + var remove_unfiltered_items: Boolean? var character_corpse_player_index: uint var character_corpse_tick_of_death: uint var character_corpse_death_cause: dynamic /* JsTuple | String | Number */ @@ -1014,8 +1020,8 @@ external interface LuaEntity : LuaControl { var inserter_filter_mode: String /* "whitelist" | "blacklist" */ var splitter_input_priority: String /* "left" | "none" | "right" */ var splitter_output_priority: String /* "left" | "none" | "right" */ - var armed: Boolean - var recipe_locked: Boolean + var armed: Boolean? + var recipe_locked: Boolean? var connected_rail: LuaEntity? var trains_in_block: uint var timeout: uint @@ -1024,19 +1030,19 @@ external interface LuaEntity : LuaControl { var highlight_box_type: String var highlight_box_blink_interval: uint var status: entity_status? - var enable_logistics_while_moving: Boolean + var enable_logistics_while_moving: Boolean? var render_player: LuaPlayer? var render_to_forces: Array? var pump_rail_target: LuaEntity? - var moving: Boolean + var moving: Boolean? var electric_network_id: uint? - var allow_dispatching_robots: Boolean - var auto_launch: Boolean + var allow_dispatching_robots: Boolean? + var auto_launch: Boolean? var energy_generated_last_tick: double var storage_filter: LuaItemPrototype - var request_from_buffers: Boolean - var corpse_expires: Boolean - var corpse_immune_to_entity_placement: Boolean + var request_from_buffers: Boolean? + var corpse_expires: Boolean? + var corpse_immune_to_entity_placement: Boolean? var tags: Tags? var command: dynamic /* AttackCommand? | GoToLocationCommand? | CompoundCommand? | GroupCommand? | AttackAreaCommand? | WanderCommand? | StopCommand? | FleeCommand? | BuildBaseCommand? */ get() = definedExternally @@ -1049,22 +1055,22 @@ external interface LuaEntity : LuaControl { var autopilot_destinations: Array var trains_count: uint? var trains_limit: uint - var is_entity_with_force: Boolean - var is_entity_with_owner: Boolean - var is_entity_with_health: Boolean + var is_entity_with_force: Boolean? + var is_entity_with_owner: Boolean? + var is_entity_with_health: Boolean? var combat_robot_owner: LuaEntity var link_id: uint var follow_target: LuaEntity var follow_offset: Position? var linked_belt_type: String /* "input" | "output" */ var linked_belt_neighbour: LuaEntity? - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaEntity" */ fun help(): String } external interface `T$24` { - var minable: Boolean + var minable: Boolean? var mining_time: double var mining_particle: String? get() = definedExternally @@ -1112,7 +1118,7 @@ external interface `T$26` { } external interface LuaEntityPrototype { - fun has_flag(flag: String /* "not-rotatable" | "placeable-neutral" | "placeable-player" | "placeable-enemy" | "placeable-off-grid" | "player-creation" | "filter-directions" | "fast-replaceable-no-build-while-moving" | "breaths-air" | "not-repairable" | "not-on-map" | "not-deconstructable" | "not-blueprintable" | "hide-from-bonus-gui" | "hide-alt-info" | "fast-replaceable-no-cross-type-while-moving" | "no-gap-fill-while-building" | "not-flammable" | "no-automated-item-removal" | "no-automated-item-insertion" | "not-upgradable" */): Boolean + fun has_flag(flag: String /* "not-rotatable" | "placeable-neutral" | "placeable-player" | "placeable-enemy" | "placeable-off-grid" | "player-creation" | "filter-directions" | "fast-replaceable-no-build-while-moving" | "breaths-air" | "not-repairable" | "not-on-map" | "not-deconstructable" | "not-blueprintable" | "hide-from-bonus-gui" | "hide-alt-info" | "fast-replaceable-no-cross-type-while-moving" | "no-gap-fill-while-building" | "not-flammable" | "no-automated-item-removal" | "no-automated-item-insertion" | "not-upgradable" */): Boolean? fun get_inventory_size(index: inventory): uint? var type: String var name: String @@ -1145,7 +1151,7 @@ external interface LuaEntityPrototype { var healing_per_tick: float var emissions_per_second: double var corpses: Record - var selectable_in_game: Boolean + var selectable_in_game: Boolean? var selection_priority: uint var weight: double? var resistances: Record @@ -1170,7 +1176,7 @@ external interface LuaEntityPrototype { var flags: EntityPrototypeFlags var remains_when_mined: Array var additional_pastable_entities: Array - var allow_copy_paste: Boolean + var allow_copy_paste: Boolean? var shooting_cursor_size: double var created_smoke: `T$26`? var created_effect: Array? @@ -1221,9 +1227,9 @@ external interface LuaEntityPrototype { var fluid: LuaFluidPrototype? var fluid_capacity: double var pumping_speed: double? - var stack: Boolean - var allow_custom_vectors: Boolean - var allow_burner_leech: Boolean + var stack: Boolean? + var allow_custom_vectors: Boolean? + var allow_burner_leech: Boolean? var inserter_extension_speed: double? var inserter_rotation_speed: double? var inserter_pickup_position: dynamic /* typealias Vector = dynamic */ @@ -1233,7 +1239,7 @@ external interface LuaEntityPrototype { get() = definedExternally set(value) = definedExternally var inserter_chases_belt_items: Boolean? - var count_as_rock_for_filtered_deconstruction: Boolean + var count_as_rock_for_filtered_deconstruction: Boolean? var filter_count: uint? var time_to_live: uint var distribution_effectivity: double? @@ -1243,9 +1249,9 @@ external interface LuaEntityPrototype { var alert_when_damaged: Boolean? var alert_when_attacking: Boolean? var color: ColorTable? - var collision_mask_collides_with_self: Boolean - var collision_mask_collides_with_tiles_only: Boolean - var collision_mask_considers_tile_transitions: Boolean + var collision_mask_collides_with_self: Boolean? + var collision_mask_collides_with_tiles_only: Boolean? + var collision_mask_considers_tile_transitions: Boolean? var allowed_effects: Record? var rocket_parts_required: uint? var rocket_rising_delay: uint8? @@ -1260,7 +1266,7 @@ external interface LuaEntityPrototype { var construction_radius: double? var logistic_radius: double? var energy_per_hit_point: double? - var create_ghost_on_death: Boolean + var create_ghost_on_death: Boolean? var timeout: uint var fluidbox_prototypes: Array var neighbour_bonus: double @@ -1268,7 +1274,7 @@ external interface LuaEntityPrototype { var container_distance: double var belt_distance: double var belt_length: double - var is_building: Boolean + var is_building: Boolean? var automated_ammo_count: uint? var max_speed: double? var darkness_for_all_lamps_on: float? @@ -1302,10 +1308,10 @@ external interface LuaEntityPrototype { var researching_speed: double? var item_slot_count: uint? var base_productivity: double? - var allow_access_to_all_forces: Boolean - var supports_direction: Boolean + var allow_access_to_all_forces: Boolean? + var supports_direction: Boolean? var terrain_friction_modifier: float - var allow_passengers: Boolean + var allow_passengers: Boolean? var max_distance_of_sector_revealed: uint var max_distance_of_nearby_sector_revealed: uint var adjacent_tile_collision_box: BoundingBoxTable @@ -1330,7 +1336,7 @@ external interface LuaEntityPrototype { var respawn_time: uint var damage_hit_tint: ColorTable var character_corpse: LuaEntityPrototype - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaEntityPrototype" */ fun help(): String } @@ -1354,7 +1360,7 @@ external interface LuaEquipment { var max_energy: double var prototype: LuaEquipmentPrototype var burner: LuaBurner? - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaEquipment" */ fun help(): String } @@ -1368,7 +1374,7 @@ external interface LuaEquipmentCategoryPrototype { var localised_description: dynamic /* JsTuple | String | Number */ get() = definedExternally set(value) = definedExternally - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaEquipmentCategoryPrototype" */ fun help(): String } @@ -1411,8 +1417,8 @@ external interface LuaEquipmentGrid { fun clear(by_player: String = definedExternally) fun clear(by_player: LuaPlayer = definedExternally) fun put(params: `T$29`): LuaEquipment? - fun can_move(params: `T$30`): Boolean - fun move(params: `T$30`): Boolean + fun can_move(params: `T$30`): Boolean? + fun move(params: `T$30`): Boolean? fun get(position: Position): LuaEquipment? fun get_contents(): Record var prototype: LuaEquipmentGridPrototype @@ -1425,8 +1431,8 @@ external interface LuaEquipmentGrid { var battery_capacity: double var shield: float var max_shield: float - var inhibit_movement_bonus: Boolean - var valid: Boolean + var inhibit_movement_bonus: Boolean? + var valid: Boolean? var object_name: String /* "LuaEquipmentGrid" */ fun help(): String } @@ -1443,8 +1449,8 @@ external interface LuaEquipmentGridPrototype { var equipment_categories: Array var width: uint var height: uint - var locked: Boolean - var valid: Boolean + var locked: Boolean? + var valid: Boolean? var object_name: String /* "LuaEquipmentGridPrototype" */ fun help(): String } @@ -1476,7 +1482,7 @@ external interface `T$32` { set(value) = definedExternally var robot_limit: uint var logistics_connection_distance: float - var robots_shrink_when_entering_and_exiting: Boolean + var robots_shrink_when_entering_and_exiting: Boolean? } external interface LuaEquipmentPrototype { @@ -1505,15 +1511,15 @@ external interface LuaEquipmentPrototype { var attack_parameters: dynamic /* ProjectileAttackParameters? | StreamAttackParameters? | OtherAttackParameters? */ get() = definedExternally set(value) = definedExternally - var automatic: Boolean - var valid: Boolean + var automatic: Boolean? + var valid: Boolean? var object_name: String /* "LuaEquipmentPrototype" */ fun help(): String } external interface `T$33` { var name: String - var input: Boolean + var input: Boolean? var precision_index: flow_precision_index var count: Boolean? get() = definedExternally @@ -1531,7 +1537,7 @@ external interface LuaFlowStatistics { var input_counts: Record var output_counts: Record var force: LuaForce? - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaFlowStatistics" */ fun help(): String } @@ -1552,23 +1558,23 @@ external interface LuaFluidBoxPrototype { var maximum_temperature: double? var secondary_draw_orders: Array var render_layer: String - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaFluidBoxPrototype" */ fun help(): String } external interface LuaFluidEnergySourcePrototype { var emissions: double - var render_no_network_icon: Boolean - var render_no_power_icon: Boolean + var render_no_network_icon: Boolean? + var render_no_power_icon: Boolean? var effectivity: double - var burns_fluid: Boolean - var scale_fluid_usage: Boolean + var burns_fluid: Boolean? + var scale_fluid_usage: Boolean? var fluid_usage_per_tick: double var smoke: Array var maximum_temperature: double var fluid_box: LuaFluidBoxPrototype - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaFluidEnergySourcePrototype" */ fun help(): String } @@ -1592,8 +1598,8 @@ external interface LuaFluidPrototype { var gas_temperature: double var emissions_multiplier: double var fuel_value: double - var hidden: Boolean - var valid: Boolean + var hidden: Boolean? + var valid: Boolean? var object_name: String /* "LuaFluidPrototype" */ fun help(): String } @@ -1603,10 +1609,10 @@ external interface LuaFontPrototype { var from: String var size: int var spacing: float - var border: Boolean - var filtered: Boolean + var border: Boolean? + var filtered: Boolean? var border_color: ColorTable? - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaFontPrototype" */ fun help(): String } @@ -1663,18 +1669,18 @@ external interface LuaForce { fun chart_all() fun chart_all(surface: String = definedExternally) fun chart_all(surface: LuaSurface = definedExternally) - fun is_chunk_charted(surface: uint, position: ChunkPositionTable): Boolean - fun is_chunk_charted(surface: uint, position: Any /* JsTuple */): Boolean - fun is_chunk_charted(surface: String, position: ChunkPositionTable): Boolean - fun is_chunk_charted(surface: String, position: Any /* JsTuple */): Boolean - fun is_chunk_charted(surface: LuaSurface, position: ChunkPositionTable): Boolean - fun is_chunk_charted(surface: LuaSurface, position: Any /* JsTuple */): Boolean - fun is_chunk_visible(surface: uint, position: ChunkPositionTable): Boolean - fun is_chunk_visible(surface: uint, position: Any /* JsTuple */): Boolean - fun is_chunk_visible(surface: String, position: ChunkPositionTable): Boolean - fun is_chunk_visible(surface: String, position: Any /* JsTuple */): Boolean - fun is_chunk_visible(surface: LuaSurface, position: ChunkPositionTable): Boolean - fun is_chunk_visible(surface: LuaSurface, position: Any /* JsTuple */): Boolean + fun is_chunk_charted(surface: uint, position: ChunkPositionTable): Boolean? + fun is_chunk_charted(surface: uint, position: Any /* JsTuple */): Boolean? + fun is_chunk_charted(surface: String, position: ChunkPositionTable): Boolean? + fun is_chunk_charted(surface: String, position: Any /* JsTuple */): Boolean? + fun is_chunk_charted(surface: LuaSurface, position: ChunkPositionTable): Boolean? + fun is_chunk_charted(surface: LuaSurface, position: Any /* JsTuple */): Boolean? + fun is_chunk_visible(surface: uint, position: ChunkPositionTable): Boolean? + fun is_chunk_visible(surface: uint, position: Any /* JsTuple */): Boolean? + fun is_chunk_visible(surface: String, position: ChunkPositionTable): Boolean? + fun is_chunk_visible(surface: String, position: Any /* JsTuple */): Boolean? + fun is_chunk_visible(surface: LuaSurface, position: ChunkPositionTable): Boolean? + fun is_chunk_visible(surface: LuaSurface, position: Any /* JsTuple */): Boolean? fun cancel_charting(surface: uint = definedExternally) fun cancel_charting() fun cancel_charting(surface: String = definedExternally) @@ -1687,13 +1693,13 @@ external interface LuaForce { fun set_turret_attack_modifier(turret: String, modifier: double) fun set_cease_fire(other: String, cease_fire: Boolean) fun set_cease_fire(other: LuaForce, cease_fire: Boolean) - fun get_cease_fire(other: String): Boolean - fun get_cease_fire(other: LuaForce): Boolean + fun get_cease_fire(other: String): Boolean? + fun get_cease_fire(other: LuaForce): Boolean? fun set_friend(other: String, friend: Boolean) fun set_friend(other: LuaForce, friend: Boolean) - fun get_friend(other: String): Boolean - fun get_friend(other: LuaForce): Boolean - fun is_pathfinder_busy(): Boolean + fun get_friend(other: String): Boolean? + fun get_friend(other: LuaForce): Boolean? + fun is_pathfinder_busy(): Boolean? fun kill_all_units() fun find_logistic_network_by_position(position: Position, surface: uint): LuaLogisticNetwork? fun find_logistic_network_by_position(position: Position, surface: String): LuaLogisticNetwork? @@ -1746,21 +1752,21 @@ external interface LuaForce { fun reset_evolution() fun play_sound(params: `T$34`) fun get_train_stops(params: `T$35` = definedExternally): Array - fun get_hand_crafting_disabled_for_recipe(recipe: String): Boolean - fun get_hand_crafting_disabled_for_recipe(recipe: LuaRecipe): Boolean + fun get_hand_crafting_disabled_for_recipe(recipe: String): Boolean? + fun get_hand_crafting_disabled_for_recipe(recipe: LuaRecipe): Boolean? fun set_hand_crafting_disabled_for_recipe(recipe: String, hand_crafting_disabled: Boolean) fun set_hand_crafting_disabled_for_recipe(recipe: LuaRecipe, hand_crafting_disabled: Boolean) - fun add_research(technology: String): Boolean - fun add_research(technology: LuaTechnology): Boolean - fun add_research(technology: LuaTechnologyPrototype): Boolean + fun add_research(technology: String): Boolean? + fun add_research(technology: LuaTechnology): Boolean? + fun add_research(technology: LuaTechnologyPrototype): Boolean? fun cancel_current_research() fun get_linked_inventory(prototype: LuaEntity, link_id: uint): LuaInventory? fun get_linked_inventory(prototype: LuaEntityPrototype, link_id: uint): LuaInventory? fun get_linked_inventory(prototype: String, link_id: uint): LuaInventory? - fun is_friend(other: String): Boolean - fun is_friend(other: LuaForce): Boolean - fun is_enemy(other: String): Boolean - fun is_enemy(other: LuaForce): Boolean + fun is_friend(other: String): Boolean? + fun is_friend(other: LuaForce): Boolean? + fun is_enemy(other: String): Boolean? + fun is_enemy(other: LuaForce): Boolean? var name: String var technologies: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ var recipes: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ @@ -1781,7 +1787,7 @@ external interface LuaForce { var following_robots_lifetime_modifier: double var ghost_time_to_live: uint var players: Array - var ai_controllable: Boolean + var ai_controllable: Boolean? var logistic_networks: Record> var item_production_statistics: LuaFlowStatistics var fluid_production_statistics: LuaFlowStatistics @@ -1800,12 +1806,12 @@ external interface LuaForce { var character_health_bonus: double var max_successful_attempts_per_tick_per_construction_queue: uint var max_failed_attempts_per_tick_per_construction_queue: uint - var zoom_to_world_enabled: Boolean - var zoom_to_world_ghost_building_enabled: Boolean - var zoom_to_world_blueprint_enabled: Boolean - var zoom_to_world_deconstruction_planner_enabled: Boolean - var zoom_to_world_selection_tool_enabled: Boolean - var character_logistic_requests: Boolean + var zoom_to_world_enabled: Boolean? + var zoom_to_world_ghost_building_enabled: Boolean? + var zoom_to_world_blueprint_enabled: Boolean? + var zoom_to_world_deconstruction_planner_enabled: Boolean? + var zoom_to_world_selection_tool_enabled: Boolean? + var character_logistic_requests: Boolean? var rockets_launched: uint var items_launched: Record var connected_players: Array @@ -1815,13 +1821,13 @@ external interface LuaForce { var evolution_factor_by_pollution: double var evolution_factor_by_time: double var evolution_factor_by_killing_spawners: double - var friendly_fire: Boolean - var share_chart: Boolean - var research_queue_enabled: Boolean + var friendly_fire: Boolean? + var share_chart: Boolean? + var research_queue_enabled: Boolean? var index: uint var research_queue: Array? - var research_enabled: Boolean - var valid: Boolean + var research_enabled: Boolean? + var valid: Boolean? var object_name: String /* "LuaForce" */ fun help(): String } @@ -1835,16 +1841,16 @@ external interface LuaFuelCategoryPrototype { var localised_description: dynamic /* JsTuple | String | Number */ get() = definedExternally set(value) = definedExternally - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaFuelCategoryPrototype" */ fun help(): String } external interface `T$36` { - var game_finished: Boolean - var player_won: Boolean + var game_finished: Boolean? + var player_won: Boolean? var next_level: String - var can_continue: Boolean + var can_continue: Boolean? var victorious_force: dynamic /* String | LuaForce */ get() = definedExternally set(value) = definedExternally @@ -1956,7 +1962,7 @@ external interface LuaGameScript { fun set_game_state(params: `T$36`) fun get_entity_by_tag(tag: String): LuaEntity fun show_message_dialog(params: `T$37`) - fun is_demo(): Boolean + fun is_demo(): Boolean? fun reload_script() fun reload_mods() fun save_atlas() @@ -2005,10 +2011,10 @@ external interface LuaGameScript { fun create_random_generator(seed: uint = definedExternally): LuaRandomGenerator fun check_prototype_translations() fun play_sound(params: `T$34`) - fun is_valid_sound_path(sound_path: String): Boolean - fun is_valid_sound_path(sound_path: ): Boolean - fun is_valid_sprite_path(sprite_path: String): Boolean - fun is_valid_sprite_path(sprite_path: ): Boolean + fun is_valid_sound_path(sound_path: String): Boolean? +// fun is_valid_sound_path(sound_path: String): Boolean? + fun is_valid_sprite_path(sprite_path: String): Boolean? +// fun is_valid_sprite_path(sprite_path: String): Boolean? fun kick_player(player: uint, reason: Any /* JsTuple */ = definedExternally) fun kick_player(player: uint) fun kick_player(player: uint, reason: String = definedExternally) @@ -2046,7 +2052,7 @@ external interface LuaGameScript { fun unmute_player(player: String) fun unmute_player(player: LuaPlayer) fun count_pipe_groups() - fun is_multiplayer(): Boolean + fun is_multiplayer(): Boolean? fun get_active_entities_count(surface: uint = definedExternally): uint fun get_active_entities_count(): uint fun get_active_entities_count(surface: String = definedExternally): uint @@ -2114,9 +2120,9 @@ external interface LuaGameScript { var styles: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ var tick: uint var ticks_played: uint - var tick_paused: Boolean + var tick_paused: Boolean? var ticks_to_run: uint - var finished: Boolean + var finished: Boolean? var speed: float var surfaces: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ var active_mods: Record @@ -2124,9 +2130,9 @@ external interface LuaGameScript { var permissions: LuaPermissionGroups var backer_names: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ var default_map_gen_settings: MapGenSettings - var enemy_has_vision_on_land_mines: Boolean - var autosave_enabled: Boolean - var draw_resource_selection: Boolean + var enemy_has_vision_on_land_mines: Boolean? + var autosave_enabled: Boolean? + var draw_resource_selection: Boolean? var pollution_statistics: LuaFlowStatistics var max_force_distraction_distance: double var max_force_distraction_chunk_distance: uint @@ -2141,11 +2147,11 @@ external interface LuaGameScript { } external interface LuaGenericOnOffControlBehavior : LuaControlBehavior { - var disabled: Boolean + var disabled: Boolean? var circuit_condition: CircuitConditionDefinition var logistic_condition: CircuitConditionDefinition - var connect_to_logistic_network: Boolean - var valid: Boolean + var connect_to_logistic_network: Boolean? + var valid: Boolean? var object_name: String fun help(): String } @@ -2160,14 +2166,14 @@ external interface LuaGroup { var subgroups: Array var order_in_recipe: String var order: String - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaGroup" */ fun help(): String } external interface LuaGui { - fun is_valid_sprite_path(sprite_path: String): Boolean - fun is_valid_sprite_path(sprite_path: ): Boolean + fun is_valid_sprite_path(sprite_path: String): Boolean? +// fun is_valid_sprite_path(sprite_path: ): Boolean? var player: LuaPlayer var children: Record var top: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ @@ -2188,7 +2194,7 @@ external interface LuaGui { var relative: dynamic /* ChooseElemButtonGuiElementMembers | DropDownGuiElementMembers | EmptyWidgetGuiElementMembers | EntityPreviewGuiElementMembers | ListBoxGuiElementMembers | ScrollPaneGuiElementMembers | SpriteButtonGuiElementMembers | TabbedPaneGuiElementMembers | TextBoxGuiElementMembers | ButtonGuiElementMembers | CameraGuiElementMembers | CheckboxGuiElementMembers | FlowGuiElementMembers | FrameGuiElementMembers | LabelGuiElementMembers | LineGuiElementMembers | MinimapGuiElementMembers | ProgressbarGuiElementMembers | RadiobuttonGuiElementMembers | SliderGuiElementMembers | SpriteGuiElementMembers | SwitchGuiElementMembers | TabGuiElementMembers | TableGuiElementMembers | TextfieldGuiElementMembers */ get() = definedExternally set(value) = definedExternally - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaGui" */ fun help(): String } @@ -2299,12 +2305,12 @@ external interface ProgressbarGuiSpec : BaseGuiSpec { external interface CheckboxGuiSpec : BaseGuiSpec { override var type: String /* "checkbox" */ - var state: Boolean + var state: Boolean? } external interface RadiobuttonGuiSpec : BaseGuiSpec { override var type: String /* "radiobutton" */ - var state: Boolean + var state: Boolean? } external interface SpriteButtonGuiSpec : BaseGuiSpec { @@ -2407,7 +2413,7 @@ external interface ChooseElemButtonFilters { external interface BaseChooseElemButtonSpec : BaseGuiSpec { override var type: String /* "choose-elem-button" */ var elem_type: String /* "item" | "tile" | "entity" | "signal" | "fluid" | "recipe" | "decorative" | "item-group" | "achievement" | "equipment" | "technology" */ - var filters: Any + var filters: Any? get() = definedExternally set(value) = definedExternally } @@ -2655,8 +2661,8 @@ external interface BaseGuiElement { fun get_slider_maximum(): double fun set_slider_minimum_maximum(minimum: double, maximum: double) fun get_slider_value_step(): double - fun get_slider_discrete_slider(): Boolean - fun get_slider_discrete_values(): Boolean + fun get_slider_discrete_slider(): Boolean? + fun get_slider_discrete_values(): Boolean? fun set_slider_value_step(value: double) fun set_slider_discrete_slider(value: Boolean) fun set_slider_discrete_values(value: Boolean) @@ -2674,13 +2680,13 @@ external interface BaseGuiElement { var style: dynamic /* LuaStyle | String */ get() = definedExternally set(value) = definedExternally - var visible: Boolean + var visible: Boolean? var children_names: Array var player_index: uint var sprite: dynamic /* String | */ get() = definedExternally set(value) = definedExternally - var resize_to_sprite: Boolean + var resize_to_sprite: Boolean? var clicked_sprite: dynamic /* String | */ get() = definedExternally set(value) = definedExternally @@ -2692,7 +2698,7 @@ external interface BaseGuiElement { var items: Array | String | Number */> var selected_index: uint var number: double? - var show_percent_for_small_numbers: Boolean + var show_percent_for_small_numbers: Boolean? var location: dynamic /* GuiLocationTable? | JsTuple */ get() = definedExternally set(value) = definedExternally @@ -2700,8 +2706,8 @@ external interface BaseGuiElement { var surface_index: uint var zoom: double var force: String? - var enabled: Boolean - var ignored_by_interaction: Boolean + var enabled: Boolean? + var ignored_by_interaction: Boolean? var mouse_button_filter: dynamic /* MouseButtonFlagsTable | MouseButtonFlagsArray */ get() = definedExternally set(value) = definedExternally @@ -2712,7 +2718,7 @@ external interface BaseGuiElement { var entity: LuaEntity? var anchor: GuiAnchor? var tags: Tags - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaGuiElement" */ fun help(): String } @@ -2722,7 +2728,7 @@ external interface ChooseElemButtonGuiElementMembers : BaseGuiElement { var elem_type: String /* "item" | "tile" | "entity" | "signal" | "fluid" | "recipe" | "decorative" | "item-group" | "achievement" | "equipment" | "technology" */ var elem_value: Any? var elem_filters: Any - var locked: Boolean + var locked: Boolean? } external interface DropDownGuiElementMembers : BaseGuiElement { @@ -2776,10 +2782,10 @@ external interface TextBoxGuiElementMembers : BaseGuiElement { fun select_all() fun select(start: int, end: int) var text: String - var selectable: Boolean - var word_wrap: Boolean - var read_only: Boolean - var clear_and_focus_on_right_click: Boolean + var selectable: Boolean? + var word_wrap: Boolean? + var read_only: Boolean? + var clear_and_focus_on_right_click: Boolean? } external interface ButtonGuiElementMembers : BaseGuiElement { @@ -2792,7 +2798,7 @@ external interface CameraGuiElementMembers : BaseGuiElement { external interface CheckboxGuiElementMembers : BaseGuiElement { override var type: String /* "checkbox" */ - var state: Boolean + var state: Boolean? } external interface FlowGuiElementMembers : BaseGuiElement { @@ -2804,7 +2810,7 @@ external interface FrameGuiElementMembers : BaseGuiElement { override var type: String /* "frame" */ fun force_auto_center() var direction: String /* "horizontal" | "vertical" */ - var auto_center: Boolean + var auto_center: Boolean? } external interface LabelGuiElementMembers : BaseGuiElement { @@ -2828,7 +2834,7 @@ external interface ProgressbarGuiElementMembers : BaseGuiElement { external interface RadiobuttonGuiElementMembers : BaseGuiElement { override var type: String /* "radiobutton" */ - var state: Boolean + var state: Boolean? } external interface SliderGuiElementMembers : BaseGuiElement { @@ -2843,7 +2849,7 @@ external interface SpriteGuiElementMembers : BaseGuiElement { external interface SwitchGuiElementMembers : BaseGuiElement { override var type: String /* "switch" */ var switch_state: String - var allow_none_state: Boolean + var allow_none_state: Boolean? var left_label_caption: dynamic /* JsTuple | String | Number */ get() = definedExternally set(value) = definedExternally @@ -2867,11 +2873,11 @@ external interface TabGuiElementMembers : BaseGuiElement { external interface TableGuiElementMembers : BaseGuiElement { override var type: String /* "table" */ - var draw_vertical_lines: Boolean - var draw_horizontal_lines: Boolean - var draw_horizontal_line_after_headers: Boolean + var draw_vertical_lines: Boolean? + var draw_horizontal_lines: Boolean? + var draw_horizontal_line_after_headers: Boolean? var column_count: uint - var vertical_centering: Boolean + var vertical_centering: Boolean? } external interface TextfieldGuiElementMembers : BaseGuiElement { @@ -2879,18 +2885,18 @@ external interface TextfieldGuiElementMembers : BaseGuiElement { fun select_all() fun select(start: int, end: int) var text: String - var numeric: Boolean - var allow_decimal: Boolean - var allow_negative: Boolean - var is_password: Boolean - var lose_focus_on_confirm: Boolean - var clear_and_focus_on_right_click: Boolean + var numeric: Boolean? + var allow_decimal: Boolean? + var allow_negative: Boolean? + var is_password: Boolean? + var lose_focus_on_confirm: Boolean? + var clear_and_focus_on_right_click: Boolean? } external interface LuaHeatEnergySourcePrototype { var emissions: double - var render_no_network_icon: Boolean - var render_no_power_icon: Boolean + var render_no_network_icon: Boolean? + var render_no_power_icon: Boolean? var max_temperature: double var default_temperature: double var specific_heat: double @@ -2899,18 +2905,18 @@ external interface LuaHeatEnergySourcePrototype { var min_working_temperature: double var minimum_glow_temperature: double var connections: Array - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaHeatEnergySourcePrototype" */ fun help(): String } external interface LuaInserterControlBehavior : LuaGenericOnOffControlBehavior { - var circuit_read_hand_contents: Boolean + var circuit_read_hand_contents: Boolean? var circuit_mode_of_operation: circuit_mode_of_operation var circuit_hand_read_mode: hand_read_mode - var circuit_set_stack_size: Boolean + var circuit_set_stack_size: Boolean? var circuit_stack_control_signal: SignalID - override var valid: Boolean + override var valid: Boolean? override var object_name: String /* "LuaInserterControlBehavior" */ override fun help(): String } @@ -2918,7 +2924,7 @@ external interface LuaInserterControlBehavior : LuaGenericOnOffControlBehavior { typealias LuaInventory = Array external interface LuaItemPrototype { - fun has_flag(flag: String): Boolean + fun has_flag(flag: String): Boolean? fun get_ammo_type(ammo_source_type: String /* "default" | "player" | "turret" | "vehicle" */ = definedExternally): AmmoType? var type: String /* "gun" | "mining-tool" */ var name: String @@ -2932,7 +2938,7 @@ external interface LuaItemPrototype { var place_result: LuaEntityPrototype? var place_as_equipment_result: LuaEquipmentPrototype? var place_as_tile_result: PlaceAsTileResult? - var stackable: Boolean + var stackable: Boolean? var default_request_amount: uint var stack_size: uint var wire_count: uint @@ -2946,7 +2952,7 @@ external interface LuaItemPrototype { var group: LuaGroup var flags: ItemPrototypeFlags var rocket_launch_products: Array - var can_be_mod_opened: Boolean + var can_be_mod_opened: Boolean? var magazine_size: float? var reload_time: float? var equipment_grid: LuaEquipmentGridPrototype? @@ -2965,9 +2971,9 @@ external interface LuaItemPrototype { var localised_filter_message: dynamic /* JsTuple | String | Number */ get() = definedExternally set(value) = definedExternally - var extend_inventory_by_default: Boolean + var extend_inventory_by_default: Boolean? var default_label_color: ColorTable? - var draw_label_for_cursor_render: Boolean + var draw_label_for_cursor_render: Boolean? var speed: float? var module_effects: ModuleEffects? var category: String @@ -2983,7 +2989,7 @@ external interface LuaItemPrototype { var alt_selection_mode_flags: SelectionModeFlags var selection_cursor_box_type: String var alt_selection_cursor_box_type: String - var always_include_tiles: Boolean + var always_include_tiles: Boolean? var entity_filter_mode: String var alt_entity_filter_mode: String var tile_filter_mode: String @@ -3000,7 +3006,7 @@ external interface LuaItemPrototype { var durability: double? var infinite: Boolean? var mapper_count: uint? - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaItemPrototype" */ fun help(): String } @@ -3079,27 +3085,27 @@ external interface `T$44` { } external interface LuaItemStack { - fun is_blueprint_setup(): Boolean + fun is_blueprint_setup(): Boolean? fun get_blueprint_entities(): Array fun set_blueprint_entities(entities: Array) fun add_ammo(amount: float) fun drain_ammo(amount: float) fun add_durability(amount: double) fun drain_durability(amount: double) - fun can_set_stack(stack: String = definedExternally): Boolean - fun can_set_stack(): Boolean - fun can_set_stack(stack: ItemStackDefinition = definedExternally): Boolean - fun can_set_stack(stack: LuaItemStack = definedExternally): Boolean - fun set_stack(stack: String = definedExternally): Boolean - fun set_stack(): Boolean - fun set_stack(stack: ItemStackDefinition = definedExternally): Boolean - fun set_stack(stack: LuaItemStack = definedExternally): Boolean - fun transfer_stack(stack: String): Boolean - fun transfer_stack(stack: ItemStackDefinition): Boolean - fun transfer_stack(stack: LuaItemStack): Boolean + fun can_set_stack(stack: String = definedExternally): Boolean? + fun can_set_stack(): Boolean? + fun can_set_stack(stack: ItemStackDefinition = definedExternally): Boolean? + fun can_set_stack(stack: LuaItemStack = definedExternally): Boolean? + fun set_stack(stack: String = definedExternally): Boolean? + fun set_stack(): Boolean? + fun set_stack(stack: ItemStackDefinition = definedExternally): Boolean? + fun set_stack(stack: LuaItemStack = definedExternally): Boolean? + fun transfer_stack(stack: String): Boolean? + fun transfer_stack(stack: ItemStackDefinition): Boolean? + fun transfer_stack(stack: LuaItemStack): Boolean? fun export_stack(): String fun import_stack(data: String): int - fun swap_stack(stack: LuaItemStack): Boolean + fun swap_stack(stack: LuaItemStack): Boolean? fun clear() fun get_blueprint_tiles(): Array fun set_blueprint_tiles(tiles: Array) @@ -3113,16 +3119,16 @@ external interface LuaItemStack { fun set_tag(tag_name: String, tag: Number): dynamic /* String | Number | Boolean | table */ fun set_tag(tag_name: String, tag: Boolean): dynamic /* String | Number | Boolean | table */ fun set_tag(tag_name: String, tag: table): dynamic /* String | Number | Boolean | table */ - fun remove_tag(tag: String): Boolean + fun remove_tag(tag: String): Boolean? fun clear_blueprint() fun get_entity_filter(index: uint): String - fun set_entity_filter(index: uint, filter: String?): Boolean - fun set_entity_filter(index: uint, filter: LuaEntityPrototype?): Boolean - fun set_entity_filter(index: uint, filter: LuaEntity?): Boolean + fun set_entity_filter(index: uint, filter: String?): Boolean? + fun set_entity_filter(index: uint, filter: LuaEntityPrototype?): Boolean? + fun set_entity_filter(index: uint, filter: LuaEntity?): Boolean? fun get_tile_filter(index: uint): String - fun set_tile_filter(index: uint, filter: String?): Boolean - fun set_tile_filter(index: uint, filter: LuaTilePrototype?): Boolean - fun set_tile_filter(index: uint, filter: LuaTile?): Boolean + fun set_tile_filter(index: uint, filter: String?): Boolean? + fun set_tile_filter(index: uint, filter: LuaTilePrototype?): Boolean? + fun set_tile_filter(index: uint, filter: LuaTile?): Boolean? fun clear_deconstruction_item() fun clear_upgrade_item() fun get_mapper(index: uint, type: String /* "from" | "to" */): UpgradeFilter @@ -3136,7 +3142,7 @@ external interface LuaItemStack { fun set_blueprint_entity_tag(index: uint, tag: String, value: Boolean?) fun set_blueprint_entity_tag(index: uint, tag: String, value: table?) fun create_grid(): LuaEquipmentGrid - var valid_for_read: Boolean + var valid_for_read: Boolean? var prototype: LuaItemPrototype var name: String var type: String @@ -3148,14 +3154,14 @@ external interface LuaItemStack { var blueprint_icons: Array? var blueprint_snap_to_grid: Position? var blueprint_position_relative_to_grid: Position? - var blueprint_absolute_snapping: Boolean + var blueprint_absolute_snapping: Boolean? var label: String? var label_color: dynamic /* ColorTable? | JsTuple */ get() = definedExternally set(value) = definedExternally - var allow_manual_label_change: Boolean + var allow_manual_label_change: Boolean? var cost_to_build: Record - var extends_inventory: Boolean + var extends_inventory: Boolean? var prioritize_insertion_mode: String var default_icons: Array var tags: Tags @@ -3167,57 +3173,57 @@ external interface LuaItemStack { var entity_filter_mode: entity_filter_mode var tile_filter_mode: tile_filter_mode var tile_selection_mode: tile_selection_mode - var trees_and_rocks_only: Boolean + var trees_and_rocks_only: Boolean? var entity_filter_count: uint var tile_filter_count: uint var active_index: uint? var item_number: uint? var connected_entity: LuaEntity? - var is_blueprint: Boolean - var is_blueprint_book: Boolean - var is_module: Boolean - var is_tool: Boolean - var is_mining_tool: Boolean - var is_armor: Boolean - var is_repair_tool: Boolean - var is_item_with_label: Boolean - var is_item_with_inventory: Boolean - var is_item_with_entity_data: Boolean - var is_selection_tool: Boolean - var is_item_with_tags: Boolean - var is_deconstruction_item: Boolean - var is_upgrade_item: Boolean - var valid: Boolean + var is_blueprint: Boolean? + var is_blueprint_book: Boolean? + var is_module: Boolean? + var is_tool: Boolean? + var is_mining_tool: Boolean? + var is_armor: Boolean? + var is_repair_tool: Boolean? + var is_item_with_label: Boolean? + var is_item_with_inventory: Boolean? + var is_item_with_entity_data: Boolean? + var is_selection_tool: Boolean? + var is_item_with_tags: Boolean? + var is_deconstruction_item: Boolean? + var is_upgrade_item: Boolean? + var valid: Boolean? var object_name: String /* "LuaItemStack" */ fun help(): String } external interface LuaLampControlBehavior : LuaGenericOnOffControlBehavior { - var use_colors: Boolean + var use_colors: Boolean? var color: ColorTable? - override var valid: Boolean + override var valid: Boolean? override var object_name: String /* "LuaLampControlBehavior" */ override fun help(): String } external interface LuaLazyLoadedValue { fun get(): T - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaLazyLoadedValue" */ fun help(): String } external interface LuaLogisticCell { - fun is_in_logistic_range(position: Position): Boolean - fun is_in_construction_range(position: Position): Boolean - fun is_neighbour_with(other: LuaLogisticCell): Boolean + fun is_in_logistic_range(position: Position): Boolean? + fun is_in_construction_range(position: Position): Boolean? + fun is_neighbour_with(other: LuaLogisticCell): Boolean? var logistic_radius: float var logistics_connection_distance: float var construction_radius: float var stationed_logistic_robot_count: uint var stationed_construction_robot_count: uint - var mobile: Boolean - var transmitting: Boolean + var mobile: Boolean? + var transmitting: Boolean? var charge_approach_distance: float var charging_robot_count: uint var to_charge_robot_count: uint @@ -3226,14 +3232,14 @@ external interface LuaLogisticCell { var neighbours: Array var charging_robots: Array var to_charge_robots: Array - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaLogisticCell" */ fun help(): String } external interface LuaLogisticContainerControlBehavior : LuaControlBehavior { var circuit_mode_of_operation: _defines_control_behavior_logistic_container_circuit_mode_of_operation - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaLogisticContainerControlBehavior" */ fun help(): String } @@ -3299,7 +3305,7 @@ external interface LuaLogisticNetwork { var robots: Array var construction_robots: Array var logistic_robots: Array - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaLogisticNetwork" */ fun help(): String } @@ -3313,18 +3319,18 @@ external interface LuaLogisticPoint { var force: LuaForce var targeted_items_pickup: Record var targeted_items_deliver: Record - var exact: Boolean - var valid: Boolean + var exact: Boolean? + var valid: Boolean? var object_name: String /* "LuaLogisticPoint" */ fun help(): String } external interface LuaMiningDrillControlBehavior : LuaGenericOnOffControlBehavior { - var circuit_enable_disable: Boolean - var circuit_read_resources: Boolean + var circuit_enable_disable: Boolean? + var circuit_read_resources: Boolean? var resource_read_mode: resource_read_mode var resource_read_targets: Array - override var valid: Boolean + override var valid: Boolean? override var object_name: String /* "LuaMiningDrillControlBehavior" */ override fun help(): String } @@ -3354,8 +3360,8 @@ external interface LuaModSettingPrototype { set(value) = definedExternally var allow_blank: Boolean? var auto_trim: Boolean? - var hidden: Boolean - var valid: Boolean + var hidden: Boolean? + var valid: Boolean? var object_name: String /* "LuaModSettingPrototype" */ fun help(): String } @@ -3369,7 +3375,7 @@ external interface LuaModuleCategoryPrototype { var localised_description: dynamic /* JsTuple | String | Number */ get() = definedExternally set(value) = definedExternally - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaModuleCategoryPrototype" */ fun help(): String } @@ -3385,7 +3391,7 @@ external interface LuaNamedNoiseExpression { set(value) = definedExternally var intended_property: String var expression: NoiseExpression - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaNamedNoiseExpression" */ fun help(): String } @@ -3399,7 +3405,7 @@ external interface LuaNoiseLayerPrototype { var localised_description: dynamic /* JsTuple | String | Number */ get() = definedExternally set(value) = definedExternally - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaNoiseLayerPrototype" */ fun help(): String } @@ -3426,25 +3432,25 @@ external interface LuaParticlePrototype { var movement_modifier_when_on_ground: float var movement_modifier: float var mining_particle_frame_speed: float - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaParticlePrototype" */ fun help(): String } external interface LuaPermissionGroup { - fun add_player(player: uint): Boolean - fun add_player(player: String): Boolean - fun add_player(player: LuaPlayer): Boolean - fun remove_player(player: uint): Boolean - fun remove_player(player: String): Boolean - fun remove_player(player: LuaPlayer): Boolean - fun allows_action(action: input_action): Boolean - fun set_allows_action(action: input_action, allow_action: Boolean): Boolean - fun destroy(): Boolean + fun add_player(player: uint): Boolean? + fun add_player(player: String): Boolean? + fun add_player(player: LuaPlayer): Boolean? + fun remove_player(player: uint): Boolean? + fun remove_player(player: String): Boolean? + fun remove_player(player: LuaPlayer): Boolean? + fun allows_action(action: input_action): Boolean? + fun set_allows_action(action: input_action, allow_action: Boolean): Boolean? + fun destroy(): Boolean? var name: String var players: Array var group_id: uint - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaPermissionGroup" */ fun help(): String } @@ -3454,7 +3460,7 @@ external interface LuaPermissionGroups { fun get_group(group: String): LuaPermissionGroup? fun get_group(group: uint): LuaPermissionGroup? var groups: Array - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaPermissionGroups" */ fun help(): String } @@ -3611,7 +3617,7 @@ external interface LuaPlayer : LuaControl { fun set_goal_description(text: Number = definedExternally, only_update: Boolean = definedExternally) fun set_goal_description(text: Number = definedExternally) fun set_controller(params: `T$47`) - fun drag_wire(params: `T$48`): Boolean + fun drag_wire(params: `T$48`): Boolean? fun disable_recipe_groups() fun enable_recipe_groups() fun disable_recipe_subgroups() @@ -3622,25 +3628,25 @@ external interface LuaPlayer : LuaControl { fun log_active_entity_chunk_counts() fun log_active_entity_counts() fun unlock_achievement(name: String) - fun clear_cursor(): Boolean - fun create_character(character: String = definedExternally): Boolean + fun clear_cursor(): Boolean? + fun create_character(character: String = definedExternally): Boolean? fun add_alert(entity: LuaEntity, type: alert_type) fun add_custom_alert(entity: LuaEntity, icon: SignalID, message: Any /* JsTuple */, show_on_map: Boolean) fun add_custom_alert(entity: LuaEntity, icon: SignalID, message: String, show_on_map: Boolean) fun add_custom_alert(entity: LuaEntity, icon: SignalID, message: Number, show_on_map: Boolean) fun remove_alert(params: `T$49`) fun get_alerts(params: `T$50`): Record>> - fun mute_alert(alert_type: alert_type): Boolean - fun unmute_alert(alert_type: alert_type): Boolean - fun is_alert_muted(alert_type: alert_type): Boolean - fun enable_alert(alert_type: alert_type): Boolean - fun disable_alert(alert_type: alert_type): Boolean - fun is_alert_enabled(alert_type: alert_type): Boolean - fun pipette_entity(entity: String): Boolean - fun pipette_entity(entity: LuaEntity): Boolean - fun pipette_entity(entity: LuaEntityPrototype): Boolean - fun can_place_entity(params: `T$51`): Boolean - fun can_build_from_cursor(params: `T$52`): Boolean + fun mute_alert(alert_type: alert_type): Boolean? + fun unmute_alert(alert_type: alert_type): Boolean? + fun is_alert_muted(alert_type: alert_type): Boolean? + fun enable_alert(alert_type: alert_type): Boolean? + fun disable_alert(alert_type: alert_type): Boolean? + fun is_alert_enabled(alert_type: alert_type): Boolean? + fun pipette_entity(entity: String): Boolean? + fun pipette_entity(entity: LuaEntity): Boolean? + fun pipette_entity(entity: LuaEntityPrototype): Boolean? + fun can_place_entity(params: `T$51`): Boolean? + fun can_build_from_cursor(params: `T$52`): Boolean? fun build_from_cursor(params: `T$52`) fun use_from_cursor(position: Position) fun play_sound(params: `T$34`) @@ -3659,15 +3665,15 @@ external interface LuaPlayer : LuaControl { fun open_map(position: Position, scale: double = definedExternally) fun zoom_to_world(position: Position, scale: double = definedExternally) fun close_map() - fun is_shortcut_toggled(prototype_name: String): Boolean - fun is_shortcut_available(prototype_name: String): Boolean + fun is_shortcut_toggled(prototype_name: String): Boolean? + fun is_shortcut_available(prototype_name: String): Boolean? fun set_shortcut_toggled(prototype_name: String, toggled: Boolean) fun set_shortcut_available(prototype_name: String, available: Boolean) fun connect_to_server(params: `T$54`) fun toggle_map_editor() - fun request_translation(localised_string: Any /* JsTuple */): Boolean - fun request_translation(localised_string: String): Boolean - fun request_translation(localised_string: Number): Boolean + fun request_translation(localised_string: Any /* JsTuple */): Boolean? + fun request_translation(localised_string: String): Boolean? + fun request_translation(localised_string: Number): Boolean? fun get_infinity_inventory_filter(index: uint): InfinityInventoryFilter? fun set_infinity_inventory_filter(index: uint, filter: InfinityInventoryFilter?) fun clear_recipe_notifications() @@ -3680,11 +3686,11 @@ external interface LuaPlayer : LuaControl { var cutscene_character: LuaEntity? var index: uint var gui: LuaGui - var opened_self: Boolean + var opened_self: Boolean? var controller_type: controllers var stashed_controller_type: controllers? var game_view_settings: GameViewSettings - var minimap_enabled: Boolean + var minimap_enabled: Boolean? var color: dynamic /* ColorTable | JsTuple */ get() = definedExternally set(value) = definedExternally @@ -3693,8 +3699,8 @@ external interface LuaPlayer : LuaControl { set(value) = definedExternally var name: String var tag: String - var connected: Boolean - var admin: Boolean + var connected: Boolean? + var admin: Boolean? var entity_copy_source: LuaEntity? var afk_time: uint var online_time: uint @@ -3706,10 +3712,10 @@ external interface LuaPlayer : LuaControl { var display_scale: double var blueprint_to_setup: LuaItemStack var render_mode: render_mode - var spectator: Boolean - var remove_unfiltered_items: Boolean + var spectator: Boolean? + var remove_unfiltered_items: Boolean? var infinity_inventory_filters: Array - var auto_sort_main_inventory: Boolean + var auto_sort_main_inventory: Boolean? var hand_location: ItemStackLocation } @@ -3719,7 +3725,7 @@ external interface LuaProfiler { fun restart() fun add(other: LuaProfiler) fun divide(number: double) - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaProfiler" */ fun help(): String } @@ -3727,7 +3733,7 @@ external interface LuaProfiler { external interface LuaProgrammableSpeakerControlBehavior : LuaControlBehavior { var circuit_parameters: ProgrammableSpeakerCircuitParameters var circuit_condition: CircuitConditionDefinition - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaProgrammableSpeakerControlBehavior" */ fun help(): String } @@ -3744,7 +3750,7 @@ external interface LuaRailChainSignalControlBehavior : LuaControlBehavior { var orange_signal: SignalID var green_signal: SignalID var blue_signal: SignalID - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaRailChainSignalControlBehavior" */ fun help(): String } @@ -3755,7 +3761,7 @@ external interface LuaRailPath { var total_distance: double var travelled_distance: double var rails: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaRailPath" */ fun help(): String } @@ -3764,10 +3770,10 @@ external interface LuaRailSignalControlBehavior : LuaControlBehavior { var red_signal: SignalID var orange_signal: SignalID var green_signal: SignalID - var close_signal: Boolean - var read_signal: Boolean + var close_signal: Boolean? + var read_signal: Boolean? var circuit_condition: CircuitConditionDefinition - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaRailSignalControlBehavior" */ fun help(): String } @@ -3776,7 +3782,7 @@ external interface LuaRandomGenerator { fun re_seed(seed: uint) @nativeInvoke operator fun invoke(lower: int = definedExternally, upper: int = definedExternally): double - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaRandomGenerator" */ fun help(): String } @@ -3791,18 +3797,18 @@ external interface LuaRecipe { get() = definedExternally set(value) = definedExternally var prototype: LuaRecipePrototype - var enabled: Boolean + var enabled: Boolean? var category: String var ingredients: Array var products: Array - var hidden: Boolean - var hidden_from_flow_stats: Boolean + var hidden: Boolean? + var hidden_from_flow_stats: Boolean? var energy: double var order: String var group: LuaGroup var subgroup: LuaGroup var force: LuaForce - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaRecipe" */ fun help(): String } @@ -3816,13 +3822,13 @@ external interface LuaRecipeCategoryPrototype { var localised_description: dynamic /* JsTuple | String | Number */ get() = definedExternally set(value) = definedExternally - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaRecipeCategoryPrototype" */ fun help(): String } external interface LuaRecipePrototype { - var enabled: Boolean + var enabled: Boolean? var name: String var localised_name: dynamic /* JsTuple | String | Number */ get() = definedExternally @@ -3836,32 +3842,32 @@ external interface LuaRecipePrototype { var main_product: dynamic /* FluidProduct? | OtherProduct? */ get() = definedExternally set(value) = definedExternally - var hidden: Boolean - var hidden_from_flow_stats: Boolean - var hidden_from_player_crafting: Boolean - var always_show_made_in: Boolean + var hidden: Boolean? + var hidden_from_flow_stats: Boolean? + var hidden_from_player_crafting: Boolean? + var always_show_made_in: Boolean? var energy: double var order: String var group: LuaGroup var subgroup: LuaGroup var request_paste_multiplier: uint var overload_multiplier: uint - var allow_inserter_overload: Boolean - var allow_as_intermediate: Boolean - var allow_intermediates: Boolean - var show_amount_in_title: Boolean - var always_show_products: Boolean + var allow_inserter_overload: Boolean? + var allow_as_intermediate: Boolean? + var allow_intermediates: Boolean? + var show_amount_in_title: Boolean? + var always_show_products: Boolean? var emissions_multiplier: double - var allow_decomposition: Boolean - var unlock_results: Boolean - var valid: Boolean + var allow_decomposition: Boolean? + var unlock_results: Boolean? + var valid: Boolean? var object_name: String /* "LuaRecipePrototype" */ fun help(): String } external interface LuaRemote { fun add_interface(name: String, functions: Record Unit>) - fun remove_interface(name: String): Boolean + fun remove_interface(name: String): Boolean? fun call(_interface: String, _function: String, vararg args: Any): Any var interfaces: Record> var object_name: String /* "LuaRemote" */ @@ -3975,7 +3981,7 @@ external interface `T$57` { var width: float? get() = definedExternally set(value) = definedExternally - var filled: Boolean + var filled: Boolean? var target: dynamic /* Position | LuaEntity */ get() = definedExternally set(value) = definedExternally @@ -4012,7 +4018,7 @@ external interface `T$58` { var width: float? get() = definedExternally set(value) = definedExternally - var filled: Boolean + var filled: Boolean? var left_top: dynamic /* Position | LuaEntity */ get() = definedExternally set(value) = definedExternally @@ -4299,8 +4305,8 @@ external interface LuaRendering { fun draw_light(params: `T$62`): uint64 fun draw_animation(params: `T$63`): uint64 fun destroy(id: uint64) - fun is_font_valid(font_name: String): Boolean - fun is_valid(id: uint64): Boolean + fun is_font_valid(font_name: String): Boolean? + fun is_valid(id: uint64): Boolean? fun get_all_ids(mod_name: String = definedExternally): Array fun clear(mod_name: String = definedExternally) fun get_type(id: uint64): String /* "text" | "line" | "circle" | "rectangle" | "arc" | "polygon" | "sprite" | "light" | "animation" */ @@ -4312,11 +4318,11 @@ external interface LuaRendering { fun set_forces(id: uint64, forces: Array) fun get_players(id: uint64): Array? fun set_players(id: uint64, players: Array) - fun get_visible(id: uint64): Boolean + fun get_visible(id: uint64): Boolean? fun set_visible(id: uint64, visible: Boolean) - fun get_draw_on_ground(id: uint64): Boolean + fun get_draw_on_ground(id: uint64): Boolean? fun set_draw_on_ground(id: uint64, draw_on_ground: Boolean) - fun get_only_in_alt_mode(id: uint64): Boolean + fun get_only_in_alt_mode(id: uint64): Boolean? fun set_only_in_alt_mode(id: uint64, only_in_alt_mode: Boolean) fun get_color(id: uint64): ColorTable? fun set_color(id: uint64, color: ColorTable) @@ -4389,14 +4395,14 @@ external interface LuaRendering { fun set_vertices(id: uint64, vertices: Array) fun get_sprite(id: uint64): dynamic /* String? | ? */ fun set_sprite(id: uint64, sprite: String) - fun set_sprite(id: uint64, sprite: ) +// fun set_sprite(id: uint64, sprite: ) fun get_x_scale(id: uint64): double? fun set_x_scale(id: uint64, x_scale: double) fun get_y_scale(id: uint64): double? fun set_y_scale(id: uint64, y_scale: double) fun get_render_layer(id: uint64): dynamic /* Number? | ? */ fun set_render_layer(id: uint64, render_layer: Number) - fun set_render_layer(id: uint64, render_layer: ) + fun set_render_layer(id: uint64, render_layer: String) fun get_orientation_target(id: uint64): ScriptRenderTarget? fun set_orientation_target(id: uint64, orientation_target: Position, orientation_target_offset: dynamic /* typealias Vector = dynamic */ = definedExternally) fun set_orientation_target(id: uint64, orientation_target: Position) @@ -4428,19 +4434,19 @@ external interface LuaResourceCategoryPrototype { var localised_description: dynamic /* JsTuple | String | Number */ get() = definedExternally set(value) = definedExternally - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaResourceCategoryPrototype" */ fun help(): String } external interface LuaRoboportControlBehavior : LuaControlBehavior { - var read_logistics: Boolean - var read_robot_stats: Boolean + var read_logistics: Boolean? + var read_robot_stats: Boolean? var available_logistic_output_signal: SignalID var total_logistic_output_signal: SignalID var available_construction_output_signal: SignalID var total_construction_output_signal: SignalID - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaRoboportControlBehavior" */ fun help(): String } @@ -4467,15 +4473,15 @@ external interface LuaShortcutPrototype { var action: String var item_to_spawn: LuaItemPrototype var technology_to_unlock: LuaTechnologyPrototype - var toggleable: Boolean + var toggleable: Boolean? var associated_control_input: String - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaShortcutPrototype" */ fun help(): String } external interface LuaStorageTankControlBehavior : LuaControlBehavior { - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaStorageTankControlBehavior" */ fun help(): String } @@ -4507,10 +4513,10 @@ external interface LuaStyle { var right_cell_padding: int var bottom_cell_padding: int var left_cell_padding: int - var horizontally_stretchable: Boolean - var vertically_stretchable: Boolean - var horizontally_squashable: Boolean - var vertically_squashable: Boolean + var horizontally_stretchable: Boolean? + var vertically_stretchable: Boolean? + var horizontally_squashable: Boolean? + var vertically_squashable: Boolean? var rich_text_setting: rich_text_setting var hovered_font_color: dynamic /* ColorTable | JsTuple */ get() = definedExternally @@ -4539,12 +4545,12 @@ external interface LuaStyle { set(value) = definedExternally var horizontal_spacing: int var vertical_spacing: int - var use_header_filler: Boolean + var use_header_filler: Boolean? var color: dynamic /* ColorTable | JsTuple */ get() = definedExternally set(value) = definedExternally var column_alignments: LuaCustomTableMembers /* LuaCustomTableMembers & CustomTableIndex */ - var single_line: Boolean + var single_line: Boolean? var extra_top_padding_when_activated: int var extra_bottom_padding_when_activated: int var extra_left_padding_when_activated: int @@ -4553,7 +4559,7 @@ external interface LuaStyle { var extra_bottom_margin_when_activated: int var extra_left_margin_when_activated: int var extra_right_margin_when_activated: int - var stretch_image_to_widget_size: Boolean + var stretch_image_to_widget_size: Boolean? var badge_font: String var badge_horizontal_spacing: int var default_badge_font_color: dynamic /* ColorTable | JsTuple */ @@ -5239,8 +5245,8 @@ external interface `T$85` { external interface LuaSurface { fun get_pollution(position: Position): double - fun can_place_entity(params: `T$64`): Boolean - fun can_fast_replace(params: `T$65`): Boolean + fun can_place_entity(params: `T$64`): Boolean? + fun can_fast_replace(params: `T$65`): Boolean? fun find_entity(entity: String, position: Position): LuaEntity? fun find_entities(area: BoundingBoxTable = definedExternally): Array fun find_entities(): Array @@ -5297,8 +5303,8 @@ external interface LuaSurface { fun set_tiles(tiles: Array, correct_tiles: Boolean = definedExternally, remove_colliding_entities: String = definedExternally, remove_colliding_decoratives: Boolean = definedExternally) fun pollute(source: Position, amount: double) fun get_chunks(): LuaChunkIterator - fun is_chunk_generated(position: ChunkPositionTable): Boolean - fun is_chunk_generated(position: Any /* JsTuple */): Boolean + fun is_chunk_generated(position: ChunkPositionTable): Boolean? + fun is_chunk_generated(position: Any /* JsTuple */): Boolean? fun request_to_generate_chunks(position: Position, radius: uint) fun force_generate_chunk_requests() fun set_chunk_generated_status(position: ChunkPositionTable, status: chunk_generated_status) @@ -5360,14 +5366,14 @@ external interface LuaSurface { fun get_script_area(key: uint = definedExternally): ScriptArea fun edit_script_area(id: uint, area: ScriptArea) fun add_script_area(area: ScriptArea): uint - fun remove_script_area(id: uint): Boolean + fun remove_script_area(id: uint): Boolean? fun get_script_positions(name: String = definedExternally): Array fun get_script_position(key: String = definedExternally): ScriptPosition fun get_script_position(): ScriptPosition fun get_script_position(key: uint = definedExternally): ScriptPosition fun edit_script_position(id: uint, area: ScriptPosition) fun add_script_position(area: ScriptPosition): uint - fun remove_script_position(id: uint): Boolean + fun remove_script_position(id: uint): Boolean? fun get_map_exchange_string(): String fun get_starting_area_radius(): double fun get_closest(position: Position, entities: Array): LuaEntity @@ -5390,15 +5396,15 @@ external interface LuaSurface { var name: String var index: uint var map_gen_settings: MapGenSettings - var generate_with_lab_tiles: Boolean - var always_day: Boolean + var generate_with_lab_tiles: Boolean? + var always_day: Boolean? var daytime: float var darkness: float var wind_speed: double var wind_orientation: RealOrientation var wind_orientation_change: double - var peaceful_mode: Boolean - var freeze_daytime: Boolean + var peaceful_mode: Boolean? + var freeze_daytime: Boolean? var ticks_per_day: uint var dusk: double var dawn: double @@ -5409,8 +5415,8 @@ external interface LuaSurface { var brightness_visual_weights: dynamic /* ColorModifierTable | JsTuple */ get() = definedExternally set(value) = definedExternally - var show_clouds: Boolean - var valid: Boolean + var show_clouds: Boolean? + var valid: Boolean? var object_name: String /* "LuaSurface" */ fun help(): String } @@ -5426,10 +5432,10 @@ external interface LuaTechnology { get() = definedExternally set(value) = definedExternally var prototype: LuaTechnologyPrototype - var enabled: Boolean - var visible_when_disabled: Boolean - var upgrade: Boolean - var researched: Boolean + var enabled: Boolean? + var visible_when_disabled: Boolean? + var upgrade: Boolean? + var researched: Boolean? var prerequisites: Record var research_unit_ingredients: Array var effects: Array @@ -5438,7 +5444,7 @@ external interface LuaTechnology { var order: String var level: uint var research_unit_count_formula: String? - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaTechnology" */ fun help(): String } @@ -5451,11 +5457,11 @@ external interface LuaTechnologyPrototype { var localised_description: dynamic /* JsTuple | String | Number */ get() = definedExternally set(value) = definedExternally - var enabled: Boolean - var hidden: Boolean - var visible_when_disabled: Boolean - var ignore_tech_cost_multiplier: Boolean - var upgrade: Boolean + var enabled: Boolean? + var hidden: Boolean? + var visible_when_disabled: Boolean? + var ignore_tech_cost_multiplier: Boolean? + var upgrade: Boolean? var prerequisites: Record var research_unit_ingredients: Array var effects: Array @@ -5465,15 +5471,15 @@ external interface LuaTechnologyPrototype { var level: uint var max_level: uint var research_unit_count_formula: String? - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaTechnologyPrototype" */ fun help(): String } external interface LuaTile { - fun collides_with(layer: String /* "ground-tile" | "water-tile" | "resource-layer" | "doodad-layer" | "floor-layer" | "item-layer" | "ghost-layer" | "object-layer" | "player-layer" | "train-layer" | "rail-layer" | "transport-belt-layer" | "not-setup" */): Boolean - fun collides_with(layer: ): Boolean - fun to_be_deconstructed(): Boolean + fun collides_with(layer: String /* "ground-tile" | "water-tile" | "resource-layer" | "doodad-layer" | "floor-layer" | "item-layer" | "ghost-layer" | "object-layer" | "player-layer" | "train-layer" | "rail-layer" | "transport-belt-layer" | "not-setup" */): Boolean? +// fun collides_with(layer: ): Boolean? + fun to_be_deconstructed(): Boolean? fun order_deconstruction(force: String, player: uint = definedExternally): LuaEntity? fun order_deconstruction(force: String): LuaEntity? fun order_deconstruction(force: String, player: String = definedExternally): LuaEntity? @@ -5495,13 +5501,13 @@ external interface LuaTile { var position: PositionTable var hidden_tile: String? var surface: LuaSurface - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaTile" */ fun help(): String } external interface `T$86` { - var minable: Boolean + var minable: Boolean? var miningtime: double var miningparticle: String? get() = definedExternally @@ -5526,15 +5532,15 @@ external interface LuaTilePrototype { var vehicle_friction_modifier: float var map_color: ColorTable var decorative_removal_probability: float - var automatic_neighbors: Boolean + var automatic_neighbors: Boolean? var allowed_neighbors: Record - var needs_correction: Boolean + var needs_correction: Boolean? var mineable_properties: `T$86` var next_direction: LuaTilePrototype? var items_to_place_this: Array - var can_be_part_of_blueprint: Boolean + var can_be_part_of_blueprint: Boolean? var emissions_per_second: double - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaTilePrototype" */ fun help(): String } @@ -5549,7 +5555,7 @@ external interface LuaTrain { fun insert(stack: ItemStackDefinition) fun insert(stack: LuaItemStack) fun clear_items_inside() - fun recalculate_path(force: Boolean = definedExternally): Boolean + fun recalculate_path(force: Boolean = definedExternally): Boolean? fun get_fluid_count(fluid: String = definedExternally): double fun get_fluid_contents(): Record fun remove_fluid(fluid: Fluid): double @@ -5557,7 +5563,7 @@ external interface LuaTrain { fun clear_fluids_inside() fun go_to_station(index: uint) fun get_rails(): Array - var manual_mode: Boolean + var manual_mode: Boolean? var speed: double var max_forward_speed: double var max_backward_speed: double @@ -5575,7 +5581,7 @@ external interface LuaTrain { var front_stock: LuaEntity? var back_stock: LuaEntity? var station: LuaEntity? - var has_path: Boolean + var has_path: Boolean? var path_end_rail: LuaEntity? var path_end_stop: LuaEntity? var id: uint @@ -5585,31 +5591,31 @@ external interface LuaTrain { var kill_count: uint var path: LuaRailPath? var signal: LuaEntity? - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaTrain" */ fun help(): String } external interface LuaTrainStopControlBehavior : LuaGenericOnOffControlBehavior { - var send_to_train: Boolean - var read_from_train: Boolean - var read_stopped_train: Boolean - var set_trains_limit: Boolean - var read_trains_count: Boolean - var enable_disable: Boolean + var send_to_train: Boolean? + var read_from_train: Boolean? + var read_stopped_train: Boolean? + var set_trains_limit: Boolean? + var read_trains_count: Boolean? + var enable_disable: Boolean? var stopped_train_signal: SignalID var trains_count_signal: SignalID var trains_limit_signal: SignalID - override var valid: Boolean + override var valid: Boolean? override var object_name: String /* "LuaTrainStopControlBehavior" */ override fun help(): String } external interface LuaTransportBeltControlBehavior : LuaGenericOnOffControlBehavior { - var enable_disable: Boolean - var read_contents: Boolean + var enable_disable: Boolean? + var read_contents: Boolean? var read_contents_mode: content_read_mode - override var valid: Boolean + override var valid: Boolean? override var object_name: String /* "LuaTransportBeltControlBehavior" */ override fun help(): String } @@ -5634,14 +5640,14 @@ external interface LuaTrivialSmokePrototype { var fade_away_duration: uint var fade_in_duration: uint var glow_fade_away_duration: uint - var cyclic: Boolean - var affected_by_wind: Boolean - var show_when_smoke_off: Boolean - var glow_animation: Boolean + var cyclic: Boolean? + var affected_by_wind: Boolean? + var show_when_smoke_off: Boolean? + var glow_animation: Boolean? var render_layer: dynamic /* Number | */ get() = definedExternally set(value) = definedExternally - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaTrivialSmokePrototype" */ fun help(): String } @@ -5675,14 +5681,14 @@ external interface LuaUnitGroup { var force: LuaForce var surface: LuaSurface var group_number: uint - var is_script_driven: Boolean + var is_script_driven: Boolean? var command: dynamic /* AttackCommand? | GoToLocationCommand? | CompoundCommand? | GroupCommand? | AttackAreaCommand? | WanderCommand? | StopCommand? | FleeCommand? | BuildBaseCommand? */ get() = definedExternally set(value) = definedExternally var distraction_command: dynamic /* AttackCommand? | GoToLocationCommand? | CompoundCommand? | GroupCommand? | AttackAreaCommand? | WanderCommand? | StopCommand? | FleeCommand? | BuildBaseCommand? */ get() = definedExternally set(value) = definedExternally - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaUnitGroup" */ fun help(): String } @@ -5696,28 +5702,28 @@ external interface LuaVirtualSignalPrototype { var localised_description: dynamic /* JsTuple | String | Number */ get() = definedExternally set(value) = definedExternally - var special: Boolean + var special: Boolean? var subgroup: LuaGroup - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaVirtualSignalPrototype" */ fun help(): String } external interface LuaVoidEnergySourcePrototype { var emissions: double - var render_no_network_icon: Boolean - var render_no_power_icon: Boolean - var valid: Boolean + var render_no_network_icon: Boolean? + var render_no_power_icon: Boolean? + var valid: Boolean? var object_name: String /* "LuaVoidEnergySourcePrototype" */ fun help(): String } external interface LuaWallControlBehavior : LuaControlBehavior { var circuit_condition: CircuitConditionDefinition - var open_gate: Boolean - var read_sensor: Boolean + var open_gate: Boolean? + var read_sensor: Boolean? var output_signal: SignalID - var valid: Boolean + var valid: Boolean? var object_name: String /* "LuaWallControlBehavior" */ fun help(): String } \ No newline at end of file diff --git a/modules/mod2/dukat-custom/coroutine.coroutine.module_lua-types.kt b/modules/mod2/dukat-custom/coroutine/coroutine.coroutine.module_lua-types.kt similarity index 100% rename from modules/mod2/dukat-custom/coroutine.coroutine.module_lua-types.kt rename to modules/mod2/dukat-custom/coroutine/coroutine.coroutine.module_lua-types.kt diff --git a/modules/mod2/dukat-custom/debug.debug.module_lua-types.kt b/modules/mod2/dukat-custom/debug/debug.debug.module_lua-types.kt similarity index 99% rename from modules/mod2/dukat-custom/debug.debug.module_lua-types.kt rename to modules/mod2/dukat-custom/debug/debug.debug.module_lua-types.kt index 7068d82..fd5215e 100644 --- a/modules/mod2/dukat-custom/debug.debug.module_lua-types.kt +++ b/modules/mod2/dukat-custom/debug/debug.debug.module_lua-types.kt @@ -27,8 +27,8 @@ external fun gethook(thread: LuaThread = definedExternally): dynamic /* JsTuple< external interface FunctionInfo> { var nparams: Number - var isvararg: Boolean - var istailcall: Boolean + var isvararg: Boolean? + var istailcall: Boolean? var func: T var name: String? get() = definedExternally diff --git a/modules/mod2/dukat-custom/defines.defines.control_behavior.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/control_behavior/defines.defines.control_behavior.module_typed-factorio.kt similarity index 100% rename from modules/mod2/dukat-custom/defines.defines.control_behavior.module_typed-factorio.kt rename to modules/mod2/dukat-custom/defines/control_behavior/defines.defines.control_behavior.module_typed-factorio.kt diff --git a/modules/mod2/dukat-custom/defines.defines.control_behavior.inserter.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/control_behavior/inserter/defines.defines.control_behavior.inserter.module_typed-factorio.kt similarity index 100% rename from modules/mod2/dukat-custom/defines.defines.control_behavior.inserter.module_typed-factorio.kt rename to modules/mod2/dukat-custom/defines/control_behavior/inserter/defines.defines.control_behavior.inserter.module_typed-factorio.kt diff --git a/modules/mod2/dukat-custom/defines.defines.control_behavior.lamp.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/control_behavior/lamp/defines.defines.control_behavior.lamp.module_typed-factorio.kt similarity index 100% rename from modules/mod2/dukat-custom/defines.defines.control_behavior.lamp.module_typed-factorio.kt rename to modules/mod2/dukat-custom/defines/control_behavior/lamp/defines.defines.control_behavior.lamp.module_typed-factorio.kt diff --git a/modules/mod2/dukat-custom/defines.defines.control_behavior.logistic_container.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/control_behavior/logistic_container/defines.defines.control_behavior.logistic_container.module_typed-factorio.kt similarity index 100% rename from modules/mod2/dukat-custom/defines.defines.control_behavior.logistic_container.module_typed-factorio.kt rename to modules/mod2/dukat-custom/defines/control_behavior/logistic_container/defines.defines.control_behavior.logistic_container.module_typed-factorio.kt diff --git a/modules/mod2/dukat-custom/defines.defines.control_behavior.mining_drill.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/control_behavior/mining_drill/defines.defines.control_behavior.mining_drill.module_typed-factorio.kt similarity index 100% rename from modules/mod2/dukat-custom/defines.defines.control_behavior.mining_drill.module_typed-factorio.kt rename to modules/mod2/dukat-custom/defines/control_behavior/mining_drill/defines.defines.control_behavior.mining_drill.module_typed-factorio.kt diff --git a/modules/mod2/dukat-custom/defines.defines.control_behavior.transport_belt.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/control_behavior/transport_belt/defines.defines.control_behavior.transport_belt.module_typed-factorio.kt similarity index 100% rename from modules/mod2/dukat-custom/defines.defines.control_behavior.transport_belt.module_typed-factorio.kt rename to modules/mod2/dukat-custom/defines/control_behavior/transport_belt/defines.defines.control_behavior.transport_belt.module_typed-factorio.kt diff --git a/modules/mod2/dukat-custom/defines.defines.deconstruction_item.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/deconstruction_item/defines.defines.deconstruction_item.module_typed-factorio.kt similarity index 100% rename from modules/mod2/dukat-custom/defines.defines.deconstruction_item.module_typed-factorio.kt rename to modules/mod2/dukat-custom/defines/deconstruction_item/defines.defines.deconstruction_item.module_typed-factorio.kt diff --git a/modules/mod2/dukat-custom/defines.defines.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/defines.defines.module_typed-factorio.kt similarity index 100% rename from modules/mod2/dukat-custom/defines.defines.module_typed-factorio.kt rename to modules/mod2/dukat-custom/defines/defines.defines.module_typed-factorio.kt diff --git a/modules/mod2/dukat-custom/defines.defines.difficulty_settings.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/difficulty_settings/defines.defines.difficulty_settings.module_typed-factorio.kt similarity index 100% rename from modules/mod2/dukat-custom/defines.defines.difficulty_settings.module_typed-factorio.kt rename to modules/mod2/dukat-custom/defines/difficulty_settings/defines.defines.difficulty_settings.module_typed-factorio.kt diff --git a/modules/mod2/dukat-custom/defines.defines.events.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/events/defines.defines.events.module_typed-factorio.kt similarity index 100% rename from modules/mod2/dukat-custom/defines.defines.events.module_typed-factorio.kt rename to modules/mod2/dukat-custom/defines/events/defines.defines.events.module_typed-factorio.kt diff --git a/modules/mod2/dukat-custom/defines.defines.riding.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/riding/defines.defines.riding.module_typed-factorio.kt similarity index 100% rename from modules/mod2/dukat-custom/defines.defines.riding.module_typed-factorio.kt rename to modules/mod2/dukat-custom/defines/riding/defines.defines.riding.module_typed-factorio.kt diff --git a/modules/mod2/dukat-custom/events.module_typed-factorio.kt b/modules/mod2/dukat-custom/events.module_typed-factorio.kt index 11d3550..497a8ff 100644 --- a/modules/mod2/dukat-custom/events.module_typed-factorio.kt +++ b/modules/mod2/dukat-custom/events.module_typed-factorio.kt @@ -37,7 +37,7 @@ external interface CustomInputEvent { external interface OnAiCommandCompletedEvent { var unit_number: uint var result: behavior_result - var was_distracted: Boolean + var was_distracted: Boolean? var name: Any var tick: uint } @@ -54,11 +54,11 @@ external interface OnAreaClonedEvent { var destination_force: LuaForce? get() = definedExternally set(value) = definedExternally - var clone_tiles: Boolean - var clone_entities: Boolean - var clone_decoratives: Boolean - var clear_destination_entities: Boolean - var clear_destination_decoratives: Boolean + var clone_tiles: Boolean? + var clone_entities: Boolean? + var clone_decoratives: Boolean? + var clear_destination_entities: Boolean? + var clear_destination_decoratives: Boolean? var name: Any var tick: uint } @@ -82,11 +82,11 @@ external interface OnBrushClonedEvent { var destination_force: LuaForce? get() = definedExternally set(value) = definedExternally - var clone_tiles: Boolean - var clone_entities: Boolean - var clone_decoratives: Boolean - var clear_destination_entities: Boolean - var clear_destination_decoratives: Boolean + var clone_tiles: Boolean? + var clone_entities: Boolean? + var clone_decoratives: Boolean? + var clear_destination_entities: Boolean? + var clear_destination_decoratives: Boolean? var name: Any var tick: uint } @@ -319,7 +319,7 @@ external interface OnEntityRenamedEvent { var player_index: uint? get() = definedExternally set(value) = definedExternally - var by_script: Boolean + var by_script: Boolean? var entity: LuaEntity var old_name: String var name: Any @@ -359,7 +359,7 @@ external interface OnEquipmentRemovedEvent { external interface OnForceCeaseFireChangedEvent { var force: LuaForce var other_force: LuaForce - var added: Boolean + var added: Boolean? var name: Any var tick: uint } @@ -373,7 +373,7 @@ external interface OnForceCreatedEvent { external interface OnForceFriendsChangedEvent { var force: LuaForce var other_force: LuaForce - var added: Boolean + var added: Boolean? var name: Any var tick: uint } @@ -419,9 +419,9 @@ external interface OnGuiClickEvent { set(value) = definedExternally var player_index: uint var button: mouse_button_type - var alt: Boolean - var control: Boolean - var shift: Boolean + var alt: Boolean? + var control: Boolean? + var shift: Boolean? var name: Any var tick: uint } @@ -459,9 +459,9 @@ external interface OnGuiConfirmedEvent { get() = definedExternally set(value) = definedExternally var player_index: uint - var alt: Boolean - var control: Boolean - var shift: Boolean + var alt: Boolean? + var control: Boolean? + var shift: Boolean? var name: Any var tick: uint } @@ -789,7 +789,7 @@ external interface OnPlayerDeconstructedAreaEvent { get() = definedExternally set(value) = definedExternally var item: String - var alt: Boolean + var alt: Boolean? var name: Any var tick: uint } @@ -842,7 +842,7 @@ external interface OnPlayerDroppedItemEvent { external interface OnPlayerFastTransferredEvent { var player_index: uint var entity: LuaEntity - var from_player: Boolean + var from_player: Boolean? var name: Any var tick: uint } @@ -852,7 +852,7 @@ external interface OnPlayerFlushedFluidEvent { var fluid: String var amount: double var entity: LuaEntity - var only_this_entity: Boolean + var only_this_entity: Boolean? var name: Any var tick: uint } @@ -928,7 +928,7 @@ external interface OnPlayerMutedEvent { external interface OnPlayerPipetteEvent { var player_index: uint var item: LuaItemPrototype - var used_cheat_mode: Boolean + var used_cheat_mode: Boolean? var name: Any var tick: uint } @@ -1012,7 +1012,7 @@ external interface OnPlayerSetupBlueprintEvent { get() = definedExternally set(value) = definedExternally var item: String - var alt: Boolean + var alt: Boolean? var mapping: LuaLazyLoadedValue> var name: Any var tick: uint @@ -1020,7 +1020,7 @@ external interface OnPlayerSetupBlueprintEvent { external interface OnPlayerToggledAltModeEvent { var player_index: uint - var alt_mode: Boolean + var alt_mode: Boolean? var name: Any var tick: uint } @@ -1070,7 +1070,7 @@ external interface OnPlayerUsedSpiderRemoteEvent { var player_index: uint var vehicle: LuaEntity var position: Position - var success: Boolean + var success: Boolean? var name: Any var tick: uint } @@ -1099,11 +1099,11 @@ external interface OnPostEntityDiedEvent { external interface OnPreBuildEvent { var player_index: uint var position: Position - var shift_build: Boolean + var shift_build: Boolean? var direction: direction - var flip_horizontal: Boolean - var flip_vertical: Boolean - var created_by_moving: Boolean + var flip_horizontal: Boolean? + var flip_vertical: Boolean? + var created_by_moving: Boolean? var name: Any var tick: uint } @@ -1223,14 +1223,14 @@ external interface OnPreSurfaceDeletedEvent { external interface OnResearchFinishedEvent { var research: LuaTechnology - var by_script: Boolean + var by_script: Boolean? var name: Any var tick: uint } external interface OnResearchReversedEvent { var research: LuaTechnology - var by_script: Boolean + var by_script: Boolean? var name: Any var tick: uint } @@ -1361,7 +1361,7 @@ external interface OnScriptPathRequestFinishedEvent { get() = definedExternally set(value) = definedExternally var id: uint - var try_again_later: Boolean + var try_again_later: Boolean? var name: Any var tick: uint } @@ -1418,7 +1418,7 @@ external interface OnStringTranslatedEvent { get() = definedExternally set(value) = definedExternally var result: String - var translated: Boolean + var translated: Boolean? var name: Any var tick: uint } diff --git a/modules/mod2/dukat-custom/global.module_lua-types.kt b/modules/mod2/dukat-custom/global.module_lua-types.kt index e25a73e..1a0a17e 100644 --- a/modules/mod2/dukat-custom/global.module_lua-types.kt +++ b/modules/mod2/dukat-custom/global.module_lua-types.kt @@ -48,7 +48,7 @@ external fun ipairs(t: Record): Iterable | JsTuple<> */ -external fun pairs(t: LuaTable): Iterable> */> /* Iterable> */> & LuaIterator> */, undefined> & LuaExtension */ +external fun pairs(t: LuaTable): Iterable> */> /* Iterable> */> & LuaIterator> */, undefined> & LuaExtension */ external fun pairs(t: T): Iterable> */> /* Iterable> */> & LuaIterator> */, undefined> & LuaExtension */ diff --git a/modules/mod2/dukat-custom/index.module_typescript-to-lua.kt b/modules/mod2/dukat-custom/index.module_typescript-to-lua.kt index 25e92fc..cb772bd 100644 --- a/modules/mod2/dukat-custom/index.module_typescript-to-lua.kt +++ b/modules/mod2/dukat-custom/index.module_typescript-to-lua.kt @@ -22,7 +22,8 @@ external interface AnyNotNil typealias LuaExtension = Any -external var `$multi`: (values: T) -> T /* (values: T) -> T & LuaExtension */ +//external var `$multi`: (values: T) -> T /* (values: T) -> T & LuaExtension */ +external fun `$multi`(values: T): T /* (values: T) -> T & LuaExtension */ external var `$range`: (start: Number, limit: Number, step: Number) -> Iterable /* (start: Number, limit: Number, step: Number) -> Iterable & LuaExtension */ @@ -38,5 +39,5 @@ external interface LuaTable { var has: (key: TKey) -> Boolean /* (key: TKey) -> Boolean & LuaExtension */ var delete: (key: TKey) -> Boolean /* (key: TKey) -> Boolean & LuaExtension */ - companion object : Any by definedExternally +// companion object : Any by definedExternally } \ No newline at end of file diff --git a/modules/mod2/dukat-custom/io.module_lua-types.kt b/modules/mod2/dukat-custom/io.module_lua-types.kt index abe679d..af58374 100644 --- a/modules/mod2/dukat-custom/io.module_lua-types.kt +++ b/modules/mod2/dukat-custom/io.module_lua-types.kt @@ -21,7 +21,7 @@ external interface LuaFile { fun flush(): Boolean fun > lines(vararg formats: T): Iterable */> /* Iterable */> & LuaIterator */, undefined> & LuaExtension */ fun read(): FileReadFormatToType? - fun read(format: T): FileReadFormatToType? /* Any & LuaExtension */ + fun read(format: T): FileReadFormatToType? /* Any & LuaExtension */ fun seek(whence: String /* "set" | "cur" | "end" */ = definedExternally, offset: Number = definedExternally): dynamic /* JsTuple | JsTuple */ fun setvbuf(mode: String /* "no" | "full" | "line" */, size: Number = definedExternally) fun write(vararg args: Any /* String | Number */): dynamic /* JsTuple | JsTuple */ diff --git a/modules/mod2/dukat-custom/io.io.module_lua-types.kt b/modules/mod2/dukat-custom/io/io.io.module_lua-types.kt similarity index 94% rename from modules/mod2/dukat-custom/io.io.module_lua-types.kt rename to modules/mod2/dukat-custom/io/io.io.module_lua-types.kt index 80cd0cd..87ba8d5 100644 --- a/modules/mod2/dukat-custom/io.io.module_lua-types.kt +++ b/modules/mod2/dukat-custom/io/io.io.module_lua-types.kt @@ -42,7 +42,7 @@ external fun popen(prog: String, mode: String /* "r" | "w" */ = definedExternall external fun read(): FileReadFormatToType? -external fun read(format: T): FileReadFormatToType? /* Any & LuaExtension */ +external fun read(format: T): FileReadFormatToType? /* Any & LuaExtension */ external var stderr: LuaFile diff --git a/modules/mod2/dukat-custom/nonDeclarations.io.kt b/modules/mod2/dukat-custom/io/nonDeclarations.io.kt similarity index 100% rename from modules/mod2/dukat-custom/nonDeclarations.io.kt rename to modules/mod2/dukat-custom/io/nonDeclarations.io.kt diff --git a/modules/mod2/dukat-custom/librariesAndFunctions.module_typed-factorio.kt b/modules/mod2/dukat-custom/librariesAndFunctions.module_typed-factorio.kt index 547ceff..dec76ff 100644 --- a/modules/mod2/dukat-custom/librariesAndFunctions.module_typed-factorio.kt +++ b/modules/mod2/dukat-custom/librariesAndFunctions.module_typed-factorio.kt @@ -30,15 +30,15 @@ external interface SerpentOptions { var sortkeys: dynamic /* Boolean | (this: Unit, keys: Array, table: Any) -> Unit */ get() = definedExternally set(value) = definedExternally - var sparse: Boolean - var compact: Boolean - var fatal: Boolean - var nocode: Boolean - var nohuge: Boolean + var sparse: Boolean? + var compact: Boolean? + var fatal: Boolean? + var nocode: Boolean? + var nohuge: Boolean? var maxlevel: Number var maxnum: Number var maxlength: Number - var metatostring: Boolean + var metatostring: Boolean? var numformat: String var valignore: Array var keyallow: Array diff --git a/modules/mod2/dukat-custom/math.math.module_lua-types.kt b/modules/mod2/dukat-custom/math/math.math.module_lua-types.kt similarity index 100% rename from modules/mod2/dukat-custom/math.math.module_lua-types.kt rename to modules/mod2/dukat-custom/math/math.math.module_lua-types.kt diff --git a/modules/mod2/dukat-custom/metatable.module_lua-types.kt b/modules/mod2/dukat-custom/metatable.module_lua-types.kt index c538a64..654ca6c 100644 --- a/modules/mod2/dukat-custom/metatable.module_lua-types.kt +++ b/modules/mod2/dukat-custom/metatable.module_lua-types.kt @@ -15,8 +15,10 @@ import org.w3c.workers.* import org.w3c.xhr.* external interface LuaMetatable { - val __pairs: ((t: T) -> dynamic)? - val __ipairs: ((t: T) -> dynamic)? +// val __pairs: ((t: T) -> dynamic)? +// val __ipairs: ((t: T) -> dynamic)? + fun __pairs(t: T): dynamic + fun __ipairs(t: T): dynamic val __add: ((operand: Any) -> Any)? val __sub: ((operand: Any) -> Any)? val __mul: ((operand: Any) -> Any)? diff --git a/modules/mod2/dukat-custom/mod-gui.mod_gui.module_typed-factorio.kt b/modules/mod2/dukat-custom/mod_gui/mod-gui.mod_gui.module_typed-factorio.kt similarity index 100% rename from modules/mod2/dukat-custom/mod-gui.mod_gui.module_typed-factorio.kt rename to modules/mod2/dukat-custom/mod_gui/mod-gui.mod_gui.module_typed-factorio.kt diff --git a/modules/mod2/dukat-custom/os.module_lua-types.kt b/modules/mod2/dukat-custom/os.module_lua-types.kt index a6818b4..8f6fe7b 100644 --- a/modules/mod2/dukat-custom/os.module_lua-types.kt +++ b/modules/mod2/dukat-custom/os.module_lua-types.kt @@ -39,7 +39,7 @@ external interface LuaDateInfoResult { var hour: Number var min: Number var sec: Number - var isdst: Boolean + var isdst: Boolean? var yday: Number var wday: Number } \ No newline at end of file diff --git a/modules/mod2/dukat-custom/os.os.module_lua-types.kt b/modules/mod2/dukat-custom/os/os.os.module_lua-types.kt similarity index 100% rename from modules/mod2/dukat-custom/os.os.module_lua-types.kt rename to modules/mod2/dukat-custom/os/os.os.module_lua-types.kt diff --git a/modules/mod2/dukat-custom/modules.package.module_lua-types.kt b/modules/mod2/dukat-custom/package/modules.package.module_lua-types.kt similarity index 100% rename from modules/mod2/dukat-custom/modules.package.module_lua-types.kt rename to modules/mod2/dukat-custom/package/modules.package.module_lua-types.kt diff --git a/modules/mod2/dukat-custom/librariesAndFunctions.serpent.module_typed-factorio.kt b/modules/mod2/dukat-custom/serpent/librariesAndFunctions.serpent.module_typed-factorio.kt similarity index 100% rename from modules/mod2/dukat-custom/librariesAndFunctions.serpent.module_typed-factorio.kt rename to modules/mod2/dukat-custom/serpent/librariesAndFunctions.serpent.module_typed-factorio.kt diff --git a/modules/mod2/dukat-custom/string.string.module_lua-types.kt b/modules/mod2/dukat-custom/string/string.string.module_lua-types.kt similarity index 100% rename from modules/mod2/dukat-custom/string.string.module_lua-types.kt rename to modules/mod2/dukat-custom/string/string.string.module_lua-types.kt diff --git a/modules/mod2/dukat-custom/table.table.module_lua-types.kt b/modules/mod2/dukat-custom/table/table.table.module_lua-types.kt similarity index 98% rename from modules/mod2/dukat-custom/table.table.module_lua-types.kt rename to modules/mod2/dukat-custom/table/table.table.module_lua-types.kt index 63cd957..f39ea86 100644 --- a/modules/mod2/dukat-custom/table.table.module_lua-types.kt +++ b/modules/mod2/dukat-custom/table/table.table.module_lua-types.kt @@ -1,6 +1,6 @@ @file:JsQualifier("table") @file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") -package table +package table2 import kotlin.js.* import org.khronos.webgl.* diff --git a/modules/mod2/dukat-custom/lib.dom.kt b/modules/mod2/dukat-custom/tsstdlib/lib.dom.kt similarity index 100% rename from modules/mod2/dukat-custom/lib.dom.kt rename to modules/mod2/dukat-custom/tsstdlib/lib.dom.kt diff --git a/modules/mod2/dukat-custom/lib.es2015.iterable.kt b/modules/mod2/dukat-custom/tsstdlib/lib.es2015.iterable.kt similarity index 98% rename from modules/mod2/dukat-custom/lib.es2015.iterable.kt rename to modules/mod2/dukat-custom/tsstdlib/lib.es2015.iterable.kt index fd548b7..41ccc71 100644 --- a/modules/mod2/dukat-custom/lib.es2015.iterable.kt +++ b/modules/mod2/dukat-custom/tsstdlib/lib.es2015.iterable.kt @@ -23,7 +23,7 @@ external interface IteratorYieldResult { } external interface IteratorReturnResult { - var done: Boolean + var done: Boolean? var value: TReturn } diff --git a/modules/mod2/dukat-custom/lib.es5.kt b/modules/mod2/dukat-custom/tsstdlib/lib.es5.kt similarity index 100% rename from modules/mod2/dukat-custom/lib.es5.kt rename to modules/mod2/dukat-custom/tsstdlib/lib.es5.kt diff --git a/modules/mod2/dukat-custom/types.module_typed-factorio.kt b/modules/mod2/dukat-custom/types.module_typed-factorio.kt index 11d34eb..3b00bbe 100644 --- a/modules/mod2/dukat-custom/types.module_typed-factorio.kt +++ b/modules/mod2/dukat-custom/types.module_typed-factorio.kt @@ -35,7 +35,7 @@ external interface BaseSettingDefinition { external interface BoolSettingDefinition : BaseSettingDefinition { override var type: String /* "bool-setting" */ - var default_value: Boolean + var default_value: Boolean? var forced_value: Boolean? get() = definedExternally set(value) = definedExternally diff --git a/modules/mod2/dukat-custom/util.util.table.module_typed-factorio.kt b/modules/mod2/dukat-custom/util/table/util.util.table.module_typed-factorio.kt similarity index 100% rename from modules/mod2/dukat-custom/util.util.table.module_typed-factorio.kt rename to modules/mod2/dukat-custom/util/table/util.util.table.module_typed-factorio.kt diff --git a/modules/mod2/dukat-custom/util.util.module_typed-factorio.kt b/modules/mod2/dukat-custom/util/util.util.module_typed-factorio.kt similarity index 84% rename from modules/mod2/dukat-custom/util.util.module_typed-factorio.kt rename to modules/mod2/dukat-custom/util/util.util.module_typed-factorio.kt index 843ae01..ed78e1c 100644 --- a/modules/mod2/dukat-custom/util.util.module_typed-factorio.kt +++ b/modules/mod2/dukat-custom/util/util.util.module_typed-factorio.kt @@ -3,6 +3,7 @@ @file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") package util +import AnyNotNil import kotlin.js.* import org.khronos.webgl.* import org.w3c.dom.* @@ -49,15 +50,13 @@ external fun multiply_color(c1: ColorTable, n: Number): dynamic /* JsTuple */, n: Number): dynamic /* JsTuple */ -external fun moveposition(position: Position, direction: defines.direction.north, distance: Number): Position +external fun moveposition(position: Position, direction: defines.direction, distance: Number): Position? +//external fun moveposition(position: Position, direction: defines.direction.north, distance: Number): Position +//external fun moveposition(position: Position, direction: defines.direction.east, distance: Number): Position +//external fun moveposition(position: Position, direction: defines.direction.south, distance: Number): Position +//external fun moveposition(position: Position, direction: defines.direction.west, distance: Number): Position -external fun moveposition(position: Position, direction: defines.direction.east, distance: Number): Position - -external fun moveposition(position: Position, direction: defines.direction.south, distance: Number): Position - -external fun moveposition(position: Position, direction: defines.direction.west, distance: Number): Position - -external fun moveposition(position: Position, direction: direction, distance: Number): Position? +//external fun moveposition(position: Position, direction: direction, distance: Number): Position? external fun oppositedirection(direction: direction): direction @@ -108,4 +107,4 @@ external fun remove_from_list(list: Array, value: T): Boolean external fun list_to_map(list: Array): dynamic /* Record | LuaTable */ -external fun list_to_map(list: T): LuaTable \ No newline at end of file +external fun list_to_map(list: T): LuaTable \ No newline at end of file From 17b4fc3b9a5089f5d729a77baecb11c5488066a4 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 13 Oct 2021 21:29:21 +0200 Subject: [PATCH 009/629] set up tstl factorio mod, and auto deploy stuff. A bit of mucking around with kotlin/js & dukat but it didn't go anywhere. Add a license. --- LICENSE | 24 + .../factoriowebmap/archetype/base.gradle.kts | 6 +- .../archetype/kotlin-js.gradle.kts | 13 +- .../factoriowebmap/archetype/node.gradle.kts | 23 + modules/mod/build.gradle.kts | 104 +- modules/mod/src/events.ts | 19 - .../resources/mod-data}/changelog.txt | 0 .../{ => main/resources/mod-data}/info.json | 2 +- .../resources/mod-data}/thumbnail.png | Bin .../mod/src/{ => main/typescript}/control.ts | 0 modules/mod/src/main/typescript/events.ts | 30 + .../{ => main/typescript}/package-lock.json | 19 - .../src/{ => main/typescript}/package.json | 0 .../src/{ => main/typescript}/tsconfig.json | 0 .../test/resources/server}/docker-compose.yml | 2 +- .../test/data/config/map-gen-settings.json | 78 + .../mod/test/data/config/map-settings.json | 120 + modules/mod/test/data/config/rconpw | 1 + .../mod/test/data/config/server-settings.json | 69 + modules/mod/test/data/mods/mod-list.json | 11 + modules/mod/test/data/player-data.json | 532 + modules/mod2/build.gradle.kts | 6 + .../builtin-types.module_typed-factorio.kt | 12 - .../classes.module_typed-factorio.kt | 6 +- ...es.defines.events.module_typed-factorio.kt | 4 +- modules/mod2/dukat-custom/eventId.kt | 11 + .../dukat-custom/global.module_lua-types.kt | 42 +- modules/mod2/dukat-custom/tsstdlib/lib.es5.kt | 4 +- modules/mod2/src/main/kotlin/events.kt | 11 + modules/mod2/typed-factorio/README.md | 113 + modules/mod2/typed-factorio/data/types.d.ts | 13 + .../generated/builtin-types.d.ts | 66 + .../typed-factorio/generated/classes.d.ts | 20023 ++++++++++++++++ .../typed-factorio/generated/concepts.d.ts | 5635 +++++ .../typed-factorio/generated/defines.d.ts | 1642 ++ .../mod2/typed-factorio/generated/events.d.ts | 2976 +++ .../generated/global-objects.d.ts | 51 + .../mod2/typed-factorio/generated/index.d.ts | 7 + modules/mod2/typed-factorio/package.json | 39 + .../mod2/typed-factorio/runtime/index.d.ts | 10 + .../runtime/librariesAndFunctions.d.ts | 123 + .../mod2/typed-factorio/runtime/mod-gui.d.ts | 11 + .../mod2/typed-factorio/runtime/pairs.d.ts | 13 + modules/mod2/typed-factorio/runtime/util.d.ts | 120 + .../mod2/typed-factorio/settings/types.d.ts | 120 + settings.gradle.kts | 4 +- src/jsMain/kotlin/factorio.kt | 3 - 47 files changed, 32006 insertions(+), 112 deletions(-) create mode 100644 LICENSE create mode 100644 buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts delete mode 100644 modules/mod/src/events.ts rename modules/mod/src/{ => main/resources/mod-data}/changelog.txt (100%) rename modules/mod/src/{ => main/resources/mod-data}/info.json (86%) rename modules/mod/src/{ => main/resources/mod-data}/thumbnail.png (100%) rename modules/mod/src/{ => main/typescript}/control.ts (100%) create mode 100644 modules/mod/src/main/typescript/events.ts rename modules/mod/src/{ => main/typescript}/package-lock.json (98%) rename modules/mod/src/{ => main/typescript}/package.json (100%) rename modules/mod/src/{ => main/typescript}/tsconfig.json (100%) rename modules/mod/{test => src/test/resources/server}/docker-compose.yml (90%) create mode 100644 modules/mod/test/data/config/map-gen-settings.json create mode 100644 modules/mod/test/data/config/map-settings.json create mode 100644 modules/mod/test/data/config/rconpw create mode 100644 modules/mod/test/data/config/server-settings.json create mode 100644 modules/mod/test/data/mods/mod-list.json create mode 100644 modules/mod/test/data/player-data.json create mode 100644 modules/mod2/dukat-custom/eventId.kt create mode 100644 modules/mod2/src/main/kotlin/events.kt create mode 100644 modules/mod2/typed-factorio/README.md create mode 100644 modules/mod2/typed-factorio/data/types.d.ts create mode 100644 modules/mod2/typed-factorio/generated/builtin-types.d.ts create mode 100644 modules/mod2/typed-factorio/generated/classes.d.ts create mode 100644 modules/mod2/typed-factorio/generated/concepts.d.ts create mode 100644 modules/mod2/typed-factorio/generated/defines.d.ts create mode 100644 modules/mod2/typed-factorio/generated/events.d.ts create mode 100644 modules/mod2/typed-factorio/generated/global-objects.d.ts create mode 100644 modules/mod2/typed-factorio/generated/index.d.ts create mode 100644 modules/mod2/typed-factorio/package.json create mode 100644 modules/mod2/typed-factorio/runtime/index.d.ts create mode 100644 modules/mod2/typed-factorio/runtime/librariesAndFunctions.d.ts create mode 100644 modules/mod2/typed-factorio/runtime/mod-gui.d.ts create mode 100644 modules/mod2/typed-factorio/runtime/pairs.d.ts create mode 100644 modules/mod2/typed-factorio/runtime/util.d.ts create mode 100644 modules/mod2/typed-factorio/settings/types.d.ts delete mode 100644 src/jsMain/kotlin/factorio.kt diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0804e5f --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +COPYRIGHT (C) LIMITED USE SOFTWARE LICENSE AGREEMENT + +All rights are reserved by the copyright holder. + +Permission is granted to use this software as a Factorio mod. + +Permission is granted distribute this software under the +condition that the distribution is publicly accessible, +and no payment or registration is required. Additionally, +all distributions must include the full source code of the +software, without restrictions or limitations. + +Permission is granted to make modifications to this software +under the condition that any claim of ownership is +relinquished, and any modification becomes the property of +the original copyright holder of this software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +For more information contact fredthedeadhead@gmail.com diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts index 02ed00f..555967c 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/base.gradle.kts @@ -4,11 +4,11 @@ plugins { base } -group = rootProject.group.toString() + "." + project.name +group = "${rootProject.group}.${project.name}" version = rootProject.version -val projectId by extra(rootProject.name + "-" + project.name) -val modBuildDir by extra(layout.buildDirectory.dir(projectId).get()) +val projectId by extra("${rootProject.name}-${project.name}") +//val modBuildDir by extra(layout.buildDirectory.dir(projectId).get()) //group = "dev.adamko.factoriowebmap" //version = "0.0.1" diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts index 176bf65..2dcac1b 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts @@ -12,10 +12,11 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject plugins { kotlin("js") - id("com.github.node-gradle.node") - id("dev.adamko.factoriowebmap.archetype.base") + id("dev.adamko.factoriowebmap.archetype.node") } + + kotlin { js(IR) { @@ -47,16 +48,18 @@ val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) //fun NpmTask.setNodeModulesPath(folder: File): Unit = // setNodeModulesPath(folder.normalize().absolutePath) +// https://github.com/node-gradle/gradle-node-plugin/issues/150 +// https://github.com/lamba92/kotlingram/blob/master/examples/js-bot/build.gradle.kts val nodePath: Directory by extra { val file = rootPackageJson.rootPackageJson.parentFile.normalize() - logger.lifecycle("Found root NODE_PATH: $file") + logger.lifecycle("Kotlin/JS NODE_PATH: $file") project.layout.dir(provider { file }).get() } val nodeModulesDir: Directory by extra { val file = nodePath.dir(NpmProject.NODE_MODULES) - logger.lifecycle("Found root NODE_MODULES: $file") + logger.lifecycle("Kotlin/JS NODE_MODULES: $file") file } @@ -66,7 +69,7 @@ node { distBaseUrl.set(null as String?) // set by dependencyResolutionManagement - nodeProjectDir.set(nodePath) +// nodeProjectDir.set(nodePath) // nodeProjectDir.set(packageJson.packageJson.parentFile.normalize()) } diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts new file mode 100644 index 0000000..cb83376 --- /dev/null +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/node.gradle.kts @@ -0,0 +1,23 @@ +package dev.adamko.factoriowebmap.archetype + +import org.gradle.kotlin.dsl.kotlin +import com.github.gradle.node.npm.task.NpmTask +import com.github.gradle.node.task.NodeTask +import org.jetbrains.kotlin.gradle.targets.js.dukat.DtsResolver +import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask +import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask +import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs +import org.jetbrains.kotlin.gradle.targets.js.npm.NpmProject + +plugins { + id("com.github.node-gradle.node") + id("dev.adamko.factoriowebmap.archetype.base") +} + +node { + download.set(true) + version.set("14.18.0") + + distBaseUrl.set(null as String?) // set by dependencyResolutionManagement +} + diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index 742c8f3..5124676 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -1,28 +1,22 @@ import com.github.gradle.node.npm.task.NpmTask +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { - base - id("com.github.node-gradle.node") + id("dev.adamko.factoriowebmap.archetype.node") } -group = "${rootProject.group}.mod" -version = rootProject.version +val projectId: String by project.extra + + +val tsSrcDir = layout.projectDirectory.dir("src/main/typescript") +val modBuildDir = layout.buildDirectory.dir(projectId).get() node { - download.set(true) - version.set("14.18.0") - - nodeProjectDir.set(layout.projectDirectory.dir("src")) - - distBaseUrl.set(null as String?) // set root dependencyResolutionManagement + nodeProjectDir.set(tsSrcDir) } -val projectId = rootProject.name + "-" + project.name -val modBuildDir = layout.buildDirectory.dir(projectId).get() -//val tsSrcDir = layout.projectDirectory.dir("src") - -val tstlTask = tasks.register("tstl") { +val tstlTask = tasks.register("typescriptToLua") { description = "Typescript To Lua" group = projectId @@ -30,15 +24,25 @@ val tstlTask = tasks.register("tstl") { execOverrides { standardOutput = System.out } - npmCommand.set(listOf("run", "build")) + npmCommand.set(listOf( + "run", + "build", +// "--workspace=factorio-web-map-mod", + )) - val outputDir = modBuildDir.dir("tstl") - args.set(parseSpaceSeparatedArgs("-- --outDir $outputDir")) + inputs.dir(node.nodeProjectDir) + + val outputDir = modBuildDir.dir("typescriptToLua") outputs.dir(outputDir) + args.set(parseSpaceSeparatedArgs("-- --outDir $outputDir")) +// args.set(listOf( +// "--", +// "--outDir $outputDir", +// "--workspace=factorio-web-map-mod", +// )) ignoreExitValue.set(false) // workingDir.set(tsSrcDir.asFile) - inputs.dir(node.nodeProjectDir) // inputs.dir("node_modules") // inputs.dir(fileTree("src")) // inputs.files( @@ -56,18 +60,62 @@ val modPackageTask = tasks.register("package") { dependsOn(tstlTask) - from(layout.projectDirectory.dir("src")) { - exclude("*.ts") - into(rootProject.name) - } - from(tstlTask) { - into(rootProject.name) - } + from( + layout.projectDirectory.dir("src/main/resources/mod-data"), + rootProject.layout.projectDirectory.file("LICENSE"), + tstlTask, + ) + into(rootProject.name) + + // Factorio required format is: + // - filename: `mod-name_version.zip` + // - zip contains dir `mod-name` archiveFileName.set("${rootProject.name}_${rootProject.version}.zip") destinationDirectory.set(modBuildDir.dir("dist")) - } -tasks.build { dependsOn(tstlTask, modPackageTask) } +//tasks.build { dependsOn(tstlTask, modPackageTask) } +val copyModToServerTask = tasks.register("copyModToServer") { + description = "Copy the mod to the Factorio Docker server" + group = projectId + + dependsOn(modPackageTask) + + from(modPackageTask) + into(layout.projectDirectory.dir("src/test/resources/server/data/mods").asFile) +} + +val copyModToClientTask = tasks.register("copyModToClient") { + description = "Copy the mod to the Factorio client" + group = projectId + + dependsOn(modPackageTask) + + from(modPackageTask) + into("""D:\Users\Adam\AppData\Roaming\Factorio\mods""") +} + +val serverRestartTask = tasks.register("serverRestart") { + group = projectId + + workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile + commandLine = parseSpaceSeparatedArgs("docker-compose restart") +} + +tasks.register("serverStop") { + group = projectId + + workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile + commandLine = parseSpaceSeparatedArgs("docker-compose stop") +} + +val launch = tasks.register("modLauncher") { + group = projectId + dependsOn( + copyModToServerTask, + copyModToClientTask, + serverRestartTask, + ) +} diff --git a/modules/mod/src/events.ts b/modules/mod/src/events.ts deleted file mode 100644 index dc2b9b5..0000000 --- a/modules/mod/src/events.ts +++ /dev/null @@ -1,19 +0,0 @@ -script.on_event( - [defines.events.on_pre_build, defines.events.on_player_dropped_item], - (e: OnPreBuildEvent | OnPlayerDroppedItemEvent) => { - game.print("player " + e.player_index + " dropped item, tick:" + e.tick) - } -); - -script.on_event( - defines.events.on_tick, - (e: OnTickEvent) => { - if (e.tick % 60 == 0) { - game.print("test mod tick: " + e.tick) - } - } -); - -script.on_load(() => { - game.print("loaded Factorio Web Map!") -}); diff --git a/modules/mod/src/changelog.txt b/modules/mod/src/main/resources/mod-data/changelog.txt similarity index 100% rename from modules/mod/src/changelog.txt rename to modules/mod/src/main/resources/mod-data/changelog.txt diff --git a/modules/mod/src/info.json b/modules/mod/src/main/resources/mod-data/info.json similarity index 86% rename from modules/mod/src/info.json rename to modules/mod/src/main/resources/mod-data/info.json index f24f7d0..edb1777 100644 --- a/modules/mod/src/info.json +++ b/modules/mod/src/main/resources/mod-data/info.json @@ -1,6 +1,6 @@ { "name": "factorio-web-map", - "version": "0.0.1", + "version": "0.0.2", "title": "Factorio Web Map", "author": "fredthedeadhead", "factorio_version": "1.1", diff --git a/modules/mod/src/thumbnail.png b/modules/mod/src/main/resources/mod-data/thumbnail.png similarity index 100% rename from modules/mod/src/thumbnail.png rename to modules/mod/src/main/resources/mod-data/thumbnail.png diff --git a/modules/mod/src/control.ts b/modules/mod/src/main/typescript/control.ts similarity index 100% rename from modules/mod/src/control.ts rename to modules/mod/src/main/typescript/control.ts diff --git a/modules/mod/src/main/typescript/events.ts b/modules/mod/src/main/typescript/events.ts new file mode 100644 index 0000000..946f1b9 --- /dev/null +++ b/modules/mod/src/main/typescript/events.ts @@ -0,0 +1,30 @@ +script.on_event( + [defines.events.on_pre_build, defines.events.on_player_dropped_item], + (e: OnPreBuildEvent | OnPlayerDroppedItemEvent) => { + game.print("player " + e.player_index + " dropped item, tick:" + e.tick) + } +); + +script.on_event( + defines.events.on_tick, + (e: OnTickEvent) => { + if (e.tick % 60 == 0) { + let msg = "test mod tick: " + e.tick + "\n" + // game.print(msg) + game.write_file("tick.log", msg, true) + + + let groups = game.permissions.groups.map(val => { + return val.name + "\n" + serpent.block(val) + }).join("\n") + + game.write_file("permissions.json", groups, false) + // game.write_file("permissions-groups.json", serpent.block(game.permissions.groups), false) + } + } +); + + +// script.on_load(() => { +// game.print("loaded Factorio Web Map!") +// }); diff --git a/modules/mod/src/package-lock.json b/modules/mod/src/main/typescript/package-lock.json similarity index 98% rename from modules/mod/src/package-lock.json rename to modules/mod/src/main/typescript/package-lock.json index 403b9ef..d5b6264 100644 --- a/modules/mod/src/package-lock.json +++ b/modules/mod/src/main/typescript/package-lock.json @@ -907,16 +907,6 @@ "object-assign": "^4.1.1" } }, - "react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" - } - }, "rechoir": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", @@ -962,15 +952,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, "schema-utils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", diff --git a/modules/mod/src/package.json b/modules/mod/src/main/typescript/package.json similarity index 100% rename from modules/mod/src/package.json rename to modules/mod/src/main/typescript/package.json diff --git a/modules/mod/src/tsconfig.json b/modules/mod/src/main/typescript/tsconfig.json similarity index 100% rename from modules/mod/src/tsconfig.json rename to modules/mod/src/main/typescript/tsconfig.json diff --git a/modules/mod/test/docker-compose.yml b/modules/mod/src/test/resources/server/docker-compose.yml similarity index 90% rename from modules/mod/test/docker-compose.yml rename to modules/mod/src/test/resources/server/docker-compose.yml index 5359a78..78bc9a8 100644 --- a/modules/mod/test/docker-compose.yml +++ b/modules/mod/src/test/resources/server/docker-compose.yml @@ -1,7 +1,7 @@ version: "3.9" services: factorio: - image: factoriotools/factorio:1.1.41 + image: factoriotools/factorio:1.1.42 # logging: # driver: "json-file" container_name: "factorio" diff --git a/modules/mod/test/data/config/map-gen-settings.json b/modules/mod/test/data/config/map-gen-settings.json new file mode 100644 index 0000000..7a2b412 --- /dev/null +++ b/modules/mod/test/data/config/map-gen-settings.json @@ -0,0 +1,78 @@ +{ + "_terrain_segmentation_comment": "The inverse of 'water scale' in the map generator GUI.", + "terrain_segmentation": 1, + + "_water_comment": + [ + "The equivalent to 'water coverage' in the map generator GUI. Higher coverage means more water in larger oceans.", + "Water level = 10 * log2(this value)" + ], + "water": 1, + + "_comment_width+height": "Width and height of map, in tiles; 0 means infinite", + "width": 0, + "height": 0, + + "_starting_area_comment": "Multiplier for 'biter free zone radius'", + "starting_area": 1, + + "peaceful_mode": false, + "autoplace_controls": + { + "coal": {"frequency": 1, "size": 1, "richness": 1}, + "stone": {"frequency": 1, "size": 1, "richness": 1}, + "copper-ore": {"frequency": 1, "size": 1,"richness": 1}, + "iron-ore": {"frequency": 1, "size": 1, "richness": 1}, + "uranium-ore": {"frequency": 1, "size": 1, "richness": 1}, + "crude-oil": {"frequency": 1, "size": 1, "richness": 1}, + "trees": {"frequency": 1, "size": 1, "richness": 1}, + "enemy-base": {"frequency": 1, "size": 1, "richness": 1} + }, + + "cliff_settings": + { + "_name_comment": "Name of the cliff prototype", + "name": "cliff", + + "_cliff_elevation_0_comment": "Elevation of first row of cliffs", + "cliff_elevation_0": 10, + + "_cliff_elevation_interval_comment": + [ + "Elevation difference between successive rows of cliffs.", + "This is inversely proportional to 'frequency' in the map generation GUI. Specifically, when set from the GUI the value is 40 / frequency." + ], + "cliff_elevation_interval": 40, + + "_richness_comment": "Called 'cliff continuity' in the map generator GUI. 0 will result in no cliffs, 10 will make all cliff rows completely solid", + "richness": 1 + }, + + "_property_expression_names_comment": + [ + "Overrides for property value generators (map type)", + "Leave 'elevation' blank to get 'normal' terrain.", + "Use 'elevation': '0_16-elevation' to reproduce terrain from 0.16.", + "Use 'elevation': '0_17-island' to get an island.", + "Moisture and terrain type are also controlled via this.", + "'control-setting:moisture:frequency:multiplier' is the inverse of the 'moisture scale' in the map generator GUI.", + "'control-setting:moisture:bias' is the 'moisture bias' in the map generator GUI.", + "'control-setting:aux:frequency:multiplier' is the inverse of the 'terrain type scale' in the map generator GUI.", + "'control-setting:aux:bias' is the 'terrain type bias' in the map generator GUI." + ], + "property_expression_names": + { + "control-setting:moisture:frequency:multiplier": "1", + "control-setting:moisture:bias": "0", + "control-setting:aux:frequency:multiplier": "1", + "control-setting:aux:bias": "0" + }, + + "starting_points": + [ + { "x": 0, "y": 0} + ], + + "_seed_comment": "Use null for a random seed, number for a specific seed.", + "seed": null +} diff --git a/modules/mod/test/data/config/map-settings.json b/modules/mod/test/data/config/map-settings.json new file mode 100644 index 0000000..62798d9 --- /dev/null +++ b/modules/mod/test/data/config/map-settings.json @@ -0,0 +1,120 @@ +{ + "difficulty_settings": + { + "recipe_difficulty": 0, + "technology_difficulty": 0, + "technology_price_multiplier": 1, + "research_queue_setting": "after-victory" + }, + "pollution": + { + "enabled": true, + "_comment_min_to_diffuse_1": "these are values for 60 ticks (1 simulated second)", + "_comment_min_to_diffuse_2": "amount that is diffused to neighboring chunk", + "diffusion_ratio": 0.02, + "min_to_diffuse": 15, + "ageing": 1, + "expected_max_per_chunk": 150, + "min_to_show_per_chunk": 50, + "min_pollution_to_damage_trees": 60, + "pollution_with_max_forest_damage": 150, + "pollution_per_tree_damage": 50, + "pollution_restored_per_tree_damage": 10, + "max_pollution_to_restore_trees": 20, + "enemy_attack_pollution_consumption_modifier": 1 + }, + "enemy_evolution": + { + "enabled": true, + "time_factor": 0.000004, + "destroy_factor": 0.002, + "pollution_factor": 0.0000009 + }, + "enemy_expansion": + { + "enabled": true, + "min_base_spacing": 3, + "max_expansion_distance": 7, + "friendly_base_influence_radius": 2, + "enemy_building_influence_radius": 2, + "building_coefficient": 0.1, + "other_base_coefficient": 2.0, + "neighbouring_chunk_coefficient": 0.5, + "neighbouring_base_chunk_coefficient": 0.4, + "max_colliding_tiles_coefficient": 0.9, + "settler_group_min_size": 5, + "settler_group_max_size": 20, + "min_expansion_cooldown": 14400, + "max_expansion_cooldown": 216000 + }, + "unit_group": + { + "min_group_gathering_time": 3600, + "max_group_gathering_time": 36000, + "max_wait_time_for_late_members": 7200, + "max_group_radius": 30.0, + "min_group_radius": 5.0, + "max_member_speedup_when_behind": 1.4, + "max_member_slowdown_when_ahead": 0.6, + "max_group_slowdown_factor": 0.3, + "max_group_member_fallback_factor": 3, + "member_disown_distance": 10, + "tick_tolerance_when_member_arrives": 60, + "max_gathering_unit_groups": 30, + "max_unit_group_size": 200 + }, + "steering": + { + "default": + { + "radius": 1.2, + "separation_force": 0.005, + "separation_factor": 1.2, + "force_unit_fuzzy_goto_behavior": false + }, + "moving": + { + "radius": 3, + "separation_force": 0.01, + "separation_factor": 3, + "force_unit_fuzzy_goto_behavior": false + } + }, + "path_finder": + { + "fwd2bwd_ratio": 5, + "goal_pressure_ratio": 2, + "max_steps_worked_per_tick": 100, + "max_work_done_per_tick": 8000, + "use_path_cache": true, + "short_cache_size": 5, + "long_cache_size": 25, + "short_cache_min_cacheable_distance": 10, + "short_cache_min_algo_steps_to_cache": 50, + "long_cache_min_cacheable_distance": 30, + "cache_max_connect_to_cache_steps_multiplier": 100, + "cache_accept_path_start_distance_ratio": 0.2, + "cache_accept_path_end_distance_ratio": 0.15, + "negative_cache_accept_path_start_distance_ratio": 0.3, + "negative_cache_accept_path_end_distance_ratio": 0.3, + "cache_path_start_distance_rating_multiplier": 10, + "cache_path_end_distance_rating_multiplier": 20, + "stale_enemy_with_same_destination_collision_penalty": 30, + "ignore_moving_enemy_collision_distance": 5, + "enemy_with_different_destination_collision_penalty": 30, + "general_entity_collision_penalty": 10, + "general_entity_subsequent_collision_penalty": 3, + "extended_collision_penalty": 3, + "max_clients_to_accept_any_new_request": 10, + "max_clients_to_accept_short_new_request": 100, + "direct_distance_to_consider_short_request": 100, + "short_request_max_steps": 1000, + "short_request_ratio": 0.5, + "min_steps_to_check_path_find_termination": 2000, + "start_to_goal_cost_multiplier_to_terminate_path_find": 500.0, + "overload_levels": [0, 100, 500], + "overload_multipliers": [2, 3, 4], + "negative_path_cache_delay_interval": 20 + }, + "max_failed_behavior_count": 3 +} diff --git a/modules/mod/test/data/config/rconpw b/modules/mod/test/data/config/rconpw new file mode 100644 index 0000000..581e57b --- /dev/null +++ b/modules/mod/test/data/config/rconpw @@ -0,0 +1 @@ +we3Sai7phaeFohc diff --git a/modules/mod/test/data/config/server-settings.json b/modules/mod/test/data/config/server-settings.json new file mode 100644 index 0000000..0bb77f5 --- /dev/null +++ b/modules/mod/test/data/config/server-settings.json @@ -0,0 +1,69 @@ +{ + "name": "Name of the game as it will appear in the game listing", + "description": "Description of the game that will appear in the listing", + "tags": ["game", "tags"], + + "_comment_max_players": "Maximum number of players allowed, admins can join even a full server. 0 means unlimited.", + "max_players": 0, + + "_comment_visibility": ["public: Game will be published on the official Factorio matching server", + "lan: Game will be broadcast on LAN"], + "visibility": + { + "public": true, + "lan": true + }, + + "_comment_credentials": "Your factorio.com login credentials. Required for games with visibility public", + "username": "", + "password": "", + + "_comment_token": "Authentication token. May be used instead of 'password' above.", + "token": "", + + "game_password": "", + + "_comment_require_user_verification": "When set to true, the server will only allow clients that have a valid Factorio.com account", + "require_user_verification": true, + + "_comment_max_upload_in_kilobytes_per_second" : "optional, default value is 0. 0 means unlimited.", + "max_upload_in_kilobytes_per_second": 0, + + "_comment_max_upload_slots" : "optional, default value is 5. 0 means unlimited.", + "max_upload_slots": 5, + + "_comment_minimum_latency_in_ticks": "optional one tick is 16ms in default speed, default value is 0. 0 means no minimum.", + "minimum_latency_in_ticks": 0, + + "_comment_ignore_player_limit_for_returning_players": "Players that played on this map already can join even when the max player limit was reached.", + "ignore_player_limit_for_returning_players": false, + + "_comment_allow_commands": "possible values are, true, false and admins-only", + "allow_commands": "admins-only", + + "_comment_autosave_interval": "Autosave interval in minutes", + "autosave_interval": 10, + + "_comment_autosave_slots": "server autosave slots, it is cycled through when the server autosaves.", + "autosave_slots": 5, + + "_comment_afk_autokick_interval": "How many minutes until someone is kicked when doing nothing, 0 for never.", + "afk_autokick_interval": 0, + + "_comment_auto_pause": "Whether should the server be paused when no players are present.", + "auto_pause": true, + + "only_admins_can_pause_the_game": true, + + "_comment_autosave_only_on_server": "Whether autosaves should be saved only on server or also on all connected clients. Default is true.", + "autosave_only_on_server": true, + + "_comment_non_blocking_saving": "Highly experimental feature, enable only at your own risk of losing your saves. On UNIX systems, server will fork itself to create an autosave. Autosaving on connected Windows clients will be disabled regardless of autosave_only_on_server option.", + "non_blocking_saving": false, + + "_comment_segment_sizes": "Long network messages are split into segments that are sent over multiple ticks. Their size depends on the number of peers currently connected. Increasing the segment size will increase upload bandwidth requirement for the server and download bandwidth requirement for clients. This setting only affects server outbound messages. Changing these settings can have a negative impact on connection stability for some clients.", + "minimum_segment_size": 25, + "minimum_segment_size_peer_count": 20, + "maximum_segment_size": 100, + "maximum_segment_size_peer_count": 10 +} diff --git a/modules/mod/test/data/mods/mod-list.json b/modules/mod/test/data/mods/mod-list.json new file mode 100644 index 0000000..95a6869 --- /dev/null +++ b/modules/mod/test/data/mods/mod-list.json @@ -0,0 +1,11 @@ + +{ + "mods": + [ + + { + "name": "base", + "enabled": true + } + ] +} diff --git a/modules/mod/test/data/player-data.json b/modules/mod/test/data/player-data.json new file mode 100644 index 0000000..c59d595 --- /dev/null +++ b/modules/mod/test/data/player-data.json @@ -0,0 +1,532 @@ + +{ + "available-campaign-levels": + { + "tight-spot": + { + "level-01": "hard" + }, + "transport-belt-madness": + { + "level-01": "hard" + }, + "tutorial": + { + "level-01": "hard" + } + }, + "tips": + { + "introduction": + { + "status": "unlocked", + "elapsed": 0 + }, + "show-info": + { + "status": "dependencies-not-met" + }, + "e-confirm": + { + "status": "locked" + }, + "clear-cursor": + { + "status": "dependencies-not-met" + }, + "pipette": + { + "status": "locked" + }, + "stack-transfers": + { + "status": "locked", + "skip_status": + { + "conditions": + [ + + {}, + + {}, + + {} + ] + } + }, + "entity-transfers": + { + "status": "locked", + "conditions": + [ + + {}, + + { + "elapsed": 0 + } + ], + "skip_status": + { + "conditions": + [ + + {}, + + {} + ] + } + }, + "z-dropping": + { + "status": "locked", + "conditions": + [ + + {}, + + { + "elapsed": 0 + } + ] + }, + "shoot-targeting": + { + "status": "locked", + "conditions": + [ + + {}, + + { + "elapsed": 0 + } + ] + }, + "bulk-crafting": + { + "status": "locked", + "conditions": + [ + + {}, + + {} + ] + }, + "inserters": + { + "status": "locked" + }, + "burner-inserter-refueling": + { + "status": "locked" + }, + "long-handed-inserters": + { + "status": "locked" + }, + "move-between-labs": + { + "status": "locked" + }, + "insertion-limits": + { + "status": "locked" + }, + "limit-chests": + { + "status": "locked", + "conditions": + [ + + {}, + + {} + ] + }, + "transport-belts": + { + "status": "locked" + }, + "belt-lanes": + { + "status": "locked" + }, + "splitters": + { + "status": "locked" + }, + "splitter-filters": + { + "status": "locked" + }, + "underground-belts": + { + "status": "locked" + }, + "electric-network": + { + "status": "locked", + "conditions": + [ + + { + "conditions": + [ + + { + "conditions": + [ + + {}, + + {} + ] + }, + + { + "elapsed": 0 + } + ] + }, + + {}, + + {}, + + {} + ] + }, + "steam-power": + { + "status": "dependencies-not-met" + }, + "electric-pole-connections": + { + "status": "locked", + "conditions": + [ + + { + "elapsed": 0 + }, + + {} + ] + }, + "low-power": + { + "status": "locked" + }, + "connect-switch": + { + "status": "locked" + }, + "copy-entity-settings": + { + "status": "locked" + }, + "copy-paste-trains": + { + "status": "locked" + }, + "copy-paste-filters": + { + "status": "locked", + "conditions": + [ + + {}, + + {} + ] + }, + "copy-paste-requester-chest": + { + "status": "locked", + "conditions": + [ + + {}, + + {} + ] + }, + "copy-paste-spidertron": + { + "status": "locked" + }, + "drag-building": + { + "status": "locked" + }, + "drag-building-poles": + { + "status": "locked" + }, + "drag-building-underground-belts": + { + "status": "locked" + }, + "fast-belt-bending": + { + "status": "locked" + }, + "fast-obstacle-traversing": + { + "status": "locked", + "conditions": + [ + + {}, + + {} + ] + }, + "trains": + { + "status": "locked" + }, + "rail-building": + { + "status": "locked" + }, + "train-stops": + { + "status": "locked", + "conditions": + [ + + {}, + + { + "conditions": + [ + + {}, + + {} + ] + } + ] + }, + "rail-signals-basic": + { + "status": "locked", + "conditions": + [ + + {}, + + { + "conditions": + [ + + {}, + + {} + ] + } + ] + }, + "rail-signals-advanced": + { + "status": "locked", + "conditions": + [ + + {}, + + {} + ] + }, + "gate-over-rail": + { + "status": "locked", + "conditions": + [ + + {}, + + {}, + + {} + ] + }, + "pump-connection": + { + "status": "locked" + }, + "train-stop-same-name": + { + "status": "locked" + }, + "logistic-network": + { + "status": "locked", + "conditions": + [ + + {}, + + {} + ] + }, + "personal-logistics": + { + "status": "locked" + }, + "construction-robots": + { + "status": "locked" + }, + "passive-provider-chest": + { + "status": "dependencies-not-met" + }, + "storage-chest": + { + "status": "dependencies-not-met" + }, + "requester-chest": + { + "status": "locked" + }, + "active-provider-chest": + { + "status": "locked" + }, + "buffer-chest": + { + "status": "locked" + }, + "ghost-building": + { + "status": "locked" + }, + "ghost-rail-planner": + { + "status": "locked", + "conditions": + [ + + { + "conditions": + [ + + {}, + + {} + ] + }, + + {} + ] + }, + "copy-paste": + { + "status": "locked", + "conditions": + [ + + {}, + + { + "elapsed": 0 + } + ] + }, + "fast-replace": + { + "status": "locked", + "conditions": + [ + + {}, + + {}, + + {} + ] + }, + "fast-replace-direction": + { + "status": "locked" + }, + "fast-replace-belt-splitter": + { + "status": "locked", + "skip_status": + { + "conditions": + [ + + {}, + + {} + ] + } + }, + "fast-replace-belt-underground": + { + "status": "locked" + }, + "rotating-assemblers": + { + "status": "locked", + "conditions": + [ + + {}, + + {} + ] + }, + "circuit-network": + { + "status": "locked", + "conditions": + [ + + {}, + + { + "elapsed": 0 + } + ] + } + }, + "service-username": "", + "service-token": "", + "last-used-filters": + { + "players": "any", + "password": "any", + "mods": "any", + "friends": "any" + }, + "column-ordering": + { + "public-index": "name", + "public-ascending": true, + "lan-index": "name", + "lan-ascending": true + }, + "editor-lua-snippets": + [ + + { + "name": "Example (Turn trees into biters)", + "code": "local surface = game.player.surface\nlocal entities = surface.find_entities_filtered{area = area, type = 'tree'}\nfor k, tree in pairs(entities) do\n local position = tree.position\n tree.destroy()\n surface.create_entity{name = 'small-biter', position = position}\nend" + } + ], + "last-played-version": + { + "game_version": "1.1.41", + "build_version": 58972, + "build_mode": "headless", + "platform": "linux64" + }, + "blueprint-view": "grid" +} diff --git a/modules/mod2/build.gradle.kts b/modules/mod2/build.gradle.kts index c981bd1..60d7616 100644 --- a/modules/mod2/build.gradle.kts +++ b/modules/mod2/build.gradle.kts @@ -157,3 +157,9 @@ tasks { } } } + + +configure { + versions.dukat.version = "0.5.8-rc.4-dev.20211001" +// versions.dukat.version = "0.5.8-rc.4" +} diff --git a/modules/mod2/dukat-custom/builtin-types.module_typed-factorio.kt b/modules/mod2/dukat-custom/builtin-types.module_typed-factorio.kt index ecd4eab..28b7280 100644 --- a/modules/mod2/dukat-custom/builtin-types.module_typed-factorio.kt +++ b/modules/mod2/dukat-custom/builtin-types.module_typed-factorio.kt @@ -2,18 +2,6 @@ import kotlin.js.* import kotlinext.js.PropertyDescriptor -import org.khronos.webgl.* -import org.w3c.dom.* -import org.w3c.dom.events.* -import org.w3c.dom.parsing.* -import org.w3c.dom.svg.* -import org.w3c.dom.url.* -import org.w3c.fetch.* -import org.w3c.files.* -import org.w3c.notifications.* -import org.w3c.performance.* -import org.w3c.workers.* -import org.w3c.xhr.* typealias float = Number diff --git a/modules/mod2/dukat-custom/classes.module_typed-factorio.kt b/modules/mod2/dukat-custom/classes.module_typed-factorio.kt index 7b92c6a..6522dd4 100644 --- a/modules/mod2/dukat-custom/classes.module_typed-factorio.kt +++ b/modules/mod2/dukat-custom/classes.module_typed-factorio.kt @@ -183,9 +183,9 @@ external interface LuaBootstrap { fun on_init(f: (() -> Unit)?) fun on_load(f: (() -> Unit)?) fun on_configuration_changed(f: ((param1: ConfigurationChangedData) -> Unit)?) - fun on_event(event: E, f: ((data: Any) -> Unit)?, filters: Array = definedExternally) - fun on_event(event: E, f: ((data: Any) -> Unit)?) - fun on_event(event: Array, f: ((data: Any) -> Unit)?) + fun on_event(event: E, f: ((data: E) -> Unit)?, filters: Array = definedExternally) + fun on_event(event: E, f: ((data: E) -> Unit)?) + fun on_event(event: Array, f: ((data: Any) -> Unit)?) fun on_event(event: String, f: ((data: CustomInputEvent) -> Unit)?) fun on_nth_tick(tick: uint?, f: ((param1: NthTickEventData) -> Unit)?) fun on_nth_tick(tick: Array?, f: ((param1: NthTickEventData) -> Unit)?) diff --git a/modules/mod2/dukat-custom/defines/events/defines.defines.events.module_typed-factorio.kt b/modules/mod2/dukat-custom/defines/events/defines.defines.events.module_typed-factorio.kt index 948e6bc..cccc0aa 100644 --- a/modules/mod2/dukat-custom/defines/events/defines.defines.events.module_typed-factorio.kt +++ b/modules/mod2/dukat-custom/defines/events/defines.defines.events.module_typed-factorio.kt @@ -2,6 +2,8 @@ @file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") package defines.events +import EventId +import OnTickEvent import kotlin.js.* import org.khronos.webgl.* import org.w3c.dom.* @@ -17,7 +19,7 @@ import org.w3c.workers.* import org.w3c.xhr.* import uint -external var on_tick: uint /* uint & `T$93` */ +external var on_tick: EventId /* uint & `T$93` */ external var on_gui_click: uint /* uint & `T$93` */ diff --git a/modules/mod2/dukat-custom/eventId.kt b/modules/mod2/dukat-custom/eventId.kt new file mode 100644 index 0000000..b4cd976 --- /dev/null +++ b/modules/mod2/dukat-custom/eventId.kt @@ -0,0 +1,11 @@ + +external class TsUInt : tsstdlib.Number + +external class EventId { + @JsName("_eventData") + val eventData: DataT + + @JsName("_filter") + val filter: FilterT + +} \ No newline at end of file diff --git a/modules/mod2/dukat-custom/global.module_lua-types.kt b/modules/mod2/dukat-custom/global.module_lua-types.kt index 1a0a17e..470dcc5 100644 --- a/modules/mod2/dukat-custom/global.module_lua-types.kt +++ b/modules/mod2/dukat-custom/global.module_lua-types.kt @@ -1,4 +1,5 @@ -@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") +@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", + "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") import kotlin.js.* import org.khronos.webgl.* @@ -17,11 +18,11 @@ import tsstdlib.Record import tsstdlib.Iterable external interface LuaThread { - var __internal__: Any + var __internal__: Any } external interface LuaUserdata { - var __internal__: Any + var __internal__: Any } external var _VERSION: String /* "Lua 5.1" | "Lua 5.2" | "Lua 5.3" | "Lua 5.4" */ @@ -30,13 +31,15 @@ external var _G: Any external fun assert(v: V): Any -external fun > assert(v: V, vararg args: A): dynamic /* JsTuple, Any> */ +external fun > assert(v: V, + vararg args: A): dynamic /* JsTuple, Any> */ external fun collectgarbage(opt: String /* "collect" | "stop" | "restart" */ = definedExternally) external fun collectgarbage() -external fun collectgarbage(opt: String /* "setpause" | "setstepmul" | "step" */, arg: Number): dynamic /* Number | Boolean */ +external fun collectgarbage(opt: String /* "setpause" | "setstepmul" | "step" */, + arg: Number): dynamic /* Number | Boolean */ external fun dofile(filename: String = definedExternally): Any @@ -44,17 +47,25 @@ external fun error(message: String, level: Number = definedExternally): Any external fun getmetatable(obj: T): LuaMetatable__1? -external fun ipairs(t: Record): Iterable> */> /* Iterable> */> & LuaIterator> */, undefined> & LuaExtension */ +external fun ipairs( + t: kotlinext.js.Record): + Iterable> */> +/* Iterable> */> & LuaIterator> */, undefined> & LuaExtension */ -external fun next(table: Any?, index: Any = definedExternally): dynamic /* JsTuple | JsTuple<> */ +external fun next(table: Any?, + index: Any = definedExternally): dynamic /* JsTuple | JsTuple<> */ -external fun pairs(t: LuaTable): Iterable> */> /* Iterable> */> & LuaIterator> */, undefined> & LuaExtension */ +external fun pairs( + t: LuaTable): Iterable> */> /* Iterable> */> & LuaIterator> */, undefined> & LuaExtension */ -external fun pairs(t: T): Iterable> */> /* Iterable> */> & LuaIterator> */, undefined> & LuaExtension */ +external fun pairs( + t: T): Iterable> */> /* Iterable> */> & LuaIterator> */, undefined> & LuaExtension */ -external fun , R> pcall(f: (self: This, args: Args) -> R, context: This, vararg args: Args): dynamic /* JsTuple | JsTuple */ +external fun , R> pcall(f: (self: This, args: Args) -> R, context: This, + vararg args: Args): dynamic /* JsTuple | JsTuple */ -external fun , R> pcall(f: (self: Unit, args: A) -> R, vararg args: A): dynamic /* JsTuple | JsTuple */ +external fun , R> pcall(f: (self: Unit, args: A) -> R, + vararg args: A): dynamic /* JsTuple | JsTuple */ external fun print(vararg args: Any) @@ -68,14 +79,17 @@ external fun rawlen(v: String?): Number external fun rawset(table: T, index: K, value: Any): T -external fun select(index: Number, vararg args: T): Array /* Array & LuaExtension */ +external fun select(index: Number, + vararg args: T): Array /* Array & LuaExtension */ external fun select(index: String /* "#" */, vararg args: T): Number -external fun setmetatable(table: T, metatable: LuaMetatable? = definedExternally): Any +external fun setmetatable(table: T, + metatable: LuaMetatable? = definedExternally): Any external fun tonumber(e: Any, base: Number = definedExternally): Number? external fun tostring(v: Any): String -external fun type(v: Any): String /* "nil" | "number" | "string" | "boolean" | "table" | "function" | "thread" | "userdata" */ \ No newline at end of file +external fun type( + v: Any): String /* "nil" | "number" | "string" | "boolean" | "table" | "function" | "thread" | "userdata" */ \ No newline at end of file diff --git a/modules/mod2/dukat-custom/tsstdlib/lib.es5.kt b/modules/mod2/dukat-custom/tsstdlib/lib.es5.kt index 8235e3b..a96c4b5 100644 --- a/modules/mod2/dukat-custom/tsstdlib/lib.es5.kt +++ b/modules/mod2/dukat-custom/tsstdlib/lib.es5.kt @@ -63,7 +63,9 @@ typealias Partial = Any typealias Pick = Any -typealias Record = Any +@Deprecated("use Kotlin Wrapper", ReplaceWith("kotlinext.js.Record")) +typealias Record = kotlinext.js.Record + typealias Exclude = Any diff --git a/modules/mod2/src/main/kotlin/events.kt b/modules/mod2/src/main/kotlin/events.kt new file mode 100644 index 0000000..5684b55 --- /dev/null +++ b/modules/mod2/src/main/kotlin/events.kt @@ -0,0 +1,11 @@ +fun main() { + + +script.on_event( + defines.events.on_tick +) { event -> + +} + + +} diff --git a/modules/mod2/typed-factorio/README.md b/modules/mod2/typed-factorio/README.md new file mode 100644 index 0000000..08ae6dc --- /dev/null +++ b/modules/mod2/typed-factorio/README.md @@ -0,0 +1,113 @@ +# Typed Factorio + +Complete and featureful typescript definitions for the Factorio modding lua api. This is intended to be used with [TypescriptToLua](https://typescripttolua.github.io/). + +This project aims to provide type definitions for the Factorio API that are as complete as possible. This means minimal `any`s and `unknown`s, correct nullability, and smart types where possible. The generator integrates both the Factorio JSON api docs and manually defined additions and overrides. + +## Installation + +To use in your TypescriptToLua project: + +1. Install this package + +``` +npm install typed-factorio + +or + +yarn add typed-factorio +``` + +2. Add to your `tsconfig.json`: + +```diff +{ + "compilerOptions": { ++ "types": [ "typed-factorio/runtime" ] + } +} +``` + +This will add the types for the runtime stage to your entire project. + +Note: When types are updated, or released for a new factorio version, you will need update your package version to get the types. + +### Settings and data stage + +There are also definitions for the settings/data stage. + +To avoid type conflicts, the global tables for the settings/data stages have to be declared manually where you need them. These types can be imported from `typed-factorio/data/types` or `typed-factorio/settings/types`. + +Example: + +```ts +import { Data, Mods } from "typed-factorio/data/types" +// or +import { Data, Mods } from "typed-factorio/settings/types" + +declare const data: Data +declare const mods: Mods + +data.extend([{ ... }]) +``` + +There are currently full types for settings stage, but only basic types for the data stage. + +### Factorio lualib modules + +Currently, there are types for the following modules: + +- `util` +- `mod-gui` + +If you have a need for types to more lualib modules, feel free to open an issue or pull request on GitHub. + +## Type features + +Typed-factorio has 100% complete types for the runtime stage. Description-only concepts and some not documented types are filled in manually. + +### Lua features + +The types include [TypescriptToLua language extensions](https://typescripttolua.github.io/docs/advanced/language-extensions/) +and [lua-types](https://github.com/TypeScriptToLua/lua-types) (for v5.2) as dependencies. + +This is to use tstl features such as `LuaLengthMethod` and `LuaMultiReturn`. + +### `nil` + +The types consistently use `undefined` to represent `nil`. +`null` is not used, because `undefined` in typescript is much more similar to `nil` in lua, and optional parameters/properties already use `undefined`. + +A class attribute is marked as possibly undefined only if the _read_ type is possibly `nil`. For properties where `nil` is not possible on _read_, but is possible on _write_, you can write `nil` by using `undefined!` or `myNullableValue!`, e.g. `controlBehavior.parameters = undefined!`. + +### Variant parameter types + +Variant parameter types (types with "additional fields can be specified depending on ...") are handled as discriminated unions. This gives proper type checking for individual variants. + +The type for a specific variant is prefixed with the either variant name or "Other" for variants without additional fields, e.g. `AmmoDamageTechnologyModifier`, `OtherTechnologyModifier` + +### Events + +`script.on_event()`, `script.get/set_filters()`, and `script.raise_event()` all have type checking on the event data/filter type, inferred from what is passed as the event name/id. + +You can pass a type parameter to `script.generate_event_name()`, and it will return an `EventId` that holds type info of the event data. Event functions on `script` can then use the type data when the `EventId` is passed. + +### Array-like types + +Classes that have an index operator, a length operator, and have an array-like structure, inherit from `(Readonly)Array`. These are `LuaInventory`, `LuaFluidBox`, `LuaTransportLine`. This allows you to use these classes like arrays, meaning having array methods, and `.length` translating to the lua length operator. However, this also means, like typescript arrays, they are **0-indexed, not 1-indexed**. + +### Table or array types + +For table or array types (e.g. Position), there also are types such as `PositionTable` and `PositionArray` that refer to the table or array form specifically. + +### LuaGuiElement + +`LuaGuiElement` is broken up into a discriminated union for each gui element type (See [here](https://basarat.gitbook.io/typescript/type-system/discriminated-unions) for information on discriminated unions). The type for a specific GuiElement type is `GuiElement`, e.g. `ButtonGuiElement`. + +Similarly, the table passed to `LuaGuiElement.add`, referred to as `GuiSpec`, is also broken up into a discriminated union for each gui element type. The type for a specific GuiSpec type is `GuiSpec`, e.g. `ListBoxGuiSpec`. + +This is done both to provide more accurate types, and for possible integration with [JSX](https://typescripttolua.github.io/docs/jsx/). + +### Examples + +Check out the `test` directory on GitHub for more examples on particular type features. diff --git a/modules/mod2/typed-factorio/data/types.d.ts b/modules/mod2/typed-factorio/data/types.d.ts new file mode 100644 index 0000000..408f32a --- /dev/null +++ b/modules/mod2/typed-factorio/data/types.d.ts @@ -0,0 +1,13 @@ +export interface Data { + readonly raw: Record> + + /** + * The `data` table expects a specific format for each item in the table. Missing properties will either fall back to + * default values or give an error indicating what's missing. Extra properties that the game isn't looking for are + * simply ignored. + */ + extend(prototypes: Record[]): void +} + +/** A mapping of mod names to mod version for all enabled mods. */ +export type Mods = Record diff --git a/modules/mod2/typed-factorio/generated/builtin-types.d.ts b/modules/mod2/typed-factorio/generated/builtin-types.d.ts new file mode 100644 index 0000000..bcd4172 --- /dev/null +++ b/modules/mod2/typed-factorio/generated/builtin-types.d.ts @@ -0,0 +1,66 @@ +/** @noSelfInFile */ + +/** + * A floating-point number. This is a single-precision floating point number. Whilst Lua only uses double-precision + * numbers, when a function takes a float, the game engine will immediately convert the double-precision number to + * single-precision. + * + * {@link https://lua-api.factorio.com/next/Builtin-Types.html#float View documentation} + */ +type float = number + +/** + * A double-precision floating-point number. This is the same data type as all Lua numbers use. + * + * {@link https://lua-api.factorio.com/next/Builtin-Types.html#double View documentation} + */ +type double = number + +/** + * 32-bit signed integer. Possible values are -2,147,483,648 to 2,147,483,647. + * + * {@link https://lua-api.factorio.com/next/Builtin-Types.html#int View documentation} + */ +type int = number + +/** + * 8-bit signed integer. Possible values are -128 to 127. + * + * {@link https://lua-api.factorio.com/next/Builtin-Types.html#int8 View documentation} + */ +type int8 = number + +/** + * 32-bit unsigned integer. Possible values are 0 to 4,294,967,295. + * + * {@link https://lua-api.factorio.com/next/Builtin-Types.html#uint View documentation} + */ +type uint = number + +/** + * 8-bit unsigned integer. Possible values are 0 to 255. + * + * {@link https://lua-api.factorio.com/next/Builtin-Types.html#uint8 View documentation} + */ +type uint8 = number + +/** + * 16-bit unsigned integer. Possible values are 0 to 65535. + * + * {@link https://lua-api.factorio.com/next/Builtin-Types.html#uint16 View documentation} + */ +type uint16 = number + +/** + * 64-bit unsigned integer. Possible values are 0 to 18,446,744,073,709,551,615. + * + * {@link https://lua-api.factorio.com/next/Builtin-Types.html#uint64 View documentation} + */ +type uint64 = number + +/** + * Tables are enclosed in curly brackets, like this `{}` + * + * {@link https://lua-api.factorio.com/next/Builtin-Types.html#table View documentation} + */ +type table = object diff --git a/modules/mod2/typed-factorio/generated/classes.d.ts b/modules/mod2/typed-factorio/generated/classes.d.ts new file mode 100644 index 0000000..65469c5 --- /dev/null +++ b/modules/mod2/typed-factorio/generated/classes.d.ts @@ -0,0 +1,20023 @@ +/** @noSelfInFile */ + +/** + * Collection of settings for overriding default ai behavior. + * + * {@link https://lua-api.factorio.com/next/LuaAISettings.html View documentation} + * + * @noSelf + */ +interface LuaAISettings { + /** + * If enabled, units that repeatedly fail to succeed at commands will be destroyed. + * + * {@link https://lua-api.factorio.com/next/LuaAISettings.html#LuaAISettings.allow_destroy_when_commands_fail View documentation} + */ + allow_destroy_when_commands_fail: boolean + /** + * If enabled, units that have nothing else to do will attempt to return to a spawner. + * + * {@link https://lua-api.factorio.com/next/LuaAISettings.html#LuaAISettings.allow_try_return_to_spawner View documentation} + */ + allow_try_return_to_spawner: boolean + /** + * If enabled, units will try to separate themselves from nearby friendly units. + * + * {@link https://lua-api.factorio.com/next/LuaAISettings.html#LuaAISettings.do_separation View documentation} + */ + do_separation: boolean + /** + * The pathing resolution modifier, must be between -8 and 8. + * + * {@link https://lua-api.factorio.com/next/LuaAISettings.html#LuaAISettings.path_resolution_modifier View documentation} + */ + path_resolution_modifier: int8 + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaAISettings" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Control behavior for accumulators. + * + * {@link https://lua-api.factorio.com/next/LuaAccumulatorControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaAccumulatorControlBehavior extends LuaControlBehavior { + output_signal: SignalID + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaAccumulatorControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a achievement. + * + * {@link https://lua-api.factorio.com/next/LuaAchievementPrototype.html View documentation} + * + * @noSelf + */ +interface LuaAchievementPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaAchievementPrototype.html#LuaAchievementPrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaAchievementPrototype.html#LuaAchievementPrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + readonly allowed_without_fight: boolean + readonly hidden: boolean + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaAchievementPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a ammo category. + * + * {@link https://lua-api.factorio.com/next/LuaAmmoCategoryPrototype.html View documentation} + * + * @noSelf + */ +interface LuaAmmoCategoryPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaAmmoCategoryPrototype.html#LuaAmmoCategoryPrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaAmmoCategoryPrototype.html#LuaAmmoCategoryPrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + readonly bonus_gui_order: string + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaAmmoCategoryPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Control behavior for arithmetic combinators. + * + * {@link https://lua-api.factorio.com/next/LuaArithmeticCombinatorControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaArithmeticCombinatorControlBehavior extends LuaCombinatorControlBehavior { + /** + * The arithmetic combinator parameters. + * + * **Note**: `parameters` may be `nil` in order to clear the parameters. + * + * {@link https://lua-api.factorio.com/next/LuaArithmeticCombinatorControlBehavior.html#LuaArithmeticCombinatorControlBehavior.parameters View documentation} + */ + parameters: ArithmeticCombinatorParameters + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaArithmeticCombinatorControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of an autoplace control. + * + * {@link https://lua-api.factorio.com/next/LuaAutoplaceControlPrototype.html View documentation} + * + * @noSelf + */ +interface LuaAutoplaceControlPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaAutoplaceControlPrototype.html#LuaAutoplaceControlPrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaAutoplaceControlPrototype.html#LuaAutoplaceControlPrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + readonly richness: boolean + readonly control_order: string + /** + * Category name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaAutoplaceControlPrototype.html#LuaAutoplaceControlPrototype.category View documentation} + */ + readonly category: string + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaAutoplaceControlPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +type RaiseableEvents = + | typeof defines.events.on_console_chat + | typeof defines.events.on_player_crafted_item + | typeof defines.events.on_player_fast_transferred + | typeof defines.events.on_biter_base_built + | typeof defines.events.on_market_item_purchased + | typeof defines.events.script_raised_built + | typeof defines.events.script_raised_destroy + | typeof defines.events.script_raised_revive + | typeof defines.events.script_raised_set_tiles + +/** + * Entry point for registering event handlers. It is accessible through the global object named `script`. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html View documentation} + * + * @noSelf + */ +interface LuaBootstrap { + /** + * Register a callback to be run on mod initialization. This is only called when a new save game is created or when + * a save file is loaded that previously didn't contain the mod. During it, the mod gets the chance to set up + * initial values that it will use for its lifetime. It has full access to {@link LuaGameScript} and the `global` + * table and can change anything about them that it deems appropriate. No other events will be raised for the mod + * until it has finished this step. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.on_init View documentation} + * + * @example + * Initialize a `players` table in `global` for later use. + * + * ```lua + * script.on_init(function() + * global.players = {} + * end) + * ``` + * + * @param f - The handler for this event. Passing `nil` will unregister it. + */ + on_init(f: (() => void) | undefined): void + /** + * Register a function to be run on save load. This is only called for mods that have been part of the save + * previously, or for players connecting to a running multiplayer session. It gives the mod the opportunity to do + * some very specific actions, should it need to. Doing anything other than these three will lead to desyncs, which + * breaks multiplayer and replay functionality. Access to {@link LuaGameScript} and {@link LuaRendering} is not + * available. The `global` table can be accessed and is safe to read from, but not write to. + * + * The only legitimate uses of this event are these three: + * + * - Re-setup {@link https://www.lua.org/pil/13.html metatables} as they are not persisted through save-load. + * - Re-setup conditional event handlers. + * - Create local references to data stored in the {@link https://lua-api.factorio.com/next/Global.html global} table. + * + * For all other purposes, {@link LuaBootstrap.on_init LuaBootstrap::on_init}, + * {@link LuaBootstrap.on_configuration_changed LuaBootstrap::on_configuration_changed} or migration scripts should + * be used instead. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.on_load View documentation} + * + * @param f - The handler for this event. Passing `nil` will unregister it. + */ + on_load(f: (() => void) | undefined): void + /** + * Register a function to be run when mod configuration changes. This is called when the game version or any mod + * version changes; when any mod is added or removed; or when prototypes or startup mod settings have changed. It + * allows the mod to make any changes it deems appropriate to both the data structures in its `global` table or to + * the game state through {@link LuaGameScript}. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.on_configuration_changed View documentation} + * + * @param f - The handler for this event. Passing `nil` will unregister it. + */ + on_configuration_changed(f: ((param1: ConfigurationChangedData) => void) | undefined): void + /** + * Register a handler to run on the specified event(s). Each mod can only register once for every event, as any + * additional registration will overwrite the previous one. This holds true even if different filters are used for + * subsequent registrations. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.on_event View documentation} + * + * @example + * Register for the {@link OnTickEvent on_tick} event to print the current tick to console each tick. + * + * ```lua + * script.on_event(defines.events.on_tick, + * function(event) game.print(event.tick) end) + * ``` + * + * @example + * Register for the {@link OnBuiltEntityEvent on_built_entity} event, limiting it to only be received when a `"fast-inserter"` is built. + * + * ```lua + * script.on_event(defines.events.on_built_entity, + * function(event) game.print("Gotta go fast!") end, + * {{filter = "name", name = "fast-inserter"}}) + * ``` + * + * @param event - The event(s) or custom-input to invoke the handler on. + * @param f - The handler for this event. Passing `nil` will unregister it. + * @param filters - The filters for this event. Can only be used when registering for individual events. + */ + on_event>( + event: E, + f: ((data: E["_eventData"]) => void) | undefined, + filters?: E["_filter"][] + ): void + on_event>(event: E | E[], f: ((data: E["_eventData"]) => void) | undefined): void + on_event(event: string, f: ((data: CustomInputEvent) => void) | undefined): void + /** + * Register a handler to run every nth-tick(s). When the game is on tick 0 it will trigger all registered handlers. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.on_nth_tick View documentation} + * + * @param tick - The nth-tick(s) to invoke the handler on. Passing `nil` as the only parameter will unregister all + * nth-tick handlers. + * @param f - The handler to run. Passing `nil` will unregister it for the provided nth-tick(s). + */ + on_nth_tick(tick: uint | uint[] | undefined, f: ((param1: NthTickEventData) => void) | undefined): void + /** + * Registers an entity so that after it's destroyed, {@link OnEntityDestroyedEvent on_entity_destroyed} is called. + * Once an entity is registered, it stays registered until it is actually destroyed, even through save/load cycles. + * The registration is global across all mods, meaning once one mod registers an entity, all mods listening to + * {@link OnEntityDestroyedEvent on_entity_destroyed} will receive the event when it is destroyed. Registering the + * same entity multiple times will still only fire the destruction event once, and will return the same registration number. + * + * **Note**: Depending on when a given entity is destroyed, {@link OnEntityDestroyedEvent on_entity_destroyed} will + * either be fired at the end of the current tick or at the end of the next tick. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.register_on_entity_destroyed View documentation} + * + * @param entity - The entity to register. + * @returns The registration number. It is used to identify the entity in the + * {@link OnEntityDestroyedEvent on_entity_destroyed} event. + */ + register_on_entity_destroyed(entity: LuaEntity): uint64 + /** + * Generate a new, unique event ID that can be used to raise custom events with + * {@link LuaBootstrap.raise_event LuaBootstrap::raise_event}. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.generate_event_name View documentation} + * + * @returns The newly generated event ID. + */ + generate_event_name(): CustomEventId + /** + * Find the event handler for an event. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.get_event_handler View documentation} + * + * @param event - The event identifier to get a handler for. + * @returns Reference to the function currently registered as the handler. + */ + get_event_handler>(event: E): (data: E["_eventData"]) => void + get_event_handler(event: string): (data: CustomInputEvent) => void + /** + * Gets the mod event order as a string. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.get_event_order View documentation} + */ + get_event_order(): string + /** + * Sets the filters for the given event. The filters are only retained when set after the actual event registration, + * because registering for an event with different or no filters will overwrite previously set ones. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.set_event_filter View documentation} + * + * @example + * Limit the {@link OnMarkedForDeconstructionEvent on_marked_for_deconstruction} event to only be received when a non-ghost entity is marked for deconstruction. + * + * ```lua + * script.set_event_filter(defines.events.on_marked_for_deconstruction, {{filter = "ghost", invert = true}}) + * ``` + * + * @example + * Limit the {@link OnBuiltEntityEvent on_built_entity} event to only be received when either a `unit` or a `unit-spawner` is built. + * + * ```lua + * script.set_event_filter(defines.events.on_built_entity, {{filter = "type", type = "unit"}, {filter = "type", type = "unit-spawner"}}) + * ``` + * + * @example + * Limit the {@link OnEntityDamagedEvent on_entity_damaged} event to only be received when a `rail` is damaged by an `acid` attack. + * + * ```lua + * script.set_event_filter(defines.events.on_entity_damaged, {{filter = "rail"}, {filter = "damage-type", type = "acid", mode = "and"}}) + * ``` + * + * @param event - ID of the event to filter. + * @param filters - The filters or `nil` to clear them. + */ + set_event_filter>(event: E, filters: E["_filter"][] | undefined): void + /** + * Gets the filters for the given event. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.get_event_filter View documentation} + * + * @param event - ID of the event to get. + * @returns The filters or `nil` if none are defined. + */ + get_event_filter>(event: E): E["_filter"][] | undefined + /** + * Raise an event. Only events generated with + * {@link LuaBootstrap.generate_event_name LuaBootstrap::generate_event_name} and the following can be raised: + * + * - {@link OnConsoleChatEvent on_console_chat} + * - {@link OnPlayerCraftedItemEvent on_player_crafted_item} + * - {@link OnPlayerFastTransferredEvent on_player_fast_transferred} + * - {@link OnBiterBaseBuiltEvent on_biter_base_built} + * - {@link OnMarketItemPurchasedEvent on_market_item_purchased} + * - {@link ScriptRaisedBuiltEvent script_raised_built} + * - {@link ScriptRaisedDestroyEvent script_raised_destroy} + * - {@link ScriptRaisedReviveEvent script_raised_revive} + * - {@link ScriptRaisedSetTilesEvent script_raised_set_tiles} + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_event View documentation} + * + * @example + * Raise the {@link OnConsoleChatEvent on_console_chat} event with the desired message 'from' the first player. + * + * ```lua + * local data = {player_index = 1, message = "Hello friends!"} + * script.raise_event(defines.events.on_console_chat, data) + * ``` + * + * @param event - ID of the event to raise. + * @param data - Table with extra data that will be passed to the event handler. + */ + raise_event>( + event: E, + data: Omit + ): void + /** + * Raises {@link OnConsoleChatEvent on_console_chat} with the given parameters. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_console_chat View documentation} + */ + raise_console_chat(params: { + /** The player doing the chatting. */ + readonly player_index: uint + /** The chat message to send. */ + readonly message: string + }): void + /** + * Raises {@link OnPlayerCraftedItemEvent on_player_crafted_item} with the given parameters. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_player_crafted_item View documentation} + */ + raise_player_crafted_item(params: { + /** The item that has been crafted. */ + readonly item_stack: LuaItemStack + /** The player doing the crafting. */ + readonly player_index: uint + /** The recipe used to craft this item. */ + readonly recipe: LuaRecipe + }): void + /** + * Raises {@link OnPlayerFastTransferredEvent on_player_fast_transferred} with the given parameters. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_player_fast_transferred View documentation} + */ + raise_player_fast_transferred(params: { + /** The player transferred from or to. */ + readonly player_index: uint + /** The entity transferred from or to. */ + readonly entity: LuaEntity + /** Whether the transfer was from player to entity. If `false`, the transfer was from entity to player. */ + readonly from_player: boolean + }): void + /** + * Raises {@link OnBiterBaseBuiltEvent on_biter_base_built} with the given parameters. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_biter_base_built View documentation} + */ + raise_biter_base_built(params: { + /** The entity that was built. */ + readonly entity: LuaEntity + }): void + /** + * Raises {@link OnMarketItemPurchasedEvent on_market_item_purchased} with the given parameters. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_market_item_purchased View documentation} + */ + raise_market_item_purchased(params: { + /** The player who did the purchasing. */ + readonly player_index: uint + /** The market entity. */ + readonly market: LuaEntity + /** The index of the offer purchased. */ + readonly offer_index: uint + /** The amount of offers purchased. */ + readonly count: uint + }): void + /** + * Raises {@link ScriptRaisedBuiltEvent script_raised_built} with the given parameters. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_script_built View documentation} + */ + raise_script_built(params: { + /** The entity that has been built. */ + readonly entity: LuaEntity + }): void + /** + * Raises {@link ScriptRaisedDestroyEvent script_raised_destroy} with the given parameters. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_script_destroy View documentation} + */ + raise_script_destroy(params: { + /** The entity that was destroyed. */ + readonly entity: LuaEntity + }): void + /** + * Raises {@link ScriptRaisedReviveEvent script_raised_revive} with the given parameters. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_script_revive View documentation} + */ + raise_script_revive(params: { + /** The entity that was revived. */ + readonly entity: LuaEntity + /** The tags associated with this entity, if any. */ + readonly tags?: Tags + }): void + /** + * Raises {@link ScriptRaisedSetTilesEvent script_raised_set_tiles} with the given parameters. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.raise_script_set_tiles View documentation} + */ + raise_script_set_tiles(params: { + /** The surface whose tiles have been changed. */ + readonly surface_index: uint + /** The tiles that have been changed. */ + readonly tiles: Tile[] + }): void + /** + * The name of the mod from the environment this is used in. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.mod_name View documentation} + */ + readonly mod_name: string + /** + * Information about the currently running scenario/campaign/tutorial. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.level View documentation} + */ + readonly level: { + /** Is this level a simulation? (The main menu and 'Tips and tricks' use simulations) */ + readonly is_simulation?: boolean + /** Is this level a tutorial? */ + readonly is_tutorial?: boolean + /** The campaign name if any. */ + readonly campaign_name?: string + /** The level name. */ + readonly level_name: string + /** The mod name if any. */ + readonly mod_name?: string + } + /** + * A dictionary listing the names of all currently active mods and mapping them to their version. + * + * {@link https://lua-api.factorio.com/next/LuaBootstrap.html#LuaBootstrap.active_mods View documentation} + * + * @example + * This will print the names and versions of all active mods to the console. + * + * ```lua + * for name, version in pairs(script.active_mods) do + * game.print(name .. " version " .. version) + * end + * ``` + */ + readonly active_mods: Record + /** This object's name. */ + readonly object_name: "LuaBootstrap" +} + +/** + * A reference to the burner energy source owned by a specific {@link LuaEntity} or {@link LuaEquipment}. + * + * {@link https://lua-api.factorio.com/next/LuaBurner.html View documentation} + * + * @noSelf + */ +interface LuaBurner { + /** + * The owner of this burner energy source + * + * {@link https://lua-api.factorio.com/next/LuaBurner.html#LuaBurner.owner View documentation} + */ + readonly owner: LuaEntity | LuaEquipment + /** + * The fuel inventory. + * + * {@link https://lua-api.factorio.com/next/LuaBurner.html#LuaBurner.inventory View documentation} + */ + readonly inventory: LuaInventory + /** + * The burnt result inventory. + * + * {@link https://lua-api.factorio.com/next/LuaBurner.html#LuaBurner.burnt_result_inventory View documentation} + */ + readonly burnt_result_inventory: LuaInventory + heat: double + readonly heat_capacity: double + /** + * **Note**: Writing will silently do nothing if there's no + * {@link LuaBurner.currently_burning LuaBurner::currently_burning} set. + * + * {@link https://lua-api.factorio.com/next/LuaBurner.html#LuaBurner.remaining_burning_fuel View documentation} + */ + remaining_burning_fuel: double + /** + * **Note**: Writing automatically handles correcting + * {@link LuaBurner.remaining_burning_fuel LuaBurner::remaining_burning_fuel}. + * + * {@link https://lua-api.factorio.com/next/LuaBurner.html#LuaBurner.currently_burning View documentation} + */ + currently_burning: LuaItemPrototype + /** + * The fuel categories this burner uses. + * + * **Note**: The value in the dictionary is meaningless and exists just to allow the dictionary type for easy lookup. + * + * {@link https://lua-api.factorio.com/next/LuaBurner.html#LuaBurner.fuel_categories View documentation} + */ + readonly fuel_categories: Record + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaBurner" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a burner energy source. + * + * {@link https://lua-api.factorio.com/next/LuaBurnerPrototype.html View documentation} + * + * @noSelf + */ +interface LuaBurnerPrototype { + readonly emissions: double + readonly render_no_network_icon: boolean + readonly render_no_power_icon: boolean + readonly effectivity: double + readonly fuel_inventory_size: uint + readonly burnt_inventory_size: uint + /** + * The smoke sources for this burner prototype if any. + * + * {@link https://lua-api.factorio.com/next/LuaBurnerPrototype.html#LuaBurnerPrototype.smoke View documentation} + */ + readonly smoke: SmokeSource[] + /** + * The light flicker definition for this burner prototype if any. + * + * {@link https://lua-api.factorio.com/next/LuaBurnerPrototype.html#LuaBurnerPrototype.light_flicker View documentation} + */ + readonly light_flicker: { + readonly minimum_intensity: float + readonly maximum_intensity: float + readonly derivation_change_frequency: float + readonly derivation_change_deviation: float + readonly border_fix_speed: float + readonly minimum_light_size: float + readonly light_intensity_to_size_coefficient: float + readonly color: Color + } + /** + * **Note**: The value in the dictionary is meaningless and exists just to allow the dictionary type for easy lookup. + * + * {@link https://lua-api.factorio.com/next/LuaBurnerPrototype.html#LuaBurnerPrototype.fuel_categories View documentation} + */ + readonly fuel_categories: Record + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaBurnerPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A chunk iterator can be used for iterating chunks coordinates of a surface. + * + * The returned type is a {@link ChunkPositionAndArea} containing the chunk coordinates and its area. + * + * {@link https://lua-api.factorio.com/next/LuaChunkIterator.html View documentation} + * + * @example + * ```lua + * for chunk in some_surface.get_chunks() do + * game.player.print("x: " .. chunk.x .. ", y: " .. chunk.y) + * game.player.print("area: " .. serpent.line(chunk.area)) + * end + * ``` + * + * @noSelf + */ +interface LuaChunkIterator extends LuaIterable { + /** + * Get the next chunk position or `nil`, and increments the iterator. + * + * {@link https://lua-api.factorio.com/next/LuaChunkIterator.html#LuaChunkIterator.operator%20() View documentation} + */ + (): ChunkPositionAndArea | undefined + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaChunkIterator" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A circuit network associated with a given entity, connector, and wire type. + * + * {@link https://lua-api.factorio.com/next/LuaCircuitNetwork.html View documentation} + * + * @noSelf + */ +interface LuaCircuitNetwork { + /** + * {@link https://lua-api.factorio.com/next/LuaCircuitNetwork.html#LuaCircuitNetwork.get_signal View documentation} + * + * @param signal - The signal to read. + * @returns The current value of the signal. + */ + get_signal(signal: SignalID): int + /** + * The entity this circuit network reference is associated with + * + * {@link https://lua-api.factorio.com/next/LuaCircuitNetwork.html#LuaCircuitNetwork.entity View documentation} + */ + readonly entity: LuaEntity + /** + * The wire type this network is associated with. + * + * {@link https://lua-api.factorio.com/next/LuaCircuitNetwork.html#LuaCircuitNetwork.wire_type View documentation} + */ + readonly wire_type: defines.wire_type + /** + * The circuit connector ID on the associated entity this network was gotten from. + * + * {@link https://lua-api.factorio.com/next/LuaCircuitNetwork.html#LuaCircuitNetwork.circuit_connector_id View documentation} + */ + readonly circuit_connector_id: defines.circuit_connector_id + /** + * The circuit network signals last tick. `nil` if there are no signals. + * + * {@link https://lua-api.factorio.com/next/LuaCircuitNetwork.html#LuaCircuitNetwork.signals View documentation} + */ + readonly signals: Signal[] | undefined + /** + * The circuit networks ID. + * + * {@link https://lua-api.factorio.com/next/LuaCircuitNetwork.html#LuaCircuitNetwork.network_id View documentation} + */ + readonly network_id: uint + /** + * The number of circuits connected to this network. + * + * {@link https://lua-api.factorio.com/next/LuaCircuitNetwork.html#LuaCircuitNetwork.connected_circuit_count View documentation} + */ + readonly connected_circuit_count: uint + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaCircuitNetwork" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * {@link https://lua-api.factorio.com/next/LuaCombinatorControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaCombinatorControlBehavior extends LuaControlBehavior { + /** + * Gets the value of a specific signal sent by this combinator behavior last tick or nil if the signal didn't exist. + * + * {@link https://lua-api.factorio.com/next/LuaCombinatorControlBehavior.html#LuaCombinatorControlBehavior.get_signal_last_tick View documentation} + * + * @param signal - The signal to get + * @returns The value or `nil` if none. + */ + get_signal_last_tick(signal: SignalID): int | undefined + /** + * The circuit network signals sent by this combinator last tick. + * + * {@link https://lua-api.factorio.com/next/LuaCombinatorControlBehavior.html#LuaCombinatorControlBehavior.signals_last_tick View documentation} + */ + readonly signals_last_tick: Signal[] +} + +/** + * Allows for the registration of custom console commands. Similarly to + * {@link LuaBootstrap.on_event event subscriptions}, these don't persist through a save-and-load cycle. + * + * {@link https://lua-api.factorio.com/next/LuaCommandProcessor.html View documentation} + * + * @noSelf + */ +interface LuaCommandProcessor { + /** + * Add a custom console command. + * + * **Note**: Trying to add a command with the `name` of a game command or the name of a custom command that is + * already in use will result in an error. + * + * {@link https://lua-api.factorio.com/next/LuaCommandProcessor.html#LuaCommandProcessor.add_command View documentation} + * + * @example + * This will register a custom event called `print_tick` that prints the current tick to either the player issuing the command or to everyone on the server, depending on the command parameter. It shows the usage of the table that gets passed to any function handling a custom command. This specific example makes use of the `tick` and the optional `player_index` and `parameter` fields. The user is supposed to either call it without any parameter (`"/print_tick"`) or with the `"me"` parameter (`"/print_tick me"`). + * + * ```lua + * commands.add_command("print_tick", nil, function(command) + * if command.player_index ~= nil and command.parameter == "me" then + * game.get_player(command.player_index).print(command.tick) + * else + * game.print(command.tick) + * end + * end) + * ``` + * + * @param name - The desired name of the command (case sensitive). + * @param help - The localised help message. It will be shown to players using the `/help` command. + * @param _function - The function that will be called when this command is invoked. + */ + add_command(name: string, help: LocalisedString, _function: (param1: CustomCommandData) => void): void + /** + * Remove a custom console command. + * + * {@link https://lua-api.factorio.com/next/LuaCommandProcessor.html#LuaCommandProcessor.remove_command View documentation} + * + * @param name - The name of the command to remove (case sensitive). + * @returns Whether the command was successfully removed. Returns `false` if the command didn't exist. + */ + remove_command(name: string): boolean + /** + * Lists the custom commands registered by scripts through `LuaCommandProcessor`. + * + * {@link https://lua-api.factorio.com/next/LuaCommandProcessor.html#LuaCommandProcessor.commands View documentation} + */ + readonly commands: Record + /** + * Lists the built-in commands of the core game. The {@link https://wiki.factorio.com/Console wiki} has an overview of these. + * + * {@link https://lua-api.factorio.com/next/LuaCommandProcessor.html#LuaCommandProcessor.game_commands View documentation} + */ + readonly game_commands: Record + /** This object's name. */ + readonly object_name: "LuaCommandProcessor" +} + +/** + * Control behavior for constant combinators. + * + * {@link https://lua-api.factorio.com/next/LuaConstantCombinatorControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaConstantCombinatorControlBehavior extends LuaControlBehavior { + /** + * Sets the signal at the given index + * + * {@link https://lua-api.factorio.com/next/LuaConstantCombinatorControlBehavior.html#LuaConstantCombinatorControlBehavior.set_signal View documentation} + * + * @param index + * @param signal + */ + set_signal(index: uint, signal: Signal): void + /** + * Gets the signal at the given index. Returned {@link Signal} will not contain signal if none is set for the index. + * + * {@link https://lua-api.factorio.com/next/LuaConstantCombinatorControlBehavior.html#LuaConstantCombinatorControlBehavior.get_signal View documentation} + * + * @param index + */ + get_signal(index: uint): Signal + /** + * The constant combinator parameters + * + * **Note**: Setting to `nil` clears the parameters. + * + * {@link https://lua-api.factorio.com/next/LuaConstantCombinatorControlBehavior.html#LuaConstantCombinatorControlBehavior.parameters View documentation} + */ + parameters: ConstantCombinatorParameters[] + /** + * Turns this constant combinator on and off. + * + * {@link https://lua-api.factorio.com/next/LuaConstantCombinatorControlBehavior.html#LuaConstantCombinatorControlBehavior.enabled View documentation} + */ + enabled: boolean + /** + * The number of signals this constant combinator supports + * + * {@link https://lua-api.factorio.com/next/LuaConstantCombinatorControlBehavior.html#LuaConstantCombinatorControlBehavior.signals_count View documentation} + */ + readonly signals_count: uint + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaConstantCombinatorControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Control behavior for container entities. + * + * {@link https://lua-api.factorio.com/next/LuaContainerControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaContainerControlBehavior extends LuaControlBehavior { + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaContainerControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} + +interface BaseControlSetGuiArrow { + /** + * Where to point to. This field determines what other fields are mandatory. May be `"nowhere"`, `"goal"`, + * `"entity_info"`, `"active_window"`, `"entity"`, `"position"`, `"crafting_queue"`, or `"item_stack"`. + */ + readonly type: + | "nowhere" + | "goal" + | "entity_info" + | "active_window" + | "entity" + | "position" + | "crafting_queue" + | "item_stack" +} + +interface EntityControlSetGuiArrow extends BaseControlSetGuiArrow { + readonly type: "entity" + readonly entity: LuaEntity +} + +interface PositionControlSetGuiArrow extends BaseControlSetGuiArrow { + readonly type: "position" + readonly position: Position +} + +interface CraftingQueueControlSetGuiArrow extends BaseControlSetGuiArrow { + readonly type: "crafting_queue" + readonly crafting_queueindex: uint +} + +interface ItemStackControlSetGuiArrow extends BaseControlSetGuiArrow { + readonly type: "item_stack" + readonly inventory_index: defines.inventory + readonly item_stack_index: uint + /** May be either `"player"` or `"target"`. */ + readonly source: "player" | "target" +} + +interface OtherControlSetGuiArrow extends BaseControlSetGuiArrow { + readonly type: "nowhere" | "goal" | "entity_info" | "active_window" +} + +type ControlSetGuiArrow = + | EntityControlSetGuiArrow + | PositionControlSetGuiArrow + | CraftingQueueControlSetGuiArrow + | ItemStackControlSetGuiArrow + | OtherControlSetGuiArrow + +/** + * This is an abstract base class containing the common functionality between {@link LuaPlayer} and entities (see + * {@link LuaEntity}). When accessing player-related functions through a {@link LuaEntity}, it must refer to a character entity. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html View documentation} + * + * @noSelf + */ +interface LuaControl { + /** + * Get an inventory belonging to this entity. This can be either the "main" inventory or some auxiliary one, like + * the module slots or logistic trash slots. + * + * **Note**: A given {@link defines.inventory} is only meaningful for the corresponding LuaObject type. EG: + * get_inventory(defines.inventory.character_main) is only meaningful if 'this' is a player character. You may get a + * value back but if the type of 'this' isn't the type referred to by the {@link defines.inventory} it's almost + * guaranteed to not be the inventory asked for. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.get_inventory View documentation} + * + * @param inventory + * @returns Or `nil` if this entity doesn't have an inventory with the given index. + */ + get_inventory(inventory: defines.inventory): LuaInventory | undefined + /** + * Gets the main inventory for this character or player if this is a character or player. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.get_main_inventory View documentation} + * + * @returns Or `nil` if this entity is not a character or player. + */ + get_main_inventory(): LuaInventory | undefined + /** + * Can at least some items be inserted? + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.can_insert View documentation} + * + * @param items - Items that would be inserted. + * @returns `true` if at least a part of the given items could be inserted into this inventory. + */ + can_insert(items: ItemStackIdentification): boolean + /** + * Insert items into this entity. This works the same way as inserters or shift-clicking: the "best" inventory is + * chosen automatically. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.insert View documentation} + * + * @param items - Items to insert. + * @returns Number of items actually inserted. + */ + insert(items: ItemStackIdentification): uint + /** + * Create an arrow which points at this entity. This is used in the tutorial. For examples, see `control.lua` in the + * campaign missions. + * + * Other attributes may be specified depending on `type`: + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.set_gui_arrow View documentation} + */ + set_gui_arrow(params: ControlSetGuiArrow): void + /** + * Removes the arrow created by `set_gui_arrow`. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.clear_gui_arrow View documentation} + */ + clear_gui_arrow(): void + /** + * Get the number of all or some items in this entity. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.get_item_count View documentation} + * + * @param item - Prototype name of the item to count. If not specified, count all items. + */ + get_item_count(item?: string): uint + /** + * Does this entity have any item inside it? + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.has_items_inside View documentation} + */ + has_items_inside(): boolean + /** + * Can a given entity be opened or accessed? + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.can_reach_entity View documentation} + * + * @param entity + */ + can_reach_entity(entity: LuaEntity): boolean + /** + * Remove all items from this entity. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.clear_items_inside View documentation} + */ + clear_items_inside(): void + /** + * Remove items from this entity. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.remove_item View documentation} + * + * @param items - Items to remove. + * @returns Number of items actually removed. + */ + remove_item(items: ItemStackIdentification): uint + /** + * Teleport the entity to a given position, possibly on another surface. + * + * **Note**: Some entities may not be teleported. For instance, transport belts won't allow teleportation and this + * method will always return `false` when used on any such entity. + * + * **Note**: You can also pass 1 or 2 numbers as the parameters and they will be used as relative teleport + * coordinates `'teleport(0, 1)'` to move the entity 1 tile positive y. `'teleport(4)'` to move the entity 4 tiles + * to the positive x. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.teleport View documentation} + * + * @param position - Where to teleport to. + * @param surface - Surface to teleport to. If not given, will teleport to the entity's current surface. Only + * players, cars, and spidertrons can be teleported cross-surface. + * @returns `true` when the entity was successfully teleported. + */ + teleport(position: Position, surface?: SurfaceIdentification): boolean + /** + * Select an entity, as if by hovering the mouse above it. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.update_selected_entity View documentation} + * + * @param position - Position of the entity to select + */ + update_selected_entity(position: Position): void + /** + * Unselect any selected entity. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.clear_selected_entity View documentation} + */ + clear_selected_entity(): void + /** + * Disable the flashlight. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.disable_flashlight View documentation} + */ + disable_flashlight(): void + /** + * Enable the flashlight. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.enable_flashlight View documentation} + */ + enable_flashlight(): void + /** + * Is the flashlight enabled. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.is_flashlight_enabled View documentation} + */ + is_flashlight_enabled(): void + /** + * Gets the count of the given recipe that can be crafted. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.get_craftable_count View documentation} + * + * @param recipe - The recipe. + * @returns The count that can be crafted. + */ + get_craftable_count(recipe: string | LuaRecipe): uint + /** + * Begins crafting the given count of the given recipe. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.begin_crafting View documentation} + * + * @returns The count that was actually started crafting. + */ + begin_crafting(params: { + /** The count to craft. */ + readonly count: uint + /** The recipe to craft. */ + readonly recipe: string | LuaRecipe + /** If false and the recipe can't be crafted the requested number of times printing the failure is skipped. */ + readonly silent?: boolean + }): uint + /** + * Cancels crafting the given count of the given crafting queue index. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.cancel_crafting View documentation} + */ + cancel_crafting(params: { + /** The crafting queue index. */ + readonly index: uint + /** The count to cancel crafting. */ + readonly count: uint + }): void + /** + * Mines the given entity as if this player (or character) mined it. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.mine_entity View documentation} + * + * @param entity - The entity to mine + * @param force - Forces mining the entity even if the items can't fit in the player. + * @returns If the mining succeeded. + */ + mine_entity(entity: LuaEntity, force?: boolean): boolean + /** + * Mines the given tile as if this player (or character) mined it. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.mine_tile View documentation} + * + * @param tile - The tile to mine. + * @returns If the mining succeeded. + */ + mine_tile(tile: LuaTile): boolean + /** + * When `true` control adapter is a LuaPlayer object, `false` for entities including characters with players + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.is_player View documentation} + */ + is_player(): boolean + /** + * Open the technology GUI and select a given technology. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.open_technology_gui View documentation} + * + * @param technology - The technology to select after opening the GUI. + */ + open_technology_gui(technology?: TechnologyIdentification): void + /** + * Sets a personal logistic request and auto-trash slot to the given value. + * + * **Note**: This will silently fail if personal logistics are not researched yet. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.set_personal_logistic_slot View documentation} + * + * @param slot_index - The slot to set. + * @param value - The logistic request parameters. + * @returns Whether the slot was set successfully. + */ + set_personal_logistic_slot(slot_index: uint, value: PersonalLogisticParameters): boolean + /** + * Sets a vehicle logistic request and auto-trash slot to the given value. + * + * **Note**: This will silently fail if the vehicle does not use logistics. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.set_vehicle_logistic_slot View documentation} + * + * @param slot_index - The slot to set. + * @param value - The logistic request parameters. + * @returns Whether the slot was set successfully. + */ + set_vehicle_logistic_slot(slot_index: uint, value: PersonalLogisticParameters): boolean + /** + * Gets the parameters of a personal logistic request and auto-trash slot. + * + * **Note**: This will silently return an empty value (`name` will be `nil`) if personal logistics are not researched yet. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.get_personal_logistic_slot View documentation} + * + * @param slot_index - The slot to get. + */ + get_personal_logistic_slot(slot_index: uint): PersonalLogisticParameters + /** + * Gets the parameters of a vehicle logistic request and auto-trash slot. + * + * **Note**: This will silently return an empty value (`name` will be `nil`) if the vehicle does not use logistics. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.get_vehicle_logistic_slot View documentation} + * + * @param slot_index - The slot to get. + */ + get_vehicle_logistic_slot(slot_index: uint): PersonalLogisticParameters + /** + * **Note**: This will silently fail if personal logistics are not researched yet. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.clear_personal_logistic_slot View documentation} + * + * @param slot_index - The slot to clear. + */ + clear_personal_logistic_slot(slot_index: uint): void + /** + * **Note**: This will silently fail if the vehicle does not use logistics. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.clear_vehicle_logistic_slot View documentation} + * + * @param slot_index - The slot to clear. + */ + clear_vehicle_logistic_slot(slot_index: uint): void + /** + * Returns whether the player is holding a blueprint, it takes into account a blueprint as an item as well as + * blueprint from the blueprint record from the blueprint library. Note that the is_cursor_blueprint and + * get_cursor_blueprint_entities refer to the currently selected blueprint, so it returns blueprint related + * information also when holding a blueprint book with a blueprint being selected in it. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.is_cursor_blueprint View documentation} + */ + is_cursor_blueprint(): boolean + /** + * Gets the entities that are part of the currently selected blueprint, regardless of it being in a blueprint book + * or picked from the blueprint library. Returns `nil` if there is no currently selected blueprint. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.get_blueprint_entities View documentation} + */ + get_blueprint_entities(): BlueprintEntity[] | undefined + /** + * Returns whether the player is holding something in the cursor. It takes into account items from the blueprint + * library, as well as items and ghost cursor. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.is_cursor_empty View documentation} + */ + is_cursor_empty(): boolean + /** + * The surface this entity is currently on. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.surface View documentation} + */ + readonly surface: LuaSurface + /** + * Current position of the entity. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.position View documentation} + */ + readonly position: PositionTable + /** + * The vehicle the player is currently sitting in; `nil` if none. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.vehicle View documentation} + */ + readonly vehicle: LuaEntity | undefined + /** + * The force of this entity. Reading will always give a {@link LuaForce}, but it is possible to assign either + * {@link string} or {@link LuaForce} to this attribute to change the force. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.force View documentation} + */ + force: ForceIdentification + /** + * The currently selected entity; `nil` if none. Assigning an entity will select it if selectable otherwise clears selection. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.selected View documentation} + */ + selected: LuaEntity | undefined + /** + * The GUI target the player currently has open; `nil` if none. + * + * **Note**: Write supports any of the types. Read will return the entity, equipment, equipment-grid, player, element or nil. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.opened View documentation} + */ + opened: + | LuaEntity + | LuaItemStack + | LuaEquipment + | LuaEquipmentGrid + | LuaPlayer + | LuaGuiElement + | defines.gui_type + | undefined + /** + * Size of the crafting queue. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.crafting_queue_size View documentation} + */ + readonly crafting_queue_size: uint + /** + * The crafting queue progress [0-1] 0 when no recipe is being crafted. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.crafting_queue_progress View documentation} + */ + readonly crafting_queue_progress: double + /** + * Current walking state. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.walking_state View documentation} + * + * @example + * Make the player go north. Note that a one-shot action like this will only make the player walk for one tick. + * + * ```lua + * game.player.walking_state = {walking = true, direction = defines.direction.north} + * ``` + */ + walking_state: { + /** If `false`, the player is currently not walking; otherwise it's going somewhere */ + readonly walking: boolean + /** Direction where the player is walking */ + readonly direction: defines.direction + } + /** + * Current riding state of this car or the vehicle this player is riding in. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.riding_state View documentation} + */ + riding_state: RidingState + /** + * Current mining state. + * + * **Note**: When the player isn't mining tiles the player will mine what ever entity is currently selected. See + * {@link LuaControl.selected LuaControl::selected} and + * {@link LuaControl.update_selected_entity LuaControl::update_selected_entity}. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.mining_state View documentation} + */ + mining_state: { + /** Whether the player is mining at all */ + readonly mining: boolean + /** What tiles the player is mining; only used when the player is mining tiles (holding a tile in the cursor). */ + readonly position?: Position + } + /** + * Current shooting state. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.shooting_state View documentation} + */ + shooting_state: { + /** The current state */ + readonly state: defines.shooting + /** The position being shot at */ + readonly position: Position + } + /** + * Current item-picking state. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.picking_state View documentation} + */ + picking_state: boolean + /** + * Current repair state. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.repair_state View documentation} + */ + repair_state: { + /** The current state */ + readonly repairing: boolean + /** The position being repaired */ + readonly position: Position + } + /** + * The player's cursor stack, or `nil` if the player controller is a spectator. Even though this property is marked + * as read-only, it returns a {@link LuaItemStack}, meaning it can be manipulated like so: + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.cursor_stack View documentation} + * + * @example + * ```lua + * player.cursor_stack.clear() + * ``` + */ + readonly cursor_stack: LuaItemStack | undefined + /** + * The ghost prototype in the player's cursor. + * + * **Note**: When read, it will be a {@link LuaItemPrototype}. + * + * **Note**: Items in the cursor stack will take priority over the cursor ghost. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.cursor_ghost View documentation} + */ + cursor_ghost: ItemPrototypeIdentification + /** + * `true` if the player is in a vehicle. Writing to this attribute puts the player in or out of a vehicle. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.driving View documentation} + */ + driving: boolean + /** + * Gets the current crafting queue items. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.crafting_queue View documentation} + */ + readonly crafting_queue: CraftingQueueItem[] + /** + * The current combat robots following the character + * + * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character(see + * {@link LuaPlayer.character LuaPlayer::character}). + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.following_robots View documentation} + */ + readonly following_robots: LuaEntity[] + /** + * When `true` hand crafting is free and instant + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.cheat_mode View documentation} + */ + cheat_mode: boolean + /** + * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see + * {@link LuaPlayer.character LuaPlayer::character}). + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_crafting_speed_modifier View documentation} + */ + character_crafting_speed_modifier: double + /** + * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see + * {@link LuaPlayer.character LuaPlayer::character}). + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_mining_speed_modifier View documentation} + */ + character_mining_speed_modifier: double + /** + * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see + * {@link LuaPlayer.character LuaPlayer::character}). + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_additional_mining_categories View documentation} + */ + character_additional_mining_categories: string[] + /** + * Modifies the running speed of this character by the given value as a percentage. Setting the running modifier to + * `0.5` makes the character run 50% faster. The minimum value of `-1` reduces the movement speed by 100%, resulting + * in a speed of `0`. + * + * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see + * {@link LuaPlayer.character LuaPlayer::character}). + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_running_speed_modifier View documentation} + */ + character_running_speed_modifier: double + /** + * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see + * {@link LuaPlayer.character LuaPlayer::character}). + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_build_distance_bonus View documentation} + */ + character_build_distance_bonus: uint + /** + * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see + * {@link LuaPlayer.character LuaPlayer::character}). + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_item_drop_distance_bonus View documentation} + */ + character_item_drop_distance_bonus: uint + /** + * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see + * {@link LuaPlayer.character LuaPlayer::character}). + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_reach_distance_bonus View documentation} + */ + character_reach_distance_bonus: uint + /** + * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see + * {@link LuaPlayer.character LuaPlayer::character}). + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_resource_reach_distance_bonus View documentation} + */ + character_resource_reach_distance_bonus: uint + /** + * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see + * {@link LuaPlayer.character LuaPlayer::character}). + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_item_pickup_distance_bonus View documentation} + */ + character_item_pickup_distance_bonus: uint + /** + * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see + * {@link LuaPlayer.character LuaPlayer::character}). + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_loot_pickup_distance_bonus View documentation} + */ + character_loot_pickup_distance_bonus: uint + /** + * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see + * {@link LuaPlayer.character LuaPlayer::character}). + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_inventory_slots_bonus View documentation} + */ + character_inventory_slots_bonus: uint + /** + * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see + * {@link LuaPlayer.character LuaPlayer::character}). + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_trash_slot_count_bonus View documentation} + */ + character_trash_slot_count_bonus: uint + /** + * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see + * {@link LuaPlayer.character LuaPlayer::character}). + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_maximum_following_robot_count_bonus View documentation} + */ + character_maximum_following_robot_count_bonus: uint + /** + * **Note**: When called on a {@link LuaPlayer}, it must be associated with a character (see + * {@link LuaPlayer.character LuaPlayer::character}). + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_health_bonus View documentation} + */ + character_health_bonus: float + /** + * If personal logistic requests are enabled for this character or players character. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_personal_logistic_requests_enabled View documentation} + */ + character_personal_logistic_requests_enabled: boolean + /** + * If personal logistic requests are enabled for this vehicle (spidertron). + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.vehicle_logistic_requests_enabled View documentation} + */ + vehicle_logistic_requests_enabled: boolean + /** + * Returns the {@link defines.gui_type} or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.opened_gui_type View documentation} + */ + readonly opened_gui_type: defines.gui_type | undefined + /** + * The build distance of this character or max uint when not a character or player connected to a character. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.build_distance View documentation} + */ + readonly build_distance: uint + /** + * The item drop distance of this character or max uint when not a character or player connected to a character. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.drop_item_distance View documentation} + */ + readonly drop_item_distance: uint + /** + * The reach distance of this character or max uint when not a character or player connected to a character. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.reach_distance View documentation} + */ + readonly reach_distance: uint + /** + * The item pickup distance of this character or max double when not a character or player connected to a character. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.item_pickup_distance View documentation} + */ + readonly item_pickup_distance: double + /** + * The loot pickup distance of this character or max double when not a character or player connected to a character. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.loot_pickup_distance View documentation} + */ + readonly loot_pickup_distance: double + /** + * The resource reach distance of this character or max double when not a character or player connected to a character. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.resource_reach_distance View documentation} + */ + readonly resource_reach_distance: double + /** + * If this character entity is in combat. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.in_combat View documentation} + */ + readonly in_combat: boolean + /** + * Gets the current movement speed of this character, including effects from exoskeletons, tiles, stickers and shooting. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_running_speed View documentation} + */ + readonly character_running_speed: double + /** + * Gets the current mining progress between 0 and 1 of this character, or 0 if they aren't mining. + * + * {@link https://lua-api.factorio.com/next/LuaControl.html#LuaControl.character_mining_progress View documentation} + */ + readonly character_mining_progress: double +} + +/** + * The control behavior for an entity. Inserters have logistic network and circuit network behavior logic, lamps have + * circuit logic and so on. This is an abstract base class that concrete control behaviors inherit. + * + * **Note**: An control reference becomes invalid once the control behavior is removed or the entity (see + * {@link LuaEntity}) it resides in is destroyed. + * + * {@link https://lua-api.factorio.com/next/LuaControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaControlBehavior { + /** + * {@link https://lua-api.factorio.com/next/LuaControlBehavior.html#LuaControlBehavior.get_circuit_network View documentation} + * + * @param wire - Wire color of the network connected to this entity. + * @param circuit_connector - The connector to get circuit network for. Must be specified for entities with more + * than one circuit network connector. + * @returns The circuit network or nil. + */ + get_circuit_network( + wire: defines.wire_type, + circuit_connector?: defines.circuit_connector_id + ): LuaCircuitNetwork | undefined + /** + * The concrete type of this control behavior. + * + * {@link https://lua-api.factorio.com/next/LuaControlBehavior.html#LuaControlBehavior.type View documentation} + */ + readonly type: defines.control_behavior.type + /** + * The entity this control behavior belongs to. + * + * {@link https://lua-api.factorio.com/next/LuaControlBehavior.html#LuaControlBehavior.entity View documentation} + */ + readonly entity: LuaEntity +} + +/** + * A custom tag that shows on the map view. + * + * {@link https://lua-api.factorio.com/next/LuaCustomChartTag.html View documentation} + * + * @noSelf + */ +interface LuaCustomChartTag { + /** + * Destroys this tag. + * + * {@link https://lua-api.factorio.com/next/LuaCustomChartTag.html#LuaCustomChartTag.destroy View documentation} + */ + destroy(): void + /** + * This tag's icon, if it has one. Writing `nil` removes it. + * + * {@link https://lua-api.factorio.com/next/LuaCustomChartTag.html#LuaCustomChartTag.icon View documentation} + */ + icon: SignalID | undefined + /** + * The player who last edited this tag. + * + * {@link https://lua-api.factorio.com/next/LuaCustomChartTag.html#LuaCustomChartTag.last_user View documentation} + */ + last_user: LuaPlayer + /** + * The position of this tag. + * + * {@link https://lua-api.factorio.com/next/LuaCustomChartTag.html#LuaCustomChartTag.position View documentation} + */ + readonly position: PositionTable + text: string + /** + * The unique ID for this tag on this force. + * + * {@link https://lua-api.factorio.com/next/LuaCustomChartTag.html#LuaCustomChartTag.tag_number View documentation} + */ + readonly tag_number: uint + /** + * The force this tag belongs to. + * + * {@link https://lua-api.factorio.com/next/LuaCustomChartTag.html#LuaCustomChartTag.force View documentation} + */ + readonly force: LuaForce + /** + * The surface this tag belongs to. + * + * {@link https://lua-api.factorio.com/next/LuaCustomChartTag.html#LuaCustomChartTag.surface View documentation} + */ + readonly surface: LuaSurface + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaCustomChartTag" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a custom input. + * + * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html View documentation} + * + * @noSelf + */ +interface LuaCustomInputPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * The default key sequence for this custom input. + * + * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.key_sequence View documentation} + */ + readonly key_sequence: string + /** + * The default alternative key sequence for this custom input. `nil` when not defined. + * + * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.alternative_key_sequence View documentation} + */ + readonly alternative_key_sequence: string | undefined + /** + * The linked game control name or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.linked_game_control View documentation} + */ + readonly linked_game_control: string | undefined + /** + * The consuming type: `"none"` or `"game-only"`. + * + * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.consuming View documentation} + */ + readonly consuming: "none" | "game-only" + /** + * The action that happens when this custom input is triggered. + * + * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.action View documentation} + */ + readonly action: string + /** + * If this custom input is enabled. Disabled custom inputs exist but are not used by the game. + * + * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.enabled View documentation} + */ + readonly enabled: boolean + /** + * If this custom input is enabled while using the spectator controller. + * + * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.enabled_while_spectating View documentation} + */ + readonly enabled_while_spectating: boolean + /** + * If this custom input is enabled while using the cutscene controller. + * + * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.enabled_while_in_cutscene View documentation} + */ + readonly enabled_while_in_cutscene: boolean + /** + * If this custom input will include the selected prototype (if any) when triggered. + * + * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.include_selected_prototype View documentation} + */ + readonly include_selected_prototype: boolean + /** + * The item that gets spawned when this custom input is fired or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaCustomInputPrototype.html#LuaCustomInputPrototype.item_to_spawn View documentation} + */ + readonly item_to_spawn: LuaItemPrototype | undefined + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaCustomInputPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +type CustomTableIndex +/** + * Access an element of this custom table. + * + * {@link https://lua-api.factorio.com/next/LuaCustomTable.html#LuaCustomTable.operator%20[] View documentation} + */ = { + [P in K]: V +} + +/** @noSelf */ +interface LuaCustomTableMembers { + /** + * Number of elements in this table. + * + * {@link https://lua-api.factorio.com/next/LuaCustomTable.html#LuaCustomTable.operator%20# View documentation} + */ + readonly length: LuaLengthMethod + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaCustomTable" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Lazily evaluated table. For performance reasons, we sometimes return a custom table-like type instead of a native Lua + * table. This custom type lazily constructs the necessary Lua wrappers of the corresponding C++ objects, therefore + * preventing their unnecessary construction in some cases. + * + * There are some notable consequences to the usage of a custom table type rather than the native Lua table type: + * Iterating a custom table is only possible using the `pairs` Lua function; `ipairs` won't work. Another key difference + * is that custom tables cannot be serialised into a game save file -- if saving the game would require serialisation of + * a custom table, an error will be displayed and the game will not be saved. + * + * {@link https://lua-api.factorio.com/next/LuaCustomTable.html View documentation} + * + * @example + * In previous versions of Factorio, this would create a {@link LuaPlayer} instance for every player in the game, even though only one such wrapper is needed. In the current version, accessing {@link LuaGameScript.players game.players} by itself does not create any {@link LuaPlayer} instances; they are created lazily when accessed. Therefore, this example only constructs one {@link LuaPlayer} instance, no matter how many elements there are in `game.players`. + * + * ```lua + * game.players["Oxyd"].character.die() + * ``` + * + * @example + * Custom tables may be iterated using `pairs`. + * + * ```lua + * for _, p in pairs(game.players) do game.player.print(p.name); end + * ``` + * + * @example + * The following will produce no output because `ipairs` is not supported with custom tables. + * + * ```lua + * for _, p in ipairs(game.players) do game.player.print(p.name); end -- incorrect; use pairs instead + * ``` + * + * @example + * This statement will execute successfully and `global.p` will be useable as one might expect. However, as soon as the user tries to save the game, a "LuaCustomTable cannot be serialized" error will be shown. The game will remain unsaveable so long as `global.p` refers to an instance of a custom table. + * + * ```lua + * global.p = game.players -- This has high potential to make the game unsaveable + * ``` + */ +type LuaCustomTable = LuaCustomTableMembers & CustomTableIndex + +/** + * Prototype of a damage. + * + * {@link https://lua-api.factorio.com/next/LuaDamagePrototype.html View documentation} + * + * @noSelf + */ +interface LuaDamagePrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaDamagePrototype.html#LuaDamagePrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaDamagePrototype.html#LuaDamagePrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * Whether this damage type is hidden from entity tooltips. + * + * {@link https://lua-api.factorio.com/next/LuaDamagePrototype.html#LuaDamagePrototype.hidden View documentation} + */ + readonly hidden: boolean + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaDamagePrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Control behavior for decider combinators. + * + * {@link https://lua-api.factorio.com/next/LuaDeciderCombinatorControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaDeciderCombinatorControlBehavior extends LuaCombinatorControlBehavior { + /** + * The decider combinator parameters + * + * **Note**: Setting to `nil` clears the parameters. + * + * {@link https://lua-api.factorio.com/next/LuaDeciderCombinatorControlBehavior.html#LuaDeciderCombinatorControlBehavior.parameters View documentation} + */ + parameters: DeciderCombinatorParameters + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaDeciderCombinatorControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of an optimized decorative. + * + * {@link https://lua-api.factorio.com/next/LuaDecorativePrototype.html View documentation} + * + * @noSelf + */ +interface LuaDecorativePrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaDecorativePrototype.html#LuaDecorativePrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaDecorativePrototype.html#LuaDecorativePrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * The bounding box used for collision checking. + * + * {@link https://lua-api.factorio.com/next/LuaDecorativePrototype.html#LuaDecorativePrototype.collision_box View documentation} + */ + readonly collision_box: BoundingBoxTable + /** + * The collision masks this decorative uses + * + * {@link https://lua-api.factorio.com/next/LuaDecorativePrototype.html#LuaDecorativePrototype.collision_mask View documentation} + */ + readonly collision_mask: CollisionMask + readonly collision_mask_with_flags: CollisionMaskWithFlags + /** + * Autoplace specification for this decorative prototype. `nil` if none. + * + * {@link https://lua-api.factorio.com/next/LuaDecorativePrototype.html#LuaDecorativePrototype.autoplace_specification View documentation} + */ + readonly autoplace_specification: AutoplaceSpecification | undefined + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaDecorativePrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of an electric energy source. + * + * {@link https://lua-api.factorio.com/next/LuaElectricEnergySourcePrototype.html View documentation} + * + * @noSelf + */ +interface LuaElectricEnergySourcePrototype { + readonly buffer_capacity: double + readonly usage_priority: string + readonly input_flow_limit: double + readonly output_flow_limit: double + readonly drain: double + readonly emissions: double + readonly render_no_network_icon: boolean + readonly render_no_power_icon: boolean + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaElectricEnergySourcePrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * The primary interface for interacting with entities through the Lua API. Entities are everything that exists on the + * map except for tiles (see {@link LuaTile}). + * + * Most functions on LuaEntity also work when the entity is contained in a ghost. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html View documentation} + * + * @noSelf + */ +interface LuaEntity extends LuaControl { + /** + * Gets the entities output inventory if it has one. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_output_inventory View documentation} + * + * @returns A reference to the entities output inventory. + */ + get_output_inventory(): LuaInventory + /** + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_module_inventory View documentation} + * + * @returns Inventory for storing modules of this entity; `nil` if this entity has no module inventory. + */ + get_module_inventory(): LuaInventory | undefined + /** + * The fuel inventory for this entity or `nil` if this entity doesn't have a fuel inventory. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_fuel_inventory View documentation} + */ + get_fuel_inventory(): LuaInventory | undefined + /** + * The burnt result inventory for this entity or `nil` if this entity doesn't have a burnt result inventory. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_burnt_result_inventory View documentation} + */ + get_burnt_result_inventory(): LuaInventory | undefined + /** + * Damages the entity. + * + * *Can only be used if this is EntityWithHealth* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.damage View documentation} + * + * @param damage - The amount of damage to be done + * @param force - The force that will be doing the damage. + * @param type - The type of damage to be done, defaults to "impact". + * @param dealer - The entity to consider as the damage dealer. + * @returns The total damage actually applied after resistances. + */ + damage(damage: float, force: ForceIdentification, type?: string, dealer?: LuaEntity): float + /** + * Checks if the entity can be destroyed + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.can_be_destroyed View documentation} + * + * @returns If the entity can be destroyed. + */ + can_be_destroyed(): boolean + /** + * Destroys the entity. + * + * **Note**: Not all entities can be destroyed - things such as rails under trains cannot be destroyed until the + * train is moved or destroyed. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.destroy View documentation} + * + * @returns Returns `false` if the entity was valid and destruction failed, `true` in all other cases. + */ + destroy(params?: { + /** Whether neighbouring cliffs should be corrected. Defaults to `false`. */ + readonly do_cliff_correction?: boolean + /** If `true`, {@link ScriptRaisedDestroyEvent script_raised_destroy} will be called. Defaults to `false`. */ + readonly raise_destroy?: boolean + }): boolean + /** + * Give the entity a command. + * + * *Can only be used if this is Unit* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_command View documentation} + * + * @param command + */ + set_command(command: Command): void + /** + * Give the entity a distraction command. + * + * *Can only be used if this is Unit* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_distraction_command View documentation} + * + * @param command + */ + set_distraction_command(command: Command): void + /** + * Has this unit been assigned a command? + * + * *Can only be used if this is Unit* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.has_command View documentation} + */ + has_command(): boolean + /** + * Immediately kills the entity. Does nothing if the entity doesn't have health. + * + * Unlike {@link LuaEntity.destroy LuaEntity::destroy}, `die` will trigger the + * {@link OnEntityDiedEvent on_entity_died} event and the entity will produce a corpse and drop loot if it has any. + * + * **Note**: If `force` is not specified, `on_entity_died` will blame the `"neutral"` force. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.die View documentation} + * + * @example + * This function can be called with only the `cause` argument and no `force`: + * + * ```lua + * entity.die(nil, killer_entity) + * ``` + * + * @param force - The force to attribute the kill to. + * @param cause - The cause to attribute the kill to. + * @returns Whether the entity was successfully killed. + */ + die(force?: ForceIdentification, cause?: LuaEntity): boolean + /** + * Test whether this entity's prototype has a flag set. + * + * **Note**: `entity.has_flag(f)` is a shortcut for `entity.prototype.has_flag(f)`. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.has_flag View documentation} + * + * @param flag - The flag to test + * @returns `true` if the entity has the given flag set. + */ + has_flag(flag: string): boolean + /** + * Same as {@link LuaEntity.has_flag LuaEntity::has_flag} but targets the inner entity on a entity ghost. + * + * *Can only be used if this is EntityGhost* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.ghost_has_flag View documentation} + * + * @param flag - The flag to test + * @returns `true` if the entity has the given flag set. + */ + ghost_has_flag(flag: string): boolean + /** + * Offer a thing on the market. + * + * *Can only be used if this is Market* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.add_market_item View documentation} + * + * @example + * Adds market offer, 1 copper ore for 10 iron ore. + * + * ```lua + * market.add_market_item{price={{"iron-ore", 10}}, offer={type="give-item", item="copper-ore"}} + * ``` + * + * @example + * Adds market offer, 1 copper ore for 5 iron ore and 5 stone ore. + * + * ```lua + * market.add_market_item{price={{"iron-ore", 5}, {"stone", 5}}, offer={type="give-item", item="copper-ore"}} + * ``` + * + * @param offer + */ + add_market_item(offer: Offer): void + /** + * Remove an offer from a market. + * + * **Note**: The other offers are moved down to fill the gap created by removing the offer, which decrements the + * overall size of the offer array. + * + * *Can only be used if this is Market* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.remove_market_item View documentation} + * + * @param offer - Index of offer to remove. + * @returns `true` if the offer was successfully removed; `false` when the given index was not valid. + */ + remove_market_item(offer: uint): boolean + /** + * Get all offers in a market as an array. + * + * *Can only be used if this is Market* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_market_items View documentation} + */ + get_market_items(): Offer[] + /** + * Removes all offers from a market. + * + * *Can only be used if this is Market* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.clear_market_items View documentation} + */ + clear_market_items(): void + /** + * Connect two devices with a circuit wire or copper cable. Depending on which type of connection should be made, + * there are different procedures: + * + * - To connect two electric poles, `target` must be a {@link LuaEntity} that specifies another electric pole. This + * will connect them with copper cable. + * - To connect two devices with circuit wire, `target` must be a table of type {@link WireConnectionDefinition}. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.connect_neighbour View documentation} + * + * @param target - The target with which to establish a connection. + * @returns Whether the connection was successfully formed. + */ + connect_neighbour(target: LuaEntity | WireConnectionDefinition): boolean + /** + * Disconnect circuit wires or copper cables between devices. Depending on which type of connection should be cut, + * there are different procedures: + * + * - To remove all copper cables, leave the `target` parameter blank: `pole.disconnect_neighbour()`. + * - To remove all wires of a specific color, set `target` to {@link defines.wire_type.red} or {@link defines.wire_type.green}. + * - To remove a specific copper cable between two electric poles, `target` must be a {@link LuaEntity} that specifies + * the other pole: `pole1.disconnect_neighbour(pole2)`. + * - To remove a specific circuit wire, `target` must be a table of type {@link WireConnectionDefinition}. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.disconnect_neighbour View documentation} + * + * @param target - The target with which to cut a connection. + */ + disconnect_neighbour(target?: defines.wire_type | LuaEntity | WireConnectionDefinition): void + /** + * Sets the entity to be deconstructed by construction robots. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.order_deconstruction View documentation} + * + * @param force - The force whose robots are supposed to do the deconstruction. + * @param player - The player to set the last_user to if any. + * @returns If the entity was marked for deconstruction. + */ + order_deconstruction(force: ForceIdentification, player?: PlayerIdentification): boolean + /** + * Cancels deconstruction if it is scheduled, does nothing otherwise. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.cancel_deconstruction View documentation} + * + * @param force - The force who did the deconstruction order. + * @param player - The player to set the last_user to if any. + */ + cancel_deconstruction(force: ForceIdentification, player?: PlayerIdentification): void + /** + * Is this entity marked for deconstruction? + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.to_be_deconstructed View documentation} + */ + to_be_deconstructed(): boolean + /** + * Sets the entity to be upgraded by construction robots. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.order_upgrade View documentation} + * + * @returns If the entity was marked for upgrade. + */ + order_upgrade(params: { + /** The force whose robots are supposed to do the upgrade. */ + readonly force: ForceIdentification + /** The prototype of the entity to upgrade to. */ + readonly target: EntityPrototypeIdentification + readonly player?: PlayerIdentification + /** The new direction if any. */ + readonly direction?: defines.direction + }): boolean + /** + * Cancels upgrade if it is scheduled, does nothing otherwise. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.cancel_upgrade View documentation} + * + * @param force - The force who did the upgrade order. + * @param player - The player to set the last_user to if any. + * @returns If the cancel was successful. + */ + cancel_upgrade(force: ForceIdentification, player?: PlayerIdentification): boolean + /** + * Is this entity marked for upgrade? + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.to_be_upgraded View documentation} + */ + to_be_upgraded(): boolean + /** + * Get a logistic requester slot. + * + * **Note**: Useable only on entities that have requester slots. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_request_slot View documentation} + * + * @param slot - The slot index. + * @returns Contents of the specified slot; `nil` if the given slot contains no request. + */ + get_request_slot(slot: uint): SimpleItemStack | undefined + /** + * Set a logistic requester slot. + * + * **Note**: Useable only on entities that have requester slots. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_request_slot View documentation} + * + * @param request - What to request. + * @param slot - The slot index. + * @returns If the slot was set. + */ + set_request_slot(request: ItemStackIdentification, slot: uint): boolean + /** + * Clear a logistic requester slot. + * + * **Note**: Useable only on entities that have requester slots. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.clear_request_slot View documentation} + * + * @param slot - The slot index. + */ + clear_request_slot(slot: uint): void + /** + * Returns whether a craft is currently in process. It does not indicate whether progress is currently being made, + * but whether any crafting action has made progress in this machine. + * + * *Can only be used if this is CraftingMachine* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_crafting View documentation} + */ + is_crafting(): void + /** + * *Can only be used if this is Gate* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_opened View documentation} + * + * @returns `true` if this gate is currently opened. + */ + is_opened(): boolean + /** + * *Can only be used if this is Gate* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_opening View documentation} + * + * @returns `true` if this gate is currently opening. + */ + is_opening(): boolean + /** + * *Can only be used if this is Gate* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_closed View documentation} + * + * @returns `true` if this gate is currently closed. + */ + is_closed(): boolean + /** + * *Can only be used if this is Gate* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_closing View documentation} + * + * @returns `true` if this gate is currently closing + */ + is_closing(): boolean + /** + * *Can only be used if this is Gate* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.request_to_open View documentation} + * + * @param force - The force that requests the gate to be open. + * @param extra_time - Extra ticks to stay open. + */ + request_to_open(force: ForceIdentification, extra_time?: uint): void + /** + * *Can only be used if this is Gate* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.request_to_close View documentation} + * + * @param force - The force that requests the gate to be closed. + */ + request_to_close(force: ForceIdentification): void + /** + * Get a transport line of a belt or belt connectable entity. + * + * *Can only be used if this is TransportBeltConnectable* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_transport_line View documentation} + * + * @param index - Index of the requested transport line. + */ + get_transport_line(index: uint): LuaTransportLine + /** + * Get the maximum transport line index of a belt or belt connectable entity. + * + * *Can only be used if this is TransportBeltConnectable* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_max_transport_line_index View documentation} + */ + get_max_transport_line_index(): uint + /** + * *Can only be used if this is RocketSilo* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.launch_rocket View documentation} + * + * @returns `true` if the rocket was successfully launched. Return value of `false` means the silo is not ready for launch. + */ + launch_rocket(): boolean + /** + * Revive a ghost. I.e. turn it from a ghost to a real entity or tile. + * + * **Note**: If this is an entity ghost and it is successfully revived this will also return the revived entity or + * `nil` as a second return value and possibly item request proxy as the third parameter depending on value of + * return_item_request_proxy. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.revive View documentation} + * + * @returns Any items the new real entity collided with or `nil` if the ghost could not be revived. + */ + revive(params?: { + /** If `true` the function will return item request proxy as the third parameter. */ + readonly return_item_request_proxy?: boolean + /** + * If true, and an entity ghost; {@link ScriptRaisedReviveEvent script_raised_revive} will be called. Else if + * true, and a tile ghost; {@link ScriptRaisedSetTilesEvent script_raised_set_tiles} will be called. + */ + readonly raise_revive?: boolean + }): LuaMultiReturn<[undefined] | [Record, LuaEntity, LuaEntity | undefined]> + /** + * Revives a ghost silently. + * + * **Note**: If this is an entity ghost and it is successfully revived this will also return the revived entity or + * `nil` as a second return value and possibly item request proxy as the third parameter depending on value of + * return_item_request_proxy. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.silent_revive View documentation} + * + * @returns Any items the new real entity collided with or `nil` if the ghost could not be revived. + */ + silent_revive(params?: { + /** If `true` the function will return item request proxy as the third parameter. */ + readonly return_item_request_proxy?: boolean + /** + * If true, and an entity ghost; {@link ScriptRaisedReviveEvent script_raised_revive} will be called. Else if + * true, and a tile ghost; {@link ScriptRaisedSetTilesEvent script_raised_set_tiles} will be called. + */ + readonly raise_revive?: boolean + }): LuaMultiReturn<[undefined] | [Record, LuaEntity, LuaEntity | undefined]> + /** + * *Can only be used if this is Rail* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_connected_rail View documentation} + * + * @returns Rail connected in the specified manner to this one. + */ + get_connected_rail(params: { + readonly rail_direction: defines.rail_direction + readonly rail_connection_direction: defines.rail_connection_direction + }): LuaEntity + /** + * Get the rails that this signal is connected to. + * + * *Can only be used if this is RailSignal* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_connected_rails View documentation} + */ + get_connected_rails(): LuaEntity[] + /** + * Get the rail signal or train stop at the start/end of the rail segment this rail is in, or `nil` if the rail + * segment doesn't start/end with a signal nor a train stop. + * + * **Note**: A rail segment is a continuous section of rail with no branches, signals, nor train stops. + * + * *Can only be used if this is Rail* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_rail_segment_entity View documentation} + * + * @param direction - The direction of travel relative to this rail. + * @param in_else_out - If true, gets the entity at the entrance of the rail segment, otherwise gets the entity at + * the exit of the rail segment. + */ + get_rail_segment_entity(direction: defines.rail_direction, in_else_out: boolean): LuaEntity | undefined + /** + * Get the rail at the end of the rail segment this rail is in. + * + * **Note**: A rail segment is a continuous section of rail with no branches, signals, nor train stops. + * + * **Note**: This function has a second return value. A {@link defines.rail_direction} that points out of the rail + * segment from the end rail. + * + * *Can only be used if this is Rail* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_rail_segment_end View documentation} + * + * @param direction + */ + get_rail_segment_end(direction: defines.rail_direction): LuaMultiReturn<[LuaEntity, defines.rail_direction]> + /** + * Get the length of the rail segment this rail is in. + * + * **Note**: A rail segment is a continuous section of rail with no branches, signals, nor train stops. + * + * *Can only be used if this is Rail* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_rail_segment_length View documentation} + */ + get_rail_segment_length(): double + /** + * Get a rail from each rail segment that overlaps with this rail's rail segment. + * + * **Note**: A rail segment is a continuous section of rail with no branches, signals, nor train stops. + * + * *Can only be used if this is Rail* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_rail_segment_overlaps View documentation} + */ + get_rail_segment_overlaps(): LuaEntity[] + /** + * Get the filter for a slot in an inserter, loader, or logistic storage container. + * + * **Note**: The entity must allow filters. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_filter View documentation} + * + * @param slot_index - Index of the slot to get the filter for. + * @returns Prototype name of the item being filtered. `nil` if the given slot has no filter. + */ + get_filter(slot_index: uint): string | undefined + /** + * Set the filter for a slot in an inserter, loader, or logistic storage container. + * + * **Note**: The entity must allow filters. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_filter View documentation} + * + * @param slot_index - Index of the slot to set the filter for. + * @param item - Prototype name of the item to filter. + */ + set_filter(slot_index: uint, item: string): void + /** + * Gets the filter for this infinity container at the given index or `nil` if the filter index doesn't exist or is empty. + * + * *Can only be used if this is InfinityContainer* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_infinity_container_filter View documentation} + * + * @param index - The index to get. + */ + get_infinity_container_filter(index: uint): InfinityInventoryFilter | undefined + /** + * Sets the filter for this infinity container at the given index. + * + * *Can only be used if this is InfinityContainer* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_infinity_container_filter View documentation} + * + * @param index - The index to set. + * @param filter - The new filter or `nil` to clear the filter. + */ + set_infinity_container_filter(index: uint, filter: InfinityInventoryFilter | undefined): void + /** + * Gets the filter for this infinity pipe or `nil` if the filter is empty. + * + * *Can only be used if this is InfinityPipe* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_infinity_pipe_filter View documentation} + */ + get_infinity_pipe_filter(): InfinityPipeFilter | undefined + /** + * Sets the filter for this infinity pipe. + * + * *Can only be used if this is InfinityPipe* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_infinity_pipe_filter View documentation} + * + * @param filter - The new filter or `nil` to clear the filter. + */ + set_infinity_pipe_filter(filter: InfinityPipeFilter | undefined): void + /** + * Gets the heat setting for this heat interface. + * + * *Can only be used if this is HeatInterface* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_heat_setting View documentation} + */ + get_heat_setting(): HeatSetting + /** + * Sets the heat setting for this heat interface. + * + * *Can only be used if this is HeatInterface* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_heat_setting View documentation} + * + * @param filter - The new setting. + */ + set_heat_setting(filter: HeatSetting): void + /** + * Gets the control behavior of the entity (if any). + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_control_behavior View documentation} + * + * @returns The control behavior or nil. + */ + get_control_behavior(): LuaControlBehavior | undefined + /** + * Gets (and or creates if needed) the control behavior of the entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_or_create_control_behavior View documentation} + * + * @returns The control behavior or nil. + */ + get_or_create_control_behavior(): LuaControlBehavior | undefined + /** + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_circuit_network View documentation} + * + * @param wire - Wire color of the network connected to this entity. + * @param circuit_connector - The connector to get circuit network for. Must be specified for entities with more + * than one circuit network connector. + * @returns The circuit network or nil. + */ + get_circuit_network( + wire: defines.wire_type, + circuit_connector?: defines.circuit_connector_id + ): LuaCircuitNetwork | undefined + /** + * Read a single signal from the combined circuit networks. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_merged_signal View documentation} + * + * @param signal - The signal to read. + * @param circuit_connector - The connector to get signals for. Must be specified for entities with more than one + * circuit network connector. + * @returns The current value of the signal. + */ + get_merged_signal(signal: SignalID, circuit_connector?: defines.circuit_connector_id): int + /** + * The merged circuit network signals or `nil` if there are no signals. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_merged_signals View documentation} + * + * @param circuit_connector - The connector to get signals for. Must be specified for entities with more than one + * circuit network connector. + * @returns The sum of signals on both the red and green networks, or nil if it doesn't have a circuit connector. + */ + get_merged_signals(circuit_connector?: defines.circuit_connector_id): Signal[] | undefined + /** + * Whether this entity supports a backer name. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.supports_backer_name View documentation} + */ + supports_backer_name(): boolean + /** + * Copies settings from the given entity onto this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.copy_settings View documentation} + * + * @param entity + * @param by_player - If provided, the copying is done 'as' this player and + * {@link OnEntitySettingsPastedEvent on_entity_settings_pasted} is triggered. + * @returns Any items removed from this entity as a result of copying the settings. + */ + copy_settings(entity: LuaEntity, by_player?: PlayerIdentification): Record + /** + * Gets all the `LuaLogisticPoint`s that this entity owns. Optionally returns only the point specified by the index parameter. + * + * **Note**: When `index` is not given, this will be a single `LuaLogisticPoint` for most entities. For some (such + * as the player character), it can be zero or more. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_logistic_point View documentation} + * + * @param index - If provided, only returns the `LuaLogisticPoint` specified by this index. + */ + get_logistic_point(index?: defines.logistic_member_index): LuaLogisticPoint | LuaLogisticPoint[] + /** + * Plays a note with the given instrument and note. + * + * *Can only be used if this is ProgrammableSpeaker* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.play_note View documentation} + * + * @param instrument + * @param note + * @returns If the request is valid. The sound may or may not be played depending on polyphony settings. + */ + play_note(instrument: uint, note: uint): boolean + /** + * Connects the rolling stock in the given direction. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.connect_rolling_stock View documentation} + * + * @param direction + * @returns If any connection was made + */ + connect_rolling_stock(direction: defines.rail_direction): boolean + /** + * Tries to disconnect this rolling stock in the given direction. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.disconnect_rolling_stock View documentation} + * + * @param direction + * @returns If anything was disconnected + */ + disconnect_rolling_stock(direction: defines.rail_direction): boolean + /** + * Reconnect loader, beacon, cliff and mining drill connections to entities that might have been teleported out or + * in by the script. The game doesn't do this automatically as we don't want to loose performance by checking this + * in normal games. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.update_connections View documentation} + */ + update_connections(): void + /** + * Current recipe being assembled by this machine or `nil` if no recipe is set. + * + * *Can only be used if this is CraftingMachine* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_recipe View documentation} + */ + get_recipe(): LuaRecipe | undefined + /** + * Sets the current recipe in this assembly machine. + * + * *Can only be used if this is CraftingMachine* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_recipe View documentation} + * + * @param recipe - The new recipe or `nil` to clear the recipe. + * @returns Any items removed from this entity as a result of setting the recipe. + */ + set_recipe(recipe: string | LuaRecipe | undefined): Record + /** + * Rotates this entity as if the player rotated it. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.rotate View documentation} + * + * @returns Whether the rotation was successful. + */ + rotate(params?: { + /** If `true`, rotate the entity in the counter-clockwise direction. */ + readonly reverse?: boolean + readonly by_player?: PlayerIdentification + /** If the player is not given should extra items be spilled or returned as a second return value from this. */ + readonly spill_items?: boolean + /** When true, each spilled item will be flagged with the {@link LuaEntity.to_be_looted LuaEntity::to_be_looted} flag. */ + readonly enable_looted?: boolean + /** When provided the spilled items will be marked for deconstruction by this force. */ + readonly force?: LuaForce | string + }): boolean + /** + * Gets the driver of this vehicle if any. + * + * **Note**: May be `nil` if the vehicle contains no driver. To check if there's a passenger see + * {@link LuaEntity.get_passenger LuaEntity::get_passenger}. + * + * *Can only be used if this is Vehicle* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_driver View documentation} + */ + get_driver(): LuaEntity | LuaPlayer | undefined + /** + * Sets the driver of this vehicle. + * + * **Note**: This differs over {@link LuaEntity.set_passenger LuaEntity::set_passenger} in that the passenger can't + * drive the vehicle. + * + * *Can only be used if this is Vehicle* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_driver View documentation} + * + * @param driver - The new driver or `nil` to eject the current driver if any. + */ + set_driver(driver: LuaEntity | PlayerIdentification | undefined): void + /** + * Gets the passenger of this car or spidertron if any. + * + * **Note**: May be `nil` if the vehicle contains no passenger. To check if there's a driver see + * {@link LuaEntity.get_driver LuaEntity::get_driver}. + * + * **Note**: This differs over {@link LuaEntity.get_driver LuaEntity::get_driver} in that the passenger can't drive the car. + * + * *Can only be used if this is Vehicle* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_passenger View documentation} + */ + get_passenger(): LuaEntity | LuaPlayer | undefined + /** + * Sets the passenger of this car or spidertron. + * + * **Note**: This differs over {@link LuaEntity.get_driver LuaEntity::get_driver} in that the passenger can't drive the car. + * + * *Can only be used if this is Vehicle* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_passenger View documentation} + * + * @param passenger + */ + set_passenger(passenger: LuaEntity | PlayerIdentification): void + /** + * Returns true if this entity is connected to an electric network. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_connected_to_electric_network View documentation} + */ + is_connected_to_electric_network(): boolean + /** + * The trains scheduled to stop at this train stop. + * + * *Can only be used if this is TrainStop* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_train_stop_trains View documentation} + */ + get_train_stop_trains(): LuaTrain[] + /** + * The train currently stopped at this train stop or `nil` if none. + * + * *Can only be used if this is TrainStop* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_stopped_train View documentation} + */ + get_stopped_train(): LuaTrain | undefined + /** + * Clones this entity. + * + * **Note**: {@link defines.events.on_entity_cloned} is raised. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.clone View documentation} + * + * @returns The cloned entity or `nil` if this entity can't be cloned/can't be cloned to the given location. + */ + clone(params: { + /** The destination position */ + readonly position: Position + /** The destination surface */ + readonly surface?: LuaSurface + readonly force?: ForceIdentification + /** If false, the building effect smoke will not be shown around the new entity. */ + readonly create_build_effect_smoke?: boolean + }): LuaEntity | undefined + /** + * Get the amount of all or some fluid in this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_fluid_count View documentation} + * + * @param fluid - Prototype name of the fluid to count. If not specified, count all fluids. + */ + get_fluid_count(fluid?: string): double + /** + * Get amounts of all fluids in this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_fluid_contents View documentation} + * + * @returns The amounts, indexed by fluid names. + */ + get_fluid_contents(): Record + /** + * Remove fluid from this entity. + * + * **Note**: If temperature is given only fluid matching that exact temperature is removed. If minimum and maximum + * is given fluid within that range is removed. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.remove_fluid View documentation} + * + * @returns Amount of fluid actually removed. + */ + remove_fluid(params: { + /** Fluid prototype name. */ + readonly name: string + /** Amount to remove */ + readonly amount: double + readonly minimum_temperature?: double + readonly maximum_temperature?: double + readonly temperature?: double + }): double + /** + * Insert fluid into this entity. Fluidbox is chosen automatically. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.insert_fluid View documentation} + * + * @param fluid - Fluid to insert. + * @returns Amount of fluid actually inserted. + */ + insert_fluid(fluid: Fluid): double + /** + * Remove all fluids from this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.clear_fluid_inside View documentation} + */ + clear_fluid_inside(): void + /** + * Get the source of this beam. + * + * *Can only be used if this is Beam* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_beam_source View documentation} + */ + get_beam_source(): BeamTarget + /** + * Set the source of this beam. + * + * *Can only be used if this is Beam* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_beam_source View documentation} + * + * @param source + */ + set_beam_source(source: LuaEntity | Position): void + /** + * Get the target of this beam. + * + * *Can only be used if this is Beam* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_beam_target View documentation} + */ + get_beam_target(): BeamTarget + /** + * Set the target of this beam. + * + * *Can only be used if this is Beam* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.set_beam_target View documentation} + * + * @param target + */ + set_beam_target(target: LuaEntity | Position): void + /** + * The radius of this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_radius View documentation} + */ + get_radius(): double + /** + * The health ratio of this entity between 1 and 0 (for full health and no health respectively). + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_health_ratio View documentation} + */ + get_health_ratio(): float + /** + * Creates the same smoke that is created when you place a building by hand. You can play the building sound to go + * with it by using {@link LuaSurface.play_sound LuaSurface::play_sound}, eg: + * entity.surface.play_sound{path="entity-build/"..entity.prototype.name, position=entity.position} + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.create_build_effect_smoke View documentation} + */ + create_build_effect_smoke(): void + /** + * Release the unit from the spawner which spawned it. This allows the spawner to continue spawning additional units. + * + * *Can only be used if this is Unit* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.release_from_spawner View documentation} + */ + release_from_spawner(): void + /** + * Toggle this entity's equipment movement bonus. Does nothing if the entity does not have an equipment grid. + * + * **Note**: This property can also be read and written on the equipment grid of this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.toggle_equipment_movement_bonus View documentation} + */ + toggle_equipment_movement_bonus(): void + /** + * If this character can shoot the given entity or position. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.can_shoot View documentation} + * + * @param target + * @param position + */ + can_shoot(target: LuaEntity, position: Position): boolean + /** + * Only works if the entity is a speech-bubble, with an "effect" defined in its wrapper_flow_style. Starts animating + * the opacity of the speech bubble towards zero, and destroys the entity when it hits zero. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.start_fading_out View documentation} + */ + start_fading_out(): void + /** + * Returns the new entity prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_upgrade_target View documentation} + * + * @returns Nil if this entity is not marked for upgrade. + */ + get_upgrade_target(): LuaEntityPrototype | undefined + /** + * Returns the new entity direction after upgrading. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_upgrade_direction View documentation} + * + * @returns Nil if this entity is not marked for upgrade. + */ + get_upgrade_direction(): defines.direction | undefined + /** + * Returns the amount of damage to be taken by this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_damage_to_be_taken View documentation} + */ + get_damage_to_be_taken(): float + /** + * Depletes and destroys this resource entity. + * + * *Can only be used if this is ResourceEntity* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.deplete View documentation} + */ + deplete(): void + /** + * Mines this entity. + * + * **Note**: 'standard' operation is to keep calling mine() with an inventory until all items are transferred and + * the items dealt with. + * + * **Note**: The result of mining the entity (the item(s) it produces when mined) will be dropped on the ground if + * they don't fit into the provided inventory. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.mine View documentation} + * + * @returns Whether mining succeeded. + */ + mine(params?: { + /** + * If provided the item(s) will be transferred into this inventory. If provided, this must be an inventory + * created with {@link LuaGameScript.create_inventory LuaGameScript::create_inventory} or be a basic inventory + * owned by some entity. + */ + readonly inventory?: LuaInventory + /** + * If true, when the item(s) don't fit into the given inventory the entity is force mined. If false, the mining + * operation fails when there isn't enough room to transfer all of the items into the inventory. Defaults to + * false. This is ignored and acts as 'true' if no inventory is provided. + */ + readonly force?: boolean + /** If true, {@link ScriptRaisedDestroyEvent script_raised_destroy} will be raised. Defaults to true. */ + readonly raise_destroyed?: boolean + /** + * If true, the minable state of the entity is ignored. Defaults to false. If false, an entity that isn't + * minable (set as not-minable in the prototype or isn't minable for other reasons) will fail to be mined. + */ + readonly ignore_minable?: boolean + }): boolean + /** + * Triggers spawn_decoration actions defined in the entity prototype or does nothing if entity is not "turret" or + * "unit-spawner". + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.spawn_decorations View documentation} + */ + spawn_decorations(): void + /** + * Can wires reach between these entities. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.can_wires_reach View documentation} + * + * @param entity + */ + can_wires_reach(entity: LuaEntity): boolean + /** + * Gets rolling stock connected to the given end of this stock + * + * **Note**: This will also return {@link defines.rail_direction} of other rolling stock that is connected back to + * this rolling stock + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.get_connected_rolling_stock View documentation} + * + * @param direction + * @returns One of connected rolling stocks + */ + get_connected_rolling_stock(direction: defines.rail_direction): LuaEntity + /** + * Is this entity or tile ghost or item request proxy registered for construction? If false, it means a construction + * robot has been dispatched to build the entity, or it is not an entity that can be constructed. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_registered_for_construction View documentation} + */ + is_registered_for_construction(): boolean + /** + * Is this entity registered for deconstruction with this force? If false, it means a construction robot has been + * dispatched to deconstruct it, or it is not marked for deconstruction. This is worst-case O(N) complexity where N + * is the current number of things in the deconstruct queue. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_registered_for_deconstruction View documentation} + * + * @param force - The force construction manager to check. + */ + is_registered_for_deconstruction(force: ForceIdentification): boolean + /** + * Is this entity registered for upgrade? If false, it means a construction robot has been dispatched to upgrade it, + * or it is not marked for upgrade. This is worst-case O(N) complexity where N is the current number of things in + * the upgrade queue. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_registered_for_upgrade View documentation} + */ + is_registered_for_upgrade(): boolean + /** + * Is this entity registered for repair? If false, it means a construction robot has been dispatched to upgrade it, + * or it is not damaged. This is worst-case O(N) complexity where N is the current number of things in the repair queue. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_registered_for_repair View documentation} + */ + is_registered_for_repair(): boolean + /** + * Adds the given position to this spidertron's autopilot's queue of destinations. + * + * *Can only be used if this is SpiderVehicle* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.add_autopilot_destination View documentation} + * + * @param position - The position the spidertron should move to. + */ + add_autopilot_destination(position: Position): void + /** + * Connects current linked belt with another one. + * + * Neighbours have to be of different type. If given linked belt is connected to something else it will be + * disconnected first. If provided neighbour is connected to something else it will also be disconnected first. + * Automatically updates neighbour to be connected back to this one. + * + * **Note**: Can also be used on entity ghost if it contains linked-belt + * + * *Can only be used if this is LinkedBelt* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.connect_linked_belts View documentation} + * + * @param neighbour - Another linked belt or entity ghost containing linked belt to connect or nil to disconnect + */ + connect_linked_belts(neighbour: LuaEntity | undefined): void + /** + * Disconnects linked belt from its neighbour. + * + * **Note**: Can also be used on entity ghost if it contains linked-belt + * + * *Can only be used if this is LinkedBelt* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.disconnect_linked_belts View documentation} + */ + disconnect_linked_belts(): void + /** + * Name of the entity prototype. E.g. "inserter" or "filter-inserter". + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.name View documentation} + */ + readonly name: "inserter" | "filter-inserter" + /** + * Name of the entity or tile contained in this ghost + * + * *Can only be used if this is Ghost* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.ghost_name View documentation} + */ + readonly ghost_name: string + /** + * Localised name of the entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.localised_name View documentation} + */ + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * Localised name of the entity or tile contained in this ghost. + * + * *Can only be used if this is Ghost* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.ghost_localised_name View documentation} + */ + readonly ghost_localised_name: LocalisedString + /** + * *Can only be used if this is Ghost* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.ghost_localised_description View documentation} + */ + readonly ghost_localised_description: LocalisedString + /** + * The entity prototype type of this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.type View documentation} + */ + readonly type: string + /** + * The prototype type of the entity or tile contained in this ghost. + * + * *Can only be used if this is Ghost* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.ghost_type View documentation} + */ + readonly ghost_type: string + /** + * Deactivating an entity will stop all its operations (car will stop moving, inserters will stop working, fish will + * stop moving etc). + * + * **Note**: Entities that are not active naturally can't be set to be active (setting it to be active will do nothing) + * + * **Note**: Ghosts, simple smoke, and corpses can't be modified at this time. + * + * **Note**: It is even possible to set the character to not be active, so he can't move and perform most of the tasks. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.active View documentation} + */ + active: boolean + /** + * When the entity is not destructible it can't be damaged. + * + * **Note**: An indestructible entity can still be mined. + * + * **Note**: Entities that are indestructible naturally (they have no health, like smoke, resource etc) can't be set + * to be destructible. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.destructible View documentation} + */ + destructible: boolean + /** + * **Note**: Not minable entities can still be destroyed. + * + * **Note**: Entities that are not minable naturally (like smoke, character, enemy units etc) can't be set to minable. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.minable View documentation} + */ + minable: boolean + /** + * When entity is not to be rotatable (inserter, transport belt etc), it can't be rotated by player using the R key. + * + * **Note**: Entities that are not rotatable naturally (like chest or furnace) can't be set to be rotatable. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.rotatable View documentation} + */ + rotatable: boolean + /** + * Player can't open gui of this entity and he can't quick insert/input stuff in to the entity when it is not operable. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.operable View documentation} + */ + operable: boolean + /** + * The current health of the entity, or `nil` if it doesn't have health. Health is automatically clamped to be + * between `0` and max health (inclusive). Entities with a health of `0` can not be attacked. + * + * **Note**: To get the maximum possible health of this entity, see + * {@link LuaEntityPrototype.max_health LuaEntityPrototype::max_health} on its prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.health View documentation} + */ + health: float | undefined + /** + * The current direction this entity is facing. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.direction View documentation} + */ + direction: defines.direction + /** + * Whether the entity has direction. When it is false for this entity, it will always return north direction when asked for. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.supports_direction View documentation} + */ + readonly supports_direction: boolean + /** + * The smooth orientation of this entity, if it supports orientation. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.orientation View documentation} + */ + orientation: RealOrientation + /** + * The orientation of this cliff. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.cliff_orientation View documentation} + */ + readonly cliff_orientation: CliffOrientation + /** + * The relative orientation of the vehicle turret, artillery turret, artillery wagon or `nil` if this entity isn't a + * vehicle with a vehicle turret or artillery turret/wagon. + * + * **Note**: Writing does nothing if the vehicle doesn't have a turret. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.relative_turret_orientation View documentation} + */ + relative_turret_orientation: RealOrientation | undefined + /** + * The torso orientation of this spider vehicle. + * + * *Can only be used if this is SpiderVehicle* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.torso_orientation View documentation} + */ + torso_orientation: RealOrientation + /** + * Count of resource units contained. + * + * *Can only be used if this is ResourceEntity* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.amount View documentation} + */ + amount: uint + /** + * Count of initial resource units contained. + * + * **Note**: If this is not an infinite resource reading will give `nil` and writing will give an error. + * + * *Can only be used if this is ResourceEntity* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.initial_amount View documentation} + */ + initial_amount: uint | undefined + /** + * Multiplies the acceleration the vehicle can create for one unit of energy. By default is `1`. + * + * *Can only be used if this is Car* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.effectivity_modifier View documentation} + */ + effectivity_modifier: float + /** + * Multiplies the energy consumption. + * + * *Can only be used if this is Car* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.consumption_modifier View documentation} + */ + consumption_modifier: float + /** + * Multiplies the car friction rate. + * + * *Can only be used if this is Car* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.friction_modifier View documentation} + * + * @example + * This will allow the car to go much faster + * + * ```lua + * game.player.vehicle.friction_modifier = 0.5 + * ``` + */ + friction_modifier: float + /** + * Whether the driver of this car or spidertron is the gunner, if false, the passenger is the gunner. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.driver_is_gunner View documentation} + */ + driver_is_gunner: boolean + /** + * Read when this spidertron auto-targets enemies + * + * *Can only be used if this is SpiderVehicle* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.vehicle_automatic_targeting_parameters View documentation} + */ + vehicle_automatic_targeting_parameters: VehicleAutomaticTargetingParameters + /** + * The current speed of this car in tiles per tick, rolling stock, projectile or spider vehicle, or current max + * speed of the unit. Only the speed of units, cars, and projectiles are writable. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.speed View documentation} + */ + speed: float + /** + * The current speed of this unit in tiles per tick, taking into account any walking speed modifier given by the + * tile the unit is standing on. + * + * *Can only be used if this is Unit* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.effective_speed View documentation} + */ + readonly effective_speed: float + /** + * *Can only be used if this is ItemEntity* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.stack View documentation} + */ + readonly stack: LuaItemStack + /** + * The entity prototype of this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.prototype View documentation} + */ + readonly prototype: LuaEntityPrototype + /** + * The prototype of the entity or tile contained in this ghost. + * + * *Can only be used if this is Ghost* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.ghost_prototype View documentation} + */ + readonly ghost_prototype: LuaEntityPrototype | LuaTilePrototype + /** + * Position where the entity puts its stuff. + * + * **Note**: Meaningful only for entities that put stuff somewhere, such as mining drills or inserters. Mining + * drills can't have their drop position changed; inserters must have `allow_custom_vectors` set to true on their + * prototype to allow changing the drop position. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.drop_position View documentation} + */ + drop_position: Position + /** + * Where the inserter will pick up items from. + * + * **Note**: Inserters must have `allow_custom_vectors` set to true on their prototype to allow changing the pickup position. + * + * *Can only be used if this is Inserter* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.pickup_position View documentation} + */ + pickup_position: Position + /** + * The entity this entity is putting its stuff to or `nil` if there is no such entity. + * + * **Note**: Meaningful only for entities that put stuff somewhere, such as mining drills or inserters. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.drop_target View documentation} + */ + drop_target: LuaEntity | undefined + /** + * The entity the inserter will attempt to pick up from. For example, this can be a transport belt or a storage chest. + * + * *Can only be used if this is Inserter* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.pickup_target View documentation} + */ + pickup_target: LuaEntity + /** + * Index of the currently selected weapon slot of this character, car, or spidertron, or `nil` if the car/spidertron + * doesn't have guns. + * + * *Can only be used if this is Character or Car* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.selected_gun_index View documentation} + */ + selected_gun_index: uint | undefined + /** + * Energy stored in the entity (heat in furnace, energy stored in electrical devices etc.). always 0 for entities + * that don't have the concept of energy stored inside. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.energy View documentation} + * + * @example + * ```lua + * game.player.print("Machine energy: " .. game.player.selected.energy .. "J") + * game.player.selected.energy = 3000 + * ``` + */ + energy: double + /** + * The temperature of this entities heat energy source if this entity uses a heat energy source or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.temperature View documentation} + */ + temperature: double | undefined + /** + * The previous recipe this furnace was using or nil if the furnace had no previous recipe. + * + * *Can only be used if this is Furnace* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.previous_recipe View documentation} + */ + readonly previous_recipe: LuaRecipe | undefined + /** + * The item stack currently held in an inserter's hand. + * + * *Can only be used if this is Inserter* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.held_stack View documentation} + */ + readonly held_stack: LuaItemStack + /** + * Current position of the inserter's "hand". + * + * *Can only be used if this is Inserter* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.held_stack_position View documentation} + */ + readonly held_stack_position: PositionTable + /** + * The train this rolling stock belongs to or nil if not rolling stock. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.train View documentation} + */ + readonly train: LuaTrain | undefined + /** + * - When called on an electric pole, this is a dictionary of all connections, indexed by the strings `"copper"`, + * `"red"`, and `"green"`. + * - When called on a pipe-connectable entity, this is an array of entity arrays of all entities a given fluidbox is + * connected to. + * - When called on an underground transport belt, this is the other end of the underground belt connection, or `nil` if none. + * - When called on a wall-connectable entity or reactor, this is a dictionary of all connections indexed by the + * connection direction "north", "south", "east", and "west". + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.neighbours View documentation} + */ + readonly neighbours: Record | LuaEntity[][] | LuaEntity | undefined + /** + * The belt connectable neighbours of this belt connectable entity. Only entities that input to or are outputs of + * this entity. Does not contain the other end of an underground belt, see + * {@link LuaEntity.neighbours LuaEntity::neighbours} for that. This is a dictionary with `"inputs"`, `"outputs"` + * entries that are arrays of transport belt connectable entities, or empty tables if no entities. + * + * *Can only be used if this is TransportBeltConnectable* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.belt_neighbours View documentation} + */ + readonly belt_neighbours: Record + /** + * Fluidboxes of this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.fluidbox View documentation} + */ + fluidbox: LuaFluidBox + /** + * The backer name assigned to this entity, or `nil` if this entity doesn't support backer names. Entities that + * support backer names are labs, locomotives, radars, roboports, and train stops. + * + * **Note**: While train stops get the name of a backer when placed down, players can rename them if they want to. + * In this case, `backer_name` returns the player-given name of the entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.backer_name View documentation} + */ + backer_name: string | undefined + /** + * The label of this entity if it has one or `nil`. Changing the value will trigger on_entity_renamed event + * + * **Note**: only usable on entities that have labels (currently only spider-vehicles). + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.entity_label View documentation} + */ + entity_label: string | undefined + /** + * The ticks left before a ghost, combat robot, highlight box or smoke with trigger is destroyed. + * + * - For ghosts set to uint32 max (4,294,967,295) to never expire. + * - For ghosts Cannot be set higher than {@link LuaForce.ghost_time_to_live LuaForce::ghost_time_to_live} of the entity's force. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.time_to_live View documentation} + */ + time_to_live: uint + /** + * The character, rolling stock, train stop, car, spider-vehicle, flying text, corpse or simple-entity-with-owner + * color. Returns `nil` if this entity doesn't use custom colors. + * + * **Note**: Car color is overridden by the color of the current driver/passenger, if there is one. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.color View documentation} + */ + color: Color | undefined + /** + * The text of this flying-text entity. + * + * *Can only be used if this is FlyingText* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.text View documentation} + */ + text: LocalisedString + /** + * The state of this rail signal. + * + * *Can only be used if this is RailSignal* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.signal_state View documentation} + */ + readonly signal_state: defines.signal_state + /** + * The state of this chain signal. + * + * *Can only be used if this is RailChainSignal* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.chain_signal_state View documentation} + */ + readonly chain_signal_state: defines.chain_signal_state + /** + * Will this entity be picked up automatically when the player walks over it? + * + * *Can only be used if this is ItemEntity* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.to_be_looted View documentation} + */ + to_be_looted: boolean + /** + * The current crafting speed, including speed bonuses from modules and beacons. + * + * *Can only be used if this is CraftingMachine* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.crafting_speed View documentation} + */ + readonly crafting_speed: double + /** + * The current crafting progress, as a number in range [0, 1]. + * + * *Can only be used if this is CraftingMachine* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.crafting_progress View documentation} + */ + crafting_progress: float + /** + * The current productivity bonus progress, as a number in range [0, 1]. + * + * *Can only be used if this is CraftingMachine* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.bonus_progress View documentation} + */ + bonus_progress: double + /** + * The productivity bonus of this entity. + * + * **Note**: This includes force based bonuses as well as beacon/module bonuses. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.productivity_bonus View documentation} + */ + readonly productivity_bonus: double + /** + * The pollution bonus of this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.pollution_bonus View documentation} + */ + readonly pollution_bonus: double + /** + * The speed bonus of this entity. + * + * **Note**: This includes force based bonuses as well as beacon/module bonuses. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.speed_bonus View documentation} + */ + readonly speed_bonus: double + /** + * The consumption bonus of this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.consumption_bonus View documentation} + */ + readonly consumption_bonus: double + /** + * `"input"` or `"output"`, depending on whether this underground belt goes down or up. + * + * *Can only be used if this is TransportBeltToGround* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.belt_to_ground_type View documentation} + */ + readonly belt_to_ground_type: "input" | "output" + /** + * `"input"` or `"output"`, depending on whether this loader puts to or gets from a container. + * + * *Can only be used if this is Loader* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.loader_type View documentation} + */ + loader_type: "input" | "output" + /** + * Number of rocket parts in the silo. + * + * *Can only be used if this is RocketSilo* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.rocket_parts View documentation} + */ + rocket_parts: uint + /** + * The logistic network this entity is a part of. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.logistic_network View documentation} + */ + logistic_network: LuaLogisticNetwork + /** + * The logistic cell this entity is a part of. Will be `nil` if this entity is not a part of any logistic cell. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.logistic_cell View documentation} + */ + readonly logistic_cell: LuaLogisticCell | undefined + /** + * Items this ghost will request when revived or items this item request proxy is requesting. Result is a dictionary + * mapping each item prototype name to the required count. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.item_requests View documentation} + */ + item_requests: Record + /** + * The player connected to this character or `nil` if none. + * + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.player View documentation} + */ + readonly player: LuaPlayer | undefined + /** + * The unit group this unit is a member of, or `nil` if none. + * + * *Can only be used if this is Unit* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.unit_group View documentation} + */ + readonly unit_group: LuaUnitGroup | undefined + /** + * The damage dealt by this turret, artillery turret, or artillery wagon. + * + * *Can only be used if this is Turret* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.damage_dealt View documentation} + */ + damage_dealt: double + /** + * The number of units killed by this turret, artillery turret, or artillery wagon. + * + * *Can only be used if this is Turret* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.kills View documentation} + */ + kills: uint + /** + * The last player that changed any setting on this entity. This includes building the entity, changing its color, + * or configuring its circuit network. Can be `nil` if the last user is not part of the save anymore. Mods can + * overwrite it if desired. + * + * *Can only be used if this is EntityWithOwner* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.last_user View documentation} + */ + last_user: LuaPlayer | undefined + /** + * The buffer size for the electric energy source or nil if the entity doesn't have an electric energy source. + * + * **Note**: Write access is limited to the ElectricEnergyInterface type + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.electric_buffer_size View documentation} + */ + electric_buffer_size: double | undefined + /** + * The input flow limit for the electric energy source or nil if the entity doesn't have an electric energy source. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.electric_input_flow_limit View documentation} + */ + readonly electric_input_flow_limit: double | undefined + /** + * The output flow limit for the electric energy source or nil if the entity doesn't have an electric energy source. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.electric_output_flow_limit View documentation} + */ + readonly electric_output_flow_limit: double | undefined + /** + * The electric drain for the electric energy source or nil if the entity doesn't have an electric energy source. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.electric_drain View documentation} + */ + readonly electric_drain: double | undefined + /** + * The emissions for the electric energy source or nil if the entity doesn't have an electric energy source. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.electric_emissions View documentation} + */ + readonly electric_emissions: double | undefined + /** + * The unit number or nil if the entity doesn't have one. This is universally unique for every entity that has one, + * for the lifetime of a whole game. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.unit_number View documentation} + */ + readonly unit_number: uint | undefined + /** + * The unit number of the entity contained in this ghost or nil if the entity doesn't have one. + * + * *Can only be used if this is EntityGhost* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.ghost_unit_number View documentation} + */ + readonly ghost_unit_number: uint | undefined + /** + * The mining progress for this mining drill or `nil` if this isn't a mining drill. Is a number in range [0, + * mining_target.prototype.mineable_properties.mining_time] + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.mining_progress View documentation} + */ + mining_progress: double | undefined + /** + * The bonus mining progress for this mining drill or `nil` if this isn't a mining drill. Read yields a number in + * range [0, mining_target.prototype.mineable_properties.mining_time] + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.bonus_mining_progress View documentation} + */ + bonus_mining_progress: double | undefined + /** + * The power production specific to the ElectricEnergyInterface entity type. + * + * *Can only be used if this is ElectricEnergyInterface* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.power_production View documentation} + */ + power_production: double + /** + * The power usage specific to the ElectricEnergyInterface entity type. + * + * *Can only be used if this is ElectricEnergyInterface* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.power_usage View documentation} + */ + power_usage: double + /** + * {@link LuaEntityPrototype.collision_box LuaEntityPrototype::collision_box} around entity's given position and + * respecting the current entity orientation. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.bounding_box View documentation} + */ + readonly bounding_box: BoundingBoxTable + /** + * The secondary bounding box of this entity or `nil` if it doesn't have one. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.secondary_bounding_box View documentation} + */ + readonly secondary_bounding_box: BoundingBoxTable | undefined + /** + * {@link LuaEntityPrototype.selection_box LuaEntityPrototype::selection_box} around entity's given position and + * respecting the current entity orientation. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.selection_box View documentation} + */ + readonly selection_box: BoundingBoxTable + /** + * The secondary selection box of this entity or `nil` if it doesn't have one. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.secondary_selection_box View documentation} + */ + readonly secondary_selection_box: BoundingBoxTable | undefined + /** + * The mining target or `nil` if none + * + * *Can only be used if this is MiningDrill* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.mining_target View documentation} + */ + readonly mining_target: LuaEntity | undefined + /** + * Entities that are directly connected to this entity via the circuit network. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.circuit_connected_entities View documentation} + */ + readonly circuit_connected_entities: { + /** Entities connected via the red wire. */ + readonly red: LuaEntity[] + /** Entities connected via the green wire. */ + readonly green: LuaEntity[] + } + /** + * The connection definition for entities that are directly connected to this entity via the circuit network. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.circuit_connection_definitions View documentation} + */ + readonly circuit_connection_definitions: CircuitConnectionDefinition[] + /** + * The index of the configured request with the highest index for this entity. This means 0 if no requests are set + * and e.g. 20 if the 20th request slot is configured. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.request_slot_count View documentation} + */ + readonly request_slot_count: uint + /** + * The number of filter slots this inserter, loader, or logistic storage container has. 0 if not one of those entities. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.filter_slot_count View documentation} + */ + readonly filter_slot_count: uint + /** + * The container entity this loader is pointing at/pulling from depending on the + * {@link LuaEntity.loader_type LuaEntity::loader_type}. + * + * *Can only be used if this is Loader* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.loader_container View documentation} + */ + readonly loader_container: LuaEntity + /** + * The equipment grid or `nil` if this entity doesn't have an equipment grid. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.grid View documentation} + */ + readonly grid: LuaEquipmentGrid | undefined + /** + * The graphics variation for this entity or `nil` if this entity doesn't use graphics variations. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.graphics_variation View documentation} + */ + graphics_variation: uint8 | undefined + /** + * Index of the tree color. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tree_color_index View documentation} + */ + tree_color_index: uint8 + /** + * Maximum index of the tree colors. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tree_color_index_max View documentation} + */ + readonly tree_color_index_max: uint8 + /** + * Index of the tree stage. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tree_stage_index View documentation} + */ + tree_stage_index: uint8 + /** + * Maximum index of the tree stages. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tree_stage_index_max View documentation} + */ + readonly tree_stage_index_max: uint8 + /** + * Index of the tree gray stage + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tree_gray_stage_index View documentation} + */ + tree_gray_stage_index: uint8 + /** + * Maximum index of the tree gray stages. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tree_gray_stage_index_max View documentation} + */ + readonly tree_gray_stage_index_max: uint8 + /** + * The burner energy source for this entity or `nil` if there isn't one. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.burner View documentation} + */ + readonly burner: LuaBurner | undefined + /** + * The shooting target for this turret or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.shooting_target View documentation} + */ + shooting_target: LuaEntity | undefined + /** + * The target entity for this item-request-proxy or `nil` + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.proxy_target View documentation} + */ + readonly proxy_target: LuaEntity | undefined + /** + * The sticker entities attached to this entity or `nil` if none. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.stickers View documentation} + */ + readonly stickers: LuaEntity[] | undefined + /** + * The entity this sticker is sticked to. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.sticked_to View documentation} + */ + readonly sticked_to: LuaEntity + /** + * *Can only be used if this is ProgrammableSpeaker* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.parameters View documentation} + */ + parameters: ProgrammableSpeakerParameters + /** + * *Can only be used if this is ProgrammableSpeaker* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.alert_parameters View documentation} + */ + alert_parameters: ProgrammableSpeakerAlertParameters + /** + * The electric network statistics for this electric pole. + * + * *Can only be used if this is ElectricPole* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.electric_network_statistics View documentation} + */ + readonly electric_network_statistics: LuaFlowStatistics + /** + * Sets the stack size limit on this inserter. If the stack size is > than the force stack size limit the value is ignored. + * + * **Note**: Set to 0 to reset. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.inserter_stack_size_override View documentation} + */ + inserter_stack_size_override: uint + /** + * The number of products this machine finished crafting in its lifetime. + * + * *Can only be used if this is CraftingMachine* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.products_finished View documentation} + */ + products_finished: uint + /** + * The spawner associated with this unit entity or `nil` if the unit has no associated spawner. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.spawner View documentation} + */ + readonly spawner: LuaEntity | undefined + /** + * The units associated with this spawner entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.units View documentation} + */ + readonly units: LuaEntity[] + /** + * The state of this power switch. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.power_switch_state View documentation} + */ + power_switch_state: boolean + /** + * The effects being applied to this entity or `nil`. For beacons this is the effect the beacon is broadcasting. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.effects View documentation} + */ + readonly effects: ModuleEffects | undefined + /** + * The filters for this infinity container. + * + * *Can only be used if this is InfinityContainer* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.infinity_container_filters View documentation} + */ + infinity_container_filters: InfinityInventoryFilter[] + /** + * If items not included in this infinity container filters should be removed from the container. + * + * *Can only be used if this is InfinityContainer* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.remove_unfiltered_items View documentation} + */ + remove_unfiltered_items: boolean + /** + * The player index associated with this character corpse. + * + * **Note**: The index is not guaranteed to be valid so it should always be checked first if a player with that + * index actually exists. + * + * *Can only be used if this is CharacterCorpse* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.character_corpse_player_index View documentation} + */ + character_corpse_player_index: uint + /** + * The tick this character corpse died at. + * + * *Can only be used if this is CharacterCorpse* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.character_corpse_tick_of_death View documentation} + */ + character_corpse_tick_of_death: uint + /** + * The reason this character corpse character died (if any). + * + * *Can only be used if this is CharacterCorpse* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.character_corpse_death_cause View documentation} + */ + character_corpse_death_cause: LocalisedString + /** + * The player this character is associated with or `nil` if none. When the player logs off in multiplayer all of the + * associated characters will be logged off with him. + * + * **Note**: A character associated with a player is not directly controlled by any player. + * + * **Note**: Set to `nil` to clear. The player will be automatically disassociated when a controller is set on the character. + * + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.associated_player View documentation} + */ + associated_player: LuaPlayer | undefined + /** + * The last tick this character entity was attacked. + * + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tick_of_last_attack View documentation} + */ + tick_of_last_attack: uint + /** + * The last tick this character entity was damaged. + * + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tick_of_last_damage View documentation} + */ + tick_of_last_damage: uint + /** + * The filter for this splitter or `nil` if no filter is set. + * + * *Can only be used if this is Splitter* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.splitter_filter View documentation} + */ + splitter_filter: LuaItemPrototype | undefined + /** + * The filter mode for this filter inserter: "whitelist", "blacklist", or `nil` if this inserter doesn't use filters. + * + * *Can only be used if this is Inserter* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.inserter_filter_mode View documentation} + */ + inserter_filter_mode: "whitelist" | "blacklist" | undefined + /** + * The input priority for this splitter : "left", "none", or "right". + * + * *Can only be used if this is Splitter* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.splitter_input_priority View documentation} + */ + splitter_input_priority: "left" | "none" | "right" + /** + * The output priority for this splitter : "left", "none", or "right". + * + * *Can only be used if this is Splitter* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.splitter_output_priority View documentation} + */ + splitter_output_priority: "left" | "none" | "right" + /** + * If this land mine is armed. + * + * *Can only be used if this is LandMine* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.armed View documentation} + */ + readonly armed: boolean + /** + * When locked; the recipe in this assembling machine can't be changed by the player. + * + * *Can only be used if this is AssemblingMachine* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.recipe_locked View documentation} + */ + recipe_locked: boolean + /** + * The rail entity this train stop is connected to or `nil` if there is none. + * + * *Can only be used if this is TrainStop* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.connected_rail View documentation} + */ + readonly connected_rail: LuaEntity | undefined + /** + * The number of trains in this rail block for this rail entity. + * + * *Can only be used if this is Rail* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.trains_in_block View documentation} + */ + readonly trains_in_block: uint + /** + * The timeout that's left on this landmine in ticks. It describes the time between the landmine being placed and it + * being armed. + * + * *Can only be used if this is LandMine* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.timeout View documentation} + */ + timeout: uint + /** + * The current total neighbour bonus of this reactor. + * + * *Can only be used if this is Reactor* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.neighbour_bonus View documentation} + */ + readonly neighbour_bonus: double + /** + * The ai settings of this unit. + * + * *Can only be used if this is Unit* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.ai_settings View documentation} + */ + readonly ai_settings: LuaAISettings + /** + * The hightlight box type of this highlight box entity. + * + * *Can only be used if this is HighlightBox* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.highlight_box_type View documentation} + */ + highlight_box_type: string + /** + * The blink interval of this highlight box entity. 0 indicates no blink. + * + * *Can only be used if this is HighlightBox* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.highlight_box_blink_interval View documentation} + */ + highlight_box_blink_interval: uint + /** + * The status of this entity or `nil` if no status. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.status View documentation} + */ + readonly status: defines.entity_status | undefined + /** + * If equipment grid logistics are enabled while this vehicle is moving. + * + * *Can only be used if this is Vehicle* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.enable_logistics_while_moving View documentation} + */ + enable_logistics_while_moving: boolean + /** + * The player that this `simple-entity-with-owner`, `simple-entity-with-force`, `flying-text`, or `highlight-box` is + * visible to. `nil` means it is rendered for every player. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.render_player View documentation} + */ + render_player: LuaPlayer | undefined + /** + * The forces that this `simple-entity-with-owner`, `simple-entity-with-force`, or `flying-text` is visible to. + * `nil` or an empty array means it is rendered for every force. + * + * **Note**: Reading will always give an array of {@link LuaForce} + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.render_to_forces View documentation} + */ + render_to_forces: ForceIdentification[] | undefined + /** + * The rail target of this pump or `nil`. + * + * *Can only be used if this is Pump* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.pump_rail_target View documentation} + */ + readonly pump_rail_target: LuaEntity | undefined + /** + * Returns true if this unit is moving. + * + * *Can only be used if this is Unit* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.moving View documentation} + */ + readonly moving: boolean + /** + * Returns the id of the electric network that this entity is connected to or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.electric_network_id View documentation} + */ + readonly electric_network_id: uint | undefined + /** + * Whether this character's personal roboports are allowed to dispatch robots. + * + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.allow_dispatching_robots View documentation} + */ + allow_dispatching_robots: boolean + /** + * Whether this rocket silo automatically launches the rocket when cargo is inserted. + * + * *Can only be used if this is RocketSilo* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.auto_launch View documentation} + */ + auto_launch: boolean + /** + * How much energy this generator generated in the last tick. + * + * *Can only be used if this is Generator* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.energy_generated_last_tick View documentation} + */ + readonly energy_generated_last_tick: double + /** + * The storage filter for this logistic storage container. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.storage_filter View documentation} + */ + storage_filter: LuaItemPrototype + /** + * Whether this requester chest is set to also request from buffer chests. + * + * **Note**: Useable only on entities that have requester slots. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.request_from_buffers View documentation} + */ + request_from_buffers: boolean + /** + * Whether this corpse will ever fade away. + * + * **Note**: Useable only on corpses. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.corpse_expires View documentation} + */ + corpse_expires: boolean + /** + * If true, corpse won't be destroyed when entities are placed over it. If false, whether corpse will be removed or + * not depends on value of CorpsePrototype::remove_on_entity_placement. + * + * **Note**: Useable only on corpses. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.corpse_immune_to_entity_placement View documentation} + */ + corpse_immune_to_entity_placement: boolean + /** + * The tags associated with this entity ghost or `nil` if not an entity ghost. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.tags View documentation} + */ + tags: Tags | undefined + /** + * The command given to this unit or `nil` is the unit has no command. + * + * *Can only be used if this is Unit* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.command View documentation} + */ + readonly command: Command | undefined + /** + * The distraction command given to this unit or `nil` is the unit currently isn't distracted. + * + * *Can only be used if this is Unit* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.distraction_command View documentation} + */ + readonly distraction_command: Command | undefined + /** + * The ticks until the next trigger effect of this smoke-with-trigger. + * + * *Can only be used if this is SmokeWithTrigger* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.time_to_next_effect View documentation} + */ + time_to_next_effect: uint + /** + * Destination position of spidertron's autopilot. Returns `nil` if autopilot doesn't have destination set. + * + * *Can only be used if this is SpiderVehicle* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.autopilot_destination View documentation} + */ + autopilot_destination: Position | undefined + /** + * The queued destination positions of spidertron's autopilot. + * + * *Can only be used if this is SpiderVehicle* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.autopilot_destinations View documentation} + */ + readonly autopilot_destinations: PositionTable[] + /** + * Amount of trains related to this particular train stop. Includes train stopped at this train stop (until it finds + * a path to next target) and trains having this train stop as goal or waypoint. Writing nil will disable the limit + * (will set a maximum possible value). + * + * **Note**: Train may be included multiple times when braking distance covers this train stop multiple times + * + * **Note**: Value may be read even when train stop has no control behavior + * + * *Can only be used if this is TrainStop* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.trains_count View documentation} + */ + readonly trains_count: uint | undefined + /** + * Amount of trains above which no new trains will be sent to this train stop. + * + * **Note**: When a train stop has a control behavior with wire connected and set_trains_limit enabled, this value + * will be overwritten by it + * + * *Can only be used if this is TrainStop* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.trains_limit View documentation} + */ + trains_limit: uint + /** + * If this entity is EntityWithForce + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_entity_with_force View documentation} + */ + readonly is_entity_with_force: boolean + /** + * If this entity is EntityWithOwner + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_entity_with_owner View documentation} + */ + readonly is_entity_with_owner: boolean + /** + * If this entity is EntityWithHealth + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.is_entity_with_health View documentation} + */ + readonly is_entity_with_health: boolean + /** + * The owner of this combat robot if any. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.combat_robot_owner View documentation} + */ + combat_robot_owner: LuaEntity + /** + * The link ID this linked container is using. + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.link_id View documentation} + */ + link_id: uint + /** + * The follow target of this spidertron if any. + * + * *Can only be used if this is SpiderVehicle* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.follow_target View documentation} + */ + follow_target: LuaEntity + /** + * The follow offset of this spidertron if any. If it is not following an entity this will be nil. This is + * randomized each time the follow entity is set. + * + * *Can only be used if this is SpiderVehicle* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.follow_offset View documentation} + */ + follow_offset: Position | undefined + /** + * Type of linked belt: it is either `"input"` or `"output"`. Changing type will also flip direction so the belt is + * out of the same side + * + * **Note**: Can only be changed when linked belt is disconnected (has no neighbour set) + * + * **Note**: Can also be used on entity ghost if it contains linked-belt + * + * *Can only be used if this is LinkedBelt* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.linked_belt_type View documentation} + */ + linked_belt_type: "input" | "output" + /** + * Neighbour to which this linked belt is connected to. Returns nil if not connected. + * + * **Note**: Can also be used on entity ghost if it contains linked-belt + * + * **Note**: May return entity ghost which contains linked belt to which connection is made + * + * *Can only be used if this is LinkedBelt* + * + * {@link https://lua-api.factorio.com/next/LuaEntity.html#LuaEntity.linked_belt_neighbour View documentation} + */ + readonly linked_belt_neighbour: LuaEntity | undefined + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaEntity" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of an entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html View documentation} + * + * @noSelf + */ +interface LuaEntityPrototype { + /** + * Does this prototype have a flag enabled? + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.has_flag View documentation} + * + * @param flag - The flag to check. Must be one of - `"not-rotatable"` - `"placeable-neutral"` - + * `"placeable-player"` - `"placeable-enemy"` - `"placeable-off-grid"` - `"player-creation"` - + * `"building-direction-8-way"` - `"filter-directions"` - `"fast-replaceable-no-build-while-moving"` - + * `"breaths-air"` - `"not-repairable"` - `"not-on-map"` - `"not-deconstructable"` - `"not-blueprintable"` - + * `"hide-from-bonus-gui"` - `"hide-alt-info"` - `"fast-replaceable-no-cross-type-while-moving"` - + * `"no-gap-fill-while-building"` - `"not-flammable"` - `"no-automated-item-removal"` - + * `"no-automated-item-insertion"` - `"not-upgradable"` + */ + has_flag( + flag: + | "not-rotatable" + | "placeable-neutral" + | "placeable-player" + | "placeable-enemy" + | "placeable-off-grid" + | "player-creation" + | "filter-directions" + | "fast-replaceable-no-build-while-moving" + | "breaths-air" + | "not-repairable" + | "not-on-map" + | "not-deconstructable" + | "not-blueprintable" + | "hide-from-bonus-gui" + | "hide-alt-info" + | "fast-replaceable-no-cross-type-while-moving" + | "no-gap-fill-while-building" + | "not-flammable" + | "no-automated-item-removal" + | "no-automated-item-insertion" + | "not-upgradable" + ): boolean + /** + * Gets the base size of the given inventory on this entity or `nil` if the given inventory doesn't exist. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.get_inventory_size View documentation} + * + * @param index + */ + get_inventory_size(index: defines.inventory): uint | undefined + /** + * Type of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.type View documentation} + */ + readonly type: string + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.name View documentation} + */ + readonly name: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * Max health of this entity. Will be `0` if this is not an entity with health. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_health View documentation} + */ + readonly max_health: float + /** + * Is this resource infinite? Will be `nil` when used on a non-resource. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.infinite_resource View documentation} + */ + readonly infinite_resource: boolean | undefined + /** + * Minimum amount of this resource. Will be `nil` when used on a non-resource. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.minimum_resource_amount View documentation} + */ + readonly minimum_resource_amount: uint | undefined + /** + * The normal amount for this resource. `nil` when not a resource. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.normal_resource_amount View documentation} + */ + readonly normal_resource_amount: uint | undefined + /** + * Every time this infinite resource 'ticks' down it is reduced by this amount. `nil` when not a resource. + * Meaningless if this isn't an infinite type resource. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.infinite_depletion_resource_amount View documentation} + */ + readonly infinite_depletion_resource_amount: uint | undefined + /** + * Name of the category of this resource or `nil` when not a resource. + * + * **Note**: During data stage this property is named "category". + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.resource_category View documentation} + */ + readonly resource_category: string | undefined + /** + * Whether this entity is minable and what can be obtained by mining it. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.mineable_properties View documentation} + */ + readonly mineable_properties: { + /** Is this entity mineable at all? */ + readonly minable: boolean + /** Energy required to mine an entity. */ + readonly mining_time: double + /** + * Prototype name of the particle produced when mining this entity. Will only be present if this entity produces + * any particle during mining. + */ + readonly mining_particle?: string + /** Products obtained by mining this entity. */ + readonly products?: Product[] + /** The required fluid amount if any. */ + readonly fluid_amount?: double + /** The prototype name of the required fluid if any. */ + readonly required_fluid?: string + /** The mining trigger if any. */ + readonly mining_trigger?: TriggerItem[] + } + /** + * Items that, when placed, will produce this entity. It is an array of items, or `nil` if no items place this + * entity. Construction bots will always choose the first item in this list to build this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.items_to_place_this View documentation} + */ + readonly items_to_place_this: SimpleItemStack[] | undefined + /** + * The bounding box used for collision checking. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.collision_box View documentation} + */ + readonly collision_box: BoundingBoxTable + /** + * The secondary bounding box used for collision checking, or `nil` if it doesn't have one. This is only used in + * rails and rail remnants. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.secondary_collision_box View documentation} + */ + readonly secondary_collision_box: BoundingBoxTable | undefined + /** + * The bounding box used for map generator collision checking. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.map_generator_bounding_box View documentation} + */ + readonly map_generator_bounding_box: BoundingBoxTable + /** + * The bounding box used for drawing selection. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.selection_box View documentation} + */ + readonly selection_box: BoundingBoxTable + /** + * The bounding box used for drawing the entity icon. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.drawing_box View documentation} + */ + readonly drawing_box: BoundingBoxTable + /** + * The bounding box used to attach sticker type entities. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.sticker_box View documentation} + */ + readonly sticker_box: BoundingBoxTable + /** + * The collision masks this entity uses + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.collision_mask View documentation} + */ + readonly collision_mask: CollisionMask + readonly collision_mask_with_flags: CollisionMaskWithFlags + /** + * The hardcoded default collision mask (with flags) for this entity prototype type. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.default_collision_mask_with_flags View documentation} + */ + readonly default_collision_mask_with_flags: CollisionMaskWithFlags + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.order View documentation} + */ + readonly order: string + /** + * Group of this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.group View documentation} + */ + readonly group: LuaGroup + /** + * Subgroup of this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.subgroup View documentation} + */ + readonly subgroup: LuaGroup + /** + * Amount this entity can heal per tick. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.healing_per_tick View documentation} + */ + readonly healing_per_tick: float + /** + * Amount of pollution emissions per second this entity will create. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.emissions_per_second View documentation} + */ + readonly emissions_per_second: double + /** + * Corpses used when this entity is destroyed. It is a dictionary indexed by the corpse's prototype name. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.corpses View documentation} + */ + readonly corpses: Record + /** + * Is this entity selectable? + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.selectable_in_game View documentation} + */ + readonly selectable_in_game: boolean + /** + * The selection priority of this entity - a value between 0 and 255 + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.selection_priority View documentation} + */ + readonly selection_priority: uint + /** + * The weight of this vehicle prototype or `nil` if not a vehicle prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.weight View documentation} + */ + readonly weight: double | undefined + /** + * List of resistances towards each damage type. It is a dictionary indexed by damage type names (see + * `data/base/prototypes/damage-type.lua`). + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.resistances View documentation} + */ + readonly resistances: Record + /** + * The group of mutually fast-replaceable entities. Possibly `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.fast_replaceable_group View documentation} + */ + readonly fast_replaceable_group: string | undefined + /** + * The next upgrade for this entity or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.next_upgrade View documentation} + */ + readonly next_upgrade: LuaEntityPrototype | undefined + /** + * Loot that will be dropped when this entity is killed. `nil` if there is no loot. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.loot View documentation} + */ + readonly loot: Loot[] | undefined + /** + * Repair-speed modifier for this entity. Actual repair speed will be `tool_repair_speed * + * entity_repair_speed_modifier`. May be `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.repair_speed_modifier View documentation} + */ + readonly repair_speed_modifier: uint | undefined + /** + * The range of this turret or `nil` if this isn't a turret related prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.turret_range View documentation} + */ + readonly turret_range: uint | undefined + /** + * Autoplace specification for this entity prototype. `nil` if none. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.autoplace_specification View documentation} + */ + readonly autoplace_specification: AutoplaceSpecification | undefined + /** + * The speed of this transport belt or `nil` if this isn't a transport belt related prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.belt_speed View documentation} + */ + readonly belt_speed: double | undefined + /** + * The result units and spawn points with weight and evolution factor for a biter spawner entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.result_units View documentation} + */ + readonly result_units: UnitSpawnDefinition[] + /** + * The attack result of this entity if the entity has one, else `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.attack_result View documentation} + */ + readonly attack_result: TriggerItem[] | undefined + /** + * The final attack result for projectiles `nil` if not a projectile + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.final_attack_result View documentation} + */ + readonly final_attack_result: TriggerItem[] | undefined + /** + * The attack parameters for this entity or `nil` if the entity doesn't use attack parameters. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.attack_parameters View documentation} + */ + readonly attack_parameters: AttackParameters | undefined + /** + * The spawning cooldown for this enemy spawner prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.spawn_cooldown View documentation} + */ + readonly spawn_cooldown: + | { + readonly min: double + readonly max: double + } + | undefined + /** + * The mining radius of this mining drill prototype or `nil` if this isn't a mining drill prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.mining_drill_radius View documentation} + */ + readonly mining_drill_radius: double | undefined + /** + * The mining speed of this mining drill/character prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.mining_speed View documentation} + */ + readonly mining_speed: double | undefined + /** + * The logistic mode of this logistic container or `nil` if this isn't a logistic container prototype. One of + * `"requester"`, `"active-provider"`, `"passive-provider"`, `"buffer"`, `"storage"`, `"none"`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.logistic_mode View documentation} + */ + readonly logistic_mode: + | "requester" + | "active-provider" + | "passive-provider" + | "buffer" + | "storage" + | "none" + | undefined + /** + * The max underground distance for underground belts and underground pipes or `nil` if this isn't one of those prototypes. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_underground_distance View documentation} + */ + readonly max_underground_distance: uint8 | undefined + /** + * The entity prototype flags for this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.flags View documentation} + */ + readonly flags: EntityPrototypeFlags + /** + * The remains left behind when this entity is mined. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.remains_when_mined View documentation} + */ + readonly remains_when_mined: LuaEntityPrototype[] + /** + * Entities this entity can be pasted onto in addition to the normal allowed ones. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.additional_pastable_entities View documentation} + */ + readonly additional_pastable_entities: LuaEntityPrototype[] + /** + * When false copy-paste is not allowed for this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.allow_copy_paste View documentation} + */ + readonly allow_copy_paste: boolean + /** + * The cursor size used when shooting at this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.shooting_cursor_size View documentation} + */ + readonly shooting_cursor_size: double + /** + * The smoke trigger run when this entity is built or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.created_smoke View documentation} + */ + readonly created_smoke: + | { + readonly smoke_name: string + readonly offsets: Vector[] + readonly offset_deviation: BoundingBox + readonly initial_height: float + readonly max_radius?: float + readonly speed: Vector + readonly speed_multiplier: float + readonly speed_multiplier_deviation: float + readonly starting_frame: float + readonly starting_frame_deviation: float + readonly starting_frame_speed: float + readonly starting_frame_speed_deviation: float + readonly speed_from_center: float + readonly speed_from_center_deviation: float + } + | undefined + /** + * The trigger run when this entity is created or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.created_effect View documentation} + */ + readonly created_effect: TriggerItem[] | undefined + /** + * The map color used when charting this entity if a friendly or enemy color isn't defined or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.map_color View documentation} + */ + readonly map_color: ColorTable | undefined + /** + * The friendly map color used when charting this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.friendly_map_color View documentation} + */ + readonly friendly_map_color: ColorTable + /** + * The enemy map color used when charting this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.enemy_map_color View documentation} + */ + readonly enemy_map_color: ColorTable + /** + * The evolution requirement to build this entity as a base when expanding enemy bases. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.build_base_evolution_requirement View documentation} + */ + readonly build_base_evolution_requirement: double + /** + * The instruments for this programmable speaker or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.instruments View documentation} + */ + readonly instruments: ProgrammableSpeakerInstrument[] | undefined + /** + * The maximum polyphony for this programmable speaker or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_polyphony View documentation} + */ + readonly max_polyphony: uint | undefined + /** + * The module inventory size or `nil` if this entity doesn't support modules. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.module_inventory_size View documentation} + */ + readonly module_inventory_size: uint | undefined + /** + * The max number of ingredients this crafting-machine prototype supports or `nil` if this isn't a crafting-machine prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.ingredient_count View documentation} + */ + readonly ingredient_count: uint | undefined + /** + * The crafting speed of this crafting-machine or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.crafting_speed View documentation} + */ + readonly crafting_speed: double | undefined + /** + * The crafting categories this entity supports. Only meaningful when this is a crafting-machine or player entity type. + * + * **Note**: The value in the dictionary is meaningless and exists just to allow the dictionary type for easy lookup. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.crafting_categories View documentation} + */ + readonly crafting_categories: Record + /** + * The resource categories this character or mining drill supports, or `nil` if not a character or mining dill. + * + * **Note**: The value in the dictionary is meaningless and exists just to allow the dictionary type for easy lookup. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.resource_categories View documentation} + */ + readonly resource_categories: Record | undefined + /** + * The supply area of this electric pole, beacon, or `nil` if this is neither. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.supply_area_distance View documentation} + */ + readonly supply_area_distance: double | undefined + /** + * The maximum wire distance for this entity. 0 when the entity doesn't support wires. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_wire_distance View documentation} + */ + readonly max_wire_distance: double + /** + * The maximum circuit wire distance for this entity. 0 when the entity doesn't support circuit wires. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_circuit_wire_distance View documentation} + */ + readonly max_circuit_wire_distance: double + /** + * The direct energy usage of this entity or `nil` if this entity doesn't have a direct energy usage. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.energy_usage View documentation} + */ + readonly energy_usage: double | undefined + /** + * The theoretical maximum energy usage for this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_energy_usage View documentation} + */ + readonly max_energy_usage: double + /** + * The theoretical maximum energy production for this this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_energy_production View documentation} + */ + readonly max_energy_production: double + /** + * The effectivity of this car prototype, generator prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.effectivity View documentation} + */ + readonly effectivity: double | undefined + /** + * The energy consumption of this car prototype or `nil` if not a car prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.consumption View documentation} + */ + readonly consumption: double | undefined + /** + * The friction of this vehicle prototype or `nil` if not a vehicle prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.friction_force View documentation} + */ + readonly friction_force: double | undefined + /** + * The braking force of this vehicle prototype or `nil` if not a vehicle prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.braking_force View documentation} + */ + readonly braking_force: double | undefined + /** + * The air resistance of this rolling stock prototype or `nil` if not a rolling stock prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.air_resistance View documentation} + */ + readonly air_resistance: double | undefined + /** + * If this car prototype uses tank controls to drive or `nil` if this is not a car prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.tank_driving View documentation} + */ + readonly tank_driving: boolean | undefined + /** + * The rotation speed of this car prototype or `nil` if not a car prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.rotation_speed View documentation} + */ + readonly rotation_speed: double | undefined + /** + * The turret rotation speed of this car prototype or `nil` if not a car prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.turret_rotation_speed View documentation} + */ + readonly turret_rotation_speed: double | undefined + /** + * The guns this prototype uses or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.guns View documentation} + */ + readonly guns: Record | undefined + /** + * The default speed of this flying robot, rolling stock or unit, `nil` if not one of these. + * + * **Note**: For rolling stocks, this is their `max_speed`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.speed View documentation} + */ + readonly speed: double | undefined + /** + * The speed multiplier when this flying robot is out of energy or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.speed_multiplier_when_out_of_energy View documentation} + */ + readonly speed_multiplier_when_out_of_energy: float | undefined + /** + * The max payload size of this logistics or construction robot or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_payload_size View documentation} + */ + readonly max_payload_size: uint | undefined + /** + * Whether this logistics or construction robot renders its cargo when flying or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.draw_cargo View documentation} + */ + readonly draw_cargo: boolean | undefined + /** + * The energy consumed per tile moved for this flying robot or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.energy_per_move View documentation} + */ + readonly energy_per_move: double | undefined + /** + * The energy consumed per tick for this flying robot or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.energy_per_tick View documentation} + */ + readonly energy_per_tick: double | undefined + /** + * The max energy for this flying robot or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_energy View documentation} + */ + readonly max_energy: double | undefined + /** + * The minimum energy for this flying robot before it tries to recharge or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.min_to_charge View documentation} + */ + readonly min_to_charge: float | undefined + /** + * The maximum energy for this flying robot above which it won't try to recharge when stationing or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_to_charge View documentation} + */ + readonly max_to_charge: float | undefined + /** + * The burner energy source prototype this entity uses or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.burner_prototype View documentation} + */ + readonly burner_prototype: LuaBurnerPrototype | undefined + /** + * The electric energy source prototype this entity uses or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.electric_energy_source_prototype View documentation} + */ + readonly electric_energy_source_prototype: LuaElectricEnergySourcePrototype | undefined + /** + * The heat energy source prototype this entity uses or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.heat_energy_source_prototype View documentation} + */ + readonly heat_energy_source_prototype: LuaHeatEnergySourcePrototype | undefined + /** + * The fluid energy source prototype this entity uses or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.fluid_energy_source_prototype View documentation} + */ + readonly fluid_energy_source_prototype: LuaFluidEnergySourcePrototype | undefined + /** + * The void energy source prototype this entity uses or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.void_energy_source_prototype View documentation} + */ + readonly void_energy_source_prototype: LuaVoidEnergySourcePrototype | undefined + /** + * The log2 of grid size of the building + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.building_grid_bit_shift View documentation} + */ + readonly building_grid_bit_shift: uint + /** + * The fluid usage of this generator prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.fluid_usage_per_tick View documentation} + */ + readonly fluid_usage_per_tick: double | undefined + /** + * The maximum fluid temperature of this generator prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.maximum_temperature View documentation} + */ + readonly maximum_temperature: double | undefined + /** + * The target temperature of this boiler prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.target_temperature View documentation} + */ + readonly target_temperature: double | undefined + /** + * The fluid this offshore pump produces or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.fluid View documentation} + */ + readonly fluid: LuaFluidPrototype | undefined + /** + * The fluid capacity of this entity or 0 if this entity doesn't support fluids. + * + * **Note**: Crafting machines will report 0 due to their fluid capacity being what ever a given recipe needs. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.fluid_capacity View documentation} + */ + readonly fluid_capacity: double + /** + * The pumping speed of this offshore pump, normal pump, or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.pumping_speed View documentation} + */ + readonly pumping_speed: double | undefined + /** + * If this inserter is a stack-type. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.stack View documentation} + */ + readonly stack: boolean + /** + * If this inserter allows custom pickup and drop vectors. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.allow_custom_vectors View documentation} + */ + readonly allow_custom_vectors: boolean + /** + * If this inserter allows burner leeching. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.allow_burner_leech View documentation} + */ + readonly allow_burner_leech: boolean + /** + * The extension speed of this inserter or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.inserter_extension_speed View documentation} + */ + readonly inserter_extension_speed: double | undefined + /** + * The rotation speed of this inserter or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.inserter_rotation_speed View documentation} + */ + readonly inserter_rotation_speed: double | undefined + /** + * The pickup position for this inserter or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.inserter_pickup_position View documentation} + */ + readonly inserter_pickup_position: Vector | undefined + /** + * The drop position for this inserter or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.inserter_drop_position View documentation} + */ + readonly inserter_drop_position: Vector | undefined + /** + * True if this inserter chases items on belts for pickup or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.inserter_chases_belt_items View documentation} + */ + readonly inserter_chases_belt_items: boolean | undefined + /** + * If this simple-entity is counted as a rock for the deconstruction planner "trees and rocks only" filter. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.count_as_rock_for_filtered_deconstruction View documentation} + */ + readonly count_as_rock_for_filtered_deconstruction: boolean + /** + * The filter count of this inserter, loader, or logistic chest or `nil`. For logistic containers, `nil` means no limit. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.filter_count View documentation} + */ + readonly filter_count: uint | undefined + /** + * The time to live for this prototype or `0` if prototype doesn't have time_to_live or time_before_removed. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.time_to_live View documentation} + */ + readonly time_to_live: uint + /** + * The distribution effectivity for this beacon prototype or `nil` if not a beacon prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.distribution_effectivity View documentation} + */ + readonly distribution_effectivity: double | undefined + /** + * Does this explosion have a beam or `nil` if not an explosion prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.explosion_beam View documentation} + */ + readonly explosion_beam: double | undefined + /** + * Does this explosion rotate or `nil` if not an explosion prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.explosion_rotate View documentation} + */ + readonly explosion_rotate: double | undefined + /** + * If it is a tree, return the number of colors it supports. `nil` otherwise. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.tree_color_count View documentation} + */ + readonly tree_color_count: uint8 | undefined + /** + * Does this entity with health prototype alert when damaged? or `nil` if not entity with health prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.alert_when_damaged View documentation} + */ + readonly alert_when_damaged: boolean | undefined + /** + * Does this turret prototype alert when attacking? or `nil` if not turret prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.alert_when_attacking View documentation} + */ + readonly alert_when_attacking: boolean | undefined + /** + * The color of the prototype, or `nil` if the prototype doesn't have color. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.color View documentation} + */ + readonly color: ColorTable | undefined + /** + * Does this prototype collision mask collide with itself? + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.collision_mask_collides_with_self View documentation} + */ + readonly collision_mask_collides_with_self: boolean + /** + * Does this prototype collision mask collide with tiles only? + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.collision_mask_collides_with_tiles_only View documentation} + */ + readonly collision_mask_collides_with_tiles_only: boolean + /** + * Does this prototype collision mask consider tile transitions? + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.collision_mask_considers_tile_transitions View documentation} + */ + readonly collision_mask_considers_tile_transitions: boolean + /** + * The allowed module effects for this entity or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.allowed_effects View documentation} + */ + readonly allowed_effects: Record | undefined + /** + * The rocket parts required for this rocket silo prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.rocket_parts_required View documentation} + */ + readonly rocket_parts_required: uint | undefined + /** + * The rocket rising delay for this rocket silo prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.rocket_rising_delay View documentation} + */ + readonly rocket_rising_delay: uint8 | undefined + /** + * The rocket launch delay for this rocket silo prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.launch_wait_time View documentation} + */ + readonly launch_wait_time: uint8 | undefined + /** + * The light blinking speed for this rocket silo prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.light_blinking_speed View documentation} + */ + readonly light_blinking_speed: double | undefined + /** + * The door opening speed for this rocket silo prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.door_opening_speed View documentation} + */ + readonly door_opening_speed: double | undefined + /** + * The rising speed for this rocket silo rocket prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.rising_speed View documentation} + */ + readonly rising_speed: double | undefined + /** + * The engine starting speed for this rocket silo rocket prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.engine_starting_speed View documentation} + */ + readonly engine_starting_speed: double | undefined + /** + * The flying speed for this rocket silo rocket prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.flying_speed View documentation} + */ + readonly flying_speed: double | undefined + /** + * The flying acceleration for this rocket silo rocket prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.flying_acceleration View documentation} + */ + readonly flying_acceleration: double | undefined + /** + * The fixed recipe name for this assembling machine prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.fixed_recipe View documentation} + */ + readonly fixed_recipe: string | undefined + /** + * The construction radius for this roboport prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.construction_radius View documentation} + */ + readonly construction_radius: double | undefined + /** + * The logistic radius for this roboport prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.logistic_radius View documentation} + */ + readonly logistic_radius: double | undefined + /** + * The energy used per hitpoint taken for this vehicle during collisions or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.energy_per_hit_point View documentation} + */ + readonly energy_per_hit_point: double | undefined + /** + * If this prototype will attempt to create a ghost of itself on death. + * + * **Note**: If this is false then a ghost will never be made, if it's true a ghost may be made. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.create_ghost_on_death View documentation} + */ + readonly create_ghost_on_death: boolean + /** + * The time it takes this land mine to arm. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.timeout View documentation} + */ + readonly timeout: uint + /** + * The fluidbox prototypes for this entity. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.fluidbox_prototypes View documentation} + */ + readonly fluidbox_prototypes: LuaFluidBoxPrototype[] + /** + * *Can only be used if this is Reactor* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.neighbour_bonus View documentation} + */ + readonly neighbour_bonus: double + /** + * Controls how much a reactor extends when connected to other reactors. + * + * *Can only be used if this is Reactor* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.neighbour_collision_increase View documentation} + */ + readonly neighbour_collision_increase: double + /** + * *Can only be used if this is Loader* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.container_distance View documentation} + */ + readonly container_distance: double + /** + * *Can only be used if this is Loader* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.belt_distance View documentation} + */ + readonly belt_distance: double + /** + * *Can only be used if this is Loader* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.belt_length View documentation} + */ + readonly belt_length: double + readonly is_building: boolean + /** + * The amount of ammo that inserters automatically insert into this ammo-turret or artillery-turret or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.automated_ammo_count View documentation} + */ + readonly automated_ammo_count: uint | undefined + /** + * The max speed of this projectile prototype or flying robot prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_speed View documentation} + */ + readonly max_speed: double | undefined + /** + * Value between 0 and 1 darkness where all lamps of this lamp prototype are on or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.darkness_for_all_lamps_on View documentation} + */ + readonly darkness_for_all_lamps_on: float | undefined + /** + * Value between 0 and 1 darkness where all lamps of this lamp prototype are off or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.darkness_for_all_lamps_off View documentation} + */ + readonly darkness_for_all_lamps_off: float | undefined + /** + * Whether the lamp is always on (except when out of power or turned off by the circuit network) or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.always_on View documentation} + */ + readonly always_on: boolean | undefined + /** + * The minimum darkness at which this unit spawner can spawn entities. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.min_darkness_to_spawn View documentation} + */ + readonly min_darkness_to_spawn: float + /** + * The maximum darkness at which this unit spawner can spawn entities. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_darkness_to_spawn View documentation} + */ + readonly max_darkness_to_spawn: float + readonly call_for_help_radius: double + /** + * Count of enemies this spawner can sustain. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_count_of_owned_units View documentation} + */ + readonly max_count_of_owned_units: double + /** + * How many friendly units are required within the spawning_radius of this spawner for it to stop producing more units. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_friends_around_to_spawn View documentation} + */ + readonly max_friends_around_to_spawn: double + /** + * How far from the spawner can the units be spawned. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.spawning_radius View documentation} + */ + readonly spawning_radius: double + /** + * What spaces should be between the spawned units. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.spawning_spacing View documentation} + */ + readonly spawning_spacing: double + /** + * The radius of this entity prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.radius View documentation} + */ + readonly radius: double + /** + * The item prototype name used to destroy this cliff or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.cliff_explosive_prototype View documentation} + */ + readonly cliff_explosive_prototype: string | undefined + /** + * The rocket entity prototype associated with this rocket silo prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.rocket_entity_prototype View documentation} + */ + readonly rocket_entity_prototype: LuaEntityPrototype | undefined + /** + * Whether this unit, car, or character prototype has belt immunity, `nil` if not car, unit, or character prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.has_belt_immunity View documentation} + */ + readonly has_belt_immunity: boolean | undefined + /** + * The vision distance of this unit prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.vision_distance View documentation} + */ + readonly vision_distance: double | undefined + /** + * The amount of pollution that has to be absorbed by the unit's spawner before the unit will leave the spawner and + * attack the source of the pollution. `nil` when prototype is not a unit prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.pollution_to_join_attack View documentation} + */ + readonly pollution_to_join_attack: float | undefined + /** + * The minimum pursue time of this unit prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.min_pursue_time View documentation} + */ + readonly min_pursue_time: uint | undefined + /** + * The maximum pursue distance of this unit prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_pursue_distance View documentation} + */ + readonly max_pursue_distance: double | undefined + /** + * The radar range of this unit prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.radar_range View documentation} + */ + readonly radar_range: uint | undefined + /** + * Whether this unit prototype can move while shooting or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.move_while_shooting View documentation} + */ + readonly move_while_shooting: boolean | undefined + /** + * Whether this unit prototype can open gates or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.can_open_gates View documentation} + */ + readonly can_open_gates: boolean | undefined + /** + * Whether this unit prototype is affected by tile walking speed modifiers or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.affected_by_tiles View documentation} + */ + readonly affected_by_tiles: boolean | undefined + /** + * The distraction cooldown of this unit prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.distraction_cooldown View documentation} + */ + readonly distraction_cooldown: uint | undefined + /** + * The spawning time modifier of this unit prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.spawning_time_modifier View documentation} + */ + readonly spawning_time_modifier: double | undefined + /** + * The alert icon shift of this entity prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.alert_icon_shift View documentation} + */ + readonly alert_icon_shift: Vector + /** + * The item prototype names that are the inputs of this lab prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.lab_inputs View documentation} + */ + readonly lab_inputs: string[] | undefined + /** + * The base researching speed of this lab prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.researching_speed View documentation} + */ + readonly researching_speed: double | undefined + /** + * The item slot count of this constant combinator prototype or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.item_slot_count View documentation} + */ + readonly item_slot_count: uint | undefined + /** + * The base productivity of this crafting machine, lab, or mining drill, or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.base_productivity View documentation} + */ + readonly base_productivity: double | undefined + /** + * If this market allows access to all forces or just friendly ones. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.allow_access_to_all_forces View documentation} + */ + readonly allow_access_to_all_forces: boolean + /** + * If this entity prototype could possibly ever be rotated. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.supports_direction View documentation} + */ + readonly supports_direction: boolean + /** + * The terrain friction modifier for this vehicle. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.terrain_friction_modifier View documentation} + */ + readonly terrain_friction_modifier: float + /** + * If this vehicle allows passengers. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.allow_passengers View documentation} + */ + readonly allow_passengers: boolean + /** + * The radius of the area this radar can chart, in chunks. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_distance_of_sector_revealed View documentation} + */ + readonly max_distance_of_sector_revealed: uint + /** + * The radius of the area constantly revealed by this radar, in chunks. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.max_distance_of_nearby_sector_revealed View documentation} + */ + readonly max_distance_of_nearby_sector_revealed: uint + /** + * The bounding box that specifies which tiles adjacent to the offshore pump should be checked. + * + * *Can only be used if this is OffshorePump* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.adjacent_tile_collision_box View documentation} + */ + readonly adjacent_tile_collision_box: BoundingBoxTable + /** + * Tiles adjacent to the offshore pump must not collide with this collision mask. + * + * *Can only be used if this is OffshorePump* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.adjacent_tile_collision_mask View documentation} + */ + readonly adjacent_tile_collision_mask: CollisionMask + /** + * If this mask is not empty, tiles adjacent to the offshore pump must not collide with this collision mask. + * + * *Can only be used if this is OffshorePump* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.adjacent_tile_collision_test View documentation} + */ + readonly adjacent_tile_collision_test: CollisionMask + /** + * The collision mask used only for collision test with tile directly at offshore pump position. + * + * *Can only be used if this is OffshorePump* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.center_collision_mask View documentation} + */ + readonly center_collision_mask: CollisionMask + /** + * The equipment grid prototype for this entity or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.grid_prototype View documentation} + */ + readonly grid_prototype: LuaEquipmentGridPrototype | undefined + readonly remove_decoratives: string + /** + * *Can only be used if this is TransportBelt* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.related_underground_belt View documentation} + */ + readonly related_underground_belt: LuaEntityPrototype + /** + * Gets the current movement speed of this character, including effects from exoskeletons, tiles, stickers and shooting. + * + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.running_speed View documentation} + */ + readonly running_speed: double + /** + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.maximum_corner_sliding_distance View documentation} + */ + readonly maximum_corner_sliding_distance: double + /** + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.build_distance View documentation} + */ + readonly build_distance: uint + /** + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.drop_item_distance View documentation} + */ + readonly drop_item_distance: uint + /** + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.reach_distance View documentation} + */ + readonly reach_distance: uint + /** + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.reach_resource_distance View documentation} + */ + readonly reach_resource_distance: double + /** + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.item_pickup_distance View documentation} + */ + readonly item_pickup_distance: double + /** + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.loot_pickup_distance View documentation} + */ + readonly loot_pickup_distance: double + /** + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.enter_vehicle_distance View documentation} + */ + readonly enter_vehicle_distance: double + /** + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.ticks_to_keep_gun View documentation} + */ + readonly ticks_to_keep_gun: uint + /** + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.ticks_to_keep_aiming_direction View documentation} + */ + readonly ticks_to_keep_aiming_direction: uint + /** + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.ticks_to_stay_in_combat View documentation} + */ + readonly ticks_to_stay_in_combat: uint + /** + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.respawn_time View documentation} + */ + readonly respawn_time: uint + /** + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.damage_hit_tint View documentation} + */ + readonly damage_hit_tint: ColorTable + /** + * *Can only be used if this is Character* + * + * {@link https://lua-api.factorio.com/next/LuaEntityPrototype.html#LuaEntityPrototype.character_corpse View documentation} + */ + readonly character_corpse: LuaEntityPrototype + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaEntityPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * An item in a {@link LuaEquipmentGrid}, for example one's power armor. + * + * **Note**: An equipment reference becomes invalid once the equipment is removed or the equipment grid it resides in is + * destroyed. + * + * {@link https://lua-api.factorio.com/next/LuaEquipment.html View documentation} + * + * @noSelf + */ +interface LuaEquipment { + /** + * Name of this equipment. + * + * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.name View documentation} + */ + readonly name: string + /** + * Type of this equipment. + * + * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.type View documentation} + */ + readonly type: string + /** + * Position of this equipment in the equipment grid. + * + * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.position View documentation} + */ + readonly position: PositionTable + /** + * Shape of this equipment. + * + * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.shape View documentation} + */ + readonly shape: { + readonly width: uint + readonly height: uint + } + /** + * Current shield value of the equipment. + * + * **Note**: Can't be set higher than {@link LuaEquipment.max_shield LuaEquipment::max_shield}. + * + * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.shield View documentation} + */ + shield: double + /** + * Maximum shield value. + * + * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.max_shield View documentation} + */ + readonly max_shield: double + /** + * Maximum solar power generated. + * + * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.max_solar_power View documentation} + */ + readonly max_solar_power: double + /** + * Movement speed bonus. + * + * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.movement_bonus View documentation} + */ + readonly movement_bonus: double + /** + * Energy generated per tick. + * + * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.generator_power View documentation} + */ + readonly generator_power: double + /** + * Current available energy. + * + * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.energy View documentation} + */ + energy: double + /** + * Maximum amount of energy that can be stored in this equipment. + * + * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.max_energy View documentation} + */ + readonly max_energy: double + readonly prototype: LuaEquipmentPrototype + /** + * The burner energy source for this equipment or `nil` if there isn't one. + * + * {@link https://lua-api.factorio.com/next/LuaEquipment.html#LuaEquipment.burner View documentation} + */ + readonly burner: LuaBurner | undefined + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaEquipment" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of an equipment category. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentCategoryPrototype.html View documentation} + * + * @noSelf + */ +interface LuaEquipmentCategoryPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentCategoryPrototype.html#LuaEquipmentCategoryPrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentCategoryPrototype.html#LuaEquipmentCategoryPrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaEquipmentCategoryPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * An equipment grid is for example the inside of a power armor. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html View documentation} + * + * @noSelf + */ +interface LuaEquipmentGrid { + /** + * Remove an equipment from the grid. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.take View documentation} + * + * @returns The removed equipment, or `nil` if no equipment was removed. + */ + take(params: { + /** Take the equipment that contains this position in the grid. */ + readonly position?: Position + /** Take this exact equipment. */ + readonly equipment?: LuaEquipment + /** + * If provided the action is done 'as' this player and + * {@link OnPlayerRemovedEquipmentEvent on_player_removed_equipment} is triggered. + */ + readonly by_player?: PlayerIdentification + }): SimpleItemStack | undefined + /** + * Remove all equipment from the grid. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.take_all View documentation} + * + * @param by_player - If provided, the action is done 'as' this player and + * {@link OnPlayerRemovedEquipmentEvent on_player_removed_equipment} is triggered. + * @returns Count of each removed equipment, indexed by their prototype names. + */ + take_all(by_player?: PlayerIdentification): Record + /** + * Clear all equipment from the grid, removing it without actually returning it. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.clear View documentation} + * + * @param by_player - If provided, the action is done 'as' this player and + * {@link OnPlayerRemovedEquipmentEvent on_player_removed_equipment} is triggered. + */ + clear(by_player?: PlayerIdentification): void + /** + * Insert an equipment into the grid. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.put View documentation} + * + * @returns The newly-added equipment, or `nil` if the equipment could not be added. + */ + put(params: { + /** Equipment prototype name */ + readonly name: string + /** Grid position to put the equipment in. */ + readonly position?: Position + /** + * If provided the action is done 'as' this player and + * {@link OnPlayerPlacedEquipmentEvent on_player_placed_equipment} is triggered. + */ + readonly by_player?: PlayerIdentification + }): LuaEquipment | undefined + /** + * Check whether moving an equipment would succeed. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.can_move View documentation} + */ + can_move(params: { + /** The equipment to move */ + readonly equipment: LuaEquipment + /** Where to put it */ + readonly position: Position + }): boolean + /** + * Move an equipment within this grid. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.move View documentation} + * + * @returns `true` if the equipment was successfully moved. + */ + move(params: { + /** The equipment to move */ + readonly equipment: LuaEquipment + /** Where to put it */ + readonly position: Position + }): boolean + /** + * Find equipment in the Equipment Grid based off a position. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.get View documentation} + * + * @param position - The position + * @returns The found equipment, or `nil` if equipment could not be found at the given position. + */ + get(position: Position): LuaEquipment | undefined + /** + * Get counts of all equipment in this grid. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.get_contents View documentation} + * + * @returns The counts, indexed by equipment names. + */ + get_contents(): Record + readonly prototype: LuaEquipmentGridPrototype + /** + * Width of the equipment grid. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.width View documentation} + */ + readonly width: uint + /** + * Height of the equipment grid. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.height View documentation} + */ + readonly height: uint + /** + * All the equipment in this grid. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.equipment View documentation} + */ + readonly equipment: LuaEquipment[] + /** + * Total energy per tick generated by the equipment inside this grid. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.generator_energy View documentation} + */ + readonly generator_energy: double + /** + * Maximum energy per tick that can be created by any solar panels in the equipment grid. Actual generated energy + * varies depending on the daylight levels. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.max_solar_energy View documentation} + */ + readonly max_solar_energy: double + /** + * The total energy stored in all batteries in the equipment grid. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.available_in_batteries View documentation} + */ + readonly available_in_batteries: double + /** + * Total energy storage capacity of all batteries in the equipment grid. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.battery_capacity View documentation} + */ + readonly battery_capacity: double + /** + * The amount of shields this equipment grid has. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.shield View documentation} + */ + readonly shield: float + /** + * The maximum amount of shields this equipment grid has. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.max_shield View documentation} + */ + readonly max_shield: float + /** + * True if this movement bonus equipment is turned off, otherwise false. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGrid.html#LuaEquipmentGrid.inhibit_movement_bonus View documentation} + */ + inhibit_movement_bonus: boolean + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaEquipmentGrid" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of an equipment grid. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGridPrototype.html View documentation} + * + * @noSelf + */ +interface LuaEquipmentGridPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGridPrototype.html#LuaEquipmentGridPrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGridPrototype.html#LuaEquipmentGridPrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * Equipment category names for the categories that may be inserted into this equipment grid. The grid will accept + * any equipment that has at least one category in this list. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGridPrototype.html#LuaEquipmentGridPrototype.equipment_categories View documentation} + * + * @see {@link LuaEquipmentPrototype.equipment_categories} + */ + readonly equipment_categories: string[] + readonly width: uint + readonly height: uint + /** + * If the player can move equipment into or out of this grid. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentGridPrototype.html#LuaEquipmentGridPrototype.locked View documentation} + */ + readonly locked: boolean + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaEquipmentGridPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a modular equipment. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html View documentation} + * + * @noSelf + */ +interface LuaEquipmentPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.name View documentation} + */ + readonly name: string + /** + * Type of this equipment prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.type View documentation} + */ + readonly type: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * Shape of this equipment prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.shape View documentation} + */ + readonly shape: { + readonly width: uint + readonly height: uint + /** Only set when the shape is "manual" */ + readonly points?: EquipmentPoint[] + } + /** + * The result item when taking this equipment out of an equipment grid. `nil` if there is no result item. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.take_result View documentation} + */ + readonly take_result: LuaItemPrototype | undefined + /** + * The max power generated by this equipment. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.energy_production View documentation} + */ + readonly energy_production: double + /** + * The shield value of this equipment. 0 for non-shield equipment. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.shield View documentation} + */ + readonly shield: float + /** + * The energy per shield point restored. 0 for non-shield equipment. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.energy_per_shield View documentation} + */ + readonly energy_per_shield: double + /** + * The logistic parameters for this roboport equipment. + * + * **Note**: Both the `charging_station_shift` and `stationing_offset` vectors are tables with `x` and `y` keys + * instead of an array. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.logistic_parameters View documentation} + */ + readonly logistic_parameters: { + readonly spawn_and_station_height: float + readonly spawn_and_station_shadow_height_offset: float + readonly charge_approach_distance: float + readonly logistic_radius: float + readonly construction_radius: float + readonly charging_station_count: uint + readonly charging_distance: float + readonly charging_station_shift: Vector + readonly charging_energy: double + readonly charging_threshold_distance: float + readonly robot_vertical_acceleration: float + readonly stationing_offset: Vector + readonly robot_limit: uint + readonly logistics_connection_distance: float + readonly robots_shrink_when_entering_and_exiting: boolean + } + readonly energy_consumption: double + /** + * *Can only be used if this is MovementBonusEquipmentPrototype* + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.movement_bonus View documentation} + */ + readonly movement_bonus: float + /** + * The energy source prototype for the equipment. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.energy_source View documentation} + */ + readonly energy_source: LuaElectricEnergySourcePrototype + /** + * Category names for this equipment. These categories will be used to determine whether this equipment is allowed + * in a particular equipment grid. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.equipment_categories View documentation} + * + * @see {@link LuaEquipmentGridPrototype.equipment_categories} + */ + readonly equipment_categories: string[] + /** + * The burner energy source prototype this equipment uses or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.burner_prototype View documentation} + */ + readonly burner_prototype: LuaBurnerPrototype | undefined + /** + * The electric energy source prototype this equipment uses or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.electric_energy_source_prototype View documentation} + */ + readonly electric_energy_source_prototype: LuaElectricEnergySourcePrototype | undefined + /** + * The background color of this equipment prototype. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.background_color View documentation} + */ + readonly background_color: ColorTable + /** + * The equipment attack parameters or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.attack_parameters View documentation} + */ + readonly attack_parameters: AttackParameters | undefined + /** + * Is this active defense equipment automatic. Returns false if not active defense equipment. + * + * {@link https://lua-api.factorio.com/next/LuaEquipmentPrototype.html#LuaEquipmentPrototype.automatic View documentation} + */ + readonly automatic: boolean + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaEquipmentPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Encapsulates statistic data for different parts of the game. In the context of flow statistics, `input` and `output` + * describe on which side of the associated GUI the values are shown. Input values are shown on the left side, output + * values on the right side. + * + * Examples: + * + * - The item production GUI shows "consumption" on the right, thus `output` describes the item consumption numbers. The + * same goes for fluid consumption. + * - The kills gui shows "losses" on the right, so `output` describes how many of the force's entities were killed by enemies. + * - The electric network GUI shows "power consumption" on the left side, so in this case `input` describes the power + * consumption numbers. + * + * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html View documentation} + * + * @noSelf + */ +interface LuaFlowStatistics { + /** + * Gets the total input count for a given prototype. + * + * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.get_input_count View documentation} + * + * @param name - The prototype name. + */ + get_input_count(name: string): uint64 | double + /** + * Sets the total input count for a given prototype. + * + * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.set_input_count View documentation} + * + * @param name - The prototype name. + * @param count - The new count. The type depends on the instance of the statistics. + */ + set_input_count(name: string, count: uint64 | double): void + /** + * Gets the total output count for a given prototype. + * + * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.get_output_count View documentation} + * + * @param name - The prototype name. + */ + get_output_count(name: string): uint64 | double + /** + * Sets the total output count for a given prototype. + * + * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.set_output_count View documentation} + * + * @param name - The prototype name. + * @param count - The new count. The type depends on the instance of the statistics. + */ + set_output_count(name: string, count: uint64 | double): void + /** + * Gets the flow count value for the given time frame. + * + * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.get_flow_count View documentation} + */ + get_flow_count(params: { + /** The prototype name. */ + readonly name: string + /** Read the input values or the output values */ + readonly input: boolean + /** The precision to read. */ + readonly precision_index: defines.flow_precision_index + /** If true, the count is returned instead of the per-time-frame value. */ + readonly count?: boolean + }): double + /** + * Adds a value to this flow statistics. + * + * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.on_flow View documentation} + * + * @param name - The prototype name. + * @param count - The count: positive or negative determines if the value goes in the input or output statistics. + */ + on_flow(name: string, count: float): void + /** + * Reset all the statistics data to 0. + * + * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.clear View documentation} + */ + clear(): void + /** + * List of input counts indexed by prototype name. Represents the data that is shown on the left side of the GUI for + * the given statistics. + * + * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.input_counts View documentation} + */ + readonly input_counts: Record + /** + * List of output counts indexed by prototype name. Represents the data that is shown on the right side of the GUI + * for the given statistics. + * + * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.output_counts View documentation} + */ + readonly output_counts: Record + /** + * The force these statistics belong to or `nil` for pollution statistics. + * + * {@link https://lua-api.factorio.com/next/LuaFlowStatistics.html#LuaFlowStatistics.force View documentation} + */ + readonly force: LuaForce | undefined + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaFlowStatistics" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * An array of fluid boxes of an entity. Entities may contain more than one fluid box, and some can change the number of + * fluid boxes -- for instance, an assembling machine will change its number of fluid boxes depending on its active recipe. + * + * See {@link Fluid} + * + * Do note that reading from a {@link LuaFluidBox} creates a new table and writing will copy the given fields from the + * table into the engine's own fluid box structure. Therefore, the correct way to update a fluidbox of an entity is to + * read it first, modify the table, then write the modified table back. Directly accessing the returned table's + * attributes won't have the desired effect. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBox.html View documentation} + * + * @example + * Double the temperature of the fluid in `entity`'s first fluid box. + * + * ```lua + * fluid = entity.fluidbox[1] + * fluid.temperature = fluid.temperature * 2 + * entity.fluidbox[1] = fluid + * ``` + * + * @noSelf + */ +interface LuaFluidBox extends Array { + /** + * The prototype of this fluidbox index. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.get_prototype View documentation} + * + * @param index + */ + get_prototype(index: uint): LuaFluidBoxPrototype + /** + * The capacity of the given fluidbox index. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.get_capacity View documentation} + * + * @param index + */ + get_capacity(index: uint): double + /** + * The fluidbox connections for the given fluidbox index. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.get_connections View documentation} + * + * @param index + */ + get_connections(index: uint): LuaFluidBox[] + /** + * Get a fluid box filter + * + * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.get_filter View documentation} + * + * @param index - The index of the filter to get. + * @returns The filter at the requested index. `nil` if there isn't one. + */ + get_filter(index: uint): FluidBoxFilter | undefined + /** + * Set a fluid box filter. + * + * **Note**: Some entities cannot have their fluidbox filter set, notably fluid wagons and crafting machines. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.set_filter View documentation} + * + * @param index - The index of the filter to set. + * @param filter - The filter to set. Setting `nil` clears the filter. + * @returns Whether the filter was set successfully. + */ + set_filter(index: uint, filter?: FluidBoxFilterSpec): boolean + /** + * Flow through the fluidbox in the last tick. It is the larger of in-flow and out-flow. + * + * **Note**: Fluid wagons do not track it and will return 0. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.get_flow View documentation} + * + * @param index + */ + get_flow(index: uint): double + /** + * Returns the fluid the fluidbox is locked onto Returns 'nil' for no lock + * + * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.get_locked_fluid View documentation} + * + * @param index + */ + get_locked_fluid(index: uint): string | undefined + /** + * Flushes all fluid from this fluidbox and its fluid system. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.flush View documentation} + * + * @param index + * @param fluid - If provided, only this fluid is flushed. + * @returns The fluid removed. + */ + flush(index: uint, fluid?: FluidIdentification): Record + /** + * Number of fluid boxes. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.operator%20# View documentation} + */ + readonly length: uint + /** + * The entity that owns this fluidbox. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.owner View documentation} + */ + readonly owner: LuaEntity + /** + * Access, set or clear a fluid box. The index must always be in bounds (see + * {@link LuaFluidBox.length LuaFluidBox::operator #}). New fluidboxes may not be added or removed using this + * operator. If the given fluid box doesn't contain any fluid, `nil` is returned. Similarly, `nil` can be written to + * a fluid box to remove all fluid from it. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBox.html#LuaFluidBox.operator%20[] View documentation} + */ + [index: number]: Fluid | undefined + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaFluidBox" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A prototype of a fluidbox owned by some {@link LuaEntityPrototype}. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html View documentation} + * + * @noSelf + */ +interface LuaFluidBoxPrototype { + /** + * The entity that this belongs to. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.entity View documentation} + */ + readonly entity: LuaEntityPrototype + /** + * The index of this fluidbox prototype in the owning entity. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.index View documentation} + */ + readonly index: uint + /** + * The pipe connection points. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.pipe_connections View documentation} + */ + readonly pipe_connections: FluidBoxConnection[] + /** + * The production type. "input", "output", "input-output", or "none". + * + * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.production_type View documentation} + */ + readonly production_type: "input" | "output" | "input-output" | "none" + readonly base_area: double + readonly base_level: double + readonly height: double + readonly volume: double + /** + * The filter or `nil` if no filter is set. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.filter View documentation} + */ + readonly filter: LuaFluidPrototype | undefined + /** + * The minimum temperature or `nil` if none is set. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.minimum_temperature View documentation} + */ + readonly minimum_temperature: double | undefined + /** + * The maximum temperature or `nil` if none is set. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.maximum_temperature View documentation} + */ + readonly maximum_temperature: double | undefined + /** + * The secondary draw orders for the 4 possible connection directions. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.secondary_draw_orders View documentation} + */ + readonly secondary_draw_orders: int[] + /** + * The render layer. + * + * {@link https://lua-api.factorio.com/next/LuaFluidBoxPrototype.html#LuaFluidBoxPrototype.render_layer View documentation} + */ + readonly render_layer: string + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaFluidBoxPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a fluid energy source. + * + * {@link https://lua-api.factorio.com/next/LuaFluidEnergySourcePrototype.html View documentation} + * + * @noSelf + */ +interface LuaFluidEnergySourcePrototype { + readonly emissions: double + readonly render_no_network_icon: boolean + readonly render_no_power_icon: boolean + readonly effectivity: double + readonly burns_fluid: boolean + readonly scale_fluid_usage: boolean + readonly fluid_usage_per_tick: double + /** + * The smoke sources for this prototype if any. + * + * {@link https://lua-api.factorio.com/next/LuaFluidEnergySourcePrototype.html#LuaFluidEnergySourcePrototype.smoke View documentation} + */ + readonly smoke: SmokeSource[] + readonly maximum_temperature: double + /** + * The fluid box for this energy source. + * + * {@link https://lua-api.factorio.com/next/LuaFluidEnergySourcePrototype.html#LuaFluidEnergySourcePrototype.fluid_box View documentation} + */ + readonly fluid_box: LuaFluidBoxPrototype + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaFluidEnergySourcePrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a fluid. + * + * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html View documentation} + * + * @noSelf + */ +interface LuaFluidPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.name View documentation} + */ + readonly name: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * Default temperature of this fluid. + * + * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.default_temperature View documentation} + */ + readonly default_temperature: double + /** + * Maximum temperature this fluid can reach. + * + * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.max_temperature View documentation} + */ + readonly max_temperature: double + /** + * The amount of energy in Joules required to heat one unit of this fluid by 1°C. + * + * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.heat_capacity View documentation} + */ + readonly heat_capacity: double + /** + * Order string for this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.order View documentation} + */ + readonly order: string + /** + * Group of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.group View documentation} + */ + readonly group: LuaGroup + /** + * Subgroup of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.subgroup View documentation} + */ + readonly subgroup: LuaGroup + readonly base_color: ColorTable + readonly flow_color: ColorTable + /** + * The temperature above which this fluid will be shown as gaseous inside tanks and pipes. + * + * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.gas_temperature View documentation} + */ + readonly gas_temperature: double + /** + * A multiplier on the amount of emissions produced when this fluid is burnt in a generator. A value above `1.0` + * increases emissions and vice versa. The multiplier can't be negative. + * + * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.emissions_multiplier View documentation} + */ + readonly emissions_multiplier: double + /** + * The amount of energy in Joules one unit of this fluid will produce when burnt in a generator. A value of `0` + * means this fluid can't be used for energy generation. The value can't be negative. + * + * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.fuel_value View documentation} + */ + readonly fuel_value: double + /** + * Whether this fluid is hidden from the fluid and signal selectors. + * + * {@link https://lua-api.factorio.com/next/LuaFluidPrototype.html#LuaFluidPrototype.hidden View documentation} + */ + readonly hidden: boolean + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaFluidPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a font. + * + * {@link https://lua-api.factorio.com/next/LuaFontPrototype.html View documentation} + * + * @noSelf + */ +interface LuaFontPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaFontPrototype.html#LuaFontPrototype.name View documentation} + */ + readonly name: string + readonly from: string + readonly size: int + readonly spacing: float + readonly border: boolean + readonly filtered: boolean + /** + * The border color or `nil` if not set. + * + * {@link https://lua-api.factorio.com/next/LuaFontPrototype.html#LuaFontPrototype.border_color View documentation} + */ + readonly border_color: ColorTable | undefined + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaFontPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * `LuaForce` encapsulates data local to each "force" or "faction" of the game. Default forces are player, enemy and + * neutral. Players and mods can create additional forces (up to 64 total). + * + * {@link https://lua-api.factorio.com/next/LuaForce.html View documentation} + * + * @noSelf + */ +interface LuaForce { + /** + * Count entities of given type. + * + * **Note**: This function has O(1) time complexity as entity counts are kept and maintained in the game engine. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_entity_count View documentation} + * + * @param name - Prototype name of the entity. + * @returns Number of entities of given prototype belonging to this force. + */ + get_entity_count(name: string): uint + /** + * Disable research for this force. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.disable_research View documentation} + */ + disable_research(): void + /** + * Enable research for this force. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.enable_research View documentation} + */ + enable_research(): void + /** + * Disable all recipes and technologies. Only recipes and technologies enabled explicitly will be useable from this point. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.disable_all_prototypes View documentation} + */ + disable_all_prototypes(): void + /** + * Enables all recipes and technologies. The opposite of + * {@link LuaForce.disable_all_prototypes LuaForce::disable_all_prototypes} + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.enable_all_prototypes View documentation} + */ + enable_all_prototypes(): void + /** + * Load the original version of all recipes from the prototypes. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.reset_recipes View documentation} + */ + reset_recipes(): void + /** + * Unlock all recipes. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.enable_all_recipes View documentation} + */ + enable_all_recipes(): void + /** + * Unlock all technologies. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.enable_all_technologies View documentation} + */ + enable_all_technologies(): void + /** + * Research all technologies. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.research_all_technologies View documentation} + * + * @param include_disabled_prototypes - Whether technologies that are explicitly disabled in the prototype should + * also be researched. Defaults to `false`. + */ + research_all_technologies(include_disabled_prototypes?: boolean): void + /** + * Load the original versions of technologies from prototypes. Preserves research state of technologies. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.reset_technologies View documentation} + */ + reset_technologies(): void + /** + * Reset everything. All technologies are set to not researched, all modifiers are set to default values. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.reset View documentation} + */ + reset(): void + /** + * Reapplies all possible research effects, including unlocked recipes. Any custom changes are lost. Preserves + * research state of technologies. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.reset_technology_effects View documentation} + */ + reset_technology_effects(): void + /** + * Chart a portion of the map. The chart for the given area is refreshed; it creates chart for any parts of the + * given area that haven't been charted yet. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.chart View documentation} + * + * @example + * Charts a 2048x2048 rectangle centered around the origin. + * + * ```lua + * game.player.force.chart(game.player.surface, {{x = -1024, y = -1024}, {x = 1024, y = 1024}}) + * ``` + * + * @param surface + * @param area - The area on the given surface to chart. + */ + chart(surface: SurfaceIdentification, area: BoundingBox): void + /** + * Erases chart data for this force. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.clear_chart View documentation} + * + * @param surface - Which surface to erase chart data for or if not provided all surfaces charts are erased. + */ + clear_chart(surface?: SurfaceIdentification): void + /** + * Force a rechart of the whole chart. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.rechart View documentation} + */ + rechart(): void + /** + * Chart all generated chunks. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.chart_all View documentation} + * + * @param surface - Which surface to chart or all if not given. + */ + chart_all(surface?: SurfaceIdentification): void + /** + * Has a chunk been charted? + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.is_chunk_charted View documentation} + * + * @param surface + * @param position - Position of the chunk. + */ + is_chunk_charted(surface: SurfaceIdentification, position: ChunkPosition): boolean + /** + * Is the given chunk currently charted and visible (not covered by fog of war) on the map. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.is_chunk_visible View documentation} + * + * @param surface + * @param position + */ + is_chunk_visible(surface: SurfaceIdentification, position: ChunkPosition): boolean + /** + * Cancels pending chart requests for the given surface or all surfaces. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.cancel_charting View documentation} + * + * @param surface + */ + cancel_charting(surface?: SurfaceIdentification): void + /** + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_ammo_damage_modifier View documentation} + * + * @param ammo - Ammo category + */ + get_ammo_damage_modifier(ammo: string): double + /** + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_ammo_damage_modifier View documentation} + * + * @param ammo - Ammo category + * @param modifier + */ + set_ammo_damage_modifier(ammo: string, modifier: double): void + /** + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_gun_speed_modifier View documentation} + * + * @param ammo - Ammo category + */ + get_gun_speed_modifier(ammo: string): double + /** + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_gun_speed_modifier View documentation} + * + * @param ammo - Ammo category + * @param modifier + */ + set_gun_speed_modifier(ammo: string, modifier: double): void + /** + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_turret_attack_modifier View documentation} + * + * @param turret - Turret prototype name + */ + get_turret_attack_modifier(turret: string): double + /** + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_turret_attack_modifier View documentation} + * + * @param turret - Turret prototype name + * @param modifier + */ + set_turret_attack_modifier(turret: string, modifier: double): void + /** + * Add `other` force to this force's cease fire list. Forces on the cease fire list won't be targeted for attack. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_cease_fire View documentation} + * + * @param other + * @param cease_fire + */ + set_cease_fire(other: ForceIdentification, cease_fire: boolean): void + /** + * Is `other` force in this force's cease fire list? + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_cease_fire View documentation} + * + * @param other + */ + get_cease_fire(other: ForceIdentification): boolean + /** + * Add `other` force to this force's friends list. Friends have unrestricted access to buildings and turrets won't + * fire at them. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_friend View documentation} + * + * @param other + * @param friend + */ + set_friend(other: ForceIdentification, friend: boolean): void + /** + * Is `other` force in this force's friends list. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_friend View documentation} + * + * @param other + */ + get_friend(other: ForceIdentification): boolean + /** + * Is pathfinder busy? When the pathfinder is busy, it won't accept any more pathfinding requests. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.is_pathfinder_busy View documentation} + */ + is_pathfinder_busy(): boolean + /** + * Kill all units and flush the pathfinder. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.kill_all_units View documentation} + */ + kill_all_units(): void + /** + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.find_logistic_network_by_position View documentation} + * + * @param position - Position to find a network for + * @param surface - Surface to search on + * @returns The found network or `nil`. + */ + find_logistic_network_by_position(position: Position, surface: SurfaceIdentification): LuaLogisticNetwork | undefined + /** + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_spawn_position View documentation} + * + * @param position - The new position on the given surface. + * @param surface - Surface to set the spawn position for. + */ + set_spawn_position(position: Position, surface: SurfaceIdentification): void + /** + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_spawn_position View documentation} + * + * @param surface + */ + get_spawn_position(surface: SurfaceIdentification): PositionTable + /** + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.unchart_chunk View documentation} + * + * @param position - The chunk position to unchart. + * @param surface - Surface to unchart on. + */ + unchart_chunk(position: ChunkPosition, surface: SurfaceIdentification): void + /** + * Gets the count of a given item launched in rockets. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_item_launched View documentation} + * + * @param item - The item to get + * @returns The count of the item that has been launched. + */ + get_item_launched(item: string): uint + /** + * Sets the count of a given item launched in rockets. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_item_launched View documentation} + * + * @param item - The item to set + * @param count - The count to set + */ + set_item_launched(item: string, count: uint): void + /** + * Print text to the chat console of all players on this force. + * + * **Note**: Messages that are identical to a message sent in the last 60 ticks are not printed again. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.print View documentation} + * + * @param message + * @param color + */ + print(message: LocalisedString, color?: Color): void + /** + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_trains View documentation} + * + * @param surface - If given only trains on the surface are returned. + */ + get_trains(surface?: SurfaceIdentification): LuaTrain[] + /** + * Adds a custom chart tag to the given surface and returns the new tag or `nil` if the given position isn't valid + * for a chart tag. + * + * **Note**: The chunk must be charted for a tag to be valid at that location. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.add_chart_tag View documentation} + * + * @param surface - Which surface to add the tag to. + * @param tag - The tag to add. + */ + add_chart_tag(surface: SurfaceIdentification, tag: ChartTagSpec): LuaCustomChartTag | undefined + /** + * Finds all custom chart tags within the given bounding box on the given surface. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.find_chart_tags View documentation} + * + * @param surface + * @param area + */ + find_chart_tags(surface: SurfaceIdentification, area?: BoundingBox): LuaCustomChartTag[] + /** + * Gets the saved progress for the given technology or `nil` if there is no saved progress. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_saved_technology_progress View documentation} + * + * @param technology - The technology + * @returns The progress as a percent. + */ + get_saved_technology_progress(technology: TechnologyIdentification): double | undefined + /** + * Sets the saved progress for the given technology. The technology must not be in progress, must not be completed, + * and the new progress must be < 100%. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_saved_technology_progress View documentation} + * + * @param technology - The technology + * @param progress - Progress as a percent. Set to `nil` to remove the saved progress. + */ + set_saved_technology_progress(technology: TechnologyIdentification, progress: double | undefined): void + /** + * Resets evolution for this force to zero. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.reset_evolution View documentation} + */ + reset_evolution(): void + /** + * Play a sound for every player in this force. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.play_sound View documentation} + */ + play_sound(params: { + /** The sound to play. */ + readonly path: SoundPath + /** Where the sound should be played. If not given, it's played at the current position of each player. */ + readonly position?: Position + /** The volume of the sound to play. Must be between 0 and 1 inclusive. */ + readonly volume_modifier?: double + /** The volume mixer to play the sound through. Defaults to the default mixer for the given sound type. */ + readonly override_sound_type?: SoundType + }): void + /** + * Gets train stops matching the given filters. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_train_stops View documentation} + */ + get_train_stops(params?: { readonly name?: string | string[]; readonly surface?: SurfaceIdentification }): LuaEntity[] + /** + * Gets if the given recipe is explicitly disabled from being hand crafted. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_hand_crafting_disabled_for_recipe View documentation} + * + * @param recipe + */ + get_hand_crafting_disabled_for_recipe(recipe: string | LuaRecipe): boolean + /** + * Sets if the given recipe can be hand-crafted. This is used to explicitly disable hand crafting a recipe - it + * won't allow hand-crafting otherwise not hand-craftable recipes. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.set_hand_crafting_disabled_for_recipe View documentation} + * + * @param recipe + * @param hand_crafting_disabled + */ + set_hand_crafting_disabled_for_recipe(recipe: string | LuaRecipe, hand_crafting_disabled: boolean): void + /** + * Add this technology to the back of the research queue if the queue is enabled. Otherwise, set this technology to + * be researched now. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.add_research View documentation} + * + * @param technology + * @returns If the technology was added. + */ + add_research(technology: TechnologyIdentification): boolean + /** + * Stop the research currently in progress. This will remove any dependent technologies from the research queue. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.cancel_current_research View documentation} + */ + cancel_current_research(): void + /** + * Gets the linked inventory for the given prototype and link ID if it exists or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.get_linked_inventory View documentation} + * + * @param prototype + * @param link_id + */ + get_linked_inventory(prototype: EntityPrototypeIdentification, link_id: uint): LuaInventory | undefined + /** + * Is this force a friend? This differs from `get_friend` in that it is always true for neutral force. This is + * equivalent to checking the `friend` ForceCondition. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.is_friend View documentation} + * + * @param other + */ + is_friend(other: ForceIdentification): boolean + /** + * Is this force an enemy? This differs from `get_cease_fire` in that it is always false for neutral force. This is + * equivalent to checking the `enemy` ForceCondition. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.is_enemy View documentation} + * + * @param other + */ + is_enemy(other: ForceIdentification): boolean + /** + * Name of the force. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.name View documentation} + * + * @example + * Prints "`player`" + * + * ```lua + * game.player.print(game.player.force.name) + * ``` + */ + readonly name: string + /** + * Technologies owned by this force, indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.technologies View documentation} + * + * @example + * Researches the technology for the player's force + * + * ```lua + * game.player.force.technologies["steel-processing"].researched = true + * ``` + */ + readonly technologies: LuaCustomTable + /** + * Recipes available to this force, indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.recipes View documentation} + * + * @example + * Prints the category of the given recipe + * + * ```lua + * game.player.print(game.player.force.recipes["transport-belt"].category) + * ``` + */ + readonly recipes: LuaCustomTable + /** + * Multiplier of the manual mining speed. Default value is `0`. The actual mining speed will be multiplied by `1 + + * manual_mining_speed_modifier`. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.manual_mining_speed_modifier View documentation} + * + * @example + * Double the player's mining speed + * + * ```lua + * game.player.force.manual_mining_speed_modifier = 1 + * ``` + */ + manual_mining_speed_modifier: double + /** + * Multiplier of the manual crafting speed. Default value is `0`. The actual crafting speed will be multiplied by `1 + * + manual_crafting_speed_modifier`. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.manual_crafting_speed_modifier View documentation} + * + * @example + * Double the player's crafting speed + * + * ```lua + * game.player.force.manual_crafting_speed_modifier = 1 + * ``` + */ + manual_crafting_speed_modifier: double + laboratory_speed_modifier: double + laboratory_productivity_bonus: double + worker_robots_speed_modifier: double + worker_robots_battery_modifier: double + worker_robots_storage_bonus: double + /** + * The current technology in research, or `nil` if no research is currently ongoing. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.current_research View documentation} + */ + readonly current_research: LuaTechnology | undefined + /** + * Progress of current research, as a number in range [0, 1]. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.research_progress View documentation} + */ + research_progress: double + /** + * The previous research if any. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.previous_research View documentation} + */ + previous_research: LuaTechnology + /** + * The inserter stack size bonus for non stack inserters + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.inserter_stack_size_bonus View documentation} + */ + inserter_stack_size_bonus: double + /** + * Number of items that can be transferred by stack inserters. When writing to this value, it must be >= 0 and <= 254. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.stack_inserter_capacity_bonus View documentation} + */ + stack_inserter_capacity_bonus: uint + /** + * Number of character trash slots. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.character_trash_slot_count View documentation} + */ + character_trash_slot_count: double + /** + * Maximum number of follower robots. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.maximum_following_robot_count View documentation} + */ + maximum_following_robot_count: uint + /** + * Additional lifetime for following robots. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.following_robots_lifetime_modifier View documentation} + */ + following_robots_lifetime_modifier: double + /** + * The time, in ticks, before a placed ghost disappears. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.ghost_time_to_live View documentation} + */ + ghost_time_to_live: uint + /** + * Players belonging to this force. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.players View documentation} + */ + readonly players: LuaPlayer[] + /** + * Enables some higher-level AI behaviour for this force. When set to `true`, biters belonging to this force will + * automatically expand into new territories, build new spawners, and form unit groups. By default, this value is + * `true` for the enemy force and `false` for all others. + * + * **Note**: Setting this to `false` does not turn off biters' AI. They will still move around and attack players + * who come close. + * + * **Note**: It is necessary for a force to be AI controllable in order to be able to create unit groups or build + * bases from scripts. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.ai_controllable View documentation} + */ + ai_controllable: boolean + /** + * List of logistic networks, grouped by surface. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.logistic_networks View documentation} + */ + readonly logistic_networks: Record + /** + * The item production statistics for this force. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.item_production_statistics View documentation} + */ + readonly item_production_statistics: LuaFlowStatistics + /** + * The fluid production statistics for this force. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.fluid_production_statistics View documentation} + */ + readonly fluid_production_statistics: LuaFlowStatistics + /** + * The kill counter statistics for this force. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.kill_count_statistics View documentation} + */ + readonly kill_count_statistics: LuaFlowStatistics + /** + * The entity build statistics for this force (built and mined) + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.entity_build_count_statistics View documentation} + */ + readonly entity_build_count_statistics: LuaFlowStatistics + /** + * Modifies the running speed of all characters in this force by the given value as a percentage. Setting the + * running modifier to `0.5` makes the character run 50% faster. The minimum value of `-1` reduces the movement + * speed by 100%, resulting in a speed of `0`. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.character_running_speed_modifier View documentation} + */ + character_running_speed_modifier: double + artillery_range_modifier: double + character_build_distance_bonus: uint + character_item_drop_distance_bonus: uint + character_reach_distance_bonus: uint + character_resource_reach_distance_bonus: double + character_item_pickup_distance_bonus: double + character_loot_pickup_distance_bonus: double + /** + * The number of additional inventory slots the character main inventory has. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.character_inventory_slots_bonus View documentation} + */ + character_inventory_slots_bonus: uint + /** + * The time, in ticks, before a deconstruction order is removed. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.deconstruction_time_to_live View documentation} + */ + deconstruction_time_to_live: uint + character_health_bonus: double + max_successful_attempts_per_tick_per_construction_queue: uint + max_failed_attempts_per_tick_per_construction_queue: uint + /** + * Ability to use zoom-to-world on map. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.zoom_to_world_enabled View documentation} + */ + zoom_to_world_enabled: boolean + /** + * Ability to build ghosts through blueprint or direct ghost placement, or "mine" ghosts when using zoom-to-world. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.zoom_to_world_ghost_building_enabled View documentation} + */ + zoom_to_world_ghost_building_enabled: boolean + /** + * Ability to create new blueprints using empty blueprint item when using zoom-to-world. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.zoom_to_world_blueprint_enabled View documentation} + */ + zoom_to_world_blueprint_enabled: boolean + /** + * Ability to use deconstruction planner when using zoom-to-world. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.zoom_to_world_deconstruction_planner_enabled View documentation} + */ + zoom_to_world_deconstruction_planner_enabled: boolean + /** + * Ability to use custom selection tools when using zoom-to-world. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.zoom_to_world_selection_tool_enabled View documentation} + */ + zoom_to_world_selection_tool_enabled: boolean + /** + * `true` if character requester logistics is enabled. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.character_logistic_requests View documentation} + */ + character_logistic_requests: boolean + /** + * The number of rockets launched. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.rockets_launched View documentation} + */ + rockets_launched: uint + /** + * All of the items that have been launched in rockets. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.items_launched View documentation} + */ + readonly items_launched: Record + /** + * The connected players belonging to this force. + * + * This is primarily useful when you want to do some action against all online players of this force. + * + * **Note**: This does *not* index using player index. See {@link LuaPlayer.index LuaPlayer::index} on each player + * instance for the player index. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.connected_players View documentation} + */ + readonly connected_players: LuaPlayer[] + mining_drill_productivity_bonus: double + train_braking_force_bonus: double + /** + * Evolution factor of this force. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.evolution_factor View documentation} + */ + evolution_factor: double + evolution_factor_by_pollution: double + evolution_factor_by_time: double + evolution_factor_by_killing_spawners: double + /** + * If friendly fire is enabled for this force. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.friendly_fire View documentation} + */ + friendly_fire: boolean + /** + * If sharing chart data is enabled for this force. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.share_chart View documentation} + */ + share_chart: boolean + /** + * Whether the research queue is available for this force. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.research_queue_enabled View documentation} + */ + research_queue_enabled: boolean + /** + * Unique ID associated with this force. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.index View documentation} + */ + readonly index: uint + /** + * The research queue of this force. The first technology in the array is the currently active one. Reading this + * attribute gives an array of {@link LuaTechnology}. + * + * To write to this, the entire table must be written. Providing an empty table or `nil` will empty the research + * queue and cancel the current research. Writing to this when the research queue is disabled will simply set the + * last research in the table as the current research. + * + * **Note**: This only allows mods to queue research that this force is able to research in the first place. As an + * example, an already researched technology or one whose prerequisites are not fulfilled will not be queued, but + * dropped silently instead. + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.research_queue View documentation} + */ + research_queue: TechnologyIdentification[] | undefined + /** + * Whether research is enabled for this force, see {@link LuaForce.enable_research LuaForce::enable_research} and + * {@link LuaForce.disable_research LuaForce::disable_research} + * + * {@link https://lua-api.factorio.com/next/LuaForce.html#LuaForce.research_enabled View documentation} + */ + readonly research_enabled: boolean + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaForce" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a fuel category. + * + * {@link https://lua-api.factorio.com/next/LuaFuelCategoryPrototype.html View documentation} + * + * @noSelf + */ +interface LuaFuelCategoryPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaFuelCategoryPrototype.html#LuaFuelCategoryPrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaFuelCategoryPrototype.html#LuaFuelCategoryPrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaFuelCategoryPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Main toplevel type, provides access to most of the API though its members. An instance of LuaGameScript is available + * as the global object named `game`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html View documentation} + * + * @noSelf + */ +interface LuaGameScript { + /** + * Set scenario state. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.set_game_state View documentation} + */ + set_game_state(params: { + readonly game_finished: boolean + readonly player_won: boolean + readonly next_level: string + readonly can_continue: boolean + readonly victorious_force: ForceIdentification + }): void + /** + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_entity_by_tag View documentation} + * + * @param tag + */ + get_entity_by_tag(tag: string): LuaEntity + /** + * Show an in-game message dialog. + * + * **Note**: Can only be used when the map contains exactly one player. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.show_message_dialog View documentation} + */ + show_message_dialog(params: { + /** What the dialog should say */ + readonly text: LocalisedString + /** Path to an image to show on the dialog */ + readonly image?: string + /** + * If specified, dialog will show an arrow pointing to this place. When not specified, the arrow will point to + * the player's position. (Use `point_to={type="nowhere"}` to remove the arrow entirely.) The dialog itself will + * be placed near the arrow's target. + */ + readonly point_to?: GuiArrowSpecification + /** The gui style to use for this speech bubble. Must be of type speech_bubble. */ + readonly style?: string + /** Must be of type flow_style. */ + readonly wrapper_frame_style?: string + }): void + /** + * Is this the demo version of Factorio? + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.is_demo View documentation} + */ + is_demo(): boolean + /** + * Forces a reload of the scenario script from the original scenario location. + * + * **Note**: This disables the replay if replay is enabled. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.reload_script View documentation} + */ + reload_script(): void + /** + * Forces a reload of all mods. + * + * **Note**: This will act like saving and loading from the mod(s) perspective. + * + * **Note**: This will do nothing if run in multiplayer. + * + * **Note**: This disables the replay if replay is enabled. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.reload_mods View documentation} + */ + reload_mods(): void + /** + * Saves the current configuration of Atlas to a file. This will result in huge file containing all of the game + * graphics moved to as small space as possible. + * + * **Note**: Exists mainly for debugging reasons. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.save_atlas View documentation} + */ + save_atlas(): void + /** + * Run internal consistency checks. Allegedly prints any errors it finds. + * + * **Note**: Exists mainly for debugging reasons. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.check_consistency View documentation} + */ + check_consistency(): void + /** + * Regenerate autoplacement of some entities on all surfaces. This can be used to autoplace newly-added entities. + * + * **Note**: All specified entity prototypes must be autoplacable. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.regenerate_entity View documentation} + * + * @param entities - Prototype names of entity or entities to autoplace. + */ + regenerate_entity(entities: string | string[]): void + /** + * Take a screenshot and save it to a file. + * + * **Note**: If Factorio is running headless, this function will do nothing. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.take_screenshot View documentation} + */ + take_screenshot(params: { + readonly player?: PlayerIdentification + /** If defined, the screenshot will only be taken for this player. */ + readonly by_player?: PlayerIdentification + /** If defined, the screenshot will be taken on this surface. */ + readonly surface?: SurfaceIdentification + /** If defined, the screenshot will be centered on this position. */ + readonly position?: Position + /** + * Maximum allowed resolution is 16384x16384 (resp. 8192x8192 when anti_alias is true), but maximum recommended + * resolution is 4096x4096 (resp. 2048x2048). + */ + readonly resolution?: Position + readonly zoom?: double + /** Path to save the screenshot in */ + readonly path?: string + /** Include game GUI in the screenshot? */ + readonly show_gui?: boolean + /** Include entity info (alt-mode)? */ + readonly show_entity_info?: boolean + /** When true, and player is specified, building preview for item in player's cursor will be rendered also. */ + readonly show_cursor_building_preview?: boolean + /** Render in double resolution and scale down (including GUI)? */ + readonly anti_alias?: boolean + /** The render quality if using jpg format (0-100 inclusive). */ + readonly quality?: int + /** + * If true, the screenshot will be saved even during replay playback, otherwise this function call does nothing + * in replays. + */ + readonly allow_in_replay?: boolean + /** Overrides current surface daytime for duration of screenshot rendering. */ + readonly daytime?: double + /** Overrides tick of water animation (if animated water is enabled). */ + readonly water_tick?: uint + /** + * Screenshot requests are processed in between update and render. The game may skip rendering (drop frames) if + * previous frame has not finished rendering or the game simulation starts to fall under 60 updates per second. + * If force_render is set to true, the game won't drop frames and process the screenshot request at the end of + * the update in which the request was created. This is not honored on multiplayer clients that are catching up + * to server. + */ + readonly force_render?: boolean + }): void + /** + * Forces the screenshot saving system to wait until all queued screenshots have been written to disk. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.set_wait_for_screenshots_to_finish View documentation} + */ + set_wait_for_screenshots_to_finish(): void + take_technology_screenshot(params: { + /** The force to use. If not given the `"player`" force is used. */ + readonly force?: ForceIdentification + /** Path to save the screenshot in. */ + readonly path?: string + /** If defined, the screenshot will only be taken for this player. */ + readonly by_player?: PlayerIdentification + /** The technology to highlight. */ + readonly selected_technology?: TechnologyIdentification + /** + * If `true`, disabled technologies will be skipped. Their successors will be attached to the disabled + * technology's parents. Defaults to `false`. + */ + readonly skip_disabled?: boolean + /** The render quality if using jpg format (0-100 inclusive). */ + readonly quality?: int + }): void + /** + * Convert a table to a JSON string + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.table_to_json View documentation} + * + * @param data + */ + table_to_json(data: table): string + /** + * Convert a JSON string to a table. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.json_to_table View documentation} + * + * @param json - The string to convert. + * @returns The returned object, or `nil` if the json was invalid. + */ + json_to_table(json: string): AnyBasic | undefined + /** + * Write a string to a file. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.write_file View documentation} + * + * @param filename - Path to the file to write to. + * @param data - File content + * @param append - When `true`, this will append to the end of the file. Defaults to `false`, which will overwrite + * any pre-existing file with the new data. + * @param for_player - If given, the file will only be written for this player_index. 0 means only the server if one exists. + */ + write_file(filename: string, data: LocalisedString, append?: boolean, for_player?: uint): void + /** + * Remove file or directory. Given path is taken relative to the script output directory. Can be used to remove + * files created by {@link LuaGameScript.write_file LuaGameScript::write_file}. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.remove_path View documentation} + * + * @param path - Path to remove, relative to the script output directory + */ + remove_path(path: string): void + /** + * Remove players who are currently not connected from the map. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.remove_offline_players View documentation} + * + * @param players - List of players to remove. If not specified, remove all offline players. + */ + remove_offline_players(players?: (LuaPlayer | string)[]): void + /** + * Force a CRC check. Tells all peers to calculate their current map CRC; these CRC are then compared against each + * other. If a mismatch is detected, the game is desynced and some peers are forced to reconnect. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.force_crc View documentation} + */ + force_crc(): void + /** + * Create a new force. + * + * **Note**: The game currently supports a maximum of 64 forces, including the three built-in forces. This means + * that a maximum of 61 new forces may be created. + * + * **Note**: Force names must be unique. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.create_force View documentation} + * + * @param force - Name of the new force + * @returns The force that was just created + */ + create_force(force: string): LuaForce + /** + * Marks two forces to be merge together. All entities in the source force will be reassigned to the target force. + * The source force will then be destroyed. + * + * **Note**: The three built-in forces -- player, enemy and neutral -- can't be destroyed. I.e. they can't be used + * as the source argument to this function. + * + * **Note**: The source force is not merged until the end of the current tick or if called during the + * {@link OnForcesMergingEvent on_forces_merging} event or {@link OnForcesMergedEvent on_forces_merged} event the end + * of the next tick. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.merge_forces View documentation} + * + * @param source - The force to remove + * @param destination - The force to reassign all entities to + */ + merge_forces(source: ForceIdentification, destination: ForceIdentification): void + /** + * Create a new surface + * + * **Note**: The game currently supports a maximum of 4,294,967,295 surfaces, including the default surface. + * + * **Note**: Surface names must be unique + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.create_surface View documentation} + * + * @param name - Name of the new surface + * @param settings - Map generation settings + * @returns The surface that was just created + */ + create_surface(name: string, settings?: MapGenSettings): LuaSurface + /** + * Instruct the server to save the map. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.server_save View documentation} + * + * @param name - Save name. If not specified, writes into the currently-running save. + */ + server_save(name?: string): void + /** + * Instruct the game to perform an auto-save. + * + * **Note**: Only the server will save in multiplayer. In single player a standard auto-save is triggered. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.auto_save View documentation} + * + * @param name - The autosave name if any. Saves will be named _autosave-*name* when provided. + */ + auto_save(name?: string): void + /** + * Deletes the given surface and all entities on it. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.delete_surface View documentation} + * + * @param surface - The surface to be deleted. Currently the primary surface (1, 'nauvis') cannot be deleted. + */ + delete_surface(surface: string | LuaSurface): void + /** + * Disables replay saving for the current save file. Once done there's no way to re-enable replay saving for the + * save file without loading an old save. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.disable_replay View documentation} + */ + disable_replay(): void + /** + * Disables tutorial triggers, that unlock new tutorials and show notices about unlocked tutorials. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.disable_tutorial_triggers View documentation} + */ + disable_tutorial_triggers(): void + /** + * Converts the given direction into the string version of the direction. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.direction_to_string View documentation} + * + * @param direction + */ + direction_to_string(direction: defines.direction): void + /** + * Print text to the chat console all players. + * + * **Note**: Messages that are identical to a message sent in the last 60 ticks are not printed again. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.print View documentation} + * + * @param message + * @param color + */ + print(message: LocalisedString, color?: Color): void + /** + * Creates a deterministic standalone random generator with the given seed or if a seed is not provided the initial + * map seed is used. + * + * **Note**: *Make sure* you actually want to use this over math.random(...) as this provides entirely different + * functionality over math.random(...). + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.create_random_generator View documentation} + * + * @param seed + */ + create_random_generator(seed?: uint): LuaRandomGenerator + /** + * Goes over all items, entities, tiles, recipes, technologies among other things and logs if the locale is incorrect. + * + * **Note**: Also prints true/false if called from the console. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.check_prototype_translations View documentation} + */ + check_prototype_translations(): void + /** + * Play a sound for every player in the game. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.play_sound View documentation} + */ + play_sound(params: { + /** The sound to play. */ + readonly path: SoundPath + /** Where the sound should be played. If not given, it's played at the current position of each player. */ + readonly position?: Position + /** The volume of the sound to play. Must be between 0 and 1 inclusive. */ + readonly volume_modifier?: double + /** The volume mixer to play the sound through. Defaults to the default mixer for the given sound type. */ + readonly override_sound_type?: SoundType + }): void + /** + * Checks if the given SoundPath is valid. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.is_valid_sound_path View documentation} + * + * @param sound_path - Path to the sound. + */ + is_valid_sound_path(sound_path: SoundPath): boolean + /** + * Checks if the given SpritePath is valid and contains a loaded sprite. + * + * **Note**: The existence of the image is not checked for paths of type `file`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.is_valid_sprite_path View documentation} + * + * @param sprite_path - Path to the image. + */ + is_valid_sprite_path(sprite_path: SpritePath): boolean + /** + * Kicks the given player from this multiplayer game. Does nothing if this is a single player game or if the player + * running this isn't an admin. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.kick_player View documentation} + * + * @param player - The player to kick. + * @param reason - The reason given if any. + */ + kick_player(player: PlayerIdentification, reason?: LocalisedString): void + /** + * Bans the given player from this multiplayer game. Does nothing if this is a single player game of if the player + * running this isn't an admin. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.ban_player View documentation} + * + * @param player - The player to ban. + * @param reason - The reason given if any. + */ + ban_player(player: PlayerIdentification, reason?: LocalisedString): void + /** + * Unbans the given player from this multiplayer game. Does nothing if this is a single player game of if the player + * running this isn't an admin. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.unban_player View documentation} + * + * @param player - The player to unban. + */ + unban_player(player: PlayerIdentification): void + /** + * Purges the given players messages from the game. Does nothing if the player running this isn't an admin. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.purge_player View documentation} + * + * @param player - The player to purge. + */ + purge_player(player: PlayerIdentification): void + /** + * Mutes the given player. Does nothing if the player running this isn't an admin. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.mute_player View documentation} + * + * @param player - The player to mute. + */ + mute_player(player: PlayerIdentification): void + /** + * Unmutes the given player. Does nothing if the player running this isn't an admin. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.unmute_player View documentation} + * + * @param player - The player to unmute. + */ + unmute_player(player: PlayerIdentification): void + /** + * Counts how many distinct groups of pipes exist in the world. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.count_pipe_groups View documentation} + */ + count_pipe_groups(): void + /** + * Is the map loaded is multiplayer? + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.is_multiplayer View documentation} + */ + is_multiplayer(): boolean + /** + * Gets the number of entities that are active (updated each tick). + * + * **Note**: This is very expensive to calculate. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_active_entities_count View documentation} + * + * @param surface - If give, only the entities active on this surface are counted. + */ + get_active_entities_count(surface?: SurfaceIdentification): uint + /** + * Gets the map exchange string for the map generation settings that were used to create this map. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_map_exchange_string View documentation} + */ + get_map_exchange_string(): string + /** + * Convert a map exchange string to map gen settings and map settings. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.parse_map_exchange_string View documentation} + * + * @param map_exchange_string + */ + parse_map_exchange_string(map_exchange_string: string): MapExchangeStringData + /** + * Gets train stops matching the given filters. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_train_stops View documentation} + */ + get_train_stops(params?: { + readonly name?: string | string[] + readonly surface?: SurfaceIdentification + readonly force?: ForceIdentification + }): LuaEntity[] + /** + * Gets the given player or returns `nil` if no player is found. + * + * **Note**: This is a shortcut for game.players[...] + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_player View documentation} + * + * @param player - The player index or name. + */ + get_player(player: uint | string): LuaPlayer | undefined + /** + * Gets the given surface or returns `nil` if no surface is found. + * + * **Note**: This is a shortcut for game.surfaces[...] + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_surface View documentation} + * + * @param surface - The surface index or name. + */ + get_surface(surface: uint | string): LuaSurface | undefined + /** + * Creates a {@link LuaProfiler}, which is used for measuring script performance. + * + * **Note**: LuaProfiler cannot be serialized. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.create_profiler View documentation} + * + * @param stopped - Create the timer stopped + */ + create_profiler(stopped?: boolean): LuaProfiler + /** + * Evaluate an expression, substituting variables as provided. For details on the formula, see the relevant page on + * the {@link https://wiki.factorio.com/Prototype/Technology#unit Factorio wiki}. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.evaluate_expression View documentation} + * + * @example + * Calculate the number of research units required to unlock mining productivity level 10. + * + * ```lua + * local formula = game.forces["player"].technologies["mining-productivity-4"].research_unit_count_formula + * local units = game.evaluate_expression(formula, { L = 10, l = 10 }) + * ``` + * + * @param expression - The expression to evaluate. + * @param variables - Variables to be substituted. + */ + evaluate_expression(expression: string, variables?: Record): double + /** + * Returns a dictionary of all LuaEntityPrototypes that fit the given filters. The prototypes are indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_entity_prototypes View documentation} + * + * @example + * Get every entity prototype that can craft recipes involving fluids in the way some assembling machines can. + * + * ```lua + * local prototypes = game.get_filtered_entity_prototypes{{filter="crafting-category", crafting_category="crafting-with-fluid"}} + * ``` + * + * @param filters + */ + get_filtered_entity_prototypes(filters: EntityPrototypeFilter[]): LuaCustomTable + /** + * Returns a dictionary of all LuaItemPrototypes that fit the given filters. The prototypes are indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_item_prototypes View documentation} + * + * @example + * Get every item prototype that, when launched with a rocket, produces a result. + * + * ```lua + * local prototypes = game.get_filtered_item_prototypes{{filter="has-rocket-launch-products"}} + * ``` + * + * @param filters + */ + get_filtered_item_prototypes(filters: ItemPrototypeFilter[]): LuaCustomTable + /** + * Returns a dictionary of all LuaEquipmentPrototypes that fit the given filters. The prototypes are indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_equipment_prototypes View documentation} + * + * @example + * Get every equipment prototype that functions as a battery. + * + * ```lua + * local prototypes = game.get_filtered_equipment_prototypes{{filter="type", type="battery-equipment"}} + * ``` + * + * @param filters + */ + get_filtered_equipment_prototypes(filters: EquipmentPrototypeFilter[]): LuaCustomTable + /** + * Returns a dictionary of all LuaModSettingPrototypes that fit the given filters. The prototypes are indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_mod_setting_prototypes View documentation} + * + * @example + * Get every mod setting prototype that belongs to the specified mod. + * + * ```lua + * local prototypes = game.get_filtered_mod_setting_prototypes{{filter="mod", mod="space-exploration"}} + * ``` + * + * @param filters + */ + get_filtered_mod_setting_prototypes( + filters: ModSettingPrototypeFilter[] + ): LuaCustomTable + /** + * Returns a dictionary of all LuaAchievementPrototypes that fit the given filters. The prototypes are indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_achievement_prototypes View documentation} + * + * @example + * Get every achievement prototype that is not allowed to be completed on the peaceful difficulty setting. + * + * ```lua + * local prototypes = game.get_filtered_achievement_prototypes{{filter="allowed-without-fight", invert=true}} + * ``` + * + * @param filters + */ + get_filtered_achievement_prototypes( + filters: AchievementPrototypeFilter[] + ): LuaCustomTable + /** + * Returns a dictionary of all LuaTilePrototypes that fit the given filters. The prototypes are indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_tile_prototypes View documentation} + * + * @example + * Get every tile prototype that improves a player's walking speed by at least 50%. + * + * ```lua + * local prototypes = game.get_filtered_tile_prototypes{{filter="walking-speed-modifier", comparison="≥", value=1.5}} + * ``` + * + * @param filters + */ + get_filtered_tile_prototypes(filters: TilePrototypeFilter[]): LuaCustomTable + /** + * Returns a dictionary of all LuaDecorativePrototypes that fit the given filters. The prototypes are indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_decorative_prototypes View documentation} + * + * @example + * Get every decorative prototype that is auto-placed. + * + * ```lua + * local prototypes = game.get_filtered_decorative_prototypes{{filter="autoplace"}} + * ``` + * + * @param filters + */ + get_filtered_decorative_prototypes( + filters: DecorativePrototypeFilter[] + ): LuaCustomTable + /** + * Returns a dictionary of all LuaFluidPrototypes that fit the given filters. The prototypes are indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_fluid_prototypes View documentation} + * + * @example + * Get every fluid prototype that has a heat capacity of exactly `100`. + * + * ```lua + * local prototypes = game.get_filtered_fluid_prototypes{{filter="heat-capacity", comparison="=", value=100}} + * ``` + * + * @param filters + */ + get_filtered_fluid_prototypes(filters: FluidPrototypeFilter[]): LuaCustomTable + /** + * Returns a dictionary of all LuaRecipePrototypes that fit the given filters. The prototypes are indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_recipe_prototypes View documentation} + * + * @example + * Get every recipe prototype that takes less than half a second to craft (at crafting speed `1`). + * + * ```lua + * local prototypes = game.get_filtered_recipe_prototypes{{filter="energy", comparison="<", value=0.5}} + * ``` + * + * @param filters + */ + get_filtered_recipe_prototypes(filters: RecipePrototypeFilter[]): LuaCustomTable + /** + * Returns a dictionary of all LuaTechnologyPrototypes that fit the given filters. The prototypes are indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_filtered_technology_prototypes View documentation} + * + * @example + * Get every technology prototype that can be researched at the start of the game. + * + * ```lua + * local prototypes = game.get_filtered_technology_prototypes{{filter="has-prerequisites", invert=true}} + * ``` + * + * @param filters + */ + get_filtered_technology_prototypes( + filters: TechnologyPrototypeFilter[] + ): LuaCustomTable + /** + * Creates an inventory that is not owned by any game object. It can be resized later with + * {@link LuaInventory.resize LuaInventory::resize}. + * + * **Note**: Make sure to destroy it when you are done with it with {@link LuaInventory.destroy LuaInventory::destroy}. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.create_inventory View documentation} + * + * @param size - The number of slots the inventory initially has. + */ + create_inventory(size: uint16): LuaInventory + /** + * Gets the inventories created through {@link LuaGameScript.create_inventory LuaGameScript::create_inventory} + * + * **Note**: Inventories created through console commands will be owned by `"core"`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.get_script_inventories View documentation} + * + * @param mod - The mod who's inventories to get. If not provided all inventories are returned. + * @returns A mapping of mod name to array of inventories owned by that mod. + */ + get_script_inventories(mod?: string): Record + /** + * Resets the amount of time played for this map. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.reset_time_played View documentation} + */ + reset_time_played(): void + /** + * Deflates and base64 encodes the given string. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.encode_string View documentation} + * + * @param string - The string to encode. + * @returns The encoded string or `nil` if the encode failed. + */ + encode_string(string: string): string | undefined + /** + * Base64 decodes and inflates the given string. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.decode_string View documentation} + * + * @param string - The string to decode. + * @returns The decoded string or `nil` if the decode failed. + */ + decode_string(string: string): string | undefined + /** + * The player typing at the console - `nil` in all other instances. See + * {@link LuaGameScript.players LuaGameScript::players} for accessing all players. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.player View documentation} + */ + readonly player: LuaPlayer | undefined + /** + * Get a table of all the players that currently exist. This sparse table allows you to find players by indexing it + * with either their `name` or `index`. Iterating this table with `pairs()` will only iterate the array part of the + * table. Iterating with `ipairs()` will not work at all. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.players View documentation} + */ + readonly players: LuaCustomTable + /** + * The currently active set of map settings. Even though this property is marked as read-only, the members of the + * dictionary that is returned can be modified mid-game. + * + * **Note**: This does not contain difficulty settings, use + * {@link LuaGameScript.difficulty_settings LuaGameScript::difficulty_settings} instead. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.map_settings View documentation} + */ + readonly map_settings: MapSettings + /** + * The currently active set of difficulty settings. Even though this property is marked as read-only, the members of + * the dictionary that is returned can be modified mid-game. This is however not recommended as different + * difficulties can have differing technology and recipe trees, which can cause problems for players. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.difficulty_settings View documentation} + * + * @example + * This will set the technology price multiplier to 12. + * + * ```lua + * game.difficulty_settings.technology_price_multiplier = 12 + * ``` + */ + readonly difficulty_settings: DifficultySettings + /** + * Current scenario difficulty. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.difficulty View documentation} + */ + readonly difficulty: defines.difficulty + /** + * Get a table of all the forces that currently exist. This sparse table allows you to find forces by indexing it + * with either their `name` or `index`. Iterating this table with `pairs()` will only iterate the array part of the + * table. Iterating with `ipairs()` will not work at all. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.forces View documentation} + */ + readonly forces: LuaCustomTable + /** + * A dictionary containing every LuaEntityPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.entity_prototypes View documentation} + */ + readonly entity_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaItemPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.item_prototypes View documentation} + */ + readonly item_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaFluidPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.fluid_prototypes View documentation} + */ + readonly fluid_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaTilePrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.tile_prototypes View documentation} + */ + readonly tile_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaEquipmentPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.equipment_prototypes View documentation} + */ + readonly equipment_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaDamagePrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.damage_prototypes View documentation} + */ + readonly damage_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaVirtualSignalPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.virtual_signal_prototypes View documentation} + */ + readonly virtual_signal_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaEquipmentGridPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.equipment_grid_prototypes View documentation} + */ + readonly equipment_grid_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaRecipePrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.recipe_prototypes View documentation} + */ + readonly recipe_prototypes: LuaCustomTable + /** + * A dictionary containing every {@link LuaTechnologyPrototype} indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.technology_prototypes View documentation} + */ + readonly technology_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaDecorativePrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.decorative_prototypes View documentation} + */ + readonly decorative_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaParticlePrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.particle_prototypes View documentation} + */ + readonly particle_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaAutoplaceControlPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.autoplace_control_prototypes View documentation} + */ + readonly autoplace_control_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaNoiseLayerPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.noise_layer_prototypes View documentation} + */ + readonly noise_layer_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaModSettingPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.mod_setting_prototypes View documentation} + */ + readonly mod_setting_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaCustomInputPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.custom_input_prototypes View documentation} + */ + readonly custom_input_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaAmmoCategoryPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.ammo_category_prototypes View documentation} + */ + readonly ammo_category_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaNamedNoiseExpression indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.named_noise_expressions View documentation} + */ + readonly named_noise_expressions: LuaCustomTable + /** + * A dictionary containing every ItemSubgroup indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.item_subgroup_prototypes View documentation} + */ + readonly item_subgroup_prototypes: LuaCustomTable + /** + * A dictionary containing every ItemGroup indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.item_group_prototypes View documentation} + */ + readonly item_group_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaFuelCategoryPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.fuel_category_prototypes View documentation} + */ + readonly fuel_category_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaResourceCategoryPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.resource_category_prototypes View documentation} + */ + readonly resource_category_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaAchievementPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.achievement_prototypes View documentation} + */ + readonly achievement_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaModuleCategoryPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.module_category_prototypes View documentation} + */ + readonly module_category_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaEquipmentCategoryPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.equipment_category_prototypes View documentation} + */ + readonly equipment_category_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaTrivialSmokePrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.trivial_smoke_prototypes View documentation} + */ + readonly trivial_smoke_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaShortcutPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.shortcut_prototypes View documentation} + */ + readonly shortcut_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaRecipeCategoryPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.recipe_category_prototypes View documentation} + */ + readonly recipe_category_prototypes: LuaCustomTable + /** + * A dictionary containing every LuaFontPrototype indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.font_prototypes View documentation} + */ + readonly font_prototypes: LuaCustomTable + /** + * A dictionary containing every MapGenPreset indexed by `name`. + * + * **Note**: A MapGenPreset is an exact copy of the prototype table provided from the data stage. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.map_gen_presets View documentation} + */ + readonly map_gen_presets: LuaCustomTable + /** + * The styles that {@link LuaGuiElement} can use, indexed by `name`. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.styles View documentation} + */ + readonly styles: LuaCustomTable + /** + * Current map tick. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.tick View documentation} + */ + readonly tick: uint + /** + * The number of ticks since this game was 'created'. A game is 'created' either by using "new game" or "new game + * from scenario". + * + * **Note**: This differs over {@link LuaGameScript.tick LuaGameScript::tick} in that making a game from a scenario + * always starts with ticks_played value at 0 even if the scenario has its own level data where the + * {@link LuaGameScript.tick LuaGameScript::tick} is > 0. + * + * **Note**: This value has no relation with {@link LuaGameScript.tick LuaGameScript::tick} and can be completely + * different values. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.ticks_played View documentation} + */ + readonly ticks_played: uint + /** + * If the tick has been paused. This means that entity update has been paused. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.tick_paused View documentation} + */ + tick_paused: boolean + /** + * The number of ticks to be run while the tick is paused. When + * {@link LuaGameScript.tick_paused LuaGameScript::tick_paused} is true, ticks_to_run behaves the following way: + * While this is > 0, the entity update is running normally and this value is decremented every tick. When this + * reaches 0, the game will pause again. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.ticks_to_run View documentation} + */ + ticks_to_run: uint + /** + * Is the scenario finished? + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.finished View documentation} + */ + readonly finished: boolean + /** + * Speed to update the map at. 1.0 is normal speed -- 60 UPS. + * + * **Note**: Minimum value is 0.01. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.speed View documentation} + */ + speed: float + /** + * Get a table of all the surfaces that currently exist. This sparse table allows you to find surfaces by indexing + * it with either their `name` or `index`. Iterating this table with `pairs()` will only iterate the array part of + * the table. Iterating with `ipairs()` will not work at all. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.surfaces View documentation} + */ + readonly surfaces: LuaCustomTable + /** + * The active mods versions. The keys are mod names, the values are the versions. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.active_mods View documentation} + * + * @example + * This will print the names and versions of active mods to player p's console. + * + * ```lua + * for name, version in pairs(game.active_mods) do + * p.print(name .. " version " .. version) + * end + * ``` + */ + readonly active_mods: Record + /** + * The players that are currently online. + * + * This is primarily useful when you want to do some action against all online players. + * + * **Note**: This does *not* index using player index. See {@link LuaPlayer.index LuaPlayer::index} on each player + * instance for the player index. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.connected_players View documentation} + */ + readonly connected_players: LuaPlayer[] + readonly permissions: LuaPermissionGroups + /** + * Array of the names of all the backers that supported the game development early on. These are used as names for + * labs, locomotives, radars, roboports, and train stops. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.backer_names View documentation} + */ + readonly backer_names: LuaCustomTable + /** + * The default map gen settings for this save. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.default_map_gen_settings View documentation} + */ + readonly default_map_gen_settings: MapGenSettings + /** + * Determines if enemy land mines are completely invisible or not. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.enemy_has_vision_on_land_mines View documentation} + */ + enemy_has_vision_on_land_mines: boolean + /** + * True by default. Can be used to disable autosaving. Make sure to turn it back on soon after. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.autosave_enabled View documentation} + */ + autosave_enabled: boolean + /** + * True by default. Can be used to disable the highlighting of resource patches when they are hovered on the map. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.draw_resource_selection View documentation} + */ + draw_resource_selection: boolean + /** + * The pollution statistics for this map. + * + * {@link https://lua-api.factorio.com/next/LuaGameScript.html#LuaGameScript.pollution_statistics View documentation} + */ + readonly pollution_statistics: LuaFlowStatistics + readonly max_force_distraction_distance: double + readonly max_force_distraction_chunk_distance: uint + readonly max_electric_pole_supply_area_distance: float + readonly max_electric_pole_connection_distance: double + readonly max_beacon_supply_area_distance: double + readonly max_gate_activation_distance: double + readonly max_inserter_reach_distance: double + readonly max_pipe_to_ground_distance: uint8 + readonly max_underground_belt_distance: uint8 + /** This object's name. */ + readonly object_name: "LuaGameScript" +} + +/** + * An abstract base class for behaviors that support switching the entity on or off based on some condition. + * + * {@link https://lua-api.factorio.com/next/LuaGenericOnOffControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaGenericOnOffControlBehavior extends LuaControlBehavior { + /** + * If the entity is currently disabled because of the control behavior. + * + * {@link https://lua-api.factorio.com/next/LuaGenericOnOffControlBehavior.html#LuaGenericOnOffControlBehavior.disabled View documentation} + */ + readonly disabled: boolean + /** + * The circuit condition. + * + * **Note**: `condition` may be `nil` in order to clear the circuit condition. + * + * {@link https://lua-api.factorio.com/next/LuaGenericOnOffControlBehavior.html#LuaGenericOnOffControlBehavior.circuit_condition View documentation} + * + * @example + * Tell an entity to be active (e.g. a lamp to be lit) when it receives a circuit signal of more than 4 chain signals. + * + * ```lua + * a_behavior.circuit_condition = {condition={comparator=">", + * first_signal={type="item", name="rail-chain-signal"}, + * constant=4}} + * ``` + */ + circuit_condition: CircuitConditionDefinition + /** + * The logistic condition. + * + * **Note**: `condition` may be `nil` in order to clear the logistic condition. + * + * {@link https://lua-api.factorio.com/next/LuaGenericOnOffControlBehavior.html#LuaGenericOnOffControlBehavior.logistic_condition View documentation} + * + * @example + * Tell an entity to be active (e.g. a lamp to be lit) when the logistics network it's connected to has more than four chain signals. + * + * ```lua + * a_behavior.logistic_condition = {condition={comparator=">", + * first_signal={type="item", name="rail-chain-signal"}, + * constant=4}} + * ``` + */ + logistic_condition: CircuitConditionDefinition + /** + * `true` if this should connect to the logistic network. + * + * {@link https://lua-api.factorio.com/next/LuaGenericOnOffControlBehavior.html#LuaGenericOnOffControlBehavior.connect_to_logistic_network View documentation} + */ + connect_to_logistic_network: boolean + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: string + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Item group or subgroup. + * + * {@link https://lua-api.factorio.com/next/LuaGroup.html View documentation} + * + * @noSelf + */ +interface LuaGroup { + readonly name: string + /** + * Localised name of the group. + * + * {@link https://lua-api.factorio.com/next/LuaGroup.html#LuaGroup.localised_name View documentation} + */ + readonly localised_name: LocalisedString + readonly type: string + /** + * The parent group if any; `nil` if none. + * + * {@link https://lua-api.factorio.com/next/LuaGroup.html#LuaGroup.group View documentation} + */ + readonly group: LuaGroup | undefined + /** + * Subgroups of this group. + * + * **Note**: Can only be used on groups, not on subgroups. + * + * {@link https://lua-api.factorio.com/next/LuaGroup.html#LuaGroup.subgroups View documentation} + */ + readonly subgroups: LuaGroup[] + /** + * The additional order value used in recipe ordering. + * + * **Note**: Can only be used on groups, not on subgroups. + * + * {@link https://lua-api.factorio.com/next/LuaGroup.html#LuaGroup.order_in_recipe View documentation} + */ + readonly order_in_recipe: string + readonly order: string + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaGroup" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * The root of the GUI. This type houses the root elements, `top`, `left`, `center`, `goal`, and `screen`, to which + * other elements can be added to be displayed on screen. + * + * **Note**: Every player can have a different GUI state. + * + * {@link https://lua-api.factorio.com/next/LuaGui.html View documentation} + * + * @noSelf + */ +interface LuaGui { + /** + * Returns `true` if sprite_path is valid and contains loaded sprite, otherwise `false`. Sprite path of type `file` + * doesn't validate if file exists. + * + * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.is_valid_sprite_path View documentation} + * + * @param sprite_path - Path to a image. + */ + is_valid_sprite_path(sprite_path: SpritePath): boolean + /** + * The player who owns this gui. + * + * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.player View documentation} + */ + readonly player: LuaPlayer + /** + * The children GUI elements mapped by name <> element. + * + * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.children View documentation} + */ + readonly children: Record + /** + * The top part of the GUI. It is a flow element inside a scroll pane element. + * + * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.top View documentation} + */ + readonly top: LuaGuiElement + /** + * The left part of the GUI. It is a flow element inside a scroll pane element. + * + * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.left View documentation} + */ + readonly left: LuaGuiElement + /** + * The center part of the GUI. It is a flow element. + * + * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.center View documentation} + */ + readonly center: LuaGuiElement + /** + * The flow used in the objectives window. It is a flow element. The objectives window is only visible when the flow + * is not empty or the objective text is set. + * + * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.goal View documentation} + */ + readonly goal: LuaGuiElement + /** + * For showing a GUI somewhere on the entire screen. It is an empty-widget element. + * + * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.screen View documentation} + */ + readonly screen: LuaGuiElement + /** + * For showing a GUI somewhere relative to one of the game GUIs. It is an empty-widget element. + * + * {@link https://lua-api.factorio.com/next/LuaGui.html#LuaGui.relative View documentation} + */ + readonly relative: LuaGuiElement + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaGui" + /** All methods and properties that this object supports. */ + help(): string +} + +type GuiElementType = + | "choose-elem-button" + | "drop-down" + | "empty-widget" + | "entity-preview" + | "list-box" + | "scroll-pane" + | "sprite-button" + | "tabbed-pane" + | "text-box" + | "button" + | "camera" + | "checkbox" + | "flow" + | "frame" + | "label" + | "line" + | "minimap" + | "progressbar" + | "radiobutton" + | "slider" + | "sprite" + | "switch" + | "tab" + | "table" + | "textfield" + +interface BaseGuiSpec { + /** The kind of element to add. Has to be one of the GUI element types listed at the top of this page. */ + readonly type: GuiElementType + /** Name of the child element. */ + readonly name?: string + /** + * Text displayed on the child element. For frames, this is their title. For other elements, like buttons or labels, + * this is the content. Whilst this attribute may be used on all elements, it doesn't make sense for tables and + * flows as they won't display it. + */ + readonly caption?: LocalisedString + /** Tooltip of the child element. */ + readonly tooltip?: LocalisedString + /** Whether the child element is enabled. Defaults to `true`. */ + readonly enabled?: boolean + /** Whether the child element is visible. Defaults to `true`. */ + readonly visible?: boolean + /** Whether the child element is ignored by interaction. Defaults to `false`. */ + readonly ignored_by_interaction?: boolean + /** Style of the child element. */ + readonly style?: string + /** {@link Tags} associated with the child element. */ + readonly tags?: Tags + /** Location in its parent that the child element should slot into. By default, the child will be appended onto the end. */ + readonly index?: uint + /** Where to position the child element when in the `relative` element. */ + readonly anchor?: GuiAnchor +} + +interface ButtonGuiSpec extends BaseGuiSpec { + readonly type: "button" + /** Which mouse buttons the button responds to. Defaults to `"left-and-right"`. */ + readonly mouse_button_filter?: MouseButtonFlags +} + +interface FlowGuiSpec extends BaseGuiSpec { + readonly type: "flow" + /** + * The initial direction of the flow's layout. See {@link LuaGuiElement.direction LuaGuiElement::direction}. Defaults + * to `"horizontal"`. + */ + readonly direction?: "horizontal" | "vertical" +} + +interface FrameGuiSpec extends BaseGuiSpec { + readonly type: "frame" + /** + * The initial direction of the frame's layout. See {@link LuaGuiElement.direction LuaGuiElement::direction}. + * Defaults to `"horizontal"`. + */ + readonly direction?: "horizontal" | "vertical" +} + +interface TableGuiSpec extends BaseGuiSpec { + readonly type: "table" + /** Number of columns. This can't be changed after the table is created. */ + readonly column_count: uint + /** Whether the table should draw vertical grid lines. Defaults to `false`. */ + readonly draw_vertical_lines?: boolean + /** Whether the table should draw horizontal grid lines. Defaults to `false`. */ + readonly draw_horizontal_lines?: boolean + /** Whether the table should draw a single horizontal grid line after the headers. Defaults to `false`. */ + readonly draw_horizontal_line_after_headers?: boolean + /** Whether the content of the table should be vertically centered. Defaults to `true`. */ + readonly vertical_centering?: boolean +} + +interface TextfieldGuiSpec extends BaseGuiSpec { + readonly type: "textfield" + /** The initial text contained in the textfield. */ + readonly text?: string + /** Defaults to `false`. */ + readonly numeric?: boolean + /** Defaults to `false`. */ + readonly allow_decimal?: boolean + /** Defaults to `false`. */ + readonly allow_negative?: boolean + /** Defaults to `false`. */ + readonly is_password?: boolean + /** Defaults to `false`. */ + readonly lose_focus_on_confirm?: boolean + /** Defaults to `false`. */ + readonly clear_and_focus_on_right_click?: boolean +} + +interface ProgressbarGuiSpec extends BaseGuiSpec { + readonly type: "progressbar" + /** The initial value of the progressbar, in the range [0, 1]. Defaults to `0`. */ + readonly value?: double +} + +interface CheckboxGuiSpec extends BaseGuiSpec { + readonly type: "checkbox" + /** The initial checked-state of the checkbox. */ + readonly state: boolean +} + +interface RadiobuttonGuiSpec extends BaseGuiSpec { + readonly type: "radiobutton" + /** The initial checked-state of the radiobutton. */ + readonly state: boolean +} + +interface SpriteButtonGuiSpec extends BaseGuiSpec { + readonly type: "sprite-button" + /** Path to the image to display on the button. */ + readonly sprite?: SpritePath + /** Path to the image to display on the button when it is hovered. */ + readonly hovered_sprite?: SpritePath + /** Path to the image to display on the button when it is clicked. */ + readonly clicked_sprite?: SpritePath + /** The number shown on the button. */ + readonly number?: double + /** Formats small numbers as percentages. Defaults to `false`. */ + readonly show_percent_for_small_numbers?: boolean + /** The mouse buttons that the button responds to. Defaults to `"left-and-right"`. */ + readonly mouse_button_filter?: MouseButtonFlags +} + +interface SpriteGuiSpec extends BaseGuiSpec { + readonly type: "sprite" + /** Path to the image to display. */ + readonly sprite?: SpritePath + /** Whether the widget should resize according to the sprite in it. Defaults to `true`. */ + readonly resize_to_sprite?: boolean +} + +interface ScrollPaneGuiSpec extends BaseGuiSpec { + readonly type: "scroll-pane" + /** + * Policy of the horizontal scroll bar. Possible values are `"auto"`, `"never"`, `"always"`, + * `"auto-and-reserve-space"`, `"dont-show-but-allow-scrolling"`. Defaults to `"auto"`. + */ + readonly horizontal_scroll_policy?: + | "auto" + | "never" + | "always" + | "auto-and-reserve-space" + | "dont-show-but-allow-scrolling" + /** + * Policy of the vertical scroll bar. Possible values are `"auto"`, `"never"`, `"always"`, + * `"auto-and-reserve-space"`, `"dont-show-but-allow-scrolling"`. Defaults to `"auto"`. + */ + readonly vertical_scroll_policy?: + | "auto" + | "never" + | "always" + | "auto-and-reserve-space" + | "dont-show-but-allow-scrolling" +} + +interface DropDownGuiSpec extends BaseGuiSpec { + readonly type: "drop-down" + /** The initial items in the dropdown. */ + readonly items?: LocalisedString[] + /** The index of the initially selected item. Defaults to 0. */ + readonly selected_index?: uint +} + +interface LineGuiSpec extends BaseGuiSpec { + readonly type: "line" + /** The initial direction of the line. Defaults to `"horizontal"`. */ + readonly direction?: "horizontal" | "vertical" +} + +interface ListBoxGuiSpec extends BaseGuiSpec { + readonly type: "list-box" + /** The initial items in the listbox. */ + readonly items?: LocalisedString[] + /** The index of the initially selected item. Defaults to 0. */ + readonly selected_index?: uint +} + +interface CameraGuiSpec extends BaseGuiSpec { + readonly type: "camera" + /** The position the camera centers on. */ + readonly position: Position + /** The surface that the camera will render. Defaults to the player's current surface. */ + readonly surface_index?: uint + /** The initial camera zoom. Defaults to `0.75`. */ + readonly zoom?: double +} + +type ChooseElemButtonType = + | "item" + | "tile" + | "entity" + | "signal" + | "fluid" + | "recipe" + | "decorative" + | "item-group" + | "achievement" + | "equipment" + | "technology" + +interface ChooseElemButtonFilters { + item: ItemPrototypeFilter[] + tile: TilePrototypeFilter[] + entity: EntityPrototypeFilter[] + signal: never + fluid: FluidPrototypeFilter[] + recipe: RecipePrototypeFilter[] + decorative: DecorativePrototypeFilter[] + "item-group": never + achievement: AchievementPrototypeFilter[] + equipment: EquipmentPrototypeFilter[] + technology: TechnologyPrototypeFilter[] +} + +interface BaseChooseElemButtonSpec extends BaseGuiSpec { + readonly type: "choose-elem-button" + /** The type of the button - one of the following values. */ + readonly elem_type: ChooseElemButtonType + /** Filters describing what to show in the selection window. See {@link LuaGuiElement.elem_filters LuaGuiElement::elem_filters}. */ + readonly filters?: ChooseElemButtonFilters[this["elem_type"]] +} + +interface ItemChooseElemButtonSpec extends BaseChooseElemButtonSpec { + readonly elem_type: "item" + /** If type is `"item"` - the default value for the button. */ + readonly item?: string +} + +interface TileChooseElemButtonSpec extends BaseChooseElemButtonSpec { + readonly elem_type: "tile" + /** If type is `"tile"` - the default value for the button. */ + readonly tile?: string +} + +interface EntityChooseElemButtonSpec extends BaseChooseElemButtonSpec { + readonly elem_type: "entity" + /** If type is `"entity"` - the default value for the button. */ + readonly entity?: string +} + +interface SignalChooseElemButtonSpec extends BaseChooseElemButtonSpec { + readonly elem_type: "signal" + /** If type is `"signal"` - the default value for the button. */ + readonly signal?: SignalID +} + +interface FluidChooseElemButtonSpec extends BaseChooseElemButtonSpec { + readonly elem_type: "fluid" + /** If type is `"fluid"` - the default value for the button. */ + readonly fluid?: string +} + +interface RecipeChooseElemButtonSpec extends BaseChooseElemButtonSpec { + readonly elem_type: "recipe" + /** If type is `"recipe"` - the default value for the button. */ + readonly recipe?: string +} + +interface DecorativeChooseElemButtonSpec extends BaseChooseElemButtonSpec { + readonly elem_type: "decorative" + /** If type is `"decorative"` - the default value for the button. */ + readonly decorative?: string +} + +interface ItemGroupChooseElemButtonSpec extends BaseChooseElemButtonSpec { + readonly elem_type: "item-group" + /** If type is `"item-group"` - the default value for the button. */ + readonly "item-group"?: string +} + +interface AchievementChooseElemButtonSpec extends BaseChooseElemButtonSpec { + readonly elem_type: "achievement" + /** If type is `"achievement"` - the default value for the button. */ + readonly achievement?: string +} + +interface EquipmentChooseElemButtonSpec extends BaseChooseElemButtonSpec { + readonly elem_type: "equipment" + /** If type is `"equipment"` - the default value for the button. */ + readonly equipment?: string +} + +interface TechnologyChooseElemButtonSpec extends BaseChooseElemButtonSpec { + readonly elem_type: "technology" + /** If type is `"technology"` - the default value for the button. */ + readonly technology?: string +} + +type ChooseElemButtonGuiSpec = + | ItemChooseElemButtonSpec + | TileChooseElemButtonSpec + | EntityChooseElemButtonSpec + | SignalChooseElemButtonSpec + | FluidChooseElemButtonSpec + | RecipeChooseElemButtonSpec + | DecorativeChooseElemButtonSpec + | ItemGroupChooseElemButtonSpec + | AchievementChooseElemButtonSpec + | EquipmentChooseElemButtonSpec + | TechnologyChooseElemButtonSpec + +interface TextBoxGuiSpec extends BaseGuiSpec { + readonly type: "text-box" + /** The initial text contained in the text-box. */ + readonly text?: string + /** Defaults to `false`. */ + readonly clear_and_focus_on_right_click?: boolean +} + +interface SliderGuiSpec extends BaseGuiSpec { + readonly type: "slider" + /** The minimum value for the slider. Defaults to `0`. */ + readonly minimum_value?: double + /** The maximum value for the slider. Defaults to `30`. */ + readonly maximum_value?: double + /** The initial value for the slider. Defaults to `minimum_value`. */ + readonly value?: double + /** The minimum value the slider can move. Defaults to `1`. */ + readonly value_step?: double + /** Defaults to `false`. */ + readonly discrete_slider?: boolean + /** Defaults to `true`. */ + readonly discrete_values?: boolean +} + +interface MinimapGuiSpec extends BaseGuiSpec { + readonly type: "minimap" + /** The position the minimap centers on. Defaults to the player's current position. */ + readonly position?: Position + /** The surface the camera will render. Defaults to the player's current surface. */ + readonly surface_index?: uint + /** The player index the map should use. Defaults to the current player. */ + readonly chart_player_index?: uint + /** The force this minimap should use. Defaults to the player's current force. */ + readonly force?: string + /** The initial camera zoom. Defaults to `0.75`. */ + readonly zoom?: double +} + +interface TabGuiSpec extends BaseGuiSpec { + readonly type: "tab" + /** The text to display after the normal tab text (designed to work with numbers). */ + readonly badge_text?: LocalisedString +} + +interface SwitchGuiSpec extends BaseGuiSpec { + readonly type: "switch" + /** + * Possible values are `"left"`, `"right"`, or `"none"`. If set to "none", `allow_none_state` must be `true`. + * Defaults to `"left"`. + */ + readonly switch_state?: "left" | "right" | "none" + /** Whether the switch can be set to a middle state. Defaults to `false`. */ + readonly allow_none_state?: boolean + readonly left_label_caption?: LocalisedString + readonly left_label_tooltip?: LocalisedString + readonly right_label_caption?: LocalisedString + readonly right_label_tooltip?: LocalisedString +} + +interface OtherGuiSpec extends BaseGuiSpec { + readonly type: "empty-widget" | "entity-preview" | "tabbed-pane" | "label" +} + +type GuiSpec = + | ButtonGuiSpec + | FlowGuiSpec + | FrameGuiSpec + | TableGuiSpec + | TextfieldGuiSpec + | ProgressbarGuiSpec + | CheckboxGuiSpec + | RadiobuttonGuiSpec + | SpriteButtonGuiSpec + | SpriteGuiSpec + | ScrollPaneGuiSpec + | DropDownGuiSpec + | LineGuiSpec + | ListBoxGuiSpec + | CameraGuiSpec + | ChooseElemButtonGuiSpec + | TextBoxGuiSpec + | SliderGuiSpec + | MinimapGuiSpec + | TabGuiSpec + | SwitchGuiSpec + | OtherGuiSpec + +interface GuiElementIndex { + /** + * The indexing operator. Gets children by name. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.operator%20[] View documentation} + */ + readonly [name: string]: LuaGuiElement | undefined +} + +/** @noSelf */ +interface BaseGuiElement { + /** + * Add a new child element to this GuiElement. + * + * Other attributes may be specified depending on `type`: + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.add View documentation} + * + * @returns The added GUI element. + */ + add( + element: GuiSpec & { + type: Type + } + ): Extract< + LuaGuiElement, + { + type: Type + } + > + /** + * Remove children of this element. Any {@link LuaGuiElement} objects referring to the destroyed elements become + * invalid after this operation. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.clear View documentation} + * + * @example + * ```lua + * game.player.gui.top.clear() + * ``` + */ + clear(): void + /** + * Remove this element, along with its children. Any {@link LuaGuiElement} objects referring to the destroyed + * elements become invalid after this operation. + * + * **Note**: The top-level GUI elements - {@link LuaGui.top LuaGui::top}, {@link LuaGui.left LuaGui::left}, + * {@link LuaGui.center LuaGui::center} and {@link LuaGui.screen LuaGui::screen} - can't be destroyed. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.destroy View documentation} + * + * @example + * ```lua + * game.player.gui.top.greeting.destroy() + * ``` + */ + destroy(): void + /** + * The mod that owns this Gui element or `nil` if it's owned by the scenario script. + * + * **Note**: This has a not-super-expensive, but non-free cost to get. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.get_mod View documentation} + */ + get_mod(): string | undefined + /** + * Gets the index that this element has in its parent element. + * + * **Note**: This iterates through the children of the parent of this element, meaning this has a non-free cost to + * get, but is faster than doing the equivalent in Lua. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.get_index_in_parent View documentation} + */ + get_index_in_parent(): uint + /** + * Removes the items in this dropdown or listbox. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.clear_items View documentation} + */ + clear_items(): void + /** + * Gets the item at the given index from this dropdown or listbox. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.get_item View documentation} + * + * @param index - The index to get + */ + get_item(index: uint): LocalisedString + /** + * Sets the given string at the given index in this dropdown or listbox. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.set_item View documentation} + * + * @param index - The index whose text to replace. + * @param string - The text to set at the given index. + */ + set_item(index: uint, string: LocalisedString): void + /** + * Inserts a string at the end or at the given index of this dropdown or listbox. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.add_item View documentation} + * + * @param string - The text to insert. + * @param index - The index at which to insert the item. + */ + add_item(string: LocalisedString, index?: uint): void + /** + * Removes the item at the given index from this dropdown or listbox. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.remove_item View documentation} + * + * @param index - The index + */ + remove_item(index: uint): void + /** + * Gets this sliders minimum value. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.get_slider_minimum View documentation} + */ + get_slider_minimum(): double + /** + * Gets this sliders maximum value. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.get_slider_maximum View documentation} + */ + get_slider_maximum(): double + /** + * Sets this sliders minimum and maximum values. + * + * **Note**: The minimum can't be >= the maximum. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.set_slider_minimum_maximum View documentation} + * + * @param minimum + * @param maximum + */ + set_slider_minimum_maximum(minimum: double, maximum: double): void + /** + * Gets the minimum distance this slider can move. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.get_slider_value_step View documentation} + */ + get_slider_value_step(): double + /** + * Returns whether this slider only allows being moved to discrete positions. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.get_slider_discrete_slider View documentation} + */ + get_slider_discrete_slider(): boolean + /** + * Returns whether this slider only allows discrete values. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.get_slider_discrete_values View documentation} + */ + get_slider_discrete_values(): boolean + /** + * Sets the minimum distance this slider can move. + * + * **Note**: The minimum distance can't be > (max - min). + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.set_slider_value_step View documentation} + * + * @param value + */ + set_slider_value_step(value: double): void + /** + * Sets whether this slider only allows being moved to discrete positions. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.set_slider_discrete_slider View documentation} + * + * @param value + */ + set_slider_discrete_slider(value: boolean): void + /** + * Sets whether this slider only allows discrete values. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.set_slider_discrete_values View documentation} + * + * @param value + */ + set_slider_discrete_values(value: boolean): void + /** + * Focuses this GUI element if possible. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.focus View documentation} + */ + focus(): void + /** + * Moves this GUI element to the "front" so it will draw over other elements. + * + * **Note**: Only works for elements in {@link LuaGui.screen LuaGui::screen} + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.bring_to_front View documentation} + */ + bring_to_front(): void + /** + * The index of this GUI element (unique amongst the GUI elements of a LuaPlayer). + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.index View documentation} + */ + readonly index: uint + /** + * The GUI this element is a child of. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.gui View documentation} + */ + readonly gui: LuaGui + /** + * The direct parent of this element; `nil` if this is a top-level element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.parent View documentation} + */ + readonly parent: LuaGuiElement | undefined + /** + * The name of this element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.name View documentation} + * + * @example + * ```lua + * game.player.gui.top.greeting.name == "greeting" + * ``` + */ + name: string + /** + * The text displayed on this element. For frames, this is the "heading". For other elements, like buttons or + * labels, this is the content. + * + * **Note**: Whilst this attribute may be used on all elements without producing an error, it doesn't make sense for + * tables and flows as they won't display it. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.caption View documentation} + */ + caption: LocalisedString + /** + * The style of this element. When read, this evaluates to a {@link LuaStyle}. For writing, it only accepts a string + * that specifies the textual identifier (prototype name) of the desired style. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.style View documentation} + */ + style: LuaStyle | string + /** + * Sets whether this GUI element is visible or completely hidden, taking no space in the layout. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.visible View documentation} + */ + visible: boolean + /** + * Names of all the children of this element. These are the identifiers that can be used to access the child as an + * attribute of this element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.children_names View documentation} + */ + readonly children_names: string[] + /** + * Index into {@link LuaGameScript.players LuaGameScript::players} specifying the player who owns this element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.player_index View documentation} + */ + readonly player_index: uint + /** + * The image to display on this sprite-button or sprite in the default state. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.sprite View documentation} + */ + sprite: SpritePath + /** + * Whether the image widget should resize according to the sprite in it. Defaults to `true`. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.resize_to_sprite View documentation} + */ + resize_to_sprite: boolean + /** + * The image to display on this sprite-button when it is clicked. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.clicked_sprite View documentation} + */ + clicked_sprite: SpritePath + tooltip: LocalisedString + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: GuiElementType + /** + * The child-elements of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.children View documentation} + */ + readonly children: LuaGuiElement[] + /** + * The items in this dropdown or listbox. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.items View documentation} + */ + items: LocalisedString[] + /** + * The selected index for this dropdown or listbox. Returns `0` if none is selected. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.selected_index View documentation} + */ + selected_index: uint + /** + * The number to be shown in the bottom right corner of this sprite-button. Set this to `nil` to show nothing. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.number View documentation} + */ + number: double | undefined + /** + * Related to the number to be shown in the bottom right corner of this sprite-button. When set to `true`, numbers + * that are non-zero and smaller than one are shown as a percentage rather than the value. For example, `0.5` will + * be shown as `50%` instead. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.show_percent_for_small_numbers View documentation} + */ + show_percent_for_small_numbers: boolean + /** + * The location of this widget when stored in {@link LuaGui.screen LuaGui::screen} or `nil` if not not set or not in + * {@link LuaGui.screen LuaGui::screen}. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.location View documentation} + */ + location: GuiLocation | undefined + /** + * The position this camera or minimap is focused on, if any. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.position View documentation} + */ + position: Position + /** + * The surface index this camera or minimap is using. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.surface_index View documentation} + */ + surface_index: uint + /** + * The zoom this camera or minimap is using. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.zoom View documentation} + */ + zoom: double + /** + * The force this minimap is using or `nil` if no force is set. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.force View documentation} + */ + force: string | undefined + /** + * Whether this GUI element is enabled. Disabled GUI elements don't trigger events when clicked. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.enabled View documentation} + */ + enabled: boolean + /** + * Whether this GUI element is ignored by interaction. This makes clicks on this element 'go through' to the GUI + * element or even the game surface below it. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.ignored_by_interaction View documentation} + */ + ignored_by_interaction: boolean + /** + * The mouse button filters for this button or sprite-button. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.mouse_button_filter View documentation} + */ + mouse_button_filter: MouseButtonFlags + /** + * The frame drag target for this flow, frame, label, table, or empty-widget. + * + * **Note**: drag_target can only be set to a frame stored directly in {@link LuaGui.screen LuaGui::screen} or `nil`. + * + * **Note**: drag_target can only be set on child elements in {@link LuaGui.screen LuaGui::screen}. + * + * **Note**: drag_target can only be set to a higher level parent element (this element must be owned at some nested + * level by the drag_target). + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.drag_target View documentation} + */ + drag_target: LuaGuiElement | undefined + /** + * The tabs and contents being shown in this tabbed-pane. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.tabs View documentation} + */ + readonly tabs: TabAndContent[] + /** + * The entity associated with this entity-preview, camera, minimap or `nil` if no entity is associated. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.entity View documentation} + */ + entity: LuaEntity | undefined + /** + * Sets the anchor for this relative widget. Setting `nil` clears the anchor. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.anchor View documentation} + */ + anchor: GuiAnchor | undefined + /** + * The tags associated with this LuaGuiElement. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.tags View documentation} + */ + tags: Tags + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaGuiElement" + /** All methods and properties that this object supports. */ + help(): string +} + +/** @noSelf */ +interface ChooseElemButtonGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "choose-elem-button" + /** + * The elem type of this choose-elem-button. + * + * *Can only be used if this is choose-elem-button* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.elem_type View documentation} + */ + readonly elem_type: ChooseElemButtonType + /** + * The elem value of this choose-elem-button or `nil` if there is no value. + * + * **Note**: The `"signal"` type operates with {@link SignalID}, while all other types use strings. + * + * *Can only be used if this is choose-elem-button* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.elem_value View documentation} + */ + elem_value: (this["elem_type"] extends "signal" ? SignalID : string) | undefined + /** + * The elem filters of this choose-elem-button or `nil` if there are no filters. + * + * The compatible type of filter is determined by elem_type: + * + * - Type `"item"` - {@link ItemPrototypeFilter} + * - Type `"tile"` - {@link TilePrototypeFilter} + * - Type `"entity"` - {@link EntityPrototypeFilter} + * - Type `"signal"` - Does not support filters + * - Type `"fluid"` - {@link FluidPrototypeFilter} + * - Type `"recipe"` - {@link RecipePrototypeFilter} + * - Type `"decorative"` - {@link DecorativePrototypeFilter} + * - Type `"item-group"` - Does not support filters + * - Type `"achievement"` - {@link AchievementPrototypeFilter} + * - Type `"equipment"` - {@link EquipmentPrototypeFilter} + * - Type `"technology"` - {@link TechnologyPrototypeFilter} + * + * **Note**: Writing to this field does not change or clear the currently selected element. + * + * *Can only be used if this is choose-elem-button* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.elem_filters View documentation} + * + * @example + * This will configure a choose-elem-button of type `"entity"` to only show items of type `"furnace"`. + * + * ```lua + * button.elem_filters = {{filter = "type", type = "furnace"}} + * ``` + * + * @example + * Then, there are some types of filters that work on a specific kind of attribute. The following will configure a choose-elem-button of type `"entity"` to only show entities that have their `"hidden"` {@link EntityPrototypeFlags flags} set. + * + * ```lua + * button.elem_filters = {{filter = "hidden"}} + * ``` + * + * @example + * Lastly, these filters can be combined at will, taking care to specify how they should be combined (either `"and"` or `"or"`. The following will filter for any `"entities"` that are `"furnaces"` and that are not `"hidden"`. + * + * ```lua + * button.elem_filters = {{filter = "type", type = "furnace"}, {filter = "hidden", invert = true, mode = "and"}} + * ``` + */ + elem_filters: ChooseElemButtonFilters[this["elem_type"]] | undefined + /** + * Whether this choose-elem-button can be changed by the player. + * + * *Can only be used if this is choose-elem-button* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.locked View documentation} + */ + locked: boolean +} + +type ChooseElemButtonGuiElement = ChooseElemButtonGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface DropDownGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "drop-down" +} + +type DropDownGuiElement = DropDownGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface EmptyWidgetGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "empty-widget" +} + +type EmptyWidgetGuiElement = EmptyWidgetGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface EntityPreviewGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "entity-preview" +} + +type EntityPreviewGuiElement = EntityPreviewGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface ListBoxGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "list-box" + /** + * Scrolls the scroll bar such that the specified listbox item is visible to the player. + * + * *Can only be used if this is list-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_item View documentation} + * + * @param index - The item index to scroll to. + * @param scroll_mode - Where the item should be positioned in the scroll-pane. Must be either `"in-view"` or + * `"top-third"`. Defaults to `"in-view"`. + */ + scroll_to_item(index: int, scroll_mode?: "in-view" | "top-third"): void +} + +type ListBoxGuiElement = ListBoxGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface ScrollPaneGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "scroll-pane" + /** + * Scrolls this scroll bar to the top. + * + * *Can only be used if this is scroll-pane or text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_top View documentation} + */ + scroll_to_top(): void + /** + * Scrolls this scroll bar to the bottom. + * + * *Can only be used if this is scroll-pane or text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_bottom View documentation} + */ + scroll_to_bottom(): void + /** + * Scrolls this scroll bar to the left. + * + * *Can only be used if this is scroll-pane or text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_left View documentation} + */ + scroll_to_left(): void + /** + * Scrolls this scroll bar to the right. + * + * *Can only be used if this is scroll-pane or text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_right View documentation} + */ + scroll_to_right(): void + /** + * Scrolls this scroll bar such that the specified GUI element is visible to the player. + * + * *Can only be used if this is scroll-pane* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_element View documentation} + * + * @param element - The element to scroll to. + * @param scroll_mode - Where the element should be positioned in the scroll-pane. Must be either `"in-view"` or + * `"top-third"`. Defaults to `"in-view"`. + */ + scroll_to_element(element: LuaGuiElement, scroll_mode?: "in-view" | "top-third"): void + /** + * Policy of the horizontal scroll bar. Possible values are `"auto"`, `"never"`, `"always"`, + * `"auto-and-reserve-space"`, `"dont-show-but-allow-scrolling"`. + * + * *Can only be used if this is scroll-pane* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.horizontal_scroll_policy View documentation} + */ + horizontal_scroll_policy: "auto" | "never" | "always" | "auto-and-reserve-space" | "dont-show-but-allow-scrolling" + /** + * Policy of the vertical scroll bar. Possible values are `"auto"`, `"never"`, `"always"`, + * `"auto-and-reserve-space"`, `"dont-show-but-allow-scrolling"`. + * + * *Can only be used if this is scroll-pane* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.vertical_scroll_policy View documentation} + */ + vertical_scroll_policy: "auto" | "never" | "always" | "auto-and-reserve-space" | "dont-show-but-allow-scrolling" +} + +type ScrollPaneGuiElement = ScrollPaneGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface SpriteButtonGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "sprite-button" + /** + * The image to display on this sprite-button when it is hovered. + * + * *Can only be used if this is sprite-button* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.hovered_sprite View documentation} + */ + hovered_sprite: SpritePath +} + +type SpriteButtonGuiElement = SpriteButtonGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface TabbedPaneGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "tabbed-pane" + /** + * Adds the given tab and content widgets to this tabbed pane as a new tab. + * + * *Can only be used if this is tabbed-pane* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.add_tab View documentation} + * + * @param tab - The tab to add, must be a GUI element of type "tab". + * @param content - The content to show when this tab is selected. Can be any type of GUI element. + */ + add_tab(tab: LuaGuiElement, content: LuaGuiElement): void + /** + * Removes the given tab and its associated content from this tabbed pane. + * + * **Note**: Removing a tab does not destroy the tab or the tab contents. It just removes them from the view. + * + * **Note**: When removing tabs, {@link LuaGuiElement.selected_tab_index LuaGuiElement::selected_tab_index} needs to + * be manually updated. + * + * *Can only be used if this is tabbed-pane* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.remove_tab View documentation} + * + * @param tab - The tab to remove. If not given, it removes all tabs. + */ + remove_tab(tab: LuaGuiElement): void + /** + * The selected tab index for this tabbed pane or `nil` if no tab is selected. + * + * *Can only be used if this is tabbed-pane* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.selected_tab_index View documentation} + */ + selected_tab_index: uint | undefined +} + +type TabbedPaneGuiElement = TabbedPaneGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface TextBoxGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "text-box" + /** + * Scrolls this scroll bar to the top. + * + * *Can only be used if this is scroll-pane or text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_top View documentation} + */ + scroll_to_top(): void + /** + * Scrolls this scroll bar to the bottom. + * + * *Can only be used if this is scroll-pane or text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_bottom View documentation} + */ + scroll_to_bottom(): void + /** + * Scrolls this scroll bar to the left. + * + * *Can only be used if this is scroll-pane or text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_left View documentation} + */ + scroll_to_left(): void + /** + * Scrolls this scroll bar to the right. + * + * *Can only be used if this is scroll-pane or text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.scroll_to_right View documentation} + */ + scroll_to_right(): void + /** + * Selects all the text in this textbox. + * + * *Can only be used if this is textfield or text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.select_all View documentation} + */ + select_all(): void + /** + * Selects a range of text in this textbox. + * + * *Can only be used if this is textfield or text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.select View documentation} + * + * @example + * Select the characters `amp` from `example`: + * + * ```lua + * textbox.select(3, 5) + * ``` + * + * @example + * Move the cursor to the start of the text box: + * + * ```lua + * textbox.select(1, 0) + * ``` + * + * @param start - The index of the first character to select + * @param end - The index of the last character to select + */ + select(start: int, end: int): void + /** + * The text contained in this textfield or text-box. + * + * *Can only be used if this is textfield or text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.text View documentation} + */ + text: string + /** + * Whether the contents of this text-box are selectable. Defaults to `true`. + * + * *Can only be used if this is text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.selectable View documentation} + */ + selectable: boolean + /** + * Whether this text-box will word-wrap automatically. Defaults to `false`. + * + * *Can only be used if this is text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.word_wrap View documentation} + */ + word_wrap: boolean + /** + * Whether this text-box is read-only. Defaults to `false`. + * + * *Can only be used if this is text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.read_only View documentation} + */ + read_only: boolean + /** + * Makes it so right-clicking on this textfield clears and focuses it. + * + * *Can only be used if this is textfield or text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.clear_and_focus_on_right_click View documentation} + */ + clear_and_focus_on_right_click: boolean +} + +type TextBoxGuiElement = TextBoxGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface ButtonGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "button" +} + +type ButtonGuiElement = ButtonGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface CameraGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "camera" +} + +type CameraGuiElement = CameraGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface CheckboxGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "checkbox" + /** + * Is this checkbox or radiobutton checked? + * + * *Can only be used if this is CheckBox or RadioButton* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.state View documentation} + */ + state: boolean +} + +type CheckboxGuiElement = CheckboxGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface FlowGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "flow" + /** + * Direction of this element's layout. May be either `"horizontal"` or `"vertical"`. + * + * *Can only be used if this is frame, flow or line* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.direction View documentation} + */ + readonly direction: "horizontal" | "vertical" +} + +type FlowGuiElement = FlowGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface FrameGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "frame" + /** + * Forces this frame to re-auto-center. Only works on frames stored directly in {@link LuaGui.screen LuaGui::screen}. + * + * *Can only be used if this is frame* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.force_auto_center View documentation} + */ + force_auto_center(): void + /** + * Direction of this element's layout. May be either `"horizontal"` or `"vertical"`. + * + * *Can only be used if this is frame, flow or line* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.direction View documentation} + */ + readonly direction: "horizontal" | "vertical" + /** + * Whether this frame auto-centers on window resize when stored in {@link LuaGui.screen LuaGui::screen}. + * + * *Can only be used if this is frame* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.auto_center View documentation} + */ + auto_center: boolean +} + +type FrameGuiElement = FrameGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface LabelGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "label" +} + +type LabelGuiElement = LabelGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface LineGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "line" + /** + * Direction of this element's layout. May be either `"horizontal"` or `"vertical"`. + * + * *Can only be used if this is frame, flow or line* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.direction View documentation} + */ + readonly direction: "horizontal" | "vertical" +} + +type LineGuiElement = LineGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface MinimapGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "minimap" + /** + * The player index this minimap is using. + * + * *Can only be used if this is minimap* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.minimap_player_index View documentation} + */ + minimap_player_index: uint +} + +type MinimapGuiElement = MinimapGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface ProgressbarGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "progressbar" + /** + * How much this progress bar is filled. It is a value in the range [0, 1]. + * + * *Can only be used if this is progressbar* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.value View documentation} + */ + value: double +} + +type ProgressbarGuiElement = ProgressbarGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface RadiobuttonGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "radiobutton" + /** + * Is this checkbox or radiobutton checked? + * + * *Can only be used if this is CheckBox or RadioButton* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.state View documentation} + */ + state: boolean +} + +type RadiobuttonGuiElement = RadiobuttonGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface SliderGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "slider" + /** + * The value of this slider element. + * + * *Can only be used if this is slider* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.slider_value View documentation} + */ + slider_value: double +} + +type SliderGuiElement = SliderGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface SpriteGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "sprite" +} + +type SpriteGuiElement = SpriteGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface SwitchGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "switch" + /** + * The switch state (left, none, right) for this switch. + * + * **Note**: If {@link LuaGuiElement.allow_none_state LuaGuiElement::allow_none_state} is false this can't be set to `"none"`. + * + * *Can only be used if this is switch* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.switch_state View documentation} + */ + switch_state: string + /** + * Whether the `"none"` state is allowed for this switch. + * + * **Note**: This can't be set to false if the current switch_state is 'none'. + * + * *Can only be used if this is switch* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.allow_none_state View documentation} + */ + allow_none_state: boolean + /** + * The text shown for the left switch label. + * + * *Can only be used if this is switch* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.left_label_caption View documentation} + */ + left_label_caption: LocalisedString + /** + * The tooltip shown on the left switch label. + * + * *Can only be used if this is switch* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.left_label_tooltip View documentation} + */ + left_label_tooltip: LocalisedString + /** + * The text shown for the right switch label. + * + * *Can only be used if this is switch* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.right_label_caption View documentation} + */ + right_label_caption: LocalisedString + /** + * The tooltip shown on the right switch label. + * + * *Can only be used if this is switch* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.right_label_tooltip View documentation} + */ + right_label_tooltip: LocalisedString +} + +type SwitchGuiElement = SwitchGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface TabGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "tab" + /** + * The text to display after the normal tab text (designed to work with numbers) + * + * *Can only be used if this is tab* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.badge_text View documentation} + */ + badge_text: LocalisedString +} + +type TabGuiElement = TabGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface TableGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "table" + /** + * Whether this table should draw vertical grid lines. + * + * *Can only be used if this is table* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.draw_vertical_lines View documentation} + */ + draw_vertical_lines: boolean + /** + * Whether this table should draw horizontal grid lines. + * + * *Can only be used if this is table* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.draw_horizontal_lines View documentation} + */ + draw_horizontal_lines: boolean + /** + * Whether this table should draw a horizontal grid line below the first table row. + * + * *Can only be used if this is table* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.draw_horizontal_line_after_headers View documentation} + */ + draw_horizontal_line_after_headers: boolean + /** + * The number of columns in this table. + * + * *Can only be used if this is table* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.column_count View documentation} + */ + readonly column_count: uint + /** + * Whether the content of this table should be vertically centered. Overrides + * {@link LuaStyle.column_alignments LuaStyle::column_alignments}. Defaults to `true`. + * + * *Can only be used if this is table* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.vertical_centering View documentation} + */ + vertical_centering: boolean +} + +type TableGuiElement = TableGuiElementMembers & GuiElementIndex + +/** @noSelf */ +interface TextfieldGuiElementMembers extends BaseGuiElement { + /** + * The type of this GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.type View documentation} + */ + readonly type: "textfield" + /** + * Selects all the text in this textbox. + * + * *Can only be used if this is textfield or text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.select_all View documentation} + */ + select_all(): void + /** + * Selects a range of text in this textbox. + * + * *Can only be used if this is textfield or text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.select View documentation} + * + * @example + * Select the characters `amp` from `example`: + * + * ```lua + * textbox.select(3, 5) + * ``` + * + * @example + * Move the cursor to the start of the text box: + * + * ```lua + * textbox.select(1, 0) + * ``` + * + * @param start - The index of the first character to select + * @param end - The index of the last character to select + */ + select(start: int, end: int): void + /** + * The text contained in this textfield or text-box. + * + * *Can only be used if this is textfield or text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.text View documentation} + */ + text: string + /** + * Whether this textfield is limited to only numberic characters. + * + * *Can only be used if this is textfield* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.numeric View documentation} + */ + numeric: boolean + /** + * Whether this textfield (when in numeric mode) allows decimal numbers. + * + * *Can only be used if this is textfield* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.allow_decimal View documentation} + */ + allow_decimal: boolean + /** + * Whether this textfield (when in numeric mode) allows negative numbers. + * + * *Can only be used if this is textfield* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.allow_negative View documentation} + */ + allow_negative: boolean + /** + * Whether this textfield displays as a password field, which renders all characters as `*`. + * + * *Can only be used if this is textfield* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.is_password View documentation} + */ + is_password: boolean + /** + * Whether this textfield loses focus after {@link defines.events.on_gui_confirmed} is fired. + * + * *Can only be used if this is textfield* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.lose_focus_on_confirm View documentation} + */ + lose_focus_on_confirm: boolean + /** + * Makes it so right-clicking on this textfield clears and focuses it. + * + * *Can only be used if this is textfield or text-box* + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html#LuaGuiElement.clear_and_focus_on_right_click View documentation} + */ + clear_and_focus_on_right_click: boolean +} + +type TextfieldGuiElement = TextfieldGuiElementMembers & GuiElementIndex + +type GuiElementMembers = + | ChooseElemButtonGuiElementMembers + | DropDownGuiElementMembers + | EmptyWidgetGuiElementMembers + | EntityPreviewGuiElementMembers + | ListBoxGuiElementMembers + | ScrollPaneGuiElementMembers + | SpriteButtonGuiElementMembers + | TabbedPaneGuiElementMembers + | TextBoxGuiElementMembers + | ButtonGuiElementMembers + | CameraGuiElementMembers + | CheckboxGuiElementMembers + | FlowGuiElementMembers + | FrameGuiElementMembers + | LabelGuiElementMembers + | LineGuiElementMembers + | MinimapGuiElementMembers + | ProgressbarGuiElementMembers + | RadiobuttonGuiElementMembers + | SliderGuiElementMembers + | SpriteGuiElementMembers + | SwitchGuiElementMembers + | TabGuiElementMembers + | TableGuiElementMembers + | TextfieldGuiElementMembers + +/** + * An element of a custom GUI. This type is used to represent any kind of a GUI element - labels, buttons and frames are + * all instances of this type. Just like {@link LuaEntity}, different kinds of elements support different attributes; + * attempting to access an attribute on an element that doesn't support it (for instance, trying to access the + * `column_count` of a `textfield`) will result in a runtime error. + * + * The following types of GUI element are supported: + * + * - `"button"`: A clickable element. Relevant event: {@link OnGuiClickEvent on_gui_click} + * - `"sprite-button"`: A `button` that displays a sprite rather than text. Relevant event: {@link OnGuiClickEvent on_gui_click} + * - `"checkbox"`: A clickable element with a check mark that can be turned off or on. Relevant event: + * {@link OnGuiCheckedStateChangedEvent on_gui_checked_state_changed} + * - `"flow"`: An invisible container that lays out its children either horizontally or vertically. + * - `"frame"`: A non-transparent box that contains other elements. It can have a title (set via the `caption` attribute). + * Just like a `flow`, it lays out its children either horizontally or vertically. Relevant event: + * {@link OnGuiLocationChangedEvent on_gui_location_changed} + * - `"label"`: A piece of text. + * - `"line"`: A horizontal or vertical separation line. + * - `"progressbar"`: A partially filled bar that can be used to indicate progress. + * - `"table"`: An invisible container that lays out its children in a specific number of columns. The width of each + * column is determined by the widest element it contains. + * - `"textfield"`: A single-line box the user can type into. Relevant events: + * {@link OnGuiTextChangedEvent on_gui_text_changed}, {@link OnGuiConfirmedEvent on_gui_confirmed} + * - `"radiobutton"`: A clickable element that is functionally identical to a `checkbox`, but has a circular appearance. + * Relevant event: {@link OnGuiCheckedStateChangedEvent on_gui_checked_state_changed} + * - `"sprite"`: An element that shows an image. + * - `"scroll-pane"`: An invisible element that is similar to a `flow`, but has the ability to show and use scroll bars. + * - `"drop-down"`: A drop-down containing strings of text. Relevant event: + * {@link OnGuiSelectionStateChangedEvent on_gui_selection_state_changed} + * - `"list-box"`: A list of strings, only one of which can be selected at a time. Shows a scroll bar if necessary. + * Relevant event: {@link OnGuiSelectionStateChangedEvent on_gui_selection_state_changed} + * - `"camera"`: A camera that shows the game at the given position on the given surface. It can visually track an + * {@link LuaGuiElement.entity entity} that is set after the element has been created. + * - `"choose-elem-button"`: A button that lets the player pick from a certain kind of prototype, with optional filtering. + * Relevant event: {@link OnGuiElemChangedEvent on_gui_elem_changed} + * - `"text-box"`: A multi-line `textfield`. Relevant event: {@link OnGuiTextChangedEvent on_gui_text_changed} + * - `"slider"`: A horizontal number line which can be used to choose a number. Relevant event: + * {@link OnGuiValueChangedEvent on_gui_value_changed} + * - `"minimap"`: A minimap preview, similar to the normal player minimap. It can visually track an + * {@link LuaGuiElement.entity entity} that is set after the element has been created. + * - `"entity-preview"`: A preview of an entity. The {@link LuaGuiElement.entity entity} has to be set after the element + * has been created. + * - `"empty-widget"`: An empty element that just exists. The root GUI elements `screen` and `relative` are `empty-widget`s. + * - `"tabbed-pane"`: A collection of `tab`s and their contents. Relevant event: + * {@link OnGuiSelectedTabChangedEvent on_gui_selected_tab_changed} + * - `"tab"`: A tab for use in a `tabbed-pane`. + * - `"switch"`: A switch with three possible states. Can have labels attached to either side. Relevant event: + * {@link OnGuiSwitchStateChangedEvent on_gui_switch_state_changed} + * + * Each GUI element allows access to its children by having them as attributes. Thus, one can use the `parent.child` + * syntax to refer to children. Lua also supports the `parent["child"]` syntax to refer to the same element. This can be + * used in cases where the child has a name that isn't a valid Lua identifier. + * + * {@link https://lua-api.factorio.com/next/LuaGuiElement.html View documentation} + * + * @example + * This will add a label called `greeting` to the top flow. Immediately after, it will change its text to illustrate accessing child elements. + * + * ```lua + * game.player.gui.top.add{type="label", name="greeting", caption="Hi"} + * game.player.gui.top.greeting.caption = "Hello there!" + * game.player.gui.top["greeting"].caption = "Actually, never mind, I don't like your face" + * ``` + * + * @example + * This will add a tabbed-pane and 2 tabs with contents. + * + * ```lua + * local tabbed_pane = game.player.gui.top.add{type="tabbed-pane"} + * local tab1 = tabbed_pane.add{type="tab", caption="Tab 1"} + * local tab2 = tabbed_pane.add{type="tab", caption="Tab 2"} + * local label1 = tabbed_pane.add{type="label", caption="Label 1"} + * local label2 = tabbed_pane.add{type="label", caption="Label 2"} + * tabbed_pane.add_tab(tab1, label1) + * tabbed_pane.add_tab(tab2, label2) + * ``` + */ +type LuaGuiElement = GuiElementMembers & GuiElementIndex + +/** + * Prototype of a heat energy source. + * + * {@link https://lua-api.factorio.com/next/LuaHeatEnergySourcePrototype.html View documentation} + * + * @noSelf + */ +interface LuaHeatEnergySourcePrototype { + readonly emissions: double + readonly render_no_network_icon: boolean + readonly render_no_power_icon: boolean + readonly max_temperature: double + readonly default_temperature: double + readonly specific_heat: double + readonly max_transfer: double + readonly min_temperature_gradient: double + readonly min_working_temperature: double + readonly minimum_glow_temperature: double + readonly connections: HeatConnection[] + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaHeatEnergySourcePrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Control behavior for inserters. + * + * {@link https://lua-api.factorio.com/next/LuaInserterControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaInserterControlBehavior extends LuaGenericOnOffControlBehavior { + /** + * `true` if the contents of the inserter hand should be sent to the circuit network + * + * {@link https://lua-api.factorio.com/next/LuaInserterControlBehavior.html#LuaInserterControlBehavior.circuit_read_hand_contents View documentation} + */ + circuit_read_hand_contents: boolean + /** + * The circuit mode of operations for the inserter. + * + * {@link https://lua-api.factorio.com/next/LuaInserterControlBehavior.html#LuaInserterControlBehavior.circuit_mode_of_operation View documentation} + */ + circuit_mode_of_operation: defines.control_behavior.inserter.circuit_mode_of_operation + /** + * The hand read mode for the inserter. + * + * {@link https://lua-api.factorio.com/next/LuaInserterControlBehavior.html#LuaInserterControlBehavior.circuit_hand_read_mode View documentation} + */ + circuit_hand_read_mode: defines.control_behavior.inserter.hand_read_mode + /** + * If the stack size of the inserter is set through the circuit network or not. + * + * {@link https://lua-api.factorio.com/next/LuaInserterControlBehavior.html#LuaInserterControlBehavior.circuit_set_stack_size View documentation} + */ + circuit_set_stack_size: boolean + /** + * The signal used to set the stack size of the inserter. + * + * {@link https://lua-api.factorio.com/next/LuaInserterControlBehavior.html#LuaInserterControlBehavior.circuit_stack_control_signal View documentation} + */ + circuit_stack_control_signal: SignalID + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaInserterControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A storage of item stacks. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html View documentation} + * + * @noSelf + */ +interface LuaInventory extends ReadonlyArray { + /** + * Make this inventory empty. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.clear View documentation} + */ + clear(): void + /** + * Can at least some items be inserted? + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.can_insert View documentation} + * + * @param items - Items that would be inserted. + * @returns `true` if at least a part of the given items could be inserted into this inventory. + */ + can_insert(items: ItemStackIdentification): boolean + /** + * Insert items into this inventory. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.insert View documentation} + * + * @param items - Items to insert. + * @returns Number of items actually inserted. + */ + insert(items: ItemStackIdentification): uint + /** + * Remove items from this inventory. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.remove View documentation} + * + * @param items - Items to remove. + * @returns Number of items actually removed. + */ + remove(items: ItemStackIdentification): uint + /** + * Get the number of all or some items in this inventory. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.get_item_count View documentation} + * + * @param item - Prototype name of the item to count. If not specified, count all items. + */ + get_item_count(item?: string): uint + /** + * Does this inventory contain nothing? + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.is_empty View documentation} + */ + is_empty(): boolean + /** + * Get counts of all items in this inventory. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.get_contents View documentation} + * + * @returns The counts, indexed by item names. + */ + get_contents(): Record + /** + * Does this inventory support a bar? Bar is the draggable red thing, found for example on chests, that limits the + * portion of the inventory that may be manipulated by machines. + * + * **Note**: "Supporting a bar" doesn't mean that the bar is set to some nontrivial value. Supporting a bar means + * the inventory supports having this limit at all. The character's inventory is an example of an inventory without + * a bar; the wooden chest's inventory is an example of one with a bar. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.supports_bar View documentation} + */ + supports_bar(): boolean + /** + * Get the current bar. This is the index at which the red area starts. + * + * **Note**: Only useable if this inventory supports having a bar. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.get_bar View documentation} + */ + get_bar(): uint + /** + * Set the current bar. + * + * **Note**: Only useable if this inventory supports having a bar. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.set_bar View documentation} + * + * @param bar - The new limit. Omitting this parameter will clear the limit. + */ + set_bar(bar?: uint): void + /** + * If this inventory supports filters. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.supports_filters View documentation} + */ + supports_filters(): boolean + /** + * If this inventory supports filters and has at least 1 filter set. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.is_filtered View documentation} + */ + is_filtered(): boolean + /** + * If the given inventory slot filter can be set to the given filter. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.can_set_filter View documentation} + * + * @param index - The item stack index + * @param filter - The item name of the filter + */ + can_set_filter(index: uint, filter: string): boolean + /** + * Gets the filter for the given item stack index. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.get_filter View documentation} + * + * @param index - The item stack index + * @returns The current filter or nil if none. + */ + get_filter(index: uint): string | undefined + /** + * Sets the filter for the given item stack index. + * + * **Note**: Some inventory slots don't allow some filters (gun ammo can't be filtered for non-ammo). + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.set_filter View documentation} + * + * @param index - The item stack index + * @param filter - The new filter or nil to erase the filter + * @returns If the filter was allowed to be set. + */ + set_filter(index: uint, filter: string | undefined): boolean + /** + * Gets the first LuaItemStack in the inventory that matches the given item name. + * + * **Note**: This will also return the stack index if one is found that matches as a second return value. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.find_item_stack View documentation} + * + * @param item - The item name to find + * @returns The first matching stack, or `nil` if none match. + */ + find_item_stack(item: string): LuaMultiReturn<[undefined] | [LuaItemStack, uint]> + /** + * Finds the first empty stack. Filtered slots are excluded unless a filter item is given. + * + * **Note**: This will also return the stack index if one is found that matches as a second return value. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.find_empty_stack View documentation} + * + * @param item - If given, empty stacks that are filtered for this item will be included. + * @returns The first empty stack, or `nil` if there aren't any empty stacks. + */ + find_empty_stack(item?: string): LuaMultiReturn<[undefined] | [LuaItemStack, uint]> + /** + * Counts the number of empty stacks. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.count_empty_stacks View documentation} + * + * @param include_filtered - If true, filtered slots will be included. Defaults to false. + */ + count_empty_stacks(include_filtered?: boolean): uint + /** + * Gets the number of the given item that can be inserted into this inventory. + * + * **Note**: This is a "best guess" number; things like assembling machine filtered slots, module slots, items with + * durability, and items with mixed health will cause the result to be inaccurate. + * + * **Note**: The main use for this is in checking how many of a basic item can fit into a basic inventory. + * + * **Note**: This accounts for the 'bar' on the inventory. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.get_insertable_count View documentation} + * + * @param item - The item to check. + */ + get_insertable_count(item: string): void + /** + * Sorts and merges the items in this inventory. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.sort_and_merge View documentation} + */ + sort_and_merge(): void + /** + * Resizes the inventory. + * + * **Note**: Items in slots beyond the new capacity are deleted. + * + * **Note**: Only inventories created by {@link LuaGameScript.create_inventory LuaGameScript::create_inventory} can be resized. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.resize View documentation} + * + * @param size - New size of a inventory + */ + resize(size: uint16): void + /** + * Destroys this inventory. + * + * **Note**: Only inventories created by {@link LuaGameScript.create_inventory LuaGameScript::create_inventory} can + * be destroyed this way. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.destroy View documentation} + */ + destroy(): void + /** + * Get the number of slots in this inventory. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.operator%20# View documentation} + * + * @example + * Will print the number of slots in the player's main inventory. + * + * ```lua + * game.player.print(#game.player.get_main_inventory()) + * ``` + */ + readonly length: uint + /** + * The inventory index this inventory uses, or `nil` if the inventory doesn't have an index. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.index View documentation} + */ + readonly index: defines.inventory | undefined + /** + * The entity that owns this inventory or `nil` if this isn't owned by an entity. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.entity_owner View documentation} + */ + readonly entity_owner: LuaEntity | undefined + /** + * The player that owns this inventory or `nil` if this isn't owned by a player. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.player_owner View documentation} + */ + readonly player_owner: LuaPlayer | undefined + /** + * The equipment that owns this inventory or `nil` if this isn't owned by an equipment. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.equipment_owner View documentation} + */ + readonly equipment_owner: LuaEquipment | undefined + /** + * The mod that owns this inventory or `nil` if this isn't owned by a mod. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.mod_owner View documentation} + */ + readonly mod_owner: string | undefined + /** + * The indexing operator. + * + * {@link https://lua-api.factorio.com/next/LuaInventory.html#LuaInventory.operator%20[] View documentation} + * + * @example + * Will get the first item in the player's inventory. + * + * ```lua + * game.player.get_main_inventory()[1] + * ``` + */ + readonly [index: number]: LuaItemStack + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaInventory" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of an item. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html View documentation} + * + * @example + * ```lua + * game.item_prototypes["iron-plate"] + * ``` + * + * @noSelf + */ +interface LuaItemPrototype { + /** + * Does this prototype have a flag enabled? + * + * Any other value will cause an error. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.has_flag View documentation} + * + * @param flag - The flag to check. Can be one of {@link ItemPrototypeFlags} + */ + has_flag(flag: string): boolean + /** + * Type of this ammo prototype or `nil` if this is not an ammo prototype. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.get_ammo_type View documentation} + * + * @param ammo_source_type - "default", "player", "turret", or "vehicle" + */ + get_ammo_type(ammo_source_type?: "default" | "player" | "turret" | "vehicle"): AmmoType | undefined + /** + * Type of this prototype. E.g. `"gun"` or `"mining-tool"`. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.type View documentation} + */ + readonly type: "gun" | "mining-tool" + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.name View documentation} + */ + readonly name: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * Order string. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.order View documentation} + */ + readonly order: string + /** + * Prototype of the entity that will be created by placing this item, or `nil` if there is no such entity. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.place_result View documentation} + */ + readonly place_result: LuaEntityPrototype | undefined + /** + * Prototype of the equipment that will be created by placing this item in an equipment grid or `nil` if there is no + * equipment defined. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.place_as_equipment_result View documentation} + */ + readonly place_as_equipment_result: LuaEquipmentPrototype | undefined + /** + * The place-as-tile result if one is defined, else `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.place_as_tile_result View documentation} + */ + readonly place_as_tile_result: PlaceAsTileResult | undefined + /** + * Is this item allowed to stack at all? + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.stackable View documentation} + */ + readonly stackable: boolean + /** + * The default request value. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.default_request_amount View documentation} + */ + readonly default_request_amount: uint + /** + * Maximum stack size of the item specified by this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.stack_size View documentation} + */ + readonly stack_size: uint + /** + * The number of items needed to connect 2 entities with this as wire. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.wire_count View documentation} + */ + readonly wire_count: uint + /** + * The fuel category or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.fuel_category View documentation} + */ + readonly fuel_category: string | undefined + /** + * The result of burning this item as fuel or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.burnt_result View documentation} + */ + readonly burnt_result: LuaItemPrototype | undefined + /** + * Fuel value when burned. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.fuel_value View documentation} + */ + readonly fuel_value: float + /** + * The acceleration multiplier when this item is used as fuel in a vehicle. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.fuel_acceleration_multiplier View documentation} + */ + readonly fuel_acceleration_multiplier: double + /** + * The fuel top speed multiplier when this item is used as fuel in a vehicle. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.fuel_top_speed_multiplier View documentation} + */ + readonly fuel_top_speed_multiplier: double + /** + * The emissions multiplier if this is used as fuel. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.fuel_emissions_multiplier View documentation} + */ + readonly fuel_emissions_multiplier: double + /** + * The subgroup this prototype belongs to. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.subgroup View documentation} + */ + readonly subgroup: LuaGroup + /** + * The group this prototype belongs to. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.group View documentation} + */ + readonly group: LuaGroup + /** + * The item prototype flags for this item prototype. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.flags View documentation} + */ + readonly flags: ItemPrototypeFlags + /** + * The results from launching this item in a rocket. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.rocket_launch_products View documentation} + */ + readonly rocket_launch_products: Product[] + /** + * If this item can be mod-opened. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.can_be_mod_opened View documentation} + */ + readonly can_be_mod_opened: boolean + /** + * Size of full magazine; `nil` if this is not an ammo item. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.magazine_size View documentation} + */ + readonly magazine_size: float | undefined + /** + * Amount of extra time (in ticks) it takes to reload the weapon after depleting the magazine or `nil` if this is + * not an ammo item. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.reload_time View documentation} + */ + readonly reload_time: float | undefined + /** + * The prototype of this armor equipment grid or `nil` if none or this is not an armor item. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.equipment_grid View documentation} + */ + readonly equipment_grid: LuaEquipmentGridPrototype | undefined + /** + * Resistances of this armour item, indexed by damage type name. `nil` if not an armor or the armor has no resistances. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.resistances View documentation} + */ + readonly resistances: Record | undefined + /** + * The inventory size bonus for this armor prototype. `nil` if this isn't an armor prototype. + * + * *Can only be used if this is ArmorPrototype* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.inventory_size_bonus View documentation} + */ + readonly inventory_size_bonus: uint | undefined + /** + * The capsule action for this capsule item prototype or `nil` if this isn't a capsule item prototype. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.capsule_action View documentation} + */ + readonly capsule_action: CapsuleAction | undefined + /** + * The gun attack parameters or `nil` if not a gun item prototype. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.attack_parameters View documentation} + */ + readonly attack_parameters: AttackParameters | undefined + /** + * The main inventory size for item-with-inventory-prototype. `nil` if not an item-with-inventory-prototype. + * + * *Can only be used if this is ItemWithInventoryPrototype* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.inventory_size View documentation} + */ + readonly inventory_size: uint | undefined + /** + * *Can only be used if this is ItemWithInventory* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.item_filters View documentation} + */ + readonly item_filters: Record + /** + * *Can only be used if this is ItemWithInventory* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.item_group_filters View documentation} + */ + readonly item_group_filters: Record + /** + * *Can only be used if this is ItemWithInventory* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.item_subgroup_filters View documentation} + */ + readonly item_subgroup_filters: Record + /** + * The filter mode used by this item with inventory. + * + * *Can only be used if this is ItemWithInventory* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.filter_mode View documentation} + */ + readonly filter_mode: string + /** + * The insertion priority mode used by this item with inventory. + * + * *Can only be used if this is ItemWithInventory* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.insertion_priority_mode View documentation} + */ + readonly insertion_priority_mode: string + /** + * The localised string used when the player attempts to put items into this item with inventory that aren't allowed. + * + * *Can only be used if this is ItemWithInventory* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.localised_filter_message View documentation} + */ + readonly localised_filter_message: LocalisedString + /** + * If this item with inventory extends the inventory it resides in by default. + * + * *Can only be used if this is ItemWithInventory* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.extend_inventory_by_default View documentation} + */ + readonly extend_inventory_by_default: boolean + /** + * The default label color used for this item with label. `nil` if not defined or if this isn't an item with label. + * + * *Can only be used if this is ItemWithLabel* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.default_label_color View documentation} + */ + readonly default_label_color: ColorTable | undefined + /** + * If true, and this item with label has a label it is drawn in place of the normal number when held in the cursor. + * + * *Can only be used if this is ItemWithLabel* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.draw_label_for_cursor_render View documentation} + */ + readonly draw_label_for_cursor_render: boolean + /** + * The repairing speed if this is a repairing tool; otherwise `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.speed View documentation} + */ + readonly speed: float | undefined + /** + * Effects of this module; `nil` if this is not a module. + * + * *Can only be used if this is ModuleItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.module_effects View documentation} + */ + readonly module_effects: ModuleEffects | undefined + /** + * The name of a {@link LuaModuleCategoryPrototype}. Used when upgrading modules: Ctrl + click modules into an entity + * and it will replace lower tier modules of the same category with higher tier modules. + * + * *Can only be used if this is ModuleItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.category View documentation} + */ + readonly category: string + /** + * Tier of the module inside its category. Used when upgrading modules: Ctrl + click modules into an entity and it + * will replace lower tier modules with higher tier modules if they have the same category. + * + * *Can only be used if this is ModuleItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.tier View documentation} + */ + readonly tier: uint + /** + * An array of recipe names this module is allowed to work with. Empty when all recipes are allowed. + * + * *Can only be used if this is ModuleItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.limitations View documentation} + */ + readonly limitations: string[] + /** + * The limitation message key used when the player attempts to use this modules in some place it's not allowed. + * + * *Can only be used if this is ModuleItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.limitation_message_key View documentation} + */ + readonly limitation_message_key: string + /** + * The straight rail prototype used for this rail planner prototype. + * + * *Can only be used if this is RailPlanner* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.straight_rail View documentation} + */ + readonly straight_rail: LuaEntityPrototype + /** + * The curved rail prototype used for this rail planner prototype. + * + * *Can only be used if this is RailPlanner* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.curved_rail View documentation} + */ + readonly curved_rail: LuaEntityPrototype + /** + * The repair result of this repair tool prototype or `nil` if this isn't a repair tool prototype. + * + * *Can only be used if this is RepairTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.repair_result View documentation} + */ + readonly repair_result: TriggerItem[] | undefined + /** + * The color used when doing normal selection with this selection tool prototype. + * + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.selection_border_color View documentation} + */ + readonly selection_border_color: ColorTable + /** + * The color used when doing alt selection with this selection tool prototype. + * + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.alt_selection_border_color View documentation} + */ + readonly alt_selection_border_color: ColorTable + /** + * Flags that affect which entities will be selected. + * + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.selection_mode_flags View documentation} + */ + readonly selection_mode_flags: SelectionModeFlags + /** + * Flags that affect which entities will be selected during alternate selection. + * + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.alt_selection_mode_flags View documentation} + */ + readonly alt_selection_mode_flags: SelectionModeFlags + /** + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.selection_cursor_box_type View documentation} + */ + readonly selection_cursor_box_type: string + /** + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.alt_selection_cursor_box_type View documentation} + */ + readonly alt_selection_cursor_box_type: string + /** + * If tiles area always included when doing selection with this selection tool prototype. + * + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.always_include_tiles View documentation} + */ + readonly always_include_tiles: boolean + /** + * The entity filter mode used by this selection tool. + * + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.entity_filter_mode View documentation} + */ + readonly entity_filter_mode: string + /** + * The alt entity filter mode used by this selection tool. + * + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.alt_entity_filter_mode View documentation} + */ + readonly alt_entity_filter_mode: string + /** + * The tile filter mode used by this selection tool. + * + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.tile_filter_mode View documentation} + */ + readonly tile_filter_mode: string + /** + * The alt tile filter mode used by this selection tool. + * + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.alt_tile_filter_mode View documentation} + */ + readonly alt_tile_filter_mode: string + /** + * The entity filters used by this selection tool indexed by entity name. + * + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.entity_filters View documentation} + */ + readonly entity_filters: Record + /** + * The alt entity filters used by this selection tool indexed by entity name. + * + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.alt_entity_filters View documentation} + */ + readonly alt_entity_filters: Record + /** + * The entity type filters used by this selection tool indexed by entity type. + * + * **Note**: The boolean value is meaningless and is used to allow easy lookup if a type exists in the dictionary. + * + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.entity_type_filters View documentation} + */ + readonly entity_type_filters: Record + /** + * The alt entity type filters used by this selection tool indexed by entity type. + * + * **Note**: The boolean value is meaningless and is used to allow easy lookup if a type exists in the dictionary. + * + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.alt_entity_type_filters View documentation} + */ + readonly alt_entity_type_filters: Record + /** + * The tile filters used by this selection tool indexed by tile name. + * + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.tile_filters View documentation} + */ + readonly tile_filters: Record + /** + * The alt tile filters used by this selection tool indexed by tile name. + * + * *Can only be used if this is SelectionTool* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.alt_tile_filters View documentation} + */ + readonly alt_tile_filters: Record + /** + * The number of entity filters this deconstruction item has or `nil` if this isn't a deconstruction item prototype. + * + * *Can only be used if this is DeconstructionItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.entity_filter_slots View documentation} + */ + readonly entity_filter_slots: uint | undefined + /** + * The number of tile filters this deconstruction item has or `nil` if this isn't a deconstruction item prototype. + * + * *Can only be used if this is DeconstructionItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.tile_filter_slots View documentation} + */ + readonly tile_filter_slots: uint | undefined + /** + * The durability message key used when displaying the durability of this tool. + * + * *Can only be used if this is ToolItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.durability_description_key View documentation} + */ + readonly durability_description_key: string + /** + * The durability of this tool item or `nil` if not a tool item. + * + * *Can only be used if this is ToolItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.durability View documentation} + */ + readonly durability: double | undefined + /** + * If this tool item has infinite durability. `nil` if not a tool type item. + * + * *Can only be used if this is ToolItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.infinite View documentation} + */ + readonly infinite: boolean | undefined + /** + * How many filters an upgrade item has. `nil` if not a upgrade item. + * + * *Can only be used if this is UpgradeItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemPrototype.html#LuaItemPrototype.mapper_count View documentation} + */ + readonly mapper_count: uint | undefined + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaItemPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A reference to an item and count owned by some external entity. + * + * **Note**: In most instances this is a simple reference as in: it points at a specific slot in an inventory and not + * the item in the slot. + * + * **Note**: In the instance this references an item on a {@link LuaTransportLine} the reference is only guaranteed to + * stay valid (and refer to the same item) as long as nothing changes the transport line. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html View documentation} + * + * @noSelf + */ +interface LuaItemStack { + /** + * Is this blueprint item setup? I.e. is it a non-empty blueprint? + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_blueprint_setup View documentation} + */ + is_blueprint_setup(): boolean + /** + * The entities in this blueprint. + * + * *Can only be used if this is BlueprintItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_blueprint_entities View documentation} + */ + get_blueprint_entities(): BlueprintEntity[] + /** + * Set new entities to be a part of this blueprint. + * + * *Can only be used if this is BlueprintItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_blueprint_entities View documentation} + * + * @param entities - The new blueprint entities. + */ + set_blueprint_entities(entities: BlueprintEntity[]): void + /** + * Add ammo to this ammo item. + * + * *Can only be used if this is AmmoItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.add_ammo View documentation} + * + * @param amount - Amount of ammo to add. + */ + add_ammo(amount: float): void + /** + * Remove ammo from this ammo item. + * + * *Can only be used if this is AmmoItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.drain_ammo View documentation} + * + * @param amount - Amount of ammo to remove. + */ + drain_ammo(amount: float): void + /** + * Add durability to this tool item. + * + * *Can only be used if this is ToolItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.add_durability View documentation} + * + * @param amount - Amount of durability to add. + */ + add_durability(amount: double): void + /** + * Remove durability from this tool item. + * + * *Can only be used if this is ToolItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.drain_durability View documentation} + * + * @param amount - Amount of durability to remove. + */ + drain_durability(amount: double): void + /** + * Would a call to {@link LuaItemStack.set_stack LuaItemStack::set_stack} succeed? + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.can_set_stack View documentation} + * + * @param stack - Stack that would be set, possibly `nil`. + */ + can_set_stack(stack?: ItemStackIdentification): boolean + /** + * Set this item stack to another item stack. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_stack View documentation} + * + * @param stack - Item stack to set this one to. Omitting this parameter or passing `nil` will clear this item + * stack, as if by calling {@link LuaItemStack.clear LuaItemStack::clear}. + * @returns Was the stack set successfully? + */ + set_stack(stack?: ItemStackIdentification): boolean + /** + * Transfers the given item stack into this item stack. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.transfer_stack View documentation} + * + * @param stack + * @returns True if the full stack was transferred. + */ + transfer_stack(stack: ItemStackIdentification): boolean + /** + * Export a supported item (blueprint, blueprint-book, deconstruction-planner, upgrade-planner, item-with-tags) to a string + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.export_stack View documentation} + * + * @returns The exported string + */ + export_stack(): string + /** + * Import a supported item (blueprint, blueprint-book, deconstruction-planner, upgrade-planner, item-with-tags) from a string + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.import_stack View documentation} + * + * @param data - The string to import + * @returns 0 if the import succeeded with no errors. -1 if the import succeeded with errors. 1 if the import failed. + */ + import_stack(data: string): int + /** + * Swaps this item stack with the given item stack if allowed. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.swap_stack View documentation} + * + * @param stack + * @returns If the 2 stacks were swapped successfully. + */ + swap_stack(stack: LuaItemStack): boolean + /** + * Clear this item stack. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.clear View documentation} + */ + clear(): void + /** + * A list of the tiles in this blueprint. + * + * *Can only be used if this is BlueprintItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_blueprint_tiles View documentation} + */ + get_blueprint_tiles(): Tile[] + /** + * Set specific tiles in this blueprint. + * + * *Can only be used if this is BlueprintItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_blueprint_tiles View documentation} + * + * @param tiles - Tiles to be a part of the blueprint. + */ + set_blueprint_tiles(tiles: Tile[]): void + /** + * Access the inner inventory of an item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_inventory View documentation} + * + * @param inventory - Index of the inventory to access -- currently can only be {@link defines.inventory.item_main}. + * @returns Or `nil` if there is no inventory with the given index. + */ + get_inventory(inventory: defines.inventory): LuaInventory | undefined + /** + * Build this blueprint + * + * **Note**: Built entities can be come invalid between the building of the blueprint and the function returning if + * by_player or raise_built is used and one of those events invalidates the entity. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.build_blueprint View documentation} + * + * @returns Array of created ghosts + */ + build_blueprint(params: { + /** Surface to build on */ + readonly surface: SurfaceIdentification + /** Force to use for the building */ + readonly force: ForceIdentification + /** The position to build at */ + readonly position: Position + /** When true, anything that can be built is else nothing is built if any one thing can't be built */ + readonly force_build?: boolean + /** The direction to use when building */ + readonly direction?: defines.direction + /** If chunks covered by fog-of-war are skipped. */ + readonly skip_fog_of_war?: boolean + /** + * The player to use if any. If provided {@link defines.events.on_built_entity} will also be fired on successful + * entity creation. + */ + readonly by_player?: PlayerIdentification + /** + * If true; {@link defines.events.script_raised_built} will be fired on successful entity creation. Note: this is + * ignored if by_player is provided. + */ + readonly raise_built?: boolean + }): LuaEntity[] + /** + * Deconstruct the given area with this deconstruction item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.deconstruct_area View documentation} + */ + deconstruct_area(params: { + /** Surface to deconstruct on */ + readonly surface: SurfaceIdentification + /** Force to use for the deconstruction */ + readonly force: ForceIdentification + /** The area to deconstruct */ + readonly area: BoundingBox + /** If chunks covered by fog-of-war are skipped. */ + readonly skip_fog_of_war?: boolean + /** The player to use if any. */ + readonly by_player?: PlayerIdentification + }): void + /** + * Cancel deconstruct the given area with this deconstruction item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.cancel_deconstruct_area View documentation} + */ + cancel_deconstruct_area(params: { + /** Surface to cancel deconstruct on */ + readonly surface: SurfaceIdentification + /** Force to use for canceling deconstruction */ + readonly force: ForceIdentification + /** The area to deconstruct */ + readonly area: BoundingBox + /** If chunks covered by fog-of-war are skipped. */ + readonly skip_fog_of_war?: boolean + /** The player to use if any. */ + readonly by_player?: PlayerIdentification + }): void + /** + * Sets up this blueprint using the found blueprintable entities/tiles on the surface. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.create_blueprint View documentation} + * + * @returns The blueprint entity index to source entity mapping. + */ + create_blueprint(params: { + /** Surface to create from */ + readonly surface: SurfaceIdentification + /** Force to use for the creation */ + readonly force: ForceIdentification + /** The bounding box */ + readonly area: BoundingBox + /** + * When true, blueprintable tiles are always included in the blueprint. When false they're only included if no + * entities exist in the setup area. + */ + readonly always_include_tiles?: boolean + /** When true, entities are included in the blueprint. Defaults to true. */ + readonly include_entities?: boolean + /** When true, modules are included in the blueprint. Defaults to true. */ + readonly include_modules?: boolean + /** When true, station names are included in the blueprint. Defaults to false. */ + readonly include_station_names?: boolean + /** When true, trains are included in the blueprint. Defaults to false. */ + readonly include_trains?: boolean + /** When true, train fuel is included in the blueprint, Defaults to true. */ + readonly include_fuel?: boolean + }): Record + /** + * Gets the tag with the given name or returns `nil` if it doesn't exist. + * + * *Can only be used if this is ItemWithTags* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_tag View documentation} + * + * @param tag_name + */ + get_tag(tag_name: string): AnyBasic | undefined + /** + * Sets the tag with the given name and value. + * + * *Can only be used if this is ItemWithTags* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_tag View documentation} + * + * @param tag_name + * @param tag + */ + set_tag(tag_name: string, tag: AnyBasic): AnyBasic + /** + * Removes a tag with the given name. + * + * *Can only be used if this is ItemWithTags* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.remove_tag View documentation} + * + * @param tag + * @returns If the tag existed and was removed. + */ + remove_tag(tag: string): boolean + /** + * Clears this blueprint item. + * + * *Can only be used if this is BlueprintItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.clear_blueprint View documentation} + */ + clear_blueprint(): void + /** + * Gets the entity filter at the given index for this deconstruction item. + * + * *Can only be used if this is DeconstructionItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_entity_filter View documentation} + * + * @param index + */ + get_entity_filter(index: uint): string + /** + * Sets the entity filter at the given index for this deconstruction item. + * + * *Can only be used if this is DeconstructionItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_entity_filter View documentation} + * + * @param index + * @param filter - Setting to nil erases the filter. + * @returns If the new filter was set (was valid.) + */ + set_entity_filter(index: uint, filter: string | LuaEntityPrototype | LuaEntity | undefined): boolean + /** + * Gets the tile filter at the given index for this deconstruction item. + * + * *Can only be used if this is DeconstructionItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_tile_filter View documentation} + * + * @param index + */ + get_tile_filter(index: uint): string + /** + * Sets the tile filter at the given index for this deconstruction item. + * + * *Can only be used if this is DeconstructionItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_tile_filter View documentation} + * + * @param index + * @param filter - Setting to nil erases the filter. + * @returns If the new filter was set (was valid.) + */ + set_tile_filter(index: uint, filter: string | LuaTilePrototype | LuaTile | undefined): boolean + /** + * Clears all settings/filters on this deconstruction item resetting it to default values. + * + * *Can only be used if this is DeconstructionItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.clear_deconstruction_item View documentation} + */ + clear_deconstruction_item(): void + /** + * Clears all settings/filters on this upgrade item resetting it to default values. + * + * *Can only be used if this is UpgradeItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.clear_upgrade_item View documentation} + */ + clear_upgrade_item(): void + /** + * Gets the filter at the given index for this upgrade item. + * + * *Can only be used if this is UpgradeItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_mapper View documentation} + * + * @param index - The index of the mapper to read. + * @param type - 'from' or 'to'. + */ + get_mapper(index: uint, type: "from" | "to"): UpgradeFilter + /** + * Sets the module filter at the given index for this upgrade item. + * + * *Can only be used if this is UpgradeItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_mapper View documentation} + * + * @param index - The index of the mapper to set. + * @param type - `from` or `to`. + * @param filter - The filter to set or `nil` + */ + set_mapper(index: uint, type: string, filter: UpgradeFilter | undefined): void + /** + * Gets the number of entities in this blueprint item. + * + * *Can only be used if this is BlueprintItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_blueprint_entity_count View documentation} + */ + get_blueprint_entity_count(): uint + /** + * Gets the tags for the given blueprint entity index in this blueprint item. + * + * *Can only be used if this is BlueprintItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_blueprint_entity_tags View documentation} + * + * @param index + */ + get_blueprint_entity_tags(index: uint): Tags + /** + * Sets the tags on the given blueprint entity index in this blueprint item. + * + * *Can only be used if this is BlueprintItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_blueprint_entity_tags View documentation} + * + * @param index - The entity index + * @param tags + */ + set_blueprint_entity_tags(index: uint, tags: Tags): void + /** + * Gets the given tag on the given blueprint entity index in this blueprint item. + * + * *Can only be used if this is BlueprintItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.get_blueprint_entity_tag View documentation} + * + * @param index - The entity index. + * @param tag - The tag to get. + */ + get_blueprint_entity_tag(index: uint, tag: string): AnyBasic + /** + * Sets the given tag on the given blueprint entity index in this blueprint item. + * + * *Can only be used if this is BlueprintItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.set_blueprint_entity_tag View documentation} + * + * @param index - The entity index. + * @param tag - The tag to set. + * @param value - The tag value to set or `nil` to clear the tag. + */ + set_blueprint_entity_tag(index: uint, tag: string, value: AnyBasic | undefined): void + /** + * Creates the equipment grid for this item if it doesn't exist and this is an item-with-entity-data that supports + * equipment grids. + * + * *Can only be used if this is ItemWithEntityData* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.create_grid View documentation} + */ + create_grid(): LuaEquipmentGrid + /** + * Is this valid for reading? Differs from the usual `valid` in that `valid` will be `true` even if the item stack + * is blank but the entity that holds it is still valid. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.valid_for_read View documentation} + */ + readonly valid_for_read: boolean + /** + * Prototype of the item held in this stack. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.prototype View documentation} + */ + readonly prototype: LuaItemPrototype + /** + * Prototype name of the item held in this stack. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.name View documentation} + */ + readonly name: string + /** + * Type of the item prototype. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.type View documentation} + */ + readonly type: string + /** + * Number of items in this stack. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.count View documentation} + */ + count: uint + /** + * The equipment grid of this item or `nil` if this item doesn't have a grid. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.grid View documentation} + */ + readonly grid: LuaEquipmentGrid | undefined + /** + * How much health the item has, as a number in range [0, 1]. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.health View documentation} + */ + health: float + /** + * Durability of the contained item. Automatically capped at the item's maximum durability. + * + * **Note**: When used on a non-tool item, the value of this attribute is `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.durability View documentation} + */ + durability: double | undefined + /** + * Number of bullets left in the magazine. + * + * *Can only be used if this is AmmoItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.ammo View documentation} + */ + ammo: uint + /** + * Icons of a blueprint item, blueprint book, deconstruction item or upgrade planner. An item that doesn't have + * icons returns nil on read and throws error on write. + * + * *Can only be used if this is BlueprintItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.blueprint_icons View documentation} + */ + blueprint_icons: BlueprintSignalIcon[] | undefined + /** + * The snapping grid size in this blueprint item or nil if snapping is not enabled. + * + * *Can only be used if this is BlueprintItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.blueprint_snap_to_grid View documentation} + */ + blueprint_snap_to_grid: Position | undefined + /** + * The offset from the absolute grid or nil if absolute snapping is not enabled. + * + * *Can only be used if this is BlueprintItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.blueprint_position_relative_to_grid View documentation} + */ + blueprint_position_relative_to_grid: Position | undefined + /** + * If absolute snapping is enabled on this blueprint item. + * + * *Can only be used if this is BlueprintItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.blueprint_absolute_snapping View documentation} + */ + blueprint_absolute_snapping: boolean + /** + * The current label for this item. Nil when none. + * + * *Can only be used if this is ItemWithLabel* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.label View documentation} + */ + label: string | undefined + /** + * The current label color for this item. Nil when none. + * + * *Can only be used if this is ItemWithLabel* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.label_color View documentation} + */ + label_color: Color | undefined + /** + * If the label for this item can be manually changed. When false the label can only be changed through the API. + * + * *Can only be used if this is ItemWithLabel* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.allow_manual_label_change View documentation} + */ + allow_manual_label_change: boolean + /** + * Raw materials required to build this blueprint. Result is a dictionary mapping each item prototype name to the + * required count. + * + * *Can only be used if this is BlueprintItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.cost_to_build View documentation} + */ + readonly cost_to_build: Record + /** + * If this item extends the inventory it resides in (provides its contents for counts, crafting, insertion). Only + * callable on items with inventories. + * + * *Can only be used if this is ItemWithInventory* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.extends_inventory View documentation} + */ + extends_inventory: boolean + /** + * The insertion mode priority this ItemWithInventory uses when items are inserted into an inventory it resides in. + * Only callable on items with inventories. + * + * *Can only be used if this is ItemWithInventory* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.prioritize_insertion_mode View documentation} + */ + prioritize_insertion_mode: string + /** + * The default icons for a blueprint item. + * + * *Can only be used if this is BlueprintItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.default_icons View documentation} + */ + readonly default_icons: BlueprintItemIcon[] + /** + * *Can only be used if this is ItemWithTags* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.tags View documentation} + */ + tags: Tags + /** + * The custom description this item-with-tags. This is shown over the normal item description if this is set to a + * non-empty value. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.custom_description View documentation} + */ + custom_description: LocalisedString + /** + * The entity filters for this deconstruction item. The attribute is a sparse array with the keys representing the + * index of the filter. All strings in this array must be entity prototype names that don't have the + * `"not-deconstructable"` flag set and are either a `cliff` or marked as `minable`. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.entity_filters View documentation} + */ + entity_filters: string[] + /** + * The tile filters for this deconstruction item. The attribute is a sparse array with the keys representing the + * index of the filter. All strings in this array must be tile prototype names. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.tile_filters View documentation} + */ + tile_filters: string[] + /** + * The blacklist/whitelist entity filter mode for this deconstruction item. + * + * *Can only be used if this is DeconstructionItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.entity_filter_mode View documentation} + */ + entity_filter_mode: defines.deconstruction_item.entity_filter_mode + /** + * The blacklist/whitelist tile filter mode for this deconstruction item. + * + * *Can only be used if this is DeconstructionItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.tile_filter_mode View documentation} + */ + tile_filter_mode: defines.deconstruction_item.tile_filter_mode + /** + * The tile selection mode for this deconstruction item. + * + * *Can only be used if this is DeconstructionItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.tile_selection_mode View documentation} + */ + tile_selection_mode: defines.deconstruction_item.tile_selection_mode + /** + * If this deconstruction item is set to allow trees and rocks only. + * + * *Can only be used if this is DeconstructionItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.trees_and_rocks_only View documentation} + */ + trees_and_rocks_only: boolean + /** + * The number of entity filters this deconstruction item supports. + * + * *Can only be used if this is DeconstructionItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.entity_filter_count View documentation} + */ + readonly entity_filter_count: uint + /** + * The number of tile filters this deconstruction item supports. + * + * *Can only be used if this is DeconstructionItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.tile_filter_count View documentation} + */ + readonly tile_filter_count: uint + /** + * The active blueprint index for this blueprint book. May be `nil`. + * + * *Can only be used if this is BlueprintBookItem* + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.active_index View documentation} + */ + active_index: uint | undefined + /** + * The unique identifier for this item if it has one, `nil` otherwise. Note that this ID stays the same no matter + * where the item is moved to. + * + * Only these types of items have unique IDs: + * + * - `"armor"` + * - `"spidertron-remote"` + * - `"selection-tool"` + * - `"copy-paste-tool"` + * - `"upgrade-item"` + * - `"deconstruction-item"` + * - `"blueprint"` + * - `"blueprint-book"` + * - `"item-with-entity-data"` + * - `"item-with-inventory"` + * - `"item-with-tags"` + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.item_number View documentation} + */ + readonly item_number: uint | undefined + /** + * If this item is a spidertron remote that has a spidertron bound to it, it returns the connected spider-vehicle + * entity, `nil` otherwise. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.connected_entity View documentation} + */ + connected_entity: LuaEntity | undefined + /** + * If this is a blueprint item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_blueprint View documentation} + */ + readonly is_blueprint: boolean + /** + * If this is a blueprint book item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_blueprint_book View documentation} + */ + readonly is_blueprint_book: boolean + /** + * If this is a module item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_module View documentation} + */ + readonly is_module: boolean + /** + * If this is a tool item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_tool View documentation} + */ + readonly is_tool: boolean + /** + * If this is a mining tool item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_mining_tool View documentation} + */ + readonly is_mining_tool: boolean + /** + * If this is an armor item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_armor View documentation} + */ + readonly is_armor: boolean + /** + * If this is a repair tool item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_repair_tool View documentation} + */ + readonly is_repair_tool: boolean + /** + * If this is an item with label item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_item_with_label View documentation} + */ + readonly is_item_with_label: boolean + /** + * If this is an item with inventory item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_item_with_inventory View documentation} + */ + readonly is_item_with_inventory: boolean + /** + * If this is an item with entity data item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_item_with_entity_data View documentation} + */ + readonly is_item_with_entity_data: boolean + /** + * If this is a selection tool item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_selection_tool View documentation} + */ + readonly is_selection_tool: boolean + /** + * If this is an item with tags item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_item_with_tags View documentation} + */ + readonly is_item_with_tags: boolean + /** + * If this is a deconstruction tool item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_deconstruction_item View documentation} + */ + readonly is_deconstruction_item: boolean + /** + * If this is a upgrade item. + * + * {@link https://lua-api.factorio.com/next/LuaItemStack.html#LuaItemStack.is_upgrade_item View documentation} + */ + readonly is_upgrade_item: boolean + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaItemStack" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Control behavior for lamps. + * + * {@link https://lua-api.factorio.com/next/LuaLampControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaLampControlBehavior extends LuaGenericOnOffControlBehavior { + /** + * `true` if the lamp should set the color from the circuit network signals. + * + * {@link https://lua-api.factorio.com/next/LuaLampControlBehavior.html#LuaLampControlBehavior.use_colors View documentation} + */ + use_colors: boolean + /** + * The color the lamp is showing or `nil` if not using any color. + * + * {@link https://lua-api.factorio.com/next/LuaLampControlBehavior.html#LuaLampControlBehavior.color View documentation} + */ + readonly color: ColorTable | undefined + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaLampControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A lazily loaded value. For performance reasons, we sometimes return a custom lazily-loaded value type instead of the + * native Lua value. This custom type lazily constructs the necessary value when + * {@link LuaLazyLoadedValue.get LuaLazyLoadedValue::get} is called, therefore preventing its unnecessary construction in + * some cases. + * + * An instance of LuaLazyLoadedValue is only valid during the event it was created from and cannot be saved. + * + * {@link https://lua-api.factorio.com/next/LuaLazyLoadedValue.html View documentation} + * + * @noSelf + */ +interface LuaLazyLoadedValue { + /** + * Gets the value of this lazy loaded value. + * + * {@link https://lua-api.factorio.com/next/LuaLazyLoadedValue.html#LuaLazyLoadedValue.get View documentation} + */ + get(): T + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaLazyLoadedValue" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Logistic cell of a particular {@link LuaEntity}. A "Logistic Cell" is the given name for settings and properties used + * by what would normally be seen as a "Roboport". A logistic cell however doesn't have to be attached to the roboport + * entity (the character has one for the personal roboport). + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html View documentation} + * + * @noSelf + */ +interface LuaLogisticCell { + /** + * Is a given position within the logistic range of this cell? + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.is_in_logistic_range View documentation} + * + * @param position + */ + is_in_logistic_range(position: Position): boolean + /** + * Is a given position within the construction range of this cell? + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.is_in_construction_range View documentation} + * + * @param position + */ + is_in_construction_range(position: Position): boolean + /** + * Are two cells neighbours? + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.is_neighbour_with View documentation} + * + * @param other + */ + is_neighbour_with(other: LuaLogisticCell): boolean + /** + * Logistic radius of this cell. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.logistic_radius View documentation} + */ + readonly logistic_radius: float + /** + * Logistic connection distance of this cell. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.logistics_connection_distance View documentation} + */ + readonly logistics_connection_distance: float + /** + * Construction radius of this cell. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.construction_radius View documentation} + */ + readonly construction_radius: float + /** + * Number of stationed logistic robots in this cell. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.stationed_logistic_robot_count View documentation} + */ + readonly stationed_logistic_robot_count: uint + /** + * Number of stationed construction robots in this cell. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.stationed_construction_robot_count View documentation} + */ + readonly stationed_construction_robot_count: uint + /** + * `true` if this is a mobile cell. In vanilla, only the logistic cell created by a character's personal roboport is mobile. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.mobile View documentation} + */ + readonly mobile: boolean + /** + * `true` if this cell is active. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.transmitting View documentation} + */ + readonly transmitting: boolean + /** + * Radius at which the robots hover when waiting to be charged. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.charge_approach_distance View documentation} + */ + readonly charge_approach_distance: float + /** + * Number of robots currently charging. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.charging_robot_count View documentation} + */ + readonly charging_robot_count: uint + /** + * Number of robots waiting to charge. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.to_charge_robot_count View documentation} + */ + readonly to_charge_robot_count: uint + /** + * This cell's owner. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.owner View documentation} + */ + readonly owner: LuaEntity + /** + * The network that owns this cell or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.logistic_network View documentation} + */ + readonly logistic_network: LuaLogisticNetwork | undefined + /** + * Neighbouring cells. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.neighbours View documentation} + */ + readonly neighbours: LuaLogisticCell[] + /** + * Robots currently being charged. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.charging_robots View documentation} + */ + readonly charging_robots: LuaEntity[] + /** + * Robots waiting to charge. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticCell.html#LuaLogisticCell.to_charge_robots View documentation} + */ + readonly to_charge_robots: LuaEntity[] + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaLogisticCell" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Control behavior for logistic chests. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticContainerControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaLogisticContainerControlBehavior extends LuaControlBehavior { + /** + * The circuit mode of operations for the logistic container. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticContainerControlBehavior.html#LuaLogisticContainerControlBehavior.circuit_mode_of_operation View documentation} + */ + circuit_mode_of_operation: defines.control_behavior.logistic_container.circuit_mode_of_operation + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaLogisticContainerControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A single logistic network of a given force on a given surface. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html View documentation} + * + * @noSelf + */ +interface LuaLogisticNetwork { + /** + * Count given or all items in the network or given members. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.get_item_count View documentation} + * + * @param item - Item name to count. If not given, gives counts of all items in the network. + * @param member - Logistic members to check, must be either `"storage"` or `"providers"`. If not given, gives count + * in the entire network. + */ + get_item_count(item?: string, member?: "storage" | "providers"): int + /** + * Get item counts for the entire network. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.get_contents View documentation} + * + * @returns A mapping of item prototype names to the number available in the network. + * @see {@link LuaInventory.get_contents} + */ + get_contents(): Record + /** + * Remove items from the logistic network. This will actually remove the items from some logistic chests. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.remove_item View documentation} + * + * @param item - What to remove. + * @param members - Which logistic members to remove from. Must be `"storage"`, `"passive-provider"`, `"buffer"`, or + * `"active-provider"`. If not specified, removes from the network in the usual order. + * @returns Number of items removed. + */ + remove_item( + item: ItemStackIdentification, + members?: "storage" | "passive-provider" | "buffer" | "active-provider" + ): uint + /** + * Insert items into the logistic network. This will actually insert the items into some logistic chests. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.insert View documentation} + * + * @param item - What to insert. + * @param members - Which logistic members to insert the items to. Must be `"storage"`, `"storage-empty"` (storage + * chests that are completely empty), `"storage-empty-slot"` (storage chests that have an empty slot), or + * `"requester"`. If not specified, inserts items into the logistic network in the usual order. + * @returns Number of items actually inserted. + */ + insert( + item: ItemStackIdentification, + members?: "storage" | "storage-empty" | "storage-empty-slot" | "requester" + ): uint + /** + * Find logistic cell closest to a given position. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.find_cell_closest_to View documentation} + * + * @param position + * @returns May be `nil` if no cell was found. + */ + find_cell_closest_to(position: Position): LuaLogisticCell | undefined + /** + * Find the 'best' logistic point with this item ID and from the given position or from given chest type. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.select_pickup_point View documentation} + * + * @returns May be `nil` if no point was found. + */ + select_pickup_point(params: { + /** Name of the item to select. */ + readonly name: string + /** When given, it will find the storage 'best' storage point from this position. */ + readonly position?: Position + /** Whether to consider buffer chests or not. Defaults to false. Only considered if selecting with position. */ + readonly include_buffers?: boolean + /** + * When given, it will find from only the specific type of member. Must be `"storage"`, `"passive-provider"`, + * `"buffer"` or `"active-provider"`. If not specified, selects with normal priorities. Not considered if + * position is specified. + */ + readonly members?: "storage" | "passive-provider" | "buffer" | "active-provider" + }): LuaLogisticPoint | undefined + /** + * Find a logistic point to drop the specific item stack. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.select_drop_point View documentation} + * + * @returns May be `nil` if no point was found. + */ + select_drop_point(params: { + /** Name of the item to select. */ + readonly stack: ItemStackIdentification + /** + * When given, it will find from only the specific type of member. Must be `"storage"`, `"storage-empty"`, + * `"storage-empty-slot"` or `"requester"`. If not specified, selects with normal priorities. + */ + readonly members?: "storage" | "storage-empty" | "storage-empty-slot" | "requester" + }): LuaLogisticPoint | undefined + /** + * The force this logistic network belongs to. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.force View documentation} + */ + readonly force: LuaForce + /** + * Number of logistic robots available for a job. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.available_logistic_robots View documentation} + */ + readonly available_logistic_robots: uint + /** + * The total number of logistic robots in the network (idle and active + in roboports). + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.all_logistic_robots View documentation} + */ + readonly all_logistic_robots: uint + /** + * Number of construction robots available for a job. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.available_construction_robots View documentation} + */ + readonly available_construction_robots: uint + /** + * The total number of construction robots in the network (idle and active + in roboports). + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.all_construction_robots View documentation} + */ + readonly all_construction_robots: uint + /** + * Maximum number of robots the network can work with. Currently only used for the personal roboport. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.robot_limit View documentation} + */ + readonly robot_limit: uint + /** + * All cells in this network. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.cells View documentation} + */ + readonly cells: LuaLogisticCell[] + /** + * All entities that have logistic provider points in this network. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.providers View documentation} + */ + readonly providers: LuaEntity[] + /** + * All entities that have empty logistic provider points in this network. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.empty_providers View documentation} + */ + readonly empty_providers: LuaEntity[] + /** + * All entities that have logistic requester points in this network. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.requesters View documentation} + */ + readonly requesters: LuaEntity[] + /** + * All entities that have logistic storage points in this network. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.storages View documentation} + */ + readonly storages: LuaEntity[] + /** + * All other entities that have logistic points in this network (inserters mostly). + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.logistic_members View documentation} + */ + readonly logistic_members: LuaEntity[] + /** + * All things that have provider points in this network. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.provider_points View documentation} + */ + readonly provider_points: LuaLogisticPoint[] + /** + * All passive provider points in this network. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.passive_provider_points View documentation} + */ + readonly passive_provider_points: LuaLogisticPoint[] + /** + * All active provider points in this network. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.active_provider_points View documentation} + */ + readonly active_provider_points: LuaLogisticPoint[] + /** + * All things that have empty provider points in this network. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.empty_provider_points View documentation} + */ + readonly empty_provider_points: LuaLogisticPoint[] + /** + * All things that have requester points in this network. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.requester_points View documentation} + */ + readonly requester_points: LuaLogisticPoint[] + /** + * All things that have storage points in this network. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.storage_points View documentation} + */ + readonly storage_points: LuaLogisticPoint[] + /** + * All robots in this logistic network. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.robots View documentation} + */ + readonly robots: LuaEntity[] + /** + * All construction robots in this logistic network. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.construction_robots View documentation} + */ + readonly construction_robots: LuaEntity[] + /** + * All logistic robots in this logistic network. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticNetwork.html#LuaLogisticNetwork.logistic_robots View documentation} + */ + readonly logistic_robots: LuaEntity[] + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaLogisticNetwork" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Logistic point of a particular {@link LuaEntity}. A "Logistic point" is the name given for settings and properties + * used by requester, provider, and storage points in a given logistic network. These "points" don't have to be a + * logistic container but often are. One other entity that can own several points is the "character" character type entity. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html View documentation} + * + * @noSelf + */ +interface LuaLogisticPoint { + /** + * The {@link LuaEntity} owner of this {@link LuaLogisticPoint}. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html#LuaLogisticPoint.owner View documentation} + */ + readonly owner: LuaEntity + readonly logistic_network: LuaLogisticNetwork + /** + * The Logistic member index of this logistic point. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html#LuaLogisticPoint.logistic_member_index View documentation} + */ + readonly logistic_member_index: uint + /** + * The logistic filters for this logistic point or `nil` if this doesn't use logistic filters. + * + * **Note**: The returned array will always have an entry for each filter and will be indexed in sequence when not nil. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html#LuaLogisticPoint.filters View documentation} + */ + readonly filters: LogisticFilter[] | undefined + /** + * The logistic mode. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html#LuaLogisticPoint.mode View documentation} + */ + readonly mode: defines.logistic_mode + /** + * The force of this logistic point. + * + * **Note**: This will always be the same as the {@link LuaLogisticPoint.owner LuaLogisticPoint::owner} force. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html#LuaLogisticPoint.force View documentation} + */ + readonly force: LuaForce + /** + * Items targeted to be picked up from this logistic point by robots. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html#LuaLogisticPoint.targeted_items_pickup View documentation} + */ + readonly targeted_items_pickup: Record + /** + * Items targeted to be dropped off into this logistic point by robots. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html#LuaLogisticPoint.targeted_items_deliver View documentation} + */ + readonly targeted_items_deliver: Record + /** + * If this logistic point is using the exact mode. In exact mode robots never over-deliver requests. + * + * {@link https://lua-api.factorio.com/next/LuaLogisticPoint.html#LuaLogisticPoint.exact View documentation} + */ + readonly exact: boolean + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaLogisticPoint" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Control behavior for mining drills. + * + * {@link https://lua-api.factorio.com/next/LuaMiningDrillControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaMiningDrillControlBehavior extends LuaGenericOnOffControlBehavior { + /** + * `true` if this drill is enabled or disabled using the logistics or circuit condition. + * + * {@link https://lua-api.factorio.com/next/LuaMiningDrillControlBehavior.html#LuaMiningDrillControlBehavior.circuit_enable_disable View documentation} + */ + circuit_enable_disable: boolean + /** + * `true` if this drill should send the resources in the field to the circuit network. Which resources depends on + * {@link LuaMiningDrillControlBehavior.resource_read_mode LuaMiningDrillControlBehavior::resource_read_mode} + * + * {@link https://lua-api.factorio.com/next/LuaMiningDrillControlBehavior.html#LuaMiningDrillControlBehavior.circuit_read_resources View documentation} + */ + circuit_read_resources: boolean + /** + * If the mining drill should send just the resources in its area or the entire field it's on to the circuit network. + * + * {@link https://lua-api.factorio.com/next/LuaMiningDrillControlBehavior.html#LuaMiningDrillControlBehavior.resource_read_mode View documentation} + */ + resource_read_mode: defines.control_behavior.mining_drill.resource_read_mode + /** + * The resource entities that the mining drill will send information about to the circuit network or an empty array. + * + * {@link https://lua-api.factorio.com/next/LuaMiningDrillControlBehavior.html#LuaMiningDrillControlBehavior.resource_read_targets View documentation} + */ + readonly resource_read_targets: LuaEntity[] + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaMiningDrillControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a mod setting. + * + * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html View documentation} + * + * @noSelf + */ +interface LuaModSettingPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * The mod that owns this setting. + * + * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.mod View documentation} + */ + readonly mod: string + readonly setting_type: string + /** + * The default value of this setting. + * + * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.default_value View documentation} + */ + readonly default_value: boolean | double | int | string + /** + * The minimum value for this setting or `nil` if this setting type doesn't support a minimum. + * + * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.minimum_value View documentation} + */ + readonly minimum_value: double | int | undefined + /** + * The maximum value for this setting or `nil` if this setting type doesn't support a maximum. + * + * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.maximum_value View documentation} + */ + readonly maximum_value: double | int | undefined + /** + * The allowed values for this setting or `nil` if this setting doesn't use the a fixed set of values. + * + * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.allowed_values View documentation} + */ + readonly allowed_values: string[] | int[] | double[] | undefined + /** + * If this string setting allows blank values or `nil` if not a string setting. + * + * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.allow_blank View documentation} + */ + readonly allow_blank: boolean | undefined + /** + * If this string setting auto-trims values or `nil` if not a string setting. + * + * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.auto_trim View documentation} + */ + readonly auto_trim: boolean | undefined + /** + * If this setting is hidden from the GUI. + * + * {@link https://lua-api.factorio.com/next/LuaModSettingPrototype.html#LuaModSettingPrototype.hidden View documentation} + */ + readonly hidden: boolean + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaModSettingPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a module category. + * + * {@link https://lua-api.factorio.com/next/LuaModuleCategoryPrototype.html View documentation} + * + * @noSelf + */ +interface LuaModuleCategoryPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaModuleCategoryPrototype.html#LuaModuleCategoryPrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaModuleCategoryPrototype.html#LuaModuleCategoryPrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaModuleCategoryPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a named noise expression. + * + * {@link https://lua-api.factorio.com/next/LuaNamedNoiseExpression.html View documentation} + * + * @noSelf + */ +interface LuaNamedNoiseExpression { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaNamedNoiseExpression.html#LuaNamedNoiseExpression.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaNamedNoiseExpression.html#LuaNamedNoiseExpression.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * Name of the property that this expression is intended to provide a value for, if any. + * + * {@link https://lua-api.factorio.com/next/LuaNamedNoiseExpression.html#LuaNamedNoiseExpression.intended_property View documentation} + */ + readonly intended_property: string + /** + * The expression itself. + * + * {@link https://lua-api.factorio.com/next/LuaNamedNoiseExpression.html#LuaNamedNoiseExpression.expression View documentation} + */ + readonly expression: NoiseExpression + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaNamedNoiseExpression" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a noise layer. + * + * {@link https://lua-api.factorio.com/next/LuaNoiseLayerPrototype.html View documentation} + * + * @noSelf + */ +interface LuaNoiseLayerPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaNoiseLayerPrototype.html#LuaNoiseLayerPrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaNoiseLayerPrototype.html#LuaNoiseLayerPrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaNoiseLayerPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of an optimized particle. + * + * {@link https://lua-api.factorio.com/next/LuaParticlePrototype.html View documentation} + * + * @noSelf + */ +interface LuaParticlePrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaParticlePrototype.html#LuaParticlePrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaParticlePrototype.html#LuaParticlePrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + readonly regular_trigger_effect: TriggerEffectItem + readonly ended_in_water_trigger_effect: TriggerEffectItem + readonly render_layer: RenderLayer + readonly render_layer_when_on_ground: RenderLayer + readonly life_time: uint + readonly regular_trigger_effect_frequency: uint + readonly movement_modifier_when_on_ground: float + readonly movement_modifier: float + readonly mining_particle_frame_speed: float + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaParticlePrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A permission group that defines what players in this group are allowed to do. + * + * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html View documentation} + * + * @noSelf + */ +interface LuaPermissionGroup { + /** + * Adds the given player to this group. + * + * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html#LuaPermissionGroup.add_player View documentation} + * + * @param player + * @returns If the player was added. + */ + add_player(player: PlayerIdentification): boolean + /** + * Removes the given player from this group. + * + * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html#LuaPermissionGroup.remove_player View documentation} + * + * @param player + * @returns If the player was removed. + */ + remove_player(player: PlayerIdentification): boolean + /** + * Whether this group allows the given action. + * + * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html#LuaPermissionGroup.allows_action View documentation} + * + * @param action - The action in question. + */ + allows_action(action: defines.input_action): boolean + /** + * Sets whether this group allows the performance the given action. + * + * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html#LuaPermissionGroup.set_allows_action View documentation} + * + * @param action - The action in question. + * @param allow_action - Whether to allow the specified action. + * @returns Whether the value was successfully applied. + */ + set_allows_action(action: defines.input_action, allow_action: boolean): boolean + /** + * Destroys this group. + * + * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html#LuaPermissionGroup.destroy View documentation} + * + * @returns Whether the group was successfully destroyed. + */ + destroy(): boolean + /** + * The name of this group. + * + * **Note**: Setting the name to `nil` or an empty string sets the name to the default value. + * + * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html#LuaPermissionGroup.name View documentation} + */ + name: string + /** + * The players in this group. + * + * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html#LuaPermissionGroup.players View documentation} + */ + readonly players: LuaPlayer[] + /** + * The group ID + * + * {@link https://lua-api.factorio.com/next/LuaPermissionGroup.html#LuaPermissionGroup.group_id View documentation} + */ + readonly group_id: uint + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaPermissionGroup" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * All permission groups. + * + * {@link https://lua-api.factorio.com/next/LuaPermissionGroups.html View documentation} + * + * @noSelf + */ +interface LuaPermissionGroups { + /** + * Creates a new permission group. + * + * **Note**: May return nil if the calling player doesn't have permission to make groups. + * + * {@link https://lua-api.factorio.com/next/LuaPermissionGroups.html#LuaPermissionGroups.create_group View documentation} + * + * @param name + */ + create_group(name?: string): LuaPermissionGroup | undefined + /** + * Gets the permission group with the given name or group ID or `nil` if there is no matching group. + * + * {@link https://lua-api.factorio.com/next/LuaPermissionGroups.html#LuaPermissionGroups.get_group View documentation} + * + * @param group + */ + get_group(group: string | uint): LuaPermissionGroup | undefined + /** + * All of the permission groups. + * + * {@link https://lua-api.factorio.com/next/LuaPermissionGroups.html#LuaPermissionGroups.groups View documentation} + */ + readonly groups: LuaPermissionGroup[] + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaPermissionGroups" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A player in the game. Pay attention that a player may or may not have a character, which is the {@link LuaEntity} of + * the little guy running around the world doing things. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html View documentation} + * + * @noSelf + */ +interface LuaPlayer extends LuaControl { + /** + * Setup the screen to be shown when the game is finished. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.set_ending_screen_data View documentation} + * + * @param message - Message to be shown. + * @param file - Path to image to be shown. + */ + set_ending_screen_data(message: LocalisedString, file?: string): void + /** + * Print text to the chat console. + * + * **Note**: Messages that are identical to a message sent in the last 60 ticks are not printed again. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.print View documentation} + * + * @param message + * @param color + */ + print(message: LocalisedString, color?: Color): void + /** + * Clear the chat console. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.clear_console View documentation} + */ + clear_console(): void + /** + * Get the current goal description, as a localised string. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.get_goal_description View documentation} + */ + get_goal_description(): LocalisedString + /** + * Set the text in the goal window (top left). + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.set_goal_description View documentation} + * + * @param text - The text to display. Lines can be delimited with `\n`. Passing an empty string or omitting this + * parameter entirely will make the goal window disappear. + * @param only_update - When `true`, won't play the "goal updated" sound. + */ + set_goal_description(text?: LocalisedString, only_update?: boolean): void + /** + * Set the controller type of the player. + * + * **Note**: Setting a player to {@link defines.controllers.editor} auto promotes the player to admin and enables cheat mode. + * + * **Note**: Setting a player to {@link defines.controllers.editor} also requires the calling player be an admin. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.set_controller View documentation} + */ + set_controller(params: { + /** Which controller to use. */ + readonly type: defines.controllers + /** Entity to control. Mandatory when `type` is {@link defines.controllers.character}, ignored otherwise. */ + readonly character?: LuaEntity + /** + * List of waypoints for the cutscene controller. This parameter is mandatory when `type` is + * {@link defines.controllers.cutscene}. + */ + readonly waypoints?: CutsceneWaypoint + /** + * If specified and `type` is {@link defines.controllers.cutscene}, the cutscene will start at this position. If + * not given the start position will be the player position. + */ + readonly start_position?: Position + /** + * If specified and `type` is {@link defines.controllers.cutscene}, the cutscene will start at this zoom level. + * If not given the start zoom will be the players zoom. + */ + readonly start_zoom?: double + /** + * If specified and `type` is {@link defines.controllers.cutscene}, it is the time in ticks it will take for the + * camera to pan from the final waypoint back to the starting position. If not given the camera will not pan + * back to the start position/zoom. + */ + readonly final_transition_time?: uint + /** + * If specified and `type` is {@link defines.controllers.cutscene}, the game will switch to chart-mode (map + * zoomed out) rendering when the zoom level is less than this value. + */ + readonly chart_mode_cutoff?: double + }): void + /** + * Start/end wire dragging at the specified location, wire type is based on the cursor contents + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.drag_wire View documentation} + * + * @returns `true` if the action did something + */ + drag_wire(params: { + /** + * Position at which cursor was clicked. Used only to decide which side of arithmetic combinator, decider + * combinator or power switch is to be connected. Entity itself to be connected is based on the player's selected entity. + */ + readonly position: Position + }): boolean + /** + * Disable recipe groups. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.disable_recipe_groups View documentation} + */ + disable_recipe_groups(): void + /** + * Enable recipe groups. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.enable_recipe_groups View documentation} + */ + enable_recipe_groups(): void + /** + * Disable recipe subgroups. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.disable_recipe_subgroups View documentation} + */ + disable_recipe_subgroups(): void + /** + * Enable recipe subgroups. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.enable_recipe_subgroups View documentation} + */ + enable_recipe_subgroups(): void + /** + * Print entity statistics to the player's console. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.print_entity_statistics View documentation} + * + * @param entities - Entity prototypes to get statistics for. If not specified or empty, display statistics for all entities. + */ + print_entity_statistics(entities?: string[]): void + /** + * Print construction robot job counts to the players console. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.print_robot_jobs View documentation} + */ + print_robot_jobs(): void + /** + * Print LuaObject counts per mod. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.print_lua_object_statistics View documentation} + */ + print_lua_object_statistics(): void + /** + * Logs a dictionary of chunks -> active entities for the surface this player is on. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.log_active_entity_chunk_counts View documentation} + */ + log_active_entity_chunk_counts(): void + /** + * Logs a dictionary of active entities -> count for the surface this player is on. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.log_active_entity_counts View documentation} + */ + log_active_entity_counts(): void + /** + * Unlock the achievements of the given player. This has any effect only when this is the local player, the + * achievement isn't unlocked so far and the achievement is of the type "achievement". + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.unlock_achievement View documentation} + * + * @param name - Name of the achievement to unlock + */ + unlock_achievement(name: string): void + /** + * Invokes the "clear cursor" action on the player as if the user pressed it. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.clear_cursor View documentation} + * + * @returns If the cursor is now empty. + */ + clear_cursor(): boolean + /** + * Creates and attaches a character entity to this player. + * + * **Note**: The player must not have a character already connected and must be online (see + * {@link LuaPlayer.connected LuaPlayer::connected}). + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.create_character View documentation} + * + * @param character - The character to create else the default is used. + * @returns Whether the character was created. + */ + create_character(character?: string): boolean + /** + * Adds an alert to this player for the given entity of the given alert type. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.add_alert View documentation} + * + * @param entity + * @param type + */ + add_alert(entity: LuaEntity, type: defines.alert_type): void + /** + * Adds a custom alert to this player. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.add_custom_alert View documentation} + * + * @param entity - If the alert is clicked, the map will open at the position of this entity. + * @param icon + * @param message + * @param show_on_map + */ + add_custom_alert(entity: LuaEntity, icon: SignalID, message: LocalisedString, show_on_map: boolean): void + /** + * Removes all alerts matching the given filters or if an empty filters table is given all alerts are removed. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.remove_alert View documentation} + */ + remove_alert(params: { + readonly entity?: LuaEntity + readonly prototype?: LuaEntityPrototype + readonly position?: Position + readonly type?: defines.alert_type + readonly surface?: SurfaceIdentification + readonly icon?: SignalID + readonly message?: LocalisedString + }): void + /** + * Get all alerts matching the given filters, or all alerts if no filters are given. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.get_alerts View documentation} + * + * @returns A mapping of surface index to an array of arrays of {@link Alert alerts} indexed by the + * {@link defines.alert_type alert type}. + */ + get_alerts(params: { + readonly entity?: LuaEntity + readonly prototype?: LuaEntityPrototype + readonly position?: Position + readonly type?: defines.alert_type + readonly surface?: SurfaceIdentification + }): Record> + /** + * Mutes alerts for the given alert category. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.mute_alert View documentation} + * + * @param alert_type + * @returns If the alert type was muted (false if it was already muted). + */ + mute_alert(alert_type: defines.alert_type): boolean + /** + * Unmutes alerts for the given alert category. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.unmute_alert View documentation} + * + * @param alert_type + * @returns If the alert type was unmuted (false if it was wasn't muted). + */ + unmute_alert(alert_type: defines.alert_type): boolean + /** + * If the given alert type is currently muted. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.is_alert_muted View documentation} + * + * @param alert_type + */ + is_alert_muted(alert_type: defines.alert_type): boolean + /** + * Enables alerts for the given alert category. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.enable_alert View documentation} + * + * @param alert_type + * @returns If the alert type was enabled (false if it was already enabled). + */ + enable_alert(alert_type: defines.alert_type): boolean + /** + * Disables alerts for the given alert category. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.disable_alert View documentation} + * + * @param alert_type + * @returns If the alert type was disabled (false if it was already disabled). + */ + disable_alert(alert_type: defines.alert_type): boolean + /** + * If the given alert type is currently enabled. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.is_alert_enabled View documentation} + * + * @param alert_type + */ + is_alert_enabled(alert_type: defines.alert_type): boolean + /** + * Invokes the "smart pipette" action on the player as if the user pressed it. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.pipette_entity View documentation} + * + * @param entity + * @returns If the smart pipette found something to place + */ + pipette_entity(entity: string | LuaEntity | LuaEntityPrototype): boolean + /** + * Checks if this player can build the give entity at the given location on the surface the player is on. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.can_place_entity View documentation} + */ + can_place_entity(params: { + /** Name of the entity to check */ + readonly name: string + /** Where the entity would be placed */ + readonly position: Position + /** Direction the entity would be placed */ + readonly direction?: defines.direction + }): boolean + /** + * Checks if this player can build what ever is in the cursor on the surface the player is on. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.can_build_from_cursor View documentation} + */ + can_build_from_cursor(params: { + /** Where the entity would be placed */ + readonly position: Position + /** Direction the entity would be placed */ + readonly direction?: defines.direction + /** If alt build should be used instead of normal build. Defaults to normal. */ + readonly alt?: boolean + /** The size for building terrain if building terrain. Defaults to 2. */ + readonly terrain_building_size?: uint + /** If chunks covered by fog-of-war are skipped. */ + readonly skip_fog_of_war?: boolean + }): boolean + /** + * Builds what ever is in the cursor on the surface the player is on. + * + * **Note**: Anything built will fire normal player-built events. + * + * **Note**: The cursor stack will automatically be reduced as if the player built normally. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.build_from_cursor View documentation} + */ + build_from_cursor(params: { + /** Where the entity would be placed */ + readonly position: Position + /** Direction the entity would be placed */ + readonly direction?: defines.direction + /** If alt build should be used instead of normal build. Defaults to normal. */ + readonly alt?: boolean + /** The size for building terrain if building terrain. Defaults to 2. */ + readonly terrain_building_size?: uint + /** If chunks covered by fog-of-war are skipped. */ + readonly skip_fog_of_war?: boolean + }): void + /** + * Uses the current item in the cursor if it's a capsule or does nothing if not. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.use_from_cursor View documentation} + * + * @param position - Where the item would be used. + */ + use_from_cursor(position: Position): void + /** + * Play a sound for this player. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.play_sound View documentation} + */ + play_sound(params: { + /** The sound to play. */ + readonly path: SoundPath + /** Where the sound should be played. If not given, it's played at the current position of the player. */ + readonly position?: Position + /** The volume of the sound to play. Must be between 0 and 1 inclusive. */ + readonly volume_modifier?: double + /** The volume mixer to play the sound through. Defaults to the default mixer for the given sound type. */ + readonly override_sound_type?: SoundType + }): void + /** + * The characters associated with this player. + * + * **Note**: The array will always be empty when the player is disconnected (see + * {@link LuaPlayer.connected LuaPlayer::connected}) regardless of there being associated characters. + * + * **Note**: Characters associated with this player will be logged off when this player disconnects but are not + * controlled by any player. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.get_associated_characters View documentation} + */ + get_associated_characters(): LuaEntity[] + /** + * Associates a character with this player. + * + * **Note**: The character must not be connected to any controller. + * + * **Note**: If this player is currently disconnected (see {@link LuaPlayer.connected LuaPlayer::connected}) the + * character will be immediately "logged off". + * + * **Note**: See {@link LuaPlayer.get_associated_characters LuaPlayer::get_associated_characters} for more information. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.associate_character View documentation} + * + * @param character - The character entity. + */ + associate_character(character: LuaEntity): void + /** + * Disassociates a character from this player. This is functionally the same as setting + * {@link LuaEntity.associated_player LuaEntity::associated_player} to `nil`. + * + * **Note**: See {@link LuaPlayer.get_associated_characters LuaPlayer::get_associated_characters} for more information. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.disassociate_character View documentation} + * + * @param character - The character entity + */ + disassociate_character(character: LuaEntity): void + /** + * Spawn flying text that is only visible to this player. Either `position` or `create_at_cursor` are required. When + * `create_at_cursor` is `true`, all parameters other than `text` are ignored. + * + * **Note**: If no custom `speed` is set and the text is longer than 25 characters, its `time_to_live` and `speed` + * are dynamically adjusted to give players more time to read it. + * + * **Note**: Local flying text is not saved, which means it will disappear after a save/load-cycle. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.create_local_flying_text View documentation} + */ + create_local_flying_text(params: { + /** The flying text to show. */ + readonly text: LocalisedString + /** The location on the map at which to show the flying text. */ + readonly position?: Position + /** If `true`, the flying text is created at the player's cursor. Defaults to `false`. */ + readonly create_at_cursor?: boolean + /** The color of the flying text. Defaults to white text. */ + readonly color?: Color + /** The amount of ticks that the flying text will be shown for. Defaults to `80`. */ + readonly time_to_live?: uint + /** The speed at which the text rises upwards in tiles/second. Can't be a negative value. */ + readonly speed?: double + }): void + /** + * Gets the quick bar filter for the given slot or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.get_quick_bar_slot View documentation} + * + * @param index - The slot index. 1 for the first slot of page one, 2 for slot two of page one, 11 for the first + * slot of page 2, etc. + */ + get_quick_bar_slot(index: uint): LuaItemPrototype | undefined + /** + * Sets the quick bar filter for the given slot. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.set_quick_bar_slot View documentation} + * + * @param index - The slot index. 1 for the first slot of page one, 2 for slot two of page one, 11 for the first + * slot of page 2, etc. + * @param filter - The filter or `nil`. + */ + set_quick_bar_slot(index: uint, filter: string | LuaItemPrototype | LuaItemStack | undefined): void + /** + * Gets which quick bar page is being used for the given screen page or `nil` if not known. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.get_active_quick_bar_page View documentation} + * + * @param index - The screen page. Index 1 is the top row in the gui. Index can go beyond the visible number of bars + * on the screen to account for the interface config setting change. + */ + get_active_quick_bar_page(index: uint): uint8 | undefined + /** + * Sets which quick bar page is being used for the given screen page. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.set_active_quick_bar_page View documentation} + * + * @param screen_index - The screen page. Index 1 is the top row in the gui. Index can go beyond the visible number + * of bars on the screen to account for the interface config setting change. + * @param page_index - The new quick bar page. + */ + set_active_quick_bar_page(screen_index: uint, page_index: uint): void + /** + * Jump to the specified cutscene waypoint. Only works when the player is viewing a cutscene. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.jump_to_cutscene_waypoint View documentation} + * + * @param waypoint_index + */ + jump_to_cutscene_waypoint(waypoint_index: uint): void + /** + * Exit the current cutscene. Errors if not in a cutscene. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.exit_cutscene View documentation} + */ + exit_cutscene(): void + /** + * Queues a request to open the map at the specified position. If the map is already opened, the request will simply + * set the position (and scale). Render mode change requests are processed before rendering of the next frame. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.open_map View documentation} + * + * @param position + * @param scale + */ + open_map(position: Position, scale?: double): void + /** + * Queues a request to zoom to world at the specified position. If the player is already zooming to world, the + * request will simply set the position (and scale). Render mode change requests are processed before rendering of + * the next frame. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.zoom_to_world View documentation} + * + * @param position + * @param scale + */ + zoom_to_world(position: Position, scale?: double): void + /** + * Queues request to switch to the normal game view from the map or zoom to world view. Render mode change requests + * are processed before rendering of the next frame. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.close_map View documentation} + */ + close_map(): void + /** + * Is a custom Lua shortcut currently toggled? + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.is_shortcut_toggled View documentation} + * + * @param prototype_name - Prototype name of the custom shortcut. + */ + is_shortcut_toggled(prototype_name: string): boolean + /** + * Is a custom Lua shortcut currently available? + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.is_shortcut_available View documentation} + * + * @param prototype_name - Prototype name of the custom shortcut. + */ + is_shortcut_available(prototype_name: string): boolean + /** + * Toggle or untoggle a custom Lua shortcut + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.set_shortcut_toggled View documentation} + * + * @param prototype_name - Prototype name of the custom shortcut. + * @param toggled + */ + set_shortcut_toggled(prototype_name: string, toggled: boolean): void + /** + * Make a custom Lua shortcut available or unavailable. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.set_shortcut_available View documentation} + * + * @param prototype_name - Prototype name of the custom shortcut. + * @param available + */ + set_shortcut_available(prototype_name: string, available: boolean): void + /** + * Asks the player if they would like to connect to the given server. + * + * **Note**: This only does anything when used on a multiplayer peer. Single player and server hosts will ignore the prompt. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.connect_to_server View documentation} + */ + connect_to_server(params: { + /** The server (address:port) if port is not given the default Factorio port is used. */ + readonly address: string + /** The name of the server. */ + readonly name?: LocalisedString + readonly description?: LocalisedString + /** + * The password if different from the one used to join this game. Note, if the current password is not empty but + * the one required to join the new server is an empty string should be given for this field. + */ + readonly password?: string + }): void + /** + * Toggles this player into or out of the map editor. Does nothing if this player isn't an admin or if the player + * doesn't have permission to use the map editor. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.toggle_map_editor View documentation} + */ + toggle_map_editor(): void + /** + * Requests a translation for the given localised string. If the request is successful the + * {@link OnStringTranslatedEvent on_string_translated} event will be fired at a later time with the results. + * + * **Note**: Does nothing if this player is not connected. (see {@link LuaPlayer.connected LuaPlayer::connected}). + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.request_translation View documentation} + * + * @param localised_string + * @returns If the request was sent or not. + */ + request_translation(localised_string: LocalisedString): boolean + /** + * Gets the filter for this map editor infinity filters at the given index or `nil` if the filter index doesn't + * exist or is empty. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.get_infinity_inventory_filter View documentation} + * + * @param index - The index to get. + */ + get_infinity_inventory_filter(index: uint): InfinityInventoryFilter | undefined + /** + * Sets the filter for this map editor infinity filters at the given index. + * + * *Can only be used if this is InfinityContainer* + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.set_infinity_inventory_filter View documentation} + * + * @param index - The index to set. + * @param filter - The new filter or `nil` to clear the filter. + */ + set_infinity_inventory_filter(index: uint, filter: InfinityInventoryFilter | undefined): void + /** + * Clears all recipe notifications for this player. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.clear_recipe_notifications View documentation} + */ + clear_recipe_notifications(): void + /** + * Adds the given recipe to the list of recipe notifications for this player. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.add_recipe_notification View documentation} + * + * @param recipe - Name of the recipe prototype to add. + */ + add_recipe_notification(recipe: string): void + /** + * Adds the given blueprint to this player's clipboard queue. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.add_to_clipboard View documentation} + * + * @param blueprint - The blueprint to add. + */ + add_to_clipboard(blueprint: LuaItemStack): void + /** + * Gets a copy of the currently selected blueprint in the clipboard queue into the player's cursor, as if the player + * activated Paste. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.activate_paste View documentation} + */ + activate_paste(): void + /** + * Starts selection with selection tool from the specified position. Does nothing if the players cursor is not a + * selection tool. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.start_selection View documentation} + * + * @param position - The position to start selection from. + * @param selection_mode - The type of selection to start. Can be `select`, `alternative-select`, `reverse-select`. + */ + start_selection(position: Position, selection_mode: string): void + /** + * Clears the players selection tool selection position. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.clear_selection View documentation} + */ + clear_selection(): void + /** + * The character attached to this player, or `nil` if no character. + * + * **Note**: Will also return `nil` when the player is disconnected (see {@link LuaPlayer.connected LuaPlayer::connected}). + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.character View documentation} + */ + character: LuaEntity | undefined + /** + * When in a cutscene; the character this player would be using once the cutscene is over. + * + * **Note**: Will also return `nil` when the player is disconnected (see {@link LuaPlayer.connected LuaPlayer::connected}). + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.cutscene_character View documentation} + */ + readonly cutscene_character: LuaEntity | undefined + /** + * This player's index in {@link LuaGameScript.players LuaGameScript::players}. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.index View documentation} + */ + readonly index: uint + readonly gui: LuaGui + /** + * `true` if the player opened itself. I.e. if they opened the character or god-controller GUI. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.opened_self View documentation} + */ + readonly opened_self: boolean + readonly controller_type: defines.controllers + /** + * The stashed controller type or `nil` if no controller is stashed. + * + * **Note**: This is mainly useful when a player is in the map editor. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.stashed_controller_type View documentation} + */ + readonly stashed_controller_type: defines.controllers | undefined + /** + * The player's game view settings. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.game_view_settings View documentation} + */ + game_view_settings: GameViewSettings + /** + * `true` if the minimap is visible. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.minimap_enabled View documentation} + */ + minimap_enabled: boolean + /** + * The color associated with the player. This will be used to tint the player's character as well as their buildings + * and vehicles. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.color View documentation} + */ + color: Color + /** + * The color used when this player talks in game. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.chat_color View documentation} + */ + chat_color: Color + /** + * The player's username. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.name View documentation} + */ + readonly name: string + /** + * The tag that is shown after the player in chat and on the map. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.tag View documentation} + */ + tag: string + /** + * `true` if the player is currently connected to the game. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.connected View documentation} + */ + readonly connected: boolean + /** + * `true` if the player is an admin. + * + * **Note**: Trying to change player admin status from the console when you aren't an admin does nothing. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.admin View documentation} + */ + admin: boolean + /** + * The source entity used during entity settings copy-paste if any. + * + * `nil` if there isn't currently a source entity. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.entity_copy_source View documentation} + */ + readonly entity_copy_source: LuaEntity | undefined + /** + * How many ticks since the last action of this player + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.afk_time View documentation} + */ + readonly afk_time: uint + /** + * How many ticks did this player spend playing this save (all sessions combined) + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.online_time View documentation} + */ + readonly online_time: uint + /** + * At what tick this player was last online. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.last_online View documentation} + */ + readonly last_online: uint + /** + * The permission group this player is part of or `nil` if not part of any group. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.permission_group View documentation} + */ + permission_group: LuaPermissionGroup | undefined + /** + * Gets the current per-player settings for the this player, indexed by prototype name. Returns the same structure + * as {@link LuaSettings.get_player_settings LuaSettings::get_player_settings}. + * + * **Note**: This can become invalid if during operation this player becomes invalid. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.mod_settings View documentation} + */ + readonly mod_settings: LuaCustomTable + /** + * The number of ticks until this player will respawn or `nil` if not waiting to respawn. + * + * **Note**: Set to `nil` to immediately respawn the player. + * + * **Note**: Set to any positive value to trigger the respawn state for this player. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.ticks_to_respawn View documentation} + */ + ticks_to_respawn: uint | undefined + /** + * The display resolution for this player. + * + * **Note**: During {@link OnPlayerCreatedEvent on_player_created}, this attribute will always return a resolution of + * `{width=1920, height=1080}`. To get the actual resolution, listen to the + * {@link OnPlayerDisplayResolutionChangedEvent on_player_display_resolution_changed} event raised shortly afterwards. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.display_resolution View documentation} + */ + readonly display_resolution: DisplayResolution + /** + * The display scale for this player. + * + * **Note**: During {@link OnPlayerCreatedEvent on_player_created}, this attribute will always return a scale of `1`. + * To get the actual scale, listen to the {@link OnPlayerDisplayScaleChangedEvent on_player_display_scale_changed} + * event raised shortly afterwards. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.display_scale View documentation} + */ + readonly display_scale: double + /** + * The item stack containing a blueprint to be setup. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.blueprint_to_setup View documentation} + */ + readonly blueprint_to_setup: LuaItemStack + /** + * The render mode of the player, like map or zoom to world. The render mode can be set using + * {@link LuaPlayer.open_map LuaPlayer::open_map}, {@link LuaPlayer.zoom_to_world LuaPlayer::zoom_to_world} and + * {@link LuaPlayer.close_map LuaPlayer::close_map}. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.render_mode View documentation} + */ + readonly render_mode: defines.render_mode + /** + * If `true`, zoom-to-world noise effect will be disabled and environmental sounds will be based on zoom-to-world + * view instead of position of player's character. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.spectator View documentation} + */ + spectator: boolean + /** + * If items not included in this map editor infinity inventory filters should be removed. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.remove_unfiltered_items View documentation} + */ + remove_unfiltered_items: boolean + /** + * The filters for this map editor infinity inventory settings. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.infinity_inventory_filters View documentation} + */ + infinity_inventory_filters: InfinityInventoryFilter[] + /** + * If the main inventory will be auto sorted. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.auto_sort_main_inventory View documentation} + */ + readonly auto_sort_main_inventory: boolean + /** + * The original location of the item in the cursor, marked with a hand. When writing, the specified inventory slot + * must be empty and the cursor stack must not be empty. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.hand_location View documentation} + */ + hand_location: ItemStackLocation + /** + * The player's zoom-level. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.zoom View documentation} + */ + set zoom(value: double) + /** + * The player's map view settings. To write to this, use a table containing the fields that should be changed. + * + * {@link https://lua-api.factorio.com/next/LuaPlayer.html#LuaPlayer.map_view_settings View documentation} + */ + set map_view_settings(value: MapViewSettings) + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaPlayer" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * An object used to measure script performance. + * + * **Note**: Since performance is non-deterministic these objects don't allow reading the raw time values from lua. They + * can be used anywhere a {@link LocalisedString} is used. + * + * {@link https://lua-api.factorio.com/next/LuaProfiler.html View documentation} + * + * @noSelf + */ +interface LuaProfiler { + /** + * Resets the clock, also restarting it. + * + * {@link https://lua-api.factorio.com/next/LuaProfiler.html#LuaProfiler.reset View documentation} + */ + reset(): void + /** + * Stops the clock. + * + * {@link https://lua-api.factorio.com/next/LuaProfiler.html#LuaProfiler.stop View documentation} + */ + stop(): void + /** + * Start the clock again, without resetting it. + * + * {@link https://lua-api.factorio.com/next/LuaProfiler.html#LuaProfiler.restart View documentation} + */ + restart(): void + /** + * Add the duration of another timer to this timer. Useful to reduce start/stop overhead when accumulating time onto + * many timers at once. + * + * **Note**: If other is running, the time to now will be added. + * + * {@link https://lua-api.factorio.com/next/LuaProfiler.html#LuaProfiler.add View documentation} + * + * @param other - The timer to add to this timer. + */ + add(other: LuaProfiler): void + /** + * Divides the current duration by a set value. Useful for calculating the average of many iterations. + * + * **Note**: Does nothing if this isn't stopped. + * + * {@link https://lua-api.factorio.com/next/LuaProfiler.html#LuaProfiler.divide View documentation} + * + * @param number - The number to divide by. Must be > 0. + */ + divide(number: double): void + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaProfiler" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Control behavior for programmable speakers. + * + * {@link https://lua-api.factorio.com/next/LuaProgrammableSpeakerControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaProgrammableSpeakerControlBehavior extends LuaControlBehavior { + circuit_parameters: ProgrammableSpeakerCircuitParameters + circuit_condition: CircuitConditionDefinition + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaProgrammableSpeakerControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * An interface to send messages to the calling RCON interface. + * + * {@link https://lua-api.factorio.com/next/LuaRCON.html View documentation} + * + * @noSelf + */ +interface LuaRCON { + /** + * Print text to the calling RCON interface if any. + * + * {@link https://lua-api.factorio.com/next/LuaRCON.html#LuaRCON.print View documentation} + * + * @param message + */ + print(message: LocalisedString): void + /** This object's name. */ + readonly object_name: "LuaRCON" +} + +/** + * Control behavior for rail chain signals. + * + * {@link https://lua-api.factorio.com/next/LuaRailChainSignalControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaRailChainSignalControlBehavior extends LuaControlBehavior { + red_signal: SignalID + orange_signal: SignalID + green_signal: SignalID + blue_signal: SignalID + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaRailChainSignalControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A rail path. + * + * {@link https://lua-api.factorio.com/next/LuaRailPath.html View documentation} + * + * @noSelf + */ +interface LuaRailPath { + /** + * The total number of rails in this path. + * + * {@link https://lua-api.factorio.com/next/LuaRailPath.html#LuaRailPath.size View documentation} + */ + readonly size: uint + /** + * The current rail index. + * + * {@link https://lua-api.factorio.com/next/LuaRailPath.html#LuaRailPath.current View documentation} + */ + readonly current: uint + /** + * The total path distance. + * + * {@link https://lua-api.factorio.com/next/LuaRailPath.html#LuaRailPath.total_distance View documentation} + */ + readonly total_distance: double + /** + * The total distance travelled. + * + * {@link https://lua-api.factorio.com/next/LuaRailPath.html#LuaRailPath.travelled_distance View documentation} + */ + readonly travelled_distance: double + /** + * Array of the rails that this path travels over. + * + * {@link https://lua-api.factorio.com/next/LuaRailPath.html#LuaRailPath.rails View documentation} + */ + readonly rails: LuaCustomTable + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaRailPath" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Control behavior for rail signals. + * + * {@link https://lua-api.factorio.com/next/LuaRailSignalControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaRailSignalControlBehavior extends LuaControlBehavior { + red_signal: SignalID + orange_signal: SignalID + green_signal: SignalID + /** + * If this will close the rail signal based off the circuit condition. + * + * {@link https://lua-api.factorio.com/next/LuaRailSignalControlBehavior.html#LuaRailSignalControlBehavior.close_signal View documentation} + */ + close_signal: boolean + /** + * If this will read the rail signal state. + * + * {@link https://lua-api.factorio.com/next/LuaRailSignalControlBehavior.html#LuaRailSignalControlBehavior.read_signal View documentation} + */ + read_signal: boolean + /** + * The circuit condition when controlling the signal through the circuit network. + * + * {@link https://lua-api.factorio.com/next/LuaRailSignalControlBehavior.html#LuaRailSignalControlBehavior.circuit_condition View documentation} + */ + circuit_condition: CircuitConditionDefinition + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaRailSignalControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A deterministic random generator independent from the core games random generator that can be seeded and re-seeded at + * will. This random generator can be saved and loaded and will maintain its state. Note this is entirely different from + * calling {@link https://lua-api.factorio.com/next/Libraries.html#math.random math.random}() and you should be sure you + * actually want to use this over calling `math.random()`. If you aren't sure if you need to use this over calling + * `math.random()` then you probably don't need to use this. + * + * {@link https://lua-api.factorio.com/next/LuaRandomGenerator.html View documentation} + * + * @example + * Create a generator and use it to print a random number. + * + * ```lua + * global.generator = game.create_random_generator() + * game.player.print(global.generator()) + * ``` + * + * @noSelf + */ +interface LuaRandomGenerator { + /** + * Re-seeds the random generator with the given value. + * + * **Note**: Seeds that are close together will produce similar results. Seeds from 0 to 341 will produce the same results. + * + * {@link https://lua-api.factorio.com/next/LuaRandomGenerator.html#LuaRandomGenerator.re_seed View documentation} + * + * @param seed + */ + re_seed(seed: uint): void + /** + * Generates a random number. If no parameters are given a number in the [0, 1) range is returned. If a single + * parameter is given a floored number in the [1, N] range is returned. If 2 parameters are given a floored number + * in the [N1, N2] range is returned. + * + * {@link https://lua-api.factorio.com/next/LuaRandomGenerator.html#LuaRandomGenerator.operator%20() View documentation} + * + * @param lower - Inclusive lower bound on the result + * @param upper - Inclusive upper bound on the result + */ + (lower?: int, upper?: int): double + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaRandomGenerator" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A crafting recipe. Recipes belong to forces (see {@link LuaForce}) because some recipes are unlocked by research, and + * researches are per-force. + * + * {@link https://lua-api.factorio.com/next/LuaRecipe.html View documentation} + * + * @noSelf + */ +interface LuaRecipe { + /** + * Reload the recipe from the prototype. + * + * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.reload View documentation} + */ + reload(): void + /** + * Name of the recipe. This can be different than the name of the result items as there could be more recipes to + * make the same item. + * + * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.name View documentation} + */ + readonly name: string + /** + * Localised name of the recipe. + * + * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.localised_name View documentation} + */ + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * The prototype for this recipe. + * + * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.prototype View documentation} + */ + readonly prototype: LuaRecipePrototype + /** + * Can the recipe be used? + * + * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.enabled View documentation} + */ + enabled: boolean + /** + * Category of the recipe. + * + * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.category View documentation} + */ + readonly category: string + /** + * Ingredients for this recipe. + * + * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.ingredients View documentation} + * + * @example + * What the "steel-chest" recipe would return + * + * ```lua + * {{type="item", name="steel-plate", amount=8}} + * ``` + * + * @example + * What the "advanced-oil-processing" recipe would return + * + * ```lua + * {{type="fluid", name="crude-oil", amount=10}, {type="fluid", name="water", amount=5}} + * ``` + */ + readonly ingredients: Ingredient[] + /** + * The results of this recipe. + * + * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.products View documentation} + */ + readonly products: Product[] + /** + * Is the recipe hidden? Hidden recipe don't show up in the crafting menu. + * + * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.hidden View documentation} + */ + readonly hidden: boolean + /** + * Is the recipe hidden from flow statistics? + * + * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.hidden_from_flow_stats View documentation} + */ + hidden_from_flow_stats: boolean + /** + * Energy required to execute this recipe. This directly affects the crafting time: Recipe's energy is exactly its + * crafting time in seconds, when crafted in an assembling machine with crafting speed exactly equal to one. + * + * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.energy View documentation} + */ + readonly energy: double + /** + * Order string. This is used to sort the crafting menu. + * + * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.order View documentation} + */ + readonly order: string + /** + * Group of this recipe. + * + * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.group View documentation} + */ + readonly group: LuaGroup + /** + * Subgroup of this recipe. + * + * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.subgroup View documentation} + */ + readonly subgroup: LuaGroup + /** + * The force that owns this recipe. + * + * {@link https://lua-api.factorio.com/next/LuaRecipe.html#LuaRecipe.force View documentation} + */ + readonly force: LuaForce + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaRecipe" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a recipe category. + * + * {@link https://lua-api.factorio.com/next/LuaRecipeCategoryPrototype.html View documentation} + * + * @noSelf + */ +interface LuaRecipeCategoryPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaRecipeCategoryPrototype.html#LuaRecipeCategoryPrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaRecipeCategoryPrototype.html#LuaRecipeCategoryPrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaRecipeCategoryPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A crafting recipe prototype. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html View documentation} + * + * @noSelf + */ +interface LuaRecipePrototype { + /** + * If this recipe prototype is enabled by default (enabled at the beginning of a game). + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.enabled View documentation} + */ + readonly enabled: boolean + /** + * Name of the recipe. This can be different than the name of the result items as there could be more recipes to + * make the same item. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.name View documentation} + */ + readonly name: string + /** + * Localised name of the recipe. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.localised_name View documentation} + */ + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * Category of the recipe. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.category View documentation} + */ + readonly category: string + /** + * Ingredients for this recipe. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.ingredients View documentation} + */ + readonly ingredients: Ingredient[] + /** + * The results of this recipe. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.products View documentation} + */ + readonly products: Product[] + /** + * The main product of this recipe, `nil` if no main product is defined. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.main_product View documentation} + */ + readonly main_product: Product | undefined + /** + * Is the recipe hidden? Hidden recipe don't show up in the crafting menu. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.hidden View documentation} + */ + readonly hidden: boolean + /** + * Is the recipe hidden from flow statistics (item/fluid production statistics)? + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.hidden_from_flow_stats View documentation} + */ + readonly hidden_from_flow_stats: boolean + /** + * Is the recipe hidden from player crafting? The recipe will still show up for selection in machines. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.hidden_from_player_crafting View documentation} + */ + readonly hidden_from_player_crafting: boolean + /** + * Should this recipe always show "Made in" in the tooltip? + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.always_show_made_in View documentation} + */ + readonly always_show_made_in: boolean + /** + * Energy required to execute this recipe. This directly affects the crafting time: Recipe's energy is exactly its + * crafting time in seconds, when crafted in an assembling machine with crafting speed exactly equal to one. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.energy View documentation} + */ + readonly energy: double + /** + * Order string. This is used to sort the crafting menu. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.order View documentation} + */ + readonly order: string + /** + * Group of this recipe. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.group View documentation} + */ + readonly group: LuaGroup + /** + * Subgroup of this recipe. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.subgroup View documentation} + */ + readonly subgroup: LuaGroup + /** + * The multiplier used when this recipe is copied from an assembling machine to a requester chest. For each item in + * the recipe the item count * this value is set in the requester chest. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.request_paste_multiplier View documentation} + */ + readonly request_paste_multiplier: uint + /** + * Used to determine how many extra items are put into an assembling machine before it's considered "full enough". + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.overload_multiplier View documentation} + */ + readonly overload_multiplier: uint + /** + * If the recipe is allowed to have the extra inserter overload bonus applied (4 * stack inserter stack size). + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.allow_inserter_overload View documentation} + */ + readonly allow_inserter_overload: boolean + /** + * If this recipe is enabled for the purpose of intermediate hand-crafting. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.allow_as_intermediate View documentation} + */ + readonly allow_as_intermediate: boolean + /** + * If this recipe is allowed to use intermediate recipes when hand-crafting. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.allow_intermediates View documentation} + */ + readonly allow_intermediates: boolean + /** + * If the amount is shown in the recipe tooltip title when the recipe produces more than 1 product. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.show_amount_in_title View documentation} + */ + readonly show_amount_in_title: boolean + /** + * If the products are always shown in the recipe tooltip. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.always_show_products View documentation} + */ + readonly always_show_products: boolean + /** + * The emissions multiplier for this recipe. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.emissions_multiplier View documentation} + */ + readonly emissions_multiplier: double + /** + * Is this recipe allowed to be broken down for the recipe tooltip "Total raw" calculations? + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.allow_decomposition View documentation} + */ + readonly allow_decomposition: boolean + /** + * Is this recipe unlocks the result item(s) so they're shown in filter-select GUIs. + * + * {@link https://lua-api.factorio.com/next/LuaRecipePrototype.html#LuaRecipePrototype.unlock_results View documentation} + */ + readonly unlock_results: boolean + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaRecipePrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Registry of interfaces between scripts. An interface is simply a dictionary mapping names to functions. A script or + * mod can then register an interface with {@link LuaRemote}, after that any script can call the registered functions, + * provided it knows the interface name and the desired function name. An instance of LuaRemote is available through the + * global object named `remote`. + * + * {@link https://lua-api.factorio.com/next/LuaRemote.html View documentation} + * + * @example + * Will register a remote interface containing two functions. Later, it will call these functions through `remote`. + * + * ```lua + * remote.add_interface("human interactor", + * {hello = function() game.player.print("Hi!") end, + * bye = function(name) game.player.print("Bye " .. name) end}) + * -- Some time later, possibly in a different mod... + * remote.call("human interactor", "hello") + * remote.call("human interactor", "bye", "dear reader") + * ``` + * + * @noSelf + */ +interface LuaRemote { + /** + * Add a remote interface. + * + * **Note**: It is an error if the given interface `name` is already registered. + * + * {@link https://lua-api.factorio.com/next/LuaRemote.html#LuaRemote.add_interface View documentation} + * + * @param name - Name of the interface. + * @param functions - List of functions that are members of the new interface. + */ + add_interface(name: string, functions: Record void>): void + /** + * Removes an interface with the given name. + * + * {@link https://lua-api.factorio.com/next/LuaRemote.html#LuaRemote.remove_interface View documentation} + * + * @param name - Name of the interface. + * @returns If the interface was removed. `False` if the interface didn't exist. + */ + remove_interface(name: string): boolean + /** + * Call a function of an interface. + * + * {@link https://lua-api.factorio.com/next/LuaRemote.html#LuaRemote.call View documentation} + * + * @param _interface - Interface to look up `function` in. + * @param _function - Function name that belongs to `interface`. + * @param args - Arguments to pass to the called function. + */ + call(_interface: string, _function: string, ...args: Any[]): Any + /** + * List of all registered interfaces. For each interface name, `remote.interfaces[name]` is a dictionary mapping the + * interface's registered functions to the value `true`. + * + * {@link https://lua-api.factorio.com/next/LuaRemote.html#LuaRemote.interfaces View documentation} + * + * @example + * Assuming the "human interactor" interface is registered as above + * + * ```lua + * game.player.print(tostring(remote.interfaces["human interactor"]["hello"])) -- prints true + * game.player.print(tostring(remote.interfaces["human interactor"]["nonexistent"])) -- prints nil + * ``` + */ + readonly interfaces: Record> + /** This object's name. */ + readonly object_name: "LuaRemote" +} + +/** + * Allows rendering of geometric shapes, text and sprites in the game world. Each render object is identified by an id + * that is universally unique for the lifetime of a whole game. + * + * **Note**: If an entity target of an object is destroyed or changes surface, then the object is also destroyed. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html View documentation} + * + * @noSelf + */ +interface LuaRendering { + /** + * Create a line. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_line View documentation} + * + * @example + * Draw a white and 2 pixel wide line from {0, 0} to {2, 2}. + * + * ```lua + * rendering.draw_line{surface = game.player.surface, from = {0, 0}, to = {2, 2}, color = {1, 1, 1}, width = 2} + * ``` + * + * @example + * Draw a red and 3 pixel wide line from {0, 0} to {0, 5}. The line has 1 tile long dashes and gaps. + * + * ```lua + * rendering.draw_line{surface = game.player.surface, from = {0, 0}, to = {0, 5}, color = {r = 1}, width = 3, gap_length = 1, dash_length = 1} + * ``` + * + * @returns Id of the render object + */ + draw_line(params: { + readonly color: Color + /** In pixels (32 per tile). */ + readonly width: float + /** Length of the gaps that this line has, in tiles. Default is 0. */ + readonly gap_length?: double + /** Length of the dashes that this line has. Used only if gap_length > 0. Default is 0. */ + readonly dash_length?: double + readonly from: Position | LuaEntity + /** Only used if `from` is a LuaEntity. */ + readonly from_offset?: Vector + readonly to: Position | LuaEntity + /** Only used if `to` is a LuaEntity. */ + readonly to_offset?: Vector + readonly surface: SurfaceIdentification + /** In ticks. Defaults to living forever. */ + readonly time_to_live?: uint + /** The forces that this object is rendered to. */ + readonly forces?: ForceIdentification[] + /** The players that this object is rendered to. */ + readonly players?: PlayerIdentification[] + /** If this is rendered to anyone at all. Defaults to true. */ + readonly visible?: boolean + /** If this should be drawn below sprites and entities. */ + readonly draw_on_ground?: boolean + /** If this should only be rendered in alt mode. Defaults to false. */ + readonly only_in_alt_mode?: boolean + }): uint64 + /** + * Create a text. + * + * **Note**: Not all fonts support scaling. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_text View documentation} + * + * @returns Id of the render object + */ + draw_text(params: { + /** The text to display. */ + readonly text: LocalisedString + readonly surface: SurfaceIdentification + readonly target: Position | LuaEntity + /** Only used if `target` is a LuaEntity. */ + readonly target_offset?: Vector + readonly color: Color + readonly scale?: double + /** Name of font to use. Defaults to the same font as flying-text. */ + readonly font?: string + /** In ticks. Defaults to living forever. */ + readonly time_to_live?: uint + /** The forces that this object is rendered to. */ + readonly forces?: ForceIdentification[] + /** The players that this object is rendered to. */ + readonly players?: PlayerIdentification[] + /** If this is rendered to anyone at all. Defaults to true. */ + readonly visible?: boolean + /** If this should be drawn below sprites and entities. */ + readonly draw_on_ground?: boolean + /** The orientation of the text. Default is 0. */ + readonly orientation?: RealOrientation + /** Defaults to "left". Other options are "right" and "center". */ + readonly alignment?: "left" | "right" | "center" + /** Defaults to "top". Other options are "middle", "baseline" and "bottom". */ + readonly vertical_alignment?: "top" | "middle" | "baseline" | "bottom" + /** + * Defaults to false. If true, the text scales with player zoom, resulting in it always being the same size on + * screen, and the size compared to the game world changes. + */ + readonly scale_with_zoom?: boolean + /** If this should only be rendered in alt mode. Defaults to false. */ + readonly only_in_alt_mode?: boolean + }): uint64 + /** + * Create a circle. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_circle View documentation} + * + * @returns Id of the render object + */ + draw_circle(params: { + readonly color: Color + /** In tiles. */ + readonly radius: double + /** Width of the outline, used only if filled = false. Value is in pixels (32 per tile). */ + readonly width?: float + /** If the circle should be filled. */ + readonly filled: boolean + readonly target: Position | LuaEntity + /** Only used if `target` is a LuaEntity. */ + readonly target_offset?: Vector + readonly surface: SurfaceIdentification + /** In ticks. Defaults to living forever. */ + readonly time_to_live?: uint + /** The forces that this object is rendered to. */ + readonly forces?: ForceIdentification[] + /** The players that this object is rendered to. */ + readonly players?: PlayerIdentification[] + /** If this is rendered to anyone at all. Defaults to true. */ + readonly visible?: boolean + /** If this should be drawn below sprites and entities. */ + readonly draw_on_ground?: boolean + /** If this should only be rendered in alt mode. Defaults to false. */ + readonly only_in_alt_mode?: boolean + }): uint64 + /** + * Create a rectangle. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_rectangle View documentation} + * + * @returns Id of the render object + */ + draw_rectangle(params: { + readonly color: Color + /** Width of the outline, used only if filled = false. Value is in pixels (32 per tile). */ + readonly width?: float + /** If the rectangle should be filled. */ + readonly filled: boolean + readonly left_top: Position | LuaEntity + /** Only used if `left_top` is a LuaEntity. */ + readonly left_top_offset?: Vector + readonly right_bottom: Position | LuaEntity + /** Only used if `right_bottom` is a LuaEntity. */ + readonly right_bottom_offset?: Vector + readonly surface: SurfaceIdentification + /** In ticks. Defaults to living forever. */ + readonly time_to_live?: uint + /** The forces that this object is rendered to. */ + readonly forces?: ForceIdentification[] + /** The players that this object is rendered to. */ + readonly players?: PlayerIdentification[] + /** If this is rendered to anyone at all. Defaults to true. */ + readonly visible?: boolean + /** If this should be drawn below sprites and entities. */ + readonly draw_on_ground?: boolean + /** If this should only be rendered in alt mode. Defaults to false. */ + readonly only_in_alt_mode?: boolean + }): uint64 + /** + * Create an arc. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_arc View documentation} + * + * @returns Id of the render object + */ + draw_arc(params: { + readonly color: Color + /** The radius of the outer edge of the arc, in tiles. */ + readonly max_radius: double + /** The radius of the inner edge of the arc, in tiles. */ + readonly min_radius: double + /** Where the arc starts, in radian. */ + readonly start_angle: float + /** The angle of the arc, in radian. */ + readonly angle: float + readonly target: Position | LuaEntity + /** Only used if `target` is a LuaEntity. */ + readonly target_offset?: Vector + readonly surface: SurfaceIdentification + /** In ticks. Defaults to living forever. */ + readonly time_to_live?: uint + /** The forces that this object is rendered to. */ + readonly forces?: ForceIdentification[] + /** The players that this object is rendered to. */ + readonly players?: PlayerIdentification[] + /** If this is rendered to anyone at all. Defaults to true. */ + readonly visible?: boolean + /** If this should be drawn below sprites and entities. */ + readonly draw_on_ground?: boolean + /** If this should only be rendered in alt mode. Defaults to false. */ + readonly only_in_alt_mode?: boolean + }): uint64 + /** + * Create a triangle mesh defined by a triangle strip. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_polygon View documentation} + * + * @returns Id of the render object + */ + draw_polygon(params: { + readonly color: Color + readonly vertices: ScriptRenderVertexTarget[] + /** Acts like an offset applied to all vertices that are not set to an entity. */ + readonly target?: Position | LuaEntity + /** Only used if `target` is a LuaEntity. */ + readonly target_offset?: Vector + /** The orientation applied to all vertices. Default is 0. */ + readonly orientation?: RealOrientation + /** + * If given, the vertices (that are not set to an entity) rotate so that it faces this target. Note that + * `orientation` is still applied. + */ + readonly orientation_target?: Position | LuaEntity + /** Only used if `orientation_target` is a LuaEntity. */ + readonly orientation_target_offset?: Vector + readonly surface: SurfaceIdentification + /** In ticks. Defaults to living forever. */ + readonly time_to_live?: uint + /** The forces that this object is rendered to. */ + readonly forces?: ForceIdentification[] + /** The players that this object is rendered to. */ + readonly players?: PlayerIdentification[] + /** If this is rendered to anyone at all. Defaults to true. */ + readonly visible?: boolean + /** If this should be drawn below sprites and entities. */ + readonly draw_on_ground?: boolean + /** If this should only be rendered in alt mode. Defaults to false. */ + readonly only_in_alt_mode?: boolean + }): uint64 + /** + * Create a sprite. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_sprite View documentation} + * + * @example + * This will draw an iron plate icon at the character's feet. The sprite will move together with the character. + * + * ```lua + * rendering.draw_sprite{sprite = "item.iron-plate", target = game.player.character, surface = game.player.surface} + * ``` + * + * @example + * This will draw an iron plate icon at the character's head. The sprite will move together with the character. + * + * ```lua + * rendering.draw_sprite{sprite = "item.iron-plate", target = game.player.character, target_offset = {0, -2}, surface = game.player.surface} + * ``` + * + * @returns Id of the render object + */ + draw_sprite(params: { + readonly sprite: SpritePath + /** The orientation of the sprite. Default is 0. */ + readonly orientation?: RealOrientation + /** Horizontal scale of the sprite. Default is 1. */ + readonly x_scale?: double + /** Vertical scale of the sprite. Default is 1. */ + readonly y_scale?: double + readonly tint?: Color + readonly render_layer?: RenderLayer + /** If given, the sprite rotates so that it faces this target. Note that `orientation` is still applied to the sprite. */ + readonly orientation_target?: Position | LuaEntity + /** Only used if `orientation_target` is a LuaEntity. */ + readonly orientation_target_offset?: Vector + /** Offsets the center of the sprite if `orientation_target` is given. This offset will rotate together with the sprite. */ + readonly oriented_offset?: Vector + /** Center of the sprite. */ + readonly target: Position | LuaEntity + /** Only used if `target` is a LuaEntity. */ + readonly target_offset?: Vector + readonly surface: SurfaceIdentification + /** In ticks. Defaults to living forever. */ + readonly time_to_live?: uint + /** The forces that this object is rendered to. */ + readonly forces?: ForceIdentification[] + /** The players that this object is rendered to. */ + readonly players?: PlayerIdentification[] + /** If this is rendered to anyone at all. Defaults to true. */ + readonly visible?: boolean + /** If this should only be rendered in alt mode. Defaults to false. */ + readonly only_in_alt_mode?: boolean + }): uint64 + /** + * Create a light. + * + * **Note**: The base game uses the utility sprites `light_medium` and `light_small` for lights. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_light View documentation} + * + * @returns Id of the render object + */ + draw_light(params: { + readonly sprite: SpritePath + /** The orientation of the light. Default is 0. */ + readonly orientation?: RealOrientation + /** Default is 1. */ + readonly scale?: float + /** Default is 1. */ + readonly intensity?: float + /** The minimum darkness at which this light is rendered. Default is 0. */ + readonly minimum_darkness?: float + /** + * If this light has the same orientation as the entity target, default is false. Note that `orientation` is + * still applied to the sprite. + */ + readonly oriented?: boolean + /** Defaults to white (no tint). */ + readonly color?: Color + /** Center of the light. */ + readonly target: Position | LuaEntity + /** Only used if `target` is a LuaEntity. */ + readonly target_offset?: Vector + readonly surface: SurfaceIdentification + /** In ticks. Defaults to living forever. */ + readonly time_to_live?: uint + /** The forces that this object is rendered to. */ + readonly forces?: ForceIdentification[] + /** The players that this object is rendered to. */ + readonly players?: PlayerIdentification[] + /** If this is rendered to anyone at all. Defaults to true. */ + readonly visible?: boolean + /** If this should only be rendered in alt mode. Defaults to false. */ + readonly only_in_alt_mode?: boolean + }): uint64 + /** + * Create an animation. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.draw_animation View documentation} + * + * @returns Id of the render object + */ + draw_animation(params: { + /** Name of an {@link https://wiki.factorio.com/Prototype/Animation animation prototype}. */ + readonly animation: string + /** The orientation of the animation. Default is 0. */ + readonly orientation?: RealOrientation + /** Horizontal scale of the animation. Default is 1. */ + readonly x_scale?: double + /** Vertical scale of the animation. Default is 1. */ + readonly y_scale?: double + readonly tint?: Color + readonly render_layer?: RenderLayer + /** How many frames the animation goes forward per tick. Default is 1. */ + readonly animation_speed?: double + /** Offset of the animation in frames. Default is 0. */ + readonly animation_offset?: double + /** + * If given, the animation rotates so that it faces this target. Note that `orientation` is still applied to the + * animation. + */ + readonly orientation_target?: Position | LuaEntity + /** Only used if `orientation_target` is a LuaEntity. */ + readonly orientation_target_offset?: Vector + /** + * Offsets the center of the animation if `orientation_target` is given. This offset will rotate together with + * the animation. + */ + readonly oriented_offset?: Vector + /** Center of the animation. */ + readonly target: Position | LuaEntity + /** Only used if `target` is a LuaEntity. */ + readonly target_offset?: Vector + readonly surface: SurfaceIdentification + /** In ticks. Defaults to living forever. */ + readonly time_to_live?: uint + /** The forces that this object is rendered to. */ + readonly forces?: ForceIdentification[] + /** The players that this object is rendered to. */ + readonly players?: PlayerIdentification[] + /** If this is rendered to anyone at all. Defaults to true. */ + readonly visible?: boolean + /** If this should only be rendered in alt mode. Defaults to false. */ + readonly only_in_alt_mode?: boolean + }): uint64 + /** + * Destroy the object with the given id. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.destroy View documentation} + * + * @param id + */ + destroy(id: uint64): void + /** + * Does a font with this name exist? + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.is_font_valid View documentation} + * + * @param font_name + */ + is_font_valid(font_name: string): boolean + /** + * Does a valid object with this id exist? + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.is_valid View documentation} + * + * @param id + */ + is_valid(id: uint64): boolean + /** + * Gets an array of all valid object ids. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_all_ids View documentation} + * + * @param mod_name - If provided, get only the render objects created by this mod. + */ + get_all_ids(mod_name?: string): uint64[] + /** + * Destroys all render objects. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.clear View documentation} + * + * @param mod_name - If provided, only the render objects created by this mod are destroyed. + */ + clear(mod_name?: string): void + /** + * Gets the type of the given object. The types are "text", "line", "circle", "rectangle", "arc", "polygon", + * "sprite", "light" and "animation". + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_type View documentation} + * + * @param id + */ + get_type(id: uint64): "text" | "line" | "circle" | "rectangle" | "arc" | "polygon" | "sprite" | "light" | "animation" + /** + * Reorder this object so that it is drawn in front of the already existing objects. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.bring_to_front View documentation} + * + * @param id + */ + bring_to_front(id: uint64): void + /** + * The surface the object with this id is rendered on. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_surface View documentation} + * + * @param id + */ + get_surface(id: uint64): LuaSurface + /** + * Get the time to live of the object with this id. This will be 0 if the object does not expire. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_time_to_live View documentation} + * + * @param id + */ + get_time_to_live(id: uint64): uint + /** + * Set the time to live of the object with this id. Set to 0 if the object should not expire. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_time_to_live View documentation} + * + * @param id + * @param time_to_live + */ + set_time_to_live(id: uint64, time_to_live: uint): void + /** + * Get the forces that the object with this id is rendered to or `nil` if visible to all forces. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_forces View documentation} + * + * @param id + */ + get_forces(id: uint64): LuaForce[] | undefined + /** + * Set the forces that the object with this id is rendered to. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_forces View documentation} + * + * @param id + * @param forces - Providing an empty array will set the object to be visible to all forces. + */ + set_forces(id: uint64, forces: ForceIdentification[]): void + /** + * Get the players that the object with this id is rendered to or `nil` if visible to all players. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_players View documentation} + * + * @param id + */ + get_players(id: uint64): LuaPlayer[] | undefined + /** + * Set the players that the object with this id is rendered to. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_players View documentation} + * + * @param id + * @param players - Providing an empty array will set the object to be visible to all players. + */ + set_players(id: uint64, players: PlayerIdentification[]): void + /** + * Get whether this is rendered to anyone at all. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_visible View documentation} + * + * @param id + */ + get_visible(id: uint64): boolean + /** + * Set whether this is rendered to anyone at all. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_visible View documentation} + * + * @param id + * @param visible + */ + set_visible(id: uint64, visible: boolean): void + /** + * Get whether this is being drawn on the ground, under most entities and sprites. + * + * *Can only be used if this is Text, Line, Circle, Rectangle, Arc or Polygon* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_draw_on_ground View documentation} + * + * @param id + */ + get_draw_on_ground(id: uint64): boolean + /** + * Set whether this is being drawn on the ground, under most entities and sprites. + * + * *Can only be used if this is Text, Line, Circle, Rectangle, Arc or Polygon* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_draw_on_ground View documentation} + * + * @param id + * @param draw_on_ground + */ + set_draw_on_ground(id: uint64, draw_on_ground: boolean): void + /** + * Get whether this is only rendered in alt-mode. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_only_in_alt_mode View documentation} + * + * @param id + */ + get_only_in_alt_mode(id: uint64): boolean + /** + * Set whether this is only rendered in alt-mode. + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_only_in_alt_mode View documentation} + * + * @param id + * @param only_in_alt_mode + */ + set_only_in_alt_mode(id: uint64, only_in_alt_mode: boolean): void + /** + * Get the color or tint of the object with this id. + * + * *Can only be used if this is Text, Line, Circle, Rectangle, Arc, Polygon, Sprite, Light or Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_color View documentation} + * + * @param id + * @returns Or `nil` if the object does not support color. + */ + get_color(id: uint64): ColorTable | undefined + /** + * Set the color or tint of the object with this id. Does nothing if this object does not support color. + * + * *Can only be used if this is Text, Line, Circle, Rectangle, Arc, Polygon, Sprite, Light or Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_color View documentation} + * + * @param id + * @param color + */ + set_color(id: uint64, color: Color): void + /** + * Get the width of the object with this id. Value is in pixels (32 per tile). + * + * *Can only be used if this is Line, Circle or Rectangle* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_width View documentation} + * + * @param id + * @returns Or `nil` if the object does not support width. + */ + get_width(id: uint64): float | undefined + /** + * Set the width of the object with this id. Does nothing if this object does not support width. Value is in pixels + * (32 per tile). + * + * *Can only be used if this is Line, Circle or Rectangle* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_width View documentation} + * + * @param id + * @param width + */ + set_width(id: uint64, width: float): void + /** + * Get from where the line with this id is drawn or `nil` if this object is not a line. + * + * *Can only be used if this is Line* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_from View documentation} + * + * @param id + */ + get_from(id: uint64): ScriptRenderTarget | undefined + /** + * Set from where the line with this id is drawn. Does nothing if the object is not a line. + * + * *Can only be used if this is Line* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_from View documentation} + * + * @param id + * @param from + * @param from_offset + */ + set_from(id: uint64, from: Position | LuaEntity, from_offset?: Vector): void + /** + * Get where the line with this id is drawn to or `nil` if the object is not a line. + * + * *Can only be used if this is Line* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_to View documentation} + * + * @param id + */ + get_to(id: uint64): ScriptRenderTarget | undefined + /** + * Set where the line with this id is drawn to. Does nothing if this object is not a line. + * + * *Can only be used if this is Line* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_to View documentation} + * + * @param id + * @param to + * @param to_offset + */ + set_to(id: uint64, to: Position | LuaEntity, to_offset?: Vector): void + /** + * Get the dash length of the line with this id or `nil` if the object is not a line. + * + * *Can only be used if this is Line* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_dash_length View documentation} + * + * @param id + */ + get_dash_length(id: uint64): double | undefined + /** + * Set the dash length of the line with this id. Does nothing if this object is not a line. + * + * *Can only be used if this is Line* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_dash_length View documentation} + * + * @param id + * @param dash_length + */ + set_dash_length(id: uint64, dash_length: double): void + /** + * Get the length of the gaps in the line with this id or `nil` if the object is not a line. + * + * *Can only be used if this is Line* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_gap_length View documentation} + * + * @param id + */ + get_gap_length(id: uint64): double | undefined + /** + * Set the length of the gaps in the line with this id. Does nothing if this object is not a line. + * + * *Can only be used if this is Line* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_gap_length View documentation} + * + * @param id + * @param gap_length + */ + set_gap_length(id: uint64, gap_length: double): void + /** + * Set the length of the dashes and the length of the gaps in the line with this id. Does nothing if this object is + * not a line. + * + * *Can only be used if this is Line* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_dashes View documentation} + * + * @param id + * @param dash_length + * @param gap_length + */ + set_dashes(id: uint64, dash_length: double, gap_length: double): void + /** + * Get where the object with this id is drawn or `nil` if the object does not support target. + * + * **Note**: Polygon vertices that are set to an entity will ignore this. + * + * *Can only be used if this is Text, Circle, Arc, Polygon, Sprite, Light or Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_target View documentation} + * + * @param id + */ + get_target(id: uint64): ScriptRenderTarget | undefined + /** + * Set where the object with this id is drawn. Does nothing if this object does not support target. + * + * **Note**: Polygon vertices that are set to an entity will ignore this. + * + * *Can only be used if this is Text, Circle, Arc, Polygon, Sprite, Light or Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_target View documentation} + * + * @param id + * @param target + * @param target_offset + */ + set_target(id: uint64, target: Position | LuaEntity, target_offset?: Vector): void + /** + * Get the orientation of the object with this id or `nil` if the object is not a text, polygon, sprite, light or animation. + * + * **Note**: Polygon vertices that are set to an entity will ignore this. + * + * *Can only be used if this is Text, Polygon, Sprite, Light or Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_orientation View documentation} + * + * @param id + */ + get_orientation(id: uint64): RealOrientation | undefined + /** + * Set the orientation of the object with this id. Does nothing if this object is not a text, polygon, sprite, light + * or animation. + * + * **Note**: Polygon vertices that are set to an entity will ignore this. + * + * *Can only be used if this is Text, Polygon, Sprite, Light or Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_orientation View documentation} + * + * @param id + * @param orientation + */ + set_orientation(id: uint64, orientation: RealOrientation): void + /** + * Get the scale of the text or light with this id or `nil` if the object is not a text or light. + * + * *Can only be used if this is Text or Light* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_scale View documentation} + * + * @param id + */ + get_scale(id: uint64): double | undefined + /** + * Set the scale of the text or light with this id. Does nothing if this object is not a text or light. + * + * *Can only be used if this is Text or Light* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_scale View documentation} + * + * @param id + * @param scale + */ + set_scale(id: uint64, scale: double): void + /** + * Get the text that is displayed by the text with this id or `nil` if the object is not a text. + * + * *Can only be used if this is Text* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_text View documentation} + * + * @param id + */ + get_text(id: uint64): LocalisedString | undefined + /** + * Set the text that is displayed by the text with this id. Does nothing if this object is not a text. + * + * *Can only be used if this is Text* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_text View documentation} + * + * @param id + * @param text + */ + set_text(id: uint64, text: LocalisedString): void + /** + * Get the font of the text with this id or `nil` if the object is not a text. + * + * *Can only be used if this is Text* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_font View documentation} + * + * @param id + */ + get_font(id: uint64): string | undefined + /** + * Set the font of the text with this id. Does nothing if this object is not a text. + * + * *Can only be used if this is Text* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_font View documentation} + * + * @param id + * @param font + */ + set_font(id: uint64, font: string): void + /** + * Get the alignment of the text with this id or `nil` if the object is not a text. + * + * *Can only be used if this is Text* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_alignment View documentation} + * + * @param id + */ + get_alignment(id: uint64): string | undefined + /** + * Set the alignment of the text with this id. Does nothing if this object is not a text. + * + * *Can only be used if this is Text* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_alignment View documentation} + * + * @param id + * @param alignment - "left", "right" or "center". + */ + set_alignment(id: uint64, alignment: "left" | "right" | "center"): void + /** + * Get the vertical alignment of the text with this id or `nil` if the object is not a text. + * + * *Can only be used if this is Text* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_vertical_alignment View documentation} + * + * @param id + */ + get_vertical_alignment(id: uint64): string | undefined + /** + * Set the vertical alignment of the text with this id. Does nothing if this object is not a text. + * + * *Can only be used if this is Text* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_vertical_alignment View documentation} + * + * @param id + * @param alignment - "top", "middle", "baseline" or "bottom" + */ + set_vertical_alignment(id: uint64, alignment: "top" | "middle" | "baseline" | "bottom"): void + /** + * Get if the text with this id scales with player zoom or `nil` if the object is not a text. + * + * *Can only be used if this is Text* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_scale_with_zoom View documentation} + * + * @param id + */ + get_scale_with_zoom(id: uint64): boolean | undefined + /** + * Set if the text with this id scales with player zoom, resulting in it always being the same size on screen, and + * the size compared to the game world changes. Does nothing if this object is not a text. + * + * *Can only be used if this is Text* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_scale_with_zoom View documentation} + * + * @param id + * @param scale_with_zoom + */ + set_scale_with_zoom(id: uint64, scale_with_zoom: boolean): void + /** + * Get if the circle or rectangle with this id is filled or `nil` if the object is not a circle or rectangle. + * + * *Can only be used if this is Circle or Rectangle* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_filled View documentation} + * + * @param id + */ + get_filled(id: uint64): boolean | undefined + /** + * Set if the circle or rectangle with this id is filled. Does nothing if this object is not a circle or rectangle. + * + * *Can only be used if this is Circle or Rectangle* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_filled View documentation} + * + * @param id + * @param filled + */ + set_filled(id: uint64, filled: boolean): void + /** + * Get the radius of the circle with this id or `nil` if the object is not a circle. + * + * *Can only be used if this is Circle* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_radius View documentation} + * + * @param id + */ + get_radius(id: uint64): double | undefined + /** + * Set the radius of the circle with this id. Does nothing if this object is not a circle. + * + * *Can only be used if this is Circle* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_radius View documentation} + * + * @param id + * @param radius + */ + set_radius(id: uint64, radius: double): void + /** + * Get where top left corner of the rectangle with this id is drawn or `nil` if the object is not a rectangle. + * + * *Can only be used if this is Rectangle* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_left_top View documentation} + * + * @param id + */ + get_left_top(id: uint64): ScriptRenderTarget | undefined + /** + * Set where top left corner of the rectangle with this id is drawn. Does nothing if this object is not a rectangle. + * + * *Can only be used if this is Rectangle* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_left_top View documentation} + * + * @param id + * @param left_top + * @param left_top_offset + */ + set_left_top(id: uint64, left_top: Position | LuaEntity, left_top_offset?: Vector): void + /** + * Get where bottom right corner of the rectangle with this id is drawn or `nil` if the object is not a rectangle. + * + * *Can only be used if this is Rectangle* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_right_bottom View documentation} + * + * @param id + */ + get_right_bottom(id: uint64): ScriptRenderTarget | undefined + /** + * Set where top bottom right of the rectangle with this id is drawn. Does nothing if this object is not a rectangle. + * + * *Can only be used if this is Rectangle* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_right_bottom View documentation} + * + * @param id + * @param right_bottom + * @param right_bottom_offset + */ + set_right_bottom(id: uint64, right_bottom: Position | LuaEntity, right_bottom_offset?: Vector): void + /** + * Set the corners of the rectangle with this id. Does nothing if this object is not a rectangle. + * + * *Can only be used if this is Rectangle* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_corners View documentation} + * + * @param id + * @param left_top + * @param left_top_offset + * @param right_bottom + * @param right_bottom_offset + */ + set_corners( + id: uint64, + left_top: Position | LuaEntity, + left_top_offset: Vector, + right_bottom: Position | LuaEntity, + right_bottom_offset: Vector + ): void + /** + * Get the radius of the outer edge of the arc with this id or `nil` if the object is not a arc. + * + * *Can only be used if this is Arc* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_max_radius View documentation} + * + * @param id + */ + get_max_radius(id: uint64): double | undefined + /** + * Set the radius of the outer edge of the arc with this id. Does nothing if this object is not a arc. + * + * *Can only be used if this is Arc* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_max_radius View documentation} + * + * @param id + * @param max_radius + */ + set_max_radius(id: uint64, max_radius: double): void + /** + * Get the radius of the inner edge of the arc with this id or `nil` if the object is not a arc. + * + * *Can only be used if this is Arc* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_min_radius View documentation} + * + * @param id + */ + get_min_radius(id: uint64): double | undefined + /** + * Set the radius of the inner edge of the arc with this id. Does nothing if this object is not a arc. + * + * *Can only be used if this is Arc* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_min_radius View documentation} + * + * @param id + * @param min_radius + */ + set_min_radius(id: uint64, min_radius: double): void + /** + * Get where the arc with this id starts or `nil` if the object is not a arc. + * + * *Can only be used if this is Arc* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_start_angle View documentation} + * + * @param id + * @returns Angle in radian + */ + get_start_angle(id: uint64): float | undefined + /** + * Set where the arc with this id starts. Does nothing if this object is not a arc. + * + * *Can only be used if this is Arc* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_start_angle View documentation} + * + * @param id + * @param start_angle - Angle in radian + */ + set_start_angle(id: uint64, start_angle: float): void + /** + * Get the angle of the arc with this id or `nil` if the object is not a arc. + * + * *Can only be used if this is Arc* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_angle View documentation} + * + * @param id + * @returns Angle in radian + */ + get_angle(id: uint64): float | undefined + /** + * Set the angle of the arc with this id. Does nothing if this object is not a arc. + * + * *Can only be used if this is Arc* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_angle View documentation} + * + * @param id + * @param angle - Angle in radian + */ + set_angle(id: uint64, angle: float): void + /** + * Get the vertices of the polygon with this id or `nil` if the object is not a polygon. + * + * *Can only be used if this is Polygon* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_vertices View documentation} + * + * @param id + */ + get_vertices(id: uint64): ScriptRenderTarget[] | undefined + /** + * Set the vertices of the polygon with this id. Does nothing if this object is not a polygon. + * + * *Can only be used if this is Polygon* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_vertices View documentation} + * + * @param id + * @param vertices + */ + set_vertices(id: uint64, vertices: ScriptRenderVertexTarget[]): void + /** + * Get the sprite of the sprite or light with this id or `nil` if the object is not a sprite or light. + * + * *Can only be used if this is Sprite or Light* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_sprite View documentation} + * + * @param id + */ + get_sprite(id: uint64): SpritePath | undefined + /** + * Set the sprite of the sprite or light with this id. Does nothing if this object is not a sprite or light. + * + * *Can only be used if this is Sprite or Light* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_sprite View documentation} + * + * @param id + * @param sprite + */ + set_sprite(id: uint64, sprite: SpritePath): void + /** + * Get the horizontal scale of the sprite or animation with this id or `nil` if the object is not a sprite or animation. + * + * *Can only be used if this is Sprite or Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_x_scale View documentation} + * + * @param id + */ + get_x_scale(id: uint64): double | undefined + /** + * Set the horizontal scale of the sprite or animation with this id. Does nothing if this object is not a sprite or animation. + * + * *Can only be used if this is Sprite or Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_x_scale View documentation} + * + * @param id + * @param x_scale + */ + set_x_scale(id: uint64, x_scale: double): void + /** + * Get the vertical scale of the sprite or animation with this id or `nil` if the object is not a sprite or animation. + * + * *Can only be used if this is Sprite or Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_y_scale View documentation} + * + * @param id + */ + get_y_scale(id: uint64): double | undefined + /** + * Set the vertical scale of the sprite or animation with this id. Does nothing if this object is not a sprite or animation. + * + * *Can only be used if this is Sprite or Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_y_scale View documentation} + * + * @param id + * @param y_scale + */ + set_y_scale(id: uint64, y_scale: double): void + /** + * Get the render layer of the sprite or animation with this id or `nil` if the object is not a sprite or animation. + * + * *Can only be used if this is Sprite or Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_render_layer View documentation} + * + * @param id + */ + get_render_layer(id: uint64): RenderLayer | undefined + /** + * Set the render layer of the sprite or animation with this id. Does nothing if this object is not a sprite or animation. + * + * *Can only be used if this is Sprite or Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_render_layer View documentation} + * + * @param id + * @param render_layer + */ + set_render_layer(id: uint64, render_layer: RenderLayer): void + /** + * The object rotates so that it faces this target. Note that `orientation` is still applied to the object. Get the + * orientation_target of the object with this id or `nil` if no target or if this object is not a polygon, sprite, + * or animation. + * + * **Note**: Polygon vertices that are set to an entity will ignore this. + * + * *Can only be used if this is Polygon, Sprite or Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_orientation_target View documentation} + * + * @param id + */ + get_orientation_target(id: uint64): ScriptRenderTarget | undefined + /** + * The object rotates so that it faces this target. Note that `orientation` is still applied to the object. Set the + * orientation_target of the object with this id. Does nothing if this object is not a polygon, sprite, or + * animation. Set to `nil` if the object should not have an orientation_target. + * + * **Note**: Polygon vertices that are set to an entity will ignore this. + * + * *Can only be used if this is Polygon, Sprite or Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_orientation_target View documentation} + * + * @param id + * @param orientation_target + * @param orientation_target_offset + */ + set_orientation_target(id: uint64, orientation_target: Position | LuaEntity, orientation_target_offset?: Vector): void + /** + * Offsets the center of the sprite or animation if `orientation_target` is given. This offset will rotate together + * with the sprite or animation. Get the oriented_offset of the sprite or animation with this id or `nil` if this + * object is not a sprite or animation. + * + * *Can only be used if this is Sprite or Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_oriented_offset View documentation} + * + * @param id + */ + get_oriented_offset(id: uint64): Vector | undefined + /** + * Offsets the center of the sprite or animation if `orientation_target` is given. This offset will rotate together + * with the sprite or animation. Set the oriented_offset of the sprite or animation with this id. Does nothing if + * this object is not a sprite or animation. + * + * *Can only be used if this is Sprite or Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_oriented_offset View documentation} + * + * @param id + * @param oriented_offset + */ + set_oriented_offset(id: uint64, oriented_offset: Vector): void + /** + * Get the intensity of the light with this id or `nil` if the object is not a light. + * + * *Can only be used if this is Light* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_intensity View documentation} + * + * @param id + */ + get_intensity(id: uint64): float | undefined + /** + * Set the intensity of the light with this id. Does nothing if this object is not a light. + * + * *Can only be used if this is Light* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_intensity View documentation} + * + * @param id + * @param intensity + */ + set_intensity(id: uint64, intensity: float): void + /** + * Get the minimum darkness at which the light with this id is rendered or `nil` if the object is not a light. + * + * *Can only be used if this is Light* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_minimum_darkness View documentation} + * + * @param id + */ + get_minimum_darkness(id: uint64): float | undefined + /** + * Set the minimum darkness at which the light with this id is rendered. Does nothing if this object is not a light. + * + * *Can only be used if this is Light* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_minimum_darkness View documentation} + * + * @param id + * @param minimum_darkness + */ + set_minimum_darkness(id: uint64, minimum_darkness: float): void + /** + * Get if the light with this id is rendered has the same orientation as the target entity or `nil` if the object is + * not a light. Note that `orientation` is still applied to the sprite. + * + * *Can only be used if this is Light* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_oriented View documentation} + * + * @param id + */ + get_oriented(id: uint64): boolean | undefined + /** + * Set if the light with this id is rendered has the same orientation as the target entity. Does nothing if this + * object is not a light. Note that `orientation` is still applied to the sprite. + * + * *Can only be used if this is Light* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_oriented View documentation} + * + * @param id + * @param oriented + */ + set_oriented(id: uint64, oriented: boolean): void + /** + * Get the animation prototype name of the animation with this id or `nil` if the object is not an animation. + * + * *Can only be used if this is Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_animation View documentation} + * + * @param id + */ + get_animation(id: uint64): string | undefined + /** + * Set the animation prototype name of the animation with this id. Does nothing if this object is not an animation. + * + * *Can only be used if this is Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_animation View documentation} + * + * @param id + * @param animation + */ + set_animation(id: uint64, animation: string): void + /** + * Get the animation speed of the animation with this id or `nil` if the object is not an animation. + * + * *Can only be used if this is Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_animation_speed View documentation} + * + * @param id + * @returns Animation speed in frames per tick. + */ + get_animation_speed(id: uint64): double | undefined + /** + * Set the animation speed of the animation with this id. Does nothing if this object is not an animation. + * + * *Can only be used if this is Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_animation_speed View documentation} + * + * @param id + * @param animation_speed - Animation speed in frames per tick. + */ + set_animation_speed(id: uint64, animation_speed: double): void + /** + * Get the animation offset of the animation with this id or `nil` if the object is not an animation. + * + * *Can only be used if this is Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.get_animation_offset View documentation} + * + * @param id + * @returns Animation offset in frames. + */ + get_animation_offset(id: uint64): double | undefined + /** + * Set the animation offset of the animation with this id. Does nothing if this object is not an animation. + * + * *Can only be used if this is Animation* + * + * {@link https://lua-api.factorio.com/next/LuaRendering.html#LuaRendering.set_animation_offset View documentation} + * + * @param id + * @param animation_offset - Animation offset in frames. + */ + set_animation_offset(id: uint64, animation_offset: double): void + /** This object's name. */ + readonly object_name: "LuaRendering" +} + +/** + * Prototype of a resource category. + * + * {@link https://lua-api.factorio.com/next/LuaResourceCategoryPrototype.html View documentation} + * + * @noSelf + */ +interface LuaResourceCategoryPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaResourceCategoryPrototype.html#LuaResourceCategoryPrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaResourceCategoryPrototype.html#LuaResourceCategoryPrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaResourceCategoryPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Control behavior for roboports. + * + * {@link https://lua-api.factorio.com/next/LuaRoboportControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaRoboportControlBehavior extends LuaControlBehavior { + /** + * `true` if the roboport should report the logistics network content to the circuit network. + * + * {@link https://lua-api.factorio.com/next/LuaRoboportControlBehavior.html#LuaRoboportControlBehavior.read_logistics View documentation} + */ + read_logistics: boolean + /** + * `true` if the roboport should report the robot statistics to the circuit network. + * + * {@link https://lua-api.factorio.com/next/LuaRoboportControlBehavior.html#LuaRoboportControlBehavior.read_robot_stats View documentation} + */ + read_robot_stats: boolean + available_logistic_output_signal: SignalID + total_logistic_output_signal: SignalID + available_construction_output_signal: SignalID + total_construction_output_signal: SignalID + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaRoboportControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Object containing mod settings of three distinct types: `startup`, `global`, and `player`. An instance of LuaSettings + * is available through the global object named `settings`. + * + * {@link https://lua-api.factorio.com/next/LuaSettings.html View documentation} + * + * @noSelf + */ +interface LuaSettings { + /** + * Gets the current per-player settings for the given player, indexed by prototype name. Returns the same structure + * as {@link LuaPlayer.mod_settings LuaPlayer::mod_settings}. + * + * **Note**: This can become invalid if during operation if the given player becomes invalid. + * + * {@link https://lua-api.factorio.com/next/LuaSettings.html#LuaSettings.get_player_settings View documentation} + * + * @param player + */ + get_player_settings(player: PlayerIdentification): LuaCustomTable + /** + * The startup mod settings, indexed by prototype name. + * + * {@link https://lua-api.factorio.com/next/LuaSettings.html#LuaSettings.startup View documentation} + */ + readonly startup: LuaCustomTable + /** + * The current global mod settings, indexed by prototype name. + * + * Even though these are marked as read-only, they can be changed by overwriting individual {@link ModSetting} tables + * in the custom table. Mods can only change their own settings. Using the in-game console, all global settings can + * be changed. + * + * {@link https://lua-api.factorio.com/next/LuaSettings.html#LuaSettings.global View documentation} + */ + readonly global: LuaCustomTable + /** + * The default player mod settings for this map, indexed by prototype name. + * + * Even though these are marked as read-only, they can be changed by overwriting individual {@link ModSetting} tables + * in the custom table. Mods can only change their own settings. Using the in-game console, all player settings can + * be changed. + * + * {@link https://lua-api.factorio.com/next/LuaSettings.html#LuaSettings.player View documentation} + */ + readonly player: LuaCustomTable + /** This object's name. */ + readonly object_name: "LuaSettings" +} + +/** + * Prototype of a shortcut. + * + * {@link https://lua-api.factorio.com/next/LuaShortcutPrototype.html View documentation} + * + * @noSelf + */ +interface LuaShortcutPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaShortcutPrototype.html#LuaShortcutPrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaShortcutPrototype.html#LuaShortcutPrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + readonly action: string + readonly item_to_spawn: LuaItemPrototype + readonly technology_to_unlock: LuaTechnologyPrototype + readonly toggleable: boolean + readonly associated_control_input: string + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaShortcutPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Control behavior for storage tanks. + * + * {@link https://lua-api.factorio.com/next/LuaStorageTankControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaStorageTankControlBehavior extends LuaControlBehavior { + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaStorageTankControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Style of a GUI element. All of the attributes listed here may be `nil` if not available for a particular GUI element. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html View documentation} + * + * @noSelf + */ +interface LuaStyle { + /** + * Gui of the {@link LuaGuiElement} of this style. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.gui View documentation} + */ + readonly gui: LuaGui + /** + * Name of this style. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.name View documentation} + */ + readonly name: string + /** + * Minimal width ensures, that the widget will never be smaller than than that size. It can't be squashed to be smaller. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.minimal_width View documentation} + */ + minimal_width: int + /** + * Maximal width ensures, that the widget will never be bigger than than that size. It can't be stretched to be bigger. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.maximal_width View documentation} + */ + maximal_width: int + /** + * Minimal height ensures, that the widget will never be smaller than than that size. It can't be squashed to be smaller. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.minimal_height View documentation} + */ + minimal_height: int + /** + * Maximal height ensures, that the widget will never be bigger than than that size. It can't be stretched to be bigger. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.maximal_height View documentation} + */ + maximal_height: int + /** + * Natural width specifies the width of the element tries to have, but it can still be squashed/stretched to have a + * smaller or bigger size. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.natural_width View documentation} + */ + natural_width: int + /** + * Natural height specifies the height of the element tries to have, but it can still be squashed/stretched to have + * a smaller or bigger size. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.natural_height View documentation} + */ + natural_height: int + top_padding: int + right_padding: int + bottom_padding: int + left_padding: int + top_margin: int + right_margin: int + bottom_margin: int + left_margin: int + /** + * Horizontal align of the inner content of the widget, possible values are "left", "center" or "right" + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.horizontal_align View documentation} + */ + horizontal_align: "left" | "center" | "right" + /** + * Vertical align of the inner content of the widget, possible values are "top", "center" or "bottom" + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.vertical_align View documentation} + */ + vertical_align: "top" | "center" | "bottom" + font_color: Color + font: string + /** + * Space between the table cell contents top and border. + * + * *Can only be used if this is LuaTableStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.top_cell_padding View documentation} + */ + top_cell_padding: int + /** + * Space between the table cell contents right and border. + * + * *Can only be used if this is LuaTableStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.right_cell_padding View documentation} + */ + right_cell_padding: int + /** + * Space between the table cell contents bottom and border. + * + * *Can only be used if this is LuaTableStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.bottom_cell_padding View documentation} + */ + bottom_cell_padding: int + /** + * Space between the table cell contents left and border. + * + * *Can only be used if this is LuaTableStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.left_cell_padding View documentation} + */ + left_cell_padding: int + /** + * If the GUI element stretches its size horizontally to other elements. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.horizontally_stretchable View documentation} + */ + horizontally_stretchable: boolean + /** + * If the GUI element stretches its size vertically to other elements. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.vertically_stretchable View documentation} + */ + vertically_stretchable: boolean + /** + * If the GUI element can be squashed (by maximal width of some parent element) horizontally. This is mainly meant + * to be used for scroll-pane The default value is false. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.horizontally_squashable View documentation} + */ + horizontally_squashable: boolean + /** + * If the GUI element can be squashed (by maximal height of some parent element) vertically. This is mainly meant to + * be used for scroll-pane The default (parent) value for scroll pane is true, false otherwise. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.vertically_squashable View documentation} + */ + vertically_squashable: boolean + /** + * How this GUI element handles rich text. + * + * *Can only be used if this is LuaLabelStyle, LuaTextBoxStyle or LuaTextFieldStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.rich_text_setting View documentation} + */ + rich_text_setting: defines.rich_text_setting + /** + * *Can only be used if this is LuaButtonStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.hovered_font_color View documentation} + */ + hovered_font_color: Color + /** + * *Can only be used if this is LuaButtonStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.clicked_font_color View documentation} + */ + clicked_font_color: Color + /** + * *Can only be used if this is LuaButtonStyle or LuaTabStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.disabled_font_color View documentation} + */ + disabled_font_color: Color + /** + * *Can only be used if this is LuaButtonStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.pie_progress_color View documentation} + */ + pie_progress_color: Color + /** + * *Can only be used if this is LuaButtonStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.clicked_vertical_offset View documentation} + */ + clicked_vertical_offset: int + /** + * *Can only be used if this is LuaButtonStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.selected_font_color View documentation} + */ + selected_font_color: Color + /** + * *Can only be used if this is LuaButtonStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.selected_hovered_font_color View documentation} + */ + selected_hovered_font_color: Color + /** + * *Can only be used if this is LuaButtonStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.selected_clicked_font_color View documentation} + */ + selected_clicked_font_color: Color + /** + * *Can only be used if this is LuaButtonStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.strikethrough_color View documentation} + */ + strikethrough_color: Color + /** + * Horizontal space between individual cells. + * + * *Can only be used if this is LuaTableStyle, LuaFlowStyle or LuaHorizontalFlow* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.horizontal_spacing View documentation} + */ + horizontal_spacing: int + /** + * Vertical space between individual cells. + * + * *Can only be used if this is LuaTableStyle, LuaFlowStyle, LuaVerticalFlowStyle or LuaTabbedPaneStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.vertical_spacing View documentation} + */ + vertical_spacing: int + /** + * *Can only be used if this is LuaFrameStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.use_header_filler View documentation} + */ + use_header_filler: boolean + /** + * *Can only be used if this is LuaProgressBarStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.color View documentation} + */ + color: Color + /** + * Array containing the alignment for every column of this table element. Even though this property is marked as + * read-only, the alignment can be changed by indexing the LuaCustomTable, like so: + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.column_alignments View documentation} + * + * @example + * ```lua + * table_element.style.column_alignments[1] = "center" + * ``` + */ + readonly column_alignments: LuaCustomTable + /** + * *Can only be used if this is LabelStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.single_line View documentation} + */ + single_line: boolean + /** + * *Can only be used if this is ScrollPaneStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_top_padding_when_activated View documentation} + */ + extra_top_padding_when_activated: int + /** + * *Can only be used if this is ScrollPaneStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_bottom_padding_when_activated View documentation} + */ + extra_bottom_padding_when_activated: int + /** + * *Can only be used if this is ScrollPaneStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_left_padding_when_activated View documentation} + */ + extra_left_padding_when_activated: int + /** + * *Can only be used if this is ScrollPaneStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_right_padding_when_activated View documentation} + */ + extra_right_padding_when_activated: int + /** + * *Can only be used if this is ScrollPaneStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_top_margin_when_activated View documentation} + */ + extra_top_margin_when_activated: int + /** + * *Can only be used if this is ScrollPaneStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_bottom_margin_when_activated View documentation} + */ + extra_bottom_margin_when_activated: int + /** + * *Can only be used if this is ScrollPaneStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_left_margin_when_activated View documentation} + */ + extra_left_margin_when_activated: int + /** + * *Can only be used if this is ScrollPaneStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_right_margin_when_activated View documentation} + */ + extra_right_margin_when_activated: int + /** + * *Can only be used if this is ImageStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.stretch_image_to_widget_size View documentation} + */ + stretch_image_to_widget_size: boolean + /** + * *Can only be used if this is TabStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.badge_font View documentation} + */ + badge_font: string + /** + * *Can only be used if this is TabStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.badge_horizontal_spacing View documentation} + */ + badge_horizontal_spacing: int + /** + * *Can only be used if this is TabStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.default_badge_font_color View documentation} + */ + default_badge_font_color: Color + /** + * *Can only be used if this is TabStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.selected_badge_font_color View documentation} + */ + selected_badge_font_color: Color + /** + * *Can only be used if this is TabStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.disabled_badge_font_color View documentation} + */ + disabled_badge_font_color: Color + /** + * Sets both minimal and maximal width to the given value. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.width View documentation} + */ + set width(value: int) + /** + * Sets both minimal and maximal height to the given value. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.height View documentation} + */ + set height(value: int) + /** + * Sets both width and height to the given value. Also accepts an array with two values, setting width to the first + * and height to the second one. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.size View documentation} + */ + set size(value: int | int[]) + /** + * Sets top/right/bottom/left paddings to this value. An array with two values sets top/bottom padding to the first + * value and left/right padding to the second value. An array with four values sets top, right, bottom, left padding + * respectively. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.padding View documentation} + */ + set padding(value: int | int[]) + /** + * Sets top/right/bottom/left margins to this value. An array with two values sets top/bottom margin to the first + * value and left/right margin to the second value. An array with four values sets top, right, bottom, left margin + * respectively. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.margin View documentation} + */ + set margin(value: int | int[]) + /** + * Space between the table cell contents and border. Sets top/right/bottom/left cell paddings to this value. + * + * *Can only be used if this is LuaTableStyle* + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.cell_padding View documentation} + */ + set cell_padding(value: int) + /** + * Sets extra_top/right/bottom/left_padding_when_actived to this value. An array with two values sets top/bottom + * padding to the first value and left/right padding to the second value. An array with four values sets top, right, + * bottom, left padding respectively. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_padding_when_activated View documentation} + */ + set extra_padding_when_activated(value: int | int[]) + /** + * Sets extra_top/right/bottom/left_margin_when_activated to this value. An array with two values sets top/bottom + * margin to the first value and left/right margin to the second value. An array with four values sets top, right, + * bottom, left margin respectively. + * + * {@link https://lua-api.factorio.com/next/LuaStyle.html#LuaStyle.extra_margin_when_activated View documentation} + */ + set extra_margin_when_activated(value: int | int[]) + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaStyle" + /** All methods and properties that this object supports. */ + help(): string +} + +interface BaseSurfaceCreateEntity { + /** The entity prototype name to create. */ + readonly name: string + /** Where to create the entity. */ + readonly position: Position + /** Desired orientation of the entity after creation. */ + readonly direction?: defines.direction + /** Force of the entity, default is enemy. */ + readonly force?: ForceIdentification + /** Entity with health for the new entity to target. */ + readonly target?: LuaEntity + /** Source entity. Used for beams and highlight-boxes. */ + readonly source?: LuaEntity + /** If true, building will attempt to simulate fast-replace building. */ + readonly fast_replace?: boolean + /** If given set the last_user to this player. If fast_replace is true simulate fast replace using this player. */ + readonly player?: PlayerIdentification + /** + * If false while fast_replace is true and player is nil any items from fast-replacing will be deleted instead of + * dropped on the ground. + */ + readonly spill?: boolean + /** If true; {@link defines.events.script_raised_built} will be fired on successful entity creation. */ + readonly raise_built?: boolean + /** If false, the building effect smoke will not be shown around the new entity. */ + readonly create_build_effect_smoke?: boolean + /** If true, entity types that have spawn_decorations property will apply triggers defined in the property. */ + readonly spawn_decorations?: boolean + /** If true, any characters that are in the way of the entity are teleported out of the way. */ + readonly move_stuck_players?: boolean + /** + * If provided, the entity will attempt to pull stored values from this item (for example; creating a spidertron + * from a previously named and mined spidertron) + */ + readonly item?: LuaItemStack +} + +interface AssemblingMachineSurfaceCreateEntity extends BaseSurfaceCreateEntity { + readonly recipe?: string +} + +interface BeamSurfaceCreateEntity extends BaseSurfaceCreateEntity { + /** + * Absolute target position that can be used instead of target entity (entity has precedence if both entity and + * position are defined). + */ + readonly target_position?: Position + /** + * Absolute source position that can be used instead of source entity (entity has precedence if both entity and + * position are defined). + */ + readonly source_position?: Position + /** If set, beam will be destroyed when distance between source and target is greater than this value. */ + readonly max_length?: uint + /** If set, beam will be destroyed after this value of ticks. */ + readonly duration?: uint + /** Source position will be offset by this value when rendering the beam. */ + readonly source_offset?: Vector +} + +interface ContainerSurfaceCreateEntity extends BaseSurfaceCreateEntity { + /** Inventory index where the red limiting bar should be set. */ + readonly bar?: uint +} + +interface CliffSurfaceCreateEntity extends BaseSurfaceCreateEntity { + /** If not specified, `direction` will be used instead. */ + readonly cliff_orientation?: CliffOrientation +} + +interface FlyingTextSurfaceCreateEntity extends BaseSurfaceCreateEntity { + /** The string to show. */ + readonly text: LocalisedString + /** Color of the displayed text. */ + readonly color?: Color + readonly render_player_index?: uint +} + +interface EntityGhostSurfaceCreateEntity extends BaseSurfaceCreateEntity { + /** The prototype name of the entity contained in the ghost. */ + readonly inner_name: string + /** If `false` the ghost entity will not expire. Default is `false`. */ + readonly expires?: boolean +} + +interface FireSurfaceCreateEntity extends BaseSurfaceCreateEntity { + /** With how many small flames should the fire on ground be created. Defaults to the initial flame count of the prototype. */ + readonly initial_ground_flame_count?: uint8 +} + +interface InserterSurfaceCreateEntity extends BaseSurfaceCreateEntity { + readonly conditions: InserterCircuitConditions + readonly filters: InventoryFilter[] +} + +interface ItemEntitySurfaceCreateEntity extends BaseSurfaceCreateEntity { + /** The stack of items to create. */ + readonly stack: SimpleItemStack +} + +interface ItemRequestProxySurfaceCreateEntity extends BaseSurfaceCreateEntity { + /** The target items are to be delivered to. */ + readonly target: LuaEntity + /** The stacks of items to be delivered to target entity from logistic network. */ + readonly modules: Record +} + +interface RollingStockSurfaceCreateEntity extends BaseSurfaceCreateEntity { + /** The orientation of this rolling stock. */ + readonly orientation?: RealOrientation + /** The color of this rolling stock, if it supports colors. */ + readonly color?: Color +} + +interface LocomotiveSurfaceCreateEntity extends BaseSurfaceCreateEntity { + /** Whether the locomotive should snap to an adjacent train stop. Defaults to true. */ + readonly snap_to_train_stop?: boolean +} + +interface LogisticContainerSurfaceCreateEntity extends BaseSurfaceCreateEntity { + readonly request_filters?: InventoryFilter[] +} + +interface ParticleSurfaceCreateEntity extends BaseSurfaceCreateEntity { + readonly movement: Vector + readonly height: float + readonly vertical_speed: float + readonly frame_speed: float +} + +interface ArtilleryFlareSurfaceCreateEntity extends BaseSurfaceCreateEntity { + readonly movement: Vector + readonly height: float + readonly vertical_speed: float + readonly frame_speed: float +} + +interface ProjectileSurfaceCreateEntity extends BaseSurfaceCreateEntity { + readonly speed: double + readonly max_range: double +} + +interface ResourceSurfaceCreateEntity extends BaseSurfaceCreateEntity { + readonly amount: uint + /** + * If colliding trees are removed normally for this resource entity based off the prototype tree removal values. + * Default is true. + */ + readonly enable_tree_removal?: boolean + /** If colliding cliffs are removed. Default is true. */ + readonly enable_cliff_removal?: boolean + /** + * If true, the resource entity will be placed to center of a tile as map generator would place it, otherwise + * standard non-resource grid alignment rules will apply. Default is true. + */ + readonly snap_to_tile_center?: boolean +} + +interface UndergroundBeltSurfaceCreateEntity extends BaseSurfaceCreateEntity { + /** `"output"` or `"input"`; default is `"input"`. */ + readonly type?: "output" | "input" +} + +interface ProgrammableSpeakerSurfaceCreateEntity extends BaseSurfaceCreateEntity { + readonly parameters?: ProgrammableSpeakerParameters + readonly alert_parameters?: ProgrammableSpeakerAlertParameters +} + +interface CharacterCorpseSurfaceCreateEntity extends BaseSurfaceCreateEntity { + readonly inventory_size?: uint + readonly player_index?: uint +} + +interface HighlightBoxSurfaceCreateEntity extends BaseSurfaceCreateEntity { + /** + * The bounding box defining the highlight box using absolute map coordinates. If specified, the `position` + * parameter is ignored, but needs to be present anyways. If not specified, the game falls back to the `source` + * parameter first, then the `target` parameter second. One of these three parameters need to be specified. + */ + readonly bounding_box?: BoundingBox + /** Specifies the graphical appearance (color) of the highlight box. Defaults to `"electricity"`. */ + readonly box_type?: CursorBoxRenderType + /** The player to render the highlight box for. If not provided, it will be rendered for all players. */ + readonly render_player_index?: uint + /** + * The blink interval for this highlight box. Makes it be shown every `blink_interval` ticks. Defaults to `0` + * (constantly shown). + */ + readonly blink_interval?: uint + /** The amount of time in ticks that the highlight box will exist for. Defaults to existing forever. */ + readonly time_to_live?: uint +} + +interface SpeechBubbleSurfaceCreateEntity extends BaseSurfaceCreateEntity { + readonly text: LocalisedString + readonly lifetime?: uint +} + +interface SimpleEntityWithOwnerSurfaceCreateEntity extends BaseSurfaceCreateEntity { + readonly render_player_index?: uint +} + +interface SimpleEntityWithForceSurfaceCreateEntity extends BaseSurfaceCreateEntity { + readonly render_player_index?: uint +} + +type SurfaceCreateEntity = + | AssemblingMachineSurfaceCreateEntity + | BeamSurfaceCreateEntity + | ContainerSurfaceCreateEntity + | CliffSurfaceCreateEntity + | FlyingTextSurfaceCreateEntity + | EntityGhostSurfaceCreateEntity + | FireSurfaceCreateEntity + | InserterSurfaceCreateEntity + | ItemEntitySurfaceCreateEntity + | ItemRequestProxySurfaceCreateEntity + | RollingStockSurfaceCreateEntity + | LocomotiveSurfaceCreateEntity + | LogisticContainerSurfaceCreateEntity + | ParticleSurfaceCreateEntity + | ArtilleryFlareSurfaceCreateEntity + | ProjectileSurfaceCreateEntity + | ResourceSurfaceCreateEntity + | UndergroundBeltSurfaceCreateEntity + | ProgrammableSpeakerSurfaceCreateEntity + | CharacterCorpseSurfaceCreateEntity + | HighlightBoxSurfaceCreateEntity + | SpeechBubbleSurfaceCreateEntity + | SimpleEntityWithOwnerSurfaceCreateEntity + | SimpleEntityWithForceSurfaceCreateEntity + +/** + * A "domain" of the world. Surfaces can only be created and deleted through the API. Surfaces are uniquely identified + * by their name. Every game contains at least the surface "nauvis". + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html View documentation} + * + * @noSelf + */ +interface LuaSurface { + /** + * Get the pollution for a given position. + * + * **Note**: Pollution is stored per chunk, so this will return the same value for all positions in one chunk. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_pollution View documentation} + * + * @example + * ```lua + * game.surfaces[1].get_pollution({1,2}) + * ``` + * + * @param position + */ + get_pollution(position: Position): double + /** + * Check for collisions with terrain or other entities. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.can_place_entity View documentation} + */ + can_place_entity(params: { + /** Name of the entity prototype to check. */ + readonly name: string + /** Where the entity would be placed. */ + readonly position: Position + /** Direction of the placed entity. */ + readonly direction?: defines.direction + /** The force that would place the entity. If not specified, the enemy force is assumed. */ + readonly force?: ForceIdentification + /** Which type of check should be carried out. */ + readonly build_check_type?: defines.build_check_type + /** + * If `true`, entities that can be marked for deconstruction are ignored. Only used if `build_check_type` is + * either `manual_ghost`, `script_ghost` or `blueprint_ghost`. + */ + readonly forced?: boolean + /** The prototype name of the entity contained in the ghost. Only used if `name` is `entity-ghost`. */ + readonly inner_name?: string + }): boolean + /** + * If there exists an entity at the given location that can be fast-replaced with the given entity parameters. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.can_fast_replace View documentation} + */ + can_fast_replace(params: { + /** Name of the entity to check */ + readonly name: string + /** Where the entity would be placed */ + readonly position: Position + /** Direction the entity would be placed */ + readonly direction?: defines.direction + /** The force that would place the entity. If not specified, the enemy force is assumed. */ + readonly force?: ForceIdentification + }): boolean + /** + * Find a specific entity at a specific position. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_entity View documentation} + * + * @example + * ```lua + * game.player.selected.surface.find_entity('filter-inserter', {0,0}) + * ``` + * + * @param entity - Entity to look for + * @param position - Coordinates to look at + * @returns Will be `nil` if no such entity is found. + */ + find_entity(entity: string, position: Position): LuaEntity | undefined + /** + * Find entities in a given area. + * + * If no area is given all entities on the surface are returned. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_entities View documentation} + * + * @example + * Will evaluate to a list of all entities within given area. + * + * ```lua + * game.surfaces["nauvis"].find_entities({{-10, -10}, {10, 10}}) + * ``` + * + * @param area + */ + find_entities(area?: BoundingBox): LuaEntity[] + /** + * Find entities of given type or name in a given area. + * + * If no filters (`name`, `type`, `force`, etc.) are given, returns all entities in the search area. If multiple + * filters are specified, returns only entities matching all given filters. + * + * If no area or position are given, then the entire surface is searched. If position is given, returns entities + * colliding with that position (i.e the given position is within the entity's collision box). If position and + * radius are given, returns entities in that radius of the position. If area is specified, returns entities + * colliding with that area. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_entities_filtered View documentation} + * + * @example + * ```lua + * game.surfaces[1].find_entities_filtered{area = {{-10, -10}, {10, 10}}, type = "resource"} -- gets all resources in the rectangle + * game.surfaces[1].find_entities_filtered{area = {{-10, -10}, {10, 10}}, name = "iron-ore"} -- gets all iron ores in the rectangle + * game.surfaces[1].find_entities_filtered{area = {{-10, -10}, {10, 10}}, name = {"iron-ore", "copper-ore"}} -- gets all iron ore and copper ore in the rectangle + * game.surfaces[1].find_entities_filtered{area = {{-10, -10}, {10, 10}}, force = "player"} -- gets player owned entities in the rectangle + * game.surfaces[1].find_entities_filtered{area = {{-10, -10}, {10, 10}}, limit = 5} -- gets the first 5 entities in the rectangle + * game.surfaces[1].find_entities_filtered{position = {0, 0}, radius = 10} -- gets all entities within 10 tiles of the position [0,0]. + * ``` + */ + find_entities_filtered(params: { + readonly area?: BoundingBox + /** Has precedence over area field. */ + readonly position?: Position + /** If given with position, will return all entities within the radius of the position. */ + readonly radius?: double + readonly name?: string | string[] + readonly type?: string | string[] + readonly ghost_name?: string | string[] + readonly ghost_type?: string | string[] + readonly direction?: defines.direction | defines.direction[] + readonly collision_mask?: CollisionMaskLayer | CollisionMaskLayer[] + readonly force?: ForceIdentification | ForceIdentification[] + readonly to_be_deconstructed?: boolean + readonly to_be_upgraded?: boolean + readonly limit?: uint + /** + * If the filters should be inverted. These filters are: name, type, ghost_name, ghost_type, direction, + * collision_mask, force. + */ + readonly invert?: boolean + }): LuaEntity[] + /** + * Find tiles of a given name in a given area. + * + * If no filters are given returns all tiles in the search area. + * + * If no area or position and radius is given, then the entire surface is searched. If position and radius are + * given, only tiles within the radius of the position are included. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_tiles_filtered View documentation} + */ + find_tiles_filtered(params: { + readonly area?: BoundingBox + /** Ignored if not given with radius. */ + readonly position?: Position + /** If given with position, will return all entities within the radius of the position. */ + readonly radius?: double + readonly name?: string | string[] + readonly limit?: uint + readonly has_hidden_tile?: boolean + readonly collision_mask?: CollisionMaskLayer | CollisionMaskLayer[] + }): LuaTile[] + /** + * Count entities of given type or name in a given area. Works just like + * {@link LuaSurface.find_entities_filtered LuaSurface::find_entities_filtered}, except this only returns the count. + * As it doesn't construct all the wrapper objects, this is more efficient if one is only interested in the number + * of entities. + * + * If no area or position are given, then the entire surface is searched. If position is given, returns entities + * colliding with that position (i.e the given position is within the entity's collision box). If position and + * radius are given, returns entities in that radius of the position. If area is specified, returns entities + * colliding with that area. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.count_entities_filtered View documentation} + */ + count_entities_filtered(params: { + readonly area?: BoundingBox + readonly position?: Position + /** If given with position, will count all entities within the radius of the position. */ + readonly radius?: double + readonly name?: string | string[] + readonly type?: string | string[] + readonly ghost_name?: string | string[] + readonly ghost_type?: string | string[] + readonly direction?: defines.direction | defines.direction[] + readonly collision_mask?: CollisionMaskLayer | CollisionMaskLayer[] + readonly force?: ForceIdentification | ForceIdentification[] + readonly to_be_deconstructed?: boolean + readonly to_be_upgraded?: boolean + readonly limit?: uint + /** + * If the filters should be inverted. These filters are: name, type, ghost_name, ghost_type, direction, + * collision_mask, force. + */ + readonly invert?: boolean + }): uint + /** + * Count tiles of a given name in a given area. Works just like + * {@link LuaSurface.find_tiles_filtered LuaSurface::find_tiles_filtered}, except this only returns the count. As it + * doesn't construct all the wrapper objects, this is more efficient if one is only interested in the number of tiles. + * + * If no area or position and radius is given, then the entire surface is searched. If position and radius are + * given, only tiles within the radius of the position are included. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.count_tiles_filtered View documentation} + */ + count_tiles_filtered(params: { + readonly area?: BoundingBox + /** Ignored if not given with radius. */ + readonly position?: Position + /** If given with position, will return all entities within the radius of the position. */ + readonly radius?: double + readonly name?: string | string[] + readonly limit?: uint + readonly has_hidden_tile?: boolean + readonly collision_mask?: CollisionMaskLayer | CollisionMaskLayer[] + }): uint + /** + * Find a non-colliding position within a given radius. + * + * **Note**: Special care needs to be taken when using a radius of `0`. The game will not stop searching until it + * finds a suitable position, so it is important to make sure such a position exists. One particular case where it + * would not be able to find a solution is running it before any chunks have been generated. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_non_colliding_position View documentation} + * + * @param name - Prototype name of the entity to find a position for. (The bounding box for the collision checking + * is taken from this prototype.) + * @param center - Center of the search area. + * @param radius - Max distance from `center` to search in. A radius of `0` means an infinitely-large search area. + * @param precision - The step length from the given position as it searches, in tiles. Minimum value is `0.01`. + * @param force_to_tile_center - Will only check tile centers. This can be useful when your intent is to place a + * building at the resulting position, as they must generally be placed at tile centers. Default false. + * @returns The non-colliding position. May be `nil` if no suitable position was found. + */ + find_non_colliding_position( + name: string, + center: Position, + radius: double, + precision: double, + force_to_tile_center?: boolean + ): PositionTable | undefined + /** + * Find a non-colliding position within a given rectangle. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_non_colliding_position_in_box View documentation} + * + * @param name - Prototype name of the entity to find a position for. (The bounding box for the collision checking + * is taken from this prototype.) + * @param search_space - The rectangle to search inside. + * @param precision - The step length from the given position as it searches, in tiles. Minimum value is 0.01. + * @param force_to_tile_center - Will only check tile centers. This can be useful when your intent is to place a + * building at the resulting position, as they must generally be placed at tile centers. Default false. + * @returns The non-colliding position. May be `nil` if no suitable position was found. + */ + find_non_colliding_position_in_box( + name: string, + search_space: BoundingBox, + precision: double, + force_to_tile_center?: boolean + ): PositionTable | undefined + /** + * Spill items on the ground centered at a given location. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.spill_item_stack View documentation} + * + * @param position - Center of the spillage + * @param items - Items to spill + * @param enable_looted - When true, each created item will be flagged with the + * {@link LuaEntity.to_be_looted LuaEntity::to_be_looted} flag. + * @param force - When provided (and not `nil`) the items will be marked for deconstruction by this force. + * @param allow_belts - Whether items can be spilled onto belts. Defaults to `true`. + * @returns The created item-on-ground entities. + */ + spill_item_stack( + position: Position, + items: ItemStackIdentification, + enable_looted?: boolean, + force?: LuaForce | string, + allow_belts?: boolean + ): LuaEntity[] + /** + * Find enemy units (entities with type "unit") of a given force within an area. + * + * **Note**: This is more efficient than {@link LuaSurface.find_entities LuaSurface::find_entities}. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_enemy_units View documentation} + * + * @example + * Find all units who would be interested to attack the player, within 100-tile area. + * + * ```lua + * local enemies = game.player.surface.find_enemy_units(game.player.position, 100) + * ``` + * + * @param center - Center of the search area + * @param radius - Radius of the circular search area + * @param force - Force to find enemies of. If not given, uses the player force. + */ + find_enemy_units(center: Position, radius: double, force?: LuaForce | string): LuaEntity[] + /** + * Find units (entities with type "unit") of a given force and force condition within a given area. + * + * **Note**: This is more efficient than {@link LuaSurface.find_entities LuaSurface::find_entities}. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_units View documentation} + * + * @example + * Find friendly units to "player" force + * + * ```lua + * local friendly_units = game.player.surface.find_units({area = {{-10, -10},{10, 10}}, force = "player", condition = "friend") + * ``` + * + * @example + * Find units of "player" force + * + * ```lua + * local units = game.player.surface.find_units({area = {{-10, -10},{10, 10}}, force = "player", condition = "same"}) + * ``` + */ + find_units(params: { + /** Box to find units within. */ + readonly area: BoundingBox + /** Force performing the search. */ + readonly force: LuaForce | string + /** Only forces which meet the condition will be included in the search. */ + readonly condition: ForceCondition + }): LuaEntity[] + /** + * Find the enemy entity-with-force ({@link https://wiki.factorio.com/Military_units_and_structures military entity}) + * closest to the given position. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_nearest_enemy View documentation} + * + * @returns The nearest enemy entity-with-force or `nil` if no enemy could be found within the given area. + */ + find_nearest_enemy(params: { + /** Center of the search area. */ + readonly position: Position + /** Radius of the circular search area. */ + readonly max_distance: double + /** The force the result will be an enemy of. Uses the player force if not specified. */ + readonly force?: ForceIdentification + }): LuaEntity | undefined + /** + * Find the enemy entity-with-owner closest to the given position. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_nearest_enemy_entity_with_owner View documentation} + * + * @returns The nearest enemy entity-with-owner or `nil` if no enemy could be found within the given area. + */ + find_nearest_enemy_entity_with_owner(params: { + /** Center of the search area. */ + readonly position: Position + /** Radius of the circular search area. */ + readonly max_distance: double + /** The force the result will be an enemy of. Uses the player force if not specified. */ + readonly force?: ForceIdentification + }): LuaEntity | undefined + /** + * Give a command to multiple units. This will automatically select suitable units for the task. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.set_multi_command View documentation} + * + * @returns Number of units actually sent. May be less than `count` if not enough units were available. + */ + set_multi_command(params: { + readonly command: Command + /** Number of units to give the command to. */ + readonly unit_count: uint + /** Force of the units this command is to be given to. If not specified, uses the enemy force. */ + readonly force?: ForceIdentification + /** Radius to search for units. The search area is centered on the destination of the command. */ + readonly unit_search_distance?: uint + }): uint + /** + * Create an entity on this surface. + * + * Other attributes may be specified depending on the type of entity: + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.create_entity View documentation} + * + * @example + * ```lua + * asm = game.surfaces[1].create_entity{name = "assembling-machine-1", position = {15, 3}, force = game.forces.player, recipe = "iron-stick"} + * ``` + * + * @example + * Creates a filter inserter with circuit conditions and a filter + * + * ```lua + * game.surfaces[1].create_entity{ + * name = "filter-inserter", position = {20, 15}, force = game.player.force, + * conditions = {red = {name = "wood", count = 3, operator = ">"}, + * green = {name = "iron-ore", count = 1, operator = "<"}, + * logistics = {name = "wood", count = 3, operator = "="}}, + * filters = {{index = 1, name = "iron-ore"}} + * } + * ``` + * + * @example + * Creates a requester chest already set to request 128 iron plates. + * + * ```lua + * game.surfaces[1].create_entity{ + * name = "logistic-chest-requester", position = {game.player.position.x+3, game.player.position.y}, + * force = game.player.force, request_filters = {{index = 1, name = "iron-plate", count = 128}} + * } + * ``` + * + * @example + * ```lua + * game.surfaces[1].create_entity{name = "big-biter", position = {15, 3}, force = game.forces.player} -- Friendly biter + * game.surfaces[1].create_entity{name = "medium-biter", position = {15, 3}, force = game.forces.enemy} -- Enemy biter + * ``` + * + * @example + * Creates a basic inserter at the player's location facing north + * + * ```lua + * game.surfaces[1].create_entity{name = "inserter", position = game.player.position, direction = defines.direction.north} + * ``` + * + * @returns The created entity or `nil` if the creation failed. + */ + create_entity(params: SurfaceCreateEntity): LuaEntity | undefined + create_trivial_smoke(params: { + /** The smoke prototype name to create. */ + readonly name: string + /** Where to create the smoke. */ + readonly position: Position + }): void + /** + * Creates a particle at the given location + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.create_particle View documentation} + */ + create_particle(params: { + /** The particle name. */ + readonly name: string + /** Where to create the particle. */ + readonly position: Position + readonly movement: Vector + readonly height: float + readonly vertical_speed: float + readonly frame_speed: float + }): void + /** + * Create a new unit group at a given position. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.create_unit_group View documentation} + */ + create_unit_group(params: { + /** Initial position of the new unit group. */ + readonly position: Position + /** Force of the new unit group. Defaults to `"enemy"`. */ + readonly force?: ForceIdentification + }): LuaUnitGroup + /** + * Send a group to build a new base. + * + * **Note**: The specified force must be AI-controlled; i.e. `force.ai_controllable` must be `true`. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.build_enemy_base View documentation} + * + * @param position - Location of the new base. + * @param unit_count - Number of biters to send for the base-building task. + * @param force - Force the new base will belong to. Defaults to enemy. + */ + build_enemy_base(position: Position, unit_count: uint, force?: ForceIdentification): void + /** + * Get the tile at a given position. + * + * **Note**: The input position params can also be a single tile position. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_tile View documentation} + * + * @param x + * @param y + */ + get_tile(x: int, y: int): LuaTile + /** + * Set tiles at specified locations. Can automatically correct the edges around modified tiles. + * + * Placing a {@link LuaTilePrototype.mineable_properties mineable} tile on top of a non-mineable one will turn the + * latter into the {@link LuaTile.hidden_tile LuaTile::hidden_tile} for that tile. Placing a mineable tile on a + * mineable one or a non-mineable tile on a non-mineable one will not modify the hidden tile. This restriction can + * however be circumvented by using {@link LuaSurface.set_hidden_tile LuaSurface::set_hidden_tile}. + * + * **Note**: It is recommended to call this method once for all the tiles you want to change rather than calling it + * individually for every tile. As the tile correction is used after every step, calling it one by one could cause + * the tile correction logic to redo some of the changes. Also, many small API calls are generally more performance + * intensive than one big one. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.set_tiles View documentation} + * + * @param tiles + * @param correct_tiles - If `false`, the correction logic is not applied to the changed tiles. Defaults to `true`. + * @param remove_colliding_entities - `true`, `false`, or `abort_on_collision`. Defaults to `true`. + * @param remove_colliding_decoratives - `true` or `false`. Defaults to `true`. + * @param raise_event - `true` or `false`. Defaults to `false`. + */ + set_tiles( + tiles: Tile[], + correct_tiles?: boolean, + remove_colliding_entities?: boolean | string, + remove_colliding_decoratives?: boolean, + raise_event?: boolean + ): void + /** + * Spawn pollution at the given position. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.pollute View documentation} + * + * @param source - Where to spawn the pollution. + * @param amount - How much pollution to add. + */ + pollute(source: Position, amount: double): void + /** + * Get an iterator going over every chunk on this surface. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_chunks View documentation} + */ + get_chunks(): LuaChunkIterator + /** + * Is a given chunk generated? + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.is_chunk_generated View documentation} + * + * @param position - The chunk's position. + */ + is_chunk_generated(position: ChunkPosition): boolean + /** + * Request that the game's map generator generate chunks at the given position for the given radius on this surface. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.request_to_generate_chunks View documentation} + * + * @param position - Where to generate the new chunks. + * @param radius - The chunk radius from `position` to generate new chunks in. + */ + request_to_generate_chunks(position: Position, radius: uint): void + /** + * Blocks and generates all chunks that have been requested using all available threads. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.force_generate_chunk_requests View documentation} + */ + force_generate_chunk_requests(): void + /** + * Set generated status of a chunk. Useful when copying chunks. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.set_chunk_generated_status View documentation} + * + * @param position - The chunk's position. + * @param status - The chunk's new status. + */ + set_chunk_generated_status(position: ChunkPosition, status: defines.chunk_generated_status): void + /** + * Find the logistic network that covers a given position. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_logistic_network_by_position View documentation} + * + * @param position + * @param force - Force the logistic network should belong to. + * @returns The found network or `nil` if no such network was found. + */ + find_logistic_network_by_position(position: Position, force: ForceIdentification): LuaLogisticNetwork | undefined + /** + * Finds all of the logistics networks whose construction area intersects with the given position. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_logistic_networks_by_construction_area View documentation} + * + * @param position + * @param force - Force the logistic networks should belong to. + */ + find_logistic_networks_by_construction_area(position: Position, force: ForceIdentification): LuaLogisticNetwork[] + /** + * Place a deconstruction request. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.deconstruct_area View documentation} + */ + deconstruct_area(params: { + /** The area to mark for deconstruction. */ + readonly area: BoundingBox + /** The force whose bots should perform the deconstruction. */ + readonly force: ForceIdentification + /** The player to set the last_user to if any. */ + readonly player?: PlayerIdentification + /** If chunks covered by fog-of-war are skipped. */ + readonly skip_fog_of_war?: boolean + /** The deconstruction item to use if any. */ + readonly item?: LuaItemStack + }): void + /** + * Cancel a deconstruction order. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.cancel_deconstruct_area View documentation} + */ + cancel_deconstruct_area(params: { + /** The area to cancel deconstruction orders in. */ + readonly area: BoundingBox + /** The force whose deconstruction orders to cancel. */ + readonly force: ForceIdentification + /** The player to set the last_user to if any. */ + readonly player?: PlayerIdentification + /** If chunks covered by fog-of-war are skipped. */ + readonly skip_fog_of_war?: boolean + /** The deconstruction item to use if any. */ + readonly item?: LuaItemStack + }): void + /** + * Place an upgrade request. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.upgrade_area View documentation} + */ + upgrade_area(params: { + /** The area to mark for upgrade. */ + readonly area: BoundingBox + /** The force whose bots should perform the upgrade. */ + readonly force: ForceIdentification + /** The player to set the last_user to if any. */ + readonly player?: PlayerIdentification + /** If chunks covered by fog-of-war are skipped. */ + readonly skip_fog_of_war?: boolean + /** The upgrade item to use. */ + readonly item: LuaItemStack + }): void + /** + * Cancel a upgrade order. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.cancel_upgrade_area View documentation} + */ + cancel_upgrade_area(params: { + /** The area to cancel upgrade orders in. */ + readonly area: BoundingBox + /** The force whose upgrade orders to cancel. */ + readonly force: ForceIdentification + /** The player to set the last_user to if any. */ + readonly player?: PlayerIdentification + /** If chunks covered by fog-of-war are skipped. */ + readonly skip_fog_of_war?: boolean + /** The upgrade item to use if any. */ + readonly item?: LuaItemStack + }): void + /** + * The hidden tile name or `nil` if there isn't one for the given position. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_hidden_tile View documentation} + * + * @param position - The tile position. + */ + get_hidden_tile(position: TilePosition): string | undefined + /** + * Set the hidden tile for the specified position. While during normal gameplay only + * {@link LuaTilePrototype.mineable_properties non-mineable} tiles can become hidden, this method allows any kind of + * tile to be set as the hidden one. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.set_hidden_tile View documentation} + * + * @param position - The tile position. + * @param tile - The new hidden tile or `nil` to clear the hidden tile. + */ + set_hidden_tile(position: TilePosition, tile: string | LuaTilePrototype | undefined): void + /** + * Gets all tiles of the given types that are connected horizontally or vertically to the given tile position + * including the given tile position. + * + * **Note**: This won't find tiles in non-generated chunks. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_connected_tiles View documentation} + * + * @param position - The tile position to start at. + * @param tiles - The tiles to search for. + * @returns The resulting set of tiles. + */ + get_connected_tiles(position: Position, tiles: string[]): PositionTable[] + /** + * **Note**: This won't delete the chunk immediately. Chunks are deleted at the end of the current tick. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.delete_chunk View documentation} + * + * @param position - The chunk position to delete + */ + delete_chunk(position: ChunkPosition): void + /** + * Regenerate autoplacement of some entities on this surface. This can be used to autoplace newly-added entities. + * + * **Note**: All specified entity prototypes must be autoplacable. If nothing is given all entities are generated on + * all chunks. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.regenerate_entity View documentation} + * + * @param entities - Prototype names of entity or entities to autoplace. When `nil` all entities with an autoplace are used. + * @param chunks - The chunk positions to regenerate the entities on. If not given all chunks are regenerated. Note + * chunks with status < entities are ignored. + */ + regenerate_entity(entities?: string | string[], chunks?: ChunkPosition[]): void + /** + * Regenerate autoplacement of some decoratives on this surface. This can be used to autoplace newly-added decoratives. + * + * **Note**: All specified decorative prototypes must be autoplacable. If nothing is given all decoratives are + * generated on all chunks. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.regenerate_decorative View documentation} + * + * @param decoratives - Prototype names of decorative or decoratives to autoplace. When `nil` all decoratives with + * an autoplace are used. + * @param chunks - The chunk positions to regenerate the entities on. If not given all chunks are regenerated. Note + * chunks with status < entities are ignored. + */ + regenerate_decorative(decoratives?: string | string[], chunks?: ChunkPosition[]): void + /** + * Print text to the chat console of all players on this surface. + * + * **Note**: Messages that are identical to a message sent in the last 60 ticks are not printed again. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.print View documentation} + * + * @param message + * @param color + */ + print(message: LocalisedString, color?: Color): void + /** + * Removes all decoratives from the given area. If no area and no position are given, then the entire surface is searched. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.destroy_decoratives View documentation} + */ + destroy_decoratives(params: { + readonly area?: BoundingBox + readonly position?: TilePosition + readonly name?: string | string[] | LuaDecorativePrototype | LuaDecorativePrototype[] + readonly limit?: uint + /** If the filters should be inverted. */ + readonly invert?: boolean + }): void + /** + * Adds the given decoratives to the surface. + * + * **Note**: This will merge decoratives of the same type that already exist effectively increasing the "amount" field. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.create_decoratives View documentation} + */ + create_decoratives(params: { + /** If collision should be checked against entities/tiles. */ + readonly check_collision?: boolean + readonly decoratives: Decorative[] + }): void + /** + * Find decoratives of a given name in a given area. + * + * If no filters are given, returns all decoratives in the search area. If multiple filters are specified, returns + * only decoratives matching every given filter. If no area and no position are given, the entire surface is searched. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.find_decoratives_filtered View documentation} + * + * @example + * ```lua + * game.surfaces[1].find_decoratives_filtered{area = {{-10, -10}, {10, 10}}, name = "sand-decal"} -- gets all sand-decals in the rectangle + * game.surfaces[1].find_decoratives_filtered{area = {{-10, -10}, {10, 10}}, limit = 5} -- gets the first 5 decoratives in the rectangle + * ``` + */ + find_decoratives_filtered(params: { + readonly area?: BoundingBox + readonly position?: TilePosition + readonly name?: string | string[] | LuaDecorativePrototype | LuaDecorativePrototype[] + readonly limit?: uint + /** If the filters should be inverted. */ + readonly invert?: boolean + }): DecorativeResult[] + /** + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_trains View documentation} + * + * @param force - If given only trains matching this force are returned. + */ + get_trains(force?: ForceIdentification): LuaTrain[] + /** + * Clears all pollution on this surface. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.clear_pollution View documentation} + */ + clear_pollution(): void + /** + * Play a sound for every player on this surface. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.play_sound View documentation} + */ + play_sound(params: { + /** The sound to play. */ + readonly path: SoundPath + /** Where the sound should be played. If not given, it's played at the current position of each player. */ + readonly position?: Position + /** The volume of the sound to play. Must be between 0 and 1 inclusive. */ + readonly volume_modifier?: double + /** The volume mixer to play the sound through. Defaults to the default mixer for the given sound type. */ + readonly override_sound_type?: SoundType + }): void + /** + * Gets the resource amount of all resources on this surface + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_resource_counts View documentation} + */ + get_resource_counts(): Record + /** + * Gets a random generated chunk position or 0,0 if no chunks have been generated on this surface. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_random_chunk View documentation} + */ + get_random_chunk(): ChunkPositionTable + /** + * Clones the given area. + * + * **Note**: {@link defines.events.on_entity_cloned} is raised for each entity, and then + * {@link defines.events.on_area_cloned} is raised. + * + * **Note**: Entities are cloned in an order such that they can always be created, eg rails before trains. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.clone_area View documentation} + */ + clone_area(params: { + readonly source_area: BoundingBox + readonly destination_area: BoundingBox + readonly destination_surface?: SurfaceIdentification + readonly destination_force?: LuaForce | string + /** If tiles should be cloned */ + readonly clone_tiles?: boolean + /** If entities should be cloned */ + readonly clone_entities?: boolean + /** If decoratives should be cloned */ + readonly clone_decoratives?: boolean + /** If the destination entities should be cleared */ + readonly clear_destination_entities?: boolean + /** If the destination decoratives should be cleared */ + readonly clear_destination_decoratives?: boolean + /** If the destination surface should be expanded when destination_area is outside current bounds. Default false. */ + readonly expand_map?: boolean + /** If true, the building effect smoke will be shown around the new entities. */ + readonly create_build_effect_smoke?: boolean + }): void + /** + * Clones the given area. + * + * **Note**: {@link defines.events.on_entity_cloned} is raised for each entity, and then + * {@link defines.events.on_area_cloned} is raised. + * + * **Note**: Entities are cloned in an order such that they can always be created, eg rails before trains. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.clone_brush View documentation} + */ + clone_brush(params: { + readonly source_offset: TilePosition + readonly destination_offset: TilePosition + readonly source_positions: TilePosition[] + readonly destination_surface?: SurfaceIdentification + readonly destination_force?: LuaForce | string + /** If tiles should be cloned */ + readonly clone_tiles?: boolean + /** If entities should be cloned */ + readonly clone_entities?: boolean + /** If decoratives should be cloned */ + readonly clone_decoratives?: boolean + /** If the destination entities should be cleared */ + readonly clear_destination_entities?: boolean + /** If the destination decoratives should be cleared */ + readonly clear_destination_decoratives?: boolean + /** If the destination surface should be expanded when destination_area is outside current bounds. Default false. */ + readonly expand_map?: boolean + /** If manual-style collision checks should be done. */ + readonly manual_collision_mode?: boolean + /** If true, the building effect smoke will be shown around the new entities. */ + readonly create_build_effect_smoke?: boolean + }): void + /** + * Clones the given entities. + * + * **Note**: {@link defines.events.on_entity_cloned} is raised for each entity. + * + * **Note**: Entities are cloned in an order such that they can always be created, eg rails before trains. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.clone_entities View documentation} + */ + clone_entities(params: { + readonly entities: LuaEntity[] + readonly destination_offset: Vector + readonly destination_surface?: SurfaceIdentification + readonly destination_force?: ForceIdentification + readonly snap_to_grid?: boolean + /** If true, the building effect smoke will be shown around the new entities. */ + readonly create_build_effect_smoke?: boolean + }): void + /** + * Clears this surface deleting all entities and chunks on it. + * + * **Note**: This won't clear the surface immediately. It will be cleared at the end of the current tick. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.clear View documentation} + * + * @param ignore_characters - Whether characters on this surface that are connected to or associated with players + * should be ignored (not destroyed). + */ + clear(ignore_characters?: boolean): void + /** + * Generates a path with the specified constraints (as an array of {@link PathfinderWaypoint PathfinderWaypoints}) + * using the unit pathfinding algorithm. This path can be used to emulate pathing behavior by script for non-unit + * entities. If you want to command actual units to move, use the + * {@link LuaEntity.set_command LuaEntity::set_command} functionality instead. + * + * The resulting path is ultimately returned asynchronously via + * {@link OnScriptPathRequestFinishedEvent on_script_path_request_finished}. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.request_path View documentation} + * + * @returns A unique handle to identify this call when + * {@link OnScriptPathRequestFinishedEvent on_script_path_request_finished} fires. + */ + request_path(params: { + /** The dimensions of the object that's supposed to travel the path. */ + readonly bounding_box: BoundingBox + /** The list of masks the `bounding_box` collides with. */ + readonly collision_mask: CollisionMask | string[] + /** The position from which to start pathfinding. */ + readonly start: Position + /** The position to find a path to. */ + readonly goal: Position + /** The force for which to generate the path, determining which gates can be opened for example. */ + readonly force: ForceIdentification + /** How close the pathfinder needs to get to its `goal` (in tiles). Defaults to `1`. */ + readonly radius?: double + /** Flags that affect pathfinder behavior. */ + readonly pathfind_flags?: PathfinderFlags + /** Whether the path request can open gates. Defaults to `false`. */ + readonly can_open_gates?: boolean + /** + * Defines how coarse the pathfinder's grid is. Smaller values mean a coarser grid (negative numbers allowed). + * Defaults to `0`. + */ + readonly path_resolution_modifier?: int + /** Makes the pathfinder ignore collisions with this entity if it is given. */ + readonly entity_to_ignore?: LuaEntity + }): uint + /** + * Gets the script areas that match the given name or if no name is given all areas are returned. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_script_areas View documentation} + * + * @param name + */ + get_script_areas(name?: string): ScriptArea[] + /** + * Gets the first script area by name or id. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_script_area View documentation} + * + * @param key - The name or id of the area to get. + */ + get_script_area(key?: string | uint): ScriptArea + /** + * Sets the given script area to the new values. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.edit_script_area View documentation} + * + * @param id - The area to edit. + * @param area + */ + edit_script_area(id: uint, area: ScriptArea): void + /** + * Adds the given script area. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.add_script_area View documentation} + * + * @param area + * @returns The id of the created area. + */ + add_script_area(area: ScriptArea): uint + /** + * Removes the given script area. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.remove_script_area View documentation} + * + * @param id + * @returns If the area was actually removed. False when it didn't exist. + */ + remove_script_area(id: uint): boolean + /** + * Gets the script positions that match the given name or if no name is given all positions are returned. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_script_positions View documentation} + * + * @param name + */ + get_script_positions(name?: string): ScriptPosition[] + /** + * Gets the first script position by name or id. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_script_position View documentation} + * + * @param key - The name or id of the position to get. + */ + get_script_position(key?: string | uint): ScriptPosition + /** + * Sets the given script position to the new values. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.edit_script_position View documentation} + * + * @param id - The position to edit. + * @param area + */ + edit_script_position(id: uint, area: ScriptPosition): void + /** + * Adds the given script position. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.add_script_position View documentation} + * + * @param area + * @returns The id of the created position. + */ + add_script_position(area: ScriptPosition): uint + /** + * Removes the given script position. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.remove_script_position View documentation} + * + * @param id + * @returns If the position was actually removed. False when it didn't exist. + */ + remove_script_position(id: uint): boolean + /** + * Gets the map exchange string for the current map generation settings of this surface. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_map_exchange_string View documentation} + */ + get_map_exchange_string(): string + /** + * Gets the starting area radius of this surface. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_starting_area_radius View documentation} + */ + get_starting_area_radius(): double + /** + * Gets the closest entity in the list to this position. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_closest View documentation} + * + * @param position + * @param entities - The Entities to check + */ + get_closest(position: Position, entities: LuaEntity[]): LuaEntity + /** + * Gets train stops matching the given filters. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_train_stops View documentation} + */ + get_train_stops(params?: { readonly name?: string | string[]; readonly force?: ForceIdentification }): LuaEntity[] + /** + * Gets the total amount of pollution on the surface by iterating over all of the chunks containing pollution. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_total_pollution View documentation} + */ + get_total_pollution(): double + /** + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.entity_prototype_collides View documentation} + * + * @param prototype - The entity prototype to check + * @param position - The position to check + * @param use_map_generation_bounding_box - If the map generation bounding box should be used instead of the + * collision bounding box + * @param direction + */ + entity_prototype_collides( + prototype: EntityPrototypeIdentification, + position: Position, + use_map_generation_bounding_box: boolean, + direction?: defines.direction + ): void + /** + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.decorative_prototype_collides View documentation} + * + * @param prototype - The decorative prototype to check + * @param position - The position to check + */ + decorative_prototype_collides(prototype: string, position: Position): void + /** + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.calculate_tile_properties View documentation} + * + * @param property_names - Names of properties (e.g. "elevation") to calculate + * @param positions - Positions for which to calculate property values + * @returns Table of property value lists, keyed by property name + */ + calculate_tile_properties(property_names: string[], positions: Position[]): Record + /** + * Returns all the entities with force on this chunk for the given force. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.get_entities_with_force View documentation} + * + * @param position - The chunk's position. + * @param force - Entities of this force will be returned. + */ + get_entities_with_force(position: ChunkPosition, force: LuaForce | string): LuaEntity[] + /** + * Sets the given area to the checkerboard lab tiles. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.build_checkerboard View documentation} + * + * @param area - The tile area. + */ + build_checkerboard(area: BoundingBox): void + /** + * The name of this surface. Names are unique among surfaces. + * + * **Note**: the default surface can't be renamed. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.name View documentation} + */ + name: string + /** + * Unique ID associated with this surface. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.index View documentation} + */ + readonly index: uint + /** + * The generation settings for this surface. These can be modified to after surface generation, but note that this + * will not retroactively update the surface. To manually adjust it, + * {@link LuaSurface.regenerate_entity LuaSurface::regenerate_entity}, + * {@link LuaSurface.regenerate_decorative LuaSurface::regenerate_decorative} and + * {@link LuaSurface.delete_chunk LuaSurface::delete_chunk} can be used. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.map_gen_settings View documentation} + */ + map_gen_settings: MapGenSettings + /** + * When set to true, new chunks will be generated with lab tiles, instead of using the surface's map generation settings. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.generate_with_lab_tiles View documentation} + */ + generate_with_lab_tiles: boolean + /** + * When set to true, the sun will always shine. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.always_day View documentation} + */ + always_day: boolean + /** + * Current time of day, as a number in range [0, 1). + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.daytime View documentation} + */ + daytime: float + /** + * Amount of darkness at the current time. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.darkness View documentation} + */ + readonly darkness: float + /** + * Current wind speed. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.wind_speed View documentation} + */ + wind_speed: double + /** + * Current wind direction. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.wind_orientation View documentation} + */ + wind_orientation: RealOrientation + /** + * Change in wind orientation per tick. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.wind_orientation_change View documentation} + */ + wind_orientation_change: double + /** + * Is peaceful mode enabled on this surface? + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.peaceful_mode View documentation} + */ + peaceful_mode: boolean + /** + * True if daytime is currently frozen. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.freeze_daytime View documentation} + */ + freeze_daytime: boolean + /** + * The number of ticks per day for this surface. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.ticks_per_day View documentation} + */ + ticks_per_day: uint + /** + * The daytime when dusk starts. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.dusk View documentation} + */ + dusk: double + /** + * The daytime when dawn starts. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.dawn View documentation} + */ + dawn: double + /** + * The daytime when evening starts. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.evening View documentation} + */ + evening: double + /** + * The daytime when morning starts. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.morning View documentation} + */ + morning: double + /** + * The multiplier of solar power on this surface. Cannot be less than 0. + * + * **Note**: Solar equipment is still limited to its maximum power output. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.solar_power_multiplier View documentation} + */ + solar_power_multiplier: double + /** + * The minimal brightness during the night. Default is `0.15`. The value has an effect on the game simalution only, + * it doesn't have any effect on rendering. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.min_brightness View documentation} + */ + min_brightness: double + /** + * Defines how surface daytime brightness influences each color channel of the current color lookup table (LUT). + * + * The LUT is multiplied by `((1 - weight) + brightness * weight)` and result is clamped to range [0, 1]. + * + * Default is `{0, 0, 0}`, which means no influence. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.brightness_visual_weights View documentation} + * + * @example + * Makes night on the surface pitch black, assuming {@link LuaSurface.min_brightness LuaSurface::min_brightness} being set to default value `0.15`. + * + * ```lua + * game.surfaces[1].brightness_visual_weights = { 1 / 0.85, 1 / 0.85, 1 / 0.85 } + * ``` + */ + brightness_visual_weights: ColorModifier + /** + * If clouds are shown on this surface. + * + * **Note**: If false, clouds are never shown. If true the player must also have clouds enabled in graphics settings + * for them to be shown. + * + * {@link https://lua-api.factorio.com/next/LuaSurface.html#LuaSurface.show_clouds View documentation} + */ + show_clouds: boolean + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaSurface" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * One research item. + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html View documentation} + * + * @noSelf + */ +interface LuaTechnology { + /** + * Reload this technology from its prototype. + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.reload View documentation} + */ + reload(): void + /** + * The force this technology belongs to. + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.force View documentation} + */ + readonly force: LuaForce + /** + * Name of this technology. + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.name View documentation} + */ + readonly name: string + /** + * Localised name of this technology. + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.localised_name View documentation} + */ + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * The prototype of this technology. + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.prototype View documentation} + */ + readonly prototype: LuaTechnologyPrototype + /** + * Can this technology be researched? + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.enabled View documentation} + */ + enabled: boolean + /** + * If this technology will be visible in the research GUI even though it is disabled. + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.visible_when_disabled View documentation} + */ + visible_when_disabled: boolean + /** + * Is this an upgrade-type research? + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.upgrade View documentation} + */ + readonly upgrade: boolean + /** + * Has this technology been researched? Switching from `false` to `true` will trigger the technology advancement + * perks; switching from `true` to `false` will reverse them. + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.researched View documentation} + */ + researched: boolean + /** + * Prerequisites of this technology. The result maps technology name to the {@link LuaTechnology} object. + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.prerequisites View documentation} + */ + readonly prerequisites: Record + /** + * Ingredients labs will require to research this technology. + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.research_unit_ingredients View documentation} + * + * @see {@link LuaTechnology.research_unit_count} + */ + readonly research_unit_ingredients: Ingredient[] + /** + * Effects applied when this technology is researched. + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.effects View documentation} + */ + readonly effects: TechnologyModifier[] + /** + * Number of research units required for this technology. + * + * **Note**: This is multiplied by the current research cost multiplier, unless + * {@link LuaTechnologyPrototype.ignore_tech_cost_multiplier LuaTechnologyPrototype::ignore_tech_cost_multiplier} is `true`. + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.research_unit_count View documentation} + * + * @see {@link LuaTechnology.research_unit_ingredients} + */ + readonly research_unit_count: uint + /** + * Amount of energy required to finish a unit of research. + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.research_unit_energy View documentation} + */ + readonly research_unit_energy: double + /** + * Order string for this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.order View documentation} + */ + readonly order: string + /** + * The current level of this technology. For level-based technology writing to this is the same as researching the + * technology to the *previous* level. Writing the level will set + * {@link LuaTechnology.enabled LuaTechnology::enabled} to `true`. + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.level View documentation} + */ + level: uint + /** + * The count formula used for this infinite research or nil if this isn't an infinite research. + * + * {@link https://lua-api.factorio.com/next/LuaTechnology.html#LuaTechnology.research_unit_count_formula View documentation} + * + * @see {@link LuaGameScript.evaluate_expression} + */ + readonly research_unit_count_formula: string | undefined + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaTechnology" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A Technology prototype. + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html View documentation} + * + * @noSelf + */ +interface LuaTechnologyPrototype { + /** + * Name of this technology. + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.name View documentation} + */ + readonly name: string + /** + * Localised name of this technology. + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.localised_name View documentation} + */ + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * If this technology prototype is enabled by default (enabled at the beginning of a game). + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.enabled View documentation} + */ + readonly enabled: boolean + /** + * If this technology prototype is hidden. + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.hidden View documentation} + */ + readonly hidden: boolean + /** + * If this technology will be visible in the research GUI even though it is disabled. + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.visible_when_disabled View documentation} + */ + readonly visible_when_disabled: boolean + /** + * If this technology ignores the technology cost multiplier setting. + * + * **Note**: {@link LuaTechnologyPrototype.research_unit_count LuaTechnologyPrototype::research_unit_count} will + * already take this setting into account. + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.ignore_tech_cost_multiplier View documentation} + */ + readonly ignore_tech_cost_multiplier: boolean + /** + * If the is technology prototype is an upgrade to some other technology. + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.upgrade View documentation} + */ + readonly upgrade: boolean + /** + * Prerequisites of this technology. The result maps technology name to the {@link LuaTechnologyPrototype} object. + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.prerequisites View documentation} + */ + readonly prerequisites: Record + /** + * Ingredients labs will require to research this technology. + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.research_unit_ingredients View documentation} + * + * @see {@link LuaTechnologyPrototype.research_unit_count} + */ + readonly research_unit_ingredients: Ingredient[] + /** + * Effects applied when this technology is researched. + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.effects View documentation} + */ + readonly effects: TechnologyModifier[] + /** + * Number of research units required for this technology. + * + * **Note**: This is multiplied by the current research cost multiplier, unless + * {@link LuaTechnologyPrototype.ignore_tech_cost_multiplier LuaTechnologyPrototype::ignore_tech_cost_multiplier} is `true`. + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.research_unit_count View documentation} + * + * @see {@link LuaTechnologyPrototype.research_unit_ingredients} + */ + readonly research_unit_count: uint + /** + * Amount of energy required to finish a unit of research. + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.research_unit_energy View documentation} + */ + readonly research_unit_energy: double + /** + * Order string for this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.order View documentation} + */ + readonly order: string + /** + * The level of this research. + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.level View documentation} + */ + readonly level: uint + /** + * The max level of this research. + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.max_level View documentation} + */ + readonly max_level: uint + /** + * The count formula used for this infinite research or nil if this isn't an infinite research. + * + * {@link https://lua-api.factorio.com/next/LuaTechnologyPrototype.html#LuaTechnologyPrototype.research_unit_count_formula View documentation} + * + * @see {@link LuaGameScript.evaluate_expression} + */ + readonly research_unit_count_formula: string | undefined + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaTechnologyPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A single "square" on the map. + * + * {@link https://lua-api.factorio.com/next/LuaTile.html View documentation} + * + * @noSelf + */ +interface LuaTile { + /** + * What type of things can collide with this tile? + * + * {@link https://lua-api.factorio.com/next/LuaTile.html#LuaTile.collides_with View documentation} + * + * @example + * Check if the character would collide with a tile + * + * ```lua + * game.player.print(tostring(game.player.surface.get_tile(1, 1).collides_with("player-layer"))) + * ``` + * + * @param layer + */ + collides_with(layer: CollisionMaskLayer): boolean + /** + * Is this tile marked for deconstruction? + * + * {@link https://lua-api.factorio.com/next/LuaTile.html#LuaTile.to_be_deconstructed View documentation} + */ + to_be_deconstructed(): boolean + /** + * Orders deconstruction of this tile by the given force. + * + * {@link https://lua-api.factorio.com/next/LuaTile.html#LuaTile.order_deconstruction View documentation} + * + * @param force - The force whose robots are supposed to do the deconstruction. + * @param player - The player to set the last_user to if any. + * @returns The deconstructible tile proxy created if any or `nil`. + */ + order_deconstruction(force: ForceIdentification, player?: PlayerIdentification): LuaEntity | undefined + /** + * Cancels deconstruction if it is scheduled, does nothing otherwise. + * + * {@link https://lua-api.factorio.com/next/LuaTile.html#LuaTile.cancel_deconstruction View documentation} + * + * @param force - The force who did the deconstruction order. + * @param player - The player to set the last_user to if any. + */ + cancel_deconstruction(force: ForceIdentification, player?: PlayerIdentification): void + /** + * Prototype name of this tile. E.g. `"sand-3"` or `"grass-2"`. + * + * {@link https://lua-api.factorio.com/next/LuaTile.html#LuaTile.name View documentation} + */ + readonly name: string + readonly prototype: LuaTilePrototype + /** + * The position this tile references. + * + * {@link https://lua-api.factorio.com/next/LuaTile.html#LuaTile.position View documentation} + */ + readonly position: PositionTable + /** + * The name of the {@link LuaTilePrototype} hidden under this tile or `nil` if there is no hidden tile. During normal + * gameplay, only {@link LuaTilePrototype.mineable_properties non-mineable} tiles can become hidden. This can however + * be circumvented with {@link LuaSurface.set_hidden_tile LuaSurface::set_hidden_tile}. + * + * {@link https://lua-api.factorio.com/next/LuaTile.html#LuaTile.hidden_tile View documentation} + */ + readonly hidden_tile: string | undefined + /** + * The surface this tile is on. + * + * {@link https://lua-api.factorio.com/next/LuaTile.html#LuaTile.surface View documentation} + */ + readonly surface: LuaSurface + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaTile" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a tile. + * + * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html View documentation} + * + * @noSelf + */ +interface LuaTilePrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * The collision mask this tile uses + * + * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.collision_mask View documentation} + */ + readonly collision_mask: CollisionMask + readonly collision_mask_with_flags: CollisionMaskWithFlags + readonly layer: uint + /** + * Autoplace specification for this prototype. `nil` if none. + * + * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.autoplace_specification View documentation} + */ + readonly autoplace_specification: AutoplaceSpecification | undefined + readonly walking_speed_modifier: float + readonly vehicle_friction_modifier: float + readonly map_color: ColorTable + /** + * The probability that decorative entities will be removed from on top of this tile when this tile is generated. + * + * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.decorative_removal_probability View documentation} + */ + readonly decorative_removal_probability: float + readonly automatic_neighbors: boolean + readonly allowed_neighbors: Record + /** + * If this tile needs correction logic applied when it's generated in the world.. + * + * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.needs_correction View documentation} + */ + readonly needs_correction: boolean + readonly mineable_properties: { + /** Is this tile mineable at all? */ + readonly minable: boolean + /** Energy required to mine a tile. */ + readonly miningtime: double + /** + * Prototype name of the particle produced when mining this tile. Will only be present if this tile produces any + * particle during mining. + */ + readonly miningparticle?: string + /** Products obtained by mining this tile. */ + readonly products: Product[] + } + /** + * The next direction of this tile or `nil` - used when a tile has multiple directions (such as hazard concrete) + * + * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.next_direction View documentation} + */ + readonly next_direction: LuaTilePrototype | undefined + /** + * Items that when placed will produce this tile. It is a dictionary indexed by the item prototype name. + * + * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.items_to_place_this View documentation} + */ + readonly items_to_place_this: SimpleItemStack[] + /** + * False if this tile is not allowed in blueprints regardless of the ability to build it. + * + * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.can_be_part_of_blueprint View documentation} + */ + readonly can_be_part_of_blueprint: boolean + /** + * Amount of pollution emissions per second this tile will absorb. + * + * {@link https://lua-api.factorio.com/next/LuaTilePrototype.html#LuaTilePrototype.emissions_per_second View documentation} + */ + readonly emissions_per_second: double + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaTilePrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A train. Trains are a sequence of connected rolling stocks -- locomotives and wagons. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html View documentation} + * + * @noSelf + */ +interface LuaTrain { + /** + * Get the amount of a particular item stored in the train. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.get_item_count View documentation} + * + * @param item - Item name to count. If not given, counts all items. + */ + get_item_count(item?: string): uint + /** + * Get a mapping of the train's inventory. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.get_contents View documentation} + * + * @returns The counts, indexed by item names. + */ + get_contents(): Record + /** + * Remove some items from the train. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.remove_item View documentation} + * + * @param stack - The amount and type of items to remove + * @returns Number of items actually removed. + */ + remove_item(stack: ItemStackIdentification): uint + /** + * Insert a stack into the train. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.insert View documentation} + * + * @param stack + */ + insert(stack: ItemStackIdentification): void + /** + * Clear all items in this train. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.clear_items_inside View documentation} + */ + clear_items_inside(): void + /** + * Checks if the path is invalid and tries to re-path if it isn't. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.recalculate_path View documentation} + * + * @param force - Forces the train to re-path regardless of the current path being valid or not. + * @returns If the train has a path after the repath attempt. + */ + recalculate_path(force?: boolean): boolean + /** + * Get the amount of a particular fluid stored in the train. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.get_fluid_count View documentation} + * + * @param fluid - Fluid name to count. If not given, counts all fluids. + */ + get_fluid_count(fluid?: string): double + /** + * Gets a mapping of the train's fluid inventory. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.get_fluid_contents View documentation} + * + * @returns The counts, indexed by fluid names. + */ + get_fluid_contents(): Record + /** + * Remove some fluid from the train. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.remove_fluid View documentation} + * + * @param fluid + * @returns The amount of fluid actually removed. + */ + remove_fluid(fluid: Fluid): double + /** + * Inserts the given fluid into the first available location in this train. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.insert_fluid View documentation} + * + * @param fluid + * @returns The amount inserted. + */ + insert_fluid(fluid: Fluid): double + /** + * Clears all fluids in this train. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.clear_fluids_inside View documentation} + */ + clear_fluids_inside(): void + /** + * Go to the station specified by the index in the train's schedule. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.go_to_station View documentation} + * + * @param index + */ + go_to_station(index: uint): void + /** + * Gets all rails under the train. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.get_rails View documentation} + */ + get_rails(): LuaEntity[] + /** + * When `true`, the train is explicitly controlled by the player or script. When `false`, the train moves + * autonomously according to its schedule. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.manual_mode View documentation} + */ + manual_mode: boolean + /** + * Current speed. + * + * **Note**: Changing the speed of the train is potentially an unsafe operation because train uses the speed for its + * internal calculations of break distances, etc. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.speed View documentation} + */ + speed: double + /** + * Current max speed when moving forward, depends on locomotive prototype and fuel. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.max_forward_speed View documentation} + */ + readonly max_forward_speed: double + /** + * Current max speed when moving backwards, depends on locomotive prototype and fuel. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.max_backward_speed View documentation} + */ + readonly max_backward_speed: double + /** + * The weight of this train. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.weight View documentation} + */ + readonly weight: double + /** + * Rolling stocks the train is composed of. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.carriages View documentation} + */ + readonly carriages: LuaEntity[] + /** + * Arrays of locomotives. The result is two arrays, indexed by `"front_movers"` and `"back_movers"` containing the + * locomotives. E.g. `{front_movers={loco1, loco2}, back_movers={loco3}}`. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.locomotives View documentation} + */ + readonly locomotives: Record + /** + * The cargo carriages the train contains. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.cargo_wagons View documentation} + */ + readonly cargo_wagons: LuaEntity[] + /** + * The fluid carriages the train contains. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.fluid_wagons View documentation} + */ + readonly fluid_wagons: LuaEntity[] + /** + * The trains current schedule or `nil` if empty. Set to `nil` to clear. + * + * **Note**: The schedule can't be changed by modifying the returned table. Instead, changes must be made by + * assigning a new table to this attribute. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.schedule View documentation} + */ + schedule: TrainSchedule | undefined + /** + * This train's current state. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.state View documentation} + */ + readonly state: defines.train_state + /** + * The rail at the front end of the train, possibly `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.front_rail View documentation} + */ + readonly front_rail: LuaEntity | undefined + /** + * The rail at the back end of the train, possibly `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.back_rail View documentation} + */ + readonly back_rail: LuaEntity | undefined + readonly rail_direction_from_front_rail: defines.rail_direction + readonly rail_direction_from_back_rail: defines.rail_direction + /** + * The front stock of this train or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.front_stock View documentation} + */ + readonly front_stock: LuaEntity | undefined + /** + * The back stock of this train or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.back_stock View documentation} + */ + readonly back_stock: LuaEntity | undefined + /** + * The train stop this train is stopped at or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.station View documentation} + */ + readonly station: LuaEntity | undefined + /** + * If this train has a path. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.has_path View documentation} + */ + readonly has_path: boolean + /** + * The destination rail this train is currently pathing to or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.path_end_rail View documentation} + */ + readonly path_end_rail: LuaEntity | undefined + /** + * The destination train stop this train is currently pathing to or `nil`. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.path_end_stop View documentation} + */ + readonly path_end_stop: LuaEntity | undefined + /** + * The unique train ID. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.id View documentation} + */ + readonly id: uint + /** + * The player passengers on the train + * + * **Note**: This does *not* index using player index. See {@link LuaPlayer.index LuaPlayer::index} on each player + * instance for the player index. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.passengers View documentation} + */ + readonly passengers: LuaPlayer[] + /** + * The riding state of this train. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.riding_state View documentation} + */ + readonly riding_state: RidingState + /** + * The players killed by this train. + * + * The keys are the player indexes, the values are how often this train killed that player. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.killed_players View documentation} + */ + readonly killed_players: Record + /** + * The total number of kills by this train. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.kill_count View documentation} + */ + readonly kill_count: uint + /** + * The path this train is using or `nil` if none. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.path View documentation} + */ + readonly path: LuaRailPath | undefined + /** + * The signal this train is arriving or waiting at or `nil` if none. + * + * {@link https://lua-api.factorio.com/next/LuaTrain.html#LuaTrain.signal View documentation} + */ + readonly signal: LuaEntity | undefined + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaTrain" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Control behavior for train stops. + * + * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaTrainStopControlBehavior extends LuaGenericOnOffControlBehavior { + /** + * `true` if the train stop should send the circuit network contents to the train to use. + * + * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.send_to_train View documentation} + */ + send_to_train: boolean + /** + * `true` if the train stop should send the train contents to the circuit network. + * + * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.read_from_train View documentation} + */ + read_from_train: boolean + /** + * `true` if the train stop should send the stopped train id to the circuit network. + * + * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.read_stopped_train View documentation} + */ + read_stopped_train: boolean + /** + * `true` if the trains_limit_signal is used to set a limit of trains incoming for train stop. + * + * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.set_trains_limit View documentation} + */ + set_trains_limit: boolean + /** + * `true` if the train stop should send amount of incoming trains to the circuit network. + * + * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.read_trains_count View documentation} + */ + read_trains_count: boolean + /** + * `true` if the train stop is enabled/disabled through the circuit network. + * + * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.enable_disable View documentation} + */ + enable_disable: boolean + /** + * The signal that will be sent when using the send-train-id option. + * + * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.stopped_train_signal View documentation} + */ + stopped_train_signal: SignalID + /** + * The signal that will be sent when using the read-trains-count option. + * + * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.trains_count_signal View documentation} + */ + trains_count_signal: SignalID + /** + * The signal to be used by set-trains-limit to limit amount of incoming trains + * + * {@link https://lua-api.factorio.com/next/LuaTrainStopControlBehavior.html#LuaTrainStopControlBehavior.trains_limit_signal View documentation} + */ + trains_limit_signal: SignalID + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaTrainStopControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Control behavior for transport belts. + * + * {@link https://lua-api.factorio.com/next/LuaTransportBeltControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaTransportBeltControlBehavior extends LuaGenericOnOffControlBehavior { + /** + * If the belt will be enabled/disabled based off the circuit network. + * + * {@link https://lua-api.factorio.com/next/LuaTransportBeltControlBehavior.html#LuaTransportBeltControlBehavior.enable_disable View documentation} + */ + enable_disable: boolean + /** + * If the belt will read the contents and send them to the circuit network. + * + * {@link https://lua-api.factorio.com/next/LuaTransportBeltControlBehavior.html#LuaTransportBeltControlBehavior.read_contents View documentation} + */ + read_contents: boolean + /** + * The read mode for the belt. + * + * {@link https://lua-api.factorio.com/next/LuaTransportBeltControlBehavior.html#LuaTransportBeltControlBehavior.read_contents_mode View documentation} + */ + read_contents_mode: defines.control_behavior.transport_belt.content_read_mode + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaTransportBeltControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * One line on a transport belt. + * + * {@link https://lua-api.factorio.com/next/LuaTransportLine.html View documentation} + * + * @noSelf + */ +interface LuaTransportLine extends ReadonlyArray { + /** + * Remove all items from this transport line. + * + * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.clear View documentation} + */ + clear(): void + /** + * Count some or all items on this line. + * + * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.get_item_count View documentation} + * + * @param item - Prototype name of the item to count. If not specified, count all items. + * @see {@link LuaInventory.get_item_count} + */ + get_item_count(item?: string): uint + /** + * Remove some items from this line. + * + * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.remove_item View documentation} + * + * @param items - Items to remove. + * @returns Number of items actually removed. + */ + remove_item(items: ItemStackIdentification): uint + /** + * Can an item be inserted at a given position? + * + * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.can_insert_at View documentation} + * + * @param position - Where to insert an item. + */ + can_insert_at(position: float): boolean + /** + * Can an item be inserted at the back of this line? + * + * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.can_insert_at_back View documentation} + */ + can_insert_at_back(): boolean + /** + * Insert items at a given position. + * + * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.insert_at View documentation} + * + * @param position - Where on the line to insert the items. + * @param items - Items to insert. + * @returns Were the items inserted successfully? + */ + insert_at(position: float, items: ItemStackIdentification): boolean + /** + * Insert items at the back of this line. + * + * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.insert_at_back View documentation} + * + * @param items + * @returns Were the items inserted successfully? + */ + insert_at_back(items: ItemStackIdentification): boolean + /** + * Get counts of all items on this line. + * + * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.get_contents View documentation} + * + * @returns The counts, indexed by item names. + * @see {@link LuaInventory.get_contents} + */ + get_contents(): Record + /** + * Returns whether the associated internal transport line of this line is the same as the others associated internal + * transport line. + * + * **Note**: This can return true even when the {@link LuaTransportLine.owner LuaTransportLine::owner}s are different + * (so `this == other` is false), because the internal transport lines can span multiple tiles. + * + * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.line_equals View documentation} + * + * @param other + */ + line_equals(other: LuaTransportLine): boolean + /** + * Get the number of items on this transport line. + * + * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.operator%20# View documentation} + */ + readonly length: uint + /** + * The entity this transport line belongs to. + * + * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.owner View documentation} + */ + readonly owner: LuaEntity + /** + * The transport lines that this transport line outputs items to or an empty table if none. + * + * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.output_lines View documentation} + */ + readonly output_lines: LuaTransportLine[] + /** + * The transport lines that this transport line is fed by or an empty table if none. + * + * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.input_lines View documentation} + */ + readonly input_lines: LuaTransportLine[] + /** + * The indexing operator. + * + * {@link https://lua-api.factorio.com/next/LuaTransportLine.html#LuaTransportLine.operator%20[] View documentation} + */ + readonly [index: number]: LuaItemStack + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaTransportLine" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a trivial smoke. + * + * {@link https://lua-api.factorio.com/next/LuaTrivialSmokePrototype.html View documentation} + * + * @noSelf + */ +interface LuaTrivialSmokePrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaTrivialSmokePrototype.html#LuaTrivialSmokePrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaTrivialSmokePrototype.html#LuaTrivialSmokePrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + readonly color: ColorTable + readonly start_scale: double + readonly end_scale: double + readonly movement_slow_down_factor: double + readonly duration: uint + readonly spread_duration: uint + readonly fade_away_duration: uint + readonly fade_in_duration: uint + readonly glow_fade_away_duration: uint + readonly cyclic: boolean + readonly affected_by_wind: boolean + readonly show_when_smoke_off: boolean + readonly glow_animation: boolean + readonly render_layer: RenderLayer + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaTrivialSmokePrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * A collection of units moving and attacking together. The engine creates autonomous unit groups to attack polluted + * areas. The script can create and control such groups as well. Groups can accept commands in the same manner as regular units. + * + * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html View documentation} + * + * @noSelf + */ +interface LuaUnitGroup { + /** + * Make a unit a member of this group. Has the same effect as giving a `group_command` with this group to the unit. + * + * **Note**: The member must have the same force as the unit group. + * + * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.add_member View documentation} + * + * @param unit + */ + add_member(unit: LuaEntity): void + /** + * Give this group a command. + * + * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.set_command View documentation} + * + * @param command + * @see {@link LuaEntity.set_command} + */ + set_command(command: Command): void + /** + * Give this group a distraction command. + * + * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.set_distraction_command View documentation} + * + * @param command + * @see {@link LuaEntity.set_command} + */ + set_distraction_command(command: Command): void + /** + * Make this group autonomous. Autonomous groups will automatically attack polluted areas. Autonomous groups aren't + * considered to be script driven + * + * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.set_autonomous View documentation} + * + * @see {@link LuaUnitGroup.is_script_driven} + */ + set_autonomous(): void + /** + * Make the group start moving even if some of its members haven't yet arrived. + * + * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.start_moving View documentation} + */ + start_moving(): void + /** + * Dissolve this group. Its members won't be destroyed, they will be merely unlinked from this group. + * + * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.destroy View documentation} + */ + destroy(): void + /** + * Members of this group. + * + * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.members View documentation} + */ + readonly members: LuaEntity[] + /** + * Group position. This can have different meanings depending on the group state. When the group is gathering, the + * position is the place of gathering. When the group is moving, the position is the expected position of its + * members along the path. When the group is attacking, it is the average position of its members. + * + * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.position View documentation} + */ + readonly position: PositionTable + /** + * Whether this group is gathering, moving or attacking. + * + * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.state View documentation} + */ + readonly state: defines.group_state + /** + * The force of this unit group. + * + * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.force View documentation} + */ + readonly force: LuaForce + /** + * The surface of this unit group. + * + * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.surface View documentation} + */ + readonly surface: LuaSurface + /** + * The group number for this unit group. + * + * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.group_number View documentation} + */ + readonly group_number: uint + /** + * Whether this unit group is controlled by a script or by the game engine. + * + * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.is_script_driven View documentation} + * + * @see {@link LuaUnitGroup.set_autonomous} + */ + readonly is_script_driven: boolean + /** + * The command given to this group or `nil` is the group has no command. + * + * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.command View documentation} + */ + readonly command: Command | undefined + /** + * The distraction command given to this group or `nil` is the group currently isn't distracted. + * + * {@link https://lua-api.factorio.com/next/LuaUnitGroup.html#LuaUnitGroup.distraction_command View documentation} + */ + readonly distraction_command: Command | undefined + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaUnitGroup" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a virtual signal. + * + * {@link https://lua-api.factorio.com/next/LuaVirtualSignalPrototype.html View documentation} + * + * @noSelf + */ +interface LuaVirtualSignalPrototype { + /** + * Name of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaVirtualSignalPrototype.html#LuaVirtualSignalPrototype.name View documentation} + */ + readonly name: string + /** + * Order string of this prototype. + * + * {@link https://lua-api.factorio.com/next/LuaVirtualSignalPrototype.html#LuaVirtualSignalPrototype.order View documentation} + */ + readonly order: string + readonly localised_name: LocalisedString + readonly localised_description: LocalisedString + /** + * If this is a special signal + * + * {@link https://lua-api.factorio.com/next/LuaVirtualSignalPrototype.html#LuaVirtualSignalPrototype.special View documentation} + */ + readonly special: boolean + readonly subgroup: LuaGroup + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaVirtualSignalPrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Prototype of a void energy source. + * + * {@link https://lua-api.factorio.com/next/LuaVoidEnergySourcePrototype.html View documentation} + * + * @noSelf + */ +interface LuaVoidEnergySourcePrototype { + readonly emissions: double + readonly render_no_network_icon: boolean + readonly render_no_power_icon: boolean + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaVoidEnergySourcePrototype" + /** All methods and properties that this object supports. */ + help(): string +} + +/** + * Control behavior for walls. + * + * {@link https://lua-api.factorio.com/next/LuaWallControlBehavior.html View documentation} + * + * @noSelf + */ +interface LuaWallControlBehavior extends LuaControlBehavior { + /** + * The circuit condition. + * + * {@link https://lua-api.factorio.com/next/LuaWallControlBehavior.html#LuaWallControlBehavior.circuit_condition View documentation} + */ + circuit_condition: CircuitConditionDefinition + open_gate: boolean + read_sensor: boolean + output_signal: SignalID + /** + * Is this object valid? This Lua object holds a reference to an object within the game engine. It is possible that + * the game-engine object is removed whilst a mod still holds the corresponding Lua object. If that happens, the + * object becomes invalid, i.e. this attribute will be `false`. Mods are advised to check for object validity if any + * change to the game state might have occurred between the creation of the Lua object and its access. + */ + readonly valid: boolean + /** + * The class name of this object. Available even when `valid` is false. For LuaStruct objects it may also be + * suffixed with a dotted path to a member of the struct. + */ + readonly object_name: "LuaWallControlBehavior" + /** All methods and properties that this object supports. */ + help(): string +} diff --git a/modules/mod2/typed-factorio/generated/concepts.d.ts b/modules/mod2/typed-factorio/generated/concepts.d.ts new file mode 100644 index 0000000..e097d47 --- /dev/null +++ b/modules/mod2/typed-factorio/generated/concepts.d.ts @@ -0,0 +1,5635 @@ +/** @noSelfInFile */ + +/** + * Localised strings are a way to support translation of in-game text. It is an array where the first element is the key + * and the remaining elements are parameters that will be substituted for placeholders in the template designated by the key. + * + * The key identifies the string template. For example, `"gui-alert-tooltip.attack"` (for the template `"__1__ objects + * are being damaged"`; see the file `data/core/locale/en.cfg`). + * + * The template can contain placeholders such as `__1__` or `__2__`. These will be replaced by the respective parameter + * in the LocalisedString. The parameters themselves can be other localised strings, which will be processed recursively + * in the same fashion. Localised strings cannot be recursed deeper than 20 levels and cannot have more than 20 parameters. + * + * As a special case, when the key is just the empty string, all the parameters will be concatenated (after processing, + * if any are localised strings). If there is only one parameter, it will be used as is. + * + * Furthermore, when an API function expects a localised string, it will also accept a regular string (i.e. not a table) + * which will not be translated, or number which will be converted to its textual representation. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LocalisedString View documentation} + * + * @example + * In the English translation, this will print `"No ammo"`; in the Czech translation, it will print `"Bez munice"`: + * + * ```lua + * game.player.print({"description.no-ammo"}) + * ``` The `description.no-ammo` template contains no placeholders, so no further parameters are necessary. + * + * @example + * In the English translation, this will print `"Durability: 5/9"`; in the Japanese one, it will print `"耐久度: 5/9"`: + * + * ```lua + * game.player.print({"description.durability", 5, 9}) + * ``` + * + * @example + * This will print `"hello"` in all translations: + * + * ```lua + * game.player.print({"", "hello"}) + * ``` + * + * @example + * This will print `"Iron plate: 60"` in the English translation and `"Eisenplatte: 60"` in the German translation. + * + * ```lua + * game.print({"", {"item-name.iron-plate"}, ": ", 60}) + * ``` + */ +type LocalisedString = [string, ...LocalisedString[]] | string | number + +interface DisplayResolution { + readonly width: uint + readonly height: uint +} + +interface PersonalLogisticParameters { + /** The item. `nil` clears the filter. */ + readonly name?: string + readonly min?: uint + readonly max?: uint +} + +/** + * The smooth orientation. It is a {@link float} in the range `[0, 1)` that covers a full circle, starting at the top and + * going clockwise. This means a value of `0` indicates "north", a value of `0.5` indicates "south". + * + * For example then, a value of `0.625` would indicate "south-west", and a value of `0.875` would indicate "north-west". + * + * {@link https://lua-api.factorio.com/next/Concepts.html#RealOrientation View documentation} + */ +type RealOrientation = float + +interface PositionTable { + readonly x: int + readonly y: int +} + +type PositionArray = readonly [x: int, y: int] + +/** + * Coordinates of a tile in a map. Positions may be specified either as a dictionary with `x`, `y` as keys, or simply as + * an array with two elements. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#Position View documentation} + * + * @example + * Explicit definition: + * + * ```lua + * {x = 50, y = 20} + * {y = 20, x = 50} + * ``` + * + * @example + * Shorthand: ```lua + * {10, 20} + * ``` + */ +type Position = PositionTable | PositionArray + +interface ChunkPositionTable { + readonly x: int + readonly y: int +} + +type ChunkPositionArray = readonly [x: int, y: int] + +/** + * Coordinates of a chunk in a {@link LuaSurface} where each integer `x`/`y` represents a different chunk. This uses the + * same format as {@link Position}, meaning it can be specified either with or without explicit keys. A {@link Position} + * can be translated to a ChunkPosition by dividing the `x`/`y` values by 32. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#ChunkPosition View documentation} + */ +type ChunkPosition = ChunkPositionTable | ChunkPositionArray + +interface TilePositionTable { + readonly x: int + readonly y: int +} + +type TilePositionArray = readonly [x: int, y: int] + +/** + * Coordinates of a tile in a chunk on a {@link LuaSurface} where each integer `x`/`y` represents a different tile. This + * uses the same format as {@link Position} except it rounds any `x`/`y` down to whole numbers. It can be specified + * either with or without explicit keys. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#TilePosition View documentation} + */ +type TilePosition = TilePositionTable | TilePositionArray + +interface GuiLocationTable { + readonly x: int + readonly y: int +} + +type GuiLocationArray = readonly [x: int, y: int] + +/** + * Screen coordinates of a GUI element in a {@link LuaGui}. This uses the same format as {@link Position} except it rounds + * any `x`/`y` down to whole numbers. It can be specified either with or without explicit keys. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#GuiLocation View documentation} + */ +type GuiLocation = GuiLocationTable | GuiLocationArray + +/** + * A {@link ChunkPosition} with an added bounding box for the area of the chunk. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#ChunkPositionAndArea View documentation} + */ +interface ChunkPositionAndArea { + readonly x: int + readonly y: int + readonly area: BoundingBox +} + +/** + * A table used to define a manual shape for a piece of equipment. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#EquipmentPoint View documentation} + */ +interface EquipmentPoint { + readonly x: uint + readonly y: uint +} + +interface GuiAnchor { + readonly gui: defines.relative_gui_type + readonly position: defines.relative_gui_position + /** If provided, only anchors the GUI element when the opened things type matches the type. */ + readonly type?: string + /** If provided, only anchors the GUI element when the opened thing matches the name. `name` takes precedence over `names`. */ + readonly name?: string + /** + * If provided, only anchors the GUI element when the opened thing matches one of the names. When reading an anchor, + * `names` is always populated. + */ + readonly names?: string[] +} + +interface TabAndContent { + readonly tab: LuaGuiElement + readonly content: LuaGuiElement +} + +interface OldTileAndPosition { + readonly old_tile: LuaTilePrototype + readonly position: TilePosition +} + +/** + * A dictionary of string to the four basic Lua types: `string`, `boolean`, `number`, `table`. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#Tags View documentation} + * + * @example + * ```lua + * {a = 1, b = true, c = "three", d = {e = "f"}} + * ``` + */ +type Tags = Record + +/** + * **Note**: The vectors for all 5 position attributes are a table with `x` and `y` keys instead of an array. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#SmokeSource View documentation} + */ +interface SmokeSource { + readonly name: string + readonly frequency: double + readonly offset: double + readonly position?: PositionTable + readonly north_position?: PositionTable + readonly east_position?: PositionTable + readonly south_position?: PositionTable + readonly west_position?: PositionTable + readonly deviation?: Position + readonly starting_frame_speed: uint16 + readonly starting_frame_speed_deviation: double + readonly starting_frame: uint16 + readonly starting_frame_deviation: double + readonly slow_down_factor: uint8 + readonly height: float + readonly height_deviation: float + readonly starting_vertical_speed: float + readonly starting_vertical_speed_deviation: float + readonly vertical_speed_slowdown: float +} + +/** + * A vector is a two-element array containing the `x` and `y` components. In some specific cases, the vector is a table + * with `x` and `y` keys instead, which the documentation will point out. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#Vector View documentation} + * + * @example + * ```lua + * right = {1.0, 0.0} + * ``` + */ +type Vector = PositionArray + +interface BoundingBoxTable { + readonly left_top: Position + readonly right_bottom: Position + readonly orientation?: RealOrientation +} + +type BoundingBoxArray = readonly [left_top: Position, right_bottom: Position, orientation?: RealOrientation] + +/** + * Two positions, specifying the top-left and bottom-right corner of the box respectively. Like with {@link Position}, + * the names of the members may be omitted. When read from the game, the third member `orientation` is present if it is + * non-zero, however it is ignored when provided to the game. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#BoundingBox View documentation} + * + * @example + * Explicit definition: + * + * ```lua + * {left_top = {-2, -3}, right_bottom = {5, 8}} + * ``` + * + * @example + * Shorthand: ```lua + * {{-2, -3}, {5, 8}} + * ``` + */ +type BoundingBox = BoundingBoxTable | BoundingBoxArray + +/** + * An area defined using the map editor. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#ScriptArea View documentation} + */ +interface ScriptArea { + readonly area: BoundingBox + readonly name: string + readonly color: Color + readonly id: uint +} + +/** + * A position defined using the map editor. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#ScriptPosition View documentation} + */ +interface ScriptPosition { + readonly position: Position + readonly name: string + readonly color: Color + readonly id: uint +} + +interface ColorTable { + readonly r?: float + readonly g?: float + readonly b?: float + readonly a?: float +} + +type ColorArray = readonly [r?: float, g?: float, b?: float, a?: float] + +/** + * Red, green, blue and alpha values, all in range [0, 1] or all in range [0, 255] if any value is > 1. All values here + * are optional. Color channels default to `0`, the alpha channel defaults to `1`. + * + * Similar to {@link Position}, Color allows the short-hand notation of passing an array of exactly 3 or 4 numbers. The + * game usually expects colors to be in pre-multiplied form (color channels are pre-multiplied by alpha). + * + * {@link https://lua-api.factorio.com/next/Concepts.html#Color View documentation} + * + * @example + * ```lua + * red1 = {r = 0.5, g = 0, b = 0, a = 0.5} -- Half-opacity red + * red2 = {r = 0.5, a = 0.5} -- Same color as red1 + * black = {} -- All channels omitted: black + * red1_short = {0.5, 0, 0, 0.5} -- Same color as red1 in short-hand notation + * ``` + */ +type Color = ColorTable | ColorArray + +interface ColorModifierTable { + readonly r?: float + readonly g?: float + readonly b?: float + readonly a?: float +} + +type ColorModifierArray = readonly [r?: float, g?: float, b?: float, a?: float] + +/** + * Same as {@link Color}, but red, green, blue and alpha values can be any floating point number, without any special + * handling of the range [1, 255]. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#ColorModifier View documentation} + */ +type ColorModifier = ColorModifierTable | ColorModifierArray + +interface CraftingQueueItem { + /** The index of the item in the crafting queue. */ + readonly index: uint + /** The recipe being crafted. */ + readonly recipe: string + /** The amount of items being crafted. */ + readonly count: uint +} + +interface Alert { + /** The tick this alert was created. */ + readonly tick: uint + readonly target?: LuaEntity + readonly prototype?: LuaEntityPrototype + readonly position?: Position + /** The SignalID used for a custom alert. Only present for custom alerts. */ + readonly icon?: SignalID + /** The message for a custom alert. Only present for custom alerts. */ + readonly message?: LocalisedString +} + +/** + * One vertex of a ScriptRenderPolygon. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#ScriptRenderVertexTarget View documentation} + */ +interface ScriptRenderVertexTarget { + readonly target: Position | LuaEntity + /** Only used if `target` is a LuaEntity. */ + readonly target_offset?: Vector +} + +interface PathfinderWaypoint { + /** The position of the waypoint on its surface. */ + readonly position: Position + /** `true` if the path from the previous waypoint to this one goes through an entity that must be destroyed. */ + readonly needs_destroy_to_reach: boolean +} + +interface CutsceneWaypoint { + /** Position to pan the camera to. */ + readonly position?: Position + /** Entity or unit group to pan the camera to. */ + readonly target?: LuaEntity | LuaUnitGroup + /** How many ticks it will take to reach this waypoint from the previous one. */ + readonly transition_time: uint + /** Time in ticks to wait before moving to the next waypoint. */ + readonly time_to_wait: uint + /** Zoom level to be set when the waypoint is reached. When not specified, the previous waypoint's zoom is used. */ + readonly zoom?: double +} + +interface Decorative { + /** The name of the decorative prototype. */ + readonly name: string + readonly position: Position + readonly amount: uint8 +} + +interface DecorativeResult { + readonly position: TilePosition + readonly decorative: LuaDecorativePrototype + readonly amount: uint +} + +/** + * **Note**: Either `icon`, `text`, or both must be provided. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#ChartTagSpec View documentation} + */ +interface ChartTagSpec { + readonly position: Position + readonly icon?: SignalID + readonly text?: string + readonly last_user?: PlayerIdentification +} + +/** + * Parameters that affect the look and control of the game. Updating any of the member attributes here will immediately + * take effect in the game engine. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings View documentation} + */ +interface GameViewSettings { + /** + * Show the controller GUI elements. This includes the toolbar, the selected tool slot, the armour slot, and the gun + * and ammunition slots. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_controller_gui View documentation} + */ + show_controller_gui: boolean + /** + * Show the chart in the upper right-hand corner of the screen. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_minimap View documentation} + */ + show_minimap: boolean + /** + * Show research progress and name in the upper right-hand corner of the screen. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_research_info View documentation} + */ + show_research_info: boolean + /** + * Show overlay icons on entities. Also known as "alt-mode". + * + * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_entity_info View documentation} + */ + show_entity_info: boolean + /** + * Show the flashing alert icons next to the player's toolbar. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_alert_gui View documentation} + */ + show_alert_gui: boolean + /** + * When `true` (the default), mousing over an entity will select it. Otherwise, moving the mouse won't update entity + * selection. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.update_entity_selection View documentation} + */ + update_entity_selection: boolean + /** + * When `true` (`false` is default), the rails will always show the rail block visualisation. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_rail_block_visualisation View documentation} + */ + show_rail_block_visualisation: boolean + /** + * Shows or hides the buttons row. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_side_menu View documentation} + */ + show_side_menu: boolean + /** + * Shows or hides the view options when map is opened. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_map_view_options View documentation} + */ + show_map_view_options: boolean + /** + * Shows or hides quickbar of shortcuts. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_quickbar View documentation} + */ + show_quickbar: boolean + /** + * Shows or hides the shortcut bar. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#GameViewSettings#GameViewSettings.show_shortcut_bar View documentation} + */ + show_shortcut_bar: boolean +} + +/** + * What is shown in the map view. If a field is not given, that setting will not be changed. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#MapViewSettings View documentation} + */ +interface MapViewSettings { + readonly "show-logistic-network"?: boolean + readonly "show-electric-network"?: boolean + readonly "show-turret-range"?: boolean + readonly "show-pollution"?: boolean + readonly "show-train-station-names"?: boolean + readonly "show-player-names"?: boolean + readonly "show-networkless-logistic-members"?: boolean + readonly "show-non-standard-map-info"?: boolean +} + +/** + * These values are for the time frame of one second (60 ticks). + * + * {@link https://lua-api.factorio.com/next/Concepts.html#PollutionMapSettings View documentation} + */ +interface PollutionMapSettings { + /** Whether pollution is enabled at all. */ + readonly enabled: boolean + /** The amount that is diffused to a neighboring chunk (possibly repeated for other directions as well). Defaults to `0.02`. */ + readonly diffusion_ratio: double + /** The amount of PUs that need to be in a chunk for it to start diffusing. Defaults to `15`. */ + readonly min_to_diffuse: double + /** The amount of pollution eaten by a chunk's tiles as a percentage of 1. Defaults to `1`. */ + readonly aeging: double + /** Any amount of pollution larger than this value is visualized as this value instead. Defaults to `150`. */ + readonly expected_max_per_chunk: double + /** + * Any amount of pollution smaller than this value (but bigger than zero) is visualized as this value instead. + * Defaults to `50`. + */ + readonly min_to_show_per_chunk: double + /** Defaults to `60`. */ + readonly min_pollution_to_damage_trees: double + /** Defaults to `150`. */ + readonly pollution_with_max_forest_damage: double + /** Defaults to `50`. */ + readonly pollution_per_tree_damage: double + /** Defaults to `10`. */ + readonly pollution_restored_per_tree_damage: double + /** Defaults to `20`. */ + readonly max_pollution_to_restore_trees: double + /** Defaults to `1`. */ + readonly enemy_attack_pollution_consumption_modifier: double +} + +/** + * These values represent a percentual increase in evolution. This means a value of `0.1` would increase evolution by 10%. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#EnemyEvolutionMapSettings View documentation} + */ +interface EnemyEvolutionMapSettings { + /** Whether enemy evolution is enabled at all. */ + readonly enabled: boolean + /** The amount evolution naturally progresses by every second. Defaults to `0.000004`. */ + readonly time_factor: double + /** The amount evolution progresses for every destroyed spawner. Defaults to `0.002`. */ + readonly destroy_factor: double + /** The amount evolution progresses for every unit of pollution. Defaults to `0.0000009`. */ + readonly pollution_factor: double +} + +/** + * Candidate chunks are given scores to determine which one of them should be expanded into. This score takes into + * account various settings noted below. The iteration is over a square region centered around the chunk for which the + * calculation is done, and includes the central chunk as well. Distances are calculated as + * {@link https://en.wikipedia.org/wiki/Taxicab_geometry Manhattan distance}. + * + * The pseudocode algorithm to determine a chunk's score is as follows: + * + * ```lua + * player = 0 + * for neighbour in all chunks within enemy_building_influence_radius from chunk: + * player += number of player buildings on neighbour + * * building_coefficient + * * neighbouring_chunk_coefficient^distance(chunk, neighbour) + * + * base = 0 + * for neighbour in all chunk within friendly_base_influence_radius from chunk: + * base += num of enemy bases on neighbour + * * other_base_coefficient + * * neighbouring_base_chunk_coefficient^distance(chunk, neighbour) + * + * score(chunk) = 1 / (1 + player + base) + * ``` + * + * {@link https://lua-api.factorio.com/next/Concepts.html#EnemyExpansionMapSettings View documentation} + */ +interface EnemyExpansionMapSettings { + /** Whether enemy expansion is enabled at all. */ + readonly enabled: boolean + /** + * Distance in chunks from the furthest base around to prevent expansions from reaching too far into the player's + * territory. Defaults to `7`. + */ + readonly max_expansion_distance: uint + /** Defaults to `2`. */ + readonly friendly_base_influence_radius: uint + /** Defaults to `2`. */ + readonly enemy_building_influence_radius: uint + /** Defaults to `0.1`. */ + readonly building_coefficient: double + /** Defaults to `2.0`. */ + readonly other_base_coefficient: double + /** Defaults to `0.5`. */ + readonly neighbouring_chunk_coefficient: double + /** Defaults to `0.4`. */ + readonly neighbouring_base_chunk_coefficient: double + /** + * A chunk has to have at most this high of a percentage of unbuildable tiles for it to be considered a candidate to + * avoid chunks full of water as candidates. Defaults to `0.9`, or 90%. + */ + readonly max_colliding_tiles_coefficient: double + /** + * The minimum size of a biter group that goes to build a new base. This is multiplied by the evolution factor. + * Defaults to `5`. + */ + readonly settler_group_min_size: uint + /** + * The maximum size of a biter group that goes to build a new base. This is multiplied by the evolution factor. + * Defaults to `20`. + */ + readonly settler_group_max_size: uint + /** + * The minimum time between expansions in ticks. The actual cooldown is adjusted to the current evolution levels. + * Defaults to `4*3,600=14,400` ticks. + */ + readonly min_expansion_cooldown: uint + /** + * The maximum time between expansions in ticks. The actual cooldown is adjusted to the current evolution levels. + * Defaults to `60*3,600=216,000` ticks. + */ + readonly max_expansion_cooldown: uint +} + +interface UnitGroupMapSettings { + /** + * The minimum amount of time in ticks a group will spend gathering before setting off. The actual time is a random + * time between the minimum and maximum times. Defaults to `3,600` ticks. + */ + readonly min_group_gathering_time: uint + /** + * The maximum amount of time in ticks a group will spend gathering before setting off. The actual time is a random + * time between the minimum and maximum times. Defaults to `10*3,600=36,000` ticks. + */ + readonly max_group_gathering_time: uint + /** + * After gathering has finished, the group is allowed to wait this long in ticks for delayed members. New members + * are not accepted anymore however. Defaults to `2*3,600=7,200` ticks. + */ + readonly max_wait_time_for_late_members: uint + /** The minimum group radius in tiles. The actual radius is adjusted based on the number of members. Defaults to `5.0`. */ + readonly min_group_radius: double + /** The maximum group radius in tiles. The actual radius is adjusted based on the number of members. Defaults to `30.0`. */ + readonly max_group_radius: double + /** + * The maximum speed a percentage of its regular speed that a group member can speed up to when catching up with the + * group. Defaults to `1.4`, or 140%. + */ + readonly max_member_speedup_when_behind: double + /** + * The minimum speed a percentage of its regular speed that a group member can slow down to when ahead of the group. + * Defaults to `0.6`, or 60%. + */ + readonly max_member_slowdown_when_ahead: double + /** + * The minimum speed as a percentage of its maximum speed that a group will slow down to so members that fell behind + * can catch up. Defaults to `0.3`, or 30%. + */ + readonly max_group_slowdown_factor: double + /** + * When a member of a group falls back more than this factor times the group radius, the group will slow down to its + * `max_group_slowdown_factor` speed to let them catch up. Defaults to `3`. + */ + readonly max_group_member_fallback_factor: double + /** + * When a member of a group falls back more than this factor times the group radius, it will be dropped from the + * group. Defaults to `10`. + */ + readonly member_disown_distance: double + readonly tick_tolerance_when_member_arrives: uint + /** The maximum number of automatically created unit groups gathering for attack at any time. Defaults to `30`. */ + readonly max_gathering_unit_groups: uint + /** + * The maximum number of members for an attack unit group. This only affects automatically created unit groups, + * manual groups created through the API are unaffected. Defaults to `200`. + */ + readonly max_unit_group_size: uint +} + +interface SteeringMapSetting { + /** Does not include the radius of the unit. */ + readonly radius: double + readonly separation_factor: double + readonly separation_force: double + /** Used to make steering look better for aesthetic purposes. */ + readonly force_unit_fuzzy_goto_behavior: boolean +} + +interface SteeringMapSettings { + readonly default: SteeringMapSetting + readonly moving: SteeringMapSetting +} + +interface PathFinderMapSettings { + /** Determines whether forwards (`>1`), backwards (`<-1`), or symmetrical (`1`) search is preferred. Defaults to `5`. */ + readonly fwd2bwd_ratio: uint + /** + * When looking at which node to check next, their heuristic value is multiplied by this ratio. The higher it is, + * the more the search is directed straight at the goal. Defaults to `2`. + */ + readonly goal_pressure_ratio: double + /** The maximum number of nodes that are expanded per tick. Defaults to `1,000`. */ + readonly max_steps_worked_per_tick: double + /** The maximum amount of work each pathfinding job is allowed to do per tick. Defaults to `8,000`. */ + readonly max_work_done_per_tick: uint + /** Whether to cache paths at all. Defaults to `true`. */ + readonly use_path_cache: boolean + /** Number of elements in the short cache. Defaults to `5`. */ + readonly short_cache_size: uint + /** Number of elements in the long cache. Defaults to `25`. */ + readonly long_cache_size: uint + /** The minimal distance to the goal in tiles required to be searched in the short path cache. Defaults to `10`. */ + readonly short_cache_min_cacheable_distance: double + /** The minimal number of nodes required to be searched in the short path cache. Defaults to `50`. */ + readonly short_cache_min_algo_steps_to_cache: uint + /** The minimal distance to the goal in tiles required to be searched in the long path cache. Defaults to `30`. */ + readonly long_cache_min_cacheable_distance: double + /** + * When looking for a connection to a cached path, search at most for this number of steps times the original + * estimate. Defaults to `100`. + */ + readonly cache_max_connect_to_cache_steps_multiplier: uint + /** + * When looking for a path from cache, make sure it doesn't start too far from the requested start in relative + * terms. Defaults to `0.2`. + */ + readonly cache_accept_path_start_distance_ratio: double + /** + * When looking for a path from cache, make sure it doesn't end too far from the requested end in relative terms. + * This is typically more lenient than the start ratio since the end target could be moving. Defaults to `0.15`. + */ + readonly cache_accept_path_end_distance_ratio: double + /** Same principle as `cache_accept_path_start_distance_ratio`, but used for negative cache queries. Defaults to `0.3`. */ + readonly negative_cache_accept_path_start_distance_ratio: double + /** Same principle as `cache_accept_path_end_distance_ratio`, but used for negative cache queries. Defaults to `0.3`. */ + readonly negative_cache_accept_path_end_distance_ratio: double + /** When assigning a rating to the best path, this multiplier times start distances is considered. Defaults to `10`. */ + readonly cache_path_start_distance_rating_multiplier: double + /** + * When assigning a rating to the best path, this multiplier times end distances is considered. This value is + * typically higher than the start multiplier as this results in better end path quality. Defaults to `20`. + */ + readonly cache_path_end_distance_rating_multiplier: double + /** + * A penalty that is applied for another unit that is on the way to the goal. This is mainly relevant for situations + * where a group of units has arrived at the target they are supposed to attack, making units further back circle + * around to reach the target. Defaults to `30`. + */ + readonly stale_enemy_with_same_destination_collision_penalty: double + /** The distance in tiles after which other moving units are not considered for pathfinding. Defaults to `5`. */ + readonly ignore_moving_enemy_collision_distance: double + /** + * A penalty that is applied for another unit that is too close and either not moving or has a different goal. + * Defaults to `30`. + */ + readonly enemy_with_different_destination_collision_penalty: double + /** The general collision penalty with other units. Defaults to `10`. */ + readonly general_entity_collision_penalty: double + /** The collision penalty for positions that require the destruction of an entity to get to. Defaults to `3`. */ + readonly general_entity_subsequent_collision_penalty: double + /** + * The collision penalty for collisions in the extended bounding box but outside the entity's actual bounding box. + * Defaults to `3`. + */ + readonly extended_collision_penalty: double + /** The amount of path finder requests accepted per tick regardless of the requested path's length. Defaults to `10`. */ + readonly max_clients_to_accept_any_new_request: uint + /** + * When the `max_clients_to_accept_any_new_request` amount is exhausted, only path finder requests with a short + * estimate will be accepted until this amount (per tick) is reached. Defaults to `100`. + */ + readonly max_clients_to_accept_short_new_request: uint + /** The maximum direct distance in tiles before a request is no longer considered short. Defaults to `100`. */ + readonly direct_distance_to_consider_short_request: uint + /** The maximum amount of nodes a short request will traverse before being rescheduled as a long request. Defaults to `1000`. */ + readonly short_request_max_steps: uint + /** + * The amount of steps that are allocated to short requests each tick, as a percentage of all available steps. + * Defaults to `0.5`, or 50%. + */ + readonly short_request_ratio: double + /** The minimum amount of steps that are guaranteed to be performed for every request. Defaults to `2000`. */ + readonly min_steps_to_check_path_find_termination: uint + /** + * If the actual amount of steps is higher than the initial estimate by this factor, pathfinding is terminated. + * Defaults to `2000.0`. + */ + readonly start_to_goal_cost_multiplier_to_terminate_path_find: double + /** + * The thresholds of waiting clients after each of which the per-tick work limit will be increased by the + * corresponding value in `overload_multipliers`. This is to avoid clients having to wait too long. Must have the + * same number of elements as `overload_multipliers`. Defaults to `{0, 100, 500}`. + */ + readonly overload_levels: uint[] + /** + * The multipliers to the amount of per-tick work applied after the corresponding thresholds in `overload_levels` + * have been reached. Must have the same number of elements as `overload_multipliers`. Defaults to `{2, 3, 4}`. + */ + readonly overload_multipliers: double[] + /** The delay in ticks between decrementing the score of all paths in the negative cache by one. Defaults to `20`. */ + readonly negative_path_cache_delay_interval: uint +} + +/** + * Various game-related settings. Updating any of the attributes will immediately take effect in the game engine. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#MapSettings View documentation} + * + * @example + * Increase the number of short paths the pathfinder can cache. + * + * ```lua + * game.map_settings.path_finder.short_cache_size = 15 + * ``` + */ +interface MapSettings { + readonly pollution: PollutionMapSettings + readonly enemy_evolution: EnemyEvolutionMapSettings + readonly enemy_expansion: EnemyExpansionMapSettings + readonly unit_group: UnitGroupMapSettings + readonly steering: SteeringMapSettings + readonly path_finder: PathFinderMapSettings + /** + * If a behavior fails this many times, the enemy (or enemy group) is destroyed. This solves biters getting stuck + * within their own base. + */ + readonly max_failed_behavior_count: uint +} + +/** + * Technology and recipe difficulty settings. Updating any of the attributes will immediately take effect in the game engine. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#DifficultySettings View documentation} + */ +interface DifficultySettings { + readonly recipe_difficulty: defines.difficulty_settings.recipe_difficulty + readonly technology_difficulty: defines.difficulty_settings.technology_difficulty + /** A value in range [0.001, 1000]. */ + readonly technology_price_multiplier: double + /** + * Either `"after-victory"`, `"always"` or `"never"`. Changing this to `"always"` or `"after-victory"` does not + * automatically unlock the research queue. See {@link LuaForce} for that. + */ + readonly research_queue_setting: "after-victory" | "always" | "never" +} + +/** + * The data that can be extracted from a map exchange string, as a plain table. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#MapExchangeStringData View documentation} + */ +interface MapExchangeStringData { + /** + * All the regular map settings plus an additional table called `difficulty_settings` that contains the + * {@link DifficultySettings}. + */ + readonly map_settings: MapSettings + readonly map_gen_settings: MapGenSettings +} + +interface BlueprintItemIcon { + /** Name of the item prototype whose icon should be used. */ + readonly name: string + /** Index of the icon in the blueprint icons slots. Has to be an integer in the range [1, 4]. */ + readonly index: uint +} + +interface BlueprintSignalIcon { + /** The icon to use. It can be any item icon as well as any virtual signal icon. */ + readonly signal: SignalID + /** Index of the icon in the blueprint icons slots. Has to be an integer in the range [1, 4]. */ + readonly index: uint +} + +/** + * Information about a single connection between two connection points. + * + * {@link https://wiki.factorio.com/Blueprint_string_format#Connection_data_object View Documentation} + */ +interface BlueprintConnectionData { + /** ID of the entity this connection is connected with. */ + entity_id: uint + /** The circuit connector id of the entity this connection is connected to, see {@link defines.circuit_connector_id} */ + circuit_id?: defines.circuit_connector_id +} + +/** + * The actual point where a wire is connected to. Contains information about where it is connected to. + * + * {@link https://wiki.factorio.com/Blueprint_string_format#Connection_point_object View Documentation} + */ +interface BlueprintConnectionPoint { + /** + * An array of {@link BlueprintConnectionData Connection data object} containing all the connections from this point + * created by red wire. + */ + red?: BlueprintConnectionData[] + /** + * An array of {@link BlueprintConnectionData Connection data object} containing all the connections from this point + * created by green wire. + */ + green?: BlueprintConnectionData[] +} + +/** + * Object containing information about the connections to other entities formed by red or green wires. + * + * {@link https://wiki.factorio.com/Blueprint_string_format#Connection_object View Documentation} + */ +interface BlueprintCircuitConnection { + /** First connection point. The default for everything that doesn't have multiple connection points. */ + "1"?: BlueprintConnectionPoint + /** Second connection point. For example, the "output" part of an arithmetic combinator. */ + "2"?: BlueprintConnectionPoint +} + +/** + * The representation of an entity inside of a blueprint. It has at least these fields, but can contain additional ones + * depending on the kind of entity. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#BlueprintEntity View documentation} + */ +interface BlueprintEntity { + /** The entity's unique identifier in the blueprint. */ + readonly entity_number: uint + /** The prototype name of the entity. */ + readonly name: string + /** The position of the entity. */ + readonly position: Position + /** + * The direction the entity is facing. Only present for entities that can face in different directions and when the + * entity is not facing north. + */ + readonly direction?: defines.direction + /** The entity tags of the entity, if there are any. Only relevant for entity ghosts. */ + readonly tags?: Tags + /** + * The items that the entity will request when revived, if there are any. It's a mapping of prototype names to + * amounts. Only relevant for entity ghosts. + */ + readonly items?: Record + /** + * The circuit network connections of the entity, if there are any. Only relevant for entities that support circuit + * connections. + */ + readonly connections?: BlueprintCircuitConnection + /** + * The control behavior of the entity, if it has one. The format of the control behavior depends on the entity's + * type. Only relevant for entities that support control behaviors. + */ + readonly control_behavior?: BlueprintControlBehavior + /** The schedule of the entity, if it has one. Only relevant for locomotives. */ + readonly schedule?: TrainScheduleRecord[] +} + +interface Tile { + /** The position of the tile. */ + readonly position: Position + /** The prototype name of the tile. */ + readonly name: string +} + +interface Fluid { + /** Fluid prototype name of the fluid. */ + readonly name: string + /** Amount of the fluid. */ + readonly amount: double + /** + * The temperature. When reading from {@link LuaFluidBox}, this field will always be present. It is not necessary to + * specify it when writing, however. When not specified, the fluid will be set to the fluid's default temperature as + * specified in the fluid's prototype. + */ + readonly temperature?: double +} + +interface BaseIngredient { + /** `"item"` or `"fluid"`. */ + readonly type: "item" | "fluid" + /** Prototype name of the required item or fluid. */ + readonly name: string + /** Amount of the item or fluid. */ + readonly amount: double + /** How much of this ingredient is a catalyst. */ + readonly catalyst_amount?: uint | double +} + +interface FluidIngredient extends BaseIngredient { + readonly type: "fluid" + /** The minimum fluid temperature required. */ + readonly minimum_temperature?: double + /** The maximum fluid temperature allowed. */ + readonly maximum_temperature?: double +} + +interface OtherIngredient extends BaseIngredient { + readonly type: "item" +} + +/** + * Other attributes may be specified depending on `type`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#Ingredient View documentation} + */ +type Ingredient = FluidIngredient | OtherIngredient + +interface BaseProduct { + /** `"item"` or `"fluid"`. */ + readonly type: "item" | "fluid" + /** Prototype name of the result. */ + readonly name: string + /** Amount of the item or fluid to give. If not specified, `amount_min`, `amount_max` and `probability` must all be specified. */ + readonly amount?: double + /** Minimal amount of the item or fluid to give. Has no effect when `amount` is specified. */ + readonly amount_min?: uint | double + /** Maximum amount of the item or fluid to give. Has no effect when `amount` is specified. */ + readonly amount_max?: uint | double + /** A value in range [0, 1]. Item or fluid is only given with this probability; otherwise no product is produced. */ + readonly probability?: double + /** How much of this product is a catalyst. */ + readonly catalyst_amount?: uint | double +} + +interface FluidProduct extends BaseProduct { + readonly type: "fluid" + /** The fluid temperature of this product. */ + readonly temperature?: double +} + +interface OtherProduct extends BaseProduct { + readonly type: "item" +} + +/** + * Other attributes may be specified depending on `type`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#Product View documentation} + * + * @example + * Products of the "steel-chest" recipe (an array of Product): + * + * ```lua + * {{type="item", name="steel-chest", amount=1}} + * ``` + * + * @example + * Products of the "advanced-oil-processing" recipe: + * + * ```lua + * {{type="fluid", name="heavy-oil", amount=1}, + * {type="fluid", name="light-oil", amount=4.5}, + * {type="fluid", name="petroleum-gas", amount=5.5}} + * ``` + * + * @example + * What a custom recipe would look like that had a probability of 0.5 to return a minimum amount of 1 and a maximum amount of 5: + * + * ```lua + * {{type=0, name="custom-item", probability=0.5, amount_min=1, amount_max=5}} + * ``` + * + * @see {@link LuaRecipe.products} + */ +type Product = FluidProduct | OtherProduct + +interface Loot { + /** Item prototype name of the result. */ + readonly item: string + /** Probability that any loot at all will drop, as a number in range [0, 1]. */ + readonly probability: double + /** Minimum amount of loot to drop. */ + readonly count_min: double + /** Maximum amount of loot to drop. */ + readonly count_max: double +} + +interface BaseTechnologyModifier { + /** + * Modifier type. Specifies which of the other fields will be available. Possible values are: + * `"inserter-stack-size-bonus"`, `"stack-inserter-capacity-bonus"`, `"laboratory-speed"`, + * `"character-logistic-trash-slots"`, `"maximum-following-robots-count"`, `"worker-robot-speed"`, + * `"worker-robot-storage"`, `"ghost-time-to-live"`, `"turret-attack"`, `"ammo-damage"`, `"give-item"`, + * `"gun-speed"`, `"unlock-recipe"`, `"character-crafting-speed"`, `"character-mining-speed"`, + * `"character-running-speed"`, `"character-build-distance"`, `"character-item-drop-distance"`, + * `"character-reach-distance"`, `"character-resource-reach-distance"`, `"character-item-pickup-distance"`, + * `"character-loot-pickup-distance"`, `"character-inventory-slots-bonus"`, `"deconstruction-time-to-live"`, + * `"max-failed-attempts-per-tick-per-construction-queue"`, + * `"max-successful-attempts-per-tick-per-construction-queue"`, `"character-health-bonus"`, + * `"mining-drill-productivity-bonus"`, `"train-braking-force-bonus"`, `"zoom-to-world-enabled"`, + * `"zoom-to-world-ghost-building-enabled"`, `"zoom-to-world-blueprint-enabled"`, + * `"zoom-to-world-deconstruction-planner-enabled"`, `"zoom-to-world-upgrade-planner-enabled"`, + * `"zoom-to-world-selection-tool-enabled"`, `"worker-robot-battery"`, `"laboratory-productivity"`, + * `"follower-robot-lifetime"`, `"artillery-range"`, `"nothing"`, `"character-additional-mining-categories"`, + * `"character-logistic-requests"`. + */ + readonly type: + | "inserter-stack-size-bonus" + | "stack-inserter-capacity-bonus" + | "laboratory-speed" + | "character-logistic-trash-slots" + | "maximum-following-robots-count" + | "worker-robot-speed" + | "worker-robot-storage" + | "ghost-time-to-live" + | "turret-attack" + | "ammo-damage" + | "give-item" + | "gun-speed" + | "unlock-recipe" + | "character-crafting-speed" + | "character-mining-speed" + | "character-running-speed" + | "character-build-distance" + | "character-item-drop-distance" + | "character-reach-distance" + | "character-resource-reach-distance" + | "character-item-pickup-distance" + | "character-loot-pickup-distance" + | "character-inventory-slots-bonus" + | "deconstruction-time-to-live" + | "max-failed-attempts-per-tick-per-construction-queue" + | "max-successful-attempts-per-tick-per-construction-queue" + | "character-health-bonus" + | "mining-drill-productivity-bonus" + | "train-braking-force-bonus" + | "zoom-to-world-enabled" + | "zoom-to-world-ghost-building-enabled" + | "zoom-to-world-blueprint-enabled" + | "zoom-to-world-deconstruction-planner-enabled" + | "zoom-to-world-upgrade-planner-enabled" + | "zoom-to-world-selection-tool-enabled" + | "worker-robot-battery" + | "laboratory-productivity" + | "follower-robot-lifetime" + | "artillery-range" + | "nothing" + | "character-additional-mining-categories" + | "character-logistic-requests" +} + +interface GunSpeedTechnologyModifier extends BaseTechnologyModifier { + readonly type: "gun-speed" + /** Prototype name of the ammunition category that is affected */ + readonly ammo_category: string + /** Modification value. This will be added to the current gun speed modifier upon researching. */ + readonly modifier: double +} + +interface AmmoDamageTechnologyModifier extends BaseTechnologyModifier { + readonly type: "ammo-damage" + /** Prototype name of the ammunition category that is affected */ + readonly ammo_category: string + /** Modification value. This will be added to the current ammo damage modifier upon researching. */ + readonly modifier: double +} + +interface GiveItemTechnologyModifier extends BaseTechnologyModifier { + readonly type: "give-item" + /** Item prototype name to give. */ + readonly item: string + /** Number of items to give. Defaults to `1`. */ + readonly count?: uint +} + +interface TurretAttackTechnologyModifier extends BaseTechnologyModifier { + readonly type: "turret-attack" + /** Turret prototype name this modifier will affect. */ + readonly turret_id: string + /** Modification value. This will be added to the current turret damage modifier upon researching. */ + readonly modifier: double +} + +interface UnlockRecipeTechnologyModifier extends BaseTechnologyModifier { + readonly type: "unlock-recipe" + /** Recipe prototype name to unlock. */ + readonly recipe: string +} + +interface NothingTechnologyModifier extends BaseTechnologyModifier { + readonly type: "nothing" + /** Description of this nothing modifier. */ + readonly effect_description: LocalisedString +} + +interface OtherTechnologyModifier extends BaseTechnologyModifier { + readonly type: + | "inserter-stack-size-bonus" + | "stack-inserter-capacity-bonus" + | "laboratory-speed" + | "character-logistic-trash-slots" + | "maximum-following-robots-count" + | "worker-robot-speed" + | "worker-robot-storage" + | "ghost-time-to-live" + | "character-crafting-speed" + | "character-mining-speed" + | "character-running-speed" + | "character-build-distance" + | "character-item-drop-distance" + | "character-reach-distance" + | "character-resource-reach-distance" + | "character-item-pickup-distance" + | "character-loot-pickup-distance" + | "character-inventory-slots-bonus" + | "deconstruction-time-to-live" + | "max-failed-attempts-per-tick-per-construction-queue" + | "max-successful-attempts-per-tick-per-construction-queue" + | "character-health-bonus" + | "mining-drill-productivity-bonus" + | "train-braking-force-bonus" + | "zoom-to-world-enabled" + | "zoom-to-world-ghost-building-enabled" + | "zoom-to-world-blueprint-enabled" + | "zoom-to-world-deconstruction-planner-enabled" + | "zoom-to-world-upgrade-planner-enabled" + | "zoom-to-world-selection-tool-enabled" + | "worker-robot-battery" + | "laboratory-productivity" + | "follower-robot-lifetime" + | "artillery-range" + | "character-additional-mining-categories" + | "character-logistic-requests" + /** Modification value. This value will be added to the variable it modifies. */ + readonly modifier: double +} + +/** + * The effect that is applied when a technology is researched. It is a table that contains at least the field `type`. + * + * Other attributes may be specified depending on `type`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#TechnologyModifier View documentation} + */ +type TechnologyModifier = + | GunSpeedTechnologyModifier + | AmmoDamageTechnologyModifier + | GiveItemTechnologyModifier + | TurretAttackTechnologyModifier + | UnlockRecipeTechnologyModifier + | NothingTechnologyModifier + | OtherTechnologyModifier + +/** + * A single offer on a market entity. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#Offer View documentation} + */ +interface Offer { + /** List of prices. */ + readonly price: Ingredient[] + /** The action that will take place when a player accepts the offer. Usually a `"give-item"` modifier. */ + readonly offer: TechnologyModifier +} + +/** + * Specifies how probability and richness are calculated when placing something on the map. Can be specified either + * using `probability_expression` and `richness_expression` or by using all the other fields. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#AutoplaceSpecification View documentation} + */ +interface AutoplaceSpecification { + readonly probability_expression: NoiseExpression + readonly richness_expression: NoiseExpression + readonly coverage: double + readonly sharpness: double + readonly max_probability: double + readonly placement_density: uint + readonly richness_base: double + readonly richness_multiplier: double + readonly richness_multiplier_distance_bonus: double + readonly starting_area_size: uint + readonly order: string + readonly default_enabled: boolean + readonly peaks?: AutoplaceSpecificationPeak[] + /** Control prototype name. */ + readonly control?: string + readonly tile_restriction?: AutoplaceSpecificationRestriction[] + readonly force: string + readonly random_probability_penalty: double +} + +/** + * A fragment of a functional program used to generate coherent noise, probably for purposes related to terrain + * generation. These can only be meaningfully written/modified during the data load phase. More detailed information is + * found on the {@link https://wiki.factorio.com/Types/NoiseExpression wiki}. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#NoiseExpression View documentation} + */ +interface NoiseExpression { + /** Names the type of the expression and determines what other fields are required. */ + readonly type: string +} + +interface AutoplaceSpecificationPeak { + readonly influence: double + readonly max_influence: double + readonly min_influence: double + readonly richness_influence: double + readonly noisePersistence: double + /** Prototype name of the noise layer. */ + readonly noise_layer?: string + readonly noise_octaves_difference: double + readonly water_optimal: double + readonly water_range: double + readonly water_max_range: double + readonly water_top_property_limit: double + readonly elevation_optimal: double + readonly elevation_range: double + readonly elevation_max_range: double + readonly elevation_top_property_limit: double + readonly temperature_optimal: double + readonly temperature_range: double + readonly temperature_max_range: double + readonly temperature_top_property_limit: double + readonly starting_area_weight_optimal: double + readonly starting_area_weight_range: double + readonly starting_area_weight_max_range: double + readonly starting_area_weight_top_property_limit: double + readonly tier_from_start_optimal: double + readonly tier_from_start_range: double + readonly tier_from_start_max_range: double + readonly tier_from_start_top_property_limit: double + readonly distance_optimal: double + readonly distance_range: double + readonly distance_max_range: double + readonly distance_top_property_limit: double + readonly aux_optimal: double + readonly aux_range: double + readonly aux_max_range: double + readonly aux_top_property_limit: double +} + +interface AutoplaceSpecificationRestriction { + /** Tile prototype name */ + readonly first?: string + /** Second prototype name */ + readonly second?: string +} + +interface Resistance { + /** Absolute damage decrease */ + readonly decrease: float + /** Percentual damage decrease */ + readonly percent: float +} + +/** + * A floating point number specifying an amount. + * + * For backwards compatibility, MapGenSizes can also be specified as one of the following strings, which will be + * converted to a number (when queried, a number will always be returned): + * + * - `"none"` - equivalent to `0` + * - `"very-low"`, `"very-small"`, `"very-poor"` - equivalent to `1/2` + * - `"low"`, `"small"`, `"poor"` - equivalent to `1/sqrt(2)` + * - `"normal"`, `"medium"`, `"regular"` - equivalent to `1` + * - `"high"`, `"big"`, `"good"` - equivalent to `sqrt(2)` + * - `"very-high"`, `"very-big"`, `"very-good"` - equivalent to `2` + * + * **Note**: The map generation algorithm officially supports the range of values the in-game map generation screen + * shows (specifically `0` and values from `1/6` to `6`). Values outside this range are not guaranteed to work as expected. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#MapGenSize View documentation} + */ +type MapGenSize = + | number + | "none" + | "very-low" + | "very-small" + | "very-poor" + | "low" + | "small" + | "poor" + | "normal" + | "medium" + | "regular" + | "high" + | "big" + | "good" + | "very-high" + | "very-big" + | "very-good" + +interface AutoplaceSetting { + readonly frequency: MapGenSize + readonly size: MapGenSize + readonly richness: MapGenSize +} + +interface AutoplaceSettings { + /** Whether missing autoplace names for this type should be default enabled. */ + readonly treat_missing_as_default: boolean + readonly settings: Record +} + +interface AutoplaceControl { + /** + * For things that are placed as spots such as ores and enemy bases, frequency is generally proportional to number + * of spots placed per unit area. For continuous features such as forests, frequency is how compressed the + * probability function is over distance, i.e. the inverse of 'scale' (similar to terrain_segmentation). When the + * {@link LuaAutoplaceControlPrototype} is of the category `"terrain"`, then scale is shown in the map generator GUI + * instead of frequency. + */ + readonly frequency: MapGenSize + /** + * For things that are placed as spots, size is proportional to the area of each spot. For continuous features, size + * affects how much of the map is covered with the thing, and is called 'coverage' in the GUI. + */ + readonly size: MapGenSize + /** + * Has different effects for different things, but generally affects the 'health' or density of a thing that is + * placed without affecting where it is placed. For trees, richness affects tree health. For ores, richness + * multiplies the amount of ore at any given tile in a patch. Metadata about autoplace controls (such as whether or + * not 'richness' does anything for them) can be found in the {@link LuaAutoplaceControlPrototype} by looking up + * `game.autoplace_control_prototypes[(control prototype name)]`, e.g. + * `game.autoplace_control_prototypes["enemy-base"].richness` is false, because enemy base autoplacement doesn't use + * richness. + */ + readonly richness: MapGenSize +} + +interface CliffPlacementSettings { + /** Name of the cliff prototype. */ + readonly name: string + /** + * Elevation at which the first row of cliffs is placed. The default is `10`, and this cannot be set from the map + * generation GUI. + */ + readonly cliff_elevation_0: float + /** + * Elevation difference between successive rows of cliffs. This is inversely proportional to 'frequency' in the map + * generation GUI. Specifically, when set from the GUI the value is `40 / frequency`. + */ + readonly cliff_elevation_interval: float + /** + * Corresponds to 'continuity' in the GUI. This value is not used directly, but is used by the 'cliffiness' noise + * expression, which in combination with elevation and the two cliff elevation properties drives cliff placement + * (cliffs are placed when elevation crosses the elevation contours defined by `cliff_elevation_0` and + * `cliff_elevation_interval` when 'cliffiness' is greater than `0.5`). The default 'cliffiness' expression + * interprets this value such that larger values result in longer unbroken walls of cliffs, and smaller values + * (between `0` and `1`) result in larger gaps in cliff walls. + */ + readonly richness: MapGenSize +} + +/** + * The 'map type' dropdown in the map generation GUI is actually a selector for elevation generator. The base game sets + * `property_expression_names.elevation` to `"0_16-elevation"` to reproduce terrain from 0.16 or to `"0_17-island"` for + * the island preset. If generators are available for other properties, the 'map type' dropdown in the GUI will be + * renamed to 'elevation' and shown along with selectors for the other selectable properties. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#MapGenSettings View documentation} + * + * @example + * Assuming a NamedNoiseExpression with the name "my-alternate-grass1-probability" is defined + * + * ```lua + * local surface = game.player.surface + * local mgs = surface.map_gen_settings + * mgs.property_expression_names["tile:grass1:probability"] = "my-alternate-grass1-probability" + * surface.map_gen_settings = mgs + * ``` would override the probability of grass1 being placed at any given point on the current surface. + * + * @example + * To make there be no deep water on (newly generated chunks) a surface: + * + * ```lua + * local surface = game.player.surface + * local mgs = surface.map_gen_settings + * mgs.property_expression_names["tile:deepwater:probability"] = -1000 + * surface.map_gen_settings = mgs + * ``` This does not require a NamedNoiseExpression to be defined, since literal numbers (and strings naming literal numbers, e.g. `"123"`) are understood to stand for constant value expressions. + */ +interface MapGenSettings { + /** + * The inverse of 'water scale' in the map generator GUI. Lower `terrain_segmentation` increases the scale of + * elevation features (lakes, continents, etc). This behavior can be overridden with alternate elevation generators + * (see `property_expression_names`, below). + */ + readonly terrain_segmentation: MapGenSize + /** + * The equivalent to 'water coverage' in the map generator GUI. Specifically, when this value is non-zero, + * `water_level = 10 * log2` (the value of this field), and the elevation generator subtracts water level from + * elevation before adding starting lakes. If water is set to 'none', elevation is clamped to a small positive value + * before adding starting lakes. This behavior can be overridden with alternate elevation generators (see + * `property_expression_names`, below). + */ + readonly water: MapGenSize + /** Indexed by autoplace control prototype name. */ + readonly autoplace_controls: Record + /** Whether undefined `autoplace_controls` should fall back to the default controls or not. Defaults to `true`. */ + readonly default_enable_all_autoplace_controls: boolean + /** + * Each setting in this dictionary maps the string type to the settings for that type. Valid types are `"entity"`, + * `"tile"` and `"decorative"`. + */ + readonly autoplace_settings: Record + /** Map generation settings for entities of the type "cliff". */ + readonly cliff_settings: CliffPlacementSettings + /** The random seed used to generated this map. */ + readonly seed: uint + /** + * Width in tiles. If `0`, the map has 'infinite' width, with the actual limitation being one million tiles in each + * direction from the center. + */ + readonly width: uint + /** + * Height in tiles. If `0`, the map has 'infinite' height, with the actual limitation being one million tiles in + * each direction from the center. + */ + readonly height: uint + /** Size of the starting area. */ + readonly starting_area: MapGenSize + /** Positions of the starting areas. */ + readonly starting_points: Position[] + /** Whether peaceful mode is enabled for this map. */ + readonly peaceful_mode: boolean + /** + * Overrides for tile property value generators. Values either name a NamedNoiseExpression or can be literal + * numbers, stored as strings (e.g. `"5"`). All other controls can be overridden by a property expression names. + * Notable properties: + * + * - `moisture` - a value between 0 and 1 that determines whether a tile becomes sandy (low moisture) or grassy (high moisture). + * - `aux` - a value between 0 and 1 that determines whether low-moisture tiles become sand or red desert. + * - `temperature` - provides a value (vaguely representing degrees Celsius, varying between -20 and 50) that is used + * (together with moisture and aux) as part of tree and decorative placement. + * - `elevation` - tiles values less than zero become water. Cliffs are placed along certain contours according to + * {@link CliffPlacementSettings}. + * - `cliffiness` - determines whether (when >0.5) or not (when <0.5) a cliff will be placed at an otherwise suitable + * (according to {@link CliffPlacementSettings}) location. + * - `enemy-base-intensity` - a number that is referenced by both `enemy-base-frequency` and `enemy-base-radius`. i.e. + * if this is overridden, enemy base frequency and size will both be affected and do something reasonable. By + * default, this expression returns a value proportional to distance from any starting point, clamped at about 7. + * - `enemy-base-frequency` - a number representing average number of enemy bases per tile for a region, by default in + * terms of `enemy-base-intensity`. + * - `enemy-base-radius` - a number representing the radius of an enemy base, if one were to be placed on the given + * tile, by default proportional to a constant plus `enemy-base-intensity`. Climate controls ('Moisture' and + * 'Terrain type' at the bottom of the Terrain tab in the map generator GUI) don't have their own dedicated + * structures in MapGenSettings. Instead, their values are stored as property expression overrides with long names: + * - `control-setting:moisture:frequency:multiplier` - frequency (inverse of scale) multiplier for moisture noise. Default is 1. + * - `control-setting:moisture:bias` - global bias for moisture (which normally varies between 0 and 1). Default is 0. + * - `control-setting:aux:frequency:multiplier` - frequency (inverse of scale) multiplier for aux (called 'terrain + * type' in the GUI) noise. Default is 1. + * - `control-setting:aux:bias` - global bias for aux/terrain type (which normally varies between 0 and 1). Default is + * 0. All other MapGenSettings feed into named noise expressions, and therefore placement can be overridden by + * including the name of a property in this dictionary. The probability and richness functions for placing + * specific tiles, entities, and decoratives can be overridden by including an entry named + * `{tile|entity|decorative}:(prototype name):{probability|richness}`. + */ + readonly property_expression_names: Record +} + +interface SignalID { + /** `"item"`, `"fluid"`, or `"virtual"`. */ + readonly type: "item" | "fluid" | "virtual" + /** Name of the item, fluid or virtual signal. */ + readonly name?: string +} + +/** + * An actual signal transmitted by the network. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#Signal View documentation} + */ +interface Signal { + /** ID of the signal. */ + readonly signal: SignalID + /** Value of the signal. */ + readonly count: int +} + +interface UpgradeFilter { + /** `"item"`, or `"entity"`. */ + readonly type: "item" | "entity" + /** Name of the item, or entity. */ + readonly name?: string +} + +/** + * A single filter used by an infinity-filters instance. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#InfinityInventoryFilter View documentation} + */ +interface InfinityInventoryFilter { + /** Name of the item. */ + readonly name: string + /** The count of the filter. */ + readonly count?: uint + /** `"at-least"`, `"at-most"`, or `"exactly"`. Defaults to `"at-least"`. */ + readonly mode?: "at-least" | "at-most" | "exactly" + /** The index of this filter in the filters list. */ + readonly index: uint +} + +/** + * A single filter used by an infinity-pipe type entity. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#InfinityPipeFilter View documentation} + */ +interface InfinityPipeFilter { + /** Name of the fluid. */ + readonly name: string + /** The fill percentage the pipe (e.g. 0.5 for 50%). Can't be negative. */ + readonly percentage?: double + /** The temperature of the fluid. Defaults to the default/minimum temperature of the fluid. */ + readonly temperature?: double + /** `"at-least"`, `"at-most"`, `"exactly"`, `"add"`, or `"remove"`. Defaults to `"at-least"`. */ + readonly mode?: "at-least" | "at-most" | "exactly" | "add" | "remove" +} + +interface FluidBoxFilter { + /** Fluid prototype name of the filtered fluid. */ + readonly name: string + /** The minimum temperature allowed into the fluidbox. */ + readonly minimum_temperature: double + /** The maximum temperature allowed into the fluidbox. */ + readonly maximum_temperature: double +} + +interface FluidBoxFilterSpec { + /** Fluid prototype name of the filtered fluid. */ + readonly name: string + /** The minimum temperature allowed into the fluidbox. */ + readonly minimum_temperature?: double + /** The maximum temperature allowed into the fluidbox. */ + readonly maximum_temperature?: double + /** Force the filter to be set, regardless of current fluid content. */ + readonly force?: boolean +} + +/** + * The settings used by a heat-interface type entity. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#HeatSetting View documentation} + */ +interface HeatSetting { + /** The target temperature. Defaults to the minimum temperature of the heat buffer. */ + readonly temperature?: double + /** `"at-least"`, `"at-most"`, `"exactly"`, `"add"`, or `"remove"`. Defaults to `"at-least"`. */ + readonly mode?: "at-least" | "at-most" | "exactly" | "add" | "remove" +} + +interface HeatConnection { + readonly position: Vector + readonly direction: defines.direction +} + +/** + * A definition of a fluidbox connection point. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#FluidBoxConnection View documentation} + */ +interface FluidBoxConnection { + /** The connection type: "input", "output", or "input-output". */ + readonly type: "input" | "output" | "input-output" + /** The 4 cardinal direction connection points for this pipe. This vector is a table with `x` and `y` keys instead of an array. */ + readonly positions: PositionTable[] + /** The maximum tile distance this underground connection can connect at if this is an underground pipe. */ + readonly max_underground_distance?: uint +} + +interface ArithmeticCombinatorParameters { + /** First signal to use in an operation. If not specified, the second argument will be the value of `first_constant`. */ + readonly first_signal?: SignalID + /** Second signal to use in an operation. If not specified, the second argument will be the value of `second_constant`. */ + readonly second_signal?: SignalID + /** Constant to use as the first argument of the operation. Has no effect when `first_signal` is set. Defaults to `0`. */ + readonly first_constant?: int + /** Constant to use as the second argument of the operation. Has no effect when `second_signal` is set. Defaults to `0`. */ + readonly second_constant?: int + /** + * Must be one of `"*"`, `"/"`, `"+"`, `"-"`, `"%"`, `"^"`, `"<<"`, `">>"`, `"AND"`, `"OR"`, `"XOR"`. When not + * specified, defaults to `"*"`. + */ + readonly operation?: "*" | "/" | "+" | "-" | "%" | "^" | "<<" | ">>" | "AND" | "OR" | "XOR" + /** Specifies the signal to output. */ + readonly output_signal?: SignalID +} + +interface ConstantCombinatorParameters { + /** Signal to emit. */ + readonly signal: SignalID + /** Value of the signal to emit. */ + readonly count: int + /** Index of the constant combinator's slot to set this signal to. */ + readonly index: uint +} + +/** + * A {@link string} that specifies how the inputs should be compared. + * + * **Note**: While the API accepts both versions for `"less/greater than or equal to"` and `"not equal"`, it'll always + * return `"≥"`, `"≤"` or `"≠"` respectively when reading them back. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#ComparatorString View documentation} + */ +type ComparatorString /** "equal to" */ = + | "=" /** "greater than" */ + | ">" /** "lesser than" */ + | "<" /** "greater than or equal to" */ + | "\u2265" /** "greater than or equal to" */ + | ">=" /** "lesser than or equal to" */ + | "\u2264" /** "lesser than or equal to" */ + | "<=" /** "not equal to" */ + | "\u2260" /** "not equal to" */ + | "!=" + +interface DeciderCombinatorParameters { + /** Defaults to blank. */ + readonly first_signal?: SignalID + /** + * Second signal to use in an operation, if any. If this is not specified, the second argument to a decider + * combinator's operation is assumed to be the value of `constant`. + */ + readonly second_signal?: SignalID + /** Constant to use as the second argument of operation. Defaults to `0`. */ + readonly constant?: uint + /** Specifies how the inputs should be compared. If not specified, defaults to `"<"`. */ + readonly comparator?: ComparatorString + /** Defaults to blank. */ + readonly output_signal?: SignalID + /** Defaults to `true`. When `false`, will output a value of `1` for the given `output_signal`. */ + readonly copy_count_from_input?: boolean +} + +interface InserterCircuitConditions { + readonly circuit?: CircuitCondition + readonly logistics?: CircuitCondition +} + +interface CircuitCondition { + /** Specifies how the inputs should be compared. If not specified, defaults to `"<"`. */ + readonly comparator?: ComparatorString + /** Defaults to blank */ + readonly first_signal?: SignalID + /** What to compare `first_signal` to. If not specified, `first_signal` will be compared to `constant`. */ + readonly second_signal?: SignalID + /** + * Constant to compare `first_signal` to. Has no effect when `second_signal` is set. When neither `second_signal` + * nor `constant` are specified, the effect is as though `constant` were specified with the value `0`. + */ + readonly constant?: int +} + +interface CircuitConditionDefinition { + readonly condition: CircuitCondition + /** Whether the condition is currently fulfilled */ + readonly fulfilled?: boolean +} + +interface CircuitConnectionDefinition { + /** Wire color, either {@link defines.wire_type.red} or {@link defines.wire_type.green}. */ + readonly wire: defines.wire_type + readonly target_entity: LuaEntity + readonly source_circuit_id: defines.circuit_connector_id + readonly target_circuit_id: defines.circuit_connector_id +} + +interface WireConnectionDefinition { + /** Wire color, either {@link defines.wire_type.red} or {@link defines.wire_type.green}. */ + readonly wire: defines.wire_type + /** The entity to (dis)connect the source entity with. */ + readonly target_entity: LuaEntity + /** Mandatory if the source entity has more than one circuit connection using circuit wire. */ + readonly source_circuit_id?: defines.circuit_connector_id + /** Mandatory if the target entity has more than one circuit connection using circuit wire. */ + readonly target_circuit_id?: defines.circuit_connector_id + /** Mandatory if the source entity has more than one wire connection using copper wire. */ + readonly source_wire_id?: defines.circuit_connector_id + /** Mandatory if the target entity has more than one wire connection using copper wire. */ + readonly target_wire_id?: defines.circuit_connector_id +} + +interface InventoryFilter { + /** Position of the corresponding filter slot. */ + readonly index: uint + /** Item prototype name of the item to filter. */ + readonly name: string +} + +interface PlaceAsTileResult { + /** The tile prototype. */ + readonly result: LuaTilePrototype + readonly condition_size: uint + readonly condition: CollisionMask +} + +interface BaseCommand { + /** Type of command. The remaining fields depend on the value of this field. */ + readonly type: defines.command +} + +interface AttackCommand extends BaseCommand { + readonly type: defines.command.attack + readonly target: LuaEntity + /** Defaults to `defines.distraction.by_enemy`. */ + readonly distraction?: defines.distraction +} + +interface GoToLocationCommand extends BaseCommand { + readonly type: defines.command.go_to_location + /** + * The position to path to. Either this or `destination_entity` need to be specified. If both are, + * `destination_entity` is used. + */ + readonly destination?: Position + /** The entity to path to. Either this or `destination` need to be specified. If both are, `destination_entity` is used. */ + readonly destination_entity?: LuaEntity + /** Defaults to `defines.distraction.by_enemy`. */ + readonly distraction?: defines.distraction + /** Flags that affect pathfinder behavior. */ + readonly pathfind_flags?: PathfinderFlags + /** How close the pathfinder needs to get to its destination (in tiles). Defaults to `3`. */ + readonly radius?: double +} + +interface CompoundCommand extends BaseCommand { + readonly type: defines.command.compound + /** How the commands should be chained together. */ + readonly structure_type: defines.compound_command + /** The sub-commands. */ + readonly commands: Command[] +} + +interface GroupCommand extends BaseCommand { + readonly type: defines.command.group + /** The group whose command to follow. */ + readonly group: LuaUnitGroup + /** Defaults to `defines.distraction.by_enemy`. */ + readonly distraction?: defines.distraction + /** Whether the unit will use the group distraction or the commands distraction. Defaults to true. */ + readonly use_group_distraction?: boolean +} + +interface AttackAreaCommand extends BaseCommand { + readonly type: defines.command.attack_area + /** Center of the attack area. */ + readonly destination: Position + /** Radius of the attack area. */ + readonly radius: double + /** Defaults to `defines.distraction.by_enemy`. */ + readonly distraction?: defines.distraction +} + +interface WanderCommand extends BaseCommand { + readonly type: defines.command.wander + /** Defaults to `defines.distraction.by_enemy`. */ + readonly distraction?: defines.distraction + /** Defaults to 10. Does not apply when `wander_in_group` is `true`. */ + readonly radius?: double + /** + * When commanding a group, defines how the group will wander. When `true`, the units in the group will wander + * around inside the group's radius, just like gathering biters. When `false`, the units will wander as a group, ie + * they will all walk together in the same random direction. Default is true for groups. Passing true for a single + * unit is an error. + */ + readonly wander_in_group?: boolean + /** Ticks to wander before successfully completing the command. Default is max uint, which means wander forever. */ + readonly ticks_to_wait?: uint +} + +interface StopCommand extends BaseCommand { + readonly type: defines.command.stop + /** Defaults to `defines.distraction.by_enemy`. */ + readonly distraction?: defines.distraction + /** Ticks to wander before successfully completing the command. Default is max uint, which means stop forever. */ + readonly ticks_to_wait?: uint +} + +interface FleeCommand extends BaseCommand { + readonly type: defines.command.flee + /** The entity to flee from */ + readonly from: LuaEntity + /** Defaults to `defines.distraction.by_enemy`. */ + readonly distraction?: defines.distraction +} + +interface BuildBaseCommand extends BaseCommand { + readonly type: defines.command.build_base + /** Where to build the base. */ + readonly destination: Position + /** Defaults to `defines.distraction.by_enemy`. */ + readonly distraction?: defines.distraction + /** + * Whether the units should ignore expansion candidate chunks. When `false`, they will obey and not build a base in + * a non-candidate chunk. Defaults to `false`. + */ + readonly ignore_planner?: boolean +} + +/** + * Commands can be given to enemies and unit groups. + * + * Other attributes may be specified depending on `type`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#Command View documentation} + */ +type Command = + | AttackCommand + | GoToLocationCommand + | CompoundCommand + | GroupCommand + | AttackAreaCommand + | WanderCommand + | StopCommand + | FleeCommand + | BuildBaseCommand + +interface PathfinderFlags { + /** Allows pathing through friendly entities. Defaults to `false`. */ + readonly allow_destroy_friendly_entities?: boolean + /** Allows the pathfinder to path through entities of the same force. Defaults to `false`. */ + readonly allow_paths_through_own_entities?: boolean + /** + * Enables path caching. This can be more efficient, but might fail to respond to changes in the environment. + * Defaults to `true`. + */ + readonly cache?: boolean + /** Makes the pathfinder try to path in straight lines. Defaults to `false`. */ + readonly prefer_straight_paths?: boolean + /** + * Sets lower priority on the path request, meaning it might take longer to find a path at the expense of speeding + * up others. Defaults to `false`. + */ + readonly low_priority?: boolean + /** + * Makes the pathfinder not break in the middle of processing this pathfind, no matter how much work is needed. + * Defaults to `false`. + */ + readonly no_break?: boolean +} + +interface UnitSpawnDefinition { + /** Prototype name of the unit that would be spawned. */ + readonly unit: string + /** The points at which to spawn the unit. */ + readonly spawn_points: SpawnPointDefinition[] +} + +interface SpawnPointDefinition { + /** Evolution factor for which this weight applies. */ + readonly evolution_factor: double + /** Probability of spawning this unit at this evolution factor. */ + readonly weight: double +} + +interface ItemStackDefinition { + /** Prototype name of the item the stack holds. */ + readonly name: string + /** Number of items the stack holds. If not specified, defaults to `1`. */ + readonly count?: uint + /** Health of the items in the stack. Defaults to `1.0`. */ + readonly health?: float + /** Durability of the tool items in the stack. */ + readonly durability?: double + /** Amount of ammo in the ammo items in the stack. */ + readonly ammo?: double + /** Tags of the items with tags in the stack. */ + readonly tags?: string[] +} + +/** + * - String: The name of the item, which represents a full stack of that item. + * - ItemStackDefinition: The detailed definition of an item stack. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#SimpleItemStack View documentation} + * + * @example + * Both of these lines specify an item stack of one iron plate: + * + * ```lua + * {name="iron-plate"} + * ``` + * + * ```lua + * {name="iron-plate", count=1} + * ``` + * + * @example + * This is a stack of 47 copper plates: + * + * ```lua + * {name="copper-plate", count=47} + * ``` + * + * @example + * These are both full stacks of iron plates (for iron-plate, a full stack is 100 plates): + * + * ```lua + * "iron-plate" + * ``` + * + * ```lua + * {name="iron-plate", count=100} + * ``` + */ +type SimpleItemStack = string | ItemStackDefinition + +/** + * - String: The fluid name. + * - LuaFluidPrototype: The fluid prototype. + * - Fluid: The fluid. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#FluidIdentification View documentation} + */ +type FluidIdentification = string | LuaFluidPrototype | Fluid + +/** + * - String: The force name. + * - LuaForce: A reference to {@link LuaForce} may be passed directly. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#ForceIdentification View documentation} + */ +type ForceIdentification = string | LuaForce + +/** + * - String: The technology name. + * - LuaTechnology: A reference to {@link LuaTechnology} may be passed directly. + * - LuaTechnologyPrototype: A reference to {@link LuaTechnologyPrototype} may be passed directly. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#TechnologyIdentification View documentation} + */ +type TechnologyIdentification = string | LuaTechnology | LuaTechnologyPrototype + +/** + * - Uint: It will be the index of the surface. `nauvis` has index `1`, the first surface-created surface will have index + * `2` and so on. + * - String: It will be the surface name. E.g. `"nauvis"`. + * - LuaSurface: A reference to {@link LuaSurface} may be passed directly. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#SurfaceIdentification View documentation} + */ +type SurfaceIdentification = uint | string | LuaSurface + +/** + * - Uint: The player index. + * - String: The player name. + * - LuaPlayer: A reference to {@link LuaPlayer} may be passed directly. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#PlayerIdentification View documentation} + */ +type PlayerIdentification = uint | string | LuaPlayer + +type ItemStackIdentification = SimpleItemStack | LuaItemStack + +/** + * - LuaEntity: The entity. + * - LuaEntityPrototype: The entity prototype. + * - String: The prototype name. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#EntityPrototypeIdentification View documentation} + */ +type EntityPrototypeIdentification = LuaEntity | LuaEntityPrototype | string + +/** + * - LuaItemStack: The item. + * - LuaItemPrototype: The item prototype. + * - String: The prototype name. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#ItemPrototypeIdentification View documentation} + */ +type ItemPrototypeIdentification = LuaItemStack | LuaItemPrototype | string + +interface WaitCondition { + /** + * One of `"time"`, `"inactivity"`, `"full"`, `"empty"`, `"item_count"`, `"circuit"`, `"robots_inactive"`, + * `"fluid_count"`, `"passenger_present"`, `"passenger_not_present"`. + */ + readonly type: + | "time" + | "inactivity" + | "full" + | "empty" + | "item_count" + | "circuit" + | "robots_inactive" + | "fluid_count" + | "passenger_present" + | "passenger_not_present" + /** + * Either `"and"`, or `"or"`. Tells how this condition is to be compared with the preceding conditions in the + * corresponding `wait_conditions` array. + */ + readonly compare_type: "and" | "or" + /** Number of ticks to wait or of inactivity. Only present when `type` is `"time"` or `"inactivity"`. */ + readonly ticks?: uint + /** Only present when `type` is `"item_count"`, `"circuit"` or `"fluid_count"`. */ + readonly condition?: CircuitCondition +} + +interface TrainScheduleRecord { + /** Name of the station. */ + readonly station?: string + /** Rail to path to. Ignored if `station` is present. */ + readonly rail?: LuaEntity + readonly wait_conditions?: WaitCondition[] + /** Only present when the station is temporary, the value is then always `true`. */ + readonly temporary?: boolean +} + +interface TrainSchedule { + /** Index of the currently active record */ + readonly current: uint + readonly records: TrainScheduleRecord[] +} + +interface BaseGuiArrowSpecification { + /** + * This determines which of the following fields will be required. Must be one of `"nowhere"` (will remove the arrow + * entirely), `"goal"` (will point to the current goal), `"entity_info"`, `"active_window"`, `"entity"`, + * `"position"`, `"crafting_queue"` or `"item_stack"` (will point to a given item stack in an inventory). Depending + * on this value, other fields may have to be specified. + */ + readonly type: + | "nowhere" + | "goal" + | "entity_info" + | "active_window" + | "entity" + | "position" + | "crafting_queue" + | "item_stack" +} + +interface EntityGuiArrowSpecification extends BaseGuiArrowSpecification { + readonly type: "entity" + readonly entity: LuaEntity +} + +interface PositionGuiArrowSpecification extends BaseGuiArrowSpecification { + readonly type: "position" + readonly position: Position +} + +interface CraftingQueueGuiArrowSpecification extends BaseGuiArrowSpecification { + readonly type: "crafting_queue" + /** Index in the crafting queue to point to. */ + readonly crafting_queueindex: uint +} + +interface ItemStackGuiArrowSpecification extends BaseGuiArrowSpecification { + readonly type: "item_stack" + /** Which inventory the stack is in. */ + readonly inventory_index: defines.inventory + /** Which stack to point to. */ + readonly item_stack_index: uint + /** Must be either `"player"`, `"target"`, `"player-quickbar"` or `"player-equipment-bar"`. */ + readonly source: "player" | "target" | "player-quickbar" | "player-equipment-bar" +} + +interface OtherGuiArrowSpecification extends BaseGuiArrowSpecification { + readonly type: "nowhere" | "goal" | "entity_info" | "active_window" +} + +/** + * Used for specifying where a GUI arrow should point to. + * + * Other attributes may be specified depending on `type`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#GuiArrowSpecification View documentation} + */ +type GuiArrowSpecification = + | EntityGuiArrowSpecification + | PositionGuiArrowSpecification + | CraftingQueueGuiArrowSpecification + | ItemStackGuiArrowSpecification + | OtherGuiArrowSpecification + +interface AmmoType { + readonly action?: TriggerItem[] + /** + * One of `"entity"` (fires at an entity), `"position"` (fires directly at a position), or `"direction"` (fires in a + * direction). + */ + readonly target_type: "entity" | "position" | "direction" + /** + * When `true`, the gun will be able to shoot even when the target is out of range. Only applies when `target_type` + * is `position`. The gun will fire at the maximum range in the direction of the target position. Defaults to `false`. + */ + readonly clamp_position?: boolean + /** Ammo category of this ammo. */ + readonly category: string + /** Energy consumption of a single shot, if applicable. Defaults to `0`. */ + readonly energy_consumption?: double +} + +interface BeamTarget { + /** The target entity. */ + readonly entity?: LuaEntity + /** The target position. */ + readonly position?: Position +} + +interface RidingState { + readonly acceleration: defines.riding.acceleration + readonly direction: defines.riding.direction +} + +type SpriteType = + | "item" + | "entity" + | "technology" + | "recipe" + | "item-group" + | "fluid" + | "tile" + | "virtual-signal" + | "achievement" + | "equipment" + | "file" + | "utility" + +/** + * It is specified by {@link string}. It can be either the name of a + * {@link https://wiki.factorio.com/Prototype/Sprite sprite prototype} defined in the data stage or a path in form "type/name". + * + * The supported types are: + * + * - `"item"` - for example "item/iron-plate" is the icon sprite of iron plate + * - `"entity"` - for example "entity/small-biter" is the icon sprite of the small biter + * - `"technology"` + * - `"recipe"` + * - `"item-group"` + * - `"fluid"` + * - `"tile"` + * - `"virtual-signal"` + * - `"achievement"` + * - `"equipment"` + * - `"file"` - path to an image file located inside the current scenario. This file is not preloaded so it will be + * slower; for frequently used sprites, it is better to define sprite prototype and use it instead. + * - `"utility"` - sprite defined in the utility-sprites object, these are the pictures used by the game internally for the UI. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#SpritePath View documentation} + */ +type SpritePath = string | `${SpriteType}/${string}` + +/** + * A sound defined by a {@link string}. It can be either the name of a + * {@link https://wiki.factorio.com/Prototype/Sound sound prototype} defined in the data stage or a path in the form + * `"type/name"`. The latter option can be sorted into three categories. + * + * The utility and ambient types each contain general use sound prototypes defined by the game itself. + * + * - `"utility"` - Uses the {@link https://wiki.factorio.com/Prototype/UtilitySounds UtilitySounds} prototype. Example: + * `"utility/wire_connect_pole"` + * - `"ambient"` - Uses {@link https://wiki.factorio.com/Prototype/AmbientSound AmbientSound} prototypes. Example: + * `"ambient/resource-deficiency"` + * + * The following types can be combined with any tile name as long as its prototype defines the + * + * corresponding sound. + * + * - `"tile-walking"` - Uses {@link https://wiki.factorio.com/Prototype/Tile#walking_sound Tile::walking_sound}. Example: + * `"tile-walking/concrete"` + * - `"tile-mined"` - Uses {@link https://wiki.factorio.com/Prototype/Tile#mined_sound Tile::mined_sound} + * - `"tile-build-small"` - Uses {@link https://wiki.factorio.com/Prototype/Tile#build_sound Tile::build_sound}. Example: + * `"tile-build-small/concrete"` + * - `"tile-build-medium"` - Uses {@link https://wiki.factorio.com/Prototype/Tile#build_sound Tile::build_sound} + * - `"tile-build-large"` - Uses {@link https://wiki.factorio.com/Prototype/Tile#build_sound Tile::build_sound} + * + * The following types can be combined with any entity name as long as its prototype defines the + * + * corresponding sound. + * + * - `"entity-build"` - Uses {@link https://wiki.factorio.com/Prototype/Entity#build_sound Entity::build_sound}. Example: + * `"entity-build/wooden-chest"` + * - `"entity-mined"` - Uses {@link https://wiki.factorio.com/Prototype/Entity#mined_sound Entity::mined_sound} + * - `"entity-mining"` - Uses {@link https://wiki.factorio.com/Prototype/Entity#mining_sound Entity::mining_sound} + * - `"entity-vehicle_impact"` - Uses + * {@link https://wiki.factorio.com/Prototype/Entity#vehicle_impact_sound Entity::vehicle_impact_sound} + * - `"entity-rotated"` - Uses {@link https://wiki.factorio.com/Prototype/Entity#rotated_sound Entity::rotated_sound} + * - `"entity-open"` - Uses {@link https://wiki.factorio.com/Prototype/Entity#open_sound Entity::open_sound} + * - `"entity-close"` - Uses {@link https://wiki.factorio.com/Prototype/Entity#close_sound Entity::close_sound} + * + * {@link https://lua-api.factorio.com/next/Concepts.html#SoundPath View documentation} + */ +type SoundPath = string | `${SoundType}/${string}` + +interface ModuleEffectValue { + /** The percentual increase of the attribute. A value of `0.6` means a 60% increase. */ + readonly bonus: float +} + +/** + * {@link https://lua-api.factorio.com/next/Concepts.html#ModuleEffects View documentation} + * + * @example + * These are the effects of the vanilla Productivity Module 3 (up to floating point imprecisions): + * + * ```lua + * {consumption={bonus=0.6}, + * speed={bonus=-0.15}, + * productivity={bonus=0.06}, + * pollution={bonus=0.075}} + * ``` + */ +interface ModuleEffects { + readonly consumption?: ModuleEffectValue + readonly speed?: ModuleEffectValue + readonly productivity?: ModuleEffectValue + readonly pollution?: ModuleEffectValue +} + +/** + * This is a set of flags given as a dictionary[{@link string} → {@link boolean}]. When a flag is set, it is present in + * the dictionary with the value `true`. Unset flags aren't present in the dictionary at all. So, the boolean value is + * meaningless and exists just for easy table lookup if a flag is set. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#EntityPrototypeFlags View documentation} + */ +interface EntityPrototypeFlags { + readonly "not-rotatable"?: boolean + readonly "placeable-neutral"?: boolean + readonly "placeable-player"?: boolean + readonly "placeable-enemy"?: boolean + readonly "placeable-off-grid"?: boolean + readonly "player-creation"?: boolean + readonly "building-direction-8-way"?: boolean + readonly "filter-directions"?: boolean + readonly "fast-replaceable-no-build-while-moving"?: boolean + readonly "breaths-air"?: boolean + readonly "not-repairable"?: boolean + readonly "not-on-map"?: boolean + readonly "not-deconstructable"?: boolean + readonly "not-blueprintable"?: boolean + readonly hidden?: boolean + readonly "hide-alt-info"?: boolean + readonly "fast-replaceable-no-cross-type-while-moving"?: boolean + readonly "no-gap-fill-while-building"?: boolean + readonly "not-flammable"?: boolean + readonly "no-automated-item-removal"?: boolean + readonly "no-automated-item-insertion"?: boolean + readonly "no-copy-paste"?: boolean + readonly "not-selectable-in-game"?: boolean + readonly "not-upgradable"?: boolean +} + +/** + * This is a set of flags given as dictionary[{@link string} → {@link boolean}]. When a flag is set, it is present in the + * dictionary with the value `true`. Unset flags aren't present in the dictionary at all. So, the boolean value is + * meaningless and exists just for easy table lookup if a flag is set. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#ItemPrototypeFlags View documentation} + */ +interface ItemPrototypeFlags { + readonly "draw-logistic-overlay"?: boolean + readonly hidden?: boolean + readonly "always-show"?: boolean + readonly "hide-from-bonus-gui"?: boolean + readonly "hide-from-fuel-tooltip"?: boolean + readonly "not-stackable"?: boolean + readonly "can-extend-inventory"?: boolean + readonly "primary-place-result"?: boolean + readonly "mod-openable"?: boolean + readonly "only-in-cursor"?: boolean +} + +/** + * A {@link string} specifying a collision mask layer. + * + * Possible values for the string are: + * + * - `"ground-tile"` + * - `"water-tile"` + * - `"resource-layer"` + * - `"doodad-layer"` + * - `"floor-layer"` + * - `"item-layer"` + * - `"ghost-layer"` + * - `"object-layer"` + * - `"player-layer"` + * - `"train-layer"` + * - `"rail-layer"` + * - `"transport-belt-layer"` + * - `"not-setup"` + * + * Additionally the values `"layer-13"` through `"layer-55"`. These layers are currently unused by the game but may + * change. If a mod is going to use one of the unused layers it's recommended to start at the higher layers because the + * base game will take from the lower ones. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#CollisionMaskLayer View documentation} + */ +type CollisionMaskLayer = + | "ground-tile" + | "water-tile" + | "resource-layer" + | "doodad-layer" + | "floor-layer" + | "item-layer" + | "ghost-layer" + | "object-layer" + | "player-layer" + | "train-layer" + | "rail-layer" + | "transport-belt-layer" + | "not-setup" + | `layer-${number}` + +/** + * This is a set of masks given as a dictionary[{@link CollisionMaskLayer} → {@link boolean}]. Only set masks are present + * in the dictionary and they have the value `true`. Unset flags aren't present at all. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#CollisionMask View documentation} + */ +type CollisionMask = { + readonly [P in CollisionMaskLayer]?: true +} + +/** + * A {@link CollisionMask} but also includes any flags this mask has. + * + * Flags such as: + * + * - `"not-colliding-with-itself"` + * - `"consider-tile-transitions"` + * - `"colliding-with-tiles-only"` + * + * {@link https://lua-api.factorio.com/next/Concepts.html#CollisionMaskWithFlags View documentation} + */ +type CollisionMaskWithFlags = { + readonly [P in + | CollisionMaskLayer + | "not-colliding-with-itself" + | "consider-tile-transitions" + | "colliding-with-tiles-only"]?: true +} + +/** + * This is a set of trigger target masks given as a dictionary[{@link string} → {@link boolean}]. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#TriggerTargetMask View documentation} + */ +type TriggerTargetMask = { + readonly [P in string]?: true +} + +interface TriggerEffectItem { + /** + * One of`"damage"`, `"create-entity"`, `"create-explosion"`, `"create-fire"`, `"create-smoke"`, + * `"create-trivial-smoke"`, `"create-particle"`, `"create-sticker"`, `"nested-result"`, `"play-sound"`, + * `"push-back"`, `"destroy-cliffs"`, `"show-explosion-on-chart"`, `"insert-item"`, `"script"`. + */ + readonly type: + | "damage" + | "create-entity" + | "create-explosion" + | "create-fire" + | "create-smoke" + | "create-trivial-smoke" + | "create-particle" + | "create-sticker" + | "nested-result" + | "play-sound" + | "push-back" + | "destroy-cliffs" + | "show-explosion-on-chart" + | "insert-item" + | "script" + readonly repeat_count: uint + readonly affects_target: boolean + readonly show_in_tooltip: boolean +} + +interface TriggerDelivery { + /** One of `"instant"`, `"projectile"`, `"flame-thrower"`, `"beam"`, `"stream"`, `"artillery"`. */ + readonly type: "instant" | "projectile" | "flame-thrower" | "beam" | "stream" | "artillery" + readonly source_effects: TriggerEffectItem[] + readonly target_effects: TriggerEffectItem[] +} + +interface TriggerItem { + /** One of `"direct"`, `"area"`, `"line"`, `"cluster"`. */ + readonly type: "direct" | "area" | "line" | "cluster" + readonly action_delivery?: TriggerDelivery[] + /** The trigger will only affect entities that contain any of these flags. */ + readonly entity_flags?: EntityPrototypeFlags + readonly ignore_collision_condition: boolean + /** The trigger will only affect entities that would collide with given collision mask. */ + readonly collision_mask: CollisionMask + readonly trigger_target_mask: TriggerTargetMask + /** + * If `"enemy"`, the trigger will only affect entities whose force is different from the attacker's and for which + * there is no cease-fire set. `"ally"` is the opposite of `"enemy"`. + */ + readonly force: ForceCondition + readonly repeat_count: uint +} + +interface CircularParticleCreationSpecification { + /** Name of the {@link LuaEntityPrototype} */ + readonly name: string + readonly direction: float + readonly direction_deviation: float + readonly speed: float + readonly speed_deviation: float + readonly starting_frame_speed: float + readonly starting_frame_speed_deviation: float + readonly height: float + readonly height_deviation: float + readonly vertical_speed: float + readonly vertical_speed_deviation: float + /** This vector is a table with `x` and `y` keys instead of an array. */ + readonly center: PositionTable + readonly creation_distance: double + readonly creation_distance_orientation: double + readonly use_source_position: boolean +} + +/** + * An array with the following members: + * + * - A {@link RealOrientation} + * - A {@link Vector} + * + * {@link https://lua-api.factorio.com/next/Concepts.html#CircularProjectileCreationSpecification View documentation} + */ +type CircularProjectileCreationSpecification = [RealOrientation, Vector] + +interface AttackParameterFluid { + /** Name of the {@link LuaFluidPrototype}. */ + readonly type: string + /** Multiplier applied to the damage of an attack. */ + readonly damage_modifier: double +} + +interface BaseAttackParameters { + /** The type of AttackParameter. One of `'projectile'`, `'stream'` or `'beam'`. */ + readonly type: "projectile" | "stream" | "beam" + /** Maximum range of attack. */ + readonly range: float + /** Minimum range of attack. Used with flamethrower turrets to prevent self-immolation. */ + readonly min_range: float + /** Defines how the range is determined. Either `'center-to-center'` or `'bounding-box-to-bounding-box'`. */ + readonly range_mode: "center-to-center" | "bounding-box-to-bounding-box" + /** When searching for the nearest enemy to attack, `fire_penalty` is added to the enemy's distance if they are on fire. */ + readonly fire_penalty: float + /** + * When searching for an enemy to attack, a higher `rotate_penalty` will discourage targeting enemies that would + * take longer to turn to face. + */ + readonly rotate_penalty: float + /** + * When searching for an enemy to attack, a higher `health_penalty` will discourage targeting enemies with high + * health. A negative penalty will do the opposite. + */ + readonly health_penalty: float + /** + * If less than `range`, the entity will choose a random distance between `range` and `min_attack_distance` and + * attack from that distance. Used for spitters. + */ + readonly min_attack_distance: float + /** The arc that the entity can attack in as a fraction of a circle. A value of `1` means the full 360 degrees. */ + readonly turn_range: float + /** Multiplier applied to the damage of an attack. */ + readonly damage_modifier: float + /** Multiplier applied to the ammo consumption of an attack. */ + readonly ammo_consumption_modifier: float + /** Minimum amount of ticks between shots. If this is less than `1`, multiple shots can be performed per tick. */ + readonly cooldown: float + /** Number of ticks it takes for the weapon to actually shoot after it has been ordered to do so. */ + readonly warmup: uint + readonly movement_slow_down_factor: double + readonly movement_slow_down_cooldown: float + readonly ammo_type?: AmmoType + /** List of the names of compatible {@link LuaAmmoCategoryPrototype LuaAmmoCategoryPrototypes}. */ + readonly ammo_categories?: string[] +} + +interface ProjectileAttackParameters extends BaseAttackParameters { + readonly type: "projectile" + readonly projectile_center: Vector + readonly projectile_creation_distance: float + readonly projectile_orientation_offset: float + readonly shell_particle?: CircularParticleCreationSpecification + readonly projectile_creation_parameters?: CircularProjectileCreationSpecification[] +} + +interface StreamAttackParameters extends BaseAttackParameters { + readonly type: "stream" + readonly gun_barrel_length: float + readonly gun_center_shift: Record + readonly fluid_consumption: float + readonly fluids?: AttackParameterFluid[] + readonly projectile_creation_parameters?: CircularProjectileCreationSpecification[] +} + +interface OtherAttackParameters extends BaseAttackParameters { + readonly type: "beam" +} + +/** + * Other attributes may be specified depending on `type`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#AttackParameters View documentation} + */ +type AttackParameters = ProjectileAttackParameters | StreamAttackParameters | OtherAttackParameters + +interface CapsuleAction { + /** One of `"throw"`, `"equipment-remote"`, `"use-on-self"`. */ + readonly type: "throw" | "equipment-remote" | "use-on-self" + /** Only present when `type` is `"throw"` or `"use-on-self"`. */ + readonly attack_parameters?: AttackParameters + /** Only present when `type` is `"equipment-remote"`. It is the equipment prototype name. */ + readonly equipment?: string +} + +/** + * This is a set of flags given as a dictionary[{@link string} → {@link boolean}]. Set flags are present in the dictionary + * with the value `true`; unset flags aren't present at all. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#SelectionModeFlags View documentation} + */ +interface SelectionModeFlags { + /** Entities that can be selected for blueprint. */ + readonly blueprint?: boolean + /** Entities that can be marked for deconstruction. */ + readonly deconstruct?: boolean + /** Entities that can be marked for deconstruction cancelling. */ + readonly "cancel-deconstruct"?: boolean + readonly items?: boolean + readonly trees?: boolean + /** Buildable entities. */ + readonly "buildable-type"?: boolean + /** Only select an area. */ + readonly nothing?: boolean + /** Entities that can be placed using an item. */ + readonly "items-to-place"?: boolean + readonly "any-entity"?: boolean + readonly "any-tile"?: boolean + /** Entities with the same force as the selector. */ + readonly "same-force"?: boolean + readonly "not-same-force"?: boolean + readonly friend?: boolean + readonly enemy?: boolean + readonly upgrade?: boolean + readonly "cancel-upgrade"?: boolean + readonly "entity-with-health"?: boolean + readonly "entity-with-force"?: boolean + readonly "entity-with-owner"?: boolean +} + +interface LogisticFilter { + /** The index this filter applies to. */ + readonly index: uint + /** The item name for this filter. */ + readonly name: string + /** The count for this filter. */ + readonly count: uint +} + +/** + * **Note**: Runtime settings can be changed through console commands and by the mod that owns the settings by writing a + * new table to the ModSetting. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#ModSetting View documentation} + */ +interface ModSetting { + /** The value of the mod setting. The type depends on the setting. */ + readonly value: uint | double | boolean | string +} + +/** + * Any basic type (string, number, boolean) or table. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#AnyBasic View documentation} + */ +type AnyBasic = string | number | boolean | table + +/** + * Any basic type (string, number, boolean), table, or LuaObject. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#Any View documentation} + */ +type Any = any + +interface ProgrammableSpeakerParameters { + readonly playback_volume: double + readonly playback_globally: boolean + readonly allow_polyphony: boolean +} + +interface ProgrammableSpeakerAlertParameters { + readonly show_alert: boolean + readonly show_on_map: boolean + readonly icon_signal_id: SignalID + readonly alert_message: string +} + +interface ProgrammableSpeakerCircuitParameters { + readonly signal_value_is_pitch: boolean + readonly instrument_id: uint + readonly note_id: uint +} + +interface ProgrammableSpeakerInstrument { + readonly name: string + readonly notes: string[] +} + +/** + * A {@link string} that specifies where a gui element should be. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#Alignment View documentation} + */ +type Alignment = + | "top-left" + | "middle-left" /** The same as `"middle-left"` */ + | "left" + | "bottom-left" + | "top-center" + | "middle-center" /** The same as `"middle-center"` */ + | "center" + | "bottom-center" + | "top-right" /** The same as `"middle-right"` */ + | "right" + | "bottom-right" + +/** + * Information about the event that has been raised. The table can also contain other fields depending on the type of + * event. See {@link https://lua-api.factorio.com/next/events.html the list of Factorio events} for more information on these. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#EventData View documentation} + */ +interface EventData { + /** The identifier of the event this handler was registered to. */ + readonly name: EventId + /** The tick during which the event happened. */ + readonly tick: uint + /** The name of the mod that raised the event if it was raised using {@link LuaBootstrap.raise_event LuaBootstrap::raise_event}. */ + readonly mod_name?: string +} + +interface NthTickEventData { + /** The tick during which the event happened. */ + readonly tick: uint + /** The nth tick this handler was registered to. */ + readonly nth_tick: uint +} + +interface ModChangeData { + /** Old version of the mod. May be `nil` if the mod wasn't previously present (i.e. it was just added). */ + readonly old_version: string | undefined + /** New version of the mod. May be `nil` if the mod is no longer present (i.e. it was just removed). */ + readonly new_version: string | undefined +} + +interface ConfigurationChangedData { + /** Old version of the map. Present only when loading map version other than the current version. */ + readonly old_version?: string + /** New version of the map. Present only when loading map version other than the current version. */ + readonly new_version?: string + /** Dictionary of mod changes. It is indexed by mod name. */ + readonly mod_changes: Record + /** `true` when mod startup settings have changed since the last time this save was loaded. */ + readonly mod_startup_settings_changed: boolean + /** `true` when mod prototype migrations have been applied since the last time this save was loaded. */ + readonly migration_applied: boolean +} + +interface CustomCommandData { + /** The name of the command. */ + readonly name: string + /** The tick the command was used in. */ + readonly tick: uint + /** The player who issued the command, or `nil` if it was issued from the server console. */ + readonly player_index?: uint + /** The parameter passed after the command, if there is one. */ + readonly parameter?: string +} + +interface SelectedPrototypeData { + /** E.g. `"entity"`. */ + readonly base_type: string + /** E.g. `"tree"`. */ + readonly derived_type: string + /** E.g. `"tree-05"`. */ + readonly name: string +} + +interface ScriptRenderTarget { + readonly entity?: LuaEntity + readonly entity_offset?: Vector + readonly position?: Position +} + +type MouseButtonFlag = + | "left" + | "right" + | "middle" + | "button-4" + | "button-5" + | "button-6" + | "button-7" + | "button-8" + | "button-9" + +type MouseButtonFlagsTable = { + readonly [P in MouseButtonFlag]?: true +} + +type MouseButtonFlagsArray = readonly (MouseButtonFlag | "left-and-right")[] + +/** + * This is a set of flags given as a dictionary[{@link string} → {@link boolean}]. When a flag is set, it is present in + * the dictionary with the value `true`. Unset flags aren't present in the dictionary at all. + * + * To write to this, use an array[{@link string}] of the mouse buttons that should be possible to use with on button. + * + * When setting flags, the flag `"left-and-right"` can also be set which will set `"left"` and `"right"` true. + * + * Possible flags when reading are: + * + * - `"left"` + * - `"right"` + * - `"middle"` + * - `"button-4"` + * - `"button-5"` + * - `"button-6"` + * - `"button-7"` + * - `"button-8"` + * - `"button-9"` + * + * {@link https://lua-api.factorio.com/next/Concepts.html#MouseButtonFlags View documentation} + */ +type MouseButtonFlags = MouseButtonFlagsTable | MouseButtonFlagsArray + +/** + * It is specified by {@link string}. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#CursorBoxRenderType View documentation} + */ +type CursorBoxRenderType /** Yellow box. */ = + | "entity" /** Red box. */ + | "not-allowed" /** Light blue box. */ + | "electricity" /** Light blue box. */ + | "pair" /** Green box. */ + | "copy" /** White box. */ + | "train-visualization" /** Light blue box. */ + | "logistics" /** Green box. */ + | "blueprint-snap-rectangle" + +/** + * It is specified by {@link string}. + * + * {@link https://lua-api.factorio.com/next/Concepts.html#ForceCondition View documentation} + */ +type ForceCondition /** All forces pass. */ = + | "all" /** Forces which will attack pass. */ + | "enemy" /** Forces which won't attack pass. */ + | "ally" /** Forces which are friends pass. */ + | "friend" /** Forces which are not friends pass. */ + | "not-friend" /** The same force pass. */ + | "same" /** The non-same forces pass. */ + | "not-same" + +/** + * A value between 0 and 255 inclusive represented by one of the following named {@link string} or string version of the + * value (for example `"27"` and `"decals"` are both valid). Higher values are rendered on top of lower values. + * + * - `"water-tile"`: 15 + * - `"ground-tile"`: 25 + * - `"tile-transition"`: 26 + * - `"decals"`: 27 + * - `"lower-radius-visualization"`: 29 + * - `"radius-visualization"`: 30 + * - `"transport-belt-integration"`: 65 + * - `"resource"`:66 + * - `"building-smoke"`:67 + * - `"decorative"`: 92 + * - `"ground-patch"`: 93 + * - `"ground-patch-higher"`: 94 + * - `"ground-patch-higher2"`: 95 + * - `"remnants"`: 112 + * - `"floor"`: 113 + * - `"transport-belt"`: 114 + * - `"transport-belt-endings"`: 115 + * - `"floor-mechanics-under-corpse"`: 120 + * - `"corpse"`: 121 + * - `"floor-mechanics"`: 122 + * - `"item"`: 123 + * - `"lower-object"`: 124 + * - `"transport-belt-circuit-connector"`: 126 + * - `"lower-object-above-shadow"`: 127 + * - `"object"`: 129 + * - `"higher-object-under"`: 131 + * - `"higher-object-above"`: 132 + * - `"item-in-inserter-hand"`: 134 + * - `"wires"`: 135 + * - `"wires-above"`: 136 + * - `"entity-info-icon"`: 138 + * - `"entity-info-icon-above"`: 139 + * - `"explosion"`: 142 + * - `"projectile"`: 143 + * - `"smoke"`: 144 + * - `"air-object"`: 145 + * - `"air-entity-info-icon"`: 147 + * - `"light-effect"`: 148 + * - `"selection-box"`: 187 + * - `"higher-selection-box"`: 188 + * - `"collision-selection-box"`: 189 + * - `"arrow"`: 190 + * - `"cursor"`: 210 + * + * {@link https://lua-api.factorio.com/next/Concepts.html#RenderLayer View documentation} + */ +type RenderLayer = + | number + | `${number}` + | "water-tile" + | "ground-tile" + | "tile-transition" + | "decals" + | "lower-radius-visualization" + | "radius-visualization" + | "transport-belt-integration" + | "resource" + | "building-smoke" + | "decorative" + | "ground-patch" + | "ground-patch-higher" + | "remnants" + | "floor" + | "transport-belt" + | "transport-belt-endings" + | "floor-mechanics-under-corpse" + | "corpse" + | "floor-mechanics" + | "item" + | "lower-object" + | "transport-belt-circuit-connector" + | "lower-object-above-shadow" + | "object" + | "higher-object-under" + | "higher-object-above" + | "item-in-inserter-hand" + | "wires" + | "wires-above" + | "entity-info-icon" + | "entity-info-icon-above" + | "explosion" + | "projectile" + | "smoke" + | "air-object" + | "air-entity-info-icon" + | "light-effect" + | "selection-box" + | "higher-selection-box" + | "collision-selection-box" + | "arrow" + | "cursor" + +type CliffOrientation = + | "west-to-east" + | "north-to-south" + | "east-to-west" + | "south-to-north" + | "west-to-north" + | "north-to-east" + | "east-to-south" + | "south-to-west" + | "west-to-south" + | "north-to-west" + | "east-to-north" + | "south-to-east" + | "west-to-none" + | "none-to-east" + | "east-to-none" + | "none-to-west" + | "north-to-none" + | "none-to-south" + | "south-to-none" + | "none-to-north" + +interface ItemStackLocation { + readonly inventory: defines.inventory + readonly slot: uint +} + +interface VehicleAutomaticTargetingParameters { + readonly auto_target_without_gunner: boolean + readonly auto_target_with_gunner: boolean +} + +type SoundType = "game-effect" | "gui-effect" | "ambient" | "environment" | "walking" | "alert" | "wind" + +interface BaseItemPrototypeFilter { + /** + * The condition to filter on. One of `"tool"`, `"mergeable"`, `"item-with-inventory"`, `"selection-tool"`, + * `"item-with-label"`, `"has-rocket-launch-products"`, `"fuel"`, `"place-result"`, `"burnt-result"`, + * `"place-as-tile"`, `"placed-as-equipment-result"`, `"name"`, `"type"`, `"flag"`, `"subgroup"`, `"fuel-category"`, + * `"stack-size"`, `"default-request-amount"`, `"wire-count"`, `"fuel-value"`, `"fuel-acceleration-multiplier"`, + * `"fuel-top-speed-multiplier"`, `"fuel-emissions-multiplier"` + */ + readonly filter: + | "tool" + | "mergeable" + | "item-with-inventory" + | "selection-tool" + | "item-with-label" + | "has-rocket-launch-products" + | "fuel" + | "place-result" + | "burnt-result" + | "place-as-tile" + | "placed-as-equipment-result" + | "name" + | "type" + | "flag" + | "subgroup" + | "fuel-category" + | "stack-size" + | "default-request-amount" + | "wire-count" + | "fuel-value" + | "fuel-acceleration-multiplier" + | "fuel-top-speed-multiplier" + | "fuel-emissions-multiplier" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface PlaceResultItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: "place-result" + /** Filters for the place result. */ + readonly elem_filters?: EntityPrototypeFilter[] +} + +interface BurntResultItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: "burnt-result" + /** Filters for the burnt result. */ + readonly elem_filters?: ItemPrototypeFilter[] +} + +interface PlaceAsTileItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: "place-as-tile" + /** Filters for the placed tile. */ + readonly elem_filters?: TilePrototypeFilter[] +} + +interface PlacedAsEquipmentResultItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: "placed-as-equipment-result" + /** Filters for the placed equipment. */ + readonly elem_filters?: EquipmentPrototypeFilter[] +} + +/** + * For use within nested filters such as the `has-product-item` filter of array[{@link RecipePrototypeFilter}]. To get a + * specific prototype by name, see {@link LuaGameScript.item_prototypes LuaGameScript::item_prototypes}. + */ +interface NameItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: "name" + /** The prototype name, or list of acceptable names. */ + readonly name: string | string[] +} + +/** + * Usage example: + * + * ```lua + * game.get_filtered_item_prototypes({{filter = "type", type = "armor"}}) + * ``` + */ +interface TypeItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface FlagItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: "flag" + /** One of the values in {@link ItemPrototypeFlags}. */ + readonly flag: string +} + +interface SubgroupItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: "subgroup" + /** A {@link LuaGroup} (subgroup) name */ + readonly subgroup: string +} + +interface FuelCategoryItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: "fuel-category" + /** A {@link LuaFuelCategoryPrototype} name */ + readonly "fuel-category": string +} + +/** + * Usage example: + * + * ```lua + * game.get_filtered_item_prototypes({{filter = "stack-size", comparison = ">", value = 20}, {filter = "stack-size", comparison = "<", value = 100, mode = "and"}}) + * ``` + */ +interface StackSizeItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: "stack-size" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: uint +} + +interface DefaultRequestAmountItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: "default-request-amount" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: uint +} + +interface WireCountItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: "wire-count" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: uint +} + +interface FuelValueItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: "fuel-value" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface FuelAccelerationMultiplierItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: "fuel-acceleration-multiplier" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface FuelTopSpeedMultiplierItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: "fuel-top-speed-multiplier" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface FuelEmissionsMultiplierItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: "fuel-emissions-multiplier" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface OtherItemPrototypeFilter extends BaseItemPrototypeFilter { + readonly filter: + | "tool" + | "mergeable" + | "item-with-inventory" + | "selection-tool" + | "item-with-label" + | "has-rocket-launch-products" + | "fuel" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#ItemPrototypeFilter View documentation} + */ +type ItemPrototypeFilter = + | PlaceResultItemPrototypeFilter + | BurntResultItemPrototypeFilter + | PlaceAsTileItemPrototypeFilter + | PlacedAsEquipmentResultItemPrototypeFilter + | NameItemPrototypeFilter + | TypeItemPrototypeFilter + | FlagItemPrototypeFilter + | SubgroupItemPrototypeFilter + | FuelCategoryItemPrototypeFilter + | StackSizeItemPrototypeFilter + | DefaultRequestAmountItemPrototypeFilter + | WireCountItemPrototypeFilter + | FuelValueItemPrototypeFilter + | FuelAccelerationMultiplierItemPrototypeFilter + | FuelTopSpeedMultiplierItemPrototypeFilter + | FuelEmissionsMultiplierItemPrototypeFilter + | OtherItemPrototypeFilter + +interface BaseModSettingPrototypeFilter { + /** The condition to filter on. One of `"type"`, `"mod"`, `"setting-type"` */ + readonly filter: "type" | "mod" | "setting-type" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypeModSettingPrototypeFilter extends BaseModSettingPrototypeFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface ModModSettingPrototypeFilter extends BaseModSettingPrototypeFilter { + readonly filter: "mod" + /** The mod name */ + readonly mod: string +} + +interface SettingTypeModSettingPrototypeFilter extends BaseModSettingPrototypeFilter { + readonly filter: "setting-type" + /** The setting scope type (startup, runtime-global, or runtime-per-user) */ + readonly type: string +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#ModSettingPrototypeFilter View documentation} + */ +type ModSettingPrototypeFilter = + | TypeModSettingPrototypeFilter + | ModModSettingPrototypeFilter + | SettingTypeModSettingPrototypeFilter + +interface BaseTechnologyPrototypeFilter { + /** + * The condition to filter on. One of `"enabled"`, `"hidden"`, `"upgrade"`, `"visible-when-disabled"`, + * `"has-effects"`, `"has-prerequisites"`, `"research-unit-ingredient"`, `"level"`, `"max-level"`, `"time"` + */ + readonly filter: + | "enabled" + | "hidden" + | "upgrade" + | "visible-when-disabled" + | "has-effects" + | "has-prerequisites" + | "research-unit-ingredient" + | "level" + | "max-level" + | "time" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface ResearchUnitIngredientTechnologyPrototypeFilter extends BaseTechnologyPrototypeFilter { + readonly filter: "research-unit-ingredient" + /** The research ingredient to check. */ + readonly ingredient: string +} + +interface LevelTechnologyPrototypeFilter extends BaseTechnologyPrototypeFilter { + readonly filter: "level" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: uint +} + +interface MaxLevelTechnologyPrototypeFilter extends BaseTechnologyPrototypeFilter { + readonly filter: "max-level" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: uint +} + +interface TimeTechnologyPrototypeFilter extends BaseTechnologyPrototypeFilter { + readonly filter: "time" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: uint +} + +interface OtherTechnologyPrototypeFilter extends BaseTechnologyPrototypeFilter { + readonly filter: "enabled" | "hidden" | "upgrade" | "visible-when-disabled" | "has-effects" | "has-prerequisites" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#TechnologyPrototypeFilter View documentation} + */ +type TechnologyPrototypeFilter = + | ResearchUnitIngredientTechnologyPrototypeFilter + | LevelTechnologyPrototypeFilter + | MaxLevelTechnologyPrototypeFilter + | TimeTechnologyPrototypeFilter + | OtherTechnologyPrototypeFilter + +interface BaseDecorativePrototypeFilter { + /** The condition to filter on. One of `"decal"`, `"autoplace"`, `"collision-mask"` */ + readonly filter: "decal" | "autoplace" | "collision-mask" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface CollisionMaskDecorativePrototypeFilter extends BaseDecorativePrototypeFilter { + readonly filter: "collision-mask" + readonly mask: CollisionMask | CollisionMaskWithFlags + /** How to filter: `"collides"` or `"layers-equals"` */ + readonly mask_mode: "collides" | "layers-equals" +} + +interface OtherDecorativePrototypeFilter extends BaseDecorativePrototypeFilter { + readonly filter: "decal" | "autoplace" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#DecorativePrototypeFilter View documentation} + */ +type DecorativePrototypeFilter = CollisionMaskDecorativePrototypeFilter | OtherDecorativePrototypeFilter + +interface BaseAchievementPrototypeFilter { + /** The condition to filter on. One of `"allowed-without-fight"`, `"type"` */ + readonly filter: "allowed-without-fight" | "type" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypeAchievementPrototypeFilter extends BaseAchievementPrototypeFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface OtherAchievementPrototypeFilter extends BaseAchievementPrototypeFilter { + readonly filter: "allowed-without-fight" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#AchievementPrototypeFilter View documentation} + */ +type AchievementPrototypeFilter = TypeAchievementPrototypeFilter | OtherAchievementPrototypeFilter + +interface BaseFluidPrototypeFilter { + /** + * The condition to filter on. One of `"hidden"`, `"name"`, `"subgroup"`, `"default-temperature"`, + * `"max-temperature"`, `"heat-capacity"`, `"fuel-value"`, `"emissions-multiplier"`, `"gas-temperature"` + */ + readonly filter: + | "hidden" + | "name" + | "subgroup" + | "default-temperature" + | "max-temperature" + | "heat-capacity" + | "fuel-value" + | "emissions-multiplier" + | "gas-temperature" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +/** + * For use within nested filters such as the `has-product-fluid` filter of array[{@link RecipePrototypeFilter}]. To get a + * specific prototype by name, see {@link LuaGameScript.fluid_prototypes LuaGameScript::fluid_prototypes}. + */ +interface NameFluidPrototypeFilter extends BaseFluidPrototypeFilter { + readonly filter: "name" + /** The prototype name, or list of acceptable names. */ + readonly name: string | string[] +} + +interface SubgroupFluidPrototypeFilter extends BaseFluidPrototypeFilter { + readonly filter: "subgroup" + /** A {@link LuaGroup} (subgroup) name */ + readonly subgroup: string +} + +interface DefaultTemperatureFluidPrototypeFilter extends BaseFluidPrototypeFilter { + readonly filter: "default-temperature" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface MaxTemperatureFluidPrototypeFilter extends BaseFluidPrototypeFilter { + readonly filter: "max-temperature" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface HeatCapacityFluidPrototypeFilter extends BaseFluidPrototypeFilter { + readonly filter: "heat-capacity" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface FuelValueFluidPrototypeFilter extends BaseFluidPrototypeFilter { + readonly filter: "fuel-value" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface EmissionsMultiplierFluidPrototypeFilter extends BaseFluidPrototypeFilter { + readonly filter: "emissions-multiplier" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface GasTemperatureFluidPrototypeFilter extends BaseFluidPrototypeFilter { + readonly filter: "gas-temperature" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface OtherFluidPrototypeFilter extends BaseFluidPrototypeFilter { + readonly filter: "hidden" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#FluidPrototypeFilter View documentation} + */ +type FluidPrototypeFilter = + | NameFluidPrototypeFilter + | SubgroupFluidPrototypeFilter + | DefaultTemperatureFluidPrototypeFilter + | MaxTemperatureFluidPrototypeFilter + | HeatCapacityFluidPrototypeFilter + | FuelValueFluidPrototypeFilter + | EmissionsMultiplierFluidPrototypeFilter + | GasTemperatureFluidPrototypeFilter + | OtherFluidPrototypeFilter + +interface BaseEquipmentPrototypeFilter { + /** The condition to filter on. One of `"item-to-place"`, `"type"` */ + readonly filter: "item-to-place" | "type" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypeEquipmentPrototypeFilter extends BaseEquipmentPrototypeFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface OtherEquipmentPrototypeFilter extends BaseEquipmentPrototypeFilter { + readonly filter: "item-to-place" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#EquipmentPrototypeFilter View documentation} + */ +type EquipmentPrototypeFilter = TypeEquipmentPrototypeFilter | OtherEquipmentPrototypeFilter + +interface BaseTilePrototypeFilter { + /** + * The condition to filter on. One of `"minable"`, `"autoplace"`, `"blueprintable"`, `"item-to-place"`, + * `"collision-mask"`, `"walking-speed-modifier"`, `"vehicle-friction-modifier"`, + * `"decorative-removal-probability"`, `"emissions"` + */ + readonly filter: + | "minable" + | "autoplace" + | "blueprintable" + | "item-to-place" + | "collision-mask" + | "walking-speed-modifier" + | "vehicle-friction-modifier" + | "decorative-removal-probability" + | "emissions" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface CollisionMaskTilePrototypeFilter extends BaseTilePrototypeFilter { + readonly filter: "collision-mask" + readonly mask: CollisionMask | CollisionMaskWithFlags + /** How to filter: `"collides"` or `"layers-equals"` */ + readonly mask_mode: "collides" | "layers-equals" +} + +interface WalkingSpeedModifierTilePrototypeFilter extends BaseTilePrototypeFilter { + readonly filter: "walking-speed-modifier" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface VehicleFrictionModifierTilePrototypeFilter extends BaseTilePrototypeFilter { + readonly filter: "vehicle-friction-modifier" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface DecorativeRemovalProbabilityTilePrototypeFilter extends BaseTilePrototypeFilter { + readonly filter: "decorative-removal-probability" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: float +} + +interface EmissionsTilePrototypeFilter extends BaseTilePrototypeFilter { + readonly filter: "emissions" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface OtherTilePrototypeFilter extends BaseTilePrototypeFilter { + readonly filter: "minable" | "autoplace" | "blueprintable" | "item-to-place" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#TilePrototypeFilter View documentation} + */ +type TilePrototypeFilter = + | CollisionMaskTilePrototypeFilter + | WalkingSpeedModifierTilePrototypeFilter + | VehicleFrictionModifierTilePrototypeFilter + | DecorativeRemovalProbabilityTilePrototypeFilter + | EmissionsTilePrototypeFilter + | OtherTilePrototypeFilter + +interface BaseRecipePrototypeFilter { + /** + * The condition to filter on. One of `"enabled"`, `"hidden"`, `"hidden-from-flow-stats"`, + * `"hidden-from-player-crafting"`, `"allow-as-intermediate"`, `"allow-intermediates"`, `"allow-decomposition"`, + * `"always-show-made-in"`, `"always-show-products"`, `"show-amount-in-title"`, `"has-ingredients"`, + * `"has-products"`, `"has-ingredient-item"`, `"has-ingredient-fluid"`, `"has-product-item"`, `"has-product-fluid"`, + * `"subgroup"`, `"category"`, `"energy"`, `"emissions-multiplier"`, `"request-paste-multiplier"`, `"overload-multiplier"` + */ + readonly filter: + | "enabled" + | "hidden" + | "hidden-from-flow-stats" + | "hidden-from-player-crafting" + | "allow-as-intermediate" + | "allow-intermediates" + | "allow-decomposition" + | "always-show-made-in" + | "always-show-products" + | "show-amount-in-title" + | "has-ingredients" + | "has-products" + | "has-ingredient-item" + | "has-ingredient-fluid" + | "has-product-item" + | "has-product-fluid" + | "subgroup" + | "category" + | "energy" + | "emissions-multiplier" + | "request-paste-multiplier" + | "overload-multiplier" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface HasIngredientItemRecipePrototypeFilter extends BaseRecipePrototypeFilter { + readonly filter: "has-ingredient-item" + /** Matches if at least 1 ingredient is an item that matches these filters. */ + readonly elem_filters?: ItemPrototypeFilter[] +} + +/** + * Usage example: + * + * ```lua + * -- selects recipes that consume sulfuric acid + * {{filter = "has-ingredient-fluid", elem_filters = {{filter = "name", name = "sulfuric-acid"}}}} + * ``` + */ +interface HasIngredientFluidRecipePrototypeFilter extends BaseRecipePrototypeFilter { + readonly filter: "has-ingredient-fluid" + /** Matches if at least 1 ingredient is a fluid that matches these filters. */ + readonly elem_filters?: FluidPrototypeFilter[] +} + +/** + * Usage example: + * + * ```lua + * -- selects recipes that produce an item + * {{filter = "has-product-item"}} + * -- selects recipes that produce iron plates + * {{filter = "has-product-item", elem_filters = {{filter = "name", name = "iron-plate"}}}} + * -- selects recipes that produce items that place furnaces + * {{filter = "has-product-item", elem_filters = {{filter = "place-result", elem_filters = {{filter = "type", type = "furnace"}}}}}} + * ``` + */ +interface HasProductItemRecipePrototypeFilter extends BaseRecipePrototypeFilter { + readonly filter: "has-product-item" + /** Matches if at least 1 product is an item that matches these filters. */ + readonly elem_filters?: ItemPrototypeFilter[] +} + +interface HasProductFluidRecipePrototypeFilter extends BaseRecipePrototypeFilter { + readonly filter: "has-product-fluid" + /** Matches if at least 1 product is a fluid that matches these filters. */ + readonly elem_filters?: FluidPrototypeFilter[] +} + +interface SubgroupRecipePrototypeFilter extends BaseRecipePrototypeFilter { + readonly filter: "subgroup" + /** A {@link LuaGroup} (subgroup) name */ + readonly subgroup: string +} + +interface CategoryRecipePrototypeFilter extends BaseRecipePrototypeFilter { + readonly filter: "category" + /** A {@link LuaRecipeCategoryPrototype} name */ + readonly category: string +} + +interface EnergyRecipePrototypeFilter extends BaseRecipePrototypeFilter { + readonly filter: "energy" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface EmissionsMultiplierRecipePrototypeFilter extends BaseRecipePrototypeFilter { + readonly filter: "emissions-multiplier" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface RequestPasteMultiplierRecipePrototypeFilter extends BaseRecipePrototypeFilter { + readonly filter: "request-paste-multiplier" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: uint +} + +interface OverloadMultiplierRecipePrototypeFilter extends BaseRecipePrototypeFilter { + readonly filter: "overload-multiplier" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: uint +} + +interface OtherRecipePrototypeFilter extends BaseRecipePrototypeFilter { + readonly filter: + | "enabled" + | "hidden" + | "hidden-from-flow-stats" + | "hidden-from-player-crafting" + | "allow-as-intermediate" + | "allow-intermediates" + | "allow-decomposition" + | "always-show-made-in" + | "always-show-products" + | "show-amount-in-title" + | "has-ingredients" + | "has-products" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#RecipePrototypeFilter View documentation} + */ +type RecipePrototypeFilter = + | HasIngredientItemRecipePrototypeFilter + | HasIngredientFluidRecipePrototypeFilter + | HasProductItemRecipePrototypeFilter + | HasProductFluidRecipePrototypeFilter + | SubgroupRecipePrototypeFilter + | CategoryRecipePrototypeFilter + | EnergyRecipePrototypeFilter + | EmissionsMultiplierRecipePrototypeFilter + | RequestPasteMultiplierRecipePrototypeFilter + | OverloadMultiplierRecipePrototypeFilter + | OtherRecipePrototypeFilter + +interface BaseEntityPrototypeFilter { + /** + * The condition to filter on. One of `"flying-robot"`, `"robot-with-logistics-interface"`, `"rail"`, `"ghost"`, + * `"explosion"`, `"vehicle"`, `"crafting-machine"`, `"rolling-stock"`, `"turret"`, `"transport-belt-connectable"`, + * `"wall-connectable"`, `"buildable"`, `"placable-in-editor"`, `"clonable"`, `"selectable"`, `"hidden"`, + * `"entity-with-health"`, `"building"`, `"fast-replaceable"`, `"uses-direction"`, `"minable"`, + * `"circuit-connectable"`, `"autoplace"`, `"blueprintable"`, `"item-to-place"`, `"name"`, `"type"`, + * `"collision-mask"`, `"flag"`, `"build-base-evolution-requirement"`, `"selection-priority"`, `"emissions"`, + * `"crafting-category"` + */ + readonly filter: + | "flying-robot" + | "robot-with-logistics-interface" + | "rail" + | "ghost" + | "explosion" + | "vehicle" + | "crafting-machine" + | "rolling-stock" + | "turret" + | "transport-belt-connectable" + | "wall-connectable" + | "buildable" + | "placable-in-editor" + | "clonable" + | "selectable" + | "hidden" + | "entity-with-health" + | "building" + | "fast-replaceable" + | "uses-direction" + | "minable" + | "circuit-connectable" + | "autoplace" + | "blueprintable" + | "item-to-place" + | "name" + | "type" + | "collision-mask" + | "flag" + | "build-base-evolution-requirement" + | "selection-priority" + | "emissions" + | "crafting-category" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +/** + * For use within nested filters such as the `place-result` filter of array[{@link ItemPrototypeFilter}]. To get a + * specific prototype by name, see {@link LuaGameScript.entity_prototypes LuaGameScript::entity_prototypes}. + */ +interface NameEntityPrototypeFilter extends BaseEntityPrototypeFilter { + readonly filter: "name" + /** The prototype name, or list of acceptable names. */ + readonly name: string | string[] +} + +/** + * Usage example: + * + * ```lua + * game.get_filtered_entity_prototypes({{filter = "type", type = "unit"}}) + * ``` + */ +interface TypeEntityPrototypeFilter extends BaseEntityPrototypeFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +/** + * Usage example: + * + * ```lua + * game.get_filtered_entity_prototypes({{filter = "collision-mask", mask = "player-layer", mask_mode = "collides"}}) + * ``` + */ +interface CollisionMaskEntityPrototypeFilter extends BaseEntityPrototypeFilter { + readonly filter: "collision-mask" + readonly mask: CollisionMask | CollisionMaskWithFlags + /** How to filter: `"collides"` or `"layers-equals"` */ + readonly mask_mode: "collides" | "layers-equals" +} + +/** + * Usage example: + * + * ```lua + * game.get_filtered_entity_prototypes({{filter = "flag", flag = "placeable-player"}, {filter = "flag", flag = "placeable-enemy", mode = "and"}}) + * ``` + */ +interface FlagEntityPrototypeFilter extends BaseEntityPrototypeFilter { + readonly filter: "flag" + /** One of the values in {@link EntityPrototypeFlags}. */ + readonly flag: string +} + +interface BuildBaseEvolutionRequirementEntityPrototypeFilter extends BaseEntityPrototypeFilter { + readonly filter: "build-base-evolution-requirement" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface SelectionPriorityEntityPrototypeFilter extends BaseEntityPrototypeFilter { + readonly filter: "selection-priority" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: uint8 +} + +interface EmissionsEntityPrototypeFilter extends BaseEntityPrototypeFilter { + readonly filter: "emissions" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: double +} + +interface CraftingCategoryEntityPrototypeFilter extends BaseEntityPrototypeFilter { + readonly filter: "crafting-category" + /** Matches if the prototype is for a crafting machine with this crafting category. */ + readonly crafting_category: string +} + +interface OtherEntityPrototypeFilter extends BaseEntityPrototypeFilter { + readonly filter: + | "flying-robot" + | "robot-with-logistics-interface" + | "rail" + | "ghost" + | "explosion" + | "vehicle" + | "crafting-machine" + | "rolling-stock" + | "turret" + | "transport-belt-connectable" + | "wall-connectable" + | "buildable" + | "placable-in-editor" + | "clonable" + | "selectable" + | "hidden" + | "entity-with-health" + | "building" + | "fast-replaceable" + | "uses-direction" + | "minable" + | "circuit-connectable" + | "autoplace" + | "blueprintable" + | "item-to-place" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#EntityPrototypeFilter View documentation} + */ +type EntityPrototypeFilter = + | NameEntityPrototypeFilter + | TypeEntityPrototypeFilter + | CollisionMaskEntityPrototypeFilter + | FlagEntityPrototypeFilter + | BuildBaseEvolutionRequirementEntityPrototypeFilter + | SelectionPriorityEntityPrototypeFilter + | EmissionsEntityPrototypeFilter + | CraftingCategoryEntityPrototypeFilter + | OtherEntityPrototypeFilter + +interface BaseScriptRaisedReviveEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypeScriptRaisedReviveEventFilter extends BaseScriptRaisedReviveEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NameScriptRaisedReviveEventFilter extends BaseScriptRaisedReviveEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypeScriptRaisedReviveEventFilter extends BaseScriptRaisedReviveEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNameScriptRaisedReviveEventFilter extends BaseScriptRaisedReviveEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OtherScriptRaisedReviveEventFilter extends BaseScriptRaisedReviveEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaScriptRaisedReviveEventFilter View documentation} + */ +type LuaScriptRaisedReviveEventFilter = + | TypeScriptRaisedReviveEventFilter + | NameScriptRaisedReviveEventFilter + | GhostTypeScriptRaisedReviveEventFilter + | GhostNameScriptRaisedReviveEventFilter + | OtherScriptRaisedReviveEventFilter + +interface BaseEntityDiedEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypeEntityDiedEventFilter extends BaseEntityDiedEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NameEntityDiedEventFilter extends BaseEntityDiedEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypeEntityDiedEventFilter extends BaseEntityDiedEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNameEntityDiedEventFilter extends BaseEntityDiedEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OtherEntityDiedEventFilter extends BaseEntityDiedEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaEntityDiedEventFilter View documentation} + */ +type LuaEntityDiedEventFilter = + | TypeEntityDiedEventFilter + | NameEntityDiedEventFilter + | GhostTypeEntityDiedEventFilter + | GhostNameEntityDiedEventFilter + | OtherEntityDiedEventFilter + +interface BaseEntityMarkedForDeconstructionEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypeEntityMarkedForDeconstructionEventFilter extends BaseEntityMarkedForDeconstructionEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NameEntityMarkedForDeconstructionEventFilter extends BaseEntityMarkedForDeconstructionEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypeEntityMarkedForDeconstructionEventFilter extends BaseEntityMarkedForDeconstructionEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNameEntityMarkedForDeconstructionEventFilter extends BaseEntityMarkedForDeconstructionEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OtherEntityMarkedForDeconstructionEventFilter extends BaseEntityMarkedForDeconstructionEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaEntityMarkedForDeconstructionEventFilter View documentation} + */ +type LuaEntityMarkedForDeconstructionEventFilter = + | TypeEntityMarkedForDeconstructionEventFilter + | NameEntityMarkedForDeconstructionEventFilter + | GhostTypeEntityMarkedForDeconstructionEventFilter + | GhostNameEntityMarkedForDeconstructionEventFilter + | OtherEntityMarkedForDeconstructionEventFilter + +interface BasePreGhostDeconstructedEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypePreGhostDeconstructedEventFilter extends BasePreGhostDeconstructedEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NamePreGhostDeconstructedEventFilter extends BasePreGhostDeconstructedEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypePreGhostDeconstructedEventFilter extends BasePreGhostDeconstructedEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNamePreGhostDeconstructedEventFilter extends BasePreGhostDeconstructedEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OtherPreGhostDeconstructedEventFilter extends BasePreGhostDeconstructedEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaPreGhostDeconstructedEventFilter View documentation} + */ +type LuaPreGhostDeconstructedEventFilter = + | TypePreGhostDeconstructedEventFilter + | NamePreGhostDeconstructedEventFilter + | GhostTypePreGhostDeconstructedEventFilter + | GhostNamePreGhostDeconstructedEventFilter + | OtherPreGhostDeconstructedEventFilter + +interface BaseScriptRaisedDestroyEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypeScriptRaisedDestroyEventFilter extends BaseScriptRaisedDestroyEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NameScriptRaisedDestroyEventFilter extends BaseScriptRaisedDestroyEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypeScriptRaisedDestroyEventFilter extends BaseScriptRaisedDestroyEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNameScriptRaisedDestroyEventFilter extends BaseScriptRaisedDestroyEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OtherScriptRaisedDestroyEventFilter extends BaseScriptRaisedDestroyEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaScriptRaisedDestroyEventFilter View documentation} + */ +type LuaScriptRaisedDestroyEventFilter = + | TypeScriptRaisedDestroyEventFilter + | NameScriptRaisedDestroyEventFilter + | GhostTypeScriptRaisedDestroyEventFilter + | GhostNameScriptRaisedDestroyEventFilter + | OtherScriptRaisedDestroyEventFilter + +interface BaseUpgradeCancelledEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypeUpgradeCancelledEventFilter extends BaseUpgradeCancelledEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NameUpgradeCancelledEventFilter extends BaseUpgradeCancelledEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypeUpgradeCancelledEventFilter extends BaseUpgradeCancelledEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNameUpgradeCancelledEventFilter extends BaseUpgradeCancelledEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OtherUpgradeCancelledEventFilter extends BaseUpgradeCancelledEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaUpgradeCancelledEventFilter View documentation} + */ +type LuaUpgradeCancelledEventFilter = + | TypeUpgradeCancelledEventFilter + | NameUpgradeCancelledEventFilter + | GhostTypeUpgradeCancelledEventFilter + | GhostNameUpgradeCancelledEventFilter + | OtherUpgradeCancelledEventFilter + +interface BasePlayerRepairedEntityEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypePlayerRepairedEntityEventFilter extends BasePlayerRepairedEntityEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NamePlayerRepairedEntityEventFilter extends BasePlayerRepairedEntityEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypePlayerRepairedEntityEventFilter extends BasePlayerRepairedEntityEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNamePlayerRepairedEntityEventFilter extends BasePlayerRepairedEntityEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OtherPlayerRepairedEntityEventFilter extends BasePlayerRepairedEntityEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaPlayerRepairedEntityEventFilter View documentation} + */ +type LuaPlayerRepairedEntityEventFilter = + | TypePlayerRepairedEntityEventFilter + | NamePlayerRepairedEntityEventFilter + | GhostTypePlayerRepairedEntityEventFilter + | GhostNamePlayerRepairedEntityEventFilter + | OtherPlayerRepairedEntityEventFilter + +interface BaseEntityMarkedForUpgradeEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypeEntityMarkedForUpgradeEventFilter extends BaseEntityMarkedForUpgradeEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NameEntityMarkedForUpgradeEventFilter extends BaseEntityMarkedForUpgradeEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypeEntityMarkedForUpgradeEventFilter extends BaseEntityMarkedForUpgradeEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNameEntityMarkedForUpgradeEventFilter extends BaseEntityMarkedForUpgradeEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OtherEntityMarkedForUpgradeEventFilter extends BaseEntityMarkedForUpgradeEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaEntityMarkedForUpgradeEventFilter View documentation} + */ +type LuaEntityMarkedForUpgradeEventFilter = + | TypeEntityMarkedForUpgradeEventFilter + | NameEntityMarkedForUpgradeEventFilter + | GhostTypeEntityMarkedForUpgradeEventFilter + | GhostNameEntityMarkedForUpgradeEventFilter + | OtherEntityMarkedForUpgradeEventFilter + +interface BasePostEntityDiedEventFilter { + /** The condition to filter on. One of `"type"` */ + readonly filter: "type" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypePostEntityDiedEventFilter extends BasePostEntityDiedEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaPostEntityDiedEventFilter View documentation} + */ +type LuaPostEntityDiedEventFilter = TypePostEntityDiedEventFilter + +interface BasePreRobotMinedEntityEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypePreRobotMinedEntityEventFilter extends BasePreRobotMinedEntityEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NamePreRobotMinedEntityEventFilter extends BasePreRobotMinedEntityEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypePreRobotMinedEntityEventFilter extends BasePreRobotMinedEntityEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNamePreRobotMinedEntityEventFilter extends BasePreRobotMinedEntityEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OtherPreRobotMinedEntityEventFilter extends BasePreRobotMinedEntityEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaPreRobotMinedEntityEventFilter View documentation} + */ +type LuaPreRobotMinedEntityEventFilter = + | TypePreRobotMinedEntityEventFilter + | NamePreRobotMinedEntityEventFilter + | GhostTypePreRobotMinedEntityEventFilter + | GhostNamePreRobotMinedEntityEventFilter + | OtherPreRobotMinedEntityEventFilter + +interface BaseEntityClonedEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypeEntityClonedEventFilter extends BaseEntityClonedEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NameEntityClonedEventFilter extends BaseEntityClonedEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypeEntityClonedEventFilter extends BaseEntityClonedEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNameEntityClonedEventFilter extends BaseEntityClonedEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OtherEntityClonedEventFilter extends BaseEntityClonedEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaEntityClonedEventFilter View documentation} + */ +type LuaEntityClonedEventFilter = + | TypeEntityClonedEventFilter + | NameEntityClonedEventFilter + | GhostTypeEntityClonedEventFilter + | GhostNameEntityClonedEventFilter + | OtherEntityClonedEventFilter + +interface BaseScriptRaisedBuiltEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypeScriptRaisedBuiltEventFilter extends BaseScriptRaisedBuiltEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NameScriptRaisedBuiltEventFilter extends BaseScriptRaisedBuiltEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypeScriptRaisedBuiltEventFilter extends BaseScriptRaisedBuiltEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNameScriptRaisedBuiltEventFilter extends BaseScriptRaisedBuiltEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OtherScriptRaisedBuiltEventFilter extends BaseScriptRaisedBuiltEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaScriptRaisedBuiltEventFilter View documentation} + */ +type LuaScriptRaisedBuiltEventFilter = + | TypeScriptRaisedBuiltEventFilter + | NameScriptRaisedBuiltEventFilter + | GhostTypeScriptRaisedBuiltEventFilter + | GhostNameScriptRaisedBuiltEventFilter + | OtherScriptRaisedBuiltEventFilter + +interface BaseRobotMinedEntityEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypeRobotMinedEntityEventFilter extends BaseRobotMinedEntityEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NameRobotMinedEntityEventFilter extends BaseRobotMinedEntityEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypeRobotMinedEntityEventFilter extends BaseRobotMinedEntityEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNameRobotMinedEntityEventFilter extends BaseRobotMinedEntityEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OtherRobotMinedEntityEventFilter extends BaseRobotMinedEntityEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaRobotMinedEntityEventFilter View documentation} + */ +type LuaRobotMinedEntityEventFilter = + | TypeRobotMinedEntityEventFilter + | NameRobotMinedEntityEventFilter + | GhostTypeRobotMinedEntityEventFilter + | GhostNameRobotMinedEntityEventFilter + | OtherRobotMinedEntityEventFilter + +interface BasePrePlayerMinedEntityEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypePrePlayerMinedEntityEventFilter extends BasePrePlayerMinedEntityEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NamePrePlayerMinedEntityEventFilter extends BasePrePlayerMinedEntityEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypePrePlayerMinedEntityEventFilter extends BasePrePlayerMinedEntityEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNamePrePlayerMinedEntityEventFilter extends BasePrePlayerMinedEntityEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OtherPrePlayerMinedEntityEventFilter extends BasePrePlayerMinedEntityEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaPrePlayerMinedEntityEventFilter View documentation} + */ +type LuaPrePlayerMinedEntityEventFilter = + | TypePrePlayerMinedEntityEventFilter + | NamePrePlayerMinedEntityEventFilter + | GhostTypePrePlayerMinedEntityEventFilter + | GhostNamePrePlayerMinedEntityEventFilter + | OtherPrePlayerMinedEntityEventFilter + +interface BaseRobotBuiltEntityEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, + * `"ghost_name"`, `"force"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + | "force" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypeRobotBuiltEntityEventFilter extends BaseRobotBuiltEntityEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NameRobotBuiltEntityEventFilter extends BaseRobotBuiltEntityEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypeRobotBuiltEntityEventFilter extends BaseRobotBuiltEntityEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNameRobotBuiltEntityEventFilter extends BaseRobotBuiltEntityEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface ForceRobotBuiltEntityEventFilter extends BaseRobotBuiltEntityEventFilter { + readonly filter: "force" + /** The entity force */ + readonly force: string +} + +interface OtherRobotBuiltEntityEventFilter extends BaseRobotBuiltEntityEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaRobotBuiltEntityEventFilter View documentation} + */ +type LuaRobotBuiltEntityEventFilter = + | TypeRobotBuiltEntityEventFilter + | NameRobotBuiltEntityEventFilter + | GhostTypeRobotBuiltEntityEventFilter + | GhostNameRobotBuiltEntityEventFilter + | ForceRobotBuiltEntityEventFilter + | OtherRobotBuiltEntityEventFilter + +interface BaseEntityDeconstructionCancelledEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypeEntityDeconstructionCancelledEventFilter extends BaseEntityDeconstructionCancelledEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NameEntityDeconstructionCancelledEventFilter extends BaseEntityDeconstructionCancelledEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypeEntityDeconstructionCancelledEventFilter extends BaseEntityDeconstructionCancelledEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNameEntityDeconstructionCancelledEventFilter extends BaseEntityDeconstructionCancelledEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OtherEntityDeconstructionCancelledEventFilter extends BaseEntityDeconstructionCancelledEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaEntityDeconstructionCancelledEventFilter View documentation} + */ +type LuaEntityDeconstructionCancelledEventFilter = + | TypeEntityDeconstructionCancelledEventFilter + | NameEntityDeconstructionCancelledEventFilter + | GhostTypeEntityDeconstructionCancelledEventFilter + | GhostNameEntityDeconstructionCancelledEventFilter + | OtherEntityDeconstructionCancelledEventFilter + +interface BasePlayerBuiltEntityEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, + * `"ghost_name"`, `"force"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + | "force" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypePlayerBuiltEntityEventFilter extends BasePlayerBuiltEntityEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NamePlayerBuiltEntityEventFilter extends BasePlayerBuiltEntityEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypePlayerBuiltEntityEventFilter extends BasePlayerBuiltEntityEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNamePlayerBuiltEntityEventFilter extends BasePlayerBuiltEntityEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface ForcePlayerBuiltEntityEventFilter extends BasePlayerBuiltEntityEventFilter { + readonly filter: "force" + /** The entity force */ + readonly force: string +} + +interface OtherPlayerBuiltEntityEventFilter extends BasePlayerBuiltEntityEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaPlayerBuiltEntityEventFilter View documentation} + */ +type LuaPlayerBuiltEntityEventFilter = + | TypePlayerBuiltEntityEventFilter + | NamePlayerBuiltEntityEventFilter + | GhostTypePlayerBuiltEntityEventFilter + | GhostNamePlayerBuiltEntityEventFilter + | ForcePlayerBuiltEntityEventFilter + | OtherPlayerBuiltEntityEventFilter + +interface BasePlayerMinedEntityEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypePlayerMinedEntityEventFilter extends BasePlayerMinedEntityEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NamePlayerMinedEntityEventFilter extends BasePlayerMinedEntityEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypePlayerMinedEntityEventFilter extends BasePlayerMinedEntityEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNamePlayerMinedEntityEventFilter extends BasePlayerMinedEntityEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OtherPlayerMinedEntityEventFilter extends BasePlayerMinedEntityEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaPlayerMinedEntityEventFilter View documentation} + */ +type LuaPlayerMinedEntityEventFilter = + | TypePlayerMinedEntityEventFilter + | NamePlayerMinedEntityEventFilter + | GhostTypePlayerMinedEntityEventFilter + | GhostNamePlayerMinedEntityEventFilter + | OtherPlayerMinedEntityEventFilter + +interface BaseEntityDamagedEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, + * `"ghost_name"`, `"original-damage-amount"`, `"final-damage-amount"`, `"damage-type"`, `"final-health"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + | "original-damage-amount" + | "final-damage-amount" + | "damage-type" + | "final-health" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypeEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NameEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypeEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNameEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OriginalDamageAmountEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { + readonly filter: "original-damage-amount" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: float +} + +interface FinalDamageAmountEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { + readonly filter: "final-damage-amount" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: float +} + +interface DamageTypeEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { + readonly filter: "damage-type" + /** A {@link LuaDamagePrototype} name */ + readonly type: string +} + +interface FinalHealthEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { + readonly filter: "final-health" + readonly comparison: ComparatorString + /** The value to compare against. */ + readonly value: float +} + +interface OtherEntityDamagedEventFilter extends BaseEntityDamagedEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaEntityDamagedEventFilter View documentation} + */ +type LuaEntityDamagedEventFilter = + | TypeEntityDamagedEventFilter + | NameEntityDamagedEventFilter + | GhostTypeEntityDamagedEventFilter + | GhostNameEntityDamagedEventFilter + | OriginalDamageAmountEntityDamagedEventFilter + | FinalDamageAmountEntityDamagedEventFilter + | DamageTypeEntityDamagedEventFilter + | FinalHealthEntityDamagedEventFilter + | OtherEntityDamagedEventFilter + +interface BaseSectorScannedEventFilter { + /** + * The condition to filter on. One of `"ghost"`, `"rail"`, `"rail-signal"`, `"rolling-stock"`, + * `"robot-with-logistics-interface"`, `"vehicle"`, `"turret"`, `"crafting-machine"`, `"wall-connectable"`, + * `"transport-belt-connectable"`, `"circuit-network-connectable"`, `"type"`, `"name"`, `"ghost_type"`, `"ghost_name"` + */ + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" + | "type" + | "name" + | "ghost_type" + | "ghost_name" + /** + * How to combine this with the previous filter. Must be `"or"` or `"and"`. Defaults to `"or"`. When evaluating the + * filters, `"and"` has higher precedence than `"or"`. + */ + readonly mode?: "or" | "and" + /** Inverts the condition. Default is `false`. */ + readonly invert?: boolean +} + +interface TypeSectorScannedEventFilter extends BaseSectorScannedEventFilter { + readonly filter: "type" + /** The prototype type */ + readonly type: string +} + +interface NameSectorScannedEventFilter extends BaseSectorScannedEventFilter { + readonly filter: "name" + /** The prototype name */ + readonly name: string +} + +interface GhostTypeSectorScannedEventFilter extends BaseSectorScannedEventFilter { + readonly filter: "ghost_type" + /** The ghost prototype type */ + readonly type: string +} + +interface GhostNameSectorScannedEventFilter extends BaseSectorScannedEventFilter { + readonly filter: "ghost_name" + /** The ghost prototype name */ + readonly name: string +} + +interface OtherSectorScannedEventFilter extends BaseSectorScannedEventFilter { + readonly filter: + | "ghost" + | "rail" + | "rail-signal" + | "rolling-stock" + | "robot-with-logistics-interface" + | "vehicle" + | "turret" + | "crafting-machine" + | "wall-connectable" + | "transport-belt-connectable" + | "circuit-network-connectable" +} + +/** + * Other attributes may be specified depending on `filter`: + * + * {@link https://lua-api.factorio.com/next/Concepts.html#LuaSectorScannedEventFilter View documentation} + */ +type LuaSectorScannedEventFilter = + | TypeSectorScannedEventFilter + | NameSectorScannedEventFilter + | GhostTypeSectorScannedEventFilter + | GhostNameSectorScannedEventFilter + | OtherSectorScannedEventFilter + +/** + * A map gen preset. Used in {@link https://wiki.factorio.com/Prototype/MapGenPresets Prototype/MapGenPresets}. + * + * {@link https://wiki.factorio.com/Types/MapGenPreset View Documentation} + */ +interface MapGenPreset { + /** Specifies the ordering the map generator gui. */ + order: string + /** + * Whether this is the default preset. If set to boolean, this preset may not have any other properties besides this + * and order. + */ + default?: boolean + /** + * This is a table with the below key/value pairs. All key/value pairs are optional. If not set they will just use + * the default values. + */ + basic_settings: Partial + /** + * This is a table with the below key/value pairs. All key/value pairs are optional, if not set they will just use + * the existing values. + */ + readonly advanced_settings: { + readonly pollution?: { + enabled?: boolean + /** Must be <= 0.25. */ + diffusion_ratio?: double + /** Also known as dissipation rate. Must be >= 0.5. */ + ageing?: double + enemy_attack_pollution_consumption_modifier?: double + min_pollution_to_damage_trees?: double + pollution_restored_per_tree_damage?: double + } + readonly enemy_evolution?: { + enabled?: boolean + time_factor?: double + destroy_factor?: double + pollution_factor?: double + } + readonly enemy_expansion?: { + enabled?: boolean + max_expansion_distance?: double + settler_group_min_size?: double + settler_group_max_size?: double + /** In ticks. */ + min_expansion_cooldown?: double + /** In ticks. */ + max_expansion_cooldown?: double + } + readonly difficulty_settings?: { + recipe_difficulty?: defines.difficulty_settings.recipe_difficulty + technology_difficulty?: defines.difficulty_settings.technology_difficulty + technology_price_multiplier?: double + research_queue_setting?: "after-victory" | "always" | "never" + } + } +} + +interface BlueprintControlBehavior { + readonly condition?: CircuitCondition + readonly circuit_condition?: CircuitCondition + readonly filters?: Signal[] + readonly is_on?: boolean + readonly arithmetic_conditions?: ArithmeticCombinatorParameters + readonly decider_conditions?: DeciderCombinatorParameters + readonly circuit_enable_disable?: boolean + readonly circuit_read_resources?: boolean + readonly circuit_resource_read_mode?: defines.control_behavior.mining_drill.resource_read_mode + readonly read_stopped_train?: boolean + readonly train_stopped_signal?: SignalID + readonly read_from_train?: boolean + readonly send_to_train?: boolean + readonly circuit_mode_of_operation?: number + readonly circuit_read_hand_contents?: boolean + readonly circuit_hand_read_mode?: defines.control_behavior.inserter.hand_read_mode + readonly circuit_set_stack_size?: boolean + readonly stack_control_input_signal?: SignalID + readonly use_colors?: boolean + readonly read_robot_stats?: boolean + readonly read_logistics?: boolean + readonly available_logistic_output_signal?: boolean + readonly total_logistic_output_signal?: boolean + readonly available_construction_output_signal?: boolean + readonly total_construction_output_signal?: boolean + readonly circuit_contents_read_mode?: defines.control_behavior.transport_belt.content_read_mode + readonly output_signal?: SignalID + readonly circuit_close_signal?: boolean + readonly circuit_read_signal?: boolean + readonly red_output_signal?: SignalID + readonly orange_output_signal?: SignalID + readonly green_output_signal?: SignalID + readonly blue_output_signal?: SignalID + readonly circuit_open_gate?: boolean + readonly circuit_read_sensor?: boolean + readonly circuit_parameters?: ProgrammableSpeakerCircuitParameters +} diff --git a/modules/mod2/typed-factorio/generated/defines.d.ts b/modules/mod2/typed-factorio/generated/defines.d.ts new file mode 100644 index 0000000..db30ab0 --- /dev/null +++ b/modules/mod2/typed-factorio/generated/defines.d.ts @@ -0,0 +1,1642 @@ +/** @noSelfInFile */ + +declare namespace defines { + enum alert_type { + entity_destroyed, + entity_under_attack, + not_enough_construction_robots, + no_material_for_construction, + not_enough_repair_packs, + turret_fire, + custom, + no_storage, + train_out_of_fuel, + } + /** + * AI command exit status. See {@link LuaEntity.set_command LuaEntity::set_command} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.behavior_result View documentation} + */ + enum behavior_result { + in_progress, + fail, + success, + deleted, + } + enum build_check_type { + script, + manual, + manual_ghost, + script_ghost, + blueprint_ghost, + ghost_revive, + } + /** + * State of a chain signal. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.chain_signal_state View documentation} + */ + enum chain_signal_state { + none, + all_open, + partially_open, + none_open, + } + enum chunk_generated_status { + nothing, + custom_tiles, + basic_tiles, + corrected_tiles, + tiles, + entities, + } + enum circuit_condition_index { + inserter_circuit, + inserter_logistic, + lamp, + arithmetic_combinator, + decider_combinator, + constant_combinator, + offshore_pump, + pump, + } + enum circuit_connector_id { + accumulator, + constant_combinator, + container, + programmable_speaker, + rail_signal, + rail_chain_signal, + roboport, + storage_tank, + wall, + electric_pole, + inserter, + lamp, + combinator_input, + combinator_output, + offshore_pump, + pump, + } + /** + * Command given to units describing what they should do. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.command View documentation} + */ + enum command { + /** + * Attack another entity. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.command.attack View documentation} + */ + attack = 0, + /** + * Go to a specific position. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.command.go_to_location View documentation} + */ + go_to_location = 1, + /** + * Chain commands together, see {@link defines.compound_command}. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.command.compound View documentation} + */ + compound = 2, + /** + * Do what your group wants you to do. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.command.group View documentation} + */ + group = 3, + /** + * Go to a place and attack what you see. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.command.attack_area View documentation} + */ + attack_area = 4, + /** + * Chill. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.command.wander View documentation} + */ + wander = 5, + /** + * Flee from another entity. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.command.flee View documentation} + */ + flee = 6, + /** + * Stop moving and stay where you are. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.command.stop View documentation} + */ + stop = 7, + /** + * Go to a position and build a base there. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.command.build_base View documentation} + */ + build_base = 8, + } + /** + * How commands are joined together in a compound command (see {@link defines.command.compound}). + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.compound_command View documentation} + */ + enum compound_command { + /** + * Fail on first failure. Only succeeds if all commands (executed one after another) succeed. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.compound_command.logical_and View documentation} + */ + logical_and, + /** + * Succeed on first success. Only fails if all commands (executed one after another) fail. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.compound_command.logical_or View documentation} + */ + logical_or, + /** + * Execute all commands in sequence and fail or succeed depending on the return status of the last command. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.compound_command.return_last View documentation} + */ + return_last, + } + namespace control_behavior { + namespace inserter { + enum circuit_mode_of_operation { + none, + enable_disable, + set_filters, + read_hand_contents, + set_stack_size, + } + enum hand_read_mode { + hold, + pulse, + } + } + namespace logistic_container { + enum circuit_mode_of_operation { + send_contents, + set_requests, + } + } + namespace lamp { + enum circuit_mode_of_operation { + use_colors, + } + } + namespace mining_drill { + enum resource_read_mode { + this_miner, + entire_patch, + } + } + namespace transport_belt { + enum content_read_mode { + pulse, + hold, + } + } + enum type { + /** + * {@link LuaContainerControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.container View documentation} + */ + container, + /** + * {@link LuaGenericOnOffControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.generic_on_off View documentation} + */ + generic_on_off, + /** + * {@link LuaInserterControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.inserter View documentation} + */ + inserter, + /** + * {@link LuaLampControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.lamp View documentation} + */ + lamp, + /** + * {@link LuaLogisticContainerControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.logistic_container View documentation} + */ + logistic_container, + /** + * {@link LuaRoboportControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.roboport View documentation} + */ + roboport, + /** + * {@link LuaStorageTankControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.storage_tank View documentation} + */ + storage_tank, + /** + * {@link LuaTrainStopControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.train_stop View documentation} + */ + train_stop, + /** + * {@link LuaDeciderCombinatorControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.decider_combinator View documentation} + */ + decider_combinator, + /** + * {@link LuaArithmeticCombinatorControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.arithmetic_combinator View documentation} + */ + arithmetic_combinator, + /** + * {@link LuaConstantCombinatorControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.constant_combinator View documentation} + */ + constant_combinator, + /** + * {@link LuaTransportBeltControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.transport_belt View documentation} + */ + transport_belt, + /** + * {@link LuaAccumulatorControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.accumulator View documentation} + */ + accumulator, + /** + * {@link LuaRailSignalControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.rail_signal View documentation} + */ + rail_signal, + /** + * {@link LuaRailChainSignalControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.rail_chain_signal View documentation} + */ + rail_chain_signal, + /** + * {@link LuaWallControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.wall View documentation} + */ + wall, + /** + * {@link LuaMiningDrillControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.mining_drill View documentation} + */ + mining_drill, + /** + * {@link LuaProgrammableSpeakerControlBehavior} + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.control_behavior.type.programmable_speaker View documentation} + */ + programmable_speaker, + } + } + enum controllers { + /** + * Can't interact with the world, can only observe. Used in the multiplayer waiting-to-respawn screen. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.controllers.ghost View documentation} + */ + ghost, + /** + * The controller controls a character. This is the default controller in freeplay. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.controllers.character View documentation} + */ + character, + /** + * The controller isn't tied to a character. This is the default controller in sandbox. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.controllers.god View documentation} + */ + god, + /** + * The Editor Controller near ultimate power to do almost anything in the game. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.controllers.editor View documentation} + */ + editor, + /** + * The player can't interact with the world, and the camera pans around in a predefined manner. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.controllers.cutscene View documentation} + */ + cutscene, + /** + * Can't change anything in the world but can view anything. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.controllers.spectator View documentation} + */ + spectator, + } + namespace deconstruction_item { + enum entity_filter_mode { + whitelist, + blacklist, + } + enum tile_filter_mode { + whitelist, + blacklist, + } + enum tile_selection_mode { + normal, + always, + never, + only, + } + } + enum difficulty { + easy, + normal, + hard, + } + namespace difficulty_settings { + enum recipe_difficulty { + normal, + expensive, + } + enum technology_difficulty { + normal, + expensive, + } + } + enum direction { + north = 0, + northeast = 1, + east = 2, + southeast = 3, + south = 4, + southwest = 5, + west = 6, + northwest = 7, + } + enum disconnect_reason { + quit, + dropped, + reconnect, + wrong_input, + desync_limit_reached, + cannot_keep_up, + afk, + kicked, + kicked_and_deleted, + banned, + switching_servers, + } + enum distraction { + /** + * Perform command even if someone attacks the unit. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.distraction.none View documentation} + */ + none, + /** + * Attack closer enemy entities with force. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.distraction.by_enemy View documentation} + */ + by_enemy, + /** + * Attack closer enemy entities, including entities "built" by player (belts, inserters, chests). + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.distraction.by_anything View documentation} + */ + by_anything, + /** + * Attack when attacked. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.distraction.by_damage View documentation} + */ + by_damage, + } + enum entity_status { + working, + normal, + no_power, + low_power, + no_fuel, + disabled_by_control_behavior, + opened_by_circuit_network, + closed_by_circuit_network, + disabled_by_script, + marked_for_deconstruction, + /** + * Used by generators and solar panels. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.not_plugged_in_electric_network View documentation} + */ + not_plugged_in_electric_network, + /** + * Used by power switches. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.networks_connected View documentation} + */ + networks_connected, + /** + * Used by power switches. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.networks_disconnected View documentation} + */ + networks_disconnected, + /** + * Used by accumulators. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.charging View documentation} + */ + charging, + /** + * Used by accumulators. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.discharging View documentation} + */ + discharging, + /** + * Used by accumulators. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.fully_charged View documentation} + */ + fully_charged, + /** + * Used by logistic containers. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.out_of_logistic_network View documentation} + */ + out_of_logistic_network, + /** + * Used by assembling machines. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.no_recipe View documentation} + */ + no_recipe, + /** + * Used by furnaces. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.no_ingredients View documentation} + */ + no_ingredients, + /** + * Used by boilers, fluid turrets and fluid energy sources: Boiler has no fluid to work with. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.no_input_fluid View documentation} + */ + no_input_fluid, + /** + * Used by labs. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.no_research_in_progress View documentation} + */ + no_research_in_progress, + /** + * Used by mining drills. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.no_minable_resources View documentation} + */ + no_minable_resources, + /** + * Used by boilers and fluid turrets: Boiler still has some fluid but is about to run out. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.low_input_fluid View documentation} + */ + low_input_fluid, + /** + * Used by crafting machines. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.fluid_ingredient_shortage View documentation} + */ + fluid_ingredient_shortage, + /** + * Used by crafting machines, boilers, burner energy sources and reactors: Reactor/burner has full burnt result + * inventory, boiler has full output fluidbox. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.full_output View documentation} + */ + full_output, + /** + * Used by crafting machines. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.item_ingredient_shortage View documentation} + */ + item_ingredient_shortage, + /** + * Used by mining drills when the mining fluid is missing. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.missing_required_fluid View documentation} + */ + missing_required_fluid, + /** + * Used by labs. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.missing_science_packs View documentation} + */ + missing_science_packs, + /** + * Used by inserters. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.waiting_for_source_items View documentation} + */ + waiting_for_source_items, + /** + * Used by inserters and mining drills. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.waiting_for_space_in_destination View documentation} + */ + waiting_for_space_in_destination, + /** + * Used by the rocket silo. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.preparing_rocket_for_launch View documentation} + */ + preparing_rocket_for_launch, + /** + * Used by the rocket silo. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.waiting_to_launch_rocket View documentation} + */ + waiting_to_launch_rocket, + /** + * Used by the rocket silo. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.launching_rocket View documentation} + */ + launching_rocket, + /** + * Used by beacons. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.no_modules_to_transmit View documentation} + */ + no_modules_to_transmit, + /** + * Used by roboports. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.recharging_after_power_outage View documentation} + */ + recharging_after_power_outage, + /** + * Used by inserters targeting entity ghosts. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.waiting_for_target_to_be_built View documentation} + */ + waiting_for_target_to_be_built, + /** + * Used by inserters targeting rails. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.waiting_for_train View documentation} + */ + waiting_for_train, + /** + * Used by ammo turrets. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.no_ammo View documentation} + */ + no_ammo, + /** + * Used by heat energy sources. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.low_temperature View documentation} + */ + low_temperature, + /** + * Used by constant combinators: Combinator is turned off via switch in GUI. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.disabled View documentation} + */ + disabled, + /** + * Used by lamps. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.turned_off_during_daytime View documentation} + */ + turned_off_during_daytime, + /** + * Used by rail signals. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.not_connected_to_rail View documentation} + */ + not_connected_to_rail, + /** + * Used by rail signals. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.entity_status.cant_divide_segments View documentation} + */ + cant_divide_segments, + } + /** + * See the {@link https://lua-api.factorio.com/next/events.html events page} for more info on what events contain and + * when they get raised. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.events View documentation} + */ + namespace events { + /** Event type: {@link OnTickEvent} */ + const on_tick: EventId + /** Event type: {@link OnGuiClickEvent} */ + const on_gui_click: EventId + /** Event type: {@link OnGuiConfirmedEvent} */ + const on_gui_confirmed: EventId + /** Event type: {@link OnGuiTextChangedEvent} */ + const on_gui_text_changed: EventId + /** Event type: {@link OnGuiCheckedStateChangedEvent} */ + const on_gui_checked_state_changed: EventId + /** + * Event type: {@link OnEntityDiedEvent} + * + * Event filter: {@link LuaEntityDiedEventFilter} + */ + const on_entity_died: EventId + /** + * Event type: {@link OnPostEntityDiedEvent} + * + * Event filter: {@link LuaPostEntityDiedEventFilter} + */ + const on_post_entity_died: EventId + /** + * Event type: {@link OnEntityDamagedEvent} + * + * Event filter: {@link LuaEntityDamagedEventFilter} + */ + const on_entity_damaged: EventId + /** Event type: {@link OnPickedUpItemEvent} */ + const on_picked_up_item: EventId + /** + * Event type: {@link OnBuiltEntityEvent} + * + * Event filter: {@link LuaPlayerBuiltEntityEventFilter} + */ + const on_built_entity: EventId + /** + * Event type: {@link OnSectorScannedEvent} + * + * Event filter: {@link LuaSectorScannedEventFilter} + */ + const on_sector_scanned: EventId + /** Event type: {@link OnPlayerMinedItemEvent} */ + const on_player_mined_item: EventId + /** Event type: {@link OnPreBuildEvent} */ + const on_pre_build: EventId + /** Event type: {@link OnRocketLaunchedEvent} */ + const on_rocket_launched: EventId + /** + * Event type: {@link OnPrePlayerMinedItemEvent} + * + * Event filter: {@link LuaPrePlayerMinedEntityEventFilter} + */ + const on_pre_player_mined_item: EventId + /** Event type: {@link OnChunkGeneratedEvent} */ + const on_chunk_generated: EventId + /** Event type: {@link OnPlayerCraftedItemEvent} */ + const on_player_crafted_item: EventId + /** + * Event type: {@link OnRobotBuiltEntityEvent} + * + * Event filter: {@link LuaRobotBuiltEntityEventFilter} + */ + const on_robot_built_entity: EventId + /** + * Event type: {@link OnRobotPreMinedEvent} + * + * Event filter: {@link LuaPreRobotMinedEntityEventFilter} + */ + const on_robot_pre_mined: EventId + /** Event type: {@link OnRobotMinedEvent} */ + const on_robot_mined: EventId + /** Event type: {@link OnResearchStartedEvent} */ + const on_research_started: EventId + /** Event type: {@link OnResearchFinishedEvent} */ + const on_research_finished: EventId + /** Event type: {@link OnResearchReversedEvent} */ + const on_research_reversed: EventId + /** Event type: {@link OnPlayerRotatedEntityEvent} */ + const on_player_rotated_entity: EventId + /** + * Event type: {@link OnMarkedForDeconstructionEvent} + * + * Event filter: {@link LuaEntityMarkedForDeconstructionEventFilter} + */ + const on_marked_for_deconstruction: EventId< + OnMarkedForDeconstructionEvent, + LuaEntityMarkedForDeconstructionEventFilter + > + /** + * Event type: {@link OnCancelledDeconstructionEvent} + * + * Event filter: {@link LuaEntityDeconstructionCancelledEventFilter} + */ + const on_cancelled_deconstruction: EventId< + OnCancelledDeconstructionEvent, + LuaEntityDeconstructionCancelledEventFilter + > + /** Event type: {@link OnTriggerCreatedEntityEvent} */ + const on_trigger_created_entity: EventId + /** Event type: {@link OnTriggerFiredArtilleryEvent} */ + const on_trigger_fired_artillery: EventId + /** Event type: {@link OnTrainChangedStateEvent} */ + const on_train_changed_state: EventId + /** Event type: {@link OnPlayerCreatedEvent} */ + const on_player_created: EventId + /** Event type: {@link OnResourceDepletedEvent} */ + const on_resource_depleted: EventId + /** Event type: {@link OnPlayerDrivingChangedStateEvent} */ + const on_player_driving_changed_state: EventId + /** Event type: {@link OnForceCreatedEvent} */ + const on_force_created: EventId + /** Event type: {@link OnForcesMergingEvent} */ + const on_forces_merging: EventId + /** Event type: {@link OnPlayerCursorStackChangedEvent} */ + const on_player_cursor_stack_changed: EventId + /** Event type: {@link OnPreEntitySettingsPastedEvent} */ + const on_pre_entity_settings_pasted: EventId + /** Event type: {@link OnEntitySettingsPastedEvent} */ + const on_entity_settings_pasted: EventId + /** Event type: {@link OnPlayerMainInventoryChangedEvent} */ + const on_player_main_inventory_changed: EventId + /** Event type: {@link OnPlayerArmorInventoryChangedEvent} */ + const on_player_armor_inventory_changed: EventId + /** Event type: {@link OnPlayerAmmoInventoryChangedEvent} */ + const on_player_ammo_inventory_changed: EventId + /** Event type: {@link OnPlayerGunInventoryChangedEvent} */ + const on_player_gun_inventory_changed: EventId + /** Event type: {@link OnPlayerPlacedEquipmentEvent} */ + const on_player_placed_equipment: EventId + /** Event type: {@link OnPlayerRemovedEquipmentEvent} */ + const on_player_removed_equipment: EventId + /** Event type: {@link OnPrePlayerDiedEvent} */ + const on_pre_player_died: EventId + /** Event type: {@link OnPlayerDiedEvent} */ + const on_player_died: EventId + /** Event type: {@link OnPlayerRespawnedEvent} */ + const on_player_respawned: EventId + /** Event type: {@link OnPlayerJoinedGameEvent} */ + const on_player_joined_game: EventId + /** Event type: {@link OnPlayerLeftGameEvent} */ + const on_player_left_game: EventId + /** Event type: {@link OnPlayerBuiltTileEvent} */ + const on_player_built_tile: EventId + /** Event type: {@link OnPlayerMinedTileEvent} */ + const on_player_mined_tile: EventId + /** Event type: {@link OnRobotBuiltTileEvent} */ + const on_robot_built_tile: EventId + /** Event type: {@link OnRobotMinedTileEvent} */ + const on_robot_mined_tile: EventId + /** Event type: {@link OnPlayerSelectedAreaEvent} */ + const on_player_selected_area: EventId + /** Event type: {@link OnPlayerAltSelectedAreaEvent} */ + const on_player_alt_selected_area: EventId + /** Event type: {@link OnPlayerChangedSurfaceEvent} */ + const on_player_changed_surface: EventId + /** Event type: {@link OnSelectedEntityChangedEvent} */ + const on_selected_entity_changed: EventId + /** Event type: {@link OnMarketItemPurchasedEvent} */ + const on_market_item_purchased: EventId + /** Event type: {@link OnPlayerDroppedItemEvent} */ + const on_player_dropped_item: EventId + /** Event type: {@link OnBiterBaseBuiltEvent} */ + const on_biter_base_built: EventId + /** Event type: {@link OnPlayerChangedForceEvent} */ + const on_player_changed_force: EventId + /** Event type: {@link OnEntityRenamedEvent} */ + const on_entity_renamed: EventId + /** Event type: {@link OnGuiSelectionStateChangedEvent} */ + const on_gui_selection_state_changed: EventId + /** Event type: {@link OnRuntimeModSettingChangedEvent} */ + const on_runtime_mod_setting_changed: EventId + /** Event type: {@link OnDifficultySettingsChangedEvent} */ + const on_difficulty_settings_changed: EventId + /** Event type: {@link OnSurfaceCreatedEvent} */ + const on_surface_created: EventId + /** Event type: {@link OnSurfaceDeletedEvent} */ + const on_surface_deleted: EventId + /** Event type: {@link OnPreSurfaceDeletedEvent} */ + const on_pre_surface_deleted: EventId + /** + * Event type: {@link OnPlayerMinedEntityEvent} + * + * Event filter: {@link LuaPlayerMinedEntityEventFilter} + */ + const on_player_mined_entity: EventId + /** + * Event type: {@link OnRobotMinedEntityEvent} + * + * Event filter: {@link LuaRobotMinedEntityEventFilter} + */ + const on_robot_mined_entity: EventId + /** Event type: {@link OnTrainCreatedEvent} */ + const on_train_created: EventId + /** Event type: {@link OnGuiElemChangedEvent} */ + const on_gui_elem_changed: EventId + /** Event type: {@link OnPlayerSetupBlueprintEvent} */ + const on_player_setup_blueprint: EventId + /** Event type: {@link OnPlayerDeconstructedAreaEvent} */ + const on_player_deconstructed_area: EventId + /** Event type: {@link OnPlayerConfiguredBlueprintEvent} */ + const on_player_configured_blueprint: EventId + /** Event type: {@link OnConsoleChatEvent} */ + const on_console_chat: EventId + /** Event type: {@link OnConsoleCommandEvent} */ + const on_console_command: EventId + /** Event type: {@link OnPlayerRemovedEvent} */ + const on_player_removed: EventId + /** Event type: {@link OnPrePlayerRemovedEvent} */ + const on_pre_player_removed: EventId + /** Event type: {@link OnPlayerUsedCapsuleEvent} */ + const on_player_used_capsule: EventId + /** + * Event type: {@link ScriptRaisedBuiltEvent} + * + * Event filter: {@link LuaScriptRaisedBuiltEventFilter} + */ + const script_raised_built: EventId + /** + * Event type: {@link ScriptRaisedDestroyEvent} + * + * Event filter: {@link LuaScriptRaisedDestroyEventFilter} + */ + const script_raised_destroy: EventId + /** + * Event type: {@link ScriptRaisedReviveEvent} + * + * Event filter: {@link LuaScriptRaisedReviveEventFilter} + */ + const script_raised_revive: EventId + /** Event type: {@link ScriptRaisedSetTilesEvent} */ + const script_raised_set_tiles: EventId + /** Event type: {@link OnPlayerPromotedEvent} */ + const on_player_promoted: EventId + /** Event type: {@link OnPlayerDemotedEvent} */ + const on_player_demoted: EventId + /** Event type: {@link OnCombatRobotExpiredEvent} */ + const on_combat_robot_expired: EventId + /** Event type: {@link OnWorkerRobotExpiredEvent} */ + const on_worker_robot_expired: EventId + /** Event type: {@link OnPlayerChangedPositionEvent} */ + const on_player_changed_position: EventId + /** Event type: {@link OnModItemOpenedEvent} */ + const on_mod_item_opened: EventId + /** Event type: {@link OnGuiOpenedEvent} */ + const on_gui_opened: EventId + /** Event type: {@link OnGuiClosedEvent} */ + const on_gui_closed: EventId + /** Event type: {@link OnGuiValueChangedEvent} */ + const on_gui_value_changed: EventId + /** Event type: {@link OnPlayerMutedEvent} */ + const on_player_muted: EventId + /** Event type: {@link OnPlayerUnmutedEvent} */ + const on_player_unmuted: EventId + /** Event type: {@link OnPlayerCheatModeEnabledEvent} */ + const on_player_cheat_mode_enabled: EventId + /** Event type: {@link OnPlayerCheatModeDisabledEvent} */ + const on_player_cheat_mode_disabled: EventId + /** Event type: {@link OnCharacterCorpseExpiredEvent} */ + const on_character_corpse_expired: EventId + /** + * Event type: {@link OnPreGhostDeconstructedEvent} + * + * Event filter: {@link LuaPreGhostDeconstructedEventFilter} + */ + const on_pre_ghost_deconstructed: EventId + /** Event type: {@link OnPlayerPipetteEvent} */ + const on_player_pipette: EventId + /** Event type: {@link OnPlayerDisplayResolutionChangedEvent} */ + const on_player_display_resolution_changed: EventId + /** Event type: {@link OnPlayerDisplayScaleChangedEvent} */ + const on_player_display_scale_changed: EventId + /** Event type: {@link OnPrePlayerCraftedItemEvent} */ + const on_pre_player_crafted_item: EventId + /** Event type: {@link OnPlayerCancelledCraftingEvent} */ + const on_player_cancelled_crafting: EventId + /** Event type: {@link OnChunkChartedEvent} */ + const on_chunk_charted: EventId + /** Event type: {@link OnTechnologyEffectsResetEvent} */ + const on_technology_effects_reset: EventId + /** Event type: {@link OnForceResetEvent} */ + const on_force_reset: EventId + /** Event type: {@link OnLandMineArmedEvent} */ + const on_land_mine_armed: EventId + /** Event type: {@link OnForcesMergedEvent} */ + const on_forces_merged: EventId + /** Event type: {@link OnPlayerTrashInventoryChangedEvent} */ + const on_player_trash_inventory_changed: EventId + /** Event type: {@link OnPrePlayerLeftGameEvent} */ + const on_pre_player_left_game: EventId + /** Event type: {@link OnPreSurfaceClearedEvent} */ + const on_pre_surface_cleared: EventId + /** Event type: {@link OnSurfaceClearedEvent} */ + const on_surface_cleared: EventId + /** Event type: {@link OnChunkDeletedEvent} */ + const on_chunk_deleted: EventId + /** Event type: {@link OnPreChunkDeletedEvent} */ + const on_pre_chunk_deleted: EventId + /** Event type: {@link OnTrainScheduleChangedEvent} */ + const on_train_schedule_changed: EventId + /** Event type: {@link OnPlayerBannedEvent} */ + const on_player_banned: EventId + /** Event type: {@link OnPlayerKickedEvent} */ + const on_player_kicked: EventId + /** Event type: {@link OnPlayerUnbannedEvent} */ + const on_player_unbanned: EventId + /** Event type: {@link OnRocketLaunchOrderedEvent} */ + const on_rocket_launch_ordered: EventId + /** Event type: {@link OnScriptPathRequestFinishedEvent} */ + const on_script_path_request_finished: EventId + /** Event type: {@link OnAiCommandCompletedEvent} */ + const on_ai_command_completed: EventId + /** + * Event type: {@link OnMarkedForUpgradeEvent} + * + * Event filter: {@link LuaEntityMarkedForUpgradeEventFilter} + */ + const on_marked_for_upgrade: EventId + /** + * Event type: {@link OnCancelledUpgradeEvent} + * + * Event filter: {@link LuaUpgradeCancelledEventFilter} + */ + const on_cancelled_upgrade: EventId + /** Event type: {@link OnPlayerToggledMapEditorEvent} */ + const on_player_toggled_map_editor: EventId + /** + * Event type: {@link OnEntityClonedEvent} + * + * Event filter: {@link LuaEntityClonedEventFilter} + */ + const on_entity_cloned: EventId + /** Event type: {@link OnAreaClonedEvent} */ + const on_area_cloned: EventId + /** Event type: {@link OnBrushClonedEvent} */ + const on_brush_cloned: EventId + /** Event type: {@link OnGameCreatedFromScenarioEvent} */ + const on_game_created_from_scenario: EventId + /** Event type: {@link OnSurfaceImportedEvent} */ + const on_surface_imported: EventId + /** Event type: {@link OnSurfaceRenamedEvent} */ + const on_surface_renamed: EventId + /** Event type: {@link OnPlayerToggledAltModeEvent} */ + const on_player_toggled_alt_mode: EventId + /** + * Event type: {@link OnPlayerRepairedEntityEvent} + * + * Event filter: {@link LuaPlayerRepairedEntityEventFilter} + */ + const on_player_repaired_entity: EventId + /** Event type: {@link OnPlayerFastTransferredEvent} */ + const on_player_fast_transferred: EventId + /** Event type: {@link OnPreRobotExplodedCliffEvent} */ + const on_pre_robot_exploded_cliff: EventId + /** Event type: {@link OnRobotExplodedCliffEvent} */ + const on_robot_exploded_cliff: EventId + /** Event type: {@link OnEntitySpawnedEvent} */ + const on_entity_spawned: EventId + /** Event type: {@link OnCutsceneWaypointReachedEvent} */ + const on_cutscene_waypoint_reached: EventId + /** Event type: {@link OnUnitGroupCreatedEvent} */ + const on_unit_group_created: EventId + /** Event type: {@link OnUnitAddedToGroupEvent} */ + const on_unit_added_to_group: EventId + /** Event type: {@link OnUnitRemovedFromGroupEvent} */ + const on_unit_removed_from_group: EventId + /** Event type: {@link OnUnitGroupFinishedGatheringEvent} */ + const on_unit_group_finished_gathering: EventId + /** Event type: {@link OnBuildBaseArrivedEvent} */ + const on_build_base_arrived: EventId + /** Event type: {@link OnChartTagAddedEvent} */ + const on_chart_tag_added: EventId + /** Event type: {@link OnChartTagModifiedEvent} */ + const on_chart_tag_modified: EventId + /** Event type: {@link OnChartTagRemovedEvent} */ + const on_chart_tag_removed: EventId + /** Event type: {@link OnLuaShortcutEvent} */ + const on_lua_shortcut: EventId + /** Event type: {@link OnGuiLocationChangedEvent} */ + const on_gui_location_changed: EventId + /** Event type: {@link OnGuiSelectedTabChangedEvent} */ + const on_gui_selected_tab_changed: EventId + /** Event type: {@link OnGuiSwitchStateChangedEvent} */ + const on_gui_switch_state_changed: EventId + /** Event type: {@link OnForceCeaseFireChangedEvent} */ + const on_force_cease_fire_changed: EventId + /** Event type: {@link OnForceFriendsChangedEvent} */ + const on_force_friends_changed: EventId + /** Event type: {@link OnStringTranslatedEvent} */ + const on_string_translated: EventId + /** Event type: {@link OnScriptTriggerEffectEvent} */ + const on_script_trigger_effect: EventId + /** Event type: {@link OnPlayerSetQuickBarSlotEvent} */ + const on_player_set_quick_bar_slot: EventId + /** Event type: {@link OnPrePlayerToggledMapEditorEvent} */ + const on_pre_player_toggled_map_editor: EventId + /** Event type: {@link OnPreScriptInventoryResizedEvent} */ + const on_pre_script_inventory_resized: EventId + /** Event type: {@link OnScriptInventoryResizedEvent} */ + const on_script_inventory_resized: EventId + /** Event type: {@link OnEntityDestroyedEvent} */ + const on_entity_destroyed: EventId + /** Event type: {@link OnPlayerClickedGpsTagEvent} */ + const on_player_clicked_gps_tag: EventId + /** Event type: {@link OnPlayerFlushedFluidEvent} */ + const on_player_flushed_fluid: EventId + /** Event type: {@link OnPermissionGroupEditedEvent} */ + const on_permission_group_edited: EventId + /** Event type: {@link OnPrePermissionStringImportedEvent} */ + const on_pre_permission_string_imported: EventId + /** Event type: {@link OnPermissionStringImportedEvent} */ + const on_permission_string_imported: EventId + /** Event type: {@link OnPrePermissionGroupDeletedEvent} */ + const on_pre_permission_group_deleted: EventId + /** Event type: {@link OnPermissionGroupDeletedEvent} */ + const on_permission_group_deleted: EventId + /** Event type: {@link OnPermissionGroupAddedEvent} */ + const on_permission_group_added: EventId + /** Event type: {@link OnCutsceneCancelledEvent} */ + const on_cutscene_cancelled: EventId + /** Event type: {@link OnPlayerConfiguredSpiderRemoteEvent} */ + const on_player_configured_spider_remote: EventId + /** Event type: {@link OnPlayerUsedSpiderRemoteEvent} */ + const on_player_used_spider_remote: EventId + /** Event type: {@link OnSpiderCommandCompletedEvent} */ + const on_spider_command_completed: EventId + /** Event type: {@link OnEntityLogisticSlotChangedEvent} */ + const on_entity_logistic_slot_changed: EventId + /** Event type: {@link OnEquipmentInsertedEvent} */ + const on_equipment_inserted: EventId + /** Event type: {@link OnEquipmentRemovedEvent} */ + const on_equipment_removed: EventId + } + /** + * See the {@link https://lua-api.factorio.com/next/events.html events page} for more info on what events contain and + * when they get raised. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.events View documentation} + */ + type events = typeof events[keyof typeof events] + enum flow_precision_index { + five_seconds, + one_minute, + ten_minutes, + one_hour, + ten_hours, + fifty_hours, + two_hundred_fifty_hours, + one_thousand_hours, + } + enum group_state { + gathering, + moving, + attacking_distraction, + attacking_target, + finished, + pathfinding, + wander_in_group, + } + enum gui_type { + none, + entity, + research, + controller, + production, + item, + bonus, + trains, + achievement, + blueprint_library, + equipment, + logistic, + other_player, + permissions, + tutorials, + custom, + server_management, + player_management, + tile, + } + enum input_action { + activate_copy, + activate_cut, + activate_paste, + add_permission_group, + add_train_station, + admin_action, + alt_select_area, + alt_select_blueprint_entities, + alternative_copy, + begin_mining, + begin_mining_terrain, + build, + build_rail, + build_terrain, + cancel_craft, + cancel_deconstruct, + cancel_new_blueprint, + cancel_research, + cancel_upgrade, + change_active_character_tab, + change_active_item_group_for_crafting, + change_active_item_group_for_filters, + change_active_quick_bar, + change_arithmetic_combinator_parameters, + change_decider_combinator_parameters, + change_entity_label, + change_item_description, + change_item_label, + change_multiplayer_config, + change_picking_state, + change_programmable_speaker_alert_parameters, + change_programmable_speaker_circuit_parameters, + change_programmable_speaker_parameters, + change_riding_state, + change_shooting_state, + change_train_stop_station, + change_train_wait_condition, + change_train_wait_condition_data, + clear_cursor, + connect_rolling_stock, + copy, + copy_entity_settings, + copy_opened_blueprint, + copy_opened_item, + craft, + cursor_split, + cursor_transfer, + custom_input, + cycle_blueprint_book_backwards, + cycle_blueprint_book_forwards, + deconstruct, + delete_blueprint_library, + delete_blueprint_record, + delete_custom_tag, + delete_permission_group, + destroy_item, + destroy_opened_item, + disconnect_rolling_stock, + drag_train_schedule, + drag_train_wait_condition, + drop_blueprint_record, + drop_item, + edit_blueprint_tool_preview, + edit_custom_tag, + edit_permission_group, + export_blueprint, + fast_entity_split, + fast_entity_transfer, + flush_opened_entity_fluid, + flush_opened_entity_specific_fluid, + go_to_train_station, + grab_blueprint_record, + gui_checked_state_changed, + gui_click, + gui_confirmed, + gui_elem_changed, + gui_location_changed, + gui_selected_tab_changed, + gui_selection_state_changed, + gui_switch_state_changed, + gui_text_changed, + gui_value_changed, + import_blueprint, + import_blueprint_string, + import_blueprints_filtered, + import_permissions_string, + inventory_split, + inventory_transfer, + launch_rocket, + lua_shortcut, + map_editor_action, + market_offer, + mod_settings_changed, + open_achievements_gui, + open_blueprint_library_gui, + open_blueprint_record, + open_bonus_gui, + open_character_gui, + open_current_vehicle_gui, + open_equipment, + open_gui, + open_item, + open_logistic_gui, + open_mod_item, + open_parent_of_opened_item, + open_production_gui, + open_technology_gui, + open_tips_and_tricks_gui, + open_train_gui, + open_train_station_gui, + open_trains_gui, + paste_entity_settings, + place_equipment, + quick_bar_pick_slot, + quick_bar_set_selected_page, + quick_bar_set_slot, + reassign_blueprint, + remove_cables, + remove_train_station, + reset_assembling_machine, + reset_item, + rotate_entity, + select_area, + select_blueprint_entities, + select_entity_slot, + select_item, + select_mapper_slot, + select_next_valid_gun, + select_tile_slot, + send_spidertron, + set_auto_launch_rocket, + set_autosort_inventory, + set_behavior_mode, + set_car_weapons_control, + set_circuit_condition, + set_circuit_mode_of_operation, + set_controller_logistic_trash_filter_item, + set_deconstruction_item_tile_selection_mode, + set_deconstruction_item_trees_and_rocks_only, + set_entity_color, + set_entity_energy_property, + set_entity_logistic_trash_filter_item, + set_filter, + set_flat_controller_gui, + set_heat_interface_mode, + set_heat_interface_temperature, + set_infinity_container_filter_item, + set_infinity_container_remove_unfiltered_items, + set_infinity_pipe_filter, + set_inserter_max_stack_size, + set_inventory_bar, + set_linked_container_link_i_d, + set_logistic_filter_item, + set_logistic_filter_signal, + set_player_color, + set_recipe_notifications, + set_request_from_buffers, + set_research_finished_stops_game, + set_signal, + set_splitter_priority, + set_train_stopped, + set_trains_limit, + set_vehicle_automatic_targeting_parameters, + setup_assembling_machine, + setup_blueprint, + setup_single_blueprint_record, + smart_pipette, + spawn_item, + stack_split, + stack_transfer, + start_repair, + start_research, + start_walking, + stop_building_by_moving, + switch_connect_to_logistic_network, + switch_constant_combinator_state, + switch_inserter_filter_mode_state, + switch_power_switch_state, + switch_to_rename_stop_gui, + take_equipment, + toggle_deconstruction_item_entity_filter_mode, + toggle_deconstruction_item_tile_filter_mode, + toggle_driving, + toggle_enable_vehicle_logistics_while_moving, + toggle_entity_logistic_requests, + toggle_equipment_movement_bonus, + toggle_map_editor, + toggle_personal_logistic_requests, + toggle_personal_roboport, + toggle_show_entity_info, + translate_string, + undo, + upgrade, + upgrade_opened_blueprint_by_item, + upgrade_opened_blueprint_by_record, + use_artillery_remote, + use_item, + wire_dragging, + write_to_console, + } + enum inventory { + fuel, + burnt_result, + chest, + furnace_source, + furnace_result, + furnace_modules, + character_main, + character_guns, + character_ammo, + character_armor, + character_vehicle, + character_trash, + god_main, + editor_main, + editor_guns, + editor_ammo, + editor_armor, + roboport_robot, + roboport_material, + robot_cargo, + robot_repair, + assembling_machine_input, + assembling_machine_output, + assembling_machine_modules, + lab_input, + lab_modules, + mining_drill_modules, + item_main, + rocket_silo_rocket, + rocket_silo_result, + rocket, + car_trunk, + car_ammo, + cargo_wagon, + turret_ammo, + beacon_modules, + character_corpse, + artillery_turret_ammo, + artillery_wagon_ammo, + spider_trunk, + spider_ammo, + spider_trash, + } + enum logistic_member_index { + logistic_container, + vehicle_storage, + character_requester, + character_storage, + character_provider, + generic_on_off_behavior, + } + enum logistic_mode { + none, + active_provider, + storage, + requester, + passive_provider, + buffer, + } + enum mouse_button_type { + none, + left, + right, + middle, + } + /** + * A dictionary mapping all top-level prototypes by name to a list of their associated subtypes. This list is + * organized as a lookup table, meaning it maps the sub-prototype names to `0`. As an example, + * `defines.prototypes['entity']` looks like this: `{furnace=0, inserter=0, container=0, ...}`. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.prototypes View documentation} + */ + const prototypes: { + readonly [Type in string]?: { + readonly [Name in string]?: 0 & { + _notFalsyBrand: any + } + } + } + enum rail_connection_direction { + left, + straight, + right, + none, + } + enum rail_direction { + front, + back, + } + enum relative_gui_position { + top, + bottom, + left, + right, + } + enum relative_gui_type { + accumulator_gui, + achievement_gui, + additional_entity_info_gui, + admin_gui, + arithmetic_combinator_gui, + armor_gui, + assembling_machine_gui, + assembling_machine_select_recipe_gui, + beacon_gui, + blueprint_book_gui, + blueprint_library_gui, + blueprint_setup_gui, + bonus_gui, + burner_equipment_gui, + car_gui, + constant_combinator_gui, + container_gui, + controller_gui, + decider_combinator_gui, + deconstruction_item_gui, + electric_energy_interface_gui, + electric_network_gui, + entity_variations_gui, + entity_with_energy_source_gui, + equipment_grid_gui, + furnace_gui, + generic_on_off_entity_gui, + heat_interface_gui, + infinity_pipe_gui, + inserter_gui, + item_with_inventory_gui, + lab_gui, + lamp_gui, + linked_container_gui, + loader_gui, + logistic_gui, + market_gui, + mining_drill_gui, + other_player_gui, + permissions_gui, + pipe_gui, + power_switch_gui, + production_gui, + programmable_speaker_gui, + rail_chain_signal_gui, + rail_signal_gui, + reactor_gui, + rename_stop_gui, + resource_entity_gui, + roboport_gui, + rocket_silo_gui, + server_config_gui, + spider_vehicle_gui, + splitter_gui, + standalone_character_gui, + storage_tank_gui, + tile_variations_gui, + train_gui, + train_stop_gui, + trains_gui, + transport_belt_gui, + upgrade_item_gui, + wall_gui, + } + enum render_mode { + game, + chart, + chart_zoomed_in, + } + enum rich_text_setting { + enabled, + disabled, + highlight, + } + namespace riding { + enum acceleration { + nothing, + accelerating, + braking, + reversing, + } + enum direction { + left, + straight, + right, + } + } + enum shooting { + not_shooting, + shooting_enemies, + shooting_selected, + } + /** + * State of an ordinary rail signal. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.signal_state View documentation} + */ + enum signal_state { + /** + * Green. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.signal_state.open View documentation} + */ + open, + /** + * Red. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.signal_state.closed View documentation} + */ + closed, + /** + * Orange. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.signal_state.reserved View documentation} + */ + reserved, + /** + * Red - From circuit network. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.signal_state.reserved_by_circuit_network View documentation} + */ + reserved_by_circuit_network, + } + enum train_state { + /** + * Normal state -- following the path. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.on_the_path View documentation} + */ + on_the_path, + /** + * Had path and lost it -- must stop. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.path_lost View documentation} + */ + path_lost, + /** + * Doesn't have anywhere to go. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.no_schedule View documentation} + */ + no_schedule, + /** + * Has no path and is stopped. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.no_path View documentation} + */ + no_path, + /** + * Braking before a rail signal. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.arrive_signal View documentation} + */ + arrive_signal, + /** + * Waiting at a signal. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.wait_signal View documentation} + */ + wait_signal, + /** + * Braking before a station. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.arrive_station View documentation} + */ + arrive_station, + /** + * Waiting at a station. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.wait_station View documentation} + */ + wait_station, + /** + * Switched to manual control and has to stop. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.manual_control_stop View documentation} + */ + manual_control_stop, + /** + * Can move if user explicitly sits in and rides the train. + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.manual_control View documentation} + */ + manual_control, + /** + * Same as no_path but all candidate train stops are full + * + * {@link https://lua-api.factorio.com/next/defines.html#defines.train_state.destination_full View documentation} + */ + destination_full, + } + enum transport_line { + left_line, + right_line, + left_underground_line, + right_underground_line, + secondary_left_line, + secondary_right_line, + left_split_line, + right_split_line, + secondary_left_split_line, + secondary_right_split_line, + } + enum wire_connection_id { + electric_pole, + power_switch_left, + power_switch_right, + } + enum wire_type { + red, + green, + copper, + } +} diff --git a/modules/mod2/typed-factorio/generated/events.d.ts b/modules/mod2/typed-factorio/generated/events.d.ts new file mode 100644 index 0000000..b65e09a --- /dev/null +++ b/modules/mod2/typed-factorio/generated/events.d.ts @@ -0,0 +1,2976 @@ +/** @noSelfInFile */ + +/** + * Called when a {@link https://wiki.factorio.com/Prototype/CustomInput CustomInput} is activated. + * + * {@link https://lua-api.factorio.com/next/Events.html#CustomInputEvent View documentation} + */ +interface CustomInputEvent { + /** The player that activated the custom input. */ + readonly player_index: uint + /** The prototype name of the custom input that was activated. */ + readonly input_name: string + /** The mouse cursor position when the custom input was activated. */ + readonly cursor_position: Position + /** Information about the prototype that is selected when the custom input is used. `nil` if none is selected. */ + readonly selected_prototype?: SelectedPrototypeData + /** Identifier of the event */ + readonly name: string + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a unit/group completes a command. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_ai_command_completed View documentation} + */ +interface OnAiCommandCompletedEvent { + /** Unit_number/group_number of the unit/group which just completed a command. */ + readonly unit_number: uint + readonly result: defines.behavior_result + /** Was this command generated by a distraction. */ + readonly was_distracted: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_ai_command_completed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when an area of the map is cloned. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_area_cloned View documentation} + */ +interface OnAreaClonedEvent { + readonly source_surface: LuaSurface + readonly source_area: BoundingBox + readonly destination_surface: LuaSurface + readonly destination_area: BoundingBox + readonly destination_force?: LuaForce + readonly clone_tiles: boolean + readonly clone_entities: boolean + readonly clone_decoratives: boolean + readonly clear_destination_entities: boolean + readonly clear_destination_decoratives: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_area_cloned + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a biter migration builds a base. + * + * **Note**: This will be called multiple times for each migration, once for every biter that is sacrificed to build + * part of the new base. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_biter_base_built View documentation} + */ +interface OnBiterBaseBuiltEvent { + /** The entity that was built. */ + readonly entity: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_biter_base_built + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a set of positions on the map is cloned. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_brush_cloned View documentation} + */ +interface OnBrushClonedEvent { + readonly source_offset: TilePosition + readonly destination_offset: TilePosition + readonly source_surface: LuaSurface + readonly source_positions: TilePosition[] + readonly destination_surface: LuaSurface + readonly destination_force?: LuaForce + readonly clone_tiles: boolean + readonly clone_entities: boolean + readonly clone_decoratives: boolean + readonly clear_destination_entities: boolean + readonly clear_destination_decoratives: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_brush_cloned + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a {@link defines.command.build_base} command reaches its destination, and before building starts. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_build_base_arrived View documentation} + */ +interface OnBuildBaseArrivedEvent { + /** The unit the command was assigned to. */ + readonly unit?: LuaEntity + /** The unit group the command was assigned to. */ + readonly group?: LuaUnitGroup + /** Identifier of the event */ + readonly name: typeof defines.events.on_build_base_arrived + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when player builds something. Can be filtered using {@link LuaPlayerBuiltEntityEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_built_entity View documentation} + */ +interface OnBuiltEntityEvent { + readonly created_entity: LuaEntity + readonly player_index: uint + readonly stack: LuaItemStack + /** The item prototype used to build the entity. Note this won't exist in some situations (built from blueprint, undo, etc). */ + readonly item?: LuaItemPrototype + /** The tags associated with this entity if any. */ + readonly tags?: Tags + /** Identifier of the event */ + readonly name: typeof defines.events.on_built_entity + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the deconstruction of an entity is canceled. Can be filtered using + * {@link LuaEntityDeconstructionCancelledEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_cancelled_deconstruction View documentation} + */ +interface OnCancelledDeconstructionEvent { + readonly entity: LuaEntity + readonly player_index?: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_cancelled_deconstruction + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the upgrade of an entity is canceled. Can be filtered using {@link LuaUpgradeCancelledEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_cancelled_upgrade View documentation} + */ +interface OnCancelledUpgradeEvent { + readonly entity: LuaEntity + readonly player_index?: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_cancelled_upgrade + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a character corpse expires due to timeout or all of the items being removed from it. + * + * **Note**: this is not called if the corpse is mined. See {@link defines.events.on_pre_player_mined_item} to detect that. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_character_corpse_expired View documentation} + */ +interface OnCharacterCorpseExpiredEvent { + /** The corpse. */ + readonly corpse: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_character_corpse_expired + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a chart tag is created. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_chart_tag_added View documentation} + */ +interface OnChartTagAddedEvent { + readonly tag: LuaCustomChartTag + readonly force: LuaForce + readonly player_index?: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_chart_tag_added + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a chart tag is modified by a player. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_chart_tag_modified View documentation} + */ +interface OnChartTagModifiedEvent { + readonly tag: LuaCustomChartTag + readonly player_index?: uint + readonly force: LuaForce + readonly old_text: string + readonly old_icon?: SignalID + readonly old_player?: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_chart_tag_modified + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called just before a chart tag is deleted. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_chart_tag_removed View documentation} + */ +interface OnChartTagRemovedEvent { + readonly tag: LuaCustomChartTag + readonly force: LuaForce + readonly player_index?: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_chart_tag_removed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a chunk is charted or re-charted. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_chunk_charted View documentation} + */ +interface OnChunkChartedEvent { + readonly surface_index: uint + readonly position: ChunkPosition + /** Area of the chunk. */ + readonly area: BoundingBox + readonly force: LuaForce + /** Identifier of the event */ + readonly name: typeof defines.events.on_chunk_charted + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when one or more chunks are deleted using {@link LuaSurface.delete_chunk LuaSurface::delete_chunk}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_chunk_deleted View documentation} + */ +interface OnChunkDeletedEvent { + readonly surface_index: uint + /** The chunks deleted. */ + readonly positions: ChunkPosition[] + /** Identifier of the event */ + readonly name: typeof defines.events.on_chunk_deleted + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a chunk is generated. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_chunk_generated View documentation} + */ +interface OnChunkGeneratedEvent { + /** Area of the chunk. */ + readonly area: BoundingBox + /** Position of the chunk. */ + readonly position: ChunkPosition + /** The surface the chunk is on. */ + readonly surface: LuaSurface + /** Identifier of the event */ + readonly name: typeof defines.events.on_chunk_generated + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a combat robot expires through a lack of energy, or timeout. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_combat_robot_expired View documentation} + */ +interface OnCombatRobotExpiredEvent { + readonly robot: LuaEntity + /** The entity that owns the robot if any. */ + readonly owner?: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_combat_robot_expired + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a message is sent to the in-game console, either by a player or through the server interface. + * + * **Note**: This event only fires for plain messages, not for any commands (including `/shout` or `/whisper`). + * + * {@link https://lua-api.factorio.com/next/Events.html#on_console_chat View documentation} + */ +interface OnConsoleChatEvent { + /** The player doing the chatting, if any. */ + readonly player_index?: uint + /** The chat message that was sent. */ + readonly message: string + /** Identifier of the event */ + readonly name: typeof defines.events.on_console_chat + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when someone enters a command-like message regardless of it being a valid command. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_console_command View documentation} + */ +interface OnConsoleCommandEvent { + /** The player if any. */ + readonly player_index?: uint + /** The command as typed without the preceding forward slash ('/'). */ + readonly command: string + /** The parameters provided if any. */ + readonly parameters: string + /** Identifier of the event */ + readonly name: typeof defines.events.on_console_command + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a cutscene is cancelled by the player or by script. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_cutscene_cancelled View documentation} + */ +interface OnCutsceneCancelledEvent { + /** The player the cutscene was shown to. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_cutscene_cancelled + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a cutscene is playing, each time it reaches a waypoint in that cutscene. + * + * This refers to an index in the table previously passed to set_controller which started the cutscene. + * + * **Note**: Due to implementation omission, waypoint_index is 0-based. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_cutscene_waypoint_reached View documentation} + */ +interface OnCutsceneWaypointReachedEvent { + /** The player index of the player viewing the cutscene. */ + readonly player_index: uint + /** The index of the waypoint we just completed. */ + readonly waypoint_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_cutscene_waypoint_reached + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the map difficulty settings are changed. + * + * **Note**: It's not guaranteed that both settings are changed - just that at least one has been changed. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_difficulty_settings_changed View documentation} + */ +interface OnDifficultySettingsChangedEvent { + readonly old_recipe_difficulty: uint + readonly old_technology_difficulty: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_difficulty_settings_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when an entity is cloned. Can be filtered for the source entity using {@link LuaEntityClonedEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_entity_cloned View documentation} + */ +interface OnEntityClonedEvent { + readonly source: LuaEntity + readonly destination: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_entity_cloned + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when an entity is damaged. Can be filtered using {@link LuaEntityDamagedEventFilter}. + * + * **Note**: This is not called when an entities health is set directly by another mod. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_entity_damaged View documentation} + */ +interface OnEntityDamagedEvent { + readonly entity: LuaEntity + readonly damage_type: LuaDamagePrototype + /** The damage amount before resistances. */ + readonly original_damage_amount: float + /** The damage amount after resistances. */ + readonly final_damage_amount: float + /** The health of the entity after the damage was applied. */ + readonly final_health: float + /** The entity that did the attacking if available. */ + readonly cause?: LuaEntity + /** The force that did the attacking if any. */ + readonly force?: LuaForce + /** Identifier of the event */ + readonly name: typeof defines.events.on_entity_damaged + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after an entity is destroyed that has been registered with + * {@link LuaBootstrap.register_on_entity_destroyed LuaBootstrap::register_on_entity_destroyed} + * + * **Note**: Depending on when a given entity is destroyed this will be fired at the end of the current tick or end of + * the next tick. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_entity_destroyed View documentation} + */ +interface OnEntityDestroyedEvent { + readonly registration_number: uint64 + readonly unit_number?: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_entity_destroyed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when an entity dies. Can be filtered using {@link LuaEntityDiedEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_entity_died View documentation} + */ +interface OnEntityDiedEvent { + /** The entity that died. */ + readonly entity: LuaEntity + /** The entity that did the killing if available. */ + readonly cause?: LuaEntity + /** The loot generated by this entity if any. */ + readonly loot: LuaInventory + /** The force that did the killing if any. */ + readonly force?: LuaForce + /** The damage type if any. */ + readonly damage_type?: LuaDamagePrototype + /** Identifier of the event */ + readonly name: typeof defines.events.on_entity_died + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when one of an entity's personal logistic slots changes. + * + * **Note**: "Personal logistic slot" refers to a character or vehicle's personal request / auto-trash slots, not the + * request slots on logistic chests. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_entity_logistic_slot_changed View documentation} + */ +interface OnEntityLogisticSlotChangedEvent { + /** The player who changed the slot, or `nil` if changed by script. */ + readonly player_index?: uint + /** The entity for whom a logistic slot was changed. */ + readonly entity: LuaEntity + /** The slot index that was changed. */ + readonly slot_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_entity_logistic_slot_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after an entity has been renamed either by the player or through script. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_entity_renamed View documentation} + */ +interface OnEntityRenamedEvent { + /** If by_script is true this will not be included. */ + readonly player_index?: uint + readonly by_script: boolean + readonly entity: LuaEntity + readonly old_name: string + /** Identifier of the event */ + readonly name: typeof defines.events.on_entity_renamed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after entity copy-paste is done. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_entity_settings_pasted View documentation} + */ +interface OnEntitySettingsPastedEvent { + readonly player_index: uint + /** The source entity settings were copied from. */ + readonly source: LuaEntity + /** The destination entity settings were copied to. */ + readonly destination: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_entity_settings_pasted + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when an entity is spawned by a EnemySpawner + * + * {@link https://lua-api.factorio.com/next/Events.html#on_entity_spawned View documentation} + */ +interface OnEntitySpawnedEvent { + readonly spawner: LuaEntity + readonly entity: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_entity_spawned + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after equipment is inserted into an equipment grid. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_equipment_inserted View documentation} + */ +interface OnEquipmentInsertedEvent { + /** The equipment grid inserted into. */ + readonly grid: LuaEquipmentGrid + /** The equipment inserted. */ + readonly equipment: LuaEquipment + /** Identifier of the event */ + readonly name: typeof defines.events.on_equipment_inserted + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after equipment is removed from an equipment grid. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_equipment_removed View documentation} + */ +interface OnEquipmentRemovedEvent { + /** The equipment grid removed from. */ + readonly grid: LuaEquipmentGrid + /** The equipment removed. */ + readonly equipment: string + /** The count of equipment removed. */ + readonly count: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_equipment_removed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the a forces cease fire values change. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_force_cease_fire_changed View documentation} + */ +interface OnForceCeaseFireChangedEvent { + /** The force who's cease fire changed. */ + readonly force: LuaForce + /** Which force was added or removed. */ + readonly other_force: LuaForce + /** If the other force was added or removed. */ + readonly added: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_force_cease_fire_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a new force is created using `game.create_force()` + * + * **Note**: This is not called when the default forces (`'player'`, `'enemy'`, `'neutral'`) are created as they will + * always exist. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_force_created View documentation} + */ +interface OnForceCreatedEvent { + /** The newly created force. */ + readonly force: LuaForce + /** Identifier of the event */ + readonly name: typeof defines.events.on_force_created + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the a forces friends change. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_force_friends_changed View documentation} + */ +interface OnForceFriendsChangedEvent { + /** The force who's friends changed. */ + readonly force: LuaForce + /** Which force was added or removed. */ + readonly other_force: LuaForce + /** If the other force was added or removed. */ + readonly added: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_force_friends_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when {@link LuaForce.reset LuaForce::reset} is finished. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_force_reset View documentation} + */ +interface OnForceResetEvent { + readonly force: LuaForce + /** Identifier of the event */ + readonly name: typeof defines.events.on_force_reset + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after two forces have been merged using `game.merge_forces()`. + * + * **Note**: The source force is invalidated before this event is called and the name can be re-used in this event if desired. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_forces_merged View documentation} + */ +interface OnForcesMergedEvent { + /** The force destroyed. */ + readonly source_name: string + /** The index of the destroyed force. */ + readonly source_index: uint + /** The force entities where reassigned to. */ + readonly destination: LuaForce + /** Identifier of the event */ + readonly name: typeof defines.events.on_forces_merged + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when two forces are about to be merged using `game.merge_forces()`. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_forces_merging View documentation} + */ +interface OnForcesMergingEvent { + /** The force to be destroyed */ + readonly source: LuaForce + /** The force to reassign entities to. */ + readonly destination: LuaForce + /** Identifier of the event */ + readonly name: typeof defines.events.on_forces_merging + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a game is created from a scenario. This is fired for every mod, even when the scenario's save data + * already includes it. In those cases however, {@link LuaBootstrap.on_init LuaBootstrap::on_init} is not fired. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_game_created_from_scenario View documentation} + */ +interface OnGameCreatedFromScenarioEvent { + /** Identifier of the event */ + readonly name: typeof defines.events.on_game_created_from_scenario + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when {@link LuaGuiElement} checked state is changed (related to checkboxes and radio buttons). + * + * {@link https://lua-api.factorio.com/next/Events.html#on_gui_checked_state_changed View documentation} + */ +interface OnGuiCheckedStateChangedEvent { + /** The element whose checked state changed. */ + readonly element: LuaGuiElement + /** The player who did the change. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_gui_checked_state_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when {@link LuaGuiElement} is clicked. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_gui_click View documentation} + */ +interface OnGuiClickEvent { + /** The clicked element. */ + readonly element: LuaGuiElement + /** The player who did the clicking. */ + readonly player_index: uint + /** The mouse button used if any. */ + readonly button: defines.mouse_button_type + /** If alt was pressed. */ + readonly alt: boolean + /** If control was pressed. */ + readonly control: boolean + /** If shift was pressed. */ + readonly shift: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_gui_click + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the player closes the GUI they have open. + * + * **Note**: This is only called if the player explicitly closed the GUI. + * + * **Note**: It's not advised to open any other GUI during this event because if this is run as a request to open a + * different GUI the game will force close the new opened GUI without notice to ensure the original requested GUI is opened. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_gui_closed View documentation} + */ +interface OnGuiClosedEvent { + /** The player. */ + readonly player_index: uint + /** The GUI type that was open. */ + readonly gui_type: defines.gui_type + /** The entity that was open */ + readonly entity?: LuaEntity + /** The item that was open */ + readonly item?: LuaItemStack + /** The equipment that was open */ + readonly equipment?: LuaEquipment + /** The other player that was open */ + readonly other_player?: LuaPlayer + /** The custom GUI element that was open */ + readonly element?: LuaGuiElement + /** The technology that was automatically selected when opening the research GUI */ + readonly technology?: LuaTechnology + /** The tile position that was open */ + readonly tile_position?: TilePosition + /** Identifier of the event */ + readonly name: typeof defines.events.on_gui_closed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a {@link LuaGuiElement} is confirmed, for example by pressing Enter in a textfield. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_gui_confirmed View documentation} + */ +interface OnGuiConfirmedEvent { + /** The confirmed element. */ + readonly element: LuaGuiElement + /** The player who did the confirming. */ + readonly player_index: uint + /** If alt was pressed. */ + readonly alt: boolean + /** If control was pressed. */ + readonly control: boolean + /** If shift was pressed. */ + readonly shift: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_gui_confirmed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when {@link LuaGuiElement} element value is changed (related to choose element buttons). + * + * {@link https://lua-api.factorio.com/next/Events.html#on_gui_elem_changed View documentation} + */ +interface OnGuiElemChangedEvent { + /** The element whose element value changed. */ + readonly element: LuaGuiElement + /** The player who did the change. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_gui_elem_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when {@link LuaGuiElement} element location is changed (related to frames in `player.gui.screen`). + * + * {@link https://lua-api.factorio.com/next/Events.html#on_gui_location_changed View documentation} + */ +interface OnGuiLocationChangedEvent { + /** The element whose location changed. */ + readonly element: LuaGuiElement + /** The player who did the change. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_gui_location_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the player opens a GUI. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_gui_opened View documentation} + */ +interface OnGuiOpenedEvent { + /** The player. */ + readonly player_index: uint + /** The GUI type that was opened. */ + readonly gui_type: defines.gui_type + /** The entity that was opened */ + readonly entity?: LuaEntity + /** The item that was opened */ + readonly item?: LuaItemStack + /** The equipment that was opened */ + readonly equipment?: LuaEquipment + /** The other player that was opened */ + readonly other_player?: LuaPlayer + /** The custom GUI element that was opened */ + readonly element?: LuaGuiElement + /** Identifier of the event */ + readonly name: typeof defines.events.on_gui_opened + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when {@link LuaGuiElement} selected tab is changed (related to tabbed-panes). + * + * {@link https://lua-api.factorio.com/next/Events.html#on_gui_selected_tab_changed View documentation} + */ +interface OnGuiSelectedTabChangedEvent { + /** The tabbed pane whose selected tab changed. */ + readonly element: LuaGuiElement + /** The player who did the change. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_gui_selected_tab_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when {@link LuaGuiElement} selection state is changed (related to drop-downs and listboxes). + * + * {@link https://lua-api.factorio.com/next/Events.html#on_gui_selection_state_changed View documentation} + */ +interface OnGuiSelectionStateChangedEvent { + /** The element whose selection state changed. */ + readonly element: LuaGuiElement + /** The player who did the change. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_gui_selection_state_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when {@link LuaGuiElement} switch state is changed (related to switches). + * + * {@link https://lua-api.factorio.com/next/Events.html#on_gui_switch_state_changed View documentation} + */ +interface OnGuiSwitchStateChangedEvent { + /** The switch whose switch state changed. */ + readonly element: LuaGuiElement + /** The player who did the change. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_gui_switch_state_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when {@link LuaGuiElement} text is changed by the player. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_gui_text_changed View documentation} + */ +interface OnGuiTextChangedEvent { + /** The edited element. */ + readonly element: LuaGuiElement + /** The player who did the edit. */ + readonly player_index: uint + /** The new text in the element. */ + readonly text: string + /** Identifier of the event */ + readonly name: typeof defines.events.on_gui_text_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when {@link LuaGuiElement} slider value is changed (related to the slider element). + * + * {@link https://lua-api.factorio.com/next/Events.html#on_gui_value_changed View documentation} + */ +interface OnGuiValueChangedEvent { + /** The element whose value changed. */ + readonly element: LuaGuiElement + /** The player who did the change. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_gui_value_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a land mine is armed. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_land_mine_armed View documentation} + */ +interface OnLandMineArmedEvent { + readonly mine: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_land_mine_armed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a custom Lua shortcut is pressed. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_lua_shortcut View documentation} + */ +interface OnLuaShortcutEvent { + readonly player_index: uint + /** Shortcut prototype name of the shortcut that was clicked. */ + readonly prototype_name: string + /** Identifier of the event */ + readonly name: typeof defines.events.on_lua_shortcut + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when an entity is marked for deconstruction with the Deconstruction planner or via script. Can be filtered + * using {@link LuaEntityMarkedForDeconstructionEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_marked_for_deconstruction View documentation} + */ +interface OnMarkedForDeconstructionEvent { + readonly entity: LuaEntity + readonly player_index?: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_marked_for_deconstruction + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when an entity is marked for upgrade with the Upgrade planner or via script. Can be filtered using + * {@link LuaEntityMarkedForUpgradeEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_marked_for_upgrade View documentation} + */ +interface OnMarkedForUpgradeEvent { + readonly entity: LuaEntity + readonly target: LuaEntityPrototype + readonly player_index?: uint + /** The new direction (if any) */ + readonly direction?: defines.direction + /** Identifier of the event */ + readonly name: typeof defines.events.on_marked_for_upgrade + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a player purchases some offer from a `market` entity. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_market_item_purchased View documentation} + */ +interface OnMarketItemPurchasedEvent { + /** The player who did the purchasing. */ + readonly player_index: uint + /** The market entity. */ + readonly market: LuaEntity + /** The index of the offer purchased. */ + readonly offer_index: uint + /** The amount of offers purchased. */ + readonly count: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_market_item_purchased + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the player uses the 'Open item GUI' control on an item defined with the 'mod-openable' flag + * + * {@link https://lua-api.factorio.com/next/Events.html#on_mod_item_opened View documentation} + */ +interface OnModItemOpenedEvent { + /** The player. */ + readonly player_index: uint + /** The item clicked on. */ + readonly item: LuaItemPrototype + /** Identifier of the event */ + readonly name: typeof defines.events.on_mod_item_opened + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called directly after a permission group is added. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_permission_group_added View documentation} + */ +interface OnPermissionGroupAddedEvent { + /** The player that added the group. */ + readonly player_index: uint + /** The group added. */ + readonly group: LuaPermissionGroup + /** Identifier of the event */ + readonly name: typeof defines.events.on_permission_group_added + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called directly after a permission group is deleted. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_permission_group_deleted View documentation} + */ +interface OnPermissionGroupDeletedEvent { + /** The player doing the deletion. */ + readonly player_index: uint + /** The group that was deleted. */ + readonly group_name: string + /** The group id that was deleted. */ + readonly id: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_permission_group_deleted + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called directly after a permission group is edited in some way. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_permission_group_edited View documentation} + */ +interface OnPermissionGroupEditedEvent { + /** The player that did the editing. */ + readonly player_index: uint + /** The group being edited. */ + readonly group: LuaPermissionGroup + /** The edit type: "add-permission", "remove-permission", "enable-all", "disable-all", "add-player", "remove-player", "rename". */ + readonly type: + | "add-permission" + | "remove-permission" + | "enable-all" + | "disable-all" + | "add-player" + | "remove-player" + | "rename" + /** The action when the `type` is "add-permission" or "remove-permission". */ + readonly action: defines.input_action + /** The other player when the `type` is "add-player" or "remove-player". */ + readonly other_player_index: uint + /** The old group name when the `type` is "rename". */ + readonly old_name: string + /** The new group name when the `type` is "rename". */ + readonly new_name: string + /** Identifier of the event */ + readonly name: typeof defines.events.on_permission_group_edited + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called directly after a permission string is imported. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_permission_string_imported View documentation} + */ +interface OnPermissionStringImportedEvent { + /** The player that imported the string. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_permission_string_imported + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player picks up an item. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_picked_up_item View documentation} + */ +interface OnPickedUpItemEvent { + readonly item_stack: SimpleItemStack + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_picked_up_item + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a player alt-selects an area with a selection-tool item. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_alt_selected_area View documentation} + */ +interface OnPlayerAltSelectedAreaEvent { + /** The player doing the selection. */ + readonly player_index: uint + /** The surface selected. */ + readonly surface: LuaSurface + /** The area selected. */ + readonly area: BoundingBox + /** The item used to select the area. */ + readonly item: string + /** The entities selected. */ + readonly entities: LuaEntity[] + /** The tiles selected. */ + readonly tiles: LuaTile[] + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_alt_selected_area + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a players ammo inventory changed in some way. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_ammo_inventory_changed View documentation} + */ +interface OnPlayerAmmoInventoryChangedEvent { + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_ammo_inventory_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a players armor inventory changed in some way. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_armor_inventory_changed View documentation} + */ +interface OnPlayerArmorInventoryChangedEvent { + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_armor_inventory_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player is banned. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_banned View documentation} + */ +interface OnPlayerBannedEvent { + /** The player banned. */ + readonly player_index?: uint + /** The banned player name. */ + readonly player_name: string + /** The player that did the banning if any. */ + readonly by_player?: uint + /** The reason given if any. */ + readonly reason?: string + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_banned + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a player builds tiles. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_built_tile View documentation} + */ +interface OnPlayerBuiltTileEvent { + readonly player_index: uint + /** The surface the tile(s) were built on. */ + readonly surface_index: uint + /** The position data. */ + readonly tiles: OldTileAndPosition[] + /** The tile prototype that was placed. */ + readonly tile: LuaTilePrototype + /** The item type used to build the tiles */ + readonly item?: LuaItemPrototype + /** The stack used to build the tiles (may be empty if all of the items where used to build the tiles). */ + readonly stack?: LuaItemStack + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_built_tile + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player cancels crafting. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_cancelled_crafting View documentation} + */ +interface OnPlayerCancelledCraftingEvent { + /** The player that did the crafting. */ + readonly player_index: uint + /** The crafting items returned to the player's inventory. */ + readonly items: LuaInventory + /** The recipe that has been cancelled. */ + readonly recipe: LuaRecipe + /** The number of crafts that have been cancelled. */ + readonly cancel_count: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_cancelled_crafting + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a player changes forces. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_changed_force View documentation} + */ +interface OnPlayerChangedForceEvent { + /** The player who changed forces. */ + readonly player_index: uint + /** The old force. */ + readonly force: LuaForce + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_changed_force + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the tile position a player is located at changes. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_changed_position View documentation} + */ +interface OnPlayerChangedPositionEvent { + /** The player. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_changed_position + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a player changes surfaces. + * + * **Note**: In the instance a player is moved off a surface due to it being deleted this is not called. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_changed_surface View documentation} + */ +interface OnPlayerChangedSurfaceEvent { + /** The player who changed surfaces. */ + readonly player_index: uint + /** The surface index the player was on. */ + readonly surface_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_changed_surface + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when cheat mode is disabled on a player. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_cheat_mode_disabled View documentation} + */ +interface OnPlayerCheatModeDisabledEvent { + /** The player. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_cheat_mode_disabled + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when cheat mode is enabled on a player. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_cheat_mode_enabled View documentation} + */ +interface OnPlayerCheatModeEnabledEvent { + /** The player. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_cheat_mode_enabled + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player clicks a gps tag + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_clicked_gps_tag View documentation} + */ +interface OnPlayerClickedGpsTagEvent { + /** Index of the player */ + readonly player_index: uint + /** Map position contained in gps tag */ + readonly position: Position + /** Surface name contained in gps tag, even when such surface does not exists */ + readonly surface: string + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_clicked_gps_tag + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player clicks the "confirm" button in the configure Blueprint GUI. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_configured_blueprint View documentation} + */ +interface OnPlayerConfiguredBlueprintEvent { + /** The player. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_configured_blueprint + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player configures spidertron remote to be connected with a given spidertron + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_configured_spider_remote View documentation} + */ +interface OnPlayerConfiguredSpiderRemoteEvent { + /** The player that configured the remote. */ + readonly player_index: uint + /** Spider vehicle to which remote was connected to. */ + readonly vehicle: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_configured_spider_remote + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the player finishes crafting an item. This event fires just before the results are inserted into the + * player's inventory, not when the crafting is queued (see {@link OnPrePlayerCraftedItemEvent on_pre_player_crafted_item}). + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_crafted_item View documentation} + */ +interface OnPlayerCraftedItemEvent { + /** The item that has been crafted. */ + readonly item_stack: LuaItemStack + /** The player doing the crafting. */ + readonly player_index: uint + /** The recipe used to craft this item. */ + readonly recipe: LuaRecipe + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_crafted_item + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after the player was created. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_created View documentation} + */ +interface OnPlayerCreatedEvent { + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_created + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a players cursorstack changed in some way. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_cursor_stack_changed View documentation} + */ +interface OnPlayerCursorStackChangedEvent { + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_cursor_stack_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player selects an area with a deconstruction planner. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_deconstructed_area View documentation} + */ +interface OnPlayerDeconstructedAreaEvent { + /** The player doing the selection. */ + readonly player_index: uint + /** The surface selected. */ + readonly surface: LuaSurface + /** The area selected. */ + readonly area: BoundingBox + /** The item used to select the area. */ + readonly item: string + /** If normal selection or alt selection was used. */ + readonly alt: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_deconstructed_area + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player is demoted. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_demoted View documentation} + */ +interface OnPlayerDemotedEvent { + /** The player. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_demoted + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a player dies. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_died View documentation} + */ +interface OnPlayerDiedEvent { + readonly player_index: uint + readonly cause?: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_died + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the display resolution changes for a given player. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_display_resolution_changed View documentation} + */ +interface OnPlayerDisplayResolutionChangedEvent { + /** The player */ + readonly player_index: uint + /** The old display resolution */ + readonly old_resolution: DisplayResolution + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_display_resolution_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the display scale changes for a given player. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_display_scale_changed View documentation} + */ +interface OnPlayerDisplayScaleChangedEvent { + /** The player */ + readonly player_index: uint + /** The old display scale */ + readonly old_scale: double + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_display_scale_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the player's driving state has changed, this means a player has either entered or left a vehicle. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_driving_changed_state View documentation} + */ +interface OnPlayerDrivingChangedStateEvent { + readonly player_index: uint + /** The vehicle if any. */ + readonly entity?: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_driving_changed_state + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player drops an item on the ground. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_dropped_item View documentation} + */ +interface OnPlayerDroppedItemEvent { + readonly player_index: uint + /** The item-on-ground entity. */ + readonly entity: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_dropped_item + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player fast-transfers something to or from an entity. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_fast_transferred View documentation} + */ +interface OnPlayerFastTransferredEvent { + /** The player transferred from or to. */ + readonly player_index: uint + /** The entity transferred from or to. */ + readonly entity: LuaEntity + /** Whether the transfer was from player to entity. If `false`, the transfer was from entity to player. */ + readonly from_player: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_fast_transferred + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after player flushed fluid + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_flushed_fluid View documentation} + */ +interface OnPlayerFlushedFluidEvent { + /** Index of the player */ + readonly player_index: uint + /** Name of a fluid that was flushed */ + readonly fluid: string + /** Amount of fluid that was removed */ + readonly amount: double + /** Entity from which flush was performed */ + readonly entity: LuaEntity + /** True if flush was requested only on this entity */ + readonly only_this_entity: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_flushed_fluid + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a players gun inventory changed in some way. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_gun_inventory_changed View documentation} + */ +interface OnPlayerGunInventoryChangedEvent { + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_gun_inventory_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a player joins the game. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_joined_game View documentation} + */ +interface OnPlayerJoinedGameEvent { + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_joined_game + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player is kicked. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_kicked View documentation} + */ +interface OnPlayerKickedEvent { + /** The player kicked. */ + readonly player_index: uint + /** The player that did the kicking if any. */ + readonly by_player?: uint + /** The reason given if any. */ + readonly reason?: string + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_kicked + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a player leaves the game. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_left_game View documentation} + */ +interface OnPlayerLeftGameEvent { + readonly player_index: uint + readonly reason: defines.disconnect_reason + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_left_game + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a players main inventory changed in some way. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_main_inventory_changed View documentation} + */ +interface OnPlayerMainInventoryChangedEvent { + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_main_inventory_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after the results of an entity being mined are collected just before the entity is destroyed. After this event + * any items in the buffer will be transferred into the player as if they came from mining the entity. Can be filtered + * using {@link LuaPlayerMinedEntityEventFilter}. + * + * **Note**: The buffer inventory is special in that it's only valid during this event and has a dynamic size expanding + * as more items are transferred into it. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_mined_entity View documentation} + */ +interface OnPlayerMinedEntityEvent { + /** The index of the player doing the mining. */ + readonly player_index: uint + /** The entity that has been mined. */ + readonly entity: LuaEntity + /** The temporary inventory that holds the result of mining the entity. */ + readonly buffer: LuaInventory + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_mined_entity + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the player mines something. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_mined_item View documentation} + */ +interface OnPlayerMinedItemEvent { + /** The item given to the player */ + readonly item_stack: SimpleItemStack + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_mined_item + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a player mines tiles. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_mined_tile View documentation} + */ +interface OnPlayerMinedTileEvent { + readonly player_index: uint + /** The surface the tile(s) were mined from. */ + readonly surface_index: uint + /** The position data. */ + readonly tiles: OldTileAndPosition[] + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_mined_tile + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player is muted. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_muted View documentation} + */ +interface OnPlayerMutedEvent { + /** The player. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_muted + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player invokes the "smart pipette" over an entity. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_pipette View documentation} + */ +interface OnPlayerPipetteEvent { + /** The player */ + readonly player_index: uint + /** The item put in the cursor */ + readonly item: LuaItemPrototype + /** If cheat mode was used to give a free stack of the item. */ + readonly used_cheat_mode: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_pipette + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after the player puts equipment in an equipment grid + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_placed_equipment View documentation} + */ +interface OnPlayerPlacedEquipmentEvent { + readonly player_index: uint + /** The equipment put in the equipment grid. */ + readonly equipment: LuaEquipment + /** The equipment grid the equipment was put in. */ + readonly grid: LuaEquipmentGrid + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_placed_equipment + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player is promoted. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_promoted View documentation} + */ +interface OnPlayerPromotedEvent { + /** The player. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_promoted + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player is removed (deleted) from the game. Not to be confused with the player logging of this is + * different in that the player is deleted as if he never existed in the save file. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_removed View documentation} + */ +interface OnPlayerRemovedEvent { + /** The player index that was removed */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_removed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after the player removes equipment from an equipment grid + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_removed_equipment View documentation} + */ +interface OnPlayerRemovedEquipmentEvent { + readonly player_index: uint + /** The equipment grid removed from. */ + readonly grid: LuaEquipmentGrid + /** The equipment removed. */ + readonly equipment: string + /** The count of equipment removed. */ + readonly count: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_removed_equipment + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player repairs an entity. Can be filtered using {@link LuaPlayerRepairedEntityEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_repaired_entity View documentation} + */ +interface OnPlayerRepairedEntityEvent { + readonly player_index: uint + readonly entity: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_repaired_entity + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a player respawns. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_respawned View documentation} + */ +interface OnPlayerRespawnedEvent { + readonly player_index: uint + /** The player port used to respawn if one was used. */ + readonly player_port?: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_respawned + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the player rotates an entity. This event is only fired when the entity actually changes its orientation + * -- pressing the rotate key on an entity that can't be rotated won't fire this event. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_rotated_entity View documentation} + */ +interface OnPlayerRotatedEntityEvent { + /** The rotated entity. */ + readonly entity: LuaEntity + /** The previous direction */ + readonly previous_direction: defines.direction + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_rotated_entity + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a player selects an area with a selection-tool item. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_selected_area View documentation} + */ +interface OnPlayerSelectedAreaEvent { + /** The player doing the selection. */ + readonly player_index: uint + /** The surface selected. */ + readonly surface: LuaSurface + /** The area selected. */ + readonly area: BoundingBox + /** The item used to select the area. */ + readonly item: string + /** The entities selected. */ + readonly entities: LuaEntity[] + /** The tiles selected. */ + readonly tiles: LuaTile[] + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_selected_area + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player sets a quickbar slot to anything (new value, or set to empty). + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_set_quick_bar_slot View documentation} + */ +interface OnPlayerSetQuickBarSlotEvent { + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_set_quick_bar_slot + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player selects an area with a blueprint. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_setup_blueprint View documentation} + */ +interface OnPlayerSetupBlueprintEvent { + /** The player doing the selection. */ + readonly player_index: uint + /** The surface selected. */ + readonly surface: LuaSurface + /** The area selected. */ + readonly area: BoundingBox + /** The item used to select the area. */ + readonly item: string + /** If normal selection or alt selection was used. */ + readonly alt: boolean + /** The blueprint entity index to source entity mapping. Note: if any mod changes the blueprint this will be incorrect. */ + readonly mapping: LuaLazyLoadedValue> + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_setup_blueprint + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player toggles alt mode, also known as "show entity info". + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_toggled_alt_mode View documentation} + */ +interface OnPlayerToggledAltModeEvent { + readonly player_index: uint + /** + * The new alt mode value. This value is a shortcut for accessing + * {@link GameViewSettings.show_entity_info GameViewSettings::show_entity_info} on the player. + */ + readonly alt_mode: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_toggled_alt_mode + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player toggles the map editor on or off. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_toggled_map_editor View documentation} + */ +interface OnPlayerToggledMapEditorEvent { + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_toggled_map_editor + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a players trash inventory changed in some way. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_trash_inventory_changed View documentation} + */ +interface OnPlayerTrashInventoryChangedEvent { + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_trash_inventory_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player is un-banned. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_unbanned View documentation} + */ +interface OnPlayerUnbannedEvent { + /** The player un-banned. */ + readonly player_index?: uint + /** The player name un-banned. */ + readonly player_name: string + /** The player that did the un-banning if any. */ + readonly by_player?: uint + /** The reason the player was banned if any. */ + readonly reason?: string + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_unbanned + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player is unmuted. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_unmuted View documentation} + */ +interface OnPlayerUnmutedEvent { + /** The player. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_unmuted + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player uses a capsule that results in some game action. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_used_capsule View documentation} + */ +interface OnPlayerUsedCapsuleEvent { + /** The player. */ + readonly player_index: uint + /** The capsule item used. */ + readonly item: LuaItemPrototype + /** The position the capsule was used. */ + readonly position: Position + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_used_capsule + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player uses spidertron remote to send a spidertron to a given position + * + * {@link https://lua-api.factorio.com/next/Events.html#on_player_used_spider_remote View documentation} + */ +interface OnPlayerUsedSpiderRemoteEvent { + /** The player that used the remote. */ + readonly player_index: uint + /** Spider vehicle which was requested to move. */ + readonly vehicle: LuaEntity + /** Goal position to which spidertron was sent to. */ + readonly position: Position + /** If the use was successful. It may fail when spidertron has different driver or when player is on different surface. */ + readonly success: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_player_used_spider_remote + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after an entity dies. Can be filtered using {@link LuaPostEntityDiedEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_post_entity_died View documentation} + */ +interface OnPostEntityDiedEvent { + /** The ghost created by the entity dying if any. */ + readonly ghost?: LuaEntity + /** The force that did the killing if any. */ + readonly force?: LuaForce + /** Position where the entity died. */ + readonly position: Position + /** The entity prototype of the entity that died. */ + readonly prototype: LuaEntityPrototype + /** The damage type if any. */ + readonly damage_type?: LuaDamagePrototype + /** The corpses created by the entity dying if any. */ + readonly corpses: LuaEntity[] + /** The surface the entity was on. */ + readonly surface_index: uint + /** The unit number the entity had if any. */ + readonly unit_number?: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_post_entity_died + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when players uses an item to build something. Called before {@link OnBuiltEntityEvent on_built_entity}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_pre_build View documentation} + */ +interface OnPreBuildEvent { + /** The player who did the placing. */ + readonly player_index: uint + /** Where the item was placed. */ + readonly position: Position + /** Item was placed using shift building. */ + readonly shift_build: boolean + /** The direction the item was facing when placed. */ + readonly direction: defines.direction + /** If building this blueprint was flipped horizontally. */ + readonly flip_horizontal: boolean + /** If building this blueprint was flipped vertically. */ + readonly flip_vertical: boolean + /** Item was placed while moving. */ + readonly created_by_moving: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_pre_build + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called before one or more chunks are deleted using {@link LuaSurface.delete_chunk LuaSurface::delete_chunk}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_pre_chunk_deleted View documentation} + */ +interface OnPreChunkDeletedEvent { + readonly surface_index: uint + /** The chunks to be deleted. */ + readonly positions: ChunkPosition[] + /** Identifier of the event */ + readonly name: typeof defines.events.on_pre_chunk_deleted + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called before entity copy-paste is done. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_pre_entity_settings_pasted View documentation} + */ +interface OnPreEntitySettingsPastedEvent { + readonly player_index: uint + /** The source entity settings will be copied from. */ + readonly source: LuaEntity + /** The destination entity settings will be copied to. */ + readonly destination: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_pre_entity_settings_pasted + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called before a ghost entity is destroyed as a result of being marked for deconstruction. Can be filtered using + * {@link LuaPreGhostDeconstructedEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_pre_ghost_deconstructed View documentation} + */ +interface OnPreGhostDeconstructedEvent { + /** The player that did the deconstruction if any. */ + readonly player_index?: uint + readonly ghost: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_pre_ghost_deconstructed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called directly before a permission group is deleted. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_pre_permission_group_deleted View documentation} + */ +interface OnPrePermissionGroupDeletedEvent { + /** The player doing the deletion. */ + readonly player_index: uint + /** The group to be deleted. */ + readonly group: LuaPermissionGroup + /** Identifier of the event */ + readonly name: typeof defines.events.on_pre_permission_group_deleted + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called directly before a permission string is imported. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_pre_permission_string_imported View documentation} + */ +interface OnPrePermissionStringImportedEvent { + /** The player importing the string. */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_pre_permission_string_imported + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a player queues something to be crafted. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_pre_player_crafted_item View documentation} + */ +interface OnPrePlayerCraftedItemEvent { + /** The player doing the crafting. */ + readonly player_index: uint + /** The recipe being queued. */ + readonly recipe: LuaRecipe + /** The items removed from the players inventory to do the crafting. */ + readonly items: LuaInventory + /** The number of times the recipe is being queued. */ + readonly queued_count: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_pre_player_crafted_item + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called before a players dies. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_pre_player_died View documentation} + */ +interface OnPrePlayerDiedEvent { + readonly player_index: uint + readonly cause?: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_pre_player_died + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called before a player leaves the game. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_pre_player_left_game View documentation} + */ +interface OnPrePlayerLeftGameEvent { + readonly player_index: uint + readonly reason: defines.disconnect_reason + /** Identifier of the event */ + readonly name: typeof defines.events.on_pre_player_left_game + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the player finishes mining an entity, before the entity is removed from map. Can be filtered using + * {@link LuaPrePlayerMinedEntityEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_pre_player_mined_item View documentation} + */ +interface OnPrePlayerMinedItemEvent { + /** The entity being mined */ + readonly entity: LuaEntity + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_pre_player_mined_item + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called before a player is removed (deleted) from the game. Not to be confused with the player logging of this is + * different in that the player is deleted as if he never existed in the save file. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_pre_player_removed View documentation} + */ +interface OnPrePlayerRemovedEvent { + /** The player index that will be removed */ + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_pre_player_removed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called before a player toggles the map editor on or off. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_pre_player_toggled_map_editor View documentation} + */ +interface OnPrePlayerToggledMapEditorEvent { + readonly player_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_pre_player_toggled_map_editor + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called directly before a robot explodes cliffs. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_pre_robot_exploded_cliff View documentation} + */ +interface OnPreRobotExplodedCliffEvent { + readonly robot: LuaEntity + readonly cliff: LuaEntity + /** The cliff explosive used. */ + readonly item: LuaItemPrototype + /** Identifier of the event */ + readonly name: typeof defines.events.on_pre_robot_exploded_cliff + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called just before a script inventory is resized. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_pre_script_inventory_resized View documentation} + */ +interface OnPreScriptInventoryResizedEvent { + /** If done by console command; the player who ran the command. */ + readonly player_index?: uint + /** The mod that did the resizing. This will be `"core"` if done by console command or scenario script. */ + readonly mod: string + readonly inventory: LuaInventory + /** The old inventory size. */ + readonly old_size: uint + /** The new inventory size. */ + readonly new_size: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_pre_script_inventory_resized + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called just before a surface is cleared (all entities removed and all chunks deleted). + * + * {@link https://lua-api.factorio.com/next/Events.html#on_pre_surface_cleared View documentation} + */ +interface OnPreSurfaceClearedEvent { + readonly surface_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_pre_surface_cleared + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called just before a surface is deleted. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_pre_surface_deleted View documentation} + */ +interface OnPreSurfaceDeletedEvent { + readonly surface_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_pre_surface_deleted + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a research finishes. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_research_finished View documentation} + */ +interface OnResearchFinishedEvent { + /** The researched technology */ + readonly research: LuaTechnology + /** If the technology was researched by script. */ + readonly by_script: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_research_finished + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a research is reversed (unresearched). + * + * {@link https://lua-api.factorio.com/next/Events.html#on_research_reversed View documentation} + */ +interface OnResearchReversedEvent { + /** The technology un-researched */ + readonly research: LuaTechnology + /** If the technology was un-researched by script. */ + readonly by_script: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_research_reversed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a technology research starts. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_research_started View documentation} + */ +interface OnResearchStartedEvent { + /** The technology being researched */ + readonly research: LuaTechnology + readonly last_research?: LuaTechnology + /** Identifier of the event */ + readonly name: typeof defines.events.on_research_started + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a resource entity reaches 0 or its minimum yield for infinite resources. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_resource_depleted View documentation} + */ +interface OnResourceDepletedEvent { + readonly entity: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_resource_depleted + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a construction robot builds an entity. Can be filtered using {@link LuaRobotBuiltEntityEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_robot_built_entity View documentation} + */ +interface OnRobotBuiltEntityEvent { + /** The robot that did the building. */ + readonly robot: LuaEntity + /** The entity built. */ + readonly created_entity: LuaEntity + /** The item used to do the building. */ + readonly stack: LuaItemStack + /** The tags associated with this entity if any. */ + readonly tags?: Tags + /** Identifier of the event */ + readonly name: typeof defines.events.on_robot_built_entity + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a robot builds tiles. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_robot_built_tile View documentation} + */ +interface OnRobotBuiltTileEvent { + /** The robot. */ + readonly robot: LuaEntity + /** The position data. */ + readonly tiles: OldTileAndPosition[] + /** The tile prototype that was placed. */ + readonly tile: LuaTilePrototype + /** The item type used to build the tiles. */ + readonly item: LuaItemPrototype + /** The stack used to build the tiles (may be empty if all of the items where used to build the tiles). */ + readonly stack: LuaItemStack + /** The surface the tile(s) are build on. */ + readonly surface_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_robot_built_tile + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called directly after a robot explodes cliffs. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_robot_exploded_cliff View documentation} + */ +interface OnRobotExplodedCliffEvent { + readonly robot: LuaEntity + /** The cliff explosive used. */ + readonly item: LuaItemPrototype + /** Identifier of the event */ + readonly name: typeof defines.events.on_robot_exploded_cliff + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a robot mines an entity. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_robot_mined View documentation} + */ +interface OnRobotMinedEvent { + /** The robot that did the mining. */ + readonly robot: LuaEntity + /** The entity the robot just picked up. */ + readonly item_stack: SimpleItemStack + /** Identifier of the event */ + readonly name: typeof defines.events.on_robot_mined + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after the results of an entity being mined are collected just before the entity is destroyed. After this event + * any items in the buffer will be transferred into the robot as if they came from mining the entity. Can be filtered + * using {@link LuaRobotMinedEntityEventFilter}. + * + * **Note**: The buffer inventory is special in that it's only valid during this event and has a dynamic size expanding + * as more items are transferred into it. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_robot_mined_entity View documentation} + */ +interface OnRobotMinedEntityEvent { + /** The robot doing the mining. */ + readonly robot: LuaEntity + /** The entity that has been mined. */ + readonly entity: LuaEntity + /** The temporary inventory that holds the result of mining the entity. */ + readonly buffer: LuaInventory + /** Identifier of the event */ + readonly name: typeof defines.events.on_robot_mined_entity + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a robot mines tiles. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_robot_mined_tile View documentation} + */ +interface OnRobotMinedTileEvent { + /** The robot. */ + readonly robot: LuaEntity + /** The position data. */ + readonly tiles: OldTileAndPosition[] + /** The surface the tile(s) were mined on. */ + readonly surface_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_robot_mined_tile + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called before a robot mines an entity. Can be filtered using {@link LuaPreRobotMinedEntityEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_robot_pre_mined View documentation} + */ +interface OnRobotPreMinedEvent { + /** The robot that's about to do the mining. */ + readonly robot: LuaEntity + /** The entity which is about to be mined. */ + readonly entity: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_robot_pre_mined + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a rocket silo is ordered to be launched. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_rocket_launch_ordered View documentation} + */ +interface OnRocketLaunchOrderedEvent { + readonly rocket: LuaEntity + readonly rocket_silo: LuaEntity + /** The player that is riding the rocket, if any. */ + readonly player_index?: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_rocket_launch_ordered + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when the rocket is launched. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_rocket_launched View documentation} + */ +interface OnRocketLaunchedEvent { + readonly rocket: LuaEntity + readonly rocket_silo?: LuaEntity + /** The player that is riding the rocket, if any. */ + readonly player_index?: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_rocket_launched + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a runtime mod setting is changed by a player. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_runtime_mod_setting_changed View documentation} + */ +interface OnRuntimeModSettingChangedEvent { + /** + * If the `setting_type` is `"global"` and it was changed through the mod settings GUI, this is the index of the + * player that changed the global setting. If the `setting_type` is `"runtime-per-user"` and it changed a current + * setting of the player, this is the index of the player whose setting was changed. In all other cases, this is `nil`. + */ + readonly player_index?: uint + /** The prototype name of the setting that was changed. */ + readonly setting: string + /** Either "runtime-per-user" or "runtime-global". */ + readonly setting_type: "runtime-per-user" | "runtime-global" + /** Identifier of the event */ + readonly name: typeof defines.events.on_runtime_mod_setting_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called just after a script inventory is resized. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_script_inventory_resized View documentation} + */ +interface OnScriptInventoryResizedEvent { + /** If done by console command; the player who ran the command. */ + readonly player_index?: uint + /** The mod that did the resizing. This will be `"core"` if done by console command or scenario script. */ + readonly mod: string + readonly inventory: LuaInventory + /** The old inventory size. */ + readonly old_size: uint + /** The new inventory size. */ + readonly new_size: uint + /** Any items which didn't fit into the new inventory size. */ + readonly overflow_inventory: LuaInventory + /** Identifier of the event */ + readonly name: typeof defines.events.on_script_inventory_resized + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a {@link LuaSurface.request_path LuaSurface::request_path} call completes. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_script_path_request_finished View documentation} + */ +interface OnScriptPathRequestFinishedEvent { + /** The actual path that the pathfinder has determined. `nil` if pathfinding failed. */ + readonly path?: PathfinderWaypoint[] + /** Handle to associate the callback with a particular call to {@link LuaSurface.request_path LuaSurface::request_path}. */ + readonly id: uint + /** Indicates that the pathfinder failed because it is too busy, and that you can retry later. */ + readonly try_again_later: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_script_path_request_finished + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a script trigger effect is triggered. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_script_trigger_effect View documentation} + */ +interface OnScriptTriggerEffectEvent { + /** The effect_id specified in the trigger effect. */ + readonly effect_id: string + /** The surface the effect happened on. */ + readonly surface_index: uint + readonly source_position?: Position + readonly source_entity?: LuaEntity + readonly target_position?: Position + readonly target_entity?: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_script_trigger_effect + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when an entity of type `radar` finishes scanning a sector. Can be filtered for the radar using + * {@link LuaSectorScannedEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_sector_scanned View documentation} + */ +interface OnSectorScannedEvent { + /** The radar that did the scanning. */ + readonly radar: LuaEntity + /** The chunk scanned. */ + readonly chunk_position: ChunkPosition + /** Area of the scanned chunk. */ + readonly area: BoundingBox + /** Identifier of the event */ + readonly name: typeof defines.events.on_sector_scanned + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after the selected entity changes for a given player. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_selected_entity_changed View documentation} + */ +interface OnSelectedEntityChangedEvent { + /** The player whose selected entity changed. */ + readonly player_index: uint + /** The last selected entity if it still exists and there was one. */ + readonly last_entity?: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_selected_entity_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a spider finishes moving to its autopilot position. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_spider_command_completed View documentation} + */ +interface OnSpiderCommandCompletedEvent { + /** Spider vehicle which was requested to move. */ + readonly vehicle: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_spider_command_completed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a translation request generated through + * {@link LuaPlayer.request_translation LuaPlayer::request_translation} is translated. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_string_translated View documentation} + */ +interface OnStringTranslatedEvent { + /** The player whose locale was used for the translation. */ + readonly player_index: uint + /** The localised string being translated. */ + readonly localised_string: LocalisedString + /** The translated `localised_string`. */ + readonly result: string + /** Whether the requested localised string was valid and could be translated. */ + readonly translated: boolean + /** Identifier of the event */ + readonly name: typeof defines.events.on_string_translated + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called just after a surface is cleared (all entities removed and all chunks deleted). + * + * {@link https://lua-api.factorio.com/next/Events.html#on_surface_cleared View documentation} + */ +interface OnSurfaceClearedEvent { + readonly surface_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_surface_cleared + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a surface is created. + * + * **Note**: This is not called when the default surface is created as it will always exist. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_surface_created View documentation} + */ +interface OnSurfaceCreatedEvent { + readonly surface_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_surface_created + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a surface is deleted. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_surface_deleted View documentation} + */ +interface OnSurfaceDeletedEvent { + readonly surface_index: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_surface_deleted + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called after a surface is imported. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_surface_imported View documentation} + */ +interface OnSurfaceImportedEvent { + readonly surface_index: uint + /** The original surface name. */ + readonly original_name: string + /** Identifier of the event */ + readonly name: typeof defines.events.on_surface_imported + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a surface is renamed. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_surface_renamed View documentation} + */ +interface OnSurfaceRenamedEvent { + readonly surface_index: uint + readonly old_name: string + readonly new_name: string + /** Identifier of the event */ + readonly name: typeof defines.events.on_surface_renamed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when {@link LuaForce.reset_technology_effects LuaForce::reset_technology_effects} is finished. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_technology_effects_reset View documentation} + */ +interface OnTechnologyEffectsResetEvent { + readonly force: LuaForce + /** Identifier of the event */ + readonly name: typeof defines.events.on_technology_effects_reset + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * It is fired once every tick. Since this event is fired every tick, its handler shouldn't include performance heavy code. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_tick View documentation} + */ +interface OnTickEvent { + /** Identifier of the event */ + readonly name: typeof defines.events.on_tick + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a train changes state (started to stopped and vice versa) + * + * {@link https://lua-api.factorio.com/next/Events.html#on_train_changed_state View documentation} + */ +interface OnTrainChangedStateEvent { + readonly train: LuaTrain + readonly old_state: defines.train_state + /** Identifier of the event */ + readonly name: typeof defines.events.on_train_changed_state + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a new train is created either through disconnecting/connecting an existing one or building a new one. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_train_created View documentation} + */ +interface OnTrainCreatedEvent { + readonly train: LuaTrain + /** The first old train id when splitting/merging trains. */ + readonly old_train_id_1?: uint + /** The second old train id when splitting/merging trains. */ + readonly old_train_id_2?: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_train_created + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a trains schedule is changed either by the player or through script. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_train_schedule_changed View documentation} + */ +interface OnTrainScheduleChangedEvent { + readonly train: LuaTrain + /** The player who made the change if any. */ + readonly player_index?: uint + /** Identifier of the event */ + readonly name: typeof defines.events.on_train_schedule_changed + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when an entity with a trigger prototype (such as capsules) create an entity AND that trigger prototype defined + * `trigger_created_entity="true"`. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_trigger_created_entity View documentation} + */ +interface OnTriggerCreatedEntityEvent { + readonly entity: LuaEntity + readonly source?: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_trigger_created_entity + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when an entity with a trigger prototype (such as capsules) fire an artillery projectile AND that trigger + * prototype defined `trigger_fired_artillery="true"`. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_trigger_fired_artillery View documentation} + */ +interface OnTriggerFiredArtilleryEvent { + readonly entity: LuaEntity + readonly source?: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_trigger_fired_artillery + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a unit is added to a unit group. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_unit_added_to_group View documentation} + */ +interface OnUnitAddedToGroupEvent { + readonly unit: LuaEntity + readonly group: LuaUnitGroup + /** Identifier of the event */ + readonly name: typeof defines.events.on_unit_added_to_group + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a new unit group is created, before any members are added to it. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_unit_group_created View documentation} + */ +interface OnUnitGroupCreatedEvent { + readonly group: LuaUnitGroup + /** Identifier of the event */ + readonly name: typeof defines.events.on_unit_group_created + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a unit group finishes gathering and starts executing its command. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_unit_group_finished_gathering View documentation} + */ +interface OnUnitGroupFinishedGatheringEvent { + readonly group: LuaUnitGroup + /** Identifier of the event */ + readonly name: typeof defines.events.on_unit_group_finished_gathering + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a unit is removed from a unit group. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_unit_removed_from_group View documentation} + */ +interface OnUnitRemovedFromGroupEvent { + readonly unit: LuaEntity + readonly group: LuaUnitGroup + /** Identifier of the event */ + readonly name: typeof defines.events.on_unit_removed_from_group + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * Called when a worker (construction or logistic) robot expires through a lack of energy. + * + * {@link https://lua-api.factorio.com/next/Events.html#on_worker_robot_expired View documentation} + */ +interface OnWorkerRobotExpiredEvent { + readonly robot: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.on_worker_robot_expired + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * A static event mods can use to tell other mods they built something by script. This event is only raised if a mod + * does so with {@link LuaBootstrap.raise_event LuaBootstrap::raise_event} or + * {@link LuaBootstrap.raise_script_built LuaBootstrap::raise_script_built}, or when `raise_built` is passed to + * {@link LuaSurface.create_entity LuaSurface::create_entity}. Can be filtered using {@link LuaScriptRaisedBuiltEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#script_raised_built View documentation} + */ +interface ScriptRaisedBuiltEvent { + /** The entity that has been built. */ + readonly entity: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.script_raised_built + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * A static event mods can use to tell other mods they destroyed something by script. This event is only raised if a mod + * does so with {@link LuaBootstrap.raise_event LuaBootstrap::raise_event} or + * {@link LuaBootstrap.raise_script_destroy LuaBootstrap::raise_script_destroy}, or when `raise_destroy` is passed to + * {@link LuaEntity.destroy LuaEntity::destroy}. Can be filtered using {@link LuaScriptRaisedDestroyEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#script_raised_destroy View documentation} + */ +interface ScriptRaisedDestroyEvent { + /** The entity that was destroyed. */ + readonly entity: LuaEntity + /** Identifier of the event */ + readonly name: typeof defines.events.script_raised_destroy + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * A static event mods can use to tell other mods they revived something by script. This event is only raised if a mod + * does so with {@link LuaBootstrap.raise_event LuaBootstrap::raise_event} or + * {@link LuaBootstrap.raise_script_revive LuaBootstrap::raise_script_revive}, or when `raise_revive` is passed to + * {@link LuaEntity.revive LuaEntity::revive}. Can be filtered using {@link LuaScriptRaisedReviveEventFilter}. + * + * {@link https://lua-api.factorio.com/next/Events.html#script_raised_revive View documentation} + */ +interface ScriptRaisedReviveEvent { + /** The entity that was revived. */ + readonly entity: LuaEntity + /** The tags associated with this entity, if any. */ + readonly tags?: Tags + /** Identifier of the event */ + readonly name: typeof defines.events.script_raised_revive + /** Tick the event was generated. */ + readonly tick: uint +} + +/** + * A static event mods can use to tell other mods they changed tiles on a surface by script. This event is only raised + * if a mod does so with {@link LuaBootstrap.raise_event LuaBootstrap::raise_event} or + * {@link LuaBootstrap.raise_script_set_tiles LuaBootstrap::raise_script_set_tiles}, or when `raise_event` is passed to + * {@link LuaSurface.set_tiles LuaSurface::set_tiles}. + * + * {@link https://lua-api.factorio.com/next/Events.html#script_raised_set_tiles View documentation} + */ +interface ScriptRaisedSetTilesEvent { + /** The surface whose tiles were changed. */ + readonly surface_index: uint + /** The tiles that were changed. */ + readonly tiles: Tile[] + /** Identifier of the event */ + readonly name: typeof defines.events.script_raised_set_tiles + /** Tick the event was generated. */ + readonly tick: uint +} + +/** An event id. */ +type EventId = uint & { + readonly _eventData: T + readonly _filter: F +} + +/** + * An event id generated by {@link LuaBootstrap.generate_event_name LuaBootstrap::generate_event_name} and raisable via + * {@link LuaBootstrap.raise_event LuaBootstrap::raise_event}. + */ +type CustomEventId = EventId & { + _customEventIdBrand: any +} diff --git a/modules/mod2/typed-factorio/generated/global-objects.d.ts b/modules/mod2/typed-factorio/generated/global-objects.d.ts new file mode 100644 index 0000000..f4c5a0f --- /dev/null +++ b/modules/mod2/typed-factorio/generated/global-objects.d.ts @@ -0,0 +1,51 @@ +/** @noSelfInFile */ + +/** + * This is the main object, through which most of the API is accessed. It is, however, not available inside handlers + * registered with {@link LuaBootstrap.on_load LuaBootstrap::on_load}. + * + * {@link https://lua-api.factorio.com/next/ View documentation} + */ +declare const game: LuaGameScript + +/** + * Provides an interface for registering event handlers. + * + * {@link https://lua-api.factorio.com/next/ View documentation} + */ +declare const script: LuaBootstrap + +/** + * Allows inter-mod communication by way of providing a repository of interfaces that is shared by all mods. + * + * {@link https://lua-api.factorio.com/next/ View documentation} + */ +declare const remote: LuaRemote + +/** + * Allows registering custom commands for the in-game console accessible via the grave key. + * + * {@link https://lua-api.factorio.com/next/ View documentation} + */ +declare const commands: LuaCommandProcessor + +/** + * Allows reading the current mod settings. + * + * {@link https://lua-api.factorio.com/next/ View documentation} + */ +declare const settings: LuaSettings + +/** + * Allows printing messages to the calling RCON instance if any. + * + * {@link https://lua-api.factorio.com/next/ View documentation} + */ +declare const rcon: LuaRCON + +/** + * Allows rendering of geometric shapes, text and sprites in the game world. + * + * {@link https://lua-api.factorio.com/next/ View documentation} + */ +declare const rendering: LuaRendering diff --git a/modules/mod2/typed-factorio/generated/index.d.ts b/modules/mod2/typed-factorio/generated/index.d.ts new file mode 100644 index 0000000..4a7b7d8 --- /dev/null +++ b/modules/mod2/typed-factorio/generated/index.d.ts @@ -0,0 +1,7 @@ +/// +/// +/// +/// +/// +/// +/// diff --git a/modules/mod2/typed-factorio/package.json b/modules/mod2/typed-factorio/package.json new file mode 100644 index 0000000..6a0eb5a --- /dev/null +++ b/modules/mod2/typed-factorio/package.json @@ -0,0 +1,39 @@ +{ + "name": "typed-factorio", + "version": "0.7.1", + "description": "Featureful typescript definitions for the the Factorio modding lua api.", + "keywords": [ + "factorio", + "types", + "typescript-to-lua", + "tstl" + ], + "repository": "https://github.com/GlassBricks/typed-factorio", + "license": "MIT", + "files": [ + "**/*.d.ts" + ], + "homepage": "https://github.com/GlassBricks/typed-factorio#readme", + "scripts": { + "generate": "cd ../generator && yarn run check && yarn run gen --in ../definitions/generatorSrc --out ../definitions/generated --warn-as-error", + "generate:dev": "cd ../generator && yarn run gen --in ../definitions/generatorSrc --out ../definitions/generated --no-format", + "clean": "rimraf ./generated", + "pretest": "yarn run generate", + "test": "jest", + "prepublishOnly": "yarn run test", + "download-latest-runtime-api": "ts-node ./scripts/downloadLatest.ts" + }, + "dependencies": { + "lua-types": "^2.10.1", + "typescript": "~4.3.5", + "typescript-to-lua": "^1.0.0" + }, + "devDependencies": { + "@types/jest": "^26.0.24", + "@types/node": "^16.4.13", + "jest": "^27.0.6", + "prettier": "^2.3.2", + "ts-jest": "^27.0.4", + "ts-node": "^10.1.0" + } +} diff --git a/modules/mod2/typed-factorio/runtime/index.d.ts b/modules/mod2/typed-factorio/runtime/index.d.ts new file mode 100644 index 0000000..43bdc07 --- /dev/null +++ b/modules/mod2/typed-factorio/runtime/index.d.ts @@ -0,0 +1,10 @@ +/// + +/// + +/// +/// + +// lualib +/// +/// diff --git a/modules/mod2/typed-factorio/runtime/librariesAndFunctions.d.ts b/modules/mod2/typed-factorio/runtime/librariesAndFunctions.d.ts new file mode 100644 index 0000000..82a0f31 --- /dev/null +++ b/modules/mod2/typed-factorio/runtime/librariesAndFunctions.d.ts @@ -0,0 +1,123 @@ +// from https://lua-api.factorio.com/latest/Libraries.html +// last updated for 1.1.35, 1.1.36, 1.1.37 + +/** @noSelfInFile */ + +/** @noSelf */ +interface SerpentOptions { + /** Indentation; triggers long multi-line output. */ + indent: string + /** Provide stringified value in a comment (up to maxlevel of depth). */ + comment: boolean | number + /** Sort keys. */ + sortkeys: boolean | ((this: void, keys: any[], table: any) => void) + /** Force sparse encoding (no nil filling based on #t). */ + sparse: boolean + /** Remove spaces. */ + compact: boolean + /** Raise fatal error on non-serializable values. */ + fatal: boolean + /** Disable bytecode serialization for easy comparison. */ + nocode: boolean + /** Disable checking numbers against undefined and huge values. */ + nohuge: boolean + /** Specify max level up to which to expand nested tables. */ + maxlevel: number + /** Specify max number of elements in a table. */ + maxnum: number + /** Specify max length for all table elements. */ + maxlength: number + /** + * Use __tostring metamethod when serializing tables (v0.29); set to false to disable and serialize the table as is, + * even when __tostring is present. + */ + metatostring: boolean + /** + * Specify format for numeric values as shortest possible round-trippable double (v0.30). Use "%.16g" for better + * readability and "%.17g" (the default value) to preserve floating point precision. + */ + numformat: string + /** Allows to specify a list of values to ignore (as keys). */ + valignore: string[] + /** Allows to specify the list of keys to be serialized. Any keys not in this list are not included in final output (as keys). */ + keyallow: string[] + /** Allows to specity the list of keys to ignore in serialization. */ + keyignore: string[] + /** Allows to specify a list of value types to ignore (as keys). */ + valtypeignore: string[] + /** Provide custom output for tables. */ + custom(opts: { + /** The name of the current element with '=' or an empty string in case of array index, */ + tag: string + /** An opening table bracket { and associated indentation and newline (if any), */ + head: string + /** Table elements concatenated into a string using commas and indentation/newlines (if any), */ + body: string + /** A closing table bracket } and associated indentation and newline (if any), and */ + tail: string + /** The current level. */ + level: number + }): string + /** Name; triggers full serialization with self-ref section. */ + name: string + + refcomment: boolean | number + tablecomment: boolean | number +} + +/** + * Factorio provides the {@link https://github.com/pkulchenko/serpent serpent library} as a global variable `serpent` for + * all mods to use. It allows for easy debugging of tables, because serpent makes it trivial to print them, for example + * by using `serpent.block()`. However, serpent cannot pretty-print LuaObjects such as LuaEntity. The serpent library + * was modified to improve determinism, e.g. comments are turned off by default to avoid returning table addresses. + * Furthermore, two options were added: `refcomment` (true/false/maxlevel) and `tablecomment` (true/false/maxlevel), + * which allow to separately control the self-reference and table value output of the `comment` option. + */ +declare namespace serpent { + /** Full serialization; sets name, compact and sparse options; */ + function dump(tbl: unknown, options?: Partial): string + + /** Single line pretty printing, no self-ref section; sets sortkeys and comment options; */ + function line(tbl: unknown, options?: Partial): string + + /** Multi-line indented pretty printing, no self-ref section; sets indent, sortkeys, and comment options. */ + function block(tbl: unknown, options?: Partial): string + + /** + * For loading serialized fragments, serpent also provides `load` function that adds safety checks and reports an + * error if there is any executable code in the fragment. + */ + function load(str: string, options?: { safe?: boolean }): LuaMultiReturn<[true, T] | [false, string]> +} + +/** + * This function allows to log {@link LocalisedString} to the Factorio + * {@link https://wiki.factorio.com/Log_file log file}. This, in combination with serpent, makes debugging in the data + * stage easier, because it allows to simply inspect entire prototype tables. For example, this allows to see all + * properties of the sulfur item prototype: `log(serpent.block(data.raw["item"]["sulfur"]))` + */ +declare function log(ls: LocalisedString): void + +/** + * This function allows printing {@link LocalisedString}s to stdout without polluting the logfile. This is primarily + * useful for communicating with external tools that launch Factorio as a child process. + */ +declare function localised_print(ls: LocalisedString): void + +/** + * Factorio provides the function `table_size()` as a simple way to find the size of tables with non-continuous keys, + * because the standard `#` does not work correctly for these. The function is a C++-side implementation of the + * following Lua code, thus it is faster than using this code in Lua: + * + * local function size(t) + * local count = 0 + * for k,v in pairs(t) do + * count = count + 1 + * end + * return count + * end + * + * Note that `table_size()` does not work correctly for {@link LuaCustomTable}s, their size has to be determined with + * {@link LuaCustomTable.length LuaCustomTable::operator #} instead. + */ +declare function table_size(tbl: table): number diff --git a/modules/mod2/typed-factorio/runtime/mod-gui.d.ts b/modules/mod2/typed-factorio/runtime/mod-gui.d.ts new file mode 100644 index 0000000..761a98f --- /dev/null +++ b/modules/mod2/typed-factorio/runtime/mod-gui.d.ts @@ -0,0 +1,11 @@ +/** @noSelfInFile */ + +/** @noResolution */ +declare module "mod-gui" { + const button_style: string + const frame_style: string + + function get_button_flow(player: LuaPlayer): FrameGuiElement + + function get_frame_flow(player: LuaPlayer): FlowGuiElement +} diff --git a/modules/mod2/typed-factorio/runtime/pairs.d.ts b/modules/mod2/typed-factorio/runtime/pairs.d.ts new file mode 100644 index 0000000..2ec352f --- /dev/null +++ b/modules/mod2/typed-factorio/runtime/pairs.d.ts @@ -0,0 +1,13 @@ +/** @noSelfInFile */ + +/** Iterating with `pairs` will only iterate the array part of a {@link LuaCustomTable}. */ +declare function pairs(table: LuaCustomTable): LuaIterable> + +declare function pairs(table: LuaCustomTable): LuaIterable> + +/** + * {@link LuaCustomTable} cannot be iterated with `ipairs`. Use `pairs` instead. + * + * @deprecated + */ +declare function ipairs(table: LuaCustomTable): never diff --git a/modules/mod2/typed-factorio/runtime/util.d.ts b/modules/mod2/typed-factorio/runtime/util.d.ts new file mode 100644 index 0000000..08ed5e0 --- /dev/null +++ b/modules/mod2/typed-factorio/runtime/util.d.ts @@ -0,0 +1,120 @@ +// "util" is declared only as a module, even though it also modifies global variables +// This is both because of limitations in `declare module`, and that modules are much friendlier to tooling. + +/** @noSelfInFile */ + +/** @noResolution */ +declare module "util" { + namespace table { + function deepcopy(table: T): T + + function compare(tb1: T, tb2: T): boolean + } + + function copy(table: T): T + + function distance(position1: Position, position2: Position): number + + function positiontostr(position: Position): string + + function formattime(ticks: number): string + + /** Supports 'rrggbb', 'rgb', 'rrggbbaa', 'rgba', 'ww', 'w' */ + function color(hex: string): ColorTable + + function premul_color(color: Color): ColorTable + + function mix_color(c1: Color, c2: Color): ColorArray + + function multiply_color(c1: Color, n: number): ColorArray + + function moveposition( + position: Position, + direction: defines.direction.north | defines.direction.east | defines.direction.south | defines.direction.west, + distance: number + ): Position + function moveposition( + position: Position, + direction: defines.direction, //todo: cardinal only + distance: number + ): Position | undefined + + function oppositedirection(direction: defines.direction): defines.direction + + /** Creates a new array where each element in `stripes` is duplicated `count` times */ + function multiplystripes(count: number, stripes: T[]): T[] + + /** Gets tile position by pixel */ + function by_pixel(x: number, y: number): Position + + /** Gets tile position by pixel, hr */ + function by_pixel_hr(x: number, y: number): Position + + // omitted: foreach_sprite_definition + + function add_shift(a: PositionArray | undefined, b: PositionArray): PositionArray + function add_shift(a: PositionArray, b: PositionArray | undefined): PositionArray + function add_shift(a: PositionArray | undefined, b: PositionArray | undefined): PositionArray | undefined + + // omitted: add_shift_offset + + function mul_shift(shift: PositionArray, scale: number | undefined): PositionArray + function mul_shift(shift: PositionArray | undefined, scale: number | undefined): PositionArray | undefined + + function format_number(amount: number, append_suffix?: boolean): string + + function increment(t: number[], index: number, v?: number): void + + // omitted: conditional_return + + /** + * Recursively merges and/or deep-copies tables. Entries in later tables override entries in earlier ones, unless both + * entries are themselves tables, in which case they are recursively merged. Non-merged tables are deep-copied, so + * that the result is brand new. + */ + function merge(tables: T[]): T + + function insert_safe(entity: LuaEntity | undefined, item_dict: Record | undefined): void + + function remove_safe(entity: LuaEntity | undefined, item_dict: Record | undefined): void + + function split_whitespace(string: string): string[] + + // omitted: split, string_starts_with. already TS functions for that + + // omitted: online_players. use game.connected_players + + function clamp(x: number, lower: number, upper: number): number + + // omitted: get_walkable_tile + + // omitted: combine_icons + // omitted: technology_icons. Create an issue if you really want to see these + + function parse_energy(energy: string): number + + function product_amount( + product: { + probability: number + } & ( + | { + amount: number + } + | { + amount_min: number + amount_max: number + } + ) + ): number + + function empty_sprite(): object + + // omitted: draw_as_glow + // omitted: remove_tile_references + + function remove_from_list(list: T[], value: T): boolean + + function list_to_map(list: T[]): Record + function list_to_map(list: T[]): LuaTable + function list_to_map(list: T): LuaTable +} diff --git a/modules/mod2/typed-factorio/settings/types.d.ts b/modules/mod2/typed-factorio/settings/types.d.ts new file mode 100644 index 0000000..d11dae2 --- /dev/null +++ b/modules/mod2/typed-factorio/settings/types.d.ts @@ -0,0 +1,120 @@ +// Based off of https://wiki.factorio.com/Tutorial:Mod_settings + +export type SettingType = "bool-setting" | "int-setting" | "double-setting" | "string-setting" + +export interface BaseSettingDefinition { + type: SettingType + /** + * The name of the settings prototype should be unique to avoid mod conflicts since the mod settings are global across + * all mods. Because of that it is recommended to prefix mod settings with your mod name, + */ + name: string + localized_name?: LocalisedString + localized_description?: LocalisedString + + /** + * The order property can be used to change how the mod settings are ordered in the settings gui. Mod settings are sorted + * + * - First by mod + * - Then by the setting "order" string + * - Then finally by the setting name. + */ + order?: string + /** + * The hidden property can be used to hide mod settings from GUIs, so that they cannot be seen or changed by players. + * However, other mods can still access hidden settings. {@link https://forums.factorio.com/83316} + */ + hidden?: boolean + /** + * There are the overall kinds of settings: + * + * - **startup**: This kind of setting is available in the prototype stage, and can not be changed runtime. They have to + * be set to the same values for all players on a server. + * - **runtime-global**: This kind of setting is global to an entire save game and can be changed runtime. On servers, + * only admins can change these settings. + * - **runtime-per-user**: This kind of setting is only available runtime in the control.lua stage and each player has + * their own instance of this setting. When a player joins a server their local setting of "keep mod settings per + * save" determines if the local settings they have set are synced to the loaded save or if the save's settings are used. + * + * This "setting_type" also determines in which tab the setting is showed in the mod settings menu. + */ + + setting_type: "startup" | "runtime-global" | "runtime-per-user" +} +/** A true/false checkbox */ +export interface BoolSettingDefinition extends BaseSettingDefinition { + type: "bool-setting" + /** Defines the default value of the setting, in this case whether the checkbox is checked or not. */ + default_value: boolean + /** + * Only loaded if `hidden = true`. This forces the setting to be of this value. This can be useful for mod + * compatibility. {@link https://forums.factorio.com/viewtopic.php?p=531322#p531322} + */ + forced_value?: boolean +} +/** A signed 64 bit integer textfield (or selection dropdown) */ +export interface IntSettingDefinition extends BaseSettingDefinition { + type: "int-setting" + /** Defines the default value of the setting. */ + default_value: number + /** Defines the lowest possible number. */ + minimum_value?: number + /** Defines the highest possible number. */ + maximum_value?: number + /** + * Makes it possible to force the player to choose between the defined numbers, creates a dropdown instead of a + * textfield. If only one allowed value is given, the settings is forced to be of that value. + */ + allowed_values?: number[] +} +/** A double precision floating point textfield (or selection dropdown) */ +export interface DoubleSettingDefinition extends BaseSettingDefinition { + type: "double-setting" + /** Defines the default value of the setting. */ + default_value: number + /** Defines the lowest possible number. */ + minimum_value?: number + /** Defines the highest possible number. */ + maximum_value?: number + /** + * Makes it possible to force the player to choose between the defined numbers, creates a dropdown instead of a + * textfield. If only one allowed value is given, the settings is forced to be of that value. + */ + allowed_values?: number[] +} +/** A string textfield (or selection dropdown) */ +export interface StringSettingDefinition extends BaseSettingDefinition { + type: "string-setting" + /** Defines the default value of the setting. */ + default_value: string + /** Defines whether it's possible for the user to set the textfield to empty and apply the setting. */ + allow_blank?: boolean + /** Whether values that are input by the user should have whitespace removed from both ends of the string. */ + auto_trim?: boolean + /** + * Makes it possible to force the player to choose between the defined strings, creates a dropdown instead of a + * textfield. The strings in the dropdown can be localized (translated) and can have a tooltip, see below. If only one + * allowed value is given, the settings is forced to be of that value. + */ + allowed_values?: string[] +} +/** Setting definitions. See {@link https://wiki.factorio.com/Tutorial:Mod_settings} for more info. */ +export type SettingDefinition = + | BoolSettingDefinition + | IntSettingDefinition + | DoubleSettingDefinition + | StringSettingDefinition + +export interface Data { + readonly raw: { + [T in SettingDefinition["type"]]: Record> + } + /** + * The `data` table expects a specific format for each item in the table. Missing properties will either fall back to + * default values or give an error indicating what's missing. Extra properties that the game isn't looking for are + * simply ignored. + */ + extend(prototypes: SettingDefinition[]): void +} +/** A mapping of mod names to mod version for all enabled mods. */ +export type Mods = Record diff --git a/settings.gradle.kts b/settings.gradle.kts index bc26244..d94594e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,8 +1,8 @@ rootProject.name = "factorio-web-map" include( -// ":modules:mod", - ":modules:mod2", + ":modules:mod", +// ":modules:mod2", ":modules:server", ) diff --git a/src/jsMain/kotlin/factorio.kt b/src/jsMain/kotlin/factorio.kt deleted file mode 100644 index b28b04f..0000000 --- a/src/jsMain/kotlin/factorio.kt +++ /dev/null @@ -1,3 +0,0 @@ - - - From c3ac3bd34a653c33fd1e52723a9ea8942ad3b6e1 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 15 Oct 2021 23:43:42 +0200 Subject: [PATCH 010/629] mucking around with sockets and rcon --- README.md | 0 .../archetype/kotlin-jvm.gradle.kts | 10 ++ modules/kt-rcon/build.gradle.kts | 15 ++ .../kotlin/dev/adamko/ktrcon/KtRconClient.kt | 124 ++++++++++++++ .../kotlin/dev/adamko/ktrcon/KtRconClient2.kt | 103 ++++++++++++ .../kotlin/dev/adamko/ktrcon/KtRconClient3.kt | 130 +++++++++++++++ .../main/kotlin/dev/adamko/ktrcon/Packet.kt | 152 ++++++++++++++++++ .../kotlin/dev/adamko/ktrcon/PacketType.kt | 31 ++++ .../main/kotlin/dev/adamko/ktrcon/Password.kt | 16 ++ .../src/main/kotlin/dev/adamko/ktrcon/main.kt | 25 +++ .../test/resources/server/docker-compose.yml | 10 +- settings.gradle.kts | 1 + 12 files changed, 613 insertions(+), 4 deletions(-) create mode 100644 README.md create mode 100644 modules/kt-rcon/build.gradle.kts create mode 100644 modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient.kt create mode 100644 modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient2.kt create mode 100644 modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient3.kt create mode 100644 modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/Packet.kt create mode 100644 modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/PacketType.kt create mode 100644 modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/Password.kt create mode 100644 modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/main.kt diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts index 4ad22ae..5f33e8a 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-jvm.gradle.kts @@ -1,5 +1,7 @@ package dev.adamko.factoriowebmap.archetype +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { id("dev.adamko.factoriowebmap.archetype.base") kotlin("jvm") @@ -11,3 +13,11 @@ kotlin { dependencies { implementation(platform("org.jetbrains.kotlin:kotlin-bom")) } + +tasks.withType().configureEach { + kotlinOptions.freeCompilerArgs += listOf( + "-Xopt-in=kotlin.OptIn", + "-Xopt-in=kotlin.ExperimentalStdlibApi", + "-Xopt-in=kotlin.time.ExperimentalTime", + ) +} \ No newline at end of file diff --git a/modules/kt-rcon/build.gradle.kts b/modules/kt-rcon/build.gradle.kts new file mode 100644 index 0000000..dbd36d2 --- /dev/null +++ b/modules/kt-rcon/build.gradle.kts @@ -0,0 +1,15 @@ +plugins { + id("dev.adamko.factoriowebmap.archetype.kotlin-jvm") +} + +//group = "${rootProject.group}.server" +//version = rootProject.version +// + +dependencies { + + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2") + + implementation("io.ktor:ktor-network:1.6.4") + +} \ No newline at end of file diff --git a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient.kt b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient.kt new file mode 100644 index 0000000..c5f4419 --- /dev/null +++ b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient.kt @@ -0,0 +1,124 @@ +package dev.adamko.ktrcon + +import java.io.* +import java.net.Socket +import java.net.SocketException +import java.nio.BufferUnderflowException +import java.nio.ByteBuffer +import java.nio.ByteOrder +import java.nio.channels.AsynchronousSocketChannel +import kotlin.coroutines.coroutineContext +import kotlin.coroutines.suspendCoroutine +import kotlin.random.Random +import kotlin.random.nextUInt +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.supervisorScope +import kotlinx.coroutines.yield + +class KtRconClient( + private val host: String, + private val port: Int, + private val password: Password, +) : AutoCloseable { + + private val rconClientScope = CoroutineScope(SupervisorJob()) + + private val socket: Socket = Socket(host, port) + + init { + + runBlocking { + send(PacketType.AUTH_REQUEST, password()) + } + + require(socket.isConnected) { "Socket must connect" } + + println("socket.isConnected: ${socket.isConnected}") + +// val j = rconClientScope.launch { + + runCatching { + val reader = socket.getInputStream() + .bufferedReader() + .lineSequence() + .asFlow() + .onEach { + println("socket response: [$it]") + } + .launchIn(rconClientScope) + +// while (socket.isConnected) { +// println("response: ${input.read().toByte().toInt().toChar()}") + + println("is listener active? ${reader.isActive}") + + reader.invokeOnCompletion { + println("cancelled input stream job") + } + + } +// } +// yield() +// } +// } + + + } + + suspend fun send(type: PacketType, body: String) = supervisorScope { + + val p = Packet(Random.nextUInt(), type, body) + + println("Sending packet: $p - totalSize: ${p.totalSize}") + println("p.size: ${p.size}") + println("p.id: ${p.id}") + println("p.type.value: ${p.type.value}") +// println("p.bodyBytes: ${p.bodyBytes} / ${p.body}") +// println("p.terminator: ${p.terminator} / ${p.terminator.decodeToString()}") + +// println("p.byteArray: ${p.toByteArray()}") + + val bb = p.toByteBuffer2() +// ByteBuffer.wrap(p.toByteArray()) +// bb.order(ByteOrder.LITTLE_ENDIAN) + +// val bb = ByteBuffer.allocate(p.totalSize * 2).apply { +// order(ByteOrder.LITTLE_ENDIAN) +// putInt(p.size) +// putInt(p.id.toInt()) +// putInt(p.type.value) +// put(p.bodyBytes) +// put(p.terminator) +// } + + runCatching { + socket.getOutputStream().use { os -> + os.write(bb.array()) + os.flush() + } + } +// socket.channel.finishConnect() +// socket.getInputStream().use { input -> +// println("running inputddd") +//// while (true) { +// println("response: ${input.readAllBytes().decodeToString()}") +// +//// yield() +//// } +// } + } + + override fun close() { + rconClientScope.cancel("Closing ${this::class}") + socket.close() + } + + +} \ No newline at end of file diff --git a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient2.kt b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient2.kt new file mode 100644 index 0000000..cc4a1bf --- /dev/null +++ b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient2.kt @@ -0,0 +1,103 @@ +package dev.adamko.ktrcon + +import java.io.* +import java.net.InetSocketAddress +import java.net.Socket +import java.net.SocketException +import java.nio.BufferUnderflowException +import java.nio.ByteBuffer +import java.nio.ByteOrder +import java.nio.channels.AsynchronousSocketChannel +import java.nio.channels.CompletionHandler +import java.util.concurrent.TimeUnit +import kotlin.coroutines.coroutineContext +import kotlin.coroutines.suspendCoroutine +import kotlin.random.Random +import kotlin.random.nextUInt +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.supervisorScope +import kotlinx.coroutines.yield + +class KtRconClient2( + private val host: String, + private val port: Int, + private val password: Password, +) : AutoCloseable { + + private val rconClientScope = CoroutineScope(SupervisorJob()) + + private val client: AsynchronousSocketChannel by lazy { + println("Initialising client") + + val client = AsynchronousSocketChannel.open() + val address = InetSocketAddress(host, port) + val result = client.connect(address) + result.get() //.get(2, TimeUnit.SECONDS) + + println("connected to async - $address") + require(client.isOpen) { "Require client is open" } + + client + } + + init { + } + + suspend fun send(type: PacketType, body: String) = supervisorScope { + + val p = Packet(Random.nextUInt(1u..100u), type, body) + + println("Sending packet: $p - totalSize: ${p.totalSize}") + println("p.size: ${p.size}") + println("p.totalSize: ${p.totalSize}") + println("p.id: ${p.id}") + println("p.type.value: ${p.type.value}") +// println("p.bodyBytes: ${p.bodyBytes} / ${p.body}") +// println("p.terminator: ${p.terminator} / ${p.terminator.decodeToString()}") + +// println("p.byteArray: ${p.toByteArray()}") +// println("p.byteArray: ${p.toByteBuffer().array()}") + + + runCatching { + val bb = p.toByteBuffer2() +// ByteBuffer.wrap(p.toByteArray()) +// bb.order(ByteOrder.LITTLE_ENDIAN) + + println("writing bb to client") + bb.compact() + val future = client.write(bb) + + delay(2000) + + val writeResult = future.get() //.get(2, TimeUnit.SECONDS) + delay(2000) + + println("write result: $writeResult") + + + val response = ByteBuffer.allocate(Int.SIZE_BYTES) + val responseStatus = runCatching { + client.read(response).get() //.get(2, TimeUnit.SECONDS) + } + println("responseStatus: $responseStatus") + println("response from server: ${response.array().decodeToString()}") + delay(2000) + } + + } + + override fun close() { + rconClientScope.cancel("Closing ${this::class}") + client.shutdownInput() + client.close() + } + +} \ No newline at end of file diff --git a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient3.kt b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient3.kt new file mode 100644 index 0000000..cdf69d0 --- /dev/null +++ b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient3.kt @@ -0,0 +1,130 @@ +package dev.adamko.ktrcon + +import io.ktor.network.selector.ActorSelectorManager +import io.ktor.network.sockets.aSocket +import io.ktor.network.sockets.openReadChannel +import io.ktor.network.sockets.openWriteChannel +import io.ktor.util.decodeString +import io.ktor.utils.io.ByteReadChannel +import io.ktor.utils.io.ByteWriteChannel +import io.ktor.utils.io.core.isNotEmpty +import io.ktor.utils.io.core.readBytes +import io.ktor.utils.io.readRemaining +import io.ktor.utils.io.readUTF8Line +import io.ktor.utils.io.writeIntLittleEndian +import io.ktor.utils.io.writeStringUtf8 +import java.io.* +import java.net.InetSocketAddress +import java.net.Socket +import java.net.SocketException +import java.nio.BufferUnderflowException +import java.nio.ByteBuffer +import java.nio.ByteOrder +import java.nio.channels.AsynchronousSocketChannel +import java.nio.channels.CompletionHandler +import java.util.concurrent.TimeUnit +import kotlin.coroutines.coroutineContext +import kotlin.coroutines.suspendCoroutine +import kotlin.random.Random +import kotlin.random.nextUInt +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.supervisorScope +import kotlinx.coroutines.yield + +class KtRconClient3( + private val host: String, + private val port: Int, + private val password: Password, +) : AutoCloseable { + + private val rconClientJob = SupervisorJob() + private val rconClientScope = CoroutineScope(rconClientJob) + + private val input: ByteReadChannel + private val output: ByteWriteChannel + + init { + val socket = runBlocking { + val selector = ActorSelectorManager(rconClientJob) + aSocket(selector) + .tcp() + .connect(InetSocketAddress(host, port)) + } + input = socket.openReadChannel() + output = socket.openWriteChannel() + +// runBlocking { +// output.writeStringUtf8("test") +// output.flush() +// delay(1000) +// println("availableForRead: ${input.availableForRead}") +// +// } + + rconClientScope.launch { + while (!input.isClosedForRead) { + val packet = input.readRemaining(1) + while (packet.isNotEmpty) { + val bytes = packet.readBytes() + println( + "received ${bytes.size} bytes: ${bytes.joinToString { "$it" }} - ${bytes.decodeToString()}" + ) + yield() + } + yield() + } + } + } + + suspend fun send(type: PacketType, body: String) = supervisorScope { + + val p = Packet(Random.nextUInt(1u..100u), type, body) + + println("Sending packet: $p - totalSize: ${p.totalSize}") + println("p.size: ${p.size}") + println("p.totalSize: ${p.totalSize}") + println("p.id: ${p.id}") + println("p.type.value: ${p.type.value}") +// println("p.bodyBytes: ${p.bodyBytes} / ${p.body}") +// println("p.terminator: ${p.terminator} / ${p.terminator.decodeToString()}") + +// println("p.byteArray: ${p.toByteArray()}") + println("p.byteArray: ${p.toByteBuffer2().array().joinToString { it.toString() }}") + + + val bb = p.toByteBuffer2() + println("bb: ${bb.position()} - ${bb.toString()}") + + bb.array().forEach { + print("-$it") + output.writeByte(it) + } +// output.writeFully(bb) +// output.writeFully(bb) + output.flush() + println("finished writing") + +// if (type == PacketType.EXEC_COMMAND) { +// println("awaiting response from server") +// input.read(0) { +// println("server response: ${it.array()}") +// } +//// val response = input.readUTF8Line() +//// println("Server said $response") +// } + + } + + override fun close() { + rconClientJob.complete() + rconClientScope.cancel("Closing ${this::class}") + } + +} \ No newline at end of file diff --git a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/Packet.kt b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/Packet.kt new file mode 100644 index 0000000..baa296b --- /dev/null +++ b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/Packet.kt @@ -0,0 +1,152 @@ +package dev.adamko.ktrcon + +import io.ktor.utils.io.bits.reverseByteOrder +import java.nio.ByteBuffer +import java.nio.ByteOrder + + +/** + * @param[size] The packet size field is a 32-bit little endian integer, representing the length of the + * request in bytes. Note that the packet size field itself is not included when determining the + * size of the packet, so the value of this field is always 4 less than the packet's actual + * length. + * + * The minimum possible value for packet size is 10. The maximum possible value of packet size + * is 4096. If the response is too large to fit into one packet, it will be split and sent as + * multiple packets. + * + * @param[id] The packet id field is a 32-bit little endian integer chosen by the client for each + * request. It may be set to any positive integer. When the server responds to the request, the + * response packet will have the same packet id as the original request (unless it is a failed + * [PacketType.AUTH_RESPONSE] packet.) It need not be unique, but if a unique packet id is + * assigned, it can be used to match incoming responses to their corresponding requests. + * + * @param[type] See [PacketType] + * + * @param[body] The packet body field is a null-terminated string encoded in ASCII (i.e. ASCIIZ). + * Depending on the packet type, it may contain either the RCON password for the server, the command + * to be executed, or the server's response to a request. + */ +data class Packet( + val id: UInt, + val type: PacketType, + val bodyRaw: String, +) { + private val bodyTerminator: Byte = NULL_CHAR_BYTE + + private val body: ByteArray = bodyRaw.toByteArray(Charsets.UTF_8) + +// val bodyBytes = body.toByteArray(Charsets.UTF_8) + /** The size of this packet (note that the size itself is excluded from the calculation.) */ + val size: Int = run { + val idSize = 1 * Int.SIZE_BYTES + val typeSize = 1 * Int.SIZE_BYTES + val bodySize = body.size * Byte.SIZE_BYTES + val bodyTerminatorSize = 1 * Byte.SIZE_BYTES + val packetTerminatorSize = 1 * Byte.SIZE_BYTES + val total = idSize + typeSize + bodySize + bodyTerminatorSize + packetTerminatorSize + println( + "packetSize: $total = $idSize + $typeSize + $bodySize + $bodyTerminatorSize + $packetTerminatorSize" + ) + + total + } + + val totalSize: Int = size + Int.SIZE_BYTES + + init { + println("totalSize: $totalSize") + println("body: ${body.joinToString { it.toString() }}") + } + +// fun toByteArray(): ByteArray { +// val array = buildList { +// add(this@Packet.size.toByte()) +// add(id.toByte()) +// add(type.value.toByte()) +// addAll(body.toByteArray(Charsets.UTF_8).asIterable()) +// add(bodyTerminator) +// add(RCON_PACKET_TERMINATOR) +// }.toByteArray() +// +// println(array.joinToString { it.toInt().toChar().toString().padStart(3, ' ') }) +// println(array.joinToString { it.toInt().toString().padStart(3, ' ') }) +// println(array.joinToString { it.toUInt().toString().padStart(3, ' ') }) +// println(array.joinToString { it.toString().padStart(3, ' ') }) +// +//// require(array.size == totalSize) { "${array.size} == $totalSize" } +// return array +// } + + fun toByteBuffer2(): ByteBuffer { + + return ByteBuffer + .allocate(totalSize) + .order(ByteOrder.LITTLE_ENDIAN) + // size + .putInt(size) + // ID + .putInt(id.toInt()) + // type + .putInt(type.value) + // body + .put(body) + // body terminator + .put(bodyTerminator) + // packet terminator + .put(RCON_PACKET_TERMINATOR) +// .asReadOnlyBuffer() + + + } + +// fun toByteBuffer(): ByteBuffer { +// +// +// val bodyBA = buildList { +// add(id.toByte()) +// add(type.value.toByte()) +// addAll(bodyBytes.asIterable()) +// add(bodyTerminator) +// add(RCON_PACKET_TERMINATOR) +// }.toByteArray() +//// +//// +//// val body = ByteBuffer.allocate(totalSize + 15).apply { +//// order(ByteOrder.LITTLE_ENDIAN) +////// putInt(this@Packet.size) +//// putInt(this@Packet.id.toInt()) +//// putInt(this@Packet.type.value) +//// put(this@Packet.bodyBytes) +//// put(this@Packet.terminator) +//// } +// +// val bodySize = bodyBA.size //* Byte.SIZE_BYTES +// println("bodySize: $bodySize") +// +// val bb = ByteBuffer.allocate(bodySize + Int.SIZE_BYTES).apply { +// order(ByteOrder.LITTLE_ENDIAN) +// putInt(bodySize) +//// put(body.array()) +// put(bodyBA) +// } +// +// require( +// bb.array().size == totalSize) { "${bb.array().size} == $totalSize ($size + ${Int.SIZE_BYTES})" } +// +// return bb +// } + + companion object { + /** [Char.MIN_VALUE] = null char */ + const val NULL_CHAR_BYTE = Char.MIN_VALUE.code.toByte() + + /** + * The end of a Source RCON Protocol packet is marked by an empty ASCIIZ string - + * essentially just 8 bits of 0. In languages that do not null-terminate strings automatically, + * you can simply write 16 bits of 0 immediately after the packet body (8 to terminate the + * packet body and 8 for the empty string afterwards). + */ + const val RCON_PACKET_TERMINATOR = NULL_CHAR_BYTE + } +} diff --git a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/PacketType.kt b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/PacketType.kt new file mode 100644 index 0000000..f2878a1 --- /dev/null +++ b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/PacketType.kt @@ -0,0 +1,31 @@ +package dev.adamko.ktrcon +/** + * The packet type field is a 32-bit little endian integer, which indicates the purpose of the + * packet. Its value will always be either 0, 2, or 3, depending on which of the request/response + * types the packet represents. + */ +enum class PacketType( + val value: Int, + val descriptor: String, +) { + + /** + * Typically, the first packet sent by the client will be a [AUTH_RESPONSE] packet, which is + * used to authenticate the connection with the server. + * + * The value of the packet's fields are as follows: + * + * * **ID** - any positive integer, chosen by the client + * (will be mirrored back in the server's response) + * * **Type** - 3 + * * **Body** - the RCON password of the server (if this matches the server's *rcon_password* + * cvar, the auth will succeed) + * + * If the rcon_password cvar is not set, or if it is set to empty string, all + * [AUTH_RESPONSE] requests will be refused. + */ + AUTH_REQUEST(3, "SERVERDATA_AUTH"), + AUTH_RESPONSE(2, "SERVERDATA_AUTH_RESPONSE"), + EXEC_COMMAND(2, "SERVERDATA_EXECCOMMAND"), + RESPONSE_VALUE(0, "SERVERDATA_RESPONSE_VALUE"), +} diff --git a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/Password.kt b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/Password.kt new file mode 100644 index 0000000..8b8b9b2 --- /dev/null +++ b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/Password.kt @@ -0,0 +1,16 @@ +package dev.adamko.ktrcon + +class Password constructor(password: String) { + private val password: ByteArray = password.encodeToByteArray() + private val hashcode: Int = password.hashCode() + + operator fun invoke() = password.decodeToString() + + fun access(accessor: (password: String) -> Unit) { + accessor(password.decodeToString()) + } + + override fun equals(other: Any?) = (other as? Password)?.hashcode == this.hashcode + + override fun hashCode() = hashcode +} \ No newline at end of file diff --git a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/main.kt b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/main.kt new file mode 100644 index 0000000..946446c --- /dev/null +++ b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/main.kt @@ -0,0 +1,25 @@ +package dev.adamko.ktrcon + +import kotlin.time.Duration +import kotlinx.coroutines.delay +import kotlinx.coroutines.runBlocking + +fun main(): Unit = runBlocking { + KtRconClient3( + "localhost", + 27715, + Password("coh9oongoojahX4") + ).use { client -> + + +// client.send(PacketType.AUTH_REQUEST, "passwrd") + client.send(PacketType.AUTH_REQUEST, "coh9oongoojahX4") + delay(Duration.seconds(10)) + + client.send(PacketType.EXEC_COMMAND, "/help") + + + delay(Duration.seconds(10)) + + } +} diff --git a/modules/mod/src/test/resources/server/docker-compose.yml b/modules/mod/src/test/resources/server/docker-compose.yml index 78bc9a8..ff0775c 100644 --- a/modules/mod/src/test/resources/server/docker-compose.yml +++ b/modules/mod/src/test/resources/server/docker-compose.yml @@ -2,15 +2,17 @@ version: "3.9" services: factorio: image: factoriotools/factorio:1.1.42 -# logging: -# driver: "json-file" + # logging: + # driver: "json-file" container_name: "factorio" restart: "unless-stopped" ports: - - "34197:34197/udp" - - "27015:27015/tcp" + - "34197:34197/udp" # factorio + - "27715:27715/tcp" # rcon volumes: - "./data:/factorio" + environment: + RCON_PORT: 27715 # environment: # - PUID=1000 # - PGID=1000 diff --git a/settings.gradle.kts b/settings.gradle.kts index d94594e..f77beda 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,6 +4,7 @@ include( ":modules:mod", // ":modules:mod2", ":modules:server", + ":modules:kt-rcon", ) enableFeaturePreview("VERSION_CATALOGS") From 9adcfb7a12c20b79ba630fb9630dfcce52a54490 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 16 Oct 2021 23:16:09 +0200 Subject: [PATCH 011/629] delete/ignore factorio service files --- .../mod/src/test/resources/server/.gitignore | 1 + .../test/data/config/map-gen-settings.json | 78 --- .../mod/test/data/config/map-settings.json | 120 ---- modules/mod/test/data/config/rconpw | 1 - .../mod/test/data/config/server-settings.json | 69 --- modules/mod/test/data/mods/mod-list.json | 11 - modules/mod/test/data/player-data.json | 532 ------------------ 7 files changed, 1 insertion(+), 811 deletions(-) create mode 100644 modules/mod/src/test/resources/server/.gitignore delete mode 100644 modules/mod/test/data/config/map-gen-settings.json delete mode 100644 modules/mod/test/data/config/map-settings.json delete mode 100644 modules/mod/test/data/config/rconpw delete mode 100644 modules/mod/test/data/config/server-settings.json delete mode 100644 modules/mod/test/data/mods/mod-list.json delete mode 100644 modules/mod/test/data/player-data.json diff --git a/modules/mod/src/test/resources/server/.gitignore b/modules/mod/src/test/resources/server/.gitignore new file mode 100644 index 0000000..1269488 --- /dev/null +++ b/modules/mod/src/test/resources/server/.gitignore @@ -0,0 +1 @@ +data diff --git a/modules/mod/test/data/config/map-gen-settings.json b/modules/mod/test/data/config/map-gen-settings.json deleted file mode 100644 index 7a2b412..0000000 --- a/modules/mod/test/data/config/map-gen-settings.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "_terrain_segmentation_comment": "The inverse of 'water scale' in the map generator GUI.", - "terrain_segmentation": 1, - - "_water_comment": - [ - "The equivalent to 'water coverage' in the map generator GUI. Higher coverage means more water in larger oceans.", - "Water level = 10 * log2(this value)" - ], - "water": 1, - - "_comment_width+height": "Width and height of map, in tiles; 0 means infinite", - "width": 0, - "height": 0, - - "_starting_area_comment": "Multiplier for 'biter free zone radius'", - "starting_area": 1, - - "peaceful_mode": false, - "autoplace_controls": - { - "coal": {"frequency": 1, "size": 1, "richness": 1}, - "stone": {"frequency": 1, "size": 1, "richness": 1}, - "copper-ore": {"frequency": 1, "size": 1,"richness": 1}, - "iron-ore": {"frequency": 1, "size": 1, "richness": 1}, - "uranium-ore": {"frequency": 1, "size": 1, "richness": 1}, - "crude-oil": {"frequency": 1, "size": 1, "richness": 1}, - "trees": {"frequency": 1, "size": 1, "richness": 1}, - "enemy-base": {"frequency": 1, "size": 1, "richness": 1} - }, - - "cliff_settings": - { - "_name_comment": "Name of the cliff prototype", - "name": "cliff", - - "_cliff_elevation_0_comment": "Elevation of first row of cliffs", - "cliff_elevation_0": 10, - - "_cliff_elevation_interval_comment": - [ - "Elevation difference between successive rows of cliffs.", - "This is inversely proportional to 'frequency' in the map generation GUI. Specifically, when set from the GUI the value is 40 / frequency." - ], - "cliff_elevation_interval": 40, - - "_richness_comment": "Called 'cliff continuity' in the map generator GUI. 0 will result in no cliffs, 10 will make all cliff rows completely solid", - "richness": 1 - }, - - "_property_expression_names_comment": - [ - "Overrides for property value generators (map type)", - "Leave 'elevation' blank to get 'normal' terrain.", - "Use 'elevation': '0_16-elevation' to reproduce terrain from 0.16.", - "Use 'elevation': '0_17-island' to get an island.", - "Moisture and terrain type are also controlled via this.", - "'control-setting:moisture:frequency:multiplier' is the inverse of the 'moisture scale' in the map generator GUI.", - "'control-setting:moisture:bias' is the 'moisture bias' in the map generator GUI.", - "'control-setting:aux:frequency:multiplier' is the inverse of the 'terrain type scale' in the map generator GUI.", - "'control-setting:aux:bias' is the 'terrain type bias' in the map generator GUI." - ], - "property_expression_names": - { - "control-setting:moisture:frequency:multiplier": "1", - "control-setting:moisture:bias": "0", - "control-setting:aux:frequency:multiplier": "1", - "control-setting:aux:bias": "0" - }, - - "starting_points": - [ - { "x": 0, "y": 0} - ], - - "_seed_comment": "Use null for a random seed, number for a specific seed.", - "seed": null -} diff --git a/modules/mod/test/data/config/map-settings.json b/modules/mod/test/data/config/map-settings.json deleted file mode 100644 index 62798d9..0000000 --- a/modules/mod/test/data/config/map-settings.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "difficulty_settings": - { - "recipe_difficulty": 0, - "technology_difficulty": 0, - "technology_price_multiplier": 1, - "research_queue_setting": "after-victory" - }, - "pollution": - { - "enabled": true, - "_comment_min_to_diffuse_1": "these are values for 60 ticks (1 simulated second)", - "_comment_min_to_diffuse_2": "amount that is diffused to neighboring chunk", - "diffusion_ratio": 0.02, - "min_to_diffuse": 15, - "ageing": 1, - "expected_max_per_chunk": 150, - "min_to_show_per_chunk": 50, - "min_pollution_to_damage_trees": 60, - "pollution_with_max_forest_damage": 150, - "pollution_per_tree_damage": 50, - "pollution_restored_per_tree_damage": 10, - "max_pollution_to_restore_trees": 20, - "enemy_attack_pollution_consumption_modifier": 1 - }, - "enemy_evolution": - { - "enabled": true, - "time_factor": 0.000004, - "destroy_factor": 0.002, - "pollution_factor": 0.0000009 - }, - "enemy_expansion": - { - "enabled": true, - "min_base_spacing": 3, - "max_expansion_distance": 7, - "friendly_base_influence_radius": 2, - "enemy_building_influence_radius": 2, - "building_coefficient": 0.1, - "other_base_coefficient": 2.0, - "neighbouring_chunk_coefficient": 0.5, - "neighbouring_base_chunk_coefficient": 0.4, - "max_colliding_tiles_coefficient": 0.9, - "settler_group_min_size": 5, - "settler_group_max_size": 20, - "min_expansion_cooldown": 14400, - "max_expansion_cooldown": 216000 - }, - "unit_group": - { - "min_group_gathering_time": 3600, - "max_group_gathering_time": 36000, - "max_wait_time_for_late_members": 7200, - "max_group_radius": 30.0, - "min_group_radius": 5.0, - "max_member_speedup_when_behind": 1.4, - "max_member_slowdown_when_ahead": 0.6, - "max_group_slowdown_factor": 0.3, - "max_group_member_fallback_factor": 3, - "member_disown_distance": 10, - "tick_tolerance_when_member_arrives": 60, - "max_gathering_unit_groups": 30, - "max_unit_group_size": 200 - }, - "steering": - { - "default": - { - "radius": 1.2, - "separation_force": 0.005, - "separation_factor": 1.2, - "force_unit_fuzzy_goto_behavior": false - }, - "moving": - { - "radius": 3, - "separation_force": 0.01, - "separation_factor": 3, - "force_unit_fuzzy_goto_behavior": false - } - }, - "path_finder": - { - "fwd2bwd_ratio": 5, - "goal_pressure_ratio": 2, - "max_steps_worked_per_tick": 100, - "max_work_done_per_tick": 8000, - "use_path_cache": true, - "short_cache_size": 5, - "long_cache_size": 25, - "short_cache_min_cacheable_distance": 10, - "short_cache_min_algo_steps_to_cache": 50, - "long_cache_min_cacheable_distance": 30, - "cache_max_connect_to_cache_steps_multiplier": 100, - "cache_accept_path_start_distance_ratio": 0.2, - "cache_accept_path_end_distance_ratio": 0.15, - "negative_cache_accept_path_start_distance_ratio": 0.3, - "negative_cache_accept_path_end_distance_ratio": 0.3, - "cache_path_start_distance_rating_multiplier": 10, - "cache_path_end_distance_rating_multiplier": 20, - "stale_enemy_with_same_destination_collision_penalty": 30, - "ignore_moving_enemy_collision_distance": 5, - "enemy_with_different_destination_collision_penalty": 30, - "general_entity_collision_penalty": 10, - "general_entity_subsequent_collision_penalty": 3, - "extended_collision_penalty": 3, - "max_clients_to_accept_any_new_request": 10, - "max_clients_to_accept_short_new_request": 100, - "direct_distance_to_consider_short_request": 100, - "short_request_max_steps": 1000, - "short_request_ratio": 0.5, - "min_steps_to_check_path_find_termination": 2000, - "start_to_goal_cost_multiplier_to_terminate_path_find": 500.0, - "overload_levels": [0, 100, 500], - "overload_multipliers": [2, 3, 4], - "negative_path_cache_delay_interval": 20 - }, - "max_failed_behavior_count": 3 -} diff --git a/modules/mod/test/data/config/rconpw b/modules/mod/test/data/config/rconpw deleted file mode 100644 index 581e57b..0000000 --- a/modules/mod/test/data/config/rconpw +++ /dev/null @@ -1 +0,0 @@ -we3Sai7phaeFohc diff --git a/modules/mod/test/data/config/server-settings.json b/modules/mod/test/data/config/server-settings.json deleted file mode 100644 index 0bb77f5..0000000 --- a/modules/mod/test/data/config/server-settings.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "Name of the game as it will appear in the game listing", - "description": "Description of the game that will appear in the listing", - "tags": ["game", "tags"], - - "_comment_max_players": "Maximum number of players allowed, admins can join even a full server. 0 means unlimited.", - "max_players": 0, - - "_comment_visibility": ["public: Game will be published on the official Factorio matching server", - "lan: Game will be broadcast on LAN"], - "visibility": - { - "public": true, - "lan": true - }, - - "_comment_credentials": "Your factorio.com login credentials. Required for games with visibility public", - "username": "", - "password": "", - - "_comment_token": "Authentication token. May be used instead of 'password' above.", - "token": "", - - "game_password": "", - - "_comment_require_user_verification": "When set to true, the server will only allow clients that have a valid Factorio.com account", - "require_user_verification": true, - - "_comment_max_upload_in_kilobytes_per_second" : "optional, default value is 0. 0 means unlimited.", - "max_upload_in_kilobytes_per_second": 0, - - "_comment_max_upload_slots" : "optional, default value is 5. 0 means unlimited.", - "max_upload_slots": 5, - - "_comment_minimum_latency_in_ticks": "optional one tick is 16ms in default speed, default value is 0. 0 means no minimum.", - "minimum_latency_in_ticks": 0, - - "_comment_ignore_player_limit_for_returning_players": "Players that played on this map already can join even when the max player limit was reached.", - "ignore_player_limit_for_returning_players": false, - - "_comment_allow_commands": "possible values are, true, false and admins-only", - "allow_commands": "admins-only", - - "_comment_autosave_interval": "Autosave interval in minutes", - "autosave_interval": 10, - - "_comment_autosave_slots": "server autosave slots, it is cycled through when the server autosaves.", - "autosave_slots": 5, - - "_comment_afk_autokick_interval": "How many minutes until someone is kicked when doing nothing, 0 for never.", - "afk_autokick_interval": 0, - - "_comment_auto_pause": "Whether should the server be paused when no players are present.", - "auto_pause": true, - - "only_admins_can_pause_the_game": true, - - "_comment_autosave_only_on_server": "Whether autosaves should be saved only on server or also on all connected clients. Default is true.", - "autosave_only_on_server": true, - - "_comment_non_blocking_saving": "Highly experimental feature, enable only at your own risk of losing your saves. On UNIX systems, server will fork itself to create an autosave. Autosaving on connected Windows clients will be disabled regardless of autosave_only_on_server option.", - "non_blocking_saving": false, - - "_comment_segment_sizes": "Long network messages are split into segments that are sent over multiple ticks. Their size depends on the number of peers currently connected. Increasing the segment size will increase upload bandwidth requirement for the server and download bandwidth requirement for clients. This setting only affects server outbound messages. Changing these settings can have a negative impact on connection stability for some clients.", - "minimum_segment_size": 25, - "minimum_segment_size_peer_count": 20, - "maximum_segment_size": 100, - "maximum_segment_size_peer_count": 10 -} diff --git a/modules/mod/test/data/mods/mod-list.json b/modules/mod/test/data/mods/mod-list.json deleted file mode 100644 index 95a6869..0000000 --- a/modules/mod/test/data/mods/mod-list.json +++ /dev/null @@ -1,11 +0,0 @@ - -{ - "mods": - [ - - { - "name": "base", - "enabled": true - } - ] -} diff --git a/modules/mod/test/data/player-data.json b/modules/mod/test/data/player-data.json deleted file mode 100644 index c59d595..0000000 --- a/modules/mod/test/data/player-data.json +++ /dev/null @@ -1,532 +0,0 @@ - -{ - "available-campaign-levels": - { - "tight-spot": - { - "level-01": "hard" - }, - "transport-belt-madness": - { - "level-01": "hard" - }, - "tutorial": - { - "level-01": "hard" - } - }, - "tips": - { - "introduction": - { - "status": "unlocked", - "elapsed": 0 - }, - "show-info": - { - "status": "dependencies-not-met" - }, - "e-confirm": - { - "status": "locked" - }, - "clear-cursor": - { - "status": "dependencies-not-met" - }, - "pipette": - { - "status": "locked" - }, - "stack-transfers": - { - "status": "locked", - "skip_status": - { - "conditions": - [ - - {}, - - {}, - - {} - ] - } - }, - "entity-transfers": - { - "status": "locked", - "conditions": - [ - - {}, - - { - "elapsed": 0 - } - ], - "skip_status": - { - "conditions": - [ - - {}, - - {} - ] - } - }, - "z-dropping": - { - "status": "locked", - "conditions": - [ - - {}, - - { - "elapsed": 0 - } - ] - }, - "shoot-targeting": - { - "status": "locked", - "conditions": - [ - - {}, - - { - "elapsed": 0 - } - ] - }, - "bulk-crafting": - { - "status": "locked", - "conditions": - [ - - {}, - - {} - ] - }, - "inserters": - { - "status": "locked" - }, - "burner-inserter-refueling": - { - "status": "locked" - }, - "long-handed-inserters": - { - "status": "locked" - }, - "move-between-labs": - { - "status": "locked" - }, - "insertion-limits": - { - "status": "locked" - }, - "limit-chests": - { - "status": "locked", - "conditions": - [ - - {}, - - {} - ] - }, - "transport-belts": - { - "status": "locked" - }, - "belt-lanes": - { - "status": "locked" - }, - "splitters": - { - "status": "locked" - }, - "splitter-filters": - { - "status": "locked" - }, - "underground-belts": - { - "status": "locked" - }, - "electric-network": - { - "status": "locked", - "conditions": - [ - - { - "conditions": - [ - - { - "conditions": - [ - - {}, - - {} - ] - }, - - { - "elapsed": 0 - } - ] - }, - - {}, - - {}, - - {} - ] - }, - "steam-power": - { - "status": "dependencies-not-met" - }, - "electric-pole-connections": - { - "status": "locked", - "conditions": - [ - - { - "elapsed": 0 - }, - - {} - ] - }, - "low-power": - { - "status": "locked" - }, - "connect-switch": - { - "status": "locked" - }, - "copy-entity-settings": - { - "status": "locked" - }, - "copy-paste-trains": - { - "status": "locked" - }, - "copy-paste-filters": - { - "status": "locked", - "conditions": - [ - - {}, - - {} - ] - }, - "copy-paste-requester-chest": - { - "status": "locked", - "conditions": - [ - - {}, - - {} - ] - }, - "copy-paste-spidertron": - { - "status": "locked" - }, - "drag-building": - { - "status": "locked" - }, - "drag-building-poles": - { - "status": "locked" - }, - "drag-building-underground-belts": - { - "status": "locked" - }, - "fast-belt-bending": - { - "status": "locked" - }, - "fast-obstacle-traversing": - { - "status": "locked", - "conditions": - [ - - {}, - - {} - ] - }, - "trains": - { - "status": "locked" - }, - "rail-building": - { - "status": "locked" - }, - "train-stops": - { - "status": "locked", - "conditions": - [ - - {}, - - { - "conditions": - [ - - {}, - - {} - ] - } - ] - }, - "rail-signals-basic": - { - "status": "locked", - "conditions": - [ - - {}, - - { - "conditions": - [ - - {}, - - {} - ] - } - ] - }, - "rail-signals-advanced": - { - "status": "locked", - "conditions": - [ - - {}, - - {} - ] - }, - "gate-over-rail": - { - "status": "locked", - "conditions": - [ - - {}, - - {}, - - {} - ] - }, - "pump-connection": - { - "status": "locked" - }, - "train-stop-same-name": - { - "status": "locked" - }, - "logistic-network": - { - "status": "locked", - "conditions": - [ - - {}, - - {} - ] - }, - "personal-logistics": - { - "status": "locked" - }, - "construction-robots": - { - "status": "locked" - }, - "passive-provider-chest": - { - "status": "dependencies-not-met" - }, - "storage-chest": - { - "status": "dependencies-not-met" - }, - "requester-chest": - { - "status": "locked" - }, - "active-provider-chest": - { - "status": "locked" - }, - "buffer-chest": - { - "status": "locked" - }, - "ghost-building": - { - "status": "locked" - }, - "ghost-rail-planner": - { - "status": "locked", - "conditions": - [ - - { - "conditions": - [ - - {}, - - {} - ] - }, - - {} - ] - }, - "copy-paste": - { - "status": "locked", - "conditions": - [ - - {}, - - { - "elapsed": 0 - } - ] - }, - "fast-replace": - { - "status": "locked", - "conditions": - [ - - {}, - - {}, - - {} - ] - }, - "fast-replace-direction": - { - "status": "locked" - }, - "fast-replace-belt-splitter": - { - "status": "locked", - "skip_status": - { - "conditions": - [ - - {}, - - {} - ] - } - }, - "fast-replace-belt-underground": - { - "status": "locked" - }, - "rotating-assemblers": - { - "status": "locked", - "conditions": - [ - - {}, - - {} - ] - }, - "circuit-network": - { - "status": "locked", - "conditions": - [ - - {}, - - { - "elapsed": 0 - } - ] - } - }, - "service-username": "", - "service-token": "", - "last-used-filters": - { - "players": "any", - "password": "any", - "mods": "any", - "friends": "any" - }, - "column-ordering": - { - "public-index": "name", - "public-ascending": true, - "lan-index": "name", - "lan-ascending": true - }, - "editor-lua-snippets": - [ - - { - "name": "Example (Turn trees into biters)", - "code": "local surface = game.player.surface\nlocal entities = surface.find_entities_filtered{area = area, type = 'tree'}\nfor k, tree in pairs(entities) do\n local position = tree.position\n tree.destroy()\n surface.create_entity{name = 'small-biter', position = position}\nend" - } - ], - "last-played-version": - { - "game_version": "1.1.41", - "build_version": 58972, - "build_mode": "headless", - "platform": "linux64" - }, - "blueprint-view": "grid" -} From 5a62aa82184dbba12e90740c76974b031b03cd0f Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 16 Oct 2021 23:16:26 +0200 Subject: [PATCH 012/629] rm old command --- .../kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient2.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient2.kt b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient2.kt index cc4a1bf..dd79d4e 100644 --- a/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient2.kt +++ b/modules/kt-rcon/src/main/kotlin/dev/adamko/ktrcon/KtRconClient2.kt @@ -72,7 +72,7 @@ class KtRconClient2( // bb.order(ByteOrder.LITTLE_ENDIAN) println("writing bb to client") - bb.compact() + val future = client.write(bb) delay(2000) From ce3a75cae5a6c168c96eb5623502f5032052b99e Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 16 Oct 2021 23:16:36 +0200 Subject: [PATCH 013/629] kakfa kraft --- modules/kafka/build.gradle.kts | 0 modules/kafka/docker-compose.yml | 14 ++++++++++ modules/kafka/id-gen.sh | 13 +++++++++ modules/kafka/kafka.Dockerfile | 46 ++++++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 modules/kafka/build.gradle.kts create mode 100644 modules/kafka/docker-compose.yml create mode 100644 modules/kafka/id-gen.sh create mode 100644 modules/kafka/kafka.Dockerfile diff --git a/modules/kafka/build.gradle.kts b/modules/kafka/build.gradle.kts new file mode 100644 index 0000000..e69de29 diff --git a/modules/kafka/docker-compose.yml b/modules/kafka/docker-compose.yml new file mode 100644 index 0000000..55217c6 --- /dev/null +++ b/modules/kafka/docker-compose.yml @@ -0,0 +1,14 @@ +version: "3.9" + +services: + + kafka: + image: dev-adamko/kafka + container_name: "kafka-factorio" + build: + dockerfile: "kafka.Dockerfile" + args: + KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/3.0.0/kafka_2.13-3.0.0.tgz" + ports: + - "9092:9092" + - "9093:9093" \ No newline at end of file diff --git a/modules/kafka/id-gen.sh b/modules/kafka/id-gen.sh new file mode 100644 index 0000000..3473494 --- /dev/null +++ b/modules/kafka/id-gen.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +DELIM='-' + +WORDS="$(xkcdpass --numwords=2 --delimiter="$DELIM" --valid-chars='\w' --case='first')" + +NUMS=$(( (RANDOM + 10) % 100 )) + +echo "Generated ID $WORDS$DELIM$NUMS" + +echo "$WORDS$DELIM$NUMS" + +exit 0 \ No newline at end of file diff --git a/modules/kafka/kafka.Dockerfile b/modules/kafka/kafka.Dockerfile new file mode 100644 index 0000000..5297d14 --- /dev/null +++ b/modules/kafka/kafka.Dockerfile @@ -0,0 +1,46 @@ +ARG KAFKA_DL_URL=https://dlcdn.apache.org/kafka/3.0.0/kafka_2.13-3.0.0.tgz + +FROM debian:11-slim as Kafka-Download +ARG KAFKA_DL_URL + +WORKDIR /kafka + +RUN apt-get update && apt-get install -y \ + curl \ + && rm -rf /var/lib/apt/lists/* + +RUN echo "Downloading Kafka from $KAFKA_DL_URL" \ + && curl "$KAFKA_DL_URL" | tar --strip-components=1 -xz \ + && echo "Finished Kafka download" \ + && ls -la + + +FROM openjdk:11 + +WORKDIR /kafka + +COPY --from=Kafka-Download /kafka /kafka + +# hardcoded for now, based on values from './config/kraft/server.properties' +# log.dirs +VOLUME /tmp/kraft-combined-logs +# listeners, controller.quorum.voters +EXPOSE 9092, 9093 + +# KRaft (aka KIP-500) mode Preview Release +# https://github.com/apache/kafka/blob/041b76dc57f096be2a2d7532d917122992bff6e2/config/kraft/README.md + +# Generate a cluster ID +RUN echo "$(./bin/kafka-storage.sh random-uuid)" > cluster_id \ + && echo "Generated a Kafka Cluster ID: $(cat cluster_id)" + +# Format storage directories +RUN ./bin/kafka-storage.sh format -t "$(cat cluster_id)" -c ./config/kraft/server.properties + +# launch the broker in KRaft mode, which means that it runs without ZooKeeper +RUN ./bin/kafka-storage.sh format \ + --ignore-formatted \ + --config ./config/kraft/server.properties \ + --cluster-id "$(cat cluster_id)" + +ENTRYPOINT ["./bin/kafka-server-start.sh", "./config/kraft/server.properties"] From 5ee8f0af488963e1656716ae08268aea6b65295a Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 16 Oct 2021 23:16:50 +0200 Subject: [PATCH 014/629] rm id-gen.sh --- modules/kafka/id-gen.sh | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 modules/kafka/id-gen.sh diff --git a/modules/kafka/id-gen.sh b/modules/kafka/id-gen.sh deleted file mode 100644 index 3473494..0000000 --- a/modules/kafka/id-gen.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -DELIM='-' - -WORDS="$(xkcdpass --numwords=2 --delimiter="$DELIM" --valid-chars='\w' --case='first')" - -NUMS=$(( (RANDOM + 10) % 100 )) - -echo "Generated ID $WORDS$DELIM$NUMS" - -echo "$WORDS$DELIM$NUMS" - -exit 0 \ No newline at end of file From f6781df4f8b06eb712cdd28b495ecaecc739ae40 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 16 Oct 2021 23:36:33 +0200 Subject: [PATCH 015/629] rm dupe'd command, move comment --- modules/kafka/docker-compose.yml | 2 +- modules/kafka/kafka.Dockerfile | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/modules/kafka/docker-compose.yml b/modules/kafka/docker-compose.yml index 55217c6..d7ab38b 100644 --- a/modules/kafka/docker-compose.yml +++ b/modules/kafka/docker-compose.yml @@ -11,4 +11,4 @@ services: KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/3.0.0/kafka_2.13-3.0.0.tgz" ports: - "9092:9092" - - "9093:9093" \ No newline at end of file + - "9093:9093" diff --git a/modules/kafka/kafka.Dockerfile b/modules/kafka/kafka.Dockerfile index 5297d14..88a8d8a 100644 --- a/modules/kafka/kafka.Dockerfile +++ b/modules/kafka/kafka.Dockerfile @@ -15,6 +15,8 @@ RUN echo "Downloading Kafka from $KAFKA_DL_URL" \ && ls -la +# KRaft (aka KIP-500) mode Preview Release +# https://github.com/apache/kafka/blob/041b76dc57f096be2a2d7532d917122992bff6e2/config/kraft/README.md FROM openjdk:11 WORKDIR /kafka @@ -27,20 +29,15 @@ VOLUME /tmp/kraft-combined-logs # listeners, controller.quorum.voters EXPOSE 9092, 9093 -# KRaft (aka KIP-500) mode Preview Release -# https://github.com/apache/kafka/blob/041b76dc57f096be2a2d7532d917122992bff6e2/config/kraft/README.md - # Generate a cluster ID RUN echo "$(./bin/kafka-storage.sh random-uuid)" > cluster_id \ && echo "Generated a Kafka Cluster ID: $(cat cluster_id)" # Format storage directories -RUN ./bin/kafka-storage.sh format -t "$(cat cluster_id)" -c ./config/kraft/server.properties - -# launch the broker in KRaft mode, which means that it runs without ZooKeeper RUN ./bin/kafka-storage.sh format \ --ignore-formatted \ --config ./config/kraft/server.properties \ --cluster-id "$(cat cluster_id)" +# launch the broker in KRaft mode, which means that it runs without ZooKeeper ENTRYPOINT ["./bin/kafka-server-start.sh", "./config/kraft/server.properties"] From 16137e5435fbec0a4ecadac43997ada2ab018f32 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sat, 16 Oct 2021 23:37:50 +0200 Subject: [PATCH 016/629] add kafka gradle module --- modules/kafka/build.gradle.kts | 3 +++ settings.gradle.kts | 1 + 2 files changed, 4 insertions(+) diff --git a/modules/kafka/build.gradle.kts b/modules/kafka/build.gradle.kts index e69de29..142fb17 100644 --- a/modules/kafka/build.gradle.kts +++ b/modules/kafka/build.gradle.kts @@ -0,0 +1,3 @@ +plugins { + id("dev.adamko.factoriowebmap.archetype.base") +} diff --git a/settings.gradle.kts b/settings.gradle.kts index f77beda..c681010 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,6 +5,7 @@ include( // ":modules:mod2", ":modules:server", ":modules:kt-rcon", + ":modules:kafka", ) enableFeaturePreview("VERSION_CATALOGS") From b8de97afc9190d9bdf444f9dc888e86b723a4bb1 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sun, 17 Oct 2021 17:56:19 +0200 Subject: [PATCH 017/629] renaming, formatting, comments, typescript source set experiment, run Factorioi client experiment, download Factorio API json --- modules/mod/build.gradle.kts | 138 ++++++++++++++++++++++++----------- 1 file changed, 95 insertions(+), 43 deletions(-) diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index 5124676..81595ce 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -8,7 +8,6 @@ plugins { val projectId: String by project.extra - val tsSrcDir = layout.projectDirectory.dir("src/main/typescript") val modBuildDir = layout.buildDirectory.dir(projectId).get() @@ -17,45 +16,46 @@ node { } val tstlTask = tasks.register("typescriptToLua") { - description = "Typescript To Lua" + description = "Convert Typescript To Lua" group = projectId dependsOn(tasks.npmInstall) execOverrides { standardOutput = System.out } - npmCommand.set(listOf( - "run", - "build", -// "--workspace=factorio-web-map-mod", - )) + npmCommand.set(listOf("run", "build")) - inputs.dir(node.nodeProjectDir) + inputs.dir(node.nodeProjectDir.asFileTree) + .skipWhenEmpty() + .withPropertyName("sourceFiles") + .withPathSensitivity(PathSensitivity.RELATIVE) val outputDir = modBuildDir.dir("typescriptToLua") - outputs.dir(outputDir) args.set(parseSpaceSeparatedArgs("-- --outDir $outputDir")) -// args.set(listOf( -// "--", -// "--outDir $outputDir", -// "--workspace=factorio-web-map-mod", -// )) + outputs.dir(outputDir) + .withPropertyName("outputDir") + ignoreExitValue.set(false) -// workingDir.set(tsSrcDir.asFile) -// inputs.dir("node_modules") -// inputs.dir(fileTree("src")) -// inputs.files( -// "tsconfig.json", -// "package.json", -// ) -// outputs.dir("$buildDir/factorio-web-map/") -// outputs.dir("$buildDir/npm-output") -// outputs.upToDateWhen { false } } +//val typescriptSrc = +// project.objects.sourceDirectorySet("typescript", "typescript").apply { +// srcDir( +// layout.projectDirectory.dir("src/main/typescript") +// ) +// destinationDirectory.set( +// modBuildDir.dir("typescriptToLua") +// ) +// compiledBy(tstlTask) { +// project.objects.directoryProperty().apply { +// set( modBuildDir.dir("typescriptToLua")) +// } +// } +// } + val modPackageTask = tasks.register("package") { - description = "Package mod" + description = "Package mod files into ZIP" group = projectId dependsOn(tstlTask) @@ -63,14 +63,14 @@ val modPackageTask = tasks.register("package") { from( layout.projectDirectory.dir("src/main/resources/mod-data"), rootProject.layout.projectDirectory.file("LICENSE"), - tstlTask, + tstlTask.get().outputs.files.filter { it.extension == "lua" }, ) into(rootProject.name) // Factorio required format is: // - filename: `mod-name_version.zip` - // - zip contains dir `mod-name` + // - zip contains one directory, `mod-name` archiveFileName.set("${rootProject.name}_${rootProject.version}.zip") destinationDirectory.set(modBuildDir.dir("dist")) } @@ -79,7 +79,7 @@ val modPackageTask = tasks.register("package") { val copyModToServerTask = tasks.register("copyModToServer") { description = "Copy the mod to the Factorio Docker server" - group = projectId + group = "$projectId.factorioServer" dependsOn(modPackageTask) @@ -87,9 +87,31 @@ val copyModToServerTask = tasks.register("copyModToServer") { into(layout.projectDirectory.dir("src/test/resources/server/data/mods").asFile) } +val serverUpTask = tasks.register("dockerUp") { + group = "$projectId.factorioServer" + + workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile + commandLine = parseSpaceSeparatedArgs("docker-compose up") +} + + +//val serverRestartTask = tasks.register("dockerRestart") { +// group = "$projectId.factorioServer" +// +// workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile +// commandLine = parseSpaceSeparatedArgs("docker-compose restart") +//} + +tasks.register("dockerStop") { + group = "$projectId.factorioServer" + + workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile + commandLine = parseSpaceSeparatedArgs("docker-compose stop") +} + val copyModToClientTask = tasks.register("copyModToClient") { description = "Copy the mod to the Factorio client" - group = projectId + group = "$projectId.factorioClient" dependsOn(modPackageTask) @@ -97,25 +119,55 @@ val copyModToClientTask = tasks.register("copyModToClient") { into("""D:\Users\Adam\AppData\Roaming\Factorio\mods""") } -val serverRestartTask = tasks.register("serverRestart") { - group = projectId - - workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile - commandLine = parseSpaceSeparatedArgs("docker-compose restart") -} - -tasks.register("serverStop") { - group = projectId - - workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile - commandLine = parseSpaceSeparatedArgs("docker-compose stop") -} +//val factorioClientLaunch = tasks.register("launch") { +// description = "Run Factorio client" +// group = "$projectId.factorioClient" +// +// dependsOn( +// serverRestartTask, +// copyModToClientTask +// ) +// +//// workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile +// commandLine = parseSpaceSeparatedArgs( +// """explorer "steam://rungameid/427520 --mp-connect localhost" """ +// ) +//} val launch = tasks.register("modLauncher") { + description = "Build the mod, upload to Server and Client, and start both" group = projectId dependsOn( copyModToServerTask, copyModToClientTask, - serverRestartTask, + serverUpTask, +// factorioClientLaunch, ) } + +tasks.register("downloadFactorioApiDocs") { + group = projectId + + val target = uri("https://lua-api.factorio.com/latest/runtime-api.json") + val apiFilename = File(target.path).name + val downloadedFile = file(temporaryDir.path + "/" + apiFilename) + + val apiFile = modBuildDir.file(apiFilename) + outputs.file(apiFile) + + doLast { + + ant.invokeMethod("get", mapOf( + "src" to target, + "dest" to downloadedFile, + "verbose" to true, + )) + + val json = downloadedFile.readText() + val prettyJson = groovy.json.JsonOutput.prettyPrint(json) + + apiFile.asFile.writeText(prettyJson) + + logger.lifecycle("Downloaded Factorio API json: $apiFile") + } +} From 9238140a4cc02aadf6bde6c385a64cfc8d64ce46 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Sun, 17 Oct 2021 19:47:39 +0200 Subject: [PATCH 018/629] output files to dir --- modules/mod/build.gradle.kts | 33 +- modules/mod/src/main/typescript/events.ts | 52 +- .../mod/src/main/typescript/package-lock.json | 1218 +---------------- modules/mod/src/main/typescript/package.json | 34 +- modules/mod/src/main/typescript/tsconfig.json | 53 +- .../test/resources/server/docker-compose.yml | 6 +- 6 files changed, 139 insertions(+), 1257 deletions(-) diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index 81595ce..3634cba 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -25,7 +25,7 @@ val tstlTask = tasks.register("typescriptToLua") { npmCommand.set(listOf("run", "build")) - inputs.dir(node.nodeProjectDir.asFileTree) + inputs.dir(node.nodeProjectDir) .skipWhenEmpty() .withPropertyName("sourceFiles") .withPathSensitivity(PathSensitivity.RELATIVE) @@ -35,8 +35,12 @@ val tstlTask = tasks.register("typescriptToLua") { outputs.dir(outputDir) .withPropertyName("outputDir") - ignoreExitValue.set(false) + + doFirst("clean") { + delete(outputDir) + } + } //val typescriptSrc = @@ -63,7 +67,7 @@ val modPackageTask = tasks.register("package") { from( layout.projectDirectory.dir("src/main/resources/mod-data"), rootProject.layout.projectDirectory.file("LICENSE"), - tstlTask.get().outputs.files.filter { it.extension == "lua" }, + tstlTask, ) into(rootProject.name) @@ -87,13 +91,23 @@ val copyModToServerTask = tasks.register("copyModToServer") { into(layout.projectDirectory.dir("src/test/resources/server/data/mods").asFile) } +val serverStopTask = tasks.register("dockerStop") { + group = "$projectId.factorioServer" + + mustRunAfter(copyModToServerTask) + + workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile + commandLine = parseSpaceSeparatedArgs("docker-compose stop") +} + val serverUpTask = tasks.register("dockerUp") { group = "$projectId.factorioServer" - workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile - commandLine = parseSpaceSeparatedArgs("docker-compose up") -} + dependsOn(copyModToServerTask, serverStopTask) + workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile + commandLine = parseSpaceSeparatedArgs("docker-compose up -d") +} //val serverRestartTask = tasks.register("dockerRestart") { // group = "$projectId.factorioServer" @@ -102,13 +116,6 @@ val serverUpTask = tasks.register("dockerUp") { // commandLine = parseSpaceSeparatedArgs("docker-compose restart") //} -tasks.register("dockerStop") { - group = "$projectId.factorioServer" - - workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile - commandLine = parseSpaceSeparatedArgs("docker-compose stop") -} - val copyModToClientTask = tasks.register("copyModToClient") { description = "Copy the mod to the Factorio client" group = "$projectId.factorioClient" diff --git a/modules/mod/src/main/typescript/events.ts b/modules/mod/src/main/typescript/events.ts index 946f1b9..67dee7d 100644 --- a/modules/mod/src/main/typescript/events.ts +++ b/modules/mod/src/main/typescript/events.ts @@ -1,3 +1,26 @@ +// import {Kafka, Producer} from "kafkajs"; + +// const {Kafka} = require("kafkajs") +// import {Kafka, Producer} from "kafkajs/types" +// import {Data, Mods} from "typed-factorio/settings/types" +// import { events } from "typed-factorio/generated" + +// declare const factorioData: Data +// declare const factorioMods: Mods + + +// const eventEnum = { +// thingType: Object.values(defines.events) +// } + +const SERVER_ID : uint = 0 + +function outputEvent(filename: string, event: table) { + let json : string = game.table_to_json(event) + // game.print(`Creating file ${filename}, content: ${json}`) + game.write_file(filename, json, false, SERVER_ID) +} + script.on_event( [defines.events.on_pre_build, defines.events.on_player_dropped_item], (e: OnPreBuildEvent | OnPlayerDroppedItemEvent) => { @@ -5,21 +28,30 @@ script.on_event( } ); +script.on_event( + defines.events.on_player_joined_game, + (e: OnPlayerJoinedGameEvent) => { + let filename : string = `${e.name}/${e.tick}_${e.player_index}` + outputEvent(filename, e) + } +) + +script.on_event( + defines.events.on_player_changed_position, + (e: OnPlayerJoinedGameEvent) => { + let filename : string = `${e.name}/${e.tick}_${e.player_index}` + outputEvent(filename, e) + } +) + script.on_event( defines.events.on_tick, (e: OnTickEvent) => { if (e.tick % 60 == 0) { let msg = "test mod tick: " + e.tick + "\n" - // game.print(msg) - game.write_file("tick.log", msg, true) - - - let groups = game.permissions.groups.map(val => { - return val.name + "\n" + serpent.block(val) - }).join("\n") - - game.write_file("permissions.json", groups, false) - // game.write_file("permissions-groups.json", serpent.block(game.permissions.groups), false) + game.write_file("tick.log", msg, true, SERVER_ID) + let filename : string = `${e.name}/${e.tick}` + outputEvent(filename, e) } } ); diff --git a/modules/mod/src/main/typescript/package-lock.json b/modules/mod/src/main/typescript/package-lock.json index d5b6264..8385974 100644 --- a/modules/mod/src/main/typescript/package-lock.json +++ b/modules/mod/src/main/typescript/package-lock.json @@ -4,365 +4,10 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@discoveryjs/json-ext": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz", - "integrity": "sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA==", - "dev": true - }, - "@types/eslint": { - "version": "7.28.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.1.tgz", - "integrity": "sha512-XhZKznR3i/W5dXqUhgU9fFdJekufbeBd5DALmkuXoeFcjbQcPk+2cL+WLHf6Q81HWAnM2vrslIHpGVyCAviRwg==", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==", - "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "0.0.47", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz", - "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==", - "dev": true - }, - "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, "@types/node": { - "version": "16.10.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.3.tgz", - "integrity": "sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ==", - "dev": true - }, - "@webassemblyjs/ast": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", - "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", - "dev": true, - "requires": { - "@webassemblyjs/helper-numbers": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", - "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", - "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", - "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==", - "dev": true - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", - "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", - "dev": true, - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", - "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", - "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", - "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", - "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", - "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", - "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/helper-wasm-section": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-opt": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "@webassemblyjs/wast-printer": "1.11.0" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", - "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", - "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", - "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", - "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webpack-cli/configtest": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.0.tgz", - "integrity": "sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==", - "dev": true - }, - "@webpack-cli/info": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.0.tgz", - "integrity": "sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==", - "dev": true, - "requires": { - "envinfo": "^7.7.3" - } - }, - "@webpack-cli/serve": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.0.tgz", - "integrity": "sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==", - "dev": true - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", - "dev": true - }, - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "browserslist": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.3.tgz", - "integrity": "sha512-59IqHJV5VGdcJZ+GZ2hU5n4Kv3YiASzW6Xk5g9tf5a/MAzGeFwgGWU39fVzNIOVcgB3+Gp+kiQu0HEfTVU/3VQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001264", - "electron-to-chromium": "^1.3.857", - "escalade": "^3.1.1", - "node-releases": "^1.1.77", - "picocolors": "^0.2.1" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001265", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001265.tgz", - "integrity": "sha512-YzBnspggWV5hep1m9Z6sZVLOt7vrju8xWooFAgN6BA5qvy98qPAPb7vNUzypFaoh2pb3vlfzbDO8tB57UPGbtw==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", - "dev": true - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "css-loader": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.6.tgz", - "integrity": "sha512-0wyN5vXMQZu6BvjbrPdUJvkCzGEO24HC7IS7nW4llc6BBFC+zwR9CKtYGv63Puzsg10L/o12inMY5/2ByzfD6w==", - "dev": true, - "requires": { - "icss-utils": "^5.1.0", - "loader-utils": "^2.0.0", - "postcss": "^8.2.15", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.1.0", - "schema-utils": "^3.0.0", - "semver": "^7.3.5" - } - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.864", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.864.tgz", - "integrity": "sha512-v4rbad8GO6/yVI92WOeU9Wgxc4NA0n4f6P1FvZTY+jyY7JHEhw3bduYu60v3Q1h81Cg6eo4ApZrFPuycwd5hGw==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true + "version": "12.20.33", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz", + "integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw==" }, "enhanced-resolve": { "version": "5.8.3", @@ -373,131 +18,11 @@ "tapable": "^2.2.0" } }, - "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", - "dev": true - }, - "es-module-lexer": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", - "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", - "dev": true - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "format-util": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/format-util/-/format-util-1.0.5.tgz", - "integrity": "sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg==", - "dev": true - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, "graceful-fs": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", @@ -511,49 +36,6 @@ "function-bind": "^1.1.1" } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true - }, - "import-local": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", - "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true - }, "is-core-module": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz", @@ -562,360 +44,16 @@ "has": "^1.0.3" } }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "jest-worker": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.2.5.tgz", - "integrity": "sha512-HTjEPZtcNKZ4LnhSp02NEH4vE+5OpJ0EsOWYvGQpHgUMLngydESAAMH5Wd/asPf29+XUDQZszxpLg1BkIIA2aw==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", - "dev": true - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, "lua-types": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.11.0.tgz", "integrity": "sha512-J/8qHrOjkZuPBDhnuAg0DWoaJEImqXNzgEnUigCTVrSVCcchM5Y5zpcI3aWAZPhuZlb0QKC/f3nc7VGmZmBg7w==" }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", - "dev": true - }, - "mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", - "dev": true, - "requires": { - "mime-db": "1.50.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "nanoid": { - "version": "3.1.29", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.29.tgz", - "integrity": "sha512-dW2pUSGZ8ZnCFIlBIA31SV8huOGCHb6OwzVCc7A69rb/a+SgPBwfmLvK5TKQ3INPbRkcI8a/Owo0XbiTNH19wg==", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node-releases": { - "version": "1.1.77", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.77.tgz", - "integrity": "sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - }, - "dependencies": { - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - } - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "postcss": { - "version": "8.3.9", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.9.tgz", - "integrity": "sha512-f/ZFyAKh9Dnqytx5X62jgjhhzttjZS7hMsohcI7HEI5tjELX/HxCy3EFhsRxyzGvrzFF+82XPvCS8T9TFleVJw==", - "dev": true, - "requires": { - "nanoid": "^3.1.28", - "picocolors": "^0.2.1", - "source-map-js": "^0.6.2" - } - }, - "postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true - }, - "postcss-modules-local-by-default": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", - "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", - "dev": true, - "requires": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.4" - } - }, - "postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dev": true, - "requires": { - "icss-utils": "^5.0.0" - } - }, - "postcss-selector-parser": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", - "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", - "dev": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", - "dev": true, - "requires": { - "resolve": "^1.9.0" - } - }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -925,223 +63,25 @@ "path-parse": "^1.0.6" } }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, "source-map": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" }, - "source-map-js": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", - "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==", - "dev": true - }, - "source-map-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.0.tgz", - "integrity": "sha512-GKGWqWvYr04M7tn8dryIWvb0s8YM41z82iQv01yBtIylgxax0CwvSy6gc2Y02iuXwEfGWRlMicH0nvms9UZphw==", - "dev": true, - "requires": { - "abab": "^2.0.5", - "iconv-lite": "^0.6.2", - "source-map-js": "^0.6.2" - } - }, - "source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "style-loader": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz", - "integrity": "sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==", - "dev": true, - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, "tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, - "terser": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.9.0.tgz", - "integrity": "sha512-h5hxa23sCdpzcye/7b8YqbE5OwKca/ni0RQz1uRX3tGh8haaGHqcuSqbGRybuAKNdntZ0mDgFNXPJ48xQ2RXKQ==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.20" - } - }, - "terser-webpack-plugin": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.2.4.tgz", - "integrity": "sha512-E2CkNMN+1cho04YpdANyRrn8CyN4yMy+WdFKZIySFZrGXZxJwJP6PMNGGc/Mcr6qygQHUUqRxnAPmi0M9f00XA==", - "dev": true, - "requires": { - "jest-worker": "^27.0.6", - "p-limit": "^3.1.0", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.2" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, "typed-factorio": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.7.1.tgz", - "integrity": "sha512-2WdnkUuWnVk2SDV3TmabDsnfpw5kvKOkg/2br7bcJ1qzAXT4dgrMK/HwL5bUubKf67xTi1rKykaQ/qjhP3TqLw==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.7.3.tgz", + "integrity": "sha512-Y0J6dqRy1rg3kPlFUX5Ca5nU7CcQgelcY4nKkk6fox17ZCAoOZx1i2ynj/JPuhQsTRsuMV0kQTS1eQKF8bzdaQ==", "requires": { "lua-types": "^2.10.1", - "typescript": "~4.3.5", "typescript-to-lua": "^1.0.0" - }, - "dependencies": { - "typescript": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", - "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==" - } } }, - "typescript": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", - "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==" - }, "typescript-to-lua": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.0.1.tgz", @@ -1159,152 +99,6 @@ "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==" } } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "watchpack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz", - "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==", - "dev": true, - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "webpack": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.38.1.tgz", - "integrity": "sha512-OqRmYD1OJbHZph6RUMD93GcCZy4Z4wC0ele4FXyYF0J6AxO1vOSuIlU1hkS/lDlR9CDYBz64MZRmdbdnFFoT2g==", - "dev": true, - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.47", - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/wasm-edit": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "acorn": "^8.2.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.4.0", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.1", - "watchpack": "^2.2.0", - "webpack-sources": "^2.3.0" - } - }, - "webpack-cli": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.7.1.tgz", - "integrity": "sha512-DJPd63AY53KXWOaD8cB8CaHR0epVP4O4GBIAk6wCPQHJugrAQ0B5kUkCg0c9vkIrD2kA6CXCmtWqKQsiVTo15A==", - "dev": true, - "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.0.4", - "@webpack-cli/info": "^1.3.0", - "@webpack-cli/serve": "^1.5.0", - "colorette": "^1.2.1", - "commander": "^7.0.0", - "execa": "^5.0.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "v8-compile-cache": "^2.2.0", - "webpack-merge": "^5.7.3" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - } - } - }, - "webpack-merge": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", - "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", - "dev": true, - "requires": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - } - }, - "webpack-sources": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", - "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", - "dev": true, - "requires": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true } } } diff --git a/modules/mod/src/main/typescript/package.json b/modules/mod/src/main/typescript/package.json index 8690038..d6f981f 100644 --- a/modules/mod/src/main/typescript/package.json +++ b/modules/mod/src/main/typescript/package.json @@ -6,25 +6,31 @@ "build": "tstl", "dev": "tstl --watch" }, - "devDependencies": { + "engines": { + "node": ">=10.13.0" + }, + "devDependencies": {}, + "dependencies": { + "lua-types": "^2.11.0", + "@types/node": "^12.0.8", + "typescript-to-lua": "1.0.1", + "typed-factorio": "0.7.3" + }, + "peerDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": [], + "//": { + "typescript": "4.4.3", + "@types/node": "^13.7.7", + "kafkajs": "1.15.0", + "lua-types": "^2.11.0", + "react": "17.0.2", + "react-dom": "17.0.2", "webpack": "5.38.1", "webpack-cli": "4.7.1", "format-util": "1.0.5", "source-map-loader": "3.0.0", "css-loader": "5.2.6", "style-loader": "2.0.0" - }, - "dependencies": { - "react": "17.0.2", - "typescript-to-lua": "1.0.1", - "typed-factorio": "0.7.1", - "lua-types": "2.11.0", - "typescript": "4.4.3" - }, - "peerDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": [], - "//": { - "react-dom": "17.0.2" } } diff --git a/modules/mod/src/main/typescript/tsconfig.json b/modules/mod/src/main/typescript/tsconfig.json index 43cb2d2..a6fa1f8 100644 --- a/modules/mod/src/main/typescript/tsconfig.json +++ b/modules/mod/src/main/typescript/tsconfig.json @@ -1,17 +1,60 @@ { + "$schema": "https://raw.githubusercontent.com/TypeScriptToLua/vscode-typescript-to-lua/master/tsconfig-schema.json", "compilerOptions": { - "target": "esnext", + "target": "es2019", "lib": [ - "esnext" + "es2019" ], + "module": "commonjs", "moduleResolution": "node", "types": [ + "typescript-to-lua/language-extensions", + "lua-types/5.2", "typed-factorio/runtime" ], - "strict": true + "explainFiles": true, + "forceConsistentCasingInFileNames": true, + "listEmittedFiles": true, + "listFiles": true, + "noImplicitAny": true, + "noImplicitThis": true, + "sourceMap": false, + "strict": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "traceResolution": true, }, "tstl": { - "luaTarget": "JIT", - "tstlVerbose": true + "luaTarget": "5.2", + "tstlVerbose": true, + "noHeader": true, + "luaLibImport" : "require", + }, + "//": { + "noResolve": true, + "newLine": "lf", + "exclude": [ + "node_modules" + ], + "exactOptionalPropertyTypes": true, + "luaTarget": "5.2", + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "types": [ + "node", + "typed-factorio/runtime", + "lua-types/5.2" + ], + "typeRoots": [ + "node_modules/@types" + ], + "//": "lua-types/5.2", + "luaLibImport" : "inline", + "noImplicitSelf": true, + + "sourceMapTraceback": true, + + "luaBundle " : "bundle.lua", + "luaBundleEntry " : "bundleEntry.lua" } } diff --git a/modules/mod/src/test/resources/server/docker-compose.yml b/modules/mod/src/test/resources/server/docker-compose.yml index ff0775c..8a6a05d 100644 --- a/modules/mod/src/test/resources/server/docker-compose.yml +++ b/modules/mod/src/test/resources/server/docker-compose.yml @@ -8,11 +8,11 @@ services: restart: "unless-stopped" ports: - "34197:34197/udp" # factorio - - "27715:27715/tcp" # rcon + - "27015:27015/tcp" # rcon volumes: - "./data:/factorio" - environment: - RCON_PORT: 27715 +# environment: +# RCON_PORT: 27715 # environment: # - PUID=1000 # - PGID=1000 From 2e15f83c903cab7aa5678ca3e243dd3a75289686 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 20 Oct 2021 00:51:35 +0200 Subject: [PATCH 019/629] readme, convert factorio objects to tables, other refactors --- README.md | 22 +++++ .../archetype/kotlin-js.gradle.kts | 23 ++--- modules/mod/build.gradle.kts | 3 +- modules/mod/src/main/typescript/events.ts | 92 ++++++++++++++----- .../mod/src/main/typescript/ext/LuaArray.ts | 16 ++++ .../mod/src/main/typescript/package-lock.json | 6 +- modules/mod/src/main/typescript/package.json | 2 +- .../mod/src/main/typescript/serdes/serdes.ts | 86 +++++++++++++++++ modules/mod/src/main/typescript/tsconfig.json | 3 +- modules/mod2/build.gradle.kts | 9 +- 10 files changed, 215 insertions(+), 47 deletions(-) create mode 100644 modules/mod/src/main/typescript/ext/LuaArray.ts create mode 100644 modules/mod/src/main/typescript/serdes/serdes.ts diff --git a/README.md b/README.md index e69de29..9606faa 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,22 @@ +1. output events from Factorio into Kafka. + 1. Factorio mod listens to events. + 2. For each event, it emits a file. + 3. A Kafka Connector consumes each file. +2. Factorio Web Map reads data from Kafka + 1. converts data to images + 2. hosts a web map + +todo + +* add settings + * is active - whether files are exported or not + * delete files - clean up all files + * tick-rate - how often reports are generated ( + * requires on some sort of in-mod cache of map) + * also divide by game-speed? to keep ratio the same + +to investigate: + +* https://github.com/starwing/lua-protobuf +* https://github.com/grafi-tt/lunajson + diff --git a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts index 2dcac1b..879e2df 100644 --- a/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts +++ b/buildSrc/src/main/kotlin/dev/adamko/factoriowebmap/archetype/kotlin-js.gradle.kts @@ -19,27 +19,22 @@ plugins { kotlin { js(IR) { - binaries.executable() useCommonJs() nodejs() -// -//// compilations.all { -// compilations["main"].apply { -// packageJson { -// customField( -// "scripts", -// mapOf( -// "build" to "tstl", -// "dev" to "tstl --watch", -// ) -// ) -// } -// } } } +dependencies { + val kotlinWrappersVersion = "0.0.1-pre.259-kotlin-1.5.31" + implementation( + project.dependencies.enforcedPlatform( + "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" + ) + ) +} + val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class) //fun NpmTask.setNodeModulesPath(path: String): Unit = diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index 3634cba..41c79e4 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -103,7 +103,8 @@ val serverStopTask = tasks.register("dockerStop") { val serverUpTask = tasks.register("dockerUp") { group = "$projectId.factorioServer" - dependsOn(copyModToServerTask, serverStopTask) + mustRunAfter(copyModToServerTask) + dependsOn(serverStopTask) workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile commandLine = parseSpaceSeparatedArgs("docker-compose up -d") diff --git a/modules/mod/src/main/typescript/events.ts b/modules/mod/src/main/typescript/events.ts index 67dee7d..5d07a8d 100644 --- a/modules/mod/src/main/typescript/events.ts +++ b/modules/mod/src/main/typescript/events.ts @@ -8,39 +8,80 @@ // declare const factorioData: Data // declare const factorioMods: Mods - // const eventEnum = { // thingType: Object.values(defines.events) // } -const SERVER_ID : uint = 0 +import {JsonTable, Serdes} from "./serdes/serdes" -function outputEvent(filename: string, event: table) { - let json : string = game.table_to_json(event) - // game.print(`Creating file ${filename}, content: ${json}`) - game.write_file(filename, json, false, SERVER_ID) +// const SERVER_ID: uint = 0 +// const EVENT_FILE_DIR: string = "events" + +function playerEvent(tick: uint, player_index: uint, eventType: string) { + let player: LuaPlayer = game.players[player_index] + + let filename: string = table.concat([player.index, eventType, tick], "_") + let data = Serdes.Player.playerToTable(player) + outputEventFile(player.object_name + "/" + filename, data) + + if (player.character != undefined) { + entityEvent(tick, player.character, eventType) + + for (const char of player.get_associated_characters()) { + if (char != undefined) { + entityEvent(tick, char, eventType) + } + } + + } } -script.on_event( - [defines.events.on_pre_build, defines.events.on_player_dropped_item], - (e: OnPreBuildEvent | OnPlayerDroppedItemEvent) => { - game.print("player " + e.player_index + " dropped item, tick:" + e.tick) - } -); +function entityEvent(tick: uint, entity: LuaEntity, eventType: string) { + if (entity.unit_number != undefined && entity.unit_number != 0) { + let filename: string = table.concat([entity.unit_number, eventType, tick], "_") + let data = Serdes.Entity.entityToTable(entity) + outputEventFile(entity.object_name + "/" + filename, data) + } +} +function surfaceEvent(tick: uint, surface: LuaSurface, eventType: string) { + let filename: string = + surface.object_name + "/" + table.concat([surface.index, eventType, tick], "_") + let data = Serdes.Surface.surfaceToTable(surface) + outputEventFile(filename, data) +} + +function outputEventFile(filename: string, obj: JsonTable) { + let data = game.table_to_json(obj) + // game.write_file(EVENT_FILE_DIR + "/" + filename, data, false, SERVER_ID) + localised_print(`!===== ${filename} | ${data} =====!`) +} + +// script.on_event( +// [defines.events.on_pre_build, defines.events.on_player_dropped_item], +// (e: OnPreBuildEvent | OnPlayerDroppedItemEvent) => { +// game.print("player " + e.player_index + " dropped item, tick:" + e.tick) +// } +// ); + +script.on_event( + defines.events.on_player_mined_entity, + (e: OnPlayerMinedEntityEvent) => { + entityEvent(e.tick, e.entity, "on_player_mined_entity") + playerEvent(e.tick, e.player_index, "on_player_mined_entity") + } +) script.on_event( defines.events.on_player_joined_game, (e: OnPlayerJoinedGameEvent) => { - let filename : string = `${e.name}/${e.tick}_${e.player_index}` - outputEvent(filename, e) + playerEvent(e.tick, e.player_index, "on_player_joined_game") } ) script.on_event( defines.events.on_player_changed_position, - (e: OnPlayerJoinedGameEvent) => { - let filename : string = `${e.name}/${e.tick}_${e.player_index}` - outputEvent(filename, e) + (e: OnPlayerChangedPositionEvent) => { + playerEvent(e.tick, e.player_index, "on_player_changed_position") } ) @@ -48,10 +89,19 @@ script.on_event( defines.events.on_tick, (e: OnTickEvent) => { if (e.tick % 60 == 0) { - let msg = "test mod tick: " + e.tick + "\n" - game.write_file("tick.log", msg, true, SERVER_ID) - let filename : string = `${e.name}/${e.tick}` - outputEvent(filename, e) + + game.surfaces + + for (const [index,] of pairs(game.surfaces)) { + let surface = game.surfaces[index] + surfaceEvent(e.tick, surface, "on_tick") + } + + // let filename: string = table.concat([entity.unit_number, eventType, tick], "_") + // let msg = "test mod tick: " + e.tick + "\n" + // game.write_file("tick.log", msg, true, SERVER_ID) + // let filename: string = `OnTickEvent/${e.tick}` + // outputEvent(filename, e) } } ); diff --git a/modules/mod/src/main/typescript/ext/LuaArray.ts b/modules/mod/src/main/typescript/ext/LuaArray.ts new file mode 100644 index 0000000..e24e759 --- /dev/null +++ b/modules/mod/src/main/typescript/ext/LuaArray.ts @@ -0,0 +1,16 @@ +// declare interface LuaArray extends LuaTable { +// } + +// = LuaTable; + +// declare type LuaArrayConstructor = (new () => LuaArray) + +// declare const LuaArray: LuaArrayConstructor + +// class LuaArray extends LuaTable { +// add(val: TValue) { +// this.set(this.length(), val) +// } +// } + +// declare type LuaArray & LuaTable \ No newline at end of file diff --git a/modules/mod/src/main/typescript/package-lock.json b/modules/mod/src/main/typescript/package-lock.json index 8385974..6aea416 100644 --- a/modules/mod/src/main/typescript/package-lock.json +++ b/modules/mod/src/main/typescript/package-lock.json @@ -74,9 +74,9 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "typed-factorio": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.7.3.tgz", - "integrity": "sha512-Y0J6dqRy1rg3kPlFUX5Ca5nU7CcQgelcY4nKkk6fox17ZCAoOZx1i2ynj/JPuhQsTRsuMV0kQTS1eQKF8bzdaQ==", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.7.4.tgz", + "integrity": "sha512-IhvydBF1eNtlV8WRJWuu64ySOoMCbNujLX/kvqNMaWL+tcLmORghuQZggCbhuX2HI4wVL+UgGpTwG4xicOQM9A==", "requires": { "lua-types": "^2.10.1", "typescript-to-lua": "^1.0.0" diff --git a/modules/mod/src/main/typescript/package.json b/modules/mod/src/main/typescript/package.json index d6f981f..d6f6e1b 100644 --- a/modules/mod/src/main/typescript/package.json +++ b/modules/mod/src/main/typescript/package.json @@ -14,7 +14,7 @@ "lua-types": "^2.11.0", "@types/node": "^12.0.8", "typescript-to-lua": "1.0.1", - "typed-factorio": "0.7.3" + "typed-factorio": "0.7.4" }, "peerDependencies": {}, "optionalDependencies": {}, diff --git a/modules/mod/src/main/typescript/serdes/serdes.ts b/modules/mod/src/main/typescript/serdes/serdes.ts new file mode 100644 index 0000000..2396228 --- /dev/null +++ b/modules/mod/src/main/typescript/serdes/serdes.ts @@ -0,0 +1,86 @@ +export type PrimitiveType = number | string | boolean +export type JsonArray = TValue[] +export type JsonTableValueType = + PrimitiveType + | JsonTable + | JsonArray +export type JsonTable = LuaTable // & table +// export type JsonArray = LuaArray // & table + + +export namespace Serdes { + + export namespace Player { + + export function playerToTable(player: LuaPlayer): JsonTable { + let table = new LuaTable() + + table.set("name", player.name) + let charIds: JsonArray = Entity.entitiesToUnitNumbers(player.get_associated_characters()) + table.set("characterIds", charIds) + + return table + } + + } + + export namespace Entity { + + export function entityToTable(entity: LuaEntity): JsonTable { + let table = new LuaTable() + + if (entity.player?.index != null) { + table.set("playerId", entity.player?.index) + } + table.set("type", entity.type) + table.set("active", entity.active) + + if (entity.health != null) { + table.set("health", entity.health) + } + + table.set("surfaceId", entity.surface.index) + table.set("position", DataClasses.positionTableToTable(entity.position)) + + return table + } + + export function entitiesToUnitNumbers(entities: LuaEntity[]): JsonArray { + let array: number[] = [] + let j: number = 0 + for (let i = 0; i < entities.length; i++) { + let unitNum = entities[i].unit_number + if (unitNum != null) { + array[j++] = unitNum + } + } + return array + } + + } + + export namespace Surface { + + export function surfaceToTable(surface: LuaSurface): JsonTable { + let table = new LuaTable() + + table.set("name", surface.name) + table.set("index", surface.index) + table.set("daytime", surface.daytime) + + return table + } + + } + + export namespace DataClasses { + + export function positionTableToTable(positionTable: PositionTable): JsonTable { + let table = new LuaTable() + table.set("x", positionTable.x) + table.set("y", positionTable.y) + return table + } + + } +} diff --git a/modules/mod/src/main/typescript/tsconfig.json b/modules/mod/src/main/typescript/tsconfig.json index a6fa1f8..dbd7f66 100644 --- a/modules/mod/src/main/typescript/tsconfig.json +++ b/modules/mod/src/main/typescript/tsconfig.json @@ -22,12 +22,13 @@ "strict": true, "strictFunctionTypes": true, "strictNullChecks": true, - "traceResolution": true, + "traceResolution": true }, "tstl": { "luaTarget": "5.2", "tstlVerbose": true, "noHeader": true, + "noImplicitSelf": true, "luaLibImport" : "require", }, "//": { diff --git a/modules/mod2/build.gradle.kts b/modules/mod2/build.gradle.kts index 60d7616..586e5cb 100644 --- a/modules/mod2/build.gradle.kts +++ b/modules/mod2/build.gradle.kts @@ -62,12 +62,9 @@ kotlin { } dependencies { - val kotlinWrappersVersion = "0.0.1-pre.254-kotlin-1.5.31" - implementation( - project.dependencies.enforcedPlatform( - "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}" - ) - ) + + + // bom is defined in archetype.kotlin-js implementation("org.jetbrains.kotlin-wrappers:kotlin-react") // implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom") From a70b2935f3a86f0b26e1662fce90420622219ec3 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 20 Oct 2021 23:27:31 +0200 Subject: [PATCH 020/629] kotlin data model experiment --- modules/data-model/build.gradle.kts | 8 +++ .../data-model/src/main/kotlin/PlayerModel.kt | 55 +++++++++++++++++++ settings.gradle.kts | 1 + 3 files changed, 64 insertions(+) create mode 100644 modules/data-model/build.gradle.kts create mode 100644 modules/data-model/src/main/kotlin/PlayerModel.kt diff --git a/modules/data-model/build.gradle.kts b/modules/data-model/build.gradle.kts new file mode 100644 index 0000000..8a701aa --- /dev/null +++ b/modules/data-model/build.gradle.kts @@ -0,0 +1,8 @@ +plugins { + id("dev.adamko.factoriowebmap.archetype.kotlin-js") +} + +val projectId: String by project.extra +val buildDir: Directory = layout.buildDirectory.dir(projectId).get() +val nodeModulesDir: Directory by project.extra + diff --git a/modules/data-model/src/main/kotlin/PlayerModel.kt b/modules/data-model/src/main/kotlin/PlayerModel.kt new file mode 100644 index 0000000..a745430 --- /dev/null +++ b/modules/data-model/src/main/kotlin/PlayerModel.kt @@ -0,0 +1,55 @@ +interface Identifiable { + val id: T +} + + +interface IndexedModel { + val index: UInt +} + +interface NamedModel { + val name: String +} + + +data class SurfaceModel( + override val name: String, + override val index: UInt, + val daytime: Float, + val darkness: Float, + val wind_speed: Double, +) : IndexedModel, NamedModel + + +/** Player/Entity shared props */ +interface ControlModel { + val driving: Boolean + val forces: List +} + + +//data class PlayerModel( +// val index: UInt, +// val characters: List +//) : Identifiable { +// override val id: UInt = index +//} + +//data class EntityModel( +// val unit_number: Int, +// override val name: String, +// val type: String, +// val active: Boolean, +// val minable: Boolean, +// val health: Boolean, +// val speed: Float, override val driving: Boolean, +//) : ControlModel, NamedModel + + +data class ForceModel( + val index: UInt, + override val name: String, + val research_progress: Double, +) : Identifiable, NamedModel { + override val id: UInt = index +} diff --git a/settings.gradle.kts b/settings.gradle.kts index c681010..ebb5496 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -6,6 +6,7 @@ include( ":modules:server", ":modules:kt-rcon", ":modules:kafka", + ":modules:data-model", ) enableFeaturePreview("VERSION_CATALOGS") From 239951ac48d0131272c78eac0f5cf71ccb2d091b Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Wed, 20 Oct 2021 23:27:47 +0200 Subject: [PATCH 021/629] events -> json export properly working! --- modules/mod/src/main/typescript/events.ts | 70 ++++++----- .../mod/src/main/typescript/ext/LuaArray.ts | 16 --- .../mod/src/main/typescript/serdes/serdes.ts | 111 ++++++++++-------- modules/mod/src/main/typescript/tsconfig.json | 12 +- 4 files changed, 108 insertions(+), 101 deletions(-) delete mode 100644 modules/mod/src/main/typescript/ext/LuaArray.ts diff --git a/modules/mod/src/main/typescript/events.ts b/modules/mod/src/main/typescript/events.ts index 5d07a8d..cbc3135 100644 --- a/modules/mod/src/main/typescript/events.ts +++ b/modules/mod/src/main/typescript/events.ts @@ -1,7 +1,3 @@ -// import {Kafka, Producer} from "kafkajs"; - -// const {Kafka} = require("kafkajs") -// import {Kafka, Producer} from "kafkajs/types" // import {Data, Mods} from "typed-factorio/settings/types" // import { events } from "typed-factorio/generated" @@ -17,44 +13,57 @@ import {JsonTable, Serdes} from "./serdes/serdes" // const SERVER_ID: uint = 0 // const EVENT_FILE_DIR: string = "events" -function playerEvent(tick: uint, player_index: uint, eventType: string) { +function createFactorioEvent(tick: uint, object_name: string, eventType: string, data: JsonTable): JsonTable { + return { + tick, + object_name, + eventType, + data, + } + +} + +function handlePlayerUpdate(tick: uint, player_index: uint, eventType: string) { + let player: LuaPlayer = game.players[player_index] + let table = Serdes.Player.playerToTable(player) + let event = createFactorioEvent(tick, player.object_name, eventType, table) + emitEvent(event) + + handleCharactersEvent(tick, player_index, eventType) +} + +function handleCharactersEvent(tick: uint, player_index: uint, eventType: string) { + let player: LuaPlayer = game.players[player_index] - let filename: string = table.concat([player.index, eventType, tick], "_") - let data = Serdes.Player.playerToTable(player) - outputEventFile(player.object_name + "/" + filename, data) - if (player.character != undefined) { - entityEvent(tick, player.character, eventType) + handleEntityUpdate(tick, player.character, eventType) for (const char of player.get_associated_characters()) { if (char != undefined) { - entityEvent(tick, char, eventType) + handleEntityUpdate(tick, char, eventType) } } - } } -function entityEvent(tick: uint, entity: LuaEntity, eventType: string) { - if (entity.unit_number != undefined && entity.unit_number != 0) { - let filename: string = table.concat([entity.unit_number, eventType, tick], "_") - let data = Serdes.Entity.entityToTable(entity) - outputEventFile(entity.object_name + "/" + filename, data) - } +function handleEntityUpdate(tick: uint, entity: LuaEntity, eventType: string) { + let table = Serdes.Entity.entityToTable(entity) + let event = createFactorioEvent(tick, entity.object_name, eventType, table) + emitEvent(event) } function surfaceEvent(tick: uint, surface: LuaSurface, eventType: string) { - let filename: string = - surface.object_name + "/" + table.concat([surface.index, eventType, tick], "_") - let data = Serdes.Surface.surfaceToTable(surface) - outputEventFile(filename, data) + let table = Serdes.Surface.surfaceToTable(surface) + let event = createFactorioEvent(tick, surface.object_name, eventType, table) + emitEvent(event) } -function outputEventFile(filename: string, obj: JsonTable) { - let data = game.table_to_json(obj) +/** Emit a serialised event */ +function emitEvent(event: JsonTable) { + let data = game.table_to_json(event) // game.write_file(EVENT_FILE_DIR + "/" + filename, data, false, SERVER_ID) - localised_print(`!===== ${filename} | ${data} =====!`) + localised_print(`FactorioWebMapJsonEvent: ${data}`) } // script.on_event( @@ -67,21 +76,22 @@ function outputEventFile(filename: string, obj: JsonTable) { script.on_event( defines.events.on_player_mined_entity, (e: OnPlayerMinedEntityEvent) => { - entityEvent(e.tick, e.entity, "on_player_mined_entity") - playerEvent(e.tick, e.player_index, "on_player_mined_entity") + handlePlayerUpdate(e.tick, e.player_index, "on_player_mined_entity") + handleEntityUpdate(e.tick, e.entity, "on_player_mined_entity") } ) script.on_event( defines.events.on_player_joined_game, (e: OnPlayerJoinedGameEvent) => { - playerEvent(e.tick, e.player_index, "on_player_joined_game") + handlePlayerUpdate(e.tick, e.player_index, "on_player_joined_game") } ) script.on_event( defines.events.on_player_changed_position, + // this is actually a character update, not a player update? (e: OnPlayerChangedPositionEvent) => { - playerEvent(e.tick, e.player_index, "on_player_changed_position") + handlePlayerUpdate(e.tick, e.player_index, "on_player_changed_position") } ) @@ -90,8 +100,6 @@ script.on_event( (e: OnTickEvent) => { if (e.tick % 60 == 0) { - game.surfaces - for (const [index,] of pairs(game.surfaces)) { let surface = game.surfaces[index] surfaceEvent(e.tick, surface, "on_tick") diff --git a/modules/mod/src/main/typescript/ext/LuaArray.ts b/modules/mod/src/main/typescript/ext/LuaArray.ts deleted file mode 100644 index e24e759..0000000 --- a/modules/mod/src/main/typescript/ext/LuaArray.ts +++ /dev/null @@ -1,16 +0,0 @@ -// declare interface LuaArray extends LuaTable { -// } - -// = LuaTable; - -// declare type LuaArrayConstructor = (new () => LuaArray) - -// declare const LuaArray: LuaArrayConstructor - -// class LuaArray extends LuaTable { -// add(val: TValue) { -// this.set(this.length(), val) -// } -// } - -// declare type LuaArray & LuaTable \ No newline at end of file diff --git a/modules/mod/src/main/typescript/serdes/serdes.ts b/modules/mod/src/main/typescript/serdes/serdes.ts index 2396228..1728991 100644 --- a/modules/mod/src/main/typescript/serdes/serdes.ts +++ b/modules/mod/src/main/typescript/serdes/serdes.ts @@ -1,25 +1,46 @@ -export type PrimitiveType = number | string | boolean -export type JsonArray = TValue[] -export type JsonTableValueType = - PrimitiveType - | JsonTable - | JsonArray -export type JsonTable = LuaTable // & table -// export type JsonArray = LuaArray // & table +export type JsonPrimitiveType = number | string | boolean | undefined | null | void +// export type JsonArray = TValue[] +// export class JsonArray extends Array { +// } + +// export type JsonArray = Array +// declare type JsonArrayConstructor = (new () => JsonArray) +// declare const JsonArray: JsonArrayConstructor + +export type JsonArray = T[] + +export type JsonTableValueType = + JsonPrimitiveType + | JsonTable + | JsonArray + | undefined + | null + +// export class JsonTable extends LuaTable { +// } +// export type JsonTable = LuaTable +// const JsonTable = () => new LuaTable() +// export type JsonTableConstructor = (new () => JsonTable) +// declare const JsonTable: JsonTableConstructor + + +export interface JsonTable { + [key: string]: JsonTableValueType +} export namespace Serdes { export namespace Player { export function playerToTable(player: LuaPlayer): JsonTable { - let table = new LuaTable() - - table.set("name", player.name) - let charIds: JsonArray = Entity.entitiesToUnitNumbers(player.get_associated_characters()) - table.set("characterIds", charIds) - - return table + let charIds = Entity.entitiesToUnitNumbers(player.get_associated_characters()) + return { + "name": player.name, + "characterId": player.character?.unit_number, + "associatedCharacterIds": charIds, + "position": DataClasses.positionTableToTable(player.position), + } } } @@ -27,34 +48,32 @@ export namespace Serdes { export namespace Entity { export function entityToTable(entity: LuaEntity): JsonTable { - let table = new LuaTable() - if (entity.player?.index != null) { - table.set("playerId", entity.player?.index) + let player: JsonTable = + entity.is_player() ? { + "playerId": entity.player?.index, + } : {} + + return { + player, + "name": entity.name, + "type": entity.type, + "active": entity.active, + "health": entity.health, + "surfaceId": entity.surface.index, + "unit_number": entity.unit_number, + "position": DataClasses.positionTableToTable(entity.position), } - table.set("type", entity.type) - table.set("active", entity.active) - - if (entity.health != null) { - table.set("health", entity.health) - } - - table.set("surfaceId", entity.surface.index) - table.set("position", DataClasses.positionTableToTable(entity.position)) - - return table } export function entitiesToUnitNumbers(entities: LuaEntity[]): JsonArray { - let array: number[] = [] - let j: number = 0 - for (let i = 0; i < entities.length; i++) { - let unitNum = entities[i].unit_number - if (unitNum != null) { - array[j++] = unitNum + let result: (number) [] = [] + for (let entity of entities) { + if (entity.unit_number != null) { + result[result.length] = entity.unit_number } } - return array + return result } } @@ -62,13 +81,11 @@ export namespace Serdes { export namespace Surface { export function surfaceToTable(surface: LuaSurface): JsonTable { - let table = new LuaTable() - - table.set("name", surface.name) - table.set("index", surface.index) - table.set("daytime", surface.daytime) - - return table + return { + "name": surface.name, + "index": surface.index, + "daytime": surface.daytime, + } } } @@ -76,10 +93,10 @@ export namespace Serdes { export namespace DataClasses { export function positionTableToTable(positionTable: PositionTable): JsonTable { - let table = new LuaTable() - table.set("x", positionTable.x) - table.set("y", positionTable.y) - return table + return { + "x": positionTable.x, + "y": positionTable.y, + } } } diff --git a/modules/mod/src/main/typescript/tsconfig.json b/modules/mod/src/main/typescript/tsconfig.json index dbd7f66..4b05c31 100644 --- a/modules/mod/src/main/typescript/tsconfig.json +++ b/modules/mod/src/main/typescript/tsconfig.json @@ -29,7 +29,7 @@ "tstlVerbose": true, "noHeader": true, "noImplicitSelf": true, - "luaLibImport" : "require", + "luaLibImport": "inline" }, "//": { "noResolve": true, @@ -39,7 +39,7 @@ ], "exactOptionalPropertyTypes": true, "luaTarget": "5.2", - "skipLibCheck": true, + "skipLibCheck": true, "skipDefaultLibCheck": true, "types": [ "node", @@ -50,12 +50,10 @@ "node_modules/@types" ], "//": "lua-types/5.2", - "luaLibImport" : "inline", + "luaLibImport": "inline", "noImplicitSelf": true, - "sourceMapTraceback": true, - - "luaBundle " : "bundle.lua", - "luaBundleEntry " : "bundleEntry.lua" + "luaBundle ": "bundle.lua", + "luaBundleEntry ": "bundleEntry.lua" } } From ef33698c330371708cf91745c1ef30c723e9569d Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 22 Oct 2021 00:07:26 +0200 Subject: [PATCH 022/629] moving docker stuff around, --- modules/kafka/build.gradle.kts | 3 - modules/kafka/docker-compose.yml | 14 ----- modules/mod/build.gradle.kts | 11 ++-- modules/mod/infra/.env | 1 + .../resources/server => infra}/.gitignore | 0 modules/mod/infra/docker-compose.yml | 56 +++++++++++++++++++ modules/{kafka => mod/infra}/kafka.Dockerfile | 29 ++++++++-- .../test/resources/server/docker-compose.yml | 21 ------- settings.gradle.kts | 2 +- 9 files changed, 88 insertions(+), 49 deletions(-) delete mode 100644 modules/kafka/build.gradle.kts delete mode 100644 modules/kafka/docker-compose.yml create mode 100644 modules/mod/infra/.env rename modules/mod/{src/test/resources/server => infra}/.gitignore (100%) create mode 100644 modules/mod/infra/docker-compose.yml rename modules/{kafka => mod/infra}/kafka.Dockerfile (62%) delete mode 100644 modules/mod/src/test/resources/server/docker-compose.yml diff --git a/modules/kafka/build.gradle.kts b/modules/kafka/build.gradle.kts deleted file mode 100644 index 142fb17..0000000 --- a/modules/kafka/build.gradle.kts +++ /dev/null @@ -1,3 +0,0 @@ -plugins { - id("dev.adamko.factoriowebmap.archetype.base") -} diff --git a/modules/kafka/docker-compose.yml b/modules/kafka/docker-compose.yml deleted file mode 100644 index d7ab38b..0000000 --- a/modules/kafka/docker-compose.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: "3.9" - -services: - - kafka: - image: dev-adamko/kafka - container_name: "kafka-factorio" - build: - dockerfile: "kafka.Dockerfile" - args: - KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/3.0.0/kafka_2.13-3.0.0.tgz" - ports: - - "9092:9092" - - "9093:9093" diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index 41c79e4..78ab75e 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -1,5 +1,4 @@ import com.github.gradle.node.npm.task.NpmTask -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs plugins { @@ -88,7 +87,7 @@ val copyModToServerTask = tasks.register("copyModToServer") { dependsOn(modPackageTask) from(modPackageTask) - into(layout.projectDirectory.dir("src/test/resources/server/data/mods").asFile) + into(layout.projectDirectory.dir("infra/factorio-server/data/mods").asFile) } val serverStopTask = tasks.register("dockerStop") { @@ -96,8 +95,8 @@ val serverStopTask = tasks.register("dockerStop") { mustRunAfter(copyModToServerTask) - workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile - commandLine = parseSpaceSeparatedArgs("docker-compose stop") + workingDir = layout.projectDirectory.dir("infra/factorio-server").asFile + commandLine = parseSpaceSeparatedArgs("docker-compose stop factorio-server") } val serverUpTask = tasks.register("dockerUp") { @@ -106,8 +105,8 @@ val serverUpTask = tasks.register("dockerUp") { mustRunAfter(copyModToServerTask) dependsOn(serverStopTask) - workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile - commandLine = parseSpaceSeparatedArgs("docker-compose up -d") + workingDir = layout.projectDirectory.dir("infra/factorio-server").asFile + commandLine = parseSpaceSeparatedArgs("docker-compose up -d factorio-server") } //val serverRestartTask = tasks.register("dockerRestart") { diff --git a/modules/mod/infra/.env b/modules/mod/infra/.env new file mode 100644 index 0000000..35ed112 --- /dev/null +++ b/modules/mod/infra/.env @@ -0,0 +1 @@ +COMPOSE_PROJECT_NAME=factorio-infra diff --git a/modules/mod/src/test/resources/server/.gitignore b/modules/mod/infra/.gitignore similarity index 100% rename from modules/mod/src/test/resources/server/.gitignore rename to modules/mod/infra/.gitignore diff --git a/modules/mod/infra/docker-compose.yml b/modules/mod/infra/docker-compose.yml new file mode 100644 index 0000000..98146d7 --- /dev/null +++ b/modules/mod/infra/docker-compose.yml @@ -0,0 +1,56 @@ +version: "3.9" + +services: + + factorio-server: + image: factoriotools/factorio:1.1.42 + # logging: + # driver: "json-file" + container_name: "factorio" + restart: "unless-stopped" + ports: + - "34197:34197/udp" # factorio + - "27015:27015/tcp" # rcon + volumes: + - "./data:/factorio" +# logging: +# driver: "mickyg/kafka-logdriver:latest" +# options: +# KAFKA_BROKER_ADDR: "kafka-kraft" +# LOG_TOPIC: "dockerlogs-factorio-server" +# LOG_TAG: "factorio-server" + + # environment: + # RCON_PORT: 27715 + # environment: + # - PUID=1000 + # - PGID=1000 + # - UPDATE_MODS_ON_START=true + # - USERNAME=FactorioUsername + # - TOKEN=FactorioToken + + kafka-kraft: + image: dev-adamko/kafka-kraft + container_name: "kafka-factorio" + build: + dockerfile: "kafka.Dockerfile" + target: "kafka-kraft" + args: + KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/3.0.0/kafka_2.13-3.0.0.tgz" + ports: + - "9092:9092" + - "9093:9093" + +# kafka-connect: +# image: dev-adamko/kafka-connect +# container_name: "kafka-connect" +# build: +# dockerfile: "kafka.Dockerfile" +# target: "kafka-connect" +# args: +# KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/3.0.0/kafka_2.13-3.0.0.tgz" +# depends_on: +# - kafka-kraft +# ports: +# - "8083:8083" +# diff --git a/modules/kafka/kafka.Dockerfile b/modules/mod/infra/kafka.Dockerfile similarity index 62% rename from modules/kafka/kafka.Dockerfile rename to modules/mod/infra/kafka.Dockerfile index 88a8d8a..48e4127 100644 --- a/modules/kafka/kafka.Dockerfile +++ b/modules/mod/infra/kafka.Dockerfile @@ -1,5 +1,6 @@ ARG KAFKA_DL_URL=https://dlcdn.apache.org/kafka/3.0.0/kafka_2.13-3.0.0.tgz +## builder ## FROM debian:11-slim as Kafka-Download ARG KAFKA_DL_URL @@ -15,21 +16,22 @@ RUN echo "Downloading Kafka from $KAFKA_DL_URL" \ && ls -la +## Kafka ## # KRaft (aka KIP-500) mode Preview Release # https://github.com/apache/kafka/blob/041b76dc57f096be2a2d7532d917122992bff6e2/config/kraft/README.md -FROM openjdk:11 +FROM openjdk:11 as kafka-kraft WORKDIR /kafka -COPY --from=Kafka-Download /kafka /kafka +COPY --from=Kafka-Download /kafka . # hardcoded for now, based on values from './config/kraft/server.properties' # log.dirs VOLUME /tmp/kraft-combined-logs # listeners, controller.quorum.voters -EXPOSE 9092, 9093 +EXPOSE 9092 9093 -# Generate a cluster ID +# Generate a cluster ID (must use this .sh to generate a UUID) RUN echo "$(./bin/kafka-storage.sh random-uuid)" > cluster_id \ && echo "Generated a Kafka Cluster ID: $(cat cluster_id)" @@ -41,3 +43,22 @@ RUN ./bin/kafka-storage.sh format \ # launch the broker in KRaft mode, which means that it runs without ZooKeeper ENTRYPOINT ["./bin/kafka-server-start.sh", "./config/kraft/server.properties"] + + +### Kafka Connect ## +#FROM openjdk:11 as kafka-connect +## https://github.com/confluentinc/cp-docker-images/blob/5.3.3-post/debian/kafka-connect-base/Dockerfile +# +#ENV COMPONENT=kafka-connect +# +#WORKDIR /kafka-connect +# +#COPY --from=Kafka-Download /kafka . +# +## Default kafka-connect rest.port +#EXPOSE 8083 +# +#VOLUME ["/etc/${COMPONENT}/jars", "/etc/${COMPONENT}/secrets"] +# +## launch the broker in KRaft mode, which means that it runs without ZooKeeper +#ENTRYPOINT ["./bin/connect-standalone.sh", "./config/connect-standalone.properties"] diff --git a/modules/mod/src/test/resources/server/docker-compose.yml b/modules/mod/src/test/resources/server/docker-compose.yml deleted file mode 100644 index 8a6a05d..0000000 --- a/modules/mod/src/test/resources/server/docker-compose.yml +++ /dev/null @@ -1,21 +0,0 @@ -version: "3.9" -services: - factorio: - image: factoriotools/factorio:1.1.42 - # logging: - # driver: "json-file" - container_name: "factorio" - restart: "unless-stopped" - ports: - - "34197:34197/udp" # factorio - - "27015:27015/tcp" # rcon - volumes: - - "./data:/factorio" -# environment: -# RCON_PORT: 27715 -# environment: -# - PUID=1000 -# - PGID=1000 -# - UPDATE_MODS_ON_START=true -# - USERNAME=FactorioUsername -# - TOKEN=FactorioToken diff --git a/settings.gradle.kts b/settings.gradle.kts index ebb5496..b158369 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,10 +5,10 @@ include( // ":modules:mod2", ":modules:server", ":modules:kt-rcon", - ":modules:kafka", ":modules:data-model", ) + enableFeaturePreview("VERSION_CATALOGS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") From f9b93c013d6b58158e1c8f9e65ba2e1bed1111c2 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 22 Oct 2021 00:07:48 +0200 Subject: [PATCH 023/629] pipe factorio events to kafka bb!!! --- modules/mod/pipe-logs-to-kafka.sh | 8 ++++++++ modules/mod/src/main/typescript/events.ts | 3 +-- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 modules/mod/pipe-logs-to-kafka.sh diff --git a/modules/mod/pipe-logs-to-kafka.sh b/modules/mod/pipe-logs-to-kafka.sh new file mode 100644 index 0000000..2a06458 --- /dev/null +++ b/modules/mod/pipe-logs-to-kafka.sh @@ -0,0 +1,8 @@ +# stream logs from 'factorio' container +# follow the logs, and +# combine stdout and stderr +# only match lines that start with 'FactorioEvent: ', +# and only return the stuff *after* 'FactorioEvent: ' +docker logs --tail 0 -f factorio 2>&1 | + sed -n -e 's/^FactorioEvent: //p' | + kafkacat -P -b localhost -t factorio-server-log diff --git a/modules/mod/src/main/typescript/events.ts b/modules/mod/src/main/typescript/events.ts index cbc3135..c60255c 100644 --- a/modules/mod/src/main/typescript/events.ts +++ b/modules/mod/src/main/typescript/events.ts @@ -20,7 +20,6 @@ function createFactorioEvent(tick: uint, object_name: string, eventType: string, eventType, data, } - } function handlePlayerUpdate(tick: uint, player_index: uint, eventType: string) { @@ -63,7 +62,7 @@ function surfaceEvent(tick: uint, surface: LuaSurface, eventType: string) { function emitEvent(event: JsonTable) { let data = game.table_to_json(event) // game.write_file(EVENT_FILE_DIR + "/" + filename, data, false, SERVER_ID) - localised_print(`FactorioWebMapJsonEvent: ${data}`) + localised_print(`FactorioEvent: ${data}`) } // script.on_event( From 5e69799136bfdfb8e4b6689584a12ed8ad7fb224 Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 22 Oct 2021 12:29:45 +0200 Subject: [PATCH 024/629] refactoring, standardised naming, shuffling the docker infra around, --- modules/mod/build.gradle.kts | 17 ++++- modules/mod/infra/.gitignore | 2 +- modules/mod/infra/docker-compose.yml | 6 +- modules/mod/pipe-logs-to-kafka.sh | 5 ++ modules/mod/src/main/typescript/events.ts | 54 ++++++++------ .../mod/src/main/typescript/serdes/serdes.ts | 71 ++++++++++--------- 6 files changed, 91 insertions(+), 64 deletions(-) diff --git a/modules/mod/build.gradle.kts b/modules/mod/build.gradle.kts index 78ab75e..46bf8fc 100644 --- a/modules/mod/build.gradle.kts +++ b/modules/mod/build.gradle.kts @@ -80,6 +80,9 @@ val modPackageTask = tasks.register("package") { //tasks.build { dependsOn(tstlTask, modPackageTask) } +val modInfraDir = layout.projectDirectory.dir("infra") +val factorioServerDataDir = modInfraDir.dir("factorio-server") + val copyModToServerTask = tasks.register("copyModToServer") { description = "Copy the mod to the Factorio Docker server" group = "$projectId.factorioServer" @@ -87,7 +90,11 @@ val copyModToServerTask = tasks.register("copyModToServer") { dependsOn(modPackageTask) from(modPackageTask) - into(layout.projectDirectory.dir("infra/factorio-server/data/mods").asFile) + into(factorioServerDataDir.dir("mods")) + + doLast { + logger.lifecycle("Copying mod from ${source.files} to $destinationDir") + } } val serverStopTask = tasks.register("dockerStop") { @@ -95,7 +102,7 @@ val serverStopTask = tasks.register("dockerStop") { mustRunAfter(copyModToServerTask) - workingDir = layout.projectDirectory.dir("infra/factorio-server").asFile + workingDir(modInfraDir) commandLine = parseSpaceSeparatedArgs("docker-compose stop factorio-server") } @@ -105,7 +112,7 @@ val serverUpTask = tasks.register("dockerUp") { mustRunAfter(copyModToServerTask) dependsOn(serverStopTask) - workingDir = layout.projectDirectory.dir("infra/factorio-server").asFile + workingDir(modInfraDir) commandLine = parseSpaceSeparatedArgs("docker-compose up -d factorio-server") } @@ -124,6 +131,10 @@ val copyModToClientTask = tasks.register("copyModToClient") { from(modPackageTask) into("""D:\Users\Adam\AppData\Roaming\Factorio\mods""") + + doLast { + logger.lifecycle("Copying mod from ${source.files} to $destinationDir") + } } //val factorioClientLaunch = tasks.register("launch") { diff --git a/modules/mod/infra/.gitignore b/modules/mod/infra/.gitignore index 1269488..b09a6cc 100644 --- a/modules/mod/infra/.gitignore +++ b/modules/mod/infra/.gitignore @@ -1 +1 @@ -data +factorio-server diff --git a/modules/mod/infra/docker-compose.yml b/modules/mod/infra/docker-compose.yml index 98146d7..7ea4ccc 100644 --- a/modules/mod/infra/docker-compose.yml +++ b/modules/mod/infra/docker-compose.yml @@ -6,13 +6,13 @@ services: image: factoriotools/factorio:1.1.42 # logging: # driver: "json-file" - container_name: "factorio" + container_name: "factorio-server" restart: "unless-stopped" ports: - "34197:34197/udp" # factorio - "27015:27015/tcp" # rcon volumes: - - "./data:/factorio" + - "./factorio-server:/factorio" # logging: # driver: "mickyg/kafka-logdriver:latest" # options: @@ -31,7 +31,7 @@ services: kafka-kraft: image: dev-adamko/kafka-kraft - container_name: "kafka-factorio" + container_name: "kafka-kraft" build: dockerfile: "kafka.Dockerfile" target: "kafka-kraft" diff --git a/modules/mod/pipe-logs-to-kafka.sh b/modules/mod/pipe-logs-to-kafka.sh index 2a06458..96fbe5a 100644 --- a/modules/mod/pipe-logs-to-kafka.sh +++ b/modules/mod/pipe-logs-to-kafka.sh @@ -1,3 +1,5 @@ +#!/usr/bin/env bash + # stream logs from 'factorio' container # follow the logs, and # combine stdout and stderr @@ -6,3 +8,6 @@ docker logs --tail 0 -f factorio 2>&1 | sed -n -e 's/^FactorioEvent: //p' | kafkacat -P -b localhost -t factorio-server-log + +# listen to events +# kafkacat -C -b localhost -t factorio-server-log | jq diff --git a/modules/mod/src/main/typescript/events.ts b/modules/mod/src/main/typescript/events.ts index c60255c..50b08ad 100644 --- a/modules/mod/src/main/typescript/events.ts +++ b/modules/mod/src/main/typescript/events.ts @@ -10,54 +10,64 @@ import {JsonTable, Serdes} from "./serdes/serdes" -// const SERVER_ID: uint = 0 -// const EVENT_FILE_DIR: string = "events" -function createFactorioEvent(tick: uint, object_name: string, eventType: string, data: JsonTable): JsonTable { - return { - tick, - object_name, - eventType, - data, - } +interface FactorioEvent extends JsonTable { + tick: uint + object_name: string, + event_type: string, + data: JsonTable, } -function handlePlayerUpdate(tick: uint, player_index: uint, eventType: string) { - let player: LuaPlayer = game.players[player_index] +const FactorioEvent = ((tick: uint, objectName: string, eventType: string, data: JsonTable) => { + return { + tick: tick, + object_name: objectName, + event_type: eventType, + data: data, + } as FactorioEvent + } +) + +// function createFactorioEvent(tick: uint, object_name: string, eventType: string, data: +// JsonTable): FactorioEvent { return { tick, object_name, eventType, data, } } + +function handlePlayerUpdate(tick: uint, playerIndex: uint, eventType: string) { + let player: LuaPlayer = game.players[playerIndex] let table = Serdes.Player.playerToTable(player) - let event = createFactorioEvent(tick, player.object_name, eventType, table) + let event = FactorioEvent(tick, player.object_name, eventType, table) emitEvent(event) - handleCharactersEvent(tick, player_index, eventType) + handleCharactersEvent(tick, playerIndex, eventType) } -function handleCharactersEvent(tick: uint, player_index: uint, eventType: string) { +function handleCharactersEvent(tick: uint, playerIndex: uint, eventType: string) { - let player: LuaPlayer = game.players[player_index] + let player: LuaPlayer = game.players[playerIndex] if (player.character != undefined) { handleEntityUpdate(tick, player.character, eventType) - - for (const char of player.get_associated_characters()) { - if (char != undefined) { - handleEntityUpdate(tick, char, eventType) - } + } + for (const character of player.get_associated_characters()) { + if (character != undefined) { + handleEntityUpdate(tick, character, eventType) } } } function handleEntityUpdate(tick: uint, entity: LuaEntity, eventType: string) { let table = Serdes.Entity.entityToTable(entity) - let event = createFactorioEvent(tick, entity.object_name, eventType, table) + let event = FactorioEvent(tick, entity.object_name, eventType, table) emitEvent(event) } function surfaceEvent(tick: uint, surface: LuaSurface, eventType: string) { let table = Serdes.Surface.surfaceToTable(surface) - let event = createFactorioEvent(tick, surface.object_name, eventType, table) + let event = FactorioEvent(tick, surface.object_name, eventType, table) emitEvent(event) } +// const SERVER_ID: uint = 0 +// const EVENT_FILE_DIR: string = "events" /** Emit a serialised event */ function emitEvent(event: JsonTable) { let data = game.table_to_json(event) diff --git a/modules/mod/src/main/typescript/serdes/serdes.ts b/modules/mod/src/main/typescript/serdes/serdes.ts index 1728991..d2fad48 100644 --- a/modules/mod/src/main/typescript/serdes/serdes.ts +++ b/modules/mod/src/main/typescript/serdes/serdes.ts @@ -1,13 +1,5 @@ export type JsonPrimitiveType = number | string | boolean | undefined | null | void -// export type JsonArray = TValue[] -// export class JsonArray extends Array { -// } - -// export type JsonArray = Array -// declare type JsonArrayConstructor = (new () => JsonArray) -// declare const JsonArray: JsonArrayConstructor - export type JsonArray = T[] export type JsonTableValueType = @@ -17,6 +9,18 @@ export type JsonTableValueType = | undefined | null +export interface JsonTable { + [key: string]: JsonTableValueType +} + +// export type JsonArray = TValue[] +// export class JsonArray extends Array { +// } + +// export type JsonArray = Array +// declare type JsonArrayConstructor = (new () => JsonArray) +// declare const JsonArray: JsonArrayConstructor + // export class JsonTable extends LuaTable { // } // export type JsonTable = LuaTable @@ -25,10 +29,6 @@ export type JsonTableValueType = // declare const JsonTable: JsonTableConstructor -export interface JsonTable { - [key: string]: JsonTableValueType -} - export namespace Serdes { export namespace Player { @@ -36,10 +36,10 @@ export namespace Serdes { export function playerToTable(player: LuaPlayer): JsonTable { let charIds = Entity.entitiesToUnitNumbers(player.get_associated_characters()) return { - "name": player.name, - "characterId": player.character?.unit_number, - "associatedCharacterIds": charIds, - "position": DataClasses.positionTableToTable(player.position), + name: player.name, + character_unit_number: player.character?.unit_number, + associated_characters_unit_numbers: charIds, + position: DataClasses.positionTableToTable(player.position), } } @@ -49,21 +49,22 @@ export namespace Serdes { export function entityToTable(entity: LuaEntity): JsonTable { - let player: JsonTable = - entity.is_player() ? { - "playerId": entity.player?.index, - } : {} - - return { - player, - "name": entity.name, - "type": entity.type, - "active": entity.active, - "health": entity.health, - "surfaceId": entity.surface.index, - "unit_number": entity.unit_number, - "position": DataClasses.positionTableToTable(entity.position), + let data: JsonTable = { + name: entity.name, + type: entity.type, + active: entity.active, + health: entity.health, + surface_index: entity.surface.index, + unit_number: entity.unit_number, + position: DataClasses.positionTableToTable(entity.position), } + + if (entity.is_player()) { + let player = entity.player!! + data.player_index = player.index + } + + return data } export function entitiesToUnitNumbers(entities: LuaEntity[]): JsonArray { @@ -82,9 +83,9 @@ export namespace Serdes { export function surfaceToTable(surface: LuaSurface): JsonTable { return { - "name": surface.name, - "index": surface.index, - "daytime": surface.daytime, + name: surface.name, + index: surface.index, + daytime: surface.daytime, } } @@ -94,8 +95,8 @@ export namespace Serdes { export function positionTableToTable(positionTable: PositionTable): JsonTable { return { - "x": positionTable.x, - "y": positionTable.y, + x: positionTable.x, + y: positionTable.y, } } From 3a33062cd45c70d08f870d46e8df5d59d6679b4f Mon Sep 17 00:00:00 2001 From: Adam <897017+asemy@users.noreply.github.com> Date: Fri, 22 Oct 2021 18:16:57 +0200 Subject: [PATCH 025/629] add kvision template --- modules/server/build.gradle.kts | 55 ++++++++++++++++++- .../server/src/main/kotlin/com/example/App.kt | 38 +++++++++++++ .../server/src/main/resources/css/kvapp.css | 0 .../src/main/resources/i18n/messages-en.po | 23 ++++++++ .../src/main/resources/i18n/messages-pl.po | 23 ++++++++ .../src/main/resources/i18n/messages.pot | 8 +++ modules/server/src/main/web/index.html | 12 ++++ .../test/kotlin/test/com/example/AppSpec.kt | 15 +++++ modules/server/webpack.config.d/bootstrap.js | 3 + modules/server/webpack.config.d/css.js | 1 + modules/server/webpack.config.d/file.js | 6 ++ modules/server/webpack.config.d/handlebars.js | 6 ++ modules/server/webpack.config.d/jquery.js | 9 +++ modules/server/webpack.config.d/moment.js | 15 +++++ modules/server/webpack.config.d/webpack.js | 15 +++++ 15 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 modules/server/src/main/kotlin/com/example/App.kt create mode 100644 modules/server/src/main/resources/css/kvapp.css create mode 100644 modules/server/src/main/resources/i18n/messages-en.po create mode 100644 modules/server/src/main/resources/i18n/messages-pl.po create mode 100644 modules/server/src/main/resources/i18n/messages.pot create mode 100644 modules/server/src/main/web/index.html create mode 100644 modules/server/src/test/kotlin/test/com/example/AppSpec.kt create mode 100644 modules/server/webpack.config.d/bootstrap.js create mode 100644 modules/server/webpack.config.d/css.js create mode 100644 modules/server/webpack.config.d/file.js create mode 100644 modules/server/webpack.config.d/handlebars.js create mode 100644 modules/server/webpack.config.d/jquery.js create mode 100644 modules/server/webpack.config.d/moment.js create mode 100644 modules/server/webpack.config.d/webpack.js diff --git a/modules/server/build.gradle.kts b/modules/server/build.gradle.kts index 0bbe330..3f32130 100644 --- a/modules/server/build.gradle.kts +++ b/modules/server/build.gradle.kts @@ -1,7 +1,60 @@ +import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig + plugins { - kotlin("jvm") + id("dev.adamko.factoriowebmap.archetype.base") +// kotlin("jvm") + id("io.kvision") version "5.4.1" + kotlin("js") + kotlin("plugin.serialization") version "1.5.31" } group = "${rootProject.group}.server" version = rootProject.version + +val webDir = file("src/main/web") + + +val kvisionVersion = "5.4.1" + +kotlin { + js { + browser { + runTask { + outputFileName = "main.bundle.js" + sourceMaps = false + devServer = KotlinWebpackConfig.DevServer( + open = false, + port = 3000, + proxy = mutableMapOf( + "/kv/*" to "http://localhost:8080", + "/kvws/*" to mapOf("target" to "ws://localhost:8080", "ws" to true) + ), + static = mutableListOf("$buildDir/processedResources/js/main") + ) + } + webpackTask { + outputFileName = "main.bundle.js" + } + testTask { + useKarma { + useChromeHeadless() + } + } + } + binaries.executable() + } + + sourceSets["main"].dependencies { + implementation("io.kvision:kvision:$kvisionVersion") + implementation("io.kvision:kvision-bootstrap:$kvisionVersion") + implementation("io.kvision:kvision-bootstrap-css:$kvisionVersion") + implementation("io.kvision:kvision-i18n:$kvisionVersion") + } + sourceSets["test"].dependencies { + implementation(kotlin("test-js")) + implementation("io.kvision:kvision-testutils:$kvisionVersion") + } + sourceSets["main"].resources.srcDir(webDir) + +} diff --git a/modules/server/src/main/kotlin/com/example/App.kt b/modules/server/src/main/kotlin/com/example/App.kt new file mode 100644 index 0000000..a7c20c1 --- /dev/null +++ b/modules/server/src/main/kotlin/com/example/App.kt @@ -0,0 +1,38 @@ +package com.example + +import io.kvision.Application +import io.kvision.BootstrapCssModule +import io.kvision.BootstrapModule +import io.kvision.CoreModule +import io.kvision.html.div +import io.kvision.i18n.DefaultI18nManager +import io.kvision.i18n.I18n +import io.kvision.i18n.I18n.tr +import io.kvision.module +import io.kvision.panel.root +import io.kvision.require +import io.kvision.startApplication + +class App : Application() { + init { + require("./css/kvapp.css") + } + + override fun start() { + I18n.manager = + DefaultI18nManager( + mapOf( + "pl" to require("./i18n/messages-pl.json"), + "en" to require("./i18n/messages-en.json") + ) + ) + + root("kvapp") { + div(tr("This is a localized message.")) + } + } +} + +fun main() { + startApplication(::App, module.hot, BootstrapModule, BootstrapCssModule, CoreModule) +} diff --git a/modules/server/src/main/resources/css/kvapp.css b/modules/server/src/main/resources/css/kvapp.css new file mode 100644 index 0000000..e69de29 diff --git a/modules/server/src/main/resources/i18n/messages-en.po b/modules/server/src/main/resources/i18n/messages-en.po new file mode 100644 index 0000000..520a528 --- /dev/null +++ b/modules/server/src/main/resources/i18n/messages-en.po @@ -0,0 +1,23 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the KVision package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: KVision\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-08-18 01:34+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: English\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: ../src/main/kotlin/com/example/App.kt:20 +msgid "This is a localized message." +msgstr "" diff --git a/modules/server/src/main/resources/i18n/messages-pl.po b/modules/server/src/main/resources/i18n/messages-pl.po new file mode 100644 index 0000000..2431017 --- /dev/null +++ b/modules/server/src/main/resources/i18n/messages-pl.po @@ -0,0 +1,23 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the KVision package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: KVision\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-08-18 01:34+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: Polish\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#: ../src/main/kotlin/com/example/App.kt:20 +msgid "This is a localized message." +msgstr "To jest przetłumaczona wiadomość." diff --git a/modules/server/src/main/resources/i18n/messages.pot b/modules/server/src/main/resources/i18n/messages.pot new file mode 100644 index 0000000..68feb5b --- /dev/null +++ b/modules/server/src/main/resources/i18n/messages.pot @@ -0,0 +1,8 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Language: \n" + +#: src/main/kotlin/com/example/App.kt:31 +msgid "This is a localized message." +msgstr "" diff --git a/modules/server/src/main/web/index.html b/modules/server/src/main/web/index.html new file mode 100644 index 0000000..b723f01 --- /dev/null +++ b/modules/server/src/main/web/index.html @@ -0,0 +1,12 @@ + + + + + + KVision App + + + +